From 362ccfeb2929c3213ea1e22d127400734392a3a5 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Sun, 10 May 2026 18:19:33 +0200 Subject: [PATCH 1/5] Bump tools --- justfile | 4 + tools/rive_update_manifest.json | 495 ++++++++++++++++++++ tools/update_rive.py | 770 ++++++++++++++++++++++++++++++++ tools/update_rive.sh | 25 -- 4 files changed, 1269 insertions(+), 25 deletions(-) create mode 100644 tools/rive_update_manifest.json create mode 100755 tools/update_rive.py delete mode 100644 tools/update_rive.sh diff --git a/justfile b/justfile index b907286a9..5008b49f9 100644 --- a/justfile +++ b/justfile @@ -97,3 +97,7 @@ python_uninstall: [working-directory: 'python'] python_test *TEST_OPTS: python -m pytest -s {{TEST_OPTS}} + +bump_rive: + uv run python tools/bump_rive.py --rive-ref runtime-v0.1.62 --allow-dirty + diff --git a/tools/rive_update_manifest.json b/tools/rive_update_manifest.json new file mode 100644 index 000000000..b7ab17cd2 --- /dev/null +++ b/tools/rive_update_manifest.json @@ -0,0 +1,495 @@ +{ + "metadata_path": "thirdparty/rive_vendor_versions.json", + "global_exclude_globs": [ + ".DS_Store", + "**/.DS_Store", + ".git/**", + ".github/**", + ".gitignore", + ".gitattributes", + ".editorconfig", + "CMakeLists.txt", + "**/CMakeLists.txt", + "BUILD*", + "WORKSPACE*", + "Makefile.in", + "Makefile.am", + "meson.build", + "meson_options.txt", + "**/meson.build", + "**/meson_options.txt", + "test/**", + "tests/**", + "example/**", + "examples/**", + "docs/**", + "doc/**", + "benchmark/**", + "benchmarks/**", + "fuzz/**", + "fuzzer/**", + "perf/**", + "script/**", + "scripts/**", + "**/*.md" + ], + "dependencies": [ + { + "name": "rive", + "repo": "https://github.com/rive-app/rive-runtime.git", + "ref": "main", + "destination": "thirdparty/rive", + "license": "MIT", + "module_header": "thirdparty/rive/rive.h", + "module_version_from_ref": true, + "follow_rive_ref": true, + "copies": [ + { + "from": "include", + "to": "include", + "include_globs": [ + "**/*.h", + "**/*.hh", + "**/*.hpp" + ] + }, + { + "from": "src", + "to": "source", + "include_globs": [ + "**/*.c", + "**/*.cc", + "**/*.cpp", + "**/*.h", + "**/*.hh", + "**/*.hpp", + "**/*.mm" + ] + } + ] + }, + { + "name": "rive_renderer", + "repo": "https://github.com/rive-app/rive-runtime.git", + "ref": "main", + "destination": "thirdparty/rive_renderer", + "license": "MIT", + "module_header": "thirdparty/rive_renderer/rive_renderer.h", + "module_version_from_ref": true, + "follow_rive_ref": true, + "copies": [ + { + "from": "renderer/include", + "to": "include", + "include_globs": [ + "**/*.h", + "**/*.hh", + "**/*.hpp" + ] + }, + { + "from": "renderer/src", + "to": "source", + "include_globs": [ + "**/*.c", + "**/*.cc", + "**/*.cpp", + "**/*.h", + "**/*.hh", + "**/*.hpp", + "**/*.m", + "**/*.mm", + "**/*.glsl", + "**/*.metal", + "**/*.frag", + "**/*.vert", + "**/*.main", + "**/*.py", + "**/Makefile" + ], + "preserve_globs": [ + "generated/shaders/**" + ], + "exclude_globs": [ + "out/**" + ] + } + ], + "shader_generation": { + "source_dir": "renderer/src/shaders", + "output_dir": "out/generated", + "destination": "thirdparty/rive_renderer/source/generated/shaders", + "python_package": "ply", + "required_tools": { + "minify": [ + "make" + ], + "rive_pls_macosx_metallib": [ + "make", + "xcrun", + "xxd" + ], + "rive_pls_ios_metallib": [ + "make", + "xcrun", + "xxd" + ], + "rive_pls_ios_simulator_metallib": [ + "make", + "xcrun", + "xxd" + ], + "rive_renderer_xros_metallib": [ + "make", + "xcrun", + "xxd" + ], + "rive_renderer_xros_simulator_metallib": [ + "make", + "xcrun", + "xxd" + ], + "rive_renderer_appletvos_metallib": [ + "make", + "xcrun", + "xxd" + ], + "rive_renderer_appletvsimulator_metallib": [ + "make", + "xcrun", + "xxd" + ], + "spirv": [ + "make", + "glslangValidator" + ], + "spirv-binary": [ + "make", + "glslangValidator" + ] + }, + "targets": [ + "minify", + "rive_pls_macosx_metallib", + "rive_pls_ios_metallib", + "rive_pls_ios_simulator_metallib", + "rive_renderer_xros_metallib", + "rive_renderer_xros_simulator_metallib", + "rive_renderer_appletvos_metallib", + "rive_renderer_appletvsimulator_metallib", + "spirv", + "spirv-binary" + ] + } + }, + { + "name": "rive_decoders", + "repo": "https://github.com/rive-app/rive-runtime.git", + "ref": "main", + "destination": "thirdparty/rive_decoders", + "license": "MIT", + "module_header": "thirdparty/rive_decoders/rive_decoders.h", + "module_version_from_ref": true, + "follow_rive_ref": true, + "copies": [ + { + "from": "decoders/include", + "to": "include", + "include_globs": [ + "**/*.h", + "**/*.hh", + "**/*.hpp" + ] + }, + { + "from": "decoders/src", + "to": "source", + "include_globs": [ + "**/*.c", + "**/*.cc", + "**/*.cpp", + "**/*.h", + "**/*.hh", + "**/*.hpp", + "**/*.m", + "**/*.mm" + ] + } + ] + }, + { + "name": "harfbuzz", + "repo": "https://github.com/rive-app/harfbuzz.git", + "rive_dependency_premake": { + "file": "dependencies/premake5_harfbuzz_v2.lua", + "project": "rive-app/harfbuzz" + }, + "destination": "thirdparty/harfbuzz", + "license": "MIT", + "copies": [ + { + "from": "src", + "to": "upstream", + "include_globs": [ + "**/*.c", + "**/*.cc", + "**/*.h", + "**/*.hh", + "**/*.rl" + ], + "exclude_globs": [ + "*-test*", + "test-*", + "main.cc" + ] + } + ] + }, + { + "name": "sheenbidi_library", + "repo": "https://github.com/Tehreer/SheenBidi.git", + "rive_dependency_premake": { + "file": "dependencies/premake5_sheenbidi_v2.lua", + "project": "Tehreer/SheenBidi" + }, + "destination": "thirdparty/sheenbidi_library", + "license": "Apache-2.0", + "copies": [ + { + "from": "Headers", + "to": "include", + "include_globs": [ + "**/*.h" + ] + }, + { + "from": "Source", + "to": "source", + "include_globs": [ + "**/*.c", + "**/*.h" + ] + } + ] + }, + { + "name": "yoga_library", + "repo": "https://github.com/rive-app/yoga.git", + "rive_dependency_premake": { + "file": "dependencies/premake5_yoga_v2.lua", + "project": "rive-app/yoga" + }, + "destination": "thirdparty/yoga_library", + "license": "MIT", + "copies": [ + { + "from": "yoga", + "to": "upstream/yoga", + "include_globs": [ + "**/*.cpp", + "**/*.h" + ], + "exclude_globs": [ + "tests/**" + ] + } + ] + }, + { + "name": "libpng", + "repo": "https://github.com/glennrp/libpng.git", + "rive_dependency_premake": { + "file": "dependencies/premake5_libpng_v2.lua", + "project": "glennrp/libpng" + }, + "destination": "thirdparty/libpng", + "license": "PNG-2.0", + "copies": [ + { + "from": ".", + "to": "upstream", + "include_globs": [ + "*.c", + "*.h", + "LICENSE", + "arm/*.c", + "arm/*.h", + "intel/*.c", + "intel/*.h" + ], + "exclude_globs": [ + "pngtest.c", + "arm/filter_neon.S" + ] + } + ] + }, + { + "name": "libwebp", + "repo": "https://github.com/webmproject/libwebp.git", + "rive_dependency_premake": { + "file": "dependencies/premake5_libwebp_v2.lua", + "project": "webmproject/libwebp" + }, + "destination": "thirdparty/libwebp", + "license": "BSD-3-Clause", + "copies": [ + { + "from": "src", + "to": "upstream/src", + "include_globs": [ + "**/*.c", + "**/*.h" + ] + } + ] + }, + { + "name": "zlib", + "repo": "https://github.com/madler/zlib.git", + "rive_dependency_premake": { + "file": "dependencies/premake5_libpng_v2.lua", + "project": "madler/zlib" + }, + "destination": "thirdparty/zlib", + "license": "Zlib", + "copies": [ + { + "from": ".", + "to": "src", + "include_globs": [ + "*.c", + "*.h", + "README" + ], + "exclude_globs": [ + "example.c", + "minigzip.c" + ] + } + ] + } + ], + "include_blocks": [ + { + "path": "thirdparty/rive/rive.cpp", + "start_marker": "// BEGIN YUP GENERATED RIVE INCLUDES", + "end_marker": "// END YUP GENERATED RIVE INCLUDES", + "insert_after": "#if !defined(_RIVE_INTERNAL_)\n#define _RIVE_INTERNAL_ 1\n#endif", + "insert_before": "#if __clang__", + "root": "thirdparty/rive/source", + "prefix": "source", + "include_globs": [ + "**/*.c", + "**/*.cc", + "**/*.cpp" + ], + "exclude_globs": [ + "**/*_test.*" + ] + }, + { + "path": "thirdparty/rive_renderer/rive_renderer.cpp", + "start_marker": "// BEGIN YUP GENERATED RIVE RENDERER INCLUDES", + "end_marker": "// END YUP GENERATED RIVE RENDERER INCLUDES", + "insert_after": "#include \"rive_renderer.h\"", + "insert_before": "#if __clang__", + "root": "thirdparty/rive_renderer/source", + "prefix": "source", + "include_globs": [ + "*.c", + "*.cc", + "*.cpp" + ] + }, + { + "path": "thirdparty/rive_decoders/rive_decoders.cpp", + "start_marker": "// BEGIN YUP GENERATED RIVE DECODER INCLUDES", + "end_marker": "// END YUP GENERATED RIVE DECODER INCLUDES", + "insert_after": "#include \"rive_decoders.h\"", + "insert_before": "#if RIVE_JPEG", + "root": "thirdparty/rive_decoders/source", + "prefix": "source", + "include_globs": [ + "*.c", + "*.cc", + "*.cpp" + ], + "exclude_globs": [ + "decode_jpeg.cpp", + "decode_png.cpp", + "decode_webp.cpp" + ] + }, + { + "path": "thirdparty/harfbuzz/harfbuzz.cpp", + "start_marker": "// BEGIN YUP GENERATED HARFBUZZ INCLUDES", + "end_marker": "// END YUP GENERATED HARFBUZZ INCLUDES", + "insert_after": "#include \"harfbuzz.h\"", + "insert_before": "#if __clang__", + "root": "thirdparty/harfbuzz/upstream", + "prefix": "upstream", + "include_globs": [ + "**/*.cc" + ], + "exclude_globs": [ + "main.cc", + "*-test*", + "test-*" + ] + }, + { + "path": "thirdparty/sheenbidi_library/sheenbidi_library.c", + "start_marker": "// BEGIN YUP GENERATED SHEENBIDI INCLUDES", + "end_marker": "// END YUP GENERATED SHEENBIDI INCLUDES", + "insert_after": "#if defined(__GNUC__) && !defined(__clang__)\n #pragma GCC diagnostic push\n #pragma GCC diagnostic ignored \"-Wpragmas\"\n #pragma GCC diagnostic ignored \"-Wstringop-overflow\"\n #pragma GCC diagnostic ignored \"-Wnonportable-include-path\"\n#endif", + "insert_before": "#if defined(__GNUC__) && !defined(__clang__)", + "root": "thirdparty/sheenbidi_library/source", + "prefix": "source", + "include_globs": [ + "*.c" + ] + }, + { + "path": "thirdparty/yoga_library/yoga_library.cpp", + "start_marker": "// BEGIN YUP GENERATED YOGA INCLUDES", + "end_marker": "// END YUP GENERATED YOGA INCLUDES", + "insert_after": "#include \"yoga_library.h\"", + "root": "thirdparty/yoga_library/upstream", + "prefix": "upstream", + "include_globs": [ + "**/*.cpp" + ], + "exclude_globs": [ + "**/*Test.cpp" + ] + }, + { + "path": "thirdparty/libpng/libpng.c", + "start_marker": "// BEGIN YUP GENERATED LIBPNG INCLUDES", + "end_marker": "// END YUP GENERATED LIBPNG INCLUDES", + "insert_after": "#include \"libpng.h\"", + "insert_before": "#if defined(__arm__)", + "root": "thirdparty/libpng/upstream", + "prefix": "upstream", + "include_globs": [ + "*.c" + ], + "exclude_globs": [ + "pngtest.c" + ] + }, + { + "path": "thirdparty/libwebp/libwebp.c", + "validate_existing_includes": true, + "search_roots": [ + "thirdparty/libwebp", + "thirdparty/libwebp/upstream" + ] + }, + { + "path": "thirdparty/zlib/zlib.c", + "validate_existing_includes": true + } + ] +} diff --git a/tools/update_rive.py b/tools/update_rive.py new file mode 100755 index 000000000..8b4e0c41f --- /dev/null +++ b/tools/update_rive.py @@ -0,0 +1,770 @@ +#!/usr/bin/env python3 +# +# ============================================================================== +# +# This file is part of the YUP library. +# Copyright (c) 2026 - kunitoki@gmail.com +# +# YUP is an open source library subject to open-source licensing. +# +# The code included in this file is provided under the terms of the ISC license +# http://www.isc.org/downloads/software-support-policy/isc-license. Permission +# to use, copy, modify, and/or distribute this software for any purpose with or +# without fee is hereby granted provided that the above copyright notice and +# this permission notice appear in all copies. +# +# YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +# DISCLAIMED. +# +# ============================================================================== + +from __future__ import annotations + +import argparse +import fnmatch +import json +import os +import re +import shutil +import subprocess +import sys +from dataclasses import dataclass, field +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + + +SCRIPT_DIR = Path(__file__).resolve().parent +REPO_ROOT = SCRIPT_DIR.parent +DEFAULT_MANIFEST = SCRIPT_DIR / "rive_update_manifest.json" +SHA_RE = re.compile(r"^[0-9a-fA-F]{7,40}$") +PREMAKE_GITHUB_RE = re.compile(r"dependency\.github\s*\(\s*['\"]([^'\"]+)['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)") + + +@dataclass +class CopyStats: + copied: int = 0 + unchanged: int = 0 + removed: int = 0 + + +@dataclass +class DependencyResult: + name: str + ref: str + version: str + checkout: str + copy_stats: list[CopyStats] = field(default_factory=list) + generated_files: int = 0 + notes: list[str] = field(default_factory=list) + + @property + def copied(self) -> int: + return sum(item.copied for item in self.copy_stats) + + @property + def unchanged(self) -> int: + return sum(item.unchanged for item in self.copy_stats) + + @property + def removed(self) -> int: + return sum(item.removed for item in self.copy_stats) + + +def run(command: list[str], cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]: + print("+ " + " ".join(command)) + try: + return subprocess.run(command, cwd=cwd, check=check, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except subprocess.CalledProcessError as error: + if error.stdout: + print(error.stdout, end="") + if error.stderr: + print(error.stderr, end="", file=sys.stderr) + raise + + +def load_manifest(path: Path) -> dict[str, Any]: + with path.open("r", encoding="utf-8") as handle: + return json.load(handle) + + +def posix(path: Path) -> str: + return path.as_posix() + + +def is_relative_to(path: Path, parent: Path) -> bool: + try: + path.resolve().relative_to(parent.resolve()) + return True + except ValueError: + return False + + +def matches_pattern(value: str, pattern: str) -> bool: + if fnmatch.fnmatch(value, pattern): + return True + if pattern.startswith("**/"): + return fnmatch.fnmatch(value, pattern[3:]) + return False + + +def matches_any(value: str, patterns: list[str]) -> bool: + return any(matches_pattern(value, pattern) for pattern in patterns) + + +def read_text(path: Path) -> str: + return path.read_text(encoding="utf-8") + + +def write_text_if_changed(path: Path, text: str) -> bool: + if path.exists() and read_text(path) == text: + return False + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(text, encoding="utf-8") + return True + + +def parse_dep_override(value: str) -> tuple[str, str]: + if "=" not in value: + raise argparse.ArgumentTypeError("--dep must be formatted as name=ref") + name, ref = value.split("=", 1) + name = name.strip() + ref = ref.strip() + if not name or not ref: + raise argparse.ArgumentTypeError("--dep must include both name and ref") + return name, ref + + +def resolve_refs(manifest: dict[str, Any], rive_ref: str | None, dep_overrides: list[tuple[str, str]]) -> dict[str, str]: + refs = {dep["name"]: dep.get("ref", "") for dep in manifest["dependencies"]} + if rive_ref: + for dep in manifest["dependencies"]: + if dep.get("follow_rive_ref"): + refs[dep["name"]] = rive_ref + + known = set(refs) + for name, ref in dep_overrides: + if name not in known: + raise SystemExit(f"Unknown dependency override '{name}'. Known dependencies: {', '.join(sorted(known))}") + refs[name] = ref + return refs + + +def ref_to_version(ref: str) -> str: + value = ref.strip() + for prefix in ("refs/tags/", "refs/heads/", "origin/"): + if value.startswith(prefix): + value = value.removeprefix(prefix) + + if value in ("main", "master", "develop", "trunk") or SHA_RE.fullmatch(value): + return "0.0.0" + + libpng_match = re.fullmatch(r"libpng(\d)(\d+)", value) + if libpng_match: + return f"{libpng_match.group(1)}.{int(libpng_match.group(2))}" + + if value == "rive_changes_v2_0_1_2": + return "2.0.2.1" + + value = re.sub(r"^(rive_changes_|rive_|release[-_/])", "", value) + if value.startswith("v") and len(value) > 1 and value[1].isdigit(): + value = value[1:] + + numeric_match = re.search(r"\d+(?:[._-]\d+)+", value) + if numeric_match: + return numeric_match.group(0).replace("_", ".").replace("-", ".") + + numeric_match = re.search(r"\d+", value) + if numeric_match: + return numeric_match.group(0) + + return "0.0.0" + + +def git_status(paths: list[Path]) -> list[str]: + rel_paths = [posix(path.relative_to(REPO_ROOT)) if path.is_absolute() else posix(path) for path in paths] + command = ["git", "status", "--porcelain", "--", *rel_paths] + completed = run(command, cwd=REPO_ROOT) + return [line for line in completed.stdout.splitlines() if line.strip()] + + +def fail_on_dirty(manifest: dict[str, Any]) -> None: + paths = [REPO_ROOT / dep["destination"] for dep in manifest["dependencies"]] + metadata_path = manifest.get("metadata_path") + if metadata_path: + paths.append(REPO_ROOT / metadata_path) + dirty = git_status(paths) + if dirty: + print("Managed vendor paths already have changes:") + for line in dirty: + print(f" {line}") + raise SystemExit("Pass --allow-dirty to update on top of these changes.") + + +def clone_dependency(dep: dict[str, Any], ref: str, work_dir: Path) -> Path: + checkout_dir = work_dir / "repos" / dep["name"] + if checkout_dir.exists(): + shutil.rmtree(checkout_dir) + checkout_dir.parent.mkdir(parents=True, exist_ok=True) + + if SHA_RE.fullmatch(ref): + checkout_dir.mkdir(parents=True) + run(["git", "init"], cwd=checkout_dir) + run(["git", "remote", "add", "origin", dep["repo"]], cwd=checkout_dir) + run(["git", "fetch", "--depth", "1", "origin", ref], cwd=checkout_dir) + run(["git", "checkout", "--detach", "FETCH_HEAD"], cwd=checkout_dir) + else: + clone = run(["git", "clone", "--depth", "1", "--branch", ref, dep["repo"], str(checkout_dir)], check=False) + if clone.returncode != 0: + if checkout_dir.exists(): + shutil.rmtree(checkout_dir) + run(["git", "clone", "--depth", "1", dep["repo"], str(checkout_dir)]) + run(["git", "fetch", "--depth", "1", "origin", ref], cwd=checkout_dir) + run(["git", "checkout", "--detach", "FETCH_HEAD"], cwd=checkout_dir) + + return checkout_dir + + +def checkout_hash(checkout_dir: Path) -> str: + completed = run(["git", "rev-parse", "HEAD"], cwd=checkout_dir) + return completed.stdout.strip() + + +def parse_rive_dependency_premake(rive_checkout: Path, dep: dict[str, Any]) -> tuple[str, str]: + config = dep["rive_dependency_premake"] + premake_path = rive_checkout / config["file"] + expected_project = config["project"] + + if not premake_path.exists(): + raise SystemExit(f"Missing Rive dependency declaration for {dep['name']}: {premake_path}") + + for project, ref in PREMAKE_GITHUB_RE.findall(read_text(premake_path)): + if project == expected_project: + return f"https://github.com/{project}.git", ref + + raise SystemExit(f"Could not find dependency.github('{expected_project}', ...) in {premake_path}") + + +def iter_source_files(source_dir: Path) -> list[Path]: + return sorted(path for path in source_dir.rglob("*") if path.is_file()) + + +def should_copy(rel: str, include_globs: list[str], exclude_globs: list[str]) -> bool: + if include_globs and not matches_any(rel, include_globs): + return False + return not matches_any(rel, exclude_globs) + + +def remove_empty_dirs(path: Path) -> None: + if not path.exists(): + return + for directory in sorted((item for item in path.rglob("*") if item.is_dir()), key=lambda item: len(item.parts), reverse=True): + try: + directory.rmdir() + except OSError: + pass + + +def remove_work_dir(work_dir: Path) -> None: + resolved = work_dir.resolve() + forbidden = { + REPO_ROOT.resolve(), + Path.home().resolve(), + Path("/").resolve(), + Path("/tmp").resolve(), + Path("/private/tmp").resolve(), + } + if resolved in forbidden or len(resolved.parts) < 3: + raise SystemExit(f"Refusing to remove unsafe work directory: {resolved}") + shutil.rmtree(resolved) + + +def copy_tree(checkout_dir: Path, destination_root: Path, copy_rule: dict[str, Any], global_excludes: list[str]) -> CopyStats: + source_dir = (checkout_dir / copy_rule["from"]).resolve() + destination_dir = (destination_root / copy_rule["to"]).resolve() + + if not source_dir.exists(): + raise SystemExit(f"Missing upstream source directory: {source_dir}") + if not is_relative_to(destination_dir, destination_root): + raise SystemExit(f"Copy destination escapes dependency root: {destination_dir}") + + include_globs = copy_rule.get("include_globs", []) + exclude_globs = global_excludes + copy_rule.get("exclude_globs", []) + preserve_globs = copy_rule.get("preserve_globs", []) + copied_paths: set[Path] = set() + stats = CopyStats() + + for source in iter_source_files(source_dir): + rel = posix(source.relative_to(source_dir)) + if not should_copy(rel, include_globs, exclude_globs): + continue + + destination = destination_dir / rel + if not is_relative_to(destination, destination_dir): + raise SystemExit(f"Copy target escapes expected tree: {destination}") + + copied_paths.add(destination.resolve()) + destination.parent.mkdir(parents=True, exist_ok=True) + if destination.exists() and destination.read_bytes() == source.read_bytes(): + stats.unchanged += 1 + continue + + shutil.copy2(source, destination) + stats.copied += 1 + + if destination_dir.exists(): + for existing in sorted(path for path in destination_dir.rglob("*") if path.is_file()): + rel = posix(existing.relative_to(destination_dir)) + if existing.resolve() in copied_paths or matches_any(rel, preserve_globs): + continue + existing.unlink() + stats.removed += 1 + + remove_empty_dirs(destination_dir) + return stats + + +def replace_module_version(header_path: Path, version: str) -> bool: + if not header_path.exists(): + return False + text = read_text(header_path) + new_text = re.sub(r"(^\s*version:\s+).*$", rf"\g<1>{version}", text, count=1, flags=re.MULTILINE) + if new_text == text: + return False + return write_text_if_changed(header_path, new_text) + + +def generate_include_lines(block: dict[str, Any]) -> list[str]: + if "entries" in block: + return list(block["entries"]) + + root = REPO_ROOT / block["root"] + include_globs = block.get("include_globs", []) + exclude_globs = block.get("exclude_globs", []) + prefix = block.get("prefix", "") + paths: list[str] = [] + + if not root.exists(): + raise SystemExit(f"Include generation root does not exist: {root}") + + for source in iter_source_files(root): + rel = posix(source.relative_to(root)) + if should_copy(rel, include_globs, exclude_globs): + include_path = f"{prefix}/{rel}" if prefix else rel + paths.append(include_path) + + return [f'#include "{path}"' for path in sorted(paths)] + + +def find_generated_range(text: str, start_marker: str, end_marker: str) -> tuple[int, int] | None: + start = text.find(start_marker) + if start < 0: + return None + start_line_end = text.find("\n", start) + if start_line_end < 0: + raise SystemExit(f"Malformed include block marker: {start_marker}") + end = text.find(end_marker, start_line_end) + if end < 0: + raise SystemExit(f"Missing include block end marker: {end_marker}") + return start, text.find("\n", end) + 1 + + +def find_insert_range(text: str, block: dict[str, Any]) -> tuple[int, int]: + insert_after = block["insert_after"] + after = text.find(insert_after) + if after < 0: + raise SystemExit(f"Cannot find insert_after in {block['path']}: {insert_after}") + start = after + len(insert_after) + if start < len(text) and text[start] == "\r": + start += 1 + if start < len(text) and text[start] == "\n": + start += 1 + + insert_before = block.get("insert_before") + if not insert_before: + return start, len(text.rstrip()) + + end = text.find(insert_before, start) + if end < 0: + raise SystemExit(f"Cannot find insert_before in {block['path']}: {insert_before}") + while end > 0 and text[end - 1] == "\n": + end -= 1 + return start, end + + +def order_include_lines(generated_lines: list[str], current_text: str) -> list[str]: + if not current_text.strip(): + return generated_lines + + by_text = {line: line for line in generated_lines} + ordered: list[str] = [] + seen: set[str] = set() + + for line in current_text.splitlines(): + stripped = line.strip() + if stripped in by_text and stripped not in seen: + ordered.append(stripped) + seen.add(stripped) + + ordered.extend(line for line in generated_lines if line not in seen) + return ordered + + +def regenerate_include_block(block: dict[str, Any]) -> bool: + path = REPO_ROOT / block["path"] + text = read_text(path) + start_marker = block["start_marker"] + end_marker = block["end_marker"] + + generated_range = find_generated_range(text, start_marker, end_marker) + if generated_range: + start, end = generated_range + current_include_text = text[start:end] + leading_newline = "" + else: + start, end = find_insert_range(text, block) + current_include_text = text[start:end] + leading_newline = "\n" + + include_lines = order_include_lines(generate_include_lines(block), current_include_text) + replacement = leading_newline + "\n".join([start_marker, *include_lines, end_marker, ""]) + + new_text = text[:start] + replacement + text[end:] + return write_text_if_changed(path, new_text) + + +def included_targets(path: Path, search_roots: list[Path]) -> list[Path]: + include_re = re.compile(r'^\s*#\s*include\s+"([^"]+)"') + targets: list[Path] = [] + for line in read_text(path).splitlines(): + match = include_re.match(line) + if not match: + continue + include_path = match.group(1) + candidates = [root / include_path for root in search_roots] + targets.append(next((candidate for candidate in candidates if candidate.exists()), candidates[0])) + return targets + + +def validate_include_targets(path: Path, block: dict[str, Any] | None = None) -> None: + search_roots = [path.parent] + if block: + search_roots.extend(REPO_ROOT / root for root in block.get("search_roots", [])) + + missing = [target for target in included_targets(path, search_roots) if not target.exists()] + if missing: + print(f"Missing include targets in {path.relative_to(REPO_ROOT)}:") + for target in missing: + print(f" {target.relative_to(REPO_ROOT)}") + raise SystemExit("Generated include target validation failed.") + + +def process_include_blocks(manifest: dict[str, Any]) -> int: + changed = 0 + for block in manifest.get("include_blocks", []): + path = REPO_ROOT / block["path"] + if block.get("validate_existing_includes"): + validate_include_targets(path, block) + continue + + if regenerate_include_block(block): + changed += 1 + validate_include_targets(path, block) + return changed + + +def selected_shader_targets(shader_config: dict[str, Any], skipped_targets: set[str]) -> list[str]: + targets = shader_config.get("targets", []) + unknown = skipped_targets.difference(targets) + if unknown: + raise SystemExit(f"Unknown shader target(s) for --skip-shader-target: {', '.join(sorted(unknown))}") + return [target for target in targets if target not in skipped_targets] + + +def preflight_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped_targets: set[str]) -> None: + shader_config = dep.get("shader_generation") + if not shader_config: + return + + shader_dir = checkout_dir / shader_config["source_dir"] + if not shader_dir.exists(): + raise SystemExit(f"Missing shader source directory: {shader_dir}") + + missing: dict[str, list[str]] = {} + required_tools = shader_config.get("required_tools", {}) + for target in selected_shader_targets(shader_config, skipped_targets): + missing_tools = [tool for tool in required_tools.get(target, []) if shutil.which(tool) is None] + if missing_tools: + missing[target] = missing_tools + + if not missing: + return + + lines = ["Missing tools required for Rive shader generation:"] + for target, tools in missing.items(): + lines.append(f" {target}: {', '.join(tools)}") + lines.append("") + lines.append("Install the missing tools, or intentionally skip affected targets, for example:") + for target in missing: + lines.append(f" --skip-shader-target {target}") + raise SystemExit("\n".join(lines)) + + +def run_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped_targets: set[str]) -> int: + shader_config = dep.get("shader_generation") + if not shader_config: + return 0 + + shader_dir = checkout_dir / shader_config["source_dir"] + if not shader_dir.exists(): + raise SystemExit(f"Missing shader source directory: {shader_dir}") + + preflight_shader_generation(dep, checkout_dir, skipped_targets) + venv_dir = shader_dir / "cooker" + run([sys.executable, "-m", "venv", str(venv_dir)]) + python_bin = venv_dir / ("Scripts/python.exe" if os.name == "nt" else "bin/python3") + package = shader_config.get("python_package") + if package: + run([str(python_bin), "-m", "pip", "install", package]) + + site_packages = next((venv_dir / "lib").glob("python*/site-packages"), None) + flags = [f"--ply-path={site_packages}"] if site_packages else [] + + targets = selected_shader_targets(shader_config, skipped_targets) + for target in targets: + run(["make", f"FLAGS={' '.join(flags)}", target], cwd=shader_dir) + + generated_dir = shader_dir / shader_config["output_dir"] + destination = REPO_ROOT / shader_config["destination"] + if not generated_dir.exists(): + raise SystemExit(f"Shader generation did not produce: {generated_dir}") + + count = 0 + destination.mkdir(parents=True, exist_ok=True) + copied_paths: set[Path] = set() + for source in iter_source_files(generated_dir): + rel = source.relative_to(generated_dir) + target = destination / rel + copied_paths.add(target.resolve()) + target.parent.mkdir(parents=True, exist_ok=True) + if not target.exists() or target.read_bytes() != source.read_bytes(): + shutil.copy2(source, target) + count += 1 + + if not skipped_targets: + for existing in sorted(path for path in destination.rglob("*") if path.is_file()): + if existing.resolve() not in copied_paths: + existing.unlink() + remove_empty_dirs(destination) + return count + + +def write_metadata(manifest: dict[str, Any], results: list[DependencyResult]) -> None: + metadata_path = REPO_ROOT / manifest["metadata_path"] + payload = { + "generatedAt": datetime.now(timezone.utc).isoformat(), + "dependencies": [ + { + "name": result.name, + "ref": result.ref, + "version": result.version, + "checkout": result.checkout, + } + for result in results + ], + } + write_text_if_changed(metadata_path, json.dumps(payload, indent=2, sort_keys=True) + "\n") + + +def check_available_refs(manifest: dict[str, Any], refs: dict[str, str], work_dir: Path) -> None: + metadata_path = REPO_ROOT / manifest.get("metadata_path", "") + current: dict[str, Any] = {} + if metadata_path.exists(): + current = json.loads(read_text(metadata_path)) + + rive_dep = next((dep for dep in manifest["dependencies"] if dep["name"] == "rive"), None) + if not rive_dep: + raise SystemExit("Manifest must contain the Rive runtime dependency named 'rive'.") + + work_dir.mkdir(parents=True, exist_ok=True) + rive_checkout = clone_dependency(rive_dep, refs["rive"], work_dir) + current_by_name = {item["name"]: item for item in current.get("dependencies", [])} + for dep in manifest["dependencies"]: + name = dep["name"] + requested = refs[name] + print(f"{name}:") + print(f" current: {current_by_name.get(name, {}).get('ref', 'unknown')}") + if dep.get("rive_dependency_premake") and not requested: + repo, requested = parse_rive_dependency_premake(rive_checkout, dep) + print(f" requested: {requested} from Rive runtime {dep['rive_dependency_premake']['file']}") + else: + repo = dep["repo"] + print(f" requested: {requested}") + remote = run(["git", "ls-remote", repo, requested], check=False) + status = "found" if remote.returncode == 0 and remote.stdout.strip() else "not found as exact remote ref" + print(f" remote: {status}") + for copy_rule in dep.get("copies", []): + print(f" copy: {copy_rule['from']} -> {dep['destination']}/{copy_rule['to']}") + + +def update_dependencies( + manifest: dict[str, Any], + refs: dict[str, str], + work_dir: Path, + skipped_shader_targets: set[str], +) -> list[DependencyResult]: + work_dir.mkdir(parents=True, exist_ok=True) + global_excludes = manifest.get("global_exclude_globs", []) + results: list[DependencyResult] = [] + rive_dep = next((dep for dep in manifest["dependencies"] if dep["name"] == "rive"), None) + if not rive_dep: + raise SystemExit("Manifest must contain the Rive runtime dependency named 'rive'.") + + rive_ref = refs["rive"] + rive_checkout = clone_dependency(rive_dep, rive_ref, work_dir) + checkout_cache: dict[tuple[str, str], Path] = {(rive_dep["repo"], rive_ref): rive_checkout} + + for dep in manifest["dependencies"]: + if dep.get("shader_generation"): + preflight_shader_generation(dep, rive_checkout, skipped_shader_targets) + + for dep in manifest["dependencies"]: + name = dep["name"] + ref = refs[name] + destination_root = REPO_ROOT / dep["destination"] + destination_root.mkdir(parents=True, exist_ok=True) + + source_dep = dep + if name == "rive": + checkout_dir = rive_checkout + elif dep.get("follow_rive_ref") and dep["repo"] == rive_dep["repo"] and ref == rive_ref: + checkout_dir = rive_checkout + elif dep.get("rive_dependency_premake") and not ref: + repo, ref = parse_rive_dependency_premake(rive_checkout, dep) + source_dep = dict(dep) + source_dep["repo"] = repo + cache_key = (repo, ref) + if cache_key not in checkout_cache: + checkout_cache[cache_key] = clone_dependency(source_dep, ref, work_dir) + checkout_dir = checkout_cache[cache_key] + else: + cache_key = (dep["repo"], ref) + if cache_key not in checkout_cache: + checkout_cache[cache_key] = clone_dependency(dep, ref, work_dir) + checkout_dir = checkout_cache[cache_key] + + version = ref_to_version(ref) + result = DependencyResult(name=name, ref=ref, version=version, checkout=checkout_hash(checkout_dir)) + + for copy_rule in dep.get("copies", []): + result.copy_stats.append(copy_tree(checkout_dir, destination_root, copy_rule, global_excludes)) + + if dep.get("module_header") and dep.get("module_version_from_ref"): + changed = replace_module_version(REPO_ROOT / dep["module_header"], version) + if changed: + result.notes.append(f"updated module declaration version to {version}") + + result.generated_files = run_shader_generation(dep, checkout_dir, skipped_shader_targets) + if result.generated_files: + result.notes.append(f"copied {result.generated_files} generated shader files") + if dep.get("shader_generation") and skipped_shader_targets: + result.notes.append(f"skipped shader targets: {', '.join(sorted(skipped_shader_targets))}") + + results.append(result) + + include_changes = process_include_blocks(manifest) + if include_changes: + results.append( + DependencyResult( + name="include-lists", + ref="generated", + version="", + checkout="", + notes=[f"regenerated {include_changes} amalgamated include lists"], + ) + ) + + write_metadata(manifest, [result for result in results if result.checkout]) + return results + + +def print_summary(results: list[DependencyResult]) -> None: + print("") + print("Rive vendor update summary") + print("==========================") + for result in results: + print(f"{result.name}:") + if result.ref: + print(f" ref: {result.ref}") + if result.version: + print(f" version: {result.version}") + if result.checkout: + print(f" checkout: {result.checkout}") + if result.copy_stats: + print(f" copied: {result.copied}") + print(f" unchanged: {result.unchanged}") + print(f" removed: {result.removed}") + if result.generated_files: + print(f" generated: {result.generated_files}") + for note in result.notes: + print(f" note: {note}") + print("") + print("Review notes:") + print(" - Inspect the unstaged diff before committing.") + print(" - Confirm generated shader outputs are expected for the host platform.") + print(" - Run project configure/build/tests separately after review.") + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Refresh vendored Rive and Rive-adjacent dependencies.") + parser.add_argument("--rive-ref", help="Rive runtime ref used for rive, rive_renderer, and rive_decoders.") + parser.add_argument("--dep", action="append", default=[], type=parse_dep_override, help="Override dependency ref as name=ref.") + parser.add_argument("--manifest", default=str(DEFAULT_MANIFEST), help="Path to the Rive update manifest.") + parser.add_argument("--work-dir", default="build/rive-update", help="Directory for checkouts and generated intermediates.") + parser.add_argument("--keep-work-dir", action="store_true", help="Leave the work directory in place after the run.") + parser.add_argument("--allow-dirty", action="store_true", help="Allow pre-existing changes under managed vendor paths.") + parser.add_argument("--check", action="store_true", help="Report planned operations and remote ref availability without modifying files.") + parser.add_argument( + "--skip-shader-target", + action="append", + default=[], + help="Skip one Rive shader Makefile target, e.g. spirv when glslangValidator is unavailable.", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + manifest = load_manifest(Path(args.manifest)) + refs = resolve_refs(manifest, args.rive_ref, args.dep) + work_dir = (REPO_ROOT / args.work_dir).resolve() + + if args.check: + if work_dir.exists() and not args.keep_work_dir: + remove_work_dir(work_dir) + try: + check_available_refs(manifest, refs, work_dir) + finally: + if work_dir.exists() and not args.keep_work_dir: + remove_work_dir(work_dir) + return 0 + + if not args.allow_dirty: + fail_on_dirty(manifest) + + if work_dir.exists() and not args.keep_work_dir: + remove_work_dir(work_dir) + + try: + results = update_dependencies(manifest, refs, work_dir, set(args.skip_shader_target)) + print_summary(results) + finally: + if work_dir.exists() and not args.keep_work_dir: + remove_work_dir(work_dir) + + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/update_rive.sh b/tools/update_rive.sh deleted file mode 100644 index 6a74c743e..000000000 --- a/tools/update_rive.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -pushd build -#rm -rf rive-runtime -#git clone https://github.com/rive-app/rive-runtime.git - -pushd rive-runtime -pushd renderer/src/shaders - -python -m venv cooker -./cooker/bin/python3 -m pip install ply -#gsed -i -e "s/python3/cooker\/bin\/python3/g" Makefile - -MINIFY_FLAGS="--ply-path=cooker/lib/python3.11/site-packages" - -make FLAGS="${MINIFY_FLAGS}" -make FLAGS="${MINIFY_FLAGS}" rive_pls_macosx_metallib -make FLAGS="${MINIFY_FLAGS}" rive_pls_ios_metallib -make FLAGS="${MINIFY_FLAGS}" rive_pls_ios_simulator_metallib -make FLAGS="${MINIFY_FLAGS}" spirv -make FLAGS="${MINIFY_FLAGS}" spirv-binary - -popd # renderer/src/shaders -popd # rive-runtime -popd # build From 0771f933526fdb979cc4a22fe9df9df4bb26cff1 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Sun, 10 May 2026 21:01:47 +0200 Subject: [PATCH 2/5] Bump rive to latest --- .gitignore | 1 + justfile | 5 +- modules/yup_graphics/imaging/yup_Image.cpp | 1 + .../native/yup_GraphicsContext_headless.cpp | 4 +- .../native/yup_GraphicsContext_metal.cpp | 6 +- modules/yup_gui/artboard/yup_ArtboardFile.cpp | 4 +- modules/yup_gui/artboard/yup_ArtboardFile.h | 4 +- thirdparty/harfbuzz/harfbuzz.cpp | 99 +- thirdparty/harfbuzz/harfbuzz.h | 2 +- .../harfbuzz/upstream/ArabicPUASimplified.txt | 250 - .../upstream/ArabicPUATraditional.txt | 295 - .../harfbuzz/upstream/OT/Color/CBDT/CBDT.hh | 16 +- .../harfbuzz/upstream/OT/Color/COLR/COLR.hh | 320 +- .../harfbuzz/upstream/OT/Color/CPAL/CPAL.hh | 9 + .../harfbuzz/upstream/OT/Color/sbix/sbix.hh | 11 +- .../harfbuzz/upstream/OT/Color/svg/svg.hh | 701 +- .../upstream/OT/Layout/Common/Coverage.hh | 72 +- .../OT/Layout/Common/CoverageFormat1.hh | 8 +- .../OT/Layout/Common/CoverageFormat2.hh | 6 +- .../harfbuzz/upstream/OT/Layout/GDEF/GDEF.hh | 82 +- .../upstream/OT/Layout/GPOS/Anchor.hh | 14 +- .../upstream/OT/Layout/GPOS/AnchorFormat3.hh | 17 +- .../upstream/OT/Layout/GPOS/AnchorMatrix.hh | 7 + .../upstream/OT/Layout/GPOS/CursivePos.hh | 8 +- .../OT/Layout/GPOS/CursivePosFormat1.hh | 15 +- .../harfbuzz/upstream/OT/Layout/GPOS/GPOS.hh | 71 +- .../upstream/OT/Layout/GPOS/LigatureArray.hh | 19 +- .../upstream/OT/Layout/GPOS/MarkArray.hh | 10 +- .../upstream/OT/Layout/GPOS/MarkBasePos.hh | 8 +- .../OT/Layout/GPOS/MarkBasePosFormat1.hh | 33 +- .../upstream/OT/Layout/GPOS/MarkLigPos.hh | 8 +- .../OT/Layout/GPOS/MarkLigPosFormat1.hh | 18 +- .../upstream/OT/Layout/GPOS/MarkMarkPos.hh | 8 +- .../OT/Layout/GPOS/MarkMarkPosFormat1.hh | 32 +- .../upstream/OT/Layout/GPOS/PairPos.hh | 8 +- .../upstream/OT/Layout/GPOS/PairPosFormat1.hh | 31 +- .../upstream/OT/Layout/GPOS/PairPosFormat2.hh | 36 +- .../upstream/OT/Layout/GPOS/SinglePos.hh | 14 +- .../OT/Layout/GPOS/SinglePosFormat1.hh | 4 +- .../OT/Layout/GPOS/SinglePosFormat2.hh | 4 +- .../upstream/OT/Layout/GPOS/ValueFormat.hh | 15 +- .../upstream/OT/Layout/GSUB/AlternateSet.hh | 13 + .../upstream/OT/Layout/GSUB/AlternateSubst.hh | 14 +- .../OT/Layout/GSUB/AlternateSubstFormat1.hh | 15 +- .../upstream/OT/Layout/GSUB/Ligature.hh | 31 +- .../upstream/OT/Layout/GSUB/LigatureSet.hh | 30 +- .../upstream/OT/Layout/GSUB/LigatureSubst.hh | 14 +- .../OT/Layout/GSUB/LigatureSubstFormat1.hh | 39 +- .../upstream/OT/Layout/GSUB/MultipleSubst.hh | 14 +- .../OT/Layout/GSUB/MultipleSubstFormat1.hh | 2 +- .../OT/Layout/GSUB/ReverseChainSingleSubst.hh | 8 +- .../GSUB/ReverseChainSingleSubstFormat1.hh | 2 +- .../upstream/OT/Layout/GSUB/Sequence.hh | 2 +- .../upstream/OT/Layout/GSUB/SingleSubst.hh | 14 +- .../OT/Layout/GSUB/SingleSubstFormat1.hh | 17 +- .../OT/Layout/GSUB/SingleSubstFormat2.hh | 13 +- .../harfbuzz/upstream/OT/Layout/types.hh | 6 + .../harfbuzz/upstream/OT/Var/VARC/VARC.cc | 195 +- .../harfbuzz/upstream/OT/Var/VARC/VARC.hh | 241 +- .../upstream/OT/Var/VARC/coord-setter.hh | 40 +- .../upstream/OT/glyf/CompositeGlyph.hh | 2 +- thirdparty/harfbuzz/upstream/OT/glyf/Glyph.hh | 114 +- .../harfbuzz/upstream/OT/glyf/SimpleGlyph.hh | 20 +- thirdparty/harfbuzz/upstream/OT/glyf/glyf.hh | 241 +- .../harfbuzz/upstream/OT/glyf/path-builder.hh | 100 +- thirdparty/harfbuzz/upstream/OT/name/name.hh | 10 +- thirdparty/harfbuzz/upstream/addTable.py | 16 - .../upstream/check-c-linkage-decls.py | 37 - thirdparty/harfbuzz/upstream/check-externs.py | 20 - .../harfbuzz/upstream/check-header-guards.py | 34 - .../harfbuzz/upstream/check-includes.py | 51 - .../harfbuzz/upstream/check-libstdc++.py | 39 - .../harfbuzz/upstream/check-static-inits.py | 51 - thirdparty/harfbuzz/upstream/check-symbols.py | 74 - thirdparty/harfbuzz/upstream/fix_get_types.py | 15 - .../upstream/gen-arabic-joining-list.py | 106 - .../harfbuzz/upstream/gen-arabic-pua.py | 35 - .../harfbuzz/upstream/gen-arabic-table.py | 358 - thirdparty/harfbuzz/upstream/gen-def.py | 33 - .../harfbuzz/upstream/gen-emoji-table.py | 98 - .../harfbuzz/upstream/gen-harfbuzzcc.py | 24 - .../harfbuzz/upstream/gen-hb-version.py | 40 - .../harfbuzz/upstream/gen-indic-table.py | 700 - .../upstream/gen-os2-unicode-ranges.py | 50 - .../harfbuzz/upstream/gen-ragel-artifacts.py | 25 - thirdparty/harfbuzz/upstream/gen-tag-table.py | 1220 - thirdparty/harfbuzz/upstream/gen-ucd-table.py | 202 - thirdparty/harfbuzz/upstream/gen-use-table.py | 529 - .../upstream/gen-vowel-constraints.py | 229 - .../harfbuzz/upstream/graph/classdef-graph.hh | 4 +- .../harfbuzz/upstream/graph/coverage-graph.hh | 72 +- thirdparty/harfbuzz/upstream/graph/graph.hh | 332 +- .../upstream/graph/gsubgpos-context.hh | 1 + .../harfbuzz/upstream/graph/gsubgpos-graph.hh | 118 +- .../harfbuzz/upstream/graph/ligature-graph.hh | 514 + .../upstream/graph/markbasepos-graph.hh | 12 +- .../harfbuzz/upstream/graph/pairpos-graph.hh | 19 +- .../harfbuzz/upstream/graph/serialize.hh | 45 +- .../harfbuzz/upstream/graph/split-helpers.hh | 4 +- .../upstream/graph/test-classdef-graph.cc | 66 +- .../harfbuzz/upstream/harfbuzz-cairo.pc.in | 13 - .../upstream/harfbuzz-config.cmake.in | 32 - .../harfbuzz/upstream/harfbuzz-gobject.pc.in | 12 - .../harfbuzz/upstream/harfbuzz-icu.pc.in | 13 - .../harfbuzz/upstream/harfbuzz-subset.cc | 11 +- .../harfbuzz/upstream/harfbuzz-subset.pc.in | 12 - thirdparty/harfbuzz/upstream/harfbuzz.cc | 4 + thirdparty/harfbuzz/upstream/harfbuzz.pc.in | 13 - .../harfbuzz/upstream/hb-aat-layout-common.hh | 483 +- .../upstream/hb-aat-layout-kerx-table.hh | 224 +- .../upstream/hb-aat-layout-morx-table.hh | 428 +- .../upstream/hb-aat-layout-trak-table.hh | 189 +- thirdparty/harfbuzz/upstream/hb-aat-layout.cc | 79 +- thirdparty/harfbuzz/upstream/hb-aat-layout.hh | 6 +- thirdparty/harfbuzz/upstream/hb-aat-map.cc | 20 +- thirdparty/harfbuzz/upstream/hb-algs.hh | 336 +- thirdparty/harfbuzz/upstream/hb-alloc-pool.hh | 105 + thirdparty/harfbuzz/upstream/hb-array.hh | 10 +- thirdparty/harfbuzz/upstream/hb-atomic.hh | 160 +- thirdparty/harfbuzz/upstream/hb-bimap.hh | 2 +- thirdparty/harfbuzz/upstream/hb-bit-page.hh | 88 +- .../upstream/hb-bit-set-invertible.hh | 15 +- thirdparty/harfbuzz/upstream/hb-bit-set.hh | 92 +- thirdparty/harfbuzz/upstream/hb-bit-vector.hh | 195 + thirdparty/harfbuzz/upstream/hb-blob.hh | 14 + .../upstream/hb-buffer-deserialize-json.hh | 616 +- .../upstream/hb-buffer-deserialize-json.rl | 17 +- .../hb-buffer-deserialize-text-glyphs.hh | 841 +- .../hb-buffer-deserialize-text-glyphs.rl | 39 +- .../hb-buffer-deserialize-text-unicode.hh | 192 +- .../hb-buffer-deserialize-text-unicode.rl | 32 +- .../harfbuzz/upstream/hb-buffer-serialize.cc | 68 +- .../harfbuzz/upstream/hb-buffer-verify.cc | 41 +- thirdparty/harfbuzz/upstream/hb-buffer.cc | 107 +- thirdparty/harfbuzz/upstream/hb-buffer.h | 75 +- thirdparty/harfbuzz/upstream/hb-buffer.hh | 122 +- thirdparty/harfbuzz/upstream/hb-cache.hh | 62 +- .../harfbuzz/upstream/hb-cairo-utils.cc | 13 +- thirdparty/harfbuzz/upstream/hb-cairo.cc | 37 +- .../harfbuzz/upstream/hb-cff-interp-common.hh | 43 +- .../harfbuzz/upstream/hb-cff-specializer.hh | 273 + .../upstream/hb-cff-width-optimizer.hh | 207 + .../harfbuzz/upstream/hb-cff2-interp-cs.hh | 70 +- thirdparty/harfbuzz/upstream/hb-common.cc | 111 +- thirdparty/harfbuzz/upstream/hb-common.h | 443 +- thirdparty/harfbuzz/upstream/hb-config.hh | 22 +- .../harfbuzz/upstream/hb-coretext-font.cc | 218 +- .../harfbuzz/upstream/hb-coretext-shape.cc | 444 +- thirdparty/harfbuzz/upstream/hb-coretext.cc | 581 + thirdparty/harfbuzz/upstream/hb-coretext.h | 4 + ...hb-gobject-enums.h.tmpl => hb-coretext.hh} | 37 +- thirdparty/harfbuzz/upstream/hb-cplusplus.hh | 58 +- thirdparty/harfbuzz/upstream/hb-debug.hh | 48 +- thirdparty/harfbuzz/upstream/hb-decycler.hh | 164 + thirdparty/harfbuzz/upstream/hb-deprecated.h | 82 +- .../harfbuzz/upstream/hb-directwrite-font.cc | 392 + .../harfbuzz/upstream/hb-directwrite-shape.cc | 656 + .../harfbuzz/upstream/hb-directwrite.cc | 1038 +- thirdparty/harfbuzz/upstream/hb-directwrite.h | 33 +- .../harfbuzz/upstream/hb-directwrite.hh | 223 + thirdparty/harfbuzz/upstream/hb-draw.cc | 107 +- thirdparty/harfbuzz/upstream/hb-draw.h | 2 +- thirdparty/harfbuzz/upstream/hb-draw.hh | 60 +- .../harfbuzz/upstream/hb-face-builder.cc | 3 +- thirdparty/harfbuzz/upstream/hb-face.cc | 276 +- thirdparty/harfbuzz/upstream/hb-face.h | 25 +- thirdparty/harfbuzz/upstream/hb-face.hh | 6 +- thirdparty/harfbuzz/upstream/hb-features.h.in | 119 - thirdparty/harfbuzz/upstream/hb-font.cc | 845 +- thirdparty/harfbuzz/upstream/hb-font.h | 218 +- thirdparty/harfbuzz/upstream/hb-font.hh | 706 +- thirdparty/harfbuzz/upstream/hb-fontations.h | 56 + .../upstream/{hb-pool.hh => hb-free-pool.hh} | 14 +- thirdparty/harfbuzz/upstream/hb-ft-colr.hh | 161 +- thirdparty/harfbuzz/upstream/hb-ft.cc | 385 +- thirdparty/harfbuzz/upstream/hb-ft.h | 13 +- thirdparty/harfbuzz/upstream/hb-geometry.hh | 276 +- thirdparty/harfbuzz/upstream/hb-glib.cc | 8 - .../upstream/hb-gobject-enums.cc.tmpl | 80 - .../harfbuzz/upstream/hb-gobject-structs.cc | 6 - thirdparty/harfbuzz/upstream/hb-graphite2.cc | 4 +- thirdparty/harfbuzz/upstream/hb-harfrust.cc | 209 + thirdparty/harfbuzz/upstream/hb-iter.hh | 11 +- thirdparty/harfbuzz/upstream/hb-kbts.cc | 325 + thirdparty/harfbuzz/upstream/hb-kern.hh | 2 +- thirdparty/harfbuzz/upstream/hb-limits.hh | 20 +- thirdparty/harfbuzz/upstream/hb-machinery.hh | 26 +- thirdparty/harfbuzz/upstream/hb-map.hh | 51 +- thirdparty/harfbuzz/upstream/hb-mutex.hh | 6 + thirdparty/harfbuzz/upstream/hb-null.hh | 2 +- thirdparty/harfbuzz/upstream/hb-object.hh | 23 +- thirdparty/harfbuzz/upstream/hb-open-file.hh | 14 +- thirdparty/harfbuzz/upstream/hb-open-type.hh | 408 +- .../harfbuzz/upstream/hb-ot-cff-common.hh | 2 +- .../harfbuzz/upstream/hb-ot-cff1-std-str.hh | 782 +- .../harfbuzz/upstream/hb-ot-cff1-table.cc | 9 - .../harfbuzz/upstream/hb-ot-cff1-table.hh | 15 +- .../harfbuzz/upstream/hb-ot-cff2-table.cc | 25 +- .../harfbuzz/upstream/hb-ot-cff2-table.hh | 19 +- .../harfbuzz/upstream/hb-ot-cmap-table.hh | 304 +- thirdparty/harfbuzz/upstream/hb-ot-color.cc | 76 +- thirdparty/harfbuzz/upstream/hb-ot-color.h | 14 + .../upstream/hb-ot-face-table-list.hh | 9 +- thirdparty/harfbuzz/upstream/hb-ot-face.cc | 2 + thirdparty/harfbuzz/upstream/hb-ot-font.cc | 833 +- .../harfbuzz/upstream/hb-ot-hdmx-table.hh | 2 +- .../harfbuzz/upstream/hb-ot-hmtx-table.hh | 75 +- .../harfbuzz/upstream/hb-ot-kern-table.hh | 26 +- .../upstream/hb-ot-layout-base-table.hh | 24 +- .../harfbuzz/upstream/hb-ot-layout-common.hh | 775 +- .../upstream/hb-ot-layout-gpos-table.hh | 10 +- .../upstream/hb-ot-layout-gsub-table.hh | 10 +- .../upstream/hb-ot-layout-gsubgpos.hh | 1153 +- thirdparty/harfbuzz/upstream/hb-ot-layout.cc | 197 +- thirdparty/harfbuzz/upstream/hb-ot-layout.h | 6 + thirdparty/harfbuzz/upstream/hb-ot-layout.hh | 47 +- thirdparty/harfbuzz/upstream/hb-ot-map.cc | 14 + thirdparty/harfbuzz/upstream/hb-ot-map.hh | 3 + .../harfbuzz/upstream/hb-ot-math-table.hh | 20 + thirdparty/harfbuzz/upstream/hb-ot-math.cc | 14 + .../harfbuzz/upstream/hb-ot-os2-table.hh | 4 +- .../harfbuzz/upstream/hb-ot-post-macroman.hh | 516 +- .../harfbuzz/upstream/hb-ot-post-table.hh | 2 +- .../harfbuzz/upstream/hb-ot-shape-fallback.cc | 38 +- .../upstream/hb-ot-shape-normalize.cc | 12 +- .../upstream/hb-ot-shape-normalize.hh | 2 +- thirdparty/harfbuzz/upstream/hb-ot-shape.cc | 289 +- thirdparty/harfbuzz/upstream/hb-ot-shape.h | 6 + thirdparty/harfbuzz/upstream/hb-ot-shape.hh | 17 +- .../upstream/hb-ot-shaper-arabic-fallback.hh | 2 + .../hb-ot-shaper-arabic-joining-list.hh | 8 +- .../upstream/hb-ot-shaper-arabic-pua.hh | 138 +- .../upstream/hb-ot-shaper-arabic-table.hh | 275 +- .../harfbuzz/upstream/hb-ot-shaper-arabic.cc | 49 +- .../harfbuzz/upstream/hb-ot-shaper-hangul.cc | 8 +- .../upstream/hb-ot-shaper-indic-machine.hh | 1279 +- .../upstream/hb-ot-shaper-indic-machine.rl | 7 +- .../upstream/hb-ot-shaper-indic-table.cc | 499 +- .../harfbuzz/upstream/hb-ot-shaper-indic.cc | 50 +- .../harfbuzz/upstream/hb-ot-shaper-khmer.cc | 6 - .../upstream/hb-ot-shaper-myanmar-machine.hh | 642 +- .../upstream/hb-ot-shaper-myanmar-machine.rl | 9 +- .../harfbuzz/upstream/hb-ot-shaper-thai.cc | 18 +- .../upstream/hb-ot-shaper-use-machine.hh | 1256 +- .../upstream/hb-ot-shaper-use-machine.rl | 1 + .../upstream/hb-ot-shaper-use-table.hh | 1111 +- .../hb-ot-shaper-vowel-constraints.cc | 8 +- thirdparty/harfbuzz/upstream/hb-ot-shaper.hh | 6 + .../harfbuzz/upstream/hb-ot-stat-table.hh | 20 +- .../harfbuzz/upstream/hb-ot-tag-table.hh | 1473 +- thirdparty/harfbuzz/upstream/hb-ot-tag.cc | 153 +- .../harfbuzz/upstream/hb-ot-var-avar-table.hh | 178 +- .../harfbuzz/upstream/hb-ot-var-common.hh | 869 +- .../harfbuzz/upstream/hb-ot-var-cvar-table.hh | 35 +- .../harfbuzz/upstream/hb-ot-var-fvar-table.hh | 29 +- .../harfbuzz/upstream/hb-ot-var-gvar-table.hh | 412 +- .../harfbuzz/upstream/hb-ot-var-hvar-table.hh | 111 +- thirdparty/harfbuzz/upstream/hb-ot-var.cc | 28 +- .../harfbuzz/upstream/hb-ot-vorg-table.hh | 1 + thirdparty/harfbuzz/upstream/hb-outline.cc | 15 + thirdparty/harfbuzz/upstream/hb-outline.hh | 2 + .../harfbuzz/upstream/hb-paint-bounded.cc | 207 + .../harfbuzz/upstream/hb-paint-bounded.hh | 117 + .../harfbuzz/upstream/hb-paint-extents.cc | 109 +- .../harfbuzz/upstream/hb-paint-extents.hh | 47 +- thirdparty/harfbuzz/upstream/hb-paint.cc | 58 +- thirdparty/harfbuzz/upstream/hb-paint.h | 55 +- thirdparty/harfbuzz/upstream/hb-paint.hh | 90 +- .../harfbuzz/upstream/hb-priority-queue.hh | 12 +- .../harfbuzz/upstream/hb-raster-draw.cc | 1386 + .../harfbuzz/upstream/hb-raster-image.cc | 967 + .../harfbuzz/upstream/hb-raster-image.hh | 63 + .../harfbuzz/upstream/hb-raster-paint.cc | 2253 ++ .../harfbuzz/upstream/hb-raster-paint.hh | 205 + .../harfbuzz/upstream/hb-raster-svg-base.cc | 501 + .../harfbuzz/upstream/hb-raster-svg-base.hh | 228 + .../harfbuzz/upstream/hb-raster-svg-bbox.cc | 109 + ...est-machinery.cc => hb-raster-svg-bbox.hh} | 31 +- .../harfbuzz/upstream/hb-raster-svg-clip.cc | 528 + .../harfbuzz/upstream/hb-raster-svg-clip.hh | 53 + .../harfbuzz/upstream/hb-raster-svg-color.cc | 340 + ...icode-ranges.cc => hb-raster-svg-color.hh} | 54 +- .../upstream/hb-raster-svg-context.hh | 113 + .../upstream/hb-raster-svg-defs-scan.cc | 108 + ...multimap.cc => hb-raster-svg-defs-scan.hh} | 65 +- .../harfbuzz/upstream/hb-raster-svg-defs.cc | 121 + .../harfbuzz/upstream/hb-raster-svg-defs.hh | 108 + .../harfbuzz/upstream/hb-raster-svg-fill.cc | 300 + .../harfbuzz/upstream/hb-raster-svg-fill.hh | 41 + .../upstream/hb-raster-svg-gradient.cc | 245 + .../upstream/hb-raster-svg-gradient.hh | 46 + .../harfbuzz/upstream/hb-raster-svg-parse.cc | 668 + .../harfbuzz/upstream/hb-raster-svg-parse.hh | 368 + .../harfbuzz/upstream/hb-raster-svg-render.cc | 548 + .../harfbuzz/upstream/hb-raster-svg-use.cc | 104 + ...os-size-params.cc => hb-raster-svg-use.hh} | 52 +- thirdparty/harfbuzz/upstream/hb-raster-svg.hh | 68 + .../harfbuzz/upstream/hb-raster-utils.hh | 81 + thirdparty/harfbuzz/upstream/hb-raster.cc | 68 + thirdparty/harfbuzz/upstream/hb-raster.h | 321 + thirdparty/harfbuzz/upstream/hb-repacker.hh | 27 +- thirdparty/harfbuzz/upstream/hb-sanitize.hh | 102 +- thirdparty/harfbuzz/upstream/hb-script-list.h | 496 + thirdparty/harfbuzz/upstream/hb-serialize.hh | 36 +- thirdparty/harfbuzz/upstream/hb-set-digest.hh | 180 +- thirdparty/harfbuzz/upstream/hb-set.hh | 5 + thirdparty/harfbuzz/upstream/hb-shape-plan.cc | 10 +- thirdparty/harfbuzz/upstream/hb-shape.cc | 14 +- thirdparty/harfbuzz/upstream/hb-shape.h | 2 + .../harfbuzz/upstream/hb-shaper-list.hh | 8 + thirdparty/harfbuzz/upstream/hb-static.cc | 24 +- .../harfbuzz/upstream/hb-string-array.hh | 12 +- .../harfbuzz/upstream/hb-subset-cff-common.cc | 8 +- .../harfbuzz/upstream/hb-subset-cff-common.hh | 36 +- .../harfbuzz/upstream/hb-subset-cff1.cc | 2 +- .../upstream/hb-subset-cff2-to-cff1.cc | 40 + .../upstream/hb-subset-cff2-to-cff1.hh | 177 + .../harfbuzz/upstream/hb-subset-cff2.cc | 596 +- .../harfbuzz/upstream/hb-subset-input.cc | 141 +- .../upstream/hb-subset-instancer-iup.cc | 121 +- .../upstream/hb-subset-instancer-iup.hh | 15 + .../upstream/hb-subset-instancer-solver.cc | 54 +- .../upstream/hb-subset-instancer-solver.hh | 22 +- .../upstream/hb-subset-plan-layout.cc | 420 + .../upstream/hb-subset-plan-member-list.hh | 4 + .../harfbuzz/upstream/hb-subset-plan-var.cc | 449 + .../harfbuzz/upstream/hb-subset-plan.cc | 805 +- .../harfbuzz/upstream/hb-subset-plan.hh | 97 +- .../harfbuzz/upstream/hb-subset-repacker.h | 81 - ...set-repacker.cc => hb-subset-serialize.cc} | 33 +- .../harfbuzz/upstream/hb-subset-serialize.h | 83 + .../harfbuzz/upstream/hb-subset-table-cff.cc | 143 + .../upstream/hb-subset-table-color.cc | 21 + .../upstream/hb-subset-table-layout.cc | 22 + .../upstream/hb-subset-table-other.cc | 31 + .../harfbuzz/upstream/hb-subset-table-var.cc | 45 + .../harfbuzz/upstream/hb-subset-table.hh | 217 + thirdparty/harfbuzz/upstream/hb-subset.cc | 474 +- thirdparty/harfbuzz/upstream/hb-subset.h | 45 +- thirdparty/harfbuzz/upstream/hb-subset.hh | 1 - thirdparty/harfbuzz/upstream/hb-ucd-table.hh | 10598 ++++--- .../upstream/hb-unicode-emoji-table.hh | 95 +- thirdparty/harfbuzz/upstream/hb-unicode.hh | 51 + thirdparty/harfbuzz/upstream/hb-utf.hh | 26 +- .../harfbuzz/upstream/hb-vector-svg-draw.cc | 740 + .../harfbuzz/upstream/hb-vector-svg-paint.cc | 1830 ++ .../harfbuzz/upstream/hb-vector-svg-path.cc | 144 + ...est-serialize.cc => hb-vector-svg-path.hh} | 37 +- .../harfbuzz/upstream/hb-vector-svg-subset.cc | 454 + .../harfbuzz/upstream/hb-vector-svg-subset.hh | 44 + .../harfbuzz/upstream/hb-vector-svg-utils.cc | 92 + .../harfbuzz/upstream/hb-vector-svg-utils.hh | 129 + thirdparty/harfbuzz/upstream/hb-vector-svg.hh | 366 + thirdparty/harfbuzz/upstream/hb-vector.cc | 41 + thirdparty/harfbuzz/upstream/hb-vector.h | 285 + thirdparty/harfbuzz/upstream/hb-vector.hh | 317 +- thirdparty/harfbuzz/upstream/hb-version.h | 6 +- thirdparty/harfbuzz/upstream/hb-version.h.in | 95 - thirdparty/harfbuzz/upstream/hb-wasm-shape.cc | 2 +- thirdparty/harfbuzz/upstream/hb-zlib.cc | 98 + thirdparty/harfbuzz/upstream/hb-zlib.hh | 37 + thirdparty/harfbuzz/upstream/hb.hh | 87 +- thirdparty/harfbuzz/upstream/justify.py | 288 - thirdparty/harfbuzz/upstream/main.cc | 533 - thirdparty/harfbuzz/upstream/meson.build | 1048 - thirdparty/harfbuzz/upstream/ms-use/COPYING | 21 - .../IndicPositionalCategory-Additional.txt | 123 - .../ms-use/IndicShapingInvalidCluster.txt | 113 - .../IndicSyllabicCategory-Additional.txt | 278 - thirdparty/harfbuzz/upstream/relative_to.py | 6 - thirdparty/harfbuzz/upstream/sample.py | 65 - thirdparty/harfbuzz/upstream/test-algs.cc | 110 - thirdparty/harfbuzz/upstream/test-array.cc | 79 - thirdparty/harfbuzz/upstream/test-bimap.cc | 76 - .../upstream/test-buffer-serialize.cc | 114 - thirdparty/harfbuzz/upstream/test-cff.cc | 75 - .../upstream/test-gsub-get-alternates.cc | 86 - .../upstream/test-gsub-would-substitute.cc | 67 - .../harfbuzz/upstream/test-item-varstore.cc | 66 - thirdparty/harfbuzz/upstream/test-iter.cc | 382 - thirdparty/harfbuzz/upstream/test-map.cc | 358 - thirdparty/harfbuzz/upstream/test-number.cc | 224 - .../harfbuzz/upstream/test-ot-glyphname.cc | 89 - thirdparty/harfbuzz/upstream/test-ot-meta.cc | 68 - thirdparty/harfbuzz/upstream/test-ot-name.cc | 74 - .../harfbuzz/upstream/test-priority-queue.cc | 81 - thirdparty/harfbuzz/upstream/test-repacker.cc | 2304 -- thirdparty/harfbuzz/upstream/test-set.cc | 165 - .../upstream/test-subset-instancer-solver.cc | 431 - .../harfbuzz/upstream/test-tuple-varstore.cc | 158 - .../harfbuzz/upstream/test-use-table.cc | 18 - thirdparty/harfbuzz/upstream/test-vector.cc | 191 - .../upstream/update-unicode-tables.make | 49 - .../harfbuzz/upstream/wasm/graphite/shape.cc | 250 + .../upstream/wasm/sample/c/shape-fallback.cc | 60 + .../upstream/wasm/sample/c/shape-ot.cc | 18 + thirdparty/libhydrogen/libhydrogen.c | 24 + thirdparty/libhydrogen/libhydrogen.h | 45 + thirdparty/libhydrogen/upstream/impl/common.h | 334 + thirdparty/libhydrogen/upstream/impl/core.h | 221 + .../libhydrogen/upstream/impl/gimli-core.h | 25 + .../upstream/impl/gimli-core/portable.h | 39 + .../upstream/impl/gimli-core/sse2.h | 112 + thirdparty/libhydrogen/upstream/impl/hash.h | 144 + .../libhydrogen/upstream/impl/hydrogen_p.h | 85 + thirdparty/libhydrogen/upstream/impl/kdf.h | 20 + thirdparty/libhydrogen/upstream/impl/kx.h | 535 + thirdparty/libhydrogen/upstream/impl/pwhash.h | 281 + thirdparty/libhydrogen/upstream/impl/random.h | 157 + .../libhydrogen/upstream/impl/random/avr.h | 63 + .../libhydrogen/upstream/impl/random/ch32.h | 35 + .../upstream/impl/random/cheriot.h | 22 + .../upstream/impl/random/chibios.h | 23 + .../libhydrogen/upstream/impl/random/esp32.h | 32 + .../upstream/impl/random/linux_kernel.h | 8 + .../libhydrogen/upstream/impl/random/mbed.h | 44 + .../upstream/impl/random/nrf52832.h | 41 + .../upstream/impl/random/particle.h | 26 + .../libhydrogen/upstream/impl/random/riot.h | 10 + .../upstream/impl/random/rtthread.h | 38 + .../libhydrogen/upstream/impl/random/stm32.h | 63 + .../libhydrogen/upstream/impl/random/unix.h | 85 + .../libhydrogen/upstream/impl/random/wasi.h | 12 + .../upstream/impl/random/windows.h | 20 + .../libhydrogen/upstream/impl/random/zephyr.h | 13 + .../libhydrogen/upstream/impl/secretbox.h | 236 + thirdparty/libhydrogen/upstream/impl/sign.h | 217 + thirdparty/libhydrogen/upstream/impl/x25519.h | 390 + thirdparty/libhydrogen/upstream/libhydrogen.c | 29 + thirdparty/libhydrogen/upstream/libhydrogen.h | 409 + thirdparty/libpng/libpng.c | 38 + thirdparty/libpng/upstream/LICENSE | 268 +- thirdparty/libpng/upstream/arm/arm_init.c | 277 +- thirdparty/libpng/upstream/arm/filter_neon.S | 61 - .../upstream/arm/filter_neon_intrinsics.c | 803 +- .../upstream/arm/palette_neon_intrinsics.c | 298 +- .../libpng/upstream/contrib/.editorconfig | 7 - .../libpng/upstream/contrib/arm-neon/README | 83 - .../upstream/contrib/arm-neon/android-ndk.c | 39 - .../upstream/contrib/arm-neon/linux-auxv.c | 120 - .../libpng/upstream/contrib/arm-neon/linux.c | 161 - thirdparty/libpng/upstream/example.c | 1040 + .../upstream/intel/filter_sse2_intrinsics.c | 799 +- thirdparty/libpng/upstream/intel/intel_init.c | 103 +- thirdparty/libpng/upstream/png.c | 8610 +++--- thirdparty/libpng/upstream/png.h | 6776 ++--- thirdparty/libpng/upstream/pngconf.h | 1238 +- thirdparty/libpng/upstream/pngdebug.h | 306 +- thirdparty/libpng/upstream/pngerror.c | 1808 +- thirdparty/libpng/upstream/pngget.c | 2636 +- thirdparty/libpng/upstream/pnginfo.h | 530 +- thirdparty/libpng/upstream/pnglibconf.h | 199 + thirdparty/libpng/upstream/pngmem.c | 571 +- thirdparty/libpng/upstream/pngpread.c | 2049 +- thirdparty/libpng/upstream/pngpriv.h | 4603 +-- thirdparty/libpng/upstream/pngread.c | 8433 +++--- thirdparty/libpng/upstream/pngrio.c | 239 +- thirdparty/libpng/upstream/pngrtran.c | 10219 +++---- thirdparty/libpng/upstream/pngrutil.c | 9363 +++---- thirdparty/libpng/upstream/pngset.c | 3858 +-- thirdparty/libpng/upstream/pngstruct.h | 943 +- thirdparty/libpng/upstream/pngtest.c | 2107 -- thirdparty/libpng/upstream/pngtrans.c | 1763 +- thirdparty/libpng/upstream/pngwio.c | 335 +- thirdparty/libpng/upstream/pngwrite.c | 4880 ++-- thirdparty/libpng/upstream/pngwtran.c | 1149 +- thirdparty/libpng/upstream/pngwutil.c | 5561 ++-- thirdparty/libwebp/libwebp.c | 2 + .../libwebp/upstream/src/dec/Makefile.am | 29 - .../libwebp/upstream/src/dec/Makefile.in | 797 - .../libwebp/upstream/src/demux/Makefile.am | 18 - .../libwebp/upstream/src/demux/Makefile.in | 748 - .../upstream/src/demux/libwebpdemux.pc.in | 11 - .../upstream/src/demux/libwebpdemux.rc | 41 - .../libwebp/upstream/src/dsp/Makefile.am | 187 - .../libwebp/upstream/src/dsp/Makefile.in | 1796 -- .../libwebp/upstream/src/enc/Makefile.am | 43 - .../libwebp/upstream/src/enc/Makefile.in | 963 - .../libwebp/upstream/src/mux/Makefile.am | 22 - .../libwebp/upstream/src/mux/Makefile.in | 756 - .../libwebp/upstream/src/mux/libwebpmux.pc.in | 12 - .../libwebp/upstream/src/mux/libwebpmux.rc | 41 - .../libwebp/upstream/src/utils/Makefile.am | 54 - .../libwebp/upstream/src/utils/Makefile.in | 761 - .../src/utils/quant_levels_dec_utils.c | 2 - thirdparty/libwebp/upstream/src/webp/config.h | 31 + .../libwebp/upstream/src/webp/config.h.in | 151 - thirdparty/luau/luau.cpp | 59 + thirdparty/luau/luau.h | 46 + thirdparty/luau/luau_split.cpp | 27 + .../upstream/Common/include/Luau/Bytecode.h | 683 + .../Common/include/Luau/BytecodeUtils.h | 43 + .../upstream/Common/include/Luau/Common.h | 150 + .../upstream/Common/include/Luau/DenseHash.h | 656 + .../Common/include/Luau/ExperimentalFlags.h | 31 + .../upstream/Common/include/Luau/HashUtil.h | 54 + .../Common/include/Luau/InsertionOrderedMap.h | 147 + .../Common/include/Luau/ScopedSeenSet.h | 29 + .../Common/include/Luau/SmallVector.h | 322 + .../Common/include/Luau/StringUtils.h | 39 + .../upstream/Common/include/Luau/TimeTrace.h | 240 + .../upstream/Common/include/Luau/Variant.h | 304 + .../upstream/Common/include/Luau/VecDeque.h | 476 + .../luau/upstream/Common/src/StringUtils.cpp | 315 + .../luau/upstream/Common/src/TimeTrace.cpp | 278 + thirdparty/luau/upstream/VM/include/lua.h | 502 + thirdparty/luau/upstream/VM/include/luaconf.h | 140 + thirdparty/luau/upstream/VM/include/lualib.h | 152 + thirdparty/luau/upstream/VM/src/lapi.cpp | 1670 ++ thirdparty/luau/upstream/VM/src/lapi.h | 8 + thirdparty/luau/upstream/VM/src/laux.cpp | 681 + thirdparty/luau/upstream/VM/src/lbaselib.cpp | 519 + thirdparty/luau/upstream/VM/src/lbitlib.cpp | 246 + thirdparty/luau/upstream/VM/src/lbuffer.cpp | 24 + thirdparty/luau/upstream/VM/src/lbuffer.h | 13 + thirdparty/luau/upstream/VM/src/lbuflib.cpp | 366 + thirdparty/luau/upstream/VM/src/lbuiltins.cpp | 2160 ++ thirdparty/luau/upstream/VM/src/lbuiltins.h | 9 + thirdparty/luau/upstream/VM/src/lbytecode.h | 6 + thirdparty/luau/upstream/VM/src/lcommon.h | 46 + thirdparty/luau/upstream/VM/src/lcorolib.cpp | 269 + thirdparty/luau/upstream/VM/src/ldblib.cpp | 192 + thirdparty/luau/upstream/VM/src/ldebug.cpp | 675 + thirdparty/luau/upstream/VM/src/ldebug.h | 34 + thirdparty/luau/upstream/VM/src/ldo.cpp | 794 + thirdparty/luau/upstream/VM/src/ldo.h | 79 + thirdparty/luau/upstream/VM/src/lfunc.cpp | 211 + thirdparty/luau/upstream/VM/src/lfunc.h | 20 + thirdparty/luau/upstream/VM/src/lgc.cpp | 1313 + thirdparty/luau/upstream/VM/src/lgc.h | 145 + thirdparty/luau/upstream/VM/src/lgcdebug.cpp | 917 + thirdparty/luau/upstream/VM/src/linit.cpp | 95 + thirdparty/luau/upstream/VM/src/lmathlib.cpp | 537 + thirdparty/luau/upstream/VM/src/lmem.cpp | 710 + thirdparty/luau/upstream/VM/src/lmem.h | 33 + thirdparty/luau/upstream/VM/src/lnumprint.cpp | 369 + thirdparty/luau/upstream/VM/src/lnumutils.h | 85 + thirdparty/luau/upstream/VM/src/lobject.cpp | 162 + thirdparty/luau/upstream/VM/src/lobject.h | 491 + thirdparty/luau/upstream/VM/src/loslib.cpp | 225 + thirdparty/luau/upstream/VM/src/lperf.cpp | 69 + thirdparty/luau/upstream/VM/src/lstate.cpp | 252 + thirdparty/luau/upstream/VM/src/lstate.h | 305 + thirdparty/luau/upstream/VM/src/lstring.cpp | 193 + thirdparty/luau/upstream/VM/src/lstring.h | 29 + thirdparty/luau/upstream/VM/src/lstrlib.cpp | 1679 ++ thirdparty/luau/upstream/VM/src/ltable.cpp | 890 + thirdparty/luau/upstream/VM/src/ltable.h | 37 + thirdparty/luau/upstream/VM/src/ltablib.cpp | 628 + thirdparty/luau/upstream/VM/src/ltm.cpp | 159 + thirdparty/luau/upstream/VM/src/ltm.h | 57 + thirdparty/luau/upstream/VM/src/ludata.cpp | 43 + thirdparty/luau/upstream/VM/src/ludata.h | 17 + thirdparty/luau/upstream/VM/src/lutf8lib.cpp | 296 + thirdparty/luau/upstream/VM/src/lveclib.cpp | 360 + thirdparty/luau/upstream/VM/src/lvm.h | 37 + .../luau/upstream/VM/src/lvmexecute.cpp | 3155 +++ thirdparty/luau/upstream/VM/src/lvmload.cpp | 694 + thirdparty/luau/upstream/VM/src/lvmutils.cpp | 638 + .../rive/include/rive/advance_flags.hpp | 3 +- .../rive/include/rive/advancing_component.hpp | 2 +- .../rive/animation/blend_animation_direct.hpp | 1 + .../data_converter_range_mapper_flags.hpp | 5 +- .../data_converter_to_string_flags.hpp | 8 +- .../include/rive/animation/focus_action.hpp | 15 + .../rive/animation/focus_action_target.hpp | 14 + .../rive/animation/focus_action_traversal.hpp | 14 + .../rive/animation/focus_listener_group.hpp | 50 + .../rive/include/rive/animation/hittable.hpp | 22 - .../animation/keyboard_listener_group.hpp | 47 + .../rive/animation/keyframe_interpolator.hpp | 2 +- .../rive/animation/linear_animation.hpp | 3 + .../rive/animation/listener_action.hpp | 28 +- .../rive/animation/listener_align_target.hpp | 3 +- .../rive/animation/listener_bool_change.hpp | 3 +- .../rive/animation/listener_fire_event.hpp | 3 +- .../rive/animation/listener_invocation.hpp | 248 + .../rive/animation/listener_number_change.hpp | 3 +- .../animation/listener_trigger_change.hpp | 3 +- .../listener_types/listener_input_type.hpp | 14 + .../listener_input_type_event.hpp | 13 + .../listener_input_type_keyboard.hpp | 41 + .../listener_input_type_semantic.hpp | 38 + .../listener_input_type_text.hpp | 12 + .../listener_input_type_viewmodel.hpp | 19 + .../animation/listener_viewmodel_change.hpp | 3 +- .../animation/nested_linear_animation.hpp | 1 + .../rive/animation/nested_state_machine.hpp | 19 +- .../animation/scripted_listener_action.hpp | 36 + .../scripted_transition_condition.hpp | 35 + .../animation/semantic_listener_group.hpp | 50 + .../include/rive/animation/state_machine.hpp | 7 + .../animation/state_machine_fire_action.hpp | 25 + .../animation/state_machine_fire_event.hpp | 13 +- .../animation/state_machine_fire_trigger.hpp | 20 + .../rive/animation/state_machine_instance.hpp | 189 +- .../rive/animation/state_machine_layer.hpp | 2 - .../state_machine_layer_component.hpp | 13 +- .../rive/animation/state_machine_listener.hpp | 22 +- .../state_machine_listener_single.hpp | 23 + .../rive/animation/state_transition.hpp | 7 + .../animation/text_input_listener_group.hpp | 40 + .../rive/animation/transition_comparator.hpp | 20 +- ...ransition_property_artboard_comparator.hpp | 11 +- ...ansition_property_component_comparator.hpp | 13 + ...ansition_property_viewmodel_comparator.hpp | 9 +- .../animation/transition_self_comparator.hpp | 13 + .../transition_value_artboard_comparator.hpp | 12 + .../transition_value_asset_comparator.hpp | 13 + .../transition_value_boolean_comparator.hpp | 8 +- .../transition_value_color_comparator.hpp | 8 +- .../transition_value_id_comparator.hpp | 11 + .../transition_value_number_comparator.hpp | 8 +- .../transition_value_string_comparator.hpp | 8 +- .../transition_viewmodel_condition.hpp | 714 + thirdparty/rive/include/rive/artboard.hpp | 281 +- .../include/rive/artboard_component_list.hpp | 203 +- .../rive/include/rive/artboard_host.hpp | 29 +- .../include/rive/artboard_list_map_rule.hpp | 14 + .../rive/include/rive/artboard_referencer.hpp | 33 + .../rive/include/rive/assets/blob_asset.hpp | 21 + .../rive/include/rive/assets/file_asset.hpp | 8 +- .../rive/assets/file_asset_contents.hpp | 4 + .../rive/assets/file_asset_referencer.hpp | 7 +- .../include/rive/assets/manifest_asset.hpp | 31 + .../rive/include/rive/assets/script_asset.hpp | 244 + .../rive/include/rive/assets/shader_asset.hpp | 72 + .../rive/include/rive/assets/text_asset.hpp | 37 + .../rive/include/rive/async/work_pool.hpp | 89 + .../rive/include/rive/async/work_task.hpp | 78 + .../rive/include/rive/audio/audio_engine.hpp | 16 + .../rive/include/rive/audio/audio_sound.hpp | 6 + .../rive/include/rive/audio/audio_source.hpp | 13 + thirdparty/rive/include/rive/audio_event.hpp | 4 +- .../rive/include/rive/bindable_artboard.hpp | 23 + .../rive/include/rive/command_queue.hpp | 657 +- .../rive/include/rive/command_server.hpp | 213 +- thirdparty/rive/include/rive/component.hpp | 11 + .../rive/include/rive/component_dirt.hpp | 10 +- .../rive/constraints/constrainable_list.hpp | 23 + .../include/rive/constraints/constraint.hpp | 2 +- .../rive/constraints/draggable_constraint.hpp | 60 +- .../constraints/follow_path_constraint.hpp | 9 +- .../rive/constraints/layout_constraint.hpp | 2 + .../rive/constraints/list_constraint.hpp | 16 + .../list_follow_path_constraint.hpp | 27 + .../scrolling/clamped_scroll_physics.hpp | 9 +- .../scrolling/elastic_scroll_physics.hpp | 51 +- .../scrolling/scroll_bar_constraint_proxy.hpp | 22 +- .../scrolling/scroll_constraint.hpp | 147 +- .../scrolling/scroll_constraint_proxy.hpp | 7 +- .../constraints/scrolling/scroll_physics.hpp | 39 +- .../scrolling/scroll_virtualizer.hpp | 41 + .../rive/include/rive/container_component.hpp | 12 + .../include/rive/core/binary_data_reader.hpp | 1 + .../rive/include/rive/core/binary_reader.hpp | 5 + .../rive/core/field_types/core_bool_type.hpp | 5 +- .../rive/core/field_types/core_bytes_type.hpp | 3 + .../rive/core/field_types/core_color_type.hpp | 3 + .../core/field_types/core_double_type.hpp | 3 + .../core/field_types/core_string_type.hpp | 3 + .../rive/core/field_types/core_uint_type.hpp | 3 + thirdparty/rive/include/rive/core/reader.h | 4 +- .../include/rive/core/type_conversions.hpp | 30 + .../rive/core/vector_binary_stream.hpp | 37 + .../rive/core/vector_binary_writer.hpp | 1 + .../include/rive/custom_property_color.hpp | 13 + .../rive/custom_property_container.hpp | 27 + .../include/rive/custom_property_enum.hpp | 13 + .../include/rive/custom_property_group.hpp | 4 +- .../include/rive/custom_property_trigger.hpp | 21 + .../data_bind/bindable_property_artboard.hpp | 14 + .../data_bind/bindable_property_asset.hpp | 11 + .../rive/data_bind/bindable_property_id.hpp | 13 + .../rive/data_bind/bindable_property_list.hpp | 13 + .../data_bind/bindable_property_viewmodel.hpp | 39 + .../context/context_target_value.hpp | 31 + .../rive/data_bind/context/context_value.hpp | 77 +- .../data_bind/context/context_value_any.hpp | 17 + .../context/context_value_artboard.hpp | 19 + .../context/context_value_asset_image.hpp | 10 +- .../context/context_value_boolean.hpp | 8 - .../data_bind/context/context_value_color.hpp | 8 - .../data_bind/context/context_value_enum.hpp | 8 - .../context/context_value_number.hpp | 8 - .../context/context_value_string.hpp | 8 - .../context_value_symbol_list_index.hpp | 8 - .../context/context_value_trigger.hpp | 8 - .../context/context_value_viewmodel.hpp | 19 + .../data_bind/converters/data_converter.hpp | 10 +- .../converters/data_converter_formula.hpp | 11 +- .../converters/data_converter_group.hpp | 13 +- .../data_converter_interpolator.hpp | 131 +- .../data_converter_list_to_length.hpp | 21 + .../data_converter_number_to_list.hpp | 5 +- .../converters/data_converter_to_number.hpp | 26 + .../converters/data_converter_to_string.hpp | 1 + .../converters/formula/formula_token.hpp | 12 +- .../rive/include/rive/data_bind/data_bind.hpp | 35 +- .../rive/data_bind/data_bind_container.hpp | 38 + .../rive/data_bind/data_bind_context.hpp | 8 + .../data_bind_list_item_consumer.hpp | 6 +- .../include/rive/data_bind/data_bind_path.hpp | 29 + .../data_bind_viewmodel_consumer.hpp | 16 + .../include/rive/data_bind/data_context.hpp | 26 +- .../rive/data_bind/data_values/data_type.hpp | 10 +- .../rive/data_bind/data_values/data_value.hpp | 6 +- .../data_values/data_value_artboard.hpp | 22 + .../data_values/data_value_asset_image.hpp | 29 +- .../data_values/data_value_boolean.hpp | 4 +- .../data_values/data_value_color.hpp | 39 +- .../data_bind/data_values/data_value_enum.hpp | 13 +- .../data_values/data_value_integer.hpp | 8 +- .../data_bind/data_values/data_value_list.hpp | 13 +- .../data_values/data_value_number.hpp | 31 +- .../data_values/data_value_string.hpp | 6 +- .../data_value_symbol_list_index.hpp | 4 +- .../data_values/data_value_trigger.hpp | 6 +- .../data_values/data_value_viewmodel.hpp | 28 + .../rive/include/rive/data_bind_flags.hpp | 12 +- .../rive/data_bind_path_referencer.hpp | 23 + .../rive/include/rive/data_resolver.hpp | 15 + .../rive/include/rive/dependency_helper.hpp | 2 + thirdparty/rive/include/rive/drawable.hpp | 18 +- .../rive/include/rive/drawable_flag.hpp | 3 +- thirdparty/rive/include/rive/enum_bitset.hpp | 129 - thirdparty/rive/include/rive/enums.hpp | 178 + thirdparty/rive/include/rive/file.hpp | 139 +- thirdparty/rive/include/rive/focus_data.hpp | 96 + .../generated/animation/focus_action_base.hpp | 34 + .../animation/focus_action_target_base.hpp | 72 + .../animation/focus_action_traversal_base.hpp | 72 + .../animation/listener_action_base.hpp | 27 +- .../listener_input_type_base.hpp | 69 + .../listener_input_type_event_base.hpp | 71 + .../listener_input_type_keyboard_base.hpp | 36 + .../listener_input_type_semantic_base.hpp | 34 + .../listener_input_type_text_base.hpp | 36 + .../listener_input_type_viewmodel_base.hpp | 62 + .../scripted_listener_action_base.hpp | 71 + .../scripted_transition_condition_base.hpp | 71 + .../state_machine_fire_action_base.hpp | 68 + .../state_machine_fire_event_base.hpp | 28 +- .../state_machine_fire_trigger_base.hpp | 62 + .../animation/state_machine_listener_base.hpp | 38 +- .../state_machine_listener_single_base.hpp | 102 + ...ion_property_component_comparator_base.hpp | 91 + .../transition_self_comparator_base.hpp | 36 + ...nsition_value_artboard_comparator_base.hpp | 38 + ...transition_value_asset_comparator_base.hpp | 38 + .../transition_value_enum_comparator_base.hpp | 42 +- .../transition_value_id_comparator_base.hpp | 72 + .../include/rive/generated/artboard_base.hpp | 19 + .../generated/artboard_list_map_rule_base.hpp | 89 + .../rive/generated/assets/blob_asset_base.hpp | 37 + .../assets/file_asset_contents_base.hpp | 14 +- .../generated/assets/manifest_asset_base.hpp | 37 + .../generated/assets/script_asset_base.hpp | 95 + .../generated/assets/shader_asset_base.hpp | 38 + .../rive/generated/assets/text_asset_base.hpp | 72 + .../list_follow_path_constraint_base.hpp | 93 + .../scrolling/scroll_constraint_base.hpp | 72 + .../include/rive/generated/core_registry.hpp | 1545 +- .../generated/custom_property_color_base.hpp | 72 + .../generated/custom_property_enum_base.hpp | 90 + .../custom_property_trigger_base.hpp | 76 + .../bindable_property_artboard_base.hpp | 37 + .../bindable_property_asset_base.hpp | 42 +- .../data_bind/bindable_property_id_base.hpp | 70 + .../data_bind/bindable_property_list_base.hpp | 71 + .../bindable_property_viewmodel_base.hpp | 37 + .../data_converter_formula_base.hpp | 35 + .../data_converter_list_to_length_base.hpp | 36 + .../data_converter_to_number_base.hpp | 36 + .../data_bind/data_bind_path_base.hpp | 80 + .../rive/generated/focus_data_base.hpp | 126 + .../generated/inputs/keyboard_input_base.hpp | 107 + .../generated/inputs/semantic_input_base.hpp | 71 + .../rive/generated/inputs/user_input_base.hpp | 41 + .../artboard_component_list_override_base.hpp | 192 + .../rive/generated/nested_artboard_base.hpp | 56 + .../rive/include/rive/generated/node_base.hpp | 28 + .../generated/script_input_artboard_base.hpp | 72 + .../generated/script_input_boolean_base.hpp | 38 + .../generated/script_input_color_base.hpp | 38 + .../generated/script_input_number_base.hpp | 38 + .../generated/script_input_string_base.hpp | 38 + .../generated/script_input_trigger_base.hpp | 38 + .../script_input_viewmodel_property_base.hpp | 63 + .../scripted/scripted_data_converter_base.hpp | 71 + .../scripted/scripted_drawable_base.hpp | 76 + .../scripted/scripted_layout_base.hpp | 42 + .../scripted/scripted_path_effect_base.hpp | 72 + .../generated/semantic/semantic_data_base.hpp | 224 + .../rive/generated/shapes/image_base.hpp | 54 + .../rive/generated/shapes/list_path_base.hpp | 77 + .../shapes/paint/group_effect_base.hpp | 37 + .../shapes/paint/target_effect_base.hpp | 71 + .../shapes/points_common_path_base.hpp | 75 + .../generated/shapes/points_path_base.hpp | 42 +- .../include/rive/generated/text/text_base.hpp | 18 + .../rive/generated/text/text_input_base.hpp | 19 + .../generated/text/text_style_paint_base.hpp | 2 - .../viewmodel_instance_artboard_base.hpp | 72 + .../viewmodel_instance_asset_base.hpp | 1 + .../viewmodel_instance_asset_image_base.hpp | 1 + .../viewmodel/viewmodel_instance_base.hpp | 11 +- .../viewmodel_instance_boolean_base.hpp | 1 + .../viewmodel_instance_color_base.hpp | 1 + .../viewmodel_instance_enum_base.hpp | 1 + .../viewmodel_instance_list_base.hpp | 36 + .../viewmodel_instance_number_base.hpp | 1 + .../viewmodel_instance_string_base.hpp | 1 + .../viewmodel_instance_symbol_base.hpp | 1 + ...wmodel_instance_symbol_list_index_base.hpp | 1 + .../viewmodel_instance_trigger_base.hpp | 1 + .../viewmodel_instance_value_base.hpp | 11 +- .../viewmodel_instance_viewmodel_base.hpp | 1 + .../viewmodel_property_artboard_base.hpp | 37 + .../viewmodel/viewmodel_property_base.hpp | 53 + .../rive/include/rive/gesture_click_phase.hpp | 1 + .../rive/importers/backboard_importer.hpp | 15 +- .../importers/data_bind_path_importer.hpp | 20 + .../rive/importers/file_asset_importer.hpp | 18 +- .../listener_input_type_keyboard_importer.hpp | 26 + .../listener_input_type_semantic_importer.hpp | 26 + .../importers/scripted_object_importer.hpp | 23 + .../rive/importers/state_machine_importer.hpp | 2 + ...state_machine_layer_component_importer.hpp | 7 +- .../state_machine_listener_importer.hpp | 1 + .../rive/importers/text_asset_importer.hpp | 56 + ...ransition_viewmodel_condition_importer.hpp | 1 + .../rive/importers/viewmodel_importer.hpp | 4 + .../importers/viewmodel_instance_importer.hpp | 3 +- .../viewmodel_instance_list_importer.hpp | 3 +- .../include/rive/input/focus_listener.hpp | 23 + .../rive/include/rive/input/focus_manager.hpp | 149 + .../rive/include/rive/input/focus_node.hpp | 192 + .../rive/include/rive/input/focusable.hpp | 192 + .../include/rive/input/keyboard_listener.hpp | 27 + .../include/rive/inputs/keyboard_input.hpp | 15 + .../rive/inputs/keyboard_key_phase.hpp | 18 + .../include/rive/inputs/semantic_input.hpp | 14 + .../rive/include/rive/inputs/user_input.hpp | 13 + thirdparty/rive/include/rive/joystick.hpp | 2 +- .../rive/include/rive/joystick_flags.hpp | 5 +- .../artboard_component_list_override.hpp | 37 + .../rive/layout/layout_node_provider.hpp | 14 +- .../include/rive/layout/n_sliced_node.hpp | 1 + .../include/rive/layout/style_overrider.hpp | 103 + .../rive/include/rive/layout_component.hpp | 21 +- .../rive/include/rive/listener_group.hpp | 108 + .../rive/include/rive/listener_type.hpp | 11 +- .../rive/include/rive/lua/lua_state.hpp | 18 + .../rive/include/rive/lua/rive_lua_libs.hpp | 2093 ++ .../rive/include/rive/lua/scripting_vm.hpp | 78 + .../rive/include/rive/manifest_sections.hpp | 12 + thirdparty/rive/include/rive/math/aabb.hpp | 2 + thirdparty/rive/include/rive/math/bitwise.hpp | 258 + .../include/rive/math/contour_measure.hpp | 26 + thirdparty/rive/include/rive/math/mat2d.hpp | 2 + thirdparty/rive/include/rive/math/mat4.hpp | 402 + .../rive/include/rive/math/math_types.hpp | 51 - .../rive/include/rive/math/path_measure.hpp | 6 + thirdparty/rive/include/rive/math/random.hpp | 53 + .../rive/include/rive/math/raw_path.hpp | 4 +- thirdparty/rive/include/rive/math/simd.hpp | 25 + .../include/rive/math/simd_gvec_polyfill.hpp | 187 +- thirdparty/rive/include/rive/math/vec2d.hpp | 2 +- .../rive/include/rive/nested_animation.hpp | 10 + .../rive/include/rive/nested_artboard.hpp | 70 +- .../include/rive/nested_artboard_layout.hpp | 15 +- thirdparty/rive/include/rive/node.hpp | 6 + .../rive/include/rive/parent_traversal.hpp | 69 + .../rive/include/rive/pointer_event.hpp | 1 - .../rive/profiler/microprofile_emscripten.h | 32 + .../include/rive/profiler/profiler_macros.h | 151 + .../include/rive/profiler/rive_profile.hpp | 165 + .../rive/include/rive/property_recorder.hpp | 86 + thirdparty/rive/include/rive/random_mode.hpp | 12 + thirdparty/rive/include/rive/refcnt.hpp | 14 + thirdparty/rive/include/rive/renderer.hpp | 14 +- .../rive/include/rive/resetting_component.hpp | 15 + thirdparty/rive/include/rive/rive_types.hpp | 18 +- thirdparty/rive/include/rive/scene.hpp | 10 +- .../include/rive/script_input_artboard.hpp | 42 + .../include/rive/script_input_boolean.hpp | 31 + .../rive/include/rive/script_input_color.hpp | 31 + .../rive/include/rive/script_input_number.hpp | 31 + .../rive/include/rive/script_input_string.hpp | 31 + .../include/rive/script_input_trigger.hpp | 22 + .../rive/script_input_viewmodel_property.hpp | 34 + .../rive/scripted/scripted_data_converter.hpp | 70 + .../rive/scripted/scripted_drawable.hpp | 99 + .../include/rive/scripted/scripted_layout.hpp | 36 + .../include/rive/scripted/scripted_object.hpp | 123 + .../rive/scripted/scripted_path_effect.hpp | 69 + .../include/rive/semantic/semantic_data.hpp | 79 + .../include/rive/semantic/semantic_dirt.hpp | 21 + .../rive/semantic/semantic_listener.hpp | 26 + .../rive/semantic/semantic_manager.hpp | 100 + .../include/rive/semantic/semantic_node.hpp | 137 + .../rive/semantic/semantic_provider.hpp | 36 + .../include/rive/semantic/semantic_role.hpp | 71 + .../rive/semantic/semantic_snapshot.hpp | 92 + .../include/rive/semantic/semantic_state.hpp | 69 + .../include/rive/semantic/semantic_trait.hpp | 74 + .../rive/include/rive/shape_paint_type.hpp | 11 + .../include/rive/shapes/clipping_shape.hpp | 104 + thirdparty/rive/include/rive/shapes/image.hpp | 9 +- .../rive/include/rive/shapes/list_path.hpp | 95 + .../include/rive/shapes/paint/blend_mode.hpp | 4 +- .../rive/include/rive/shapes/paint/color.hpp | 2 + .../rive/include/rive/shapes/paint/dash.hpp | 2 +- .../include/rive/shapes/paint/dash_path.hpp | 39 +- .../rive/shapes/paint/effects_container.hpp | 37 + .../include/rive/shapes/paint/feather.hpp | 7 + .../rive/include/rive/shapes/paint/fill.hpp | 2 + .../rive/shapes/paint/group_effect.hpp | 33 + .../rive/shapes/paint/image_sampler.hpp | 25 +- .../include/rive/shapes/paint/shape_paint.hpp | 19 +- .../rive/shapes/paint/shape_paint_mutator.hpp | 3 +- .../rive/include/rive/shapes/paint/stroke.hpp | 16 +- .../rive/shapes/paint/stroke_effect.hpp | 45 +- .../rive/shapes/paint/target_effect.hpp | 38 + .../include/rive/shapes/paint/trim_path.hpp | 31 +- thirdparty/rive/include/rive/shapes/path.hpp | 2 + .../rive/shapes/points_common_path.hpp | 16 + .../rive/include/rive/shapes/points_path.hpp | 3 - thirdparty/rive/include/rive/shapes/shape.hpp | 13 +- .../include/rive/shapes/shape_path_flags.hpp | 2 - .../include/rive/signed_content_header.hpp | 84 + thirdparty/rive/include/rive/simple_array.hpp | 30 +- thirdparty/rive/include/rive/solo.hpp | 4 + thirdparty/rive/include/rive/text/font_hb.hpp | 19 + .../rive/include/rive/text/glyph_lookup.hpp | 6 +- .../rive/include/rive/text/raw_text.hpp | 28 +- .../rive/include/rive/text/raw_text_input.hpp | 3 +- thirdparty/rive/include/rive/text/text.hpp | 126 +- .../rive/include/rive/text/text_input.hpp | 73 +- .../include/rive/text/text_input_drawable.hpp | 1 + .../rive/text/text_input_selected_text.hpp | 1 + .../rive/include/rive/text/text_style.hpp | 16 +- .../include/rive/text/text_style_paint.hpp | 6 +- .../rive/include/rive/text/text_value_run.hpp | 13 +- thirdparty/rive/include/rive/text_engine.hpp | 69 + .../rive/include/rive/texture_archive.hpp | 91 + .../rive/include/rive/transform_component.hpp | 1 + .../rive/include/rive/typed_children.hpp | 18 +- .../viewmodel/property_symbol_dependent.hpp | 69 + .../viewmodel_instance_artboard_runtime.hpp | 30 + ...viewmodel_instance_asset_image_runtime.hpp | 5 + .../viewmodel_instance_boolean_runtime.hpp | 1 + .../viewmodel_instance_color_runtime.hpp | 1 + .../viewmodel_instance_enum_runtime.hpp | 2 + .../viewmodel_instance_list_runtime.hpp | 9 +- .../viewmodel_instance_number_runtime.hpp | 1 + .../runtime/viewmodel_instance_runtime.hpp | 15 +- .../viewmodel_instance_string_runtime.hpp | 1 + .../viewmodel_instance_trigger_runtime.hpp | 1 + .../viewmodel_instance_value_runtime.hpp | 11 +- .../viewmodel/runtime/viewmodel_runtime.hpp | 14 +- .../include/rive/viewmodel/symbol_type.hpp | 26 + .../rive/include/rive/viewmodel/viewmodel.hpp | 10 + .../rive/viewmodel/viewmodel_instance.hpp | 39 +- .../viewmodel/viewmodel_instance_artboard.hpp | 44 + .../viewmodel/viewmodel_instance_asset.hpp | 7 +- .../viewmodel_instance_asset_image.hpp | 8 +- .../viewmodel/viewmodel_instance_boolean.hpp | 5 +- .../viewmodel/viewmodel_instance_color.hpp | 3 +- .../viewmodel/viewmodel_instance_enum.hpp | 2 + .../viewmodel/viewmodel_instance_list.hpp | 47 +- .../viewmodel_instance_list_item.hpp | 2 +- .../viewmodel/viewmodel_instance_number.hpp | 5 +- .../viewmodel/viewmodel_instance_string.hpp | 3 +- .../viewmodel_instance_symbol_list_index.hpp | 5 +- .../viewmodel/viewmodel_instance_trigger.hpp | 5 +- .../viewmodel/viewmodel_instance_value.hpp | 79 +- .../viewmodel_instance_viewmodel.hpp | 45 +- .../rive/viewmodel/viewmodel_property.hpp | 26 + .../viewmodel/viewmodel_property_artboard.hpp | 13 + .../viewmodel/viewmodel_value_dependent.hpp | 16 + .../include/rive/virtualizing_component.hpp | 37 + .../utils/compile_time_string_hash.hpp | 8 +- .../rive/include/utils/no_op_renderer.hpp | 1 + thirdparty/rive/rive.cpp | 268 +- thirdparty/rive/rive.h | 6 +- .../rive/source/advancing_component.cpp | 17 +- .../rive/source/animation/animation_reset.cpp | 9 +- .../animation/animation_reset_factory.cpp | 4 +- .../rive/source/animation/animation_state.cpp | 2 +- .../animation/blend_animation_direct.cpp | 9 + .../rive/source/animation/blend_state_1d.cpp | 2 +- .../source/animation/blend_state_direct.cpp | 2 +- .../animation/blend_state_direct_instance.cpp | 4 + .../source/animation/focus_action_target.cpp | 41 + .../animation/focus_action_traversal.cpp | 47 + .../source/animation/focus_listener_group.cpp | 43 + thirdparty/rive/source/animation/hittable.cpp | 18 - .../animation/keyboard_listener_group.cpp | 177 + .../rive/source/animation/layer_state.cpp | 2 +- .../source/animation/linear_animation.cpp | 25 +- .../animation/linear_animation_instance.cpp | 3 + .../rive/source/animation/listener_action.cpp | 41 +- .../animation/listener_align_target.cpp | 16 +- .../source/animation/listener_bool_change.cpp | 4 +- .../source/animation/listener_fire_event.cpp | 5 +- .../source/animation/listener_invocation.cpp | 92 + .../animation/listener_number_change.cpp | 4 +- .../animation/listener_trigger_change.cpp | 4 +- .../listener_types/listener_input_type.cpp | 23 + .../listener_input_type_keyboard.cpp | 116 + .../listener_input_type_semantic.cpp | 71 + .../listener_input_type_viewmodel.cpp | 20 + .../animation/listener_viewmodel_change.cpp | 38 +- .../rive/source/animation/nested_bool.cpp | 3 +- .../animation/nested_linear_animation.cpp | 2 +- .../rive/source/animation/nested_number.cpp | 3 +- .../source/animation/nested_state_machine.cpp | 82 +- .../rive/source/animation/nested_trigger.cpp | 3 +- .../source/animation/property_recorder.cpp | 393 + .../animation/scripted_listener_action.cpp | 157 + .../scripted_transition_condition.cpp | 138 + .../animation/semantic_listener_group.cpp | 54 + .../rive/source/animation/state_machine.cpp | 7 + .../animation/state_machine_fire_action.cpp | 20 + .../animation/state_machine_fire_trigger.cpp | 36 + .../animation/state_machine_instance.cpp | 1896 +- .../animation/state_machine_listener.cpp | 47 +- .../state_machine_listener_single.cpp | 34 + .../animation/text_input_listener_group.cpp | 108 + .../animation/transition_comparator.cpp | 115 - ...ransition_property_artboard_comparator.cpp | 58 - ...ansition_property_viewmodel_comparator.cpp | 257 +- .../transition_value_boolean_comparator.cpp | 19 - .../transition_value_color_comparator.cpp | 19 - .../transition_value_enum_comparator.cpp | 4 - .../transition_value_number_comparator.cpp | 19 - .../transition_value_string_comparator.cpp | 19 - .../transition_viewmodel_condition.cpp | 1225 +- thirdparty/rive/source/artboard.cpp | 1496 +- .../rive/source/artboard_component_list.cpp | 1633 +- .../rive/source/artboard_list_map_rule.cpp | 21 + .../rive/source/artboard_referencer.cpp | 58 + thirdparty/rive/source/assets/audio_asset.cpp | 2 +- thirdparty/rive/source/assets/blob_asset.cpp | 11 + thirdparty/rive/source/assets/file_asset.cpp | 13 +- .../source/assets/file_asset_contents.cpp | 13 + .../source/assets/file_asset_referencer.cpp | 2 +- thirdparty/rive/source/assets/image_asset.cpp | 1 + .../rive/source/assets/manifest_asset.cpp | 164 + .../rive/source/assets/script_asset.cpp | 417 + .../rive/source/assets/shader_asset.cpp | 125 + thirdparty/rive/source/async/work_pool.cpp | 346 + thirdparty/rive/source/audio/audio_engine.cpp | 116 +- thirdparty/rive/source/audio/audio_sound.cpp | 48 + thirdparty/rive/source/audio/audio_source.cpp | 92 +- thirdparty/rive/source/audio_event.cpp | 23 +- thirdparty/rive/source/bindable_artboard.cpp | 8 + thirdparty/rive/source/command_queue.cpp | 1791 +- thirdparty/rive/source/command_server.cpp | 2988 +- thirdparty/rive/source/component.cpp | 36 +- .../source/constraints/constrainable_list.cpp | 24 + .../rive/source/constraints/constraint.cpp | 5 +- .../constraints/draggable_constraint.cpp | 86 + .../constraints/follow_path_constraint.cpp | 87 +- .../rive/source/constraints/ik_constraint.cpp | 34 +- .../source/constraints/list_constraint.cpp | 15 + .../list_follow_path_constraint.cpp | 64 + .../scrolling/clamped_scroll_physics.cpp | 22 +- .../scrolling/elastic_scroll_physics.cpp | 186 +- .../scrolling/scroll_bar_constraint_proxy.cpp | 9 +- .../scrolling/scroll_constraint.cpp | 473 +- .../scrolling/scroll_constraint_proxy.cpp | 67 +- .../constraints/scrolling/scroll_physics.cpp | 41 +- .../scrolling/scroll_virtualizer.cpp | 381 + .../constraints/transform_constraint.cpp | 2 +- .../rive/source/core/binary_data_reader.cpp | 20 + thirdparty/rive/source/core/binary_reader.cpp | 38 +- .../core/field_types/core_bool_type.cpp | 9 +- .../core/field_types/core_bytes_type.cpp | 9 +- .../core/field_types/core_color_type.cpp | 9 +- .../core/field_types/core_double_type.cpp | 18 +- .../core/field_types/core_string_type.cpp | 10 +- .../core/field_types/core_uint_type.cpp | 7 + .../rive/source/custom_property_container.cpp | 37 + .../context/context_target_value.cpp | 248 + .../data_bind/context/context_value.cpp | 104 +- .../data_bind/context/context_value_any.cpp | 81 + .../context/context_value_artboard.cpp | 38 + .../context/context_value_asset_image.cpp | 28 +- .../context/context_value_boolean.cpp | 14 - .../data_bind/context/context_value_color.cpp | 14 - .../data_bind/context/context_value_enum.cpp | 46 +- .../data_bind/context/context_value_list.cpp | 12 +- .../context/context_value_number.cpp | 37 +- .../context/context_value_string.cpp | 25 +- .../context_value_symbol_list_index.cpp | 14 - .../context/context_value_trigger.cpp | 14 - .../context/context_value_viewmodel.cpp | 43 + .../data_bind/converters/data_converter.cpp | 53 +- .../converters/data_converter_formula.cpp | 53 +- .../converters/data_converter_group.cpp | 13 + .../data_converter_interpolator.cpp | 181 +- .../data_converter_list_to_length.cpp | 21 + .../data_converter_number_to_list.cpp | 17 +- .../data_converter_operation_viewmodel.cpp | 1 + .../converters/data_converter_string_pad.cpp | 2 +- .../converters/data_converter_to_number.cpp | 77 + .../converters/data_converter_to_string.cpp | 40 +- .../converters/data_converter_trigger.cpp | 5 +- .../converters/formula/formula_token.cpp | 70 +- .../rive/source/data_bind/data_bind.cpp | 266 +- .../source/data_bind/data_bind_container.cpp | 178 + .../source/data_bind/data_bind_context.cpp | 51 +- .../data_bind_list_item_consumer.cpp | 8 + .../rive/source/data_bind/data_bind_path.cpp | 55 + .../data_bind_viewmodel_consumer.cpp | 17 + .../rive/source/data_bind/data_context.cpp | 152 +- .../rive/source/data_bind_path_referencer.cpp | 46 + thirdparty/rive/source/drawable.cpp | 52 +- thirdparty/rive/source/factory.cpp | 4 +- thirdparty/rive/source/file.cpp | 548 +- thirdparty/rive/source/focus_data.cpp | 612 + .../source/foreground_layout_drawable.cpp | 6 +- .../generated/animation/focus_action_base.cpp | 4 + .../animation/focus_action_target_base.cpp | 11 + .../animation/focus_action_traversal_base.cpp | 11 + .../listener_input_type_base.cpp | 11 + .../listener_input_type_event_base.cpp | 11 + .../listener_input_type_keyboard_base.cpp | 11 + .../listener_input_type_semantic_base.cpp | 11 + .../listener_input_type_text_base.cpp | 11 + .../listener_input_type_viewmodel_base.cpp | 11 + .../scripted_listener_action_base.cpp | 11 + .../scripted_transition_condition_base.cpp | 11 + .../state_machine_fire_action_base.cpp | 4 + .../animation/state_machine_fire_event.cpp | 12 - .../state_machine_fire_trigger_base.cpp | 11 + .../state_machine_listener_single_base.cpp | 11 + ...ion_property_component_comparator_base.cpp | 11 + .../transition_self_comparator_base.cpp | 11 + ...nsition_value_artboard_comparator_base.cpp | 11 + ...transition_value_asset_comparator_base.cpp | 11 + .../transition_value_id_comparator_base.cpp | 11 + .../generated/artboard_list_map_rule_base.cpp | 11 + .../generated/assets/blob_asset_base.cpp | 11 + .../generated/assets/manifest_asset_base.cpp | 11 + .../generated/assets/script_asset_base.cpp | 11 + .../generated/assets/shader_asset_base.cpp | 11 + .../list_follow_path_constraint_base.cpp | 11 + .../generated/custom_property_color_base.cpp | 11 + .../generated/custom_property_enum_base.cpp | 11 + .../custom_property_trigger_base.cpp | 11 + .../bindable_property_artboard_base.cpp | 11 + .../data_bind/bindable_property_list_base.cpp | 11 + .../bindable_property_viewmodel_base.cpp | 11 + .../data_converter_list_to_length_base.cpp | 11 + .../data_converter_to_number_base.cpp | 11 + .../data_bind/data_bind_path_base.cpp | 11 + .../rive/source/generated/focus_data_base.cpp | 11 + .../generated/inputs/keyboard_input_base.cpp | 11 + .../generated/inputs/semantic_input_base.cpp | 11 + .../generated/inputs/user_input_base.cpp | 11 + .../artboard_component_list_override_base.cpp | 11 + .../generated/script_input_artboard_base.cpp | 11 + .../generated/script_input_boolean_base.cpp | 11 + .../generated/script_input_color_base.cpp | 11 + .../generated/script_input_number_base.cpp | 11 + .../generated/script_input_string_base.cpp | 11 + .../generated/script_input_trigger_base.cpp | 11 + .../script_input_viewmodel_property_base.cpp | 11 + .../scripted/scripted_data_converter_base.cpp | 11 + .../scripted/scripted_drawable_base.cpp | 11 + .../scripted/scripted_layout_base.cpp | 11 + .../scripted/scripted_path_effect_base.cpp | 11 + .../generated/semantic/semantic_data_base.cpp | 11 + .../generated/shapes/list_path_base.cpp | 11 + .../shapes/paint/group_effect_base.cpp | 11 + .../shapes/paint/target_effect_base.cpp | 11 + .../generated/text/text_style_paint_base.cpp | 1 - .../viewmodel_instance_artboard_base.cpp | 11 + .../viewmodel_instance_value_base.cpp | 11 + .../viewmodel_property_artboard_base.cpp | 11 + .../source/importers/backboard_importer.cpp | 18 +- .../importers/data_bind_path_importer.cpp | 15 + .../data_converter_formula_importer.cpp | 2 +- .../source/importers/file_asset_importer.cpp | 20 +- .../listener_input_type_keyboard_importer.cpp | 13 + .../listener_input_type_semantic_importer.cpp | 13 + .../importers/scripted_object_importer.cpp | 22 + .../importers/state_machine_importer.cpp | 5 + ...state_machine_layer_component_importer.cpp | 12 +- .../state_machine_listener_importer.cpp | 7 + .../source/importers/text_asset_importer.cpp | 114 + ...ransition_viewmodel_condition_importer.cpp | 6 + .../viewmodel_instance_list_importer.cpp | 3 +- .../rive/source/input/focus_manager.cpp | 968 + thirdparty/rive/source/input/focus_node.cpp | 48 + thirdparty/rive/source/input/focusable.cpp | 23 + .../rive/source/inputs/keyboard_input.cpp | 28 + .../rive/source/inputs/semantic_input.cpp | 28 + .../artboard_component_list_override.cpp | 78 + thirdparty/rive/source/layout/axis.cpp | 9 +- .../source/layout/layout_component_style.cpp | 18 +- .../source/layout/layout_node_provider.cpp | 1 + .../rive/source/layout/n_sliced_node.cpp | 5 + thirdparty/rive/source/layout/n_slicer.cpp | 2 +- thirdparty/rive/source/layout_component.cpp | 202 +- thirdparty/rive/source/listener_group.cpp | 281 + thirdparty/rive/source/lua/lua_artboards.cpp | 840 + thirdparty/rive/source/lua/lua_audio.cpp | 477 + thirdparty/rive/source/lua/lua_buffer_ext.cpp | 538 + .../rive/source/lua/lua_data_context.cpp | 92 + thirdparty/rive/source/lua/lua_data_value.cpp | 412 + .../rive/source/lua/lua_image_decode.cpp | 467 + .../source/lua/lua_listener_invocation.cpp | 380 + thirdparty/rive/source/lua/lua_promise.cpp | 1323 + thirdparty/rive/source/lua/lua_properties.cpp | 1750 ++ thirdparty/rive/source/lua/lua_rive_base.cpp | 45 + .../rive/source/lua/lua_scripted_context.cpp | 639 + .../source/lua/lua_scripted_context_apple.mm | 4 + thirdparty/rive/source/lua/lua_state.cpp | 105 + thirdparty/rive/source/lua/math/lua_color.cpp | 173 + thirdparty/rive/source/lua/math/lua_input.cpp | 146 + thirdparty/rive/source/lua/math/lua_mat2d.cpp | 390 + thirdparty/rive/source/lua/math/lua_mat4.cpp | 402 + thirdparty/rive/source/lua/math/lua_math.cpp | 24 + thirdparty/rive/source/lua/math/lua_vec2d.cpp | 213 + .../rive/source/lua/renderer/lua_blob.cpp | 70 + .../rive/source/lua/renderer/lua_gpu.cpp | 3577 +++ .../rive/source/lua/renderer/lua_gpu_apple.mm | 4 + .../rive/source/lua/renderer/lua_gradient.cpp | 89 + .../rive/source/lua/renderer/lua_image.cpp | 140 + .../rive/source/lua/renderer/lua_mesh.cpp | 216 + .../rive/source/lua/renderer/lua_paint.cpp | 569 + .../rive/source/lua/renderer/lua_path.cpp | 655 + .../rive/source/lua/renderer/lua_renderer.cpp | 214 + .../lua/renderer/lua_renderer_library.cpp | 38 + thirdparty/rive/source/lua/rive_lua_libs.cpp | 1018 + .../rive/source/math/contour_measure.cpp | 21 +- thirdparty/rive/source/math/hit_test.cpp | 6 +- thirdparty/rive/source/math/path_measure.cpp | 61 + thirdparty/rive/source/math/random.cpp | 15 + thirdparty/rive/source/math/raw_path.cpp | 123 +- .../source/math/rectangles_to_contour.cpp | 9 +- thirdparty/rive/source/nested_artboard.cpp | 445 +- .../rive/source/nested_artboard_layout.cpp | 118 +- .../rive/source/nested_artboard_leaf.cpp | 7 +- thirdparty/rive/source/node.cpp | 16 + thirdparty/rive/source/parent_traversal.cpp | 61 + thirdparty/rive/source/profiler/profiler.cpp | 16 + .../rive/source/profiler/rive_profile.cpp | 374 + thirdparty/rive/source/renderer.cpp | 21 +- .../rive/source/resetting_component.cpp | 26 + thirdparty/rive/source/scene.cpp | 11 +- .../rive/source/script_input_artboard.cpp | 135 + .../rive/source/script_input_boolean.cpp | 67 + thirdparty/rive/source/script_input_color.cpp | 67 + .../rive/source/script_input_number.cpp | 67 + .../rive/source/script_input_string.cpp | 67 + .../rive/source/script_input_trigger.cpp | 66 + .../script_input_viewmodel_property.cpp | 156 + .../scripted/scripted_data_converter.cpp | 274 + .../source/scripted/scripted_drawable.cpp | 383 + .../rive/source/scripted/scripted_layout.cpp | 148 + .../rive/source/scripted/scripted_object.cpp | 525 + .../source/scripted/scripted_path_effect.cpp | 202 + .../rive/source/semantic/semantic_data.cpp | 572 + .../semantic/semantic_inference_registry.cpp | 97 + .../semantic/semantic_inference_registry.hpp | 14 + .../rive/source/semantic/semantic_manager.cpp | 1109 + .../source/semantic/semantic_provider.cpp | 148 + .../rive/source/shapes/clipping_shape.cpp | 138 +- thirdparty/rive/source/shapes/image.cpp | 203 +- thirdparty/rive/source/shapes/list_path.cpp | 324 + thirdparty/rive/source/shapes/mesh.cpp | 36 +- thirdparty/rive/source/shapes/paint/color.cpp | 2 +- thirdparty/rive/source/shapes/paint/dash.cpp | 14 +- .../rive/source/shapes/paint/dash_path.cpp | 197 +- .../source/shapes/paint/effects_container.cpp | 70 + .../rive/source/shapes/paint/feather.cpp | 36 +- thirdparty/rive/source/shapes/paint/fill.cpp | 12 + .../rive/source/shapes/paint/group_effect.cpp | 73 + .../source/shapes/paint/linear_gradient.cpp | 3 +- .../rive/source/shapes/paint/shape_paint.cpp | 90 +- .../source/shapes/paint/shape_paint_path.cpp | 1 + .../rive/source/shapes/paint/solid_color.cpp | 5 + .../rive/source/shapes/paint/stroke.cpp | 63 +- .../source/shapes/paint/stroke_effect.cpp | 66 + .../source/shapes/paint/target_effect.cpp | 121 + .../rive/source/shapes/paint/trim_path.cpp | 107 +- thirdparty/rive/source/shapes/path.cpp | 4 + .../rive/source/shapes/points_common_path.cpp | 15 + thirdparty/rive/source/shapes/points_path.cpp | 5 - thirdparty/rive/source/shapes/rectangle.cpp | 4 +- thirdparty/rive/source/shapes/shape.cpp | 83 +- .../source/shapes/shape_paint_container.cpp | 6 +- thirdparty/rive/source/shapes/slice_mesh.cpp | 29 +- thirdparty/rive/source/solo.cpp | 54 +- thirdparty/rive/source/static_scene.cpp | 2 + thirdparty/rive/source/text/cursor.cpp | 8 +- thirdparty/rive/source/text/font_hb.cpp | 620 +- thirdparty/rive/source/text/font_hb_apple.mm | 203 +- .../rive/source/text/fully_shaped_text.cpp | 1 - thirdparty/rive/source/text/glyph_lookup.cpp | 35 +- thirdparty/rive/source/text/line_breaker.cpp | 152 +- thirdparty/rive/source/text/raw_text.cpp | 82 +- .../rive/source/text/raw_text_input.cpp | 111 +- thirdparty/rive/source/text/text.cpp | 359 +- thirdparty/rive/source/text/text_engine.cpp | 6 +- thirdparty/rive/source/text/text_input.cpp | 635 +- .../rive/source/text/text_input_drawable.cpp | 39 +- .../source/text/text_input_selected_text.cpp | 13 + .../rive/source/text/text_modifier_group.cpp | 2 +- thirdparty/rive/source/text/text_style.cpp | 33 +- .../rive/source/text/text_style_paint.cpp | 16 + .../rive/source/text/text_value_run.cpp | 31 +- thirdparty/rive/source/texture_archive.cpp | 306 + .../viewmodel/property_symbol_dependent.cpp | 81 + .../viewmodel_instance_artboard_runtime.cpp | 31 + ...viewmodel_instance_asset_image_runtime.cpp | 9 + .../viewmodel_instance_enum_runtime.cpp | 10 + .../viewmodel_instance_list_runtime.cpp | 55 +- .../runtime/viewmodel_instance_runtime.cpp | 52 +- .../viewmodel_instance_value_runtime.cpp | 2 + .../viewmodel/runtime/viewmodel_runtime.cpp | 25 +- .../rive/source/viewmodel/viewmodel.cpp | 37 +- .../source/viewmodel/viewmodel_instance.cpp | 207 +- .../viewmodel/viewmodel_instance_artboard.cpp | 50 + .../viewmodel_instance_asset_image.cpp | 50 +- .../viewmodel/viewmodel_instance_boolean.cpp | 6 + .../viewmodel/viewmodel_instance_color.cpp | 6 + .../viewmodel/viewmodel_instance_enum.cpp | 6 + .../viewmodel/viewmodel_instance_list.cpp | 188 +- .../viewmodel_instance_list_item.cpp | 2 +- .../viewmodel/viewmodel_instance_number.cpp | 6 + .../viewmodel/viewmodel_instance_string.cpp | 6 + .../viewmodel_instance_symbol_list_index.cpp | 6 + .../viewmodel/viewmodel_instance_trigger.cpp | 10 +- .../viewmodel/viewmodel_instance_value.cpp | 143 +- .../viewmodel_instance_viewmodel.cpp | 120 +- .../rive/source/virtualizing_component.cpp | 16 + .../include/rive/decoders/bitmap_decoder.hpp | 9 +- thirdparty/rive_decoders/rive_decoders.cpp | 3 + thirdparty/rive_decoders/rive_decoders.h | 2 +- .../rive_decoders/source/bitmap_decoder.cpp | 10 +- .../source/bitmap_decoder_thirdparty.cpp | 3 +- .../rive_decoders/source/decode_jpeg.cpp | 17 +- .../rive_decoders/source/decode_png.cpp | 7 +- .../rive_decoders/source/decode_webp.cpp | 8 +- .../rive/renderer/async_pipeline_manager.hpp | 686 + .../include/rive/renderer/d3d/d3d.hpp | 6 + .../include/rive/renderer/d3d/d3d_utils.hpp | 18 + .../rive/renderer/d3d/pipeline_manager.hpp | 239 +- .../d3d11/render_context_d3d_impl.hpp | 82 +- .../renderer/d3d12/d3d12_pipeline_manager.hpp | 50 +- .../rive/renderer/d3d12/d3d12_utils.hpp | 26 +- .../d3d12/render_context_d3d12_impl.hpp | 21 +- .../include/rive/renderer/draw.hpp | 86 +- .../include/rive/renderer/gl/gl_state.hpp | 23 +- .../include/rive/renderer/gl/gl_utils.hpp | 82 +- .../include/rive/renderer/gl/gles3.hpp | 107 +- .../rive/renderer/gl/load_gles_extensions.hpp | 10 + .../renderer/gl/load_store_actions_ext.hpp | 15 +- .../renderer/gl/render_buffer_gl_impl.hpp | 2 + .../renderer/gl/render_context_gl_impl.hpp | 323 +- .../rive/renderer/gl/render_target_gl.hpp | 103 +- .../include/rive/renderer/gpu.hpp | 575 +- .../include/rive/renderer/gpu_resource.hpp | 5 + .../metal/render_context_metal_impl.h | 22 +- .../rive/renderer/ore/ore_bind_group.hpp | 277 + .../renderer/ore/ore_bind_group_layout.hpp | 167 + .../rive/renderer/ore/ore_binding_map.hpp | 317 + .../include/rive/renderer/ore/ore_buffer.hpp | 119 + .../include/rive/renderer/ore/ore_context.hpp | 274 + .../rive/renderer/ore/ore_context_d3d11.hpp | 84 + .../rive/renderer/ore/ore_context_d3d12.hpp | 162 + .../rive/renderer/ore/ore_context_gl.hpp | 68 + .../rive/renderer/ore/ore_context_metal.hpp | 75 + .../rive/renderer/ore/ore_context_vulkan.hpp | 273 + .../rive/renderer/ore/ore_context_wgpu.hpp | 92 + .../rive/renderer/ore/ore_pipeline.hpp | 179 + .../rive/renderer/ore/ore_render_pass.hpp | 407 + .../include/rive/renderer/ore/ore_sampler.hpp | 98 + .../rive/renderer/ore/ore_shader_module.hpp | 307 + .../include/rive/renderer/ore/ore_texture.hpp | 250 + .../include/rive/renderer/ore/ore_types.hpp | 745 + .../include/rive/renderer/render_canvas.hpp | 39 + .../include/rive/renderer/render_context.hpp | 113 +- .../rive/renderer/render_context_impl.hpp | 70 +- .../rive/renderer/rive_render_image.hpp | 6 +- .../include/rive/renderer/rive_renderer.hpp | 6 + .../rive/renderer/shader_compilation_mode.hpp | 18 + .../rive/renderer/sk_rectanizer_skyline.hpp | 4 +- .../include/rive/renderer/stack_vector.hpp | 39 +- .../include/rive/renderer/texture.hpp | 10 +- .../rive/renderer/trivial_block_allocator.hpp | 35 +- .../vulkan/render_context_vulkan_impl.hpp | 371 +- .../renderer/vulkan/render_target_vulkan.hpp | 69 +- .../include/rive/renderer/vulkan/vkutil.hpp | 72 +- .../rive/renderer/vulkan/vulkan_context.hpp | 57 +- .../rive/renderer/webgpu/em_js_handle.hpp | 47 - .../webgpu/render_context_webgpu_impl.hpp | 261 +- thirdparty/rive_renderer/rive_renderer.cpp | 4 + thirdparty/rive_renderer/rive_renderer.h | 2 +- .../rive_renderer/source/d3d/d3d_utils.cpp | 60 + .../source/d3d/pipeline_manager.cpp | 222 +- .../source/d3d11/render_context_d3d_impl.cpp | 698 +- .../source/d3d12/d3d12_pipeline_manager.cpp | 291 +- .../source/d3d12/d3d12_utils.cpp | 83 +- .../d3d12/render_context_d3d12_impl.cpp | 787 +- thirdparty/rive_renderer/source/draw.cpp | 303 +- .../shaders/advanced_blend.exports.h | 208 - .../shaders/advanced_blend.glsl.exports.h | 252 + .../generated/shaders/advanced_blend.glsl.hpp | 20 +- .../shaders/advanced_blend.minified.glsl | 8 +- .../generated/shaders/atomic_draw.exports.h | 208 - .../shaders/atomic_draw.glsl.exports.h | 252 + .../generated/shaders/atomic_draw.glsl.hpp | 513 +- .../shaders/atomic_draw.minified.glsl | 347 +- .../generated/shaders/bezier_utils.exports.h | 208 - .../shaders/bezier_utils.glsl.exports.h | 252 + .../generated/shaders/bezier_utils.glsl.hpp | 16 +- .../shaders/bezier_utils.minified.glsl | 14 +- .../shaders/blit_texture_as_draw.exports.h | 208 - .../blit_texture_as_draw.glsl.exports.h | 252 + .../shaders/blit_texture_as_draw.glsl.hpp | 46 +- .../blit_texture_as_draw.minified.glsl | 40 +- ...clear_clockwise_atomic_clip.glsl.exports.h | 252 + .../clear_clockwise_atomic_clip.glsl.hpp | 21 + .../clear_clockwise_atomic_clip.minified.glsl | 10 + .../generated/shaders/color_ramp.exports.h | 208 - .../shaders/color_ramp.glsl.exports.h | 252 + .../generated/shaders/color_ramp.glsl.hpp | 36 +- .../shaders/color_ramp.minified.glsl | 28 +- .../source/generated/shaders/common.exports.h | 208 - .../generated/shaders/common.glsl.exports.h | 252 + .../source/generated/shaders/common.glsl.hpp | 100 +- .../generated/shaders/common.minified.glsl | 88 +- .../generated/shaders/constants.exports.h | 208 - .../shaders/constants.glsl.exports.h | 252 + .../generated/shaders/constants.glsl.hpp | 226 +- .../generated/shaders/constants.minified.glsl | 224 +- .../generated/shaders/d3d/color_ramp.frag.h | 120 - .../generated/shaders/d3d/color_ramp.vert.h | 501 - .../generated/shaders/d3d/render_atlas.vert.h | 2417 -- .../shaders/d3d/render_atlas_fill.frag.h | 352 - .../shaders/d3d/render_atlas_stroke.frag.h | 195 - .../source/generated/shaders/d3d/root.sig.h | 123 - .../generated/shaders/d3d/tessellate.frag.h | 1418 - .../generated/shaders/d3d/tessellate.vert.h | 2369 -- ...se_atomic_borrowed_coverage.frag.exports.h | 252 + ...lockwise_atomic_borrowed_coverage.frag.hpp | 26 + ...ise_atomic_borrowed_coverage.minified.frag | 15 + .../draw_clockwise_atomic_clip.frag.exports.h | 252 + .../draw_clockwise_atomic_clip.frag.hpp | 38 + .../draw_clockwise_atomic_clip.minified.frag | 27 + .../draw_clockwise_atomic_path.frag.exports.h | 252 + .../draw_clockwise_atomic_path.frag.hpp | 120 + .../draw_clockwise_atomic_path.minified.frag | 109 + .../draw_clockwise_clip.frag.exports.h | 252 + .../shaders/draw_clockwise_clip.frag.hpp | 44 + .../shaders/draw_clockwise_clip.minified.frag | 33 + .../draw_clockwise_image_mesh.exports.h | 208 - .../draw_clockwise_image_mesh.glsl.hpp | 21 - .../draw_clockwise_image_mesh.minified.glsl | 10 - .../shaders/draw_clockwise_path.exports.h | 208 - .../draw_clockwise_path.frag.exports.h | 252 + .../shaders/draw_clockwise_path.frag.hpp | 115 + .../shaders/draw_clockwise_path.glsl.hpp | 121 - .../shaders/draw_clockwise_path.minified.frag | 104 + .../shaders/draw_clockwise_path.minified.glsl | 110 - .../generated/shaders/draw_combinations.metal | 206 +- .../draw_fullscreen_quad.minified.vert | 3 + .../draw_fullscreen_quad.vert.exports.h | 252 + .../shaders/draw_fullscreen_quad.vert.hpp | 14 + .../shaders/draw_image_mesh.exports.h | 208 - .../shaders/draw_image_mesh.glsl.hpp | 93 - .../shaders/draw_image_mesh.minified.glsl | 82 - .../shaders/draw_image_mesh.minified.vert | 48 + .../shaders/draw_image_mesh.vert.exports.h | 252 + .../shaders/draw_image_mesh.vert.hpp | 59 + .../draw_input_attachment.frag.exports.h | 252 + .../shaders/draw_input_attachment.frag.hpp | 20 + .../draw_input_attachment.minified.frag | 9 + .../shaders/draw_mesh.frag.exports.h | 252 + .../generated/shaders/draw_mesh.frag.hpp | 124 + .../generated/shaders/draw_mesh.minified.frag | 113 + .../shaders/draw_msaa_object.frag.exports.h | 252 + .../shaders/draw_msaa_object.frag.hpp | 57 + .../shaders/draw_msaa_object.minified.frag | 46 + .../shaders/draw_msaa_resolve.frag.exports.h | 252 + .../shaders/draw_msaa_resolve.frag.hpp | 14 + .../shaders/draw_msaa_resolve.minified.frag | 3 + .../generated/shaders/draw_path.exports.h | 208 - .../generated/shaders/draw_path.glsl.hpp | 294 - .../generated/shaders/draw_path.minified.glsl | 283 - .../generated/shaders/draw_path.minified.vert | 205 + .../shaders/draw_path.vert.exports.h | 252 + .../generated/shaders/draw_path.vert.hpp | 216 + .../shaders/draw_path_common.exports.h | 208 - .../shaders/draw_path_common.glsl.exports.h | 252 + .../shaders/draw_path_common.glsl.hpp | 176 +- .../shaders/draw_path_common.minified.glsl | 120 +- .../draw_raster_order_path.frag.exports.h | 252 + .../shaders/draw_raster_order_path.frag.hpp | 89 + .../draw_raster_order_path.minified.frag | 78 + .../shaders/flush_uniforms.glsl.exports.h | 252 + .../generated/shaders/flush_uniforms.glsl.hpp | 30 + .../shaders/flush_uniforms.minified.glsl | 19 + .../source/generated/shaders/glsl.exports.h | 208 - .../generated/shaders/glsl.glsl.exports.h | 252 + .../source/generated/shaders/glsl.glsl.hpp | 584 +- .../generated/shaders/glsl.minified.glsl | 516 +- .../source/generated/shaders/hlsl.exports.h | 208 - .../generated/shaders/hlsl.glsl.exports.h | 252 + .../source/generated/shaders/hlsl.glsl.hpp | 266 +- .../generated/shaders/hlsl.minified.glsl | 248 +- .../image_draw_uniforms.glsl.exports.h | 252 + .../shaders/image_draw_uniforms.glsl.hpp | 15 + .../shaders/image_draw_uniforms.minified.glsl | 4 + ...clockwise_atomic_workaround.frag.exports.h | 252 + .../init_clockwise_atomic_workaround.frag.hpp | 24 + ..._clockwise_atomic_workaround.minified.frag | 13 + .../generated/shaders/ios/color_ramp.air | Bin 5536 -> 5984 bytes .../source/generated/shaders/ios/draw.air | Bin 38048 -> 37424 bytes .../shaders/ios/rive_pls_ios.metallib | Bin 139584 -> 140410 bytes .../ios/rive_pls_ios_simulator.metallib | Bin 140000 -> 140826 bytes .../ios/rive_renderer_appletvos.metallib | Bin 0 -> 144106 bytes .../rive_renderer_appletvsimulator.metallib | Bin 0 -> 144570 bytes .../shaders/ios/rive_renderer_xros.metallib | Bin 0 -> 143930 bytes .../ios/rive_renderer_xros_simulator.metallib | Bin 0 -> 144378 bytes .../generated/shaders/ios/tessellate.air | Bin 14192 -> 14720 bytes .../generated/shaders/macosx/color_ramp.air | Bin 5712 -> 5920 bytes .../source/generated/shaders/macosx/draw.air | Bin 37776 -> 37088 bytes .../shaders/macosx/rive_pls_macosx.metallib | Bin 141664 -> 143578 bytes .../generated/shaders/macosx/tessellate.air | Bin 14368 -> 14656 bytes .../source/generated/shaders/metal.exports.h | 208 - .../generated/shaders/metal.glsl.exports.h | 252 + .../source/generated/shaders/metal.glsl.hpp | 302 +- .../generated/shaders/metal.minified.glsl | 290 +- .../shaders/pls_load_store_ext.exports.h | 208 - .../shaders/pls_load_store_ext.glsl.exports.h | 252 + .../shaders/pls_load_store_ext.glsl.hpp | 60 +- .../shaders/pls_load_store_ext.minified.glsl | 36 +- .../generated/shaders/render_atlas.exports.h | 208 - .../shaders/render_atlas.glsl.exports.h | 252 + .../generated/shaders/render_atlas.glsl.hpp | 70 +- .../shaders/render_atlas.minified.glsl | 58 +- .../shaders/resolve_atlas.glsl.exports.h | 252 + .../generated/shaders/resolve_atlas.glsl.hpp | 39 + .../shaders/resolve_atlas.minified.glsl | 28 + .../source/generated/shaders/rhi.exports.h | 208 - .../generated/shaders/rhi.glsl.exports.h | 252 + .../source/generated/shaders/rhi.glsl.hpp | 341 +- .../generated/shaders/rhi.minified.glsl | 321 +- .../generated/shaders/rive_pls_ios.metallib.c | 22839 +++++++-------- .../shaders/rive_pls_ios_simulator.metallib.c | 22959 +++++++-------- .../shaders/rive_pls_macosx.metallib.c | 23065 ++++++++-------- .../rive_renderer_appletvos.metallib.c | 12012 ++++++++ .../rive_renderer_appletvsimulator.metallib.c | 12051 ++++++++ .../shaders/rive_renderer_xros.metallib.c | 11998 ++++++++ .../rive_renderer_xros_simulator.metallib.c | 12035 ++++++++ .../shaders/specialization.exports.h | 208 - .../shaders/specialization.glsl.exports.h | 252 + .../generated/shaders/specialization.glsl.hpp | 41 +- .../shaders/specialization.minified.glsl | 39 +- .../atomic_draw_atlas_blit.fixedcolor_frag.h | 463 + ...omic_draw_atlas_blit.fixedcolor_frag.spirv | Bin 0 -> 14664 bytes .../spirv/atomic_draw_atlas_blit.frag.h | 1658 ++ .../spirv/atomic_draw_atlas_blit.frag.spirv | Bin 0 -> 52928 bytes .../spirv/atomic_draw_atlas_blit.vert.h | 134 + .../spirv/atomic_draw_atlas_blit.vert.spirv | Bin 0 -> 4140 bytes .../atomic_draw_image_mesh.fixedcolor_frag.h | 527 + ...omic_draw_image_mesh.fixedcolor_frag.spirv | Bin 0 -> 16720 bytes .../spirv/atomic_draw_image_mesh.frag.h | 2923 ++ .../spirv/atomic_draw_image_mesh.frag.spirv | Bin 0 -> 93404 bytes .../spirv/atomic_draw_image_mesh.vert.h | 179 + .../spirv/atomic_draw_image_mesh.vert.spirv | Bin 0 -> 5572 bytes .../atomic_draw_image_rect.fixedcolor_frag.h | 533 + ...omic_draw_image_rect.fixedcolor_frag.spirv | Bin 0 -> 16904 bytes .../spirv/atomic_draw_image_rect.frag.h | 2929 ++ .../spirv/atomic_draw_image_rect.frag.spirv | Bin 0 -> 93588 bytes .../spirv/atomic_draw_image_rect.vert.h | 236 + .../spirv/atomic_draw_image_rect.vert.spirv | Bin 0 -> 7420 bytes ..._draw_interior_triangles.fixedcolor_frag.h | 452 + ...w_interior_triangles.fixedcolor_frag.spirv | Bin 0 -> 14328 bytes .../atomic_draw_interior_triangles.frag.h | 1648 ++ .../atomic_draw_interior_triangles.frag.spirv | Bin 0 -> 52592 bytes .../atomic_draw_interior_triangles.vert.h | 138 + .../atomic_draw_interior_triangles.vert.spirv | Bin 0 -> 4272 bytes .../spirv/atomic_draw_path.fixedcolor_frag.h | 677 + .../atomic_draw_path.fixedcolor_frag.spirv | Bin 0 -> 21532 bytes .../shaders/spirv/atomic_draw_path.frag.h | 1873 ++ .../shaders/spirv/atomic_draw_path.frag.spirv | Bin 0 -> 59780 bytes .../shaders/spirv/atomic_draw_path.vert.h | 518 + .../shaders/spirv/atomic_draw_path.vert.spirv | Bin 0 -> 16432 bytes .../spirv/atomic_resolve.fixedcolor_frag.h | 373 + .../atomic_resolve.fixedcolor_frag.spirv | Bin 0 -> 11792 bytes .../shaders/spirv/atomic_resolve.frag.h | 1569 ++ .../shaders/spirv/atomic_resolve.frag.spirv | Bin 0 -> 50072 bytes .../shaders/spirv/atomic_resolve.vert.h | 130 + .../shaders/spirv/atomic_resolve.vert.spirv | Bin 0 -> 4004 bytes .../spirv/atomic_resolve_coalesced.frag.h | 1520 + .../spirv/atomic_resolve_coalesced.frag.spirv | Bin 0 -> 48504 bytes .../spirv/atomic_resolve_coalesced.vert.h | 130 + .../spirv/atomic_resolve_coalesced.vert.spirv | Bin 0 -> 4004 bytes .../blit_texture_as_draw_filtered.frag.h | 64 + .../blit_texture_as_draw_filtered.frag.spirv | Bin 0 -> 1908 bytes .../blit_texture_as_draw_filtered.vert.h | 78 + .../blit_texture_as_draw_filtered.vert.spirv | Bin 0 -> 2364 bytes ...lit_texture_as_draw_filtered.webgpu_frag.h | 64 + ...texture_as_draw_filtered.webgpu_frag.spirv | Bin 0 -> 1908 bytes ...lit_texture_as_draw_filtered.webgpu_vert.h | 78 + ...texture_as_draw_filtered.webgpu_vert.spirv | Bin 0 -> 2364 bytes ...ar_clockwise_atomic_clip.fixedcolor_frag.h | 56 + ...lockwise_atomic_clip.fixedcolor_frag.spirv | Bin 0 -> 1660 bytes .../spirv/clear_clockwise_atomic_clip.frag.h | 56 + .../clear_clockwise_atomic_clip.frag.spirv | Bin 0 -> 1660 bytes .../spirv/clear_clockwise_atomic_clip.vert.h | 112 + .../clear_clockwise_atomic_clip.vert.spirv | Bin 0 -> 3432 bytes .../generated/shaders/spirv/color_ramp.frag.h | 52 + .../shaders/spirv/color_ramp.frag.spirv | Bin 0 -> 1524 bytes .../generated/shaders/spirv/color_ramp.vert.h | 131 + .../shaders/spirv/color_ramp.vert.spirv | Bin 0 -> 4060 bytes .../shaders/spirv/draw_atlas_blit.frag.h | 724 + .../shaders/spirv/draw_atlas_blit.frag.spirv | Bin 0 -> 23032 bytes .../shaders/spirv/draw_atlas_blit.vert.h | 260 + .../shaders/spirv/draw_atlas_blit.vert.spirv | Bin 0 -> 8172 bytes ...raw_clockwise_atlas_blit.fixedcolor_frag.h | 251 + ...clockwise_atlas_blit.fixedcolor_frag.spirv | Bin 0 -> 7892 bytes .../spirv/draw_clockwise_atlas_blit.frag.h | 715 + .../draw_clockwise_atlas_blit.frag.spirv | Bin 0 -> 22748 bytes .../spirv/draw_clockwise_atlas_blit.vert.h | 262 + .../draw_clockwise_atlas_blit.vert.spirv | Bin 0 -> 8236 bytes ...ckwise_atomic_atlas_blit.fixedcolor_frag.h | 348 + ...se_atomic_atlas_blit.fixedcolor_frag.spirv | Bin 0 -> 11000 bytes .../draw_clockwise_atomic_atlas_blit.frag.h | 1552 ++ ...raw_clockwise_atomic_atlas_blit.frag.spirv | Bin 0 -> 49528 bytes .../draw_clockwise_atomic_atlas_blit.vert.h | 271 + ...raw_clockwise_atomic_atlas_blit.vert.spirv | Bin 0 -> 8536 bytes ..._clockwise_atomic_borrowed_coverage.frag.h | 355 + ...ckwise_atomic_borrowed_coverage.frag.spirv | Bin 0 -> 11212 bytes ...orrowed_coverage_interior_triangles.frag.h | 121 + ...wed_coverage_interior_triangles.frag.spirv | Bin 0 -> 3732 bytes ...aw_clockwise_atomic_clip.fixedcolor_frag.h | 250 + ...lockwise_atomic_clip.fixedcolor_frag.spirv | Bin 0 -> 7872 bytes .../spirv/draw_clockwise_atomic_clip.frag.h | 251 + .../draw_clockwise_atomic_clip.frag.spirv | Bin 0 -> 7880 bytes ..._clip_interior_triangles.fixedcolor_frag.h | 251 + ...p_interior_triangles.fixedcolor_frag.spirv | Bin 0 -> 7888 bytes ...wise_atomic_clip_interior_triangles.frag.h | 251 + ..._atomic_clip_interior_triangles.frag.spirv | Bin 0 -> 7896 bytes ...ckwise_atomic_image_mesh.fixedcolor_frag.h | 202 + ...se_atomic_image_mesh.fixedcolor_frag.spirv | Bin 0 -> 6308 bytes .../draw_clockwise_atomic_image_mesh.frag.h | 1427 + ...raw_clockwise_atomic_image_mesh.frag.spirv | Bin 0 -> 45512 bytes .../draw_clockwise_atomic_image_mesh.vert.h | 158 + ...raw_clockwise_atomic_image_mesh.vert.spirv | Bin 0 -> 4920 bytes ...tomic_interior_triangles.fixedcolor_frag.h | 507 + ...c_interior_triangles.fixedcolor_frag.spirv | Bin 0 -> 16084 bytes ...clockwise_atomic_interior_triangles.frag.h | 1756 ++ ...kwise_atomic_interior_triangles.frag.spirv | Bin 0 -> 56052 bytes ...clockwise_atomic_interior_triangles.vert.h | 287 + ...kwise_atomic_interior_triangles.vert.spirv | Bin 0 -> 9040 bytes ...aw_clockwise_atomic_path.fixedcolor_frag.h | 807 + ...lockwise_atomic_path.fixedcolor_frag.spirv | Bin 0 -> 25680 bytes .../spirv/draw_clockwise_atomic_path.frag.h | 2063 ++ .../draw_clockwise_atomic_path.frag.spirv | Bin 0 -> 65868 bytes .../spirv/draw_clockwise_atomic_path.vert.h | 666 + .../draw_clockwise_atomic_path.vert.spirv | Bin 0 -> 21172 bytes .../draw_clockwise_clip.fixedcolor_frag.h | 138 + .../draw_clockwise_clip.fixedcolor_frag.spirv | Bin 0 -> 4276 bytes .../shaders/spirv/draw_clockwise_clip.frag.h | 147 + .../spirv/draw_clockwise_clip.frag.spirv | Bin 0 -> 4556 bytes .../shaders/spirv/draw_clockwise_clip.vert.h | 669 + .../spirv/draw_clockwise_clip.vert.spirv | Bin 0 -> 21276 bytes ..._clip_interior_triangles.fixedcolor_frag.h | 154 + ...p_interior_triangles.fixedcolor_frag.spirv | Bin 0 -> 4776 bytes ...w_clockwise_clip_interior_triangles.frag.h | 162 + ...ockwise_clip_interior_triangles.frag.spirv | Bin 0 -> 5056 bytes ...w_clockwise_clip_interior_triangles.vert.h | 290 + ...ockwise_clip_interior_triangles.vert.spirv | Bin 0 -> 9128 bytes ...raw_clockwise_image_mesh.fixedcolor_frag.h | 168 + ...clockwise_image_mesh.fixedcolor_frag.spirv | Bin 0 -> 5224 bytes .../spirv/draw_clockwise_image_mesh.frag.h | 648 + .../draw_clockwise_image_mesh.frag.spirv | Bin 0 -> 20584 bytes .../spirv/draw_clockwise_image_mesh.vert.h | 156 + .../draw_clockwise_image_mesh.vert.spirv | Bin 0 -> 4856 bytes ...kwise_interior_triangles.fixedcolor_frag.h | 308 + ...e_interior_triangles.fixedcolor_frag.spirv | Bin 0 -> 9712 bytes .../draw_clockwise_interior_triangles.frag.h | 785 + ...aw_clockwise_interior_triangles.frag.spirv | Bin 0 -> 24968 bytes .../draw_clockwise_interior_triangles.vert.h | 290 + ...aw_clockwise_interior_triangles.vert.spirv | Bin 0 -> 9128 bytes .../draw_clockwise_path.fixedcolor_frag.h | 431 + .../draw_clockwise_path.fixedcolor_frag.spirv | Bin 0 -> 13640 bytes .../shaders/spirv/draw_clockwise_path.frag.h | 926 + .../spirv/draw_clockwise_path.frag.spirv | Bin 0 -> 29476 bytes .../shaders/spirv/draw_clockwise_path.vert.h | 669 + .../spirv/draw_clockwise_path.vert.spirv | Bin 0 -> 21276 bytes .../shaders/spirv/draw_fullscreen_quad.vert.h | 73 + .../spirv/draw_fullscreen_quad.vert.spirv | Bin 0 -> 2180 bytes .../shaders/spirv/draw_image_mesh.frag.h | 657 + .../shaders/spirv/draw_image_mesh.frag.spirv | Bin 0 -> 20868 bytes .../shaders/spirv/draw_image_mesh.vert.h | 156 + .../shaders/spirv/draw_image_mesh.vert.spirv | Bin 0 -> 4856 bytes .../spirv/draw_input_attachment.frag.h | 57 + .../spirv/draw_input_attachment.frag.spirv | Bin 0 -> 1680 bytes .../spirv/draw_interior_triangles.frag.h | 802 + .../spirv/draw_interior_triangles.frag.spirv | Bin 0 -> 25528 bytes .../spirv/draw_interior_triangles.vert.h | 290 + .../spirv/draw_interior_triangles.vert.spirv | Bin 0 -> 9128 bytes .../draw_msaa_atlas_blit.fixedcolor_frag.h | 201 + ...draw_msaa_atlas_blit.fixedcolor_frag.spirv | Bin 0 -> 6296 bytes .../shaders/spirv/draw_msaa_atlas_blit.frag.h | 717 + .../spirv/draw_msaa_atlas_blit.frag.spirv | Bin 0 -> 22792 bytes ...draw_msaa_atlas_blit.noclipdistance_vert.h | 227 + ..._msaa_atlas_blit.noclipdistance_vert.spirv | Bin 0 -> 7108 bytes .../shaders/spirv/draw_msaa_atlas_blit.vert.h | 259 + .../spirv/draw_msaa_atlas_blit.vert.spirv | Bin 0 -> 8160 bytes ...w_msaa_atlas_blit.webgpu_fixedcolor_frag.h | 177 + ...aa_atlas_blit.webgpu_fixedcolor_frag.spirv | Bin 0 -> 5516 bytes .../spirv/draw_msaa_atlas_blit.webgpu_frag.h | 514 + .../draw_msaa_atlas_blit.webgpu_frag.spirv | Bin 0 -> 16304 bytes ...aa_atlas_blit.webgpu_noclipdistance_vert.h | 209 + ...tlas_blit.webgpu_noclipdistance_vert.spirv | Bin 0 -> 6536 bytes .../spirv/draw_msaa_atlas_blit.webgpu_vert.h | 239 + .../draw_msaa_atlas_blit.webgpu_vert.spirv | Bin 0 -> 7496 bytes .../draw_msaa_color_seed_attachment.frag.h | 57 + ...draw_msaa_color_seed_attachment.frag.spirv | Bin 0 -> 1680 bytes .../draw_msaa_image_mesh.fixedcolor_frag.h | 121 + ...draw_msaa_image_mesh.fixedcolor_frag.spirv | Bin 0 -> 3732 bytes .../shaders/spirv/draw_msaa_image_mesh.frag.h | 646 + .../spirv/draw_msaa_image_mesh.frag.spirv | Bin 0 -> 20544 bytes ...draw_msaa_image_mesh.noclipdistance_vert.h | 125 + ..._msaa_image_mesh.noclipdistance_vert.spirv | Bin 0 -> 3860 bytes .../shaders/spirv/draw_msaa_image_mesh.vert.h | 157 + .../spirv/draw_msaa_image_mesh.vert.spirv | Bin 0 -> 4888 bytes ...w_msaa_image_mesh.webgpu_fixedcolor_frag.h | 113 + ...aa_image_mesh.webgpu_fixedcolor_frag.spirv | Bin 0 -> 3472 bytes .../spirv/draw_msaa_image_mesh.webgpu_frag.h | 471 + .../draw_msaa_image_mesh.webgpu_frag.spirv | Bin 0 -> 14920 bytes ...aa_image_mesh.webgpu_noclipdistance_vert.h | 122 + ...mage_mesh.webgpu_noclipdistance_vert.spirv | Bin 0 -> 3768 bytes .../spirv/draw_msaa_image_mesh.webgpu_vert.h | 151 + .../draw_msaa_image_mesh.webgpu_vert.spirv | Bin 0 -> 4704 bytes .../spirv/draw_msaa_path.fixedcolor_frag.h | 189 + .../draw_msaa_path.fixedcolor_frag.spirv | Bin 0 -> 5896 bytes .../shaders/spirv/draw_msaa_path.frag.h | 704 + .../shaders/spirv/draw_msaa_path.frag.spirv | Bin 0 -> 22392 bytes .../draw_msaa_path.noclipdistance_vert.h | 505 + .../draw_msaa_path.noclipdistance_vert.spirv | Bin 0 -> 16016 bytes .../shaders/spirv/draw_msaa_path.vert.h | 537 + .../shaders/spirv/draw_msaa_path.vert.spirv | Bin 0 -> 17056 bytes .../draw_msaa_path.webgpu_fixedcolor_frag.h | 162 + ...raw_msaa_path.webgpu_fixedcolor_frag.spirv | Bin 0 -> 5056 bytes .../spirv/draw_msaa_path.webgpu_frag.h | 500 + .../spirv/draw_msaa_path.webgpu_frag.spirv | Bin 0 -> 15844 bytes ...raw_msaa_path.webgpu_noclipdistance_vert.h | 484 + ...msaa_path.webgpu_noclipdistance_vert.spirv | Bin 0 -> 15352 bytes .../spirv/draw_msaa_path.webgpu_vert.h | 514 + .../spirv/draw_msaa_path.webgpu_vert.spirv | Bin 0 -> 16300 bytes .../shaders/spirv/draw_msaa_resolve.frag.h | 70 + .../spirv/draw_msaa_resolve.frag.spirv | Bin 0 -> 2084 bytes .../spirv/draw_msaa_stencil.fixedcolor_frag.h | 56 + .../draw_msaa_stencil.fixedcolor_frag.spirv | Bin 0 -> 1664 bytes .../shaders/spirv/draw_msaa_stencil.frag.h | 56 + .../spirv/draw_msaa_stencil.frag.spirv | Bin 0 -> 1664 bytes .../shaders/spirv/draw_msaa_stencil.vert.h | 83 + .../spirv/draw_msaa_stencil.vert.spirv | Bin 0 -> 2500 bytes .../generated/shaders/spirv/draw_path.frag.h | 931 + .../shaders/spirv/draw_path.frag.spirv | Bin 0 -> 29644 bytes .../generated/shaders/spirv/draw_path.vert.h | 669 + .../shaders/spirv/draw_path.vert.spirv | Bin 0 -> 21276 bytes ...ckwise_atomic_workaround.fixedcolor_frag.h | 64 + ...se_atomic_workaround.fixedcolor_frag.spirv | Bin 0 -> 1920 bytes .../init_clockwise_atomic_workaround.frag.h | 56 + ...nit_clockwise_atomic_workaround.frag.spirv | Bin 0 -> 1664 bytes .../shaders/spirv/render_atlas.vert.h | 523 + .../shaders/spirv/render_atlas.vert.spirv | Bin 0 -> 16600 bytes .../shaders/spirv/render_atlas.webgpu_vert.h | 523 + .../spirv/render_atlas.webgpu_vert.spirv | Bin 0 -> 16600 bytes .../shaders/spirv/render_atlas_fill.frag.h | 157 + .../spirv/render_atlas_fill.frag.spirv | Bin 0 -> 4872 bytes .../spirv/render_atlas_fill.webgpu_frag.h | 150 + .../spirv/render_atlas_fill.webgpu_frag.spirv | Bin 0 -> 4660 bytes .../shaders/spirv/render_atlas_stroke.frag.h | 83 + .../spirv/render_atlas_stroke.frag.spirv | Bin 0 -> 2508 bytes .../spirv/render_atlas_stroke.webgpu_frag.h | 83 + .../render_atlas_stroke.webgpu_frag.spirv | Bin 0 -> 2508 bytes .../generated/shaders/spirv/tessellate.frag.h | 297 + .../shaders/spirv/tessellate.frag.spirv | Bin 0 -> 9372 bytes .../generated/shaders/spirv/tessellate.vert.h | 476 + .../shaders/spirv/tessellate.vert.spirv | Bin 0 -> 15096 bytes .../shaders/spirv/tessellate.webgpu_frag.h | 293 + .../spirv/tessellate.webgpu_frag.spirv | Bin 0 -> 9224 bytes .../shaders/spirv/tessellate.webgpu_vert.h | 476 + .../spirv/tessellate.webgpu_vert.spirv | Bin 0 -> 15096 bytes .../generated/shaders/stencil_draw.exports.h | 208 - .../shaders/stencil_draw.glsl.exports.h | 252 + .../generated/shaders/stencil_draw.glsl.hpp | 10 +- .../shaders/stencil_draw.minified.glsl | 4 +- .../generated/shaders/tessellate.exports.h | 208 - .../shaders/tessellate.glsl.exports.h | 252 + .../generated/shaders/tessellate.glsl.hpp | 46 +- .../shaders/tessellate.minified.glsl | 38 +- .../rive_renderer/source/gl/gl_state.cpp | 113 +- .../rive_renderer/source/gl/gl_utils.cpp | 183 +- .../source/gl/load_gles_extensions.cpp | 98 +- .../source/gl/load_store_actions_ext.cpp | 13 +- .../source/gl/pls_impl_ext_native.cpp | 122 +- .../source/gl/pls_impl_rw_texture.cpp | 347 +- .../source/gl/pls_impl_webgl.cpp | 82 +- .../source/gl/render_buffer_gl_impl.cpp | 67 +- .../source/gl/render_context_gl_impl.cpp | 2569 +- .../source/gl/render_target_gl.cpp | 277 +- thirdparty/rive_renderer/source/gpu.cpp | 995 +- .../rive_renderer/source/gr_triangulator.cpp | 10 +- thirdparty/rive_renderer/source/gradient.cpp | 37 +- thirdparty/rive_renderer/source/gradient.hpp | 18 + .../rive_renderer/source/instance_chunker.hpp | 91 + .../source/intersection_board.cpp | 776 +- .../source/intersection_board.hpp | 152 +- .../source/metal/background_shader_compiler.h | 12 +- .../metal/background_shader_compiler.mm | 174 +- .../source/metal/render_context_metal_impl.mm | 369 +- .../source/ore/d3d11/ore_bind_group_d3d11.cpp | 23 + .../source/ore/d3d11/ore_buffer_d3d11.cpp | 44 + .../source/ore/d3d11/ore_context_d3d11.cpp | 1591 ++ .../source/ore/d3d11/ore_pipeline_d3d11.cpp | 19 + .../ore/d3d11/ore_render_pass_d3d11.cpp | 423 + .../source/ore/d3d11/ore_sampler_d3d11.cpp | 16 + .../ore/d3d11/ore_shader_module_d3d11.cpp | 16 + .../source/ore/d3d11/ore_texture_d3d11.cpp | 46 + .../ore/d3d12/ore_bind_group_d3d11_d3d12.cpp | 26 + .../source/ore/d3d12/ore_bind_group_d3d12.cpp | 26 + .../ore/d3d12/ore_buffer_d3d11_d3d12.cpp | 63 + .../source/ore/d3d12/ore_buffer_d3d12.cpp | 43 + .../source/ore/d3d12/ore_context_d3d12.cpp | 2163 ++ .../ore/d3d12/ore_d3d12_bind_group_apply.hpp | 219 + .../source/ore/d3d12/ore_d3d12_root_sig.hpp | 249 + .../ore/d3d12/ore_pipeline_d3d11_d3d12.cpp | 44 + .../source/ore/d3d12/ore_pipeline_d3d12.cpp | 47 + .../ore/d3d12/ore_render_pass_d3d11_d3d12.cpp | 697 + .../ore/d3d12/ore_render_pass_d3d12.cpp | 509 + .../ore/d3d12/ore_sampler_d3d11_d3d12.cpp | 31 + .../source/ore/d3d12/ore_sampler_d3d12.cpp | 28 + .../d3d12/ore_shader_module_d3d11_d3d12.cpp | 19 + .../ore/d3d12/ore_shader_module_d3d12.cpp | 19 + .../ore/d3d12/ore_texture_d3d11_d3d12.cpp | 218 + .../source/ore/d3d12/ore_texture_d3d12.cpp | 192 + .../source/ore/gl/ore_bind_group_gl.cpp | 24 + .../source/ore/gl/ore_buffer_gl.cpp | 55 + .../source/ore/gl/ore_buffer_gl.mm | 3 + .../source/ore/gl/ore_context_gl.cpp | 1181 + .../source/ore/gl/ore_context_gl.mm | 3 + .../source/ore/gl/ore_pipeline_gl.cpp | 28 + .../source/ore/gl/ore_pipeline_gl.mm | 3 + .../source/ore/gl/ore_render_pass_gl.cpp | 740 + .../source/ore/gl/ore_render_pass_gl.mm | 3 + .../source/ore/gl/ore_sampler_gl.cpp | 26 + .../source/ore/gl/ore_sampler_gl.mm | 3 + .../source/ore/gl/ore_shader_module_gl.cpp | 25 + .../source/ore/gl/ore_shader_module_gl.mm | 3 + .../source/ore/gl/ore_texture_gl.cpp | 386 + .../source/ore/gl/ore_texture_gl.mm | 3 + .../source/ore/metal/ore_bind_group_metal.mm | 26 + .../ore/metal/ore_bind_group_metal_gl.mm | 29 + .../source/ore/metal/ore_buffer_metal.mm | 29 + .../source/ore/metal/ore_buffer_metal_gl.mm | 44 + .../source/ore/metal/ore_context_metal.mm | 1379 + .../source/ore/metal/ore_pipeline_metal.mm | 19 + .../source/ore/metal/ore_pipeline_metal_gl.mm | 30 + .../source/ore/metal/ore_render_pass_metal.mm | 404 + .../ore/metal/ore_render_pass_metal_gl.mm | 537 + .../source/ore/metal/ore_sampler_metal.mm | 16 + .../source/ore/metal/ore_sampler_metal_gl.mm | 28 + .../ore/metal/ore_shader_module_metal.mm | 16 + .../ore/metal/ore_shader_module_metal_gl.mm | 27 + .../source/ore/metal/ore_texture_metal.mm | 48 + .../source/ore/metal/ore_texture_metal_gl.mm | 113 + .../source/ore/ore_bind_group_layout.cpp | 244 + .../source/ore/ore_binding_map.cpp | 189 + .../ore/vulkan/ore_bind_group_vulkan.cpp | 41 + .../source/ore/vulkan/ore_buffer_vulkan.cpp | 46 + .../source/ore/vulkan/ore_context_vulkan.cpp | 1476 + .../source/ore/vulkan/ore_pipeline_vulkan.cpp | 593 + .../ore/vulkan/ore_render_pass_vk_gl.cpp | 796 + .../ore/vulkan/ore_render_pass_vulkan.cpp | 340 + .../source/ore/vulkan/ore_resources_vk_gl.cpp | 691 + .../source/ore/vulkan/ore_sampler_vulkan.cpp | 35 + .../ore/vulkan/ore_shader_module_vulkan.cpp | 25 + .../source/ore/vulkan/ore_texture_vulkan.cpp | 401 + .../source/ore/vulkan/ore_vulkan_dsl.hpp | 112 + .../source/ore/wgpu/ore_bind_group_wgpu.cpp | 19 + .../source/ore/wgpu/ore_buffer_wgpu.cpp | 24 + .../source/ore/wgpu/ore_context_wgpu.cpp | 1271 + .../source/ore/wgpu/ore_pipeline_wgpu.cpp | 25 + .../source/ore/wgpu/ore_render_pass_wgpu.cpp | 199 + .../source/ore/wgpu/ore_sampler_wgpu.cpp | 16 + .../ore/wgpu/ore_shader_module_wgpu.cpp | 16 + .../source/ore/wgpu/ore_texture_wgpu.cpp | 95 + .../source/ore/wgpu/ore_wgpu_layout.hpp | 283 + .../rive_renderer/source/render_context.cpp | 1637 +- .../source/rive_render_paint.cpp | 9 + .../source/rive_render_paint.hpp | 1 + .../rive_renderer/source/rive_render_path.cpp | 15 +- .../rive_renderer/source/rive_render_path.hpp | 4 +- .../rive_renderer/source/rive_renderer.cpp | 141 +- .../rive_renderer/source/shaders/Makefile | 366 +- .../source/shaders/advanced_blend.glsl | 163 +- .../source/shaders/atomic_draw.glsl | 131 +- .../source/shaders/blit_texture_as_draw.glsl | 28 +- .../shaders/clear_clockwise_atomic_clip.glsl | 36 + .../source/shaders/color_ramp.glsl | 3 + .../rive_renderer/source/shaders/common.glsl | 231 +- .../source/shaders/constants.glsl | 100 +- .../source/shaders/d3d/color_ramp.hlsl_ | 4 - .../source/shaders/d3d/render_atlas.hlsl_ | 8 - .../source/shaders/d3d/root.sig_ | 93 - .../source/shaders/d3d/tessellate.hlsl_ | 5 - ...aw_clockwise_atomic_borrowed_coverage.frag | 55 + .../shaders/draw_clockwise_atomic_clip.frag | 138 + .../shaders/draw_clockwise_atomic_path.frag | 379 + .../source/shaders/draw_clockwise_clip.frag | 101 + .../shaders/draw_clockwise_image_mesh.glsl | 69 - .../source/shaders/draw_clockwise_path.frag | 253 + .../source/shaders/draw_clockwise_path.glsl | 454 - .../source/shaders/draw_fullscreen_quad.vert | 15 + .../source/shaders/draw_image_mesh.glsl | 204 - .../source/shaders/draw_image_mesh.vert | 91 + .../source/shaders/draw_input_attachment.frag | 18 + .../source/shaders/draw_mesh.frag | 218 + .../source/shaders/draw_msaa_object.frag | 103 + .../source/shaders/draw_msaa_resolve.frag | 18 + .../{draw_path.glsl => draw_path.vert} | 418 +- .../source/shaders/draw_path_common.glsl | 127 +- .../shaders/draw_raster_order_path.frag | 232 + .../source/shaders/flush_uniforms.glsl | 58 + .../rive_renderer/source/shaders/glsl.glsl | 256 +- .../rive_renderer/source/shaders/hlsl.glsl | 60 +- .../source/shaders/image_draw_uniforms.glsl | 16 + .../init_clockwise_atomic_workaround.frag | 33 + .../rive_renderer/source/shaders/metal.glsl | 55 +- .../source/shaders/metal/color_ramp.metal | 2 + .../source/shaders/metal/draw.metal | 3 + .../metal/generate_draw_combinations.py | 25 +- .../source/shaders/metal/tessellate.metal | 2 + .../rive_renderer/source/shaders/minify.py | 102 +- .../source/shaders/pls_load_store_ext.glsl | 3 + .../source/shaders/render_atlas.glsl | 180 +- .../source/shaders/resolve_atlas.glsl | 93 + .../rive_renderer/source/shaders/rhi.glsl | 183 +- .../source/shaders/specialization.glsl | 29 +- .../source/shaders/spirv/atomic_base.glsl | 5 +- ...ain => blit_texture_as_draw_filtered.main} | 5 +- .../spirv/clear_clockwise_atomic_clip.main | 18 + .../source/shaders/spirv/color_ramp.main | 3 +- .../source/shaders/spirv/draw_atlas_blit.main | 6 +- .../spirv/draw_clockwise_atlas_blit.main | 7 +- .../draw_clockwise_atomic_atlas_blit.main | 16 + ...aw_clockwise_atomic_borrowed_coverage.frag | 17 + ..._borrowed_coverage_interior_triangles.frag | 16 + .../spirv/draw_clockwise_atomic_clip.frag | 17 + ...ckwise_atomic_clip_interior_triangles.frag | 16 + .../draw_clockwise_atomic_image_mesh.main | 17 + ...w_clockwise_atomic_interior_triangles.main | 20 + .../spirv/draw_clockwise_atomic_path.main | 20 + .../shaders/spirv/draw_clockwise_clip.main | 15 + ...raw_clockwise_clip_interior_triangles.main | 14 + .../spirv/draw_clockwise_image_mesh.main | 8 +- .../draw_clockwise_interior_triangles.main | 5 +- .../shaders/spirv/draw_clockwise_path.main | 5 +- .../shaders/spirv/draw_fullscreen_quad.vert | 7 + .../source/shaders/spirv/draw_image_mesh.main | 6 +- .../shaders/spirv/draw_input_attachment.frag | 7 + .../spirv/draw_interior_triangles.main | 5 +- .../shaders/spirv/draw_msaa_atlas_blit.main | 16 + .../draw_msaa_color_seed_attachment.frag | 8 + .../shaders/spirv/draw_msaa_image_mesh.main | 16 + .../source/shaders/spirv/draw_msaa_path.main | 16 + .../shaders/spirv/draw_msaa_resolve.frag | 7 + .../shaders/spirv/draw_msaa_stencil.main | 17 + .../source/shaders/spirv/draw_path.main | 5 +- .../init_clockwise_atomic_workaround.frag | 11 + .../source/shaders/spirv/render_atlas.vert | 2 +- .../shaders/spirv/render_atlas_common.glsl | 1 + .../shaders/spirv/render_atlas_fill.frag | 2 +- .../shaders/spirv/render_atlas_stroke.frag | 2 +- .../source/shaders/spirv/tessellate.main | 3 +- .../source/shaders/spirv_binary_to_header.py | 29 + .../source/shaders/stencil_draw.glsl | 1 + .../source/shaders/tessellate.glsl | 25 +- .../source/shaders/unreal/atomic_base.ush | 14 - .../shaders/unreal/atomic_draw_atlas_blit.usf | 4 - .../shaders/unreal/atomic_draw_image_mesh.usf | 4 - .../shaders/unreal/atomic_draw_image_rect.usf | 4 - .../unreal/atomic_draw_interior_triangles.usf | 3 - .../shaders/unreal/atomic_draw_path.usf | 3 - .../shaders/unreal/atomic_resolve_pls.usf | 4 - .../source/shaders/unreal/blt_u324_to_f4.usf | 9 - .../source/shaders/unreal/blt_u32_as_f4.usf | 9 - .../source/shaders/unreal/color_ramp.usf | 12 - .../source/shaders/unreal/draw_atlas_fill.usf | 14 - .../shaders/unreal/draw_atlas_stroke.usf | 14 - .../source/shaders/unreal/draw_image_mesh.usf | 17 - .../unreal/draw_interior_triangles.usf | 16 - .../source/shaders/unreal/draw_path.usf | 17 - .../shaders/unreal/parse_environment.ush | 41 - .../source/shaders/unreal/tessellate.usf | 13 - .../shaders/unreal/visualize_buffer.usf | 23 - .../source/sk_rectanizer_skyline.cpp | 6 +- .../rive_renderer/source/sort_key_builder.hpp | 220 + .../source/vulkan/common_layouts.hpp | 200 + .../vulkan/draw_pipeline_layout_vulkan.cpp | 176 + .../vulkan/draw_pipeline_layout_vulkan.hpp | 56 + .../source/vulkan/draw_pipeline_vulkan.cpp | 582 + .../source/vulkan/draw_pipeline_vulkan.hpp | 74 + .../source/vulkan/draw_shader_vulkan.cpp | 857 +- .../source/vulkan/draw_shader_vulkan.hpp | 92 +- .../source/vulkan/pipeline_manager_vulkan.cpp | 664 + .../source/vulkan/pipeline_manager_vulkan.hpp | 144 + .../vulkan/render_context_vulkan_impl.cpp | 4468 +-- .../source/vulkan/render_pass_vulkan.cpp | 896 + .../source/vulkan/render_pass_vulkan.hpp | 106 + .../source/vulkan/render_target_vulkan.cpp | 164 +- .../rive_renderer/source/vulkan/vkutil.cpp | 95 +- .../source/vulkan/vulkan_context.cpp | 90 +- .../source/vulkan/vulkan_shaders.cpp | 456 + .../source/vulkan/vulkan_shaders.hpp | 132 + .../source/webgpu/em_js_handle.cpp | 100 - .../webgpu/render_context_webgpu_impl.cpp | 2536 +- .../webgpu/render_context_webgpu_vulkan.cpp | 343 - .../webgpu/render_context_webgpu_vulkan.hpp | 57 - .../webgpu/wagyu-port/include/webgpu/webgpu.h | 2828 ++ .../wagyu-port/include/webgpu/webgpu_cpp.h | 5833 ++++ .../webgpu/webgpu_cpp_chained_struct.h | 54 + .../webgpu/webgpu_enum_class_bitmasks.h | 161 + .../wagyu-port/include/webgpu/webgpu_wagyu.h | 689 + .../source/webgpu/wagyu-port/src/webgpu.c | 22 + .../source/webgpu/wagyu-port/webgpu-port.py | 123 + .../source/webgpu/webgpu_compat.h | 640 + thirdparty/rive_vendor_versions.json | 71 + .../sheenbidi_library/sheenbidi_library.c | 3 + .../yoga_library/upstream/yoga/Utils.cpp | 2 +- .../yoga_library/upstream/yoga/YGMacros.h | 8 +- .../yoga_library/upstream/yoga/YGNode.h | 5 + .../yoga_library/upstream/yoga/Yoga.cpp | 40 +- thirdparty/yoga_library/yoga_library.cpp | 3 + thirdparty/yoga_library/yoga_library.h | 4 + thirdparty/zlib/src/README | 100 +- thirdparty/zlib/src/adler32.c | 307 +- thirdparty/zlib/src/compress.c | 145 +- thirdparty/zlib/src/crc32.c | 1456 +- thirdparty/zlib/src/crc32.h | 9887 ++++++- thirdparty/zlib/src/deflate.c | 3818 +-- thirdparty/zlib/src/deflate.h | 710 +- thirdparty/zlib/src/gzclose.c | 23 + thirdparty/zlib/src/gzguts.h | 214 + thirdparty/zlib/src/gzlib.c | 582 + thirdparty/zlib/src/gzread.c | 602 + thirdparty/zlib/src/gzwrite.c | 631 + thirdparty/zlib/src/infback.c | 1239 +- thirdparty/zlib/src/inffast.c | 636 +- thirdparty/zlib/src/inffast.h | 22 +- thirdparty/zlib/src/inffixed.h | 188 +- thirdparty/zlib/src/inflate.c | 2865 +- thirdparty/zlib/src/inflate.h | 247 +- thirdparty/zlib/src/inftrees.c | 627 +- thirdparty/zlib/src/inftrees.h | 123 +- thirdparty/zlib/src/trees.c | 2308 +- thirdparty/zlib/src/trees.h | 255 +- thirdparty/zlib/src/uncompr.c | 145 +- thirdparty/zlib/src/zconf.h | 888 +- thirdparty/zlib/src/zconf.in.h | 332 - thirdparty/zlib/src/zlib.h | 3296 ++- thirdparty/zlib/src/zutil.c | 610 +- thirdparty/zlib/src/zutil.h | 525 +- thirdparty/zlib/zlib.c | 39 +- thirdparty/zlib/zlib.h | 34 + thirdparty/zlib/zlib_inffast.c | 28 + thirdparty/zlib/zlib_inflate.c | 28 + thirdparty/zlib/zlib_inftrees.c | 28 + tools/{update_rive.py => rive_update.py} | 132 +- tools/rive_update_manifest.json | 292 +- 2087 files changed, 411519 insertions(+), 154013 deletions(-) delete mode 100644 thirdparty/harfbuzz/upstream/ArabicPUASimplified.txt delete mode 100644 thirdparty/harfbuzz/upstream/ArabicPUATraditional.txt delete mode 100644 thirdparty/harfbuzz/upstream/addTable.py delete mode 100755 thirdparty/harfbuzz/upstream/check-c-linkage-decls.py delete mode 100755 thirdparty/harfbuzz/upstream/check-externs.py delete mode 100755 thirdparty/harfbuzz/upstream/check-header-guards.py delete mode 100755 thirdparty/harfbuzz/upstream/check-includes.py delete mode 100755 thirdparty/harfbuzz/upstream/check-libstdc++.py delete mode 100755 thirdparty/harfbuzz/upstream/check-static-inits.py delete mode 100755 thirdparty/harfbuzz/upstream/check-symbols.py delete mode 100755 thirdparty/harfbuzz/upstream/fix_get_types.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-arabic-joining-list.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-arabic-pua.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-arabic-table.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-def.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-emoji-table.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-harfbuzzcc.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-hb-version.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-indic-table.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-os2-unicode-ranges.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-ragel-artifacts.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-tag-table.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-ucd-table.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-use-table.py delete mode 100755 thirdparty/harfbuzz/upstream/gen-vowel-constraints.py create mode 100644 thirdparty/harfbuzz/upstream/graph/ligature-graph.hh delete mode 100644 thirdparty/harfbuzz/upstream/harfbuzz-cairo.pc.in delete mode 100644 thirdparty/harfbuzz/upstream/harfbuzz-config.cmake.in delete mode 100644 thirdparty/harfbuzz/upstream/harfbuzz-gobject.pc.in delete mode 100644 thirdparty/harfbuzz/upstream/harfbuzz-icu.pc.in delete mode 100644 thirdparty/harfbuzz/upstream/harfbuzz-subset.pc.in delete mode 100644 thirdparty/harfbuzz/upstream/harfbuzz.pc.in create mode 100644 thirdparty/harfbuzz/upstream/hb-alloc-pool.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-bit-vector.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-cff-specializer.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-cff-width-optimizer.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-coretext.cc rename thirdparty/harfbuzz/upstream/{hb-gobject-enums.h.tmpl => hb-coretext.hh} (64%) create mode 100644 thirdparty/harfbuzz/upstream/hb-decycler.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-directwrite-font.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-directwrite-shape.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-directwrite.hh delete mode 100644 thirdparty/harfbuzz/upstream/hb-features.h.in create mode 100644 thirdparty/harfbuzz/upstream/hb-fontations.h rename thirdparty/harfbuzz/upstream/{hb-pool.hh => hb-free-pool.hh} (92%) delete mode 100644 thirdparty/harfbuzz/upstream/hb-gobject-enums.cc.tmpl create mode 100644 thirdparty/harfbuzz/upstream/hb-harfrust.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-kbts.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-paint-bounded.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-paint-bounded.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-draw.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-image.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-image.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-paint.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-paint.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-base.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-base.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.cc rename thirdparty/harfbuzz/upstream/{test-machinery.cc => hb-raster-svg-bbox.hh} (66%) create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-clip.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-clip.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-color.cc rename thirdparty/harfbuzz/upstream/{test-unicode-ranges.cc => hb-raster-svg-color.hh} (59%) create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-context.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.cc rename thirdparty/harfbuzz/upstream/{test-multimap.cc => hb-raster-svg-defs-scan.hh} (54%) create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-defs.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-defs.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-fill.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-fill.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-parse.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-parse.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-render.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg-use.cc rename thirdparty/harfbuzz/upstream/{test-gpos-size-params.cc => hb-raster-svg-use.hh} (56%) create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-svg.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster-utils.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-raster.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-raster.h create mode 100644 thirdparty/harfbuzz/upstream/hb-script-list.h create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-plan-layout.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-plan-var.cc delete mode 100644 thirdparty/harfbuzz/upstream/hb-subset-repacker.h rename thirdparty/harfbuzz/upstream/{hb-subset-repacker.cc => hb-subset-serialize.cc} (68%) create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-serialize.h create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-table-cff.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-table-color.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-table-layout.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-table-other.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-table-var.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-subset-table.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-draw.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-paint.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-path.cc rename thirdparty/harfbuzz/upstream/{test-serialize.cc => hb-vector-svg-path.hh} (68%) create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-subset.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-subset.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-utils.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg-utils.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-vector-svg.hh create mode 100644 thirdparty/harfbuzz/upstream/hb-vector.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-vector.h delete mode 100644 thirdparty/harfbuzz/upstream/hb-version.h.in create mode 100644 thirdparty/harfbuzz/upstream/hb-zlib.cc create mode 100644 thirdparty/harfbuzz/upstream/hb-zlib.hh delete mode 100644 thirdparty/harfbuzz/upstream/justify.py delete mode 100644 thirdparty/harfbuzz/upstream/main.cc delete mode 100644 thirdparty/harfbuzz/upstream/meson.build delete mode 100644 thirdparty/harfbuzz/upstream/ms-use/COPYING delete mode 100644 thirdparty/harfbuzz/upstream/ms-use/IndicPositionalCategory-Additional.txt delete mode 100644 thirdparty/harfbuzz/upstream/ms-use/IndicShapingInvalidCluster.txt delete mode 100644 thirdparty/harfbuzz/upstream/ms-use/IndicSyllabicCategory-Additional.txt delete mode 100755 thirdparty/harfbuzz/upstream/relative_to.py delete mode 100755 thirdparty/harfbuzz/upstream/sample.py delete mode 100644 thirdparty/harfbuzz/upstream/test-algs.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-array.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-bimap.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-buffer-serialize.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-cff.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-gsub-get-alternates.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-gsub-would-substitute.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-item-varstore.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-iter.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-map.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-number.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-ot-glyphname.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-ot-meta.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-ot-name.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-priority-queue.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-repacker.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-set.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-subset-instancer-solver.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-tuple-varstore.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-use-table.cc delete mode 100644 thirdparty/harfbuzz/upstream/test-vector.cc delete mode 100755 thirdparty/harfbuzz/upstream/update-unicode-tables.make create mode 100644 thirdparty/harfbuzz/upstream/wasm/graphite/shape.cc create mode 100644 thirdparty/harfbuzz/upstream/wasm/sample/c/shape-fallback.cc create mode 100644 thirdparty/harfbuzz/upstream/wasm/sample/c/shape-ot.cc create mode 100644 thirdparty/libhydrogen/libhydrogen.c create mode 100644 thirdparty/libhydrogen/libhydrogen.h create mode 100644 thirdparty/libhydrogen/upstream/impl/common.h create mode 100644 thirdparty/libhydrogen/upstream/impl/core.h create mode 100644 thirdparty/libhydrogen/upstream/impl/gimli-core.h create mode 100644 thirdparty/libhydrogen/upstream/impl/gimli-core/portable.h create mode 100644 thirdparty/libhydrogen/upstream/impl/gimli-core/sse2.h create mode 100644 thirdparty/libhydrogen/upstream/impl/hash.h create mode 100644 thirdparty/libhydrogen/upstream/impl/hydrogen_p.h create mode 100644 thirdparty/libhydrogen/upstream/impl/kdf.h create mode 100644 thirdparty/libhydrogen/upstream/impl/kx.h create mode 100644 thirdparty/libhydrogen/upstream/impl/pwhash.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/avr.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/ch32.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/cheriot.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/chibios.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/esp32.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/linux_kernel.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/mbed.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/nrf52832.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/particle.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/riot.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/rtthread.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/stm32.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/unix.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/wasi.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/windows.h create mode 100644 thirdparty/libhydrogen/upstream/impl/random/zephyr.h create mode 100644 thirdparty/libhydrogen/upstream/impl/secretbox.h create mode 100644 thirdparty/libhydrogen/upstream/impl/sign.h create mode 100644 thirdparty/libhydrogen/upstream/impl/x25519.h create mode 100644 thirdparty/libhydrogen/upstream/libhydrogen.c create mode 100644 thirdparty/libhydrogen/upstream/libhydrogen.h delete mode 100644 thirdparty/libpng/upstream/arm/filter_neon.S delete mode 100644 thirdparty/libpng/upstream/contrib/.editorconfig delete mode 100644 thirdparty/libpng/upstream/contrib/arm-neon/README delete mode 100644 thirdparty/libpng/upstream/contrib/arm-neon/android-ndk.c delete mode 100644 thirdparty/libpng/upstream/contrib/arm-neon/linux-auxv.c delete mode 100644 thirdparty/libpng/upstream/contrib/arm-neon/linux.c create mode 100644 thirdparty/libpng/upstream/example.c create mode 100644 thirdparty/libpng/upstream/pnglibconf.h delete mode 100644 thirdparty/libpng/upstream/pngtest.c delete mode 100644 thirdparty/libwebp/upstream/src/dec/Makefile.am delete mode 100644 thirdparty/libwebp/upstream/src/dec/Makefile.in delete mode 100644 thirdparty/libwebp/upstream/src/demux/Makefile.am delete mode 100644 thirdparty/libwebp/upstream/src/demux/Makefile.in delete mode 100644 thirdparty/libwebp/upstream/src/demux/libwebpdemux.pc.in delete mode 100644 thirdparty/libwebp/upstream/src/demux/libwebpdemux.rc delete mode 100644 thirdparty/libwebp/upstream/src/dsp/Makefile.am delete mode 100644 thirdparty/libwebp/upstream/src/dsp/Makefile.in delete mode 100644 thirdparty/libwebp/upstream/src/enc/Makefile.am delete mode 100644 thirdparty/libwebp/upstream/src/enc/Makefile.in delete mode 100644 thirdparty/libwebp/upstream/src/mux/Makefile.am delete mode 100644 thirdparty/libwebp/upstream/src/mux/Makefile.in delete mode 100644 thirdparty/libwebp/upstream/src/mux/libwebpmux.pc.in delete mode 100644 thirdparty/libwebp/upstream/src/mux/libwebpmux.rc delete mode 100644 thirdparty/libwebp/upstream/src/utils/Makefile.am delete mode 100644 thirdparty/libwebp/upstream/src/utils/Makefile.in delete mode 100644 thirdparty/libwebp/upstream/src/webp/config.h.in create mode 100644 thirdparty/luau/luau.cpp create mode 100644 thirdparty/luau/luau.h create mode 100644 thirdparty/luau/luau_split.cpp create mode 100644 thirdparty/luau/upstream/Common/include/Luau/Bytecode.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/BytecodeUtils.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/Common.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/DenseHash.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/ExperimentalFlags.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/HashUtil.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/InsertionOrderedMap.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/ScopedSeenSet.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/SmallVector.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/StringUtils.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/TimeTrace.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/Variant.h create mode 100644 thirdparty/luau/upstream/Common/include/Luau/VecDeque.h create mode 100644 thirdparty/luau/upstream/Common/src/StringUtils.cpp create mode 100644 thirdparty/luau/upstream/Common/src/TimeTrace.cpp create mode 100644 thirdparty/luau/upstream/VM/include/lua.h create mode 100644 thirdparty/luau/upstream/VM/include/luaconf.h create mode 100644 thirdparty/luau/upstream/VM/include/lualib.h create mode 100644 thirdparty/luau/upstream/VM/src/lapi.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lapi.h create mode 100644 thirdparty/luau/upstream/VM/src/laux.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lbaselib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lbitlib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lbuffer.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lbuffer.h create mode 100644 thirdparty/luau/upstream/VM/src/lbuflib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lbuiltins.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lbuiltins.h create mode 100644 thirdparty/luau/upstream/VM/src/lbytecode.h create mode 100644 thirdparty/luau/upstream/VM/src/lcommon.h create mode 100644 thirdparty/luau/upstream/VM/src/lcorolib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ldblib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ldebug.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ldebug.h create mode 100644 thirdparty/luau/upstream/VM/src/ldo.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ldo.h create mode 100644 thirdparty/luau/upstream/VM/src/lfunc.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lfunc.h create mode 100644 thirdparty/luau/upstream/VM/src/lgc.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lgc.h create mode 100644 thirdparty/luau/upstream/VM/src/lgcdebug.cpp create mode 100644 thirdparty/luau/upstream/VM/src/linit.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lmathlib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lmem.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lmem.h create mode 100644 thirdparty/luau/upstream/VM/src/lnumprint.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lnumutils.h create mode 100644 thirdparty/luau/upstream/VM/src/lobject.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lobject.h create mode 100644 thirdparty/luau/upstream/VM/src/loslib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lperf.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lstate.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lstate.h create mode 100644 thirdparty/luau/upstream/VM/src/lstring.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lstring.h create mode 100644 thirdparty/luau/upstream/VM/src/lstrlib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ltable.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ltable.h create mode 100644 thirdparty/luau/upstream/VM/src/ltablib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ltm.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ltm.h create mode 100644 thirdparty/luau/upstream/VM/src/ludata.cpp create mode 100644 thirdparty/luau/upstream/VM/src/ludata.h create mode 100644 thirdparty/luau/upstream/VM/src/lutf8lib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lveclib.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lvm.h create mode 100644 thirdparty/luau/upstream/VM/src/lvmexecute.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lvmload.cpp create mode 100644 thirdparty/luau/upstream/VM/src/lvmutils.cpp create mode 100644 thirdparty/rive/include/rive/animation/focus_action.hpp create mode 100644 thirdparty/rive/include/rive/animation/focus_action_target.hpp create mode 100644 thirdparty/rive/include/rive/animation/focus_action_traversal.hpp create mode 100644 thirdparty/rive/include/rive/animation/focus_listener_group.hpp delete mode 100644 thirdparty/rive/include/rive/animation/hittable.hpp create mode 100644 thirdparty/rive/include/rive/animation/keyboard_listener_group.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_invocation.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_types/listener_input_type.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_types/listener_input_type_event.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_types/listener_input_type_keyboard.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_types/listener_input_type_semantic.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_types/listener_input_type_text.hpp create mode 100644 thirdparty/rive/include/rive/animation/listener_types/listener_input_type_viewmodel.hpp create mode 100644 thirdparty/rive/include/rive/animation/scripted_listener_action.hpp create mode 100644 thirdparty/rive/include/rive/animation/scripted_transition_condition.hpp create mode 100644 thirdparty/rive/include/rive/animation/semantic_listener_group.hpp create mode 100644 thirdparty/rive/include/rive/animation/state_machine_fire_action.hpp create mode 100644 thirdparty/rive/include/rive/animation/state_machine_fire_trigger.hpp create mode 100644 thirdparty/rive/include/rive/animation/state_machine_listener_single.hpp create mode 100644 thirdparty/rive/include/rive/animation/text_input_listener_group.hpp create mode 100644 thirdparty/rive/include/rive/animation/transition_property_component_comparator.hpp create mode 100644 thirdparty/rive/include/rive/animation/transition_self_comparator.hpp create mode 100644 thirdparty/rive/include/rive/animation/transition_value_artboard_comparator.hpp create mode 100644 thirdparty/rive/include/rive/animation/transition_value_asset_comparator.hpp create mode 100644 thirdparty/rive/include/rive/animation/transition_value_id_comparator.hpp create mode 100644 thirdparty/rive/include/rive/artboard_list_map_rule.hpp create mode 100644 thirdparty/rive/include/rive/artboard_referencer.hpp create mode 100644 thirdparty/rive/include/rive/assets/blob_asset.hpp create mode 100644 thirdparty/rive/include/rive/assets/manifest_asset.hpp create mode 100644 thirdparty/rive/include/rive/assets/script_asset.hpp create mode 100644 thirdparty/rive/include/rive/assets/shader_asset.hpp create mode 100644 thirdparty/rive/include/rive/assets/text_asset.hpp create mode 100644 thirdparty/rive/include/rive/async/work_pool.hpp create mode 100644 thirdparty/rive/include/rive/async/work_task.hpp create mode 100644 thirdparty/rive/include/rive/bindable_artboard.hpp create mode 100644 thirdparty/rive/include/rive/constraints/constrainable_list.hpp create mode 100644 thirdparty/rive/include/rive/constraints/list_constraint.hpp create mode 100644 thirdparty/rive/include/rive/constraints/list_follow_path_constraint.hpp create mode 100644 thirdparty/rive/include/rive/constraints/scrolling/scroll_virtualizer.hpp create mode 100644 thirdparty/rive/include/rive/core/vector_binary_stream.hpp create mode 100644 thirdparty/rive/include/rive/custom_property_color.hpp create mode 100644 thirdparty/rive/include/rive/custom_property_container.hpp create mode 100644 thirdparty/rive/include/rive/custom_property_enum.hpp create mode 100644 thirdparty/rive/include/rive/custom_property_trigger.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/bindable_property_artboard.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/bindable_property_id.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/bindable_property_list.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/bindable_property_viewmodel.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/context/context_target_value.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/context/context_value_any.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/context/context_value_artboard.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/context/context_value_viewmodel.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/converters/data_converter_list_to_length.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/converters/data_converter_to_number.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/data_bind_container.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/data_bind_path.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/data_bind_viewmodel_consumer.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/data_values/data_value_artboard.hpp create mode 100644 thirdparty/rive/include/rive/data_bind/data_values/data_value_viewmodel.hpp create mode 100644 thirdparty/rive/include/rive/data_bind_path_referencer.hpp create mode 100644 thirdparty/rive/include/rive/data_resolver.hpp delete mode 100644 thirdparty/rive/include/rive/enum_bitset.hpp create mode 100644 thirdparty/rive/include/rive/enums.hpp create mode 100644 thirdparty/rive/include/rive/focus_data.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/focus_action_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/focus_action_target_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/focus_action_traversal_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_event_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_text_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_viewmodel_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/scripted_listener_action_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/scripted_transition_condition_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/state_machine_fire_action_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/state_machine_fire_trigger_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/state_machine_listener_single_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/transition_property_component_comparator_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/transition_self_comparator_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/transition_value_artboard_comparator_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/transition_value_asset_comparator_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/animation/transition_value_id_comparator_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/artboard_list_map_rule_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/assets/blob_asset_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/assets/manifest_asset_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/assets/script_asset_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/assets/shader_asset_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/assets/text_asset_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/constraints/list_follow_path_constraint_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/custom_property_color_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/custom_property_enum_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/custom_property_trigger_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/bindable_property_artboard_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/bindable_property_id_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/bindable_property_list_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/bindable_property_viewmodel_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_list_to_length_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_to_number_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/data_bind/data_bind_path_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/focus_data_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/inputs/keyboard_input_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/inputs/semantic_input_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/inputs/user_input_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/layout/artboard_component_list_override_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_artboard_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_boolean_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_color_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_number_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_string_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_trigger_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/script_input_viewmodel_property_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/scripted/scripted_data_converter_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/scripted/scripted_drawable_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/scripted/scripted_layout_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/scripted/scripted_path_effect_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/semantic/semantic_data_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/shapes/list_path_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/shapes/paint/group_effect_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/shapes/paint/target_effect_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/shapes/points_common_path_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp create mode 100644 thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_artboard_base.hpp create mode 100644 thirdparty/rive/include/rive/importers/data_bind_path_importer.hpp create mode 100644 thirdparty/rive/include/rive/importers/listener_input_type_keyboard_importer.hpp create mode 100644 thirdparty/rive/include/rive/importers/listener_input_type_semantic_importer.hpp create mode 100644 thirdparty/rive/include/rive/importers/scripted_object_importer.hpp create mode 100644 thirdparty/rive/include/rive/importers/text_asset_importer.hpp create mode 100644 thirdparty/rive/include/rive/input/focus_listener.hpp create mode 100644 thirdparty/rive/include/rive/input/focus_manager.hpp create mode 100644 thirdparty/rive/include/rive/input/focus_node.hpp create mode 100644 thirdparty/rive/include/rive/input/focusable.hpp create mode 100644 thirdparty/rive/include/rive/input/keyboard_listener.hpp create mode 100644 thirdparty/rive/include/rive/inputs/keyboard_input.hpp create mode 100644 thirdparty/rive/include/rive/inputs/keyboard_key_phase.hpp create mode 100644 thirdparty/rive/include/rive/inputs/semantic_input.hpp create mode 100644 thirdparty/rive/include/rive/inputs/user_input.hpp create mode 100644 thirdparty/rive/include/rive/layout/artboard_component_list_override.hpp create mode 100644 thirdparty/rive/include/rive/layout/style_overrider.hpp create mode 100644 thirdparty/rive/include/rive/listener_group.hpp create mode 100644 thirdparty/rive/include/rive/lua/lua_state.hpp create mode 100644 thirdparty/rive/include/rive/lua/rive_lua_libs.hpp create mode 100644 thirdparty/rive/include/rive/lua/scripting_vm.hpp create mode 100644 thirdparty/rive/include/rive/manifest_sections.hpp create mode 100644 thirdparty/rive/include/rive/math/bitwise.hpp create mode 100644 thirdparty/rive/include/rive/math/mat4.hpp create mode 100644 thirdparty/rive/include/rive/math/random.hpp create mode 100644 thirdparty/rive/include/rive/parent_traversal.hpp create mode 100644 thirdparty/rive/include/rive/profiler/microprofile_emscripten.h create mode 100644 thirdparty/rive/include/rive/profiler/profiler_macros.h create mode 100644 thirdparty/rive/include/rive/profiler/rive_profile.hpp create mode 100644 thirdparty/rive/include/rive/property_recorder.hpp create mode 100644 thirdparty/rive/include/rive/random_mode.hpp create mode 100644 thirdparty/rive/include/rive/resetting_component.hpp create mode 100644 thirdparty/rive/include/rive/script_input_artboard.hpp create mode 100644 thirdparty/rive/include/rive/script_input_boolean.hpp create mode 100644 thirdparty/rive/include/rive/script_input_color.hpp create mode 100644 thirdparty/rive/include/rive/script_input_number.hpp create mode 100644 thirdparty/rive/include/rive/script_input_string.hpp create mode 100644 thirdparty/rive/include/rive/script_input_trigger.hpp create mode 100644 thirdparty/rive/include/rive/script_input_viewmodel_property.hpp create mode 100644 thirdparty/rive/include/rive/scripted/scripted_data_converter.hpp create mode 100644 thirdparty/rive/include/rive/scripted/scripted_drawable.hpp create mode 100644 thirdparty/rive/include/rive/scripted/scripted_layout.hpp create mode 100644 thirdparty/rive/include/rive/scripted/scripted_object.hpp create mode 100644 thirdparty/rive/include/rive/scripted/scripted_path_effect.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_data.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_dirt.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_listener.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_manager.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_node.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_provider.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_role.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_snapshot.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_state.hpp create mode 100644 thirdparty/rive/include/rive/semantic/semantic_trait.hpp create mode 100644 thirdparty/rive/include/rive/shape_paint_type.hpp create mode 100644 thirdparty/rive/include/rive/shapes/list_path.hpp create mode 100644 thirdparty/rive/include/rive/shapes/paint/effects_container.hpp create mode 100644 thirdparty/rive/include/rive/shapes/paint/group_effect.hpp create mode 100644 thirdparty/rive/include/rive/shapes/paint/target_effect.hpp create mode 100644 thirdparty/rive/include/rive/shapes/points_common_path.hpp create mode 100644 thirdparty/rive/include/rive/signed_content_header.hpp create mode 100644 thirdparty/rive/include/rive/texture_archive.hpp create mode 100644 thirdparty/rive/include/rive/viewmodel/property_symbol_dependent.hpp create mode 100644 thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_artboard_runtime.hpp create mode 100644 thirdparty/rive/include/rive/viewmodel/symbol_type.hpp create mode 100644 thirdparty/rive/include/rive/viewmodel/viewmodel_instance_artboard.hpp create mode 100644 thirdparty/rive/include/rive/viewmodel/viewmodel_property_artboard.hpp create mode 100644 thirdparty/rive/include/rive/viewmodel/viewmodel_value_dependent.hpp create mode 100644 thirdparty/rive/include/rive/virtualizing_component.hpp create mode 100644 thirdparty/rive/source/animation/focus_action_target.cpp create mode 100644 thirdparty/rive/source/animation/focus_action_traversal.cpp create mode 100644 thirdparty/rive/source/animation/focus_listener_group.cpp delete mode 100644 thirdparty/rive/source/animation/hittable.cpp create mode 100644 thirdparty/rive/source/animation/keyboard_listener_group.cpp create mode 100644 thirdparty/rive/source/animation/listener_invocation.cpp create mode 100644 thirdparty/rive/source/animation/listener_types/listener_input_type.cpp create mode 100644 thirdparty/rive/source/animation/listener_types/listener_input_type_keyboard.cpp create mode 100644 thirdparty/rive/source/animation/listener_types/listener_input_type_semantic.cpp create mode 100644 thirdparty/rive/source/animation/listener_types/listener_input_type_viewmodel.cpp create mode 100644 thirdparty/rive/source/animation/property_recorder.cpp create mode 100644 thirdparty/rive/source/animation/scripted_listener_action.cpp create mode 100644 thirdparty/rive/source/animation/scripted_transition_condition.cpp create mode 100644 thirdparty/rive/source/animation/semantic_listener_group.cpp create mode 100644 thirdparty/rive/source/animation/state_machine_fire_action.cpp create mode 100644 thirdparty/rive/source/animation/state_machine_fire_trigger.cpp create mode 100644 thirdparty/rive/source/animation/state_machine_listener_single.cpp create mode 100644 thirdparty/rive/source/animation/text_input_listener_group.cpp delete mode 100644 thirdparty/rive/source/animation/transition_property_artboard_comparator.cpp delete mode 100644 thirdparty/rive/source/animation/transition_value_boolean_comparator.cpp delete mode 100644 thirdparty/rive/source/animation/transition_value_color_comparator.cpp delete mode 100644 thirdparty/rive/source/animation/transition_value_enum_comparator.cpp delete mode 100644 thirdparty/rive/source/animation/transition_value_number_comparator.cpp delete mode 100644 thirdparty/rive/source/animation/transition_value_string_comparator.cpp create mode 100644 thirdparty/rive/source/artboard_list_map_rule.cpp create mode 100644 thirdparty/rive/source/artboard_referencer.cpp create mode 100644 thirdparty/rive/source/assets/blob_asset.cpp create mode 100644 thirdparty/rive/source/assets/manifest_asset.cpp create mode 100644 thirdparty/rive/source/assets/script_asset.cpp create mode 100644 thirdparty/rive/source/assets/shader_asset.cpp create mode 100644 thirdparty/rive/source/async/work_pool.cpp create mode 100644 thirdparty/rive/source/bindable_artboard.cpp create mode 100644 thirdparty/rive/source/constraints/constrainable_list.cpp create mode 100644 thirdparty/rive/source/constraints/draggable_constraint.cpp create mode 100644 thirdparty/rive/source/constraints/list_constraint.cpp create mode 100644 thirdparty/rive/source/constraints/list_follow_path_constraint.cpp create mode 100644 thirdparty/rive/source/constraints/scrolling/scroll_virtualizer.cpp create mode 100644 thirdparty/rive/source/custom_property_container.cpp create mode 100644 thirdparty/rive/source/data_bind/context/context_target_value.cpp create mode 100644 thirdparty/rive/source/data_bind/context/context_value_any.cpp create mode 100644 thirdparty/rive/source/data_bind/context/context_value_artboard.cpp create mode 100644 thirdparty/rive/source/data_bind/context/context_value_viewmodel.cpp create mode 100644 thirdparty/rive/source/data_bind/converters/data_converter_list_to_length.cpp create mode 100644 thirdparty/rive/source/data_bind/converters/data_converter_to_number.cpp create mode 100644 thirdparty/rive/source/data_bind/data_bind_container.cpp create mode 100644 thirdparty/rive/source/data_bind/data_bind_path.cpp create mode 100644 thirdparty/rive/source/data_bind/data_bind_viewmodel_consumer.cpp create mode 100644 thirdparty/rive/source/data_bind_path_referencer.cpp create mode 100644 thirdparty/rive/source/focus_data.cpp create mode 100644 thirdparty/rive/source/generated/animation/focus_action_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/focus_action_target_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/focus_action_traversal_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/listener_types/listener_input_type_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/listener_types/listener_input_type_event_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/listener_types/listener_input_type_keyboard_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/listener_types/listener_input_type_semantic_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/listener_types/listener_input_type_text_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/listener_types/listener_input_type_viewmodel_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/scripted_listener_action_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/scripted_transition_condition_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/state_machine_fire_action_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/state_machine_fire_trigger_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/state_machine_listener_single_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/transition_property_component_comparator_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/transition_self_comparator_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/transition_value_artboard_comparator_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/transition_value_asset_comparator_base.cpp create mode 100644 thirdparty/rive/source/generated/animation/transition_value_id_comparator_base.cpp create mode 100644 thirdparty/rive/source/generated/artboard_list_map_rule_base.cpp create mode 100644 thirdparty/rive/source/generated/assets/blob_asset_base.cpp create mode 100644 thirdparty/rive/source/generated/assets/manifest_asset_base.cpp create mode 100644 thirdparty/rive/source/generated/assets/script_asset_base.cpp create mode 100644 thirdparty/rive/source/generated/assets/shader_asset_base.cpp create mode 100644 thirdparty/rive/source/generated/constraints/list_follow_path_constraint_base.cpp create mode 100644 thirdparty/rive/source/generated/custom_property_color_base.cpp create mode 100644 thirdparty/rive/source/generated/custom_property_enum_base.cpp create mode 100644 thirdparty/rive/source/generated/custom_property_trigger_base.cpp create mode 100644 thirdparty/rive/source/generated/data_bind/bindable_property_artboard_base.cpp create mode 100644 thirdparty/rive/source/generated/data_bind/bindable_property_list_base.cpp create mode 100644 thirdparty/rive/source/generated/data_bind/bindable_property_viewmodel_base.cpp create mode 100644 thirdparty/rive/source/generated/data_bind/converters/data_converter_list_to_length_base.cpp create mode 100644 thirdparty/rive/source/generated/data_bind/converters/data_converter_to_number_base.cpp create mode 100644 thirdparty/rive/source/generated/data_bind/data_bind_path_base.cpp create mode 100644 thirdparty/rive/source/generated/focus_data_base.cpp create mode 100644 thirdparty/rive/source/generated/inputs/keyboard_input_base.cpp create mode 100644 thirdparty/rive/source/generated/inputs/semantic_input_base.cpp create mode 100644 thirdparty/rive/source/generated/inputs/user_input_base.cpp create mode 100644 thirdparty/rive/source/generated/layout/artboard_component_list_override_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_artboard_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_boolean_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_color_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_number_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_string_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_trigger_base.cpp create mode 100644 thirdparty/rive/source/generated/script_input_viewmodel_property_base.cpp create mode 100644 thirdparty/rive/source/generated/scripted/scripted_data_converter_base.cpp create mode 100644 thirdparty/rive/source/generated/scripted/scripted_drawable_base.cpp create mode 100644 thirdparty/rive/source/generated/scripted/scripted_layout_base.cpp create mode 100644 thirdparty/rive/source/generated/scripted/scripted_path_effect_base.cpp create mode 100644 thirdparty/rive/source/generated/semantic/semantic_data_base.cpp create mode 100644 thirdparty/rive/source/generated/shapes/list_path_base.cpp create mode 100644 thirdparty/rive/source/generated/shapes/paint/group_effect_base.cpp create mode 100644 thirdparty/rive/source/generated/shapes/paint/target_effect_base.cpp create mode 100644 thirdparty/rive/source/generated/viewmodel/viewmodel_instance_artboard_base.cpp create mode 100644 thirdparty/rive/source/generated/viewmodel/viewmodel_instance_value_base.cpp create mode 100644 thirdparty/rive/source/generated/viewmodel/viewmodel_property_artboard_base.cpp create mode 100644 thirdparty/rive/source/importers/data_bind_path_importer.cpp create mode 100644 thirdparty/rive/source/importers/listener_input_type_keyboard_importer.cpp create mode 100644 thirdparty/rive/source/importers/listener_input_type_semantic_importer.cpp create mode 100644 thirdparty/rive/source/importers/scripted_object_importer.cpp create mode 100644 thirdparty/rive/source/importers/text_asset_importer.cpp create mode 100644 thirdparty/rive/source/input/focus_manager.cpp create mode 100644 thirdparty/rive/source/input/focus_node.cpp create mode 100644 thirdparty/rive/source/input/focusable.cpp create mode 100644 thirdparty/rive/source/inputs/keyboard_input.cpp create mode 100644 thirdparty/rive/source/inputs/semantic_input.cpp create mode 100644 thirdparty/rive/source/layout/artboard_component_list_override.cpp create mode 100644 thirdparty/rive/source/listener_group.cpp create mode 100644 thirdparty/rive/source/lua/lua_artboards.cpp create mode 100644 thirdparty/rive/source/lua/lua_audio.cpp create mode 100644 thirdparty/rive/source/lua/lua_buffer_ext.cpp create mode 100644 thirdparty/rive/source/lua/lua_data_context.cpp create mode 100644 thirdparty/rive/source/lua/lua_data_value.cpp create mode 100644 thirdparty/rive/source/lua/lua_image_decode.cpp create mode 100644 thirdparty/rive/source/lua/lua_listener_invocation.cpp create mode 100644 thirdparty/rive/source/lua/lua_promise.cpp create mode 100644 thirdparty/rive/source/lua/lua_properties.cpp create mode 100644 thirdparty/rive/source/lua/lua_rive_base.cpp create mode 100644 thirdparty/rive/source/lua/lua_scripted_context.cpp create mode 100644 thirdparty/rive/source/lua/lua_scripted_context_apple.mm create mode 100644 thirdparty/rive/source/lua/lua_state.cpp create mode 100644 thirdparty/rive/source/lua/math/lua_color.cpp create mode 100644 thirdparty/rive/source/lua/math/lua_input.cpp create mode 100644 thirdparty/rive/source/lua/math/lua_mat2d.cpp create mode 100644 thirdparty/rive/source/lua/math/lua_mat4.cpp create mode 100644 thirdparty/rive/source/lua/math/lua_math.cpp create mode 100644 thirdparty/rive/source/lua/math/lua_vec2d.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_blob.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_gpu.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_gpu_apple.mm create mode 100644 thirdparty/rive/source/lua/renderer/lua_gradient.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_image.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_mesh.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_paint.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_path.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_renderer.cpp create mode 100644 thirdparty/rive/source/lua/renderer/lua_renderer_library.cpp create mode 100644 thirdparty/rive/source/lua/rive_lua_libs.cpp create mode 100644 thirdparty/rive/source/math/random.cpp create mode 100644 thirdparty/rive/source/parent_traversal.cpp create mode 100644 thirdparty/rive/source/profiler/profiler.cpp create mode 100644 thirdparty/rive/source/profiler/rive_profile.cpp create mode 100644 thirdparty/rive/source/resetting_component.cpp create mode 100644 thirdparty/rive/source/script_input_artboard.cpp create mode 100644 thirdparty/rive/source/script_input_boolean.cpp create mode 100644 thirdparty/rive/source/script_input_color.cpp create mode 100644 thirdparty/rive/source/script_input_number.cpp create mode 100644 thirdparty/rive/source/script_input_string.cpp create mode 100644 thirdparty/rive/source/script_input_trigger.cpp create mode 100644 thirdparty/rive/source/script_input_viewmodel_property.cpp create mode 100644 thirdparty/rive/source/scripted/scripted_data_converter.cpp create mode 100644 thirdparty/rive/source/scripted/scripted_drawable.cpp create mode 100644 thirdparty/rive/source/scripted/scripted_layout.cpp create mode 100644 thirdparty/rive/source/scripted/scripted_object.cpp create mode 100644 thirdparty/rive/source/scripted/scripted_path_effect.cpp create mode 100644 thirdparty/rive/source/semantic/semantic_data.cpp create mode 100644 thirdparty/rive/source/semantic/semantic_inference_registry.cpp create mode 100644 thirdparty/rive/source/semantic/semantic_inference_registry.hpp create mode 100644 thirdparty/rive/source/semantic/semantic_manager.cpp create mode 100644 thirdparty/rive/source/semantic/semantic_provider.cpp create mode 100644 thirdparty/rive/source/shapes/list_path.cpp create mode 100644 thirdparty/rive/source/shapes/paint/effects_container.cpp create mode 100644 thirdparty/rive/source/shapes/paint/group_effect.cpp create mode 100644 thirdparty/rive/source/shapes/paint/stroke_effect.cpp create mode 100644 thirdparty/rive/source/shapes/paint/target_effect.cpp create mode 100644 thirdparty/rive/source/shapes/points_common_path.cpp create mode 100644 thirdparty/rive/source/texture_archive.cpp create mode 100644 thirdparty/rive/source/viewmodel/property_symbol_dependent.cpp create mode 100644 thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_artboard_runtime.cpp create mode 100644 thirdparty/rive/source/viewmodel/viewmodel_instance_artboard.cpp create mode 100644 thirdparty/rive/source/virtualizing_component.cpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/async_pipeline_manager.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/d3d/d3d_utils.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/gl/load_gles_extensions.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group_layout.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_binding_map.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_buffer.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d11.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d12.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_gl.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_metal.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_vulkan.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_wgpu.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_pipeline.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_render_pass.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_sampler.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_shader_module.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_texture.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/ore/ore_types.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/render_canvas.hpp create mode 100644 thirdparty/rive_renderer/include/rive/renderer/shader_compilation_mode.hpp delete mode 100644 thirdparty/rive_renderer/include/rive/renderer/webgpu/em_js_handle.hpp create mode 100644 thirdparty/rive_renderer/source/d3d/d3d_utils.cpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/advanced_blend.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/atomic_draw.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/bezier_utils.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.minified.glsl delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/color_ramp.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/common.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/common.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/constants.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/constants.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.frag.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.vert.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.minified.frag delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.glsl.hpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.minified.glsl delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.hpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.glsl.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.frag delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.glsl create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.minified.vert create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.hpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.glsl.hpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.glsl create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.vert create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_mesh.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.minified.frag delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path.glsl.hpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.glsl create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.vert create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.hpp delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path_common.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.minified.glsl delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/hlsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/image_draw_uniforms.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/image_draw_uniforms.glsl.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/image_draw_uniforms.minified.glsl create mode 100644 thirdparty/rive_renderer/source/generated/shaders/init_clockwise_atomic_workaround.frag.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/init_clockwise_atomic_workaround.frag.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/init_clockwise_atomic_workaround.minified.frag create mode 100644 thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_appletvos.metallib create mode 100644 thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_appletvsimulator.metallib create mode 100644 thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_xros.metallib create mode 100644 thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_xros_simulator.metallib delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/metal.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/metal.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/render_atlas.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.hpp create mode 100644 thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.minified.glsl delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/rhi.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/rive_renderer_appletvos.metallib.c create mode 100644 thirdparty/rive_renderer/source/generated/shaders/rive_renderer_appletvsimulator.metallib.c create mode 100644 thirdparty/rive_renderer/source/generated/shaders/rive_renderer_xros.metallib.c create mode 100644 thirdparty/rive_renderer/source/generated/shaders/rive_renderer_xros_simulator.metallib.c delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/specialization.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/specialization.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_image_mesh.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_image_mesh.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_image_mesh.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_image_mesh.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_stencil.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_stencil.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_stencil.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_stencil.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_stencil.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_stencil.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.webgpu_frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.webgpu_frag.spirv create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.webgpu_vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.webgpu_vert.spirv delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/stencil_draw.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.exports.h delete mode 100644 thirdparty/rive_renderer/source/generated/shaders/tessellate.exports.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.exports.h create mode 100644 thirdparty/rive_renderer/source/instance_chunker.hpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_bind_group_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_buffer_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_context_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_pipeline_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_render_pass_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_sampler_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_shader_module_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d11/ore_texture_d3d11.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_context_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_bind_group_apply.hpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_root_sig.hpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d11_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d12.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_bind_group_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_context_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_context_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_context_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_texture_metal.mm create mode 100644 thirdparty/rive_renderer/source/ore/metal/ore_texture_metal_gl.mm create mode 100644 thirdparty/rive_renderer/source/ore/ore_bind_group_layout.cpp create mode 100644 thirdparty/rive_renderer/source/ore/ore_binding_map.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_bind_group_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_buffer_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_context_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_pipeline_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vk_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_resources_vk_gl.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_sampler_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_shader_module_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_texture_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/ore/vulkan/ore_vulkan_dsl.hpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_bind_group_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_buffer_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_context_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_pipeline_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_render_pass_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_sampler_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_shader_module_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_texture_wgpu.cpp create mode 100644 thirdparty/rive_renderer/source/ore/wgpu/ore_wgpu_layout.hpp create mode 100644 thirdparty/rive_renderer/source/shaders/clear_clockwise_atomic_clip.glsl delete mode 100644 thirdparty/rive_renderer/source/shaders/d3d/color_ramp.hlsl_ delete mode 100644 thirdparty/rive_renderer/source/shaders/d3d/render_atlas.hlsl_ delete mode 100644 thirdparty/rive_renderer/source/shaders/d3d/root.sig_ delete mode 100644 thirdparty/rive_renderer/source/shaders/d3d/tessellate.hlsl_ create mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_borrowed_coverage.frag create mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_clip.frag create mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_path.frag create mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_clip.frag delete mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_image_mesh.glsl create mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_path.frag delete mode 100644 thirdparty/rive_renderer/source/shaders/draw_clockwise_path.glsl create mode 100644 thirdparty/rive_renderer/source/shaders/draw_fullscreen_quad.vert delete mode 100644 thirdparty/rive_renderer/source/shaders/draw_image_mesh.glsl create mode 100644 thirdparty/rive_renderer/source/shaders/draw_image_mesh.vert create mode 100644 thirdparty/rive_renderer/source/shaders/draw_input_attachment.frag create mode 100644 thirdparty/rive_renderer/source/shaders/draw_mesh.frag create mode 100644 thirdparty/rive_renderer/source/shaders/draw_msaa_object.frag create mode 100644 thirdparty/rive_renderer/source/shaders/draw_msaa_resolve.frag rename thirdparty/rive_renderer/source/shaders/{draw_path.glsl => draw_path.vert} (55%) create mode 100644 thirdparty/rive_renderer/source/shaders/draw_raster_order_path.frag create mode 100644 thirdparty/rive_renderer/source/shaders/flush_uniforms.glsl create mode 100644 thirdparty/rive_renderer/source/shaders/image_draw_uniforms.glsl create mode 100644 thirdparty/rive_renderer/source/shaders/init_clockwise_atomic_workaround.frag create mode 100644 thirdparty/rive_renderer/source/shaders/resolve_atlas.glsl rename thirdparty/rive_renderer/source/shaders/spirv/{blit_texture_as_draw.main => blit_texture_as_draw_filtered.main} (67%) create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/clear_clockwise_atomic_clip.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_atlas_blit.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_image_mesh.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_interior_triangles.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_path.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip_interior_triangles.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_fullscreen_quad.vert create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_input_attachment.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_atlas_blit.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_color_seed_attachment.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_image_mesh.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_path.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_resolve.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_stencil.main create mode 100644 thirdparty/rive_renderer/source/shaders/spirv/init_clockwise_atomic_workaround.frag create mode 100644 thirdparty/rive_renderer/source/shaders/spirv_binary_to_header.py delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_base.ush delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_atlas_blit.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_mesh.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_rect.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_interior_triangles.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_path.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/atomic_resolve_pls.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/blt_u324_to_f4.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/blt_u32_as_f4.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/color_ramp.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_fill.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_stroke.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/draw_image_mesh.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/draw_interior_triangles.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/draw_path.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/parse_environment.ush delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/tessellate.usf delete mode 100644 thirdparty/rive_renderer/source/shaders/unreal/visualize_buffer.usf create mode 100644 thirdparty/rive_renderer/source/sort_key_builder.hpp create mode 100644 thirdparty/rive_renderer/source/vulkan/common_layouts.hpp create mode 100644 thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.hpp create mode 100644 thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.hpp create mode 100644 thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.hpp create mode 100644 thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.cpp create mode 100644 thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.hpp create mode 100644 thirdparty/rive_renderer/source/vulkan/vulkan_shaders.cpp create mode 100644 thirdparty/rive_renderer/source/vulkan/vulkan_shaders.hpp delete mode 100644 thirdparty/rive_renderer/source/webgpu/em_js_handle.cpp delete mode 100644 thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.cpp delete mode 100644 thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.hpp create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu.h create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp.h create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp_chained_struct.h create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_enum_class_bitmasks.h create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/src/webgpu.c create mode 100644 thirdparty/rive_renderer/source/webgpu/wagyu-port/webgpu-port.py create mode 100644 thirdparty/rive_renderer/source/webgpu/webgpu_compat.h create mode 100644 thirdparty/rive_vendor_versions.json create mode 100644 thirdparty/zlib/src/gzclose.c create mode 100644 thirdparty/zlib/src/gzguts.h create mode 100644 thirdparty/zlib/src/gzlib.c create mode 100644 thirdparty/zlib/src/gzread.c create mode 100644 thirdparty/zlib/src/gzwrite.c delete mode 100644 thirdparty/zlib/src/zconf.in.h create mode 100644 thirdparty/zlib/zlib_inffast.c create mode 100644 thirdparty/zlib/zlib_inflate.c create mode 100644 thirdparty/zlib/zlib_inftrees.c rename tools/{update_rive.py => rive_update.py} (86%) diff --git a/.gitignore b/.gitignore index 5eca3712c..064ddd3d5 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ cmake-build* out/* # Ides/Agents +.gitnexus/ .vscode/ .idea/ .vs/ diff --git a/justfile b/justfile index 5008b49f9..749b29835 100644 --- a/justfile +++ b/justfile @@ -98,6 +98,5 @@ python_uninstall: python_test *TEST_OPTS: python -m pytest -s {{TEST_OPTS}} -bump_rive: - uv run python tools/bump_rive.py --rive-ref runtime-v0.1.62 --allow-dirty - +rive_update REF="runtime-v0.1.62": + uv run python tools/rive_update.py --rive-ref {{REF}} --allow-dirty --keep-work-dir diff --git a/modules/yup_graphics/imaging/yup_Image.cpp b/modules/yup_graphics/imaging/yup_Image.cpp index 241b6bcd3..3073e69bb 100644 --- a/modules/yup_graphics/imaging/yup_Image.cpp +++ b/modules/yup_graphics/imaging/yup_Image.cpp @@ -173,6 +173,7 @@ bool Image::createTextureIfNotPresent (GraphicsContext& context) const width, height, rive::math::msb (width | height), + rive::GPUTextureFormat::rgba32, getRawData().data()); return true; diff --git a/modules/yup_graphics/native/yup_GraphicsContext_headless.cpp b/modules/yup_graphics/native/yup_GraphicsContext_headless.cpp index 4765339da..6ce7cc979 100644 --- a/modules/yup_graphics/native/yup_GraphicsContext_headless.cpp +++ b/modules/yup_graphics/native/yup_GraphicsContext_headless.cpp @@ -79,7 +79,7 @@ class NoOpRenderPath : public rive::RenderPath void addPath (rive::CommandPath*, const rive::Mat2D&) override {} - void addRenderPath (rive::RenderPath*, const rive::Mat2D&) override {} + void addRenderPath (const rive::RenderPath*, const rive::Mat2D&) override {} void moveTo (float, float) override {} @@ -179,6 +179,8 @@ class NoOpRenderer : public rive::Renderer uint32_t indexCount, rive::BlendMode, float) override {} + + void modulateOpacity (float) override {} }; //============================================================================== diff --git a/modules/yup_graphics/native/yup_GraphicsContext_metal.cpp b/modules/yup_graphics/native/yup_GraphicsContext_metal.cpp index 8728d7793..1d1b666fd 100644 --- a/modules/yup_graphics/native/yup_GraphicsContext_metal.cpp +++ b/modules/yup_graphics/native/yup_GraphicsContext_metal.cpp @@ -82,7 +82,7 @@ class LowLevelRenderContextMetal : public GraphicsContext rive::gpu::RenderContextMetalImpl::ContextOptions metalOptions; if (m_fiddleOptions.synchronousShaderCompilations) - metalOptions.synchronousShaderCompilations = true; + metalOptions.shaderCompilationMode = rive::gpu::ShaderCompilationMode::alwaysSynchronous; if (m_fiddleOptions.disableRasterOrdering) metalOptions.disableFramebufferReads = true; @@ -192,8 +192,12 @@ class LowLevelRenderContextMetal : public GraphicsContext if (m_currentTexture != nil) { [m_currentTexture setPurgeableState:MTLPurgeableStateEmpty]; +#if defined(__has_feature) && __has_feature(objc_arc) + m_currentTexture = nil; +#else [m_currentTexture release]; m_currentTexture = nil; +#endif } MTLTextureDescriptor* descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:(MTLPixelFormatBGRA8Unorm) diff --git a/modules/yup_gui/artboard/yup_ArtboardFile.cpp b/modules/yup_gui/artboard/yup_ArtboardFile.cpp index 7fff0716e..4bbc5dd2a 100644 --- a/modules/yup_gui/artboard/yup_ArtboardFile.cpp +++ b/modules/yup_gui/artboard/yup_ArtboardFile.cpp @@ -57,7 +57,7 @@ class LambdaAssetLoader : public rive::FileAssetLoader //============================================================================== -ArtboardFile::ArtboardFile (std::unique_ptr rivFile) +ArtboardFile::ArtboardFile (rive::rcp rivFile) : rivFile (std::move (rivFile)) { } @@ -106,7 +106,7 @@ ArtboardFile::LoadResult ArtboardFile::load (InputStream& is, rive::Factory& fac is.readIntoMemoryBlock (mb); rive::ImportResult result; - std::unique_ptr rivFile; + rive::rcp rivFile; if (assetCallback != nullptr) { diff --git a/modules/yup_gui/artboard/yup_ArtboardFile.h b/modules/yup_gui/artboard/yup_ArtboardFile.h index 521688d6e..ae8b1455d 100644 --- a/modules/yup_gui/artboard/yup_ArtboardFile.h +++ b/modules/yup_gui/artboard/yup_ArtboardFile.h @@ -94,9 +94,9 @@ class YUP_API ArtboardFile private: ArtboardFile() = default; - ArtboardFile (std::unique_ptr rivFile); + ArtboardFile (rive::rcp rivFile); - std::unique_ptr rivFile; + rive::rcp rivFile; }; } // namespace yup diff --git a/thirdparty/harfbuzz/harfbuzz.cpp b/thirdparty/harfbuzz/harfbuzz.cpp index 87298820f..e76f1dd6c 100644 --- a/thirdparty/harfbuzz/harfbuzz.cpp +++ b/thirdparty/harfbuzz/harfbuzz.cpp @@ -23,6 +23,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wempty-body" #pragma clang diagnostic ignored "-Wunused-function" + #pragma clang diagnostic ignored "-Wunused-member-function" #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wformat" #elif __GNUC__ @@ -39,83 +40,27 @@ #include "harfbuzz.h" -#include "upstream/graph/gsubgpos-context.cc" -#include "upstream/hb-aat-layout.cc" -#include "upstream/hb-aat-map.cc" -#include "upstream/hb-blob.cc" -#include "upstream/hb-buffer-serialize.cc" -#include "upstream/hb-buffer-verify.cc" -#include "upstream/hb-buffer.cc" -#include "upstream/hb-cairo-utils.cc" -#include "upstream/hb-cairo.cc" -#include "upstream/hb-common.cc" -#include "upstream/hb-coretext-font.cc" -#include "upstream/hb-coretext-shape.cc" -#include "upstream/hb-directwrite.cc" -#include "upstream/hb-draw.cc" -#include "upstream/hb-face-builder.cc" -#include "upstream/hb-face.cc" -#include "upstream/hb-fallback-shape.cc" -#include "upstream/hb-font.cc" -#include "upstream/hb-ft.cc" -#include "upstream/hb-gdi.cc" -#include "upstream/hb-glib.cc" -#include "upstream/hb-gobject-structs.cc" -#include "upstream/hb-graphite2.cc" -#include "upstream/hb-icu.cc" -#include "upstream/hb-map.cc" -#include "upstream/hb-number.cc" -#include "upstream/hb-ot-cff1-table.cc" -#include "upstream/hb-ot-cff2-table.cc" -#include "upstream/hb-ot-color.cc" -#include "upstream/hb-ot-face.cc" -#include "upstream/hb-ot-font.cc" -#include "upstream/hb-ot-layout.cc" -#include "upstream/hb-ot-map.cc" -#include "upstream/hb-ot-math.cc" -#include "upstream/hb-ot-meta.cc" -#include "upstream/hb-ot-metrics.cc" -#include "upstream/hb-ot-name.cc" -#include "upstream/hb-ot-shape-fallback.cc" -#include "upstream/hb-ot-shape-normalize.cc" -#include "upstream/hb-ot-shape.cc" -#include "upstream/hb-ot-shaper-arabic.cc" -#include "upstream/hb-ot-shaper-default.cc" -#include "upstream/hb-ot-shaper-hangul.cc" -#include "upstream/hb-ot-shaper-hebrew.cc" -#include "upstream/hb-ot-shaper-indic-table.cc" -#include "upstream/hb-ot-shaper-indic.cc" -#include "upstream/hb-ot-shaper-khmer.cc" -#include "upstream/hb-ot-shaper-myanmar.cc" -#include "upstream/hb-ot-shaper-syllabic.cc" -#include "upstream/hb-ot-shaper-thai.cc" -#include "upstream/hb-ot-shaper-use.cc" -#include "upstream/hb-ot-shaper-vowel-constraints.cc" -#include "upstream/hb-ot-tag.cc" -#include "upstream/hb-ot-var.cc" -#include "upstream/hb-outline.cc" -#include "upstream/hb-paint-extents.cc" -#include "upstream/hb-paint.cc" -#include "upstream/hb-set.cc" -#include "upstream/hb-shape-plan.cc" -#include "upstream/hb-shape.cc" -#include "upstream/hb-shaper.cc" -#include "upstream/hb-static.cc" -#include "upstream/hb-style.cc" -#include "upstream/hb-subset-cff-common.cc" -#include "upstream/hb-subset-cff1.cc" -#include "upstream/hb-subset-cff2.cc" -#include "upstream/hb-subset-input.cc" -#include "upstream/hb-subset-instancer-iup.cc" -#include "upstream/hb-subset-instancer-solver.cc" -#include "upstream/hb-subset-plan.cc" -#include "upstream/hb-subset-repacker.cc" -#include "upstream/hb-subset.cc" -#include "upstream/hb-ucd.cc" -#include "upstream/hb-unicode.cc" -#include "upstream/hb-uniscribe.cc" -#include "upstream/hb-wasm-api.cc" -#include "upstream/hb-wasm-shape.cc" +#if !defined(HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR) + #define YUP_HARFBUZZ_DEFINED_HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR 1 + #define HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR 1 +#endif + +#if !defined(HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING) + #define YUP_HARFBUZZ_DEFINED_HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING 1 + #define HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING 1 +#endif + +#include "upstream/harfbuzz.cc" + +#if defined(YUP_HARFBUZZ_DEFINED_HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING) + #undef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING + #undef YUP_HARFBUZZ_DEFINED_HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING +#endif + +#if defined(YUP_HARFBUZZ_DEFINED_HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR) + #undef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR + #undef YUP_HARFBUZZ_DEFINED_HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR +#endif #if __clang__ #pragma clang diagnostic pop diff --git a/thirdparty/harfbuzz/harfbuzz.h b/thirdparty/harfbuzz/harfbuzz.h index 303c744b6..759a62b39 100644 --- a/thirdparty/harfbuzz/harfbuzz.h +++ b/thirdparty/harfbuzz/harfbuzz.h @@ -32,7 +32,7 @@ website: https://github.com/harfbuzz/harfbuzz license: MIT - defines: HAVE_ATEXIT=1 HB_ONLY_ONE_SHAPER HAVE_OT HB_NO_FALLBACK_SHAPE HB_NO_WIN1256 HB_NO_WIN1256 HB_NO_EXTERN_HELPERS HB_DISABLE_DEPRECATED HB_NO_COLOR HB_NO_BITMAP HB_NO_BUFFER_SERIALIZE HB_NO_BUFFER_VERIFY HB_NO_BUFFER_MESSAGE HB_NO_SETLOCALE HB_NO_VERTICAL HB_NO_LAYOUT_COLLECT_GLYPHS HB_NO_LAYOUT_RARELY_USED HB_NO_LAYOUT_UNUSED HB_NO_OT_FONT_GLYPH_NAMES HB_NO_PAINT HB_NO_MMAP HB_NO_META + defines: HAVE_ATEXIT=1 HB_ONLY_ONE_SHAPER HAVE_OT HB_NO_FALLBACK_SHAPE HB_NO_WIN1256 HB_NO_WIN1256 HB_NO_EXTERN_HELPERS HB_DISABLE_DEPRECATED HB_NO_BUFFER_SERIALIZE HB_NO_BUFFER_VERIFY HB_NO_BUFFER_MESSAGE HB_NO_SETLOCALE HB_NO_VERTICAL HB_NO_LAYOUT_COLLECT_GLYPHS HB_NO_LAYOUT_RARELY_USED HB_NO_LAYOUT_UNUSED HB_NO_OT_FONT_GLYPH_NAMES HB_NO_MMAP HB_NO_META appleDefines: HAVE_CORETEXT appleFrameworks: CoreText searchpaths: upstream diff --git a/thirdparty/harfbuzz/upstream/ArabicPUASimplified.txt b/thirdparty/harfbuzz/upstream/ArabicPUASimplified.txt deleted file mode 100644 index a74ef266f..000000000 --- a/thirdparty/harfbuzz/upstream/ArabicPUASimplified.txt +++ /dev/null @@ -1,250 +0,0 @@ -# -# Name: Legacy Simplified Arabic encoding -# -# Format: Three tab-separated columns -# Column #1 is the PUA code (in hex as 0xXXXX) -# Column #2 is the Unicode (in hex as 0xXXXX) -# Column #3 is the Unicode name (follows a comment sign, '#') -# -# The entries are in PUA order -# -0xF100 0x063B # ARABIC LETTER KEHEH WITH TWO DOTS ABOVE -0xF100 0x063C # ARABIC LETTER KEHEH WITH THREE DOTS BELOW -0xF100 0x063D # ARABIC LETTER FARSI YEH WITH INVERTED V -0xF100 0x063E # ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE -0xF100 0x063F # ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE -0xF100 0x0653 # ARABIC MADDAH ABOVE -0xF100 0x0654 # ARABIC HAMZA ABOVE -0xF100 0x0655 # ARABIC HAMZA BELOW -0xF100 0x0656 # ARABIC SUBSCRIPT ALEF -0xF100 0x0657 # ARABIC INVERTED DAMMA -0xF100 0x0658 # ARABIC MARK NOON GHUNNA -0xF100 0x0659 # ARABIC ZWARAKAY -0xF100 0x065A # ARABIC VOWEL SIGN SMALL V ABOVE -0xF100 0x065B # ARABIC VOWEL SIGN INVERTED SMALL V ABOVE -0xF100 0x065C # ARABIC VOWEL SIGN DOT BELOW -0xF100 0x065D # ARABIC REVERSED DAMMA -0xF100 0x065E # ARABIC FATHA WITH TWO DOTS -0xF10C 0x200C # ZERO WIDTH NON-JOINER -0xF10D 0x200D # ZERO WIDTH JOINER -0xF10E 0x200E # LEFT-TO-RIGHT MARK -0xF10F 0x200F # RIGHT-TO-LEFT MARK -0xF120 0x0020 # SPACE -0xF121 0x0021 # EXCLAMATION MARK -0xF122 0x0022 # QUOTATION MARK -0xF123 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -0xF124 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -0xF125 0x0025 # PERCENT SIGN -0xF126 0x00D7 # MULTIPLICATION SIGN -0xF127 0x00F7 # DIVISION SIGN -0xF128 0x0028 # LEFT PARENTHESIS -0xF129 0x0029 # RIGHT PARENTHESIS -0xF12A 0x002A # ASTERISK -0xF12B 0x002B # PLUS SIGN -0xF12C 0x060C # ARABIC COMMA -0xF12D 0x002D # HYPHEN-MINUS -0xF12E 0x002E # FULL STOP -0xF12F 0x002F # SOLIDUS -0xF130 0x0660 # ARABIC-INDIC DIGIT ZERO -0xF131 0x0661 # ARABIC-INDIC DIGIT ONE -0xF132 0x0662 # ARABIC-INDIC DIGIT TWO -0xF133 0x0663 # ARABIC-INDIC DIGIT THREE -0xF134 0x0664 # ARABIC-INDIC DIGIT FOUR -0xF135 0x0665 # ARABIC-INDIC DIGIT FIVE -0xF136 0x0666 # ARABIC-INDIC DIGIT SIX -0xF137 0x0667 # ARABIC-INDIC DIGIT SEVEN -0xF138 0x0668 # ARABIC-INDIC DIGIT EIGHT -0xF139 0x0669 # ARABIC-INDIC DIGIT NINE -0xF13A 0x003A # COLON -0xF13B 0x003B # SEMICOLON -0xF13B 0x061B # ARABIC SEMICOLON -0xF13C 0x2018 # LEFT SINGLE QUOTATION MARK -0xF13D 0x003D # EQUALS SIGN -0xF13E 0x2019 # RIGHT SINGLE QUOTATION MARK -0xF13F 0x003F # QUESTION MARK -0xF13F 0x061F # ARABIC QUESTION MARK -0xF141 0x0627 # ARABIC LETTER ALEF -0xF141 0xFE8D # ARABIC LETTER ALEF ISOLATED FORM -0xF142 0xFE8E # ARABIC LETTER ALEF FINAL FORM -0xF143 0x0623 # ARABIC LETTER ALEF WITH HAMZA ABOVE -0xF143 0xFE83 # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM -0xF144 0xFE84 # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM -0xF145 0x0622 # ARABIC LETTER ALEF WITH MADDA ABOVE -0xF145 0xFE81 # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM -0xF146 0xFE82 # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM -0xF147 0x0625 # ARABIC LETTER ALEF WITH HAMZA BELOW -0xF147 0xFE87 # ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM -0xF148 0xFE88 # ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM -0xF149 0xFE91 # ARABIC LETTER BEH INITIAL FORM -0xF149 0xFE92 # ARABIC LETTER BEH MEDIAL FORM -0xF14A 0x0628 # ARABIC LETTER BEH -0xF14A 0xFE8F # ARABIC LETTER BEH ISOLATED FORM -0xF14A 0xFE90 # ARABIC LETTER BEH FINAL FORM -0xF14B 0xFE97 # ARABIC LETTER TEH INITIAL FORM -0xF14B 0xFE98 # ARABIC LETTER TEH MEDIAL FORM -0xF14C 0x062A # ARABIC LETTER TEH -0xF14C 0xFE95 # ARABIC LETTER TEH ISOLATED FORM -0xF14C 0xFE96 # ARABIC LETTER TEH FINAL FORM -0xF14D 0xFE9B # ARABIC LETTER THEH INITIAL FORM -0xF14D 0xFE9C # ARABIC LETTER THEH MEDIAL FORM -0xF14E 0x062B # ARABIC LETTER THEH -0xF14E 0xFE99 # ARABIC LETTER THEH ISOLATED FORM -0xF14E 0xFE9A # ARABIC LETTER THEH FINAL FORM -0xF14F 0xFE9F # ARABIC LETTER JEEM INITIAL FORM -0xF14F 0xFEA0 # ARABIC LETTER JEEM MEDIAL FORM -0xF150 0xFE9E # ARABIC LETTER JEEM FINAL FORM -0xF151 0x062C # ARABIC LETTER JEEM -0xF151 0xFE9D # ARABIC LETTER JEEM ISOLATED FORM -0xF152 0xFEA3 # ARABIC LETTER HAH INITIAL FORM -0xF152 0xFEA4 # ARABIC LETTER HAH MEDIAL FORM -0xF153 0xFEA2 # ARABIC LETTER HAH FINAL FORM -0xF154 0x062D # ARABIC LETTER HAH -0xF154 0xFEA1 # ARABIC LETTER HAH ISOLATED FORM -0xF155 0xFEA7 # ARABIC LETTER KHAH INITIAL FORM -0xF155 0xFEA8 # ARABIC LETTER KHAH MEDIAL FORM -0xF156 0xFEA6 # ARABIC LETTER KHAH FINAL FORM -0xF157 0x062E # ARABIC LETTER KHAH -0xF157 0xFEA5 # ARABIC LETTER KHAH ISOLATED FORM -0xF158 0x062F # ARABIC LETTER DAL -0xF158 0xFEA9 # ARABIC LETTER DAL ISOLATED FORM -0xF158 0xFEAA # ARABIC LETTER DAL FINAL FORM -0xF159 0x0630 # ARABIC LETTER THAL -0xF159 0xFEAB # ARABIC LETTER THAL ISOLATED FORM -0xF159 0xFEAC # ARABIC LETTER THAL FINAL FORM -0xF15A 0x0631 # ARABIC LETTER REH -0xF15A 0xFEAD # ARABIC LETTER REH ISOLATED FORM -0xF15A 0xFEAE # ARABIC LETTER REH FINAL FORM -0xF15B 0x005B # LEFT SQUARE BRACKET -0xF15C 0x005C # REVERSE SOLIDUS -0xF15D 0x005D # RIGHT SQUARE BRACKET -0xF15E 0x002C # COMMA -0xF15E 0x066B # ARABIC DECIMAL SEPARATOR -0xF15E 0x066C # ARABIC THOUSANDS SEPARATOR -0xF15F 0x0640 # ARABIC TATWEEL -0xF160 0x0632 # ARABIC LETTER ZAIN -0xF160 0xFEAF # ARABIC LETTER ZAIN ISOLATED FORM -0xF160 0xFEB0 # ARABIC LETTER ZAIN FINAL FORM -0xF161 0xFEB3 # ARABIC LETTER SEEN INITIAL FORM -0xF161 0xFEB4 # ARABIC LETTER SEEN MEDIAL FORM -0xF162 0x0633 # ARABIC LETTER SEEN -0xF162 0xFEB1 # ARABIC LETTER SEEN ISOLATED FORM -0xF162 0xFEB2 # ARABIC LETTER SEEN FINAL FORM -0xF163 0xFEB7 # ARABIC LETTER SHEEN INITIAL FORM -0xF163 0xFEB8 # ARABIC LETTER SHEEN MEDIAL FORM -0xF164 0x0634 # ARABIC LETTER SHEEN -0xF164 0xFEB5 # ARABIC LETTER SHEEN ISOLATED FORM -0xF164 0xFEB6 # ARABIC LETTER SHEEN FINAL FORM -0xF165 0xFEBB # ARABIC LETTER SAD INITIAL FORM -0xF165 0xFEBC # ARABIC LETTER SAD MEDIAL FORM -0xF166 0x0635 # ARABIC LETTER SAD -0xF166 0xFEB9 # ARABIC LETTER SAD ISOLATED FORM -0xF166 0xFEBA # ARABIC LETTER SAD FINAL FORM -0xF167 0xFEBF # ARABIC LETTER DAD INITIAL FORM -0xF167 0xFEC0 # ARABIC LETTER DAD MEDIAL FORM -0xF168 0x0636 # ARABIC LETTER DAD -0xF168 0xFEBD # ARABIC LETTER DAD ISOLATED FORM -0xF168 0xFEBE # ARABIC LETTER DAD FINAL FORM -0xF169 0x0637 # ARABIC LETTER TAH -0xF169 0xFEC1 # ARABIC LETTER TAH ISOLATED FORM -0xF169 0xFEC2 # ARABIC LETTER TAH FINAL FORM -0xF169 0xFEC3 # ARABIC LETTER TAH INITIAL FORM -0xF169 0xFEC4 # ARABIC LETTER TAH MEDIAL FORM -0xF16A 0x0638 # ARABIC LETTER ZAH -0xF16A 0xFEC5 # ARABIC LETTER ZAH ISOLATED FORM -0xF16A 0xFEC6 # ARABIC LETTER ZAH FINAL FORM -0xF16A 0xFEC7 # ARABIC LETTER ZAH INITIAL FORM -0xF16A 0xFEC8 # ARABIC LETTER ZAH MEDIAL FORM -0xF16B 0xFECB # ARABIC LETTER AIN INITIAL FORM -0xF16C 0xFECC # ARABIC LETTER AIN MEDIAL FORM -0xF16D 0xFECA # ARABIC LETTER AIN FINAL FORM -0xF16E 0x0639 # ARABIC LETTER AIN -0xF16E 0xFEC9 # ARABIC LETTER AIN ISOLATED FORM -0xF16F 0xFECF # ARABIC LETTER GHAIN INITIAL FORM -0xF170 0xFED0 # ARABIC LETTER GHAIN MEDIAL FORM -0xF171 0xFECE # ARABIC LETTER GHAIN FINAL FORM -0xF172 0x063A # ARABIC LETTER GHAIN -0xF172 0xFECD # ARABIC LETTER GHAIN ISOLATED FORM -0xF173 0xFED3 # ARABIC LETTER FEH INITIAL FORM -0xF174 0xFED4 # ARABIC LETTER FEH MEDIAL FORM -0xF175 0x0641 # ARABIC LETTER FEH -0xF175 0xFED1 # ARABIC LETTER FEH ISOLATED FORM -0xF175 0xFED2 # ARABIC LETTER FEH FINAL FORM -0xF176 0xFED7 # ARABIC LETTER QAF INITIAL FORM -0xF177 0xFED8 # ARABIC LETTER QAF MEDIAL FORM -0xF178 0x0642 # ARABIC LETTER QAF -0xF178 0xFED5 # ARABIC LETTER QAF ISOLATED FORM -0xF178 0xFED6 # ARABIC LETTER QAF FINAL FORM -0xF179 0xFEDB # ARABIC LETTER KAF INITIAL FORM -0xF179 0xFEDC # ARABIC LETTER KAF MEDIAL FORM -0xF17A 0x0643 # ARABIC LETTER KAF -0xF17A 0xFED9 # ARABIC LETTER KAF ISOLATED FORM -0xF17A 0xFEDA # ARABIC LETTER KAF FINAL FORM -0xF17B 0xFEDF # ARABIC LETTER LAM INITIAL FORM -0xF17B 0xFEE0 # ARABIC LETTER LAM MEDIAL FORM -0xF17C 0x0644 # ARABIC LETTER LAM -0xF17C 0xFEDD # ARABIC LETTER LAM ISOLATED FORM -0xF17C 0xFEDE # ARABIC LETTER LAM FINAL FORM -0xF17D 0xFEE3 # ARABIC LETTER MEEM INITIAL FORM -0xF17D 0xFEE4 # ARABIC LETTER MEEM MEDIAL FORM -0xF17E 0x0645 # ARABIC LETTER MEEM -0xF17E 0xFEE1 # ARABIC LETTER MEEM ISOLATED FORM -0xF17E 0xFEE2 # ARABIC LETTER MEEM FINAL FORM -0xF17F 0xFEE7 # ARABIC LETTER NOON INITIAL FORM -0xF17F 0xFEE8 # ARABIC LETTER NOON MEDIAL FORM -0xF1A1 0xFEEB # ARABIC LETTER HEH INITIAL FORM -0xF1A2 0xFEEC # ARABIC LETTER HEH MEDIAL FORM -0xF1A3 0xFEEA # ARABIC LETTER HEH FINAL FORM -0xF1A4 0x0647 # ARABIC LETTER HEH -0xF1A4 0xFEE9 # ARABIC LETTER HEH ISOLATED FORM -0xF1A5 0x0648 # ARABIC LETTER WAW -0xF1A5 0xFEED # ARABIC LETTER WAW ISOLATED FORM -0xF1A5 0xFEEE # ARABIC LETTER WAW FINAL FORM -0xF1A6 0xFEF3 # ARABIC LETTER YEH INITIAL FORM -0xF1A6 0xFEF4 # ARABIC LETTER YEH MEDIAL FORM -0xF1A7 0xFEF2 # ARABIC LETTER YEH FINAL FORM -0xF1A8 0x064A # ARABIC LETTER YEH -0xF1A8 0xFEF1 # ARABIC LETTER YEH ISOLATED FORM -0xF1A9 0x0629 # ARABIC LETTER TEH MARBUTA -0xF1A9 0xFE93 # ARABIC LETTER TEH MARBUTA ISOLATED FORM -0xF1AA 0xFE94 # ARABIC LETTER TEH MARBUTA FINAL FORM -0xF1AB 0xFEF0 # ARABIC LETTER ALEF MAKSURA FINAL FORM -0xF1AC 0x0649 # ARABIC LETTER ALEF MAKSURA -0xF1AC 0xFEEF # ARABIC LETTER ALEF MAKSURA ISOLATED FORM -0xF1AD 0x0621 # ARABIC LETTER HAMZA -0xF1AE 0xFE8B # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM -0xF1AE 0xFE8C # ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM -0xF1AF 0xFE8A # ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM -0xF1B0 0x0030 # DIGIT ZERO -0xF1B1 0x0031 # DIGIT ONE -0xF1B2 0x0032 # DIGIT TWO -0xF1B3 0x0033 # DIGIT THREE -0xF1B4 0x0034 # DIGIT FOUR -0xF1B5 0x0035 # DIGIT FIVE -0xF1B6 0x0036 # DIGIT SIX -0xF1B7 0x0037 # DIGIT SEVEN -0xF1B8 0x0038 # DIGIT EIGHT -0xF1B9 0x0039 # DIGIT NINE -0xF1BA 0x0626 # ARABIC LETTER YEH WITH HAMZA ABOVE -0xF1BA 0xFE89 # ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM -0xF1BB 0x0624 # ARABIC LETTER WAW WITH HAMZA ABOVE -0xF1BB 0xFE85 # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM -0xF1BB 0xFE86 # ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM -0xF1BC 0xFEFC # ARABIC LIGATURE LAM WITH ALEF FINAL FORM -0xF1BD 0xFEFB # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM -0xF1BE 0xFEF7 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM -0xF1BF 0xFEF8 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM -0xF1C0 0xFEF5 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM -0xF1C1 0xFEF6 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM -0xF1C2 0xFEF9 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM -0xF1C3 0xFEFA # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM -0xF1C4 0x064E # ARABIC FATHA -0xF1C5 0x064F # ARABIC DAMMA -0xF1C6 0x0652 # ARABIC SUKUN -0xF1C7 0x064B # ARABIC FATHATAN -0xF1C8 0x064C # ARABIC DAMMATAN -0xF1C9 0x0651 # ARABIC SHADDA -0xF1CA 0x0650 # ARABIC KASRA -0xF1CB 0x064D # ARABIC KASRATAN -0xF1E1 0x0646 # ARABIC LETTER NOON -0xF1E1 0xFEE5 # ARABIC LETTER NOON ISOLATED FORM -0xF1E1 0xFEE6 # ARABIC LETTER NOON FINAL FORM diff --git a/thirdparty/harfbuzz/upstream/ArabicPUATraditional.txt b/thirdparty/harfbuzz/upstream/ArabicPUATraditional.txt deleted file mode 100644 index e14b383c9..000000000 --- a/thirdparty/harfbuzz/upstream/ArabicPUATraditional.txt +++ /dev/null @@ -1,295 +0,0 @@ -# -# Name: Legacy Traditional Arabic encoding -# -# Format: Three tab-separated columns -# Column #1 is the PUA code (in hex as 0xXXXX) -# Column #2 is the Unicode (in hex as 0xXXXX) -# Column #3 is the Unicode name (follows a comment sign, '#') -# -# The entries are in PUA order -# -0xF200 0x063B # ARABIC LETTER KEHEH WITH TWO DOTS ABOVE -0xF200 0x063C # ARABIC LETTER KEHEH WITH THREE DOTS BELOW -0xF200 0x063D # ARABIC LETTER FARSI YEH WITH INVERTED V -0xF200 0x063E # ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE -0xF200 0x063F # ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE -0xF200 0x0653 # ARABIC MADDAH ABOVE -0xF200 0x0654 # ARABIC HAMZA ABOVE -0xF200 0x0655 # ARABIC HAMZA BELOW -0xF200 0x0656 # ARABIC SUBSCRIPT ALEF -0xF200 0x0657 # ARABIC INVERTED DAMMA -0xF200 0x0658 # ARABIC MARK NOON GHUNNA -0xF200 0x0659 # ARABIC ZWARAKAY -0xF200 0x065A # ARABIC VOWEL SIGN SMALL V ABOVE -0xF200 0x065B # ARABIC VOWEL SIGN INVERTED SMALL V ABOVE -0xF200 0x065C # ARABIC VOWEL SIGN DOT BELOW -0xF200 0x065D # ARABIC REVERSED DAMMA -0xF200 0x065E # ARABIC FATHA WITH TWO DOTS -0xF202 0xFC08 # ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM -0xF203 0xFC0E # ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM -0xF204 0xFC12 # ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM -0xF205 0xFC42 # ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM -0xF206 0xFC4E # ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM -0xF20C 0x200C # ZERO WIDTH NON-JOINER -0xF20D 0x200D # ZERO WIDTH JOINER -0xF20E 0x200E # LEFT-TO-RIGHT MARK -0xF20F 0x200F # RIGHT-TO-LEFT MARK -0xF210 0xFD88 # ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM -0xF212 0xFC3F # ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM -0xF213 0xFC40 # ARABIC LIGATURE LAM WITH HAH ISOLATED FORM -0xF214 0xFC41 # ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM -0xF215 0xFC6A # ARABIC LIGATURE BEH WITH REH FINAL FORM -0xF216 0xFC70 # ARABIC LIGATURE TEH WITH REH FINAL FORM -0xF217 0xFC91 # ARABIC LIGATURE YEH WITH REH FINAL FORM -0xF218 0xFCB0 # ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM -0xF219 0xFD30 # ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM -0xF21A 0xFCCD # ARABIC LIGATURE LAM WITH HEH INITIAL FORM -0xF21C 0xFC44 # ARABIC LIGATURE LAM WITH YEH ISOLATED FORM -0xF21D 0xFC0A # ARABIC LIGATURE BEH WITH YEH ISOLATED FORM -0xF21E 0xFC10 # ARABIC LIGATURE TEH WITH YEH ISOLATED FORM -0xF21F 0xFC50 # ARABIC LIGATURE NOON WITH YEH ISOLATED FORM -0xF220 0x0020 # SPACE -0xF221 0x0021 # EXCLAMATION MARK -0xF222 0x0022 # QUOTATION MARK -0xF223 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -0xF224 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -0xF225 0x0025 # PERCENT SIGN -0xF226 0x00D7 # MULTIPLICATION SIGN -0xF227 0x00F7 # DIVISION SIGN -0xF228 0x0028 # LEFT PARENTHESIS -0xF229 0x0029 # RIGHT PARENTHESIS -0xF22A 0x002A # ASTERISK -0xF22B 0x002B # PLUS SIGN -0xF22C 0x060C # ARABIC COMMA -0xF22D 0x002D # HYPHEN-MINUS -0xF22E 0x002E # FULL STOP -0xF22F 0x002F # SOLIDUS -0xF230 0x0660 # ARABIC-INDIC DIGIT ZERO -0xF231 0x0661 # ARABIC-INDIC DIGIT ONE -0xF232 0x0662 # ARABIC-INDIC DIGIT TWO -0xF233 0x0663 # ARABIC-INDIC DIGIT THREE -0xF234 0x0664 # ARABIC-INDIC DIGIT FOUR -0xF235 0x0665 # ARABIC-INDIC DIGIT FIVE -0xF236 0x0666 # ARABIC-INDIC DIGIT SIX -0xF237 0x0667 # ARABIC-INDIC DIGIT SEVEN -0xF238 0x0668 # ARABIC-INDIC DIGIT EIGHT -0xF239 0x0669 # ARABIC-INDIC DIGIT NINE -0xF23A 0x003A # COLON -0xF23B 0x003B # SEMICOLON -0xF23B 0x061B # ARABIC SEMICOLON -0xF23C 0x201C # LEFT DOUBLE QUOTATION MARK -0xF23D 0x003D # EQUALS SIGN -0xF23E 0x201D # RIGHT DOUBLE QUOTATION MARK -0xF23F 0x003F # QUESTION MARK -0xF23F 0x061F # ARABIC QUESTION MARK -0xF241 0x0627 # ARABIC LETTER ALEF -0xF241 0xFE8D # ARABIC LETTER ALEF ISOLATED FORM -0xF242 0xFE8E # ARABIC LETTER ALEF FINAL FORM -0xF243 0x0623 # ARABIC LETTER ALEF WITH HAMZA ABOVE -0xF243 0xFE83 # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM -0xF244 0xFE84 # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM -0xF245 0x0622 # ARABIC LETTER ALEF WITH MADDA ABOVE -0xF245 0xFE81 # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM -0xF246 0xFE82 # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM -0xF247 0x0625 # ARABIC LETTER ALEF WITH HAMZA BELOW -0xF247 0xFE87 # ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM -0xF248 0xFE88 # ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM -0xF249 0xFE91 # ARABIC LETTER BEH INITIAL FORM -0xF24A 0xFE92 # ARABIC LETTER BEH MEDIAL FORM -0xF24B 0xFE90 # ARABIC LETTER BEH FINAL FORM -0xF24C 0x0628 # ARABIC LETTER BEH -0xF24C 0xFE8F # ARABIC LETTER BEH ISOLATED FORM -0xF24D 0xFE97 # ARABIC LETTER TEH INITIAL FORM -0xF24E 0xFE98 # ARABIC LETTER TEH MEDIAL FORM -0xF24F 0xFE96 # ARABIC LETTER TEH FINAL FORM -0xF250 0x062A # ARABIC LETTER TEH -0xF250 0xFE95 # ARABIC LETTER TEH ISOLATED FORM -0xF251 0xFE9B # ARABIC LETTER THEH INITIAL FORM -0xF252 0xFE9C # ARABIC LETTER THEH MEDIAL FORM -0xF253 0xFE9A # ARABIC LETTER THEH FINAL FORM -0xF254 0x062B # ARABIC LETTER THEH -0xF254 0xFE99 # ARABIC LETTER THEH ISOLATED FORM -0xF255 0xFE9F # ARABIC LETTER JEEM INITIAL FORM -0xF256 0xFEA0 # ARABIC LETTER JEEM MEDIAL FORM -0xF257 0xFE9E # ARABIC LETTER JEEM FINAL FORM -0xF258 0x062C # ARABIC LETTER JEEM -0xF258 0xFE9D # ARABIC LETTER JEEM ISOLATED FORM -0xF259 0xFEA3 # ARABIC LETTER HAH INITIAL FORM -0xF25A 0xFEA4 # ARABIC LETTER HAH MEDIAL FORM -0xF25B 0x005B # LEFT SQUARE BRACKET -0xF25C 0xFEA2 # ARABIC LETTER HAH FINAL FORM -0xF25D 0x005D # RIGHT SQUARE BRACKET -0xF25E 0x002C # COMMA -0xF25E 0x066B # ARABIC DECIMAL SEPARATOR -0xF25E 0x066C # ARABIC THOUSANDS SEPARATOR -0xF25F 0x0640 # ARABIC TATWEEL -0xF260 0x062D # ARABIC LETTER HAH -0xF260 0xFEA1 # ARABIC LETTER HAH ISOLATED FORM -0xF261 0xFEA7 # ARABIC LETTER KHAH INITIAL FORM -0xF262 0xFEA8 # ARABIC LETTER KHAH MEDIAL FORM -0xF263 0xFEA6 # ARABIC LETTER KHAH FINAL FORM -0xF264 0x062E # ARABIC LETTER KHAH -0xF264 0xFEA5 # ARABIC LETTER KHAH ISOLATED FORM -0xF265 0x062F # ARABIC LETTER DAL -0xF265 0xFEA9 # ARABIC LETTER DAL ISOLATED FORM -0xF266 0xFEAA # ARABIC LETTER DAL FINAL FORM -0xF267 0x0630 # ARABIC LETTER THAL -0xF267 0xFEAB # ARABIC LETTER THAL ISOLATED FORM -0xF268 0xFEAC # ARABIC LETTER THAL FINAL FORM -0xF269 0x0631 # ARABIC LETTER REH -0xF269 0xFEAD # ARABIC LETTER REH ISOLATED FORM -0xF26A 0xFEAE # ARABIC LETTER REH FINAL FORM -0xF26B 0x0632 # ARABIC LETTER ZAIN -0xF26B 0xFEAF # ARABIC LETTER ZAIN ISOLATED FORM -0xF26C 0xFEB0 # ARABIC LETTER ZAIN FINAL FORM -0xF26D 0xFEB3 # ARABIC LETTER SEEN INITIAL FORM -0xF26E 0xFEB4 # ARABIC LETTER SEEN MEDIAL FORM -0xF26F 0xFEB2 # ARABIC LETTER SEEN FINAL FORM -0xF270 0x0633 # ARABIC LETTER SEEN -0xF270 0xFEB1 # ARABIC LETTER SEEN ISOLATED FORM -0xF271 0xFEB7 # ARABIC LETTER SHEEN INITIAL FORM -0xF272 0xFEB8 # ARABIC LETTER SHEEN MEDIAL FORM -0xF273 0xFEB6 # ARABIC LETTER SHEEN FINAL FORM -0xF274 0x0634 # ARABIC LETTER SHEEN -0xF274 0xFEB5 # ARABIC LETTER SHEEN ISOLATED FORM -0xF275 0xFEBB # ARABIC LETTER SAD INITIAL FORM -0xF276 0xFEBC # ARABIC LETTER SAD MEDIAL FORM -0xF277 0xFEBA # ARABIC LETTER SAD FINAL FORM -0xF278 0x0635 # ARABIC LETTER SAD -0xF278 0xFEB9 # ARABIC LETTER SAD ISOLATED FORM -0xF279 0xFEBF # ARABIC LETTER DAD INITIAL FORM -0xF27A 0xFEC0 # ARABIC LETTER DAD MEDIAL FORM -0xF27B 0xFD3E # ORNATE LEFT PARENTHESIS -0xF27C 0xFEBE # ARABIC LETTER DAD FINAL FORM -0xF27D 0xFD3F # ORNATE RIGHT PARENTHESIS -0xF27E 0x0636 # ARABIC LETTER DAD -0xF27E 0xFEBD # ARABIC LETTER DAD ISOLATED FORM -0xF27F 0xFEC3 # ARABIC LETTER TAH INITIAL FORM -0xF280 0xFC9C # ARABIC LIGATURE BEH WITH JEEM INITIAL FORM -0xF281 0xFC9D # ARABIC LIGATURE BEH WITH HAH INITIAL FORM -0xF282 0xFC9E # ARABIC LIGATURE BEH WITH KHAH INITIAL FORM -0xF283 0xFCA1 # ARABIC LIGATURE TEH WITH JEEM INITIAL FORM -0xF284 0xFCA2 # ARABIC LIGATURE TEH WITH HAH INITIAL FORM -0xF285 0xFCA3 # ARABIC LIGATURE TEH WITH KHAH INITIAL FORM -0xF286 0xFCC9 # ARABIC LIGATURE LAM WITH JEEM INITIAL FORM -0xF287 0xFCCA # ARABIC LIGATURE LAM WITH HAH INITIAL FORM -0xF288 0xFCCB # ARABIC LIGATURE LAM WITH KHAH INITIAL FORM -0xF289 0xFCCE # ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM -0xF28A 0xFCCF # ARABIC LIGATURE MEEM WITH HAH INITIAL FORM -0xF28B 0xFCD0 # ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM -0xF28D 0xFCD2 # ARABIC LIGATURE NOON WITH JEEM INITIAL FORM -0xF28E 0xFCD3 # ARABIC LIGATURE NOON WITH HAH INITIAL FORM -0xF28F 0xFCDA # ARABIC LIGATURE YEH WITH JEEM INITIAL FORM -0xF290 0xFCDB # ARABIC LIGATURE YEH WITH HAH INITIAL FORM -0xF291 0xFCDC # ARABIC LIGATURE YEH WITH KHAH INITIAL FORM -0xF292 0xFC6D # ARABIC LIGATURE BEH WITH NOON FINAL FORM -0xF293 0xFC73 # ARABIC LIGATURE TEH WITH NOON FINAL FORM -0xF294 0xFC94 # ARABIC LIGATURE YEH WITH NOON FINAL FORM -0xF295 0xFC86 # ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM -0xF296 0xFC9F # ARABIC LIGATURE BEH WITH MEEM INITIAL FORM -0xF297 0xFCA4 # ARABIC LIGATURE TEH WITH MEEM INITIAL FORM -0xF298 0xFCD5 # ARABIC LIGATURE NOON WITH MEEM INITIAL FORM -0xF299 0xFCDD # ARABIC LIGATURE YEH WITH MEEM INITIAL FORM -0xF29A 0xFCA8 # ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM -0xF29B 0xFCAA # ARABIC LIGATURE HAH WITH MEEM INITIAL FORM -0xF29C 0xFCAC # ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM -0xF29D 0xFCCC # ARABIC LIGATURE LAM WITH MEEM INITIAL FORM -0xF29E 0xFCD1 # ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM -0xF29F 0xFC32 # ARABIC LIGATURE FEH WITH YEH ISOLATED FORM -0xF2A1 0xFEC2 # ARABIC LETTER TAH FINAL FORM -0xF2A2 0x0637 # ARABIC LETTER TAH -0xF2A2 0xFEC1 # ARABIC LETTER TAH ISOLATED FORM -0xF2A3 0x0638 # ARABIC LETTER ZAH -0xF2A3 0xFEC7 # ARABIC LETTER ZAH INITIAL FORM -0xF2A4 0xFEC8 # ARABIC LETTER ZAH MEDIAL FORM -0xF2A5 0xFEC6 # ARABIC LETTER ZAH FINAL FORM -0xF2A6 0xFEC5 # ARABIC LETTER ZAH ISOLATED FORM -0xF2A7 0xFECB # ARABIC LETTER AIN INITIAL FORM -0xF2A8 0xFECC # ARABIC LETTER AIN MEDIAL FORM -0xF2A9 0xFECA # ARABIC LETTER AIN FINAL FORM -0xF2AA 0x0639 # ARABIC LETTER AIN -0xF2AA 0xFEC9 # ARABIC LETTER AIN ISOLATED FORM -0xF2AB 0xFECF # ARABIC LETTER GHAIN INITIAL FORM -0xF2AC 0xFED0 # ARABIC LETTER GHAIN MEDIAL FORM -0xF2AD 0xFECE # ARABIC LETTER GHAIN FINAL FORM -0xF2AE 0x063A # ARABIC LETTER GHAIN -0xF2AE 0xFECD # ARABIC LETTER GHAIN ISOLATED FORM -0xF2AF 0xFED3 # ARABIC LETTER FEH INITIAL FORM -0xF2B0 0xFED4 # ARABIC LETTER FEH MEDIAL FORM -0xF2B1 0xFED2 # ARABIC LETTER FEH FINAL FORM -0xF2B2 0x0641 # ARABIC LETTER FEH -0xF2B2 0xFED1 # ARABIC LETTER FEH ISOLATED FORM -0xF2B3 0xFED7 # ARABIC LETTER QAF INITIAL FORM -0xF2B4 0xFED8 # ARABIC LETTER QAF MEDIAL FORM -0xF2B5 0xFED6 # ARABIC LETTER QAF FINAL FORM -0xF2B6 0x0642 # ARABIC LETTER QAF -0xF2B6 0xFED5 # ARABIC LETTER QAF ISOLATED FORM -0xF2B7 0xFEDB # ARABIC LETTER KAF INITIAL FORM -0xF2B8 0xFEDC # ARABIC LETTER KAF MEDIAL FORM -0xF2B9 0xFEDA # ARABIC LETTER KAF FINAL FORM -0xF2BA 0x0643 # ARABIC LETTER KAF -0xF2BA 0xFED9 # ARABIC LETTER KAF ISOLATED FORM -0xF2BB 0xFEDF # ARABIC LETTER LAM INITIAL FORM -0xF2BC 0xFEE0 # ARABIC LETTER LAM MEDIAL FORM -0xF2BD 0xFEDE # ARABIC LETTER LAM FINAL FORM -0xF2BE 0x0644 # ARABIC LETTER LAM -0xF2BE 0xFEDD # ARABIC LETTER LAM ISOLATED FORM -0xF2BF 0xFEE3 # ARABIC LETTER MEEM INITIAL FORM -0xF2C0 0xFEE4 # ARABIC LETTER MEEM MEDIAL FORM -0xF2C1 0xFEE2 # ARABIC LETTER MEEM FINAL FORM -0xF2C2 0x0645 # ARABIC LETTER MEEM -0xF2C2 0xFEE1 # ARABIC LETTER MEEM ISOLATED FORM -0xF2C3 0xFEE7 # ARABIC LETTER NOON INITIAL FORM -0xF2C4 0xFEE8 # ARABIC LETTER NOON MEDIAL FORM -0xF2C5 0xFEE6 # ARABIC LETTER NOON FINAL FORM -0xF2C6 0x0646 # ARABIC LETTER NOON -0xF2C6 0xFEE5 # ARABIC LETTER NOON ISOLATED FORM -0xF2C7 0xFEEB # ARABIC LETTER HEH INITIAL FORM -0xF2C8 0xFEEC # ARABIC LETTER HEH MEDIAL FORM -0xF2C9 0xFEEA # ARABIC LETTER HEH FINAL FORM -0xF2CA 0x0647 # ARABIC LETTER HEH -0xF2CA 0xFEE9 # ARABIC LETTER HEH ISOLATED FORM -0xF2CB 0x0648 # ARABIC LETTER WAW -0xF2CB 0xFEED # ARABIC LETTER WAW ISOLATED FORM -0xF2CC 0xFEEE # ARABIC LETTER WAW FINAL FORM -0xF2CD 0xFEF3 # ARABIC LETTER YEH INITIAL FORM -0xF2CE 0xFEF4 # ARABIC LETTER YEH MEDIAL FORM -0xF2CF 0xFEF2 # ARABIC LETTER YEH FINAL FORM -0xF2D0 0x064A # ARABIC LETTER YEH -0xF2D0 0xFEF1 # ARABIC LETTER YEH ISOLATED FORM -0xF2D1 0x0629 # ARABIC LETTER TEH MARBUTA -0xF2D1 0xFE93 # ARABIC LETTER TEH MARBUTA ISOLATED FORM -0xF2D2 0xFE94 # ARABIC LETTER TEH MARBUTA FINAL FORM -0xF2D3 0xFEF0 # ARABIC LETTER ALEF MAKSURA FINAL FORM -0xF2D4 0x0649 # ARABIC LETTER ALEF MAKSURA -0xF2D4 0xFEEF # ARABIC LETTER ALEF MAKSURA ISOLATED FORM -0xF2D5 0x0621 # ARABIC LETTER HAMZA -0xF2D6 0xFE8B # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM -0xF2D7 0xFE8C # ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM -0xF2D8 0xFE8A # ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM -0xF2D9 0x0626 # ARABIC LETTER YEH WITH HAMZA ABOVE -0xF2D9 0xFE89 # ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM -0xF2DA 0x0624 # ARABIC LETTER WAW WITH HAMZA ABOVE -0xF2DA 0xFE85 # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM -0xF2DB 0xFE86 # ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM -0xF2DC 0xFEFB # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM -0xF2DD 0xFEFC # ARABIC LIGATURE LAM WITH ALEF FINAL FORM -0xF2DE 0xFEF7 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM -0xF2DF 0xFEF8 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM -0xF2E0 0xFEF5 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM -0xF2E1 0xFEF6 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM -0xF2E2 0xFEF9 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM -0xF2E3 0xFEFA # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM -0xF2E4 0x064E # ARABIC FATHA -0xF2E5 0x064F # ARABIC DAMMA -0xF2E6 0x0652 # ARABIC SUKUN -0xF2E7 0x064B # ARABIC FATHATAN -0xF2E8 0x064C # ARABIC DAMMATAN -0xF2E9 0x0651 # ARABIC SHADDA -0xF2EA 0x0650 # ARABIC KASRA -0xF2EB 0x064D # ARABIC KASRATAN -0xF2EC 0xFC60 # ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM -0xF2ED 0xFC61 # ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM -0xF2EF 0xFC5E # ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM -0xF2F0 0xFC62 # ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM -0xF2F1 0xFEC4 # ARABIC LETTER TAH MEDIAL FORM diff --git a/thirdparty/harfbuzz/upstream/OT/Color/CBDT/CBDT.hh b/thirdparty/harfbuzz/upstream/OT/Color/CBDT/CBDT.hh index bcf1848f4..2d8f1da52 100644 --- a/thirdparty/harfbuzz/upstream/OT/Color/CBDT/CBDT.hh +++ b/thirdparty/harfbuzz/upstream/OT/Color/CBDT/CBDT.hh @@ -941,31 +941,33 @@ struct CBDT } } - bool has_data () const { return cbdt.get_length (); } + bool has_data () const { return cbdt->version.major; } bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + if (!has_data ()) return false; + hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; - hb_blob_t *blob = reference_png (font, glyph); - - if (unlikely (blob == hb_blob_get_empty ())) + if (unlikely (!font->get_glyph_extents (glyph, &extents, false))) return false; - if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; - if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + hb_blob_t *blob = reference_png (font, glyph); + if (unlikely (hb_blob_is_immutable (blob))) return false; bool ret = funcs->image (data, blob, pixel_extents.width, -pixel_extents.height, HB_PAINT_IMAGE_FORMAT_PNG, - font->slant_xy, + 0.f, &extents); hb_blob_destroy (blob); + return ret; } diff --git a/thirdparty/harfbuzz/upstream/OT/Color/COLR/COLR.hh b/thirdparty/harfbuzz/upstream/OT/Color/COLR/COLR.hh index 36b509d7c..e8c73ffaa 100644 --- a/thirdparty/harfbuzz/upstream/OT/Color/COLR/COLR.hh +++ b/thirdparty/harfbuzz/upstream/OT/Color/COLR/COLR.hh @@ -29,11 +29,15 @@ #define OT_COLOR_COLR_COLR_HH #include "../../../hb.hh" +#include "../../../hb-decycler.hh" #include "../../../hb-open-type.hh" #include "../../../hb-ot-var-common.hh" #include "../../../hb-paint.hh" +#include "../../../hb-paint-bounded.hh" #include "../../../hb-paint-extents.hh" +#include "../CPAL/CPAL.hh" + /* * COLR -- Color * https://docs.microsoft.com/en-us/typography/opentype/spec/colr @@ -44,6 +48,12 @@ namespace OT { struct hb_paint_context_t; } +struct hb_colr_scratch_t +{ + hb_paint_bounded_context_t paint_bounded; + hb_paint_extents_context_t paint_extents; +}; + namespace OT { struct COLR; @@ -66,11 +76,11 @@ public: hb_paint_funcs_t *funcs; void *data; hb_font_t *font; - unsigned int palette_index; + hb_array_t palette; hb_color_t foreground; ItemVarStoreInstancer &instancer; - hb_map_t current_glyphs; - hb_map_t current_layers; + hb_decycler_t glyphs_decycler; + hb_decycler_t layers_decycler; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_MAX_GRAPH_EDGE_COUNT; @@ -85,10 +95,29 @@ public: funcs (funcs_), data (data_), font (font_), - palette_index (palette_), + palette ( +#ifndef HB_NO_COLOR + // https://github.com/harfbuzz/harfbuzz/issues/5116 + font->face->table.CPAL->get_palette_colors (palette_ < font->face->table.CPAL->get_palette_count () ? palette_ : 0) +#endif + ), foreground (foreground_), instancer (instancer_) - { } + { + if (font->is_synthetic) + { + font = hb_font_create_sub_font (font); + hb_font_set_synthetic_bold (font, 0, 0, true); + hb_font_set_synthetic_slant (font, 0); + } + else + hb_font_reference (font); + } + + ~hb_paint_context_t () + { + hb_font_destroy (font); + } hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground) { @@ -99,12 +128,7 @@ public: if (color_index != 0xffff) { if (!funcs->custom_palette_color (data, color_index, &color)) - { - unsigned int clen = 1; - hb_face_t *face = hb_font_get_face (font); - - hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color); - } + color = palette[color_index]; *is_foreground = false; } @@ -154,7 +178,10 @@ struct hb_colrv1_closure_context_t : { glyphs->add (glyph_id); } void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers) - { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); } + { + if (num_of_layers == 0) return; + layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); + } void add_palette_index (unsigned palette_index) { palette_indices->add (palette_index); } @@ -626,10 +653,10 @@ struct PaintColrLayers TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); - return_trace (true); + uint32_t first_layer_index = numLayers ? c->plan->colrv1_layers.get (firstLayerIndex) : 0; + return_trace (c->serializer->check_assign (out->firstLayerIndex, first_layer_index, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -930,9 +957,9 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); - c->funcs->push_root_transform (c->data, c->font); + c->funcs->push_font_transform (c->data, c->font); c->recurse (this+paint); c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); @@ -1003,7 +1030,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - (this+transform).paint_glyph (c); + (this+transform).paint_glyph (c); // This does a push_transform() c->recurse (this+src); c->funcs->pop_transform (c->data); } @@ -1051,9 +1078,9 @@ struct PaintTranslate float ddx = dx + c->instancer (varIdxBase, 0); float ddy = dy + c->instancer (varIdxBase, 1); - bool p1 = c->funcs->push_translate (c->data, ddx, ddy); + c->funcs->push_translate (c->data, ddx, ddy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ @@ -1100,9 +1127,9 @@ struct PaintScale float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); - bool p1 = c->funcs->push_scale (c->data, sx, sy); + c->funcs->push_scale (c->data, sx, sy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ @@ -1153,13 +1180,9 @@ struct PaintScaleAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_scale (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_scale_around_center (c->data, sx, sy, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ @@ -1204,9 +1227,9 @@ struct PaintScaleUniform TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); - bool p1 = c->funcs->push_scale (c->data, s, s); + c->funcs->push_scale (c->data, s, s); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ @@ -1254,13 +1277,9 @@ struct PaintScaleUniformAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_scale (c->data, s, s); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_scale_around_center (c->data, s, s, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ @@ -1304,9 +1323,9 @@ struct PaintRotate TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); - bool p1 = c->funcs->push_rotate (c->data, a); + c->funcs->push_rotate (c->data, a); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ @@ -1354,13 +1373,9 @@ struct PaintRotateAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_rotate (c->data, a); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_rotate_around_center (c->data, a, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ @@ -1408,9 +1423,9 @@ struct PaintSkew float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); - bool p1 = c->funcs->push_skew (c->data, sx, sy); + c->funcs->push_skew (c->data, sx, sy); c->recurse (this+src); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ @@ -1461,13 +1476,9 @@ struct PaintSkewAroundCenter float tCenterX = centerX + c->instancer (varIdxBase, 2); float tCenterY = centerY + c->instancer (varIdxBase, 3); - bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY); - bool p2 = c->funcs->push_skew (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY); + c->funcs->push_skew_around_center (c->data, sx, sy, tCenterX, tCenterY); c->recurse (this+src); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ @@ -1509,10 +1520,12 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); + c->funcs->push_group (c->data); c->recurse (this+backdrop); c->funcs->push_group (c->data); c->recurse (this+src); c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } HBUINT8 format; /* format = 32 */ @@ -1600,7 +1613,7 @@ struct ClipBox const ItemVarStoreInstancer &instancer) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION)); case 2: return_trace (u.format2.subset (c, instancer)); default:return_trace (c->default_return_value ()); @@ -1609,8 +1622,8 @@ struct ClipBox void closurev1 (hb_colrv1_closure_context_t* c) const { - switch (u.format) { - case 2: u.format2.closurev1 (c); + switch (u.format.v) { + case 2: u.format2.closurev1 (c); return; default:return; } } @@ -1618,9 +1631,9 @@ struct ClipBox template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); default:return_trace (c->default_return_value ()); @@ -1631,7 +1644,7 @@ struct ClipBox const ItemVarStoreInstancer &instancer) const { ClipBoxData clip_box; - switch (u.format) { + switch (u.format.v) { case 1: u.format1.get_clip_box (clip_box, instancer); break; @@ -1651,7 +1664,7 @@ struct ClipBox protected: union { - HBUINT8 format; /* Format identifier */ + struct { HBUINT8 v; } format; /* Format identifier */ ClipBoxFormat1 format1; ClipBoxFormat2 format2; } u; @@ -1801,10 +1814,7 @@ struct ClipList { auto *rec = clips.as_array ().bsearch (gid); if (rec) - { - rec->get_extents (extents, this, instancer); - return true; - } + return rec->get_extents (extents, this, instancer); return false; } @@ -1831,9 +1841,9 @@ struct Paint template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.paintformat1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.paintformat2, std::forward (ds)...)); case 3: return_trace (c->dispatch (u.paintformat3, std::forward (ds)...)); @@ -1872,7 +1882,7 @@ struct Paint protected: union { - HBUINT8 format; + struct { HBUINT8 v; } format; PaintColrLayers paintformat1; NoVariable paintformat2; Variable paintformat3; @@ -2047,7 +2057,7 @@ struct delta_set_index_map_subset_plan_t outer_bit_count = 1; inner_bit_count = 1; - if (unlikely (!output_map.resize (map_count, false))) return false; + if (unlikely (!output_map.resize_dirty (map_count))) return false; for (unsigned idx = 0; idx < map_count; idx++) { @@ -2077,6 +2087,8 @@ struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; + bool has_data () const { return has_v0_data () || version; } + bool has_v0_data () const { return numBaseGlyphs; } bool has_v1_data () const { @@ -2110,7 +2122,53 @@ struct COLR { accelerator_t (hb_face_t *face) { colr = hb_sanitize_context_t ().reference_table (face); } - ~accelerator_t () { this->colr.destroy (); } + + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_colr_scratch_t (); + hb_free (scratch); + } + + colr.destroy (); + } + + + bool has_data () const { return colr->has_data (); } + +#ifndef HB_NO_PAINT + bool + get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (!has_data ())) return false; + + hb_colr_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = colr->get_extents (font, glyph, extents, *scratch); + release_scratch (scratch); + return ret; + } + + bool paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *data, + unsigned int palette_index, + hb_color_t foreground, + bool clip = true) const + { + if (unlikely (!has_data ())) return false; + + hb_colr_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = colr->paint_glyph (font, glyph, funcs, data, palette_index, foreground, clip, *scratch); + release_scratch (scratch); + return ret; + } +#endif bool is_valid () { return colr.get_blob ()->length; } @@ -2134,15 +2192,45 @@ struct COLR const ItemVariationStore &get_var_store () const { return colr->get_var_store (); } + const ItemVariationStore *get_var_store_ptr () const + { return colr->get_var_store_ptr (); } bool has_delta_set_index_map () const { return colr->has_delta_set_index_map (); } const DeltaSetIndexMap &get_delta_set_index_map () const { return colr->get_delta_set_index_map (); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return colr->get_delta_set_index_map_ptr (); } private: + + hb_colr_scratch_t *acquire_scratch () const + { + hb_colr_scratch_t *scratch = cached_scratch.get_acquire (); + + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_colr_scratch_t *) hb_calloc (1, sizeof (hb_colr_scratch_t)); + if (unlikely (!scratch)) + return nullptr; + } + + return scratch; + } + void release_scratch (hb_colr_scratch_t *scratch) const + { + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_colr_scratch_t (); + hb_free (scratch); + } + } + + public: hb_blob_ptr_t colr; + private: + mutable hb_atomic_t cached_scratch; }; void closure_glyphs (hb_codepoint_t glyph, @@ -2232,9 +2320,13 @@ struct COLR const DeltaSetIndexMap &get_delta_set_index_map () const { return has_delta_set_index_map () && hb_barrier () ? this+varIdxMap : Null (DeltaSetIndexMap); } + const DeltaSetIndexMap *get_delta_set_index_map_ptr () const + { return has_delta_set_index_map () && hb_barrier () ? &(this+varIdxMap) : nullptr; } const ItemVariationStore &get_var_store () const { return has_var_store () && hb_barrier () ? this+varStore : Null (ItemVariationStore); } + const ItemVariationStore *get_var_store_ptr () const + { return has_var_store () && hb_barrier () ? &(this+varStore) : nullptr; } const ClipList &get_clip_list () const { return has_clip_list () && hb_barrier () ? this+clipList : Null (ClipList); } @@ -2482,9 +2574,9 @@ struct COLR * after instancing */ if (!subset_varstore (c, colr_prime)) return_trace (false); - ItemVarStoreInstancer instancer (&(get_var_store ()), - &(get_delta_set_index_map ()), - c->plan->normalized_coords.as_array ()); + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + c->plan->normalized_coords.as_array ()); if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer)) return_trace (false); @@ -2510,11 +2602,14 @@ struct COLR #ifndef HB_NO_PAINT bool - get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + get_extents (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_colr_scratch_t &scratch) const { - ItemVarStoreInstancer instancer (&(get_var_store ()), - &(get_delta_set_index_map ()), + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), hb_array (font->coords, font->num_coords)); if (get_clip (glyph, extents, instancer)) @@ -2524,10 +2619,10 @@ struct COLR } auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; - bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0)); + scratch.paint_extents.clear (); + bool ret = paint_glyph (font, glyph, extents_funcs, &scratch.paint_extents, 0, HB_COLOR(0,0,0,0), true, scratch); - hb_extents_t e = extents_data.get_extents (); + auto e = scratch.paint_extents.get_extents (); if (e.is_void ()) { extents->x_bearing = 0; @@ -2573,13 +2668,21 @@ struct COLR #ifndef HB_NO_PAINT bool - paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const - { - ItemVarStoreInstancer instancer (&(get_var_store ()), - &(get_delta_set_index_map ()), - hb_array (font->coords, font->num_coords)); + paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *funcs, void *data, + unsigned int palette_index, hb_color_t foreground, + bool clip, + hb_colr_scratch_t &scratch) const + { + ItemVarStoreInstancer instancer (get_var_store_ptr (), + get_delta_set_index_map_ptr (), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); - c.current_glyphs.add (glyph); + + hb_decycler_node_t node (c.glyphs_decycler); + node.visit (glyph); if (version >= 1) { @@ -2605,26 +2708,26 @@ struct COLR } else { - auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; + clip = false; + is_bounded = false; + } + + if (!is_bounded) + { + auto *bounded_funcs = hb_paint_bounded_get_funcs (); + scratch.paint_bounded.clear (); paint_glyph (font, glyph, - extents_funcs, &extents_data, + bounded_funcs, &scratch.paint_bounded, palette_index, foreground, - false); - - hb_extents_t extents = extents_data.get_extents (); - is_bounded = extents_data.is_bounded (); + false, + scratch); - c.funcs->push_clip_rectangle (c.data, - extents.xmin, - extents.ymin, - extents.xmax, - extents.ymax); + is_bounded = scratch.paint_bounded.is_bounded (); } } - c.funcs->push_root_transform (c.data, font); + c.funcs->push_font_transform (c.data, font); if (is_bounded) c.recurse (*paint); @@ -2695,19 +2798,14 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); + hb_decycler_node_t node (c->layers_decycler); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { - if (unlikely (c->current_layers.has (i))) - continue; - - c->current_layers.add (i); + if (unlikely (!node.visit (i))) + return; const Paint &paint = paint_offset_lists.get_paint (i); - c->funcs->push_group (c->data); c->recurse (paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); - - c->current_layers.del (i); } } @@ -2715,16 +2813,14 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - if (unlikely (c->current_glyphs.has (gid))) + hb_decycler_node_t node (c->glyphs_decycler); + if (unlikely (!node.visit (gid))) return; - c->current_glyphs.add (gid); - - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->funcs->pop_transform (c->data); - c->current_glyphs.del (gid); return; } c->funcs->pop_transform (c->data); @@ -2747,8 +2843,6 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (has_clip_box) c->funcs->pop_clip (c->data); - - c->current_glyphs.del (gid); } } /* namespace OT */ diff --git a/thirdparty/harfbuzz/upstream/OT/Color/CPAL/CPAL.hh b/thirdparty/harfbuzz/upstream/OT/Color/CPAL/CPAL.hh index 2821334db..2b8b69b60 100644 --- a/thirdparty/harfbuzz/upstream/OT/Color/CPAL/CPAL.hh +++ b/thirdparty/harfbuzz/upstream/OT/Color/CPAL/CPAL.hh @@ -187,6 +187,14 @@ struct CPAL hb_ot_name_id_t get_color_name_id (unsigned int color_index) const { return v1 ().get_color_name_id (this, color_index, numColors); } + hb_array_t get_palette_colors (unsigned int palette_index) const + { + if (unlikely (palette_index >= numPalettes)) + return hb_array_t (); + unsigned int start_index = colorRecordIndicesZ[palette_index]; + hb_array_t all_colors ((this+colorRecordsZ).arrayZ, numColorRecords); + return all_colors.sub_array (start_index, numColors); + } unsigned int get_palette_colors (unsigned int palette_index, unsigned int start_offset, unsigned int *color_count, /* IN/OUT. May be NULL. */ @@ -299,6 +307,7 @@ struct CPAL if (first_color_to_layer_index.has (first_color_record_idx)) continue; first_color_index_for_layer.push (first_color_record_idx); + if (unlikely (!c->serializer->propagate_error (first_color_index_for_layer))) return_trace (false); first_color_to_layer_index.set (first_color_record_idx, first_color_index_for_layer.length - 1); } diff --git a/thirdparty/harfbuzz/upstream/OT/Color/sbix/sbix.hh b/thirdparty/harfbuzz/upstream/OT/Color/sbix/sbix.hh index 51ae1a9c6..bb0e83e2e 100644 --- a/thirdparty/harfbuzz/upstream/OT/Color/sbix/sbix.hh +++ b/thirdparty/harfbuzz/upstream/OT/Color/sbix/sbix.hh @@ -237,27 +237,28 @@ struct sbix int x_offset = 0, y_offset = 0; unsigned int strike_ppem = 0; - hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); hb_glyph_extents_t extents; hb_glyph_extents_t pixel_extents; - if (blob == hb_blob_get_empty ()) + if (!font->get_glyph_extents (glyph, &extents, false)) return false; - if (!hb_font_get_glyph_extents (font, glyph, &extents)) + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) return false; - if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); + if (hb_blob_is_immutable (blob)) return false; bool ret = funcs->image (data, blob, pixel_extents.width, -pixel_extents.height, HB_PAINT_IMAGE_FORMAT_PNG, - font->slant_xy, + 0.f, &extents); hb_blob_destroy (blob); + return ret; } diff --git a/thirdparty/harfbuzz/upstream/OT/Color/svg/svg.hh b/thirdparty/harfbuzz/upstream/OT/Color/svg/svg.hh index 2e1f93510..d6fb71832 100644 --- a/thirdparty/harfbuzz/upstream/OT/Color/svg/svg.hh +++ b/thirdparty/harfbuzz/upstream/OT/Color/svg/svg.hh @@ -27,7 +27,12 @@ #include "../../../hb-open-type.hh" #include "../../../hb-blob.hh" +#include "../../../hb-limits.hh" +#include "../../../hb-map.hh" #include "../../../hb-paint.hh" +#include "../../../hb-zlib.hh" +#include +#include /* * SVG -- SVG (Scalable Vector Graphics) @@ -39,12 +44,62 @@ namespace OT { +static inline hb_blob_t * +hb_ot_svg_reference_normalized_blob (hb_blob_t *image, + const char **svg, + unsigned *len) +{ + hb_blob_t *blob = hb_blob_reference (image); + unsigned data_len = 0; + const char *data = hb_blob_get_data (blob, &data_len); + + if (!data || !data_len) + goto fail; + + if (hb_blob_is_gzip (data, data_len)) + { + uint32_t expected_size = 0; + if (hb_gzip_get_uncompressed_size (data, data_len, &expected_size) && + unlikely ((size_t) expected_size > (size_t) HB_SVG_MAX_DOCUMENT_SIZE)) + goto fail; + + hb_blob_t *uncompressed = hb_blob_decompress_gzip (blob, + HB_SVG_MAX_DOCUMENT_SIZE); + if (!uncompressed) + goto fail; + + hb_blob_destroy (blob); + blob = uncompressed; + data = hb_blob_get_data (blob, &data_len); + if (!data || !data_len) + goto fail; + } + + if (unlikely ((size_t) data_len > (size_t) HB_SVG_MAX_DOCUMENT_SIZE)) + goto fail; + + if (svg) *svg = data; + if (len) *len = data_len; + return blob; + +fail: + hb_blob_destroy (blob); + if (svg) *svg = nullptr; + if (len) *len = 0; + return nullptr; +} struct SVGDocumentIndexEntry { int cmp (hb_codepoint_t g) const { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; } + hb_codepoint_t get_start_glyph () const + { return startGlyphID; } + + hb_codepoint_t get_end_glyph () const + { return endGlyphID; } + hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const { return hb_blob_create_sub_blob (svg_blob, @@ -78,13 +133,50 @@ struct SVG { static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG; + struct svg_id_span_t + { + const char *p; + unsigned len; + + bool operator == (const svg_id_span_t &o) const + { + return len == o.len && !memcmp (p, o.p, len); + } + + uint32_t hash () const + { + uint32_t h = hb_hash (len); + for (unsigned i = 0; i < len; i++) + h = h * 33u + (unsigned char) p[i]; + return h; + } + }; + + struct svg_defs_entry_t + { + svg_id_span_t id; + unsigned start; + unsigned end; + }; + + struct svg_doc_cache_t + { + hb_blob_t *blob = nullptr; + const char *svg = nullptr; + unsigned len = 0; + hb_vector_t defs_entries; + hb_codepoint_t start_glyph = HB_CODEPOINT_INVALID; + hb_codepoint_t end_glyph = HB_CODEPOINT_INVALID; + hb_vector_t> glyph_spans; + hb_hashmap_t> id_spans; + }; + bool has_data () const { return svgDocEntries; } struct accelerator_t { - accelerator_t (hb_face_t *face) - { table = hb_sanitize_context_t ().reference_table (face); } - ~accelerator_t () { table.destroy (); } + accelerator_t (hb_face_t *face); + ~accelerator_t (); hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const { @@ -92,8 +184,52 @@ struct SVG table->svgDocEntries); } + unsigned get_document_count () const + { return table->get_document_count (); } + + bool get_glyph_document_index (hb_codepoint_t glyph_id, unsigned *index) const + { return table->get_glyph_document_index (glyph_id, index); } + + bool get_document_glyph_range (unsigned index, + hb_codepoint_t *start_glyph, + hb_codepoint_t *end_glyph) const + { return table->get_document_glyph_range (index, start_glyph, end_glyph); } + bool has_data () const { return table->has_data (); } + const svg_doc_cache_t * + get_or_create_doc_cache (hb_blob_t *image, + const char *svg, + unsigned len, + unsigned doc_index, + hb_codepoint_t start_glyph, + hb_codepoint_t end_glyph) const; + + const char * + doc_cache_get_svg (const svg_doc_cache_t *doc, + unsigned *len) const; + + const hb_vector_t * + doc_cache_get_defs_entries (const svg_doc_cache_t *doc) const; + + bool + doc_cache_get_glyph_span (const svg_doc_cache_t *doc, + hb_codepoint_t glyph, + unsigned *start, + unsigned *end) const; + + bool + doc_cache_find_id_span (const svg_doc_cache_t *doc, + svg_id_span_t id, + unsigned *start, + unsigned *end) const; + + bool + doc_cache_find_id_cstr (const svg_doc_cache_t *doc, + const char *id, + unsigned *start, + unsigned *end) const; + bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { if (!has_data ()) @@ -104,26 +240,69 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, - blob, - 0, 0, - HB_PAINT_IMAGE_FORMAT_SVG, - font->slant_xy, - nullptr); + bool ret = funcs->image (data, + blob, + 0, 0, + HB_PAINT_IMAGE_FORMAT_SVG, + 0.f, + nullptr); hb_blob_destroy (blob); - return true; + + return ret; } private: + svg_doc_cache_t * + make_doc_cache (hb_blob_t *image, + const char *svg, + unsigned len, + hb_codepoint_t start_glyph, + hb_codepoint_t end_glyph) const; + + static void destroy_doc_cache (svg_doc_cache_t *doc); + hb_blob_ptr_t table; + mutable hb_vector_t> doc_caches; public: - DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t)); + DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t) + + sizeof (hb_vector_t>)); }; const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const { return (this+svgDocEntries).bsearch (glyph_id); } + unsigned get_document_count () const + { + if (!has_data ()) + return 0; + return (this + svgDocEntries).len; + } + + bool get_glyph_document_index (hb_codepoint_t glyph_id, unsigned *index) const + { + if (!has_data ()) + return false; + return (this + svgDocEntries).bfind (glyph_id, index); + } + + bool get_document_glyph_range (unsigned index, + hb_codepoint_t *start_glyph, + hb_codepoint_t *end_glyph) const + { + if (!has_data ()) + return false; + + const auto &entries = this + svgDocEntries; + if (index >= entries.len) + return false; + + const auto &entry = entries.arrayZ[index]; + if (start_glyph) *start_glyph = entry.get_start_glyph (); + if (end_glyph) *end_glyph = entry.get_end_glyph (); + return true; + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -142,6 +321,506 @@ struct SVG DEFINE_SIZE_STATIC (10); }; +namespace _hb_svg_cache_impl { + +struct glyph_entry_t +{ + hb_codepoint_t glyph; + uint32_t start; + uint32_t end; +}; + +struct id_entry_t +{ + SVG::svg_id_span_t id; + uint32_t start; + uint32_t end; +}; + +struct open_elem_t +{ + unsigned start; + SVG::svg_id_span_t id; + bool in_defs_content; + bool is_defs; +}; + +static const unsigned MAX_DEPTH = 128; + +static inline int +find_substr (const char *s, + unsigned n, + unsigned from, + const char *needle, + unsigned needle_len) +{ + if (!needle_len || from >= n || needle_len > n) + return -1; + for (unsigned i = from; i + needle_len <= n; i++) + if (s[i] == needle[0] && !memcmp (s + i, needle, needle_len)) + return (int) i; + return -1; +} + +static inline bool +parse_id_in_start_tag (const char *svg, + unsigned tag_start, + unsigned tag_end, + SVG::svg_id_span_t *id) +{ + unsigned p = tag_start; + while (p + 4 <= tag_end) + { + if (!memcmp (svg + p, "id=\"", 4)) + { + unsigned b = p + 4; + unsigned e = b; + while (e < tag_end && svg[e] != '"') e++; + if (e <= tag_end && e > b) + { + *id = {svg + b, e - b}; + return true; + } + } + if (!memcmp (svg + p, "id='", 4)) + { + unsigned b = p + 4; + unsigned e = b; + while (e < tag_end && svg[e] != '\'') e++; + if (e <= tag_end && e > b) + { + *id = {svg + b, e - b}; + return true; + } + } + p++; + } + return false; +} + +static inline bool +parse_glyph_id_span (const SVG::svg_id_span_t &id, + hb_codepoint_t *glyph) +{ + if (id.len <= 5 || memcmp (id.p, "glyph", 5)) + return false; + + hb_codepoint_t gid = 0; + for (unsigned i = 5; i < id.len; i++) + { + unsigned char c = (unsigned char) id.p[i]; + if (c < '0' || c > '9') + return false; + hb_codepoint_t digit = (hb_codepoint_t) (c - '0'); + if (unlikely (gid > HB_CODEPOINT_INVALID / 10 || + (gid == HB_CODEPOINT_INVALID / 10 && + digit > HB_CODEPOINT_INVALID % 10))) + return false; + gid = (hb_codepoint_t) (gid * 10 + digit); + } + + *glyph = gid; + return true; +} + +static inline bool +parse_cache_entries_linear (const char *svg, + unsigned len, + hb_vector_t *defs_entries, + hb_vector_t *glyph_spans, + hb_vector_t *id_entries) +{ + open_elem_t stack[MAX_DEPTH]; + unsigned depth = 0; + defs_entries->alloc (256); + id_entries->alloc (256); + + unsigned defs_depth = 0; + unsigned i = 0; + while (i < len) + { + if (svg[i] != '<') + { + i++; + continue; + } + + if (i + 4 <= len && !memcmp (svg + i, "", 3); + if (cend < 0) return false; + i = (unsigned) cend + 3; + continue; + } + if (i + 9 <= len && !memcmp (svg + i, "", 9)) + { + int cend = find_substr (svg, len, i + 9, "", 3); + if (cend < 0) return false; + i = (unsigned) cend + 3; + continue; + } + + bool closing = (i + 1 < len && svg[i + 1] == '/'); + bool special = (i + 1 < len && (svg[i + 1] == '!' || svg[i + 1] == '?')); + + unsigned gt = i + 1; + char quote = 0; + while (gt < len) + { + char c = svg[gt]; + if (quote) + { + if (c == quote) quote = 0; + } + else + { + if (c == '"' || c == '\'') + quote = c; + else if (c == '>') + break; + } + gt++; + } + if (gt >= len) + return false; + + if (special) + { + i = gt + 1; + continue; + } + + unsigned p = i + (closing ? 2 : 1); + while (p < gt && isspace ((unsigned char) svg[p])) p++; + const char *name = svg + p; + unsigned name_len = 0; + while (p + name_len < gt) + { + unsigned char c = (unsigned char) name[name_len]; + if (!(isalnum (c) || c == '_' || c == '-' || c == ':')) + break; + name_len++; + } + bool is_defs = (name_len == 4 && !memcmp (name, "defs", 4)); + + if (closing) + { + if (!depth) + { + i = gt + 1; + continue; + } + + open_elem_t e = stack[--depth]; + unsigned end = gt + 1; + + if (e.id.len) + { + auto *id_slot = id_entries->push (); + if (unlikely (!id_slot)) + return false; + *id_slot = {e.id, (uint32_t) e.start, (uint32_t) end}; + + if (e.in_defs_content) + { + auto *slot = defs_entries->push (); + if (unlikely (!slot)) + return false; + slot->id = e.id; + slot->start = e.start; + slot->end = end; + } + + hb_codepoint_t gid; + if (parse_glyph_id_span (e.id, &gid)) + { + auto *span = glyph_spans->push (); + if (unlikely (!span)) + return false; + span->glyph = gid; + span->start = (uint32_t) e.start; + span->end = (uint32_t) end; + } + } + + if (e.is_defs && defs_depth) + defs_depth--; + + i = end; + continue; + } + + SVG::svg_id_span_t id = {nullptr, 0}; + parse_id_in_start_tag (svg, i, gt, &id); + + unsigned r = gt; + while (r > i && isspace ((unsigned char) svg[r - 1])) r--; + bool self_closing = (r > i && svg[r - 1] == '/'); + + open_elem_t e = {i, id, defs_depth > 0, is_defs}; + + if (self_closing) + { + unsigned end = gt + 1; + if (e.id.len) + { + auto *id_slot = id_entries->push (); + if (unlikely (!id_slot)) + return false; + *id_slot = {e.id, (uint32_t) e.start, (uint32_t) end}; + + if (e.in_defs_content) + { + auto *slot = defs_entries->push (); + if (unlikely (!slot)) + return false; + slot->id = e.id; + slot->start = e.start; + slot->end = end; + } + + hb_codepoint_t gid; + if (parse_glyph_id_span (e.id, &gid)) + { + auto *span = glyph_spans->push (); + if (unlikely (!span)) + return false; + span->glyph = gid; + span->start = (uint32_t) e.start; + span->end = (uint32_t) end; + } + } + } + else + { + if (unlikely (depth >= MAX_DEPTH)) + return false; + stack[depth++] = e; + if (is_defs) + defs_depth++; + } + + i = gt + 1; + } + + return true; +} + +} /* namespace _hb_svg_cache_impl */ + +inline +SVG::accelerator_t::accelerator_t (hb_face_t *face) +{ + table = hb_sanitize_context_t ().reference_table (face); + doc_caches.init (); + unsigned doc_count = table->get_document_count (); + if (doc_count && unlikely (!doc_caches.resize (doc_count))) + doc_caches.resize (0); + for (unsigned i = 0; i < doc_caches.length; i++) + doc_caches.arrayZ[i].set_relaxed (nullptr); +} + +inline +SVG::accelerator_t::~accelerator_t () +{ + for (unsigned i = 0; i < doc_caches.length; i++) + destroy_doc_cache (doc_caches.arrayZ[i].get_relaxed ()); + doc_caches.fini (); + table.destroy (); +} + +inline void +SVG::accelerator_t::destroy_doc_cache (svg_doc_cache_t *doc) +{ + if (!doc) + return; + doc->glyph_spans.fini (); + doc->defs_entries.fini (); + doc->id_spans.fini (); + hb_blob_destroy (doc->blob); + hb_free (doc); +} + +inline SVG::svg_doc_cache_t * +SVG::accelerator_t::make_doc_cache (hb_blob_t *image, + const char *svg, + unsigned len, + hb_codepoint_t start_glyph, + hb_codepoint_t end_glyph) const +{ + static const uint32_t INVALID_SPAN = 0xFFFFFFFFu; + + auto *doc = (svg_doc_cache_t *) hb_malloc (sizeof (svg_doc_cache_t)); + if (!doc) + return nullptr; + + doc->blob = nullptr; + doc->svg = nullptr; + doc->len = 0; + doc->defs_entries.init (); + doc->start_glyph = HB_CODEPOINT_INVALID; + doc->end_glyph = HB_CODEPOINT_INVALID; + doc->glyph_spans.init (); + doc->id_spans.init (); + + doc->blob = hb_blob_reference (image); + doc->svg = svg; + doc->len = len; + doc->start_glyph = start_glyph; + doc->end_glyph = end_glyph; + + if (unlikely (start_glyph == HB_CODEPOINT_INVALID || end_glyph < start_glyph)) + { + destroy_doc_cache (doc); + return nullptr; + } + + unsigned glyph_count = end_glyph - start_glyph + 1; + if (!doc->glyph_spans.resize ((int) glyph_count)) + { + destroy_doc_cache (doc); + return nullptr; + } + for (unsigned i = 0; i < glyph_count; i++) + doc->glyph_spans.arrayZ[i] = hb_pair_t (INVALID_SPAN, INVALID_SPAN); + + hb_vector_t<_hb_svg_cache_impl::glyph_entry_t> glyph_spans; + glyph_spans.init (); + hb_vector_t<_hb_svg_cache_impl::id_entry_t> id_entries; + id_entries.init (); + if (!_hb_svg_cache_impl::parse_cache_entries_linear (svg, len, + &doc->defs_entries, + &glyph_spans, + &id_entries)) + { + id_entries.fini (); + glyph_spans.fini (); + destroy_doc_cache (doc); + return nullptr; + } + + for (unsigned i = 0; i < glyph_spans.length; i++) + { + const auto &span = glyph_spans.arrayZ[i]; + if (unlikely (span.glyph < start_glyph || span.glyph > end_glyph)) + continue; + doc->glyph_spans.arrayZ[span.glyph - start_glyph] = hb_pair_t (span.start, span.end); + } + + for (unsigned i = 0; i < id_entries.length; i++) + { + const auto &e = id_entries.arrayZ[i]; + hb_pair_t *out = nullptr; + if (doc->id_spans.has (e.id, &out)) + continue; + if (unlikely (!doc->id_spans.set (e.id, hb_pair_t (e.start, e.end)))) + { + id_entries.fini (); + glyph_spans.fini (); + destroy_doc_cache (doc); + return nullptr; + } + } + + id_entries.fini (); + glyph_spans.fini (); + return doc; +} + +inline const SVG::svg_doc_cache_t * +SVG::accelerator_t::get_or_create_doc_cache (hb_blob_t *image, + const char *svg, + unsigned len, + unsigned doc_index, + hb_codepoint_t start_glyph, + hb_codepoint_t end_glyph) const +{ + if (doc_index >= doc_caches.length) + return nullptr; + + auto &slot = doc_caches.arrayZ[doc_index]; + auto *doc = slot.get_acquire (); + if (doc) + return doc; + + auto *fresh = make_doc_cache (image, svg, len, start_glyph, end_glyph); + if (!fresh) + return nullptr; + + auto *expected = (svg_doc_cache_t *) nullptr; + if (slot.cmpexch (expected, fresh)) + return fresh; + + destroy_doc_cache (fresh); + return expected; +} + +inline const char * +SVG::accelerator_t::doc_cache_get_svg (const svg_doc_cache_t *doc, + unsigned *len) const +{ + if (!doc) + { + if (len) *len = 0; + return nullptr; + } + if (len) *len = doc->len; + return doc->svg; +} + +inline const hb_vector_t * +SVG::accelerator_t::doc_cache_get_defs_entries (const svg_doc_cache_t *doc) const +{ + return doc ? &doc->defs_entries : nullptr; +} + +inline bool +SVG::accelerator_t::doc_cache_get_glyph_span (const svg_doc_cache_t *doc, + hb_codepoint_t glyph, + unsigned *start, + unsigned *end) const +{ + static const uint32_t INVALID_SPAN = 0xFFFFFFFFu; + if (!doc || doc->start_glyph == HB_CODEPOINT_INVALID || + glyph < doc->start_glyph || glyph > doc->end_glyph) + return false; + + const auto &span = doc->glyph_spans.arrayZ[glyph - doc->start_glyph]; + if (span.first == INVALID_SPAN) + return false; + + if (start) *start = span.first; + if (end) *end = span.second; + return true; +} + +inline bool +SVG::accelerator_t::doc_cache_find_id_span (const svg_doc_cache_t *doc, + svg_id_span_t id, + unsigned *start, + unsigned *end) const +{ + if (!doc || !id.p || !id.len) + return false; + hb_pair_t *span = nullptr; + if (!doc->id_spans.has (id, &span)) + return false; + if (start) *start = span->first; + if (end) *end = span->second; + return true; +} + +inline bool +SVG::accelerator_t::doc_cache_find_id_cstr (const svg_doc_cache_t *doc, + const char *id, + unsigned *start, + unsigned *end) const +{ + if (!id) return false; + svg_id_span_t key = {id, (unsigned) strlen (id)}; + return doc_cache_find_id_span (doc, key, start, end); +} + struct SVG_accelerator_t : SVG::accelerator_t { SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {} }; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/upstream/OT/Layout/Common/Coverage.hh index 344e87afb..93ca1b2f7 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/Common/Coverage.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/Common/Coverage.hh @@ -46,7 +46,7 @@ struct Coverage protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CoverageFormat1_3 format1; CoverageFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -55,7 +55,7 @@ struct Coverage #endif } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE @@ -63,9 +63,9 @@ struct Coverage bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); @@ -86,7 +86,7 @@ struct Coverage unsigned int get (hb_codepoint_t k) const { return get_coverage (k); } unsigned int get_coverage (hb_codepoint_t glyph_id) const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.get_coverage (glyph_id); case 2: return u.format2.get_coverage (glyph_id); #ifndef HB_NO_BEYOND_64K @@ -96,10 +96,39 @@ struct Coverage default:return NOT_COVERED; } } + unsigned int get_coverage (hb_codepoint_t glyph_id, + hb_ot_layout_mapping_cache_t *cache) const + { + unsigned coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; + coverage = get_coverage (glyph_id); + if (cache) { + if (coverage == NOT_COVERED) + cache->set_unchecked (glyph_id, cache->MAX_VALUE); + else if (likely (coverage < cache->MAX_VALUE)) + cache->set_unchecked (glyph_id, coverage); + } + return coverage; + } + + unsigned int get_coverage_binary (hb_codepoint_t glyph_id, + hb_ot_layout_binary_cache_t *cache) const + { + unsigned coverage; + if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED; + coverage = get_coverage (glyph_id); + if (cache) { + if (coverage == NOT_COVERED) + cache->set_unchecked (glyph_id, cache->MAX_VALUE); + else + cache->set_unchecked (glyph_id, 0); + } + return coverage; + } unsigned get_population () const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.get_population (); case 2: return u.format2.get_population (); #ifndef HB_NO_BEYOND_64K @@ -131,11 +160,11 @@ struct Coverage last = g; if (g > max) max = g; } - u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2; + u.format.v = !unsorted && count <= num_ranges * 3 ? 1 : 2; #ifndef HB_NO_BEYOND_64K if (max > 0xFFFFu) - u.format += 2; + u.format.v += 2; if (unlikely (max > 0xFFFFFFu)) #else if (unlikely (max > 0xFFFFu)) @@ -145,7 +174,7 @@ struct Coverage return_trace (false); } - switch (u.format) + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, glyphs)); case 2: return_trace (u.format2.serialize (c, glyphs)); @@ -176,7 +205,7 @@ struct Coverage bool intersects (const hb_set_t *glyphs) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.intersects (glyphs); case 2: return u.format2.intersects (glyphs); @@ -189,7 +218,7 @@ struct Coverage } bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.intersects_coverage (glyphs, index); case 2: return u.format2.intersects_coverage (glyphs, index); @@ -201,12 +230,25 @@ struct Coverage } } + unsigned cost () const + { + switch (u.format.v) { + case 1: hb_barrier (); return u.format1.cost (); + case 2: hb_barrier (); return u.format2.cost (); +#ifndef HB_NO_BEYOND_64K + case 3: hb_barrier (); return u.format3.cost (); + case 4: hb_barrier (); return u.format4.cost (); +#endif + default:return 0u; + } + } + /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template bool collect_coverage (set_t *glyphs) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.collect_coverage (glyphs); case 2: return u.format2.collect_coverage (glyphs); @@ -222,7 +264,7 @@ struct Coverage hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const { - switch (u.format) + switch (u.format.v) { case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); @@ -240,7 +282,7 @@ struct Coverage iter_t (const Coverage &c_ = Null (Coverage)) { hb_memset (this, 0, sizeof (*this)); - format = c_.u.format; + format = c_.u.format.v; switch (format) { case 1: u.format1.init (c_.u.format1); return; @@ -310,7 +352,7 @@ struct Coverage } iter_t __end__ () const { - iter_t it = {}; + iter_t it; it.format = format; switch (format) { diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat1.hh index 3f598d40e..823e45073 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat1.hh @@ -41,11 +41,11 @@ struct CoverageFormat1_3 { friend struct Coverage; - protected: + public: HBUINT16 coverageFormat; /* Format identifier--format = 1 */ SortedArray16Of glyphArray; /* Array of GlyphIDs--in numerical order */ - public: + DEFINE_SIZE_ARRAY (4, glyphArray); private: @@ -77,7 +77,7 @@ struct CoverageFormat1_3 bool intersects (const hb_set_t *glyphs) const { - if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2) + if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len)) { for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) @@ -103,6 +103,8 @@ struct CoverageFormat1_3 intersect_glyphs << glyphArray[i]; } + unsigned cost () const { return hb_bit_storage ((unsigned) glyphArray.len); /* bsearch cost */ } + template bool collect_coverage (set_t *glyphs) const { return glyphs->add_sorted_array (glyphArray.as_array ()); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat2.hh b/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat2.hh index 9c8754235..19895cabb 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat2.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/Common/CoverageFormat2.hh @@ -40,7 +40,7 @@ struct CoverageFormat2_4 { friend struct Coverage; - protected: + public: HBUINT16 coverageFormat; /* Format identifier--format = 2 */ SortedArray16Of> rangeRecord; /* Array of glyph ranges--ordered by @@ -120,7 +120,7 @@ struct CoverageFormat2_4 bool intersects (const hb_set_t *glyphs) const { - if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len)) { for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) @@ -157,6 +157,8 @@ struct CoverageFormat2_4 } } + unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ } + template bool collect_coverage (set_t *glyphs) const { diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GDEF/GDEF.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GDEF/GDEF.hh index 16b232a2a..d0b8c1bd1 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GDEF/GDEF.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GDEF/GDEF.hh @@ -205,20 +205,19 @@ struct CaretValueFormat3 unsigned varidx = (this+deviceTable).get_variation_index (); hb_pair_t *new_varidx_delta; - if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) - return_trace (false); + if (c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) { + uint32_t new_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); + if (delta != 0) + { + if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + } - uint32_t new_varidx = hb_first (*new_varidx_delta); - int delta = hb_second (*new_varidx_delta); - if (delta != 0) - { - if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); + if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } - if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) - return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); - if (!c->serializer->embed (deviceTable)) return_trace (false); @@ -253,7 +252,7 @@ struct CaretValue hb_codepoint_t glyph_id, const ItemVariationStore &var_store) const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.get_caret_value (font, direction); case 2: return u.format2.get_caret_value (font, direction, glyph_id); case 3: return u.format3.get_caret_value (font, direction, var_store); @@ -264,9 +263,9 @@ struct CaretValue template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -276,7 +275,7 @@ struct CaretValue void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - switch (u.format) { + switch (u.format.v) { case 1: case 2: return; @@ -290,9 +289,9 @@ struct CaretValue bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); case 3: return_trace (u.format3.sanitize (c)); @@ -302,13 +301,13 @@ struct CaretValue protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CaretValueFormat1 format1; CaretValueFormat2 format2; CaretValueFormat3 format3; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; struct LigGlyph @@ -520,7 +519,7 @@ struct MarkGlyphSets { bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const { - switch (u.format) { + switch (u.format.v) { case 1: return u.format1.covers (set_index, glyph_id); default:return false; } @@ -529,7 +528,7 @@ struct MarkGlyphSets template void collect_coverage (hb_vector_t &sets) const { - switch (u.format) { + switch (u.format.v) { case 1: u.format1.collect_coverage (sets); return; default:return; } @@ -538,7 +537,7 @@ struct MarkGlyphSets void collect_used_mark_sets (const hb_set_t& glyph_set, hb_set_t& used_mark_sets /* OUT */) const { - switch (u.format) { + switch (u.format.v) { case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return; default:return; } @@ -547,7 +546,7 @@ struct MarkGlyphSets bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.subset (c)); default:return_trace (false); } @@ -556,9 +555,9 @@ struct MarkGlyphSets bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); default:return_trace (true); } @@ -566,11 +565,11 @@ struct MarkGlyphSets protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkGlyphSetsFormat1 format1; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; @@ -978,7 +977,7 @@ struct GDEF } #ifndef HB_NO_GDEF_CACHE - table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests); + table->get_mark_glyph_sets ().collect_coverage (mark_glyph_sets); #endif } ~accelerator_t () { table.destroy (); } @@ -1003,19 +1002,36 @@ struct GDEF } + HB_ALWAYS_INLINE bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const { return #ifndef HB_NO_GDEF_CACHE - mark_glyph_set_digests[set_index].may_have (glyph_id) && + // We can access arrayZ directly because of sanitize_lookup_props() guarantee. + mark_glyph_sets.arrayZ[set_index].may_have (glyph_id) && +#endif + table->mark_set_covers (set_index, glyph_id) + ; + } + + unsigned sanitize_lookup_props (unsigned lookup_props) const + { +#ifndef HB_NO_GDEF_CACHE + if (lookup_props & LookupFlag::UseMarkFilteringSet && + (lookup_props >> 16) >= mark_glyph_sets.length) + { + // Invalid mark filtering set index; unset the flag. + lookup_props &= ~LookupFlag::UseMarkFilteringSet; + } #endif - table->mark_set_covers (set_index, glyph_id); + return lookup_props; } hb_blob_ptr_t table; #ifndef HB_NO_GDEF_CACHE - hb_vector_t mark_glyph_set_digests; - mutable hb_cache_t<21, 3, 8> glyph_props_cache; + hb_vector_t mark_glyph_sets; + mutable hb_cache_t<21, 3> glyph_props_cache; + static_assert (sizeof (glyph_props_cache) == 512, ""); #endif }; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/Anchor.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/Anchor.hh index 7802e397f..1938803fa 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/Anchor.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/Anchor.hh @@ -13,20 +13,20 @@ struct Anchor { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ AnchorFormat1 format1; AnchorFormat2 format2; AnchorFormat3 format3; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); case 3: return_trace (u.format3.sanitize (c)); @@ -38,7 +38,7 @@ struct Anchor float *x, float *y) const { *x = *y = 0; - switch (u.format) { + switch (u.format.v) { case 1: u.format1.get_anchor (c, glyph_id, x, y); return; case 2: u.format2.get_anchor (c, glyph_id, x, y); return; case 3: u.format3.get_anchor (c, glyph_id, x, y); return; @@ -49,7 +49,7 @@ struct Anchor bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: return_trace (bool (reinterpret_cast (u.format1.copy (c->serializer)))); case 2: if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) @@ -66,7 +66,7 @@ struct Anchor void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - switch (u.format) { + switch (u.format.v) { case 1: case 2: return; case 3: diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorFormat3.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorFormat3.hh index b5422652c..c49705bea 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorFormat3.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorFormat3.hh @@ -37,12 +37,12 @@ struct AnchorFormat3 *x = font->em_fscale_x (xCoordinate); *y = font->em_fscale_y (yCoordinate); - if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->x_ppem || font->has_nonzero_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) { hb_barrier (); *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); } - if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) + if ((font->y_ppem || font->has_nonzero_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) { hb_barrier (); *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); @@ -63,7 +63,7 @@ struct AnchorFormat3 hb_pair_t *new_varidx_delta; if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta)) return_trace (false); - + x_varidx = hb_first (*new_varidx_delta); int delta = hb_second (*new_varidx_delta); if (delta != 0) @@ -91,10 +91,13 @@ struct AnchorFormat3 } } - /* in case that all axes are pinned or no variations after instantiation, - * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ - if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && - y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + + bool no_downgrade = (!xDeviceTable.is_null () && !(this+xDeviceTable).is_variation_device ()) || + x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || + y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX || + (!yDeviceTable.is_null () && !(this+yDeviceTable).is_variation_device ()); + + if (!no_downgrade) return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (xDeviceTable)) return_trace (false); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorMatrix.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorMatrix.hh index 2557e9a72..7e676371f 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorMatrix.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/AnchorMatrix.hh @@ -77,6 +77,13 @@ struct AnchorMatrix return_trace (true); } + + bool offset_is_null (unsigned row, unsigned col, unsigned num_cols) const + { + if (unlikely (row >= rows || col >= num_cols)) return true; + auto &offset = matrixZ[row * num_cols + col]; + return offset.is_null (); + } }; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePos.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePos.hh index 0105a9b85..38a29dd9e 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePos.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePos.hh @@ -11,7 +11,7 @@ struct CursivePos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CursivePosFormat1 format1; } u; @@ -19,9 +19,9 @@ struct CursivePos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePosFormat1.hh index 6b019ac51..4d6d34052 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/CursivePosFormat1.hh @@ -50,8 +50,9 @@ struct EntryExitRecord DEFINE_SIZE_STATIC (4); }; -static void -reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) { +static inline void +reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) +{ int chain = pos[i].attach_chain(), type = pos[i].attach_type(); if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) return; @@ -130,7 +131,7 @@ struct CursivePosFormat1 unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false); hb_barrier (); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_from; if (unlikely (!skippy_iter.prev (&unsafe_from))) @@ -229,8 +230,13 @@ struct CursivePosFormat1 */ reverse_cursive_minor_offset (pos, child, c->direction, parent); - pos[child].attach_type() = ATTACH_TYPE_CURSIVE; pos[child].attach_chain() = (int) parent - (int) child; + if (pos[child].attach_chain() != (int) parent - (int) child) + { + pos[child].attach_chain() = 0; + goto overflow; + } + pos[child].attach_type() = ATTACH_TYPE_CURSIVE; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) pos[child].y_offset = y_offset; @@ -256,6 +262,7 @@ struct CursivePosFormat1 i, j); } + overflow: buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/GPOS.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/GPOS.hh index f4af98b25..762c19eae 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/GPOS.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/GPOS.hh @@ -80,9 +80,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, { /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate * offset of glyph they are attached to. */ - int chain = pos[i].attach_chain(), type = pos[i].attach_type(); - if (likely (!chain)) - return; + int chain = pos[i].attach_chain(); + int type = pos[i].attach_type(); pos[i].attach_chain() = 0; @@ -94,7 +93,8 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, if (unlikely (!nesting_level)) return; - propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); + if (pos[j].attach_chain()) + propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1); assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE)); @@ -110,17 +110,37 @@ propagate_attachment_offsets (hb_glyph_position_t *pos, pos[i].x_offset += pos[j].x_offset; pos[i].y_offset += pos[j].y_offset; - assert (j < i); - if (HB_DIRECTION_IS_FORWARD (direction)) - for (unsigned int k = j; k < i; k++) { - pos[i].x_offset -= pos[k].x_advance; - pos[i].y_offset -= pos[k].y_advance; - } - else - for (unsigned int k = j + 1; k < i + 1; k++) { - pos[i].x_offset += pos[k].x_advance; - pos[i].y_offset += pos[k].y_advance; - } + // i is the position of the mark; j is the base. + if (j < i) + { + /* This is the common case: mark follows base. + * And currently the only way in OpenType. */ + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = j; k < i; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + else + for (unsigned int k = j + 1; k < i + 1; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + } + else // j > i + { + /* This can happen with `kerx`: a mark attaching + * to a base after it in the logical order. */ + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = i; k < j; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + else + for (unsigned int k = i + 1; k < j + 1; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + } } } @@ -149,11 +169,26 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) /* Handle attachments */ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) - for (unsigned i = 0; i < len; i++) - propagate_attachment_offsets (pos, len, i, direction); + { + auto *pos = buffer->pos; + // https://github.com/harfbuzz/harfbuzz/issues/5514 + if (HB_DIRECTION_IS_FORWARD (direction)) + { + for (unsigned i = 0; i < len; i++) + if (pos[i].attach_chain()) + propagate_attachment_offsets (pos, len, i, direction); + } else { + for (unsigned i = len; i-- > 0; ) + if (pos[i].attach_chain()) + propagate_attachment_offsets (pos, len, i, direction); + } + } - if (unlikely (font->slant)) + if (unlikely (font->slant_xy) && + HB_DIRECTION_IS_HORIZONTAL (direction)) { + /* Slanting shaping results is only supported for horizontal text, + * as it gets weird otherwise. */ for (unsigned i = 0; i < len; i++) if (unlikely (pos[i].y_offset)) pos[i].x_offset += roundf (font->slant_xy * pos[i].y_offset); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/LigatureArray.hh index 59cca40aa..fd1312246 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/LigatureArray.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/LigatureArray.hh @@ -19,22 +19,30 @@ struct LigatureArray : List16OfOffset16To bool subset (hb_subset_context_t *c, Iterator coverage, unsigned class_count, - const hb_map_t *klass_mapping) const + const hb_map_t *klass_mapping, + hb_sorted_vector_t &new_coverage /* OUT */) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = c->plan->glyph_map_gsub; auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); bool ret = false; for (const auto _ : + hb_zip (coverage, *this) - | hb_filter (glyphset, hb_first)) + | hb_filter (glyph_map, hb_first)) { + const LigatureAttach& src = (this + _.second); + bool non_empty = + hb_range (src.rows * class_count) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) + | hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); }) + | hb_any; + + if (!non_empty) continue; + auto *matrix = out->serialize_append (c->serializer); if (unlikely (!matrix)) return_trace (false); - const LigatureAttach& src = (this + _.second); auto indexes = + hb_range (src.rows * class_count) | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) @@ -44,6 +52,9 @@ struct LigatureArray : List16OfOffset16To this, src.rows, indexes); + + hb_codepoint_t new_gid = glyph_map.get (_.first); + new_coverage.push (new_gid); } return_trace (ret); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkArray.hh index 0887cc158..403a6a2bd 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkArray.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkArray.hh @@ -47,10 +47,15 @@ struct MarkArray : Array16Of /* Array of MarkRecords--in Cove } hb_glyph_position_t &o = buffer->cur_pos(); + o.attach_chain() = (int) glyph_pos - (int) buffer->idx; + if (o.attach_chain() != (int) glyph_pos - (int) buffer->idx) + { + o.attach_chain() = 0; + goto overflow; + } + o.attach_type() = ATTACH_TYPE_MARK; o.x_offset = roundf (base_x - mark_x); o.y_offset = roundf (base_y - mark_y); - o.attach_type() = ATTACH_TYPE_MARK; - o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) @@ -60,6 +65,7 @@ struct MarkArray : Array16Of /* Array of MarkRecords--in Cove c->buffer->idx, glyph_pos); } + overflow: buffer->idx++; return_trace (true); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePos.hh index cd2fc7ccf..32476663b 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePos.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePos.hh @@ -11,7 +11,7 @@ struct MarkBasePos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkBasePosFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MarkBasePosFormat1_2 format2; @@ -22,9 +22,9 @@ struct MarkBasePos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePosFormat1.hh index 1b8f3c80a..c13dc65d4 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -119,7 +119,7 @@ struct MarkBasePosFormat1_2 /* Now we search backwards for a non-mark glyph. * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (c->last_base_until > buffer->idx) @@ -209,19 +209,22 @@ struct MarkBasePosFormat1_2 ; new_coverage.reset (); - + base_iter - | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) - ; - - if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) - return_trace (false); - hb_sorted_vector_t base_indexes; - for (const unsigned row : + base_iter - | hb_map (hb_second)) + auto &base_array = (this+baseArray); + for (const auto _ : + base_iter) { + unsigned row = _.second; + bool non_empty = + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return !base_array.offset_is_null (row, col, (unsigned) classCount); }) + | hb_any + ; + + if (!non_empty) continue; + + hb_codepoint_t new_g = glyph_map.get ( _.first); + new_coverage.push (new_g); + + hb_range ((unsigned) classCount) | hb_filter (klass_mapping) | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) @@ -229,8 +232,12 @@ struct MarkBasePosFormat1_2 ; } + if (!new_coverage) return_trace (false); + if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + return_trace (out->baseArray.serialize_subset (c, baseArray, this, - base_iter.len (), + new_coverage.length, base_indexes.iter ())); } }; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPos.hh index 739c32541..5c686f576 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPos.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPos.hh @@ -11,7 +11,7 @@ struct MarkLigPos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkLigPosFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MarkLigPosFormat1_2 format2; @@ -22,9 +22,9 @@ struct MarkLigPos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPosFormat1.hh index d6bee277c..57dae77a9 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -101,7 +101,7 @@ struct MarkLigPosFormat1_2 /* Now we search backwards for a non-mark glyph */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (c->last_base_until > buffer->idx) @@ -200,19 +200,13 @@ struct MarkLigPosFormat1_2 &klass_mapping))) return_trace (false); - auto new_ligature_coverage = - + hb_iter (this + ligatureCoverage) - | hb_take ((this + ligatureArray).len) - | hb_map_retains_sorting (glyph_map) - | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; }) - ; - - if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) + hb_sorted_vector_t new_lig_coverage; + if (!out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), + classCount, &klass_mapping, new_lig_coverage)) return_trace (false); - return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, - hb_iter (this+ligatureCoverage), - classCount, &klass_mapping)); + return_trace (out->ligatureCoverage.serialize_serialize (c->serializer, new_lig_coverage.iter ())); } }; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPos.hh index cddd2a3d5..dbd8419ca 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPos.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPos.hh @@ -11,7 +11,7 @@ struct MarkMarkPos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MarkMarkPosFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MarkMarkPosFormat1_2 format2; @@ -22,9 +22,9 @@ struct MarkMarkPos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 57eb782a9..3221704ca 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -100,7 +100,7 @@ struct MarkMarkPosFormat1_2 if (likely (mark1_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; @@ -196,19 +196,23 @@ struct MarkMarkPosFormat1_2 ; new_coverage.reset (); - + mark2_iter - | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) - ; - - if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) - return_trace (false); - hb_sorted_vector_t mark2_indexes; - for (const unsigned row : + mark2_iter - | hb_map (hb_second)) + auto &mark2_array = (this+mark2Array); + for (const auto _ : + mark2_iter) { + unsigned row = _.second; + + bool non_empty = + hb_range ((unsigned) classCount) + | hb_filter (klass_mapping) + | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) + | hb_any + ; + + if (!non_empty) continue; + + hb_codepoint_t new_g = glyph_map.get ( _.first); + new_coverage.push (new_g); + + hb_range ((unsigned) classCount) | hb_filter (klass_mapping) | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) @@ -216,6 +220,10 @@ struct MarkMarkPosFormat1_2 ; } + if (!new_coverage) return_trace (false); + if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) + return_trace (false); + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ())); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPos.hh index c13d4f489..1b3b70090 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPos.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPos.hh @@ -12,7 +12,7 @@ struct PairPos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ PairPosFormat1_3 format1; PairPosFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -25,9 +25,9 @@ struct PairPos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat1.hh index ac2774a76..a8ded1e75 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat1.hh @@ -54,7 +54,7 @@ struct PairPosFormat1_3 { auto &cov = this+coverage; - if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4) + if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len)) { for (hb_codepoint_t g : glyphs->iter()) { @@ -103,14 +103,35 @@ struct PairPosFormat1_3 const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + struct external_cache_t + { + hb_ot_layout_mapping_cache_t coverage; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + } + return cache; + } + + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) @@ -156,7 +177,7 @@ struct PairPosFormat1_3 strip = true; newFormats = compute_effective_value_formats (glyphset, strip, true); } - + out->valueFormat[0] = newFormats.first; out->valueFormat[1] = newFormats.second; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat2.hh index 5ffeb5d0c..e7320b932 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/PairPosFormat2.hh @@ -123,14 +123,39 @@ struct PairPosFormat2_4 : ValueBase const Coverage &get_coverage () const { return this+coverage; } - bool apply (hb_ot_apply_context_t *c) const + struct external_cache_t + { + hb_ot_layout_mapping_cache_t coverage; + hb_ot_layout_mapping_cache_t first; + hb_ot_layout_mapping_cache_t second; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + cache->first.clear (); + cache->second.clear (); + } + return cache; + } + + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_input; skippy_iter.reset_fast (buffer->idx); unsigned unsafe_to; if (unlikely (!skippy_iter.next (&unsafe_to))) @@ -139,8 +164,13 @@ struct PairPosFormat2_4 : ValueBase return_trace (false); } +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint, cache ? &cache->first : nullptr); + unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint, cache ? &cache->second : nullptr); +#else unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); +#endif if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) { buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePos.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePos.hh index a0243a218..30fc1aacd 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePos.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePos.hh @@ -12,7 +12,7 @@ struct SinglePos { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ SinglePosFormat1 format1; SinglePosFormat2 format2; } u; @@ -41,7 +41,7 @@ struct SinglePos const hb_hashmap_t> *layout_variation_idx_delta_map, unsigned newFormat) { - if (unlikely (!c->extend_min (u.format))) return; + if (unlikely (!c->extend_min (u.format.v))) return; unsigned format = 2; ValueFormat new_format; new_format = newFormat; @@ -49,8 +49,8 @@ struct SinglePos if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs); - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: u.format1.serialize (c, src, glyph_val_iter_pairs, @@ -70,9 +70,9 @@ struct SinglePos template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); default:return_trace (c->default_return_value ()); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat1.hh index b2d151d44..4792a4974 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat1.hh @@ -67,7 +67,7 @@ struct SinglePosFormat1 : ValueBase TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) { @@ -100,7 +100,7 @@ struct SinglePosFormat1 : ValueBase if (likely (index == NOT_COVERED)) return false; /* This is ugly... */ - hb_buffer_t buffer; + hb_buffer_t buffer {}; buffer.props.direction = direction; OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat2.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat2.hh index ae4a5ed75..dc92f6a52 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/SinglePosFormat2.hh @@ -66,7 +66,7 @@ struct SinglePosFormat2 : ValueBase TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= valueCount)) return_trace (false); @@ -104,7 +104,7 @@ struct SinglePosFormat2 : ValueBase if (unlikely (index >= valueCount)) return false; /* This is ugly... */ - hb_buffer_t buffer; + hb_buffer_t buffer {}; buffer.props.direction = direction; OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/ValueFormat.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/ValueFormat.hh index 9442cc1cc..924fd7847 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/ValueFormat.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GPOS/ValueFormat.hh @@ -56,9 +56,14 @@ struct ValueFormat : HBUINT16 * PosTable (may be NULL) */ #endif - IntType& operator = (uint16_t i) { v = i; return *this; } - - unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } + NumType& operator = (uint16_t i) { v = i; return *this; } + + // Note: spec says skip 2 bytes per bit in the valueformat. But reports + // from Microsoft developers indicate that only the fields that are + // currently defined are counted. We don't expect any new fields to + // be added to ValueFormat. As such, we use the faster hb_popcount8 + // that only processes the lowest 8 bits. + unsigned int get_len () const { return hb_popcount8 ((uint8_t) *this); } unsigned int get_size () const { return get_len () * Value::static_size; } hb_vector_t get_device_table_indices () const { @@ -111,8 +116,8 @@ struct ValueFormat : HBUINT16 if (!has_device ()) return ret; - bool use_x_device = font->x_ppem || font->num_coords; - bool use_y_device = font->y_ppem || font->num_coords; + bool use_x_device = font->x_ppem || font->has_nonzero_coords; + bool use_y_device = font->y_ppem || font->has_nonzero_coords; if (!use_x_device && !use_y_device) return ret; diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSet.hh index b4466119b..0437cff46 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSet.hh @@ -91,6 +91,19 @@ struct AlternateSet return alternates.len; } + void + collect_alternates (hb_codepoint_t gid, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_enumerate (alternates) + | hb_map ([gid] (hb_pair_t _) { return hb_pair (gid + (_.first << 24), _.second); }) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + template bool serialize (hb_serialize_context_t *c, diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubst.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubst.hh index 04a052a78..08b1dbbee 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubst.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubst.hh @@ -12,7 +12,7 @@ struct AlternateSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ AlternateSubstFormat1_2 format1; #ifndef HB_NO_BEYOND_64K AlternateSubstFormat1_2 format2; @@ -23,9 +23,9 @@ struct AlternateSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -42,10 +42,10 @@ struct AlternateSubst hb_array_t alternate_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned int format = 1; - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list)); default:return_trace (false); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubstFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubstFormat1.hh index adec65d58..294855907 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -69,12 +69,25 @@ struct AlternateSubstFormat1_2 { return (this+alternateSet[(this+coverage).get_coverage (gid)]) .get_alternates (start_offset, alternate_count, alternate_glyphs); } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_iter (alternateSet) + | hb_map (hb_add (this)) + | hb_zip (this+coverage) + | hb_apply ([&] (const hb_pair_t &, hb_codepoint_t> _) { + _.first.collect_alternates (_.second, alternate_count, alternate_glyphs); + }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+alternateSet[index]).apply (c)); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Ligature.hh index e0ec82a23..dfa46b181 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Ligature.hh @@ -44,6 +44,18 @@ struct Ligature c->output->add (ligGlyph); } + template + void collect_second (set_t &s) const + { + if (unlikely (!component.get_length ())) + { + // A ligature without any components. Anything matches. + s = set_t::full (); + return; + } + s.add (component.arrayZ[0]); + } + bool would_apply (hb_would_apply_context_t *c) const { if (c->len != component.lenP1) @@ -91,15 +103,6 @@ struct Ligature unsigned int total_component_count = 0; if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (count > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (count, 1u) * sizeof (unsigned)); - if (unlikely (!match_positions)) - return_trace (false); - } - unsigned int match_end = 0; if (likely (!match_input (c, count, @@ -107,12 +110,9 @@ struct Ligature match_glyph, nullptr, &match_end, - match_positions, &total_component_count))) { c->buffer->unsafe_to_concat (c->buffer->idx, match_end); - if (match_positions != match_positions_stack) - hb_free (match_positions); return_trace (false); } @@ -129,10 +129,10 @@ struct Ligature match_end += delta; for (unsigned i = 0; i < count; i++) { - match_positions[i] += delta; + c->match_positions[i] += delta; if (i) *p++ = ','; - snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]); + snprintf (p, sizeof(buf) - (p - buf), "%u", c->match_positions[i]); p += strlen(p); } @@ -143,7 +143,6 @@ struct Ligature ligate_input (c, count, - match_positions, match_end, ligGlyph, total_component_count); @@ -156,8 +155,6 @@ struct Ligature pos); } - if (match_positions != match_positions_stack) - hb_free (match_positions); return_trace (true); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSet.hh index 08665438c..e39879475 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSet.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSet.hh @@ -11,11 +11,11 @@ namespace GSUB_impl { template struct LigatureSet { - protected: + public: Array16OfOffset16To> ligature; /* Array LigatureSet tables * ordered by preference */ - public: + DEFINE_SIZE_ARRAY (2, ligature); bool sanitize (hb_sanitize_context_t *c) const @@ -62,6 +62,15 @@ struct LigatureSet ; } + template + void collect_seconds (set_t &s) const + { + + hb_iter (ligature) + | hb_map (hb_add (this)) + | hb_apply ([&s] (const Ligature &_) { _.collect_second (s); }) + ; + } + bool would_apply (hb_would_apply_context_t *c) const { return @@ -72,14 +81,14 @@ struct LigatureSet ; } - bool apply (hb_ot_apply_context_t *c) const + bool apply (hb_ot_apply_context_t *c, const hb_set_digest_t *seconds = nullptr) const { TRACE_APPLY (this); unsigned int num_ligs = ligature.len; #ifndef HB_NO_OT_RULESETS_FAST_PATH - if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4) + if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 1) #endif { slow: @@ -91,21 +100,21 @@ struct LigatureSet return_trace (false); } - /* This version is optimized for speed by matching the first component + /* This version is optimized for speed by matching the second component * of the ligature here, instead of calling into the ligation code. * * This is replicated in ChainRuleSet and RuleSet. */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); unsigned unsafe_to; - hb_codepoint_t first = (unsigned) -1; + hb_codepoint_t second = (unsigned) -1; bool matched = skippy_iter.next (&unsafe_to); if (likely (matched)) { - first = c->buffer->info[skippy_iter.idx].codepoint; + second = c->buffer->info[skippy_iter.idx].codepoint; unsafe_to = skippy_iter.idx + 1; if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) @@ -118,13 +127,14 @@ struct LigatureSet else goto slow; + if (seconds && !seconds->may_have (second)) + return_trace (false); bool unsafe_to_concat = false; - for (unsigned int i = 0; i < num_ligs; i++) { const auto &lig = this+ligature.arrayZ[i]; if (unlikely (lig.component.lenP1 <= 1) || - lig.component.arrayZ[0] == first) + lig.component.arrayZ[0] == second) { if (lig.apply (c)) { diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubst.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubst.hh index 18f6e3558..406d91eca 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubst.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubst.hh @@ -12,7 +12,7 @@ struct LigatureSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ LigatureSubstFormat1_2 format1; #ifndef HB_NO_BEYOND_64K LigatureSubstFormat1_2 format2; @@ -23,9 +23,9 @@ struct LigatureSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -45,10 +45,10 @@ struct LigatureSubst hb_array_t component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned int format = 1; - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubstFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubstFormat1.hh index 5c7df97d1..909ddca22 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -78,15 +78,44 @@ struct LigatureSubstFormat1_2 return lig_set.would_apply (c); } - bool apply (hb_ot_apply_context_t *c) const + struct external_cache_t { - TRACE_APPLY (this); + hb_ot_layout_mapping_cache_t coverage; + hb_set_digest_t seconds; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) + { + cache->coverage.clear (); + + cache->seconds.init (); + + hb_iter (ligatureSet) + | hb_map (hb_add (this)) + | hb_apply ([cache] (const LigatureSet &_) { _.collect_seconds (cache->seconds); }) + ; + } + return cache; + } - unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + bool apply (hb_ot_apply_context_t *c, void *external_cache) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + const hb_set_digest_t *seconds = cache ? &cache->seconds : nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else + const hb_set_digest_t *seconds = nullptr; + unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); +#endif + if (index == NOT_COVERED) return_trace (false); const auto &lig_set = this+ligatureSet[index]; - return_trace (lig_set.apply (c)); + return_trace (lig_set.apply (c, seconds)); } bool serialize (hb_serialize_context_t *c, diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubst.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubst.hh index 742c8587e..2ff59ad97 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubst.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubst.hh @@ -12,7 +12,7 @@ struct MultipleSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ MultipleSubstFormat1_2 format1; #ifndef HB_NO_BEYOND_64K MultipleSubstFormat1_2 format2; @@ -24,9 +24,9 @@ struct MultipleSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); @@ -41,10 +41,10 @@ struct MultipleSubst Iterator it) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned int format = 1; - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, it)); default:return_trace (false); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubstFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubstFormat1.hh index 3b4bd1169..441d4dee0 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubstFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/MultipleSubstFormat1.hh @@ -66,7 +66,7 @@ struct MultipleSubstFormat1_2 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); return_trace ((this+sequence[index]).apply (c)); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubst.hh index 5ad463fea..e33148d77 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubst.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubst.hh @@ -12,7 +12,7 @@ struct ReverseChainSingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ReverseChainSingleSubstFormat1 format1; } u; @@ -20,9 +20,9 @@ struct ReverseChainSingleSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index ec374f2f0..1f598cc40 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -112,7 +112,7 @@ struct ReverseChainSingleSubstFormat1 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) return_trace (false); /* No chaining to this type */ diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Sequence.hh index a26cf8c6a..8edb0053b 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/Sequence.hh @@ -115,7 +115,7 @@ struct Sequence for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) { - if (buf < p) + if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) *p++ = ','; snprintf (p, sizeof(buf) - (p - buf), "%u", i); p += strlen(p); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubst.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubst.hh index 181c9e52e..7ffe3a68b 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubst.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubst.hh @@ -13,7 +13,7 @@ struct SingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ SingleSubstFormat1_3 format1; SingleSubstFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -27,9 +27,9 @@ struct SingleSubst template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...)); #ifndef HB_NO_BEYOND_64K @@ -47,7 +47,7 @@ struct SingleSubst Iterator glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return_trace (false); + if (unlikely (!c->extend_min (u.format.v))) return_trace (false); unsigned format = 2; unsigned delta = 0; if (glyphs) @@ -71,8 +71,8 @@ struct SingleSubst if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; } - u.format = format; - switch (u.format) { + u.format.v = format; + switch (u.format.v) { case 1: return_trace (u.format1.serialize (c, + glyphs | hb_map_retains_sorting (hb_first), diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat1.hh index 850be86c0..1cd3f9d9c 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -123,12 +123,27 @@ struct SingleSubstFormat1_3 return 1; } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + + hb_iter (this+coverage) + | hb_map ([d, mask] (hb_codepoint_t g) { return hb_pair (g, (g + d) & mask); }) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); hb_codepoint_t d = deltaGlyphID; hb_codepoint_t mask = get_mask (); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat2.hh index 9c651abe7..4c98f05ae 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -100,11 +100,22 @@ struct SingleSubstFormat2_4 return 1; } + void + collect_glyph_alternates (hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) const + { + + hb_zip (this+coverage, substitute) + | hb_apply ([&] (const hb_pair_t &p) -> void + { _hb_collect_glyph_alternates_add (p.first, p.second, + alternate_count, alternate_glyphs); }) + ; + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); if (unlikely (index >= substitute.len)) return_trace (false); diff --git a/thirdparty/harfbuzz/upstream/OT/Layout/types.hh b/thirdparty/harfbuzz/upstream/OT/Layout/types.hh index 3840db059..5cf9eb368 100644 --- a/thirdparty/harfbuzz/upstream/OT/Layout/types.hh +++ b/thirdparty/harfbuzz/upstream/OT/Layout/types.hh @@ -29,6 +29,12 @@ #ifndef OT_LAYOUT_TYPES_HH #define OT_LAYOUT_TYPES_HH +using hb_ot_layout_mapping_cache_t = hb_cache_t<16, 8, 8>; +static_assert (sizeof (hb_ot_layout_mapping_cache_t) == 512, ""); + +using hb_ot_layout_binary_cache_t = hb_cache_t<14, 1, 8>; +static_assert (sizeof (hb_ot_layout_binary_cache_t) == 256, ""); + namespace OT { namespace Layout { diff --git a/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.cc b/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.cc index 1afb57111..7524686d3 100644 --- a/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.cc +++ b/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.cc @@ -3,7 +3,6 @@ #ifndef HB_NO_VAR_COMPOSITES #include "../../../hb-draw.hh" -#include "../../../hb-geometry.hh" #include "../../../hb-ot-layout-common.hh" #include "../../../hb-ot-layout-gdef-table.hh" @@ -12,9 +11,11 @@ namespace OT { //namespace Var { +#ifndef HB_NO_DRAW + struct hb_transforming_pen_context_t { - hb_transform_t transform; + hb_transform_t<> transform; hb_draw_funcs_t *dfuncs; void *data; hb_draw_state_t *st; @@ -127,24 +128,19 @@ hb_transforming_pen_get_funcs () return static_transforming_pen_funcs.get_unconst (); } - hb_ubytes_t -VarComponent::get_path_at (hb_font_t *font, +VarComponent::get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, - hb_draw_session_t &draw_session, hb_array_t coords, + hb_transform_t<> total_transform, hb_ubytes_t total_record, - hb_set_t *visited, - signed *edges_left, - signed depth_left, - VarRegionList::cache_t *cache) const + hb_scalar_cache_t *cache) const { const unsigned char *end = total_record.arrayZ + total_record.length; const unsigned char *record = total_record.arrayZ; - auto &VARC = *font->face->table.VARC; + auto &VARC = *c.font->face->table.VARC->table; auto &varStore = &VARC+VARC.varStore; - auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache); #define READ_UINT32VAR(name) \ HB_STMT_START { \ @@ -187,22 +183,25 @@ VarComponent::get_path_at (hb_font_t *font, unsigned conditionIndex; READ_UINT32VAR (conditionIndex); const auto &condition = (&VARC+VARC.conditionList)[conditionIndex]; + auto instancer = MultiItemVarStoreInstancer(&varStore, nullptr, coords, cache); show = condition.evaluate (coords.arrayZ, coords.length, &instancer); } // Axis values - hb_vector_t axisIndices; - hb_vector_t axisValues; + auto &axisIndices = c.scratch.axisIndices; + axisIndices.clear (); + auto &axisValues = c.scratch.axisValues; + axisValues.clear (); if (flags & (unsigned) flags_t::HAVE_AXES) { unsigned axisIndicesIndex; READ_UINT32VAR (axisIndicesIndex); - axisIndices = (&VARC+VARC.axisIndicesList)[axisIndicesIndex]; + axisIndices.extend ((&VARC+VARC.axisIndicesList)[axisIndicesIndex]); axisValues.resize (axisIndices.length); const HBUINT8 *p = (const HBUINT8 *) record; TupleValues::decompile (p, axisValues, (const HBUINT8 *) end); - record += (const unsigned char *) p - record; + record = (const unsigned char *) p; } // Apply variations if any @@ -219,7 +218,7 @@ VarComponent::get_path_at (hb_font_t *font, * limit on the max number of coords for now. */ if ((flags & (unsigned) flags_t::RESET_UNSPECIFIED_AXES) || coords.length > HB_VAR_COMPOSITE_MAX_AXES) - component_coords = hb_array (font->coords, font->num_coords); + component_coords = hb_array (c.font->coords, c.font->num_coords); // Transform @@ -229,21 +228,21 @@ VarComponent::get_path_at (hb_font_t *font, #define PROCESS_TRANSFORM_COMPONENTS \ HB_STMT_START { \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TRANSLATE_X, translateX); \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TRANSLATE_Y, translateY); \ - PROCESS_TRANSFORM_COMPONENT (F4DOT12, HAVE_ROTATION, rotation); \ - PROCESS_TRANSFORM_COMPONENT (F6DOT10, HAVE_SCALE_X, scaleX); \ - PROCESS_TRANSFORM_COMPONENT (F6DOT10, HAVE_SCALE_Y, scaleY); \ - PROCESS_TRANSFORM_COMPONENT (F4DOT12, HAVE_SKEW_X, skewX); \ - PROCESS_TRANSFORM_COMPONENT (F4DOT12, HAVE_SKEW_Y, skewY); \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TCENTER_X, tCenterX); \ - PROCESS_TRANSFORM_COMPONENT (FWORD, HAVE_TCENTER_Y, tCenterY); \ + PROCESS_TRANSFORM_COMPONENT ( 0, FWORD, HAVE_TRANSLATE_X, translateX); \ + PROCESS_TRANSFORM_COMPONENT ( 0, FWORD, HAVE_TRANSLATE_Y, translateY); \ + PROCESS_TRANSFORM_COMPONENT (12, F4DOT12, HAVE_ROTATION, rotation); \ + PROCESS_TRANSFORM_COMPONENT (10, F6DOT10, HAVE_SCALE_X, scaleX); \ + PROCESS_TRANSFORM_COMPONENT (10, F6DOT10, HAVE_SCALE_Y, scaleY); \ + PROCESS_TRANSFORM_COMPONENT (12, F4DOT12, HAVE_SKEW_X, skewX); \ + PROCESS_TRANSFORM_COMPONENT (12, F4DOT12, HAVE_SKEW_Y, skewY); \ + PROCESS_TRANSFORM_COMPONENT ( 0, FWORD, HAVE_TCENTER_X, tCenterX); \ + PROCESS_TRANSFORM_COMPONENT ( 0, FWORD, HAVE_TCENTER_Y, tCenterY); \ } HB_STMT_END - hb_transform_decomposed_t transform; + hb_transform_decomposed_t<> transform; // Read transform components -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(shift, type, flag, name) \ if (flags & (unsigned) flags_t::flag) \ { \ static_assert (type::static_size == HBINT16::static_size, ""); \ @@ -271,9 +270,8 @@ VarComponent::get_path_at (hb_font_t *font, { // Only use coord_setter if there's actually any axis overrides. coord_setter_t coord_setter (axisIndices ? component_coords : hb_array ()); - // Go backwards, to reduce coord_setter vector reallocations. - for (unsigned i = axisIndices.length; i; i--) - coord_setter[axisIndices[i - 1]] = axisValues[i - 1]; + for (unsigned i = 0; i < axisIndices.length; i++) + coord_setter[axisIndices[i]] = roundf (axisValues[i]); if (axisIndices) component_coords = coord_setter.get_coords (); @@ -282,14 +280,14 @@ VarComponent::get_path_at (hb_font_t *font, { float transformValues[9]; unsigned numTransformValues = 0; -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(shift, type, flag, name) \ if (flags & (unsigned) flags_t::flag) \ transformValues[numTransformValues++] = transform.name; PROCESS_TRANSFORM_COMPONENTS; #undef PROCESS_TRANSFORM_COMPONENT varStore.get_delta (transformVarIdx, coords, hb_array (transformValues, numTransformValues), cache); numTransformValues = 0; -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ +#define PROCESS_TRANSFORM_COMPONENT(shift, type, flag, name) \ if (flags & (unsigned) flags_t::flag) \ transform.name = transformValues[numTransformValues++]; PROCESS_TRANSFORM_COMPONENTS; @@ -297,41 +295,30 @@ VarComponent::get_path_at (hb_font_t *font, } // Divide them by their divisors -#define PROCESS_TRANSFORM_COMPONENT(type, flag, name) \ - if (flags & (unsigned) flags_t::flag) \ - { \ - HBINT16 int_v; \ - int_v = roundf (transform.name); \ - type typed_v = * (const type *) &int_v; \ - float float_v = (float) typed_v; \ - transform.name = float_v; \ - } +#define PROCESS_TRANSFORM_COMPONENT(shift, type, flag, name) \ + if (shift && (flags & (unsigned) flags_t::flag)) \ + transform.name *= 1.f / (1 << shift); PROCESS_TRANSFORM_COMPONENTS; #undef PROCESS_TRANSFORM_COMPONENT if (!(flags & (unsigned) flags_t::HAVE_SCALE_Y)) transform.scaleY = transform.scaleX; - // Scale the transform by the font's scale - float x_scale = font->x_multf; - float y_scale = font->y_multf; - transform.translateX *= x_scale; - transform.translateY *= y_scale; - transform.tCenterX *= x_scale; - transform.tCenterY *= y_scale; - - // Build a transforming pen to apply the transform. - hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); - hb_transforming_pen_context_t context {transform.to_transform (), - draw_session.funcs, - draw_session.draw_data, - &draw_session.st}; - hb_draw_session_t transformer_session {transformer_funcs, &context}; - - VARC.get_path_at (font, gid, - transformer_session, component_coords, + transform.rotation *= HB_PI; + transform.skewX *= HB_PI; + transform.skewY *= HB_PI; + + total_transform.transform (transform.to_transform ()); + + bool same_coords = component_coords.length == coords.length && + component_coords.arrayZ == coords.arrayZ; + + c.depth_left--; + VARC.get_path_at (c, gid, + component_coords, total_transform, parent_gid, - visited, edges_left, depth_left - 1); + same_coords ? cache : nullptr); + c.depth_left++; } #undef PROCESS_TRANSFORM_COMPONENTS @@ -340,6 +327,94 @@ VarComponent::get_path_at (hb_font_t *font, return hb_ubytes_t (record, end - record); } +bool +VARC::get_path_at (const hb_varc_context_t &c, + hb_codepoint_t glyph, + hb_array_t coords, + hb_transform_t<> transform, + hb_codepoint_t parent_glyph, + hb_scalar_cache_t *parent_cache) const +{ + // Don't recurse on the same glyph. + unsigned idx = glyph == parent_glyph ? + NOT_COVERED : + (this+coverage).get_coverage (glyph); + if (idx == NOT_COVERED) + { + if (c.draw_session) + { + hb_transform_t<> leaf_transform = transform; + leaf_transform.x0 *= c.font->x_multf; + leaf_transform.y0 *= c.font->y_multf; + + // Build a transforming pen to apply the transform. + hb_draw_funcs_t *transformer_funcs = hb_transforming_pen_get_funcs (); + hb_transforming_pen_context_t context {leaf_transform, + c.draw_session->funcs, + c.draw_session->draw_data, + &c.draw_session->st}; + hb_draw_session_t transformer_session {transformer_funcs, &context}; + hb_draw_session_t &shape_draw_session = leaf_transform.is_identity () ? *c.draw_session : transformer_session; + + if (c.font->face->table.glyf->get_path_at (c.font, glyph, shape_draw_session, coords, c.scratch.glyf_scratch)) return true; +#ifndef HB_NO_CFF + if (c.font->face->table.cff2->get_path_at (c.font, glyph, shape_draw_session, coords)) return true; + if (c.font->face->table.cff1->get_path (c.font, glyph, shape_draw_session)) return true; // Doesn't have variations +#endif + return false; + } + else if (c.extents) + { + hb_glyph_extents_t glyph_extents; + if (!c.font->face->table.glyf->get_extents_at (c.font, glyph, &glyph_extents, coords)) +#ifndef HB_NO_CFF + if (!c.font->face->table.cff2->get_extents_at (c.font, glyph, &glyph_extents, coords)) + if (!c.font->face->table.cff1->get_extents (c.font, glyph, &glyph_extents)) // Doesn't have variations +#endif + return false; + + hb_extents_t<> comp_extents (glyph_extents); + hb_transform_t<> leaf_transform = transform; + leaf_transform.x0 *= c.font->x_multf; + leaf_transform.y0 *= c.font->y_multf; + leaf_transform.transform_extents (comp_extents); + c.extents->union_ (comp_extents); + } + return true; + } + + if (c.depth_left <= 0) + return true; + + if (c.edges_left <= 0) + return true; + (c.edges_left)--; + + hb_decycler_node_t node (c.decycler); + if (unlikely (!node.visit (glyph))) + return true; + + hb_ubytes_t record = (this+glyphRecords)[idx]; + + hb_scalar_cache_t static_cache; + hb_scalar_cache_t *cache = parent_cache ? + parent_cache : + (this+varStore).create_cache (&static_cache); + + VarCompositeGlyph::get_path_at (c, + glyph, + coords, transform, + record, + cache); + + if (cache != parent_cache) + (this+varStore).destroy_cache (cache, &static_cache); + + return true; +} + +#endif + //} // namespace Var } // namespace OT diff --git a/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.hh b/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.hh index d60f7b0c2..719302c93 100644 --- a/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.hh +++ b/thirdparty/harfbuzz/upstream/OT/Var/VARC/VARC.hh @@ -1,6 +1,8 @@ #ifndef OT_VAR_VARC_VARC_HH #define OT_VAR_VARC_VARC_HH +#include "../../../hb-decycler.hh" +#include "../../../hb-geometry.hh" #include "../../../hb-ot-layout-common.hh" #include "../../../hb-ot-glyf-table.hh" #include "../../../hb-ot-cff2-table.hh" @@ -19,6 +21,24 @@ namespace OT { #ifndef HB_NO_VAR_COMPOSITES +struct hb_varc_scratch_t +{ + hb_vector_t axisIndices; + hb_vector_t axisValues; + hb_glyf_scratch_t glyf_scratch; +}; + +struct hb_varc_context_t +{ + hb_font_t *font; + hb_draw_session_t *draw_session; + hb_extents_t<> *extents; + mutable hb_decycler_t decycler; + mutable signed edges_left; + mutable signed depth_left; + hb_varc_scratch_t &scratch; +}; + struct VarComponent { enum class flags_t : uint32_t @@ -42,37 +62,32 @@ struct VarComponent }; HB_INTERNAL hb_ubytes_t - get_path_at (hb_font_t *font, + get_path_at (const hb_varc_context_t &c, hb_codepoint_t parent_gid, - hb_draw_session_t &draw_session, hb_array_t coords, + hb_transform_t<> transform, hb_ubytes_t record, - hb_set_t *visited, - signed *edges_left, - signed depth_left, - VarRegionList::cache_t *cache = nullptr) const; + hb_scalar_cache_t *cache = nullptr) const; }; struct VarCompositeGlyph { static void - get_path_at (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_session_t &draw_session, + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, hb_array_t coords, + hb_transform_t<> transform, hb_ubytes_t record, - hb_set_t *visited, - signed *edges_left, - signed depth_left, - VarRegionList::cache_t *cache = nullptr) + hb_scalar_cache_t *cache) { while (record) { const VarComponent &comp = * (const VarComponent *) (record.arrayZ); - record = comp.get_path_at (font, glyph, - draw_session, coords, + record = comp.get_path_at (c, + gid, + coords, transform, record, - visited, edges_left, depth_left, cache); + cache); } } }; @@ -85,79 +100,48 @@ struct VARC static constexpr hb_tag_t tableTag = HB_TAG ('V', 'A', 'R', 'C'); - bool - get_path_at (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_session_t &draw_session, + HB_INTERNAL bool + get_path_at (const hb_varc_context_t &c, + hb_codepoint_t gid, hb_array_t coords, - hb_codepoint_t parent_glyph = HB_CODEPOINT_INVALID, - hb_set_t *visited = nullptr, - signed *edges_left = nullptr, - signed depth_left = HB_MAX_NESTING_LEVEL) const - { - hb_set_t stack_set; - if (visited == nullptr) - visited = &stack_set; - signed stack_edges = HB_MAX_GRAPH_EDGE_COUNT; - if (edges_left == nullptr) - edges_left = &stack_edges; - - // Don't recurse on the same glyph. - unsigned idx = glyph == parent_glyph ? - NOT_COVERED : - (this+coverage).get_coverage (glyph); - if (idx == NOT_COVERED) - { - if (!font->face->table.glyf->get_path_at (font, glyph, draw_session, coords)) -#ifndef HB_NO_CFF - if (!font->face->table.cff2->get_path_at (font, glyph, draw_session, coords)) - if (!font->face->table.cff1->get_path (font, glyph, draw_session)) // Doesn't have variations -#endif - return false; - return true; - } - - if (depth_left <= 0) - return true; - - if (*edges_left <= 0) - return true; - (*edges_left)--; - - if (visited->has (glyph) || visited->in_error ()) - return true; - visited->add (glyph); + hb_transform_t<> transform = HB_TRANSFORM_IDENTITY, + hb_codepoint_t parent_gid = HB_CODEPOINT_INVALID, + hb_scalar_cache_t *parent_cache = nullptr) const; - hb_ubytes_t record = (this+glyphRecords)[idx]; - - VarRegionList::cache_t *cache = record.length >= 64 ? // Heuristic - (this+varStore).create_cache () - : nullptr; - - VarCompositeGlyph::get_path_at (font, glyph, - draw_session, coords, - record, - visited, edges_left, depth_left, - cache); - - (this+varStore).destroy_cache (cache); - - visited->del (glyph); - - return true; + bool + get_path (hb_font_t *font, + hb_codepoint_t gid, + hb_draw_session_t &draw_session, + hb_varc_scratch_t &scratch) const + { + hb_varc_context_t c {font, + &draw_session, + nullptr, + hb_decycler_t {}, + HB_MAX_GRAPH_EDGE_COUNT, + HB_MAX_NESTING_LEVEL, + scratch}; + + return get_path_at (c, gid, + hb_array (font->coords, font->num_coords)); } bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_path_at (font, gid, draw_session, hb_array (font->coords, font->num_coords)); } - - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const + get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_extents_t<> *extents, + hb_varc_scratch_t &scratch) const { - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; + hb_varc_context_t c {font, + nullptr, + extents, + hb_decycler_t {}, + HB_MAX_GRAPH_EDGE_COUNT, + HB_MAX_NESTING_LEVEL, + scratch}; + + return get_path_at (c, gid, + hb_array (font->coords, font->num_coords)); } bool sanitize (hb_sanitize_context_t *c) const @@ -173,6 +157,93 @@ struct VARC glyphRecords.sanitize (c, this)); } + struct accelerator_t + { + friend struct VarComponent; + + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table (face); + } + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_varc_scratch_t (); + hb_free (scratch); + } + + table.destroy (); + } + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + { + if (!table->has_data ()) return false; + + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = table->get_path (font, gid, draw_session, *scratch); + release_scratch (scratch); + return ret; + } + + bool + get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { +#ifndef HB_NO_DRAW + if (!table->has_data ()) return false; + + hb_extents_t<> f_extents; + + auto *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + bool ret = table->get_extents (font, gid, &f_extents, *scratch); + release_scratch (scratch); + + if (ret) + *extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0); + + return ret; +#else + return false; +#endif + } + + private: + + hb_varc_scratch_t *acquire_scratch () const + { + hb_varc_scratch_t *scratch = cached_scratch.get_acquire (); + + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_varc_scratch_t *) hb_calloc (1, sizeof (hb_varc_scratch_t)); + if (unlikely (!scratch)) + return nullptr; + } + + return scratch; + } + void release_scratch (hb_varc_scratch_t *scratch) const + { + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_varc_scratch_t (); + hb_free (scratch); + } + } + + private: + hb_blob_ptr_t table; + mutable hb_atomic_t cached_scratch; + }; + + bool has_data () const { return version.major != 0; } + protected: FixedVersion<> version; /* Version identifier */ Offset32To coverage; @@ -184,6 +255,10 @@ struct VARC DEFINE_SIZE_STATIC (24); }; +struct VARC_accelerator_t : VARC::accelerator_t { + VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {} +}; + #endif //} diff --git a/thirdparty/harfbuzz/upstream/OT/Var/VARC/coord-setter.hh b/thirdparty/harfbuzz/upstream/OT/Var/VARC/coord-setter.hh index a2b483ce2..0df524ed2 100644 --- a/thirdparty/harfbuzz/upstream/OT/Var/VARC/coord-setter.hh +++ b/thirdparty/harfbuzz/upstream/OT/Var/VARC/coord-setter.hh @@ -11,22 +11,48 @@ namespace OT { struct coord_setter_t { - coord_setter_t (hb_array_t coords) : - coords (coords) {} + coord_setter_t (hb_array_t coords_) + { + length = coords_.length; + if (length <= ARRAY_LENGTH (static_coords)) + hb_memcpy (static_coords, coords_.arrayZ, length * sizeof (int)); + else + dynamic_coords.extend (coords_); + } int& operator [] (unsigned idx) { if (unlikely (idx >= HB_VAR_COMPOSITE_MAX_AXES)) return Crap(int); - if (coords.length < idx + 1) - coords.resize (idx + 1); - return coords[idx]; + + if (length <= ARRAY_LENGTH (static_coords)) + { + if (idx < ARRAY_LENGTH (static_coords)) + { + while (length <= idx) + static_coords[length++] = 0; + return static_coords[idx]; + } + else + dynamic_coords.extend (hb_array (static_coords, length)); + } + + if (dynamic_coords.length <= idx) + { + if (unlikely (!dynamic_coords.resize (idx + 1))) + return Crap(int); + length = idx + 1; + } + return dynamic_coords.arrayZ[idx]; } hb_array_t get_coords () - { return coords.as_array (); } + { return length <= ARRAY_LENGTH (static_coords) ? hb_array (static_coords, length) : dynamic_coords.as_array (); } - hb_vector_t coords; + private: + hb_vector_t dynamic_coords; + unsigned length; + int static_coords[sizeof (void *) * 8]; }; diff --git a/thirdparty/harfbuzz/upstream/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/upstream/OT/glyf/CompositeGlyph.hh index 5c0ecd513..e2ec4a80e 100644 --- a/thirdparty/harfbuzz/upstream/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/upstream/OT/glyf/CompositeGlyph.hh @@ -143,7 +143,7 @@ struct CompositeGlyphRecord float matrix[4]; contour_point_t trans; get_transformation (matrix, trans); - if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points + if (unlikely (!points.alloc (points.length + 1 + 4))) return false; // For phantom points points.push (trans); return true; } diff --git a/thirdparty/harfbuzz/upstream/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/upstream/OT/glyf/Glyph.hh index 7772597e5..83d3eaed0 100644 --- a/thirdparty/harfbuzz/upstream/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/upstream/OT/glyf/Glyph.hh @@ -102,17 +102,15 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { + // Duplicated code. int lsb = 0; - int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? - (int) header->xMin - lsb : 0; + face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + int h_delta = (int) header->xMin - lsb; HB_UNUSED int tsb = 0; - int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) -#else - 0 + face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); #endif - ; + int v_orig = (int) header->yMax + tsb; unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL @@ -251,7 +249,8 @@ struct Glyph composite_contours_p = nullptr; } - if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) + hb_glyf_scratch_t scratch; + if (!get_points (font, glyf, all_points, scratch, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false)) return false; // .notdef, set type to empty so we only update metrics and don't compile bytes for @@ -305,6 +304,7 @@ struct Glyph template bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, + hb_glyf_scratch_t &scratch, contour_point_vector_t *points_with_deltas = nullptr, /* OUT */ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ unsigned *composite_contours = nullptr, /* OUT */ @@ -312,7 +312,7 @@ struct Glyph bool use_my_metrics = true, bool phantom_only = false, hb_array_t coords = hb_array_t (), - hb_map_t *current_glyphs = nullptr, + hb_scalar_cache_t *gvar_cache = nullptr, unsigned int depth = 0, unsigned *edge_count = nullptr) const { @@ -322,20 +322,15 @@ struct Glyph if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false; (*edge_count)++; - hb_map_t current_glyphs_stack; - if (current_glyphs == nullptr) - current_glyphs = ¤t_glyphs_stack; - if (head_maxp_info) { head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); } - if (!coords) + if (!coords && font->has_nonzero_coords) coords = hb_array (font->coords, font->num_coords); - contour_point_vector_t stack_points; - contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points; + contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points; unsigned old_length = points.length; switch (type) { @@ -361,25 +356,23 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { + // Duplicated code. int lsb = 0; - int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? - (int) header->xMin - lsb : 0; + glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + int h_delta = (int) header->xMin - lsb; HB_UNUSED int tsb = 0; - int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) -#else - 0 + glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb); #endif - ; + int v_orig = (int) header->yMax + tsb; unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) + glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) #else - - font->face->get_upem () + - font->face->get_upem () #endif - ; + ; phantoms[PHANTOM_LEFT].x = h_delta; phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta; phantoms[PHANTOM_TOP].y = v_orig; @@ -387,37 +380,60 @@ struct Glyph } #ifndef HB_NO_VAR - if (coords) - glyf_accelerator.gvar->apply_deltas_to_points (gid, - coords, - points.as_array ().sub_array (old_length), - phantom_only && type == SIMPLE); + if (hb_any (coords)) + { +#ifndef HB_NO_BEYOND_64K + if (glyf_accelerator.GVAR->has_data ()) + { + if (!glyf_accelerator.GVAR->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + gvar_cache, + phantom_only && type == SIMPLE)) + return false; + } + else +#endif + if (!glyf_accelerator.gvar->apply_deltas_to_points (gid, + coords, + points.as_array ().sub_array (old_length), + scratch, + gvar_cache, + phantom_only && type == SIMPLE)) + return false; + } #endif // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it // with child glyphs' points if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE) { - if (unlikely (!points_with_deltas->resize (points.length))) return false; + assert (old_length == 0); *points_with_deltas = points; } + float shift = 0; switch (type) { case SIMPLE: if (depth == 0 && head_maxp_info) head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4); + shift = phantoms[PHANTOM_LEFT].x; break; case COMPOSITE: { + hb_decycler_node_t decycler_node (scratch.decycler); + unsigned int comp_index = 0; for (auto &item : get_composite_iterator ()) { hb_codepoint_t item_gid = item.get_gid (); - if (unlikely (current_glyphs->has (item_gid))) + if (unlikely (!decycler_node.visit (item_gid))) + { + comp_index++; continue; - - current_glyphs->add (item_gid); + } unsigned old_count = all_points.length; @@ -426,6 +442,7 @@ struct Glyph .get_points (font, glyf_accelerator, all_points, + scratch, points_with_deltas, head_maxp_info, composite_contours, @@ -433,14 +450,17 @@ struct Glyph use_my_metrics, phantom_only, coords, - current_glyphs, + gvar_cache, depth + 1, edge_count))) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } + // points might have been reallocated. Relocate phantoms. + phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + auto comp_points = all_points.as_array ().sub_array (old_count); /* Copy phantom points from component if USE_MY_METRICS flag set */ @@ -455,7 +475,7 @@ struct Glyph item.get_transformation (matrix, default_trans); /* Apply component transformation & translation (with deltas applied) */ - item.transform_points (comp_points, matrix, points[comp_index]); + item.transform_points (comp_points, matrix, points[old_length + comp_index]); } if (item.is_anchored () && !phantom_only) @@ -476,12 +496,11 @@ struct Glyph if (all_points.length > HB_GLYF_MAX_POINTS) { - current_glyphs->del (item_gid); + points.resize (old_length); return false; } comp_index++; - current_glyphs->del (item_gid); } if (head_maxp_info && depth == 0) @@ -492,9 +511,13 @@ struct Glyph head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index); } all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); } break; case EMPTY: all_points.extend (phantoms); + shift = phantoms[PHANTOM_LEFT].x; + points.resize (old_length); break; } @@ -503,10 +526,9 @@ struct Glyph /* Undocumented rasterizer behavior: * Shift points horizontally by the updated left side bearing */ - float v = -phantoms[PHANTOM_LEFT].x; - if (v) + if (shift) for (auto &point : all_points) - point.x += v; + point.x -= shift; } return !all_points.in_error (); @@ -515,7 +537,11 @@ struct Glyph bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, hb_glyph_extents_t *extents) const { - if (type == EMPTY) return true; /* Empty glyph; zero extents. */ + if (type == EMPTY) + { + *extents = {0, 0, 0, 0}; + return true; /* Empty glyph; zero extents. */ + } return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); } diff --git a/thirdparty/harfbuzz/upstream/OT/glyf/SimpleGlyph.hh b/thirdparty/harfbuzz/upstream/OT/glyf/SimpleGlyph.hh index 1d42cc292..9f4a2bac5 100644 --- a/thirdparty/harfbuzz/upstream/OT/glyf/SimpleGlyph.hh +++ b/thirdparty/harfbuzz/upstream/OT/glyf/SimpleGlyph.hh @@ -127,19 +127,20 @@ struct SimpleGlyph hb_array_t points_ /* IN/OUT */, const HBUINT8 *end) { + auto *points = points_.arrayZ; unsigned count = points_.length; for (unsigned int i = 0; i < count;) { if (unlikely (p + 1 > end)) return false; uint8_t flag = *p++; - points_.arrayZ[i++].flag = flag; + points[i++].flag = flag; if (flag & FLAG_REPEAT) { if (unlikely (p + 1 > end)) return false; unsigned int repeat_count = *p++; unsigned stop = hb_min (i + repeat_count, count); for (; i < stop; i++) - points_.arrayZ[i].flag = flag; + points[i].flag = flag; } } return true; @@ -160,10 +161,7 @@ struct SimpleGlyph if (flag & short_flag) { if (unlikely (p + 1 > end)) return false; - if (flag & same_flag) - v += *p++; - else - v -= *p++; + v += (bool(flag & same_flag) * 2 - 1) * *p++; } else { @@ -190,8 +188,8 @@ struct SimpleGlyph unsigned int num_points = endPtsOfContours[num_contours - 1] + 1; unsigned old_length = points.length; - points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy - if (unlikely (!points.resize (points.length + num_points, false))) return false; + points.alloc (points.length + num_points + 4); // Allocate for phantom points, to avoid a possible copy + if (unlikely (!points.resize_dirty (points.length + num_points))) return false; auto points_ = points.as_array ().sub_array (old_length); if (!phantom_only) hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points); @@ -281,9 +279,9 @@ struct SimpleGlyph unsigned num_points = all_points.length - 4; hb_vector_t flags, x_coords, y_coords; - if (unlikely (!flags.alloc (num_points, true))) return false; - if (unlikely (!x_coords.alloc (2*num_points, true))) return false; - if (unlikely (!y_coords.alloc (2*num_points, true))) return false; + if (unlikely (!flags.alloc_exact (num_points))) return false; + if (unlikely (!x_coords.alloc_exact (2*num_points))) return false; + if (unlikely (!y_coords.alloc_exact (2*num_points))) return false; unsigned lastflag = 255, repeat = 0; int prev_x = 0, prev_y = 0; diff --git a/thirdparty/harfbuzz/upstream/OT/glyf/glyf.hh b/thirdparty/harfbuzz/upstream/OT/glyf/glyf.hh index f346ae05d..71989d8df 100644 --- a/thirdparty/harfbuzz/upstream/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/upstream/OT/glyf/glyf.hh @@ -94,7 +94,7 @@ struct glyf } hb_vector_t padded_offsets; - if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true))) + if (unlikely (!padded_offsets.alloc_exact (c->plan->new_to_old_gid_list.length))) return_trace (false); hb_vector_t glyphs; @@ -172,6 +172,9 @@ struct glyf_accelerator_t glyf_table = nullptr; #ifndef HB_NO_VAR gvar = nullptr; +#ifndef HB_NO_BEYOND_64K + GVAR = nullptr; +#endif #endif hmtx = nullptr; #ifndef HB_NO_VERTICAL @@ -187,6 +190,9 @@ struct glyf_accelerator_t glyf_table = hb_sanitize_context_t ().reference_table (face); #ifndef HB_NO_VAR gvar = face->table.gvar; +#ifndef HB_NO_BEYOND_64K + GVAR = face->table.GVAR; +#endif #endif hmtx = face->table.hmtx; #ifndef HB_NO_VERTICAL @@ -198,6 +204,13 @@ struct glyf_accelerator_t } ~glyf_accelerator_t () { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + glyf_table.destroy (); } @@ -206,21 +219,17 @@ struct glyf_accelerator_t protected: template bool get_points (hb_font_t *font, hb_codepoint_t gid, T consumer, - hb_array_t coords = hb_array_t ()) const + hb_array_t coords, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { - if (!coords) - coords = hb_array (font->coords, font->num_coords); - if (gid >= num_glyphs) return false; - /* Making this allocfree is not that easy - https://github.com/harfbuzz/harfbuzz/issues/2095 - mostly because of gvar handling in VF fonts, - perhaps a separate path for non-VF fonts can be considered */ - contour_point_vector_t all_points; + auto &all_points = scratch.all_points; + all_points.resize (0); bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only, coords))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, scratch, nullptr, nullptr, nullptr, true, true, phantom_only, coords, gvar_cache))) return false; unsigned count = all_points.length; @@ -229,8 +238,61 @@ struct glyf_accelerator_t if (consumer.is_consuming_contour_points ()) { - for (auto &point : all_points.as_array ().sub_array (0, count)) - consumer.consume_point (point); + auto *points = all_points.arrayZ; + + if (false) + { + /* Our path-builder was designed to work with this simple loop. + * But FreeType and CoreText do it differently, so we match those + * with the other, more complicated, code branch below. */ + for (unsigned i = 0; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + consumer.contour_end (); + } + } + else + { + for (unsigned i = 0; i < count; i++) + { + // Start of a contour. + if (points[i].flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE) + { + // First point is on-curve. Draw the contour. + for (; i < count; i++) + { + consumer.consume_point (points[i]); + if (points[i].is_end_point) + { + consumer.contour_end (); + break; + } + } + } + else + { + unsigned start = i; + + // Find end of the contour. + for (; i < count; i++) + if (points[i].is_end_point) + break; + + unsigned end = i; + + // Enough to start from the end. Our path-builder takes care of the rest. + if (likely (end < count)) // Can only fail in case of alloc failure *maybe*. + consumer.consume_point (points[end]); + + for (i = start; i < end; i++) + consumer.consume_point (points[i]); + + consumer.contour_end (); + } + } + } + consumer.points_end (); } @@ -303,29 +365,35 @@ struct glyf_accelerator_t HB_ALWAYS_INLINE void consume_point (const contour_point_t &point) { bounds.add (point); } + void contour_end () {} void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } contour_point_t *get_phantoms_sink () { return phantoms; } }; +#ifndef HB_NO_VAR unsigned - get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + get_advance_with_var_unscaled (hb_codepoint_t gid, + hb_font_t *font, + bool is_vertical, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { if (unlikely (gid >= num_glyphs)) return 0; bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (font->num_coords) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); - + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + scratch, gvar_cache); if (unlikely (!success)) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : -#endif - hmtx->get_advance_without_var_unscaled (gid); + { + unsigned upem = font->face->get_upem (); + return is_vertical ? upem : upem / 2; + } float result = is_vertical ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y @@ -333,53 +401,63 @@ struct glyf_accelerator_t return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } - bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const + float + get_v_origin_with_var_unscaled (hb_codepoint_t gid, + hb_font_t *font, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const { - if (unlikely (gid >= num_glyphs)) return false; + if (unlikely (gid >= num_glyphs)) return 0; - hb_glyph_extents_t extents; + bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false)))) - return false; + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + scratch, gvar_cache); + if (unlikely (!success)) + { + return font->face->get_upem (); + } - *lsb = is_vertical - ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing - : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); - return true; + return phantoms[glyf_impl::PHANTOM_TOP].y; } +#endif #endif - bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const - { - if (unlikely (gid >= num_glyphs)) return false; - if (is_vertical) return false; // TODO Humm, what to do here? + public: - *lsb = glyph_for_gid (gid).get_header ()->xMin; - return true; - } + bool get_extents (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents) const + { return get_extents_at (font, gid, extents, hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); } - public: - bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const + bool get_extents_at (hb_font_t *font, + hb_codepoint_t gid, + hb_glyph_extents_t *extents, + hb_array_t coords) const { if (unlikely (gid >= num_glyphs)) return false; #ifndef HB_NO_VAR - if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); + if (coords) + { + hb_glyf_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return false; + bool ret = get_points (font, + gid, + points_aggregator_t (font, extents, nullptr, true), + coords, + *scratch); + release_scratch (scratch); + return ret; + } #endif return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } - bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const - { - funcs->push_clip_glyph (data, gid, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; - } - const glyf_impl::Glyph glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const { @@ -409,16 +487,66 @@ struct glyf_accelerator_t } bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const - { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session)); } + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, hb_scalar_cache_t *gvar_cache = nullptr) const + { + if (!has_data ()) return false; + + hb_glyf_scratch_t *scratch = acquire_scratch (); + if (unlikely (!scratch)) return true; + + bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0), + *scratch, + gvar_cache); + + release_scratch (scratch); + + return ret; + } bool get_path_at (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session, - hb_array_t coords) const - { return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), coords); } + hb_array_t coords, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr) const + { + if (!has_data ()) return false; + return get_points (font, gid, glyf_impl::path_builder_t (font, draw_session), + coords, + scratch, + gvar_cache); + } + + + hb_glyf_scratch_t *acquire_scratch () const + { + if (!has_data ()) return nullptr; + hb_glyf_scratch_t *scratch = cached_scratch.get_acquire (); + if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr))) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return nullptr; + } + return scratch; + } + void release_scratch (hb_glyf_scratch_t *scratch) const + { + if (!scratch) + return; + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + } #ifndef HB_NO_VAR const gvar_accelerator_t *gvar; +#ifndef HB_NO_BEYOND_64K + const GVAR_accelerator_t *GVAR; +#endif #endif const hmtx_accelerator_t *hmtx; #ifndef HB_NO_VERTICAL @@ -430,6 +558,7 @@ struct glyf_accelerator_t unsigned int num_glyphs; hb_blob_ptr_t loca_table; hb_blob_ptr_t glyf_table; + mutable hb_atomic_t cached_scratch; }; @@ -439,7 +568,7 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, hb_vector_t& glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); - if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false; + if (!glyphs.alloc_exact (plan->new_to_old_gid_list.length)) return false; for (const auto &pair : plan->new_to_old_gid_list) { diff --git a/thirdparty/harfbuzz/upstream/OT/glyf/path-builder.hh b/thirdparty/harfbuzz/upstream/OT/glyf/path-builder.hh index f55052450..859cd577f 100644 --- a/thirdparty/harfbuzz/upstream/OT/glyf/path-builder.hh +++ b/thirdparty/harfbuzz/upstream/OT/glyf/path-builder.hh @@ -42,7 +42,7 @@ struct path_builder_t { bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE; #ifdef HB_NO_CUBIC_GLYF - bool is_cubic = false; + constexpr bool is_cubic = false; #else bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC); #endif @@ -124,58 +124,60 @@ struct path_builder_t } } - if (unlikely (point.is_end_point)) - { - if (first_offcurve && last_offcurve) - { - optional_point_t mid = last_offcurve.mid (first_offcurve2 ? - first_offcurve2 : - first_offcurve); - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - mid.x, mid.y); - last_offcurve = optional_point_t (); - } - /* now check the rest */ + } - if (first_offcurve && first_oncurve) - { - if (first_offcurve2) - draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, - first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (last_offcurve && first_oncurve) - { - if (last_offcurve2) - draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, - last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - else - draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, - first_oncurve.x, first_oncurve.y); - } - else if (first_oncurve) - draw_session->line_to (first_oncurve.x, first_oncurve.y); - else if (first_offcurve) - { - float x = first_offcurve.x, y = first_offcurve.y; - draw_session->move_to (x, y); - draw_session->quadratic_to (x, y, x, y); - } + void contour_end () + { + if (first_offcurve && last_offcurve) + { + optional_point_t mid = last_offcurve.mid (first_offcurve2 ? + first_offcurve2 : + first_offcurve); + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + mid.x, mid.y); + last_offcurve = optional_point_t (); + } + /* now check the rest */ - /* Getting ready for the next contour */ - first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); - draw_session->close_path (); + if (first_offcurve && first_oncurve) + { + if (first_offcurve2) + draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y, + first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (first_offcurve.x, first_offcurve.y, + first_oncurve.x, first_oncurve.y); } + else if (last_offcurve && first_oncurve) + { + if (last_offcurve2) + draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y, + last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + else + draw_session->quadratic_to (last_offcurve.x, last_offcurve.y, + first_oncurve.x, first_oncurve.y); + } + else if (first_oncurve) + draw_session->line_to (first_oncurve.x, first_oncurve.y); + else if (first_offcurve) + { + float x = first_offcurve.x, y = first_offcurve.y; + draw_session->move_to (x, y); + draw_session->quadratic_to (x, y, x, y); + } + + /* Getting ready for the next contour */ + first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t (); + draw_session->close_path (); } + void points_end () {} bool is_consuming_contour_points () { return true; } diff --git a/thirdparty/harfbuzz/upstream/OT/name/name.hh b/thirdparty/harfbuzz/upstream/OT/name/name.hh index e2a25d4a0..33de82d35 100644 --- a/thirdparty/harfbuzz/upstream/OT/name/name.hh +++ b/thirdparty/harfbuzz/upstream/OT/name/name.hh @@ -163,7 +163,7 @@ struct NameRecord if (platformID != 1) { unsigned text_size = hb_ot_name_convert_utf (*name_bytes, nullptr, nullptr); - + text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf() unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; name_str_utf16_be = (char *) hb_calloc (byte_len, 1); @@ -174,14 +174,14 @@ struct NameRecord } hb_ot_name_convert_utf (*name_bytes, &text_size, (hb_utf16_be_t::codepoint_t *) name_str_utf16_be); - + unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size; if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) { c->revert (snap); hb_free (name_str_utf16_be); return_trace (nullptr); } - + encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len); } else @@ -392,7 +392,7 @@ struct name const hb_hashmap_t *name_table_overrides = &c->plan->name_table_overrides; #endif - + auto it = + nameRecordZ.as_array (count) | hb_filter (c->plan->name_ids, &NameRecord::nameID) @@ -485,7 +485,7 @@ struct name const hb_array_t all_names (this->table->nameRecordZ.arrayZ, this->table->count); - this->names.alloc (all_names.length, true); + this->names.alloc_exact (all_names.length); for (unsigned int i = 0; i < all_names.length; i++) { diff --git a/thirdparty/harfbuzz/upstream/addTable.py b/thirdparty/harfbuzz/upstream/addTable.py deleted file mode 100644 index 103f292dd..000000000 --- a/thirdparty/harfbuzz/upstream/addTable.py +++ /dev/null @@ -1,16 +0,0 @@ -import sys -from fontTools.ttLib import TTFont -from fontTools.ttLib.tables.DefaultTable import DefaultTable - -if len(sys.argv) == 1: - print("usage: python addTable.py input.ttf output.ttf Wasm.bin") - sys.exit(1) - -font = TTFont(sys.argv[1]) - -wasm_table = DefaultTable("Wasm") -wasm_table.data = open(sys.argv[3], "rb").read() - -font["Wasm"] = wasm_table - -font.save(sys.argv[2]) diff --git a/thirdparty/harfbuzz/upstream/check-c-linkage-decls.py b/thirdparty/harfbuzz/upstream/check-c-linkage-decls.py deleted file mode 100755 index 27f5639e7..000000000 --- a/thirdparty/harfbuzz/upstream/check-c-linkage-decls.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os - -srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) -base_srcdir = os.getenv ('base_srcdir', srcdir) - -os.chdir (srcdir) - -def removeprefix(s): - abs_path = os.path.join(base_srcdir, s) - return os.path.relpath(abs_path, srcdir) - - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] -HBHEADERS = [x for x in HBHEADERS if x.endswith ('.h')] -HBSOURCES = [ - removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () -] or [ - x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) -] -stat = 0 - -for x in HBHEADERS: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if ('HB_BEGIN_DECLS' not in content) or ('HB_END_DECLS' not in content): - print ('Ouch, file %s does not have HB_BEGIN_DECLS / HB_END_DECLS, but it should' % x) - stat = 1 - -for x in HBSOURCES: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if ('HB_BEGIN_DECLS' in content) or ('HB_END_DECLS' in content): - print ('Ouch, file %s has HB_BEGIN_DECLS / HB_END_DECLS, but it shouldn\'t' % x) - stat = 1 - -sys.exit (stat) diff --git a/thirdparty/harfbuzz/upstream/check-externs.py b/thirdparty/harfbuzz/upstream/check-externs.py deleted file mode 100755 index a64d2e5b4..000000000 --- a/thirdparty/harfbuzz/upstream/check-externs.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os, re - -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] - -stat = 0 - -print ('Checking that all public symbols are exported with HB_EXTERN') -for x in HBHEADERS: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - for s in re.findall (r'\n.+\nhb_.+\n', content): - if not s.startswith ('\nHB_EXTERN '): - print ('failure on:', s) - stat = 1 - -sys.exit (stat) diff --git a/thirdparty/harfbuzz/upstream/check-header-guards.py b/thirdparty/harfbuzz/upstream/check-header-guards.py deleted file mode 100755 index 35ae6bef6..000000000 --- a/thirdparty/harfbuzz/upstream/check-header-guards.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os, re - -srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) -base_srcdir = os.getenv ('base_srcdir', srcdir) - -os.chdir (srcdir) - -def removeprefix(s): - abs_path = os.path.join(base_srcdir, s) - return os.path.relpath(abs_path, srcdir) - - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] -HBSOURCES = [ - removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () -] or [ - x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) -] - - -stat = 0 - -for x in HBHEADERS + HBSOURCES: - if not x.endswith ('h') or x == 'hb-gobject-structs.h': continue - tag = x.upper ().replace ('.', '_').replace ('-', '_').replace(os.path.sep, '_').replace('/', '_') - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if len (re.findall (tag + r'\b', content)) != 3: - print ('Ouch, header file %s does not have correct preprocessor guards. Expected: %s' % (x, tag)) - stat = 1 - -sys.exit (stat) diff --git a/thirdparty/harfbuzz/upstream/check-includes.py b/thirdparty/harfbuzz/upstream/check-includes.py deleted file mode 100755 index fc95874b1..000000000 --- a/thirdparty/harfbuzz/upstream/check-includes.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os, re - -srcdir = os.getenv ('srcdir', os.path.dirname (__file__)) -base_srcdir = os.getenv ('base_srcdir', srcdir) - -os.chdir (srcdir) - -def removeprefix(s): - abs_path = os.path.join(base_srcdir, s) - return os.path.relpath(abs_path, srcdir) - -HBHEADERS = [os.path.basename (x) for x in os.getenv ('HBHEADERS', '').split ()] or \ - [x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith ('.h')] - -HBSOURCES = [ - removeprefix(x) for x in os.getenv ('HBSOURCES', '').split () -] or [ - x for x in os.listdir ('.') if x.startswith ('hb') and x.endswith (('.cc', '.hh')) -] - - -stat = 0 - -print ('Checking that public header files #include "hb-common.h" or "hb.h" first (or none)') -for x in HBHEADERS: - if x == 'hb.h' or x == 'hb-common.h': continue - with open (x, 'r', encoding='utf-8') as f: content = f.read () - first = re.findall (r'#.*include.*', content)[0] - if first not in ['#include "hb.h"', '#include "hb-common.h"']: - print ('failure on %s' % x) - stat = 1 - -print ('Checking that source files #include a private header first (or none)') -for x in HBSOURCES: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - includes = re.findall (r'#.*include.*', content) - if includes: - if not len (re.findall (r'".*\.hh"', includes[0])): - print ('failure on %s' % x) - stat = 1 - -print ('Checking that there is no #include ') -for x in HBHEADERS + HBSOURCES: - with open (x, 'r', encoding='utf-8') as f: content = f.read () - if re.findall ('#.*include.*<.*hb', content): - print ('failure on %s' % x) - stat = 1 - -sys.exit (stat) diff --git a/thirdparty/harfbuzz/upstream/check-libstdc++.py b/thirdparty/harfbuzz/upstream/check-libstdc++.py deleted file mode 100755 index e70d5f80b..000000000 --- a/thirdparty/harfbuzz/upstream/check-libstdc++.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os, shutil, subprocess - -os.chdir (os.getenv ('srcdir', os.path.dirname (__file__))) - -libs = os.getenv ('libs', '.libs') - -ldd = os.getenv ('LDD', shutil.which ('ldd')) -if not ldd: - otool = os.getenv ('OTOOL', shutil.which ('otool')) - if otool: - ldd = otool + ' -L' - else: - print ('check-libstdc++.py: \'ldd\' not found; skipping test') - sys.exit (77) - -stat = 0 -tested = False - -# harfbuzz-icu links to libstdc++ because icu does. -for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-gobject', 'harfbuzz-cairo']: - for suffix in ['so', 'dylib']: - so = os.path.join (libs, 'lib%s.%s' % (soname, suffix)) - if not os.path.exists (so): continue - - print ('Checking that we are not linking to libstdc++ or libc++ in %s' % so) - ldd_result = subprocess.check_output (ldd.split() + [so]) - if (b'libstdc++' in ldd_result) or (b'libc++' in ldd_result): - print ('Ouch, %s is linked to libstdc++ or libc++' % so) - stat = 1 - - tested = True - -if not tested: - print ('check-libstdc++.py: libharfbuzz shared library not found; skipping test') - sys.exit (77) - -sys.exit (stat) diff --git a/thirdparty/harfbuzz/upstream/check-static-inits.py b/thirdparty/harfbuzz/upstream/check-static-inits.py deleted file mode 100755 index c6e2db1ea..000000000 --- a/thirdparty/harfbuzz/upstream/check-static-inits.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os, shutil, subprocess, glob, re - -builddir = os.getenv ('builddir', os.path.dirname (__file__)) -libs = os.getenv ('libs', '.libs') - -objdump = os.getenv ('OBJDUMP', shutil.which ('objdump')) -if not objdump: - print ('check-static-inits.py: \'ldd\' not found; skipping test') - sys.exit (77) - -if sys.version_info < (3, 5): - print ('check-static-inits.py: needs python 3.5 for recursive support in glob') - sys.exit (77) - -OBJS = glob.glob (os.path.join (builddir, libs, '**', '*hb*.o'), recursive=True) -if not OBJS: - print ('check-static-inits.py: object files not found; skipping test') - sys.exit (77) - -stat = 0 -tested = 0 - -for obj in OBJS: - result = subprocess.run(objdump.split () + ['-t', obj], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - if result.returncode: - if result.stderr.find (b'not recognized') != -1: - # https://github.com/harfbuzz/harfbuzz/issues/3019 - print ('objdump %s returned "not recognized", skipping' % obj) - continue - print ('objdump %s returned error:\n%s' % (obj, result.stderr.decode ('utf-8'))) - stat = 2 - - result = result.stdout.decode ('utf-8') - - # Checking that no object file has static initializers - for l in re.findall (r'^.*\.[cd]tors.*$', result, re.MULTILINE): - if not re.match (r'.*\b0+\b', l): - print ('Ouch, %s has static initializers/finalizers' % obj) - stat = 1 - - # Checking that no object file has lazy static C++ constructors/destructors or other such stuff - if ('__cxa_' in result) and ('__ubsan_handle' not in result): - print ('Ouch, %s has lazy static C++ constructors/destructors or other such stuff' % obj) - stat = 1 - - tested += 1 - -sys.exit (stat if tested else 77) diff --git a/thirdparty/harfbuzz/upstream/check-symbols.py b/thirdparty/harfbuzz/upstream/check-symbols.py deleted file mode 100755 index 91bf8b067..000000000 --- a/thirdparty/harfbuzz/upstream/check-symbols.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os, shutil, subprocess, re, difflib - -os.environ['LC_ALL'] = 'C' # otherwise 'nm' prints in wrong order - -builddir = os.getenv ('builddir', os.path.dirname (__file__)) -libs = os.getenv ('libs', '.libs') - -IGNORED_SYMBOLS = '|'.join(['_fini', '_init', '_fdata', '_ftext', '_fbss', - '__bss_start', '__bss_start__', '__bss_end__', '_edata', '_end', '_bss_end__', - '__end__', '__gcov_.*', 'llvm_.*', 'flush_fn_list', 'writeout_fn_list', 'mangle_path', - 'lprofDirMode', 'reset_fn_list']) - -nm = os.getenv ('NM', shutil.which ('nm')) -if not nm: - print ('check-symbols.py: \'nm\' not found; skipping test') - sys.exit (77) - -cxxfilt = shutil.which ('c++filt') - -tested = False -stat = 0 - -for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject', 'harfbuzz-cairo']: - for suffix in ['so', 'dylib']: - so = os.path.join (builddir, libs, 'lib%s.%s' % (soname, suffix)) - if not os.path.exists (so): continue - - # On macOS, C symbols are prefixed with _ - symprefix = '_' if suffix == 'dylib' else '' - - EXPORTED_SYMBOLS = [s.split ()[2] - for s in re.findall (r'^.+ [BCDGIRSTu] .+$', subprocess.check_output (nm.split() + [so]).decode ('utf-8'), re.MULTILINE) - if not re.match (r'.* %s(%s)\b' % (symprefix, IGNORED_SYMBOLS), s)] - - # run again c++filt also if is available - if cxxfilt: - EXPORTED_SYMBOLS = subprocess.check_output ( - [cxxfilt], input='\n'.join (EXPORTED_SYMBOLS).encode () - ).decode ('utf-8').splitlines () - - prefix = (symprefix + os.path.basename (so)).replace ('libharfbuzz', 'hb').replace ('-', '_').split ('.')[0] - - print ('Checking that %s does not expose internal symbols' % so) - suspicious_symbols = [x for x in EXPORTED_SYMBOLS if not re.match (r'^%s(_|$)' % prefix, x)] - if suspicious_symbols: - print ('Ouch, internal symbols exposed:', suspicious_symbols) - stat = 1 - - def_path = os.path.join (builddir, soname + '.def') - if not os.path.exists (def_path): - print ('\'%s\' not found; skipping' % def_path) - else: - print ('Checking that %s has the same symbol list as %s' % (so, def_path)) - with open (def_path, 'r', encoding='utf-8') as f: def_file = f.read () - diff_result = list (difflib.context_diff ( - def_file.splitlines (), - ['EXPORTS'] + [re.sub ('^%shb' % symprefix, 'hb', x) for x in EXPORTED_SYMBOLS] + - # cheat: copy the last line from the def file! - [def_file.splitlines ()[-1]] - )) - - if diff_result: - print ('\n'.join (diff_result)) - stat = 1 - - tested = True - -if not tested: - print ('check-symbols.py: no shared libraries found; skipping test') - sys.exit (77) - -sys.exit (stat) diff --git a/thirdparty/harfbuzz/upstream/fix_get_types.py b/thirdparty/harfbuzz/upstream/fix_get_types.py deleted file mode 100755 index 64d8ce5a5..000000000 --- a/thirdparty/harfbuzz/upstream/fix_get_types.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 - -import re -import argparse - -parser = argparse.ArgumentParser () -parser.add_argument ('input') -parser.add_argument ('output') -args = parser.parse_args () - -with open (args.input, 'r') as inp, open (args.output, 'w') as out: - for l in inp.readlines (): - l = re.sub ('_t_get_type', '_get_type', l) - l = re.sub (r'_T \(', ' (', l) - out.write (l) diff --git a/thirdparty/harfbuzz/upstream/gen-arabic-joining-list.py b/thirdparty/harfbuzz/upstream/gen-arabic-joining-list.py deleted file mode 100755 index 7ec7425fd..000000000 --- a/thirdparty/harfbuzz/upstream/gen-arabic-joining-list.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-arabic-joining-table.py ArabicShaping.txt Scripts.txt - -Input files: -* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt -* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt -""" - -import os.path, sys - -if len (sys.argv) != 3: - sys.exit (__doc__) - -files = [open (x, encoding='utf-8') for x in sys.argv[1:]] - -headers = [[f.readline (), f.readline ()] for f in files] -while files[0].readline ().find ('##################') < 0: - pass - -def read (f): - mapping = {} - for line in f: - - j = line.find ('#') - if j >= 0: - line = line[:j] - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - - t = fields[1] - - for u in range (start, end + 1): - mapping[u] = t - - return mapping - -def read_joining_uu (f): - values = set () - for line in f: - - if line[0] == '#': - continue - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - if fields[2] in {'T', 'U'}: - continue - - values.add (int (fields[0], 16)) - - return sorted (values) - -def print_has_arabic_joining (scripts, joining_uu): - - print ("static bool") - print ("has_arabic_joining (hb_script_t script)") - print ("{") - print (" /* List of scripts that have data in arabic-table. */") - print (" switch ((int) script)") - print (" {") - - for script in sorted ({scripts[u] for u in joining_uu if scripts[u] not in {'Common', 'Inherited'}}): - print (" case HB_SCRIPT_{}:".format (script.upper ())) - - print (" return true;") - print () - print (" default:") - print (" return false;") - print (" }") - print ("}") - print () - -print ("/* == Start of generated function == */") -print ("/*") -print (" * The following function is generated by running:") -print (" *") -print (" * ./gen-arabic-joining-list.py ArabicShaping.txt Scripts.txt") -print (" *") -print (" * on files with these headers:") -print (" *") -for h in headers: - for l in h: - print (" * %s" % (l.strip ())) -print (" */") -print () -print ("#ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") -print ("#define HB_OT_SHAPER_ARABIC_JOINING_LIST_HH") -print () - -print_has_arabic_joining (read (files[1]), read_joining_uu (files[0])) - -print () -print ("#endif /* HB_OT_SHAPER_ARABIC_JOINING_LIST_HH */") -print () -print ("/* == End of generated function == */") diff --git a/thirdparty/harfbuzz/upstream/gen-arabic-pua.py b/thirdparty/harfbuzz/upstream/gen-arabic-pua.py deleted file mode 100755 index 4cf290087..000000000 --- a/thirdparty/harfbuzz/upstream/gen-arabic-pua.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-arabic-pua.py -""" - -import packTab - - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following table is generated by running:") -print (" *") -print (" * ./gen-arabic-pua.py") -print (" *") -print (" */") -print () -print ("#ifndef HB_OT_SHAPER_ARABIC_PUA_HH") -print ("#define HB_OT_SHAPER_ARABIC_PUA_HH") -print () - -code = packTab.Code('_hb_arabic') - -for p in ("ArabicPUASimplified.txt", "ArabicPUATraditional.txt"): - with open (p, encoding='utf-8') as f: - fields = [l.split('\t') for l in f if l[:1] != '#'] - data = {int(fs[1], 16):int(fs[0], 16) for fs in fields} - sol = packTab.pack_table(data, compression=9) - sol.genCode(code, f'pua_{p[9:13].lower()}_map') - -code.print_c(linkage='static inline') - -print () -print ("#endif /* HB_OT_SHAPER_ARABIC_PUA_HH */") -print () -print ("/* == End of generated table == */") diff --git a/thirdparty/harfbuzz/upstream/gen-arabic-table.py b/thirdparty/harfbuzz/upstream/gen-arabic-table.py deleted file mode 100755 index 8278d7d69..000000000 --- a/thirdparty/harfbuzz/upstream/gen-arabic-table.py +++ /dev/null @@ -1,358 +0,0 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt - -Input files: -* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt -* https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt -* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt -""" - -import os.path, sys - -if len (sys.argv) != 4: - sys.exit (__doc__) - -files = [open (x, encoding='utf-8') for x in sys.argv[1:]] - -headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]] -headers.append (["UnicodeData.txt does not have a header."]) -while files[0].readline ().find ('##################') < 0: - pass - -blocks = {} -def read_blocks(f): - global blocks - for line in f: - - j = line.find ('#') - if j >= 0: - line = line[:j] - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - - t = fields[1] - - for u in range (start, end + 1): - blocks[u] = t - -def print_joining_table(f): - - values = {} - for line in f: - - if line[0] == '#': - continue - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - - u = int (fields[0], 16) - - if fields[3] in ["ALAPH", "DALATH RISH"]: - value = "JOINING_GROUP_" + fields[3].replace(' ', '_') - else: - value = "JOINING_TYPE_" + fields[2] - values[u] = value - - short_value = {} - for value in sorted (set ([v for v in values.values ()] + ['JOINING_TYPE_X'])): - short = ''.join(x[0] for x in value.split('_')[2:]) - assert short not in short_value.values() - short_value[value] = short - - print () - for value,short in short_value.items(): - print ("#define %s %s" % (short, value)) - - uu = sorted(values.keys()) - num = len(values) - all_blocks = set([blocks[u] for u in uu]) - - last = -100000 - ranges = [] - for u in uu: - if u - last <= 1+16*5: - ranges[-1][-1] = u - else: - ranges.append([u,u]) - last = u - - print () - print ("static const uint8_t joining_table[] =") - print ("{") - last_block = None - offset = 0 - for start,end in ranges: - - print () - print ("#define joining_offset_0x%04xu %d" % (start, offset)) - - for u in range(start, end+1): - - block = blocks.get(u, last_block) - value = values.get(u, "JOINING_TYPE_X") - - if block != last_block or u == start: - if u != start: - print () - if block in all_blocks: - print ("\n /* %s */" % block) - else: - print ("\n /* FILLER */") - last_block = block - if u % 32 != 0: - print () - print (" /* %04X */" % (u//32*32), " " * (u % 32), end="") - - if u % 32 == 0: - print () - print (" /* %04X */ " % u, end="") - print ("%s," % short_value[value], end="") - print () - - offset += end - start + 1 - print () - occupancy = num * 100. / offset - print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)) - print () - - page_bits = 12 - print () - print ("static unsigned int") - print ("joining_type (hb_codepoint_t u)") - print ("{") - print (" switch (u >> %d)" % page_bits) - print (" {") - pages = set([u>>page_bits for u in [s for s,e in ranges]+[e for s,e in ranges]]) - for p in sorted(pages): - print (" case 0x%0Xu:" % p) - for (start,end) in ranges: - if p not in [start>>page_bits, end>>page_bits]: continue - offset = "joining_offset_0x%04xu" % start - print (" if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset)) - print (" break;") - print ("") - print (" default:") - print (" break;") - print (" }") - print (" return X;") - print ("}") - print () - for value,short in short_value.items(): - print ("#undef %s" % (short)) - print () - -LIGATURES = ( - 0xF2EE, 0xFC08, 0xFC0E, 0xFC12, 0xFC32, 0xFC3F, 0xFC40, 0xFC41, 0xFC42, - 0xFC44, 0xFC4E, 0xFC5E, 0xFC60, 0xFC61, 0xFC62, 0xFC6A, 0xFC6D, 0xFC6F, - 0xFC70, 0xFC73, 0xFC75, 0xFC86, 0xFC8F, 0xFC91, 0xFC94, 0xFC9C, 0xFC9D, - 0xFC9E, 0xFC9F, 0xFCA1, 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA8, 0xFCAA, 0xFCAC, - 0xFCB0, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, 0xFCCF, 0xFCD0, - 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD5, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFD30, - 0xFD88, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, - 0xF201, 0xF211, 0xF2EE, -) - -def print_shaping_table(f): - - shapes = {} - ligatures = {} - names = {} - lines = f.readlines() - lines += [ - "F201;PUA ARABIC LIGATURE LELLAH ISOLATED FORM;Lo;0;AL; 0644 0644 0647;;;;N;;;;;", - "F211;PUA ARABIC LIGATURE LAM WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 0645 062C;;;;N;;;;;", - "F2EE;PUA ARABIC LIGATURE SHADDA WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0020 064B 0651;;;;N;;;;;", - ] - for line in lines: - - fields = [x.strip () for x in line.split (';')] - if fields[5][0:1] != '<': - continue - - items = fields[5].split (' ') - shape, items = items[0][1:-1], tuple (int (x, 16) for x in items[1:]) - c = int (fields[0], 16) - - if not shape in ['initial', 'medial', 'isolated', 'final']: - continue - - if len (items) != 1: - # Mark ligatures start with space and are in visual order, so we - # remove the space and reverse the items. - if items[0] == 0x0020: - items = items[:0:-1] - shape = None - # We only care about a subset of ligatures - if c not in LIGATURES: - continue - - # Save ligature - names[c] = fields[1] - if items not in ligatures: - ligatures[items] = {} - ligatures[items][shape] = c - else: - # Save shape - if items[0] not in names: - names[items[0]] = fields[1] - else: - names[items[0]] = os.path.commonprefix ([names[items[0]], fields[1]]).strip () - if items[0] not in shapes: - shapes[items[0]] = {} - shapes[items[0]][shape] = c - - print () - print ("static const uint16_t shaping_table[][4] =") - print ("{") - - keys = shapes.keys () - min_u, max_u = min (keys), max (keys) - for u in range (min_u, max_u + 1): - s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0 - for shape in ['initial', 'medial', 'final', 'isolated']] - value = ', '.join ("0x%04Xu" % c for c in s) - print (" {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")) - - print ("};") - print () - print ("#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u) - print ("#define SHAPING_TABLE_LAST 0x%04Xu" % max_u) - print () - - ligas_2 = {} - ligas_3 = {} - ligas_mark_2 = {} - for key in ligatures.keys (): - for shape in ligatures[key]: - c = ligatures[key][shape] - if len(key) == 3: - if shape == 'isolated': - liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'], shapes[key[2]]['final']) - elif shape == 'final': - liga = (shapes[key[0]]['medial'], shapes[key[1]]['medial'], shapes[key[2]]['final']) - elif shape == 'initial': - liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'], shapes[key[2]]['medial']) - else: - raise Exception ("Unexpected shape", shape) - if liga[0] not in ligas_3: - ligas_3[liga[0]] = [] - ligas_3[liga[0]].append ((liga[1], liga[2], c)) - elif len(key) == 2: - if shape is None: - liga = key - if liga[0] not in ligas_mark_2: - ligas_mark_2[liga[0]] = [] - ligas_mark_2[liga[0]].append ((liga[1], c)) - continue - elif shape == 'isolated': - liga = (shapes[key[0]]['initial'], shapes[key[1]]['final']) - elif shape == 'final': - liga = (shapes[key[0]]['medial'], shapes[key[1]]['final']) - elif shape == 'initial': - liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial']) - else: - raise Exception ("Unexpected shape", shape) - if liga[0] not in ligas_2: - ligas_2[liga[0]] = [] - ligas_2[liga[0]].append ((liga[1], c)) - else: - raise Exception ("Unexpected number of ligature components", key) - max_i = max (len (ligas_2[l]) for l in ligas_2) - print () - print ("static const struct ligature_set_t {") - print (" uint16_t first;") - print (" struct ligature_pairs_t {") - print (" uint16_t components[1];") - print (" uint16_t ligature;") - print (" } ligatures[%d];" % max_i) - print ("} ligature_table[] =") - print ("{") - for first in sorted (ligas_2.keys ()): - - print (" { 0x%04Xu, {" % (first)) - for liga in ligas_2[first]: - print (" { {0x%04Xu}, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])) - print (" }},") - - print ("};") - print () - - max_i = max (len (ligas_mark_2[l]) for l in ligas_mark_2) - print () - print ("static const struct ligature_mark_set_t {") - print (" uint16_t first;") - print (" struct ligature_pairs_t {") - print (" uint16_t components[1];") - print (" uint16_t ligature;") - print (" } ligatures[%d];" % max_i) - print ("} ligature_mark_table[] =") - print ("{") - for first in sorted (ligas_mark_2.keys ()): - - print (" { 0x%04Xu, {" % (first)) - for liga in ligas_mark_2[first]: - print (" { {0x%04Xu}, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])) - print (" }},") - - print ("};") - print () - - max_i = max (len (ligas_3[l]) for l in ligas_3) - print () - print ("static const struct ligature_3_set_t {") - print (" uint16_t first;") - print (" struct ligature_triplets_t {") - print (" uint16_t components[2];") - print (" uint16_t ligature;") - print (" } ligatures[%d];" % max_i) - print ("} ligature_3_table[] =") - print ("{") - for first in sorted (ligas_3.keys ()): - - print (" { 0x%04Xu, {" % (first)) - for liga in ligas_3[first]: - print (" { {0x%04Xu, 0x%04Xu}, 0x%04Xu}, /* %s */" % (liga[0], liga[1], liga[2], names[liga[2]])) - print (" }},") - - print ("};") - print () - - - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following table is generated by running:") -print (" *") -print (" * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt") -print (" *") -print (" * on files with these headers:") -print (" *") -for h in headers: - for l in h: - print (" * %s" % (l.strip())) -print (" */") -print () -print ("#ifndef HB_OT_SHAPER_ARABIC_TABLE_HH") -print ("#define HB_OT_SHAPER_ARABIC_TABLE_HH") -print () - -read_blocks (files[2]) -print_joining_table (files[0]) -print_shaping_table (files[1]) - -print () -print ("#endif /* HB_OT_SHAPER_ARABIC_TABLE_HH */") -print () -print ("/* == End of generated table == */") diff --git a/thirdparty/harfbuzz/upstream/gen-def.py b/thirdparty/harfbuzz/upstream/gen-def.py deleted file mode 100755 index 6011817bc..000000000 --- a/thirdparty/harfbuzz/upstream/gen-def.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python3 - -"usage: gen-def.py harfbuzz.def hb.h [hb-blob.h hb-buffer.h ...]" - -import os, re, sys - -if len (sys.argv) < 3: - sys.exit(__doc__) - -output_file = sys.argv[1] -header_paths = sys.argv[2:] - -headers_content = [] -for h in header_paths: - if h.endswith (".h"): - with open (h, encoding='utf-8') as f: headers_content.append (f.read ()) - -symbols = sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M)) -if '--experimental-api' not in sys.argv: - # Move these to harfbuzz-sections.txt when got stable - experimental_symbols = \ -"""hb_shape_justify -hb_subset_repack_or_fail -hb_subset_input_override_name_table -""".splitlines () - symbols = [x for x in symbols if x not in experimental_symbols] -symbols = "\n".join (symbols) - -result = symbols if os.getenv ('PLAIN_LIST', '') else """EXPORTS -%s -LIBRARY lib%s-0.dll""" % (symbols, output_file.replace ('src/', '').replace ('.def', '')) - -with open (output_file, "w") as f: f.write (result) diff --git a/thirdparty/harfbuzz/upstream/gen-emoji-table.py b/thirdparty/harfbuzz/upstream/gen-emoji-table.py deleted file mode 100755 index 42a3fb8de..000000000 --- a/thirdparty/harfbuzz/upstream/gen-emoji-table.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-emoji-table.py emoji-data.txt emoji-test.txt - -Input file: -* https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt -* https://www.unicode.org/Public/emoji/latest/emoji-test.txt -""" - -import sys -from collections import OrderedDict -import packTab - -if len (sys.argv) != 3: - sys.exit (__doc__) - -f = open(sys.argv[1]) -header = [f.readline () for _ in range(10)] - -ranges = OrderedDict() -for line in f.readlines(): - line = line.strip() - if not line or line[0] == '#': - continue - rang, typ = [s.strip() for s in line.split('#')[0].split(';')[:2]] - - rang = [int(s, 16) for s in rang.split('..')] - if len(rang) > 1: - start, end = rang - else: - start = end = rang[0] - - if typ not in ranges: - ranges[typ] = [] - if ranges[typ] and ranges[typ][-1][1] == start - 1: - ranges[typ][-1] = (ranges[typ][-1][0], end) - else: - ranges[typ].append((start, end)) - - - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following tables are generated by running:") -print (" *") -print (" * ./gen-emoji-table.py emoji-data.txt") -print (" *") -print (" * on file with this header:") -print (" *") -for l in header: - print (" * %s" % (l.strip())) -print (" */") -print () -print ("#ifndef HB_UNICODE_EMOJI_TABLE_HH") -print ("#define HB_UNICODE_EMOJI_TABLE_HH") -print () -print ('#include "hb-unicode.hh"') -print () - -for typ, s in ranges.items(): - if typ != "Extended_Pictographic": continue - - arr = dict() - for start,end in s: - for i in range(start, end + 1): - arr[i] = 1 - - sol = packTab.pack_table(arr, 0, compression=9) - code = packTab.Code('_hb_emoji') - sol.genCode(code, 'is_'+typ) - code.print_c(linkage='static inline') - print() - -print () -print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */") -print () -print ("/* == End of generated table == */") - - -# Generate test file. -sequences = [] -with open(sys.argv[2]) as f: - for line in f.readlines(): - if "#" in line: - line = line[:line.index("#")] - if ";" in line: - line = line[:line.index(";")] - line = line.strip() - line = line.split(" ") - if len(line) < 2: - continue - sequences.append(line) - -with open("../test/shape/data/in-house/tests/emoji-clusters.tests", "w") as f: - for sequence in sequences: - f.write("../fonts/AdobeBlank2.ttf;--no-glyph-names --no-positions --font-funcs=ot") - f.write(";" + ",".join(sequence)) - f.write(";[" + "|".join("1=0" for c in sequence) + "]\n") diff --git a/thirdparty/harfbuzz/upstream/gen-harfbuzzcc.py b/thirdparty/harfbuzz/upstream/gen-harfbuzzcc.py deleted file mode 100755 index 227384043..000000000 --- a/thirdparty/harfbuzz/upstream/gen-harfbuzzcc.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python3 - -"This tool is intended to be used from meson" - -import os, sys, shutil - -if len (sys.argv) < 3: - sys.exit (__doc__) - -OUTPUT = sys.argv[1] -CURRENT_SOURCE_DIR = sys.argv[2] - -# make sure input files are unique -sources = sorted(set(sys.argv[3:])) - -with open (OUTPUT, "wb") as f: - f.write ("".join ('#include "{}"\n'.format (os.path.relpath (os.path.abspath (x), CURRENT_SOURCE_DIR)) for x in sources if x.endswith (".cc")).encode ()) - -# copy it also to the source tree, but only if it has changed -baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)) -with open(baseline_filename, "rb") as baseline: - with open(OUTPUT, "rb") as generated: - if baseline.read() != generated.read(): - shutil.copyfile (OUTPUT, baseline_filename) diff --git a/thirdparty/harfbuzz/upstream/gen-hb-version.py b/thirdparty/harfbuzz/upstream/gen-hb-version.py deleted file mode 100755 index 06018edfc..000000000 --- a/thirdparty/harfbuzz/upstream/gen-hb-version.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -"This tool is intended to be used from meson" - -import os, sys, shutil, re - -if len (sys.argv) < 4: - sys.exit(__doc__) - -version = sys.argv[1] -major, minor, micro = version.split (".") - -OUTPUT = sys.argv[2] -INPUT = sys.argv[3] -CURRENT_SOURCE_DIR = os.path.dirname(INPUT) - -try: - with open (OUTPUT, "r", encoding='utf-8') as old_output: - for line in old_output: - old_version = re.match (r"#define HB_VERSION_STRING \"(\d.\d.\d)\"", line) - if old_version and old_version[1] == version: - sys.exit () -except IOError: - pass - -with open (INPUT, "r", encoding='utf-8') as template: - with open (OUTPUT, "wb") as output: - output.write (template.read () - .replace ("@HB_VERSION_MAJOR@", major) - .replace ("@HB_VERSION_MINOR@", minor) - .replace ("@HB_VERSION_MICRO@", micro) - .replace ("@HB_VERSION@", version) - .encode ()) - -# copy it also to the source tree, but only if it has changed -baseline_filename = os.path.join (CURRENT_SOURCE_DIR, os.path.basename (OUTPUT)) -with open(baseline_filename, "rb") as baseline: - with open(OUTPUT, "rb") as generated: - if baseline.read() != generated.read(): - shutil.copyfile (OUTPUT, baseline_filename) diff --git a/thirdparty/harfbuzz/upstream/gen-indic-table.py b/thirdparty/harfbuzz/upstream/gen-indic-table.py deleted file mode 100755 index 2c8abcca6..000000000 --- a/thirdparty/harfbuzz/upstream/gen-indic-table.py +++ /dev/null @@ -1,700 +0,0 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt - -Input files: -* https://unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt -* https://unicode.org/Public/UCD/latest/ucd/IndicPositionalCategory.txt -* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt -""" - -import sys - -if len (sys.argv) != 4: - sys.exit (__doc__) - -ALLOWED_SINGLES = [0x00A0, 0x25CC] -ALLOWED_BLOCKS = [ - 'Basic Latin', - 'Latin-1 Supplement', - 'Devanagari', - 'Bengali', - 'Gurmukhi', - 'Gujarati', - 'Oriya', - 'Tamil', - 'Telugu', - 'Kannada', - 'Malayalam', - 'Myanmar', - 'Khmer', - 'Vedic Extensions', - 'General Punctuation', - 'Superscripts and Subscripts', - 'Devanagari Extended', - 'Myanmar Extended-B', - 'Myanmar Extended-A', - 'Myanmar Extended-C', -] - -files = [open (x, encoding='utf-8') for x in sys.argv[1:]] - -headers = [[f.readline () for i in range (2)] for f in files] - -unicode_data = [{} for _ in files] -for i, f in enumerate (files): - for line in f: - - j = line.find ('#') - if j >= 0: - line = line[:j] - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - - t = fields[1] - - for u in range (start, end + 1): - unicode_data[i][u] = t - -# Merge data into one dict: -defaults = ('Other', 'Not_Applicable', 'No_Block') -combined = {} -for i,d in enumerate (unicode_data): - for u,v in d.items (): - if i == 2 and not u in combined: - continue - if not u in combined: - combined[u] = list (defaults) - combined[u][i] = v -combined = {k:v for k,v in combined.items() if k in ALLOWED_SINGLES or v[2] in ALLOWED_BLOCKS} - - -# Convert categories & positions types - -categories = { - 'indic' : [ - 'X', - 'C', - 'V', - 'N', - 'H', - 'ZWNJ', - 'ZWJ', - 'M', - 'SM', - 'A', - 'VD', - 'PLACEHOLDER', - 'DOTTEDCIRCLE', - 'RS', - 'MPst', - 'Repha', - 'Ra', - 'CM', - 'Symbol', - 'CS', - ], - 'khmer' : [ - 'VAbv', - 'VBlw', - 'VPre', - 'VPst', - - 'Robatic', - 'Xgroup', - 'Ygroup', - ], - 'myanmar' : [ - 'VAbv', - 'VBlw', - 'VPre', - 'VPst', - - 'IV', - 'As', - 'DB', - 'GB', - 'MH', - 'MR', - 'MW', - 'MY', - 'PT', - 'VS', - 'ML', - ], -} - -category_map = { - 'Other' : 'X', - 'Avagraha' : 'Symbol', - 'Bindu' : 'SM', - 'Brahmi_Joining_Number' : 'PLACEHOLDER', # Don't care. - 'Cantillation_Mark' : 'A', - 'Consonant' : 'C', - 'Consonant_Dead' : 'C', - 'Consonant_Final' : 'CM', - 'Consonant_Head_Letter' : 'C', - 'Consonant_Initial_Postfixed' : 'C', # TODO - 'Consonant_Killer' : 'M', # U+17CD only. - 'Consonant_Medial' : 'CM', - 'Consonant_Placeholder' : 'PLACEHOLDER', - 'Consonant_Preceding_Repha' : 'Repha', - 'Consonant_Prefixed' : 'X', # Don't care. - 'Consonant_Subjoined' : 'CM', - 'Consonant_Succeeding_Repha' : 'CM', - 'Consonant_With_Stacker' : 'CS', - 'Gemination_Mark' : 'SM', # https://github.com/harfbuzz/harfbuzz/issues/552 - 'Invisible_Stacker' : 'H', - 'Joiner' : 'ZWJ', - 'Modifying_Letter' : 'X', - 'Non_Joiner' : 'ZWNJ', - 'Nukta' : 'N', - 'Number' : 'PLACEHOLDER', - 'Number_Joiner' : 'PLACEHOLDER', # Don't care. - 'Pure_Killer' : 'M', # Is like a vowel matra. - 'Register_Shifter' : 'RS', - 'Syllable_Modifier' : 'SM', - 'Tone_Letter' : 'X', - 'Tone_Mark' : 'N', - 'Virama' : 'H', - 'Visarga' : 'SM', - 'Vowel' : 'V', - 'Vowel_Dependent' : 'M', - 'Vowel_Independent' : 'V', -} -position_map = { - 'Not_Applicable' : 'END', - - 'Left' : 'PRE_C', - 'Top' : 'ABOVE_C', - 'Bottom' : 'BELOW_C', - 'Right' : 'POST_C', - - # These should resolve to the position of the last part of the split sequence. - 'Bottom_And_Right' : 'POST_C', - 'Left_And_Right' : 'POST_C', - 'Top_And_Bottom' : 'BELOW_C', - 'Top_And_Bottom_And_Left' : 'BELOW_C', - 'Top_And_Bottom_And_Right' : 'POST_C', - 'Top_And_Left' : 'ABOVE_C', - 'Top_And_Left_And_Right' : 'POST_C', - 'Top_And_Right' : 'POST_C', - - 'Overstruck' : 'AFTER_MAIN', - 'Visual_order_left' : 'PRE_M', -} - -category_overrides = { - - # These are the variation-selectors. They only appear in the Myanmar grammar - # but are not Myanmar-specific - 0xFE00: 'VS', - 0xFE01: 'VS', - 0xFE02: 'VS', - 0xFE03: 'VS', - 0xFE04: 'VS', - 0xFE05: 'VS', - 0xFE06: 'VS', - 0xFE07: 'VS', - 0xFE08: 'VS', - 0xFE09: 'VS', - 0xFE0A: 'VS', - 0xFE0B: 'VS', - 0xFE0C: 'VS', - 0xFE0D: 'VS', - 0xFE0E: 'VS', - 0xFE0F: 'VS', - - # These appear in the OT Myanmar spec, but are not Myanmar-specific - 0x2015: 'PLACEHOLDER', - 0x2022: 'PLACEHOLDER', - 0x25FB: 'PLACEHOLDER', - 0x25FC: 'PLACEHOLDER', - 0x25FD: 'PLACEHOLDER', - 0x25FE: 'PLACEHOLDER', - - - # Indic - - 0x0930: 'Ra', # Devanagari - 0x09B0: 'Ra', # Bengali - 0x09F0: 'Ra', # Bengali - 0x0A30: 'Ra', # Gurmukhi No Reph - 0x0AB0: 'Ra', # Gujarati - 0x0B30: 'Ra', # Oriya - 0x0BB0: 'Ra', # Tamil No Reph - 0x0C30: 'Ra', # Telugu Reph formed only with ZWJ - 0x0CB0: 'Ra', # Kannada - 0x0D30: 'Ra', # Malayalam No Reph, Logical Repha - - # The following act more like the Bindus. - 0x0953: 'SM', - 0x0954: 'SM', - - # U+0A40 GURMUKHI VOWEL SIGN II may be preceded by U+0A02 GURMUKHI SIGN BINDI. - 0x0A40: 'MPst', - - # The following act like consonants. - 0x0A72: 'C', - 0x0A73: 'C', - 0x1CF5: 'C', - 0x1CF6: 'C', - - # TODO: The following should only be allowed after a Visarga. - # For now, just treat them like regular tone marks. - 0x1CE2: 'A', - 0x1CE3: 'A', - 0x1CE4: 'A', - 0x1CE5: 'A', - 0x1CE6: 'A', - 0x1CE7: 'A', - 0x1CE8: 'A', - - # TODO: The following should only be allowed after some of - # the nasalization marks, maybe only for U+1CE9..U+1CF1. - # For now, just treat them like tone marks. - 0x1CED: 'A', - - # The following take marks in standalone clusters, similar to Avagraha. - 0xA8F2: 'Symbol', - 0xA8F3: 'Symbol', - 0xA8F4: 'Symbol', - 0xA8F5: 'Symbol', - 0xA8F6: 'Symbol', - 0xA8F7: 'Symbol', - 0x1CE9: 'Symbol', - 0x1CEA: 'Symbol', - 0x1CEB: 'Symbol', - 0x1CEC: 'Symbol', - 0x1CEE: 'Symbol', - 0x1CEF: 'Symbol', - 0x1CF0: 'Symbol', - 0x1CF1: 'Symbol', - - 0x0A51: 'M', # https://github.com/harfbuzz/harfbuzz/issues/524 - - # According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, - # so the Indic shaper needs to know their categories. - 0x11301: 'SM', - 0x11302: 'SM', - 0x11303: 'SM', - 0x1133B: 'N', - 0x1133C: 'N', - - 0x0AFB: 'N', # https://github.com/harfbuzz/harfbuzz/issues/552 - 0x0B55: 'N', # https://github.com/harfbuzz/harfbuzz/issues/2849 - - 0x09FC: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/pull/1613 - 0x0C80: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/pull/623 - 0x0D04: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/pull/3511 - - 0x25CC: 'DOTTEDCIRCLE', - - - # Khmer - - 0x179A: 'Ra', - - 0x17CC: 'Robatic', - 0x17C9: 'Robatic', - 0x17CA: 'Robatic', - - 0x17C6: 'Xgroup', - 0x17CB: 'Xgroup', - 0x17CD: 'Xgroup', - 0x17CE: 'Xgroup', - 0x17CF: 'Xgroup', - 0x17D0: 'Xgroup', - 0x17D1: 'Xgroup', - - 0x17C7: 'Ygroup', - 0x17C8: 'Ygroup', - 0x17DD: 'Ygroup', - 0x17D3: 'Ygroup', # Just guessing. Uniscribe doesn't categorize it. - - 0x17D9: 'PLACEHOLDER', # https://github.com/harfbuzz/harfbuzz/issues/2384 - - - # Myanmar - - # https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze - - 0x104E: 'C', # The spec says C, IndicSyllableCategory says Consonant_Placeholder - - 0x1004: 'Ra', - 0x101B: 'Ra', - 0x105A: 'Ra', - - 0x1032: 'A', - 0x1036: 'A', - - 0x103A: 'As', - - #0x1040: 'D0', # XXX The spec says D0, but Uniscribe doesn't seem to do. - - 0x103E: 'MH', - 0x1060: 'ML', - 0x103C: 'MR', - 0x103D: 'MW', - 0x1082: 'MW', - 0x103B: 'MY', - 0x105E: 'MY', - 0x105F: 'MY', - - 0x1063: 'PT', - 0x1064: 'PT', - 0x1069: 'PT', - 0x106A: 'PT', - 0x106B: 'PT', - 0x106C: 'PT', - 0x106D: 'PT', - 0xAA7B: 'PT', - - 0x1038: 'SM', - 0x1087: 'SM', - 0x1088: 'SM', - 0x1089: 'SM', - 0x108A: 'SM', - 0x108B: 'SM', - 0x108C: 'SM', - 0x108D: 'SM', - 0x108F: 'SM', - 0x109A: 'SM', - 0x109B: 'SM', - 0x109C: 'SM', - - 0x104A: 'PLACEHOLDER', -} -position_overrides = { - - 0x0A51: 'BELOW_C', # https://github.com/harfbuzz/harfbuzz/issues/524 - - 0x0B01: 'BEFORE_SUB', # Oriya Bindu is BeforeSub in the spec. -} - -def matra_pos_left(u, block): - return "PRE_M" -def matra_pos_right(u, block): - if block == 'Devanagari': return 'AFTER_SUB' - if block == 'Bengali': return 'AFTER_POST' - if block == 'Gurmukhi': return 'AFTER_POST' - if block == 'Gujarati': return 'AFTER_POST' - if block == 'Oriya': return 'AFTER_POST' - if block == 'Tamil': return 'AFTER_POST' - if block == 'Telugu': return 'BEFORE_SUB' if u <= 0x0C42 else 'AFTER_SUB' - if block == 'Kannada': return 'BEFORE_SUB' if u < 0x0CC3 or u > 0x0CD6 else 'AFTER_SUB' - if block == 'Malayalam': return 'AFTER_POST' - return 'AFTER_SUB' -def matra_pos_top(u, block): - # BENG and MLYM don't have top matras. - if block == 'Devanagari': return 'AFTER_SUB' - if block == 'Gurmukhi': return 'AFTER_POST' # Deviate from spec - if block == 'Gujarati': return 'AFTER_SUB' - if block == 'Oriya': return 'AFTER_MAIN' - if block == 'Tamil': return 'AFTER_SUB' - if block == 'Telugu': return 'BEFORE_SUB' - if block == 'Kannada': return 'BEFORE_SUB' - return 'AFTER_SUB' -def matra_pos_bottom(u, block): - if block == 'Devanagari': return 'AFTER_SUB' - if block == 'Bengali': return 'AFTER_SUB' - if block == 'Gurmukhi': return 'AFTER_POST' - if block == 'Gujarati': return 'AFTER_POST' - if block == 'Oriya': return 'AFTER_SUB' - if block == 'Tamil': return 'AFTER_POST' - if block == 'Telugu': return 'BEFORE_SUB' - if block == 'Kannada': return 'BEFORE_SUB' - if block == 'Malayalam': return 'AFTER_POST' - return "AFTER_SUB" -def indic_matra_position(u, pos, block): # Reposition matra - if pos == 'PRE_C': return matra_pos_left(u, block) - if pos == 'POST_C': return matra_pos_right(u, block) - if pos == 'ABOVE_C': return matra_pos_top(u, block) - if pos == 'BELOW_C': return matra_pos_bottom(u, block) - assert (False) - -def position_to_category(pos): - if pos == 'PRE_C': return 'VPre' - if pos == 'ABOVE_C': return 'VAbv' - if pos == 'BELOW_C': return 'VBlw' - if pos == 'POST_C': return 'VPst' - assert(False) - - -defaults = (category_map[defaults[0]], position_map[defaults[1]], defaults[2]) - -indic_data = {} -for k, (cat, pos, block) in combined.items(): - cat = category_map[cat] - pos = position_map[pos] - indic_data[k] = (cat, pos, block) - -for k,new_cat in category_overrides.items(): - (cat, pos, _) = indic_data.get(k, defaults) - indic_data[k] = (new_cat, pos, unicode_data[2][k]) - -# We only expect position for certain types -positioned_categories = ('CM', 'SM', 'RS', 'H', 'M', 'MPst') -for k, (cat, pos, block) in indic_data.items(): - if cat not in positioned_categories: - pos = 'END' - indic_data[k] = (cat, pos, block) - -# Position overrides are more complicated - -# Keep in sync with CONSONANT_FLAGS in the shaper -consonant_categories = ('C', 'CS', 'Ra','CM', 'V', 'PLACEHOLDER', 'DOTTEDCIRCLE') -matra_categories = ('M', 'MPst') -smvd_categories = ('SM', 'VD', 'A', 'Symbol') -for k, (cat, pos, block) in indic_data.items(): - if cat in consonant_categories: - pos = 'BASE_C' - elif cat in matra_categories: - if block.startswith('Khmer') or block.startswith('Myanmar'): - cat = position_to_category(pos) - else: - pos = indic_matra_position(k, pos, block) - elif cat in smvd_categories: - pos = 'SMVD'; - indic_data[k] = (cat, pos, block) - -for k,new_pos in position_overrides.items(): - (cat, pos, _) = indic_data.get(k, defaults) - indic_data[k] = (cat, new_pos, unicode_data[2][k]) - - -values = [{_: 1} for _ in defaults] -for vv in indic_data.values(): - for i,v in enumerate(vv): - values[i][v] = values[i].get (v, 0) + 1 - - - - -# Move the outliers NO-BREAK SPACE and DOTTED CIRCLE out -singles = {} -for u in ALLOWED_SINGLES: - singles[u] = indic_data[u] - del indic_data[u] - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following table is generated by running:") -print (" *") -print (" * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt") -print (" *") -print (" * on files with these headers:") -print (" *") -for h in headers: - for l in h: - print (" * %s" % (l.strip())) -print (" */") -print () -print ('#include "hb.hh"') -print () -print ('#ifndef HB_NO_OT_SHAPE') -print () -print ('#include "hb-ot-shaper-indic.hh"') -print () -print ('#pragma GCC diagnostic push') -print ('#pragma GCC diagnostic ignored "-Wunused-macros"') -print () - -# Print categories -for shaper in categories: - print ('#include "hb-ot-shaper-%s-machine.hh"' % shaper) -print () -done = {} -for shaper, shaper_cats in categories.items(): - print ('/* %s */' % shaper) - for cat in shaper_cats: - v = shaper[0].upper() - if cat not in done: - print ("#define OT_%s %s_Cat(%s)" % (cat, v, cat)) - done[cat] = v - else: - print ('static_assert (OT_%s == %s_Cat(%s), "");' % (cat, v, cat)) -print () - -# Shorten values -short = [{ - "Repha": 'Rf', - "PLACEHOLDER": 'GB', - "DOTTEDCIRCLE": 'DC', - "VPst": 'VR', - "VPre": 'VL', - "Robatic": 'Rt', - "Xgroup": 'Xg', - "Ygroup": 'Yg', - "As": 'As', -},{ - "END": 'X', - "BASE_C": 'C', - "ABOVE_C": 'T', - "BELOW_C": 'B', - "POST_C": 'R', - "PRE_C": 'L', - "PRE_M": 'LM', - "AFTER_MAIN": 'A', - "AFTER_SUB": 'AS', - "BEFORE_SUB": 'BS', - "AFTER_POST": 'AP', - "SMVD": 'SM', -}] -all_shorts = [{},{}] - -# Add some of the values, to make them more readable, and to avoid duplicates - -for i in range (2): - for v,s in short[i].items (): - all_shorts[i][s] = v - -what = ["OT", "POS"] -what_short = ["_OT", "_POS"] -cat_defs = [] -for i in range (2): - vv = sorted (values[i].keys ()) - for v in vv: - v_no_and = v.replace ('_And_', '_') - if v in short[i]: - s = short[i][v] - else: - s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')]) - if s in all_shorts[i]: - raise Exception ("Duplicate short value alias", v, all_shorts[i][s]) - all_shorts[i][s] = v - short[i][v] = s - cat_defs.append ((what_short[i] + '_' + s, what[i] + '_' + (v.upper () if i else v), str (values[i][v]), v)) - -maxlen_s = max ([len (c[0]) for c in cat_defs]) -maxlen_l = max ([len (c[1]) for c in cat_defs]) -maxlen_n = max ([len (c[2]) for c in cat_defs]) -for s in what_short: - print () - for c in [c for c in cat_defs if s in c[0]]: - print ("#define %s %s /* %s chars; %s */" % - (c[0].ljust (maxlen_s), c[1].ljust (maxlen_l), c[2].rjust (maxlen_n), c[3])) -print () -print ('#pragma GCC diagnostic pop') -print () -print ("#define INDIC_COMBINE_CATEGORIES(S,M) ((S) | ((M) << 8))") -print () -print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (%s_##S, %s_##M)" % tuple(what_short)) -print () -print () - -total = 0 -used = 0 -last_block = None -def print_block (block, start, end, data): - global total, used, last_block - if block and block != last_block: - print () - print () - print (" /* %s */" % block) - num = 0 - assert start % 8 == 0 - assert (end+1) % 8 == 0 - for u in range (start, end+1): - if u % 8 == 0: - print () - print (" /* %04X */" % u, end="") - if u in data: - num += 1 - d = data.get (u, defaults) - print ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])), end="") - - total += end - start + 1 - used += num - if block: - last_block = block - -uu = sorted (indic_data) - -last = -100000 -num = 0 -offset = 0 -starts = [] -ends = [] -print ("static const uint16_t indic_table[] = {") -for u in uu: - if u <= last: - continue - block = indic_data[u][2] - - start = u//8*8 - end = start+1 - while end in uu and block == indic_data[end][2]: - end += 1 - end = (end-1)//8*8 + 7 - - if start != last + 1: - if start - last <= 1+16*2: - print_block (None, last+1, start-1, indic_data) - else: - if last >= 0: - ends.append (last + 1) - offset += ends[-1] - starts[-1] - print () - print () - print ("#define indic_offset_0x%04xu %d" % (start, offset)) - starts.append (start) - - print_block (block, start, end, indic_data) - last = end -ends.append (last + 1) -offset += ends[-1] - starts[-1] -print () -print () -occupancy = used * 100. / total -page_bits = 12 -print ("}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)) -print () -print ("uint16_t") -print ("hb_indic_get_categories (hb_codepoint_t u)") -print ("{") -print (" switch (u >> %d)" % page_bits) -print (" {") -pages = set ([u>>page_bits for u in starts+ends+list (singles.keys ())]) -for p in sorted(pages): - print (" case 0x%0Xu:" % p) - for u,d in singles.items (): - if p != u>>page_bits: continue - print (" if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])) - for (start,end) in zip (starts, ends): - if p not in [start>>page_bits, end>>page_bits]: continue - offset = "indic_offset_0x%04xu" % start - print (" if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)) - print (" break;") - print ("") -print (" default:") -print (" break;") -print (" }") -print (" return _(X,X);") -print ("}") -print () -print ("#undef _") -print ("#undef INDIC_COMBINE_CATEGORIES") -for i in range (2): - print () - vv = sorted (values[i].keys ()) - for v in vv: - print ("#undef %s_%s" % - (what_short[i], short[i][v])) -print () -print ('#endif') -print () -print ("/* == End of generated table == */") - -# Maintain at least 50% occupancy in the table */ -if occupancy < 50: - raise Exception ("Table too sparse, please investigate: ", occupancy) diff --git a/thirdparty/harfbuzz/upstream/gen-os2-unicode-ranges.py b/thirdparty/harfbuzz/upstream/gen-os2-unicode-ranges.py deleted file mode 100755 index b1a34d478..000000000 --- a/thirdparty/harfbuzz/upstream/gen-os2-unicode-ranges.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -"""Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh -Input is a tab separated list of unicode ranges from the otspec -(https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur). -""" - -import re -import sys - - -print ("""static OS2Range _hb_os2_unicode_ranges[] = -{""") - -args = sys.argv[1:] -input_file = args[0] - -with open (input_file, mode="r", encoding="utf-8") as f: - - all_ranges = [] - current_bit = 0 - while True: - line = f.readline().strip() - if not line: - break - fields = re.split(r'\t+', line) - if len(fields) == 3: - current_bit = fields[0] - fields = fields[1:] - elif len(fields) > 3: - raise Exception("bad input :(.") - - name = fields[0] - ranges = re.split("-", fields[1]) - if len(ranges) != 2: - raise Exception("bad input :(.") - - v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name)) - all_ranges.append(v) - -all_ranges = sorted(all_ranges, key=lambda t: t[0]) - -for ranges in all_ranges: - start = ("0x%X" % ranges[0]).rjust(8) - end = ("0x%X" % ranges[1]).rjust(8) - bit = ("%s" % ranges[2]).rjust(3) - - print (" {%s, %s, %s}, // %s" % (start, end, bit, ranges[3])) - -print ("""};""") diff --git a/thirdparty/harfbuzz/upstream/gen-ragel-artifacts.py b/thirdparty/harfbuzz/upstream/gen-ragel-artifacts.py deleted file mode 100755 index 8bbb375bf..000000000 --- a/thirdparty/harfbuzz/upstream/gen-ragel-artifacts.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -"This tool is intended to be used from meson" - -import os, os.path, sys, subprocess, shutil - -ragel = sys.argv[1] -if not ragel: - sys.exit ('You have to install ragel if you are going to develop HarfBuzz itself') - -if len (sys.argv) < 4: - sys.exit (__doc__) - -OUTPUT = sys.argv[2] -CURRENT_SOURCE_DIR = sys.argv[3] -INPUT = sys.argv[4] - -outdir = os.path.dirname (OUTPUT) -shutil.copy (INPUT, outdir) -rl = os.path.basename (INPUT) -hh = rl.replace ('.rl', '.hh') -subprocess.Popen (ragel.split() + ['-e', '-F1', '-o', hh, rl], cwd=outdir).wait () - -# copy it also to src/ -shutil.copyfile (os.path.join (outdir, hh), os.path.join (CURRENT_SOURCE_DIR, hh)) diff --git a/thirdparty/harfbuzz/upstream/gen-tag-table.py b/thirdparty/harfbuzz/upstream/gen-tag-table.py deleted file mode 100755 index 9bb8f917a..000000000 --- a/thirdparty/harfbuzz/upstream/gen-tag-table.py +++ /dev/null @@ -1,1220 +0,0 @@ -#!/usr/bin/env python3 - -"""Generator of the mapping from OpenType tags to BCP 47 tags and vice -versa. - -It creates a ``const LangTag[]``, matching the tags from the OpenType -languages system tag list to the language subtags of the BCP 47 language -subtag registry, with some manual adjustments. The mappings are -supplemented with macrolanguages' sublanguages and retired codes' -replacements, according to BCP 47 and some manual additions where BCP 47 -omits a retired code entirely. - -Also generated is a function, ``hb_ot_ambiguous_tag_to_language``, -intended for use by ``hb_ot_tag_to_language``. It maps OpenType tags -back to BCP 47 tags. Ambiguous OpenType tags (those that correspond to -multiple BCP 47 tags) are listed here, except when the alphabetically -first BCP 47 tag happens to be the chosen disambiguated tag. In that -case, the fallback behavior will choose the right tag anyway. - -usage: ./gen-tag-table.py languagetags language-subtag-registry - -Input files: -* https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags -* https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry -""" - -import collections -import html -from html.parser import HTMLParser -import itertools -import re -import sys -import unicodedata - -if len (sys.argv) != 3: - sys.exit (__doc__) - -def expect (condition, message=None): - if not condition: - if message is None: - raise AssertionError - raise AssertionError (message) - -def write (s): - sys.stdout.flush () - sys.stdout.buffer.write (s.encode ('utf-8')) - -DEFAULT_LANGUAGE_SYSTEM = '' - -# from https://www-01.sil.org/iso639-3/iso-639-3.tab -ISO_639_3_TO_1 = { - 'aar': 'aa', - 'abk': 'ab', - 'afr': 'af', - 'aka': 'ak', - 'amh': 'am', - 'ara': 'ar', - 'arg': 'an', - 'asm': 'as', - 'ava': 'av', - 'ave': 'ae', - 'aym': 'ay', - 'aze': 'az', - 'bak': 'ba', - 'bam': 'bm', - 'bel': 'be', - 'ben': 'bn', - 'bis': 'bi', - 'bod': 'bo', - 'bos': 'bs', - 'bre': 'br', - 'bul': 'bg', - 'cat': 'ca', - 'ces': 'cs', - 'cha': 'ch', - 'che': 'ce', - 'chu': 'cu', - 'chv': 'cv', - 'cor': 'kw', - 'cos': 'co', - 'cre': 'cr', - 'cym': 'cy', - 'dan': 'da', - 'deu': 'de', - 'div': 'dv', - 'dzo': 'dz', - 'ell': 'el', - 'eng': 'en', - 'epo': 'eo', - 'est': 'et', - 'eus': 'eu', - 'ewe': 'ee', - 'fao': 'fo', - 'fas': 'fa', - 'fij': 'fj', - 'fin': 'fi', - 'fra': 'fr', - 'fry': 'fy', - 'ful': 'ff', - 'gla': 'gd', - 'gle': 'ga', - 'glg': 'gl', - 'glv': 'gv', - 'grn': 'gn', - 'guj': 'gu', - 'hat': 'ht', - 'hau': 'ha', - 'hbs': 'sh', - 'heb': 'he', - 'her': 'hz', - 'hin': 'hi', - 'hmo': 'ho', - 'hrv': 'hr', - 'hun': 'hu', - 'hye': 'hy', - 'ibo': 'ig', - 'ido': 'io', - 'iii': 'ii', - 'iku': 'iu', - 'ile': 'ie', - 'ina': 'ia', - 'ind': 'id', - 'ipk': 'ik', - 'isl': 'is', - 'ita': 'it', - 'jav': 'jv', - 'jpn': 'ja', - 'kal': 'kl', - 'kan': 'kn', - 'kas': 'ks', - 'kat': 'ka', - 'kau': 'kr', - 'kaz': 'kk', - 'khm': 'km', - 'kik': 'ki', - 'kin': 'rw', - 'kir': 'ky', - 'kom': 'kv', - 'kon': 'kg', - 'kor': 'ko', - 'kua': 'kj', - 'kur': 'ku', - 'lao': 'lo', - 'lat': 'la', - 'lav': 'lv', - 'lim': 'li', - 'lin': 'ln', - 'lit': 'lt', - 'ltz': 'lb', - 'lub': 'lu', - 'lug': 'lg', - 'mah': 'mh', - 'mal': 'ml', - 'mar': 'mr', - 'mkd': 'mk', - 'mlg': 'mg', - 'mlt': 'mt', - 'mol': 'mo', - 'mon': 'mn', - 'mri': 'mi', - 'msa': 'ms', - 'mya': 'my', - 'nau': 'na', - 'nav': 'nv', - 'nbl': 'nr', - 'nde': 'nd', - 'ndo': 'ng', - 'nep': 'ne', - 'nld': 'nl', - 'nno': 'nn', - 'nob': 'nb', - 'nor': 'no', - 'nya': 'ny', - 'oci': 'oc', - 'oji': 'oj', - 'ori': 'or', - 'orm': 'om', - 'oss': 'os', - 'pan': 'pa', - 'pli': 'pi', - 'pol': 'pl', - 'por': 'pt', - 'pus': 'ps', - 'que': 'qu', - 'roh': 'rm', - 'ron': 'ro', - 'run': 'rn', - 'rus': 'ru', - 'sag': 'sg', - 'san': 'sa', - 'sin': 'si', - 'slk': 'sk', - 'slv': 'sl', - 'sme': 'se', - 'smo': 'sm', - 'sna': 'sn', - 'snd': 'sd', - 'som': 'so', - 'sot': 'st', - 'spa': 'es', - 'sqi': 'sq', - 'srd': 'sc', - 'srp': 'sr', - 'ssw': 'ss', - 'sun': 'su', - 'swa': 'sw', - 'swe': 'sv', - 'tah': 'ty', - 'tam': 'ta', - 'tat': 'tt', - 'tel': 'te', - 'tgk': 'tg', - 'tgl': 'tl', - 'tha': 'th', - 'tir': 'ti', - 'ton': 'to', - 'tsn': 'tn', - 'tso': 'ts', - 'tuk': 'tk', - 'tur': 'tr', - 'twi': 'tw', - 'uig': 'ug', - 'ukr': 'uk', - 'urd': 'ur', - 'uzb': 'uz', - 'ven': 've', - 'vie': 'vi', - 'vol': 'vo', - 'wln': 'wa', - 'wol': 'wo', - 'xho': 'xh', - 'yid': 'yi', - 'yor': 'yo', - 'zha': 'za', - 'zho': 'zh', - 'zul': 'zu', -} - -class LanguageTag (object): - """A BCP 47 language tag. - - Attributes: - subtags (List[str]): The list of subtags in this tag. - grandfathered (bool): Whether this tag is grandfathered. If - ``true``, the entire lowercased tag is the ``language`` - and the other subtag fields are empty. - language (str): The language subtag. - script (str): The script subtag. - region (str): The region subtag. - variant (str): The variant subtag. - - Args: - tag (str): A BCP 47 language tag. - - """ - def __init__ (self, tag): - global bcp_47 - self.subtags = tag.lower ().split ('-') - self.grandfathered = tag.lower () in bcp_47.grandfathered - if self.grandfathered: - self.language = tag.lower () - self.script = '' - self.region = '' - self.variant = '' - else: - self.language = self.subtags[0] - self.script = self._find_first (lambda s: len (s) == 4 and s[0] > '9', self.subtags) - self.region = self._find_first (lambda s: len (s) == 2 and s[0] > '9' or len (s) == 3 and s[0] <= '9', self.subtags[1:]) - self.variant = self._find_first (lambda s: len (s) > 4 or len (s) == 4 and s[0] <= '9', self.subtags) - - def __str__(self): - return '-'.join(self.subtags) - - def __repr__ (self): - return 'LanguageTag(%r)' % str(self) - - @staticmethod - def _find_first (function, sequence): - try: - return next (iter (filter (function, sequence))) - except StopIteration: - return None - - def is_complex (self): - """Return whether this tag is too complex to represent as a - ``LangTag`` in the generated code. - - Complex tags need to be handled in - ``hb_ot_tags_from_complex_language``. - - Returns: - Whether this tag is complex. - """ - return not (len (self.subtags) == 1 - or self.grandfathered - and len (self.subtags[1]) != 3 - and ot.from_bcp_47[self.subtags[0]] == ot.from_bcp_47[self.language]) - - def get_group (self): - """Return the group into which this tag should be categorized in - ``hb_ot_tags_from_complex_language``. - - The group is the first letter of the tag, or ``'und'`` if this tag - should not be matched in a ``switch`` statement in the generated - code. - - Returns: - This tag's group. - """ - return ('und' - if (self.language == 'und' - or self.variant in bcp_47.prefixes and len (bcp_47.prefixes[self.variant]) == 1) - else self.language[0]) - -class OpenTypeRegistryParser (HTMLParser): - """A parser for the OpenType language system tag registry. - - Attributes: - header (str): The "last updated" line of the registry. - names (Mapping[str, str]): A map of language system tags to the - names they are given in the registry. - ranks (DefaultDict[str, int]): A map of language system tags to - numbers. If a single BCP 47 tag corresponds to multiple - OpenType tags, the tags are ordered in increasing order by - rank. The rank is based on the number of BCP 47 tags - associated with a tag, though it may be manually modified. - to_bcp_47 (DefaultDict[str, AbstractSet[str]]): A map of - OpenType language system tags to sets of BCP 47 tags. - from_bcp_47 (DefaultDict[str, AbstractSet[str]]): ``to_bcp_47`` - inverted. Its values start as unsorted sets; - ``sort_languages`` converts them to sorted lists. - from_bcp_47_uninherited (Optional[Dict[str, AbstractSet[str]]]): - A copy of ``from_bcp_47``. It starts as ``None`` and is - populated at the beginning of the first call to - ``inherit_from_macrolanguages``. - - """ - def __init__ (self): - HTMLParser.__init__ (self) - self.header = '' - self.names = {} - self.ranks = collections.defaultdict (int) - self.to_bcp_47 = collections.defaultdict (set) - self.from_bcp_47 = collections.defaultdict (set) - self.from_bcp_47_uninherited = None - # Whether the parser is in a element - self._td = False - # Whether the parser ignores the rest of the current element - self._disengaged = False - # The text of the elements of the current
element. - self._current_tr = [] - - def handle_starttag (self, tag, attrs): - if tag == 'a': - if self._current_tr and not self._disengaged: - self._current_tr[-1] = '' - self._disengaged = True - elif tag == 'br': - self._disengaged = True - elif tag == 'meta': - for attr, value in attrs: - if attr == 'name' and value == 'updated_at': - self.header = self.get_starttag_text () - break - elif tag == 'td': - self._td = True - self._current_tr.append ('') - elif tag == 'tr': - self._disengaged = False - self._current_tr = [] - - def handle_endtag (self, tag): - if tag == 'td': - self._td = False - self._disengaged = False - elif tag == 'tr' and self._current_tr: - expect (2 <= len (self._current_tr) <= 3) - name = self._current_tr[0].strip () - tag = self._current_tr[1].strip ("\t\n\v\f\r '") - rank = 0 - if len (tag) > 4: - expect (tag.endswith (' (deprecated)'), 'ill-formed OpenType tag: %s' % tag) - name += ' (deprecated)' - tag = tag.split (' ')[0] - rank = 1 - self.names[tag] = re.sub (' languages$', '', name) - if not self._current_tr[2]: - return - iso_codes = self._current_tr[2].strip () - self.to_bcp_47[tag].update (ISO_639_3_TO_1.get (code, code) for code in iso_codes.replace (' ', '').split (',')) - rank += 2 * len (self.to_bcp_47[tag]) - self.ranks[tag] = rank - - def handle_data (self, data): - if self._td and not self._disengaged: - self._current_tr[-1] += data - - def handle_charref (self, name): - self.handle_data (html.unescape ('&#%s;' % name)) - - def handle_entityref (self, name): - self.handle_data (html.unescape ('&%s;' % name)) - - def parse (self, filename): - """Parse the OpenType language system tag registry. - - Args: - filename (str): The file name of the registry. - """ - with open (filename, encoding='utf-8') as f: - self.feed (f.read ()) - expect (self.header) - for tag, iso_codes in self.to_bcp_47.items (): - for iso_code in iso_codes: - self.from_bcp_47[iso_code].add (tag) - - def add_language (self, bcp_47_tag, ot_tag): - """Add a language as if it were in the registry. - - Args: - bcp_47_tag (str): A BCP 47 tag. If the tag is more than just - a language subtag, and if the language subtag is a - macrolanguage, then new languages are added corresponding - to the macrolanguages' individual languages with the - remainder of the tag appended. - ot_tag (str): An OpenType language system tag. - """ - global bcp_47 - self.to_bcp_47[ot_tag].add (bcp_47_tag) - self.from_bcp_47[bcp_47_tag].add (ot_tag) - if bcp_47_tag.lower () not in bcp_47.grandfathered: - try: - [macrolanguage, suffix] = bcp_47_tag.split ('-', 1) - if macrolanguage in bcp_47.macrolanguages: - s = set () - for language in bcp_47.macrolanguages[macrolanguage]: - if language.lower () not in bcp_47.grandfathered: - s.add ('%s-%s' % (language, suffix)) - bcp_47.macrolanguages['%s-%s' % (macrolanguage, suffix)] = s - except ValueError: - pass - - @staticmethod - def _remove_language (tag_1, dict_1, dict_2): - for tag_2 in dict_1.pop (tag_1): - dict_2[tag_2].remove (tag_1) - if not dict_2[tag_2]: - del dict_2[tag_2] - - def remove_language_ot (self, ot_tag): - """Remove an OpenType tag from the registry. - - Args: - ot_tag (str): An OpenType tag. - """ - self._remove_language (ot_tag, self.to_bcp_47, self.from_bcp_47) - - def remove_language_bcp_47 (self, bcp_47_tag): - """Remove a BCP 47 tag from the registry. - - Args: - bcp_47_tag (str): A BCP 47 tag. - """ - self._remove_language (bcp_47_tag, self.from_bcp_47, self.to_bcp_47) - - def inherit_from_macrolanguages (self): - """Copy mappings from macrolanguages to individual languages. - - If a BCP 47 tag for an individual mapping has no OpenType - mapping but its macrolanguage does, the mapping is copied to - the individual language. For example, als (Tosk Albanian) has no - explicit mapping, so it inherits from sq (Albanian) the mapping - to SQI. - - However, if an OpenType tag maps to a BCP 47 macrolanguage and - some but not all of its individual languages, the mapping is not - inherited from the macrolanguage to the missing individual - languages. For example, INUK (Nunavik Inuktitut) is mapped to - ike (Eastern Canadian Inuktitut) and iu (Inuktitut) but not to - ikt (Inuinnaqtun, which is an individual language of iu), so - this method does not add a mapping from ikt to INUK. - - If a BCP 47 tag for a macrolanguage has no OpenType mapping but - some of its individual languages do, their mappings are copied - to the macrolanguage. - """ - global bcp_47 - first_time = self.from_bcp_47_uninherited is None - if first_time: - self.from_bcp_47_uninherited = dict (self.from_bcp_47) - for macrolanguage, languages in dict (bcp_47.macrolanguages).items (): - ot_macrolanguages = { - ot_macrolanguage for ot_macrolanguage in self.from_bcp_47_uninherited.get (macrolanguage, set ()) - } - blocked_ot_macrolanguages = set () - if 'retired code' not in bcp_47.scopes.get (macrolanguage, ''): - for ot_macrolanguage in ot_macrolanguages: - round_trip_macrolanguages = { - l for l in self.to_bcp_47[ot_macrolanguage] - if 'retired code' not in bcp_47.scopes.get (l, '') - } - round_trip_languages = { - l for l in languages - if 'retired code' not in bcp_47.scopes.get (l, '') - } - intersection = round_trip_macrolanguages & round_trip_languages - if intersection and intersection != round_trip_languages: - blocked_ot_macrolanguages.add (ot_macrolanguage) - if ot_macrolanguages: - for ot_macrolanguage in ot_macrolanguages: - if ot_macrolanguage not in blocked_ot_macrolanguages: - for language in languages: - self.add_language (language, ot_macrolanguage) - if not blocked_ot_macrolanguages: - self.ranks[ot_macrolanguage] += 1 - elif first_time: - for language in languages: - if language in self.from_bcp_47_uninherited: - ot_macrolanguages |= self.from_bcp_47_uninherited[language] - else: - ot_macrolanguages.clear () - if not ot_macrolanguages: - break - for ot_macrolanguage in ot_macrolanguages: - self.add_language (macrolanguage, ot_macrolanguage) - - def sort_languages (self): - """Sort the values of ``from_bcp_47`` in ascending rank order.""" - for language, tags in self.from_bcp_47.items (): - self.from_bcp_47[language] = sorted (tags, - key=lambda t: (self.ranks[t] + rank_delta (language, t), t)) - -ot = OpenTypeRegistryParser () - -class BCP47Parser (object): - """A parser for the BCP 47 subtag registry. - - Attributes: - header (str): The "File-Date" line of the registry. - names (Mapping[str, str]): A map of subtags to the names they - are given in the registry. Each value is a - ``'\\n'``-separated list of names. - scopes (Mapping[str, str]): A map of language subtags to strings - suffixed to language names, including suffixes to explain - language scopes. - macrolanguages (DefaultDict[str, AbstractSet[str]]): A map of - language subtags to the sets of language subtags which - inherit from them. See - ``OpenTypeRegistryParser.inherit_from_macrolanguages``. - prefixes (DefaultDict[str, AbstractSet[str]]): A map of variant - subtags to their prefixes. - grandfathered (AbstractSet[str]): The set of grandfathered tags, - normalized to lowercase. - - """ - def __init__ (self): - self.header = '' - self.names = {} - self.scopes = {} - self.macrolanguages = collections.defaultdict (set) - self.prefixes = collections.defaultdict (set) - self.grandfathered = set () - - def parse (self, filename): - """Parse the BCP 47 subtag registry. - - Args: - filename (str): The file name of the registry. - """ - with open (filename, encoding='utf-8') as f: - subtag_type = None - subtag = None - deprecated = False - has_preferred_value = False - line_buffer = '' - for line in itertools.chain (f, ['']): - line = line.rstrip () - if line.startswith (' '): - line_buffer += line[1:] - continue - line, line_buffer = line_buffer, line - if line.startswith ('Type: '): - subtag_type = line.split (' ')[1] - deprecated = False - has_preferred_value = False - elif line.startswith ('Subtag: ') or line.startswith ('Tag: '): - subtag = line.split (' ')[1] - if subtag_type == 'grandfathered': - self.grandfathered.add (subtag.lower ()) - elif line.startswith ('Description: '): - description = line.split (' ', 1)[1].replace (' (individual language)', '') - description = re.sub (r' (\(family\)|\((individual |macro)language\)|languages)$', '', - description) - if subtag in self.names: - self.names[subtag] += '\n' + description - else: - self.names[subtag] = description - elif subtag_type == 'language' or subtag_type == 'grandfathered': - if line.startswith ('Scope: '): - scope = line.split (' ')[1] - if scope == 'macrolanguage': - scope = ' [macrolanguage]' - elif scope == 'collection': - scope = ' [collection]' - else: - continue - self.scopes[subtag] = scope - elif line.startswith ('Deprecated: '): - self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') - deprecated = True - elif deprecated and line.startswith ('Comments: see '): - # If a subtag is split into multiple replacement subtags, - # it essentially represents a macrolanguage. - for language in line.replace (',', '').split (' ')[2:]: - self._add_macrolanguage (subtag, language) - elif line.startswith ('Preferred-Value: '): - # If a subtag is deprecated in favor of a single replacement subtag, - # it is either a dialect or synonym of the preferred subtag. Either - # way, it is close enough to the truth to consider the replacement - # the macrolanguage of the deprecated language. - has_preferred_value = True - macrolanguage = line.split (' ')[1] - self._add_macrolanguage (macrolanguage, subtag) - elif not has_preferred_value and line.startswith ('Macrolanguage: '): - self._add_macrolanguage (line.split (' ')[1], subtag) - elif subtag_type == 'variant': - if line.startswith ('Deprecated: '): - self.scopes[subtag] = ' (retired code)' + self.scopes.get (subtag, '') - elif line.startswith ('Prefix: '): - self.prefixes[subtag].add (line.split (' ')[1]) - elif line.startswith ('File-Date: '): - self.header = line - expect (self.header) - - def _add_macrolanguage (self, macrolanguage, language): - global ot - if language not in ot.from_bcp_47: - for l in self.macrolanguages.get (language, set ()): - self._add_macrolanguage (macrolanguage, l) - if macrolanguage not in ot.from_bcp_47: - for ls in list (self.macrolanguages.values ()): - if macrolanguage in ls: - ls.add (language) - return - self.macrolanguages[macrolanguage].add (language) - - def remove_extra_macrolanguages (self): - """Make every language have at most one macrolanguage.""" - inverted = collections.defaultdict (list) - for macrolanguage, languages in self.macrolanguages.items (): - for language in languages: - inverted[language].append (macrolanguage) - for language, macrolanguages in inverted.items (): - if len (macrolanguages) > 1: - macrolanguages.sort (key=lambda ml: len (self.macrolanguages[ml])) - biggest_macrolanguage = macrolanguages.pop () - for macrolanguage in macrolanguages: - self._add_macrolanguage (biggest_macrolanguage, macrolanguage) - - def _get_name_piece (self, subtag): - """Return the first name of a subtag plus its scope suffix. - - Args: - subtag (str): A BCP 47 subtag. - - Returns: - The name form of ``subtag``. - """ - return self.names[subtag].split ('\n')[0] + self.scopes.get (subtag, '') - - def get_name (self, lt): - """Return the names of the subtags in a language tag. - - Args: - lt (LanguageTag): A BCP 47 language tag. - - Returns: - The name form of ``lt``. - """ - name = self._get_name_piece (lt.language) - if lt.script: - name += '; ' + self._get_name_piece (lt.script.title ()) - if lt.region: - name += '; ' + self._get_name_piece (lt.region.upper ()) - if lt.variant: - name += '; ' + self._get_name_piece (lt.variant) - return name - -bcp_47 = BCP47Parser () - -ot.parse (sys.argv[1]) -bcp_47.parse (sys.argv[2]) - -ot.add_language ('ary', 'MOR') - -ot.add_language ('ath', 'ATH') - -ot.add_language ('bai', 'BML') - -ot.ranks['BAL'] = ot.ranks['KAR'] + 1 - -ot.add_language ('ber', 'BBR') - -ot.remove_language_ot ('PGR') -ot.add_language ('el-polyton', 'PGR') - -bcp_47.names['flm'] = 'Falam Chin' -bcp_47.scopes['flm'] = ' (retired code)' -bcp_47.macrolanguages['flm'] = {'cfm'} - -ot.ranks['FNE'] = ot.ranks['TNE'] + 1 - -ot.add_language ('und-fonipa', 'IPPH') - -ot.add_language ('und-fonnapa', 'APPH') - -ot.add_language ('ga-Latg', 'IRT') - -ot.add_language ('hy-arevmda', 'HYE') - -ot.remove_language_ot ('KGE') -ot.add_language ('und-Geok', 'KGE') - -ot.add_language ('kht', 'KHN') -ot.names['KHN'] = ot.names['KHT'] + ' (Microsoft fonts)' -ot.ranks['KHN'] = ot.ranks['KHT'] + 1 - -ot.ranks['LCR'] = ot.ranks['MCR'] + 1 - -ot.names['MAL'] = 'Malayalam Traditional' -ot.ranks['MLR'] += 1 - -bcp_47.names['mhv'] = 'Arakanese' -bcp_47.scopes['mhv'] = ' (retired code)' - -ot.add_language ('mnw-TH', 'MONT') - -ot.add_language ('no', 'NOR') - -ot.add_language ('oc-provenc', 'PRO') - -ot.remove_language_ot ('QUZ') -ot.add_language ('qu', 'QUZ') -ot.add_language ('qub', 'QWH') -ot.add_language ('qud', 'QVI') -ot.add_language ('qug', 'QVI') -ot.add_language ('qul', 'QUH') -ot.add_language ('qup', 'QVI') -ot.add_language ('qur', 'QWH') -ot.add_language ('qus', 'QUH') -ot.add_language ('quw', 'QVI') -ot.add_language ('qux', 'QWH') -ot.add_language ('qva', 'QWH') -ot.add_language ('qvh', 'QWH') -ot.add_language ('qvj', 'QVI') -ot.add_language ('qvl', 'QWH') -ot.add_language ('qvm', 'QWH') -ot.add_language ('qvn', 'QWH') -ot.add_language ('qvo', 'QVI') -ot.add_language ('qvp', 'QWH') -ot.add_language ('qvw', 'QWH') -ot.add_language ('qvz', 'QVI') -ot.add_language ('qwa', 'QWH') -ot.add_language ('qws', 'QWH') -ot.add_language ('qxa', 'QWH') -ot.add_language ('qxc', 'QWH') -ot.add_language ('qxh', 'QWH') -ot.add_language ('qxl', 'QVI') -ot.add_language ('qxn', 'QWH') -ot.add_language ('qxo', 'QWH') -ot.add_language ('qxr', 'QVI') -ot.add_language ('qxt', 'QWH') -ot.add_language ('qxw', 'QWH') - -bcp_47.macrolanguages['ro-MD'].add ('mo') - -ot.remove_language_ot ('SYRE') -ot.remove_language_ot ('SYRJ') -ot.remove_language_ot ('SYRN') -ot.add_language ('und-Syre', 'SYRE') -ot.add_language ('und-Syrj', 'SYRJ') -ot.add_language ('und-Syrn', 'SYRN') - -bcp_47.names['xst'] = "Silt'e" -bcp_47.scopes['xst'] = ' (retired code)' -bcp_47.macrolanguages['xst'] = {'stv', 'wle'} - -ot.add_language ('xwo', 'TOD') - -ot.remove_language_ot ('ZHH') -ot.remove_language_ot ('ZHP') -ot.remove_language_ot ('ZHT') -ot.remove_language_ot ('ZHTM') -bcp_47.macrolanguages['zh'].remove ('lzh') -bcp_47.macrolanguages['zh'].remove ('yue') -ot.add_language ('zh-Hant-MO', 'ZHH') -ot.add_language ('zh-Hant-MO', 'ZHTM') -ot.add_language ('zh-Hant-HK', 'ZHH') -ot.add_language ('zh-Hans', 'ZHS') -ot.add_language ('zh-Hant', 'ZHT') -ot.add_language ('zh-HK', 'ZHH') -ot.add_language ('zh-MO', 'ZHH') -ot.add_language ('zh-MO', 'ZHTM') -ot.add_language ('zh-TW', 'ZHT') -ot.add_language ('lzh', 'ZHT') -ot.add_language ('lzh-Hans', 'ZHS') -ot.add_language ('yue', 'ZHH') -ot.add_language ('yue-Hans', 'ZHS') - -def rank_delta (bcp_47, ot): - """Return a delta to apply to a BCP 47 tag's rank. - - Most OpenType tags have a constant rank, but a few have ranks that - depend on the BCP 47 tag. - - Args: - bcp_47 (str): A BCP 47 tag. - ot (str): An OpenType tag to. - - Returns: - A number to add to ``ot``'s rank when sorting ``bcp_47``'s - OpenType equivalents. - """ - if bcp_47 == 'ak' and ot == 'AKA': - return -1 - if bcp_47 == 'tw' and ot == 'TWI': - return -1 - return 0 - -disambiguation = { - 'ALT': 'alt', - 'ARK': 'rki', - 'ATH': 'ath', - 'BHI': 'bhb', - 'BLN': 'bjt', - 'BTI': 'beb', - 'CCHN': 'cco', - 'CMR': 'swb', - 'CPP': 'crp', - 'CRR': 'crx', - 'DUJ': 'dwu', - 'ECR': 'crj', - 'HAL': 'cfm', - 'HND': 'hnd', - 'HYE': 'hyw', - 'KIS': 'kqs', - 'KUI': 'uki', - 'LRC': 'bqi', - 'NDB': 'nd', - 'NIS': 'njz', - 'PLG': 'pce', - 'PRO': 'pro', - 'QIN': 'bgr', - 'QUH': 'quh', - 'QVI': 'qvi', - 'QWH': 'qwh', - 'SIG': 'stv', - 'SRB': 'sr', - 'SXT': 'xnj', - 'ZHH': 'zh-HK', - 'ZHS': 'zh-Hans', - 'ZHT': 'zh-Hant', - 'ZHTM': 'zh-MO', -} - -ot.inherit_from_macrolanguages () -bcp_47.remove_extra_macrolanguages () -ot.inherit_from_macrolanguages () -ot.names[DEFAULT_LANGUAGE_SYSTEM] = '*/' -ot.ranks[DEFAULT_LANGUAGE_SYSTEM] = max (ot.ranks.values ()) + 1 -for tricky_ot_tag in filter (lambda tag: re.match ('[A-Z]{3}$', tag), ot.names): - possible_bcp_47_tag = tricky_ot_tag.lower () - if possible_bcp_47_tag in bcp_47.names and not ot.from_bcp_47[possible_bcp_47_tag]: - ot.add_language (possible_bcp_47_tag, DEFAULT_LANGUAGE_SYSTEM) - bcp_47.macrolanguages[possible_bcp_47_tag] = set () -ot.sort_languages () - -print ('/* == Start of generated table == */') -print ('/*') -print (' * The following table is generated by running:') -print (' *') -print (' * %s languagetags language-subtag-registry' % sys.argv[0]) -print (' *') -print (' * on files with these headers:') -print (' *') -print (' * %s' % ot.header.strip ()) -print (' * %s' % bcp_47.header) -print (' */') -print () -print ('#ifndef HB_OT_TAG_TABLE_HH') -print ('#define HB_OT_TAG_TABLE_HH') -print () - -def hb_tag (tag): - """Convert a tag to ``HB_TAG`` form. - - Args: - tag (str): An OpenType tag. - - Returns: - A snippet of C++ representing ``tag``. - """ - if tag == DEFAULT_LANGUAGE_SYSTEM: - return 'HB_TAG_NONE\t ' - return "HB_TAG('%s','%s','%s','%s')" % tuple (('%-4s' % tag)[:4]) - -def get_variant_set (name): - """Return a set of variant language names from a name. - - Args: - name (str): A list of language names from the BCP 47 registry, - joined on ``'\\n'``. - - Returns: - A set of normalized language names. - """ - return set (unicodedata.normalize ('NFD', n.replace ('\u2019', "'")) - .encode ('ASCII', 'ignore') - .strip () - for n in re.split ('[\n(),]', name) if n) - -def language_name_intersection (a, b): - """Return the names in common between two language names. - - Args: - a (str): A list of language names from the BCP 47 registry, - joined on ``'\\n'``. - b (str): A list of language names from the BCP 47 registry, - joined on ``'\\n'``. - - Returns: - The normalized language names shared by ``a`` and ``b``. - """ - return get_variant_set (a).intersection (get_variant_set (b)) - -def get_matching_language_name (intersection, candidates): - return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) - -def same_tag (bcp_47_tag, ot_tags): - return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower () - -for language_len in (2, 3): - if language_len == 3: - print ('#ifndef HB_NO_LANGUAGE_LONG') - print ('static const LangTag ot_languages%d[] = {' % language_len) - for language, tags in sorted (ot.from_bcp_47.items ()): - if language == '' or '-' in language: - continue - if len(language) != language_len: continue - commented_out = same_tag (language, tags) - for i, tag in enumerate (tags, start=1): - print ('%s{%s,\t%s},' % ('/*' if commented_out else ' ', hb_tag (language), hb_tag (tag)), end='') - if commented_out: - print ('*/', end='') - print ('\t/* ', end='') - bcp_47_name = bcp_47.names.get (language, '') - bcp_47_name_candidates = bcp_47_name.split ('\n') - ot_name = ot.names[tag] - scope = bcp_47.scopes.get (language, '') - if tag == DEFAULT_LANGUAGE_SYSTEM: - write (f'{bcp_47_name_candidates[0]}{scope} != {ot.names[language.upper ()]}') - else: - intersection = language_name_intersection (bcp_47_name, ot_name) - if not intersection: - write ('%s%s -> %s' % (bcp_47_name_candidates[0], scope, ot_name)) - else: - name = get_matching_language_name (intersection, bcp_47_name_candidates) - bcp_47.names[language] = name - write ('%s%s' % (name if len (name) > len (ot_name) else ot_name, scope)) - print (' */') - print ('};') - if language_len == 3: - print ('#endif') - print () - -print ('/**') -print (' * hb_ot_tags_from_complex_language:') -print (' * @lang_str: a BCP 47 language tag to convert.') -print (' * @limit: a pointer to the end of the substring of @lang_str to consider for') -print (' * conversion.') -print (' * @count: maximum number of language tags to retrieve (IN) and actual number of') -print (' * language tags retrieved (OUT). If no tags are retrieved, it is not modified.') -print (' * @tags: array of size at least @language_count to store the language tag') -print (' * results') -print (' *') -print (' * Converts a multi-subtag BCP 47 language tag to language tags.') -print (' *') -print (' * Return value: Whether any language systems were retrieved.') -print (' **/') -print ('static inline bool') -print ('hb_ot_tags_from_complex_language (const char *lang_str,') -print ('\t\t\t\t const char *limit,') -print ('\t\t\t\t unsigned int *count /* IN/OUT */,') -print ('\t\t\t\t hb_tag_t *tags /* OUT */)') -print ('{') - -def print_subtag_matches (subtag, string, new_line): - if subtag: - if new_line: - print () - print ('\t&& ', end='') - print ('subtag_matches (%s, limit, "-%s", %i)' % (string, subtag, 1 + len (subtag)), end='') - -complex_tags = collections.defaultdict (list) -for initial, group in itertools.groupby ((lt_tags for lt_tags in [ - (LanguageTag (language), tags) - for language, tags in sorted (ot.from_bcp_47.items (), - key=lambda i: (-len (i[0]), i[0])) - ] if lt_tags[0].is_complex ()), - key=lambda lt_tags: lt_tags[0].get_group ()): - complex_tags[initial] += group - -# Calculate the min length of the subtags outside the switch -min_subtag_len = 100 -for initial, items in sorted (complex_tags.items ()): - if initial != 'und': - continue - for lt, tags in items: - if not tags: - continue - subtag_len = 0 - subtag_len += 1 + len (lt.script) if lt.script is not None else 0 - subtag_len += 1 + len (lt.region) if lt.region is not None else 0 - subtag_len += 1 + len (lt.variant) if lt.variant is not None else 0 - min_subtag_len = min(subtag_len, min_subtag_len) - -print (' if (limit - lang_str >= %d)' % (min_subtag_len + 2)) -print (' {') -print (" const char *p = strchr (lang_str, '-');") -print (" if (!p || p >= limit || limit - p < %i) goto out;" % min_subtag_len) -for initial, items in sorted (complex_tags.items ()): - if initial != 'und': - continue - for lt, tags in items: - if not tags: - continue - if lt.variant in bcp_47.prefixes: - expect (next (iter (bcp_47.prefixes[lt.variant])) == lt.language, - '%s is not a valid prefix of %s' % (lt.language, lt.variant)) - print (' if (', end='') - print_subtag_matches (lt.script, 'p', False) - print_subtag_matches (lt.region, 'p', False) - print_subtag_matches (lt.variant, 'p', False) - print (')') - print (' {') - write (' /* %s */' % bcp_47.get_name (lt)) - print () - if len (tags) == 1: - write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) - print () - print (' *count = 1;') - else: - print (' hb_tag_t possible_tags[] = {') - for tag in tags: - write (' %s, /* %s */' % (hb_tag (tag), ot.names[tag])) - print () - print (' };') - print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) - print ('\ttags[i] = possible_tags[i];') - print (' *count = i;') - print (' return true;') - print (' }') -print (' }') -print ('out:') - -print (' switch (lang_str[0])') -print (' {') -for initial, items in sorted (complex_tags.items ()): - if initial == 'und': - continue - print (" case '%s':" % initial) - for lt, tags in items: - if not tags: - continue - print (' if (', end='') - script = lt.script - region = lt.region - if lt.grandfathered: - print ('0 == strcmp (&lang_str[1], "%s")' % lt.language[1:], end='') - else: - string_literal = lt.language[1:] + '-' - if script: - string_literal += script - script = None - if region: - string_literal += '-' + region - region = None - if string_literal[-1] == '-': - print ('0 == strncmp (&lang_str[1], "%s", %i)' % (string_literal, len (string_literal)), end='') - else: - print ('lang_matches (&lang_str[1], limit, "%s", %i)' % (string_literal, len (string_literal)), end='') - print_subtag_matches (script, 'lang_str', True) - print_subtag_matches (region, 'lang_str', True) - print_subtag_matches (lt.variant, 'lang_str', True) - print (')') - print (' {') - write (' /* %s */' % bcp_47.get_name (lt)) - print () - if len (tags) == 1: - write (' tags[0] = %s; /* %s */' % (hb_tag (tags[0]), ot.names[tags[0]])) - print () - print (' *count = 1;') - else: - print (' unsigned int i;') - print (' hb_tag_t possible_tags[] = {') - for tag in tags: - write ('\t%s, /* %s */' % (hb_tag (tag), ot.names[tag])) - print () - print (' };') - print (' for (i = 0; i < %s && i < *count; i++)' % len (tags)) - print ('\ttags[i] = possible_tags[i];') - print (' *count = i;') - print (' return true;') - print (' }') - print (' break;') - -print (' }') -print (' return false;') -print ('}') -print () -print ('/**') -print (' * hb_ot_ambiguous_tag_to_language') -print (' * @tag: A language tag.') -print (' *') -print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to') -print (' * many language tags) and the best tag is not the first (sorted alphabetically,') -print (' * with two-letter tags having priority over all three-letter tags), or if the') -print (' * best tag consists of multiple subtags, or if the best tag does not appear in') -print (' * #ot_languages2 or #ot_languages3.') -print (' *') -print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') -print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') -print (' **/') -print ('static inline hb_language_t') -print ('hb_ot_ambiguous_tag_to_language (hb_tag_t tag)') -print ('{') -print (' switch (tag)') -print (' {') - -def verify_disambiguation_dict (): - """Verify and normalize ``disambiguation``. - - ``disambiguation`` is a map of ambiguous OpenType language system - tags to the particular BCP 47 tags they correspond to. This function - checks that all its keys really are ambiguous and that each key's - value is valid for that key. It checks that no ambiguous tag is - missing, except when it can figure out which BCP 47 tag is the best - by itself. - - It modifies ``disambiguation`` to remove keys whose values are the - same as those that the fallback would return anyway, and to add - ambiguous keys whose disambiguations it determined automatically. - - Raises: - AssertionError: Verification failed. - """ - global bcp_47 - global disambiguation - global ot - for ot_tag, bcp_47_tags in ot.to_bcp_47.items (): - if ot_tag == DEFAULT_LANGUAGE_SYSTEM: - primary_tags = [] - else: - primary_tags = list (t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot.from_bcp_47.get (t)[0] == ot_tag) - if len (primary_tags) == 1: - expect (ot_tag not in disambiguation, 'unnecessary disambiguation for OT tag: %s' % ot_tag) - if '-' in primary_tags[0]: - disambiguation[ot_tag] = primary_tags[0] - else: - first_tag = sorted ((t for t in bcp_47_tags if t not in bcp_47.grandfathered and ot_tag in ot.from_bcp_47.get (t)), - key=lambda t: (len (t), t))[0] - if primary_tags[0] != first_tag: - disambiguation[ot_tag] = primary_tags[0] - elif len (primary_tags) == 0: - expect (ot_tag not in disambiguation, 'There is no possible valid disambiguation for %s' % ot_tag) - else: - original_languages = [t for t in primary_tags if t in ot.from_bcp_47_uninherited and 'retired code' not in bcp_47.scopes.get (t, '')] - if len (original_languages) == 1: - macrolanguages = original_languages - else: - macrolanguages = [t for t in primary_tags if bcp_47.scopes.get (t) == ' [macrolanguage]'] - if len (macrolanguages) != 1: - macrolanguages = list (t for t in primary_tags if bcp_47.scopes.get (t) == ' [collection]') - if len (macrolanguages) != 1: - macrolanguages = list (t for t in primary_tags if 'retired code' not in bcp_47.scopes.get (t, '')) - if len (macrolanguages) != 1: - macrolanguages = list (t for t in primary_tags if t.lower () == ISO_639_3_TO_1.get (ot_tag.lower (), ot_tag.lower ())) - if len (macrolanguages) != 1: - macrolanguages = list (t for t in primary_tags if '-' not in t) - if len (macrolanguages) != 1: - expect (ot_tag in disambiguation, 'ambiguous OT tag: %s %s' % (ot_tag, sorted (primary_tags))) - expect (disambiguation[ot_tag] in bcp_47_tags, - '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) - elif ot_tag not in disambiguation: - disambiguation[ot_tag] = macrolanguages[0] - if '-' not in disambiguation[ot_tag]: - different_bcp_47_tags = sorted ((t for t in bcp_47_tags if not same_tag (t, ot.from_bcp_47.get (t))), - key=lambda t: (len (t), t)) - if different_bcp_47_tags and disambiguation[ot_tag] == different_bcp_47_tags[0]: - del disambiguation[ot_tag] - for ot_tag in disambiguation.keys (): - expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) - -verify_disambiguation_dict () -for ot_tag, bcp_47_tag in sorted (disambiguation.items ()): - write (' case %s: /* %s */' % (hb_tag (ot_tag), ot.names[ot_tag])) - print () - write (' return hb_language_from_string (\"%s\", -1); /* %s */' % (bcp_47_tag, bcp_47.get_name (LanguageTag (bcp_47_tag)))) - print () - -print (' default:') -print (' return HB_LANGUAGE_INVALID;') -print (' }') -print ('}') - -print () -print ('#endif /* HB_OT_TAG_TABLE_HH */') -print () -print ('/* == End of generated table == */') - diff --git a/thirdparty/harfbuzz/upstream/gen-ucd-table.py b/thirdparty/harfbuzz/upstream/gen-ucd-table.py deleted file mode 100755 index d85ae4faa..000000000 --- a/thirdparty/harfbuzz/upstream/gen-ucd-table.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env python3 - -"""usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h] - -Input file: -* https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip -""" - -import sys, re -import logging -logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) - -if len (sys.argv) not in (2, 3): - sys.exit (__doc__) - -# https://github.com/harfbuzz/packtab -import packTab -import packTab.ucdxml - -logging.info('Loading UCDXML...') -ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1]) -ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml) - -hb_common_h = 'hb-common.h' if len (sys.argv) < 3 else sys.argv[2] - -logging.info('Preparing data tables...') - - -# This is how the data is encoded: -# -# General_Category (gc), Canonical_Combining_Class (ccc), -# and Script (sc) are encoded as integers. -# -# Mirroring character (bmg) is encoded as difference from -# the original character. -# -# Composition & Decomposition (dm) are encoded elaborately, -# as discussed below. - -gc = [u['gc'] for u in ucd] -ccc = [int(u['ccc']) for u in ucd] -bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)] -sc = [u['sc'] for u in ucd] - - -# Prepare Compose / Decompose data -# -# This code is very dense. See hb_ucd_compose() / hb_ucd_decompose() for the logic. - -dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd) - if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)} -ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'} - -assert not any(v for v in dm.values() if len(v) not in (1,2)) -dm1 = sorted(set(v for v in dm.values() if len(v) == 1)) -assert all((v[0] >> 16) in (0,2) for v in dm1) -dm1_p0_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0] -dm1_p2_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2] -dm1_order = {v:i+1 for i,v in enumerate(dm1)} - -dm2 = sorted((v+(i if i not in ce and not ccc[i] else 0,), v) - for i,v in dm.items() if len(v) == 2) - -filt = lambda v: ((v[0] & 0xFFFFF800) == 0x0000 and - (v[1] & 0xFFFFFF80) == 0x0300 and - (v[2] & 0xFFF0C000) == 0x0000) -dm2_u32_array = [v for v in dm2 if filt(v[0])] -dm2_u64_array = [v for v in dm2 if not filt(v[0])] -assert dm2_u32_array + dm2_u64_array == dm2 -dm2_u32_array = ["HB_CODEPOINT_ENCODE3_11_7_14 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u32_array] -dm2_u64_array = ["HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u64_array] - -l = 1 + len(dm1_p0_array) + len(dm1_p2_array) -dm2_order = {v[1]:i+l for i,v in enumerate(dm2)} - -dm_order = {None: 0} -dm_order.update(dm1_order) -dm_order.update(dm2_order) - - -# Prepare General_Category / Script mapping arrays - -gc_order = dict() -for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', - 'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', - 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',)): - gc_order[i] = v - gc_order[v] = i - -sc_order = dict() -sc_array = [] -sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]") -for line in open(hb_common_h): - m = sc_re.search (line) - if not m: continue - name = m.group(1) - tag = ''.join(m.group(i) for i in range(2, 6)) - i = len(sc_array) - sc_order[tag] = i - sc_order[i] = tag - sc_array.append(name) - - -# Write out main data - -DEFAULT = 'DEFAULT' -COMPACT = 'COMPACT' -SLOPPY = 'SLOPPY' - -compression_level = { - DEFAULT: 5, - COMPACT: 9, - SLOPPY: 9, -} - -logging.info('Generating output...') -print("/* == Start of generated table == */") -print("/*") -print(" * The following table is generated by running:") -print(" *") -print(" * ./gen-ucd-table.py ucd.nounihan.grouped.xml") -print(" *") -print(" * on file with this description:", ucdxml.description) -print(" */") -print() -print("#ifndef HB_UCD_TABLE_HH") -print("#define HB_UCD_TABLE_HH") -print() -print('#include "hb.hh"') -print() - - -# Write mapping data - -code = packTab.Code('_hb_ucd') -sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array) -dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array) -dm1_p2_array, _ = code.addArray('uint16_t', 'dm1_p2_map', dm1_p2_array) -dm2_u32_array, _ = code.addArray('uint32_t', 'dm2_u32_map', dm2_u32_array) -dm2_u64_array, _ = code.addArray('uint64_t', 'dm2_u64_map', dm2_u64_array) -code.print_c(linkage='static inline') - -datasets = [ - ('gc', gc, 'Cn', gc_order), - ('ccc', ccc, 0, None), - ('bmg', bmg, 0, None), - ('sc', sc, 'Zzzz', sc_order), - ('dm', dm, None, dm_order), -] - - -# Write main data - -for step in (DEFAULT, COMPACT, SLOPPY): - compression = compression_level[step] - logging.info(' Compression=%d:' % compression) - print() - if step == DEFAULT: - print('#ifndef HB_OPTIMIZE_SIZE') - elif step == COMPACT: - print('#elif !defined(HB_NO_UCD_UNASSIGNED)') - elif step == SLOPPY: - print('#else') - else: - assert False - print() - - if step == SLOPPY: - for i in range(len(gc)): - if (i % 128) and gc[i] == 'Cn': - gc[i] = gc[i - 1] - for i in range(len(gc) - 2, -1, -1): - if ((i + 1) % 128) and gc[i] == 'Cn': - gc[i] = gc[i + 1] - for i in range(len(sc)): - if (i % 128) and sc[i] == 'Zzzz': - sc[i] = sc[i - 1] - for i in range(len(sc) - 2, -1, -1): - if ((i + 1) % 128) and sc[i] == 'Zzzz': - sc[i] = sc[i + 1] - - - code = packTab.Code('_hb_ucd') - - for name,data,default,mapping in datasets: - sol = packTab.pack_table(data, default, mapping=mapping, compression=compression) - logging.info(' Dataset=%-8s FullCost=%d' % (name, sol.fullCost)) - sol.genCode(code, name) - - code.print_c(linkage='static inline') - - print() - - -print('#endif') -print() - -print() -print("#endif /* HB_UCD_TABLE_HH */") -print() -print("/* == End of generated table == */") -logging.info('Done.') diff --git a/thirdparty/harfbuzz/upstream/gen-use-table.py b/thirdparty/harfbuzz/upstream/gen-use-table.py deleted file mode 100755 index 4e8680650..000000000 --- a/thirdparty/harfbuzz/upstream/gen-use-table.py +++ /dev/null @@ -1,529 +0,0 @@ -#!/usr/bin/env python3 -# flake8: noqa: F821 - -"""usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt - -Input files: -* https://unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt -* https://unicode.org/Public/UCD/latest/ucd/IndicPositionalCategory.txt -* https://unicode.org/Public/UCD/latest/ucd/ArabicShaping.txt -* https://unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt -* https://unicode.org/Public/UCD/latest/ucd/UnicodeData.txt -* https://unicode.org/Public/UCD/latest/ucd/Blocks.txt -* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt -* ms-use/IndicSyllabicCategory-Additional.txt -* ms-use/IndicPositionalCategory-Additional.txt -""" - -import logging -logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) - - -import sys - -if len (sys.argv) != 10: - sys.exit (__doc__) - -DISABLED_SCRIPTS = { - 'Arabic', - 'Lao', - 'Samaritan', - 'Syriac', - 'Thai', -} - -files = [open (x, encoding='utf-8') for x in sys.argv[1:]] - -headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 4] -for j in range(7, 9): - for line in files[j]: - line = line.rstrip() - if not line: - break - headers[j - 1].append(line) -headers.append (["UnicodeData.txt does not have a header."]) - -unicode_data = [{} for _ in files] -values = [{} for _ in files] -for i, f in enumerate (files): - for line in f: - - j = line.find ('#') - if j >= 0: - line = line[:j] - - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - - t = fields[1 if i not in [2, 4] else 2] - - if i == 2: - t = 'jt_' + t - elif i == 3 and t != 'Default_Ignorable_Code_Point': - continue - elif i == 7 and t == 'Consonant_Final_Modifier': - # TODO: https://github.com/MicrosoftDocs/typography-issues/issues/336 - t = 'Syllable_Modifier' - elif i == 8 and t == 'NA': - t = 'Not_Applicable' - - i0 = i if i < 7 else i - 7 - for u in range (start, end + 1): - unicode_data[i0][u] = t - values[i0][t] = values[i0].get (t, 0) + end - start + 1 - -defaults = ('Other', 'Not_Applicable', 'jt_X', '', 'Cn', 'No_Block', 'Unknown') - -# Merge data into one dict: -for i,v in enumerate (defaults): - values[i][v] = values[i].get (v, 0) + 1 -combined = {} -for i,d in enumerate (unicode_data): - for u,v in d.items (): - if not u in combined: - if i >= 4: - continue - combined[u] = list (defaults) - combined[u][i] = v -combined = {k: v for k, v in combined.items() if v[6] not in DISABLED_SCRIPTS} - - -property_names = [ - # General_Category - 'Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', 'Mc', - 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', - 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs', - # Indic_Syllabic_Category - 'Other', - 'Bindu', - 'Visarga', - 'Avagraha', - 'Nukta', - 'Virama', - 'Pure_Killer', - 'Reordering_Killer', - 'Invisible_Stacker', - 'Vowel_Independent', - 'Vowel_Dependent', - 'Vowel', - 'Consonant_Placeholder', - 'Consonant', - 'Consonant_Dead', - 'Consonant_With_Stacker', - 'Consonant_Prefixed', - 'Consonant_Preceding_Repha', - 'Consonant_Succeeding_Repha', - 'Consonant_Subjoined', - 'Consonant_Medial', - 'Consonant_Final', - 'Consonant_Head_Letter', - 'Consonant_Initial_Postfixed', - 'Modifying_Letter', - 'Tone_Letter', - 'Tone_Mark', - 'Gemination_Mark', - 'Cantillation_Mark', - 'Register_Shifter', - 'Syllable_Modifier', - 'Consonant_Killer', - 'Non_Joiner', - 'Joiner', - 'Number_Joiner', - 'Number', - 'Brahmi_Joining_Number', - 'Symbol_Modifier', - 'Hieroglyph', - 'Hieroglyph_Joiner', - 'Hieroglyph_Mark_Begin', - 'Hieroglyph_Mark_End', - 'Hieroglyph_Mirror', - 'Hieroglyph_Modifier', - 'Hieroglyph_Segment_Begin', - 'Hieroglyph_Segment_End', - # Indic_Positional_Category - 'Not_Applicable', - 'Right', - 'Left', - 'Visual_Order_Left', - 'Left_And_Right', - 'Top', - 'Bottom', - 'Top_And_Bottom', - 'Top_And_Bottom_And_Left', - 'Top_And_Right', - 'Top_And_Left', - 'Top_And_Left_And_Right', - 'Bottom_And_Left', - 'Bottom_And_Right', - 'Top_And_Bottom_And_Right', - 'Overstruck', - # Joining_Type - 'jt_C', - 'jt_D', - 'jt_L', - 'jt_R', - 'jt_T', - 'jt_U', - 'jt_X', -] - -class PropertyValue(object): - def __init__(self, name_): - self.name = name_ - def __str__(self): - return self.name - def __eq__(self, other): - return self.name == (other if isinstance(other, str) else other.name) - def __ne__(self, other): - return not (self == other) - def __hash__(self): - return hash(str(self)) - -property_values = {} - -for name in property_names: - value = PropertyValue(name) - assert value not in property_values - assert value not in globals() - property_values[name] = value -globals().update(property_values) - - -def is_BASE(U, UISC, UDI, UGC, AJT): - return (UISC in [Number, Consonant, Consonant_Head_Letter, - Tone_Letter, - Vowel_Independent, - ] or - # TODO: https://github.com/MicrosoftDocs/typography-issues/issues/484 - AJT in [jt_C, jt_D, jt_L, jt_R] and UISC != Joiner or - (UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial, - Consonant_Subjoined, Vowel, Vowel_Dependent])) -def is_BASE_NUM(U, UISC, UDI, UGC, AJT): - return UISC == Brahmi_Joining_Number -def is_BASE_OTHER(U, UISC, UDI, UGC, AJT): - if UISC == Consonant_Placeholder: return True - return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE] -def is_CGJ(U, UISC, UDI, UGC, AJT): - # Also includes VARIATION_SELECTOR and ZWJ - return UISC == Joiner or UDI and UGC in [Mc, Me, Mn] -def is_CONS_FINAL(U, UISC, UDI, UGC, AJT): - return ((UISC == Consonant_Final and UGC != Lo) or - UISC == Consonant_Succeeding_Repha) -def is_CONS_FINAL_MOD(U, UISC, UDI, UGC, AJT): - return UISC == Syllable_Modifier -def is_CONS_MED(U, UISC, UDI, UGC, AJT): - # Consonant_Initial_Postfixed is new in Unicode 11; not in the spec. - return (UISC == Consonant_Medial and UGC != Lo or - UISC == Consonant_Initial_Postfixed) -def is_CONS_MOD(U, UISC, UDI, UGC, AJT): - return UISC in [Nukta, Gemination_Mark, Consonant_Killer] -def is_CONS_SUB(U, UISC, UDI, UGC, AJT): - return UISC == Consonant_Subjoined and UGC != Lo -def is_CONS_WITH_STACKER(U, UISC, UDI, UGC, AJT): - return UISC == Consonant_With_Stacker -def is_HALANT(U, UISC, UDI, UGC, AJT): - return UISC == Virama and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT) -def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UDI, UGC, AJT): - # Split off of HALANT - return U == 0x0DCA -def is_HALANT_NUM(U, UISC, UDI, UGC, AJT): - return UISC == Number_Joiner -def is_HIEROGLYPH(U, UISC, UDI, UGC, AJT): - return UISC == Hieroglyph -def is_HIEROGLYPH_JOINER(U, UISC, UDI, UGC, AJT): - return UISC == Hieroglyph_Joiner -def is_HIEROGLYPH_MIRROR(U, UISC, UDI, UGC, AJT): - return UISC == Hieroglyph_Mirror -def is_HIEROGLYPH_MOD(U, UISC, UDI, UGC, AJT): - return UISC == Hieroglyph_Modifier -def is_HIEROGLYPH_SEGMENT_BEGIN(U, UISC, UDI, UGC, AJT): - return UISC in [Hieroglyph_Mark_Begin, Hieroglyph_Segment_Begin] -def is_HIEROGLYPH_SEGMENT_END(U, UISC, UDI, UGC, AJT): - return UISC in [Hieroglyph_Mark_End, Hieroglyph_Segment_End] -def is_INVISIBLE_STACKER(U, UISC, UDI, UGC, AJT): - # Split off of HALANT - return (UISC == Invisible_Stacker - and not is_SAKOT(U, UISC, UDI, UGC, AJT) - ) -def is_ZWNJ(U, UISC, UDI, UGC, AJT): - return UISC == Non_Joiner -def is_OTHER(U, UISC, UDI, UGC, AJT): - # Also includes BASE_IND and SYM - return ((UGC == Po or UISC in [Consonant_Dead, Joiner, Modifying_Letter, Other]) - and not is_BASE(U, UISC, UDI, UGC, AJT) - and not is_BASE_OTHER(U, UISC, UDI, UGC, AJT) - and not is_CGJ(U, UISC, UDI, UGC, AJT) - and not is_SYM_MOD(U, UISC, UDI, UGC, AJT) - and not is_Word_Joiner(U, UISC, UDI, UGC, AJT) - ) -def is_REORDERING_KILLER(U, UISC, UDI, UGC, AJT): - return UISC == Reordering_Killer -def is_REPHA(U, UISC, UDI, UGC, AJT): - return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed] -def is_SAKOT(U, UISC, UDI, UGC, AJT): - # Split off of HALANT - return U == 0x1A60 -def is_SYM_MOD(U, UISC, UDI, UGC, AJT): - return UISC == Symbol_Modifier -def is_VOWEL(U, UISC, UDI, UGC, AJT): - return (UISC == Pure_Killer or - UGC != Lo and UISC in [Vowel, Vowel_Dependent]) -def is_VOWEL_MOD(U, UISC, UDI, UGC, AJT): - return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or - UGC != Lo and UISC == Bindu) -def is_Word_Joiner(U, UISC, UDI, UGC, AJT): - # Also includes Rsv - return (UDI and U not in [0x115F, 0x1160, 0x3164, 0xFFA0, 0x1BCA0, 0x1BCA1, 0x1BCA2, 0x1BCA3] - and UISC == Other - and not is_CGJ(U, UISC, UDI, UGC, AJT) - ) or UGC == Cn - -use_mapping = { - 'B': is_BASE, - 'N': is_BASE_NUM, - 'GB': is_BASE_OTHER, - 'CGJ': is_CGJ, - 'F': is_CONS_FINAL, - 'FM': is_CONS_FINAL_MOD, - 'M': is_CONS_MED, - 'CM': is_CONS_MOD, - 'SUB': is_CONS_SUB, - 'CS': is_CONS_WITH_STACKER, - 'H': is_HALANT, - 'HVM': is_HALANT_OR_VOWEL_MODIFIER, - 'HN': is_HALANT_NUM, - 'IS': is_INVISIBLE_STACKER, - 'G': is_HIEROGLYPH, - 'HM': is_HIEROGLYPH_MOD, - 'HR': is_HIEROGLYPH_MIRROR, - 'J': is_HIEROGLYPH_JOINER, - 'SB': is_HIEROGLYPH_SEGMENT_BEGIN, - 'SE': is_HIEROGLYPH_SEGMENT_END, - 'ZWNJ': is_ZWNJ, - 'O': is_OTHER, - 'RK': is_REORDERING_KILLER, - 'R': is_REPHA, - 'Sk': is_SAKOT, - 'SM': is_SYM_MOD, - 'V': is_VOWEL, - 'VM': is_VOWEL_MOD, - 'WJ': is_Word_Joiner, -} - -use_positions = { - 'F': { - 'Abv': [Top], - 'Blw': [Bottom], - 'Pst': [Right], - }, - 'M': { - 'Abv': [Top], - 'Blw': [Bottom, Bottom_And_Left, Bottom_And_Right], - 'Pst': [Right], - 'Pre': [Left, Top_And_Bottom_And_Left], - }, - 'CM': { - 'Abv': [Top], - 'Blw': [Bottom, Overstruck], - }, - 'V': { - 'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right], - 'Blw': [Bottom, Overstruck, Bottom_And_Right], - 'Pst': [Right], - 'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right], - }, - 'VM': { - 'Abv': [Top], - 'Blw': [Bottom, Overstruck], - 'Pst': [Right], - 'Pre': [Left], - }, - 'SM': { - 'Abv': [Top], - 'Blw': [Bottom], - }, - 'H': None, - 'HM': None, - 'HR': None, - 'HVM': None, - 'IS': None, - 'B': None, - 'FM': { - 'Abv': [Top], - 'Blw': [Bottom], - 'Pst': [Not_Applicable], - }, - 'R': None, - 'RK': None, - 'SUB': None, -} - -def map_to_use(data): - out = {} - items = use_mapping.items() - for U, (UISC, UIPC, AJT, UDI, UGC, UBlock, _) in data.items(): - - # Resolve Indic_Syllabic_Category - - # TODO: These don't have UISC assigned in Unicode 13.0.0, but have UIPC - if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark - - # Tibetan: - # TODO: These don't have UISC assigned in Unicode 13.0.0, but have UIPC - if 0x0F18 <= U <= 0x0F19 or 0x0F3E <= U <= 0x0F3F: UISC = Vowel_Dependent - - # TODO: U+1CED should only be allowed after some of - # the nasalization marks, maybe only for U+1CE9..U+1CF1. - if U == 0x1CED: UISC = Tone_Mark - - values = [k for k,v in items if v(U, UISC, UDI, UGC, AJT)] - assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UISC, UDI, UGC, AJT, values) - USE = values[0] - - # Resolve Indic_Positional_Category - - # TODO: https://github.com/harfbuzz/harfbuzz/pull/1037 - # and https://github.com/harfbuzz/harfbuzz/issues/1631 - if U in [0x11302, 0x11303, 0x114C1]: UIPC = Top - - # TODO: https://github.com/microsoft/font-tools/issues/17#issuecomment-2346952091 - if U == 0x113CF: UIPC = Bottom - - assert (UIPC in [Not_Applicable, Visual_Order_Left] or - U in {0x0F7F, 0x11A3A} or - USE in use_positions), "%s %s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UDI, UGC, AJT) - - pos_mapping = use_positions.get(USE, None) - if pos_mapping: - values = [k for k,v in pos_mapping.items() if v and UIPC in v] - assert len(values) == 1, "%s %s %s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UDI, UGC, AJT, values) - USE = USE + values[0] - - out[U] = (USE, UBlock) - return out - -use_data = map_to_use(combined) - -print ("/* == Start of generated table == */") -print ("/*") -print (" * The following table is generated by running:") -print (" *") -print (" * {} IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt".format (sys.argv[0])) -print (" *") -print (" * on files with these headers:") -print (" *") -for h in headers: - for l in h: - print (" * %s" % (l.strip())) -print (" */") -print () -print ("#ifndef HB_OT_SHAPER_USE_TABLE_HH") -print ("#define HB_OT_SHAPER_USE_TABLE_HH") -print () -print ('#include "hb.hh"') -print () -print ('#include "hb-ot-shaper-use-machine.hh"') -print () - -total = 0 -used = 0 -last_block = None -def print_block (block, start, end, use_data): - global total, used, last_block - if block and block != last_block: - print () - print () - print (" /* %s */" % block) - if start % 16: - print (' ' * (20 + (start % 16 * 6)), end='') - num = 0 - assert start % 8 == 0 - assert (end+1) % 8 == 0 - for u in range (start, end+1): - if u % 16 == 0: - print () - print (" /* %04X */" % u, end='') - if u in use_data: - num += 1 - d = use_data.get (u) - if d is not None: - d = d[0] - elif u in unicode_data[4]: - d = 'O' - else: - d = 'WJ' - print ("%6s," % d, end='') - - total += end - start + 1 - used += num - if block: - last_block = block - -uu = sorted (use_data.keys ()) - -last = -100000 -num = 0 -offset = 0 -starts = [] -ends = [] -print ('#pragma GCC diagnostic push') -print ('#pragma GCC diagnostic ignored "-Wunused-macros"') -for k,v in sorted(use_mapping.items()): - if k in use_positions and use_positions[k]: continue - print ("#define %s USE(%s) /* %s */" % (k, k, v.__name__[3:])) -for k,v in sorted(use_positions.items()): - if not v: continue - for suf in v.keys(): - tag = k + suf - print ("#define %s USE(%s)" % (tag, tag)) -print ('#pragma GCC diagnostic pop') -print ("") - - -import packTab -data = {u:v[0] for u,v in use_data.items()} - -DEFAULT = 5 -COMPACT = 9 -for compression in (DEFAULT, COMPACT): - - logging.info(' Compression=%d:' % compression) - print() - if compression == DEFAULT: - print('#ifndef HB_OPTIMIZE_SIZE') - elif compression == COMPACT: - print('#else') - else: - assert False - print() - - code = packTab.Code('hb_use') - sol = packTab.pack_table(data, compression=compression, default='O') - logging.info(' FullCost=%d' % (sol.fullCost)) - sol.genCode(code, f'get_category') - code.print_c(linkage='static inline') - print () - -print('#endif') - -print () -for k in sorted(use_mapping.keys()): - if k in use_positions and use_positions[k]: continue - print ("#undef %s" % k) -for k,v in sorted(use_positions.items()): - if not v: continue - for suf in v.keys(): - tag = k + suf - print ("#undef %s" % tag) -print () -print () -print ("#endif /* HB_OT_SHAPER_USE_TABLE_HH */") -print ("/* == End of generated table == */") diff --git a/thirdparty/harfbuzz/upstream/gen-vowel-constraints.py b/thirdparty/harfbuzz/upstream/gen-vowel-constraints.py deleted file mode 100755 index 3c1f6211e..000000000 --- a/thirdparty/harfbuzz/upstream/gen-vowel-constraints.py +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env python3 - -"""Generator of the function to prohibit certain vowel sequences. - -It creates ``_hb_preprocess_text_vowel_constraints``, which inserts dotted -circles into sequences prohibited by the USE script development spec. -This function should be used as the ``preprocess_text`` of an -``hb_ot_shaper_t``. - -usage: ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt - -Input file: -* https://unicode.org/Public/UCD/latest/ucd/Scripts.txt -""" - -import collections -def write (s): - sys.stdout.flush () - sys.stdout.buffer.write (s.encode ('utf-8')) -import sys - -if len (sys.argv) != 3: - sys.exit (__doc__) - -with open (sys.argv[2], encoding='utf-8') as f: - scripts_header = [f.readline () for i in range (2)] - scripts = {} - script_order = {} - for line in f: - j = line.find ('#') - if j >= 0: - line = line[:j] - fields = [x.strip () for x in line.split (';')] - if len (fields) == 1: - continue - uu = fields[0].split ('..') - start = int (uu[0], 16) - if len (uu) == 1: - end = start - else: - end = int (uu[1], 16) - script = fields[1] - for u in range (start, end + 1): - scripts[u] = script - if script not in script_order: - script_order[script] = start - -class ConstraintSet (object): - """A set of prohibited code point sequences. - - Args: - constraint (List[int]): A prohibited code point sequence. - - """ - def __init__ (self, constraint): - # Either a list or a dictionary. As a list of code points, it - # represents a prohibited code point sequence. As a dictionary, - # it represents a set of prohibited sequences, where each item - # represents the set of prohibited sequences starting with the - # key (a code point) concatenated with any of the values - # (ConstraintSets). - self._c = constraint - - def add (self, constraint): - """Add a constraint to this set.""" - if not constraint: - return - first = constraint[0] - rest = constraint[1:] - if isinstance (self._c, list): - if constraint == self._c[:len (constraint)]: - self._c = constraint - elif self._c != constraint[:len (self._c)]: - self._c = {self._c[0]: ConstraintSet (self._c[1:])} - if isinstance (self._c, dict): - if first in self._c: - self._c[first].add (rest) - else: - self._c[first] = ConstraintSet (rest) - - @staticmethod - def _indent (depth): - return (' ' * depth).replace (' ', '\t') - - def __str__ (self, index=0, depth=4): - s = [] - indent = self._indent (depth) - if isinstance (self._c, list): - if len (self._c) == 0: - assert index == 2, 'Cannot use `matched` for this constraint; the general case has not been implemented' - s.append ('{}matched = true;\n'.format (indent)) - elif len (self._c) == 1: - assert index == 1, 'Cannot use `matched` for this constraint; the general case has not been implemented' - s.append ('{}matched = 0x{:04X}u == buffer->cur ({}).codepoint;\n'.format (indent, next (iter (self._c)), index or '')) - else: - s.append ('{}if (0x{:04X}u == buffer->cur ({}).codepoint &&\n'.format (indent, self._c[0], index or '')) - if index: - s.append ('{}buffer->idx + {} < count &&\n'.format (self._indent (depth + 2), index + 1)) - for i, cp in enumerate (self._c[1:], start=1): - s.append ('{}0x{:04X}u == buffer->cur ({}).codepoint{}\n'.format ( - self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&')) - s.append ('{}{{\n'.format (indent)) - for i in range (index): - s.append ('{}(void) buffer->next_glyph ();\n'.format (self._indent (depth + 1))) - s.append ('{}matched = true;\n'.format (self._indent (depth + 1))) - s.append ('{}}}\n'.format (indent)) - else: - s.append ('{}switch (buffer->cur ({}).codepoint)\n'.format(indent, index or '')) - s.append ('{}{{\n'.format (indent)) - cases = collections.defaultdict (set) - for first, rest in sorted (self._c.items ()): - cases[rest.__str__ (index + 1, depth + 2)].add (first) - for body, labels in sorted (cases.items (), key=lambda b_ls: sorted (b_ls[1])[0]): - for i, cp in enumerate (sorted (labels)): - if i % 4 == 0: - s.append (self._indent (depth + 1)) - else: - s.append (' ') - s.append ('case 0x{:04X}u:{}'.format (cp, '\n' if i % 4 == 3 else '')) - if len (labels) % 4 != 0: - s.append ('\n') - s.append (body) - s.append ('{}break;\n'.format (self._indent (depth + 2))) - s.append ('{}}}\n'.format (indent)) - return ''.join (s) - -constraints = {} -with open (sys.argv[1], encoding='utf-8') as f: - constraints_header = [] - while True: - line = f.readline ().strip () - if line == '#': - break - constraints_header.append(line) - for line in f: - j = line.find ('#') - if j >= 0: - line = line[:j] - constraint = [int (cp, 16) for cp in line.split (';')[0].split ()] - if not constraint: continue - assert 2 <= len (constraint), 'Prohibited sequence is too short: {}'.format (constraint) - script = scripts[constraint[0]] - if script in constraints: - constraints[script].add (constraint) - else: - constraints[script] = ConstraintSet (constraint) - assert constraints, 'No constraints found' - -print ('/* == Start of generated functions == */') -print ('/*') -print (' * The following functions are generated by running:') -print (' *') -print (' * %s ms-use/IndicShapingInvalidCluster.txt Scripts.txt' % sys.argv[0]) -print (' *') -print (' * on files with these headers:') -print (' *') -for line in constraints_header: - print (' * %s' % line.strip ()) -print (' *') -for line in scripts_header: - print (' * %s' % line.strip ()) -print (' */') - -print () -print ('#include "hb.hh"') -print () -print ('#ifndef HB_NO_OT_SHAPE') -print () -print ('#include "hb-ot-shaper-vowel-constraints.hh"') -print () -print ('static void') -print ('_output_dotted_circle (hb_buffer_t *buffer)') -print ('{') -print (' (void) buffer->output_glyph (0x25CCu);') -print (' _hb_glyph_info_reset_continuation (&buffer->prev());') -print ('}') -print () -print ('static void') -print ('_output_with_dotted_circle (hb_buffer_t *buffer)') -print ('{') -print (' _output_dotted_circle (buffer);') -print (' (void) buffer->next_glyph ();') -print ('}') -print () - -print ('void') -print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,') -print ('\t\t\t\t hb_buffer_t *buffer,') -print ('\t\t\t\t hb_font_t *font HB_UNUSED)') -print ('{') -print ('#ifdef HB_NO_OT_SHAPER_VOWEL_CONSTRAINTS') -print (' return;') -print ('#endif') -print (' if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)') -print (' return;') -print () -print (' /* UGLY UGLY UGLY business of adding dotted-circle in the middle of') -print (' * vowel-sequences that look like another vowel. Data for each script') -print (' * collected from the USE script development spec.') -print (' *') -print (' * https://github.com/harfbuzz/harfbuzz/issues/1019') -print (' */') -print (' buffer->clear_output ();') -print (' unsigned int count = buffer->len;') -print (' switch ((unsigned) buffer->props.script)') -print (' {') - -for script, constraints in sorted (constraints.items (), key=lambda s_c: script_order[s_c[0]]): - print (' case HB_SCRIPT_{}:'.format (script.upper ())) - print (' for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)') - print (' {') - print ('\tbool matched = false;') - write (str (constraints)) - print ('\t(void) buffer->next_glyph ();') - print ('\tif (matched) _output_with_dotted_circle (buffer);') - print (' }') - print (' break;') - print () - -print (' default:') -print (' break;') -print (' }') -print (' buffer->sync ();') -print ('}') - -print () -print () -print ('#endif') -print ('/* == End of generated functions == */') diff --git a/thirdparty/harfbuzz/upstream/graph/classdef-graph.hh b/thirdparty/harfbuzz/upstream/graph/classdef-graph.hh index da6378820..d1f38b9de 100644 --- a/thirdparty/harfbuzz/upstream/graph/classdef-graph.hh +++ b/thirdparty/harfbuzz/upstream/graph/classdef-graph.hh @@ -74,7 +74,7 @@ struct ClassDef : public OT::ClassDef class_def_link->width = SmallTypes::size; class_def_link->objidx = class_def_prime_id; class_def_link->position = link_position; - class_def_prime_vertex.add_parent (parent_id); + class_def_prime_vertex.add_parent (parent_id, false); return true; } @@ -117,7 +117,7 @@ struct ClassDef : public OT::ClassDef int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::ClassDef::min_size) return false; hb_barrier (); - switch (u.format) + switch (u.format.v) { case 1: return ((ClassDefFormat1*)this)->sanitize (vertex); case 2: return ((ClassDefFormat2*)this)->sanitize (vertex); diff --git a/thirdparty/harfbuzz/upstream/graph/coverage-graph.hh b/thirdparty/harfbuzz/upstream/graph/coverage-graph.hh index 61ca063e3..46c703524 100644 --- a/thirdparty/harfbuzz/upstream/graph/coverage-graph.hh +++ b/thirdparty/harfbuzz/upstream/graph/coverage-graph.hh @@ -32,29 +32,27 @@ namespace graph { -struct CoverageFormat1 : public OT::Layout::Common::CoverageFormat1_3 -{ - bool sanitize (graph_t::vertex_t& vertex) const - { - int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; - if (vertex_len < min_size) return false; - hb_barrier (); - return vertex_len >= min_size + glyphArray.get_size () - glyphArray.len.get_size (); - } -}; +static bool sanitize ( + const OT::Layout::Common::CoverageFormat1_3* thiz, + graph_t::vertex_t& vertex +) { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat1_3::min_size; + if (vertex_len < min_size) return false; + hb_barrier (); + return vertex_len >= min_size + thiz->glyphArray.get_size () - thiz->glyphArray.len.get_size (); +} -struct CoverageFormat2 : public OT::Layout::Common::CoverageFormat2_4 -{ - bool sanitize (graph_t::vertex_t& vertex) const - { - int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; - if (vertex_len < min_size) return false; - hb_barrier (); - return vertex_len >= min_size + rangeRecord.get_size () - rangeRecord.len.get_size (); - } -}; +static bool sanitize ( + const OT::Layout::Common::CoverageFormat2_4* thiz, + graph_t::vertex_t& vertex +) { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + constexpr unsigned min_size = OT::Layout::Common::CoverageFormat2_4::min_size; + if (vertex_len < min_size) return false; + hb_barrier (); + return vertex_len >= min_size + thiz->rangeRecord.get_size () - thiz->rangeRecord.len.get_size (); +} struct Coverage : public OT::Layout::Common::Coverage { @@ -98,11 +96,33 @@ struct Coverage : public OT::Layout::Common::Coverage coverage_link->width = SmallTypes::size; coverage_link->objidx = coverage_prime_id; coverage_link->position = link_position; - coverage_prime_vertex.add_parent (parent_id); + coverage_prime_vertex.add_parent (parent_id, false); return (Coverage*) coverage_prime_vertex.obj.head; } + // Filter an existing coverage table to glyphs at indices [start, end) and replace it with the filtered version. + static bool filter_coverage (gsubgpos_graph_context_t& c, + unsigned existing_coverage, + unsigned start, unsigned end) { + unsigned coverage_size = c.graph.vertices_[existing_coverage].table_size (); + auto& coverage_v = c.graph.vertices_[existing_coverage]; + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + if (!coverage_table || !coverage_table->sanitize (coverage_v)) + return false; + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second >= start && p.second < end; + }) + | hb_map_retains_sorting (hb_first) + ; + + return make_coverage (c, new_coverage, existing_coverage, coverage_size * 2 + 100); + } + + // Replace the coverage table at dest obj with one covering 'glyphs'. template static bool make_coverage (gsubgpos_graph_context_t& c, It glyphs, @@ -141,10 +161,10 @@ struct Coverage : public OT::Layout::Common::Coverage int64_t vertex_len = vertex.obj.tail - vertex.obj.head; if (vertex_len < OT::Layout::Common::Coverage::min_size) return false; hb_barrier (); - switch (u.format) + switch (u.format.v) { - case 1: return ((CoverageFormat1*)this)->sanitize (vertex); - case 2: return ((CoverageFormat2*)this)->sanitize (vertex); + case 1: return graph::sanitize ((const OT::Layout::Common::CoverageFormat1_3*) this, vertex); + case 2: return graph::sanitize ((const OT::Layout::Common::CoverageFormat2_4*) this, vertex); #ifndef HB_NO_BEYOND_64K // Not currently supported case 3: diff --git a/thirdparty/harfbuzz/upstream/graph/graph.hh b/thirdparty/harfbuzz/upstream/graph/graph.hh index b24507ece..af8b31258 100644 --- a/thirdparty/harfbuzz/upstream/graph/graph.hh +++ b/thirdparty/harfbuzz/upstream/graph/graph.hh @@ -50,6 +50,7 @@ struct graph_t private: unsigned incoming_edges_ = 0; unsigned single_parent = (unsigned) -1; + bool has_incoming_virtual_edges_ = false; hb_hashmap_t parents; public: @@ -66,6 +67,11 @@ struct graph_t return parents.in_error (); } + bool has_incoming_virtual_edges () const + { + return has_incoming_virtual_edges_; + } + bool link_positions_valid (unsigned num_objects, bool removed_nil) { hb_set_t assigned_bytes; @@ -121,7 +127,9 @@ struct graph_t } } - bool equals (const vertex_t& other, + bool equals (unsigned this_index, + unsigned other_index, + const vertex_t& other, const graph_t& graph, const graph_t& other_graph, unsigned depth) const @@ -129,8 +137,10 @@ struct graph_t if (!(as_bytes () == other.as_bytes ())) { DEBUG_MSG (SUBSET_REPACK, nullptr, - "vertex [%lu] bytes != [%lu] bytes, depth = %u", + "vertex %u [%lu bytes] != %u [%lu bytes], depth = %u", + this_index, (unsigned long) table_size (), + other_index, (unsigned long) other.table_size (), depth); @@ -162,6 +172,7 @@ struct graph_t hb_swap (a.single_parent, b.single_parent); hb_swap (a.parents, b.parents); hb_swap (a.incoming_edges_, b.incoming_edges_); + hb_swap (a.has_incoming_virtual_edges_, b.has_incoming_virtual_edges_); hb_swap (a.start, b.start); hb_swap (a.end, b.end); hb_swap (a.priority, b.priority); @@ -207,13 +218,16 @@ struct graph_t void reset_parents () { incoming_edges_ = 0; + has_incoming_virtual_edges_ = false; single_parent = (unsigned) -1; parents.reset (); } - void add_parent (unsigned parent_index) + void add_parent (unsigned parent_index, bool is_virtual) { assert (parent_index != (unsigned) -1); + has_incoming_virtual_edges_ |= is_virtual; + if (incoming_edges_ == 0) { single_parent = parent_index; @@ -408,7 +422,7 @@ struct graph_t link_a.bias != link_b.bias) return false; - if (!graph.vertices_[link_a.objidx].equals ( + if (!graph.vertices_[link_a.objidx].equals (link_a.objidx, link_b.objidx, other_graph.vertices_[link_b.objidx], graph, other_graph, depth + 1)) return false; @@ -456,8 +470,12 @@ struct graph_t num_roots_for_space_.push (1); bool removed_nil = false; vertices_.alloc (objects.length); - vertices_scratch_.alloc (objects.length); + ordering_.resize (objects.length); + ordering_scratch_.alloc (objects.length); + unsigned count = objects.length; + unsigned order = objects.length; + unsigned skip = 0; for (unsigned i = 0; i < count; i++) { // If this graph came from a serialization buffer object 0 is the @@ -465,6 +483,9 @@ struct graph_t if (i == 0 && !objects.arrayZ[i]) { removed_nil = true; + order--; + ordering_.resize(objects.length - 1); + skip++; continue; } @@ -474,6 +495,12 @@ struct graph_t check_success (v->link_positions_valid (count, removed_nil)); + // To start we set the ordering to match the provided objects + // list. Note: objects are provided to us in reverse order (ie. + // the last object is the root). + unsigned obj_idx = i - skip; + ordering_[--order] = obj_idx; + if (!removed_nil) continue; // Fix indices to account for removed nil object. for (auto& l : v->obj.all_links_writer ()) { @@ -490,17 +517,20 @@ struct graph_t bool operator== (const graph_t& other) const { - return root ().equals (other.root (), *this, other, 0); + return root ().equals (root_idx(), other.root_idx(), other.root (), *this, other, 0); } void print () const { - for (int i = vertices_.length - 1; i >= 0; i--) + for (unsigned id : ordering_) { - const auto& v = vertices_[i]; - printf("%d: %u [", i, (unsigned int)v.table_size()); + const auto& v = vertices_[id]; + printf("%u: %u [", id, (unsigned int)v.table_size()); for (const auto &l : v.obj.real_links) { printf("%u, ", l.objidx); } + for (const auto &l : v.obj.virtual_links) { + printf("v%u, ", l.objidx); + } printf("]\n"); } } @@ -516,6 +546,7 @@ struct graph_t { return !successful || vertices_.in_error () || + ordering_.in_error() || num_roots_for_space_.in_error (); } @@ -526,10 +557,10 @@ struct graph_t unsigned root_idx () const { - // Object graphs are in reverse order, the first object is at the end - // of the vector. Since the graph is topologically sorted it's safe to + // First element of ordering_ is the root. + // Since the graph is topologically sorted it's safe to // assume the first object has no incoming edges. - return vertices_.length - 1; + return ordering_[0]; } const hb_serialize_context_t::object_t& object (unsigned i) const @@ -556,7 +587,7 @@ struct graph_t link->width = 2; link->objidx = child_id; link->position = (char*) offset - (char*) v.obj.head; - vertices_[child_id].add_parent (parent_id); + vertices_[child_id].add_parent (parent_id, false); } /* @@ -587,55 +618,51 @@ struct graph_t hb_priority_queue_t queue; queue.alloc (vertices_.length); - hb_vector_t &sorted_graph = vertices_scratch_; - if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; - hb_vector_t id_map; - if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; + hb_vector_t &new_ordering = ordering_scratch_; + if (unlikely (!check_success (new_ordering.resize (vertices_.length)))) return; hb_vector_t removed_edges; if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; update_parents (); queue.insert (root ().modified_distance (0), root_idx ()); - int new_id = root_idx (); unsigned order = 1; + unsigned pos = 0; while (!queue.in_error () && !queue.is_empty ()) { unsigned next_id = queue.pop_minimum().second; - sorted_graph[new_id] = std::move (vertices_[next_id]); - const vertex_t& next = sorted_graph[new_id]; - - if (unlikely (!check_success(new_id >= 0))) { + if (unlikely (!check_success(pos < new_ordering.length))) { // We are out of ids. Which means we've visited a node more than once. // This graph contains a cycle which is not allowed. DEBUG_MSG (SUBSET_REPACK, nullptr, "Invalid graph. Contains cycle."); return; } - - id_map[next_id] = new_id--; + new_ordering[pos++] = next_id; + const vertex_t& next = vertices_[next_id]; for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; - if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) + const auto& v = vertices_[link.objidx]; + if (!(v.incoming_edges () - removed_edges[link.objidx])) // Add the order that the links were encountered to the priority. // This ensures that ties between priorities objects are broken in a consistent // way. More specifically this is set up so that if a set of objects have the same // distance they'll be added to the topological order in the order that they are // referenced from the parent object. - queue.insert (vertices_[link.objidx].modified_distance (order++), + queue.insert (v.modified_distance (order++), link.objidx); } } check_success (!queue.in_error ()); - check_success (!sorted_graph.in_error ()); + check_success (!new_ordering.in_error ()); - check_success (remap_all_obj_indices (id_map, &sorted_graph)); - vertices_ = std::move (sorted_graph); + hb_swap (ordering_, new_ordering); - if (!check_success (new_id == -1)) + if (!check_success (pos == vertices_.length)) { print_orphaned_nodes (); + } } /* @@ -645,8 +672,8 @@ struct graph_t */ void find_space_roots (hb_set_t& visited, hb_set_t& roots) { - int root_index = (int) root_idx (); - for (int i = root_index; i >= 0; i--) + unsigned root_index = root_idx (); + for (unsigned i : ordering_) { if (visited.has (i)) continue; @@ -829,7 +856,6 @@ struct graph_t if (subgraph.in_error ()) return false; - unsigned original_root_idx = root_idx (); hb_map_t index_map; bool made_changes = false; for (auto entry : subgraph.iter ()) @@ -852,14 +878,6 @@ struct graph_t if (!made_changes) return false; - if (original_root_idx != root_idx () - && parents.has (original_root_idx)) - { - // If the root idx has changed since parents was determined, update root idx in parents - parents.add (root_idx ()); - parents.del (original_root_idx); - } - auto new_subgraph = + subgraph.keys () | hb_map([&] (uint32_t node_idx) { @@ -943,12 +961,14 @@ struct graph_t /* * Moves the child of old_parent_idx pointed to by old_offset to a new * vertex at the new_offset. + * + * Returns the id of the child node that was moved. */ template - void move_child (unsigned old_parent_idx, - const O* old_offset, - unsigned new_parent_idx, - const O* new_offset) + unsigned move_child (unsigned old_parent_idx, + const O* old_offset, + unsigned new_parent_idx, + const O* new_offset) { distance_invalid = true; positions_invalid = true; @@ -965,10 +985,56 @@ struct graph_t new_link->position = (const char*) new_offset - (const char*) new_v.obj.head; auto& child = vertices_[child_id]; - child.add_parent (new_parent_idx); + child.add_parent (new_parent_idx, false); old_v.remove_real_link (child_id, old_offset); child.remove_parent (old_parent_idx); + + return child_id; + } + + /* + * Moves all outgoing links in old parent that have + * a link position between [old_post_start, old_pos_end) + * to the new parent. Links are placed serially in the new + * parent starting at new_pos_start. + */ + template + void move_children (unsigned old_parent_idx, + unsigned old_pos_start, + unsigned old_pos_end, + unsigned new_parent_idx, + unsigned new_pos_start) + { + distance_invalid = true; + positions_invalid = true; + + auto& old_v = vertices_[old_parent_idx]; + auto& new_v = vertices_[new_parent_idx]; + + hb_vector_t old_links; + for (const auto& l : old_v.obj.real_links) + { + if (l.position < old_pos_start || l.position >= old_pos_end) + { + old_links.push(l); + continue; + } + + unsigned array_pos = l.position - old_pos_start; + + unsigned child_id = l.objidx; + auto* new_link = new_v.obj.real_links.push (); + new_link->width = O::static_size; + new_link->objidx = child_id; + new_link->position = new_pos_start + array_pos; + + auto& child = vertices_[child_id]; + child.add_parent (new_parent_idx, false); + child.remove_parent (old_parent_idx); + } + + old_v.obj.real_links = std::move (old_links); } /* @@ -1000,8 +1066,11 @@ struct graph_t distance_invalid = true; auto* clone = vertices_.push (); + unsigned clone_idx = vertices_.length - 1; + ordering_.push(clone_idx); + auto& child = vertices_[node_idx]; - if (vertices_.in_error ()) { + if (vertices_.in_error () || ordering_.in_error()) { return -1; } @@ -1011,51 +1080,23 @@ struct graph_t clone->space = child.space; clone->reset_parents (); - unsigned clone_idx = vertices_.length - 2; for (const auto& l : child.obj.real_links) { clone->obj.real_links.push (l); - vertices_[l.objidx].add_parent (clone_idx); + vertices_[l.objidx].add_parent (clone_idx, false); } for (const auto& l : child.obj.virtual_links) { clone->obj.virtual_links.push (l); - vertices_[l.objidx].add_parent (clone_idx); + vertices_[l.objidx].add_parent (clone_idx, true); } check_success (!clone->obj.real_links.in_error ()); check_success (!clone->obj.virtual_links.in_error ()); - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); - - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); - return clone_idx; } - /* - * Creates a copy of child and re-assigns the link from - * parent to the clone. The copy is a shallow copy, objects - * linked from child are not duplicated. - * - * Returns the index of the newly created duplicate. - * - * If the child_idx only has incoming edges from parent_idx, this - * will do nothing and return the original child_idx. - */ - unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx) - { - unsigned new_idx = duplicate (parent_idx, child_idx); - if (new_idx == (unsigned) -1) return child_idx; - return new_idx; - } - - /* * Creates a copy of child and re-assigns the link from * parent to the clone. The copy is a shallow copy, objects @@ -1073,10 +1114,15 @@ struct graph_t const auto& child = vertices_[child_idx]; unsigned links_to_child = child.incoming_edges_from_parent(parent_idx); - if (child.incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. + // + // We don't allow duplication of nodes with incoming virtual edges because we don't track + // the number of virtual vs real incoming edges. As a result we can't tell if a node + // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed + // to by virtual edges). DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u => %u", parent_idx, child_idx); return -1; @@ -1091,12 +1137,15 @@ struct graph_t if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; + unsigned count = 0; + unsigned num_real = parent.obj.real_links.length; for (auto& l : parent.obj.all_links_writer ()) { + count++; if (l.objidx != child_idx) continue; - reassign_link (l, parent_idx, clone_idx); + reassign_link (l, parent_idx, clone_idx, count > num_real); } return clone_idx; @@ -1129,10 +1178,15 @@ struct graph_t links_to_child += child.incoming_edges_from_parent(parent_idx); } - if (child.incoming_edges () <= links_to_child) + if (child.incoming_edges () <= links_to_child || child.has_incoming_virtual_edges()) { // Can't duplicate this node, doing so would orphan the original one as all remaining links // to child are from parent. + // + // We don't allow duplication of nodes with incoming virtual edges because we don't track + // the number of virtual vs real incoming edges. As a result we can't tell if a node + // with virtual edges may end up orphaned by duplication (ie. where one copy is only pointed + // to by virtual edges). DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %u, ..., %u => %u", first_parent, last_parent, child_idx); return -1; } @@ -1146,12 +1200,15 @@ struct graph_t // duplicate shifts the root node idx, so if parent_idx was root update it. if (parent_idx == clone_idx) parent_idx++; auto& parent = vertices_[parent_idx]; + unsigned count = 0; + unsigned num_real = parent.obj.real_links.length; for (auto& l : parent.obj.all_links_writer ()) { + count++; if (l.objidx != child_idx) continue; - reassign_link (l, parent_idx, clone_idx); + reassign_link (l, parent_idx, clone_idx, count > num_real); } } @@ -1168,7 +1225,10 @@ struct graph_t distance_invalid = true; auto* clone = vertices_.push (); - if (vertices_.in_error ()) { + unsigned clone_idx = vertices_.length - 1; + ordering_.push(clone_idx); + + if (vertices_.in_error () || ordering_.in_error()) { return -1; } @@ -1177,18 +1237,35 @@ struct graph_t clone->distance = 0; clone->space = 0; - unsigned clone_idx = vertices_.length - 2; + return clone_idx; + } - // The last object is the root of the graph, so swap back the root to the end. - // The root's obj idx does change, however since it's root nothing else refers to it. - // all other obj idx's will be unaffected. - hb_swap (vertices_[vertices_.length - 2], *clone); + /* + * Creates a new child node and remap the old child to it. + * + * Returns the index of the newly created child. + * + */ + unsigned remap_child (unsigned parent_idx, unsigned old_child_idx) + { + unsigned new_child_idx = duplicate (old_child_idx); + if (new_child_idx == (unsigned) -1) return -1; - // Since the root moved, update the parents arrays of all children on the root. - for (const auto& l : root ().obj.all_links ()) - vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); + auto& parent = vertices_[parent_idx]; + for (auto& l : parent.obj.real_links) + { + if (l.objidx != old_child_idx) + continue; + reassign_link (l, parent_idx, new_child_idx, false); + } - return clone_idx; + for (auto& l : parent.obj.virtual_links) + { + if (l.objidx != old_child_idx) + continue; + reassign_link (l, parent_idx, new_child_idx, true); + } + return new_child_idx; } /* @@ -1279,6 +1356,7 @@ struct graph_t if (!DEBUG_ENABLED(SUBSET_REPACK)) return; DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + parents_invalid = true; update_parents(); @@ -1348,7 +1426,8 @@ struct graph_t size_t total_size = 0; unsigned count = vertices_.length; for (unsigned i = 0; i < count; i++) { - size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head; + const auto& obj = vertices_.arrayZ[i].obj; + size_t size = obj.tail - obj.head; total_size += size; } return total_size; @@ -1398,8 +1477,11 @@ struct graph_t for (unsigned p = 0; p < count; p++) { - for (auto& l : vertices_.arrayZ[p].obj.all_links ()) - vertices_[l.objidx].add_parent (p); + for (auto& l : vertices_.arrayZ[p].obj.real_links) + vertices_[l.objidx].add_parent (p, false); + + for (auto& l : vertices_.arrayZ[p].obj.virtual_links) + vertices_[l.objidx].add_parent (p, true); } for (unsigned i = 0; i < count; i++) @@ -1418,7 +1500,7 @@ struct graph_t if (!positions_invalid) return; unsigned current_pos = 0; - for (int i = root_idx (); i >= 0; i--) + for (unsigned i : ordering_) { auto& v = vertices_[i]; v.start = current_pos; @@ -1450,11 +1532,11 @@ struct graph_t unsigned count = vertices_.length; for (unsigned i = 0; i < count; i++) vertices_.arrayZ[i].distance = hb_int_max (int64_t); - vertices_.tail ().distance = 0; + vertices_[root_idx ()].distance = 0; hb_priority_queue_t queue; queue.alloc (count); - queue.insert (0, vertices_.length - 1); + queue.insert (0, root_idx ()); hb_vector_t visited; visited.resize (vertices_.length); @@ -1464,22 +1546,23 @@ struct graph_t unsigned next_idx = queue.pop_minimum ().second; if (visited[next_idx]) continue; const auto& next = vertices_[next_idx]; - int64_t next_distance = vertices_[next_idx].distance; + int64_t next_distance = next.distance; visited[next_idx] = true; for (const auto& link : next.obj.all_links ()) { if (visited[link.objidx]) continue; - const auto& child = vertices_.arrayZ[link.objidx].obj; + auto& child_v = vertices_.arrayZ[link.objidx]; + const auto& child = child_v.obj; unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide int64_t child_weight = (child.tail - child.head) + - ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1); + ((int64_t) 1 << (link_width * 8)) * (child_v.space + 1); int64_t child_distance = next_distance + child_weight; - if (child_distance < vertices_.arrayZ[link.objidx].distance) + if (child_distance < child_v.distance) { - vertices_.arrayZ[link.objidx].distance = child_distance; + child_v.distance = child_distance; queue.insert (child_distance, link.objidx); } } @@ -1502,12 +1585,13 @@ struct graph_t */ void reassign_link (hb_serialize_context_t::object_t::link_t& link, unsigned parent_idx, - unsigned new_idx) + unsigned new_idx, + bool is_virtual) { unsigned old_idx = link.objidx; link.objidx = new_idx; vertices_[old_idx].remove_parent (parent_idx); - vertices_[new_idx].add_parent (parent_idx); + vertices_[new_idx].add_parent (parent_idx, is_virtual); } /* @@ -1521,36 +1605,21 @@ struct graph_t if (!id_map) return; for (unsigned i : subgraph) { - for (auto& link : vertices_[i].obj.all_links_writer ()) + auto& obj = vertices_[i].obj; + unsigned num_real = obj.real_links.length; + unsigned count = 0; + for (auto& link : obj.all_links_writer ()) { + count++; const uint32_t *v; if (!id_map.has (link.objidx, &v)) continue; - if (only_wide && !(link.width == 4 && !link.is_signed)) continue; + if (only_wide && (link.is_signed || (link.width != 4 && link.width != 3))) continue; - reassign_link (link, i, *v); + reassign_link (link, i, *v, count > num_real); } } } - /* - * Updates all objidx's in all links using the provided mapping. - */ - bool remap_all_obj_indices (const hb_vector_t& id_map, - hb_vector_t* sorted_graph) const - { - unsigned count = sorted_graph->length; - for (unsigned i = 0; i < count; i++) - { - if (!(*sorted_graph)[i].remap_parents (id_map)) - return false; - for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ()) - { - link.objidx = id_map[link.objidx]; - } - } - return true; - } - /* * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. * For this search the graph is treated as being undirected. @@ -1586,7 +1655,16 @@ struct graph_t public: // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. hb_vector_t vertices_; - hb_vector_t vertices_scratch_; + + // Specifies the current topological ordering of this graph + // + // ordering_[pos] = obj index + // + // specifies that the 'pos'th spot is filled by the object + // given by obj index. + hb_vector_t ordering_; + hb_vector_t ordering_scratch_; + private: bool parents_invalid; bool distance_invalid; diff --git a/thirdparty/harfbuzz/upstream/graph/gsubgpos-context.hh b/thirdparty/harfbuzz/upstream/graph/gsubgpos-context.hh index b25d538fe..8969d0078 100644 --- a/thirdparty/harfbuzz/upstream/graph/gsubgpos-context.hh +++ b/thirdparty/harfbuzz/upstream/graph/gsubgpos-context.hh @@ -41,6 +41,7 @@ struct gsubgpos_graph_context_t unsigned lookup_list_index; hb_hashmap_t lookups; hb_hashmap_t subtable_to_extension; + hb_hashmap_t> split_subtables; HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_, graph_t& graph_); diff --git a/thirdparty/harfbuzz/upstream/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/upstream/graph/gsubgpos-graph.hh index 0f6d5662e..ea6bcd239 100644 --- a/thirdparty/harfbuzz/upstream/graph/gsubgpos-graph.hh +++ b/thirdparty/harfbuzz/upstream/graph/gsubgpos-graph.hh @@ -27,9 +27,11 @@ #include "graph.hh" #include "../hb-ot-layout-gsubgpos.hh" #include "../OT/Layout/GSUB/ExtensionSubst.hh" +#include "../OT/Layout/GSUB/SubstLookupSubTable.hh" #include "gsubgpos-context.hh" #include "pairpos-graph.hh" #include "markbasepos-graph.hh" +#include "ligature-graph.hh" #ifndef GRAPH_GSUBGPOS_GRAPH_HH #define GRAPH_GSUBGPOS_GRAPH_HH @@ -85,6 +87,12 @@ struct Lookup : public OT::Lookup return lookupType == extension_type (table_tag); } + bool use_mark_filtering_set () const + { + unsigned flag = lookupFlag; + return flag & 0x0010u; + } + bool make_extension (gsubgpos_graph_context_t& c, unsigned this_index) { @@ -120,22 +128,18 @@ struct Lookup : public OT::Lookup unsigned type = lookupType; bool is_ext = is_extension (c.table_tag); - if (c.table_tag != HB_OT_TAG_GPOS) + if (c.table_tag != HB_OT_TAG_GPOS && c.table_tag != HB_OT_TAG_GSUB) return true; - if (!is_ext && - type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair && - type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + if (!is_ext && !is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) return true; hb_vector_t>> all_new_subtables; for (unsigned i = 0; i < subTable.len; i++) { unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]); - unsigned parent_index = this_index; if (is_ext) { unsigned ext_subtable_index = subtable_index; - parent_index = ext_subtable_index; ExtensionFormat1* extension = (ExtensionFormat1*) c.graph.object (ext_subtable_index).head; @@ -144,26 +148,47 @@ struct Lookup : public OT::Lookup subtable_index = extension->get_subtable_index (c.graph, ext_subtable_index); type = extension->get_lookup_type (); - if (type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair - && type != OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase) + if (!is_supported_gpos_type(type, c) && !is_supported_gsub_type(type, c)) continue; } - hb_vector_t new_sub_tables; - switch (type) + hb_vector_t* split_result; + if (c.split_subtables.has (subtable_index, &split_result)) + { + if (split_result->length == 0) + continue; + all_new_subtables.push (hb_pair(i, *split_result)); + } + else { - case 2: - new_sub_tables = split_subtable (c, parent_index, subtable_index); break; - case 4: - new_sub_tables = split_subtable (c, parent_index, subtable_index); break; - default: - break; + hb_vector_t new_sub_tables; + + if (c.table_tag == HB_OT_TAG_GPOS) { + switch (type) + { + case 2: + new_sub_tables = split_subtable (c, subtable_index); break; + case 4: + new_sub_tables = split_subtable (c, subtable_index); break; + default: + break; + } + } else if (c.table_tag == HB_OT_TAG_GSUB) { + switch (type) + { + case 4: + new_sub_tables = split_subtable (c, subtable_index); break; + default: + break; + } + } + + if (new_sub_tables.in_error ()) return false; + + c.split_subtables.set (subtable_index, new_sub_tables); + if (new_sub_tables) + all_new_subtables.push (hb_pair (i, std::move (new_sub_tables))); } - if (new_sub_tables.in_error ()) return false; - if (!new_sub_tables) continue; - hb_pair_t>* entry = all_new_subtables.push (); - entry->first = i; - entry->second = std::move (new_sub_tables); } if (all_new_subtables) { @@ -175,30 +200,29 @@ struct Lookup : public OT::Lookup template hb_vector_t split_subtable (gsubgpos_graph_context_t& c, - unsigned parent_idx, unsigned objidx) { T* sub_table = (T*) c.graph.object (objidx).head; if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx])) return hb_vector_t (); - return sub_table->split_subtables (c, parent_idx, objidx); + return sub_table->split_subtables (c, objidx); } bool add_sub_tables (gsubgpos_graph_context_t& c, unsigned this_index, unsigned type, - hb_vector_t>>& subtable_ids) + const hb_vector_t>>& subtable_ids) { bool is_ext = is_extension (c.table_tag); - auto& v = c.graph.vertices_[this_index]; + auto* v = &c.graph.vertices_[this_index]; fix_existing_subtable_links (c, this_index, subtable_ids); unsigned new_subtable_count = 0; for (const auto& p : subtable_ids) new_subtable_count += p.second.length; - size_t new_size = v.table_size () + size_t new_size = v->table_size () + new_subtable_count * OT::Offset16::static_size; char* buffer = (char*) hb_calloc (1, new_size); if (!buffer) return false; @@ -207,10 +231,13 @@ struct Lookup : public OT::Lookup hb_free (buffer); return false; } - hb_memcpy (buffer, v.obj.head, v.table_size()); + hb_memcpy (buffer, v->obj.head, v->table_size()); - v.obj.head = buffer; - v.obj.tail = buffer + new_size; + if (use_mark_filtering_set ()) + hb_memcpy (buffer + new_size - 2, v->obj.tail - 2, 2); + + v->obj.head = buffer; + v->obj.tail = buffer + new_size; Lookup* new_lookup = (Lookup*) buffer; @@ -226,21 +253,23 @@ struct Lookup : public OT::Lookup if (is_ext) { unsigned ext_id = create_extension_subtable (c, subtable_id, type); - c.graph.vertices_[subtable_id].add_parent (ext_id); + c.graph.vertices_[subtable_id].add_parent (ext_id, false); subtable_id = ext_id; + // the reference to v may have changed on adding a node, so reassign it. + v = &c.graph.vertices_[this_index]; } - auto* link = v.obj.real_links.push (); + auto* link = v->obj.real_links.push (); link->width = 2; link->objidx = subtable_id; link->position = (char*) &new_lookup->subTable[offset_index++] - (char*) new_lookup; - c.graph.vertices_[subtable_id].add_parent (this_index); + c.graph.vertices_[subtable_id].add_parent (this_index, false); } } // Repacker sort order depends on link order, which we've messed up so resort it. - v.obj.real_links.qsort (); + v->obj.real_links.qsort (); // The head location of the lookup has changed, invalidating the lookups map entry // in the context. Update the map. @@ -250,17 +279,15 @@ struct Lookup : public OT::Lookup void fix_existing_subtable_links (gsubgpos_graph_context_t& c, unsigned this_index, - hb_vector_t>>& subtable_ids) + const hb_vector_t>>& subtable_ids) { auto& v = c.graph.vertices_[this_index]; - Lookup* lookup = (Lookup*) v.obj.head; - unsigned shift = 0; for (const auto& p : subtable_ids) { unsigned insert_index = p.first + shift; unsigned pos_offset = p.second.length * OT::Offset16::static_size; - unsigned insert_offset = (char*) &lookup->subTable[insert_index] - (char*) lookup; + unsigned insert_offset = Lookup::min_size + insert_index * OT::Offset16::static_size; shift += p.second.length; for (auto& l : v.obj.all_links_writer ()) @@ -304,7 +331,7 @@ struct Lookup : public OT::Lookup unsigned* existing_ext_index = nullptr; if (c.subtable_to_extension.has(subtable_index, &existing_ext_index)) { ext_index = *existing_ext_index; - } else { + } else { ext_index = create_extension_subtable(c, subtable_index, type); c.subtable_to_extension.set(subtable_index, ext_index); } @@ -326,7 +353,7 @@ struct Lookup : public OT::Lookup // Make extension point at the subtable. auto& ext_vertex = c.graph.vertices_[ext_index]; - ext_vertex.add_parent (lookup_index); + ext_vertex.add_parent (lookup_index, false); if (!existing_ext_index) subtable_vertex.remap_parent (lookup_index, ext_index); @@ -334,6 +361,19 @@ struct Lookup : public OT::Lookup } private: + bool is_supported_gsub_type(unsigned type, gsubgpos_graph_context_t& c) const { + return (c.table_tag == HB_OT_TAG_GSUB) && ( + type == OT::Layout::GSUB_impl::SubstLookupSubTable::Type::Ligature + ); + } + + bool is_supported_gpos_type(unsigned type, gsubgpos_graph_context_t& c) const { + return (c.table_tag == HB_OT_TAG_GPOS) && ( + type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::Pair || + type == OT::Layout::GPOS_impl::PosLookupSubTable::Type::MarkBase + ); + } + unsigned extension_type (hb_tag_t table_tag) const { switch (table_tag) diff --git a/thirdparty/harfbuzz/upstream/graph/ligature-graph.hh b/thirdparty/harfbuzz/upstream/graph/ligature-graph.hh new file mode 100644 index 000000000..842271273 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/graph/ligature-graph.hh @@ -0,0 +1,514 @@ +/* + * Copyright © 2025 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#ifndef GRAPH_LIGATURE_GRAPH_HH +#define GRAPH_LIGATURE_GRAPH_HH + +#include "graph.hh" +#include "../OT/Layout/GSUB/LigatureSubst.hh" +#include "../OT/Layout/GSUB/LigatureSubstFormat1.hh" +#include "../OT/Layout/GSUB/LigatureSet.hh" +#include "../OT/Layout/types.hh" +#include +#include + +namespace graph { + +struct LigatureSet : public OT::Layout::GSUB_impl::LigatureSet +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < OT::Layout::GSUB_impl::LigatureSet::min_size) return false; + hb_barrier (); + + int64_t total_len = ligature.get_size() + OT::Layout::GSUB_impl::LigatureSet::min_size - ligature.len.get_size(); + if (vertex_len < total_len) { + return false; + } + return true; + } +}; + +struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1_2 +{ + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + unsigned min_size = OT::Layout::GSUB_impl::LigatureSubstFormat1_2::min_size; + if (vertex_len < min_size) return false; + hb_barrier (); + + return vertex_len >= + min_size + ligatureSet.get_size() - ligatureSet.len.get_size(); + } + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned this_index) + { + auto split_points = compute_split_points(c, this_index); + split_context_t split_context { + c, + this, + this_index, + total_number_ligas(c, this_index), + liga_counts(c, this_index), + }; + return actuate_subtable_split (split_context, split_points); + } + + private: + unsigned total_number_ligas(gsubgpos_graph_context_t& c, unsigned this_index) const { + unsigned total = 0; + for (unsigned i = 0; i < ligatureSet.len; i++) + { + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return 0; + } + total += liga_set.table->ligature.len; + } + return total; + } + + hb_vector_t liga_counts(gsubgpos_graph_context_t& c, unsigned this_index) const { + hb_vector_t result; + for (unsigned i = 0; i < ligatureSet.len; i++) + { + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + result.push(!liga_set.table ? 0 : liga_set.table->ligature.len); + } + return result; + } + + hb_vector_t ligature_index_to_object_id(const graph_t::vertex_and_table_t& liga_set) const { + hb_vector_t map; + map.resize_exact(liga_set.table->ligature.len); + if (map.in_error()) return map; + + for (unsigned i = 0; i < map.length; i++) { + map[i] = (unsigned) -1; + } + + for (const auto& l : liga_set.vertex->obj.real_links) { + if (l.position < 2) continue; + unsigned array_index = (l.position - 2) / 2; + map[array_index] = l.objidx; + } + return map; + } + + hb_vector_t compute_split_points(gsubgpos_graph_context_t& c, + unsigned this_index) const + { + // For ligature subst coverage is always packed last, and as a result is where an overflow + // will happen if there is one, so we can check the estimate length of the + // LigatureSubstFormat1 -> Coverage offset length which is the sum of all data in the + // retained sub graph except for the coverage table itself. + const unsigned base_size = OT::Layout::GSUB_impl::LigatureSubstFormat1_2::min_size; + unsigned accumulated = base_size; + + unsigned ligature_index = 0; + hb_vector_t split_points; + for (unsigned i = 0; i < ligatureSet.len; i++) + { + accumulated += OT::HBUINT16::static_size; // for ligature set offset + accumulated += OT::Layout::GSUB_impl::LigatureSet::min_size; // for ligature set table + + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return hb_vector_t {}; + } + + // Finding the object id associated with an array index is O(n) + // so to avoid O(n^2), precompute the mapping by scanning through + // all links + auto index_to_id = ligature_index_to_object_id(liga_set); + if (index_to_id.in_error()) return hb_vector_t(); + + for (unsigned j = 0; j < liga_set.table->ligature.len; j++) + { + const unsigned liga_id = index_to_id[j]; + if (liga_id == (unsigned) -1) continue; // no outgoing link, ignore + const unsigned liga_size = c.graph.vertices_[liga_id].table_size (); + + accumulated += OT::HBUINT16::static_size; // for ligature offset + accumulated += liga_size; // for the ligature table + + if (accumulated >= (1 << 16)) + { + split_points.push(ligature_index); + // We're going to split such that the current ligature will be in the new sub table. + // That means we'll have one ligature subst (base_base), one ligature set, and one liga table + accumulated = base_size + // for liga subst subtable + (OT::HBUINT16::static_size * 2) + // for liga set and liga offset + OT::Layout::GSUB_impl::LigatureSet::min_size + // for liga set subtable + liga_size; // for liga sub table + } + + ligature_index++; + } + } + + return split_points; + } + + struct split_context_t + { + gsubgpos_graph_context_t& c; + LigatureSubstFormat1* thiz; + unsigned this_index; + unsigned original_count_; + hb_vector_t liga_counts; + + unsigned original_count () + { + return original_count_; + } + + unsigned clone_range (unsigned start, unsigned end) + { + return thiz->clone_range (c, this_index, liga_counts, start, end); + } + + bool shrink (unsigned count) + { + return thiz->shrink (c, this_index, original_count(), liga_counts, count); + } + }; + + hb_pair_t new_liga_set(gsubgpos_graph_context_t& c, unsigned count) const { + unsigned prime_size = OT::Layout::GSUB_impl::LigatureSet::min_size + + count * SmallTypes::size; + + unsigned prime_id = c.create_node (prime_size); + if (prime_id == (unsigned) -1) return hb_pair(-1, nullptr); + + LigatureSet* prime = (LigatureSet*) c.graph.object (prime_id).head; + prime->ligature.len = count; + return hb_pair(prime_id, prime); + } + + void clear_virtual_links (gsubgpos_graph_context_t& c, unsigned node_index) const + { + auto& obj = c.graph.vertices_[node_index].obj; + for (const auto& l : obj.virtual_links) + { + auto& child = c.graph.vertices_[l.objidx]; + child.remove_parent(node_index); + } + obj.virtual_links.clear(); + } + + void add_virtual_link(gsubgpos_graph_context_t& c, unsigned from, unsigned to) const { + auto& from_obj = c.graph.vertices_[from].obj; + c.graph.vertices_[to].add_parent(from, true); + auto& link = *from_obj.virtual_links.push (); + link.objidx = to; + } + + hb_pair_t current_liga_set_bounds (gsubgpos_graph_context_t& c, + unsigned liga_set_index, + const hb_serialize_context_t::object_t& liga_set) const + { + // Finds the actual liga indices present in the liga set currently. Takes + // into account those that have been removed by processing. + unsigned min_index = (unsigned) -1; + unsigned max_index = 0; + for (const auto& l : liga_set.real_links) { + if (l.position < 2) continue; + + unsigned liga_index = (l.position - 2) / 2; + min_index = hb_min(min_index, liga_index); + max_index = hb_max(max_index, liga_index); + } + return hb_pair(min_index, max_index + 1); + } + + void compact_liga_set (gsubgpos_graph_context_t& c, LigatureSet* table, hb_serialize_context_t::object_t& obj) const + { + if (table->ligature.len <= obj.real_links.length) return; + + // compact the remaining linked liga offsets into a continous array and shrink the node as needed. + unsigned to_remove = table->ligature.len - obj.real_links.length; + unsigned new_position = SmallTypes::size; + obj.real_links.qsort(); // for this to work we need to process links in order of position. + for (auto& l : obj.real_links) + { + l.position = new_position; + new_position += SmallTypes::size; + } + + table->ligature.len = obj.real_links.length; + obj.tail -= to_remove * SmallTypes::size; + } + + unsigned clone_range (gsubgpos_graph_context_t& c, + unsigned this_index, + hb_vector_t liga_counts, + unsigned start, unsigned end) const + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Cloning LigatureSubstFormat1 (%u) range [%u, %u).", this_index, start, end); + + // Create an oversized new liga subst, we'll adjust the size down later. We don't know + // the final size until we process it but we also need it to exist while we're processing + // so that nodes can be moved to it as needed. + unsigned prime_size = OT::Layout::GSUB_impl::LigatureSubstFormat1_2::min_size + + ligatureSet.get_size() - ligatureSet.len.get_size(); + + unsigned liga_subst_prime_id = c.create_node (prime_size); + if (liga_subst_prime_id == (unsigned) -1) return -1; + + LigatureSubstFormat1* liga_subst_prime = (LigatureSubstFormat1*) c.graph.object (liga_subst_prime_id).head; + liga_subst_prime->format = this->format; + liga_subst_prime->ligatureSet.len = this->ligatureSet.len; + + // Create a place holder coverage prime id since we need to add virtual links to it while + // generating liga and liga sets. Afterwards it will be updated to have the correct coverage. + unsigned coverage_id = c.graph.index_for_offset (this_index, &coverage); + unsigned coverage_prime_id = c.graph.duplicate(coverage_id); + auto& coverage_prime_vertex = c.graph.vertices_[coverage_prime_id]; + auto* coverage_prime_link = c.graph.vertices_[liga_subst_prime_id].obj.real_links.push (); + coverage_prime_link->width = SmallTypes::size; + coverage_prime_link->objidx = coverage_prime_id; + coverage_prime_link->position = 2; + coverage_prime_vertex.add_parent (liga_subst_prime_id, false); + + // Locate all liga sets with ligas between start and end. + // Clone or move them as needed. + unsigned count = 0; + unsigned liga_set_count = 0; + unsigned liga_set_start = -1; + unsigned liga_set_end = 0; // inclusive + for (unsigned i = 0; i < liga_counts.length; i++) + { + unsigned num_ligas = liga_counts[i]; + + unsigned current_start = count; + unsigned current_end = count + num_ligas; + + if (current_start >= end || start >= current_end) { + // No intersection, so just skip + count += num_ligas; + continue; + } + + auto liga_set_index = c.graph.index_for_offset(this_index, &ligatureSet[i]); + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return -1; + } + + // Bounds may need to be adjusted if some ligas have been previously removed. + hb_pair_t liga_bounds = current_liga_set_bounds(c, liga_set_index, liga_set.vertex->obj); + current_start = hb_max(count + liga_bounds.first, current_start); + current_end = hb_min(count + liga_bounds.second, current_end); + + unsigned liga_set_prime_id; + if (current_start >= start && current_end <= end) { + // This liga set is fully contined within [start, end) + // We can move the entire ligaset to the new liga subset object. + liga_set_end = i; + if (i < liga_set_start) liga_set_start = i; + liga_set_prime_id = c.graph.move_child<> (this_index, + &ligatureSet[i], + liga_subst_prime_id, + &liga_subst_prime->ligatureSet[liga_set_count++]); + compact_liga_set(c, liga_set.table, liga_set.vertex->obj); + } + else + { + // This liga set partially overlaps [start, end). We'll need to create + // a new liga set sub table and move the intersecting ligas to it. + unsigned start_index = hb_max(start, current_start) - count; + unsigned end_index = hb_min(end, current_end) - count; + unsigned liga_count = end_index - start_index; + auto result = new_liga_set(c, liga_count); + liga_set_prime_id = result.first; + if (liga_set_prime_id == (unsigned) -1) return -1; + + c.graph.move_children( + liga_set_index, + 2 + start_index * 2, + 2 + end_index * 2, + liga_set_prime_id, + 2); + + liga_set_end = i; + if (i < liga_set_start) liga_set_start = i; + c.graph.add_link(&liga_subst_prime->ligatureSet[liga_set_count++], liga_subst_prime_id, liga_set_prime_id); + } + + // The new liga and all children set needs to have a virtual link to the new coverage table: + auto& liga_set_prime = c.graph.vertices_[liga_set_prime_id].obj; + clear_virtual_links(c, liga_set_prime_id); + add_virtual_link(c, liga_set_prime_id, coverage_prime_id); + for (const auto& l : liga_set_prime.real_links) { + clear_virtual_links(c, l.objidx); + add_virtual_link(c, l.objidx, coverage_prime_id); + } + + count += num_ligas; + } + + c.graph.vertices_[liga_subst_prime_id].obj.tail -= (liga_subst_prime->ligatureSet.len - liga_set_count) * SmallTypes::size; + liga_subst_prime->ligatureSet.len = liga_set_count; + + if (!Coverage::filter_coverage (c, + coverage_prime_id, + liga_set_start, liga_set_end + 1)) + return -1; + + return liga_subst_prime_id; + } + + bool shrink (gsubgpos_graph_context_t& c, + unsigned this_index, + unsigned old_count, + hb_vector_t liga_counts, + unsigned count) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, + " Shrinking LigatureSubstFormat1 (%u) to [0, %u).", + this_index, + count); + if (count >= old_count) + return true; + + hb_set_t retained_indices; + unsigned new_liga_set_count = 0; + for (unsigned i = 0; i < liga_counts.length; i++) + { + auto liga_set = c.graph.as_table(this_index, &ligatureSet[i]); + if (!liga_set.table) { + return false; + } + + // We need the virtual links to coverage removed from all descendants on this liga subst. + // If any are left when we try to mutate the coverage table later it will be unnessecarily + // duplicated. Code later on will re-add the virtual links as needed (via retained_indices). + clear_virtual_links(c, liga_set.index); + retained_indices.add(liga_set.index); + + auto index_to_id = ligature_index_to_object_id(liga_set); + if (index_to_id.in_error()) return false; + + for (unsigned i = 0; i < liga_set.table->ligature.len; i++) { + unsigned liga_index = index_to_id[i]; + if (liga_index != (unsigned) -1) { + clear_virtual_links(c, liga_index); + retained_indices.add(liga_index); + } + } + + unsigned num_ligas = liga_counts[i]; + if (num_ligas >= count) { + // drop the trailing liga's from this set and all subsequent liga sets + unsigned num_ligas_to_remove = num_ligas - count; + new_liga_set_count = i + 1; + c.graph.vertices_[liga_set.index].obj.tail -= num_ligas_to_remove * SmallTypes::size; + liga_set.table->ligature.len = count; + break; + } else { + count -= num_ligas; + } + } + + // Adjust liga set array + auto& this_vertex = c.graph.vertices_[this_index]; + this_vertex.obj.tail -= (ligatureSet.len - new_liga_set_count) * SmallTypes::size; + ligatureSet.len = new_liga_set_count; + + // Coverage matches the number of liga sets so rebuild as needed + unsigned coverage_idx = c.graph.index_for_offset (this_index, &this->coverage); + if (coverage_idx == (unsigned) -1) return false; + + auto& coverage_v = c.graph.vertices_[coverage_idx]; + unsigned coverage_size = coverage_v.table_size (); + Coverage* coverage_table = (Coverage*) coverage_v.obj.head; + + if (coverage_v.is_shared ()) + { + coverage_idx = c.graph.remap_child (this_index, coverage_idx); + if (coverage_idx == (unsigned) -1) return false; + } + + for (unsigned i : retained_indices.iter()) + add_virtual_link(c, i, coverage_idx); + + auto new_coverage = + + hb_zip (coverage_table->iter (), hb_range ()) + | hb_filter ([&] (hb_pair_t p) { + return p.second < new_liga_set_count; + }) + | hb_map_retains_sorting (hb_first) + ; + + return Coverage::make_coverage (c, new_coverage, coverage_idx, coverage_size); + } +}; + +struct LigatureSubst : public OT::Layout::GSUB_impl::LigatureSubst +{ + + hb_vector_t split_subtables (gsubgpos_graph_context_t& c, + unsigned this_index) + { + switch (u.format.v) { + case 1: + return ((LigatureSubstFormat1*)(&u.format1))->split_subtables (c, this_index); +#ifndef HB_NO_BEYOND_64K + case 2: HB_FALLTHROUGH; + // Don't split 24bit Ligature Subs +#endif + default: + return hb_vector_t (); + } + } + + bool sanitize (graph_t::vertex_t& vertex) const + { + int64_t vertex_len = vertex.obj.tail - vertex.obj.head; + if (vertex_len < u.format.v.get_size ()) return false; + hb_barrier (); + + switch (u.format.v) { + case 1: + return ((LigatureSubstFormat1*)(&u.format1))->sanitize (vertex); +#ifndef HB_NO_BEYOND_64K + case 2: HB_FALLTHROUGH; +#endif + default: + // We don't handle format 2 here. + return false; + } + } +}; + +} + +#endif // GRAPH_LIGATURE_GRAPH_HH diff --git a/thirdparty/harfbuzz/upstream/graph/markbasepos-graph.hh b/thirdparty/harfbuzz/upstream/graph/markbasepos-graph.hh index fb4166128..6d1a3d4ae 100644 --- a/thirdparty/harfbuzz/upstream/graph/markbasepos-graph.hh +++ b/thirdparty/harfbuzz/upstream/graph/markbasepos-graph.hh @@ -212,7 +212,6 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2
split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { hb_set_t visited; @@ -265,7 +264,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { - switch (u.format) { + switch (u.format.v) { case 1: - return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); + return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, this_index); #ifndef HB_NO_BEYOND_64K case 2: HB_FALLTHROUGH; // Don't split 24bit MarkBasePos's. @@ -496,10 +494,10 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos bool sanitize (graph_t::vertex_t& vertex) const { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - if (vertex_len < u.format.get_size ()) return false; + if (vertex_len < u.format.v.get_size ()) return false; hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return ((MarkBasePosFormat1*)(&u.format1))->sanitize (vertex); #ifndef HB_NO_BEYOND_64K diff --git a/thirdparty/harfbuzz/upstream/graph/pairpos-graph.hh b/thirdparty/harfbuzz/upstream/graph/pairpos-graph.hh index fd46861de..85950b634 100644 --- a/thirdparty/harfbuzz/upstream/graph/pairpos-graph.hh +++ b/thirdparty/harfbuzz/upstream/graph/pairpos-graph.hh @@ -49,7 +49,6 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { hb_set_t visited; @@ -84,7 +83,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3 (split_context, split_points); @@ -207,7 +206,6 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4::min_size; @@ -291,7 +289,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4width = SmallTypes::size; class_def_link->objidx = class_def_2_id; class_def_link->position = 10; - graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id); + graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id, false); graph.duplicate (pair_pos_prime_id, class_def_2_id); return pair_pos_prime_id; @@ -607,14 +605,13 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4 split_subtables (gsubgpos_graph_context_t& c, - unsigned parent_index, unsigned this_index) { - switch (u.format) { + switch (u.format.v) { case 1: - return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); + return ((PairPosFormat1*)(&u.format1))->split_subtables (c, this_index); case 2: - return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index); + return ((PairPosFormat2*)(&u.format2))->split_subtables (c, this_index); #ifndef HB_NO_BEYOND_64K case 3: HB_FALLTHROUGH; case 4: HB_FALLTHROUGH; @@ -628,10 +625,10 @@ struct PairPos : public OT::Layout::GPOS_impl::PairPos bool sanitize (graph_t::vertex_t& vertex) const { int64_t vertex_len = vertex.obj.tail - vertex.obj.head; - if (vertex_len < u.format.get_size ()) return false; + if (vertex_len < u.format.v.get_size ()) return false; hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: return ((PairPosFormat1*)(&u.format1))->sanitize (vertex); case 2: diff --git a/thirdparty/harfbuzz/upstream/graph/serialize.hh b/thirdparty/harfbuzz/upstream/graph/serialize.hh index 06e4bf44d..37fac8909 100644 --- a/thirdparty/harfbuzz/upstream/graph/serialize.hh +++ b/thirdparty/harfbuzz/upstream/graph/serialize.hh @@ -113,7 +113,7 @@ will_overflow (graph_t& graph, hb_hashmap_t record_set; const auto& vertices = graph.vertices_; - for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--) + for (unsigned parent_idx : graph.ordering_) { // Don't need to check virtual links for overflow for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links) @@ -172,14 +172,16 @@ void print_overflows (graph_t& graph, template inline void serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, char* head, + unsigned size, + const hb_vector_t& id_map, hb_serialize_context_t* c) { + assert(link.position + link.width <= size); + OT::Offset* offset = reinterpret_cast*> (head + link.position); *offset = 0; c->add_link (*offset, - // serializer has an extra nil object at the start of the - // object array. So all id's are +1 of what our id's are. - link.objidx + 1, + id_map[link.objidx], (hb_serialize_context_t::whence_t) link.whence, link.bias); } @@ -187,6 +189,8 @@ serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, inline void serialize_link (const hb_serialize_context_t::object_t::link_t& link, char* head, + unsigned size, + const hb_vector_t& id_map, hb_serialize_context_t* c) { switch (link.width) @@ -197,21 +201,21 @@ void serialize_link (const hb_serialize_context_t::object_t::link_t& link, case 4: if (link.is_signed) { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } else { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } return; case 2: if (link.is_signed) { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } else { - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); } return; case 3: - serialize_link_of_type (link, head, c); + serialize_link_of_type (link, head, size, id_map, c); return; default: // Unexpected link width. @@ -237,25 +241,36 @@ inline hb_blob_t* serialize (const graph_t& graph) c.start_serialize (); const auto& vertices = graph.vertices_; - for (unsigned i = 0; i < vertices.length; i++) { + + // Objects are placed in the serializer in reverse order since children need + // to be inserted before their parents. + + // Maps from our obj id's to the id's used during this serialization. + hb_vector_t id_map; + id_map.resize(graph.ordering_.length); + for (int pos = graph.ordering_.length - 1; pos >= 0; pos--) { + unsigned i = graph.ordering_[pos]; c.push (); - size_t size = vertices[i].obj.tail - vertices[i].obj.head; + auto& v = vertices[i]; + + size_t size = v.obj.tail - v.obj.head; + char* start = c.allocate_size (size); if (!start) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); return nullptr; } - hb_memcpy (start, vertices[i].obj.head, size); + hb_memcpy (start, v.obj.head, size); // Only real links needs to be serialized. - for (const auto& link : vertices[i].obj.real_links) - serialize_link (link, start, &c); + for (const auto& link : v.obj.real_links) + serialize_link (link, start, size, id_map, &c); // All duplications are already encoded in the graph, so don't // enable sharing during packing. - c.pop_pack (false); + id_map[i] = c.pop_pack (false); } c.end_serialize (); diff --git a/thirdparty/harfbuzz/upstream/graph/split-helpers.hh b/thirdparty/harfbuzz/upstream/graph/split-helpers.hh index 61fd7c2d2..f1f86e332 100644 --- a/thirdparty/harfbuzz/upstream/graph/split-helpers.hh +++ b/thirdparty/harfbuzz/upstream/graph/split-helpers.hh @@ -49,7 +49,7 @@ hb_vector_t actuate_subtable_split (Context& split_context, if (id == (unsigned) -1) { new_objects.reset (); - new_objects.allocated = -1; // mark error + new_objects.ensure_error (); return new_objects; } new_objects.push (id); @@ -58,7 +58,7 @@ hb_vector_t actuate_subtable_split (Context& split_context, if (!split_context.shrink (split_points[0])) { new_objects.reset (); - new_objects.allocated = -1; // mark error + new_objects.ensure_error (); } return new_objects; diff --git a/thirdparty/harfbuzz/upstream/graph/test-classdef-graph.cc b/thirdparty/harfbuzz/upstream/graph/test-classdef-graph.cc index 2da934811..d3e8d892b 100644 --- a/thirdparty/harfbuzz/upstream/graph/test-classdef-graph.cc +++ b/thirdparty/harfbuzz/upstream/graph/test-classdef-graph.cc @@ -38,7 +38,7 @@ static unsigned actual_class_def_size(It glyph_and_class) { hb_serialize_context_t serializer(buffer, 100); OT::ClassDef_serialize (&serializer, glyph_and_class); serializer.end_serialize (); - assert(!serializer.in_error()); + hb_always_assert(!serializer.in_error()); hb_blob_t* blob = serializer.copy_blob(); unsigned size = hb_blob_get_length(blob); @@ -66,7 +66,7 @@ static unsigned actual_coverage_size(It glyphs) { hb_serialize_context_t serializer(buffer, 100); OT::Layout::Common::Coverage_serialize (&serializer, glyphs); serializer.end_serialize (); - assert(!serializer.in_error()); + hb_always_assert(!serializer.in_error()); hb_blob_t* blob = serializer.copy_blob(); unsigned size = hb_blob_get_length(blob); @@ -101,9 +101,9 @@ static bool check_coverage_size(graph::class_def_size_estimator_t& estimator, return true; } -static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator, - const gid_and_class_list_t& map, - unsigned klass, hb_vector_t klasses) +static HB_UNUSED bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator, + const gid_and_class_list_t& map, + unsigned klass, hb_vector_t klasses) { unsigned result = estimator.add_class_def_size(klass); unsigned expected = actual_class_def_size(map, klasses); @@ -115,7 +115,7 @@ static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimato return check_coverage_size(estimator, map, klasses); } -static bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass) +static HB_UNUSED bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass) { graph::class_def_size_estimator_t estimator (list.iter ()); @@ -149,13 +149,13 @@ static void test_class_and_coverage_size_estimates () { gid_and_class_list_t empty = { }; - assert (check_add_class_def_size (empty, 0)); - assert (check_add_class_def_size (empty, 1)); + hb_always_assert (check_add_class_def_size (empty, 0)); + hb_always_assert (check_add_class_def_size (empty, 1)); gid_and_class_list_t class_zero = { {5, 0}, }; - assert (check_add_class_def_size (class_zero, 0)); + hb_always_assert (check_add_class_def_size (class_zero, 0)); gid_and_class_list_t consecutive = { {4, 0}, @@ -169,9 +169,9 @@ static void test_class_and_coverage_size_estimates () {10, 2}, {11, 2}, }; - assert (check_add_class_def_size (consecutive, 0)); - assert (check_add_class_def_size (consecutive, 1)); - assert (check_add_class_def_size (consecutive, 2)); + hb_always_assert (check_add_class_def_size (consecutive, 0)); + hb_always_assert (check_add_class_def_size (consecutive, 1)); + hb_always_assert (check_add_class_def_size (consecutive, 2)); gid_and_class_list_t non_consecutive = { {4, 0}, @@ -185,9 +185,9 @@ static void test_class_and_coverage_size_estimates () {11, 2}, {13, 2}, }; - assert (check_add_class_def_size (non_consecutive, 0)); - assert (check_add_class_def_size (non_consecutive, 1)); - assert (check_add_class_def_size (non_consecutive, 2)); + hb_always_assert (check_add_class_def_size (non_consecutive, 0)); + hb_always_assert (check_add_class_def_size (non_consecutive, 1)); + hb_always_assert (check_add_class_def_size (non_consecutive, 2)); gid_and_class_list_t multiple_ranges = { {4, 0}, @@ -202,8 +202,8 @@ static void test_class_and_coverage_size_estimates () {12, 1}, {13, 1}, }; - assert (check_add_class_def_size (multiple_ranges, 0)); - assert (check_add_class_def_size (multiple_ranges, 1)); + hb_always_assert (check_add_class_def_size (multiple_ranges, 0)); + hb_always_assert (check_add_class_def_size (multiple_ranges, 1)); } static void test_running_class_and_coverage_size_estimates () { @@ -229,14 +229,14 @@ static void test_running_class_and_coverage_size_estimates () { }; graph::class_def_size_estimator_t estimator1(consecutive_map.iter()); - assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1})); - assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); - assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works - assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3})); + hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1})); + hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); + hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works + hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3})); estimator1.reset(); - assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2})); - assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3})); + hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2})); + hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3})); // #### With non-consecutive gids: always uses format 2 ### gid_and_class_list_t non_consecutive_map = { @@ -261,13 +261,13 @@ static void test_running_class_and_coverage_size_estimates () { }; graph::class_def_size_estimator_t estimator2(non_consecutive_map.iter()); - assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1})); - assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2})); - assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3})); + hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1})); + hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2})); + hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3})); estimator2.reset(); - assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2})); - assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3})); + hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2})); + hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3})); } static void test_running_class_size_estimates_with_locally_consecutive_glyphs () { @@ -278,13 +278,13 @@ static void test_running_class_size_estimates_with_locally_consecutive_glyphs () }; graph::class_def_size_estimator_t estimator(map.iter()); - assert(check_add_class_def_size(estimator, map, 1, {1})); - assert(check_add_class_def_size(estimator, map, 2, {1, 2})); - assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3})); + hb_always_assert(check_add_class_def_size(estimator, map, 1, {1})); + hb_always_assert(check_add_class_def_size(estimator, map, 2, {1, 2})); + hb_always_assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3})); estimator.reset(); - assert(check_add_class_def_size(estimator, map, 2, {2})); - assert(check_add_class_def_size(estimator, map, 3, {2, 3})); + hb_always_assert(check_add_class_def_size(estimator, map, 2, {2})); + hb_always_assert(check_add_class_def_size(estimator, map, 3, {2, 3})); } int diff --git a/thirdparty/harfbuzz/upstream/harfbuzz-cairo.pc.in b/thirdparty/harfbuzz/upstream/harfbuzz-cairo.pc.in deleted file mode 100644 index 06ba8047c..000000000 --- a/thirdparty/harfbuzz/upstream/harfbuzz-cairo.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz cairo integration -Description: HarfBuzz cairo integration -Version: %VERSION% - -Requires: harfbuzz = %VERSION% -Requires.private: cairo -Libs: -L${libdir} -lharfbuzz-cairo -Cflags: -I${includedir}/harfbuzz diff --git a/thirdparty/harfbuzz/upstream/harfbuzz-config.cmake.in b/thirdparty/harfbuzz/upstream/harfbuzz-config.cmake.in deleted file mode 100644 index 6abe2d62d..000000000 --- a/thirdparty/harfbuzz/upstream/harfbuzz-config.cmake.in +++ /dev/null @@ -1,32 +0,0 @@ -@PACKAGE_INIT@ - -set_and_check(HARFBUZZ_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") - -# Add the libraries. -add_library(harfbuzz::harfbuzz @HB_LIBRARY_TYPE@ IMPORTED) -set_target_properties(harfbuzz::harfbuzz PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@" - IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX@harfbuzz@HB_LIB_SUFFIX@") - -add_library(harfbuzz::icu @HB_LIBRARY_TYPE@ IMPORTED) -set_target_properties(harfbuzz::icu PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@" - INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" - IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX@harfbuzz-icu@HB_LIB_SUFFIX@") - -add_library(harfbuzz::subset @HB_LIBRARY_TYPE@ IMPORTED) -set_target_properties(harfbuzz::subset PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@" - INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" - IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX@harfbuzz-subset@HB_LIB_SUFFIX@") - -# Only add the gobject library if it was built. -if (@HB_HAVE_GOBJECT@) - add_library(harfbuzz::gobject @HB_LIBRARY_TYPE@ IMPORTED) - set_target_properties(harfbuzz::gobject PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "@PACKAGE_INCLUDE_INSTALL_DIR@" - INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" - IMPORTED_LOCATION "@PACKAGE_CMAKE_INSTALL_LIBDIR@/@HB_LIB_PREFIX@harfbuzz-gobject@HB_LIB_SUFFIX@") -endif () - -check_required_components(harfbuzz) diff --git a/thirdparty/harfbuzz/upstream/harfbuzz-gobject.pc.in b/thirdparty/harfbuzz/upstream/harfbuzz-gobject.pc.in deleted file mode 100644 index 700836019..000000000 --- a/thirdparty/harfbuzz/upstream/harfbuzz-gobject.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz text shaping library GObject integration -Version: %VERSION% - -Requires: harfbuzz gobject-2.0 glib-2.0 -Libs: -L${libdir} -lharfbuzz-gobject -Cflags: -I${includedir}/harfbuzz diff --git a/thirdparty/harfbuzz/upstream/harfbuzz-icu.pc.in b/thirdparty/harfbuzz/upstream/harfbuzz-icu.pc.in deleted file mode 100644 index 949869a35..000000000 --- a/thirdparty/harfbuzz/upstream/harfbuzz-icu.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz text shaping library ICU integration -Version: %VERSION% - -Requires: harfbuzz -Requires.private: icu-uc -Libs: -L${libdir} -lharfbuzz-icu -Cflags: -I${includedir}/harfbuzz diff --git a/thirdparty/harfbuzz/upstream/harfbuzz-subset.cc b/thirdparty/harfbuzz/upstream/harfbuzz-subset.cc index 05483b14c..616c244a1 100644 --- a/thirdparty/harfbuzz/upstream/harfbuzz-subset.cc +++ b/thirdparty/harfbuzz/upstream/harfbuzz-subset.cc @@ -43,6 +43,7 @@ #include "hb-ot-tag.cc" #include "hb-ot-var.cc" #include "hb-outline.cc" +#include "hb-paint-bounded.cc" #include "hb-paint-extents.cc" #include "hb-paint.cc" #include "hb-set.cc" @@ -53,12 +54,20 @@ #include "hb-style.cc" #include "hb-subset-cff-common.cc" #include "hb-subset-cff1.cc" +#include "hb-subset-cff2-to-cff1.cc" #include "hb-subset-cff2.cc" #include "hb-subset-input.cc" #include "hb-subset-instancer-iup.cc" #include "hb-subset-instancer-solver.cc" +#include "hb-subset-plan-layout.cc" +#include "hb-subset-plan-var.cc" #include "hb-subset-plan.cc" -#include "hb-subset-repacker.cc" +#include "hb-subset-serialize.cc" +#include "hb-subset-table-cff.cc" +#include "hb-subset-table-color.cc" +#include "hb-subset-table-layout.cc" +#include "hb-subset-table-other.cc" +#include "hb-subset-table-var.cc" #include "hb-subset.cc" #include "hb-ucd.cc" #include "hb-unicode.cc" diff --git a/thirdparty/harfbuzz/upstream/harfbuzz-subset.pc.in b/thirdparty/harfbuzz/upstream/harfbuzz-subset.pc.in deleted file mode 100644 index ca13c70ef..000000000 --- a/thirdparty/harfbuzz/upstream/harfbuzz-subset.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz subsetter -Description: HarfBuzz font subsetter -Version: %VERSION% - -Requires: harfbuzz = %VERSION% -Libs: -L${libdir} -lharfbuzz-subset -Cflags: -I${includedir}/harfbuzz diff --git a/thirdparty/harfbuzz/upstream/harfbuzz.cc b/thirdparty/harfbuzz/upstream/harfbuzz.cc index 9ff800daa..471942c55 100644 --- a/thirdparty/harfbuzz/upstream/harfbuzz.cc +++ b/thirdparty/harfbuzz/upstream/harfbuzz.cc @@ -8,6 +8,9 @@ #include "hb-common.cc" #include "hb-coretext-font.cc" #include "hb-coretext-shape.cc" +#include "hb-coretext.cc" +#include "hb-directwrite-font.cc" +#include "hb-directwrite-shape.cc" #include "hb-directwrite.cc" #include "hb-draw.cc" #include "hb-face-builder.cc" @@ -49,6 +52,7 @@ #include "hb-ot-tag.cc" #include "hb-ot-var.cc" #include "hb-outline.cc" +#include "hb-paint-bounded.cc" #include "hb-paint-extents.cc" #include "hb-paint.cc" #include "hb-set.cc" diff --git a/thirdparty/harfbuzz/upstream/harfbuzz.pc.in b/thirdparty/harfbuzz/upstream/harfbuzz.pc.in deleted file mode 100644 index 661251c2d..000000000 --- a/thirdparty/harfbuzz/upstream/harfbuzz.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=%prefix% -exec_prefix=%exec_prefix% -libdir=%libdir% -includedir=%includedir% - -Name: harfbuzz -Description: HarfBuzz text shaping library -Version: %VERSION% - -Libs: -L${libdir} -lharfbuzz -Libs.private: -lm %libs_private% -Requires.private: %requires_private% -Cflags: -I${includedir}/harfbuzz diff --git a/thirdparty/harfbuzz/upstream/hb-aat-layout-common.hh b/thirdparty/harfbuzz/upstream/hb-aat-layout-common.hh index 2ea86a2a1..b63e79162 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/upstream/hb-aat-layout-common.hh @@ -29,7 +29,13 @@ #include "hb-aat-layout.hh" #include "hb-aat-map.hh" +#include "hb-ot-layout-common.hh" +#include "hb-ot-layout-gdef-table.hh" #include "hb-open-type.hh" +#include "hb-cache.hh" +#include "hb-bit-set.hh" +#include "hb-bit-page.hh" + namespace OT { struct GDEF; @@ -39,10 +45,68 @@ namespace AAT { using namespace OT; -#define HB_AAT_BUFFER_DIGEST_THRESHOLD 32 - struct ankr; +using hb_aat_class_cache_t = hb_ot_layout_mapping_cache_t; + +struct hb_aat_scratch_t +{ + hb_aat_scratch_t () = default; + hb_aat_scratch_t (const hb_aat_scratch_t &) = delete; + + hb_aat_scratch_t (hb_aat_scratch_t &&o) + { + buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ()); + o.buffer_glyph_set.set_relaxed (nullptr); + } + hb_aat_scratch_t & operator = (hb_aat_scratch_t &&o) + { + buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ()); + o.buffer_glyph_set.set_relaxed (nullptr); + return *this; + } + ~hb_aat_scratch_t () + { + auto *s = buffer_glyph_set.get_relaxed (); + if (unlikely (!s)) + return; + s->fini (); + hb_free (s); + } + + hb_bit_set_t *create_buffer_glyph_set () const + { + hb_bit_set_t *s = buffer_glyph_set.get_acquire (); + if (s && buffer_glyph_set.cmpexch (s, nullptr)) + { + s->clear (); + return s; + } + + s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t)); + if (unlikely (!s)) + return nullptr; + s->init (); + + return s; + } + void destroy_buffer_glyph_set (hb_bit_set_t *s) const + { + if (unlikely (!s)) + return; + if (buffer_glyph_set.cmpexch (nullptr, s)) + return; + s->fini (); + hb_free (s); + } + + mutable hb_atomic_t buffer_glyph_set; +}; + +enum { DELETED_GLYPH = 0xFFFF }; + +#define HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED HB_BUFFER_SCRATCH_FLAG_SHAPER0 + struct hb_aat_apply_context_t : hb_dispatch_context_t { @@ -59,13 +123,17 @@ struct hb_aat_apply_context_t : hb_buffer_t *buffer; hb_sanitize_context_t sanitizer; const ankr *ankr_table; - const OT::GDEF *gdef_table; + const OT::GDEF &gdef; + bool has_glyph_classes; const hb_sorted_vector_t *range_flags = nullptr; - hb_set_digest_t buffer_digest = hb_set_digest_t::full (); - hb_set_digest_t machine_glyph_set = hb_set_digest_t::full (); - hb_set_digest_t left_set = hb_set_digest_t::full (); - hb_set_digest_t right_set = hb_set_digest_t::full (); hb_mask_t subtable_flags = 0; + bool buffer_is_reversed = false; + // Caches + bool using_buffer_glyph_set = false; + hb_bit_set_t *buffer_glyph_set = nullptr; + const hb_bit_set_t *first_set = nullptr; + const hb_bit_set_t *second_set = nullptr; + hb_aat_class_cache_t *machine_class_cache = nullptr; /* Unused. For debug tracing only. */ unsigned int lookup_index; @@ -80,6 +148,94 @@ struct hb_aat_apply_context_t : HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_); void set_lookup_index (unsigned int i) { lookup_index = i; } + + void reverse_buffer () + { + buffer->reverse (); + buffer_is_reversed = !buffer_is_reversed; + } + + void setup_buffer_glyph_set () + { + using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set; + + if (likely (using_buffer_glyph_set)) + buffer->collect_codepoints (*buffer_glyph_set); + } + bool buffer_intersects_machine () const + { + if (likely (using_buffer_glyph_set)) + return buffer_glyph_set->intersects (*first_set); + + // Faster for shorter buffers. + for (unsigned i = 0; i < buffer->len; i++) + if (first_set->has (buffer->info[i].codepoint)) + return true; + return false; + } + + template + HB_NODISCARD bool output_glyphs (unsigned int count, + const T *glyphs) + { + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add_array (glyphs, count); + for (unsigned int i = 0; i < count; i++) + { + if (glyphs[i] == DELETED_GLYPH) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + } + else + { +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->cur(), + gdef.get_glyph_props (glyphs[i])); +#endif + } + if (unlikely (!buffer->output_glyph (glyphs[i]))) return false; + } + return true; + } + + HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph) + { + if (glyph == DELETED_GLYPH) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + } + + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add (glyph); +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->cur(), + gdef.get_glyph_props (glyph)); +#endif + return buffer->replace_glyph (glyph); + } + + HB_NODISCARD bool delete_glyph () + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + return buffer->replace_glyph (DELETED_GLYPH); + } + + void replace_glyph_inplace (unsigned i, hb_codepoint_t glyph) + { + buffer->info[i].codepoint = glyph; + if (likely (using_buffer_glyph_set)) + buffer_glyph_set->add (glyph); +#ifndef HB_NO_OT_LAYOUT + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->info[i], + gdef.get_glyph_props (glyph)); +#endif + } }; @@ -87,8 +243,6 @@ struct hb_aat_apply_context_t : * Lookup Table */ -enum { DELETED_GLYPH = 0xFFFF }; - template struct Lookup; template @@ -108,6 +262,13 @@ struct LookupFormat0 { glyphs.add_range (0, num_glyphs - 1); } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < num_glyphs; i++) + if (filter (arrayZ[i])) + glyphs.add (i); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -140,8 +301,14 @@ struct LookupSegmentSingle template void collect_glyphs (set_t &glyphs) const { - if (first == DELETED_GLYPH) - return; + if (first == DELETED_GLYPH) return; + glyphs.add_range (first, last); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (first == DELETED_GLYPH) return; + if (!filter (value)) return; glyphs.add_range (first, last); } @@ -182,6 +349,13 @@ struct LookupFormat2 for (unsigned int i = 0; i < count; i++) segments[i].collect_glyphs (glyphs); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned int i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, filter); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -217,10 +391,18 @@ struct LookupSegmentArray template void collect_glyphs (set_t &glyphs) const { - if (first == DELETED_GLYPH) - return; + if (first == DELETED_GLYPH) return; glyphs.add_range (first, last); } + template + void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const + { + if (first == DELETED_GLYPH) return; + const auto &values = base+valuesZ; + for (hb_codepoint_t i = first; i <= last; i++) + if (filter (values[i - first])) + glyphs.add (i); + } int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1; } @@ -271,6 +453,13 @@ struct LookupFormat4 for (unsigned i = 0; i < count; i++) segments[i].collect_glyphs (glyphs); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = segments.get_length (); + for (unsigned i = 0; i < count; i++) + segments[i].collect_glyphs_filtered (glyphs, this, filter); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -303,8 +492,14 @@ struct LookupSingle template void collect_glyphs (set_t &glyphs) const { - if (glyph == DELETED_GLYPH) - return; + if (glyph == DELETED_GLYPH) return; + glyphs.add (glyph); + } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (glyph == DELETED_GLYPH) return; + if (!filter (value)) return; glyphs.add (glyph); } @@ -344,6 +539,13 @@ struct LookupFormat6 for (unsigned i = 0; i < count; i++) entries[i].collect_glyphs (glyphs); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + unsigned count = entries.get_length (); + for (unsigned i = 0; i < count; i++) + entries[i].collect_glyphs_filtered (glyphs, filter); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -379,12 +581,20 @@ struct LookupFormat8 template void collect_glyphs (set_t &glyphs) const { - if (unlikely (!glyphCount)) - return; - if (firstGlyph == DELETED_GLYPH) - return; + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const T *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + if (filter (p[i])) + glyphs.add (firstGlyph + i); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -433,13 +643,28 @@ struct LookupFormat10 template void collect_glyphs (set_t &glyphs) const { - if (unlikely (!glyphCount)) - return; - if (firstGlyph == DELETED_GLYPH) - return; + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1); } + template + void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const + { + if (unlikely (!glyphCount)) return; + if (firstGlyph == DELETED_GLYPH) return; + const HBUINT8 *p = valueArrayZ.arrayZ; + for (unsigned i = 0; i < glyphCount; i++) + { + unsigned int v = 0; + unsigned int count = valueSize; + for (unsigned int j = 0; j < count; j++) + v = (v << 8) | *p++; + if (filter (v)) + glyphs.add (firstGlyph + i); + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -467,7 +692,7 @@ struct Lookup { const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_value (glyph_id, num_glyphs); case 2: hb_barrier (); return u.format2.get_value (glyph_id); case 4: hb_barrier (); return u.format4.get_value (glyph_id); @@ -479,7 +704,7 @@ struct Lookup const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { - switch (u.format) { + switch (u.format.v) { /* Format 10 cannot return a pointer. */ case 10: hb_barrier (); return u.format10.get_value_or_null (glyph_id); default: @@ -491,7 +716,7 @@ struct Lookup template void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0.collect_glyphs (glyphs, num_glyphs); return; case 2: hb_barrier (); u.format2.collect_glyphs (glyphs); return; case 4: hb_barrier (); u.format4.collect_glyphs (glyphs); return; @@ -501,6 +726,19 @@ struct Lookup default:return; } } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + switch (u.format.v) { + case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return; + case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return; + case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return; + case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return; + case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return; + case 10: hb_barrier (); u.format10.collect_glyphs_filtered (glyphs, filter); return; + default:return; + } + } typename T::type get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, @@ -513,9 +751,9 @@ struct Lookup bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); case 4: hb_barrier (); return_trace (u.format4.sanitize (c)); @@ -528,9 +766,9 @@ struct Lookup bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.sanitize (c, base)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c, base)); case 4: hb_barrier (); return_trace (u.format4.sanitize (c, base)); @@ -543,7 +781,7 @@ struct Lookup protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ LookupFormat0 format0; LookupFormat2 format2; LookupFormat4 format4; @@ -552,7 +790,7 @@ struct Lookup LookupFormat10 format10; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); @@ -563,7 +801,7 @@ DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); template struct Entry { - // This does seem like it's ever called. + // This doesn't seem like it's ever called. bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -627,23 +865,51 @@ struct StateTable STATE_START_OF_LINE = 1, }; - template - void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const { - (this+classTable).collect_glyphs (glyphs, num_glyphs); + unsigned num_classes = nClasses; + + if (unlikely (num_classes > hb_bit_page_t::BITS)) + { + (this+classTable).collect_glyphs (glyphs, num_glyphs); + return; + } + + // Collect all classes going out from the start state. + hb_bit_page_t filter; + + for (unsigned i = 0; i < num_classes; i++) + { + const auto &entry = get_entry (STATE_START_OF_TEXT, i); + if (new_state (entry.newState) == STATE_START_OF_TEXT && + !table.is_action_initiable (entry) && !table.is_actionable (entry)) + continue; + + filter.add (i); + } + + // And glyphs in those classes. + + if (filter (CLASS_DELETED_GLYPH)) + glyphs.add (DELETED_GLYPH); + + (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter); } int new_state (unsigned int newState) const { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; } - template unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs, - const set_t &glyphs) const + hb_aat_class_cache_t *cache = nullptr) const { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; - if (!glyphs[glyph_id]) return CLASS_OUT_OF_BOUNDS; - return (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS); + klass = (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS); + if (cache) cache->set (glyph_id, klass); + return klass; } const Entry *get_entries () const @@ -651,13 +917,14 @@ struct StateTable const Entry &get_entry (int state, unsigned int klass) const { - if (unlikely (klass >= nClasses)) + unsigned n_classes = nClasses; + if (unlikely (klass >= n_classes)) klass = CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry *entries = (this+entryTable).arrayZ; - unsigned int entry = states[state * nClasses + klass]; + unsigned int entry = states[state * n_classes + klass]; DEBUG_MSG (APPLY, nullptr, "e%u", entry); return entries[entry]; @@ -803,6 +1070,13 @@ struct ClassTable if (classArray.arrayZ[i] != CLASS_OUT_OF_BOUNDS) glyphs.add (firstGlyph + i); } + template + void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const + { + for (unsigned i = 0; i < classArray.len; i++) + if (filter (classArray.arrayZ[i])) + glyphs.add (firstGlyph + i); + } bool sanitize (hb_sanitize_context_t *c) const { @@ -830,6 +1104,8 @@ struct SubtableGlyphCoverage for (unsigned i = 0; i < subtable_count; i++) { uint32_t offset = (uint32_t) subtableOffsets[i]; + // A font file called SFNSDisplay.ttf has value 0xFFFFFFFF in the offsets. + // Just ignore it. if (offset == 0 || offset == 0xFFFFFFFF) continue; if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes))) @@ -918,7 +1194,7 @@ struct ExtendedTypes } }; -template +template struct StateTableDriver { using StateTableT = StateTable; @@ -929,14 +1205,6 @@ struct StateTableDriver machine (machine_), num_glyphs (face_->get_num_glyphs ()) {} - template - bool is_idempotent_on_all_out_of_bounds (context_t *c, hb_aat_apply_context_t *ac) - { - const auto entry = machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_OUT_OF_BOUNDS); - return !c->is_actionable (ac->buffer, this, entry) && - machine.new_state (entry.newState) == StateTableT::STATE_START_OF_TEXT; - } - template void drive (context_t *c, hb_aat_apply_context_t *ac) { @@ -948,11 +1216,24 @@ struct StateTableDriver int state = StateTableT::STATE_START_OF_TEXT; // If there's only one range, we already checked the flag. auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr; + const bool start_state_safe_to_break_eot = + !c->table->is_actionable (machine.get_entry (StateTableT::STATE_START_OF_TEXT, CLASS_END_OF_TEXT)); for (buffer->idx = 0; buffer->successful;) { - /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ - if (last_range) + unsigned int klass = likely (buffer->idx < buffer->len) ? + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : + (unsigned) CLASS_END_OF_TEXT; + resume: + DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); + const EntryT &entry = machine.get_entry (state, klass); + const int next_state = machine.new_state (entry.newState); + + bool is_not_epsilon_transition = !(entry.flags & Flags::DontAdvance); + bool is_not_actionable = !c->table->is_actionable (entry); + + if (unlikely (last_range)) { + /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */ auto *range = last_range; if (buffer->idx < buffer->len) { @@ -967,7 +1248,7 @@ struct StateTableDriver } if (!(range->flags & ac->subtable_flags)) { - if (buffer->idx == buffer->len || unlikely (!buffer->successful)) + if (buffer->idx == buffer->len) break; state = StateTableT::STATE_START_OF_TEXT; @@ -975,13 +1256,42 @@ struct StateTableDriver continue; } } + else + { + // Fast path for when transitioning from start-state to start-state with + // no action and advancing. Do so as long as the class remains the same. + // This is common with runs of non-actionable glyphs. + + bool is_null_transition = state == StateTableT::STATE_START_OF_TEXT && + next_state == StateTableT::STATE_START_OF_TEXT && + start_state_safe_to_break_eot && + is_not_actionable && + is_not_epsilon_transition && + !last_range; + + if (is_null_transition) + { + unsigned old_klass = klass; + do + { + c->transition (buffer, this, entry); - unsigned int klass = likely (buffer->idx < buffer->len) ? - machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_glyph_set) : - (unsigned) CLASS_END_OF_TEXT; - DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); - const EntryT &entry = machine.get_entry (state, klass); - const int next_state = machine.new_state (entry.newState); + if (buffer->idx == buffer->len || !buffer->successful) + break; + + (void) buffer->next_glyph (); + + klass = likely (buffer->idx < buffer->len) ? + machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) : + (unsigned) CLASS_END_OF_TEXT; + } while (klass == old_klass); + + if (buffer->idx == buffer->len || !buffer->successful) + break; + + goto resume; + } + } /* Conditions under which it's guaranteed safe-to-break before current glyph: * @@ -1011,41 +1321,36 @@ struct StateTableDriver * * https://github.com/harfbuzz/harfbuzz/issues/2860 */ - - const auto is_safe_to_break_extra = [&]() - { - /* 2c. */ - const auto &wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass); - - /* 2c'. */ - if (c->is_actionable (buffer, this, wouldbe_entry)) - return false; - - /* 2c". */ - return next_state == machine.new_state(wouldbe_entry.newState) - && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance); - }; - - const auto is_safe_to_break = [&]() - { + const EntryT *wouldbe_entry; + bool is_safe_to_break = + ( /* 1. */ - if (c->is_actionable (buffer, this, entry)) - return false; + !c->table->is_actionable (entry) && /* 2. */ // This one is meh, I know... - const auto ok = + ( state == StateTableT::STATE_START_OF_TEXT - || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) - || is_safe_to_break_extra(); - if (!ok) - return false; + || ((entry.flags & Flags::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) + || ( + /* 2c. */ + wouldbe_entry = &machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass) + , + /* 2c'. */ + !c->table->is_actionable (*wouldbe_entry) && + /* 2c". */ + ( + next_state == machine.new_state(wouldbe_entry->newState) && + (entry.flags & Flags::DontAdvance) == (wouldbe_entry->flags & Flags::DontAdvance) + ) + ) + ) && /* 3. */ - return !c->is_actionable (buffer, this, machine.get_entry (state, CLASS_END_OF_TEXT)); - }; + !c->table->is_actionable (machine.get_entry (state, CLASS_END_OF_TEXT)) + ); - if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len) + if (!is_safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); c->transition (buffer, this, entry); @@ -1053,10 +1358,10 @@ struct StateTableDriver state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); - if (buffer->idx == buffer->len || unlikely (!buffer->successful)) + if (buffer->idx == buffer->len) break; - if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) + if (is_not_epsilon_transition || buffer->max_ops-- <= 0) (void) buffer->next_glyph (); } diff --git a/thirdparty/harfbuzz/upstream/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/upstream/hb-aat-layout-kerx-table.hh index c01c31d73..471bd187b 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-layout-kerx-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-aat-layout-kerx-table.hh @@ -112,10 +112,6 @@ struct KerxSubTableFormat0 if (header.coverage & header.Backwards) return_trace (false); - if (!(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); - accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -124,12 +120,12 @@ struct KerxSubTableFormat0 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { for (const KernPair& pair : pairs) { - left_set.add (pair.left); - right_set.add (pair.right); + first_set.add (pair.left); + second_set.add (pair.right); } } @@ -144,7 +140,7 @@ struct KerxSubTableFormat0 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!c->left_set[left] || !c->right_set[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -189,6 +185,9 @@ struct Format1Entry DEFINE_SIZE_STATIC (2); }; + static bool initiateAction (const Entry &entry) + { return entry.flags & Push; } + static bool performAction (const Entry &entry) { return entry.data.kernActionIndex != 0xFFFF; } @@ -211,6 +210,9 @@ struct Format1Entry typedef void EntryData; + static bool initiateAction (const Entry &entry) + { return entry.flags & Push; } + static bool performAction (const Entry &entry) { return entry.flags & Offset; } @@ -227,13 +229,23 @@ struct KerxSubTableFormat1 typedef Format1Entry Format1EntryT; typedef typename Format1EntryT::EntryData EntryData; + enum Flags + { + DontAdvance = Format1EntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry &entry) const + { + return Format1EntryT::initiateAction (entry); + } + bool is_actionable (const Entry &entry) const + { + return Format1EntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = true; - enum - { - DontAdvance = Format1EntryT::DontAdvance, - }; driver_context_t (const KerxSubTableFormat1 *table_, hb_aat_apply_context_t *c_) : @@ -246,12 +258,8 @@ struct KerxSubTableFormat1 depth (0), crossStream (table->header.coverage & table->header.CrossStream) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { return Format1EntryT::performAction (entry); } void transition (hb_buffer_t *buffer, - StateTableDriver *driver, + StateTableDriver *driver, const Entry &entry) { unsigned int flags = entry.flags; @@ -320,8 +328,9 @@ struct KerxSubTableFormat1 } else if (buffer->info[idx].mask & kern_mask) { - o.x_advance += c->font->em_scale_x (v); - o.x_offset += c->font->em_scale_x (v); + auto scaled = c->font->em_scale_x (v); + o.x_advance += scaled; + o.x_offset += scaled; } } else @@ -351,9 +360,10 @@ struct KerxSubTableFormat1 } } - private: + public: hb_aat_apply_context_t *c; const KerxSubTableFormat1 *table; + private: const UnsizedArrayOf &kernAction; unsigned int stack[8]; unsigned int depth; @@ -370,12 +380,7 @@ struct KerxSubTableFormat1 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->font->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); + StateTableDriver driver (machine, c->font->face); driver.drive (&dc, c); @@ -391,12 +396,10 @@ struct KerxSubTableFormat1 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - set_t set; - machine.collect_glyphs (set, num_glyphs); - left_set.union_ (set); - right_set.union_ (set); + machine.collect_initial_glyphs (first_set, num_glyphs, *this); + //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning } protected: @@ -440,10 +443,6 @@ struct KerxSubTableFormat2 if (header.coverage & header.Backwards) return_trace (false); - if (!(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); - accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -452,10 +451,10 @@ struct KerxSubTableFormat2 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - (this+leftClassTable).collect_glyphs (left_set, num_glyphs); - (this+rightClassTable).collect_glyphs (right_set, num_glyphs); + (this+leftClassTable).collect_glyphs (first_set, num_glyphs); + (this+rightClassTable).collect_glyphs (second_set, num_glyphs); } struct accelerator_t @@ -469,7 +468,7 @@ struct KerxSubTableFormat2 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!c->left_set[left] || !c->right_set[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -513,17 +512,26 @@ struct KerxSubTableFormat4 DEFINE_SIZE_STATIC (2); }; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before * going to the new state. */ - Reserved = 0x3FFF, /* Not used; set to 0. */ - }; + Reserved = 0x3FFF, /* Not used; set to 0. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & Mark); + } + bool is_actionable (const Entry &entry) const + { + return entry.data.ankrActionIndex != 0xFFFF; + } + struct driver_context_t + { + static constexpr bool in_place = true; enum SubTableFlags { ActionType = 0xC0000000, /* A two-bit field containing the action type. */ @@ -533,20 +541,17 @@ struct KerxSubTableFormat4 * point table. */ }; - driver_context_t (const KerxSubTableFormat4 *table, + driver_context_t (const KerxSubTableFormat4 *table_, hb_aat_apply_context_t *c_) : c (c_), + table (table_), action_type ((table->flags & ActionType) >> 30), ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))), mark_set (false), mark (0) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver *driver HB_UNUSED, - const Entry &entry) - { return entry.data.ankrActionIndex != 0xFFFF; } void transition (hb_buffer_t *buffer, - StateTableDriver *driver, + StateTableDriver *driver, const Entry &entry) { if (mark_set && entry.data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len) @@ -624,6 +629,8 @@ struct KerxSubTableFormat4 } o.attach_type() = OT::Layout::GPOS_impl::ATTACH_TYPE_MARK; o.attach_chain() = (int) mark - (int) buffer->idx; + if (c->buffer_is_reversed) + o.attach_chain() = -o.attach_chain(); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; } @@ -634,8 +641,10 @@ struct KerxSubTableFormat4 } } - private: + public: hb_aat_apply_context_t *c; + const KerxSubTableFormat4 *table; + private: unsigned int action_type; const HBUINT16 *ankrData; bool mark_set; @@ -648,12 +657,7 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); - StateTableDriver driver (machine, c->font->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); + StateTableDriver driver (machine, c->font->face); driver.drive (&dc, c); @@ -669,12 +673,10 @@ struct KerxSubTableFormat4 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { - set_t set; - machine.collect_glyphs (set, num_glyphs); - left_set.union_ (set); - right_set.union_ (set); + machine.collect_initial_glyphs (first_set, num_glyphs, *this); + //machine.collect_glyphs (second_set, num_glyphs); // second_set is unused for machine kerning } protected: @@ -735,10 +737,6 @@ struct KerxSubTableFormat6 if (header.coverage & header.Backwards) return_trace (false); - if (!(c->buffer_digest.may_have (c->left_set) && - c->buffer_digest.may_have (c->right_set))) - return_trace (false); - accelerator_t accel (*this, c); hb_kern_machine_t machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -766,19 +764,19 @@ struct KerxSubTableFormat6 } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { if (is_long ()) { const auto &t = u.l; - (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); - (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); } else { const auto &t = u.s; - (this+t.rowIndexTable).collect_glyphs (left_set, num_glyphs); - (this+t.columnIndexTable).collect_glyphs (right_set, num_glyphs); + (this+t.rowIndexTable).collect_glyphs (first_set, num_glyphs); + (this+t.columnIndexTable).collect_glyphs (second_set, num_glyphs); } } @@ -793,7 +791,7 @@ struct KerxSubTableFormat6 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - if (!c->left_set[left] || !c->right_set[right]) return 0; + if (!(*c->first_set)[left] || !(*c->second_set)[right]) return 0; return table.get_kerning (left, right, c); } }; @@ -882,15 +880,15 @@ struct KerxSubTable } template - void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const + void collect_glyphs (set_t &first_set, set_t &second_set, unsigned num_glyphs) const { unsigned int subtable_type = get_type (); switch (subtable_type) { - case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return; - case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return; - case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return; - case 4: u.format4.collect_glyphs (left_set, right_set, num_glyphs); return; - case 6: u.format6.collect_glyphs (left_set, right_set, num_glyphs); return; + case 0: u.format0.collect_glyphs (first_set, second_set, num_glyphs); return; + case 1: u.format1.collect_glyphs (first_set, second_set, num_glyphs); return; + case 2: u.format2.collect_glyphs (first_set, second_set, num_glyphs); return; + case 4: u.format4.collect_glyphs (first_set, second_set, num_glyphs); return; + case 6: u.format6.collect_glyphs (first_set, second_set, num_glyphs); return; default: return; } } @@ -925,7 +923,18 @@ struct KerxSubTable * The 'kerx' Table */ -using kern_accelerator_data_t = hb_vector_t>; +struct kern_subtable_accelerator_data_t +{ + hb_bit_set_t first_set; + hb_bit_set_t second_set; + mutable hb_aat_class_cache_t class_cache; +}; + +struct kern_accelerator_data_t +{ + hb_vector_t subtable_accels; + hb_aat_scratch_t scratch; +}; template struct KerxTable @@ -985,14 +994,11 @@ struct KerxTable } bool apply (AAT::hb_aat_apply_context_t *c, - const kern_accelerator_data_t *accel_data = nullptr) const + const kern_accelerator_data_t &accel_data) const { c->buffer->unsafe_to_concat (); - if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) - c->buffer_digest = c->buffer->digest (); - else - c->buffer_digest = hb_set_digest_t::full (); + c->setup_buffer_glyph_set (); typedef typename T::SubTable SubTable; @@ -1005,12 +1011,24 @@ struct KerxTable { bool reverse; + auto &subtable_accel = accel_data.subtable_accels[i]; + if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation)) goto skip; if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; + c->first_set = &subtable_accel.first_set; + c->second_set = &subtable_accel.second_set; + c->machine_class_cache = &subtable_accel.class_cache; + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped subtable %u because no glyph matches", c->lookup_index); + goto skip; + } + reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); @@ -1034,18 +1052,8 @@ struct KerxTable } } - if (reverse) - c->buffer->reverse (); - - if (accel_data) - { - c->left_set = (*accel_data)[i].first; - c->right_set = (*accel_data)[i].second; - } - else - { - c->left_set = c->right_set = hb_set_digest_t::full (); - } + if (reverse != c->buffer_is_reversed) + c->reverse_buffer (); { /* See comment in sanitize() for conditional here. */ @@ -1053,15 +1061,14 @@ struct KerxTable ret |= st->dispatch (c); } - if (reverse) - c->buffer->reverse (); - (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index); skip: st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } + if (c->buffer_is_reversed) + c->reverse_buffer (); return ret; } @@ -1122,9 +1129,13 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - hb_set_digest_t left_set, right_set; - st->collect_glyphs (left_set, right_set, num_glyphs); - accel_data.push (hb_pair (left_set, right_set)); + auto &subtable_accel = *accel_data.subtable_accels.push (); + if (unlikely (accel_data.subtable_accels.in_error ())) + return accel_data; + + st->collect_glyphs (subtable_accel.first_set, subtable_accel.second_set, num_glyphs); + subtable_accel.class_cache.clear (); + st = &StructAfter (*st); } @@ -1148,11 +1159,12 @@ struct KerxTable bool apply (AAT::hb_aat_apply_context_t *c) const { - return table->apply (c, &accel_data); + return table->apply (c, accel_data); } hb_blob_ptr_t table; kern_accelerator_data_t accel_data; + hb_aat_scratch_t scratch; }; }; diff --git a/thirdparty/harfbuzz/upstream/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/upstream/hb-aat-layout-morx-table.hh index d31834402..c25833cf2 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-aat-layout-morx-table.hh @@ -29,8 +29,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" -#include "hb-ot-layout-common.hh" -#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout.hh" #include "hb-aat-map.hh" /* @@ -53,35 +52,40 @@ struct RearrangementSubtable typedef void EntryData; - struct driver_context_t + enum Flags { - static constexpr bool in_place = true; - enum Flags - { - MarkFirst = 0x8000, /* If set, make the current glyph the first + MarkFirst = 0x8000, /* If set, make the current glyph the first * glyph to be rearranged. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph + DontAdvance = 0x4000, /* If set, don't advance to the next glyph * before going to the new state. This means * that the glyph index doesn't change, even * if the glyph at that index has changed. */ - MarkLast = 0x2000, /* If set, make the current glyph the last + MarkLast = 0x2000, /* If set, make the current glyph the last * glyph to be rearranged. */ - Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ - Verb = 0x000F, /* The type of rearrangement specified. */ - }; + Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ + Verb = 0x000F, /* The type of rearrangement specified. */ + }; - driver_context_t (const RearrangementSubtable *table HB_UNUSED) : + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & MarkFirst); + } + bool is_actionable (const Entry &entry) const + { + return (entry.flags & Verb); + } + + struct driver_context_t + { + static constexpr bool in_place = true; + + driver_context_t (const RearrangementSubtable *table_) : ret (false), + table (table_), start (0), end (0) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver *driver HB_UNUSED, - const Entry &entry) const - { - return (entry.flags & Verb) && start < end; - } void transition (hb_buffer_t *buffer, - StateTableDriver *driver, + StateTableDriver *driver, const Entry &entry) { unsigned int flags = entry.flags; @@ -158,6 +162,7 @@ struct RearrangementSubtable public: bool ret; + const RearrangementSubtable *table; private: unsigned int start; unsigned int end; @@ -169,11 +174,7 @@ struct RearrangementSubtable driver_context_t dc (this); - StateTableDriver driver (machine, c->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) - return_trace (false); + StateTableDriver driver (machine, c->face); driver.drive (&dc, c); @@ -207,39 +208,38 @@ struct ContextualSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry &entry) const + { + return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; + } + struct driver_context_t { static constexpr bool in_place = true; - enum Flags - { - SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. */ - Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ - }; driver_context_t (const ContextualSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), - gdef (*c->gdef_table), + table (table_), mark_set (false), - has_glyph_classes (gdef.has_glyph_classes ()), mark (0), - table (table_), subs (table+table->substitutionTables) {} - bool is_actionable (hb_buffer_t *buffer, - StateTableDriver *driver, - const Entry &entry) const - { - if (buffer->idx == buffer->len && !mark_set) - return false; - - return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF; - } void transition (hb_buffer_t *buffer, - StateTableDriver *driver, + StateTableDriver *driver, const Entry &entry) { /* Looks like CoreText applies neither mark nor current substitution for @@ -271,11 +271,7 @@ struct ContextualSubtable if (replacement) { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); - buffer->info[mark].codepoint = *replacement; - c->buffer_digest.add (*replacement); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&buffer->info[mark], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (mark, *replacement); ret = true; } @@ -301,11 +297,7 @@ struct ContextualSubtable } if (replacement) { - buffer->info[idx].codepoint = *replacement; - c->buffer_digest.add (*replacement); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&buffer->info[idx], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (idx, *replacement); ret = true; } @@ -318,13 +310,11 @@ struct ContextualSubtable public: bool ret; - private: hb_aat_apply_context_t *c; - const OT::GDEF &gdef; + const ContextualSubtable *table; + private: bool mark_set; - bool has_glyph_classes; unsigned int mark; - const ContextualSubtable *table; const UnsizedListOfOffset16To, HBUINT, void, false> &subs; }; @@ -334,11 +324,7 @@ struct ContextualSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) - return_trace (false); + StateTableDriver driver (machine, c->face); driver.drive (&dc, c); @@ -389,6 +375,16 @@ struct LigatureEntry; template <> struct LigatureEntry { + + struct EntryData + { + HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry + * for processing this group, if indicated + * by the flags. */ + public: + DEFINE_SIZE_STATIC (2); + }; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -400,14 +396,8 @@ struct LigatureEntry Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ }; - struct EntryData - { - HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry - * for processing this group, if indicated - * by the flags. */ - public: - DEFINE_SIZE_STATIC (2); - }; + static bool initiateAction (const Entry &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry &entry) { return entry.flags & PerformAction; } @@ -418,6 +408,8 @@ struct LigatureEntry template <> struct LigatureEntry { + typedef void EntryData; + enum Flags { SetComponent = 0x8000, /* Push this glyph onto the component stack for @@ -429,7 +421,8 @@ struct LigatureEntry * multiple of 4. */ }; - typedef void EntryData; + static bool initiateAction (const Entry &entry) + { return entry.flags & SetComponent; } static bool performAction (const Entry &entry) { return entry.flags & Offset; } @@ -447,13 +440,23 @@ struct LigatureSubtable typedef LigatureEntry LigatureEntryT; typedef typename LigatureEntryT::EntryData EntryData; + enum Flags + { + DontAdvance = LigatureEntryT::DontAdvance, + }; + + bool is_action_initiable (const Entry &entry) const + { + return LigatureEntryT::initiateAction (entry); + } + bool is_actionable (const Entry &entry) const + { + return LigatureEntryT::performAction (entry); + } + struct driver_context_t { static constexpr bool in_place = false; - enum - { - DontAdvance = LigatureEntryT::DontAdvance, - }; enum LigActionFlags { LigActionLast = 0x80000000, /* This is the last action in the list. This also @@ -476,21 +479,15 @@ struct LigatureSubtable ligature (table+table->ligature), match_length (0) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver *driver HB_UNUSED, - const Entry &entry) const - { - return LigatureEntryT::performAction (entry); - } void transition (hb_buffer_t *buffer, - StateTableDriver *driver, + StateTableDriver *driver, const Entry &entry) { DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx); if (entry.flags & LigatureEntryT::SetComponent) { /* Never mark same index twice, in case DontAdvance was used... */ - if (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len) + if (unlikely (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len)) match_length--; match_positions[match_length++ % ARRAY_LENGTH (match_positions)] = buffer->out_len; @@ -556,7 +553,7 @@ struct LigatureSubtable hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); - if (unlikely (!buffer->replace_glyph (lig))) return; + if (unlikely (!c->replace_glyph (lig))) return; unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u; /* Now go and delete all subsequent components. */ @@ -564,8 +561,7 @@ struct LigatureSubtable { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; - buffer->cur().unicode_props() |= UPROPS_MASK_IGNORABLE; - if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; + if (!c->delete_glyph ()) return; } if (unlikely (!buffer->move_to (lig_end))) return; @@ -581,9 +577,9 @@ struct LigatureSubtable public: bool ret; - private: hb_aat_apply_context_t *c; const LigatureSubtable *table; + private: const UnsizedArrayOf &ligAction; const UnsizedArrayOf &component; const UnsizedArrayOf &ligature; @@ -597,11 +593,7 @@ struct LigatureSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) - return_trace (false); + StateTableDriver driver (machine, c->face); driver.drive (&dc, c); @@ -638,9 +630,6 @@ struct NoncontextualSubtable { TRACE_APPLY (this); - const OT::GDEF &gdef (*c->gdef_table); - bool has_glyph_classes = gdef.has_glyph_classes (); - bool ret = false; unsigned int num_glyphs = c->face->get_num_glyphs (); @@ -651,7 +640,7 @@ struct NoncontextualSubtable for (unsigned int i = 0; i < count; i++) { /* This block copied from StateTableDriver::drive. Keep in sync. */ - if (last_range) + if (unlikely (last_range)) { auto *range = last_range; { @@ -670,11 +659,7 @@ struct NoncontextualSubtable const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { - info[i].codepoint = *replacement; - c->buffer_digest.add (*replacement); - if (has_glyph_classes) - _hb_glyph_info_set_glyph_props (&info[i], - gdef.get_glyph_props (*replacement)); + c->replace_glyph_inplace (i, *replacement); ret = true; } } @@ -682,6 +667,12 @@ struct NoncontextualSubtable return_trace (ret); } + template + void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs) const + { + substitute.collect_glyphs (glyphs, num_glyphs); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -715,73 +706,78 @@ struct InsertionSubtable DEFINE_SIZE_STATIC (4); }; + enum Flags + { + SetMark = 0x8000, /* If set, mark the current glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. This does not mean + * that the glyph pointed to is the same one as + * before. If you've made insertions immediately + * downstream of the current glyph, the next glyph + * processed would in fact be the first one + * inserted. */ + CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). If clear, and + * the currentInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the current glyph (depending on the state + * of the currentInsertBefore flag). */ + MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, + * then the specified glyph list will be inserted + * as a kashida-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). If clear, and + * the markedInsertList is nonzero, then the + * specified glyph list will be inserted as a + * split-vowel-like insertion, either before or + * after the marked glyph (depending on the state + * of the markedInsertBefore flag). */ + CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made + * to the left of the current glyph. If clear, + * they're made to the right of the current glyph. */ + MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be + * made to the left of the marked glyph. If clear, + * they're made to the right of the marked glyph. */ + CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the current + * position. Since zero means no insertions, the + * largest number of insertions at any given + * current location is 31 glyphs. */ + MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the + * number of glyphs to insert at the marked + * position. Since zero means no insertions, the + * largest number of insertions at any given + * marked location is 31 glyphs. */ + }; + + bool is_action_initiable (const Entry &entry) const + { + return (entry.flags & SetMark); + } + bool is_actionable (const Entry &entry) const + { + return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && + (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); + } + struct driver_context_t { static constexpr bool in_place = false; - enum Flags - { - SetMark = 0x8000, /* If set, mark the current glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. This does not mean - * that the glyph pointed to is the same one as - * before. If you've made insertions immediately - * downstream of the current glyph, the next glyph - * processed would in fact be the first one - * inserted. */ - CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). If clear, and - * the currentInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the current glyph (depending on the state - * of the currentInsertBefore flag). */ - MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero, - * then the specified glyph list will be inserted - * as a kashida-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). If clear, and - * the markedInsertList is nonzero, then the - * specified glyph list will be inserted as a - * split-vowel-like insertion, either before or - * after the marked glyph (depending on the state - * of the markedInsertBefore flag). */ - CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made - * to the left of the current glyph. If clear, - * they're made to the right of the current glyph. */ - MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be - * made to the left of the marked glyph. If clear, - * they're made to the right of the marked glyph. */ - CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the current - * position. Since zero means no insertions, the - * largest number of insertions at any given - * current location is 31 glyphs. */ - MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the - * number of glyphs to insert at the marked - * position. Since zero means no insertions, the - * largest number of insertions at any given - * marked location is 31 glyphs. */ - }; - driver_context_t (const InsertionSubtable *table, + driver_context_t (const InsertionSubtable *table_, hb_aat_apply_context_t *c_) : ret (false), c (c_), + table (table_), mark (0), insertionAction (table+table->insertionAction) {} - bool is_actionable (hb_buffer_t *buffer HB_UNUSED, - StateTableDriver *driver HB_UNUSED, - const Entry &entry) const - { - return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) && - (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF); - } void transition (hb_buffer_t *buffer, - StateTableDriver *driver, + StateTableDriver *driver, const Entry &entry) { unsigned int flags = entry.flags; @@ -805,9 +801,7 @@ struct InsertionSubtable if (buffer->idx < buffer->len && !before) if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; - for (unsigned int i = 0; i < count; i++) - c->buffer_digest.add (glyphs[i]); + if (unlikely (!c->output_glyphs (count, glyphs))) return; ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -836,7 +830,8 @@ struct InsertionSubtable if (buffer->idx < buffer->len && !before) if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; + if (unlikely (!c->output_glyphs (count, glyphs))) return; + ret = true; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -861,8 +856,9 @@ struct InsertionSubtable public: bool ret; - private: hb_aat_apply_context_t *c; + const InsertionSubtable *table; + private: unsigned int mark; const UnsizedArrayOf &insertionAction; }; @@ -873,11 +869,7 @@ struct InsertionSubtable driver_context_t dc (this, c); - StateTableDriver driver (machine, c->face); - - if (driver.is_idempotent_on_all_out_of_bounds (&dc, c) && - !c->buffer_digest.may_have (c->machine_glyph_set)) - return_trace (false); + StateTableDriver driver (machine, c->face); driver.drive (&dc, c); @@ -935,24 +927,33 @@ struct hb_accelerate_subtables_context_t : friend struct hb_aat_layout_lookup_accelerator_t; public: - hb_set_digest_t digest; + hb_bit_set_t glyph_set; + mutable hb_aat_class_cache_t class_cache; template auto init_ (const T &obj_, unsigned num_glyphs, hb_priority<1>) HB_AUTO_RETURN ( - obj_.machine.collect_glyphs (this->digest, num_glyphs) + obj_.machine.collect_initial_glyphs (glyph_set, num_glyphs, obj_) ) template void init_ (const T &obj_, unsigned num_glyphs, hb_priority<0>) { - digest = digest.full (); + obj_.collect_initial_glyphs (glyph_set, num_glyphs); } template void init (const T &obj_, unsigned num_glyphs) { + glyph_set.init (); init_ (obj_, num_glyphs, hb_prioritize); + class_cache.clear (); + } + + void + fini () + { + glyph_set.fini (); } }; @@ -999,12 +1000,21 @@ struct hb_aat_layout_chain_accelerator_t if (unlikely (!thiz)) return nullptr; + thiz->count = count; + hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables, num_glyphs); chain.dispatch (&c_accelerate_subtables); return thiz; } + void destroy () + { + for (unsigned i = 0; i < count; i++) + subtables[i].fini (); + } + + unsigned count; hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; @@ -1152,17 +1162,28 @@ struct Chain { bool reverse; + auto coverage = subtable->get_coverage (); + + hb_mask_t subtable_flags = subtable->subFeatureFlags; if (hb_none (hb_iter (c->range_flags) | - hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); }))) + hb_map ([subtable_flags] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable_flags & (_.flags); }))) goto skip; - c->subtable_flags = subtable->subFeatureFlags; - c->machine_glyph_set = accel ? accel->subtables[i].digest : hb_set_digest_t::full (); - if (!(subtable->get_coverage() & ChainSubtable::AllDirections) && + if (!(coverage & ChainSubtable::AllDirections) && HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (subtable->get_coverage() & ChainSubtable::Vertical)) + bool (coverage & ChainSubtable::Vertical)) goto skip; + c->subtable_flags = subtable_flags; + c->first_set = accel ? &accel->subtables[i].glyph_set : &Null(hb_bit_set_t); + c->machine_class_cache = accel ? &accel->subtables[i].class_cache : nullptr; + + if (!c->buffer_intersects_machine ()) + { + (void) c->buffer->message (c->font, "skipped chainsubtable %u because no glyph matches", c->lookup_index); + goto skip; + } + /* Buffer contents is always in logical direction. Determine if * we need to reverse before applying this subtable. We reverse * back after if we did reverse indeed. @@ -1190,30 +1211,29 @@ struct Chain (the order opposite that of the characters, which may be right-to-left or left-to-right). */ - reverse = subtable->get_coverage () & ChainSubtable::Logical ? - bool (subtable->get_coverage () & ChainSubtable::Backwards) : - bool (subtable->get_coverage () & ChainSubtable::Backwards) != + reverse = coverage & ChainSubtable::Logical ? + bool (coverage & ChainSubtable::Backwards) : + bool (coverage & ChainSubtable::Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index)) goto skip; - if (reverse) - c->buffer->reverse (); + if (reverse != c->buffer_is_reversed) + c->reverse_buffer (); subtable->apply (c); - if (reverse) - c->buffer->reverse (); - (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index); - if (unlikely (!c->buffer->successful)) return; + if (unlikely (!c->buffer->successful)) break; skip: subtable = &StructAfter> (*subtable); c->set_lookup_index (c->lookup_index + 1); } + if (c->buffer_is_reversed) + c->reverse_buffer (); } unsigned int get_size () const { return length; } @@ -1298,9 +1318,15 @@ struct mortmorx hb_sanitize_context_t sc; this->table = sc.reference_table (face); + if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } + this->chain_count = table->get_chain_count (); - this->accels = (hb_atomic_ptr_t *) hb_calloc (this->chain_count, sizeof (*accels)); + this->accels = (hb_atomic_t *) hb_calloc (this->chain_count, sizeof (*accels)); if (unlikely (!this->accels)) { this->chain_count = 0; @@ -1311,7 +1337,11 @@ struct mortmorx ~accelerator_t () { for (unsigned int i = 0; i < this->chain_count; i++) + { + if (this->accels[i]) + this->accels[i]->destroy (); hb_free (this->accels[i]); + } hb_free (this->accels); this->table.destroy (); } @@ -1343,7 +1373,8 @@ struct mortmorx hb_blob_ptr_t table; unsigned int chain_count; - hb_atomic_ptr_t *accels; + hb_atomic_t *accels; + hb_aat_scratch_t scratch; }; @@ -1365,9 +1396,8 @@ struct mortmorx unsigned get_chain_count () const { - return chainCount; + return chainCount; } - void apply (hb_aat_apply_context_t *c, const hb_aat_map_t &map, const accelerator_t &accel) const @@ -1376,10 +1406,7 @@ struct mortmorx c->buffer->unsafe_to_concat (); - if (c->buffer->len < HB_AAT_BUFFER_DIGEST_THRESHOLD) - c->buffer_digest = c->buffer->digest (); - else - c->buffer_digest = hb_set_digest_t::full (); + c->setup_buffer_glyph_set (); c->set_lookup_index (0); const Chain *chain = &firstChain; @@ -1428,8 +1455,17 @@ struct mortmorx DEFINE_SIZE_MIN (8); }; -struct morx : mortmorx {}; -struct mort : mortmorx {}; +struct morx : mortmorx +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; + +struct mort : mortmorx +{ + HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const; +}; struct morx_accelerator_t : morx::accelerator_t { morx_accelerator_t (hb_face_t *face) : morx::accelerator_t (face) {} diff --git a/thirdparty/harfbuzz/upstream/hb-aat-layout-trak-table.hh b/thirdparty/harfbuzz/upstream/hb-aat-layout-trak-table.hh index 345a236e9..14a7d5794 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-layout-trak-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-aat-layout-trak-table.hh @@ -31,6 +31,7 @@ #include "hb-aat-layout-common.hh" #include "hb-ot-layout.hh" #include "hb-open-type.hh" +#include "hb-ot-stat-table.hh" /* * trak -- Tracking @@ -48,22 +49,74 @@ struct TrackTableEntry float get_track_value () const { return track.to_float (); } - int get_value (const void *base, unsigned int index, - unsigned int table_size) const - { return (base+valuesZ).as_array (table_size)[index]; } + float interpolate_at (unsigned int idx, + float ptem, + const void *base, + hb_array_t size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + float s0 = size_table[idx].to_float (); + float s1 = size_table[idx + 1].to_float (); + int v0 = values[idx]; + int v1 = values[idx + 1]; + + // Deal with font bugs. + if (unlikely (s1 < s0)) + { hb_swap (s0, s1); hb_swap (v0, v1); } + if (unlikely (ptem < s0)) return v0; + if (unlikely (ptem > s1)) return v1; + if (unlikely (s0 == s1)) return (v0 + v1) * 0.5f; + + float t = (ptem - s0) / (s1 - s0); + return v0 + t * (v1 - v0); + } + + float get_value (float ptem, + const void *base, + hb_array_t size_table) const + { + const FWORD *values = (base+valuesZ).arrayZ; + + unsigned int n_sizes = size_table.length; + + /* + * Choose size. + */ + if (!n_sizes) return 0.f; + if (n_sizes == 1) return values[0]; + + // At least two entries. + + unsigned i; + for (i = 0; i < n_sizes; i++) + if (size_table[i].to_float () >= ptem) + break; + + // Boundary conditions. + if (i == 0) return values[0]; + if (i == n_sizes) return values[n_sizes - 1]; + + // Exact match. + if (size_table[i].to_float () == ptem) return values[i]; + + // Interpolate. + return interpolate_at (i - 1, ptem, base, size_table); + } public: - bool sanitize (hb_sanitize_context_t *c, const void *base, - unsigned int table_size) const + bool sanitize (hb_sanitize_context_t *c, + const void *base, + unsigned int n_sizes) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (valuesZ.sanitize (c, base, table_size)))); + (valuesZ.sanitize (c, base, n_sizes)))); } protected: F16DOT16 track; /* Track value for this record. */ - NameID trackNameID; /* The 'name' table index for this track. + OT::NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ NNOffset16To> @@ -76,58 +129,38 @@ struct TrackTableEntry struct TrackData { - float interpolate_at (unsigned int idx, - float target_size, - const TrackTableEntry &trackTableEntry, - const void *base) const + float get_tracking (const void *base, float ptem, float track = 0.f) const { - unsigned int sizes = nSizes; - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); + unsigned count = nTracks; + hb_array_t size_table = (base+sizeTable).as_array (nSizes); - float s0 = size_table[idx].to_float (); - float s1 = size_table[idx + 1].to_float (); - float t = unlikely (s0 == s1) ? 0.f : (target_size - s0) / (s1 - s0); - return t * trackTableEntry.get_value (base, idx + 1, sizes) + - (1.f - t) * trackTableEntry.get_value (base, idx, sizes); - } + if (!count) return 0.f; + if (count == 1) return trackTable[0].get_value (ptem, base, size_table); - int get_tracking (const void *base, float ptem) const - { - /* - * Choose track. - */ - const TrackTableEntry *trackTableEntry = nullptr; - unsigned int count = nTracks; - for (unsigned int i = 0; i < count; i++) - { - /* Note: Seems like the track entries are sorted by values. But the - * spec doesn't explicitly say that. It just mentions it in the example. */ + // At least two entries. - /* For now we only seek for track entries with zero tracking value */ + unsigned i = 0; + unsigned j = count - 1; - if (trackTable[i].get_track_value () == 0.f) - { - trackTableEntry = &trackTable[i]; - break; - } - } - if (!trackTableEntry) return 0; + // Find the two entries that track is between. + while (i + 1 < count && trackTable[i + 1].get_track_value () <= track) + i++; + while (j > 0 && trackTable[j - 1].get_track_value () >= track) + j--; - /* - * Choose size. - */ - unsigned int sizes = nSizes; - if (!sizes) return 0; - if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - - hb_array_t size_table ((base+sizeTable).arrayZ, sizes); - unsigned int size_index; - for (size_index = 0; size_index < sizes - 1; size_index++) - if (size_table[size_index].to_float () >= ptem) - break; + // Exact match. + if (i == j) return trackTable[i].get_value (ptem, base, size_table); + + // Interpolate. + + float t0 = trackTable[i].get_track_value (); + float t1 = trackTable[j].get_track_value (); - return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem, - *trackTableEntry, base)); + float t = (track - t0) / (t1 - t0); + + float a = trackTable[i].get_value (ptem, base, size_table); + float b = trackTable[j].get_value (ptem, base, size_table); + return a + t * (b - a); } bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -158,42 +191,52 @@ struct trak bool has_data () const { return version.to_int (); } - bool apply (hb_aat_apply_context_t *c) const + hb_position_t get_h_tracking (hb_font_t *font, float track = 0.f) const { - TRACE_APPLY (this); + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_x ((this+horizData).get_tracking (this, ptem, track)); + } + hb_position_t get_v_tracking (hb_font_t *font, float track = 0.f) const + { + float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; + return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track)); + } + hb_position_t get_tracking (hb_font_t *font, hb_direction_t dir, float track = 0.f) const + { +#ifndef HB_NO_STYLE + if (!font->face->table.STAT->has_data ()) + return 0; + return HB_DIRECTION_IS_HORIZONTAL (dir) ? + get_h_tracking (font, track) : + get_v_tracking (font, track); +#else + return 0; +#endif + } - hb_mask_t trak_mask = c->plan->trak_mask; + bool apply (hb_aat_apply_context_t *c, float track = 0.f) const + { + TRACE_APPLY (this); - const float ptem = c->font->ptem; + float ptem = c->font->ptem; if (unlikely (ptem <= 0.f)) - return_trace (false); + { + /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ + ptem = HB_CORETEXT_DEFAULT_FONT_SIZE; + } hb_buffer_t *buffer = c->buffer; if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) { - const TrackData &trackData = this+horizData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_x (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_x (tracking); + hb_position_t advance_to_add = get_h_tracking (c->font, track); foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; buffer->pos[start].x_advance += advance_to_add; - buffer->pos[start].x_offset += offset_to_add; - } } else { - const TrackData &trackData = this+vertData; - int tracking = trackData.get_tracking (this, ptem); - hb_position_t offset_to_add = c->font->em_scalef_y (tracking / 2); - hb_position_t advance_to_add = c->font->em_scalef_y (tracking); + hb_position_t advance_to_add = get_v_tracking (c->font, track); foreach_grapheme (buffer, start, end) - { - if (!(buffer->info[start].mask & trak_mask)) continue; buffer->pos[start].y_advance += advance_to_add; - buffer->pos[start].y_offset += offset_to_add; - } } return_trace (true); diff --git a/thirdparty/harfbuzz/upstream/hb-aat-layout.cc b/thirdparty/harfbuzz/upstream/hb-aat-layout.cc index 9da29e51c..a48c4e0bc 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-layout.cc +++ b/thirdparty/harfbuzz/upstream/hb-aat-layout.cc @@ -37,6 +37,9 @@ #include "hb-aat-layout-trak-table.hh" #include "hb-aat-ltag-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gdef-table.hh" + /* * hb_aat_apply_context_t @@ -55,13 +58,14 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p buffer (buffer_), sanitizer (), ankr_table (&Null (AAT::ankr)), - gdef_table ( + gdef ( #ifndef HB_NO_OT_LAYOUT - face->table.GDEF->table + *face->table.GDEF->table #else - &Null (GDEF) + Null (GDEF) #endif ), + has_glyph_classes (gdef.has_glyph_classes ()), lookup_index (0) { sanitizer.init (blob); @@ -200,13 +204,43 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) #endif -#ifndef HB_NO_AAT +#ifndef HB_NO_AAT_SHAPE /* * mort/morx/kerx/trak */ +bool +AAT::morx::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + + switch HB_CODEPOINT_ENCODE3 (blob->length, + face->table.GSUB->table.get_length (), + face->table.GDEF->table.get_length ()) + { + /* https://github.com/harfbuzz/harfbuzz/issues/4108 + sha1sum:a71ca6813b7e56a772cffff7c24a5166b087197c AALMAGHRIBI.ttf */ + case HB_CODEPOINT_ENCODE3 (19892, 2794, 340): + return true; + } + return false; +} + +bool +AAT::mort::is_blocklisted (hb_blob_t *blob, + hb_face_t *face) const +{ +#ifdef HB_NO_AAT_LAYOUT_BLOCKLIST + return false; +#endif + return false; +} + void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) @@ -254,11 +288,14 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, const hb_feature_t *features, unsigned num_features) { - hb_aat_map_builder_t builder (font->face, plan->props); - for (unsigned i = 0; i < num_features; i++) - builder.add_feature (features[i]); hb_aat_map_t map; - builder.compile (map); + if (num_features) + { + hb_aat_map_builder_t builder (font->face, plan->props); + for (unsigned i = 0; i < num_features; i++) + builder.add_feature (features[i]); + builder.compile (map); + } { auto &accel = *font->face->table.morx; @@ -267,7 +304,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, { AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table morx")) return; - morx.apply (&c, map, accel); + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); + morx.apply (&c, num_features ? map : plan->aat_map, accel); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); + c.buffer_glyph_set = nullptr; (void) buffer->message (font, "end table morx"); return; } @@ -280,34 +320,24 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, { AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table mort")) return; - mort.apply (&c, map, accel); + mort.apply (&c, num_features ? map : plan->aat_map, accel); (void) buffer->message (font, "end table mort"); return; } } } -void -hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer) -{ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int i = 0; i < count; i++) - if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH)) - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; -} - static bool is_deleted_glyph (const hb_glyph_info_t *info) { - return info->codepoint == AAT::DELETED_GLYPH; + return _hb_glyph_info_is_aat_deleted (info); } void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { - buffer->delete_glyphs_inplace (is_deleted_glyph); + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED) + buffer->delete_glyphs_inplace (is_deleted_glyph); } /** @@ -338,8 +368,11 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, AAT::hb_aat_apply_context_t c (plan, font, buffer, accel.get_blob ()); if (!buffer->message (font, "start table kerx")) return; + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); c.set_ankr_table (font->face->table.ankr.get ()); accel.apply (&c); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); + c.buffer_glyph_set = nullptr; (void) buffer->message (font, "end table kerx"); } diff --git a/thirdparty/harfbuzz/upstream/hb-aat-layout.hh b/thirdparty/harfbuzz/upstream/hb-aat-layout.hh index 15c382aa9..8b80fd797 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-layout.hh +++ b/thirdparty/harfbuzz/upstream/hb-aat-layout.hh @@ -32,6 +32,9 @@ #include "hb-ot-shape.hh" #include "hb-aat-ltag-table.hh" +/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ +#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f + struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; @@ -57,9 +60,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, const hb_feature_t *features, unsigned num_features); -HB_INTERNAL void -hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer); - HB_INTERNAL void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer); diff --git a/thirdparty/harfbuzz/upstream/hb-aat-map.cc b/thirdparty/harfbuzz/upstream/hb-aat-map.cc index 5bdb8004f..0b85c901e 100644 --- a/thirdparty/harfbuzz/upstream/hb-aat-map.cc +++ b/thirdparty/harfbuzz/upstream/hb-aat-map.cc @@ -85,25 +85,31 @@ void hb_aat_map_builder_t::compile (hb_aat_map_t &m) { /* Compute active features per range, and compile each. */ + if (!features.length) + { + hb_aat_layout_compile_map (this, &m); + return; + } /* Sort features by start/end events. */ hb_vector_t feature_events; + feature_events.alloc_exact (features.length * 2 + 1); for (unsigned int i = 0; i < features.length; i++) { - auto &feature = features[i]; + auto &feature = features.arrayZ[i]; - if (features[i].start == features[i].end) + if (feature.start == feature.end) continue; feature_event_t *event; event = feature_events.push (); - event->index = features[i].start; + event->index = feature.start; event->start = true; event->feature = feature.info; event = feature_events.push (); - event->index = features[i].end; + event->index = feature.end; event->start = false; event->feature = feature.info; } @@ -139,12 +145,12 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m) current_features.qsort (); unsigned int j = 0; for (unsigned int i = 1; i < current_features.length; i++) - if (current_features[i].type != current_features[j].type || + if (current_features.arrayZ[i].type != current_features.arrayZ[j].type || /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off * respectively, so we mask out the low-order bit when checking for "duplicates" * (selectors referring to the same feature setting) here. */ - (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1)))) - current_features[++j] = current_features[i]; + (!current_features.arrayZ[i].is_exclusive && ((current_features.arrayZ[i].setting & ~1) != (current_features.arrayZ[j].setting & ~1)))) + current_features.arrayZ[++j] = current_features.arrayZ[i]; current_features.shrink (j + 1); } diff --git a/thirdparty/harfbuzz/upstream/hb-algs.hh b/thirdparty/harfbuzz/upstream/hb-algs.hh index b02793a09..b28a587d4 100644 --- a/thirdparty/harfbuzz/upstream/hb-algs.hh +++ b/thirdparty/harfbuzz/upstream/hb-algs.hh @@ -78,129 +78,255 @@ /* - * Big-endian integers. + * Fixed-endian integers / floats. */ + /* Endian swap, used in Windows related backends */ static inline constexpr uint16_t hb_uint16_swap (uint16_t v) { return (v >> 8) | (v << 8); } static inline constexpr uint32_t hb_uint32_swap (uint32_t v) { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } -#ifndef HB_FAST_INT_ACCESS +template +struct __attribute__((packed)) hb_packed_t +{ + hb_packed_t () = default; + constexpr hb_packed_t (Type V) : v (V) {} + operator Type () const { return v; } + hb_packed_t & operator = (Type V) { v = V; return *this; } + + private: + Type v; +}; + +#ifndef HB_FAST_NUM_ACCESS + #if defined(__OPTIMIZE__) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __BIG_ENDIAN || \ (__BYTE_ORDER == __LITTLE_ENDIAN && \ hb_has_builtin(__builtin_bswap16) && \ - hb_has_builtin(__builtin_bswap32))) -#define HB_FAST_INT_ACCESS 1 + hb_has_builtin(__builtin_bswap32) && \ + hb_has_builtin(__builtin_bswap64))) +#define HB_FAST_NUM_ACCESS 1 #else -#define HB_FAST_INT_ACCESS 0 +#define HB_FAST_NUM_ACCESS 0 +#endif + +// https://github.com/harfbuzz/harfbuzz/issues/5456 +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 12) +#undef HB_FAST_NUM_ACCESS +#define HB_FAST_NUM_ACCESS 0 #endif + #endif -template -struct BEInt; -template -struct BEInt +template +struct HBInt; +template +struct HBInt { public: - BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t (V)} {} + HBInt () = default; + constexpr HBInt (Type V) : v {uint8_t (V)} {} constexpr operator Type () const { return v; } private: uint8_t v; }; -template -struct BEInt +template +struct HBInt { - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; - public: - BEInt () = default; - - BEInt (Type V) -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); } -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - { ((packed_uint16_t *) v)->v = V; } -#endif + HBInt () = default; + + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + *((hb_packed_t *) v) = V; + else + *((hb_packed_t *) v) = __builtin_bswap16 (V); + } #else - : v {uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + : v {BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 8) & 0xFF)} {} #endif - constexpr operator Type () const { -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) v)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) v)->v; -#endif + constexpr operator Type () const + { +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + (uint16_t) *((const hb_packed_t *) v) + : + __builtin_bswap16 ((uint16_t) *((const hb_packed_t *) v)) + ; #else - return (v[0] << 8) - + (v[1] ); + return (BE ? (v[0] << 8) : (v[0] )) + + (BE ? (v[1] ) : (v[1] << 8)); #endif } private: uint8_t v[2]; }; -template -struct BEInt +template +struct HBInt { static_assert (!std::is_signed::value, ""); public: - BEInt () = default; - constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} - - constexpr operator Type () const { return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); } + HBInt () = default; + constexpr HBInt (Type V) : v {BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V ) & 0xFF)} {} + + constexpr operator Type () const { return (BE ? (v[0] << 16) : (v[0] )) + + (BE ? (v[1] << 8) : (v[1] << 8)) + + (BE ? (v[2] ) : (v[2] << 16)); } private: uint8_t v[3]; }; -template -struct BEInt +template +struct HBInt { - struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; + template + friend struct HBFloat; public: - BEInt () = default; - - BEInt (Type V) -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); } -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - { ((packed_uint32_t *) v)->v = V; } -#endif + HBInt () = default; + + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + *((hb_packed_t *) v) = V; + else + *((hb_packed_t *) v) = __builtin_bswap32 (V); + } #else - : v {uint8_t ((V >> 24) & 0xFF), - uint8_t ((V >> 16) & 0xFF), - uint8_t ((V >> 8) & 0xFF), - uint8_t ((V ) & 0xFF)} {} + : v {BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 24) & 0xFF)} {} #endif constexpr operator Type () const { -#if HB_FAST_INT_ACCESS -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap32 (((packed_uint32_t *) v)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint32_t *) v)->v; -#endif +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + (uint32_t) *((const hb_packed_t *) v) + : + __builtin_bswap32 ((uint32_t) *((const hb_packed_t *) v)) + ; #else - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); + return (BE ? (v[0] << 24) : (v[0] )) + + (BE ? (v[1] << 16) : (v[1] << 8)) + + (BE ? (v[2] << 8) : (v[2] << 16)) + + (BE ? (v[3] ) : (v[3] << 24)); #endif } private: uint8_t v[4]; }; +template +struct HBInt +{ + template + friend struct HBFloat; + + public: + HBInt () = default; + + HBInt (Type V) +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + *((hb_packed_t *) v) = V; + else + *((hb_packed_t *) v) = __builtin_bswap64 (V); + } +#else + : v {BE ? uint8_t ((V >> 56) & 0xFF) : uint8_t ((V ) & 0xFF), + BE ? uint8_t ((V >> 48) & 0xFF) : uint8_t ((V >> 8) & 0xFF), + BE ? uint8_t ((V >> 40) & 0xFF) : uint8_t ((V >> 16) & 0xFF), + BE ? uint8_t ((V >> 32) & 0xFF) : uint8_t ((V >> 24) & 0xFF), + BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V >> 32) & 0xFF), + BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 40) & 0xFF), + BE ? uint8_t ((V >> 8) & 0xFF) : uint8_t ((V >> 48) & 0xFF), + BE ? uint8_t ((V ) & 0xFF) : uint8_t ((V >> 56) & 0xFF)} {} +#endif + + constexpr operator Type () const { +#if HB_FAST_NUM_ACCESS + return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ? + (uint64_t) *((const hb_packed_t *) v) + : + __builtin_bswap64 ((uint64_t) *((const hb_packed_t *) v)) + ; +#else + return (BE ? (uint64_t (v[0]) << 56) : (uint64_t (v[0]) )) + + (BE ? (uint64_t (v[1]) << 48) : (uint64_t (v[1]) << 8)) + + (BE ? (uint64_t (v[2]) << 40) : (uint64_t (v[2]) << 16)) + + (BE ? (uint64_t (v[3]) << 32) : (uint64_t (v[3]) << 24)) + + (BE ? (uint64_t (v[4]) << 24) : (uint64_t (v[4]) << 32)) + + (BE ? (uint64_t (v[5]) << 16) : (uint64_t (v[5]) << 40)) + + (BE ? (uint64_t (v[6]) << 8) : (uint64_t (v[6]) << 48)) + + (BE ? (uint64_t (v[7]) ) : (uint64_t (v[7]) << 56)); +#endif + } + private: uint8_t v[8]; +}; /* Floats. */ +template +struct HBFloat +{ + using IntType = typename std::conditional::type; + + public: + HBFloat () = default; + + HBFloat (Type V) + { +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + { + *((hb_packed_t *) v) = V; + return; + } + } +#endif + + union { + hb_packed_t f; + hb_packed_t i; + } u = {{V}}; + + const HBInt I = (IntType) u.i; + for (unsigned i = 0; i < Bytes; i++) + v[i] = I.v[i]; + } + + /* c++14 constexpr */ operator Type () const + { +#if HB_FAST_NUM_ACCESS + { + if (BE == (__BYTE_ORDER == __BIG_ENDIAN)) + return (Type) *((const hb_packed_t *) v); + } +#endif + + HBInt I; + for (unsigned i = 0; i < Bytes; i++) + I.v[i] = v[i]; + + union { + hb_packed_t i; + hb_packed_t f; + } u = {{I}}; + + return (Type) u.f; + } + private: uint8_t v[Bytes]; +}; + + /* We want our rounding towards +infinity. */ static inline double _hb_roundf (double x) { return floor (x + .5); } @@ -210,6 +336,27 @@ _hb_roundf (float x) { return floorf (x + .5f); } #define roundf(x) _hb_roundf(x) +static inline void +hb_sincos (float rotation, float &s, float &c) +{ +#ifdef HAVE_SINCOSF + sincosf (rotation, &s, &c); +#else + c = cosf (rotation); + s = sinf (rotation); +#endif +} +static inline void +hb_sincos (double rotation, double &s, double &c) +{ +#ifdef HAVE_SINCOS + sincos (rotation, &s, &c); +#else + c = cos (rotation); + s = sin (rotation); +#endif +} + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ @@ -286,7 +433,7 @@ HB_FUNCOBJ (hb_bool); // Compression function for Merkle-Damgard construction. // This function is generated using the framework provided. -#define mix(h) ( \ +#define fasthash_mix(h) ( \ (void) ((h) ^= (h) >> 23), \ (void) ((h) *= 0x2127599bf4325c37ULL), \ (h) ^= (h) >> 47) @@ -310,7 +457,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) #pragma GCC diagnostic ignored "-Wcast-align" v = * (const uint64_t *) (pos++); #pragma GCC diagnostic pop - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -320,7 +467,7 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) while (pos != end) { v = pos++->v; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } } @@ -336,11 +483,11 @@ static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed) case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH; case 2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH; case 1: v ^= (uint64_t)pos2[0]; - h ^= mix(v); + h ^= fasthash_mix(v); h *= m; } - return mix(h); + return fasthash_mix(h); } static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed) @@ -734,6 +881,17 @@ HB_FUNCOBJ (hb_clamp); * Bithacks. */ +/* Return the number of 1 bits in a uint8_t; faster than hb_popcount() */ +static inline unsigned +hb_popcount8 (uint8_t v) +{ + static const uint8_t popcount4[16] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4 + }; + return popcount4[v & 0xF] + popcount4[v >> 4]; +} + /* Return the number of 1 bits in v. */ template static inline unsigned int @@ -1042,6 +1200,21 @@ hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *resu return (size > 0) && (count >= ((unsigned int) -1) / size); } +static inline bool +hb_unsigned_add_overflows (unsigned int a, unsigned int b, unsigned *result = nullptr) +{ +#if hb_has_builtin(__builtin_add_overflow) + unsigned stack_result; + if (!result) + result = &stack_result; + return __builtin_add_overflow (a, b, result); +#endif + + if (result) + *result = a + b; + return b > (unsigned int) -1 - a; +} + /* * Sort and search. @@ -1070,6 +1243,7 @@ _hb_cmp_operator (const void *pkey, const void *pval) } template +HB_HOT static inline bool hb_bsearch_impl (unsigned *pos, /* Out */ const K& key, @@ -1514,6 +1688,13 @@ double solve_itp (func_t f, double min_y, double max_y, double &ya, double &yb, double &y) { + // Guard against degenerate interval + if (b - a <= 0.0) + { + y = ya; + return a; + } + unsigned n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0)); const unsigned n0 = 1; // Hardwired const double k1 = 0.2 / (b - a); // Hardwired. @@ -1524,7 +1705,8 @@ double solve_itp (func_t f, { double x1_2 = 0.5 * (a + b); double r = scaled_epsilon - 0.5 * (b - a); - double xf = (yb * a - ya * b) / (yb - ya); + // Guard against yb == ya to prevent division by zero + double xf = (yb != ya) ? (yb * a - ya * b) / (yb - ya) : x1_2; double sigma = x1_2 - xf; double b_a = b - a; // This has k2 = 2 hardwired for efficiency. diff --git a/thirdparty/harfbuzz/upstream/hb-alloc-pool.hh b/thirdparty/harfbuzz/upstream/hb-alloc-pool.hh new file mode 100644 index 000000000..effea78eb --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-alloc-pool.hh @@ -0,0 +1,105 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_ALLOC_POOL_HH +#define HB_ALLOC_POOL_HH + +#include "hb-vector.hh" + +/* Memory pool for persistent small- to medium-sized allocations. + * + * Some AI musings on this, not necessarily true: + * + * This is a very simple implementation, but it's good enough for our + * purposes. It's not thread-safe. It's not very fast. It's not + * very memory efficient. It's not very cache efficient. It's not + * very anything efficient. But it's simple and it works. And it's + * good enough for our purposes. If you need something more + * sophisticated, use a real allocator. Or use a real language. */ + +struct hb_alloc_pool_t +{ + unsigned ChunkSize = 65536 - 2 * sizeof (void *); + + void *alloc (size_t size, unsigned alignment = 2 * sizeof (void *)) + { + if (unlikely (chunks.in_error ())) return nullptr; + + assert (alignment > 0); + assert (alignment <= 2 * sizeof (void *)); + assert ((alignment & (alignment - 1)) == 0); /* power of two */ + + if (size > (ChunkSize) / 4) + { + /* Big chunk, allocate separately. */ + hb_vector_t chunk; + if (unlikely (!chunk.resize (size))) return nullptr; + void *ret = chunk.arrayZ; + chunks.push (std::move (chunk)); + if (chunks.in_error ()) return nullptr; + if (chunks.length > 1) + { + // Bring back the previous last chunk to the end, so that + // we can continue to allocate from it. + hb_swap (chunks.arrayZ[chunks.length - 1], chunks.arrayZ[chunks.length - 2]); + } + return ret; + } + + unsigned pad = (unsigned) ((alignment - ((uintptr_t) current_chunk.arrayZ & (alignment - 1))) & (alignment - 1)); + + // Small chunk, allocate from the last chunk. + if (current_chunk.length < pad + size) + { + chunks.push (); + if (unlikely (chunks.in_error ())) return nullptr; + hb_vector_t &chunk = chunks.arrayZ[chunks.length - 1]; + if (unlikely (!chunk.resize (ChunkSize))) return nullptr; + current_chunk = chunk; + pad = (unsigned) ((alignment - ((uintptr_t) current_chunk.arrayZ & (alignment - 1))) & (alignment - 1)); + } + + current_chunk += pad; + + assert (current_chunk.length >= size); + void *ret = current_chunk.arrayZ; + current_chunk += size; + return ret; + } + + void discard (void *p_, size_t size) + { + // Reclaim memory if we can. + char *p = (char *) p_; + if (current_chunk.arrayZ == p + size && current_chunk.backwards_length >= size) + current_chunk -= size; + } + + private: + hb_vector_t> chunks; + hb_array_t current_chunk; +}; + + +#endif /* HB_ALLOC_POOL_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-array.hh b/thirdparty/harfbuzz/upstream/hb-array.hh index 9037179bc..b0fbe1b60 100644 --- a/thirdparty/harfbuzz/upstream/hb-array.hh +++ b/thirdparty/harfbuzz/upstream/hb-array.hh @@ -251,7 +251,8 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + unsigned stop = start + (end - start) / 2; + for (unsigned lhs = start, rhs = end - 1; lhs < stop; lhs++, rhs--) hb_swap (arrayZ[rhs], arrayZ[lhs]); } @@ -290,6 +291,13 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> && (unsigned int) (arrayZ + length - (const char *) p) >= size; } + template + bool check_end (const void *p) const + { + return (uintptr_t) (((const char *) p) - arrayZ) <= length; + } + /* Only call if you allocated the underlying array using hb_malloc() or similar. */ void fini () { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; } diff --git a/thirdparty/harfbuzz/upstream/hb-atomic.hh b/thirdparty/harfbuzz/upstream/hb-atomic.hh index 366fb32b7..5ea99e391 100644 --- a/thirdparty/harfbuzz/upstream/hb-atomic.hh +++ b/thirdparty/harfbuzz/upstream/hb-atomic.hh @@ -40,7 +40,6 @@ * Atomic integers and pointers. */ - /* We need external help for these */ #if defined(hb_atomic_int_impl_add) \ @@ -80,28 +79,11 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include -#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel) +#define HB_STL_ATOMIC_IMPL + #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) -#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) -#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) - -#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) -#define hb_atomic_ptr_impl_get(P) (reinterpret_cast *> (P)->load (std::memory_order_acquire)) -static inline bool -_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) -{ - const void *O = O_; // Need lvalue - return reinterpret_cast *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed); -} -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) - - #else /* defined(HB_NO_MT) */ #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) @@ -149,75 +131,135 @@ static inline void _hb_compiler_memory_r_barrier () {} #define hb_atomic_ptr_impl_get_relaxed(P) (*(P)) #endif #ifndef hb_atomic_int_impl_set -inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; } -inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; } +template +inline void hb_atomic_int_impl_set (T *AI, T v) { _hb_memory_w_barrier (); *AI = v; } #endif #ifndef hb_atomic_int_impl_get -inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } -inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; } +template +inline T hb_atomic_int_impl_get (const T *AI) { T v = *AI; _hb_memory_r_barrier (); return v; } #endif #ifndef hb_atomic_ptr_impl_get inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif - -struct hb_atomic_short_t +#ifdef HB_STL_ATOMIC_IMPL +template +struct hb_atomic_t { - hb_atomic_short_t () = default; - constexpr hb_atomic_short_t (short v) : v (v) {} - - hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; } - operator short () const { return get_relaxed (); } - - void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); } - short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - short get_acquire () const { return hb_atomic_int_impl_get (&v); } - short inc () { return hb_atomic_int_impl_add (&v, 1); } - short dec () { return hb_atomic_int_impl_add (&v, -1); } + hb_atomic_t () = default; + constexpr hb_atomic_t (T v) : v (v) {} + constexpr hb_atomic_t (const hb_atomic_t& o) : v (o.get_relaxed ()) {} + constexpr hb_atomic_t (hb_atomic_t&& o) : v (o.get_relaxed ()) { o.set_relaxed ({}); } + + hb_atomic_t &operator= (const hb_atomic_t& o) { set_relaxed (o.get_relaxed ()); return *this; } + hb_atomic_t &operator= (hb_atomic_t&& o){ set_relaxed (o.get_relaxed ()); o.set_relaxed ({}); return *this; } + hb_atomic_t &operator= (T v_) + { + set_relaxed (v_); + return *this; + } + operator T () const { return get_relaxed (); } + + void set_relaxed (T v_) { v.store (v_, std::memory_order_relaxed); } + void set_release (T v_) { v.store (v_, std::memory_order_release); } + T get_relaxed () const { return v.load (std::memory_order_relaxed); } + T get_acquire () const { return v.load (std::memory_order_acquire); } + T inc () { return v.fetch_add (1, std::memory_order_acq_rel); } + T dec () { return v.fetch_add (-1, std::memory_order_acq_rel); } + + int operator++ (int) { return inc (); } + int operator-- (int) { return dec (); } + + friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept + { + T v = a.get_acquire (); + a.set_relaxed (b.get_acquire ()); + b.set_relaxed (v); + } + + std::atomic v = 0; +}; - short v = 0; +template +struct hb_atomic_t +{ + hb_atomic_t () = default; + constexpr hb_atomic_t (T *v) : v (v) {} + hb_atomic_t (const hb_atomic_t &other) = delete; + + void init (T *v_ = nullptr) { set_relaxed (v_); } + void set_relaxed (T *v_) { v.store (v_, std::memory_order_relaxed); } + T *get_relaxed () const { return v.load (std::memory_order_relaxed); } + T *get_acquire () const { return v.load (std::memory_order_acquire); } + bool cmpexch (T *old, T *new_) { return v.compare_exchange_weak (old, new_, std::memory_order_acq_rel, std::memory_order_relaxed); } + + hb_atomic_t &operator= (const hb_atomic_t& o) { set_relaxed (o.get_relaxed ()); return *this; } + hb_atomic_t &operator= (hb_atomic_t&& o){ set_relaxed (o.get_relaxed ()); o.set_relaxed ({}); return *this; } + + operator bool () const { return get_acquire () != nullptr; } + T *operator->() const { return get_acquire (); } + template + operator C * () const + { + return get_acquire (); + } + + friend void swap (hb_atomic_t &a, hb_atomic_t &b) noexcept + { + T *p = a.get_acquire (); + a.set_relaxed (b.get_acquire ()); + b.set_relaxed (p); + } + + std::atomic v = nullptr; }; -struct hb_atomic_int_t +#else + +template +struct hb_atomic_t { - hb_atomic_int_t () = default; - constexpr hb_atomic_int_t (int v) : v (v) {} + hb_atomic_t () = default; + constexpr hb_atomic_t (T v) : v (v) {} + + hb_atomic_t& operator = (T v_) { set_relaxed (v_); return *this; } + operator T () const { return get_relaxed (); } - hb_atomic_int_t& operator = (int v_) { set_relaxed (v_); return *this; } - operator int () const { return get_relaxed (); } + void set_relaxed (T v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } + void set_release (T v_) { hb_atomic_int_impl_set (&v, v_); } + T get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } + T get_acquire () const { return hb_atomic_int_impl_get (&v); } + T inc () { return hb_atomic_int_impl_add (&v, 1); } + T dec () { return hb_atomic_int_impl_add (&v, -1); } - void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } - void set_release (int v_) { hb_atomic_int_impl_set (&v, v_); } - int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } - int get_acquire () const { return hb_atomic_int_impl_get (&v); } - int inc () { return hb_atomic_int_impl_add (&v, 1); } - int dec () { return hb_atomic_int_impl_add (&v, -1); } + int operator ++ (int) { return inc (); } + int operator -- (int) { return dec (); } - int v = 0; + T v = 0; }; -template -struct hb_atomic_ptr_t +template +struct hb_atomic_t { - typedef hb_remove_pointer

T; - - hb_atomic_ptr_t () = default; - constexpr hb_atomic_ptr_t (T* v) : v (v) {} - hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete; + hb_atomic_t () = default; + constexpr hb_atomic_t (T* v) : v (v) {} + hb_atomic_t (const hb_atomic_t &other) = delete; void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } T *get_acquire () const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } - bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + bool cmpexch (T *old, T *new_) { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } + operator bool () const { return get_acquire () != nullptr; } T * operator -> () const { return get_acquire (); } template operator C * () const { return get_acquire (); } T *v = nullptr; }; +#endif + static inline bool hb_barrier () { _hb_compiler_memory_r_barrier (); diff --git a/thirdparty/harfbuzz/upstream/hb-bimap.hh b/thirdparty/harfbuzz/upstream/hb-bimap.hh index f54147254..f9c0e8870 100644 --- a/thirdparty/harfbuzz/upstream/hb-bimap.hh +++ b/thirdparty/harfbuzz/upstream/hb-bimap.hh @@ -176,7 +176,7 @@ struct hb_inc_bimap_t { hb_codepoint_t count = get_population (); hb_vector_t work; - if (unlikely (!work.resize (count, false))) return; + if (unlikely (!work.resize_dirty (count))) return; for (hb_codepoint_t rhs = 0; rhs < count; rhs++) work.arrayZ[rhs] = back_map[rhs]; diff --git a/thirdparty/harfbuzz/upstream/hb-bit-page.hh b/thirdparty/harfbuzz/upstream/hb-bit-page.hh index 869c67895..16d5886a2 100644 --- a/thirdparty/harfbuzz/upstream/hb-bit-page.hh +++ b/thirdparty/harfbuzz/upstream/hb-bit-page.hh @@ -78,6 +78,28 @@ struct hb_vector_size_t hb_vector_size_t operator ~ () const { return process (hb_bitwise_neg); } + operator bool () const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i]) + return true; + return false; + } + operator unsigned int () const + { + unsigned int r = 0; + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + r += hb_popcount (v[i]); + return r; + } + bool operator == (const hb_vector_size_t &o) const + { + for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) + if (v[i] != o.v[i]) + return false; + return true; + } + hb_array_t iter () const { return hb_array (v); } @@ -89,6 +111,8 @@ struct hb_vector_size_t struct hb_bit_page_t { + hb_bit_page_t () { init0 (); } + void init0 () { v.init0 (); population = 0; } void init1 () { v.init1 (); population = PAGE_BITS; } @@ -101,10 +125,9 @@ struct hb_bit_page_t bool is_empty () const { if (has_population ()) return !population; - return - + hb_iter (v) - | hb_none - ; + bool empty = !v; + if (empty) population = 0; + return empty; } uint32_t hash () const { @@ -115,6 +138,11 @@ struct hb_bit_page_t void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); } void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } + bool has (hb_codepoint_t g) const { return get (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -220,13 +248,17 @@ struct hb_bit_page_t } bool operator == (const hb_bit_page_t &other) const { return is_equal (other); } - bool is_equal (const hb_bit_page_t &other) const + bool is_equal (const hb_bit_page_t &other) const { return v == other.v; } + bool intersects (const hb_bit_page_t &other) const { for (unsigned i = 0; i < len (); i++) - if (v[i] != other.v[i]) - return false; - return true; + if (v[i] & other.v[i]) + return true; + return false; } + bool may_intersect (const hb_bit_page_t &other) const + { return intersects (other); } + bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); } bool is_subset (const hb_bit_page_t &larger_page) const { @@ -241,14 +273,10 @@ struct hb_bit_page_t } bool has_population () const { return population != UINT_MAX; } - unsigned int get_population () const + unsigned get_population () const { if (has_population ()) return population; - population = - + hb_iter (v) - | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u) - ; - return population; + return population = v; } bool next (hb_codepoint_t *codepoint) const @@ -263,7 +291,7 @@ struct hb_bit_page_t unsigned int j = m & ELT_MASK; const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); - for (const elt_t *p = &vv; i < len (); p = &v[++i]) + for (const elt_t *p = &vv; i < len (); p = ((const elt_t *) &v[0]) + (++i)) if (*p) { *codepoint = i * ELT_BITS + elt_get_min (*p); @@ -319,6 +347,36 @@ struct hb_bit_page_t return 0; } + /* + * Iterator implementation. + */ + struct iter_t : hb_iter_with_fallback_t + { + static constexpr bool is_sorted_iterator = true; + iter_t (const hb_bit_page_t &s_ = Null (hb_bit_page_t), bool init = true) : s (&s_), v (INVALID) + { + if (init) + v = s->get_min (); + } + + typedef hb_codepoint_t __item_t__; + hb_codepoint_t __item__ () const { return v; } + bool __more__ () const { return v != INVALID; } + void __next__ () { + s->next (&v); + } + void __prev__ () { s->previous (&v); } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const + { return v != o.v; } + + protected: + const hb_bit_page_t *s; + hb_codepoint_t v; + }; + iter_t iter () const { return iter_t (*this); } + operator iter_t () const { return iter (); } + static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; typedef unsigned long long elt_t; diff --git a/thirdparty/harfbuzz/upstream/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/upstream/hb-bit-set-invertible.hh index d5d1326d9..48b2e2184 100644 --- a/thirdparty/harfbuzz/upstream/hb-bit-set-invertible.hh +++ b/thirdparty/harfbuzz/upstream/hb-bit-set-invertible.hh @@ -126,6 +126,7 @@ struct hb_bit_set_invertible_t { unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -139,6 +140,9 @@ struct hb_bit_set_invertible_t hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_bit_set_invertible_t &other) const + { return inverted || other.inverted || s.intersects (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -169,7 +173,14 @@ struct hb_bit_set_invertible_t bool is_subset (const hb_bit_set_invertible_t &larger_set) const { if (unlikely (inverted != larger_set.inverted)) - return hb_all (hb_iter (s) | hb_map (larger_set.s)); + { + if (inverted) + return hb_all (iter (), larger_set.s); + else + // larger set is inverted so larger_set.s is the set of things that are not present + // in larger_set, therefore if s has any of those it can't be a subset. + return !s.intersects (larger_set.s); + } else return unlikely (inverted) ? larger_set.s.is_subset (s) : s.is_subset (larger_set.s); } @@ -364,7 +375,7 @@ struct hb_bit_set_invertible_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return v != o.v || s != o.s; } + { return v != o.v; } protected: const hb_bit_set_invertible_t *s; diff --git a/thirdparty/harfbuzz/upstream/hb-bit-set.hh b/thirdparty/harfbuzz/upstream/hb-bit-set.hh index 5f4c6f0af..05725048c 100644 --- a/thirdparty/harfbuzz/upstream/hb-bit-set.hh +++ b/thirdparty/harfbuzz/upstream/hb-bit-set.hh @@ -77,7 +77,7 @@ struct hb_bit_set_t bool successful = true; /* Allocations successful */ mutable unsigned int population = 0; - mutable hb_atomic_int_t last_page_lookup = 0; + mutable hb_atomic_t last_page_lookup = 0; hb_sorted_vector_t page_map; hb_vector_t pages; @@ -88,12 +88,13 @@ struct hb_bit_set_t { if (unlikely (!successful)) return false; - if (pages.length == 0 && count == 1) + if (pages.length < count && (unsigned) pages.allocated < count && count <= 2) exact_size = true; // Most sets are small and local - if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size))) + if (unlikely (!pages.resize_full (count, clear, exact_size) || + !page_map.resize_full (count, clear, false))) { - pages.resize (page_map.length, clear, exact_size); + pages.resize_full (page_map.length, clear, exact_size); successful = false; return false; } @@ -107,10 +108,11 @@ struct hb_bit_set_t page_map.alloc (sz); } - void reset () + hb_bit_set_t& reset () { successful = true; clear (); + return *this; } void clear () @@ -297,9 +299,9 @@ struct hb_bit_set_t unsigned int write_index = 0; for (unsigned int i = 0; i < page_map.length; i++) { - int m = (int) page_map[i].major; + int m = (int) page_map.arrayZ[i].major; if (m < ds || de < m) - page_map[write_index++] = page_map[i]; + page_map.arrayZ[write_index++] = page_map.arrayZ[i]; } compact (compact_workspace, write_index); resize (write_index); @@ -345,6 +347,7 @@ struct hb_bit_set_t return false; return page->get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -358,6 +361,31 @@ struct hb_bit_set_t hb_bit_set_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool intersects (const hb_bit_set_t &other) const + { + unsigned int na = pages.length; + unsigned int nb = other.pages.length; + + unsigned int a = 0, b = 0; + for (; a < na && b < nb; ) + { + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) + { + if (page_at (a).intersects (other.page_at (b))) + return true; + a++; + b++; + } + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) + a++; + else + b++; + } + return false; + } + bool may_intersect (const hb_bit_set_t &other) const + { return intersects (other); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { hb_codepoint_t c = first - 1; @@ -367,7 +395,7 @@ struct hb_bit_set_t { if (unlikely (!successful)) return; unsigned int count = other.pages.length; - if (unlikely (!resize (count, false, exact_size))) + if (unlikely (!resize (count, false, exact_size))) return; population = other.population; @@ -389,7 +417,7 @@ struct hb_bit_set_t { if (page_at (a).is_empty ()) { a++; continue; } if (other.page_at (b).is_empty ()) { b++; continue; } - if (page_map[a].major != other.page_map[b].major || + if (page_map.arrayZ[a].major != other.page_map.arrayZ[b].major || !page_at (a).is_equal (other.page_at (b))) return false; a++; @@ -410,23 +438,31 @@ struct hb_bit_set_t return false; uint32_t spi = 0; - for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++) + uint32_t lpi = 0; + while (spi < page_map.length && lpi < larger_set.page_map.length) { - uint32_t spm = page_map[spi].major; - uint32_t lpm = larger_set.page_map[lpi].major; + uint32_t spm = page_map.arrayZ[spi].major; + uint32_t lpm = larger_set.page_map.arrayZ[lpi].major; auto sp = page_at (spi); - if (spm < lpm && !sp.is_empty ()) - return false; + if (spm < lpm) { + if (!sp.is_empty ()) + return false; + spi++; + continue; + } - if (lpm < spm) + if (lpm < spm) { + lpi++; continue; + } auto lp = larger_set.page_at (lpi); if (!sp.is_subset (lp)) return false; spi++; + lpi++; } while (spi < page_map.length) @@ -503,7 +539,7 @@ struct hb_bit_set_t for (; a < na && b < nb; ) { - if (page_map[a].major == other.page_map[b].major) + if (page_map.arrayZ[a].major == other.page_map.arrayZ[b].major) { if (!passthru_left) { @@ -512,7 +548,7 @@ struct hb_bit_set_t // passthru_left is set since no left side pages will be removed // in that case. if (write_index < a) - page_map[write_index] = page_map[a]; + page_map.arrayZ[write_index] = page_map.arrayZ[a]; write_index++; } @@ -520,7 +556,7 @@ struct hb_bit_set_t a++; b++; } - else if (page_map[a].major < other.page_map[b].major) + else if (page_map.arrayZ[a].major < other.page_map.arrayZ[b].major) { if (passthru_left) count++; @@ -765,8 +801,8 @@ struct hb_bit_set_t unsigned int initial_size = size; for (unsigned int i = start_page; i < page_map.length && size; i++) { - uint32_t base = major_start (page_map[i].major); - unsigned int n = pages[page_map[i].index].write (base, start_page_value, out, size); + uint32_t base = major_start (page_map.arrayZ[i].major); + unsigned int n = pages[page_map.arrayZ[i].index].write (base, start_page_value, out, size); out += n; size -= n; start_page_value = 0; @@ -814,8 +850,8 @@ struct hb_bit_set_t hb_codepoint_t next_value = codepoint + 1; for (unsigned int i=start_page; i= 0; i--) { - const auto& map = page_map[(unsigned) i]; - const auto& page = pages[map.index]; + const auto& map = page_map.arrayZ[(unsigned) i]; + const auto& page = pages.arrayZ[map.index]; if (!page.is_empty ()) return map.major * page_t::PAGE_BITS + page.get_max (); @@ -895,7 +931,7 @@ struct hb_bit_set_t unsigned __len__ () const { return l; } iter_t end () const { return iter_t (*s, false); } bool operator != (const iter_t& o) const - { return s != o.s || v != o.v; } + { return v != o.v; } protected: const hb_bit_set_t *s; @@ -961,7 +997,7 @@ struct hb_bit_set_t return nullptr; last_page_lookup = i; - return &pages.arrayZ[page_map[i].index]; + return &pages.arrayZ[page_map.arrayZ[i].index]; } page_t &page_at (unsigned int i) { diff --git a/thirdparty/harfbuzz/upstream/hb-bit-vector.hh b/thirdparty/harfbuzz/upstream/hb-bit-vector.hh new file mode 100644 index 000000000..58084e59a --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-bit-vector.hh @@ -0,0 +1,195 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_BIT_VECTOR_HH +#define HB_BIT_VECTOR_HH + +#include "hb.hh" + +#include "hb-atomic.hh" + +struct hb_min_max_t +{ + void add (hb_codepoint_t v) { min_v = hb_min (min_v, v); max_v = hb_max (max_v, v); } + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + min_v = hb_min (min_v, a); + max_v = hb_max (max_v, b); + } + + template + void union_ (const set_t &set) + { + hb_codepoint_t set_min = set.get_min (); + if (unlikely (set_min == HB_CODEPOINT_INVALID)) + return; + hb_codepoint_t set_max = set.get_max (); + min_v = hb_min (min_v, set_min); + max_v = hb_max (max_v, set_max); + } + + hb_codepoint_t get_min () const { return min_v; } + hb_codepoint_t get_max () const { return max_v; } + + private: + hb_codepoint_t min_v = HB_CODEPOINT_INVALID; + hb_codepoint_t max_v = 0; +}; + +template +struct hb_bit_vector_t +{ + using int_t = uint64_t; + using elt_t = typename std::conditional, int_t>::type; + + hb_bit_vector_t () = delete; + hb_bit_vector_t (const hb_bit_vector_t &other) = delete; + hb_bit_vector_t &operator= (const hb_bit_vector_t &other) = delete; + + // Move + hb_bit_vector_t (hb_bit_vector_t &&other) + : min_v (other.min_v), max_v (other.max_v), count (other.count), elts (other.elts) + { + other.min_v = other.max_v = other.count = 0; + other.elts = nullptr; + } + hb_bit_vector_t &operator= (hb_bit_vector_t &&other) + { + hb_swap (min_v, other.min_v); + hb_swap (max_v, other.max_v); + hb_swap (count, other.count); + hb_swap (elts, other.elts); + return *this; + } + + hb_bit_vector_t (unsigned min_v, unsigned max_v) + : min_v (min_v), max_v (max_v) + { + if (unlikely (min_v >= max_v)) + { + min_v = max_v = count = 0; + return; + } + + unsigned num = (max_v - min_v + sizeof (int_t) * 8) / (sizeof (int_t) * 8); + elts = (elt_t *) hb_calloc (num, sizeof (int_t)); + if (unlikely (!elts)) + { + min_v = max_v = count = 0; + return; + } + + count = max_v - min_v + 1; + } + ~hb_bit_vector_t () + { + hb_free (elts); + } + + void add (hb_codepoint_t g) { elt (g) |= mask (g); } + void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } + void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } + bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + bool has (hb_codepoint_t g) const { return get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } + + bool operator [] (hb_codepoint_t g) const { return get (g); } + bool operator () (hb_codepoint_t g) const { return get (g); } + + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!count || a > b || a < min_v || b > max_v)) + return; + + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la |= (mask (b) << 1) - mask(a); + else + { + *la |= ~(mask (a) - 1llu); + la++; + + hb_memset (la, 0xff, (char *) lb - (char *) la); + + *lb |= ((mask (b) << 1) - 1llu); + } + } + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!count || a > b || a < min_v || b > max_v)) + return; + + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la &= ~((mask (b) << 1llu) - mask(a)); + else + { + *la &= mask (a) - 1; + la++; + + hb_memset (la, 0, (char *) lb - (char *) la); + + *lb &= ~((mask (b) << 1) - 1llu); + } + } + void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v) + { if (v) add_range (a, b); else del_range (a, b); } + + template + void union_ (const set_t &set) + { + for (hb_codepoint_t g : set) + add (g); + } + + static const unsigned int ELT_BITS = sizeof (elt_t) * 8; + static constexpr unsigned ELT_MASK = ELT_BITS - 1; + + static constexpr elt_t zero = 0; + + elt_t &elt (hb_codepoint_t g) + { + g -= min_v; + if (unlikely (g >= count)) + return Crap(elt_t); + return elts[g / ELT_BITS]; + } + const elt_t& elt (hb_codepoint_t g) const + { + g -= min_v; + if (unlikely (g >= count)) + return Null(elt_t); + return elts[g / ELT_BITS]; + } + + static constexpr int_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); } + + hb_codepoint_t min_v = 0, max_v = 0, count = 0; + elt_t *elts = nullptr; +}; + + +#endif /* HB_BIT_VECTOR_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-blob.hh b/thirdparty/harfbuzz/upstream/hb-blob.hh index b1b3b94d3..7d28c161f 100644 --- a/thirdparty/harfbuzz/upstream/hb-blob.hh +++ b/thirdparty/harfbuzz/upstream/hb-blob.hh @@ -50,6 +50,20 @@ struct hb_blob_t } } + void replace_buffer (const char *new_data, + unsigned new_length, + hb_memory_mode_t new_mode, + void *new_user_data, + hb_destroy_func_t new_destroy) + { + destroy_user_data (); + data = new_data; + length = new_length; + mode = new_mode; + user_data = new_user_data; + destroy = new_destroy; + } + HB_INTERNAL bool try_make_writable (); HB_INTERNAL bool try_make_writable_inplace (); HB_INTERNAL bool try_make_writable_inplace_unix (); diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.hh index 1deaaafd8..75a1a1129 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.hh +++ b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.hh @@ -34,60 +34,47 @@ #line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, - 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, - 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, - 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, - 9u, 123u, 0u, 0u, 0 + 0u, 0u, 9u, 34u, 97u, 121u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, + 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, + 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, + 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, + 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 98u, 98u, 9u, 123u, 9u, 123u, 9u, 123u, + 0 }; static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 21, 2, 1, 50, 49, - 10, 117, 117, 85, 117, 1, 50, 49, - 10, 117, 117, 1, 1, 50, 49, 117, - 117, 2, 1, 50, 49, 10, 117, 117, - 1, 50, 49, 10, 117, 117, 1, 1, - 50, 49, 117, 117, 1, 50, 49, 59, - 117, 59, 117, 117, 1, 50, 49, 117, - 115, 0 + 0, 26, 25, 2, 1, 50, 49, 10, + 117, 117, 85, 117, 1, 50, 49, 10, + 117, 117, 1, 1, 50, 49, 117, 117, + 2, 1, 50, 49, 10, 117, 117, 1, + 50, 49, 10, 117, 117, 1, 1, 50, + 49, 117, 117, 1, 50, 49, 59, 117, + 59, 117, 117, 1, 50, 49, 10, 117, + 1, 50, 49, 117, 1, 115, 115, 115 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 165, 168, 170, 221, - 271, 282, 400, 518, 604, 722, 724, 775, - 825, 836, 954, 1072, 1074, 1076, 1127, 1177, - 1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648, - 1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118, - 2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560, - 2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137, - 3255, 3371 + 0, 0, 27, 53, 56, 58, 109, 159, + 170, 288, 406, 492, 610, 612, 663, 713, + 724, 842, 960, 962, 964, 1015, 1065, 1183, + 1301, 1304, 1306, 1357, 1407, 1418, 1536, 1654, + 1656, 1707, 1757, 1768, 1886, 2004, 2006, 2008, + 2059, 2109, 2227, 2345, 2347, 2398, 2448, 2508, + 2626, 2686, 2804, 2922, 2924, 2975, 3025, 3036, + 3154, 3156, 3207, 3257, 3375, 3377, 3493, 3609 }; static const char _deserialize_json_indicies[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 2, 1, 3, 1, 4, 5, + 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 8, 9, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 10, 1, 11, 12, + 9, 1, 8, 10, 10, 1, 11, 12, 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -121,7 +108,7 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -131,18 +118,18 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 24, 1, 25, - 25, 25, 25, 25, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 24, 1, 24, + 24, 24, 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 25, 1, + 1, 1, 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 26, 1, 1, 1, 1, 1, + 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 27, 1, 20, 20, 20, + 1, 1, 1, 25, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, @@ -157,26 +144,26 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 22, 1, 28, 1, 28, 28, 28, - 28, 28, 1, 1, 1, 1, 1, 1, + 1, 22, 1, 26, 1, 26, 26, 26, + 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 28, 1, 1, 1, + 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 29, 29, 29, 29, 29, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 27, 1, + 27, 27, 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 29, + 1, 1, 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 30, 1, 1, 31, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 1, 33, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 35, 35, 35, - 35, 35, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 28, 1, 1, 29, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 1, 31, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 1, 33, 33, 33, + 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 1, 1, 1, + 1, 1, 1, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 36, 1, 1, 1, 1, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -186,13 +173,13 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 1, 35, 35, 35, 35, 35, + 1, 35, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 36, 1, - 1, 1, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 1, 1, 1, 1, + 1, 1, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 34, 1, + 1, 1, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -200,25 +187,25 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 37, - 1, 38, 1, 39, 1, 39, 39, 39, - 39, 39, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 35, + 1, 36, 1, 37, 1, 37, 37, 37, + 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 39, 1, 1, 1, + 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 40, 1, - 40, 40, 40, 40, 40, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 38, 1, + 38, 38, 38, 38, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 41, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 1, 43, 43, 43, 43, 43, 1, + 1, 1, 1, 1, 1, 1, 1, 39, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 1, 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 43, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 44, 1, 1, + 1, 41, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -228,41 +215,43 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 45, 1, - 43, 43, 43, 43, 43, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 43, 1, + 41, 41, 41, 41, 41, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 41, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 43, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 44, 1, 1, 1, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 45, 46, + 1, 47, 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 45, 1, 47, 48, - 1, 49, 1, 49, 49, 49, 49, 49, + 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 48, 1, 48, 48, + 48, 48, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 50, 50, - 50, 50, 50, 1, 1, 1, 1, 1, + 1, 1, 49, 1, 1, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 1, + 52, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 52, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 1, - 54, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 56, 56, 56, 56, 56, + 1, 1, 54, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -270,43 +259,43 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 56, + 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 58, - 1, 56, 56, 56, 56, 56, 1, 1, + 54, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 55, 1, 1, 1, + 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 56, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 57, 1, 1, 1, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 57, + 1, 57, 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 59, - 1, 59, 59, 59, 59, 59, 1, 1, + 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 1, 58, 58, 58, 58, + 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 60, 1, 60, 60, 60, 60, - 60, 1, 1, 1, 1, 1, 1, 1, + 59, 1, 1, 60, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 1, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 1, 64, 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 61, 1, 1, 62, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 1, 64, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 1, 66, 66, 66, 66, 66, 1, 1, + 64, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 66, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -314,42 +303,42 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 66, 1, 64, + 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 68, 1, 66, - 66, 66, 66, 66, 1, 1, 1, 1, + 1, 1, 65, 1, 1, 1, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 67, 1, 1, 1, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 67, 1, 68, + 1, 68, 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 1, 69, 1, 70, - 1, 70, 70, 70, 70, 70, 1, 1, + 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 70, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 69, 1, 69, 69, 69, 69, + 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 71, 1, 71, 71, 71, 71, - 71, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 70, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 1, 72, 72, + 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 72, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 1, 74, 74, - 74, 74, 74, 1, 1, 1, 1, 1, + 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -357,73 +346,85 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 74, 1, 72, 72, 72, 72, + 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 73, + 1, 1, 1, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 76, 1, 74, 74, 74, 74, - 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 74, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 75, - 1, 1, 1, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 76, 1, 76, 76, 76, 76, + 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 78, 1, 78, 78, 78, 78, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 77, 1, 77, + 77, 77, 77, 77, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 77, 1, 78, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 79, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 1, 82, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 83, 81, 84, 84, 84, + 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 1, 1, 1, + 1, 1, 1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 79, - 79, 79, 79, 79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 79, 1, - 80, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 81, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 1, 84, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 85, 83, 86, 86, 86, - 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 86, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 88, 1, 83, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 81, 1, 87, + 87, 87, 87, 87, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 87, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 88, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 83, 1, 89, - 89, 89, 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 90, 1, 1, 1, 1, 1, + 1, 1, 1, 89, 1, 87, 87, 87, + 87, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 88, 1, 1, 1, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -431,52 +432,86 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 91, 1, 89, 89, 89, - 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 89, 1, 1, 1, + 1, 89, 1, 91, 1, 91, 91, 91, + 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 90, 1, 1, 1, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 1, 1, + 1, 1, 1, 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 92, 1, + 92, 92, 92, 92, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 93, 1, 1, 94, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 1, 23, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 1, 23, 23, 23, + 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 91, 1, 93, 1, 93, 93, 93, - 93, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 94, 1, - 94, 94, 94, 94, 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 94, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 95, - 96, 96, 96, 96, 96, 96, 96, 96, - 96, 1, 89, 89, 89, 89, 89, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 24, 1, 97, 1, 97, 97, 97, + 97, 97, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 97, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 98, 1, + 98, 98, 98, 98, 98, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 98, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 99, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 1, 87, 87, 87, 87, 87, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 87, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 88, 1, 1, + 1, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 89, 1, + 8, 1, 102, 102, 102, 102, 102, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 102, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 89, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 90, 1, 1, - 1, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 104, 1, 103, 103, + 103, 103, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 91, 1, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -484,53 +519,65 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 104, 1, 25, 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 1, 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 104, 1, 0 }; static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 19, 25, - 38, 44, 52, 5, 13, 6, 7, 8, - 9, 12, 9, 12, 10, 2, 11, 10, - 11, 11, 56, 57, 14, 15, 16, 17, - 18, 17, 18, 10, 2, 11, 20, 21, - 22, 23, 24, 10, 2, 11, 24, 26, - 32, 27, 28, 29, 30, 31, 30, 31, - 10, 2, 11, 33, 34, 35, 36, 37, - 36, 37, 10, 2, 11, 39, 40, 41, - 42, 43, 10, 2, 11, 43, 45, 46, - 47, 50, 51, 47, 48, 49, 10, 2, - 11, 10, 2, 11, 51, 53, 54, 50, - 55, 55 + 1, 0, 2, 3, 18, 24, 37, 43, + 51, 56, 60, 4, 12, 5, 6, 7, + 8, 11, 8, 11, 9, 1, 10, 9, + 10, 63, 13, 14, 15, 16, 17, 16, + 17, 9, 1, 10, 19, 20, 21, 22, + 23, 9, 1, 10, 23, 25, 31, 26, + 27, 28, 29, 30, 29, 30, 9, 1, + 10, 32, 33, 34, 35, 36, 35, 36, + 9, 1, 10, 38, 39, 40, 41, 42, + 9, 1, 10, 42, 44, 45, 46, 49, + 50, 46, 47, 48, 9, 1, 10, 9, + 1, 10, 50, 52, 53, 54, 9, 55, + 55, 57, 58, 49, 59, 59, 61, 62, + 1 }; static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 0, 0, 3, 3, 4, 0, - 5, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 6, 6, 7, 0, 0, - 0, 2, 2, 8, 8, 9, 0, 0, - 0, 0, 0, 2, 2, 2, 0, 0, - 10, 10, 11, 0, 0, 2, 2, 2, - 0, 0, 12, 12, 13, 0, 0, 0, - 2, 2, 14, 14, 15, 0, 0, 0, - 2, 16, 16, 0, 17, 0, 18, 18, - 19, 20, 20, 21, 17, 0, 0, 22, - 22, 23 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 2, 2, 2, 0, + 0, 3, 0, 0, 1, 1, 1, 0, + 0, 4, 4, 4, 0, 0, 0, 1, + 1, 5, 5, 5, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 6, 6, + 6, 0, 0, 1, 1, 1, 0, 0, + 7, 7, 7, 0, 0, 0, 1, 1, + 8, 8, 8, 0, 0, 0, 1, 9, + 9, 0, 10, 0, 11, 11, 11, 12, + 12, 12, 10, 0, 0, 1, 1, 1, + 0, 0, 0, 13, 13, 14, 0, 0, + 15 }; -static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 56; +static const int deserialize_json_start = 61; +static const int deserialize_json_first_final = 61; static const int deserialize_json_error = 0; -static const int deserialize_json_en_main = 1; +static const int deserialize_json_en_main = 61; -#line 111 "hb-buffer-deserialize-json.rl" +#line 115 "hb-buffer-deserialize-json.rl" static hb_bool_t @@ -545,22 +592,17 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - *end_ptr = ++p; - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 559 "hb-buffer-deserialize-json.hh" +#line 601 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 564 "hb-buffer-deserialize-json.hh" +#line 606 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -585,14 +627,14 @@ _resume: goto _again; switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: + case 15: #line 38 "hb-buffer-deserialize-json.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } break; - case 5: + case 3: #line 43 "hb-buffer-deserialize-json.rl" { buffer->add_info (info); @@ -602,21 +644,21 @@ _resume: *end_ptr = p; } break; - case 2: + case 1: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; } break; - case 17: + case 10: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 23: + case 14: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 18: + case 11: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ @@ -626,35 +668,35 @@ _resume: return false; } break; - case 20: + case 12: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } break; - case 8: + case 5: #line 67 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; - case 10: + case 6: #line 68 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 12: + case 7: #line 69 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 3: + case 2: #line 70 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 6: + case 4: #line 71 "hb-buffer-deserialize-json.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 14: + case 8: #line 72 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.mask )) return false; } break; - case 16: + case 9: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -662,7 +704,7 @@ _resume: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 22: + case 13: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -670,109 +712,7 @@ _resume: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 19: -#line 58 "hb-buffer-deserialize-json.rl" - { - /* TODO Unescape \" and \\ if found. */ - if (!hb_font_glyph_from_string (font, - tok+1, p - tok - 2, /* Skip "" */ - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 21: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 68 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 69 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 4: -#line 70 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 71 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 15: -#line 72 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 776 "hb-buffer-deserialize-json.hh" +#line 716 "hb-buffer-deserialize-json.hh" } _again: @@ -784,12 +724,12 @@ _again: _out: {} } -#line 137 "hb-buffer-deserialize-json.rl" +#line 136 "hb-buffer-deserialize-json.rl" *end_ptr = p; - return p == pe && *(p-1) != ']'; + return p == pe; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.rl b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.rl index b12dd0f1a..d624d68c6 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.rl +++ b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-json.rl @@ -91,6 +91,8 @@ yoffset = "\"dy\"" colon (num >tok %parse_y_offset); xadvance= "\"ax\"" colon (num >tok %parse_x_advance); yadvance= "\"ay\"" colon (num >tok %parse_y_advance); glyphflags="\"fl\"" colon (unum >tok %parse_glyph_flags); +# Not parsed. Ignored. +glyphextents="\""("xb"|"yb"|"w"|"h")"\"" colon (num >tok); element = glyph @ensure_glyphs | unicode @ensure_unicode @@ -99,14 +101,16 @@ element = glyph @ensure_glyphs | yoffset | xadvance | yadvance - | glyphflags; + | glyphflags + | glyphextents + ; item = - ( '{' space* element (comma element)* space* '}') + ( '{' space* element (comma element)* space* '}' space* (','|']') space* ) >clear_item @add_item ; -main := space* item (comma item)* space* (','|']'); +main := space* '['? space* item*; }%% @@ -122,11 +126,6 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - *end_ptr = ++p; - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; @@ -138,7 +137,7 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, *end_ptr = p; - return p == pe && *(p-1) != ']'; + return p == pe; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.hh b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.hh index ea81273b3..8c0353b3b 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.hh +++ b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.hh @@ -34,285 +34,342 @@ #line 36 "hb-buffer-deserialize-text-glyphs.hh" static const unsigned char _deserialize_text_glyphs_trans_keys[] = { - 0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 0 + 0u, 0u, 35u, 124u, 48u, 57u, 60u, 124u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, + 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 62u, 62u, + 93u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, + 35u, 124u, 35u, 124u, 35u, 124u, 35u, 124u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, + 44u, 44u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, 44u, 57u, 35u, 124u, 43u, 124u, + 35u, 124u, 48u, 62u, 44u, 57u, 44u, 57u, 44u, 57u, 48u, 124u, 35u, 124u, 35u, 124u, + 35u, 124u, 0 }; static const char _deserialize_text_glyphs_key_spans[] = { - 0, 10, 13, 10, 13, 10, 10, 13, - 10, 1, 13, 10, 14, 82, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116 + 0, 90, 10, 65, 13, 10, 1, 13, + 10, 1, 13, 10, 1, 13, 10, 1, + 32, 13, 10, 90, 13, 10, 90, 90, + 90, 90, 90, 90, 10, 90, 13, 10, + 1, 13, 10, 90, 90, 14, 90, 82, + 90, 15, 14, 14, 14, 77, 90, 90, + 90 }; static const short _deserialize_text_glyphs_index_offsets[] = { - 0, 0, 11, 25, 36, 50, 61, 72, - 86, 97, 99, 113, 124, 139, 222, 339, - 456, 573, 690, 807, 924, 1041, 1158, 1275, - 1392, 1509, 1626 + 0, 0, 91, 102, 168, 182, 193, 195, + 209, 220, 222, 236, 247, 249, 263, 274, + 276, 309, 323, 334, 425, 439, 450, 541, + 632, 723, 814, 905, 996, 1007, 1098, 1112, + 1123, 1125, 1139, 1150, 1241, 1332, 1347, 1438, + 1521, 1612, 1628, 1643, 1658, 1673, 1751, 1842, + 1933 }; static const char _deserialize_text_glyphs_indicies[] = { - 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 1, 3, 1, 1, 4, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 1, 6, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 1, 8, 1, 1, - 9, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 1, 11, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 1, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 1, 15, 1, 1, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 1, 18, + 1, 0, 0, 0, 0, 0, 0, + 0, 2, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 5, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 3, 11, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 12, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 12, + 3, 13, 3, 3, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 3, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 3, 16, 3, 17, 3, 3, 18, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 1, 20, 1, 21, 1, 1, 22, - 23, 23, 23, 23, 23, 23, 23, 23, - 23, 1, 24, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 1, 20, 1, 1, - 1, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 1, 26, 26, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 26, 1, - 1, 26, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 26, 26, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 26, 1, 28, - 28, 28, 28, 28, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 28, 27, - 27, 29, 27, 27, 27, 27, 27, 27, - 27, 30, 1, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 31, 27, 27, 32, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 33, 1, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 28, 27, 34, 34, 34, 34, - 34, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 34, 26, 26, 35, 26, - 26, 26, 26, 26, 26, 26, 36, 1, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 37, 26, 26, 38, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 39, - 1, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 40, - 26, 41, 41, 41, 41, 41, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 42, 1, 43, 43, - 43, 43, 43, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 44, 1, 41, 41, 41, 41, 41, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 42, 1, - 46, 46, 46, 46, 46, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 46, - 1, 1, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 48, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 49, 1, 50, 50, 50, - 50, 50, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 1, 51, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 52, 1, 50, 50, 50, 50, 50, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 50, 1, 1, 51, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 52, 1, 46, - 46, 46, 46, 46, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 1, 47, 1, 1, 1, 1, 1, 1, - 1, 1, 48, 1, 1, 1, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 49, 1, 53, 53, 53, 53, - 53, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 1, 54, 1, - 1, 1, 1, 1, 1, 1, 55, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 56, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 57, - 1, 58, 58, 58, 58, 58, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 58, 1, 1, 59, 1, 1, 1, 1, - 1, 1, 1, 60, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 61, 1, 58, 58, - 58, 58, 58, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 58, 1, 1, - 59, 1, 1, 1, 1, 1, 1, 1, - 60, 1, 1, 1, 1, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 61, 1, 53, 53, 53, 53, 53, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 53, 1, 1, 54, 1, 1, - 1, 1, 1, 1, 1, 55, 1, 1, - 1, 1, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 1, 1, 1, 1, - 1, 1, 56, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 57, 1, - 0 + 19, 3, 18, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 3, 20, 3, 21, + 3, 3, 22, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 3, 22, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 3, + 24, 3, 25, 3, 3, 26, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 3, + 26, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 3, 28, 3, 29, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 29, 3, 30, 3, + 3, 31, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 3, 33, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 3, 35, + 3, 3, 3, 3, 3, 3, 3, 3, + 36, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 37, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 38, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 38, 3, 39, 3, 3, 40, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 3, + 42, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 3, 44, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 45, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 46, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 46, 3, 44, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 3, 3, 45, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 46, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 46, + 3, 35, 3, 3, 3, 3, 3, 3, + 3, 3, 36, 3, 3, 3, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 3, 3, 37, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 38, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 38, 3, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 3, 47, 0, + 0, 48, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 0, 0, 4, 5, 0, + 0, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, + 3, 0, 0, 0, 48, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 0, 0, + 4, 5, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 5, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 3, + 52, 3, 3, 3, 3, 3, 3, 3, + 53, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 54, 3, 3, 3, 55, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 56, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 56, 3, 57, 3, 3, 58, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 3, 60, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 3, 62, 3, 63, 3, + 3, 64, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 3, 66, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 3, 68, + 3, 3, 3, 3, 3, 3, 3, 69, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 70, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 71, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 71, 3, 68, 3, 3, 3, 3, 3, + 3, 3, 69, 3, 3, 3, 3, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 3, 3, 70, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 71, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 71, 3, 62, 3, 3, + 3, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 3, 52, 3, 3, 3, + 3, 3, 3, 3, 53, 3, 3, 3, + 3, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 3, 3, 54, 3, 3, + 3, 55, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 56, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 56, 3, 0, + 0, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 0, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 0, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 16, 0, 0, 0, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 0, 0, 4, 5, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 3, + 3, 3, 3, 28, 3, 24, 3, 3, + 3, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 3, 20, 3, 3, 3, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 3, 16, 3, 3, 3, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 3, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 3, 3, 11, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 12, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 12, 3, + 75, 74, 74, 74, 74, 74, 74, 74, + 76, 3, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 77, 78, 74, 74, 79, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 80, 81, 82, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 82, 74, 84, 83, 83, 83, 83, + 83, 83, 83, 85, 3, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 86, 87, 83, 83, + 88, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 89, 90, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 90, 83, 91, 74, + 74, 74, 74, 74, 74, 74, 92, 3, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 93, + 94, 74, 74, 95, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 81, + 96, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 96, + 74, 0 }; static const char _deserialize_text_glyphs_trans_targs[] = { - 16, 0, 18, 3, 19, 22, 19, 22, - 5, 20, 21, 20, 21, 23, 26, 8, - 9, 12, 9, 12, 10, 11, 24, 25, - 24, 25, 15, 15, 14, 1, 2, 6, - 7, 13, 15, 1, 2, 6, 7, 13, - 14, 17, 14, 17, 14, 18, 17, 1, - 4, 14, 17, 1, 14, 17, 1, 2, - 7, 14, 17, 1, 2, 14, 26 + 1, 2, 17, 0, 25, 28, 30, 39, + 47, 3, 45, 4, 47, 5, 6, 44, + 7, 8, 9, 43, 10, 11, 12, 42, + 13, 14, 15, 41, 16, 47, 18, 19, + 24, 19, 24, 2, 20, 4, 47, 21, + 22, 23, 22, 23, 2, 4, 47, 26, + 27, 40, 29, 38, 2, 17, 4, 30, + 47, 31, 32, 37, 32, 37, 33, 34, + 35, 36, 35, 36, 2, 17, 4, 47, + 38, 45, 1, 2, 17, 25, 28, 30, + 48, 39, 47, 1, 2, 17, 25, 28, + 30, 39, 47, 2, 17, 25, 28, 30, + 47 }; static const char _deserialize_text_glyphs_trans_actions[] = { - 1, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 2, 1, 1, 1, - 0, 0, 0, 4, 3, 5, 5, 5, - 5, 4, 6, 7, 7, 7, 7, 0, - 6, 8, 8, 0, 0, 0, 9, 10, - 10, 9, 11, 12, 11, 13, 14, 14, - 14, 13, 15, 16, 16, 15, 0 + 0, 1, 1, 0, 1, 1, 1, 0, + 1, 2, 2, 3, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 4, 4, 4, 4, 2, + 2, 2, 0, 0, 5, 5, 5, 0, + 0, 0, 2, 2, 6, 6, 6, 6, + 6, 2, 2, 2, 0, 0, 7, 2, + 2, 2, 0, 0, 8, 8, 8, 8, + 0, 0, 9, 10, 10, 10, 10, 10, + 9, 9, 10, 12, 13, 13, 13, 13, + 13, 12, 13, 14, 14, 14, 14, 14, + 14 }; static const char _deserialize_text_glyphs_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 6, - 8, 0, 8, 9, 11, 11, 9, 13, - 15, 15, 13 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, + 0 }; -static const int deserialize_text_glyphs_start = 14; -static const int deserialize_text_glyphs_first_final = 14; +static const int deserialize_text_glyphs_start = 46; +static const int deserialize_text_glyphs_first_final = 46; static const int deserialize_text_glyphs_error = 0; -static const int deserialize_text_glyphs_en_main = 14; +static const int deserialize_text_glyphs_en_main = 46; -#line 98 "hb-buffer-deserialize-text-glyphs.rl" +#line 101 "hb-buffer-deserialize-text-glyphs.rl" static hb_bool_t @@ -322,39 +379,22 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + const char *p = buf, *pe = buf + buf_len, *eof = pe; /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, ']'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 353 "hb-buffer-deserialize-text-glyphs.hh" +#line 393 "hb-buffer-deserialize-text-glyphs.hh" { cs = deserialize_text_glyphs_start; } -#line 358 "hb-buffer-deserialize-text-glyphs.hh" +#line 398 "hb-buffer-deserialize-text-glyphs.hh" { int _slen; int _trans; @@ -379,14 +419,14 @@ _resume: goto _again; switch ( _deserialize_text_glyphs_trans_actions[_trans] ) { - case 1: -#line 51 "hb-buffer-deserialize-text-glyphs.rl" + case 2: +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; - case 7: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" + case 1: +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, @@ -395,162 +435,124 @@ _resume: return false; } break; - case 14: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" + case 6: +#line 62 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; - case 2: -#line 64 "hb-buffer-deserialize-text-glyphs.rl" + case 7: +#line 63 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 16: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" + case 8: +#line 64 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 10: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" + case 4: +#line 65 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 12: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" + case 5: +#line 66 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; - case 4: + case 3: +#line 67 "hb-buffer-deserialize-text-glyphs.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } + break; + case 9: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; - case 6: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" + case 10: +#line 38 "hb-buffer-deserialize-text-glyphs.rl" { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; + tok = p; } - break; - case 13: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } break; - case 15: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } + case 12: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } - break; - case 9: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 38 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; + hb_memset (&info, 0, sizeof (info)); + hb_memset (&pos , 0, sizeof (pos )); } - break; - case 11: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; + tok = p; } break; - case 8: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" + case 14: +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); - if (unlikely (!buffer->successful)) + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } - break; - case 5: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } -#line 55 "hb-buffer-deserialize-text-glyphs.rl" + break; + case 13: +#line 43 "hb-buffer-deserialize-text-glyphs.rl" { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) + buffer->add_info_and_pos (info, pos); + if (unlikely (!buffer->successful)) return false; + *end_ptr = p; } - break; - case 3: #line 38 "hb-buffer-deserialize-text-glyphs.rl" { hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } -#line 55 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, tok, p - tok, &info.codepoint)) return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; } break; -#line 554 "hb-buffer-deserialize-text-glyphs.hh" +#line 556 "hb-buffer-deserialize-text-glyphs.hh" } _again: @@ -562,127 +564,24 @@ _again: if ( p == eof ) { switch ( _deserialize_text_glyphs_eof_actions[cs] ) { - case 6: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 15: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 11: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" - { if (!parse_uint (tok, p, &info.mask )) return false; } -#line 43 "hb-buffer-deserialize-text-glyphs.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 3: -#line 38 "hb-buffer-deserialize-text-glyphs.rl" - { - hb_memset (&info, 0, sizeof (info)); - hb_memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text-glyphs.rl" - { - tok = p; -} -#line 55 "hb-buffer-deserialize-text-glyphs.rl" - { - /* TODO Unescape delimiters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } break; -#line 671 "hb-buffer-deserialize-text-glyphs.hh" +#line 577 "hb-buffer-deserialize-text-glyphs.hh" } } _out: {} } -#line 136 "hb-buffer-deserialize-text-glyphs.rl" - +#line 122 "hb-buffer-deserialize-text-glyphs.rl" - if (pe < orig_pe && *pe == ']') - { - pe++; - if (p == pe) - p++; - } *end_ptr = p; diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.rl b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.rl index 21db14b56..023069a30 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.rl +++ b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-glyphs.rl @@ -41,10 +41,9 @@ action clear_item { } action add_item { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } @@ -77,7 +76,9 @@ glyph = (glyph_id | glyph_name) >tok %parse_glyph; cluster = '=' (unum >tok %parse_cluster); offsets = '@' (num >tok %parse_x_offset) ',' (num >tok %parse_y_offset ); advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?; -glyphflags= '#' (unum >tok %parse_glyph_flags); +glyphflags = '#' (unum >tok %parse_glyph_flags); +# Not parsed. Ignored. +glyphextents = '<' (num ',' num ',' num ',' num) '>'; glyph_item = ( @@ -86,14 +87,16 @@ glyph_item = offsets? advances? glyphflags? + glyphextents? + ( '|' | ']') ) >clear_item %add_item ; -glyphs = glyph_item (space* '|' space* glyph_item)* space*; +glyphs = '['? glyph_item* ; -main := space* glyphs; +main := glyphs; }%% @@ -104,28 +107,11 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; + const char *p = buf, *pe = buf + buf_len, *eof = pe; /* Ensure we have positions. */ (void) hb_buffer_get_glyph_positions (buffer, nullptr); - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, ']'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; @@ -135,13 +121,6 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, write exec; }%% - if (pe < orig_pe && *pe == ']') - { - pe++; - if (p == pe) - p++; - } - *end_ptr = p; return p == pe; diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.hh b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.hh index a8cdf67e7..26ec0b422 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.hh +++ b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.hh @@ -34,135 +34,106 @@ #line 36 "hb-buffer-deserialize-text-unicode.hh" static const unsigned char _deserialize_text_unicode_trans_keys[] = { - 0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 0 + 0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u, + 85u, 117u, 85u, 117u, 0 }; static const char _deserialize_text_unicode_key_spans[] = { - 0, 109, 60, 55, 10, 116, 116, 116, - 116 + 0, 60, 55, 77, 10, 63, 77, 58, + 33, 33 }; static const short _deserialize_text_unicode_index_offsets[] = { - 0, 0, 110, 171, 227, 238, 355, 472, - 589 + 0, 0, 61, 117, 195, 206, 270, 348, + 407, 441 }; static const char _deserialize_text_unicode_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, + 0, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 4, 5, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 5, 1, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 3, - 1, 1, 1, 1, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 1, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 1, 7, - 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 7, 1, + 1, 1, 1, 1, 1, 8, 1, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 1, 1, 1, 9, 1, 1, 1, 8, - 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, - 8, 8, 8, 8, 8, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 10, 1, 11, 11, 11, 11, - 11, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 11, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 12, 12, 12, 12, 12, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 12, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 8, 1, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 12, 12, - 12, 12, 12, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 12, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 11, 1, + 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 13, 1, 0 + 1, 1, 12, 1, 0 }; static const char _deserialize_text_unicode_trans_targs[] = { - 1, 0, 2, 3, 5, 7, 8, 6, - 5, 4, 1, 6, 6, 1, 8 + 2, 0, 3, 3, 4, 9, 5, 6, + 9, 6, 8, 1, 1 }; static const char _deserialize_text_unicode_trans_actions[] = { - 0, 0, 1, 0, 2, 2, 2, 3, - 0, 4, 3, 0, 5, 5, 0 + 0, 0, 1, 0, 2, 2, 1, 1, + 3, 0, 0, 4, 6 }; static const char _deserialize_text_unicode_eof_actions[] = { - 0, 0, 0, 0, 0, 3, 0, 5, - 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5 }; -static const int deserialize_text_unicode_start = 1; -static const int deserialize_text_unicode_first_final = 5; +static const int deserialize_text_unicode_start = 7; +static const int deserialize_text_unicode_first_final = 7; static const int deserialize_text_unicode_error = 0; -static const int deserialize_text_unicode_en_main = 1; +static const int deserialize_text_unicode_en_main = 7; -#line 79 "hb-buffer-deserialize-text-unicode.rl" +#line 80 "hb-buffer-deserialize-text-unicode.rl" static hb_bool_t @@ -172,37 +143,19 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '<')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, '>'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - + const char *p = buf, *pe = buf + buf_len, *eof = pe; const char *tok = nullptr; int cs; hb_glyph_info_t info = {0}; const hb_glyph_position_t pos = {0}; -#line 201 "hb-buffer-deserialize-text-unicode.hh" +#line 154 "hb-buffer-deserialize-text-unicode.hh" { cs = deserialize_text_unicode_start; } -#line 206 "hb-buffer-deserialize-text-unicode.hh" +#line 159 "hb-buffer-deserialize-text-unicode.hh" { int _slen; int _trans; @@ -227,38 +180,27 @@ _resume: goto _again; switch ( _deserialize_text_unicode_trans_actions[_trans] ) { - case 1: + case 4: #line 38 "hb-buffer-deserialize-text-unicode.rl" { hb_memset (&info, 0, sizeof (info)); } break; - case 2: + case 1: #line 51 "hb-buffer-deserialize-text-unicode.rl" { tok = p; } break; - case 4: + case 2: #line 55 "hb-buffer-deserialize-text-unicode.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } break; case 3: -#line 55 "hb-buffer-deserialize-text-unicode.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 42 "hb-buffer-deserialize-text-unicode.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - if (buffer->have_positions) - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 5: #line 57 "hb-buffer-deserialize-text-unicode.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 6: #line 42 "hb-buffer-deserialize-text-unicode.rl" { buffer->add_info (info); @@ -267,9 +209,13 @@ _resume: if (buffer->have_positions) buffer->pos[buffer->len - 1] = pos; *end_ptr = p; +} +#line 38 "hb-buffer-deserialize-text-unicode.rl" + { + hb_memset (&info, 0, sizeof (info)); } break; -#line 273 "hb-buffer-deserialize-text-unicode.hh" +#line 219 "hb-buffer-deserialize-text-unicode.hh" } _again: @@ -281,22 +227,7 @@ _again: if ( p == eof ) { switch ( _deserialize_text_unicode_eof_actions[cs] ) { - case 3: -#line 55 "hb-buffer-deserialize-text-unicode.rl" - {if (!parse_hex (tok, p, &info.codepoint )) return false; } -#line 42 "hb-buffer-deserialize-text-unicode.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - if (buffer->have_positions) - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; case 5: -#line 57 "hb-buffer-deserialize-text-unicode.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } #line 42 "hb-buffer-deserialize-text-unicode.rl" { buffer->add_info (info); @@ -307,22 +238,15 @@ _again: *end_ptr = p; } break; -#line 311 "hb-buffer-deserialize-text-unicode.hh" +#line 242 "hb-buffer-deserialize-text-unicode.hh" } } _out: {} } -#line 115 "hb-buffer-deserialize-text-unicode.rl" - +#line 98 "hb-buffer-deserialize-text-unicode.rl" - if (pe < orig_pe && *pe == '>') - { - pe++; - if (p == pe) - p++; - } *end_ptr = p; diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.rl b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.rl index 92873b804..1e123c8b2 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.rl +++ b/thirdparty/harfbuzz/upstream/hb-buffer-deserialize-text-unicode.rl @@ -67,14 +67,15 @@ unicode_item = ( unicode cluster? + ('|' | '>') ) >clear_item %add_item ; -unicodes = unicode_item (space* '|' space* unicode_item)* space*; +unicodes = '<'? unicode_item*; -main := space* unicodes; +main := unicodes; }%% @@ -85,25 +86,7 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, const char **end_ptr, hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe; - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '<')) - *end_ptr = ++p; - - const char *end = strchr ((char *) p, '>'); - if (end) - pe = eof = end; - else - { - end = strrchr ((char *) p, '|'); - if (end) - pe = eof = end; - else - pe = eof = p; - } - + const char *p = buf, *pe = buf + buf_len, *eof = pe; const char *tok = nullptr; int cs; @@ -114,13 +97,6 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, write exec; }%% - if (pe < orig_pe && *pe == '>') - { - pe++; - if (p == pe) - p++; - } - *end_ptr = p; return p == pe; diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-serialize.cc b/thirdparty/harfbuzz/upstream/hb-buffer-serialize.cc index 16f189519..923524d70 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-serialize.cc +++ b/thirdparty/harfbuzz/upstream/hb-buffer-serialize.cc @@ -114,6 +114,17 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, *buf_consumed = 0; hb_position_t x = 0, y = 0; + + /* Calculate the advance of the previous glyphs */ + if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) + { + for (unsigned int i = 0; i < start; i++) + { + x += pos[i].x_advance; + y += pos[i].y_advance; + } + } + for (unsigned int i = start; i < end; i++) { char b[1024]; @@ -151,7 +162,7 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster)); } - if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) + if (pos && !(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", x+pos[i].x_offset, y+pos[i].y_offset)); @@ -169,11 +180,13 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; - hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", - extents.x_bearing, extents.y_bearing)); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", - extents.width, extents.height)); + if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents)) + { + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", + extents.x_bearing, extents.y_bearing)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", + extents.width, extents.height)); + } } *p++ = '}'; @@ -270,6 +283,17 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, *buf_consumed = 0; hb_position_t x = 0, y = 0; + + /* Calculate the advance of the previous glyphs */ + if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) + { + for (unsigned int i = 0; i < start; i++) + { + x += pos[i].x_advance; + y += pos[i].y_advance; + } + } + for (unsigned int i = start; i < end; i++) { char b[1024]; @@ -295,7 +319,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster)); } - if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) + if (pos && !(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { if (x+pos[i].x_offset || y+pos[i].y_offset) p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); @@ -318,8 +342,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; - hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); + if (hb_font_get_glyph_extents(font, info[i].codepoint, &extents)) + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); } if (i == end-1) { @@ -415,9 +439,9 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * A human-readable, plain text format. * The serialized glyphs will look something like: * - * ``` + * |[ * [uni0651=0@518,0+0|uni0628=0+1897] - * ``` + * ]| * * - The serialized glyphs are delimited with `[` and `]`. * - Glyphs are separated with `|` @@ -425,7 +449,7 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then, * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster. * - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format: - * - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then, + * - If #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not both 0, `@x_offset,y_offset`. Then, * - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then, * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the #hb_glyph_extents_t in the format `` * @@ -433,10 +457,10 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * A machine-readable, structured format. * The serialized glyphs will look something like: * - * ``` + * |[ * [{"g":"uni0651","cl":0,"dx":518,"dy":0,"ax":0,"ay":0}, - * {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}] - * ``` + * {"g":"uni0628","cl":0,"dx":0,"dy":0,"ax":1897,"ay":0}] + * ]| * * Each glyph is a JSON object, with the following properties: * - `g`: the glyph name or glyph index if @@ -528,9 +552,9 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, * A human-readable, plain text format. * The serialized codepoints will look something like: * - * ``` + * |[ *   - * ``` + * ]| * * - Glyphs are separated with `|` * - Unicode codepoints are expressed as zero-padded four (or more) @@ -548,9 +572,9 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, * * For example: * - * ``` + * |[ * [{u:1617,cl:0},{u:1576,cl:1}] - * ``` + * ]| * * Return value: * The number of serialized items. @@ -737,8 +761,7 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) * Deserializes glyphs @buffer from textual representation in the format * produced by hb_buffer_serialize_glyphs(). * - * Return value: `true` if parse was successful, `false` if an error - * occurred. + * Return value: `true` if the full string was parsed, `false` otherwise. * * Since: 0.9.7 **/ @@ -810,8 +833,7 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, * Deserializes Unicode @buffer from textual representation in the format * produced by hb_buffer_serialize_unicode(). * - * Return value: `true` if parse was successful, `false` if an error - * occurred. + * Return value: `true` if the full string was parsed, `false` otherwise. * * Since: 2.7.3 **/ diff --git a/thirdparty/harfbuzz/upstream/hb-buffer-verify.cc b/thirdparty/harfbuzz/upstream/hb-buffer-verify.cc index 345f08d26..e1ccd5b94 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer-verify.cc +++ b/thirdparty/harfbuzz/upstream/hb-buffer-verify.cc @@ -63,23 +63,24 @@ static bool buffer_verify_monotone (hb_buffer_t *buffer, hb_font_t *font) { - /* Check that clusters are monotone. */ - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES || - buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { - bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); + /* Cannot perform this check without monotone clusters. */ + return true; + } - unsigned int num_glyphs; - hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); - for (unsigned int i = 1; i < num_glyphs; i++) - if (info[i-1].cluster != info[i].cluster && - (info[i-1].cluster < info[i].cluster) != is_forward) - { - buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone."); - return false; - } - } + unsigned int num_glyphs; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + + for (unsigned int i = 1; i < num_glyphs; i++) + if (info[i-1].cluster != info[i].cluster && + (info[i-1].cluster < info[i].cluster) != is_forward) + { + buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "clusters are not monotone."); + return false; + } return true; } @@ -92,8 +93,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, unsigned int num_features, const char * const *shapers) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { /* Cannot perform this check without monotone clusters. */ return true; @@ -163,7 +163,7 @@ buffer_verify_unsafe_to_break (hb_buffer_t *buffer, hb_buffer_append (fragment, text_buffer, text_start, text_end); if (!hb_shape_full (font, fragment, features, num_features, shapers) || - fragment->successful || fragment->shaping_failed) + fragment->successful) { hb_buffer_destroy (reconstruction); hb_buffer_destroy (fragment); @@ -207,8 +207,7 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, unsigned int num_features, const char * const *shapers) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { /* Cannot perform this check without monotone clusters. */ return true; @@ -314,11 +313,11 @@ buffer_verify_unsafe_to_concat (hb_buffer_t *buffer, * Shape the two fragment streams. */ if (!hb_shape_full (font, fragments[0], features, num_features, shapers) || - !fragments[0]->successful || fragments[0]->shaping_failed) + !fragments[0]->successful) goto out; if (!hb_shape_full (font, fragments[1], features, num_features, shapers) || - !fragments[1]->successful || fragments[1]->shaping_failed) + !fragments[1]->successful) goto out; if (!forward) diff --git a/thirdparty/harfbuzz/upstream/hb-buffer.cc b/thirdparty/harfbuzz/upstream/hb-buffer.cc index 6c98d8217..4bbe0ad4f 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer.cc +++ b/thirdparty/harfbuzz/upstream/hb-buffer.cc @@ -158,14 +158,15 @@ hb_segment_properties_overlay (hb_segment_properties_t *p, bool hb_buffer_t::enlarge (unsigned int size) { - if (unlikely (!successful)) - return false; if (unlikely (size > max_len)) { successful = false; return false; } + if (unlikely (!successful)) + return false; + unsigned int new_allocated = allocated; hb_glyph_position_t *new_pos = nullptr; hb_glyph_info_t *new_info = nullptr; @@ -226,6 +227,13 @@ hb_buffer_t::shift_forward (unsigned int count) assert (have_output); if (unlikely (!ensure (len + count))) return false; + max_ops -= len - idx; + if (unlikely (max_ops < 0)) + { + successful = false; + return false; + } + memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0])); if (idx + count > len) { @@ -297,7 +305,6 @@ hb_buffer_t::clear () props = default_props; successful = true; - shaping_failed = false; have_output = false; have_positions = false; @@ -320,7 +327,6 @@ hb_buffer_t::enter () { deallocate_var_all (); serial = 0; - shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; unsigned mul; if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR, &mul))) @@ -339,7 +345,6 @@ hb_buffer_t::leave () max_ops = HB_BUFFER_MAX_OPS_DEFAULT; deallocate_var_all (); serial = 0; - // Intentionally not reseting shaping_failed, such that it can be inspected. } @@ -370,6 +375,18 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) len++; } +void +hb_buffer_t::add_info_and_pos (const hb_glyph_info_t &glyph_info, + const hb_glyph_position_t &glyph_pos) +{ + if (unlikely (!ensure (len + 1))) return; + + info[len] = glyph_info; + assert (have_positions); + pos[len] = glyph_pos; + + len++; +} void @@ -508,7 +525,19 @@ hb_buffer_t::set_masks (hb_mask_t value, hb_mask_t not_mask = ~mask; value &= mask; + max_ops -= len; + if (unlikely (max_ops < 0)) + successful = false; + unsigned int count = len; + + if (cluster_start == 0 && cluster_end == (unsigned int) -1) + { + for (unsigned int i = 0; i < count; i++) + info[i].mask = (info[i].mask & not_mask) | value; + return; + } + for (unsigned int i = 0; i < count; i++) if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end) info[i].mask = (info[i].mask & not_mask) | value; @@ -518,11 +547,9 @@ void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { - if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) - { - unsafe_to_break (start, end); - return; - } + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; unsigned int cluster = info[start].cluster; @@ -548,14 +575,12 @@ hb_buffer_t::merge_clusters_impl (unsigned int start, set_cluster (info[i], cluster); } void -hb_buffer_t::merge_out_clusters (unsigned int start, - unsigned int end) +hb_buffer_t::merge_out_clusters_impl (unsigned int start, + unsigned int end) { - if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) - return; - - if (unlikely (end - start < 2)) - return; + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; unsigned int cluster = out_info[start].cluster; @@ -714,7 +739,6 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_SEGMENT_PROPERTIES_DEFAULT, false, /* successful */ - true, /* shaping_failed */ false, /* have_output */ true /* have_positions */ @@ -860,7 +884,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the specified buffer. + * Attaches a user-data key/data pair to the specified buffer. * * Return value: `true` if success, `false` otherwise * @@ -936,6 +960,9 @@ void hb_buffer_set_content_type (hb_buffer_t *buffer, hb_buffer_content_type_t content_type) { + if (unlikely (hb_object_is_immutable (buffer))) + return; + buffer->content_type = content_type; } @@ -1209,7 +1236,7 @@ hb_buffer_get_flags (const hb_buffer_t *buffer) * @cluster_level: The cluster level to set on the buffer * * Sets the cluster level of a buffer. The #hb_buffer_cluster_level_t - * dictates one aspect of how HarfBuzz will treat non-base characters + * dictates one aspect of how HarfBuzz will treat non-base characters * during shaping. * * Since: 0.9.42 @@ -1229,7 +1256,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * * Fetches the cluster level of a buffer. The #hb_buffer_cluster_level_t - * dictates one aspect of how HarfBuzz will treat non-base characters + * dictates one aspect of how HarfBuzz will treat non-base characters * during shaping. * * Return value: The cluster level of @buffer @@ -1985,7 +2012,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @source: source #hb_buffer_t * @start: start index into source buffer to copy. Use 0 to copy from start of buffer. - * @end: end index into source buffer to copy. Use @HB_FEATURE_GLOBAL_END to copy to end of buffer. + * @end: end index into source buffer to copy. Use @UINT_MAX (or ((unsigned int) -1)) to copy to end of buffer. * * Append (part of) contents of another buffer to this buffer. * @@ -2256,6 +2283,22 @@ hb_buffer_diff (hb_buffer_t *buffer, * Debugging. */ +void +hb_buffer_t::changed () +{ +#ifdef HB_NO_BUFFER_MESSAGE + return; +#else + if (!message_depth) + return; + + if (changed_func) + changed_func (this, changed_data); + else + update_digest (); +#endif +} + #ifndef HB_NO_BUFFER_MESSAGE /** * hb_buffer_set_message_func: @@ -2273,7 +2316,8 @@ hb_buffer_set_message_func (hb_buffer_t *buffer, hb_buffer_message_func_t func, void *user_data, hb_destroy_func_t destroy) { - if (unlikely (hb_object_is_immutable (buffer))) + if (unlikely (hb_object_is_immutable (buffer)) || + unlikely (buffer->message_depth)) { if (destroy) destroy (user_data); @@ -2293,6 +2337,23 @@ hb_buffer_set_message_func (hb_buffer_t *buffer, buffer->message_destroy = nullptr; } } +/** + * hb_buffer_changed: + * @buffer: An #hb_buffer_t + * + * Called by a message callback after modifying buffer glyph indices, + * to update internal caches. + * + * If not called from inside a message callback, does nothing. + * + * Since: 13.0.0 + **/ +void +hb_buffer_changed (hb_buffer_t *buffer) +{ + buffer->changed (); +} + bool hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) { diff --git a/thirdparty/harfbuzz/upstream/hb-buffer.h b/thirdparty/harfbuzz/upstream/hb-buffer.h index 8f2e264fe..f775d523f 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer.h +++ b/thirdparty/harfbuzz/upstream/hb-buffer.h @@ -424,18 +424,34 @@ hb_buffer_get_flags (const hb_buffer_t *buffer); * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values. * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level, * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. - * + * @HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES: Only group clusters, but don't enforce monotone order. + * * Data type for holding HarfBuzz's clustering behavior options. The cluster level - * dictates one aspect of how HarfBuzz will treat non-base characters + * dictates one aspect of how HarfBuzz will treat non-base characters * during shaping. * * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES, non-base * characters are merged into the cluster of the base character that precedes them. + * There is also cluster merging every time the clusters will otherwise become non-monotone. * * In @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, non-base characters are initially * assigned their own cluster values, which are not merged into preceding base * clusters. This allows HarfBuzz to perform additional operations like reorder - * sequences of adjacent marks. + * sequences of adjacent marks. The output is still monotone, but the cluster + * values are more granular. + * + * In @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS, non-base characters are assigned their + * own cluster values, which are not merged into preceding base clusters. Moreover, + * the cluster values are not merged into monotone order. This is the most granular + * cluster level, and it is useful for clients that need to know the exact cluster + * values of each character, but is harder to use for clients, since clusters + * might appear in any order. + * + * In @HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES, non-base characters are merged into the + * cluster of the base character that precedes them. This is similar to the Unicode + * Grapheme Cluster algorithm, but it is not exactly the same. The output is + * not forced to be monotone. This is useful for clients that want to use HarfBuzz + * as a cheap implementation of the Unicode Grapheme Cluster algorithm. * * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES is the default, because it maintains * backward compatibility with older versions of HarfBuzz. New client programs that @@ -448,9 +464,52 @@ typedef enum { HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES = 3, HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES } hb_buffer_cluster_level_t; +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level groups cluster values into monotone order. + * Requires that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)))) + +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level groups cluster values by graphemes. Requires + * that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES)))) + +/** + * HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS: + * @level: #hb_buffer_cluster_level_t to test + * + * Tests whether a cluster level does not group cluster values by graphemes. + * Requires that the level be valid. + * + * Since: 11.0.0 + */ +#define HB_BUFFER_CLUSTER_LEVEL_IS_CHARACTERS(level) \ + ((bool) ((1u << (unsigned) (level)) & \ + ((1u << HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) | \ + (1u << HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)))) + HB_EXTERN void hb_buffer_set_cluster_level (hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level); @@ -615,7 +674,12 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents. * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0 * @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances, - * glyph offsets will reflect absolute glyph positions. Since: 1.8.0 + * glyph offsets will reflect absolute glyph positions. Since: 1.8.0. + * Note: when this flag is used with a partial range of the buffer (i.e. + * @start is not 0), calculating the absolute positions has a cost + * proportional to @start. If the buffer is serialized in many small + * chunks, this can lead to quadratic behavior. It is recommended to + * use a larger @buf_size to minimize this cost. * @HB_BUFFER_SERIALIZE_FLAG_DEFINED: All currently defined flags. Since: 4.4.0 * * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs(). @@ -808,6 +872,9 @@ hb_buffer_set_message_func (hb_buffer_t *buffer, hb_buffer_message_func_t func, void *user_data, hb_destroy_func_t destroy); +HB_EXTERN void +hb_buffer_changed (hb_buffer_t *buffer); + HB_END_DECLS diff --git a/thirdparty/harfbuzz/upstream/hb-buffer.hh b/thirdparty/harfbuzz/upstream/hb-buffer.hh index 2a6ad6128..770beeee3 100644 --- a/thirdparty/harfbuzz/upstream/hb-buffer.hh +++ b/thirdparty/harfbuzz/upstream/hb-buffer.hh @@ -45,14 +45,14 @@ HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t); enum hb_buffer_scratch_flags_t { HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, - HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, + HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH = 0x00000001u, HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u, - HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u, - HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000040u, - HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000080u, + HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE = 0x00000020u, + HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK= 0x00000040u, + HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS = 0x00000080u, /* Reserved for shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_SHAPER0 = 0x01000000u, @@ -91,7 +91,6 @@ struct hb_buffer_t hb_segment_properties_t props; /* Script, language, direction */ bool successful; /* Allocations successful */ - bool shaping_failed; /* Shaping failure */ bool have_output; /* Whether we have an output buffer going on */ bool have_positions; /* Whether we have positions */ @@ -111,6 +110,7 @@ struct hb_buffer_t hb_codepoint_t context[2][CONTEXT_LENGTH]; unsigned int context_len[2]; + hb_set_digest_t digest; /* Manually updated sometimes */ /* * Managed by enter / leave @@ -130,9 +130,13 @@ struct hb_buffer_t */ #ifndef HB_NO_BUFFER_MESSAGE + typedef void (*changed_func_t) (hb_buffer_t *buffer, void *user_data); + hb_buffer_message_func_t message_func; void *message_data; hb_destroy_func_t message_destroy; + changed_func_t changed_func; + void *changed_data; unsigned message_depth; /* How deeply are we inside a message callback? */ #else static constexpr unsigned message_depth = 0u; @@ -182,21 +186,29 @@ struct hb_buffer_t allocated_var_bits = 0; } + HB_ALWAYS_INLINE hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; } + HB_ALWAYS_INLINE hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } + HB_ALWAYS_INLINE hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } - hb_set_digest_t digest () const + template + void collect_codepoints (set_t &d) const + { d.clear (); d.add_array (&info[0].codepoint, len, sizeof (info[0])); } + + void update_digest () { - hb_set_digest_t d; - d.init (); - d.add_array (&info[0].codepoint, len, sizeof (info[0])); - return d; + digest = hb_set_digest_t (); + collect_codepoints (digest); } HB_INTERNAL void similar (const hb_buffer_t &src); @@ -228,6 +240,8 @@ struct hb_buffer_t HB_INTERNAL void add (hb_codepoint_t codepoint, unsigned int cluster); HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info); + HB_INTERNAL void add_info_and_pos (const hb_glyph_info_t &glyph_info, + const hb_glyph_position_t &glyph_pos); void reverse_range (unsigned start, unsigned end) { @@ -343,7 +357,7 @@ struct hb_buffer_t { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (1, 1))) return false; + if (unlikely (!ensure (out_len + 1))) return false; out_info[out_len] = info[idx]; } out_len++; @@ -360,7 +374,7 @@ struct hb_buffer_t { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (n, n))) return false; + if (unlikely (!ensure (out_len + n))) return false; memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); } out_len += n; @@ -388,10 +402,42 @@ struct hb_buffer_t { if (end - start < 2) return; + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (cluster_level)) + { + unsafe_to_break (start, end); + return; + } + merge_clusters_impl (start, end); + } + void merge_grapheme_clusters (unsigned int start, unsigned int end) + { + if (end - start < 2) + return; + if (!HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (cluster_level)) + { + unsafe_to_break (start, end); + return; + } merge_clusters_impl (start, end); } HB_INTERNAL void merge_clusters_impl (unsigned int start, unsigned int end); - HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); + void merge_out_clusters (unsigned int start, unsigned int end) + { + if (end - start < 2) + return; + if (!HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (cluster_level)) + return; + merge_out_clusters_impl (start, end); + } + void merge_out_grapheme_clusters (unsigned int start, unsigned int end) + { + if (end - start < 2) + return; + if (!HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (cluster_level)) + return; + merge_out_clusters_impl (start, end); + } + HB_INTERNAL void merge_out_clusters_impl (unsigned int start, unsigned int end); /* Merge clusters for deleting current glyph, and skip it. */ HB_INTERNAL void delete_glyph (); HB_INTERNAL void delete_glyphs_inplace (bool (*filter) (const hb_glyph_info_t *info)); @@ -401,19 +447,12 @@ struct hb_buffer_t /* Adds glyph flags in mask to infos with clusters between start and end. * The start index will be from out-buffer if from_out_buffer is true. * If interior is true, then the cluster having the minimum value is skipped. */ - void _set_glyph_flags (hb_mask_t mask, - unsigned start = 0, - unsigned end = (unsigned) -1, - bool interior = false, - bool from_out_buffer = false) + void _set_glyph_flags_impl (hb_mask_t mask, + unsigned start, + unsigned end, + bool interior, + bool from_out_buffer) { - end = hb_min (end, len); - - if (interior && !from_out_buffer && end - start < 2) - return; - - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; - if (!from_out_buffer || !have_output) { if (!interior) @@ -450,6 +489,25 @@ struct hb_buffer_t } } + HB_ALWAYS_INLINE + void _set_glyph_flags (hb_mask_t mask, + unsigned start = 0, + unsigned end = (unsigned) -1, + bool interior = false, + bool from_out_buffer = false) + { + if (unlikely (end != (unsigned) -1 && end - start > 255)) + return; + + end = hb_min (end, len); + + if (interior && !from_out_buffer && end - start < 2) + return; + + _set_glyph_flags_impl (mask, start, end, interior, from_out_buffer); + } + + void unsafe_to_break (unsigned int start = 0, unsigned int end = -1) { _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, @@ -583,6 +641,7 @@ struct hb_buffer_t #endif } HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0); + HB_INTERNAL void changed (); static void set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0) @@ -600,6 +659,10 @@ struct hb_buffer_t if (unlikely (start == end)) return; + max_ops -= end - start; + if (unlikely (max_ops < 0)) + successful = false; + unsigned cluster_first = infos[start].cluster; unsigned cluster_last = infos[end - 1].cluster; @@ -608,10 +671,7 @@ struct hb_buffer_t { for (unsigned int i = start; i < end; i++) if (cluster != infos[i].cluster) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; - } return; } @@ -620,18 +680,12 @@ struct hb_buffer_t if (cluster == cluster_first) { for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i - 1].mask |= mask; - } } else /* cluster == cluster_last */ { for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++) - { - scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS; infos[i].mask |= mask; - } } } unsigned diff --git a/thirdparty/harfbuzz/upstream/hb-cache.hh b/thirdparty/harfbuzz/upstream/hb-cache.hh index 6d8a54cf1..7600f134f 100644 --- a/thirdparty/harfbuzz/upstream/hb-cache.hh +++ b/thirdparty/harfbuzz/upstream/hb-cache.hh @@ -30,18 +30,31 @@ #include "hb.hh" -/* Implements a lockfree cache for int->int functions. +/* Implements a lockfree and thread-safe cache for int->int functions, + * using (optionally) _relaxed_ atomic integer operations. * - * The cache is a fixed-size array of 16-bit or 32-bit integers. - * The key is split into two parts: the cache index and the rest. + * The cache is a fixed-size array of 16-bit or 32-bit integers, + * typically 256 elements. * - * The cache index is used to index into the array. The rest is used - * to store the key and the value. + * The key is split into two parts: the cache index (high bits) + * and the rest (low bits). + * + * The cache index is used to index into the array. The array + * member is a 16-bit or 32-bit integer that is used *both* + * to store the low bits of the key, and the value. * * The value is stored in the least significant bits of the integer. - * The key is stored in the most significant bits of the integer. - * The key is shifted by cache_bits to the left to make room for the - * value. + * The low bits of the key are stored in the most significant bits + * of the integer. + * + * A cache hit is detected by comparing the low bits of the key + * with the high bits of the integer at the array position indexed + * by the high bits of the key. If they match, the value is extracted + * from the least significant bits of the integer and returned. + * Otherwise, a cache miss is reported. + * + * Cache operations (storage and retrieval) involve just a few + * arithmetic operations and a single memory access. */ template ::type, - typename std::conditional::type + typename std::conditional, + typename std::conditional, + hb_atomic_t>::type>::type, + typename std::conditional::type>::type >::type; static_assert ((key_bits >= cache_bits), ""); static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), ""); + static constexpr unsigned MAX_VALUE = (1u << value_bits) - 1; + hb_cache_t () { clear (); } void clear () @@ -70,25 +89,32 @@ struct hb_cache_t v = -1; } + HB_HOT bool get (unsigned int key, unsigned int *value) const { unsigned int k = key & ((1u<> value_bits) != (key >> cache_bits)) return false; *value = v & ((1u<> key_bits) || (value >> value_bits))) - return false; /* Overflows */ + return; /* Overflows */ + set_unchecked (key, value); + } + + HB_HOT + void set_unchecked (unsigned int key, unsigned int value) + { unsigned int k = key & ((1u<>cache_bits)< - /* Some routines in this file were ported from BlackRenderer by Black Foundry. * Used by permission to relicense to HarfBuzz license. * @@ -101,7 +99,7 @@ _hb_cairo_paint_glyph_image (hb_cairo_context_t *c, unsigned width, unsigned height, hb_tag_t format, - float slant, + HB_UNUSED float slant_deprecated, hb_glyph_extents_t *extents) { cairo_t *cr = c->cr; @@ -186,12 +184,6 @@ _hb_cairo_paint_glyph_image (hb_cairo_context_t *c, cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0}; cairo_pattern_set_matrix (pattern, &matrix); - /* Undo slant in the extents and apply it in the context. */ - extents->width -= extents->height * slant; - extents->x_bearing -= extents->y_bearing * slant; - cairo_matrix_t cairo_matrix = {1., 0., (double) slant, 1., 0., 0.}; - cairo_transform (cr, &cairo_matrix); - cairo_translate (cr, extents->x_bearing, extents->y_bearing); cairo_scale (cr, extents->width, extents->height); cairo_set_source (cr, pattern); @@ -726,6 +718,9 @@ _hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops, float span; span = angles[n_stops - 1] - angles[0]; + if (!span) + goto done; + k = 0; if (angles[0] >= 0) { diff --git a/thirdparty/harfbuzz/upstream/hb-cairo.cc b/thirdparty/harfbuzz/upstream/hb-cairo.cc index d8b582c49..23ebd6bfc 100644 --- a/thirdparty/harfbuzz/upstream/hb-cairo.cc +++ b/thirdparty/harfbuzz/upstream/hb-cairo.cc @@ -180,7 +180,7 @@ hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, hb_position_t x_scale, y_scale; hb_font_get_scale (font, &x_scale, &y_scale); - cairo_scale (cr, x_scale, y_scale); + cairo_scale (cr, x_scale, -y_scale); cairo_glyph_t cairo_glyph = { glyph, 0, 0 }; cairo_set_scaled_font (cr, c->scaled_font); @@ -204,7 +204,9 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, cairo_save (cr); cairo_new_path (cr); + hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr); + cairo_close_path (cr); cairo_clip (cr); } @@ -572,9 +574,12 @@ hb_cairo_text_to_glyphs (cairo_scaled_font_t *scaled_font, hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, nullptr, 0); + int x_scale, y_scale; + hb_font_get_scale (font, &x_scale, &y_scale); + hb_cairo_glyphs_from_buffer (buffer, true, - font->x_scale, font->y_scale, + x_scale, y_scale, 0., 0., utf8, utf8_len, glyphs, (unsigned *) num_glyphs, @@ -597,12 +602,15 @@ hb_cairo_render_glyph (cairo_scaled_font_t *scaled_font, hb_position_t x_scale, y_scale; hb_font_get_scale (font, &x_scale, &y_scale); - cairo_scale (cr, +1./x_scale, -1./y_scale); - hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr); - - cairo_fill (cr); + cairo_scale (cr, + +1. / (x_scale ? x_scale : 1), + -1. / (y_scale ? y_scale : 1)); + if (hb_font_draw_glyph_or_fail (font, glyph, hb_cairo_draw_get_funcs (), cr)) + cairo_fill (cr); + // If draw fails, we still return SUCCESS, as we want empty drawing, not + // setting the cairo object into error. return CAIRO_STATUS_SUCCESS; } @@ -628,15 +636,17 @@ hb_cairo_render_color_glyph (cairo_scaled_font_t *scaled_font, hb_color_t color = HB_COLOR (0, 0, 0, 255); hb_position_t x_scale, y_scale; hb_font_get_scale (font, &x_scale, &y_scale); - cairo_scale (cr, +1./x_scale, -1./y_scale); + cairo_scale (cr, + +1. / (x_scale ? x_scale : 1), + -1. / (y_scale ? y_scale : 1)); hb_cairo_context_t c; c.scaled_font = scaled_font; c.cr = cr; c.color_cache = (hb_map_t *) cairo_scaled_font_get_user_data (scaled_font, &color_cache_key); - hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color); - + if (!hb_font_paint_glyph_or_fail (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color)) + return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; return CAIRO_STATUS_SUCCESS; } @@ -653,8 +663,7 @@ user_font_face_create (hb_face_t *face) cairo_user_font_face_set_text_to_glyphs_func (cairo_face, hb_cairo_text_to_glyphs); cairo_user_font_face_set_render_glyph_func (cairo_face, hb_cairo_render_glyph); #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC - if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face)) - cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph); + cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph); #endif if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face, @@ -685,7 +694,8 @@ hb_cairo_font_face_create_for_font (hb_font_t *font) { hb_font_make_immutable (font); - auto *cairo_face = user_font_face_create (font->face); + auto *hb_face = hb_font_get_face (font); + auto *cairo_face = user_font_face_create (hb_face); if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face, &hb_cairo_font_user_data_key, @@ -872,7 +882,6 @@ hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face) &hb_cairo_scale_factor_user_data_key); } - /** * hb_cairo_glyphs_from_buffer: * @buffer: a #hb_buffer_t containing glyphs @@ -1000,6 +1009,7 @@ hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer, end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster; else end = (const char *) hb_utf_offset_to_pointer ((const uint8_t *) start, + (const uint8_t *) utf8, utf8_len, (signed) (hb_glyph[i].cluster - hb_glyph[i+1].cluster)); (*clusters)[cluster].num_bytes = end - start; start = end; @@ -1020,6 +1030,7 @@ hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer, end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster; else end = (const char *) hb_utf_offset_to_pointer ((const uint8_t *) start, + (const uint8_t *) utf8, utf8_len, (signed) (hb_glyph[i].cluster - hb_glyph[i-1].cluster)); (*clusters)[cluster].num_bytes = end - start; start = end; diff --git a/thirdparty/harfbuzz/upstream/hb-cff-interp-common.hh b/thirdparty/harfbuzz/upstream/hb-cff-interp-common.hh index 6ca7500af..df90fb99a 100644 --- a/thirdparty/harfbuzz/upstream/hb-cff-interp-common.hh +++ b/thirdparty/harfbuzz/upstream/hb-cff-interp-common.hh @@ -344,25 +344,25 @@ struct cff_stack_t { ELEM& operator [] (unsigned int i) { - if (unlikely (i >= count)) + if (unlikely (i >= length)) { set_error (); return Crap (ELEM); } - return elements[i]; + return arrayZ[i]; } void push (const ELEM &v) { - if (likely (count < LIMIT)) - elements[count++] = v; + if (likely (length < LIMIT)) + arrayZ[length++] = v; else set_error (); } ELEM &push () { - if (likely (count < LIMIT)) - return elements[count++]; + if (likely (length < LIMIT)) + return arrayZ[length++]; else { set_error (); @@ -372,8 +372,8 @@ struct cff_stack_t ELEM& pop () { - if (likely (count > 0)) - return elements[--count]; + if (likely (length > 0)) + return arrayZ[--length]; else { set_error (); @@ -382,45 +382,44 @@ struct cff_stack_t } void pop (unsigned int n) { - if (likely (count >= n)) - count -= n; + if (likely (length >= n)) + length -= n; else set_error (); } const ELEM& peek () { - if (unlikely (count == 0)) + if (unlikely (length == 0)) { set_error (); return Null (ELEM); } - return elements[count - 1]; + return arrayZ[length - 1]; } void unpop () { - if (likely (count < LIMIT)) - count++; + if (likely (length < LIMIT)) + length++; else set_error (); } - void clear () { count = 0; } + void clear () { length = 0; } bool in_error () const { return (error); } void set_error () { error = true; } - unsigned int get_count () const { return count; } - bool is_empty () const { return !count; } + unsigned int get_count () const { return length; } + bool is_empty () const { return !length; } hb_array_t sub_array (unsigned start, unsigned length) const - { return hb_array_t (elements).sub_array (start, length); } + { return hb_array_t (arrayZ).sub_array (start, length); } - private: bool error = false; - unsigned int count = 0; - ELEM elements[LIMIT]; + unsigned int length = 0; + ELEM arrayZ[LIMIT]; }; /* argument stack */ @@ -522,7 +521,7 @@ struct parsed_values_t void alloc (unsigned n) { - values.alloc (n, true); + values.alloc_exact (n); } void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ()) diff --git a/thirdparty/harfbuzz/upstream/hb-cff-specializer.hh b/thirdparty/harfbuzz/upstream/hb-cff-specializer.hh new file mode 100644 index 000000000..5b4dce5d0 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-cff-specializer.hh @@ -0,0 +1,273 @@ +/* + * CFF CharString Specializer + * + * Optimizes CharString bytecode by using specialized operators + * (hlineto, vlineto, hhcurveto, etc.) to save bytes and respects + * CFF1 stack limit (48 values). + * + * Based on fontTools.cffLib.specializer + */ + +#ifndef HB_CFF_SPECIALIZER_HH +#define HB_CFF_SPECIALIZER_HH + +#include "hb.hh" +#include "hb-cff-interp-cs-common.hh" + +namespace CFF { + +/* CharString command representation - forward declared in hb-subset-cff-common.hh */ + +/* Check if a value is effectively zero */ +static inline bool +is_zero (const number_t &n) +{ + return n.to_int () == 0; +} + +/* Generalize CharString commands to canonical form + * + * Converts all operators to their general forms and breaks down + * multi-segment operators into single segments. This ensures we + * start from a clean baseline before specialization. + * + * Based on fontTools.cffLib.specializer.generalizeCommands + */ +static void +generalize_commands (hb_vector_t &commands) +{ + hb_vector_t result; + result.alloc (commands.length * 2); /* Estimate: might expand */ + + for (unsigned i = 0; i < commands.length; i++) + { + auto &cmd = commands[i]; + + switch (cmd.op) + { + case OpCode_hmoveto: + case OpCode_vmoveto: + { + /* Convert to rmoveto with explicit dx,dy */ + cs_command_t gen (OpCode_rmoveto); + gen.args.alloc (2); + + if (cmd.op == OpCode_hmoveto && cmd.args.length >= 1) + { + gen.args.push (cmd.args[0]); /* dx */ + number_t zero; zero.set_int (0); + gen.args.push (zero); /* dy = 0 */ + } + else if (cmd.op == OpCode_vmoveto && cmd.args.length >= 1) + { + number_t zero; zero.set_int (0); + gen.args.push (zero); /* dx = 0 */ + gen.args.push (cmd.args[0]); /* dy */ + } + result.push (gen); + break; + } + + case OpCode_hlineto: + case OpCode_vlineto: + { + /* Convert h/v lineto to rlineto, breaking into single segments + * hlineto alternates: dx1 (→ dx1,0) dy1 (→ 0,dy1) dx2 (→ dx2,0) ... + * vlineto alternates: dy1 (→ 0,dy1) dx1 (→ dx1,0) dy2 (→ 0,dy2) ... */ + bool is_h = (cmd.op == OpCode_hlineto); + number_t zero; zero.set_int (0); + + for (unsigned j = 0; j < cmd.args.length; j++) + { + cs_command_t seg (OpCode_rlineto); + seg.args.alloc (2); + + bool is_horizontal = is_h ? (j % 2 == 0) : (j % 2 == 1); + if (is_horizontal) + { + seg.args.push (cmd.args[j]); /* dx */ + seg.args.push (zero); /* dy = 0 */ + } + else + { + seg.args.push (zero); /* dx = 0 */ + seg.args.push (cmd.args[j]); /* dy */ + } + result.push (seg); + } + break; + } + + case OpCode_rlineto: + { + /* Break into single segments (dx,dy pairs) */ + for (unsigned j = 0; j + 1 < cmd.args.length; j += 2) + { + cs_command_t seg (OpCode_rlineto); + seg.args.alloc (2); + seg.args.push (cmd.args[j]); + seg.args.push (cmd.args[j + 1]); + result.push (seg); + } + break; + } + + case OpCode_rrcurveto: + { + /* Break into single segments (6 args each) */ + for (unsigned j = 0; j + 5 < cmd.args.length; j += 6) + { + cs_command_t seg (OpCode_rrcurveto); + seg.args.alloc (6); + for (unsigned k = 0; k < 6; k++) + seg.args.push (cmd.args[j + k]); + result.push (seg); + } + break; + } + + default: + /* Keep other operators as-is */ + result.push (cmd); + break; + } + } + + /* Replace commands with generalized result */ + commands.resize (0); + for (unsigned i = 0; i < result.length; i++) + commands.push (result[i]); +} + +/* Specialize CharString commands to optimize bytecode size + * + * Follows fontTools approach: + * 0. Generalize: Break down to canonical single-segment form + * 1. Specialize: Convert rmoveto/rlineto to h/v variants when dx or dy is zero + * 2. Combine: Merge adjacent compatible operators + * 3. Enforce: Respect maxstack limit (default 48 for CFF1) + * + * This ensures we never exceed stack depth while optimizing bytecode. + */ +static void +specialize_commands (hb_vector_t &commands, + unsigned maxstack = 48) +{ + if (commands.length == 0) return; + + /* Pass 0: Generalize to canonical form (fontTools does this first) */ + generalize_commands (commands); + + /* Pass 1: Specialize rmoveto/rlineto into h/v variants */ + for (unsigned i = 0; i < commands.length; i++) + { + auto &cmd = commands[i]; + + if ((cmd.op == OpCode_rmoveto || cmd.op == OpCode_rlineto) && + cmd.args.length == 2) + { + bool dx_zero = is_zero (cmd.args[0]); + bool dy_zero = is_zero (cmd.args[1]); + + if (dx_zero && !dy_zero) + { + /* Vertical movement (dx=0): keep only dy */ + cmd.op = (cmd.op == OpCode_rmoveto) ? OpCode_vmoveto : OpCode_vlineto; + /* Shift dy to position 0 */ + cmd.args[0] = cmd.args[1]; + cmd.args.resize (1); + } + else if (!dx_zero && dy_zero) + { + /* Horizontal movement (dy=0): keep only dx */ + cmd.op = (cmd.op == OpCode_rmoveto) ? OpCode_hmoveto : OpCode_hlineto; + cmd.args.resize (1); /* Keep only dx */ + } + /* else: both zero or both non-zero, keep as rmoveto/rlineto */ + } + } + + /* Pass 2: Combine adjacent hlineto/vlineto operators + * hlineto can take multiple args alternating with vlineto + * This saves operator bytes */ + for (int i = (int)commands.length - 1; i > 0; i--) + { + auto &cmd = commands[i]; + auto &prev = commands[i-1]; + + /* Combine adjacent hlineto + vlineto or vlineto + hlineto */ + if ((prev.op == OpCode_hlineto && cmd.op == OpCode_vlineto) || + (prev.op == OpCode_vlineto && cmd.op == OpCode_hlineto)) + { + /* Check stack depth */ + unsigned combined_args = prev.args.length + cmd.args.length; + if (combined_args < maxstack) + { + /* Merge into first command, keep its operator */ + for (unsigned j = 0; j < cmd.args.length; j++) + prev.args.push (cmd.args[j]); + commands.remove_ordered (i); + i++; /* Adjust for removed element */ + } + } + } + + /* Pass 3: Combine adjacent identical operators */ + for (int i = (int)commands.length - 1; i > 0; i--) + { + auto &cmd = commands[i]; + auto &prev = commands[i-1]; + + /* Combine same operators (e.g., rlineto + rlineto) */ + if (prev.op == cmd.op && + (cmd.op == OpCode_rlineto || cmd.op == OpCode_hlineto || + cmd.op == OpCode_vlineto || cmd.op == OpCode_rrcurveto)) + { + /* Check stack depth */ + unsigned combined_args = prev.args.length + cmd.args.length; + if (combined_args < maxstack) + { + /* Merge args */ + for (unsigned j = 0; j < cmd.args.length; j++) + prev.args.push (cmd.args[j]); + commands.remove_ordered (i); + i++; /* Adjust for removed element */ + } + } + } +} + +/* Encode commands back to binary CharString */ +static bool +encode_commands (const hb_vector_t &commands, + str_buff_t &output) +{ + for (const auto &cmd : commands) + { + str_encoder_t encoder (output); + + /* Encode arguments */ + for (const auto &arg : cmd.args) + encoder.encode_num_cs (arg); + + /* Encode operator */ + if (cmd.op != OpCode_Invalid) + encoder.encode_op (cmd.op); + + /* hintmask/cntrmask are followed by raw mask bytes. */ + if (cmd.op == OpCode_hintmask || cmd.op == OpCode_cntrmask) + { + for (const auto &byte : cmd.mask_bytes) + encoder.encode_byte (byte); + } + + if (encoder.in_error ()) + return false; + } + + return true; +} + +} /* namespace CFF */ + +#endif /* HB_CFF_SPECIALIZER_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-cff-width-optimizer.hh b/thirdparty/harfbuzz/upstream/hb-cff-width-optimizer.hh new file mode 100644 index 000000000..e105dae4a --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-cff-width-optimizer.hh @@ -0,0 +1,207 @@ +/* + * CFF Width Optimizer + * + * Determines optimal defaultWidthX and nominalWidthX values + * to minimize CharString byte cost. + * + * Based on fontTools.cffLib.width + */ + +#ifndef HB_CFF_WIDTH_OPTIMIZER_HH +#define HB_CFF_WIDTH_OPTIMIZER_HH + +#include "hb.hh" + +namespace CFF { + +/* Calculate byte cost for encoding a width delta */ +static inline unsigned +width_delta_cost (int delta) +{ + delta = abs (delta); + if (delta <= 107) return 1; + if (delta <= 1131) return 2; + return 5; +} + +/* Cumulative sum forward */ +static void +cumsum_forward (const hb_hashmap_t &freq, + unsigned min_w, unsigned max_w, + hb_vector_t &cumsum) +{ + cumsum.resize (max_w - min_w + 1); + unsigned v = 0; + for (unsigned x = min_w; x <= max_w; x++) + { + v += freq.get (x); + cumsum[x - min_w] = v; + } +} + +/* Cumulative max forward */ +static void +cummax_forward (const hb_hashmap_t &freq, + unsigned min_w, unsigned max_w, + hb_vector_t &cummax) +{ + cummax.resize (max_w - min_w + 1); + unsigned v = 0; + for (unsigned x = min_w; x <= max_w; x++) + { + v = hb_max (v, freq.get (x)); + cummax[x - min_w] = v; + } +} + +/* Cumulative sum backward */ +static void +cumsum_backward (const hb_hashmap_t &freq, + unsigned min_w, unsigned max_w, + hb_vector_t &cumsum) +{ + cumsum.resize (max_w - min_w + 1); + unsigned v = 0; + for (int x = (int) max_w; x >= (int) min_w; x--) + { + v += freq.get ((unsigned) x); + cumsum[x - min_w] = v; + } +} + +/* Cumulative max backward */ +static void +cummax_backward (const hb_hashmap_t &freq, + unsigned min_w, unsigned max_w, + hb_vector_t &cummax) +{ + cummax.resize (max_w - min_w + 1); + unsigned v = 0; + for (int x = (int) max_w; x >= (int) min_w; x--) + { + v = hb_max (v, freq.get ((unsigned) x)); + cummax[x - min_w] = v; + } +} + +/* Helper to safely get cumulative value with bounds checking */ +static inline unsigned +safe_get (const hb_vector_t &vec, int x, unsigned min_w, unsigned max_w) +{ + if (x < (int) min_w || x > (int) max_w) return 0; + return vec[x - min_w]; +} + +/* Optimize defaultWidthX and nominalWidthX from a list of widths + * O(UPEM+numGlyphs) algorithm from fontTools.cffLib.width */ +static void +optimize_widths (const hb_vector_t &width_list, + unsigned &default_width, + unsigned &nominal_width) +{ + if (width_list.length == 0) + { + default_width = nominal_width = 0; + return; + } + + /* Build frequency map */ + hb_hashmap_t widths; + unsigned min_w = width_list[0]; + unsigned max_w = width_list[0]; + + for (unsigned w : width_list) + { + widths.set (w, widths.get (w) + 1); + min_w = hb_min (min_w, w); + max_w = hb_max (max_w, w); + } + + /* Cumulative sum/max forward/backward */ + hb_vector_t cumFrqU, cumMaxU, cumFrqD, cumMaxD; + cumsum_forward (widths, min_w, max_w, cumFrqU); + cummax_forward (widths, min_w, max_w, cumMaxU); + cumsum_backward (widths, min_w, max_w, cumFrqD); + cummax_backward (widths, min_w, max_w, cumMaxD); + + /* Cost per nominal choice, without default consideration */ + auto nomnCost = [&] (unsigned x) -> unsigned { + return safe_get (cumFrqU, x, min_w, max_w) + + safe_get (cumFrqU, x - 108, min_w, max_w) + + safe_get (cumFrqU, x - 1132, min_w, max_w) * 3 + + safe_get (cumFrqD, x, min_w, max_w) + + safe_get (cumFrqD, x + 108, min_w, max_w) + + safe_get (cumFrqD, x + 1132, min_w, max_w) * 3 - + widths.get (x); + }; + + /* Cost-saving per nominal choice, by best default choice */ + auto dfltCost = [&] (unsigned x) -> unsigned { + unsigned u = hb_max (hb_max (safe_get (cumMaxU, x, min_w, max_w), + safe_get (cumMaxU, x - 108, min_w, max_w) * 2), + safe_get (cumMaxU, x - 1132, min_w, max_w) * 5); + unsigned d = hb_max (hb_max (safe_get (cumMaxD, x, min_w, max_w), + safe_get (cumMaxD, x + 108, min_w, max_w) * 2), + safe_get (cumMaxD, x + 1132, min_w, max_w) * 5); + return hb_max (u, d); + }; + + /* Find best nominal */ + unsigned best_nominal = min_w; + unsigned best_cost = nomnCost (min_w) - dfltCost (min_w); + + for (unsigned x = min_w + 1; x <= max_w; x++) + { + unsigned cost = nomnCost (x) - dfltCost (x); + if (cost < best_cost) + { + best_cost = cost; + best_nominal = x; + } + } + + /* Work back the best default */ + unsigned best_default = best_nominal; + unsigned best_default_cost = (unsigned) -1; + + /* Check candidates around best_nominal */ + int candidates[] = { + (int) best_nominal, + (int) best_nominal - 108, + (int) best_nominal - 1132, + (int) best_nominal + 108, + (int) best_nominal + 1132 + }; + + for (int candidate : candidates) + { + if (candidate < (int) min_w || candidate > (int) max_w) + continue; + + /* Compute actual cost with this default */ + unsigned cost = 0; + for (auto kv : widths.iter ()) + { + unsigned w = kv.first; + unsigned freq = kv.second; + + if (w == (unsigned) candidate) + continue; + + cost += freq * width_delta_cost ((int) w - (int) best_nominal); + } + + if (cost < best_default_cost) + { + best_default_cost = cost; + best_default = (unsigned) candidate; + } + } + + default_width = best_default; + nominal_width = best_nominal; +} + +} /* namespace CFF */ + +#endif /* HB_CFF_WIDTH_OPTIMIZER_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-cff2-interp-cs.hh b/thirdparty/harfbuzz/upstream/hb-cff2-interp-cs.hh index 06fbb72c6..c44b02476 100644 --- a/thirdparty/harfbuzz/upstream/hb-cff2-interp-cs.hh +++ b/thirdparty/harfbuzz/upstream/hb-cff2-interp-cs.hh @@ -71,18 +71,49 @@ struct cff2_cs_interp_env_t : cs_interp_env_t template cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd, const int *coords_=nullptr, unsigned int num_coords_=0) - : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs) + : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs), + region_count (0), cached_scalars_vector (&acc.cached_scalars_vector) { coords = coords_; num_coords = num_coords_; varStore = acc.varStore; - do_blend = num_coords && coords && varStore->size; + do_blend = num_coords && varStore->size; set_ivs (acc.privateDicts[fd].ivs); } - void fini () + ~cff2_cs_interp_env_t () { - SUPER::fini (); + release_scalars_vector (scalars); + } + + hb_vector_t *acquire_scalars_vector () const + { + hb_vector_t *scalars = cached_scalars_vector->get_acquire (); + + if (!scalars || !cached_scalars_vector->cmpexch (scalars, nullptr)) + { + scalars = (hb_vector_t *) hb_calloc (1, sizeof (hb_vector_t)); + if (unlikely (!scalars)) + return nullptr; + scalars->init (); + } + + return scalars; + } + + void release_scalars_vector (hb_vector_t *scalars) const + { + if (!scalars) + return; + + scalars->clear (); + + if (!cached_scalars_vector->cmpexch (nullptr, scalars)) + { + scalars->fini (); + hb_free (scalars); + } + scalars = nullptr; } op_code_t fetch_op () @@ -111,14 +142,20 @@ struct cff2_cs_interp_env_t : cs_interp_env_t { if (!seen_blend) { - region_count = varStore->varStore.get_region_index_count (get_ivs ()); - if (do_blend) + scalars = acquire_scalars_vector (); + if (unlikely (!scalars)) + SUPER::set_error (); + else { - if (unlikely (!scalars.resize_exact (region_count))) - SUPER::set_error (); - else - varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, - &scalars[0], region_count); + region_count = varStore->varStore.get_region_index_count (get_ivs ()); + if (do_blend) + { + if (unlikely (!scalars->resize_exact (region_count))) + SUPER::set_error (); + else + varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, + &(*scalars)[0], region_count); + } } seen_blend = true; } @@ -149,11 +186,11 @@ struct cff2_cs_interp_env_t : cs_interp_env_t double v = 0; if (do_blend) { - if (likely (scalars.length == deltas.length)) + if (likely (scalars && scalars->length == deltas.length)) { - unsigned count = scalars.length; + unsigned count = scalars->length; for (unsigned i = 0; i < count; i++) - v += (double) scalars.arrayZ[i] * deltas.arrayZ[i].to_real (); + v += (double) scalars->arrayZ[i] * deltas.arrayZ[i].to_real (); } } return v; @@ -167,7 +204,8 @@ struct cff2_cs_interp_env_t : cs_interp_env_t const CFF2ItemVariationStore *varStore; unsigned int region_count; unsigned int ivs; - hb_vector_t scalars; + hb_vector_t *scalars = nullptr; + hb_atomic_t *> *cached_scalars_vector = nullptr; bool do_blend; bool seen_vsindex_ = false; bool seen_blend = false; @@ -253,7 +291,7 @@ struct cff2_cs_opset_t : cs_opset_t, PAR for (unsigned int i = 0; i < n; i++) { const hb_array_t blends = env.argStack.sub_array (start + n + (i * k), k); - process_arg_blend (env, env.argStack[start + i], blends, n, i); + process_arg_blend (env, env.argStack.arrayZ[start + i], blends, n, i); } /* pop off blend values leaving default values now adorned with blend values */ diff --git a/thirdparty/harfbuzz/upstream/hb-common.cc b/thirdparty/harfbuzz/upstream/hb-common.cc index b7f2f36f1..f25fb866c 100644 --- a/thirdparty/harfbuzz/upstream/hb-common.cc +++ b/thirdparty/harfbuzz/upstream/hb-common.cc @@ -40,43 +40,6 @@ **/ -/* hb_options_t */ - -hb_atomic_int_t _hb_options; - -void -_hb_options_init () -{ - hb_options_union_t u; - u.i = 0; - u.opts.initialized = true; - - const char *c = getenv ("HB_OPTIONS"); - if (c) - { - while (*c) - { - const char *p = strchr (c, ':'); - if (!p) - p = c + strlen (c); - -#define OPTION(name, symbol) \ - if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast(p - c)) do { u.opts.symbol = true; } while (0) - - OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible); - -#undef OPTION - - c = *p ? p + 1 : p; - } - - } - - /* This is idempotent and threadsafe. */ - _hb_options = u.i; -} - - /* hb_tag_t */ /** @@ -273,7 +236,7 @@ struct hb_language_item_t { /* Thread-safe lockfree language list */ -static hb_atomic_ptr_t langs; +static hb_atomic_t langs; static inline void free_langs () @@ -403,7 +366,7 @@ hb_language_to_string (hb_language_t language) hb_language_t hb_language_get_default () { - static hb_atomic_ptr_t default_language; + static hb_atomic_t default_language; hb_language_t language = default_language; if (unlikely (language == HB_LANGUAGE_INVALID)) @@ -545,8 +508,11 @@ hb_script_to_iso15924_tag (hb_script_t script) * Fetches the #hb_direction_t of a script when it is * set horizontally. All right-to-left scripts will return * #HB_DIRECTION_RTL. All left-to-right scripts will return - * #HB_DIRECTION_LTR. Scripts that can be written either - * horizontally or vertically will return #HB_DIRECTION_INVALID. + * #HB_DIRECTION_LTR. + * + * Scripts that can be written either right-to-left or + * left-to-right will return #HB_DIRECTION_INVALID. + * * Unknown scripts will return #HB_DIRECTION_LTR. * * Return value: The horizontal #hb_direction_t of @script @@ -625,6 +591,12 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-14.0 additions */ case HB_SCRIPT_OLD_UYGHUR: + /* Unicode-16.0 additions */ + case HB_SCRIPT_GARAY: + + /* Unicode-17.0 additions */ + case HB_SCRIPT_SIDETIC: + return HB_DIRECTION_RTL; @@ -965,6 +937,9 @@ hb_feature_from_string (const char *str, int len, * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * + * Note that the feature value will be omitted if it is '1', but the + * string won't include any whitespace. + * * Since: 0.9.5 **/ void @@ -1118,6 +1093,8 @@ get_C_locale () * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * + * Note that the string won't include any whitespace. + * * Since: 1.4.2 */ void @@ -1211,6 +1188,58 @@ uint8_t } #endif +/** + * hb_malloc: + * @size: The size of the memory to allocate. + * + * Allocates @size bytes of memory, using the allocator set at + * compile-time. Typically just malloc(). + * + * Return value: A pointer to the allocated memory. + * + * Since: 11.0.0 + **/ +void* hb_malloc(size_t size) { return hb_malloc_impl (size); } + +/** + * hb_calloc: + * @nmemb: The number of elements to allocate. + * @size: The size of each element. + * + * Allocates @nmemb elements of @size bytes each, initialized to zero, + * using the allocator set at compile-time. Typically just calloc(). + * + * Return value: A pointer to the allocated memory. + * + * Since: 11.0.0 + **/ +void* hb_calloc(size_t nmemb, size_t size) { return hb_calloc_impl (nmemb, size); } + +/** + * hb_realloc: + * @ptr: The pointer to the memory to reallocate. + * @size: The new size of the memory. + * + * Reallocates the memory pointed to by @ptr to @size bytes, using the + * allocator set at compile-time. Typically just realloc(). + * + * Return value: A pointer to the reallocated memory. + * + * Since: 11.0.0 + **/ +void* hb_realloc(void *ptr, size_t size) { return hb_realloc_impl (ptr, size); } + +/** + * hb_free: + * @ptr: The pointer to the memory to free. + * + * Frees the memory pointed to by @ptr, using the allocator set at + * compile-time. Typically just free(). + * + * Since: 11.0.0 + **/ +void hb_free(void *ptr) { hb_free_impl (ptr); } + /* If there is no visibility control, then hb-static.cc will NOT * define anything. Instead, we get it to define one set in here * only, so only libharfbuzz.so defines them, not other libs. */ diff --git a/thirdparty/harfbuzz/upstream/hb-common.h b/thirdparty/harfbuzz/upstream/hb-common.h index 610945173..e342bcd8f 100644 --- a/thirdparty/harfbuzz/upstream/hb-common.h +++ b/thirdparty/harfbuzz/upstream/hb-common.h @@ -65,6 +65,7 @@ typedef unsigned __int64 uint64_t; #else # include #endif +#include #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define HB_DEPRECATED __attribute__((__deprecated__)) @@ -337,437 +338,7 @@ HB_EXTERN hb_bool_t hb_language_matches (hb_language_t language, hb_language_t specific); -/** - * hb_script_t: - * @HB_SCRIPT_COMMON: `Zyyy` - * @HB_SCRIPT_INHERITED: `Zinh` - * @HB_SCRIPT_UNKNOWN: `Zzzz` - * @HB_SCRIPT_ARABIC: `Arab` - * @HB_SCRIPT_ARMENIAN: `Armn` - * @HB_SCRIPT_BENGALI: `Beng` - * @HB_SCRIPT_CYRILLIC: `Cyrl` - * @HB_SCRIPT_DEVANAGARI: `Deva` - * @HB_SCRIPT_GEORGIAN: `Geor` - * @HB_SCRIPT_GREEK: `Grek` - * @HB_SCRIPT_GUJARATI: `Gujr` - * @HB_SCRIPT_GURMUKHI: `Guru` - * @HB_SCRIPT_HANGUL: `Hang` - * @HB_SCRIPT_HAN: `Hani` - * @HB_SCRIPT_HEBREW: `Hebr` - * @HB_SCRIPT_HIRAGANA: `Hira` - * @HB_SCRIPT_KANNADA: `Knda` - * @HB_SCRIPT_KATAKANA: `Kana` - * @HB_SCRIPT_LAO: `Laoo` - * @HB_SCRIPT_LATIN: `Latn` - * @HB_SCRIPT_MALAYALAM: `Mlym` - * @HB_SCRIPT_ORIYA: `Orya` - * @HB_SCRIPT_TAMIL: `Taml` - * @HB_SCRIPT_TELUGU: `Telu` - * @HB_SCRIPT_THAI: `Thai` - * @HB_SCRIPT_TIBETAN: `Tibt` - * @HB_SCRIPT_BOPOMOFO: `Bopo` - * @HB_SCRIPT_BRAILLE: `Brai` - * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` - * @HB_SCRIPT_CHEROKEE: `Cher` - * @HB_SCRIPT_ETHIOPIC: `Ethi` - * @HB_SCRIPT_KHMER: `Khmr` - * @HB_SCRIPT_MONGOLIAN: `Mong` - * @HB_SCRIPT_MYANMAR: `Mymr` - * @HB_SCRIPT_OGHAM: `Ogam` - * @HB_SCRIPT_RUNIC: `Runr` - * @HB_SCRIPT_SINHALA: `Sinh` - * @HB_SCRIPT_SYRIAC: `Syrc` - * @HB_SCRIPT_THAANA: `Thaa` - * @HB_SCRIPT_YI: `Yiii` - * @HB_SCRIPT_DESERET: `Dsrt` - * @HB_SCRIPT_GOTHIC: `Goth` - * @HB_SCRIPT_OLD_ITALIC: `Ital` - * @HB_SCRIPT_BUHID: `Buhd` - * @HB_SCRIPT_HANUNOO: `Hano` - * @HB_SCRIPT_TAGALOG: `Tglg` - * @HB_SCRIPT_TAGBANWA: `Tagb` - * @HB_SCRIPT_CYPRIOT: `Cprt` - * @HB_SCRIPT_LIMBU: `Limb` - * @HB_SCRIPT_LINEAR_B: `Linb` - * @HB_SCRIPT_OSMANYA: `Osma` - * @HB_SCRIPT_SHAVIAN: `Shaw` - * @HB_SCRIPT_TAI_LE: `Tale` - * @HB_SCRIPT_UGARITIC: `Ugar` - * @HB_SCRIPT_BUGINESE: `Bugi` - * @HB_SCRIPT_COPTIC: `Copt` - * @HB_SCRIPT_GLAGOLITIC: `Glag` - * @HB_SCRIPT_KHAROSHTHI: `Khar` - * @HB_SCRIPT_NEW_TAI_LUE: `Talu` - * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` - * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` - * @HB_SCRIPT_TIFINAGH: `Tfng` - * @HB_SCRIPT_BALINESE: `Bali` - * @HB_SCRIPT_CUNEIFORM: `Xsux` - * @HB_SCRIPT_NKO: `Nkoo` - * @HB_SCRIPT_PHAGS_PA: `Phag` - * @HB_SCRIPT_PHOENICIAN: `Phnx` - * @HB_SCRIPT_CARIAN: `Cari` - * @HB_SCRIPT_CHAM: `Cham` - * @HB_SCRIPT_KAYAH_LI: `Kali` - * @HB_SCRIPT_LEPCHA: `Lepc` - * @HB_SCRIPT_LYCIAN: `Lyci` - * @HB_SCRIPT_LYDIAN: `Lydi` - * @HB_SCRIPT_OL_CHIKI: `Olck` - * @HB_SCRIPT_REJANG: `Rjng` - * @HB_SCRIPT_SAURASHTRA: `Saur` - * @HB_SCRIPT_SUNDANESE: `Sund` - * @HB_SCRIPT_VAI: `Vaii` - * @HB_SCRIPT_AVESTAN: `Avst` - * @HB_SCRIPT_BAMUM: `Bamu` - * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` - * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` - * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` - * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` - * @HB_SCRIPT_JAVANESE: `Java` - * @HB_SCRIPT_KAITHI: `Kthi` - * @HB_SCRIPT_LISU: `Lisu` - * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` - * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` - * @HB_SCRIPT_OLD_TURKIC: `Orkh` - * @HB_SCRIPT_SAMARITAN: `Samr` - * @HB_SCRIPT_TAI_THAM: `Lana` - * @HB_SCRIPT_TAI_VIET: `Tavt` - * @HB_SCRIPT_BATAK: `Batk` - * @HB_SCRIPT_BRAHMI: `Brah` - * @HB_SCRIPT_MANDAIC: `Mand` - * @HB_SCRIPT_CHAKMA: `Cakm` - * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` - * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` - * @HB_SCRIPT_MIAO: `Plrd` - * @HB_SCRIPT_SHARADA: `Shrd` - * @HB_SCRIPT_SORA_SOMPENG: `Sora` - * @HB_SCRIPT_TAKRI: `Takr` - * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 - * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 - * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 - * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 - * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 - * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 - * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 - * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 - * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 - * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 - * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 - * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 - * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 - * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 - * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 - * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 - * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 - * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 - * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 - * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 - * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 - * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 - * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 - * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 - * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 - * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 - * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 - * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 - * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 - * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 - * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 - * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 - * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 - * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 - * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 - * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 - * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 - * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 - * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 - * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 - * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 - * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 - * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 - * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 - * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 - * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 - * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 - * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 - * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 - * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 - * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 - * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 - * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 - * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 - * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0 - * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0 - * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0 - * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 - * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 - * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 - * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 - * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 - * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 - * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 - * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 - * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 - * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 - * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 - * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 - * @HB_SCRIPT_INVALID: No script set - * - * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding - * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). - * - * See also the Script (sc) property of the Unicode Character Database. - * - **/ - -/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ -typedef enum -{ - HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/ - HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/ - HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/ - - HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/ - HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/ - HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/ - HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/ - HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/ - HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/ - HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/ - HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/ - HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/ - HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/ - HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/ - HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/ - HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/ - HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/ - HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/ - HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/ - HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/ - HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/ - HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/ - HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/ - HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/ - HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/ - - HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/ - - HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/ - HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/ - HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/ - HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/ - HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/ - HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/ - HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/ - HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/ - HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/ - HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/ - HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/ - HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/ - HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/ - HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/ - - HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/ - HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/ - HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/ - - HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/ - HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/ - HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/ - HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/ - - HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/ - HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/ - HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/ - HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/ - HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/ - HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/ - HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/ - - HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/ - HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/ - HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/ - HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/ - HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/ - HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/ - HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/ - HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/ - - HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/ - HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/ - HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/ - HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/ - HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/ - - HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/ - HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/ - HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/ - HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/ - HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/ - HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/ - HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/ - HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/ - HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/ - HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/ - HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/ - - HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/ - HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/ - HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/ - HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/ - HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/ - HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/ - HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/ - HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/ - HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/ - HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/ - HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/ - HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/ - HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/ - HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/ - HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/ - - HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/ - HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/ - HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/ - - HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/ - HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/ - HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/ - HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/ - HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/ - HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ - HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ - - /* - * Since: 0.9.30 - */ - HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ - HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ - HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ - HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/ - HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/ - HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/ - HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/ - HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/ - HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ - HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ - HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ - HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/ - HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ - HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ - HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ - HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ - HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ - HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ - HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/ - HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ - HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/ - HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ - HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ - - HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/ - HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/ - HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/ - HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/ - HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/ - HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/ - - /* - * Since 1.3.0 - */ - HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/ - HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/ - HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/ - HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/ - HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/ - HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/ - - /* - * Since 1.6.0 - */ - HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/ - HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/ - HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/ - HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/ - - /* - * Since 1.8.0 - */ - HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/ - HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/ - HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/ - HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/ - HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/ - HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/ - HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/ - - /* - * Since 2.4.0 - */ - HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/ - HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/ - HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/ - HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/ - - /* - * Since 2.6.7 - */ - HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ - HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ - HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ - HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ - - /* - * Since 3.0.0 - */ - HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/ - HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/ - HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/ - HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/ - HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/ - - /* - * Since 3.4.0 - */ - HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'), - - /* - * Since 5.2.0 - */ - HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ - HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ - - /* - * Since 10.0.0 - */ - HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ - HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ - HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ - HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ - HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ - HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ - HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ - - /* No script set. */ - HB_SCRIPT_INVALID = HB_TAG_NONE, - - /*< private >*/ - - /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t - * without risking undefined behavior. We have two, for historical reasons. - * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed - * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. - * - * See this thread for technicalities: - * - * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html - */ - _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ - _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ - -} hb_script_t; - +#include "hb-script-list.h" /* Script functions */ @@ -956,6 +527,16 @@ typedef struct hb_glyph_extents_t { */ typedef struct hb_font_t hb_font_t; +/* Not of much use to clients. */ +HB_EXTERN void* +hb_malloc (size_t size); +HB_EXTERN void* +hb_calloc (size_t nmemb, size_t size); +HB_EXTERN void* +hb_realloc (void *ptr, size_t size); +HB_EXTERN void +hb_free (void *ptr); + HB_END_DECLS #endif /* HB_COMMON_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-config.hh b/thirdparty/harfbuzz/upstream/hb-config.hh index 14105846a..b508c4e79 100644 --- a/thirdparty/harfbuzz/upstream/hb-config.hh +++ b/thirdparty/harfbuzz/upstream/hb-config.hh @@ -38,12 +38,12 @@ #ifndef HB_EXPERIMENTAL_API #define HB_NO_BEYOND_64K #define HB_NO_CUBIC_GLYF -#define HB_NO_VAR_COMPOSITES #endif #ifdef HB_TINY #define HB_LEAN #define HB_MINI +#define HB_NO_SVG #define HB_OPTIMIZE_SIZE #define HB_OPTIMIZE_SIZE_MORE #define HB_MINIMIZE_MEMORY_USAGE @@ -68,8 +68,6 @@ #define HB_NO_FACE_COLLECT_UNICODES #define HB_NO_GETENV #define HB_NO_HINTING -#define HB_NO_LANGUAGE_LONG -#define HB_NO_LANGUAGE_PRIVATE_SUBTAG #define HB_NO_LAYOUT_FEATURE_PARAMS #define HB_NO_LAYOUT_COLLECT_GLYPHS #define HB_NO_LAYOUT_RARELY_USED @@ -93,7 +91,10 @@ #ifdef HB_MINI #define HB_NO_AAT #define HB_NO_LEGACY -#define HB_NO_BORING_EXPANSION +#define HB_NO_BEYOND_64K +#define HB_NO_CUBIC_GLYF +#define HB_NO_VAR_COMPOSITES +#define HB_NO_VAR_HVF #endif #ifdef __OPTIMIZE_SIZE__ @@ -111,12 +112,6 @@ /* Closure of options. */ -#ifdef HB_NO_BORING_EXPANSION -#define HB_NO_BEYOND_64K -#define HB_NO_CUBIC_GLYF -#define HB_NO_VAR_COMPOSITES -#endif - #ifdef HB_NO_VAR #define HB_NO_VAR_COMPOSITES #endif @@ -148,10 +143,7 @@ #ifdef HB_NO_DRAW #define HB_NO_OUTLINE -#endif - -#ifdef HB_NO_GETENV -#define HB_NO_UNISCRIBE_BUG_COMPATIBLE +#define HB_NO_PAINT #endif #ifdef HB_NO_LEGACY @@ -159,6 +151,7 @@ #define HB_NO_FALLBACK_SHAPE #define HB_NO_OT_KERN #define HB_NO_OT_LAYOUT_BLOCKLIST +#define HB_NO_AAT_LAYOUT_BLOCKLIST #define HB_NO_OT_SHAPE_FALLBACK #endif @@ -192,7 +185,6 @@ #ifdef HB_MINIMIZE_MEMORY_USAGE #define HB_NO_GDEF_CACHE #define HB_NO_OT_LAYOUT_LOOKUP_CACHE -#define HB_NO_OT_FONT_ADVANCE_CACHE #define HB_NO_OT_FONT_CMAP_CACHE #endif diff --git a/thirdparty/harfbuzz/upstream/hb-coretext-font.cc b/thirdparty/harfbuzz/upstream/hb-coretext-font.cc index 22bbe0a34..24217bc6f 100644 --- a/thirdparty/harfbuzz/upstream/hb-coretext-font.cc +++ b/thirdparty/harfbuzz/upstream/hb-coretext-font.cc @@ -28,46 +28,57 @@ #ifdef HAVE_CORETEXT -#include "hb-coretext.h" +#include "hb-coretext.hh" +#include "hb-aat-layout-trak-table.hh" #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" + #if MAC_OS_X_VERSION_MIN_REQUIRED < 101100 && !defined(RIVE_APPLETVOS) && !defined(RIVE_APPLETVOS_SIMULATOR) # define kCTFontOrientationDefault kCTFontDefaultOrientation +# define kCTFontOrientationHorizontal kCTFontHorizontalOrientation +# define kCTFontOrientationVertical kCTFontVerticalOrientation #endif -#define MAX_GLYPHS 64u - -static void -_hb_coretext_font_destroy (void *font_data) -{ - CTFontRef ct_font = (CTFontRef) font_data; - - CFRelease (ct_font); -} +#define MAX_GLYPHS 256u static hb_bool_t -hb_coretext_get_nominal_glyph (hb_font_t *font HB_UNUSED, - void *font_data, +hb_coretext_get_nominal_glyph (hb_font_t *font, + void *font_data HB_UNUSED, hb_codepoint_t unicode, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; - UniChar ch = unicode; - CGGlyph cg_glyph; - if (CTFontGetGlyphsForCharacters (ct_font, &ch, &cg_glyph, 1)) + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; + + UniChar ch[2]; + CGGlyph cg_glyph[2]; + unsigned count = 0; + + if (unicode <= 0xFFFF) + { + ch[count++] = unicode; + } + else if (unicode <= 0x10FFFF) { - *glyph = cg_glyph; + ch[count++] = (unicode >> 10) + 0xD7C0; + ch[count++] = (unicode & 0x3FF) + 0xDC00; + } + else + ch[count++] = 0xFFFD; + + if (CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, count)) + { + *glyph = cg_glyph[0]; return true; } return false; } static unsigned int -hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, +hb_coretext_get_nominal_glyphs (hb_font_t *font, void *font_data, unsigned int count, const hb_codepoint_t *first_unicode, @@ -76,7 +87,32 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, unsigned int glyph_stride, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; + + // If any non-BMP codepoint is requested, use the slow path. + bool slow_path = false; + auto *unicode = first_unicode; + for (unsigned i = 0; i < count; i++) + { + if (*unicode > 0xFFFF) + { + slow_path = true; + break; + } + unicode = &StructAtOffset (unicode, unicode_stride); + } + + if (unlikely (slow_path)) + { + for (unsigned i = 0; i < count; i++) + { + if (!hb_coretext_get_nominal_glyph (font, font_data, *first_unicode, first_glyph, nullptr)) + return i; + first_unicode = &StructAtOffset (first_unicode, unicode_stride); + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + return count; + } UniChar ch[MAX_GLYPHS]; CGGlyph cg_glyph[MAX_GLYPHS]; @@ -88,7 +124,16 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, ch[j] = *first_unicode; first_unicode = &StructAtOffset (first_unicode, unicode_stride); } - CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, c); + if (unlikely (!CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, c))) + { + // Use slow path partially and return at first failure. + for (unsigned j = 0; j < c; j++) + { + if (!hb_coretext_get_nominal_glyph (font, font_data, ch[j], first_glyph, nullptr)) + return i + j; + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + } for (unsigned j = 0; j < c; j++) { *first_glyph = cg_glyph[j]; @@ -100,29 +145,59 @@ hb_coretext_get_nominal_glyphs (hb_font_t *font HB_UNUSED, } static hb_bool_t -hb_coretext_get_variation_glyph (hb_font_t *font HB_UNUSED, - void *font_data, +hb_coretext_get_variation_glyph (hb_font_t *font, + void *font_data HB_UNUSED, hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; - UniChar ch[2] = { unicode, variation_selector }; - CGGlyph cg_glyph[2]; + UniChar ch[4]; + CGGlyph cg_glyph[4]; + unsigned count = 0; - CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, 2); + // Add Unicode, then variation selector. Ugly, but works. + // + if (unicode <= 0xFFFF) + ch[count++] = unicode; + else if (unicode <= 0x10FFFF) + { + ch[count++] = (unicode >> 10) + 0xD7C0; + ch[count++] = (unicode & 0x3FF) + 0xDC00; + } + else + ch[count++] = 0xFFFD; - if (cg_glyph[1]) - return false; + if (variation_selector <= 0xFFFF) + ch[count++] = variation_selector; + else if (variation_selector <= 0x10FFFF) + { + ch[count++] = (variation_selector >> 10) + 0xD7C0; + ch[count++] = (variation_selector & 0x3FF) + 0xDC00; + } + else + ch[count++] = 0xFFFD; + + CTFontGetGlyphsForCharacters (ct_font, ch, cg_glyph, count); + + // All except for first should be zero if we succeeded + for (unsigned i = 1; i < count; i++) + if (cg_glyph[i]) + return false; + + // Humm. CoreText falls back to the default glyph if the variation selector + // is not supported. We cannot truly detect that case. So, in essence, + // we are always returning true here... *glyph = cg_glyph[0]; return true; } static void -hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, +hb_coretext_get_glyph_h_advances (hb_font_t* font, + void* font_data HB_UNUSED, unsigned count, const hb_codepoint_t *first_glyph, unsigned glyph_stride, @@ -130,10 +205,11 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; + hb_position_t tracking = font->face->table.trak->get_tracking (font, HB_DIRECTION_LTR, 0.f); CGGlyph cg_glyph[MAX_GLYPHS]; CGSize advances[MAX_GLYPHS]; @@ -148,7 +224,7 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, CTFontGetAdvancesForGlyphs (ct_font, kCTFontOrientationHorizontal, cg_glyph, advances, c); for (unsigned j = 0; j < c; j++) { - *first_advance = round (advances[j].width * x_mult); + *first_advance = round (advances[j].width * x_mult) - tracking; first_advance = &StructAtOffset (first_advance, advance_stride); } } @@ -156,7 +232,8 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, void* font_data, #ifndef HB_NO_VERTICAL static void -hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data, +hb_coretext_get_glyph_v_advances (hb_font_t* font, + void* font_data HB_UNUSED, unsigned count, const hb_codepoint_t *first_glyph, unsigned glyph_stride, @@ -164,10 +241,11 @@ hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat y_mult = (CGFloat) -font->y_scale / ct_font_size; + hb_position_t tracking = font->face->table.trak->get_tracking (font, HB_DIRECTION_TTB, 0.f); CGGlyph cg_glyph[MAX_GLYPHS]; CGSize advances[MAX_GLYPHS]; @@ -182,23 +260,21 @@ hb_coretext_get_glyph_v_advances (hb_font_t* font, void* font_data, CTFontGetAdvancesForGlyphs (ct_font, kCTFontOrientationVertical, cg_glyph, advances, c); for (unsigned j = 0; j < c; j++) { - *first_advance = round (advances[j].width * y_mult); + *first_advance = round (advances[j].width * y_mult) - tracking; first_advance = &StructAtOffset (first_advance, advance_stride); } } } -#endif -#ifndef HB_NO_VERTICAL static hb_bool_t hb_coretext_get_glyph_v_origin (hb_font_t *font, - void *font_data, + void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) -font->x_scale / ct_font_size; @@ -217,12 +293,12 @@ hb_coretext_get_glyph_v_origin (hb_font_t *font, static hb_bool_t hb_coretext_get_glyph_extents (hb_font_t *font, - void *font_data, + void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; @@ -233,20 +309,21 @@ hb_coretext_get_glyph_extents (hb_font_t *font, kCTFontOrientationDefault, glyphs, NULL, 1); extents->x_bearing = round (bounds.origin.x * x_mult); - extents->y_bearing = round (bounds.origin.y * y_mult); + extents->y_bearing = round ((bounds.origin.y + bounds.size.height) * y_mult); extents->width = round (bounds.size.width * x_mult); - extents->height = round (bounds.size.height * y_mult); + extents->height = round (bounds.origin.y * y_mult) - extents->y_bearing; return true; } static hb_bool_t hb_coretext_get_font_h_extents (hb_font_t *font, - void *font_data, + void *font_data HB_UNUSED, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; + CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; @@ -287,14 +364,14 @@ ct_apply_func (void *info, const CGPathElement *element) } } -static void -hb_coretext_draw_glyph (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) +static hb_bool_t +hb_coretext_draw_glyph_or_fail (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; @@ -305,17 +382,19 @@ hb_coretext_draw_glyph (hb_font_t *font, CGPathRef path = CTFontCreatePathForGlyph (ct_font, glyph, &transform); if (!path) - return; + return false; - hb_draw_session_t drawing = {draw_funcs, draw_data, font->slant}; + hb_draw_session_t drawing {draw_funcs, draw_data}; CGPathApply (path, &drawing, ct_apply_func); CFRelease (path); + + return true; } #endif -[[maybe_unused]] static hb_bool_t +static hb_bool_t hb_coretext_get_glyph_name (hb_font_t *font, void *font_data HB_UNUSED, hb_codepoint_t glyph, @@ -330,25 +409,28 @@ hb_coretext_get_glyph_name (hb_font_t *font, return false; CFIndex len = CFStringGetLength (cf_name); - if (len > size - 1) - len = size - 1; + if (len > (CFIndex)size - 1) + len = (CFIndex)size - 1; CFStringGetBytes (cf_name, CFRangeMake (0, len), kCFStringEncodingUTF8, 0, false, (UInt8 *) name, size, &len); name[len] = '\0'; + + CFRelease (cf_name); + return true; } -[[maybe_unused]] static hb_bool_t -hb_coretext_get_glyph_from_name (hb_font_t *font HB_UNUSED, - void *font_data, +static hb_bool_t +hb_coretext_get_glyph_from_name (hb_font_t *font, + void *font_data HB_UNUSED, const char *name, int len, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - CTFontRef ct_font = (CTFontRef) font_data; + CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; if (len == -1) len = strlen (name); @@ -381,16 +463,14 @@ static struct hb_coretext_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t hb_font_funcs_set_font_h_extents_func (funcs, hb_coretext_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_coretext_get_glyph_h_advances, nullptr, nullptr); - //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_coretext_get_glyph_h_origin, nullptr, nullptr); #ifndef HB_NO_VERTICAL - //hb_font_funcs_set_font_v_extents_func (funcs, hb_coretext_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_glyph_v_advances_func (funcs, hb_coretext_get_glyph_v_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_coretext_get_glyph_v_origin, nullptr, nullptr); #endif #ifndef HB_NO_DRAW - hb_font_funcs_set_draw_glyph_func (funcs, hb_coretext_draw_glyph, nullptr, nullptr); + hb_font_funcs_set_draw_glyph_or_fail_func (funcs, hb_coretext_draw_glyph_or_fail, nullptr, nullptr); #endif hb_font_funcs_set_glyph_extents_func (funcs, hb_coretext_get_glyph_extents, nullptr, nullptr); @@ -434,10 +514,6 @@ _hb_coretext_get_font_funcs () * created with hb_face_create(), and therefore was not * initially configured to use CoreText font functions. * - * An #hb_font_t object created with hb_coretext_font_create() - * is preconfigured for CoreText font functions and does not - * require this function to be used. - * * Note: Internally, this function creates a CTFont. * * @@ -448,12 +524,16 @@ hb_coretext_font_set_funcs (hb_font_t *font) { CTFontRef ct_font = hb_coretext_font_get_ct_font (font); if (unlikely (!ct_font)) + { + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); return; + } hb_font_set_funcs (font, _hb_coretext_get_font_funcs (), - (void *) CFRetain (ct_font), - _hb_coretext_font_destroy); + nullptr, nullptr); } #undef MAX_GLYPHS diff --git a/thirdparty/harfbuzz/upstream/hb-coretext-shape.cc b/thirdparty/harfbuzz/upstream/hb-coretext-shape.cc index 73443796d..89bf090bb 100644 --- a/thirdparty/harfbuzz/upstream/hb-coretext-shape.cc +++ b/thirdparty/harfbuzz/upstream/hb-coretext-shape.cc @@ -32,282 +32,9 @@ #include "hb-shaper-impl.hh" -#include "hb-coretext.h" +#include "hb-coretext.hh" #include "hb-aat-layout.hh" - -/** - * SECTION:hb-coretext - * @title: hb-coretext - * @short_description: CoreText integration - * @include: hb-coretext.h - * - * Functions for using HarfBuzz with the CoreText fonts. - **/ - -/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ -#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f - -static CTFontRef create_ct_font (CGFontRef cg_font, CGFloat font_size); - -static void -release_table_data (void *user_data) -{ - CFDataRef cf_data = reinterpret_cast (user_data); - CFRelease(cf_data); -} - -static hb_blob_t * -_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) -{ - CGFontRef cg_font = reinterpret_cast (user_data); - CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); - if (unlikely (!cf_data)) - return nullptr; - - const char *data = reinterpret_cast (CFDataGetBytePtr (cf_data)); - const size_t length = CFDataGetLength (cf_data); - if (!data || !length) - { - CFRelease (cf_data); - return nullptr; - } - - return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, - reinterpret_cast (const_cast<__CFData *> (cf_data)), - release_table_data); -} - -static unsigned -_hb_cg_get_table_tags (const hb_face_t *face HB_UNUSED, - unsigned int start_offset, - unsigned int *table_count, - hb_tag_t *table_tags, - void *user_data) -{ - CGFontRef cg_font = reinterpret_cast (user_data); - - CTFontRef ct_font = create_ct_font (cg_font, (CGFloat) HB_CORETEXT_DEFAULT_FONT_SIZE); - - auto arr = CTFontCopyAvailableTables (ct_font, kCTFontTableOptionNoOptions); - - unsigned population = (unsigned) CFArrayGetCount (arr); - unsigned end_offset; - - if (!table_count) - goto done; - - if (unlikely (start_offset >= population)) - { - *table_count = 0; - goto done; - } - - end_offset = start_offset + *table_count; - if (unlikely (end_offset < start_offset)) - { - *table_count = 0; - goto done; - } - end_offset= hb_min (end_offset, (unsigned) population); - - *table_count = end_offset - start_offset; - for (unsigned i = start_offset; i < end_offset; i++) - { - CTFontTableTag tag = (CTFontTableTag)(uintptr_t) CFArrayGetValueAtIndex (arr, i); - table_tags[i - start_offset] = tag; - } - -done: - CFRelease (arr); - CFRelease (ct_font); - return population; -} - -static void -_hb_cg_font_release (void *data) -{ - CGFontRelease ((CGFontRef) data); -} - - -static CTFontDescriptorRef -get_last_resort_font_desc () -{ - // TODO Handle allocation failures? - CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); - CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, - (const void **) &last_resort, - 1, - &kCFTypeArrayCallBacks); - CFRelease (last_resort); - CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, - (const void **) &kCTFontCascadeListAttribute, - (const void **) &cascade_list, - 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease (cascade_list); - - CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); - CFRelease (attributes); - return font_desc; -} - -static void -release_data (void *info, const void *data, size_t size) -{ - assert (hb_blob_get_length ((hb_blob_t *) info) == size && - hb_blob_get_data ((hb_blob_t *) info, nullptr) == data); - - hb_blob_destroy ((hb_blob_t *) info); -} - -static CGFontRef -create_cg_font (hb_face_t *face) -{ - CGFontRef cg_font = nullptr; - if (face->destroy == _hb_cg_font_release) - { - cg_font = CGFontRetain ((CGFontRef) face->user_data); - } - else - { - hb_blob_t *blob = hb_face_reference_blob (face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - DEBUG_MSG (CORETEXT, face, "Face has empty blob"); - - CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); - if (likely (provider)) - { - cg_font = CGFontCreateWithDataProvider (provider); - if (unlikely (!cg_font)) - DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); - CGDataProviderRelease (provider); - } - } - return cg_font; -} - -static CTFontRef -create_ct_font (CGFontRef cg_font, CGFloat font_size) -{ - CTFontRef ct_font = nullptr; - - /* CoreText does not enable trak table usage / tracking when creating a CTFont - * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems - * to be through the CTFontCreateUIFontForLanguage call. */ - CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font); - if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) || - CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay"))) - { -#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080 -# define kCTFontUIFontSystem kCTFontSystemFontType -# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType -#endif - CTFontUIFontType font_type = kCTFontUIFontSystem; - if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold"))) - font_type = kCTFontUIFontEmphasizedSystem; - - ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr); - CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font); - if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo) - { - CFRelease(ct_font); - ct_font = nullptr; - } - CFRelease (ct_result_name); - } - CFRelease (cg_postscript_name); - - if (!ct_font) - ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr); - - if (unlikely (!ct_font)) { - DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); - return nullptr; - } - - /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter - * bug indicate that the cascade list reconfiguration occasionally causes - * crashes in CoreText on OS X 10.9, thus let's skip this step on older - * operating system versions. Except for the emoji font, where _not_ - * reconfiguring the cascade list causes CoreText crashes. For details, see - * crbug.com/549610 */ - // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { -#pragma GCC diagnostic pop - CFStringRef fontName = CTFontCopyPostScriptName (ct_font); - bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; - CFRelease (fontName); - if (!isEmojiFont) - return ct_font; - } - - CFURLRef original_url = nullptr; -#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - ATSFontRef atsFont; - FSRef fsref; - OSStatus status; - atsFont = CTFontGetPlatformFont (ct_font, NULL); - status = ATSFontGetFileReference (atsFont, &fsref); - if (status == noErr) - original_url = CFURLCreateFromFSRef (NULL, &fsref); -#else - original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute); -#endif - - /* Create font copy with cascade list that has LastResort first; this speeds up CoreText - * font fallback which we don't need anyway. */ - { - CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc (); - CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc); - CFRelease (last_resort_font_desc); - if (new_ct_font) - { - /* The CTFontCreateCopyWithAttributes call fails to stay on the same font - * when reconfiguring the cascade list and may switch to a different font - * when there are fonts that go by the same name, since the descriptor is - * just name and size. - * - * Avoid reconfiguring the cascade lists if the new font is outside the - * system locations that we cannot access from the sandboxed renderer - * process in Blink. This can be detected by the new file URL location - * that the newly found font points to. */ - CFURLRef new_url = nullptr; -#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - atsFont = CTFontGetPlatformFont (new_ct_font, NULL); - status = ATSFontGetFileReference (atsFont, &fsref); - if (status == noErr) - new_url = CFURLCreateFromFSRef (NULL, &fsref); -#else - new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); -#endif - // Keep reconfigured font if URL cannot be retrieved (seems to be the case - // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 - if (!original_url || !new_url || CFEqual (original_url, new_url)) { - CFRelease (ct_font); - ct_font = new_ct_font; - } else { - CFRelease (new_ct_font); - DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed."); - } - if (new_url) - CFRelease (new_url); - } - else - DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed"); - } - - if (original_url) - CFRelease (original_url); - return ct_font; -} - hb_coretext_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { @@ -328,101 +55,6 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data) CFRelease ((CGFontRef) data); } -/** - * hb_coretext_face_create: - * @cg_font: The CGFontRef to work upon - * - * Creates an #hb_face_t face object from the specified - * CGFontRef. - * - * Return value: (transfer full): The new face object - * - * Since: 0.9.10 - */ -hb_face_t * -hb_coretext_face_create (CGFontRef cg_font) -{ - hb_face_t *face = hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release); - hb_face_set_get_table_tags_func (face, _hb_cg_get_table_tags, cg_font, nullptr); - return face; -} - -/** - * hb_coretext_face_create_from_file_or_fail: - * @file_name: A font filename - * @index: The index of the face within the file - * - * Creates an #hb_face_t face object from the specified - * font file and face index. - * - * This is similar in functionality to hb_face_create_from_file_or_fail(), - * but uses the CoreText library for loading the font file. - * - * Return value: (transfer full): The new face object, or `NULL` if - * no face is found at the specified index or the file cannot be read. - * - * Since: 10.1.0 - */ -hb_face_t * -hb_coretext_face_create_from_file_or_fail (const char *file_name, - unsigned int index) -{ - auto url = CFURLCreateFromFileSystemRepresentation (nullptr, - (const UInt8 *) file_name, - strlen (file_name), - false); - if (unlikely (!url)) - return nullptr; - - auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromURL (url); - if (unlikely (!ct_font_desc_array)) - { - CFRelease (url); - return nullptr; - } - auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > index) ? - (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, index) : nullptr; - if (unlikely (!ct_font_desc)) - { - CFRelease (ct_font_desc_array); - CFRelease (url); - return nullptr; - } - CFRelease (url); - auto ct_font = ct_font_desc ? CTFontCreateWithFontDescriptor (ct_font_desc, 0, nullptr) : nullptr; - CFRelease (ct_font_desc_array); - if (unlikely (!ct_font)) - return nullptr; - - auto cg_font = ct_font ? CTFontCopyGraphicsFont (ct_font, nullptr) : nullptr; - CFRelease (ct_font); - if (unlikely (!cg_font)) - return nullptr; - - hb_face_t *face = hb_coretext_face_create (cg_font); - if (unlikely (hb_face_is_immutable (face))) - return nullptr; - - return face; -} - -/** - * hb_coretext_face_get_cg_font: - * @face: The #hb_face_t to work upon - * - * Fetches the CGFontRef associated with an #hb_face_t - * face object - * - * Return value: the CGFontRef found - * - * Since: 0.9.10 - */ -CGFontRef -hb_coretext_face_get_cg_font (hb_face_t *face) -{ - return (CGFontRef) (const void *) face->data.coretext; -} - hb_coretext_font_data_t * _hb_coretext_shaper_font_data_create (hb_font_t *font) @@ -432,7 +64,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) if (unlikely (!face_data)) return nullptr; CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; - CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem); + CGFloat font_size = (CGFloat) (font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE); CTFontRef ct_font = create_ct_font (cg_font, font_size); if (unlikely (!ct_font)) @@ -449,13 +81,13 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - for (unsigned i = 0; i < font->num_coords; i++) + unsigned count = font->num_coords; + for (unsigned i = 0; i < count; i++) { - if (font->coords[i] == 0.) continue; - hb_ot_var_axis_info_t info; unsigned int c = 1; hb_ot_var_get_axis_infos (font->face, i, &c, &info); + float v = hb_clamp (font->design_coords[i], info.min_value, info.max_value); CFNumberRef tag_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag); @@ -491,64 +123,6 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data) CFRelease ((CTFontRef) data); } -/** - * hb_coretext_font_create: - * @ct_font: The CTFontRef to work upon - * - * Creates an #hb_font_t font object from the specified - * CTFontRef. - * - * The created font uses the default font functions implemented - * navitely by HarfBuzz. If you want to use the CoreText font functions - * instead (rarely needed), you can do so by calling - * by hb_coretext_font_set_funcs(). - * - * Return value: (transfer full): The new font object - * - * Since: 1.7.2 - **/ -hb_font_t * -hb_coretext_font_create (CTFontRef ct_font) -{ - CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr); - hb_face_t *face = hb_coretext_face_create (cg_font); - CFRelease (cg_font); - hb_font_t *font = hb_font_create (face); - hb_face_destroy (face); - - if (unlikely (hb_object_is_immutable (font))) - return font; - - hb_font_set_ptem (font, CTFontGetSize (ct_font)); - - /* Let there be dragons here... */ - font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); - - // https://github.com/harfbuzz/harfbuzz/pull/4895#issuecomment-2408471254 - //hb_coretext_font_set_funcs (font); - - return font; -} - -/** - * hb_coretext_font_get_ct_font: - * @font: #hb_font_t to work upon - * - * Fetches the CTFontRef associated with the specified - * #hb_font_t font object. - * - * Return value: the CTFontRef found - * - * Since: 0.9.10 - */ -CTFontRef -hb_coretext_font_get_ct_font (hb_font_t *font) -{ - CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext; - return ct_font ? (CTFontRef) ct_font : nullptr; -} - - /* * shaper */ @@ -618,14 +192,14 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will * continue pointing to B2 even though B2 was merged into B1's * cluster... */ - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (HB_BUFFER_CLUSTER_LEVEL_IS_GRAPHEMES (buffer->cluster_level)) { hb_unicode_funcs_t *unicode = buffer->unicode; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint))) - buffer->merge_clusters (i - 1, i + 1); + buffer->merge_grapheme_clusters (i - 1, i + 1); } hb_vector_t range_records; @@ -982,7 +556,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); unsigned int num_runs = CFArrayGetCount (glyph_runs); - DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs); + DEBUG_MSG (CORETEXT, nullptr, "Num runs: %u", num_runs); buffer->len = 0; uint32_t status_or = 0; @@ -1264,7 +838,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, * or the native OT backend, only that the cluster indices will be * monotonic in the output buffer. */ if (count > 1 && (status_or & kCTRunStatusNonMonotonic) && - buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + HB_BUFFER_CLUSTER_LEVEL_IS_MONOTONE (buffer->cluster_level)) { hb_glyph_info_t *info = buffer->info; if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) diff --git a/thirdparty/harfbuzz/upstream/hb-coretext.cc b/thirdparty/harfbuzz/upstream/hb-coretext.cc new file mode 100644 index 000000000..94b058828 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-coretext.cc @@ -0,0 +1,581 @@ +/* + * Copyright © 2012,2013 Mozilla Foundation. + * Copyright © 2012,2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_CORETEXT + +#include "hb-shaper-impl.hh" + +#include "hb-coretext.hh" + + +/** + * SECTION:hb-coretext + * @title: hb-coretext + * @short_description: CoreText integration + * @include: hb-coretext.h + * + * Functions for using HarfBuzz with the CoreText fonts. + **/ + +static void +release_table_data (void *user_data) +{ + CFDataRef cf_data = reinterpret_cast (user_data); + CFRelease(cf_data); +} + +static hb_blob_t * +_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + CGFontRef cg_font = reinterpret_cast (user_data); + CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); + if (unlikely (!cf_data)) + return nullptr; + + const char *data = reinterpret_cast (CFDataGetBytePtr (cf_data)); + const size_t length = CFDataGetLength (cf_data); + if (!data || !length) + { + CFRelease (cf_data); + return nullptr; + } + + return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, + reinterpret_cast (const_cast<__CFData *> (cf_data)), + release_table_data); +} + +static unsigned +_hb_cg_get_table_tags (const hb_face_t *face HB_UNUSED, + unsigned int start_offset, + unsigned int *table_count, + hb_tag_t *table_tags, + void *user_data) +{ + CGFontRef cg_font = reinterpret_cast (user_data); + + CTFontRef ct_font = create_ct_font (cg_font, (CGFloat) HB_CORETEXT_DEFAULT_FONT_SIZE); + + auto arr = CTFontCopyAvailableTables (ct_font, kCTFontTableOptionNoOptions); + + unsigned population = (unsigned) CFArrayGetCount (arr); + unsigned end_offset; + + if (!table_count) + goto done; + + if (unlikely (start_offset >= population)) + { + *table_count = 0; + goto done; + } + + end_offset = start_offset + *table_count; + if (unlikely (end_offset < start_offset)) + { + *table_count = 0; + goto done; + } + end_offset= hb_min (end_offset, (unsigned) population); + + *table_count = end_offset - start_offset; + for (unsigned i = start_offset; i < end_offset; i++) + { + CTFontTableTag tag = (CTFontTableTag)(uintptr_t) CFArrayGetValueAtIndex (arr, i); + table_tags[i - start_offset] = tag; + } + +done: + CFRelease (arr); + CFRelease (ct_font); + return population; +} + +static void +_hb_cg_font_release (void *data) +{ + CGFontRelease ((CGFontRef) data); +} + + +static CTFontDescriptorRef +get_last_resort_font_desc () +{ + // TODO Handle allocation failures? + CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); + CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, + (const void **) &last_resort, + 1, + &kCFTypeArrayCallBacks); + CFRelease (last_resort); + CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, + (const void **) &kCTFontCascadeListAttribute, + (const void **) &cascade_list, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease (cascade_list); + + CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); + CFRelease (attributes); + return font_desc; +} + +static void +release_data (void *info, const void *data, size_t size) +{ + assert (hb_blob_get_length ((hb_blob_t *) info) == size && + hb_blob_get_data ((hb_blob_t *) info, nullptr) == data); + + hb_blob_destroy ((hb_blob_t *) info); +} + +CGFontRef +create_cg_font (CFArrayRef ct_font_desc_array, unsigned int named_instance_index) +{ + if (named_instance_index == 0) + { + // Default instance. We don't know which one is it. Return the first one. + // We will set the correct variations on it later. + } + else + named_instance_index--; + auto ct_font_desc = (CFArrayGetCount (ct_font_desc_array) > (CFIndex) named_instance_index) ? + (CTFontDescriptorRef) CFArrayGetValueAtIndex (ct_font_desc_array, (CFIndex) named_instance_index) : nullptr; + if (unlikely (!ct_font_desc)) + { + CFRelease (ct_font_desc_array); + return nullptr; + } + auto ct_font = ct_font_desc ? CTFontCreateWithFontDescriptor (ct_font_desc, 0, nullptr) : nullptr; + CFRelease (ct_font_desc_array); + if (unlikely (!ct_font)) + return nullptr; + + auto cg_font = ct_font ? CTFontCopyGraphicsFont (ct_font, nullptr) : nullptr; + CFRelease (ct_font); + + return cg_font; +} + +CGFontRef +create_cg_font (hb_blob_t *blob, unsigned int index) +{ + hb_blob_make_immutable (blob); + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + DEBUG_MSG (CORETEXT, blob, "Empty blob"); + + unsigned ttc_index = index & 0xFFFF; + unsigned named_instance_index = index >> 16; + + if (ttc_index != 0) + { + DEBUG_MSG (CORETEXT, blob, "TTC index %u not supported", ttc_index); + return nullptr; // CoreText does not support TTCs + } + + if (unlikely (named_instance_index != 0)) + { + // https://github.com/harfbuzz/harfbuzz/issues/5300 + // https://github.com/harfbuzz/harfbuzz/issues/5354 +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || \ + (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= 110000) || \ + (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= 40000) || \ + (defined(__MACCATALYST_VERSION_MIN_REQUIRED) && __MACCATALYST_VERSION_MIN_REQUIRED >= 130100) || \ + (defined(__VISION_OS_VERSION_MIN_REQUIRED) && __VISION_OS_VERSION_MIN_REQUIRED >= 10000) + auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromData (CFDataCreate (kCFAllocatorDefault, (const UInt8 *) blob_data, blob_length)); + if (likely (ct_font_desc_array)) + return create_cg_font (ct_font_desc_array, named_instance_index); +#endif + return nullptr; + } + + hb_blob_reference (blob); + CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); + CGFontRef cg_font = nullptr; + if (likely (provider)) + { + cg_font = CGFontCreateWithDataProvider (provider); + if (unlikely (!cg_font)) + DEBUG_MSG (CORETEXT, blob, "CGFontCreateWithDataProvider() failed"); + CGDataProviderRelease (provider); + } + return cg_font; +} + +CGFontRef +create_cg_font (hb_face_t *face) +{ + CGFontRef cg_font = nullptr; + if (face->destroy == _hb_cg_font_release) + cg_font = CGFontRetain ((CGFontRef) face->user_data); + else + { + hb_blob_t *blob = hb_face_reference_blob (face); + cg_font = create_cg_font (blob, face->index); + hb_blob_destroy (blob); + } + return cg_font; +} + +CTFontRef +create_ct_font (CGFontRef cg_font, CGFloat font_size) +{ + CTFontRef ct_font = nullptr; + + /* CoreText does not enable trak table usage / tracking when creating a CTFont + * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems + * to be through the CTFontCreateUIFontForLanguage call. */ + CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font); + if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) || + CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay"))) + { +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1080 +# define kCTFontUIFontSystem kCTFontSystemFontType +# define kCTFontUIFontEmphasizedSystem kCTFontEmphasizedSystemFontType +#endif + CTFontUIFontType font_type = kCTFontUIFontSystem; + if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold"))) + font_type = kCTFontUIFontEmphasizedSystem; + + ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr); + CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font); + if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo) + { + CFRelease(ct_font); + ct_font = nullptr; + } + CFRelease (ct_result_name); + } + CFRelease (cg_postscript_name); + + if (!ct_font) + ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr); + + if (unlikely (!ct_font)) { + DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); + return nullptr; + } + + /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter + * bug indicate that the cascade list reconfiguration occasionally causes + * crashes in CoreText on OS X 10.9, thus let's skip this step on older + * operating system versions. Except for the emoji font, where _not_ + * reconfiguring the cascade list causes CoreText crashes. For details, see + * crbug.com/549610 */ + // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { +#pragma GCC diagnostic pop + CFStringRef fontName = CTFontCopyPostScriptName (ct_font); + bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; + CFRelease (fontName); + if (!isEmojiFont) + return ct_font; + } + + CFURLRef original_url = nullptr; +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + ATSFontRef atsFont; + FSRef fsref; + OSStatus status; + atsFont = CTFontGetPlatformFont (ct_font, NULL); + status = ATSFontGetFileReference (atsFont, &fsref); + if (status == noErr) + original_url = CFURLCreateFromFSRef (NULL, &fsref); +#else + original_url = (CFURLRef) CTFontCopyAttribute (ct_font, kCTFontURLAttribute); +#endif + + /* Create font copy with cascade list that has LastResort first; this speeds up CoreText + * font fallback which we don't need anyway. */ + { + CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc (); + CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc); + CFRelease (last_resort_font_desc); + if (new_ct_font) + { + /* The CTFontCreateCopyWithAttributes call fails to stay on the same font + * when reconfiguring the cascade list and may switch to a different font + * when there are fonts that go by the same name, since the descriptor is + * just name and size. + * + * Avoid reconfiguring the cascade lists if the new font is outside the + * system locations that we cannot access from the sandboxed renderer + * process in Blink. This can be detected by the new file URL location + * that the newly found font points to. */ + CFURLRef new_url = nullptr; +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + atsFont = CTFontGetPlatformFont (new_ct_font, NULL); + status = ATSFontGetFileReference (atsFont, &fsref); + if (status == noErr) + new_url = CFURLCreateFromFSRef (NULL, &fsref); +#else + new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); +#endif + // Keep reconfigured font if URL cannot be retrieved (seems to be the case + // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 + if (!original_url || !new_url || CFEqual (original_url, new_url)) { + CFRelease (ct_font); + ct_font = new_ct_font; + } else { + CFRelease (new_ct_font); + DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed."); + } + if (new_url) + CFRelease (new_url); + } + else + DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed"); + } + + if (original_url) + CFRelease (original_url); + return ct_font; +} + +/** + * hb_coretext_face_create: + * @cg_font: The CGFontRef to work upon + * + * Creates an #hb_face_t face object from the specified + * CGFontRef. + * + * Return value: (transfer full): The new face object + * + * Since: 0.9.10 + */ +hb_face_t * +hb_coretext_face_create (CGFontRef cg_font) +{ + hb_face_t *face = hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release); + hb_face_set_get_table_tags_func (face, _hb_cg_get_table_tags, cg_font, nullptr); + return face; +} + +/** + * hb_coretext_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * Creates an #hb_face_t face object from the specified + * font file and face index. + * + * This is similar in functionality to hb_face_create_from_file_or_fail(), + * but uses the CoreText library for loading the font file. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 10.1.0 + */ +hb_face_t * +hb_coretext_face_create_from_file_or_fail (const char *file_name, + unsigned int index) +{ + auto url = CFURLCreateFromFileSystemRepresentation (nullptr, + (const UInt8 *) file_name, + strlen (file_name), + false); + if (unlikely (!url)) + return nullptr; + + auto ct_font_desc_array = CTFontManagerCreateFontDescriptorsFromURL (url); + if (unlikely (!ct_font_desc_array)) + { + CFRelease (url); + return nullptr; + } + + unsigned ttc_index = index & 0xFFFF; + unsigned named_instance_index = index >> 16; + + if (ttc_index != 0) + { + DEBUG_MSG (CORETEXT, nullptr, "TTC index %u not supported", ttc_index); + return nullptr; // CoreText does not support TTCs + } + + auto cg_font = create_cg_font (ct_font_desc_array, named_instance_index); + CFRelease (url); + + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + if (unlikely (hb_face_is_immutable (face))) + return nullptr; + + hb_face_set_index (face, index); + + return face; +} + +/** + * hb_coretext_face_create_from_blob_or_fail: + * @blob: A blob containing the font data + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the CoreText library for loading the font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the blob cannot be read. + * + * Since: 11.0.0 + */ +hb_face_t * +hb_coretext_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + auto cg_font = create_cg_font (blob, index); + if (unlikely (!cg_font)) + return nullptr; + + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + if (unlikely (hb_face_is_immutable (face))) + return nullptr; + + hb_face_set_index (face, index); + + return face; +} + +/** + * hb_coretext_face_get_cg_font: + * @face: The #hb_face_t to work upon + * + * Fetches the CGFontRef associated with an #hb_face_t + * face object + * + * Return value: the CGFontRef found + * + * Since: 0.9.10 + */ +CGFontRef +hb_coretext_face_get_cg_font (hb_face_t *face) +{ + return (CGFontRef) (const void *) face->data.coretext; +} + +/** + * hb_coretext_font_create: + * @ct_font: The CTFontRef to work upon + * + * Creates an #hb_font_t font object from the specified + * CTFontRef. + * + * The created font uses the default font functions implemented + * natively by HarfBuzz. If you want to use the CoreText font functions + * instead (rarely needed), you can do so by calling + * by hb_coretext_font_set_funcs(). + * + * Return value: (transfer full): The new font object + * + * Since: 1.7.2 + **/ +hb_font_t * +hb_coretext_font_create (CTFontRef ct_font) +{ + CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr); + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + hb_font_t *font = hb_font_create (face); + hb_face_destroy (face); + + if (unlikely (hb_object_is_immutable (font))) + return font; + + hb_font_set_ptem (font, CTFontGetSize (ct_font)); + + /* Copy font variations */ + CFDictionaryRef variations = CTFontCopyVariation (ct_font); + if (variations) + { + hb_vector_t vars; + hb_vector_t keys; + hb_vector_t values; + + CFIndex count = CFDictionaryGetCount (variations); + if (unlikely (!vars.alloc_exact (count) || !keys.resize_exact (count) || !values.resize_exact (count))) + goto done; + + // Fetch them one by one and collect in a vector of our own. + CFDictionaryGetKeysAndValues (variations, keys.arrayZ, values.arrayZ); + for (CFIndex i = 0; i < count; i++) + { + int tag; + float value; + CFNumberGetValue ((CFNumberRef) keys.arrayZ[i], kCFNumberIntType, &tag); + CFNumberGetValue ((CFNumberRef) values.arrayZ[i], kCFNumberFloatType, &value); + + hb_variation_t var = {tag, value}; + vars.push (var); + } + hb_font_set_variations (font, vars.arrayZ, vars.length); + +done: + CFRelease (variations); + } + + /* Let there be dragons here... */ + font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); + + // https://github.com/harfbuzz/harfbuzz/pull/4895#issuecomment-2408471254 + //hb_coretext_font_set_funcs (font); + + return font; +} + +/** + * hb_coretext_font_get_ct_font: + * @font: #hb_font_t to work upon + * + * Fetches the CTFontRef associated with the specified + * #hb_font_t font object. + * + * Return value: the CTFontRef found + * + * Since: 0.9.10 + */ +CTFontRef +hb_coretext_font_get_ct_font (hb_font_t *font) +{ + return (CTFontRef) (const void *) font->data.coretext; +} + + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-coretext.h b/thirdparty/harfbuzz/upstream/hb-coretext.h index 3626f1c12..a7c7fee76 100644 --- a/thirdparty/harfbuzz/upstream/hb-coretext.h +++ b/thirdparty/harfbuzz/upstream/hb-coretext.h @@ -84,6 +84,10 @@ HB_EXTERN hb_face_t * hb_coretext_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_coretext_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + HB_EXTERN hb_font_t * hb_coretext_font_create (CTFontRef ct_font); diff --git a/thirdparty/harfbuzz/upstream/hb-gobject-enums.h.tmpl b/thirdparty/harfbuzz/upstream/hb-coretext.hh similarity index 64% rename from thirdparty/harfbuzz/upstream/hb-gobject-enums.h.tmpl rename to thirdparty/harfbuzz/upstream/hb-coretext.hh index 6dd98f7fe..5f58d2abf 100644 --- a/thirdparty/harfbuzz/upstream/hb-gobject-enums.h.tmpl +++ b/thirdparty/harfbuzz/upstream/hb-coretext.hh @@ -1,6 +1,6 @@ -/*** BEGIN file-header ***/ /* - * Copyright (C) 2013 Google, Inc. + * Copyright © 2012,2013 Mozilla Foundation. + * Copyright © 2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -22,35 +22,32 @@ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * + * Mozilla Author(s): Jonathan Kew * Google Author(s): Behdad Esfahbod */ -#if !defined(HB_GOBJECT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) -#error "Include instead." -#endif -#ifndef HB_GOBJECT_ENUMS_H -#define HB_GOBJECT_ENUMS_H +#ifndef HB_CORETEXT_HH +#define HB_CORETEXT_HH -#include "hb.h" +#include "hb.hh" -#include +#include "hb-coretext.h" -HB_BEGIN_DECLS +#include "hb-aat-layout.hh" -/*** END file-header ***/ +HB_INTERNAL CGFontRef +create_cg_font (CFArrayRef ct_font_desc_array, unsigned int index); -/*** BEGIN value-header ***/ -HB_EXTERN GType -@enum_name@_get_type (void) G_GNUC_CONST; -#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) +HB_INTERNAL CGFontRef +create_cg_font (hb_blob_t *blob, unsigned int index); -/*** END value-header ***/ +HB_INTERNAL CGFontRef +create_cg_font (hb_face_t *face); -/*** BEGIN file-tail ***/ +HB_INTERNAL CTFontRef +create_ct_font (CGFontRef cg_font, CGFloat font_size); -HB_END_DECLS -#endif /* HB_GOBJECT_ENUMS_H */ -/*** END file-tail ***/ +#endif /* HB_CORETEXT_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-cplusplus.hh b/thirdparty/harfbuzz/upstream/hb-cplusplus.hh index b6b5c8f78..14944eeea 100644 --- a/thirdparty/harfbuzz/upstream/hb-cplusplus.hh +++ b/thirdparty/harfbuzz/upstream/hb-cplusplus.hh @@ -138,52 +138,56 @@ struct vtable_t static constexpr auto get_user_data = _get_user_data; }; -#define HB_DEFINE_VTABLE(name) \ +#define HB_DEFINE_VTABLE(name, empty) \ template<> \ struct vtable \ : vtable_t {} -HB_DEFINE_VTABLE (buffer); -HB_DEFINE_VTABLE (blob); -HB_DEFINE_VTABLE (face); -HB_DEFINE_VTABLE (font); -HB_DEFINE_VTABLE (font_funcs); -HB_DEFINE_VTABLE (map); -HB_DEFINE_VTABLE (set); -HB_DEFINE_VTABLE (shape_plan); -HB_DEFINE_VTABLE (unicode_funcs); -HB_DEFINE_VTABLE (draw_funcs); -HB_DEFINE_VTABLE (paint_funcs); - -#undef HB_DEFINE_VTABLE +HB_DEFINE_VTABLE (buffer, &hb_buffer_get_empty); +HB_DEFINE_VTABLE (blob, &hb_blob_get_empty); +HB_DEFINE_VTABLE (face, &hb_face_get_empty); +HB_DEFINE_VTABLE (font, &hb_font_get_empty); +HB_DEFINE_VTABLE (font_funcs, &hb_font_funcs_get_empty); +HB_DEFINE_VTABLE (map, &hb_map_get_empty); +HB_DEFINE_VTABLE (set, &hb_set_get_empty); +HB_DEFINE_VTABLE (shape_plan, &hb_shape_plan_get_empty); +HB_DEFINE_VTABLE (unicode_funcs, &hb_unicode_funcs_get_empty); +HB_DEFINE_VTABLE (draw_funcs, &hb_draw_funcs_get_empty); +HB_DEFINE_VTABLE (paint_funcs, &hb_paint_funcs_get_empty); #ifdef HB_SUBSET_H -#define HB_DEFINE_VTABLE(name) \ - template<> \ - struct vtable \ - : vtable_t {} +HB_DEFINE_VTABLE (subset_input, nullptr); +HB_DEFINE_VTABLE (subset_plan, nullptr); +#endif -HB_DEFINE_VTABLE (subset_input); -HB_DEFINE_VTABLE (subset_plan); -#undef HB_DEFINE_VTABLE +#ifdef HB_RASTER_H + +HB_DEFINE_VTABLE (raster_image, nullptr); +HB_DEFINE_VTABLE (raster_draw, nullptr); +HB_DEFINE_VTABLE (raster_paint, nullptr); #endif +#ifdef HB_VECTOR_H + +HB_DEFINE_VTABLE (vector_draw, nullptr); +HB_DEFINE_VTABLE (vector_paint, nullptr); + +#endif + +#undef HB_DEFINE_VTABLE + + } // namespace hb /* Workaround for GCC < 7, see: diff --git a/thirdparty/harfbuzz/upstream/hb-debug.hh b/thirdparty/harfbuzz/upstream/hb-debug.hh index 559db4067..dd7343cd5 100644 --- a/thirdparty/harfbuzz/upstream/hb-debug.hh +++ b/thirdparty/harfbuzz/upstream/hb-debug.hh @@ -37,48 +37,6 @@ #endif -/* - * Global runtime options. - */ - -struct hb_options_t -{ - bool unused : 1; /* In-case sign bit is here. */ - bool initialized : 1; - bool uniscribe_bug_compatible : 1; -}; - -union hb_options_union_t { - int i; - hb_options_t opts; -}; -static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), ""); - -HB_INTERNAL void -_hb_options_init (); - -extern HB_INTERNAL hb_atomic_int_t _hb_options; - -static inline hb_options_t -hb_options () -{ -#ifdef HB_NO_GETENV - return hb_options_t (); -#endif - /* Make a local copy, so we can access bitfield threadsafely. */ - hb_options_union_t u; - u.i = _hb_options; - - if (unlikely (!u.i)) - { - _hb_options_init (); - u.i = _hb_options; - } - - return u.opts; -} - - /* * Debug output (needs enabling at compile time.) */ @@ -394,6 +352,10 @@ struct hb_no_trace_t { #define HB_DEBUG_WASM (HB_DEBUG+0) #endif +#ifndef HB_DEBUG_KBTS +#define HB_DEBUG_KBTS (HB_DEBUG+0) +#endif + /* * With tracing. */ @@ -484,7 +446,7 @@ struct hb_no_trace_t { #ifndef HB_BUFFER_MESSAGE_MORE -#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1) +#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+0) #endif diff --git a/thirdparty/harfbuzz/upstream/hb-decycler.hh b/thirdparty/harfbuzz/upstream/hb-decycler.hh new file mode 100644 index 000000000..95b961027 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-decycler.hh @@ -0,0 +1,164 @@ +/* + * Copyright © 2025 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_DECYCLER_HH +#define HB_DECYCLER_HH + +#include "hb.hh" + +/* + * hb_decycler_t is an efficient cycle detector for graph traversal. + * It's a simple tortoise-and-hare algorithm with a twist: it's + * designed to detect cycles while traversing a graph in a DFS manner, + * instead of just a linked list. + * + * For Floyd's tortoise and hare algorithm, see: + * https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare + * + * hb_decycler_t is O(n) in the number of nodes in the DFS traversal + * if there are no cycles. Unlike Floyd's algorithm, hb_decycler_t + * can be used in a DFS traversal, where the graph is not a simple + * linked list, but a tree with possible cycles. Like Floyd's algorithm, + * it is constant-memory (~three pointers). + * + * The decycler works by creating an implicit linked-list on the stack, + * of the path from the root to the current node, and apply Floyd's + * algorithm on that list as it goes. + * + * The decycler is malloc-free, and as such, much faster to use than a + * hb_set_t or hb_map_t equivalent. + * + * The decycler detects cycles in the graph *eventually*, not *immediately*. + * That is, it may not detect a cycle until the cycle is fully traversed, + * even multiple times. See Floyd's algorithm analysis for details. + * + * The implementation saves a pointer storage on the stack by combining + * this->u.decycler and this->u.next into a union. This is possible because + * at any point we only need one of those values. The invariant is that + * after construction, and before destruction, of a node, the u.decycler + * field is always valid. The u.next field is only valid when the node is + * in the traversal path, parent to another node. + * + * There are three method's: + * + * - hb_decycler_node_t() constructor: Creates a new node in the traversal. + * The constructor takes a reference to the decycler object and inserts + * itself as the latest node in the traversal path, by advancing the hare + * pointer, and for every other descent, advancing the tortoise pointer. + * + * - ~hb_decycler_node_t() destructor: Restores the decycler object to its + * previous state by removing the node from the traversal path. + * + * - bool visit(uintptr_t value): Called on every node in the graph. Returns + * true if the node is not part of a cycle, and false if it is. The value + * parameter is used to detect cycles. It's the caller's responsibility + * to ensure that the value is unique for each node in the graph. + * The cycle detection is as simple as comparing the value to the value + * held by the tortoise pointer, which is the Floyd's algorithm. + * + * For usage examples see test-decycler.cc. + */ + +struct hb_decycler_node_t; + +struct hb_decycler_t +{ + friend struct hb_decycler_node_t; + + private: + bool tortoise_awake = false; + hb_decycler_node_t *tortoise = nullptr; + hb_decycler_node_t *hare = nullptr; +}; + +struct hb_decycler_node_t +{ + hb_decycler_node_t (hb_decycler_t &decycler) + { + u.decycler = &decycler; + + decycler.tortoise_awake = !decycler.tortoise_awake; + + if (!decycler.tortoise) + { + // First node. + assert (decycler.tortoise_awake); + assert (!decycler.hare); + decycler.tortoise = decycler.hare = this; + return; + } + + if (decycler.tortoise_awake) + decycler.tortoise = decycler.tortoise->u.next; // Time to move. + + this->prev = decycler.hare; + decycler.hare->u.next = this; + decycler.hare = this; + } + + ~hb_decycler_node_t () + { + hb_decycler_t &decycler = *u.decycler; + + // Inverse of the constructor. + + assert (decycler.hare == this); + decycler.hare = prev; + if (prev) + prev->u.decycler = &decycler; + + assert (decycler.tortoise); + if (decycler.tortoise_awake) + decycler.tortoise = decycler.tortoise->prev; + + decycler.tortoise_awake = !decycler.tortoise_awake; + } + + bool visit (uintptr_t value_) + { + value = value_; + + hb_decycler_t &decycler = *u.decycler; + + if (decycler.tortoise == this) + return true; // First node; not a cycle. + + if (decycler.tortoise->value == value) + return false; // Cycle detected. + + return true; + } + + private: + union { + hb_decycler_t *decycler; + hb_decycler_node_t *next; + } u = {nullptr}; + hb_decycler_node_t *prev = nullptr; + uintptr_t value = 0; +}; + +#endif /* HB_DECYCLER_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-deprecated.h b/thirdparty/harfbuzz/upstream/hb-deprecated.h index ad19f9a3e..849869f39 100644 --- a/thirdparty/harfbuzz/upstream/hb-deprecated.h +++ b/thirdparty/harfbuzz/upstream/hb-deprecated.h @@ -275,6 +275,48 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data); +/** + * hb_font_draw_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @draw_funcs: The draw functions to send the shape data to + * @draw_data: The data accompanying the draw functions + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 7.0.0 + * Deprecated: 11.2.0: Use hb_font_draw_glyph_func_or_fail_t instead. + **/ +typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data); + +/** + * hb_font_paint_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @paint_funcs: The paint functions to use + * @paint_data: The data accompanying the paint functions + * @palette_index: The color palette to use + * @foreground: The foreground color + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * Since: 7.0.0 + * Deprecated: 11.2.0: Use hb_font_paint_glyph_or_fail_func_t instead. + */ +typedef hb_bool_t (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data); + /** * hb_font_funcs_set_glyph_shape_func: * @ffuncs: A font-function structure @@ -288,13 +330,49 @@ typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data * Since: 4.0.0 * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead **/ -HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_func) +HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_or_fail_func) HB_EXTERN void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy); -HB_DEPRECATED_FOR (hb_font_draw_glyph) +/** + * hb_font_funcs_set_draw_glyph_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_draw_glyph_func_t. + * + * Since: 7.0.0 + * Deprecated: 11.2.0: Use hb_font_funcs_set_draw_glyph_or_fail_func instead. + **/ +HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_or_fail_func) +HB_EXTERN void +hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_paint_glyph_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is no longer needed + * + * Sets the implementation function for #hb_font_paint_glyph_func_t. + * + * Since: 7.0.0 + * Deprecated: 11.2.0: Use hb_font_funcs_set_paint_glyph_or_fail_func() instead. + */ +HB_DEPRECATED_FOR (hb_font_funcs_set_paint_glyph_or_fail_func) +HB_EXTERN void +hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + +HB_DEPRECATED_FOR (hb_font_draw_glyph_or_fail) HB_EXTERN void hb_font_get_glyph_shape (hb_font_t *font, hb_codepoint_t glyph, diff --git a/thirdparty/harfbuzz/upstream/hb-directwrite-font.cc b/thirdparty/harfbuzz/upstream/hb-directwrite-font.cc new file mode 100644 index 000000000..2ebda19bf --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-directwrite-font.cc @@ -0,0 +1,392 @@ +/* + * Copyright © 2025 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_DIRECTWRITE + +#include "hb-directwrite.h" + +#include + +#include "hb-draw.hh" +#include "hb-font.hh" +#include "hb-machinery.hh" + +#define MAX_GLYPHS 256u + +static unsigned int +hb_directwrite_get_nominal_glyphs (hb_font_t *font, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + for (unsigned i = 0; i < count;) + { + UINT32 unicodes[MAX_GLYPHS]; + UINT16 gids[MAX_GLYPHS]; + + unsigned n = hb_min (MAX_GLYPHS, count - i); + + for (unsigned j = 0; j < n; j++) + { + unicodes[j] = *first_unicode; + first_unicode = &StructAtOffset (first_unicode, unicode_stride); + } + + if (!SUCCEEDED (dw_face->GetGlyphIndices (unicodes, n, gids))) + return i; + + for (unsigned j = 0; j < n; j++) + { + if (!gids[j]) + return i + j; + *first_glyph = gids[j]; + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + + i += n; + } + + return count; +} + +static hb_bool_t +hb_directwrite_get_font_h_extents (hb_font_t *font, + void *font_data HB_UNUSED, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + DWRITE_FONT_METRICS dw_metrics; + dw_face->GetMetrics (&dw_metrics); + + metrics->ascender = font->em_scale_y (dw_metrics.ascent); + metrics->descender = -font->em_scale_y (dw_metrics.descent); + metrics->line_gap = font->em_scale_y (dw_metrics.lineGap); + + return true; +} + +static void +hb_directwrite_get_glyph_h_advances (hb_font_t* font, + void* font_data HB_UNUSED, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + IDWriteFontFace1 *dw_face1 = nullptr; + dw_face->QueryInterface (__uuidof(IDWriteFontFace1), (void**)&dw_face1); + assert (dw_face1); + + unsigned int num_glyphs = font->face->get_num_glyphs (); + + for (unsigned i = 0; i < count;) + { + UINT16 gids[MAX_GLYPHS]; + INT32 advances[MAX_GLYPHS]; + + unsigned n = hb_min (MAX_GLYPHS, count - i); + + for (unsigned j = 0; j < n; j++) + { + gids[j] = *first_glyph; + advances[j] = 0; + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + dw_face1->GetDesignGlyphAdvances (n, gids, advances, false); + for (unsigned j = 0; j < n; j++) + { + // https://github.com/harfbuzz/harfbuzz/issues/5319 + auto advance = gids[j] < num_glyphs ? advances[j] : 0; + *first_advance = font->em_scale_x (advance); + first_advance = &StructAtOffset (first_advance, advance_stride); + } + + i += n; + } +} + +#ifndef HB_NO_VERTICAL + +static void +hb_directwrite_get_glyph_v_advances (hb_font_t* font, + void* font_data HB_UNUSED, + unsigned count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_advance, + unsigned advance_stride, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + IDWriteFontFace1 *dw_face1 = nullptr; + dw_face->QueryInterface (__uuidof(IDWriteFontFace1), (void**)&dw_face1); + assert (dw_face1); + + for (unsigned i = 0; i < count;) + { + UINT16 gids[MAX_GLYPHS]; + INT32 advances[MAX_GLYPHS]; + + unsigned n = hb_min (MAX_GLYPHS, count - i); + + for (unsigned j = 0; j < n; j++) + { + gids[j] = *first_glyph; + advances[j] = 0; + first_glyph = &StructAtOffset (first_glyph, glyph_stride); + } + dw_face1->GetDesignGlyphAdvances (n, gids, advances, true); + for (unsigned j = 0; j < n; j++) + { + *first_advance = -font->em_scale_y (advances[j]); + first_advance = &StructAtOffset (first_advance, advance_stride); + } + + i += n; + } +} + +static hb_bool_t +hb_directwrite_get_glyph_v_origin (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + UINT16 gid = glyph; + DWRITE_GLYPH_METRICS metrics; + + if (FAILED (dw_face->GetDesignGlyphMetrics (&gid, 1, &metrics))) + return false; + + *x = font->em_scale_x (metrics.advanceWidth / 2); + *y = font->em_scale_y (metrics.verticalOriginY); // Untested + + return true; +} +#endif + +static hb_bool_t +hb_directwrite_get_glyph_extents (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + void *user_data HB_UNUSED) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + UINT16 gid = glyph; + DWRITE_GLYPH_METRICS metrics; + + if (FAILED (dw_face->GetDesignGlyphMetrics (&gid, 1, &metrics))) + return false; + + extents->x_bearing = font->em_scale_x (metrics.leftSideBearing); + extents->y_bearing = font->em_scale_y (metrics.verticalOriginY - metrics.topSideBearing); + extents->width = font->em_scale_x (metrics.advanceWidth - metrics.rightSideBearing) - extents->x_bearing; + extents->height = font->em_scale_y (metrics.verticalOriginY - metrics.advanceHeight + metrics.bottomSideBearing) - extents->y_bearing; // Magic + + return true; +} + + +#ifndef HB_NO_DRAW + +class GeometrySink : public IDWriteGeometrySink +{ + hb_font_t *font; + hb_draw_session_t drawing; + +public: + GeometrySink(hb_font_t *font, + hb_draw_funcs_t *draw_funcs, + void *draw_data) + : font (font), drawing ({draw_funcs, draw_data}) {} + + virtual ~GeometrySink() {} + + HRESULT STDMETHODCALLTYPE Close() override { return S_OK; } + void STDMETHODCALLTYPE SetFillMode(D2D1_FILL_MODE) override {} + void STDMETHODCALLTYPE SetSegmentFlags(D2D1_PATH_SEGMENT) override {} + + IFACEMETHOD(QueryInterface)(REFIID, void **) override { return E_NOINTERFACE; } + IFACEMETHOD_(ULONG, AddRef)() override { return 1; } + IFACEMETHOD_(ULONG, Release)() override { return 1; } + + void STDMETHODCALLTYPE BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN) override + { + drawing.move_to (font->em_scalef_x (startPoint.x), -font->em_scalef_y (startPoint.y)); + } + + void STDMETHODCALLTYPE AddBeziers(const D2D1_BEZIER_SEGMENT *beziers, UINT beziersCount) override + { + for (unsigned i = 0; i < beziersCount; ++i) + drawing.cubic_to (font->em_scalef_x (beziers[i].point1.x), -font->em_scalef_y (beziers[i].point1.y), + font->em_scalef_x (beziers[i].point2.x), -font->em_scalef_y (beziers[i].point2.y), + font->em_scalef_x (beziers[i].point3.x), -font->em_scalef_y (beziers[i].point3.y)); + } + + void STDMETHODCALLTYPE AddLines(const D2D1_POINT_2F *points, UINT pointsCount) override + { + for (unsigned i = 0; i < pointsCount; ++i) + drawing.line_to (font->em_scalef_x (points[i].x), -font->em_scalef_y (points[i].y)); + } + + void STDMETHODCALLTYPE EndFigure(D2D1_FIGURE_END) override + { + drawing.close_path (); + } +}; + +static hb_bool_t +hb_directwrite_draw_glyph_or_fail (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + + GeometrySink sink (font, draw_funcs, draw_data); + UINT16 gid = static_cast(glyph); + unsigned upem = font->face->get_upem(); + + return S_OK == dw_face->GetGlyphRunOutline (upem, + &gid, nullptr, nullptr, + 1, + false, false, + &sink); +} + +#endif + +static inline void free_static_directwrite_funcs (); + +static struct hb_directwrite_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t +{ + static hb_font_funcs_t *create () + { + hb_font_funcs_t *funcs = hb_font_funcs_create (); + + hb_font_funcs_set_nominal_glyphs_func (funcs, hb_directwrite_get_nominal_glyphs, nullptr, nullptr); + //hb_font_funcs_set_variation_glyph_func (funcs, hb_directwrite_get_variation_glyph, nullptr, nullptr); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_directwrite_get_font_h_extents, nullptr, nullptr); + hb_font_funcs_set_glyph_h_advances_func (funcs, hb_directwrite_get_glyph_h_advances, nullptr, nullptr); + +#ifndef HB_NO_VERTICAL + hb_font_funcs_set_glyph_v_advances_func (funcs, hb_directwrite_get_glyph_v_advances, nullptr, nullptr); + hb_font_funcs_set_glyph_v_origin_func (funcs, hb_directwrite_get_glyph_v_origin, nullptr, nullptr); +#endif + +#ifndef HB_NO_DRAW + hb_font_funcs_set_draw_glyph_or_fail_func (funcs, hb_directwrite_draw_glyph_or_fail, nullptr, nullptr); +#endif + + hb_font_funcs_set_glyph_extents_func (funcs, hb_directwrite_get_glyph_extents, nullptr, nullptr); + +#ifndef HB_NO_OT_FONT_GLYPH_NAMES + //hb_font_funcs_set_glyph_name_func (funcs, hb_directwrite_get_glyph_name, nullptr, nullptr); + //hb_font_funcs_set_glyph_from_name_func (funcs, hb_directwrite_get_glyph_from_name, nullptr, nullptr); +#endif + + hb_font_funcs_make_immutable (funcs); + + hb_atexit (free_static_directwrite_funcs); + + return funcs; + } +} static_directwrite_funcs; + +static inline +void free_static_directwrite_funcs () +{ + static_directwrite_funcs.free_instance (); +} + +static hb_font_funcs_t * +_hb_directwrite_get_font_funcs () +{ + return static_directwrite_funcs.get_unconst (); +} + +/** + * hb_directwrite_font_set_funcs: + * @font: #hb_font_t to work upon + * + * Configures the font-functions structure of the specified + * #hb_font_t font object to use DirectWrite font functions. + * + * In particular, you can use this function to configure an + * existing #hb_face_t face object for use with DirectWrite font + * functions even if that #hb_face_t face object was initially + * created with hb_face_create(), and therefore was not + * initially configured to use DirectWrite font functions. + * + * Note: Internally, this function creates a DirectWrite font. + * + * + * Since: 11.0.0 + **/ +void +hb_directwrite_font_set_funcs (hb_font_t *font) +{ + IDWriteFontFace *dw_face = (IDWriteFontFace *) (const void *) font->data.directwrite; + if (unlikely (!dw_face)) + { + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); + return; + } + + dw_face->AddRef (); + hb_font_set_funcs (font, + _hb_directwrite_get_font_funcs (), + nullptr, nullptr); +} + +#undef MAX_GLYPHS + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-directwrite-shape.cc b/thirdparty/harfbuzz/upstream/hb-directwrite-shape.cc new file mode 100644 index 000000000..944406865 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-directwrite-shape.cc @@ -0,0 +1,656 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_DIRECTWRITE + +#include "hb-shaper-impl.hh" + +#include "hb-directwrite.hh" + +#include "hb-ms-feature-ranges.hh" + + +/* +* shaper face data +*/ + +hb_directwrite_face_data_t * +_hb_directwrite_shaper_face_data_create (hb_face_t *face) +{ + hb_blob_t *blob = hb_face_reference_blob (face); + + hb_directwrite_face_data_t *data = (hb_directwrite_face_data_t *) dw_face_create (blob, face->index); + + hb_blob_destroy (blob); + + return data; +} + +void +_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) +{ + ((IDWriteFontFace *) data)->Release (); +} + + +/* + * shaper font data + */ + +struct hb_directwrite_font_data_t {}; + +hb_directwrite_font_data_t * +_hb_directwrite_shaper_font_data_create (hb_font_t *font) +{ + IDWriteFontFace *fontFace = (IDWriteFontFace *) (const void *) font->face->data.directwrite; + + /* + * Set up variations. + */ + IDWriteFontFace5 *fontFaceVariations = nullptr; + { + IDWriteFontFace5 *fontFace5; + if (SUCCEEDED (fontFace->QueryInterface (__uuidof (IDWriteFontFace5), (void **) &fontFace5))) + { + IDWriteFontResource *fontResource; + if (SUCCEEDED (fontFace5->GetFontResource (&fontResource))) + { + hb_vector_t axis_values; + if (likely (axis_values.resize_exact (font->num_coords))) + { + for (unsigned int i = 0; i < font->num_coords; i++) + { + hb_ot_var_axis_info_t info; + unsigned int c = 1; + hb_ot_var_get_axis_infos (font->face, i, &c, &info); + axis_values[i].axisTag = (DWRITE_FONT_AXIS_TAG) hb_uint32_swap (info.tag); + axis_values[i].value = i < font->num_coords ? + hb_clamp (font->design_coords[i], info.min_value, info.max_value) : + info.default_value; + } + + fontResource->CreateFontFace (DWRITE_FONT_SIMULATIONS::DWRITE_FONT_SIMULATIONS_NONE, + axis_values.arrayZ, axis_values.length, &fontFaceVariations); + } + fontResource->Release (); + } + fontFace5->Release (); + } + } + + return (hb_directwrite_font_data_t *) fontFaceVariations; +} + +void +_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) +{ + ((IDWriteFontFace *) (const void *) data)->Release (); +} + + +// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project +// but now is relicensed to MIT for HarfBuzz use +class TextAnalysis : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink +{ +private: + hb_reference_count_t mRefCount; +public: + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) + { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () + { + return mRefCount.inc () + 1; + } + IFACEMETHOD_ (ULONG, Release) () + { + signed refCount = mRefCount.dec () - 1; + assert (refCount >= 0); + if (refCount) + return refCount; + delete this; + return 0; + } + + // A single contiguous run of characters containing the same analysis + // results. + struct Run + { + uint32_t mTextStart; // starting text position of this run + uint32_t mTextLength; // number of contiguous code units covered + uint32_t mGlyphStart; // starting glyph in the glyphs array + uint32_t mGlyphCount; // number of glyphs associated with this run + // text + DWRITE_SCRIPT_ANALYSIS mScript; + uint8_t mBidiLevel; + bool mIsSideways; + + bool ContainsTextPosition (uint32_t aTextPosition) const + { + return aTextPosition >= mTextStart && + aTextPosition < mTextStart + mTextLength; + } + + Run *nextRun; + }; + +public: + TextAnalysis (const wchar_t* text, uint32_t textLength, + const wchar_t* localeName, DWRITE_READING_DIRECTION readingDirection) + : mTextLength (textLength), mText (text), mLocaleName (localeName), + mReadingDirection (readingDirection), mCurrentRun (nullptr) + { + mRefCount.init (); + } + virtual ~TextAnalysis () + { + // delete runs, except mRunHead which is part of the TextAnalysis object + for (Run *run = mRunHead.nextRun; run;) + { + Run *origRun = run; + run = run->nextRun; + delete origRun; + } + } + + STDMETHODIMP + GenerateResults (IDWriteTextAnalyzer* textAnalyzer, Run **runHead) + { + // Analyzes the text using the script analyzer and returns + // the result as a series of runs. + + HRESULT hr = S_OK; + + // Initially start out with one result that covers the entire range. + // This result will be subdivided by the analysis processes. + mRunHead.mTextStart = 0; + mRunHead.mTextLength = mTextLength; + mRunHead.mBidiLevel = + (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); + mRunHead.nextRun = nullptr; + mCurrentRun = &mRunHead; + + // Call each of the analyzers in sequence, recording their results. + if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) + *runHead = &mRunHead; + + return hr; + } + + // IDWriteTextAnalysisSource implementation + + IFACEMETHODIMP + GetTextAtPosition (uint32_t textPosition, + OUT wchar_t const** textString, + OUT uint32_t* textLength) + { + if (textPosition >= mTextLength) + { + // No text at this position, valid query though. + *textString = nullptr; + *textLength = 0; + } + else + { + *textString = mText + textPosition; + *textLength = mTextLength - textPosition; + } + return S_OK; + } + + IFACEMETHODIMP + GetTextBeforePosition (uint32_t textPosition, + OUT wchar_t const** textString, + OUT uint32_t* textLength) + { + if (textPosition == 0 || textPosition > mTextLength) + { + // Either there is no text before here (== 0), or this + // is an invalid position. The query is considered valid though. + *textString = nullptr; + *textLength = 0; + } + else + { + *textString = mText; + *textLength = textPosition; + } + return S_OK; + } + + IFACEMETHODIMP_ (DWRITE_READING_DIRECTION) + GetParagraphReadingDirection () { return mReadingDirection; } + + IFACEMETHODIMP GetLocaleName (uint32_t textPosition, uint32_t* textLength, + wchar_t const** localeName) + { return S_OK; } + + IFACEMETHODIMP + GetNumberSubstitution (uint32_t textPosition, + OUT uint32_t* textLength, + OUT IDWriteNumberSubstitution** numberSubstitution) + { + // We do not support number substitution. + *numberSubstitution = nullptr; + *textLength = mTextLength - textPosition; + + return S_OK; + } + + // IDWriteTextAnalysisSink implementation + + IFACEMETHODIMP + SetScriptAnalysis (uint32_t textPosition, uint32_t textLength, + DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) + { + SetCurrentRun (textPosition); + SplitCurrentRun (textPosition); + while (textLength > 0) + { + Run *run = FetchNextRun (&textLength); + run->mScript = *scriptAnalysis; + } + + return S_OK; + } + + IFACEMETHODIMP + SetLineBreakpoints (uint32_t textPosition, + uint32_t textLength, + const DWRITE_LINE_BREAKPOINT* lineBreakpoints) + { return S_OK; } + + IFACEMETHODIMP SetBidiLevel (uint32_t textPosition, uint32_t textLength, + uint8_t explicitLevel, uint8_t resolvedLevel) + { return S_OK; } + + IFACEMETHODIMP + SetNumberSubstitution (uint32_t textPosition, uint32_t textLength, + IDWriteNumberSubstitution* numberSubstitution) + { return S_OK; } + +protected: + Run *FetchNextRun (IN OUT uint32_t* textLength) + { + // Used by the sink setters, this returns a reference to the next run. + // Position and length are adjusted to now point after the current run + // being returned. + + Run *origRun = mCurrentRun; + // Split the tail if needed (the length remaining is less than the + // current run's size). + if (*textLength < mCurrentRun->mTextLength) + SplitCurrentRun (mCurrentRun->mTextStart + *textLength); + else + // Just advance the current run. + mCurrentRun = mCurrentRun->nextRun; + *textLength -= origRun->mTextLength; + + // Return a reference to the run that was just current. + return origRun; + } + + void SetCurrentRun (uint32_t textPosition) + { + // Move the current run to the given position. + // Since the analyzers generally return results in a forward manner, + // this will usually just return early. If not, find the + // corresponding run for the text position. + + if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition)) + return; + + for (Run *run = &mRunHead; run; run = run->nextRun) + if (run->ContainsTextPosition (textPosition)) + { + mCurrentRun = run; + return; + } + assert (0); // We should always be able to find the text position in one of our runs + } + + void SplitCurrentRun (uint32_t splitPosition) + { + if (!mCurrentRun) + { + assert (0); // SplitCurrentRun called without current run + // Shouldn't be calling this when no current run is set! + return; + } + // Split the current run. + if (splitPosition <= mCurrentRun->mTextStart) + { + // No need to split, already the start of a run + // or before it. Usually the first. + return; + } + Run *newRun = new Run; + + *newRun = *mCurrentRun; + + // Insert the new run in our linked list. + newRun->nextRun = mCurrentRun->nextRun; + mCurrentRun->nextRun = newRun; + + // Adjust runs' text positions and lengths. + uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart; + newRun->mTextStart += splitPoint; + newRun->mTextLength -= splitPoint; + mCurrentRun->mTextLength = splitPoint; + mCurrentRun = newRun; + } + +protected: + // Input + // (weak references are fine here, since this class is a transient + // stack-based helper that doesn't need to copy data) + uint32_t mTextLength; + const wchar_t* mText; + const wchar_t* mLocaleName; + DWRITE_READING_DIRECTION mReadingDirection; + + // Current processing state. + Run *mCurrentRun; + + // Output is a list of runs starting here + Run mRunHead; +}; + +/* + * shaper + */ + +hb_bool_t +_hb_directwrite_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + IDWriteFontFace *fontFace = (IDWriteFontFace *) (const void *) font->data.directwrite; + auto *global = get_directwrite_global (); + if (unlikely (!global)) + return false; + IDWriteFactory *dwriteFactory = global->dwriteFactory; + + IDWriteTextAnalyzer* analyzer; + dwriteFactory->CreateTextAnalyzer (&analyzer); + + unsigned int scratch_size; + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); +#define ALLOCATE_ARRAY(Type, name, len) \ + Type *name = (Type *) scratch; \ + do { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + assert (_consumed <= scratch_size); \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } while (0) + +#define utf16_index() var1.u32 + + ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2); + + unsigned int chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + buffer->info[i].utf16_index () = chars_len; + if (likely (c <= 0xFFFFu)) + textString[chars_len++] = c; + else if (unlikely (c > 0x10FFFFu)) + textString[chars_len++] = 0xFFFDu; + else + { + textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); + } + } + + ALLOCATE_ARRAY (WORD, log_clusters, chars_len); + /* Need log_clusters to assign features. */ + chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + unsigned int cluster = buffer->info[i].cluster; + log_clusters[chars_len++] = cluster; + if (hb_in_range (c, 0x10000u, 0x10FFFFu)) + log_clusters[chars_len++] = cluster; /* Surrogates. */ + } + + DWRITE_READING_DIRECTION readingDirection; + readingDirection = buffer->props.direction ? + DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; + + /* + * There's an internal 16-bit limit on some things inside the analyzer, + * but we never attempt to shape a word longer than 64K characters + * in a single gfxShapedWord, so we cannot exceed that limit. + */ + uint32_t textLength = chars_len; + + TextAnalysis analysis (textString, textLength, nullptr, readingDirection); + TextAnalysis::Run *runHead; + HRESULT hr; + hr = analysis.GenerateResults (analyzer, &runHead); + +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ + return false; \ + } HB_STMT_END + + if (FAILED (hr)) + FAIL ("Analyzer failed to generate results."); + + uint32_t maxGlyphCount = 3 * textLength / 2 + 16; + uint32_t glyphCount; + bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + + const wchar_t localeName[20] = {0}; + if (buffer->props.language) + mbstowcs ((wchar_t*) localeName, + hb_language_to_string (buffer->props.language), 20); + + /* + * Set up features. + */ + static_assert ((sizeof (DWRITE_TYPOGRAPHIC_FEATURES) == sizeof (hb_ms_features_t)), ""); + static_assert ((sizeof (DWRITE_FONT_FEATURE) == sizeof (hb_ms_feature_t)), ""); + hb_vector_t range_features; + hb_vector_t range_char_counts; + + // https://github.com/harfbuzz/harfbuzz/pull/5114 + // The data allocated by these two vectors are used by the above two, so they + // should remain alive as long as the above two are. + hb_vector_t feature_records; + hb_vector_t range_records; + if (num_features) + { + if (hb_ms_setup_features (features, num_features, feature_records, range_records)) + { + hb_ms_make_feature_ranges (feature_records, + range_records, + 0, + chars_len, + log_clusters, + range_features, + range_char_counts); + } + } + + uint16_t* clusterMap; + clusterMap = new uint16_t[textLength]; + DWRITE_SHAPING_TEXT_PROPERTIES* textProperties; + textProperties = new DWRITE_SHAPING_TEXT_PROPERTIES[textLength]; + +retry_getglyphs: + uint16_t* glyphIndices = new uint16_t[maxGlyphCount]; + DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties; + glyphProperties = new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount]; + + hr = analyzer->GetGlyphs (textString, + chars_len, + fontFace, + false, + isRightToLeft, + &runHead->mScript, + localeName, + nullptr, + (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, + range_char_counts.arrayZ, + range_features.length, + maxGlyphCount, + clusterMap, + textProperties, + glyphIndices, + glyphProperties, + &glyphCount); + + if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) + { + delete [] glyphIndices; + delete [] glyphProperties; + + maxGlyphCount *= 2; + + goto retry_getglyphs; + } + if (FAILED (hr)) + FAIL ("Analyzer failed to get glyphs."); + + float* glyphAdvances = new float[maxGlyphCount]; + DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount]; + + /* The -2 in the following is to compensate for possible + * alignment needed after the WORD array. sizeof (WORD) == 2. */ + unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) + / (sizeof (WORD) + + sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + + sizeof (int) + + sizeof (DWRITE_GLYPH_OFFSET) + + sizeof (uint32_t)); + ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); + +#undef ALLOCATE_ARRAY + + unsigned fontEmSize = font->face->get_upem (); + + float x_mult = font->x_multf; + float y_mult = font->y_multf; + + hr = analyzer->GetGlyphPlacements (textString, + clusterMap, + textProperties, + chars_len, + glyphIndices, + glyphProperties, + glyphCount, + fontFace, + fontEmSize, + false, + isRightToLeft, + &runHead->mScript, + localeName, + (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, + range_char_counts.arrayZ, + range_features.length, + glyphAdvances, + glyphOffsets); + + if (FAILED (hr)) + FAIL ("Analyzer failed to get glyph placements."); + + /* Ok, we've got everything we need, now compose output buffer, + * very, *very*, carefully! */ + + /* Calculate visual-clusters. That's what we ship. */ + for (unsigned int i = 0; i < glyphCount; i++) + vis_clusters[i] = (uint32_t) -1; + for (unsigned int i = 0; i < buffer->len; i++) + { + uint32_t *p = + &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]]; + *p = hb_min (*p, buffer->info[i].cluster); + } + for (unsigned int i = 1; i < glyphCount; i++) + if (vis_clusters[i] == (uint32_t) -1) + vis_clusters[i] = vis_clusters[i - 1]; + +#undef utf16_index + + if (unlikely (!buffer->ensure (glyphCount))) + FAIL ("Buffer in error"); + +#undef FAIL + + /* Set glyph infos */ + buffer->len = 0; + for (unsigned int i = 0; i < glyphCount; i++) + { + hb_glyph_info_t *info = &buffer->info[buffer->len++]; + + info->codepoint = glyphIndices[i]; + info->cluster = vis_clusters[i]; + + /* The rest is crap. Let's store position info there for now. */ + info->mask = glyphAdvances[i]; + info->var1.i32 = glyphOffsets[i].advanceOffset; + info->var2.i32 = glyphOffsets[i].ascenderOffset; + } + + /* Set glyph positions */ + buffer->clear_positions (); + for (unsigned int i = 0; i < glyphCount; i++) + { + hb_glyph_info_t *info = &buffer->info[i]; + hb_glyph_position_t *pos = &buffer->pos[i]; + + /* TODO vertical */ + pos->x_advance = round (x_mult * (int32_t) info->mask); + pos->x_offset = round (x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32)); + pos->y_offset = round (y_mult * info->var2.i32); + } + + if (isRightToLeft) hb_buffer_reverse (buffer); + + buffer->clear_glyph_flags (); + buffer->unsafe_to_break (); + + delete [] clusterMap; + delete [] glyphIndices; + delete [] textProperties; + delete [] glyphProperties; + delete [] glyphAdvances; + delete [] glyphOffsets; + + /* Wow, done! */ + return true; +} + + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-directwrite.cc b/thirdparty/harfbuzz/upstream/hb-directwrite.cc index 6c90265d0..d94104971 100644 --- a/thirdparty/harfbuzz/upstream/hb-directwrite.cc +++ b/thirdparty/harfbuzz/upstream/hb-directwrite.cc @@ -26,13 +26,10 @@ #ifdef HAVE_DIRECTWRITE -#include "hb-shaper-impl.hh" +#include "hb-directwrite.hh" -#include +#include "hb-font.hh" -#include "hb-directwrite.h" - -#include "hb-ms-feature-ranges.hh" /** * SECTION:hb-directwrite @@ -43,173 +40,89 @@ * Functions for using HarfBuzz with DirectWrite fonts. **/ -/* Declare object creator for dynamic support of DWRITE */ -typedef HRESULT (WINAPI *t_DWriteCreateFactory)( - DWRITE_FACTORY_TYPE factoryType, - REFIID iid, - IUnknown **factory -); - - -/* - * DirectWrite font stream helpers - */ +static inline void free_static_directwrite_global (); -// This is a font loader which provides only one font (unlike its original design). -// For a better implementation which was also source of this -// and DWriteFontFileStream, have a look at to NativeFontResourceDWrite.cpp in Mozilla -class DWriteFontFileLoader : public IDWriteFontFileLoader +static struct hb_directwrite_global_lazy_loader_t : hb_lazy_loader_t { -private: - IDWriteFontFileStream *mFontFileStream; -public: - DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) - { mFontFileStream = fontFileStream; } - - // IUnknown interface - IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) - { return S_OK; } - IFACEMETHOD_ (ULONG, AddRef) () { return 1; } - IFACEMETHOD_ (ULONG, Release) () { return 1; } - - // IDWriteFontFileLoader methods - virtual HRESULT STDMETHODCALLTYPE - CreateStreamFromKey (void const* fontFileReferenceKey, - uint32_t fontFileReferenceKeySize, - OUT IDWriteFontFileStream** fontFileStream) + static hb_directwrite_global_t * create () { - *fontFileStream = mFontFileStream; - return S_OK; - } + hb_directwrite_global_t *global = new hb_directwrite_global_t; - virtual ~DWriteFontFileLoader() {} -}; + if (unlikely (!global)) + return nullptr; + if (unlikely (!global->success)) + { + delete global; + return nullptr; + } -class DWriteFontFileStream : public IDWriteFontFileStream -{ -private: - uint8_t *mData; - uint32_t mSize; -public: - DWriteFontFileStream (uint8_t *aData, uint32_t aSize) - { - mData = aData; - mSize = aSize; - } + hb_atexit (free_static_directwrite_global); - // IUnknown interface - IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) - { return S_OK; } - IFACEMETHOD_ (ULONG, AddRef) () { return 1; } - IFACEMETHOD_ (ULONG, Release) () { return 1; } - - // IDWriteFontFileStream methods - virtual HRESULT STDMETHODCALLTYPE - ReadFileFragment (void const** fragmentStart, - UINT64 fileOffset, - UINT64 fragmentSize, - OUT void** fragmentContext) + return global; + } + static void destroy (hb_directwrite_global_t *l) { - // We are required to do bounds checking. - if (fileOffset + fragmentSize > mSize) return E_FAIL; - - // truncate the 64 bit fileOffset to size_t sized index into mData - size_t index = static_cast (fileOffset); - - // We should be alive for the duration of this. - *fragmentStart = &mData[index]; - *fragmentContext = nullptr; - return S_OK; + delete l; } - - virtual void STDMETHODCALLTYPE - ReleaseFileFragment (void* fragmentContext) {} - - virtual HRESULT STDMETHODCALLTYPE - GetFileSize (OUT UINT64* fileSize) + static hb_directwrite_global_t * get_null () { - *fileSize = mSize; - return S_OK; + return nullptr; } +} static_directwrite_global; - virtual HRESULT STDMETHODCALLTYPE - GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; } - - virtual ~DWriteFontFileStream() {} -}; +static inline +void free_static_directwrite_global () +{ + static_directwrite_global.free_instance (); +} -/* -* shaper face data -*/ +hb_directwrite_global_t * +get_directwrite_global () +{ + return static_directwrite_global.get_unconst (); +} -struct hb_directwrite_face_data_t +DWriteFontFileStream::DWriteFontFileStream (hb_blob_t *blob) { - HMODULE dwrite_dll; - IDWriteFactory *dwriteFactory; - IDWriteFontFile *fontFile; - DWriteFontFileStream *fontFileStream; - DWriteFontFileLoader *fontFileLoader; - IDWriteFontFace *fontFace; - hb_blob_t *faceBlob; -}; + auto *global = get_directwrite_global (); + mLoader = global->fontFileLoader; + mRefCount.init (); + mLoader->AddRef (); + hb_blob_make_immutable (blob); + mBlob = hb_blob_reference (blob); + mData = (uint8_t *) hb_blob_get_data (blob, &mSize); + fontFileKey = mLoader->RegisterFontFileStream (this); +} -hb_directwrite_face_data_t * -_hb_directwrite_shaper_face_data_create (hb_face_t *face) +DWriteFontFileStream::~DWriteFontFileStream() { - hb_directwrite_face_data_t *data = new hb_directwrite_face_data_t; - if (unlikely (!data)) - return nullptr; + mLoader->UnregisterFontFileStream (fontFileKey); + mLoader->Release (); + hb_blob_destroy (mBlob); +} +IDWriteFontFace * +dw_face_create (hb_blob_t *blob, unsigned index) +{ #define FAIL(...) \ HB_STMT_START { \ DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ return nullptr; \ } HB_STMT_END - data->dwrite_dll = LoadLibrary (TEXT ("DWRITE")); - if (unlikely (!data->dwrite_dll)) - FAIL ("Cannot find DWrite.DLL"); - - t_DWriteCreateFactory p_DWriteCreateFactory; - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - - p_DWriteCreateFactory = (t_DWriteCreateFactory) - GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); + auto *global = get_directwrite_global (); + if (unlikely (!global)) + FAIL ("Couldn't load DirectWrite!"); -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif - - if (unlikely (!p_DWriteCreateFactory)) - FAIL ("Cannot find DWriteCreateFactory()."); - - HRESULT hr; - - // TODO: factory and fontFileLoader should be cached separately - IDWriteFactory* dwriteFactory; - hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); - - if (unlikely (hr != S_OK)) - FAIL ("Failed to run DWriteCreateFactory()."); - - hb_blob_t *blob = hb_face_reference_blob (face); - DWriteFontFileStream *fontFileStream; - fontFileStream = new DWriteFontFileStream ((uint8_t *) hb_blob_get_data (blob, nullptr), - hb_blob_get_length (blob)); - - DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream); - dwriteFactory->RegisterFontFileLoader (fontFileLoader); + DWriteFontFileStream *fontFileStream = new DWriteFontFileStream (blob); IDWriteFontFile *fontFile; - uint64_t fontFileKey = 0; - hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey), - fontFileLoader, &fontFile); + auto hr = global->dwriteFactory->CreateCustomFontFileReference (&fontFileStream->fontFileKey, sizeof (fontFileStream->fontFileKey), + global->fontFileLoader, &fontFile); + + fontFileStream->Release (); if (FAILED (hr)) FAIL ("Failed to load font file from data!"); @@ -220,596 +133,84 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) uint32_t numberOfFaces; hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces); if (FAILED (hr) || !isSupported) + { + fontFile->Release (); FAIL ("Font file is not supported."); + } #undef FAIL - IDWriteFontFace *fontFace; - dwriteFactory->CreateFontFace (faceType, 1, &fontFile, 0, - DWRITE_FONT_SIMULATIONS_NONE, &fontFace); - - data->dwriteFactory = dwriteFactory; - data->fontFile = fontFile; - data->fontFileStream = fontFileStream; - data->fontFileLoader = fontFileLoader; - data->fontFace = fontFace; - data->faceBlob = blob; + IDWriteFontFace *fontFace = nullptr; + global->dwriteFactory->CreateFontFace (faceType, 1, &fontFile, index, + DWRITE_FONT_SIMULATIONS_NONE, &fontFace); + fontFile->Release (); - return data; + return fontFace; } -void -_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) -{ - if (data->fontFace) - data->fontFace->Release (); - if (data->fontFile) - data->fontFile->Release (); - if (data->dwriteFactory) - { - if (data->fontFileLoader) - data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader); - data->dwriteFactory->Release (); - } - delete data->fontFileLoader; - delete data->fontFileStream; - hb_blob_destroy (data->faceBlob); - if (data->dwrite_dll) - FreeLibrary (data->dwrite_dll); - delete data; -} - - -/* - * shaper font data - */ - -struct hb_directwrite_font_data_t {}; - -hb_directwrite_font_data_t * -_hb_directwrite_shaper_font_data_create (hb_font_t *font) -{ - return (hb_directwrite_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} +struct _hb_directwrite_font_table_context { + IDWriteFontFace *face; + void *table_context; +}; -void -_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) +static void +_hb_directwrite_table_data_release (void *data) { + _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) data; + context->face->ReleaseFontTable (context->table_context); + hb_free (context); } - -// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project -// but now is relicensed to MIT for HarfBuzz use -class TextAnalysis : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink +static hb_blob_t * +_hb_directwrite_get_file_blob (IDWriteFontFace *dw_face) { -public: - - IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) - { return S_OK; } - IFACEMETHOD_ (ULONG, AddRef) () { return 1; } - IFACEMETHOD_ (ULONG, Release) () { return 1; } - - // A single contiguous run of characters containing the same analysis - // results. - struct Run - { - uint32_t mTextStart; // starting text position of this run - uint32_t mTextLength; // number of contiguous code units covered - uint32_t mGlyphStart; // starting glyph in the glyphs array - uint32_t mGlyphCount; // number of glyphs associated with this run - // text - DWRITE_SCRIPT_ANALYSIS mScript; - uint8_t mBidiLevel; - bool mIsSideways; - - bool ContainsTextPosition (uint32_t aTextPosition) const - { - return aTextPosition >= mTextStart && - aTextPosition < mTextStart + mTextLength; - } - - Run *nextRun; - }; - -public: - TextAnalysis (const wchar_t* text, uint32_t textLength, - const wchar_t* localeName, DWRITE_READING_DIRECTION readingDirection) - : mTextLength (textLength), mText (text), mLocaleName (localeName), - mReadingDirection (readingDirection), mCurrentRun (nullptr) {} - ~TextAnalysis () - { - // delete runs, except mRunHead which is part of the TextAnalysis object - for (Run *run = mRunHead.nextRun; run;) - { - Run *origRun = run; - run = run->nextRun; - delete origRun; - } - } - - STDMETHODIMP - GenerateResults (IDWriteTextAnalyzer* textAnalyzer, Run **runHead) - { - // Analyzes the text using the script analyzer and returns - // the result as a series of runs. - - HRESULT hr = S_OK; - - // Initially start out with one result that covers the entire range. - // This result will be subdivided by the analysis processes. - mRunHead.mTextStart = 0; - mRunHead.mTextLength = mTextLength; - mRunHead.mBidiLevel = - (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); - mRunHead.nextRun = nullptr; - mCurrentRun = &mRunHead; - - // Call each of the analyzers in sequence, recording their results. - if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) - *runHead = &mRunHead; - - return hr; - } - - // IDWriteTextAnalysisSource implementation - - IFACEMETHODIMP - GetTextAtPosition (uint32_t textPosition, - OUT wchar_t const** textString, - OUT uint32_t* textLength) - { - if (textPosition >= mTextLength) - { - // No text at this position, valid query though. - *textString = nullptr; - *textLength = 0; - } - else - { - *textString = mText + textPosition; - *textLength = mTextLength - textPosition; - } - return S_OK; - } - - IFACEMETHODIMP - GetTextBeforePosition (uint32_t textPosition, - OUT wchar_t const** textString, - OUT uint32_t* textLength) - { - if (textPosition == 0 || textPosition > mTextLength) - { - // Either there is no text before here (== 0), or this - // is an invalid position. The query is considered valid though. - *textString = nullptr; - *textLength = 0; - } - else - { - *textString = mText; - *textLength = textPosition; - } - return S_OK; - } - - IFACEMETHODIMP_ (DWRITE_READING_DIRECTION) - GetParagraphReadingDirection () { return mReadingDirection; } - - IFACEMETHODIMP GetLocaleName (uint32_t textPosition, uint32_t* textLength, - wchar_t const** localeName) - { return S_OK; } - - IFACEMETHODIMP - GetNumberSubstitution (uint32_t textPosition, - OUT uint32_t* textLength, - OUT IDWriteNumberSubstitution** numberSubstitution) - { - // We do not support number substitution. - *numberSubstitution = nullptr; - *textLength = mTextLength - textPosition; - - return S_OK; - } - - // IDWriteTextAnalysisSink implementation - - IFACEMETHODIMP - SetScriptAnalysis (uint32_t textPosition, uint32_t textLength, - DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) - { - SetCurrentRun (textPosition); - SplitCurrentRun (textPosition); - while (textLength > 0) - { - Run *run = FetchNextRun (&textLength); - run->mScript = *scriptAnalysis; - } - - return S_OK; - } - - IFACEMETHODIMP - SetLineBreakpoints (uint32_t textPosition, - uint32_t textLength, - const DWRITE_LINE_BREAKPOINT* lineBreakpoints) - { return S_OK; } - - IFACEMETHODIMP SetBidiLevel (uint32_t textPosition, uint32_t textLength, - uint8_t explicitLevel, uint8_t resolvedLevel) - { return S_OK; } - - IFACEMETHODIMP - SetNumberSubstitution (uint32_t textPosition, uint32_t textLength, - IDWriteNumberSubstitution* numberSubstitution) - { return S_OK; } - -protected: - Run *FetchNextRun (IN OUT uint32_t* textLength) - { - // Used by the sink setters, this returns a reference to the next run. - // Position and length are adjusted to now point after the current run - // being returned. - - Run *origRun = mCurrentRun; - // Split the tail if needed (the length remaining is less than the - // current run's size). - if (*textLength < mCurrentRun->mTextLength) - SplitCurrentRun (mCurrentRun->mTextStart + *textLength); - else - // Just advance the current run. - mCurrentRun = mCurrentRun->nextRun; - *textLength -= origRun->mTextLength; - - // Return a reference to the run that was just current. - return origRun; - } + UINT32 file_count; + if (FAILED (dw_face->GetFiles(&file_count, NULL))) + return nullptr; - void SetCurrentRun (uint32_t textPosition) + IDWriteFontFile **files = new IDWriteFontFile*[file_count]; + if (FAILED (dw_face->GetFiles(&file_count, files))) { - // Move the current run to the given position. - // Since the analyzers generally return results in a forward manner, - // this will usually just return early. If not, find the - // corresponding run for the text position. - - if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition)) - return; - - for (Run *run = &mRunHead; run; run = run->nextRun) - if (run->ContainsTextPosition (textPosition)) - { - mCurrentRun = run; - return; - } - assert (0); // We should always be able to find the text position in one of our runs + delete [] files; + return nullptr; } - void SplitCurrentRun (uint32_t splitPosition) + hb_blob_t *blob = nullptr; + for (UINT32 i = 0; i < file_count; i++) { - if (!mCurrentRun) + LPCVOID reference_key; + UINT32 reference_key_size; + if (FAILED (files[i]->GetReferenceKey(&reference_key, &reference_key_size))) + continue; + + IDWriteFontFileLoader *loader; + if (FAILED (files[i]->GetLoader(&loader))) + continue; + + IDWriteFontFileStream *stream; + if (FAILED (loader->CreateStreamFromKey (reference_key, reference_key_size, &stream))) { - assert (0); // SplitCurrentRun called without current run - // Shouldn't be calling this when no current run is set! - return; + loader->Release (); + continue; } - // Split the current run. - if (splitPosition <= mCurrentRun->mTextStart) - { - // No need to split, already the start of a run - // or before it. Usually the first. - return; - } - Run *newRun = new Run; - - *newRun = *mCurrentRun; - - // Insert the new run in our linked list. - newRun->nextRun = mCurrentRun->nextRun; - mCurrentRun->nextRun = newRun; - - // Adjust runs' text positions and lengths. - uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart; - newRun->mTextStart += splitPoint; - newRun->mTextLength -= splitPoint; - mCurrentRun->mTextLength = splitPoint; - mCurrentRun = newRun; - } - -protected: - // Input - // (weak references are fine here, since this class is a transient - // stack-based helper that doesn't need to copy data) - uint32_t mTextLength; - const wchar_t* mText; - const wchar_t* mLocaleName; - DWRITE_READING_DIRECTION mReadingDirection; - // Current processing state. - Run *mCurrentRun; - - // Output is a list of runs starting here - Run mRunHead; -}; - -/* - * shaper - */ - -hb_bool_t -_hb_directwrite_shape (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - hb_face_t *face = font->face; - const hb_directwrite_face_data_t *face_data = face->data.directwrite; - IDWriteFactory *dwriteFactory = face_data->dwriteFactory; - IDWriteFontFace *fontFace = face_data->fontFace; - - IDWriteTextAnalyzer* analyzer; - dwriteFactory->CreateTextAnalyzer (&analyzer); - - unsigned int scratch_size; - hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); -#define ALLOCATE_ARRAY(Type, name, len) \ - Type *name = (Type *) scratch; \ - do { \ - unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ - assert (_consumed <= scratch_size); \ - scratch += _consumed; \ - scratch_size -= _consumed; \ - } while (0) - -#define utf16_index() var1.u32 - - ALLOCATE_ARRAY (wchar_t, textString, buffer->len * 2); - - unsigned int chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) - { - hb_codepoint_t c = buffer->info[i].codepoint; - buffer->info[i].utf16_index () = chars_len; - if (likely (c <= 0xFFFFu)) - textString[chars_len++] = c; - else if (unlikely (c > 0x10FFFFu)) - textString[chars_len++] = 0xFFFDu; - else + UINT64 file_size; + const void *fragment; + void *context; + if (FAILED (stream->GetFileSize(&file_size)) || + FAILED (stream->ReadFileFragment (&fragment, 0, file_size, &context))) { - textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); - textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); + loader->Release (); + continue; } + blob = hb_blob_create ((const char *) fragment, file_size, HB_MEMORY_MODE_DUPLICATE, NULL, NULL); + stream->ReleaseFileFragment (context); + loader->Release (); + break; } - ALLOCATE_ARRAY (WORD, log_clusters, chars_len); - /* Need log_clusters to assign features. */ - chars_len = 0; - for (unsigned int i = 0; i < buffer->len; i++) - { - hb_codepoint_t c = buffer->info[i].codepoint; - unsigned int cluster = buffer->info[i].cluster; - log_clusters[chars_len++] = cluster; - if (hb_in_range (c, 0x10000u, 0x10FFFFu)) - log_clusters[chars_len++] = cluster; /* Surrogates. */ - } - - DWRITE_READING_DIRECTION readingDirection; - readingDirection = buffer->props.direction ? - DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : - DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; - - /* - * There's an internal 16-bit limit on some things inside the analyzer, - * but we never attempt to shape a word longer than 64K characters - * in a single gfxShapedWord, so we cannot exceed that limit. - */ - uint32_t textLength = chars_len; - - TextAnalysis analysis (textString, textLength, nullptr, readingDirection); - TextAnalysis::Run *runHead; - HRESULT hr; - hr = analysis.GenerateResults (analyzer, &runHead); - -#define FAIL(...) \ - HB_STMT_START { \ - DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ - return false; \ - } HB_STMT_END - - if (FAILED (hr)) - FAIL ("Analyzer failed to generate results."); - - uint32_t maxGlyphCount = 3 * textLength / 2 + 16; - uint32_t glyphCount; - bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - - const wchar_t localeName[20] = {0}; - if (buffer->props.language) - mbstowcs ((wchar_t*) localeName, - hb_language_to_string (buffer->props.language), 20); - - /* - * Set up features. - */ - static_assert ((sizeof (DWRITE_TYPOGRAPHIC_FEATURES) == sizeof (hb_ms_features_t)), ""); - static_assert ((sizeof (DWRITE_FONT_FEATURE) == sizeof (hb_ms_feature_t)), ""); - hb_vector_t range_features; - hb_vector_t range_char_counts; - if (num_features) - { - hb_vector_t feature_records; - hb_vector_t range_records; - if (hb_ms_setup_features (features, num_features, feature_records, range_records)) - hb_ms_make_feature_ranges (feature_records, - range_records, - 0, - chars_len, - log_clusters, - range_features, - range_char_counts); - } - - uint16_t* clusterMap; - clusterMap = new uint16_t[textLength]; - DWRITE_SHAPING_TEXT_PROPERTIES* textProperties; - textProperties = new DWRITE_SHAPING_TEXT_PROPERTIES[textLength]; - -retry_getglyphs: - uint16_t* glyphIndices = new uint16_t[maxGlyphCount]; - DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties; - glyphProperties = new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount]; - - hr = analyzer->GetGlyphs (textString, - chars_len, - fontFace, - false, - isRightToLeft, - &runHead->mScript, - localeName, - nullptr, - (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, - range_char_counts.arrayZ, - range_features.length, - maxGlyphCount, - clusterMap, - textProperties, - glyphIndices, - glyphProperties, - &glyphCount); - - if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) - { - delete [] glyphIndices; - delete [] glyphProperties; - - maxGlyphCount *= 2; - - goto retry_getglyphs; - } - if (FAILED (hr)) - FAIL ("Analyzer failed to get glyphs."); - - float* glyphAdvances = new float[maxGlyphCount]; - DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount]; - - /* The -2 in the following is to compensate for possible - * alignment needed after the WORD array. sizeof (WORD) == 2. */ - unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) - / (sizeof (WORD) + - sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + - sizeof (int) + - sizeof (DWRITE_GLYPH_OFFSET) + - sizeof (uint32_t)); - ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); - -#undef ALLOCATE_ARRAY - - int fontEmSize = font->face->get_upem (); - if (fontEmSize < 0) fontEmSize = -fontEmSize; - - if (fontEmSize < 0) fontEmSize = -fontEmSize; - double x_mult = (double) font->x_scale / fontEmSize; - double y_mult = (double) font->y_scale / fontEmSize; - - hr = analyzer->GetGlyphPlacements (textString, - clusterMap, - textProperties, - chars_len, - glyphIndices, - glyphProperties, - glyphCount, - fontFace, - fontEmSize, - false, - isRightToLeft, - &runHead->mScript, - localeName, - (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, - range_char_counts.arrayZ, - range_features.length, - glyphAdvances, - glyphOffsets); - - if (FAILED (hr)) - FAIL ("Analyzer failed to get glyph placements."); - - /* Ok, we've got everything we need, now compose output buffer, - * very, *very*, carefully! */ - - /* Calculate visual-clusters. That's what we ship. */ - for (unsigned int i = 0; i < glyphCount; i++) - vis_clusters[i] = (uint32_t) -1; - for (unsigned int i = 0; i < buffer->len; i++) - { - uint32_t *p = - &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]]; - *p = hb_min (*p, buffer->info[i].cluster); - } - for (unsigned int i = 1; i < glyphCount; i++) - if (vis_clusters[i] == (uint32_t) -1) - vis_clusters[i] = vis_clusters[i - 1]; - -#undef utf16_index - - if (unlikely (!buffer->ensure (glyphCount))) - FAIL ("Buffer in error"); - -#undef FAIL - - /* Set glyph infos */ - buffer->len = 0; - for (unsigned int i = 0; i < glyphCount; i++) - { - hb_glyph_info_t *info = &buffer->info[buffer->len++]; - - info->codepoint = glyphIndices[i]; - info->cluster = vis_clusters[i]; - - /* The rest is crap. Let's store position info there for now. */ - info->mask = glyphAdvances[i]; - info->var1.i32 = glyphOffsets[i].advanceOffset; - info->var2.i32 = glyphOffsets[i].ascenderOffset; - } - - /* Set glyph positions */ - buffer->clear_positions (); - for (unsigned int i = 0; i < glyphCount; i++) - { - hb_glyph_info_t *info = &buffer->info[i]; - hb_glyph_position_t *pos = &buffer->pos[i]; - - /* TODO vertical */ - pos->x_advance = x_mult * (int32_t) info->mask; - pos->x_offset = x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32); - pos->y_offset = y_mult * info->var2.i32; - } - - if (isRightToLeft) hb_buffer_reverse (buffer); - - buffer->clear_glyph_flags (); - buffer->unsafe_to_break (); - - delete [] clusterMap; - delete [] glyphIndices; - delete [] textProperties; - delete [] glyphProperties; - delete [] glyphAdvances; - delete [] glyphOffsets; - - /* Wow, done! */ - return true; -} - -struct _hb_directwrite_font_table_context { - IDWriteFontFace *face; - void *table_context; -}; - -static void -_hb_directwrite_table_data_release (void *data) -{ - _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) data; - context->face->ReleaseFontTable (context->table_context); - hb_free (context); + delete [] files; + return blob; } static hb_blob_t * @@ -820,8 +221,11 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * uint32_t length; void *table_context; BOOL exists; - if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data, - &length, &table_context, &exists))) + if (tag == HB_TAG_NONE) + return _hb_directwrite_get_file_blob (dw_face); + + if (FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data, + &length, &table_context, &exists))) return nullptr; if (!data || !exists || !length) @@ -831,6 +235,11 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * } _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) hb_malloc (sizeof (_hb_directwrite_font_table_context)); + if (unlikely (!context)) + { + dw_face->ReleaseFontTable (table_context); + return nullptr; + } context->face = dw_face; context->table_context = table_context; @@ -839,15 +248,14 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * } static void -_hb_directwrite_font_release (void *data) +_hb_directwrite_face_release (void *data) { - if (data) - ((IDWriteFontFace *) data)->Release (); + ((IDWriteFontFace *) data)->Release (); } /** * hb_directwrite_face_create: - * @font_face: a DirectWrite IDWriteFontFace object. + * @dw_face: a DirectWrite IDWriteFontFace object. * * Constructs a new face object from the specified DirectWrite IDWriteFontFace. * @@ -856,14 +264,104 @@ _hb_directwrite_font_release (void *data) * Since: 2.4.0 **/ hb_face_t * -hb_directwrite_face_create (IDWriteFontFace *font_face) +hb_directwrite_face_create (IDWriteFontFace *dw_face) +{ + if (!dw_face) + return hb_face_get_empty (); + + dw_face->AddRef (); + hb_face_t *face = hb_face_create_for_tables (_hb_directwrite_reference_table, + dw_face, + _hb_directwrite_face_release); + + hb_face_set_index (face, dw_face->GetIndex ()); + hb_face_set_glyph_count (face, dw_face->GetGlyphCount ()); + + return face; +} + +/** + * hb_directwrite_face_create_from_file_or_fail: + * @file_name: A font filename + * @index: The index of the face within the file + * + * Creates an #hb_face_t face object from the specified + * font file and face index. + * + * This is similar in functionality to hb_face_create_from_file_or_fail(), + * but uses the DirectWrite library for loading the font file. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the file cannot be read. + * + * Since: 11.0.0 + */ +hb_face_t * +hb_directwrite_face_create_from_file_or_fail (const char *file_name, + unsigned int index) +{ + auto *blob = hb_blob_create_from_file_or_fail (file_name); + if (unlikely (!blob)) + return nullptr; + + return hb_directwrite_face_create_from_blob_or_fail (blob, index); +} + +/** + * hb_directwrite_face_create_from_blob_or_fail: + * @blob: A blob containing the font data + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the DirectWrite library for loading the font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the blob cannot be read. + * + * Since: 11.0.0 + */ +HB_EXTERN hb_face_t * +hb_directwrite_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + IDWriteFontFace *dw_face = dw_face_create (blob, index); + if (unlikely (!dw_face)) + return nullptr; + + hb_face_t *face = hb_directwrite_face_create (dw_face); + if (unlikely (hb_object_is_immutable (face))) + { + dw_face->Release (); + return face; + } + + /* Let there be dragons here... */ + face->data.directwrite.cmpexch (nullptr, (hb_directwrite_face_data_t *) dw_face); + + return face; +} + +/** +* hb_directwrite_face_get_dw_font_face: +* @face: a #hb_face_t object +* +* Gets the DirectWrite IDWriteFontFace associated with @face. +* +* Return value: DirectWrite IDWriteFontFace object corresponding to the given input +* +* Since: 10.4.0 +**/ +IDWriteFontFace * +hb_directwrite_face_get_dw_font_face (hb_face_t *face) { - if (font_face) - font_face->AddRef (); - return hb_face_create_for_tables (_hb_directwrite_reference_table, font_face, - _hb_directwrite_font_release); + return (IDWriteFontFace *) (const void *) face->data.directwrite; } +#ifndef HB_DISABLE_DEPRECATED + /** * hb_directwrite_face_get_font_face: * @face: a #hb_face_t object @@ -873,12 +371,106 @@ hb_directwrite_face_create (IDWriteFontFace *font_face) * Return value: DirectWrite IDWriteFontFace object corresponding to the given input * * Since: 2.5.0 +* Deprecated: 10.4.0: Use hb_directwrite_face_get_dw_font_face() instead **/ IDWriteFontFace * hb_directwrite_face_get_font_face (hb_face_t *face) { - return face->data.directwrite->fontFace; + return hb_directwrite_face_get_dw_font_face (face); +} + +#endif + +/** + * hb_directwrite_font_create: + * @dw_face: a DirectWrite IDWriteFontFace object. + * + * Constructs a new font object from the specified DirectWrite IDWriteFontFace. + * + * Return value: #hb_font_t object corresponding to the given input + * + * Since: 11.0.0 + **/ +hb_font_t * +hb_directwrite_font_create (IDWriteFontFace *dw_face) +{ + IDWriteFontFace5 *dw_face5 = nullptr; + + hb_face_t *face = hb_directwrite_face_create (dw_face); + hb_font_t *font = hb_font_create (face); + hb_face_destroy (face); + + if (unlikely (hb_object_is_immutable (font))) + return font; + + /* Copy font variations */ + if (SUCCEEDED (dw_face->QueryInterface (__uuidof (IDWriteFontFace5), (void**) &dw_face5))) + { + if (dw_face5->HasVariations ()) + { + hb_vector_t values; + uint32_t count = dw_face5->GetFontAxisValueCount (); + if (likely (values.resize_exact (count)) && + SUCCEEDED (dw_face5->GetFontAxisValues (values.arrayZ, count))) + { + hb_vector_t vars; + if (likely (vars.resize_exact (count))) + { + for (uint32_t i = 0; i < count; ++i) + { + hb_tag_t tag = hb_uint32_swap (values[i].axisTag); + float value = values[i].value; + vars[i] = {tag, value}; + } + hb_font_set_variations (font, vars.arrayZ, vars.length); + } + } + } + dw_face5->Release (); + } + + /* Let there be dragons here... */ + dw_face->AddRef (); + font->data.directwrite.cmpexch (nullptr, (hb_directwrite_font_data_t *) dw_face); + + return font; +} + +/** +* hb_directwrite_font_get_dw_font_face: +* @font: a #hb_font_t object +* +* Gets the DirectWrite IDWriteFontFace associated with @font. +* +* Return value: DirectWrite IDWriteFontFace object corresponding to the given input +* +* Since: 11.0.0 +**/ +IDWriteFontFace * +hb_directwrite_font_get_dw_font_face (hb_font_t *font) +{ + return (IDWriteFontFace *) (const void *) font->data.directwrite; +} + +#ifndef HB_DISABLE_DEPRECATED + +/** +* hb_directwrite_font_get_dw_font: +* @font: a #hb_font_t object +* +* Deprecated. +* +* Return value: Returns `NULL`. +* +* Since: 10.3.0 +* Deprecated: 11.0.0: +**/ +IDWriteFont * +hb_directwrite_font_get_dw_font (hb_font_t *font) +{ + return nullptr; } +#endif #endif diff --git a/thirdparty/harfbuzz/upstream/hb-directwrite.h b/thirdparty/harfbuzz/upstream/hb-directwrite.h index f837627a2..a05b1a40e 100644 --- a/thirdparty/harfbuzz/upstream/hb-directwrite.h +++ b/thirdparty/harfbuzz/upstream/hb-directwrite.h @@ -27,14 +27,45 @@ #include "hb.h" +#include + HB_BEGIN_DECLS HB_EXTERN hb_face_t * -hb_directwrite_face_create (IDWriteFontFace *font_face); +hb_directwrite_face_create (IDWriteFontFace *dw_face); + +HB_EXTERN hb_face_t * +hb_directwrite_face_create_from_file_or_fail (const char *file_name, + unsigned int index); + +HB_EXTERN hb_face_t * +hb_directwrite_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + +HB_EXTERN IDWriteFontFace * +hb_directwrite_face_get_dw_font_face (hb_face_t *face); + +HB_EXTERN hb_font_t * +hb_directwrite_font_create (IDWriteFontFace *dw_face); +HB_EXTERN IDWriteFontFace * +hb_directwrite_font_get_dw_font_face (hb_font_t *font); + +HB_EXTERN void +hb_directwrite_font_set_funcs (hb_font_t *font); + +#ifndef HB_DISABLE_DEPRECATED + +HB_DEPRECATED_FOR (hb_directwrite_face_get_dw_font_face) HB_EXTERN IDWriteFontFace * hb_directwrite_face_get_font_face (hb_face_t *face); +HB_DEPRECATED +HB_EXTERN IDWriteFont * +hb_directwrite_font_get_dw_font (hb_font_t *font); + +#endif + HB_END_DECLS #endif /* HB_DIRECTWRITE_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-directwrite.hh b/thirdparty/harfbuzz/upstream/hb-directwrite.hh new file mode 100644 index 000000000..6c91b2bf5 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-directwrite.hh @@ -0,0 +1,223 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + + +#ifndef HB_DIRECTWRITE_HH +#define HB_DIRECTWRITE_HH + +#include "hb.hh" + +#include "hb-directwrite.h" + +#include "hb-mutex.hh" +#include "hb-map.hh" + +/* + * DirectWrite font stream helpers + */ + +// Have a look at to NativeFontResourceDWrite.cpp in Mozilla + + +/* Declare object creator for dynamic support of DWRITE */ +typedef HRESULT (WINAPI *t_DWriteCreateFactory)( + DWRITE_FACTORY_TYPE factoryType, + REFIID iid, + IUnknown **factory +); + +class DWriteFontFileLoader : public IDWriteFontFileLoader +{ +private: + hb_reference_count_t mRefCount; + hb_mutex_t mutex; + hb_hashmap_t mFontStreams; + uint64_t mNextFontFileKey = 0; +public: + DWriteFontFileLoader () + { + mRefCount.init (); + } + + uint64_t RegisterFontFileStream (IDWriteFontFileStream *fontFileStream) + { + fontFileStream->AddRef (); + hb_lock_t lock {mutex}; + mFontStreams.set (mNextFontFileKey, fontFileStream); + return mNextFontFileKey++; + } + void UnregisterFontFileStream (uint64_t fontFileKey) + { + hb_lock_t lock {mutex}; + IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey); + if (stream) + { + mFontStreams.del (fontFileKey); + stream->Release (); + } + } + + // IUnknown interface + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) + { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () + { + return mRefCount.inc () + 1; + } + IFACEMETHOD_ (ULONG, Release) () + { + signed refCount = mRefCount.dec () - 1; + assert (refCount >= 0); + if (refCount) + return refCount; + delete this; + return 0; + } + + // IDWriteFontFileLoader methods + virtual HRESULT STDMETHODCALLTYPE + CreateStreamFromKey (void const* fontFileReferenceKey, + uint32_t fontFileReferenceKeySize, + OUT IDWriteFontFileStream** fontFileStream) + { + if (fontFileReferenceKeySize != sizeof (uint64_t)) + return E_INVALIDARG; + uint64_t fontFileKey = * (uint64_t *) fontFileReferenceKey; + IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey); + if (!stream) + return E_FAIL; + stream->AddRef (); + *fontFileStream = stream; + return S_OK; + } + + virtual ~DWriteFontFileLoader() + { + for (auto v : mFontStreams.values ()) + v->Release (); + } +}; + +class DWriteFontFileStream : public IDWriteFontFileStream +{ +private: + hb_reference_count_t mRefCount; + hb_blob_t *mBlob; + uint8_t *mData; + unsigned mSize; + DWriteFontFileLoader *mLoader; +public: + uint64_t fontFileKey; +public: + DWriteFontFileStream (hb_blob_t *blob); + + // IUnknown interface + IFACEMETHOD (QueryInterface) (IID const& iid, OUT void** ppObject) + { return S_OK; } + IFACEMETHOD_ (ULONG, AddRef) () + { + return mRefCount.inc () + 1; + } + IFACEMETHOD_ (ULONG, Release) () + { + signed refCount = mRefCount.dec () - 1; + assert (refCount >= 0); + if (refCount) + return refCount; + delete this; + return 0; + } + + // IDWriteFontFileStream methods + virtual HRESULT STDMETHODCALLTYPE + ReadFileFragment (void const** fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void** fragmentContext) + { + // We are required to do bounds checking. + if (fileOffset + fragmentSize > mSize) return E_FAIL; + + // truncate the 64 bit fileOffset to size_t sized index into mData + size_t index = static_cast (fileOffset); + + // We should be alive for the duration of this. + *fragmentStart = &mData[index]; + *fragmentContext = nullptr; + return S_OK; + } + + virtual void STDMETHODCALLTYPE + ReleaseFileFragment (void* fragmentContext) {} + + virtual HRESULT STDMETHODCALLTYPE + GetFileSize (OUT UINT64* fileSize) + { + *fileSize = mSize; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE + GetLastWriteTime (OUT UINT64* lastWriteTime) { return E_NOTIMPL; } + + virtual ~DWriteFontFileStream(); +}; + +struct hb_directwrite_global_t +{ + hb_directwrite_global_t () + { + HRESULT hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); + + if (unlikely (hr != S_OK)) + return; + + fontFileLoader = new DWriteFontFileLoader (); + dwriteFactory->RegisterFontFileLoader (fontFileLoader); + + success = true; + } + ~hb_directwrite_global_t () + { + if (fontFileLoader) + fontFileLoader->Release (); + if (dwriteFactory) + dwriteFactory->Release (); + } + + bool success = false; + IDWriteFactory *dwriteFactory; + DWriteFontFileLoader *fontFileLoader; +}; + + +HB_INTERNAL hb_directwrite_global_t * +get_directwrite_global (); + +HB_INTERNAL IDWriteFontFace * +dw_face_create (hb_blob_t *blob, unsigned index); + + +#endif /* HB_DIRECTWRITE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-draw.cc b/thirdparty/harfbuzz/upstream/hb-draw.cc index f204f56bc..30ab86d33 100644 --- a/thirdparty/harfbuzz/upstream/hb-draw.cc +++ b/thirdparty/harfbuzz/upstream/hb-draw.cc @@ -28,6 +28,11 @@ #include "hb-draw.hh" +#include "hb-geometry.hh" + +#include "hb-machinery.hh" + + /** * SECTION:hb-draw * @title: hb-draw @@ -58,14 +63,14 @@ hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data, float to_x, float to_y, void *user_data HB_UNUSED) { -#define HB_ONE_THIRD 0.33333333f +#define HB_TWO_THIRD 0.66666666666666666666666667f dfuncs->emit_cubic_to (draw_data, *st, - (st->current_x + 2.f * control_x) * HB_ONE_THIRD, - (st->current_y + 2.f * control_y) * HB_ONE_THIRD, - (to_x + 2.f * control_x) * HB_ONE_THIRD, - (to_y + 2.f * control_y) * HB_ONE_THIRD, + st->current_x + (control_x - st->current_x) * HB_TWO_THIRD, + st->current_y + (control_y - st->current_y) * HB_TWO_THIRD, + to_x + (control_x - to_x) * HB_TWO_THIRD, + to_y + (control_y - to_y) * HB_TWO_THIRD, to_x, to_y); -#undef HB_ONE_THIRD +#undef HB_TWO_THIRD } static void @@ -272,7 +277,7 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the specified draw-functions structure. + * Attaches a user-data key/data pair to the specified draw-functions structure. * * Return value: `true` if success, `false` otherwise * @@ -455,4 +460,92 @@ hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data, } +static void +hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (to_x, to_y); +} + +static void +hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (to_x, to_y); +} + +static void +hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float control_x, float control_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (control_x, control_y); + extents->add_point (to_x, to_y); +} + +static void +hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *data, + hb_draw_state_t *st, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t<> *extents = (hb_extents_t<> *) data; + + extents->add_point (control1_x, control1_y); + extents->add_point (control2_x, control2_y); + extents->add_point (to_x, to_y); +} + +static inline void free_static_draw_extents_funcs (); + +static struct hb_draw_extents_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t +{ + static hb_draw_funcs_t *create () + { + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + + hb_draw_funcs_set_move_to_func (funcs, hb_draw_extents_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, hb_draw_extents_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, hb_draw_extents_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, hb_draw_extents_cubic_to, nullptr, nullptr); + + hb_draw_funcs_make_immutable (funcs); + + hb_atexit (free_static_draw_extents_funcs); + + return funcs; + } +} static_draw_extents_funcs; + +static inline +void free_static_draw_extents_funcs () +{ + static_draw_extents_funcs.free_instance (); +} + +hb_draw_funcs_t * +hb_draw_extents_get_funcs () +{ + return static_draw_extents_funcs.get_unconst (); +} + + #endif diff --git a/thirdparty/harfbuzz/upstream/hb-draw.h b/thirdparty/harfbuzz/upstream/hb-draw.h index 6306b69c0..76aa93f11 100644 --- a/thirdparty/harfbuzz/upstream/hb-draw.h +++ b/thirdparty/harfbuzz/upstream/hb-draw.h @@ -70,7 +70,7 @@ typedef struct hb_draw_state_t { * * The default #hb_draw_state_t at the start of glyph drawing. */ -#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}, {0.}} +#define HB_DRAW_STATE_DEFAULT {0, 0.f, 0.f, 0.f, 0.f, {0}, {0}, {0}, {0}, {0}, {0}, {0}} /** diff --git a/thirdparty/harfbuzz/upstream/hb-draw.hh b/thirdparty/harfbuzz/upstream/hb-draw.hh index 87d03a488..201f2202e 100644 --- a/thirdparty/harfbuzz/upstream/hb-draw.hh +++ b/thirdparty/harfbuzz/upstream/hb-draw.hh @@ -99,6 +99,7 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (st.path_open)) close_path (draw_data, st); + st.current_x = to_x; st.current_y = to_y; } @@ -109,7 +110,9 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + emit_line_to (draw_data, st, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -121,7 +124,9 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -134,7 +139,9 @@ struct hb_draw_funcs_t float to_x, float to_y) { if (unlikely (!st.path_open)) start_path (draw_data, st); + emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y); + st.current_x = to_x; st.current_y = to_y; } @@ -168,9 +175,8 @@ DECLARE_NULL_INSTANCE (hb_draw_funcs_t); struct hb_draw_session_t { - hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_, float slant_ = 0.f) - : slant {slant_}, not_slanted {slant == 0.f}, - funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT + hb_draw_session_t (hb_draw_funcs_t *funcs_, void *draw_data_) + : funcs {funcs_}, draw_data {draw_data_}, st HB_DRAW_STATE_DEFAULT {} ~hb_draw_session_t () { close_path (); } @@ -178,36 +184,23 @@ struct hb_draw_session_t HB_ALWAYS_INLINE void move_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->move_to (draw_data, st, - to_x, to_y); - else - funcs->move_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->move_to (draw_data, st, + to_x, to_y); } HB_ALWAYS_INLINE void line_to (float to_x, float to_y) { - if (likely (not_slanted)) - funcs->line_to (draw_data, st, - to_x, to_y); - else - funcs->line_to (draw_data, st, - to_x + to_y * slant, to_y); + funcs->line_to (draw_data, st, + to_x, to_y); } void HB_ALWAYS_INLINE quadratic_to (float control_x, float control_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->quadratic_to (draw_data, st, - control_x, control_y, - to_x, to_y); - else - funcs->quadratic_to (draw_data, st, - control_x + control_y * slant, control_y, - to_x + to_y * slant, to_y); + funcs->quadratic_to (draw_data, st, + control_x, control_y, + to_x, to_y); } void HB_ALWAYS_INLINE @@ -215,16 +208,10 @@ struct hb_draw_session_t float control2_x, float control2_y, float to_x, float to_y) { - if (likely (not_slanted)) - funcs->cubic_to (draw_data, st, - control1_x, control1_y, - control2_x, control2_y, - to_x, to_y); - else - funcs->cubic_to (draw_data, st, - control1_x + control1_y * slant, control1_y, - control2_x + control2_y * slant, control2_y, - to_x + to_y * slant, to_y); + funcs->cubic_to (draw_data, st, + control1_x, control1_y, + control2_x, control2_y, + to_x, to_y); } HB_ALWAYS_INLINE void close_path () @@ -233,11 +220,14 @@ struct hb_draw_session_t } public: - float slant; - bool not_slanted; hb_draw_funcs_t *funcs; void *draw_data; hb_draw_state_t st; }; + +HB_INTERNAL hb_draw_funcs_t * +hb_draw_extents_get_funcs (); + + #endif /* HB_DRAW_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-face-builder.cc b/thirdparty/harfbuzz/upstream/hb-face-builder.cc index beea89ed2..c3ddcd856 100644 --- a/thirdparty/harfbuzz/upstream/hb-face-builder.cc +++ b/thirdparty/harfbuzz/upstream/hb-face-builder.cc @@ -169,8 +169,7 @@ _hb_face_builder_get_table_tags (const hb_face_t *face HB_UNUSED, if (unlikely (start_offset >= population)) { - if (table_count) - *table_count = 0; + *table_count = 0; return population; } diff --git a/thirdparty/harfbuzz/upstream/hb-face.cc b/thirdparty/harfbuzz/upstream/hb-face.cc index bc0f6d90d..b0cc787d0 100644 --- a/thirdparty/harfbuzz/upstream/hb-face.cc +++ b/thirdparty/harfbuzz/upstream/hb-face.cc @@ -34,6 +34,16 @@ #include "hb-ot-face.hh" #include "hb-ot-cmap-table.hh" +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif +#ifdef HAVE_CORETEXT +#include "hb-coretext.h" +#endif +#ifdef HAVE_DIRECTWRITE +#include "hb-directwrite.h" +#endif + /** * SECTION:hb-face @@ -72,14 +82,13 @@ hb_face_count (hb_blob_t *blob) if (unlikely (!blob)) return 0; - /* TODO We shouldn't be sanitizing blob. Port to run sanitizer and return if not sane. */ - /* Make API signature const after. */ - hb_blob_t *sanitized = hb_sanitize_context_t ().sanitize_blob (hb_blob_reference (blob)); - const OT::OpenTypeFontFile& ot = *sanitized->as (); - unsigned int ret = ot.get_face_count (); - hb_blob_destroy (sanitized); + hb_sanitize_context_t c (blob); + + auto *ot = blob->as (); + if (unlikely (!ot->sanitize (&c))) + return 0; - return ret; + return ot->get_face_count (); } /* @@ -291,6 +300,7 @@ hb_face_create_or_fail (hb_blob_t *blob, return face; } +#ifndef HB_NO_OPEN /** * hb_face_create_from_file_or_fail: * @file_name: A font filename @@ -318,6 +328,209 @@ hb_face_create_from_file_or_fail (const char *file_name, return face; } +static const struct supported_face_loaders_t { + char name[16]; + hb_face_t * (*from_file) (const char *font_file, unsigned face_index); + hb_face_t * (*from_blob) (hb_blob_t *blob, unsigned face_index); +} supported_face_loaders[] = +{ + {"ot", +#ifndef HB_NO_OPEN + hb_face_create_from_file_or_fail, +#else + nullptr, +#endif + hb_face_create_or_fail + }, +#ifdef HAVE_FREETYPE + {"ft", + hb_ft_face_create_from_file_or_fail, + hb_ft_face_create_from_blob_or_fail + }, +#endif +#ifdef HAVE_CORETEXT + {"coretext", + hb_coretext_face_create_from_file_or_fail, + hb_coretext_face_create_from_blob_or_fail + }, +#endif +#ifdef HAVE_DIRECTWRITE + {"directwrite", + hb_directwrite_face_create_from_file_or_fail, + hb_directwrite_face_create_from_blob_or_fail + }, +#endif +}; + +static const char *get_default_loader_name () +{ + static hb_atomic_t static_loader_name; + const char *loader_name = static_loader_name.get_acquire (); + if (!loader_name) + { + loader_name = getenv ("HB_FACE_LOADER"); + if (!loader_name) + loader_name = ""; + if (!static_loader_name.cmpexch (nullptr, loader_name)) + loader_name = static_loader_name.get_acquire (); + } + return loader_name; +} + +/** + * hb_face_create_from_file_or_fail_using: + * @file_name: A font filename + * @index: The index of the face within the file + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, the first available loader + * is used. + * + * For example, the FreeType ("ft") loader might be able to load + * WOFF and WOFF2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * + * Return value: (transfer full): The new face object, or `NULL` if + * the file cannot be read or the loader fails to load the face. + * + * Since: 11.0.0 + **/ +hb_face_t * +hb_face_create_from_file_or_fail_using (const char *file_name, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_file && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_file (file_name, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +/** + * hb_face_create_or_fail_using: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, the first available loader + * is used. + * + * For example, the FreeType ("ft") loader might be able to load + * WOFF and WOFF2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * + * Return value: (transfer full): The new face object, or `NULL` if + * the loader fails to load the face. + * + * Since: 11.0.0 + **/ +hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_from_file_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_blob && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_blob (blob, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +static inline void free_static_face_loader_list (); + +static const char * const nil_face_loader_list[] = {nullptr}; + +static struct hb_face_loader_list_lazy_loader_t : hb_lazy_loader_t +{ + static const char ** create () + { + const char **face_loader_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_face_loaders), sizeof (const char *)); + if (unlikely (!face_loader_list)) + return nullptr; + + unsigned i; + for (i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + face_loader_list[i] = supported_face_loaders[i].name; + face_loader_list[i] = nullptr; + + hb_atexit (free_static_face_loader_list); + + return face_loader_list; + } + static void destroy (const char **l) + { hb_free (l); } + static const char * const * get_null () + { return nil_face_loader_list; } +} static_face_loader_list; + +static inline +void free_static_face_loader_list () +{ + static_face_loader_list.free_instance (); +} + +/** + * hb_face_list_loaders: + * + * Retrieves the list of face loaders supported by HarfBuzz. + * + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported face loaders + * constant strings. The returned array is owned by HarfBuzz + * and should not be modified or freed. + * + * Since: 11.0.0 + **/ +const char ** +hb_face_list_loaders () +{ + return static_face_loader_list.get_unconst (); +} +#endif + + /** * hb_face_get_empty: * @@ -458,7 +671,7 @@ hb_face_make_immutable (hb_face_t *face) * Since: 0.9.2 **/ hb_bool_t -hb_face_is_immutable (const hb_face_t *face) +hb_face_is_immutable (hb_face_t *face) { return hb_object_is_immutable (face); } @@ -470,7 +683,8 @@ hb_face_is_immutable (const hb_face_t *face) * @tag: The #hb_tag_t of the table to query * * Fetches a reference to the specified table within - * the specified face. + * the specified face. Returns an empty blob if referencing table data is not + * possible. * * Return value: (transfer full): A pointer to the @tag table within @face * @@ -490,9 +704,10 @@ hb_face_reference_table (const hb_face_t *face, * hb_face_reference_blob: * @face: A face object * - * Fetches a pointer to the binary blob that contains the - * specified face. Returns an empty blob if referencing face data is not - * possible. + * Fetches a pointer to the binary blob that contains the specified face. + * If referencing the face data is not possible, this function creates a blob + * out of individual table blobs if hb_face_get_table_tags() works with this + * face, otherwise it returns an empty blob. * * Return value: (transfer full): A pointer to the blob for @face * @@ -501,7 +716,41 @@ hb_face_reference_table (const hb_face_t *face, hb_blob_t * hb_face_reference_blob (hb_face_t *face) { - return face->reference_table (HB_TAG_NONE); + hb_blob_t *blob = face->reference_table (HB_TAG_NONE); + + if (blob == hb_blob_get_empty ()) + { + // If referencing the face blob is not possible (e.g. not implemented by the + // font functions), use face builder to create a blob out of individual + // table blobs. + unsigned total_count = hb_face_get_table_tags (face, 0, nullptr, nullptr); + if (total_count) + { + hb_tag_t tags[64]; + unsigned count = ARRAY_LENGTH (tags); + hb_face_t* builder = hb_face_builder_create (); + + for (unsigned offset = 0; offset < total_count; offset += count) + { + hb_face_get_table_tags (face, offset, &count, tags); + if (unlikely (!count)) + break; // Allocation error + for (unsigned i = 0; i < count; i++) + { + if (unlikely (!tags[i])) + continue; + hb_blob_t *table = hb_face_reference_table (face, tags[i]); + hb_face_builder_add_table (builder, tags[i], table); + hb_blob_destroy (table); + } + } + + blob = hb_face_reference_blob (builder); + hb_face_destroy (builder); + } + } + + return blob; } /** @@ -643,6 +892,7 @@ hb_face_set_get_table_tags_func (hb_face_t *face, { if (destroy) destroy (user_data); + return; } if (face->get_table_tags_destroy) diff --git a/thirdparty/harfbuzz/upstream/hb-face.h b/thirdparty/harfbuzz/upstream/hb-face.h index 8aec681cf..b8386f0af 100644 --- a/thirdparty/harfbuzz/upstream/hb-face.h +++ b/thirdparty/harfbuzz/upstream/hb-face.h @@ -63,19 +63,38 @@ HB_EXTERN hb_face_t * hb_face_create_or_fail (hb_blob_t *blob, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name); + HB_EXTERN hb_face_t * hb_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_from_file_or_fail_using (const char *file_name, + unsigned int index, + const char *loader_name); + +HB_EXTERN const char ** +hb_face_list_loaders (void); + + /** * hb_reference_table_func_t: * @face: an #hb_face_t to reference table for * @tag: the tag of the table to reference * @user_data: User data pointer passed by the caller * - * Callback function for hb_face_create_for_tables(). + * Callback function for hb_face_create_for_tables(). The @tag is the tag of the + * table to reference, and the special tag #HB_TAG_NONE is used to reference the + * blob of the face itself. If referencing the face blob is not possible, it is + * recommended to set hb_get_table_tags_func_t on the @face to allow + * hb_face_reference_blob() to create a face blob out of individual table blobs. * - * Return value: (transfer full): A pointer to the @tag table within @face + * Return value: (transfer full): A pointer to the @tag table within @face or + * `NULL` if the table is not found or cannot be referenced. * * Since: 0.9.2 */ @@ -112,7 +131,7 @@ HB_EXTERN void hb_face_make_immutable (hb_face_t *face); HB_EXTERN hb_bool_t -hb_face_is_immutable (const hb_face_t *face); +hb_face_is_immutable (hb_face_t *face); HB_EXTERN hb_blob_t * diff --git a/thirdparty/harfbuzz/upstream/hb-face.hh b/thirdparty/harfbuzz/upstream/hb-face.hh index 640156832..77c243721 100644 --- a/thirdparty/harfbuzz/upstream/hb-face.hh +++ b/thirdparty/harfbuzz/upstream/hb-face.hh @@ -49,8 +49,8 @@ struct hb_face_t hb_object_header_t header; unsigned int index; /* Face index in a collection, zero-based. */ - mutable hb_atomic_int_t upem; /* Units-per-EM. */ - mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ + mutable hb_atomic_t upem; /* Units-per-EM. */ + mutable hb_atomic_t num_glyphs;/* Number of glyphs. */ hb_reference_table_func_t reference_table_func; void *user_data; @@ -70,7 +70,7 @@ struct hb_face_t plan_node_t *next; }; #ifndef HB_NO_SHAPER - hb_atomic_ptr_t shape_plans; + hb_atomic_t shape_plans; #endif hb_blob_t *reference_table (hb_tag_t tag) const diff --git a/thirdparty/harfbuzz/upstream/hb-features.h.in b/thirdparty/harfbuzz/upstream/hb-features.h.in deleted file mode 100644 index 4b27bd5e7..000000000 --- a/thirdparty/harfbuzz/upstream/hb-features.h.in +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright © 2022 Red Hat, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#ifndef HB_FEATURES_H -#define HB_FEATURES_H - -HB_BEGIN_DECLS - -/** - * SECTION: hb-features - * @title: hb-features - * @short_description: Feature detection - * @include: hb-features.h - * - * Macros for detecting optional HarfBuzz features at build time. - **/ - -/** - * HB_HAS_CAIRO: - * - * Defined if Harfbuzz has been built with cairo support. - */ -#mesondefine HB_HAS_CAIRO - -/** - * HB_HAS_CORETEXT: - * - * Defined if Harfbuzz has been built with CoreText support. - */ -#mesondefine HB_HAS_CORETEXT - -/** - * HB_HAS_DIRECTWRITE: - * - * Defined if Harfbuzz has been built with DirectWrite support. - */ -#mesondefine HB_HAS_DIRECTWRITE - -/** - * HB_HAS_FREETYPE: - * - * Defined if Harfbuzz has been built with Freetype support. - */ -#mesondefine HB_HAS_FREETYPE - -/** - * HB_HAS_GDI: - * - * Defined if Harfbuzz has been built with GDI support. - */ -#mesondefine HB_HAS_GDI - -/** - * HB_HAS_GLIB: - * - * Defined if Harfbuzz has been built with GLib support. - */ -#mesondefine HB_HAS_GLIB - -/** - * HB_HAS_GOBJECT: - * - * Defined if Harfbuzz has been built with GObject support. - */ -#mesondefine HB_HAS_GOBJECT - -/** - * HB_HAS_GRAPHITE: - * - * Defined if Harfbuzz has been built with Graphite support. - */ -#mesondefine HB_HAS_GRAPHITE - -/** - * HB_HAS_ICU: - * - * Defined if Harfbuzz has been built with ICU support. - */ -#mesondefine HB_HAS_ICU - -/** - * HB_HAS_UNISCRIBE: - * - * Defined if Harfbuzz has been built with Uniscribe support. - */ -#mesondefine HB_HAS_UNISCRIBE - -/** - * HB_HAS_WASM: - * - * Defined if Harfbuzz has been built with WebAssembly support. - */ -#mesondefine HB_HAS_WASM - - -HB_END_DECLS - -#endif /* HB_FEATURES_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-font.cc b/thirdparty/harfbuzz/upstream/hb-font.cc index 96b79ecca..fe94e2ea6 100644 --- a/thirdparty/harfbuzz/upstream/hb-font.cc +++ b/thirdparty/harfbuzz/upstream/hb-font.cc @@ -38,6 +38,22 @@ #include "hb-ot-var-avar-table.hh" #include "hb-ot-var-fvar-table.hh" +#ifndef HB_NO_OT_FONT +#include "hb-ot.h" +#endif +#ifdef HAVE_FREETYPE +#include "hb-ft.h" +#endif +#ifdef HAVE_FONTATIONS +#include "hb-fontations.h" +#endif +#ifdef HAVE_CORETEXT +#include "hb-coretext.h" +#endif +#ifdef HAVE_DIRECTWRITE +#include "hb-directwrite.h" +#endif + /** * SECTION:hb-font @@ -87,7 +103,7 @@ hb_font_get_font_h_extents_default (hb_font_t *font, hb_font_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_font_h_extents (extents); + hb_bool_t ret = font->parent->get_font_h_extents (extents, false); if (ret) { extents->ascender = font->parent_scale_y_distance (extents->ascender); extents->descender = font->parent_scale_y_distance (extents->descender); @@ -112,7 +128,7 @@ hb_font_get_font_v_extents_default (hb_font_t *font, hb_font_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_font_v_extents (extents); + hb_bool_t ret = font->parent->get_font_v_extents (extents, false); if (ret) { extents->ascender = font->parent_scale_x_distance (extents->ascender); extents->descender = font->parent_scale_x_distance (extents->descender); @@ -218,10 +234,10 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font, if (font->has_glyph_h_advances_func_set ()) { hb_position_t ret; - font->get_glyph_h_advances (1, &glyph, 0, &ret, 0); + font->get_glyph_h_advances (1, &glyph, 0, &ret, 0, false); return ret; } - return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); + return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph, false)); } static hb_position_t @@ -230,7 +246,6 @@ hb_font_get_glyph_v_advance_nil (hb_font_t *font, hb_codepoint_t glyph HB_UNUSED, void *user_data HB_UNUSED) { - /* TODO use font_extents.ascender+descender */ return -font->y_scale; } @@ -243,10 +258,10 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font, if (font->has_glyph_v_advances_func_set ()) { hb_position_t ret; - font->get_glyph_v_advances (1, &glyph, 0, &ret, 0); + font->get_glyph_v_advances (1, &glyph, 0, &ret, 0, false); return ret; } - return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); + return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph, false)); } #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default @@ -265,7 +280,7 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font, { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->get_glyph_h_advance (*first_glyph); + *first_advance = font->get_glyph_h_advance (*first_glyph, false); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } @@ -274,7 +289,8 @@ hb_font_get_glyph_h_advances_default (hb_font_t* font, font->parent->get_glyph_h_advances (count, first_glyph, glyph_stride, - first_advance, advance_stride); + first_advance, advance_stride, + false); for (unsigned int i = 0; i < count; i++) { *first_advance = font->parent_scale_x_distance (*first_advance); @@ -297,7 +313,7 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->get_glyph_v_advance (*first_glyph); + *first_advance = font->get_glyph_v_advance (*first_glyph, false); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } @@ -306,7 +322,8 @@ hb_font_get_glyph_v_advances_default (hb_font_t* font, font->parent->get_glyph_v_advances (count, first_glyph, glyph_stride, - first_advance, advance_stride); + first_advance, advance_stride, + false); for (unsigned int i = 0; i < count; i++) { *first_advance = font->parent_scale_y_distance (*first_advance); @@ -334,6 +351,10 @@ hb_font_get_glyph_h_origin_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { + if (font->has_glyph_h_origins_func_set ()) + { + return font->get_glyph_h_origins (1, &glyph, 0, x, 0, y, 0, false); + } hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); if (ret) font->parent_scale_position (x, y); @@ -348,7 +369,6 @@ hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, hb_position_t *y, void *user_data HB_UNUSED) { - *x = *y = 0; return false; } @@ -360,12 +380,100 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { + if (font->has_glyph_v_origins_func_set ()) + { + return font->get_glyph_v_origins (1, &glyph, 0, x, 0, y, 0, false); + } hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); if (ret) font->parent_scale_position (x, y); return ret; } +#define hb_font_get_glyph_h_origins_nil hb_font_get_glyph_h_origins_default + +static hb_bool_t +hb_font_get_glyph_h_origins_default (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_glyph HB_UNUSED, + unsigned glyph_stride HB_UNUSED, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) +{ + if (font->has_glyph_h_origin_func_set ()) + { + for (unsigned int i = 0; i < count; i++) + { + font->get_glyph_h_origin (*first_glyph, first_x, first_y, false); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + return true; + } + + hb_bool_t ret = font->parent->get_glyph_h_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); + if (ret) + { + for (unsigned i = 0; i < count; i++) + { + font->parent_scale_position (first_x, first_y); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + return ret; +} + +#define hb_font_get_glyph_v_origins_nil hb_font_get_glyph_v_origins_default + +static hb_bool_t +hb_font_get_glyph_v_origins_default (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + unsigned int count, + const hb_codepoint_t *first_glyph HB_UNUSED, + unsigned glyph_stride HB_UNUSED, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) +{ + if (font->has_glyph_v_origin_func_set ()) + { + for (unsigned int i = 0; i < count; i++) + { + font->get_glyph_v_origin (*first_glyph, first_x, first_y, false); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + return true; + } + + hb_bool_t ret = font->parent->get_glyph_v_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); + if (ret) + { + for (unsigned i = 0; i < count; i++) + { + font->parent_scale_position (first_x, first_y); + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + return ret; +} + static hb_position_t hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, @@ -426,7 +534,7 @@ hb_font_get_glyph_extents_default (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); + hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents, false); if (ret) { font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); font->parent_scale_distance (&extents->width, &extents->height); @@ -456,7 +564,7 @@ hb_font_get_glyph_contour_point_default (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { - hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); + hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y, false); if (ret) font->parent_scale_position (x, y); return ret; @@ -508,26 +616,28 @@ hb_font_get_glyph_from_name_default (hb_font_t *font, return font->parent->get_glyph_from_name (name, len, glyph); } -static void -hb_font_draw_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, - void *draw_data, - void *user_data HB_UNUSED) +static hb_bool_t +hb_font_draw_glyph_or_fail_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data HB_UNUSED) { + return false; } -static void -hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - hb_paint_funcs_t *paint_funcs HB_UNUSED, - void *paint_data HB_UNUSED, - unsigned int palette HB_UNUSED, - hb_color_t foreground HB_UNUSED, - void *user_data HB_UNUSED) +static hb_bool_t +hb_font_paint_glyph_or_fail_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_paint_funcs_t *paint_funcs HB_UNUSED, + void *paint_data HB_UNUSED, + unsigned int palette HB_UNUSED, + hb_color_t foreground HB_UNUSED, + void *user_data HB_UNUSED) { + return false; } typedef struct hb_font_draw_glyph_default_adaptor_t { @@ -535,7 +645,6 @@ typedef struct hb_font_draw_glyph_default_adaptor_t { void *draw_data; float x_scale; float y_scale; - float slant; } hb_font_draw_glyph_default_adaptor_t; static void @@ -548,10 +657,9 @@ hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * to_x, y_scale * to_y); } static void @@ -563,13 +671,12 @@ hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; - st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_x = st->current_x * x_scale; st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * to_x, y_scale * to_y); } static void @@ -582,14 +689,13 @@ hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; - st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_x = st->current_x * x_scale; st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st, - x_scale * control_x + slant * control_y, y_scale * control_y, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * control_x, y_scale * control_y, + x_scale * to_x, y_scale * to_y); } static void @@ -603,15 +709,14 @@ hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data, hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data; float x_scale = adaptor->x_scale; float y_scale = adaptor->y_scale; - float slant = adaptor->slant; - st->current_x = st->current_x * x_scale + st->current_y * slant; + st->current_x = st->current_x * x_scale; st->current_y = st->current_y * y_scale; adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st, - x_scale * control1_x + slant * control1_y, y_scale * control1_y, - x_scale * control2_x + slant * control2_y, y_scale * control2_y, - x_scale * to_x + slant * to_y, y_scale * to_y); + x_scale * control1_x, y_scale * control1_y, + x_scale * control2_x, y_scale * control2_y, + x_scale * to_x, y_scale * to_y); } static void @@ -634,49 +739,47 @@ static const hb_draw_funcs_t _hb_draw_funcs_default = { } }; -static void -hb_font_draw_glyph_default (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, - void *draw_data, - void *user_data HB_UNUSED) +static hb_bool_t +hb_font_draw_glyph_or_fail_default (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data HB_UNUSED) { hb_font_draw_glyph_default_adaptor_t adaptor = { draw_funcs, draw_data, font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, - font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, - font->parent->y_scale ? (font->slant - font->parent->slant) * - (float) font->x_scale / (float) font->parent->y_scale : 0.f + font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f }; - font->parent->draw_glyph (glyph, - const_cast (&_hb_draw_funcs_default), - &adaptor); + return font->parent->draw_glyph_or_fail (glyph, + const_cast (&_hb_draw_funcs_default), + &adaptor, + false); } -static void -hb_font_paint_glyph_default (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, - void *paint_data, - unsigned int palette, - hb_color_t foreground, - void *user_data) +static hb_bool_t +hb_font_paint_glyph_or_fail_default (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) { paint_funcs->push_transform (paint_data, - font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f, - font->parent->y_scale ? (font->slant - font->parent->slant) * - (float) font->x_scale / (float) font->parent->y_scale : 0.f, - 0.f, - font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f, - 0.f, 0.f); + font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0, 0, + 0, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0, + 0, 0); - font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground); + bool ret = font->parent->paint_glyph_or_fail (glyph, paint_funcs, paint_data, palette, foreground); paint_funcs->pop_transform (paint_data); + + return ret; } DEFINE_NULL_INSTANCE (hb_font_funcs_t) = @@ -1243,6 +1346,77 @@ hb_font_get_glyph_v_origin (hb_font_t *font, return font->get_glyph_v_origin (glyph, x, y); } +/** + * hb_font_get_glyph_h_origins: + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first X coordinate of the origin retrieved + * @x_stride: The stride between successive X coordinates + * @first_y: (out): The first Y coordinate of the origin retrieved + * @y_stride: The stride between successive Y coordinates + * + * Fetches the (X,Y) coordinates of the origin for requested glyph IDs + * in the specified font, for horizontal text segments. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +hb_bool_t +hb_font_get_glyph_h_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride) + +{ + return font->get_glyph_h_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); +} + +/** + * hb_font_get_glyph_v_origins: + * @font: #hb_font_t to work upon + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first X coordinate of the origin retrieved + * @x_stride: The stride between successive X coordinates + * @first_y: (out): The first Y coordinate of the origin retrieved + * @y_stride: The stride between successive Y coordinates + * + * Fetches the (X,Y) coordinates of the origin for requested glyph IDs + * in the specified font, for vertical text segments. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +hb_bool_t +hb_font_get_glyph_v_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride) + +{ + return font->get_glyph_v_origins (count, + first_glyph, glyph_stride, + first_x, x_stride, + first_y, y_stride); +} + + /** * hb_font_get_glyph_h_kerning: * @font: #hb_font_t to work upon @@ -1413,6 +1587,92 @@ hb_font_get_glyph_shape (hb_font_t *font, } #endif +/** + * hb_font_draw_glyph_or_fail: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID + * @dfuncs: #hb_draw_funcs_t to draw to + * @draw_data: User data to pass to draw callbacks + * + * Draws the outline that corresponds to a glyph in the specified @font. + * + * This is a newer name for hb_font_draw_glyph(), that returns `false` + * if the font has no outlines for the glyph. + * + * The outline is returned by way of calls to the callbacks of the @dfuncs + * objects, with @draw_data passed to them. + * + * Return value: `true` if glyph was drawn, `false` otherwise + * + * Since: 11.2.0 + **/ +hb_bool_t +hb_font_draw_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + return font->draw_glyph_or_fail (glyph, dfuncs, draw_data); +} + +/** + * hb_font_paint_glyph_or_fail: + * @font: #hb_font_t to work upon + * @glyph: The glyph ID + * @pfuncs: #hb_paint_funcs_t to paint with + * @paint_data: User data to pass to paint callbacks + * @palette_index: The index of the font's color palette to use + * @foreground: The foreground color, unpremultipled + * + * Paints a color glyph. + * + * This function is similar to, but lower-level than, + * hb_font_paint_glyph(). It is suitable for clients that + * need more control. If there are no color glyphs available, + * it will return `false`. The client can then fall back to + * hb_font_draw_glyph_or_fail() for the monochrome outline glyph. + * + * The painting instructions are returned by way of calls to + * the callbacks of the @funcs object, with @paint_data passed + * to them. + * + * If the font has color palettes (see hb_ot_color_has_palettes()), + * then @palette_index selects the palette to use. If the font only + * has one palette, this will be 0. + * + * Return value: `true` if glyph was painted, `false` otherwise + * + * Since: 11.2.0 + */ +hb_bool_t +hb_font_paint_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground) +{ + return font->paint_glyph_or_fail (glyph, pfuncs, paint_data, palette_index, foreground); +} + +/* A bit higher-level, and with fallback */ + +void +hb_font_t::paint_glyph (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground) +{ + if (paint_glyph_or_fail (glyph, + paint_funcs, paint_data, + palette, foreground)) + return; + + /* Fallback for outline glyph. */ + paint_funcs->push_clip_glyph (paint_data, glyph, this); + paint_funcs->color (paint_data, true, foreground); + paint_funcs->pop_clip (paint_data); +} + + /** * hb_font_draw_glyph: * @font: #hb_font_t to work upon @@ -1422,6 +1682,9 @@ hb_font_get_glyph_shape (hb_font_t *font, * * Draws the outline that corresponds to a glyph in the specified @font. * + * This is an older name for hb_font_draw_glyph_or_fail(), with no + * return value. + * * The outline is returned by way of calls to the callbacks of the @dfuncs * objects, with @draw_data passed to them. * @@ -1429,10 +1692,10 @@ hb_font_get_glyph_shape (hb_font_t *font, **/ void hb_font_draw_glyph (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_funcs_t *dfuncs, void *draw_data) + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data) { - font->draw_glyph (glyph, dfuncs, draw_data); + (void) hb_font_draw_glyph_or_fail (font, glyph, dfuncs, draw_data); } /** @@ -1444,7 +1707,10 @@ hb_font_draw_glyph (hb_font_t *font, * @palette_index: The index of the font's color palette to use * @foreground: The foreground color, unpremultipled * - * Paints the glyph. + * Paints the glyph. This function is similar to + * hb_font_paint_glyph_or_fail(), but if painting a color glyph + * failed, it will fall back to painting an outline monochrome + * glyph. * * The painting instructions are returned by way of calls to * the callbacks of the @funcs object, with @paint_data passed @@ -1466,8 +1732,6 @@ hb_font_paint_glyph (hb_font_t *font, font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground); } -/* A bit higher-level, and with fallback */ - /** * hb_font_get_extents_for_direction: * @font: #hb_font_t to work upon @@ -1780,6 +2044,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* x_scale */ 1000, /* y_scale */ + false, /* is_synthetic */ 0.f, /* x_embolden */ 0.f, /* y_embolden */ true, /* embolden_in_place */ @@ -1797,6 +2062,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 0, /* ptem */ HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */ + false, /* has_nonzero_coords */ 0, /* num_coords */ nullptr, /* coords */ nullptr, /* design_coords */ @@ -1854,14 +2120,17 @@ hb_font_create (hb_face_t *face) { hb_font_t *font = _hb_font_create (face); -#ifndef HB_NO_OT_FONT - /* Install our in-house, very lightweight, funcs. */ - hb_ot_font_set_funcs (font); -#endif + hb_font_set_funcs_using (font, nullptr); #ifndef HB_NO_VAR - if (face && face->index >> 16) - hb_font_set_var_named_instance (font, (face->index >> 16) - 1); + // Initialize variations. + if (likely (face)) + { + if (face->index >> 16) + hb_font_set_var_named_instance (font, (face->index >> 16) - 1); + else + hb_font_set_variations (font, nullptr, 0); + } #endif return font; @@ -1879,8 +2148,10 @@ _hb_font_adopt_var_coords (hb_font_t *font, font->coords = coords; font->design_coords = design_coords; font->num_coords = coords_length; + font->has_nonzero_coords = hb_any (hb_array (coords, coords_length)); - font->mults_changed (); // Easiest to call this to drop cached data + font->changed (); + font->serial_coords = font->serial; } /** @@ -1935,7 +2206,8 @@ hb_font_create_sub_font (hb_font_t *parent) } } - font->mults_changed (); + font->changed (); + font->serial_coords = font->serial; return font; } @@ -2023,7 +2295,7 @@ hb_font_set_user_data (hb_font_t *font, hb_bool_t replace) { if (!hb_object_is_immutable (font)) - font->serial++; + font->changed (); return hb_object_set_user_data (font, key, data, destroy, replace); } @@ -2098,7 +2370,7 @@ hb_font_is_immutable (hb_font_t *font) unsigned int hb_font_get_serial (hb_font_t *font) { - return font->serial; + return font->serial.get_acquire (); } /** @@ -2117,9 +2389,7 @@ hb_font_changed (hb_font_t *font) if (hb_object_is_immutable (font)) return; - font->serial++; - - font->mults_changed (); + font->changed (); } /** @@ -2141,8 +2411,6 @@ hb_font_set_parent (hb_font_t *font, if (parent == font->parent) return; - font->serial++; - if (!parent) parent = hb_font_get_empty (); @@ -2151,6 +2419,8 @@ hb_font_set_parent (hb_font_t *font, font->parent = hb_font_reference (parent); hb_font_destroy (old); + + font->changed (); } /** @@ -2188,8 +2458,6 @@ hb_font_set_face (hb_font_t *font, if (face == font->face) return; - font->serial++; - if (unlikely (!face)) face = hb_face_get_empty (); @@ -2197,9 +2465,12 @@ hb_font_set_face (hb_font_t *font, hb_face_make_immutable (face); font->face = hb_face_reference (face); - font->mults_changed (); + font->changed (); hb_face_destroy (old); + + font->changed (); + font->serial_coords = font->serial; } /** @@ -2244,8 +2515,6 @@ hb_font_set_funcs (hb_font_t *font, return; } - font->serial++; - if (font->destroy) font->destroy (font->user_data); @@ -2257,6 +2526,8 @@ hb_font_set_funcs (hb_font_t *font, font->klass = klass; font->user_data = font_data; font->destroy = destroy; + + font->changed (); } /** @@ -2283,15 +2554,154 @@ hb_font_set_funcs_data (hb_font_t *font, return; } - font->serial++; - if (font->destroy) font->destroy (font->user_data); font->user_data = font_data; font->destroy = destroy; + + font->changed (); } +static const struct supported_font_funcs_t { + char name[16]; + void (*func) (hb_font_t *); +} supported_font_funcs[] = +{ +#ifndef HB_NO_OT_FONT + {"ot", hb_ot_font_set_funcs}, +#endif +#ifdef HAVE_FREETYPE + {"ft", hb_ft_font_set_funcs}, +#endif +#ifdef HAVE_FONTATIONS + {"fontations",hb_fontations_font_set_funcs}, +#endif +#ifdef HAVE_CORETEXT + {"coretext", hb_coretext_font_set_funcs}, +#endif +#ifdef HAVE_DIRECTWRITE + {"directwrite",hb_directwrite_font_set_funcs}, +#endif +}; + +static const char *get_default_funcs_name () +{ + static hb_atomic_t static_funcs_name; + const char *name = static_funcs_name.get_acquire (); + if (!name) + { + name = getenv ("HB_FONT_FUNCS"); + if (!name) + name = ""; + if (!static_funcs_name.cmpexch (nullptr, name)) + name = static_funcs_name.get_acquire (); + } + return name; +} + +/** + * hb_font_set_funcs_using: + * @font: #hb_font_t to work upon + * @name: The name of the font-functions structure to use, or `NULL` + * + * Sets the font-functions structure to use for a font, based on the + * specified name. + * + * If @name is `NULL` or the empty string, the default (first) functioning font-functions + * are used. This default can be changed by setting the `HB_FONT_FUNCS` environment + * variable to the name of the desired font-functions. + * + * Return value: `true` if the font-functions was found and set, `false` otherwise + * + * Since: 11.0.0 + **/ +hb_bool_t +hb_font_set_funcs_using (hb_font_t *font, + const char *name) +{ + if (unlikely (hb_object_is_immutable (font))) + return false; + + bool retry = false; + + if (!name || !*name) + { + name = get_default_funcs_name (); + retry = true; + } + if (name && !*name) name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + if (!name || strcmp (supported_font_funcs[i].name, name) == 0) + { + supported_font_funcs[i].func (font); + if (name || font->klass != hb_font_funcs_get_empty ()) + return true; + } + + if (retry) + { + retry = false; + name = nullptr; + goto retry; + } + + return false; +} + +static inline void free_static_font_funcs_list (); + +static const char * const nil_font_funcs_list[] = {nullptr}; + +static struct hb_font_funcs_list_lazy_loader_t : hb_lazy_loader_t +{ + static const char ** create () + { + const char **font_funcs_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_font_funcs), sizeof (const char *)); + if (unlikely (!font_funcs_list)) + return nullptr; + + unsigned i; + for (i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + font_funcs_list[i] = supported_font_funcs[i].name; + font_funcs_list[i] = nullptr; + + hb_atexit (free_static_font_funcs_list); + + return font_funcs_list; + } + static void destroy (const char **l) + { hb_free (l); } + static const char * const * get_null () + { return nil_font_funcs_list; } +} static_font_funcs_list; + +static inline +void free_static_font_funcs_list () +{ + static_font_funcs_list.free_instance (); +} + +/** + * hb_font_list_funcs: + * + * Retrieves the list of font functions supported by HarfBuzz. + * + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported font functions + * constant strings. The returned array is owned by HarfBuzz + * and should not be modified or freed. + * + * Since: 11.0.0 + **/ +const char ** +hb_font_list_funcs () +{ + return static_font_funcs_list.get_unconst (); +} /** * hb_font_set_scale: @@ -2339,11 +2749,10 @@ hb_font_set_scale (hb_font_t *font, if (font->x_scale == x_scale && font->y_scale == y_scale) return; - font->serial++; - font->x_scale = x_scale; font->y_scale = y_scale; - font->mults_changed (); + + font->changed (); } /** @@ -2390,10 +2799,10 @@ hb_font_set_ppem (hb_font_t *font, if (font->x_ppem == x_ppem && font->y_ppem == y_ppem) return; - font->serial++; - font->x_ppem = x_ppem; font->y_ppem = y_ppem; + + font->changed (); } /** @@ -2437,9 +2846,9 @@ hb_font_set_ptem (hb_font_t *font, if (font->ptem == ptem) return; - font->serial++; - font->ptem = ptem; + + font->changed (); } /** @@ -2459,6 +2868,23 @@ hb_font_get_ptem (hb_font_t *font) return font->ptem; } +/** + * hb_font_is_synthetic: + * @font: #hb_font_t to work upon + * + * Tests whether a font is synthetic. A synthetic font is one + * that has either synthetic slant or synthetic bold set on it. + * + * Return value: `true` if the font is synthetic, `false` otherwise. + * + * Since: 11.2.0 + */ +hb_bool_t +hb_font_is_synthetic (hb_font_t *font) +{ + return font->is_synthetic; +} + /** * hb_font_set_synthetic_bold: * @font: #hb_font_t to work upon @@ -2476,7 +2902,7 @@ hb_font_get_ptem (hb_font_t *font) * points of the glyph shape. * * Synthetic boldness is applied when rendering a glyph via - * hb_font_draw_glyph(). + * hb_font_draw_glyph_or_fail(). * * If @in_place is `false`, then glyph advance-widths are also * adjusted, otherwise they are not. The in-place mode is @@ -2499,12 +2925,11 @@ hb_font_set_synthetic_bold (hb_font_t *font, font->embolden_in_place == (bool) in_place) return; - font->serial++; - font->x_embolden = x_embolden; font->y_embolden = y_embolden; font->embolden_in_place = in_place; - font->mults_changed (); + + font->changed (); } /** @@ -2541,7 +2966,7 @@ hb_font_get_synthetic_bold (hb_font_t *font, * HarfBuzz needs to know this value to adjust shaping results, * metrics, and style values to match the slanted rendering. * - * Note: The glyph shape fetched via the hb_font_draw_glyph() + * Note: The glyph shape fetched via the hb_font_draw_glyph_or_fail() * function is slanted to reflect this value as well. * * Note: The slant value is a ratio. For example, a @@ -2558,10 +2983,9 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant) if (font->slant == slant) return; - font->serial++; - font->slant = slant; - font->mults_changed (); + + font->changed (); } /** @@ -2607,14 +3031,6 @@ hb_font_set_variations (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - - if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE) - { - hb_font_set_var_coords_normalized (font, nullptr, 0); - return; - } - const OT::fvar &fvar = *font->face->table.fvar; auto axes = fvar.get_axes (); const unsigned coords_length = axes.length; @@ -2677,8 +3093,6 @@ hb_font_set_variation (hb_font_t *font, if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; - // TODO Share some of this code with set_variations() const OT::fvar &fvar = *font->face->table.fvar; @@ -2723,7 +3137,6 @@ hb_font_set_variation (hb_font_t *font, hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); - } /** @@ -2744,13 +3157,16 @@ hb_font_set_variation (hb_font_t *font, void hb_font_set_var_coords_design (hb_font_t *font, const float *coords, - unsigned int coords_length) + unsigned int input_coords_length) { if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; + input_coords_length = hb_min (input_coords_length, coords_length); int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -2761,8 +3177,11 @@ hb_font_set_var_coords_design (hb_font_t *font, return; } - if (coords_length) - hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0])); + if (input_coords_length) + hb_memcpy (design_coords, coords, input_coords_length * sizeof (font->design_coords[0])); + // Fill in the rest with default values + for (unsigned int i = input_coords_length; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); @@ -2787,8 +3206,6 @@ hb_font_set_var_named_instance (hb_font_t *font, if (font->instance_index == instance_index) return; - font->serial_coords = ++font->serial; - font->instance_index = instance_index; hb_font_set_variations (font, nullptr, 0); } @@ -2829,36 +3246,31 @@ hb_font_get_var_named_instance (hb_font_t *font) void hb_font_set_var_coords_normalized (hb_font_t *font, const int *coords, /* 2.14 normalized */ - unsigned int coords_length) + unsigned int input_coords_length) { if (hb_object_is_immutable (font)) return; - font->serial_coords = ++font->serial; + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + unsigned coords_length = axes.length; + input_coords_length = hb_min (input_coords_length, coords_length); int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; - int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; - if (unlikely (coords_length && !(copy && unmapped && design_coords))) + if (unlikely (coords_length && !(copy && design_coords))) { hb_free (copy); - hb_free (unmapped); hb_free (design_coords); return; } - if (coords_length) - { - hb_memcpy (copy, coords, coords_length * sizeof (coords[0])); - hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0])); - } + if (input_coords_length) + hb_memcpy (copy, coords, input_coords_length * sizeof (coords[0])); - /* Best effort design coords simulation */ - font->face->table.avar->unmap_coords (unmapped, coords_length); for (unsigned int i = 0; i < coords_length; ++i) - design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]); - hb_free (unmapped); + design_coords[i] = NAN; _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); } @@ -2871,8 +3283,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font, * Fetches the list of normalized variation coordinates currently * set on a font. * - * Note that this returned array may only contain values for some - * (or none) of the axes; omitted axes effectively have zero values. + * Note that if no variation coordinates are set, this function may + * return %NULL. * * Return value is valid as long as variation coordinates of the font * are not modified. @@ -2899,9 +3311,12 @@ hb_font_get_var_coords_normalized (hb_font_t *font, * Fetches the list of variation coordinates (in design-space units) currently * set on a font. * - * Note that this returned array may only contain values for some - * (or none) of the axes; omitted axes effectively have their default - * values. + * Note that if no variation coordinates are set, this function may + * return %NULL. + * + * If variations have been set on the font using normalized coordinates + * (i.e. via hb_font_set_var_coords_normalized()), the design coordinates will + * have NaN (Not a Number) values. * * Return value is valid as long as variation coordinates of the font * are not modified. @@ -3058,12 +3473,134 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, #ifndef HB_DISABLE_DEPRECATED + +struct hb_draw_glyph_closure_t +{ + hb_font_draw_glyph_func_t func; + void *user_data; + hb_destroy_func_t destroy; +}; +static hb_bool_t +hb_font_draw_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, + void *draw_data, + void *user_data) +{ + hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data; + closure->func (font, font_data, glyph, draw_funcs, draw_data, closure->user_data); + return true; +} +static void +hb_font_draw_glyph_closure_destroy (void *user_data) +{ + hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data; + + if (closure->destroy) + closure->destroy (closure->user_data); + hb_free (closure); +} +static void +_hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + if (hb_object_is_immutable (ffuncs)) + { + if (destroy) + destroy (user_data); + return; + } + hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) hb_calloc (1, sizeof (hb_draw_glyph_closure_t)); + if (unlikely (!closure)) + { + if (destroy) + destroy (user_data); + return; + } + closure->func = func; + closure->user_data = user_data; + closure->destroy = destroy; + + hb_font_funcs_set_draw_glyph_or_fail_func (ffuncs, + hb_font_draw_glyph_trampoline, + closure, + hb_font_draw_glyph_closure_destroy); +} +void +hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); +} void hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_shape_func_t func, void *user_data, hb_destroy_func_t destroy /* May be NULL. */) { - hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); + _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy); +} + +struct hb_paint_glyph_closure_t +{ + hb_font_paint_glyph_func_t func; + void *user_data; + hb_destroy_func_t destroy; +}; +static hb_bool_t +hb_font_paint_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, + void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) +{ + hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data; + closure->func (font, font_data, glyph, paint_funcs, paint_data, palette, foreground, closure->user_data); + return true; +} +static void +hb_font_paint_glyph_closure_destroy (void *user_data) +{ + hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data; + + if (closure->destroy) + closure->destroy (closure->user_data); + hb_free (closure); +} +void +hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy /* May be NULL. */) +{ + if (hb_object_is_immutable (ffuncs)) + { + if (destroy) + destroy (user_data); + return; + } + hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) hb_calloc (1, sizeof (hb_paint_glyph_closure_t)); + if (unlikely (!closure)) + { + if (destroy) + destroy (user_data); + return; + } + closure->func = func; + closure->user_data = user_data; + closure->destroy = destroy; + + hb_font_funcs_set_paint_glyph_or_fail_func (ffuncs, + hb_font_paint_glyph_trampoline, + closure, + hb_font_paint_glyph_closure_destroy); } #endif diff --git a/thirdparty/harfbuzz/upstream/hb-font.h b/thirdparty/harfbuzz/upstream/hb-font.h index 3c2355af2..16b7f552e 100644 --- a/thirdparty/harfbuzz/upstream/hb-font.h +++ b/thirdparty/harfbuzz/upstream/hb-font.h @@ -97,7 +97,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); * @descender: The depth of typographic descenders. * @line_gap: The suggested line-spacing gap. * - * Font-wide extent values, measured in font units. + * Font-wide extent values, measured in scaled units. * * Note that typically @ascender is positive and @descender * negative, in coordinate systems that grow up. @@ -332,7 +332,7 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. * @@ -349,7 +349,7 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph, for horizontal-direction text segments. Each * coordinate must be returned in an #hb_position_t output parameter. * @@ -361,13 +361,72 @@ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) of the + * This method should retrieve the (X,Y) coordinates (in scaled units) of the * origin for a glyph, for vertical-direction text segments. Each coordinate * must be returned in an #hb_position_t output parameter. * **/ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; +/** + * hb_font_get_glyph_origins_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @first_glyph: The first glyph ID to query + * @count: number of glyphs to query + * @glyph_stride: The stride between successive glyph IDs + * @first_x: (out): The first origin X coordinate retrieved + * @x_stride: The stride between successive origin X coordinates + * @first_y: (out): The first origin Y coordinate retrieved + * @y_stride: The stride between successive origin Y coordinates + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for each requested glyph. Each coordinate value must be returned in + * an #hb_position_t in the two output parameters. + * + * Return value: `true` if data found, `false` otherwise + * + * Since: 11.3.0 + **/ +typedef hb_bool_t (*hb_font_get_glyph_origins_func_t) (hb_font_t *font, void *font_data, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data); + +/** + * hb_font_get_glyph_h_origins_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for requested glyph, for horizontal-direction text segments. Each + * coordinate must be returned in a the x/y #hb_position_t output parameters. + * + * Since: 11.3.0 + **/ +typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_h_origins_func_t; + +/** + * hb_font_get_glyph_v_origins_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the (X,Y) coordinates (in scaled units) of the + * origin for requested glyph, for vertical-direction text segments. Each + * coordinate must be returned in a the x/y #hb_position_t output parameters. + * + * Since: 11.3.0 + **/ +typedef hb_font_get_glyph_origins_func_t hb_font_get_glyph_v_origins_func_t; + /** * hb_font_get_glyph_kerning_func_t: * @font: #hb_font_t to work upon @@ -428,7 +487,7 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the (X,Y) coordinates (in font units) for a + * This method should retrieve the (X,Y) coordinates (in scaled units) for a * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * @@ -486,7 +545,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * void *user_data); /** - * hb_font_draw_glyph_func_t: + * hb_font_draw_glyph_or_fail_func_t: * @font: #hb_font_t to work upon * @font_data: @font user data pointer * @glyph: The glyph ID to query @@ -496,16 +555,17 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * Since: 7.0.0 + * Return value: `true` if glyph was drawn, `false` otherwise * + * Since: 11.2.0 **/ -typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data); +typedef hb_bool_t (*hb_font_draw_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data); /** - * hb_font_paint_glyph_func_t: + * hb_font_paint_glyph_or_fail_func_t: * @font: #hb_font_t to work upon * @font_data: @font user data pointer * @glyph: The glyph ID to query @@ -517,14 +577,16 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data, * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * Since: 7.0.0 + * Return value: `true` if glyph was painted, `false` otherwise + * + * Since: 11.2.0 */ -typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette_index, - hb_color_t foreground, - void *user_data); +typedef hb_bool_t (*hb_font_paint_glyph_or_fail_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data); /* func setters */ @@ -704,6 +766,38 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_origin_func_t func, void *user_data, hb_destroy_func_t destroy); +/** + * hb_font_funcs_set_glyph_h_origins_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_get_glyph_h_origins_func_t. + * + * Since: 11.3.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_h_origins_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_h_origins_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_glyph_v_origins_func: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_font_get_glyph_v_origins_func_t. + * + * Since: 11.3.0 + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_v_origins_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_v_origins_func_t func, + void *user_data, hb_destroy_func_t destroy); + /** * hb_font_funcs_set_glyph_h_kerning_func: * @ffuncs: A font-function structure @@ -785,36 +879,36 @@ hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_draw_glyph_func: + * hb_font_funcs_set_draw_glyph_or_fail_func: * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * Sets the implementation function for #hb_font_draw_glyph_func_t. + * Sets the implementation function for #hb_font_draw_glyph_or_fail_func_t. * - * Since: 7.0.0 + * Since: 11.2.0 **/ HB_EXTERN void -hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_draw_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy); +hb_font_funcs_set_draw_glyph_or_fail_func (hb_font_funcs_t *ffuncs, + hb_font_draw_glyph_or_fail_func_t func, + void *user_data, hb_destroy_func_t destroy); /** - * hb_font_funcs_set_paint_glyph_func: + * hb_font_funcs_set_paint_glyph_or_fail_func: * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func * @destroy: (nullable): The function to call when @user_data is no longer needed * - * Sets the implementation function for #hb_font_paint_glyph_func_t. + * Sets the implementation function for #hb_font_paint_glyph_or_fail_func_t. * - * Since: 7.0.0 + * Since: 11.2.0 */ HB_EXTERN void -hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_paint_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy); +hb_font_funcs_set_paint_glyph_or_fail_func (hb_font_funcs_t *ffuncs, + hb_font_paint_glyph_or_fail_func_t func, + void *user_data, hb_destroy_func_t destroy); /* func dispatch */ @@ -873,6 +967,26 @@ hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); +HB_EXTERN hb_bool_t +hb_font_get_glyph_h_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride); + +HB_EXTERN hb_bool_t +hb_font_get_glyph_v_origins (hb_font_t *font, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride); + HB_EXTERN hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); @@ -896,17 +1010,17 @@ hb_font_get_glyph_from_name (hb_font_t *font, const char *name, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph); -HB_EXTERN void -hb_font_draw_glyph (hb_font_t *font, - hb_codepoint_t glyph, - hb_draw_funcs_t *dfuncs, void *draw_data); +HB_EXTERN hb_bool_t +hb_font_draw_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data); -HB_EXTERN void -hb_font_paint_glyph (hb_font_t *font, - hb_codepoint_t glyph, - hb_paint_funcs_t *pfuncs, void *paint_data, - unsigned int palette_index, - hb_color_t foreground); +HB_EXTERN hb_bool_t +hb_font_paint_glyph_or_fail (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground); /* high-level funcs, with fallback */ @@ -979,6 +1093,19 @@ hb_font_glyph_from_string (hb_font_t *font, const char *s, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph); +/* Older alias for hb_font_draw_glyph_or_fail() with no return value. */ +HB_EXTERN void +hb_font_draw_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_draw_funcs_t *dfuncs, void *draw_data); + +/* Paints color glyph; if failed, draws outline glyph. */ +HB_EXTERN void +hb_font_paint_glyph (hb_font_t *font, + hb_codepoint_t glyph, + hb_paint_funcs_t *pfuncs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground); /* * hb_font_t @@ -1052,6 +1179,12 @@ hb_font_set_funcs_data (hb_font_t *font, void *font_data, hb_destroy_func_t destroy); +HB_EXTERN hb_bool_t +hb_font_set_funcs_using (hb_font_t *font, + const char *name); + +HB_EXTERN const char ** +hb_font_list_funcs (void); HB_EXTERN void hb_font_set_scale (hb_font_t *font, @@ -1086,6 +1219,9 @@ hb_font_set_ptem (hb_font_t *font, float ptem); HB_EXTERN float hb_font_get_ptem (hb_font_t *font); +HB_EXTERN hb_bool_t +hb_font_is_synthetic (hb_font_t *font); + HB_EXTERN void hb_font_set_synthetic_bold (hb_font_t *font, float x_embolden, float y_embolden, diff --git a/thirdparty/harfbuzz/upstream/hb-font.hh b/thirdparty/harfbuzz/upstream/hb-font.hh index 4c8190b0d..8d7bb2703 100644 --- a/thirdparty/harfbuzz/upstream/hb-font.hh +++ b/thirdparty/harfbuzz/upstream/hb-font.hh @@ -32,7 +32,11 @@ #include "hb.hh" #include "hb-face.hh" +#include "hb-atomic.hh" +#include "hb-draw.hh" +#include "hb-paint-extents.hh" #include "hb-shaper.hh" +#include "hb-outline.hh" /* @@ -51,14 +55,16 @@ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origins) \ + HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origins) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \ HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \ HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \ - HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \ - HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \ + HB_FONT_FUNC_IMPLEMENT (,draw_glyph_or_fail) \ + HB_FONT_FUNC_IMPLEMENT (,paint_glyph_or_fail) \ /* ^--- Add new callbacks here */ struct hb_font_funcs_t @@ -105,8 +111,8 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t); struct hb_font_t { hb_object_header_t header; - unsigned int serial; - unsigned int serial_coords; + hb_atomic_t serial; + hb_atomic_t serial_coords; hb_font_t *parent; hb_face_t *face; @@ -114,6 +120,8 @@ struct hb_font_t int32_t x_scale; int32_t y_scale; + bool is_synthetic; + float x_embolden; float y_embolden; bool embolden_in_place; @@ -135,6 +143,7 @@ struct hb_font_t /* Font variation coordinates. */ unsigned int instance_index; + bool has_nonzero_coords; unsigned int num_coords; int *coords; float *design_coords; @@ -191,23 +200,35 @@ struct hb_font_t void scale_glyph_extents (hb_glyph_extents_t *extents) { - float x1 = em_fscale_x (extents->x_bearing); - float y1 = em_fscale_y (extents->y_bearing); - float x2 = em_fscale_x (extents->x_bearing + extents->width); - float y2 = em_fscale_y (extents->y_bearing + extents->height); + float x1 = em_scale_x (extents->x_bearing); + float y1 = em_scale_y (extents->y_bearing); + float x2 = em_scale_x (extents->x_bearing + extents->width); + float y2 = em_scale_y (extents->y_bearing + extents->height); + + extents->x_bearing = roundf (x1); + extents->y_bearing = roundf (y1); + extents->width = roundf (x2) - extents->x_bearing; + extents->height = roundf (y2) - extents->y_bearing; + } - /* Apply slant. */ + void synthetic_glyph_extents (hb_glyph_extents_t *extents) + { + /* Slant. */ if (slant_xy) { - x1 += hb_min (y1 * slant_xy, y2 * slant_xy); - x2 += hb_max (y1 * slant_xy, y2 * slant_xy); - } + hb_position_t x1 = extents->x_bearing; + hb_position_t y1 = extents->y_bearing; + hb_position_t x2 = extents->x_bearing + extents->width; + hb_position_t y2 = extents->y_bearing + extents->height; + + x1 += floorf (hb_min (y1 * slant_xy, y2 * slant_xy)); + x2 += ceilf (hb_max (y1 * slant_xy, y2 * slant_xy)); - extents->x_bearing = floorf (x1); - extents->y_bearing = floorf (y1); - extents->width = ceilf (x2) - extents->x_bearing; - extents->height = ceilf (y2) - extents->y_bearing; + extents->x_bearing = x1; + extents->width = x2 - extents->x_bearing; + } + /* Embolden. */ if (x_strength || y_strength) { /* Y */ @@ -250,19 +271,45 @@ struct hb_font_t HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT - hb_bool_t get_font_h_extents (hb_font_extents_t *extents) + hb_bool_t get_font_h_extents (hb_font_extents_t *extents, + bool synthetic = true) { hb_memset (extents, 0, sizeof (*extents)); - return klass->get.f.font_h_extents (this, user_data, - extents, - !klass->user_data ? nullptr : klass->user_data->font_h_extents); + bool ret = klass->get.f.font_h_extents (this, user_data, + extents, + !klass->user_data ? nullptr : klass->user_data->font_h_extents); + + if (synthetic && ret) + { + /* Embolden */ + int y_shift = y_scale < 0 ? -y_strength : y_strength; + extents->ascender += y_shift; + } + + return ret; } - hb_bool_t get_font_v_extents (hb_font_extents_t *extents) + hb_bool_t get_font_v_extents (hb_font_extents_t *extents, + bool synthetic = true) { hb_memset (extents, 0, sizeof (*extents)); - return klass->get.f.font_v_extents (this, user_data, - extents, - !klass->user_data ? nullptr : klass->user_data->font_v_extents); + bool ret = klass->get.f.font_v_extents (this, user_data, + extents, + !klass->user_data ? nullptr : klass->user_data->font_v_extents); + + if (synthetic && ret) + { + /* Embolden */ + int x_shift = x_scale < 0 ? -x_strength : x_strength; + if (embolden_in_place) + { + extents->ascender += x_shift / 2; + extents->descender -= x_shift - x_shift / 2; + } + else + extents->ascender += x_shift; + } + + return ret; } bool has_glyph (hb_codepoint_t unicode) @@ -303,62 +350,212 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->variation_glyph); } - hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) + hb_position_t get_glyph_h_advance (hb_codepoint_t glyph, + bool synthetic = true) { - return klass->get.f.glyph_h_advance (this, user_data, - glyph, - !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); + hb_position_t advance = klass->get.f.glyph_h_advance (this, user_data, + glyph, + !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); + + if (synthetic && x_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; + advance += advance ? strength : 0; + } + + return advance; } - hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) + hb_position_t get_glyph_v_advance (hb_codepoint_t glyph, + bool synthetic = true) { - return klass->get.f.glyph_v_advance (this, user_data, - glyph, - !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); + hb_position_t advance = klass->get.f.glyph_v_advance (this, user_data, + glyph, + !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); + + if (synthetic && y_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; + advance += advance ? strength : 0; + } + + return advance; } void get_glyph_h_advances (unsigned int count, const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, - unsigned int advance_stride) + unsigned int advance_stride, + bool synthetic = true) { - return klass->get.f.glyph_h_advances (this, user_data, - count, - first_glyph, glyph_stride, - first_advance, advance_stride, - !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); + klass->get.f.glyph_h_advances (this, user_data, + count, + first_glyph, glyph_stride, + first_advance, advance_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); + + if (synthetic && x_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } void get_glyph_v_advances (unsigned int count, const hb_codepoint_t *first_glyph, unsigned int glyph_stride, hb_position_t *first_advance, - unsigned int advance_stride) + unsigned int advance_stride, + bool synthetic = true) { - return klass->get.f.glyph_v_advances (this, user_data, - count, - first_glyph, glyph_stride, - first_advance, advance_stride, - !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); + klass->get.f.glyph_v_advances (this, user_data, + count, + first_glyph, glyph_stride, + first_advance, advance_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); + + if (synthetic && y_strength && !embolden_in_place) + { + /* Embolden */ + hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y, + bool synthetic = true) { *x = *y = 0; - return klass->get.f.glyph_h_origin (this, user_data, - glyph, x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); + bool ret = klass->get.f.glyph_h_origin (this, user_data, + glyph, x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_h_origin); + + if (synthetic && ret) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *x += x_scale < 0 ? -x_strength : x_strength; + *y += y_scale < 0 ? -y_strength : y_strength; + } + } + + return ret; } hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y, + bool synthetic = true) { *x = *y = 0; - return klass->get.f.glyph_v_origin (this, user_data, - glyph, x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); + bool ret = klass->get.f.glyph_v_origin (this, user_data, + glyph, x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_v_origin); + + if (synthetic && ret) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *x += x_scale < 0 ? -x_strength : x_strength; + *y += y_scale < 0 ? -y_strength : y_strength; + } + } + + return ret; + } + + hb_bool_t get_glyph_h_origins (unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride, + bool synthetic = true) + + { + bool ret = klass->get.f.glyph_h_origins (this, user_data, + count, + first_glyph, glyph_stride, + first_x, x_stride, first_y, y_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_h_origins); + + if (synthetic && ret) + { + hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; + hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; + for (unsigned i = 0; i < count; i++) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *first_x += x_shift; + *first_y += y_shift; + } + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + return ret; + } + + hb_bool_t get_glyph_v_origins (unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned int glyph_stride, + hb_position_t *first_x, + unsigned int x_stride, + hb_position_t *first_y, + unsigned int y_stride, + bool synthetic = true) + + { + bool ret = klass->get.f.glyph_v_origins (this, user_data, + count, + first_glyph, glyph_stride, + first_x, x_stride, first_y, y_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_v_origins); + + if (synthetic && is_synthetic && ret) + { + hb_position_t x_shift = x_scale < 0 ? -x_strength : x_strength; + hb_position_t y_shift = y_scale < 0 ? -y_strength : y_strength; + for (unsigned i = 0; i < count; i++) + { + /* Slant is ignored as it does not affect glyph origin */ + + /* Embolden */ + if (!embolden_in_place) + { + *first_x += x_shift; + *first_y += y_shift; + } + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + return ret; } hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, @@ -386,23 +583,86 @@ struct hb_font_t } hb_bool_t get_glyph_extents (hb_codepoint_t glyph, - hb_glyph_extents_t *extents) + hb_glyph_extents_t *extents, + bool synthetic = true) { hb_memset (extents, 0, sizeof (*extents)); - return klass->get.f.glyph_extents (this, user_data, - glyph, - extents, - !klass->user_data ? nullptr : klass->user_data->glyph_extents); + + /* This is rather messy, but necessary. */ + + if (!synthetic) + { + return klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents); + } + if (!is_synthetic && + klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents)) + return true; + + /* Try getting extents from paint(), then draw(), *then* get_extents() + * and apply synthetic settings in the last case. */ + +#ifndef HB_NO_PAINT + hb_paint_extents_context_t paint_extents; + if (paint_glyph_or_fail (glyph, + hb_paint_extents_get_funcs (), &paint_extents, + 0, 0)) + { + *extents = paint_extents.get_extents ().to_glyph_extents (); + return true; + } +#endif + +#ifndef HB_NO_DRAW + hb_extents_t<> draw_extents; + if (draw_glyph_or_fail (glyph, + hb_draw_extents_get_funcs (), &draw_extents)) + { + *extents = draw_extents.to_glyph_extents (); + return true; + } +#endif + + bool ret = klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + !klass->user_data ? nullptr : klass->user_data->glyph_extents); + if (ret) + synthetic_glyph_extents (extents); + + return ret; } hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, - hb_position_t *x, hb_position_t *y) + hb_position_t *x, hb_position_t *y, + bool synthetic = true) { *x = *y = 0; - return klass->get.f.glyph_contour_point (this, user_data, - glyph, point_index, - x, y, - !klass->user_data ? nullptr : klass->user_data->glyph_contour_point); + bool ret = klass->get.f.glyph_contour_point (this, user_data, + glyph, point_index, + x, y, + !klass->user_data ? nullptr : klass->user_data->glyph_contour_point); + + if (synthetic && ret) + { + /* Slant */ + if (slant_xy) + *x += roundf (*y * slant_xy); + + /* Embolden */ + if (!embolden_in_place) + { + int x_shift = x_scale < 0 ? -x_strength : x_strength; + *x += x_shift; + } + } + + return ret; } hb_bool_t get_glyph_name (hb_codepoint_t glyph, @@ -426,29 +686,100 @@ struct hb_font_t !klass->user_data ? nullptr : klass->user_data->glyph_from_name); } - void draw_glyph (hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data) + bool draw_glyph_or_fail (hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + bool synthetic = true) { - klass->get.f.draw_glyph (this, user_data, - glyph, - draw_funcs, draw_data, - !klass->user_data ? nullptr : klass->user_data->draw_glyph); +#ifndef HB_NO_DRAW +#ifndef HB_NO_OUTLINE + bool embolden = x_strength || y_strength; + bool slanted = slant_xy; + synthetic = synthetic && (embolden || slanted); +#else + synthetic = false; +#endif + + if (!synthetic) + { + return klass->get.f.draw_glyph_or_fail (this, user_data, + glyph, + draw_funcs, draw_data, + !klass->user_data ? nullptr : klass->user_data->draw_glyph_or_fail); + } + +#ifndef HB_NO_OUTLINE + + hb_outline_t outline; + if (!klass->get.f.draw_glyph_or_fail (this, user_data, + glyph, + hb_outline_recording_pen_get_funcs (), &outline, + !klass->user_data ? nullptr : klass->user_data->draw_glyph_or_fail)) + return false; + + // Slant before embolden; produces nicer results. + + if (slanted) + { + hb_position_t xo = 0, yo = 0; + get_glyph_h_origin (glyph, &xo, &yo, false); + outline.translate (-xo, -yo); + outline.slant (slant_xy); + outline.translate (xo, yo); + } + + if (embolden) + { + float x_shift = embolden_in_place ? 0 : (float) x_strength / 2; + float y_shift = (float) y_strength / 2; + if (x_scale < 0) x_shift = -x_shift; + if (y_scale < 0) y_shift = -y_shift; + outline.embolden (x_strength, y_strength, x_shift, y_shift); + } + + outline.replay (draw_funcs, draw_data); + + return true; +#endif +#endif + return false; } - void paint_glyph (hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette, - hb_color_t foreground) + bool paint_glyph_or_fail (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, + bool synthetic = true) { - klass->get.f.paint_glyph (this, user_data, - glyph, - paint_funcs, paint_data, - palette, foreground, - !klass->user_data ? nullptr : klass->user_data->paint_glyph); +#ifndef HB_NO_PAINT + /* Slant */ + if (synthetic && slant_xy) + hb_paint_push_transform (paint_funcs, paint_data, + 1.f, 0.f, + slant_xy, 1.f, + 0.f, 0.f); + + bool ret = klass->get.f.paint_glyph_or_fail (this, user_data, + glyph, + paint_funcs, paint_data, + palette, foreground, + !klass->user_data ? nullptr : klass->user_data->paint_glyph_or_fail); + + if (synthetic && slant_xy) + hb_paint_pop_transform (paint_funcs, paint_data); + + return ret; +#endif + return false; } /* A bit higher-level, and with fallback */ + HB_INTERNAL + void paint_glyph (hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground); + void get_h_extents_with_fallback (hb_font_extents_t *extents) { if (!get_font_h_extents (extents)) @@ -500,6 +831,28 @@ struct hb_font_t get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); } + void apply_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy, + signed mult) + { + assert (mult == -1 || mult == +1); + + *x += dx * mult; + *y += dy * mult; + } + void add_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy) + { + *x += dx; + *y += dy; + } + void subtract_offset (hb_position_t *x, hb_position_t *y, + hb_position_t dx, hb_position_t dy) + { + *x -= dx; + *y -= dy; + } + void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { @@ -510,6 +863,141 @@ struct hb_font_t *y = extents.ascender; } + void apply_glyph_h_origins_with_fallback (hb_buffer_t *buf, int mult) + { + bool has_ascender = false; + hb_position_t ascender = 0; + + struct { hb_position_t x, y; } origins[32]; + + unsigned int offset = 0; + unsigned int count = buf->len; + while (offset < count) + { + unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); + if (!get_glyph_h_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (get_glyph_v_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (!has_ascender) + { + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + ascender = extents.ascender; + has_ascender = true; + } + + /* We got the v_origins, adjust them to h_origins. */ + for (unsigned j = 0; j < n; j++) + { + hb_codepoint_t glyph = buf->info[offset + j].codepoint; + origins[j].x -= get_glyph_h_advance (glyph) / 2; + origins[j].y -= ascender; + } + } + else + { + for (unsigned j = 0; j < n; j++) + { + origins[j].x = 0; + origins[j].y = 0; + } + } + } + + assert (mult == -1 || mult == +1); + if (mult == +1) + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + add_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + else /* mult == -1 */ + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + subtract_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + + offset += n; + } + } + void apply_glyph_v_origins_with_fallback (hb_buffer_t *buf, int mult) + { + bool has_ascender = false; + hb_position_t ascender = 0; + + struct { hb_position_t x, y; } origins[32]; + + unsigned int offset = 0; + unsigned int count = buf->len; + while (offset < count) + { + unsigned n = hb_min (count - offset, ARRAY_LENGTH (origins)); + if (!get_glyph_v_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (get_glyph_h_origins (n, + &buf->info[offset].codepoint, sizeof (hb_glyph_info_t), + &origins[0].x, sizeof (origins[0]), + &origins[0].y, sizeof (origins[0]))) + { + if (!has_ascender) + { + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + ascender = extents.ascender; + has_ascender = true; + } + + /* We got the h_origins, adjust them to v_origins. */ + for (unsigned j = 0; j < n; j++) + { + hb_codepoint_t glyph = buf->info[offset + j].codepoint; + origins[j].x += get_glyph_h_advance (glyph) / 2; + origins[j].y += ascender; + } + } + else + { + for (unsigned j = 0; j < n; j++) + { + origins[j].x = 0; + origins[j].y = 0; + } + } + } + + assert (mult == -1 || mult == +1); + if (mult == +1) + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + add_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + else /* mult == -1 */ + for (unsigned j = 0; j < n; j++) + { + hb_glyph_position_t *pos = &buf->pos[offset + j]; + subtract_offset (&pos->x_offset, &pos->y_offset, + origins[j].x, origins[j].y); + } + + offset += n; + } + } + void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { @@ -518,7 +1006,7 @@ struct hb_font_t { hb_position_t dx, dy; guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x -= dx; *y -= dy; + subtract_offset (x, y, dx, dy); } } void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph, @@ -529,7 +1017,7 @@ struct hb_font_t { hb_position_t dx, dy; guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x += dx; *y += dy; + add_offset (x, y, dx, dy); } } @@ -543,68 +1031,38 @@ struct hb_font_t get_glyph_v_origin_with_fallback (glyph, x, y); } - void add_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void add_glyph_h_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + apply_glyph_h_origins_with_fallback (buf, +1); } - void add_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void add_glyph_v_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + apply_glyph_v_origins_with_fallback (buf, +1); } void add_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) { hb_position_t origin_x, origin_y; - get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); - - *x += origin_x; - *y += origin_y; + add_offset (x, y, origin_x, origin_y); } - void subtract_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void subtract_glyph_h_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + apply_glyph_h_origins_with_fallback (buf, -1); } - void subtract_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) + void subtract_glyph_v_origins (hb_buffer_t *buf) { - hb_position_t origin_x, origin_y; - - get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + apply_glyph_v_origins_with_fallback (buf, -1); } void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) { hb_position_t origin_x, origin_y; - get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); - - *x -= origin_x; - *y -= origin_y; + subtract_offset (x, y, origin_x, origin_y); } void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, @@ -686,7 +1144,7 @@ struct hb_font_t return false; } - void mults_changed () + void changed () { float upem = face->get_upem (); @@ -697,12 +1155,16 @@ struct hb_font_t bool y_neg = y_scale < 0; y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; - x_strength = fabsf (roundf (x_scale * x_embolden)); - y_strength = fabsf (roundf (y_scale * y_embolden)); + is_synthetic = x_embolden || y_embolden || slant; + + x_strength = roundf (abs (x_scale) * x_embolden); + y_strength = roundf (abs (y_scale) * y_embolden); slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; data.fini (); + + serial++; } hb_position_t em_mult (int16_t v, int64_t mult) diff --git a/thirdparty/harfbuzz/upstream/hb-fontations.h b/thirdparty/harfbuzz/upstream/hb-fontations.h new file mode 100644 index 000000000..6a3fce0b5 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-fontations.h @@ -0,0 +1,56 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_FONTATIONS_H +#define HB_FONTATIONS_H + +#include "hb.h" + +/** + * SECTION: hb-fontations + * @title: hb-fontations + * @short_description: Fontations integration + * @include: hb-fontations.h + * + * Functions for using HarfBuzz with + * [Fontations](https://github.com/googlefonts/fontations/) fonts. + **/ + +HB_BEGIN_DECLS + +/** + * hb_fontations_font_set_funcs: + * @font: #hb_font_t to work upon + * + * Configures the font-functions structure of the specified #hb_font_t font + * object to use Fontations font functions. + * + * Since: 11.0.0 + **/ +HB_EXTERN void +hb_fontations_font_set_funcs (hb_font_t *font); + +HB_END_DECLS + +#endif /* HB_FONTATIONS_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-pool.hh b/thirdparty/harfbuzz/upstream/hb-free-pool.hh similarity index 92% rename from thirdparty/harfbuzz/upstream/hb-pool.hh rename to thirdparty/harfbuzz/upstream/hb-free-pool.hh index fcf10666b..0609e3954 100644 --- a/thirdparty/harfbuzz/upstream/hb-pool.hh +++ b/thirdparty/harfbuzz/upstream/hb-free-pool.hh @@ -24,12 +24,12 @@ * Facebook Author(s): Behdad Esfahbod */ -#ifndef HB_POOL_HH -#define HB_POOL_HH +#ifndef HB_FREE_POOL_HH +#define HB_FREE_POOL_HH #include "hb.hh" -/* Memory pool for persistent allocation of small objects. +/* Memory pool for persistent alloc/free of small objects. * * Some AI musings on this, not necessarily true: * @@ -41,10 +41,10 @@ * sophisticated, use a real allocator. Or use a real language. */ template -struct hb_pool_t +struct hb_free_pool_t { - hb_pool_t () : next (nullptr) {} - ~hb_pool_t () + hb_free_pool_t () : next (nullptr) {} + ~hb_free_pool_t () { next = nullptr; @@ -104,4 +104,4 @@ struct hb_pool_t }; -#endif /* HB_POOL_HH */ +#endif /* HB_FREE_POOL_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-ft-colr.hh b/thirdparty/harfbuzz/upstream/hb-ft-colr.hh index 8766a2a2c..d7a361169 100644 --- a/thirdparty/harfbuzz/upstream/hb-ft-colr.hh +++ b/thirdparty/harfbuzz/upstream/hb-ft-colr.hh @@ -27,7 +27,8 @@ #include "hb.hh" -#include "hb-paint-extents.hh" +#include "hb-decycler.hh" +#include "hb-paint-bounded.hh" #include FT_COLOR_H @@ -79,15 +80,30 @@ _hb_ft_paint (hb_ft_paint_context_t *c, struct hb_ft_paint_context_t { - hb_ft_paint_context_t (const hb_ft_font_t *ft_font, - hb_font_t *font, + hb_ft_paint_context_t (const hb_ft_font_t *ft_font_, + hb_font_t *font_, hb_paint_funcs_t *paint_funcs, void *paint_data, - FT_Color *palette, + hb_array_t palette, unsigned palette_index, hb_color_t foreground) : - ft_font (ft_font), font(font), + ft_font (ft_font_), font (font_), funcs (paint_funcs), data (paint_data), - palette (palette), palette_index (palette_index), foreground (foreground) {} + palette (palette), palette_index (palette_index), foreground (foreground) + { + if (font->is_synthetic) + { + font = hb_font_create_sub_font (font); + hb_font_set_synthetic_bold (font, 0, 0, true); + hb_font_set_synthetic_slant (font, 0); + } + else + hb_font_reference (font); + } + + ~hb_ft_paint_context_t () + { + hb_font_destroy (font); + } void recurse (FT_OpaquePaint paint) { @@ -102,11 +118,11 @@ struct hb_ft_paint_context_t hb_font_t *font; hb_paint_funcs_t *funcs; void *data; - FT_Color *palette; + hb_array_t palette; unsigned palette_index; hb_color_t foreground; - hb_map_t current_glyphs; - hb_map_t current_layers; + hb_decycler_t glyphs_decycler; + hb_decycler_t layers_decycler; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_MAX_GRAPH_EDGE_COUNT; }; @@ -166,7 +182,7 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, hb_color_get_red (color), (hb_color_get_alpha (color) * stop.color.alpha) >> 14); } - else + else if (c->palette) { FT_Color ft_color = c->palette[stop.color.palette_index]; color_stops->color = HB_COLOR (ft_color.blue, @@ -174,6 +190,8 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line, ft_color.red, (ft_color.alpha * stop.color.alpha) >> 14); } + else + color_stops->color = HB_COLOR (0, 0, 0, 0); } color_stops++; @@ -218,22 +236,17 @@ _hb_ft_paint (hb_ft_paint_context_t *c, case FT_COLR_PAINTFORMAT_COLR_LAYERS: { FT_OpaquePaint other_paint = {0}; + hb_decycler_node_t node (c->layers_decycler); while (FT_Get_Paint_Layers (ft_face, &paint.u.colr_layers.layer_iterator, &other_paint)) { - unsigned i = paint.u.colr_layers.layer_iterator.layer; - - if (unlikely (c->current_layers.has (i))) + // FreeType doesn't provide a way to get the layer index, so we use the pointer + // for cycle detection. + if (unlikely (!node.visit ((uintptr_t) other_paint.p))) continue; - c->current_layers.add (i); - - c->funcs->push_group (c->data); c->recurse (other_paint); - c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); - - c->current_layers.del (i); } } break; @@ -318,11 +331,11 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_GLYPH: { - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->ft_font->lock.unlock (); c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font); c->ft_font->lock.lock (); - c->funcs->push_root_transform (c->data, c->font); + c->funcs->push_font_transform (c->data, c->font); c->recurse (paint.u.glyph.paint); c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); @@ -333,18 +346,16 @@ _hb_ft_paint (hb_ft_paint_context_t *c, { hb_codepoint_t gid = paint.u.colr_glyph.glyphID; - if (unlikely (c->current_glyphs.has (gid))) + hb_decycler_node_t node (c->glyphs_decycler); + if (unlikely (!node.visit (gid))) return; - c->current_glyphs.add (gid); - - c->funcs->push_inverse_root_transform (c->data, c->font); + c->funcs->push_inverse_font_transform (c->data, c->font); c->ft_font->lock.unlock (); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->ft_font->lock.lock (); c->funcs->pop_transform (c->data); - c->current_glyphs.del (gid); return; } c->ft_font->lock.lock (); @@ -380,8 +391,6 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (has_clip_box) c->funcs->pop_clip (c->data); - - c->current_glyphs.del (gid); } } break; @@ -403,9 +412,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float dx = paint.u.translate.dx / 65536.f; float dy = paint.u.translate.dy / 65536.f; - bool p1 = c->funcs->push_translate (c->data, dx, dy); + c->funcs->push_translate (c->data, dx, dy); c->recurse (paint.u.translate.paint); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_SCALE: @@ -415,13 +424,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float sx = paint.u.scale.scale_x / 65536.f; float sy = paint.u.scale.scale_y / 65536.f; - bool p1 = c->funcs->push_translate (c->data, +dx, +dy); - bool p2 = c->funcs->push_scale (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -dx, -dy); + c->funcs->push_scale_around_center (c->data, sx, sy, dx, dy); c->recurse (paint.u.scale.paint); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_ROTATE: @@ -430,13 +435,9 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float dy = paint.u.rotate.center_y / 65536.f; float a = paint.u.rotate.angle / 65536.f; - bool p1 = c->funcs->push_translate (c->data, +dx, +dy); - bool p2 = c->funcs->push_rotate (c->data, a); - bool p3 = c->funcs->push_translate (c->data, -dx, -dy); + c->funcs->push_rotate_around_center (c->data, a, dx, dy); c->recurse (paint.u.rotate.paint); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_SKEW: @@ -446,21 +447,19 @@ _hb_ft_paint (hb_ft_paint_context_t *c, float sx = paint.u.skew.x_skew_angle / 65536.f; float sy = paint.u.skew.y_skew_angle / 65536.f; - bool p1 = c->funcs->push_translate (c->data, +dx, +dy); - bool p2 = c->funcs->push_skew (c->data, sx, sy); - bool p3 = c->funcs->push_translate (c->data, -dx, -dy); + c->funcs->push_skew_around_center (c->data, sx, sy, dx, dy); c->recurse (paint.u.skew.paint); - if (p3) c->funcs->pop_transform (c->data); - if (p2) c->funcs->pop_transform (c->data); - if (p1) c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_COMPOSITE: { + c->funcs->push_group (c->data); c->recurse (paint.u.composite.backdrop_paint); c->funcs->push_group (c->data); c->recurse (paint.u.composite.source_paint); c->funcs->pop_group (c->data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode)); + c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); } break; @@ -485,17 +484,24 @@ hb_ft_paint_glyph_colr (hb_font_t *font, /* Face is locked. */ - FT_Error error; - FT_Color* palette; + FT_Palette_Data palette_data = {}; + FT_Color* palette = NULL; FT_LayerIterator iterator; FT_Bool have_layers; FT_UInt layer_glyph_index; FT_UInt layer_color_index; - error = FT_Palette_Select(ft_face, palette_index, &palette); - if (error) - palette = NULL; + (void) FT_Palette_Data_Get(ft_face, &palette_data); + (void) FT_Palette_Select(ft_face, palette_index, &palette); + if (!palette) + { + // https://github.com/harfbuzz/harfbuzz/issues/5116 + (void) FT_Palette_Select(ft_face, 0, &palette); + } + + auto palette_array = hb_array ((const FT_Color *) palette, + palette ? palette_data.num_palette_entries : 0); /* COLRv1 */ FT_OpaquePaint paint = {0}; @@ -505,52 +511,45 @@ hb_ft_paint_glyph_colr (hb_font_t *font, { hb_ft_paint_context_t c (ft_font, font, paint_funcs, paint_data, - palette, palette_index, foreground); - c.current_glyphs.add (gid); + palette_array, palette_index, foreground); + hb_decycler_node_t node (c.glyphs_decycler); + node.visit (gid); - bool is_bounded = true; + bool clip = false; + bool is_bounded = false; FT_ClipBox clip_box; if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box)) { c.funcs->push_clip_rectangle (c.data, - clip_box.bottom_left.x + - roundf (hb_min (font->slant_xy * clip_box.bottom_left.y, - font->slant_xy * clip_box.top_left.y)), + clip_box.bottom_left.x, clip_box.bottom_left.y, - clip_box.top_right.x + - roundf (hb_max (font->slant_xy * clip_box.bottom_right.y, - font->slant_xy * clip_box.top_right.y)), + clip_box.top_right.x, clip_box.top_right.y); + clip = true; + is_bounded = true; } - else + if (!is_bounded) { - - auto *extents_funcs = hb_paint_extents_get_funcs (); - hb_paint_extents_context_t extents_data; + auto *bounded_funcs = hb_paint_bounded_get_funcs (); + hb_paint_bounded_context_t bounded_data; hb_ft_paint_context_t ce (ft_font, font, - extents_funcs, &extents_data, - palette, palette_index, foreground); - ce.current_glyphs.add (gid); - ce.funcs->push_root_transform (ce.data, font); + bounded_funcs, &bounded_data, + palette_array, palette_index, foreground); + hb_decycler_node_t node2 (ce.glyphs_decycler); + node2.visit (gid); ce.recurse (paint); - ce.funcs->pop_transform (ce.data); - hb_extents_t extents = extents_data.get_extents (); - is_bounded = extents_data.is_bounded (); - - c.funcs->push_clip_rectangle (c.data, - extents.xmin, - extents.ymin, - extents.xmax, - extents.ymax); + is_bounded = bounded_data.is_bounded (); } - c.funcs->push_root_transform (c.data, font); + c.funcs->push_font_transform (c.data, font); if (is_bounded) c.recurse (paint); c.funcs->pop_transform (c.data); - c.funcs->pop_clip (c.data); + + if (clip) + c.funcs->pop_clip (c.data); return true; } diff --git a/thirdparty/harfbuzz/upstream/hb-ft.cc b/thirdparty/harfbuzz/upstream/hb-ft.cc index c305df19a..971f5078e 100644 --- a/thirdparty/harfbuzz/upstream/hb-ft.cc +++ b/thirdparty/harfbuzz/upstream/hb-ft.cc @@ -97,7 +97,7 @@ struct hb_ft_font_t mutable hb_mutex_t lock; /* Protects members below. */ FT_Face ft_face; - mutable unsigned cached_serial; + mutable hb_atomic_t cached_serial; mutable hb_ft_advance_cache_t advance_cache; }; @@ -114,7 +114,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - ft_font->cached_serial = (unsigned) -1; + ft_font->cached_serial = UINT_MAX; new (&ft_font->advance_cache) hb_ft_advance_cache_t; return ft_font; @@ -143,6 +143,9 @@ _hb_ft_font_destroy (void *data) /* hb_font changed, update FT_Face. */ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) { + if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) + return; + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; float x_mult = 1.f, y_mult = 1.f; @@ -184,12 +187,14 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) FT_Set_Transform (ft_face, &matrix, nullptr); ft_font->transform = true; } + else + FT_Set_Transform (ft_face, nullptr, nullptr); #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) - unsigned int num_coords; - const float *coords = hb_font_get_var_coords_design (font, &num_coords); - if (num_coords) + if (font->has_nonzero_coords) { + unsigned int num_coords; + const float *coords = hb_font_get_var_coords_design (font, &num_coords); FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { @@ -199,6 +204,12 @@ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) hb_free (ft_coords); } } + else if (font->num_coords) + { + // Some old versions of FreeType crash if we + // call this function on non-variable fonts. + FT_Set_Var_Design_Coordinates (ft_face, 0, nullptr); + } #endif } @@ -209,9 +220,10 @@ _hb_ft_hb_font_check_changed (hb_font_t *font, { if (font->serial != ft_font->cached_serial) { + hb_lock_t lock (ft_font->lock); _hb_ft_hb_font_changed (font, ft_font->ft_face); ft_font->advance_cache.clear (); - ft_font->cached_serial = font->serial; + ft_font->cached_serial.set_release (font->serial.get_acquire ()); return true; } return false; @@ -275,7 +287,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) } /** - * hb_ft_font_get_face: (skip) + * hb_ft_font_get_ft_face: (skip) * @font: #hb_font_t to work upon * * Fetches the FT_Face associated with the specified #hb_font_t @@ -286,10 +298,10 @@ hb_ft_font_get_load_flags (hb_font_t *font) * * Return value: (nullable): the FT_Face found or `NULL` * - * Since: 0.9.2 + * Since: 10.4.0 **/ FT_Face -hb_ft_font_get_face (hb_font_t *font) +hb_ft_font_get_ft_face (hb_font_t *font) { if (unlikely (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)) return nullptr; @@ -299,6 +311,31 @@ hb_ft_font_get_face (hb_font_t *font) return ft_font->ft_face; } +#ifndef HB_DISABLE_DEPRECATED + +/** + * hb_ft_font_get_face: (skip) + * @font: #hb_font_t to work upon + * + * Fetches the FT_Face associated with the specified #hb_font_t + * font object. + * + * This function works with #hb_font_t objects created by + * hb_ft_font_create() or hb_ft_font_create_referenced(). + * + * Return value: (nullable): the FT_Face found or `NULL` + * + * Since: 0.9.2 + * Deprecated: 10.4.0: Use hb_ft_font_get_ft_face() instead. + **/ +FT_Face +hb_ft_font_get_face (hb_font_t *font) +{ + return hb_ft_font_get_ft_face (font); +} + +#endif + /** * hb_ft_font_lock_face: (skip) * @font: #hb_font_t to work upon @@ -449,7 +486,8 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - hb_position_t *orig_first_advance = first_advance; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; int load_flags = ft_font->load_flags; @@ -490,18 +528,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } - - if (font->x_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? x_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } } #ifndef HB_NO_VERTICAL @@ -512,6 +538,8 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Fixed v; float y_mult; @@ -532,13 +560,11 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) return 0; - v = (int) (y_mult * v); - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates * have a Y growing upward. Hence the extra negation. */ + v = ((-v + (1<<9)) >> 10); - hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); + return (hb_position_t) (y_mult * v); } #endif @@ -552,6 +578,8 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float x_mult, y_mult; @@ -596,6 +624,8 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Vector kerningv; @@ -607,6 +637,41 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font, } #endif +static bool +hb_ft_is_colr_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t gid) +{ +#ifndef HB_NO_PAINT +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300 + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + FT_Face ft_face = ft_font->ft_face; + + + /* COLRv1 */ + FT_OpaquePaint paint = {0}; + if (FT_Get_Color_Glyph_Paint (ft_face, gid, + FT_COLOR_NO_ROOT_TRANSFORM, + &paint)) + return true; + + /* COLRv0 */ + FT_LayerIterator iterator; + FT_UInt layer_glyph_index; + FT_UInt layer_color_index; + iterator.p = NULL; + if (FT_Get_Color_Glyph_Layer (ft_face, + gid, + &layer_glyph_index, + &layer_color_index, + &iterator)) + return true; +#endif +#endif + + return false; +} + static hb_bool_t hb_ft_get_glyph_extents (hb_font_t *font, void *font_data, @@ -614,11 +679,17 @@ hb_ft_get_glyph_extents (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { + // FreeType doesn't return COLR glyph extents. + if (hb_ft_is_colr_glyph (font, font_data, glyph)) + return false; + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float x_mult, y_mult; - float slant_xy = font->slant_xy; + #ifdef HAVE_FT_GET_TRANSFORM if (ft_font->transform) { @@ -646,33 +717,10 @@ hb_ft_get_glyph_extents (hb_font_t *font, float x2 = x1 + x_mult * ft_face->glyph->metrics.width; float y2 = y1 + y_mult * -ft_face->glyph->metrics.height; - /* Apply slant. */ - if (slant_xy) - { - x1 += hb_min (y1 * slant_xy, y2 * slant_xy); - x2 += hb_max (y1 * slant_xy, y2 * slant_xy); - } - - extents->x_bearing = floorf (x1); - extents->y_bearing = floorf (y1); - extents->width = ceilf (x2) - extents->x_bearing; - extents->height = ceilf (y2) - extents->y_bearing; - - if (font->x_strength || font->y_strength) - { - /* Y */ - int y_shift = font->y_strength; - if (font->y_scale < 0) y_shift = -y_shift; - extents->y_bearing += y_shift; - extents->height -= y_shift; - - /* X */ - int x_shift = font->x_strength; - if (font->x_scale < 0) x_shift = -x_shift; - if (font->embolden_in_place) - extents->x_bearing -= x_shift / 2; - extents->width += x_shift; - } + extents->x_bearing = roundf (x1); + extents->y_bearing = roundf (y1); + extents->width = roundf (x2) - extents->x_bearing; + extents->height = roundf (y2) - extents->y_bearing; return true; } @@ -687,6 +735,8 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; @@ -764,6 +814,8 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; float y_mult; @@ -795,7 +847,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender); } - metrics->ascender = (hb_position_t) (y_mult * (metrics->ascender + font->y_strength)); + metrics->ascender = (hb_position_t) (y_mult * metrics->ascender); metrics->descender = (hb_position_t) (y_mult * metrics->descender); metrics->line_gap = (hb_position_t) (y_mult * metrics->line_gap); @@ -846,23 +898,25 @@ _hb_ft_cubic_to (const FT_Vector *control1, return FT_Err_Ok; } -static void -hb_ft_draw_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data HB_UNUSED) +static hb_bool_t +hb_ft_draw_glyph_or_fail (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data HB_UNUSED) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; if (unlikely (FT_Load_Glyph (ft_face, glyph, FT_LOAD_NO_BITMAP | ft_font->load_flags))) - return; + return false; if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) - return; + return false; const FT_Outline_Funcs outline_funcs = { _hb_ft_move_to, @@ -873,43 +927,13 @@ hb_ft_draw_glyph (hb_font_t *font, 0, /* delta */ }; - hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); - - /* Embolden */ - if (font->x_strength || font->y_strength) - { - FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_strength, font->y_strength); - - int x_shift = 0; - int y_shift = 0; - if (font->embolden_in_place) - { - /* Undo the FreeType shift. */ - x_shift = -font->x_strength / 2; - y_shift = 0; - if (font->y_scale < 0) y_shift = -font->y_strength; - } - else - { - /* FreeType applied things in the wrong direction for negative scale; fix up. */ - if (font->x_scale < 0) x_shift = -font->x_strength; - if (font->y_scale < 0) y_shift = -font->y_strength; - } - if (x_shift || y_shift) - { - auto &outline = ft_face->glyph->outline; - for (auto &point : hb_iter (outline.points, outline.contours[outline.n_contours - 1] + 1)) - { - point.x += x_shift; - point.y += y_shift; - } - } - } - + hb_draw_session_t draw_session {draw_funcs, draw_data}; FT_Outline_Decompose (&ft_face->glyph->outline, &outline_funcs, &draw_session); + + return true; } #endif @@ -918,25 +942,31 @@ hb_ft_draw_glyph (hb_font_t *font, #include "hb-ft-colr.hh" -static void -hb_ft_paint_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t gid, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette_index, - hb_color_t foreground, - void *user_data) +static hb_bool_t +hb_ft_paint_glyph_or_fail (hb_font_t *font, + void *font_data, + hb_codepoint_t gid, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette_index, + hb_color_t foreground, + void *user_data) { const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; + _hb_ft_hb_font_check_changed (font, ft_font); + hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; + FT_Long load_flags = ft_font->load_flags | FT_LOAD_COLOR; +#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21301 + load_flags |= FT_LOAD_NO_SVG; +#endif + /* We release the lock before calling into glyph callbacks, such that * eg. draw API can call back into the face.*/ - if (unlikely (FT_Load_Glyph (ft_face, gid, - ft_font->load_flags | FT_LOAD_COLOR))) - return; + if (unlikely (FT_Load_Glyph (ft_face, gid, load_flags))) + return false; if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { @@ -944,26 +974,21 @@ hb_ft_paint_glyph (hb_font_t *font, paint_funcs, paint_data, palette_index, foreground, user_data)) - return; - - /* Simple outline. */ - ft_font->lock.unlock (); - paint_funcs->push_clip_glyph (paint_data, gid, font); - ft_font->lock.lock (); - paint_funcs->color (paint_data, true, foreground); - paint_funcs->pop_clip (paint_data); + return true; - return; + // Outline glyph + return false; } auto *glyph = ft_face->glyph; if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { + bool ret = false; auto &bitmap = glyph->bitmap; if (bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { if (bitmap.pitch != (signed) bitmap.width * 4) - return; + return ret; ft_font->lock.unlock (); @@ -973,27 +998,26 @@ hb_ft_paint_glyph (hb_font_t *font, nullptr, nullptr); hb_glyph_extents_t extents; - if (!hb_font_get_glyph_extents (font, gid, &extents)) + if (!font->get_glyph_extents (gid, &extents, false)) goto out; - if (!paint_funcs->image (paint_data, - blob, - bitmap.width, - bitmap.rows, - HB_PAINT_IMAGE_FORMAT_BGRA, - font->slant_xy, - &extents)) - { - /* TODO Try a forced outline load and paint? */ - } + if (paint_funcs->image (paint_data, + blob, + bitmap.width, + bitmap.rows, + HB_PAINT_IMAGE_FORMAT_BGRA, + 0.f, + &extents)) + ret = true; out: hb_blob_destroy (blob); ft_font->lock.lock (); } - return; + return ret; } + return false; } #endif #endif @@ -1013,10 +1037,8 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t= 21300 - hb_font_funcs_set_paint_glyph_func (funcs, hb_ft_paint_glyph, nullptr, nullptr); + hb_font_funcs_set_paint_glyph_or_fail_func (funcs, hb_ft_paint_glyph_or_fail, nullptr, nullptr); #endif #endif @@ -1083,6 +1104,10 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data FT_ULong length = 0; FT_Error error; + /* In new FreeType, a tag value of 1 loads the SFNT table directory. Reject it. */ + if (tag == 1) + return nullptr; + /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ error = FT_Load_Sfnt_Table (ft_face, tag, 0, nullptr, &length); @@ -1286,7 +1311,7 @@ hb_ft_face_create_cached (FT_Face ft_face) * * If you know you have valid reasons not to use hb_ft_font_create_referenced(), * then it is the client program's responsibility to destroy @ft_face - * after the #hb_font_t font object has been destroyed. + * only after the #hb_font_t font object has been destroyed. * * HarfBuzz will use the @destroy callback on the #hb_font_t font object * if it is supplied when you use this function. However, even if @destroy @@ -1356,7 +1381,7 @@ hb_ft_font_changed (hb_font_t *font) for (unsigned int i = 0; i < mm_var->num_axis; ++i) { - coords[i] = ft_coords[i] >>= 2; + coords[i] = (ft_coords[i] + 2) >> 2; nonzero = nonzero || coords[i]; } @@ -1390,6 +1415,10 @@ hb_ft_font_changed (hb_font_t *font) * variation-axis settings on the @font. * This call is fast if nothing has changed on @font. * + * Note that as of version 11.0.0, calling this function is not necessary, + * as HarfBuzz will automatically detect changes to the font and update + * the underlying FT_Face as needed. + * * Return value: true if changed, false otherwise * * Since: 4.4.0 @@ -1521,7 +1550,8 @@ destroy_ft_library (void *arg) * font file and face index. * * This is similar in functionality to hb_face_create_from_file_or_fail(), - * but uses the FreeType library for loading the font file. + * but uses the FreeType library for loading the font file. This can + * be useful, for example, to load WOFF and WOFF2 font data. * * Return value: (transfer full): The new face object, or `NULL` if * no face is found at the specified index or the file cannot be read. @@ -1558,6 +1588,75 @@ hb_ft_face_create_from_file_or_fail (const char *file_name, return face; } +static hb_user_data_key_t ft_blob_key = {0}; + +static void +_destroy_blob (void *p) +{ + hb_blob_destroy ((hb_blob_t *) p); +} + +/** + * hb_ft_face_create_from_blob_or_fail: + * @blob: A blob + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * font blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the FreeType library for loading the font blob. This can + * be useful, for example, to load WOFF and WOFF2 font data. + * + * Return value: (transfer full): The new face object, or `NULL` if + * loading fails (eg. blob does not contain valid font data). + * + * Since: 11.0.0 + */ +hb_face_t * +hb_ft_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + FT_Library ft_library = reference_ft_library (); + if (unlikely (!ft_library)) + { + DEBUG_MSG (FT, ft_library, "reference_ft_library failed"); + return nullptr; + } + + hb_blob_make_immutable (blob); + unsigned blob_size; + const char *blob_data = hb_blob_get_data (blob, &blob_size); + + FT_Face ft_face; + if (unlikely (FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_size, + index, + &ft_face))) + return nullptr; + + hb_face_t *face = hb_ft_face_create_referenced (ft_face); + FT_Done_Face (ft_face); + + ft_face->generic.data = ft_library; + ft_face->generic.finalizer = finalize_ft_library; + + if (hb_face_is_immutable (face)) + return nullptr; + + // Hook the blob to the hb_face_t, since FT_Face still needs it. + hb_blob_reference (blob); + if (!hb_face_set_user_data (face, &ft_blob_key, blob, _destroy_blob, true)) + { + hb_blob_destroy (blob); + hb_face_destroy (face); + return nullptr; + } + + return face; +} + static void _release_blob (void *arg) { @@ -1594,6 +1693,11 @@ _release_blob (void *arg) void hb_ft_font_set_funcs (hb_font_t *font) { + // In case of failure... + hb_font_set_funcs (font, + hb_font_funcs_get_empty (), + nullptr, nullptr); + hb_blob_t *blob = hb_face_reference_blob (font->face); unsigned int blob_length; const char *blob_data = hb_blob_get_data (blob, &blob_length); @@ -1628,7 +1732,12 @@ hb_ft_font_set_funcs (hb_font_t *font) ft_face->generic.finalizer = _release_blob; // And the FT_Library to the blob - hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true); + if (unlikely (!hb_blob_set_user_data (blob, &ft_library_key, ft_library, destroy_ft_library, true))) + { + DEBUG_MSG (FT, font, "hb_blob_set_user_data() failed"); + FT_Done_Face (ft_face); + return; + } _hb_ft_font_set_funcs (font, ft_face, true); hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); diff --git a/thirdparty/harfbuzz/upstream/hb-ft.h b/thirdparty/harfbuzz/upstream/hb-ft.h index 8cf14dc39..227b4f221 100644 --- a/thirdparty/harfbuzz/upstream/hb-ft.h +++ b/thirdparty/harfbuzz/upstream/hb-ft.h @@ -88,6 +88,10 @@ HB_EXTERN hb_face_t * hb_ft_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_ft_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + /* * hb-font from ft-face. */ @@ -111,7 +115,7 @@ HB_EXTERN hb_font_t * hb_ft_font_create_referenced (FT_Face ft_face); HB_EXTERN FT_Face -hb_ft_font_get_face (hb_font_t *font); +hb_ft_font_get_ft_face (hb_font_t *font); HB_EXTERN FT_Face hb_ft_font_lock_face (hb_font_t *font); @@ -142,6 +146,13 @@ hb_ft_hb_font_changed (hb_font_t *font); HB_EXTERN void hb_ft_font_set_funcs (hb_font_t *font); +#ifndef HB_DISABLE_DEPRECATED + +HB_DEPRECATED_FOR (hb_ft_font_get_ft_face) +HB_EXTERN FT_Face +hb_ft_font_get_face (hb_font_t *font); + +#endif HB_END_DECLS diff --git a/thirdparty/harfbuzz/upstream/hb-geometry.hh b/thirdparty/harfbuzz/upstream/hb-geometry.hh index 7777ff9ac..60f4e692c 100644 --- a/thirdparty/harfbuzz/upstream/hb-geometry.hh +++ b/thirdparty/harfbuzz/upstream/hb-geometry.hh @@ -26,11 +26,19 @@ #include "hb.hh" +#include "hb-algs.hh" + +template struct hb_extents_t { hb_extents_t () {} - hb_extents_t (float xmin, float ymin, float xmax, float ymax) : + hb_extents_t (const hb_glyph_extents_t &extents) : + xmin (hb_min (extents.x_bearing, extents.x_bearing + extents.width)), + ymin (hb_min (extents.y_bearing, extents.y_bearing + extents.height)), + xmax (hb_max (extents.x_bearing, extents.x_bearing + extents.width)), + ymax (hb_max (extents.y_bearing, extents.y_bearing + extents.height)) {} + hb_extents_t (Float xmin, Float ymin, Float xmax, Float ymax) : xmin (xmin), ymin (ymin), xmax (xmax), ymax (ymax) {} bool is_empty () const { return xmin >= xmax || ymin >= ymax; } @@ -38,6 +46,12 @@ struct hb_extents_t void union_ (const hb_extents_t &o) { + if (o.is_empty ()) return; + if (is_empty ()) + { + *this = o; + return; + } xmin = hb_min (xmin, o.xmin); ymin = hb_min (ymin, o.ymin); xmax = hb_max (xmax, o.xmax); @@ -46,6 +60,11 @@ struct hb_extents_t void intersect (const hb_extents_t &o) { + if (o.is_empty () || is_empty ()) + { + *this = hb_extents_t {}; + return; + } xmin = hb_max (xmin, o.xmin); ymin = hb_max (ymin, o.ymin); xmax = hb_min (xmax, o.xmax); @@ -53,7 +72,7 @@ struct hb_extents_t } void - add_point (float x, float y) + add_point (Float x, Float y) { if (unlikely (is_void ())) { @@ -69,55 +88,81 @@ struct hb_extents_t } } - float xmin = 0.f; - float ymin = 0.f; - float xmax = -1.f; - float ymax = -1.f; + hb_glyph_extents_t to_glyph_extents (bool xneg = false, bool yneg = false) const + { + hb_position_t x0 = (hb_position_t) roundf (xmin); + hb_position_t y0 = (hb_position_t) roundf (ymin); + hb_position_t x1 = (hb_position_t) roundf (xmax); + hb_position_t y1 = (hb_position_t) roundf (ymax); + return hb_glyph_extents_t {xneg ? x1 : x0, + yneg ? y0 : y1, + xneg ? x0 - x1 : x1 - x0, + yneg ? y1 - y0 : y0 - y1}; + } + + Float xmin = 0; + Float ymin = 0; + Float xmax = -1; + Float ymax = -1; }; +template struct hb_transform_t { hb_transform_t () {} - hb_transform_t (float xx, float yx, - float xy, float yy, - float x0, float y0) : + hb_transform_t (Float xx, Float yx, + Float xy, Float yy, + Float x0, Float y0) : xx (xx), yx (yx), xy (xy), yy (yy), x0 (x0), y0 (y0) {} - void multiply (const hb_transform_t &o) + bool is_identity () const { - /* Copied from cairo, with "o" being "a" there and "this" being "b" there. */ - hb_transform_t r; - - r.xx = o.xx * xx + o.yx * xy; - r.yx = o.xx * yx + o.yx * yy; - - r.xy = o.xy * xx + o.yy * xy; - r.yy = o.xy * yx + o.yy * yy; - - r.x0 = o.x0 * xx + o.y0 * xy + x0; - r.y0 = o.x0 * yx + o.y0 * yy + y0; + return xx == 1 && yx == 0 && + xy == 0 && yy == 1 && + x0 == 0 && y0 == 0; + } + bool is_translation () const + { + return xx == 1 && yx == 0 && + xy == 0 && yy == 1; + } - *this = r; + void multiply (const hb_transform_t &o, bool before=false) + { + // Copied from cairo-matrix.c + const hb_transform_t &a = before ? o : *this; + const hb_transform_t &b = before ? *this : o; + *this = { + a.xx * b.xx + a.xy * b.yx, + a.yx * b.xx + a.yy * b.yx, + a.xx * b.xy + a.xy * b.yy, + a.yx * b.xy + a.yy * b.yy, + a.xx * b.x0 + a.xy * b.y0 + a.x0, + a.yx * b.x0 + a.yy * b.y0 + a.y0 + }; } - void transform_distance (float &dx, float &dy) const + HB_ALWAYS_INLINE + void transform_distance (Float &dx, Float &dy) const { - float new_x = xx * dx + xy * dy; - float new_y = yx * dx + yy * dy; + Float new_x = xx * dx + xy * dy; + Float new_y = yx * dx + yy * dy; dx = new_x; dy = new_y; } - void transform_point (float &x, float &y) const + HB_ALWAYS_INLINE + void transform_point (Float &x, Float &y) const { - transform_distance (x, y); - x += x0; - y += y0; + Float new_x = x0 + xx * x + xy * y; + Float new_y = y0 + yx * x + yy * y; + x = new_x; + y = new_y; } - void transform_extents (hb_extents_t &extents) const + void transform_extents (hb_extents_t &extents) const { - float quad_x[4], quad_y[4]; + Float quad_x[4], quad_y[4]; quad_x[0] = extents.xmin; quad_y[0] = extents.ymin; @@ -128,7 +173,7 @@ struct hb_transform_t quad_x[3] = extents.xmax; quad_y[3] = extents.ymax; - extents = hb_extents_t {}; + extents = hb_extents_t {}; for (unsigned i = 0; i < 4; i++) { transform_point (quad_x[i], quad_y[i]); @@ -136,20 +181,36 @@ struct hb_transform_t } } - void transform (const hb_transform_t &o) { multiply (o); } + void transform (const hb_transform_t &o, bool before=false) { multiply (o, before); } - void translate (float x, float y) + static hb_transform_t translation (Float x, Float y) { - if (x == 0.f && y == 0.f) - return; + return {1, 0, 0, 1, x, y}; + } + void translate (Float x, Float y, bool before=false) + { + if (before) + { + x0 += x; + y0 += y; + } + else + { + if (x == 0 && y == 0) + return; - x0 += xx * x + xy * y; - y0 += yx * x + yy * y; + x0 += xx * x + xy * y; + y0 += yx * x + yy * y; + } } - void scale (float scaleX, float scaleY) + static hb_transform_t scaling (Float scaleX, Float scaleY) + { + return {scaleX, 0, 0, scaleY, 0, 0}; + } + void scale (Float scaleX, Float scaleY) { - if (scaleX == 1.f && scaleY == 1.f) + if (scaleX == 1 && scaleY == 1) return; xx *= scaleX; @@ -157,50 +218,94 @@ struct hb_transform_t xy *= scaleY; yy *= scaleY; } - - void rotate (float rotation) + static hb_transform_t scaling_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) + { + return {scaleX, 0, 0, scaleY, + center_x ? (1 - scaleX) * center_x : 0, + center_y ? (1 - scaleY) * center_y : 0}; + } + void scale_around_center (Float scaleX, Float scaleY, Float center_x, Float center_y) { - if (rotation == 0.f) + if (scaleX == 1 && scaleY == 1) return; + transform (scaling_around_center (scaleX, scaleY, center_x, center_y)); + } + + static hb_transform_t rotation (Float radians) + { // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240 - rotation = rotation * HB_PI; - float c; - float s; -#ifdef HAVE_SINCOSF - sincosf (rotation, &s, &c); -#else - c = cosf (rotation); - s = sinf (rotation); -#endif - auto other = hb_transform_t{c, s, -s, c, 0.f, 0.f}; - transform (other); + Float c; + Float s; + hb_sincos (radians, s, c); + return {c, s, -s, c, 0, 0}; + } + void rotate (Float radians, bool before=false) + { + if (radians == 0) + return; + + transform (rotation (radians), before); + } + + static hb_transform_t rotation_around_center (Float radians, Float center_x, Float center_y) + { + Float s, c; + hb_sincos (radians, s, c); + return { + c, s, -s, c, + (1 - c) * center_x + s * center_y, + -s * center_x + (1 - c) * center_y + }; } + void rotate_around_center (Float radians, Float center_x, Float center_y, bool before=false) + { + if (radians == 0) + return; - void skew (float skewX, float skewY) + transform (rotation_around_center (radians, center_x, center_y), before); + } + + static hb_transform_t skewing (Float skewX, Float skewY) + { + return {1, skewY ? tanf (skewY) : 0, skewX ? tanf (skewX) : 0, 1, 0, 0}; + } + void skew (Float skewX, Float skewY) { - if (skewX == 0.f && skewY == 0.f) + if (skewX == 0 && skewY == 0) return; - // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255 - skewX = skewX * HB_PI; - skewY = skewY * HB_PI; - auto other = hb_transform_t{1.f, - skewY ? tanf (skewY) : 0.f, - skewX ? tanf (skewX) : 0.f, - 1.f, - 0.f, 0.f}; - transform (other); + transform (skewing (skewX, skewY)); } + static hb_transform_t skewing_around_center (Float skewX, Float skewY, Float center_x, Float center_y) + { + skewX = skewX ? tanf (skewX) : 0; + skewY = skewY ? tanf (skewY) : 0; + return { + 1, skewY, skewX, 1, + center_y ? -skewX * center_y : 0, + center_x ? -skewY * center_x : 0 + }; + } + void skew_around_center (Float skewX, Float skewY, Float center_x, Float center_y) + { + if (skewX == 0 && skewY == 0) + return; - float xx = 1.f; - float yx = 0.f; - float xy = 0.f; - float yy = 1.f; - float x0 = 0.f; - float y0 = 0.f; + transform (skewing_around_center (skewX, skewY, center_x, center_y)); + } + + Float xx = 1; + Float yx = 0; + Float xy = 0; + Float yy = 1; + Float x0 = 0; + Float y0 = 0; }; +#define HB_TRANSFORM_IDENTITY {1, 0, 0, 1, 0, 0} + +template struct hb_bounds_t { enum status_t { @@ -209,8 +314,8 @@ struct hb_bounds_t EMPTY, }; - hb_bounds_t (status_t status) : status (status) {} - hb_bounds_t (const hb_extents_t &extents) : + hb_bounds_t (status_t status = UNBOUNDED) : status (status) {} + hb_bounds_t (const hb_extents_t &extents) : status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {} void union_ (const hb_bounds_t &o) @@ -244,20 +349,21 @@ struct hb_bounds_t } status_t status; - hb_extents_t extents; + hb_extents_t extents; }; +template struct hb_transform_decomposed_t { - float translateX = 0; - float translateY = 0; - float rotation = 0; // in degrees, counter-clockwise - float scaleX = 1; - float scaleY = 1; - float skewX = 0; // in degrees, counter-clockwise - float skewY = 0; // in degrees, counter-clockwise - float tCenterX = 0; - float tCenterY = 0; + Float translateX = 0; + Float translateY = 0; + Float rotation = 0; // in radians, counter-clockwise + Float scaleX = 1; + Float scaleY = 1; + Float skewX = 0; // in radians, counter-clockwise + Float skewY = 0; // in radians, counter-clockwise + Float tCenterX = 0; + Float tCenterY = 0; operator bool () const { @@ -268,9 +374,9 @@ struct hb_transform_decomposed_t tCenterX || tCenterY; } - hb_transform_t to_transform () const + hb_transform_t to_transform () const { - hb_transform_t t; + hb_transform_t t; t.translate (translateX + tCenterX, translateY + tCenterY); t.rotate (rotation); t.scale (scaleX, scaleY); diff --git a/thirdparty/harfbuzz/upstream/hb-glib.cc b/thirdparty/harfbuzz/upstream/hb-glib.cc index 1da81696e..a85cb365d 100644 --- a/thirdparty/harfbuzz/upstream/hb-glib.cc +++ b/thirdparty/harfbuzz/upstream/hb-glib.cc @@ -127,11 +127,7 @@ hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t *ab, void *user_data HB_UNUSED) { -#if GLIB_CHECK_VERSION(2,29,12) return g_unichar_compose (a, b, ab); -#else - return false; -#endif } static hb_bool_t @@ -141,11 +137,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t *b, void *user_data HB_UNUSED) { -#if GLIB_CHECK_VERSION(2,29,12) return g_unichar_decompose (ab, a, b); -#else - return false; -#endif } diff --git a/thirdparty/harfbuzz/upstream/hb-gobject-enums.cc.tmpl b/thirdparty/harfbuzz/upstream/hb-gobject-enums.cc.tmpl deleted file mode 100644 index 87a11dd40..000000000 --- a/thirdparty/harfbuzz/upstream/hb-gobject-enums.cc.tmpl +++ /dev/null @@ -1,80 +0,0 @@ -/*** BEGIN file-header ***/ -/* - * Copyright (C) 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" - -#ifdef HAVE_GOBJECT - -/* g++ didn't like older gtype.h gcc-only code path. */ -#include -#if !GLIB_CHECK_VERSION(2,29,16) -#undef __GNUC__ -#undef __GNUC_MINOR__ -#define __GNUC__ 2 -#define __GNUC_MINOR__ 6 -#endif - -#include "hb-gobject.h" - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -/* enumerations from "@basename@" */ -/*** END file-production ***/ - -/*** BEGIN file-tail ***/ - -#endif -/*** END file-tail ***/ - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type () -{ - static gsize type_id = 0; - - if (g_once_init_enter (&type_id)) - { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL } - }; - GType id = - g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - g_once_init_leave (&type_id, id); - } - - return type_id; -} - -/*** END value-tail ***/ diff --git a/thirdparty/harfbuzz/upstream/hb-gobject-structs.cc b/thirdparty/harfbuzz/upstream/hb-gobject-structs.cc index d66de0b23..60670b862 100644 --- a/thirdparty/harfbuzz/upstream/hb-gobject-structs.cc +++ b/thirdparty/harfbuzz/upstream/hb-gobject-structs.cc @@ -51,12 +51,6 @@ /* g++ didn't like older gtype.h gcc-only code path. */ #include -#if !GLIB_CHECK_VERSION(2,29,16) -#undef __GNUC__ -#undef __GNUC_MINOR__ -#define __GNUC__ 2 -#define __GNUC_MINOR__ 6 -#endif #include "hb-gobject.h" diff --git a/thirdparty/harfbuzz/upstream/hb-graphite2.cc b/thirdparty/harfbuzz/upstream/hb-graphite2.cc index 7ea038622..e2acdffb1 100644 --- a/thirdparty/harfbuzz/upstream/hb-graphite2.cc +++ b/thirdparty/harfbuzz/upstream/hb-graphite2.cc @@ -68,7 +68,7 @@ struct hb_graphite2_face_data_t { hb_face_t *face; gr_face *grface; - hb_atomic_ptr_t tlist; + hb_atomic_t tlist; }; static const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len) @@ -266,7 +266,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, gr_segment *seg = nullptr; const gr_slot *is; unsigned int ci = 0, ic = 0; - unsigned int curradvx = 0, curradvy = 0; + int curradvx = 0, curradvy = 0; unsigned int scratch_size; hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); diff --git a/thirdparty/harfbuzz/upstream/hb-harfrust.cc b/thirdparty/harfbuzz/upstream/hb-harfrust.cc new file mode 100644 index 000000000..b4ebcc279 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-harfrust.cc @@ -0,0 +1,209 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#ifdef HAVE_HARFRUST + +#include "hb-shaper-impl.hh" + +#include "hb-utf.hh" + + +/* + * buffer + */ +extern "C" void * +_hb_harfrust_buffer_create_rs (void); + +extern "C" void +_hb_harfrust_buffer_destroy_rs (void *data); + + +/* + * shaper face data + */ + +extern "C" void * +_hb_harfrust_shaper_face_data_create_rs (hb_face_t *face); + +hb_harfrust_face_data_t * +_hb_harfrust_shaper_face_data_create (hb_face_t *face) +{ + return (hb_harfrust_face_data_t *) _hb_harfrust_shaper_face_data_create_rs (face); +} + +extern "C" void +_hb_harfrust_shaper_face_data_destroy_rs (void *data); + +void +_hb_harfrust_shaper_face_data_destroy (hb_harfrust_face_data_t *data) +{ + _hb_harfrust_shaper_face_data_destroy_rs (data); +} + + +/* + * shaper font data + */ + +extern "C" void * +_hb_harfrust_shaper_font_data_create_rs (hb_font_t *font, const void *face_data); + +hb_harfrust_font_data_t * +_hb_harfrust_shaper_font_data_create (hb_font_t *font) +{ + const hb_harfrust_face_data_t *face_data = font->face->data.harfrust; + return (hb_harfrust_font_data_t *) _hb_harfrust_shaper_font_data_create_rs (font, face_data); +} + +extern "C" void +_hb_harfrust_shaper_font_data_destroy_rs (void *data); + +void +_hb_harfrust_shaper_font_data_destroy (hb_harfrust_font_data_t *data) +{ + _hb_harfrust_shaper_font_data_destroy_rs (data); +} + + +/* + * shape plan + */ + +extern "C" void * +_hb_harfrust_shape_plan_create_rs (const void *font_data, + hb_script_t script, + hb_language_t language, + hb_direction_t direction); + +extern "C" void +_hb_harfrust_shape_plan_destroy_rs (void *data); + + +/* + * shaper + */ + +extern "C" hb_bool_t +_hb_harfrust_shape_rs (const void *font_data, + const void *face_data, + const void *rs_shape_plan, + const void *rs_buffer, + hb_font_t *font, + hb_buffer_t *buffer, + const uint8_t *pre_context, + uint32_t pre_context_len, + const uint8_t *post_context, + uint32_t post_context_len, + const hb_feature_t *features, + unsigned int num_features); + +static hb_user_data_key_t hb_object_key = {0}; + +hb_bool_t +_hb_harfrust_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + const hb_harfrust_font_data_t *font_data = font->data.harfrust; + const hb_harfrust_face_data_t *face_data = font->face->data.harfrust; + +retry_buffer: + void *hr_buffer = hb_buffer_get_user_data (buffer, &hb_object_key); + if (unlikely (!hr_buffer)) + { + hr_buffer = _hb_harfrust_buffer_create_rs (); + if (unlikely (!hr_buffer)) + return false; + + if (!hb_buffer_set_user_data (buffer, + &hb_object_key, + hr_buffer, + _hb_harfrust_buffer_destroy_rs, + false)) + { + _hb_harfrust_buffer_destroy_rs (hr_buffer); + goto retry_buffer; + } + } + + void *hr_shape_plan = nullptr; + + if (!num_features) + { + retry_shape_plan: + hr_shape_plan = hb_shape_plan_get_user_data (shape_plan, &hb_object_key); + if (unlikely (!hr_shape_plan)) + { + hr_shape_plan = _hb_harfrust_shape_plan_create_rs (font_data, + shape_plan->key.props.script, + shape_plan->key.props.language, + shape_plan->key.props.direction); + if (hr_shape_plan && + !hb_shape_plan_set_user_data (shape_plan, + &hb_object_key, + hr_shape_plan, + _hb_harfrust_shape_plan_destroy_rs, + false)) + { + _hb_harfrust_shape_plan_destroy_rs (hr_shape_plan); + goto retry_shape_plan; + } + } + } + + // Encode buffer pre/post-context as UTF-8, so that HarfRust can use it. + constexpr int CONTEXT_BYTE_SIZE = 4 * hb_buffer_t::CONTEXT_LENGTH; + uint8_t pre_context[CONTEXT_BYTE_SIZE]; + unsigned pre_context_len = 0; + for (unsigned i = buffer->context_len[0]; i; i--) + pre_context_len = hb_utf8_t::encode (pre_context + pre_context_len, + pre_context + CONTEXT_BYTE_SIZE, + buffer->context[0][i - 1]) - pre_context; + uint8_t post_context[CONTEXT_BYTE_SIZE]; + unsigned post_context_len = 0; + for (unsigned i = 0; i < buffer->context_len[1]; i++) + post_context_len = hb_utf8_t::encode (post_context + post_context_len, + post_context + CONTEXT_BYTE_SIZE, + buffer->context[1][i]) - post_context; + + return _hb_harfrust_shape_rs (font_data, + face_data, + hr_shape_plan, + hr_buffer, + font, + buffer, + pre_context, + pre_context_len, + post_context, + post_context_len, + features, + num_features); +} + + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-iter.hh b/thirdparty/harfbuzz/upstream/hb-iter.hh index 04d09940a..ecc30f4e1 100644 --- a/thirdparty/harfbuzz/upstream/hb-iter.hh +++ b/thirdparty/harfbuzz/upstream/hb-iter.hh @@ -772,8 +772,9 @@ struct hb_iota_iter_t : template auto inc (hb_type_identity s, hb_priority<1>) - -> hb_void_t (s), hb_declval ()))> - { v = hb_invoke (std::forward (s), v); } + -> hb_void_t> (s), + hb_declval ()))> + { v = hb_invoke (std::forward> (s), v); } void inc (S s, hb_priority<0>) @@ -972,7 +973,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (!hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (!hb_match (p, hb_get (f, *it))) return false; return true; } @@ -989,7 +990,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (hb_match (p, hb_get (f, *it))) return true; return false; } @@ -1006,7 +1007,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (std::forward (p), hb_get (std::forward (f), *it))) + if (hb_match (p, hb_get (f, *it))) return false; return true; } diff --git a/thirdparty/harfbuzz/upstream/hb-kbts.cc b/thirdparty/harfbuzz/upstream/hb-kbts.cc new file mode 100644 index 000000000..4fc2c48db --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-kbts.cc @@ -0,0 +1,325 @@ +/* + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Khaled Hosny + */ + +#include "hb.hh" + +#ifdef HAVE_KBTS + +#include "hb-shaper-impl.hh" + +#define KB_TEXT_SHAPE_IMPLEMENTATION +#define KB_TEXT_SHAPE_STATIC +#define KB_TEXT_SHAPE_NO_CRT +#define KBTS_MALLOC(a, b) hb_malloc(b) +#define KBTS_FREE(a, b) hb_free(b) +#define KBTS_MEMCPY hb_memcpy +#define KBTS_MEMSET hb_memset + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wextra-semi-stmt" +#include "kb_text_shape.h" +#pragma GCC diagnostic pop + +static hb_user_data_key_t hb_kbts_shape_plan_data_key = {0}; + +struct hb_kbts_shape_plan_data_t +{ + kbts_shape_config *config = nullptr; + mutable hb_atomic_t scratchpad; +}; + +static void +hb_kbts_shape_plan_data_destroy (void *data) +{ + auto *plan_data = (hb_kbts_shape_plan_data_t *) data; + if (!plan_data) + return; + + auto *scratchpad = plan_data->scratchpad.get_acquire (); + if (scratchpad && plan_data->scratchpad.cmpexch (scratchpad, nullptr)) + kbts_DestroyShapeScratchpad (scratchpad); + + if (plan_data->config) + kbts_DestroyShapeConfig (plan_data->config); + + hb_free (plan_data); +} + +static void +hb_kbts_plan_props_to_script_language (const hb_segment_properties_t &props, + kbts_script *kb_script, + kbts_language *kb_language) +{ + hb_tag_t scripts[HB_OT_MAX_TAGS_PER_SCRIPT]; + hb_tag_t language; + unsigned int script_count = ARRAY_LENGTH (scripts); + unsigned int language_count = 1; + + *kb_script = KBTS_SCRIPT_DONT_KNOW; + *kb_language = KBTS_LANGUAGE_DEFAULT; + + hb_ot_tags_from_script_and_language (props.script, props.language, + &script_count, scripts, + &language_count, &language); + + for (unsigned int i = 0; i < script_count && scripts[i] != HB_TAG_NONE; ++i) + { + *kb_script = kbts_ScriptTagToScript (hb_uint32_swap (scripts[i])); + if (*kb_script != KBTS_SCRIPT_DONT_KNOW) + break; + } + + if (language_count) + *kb_language = (kbts_language) hb_uint32_swap (language); +} + +static hb_kbts_shape_plan_data_t * +hb_kbts_get_shape_plan_data (hb_shape_plan_t *shape_plan, + kbts_font *kb_font) +{ +retry: + auto *plan_data = (hb_kbts_shape_plan_data_t *) + hb_shape_plan_get_user_data (shape_plan, &hb_kbts_shape_plan_data_key); + if (plan_data) + return plan_data; + + kbts_script kb_script; + kbts_language kb_language; + hb_kbts_plan_props_to_script_language (shape_plan->key.props, &kb_script, &kb_language); + + kbts_shape_config *config = kbts_CreateShapeConfig (kb_font, kb_script, kb_language, nullptr, nullptr); + if (unlikely (!config)) + return nullptr; + + plan_data = (hb_kbts_shape_plan_data_t *) hb_calloc (1, sizeof (*plan_data)); + if (unlikely (!plan_data)) + { + kbts_DestroyShapeConfig (config); + return nullptr; + } + + plan_data->config = config; + plan_data->scratchpad.init (nullptr); + + if (!hb_shape_plan_set_user_data (shape_plan, + &hb_kbts_shape_plan_data_key, + plan_data, + hb_kbts_shape_plan_data_destroy, + false)) + { + hb_kbts_shape_plan_data_destroy (plan_data); + goto retry; + } + + return plan_data; +} + +static kbts_shape_scratchpad * +hb_kbts_acquire_shape_scratchpad (hb_kbts_shape_plan_data_t *plan_data) +{ + auto *scratchpad = plan_data->scratchpad.get_acquire (); + if (!scratchpad || unlikely (!plan_data->scratchpad.cmpexch (scratchpad, nullptr))) + scratchpad = kbts_CreateShapeScratchpad (plan_data->config, nullptr, nullptr); + + return scratchpad; +} + +static void +hb_kbts_release_shape_scratchpad (hb_kbts_shape_plan_data_t *plan_data, + kbts_shape_scratchpad *scratchpad) +{ + if (!scratchpad) + return; + + if (!plan_data->scratchpad.cmpexch (nullptr, scratchpad)) + kbts_DestroyShapeScratchpad (scratchpad); +} + + +hb_kbts_face_data_t * +_hb_kbts_shaper_face_data_create (hb_face_t *face) +{ + hb_blob_t *blob = hb_face_reference_blob (face); + + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + { + DEBUG_MSG (KBTS, blob, "Empty blob"); + hb_blob_destroy (blob); + return nullptr; + } + + kbts_font *kb_font = (kbts_font *) hb_calloc (1, sizeof (kbts_font)); + if (unlikely (!kb_font)) + { + hb_blob_destroy (blob); + return nullptr; + } + + *kb_font = kbts_FontFromMemory((void *)blob_data, blob_length, face->index, nullptr, nullptr); + hb_blob_destroy (blob); + blob = nullptr; + + if (unlikely (!kbts_FontIsValid (kb_font))) + { + DEBUG_MSG (KBTS, face, "Failed create font from data"); + kbts_FreeFont (kb_font); + hb_free (kb_font); + return nullptr; + } + + return (hb_kbts_face_data_t *) kb_font; +} + +void +_hb_kbts_shaper_face_data_destroy (hb_kbts_face_data_t *data) +{ + kbts_font *font = (kbts_font *) data; + + assert (kbts_FontIsValid (font)); + + kbts_FreeFont (font); + hb_free (font); +} + +hb_kbts_font_data_t * +_hb_kbts_shaper_font_data_create (hb_font_t *font) +{ + return (hb_kbts_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_kbts_shaper_font_data_destroy (hb_kbts_font_data_t *data) +{ +} + +hb_bool_t +_hb_kbts_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + hb_face_t *face = font->face; + kbts_font *kb_font = (kbts_font *) (const void *) face->data.kbts; + + kbts_direction kb_direction; + switch (buffer->props.direction) + { + case HB_DIRECTION_LTR: kb_direction = KBTS_DIRECTION_LTR; break; + case HB_DIRECTION_RTL: kb_direction = KBTS_DIRECTION_RTL; break; + case HB_DIRECTION_TTB: + case HB_DIRECTION_BTT: + DEBUG_MSG (KBTS, face, "Vertical direction is not supported"); + return false; + default: + case HB_DIRECTION_INVALID: + DEBUG_MSG (KBTS, face, "Invalid direction"); + return false; + } + + kbts_glyph_storage kb_glyph_storage; + if (unlikely (!kbts_InitializeGlyphStorage (&kb_glyph_storage, nullptr, nullptr))) + return false; + + hb_kbts_shape_plan_data_t *plan_data = hb_kbts_get_shape_plan_data (shape_plan, kb_font); + if (unlikely (!plan_data)) + { + kbts_FreeAllGlyphs (&kb_glyph_storage); + return false; + } + + kbts_shape_config *kb_shape_config = nullptr; + kbts_shape_scratchpad *kb_shape_scratchpad = nullptr; + uint32_t glyph_count = 0; + kbts_glyph *kb_glyph = nullptr; + kbts_glyph_iterator kb_output; + hb_glyph_info_t *info; + hb_glyph_position_t *pos; + hb_bool_t res = false; + + kb_shape_config = plan_data->config; + kb_shape_scratchpad = hb_kbts_acquire_shape_scratchpad (plan_data); + if (unlikely (!kb_shape_scratchpad)) + goto done; + + for (size_t i = 0; i < buffer->len; ++i) + { + kbts_glyph_config *kb_config = nullptr; + if (num_features) + { + hb_vector_t kb_features; + for (unsigned int j = 0; j < num_features; ++j) + { + if (hb_in_range (i, features[j].start, features[j].end)) + kb_features.push({ hb_uint32_swap (features[j].tag), (int)features[j].value }); + } + if (kb_features) + kb_config = kbts_CreateGlyphConfig (kb_shape_config, kb_features.arrayZ, kb_features.length, nullptr, nullptr); + } + kbts_PushGlyph (&kb_glyph_storage, kb_font, buffer->info[i].codepoint, kb_config, buffer->info[i].cluster); + } + + res = kbts_ShapeDirect (kb_shape_scratchpad, &kb_glyph_storage, kb_direction, &kb_output) == KBTS_SHAPE_ERROR_NONE; + if (unlikely (!res)) + goto done; + + for (auto it = kb_output; kbts_GlyphIteratorNext (&it, &kb_glyph); ) + glyph_count += 1; + + hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS); + hb_buffer_set_length (buffer, glyph_count); + + buffer->clear_positions (); + + info = buffer->info; + pos = buffer->pos; + + for (auto it = kb_output; kbts_GlyphIteratorNext (&it, &kb_glyph); info++, pos++) + { + info->codepoint = kb_glyph->Id; + info->cluster = kb_glyph->UserIdOrCodepointIndex; + pos->x_advance = font->em_scalef_x (kb_glyph->AdvanceX); + pos->y_advance = font->em_scalef_y (kb_glyph->AdvanceY); + pos->x_offset = font->em_scalef_x (kb_glyph->OffsetX); + pos->y_offset = font->em_scalef_y (kb_glyph->OffsetY); + } + +done: + if (likely (kb_shape_scratchpad)) + hb_kbts_release_shape_scratchpad (plan_data, kb_shape_scratchpad); + while (kbts_GlyphIteratorNext (&kb_output, &kb_glyph)) + kbts_DestroyGlyphConfig (kb_glyph->Config); + kbts_FreeAllGlyphs (&kb_glyph_storage); + + buffer->clear_glyph_flags (); + buffer->unsafe_to_break (); + + return res; +} + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-kern.hh b/thirdparty/harfbuzz/upstream/hb-kern.hh index 0462a0ea8..e1ebf9074 100644 --- a/thirdparty/harfbuzz/upstream/hb-kern.hh +++ b/thirdparty/harfbuzz/upstream/hb-kern.hh @@ -70,7 +70,7 @@ struct hb_kern_machine_t continue; } - skippy_iter.reset (idx); + skippy_iter.reset_fast (idx); unsigned unsafe_to; if (!skippy_iter.next (&unsafe_to)) { diff --git a/thirdparty/harfbuzz/upstream/hb-limits.hh b/thirdparty/harfbuzz/upstream/hb-limits.hh index fbc7bbe76..c115f9a86 100644 --- a/thirdparty/harfbuzz/upstream/hb-limits.hh +++ b/thirdparty/harfbuzz/upstream/hb-limits.hh @@ -29,20 +29,20 @@ #ifndef HB_BUFFER_MAX_LEN_FACTOR -#define HB_BUFFER_MAX_LEN_FACTOR 64 +#define HB_BUFFER_MAX_LEN_FACTOR 256 #endif #ifndef HB_BUFFER_MAX_LEN_MIN -#define HB_BUFFER_MAX_LEN_MIN 16384 +#define HB_BUFFER_MAX_LEN_MIN 65536 #endif #ifndef HB_BUFFER_MAX_LEN_DEFAULT #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ #endif #ifndef HB_BUFFER_MAX_OPS_FACTOR -#define HB_BUFFER_MAX_OPS_FACTOR 1024 +#define HB_BUFFER_MAX_OPS_FACTOR 4096 #endif #ifndef HB_BUFFER_MAX_OPS_MIN -#define HB_BUFFER_MAX_OPS_MIN 16384 +#define HB_BUFFER_MAX_OPS_MIN 65536 #endif #ifndef HB_BUFFER_MAX_OPS_DEFAULT #define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ @@ -108,5 +108,17 @@ #define HB_MAX_COMPOSITE_OPERATIONS_PER_GLYPH 64 #endif +#ifndef HB_SVG_MAX_PATH_SEGMENTS +#define HB_SVG_MAX_PATH_SEGMENTS 262144 +#endif + +#ifndef HB_SVG_MAX_DOCUMENT_SIZE +#define HB_SVG_MAX_DOCUMENT_SIZE ((size_t) 16 << 20) +#endif + +#ifndef HB_RASTER_MAX_BUFFER_SIZE +#define HB_RASTER_MAX_BUFFER_SIZE ((size_t) 1 << 24) +#endif + #endif /* HB_LIMITS_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-machinery.hh b/thirdparty/harfbuzz/upstream/hb-machinery.hh index ecff94f1b..869fdba0f 100644 --- a/thirdparty/harfbuzz/upstream/hb-machinery.hh +++ b/thirdparty/harfbuzz/upstream/hb-machinery.hh @@ -66,13 +66,22 @@ static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset) } /* StructAfter(X) returns the struct T& that is placed after X. - * Works with X of variable size also. X must implement get_size() */ -template -static inline const Type& StructAfter(const TObject &X) -{ return StructAtOffset(&X, X.get_size()); } -template -static inline Type& StructAfter(TObject &X) -{ return StructAtOffset(&X, X.get_size()); } + * Works with X of variable size also. X must implement get_size(). + * Any extra arguments are forwarded to get_size, so for example + * it can work with UnsizedArrayOf<> as well. */ +template +static inline auto StructAfter(const TObject &X, Ts... args) HB_AUTO_RETURN(( + StructAtOffset(&X, X.get_size(std::forward (args)...)) +)) +/* The is_const shenanigans is to avoid ambiguous overload with gcc-8. + * It disables this path when TObject is const. + * See: https://github.com/harfbuzz/harfbuzz/issues/5429 */ +template +static inline auto StructAfter(TObject &X, Ts... args) HB_AUTO_RETURN(( + sizeof(int[std::is_const::value ? -1 : +1]) > 0 ? + StructAtOffset(&X, X.get_size(std::forward (args)...)) + : *reinterpret_cast (0) +)) /* @@ -132,7 +141,6 @@ static inline Type& StructAfter(TObject &X) DEFINE_SIZE_ARRAY(size, array) - /* * Lazy loaders. * @@ -273,7 +281,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t private: /* Must only have one pointer. */ - hb_atomic_ptr_t instance; + mutable hb_atomic_t instance; }; /* Specializations. */ diff --git a/thirdparty/harfbuzz/upstream/hb-map.hh b/thirdparty/harfbuzz/upstream/hb-map.hh index 6c9fb7e63..fefdbb19d 100644 --- a/thirdparty/harfbuzz/upstream/hb-map.hh +++ b/thirdparty/harfbuzz/upstream/hb-map.hh @@ -47,11 +47,11 @@ struct hb_hashmap_t hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () + void _copy (const hb_hashmap_t& o) { if (unlikely (!o.mask)) return; - if (item_t::is_trivial) + if (hb_is_trivially_copy_assignable (item_t)) { items = (item_t *) hb_malloc (sizeof (item_t) * (o.mask + 1)); if (unlikely (!items)) @@ -70,8 +70,16 @@ struct hb_hashmap_t alloc (o.population); hb_copy (o, *this); } + + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { _copy (o); } + hb_hashmap_t& operator= (const hb_hashmap_t& o) + { + reset (); + if (!items) { _copy (o); return *this; } + alloc (o.population); hb_copy (o, *this); return *this; + } + hb_hashmap_t (hb_hashmap_t&& o) noexcept : hb_hashmap_t () { hb_swap (*this, o); } - hb_hashmap_t& operator= (const hb_hashmap_t& o) { reset (); alloc (o.population); hb_copy (o, *this); return *this; } hb_hashmap_t& operator= (hb_hashmap_t&& o) noexcept { hb_swap (*this, o); return *this; } hb_hashmap_t (std::initializer_list> lst) : hb_hashmap_t () @@ -130,10 +138,7 @@ struct hb_hashmap_t uint32_t total_hash () const { return (hash * 31u) + hb_hash (value); } - static constexpr bool is_trivial = hb_is_trivially_constructible(K) && - hb_is_trivially_destructible(K) && - hb_is_trivially_constructible(V) && - hb_is_trivially_destructible(V); + static constexpr bool is_trivially_constructible = (hb_is_trivially_constructible(K) && hb_is_trivially_constructible(V)); }; hb_object_header_t header; @@ -174,19 +179,19 @@ struct hb_hashmap_t if (likely (items)) { unsigned size = mask + 1; - if (!item_t::is_trivial) - for (unsigned i = 0; i < size; i++) - items[i].~item_t (); + for (unsigned i = 0; i < size; i++) + items[i].~item_t (); hb_free (items); items = nullptr; } population = occupancy = 0; } - void reset () + hb_hashmap_t& reset () { successful = true; clear (); + return *this; } bool in_error () const { return !successful; } @@ -197,7 +202,7 @@ struct hb_hashmap_t if (new_population != 0 && (new_population + new_population / 2) < mask) return true; - unsigned int power = hb_bit_storage (hb_max ((unsigned) population, new_population) * 2 + 8); + unsigned int power = hb_bit_storage (hb_max (hb_max ((unsigned) population, new_population) * 2, 4u)); unsigned int new_size = 1u << power; item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); if (unlikely (!new_items)) @@ -205,7 +210,7 @@ struct hb_hashmap_t successful = false; return false; } - if (!item_t::is_trivial) + if (!item_t::is_trivially_constructible) for (auto &_ : hb_iter (new_items, new_size)) new (&_) item_t (); else @@ -231,9 +236,8 @@ struct hb_hashmap_t std::move (old_items[i].value)); } } - if (!item_t::is_trivial) - for (unsigned int i = 0; i < old_size; i++) - old_items[i].~item_t (); + for (unsigned int i = 0; i < old_size; i++) + old_items[i].~item_t (); hb_free (old_items); @@ -335,7 +339,13 @@ struct hb_hashmap_t bool has (const K &key, VV **vp = nullptr) const { if (!items) return false; - auto *item = fetch_item (key, hb_hash (key)); + return has_with_hash (key, hb_hash (key), vp); + } + template + bool has_with_hash (const K &key, uint32_t hash, VV **vp = nullptr) const + { + if (!items) return false; + auto *item = fetch_item (key, hash); if (item) { if (vp) *vp = std::addressof (item->value); @@ -481,10 +491,17 @@ struct hb_hashmap_t /* Sink interface. */ hb_hashmap_t& operator << (const hb_pair_t& v) { set (v.first, v.second); return *this; } + template hb_hashmap_t& operator << (const hb_pair_t& v) { set (v.first, std::move (v.second)); return *this; } + template hb_hashmap_t& operator << (const hb_pair_t& v) { set (std::move (v.first), v.second); return *this; } + template hb_hashmap_t& operator << (const hb_pair_t& v) { set (std::move (v.first), std::move (v.second)); return *this; } diff --git a/thirdparty/harfbuzz/upstream/hb-mutex.hh b/thirdparty/harfbuzz/upstream/hb-mutex.hh index e329d9864..5942fbea1 100644 --- a/thirdparty/harfbuzz/upstream/hb-mutex.hh +++ b/thirdparty/harfbuzz/upstream/hb-mutex.hh @@ -99,6 +99,8 @@ struct hb_mutex_t hb_mutex_t () { init (); } ~hb_mutex_t () { fini (); } + hb_mutex_t (const hb_mutex_t &) = delete; + hb_mutex_t &operator= (const hb_mutex_t &) = delete; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" @@ -114,6 +116,10 @@ struct hb_lock_t hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); } hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); } ~hb_lock_t () { if (mutex) mutex->unlock (); } + + hb_lock_t (const hb_lock_t &) = delete; + hb_lock_t &operator= (const hb_lock_t &) = delete; + private: hb_mutex_t *mutex; }; diff --git a/thirdparty/harfbuzz/upstream/hb-null.hh b/thirdparty/harfbuzz/upstream/hb-null.hh index 854485d3d..3588f6ab2 100644 --- a/thirdparty/harfbuzz/upstream/hb-null.hh +++ b/thirdparty/harfbuzz/upstream/hb-null.hh @@ -176,7 +176,7 @@ template static inline Type& Crap () { static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); - memcpy (obj, std::addressof (Null (Type)), sizeof (*obj)); + memcpy (reinterpret_cast(obj), std::addressof (Null (Type)), sizeof (*obj)); return *obj; } template diff --git a/thirdparty/harfbuzz/upstream/hb-object.hh b/thirdparty/harfbuzz/upstream/hb-object.hh index 5cffe1666..3fb387978 100644 --- a/thirdparty/harfbuzz/upstream/hb-object.hh +++ b/thirdparty/harfbuzz/upstream/hb-object.hh @@ -142,7 +142,7 @@ struct hb_lockable_set_t struct hb_reference_count_t { - mutable hb_atomic_int_t ref_count; + mutable hb_atomic_t ref_count; void init (int v = 1) { ref_count = v; } int get_relaxed () const { return ref_count; } @@ -213,8 +213,8 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - mutable hb_atomic_int_t writable = 0; - hb_atomic_ptr_t user_data; + mutable hb_atomic_t writable = false; + hb_atomic_t user_data; bool is_inert () const { return !ref_count.get_relaxed (); } }; @@ -272,6 +272,8 @@ static inline void hb_object_make_immutable (const Type *obj) obj->header.writable = false; } template +static inline void hb_object_fini (Type *obj); +template static inline Type *hb_object_reference (Type *obj) { hb_object_trace (obj, HB_FUNC); @@ -282,7 +284,7 @@ static inline Type *hb_object_reference (Type *obj) return obj; } template -static inline bool hb_object_destroy (Type *obj) +static inline bool hb_object_should_destroy (Type *obj) { hb_object_trace (obj, HB_FUNC); if (unlikely (!obj || obj->header.is_inert ())) @@ -290,12 +292,25 @@ static inline bool hb_object_destroy (Type *obj) assert (hb_object_is_valid (obj)); if (obj->header.ref_count.dec () != 1) return false; + return true; +} +template +static inline void hb_object_actually_destroy (Type *obj) +{ hb_object_fini (obj); if (!std::is_trivially_destructible::value) obj->~Type (); +} + +template +static inline bool hb_object_destroy (Type *obj) +{ + if (!hb_object_should_destroy (obj)) + return false; + hb_object_actually_destroy (obj); return true; } template diff --git a/thirdparty/harfbuzz/upstream/hb-open-file.hh b/thirdparty/harfbuzz/upstream/hb-open-file.hh index 6c98226f2..6a53a7eb3 100644 --- a/thirdparty/harfbuzz/upstream/hb-open-file.hh +++ b/thirdparty/harfbuzz/upstream/hb-open-file.hh @@ -465,11 +465,11 @@ struct OpenTypeFontFile Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */ }; - hb_tag_t get_tag () const { return u.tag; } + hb_tag_t get_tag () const { return u.tag.v; } unsigned int get_face_count () const { - switch (u.tag) { + switch (u.tag.v) { case CFFTag: /* All the non-collection tags */ case TrueTag: case Typ1Tag: @@ -483,7 +483,7 @@ struct OpenTypeFontFile { if (base_offset) *base_offset = 0; - switch (u.tag) { + switch (u.tag.v) { /* Note: for non-collection SFNT data we ignore index. This is because * Apple dfont container is a container of SFNT's. So each SFNT is a * non-TTC, but the index is more than zero. */ @@ -512,9 +512,9 @@ struct OpenTypeFontFile bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.tag.sanitize (c))) return_trace (false); + if (unlikely (!u.tag.v.sanitize (c))) return_trace (false); hb_barrier (); - switch (u.tag) { + switch (u.tag.v) { case CFFTag: /* All the non-collection tags */ case TrueTag: case Typ1Tag: @@ -527,13 +527,13 @@ struct OpenTypeFontFile protected: union { - Tag tag; /* 4-byte identifier. */ + struct { Tag v; } tag; /* 4-byte identifier. */ OpenTypeFontFace fontFace; TTCHeader ttcHeader; ResourceForkHeader rfHeader; } u; public: - DEFINE_SIZE_UNION (4, tag); + DEFINE_SIZE_UNION (4, tag.v); }; diff --git a/thirdparty/harfbuzz/upstream/hb-open-type.hh b/thirdparty/harfbuzz/upstream/hb-open-type.hh index 6655259b7..44508e7eb 100644 --- a/thirdparty/harfbuzz/upstream/hb-open-type.hh +++ b/thirdparty/harfbuzz/upstream/hb-open-type.hh @@ -54,53 +54,50 @@ namespace OT { */ /* Integer types in big-endian order and no alignment requirement */ -template -struct IntType +struct NumType { typedef Type type; - - IntType () = default; - explicit constexpr IntType (Type V) : v {V} {} - IntType& operator = (Type i) { v = i; return *this; } /* For reason we define cast out operator for signed/unsigned, instead of Type, see: * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ - operator typename std::conditional::value, signed, unsigned>::type () const { return v; } + typedef typename std::conditional::value && sizeof (Type) <= sizeof(int), + typename std::conditional::value, signed, unsigned>::type, + Type>::type WideType; + + NumType () = default; + explicit constexpr NumType (Type V) : v {V} {} + NumType& operator = (Type V) { v = V; return *this; } + + operator WideType () const { return v; } - bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } - bool operator != (const IntType &o) const { return !(*this == o); } + bool operator == (const NumType &o) const { return (Type) v == (Type) o.v; } + bool operator != (const NumType &o) const { return !(*this == o); } - IntType& operator += (unsigned count) { *this = *this + count; return *this; } - IntType& operator -= (unsigned count) { *this = *this - count; return *this; } - IntType& operator ++ () { *this += 1; return *this; } - IntType& operator -- () { *this -= 1; return *this; } - IntType operator ++ (int) { IntType c (*this); ++*this; return c; } - IntType operator -- (int) { IntType c (*this); --*this; return c; } + NumType& operator += (WideType count) { *this = *this + count; return *this; } + NumType& operator -= (WideType count) { *this = *this - count; return *this; } + NumType& operator ++ () { *this += 1; return *this; } + NumType& operator -- () { *this -= 1; return *this; } + NumType operator ++ (int) { NumType c (*this); ++*this; return c; } + NumType operator -- (int) { NumType c (*this); --*this; return c; } - HB_INTERNAL static int cmp (const IntType *a, const IntType *b) + uint32_t hash () const { return hb_array ((const char *) &v, sizeof (v)).hash (); } + HB_INTERNAL static int cmp (const NumType *a, const NumType *b) { return b->cmp (*a); } HB_INTERNAL static int cmp (const void *a, const void *b) { - IntType *pa = (IntType *) a; - IntType *pb = (IntType *) b; + NumType *pa = (NumType *) a; + NumType *pb = (NumType *) b; return pb->cmp (*pa); } - template ::value && - sizeof (Type2) < sizeof (int) && - sizeof (Type) < sizeof (int))> - int cmp (Type2 a) const - { - Type b = v; - return (int) a - (int) b; - } template int cmp (Type2 a) const { Type b = v; - return a < b ? -1 : a == b ? 0 : +1; + return (a > b) - (a < b); } bool sanitize (hb_sanitize_context_t *c) const { @@ -108,20 +105,36 @@ struct IntType return_trace (c->check_struct (this)); } protected: - BEInt v; + typename std::conditional::value, + HBInt, + HBFloat>::type v; public: DEFINE_SIZE_STATIC (Size); }; -typedef IntType HBUINT8; /* 8-bit unsigned integer. */ -typedef IntType HBINT8; /* 8-bit signed integer. */ -typedef IntType HBUINT16; /* 16-bit unsigned integer. */ -typedef IntType HBINT16; /* 16-bit signed integer. */ -typedef IntType HBUINT32; /* 32-bit unsigned integer. */ -typedef IntType HBINT32; /* 32-bit signed integer. */ +typedef NumType HBUINT8; /* 8-bit big-endian unsigned integer. */ +typedef NumType HBINT8; /* 8-bit big-endian signed integer. */ +typedef NumType HBUINT16; /* 16-bit big-endian unsigned integer. */ +typedef NumType HBINT16; /* 16-bit big-endian signed integer. */ +typedef NumType HBUINT32; /* 32-bit big-endian unsigned integer. */ +typedef NumType HBINT32; /* 32-bit big-endian signed integer. */ +typedef NumType HBUINT64; /* 64-bit big-endian unsigned integer. */ +typedef NumType HBINT64; /* 64-bit big-endian signed integer. */ /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ -typedef IntType HBUINT24; /* 24-bit unsigned integer. */ +typedef NumType HBUINT24; /* 24-bit big-endian unsigned integer. */ + +typedef NumType HBUINT16LE; /* 16-bit little-endian unsigned integer. */ +typedef NumType HBINT16LE; /* 16-bit little-endian signed integer. */ +typedef NumType HBUINT32LE; /* 32-bit little-endian unsigned integer. */ +typedef NumType HBINT32LE; /* 32-bit little-endian signed integer. */ +typedef NumType HBUINT64LE; /* 64-bit little-endian unsigned integer. */ +typedef NumType HBINT64LE; /* 64-bit little-endian signed integer. */ + +typedef NumType HBFLOAT32BE; /* 32-bit little-endian floating point number. */ +typedef NumType HBFLOAT64BE; /* 64-bit little-endian floating point number. */ +typedef NumType HBFLOAT32LE; /* 32-bit little-endian floating point number. */ +typedef NumType HBFLOAT64LE; /* 64-bit little-endian floating point number. */ /* 15-bit unsigned number; top bit used for extension. */ struct HBUINT15 : HBUINT16 @@ -227,7 +240,7 @@ typedef HBUINT16 UFWORD; template struct HBFixed : Type { - static constexpr float shift = (float) (1 << fraction_bits); + static constexpr float mult = 1.f / (1 << fraction_bits); static_assert (Type::static_size * 8 > fraction_bits, ""); operator signed () const = delete; @@ -235,8 +248,8 @@ struct HBFixed : Type explicit operator float () const { return to_float (); } typename Type::type to_int () const { return Type::v; } void set_int (typename Type::type i ) { Type::v = i; } - float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; } - void set_float (float f) { Type::v = roundf (f * shift); } + float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) * mult; } + void set_float (float f) { Type::v = roundf (f / mult); } public: DEFINE_SIZE_STATIC (Type::static_size); }; @@ -299,11 +312,6 @@ typedef Index NameID; struct VarIdx : HBUINT32 { static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, ""); - static uint32_t add (uint32_t i, unsigned short v) - { - if (i == NO_VARIATION) return i; - return i + v; - } VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } }; DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); @@ -518,16 +526,9 @@ struct OffsetTo : Offset return_trace (sanitize_shallow (c, base) && hb_barrier () && (this->is_null () || - c->dispatch (StructAtOffset (base, *this), std::forward (ds)...) || - neuter (c))); + c->dispatch (StructAtOffset (base, *this), std::forward (ds)...))); } - /* Set the offset to Null */ - bool neuter (hb_sanitize_context_t *c) const - { - if (!has_null) return false; - return c->try_set (this, 0); - } DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; /* Partial specializations. */ @@ -1274,11 +1275,22 @@ struct CFFIndex if (unlikely (!serialize_header (c, +it, data_size, min_off_size))) return_trace (false); unsigned char *ret = c->allocate_size (data_size, false); if (unlikely (!ret)) return_trace (false); + unsigned remaining = data_size; for (const auto &_ : +it) { unsigned len = _.length; + if (!len) continue; + + if (unlikely (len > remaining)) { + // We have more bytes to write then the computed data size, so the size calculation + // must have encountered overflow. + return_trace (c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + + remaining -= len; + if (len <= 1) { *ret++ = *_.arrayZ; @@ -1495,8 +1507,8 @@ struct TupleValues VALUE_RUN_COUNT_MASK = 0x3F }; - static unsigned compile (hb_array_t values, /* IN */ - hb_array_t encoded_bytes /* OUT */) + static unsigned compile_unsafe (hb_array_t values, /* IN */ + unsigned char *encoded_bytes /* OUT */) { unsigned num_values = values.length; unsigned encoded_len = 0; @@ -1505,24 +1517,23 @@ struct TupleValues { int val = values.arrayZ[i]; if (val == 0) - encoded_len += encode_value_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), values); - else if (val >= -128 && val <= 127) - encoded_len += encode_value_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), values); - else if (val >= -32768 && val <= 32767) - encoded_len += encode_value_run_as_words (i, encoded_bytes.sub_array (encoded_len), values); + encoded_len += encode_value_run_as_zeroes (i, encoded_bytes + encoded_len, values); + else if ((int8_t) val == val) + encoded_len += encode_value_run_as_bytes (i, encoded_bytes + encoded_len, values); + else if ((int16_t) val == val) + encoded_len += encode_value_run_as_words (i, encoded_bytes + encoded_len, values); else - encoded_len += encode_value_run_as_longs (i, encoded_bytes.sub_array (encoded_len), values); + encoded_len += encode_value_run_as_longs (i, encoded_bytes + encoded_len, values); } return encoded_len; } static unsigned encode_value_run_as_zeroes (unsigned& i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned num_values = values.length; unsigned run_length = 0; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (i < num_values && values.arrayZ[i] == 0) { @@ -1546,7 +1557,7 @@ struct TupleValues } static unsigned encode_value_run_as_bytes (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1554,7 +1565,7 @@ struct TupleValues while (i < num_values) { int val = values.arrayZ[i]; - if (val > 127 || val < -128) + if ((int8_t) val != val) break; /* from fonttools: if there're 2 or more zeros in a sequence, @@ -1567,7 +1578,6 @@ struct TupleValues unsigned run_length = i - start; unsigned encoded_len = 0; - auto it = encoded_bytes.iter (); while (run_length >= 64) { @@ -1575,10 +1585,9 @@ struct TupleValues encoded_len++; for (unsigned j = 0; j < 64; j++) - { - *it++ = static_cast (values.arrayZ[start + j]); - encoded_len++; - } + it[j] = static_cast (values.arrayZ[start + j]); + it += 64; + encoded_len += 64; start += 64; run_length -= 64; @@ -1589,18 +1598,16 @@ struct TupleValues *it++ = (VALUES_ARE_BYTES | (run_length - 1)); encoded_len++; - while (start < i) - { - *it++ = static_cast (values.arrayZ[start++]); - encoded_len++; - } + for (unsigned j = 0; j < run_length; j++) + it[j] = static_cast (values.arrayZ[start + j]); + encoded_len += run_length; } return encoded_len; } static unsigned encode_value_run_as_words (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1609,22 +1616,24 @@ struct TupleValues { int val = values.arrayZ[i]; - /* start a new run for a single zero value*/ + if ((int16_t) val != val) + break; + + /* start a new run for a single zero value. */ if (val == 0) break; - /* from fonttools: continue word-encoded run if there's only one + /* From fonttools: continue word-encoded run if there's only one * single value in the range [-128, 127] because it is more compact. * Only start a new run when there're 2 continuous such values. */ - if (val >= -128 && val <= 127 && + if ((int8_t) val == val && i + 1 < num_values && - values.arrayZ[i+1] >= -128 && values.arrayZ[i+1] <= 127) + (int8_t) values.arrayZ[i+1] == values.arrayZ[i+1]) break; i++; } unsigned run_length = i - start; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (run_length >= 64) { @@ -1661,7 +1670,7 @@ struct TupleValues } static unsigned encode_value_run_as_longs (unsigned &i, - hb_array_t encoded_bytes, + unsigned char *it, hb_array_t values) { unsigned start = i; @@ -1670,14 +1679,13 @@ struct TupleValues { int val = values.arrayZ[i]; - if (val >= -32768 && val <= 32767) + if ((int16_t) val == val) break; i++; } unsigned run_length = i - start; - auto it = encoded_bytes.iter (); unsigned encoded_len = 0; while (run_length >= 64) { @@ -1718,10 +1726,14 @@ struct TupleValues } template +#ifndef HB_OPTIMIZE_SIZE + HB_ALWAYS_INLINE +#endif static bool decompile (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &values /* IN/OUT */, const HBUINT8 *end, - bool consume_all = false) + bool consume_all = false, + unsigned start = 0) { unsigned i = 0; unsigned count = consume_all ? UINT_MAX : values.length; @@ -1734,19 +1746,37 @@ struct TupleValues unsigned run_count = (control & VALUE_RUN_COUNT_MASK) + 1; if (consume_all) { - if (unlikely (!values.resize (values.length + run_count, false))) + if (unlikely (!values.resize_dirty (values.length + run_count))) return false; } unsigned stop = i + run_count; if (unlikely (stop > count)) return false; + + unsigned skip = i < start ? hb_min (start - i, run_count) : 0; + i += skip; + if ((control & VALUES_SIZE_MASK) == VALUES_ARE_ZEROS) { - for (; i < stop; i++) - values.arrayZ[i] = 0; + hb_memset (&values.arrayZ[i], 0, (stop - i) * sizeof (T)); + i = stop; } else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_WORDS) { if (unlikely (p + run_count * HBINT16::static_size > end)) return false; + p += skip * HBINT16::static_size; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 1] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 2] = * (const HBINT16 *) p; + p += HBINT16::static_size; + values.arrayZ[i + 3] = * (const HBINT16 *) p; + p += HBINT16::static_size; + } +#endif for (; i < stop; i++) { values.arrayZ[i] = * (const HBINT16 *) p; @@ -1756,6 +1786,7 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_LONGS) { if (unlikely (p + run_count * HBINT32::static_size > end)) return false; + p += skip * HBINT32::static_size; for (; i < stop; i++) { values.arrayZ[i] = * (const HBINT32 *) p; @@ -1765,10 +1796,18 @@ struct TupleValues else if ((control & VALUES_SIZE_MASK) == VALUES_ARE_BYTES) { if (unlikely (p + run_count > end)) return false; + p += skip * HBINT8::static_size; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < stop; i += 4) + { + values.arrayZ[i] = * (const HBINT8 *) p++; + values.arrayZ[i + 1] = * (const HBINT8 *) p++; + values.arrayZ[i + 2] = * (const HBINT8 *) p++; + values.arrayZ[i + 3] = * (const HBINT8 *) p++; + } +#endif for (; i < stop; i++) - { values.arrayZ[i] = * (const HBINT8 *) p++; - } } } return true; @@ -1777,21 +1816,25 @@ struct TupleValues struct iter_t : hb_iter_with_fallback_t { iter_t (const unsigned char *p_, unsigned len_) - : p (p_), end (p_ + len_) - { if (ensure_run ()) read_value (); } + : p (p_), endp (p_ + len_) + { if (likely (ensure_run ())) read_value (); } private: const unsigned char *p; - const unsigned char * const end; + const unsigned char * const endp; int current_value = 0; signed run_count = 0; unsigned width = 0; + HB_ALWAYS_INLINE bool ensure_run () { if (likely (run_count > 0)) return true; - - if (unlikely (p >= end)) + return _ensure_run (); + } + bool _ensure_run () + { + if (unlikely (p >= endp)) { run_count = 0; current_value = 0; @@ -1810,7 +1853,7 @@ struct TupleValues default: assert (false); } - if (unlikely (p + run_count * width > end)) + if (unlikely (p + run_count * width > endp)) { run_count = 0; current_value = 0; @@ -1837,7 +1880,7 @@ struct TupleValues __item_t__ __item__ () const { return current_value; } - bool __more__ () const { return run_count || p < end; } + bool __more__ () const { return run_count || p < endp; } void __next__ () { run_count--; @@ -1864,10 +1907,158 @@ struct TupleValues { return p != o.p || run_count != o.run_count; } iter_t __end__ () const { - iter_t it (end, 0); + iter_t it (endp, 0); return it; } }; + + struct fetcher_t + { + fetcher_t (const unsigned char *p_, unsigned len_) + : p (p_), end (p_ + len_) {} + + private: + const unsigned char *p; + const unsigned char * const end; + signed run_count = 0; + unsigned width = 0; + + HB_ALWAYS_INLINE + bool ensure_run () + { + if (likely (run_count > 0)) return true; + return _ensure_run (); + } + + bool _ensure_run () + { + if (unlikely (p >= end)) + { + run_count = 0; + return false; + } + + unsigned control = *p++; + run_count = (control & VALUE_RUN_COUNT_MASK) + 1; + width = control & VALUES_SIZE_MASK; + switch (width) + { + case VALUES_ARE_ZEROS: width = 0; break; + case VALUES_ARE_BYTES: width = HBINT8::static_size; break; + case VALUES_ARE_WORDS: width = HBINT16::static_size; break; + case VALUES_ARE_LONGS: width = HBINT32::static_size; break; + default: assert (false); + } + + if (unlikely (p + run_count * width > end)) + { + run_count = 0; + return false; + } + + return true; + } + + public: + void skip (unsigned n) + { + while (n) + { + if (unlikely (!ensure_run ())) + return; + unsigned i = hb_min (n, (unsigned) run_count); + run_count -= i; + n -= i; + p += i * width; + } + } + + private: + template + void _add_to (hb_array_t out, float scale = 1.0f) + { + unsigned n = out.length; + float *arrayZ = out.arrayZ; + + for (unsigned i = 0; i < n;) + { + if (unlikely (!ensure_run ())) + break; + unsigned count = hb_min (n - i, (unsigned) run_count); + switch (width) + { + case 0: + { + arrayZ += count; + break; + } + case 1: + { + const auto *pp = (const HBINT8 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; + } + break; + case 2: + { + const auto *pp = (const HBINT16 *) p; + unsigned j = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; j + 3 < count; j += 4) + { + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + } +#endif + for (; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; + } + break; + case 4: + { + const auto *pp = (const HBINT32 *) p; + for (unsigned j = 0; j < count; j++) + *arrayZ++ += scaled ? *pp++ * scale : *pp++; + + p = (const unsigned char *) pp; + } + break; + } + run_count -= count; + i += count; + } + } + + public: + void add_to (hb_array_t out, float scale = 1.0f) + { +#ifndef HB_OPTIMIZE_SIZE + // The following branch is supposed to speed things up by avoiding + // the multiplication in _add_to<> if scale is 1.0f. + // But in practice it seems to bloat the code and slow things down. + if (false && scale == 1.0f) + _add_to (out); + else +#endif + _add_to (out, scale); + } + }; }; struct TupleList : CFF2Index @@ -1877,9 +2068,32 @@ struct TupleList : CFF2Index auto bytes = CFF2Index::operator [] (i); return TupleValues::iter_t (bytes.arrayZ, bytes.length); } + + TupleValues::fetcher_t fetcher (unsigned i) const + { + auto bytes = CFF2Index::operator [] (i); + return TupleValues::fetcher_t (bytes.arrayZ, bytes.length); + } +}; + + +// Alignment + +template +struct Align +{ + unsigned get_size (const void *base) const + { + unsigned offset = (const char *) this - (const char *) base; + return (alignment - offset) & (alignment - 1); + } + + public: + DEFINE_SIZE_MIN (0); }; + } /* namespace OT */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cff-common.hh b/thirdparty/harfbuzz/upstream/hb-ot-cff-common.hh index b49c0be51..4308a7344 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-cff-common.hh @@ -79,7 +79,7 @@ struct Dict : UnsizedByteStr { TRACE_SERIALIZE (this); for (unsigned int i = 0; i < dictval.get_count (); i++) - if (unlikely (!opszr.serialize (c, dictval[i], std::forward (ds)...))) + if (unlikely (!opszr.serialize (c, dictval[i], ds...))) return_trace (false); return_trace (true); diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cff1-std-str.hh b/thirdparty/harfbuzz/upstream/hb-ot-cff1-std-str.hh index 65d56ae18..bf56abb97 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cff1-std-str.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-cff1-std-str.hh @@ -30,396 +30,396 @@ #include "hb.hh" #endif -_S(".notdef") -_S("space") -_S("exclam") -_S("quotedbl") -_S("numbersign") -_S("dollar") -_S("percent") -_S("ampersand") -_S("quoteright") -_S("parenleft") -_S("parenright") -_S("asterisk") -_S("plus") -_S("comma") -_S("hyphen") -_S("period") -_S("slash") -_S("zero") -_S("one") -_S("two") -_S("three") -_S("four") -_S("five") -_S("six") -_S("seven") -_S("eight") -_S("nine") -_S("colon") -_S("semicolon") -_S("less") -_S("equal") -_S("greater") -_S("question") -_S("at") -_S("A") -_S("B") -_S("C") -_S("D") -_S("E") -_S("F") -_S("G") -_S("H") -_S("I") -_S("J") -_S("K") -_S("L") -_S("M") -_S("N") -_S("O") -_S("P") -_S("Q") -_S("R") -_S("S") -_S("T") -_S("U") -_S("V") -_S("W") -_S("X") -_S("Y") -_S("Z") -_S("bracketleft") -_S("backslash") -_S("bracketright") -_S("asciicircum") -_S("underscore") -_S("quoteleft") -_S("a") -_S("b") -_S("c") -_S("d") -_S("e") -_S("f") -_S("g") -_S("h") -_S("i") -_S("j") -_S("k") -_S("l") -_S("m") -_S("n") -_S("o") -_S("p") -_S("q") -_S("r") -_S("s") -_S("t") -_S("u") -_S("v") -_S("w") -_S("x") -_S("y") -_S("z") -_S("braceleft") -_S("bar") -_S("braceright") -_S("asciitilde") -_S("exclamdown") -_S("cent") -_S("sterling") -_S("fraction") -_S("yen") -_S("florin") -_S("section") -_S("currency") -_S("quotesingle") -_S("quotedblleft") -_S("guillemotleft") -_S("guilsinglleft") -_S("guilsinglright") -_S("fi") -_S("fl") -_S("endash") -_S("dagger") -_S("daggerdbl") -_S("periodcentered") -_S("paragraph") -_S("bullet") -_S("quotesinglbase") -_S("quotedblbase") -_S("quotedblright") -_S("guillemotright") -_S("ellipsis") -_S("perthousand") -_S("questiondown") -_S("grave") -_S("acute") -_S("circumflex") -_S("tilde") -_S("macron") -_S("breve") -_S("dotaccent") -_S("dieresis") -_S("ring") -_S("cedilla") -_S("hungarumlaut") -_S("ogonek") -_S("caron") -_S("emdash") -_S("AE") -_S("ordfeminine") -_S("Lslash") -_S("Oslash") -_S("OE") -_S("ordmasculine") -_S("ae") -_S("dotlessi") -_S("lslash") -_S("oslash") -_S("oe") -_S("germandbls") -_S("onesuperior") -_S("logicalnot") -_S("mu") -_S("trademark") -_S("Eth") -_S("onehalf") -_S("plusminus") -_S("Thorn") -_S("onequarter") -_S("divide") -_S("brokenbar") -_S("degree") -_S("thorn") -_S("threequarters") -_S("twosuperior") -_S("registered") -_S("minus") -_S("eth") -_S("multiply") -_S("threesuperior") -_S("copyright") -_S("Aacute") -_S("Acircumflex") -_S("Adieresis") -_S("Agrave") -_S("Aring") -_S("Atilde") -_S("Ccedilla") -_S("Eacute") -_S("Ecircumflex") -_S("Edieresis") -_S("Egrave") -_S("Iacute") -_S("Icircumflex") -_S("Idieresis") -_S("Igrave") -_S("Ntilde") -_S("Oacute") -_S("Ocircumflex") -_S("Odieresis") -_S("Ograve") -_S("Otilde") -_S("Scaron") -_S("Uacute") -_S("Ucircumflex") -_S("Udieresis") -_S("Ugrave") -_S("Yacute") -_S("Ydieresis") -_S("Zcaron") -_S("aacute") -_S("acircumflex") -_S("adieresis") -_S("agrave") -_S("aring") -_S("atilde") -_S("ccedilla") -_S("eacute") -_S("ecircumflex") -_S("edieresis") -_S("egrave") -_S("iacute") -_S("icircumflex") -_S("idieresis") -_S("igrave") -_S("ntilde") -_S("oacute") -_S("ocircumflex") -_S("odieresis") -_S("ograve") -_S("otilde") -_S("scaron") -_S("uacute") -_S("ucircumflex") -_S("udieresis") -_S("ugrave") -_S("yacute") -_S("ydieresis") -_S("zcaron") -_S("exclamsmall") -_S("Hungarumlautsmall") -_S("dollaroldstyle") -_S("dollarsuperior") -_S("ampersandsmall") -_S("Acutesmall") -_S("parenleftsuperior") -_S("parenrightsuperior") -_S("twodotenleader") -_S("onedotenleader") -_S("zerooldstyle") -_S("oneoldstyle") -_S("twooldstyle") -_S("threeoldstyle") -_S("fouroldstyle") -_S("fiveoldstyle") -_S("sixoldstyle") -_S("sevenoldstyle") -_S("eightoldstyle") -_S("nineoldstyle") -_S("commasuperior") -_S("threequartersemdash") -_S("periodsuperior") -_S("questionsmall") -_S("asuperior") -_S("bsuperior") -_S("centsuperior") -_S("dsuperior") -_S("esuperior") -_S("isuperior") -_S("lsuperior") -_S("msuperior") -_S("nsuperior") -_S("osuperior") -_S("rsuperior") -_S("ssuperior") -_S("tsuperior") -_S("ff") -_S("ffi") -_S("ffl") -_S("parenleftinferior") -_S("parenrightinferior") -_S("Circumflexsmall") -_S("hyphensuperior") -_S("Gravesmall") -_S("Asmall") -_S("Bsmall") -_S("Csmall") -_S("Dsmall") -_S("Esmall") -_S("Fsmall") -_S("Gsmall") -_S("Hsmall") -_S("Ismall") -_S("Jsmall") -_S("Ksmall") -_S("Lsmall") -_S("Msmall") -_S("Nsmall") -_S("Osmall") -_S("Psmall") -_S("Qsmall") -_S("Rsmall") -_S("Ssmall") -_S("Tsmall") -_S("Usmall") -_S("Vsmall") -_S("Wsmall") -_S("Xsmall") -_S("Ysmall") -_S("Zsmall") -_S("colonmonetary") -_S("onefitted") -_S("rupiah") -_S("Tildesmall") -_S("exclamdownsmall") -_S("centoldstyle") -_S("Lslashsmall") -_S("Scaronsmall") -_S("Zcaronsmall") -_S("Dieresissmall") -_S("Brevesmall") -_S("Caronsmall") -_S("Dotaccentsmall") -_S("Macronsmall") -_S("figuredash") -_S("hypheninferior") -_S("Ogoneksmall") -_S("Ringsmall") -_S("Cedillasmall") -_S("questiondownsmall") -_S("oneeighth") -_S("threeeighths") -_S("fiveeighths") -_S("seveneighths") -_S("onethird") -_S("twothirds") -_S("zerosuperior") -_S("foursuperior") -_S("fivesuperior") -_S("sixsuperior") -_S("sevensuperior") -_S("eightsuperior") -_S("ninesuperior") -_S("zeroinferior") -_S("oneinferior") -_S("twoinferior") -_S("threeinferior") -_S("fourinferior") -_S("fiveinferior") -_S("sixinferior") -_S("seveninferior") -_S("eightinferior") -_S("nineinferior") -_S("centinferior") -_S("dollarinferior") -_S("periodinferior") -_S("commainferior") -_S("Agravesmall") -_S("Aacutesmall") -_S("Acircumflexsmall") -_S("Atildesmall") -_S("Adieresissmall") -_S("Aringsmall") -_S("AEsmall") -_S("Ccedillasmall") -_S("Egravesmall") -_S("Eacutesmall") -_S("Ecircumflexsmall") -_S("Edieresissmall") -_S("Igravesmall") -_S("Iacutesmall") -_S("Icircumflexsmall") -_S("Idieresissmall") -_S("Ethsmall") -_S("Ntildesmall") -_S("Ogravesmall") -_S("Oacutesmall") -_S("Ocircumflexsmall") -_S("Otildesmall") -_S("Odieresissmall") -_S("OEsmall") -_S("Oslashsmall") -_S("Ugravesmall") -_S("Uacutesmall") -_S("Ucircumflexsmall") -_S("Udieresissmall") -_S("Yacutesmall") -_S("Thornsmall") -_S("Ydieresissmall") -_S("001.000") -_S("001.001") -_S("001.002") -_S("001.003") -_S("Black") -_S("Bold") -_S("Book") -_S("Light") -_S("Medium") -_S("Regular") -_S("Roman") -_S("Semibold") +HB_STR(".notdef") +HB_STR("space") +HB_STR("exclam") +HB_STR("quotedbl") +HB_STR("numbersign") +HB_STR("dollar") +HB_STR("percent") +HB_STR("ampersand") +HB_STR("quoteright") +HB_STR("parenleft") +HB_STR("parenright") +HB_STR("asterisk") +HB_STR("plus") +HB_STR("comma") +HB_STR("hyphen") +HB_STR("period") +HB_STR("slash") +HB_STR("zero") +HB_STR("one") +HB_STR("two") +HB_STR("three") +HB_STR("four") +HB_STR("five") +HB_STR("six") +HB_STR("seven") +HB_STR("eight") +HB_STR("nine") +HB_STR("colon") +HB_STR("semicolon") +HB_STR("less") +HB_STR("equal") +HB_STR("greater") +HB_STR("question") +HB_STR("at") +HB_STR("A") +HB_STR("B") +HB_STR("C") +HB_STR("D") +HB_STR("E") +HB_STR("F") +HB_STR("G") +HB_STR("H") +HB_STR("I") +HB_STR("J") +HB_STR("K") +HB_STR("L") +HB_STR("M") +HB_STR("N") +HB_STR("O") +HB_STR("P") +HB_STR("Q") +HB_STR("R") +HB_STR("S") +HB_STR("T") +HB_STR("U") +HB_STR("V") +HB_STR("W") +HB_STR("X") +HB_STR("Y") +HB_STR("Z") +HB_STR("bracketleft") +HB_STR("backslash") +HB_STR("bracketright") +HB_STR("asciicircum") +HB_STR("underscore") +HB_STR("quoteleft") +HB_STR("a") +HB_STR("b") +HB_STR("c") +HB_STR("d") +HB_STR("e") +HB_STR("f") +HB_STR("g") +HB_STR("h") +HB_STR("i") +HB_STR("j") +HB_STR("k") +HB_STR("l") +HB_STR("m") +HB_STR("n") +HB_STR("o") +HB_STR("p") +HB_STR("q") +HB_STR("r") +HB_STR("s") +HB_STR("t") +HB_STR("u") +HB_STR("v") +HB_STR("w") +HB_STR("x") +HB_STR("y") +HB_STR("z") +HB_STR("braceleft") +HB_STR("bar") +HB_STR("braceright") +HB_STR("asciitilde") +HB_STR("exclamdown") +HB_STR("cent") +HB_STR("sterling") +HB_STR("fraction") +HB_STR("yen") +HB_STR("florin") +HB_STR("section") +HB_STR("currency") +HB_STR("quotesingle") +HB_STR("quotedblleft") +HB_STR("guillemotleft") +HB_STR("guilsinglleft") +HB_STR("guilsinglright") +HB_STR("fi") +HB_STR("fl") +HB_STR("endash") +HB_STR("dagger") +HB_STR("daggerdbl") +HB_STR("periodcentered") +HB_STR("paragraph") +HB_STR("bullet") +HB_STR("quotesinglbase") +HB_STR("quotedblbase") +HB_STR("quotedblright") +HB_STR("guillemotright") +HB_STR("ellipsis") +HB_STR("perthousand") +HB_STR("questiondown") +HB_STR("grave") +HB_STR("acute") +HB_STR("circumflex") +HB_STR("tilde") +HB_STR("macron") +HB_STR("breve") +HB_STR("dotaccent") +HB_STR("dieresis") +HB_STR("ring") +HB_STR("cedilla") +HB_STR("hungarumlaut") +HB_STR("ogonek") +HB_STR("caron") +HB_STR("emdash") +HB_STR("AE") +HB_STR("ordfeminine") +HB_STR("Lslash") +HB_STR("Oslash") +HB_STR("OE") +HB_STR("ordmasculine") +HB_STR("ae") +HB_STR("dotlessi") +HB_STR("lslash") +HB_STR("oslash") +HB_STR("oe") +HB_STR("germandbls") +HB_STR("onesuperior") +HB_STR("logicalnot") +HB_STR("mu") +HB_STR("trademark") +HB_STR("Eth") +HB_STR("onehalf") +HB_STR("plusminus") +HB_STR("Thorn") +HB_STR("onequarter") +HB_STR("divide") +HB_STR("brokenbar") +HB_STR("degree") +HB_STR("thorn") +HB_STR("threequarters") +HB_STR("twosuperior") +HB_STR("registered") +HB_STR("minus") +HB_STR("eth") +HB_STR("multiply") +HB_STR("threesuperior") +HB_STR("copyright") +HB_STR("Aacute") +HB_STR("Acircumflex") +HB_STR("Adieresis") +HB_STR("Agrave") +HB_STR("Aring") +HB_STR("Atilde") +HB_STR("Ccedilla") +HB_STR("Eacute") +HB_STR("Ecircumflex") +HB_STR("Edieresis") +HB_STR("Egrave") +HB_STR("Iacute") +HB_STR("Icircumflex") +HB_STR("Idieresis") +HB_STR("Igrave") +HB_STR("Ntilde") +HB_STR("Oacute") +HB_STR("Ocircumflex") +HB_STR("Odieresis") +HB_STR("Ograve") +HB_STR("Otilde") +HB_STR("Scaron") +HB_STR("Uacute") +HB_STR("Ucircumflex") +HB_STR("Udieresis") +HB_STR("Ugrave") +HB_STR("Yacute") +HB_STR("Ydieresis") +HB_STR("Zcaron") +HB_STR("aacute") +HB_STR("acircumflex") +HB_STR("adieresis") +HB_STR("agrave") +HB_STR("aring") +HB_STR("atilde") +HB_STR("ccedilla") +HB_STR("eacute") +HB_STR("ecircumflex") +HB_STR("edieresis") +HB_STR("egrave") +HB_STR("iacute") +HB_STR("icircumflex") +HB_STR("idieresis") +HB_STR("igrave") +HB_STR("ntilde") +HB_STR("oacute") +HB_STR("ocircumflex") +HB_STR("odieresis") +HB_STR("ograve") +HB_STR("otilde") +HB_STR("scaron") +HB_STR("uacute") +HB_STR("ucircumflex") +HB_STR("udieresis") +HB_STR("ugrave") +HB_STR("yacute") +HB_STR("ydieresis") +HB_STR("zcaron") +HB_STR("exclamsmall") +HB_STR("Hungarumlautsmall") +HB_STR("dollaroldstyle") +HB_STR("dollarsuperior") +HB_STR("ampersandsmall") +HB_STR("Acutesmall") +HB_STR("parenleftsuperior") +HB_STR("parenrightsuperior") +HB_STR("twodotenleader") +HB_STR("onedotenleader") +HB_STR("zerooldstyle") +HB_STR("oneoldstyle") +HB_STR("twooldstyle") +HB_STR("threeoldstyle") +HB_STR("fouroldstyle") +HB_STR("fiveoldstyle") +HB_STR("sixoldstyle") +HB_STR("sevenoldstyle") +HB_STR("eightoldstyle") +HB_STR("nineoldstyle") +HB_STR("commasuperior") +HB_STR("threequartersemdash") +HB_STR("periodsuperior") +HB_STR("questionsmall") +HB_STR("asuperior") +HB_STR("bsuperior") +HB_STR("centsuperior") +HB_STR("dsuperior") +HB_STR("esuperior") +HB_STR("isuperior") +HB_STR("lsuperior") +HB_STR("msuperior") +HB_STR("nsuperior") +HB_STR("osuperior") +HB_STR("rsuperior") +HB_STR("ssuperior") +HB_STR("tsuperior") +HB_STR("ff") +HB_STR("ffi") +HB_STR("ffl") +HB_STR("parenleftinferior") +HB_STR("parenrightinferior") +HB_STR("Circumflexsmall") +HB_STR("hyphensuperior") +HB_STR("Gravesmall") +HB_STR("Asmall") +HB_STR("Bsmall") +HB_STR("Csmall") +HB_STR("Dsmall") +HB_STR("Esmall") +HB_STR("Fsmall") +HB_STR("Gsmall") +HB_STR("Hsmall") +HB_STR("Ismall") +HB_STR("Jsmall") +HB_STR("Ksmall") +HB_STR("Lsmall") +HB_STR("Msmall") +HB_STR("Nsmall") +HB_STR("Osmall") +HB_STR("Psmall") +HB_STR("Qsmall") +HB_STR("Rsmall") +HB_STR("Ssmall") +HB_STR("Tsmall") +HB_STR("Usmall") +HB_STR("Vsmall") +HB_STR("Wsmall") +HB_STR("Xsmall") +HB_STR("Ysmall") +HB_STR("Zsmall") +HB_STR("colonmonetary") +HB_STR("onefitted") +HB_STR("rupiah") +HB_STR("Tildesmall") +HB_STR("exclamdownsmall") +HB_STR("centoldstyle") +HB_STR("Lslashsmall") +HB_STR("Scaronsmall") +HB_STR("Zcaronsmall") +HB_STR("Dieresissmall") +HB_STR("Brevesmall") +HB_STR("Caronsmall") +HB_STR("Dotaccentsmall") +HB_STR("Macronsmall") +HB_STR("figuredash") +HB_STR("hypheninferior") +HB_STR("Ogoneksmall") +HB_STR("Ringsmall") +HB_STR("Cedillasmall") +HB_STR("questiondownsmall") +HB_STR("oneeighth") +HB_STR("threeeighths") +HB_STR("fiveeighths") +HB_STR("seveneighths") +HB_STR("onethird") +HB_STR("twothirds") +HB_STR("zerosuperior") +HB_STR("foursuperior") +HB_STR("fivesuperior") +HB_STR("sixsuperior") +HB_STR("sevensuperior") +HB_STR("eightsuperior") +HB_STR("ninesuperior") +HB_STR("zeroinferior") +HB_STR("oneinferior") +HB_STR("twoinferior") +HB_STR("threeinferior") +HB_STR("fourinferior") +HB_STR("fiveinferior") +HB_STR("sixinferior") +HB_STR("seveninferior") +HB_STR("eightinferior") +HB_STR("nineinferior") +HB_STR("centinferior") +HB_STR("dollarinferior") +HB_STR("periodinferior") +HB_STR("commainferior") +HB_STR("Agravesmall") +HB_STR("Aacutesmall") +HB_STR("Acircumflexsmall") +HB_STR("Atildesmall") +HB_STR("Adieresissmall") +HB_STR("Aringsmall") +HB_STR("AEsmall") +HB_STR("Ccedillasmall") +HB_STR("Egravesmall") +HB_STR("Eacutesmall") +HB_STR("Ecircumflexsmall") +HB_STR("Edieresissmall") +HB_STR("Igravesmall") +HB_STR("Iacutesmall") +HB_STR("Icircumflexsmall") +HB_STR("Idieresissmall") +HB_STR("Ethsmall") +HB_STR("Ntildesmall") +HB_STR("Ogravesmall") +HB_STR("Oacutesmall") +HB_STR("Ocircumflexsmall") +HB_STR("Otildesmall") +HB_STR("Odieresissmall") +HB_STR("OEsmall") +HB_STR("Oslashsmall") +HB_STR("Ugravesmall") +HB_STR("Uacutesmall") +HB_STR("Ucircumflexsmall") +HB_STR("Udieresissmall") +HB_STR("Yacutesmall") +HB_STR("Thornsmall") +HB_STR("Ydieresissmall") +HB_STR("001.000") +HB_STR("001.001") +HB_STR("001.002") +HB_STR("001.003") +HB_STR("Black") +HB_STR("Bold") +HB_STR("Book") +HB_STR("Light") +HB_STR("Medium") +HB_STR("Regular") +HB_STR("Roman") +HB_STR("Semibold") #endif /* HB_OT_CFF1_STD_STR_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.cc b/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.cc index 66df28aae..8b666a3d0 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.cc @@ -553,15 +553,6 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin return true; } -bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const { #ifdef HB_NO_OT_FONT_CFF diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.hh index b84d896e3..66c375b2c 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-cff1-table.hh @@ -326,7 +326,7 @@ struct Charset0 void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { - mapping->resize (num_glyphs, false); + mapping->resize_dirty (num_glyphs); for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++) mapping->arrayZ[gid] = {sids[gid - 1], gid}; } @@ -426,7 +426,7 @@ struct Charset1_2 { void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const { - mapping->resize (num_glyphs, false); + mapping->resize_dirty (num_glyphs); hb_codepoint_t gid = 1; if (gid >= num_glyphs) return; @@ -1073,7 +1073,7 @@ struct cff1 this->blob = sc.reference_table (face); - /* setup for run-time santization */ + /* setup for run-time sanitization */ sc.init (this->blob); sc.start_processing (); @@ -1176,7 +1176,8 @@ struct cff1 if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (unlikely (font->privateDictInfo.size && + privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); priv->init (); @@ -1191,7 +1192,8 @@ struct cff1 PRIVDICTVAL *priv = &privateDicts[0]; const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (font->privateDictInfo.size && + unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; num_interp_env_t env (privDictStr); dict_interpreter_t priv_interp (env); priv->init (); @@ -1462,7 +1464,6 @@ struct cff1 } HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; private: @@ -1484,7 +1485,7 @@ struct cff1 int cmp (const gname_t &a) const { return cmp (&a, this); } }; - mutable hb_atomic_ptr_t> glyph_names; + mutable hb_atomic_t *> glyph_names; typedef accelerator_templ_t SUPER; }; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.cc b/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.cc index e42217b4e..bec1397ed 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.cc @@ -102,6 +102,14 @@ struct cff2_cs_opset_extents_t : cff2_cs_opset_tcoords, font->num_coords)); +} + +bool OT::cff2::accelerator_t::get_extents_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_array_t coords) const { #ifdef HB_NO_OT_FONT_CFF /* XXX Remove check when this code moves to .hh file. */ @@ -112,7 +120,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, unsigned int fd = fdSelect->get_fd (glyph); const hb_ubytes_t str = (*charStrings)[glyph]; - cff2_cs_interp_env_t env (str, *this, fd, font->coords, font->num_coords); + cff2_cs_interp_env_t env (str, *this, fd, coords.arrayZ, coords.length); cff2_cs_interpreter_t interp (env); cff2_extents_param_t param; if (unlikely (!interp.interpret (param))) return false; @@ -143,15 +151,6 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, return true; } -bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const -{ - funcs->push_clip_glyph (data, glyph, font); - funcs->color (data, true, foreground); - funcs->pop_clip (data); - - return true; -} - struct cff2_path_param_t { cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_) @@ -203,7 +202,11 @@ struct cff2_cs_opset_path_t : cff2_cs_opset_tcoords, font->num_coords)); + return get_path_at (font, + glyph, + draw_session, + hb_array (font->coords, + font->has_nonzero_coords ? font->num_coords : 0)); } bool OT::cff2::accelerator_t::get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.hh index c52c0511c..490077a67 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-cff2-table.hh @@ -405,7 +405,7 @@ struct cff2 this->blob = sc.reference_table (face); - /* setup for run-time santization */ + /* setup for run-time sanitization */ sc.init (this->blob); sc.start_processing (); @@ -458,7 +458,8 @@ struct cff2 if (unlikely (!font_interp.interpret (*font))) goto fail; const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff2, font->privateDictInfo.offset, sc, font->privateDictInfo.size).as_ubytes (font->privateDictInfo.size); - if (unlikely (privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; + if (unlikely (font->privateDictInfo.size && + privDictStr == (const unsigned char *) &Null (UnsizedByteStr))) goto fail; cff2_priv_dict_interp_env_t env2 (privDictStr); dict_interpreter_t priv_interp (env2); privateDicts[i].init (); @@ -481,6 +482,13 @@ struct cff2 privateDicts.fini (); hb_blob_destroy (blob); blob = nullptr; + + auto *scalars = cached_scalars_vector.get_acquire (); + if (scalars && cached_scalars_vector.cmpexch (scalars, nullptr)) + { + scalars->fini (); + hb_free (scalars); + } } hb_vector_t *create_glyph_to_sid_map () const @@ -508,6 +516,8 @@ struct cff2 hb_vector_t fontDicts; hb_vector_t privateDicts; + mutable hb_atomic_t *> cached_scalars_vector; + unsigned int num_glyphs = 0; }; @@ -518,7 +528,10 @@ struct cff2 HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; - HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const; + HB_INTERNAL bool get_extents_at (hb_font_t *font, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + hb_array_t coords) const; HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const; HB_INTERNAL bool get_path_at (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session, hb_array_t coords) const; }; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-cmap-table.hh index 0f1edce0b..6765c557f 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-cmap-table.hh @@ -237,8 +237,6 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { - - template @@ -501,10 +499,6 @@ struct CmapSubtableFormat4 this->length = c->length () - table_initpos; if ((long long) this->length != (long long) c->length () - table_initpos) { - // Length overflowed. Discard the current object before setting the error condition, otherwise - // discard is a noop which prevents the higher level code from reverting the serializer to the - // pre-error state in cmap4 overflow handling code. - c->pop_discard (); c->err (HB_SERIALIZE_ERROR_INT_OVERFLOW); return; } @@ -525,9 +519,10 @@ struct CmapSubtableFormat4 struct accelerator_t { accelerator_t () {} - accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); } + accelerator_t (const CmapSubtableFormat4 *subtable) = delete; - void init (const CmapSubtableFormat4 *subtable) + void init (const CmapSubtableFormat4 *subtable, + unsigned int subtable_data_size) { segCount = subtable->segCountX2 / 2; endCount = subtable->values.arrayZ; @@ -535,7 +530,11 @@ struct CmapSubtableFormat4 idDelta = startCount + segCount; idRangeOffset = idDelta + segCount; glyphIdArray = idRangeOffset + segCount; - glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2; + + unsigned int values_offset = 16 + 8 * segCount; + glyphIdArrayLength = subtable_data_size > values_offset + ? (subtable_data_size - values_offset) / 2 + : 0; } bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const @@ -675,23 +674,36 @@ struct CmapSubtableFormat4 unsigned int glyphIdArrayLength; }; - bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph, + unsigned int subtable_data_size) const { - accelerator_t accel (this); + accelerator_t accel; + accel.init (this, subtable_data_size); return accel.get_glyph_func (&accel, codepoint, glyph); } - void collect_unicodes (hb_set_t *out) const + bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + { return false; } + + void collect_unicodes (hb_set_t *out, unsigned int subtable_data_size) const { - accelerator_t accel (this); + accelerator_t accel; + accel.init (this, subtable_data_size); accel.collect_unicodes (out); } + void collect_unicodes (hb_set_t *out) const + { collect_unicodes (out, length); } void collect_mapping (hb_set_t *unicodes, /* OUT */ - hb_map_t *mapping /* OUT */) const + hb_map_t *mapping, /* OUT */ + unsigned int subtable_data_size) const { - accelerator_t accel (this); + accelerator_t accel; + accel.init (this, subtable_data_size); accel.collect_mapping (unicodes, mapping); } + void collect_mapping (hb_set_t *unicodes, /* OUT */ + hb_map_t *mapping /* OUT */) const + { collect_mapping (unicodes, mapping, length); } bool sanitize (hb_sanitize_context_t *c) const { @@ -700,23 +712,9 @@ struct CmapSubtableFormat4 return_trace (false); hb_barrier (); - if (unlikely (!c->check_range (this, length))) - { - /* Some broken fonts have too long of a "length" value. - * If that is the case, just change the value to truncate - * the subtable at the end of the blob. */ - uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535, - (uintptr_t) (c->end - - (char *) this)); - if (!c->try_set (&length, new_length)) - return_trace (false); - } - - return_trace (16 + 4 * (unsigned int) segCountX2 <= length); + return_trace (c->check_range (values, 2 + 4 * segCountX2)); } - - protected: HBUINT16 format; /* Format number is set to 4. */ HBUINT16 length; /* This is the length in bytes of the @@ -1397,6 +1395,9 @@ struct CmapSubtableFormat14 hb_vector_t> obj_indices; for (int i = src_tbl->record.len - 1; i >= 0; i--) { + if (!unicodes->has(src_tbl->record[i].varSelector)) + continue; + hb_pair_t result = src_tbl->record[i].copy (c, unicodes, glyphs_requested, glyph_map, base); if (result.first || result.second) obj_indices.push (result); @@ -1453,6 +1454,7 @@ struct CmapSubtableFormat14 { + hb_iter (record) | hb_filter (hb_bool, &VariationSelectorRecord::nonDefaultUVS) + | hb_filter (unicodes, &VariationSelectorRecord::varSelector) | hb_map (&VariationSelectorRecord::nonDefaultUVS) | hb_map (hb_add (this)) | hb_apply ([=] (const NonDefaultUVS& _) { _.closure_glyphs (unicodes, glyphset); }) @@ -1494,11 +1496,14 @@ struct CmapSubtable /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ bool get_glyph (hb_codepoint_t codepoint, - hb_codepoint_t *glyph) const + hb_codepoint_t *glyph, + unsigned int subtable_data_size = 0) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0 .get_glyph (codepoint, glyph); - case 4: hb_barrier (); return u.format4 .get_glyph (codepoint, glyph); + case 4: hb_barrier (); return subtable_data_size + ? u.format4.get_glyph (codepoint, glyph, subtable_data_size) + : false; case 6: hb_barrier (); return u.format6 .get_glyph (codepoint, glyph); case 10: hb_barrier (); return u.format10.get_glyph (codepoint, glyph); case 12: hb_barrier (); return u.format12.get_glyph (codepoint, glyph); @@ -1507,11 +1512,17 @@ struct CmapSubtable default: return false; } } - void collect_unicodes (hb_set_t *out, unsigned int num_glyphs = UINT_MAX) const + void collect_unicodes (hb_set_t *out, + unsigned int num_glyphs = UINT_MAX, + unsigned int subtable_data_size = 0) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0 .collect_unicodes (out); return; - case 4: hb_barrier (); u.format4 .collect_unicodes (out); return; + case 4: hb_barrier (); if (subtable_data_size) + u.format4.collect_unicodes (out, subtable_data_size); + else + u.format4.collect_unicodes (out); + return; case 6: hb_barrier (); u.format6 .collect_unicodes (out); return; case 10: hb_barrier (); u.format10.collect_unicodes (out); return; case 12: hb_barrier (); u.format12.collect_unicodes (out, num_glyphs); return; @@ -1523,11 +1534,16 @@ struct CmapSubtable void collect_mapping (hb_set_t *unicodes, /* OUT */ hb_map_t *mapping, /* OUT */ - unsigned num_glyphs = UINT_MAX) const + unsigned num_glyphs = UINT_MAX, + unsigned int subtable_data_size = 0) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); u.format0 .collect_mapping (unicodes, mapping); return; - case 4: hb_barrier (); u.format4 .collect_mapping (unicodes, mapping); return; + case 4: hb_barrier (); if (subtable_data_size) + u.format4.collect_mapping (unicodes, mapping, subtable_data_size); + else + u.format4.collect_mapping (unicodes, mapping); + return; case 6: hb_barrier (); u.format6 .collect_mapping (unicodes, mapping); return; case 10: hb_barrier (); u.format10.collect_mapping (unicodes, mapping); return; case 12: hb_barrier (); u.format12.collect_mapping (unicodes, mapping, num_glyphs); return; @@ -1539,7 +1555,7 @@ struct CmapSubtable unsigned get_language () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0 .get_language (); case 4: hb_barrier (); return u.format4 .get_language (); case 6: hb_barrier (); return u.format6 .get_language (); @@ -1570,9 +1586,9 @@ struct CmapSubtable bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0 .sanitize (c)); case 4: hb_barrier (); return_trace (u.format4 .sanitize (c)); case 6: hb_barrier (); return_trace (u.format6 .sanitize (c)); @@ -1586,7 +1602,7 @@ struct CmapSubtable public: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ CmapSubtableFormat0 format0; CmapSubtableFormat4 format4; CmapSubtableFormat6 format6; @@ -1596,7 +1612,7 @@ struct CmapSubtable CmapSubtableFormat14 format14; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; @@ -1642,7 +1658,7 @@ struct EncodingRecord CmapSubtable *cmapsubtable = c->push (); unsigned origin_length = c->length (); cmapsubtable->serialize (c, it, format, plan, &(base+subtable)); - if (c->length () - origin_length > 0) *objidx = c->pop_pack (); + if (c->length () > origin_length && !c->in_error()) *objidx = c->pop_pack (); else c->pop_discard (); } @@ -1671,6 +1687,7 @@ struct SubtableUnicodesCache { private: hb_blob_ptr_t base_blob; const char* base; + unsigned int table_length; hb_hashmap_t> cached_unicodes; public: @@ -1679,6 +1696,10 @@ struct SubtableUnicodesCache { { SubtableUnicodesCache* cache = (SubtableUnicodesCache*) hb_malloc (sizeof(SubtableUnicodesCache)); + + if (unlikely (!cache)) + return nullptr; + new (cache) SubtableUnicodesCache (source_table); return cache; } @@ -1691,15 +1712,18 @@ struct SubtableUnicodesCache { hb_free (cache); } - SubtableUnicodesCache(const void* cmap_base) + SubtableUnicodesCache(const void* cmap_base, + unsigned int table_length_ = 0) : base_blob(), base ((const char*) cmap_base), + table_length (table_length_), cached_unicodes () {} SubtableUnicodesCache(hb_blob_ptr_t base_blob_) : base_blob(base_blob_), base ((const char *) base_blob.get()), + table_length (base_blob.get_length ()), cached_unicodes () {} @@ -1730,7 +1754,10 @@ struct SubtableUnicodesCache { if (unlikely (s->in_error ())) return hb_set_get_empty (); - (base+record->subtable).collect_unicodes (s); + unsigned int subtable_data_size = record->subtable < table_length + ? table_length - (unsigned int) record->subtable + : 0; + (base+record->subtable).collect_unicodes (s, UINT_MAX, subtable_data_size); if (unlikely (!cached_unicodes.set ((unsigned) ((const char *) record - base), hb::unique_ptr {s}))) return hb_set_get_empty (); @@ -1742,7 +1769,7 @@ struct SubtableUnicodesCache { }; -static inline uint_fast16_t +static inline uint16_t _hb_symbol_pua_map (unsigned codepoint) { if (codepoint <= 0x00FFu) @@ -1772,6 +1799,10 @@ struct cmap ; SubtableUnicodesCache* cache = SubtableUnicodesCache::create(source_table); + + if (unlikely (!cache)) + return nullptr; + for (const EncodingRecord& _ : it) cache->set_for(&_); // populate the cache for this encoding record. @@ -1785,7 +1816,8 @@ struct cmap EncodingRecIter encodingrec_iter, const void *base, hb_subset_plan_t *plan, - bool drop_format_4 = false) + bool drop_format_4 = false, + unsigned int source_table_length = 0) { if (unlikely (!c->extend_min ((*this)))) return false; this->version = 0; @@ -1793,7 +1825,7 @@ struct cmap unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0; auto snap = c->snapshot (); - SubtableUnicodesCache local_unicodes_cache (base); + SubtableUnicodesCache local_unicodes_cache (base, source_table_length); const SubtableUnicodesCache* unicodes_cache = &local_unicodes_cache; if (plan->accelerator && @@ -1806,7 +1838,7 @@ struct cmap if (c->in_error ()) return false; - unsigned format = (base+_.subtable).u.format; + unsigned format = (base+_.subtable).u.format.v; if (format != 4 && format != 12 && format != 14) continue; const hb_set_t* unicodes_set = unicodes_cache->set_for (&_, local_unicodes_cache); @@ -1822,7 +1854,8 @@ struct cmap encodingrec_iter, base, plan, - true); + true, + source_table_length); } } @@ -1839,9 +1872,11 @@ struct cmap } else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); } - c->check_assign(this->encodingRecord.len, - (c->length () - cmap::min_size)/EncodingRecord::static_size, - HB_SERIALIZE_ERROR_INT_OVERFLOW); + unsigned length = c->length (); + unsigned available = length > cmap::min_size ? length - cmap::min_size : 0; + c->check_assign(this->encodingRecord.len, + available / EncodingRecord::static_size, + HB_SERIALIZE_ERROR_INT_OVERFLOW); // Fail if format 4 was dropped and there is no cmap12. return !drop_format_4 || format12objidx; @@ -1908,7 +1943,7 @@ struct cmap + hb_iter (encodingRecord) | hb_map (&EncodingRecord::subtable) | hb_map (hb_add (this)) - | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == 14; }) + | hb_filter ([&] (const CmapSubtable& _) { return _.u.format.v == 14; }) | hb_apply ([=] (const CmapSubtable& _) { _.u.format14.closure_glyphs (unicodes, glyphset); }) ; } @@ -1933,7 +1968,7 @@ struct cmap for (const EncodingRecord& _ : encodingrec_iter) { - unsigned format = (this + _.subtable).u.format; + unsigned format = (this + _.subtable).u.format.v; if (format == 12) has_format12 = true; const EncodingRecord *table = std::addressof (_); @@ -1956,7 +1991,9 @@ struct cmap it, encodingrec_iter, this, - c->plan)); + c->plan, + false, + c->source_blob->length)); } const CmapSubtable *find_best_subtable (bool *symbol = nullptr, @@ -2010,7 +2047,8 @@ struct cmap struct accelerator_t { - using cache_t = hb_cache_t<21, 16, 8, true>; + using cache_t = hb_cache_t<21, 19>; + static_assert (sizeof (cache_t) == 1024, ""); accelerator_t (hb_face_t *face) { @@ -2020,99 +2058,145 @@ struct cmap this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); - if (st && st->u.format == 14) + if (st && st->u.format.v == 14) subtable_uvs = &st->u.format14; } +#ifndef HB_NO_OT_FONT_CMAP_CACHE + cache = (cache_t *) hb_malloc (sizeof (cache_t)); + if (cache) + new (cache) cache_t (); + else + return; // Such that get_glyph_funcZ remains null. +#endif + this->get_glyph_data = subtable; #ifndef HB_NO_CMAP_LEGACY_SUBTABLES + bool is_format4 = subtable->u.format.v == 4; + auto set_format4_getter = [this] (bool (*func) (const void *, + hb_codepoint_t, + hb_codepoint_t *)) + { + this->format4_accel.init (&this->subtable->u.format4, + get_subtable_data_size (this->subtable)); + this->get_glyph_data = &this->format4_accel; + this->get_glyph_funcZ = func; + }; if (unlikely (symbol)) { switch ((unsigned) face->table.OS2->get_font_page ()) { case OS2::font_page_t::FONT_PAGE_NONE: - this->get_glyph_funcZ = get_glyph_from_symbol; + if (is_format4) + set_format4_getter (get_glyph_from_symbol); + else + this->get_glyph_funcZ = get_glyph_from_symbol; break; #ifndef HB_NO_OT_SHAPER_ARABIC_FALLBACK case OS2::font_page_t::FONT_PAGE_SIMP_ARABIC: - this->get_glyph_funcZ = get_glyph_from_symbol; + if (is_format4) + set_format4_getter (get_glyph_from_symbol); + else + this->get_glyph_funcZ = get_glyph_from_symbol; break; case OS2::font_page_t::FONT_PAGE_TRAD_ARABIC: - this->get_glyph_funcZ = get_glyph_from_symbol; + if (is_format4) + set_format4_getter (get_glyph_from_symbol); + else + this->get_glyph_funcZ = get_glyph_from_symbol; break; #endif default: - this->get_glyph_funcZ = get_glyph_from; + if (is_format4) + set_format4_getter (get_glyph_from); + else + this->get_glyph_funcZ = get_glyph_from; break; } } else if (unlikely (macroman)) { - this->get_glyph_funcZ = get_glyph_from_macroman; + if (is_format4) + set_format4_getter (get_glyph_from_macroman); + else + this->get_glyph_funcZ = get_glyph_from_macroman; } else if (unlikely (mac)) { - this->get_glyph_funcZ = get_glyph_from_ascii; + if (is_format4) + set_format4_getter (get_glyph_from_ascii); + else + this->get_glyph_funcZ = get_glyph_from_ascii; } else #endif { - switch (subtable->u.format) { - /* Accelerate format 4 and format 12. */ - default: - this->get_glyph_funcZ = get_glyph_from; - break; - case 12: - this->get_glyph_funcZ = get_glyph_from; - break; - case 4: - { - this->format4_accel.init (&subtable->u.format4); - this->get_glyph_data = &this->format4_accel; - this->get_glyph_funcZ = this->format4_accel.get_glyph_func; - break; - } + switch (subtable->u.format.v) { + /* Accelerate format 4 and format 12. */ + default: + this->get_glyph_funcZ = get_glyph_from; + break; + case 12: + this->get_glyph_funcZ = get_glyph_from; + break; + case 4: + { + this->format4_accel.init (&subtable->u.format4, + get_subtable_data_size (subtable)); + this->get_glyph_data = &this->format4_accel; + this->get_glyph_funcZ = this->format4_accel.get_glyph_func; + break; + } } } } - ~accelerator_t () { this->table.destroy (); } + ~accelerator_t () + { +#ifndef HB_NO_OT_FONT_CMAP_CACHE + hb_free (cache); +#endif + table.destroy (); + } inline bool _cached_get (hb_codepoint_t unicode, - hb_codepoint_t *glyph, - cache_t *cache) const + hb_codepoint_t *glyph) const { +#ifndef HB_NO_OT_FONT_CMAP_CACHE + // cache is always non-null if we have a get_glyph_funcZ unsigned v; - if (cache && cache->get (unicode, &v)) + if (cache->get (unicode, &v)) { *glyph = v; return true; } +#endif bool ret = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); - if (cache && ret) +#ifndef HB_NO_OT_FONT_CMAP_CACHE + if (ret) cache->set (unicode, *glyph); +#endif + return ret; } bool get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph, - cache_t *cache = nullptr) const + hb_codepoint_t *glyph) const { if (unlikely (!this->get_glyph_funcZ)) return false; - return _cached_get (unicode, glyph, cache); + return _cached_get (unicode, glyph); } unsigned int get_nominal_glyphs (unsigned int count, const hb_codepoint_t *first_unicode, unsigned int unicode_stride, hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - cache_t *cache = nullptr) const + unsigned int glyph_stride) const { if (unlikely (!this->get_glyph_funcZ)) return 0; unsigned int done; for (done = 0; - done < count && _cached_get (*first_unicode, first_glyph, cache); + done < count && _cached_get (*first_unicode, first_glyph); done++) { first_unicode = &StructAtOffsetUnaligned (first_unicode, unicode_stride); @@ -2123,8 +2207,7 @@ struct cmap bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - cache_t *cache = nullptr) const + hb_codepoint_t *glyph) const { switch (this->subtable_uvs->get_glyph_variant (unicode, variation_selector, @@ -2135,14 +2218,14 @@ struct cmap case GLYPH_VARIANT_USE_DEFAULT: break; } - return get_nominal_glyph (unicode, glyph, cache); + return get_nominal_glyph (unicode, glyph); } void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const - { subtable->collect_unicodes (out, num_glyphs); } + { subtable->collect_unicodes (out, num_glyphs, get_subtable_data_size (subtable)); } void collect_mapping (hb_set_t *unicodes, hb_map_t *mapping, unsigned num_glyphs = UINT_MAX) const - { subtable->collect_mapping (unicodes, mapping, num_glyphs); } + { subtable->collect_mapping (unicodes, mapping, num_glyphs, get_subtable_data_size (subtable)); } void collect_variation_selectors (hb_set_t *out) const { subtable_uvs->collect_variation_selectors (out); } void collect_variation_unicodes (hb_codepoint_t variation_selector, @@ -2153,7 +2236,7 @@ struct cmap typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); - typedef uint_fast16_t (*hb_pua_remap_func_t) (unsigned); + typedef uint16_t (*hb_pua_remap_func_t) (unsigned); template HB_INTERNAL static bool get_glyph_from (const void *obj, @@ -2201,15 +2284,34 @@ struct cmap return c && typed_obj->get_glyph (c, glyph); } + unsigned int get_subtable_data_size (const CmapSubtable *subtable) const + { + unsigned int table_length = this->table.get_length (); + uintptr_t table_start = (uintptr_t) (const void *) this->table.get (); + uintptr_t subtable_addr = (uintptr_t) (const void *) subtable; + if (unlikely (subtable_addr < table_start)) + return 0; + + uintptr_t subtable_offset = subtable_addr - table_start; + if (unlikely (subtable_offset >= table_length)) + return 0; + + return table_length - (unsigned int) subtable_offset; + } + private: hb_nonnull_ptr_t subtable; hb_nonnull_ptr_t subtable_uvs; - hb_cmap_get_glyph_func_t get_glyph_funcZ; - const void *get_glyph_data; + hb_cmap_get_glyph_func_t get_glyph_funcZ = nullptr; + const void *get_glyph_data = nullptr; CmapSubtableFormat4::accelerator_t format4_accel; +#ifndef HB_NO_OT_FONT_CMAP_CACHE + cache_t *cache = nullptr; +#endif + public: hb_blob_ptr_t table; }; @@ -2251,7 +2353,7 @@ struct cmap (_.platformID == 0 && _.encodingID == 4) || (_.platformID == 3 && _.encodingID == 1) || (_.platformID == 3 && _.encodingID == 10) || - (cmap + _.subtable).u.format == 14; + (cmap + _.subtable).u.format.v == 14; } protected: diff --git a/thirdparty/harfbuzz/upstream/hb-ot-color.cc b/thirdparty/harfbuzz/upstream/hb-ot-color.cc index 37d42e08d..34cdedb63 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-color.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-color.cc @@ -35,7 +35,9 @@ #include "OT/Color/COLR/COLR.hh" #include "OT/Color/CPAL/CPAL.hh" #include "OT/Color/sbix/sbix.hh" +#ifndef HB_NO_SVG #include "OT/Color/svg/svg.hh" +#endif /** @@ -204,7 +206,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { - return face->table.COLR->has_v0_data (); + return face->table.COLR->colr->has_v0_data (); } /** @@ -221,7 +223,7 @@ hb_ot_color_has_layers (hb_face_t *face) hb_bool_t hb_ot_color_has_paint (hb_face_t *face) { - return face->table.COLR->has_v1_data (); + return face->table.COLR->colr->has_v1_data (); } /** @@ -240,7 +242,7 @@ hb_bool_t hb_ot_color_glyph_has_paint (hb_face_t *face, hb_codepoint_t glyph) { - return face->table.COLR->has_paint_for_glyph (glyph); + return face->table.COLR->colr->has_paint_for_glyph (glyph); } /** @@ -266,7 +268,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) { - return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers); + return face->table.COLR->colr->get_glyph_layers (glyph, start_offset, layer_count, layers); } @@ -274,6 +276,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * SVG */ +#ifndef HB_NO_SVG /** * hb_ot_color_has_svg: * @face: #hb_face_t to work upon. @@ -290,6 +293,70 @@ hb_ot_color_has_svg (hb_face_t *face) return face->table.SVG->has_data (); } +/** + * hb_ot_color_get_svg_document_count: + * @face: #hb_face_t to work upon. + * + * Gets the number of SVG documents in the face `SVG` table. + * + * Return value: number of SVG documents in the face. + * + * Since: 12.1.0 + */ +unsigned int +hb_ot_color_get_svg_document_count (hb_face_t *face) +{ + return face->table.SVG->get_document_count (); +} + +/** + * hb_ot_color_glyph_get_svg_document_index: + * @face: #hb_face_t to work upon. + * @glyph: glyph ID to query. + * @svg_document_index: (out) (nullable): output SVG document index. + * + * Gets the `SVG`-table document index associated with a glyph. + * + * Return value: `true` if @glyph maps to an SVG document, `false` otherwise. + * + * Since: 12.1.0 + */ +hb_bool_t +hb_ot_color_glyph_get_svg_document_index (hb_face_t *face, + hb_codepoint_t glyph, + unsigned int *svg_document_index) +{ + unsigned doc_index = 0; + hb_bool_t ret = face->table.SVG->get_glyph_document_index (glyph, &doc_index); + if (ret && svg_document_index) + *svg_document_index = doc_index; + return ret; +} + +/** + * hb_ot_color_get_svg_document_glyph_range: + * @face: #hb_face_t to work upon. + * @svg_document_index: SVG document index. + * @start_glyph_id: (out) (nullable): output start glyph ID. + * @end_glyph_id: (out) (nullable): output end glyph ID. + * + * Gets the glyph range covered by an `SVG`-table document index. + * + * Return value: `true` if @svg_document_index is valid, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_ot_color_get_svg_document_glyph_range (hb_face_t *face, + unsigned int svg_document_index, + hb_codepoint_t *start_glyph_id, + hb_codepoint_t *end_glyph_id) +{ + return face->table.SVG->get_document_glyph_range (svg_document_index, + start_glyph_id, + end_glyph_id); +} + /** * hb_ot_color_glyph_reference_svg: * @face: #hb_face_t to work upon @@ -308,6 +375,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) { return face->table.SVG->reference_blob_for_glyph (glyph); } +#endif /* diff --git a/thirdparty/harfbuzz/upstream/hb-ot-color.h b/thirdparty/harfbuzz/upstream/hb-ot-color.h index 22ee497e3..eae339f82 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-color.h +++ b/thirdparty/harfbuzz/upstream/hb-ot-color.h @@ -136,6 +136,20 @@ hb_ot_color_glyph_has_paint (hb_face_t *face, HB_EXTERN hb_bool_t hb_ot_color_has_svg (hb_face_t *face); +HB_EXTERN unsigned int +hb_ot_color_get_svg_document_count (hb_face_t *face); + +HB_EXTERN hb_bool_t +hb_ot_color_glyph_get_svg_document_index (hb_face_t *face, + hb_codepoint_t glyph, + unsigned int *svg_document_index /* OUT */); + +HB_EXTERN hb_bool_t +hb_ot_color_get_svg_document_glyph_range (hb_face_t *face, + unsigned int svg_document_index, + hb_codepoint_t *start_glyph_id, /* OUT */ + hb_codepoint_t *end_glyph_id /* OUT */); + HB_EXTERN hb_blob_t * hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph); diff --git a/thirdparty/harfbuzz/upstream/hb-ot-face-table-list.hh b/thirdparty/harfbuzz/upstream/hb-ot-face-table-list.hh index dd4befffa..9047b2880 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-face-table-list.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-face-table-list.hh @@ -95,9 +95,12 @@ HB_OT_CORE_TABLE (OT, fvar) HB_OT_CORE_TABLE (OT, avar) HB_OT_CORE_TABLE (OT, cvar) HB_OT_ACCELERATOR (OT, gvar) +#ifndef HB_NO_BEYOND_64K +HB_OT_ACCELERATOR (OT, GVAR) +#endif HB_OT_CORE_TABLE (OT, MVAR) #ifndef HB_NO_VAR_COMPOSITES -HB_OT_CORE_TABLE (OT, VARC) +HB_OT_ACCELERATOR (OT, VARC) #endif #endif @@ -133,12 +136,14 @@ HB_OT_TABLE (AAT, feat) /* OpenType color fonts. */ #ifndef HB_NO_COLOR -HB_OT_CORE_TABLE (OT, COLR) +HB_OT_ACCELERATOR (OT, COLR) HB_OT_CORE_TABLE (OT, CPAL) HB_OT_ACCELERATOR (OT, CBDT) HB_OT_ACCELERATOR (OT, sbix) +#ifndef HB_NO_SVG HB_OT_ACCELERATOR (OT, SVG) #endif +#endif /* OpenType math. */ #ifndef HB_NO_MATH diff --git a/thirdparty/harfbuzz/upstream/hb-ot-face.cc b/thirdparty/harfbuzz/upstream/hb-ot-face.cc index b0c927979..d17f08807 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-face.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-face.cc @@ -36,11 +36,13 @@ #include "hb-ot-name-table.hh" #include "hb-ot-post-table.hh" #include "OT/Color/CBDT/CBDT.hh" +#include "OT/Color/COLR/COLR.hh" #include "OT/Color/sbix/sbix.hh" #include "OT/Color/svg/svg.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-var-varc-table.hh" #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" diff --git a/thirdparty/harfbuzz/upstream/hb-ot-font.cc b/thirdparty/harfbuzz/upstream/hb-ot-font.cc index 7b4724710..bc43f5f0e 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-font.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-font.cc @@ -34,15 +34,15 @@ #include "hb-font.hh" #include "hb-machinery.hh" #include "hb-ot-face.hh" -#include "hb-outline.hh" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" +#include "hb-ot-var-gvar-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-stat-table.hh" #include "hb-ot-var-varc-table.hh" #include "hb-ot-vorg-table.hh" #include "OT/Color/CBDT/CBDT.hh" @@ -62,24 +62,255 @@ * never need to call these functions directly. **/ -using hb_ot_font_cmap_cache_t = hb_cache_t<21, 16, 8, true>; -using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>; +using hb_ot_font_advance_cache_t = hb_cache_t<24, 16>; +static_assert (sizeof (hb_ot_font_advance_cache_t) == 1024, ""); -#ifndef HB_NO_OT_FONT_CMAP_CACHE -static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key; -#endif +using hb_ot_font_origin_cache_t = hb_cache_t<20, 20>; +static_assert (sizeof (hb_ot_font_origin_cache_t) == 1024, ""); struct hb_ot_font_t { const hb_ot_face_t *ot_face; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - hb_ot_font_cmap_cache_t *cmap_cache; -#endif + mutable hb_atomic_t cached_serial; + mutable hb_atomic_t cached_coords_serial; + + struct direction_cache_t + { + mutable hb_atomic_t advance_cache; + mutable hb_atomic_t varStore_cache; + + ~direction_cache_t () + { + clear (); + } + + hb_ot_font_advance_cache_t *acquire_advance_cache () const + { + retry: + auto *cache = advance_cache.get_acquire (); + if (!cache) + { + cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); + if (!cache) + return nullptr; + new (cache) hb_ot_font_advance_cache_t; + return cache; + } + if (advance_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_advance_cache (hb_ot_font_advance_cache_t *cache) const + { + if (!cache) + return; + if (!advance_cache.cmpexch (nullptr, cache)) + hb_free (cache); + } + void clear_advance_cache () const + { + retry: + auto *cache = advance_cache.get_acquire (); + if (!cache) + return; + if (advance_cache.cmpexch (cache, nullptr)) + hb_free (cache); + else + goto retry; + } + + OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return varStore.create_cache (); + if (varStore_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_varStore_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; + if (!varStore_cache.cmpexch (nullptr, cache)) + OT::ItemVariationStore::destroy_cache (cache); + } + void clear_varStore_cache () const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return; + if (varStore_cache.cmpexch (cache, nullptr)) + OT::ItemVariationStore::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_advance_cache (); + clear_varStore_cache (); + } + + } h, v; + + struct origin_cache_t + { + mutable hb_atomic_t origin_cache; + mutable hb_atomic_t varStore_cache; + + ~origin_cache_t () + { + clear (); + } + + hb_ot_font_origin_cache_t *acquire_origin_cache () const + { + retry: + auto *cache = origin_cache.get_acquire (); + if (!cache) + { + cache = (hb_ot_font_origin_cache_t *) hb_malloc (sizeof (hb_ot_font_origin_cache_t)); + if (!cache) + return nullptr; + new (cache) hb_ot_font_origin_cache_t; + return cache; + } + if (origin_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_origin_cache (hb_ot_font_origin_cache_t *cache) const + { + if (!cache) + return; + if (!origin_cache.cmpexch (nullptr, cache)) + hb_free (cache); + } + void clear_origin_cache () const + { + retry: + auto *cache = origin_cache.get_acquire (); + if (!cache) + return; + if (origin_cache.cmpexch (cache, nullptr)) + hb_free (cache); + else + goto retry; + } + + OT::hb_scalar_cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return varStore.create_cache (); + if (varStore_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_varStore_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; + if (!varStore_cache.cmpexch (nullptr, cache)) + OT::ItemVariationStore::destroy_cache (cache); + } + void clear_varStore_cache () const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return; + if (varStore_cache.cmpexch (cache, nullptr)) + OT::ItemVariationStore::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_origin_cache (); + clear_varStore_cache (); + } + } v_origin; + + struct draw_cache_t + { + mutable hb_atomic_t gvar_cache; + + ~draw_cache_t () + { + clear (); + } - /* h_advance caching */ - mutable hb_atomic_int_t cached_coords_serial; - mutable hb_atomic_ptr_t advance_cache; + OT::hb_scalar_cache_t *acquire_gvar_cache (const OT::gvar_accelerator_t &gvar) const + { + retry: + auto *cache = gvar_cache.get_acquire (); + if (!cache) + return gvar.create_cache (); + if (gvar_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_gvar_cache (OT::hb_scalar_cache_t *cache) const + { + if (!cache) + return; + if (!gvar_cache.cmpexch (nullptr, cache)) + OT::gvar_accelerator_t::destroy_cache (cache); + } + void clear_gvar_cache () const + { + retry: + auto *cache = gvar_cache.get_acquire (); + if (!cache) + return; + if (gvar_cache.cmpexch (cache, nullptr)) + OT::gvar_accelerator_t::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_gvar_cache (); + } + } draw; + + void check_serial (hb_font_t *font) const + { + int font_serial = font->serial_coords.get_acquire (); + if (cached_serial.get_acquire () != font_serial) + { + /* These caches are dependent on scale and synthetic settings. + * Any change to the font invalidates them. */ + v_origin.clear (); + + cached_serial.set_release (font_serial); + } + + int font_serial_coords = font->serial_coords.get_acquire (); + if (cached_coords_serial.get_acquire () != font_serial_coords) + { + /* These caches are independent of scale or synthetic settings. + * Just variation changes will invalidate them. */ + h.clear (); + v.clear (); + draw.clear (); + + cached_coords_serial.set_release (font_serial_coords); + } + } }; static hb_ot_font_t * @@ -91,35 +322,6 @@ _hb_ot_font_create (hb_font_t *font) ot_font->ot_face = &font->face->table; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - // retry: - auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face, - &hb_ot_font_cmap_cache_user_data_key); - if (!cmap_cache) - { - cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t)); - if (unlikely (!cmap_cache)) goto out; - new (cmap_cache) hb_ot_font_cmap_cache_t (); - if (unlikely (!hb_face_set_user_data (font->face, - &hb_ot_font_cmap_cache_user_data_key, - cmap_cache, - hb_free, - false))) - { - hb_free (cmap_cache); - cmap_cache = nullptr; - /* Normally we would retry here, but that would - * infinite-loop if the face is the empty-face. - * Just let it go and this font will be uncached if it - * happened to collide with another thread creating the - * cache at the same time. */ - // goto retry; - } - } - out: - ot_font->cmap_cache = cmap_cache; -#endif - return ot_font; } @@ -128,8 +330,7 @@ _hb_ot_font_destroy (void *font_data) { hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data; - auto *cache = ot_font->advance_cache.get_relaxed (); - hb_free (cache); + ot_font->~hb_ot_font_t (); hb_free (ot_font); } @@ -143,11 +344,7 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif - return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache); + return ot_face->cmap->get_nominal_glyph (unicode, glyph); } static unsigned int @@ -162,14 +359,9 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif return ot_face->cmap->get_nominal_glyphs (count, first_unicode, unicode_stride, - first_glyph, glyph_stride, - cmap_cache); + first_glyph, glyph_stride); } static hb_bool_t @@ -182,13 +374,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif return ot_face->cmap->get_variation_glyph (unicode, - variation_selector, glyph, - cmap_cache); + variation_selector, glyph); } static void @@ -200,98 +387,118 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + // Duplicated in v_advances. Ugly. Keep in sync'ish. const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; - hb_position_t *orig_first_advance = first_advance; - -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - const OT::HVAR &HVAR = *hmtx.var_table; - const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; - - bool use_cache = font->num_coords; -#else - OT::ItemVariationStore::cache_t *varStore_cache = nullptr; - bool use_cache = false; -#endif - - hb_ot_font_advance_cache_t *cache = nullptr; - if (use_cache) + if (unlikely (!hmtx.has_data ())) { - retry: - cache = ot_font->advance_cache.get_acquire (); - if (unlikely (!cache)) + hb_position_t advance = font->face->get_upem () / 2; + advance = font->em_scale_x (advance); + for (unsigned int i = 0; i < count; i++) { - cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); - if (unlikely (!cache)) - { - use_cache = false; - goto out; - } - new (cache) hb_ot_font_advance_cache_t; - - if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache))) - { - hb_free (cache); - goto retry; - } - ot_font->cached_coords_serial.set_release (font->serial_coords); + *first_advance = advance; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + return; } - out: - if (!use_cache) +#ifndef HB_NO_VAR + if (!font->has_nonzero_coords) + { + fallback: +#else { +#endif + // Just plain htmx data. No need to cache. for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_x (hmtx.get_advance_without_var_unscaled (*first_glyph)); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + return; } - else - { /* Use cache. */ - if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords) - { - ot_font->advance_cache->clear (); - ot_font->cached_coords_serial.set_release (font->serial_coords); - } + +#ifndef HB_NO_VAR + /* has_nonzero_coords. */ + + ot_font->check_serial (font); + hb_ot_font_advance_cache_t *advance_cache = ot_font->h.acquire_advance_cache (); + if (!advance_cache) + { + // malloc failure. Just use the fallback non-variable path. + goto fallback; + } + + /* If HVAR is present, use it.*/ + const OT::HVAR &HVAR = *hmtx.var_table; + if (HVAR.has_data ()) + { + const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; + OT::hb_scalar_cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); for (unsigned int i = 0; i < count; i++) { hb_position_t v; unsigned cv; - if (ot_font->advance_cache->get (*first_glyph, &cv)) + if (advance_cache->get (*first_glyph, &cv)) v = cv; else { v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); - ot_font->advance_cache->set (*first_glyph, v); + advance_cache->set (*first_glyph, v); } *first_advance = font->em_scale_x (v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } - } -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::ItemVariationStore::destroy_cache (varStore_cache); -#endif + ot_font->h.release_varStore_cache (varStore_cache); + ot_font->h.release_advance_cache (advance_cache); + return; + } - if (font->x_strength && !font->embolden_in_place) + const auto &gvar = *ot_face->gvar; + if (gvar.has_data ()) { - /* Emboldening. */ - hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; - first_advance = orig_first_advance; + const auto &glyf = *ot_face->glyf; + auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->h.release_advance_cache (advance_cache); + goto fallback; + } + OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); + for (unsigned int i = 0; i < count; i++) { - *first_advance += *first_advance ? x_strength : 0; + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = glyf.get_advance_with_var_unscaled (*first_glyph, font, false, *scratch, gvar_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_x (v); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->h.release_advance_cache (advance_cache); + return; } + + ot_font->h.release_advance_cache (advance_cache); + // No HVAR or GVAR. Just use the fallback non-variable path. + goto fallback; +#endif } #ifndef HB_NO_VERTICAL @@ -304,116 +511,290 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + // Duplicated from h_advances. Ugly. Keep in sync'ish. + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - hb_position_t *orig_first_advance = first_advance; + if (unlikely (!vmtx.has_data ())) + { + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + hb_position_t advance = font_extents.descender - font_extents.ascender; + for (unsigned int i = 0; i < count; i++) + { + *first_advance = advance; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + return; + } - if (vmtx.has_data ()) +#ifndef HB_NO_VAR + if (!font->has_nonzero_coords) { -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - const OT::VVAR &VVAR = *vmtx.var_table; - const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; + fallback: #else - OT::ItemVariationStore::cache_t *varStore_cache = nullptr; + { #endif - + // Just plain vtmx data. No need to cache. for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_y (- (int) vmtx.get_advance_without_var_unscaled (*first_glyph)); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + return; + } -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::ItemVariationStore::destroy_cache (varStore_cache); -#endif +#ifndef HB_NO_VAR + /* has_nonzero_coords. */ + + ot_font->check_serial (font); + hb_ot_font_advance_cache_t *advance_cache = ot_font->v.acquire_advance_cache (); + if (!advance_cache) + { + // malloc failure. Just use the fallback non-variable path. + goto fallback; } - else + + /* If VVAR is present, use it.*/ + const OT::VVAR &VVAR = *vmtx.var_table; + if (VVAR.has_data ()) { - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = -(font_extents.ascender - font_extents.descender); + const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; + OT::hb_scalar_cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); for (unsigned int i = 0; i < count; i++) { - *first_advance = advance; + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_y (- (int) v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + ot_font->v.release_varStore_cache (varStore_cache); + ot_font->v.release_advance_cache (advance_cache); + return; } - if (font->y_strength && !font->embolden_in_place) + const auto &gvar = *ot_face->gvar; + if (gvar.has_data ()) { - /* Emboldening. */ - hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - first_advance = orig_first_advance; + const auto &glyf = *ot_face->glyf; + auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) + { + ot_font->v.release_advance_cache (advance_cache); + goto fallback; + } + OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar); + for (unsigned int i = 0; i < count; i++) { - *first_advance += *first_advance ? y_strength : 0; + hb_position_t v; + unsigned cv; + if (advance_cache->get (*first_glyph, &cv)) + v = cv; + else + { + v = glyf.get_advance_with_var_unscaled (*first_glyph, font, true, *scratch, gvar_cache); + advance_cache->set (*first_glyph, v); + } + *first_advance = font->em_scale_y (- (int) v); + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->v.release_advance_cache (advance_cache); + return; } + + ot_font->v.release_advance_cache (advance_cache); + // No VVAR or GVAR. Just use the fallback non-variable path. + goto fallback; +#endif } #endif #ifndef HB_NO_VERTICAL +HB_HOT static hb_bool_t -hb_ot_get_glyph_v_origin (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_ot_get_glyph_v_origins (hb_font_t *font, + void *font_data, + unsigned int count, + const hb_codepoint_t *first_glyph, + unsigned glyph_stride, + hb_position_t *first_x, + unsigned x_stride, + hb_position_t *first_y, + unsigned y_stride, + void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - *x = font->get_glyph_h_advance (glyph) / 2; + /* First, set all the x values to half the advance width. */ + font->get_glyph_h_advances (count, + first_glyph, glyph_stride, + first_x, x_stride); + for (unsigned i = 0; i < count; i++) + { + *first_x /= 2; + first_x = &StructAtOffsetUnaligned (first_x, x_stride); + } + + /* The vertical origin business is messy... + * + * We allocate the cache, then have various code paths that use the cache. + * Each one is responsible to free it before returning. + */ + hb_ot_font_origin_cache_t *origin_cache = ot_font->v_origin.acquire_origin_cache (); + /* If there is VORG, always use it. It uses VVAR for variations if necessary. */ const OT::VORG &VORG = *ot_face->VORG; - if (VORG.has_data ()) + if (origin_cache && VORG.has_data ()) { - float delta = 0; - #ifndef HB_NO_VAR - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - const OT::VVAR &VVAR = *vmtx.var_table; - if (font->num_coords) - VVAR.get_vorg_delta_unscaled (glyph, - font->coords, font->num_coords, - &delta); + if (!font->has_nonzero_coords) #endif - - *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); + { + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } +#ifndef HB_NO_VAR + else + { + const OT::VVAR &VVAR = *ot_face->vmtx->var_table; + const auto &varStore = &VVAR + VVAR.varStore; + auto *varStore_cache = ot_font->v_origin.acquire_varStore_cache (varStore); + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph) + + VVAR.get_vorg_delta_unscaled (*first_glyph, + font->coords, font->num_coords, + varStore_cache)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + ot_font->v_origin.release_varStore_cache (varStore_cache); + } +#endif + ot_font->v_origin.release_origin_cache (origin_cache); return true; } - hb_glyph_extents_t extents = {0}; - if (ot_face->glyf->get_extents (font, glyph, &extents)) + /* If and only if `vmtx` is present and it's a `glyf` font, + * we use the top phantom point, deduced from vmtx,glyf[,gvar]. */ + const auto &vmtx = *ot_face->vmtx; + const auto &glyf = *ot_face->glyf; + if (origin_cache && vmtx.has_data() && glyf.has_data ()) { - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - int tsb = 0; - if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) + auto *scratch = glyf.acquire_scratch (); + if (unlikely (!scratch)) { - *y = extents.y_bearing + font->em_scale_y (tsb); - return true; + ot_font->v_origin.release_origin_cache (origin_cache); + return false; } + OT::hb_scalar_cache_t *gvar_cache = font->has_nonzero_coords ? + ot_font->draw.acquire_gvar_cache (*ot_face->gvar) : + nullptr; - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - hb_position_t advance = font_extents.ascender - font_extents.descender; - int diff = advance - -extents.height; - *y = extents.y_bearing + (diff >> 1); + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + origin = font->em_scalef_y (glyf.get_v_origin_with_var_unscaled (*first_glyph, font, *scratch, gvar_cache)); + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + + if (gvar_cache) + ot_font->draw.release_gvar_cache (gvar_cache); + glyf.release_scratch (scratch); + ot_font->v_origin.release_origin_cache (origin_cache); return true; } - hb_font_extents_t font_extents; - font->get_h_extents_with_fallback (&font_extents); - *y = font_extents.ascender; + /* Otherwise, use glyph extents to center the glyph vertically. + * If getting glyph extents failed, just use the font ascender. */ + if (origin_cache && font->has_glyph_extents_func ()) + { + hb_font_extents_t font_extents; + font->get_h_extents_with_fallback (&font_extents); + hb_position_t font_advance = font_extents.ascender - font_extents.descender; + + for (unsigned i = 0; i < count; i++) + { + hb_position_t origin; + unsigned cv; + + if (origin_cache->get (*first_glyph, &cv)) + origin = font->y_scale < 0 ? -static_cast(cv) : static_cast(cv); + else + { + hb_glyph_extents_t extents = {0}; + if (likely (font->get_glyph_extents (*first_glyph, &extents))) + origin = extents.y_bearing + ((font_advance - -extents.height) >> 1); + else + origin = font_extents.ascender; + + origin_cache->set (*first_glyph, font->y_scale < 0 ? -origin : origin); + } + *first_y = origin; + + first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); + first_y = &StructAtOffsetUnaligned (first_y, y_stride); + } + } + + ot_font->v_origin.release_origin_cache (origin_cache); return true; } #endif @@ -434,6 +815,9 @@ hb_ot_get_glyph_extents (hb_font_t *font, #endif #if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT) if (ot_face->COLR->get_extents (font, glyph, extents)) return true; +#endif +#ifndef HB_NO_VAR_COMPOSITES + if (ot_face->VARC->get_extents (font, glyph, extents)) return true; #endif if (ot_face->glyf->get_extents (font, glyph, extents)) return true; #ifndef HB_NO_OT_FONT_CFF @@ -485,16 +869,9 @@ hb_ot_get_font_h_extents (hb_font_t *font, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - bool ret = _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && - _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && - _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); - - /* Embolden */ - int y_shift = font->y_strength; - if (font->y_scale < 0) y_shift = -y_shift; - metrics->ascender += y_shift; - - return ret; + return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) && + _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) && + _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); } #ifndef HB_NO_VERTICAL @@ -511,71 +888,64 @@ hb_ot_get_font_v_extents (hb_font_t *font, #endif #ifndef HB_NO_DRAW -static void -hb_ot_draw_glyph (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_draw_funcs_t *draw_funcs, void *draw_data, - void *user_data) +static hb_bool_t +hb_ot_draw_glyph_or_fail (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_draw_funcs_t *draw_funcs, void *draw_data, + void *user_data) { - bool embolden = font->x_strength || font->y_strength; - hb_outline_t outline; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + hb_draw_session_t draw_session {draw_funcs, draw_data}; + bool ret = false; + + OT::hb_scalar_cache_t *gvar_cache = nullptr; + if (font->num_coords) + { + ot_font->check_serial (font); + gvar_cache = ot_font->draw.acquire_gvar_cache (*ot_font->ot_face->gvar); + } - { // Need draw_session to be destructed before emboldening. - hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs, - embolden ? &outline : draw_data, font->slant_xy); #ifndef HB_NO_VAR_COMPOSITES - if (!font->face->table.VARC->get_path (font, glyph, draw_session)) + if (font->face->table.VARC->get_path (font, glyph, draw_session)) { ret = true; goto done; } #endif - // Keep the following in synch with VARC::get_path_at() - if (!font->face->table.glyf->get_path (font, glyph, draw_session)) + // Keep the following in synch with VARC::get_path_at() + if (font->face->table.glyf->get_path (font, glyph, draw_session, gvar_cache)) { ret = true; goto done; } + #ifndef HB_NO_CFF - if (!font->face->table.cff2->get_path (font, glyph, draw_session)) - if (!font->face->table.cff1->get_path (font, glyph, draw_session)) + if (font->face->table.cff2->get_path (font, glyph, draw_session)) { ret = true; goto done; } + if (font->face->table.cff1->get_path (font, glyph, draw_session)) { ret = true; goto done; } #endif - {} - } - if (embolden) - { - float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2; - float y_shift = (float) font->y_strength / 2; - if (font->x_scale < 0) x_shift = -x_shift; - if (font->y_scale < 0) y_shift = -y_shift; - outline.embolden (font->x_strength, font->y_strength, - x_shift, y_shift); - - outline.replay (draw_funcs, draw_data); - } +done: + + ot_font->draw.release_gvar_cache (gvar_cache); + + return ret; } #endif #ifndef HB_NO_PAINT -static void -hb_ot_paint_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_paint_funcs_t *paint_funcs, void *paint_data, - unsigned int palette, - hb_color_t foreground, - void *user_data) +static hb_bool_t +hb_ot_paint_glyph_or_fail (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_paint_funcs_t *paint_funcs, void *paint_data, + unsigned int palette, + hb_color_t foreground, + void *user_data) { #ifndef HB_NO_COLOR - if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return; - if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return; -#ifndef HB_NO_OT_FONT_BITMAP - if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return; - if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return; -#endif + if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return true; +#ifndef HB_NO_SVG + if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return true; #endif -#ifndef HB_NO_VAR_COMPOSITES - if (font->face->table.VARC->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; +#ifndef HB_NO_OT_FONT_BITMAP + if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return true; + if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return true; #endif - if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; -#ifndef HB_NO_CFF - if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; - if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return; #endif + return false; } #endif @@ -593,20 +963,19 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t &new_to_old_gid_list, + hb_array_t new_to_old_gid_list, unsigned num_glyphs) { TRACE_SERIALIZE (this); diff --git a/thirdparty/harfbuzz/upstream/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-hmtx-table.hh index 493bc6e7a..99ea38042 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-hmtx-table.hh @@ -45,16 +45,6 @@ #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x') -HB_INTERNAL bool -_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, int *lsb); - -HB_INTERNAL unsigned -_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); - -HB_INTERNAL bool -_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb); - - namespace OT { @@ -182,7 +172,7 @@ struct hmtxvmtx hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, Iterator it, - const hb_vector_t new_to_old_gid_list, + hb_array_t new_to_old_gid_list, unsigned num_long_metrics, unsigned total_num_metrics) { @@ -237,7 +227,7 @@ struct hmtxvmtx auto it = + hb_iter (c->plan->new_to_old_gid_list) - | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _) + | hb_map ([&_mtx, mtx_map] (hb_codepoint_pair_t _) { hb_codepoint_t new_gid = _.first; hb_codepoint_t old_gid = _.second; @@ -246,8 +236,7 @@ struct hmtxvmtx if (!mtx_map->has (new_gid, &v)) { int lsb = 0; - if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb); + _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); } return *v; @@ -326,43 +315,23 @@ struct hmtxvmtx bool has_data () const { return (bool) num_bearings; } - bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + void get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, int *lsb) const { if (glyph < num_long_metrics) { *lsb = table->longMetricZ[glyph].sb; - return true; + return; } if (unlikely (glyph >= num_bearings)) - return false; - - const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; - *lsb = bearings[glyph - num_long_metrics]; - return true; - } - - bool get_leading_bearing_with_var_unscaled (hb_font_t *font, - hb_codepoint_t glyph, - int *lsb) const - { - if (!font->num_coords) - return get_leading_bearing_without_var_unscaled (glyph, lsb); - -#ifndef HB_NO_VAR - float delta; - if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) && - get_leading_bearing_without_var_unscaled (glyph, lsb)) { - *lsb += roundf (delta); - return true; + *lsb = 0; + return; } - return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb); -#else - return false; -#endif + const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; + *lsb = bearings[glyph - num_long_metrics]; } unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const @@ -396,27 +365,17 @@ struct hmtxvmtx return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; } - unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, - hb_font_t *font, - ItemVariationStore::cache_t *store_cache = nullptr) const +#ifndef HB_NO_VAR + unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, + hb_font_t *font, + hb_scalar_cache_t *store_cache = nullptr) const { unsigned int advance = get_advance_without_var_unscaled (glyph); - -#ifndef HB_NO_VAR - if (unlikely (glyph >= num_bearings) || !font->num_coords) - return advance; - - if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_delta_unscaled (glyph, - font->coords, font->num_coords, - store_cache)); - - unsigned glyf_advance = _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); - return glyf_advance ? glyf_advance : advance; -#else - return advance; -#endif + return hb_max(0.0f, advance + roundf (var_table->get_advance_delta_unscaled (glyph, + font->coords, font->num_coords, + store_cache))); } +#endif protected: // 0 <= num_long_metrics <= num_bearings <= num_advances <= num_glyphs diff --git a/thirdparty/harfbuzz/upstream/hb-ot-kern-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-kern-table.hh index 2abda78af..229c6d2fe 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-kern-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-kern-table.hh @@ -27,6 +27,7 @@ #ifndef HB_OT_KERN_TABLE_HH #define HB_OT_KERN_TABLE_HH +#include "hb-aat-layout-common.hh" #include "hb-aat-layout-kerx-table.hh" @@ -89,11 +90,11 @@ struct KernSubTableFormat3 template void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const { - set_t set; if (likely (glyphCount)) - set.add_range (0, glyphCount - 1); - left_set.union_ (set); - right_set.union_ (set); + { + left_set.add_range (0, num_glyphs - 1); + right_set.add_range (0, num_glyphs - 1); + } } protected: @@ -305,8 +306,8 @@ struct kern { static constexpr hb_tag_t tableTag = HB_OT_TAG_kern; - bool has_data () const { return u.version32; } - unsigned get_type () const { return u.major; } + bool has_data () const { return u.version32.v; } + unsigned get_type () const { return u.major.v; } bool has_state_machine () const { @@ -342,7 +343,7 @@ struct kern } bool apply (AAT::hb_aat_apply_context_t *c, - const AAT::kern_accelerator_data_t *accel_data = nullptr) const + const AAT::kern_accelerator_data_t &accel_data) const { return dispatch (c, accel_data); } template @@ -362,7 +363,7 @@ struct kern bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.version32.sanitize (c)) return_trace (false); + if (!u.version32.v.sanitize (c)) return_trace (false); hb_barrier (); return_trace (dispatch (c)); } @@ -395,24 +396,25 @@ struct kern bool apply (AAT::hb_aat_apply_context_t *c) const { - return table->apply (c, &accel_data); + return table->apply (c, accel_data); } hb_blob_ptr_t table; AAT::kern_accelerator_data_t accel_data; + AAT::hb_aat_scratch_t scratch; }; protected: union { - HBUINT32 version32; - HBUINT16 major; + struct { HBUINT32 v; } version32; + struct { HBUINT16 v; } major; KernOT ot; #ifndef HB_NO_AAT_SHAPE KernAAT aat; #endif } u; public: - DEFINE_SIZE_UNION (4, version32); + DEFINE_SIZE_UNION (4, version32.v); }; struct kern_accelerator_t : kern::accelerator_t { diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-layout-base-table.hh index 68a4e7cba..2470e7e2f 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout-base-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout-base-table.hh @@ -165,13 +165,13 @@ struct BaseCoordFormat3 struct BaseCoord { - bool has_data () const { return u.format; } + bool has_data () const { return u.format.v; } hb_position_t get_coord (hb_font_t *font, const ItemVariationStore &var_store, hb_direction_t direction) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_coord (font, direction); case 2: hb_barrier (); return u.format2.get_coord (font, direction); case 3: hb_barrier (); return u.format3.get_coord (font, var_store, direction); @@ -181,8 +181,8 @@ struct BaseCoord void collect_variation_indices (hb_set_t& varidx_set /* OUT */) const { - switch (u.format) { - case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); + switch (u.format.v) { + case 3: hb_barrier (); u.format3.collect_variation_indices (varidx_set); return; default:return; } } @@ -190,9 +190,9 @@ struct BaseCoord template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -203,9 +203,9 @@ struct BaseCoord bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.format.sanitize (c))) return_trace (false); + if (unlikely (!u.format.v.sanitize (c))) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); @@ -215,13 +215,13 @@ struct BaseCoord protected: union { - HBUINT16 format; + struct { HBUINT16 v; } format; BaseCoordFormat1 format1; BaseCoordFormat2 format2; BaseCoordFormat3 format3; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; struct FeatMinMaxRecord @@ -460,7 +460,7 @@ struct BaseScript { return (this+baseValues).get_base_coord (baseline_tag_index); } bool has_values () const { return baseValues; } - bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ } + bool has_min_max () const { return defaultMinMax || baseLangSysRecords; } void collect_variation_indices (const hb_subset_plan_t* plan, hb_set_t& varidx_set /* OUT */) const diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout-common.hh b/thirdparty/harfbuzz/upstream/hb-ot-layout-common.hh index 757b05031..a9c03db3e 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout-common.hh @@ -34,6 +34,7 @@ #include "hb-open-type.hh" #include "hb-set.hh" #include "hb-bimap.hh" +#include "hb-cache.hh" #include "OT/Layout/Common/Coverage.hh" #include "OT/Layout/types.hh" @@ -140,6 +141,7 @@ struct hb_subset_layout_context_t : const hb_map_t *lookup_index_map; const hb_hashmap_t> *script_langsys_map; const hb_map_t *feature_index_map; + const hb_map_t *feature_map_w_duplicates; const hb_hashmap_t *feature_substitutes_map; hb_hashmap_t> *feature_record_cond_idx_map; const hb_set_t *catch_all_record_feature_idxes; @@ -164,6 +166,7 @@ struct hb_subset_layout_context_t : lookup_index_map = &c_->plan->gsub_lookups; script_langsys_map = &c_->plan->gsub_langsys; feature_index_map = &c_->plan->gsub_features; + feature_map_w_duplicates = &c_->plan->gsub_features_w_duplicates; feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map; catch_all_record_feature_idxes = &c_->plan->gsub_old_features; @@ -174,6 +177,7 @@ struct hb_subset_layout_context_t : lookup_index_map = &c_->plan->gpos_lookups; script_langsys_map = &c_->plan->gpos_langsys; feature_index_map = &c_->plan->gpos_features; + feature_map_w_duplicates = &c_->plan->gpos_features_w_duplicates; feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map; feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map; catch_all_record_feature_idxes = &c_->plan->gpos_old_features; @@ -824,46 +828,9 @@ struct Feature const Record_sanitize_closure_t *closure = nullptr) const { TRACE_SANITIZE (this); - if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) - return_trace (false); - hb_barrier (); - - /* Some earlier versions of Adobe tools calculated the offset of the - * FeatureParams subtable from the beginning of the FeatureList table! - * - * If sanitizing "failed" for the FeatureParams subtable, try it with the - * alternative location. We would know sanitize "failed" if old value - * of the offset was non-zero, but it's zeroed now. - * - * Only do this for the 'size' feature, since at the time of the faulty - * Adobe tools, only the 'size' feature had FeatureParams defined. - */ - - if (likely (featureParams.is_null ())) - return_trace (true); - - unsigned int orig_offset = featureParams; - if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) - return_trace (false); - hb_barrier (); - - if (featureParams == 0 && closure && - closure->tag == HB_TAG ('s','i','z','e') && - closure->list_base && closure->list_base < this) - { - unsigned int new_offset_int = orig_offset - - (((char *) this) - ((char *) closure->list_base)); - - Offset16To new_offset; - /* Check that it would not overflow. */ - new_offset = new_offset_int; - if (new_offset == new_offset_int && - c->try_set (&featureParams, new_offset_int) && - !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) - return_trace (false); - } - - return_trace (true); + return_trace (c->check_struct (this) && + featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE) && + lookupIndex.sanitize (c)); } Offset16To @@ -1081,15 +1048,15 @@ struct LangSys if (unlikely (!c->serializer->extend_min (out))) return_trace (false); const uint32_t *v; - out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; + out->reqFeatureIndex = l->feature_map_w_duplicates->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; if (!l->visitFeatureIndex (featureIndex.len)) return_trace (false); auto it = + hb_iter (featureIndex) - | hb_filter (l->feature_index_map) - | hb_map (l->feature_index_map) + | hb_filter (l->feature_map_w_duplicates) + | hb_map (l->feature_map_w_duplicates) ; bool ret = bool (it); @@ -1336,7 +1303,7 @@ struct Lookup TRACE_DISPATCH (this, lookup_type); unsigned int count = get_subtable_count (); for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, std::forward (ds)...); + typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, ds...); if (c->stop_sublookup_iteration (r)) return_trace (r); } @@ -1386,6 +1353,11 @@ struct Lookup { unsigned new_flag = lookupFlag; new_flag &= ~LookupFlag::UseMarkFilteringSet; + // https://github.com/harfbuzz/harfbuzz/issues/5499 + // If we remove UseMarkFilteringSet flag because the set is now empty, + // we need to add IgnoreMarks flag, otherwise the lookup will not + // ignore any marks, which changes the behavior. + new_flag |= LookupFlag::IgnoreMarks; out->lookupFlag = new_flag; } else @@ -1424,7 +1396,7 @@ struct Lookup if (unlikely (!get_subtables ().sanitize (c, this, get_type ()))) return_trace (false); - if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) + if (unlikely (get_type () == TSubTable::Extension)) { hb_barrier (); @@ -1432,11 +1404,6 @@ struct Lookup * have the same type, which shall not be the Extension type * itself (but we already checked for that). * This is specially important if one has a reverse type! - * - * We only do this if sanitizer edit_count is zero. Otherwise, - * some of the subtables might have become insane after they - * were sanity-checked by the edits of subsequent subtables. - * https://bugs.chromium.org/p/chromium/issues/detail?id=960331 */ unsigned int type = get_subtable (0).u.extension.get_type (); for (unsigned int i = 1; i < subtables; i++) @@ -1849,7 +1816,7 @@ struct ClassDefFormat2_4 hb_sorted_vector_t glyph_and_klass; hb_set_t orig_klasses; - if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2 + if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) < get_population ()) { for (hb_codepoint_t g : glyph_set) @@ -1930,7 +1897,7 @@ struct ClassDefFormat2_4 bool intersects (const hb_set_t *glyphs) const { - if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len)) { for (auto g : *glyphs) if (get_class (g)) @@ -1999,7 +1966,7 @@ struct ClassDefFormat2_4 } unsigned count = rangeRecord.len; - if (count > glyphs->get_population () * hb_bit_storage (count) * 8) + if (count > glyphs->get_population () * hb_bit_storage (count)) { for (auto g : *glyphs) { @@ -2066,7 +2033,7 @@ struct ClassDef unsigned int get (hb_codepoint_t k) const { return get_class (k); } unsigned int get_class (hb_codepoint_t glyph_id) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_class (glyph_id); case 2: hb_barrier (); return u.format2.get_class (glyph_id); #ifndef HB_NO_BEYOND_64K @@ -2076,10 +2043,19 @@ struct ClassDef default:return 0; } } + unsigned int get_class (hb_codepoint_t glyph_id, + hb_ot_layout_mapping_cache_t *cache) const + { + unsigned klass; + if (cache && cache->get (glyph_id, &klass)) return klass; + klass = get_class (glyph_id); + if (cache) cache->set (glyph_id, klass); + return klass; + } unsigned get_population () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_population (); case 2: hb_barrier (); return u.format2.get_population (); #ifndef HB_NO_BEYOND_64K @@ -2132,7 +2108,7 @@ struct ClassDef #ifndef HB_NO_BEYOND_64K if (glyph_max > 0xFFFFu) - u.format += 2; + u.format.v += 2; if (unlikely (glyph_max > 0xFFFFFFu)) #else if (unlikely (glyph_max > 0xFFFFu)) @@ -2142,9 +2118,9 @@ struct ClassDef return_trace (false); } - u.format = format; + u.format.v = format; - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.serialize (c, it)); case 2: hb_barrier (); return_trace (u.format2.serialize (c, it)); @@ -2163,7 +2139,7 @@ struct ClassDef const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); case 2: hb_barrier (); return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); #ifndef HB_NO_BEYOND_64K @@ -2177,9 +2153,9 @@ struct ClassDef bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); #ifndef HB_NO_BEYOND_64K @@ -2192,7 +2168,7 @@ struct ClassDef unsigned cost () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.cost (); case 2: hb_barrier (); return u.format2.cost (); #ifndef HB_NO_BEYOND_64K @@ -2208,7 +2184,7 @@ struct ClassDef template bool collect_coverage (set_t *glyphs) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.collect_coverage (glyphs); case 2: hb_barrier (); return u.format2.collect_coverage (glyphs); #ifndef HB_NO_BEYOND_64K @@ -2224,7 +2200,7 @@ struct ClassDef template bool collect_class (set_t *glyphs, unsigned int klass) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.collect_class (glyphs, klass); case 2: hb_barrier (); return u.format2.collect_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K @@ -2237,7 +2213,7 @@ struct ClassDef bool intersects (const hb_set_t *glyphs) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersects (glyphs); case 2: hb_barrier (); return u.format2.intersects (glyphs); #ifndef HB_NO_BEYOND_64K @@ -2249,7 +2225,7 @@ struct ClassDef } bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersects_class (glyphs, klass); case 2: hb_barrier (); return u.format2.intersects_class (glyphs, klass); #ifndef HB_NO_BEYOND_64K @@ -2262,7 +2238,7 @@ struct ClassDef void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); case 2: hb_barrier (); return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); #ifndef HB_NO_BEYOND_64K @@ -2275,7 +2251,7 @@ struct ClassDef void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.intersected_classes (glyphs, intersect_classes); case 2: hb_barrier (); return u.format2.intersected_classes (glyphs, intersect_classes); #ifndef HB_NO_BEYOND_64K @@ -2289,7 +2265,7 @@ struct ClassDef protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ClassDefFormat1_3 format1; ClassDefFormat2_4 format2; #ifndef HB_NO_BEYOND_64K @@ -2298,7 +2274,7 @@ struct ClassDef #endif } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; template @@ -2316,139 +2292,168 @@ struct delta_row_encoding_t { /* each byte represents a region, value is one of 0/1/2/4, which means bytes * needed for this region */ - hb_vector_t chars; + struct chars_t : hb_vector_t + { + int cmp (const chars_t& other) const + { + return as_array ().cmp (other.as_array ()); + } + + hb_pair_t get_width () + { + unsigned width = 0; + unsigned columns = 0; + for (unsigned i = 0; i < length; i++) + { + unsigned v = arrayZ[i]; + width += v; + columns += (v != 0); + } + return hb_pair (width, columns); + } + + HB_HOT + hb_pair_t combine_width (const chars_t& other) const + { + unsigned combined_width = 0; + unsigned combined_columns = 0; + for (unsigned i = 0; i < length; i++) + { + unsigned v = hb_max (arrayZ[i], other.arrayZ[i]); + combined_width += v; + combined_columns += (v != 0); + } + return hb_pair (combined_width, combined_columns); + } + }; + + hb_pair_t combine_width (const delta_row_encoding_t& other_encoding) const { return chars.combine_width (other_encoding.chars); } + + // Actual data + + chars_t chars; unsigned width = 0; - hb_vector_t columns; unsigned overhead = 0; hb_vector_t*> items; delta_row_encoding_t () = default; - delta_row_encoding_t (hb_vector_t&& chars_, - const hb_vector_t* row = nullptr) : - delta_row_encoding_t () + delta_row_encoding_t (hb_vector_t*> &&rows, unsigned num_cols) + { + assert (rows); + + items = std::move (rows); + + if (unlikely (!chars.resize (num_cols))) + return; + + calculate_chars (); + } + void merge (const delta_row_encoding_t& other) { - chars = std::move (chars_); - width = get_width (); - columns = get_columns (); - overhead = get_chars_overhead (columns); - if (row) items.push (row); + items.alloc (items.length + other.items.length); + for (auto &row : other.items) + add_row (row); + + // Merge chars + assert (chars.length == other.chars.length); + for (unsigned i = 0; i < chars.length; i++) + chars.arrayZ[i] = hb_max (chars.arrayZ[i], other.chars.arrayZ[i]); + chars_changed (); } - bool is_empty () const - { return !items; } + void chars_changed () + { + auto _ = chars.get_width (); + width = _.first; + overhead = get_chars_overhead (_.second); + } - static hb_vector_t get_row_chars (const hb_vector_t& row) + void calculate_chars () { - hb_vector_t ret; - if (!ret.alloc (row.length)) return ret; + assert (items); bool long_words = false; - /* 0/1/2 byte encoding */ - for (int i = row.length - 1; i >= 0; i--) + for (auto &row : items) { - int v = row.arrayZ[i]; - if (v == 0) - ret.push (0); - else if (v > 32767 || v < -32768) + assert (row->length == chars.length); + + /* 0/1/2 byte encoding */ + for (unsigned i = 0; i < row->length; i++) { - long_words = true; - break; + int v = row->arrayZ[i]; + if (v == 0) + continue; + else if (v > 32767 || v < -32768) + { + long_words = true; + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 4); + } + else if (v > 127 || v < -128) + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 2); + else + chars.arrayZ[i] = hb_max (chars.arrayZ[i], 1); } - else if (v > 127 || v < -128) - ret.push (2); - else - ret.push (1); } - if (!long_words) - return ret; - - /* redo, 0/2/4 bytes encoding */ - ret.reset (); - for (int i = row.length - 1; i >= 0; i--) + if (long_words) { - int v = row.arrayZ[i]; - if (v == 0) - ret.push (0); - else if (v > 32767 || v < -32768) - ret.push (4); - else - ret.push (2); + // Convert 1s to 2s + for (auto &v : chars) + if (v == 1) + v = 2; } - return ret; - } - inline unsigned get_width () - { - unsigned ret = + hb_iter (chars) - | hb_reduce (hb_add, 0u) - ; - return ret; + chars_changed (); } - hb_vector_t get_columns () - { - hb_vector_t cols; - cols.alloc (chars.length); - for (auto v : chars) - { - uint8_t flag = v ? 1 : 0; - cols.push (flag); - } - return cols; - } + bool is_empty () const + { return !items; } - static inline unsigned get_chars_overhead (const hb_vector_t& cols) + static inline unsigned get_chars_overhead (unsigned num_columns) { unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header - unsigned cols_bit_count = 0; - for (auto v : cols) - if (v) cols_bit_count++; - return c + cols_bit_count * 2; + return c + num_columns * 2; } - unsigned get_gain () const + unsigned get_gain (unsigned additional_bytes_per_rows = 1) const { int count = items.length; - return hb_max (0, (int) overhead - count); + return hb_max (0, (int) overhead - count * (int) additional_bytes_per_rows); } int gain_from_merging (const delta_row_encoding_t& other_encoding) const { - int combined_width = 0; - for (unsigned i = 0; i < chars.length; i++) - combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]); + // Back of the envelope calculations to reject early. + signed additional_bytes_per_rows = other_encoding.width - width; + if (additional_bytes_per_rows > 0) + { + if (get_gain (additional_bytes_per_rows) == 0) + return 0; + } + else + { + if (other_encoding.get_gain (-additional_bytes_per_rows) == 0) + return 0; + } - hb_vector_t combined_columns; - combined_columns.alloc (columns.length); - for (unsigned i = 0; i < columns.length; i++) - combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]); + auto pair = combine_width (other_encoding); + unsigned combined_width = pair.first; + unsigned combined_columns = pair.second; - int combined_overhead = get_chars_overhead (combined_columns); - int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead - - (combined_width - (int) width) * items.length - - (combined_width - (int) other_encoding.width) * other_encoding.items.length; + int combined_gain = (int) overhead + (int) other_encoding.overhead; + combined_gain -= (combined_width - (int) width) * items.length; + combined_gain -= (combined_width - (int) other_encoding.width) * other_encoding.items.length; + combined_gain -= get_chars_overhead (combined_columns); return combined_gain; } - static int cmp (const void *pa, const void *pb) - { - const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; - const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; - - int gain_a = a->get_gain (); - int gain_b = b->get_gain (); - - if (gain_a != gain_b) - return gain_a - gain_b; - - return (b->chars).as_array ().cmp ((a->chars).as_array ()); - } + bool add_row (const hb_vector_t* row) + { return items.push (row); } - static int cmp_width (const void *pa, const void *pb) + static int cmp (const void *pa, const void *pb) { const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; @@ -2456,11 +2461,8 @@ struct delta_row_encoding_t if (a->width != b->width) return (int) a->width - (int) b->width; - return (b->chars).as_array ().cmp ((a->chars).as_array ()); + return b->chars.cmp (a->chars); } - - bool add_row (const hb_vector_t* row) - { return items.push (row); } }; struct VarRegionAxis @@ -2538,30 +2540,113 @@ struct SparseVarRegionAxis DEFINE_SIZE_STATIC (8); }; -#define REGION_CACHE_ITEM_CACHE_INVALID 2.f - -struct VarRegionList +struct hb_scalar_cache_t { - using cache_t = float; + private: + static constexpr unsigned STATIC_LENGTH = 128; + static constexpr int INVALID = INT_MIN; + static constexpr float MULTIPLIER = 1 << ((sizeof (int) * 8) - 2); + static constexpr float DIVISOR = 1.f / MULTIPLIER; - float evaluate (unsigned int region_index, - const int *coords, unsigned int coord_len, - cache_t *cache = nullptr) const + public: + hb_scalar_cache_t () {} + + hb_scalar_cache_t (const hb_scalar_cache_t&) = delete; + hb_scalar_cache_t (hb_scalar_cache_t&&) = delete; + hb_scalar_cache_t& operator= (const hb_scalar_cache_t&) = delete; + hb_scalar_cache_t& operator= (hb_scalar_cache_t&&) = delete; + + static hb_scalar_cache_t *create (unsigned int count, + hb_scalar_cache_t *scratch_cache = nullptr) { - if (unlikely (region_index >= regionCount)) - return 0.; + if (!count) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); - float *cached_value = nullptr; - if (cache) + if (scratch_cache && count <= STATIC_LENGTH) + { + scratch_cache->length = count; + scratch_cache->clear (); + return scratch_cache; + } + + auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (static_values) + sizeof (static_values[0]) * count); + if (unlikely (!cache)) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t); + + cache->length = count; + cache->clear (); + + return cache; + } + + static void destroy (hb_scalar_cache_t *cache, + hb_scalar_cache_t *scratch_cache = nullptr) + { + if (cache != &Null(hb_scalar_cache_t) && cache != scratch_cache) + hb_free (cache); + } + + void clear () + { + auto *values = &static_values[0]; + unsigned i = 0; +#ifndef HB_OPTIMIZE_SIZE + for (; i + 3 < length; i += 4) + { + values[i + 0] = INVALID; + values[i + 1] = INVALID; + values[i + 2] = INVALID; + values[i + 3] = INVALID; + } +#endif + for (; i < length; i++) + values[i] = INVALID; + } + + HB_ALWAYS_INLINE + bool get (unsigned i, float *value) const + { + if (unlikely (i >= length)) { - cached_value = &(cache[region_index]); - if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) - return *cached_value; + *value = 0.f; + return true; } + auto *values = &static_values[0]; + auto *cached_value = &values[i]; + // Super hot. Most common path is that we have a cached value of 0. + int v = *cached_value; + if (likely (!v)) + { + *value = 0.f; + return true; + } + if (v == INVALID) + return false; + *value = v * DIVISOR; + return true; + } + + HB_ALWAYS_INLINE + void set (unsigned i, float value) + { + if (unlikely (i >= length)) return; + auto *values = &static_values[0]; + auto *cached_value = &values[i]; + *cached_value = roundf(value * MULTIPLIER); + } + + private: + unsigned length; + mutable hb_atomic_t static_values[STATIC_LENGTH]; +}; +struct VarRegionList +{ + private: + float evaluate_impl (unsigned int region_index, + const int *coords, unsigned int coord_len) const + { const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); + float v = 1.f; - float v = 1.; unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { @@ -2569,15 +2654,32 @@ struct VarRegionList float factor = axes[i].evaluate (coord); if (factor == 0.f) { - if (cache) - *cached_value = 0.; - return 0.; + v = 0.f; + break; } v *= factor; } + return v; + } + + public: + HB_ALWAYS_INLINE + float evaluate (unsigned int region_index, + const int *coords, unsigned int coord_len, + hb_scalar_cache_t *cache = nullptr) const + { + if (unlikely (region_index >= regionCount)) + return 0.; + + float v; + if (cache && cache->get (region_index, &v)) + return v; + + v = evaluate_impl (region_index, coords, coord_len); + if (cache) - *cached_value = v; + cache->set (region_index, v); return v; } @@ -2720,29 +2822,24 @@ struct SparseVariationRegion : Array16Of struct SparseVarRegionList { - using cache_t = float; - + HB_ALWAYS_INLINE float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, - cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { if (unlikely (region_index >= regions.len)) return 0.; - float *cached_value = nullptr; - if (cache) - { - cached_value = &(cache[region_index]); - if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID)) - return *cached_value; - } + float v; + if (cache && cache->get (region_index, &v)) + return v; const SparseVariationRegion ®ion = this+regions[region_index]; - float v = region.evaluate (coords, coord_len); - + v = region.evaluate (coords, coord_len); if (cache) - *cached_value = v; + cache->set (region_index, v); + return v; } @@ -2780,46 +2877,62 @@ struct VarData + itemCount * get_row_size (); } - float get_delta (unsigned int inner, - const int *coords, unsigned int coord_count, - const VarRegionList ®ions, - VarRegionList::cache_t *cache = nullptr) const + float _get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + hb_scalar_cache_t *cache = nullptr) const { if (unlikely (inner >= itemCount)) return 0.; + bool is_long = longWords (); + unsigned int count = regionIndices.len; + unsigned word_count = wordCount (); + unsigned int scount = is_long ? count : word_count; + unsigned int lcount = is_long ? word_count : 0; - unsigned int count = regionIndices.len; - bool is_long = longWords (); - unsigned word_count = wordCount (); - unsigned int scount = is_long ? count : word_count; - unsigned int lcount = is_long ? word_count : 0; + const HBUINT8 *bytes = get_delta_bytes (); + const HBUINT8 *row = bytes + inner * get_row_size (); - const HBUINT8 *bytes = get_delta_bytes (); - const HBUINT8 *row = bytes + inner * get_row_size (); + float delta = 0.; + unsigned int i = 0; - float delta = 0.; - unsigned int i = 0; + const HBINT32 *lcursor = reinterpret_cast (row); + for (; i < lcount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *lcursor; + lcursor++; + } + const HBINT16 *scursor = reinterpret_cast (lcursor); + for (; i < scount; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *scursor; + scursor++; + } + const HBINT8 *bcursor = reinterpret_cast (scursor); + for (; i < count; i++) + { + float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); + if (scalar) + delta += scalar * *bcursor; + bcursor++; + } - const HBINT32 *lcursor = reinterpret_cast (row); - for (; i < lcount; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *lcursor++; - } - const HBINT16 *scursor = reinterpret_cast (lcursor); - for (; i < scount; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *scursor++; - } - const HBINT8 *bcursor = reinterpret_cast (scursor); - for (; i < count; i++) - { - float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache); - delta += scalar * *bcursor++; - } + return delta; + } - return delta; + HB_ALWAYS_INLINE + float get_delta (unsigned int inner, + const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + hb_scalar_cache_t *cache = nullptr) const + { + unsigned int count = regionIndices.len; + if (!count) return 0.f; // This is quite common, so optimize it. + return _get_delta (inner, coords, coord_count, regions, cache); } void get_region_scalars (const int *coords, unsigned int coord_count, @@ -2851,9 +2964,16 @@ struct VarData const hb_vector_t*>& rows) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); unsigned row_count = rows.length; - itemCount = row_count; + if (!row_count) { + // Nothing to serialize, will be empty. + return false; + } + + if (unlikely (!c->extend_min (this))) return_trace (false); + if (unlikely (!c->check_assign (itemCount, row_count, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); int min_threshold = has_long ? -65536 : -128; int max_threshold = has_long ? +65535 : +127; @@ -3133,27 +3253,30 @@ struct MultiVarData const int *coords, unsigned int coord_count, const SparseVarRegionList ®ions, hb_array_t out, - SparseVarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { auto &deltaSets = StructAfter (regionIndices); - auto values_iter = deltaSets[inner]; - + auto values_iter = deltaSets.fetcher (inner); unsigned regionCount = regionIndices.len; - unsigned count = out.length; + unsigned skip = 0; for (unsigned regionIndex = 0; regionIndex < regionCount; regionIndex++) { float scalar = regions.evaluate (regionIndices.arrayZ[regionIndex], coords, coord_count, cache); - if (scalar == 1.f) - for (unsigned i = 0; i < count; i++) - out.arrayZ[i] += *values_iter++; - else if (scalar) - for (unsigned i = 0; i < count; i++) - out.arrayZ[i] += *values_iter++ * scalar; + // We skip lazily. Helps with the tail end. + if (scalar == 0.0f) + skip += out.length; else - values_iter += count; + { + if (skip) + { + values_iter.skip (skip); + skip = 0; + } + values_iter.add_to (out, scalar); + } } } @@ -3179,31 +3302,24 @@ struct MultiVarData struct ItemVariationStore { friend struct item_variations_t; - using cache_t = VarRegionList::cache_t; - cache_t *create_cache () const + hb_scalar_cache_t *create_cache () const { #ifdef HB_NO_VAR - return nullptr; + return hb_scalar_cache_t::create (0); #endif - auto &r = this+regions; - unsigned count = r.regionCount; - - float *cache = (float *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; - - for (unsigned i = 0; i < count; i++) - cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; - - return cache; + return hb_scalar_cache_t::create ((this+regions).regionCount); } - static void destroy_cache (cache_t *cache) { hb_free (cache); } + static void destroy_cache (hb_scalar_cache_t *cache) + { + hb_scalar_cache_t::destroy (cache); + } private: float get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return 0.f; @@ -3221,7 +3337,7 @@ struct ItemVariationStore public: float get_delta (unsigned int index, const int *coords, unsigned int coord_count, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; @@ -3229,7 +3345,7 @@ struct ItemVariationStore } float get_delta (unsigned int index, hb_array_t coords, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { return get_delta (index, coords.arrayZ, coords.length, @@ -3348,7 +3464,7 @@ struct ItemVariationStore for (unsigned i = 0; i < count; i++) { hb_inc_bimap_t *map = inner_maps.push (); - if (!c->propagate_error(inner_maps)) + if (unlikely (!c->propagate_error(inner_maps))) return_trace(nullptr); auto &data = this+dataSets[i]; @@ -3437,32 +3553,28 @@ struct ItemVariationStore struct MultiItemVariationStore { - using cache_t = SparseVarRegionList::cache_t; - - cache_t *create_cache () const + hb_scalar_cache_t *create_cache (hb_scalar_cache_t *static_cache = nullptr) const { #ifdef HB_NO_VAR - return nullptr; + return hb_scalar_cache_t::create (0); #endif auto &r = this+regions; unsigned count = r.regions.len; - float *cache = (float *) hb_malloc (sizeof (float) * count); - if (unlikely (!cache)) return nullptr; - - for (unsigned i = 0; i < count; i++) - cache[i] = REGION_CACHE_ITEM_CACHE_INVALID; - - return cache; + return hb_scalar_cache_t::create (count, static_cache); } - static void destroy_cache (cache_t *cache) { hb_free (cache); } + static void destroy_cache (hb_scalar_cache_t *cache, + hb_scalar_cache_t *static_cache = nullptr) + { + hb_scalar_cache_t::destroy (cache, static_cache); + } private: void get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { #ifdef HB_NO_VAR return; @@ -3482,7 +3594,7 @@ struct MultiItemVariationStore void get_delta (unsigned int index, const int *coords, unsigned int coord_count, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { unsigned int outer = index >> 16; unsigned int inner = index & 0xFFFF; @@ -3491,7 +3603,7 @@ struct MultiItemVariationStore void get_delta (unsigned int index, hb_array_t coords, hb_array_t out, - VarRegionList::cache_t *cache = nullptr) const + hb_scalar_cache_t *cache = nullptr) const { return get_delta (index, coords.arrayZ, coords.length, @@ -3521,8 +3633,6 @@ struct MultiItemVariationStore DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; -#undef REGION_CACHE_ITEM_CACHE_INVALID - template struct DeltaSetIndexMapFormat01 { @@ -3573,13 +3683,19 @@ struct DeltaSetIndexMapFormat01 return_trace (true); } + HB_ALWAYS_INLINE uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ { /* If count is zero, pass value unchanged. This takes * care of direct mapping for advance map. */ if (!mapCount) return v; + return _map (v); + } + HB_HOT + uint32_t _map (unsigned int v) const /* Returns 16.16 outer.inner. */ + { if (v >= mapCount) v = mapCount - 1; @@ -3635,8 +3751,8 @@ struct DeltaSetIndexMap { TRACE_SERIALIZE (this); unsigned length = plan.get_output_map ().length; - u.format = length <= 0xFFFF ? 0 : 1; - switch (u.format) { + u.format.v = length <= 0xFFFF ? 0 : 1; + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.serialize (c, plan)); case 1: hb_barrier (); return_trace (u.format1.serialize (c, plan)); default:return_trace (false); @@ -3645,7 +3761,7 @@ struct DeltaSetIndexMap uint32_t map (unsigned v) const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return (u.format0.map (v)); case 1: hb_barrier (); return (u.format1.map (v)); default:return v; @@ -3654,7 +3770,7 @@ struct DeltaSetIndexMap unsigned get_map_count () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_map_count (); case 1: hb_barrier (); return u.format1.get_map_count (); default:return 0; @@ -3663,7 +3779,7 @@ struct DeltaSetIndexMap unsigned get_width () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_width (); case 1: hb_barrier (); return u.format1.get_width (); default:return 0; @@ -3672,7 +3788,7 @@ struct DeltaSetIndexMap unsigned get_inner_bit_count () const { - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return u.format0.get_inner_bit_count (); case 1: hb_barrier (); return u.format1.get_inner_bit_count (); default:return 0; @@ -3682,9 +3798,9 @@ struct DeltaSetIndexMap bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (u.format0.sanitize (c)); case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); default:return_trace (true); @@ -3694,7 +3810,7 @@ struct DeltaSetIndexMap DeltaSetIndexMap* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); - switch (u.format) { + switch (u.format.v) { case 0: hb_barrier (); return_trace (reinterpret_cast (u.format0.copy (c))); case 1: hb_barrier (); return_trace (reinterpret_cast (u.format1.copy (c))); default:return_trace (nullptr); @@ -3703,12 +3819,12 @@ struct DeltaSetIndexMap protected: union { - HBUINT8 format; /* Format identifier */ + struct { HBUINT8 v; } format; /* Format identifier */ DeltaSetIndexMapFormat01 format0; DeltaSetIndexMapFormat01 format1; } u; public: - DEFINE_SIZE_UNION (1, format); + DEFINE_SIZE_UNION (1, format.v); }; @@ -3717,7 +3833,7 @@ struct ItemVarStoreInstancer ItemVarStoreInstancer (const ItemVariationStore *varStore_, const DeltaSetIndexMap *varIdxMap, hb_array_t coords, - VarRegionList::cache_t *cache = nullptr) : + hb_scalar_cache_t *cache = nullptr) : varStore (varStore_), varIdxMap (varIdxMap), coords (coords), cache (cache) { if (!varStore) @@ -3731,17 +3847,19 @@ struct ItemVarStoreInstancer float operator() (uint32_t varIdx, unsigned short offset = 0) const { + if (!coords || varIdx == VarIdx::NO_VARIATION) + return 0.f; + + varIdx += offset; if (varIdxMap) - varIdx = varIdxMap->map (VarIdx::add (varIdx, offset)); - else - varIdx += offset; - return coords ? varStore->get_delta (varIdx, coords, cache) : 0.f; + varIdx = varIdxMap->map (varIdx); + return varStore->get_delta (varIdx, coords, cache); } const ItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; - VarRegionList::cache_t *cache; + hb_scalar_cache_t *cache; }; struct MultiItemVarStoreInstancer @@ -3749,7 +3867,7 @@ struct MultiItemVarStoreInstancer MultiItemVarStoreInstancer (const MultiItemVariationStore *varStore, const DeltaSetIndexMap *varIdxMap, hb_array_t coords, - SparseVarRegionList::cache_t *cache = nullptr) : + hb_scalar_cache_t *cache = nullptr) : varStore (varStore), varIdxMap (varIdxMap), coords (coords), cache (cache) { if (!varStore) @@ -3767,12 +3885,11 @@ struct MultiItemVarStoreInstancer void operator() (hb_array_t out, uint32_t varIdx, unsigned short offset = 0) const { - if (coords) + if (coords && varIdx != VarIdx::NO_VARIATION) { + varIdx += offset; if (varIdxMap) - varIdx = varIdxMap->map (VarIdx::add (varIdx, offset)); - else - varIdx += offset; + varIdx = varIdxMap->map (varIdx); varStore->get_delta (varIdx, coords, out, cache); } else @@ -3783,7 +3900,7 @@ struct MultiItemVarStoreInstancer const MultiItemVariationStore *varStore; const DeltaSetIndexMap *varIdxMap; hb_array_t coords; - SparseVarRegionList::cache_t *cache; + hb_scalar_cache_t *cache; }; @@ -3890,8 +4007,8 @@ struct ConditionAxisRange { // add axisIndex->value into the hashmap so we can check if the record is // unique with variations - int16_t int_filter_max_val = filterRangeMaxValue.to_int (); - int16_t int_filter_min_val = filterRangeMinValue.to_int (); + uint16_t int_filter_max_val = (uint16_t) filterRangeMaxValue.to_int (); + uint16_t int_filter_min_val = (uint16_t) filterRangeMinValue.to_int (); hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val; condition_map->set (axisIndex, val); @@ -3939,7 +4056,7 @@ struct ConditionValue bool evaluate (const int *coords, unsigned int coord_len, Instancer *instancer) const { - signed value = defaultValue; + float value = defaultValue; value += (*instancer)[varIdx]; return value > 0; } @@ -4110,7 +4227,7 @@ struct Condition bool evaluate (const int *coords, unsigned int coord_len, Instancer *instancer) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.evaluate (coords, coord_len, instancer); case 2: hb_barrier (); return u.format2.evaluate (coords, coord_len, instancer); case 3: hb_barrier (); return u.format3.evaluate (coords, coord_len, instancer); @@ -4123,7 +4240,7 @@ struct Condition Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c, hb_map_t *condition_map /* OUT */) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.keep_with_variations (c, condition_map); // TODO(subset) default: c->apply = false; return KEEP_COND_WITH_VAR; @@ -4133,9 +4250,9 @@ struct Condition template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -4148,9 +4265,9 @@ struct Condition bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (!u.format.v.sanitize (c)) return_trace (false); hb_barrier (); - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); case 3: hb_barrier (); return_trace (u.format3.sanitize (c)); @@ -4162,7 +4279,7 @@ struct Condition protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ConditionAxisRange format1; ConditionValue format2; ConditionAnd format3; @@ -4170,7 +4287,7 @@ struct Condition ConditionNegate format5; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; template @@ -4333,7 +4450,7 @@ struct FeatureTableSubstitutionRecord if (unlikely (!s->extend_min (this))) return_trace (false); uint32_t *new_feature_idx; - if (!c->feature_index_map->has (feature_index, &new_feature_idx)) + if (!c->feature_map_w_duplicates->has (feature_index, &new_feature_idx)) return_trace (false); if (!s->check_assign (featureIndex, *new_feature_idx, HB_SERIALIZE_ERROR_INT_OVERFLOW)) @@ -4351,7 +4468,7 @@ struct FeatureTableSubstitutionRecord { TRACE_SUBSET (this); uint32_t *new_feature_index; - if (!c->feature_index_map->has (featureIndex, &new_feature_index)) + if (!c->feature_map_w_duplicates->has (featureIndex, &new_feature_index)) return_trace (false); auto *out = c->subset_context->serializer->embed (this); @@ -4625,7 +4742,7 @@ struct FeatureVariations int keep_up_to = -1; for (int i = varRecords.len - 1; i >= 0; i--) { - if (varRecords[i].intersects_features (this, l->feature_index_map)) { + if (varRecords[i].intersects_features (this, l->feature_map_w_duplicates)) { keep_up_to = i; break; } @@ -4763,13 +4880,13 @@ struct VariationDevice hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const - { return font->em_scalef_x (get_delta (font, store, store_cache)); } + hb_scalar_cache_t *store_cache = nullptr) const + { return !font->has_nonzero_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const - { return font->em_scalef_y (get_delta (font, store, store_cache)); } + hb_scalar_cache_t *store_cache = nullptr) const + { return !font->has_nonzero_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, const hb_hashmap_t> *layout_variation_idx_delta_map) const @@ -4803,9 +4920,9 @@ struct VariationDevice float get_delta (hb_font_t *font, const ItemVariationStore &store, - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { - return store.get_delta (varIdx, font->coords, font->num_coords, (ItemVariationStore::cache_t *) store_cache); + return store.get_delta (varIdx, font->coords, font->num_coords, store_cache); } protected: @@ -4830,7 +4947,7 @@ struct Device { hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store=Null (ItemVariationStore), - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4848,7 +4965,7 @@ struct Device } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store=Null (ItemVariationStore), - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { switch (u.b.format) { @@ -4934,6 +5051,18 @@ struct Device } } + bool is_variation_device () const + { + switch (u.b.format) { +#ifndef HB_NO_VAR + case 0x8000: + return true; +#endif + default: + return false; + } + } + protected: union { DeviceHeader b; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-layout-gpos-table.hh index 0cfa139a2..f6aabc84a 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout-gpos-table.hh @@ -63,12 +63,20 @@ inline bool PosLookup::dispatch_recurse_func (hb_ot_apply c->set_lookup_index (lookup_index); c->set_lookup_props (l.get_props ()); + uint32_t stack_match_positions[8]; + hb_vector_t saved_match_positions; + saved_match_positions.set_storage (stack_match_positions); + hb_swap (c->match_positions, saved_match_positions); + bool ret = false; auto *accel = gpos->get_accel (lookup_index); - ret = accel && accel->apply (c, l.get_subtable_count (), false); + ret = accel && accel->apply (c, false); c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); + + hb_swap (c->match_positions, saved_match_positions); + return ret; } #endif diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-layout-gsub-table.hh index fd8a68be0..8d5e1f186 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout-gsub-table.hh @@ -76,12 +76,20 @@ inline bool SubstLookup::dispatch_recurse_func (hb_ot_app c->set_lookup_index (lookup_index); c->set_lookup_props (l.get_props ()); + uint32_t stack_match_positions[8]; + hb_vector_t saved_match_positions; + saved_match_positions.set_storage (stack_match_positions); + hb_swap (c->match_positions, saved_match_positions); + bool ret = false; auto *accel = gsub->get_accel (lookup_index); - ret = accel && accel->apply (c, l.get_subtable_count (), false); + ret = accel && accel->apply (c, false); c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); + + hb_swap (c->match_positions, saved_match_positions); + return ret; } #endif diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/upstream/hb-ot-layout-gsubgpos.hh index 2c9056c70..1f24376e7 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout-gsubgpos.hh @@ -397,303 +397,311 @@ struct hb_collect_coverage_context_t : set_t *set; }; -struct hb_ot_apply_context_t : - hb_dispatch_context_t +struct matcher_t { - struct matcher_t - { - typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); - - void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } - void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } - void set_ignore_hidden (bool ignore_hidden_) { ignore_hidden = ignore_hidden_; } - void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } - void set_mask (hb_mask_t mask_) { mask = mask_; } - void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; } - void set_syllable (uint8_t syllable_) { syllable = per_syllable ? syllable_ : 0; } - void set_match_func (match_func_t match_func_, - const void *match_data_) - { match_func = match_func_; match_data = match_data_; } - - enum may_match_t { - MATCH_NO, - MATCH_YES, - MATCH_MAYBE - }; + typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); + + template + void init (const context_t *c, bool context_match = false) + { + set_match_func (nullptr, nullptr); + lookup_props = c->lookup_props; + /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ + ignore_zwnj = c->table_index == 1 || (context_match && c->auto_zwnj); + /* Ignore ZWJ if we are matching context, or asked to. */ + ignore_zwj = context_match || c->auto_zwj; + /* Ignore hidden glyphs (like CGJ) during GPOS. */ + ignore_hidden = c->table_index == 1; + mask = context_match ? -1 : c->lookup_mask; + /* Per syllable matching is only for GSUB. */ + per_syllable = c->table_index == 0 && c->per_syllable; + syllable = 0; + } + + void set_match_func (match_func_t match_func_, + const void *match_data_) + { match_func = match_func_; match_data = match_data_; } + + enum may_match_t { + MATCH_NO, + MATCH_YES, + MATCH_MAYBE + }; #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - may_match_t may_match (hb_glyph_info_t &info, - hb_codepoint_t glyph_data) const - { - if (!(info.mask & mask) || - (syllable && syllable != info.syllable ())) - return MATCH_NO; + may_match_t may_match (hb_glyph_info_t &info, + hb_codepoint_t glyph_data) const + { + if (!(info.mask & mask) || + (per_syllable && syllable && syllable != info.syllable ())) + return MATCH_NO; - if (match_func) - return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; + if (match_func) + return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; - return MATCH_MAYBE; - } + return MATCH_MAYBE; + } - enum may_skip_t { - SKIP_NO, - SKIP_YES, - SKIP_MAYBE - }; + enum may_skip_t { + SKIP_NO, + SKIP_YES, + SKIP_MAYBE + }; + template #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - may_skip_t may_skip (const hb_ot_apply_context_t *c, - const hb_glyph_info_t &info) const - { - if (!c->check_glyph_property (&info, lookup_props)) - return SKIP_YES; + may_skip_t may_skip (const context_t *c, + const hb_glyph_info_t &info) const + { + if (!c->check_glyph_property (&info, lookup_props)) + return SKIP_YES; - if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && - (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && - (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && - (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) - return SKIP_MAYBE; + if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && + (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && + (ignore_hidden || !_hb_glyph_info_is_hidden (&info)))) + return SKIP_MAYBE; - return SKIP_NO; - } + return SKIP_NO; + } - protected: - unsigned int lookup_props = 0; - hb_mask_t mask = -1; - bool ignore_zwnj = false; - bool ignore_zwj = false; - bool ignore_hidden = false; - bool per_syllable = false; - uint8_t syllable = 0; - match_func_t match_func = nullptr; - const void *match_data = nullptr; - }; + public: + unsigned int lookup_props = 0; + hb_mask_t mask = -1; + bool ignore_zwnj = false; + bool ignore_zwj = false; + bool ignore_hidden = false; + bool per_syllable = false; + uint8_t syllable = 0; + match_func_t match_func = nullptr; + const void *match_data = nullptr; +}; - struct skipping_iterator_t +template +struct skipping_iterator_t +{ + void init (context_t *c_, bool context_match = false) { - void init (hb_ot_apply_context_t *c_, bool context_match = false) - { - c = c_; - end = c->buffer->len; - match_glyph_data16 = nullptr; + c = c_; + end = c->buffer->len; + match_glyph_data16 = nullptr; #ifndef HB_NO_BEYOND_64K - match_glyph_data24 = nullptr; + match_glyph_data24 = nullptr; #endif - matcher.set_match_func (nullptr, nullptr); - matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ - matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj)); - /* Ignore ZWJ if we are matching context, or asked to. */ - matcher.set_ignore_zwj (context_match || c->auto_zwj); - /* Ignore hidden glyphs (like CGJ) during GPOS. */ - matcher.set_ignore_hidden (c->table_index == 1); - matcher.set_mask (context_match ? -1 : c->lookup_mask); - /* Per syllable matching is only for GSUB. */ - matcher.set_per_syllable (c->table_index == 0 && c->per_syllable); - matcher.set_syllable (0); - } - void set_lookup_props (unsigned int lookup_props) - { - matcher.set_lookup_props (lookup_props); - } - void set_match_func (matcher_t::match_func_t match_func_, - const void *match_data_) - { - matcher.set_match_func (match_func_, match_data_); - } - void set_glyph_data (const HBUINT16 glyph_data[]) - { - match_glyph_data16 = glyph_data; + matcher.init (c, context_match); + } + void set_lookup_props (unsigned int lookup_props) + { + matcher.lookup_props = lookup_props; + } + void set_match_func (matcher_t::match_func_t match_func_, + const void *match_data_) + { + matcher.set_match_func (match_func_, match_data_); + } + void set_glyph_data (const HBUINT16 glyph_data[]) + { + match_glyph_data16 = glyph_data; #ifndef HB_NO_BEYOND_64K - match_glyph_data24 = nullptr; + match_glyph_data24 = nullptr; #endif - } + } #ifndef HB_NO_BEYOND_64K - void set_glyph_data (const HBUINT24 glyph_data[]) - { - match_glyph_data16 = nullptr; - match_glyph_data24 = glyph_data; - } + void set_glyph_data (const HBUINT24 glyph_data[]) + { + match_glyph_data16 = nullptr; + match_glyph_data24 = glyph_data; + } #endif #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - void reset (unsigned int start_index_) - { - idx = start_index_; - end = c->buffer->len; - matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); - } + void reset (unsigned int start_index_) + { + // For GSUB forward iterator + idx = start_index_; + end = c->buffer->len; + matcher.syllable = c->buffer->cur().syllable(); + } + void reset_back (unsigned int start_index_, bool from_out_buffer = false) + { + // For GSUB backward iterator + idx = start_index_; + matcher.syllable = c->buffer->cur().syllable(); + } #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - void reset_fast (unsigned int start_index_) - { - // Doesn't set end or syllable. Used by GPOS which doesn't care / change. - idx = start_index_; - } - - void reject () - { - backup_glyph_data (); - } + void reset_fast (unsigned int start_index_) + { + // Doesn't set end or syllable. Used by GPOS which doesn't care / change. + idx = start_index_; + } - matcher_t::may_skip_t #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - may_skip (const hb_glyph_info_t &info) const - { return matcher.may_skip (c, info); } + matcher_t::may_skip_t may_skip (const hb_glyph_info_t &info) const + { return matcher.may_skip (c, info); } - enum match_t { - MATCH, - NOT_MATCH, - SKIP - }; + enum match_t { + MATCH, + NOT_MATCH, + SKIP + }; #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - match_t match (hb_glyph_info_t &info) - { - matcher_t::may_skip_t skip = matcher.may_skip (c, info); - if (unlikely (skip == matcher_t::SKIP_YES)) - return SKIP; + match_t match (hb_glyph_info_t &info) + { + matcher_t::may_skip_t skip = matcher.may_skip (c, info); + if (unlikely (skip == matcher_t::SKIP_YES)) + return SKIP; - matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); - if (match == matcher_t::MATCH_YES || - (match == matcher_t::MATCH_MAYBE && - skip == matcher_t::SKIP_NO)) - return MATCH; + matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); + if (match == matcher_t::MATCH_YES || + (match == matcher_t::MATCH_MAYBE && + skip == matcher_t::SKIP_NO)) + return MATCH; - if (skip == matcher_t::SKIP_NO) - return NOT_MATCH; + if (skip == matcher_t::SKIP_NO) + return NOT_MATCH; - return SKIP; + return SKIP; } #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - bool next (unsigned *unsafe_to = nullptr) + bool next (unsigned *unsafe_to = nullptr) + { + auto *info = c->buffer->info; + const signed stop = (signed) end - 1; + while ((signed) idx < stop) { - const signed stop = (signed) end - 1; - while ((signed) idx < stop) + idx++; + switch (match (info[idx])) { - idx++; - switch (match (c->buffer->info[idx])) + case MATCH: { - case MATCH: - { - advance_glyph_data (); - return true; - } - case NOT_MATCH: - { - if (unsafe_to) - *unsafe_to = idx + 1; - return false; - } - case SKIP: - continue; + advance_glyph_data (); + return true; } + case NOT_MATCH: + { + if (unsafe_to) + *unsafe_to = idx + 1; + return false; + } + case SKIP: + continue; } - if (unsafe_to) - *unsafe_to = end; - return false; } + if (unsafe_to) + *unsafe_to = end; + return false; + } #ifndef HB_OPTIMIZE_SIZE - HB_ALWAYS_INLINE + HB_ALWAYS_INLINE #endif - bool prev (unsigned *unsafe_from = nullptr) + bool prev (unsigned *unsafe_from = nullptr) + { + auto *out_info = c->buffer->out_info; + const unsigned stop = 0; + while (idx > stop) { - const unsigned stop = 0; - while (idx > stop) + idx--; + switch (match (out_info[idx])) { - idx--; - switch (match (c->buffer->out_info[idx])) + case MATCH: { - case MATCH: - { - advance_glyph_data (); - return true; - } - case NOT_MATCH: - { - if (unsafe_from) - *unsafe_from = hb_max (1u, idx) - 1u; - return false; - } - case SKIP: - continue; + advance_glyph_data (); + return true; } + case NOT_MATCH: + { + if (unsafe_from) + *unsafe_from = hb_max (1u, idx) - 1u; + return false; + } + case SKIP: + continue; } - if (unsafe_from) - *unsafe_from = 0; - return false; } + if (unsafe_from) + *unsafe_from = 0; + return false; + } - HB_ALWAYS_INLINE - hb_codepoint_t - get_glyph_data () - { - if (match_glyph_data16) return *match_glyph_data16; -#ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) return *match_glyph_data24; -#endif - return 0; - } - HB_ALWAYS_INLINE - void - advance_glyph_data () - { - if (match_glyph_data16) match_glyph_data16++; + HB_ALWAYS_INLINE + hb_codepoint_t + get_glyph_data () + { + if (match_glyph_data16) return *match_glyph_data16; #ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) match_glyph_data24++; + else + if (match_glyph_data24) return *match_glyph_data24; #endif - } - void - backup_glyph_data () - { - if (match_glyph_data16) match_glyph_data16--; + return 0; + } + HB_ALWAYS_INLINE + void + advance_glyph_data () + { + if (match_glyph_data16) match_glyph_data16++; #ifndef HB_NO_BEYOND_64K - else - if (match_glyph_data24) match_glyph_data24--; + else + if (match_glyph_data24) match_glyph_data24++; #endif - } + } - unsigned int idx; - protected: - hb_ot_apply_context_t *c; - matcher_t matcher; - const HBUINT16 *match_glyph_data16; + unsigned int idx; + protected: + context_t *c; + matcher_t matcher; + const HBUINT16 *match_glyph_data16; #ifndef HB_NO_BEYOND_64K - const HBUINT24 *match_glyph_data24; + const HBUINT24 *match_glyph_data24; #endif - unsigned int end; - }; - + unsigned int end; +}; +struct hb_ot_apply_context_t : + hb_dispatch_context_t +{ const char *get_name () { return "APPLY"; } typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); + + template + static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (return_t, obj.apply (c, nullptr) ) template - return_t dispatch (const T &obj) { return obj.apply (this); } + static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (return_t, obj.apply (c) ) + template + return_t dispatch (const T &obj) { return apply_(obj, this, hb_prioritize); } + static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int sub_lookup_index) { - if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) + assert (recurse_func); + if (unlikely (nesting_level_left == 0)) + { + buffer->successful = false; + return default_return_value (); + } + + buffer->max_ops--; + if (unlikely (buffer->max_ops < 0)) { - buffer->shaping_failed = true; + buffer->successful = false; return default_return_value (); } @@ -703,7 +711,7 @@ struct hb_ot_apply_context_t : return ret; } - skipping_iterator_t iter_input, iter_context; + skipping_iterator_t iter_input, iter_context; unsigned int table_index; /* GSUB/GPOS */ hb_font_t *font; @@ -713,9 +721,9 @@ struct hb_ot_apply_context_t : recurse_func_t recurse_func = nullptr; const GDEF &gdef; const GDEF::accelerator_t &gdef_accel; + const hb_ot_layout_lookup_accelerator_t *lookup_accel = nullptr; const ItemVariationStore &var_store; - ItemVariationStore::cache_t *var_store_cache; - hb_set_digest_t digest; + hb_scalar_cache_t *var_store_cache; hb_direction_t direction; hb_mask_t lookup_mask = 1; @@ -733,10 +741,18 @@ struct hb_ot_apply_context_t : signed last_base = -1; // GPOS uses unsigned last_base_until = 0; // GPOS uses + hb_vector_t match_positions; + uint32_t stack_match_positions[8]; +#ifndef HB_NO_BUFFER_MESSAGE + hb_buffer_t::changed_func_t orig_changed_func = nullptr; + void *orig_changed_data = nullptr; +#endif + hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_, - hb_blob_t *table_blob_) : + hb_blob_t *table_blob_, + hb_scalar_cache_t *var_store_cache_ = nullptr) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), sanitizer (table_blob_), @@ -755,22 +771,35 @@ struct hb_ot_apply_context_t : #endif ), var_store (gdef.get_var_store ()), - var_store_cache ( -#ifndef HB_NO_VAR - table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr -#else - nullptr -#endif - ), - digest (buffer_->digest ()), + var_store_cache (var_store_cache_), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) - { init_iters (); } + { + init_iters (); + match_positions.set_storage (stack_match_positions); +#ifndef HB_NO_BUFFER_MESSAGE + if (buffer->messaging ()) + { + assert (buffer->changed_func == nullptr || + buffer->changed_func == buffer_changed_trampoline); + orig_changed_func = buffer->changed_func; + orig_changed_data = buffer->changed_data; + buffer->changed_func = buffer_changed_trampoline; + buffer->changed_data = this; + } +#endif + } ~hb_ot_apply_context_t () { -#ifndef HB_NO_VAR - ItemVariationStore::destroy_cache (var_store_cache); +#ifndef HB_NO_BUFFER_MESSAGE + if (buffer->messaging ()) + { + assert (buffer->changed_func == buffer_changed_trampoline); + assert (buffer->changed_data == this); + buffer->changed_func = orig_changed_func; + buffer->changed_data = orig_changed_data; + } #endif } @@ -787,7 +816,11 @@ struct hb_ot_apply_context_t : void set_random (bool random_) { random = random_; } void set_recurse_func (recurse_func_t func) { recurse_func = func; } void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } - void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); } + void set_lookup_props (unsigned int lookup_props_) + { + lookup_props = gdef_accel.sanitize_lookup_props (lookup_props_); + init_iters (); + } uint32_t random_number () { @@ -796,7 +829,21 @@ struct hb_ot_apply_context_t : return buffer->random_state; } - bool match_properties_mark (hb_codepoint_t glyph, + static void buffer_changed_trampoline (hb_buffer_t *buffer HB_UNUSED, void *user_data) + { + ((hb_ot_apply_context_t *) user_data)->buffer_changed (); + } + void buffer_changed () + { + buffer->update_digest (); + if (likely (has_glyph_classes)) + for (unsigned i = 0; i < buffer->len; i++) + _set_glyph_class_props (buffer->info[i]); + } + + HB_ALWAYS_INLINE + HB_HOT + bool match_properties_mark (const hb_glyph_info_t *info, unsigned int glyph_props, unsigned int match_props) const { @@ -804,7 +851,7 @@ struct hb_ot_apply_context_t : * match_props has the set index. */ if (match_props & LookupFlag::UseMarkFilteringSet) - return gdef_accel.mark_set_covers (match_props >> 16, glyph); + return gdef_accel.mark_set_covers (match_props >> 16, info->codepoint); /* The second byte of match_props has the meaning * "ignore marks of attachment type different than @@ -820,7 +867,7 @@ struct hb_ot_apply_context_t : HB_ALWAYS_INLINE #endif bool check_glyph_property (const hb_glyph_info_t *info, - unsigned int match_props) const + unsigned match_props) const { unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); @@ -830,8 +877,8 @@ struct hb_ot_apply_context_t : if (glyph_props & match_props & LookupFlag::IgnoreFlags) return false; - if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - return match_properties_mark (info->codepoint, glyph_props, match_props); + if (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK) + return match_properties_mark (info, glyph_props, match_props); return true; } @@ -841,7 +888,7 @@ struct hb_ot_apply_context_t : bool ligature = false, bool component = false) { - digest.add (glyph_index); + buffer->digest.add (glyph_index); if (new_syllables != (unsigned) -1) buffer->cur().syllable() = new_syllables; @@ -863,8 +910,7 @@ struct hb_ot_apply_context_t : props |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED; if (likely (has_glyph_classes)) { - props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE; - _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef_accel.get_glyph_props (glyph_index)); + _set_glyph_class_props (buffer->cur(), props, glyph_index); } else if (class_guess) { @@ -874,6 +920,19 @@ struct hb_ot_apply_context_t : else _hb_glyph_info_set_glyph_props (&buffer->cur(), props); } + void _set_glyph_class_props (hb_glyph_info_t &info, + unsigned int props, + hb_codepoint_t glyph_index) + { + props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE; + _hb_glyph_info_set_glyph_props (&info, props | gdef_accel.get_glyph_props (glyph_index)); + } + void _set_glyph_class_props (hb_glyph_info_t &info) + { + _set_glyph_class_props (info, + _hb_glyph_info_get_glyph_props (&info), + info.codepoint); + } void replace_glyph (hb_codepoint_t glyph_index) { @@ -899,43 +958,58 @@ struct hb_ot_apply_context_t : } }; +enum class hb_ot_subtable_cache_op_t +{ + ENTER, + LEAVE, +}; struct hb_accelerate_subtables_context_t : hb_dispatch_context_t { - template - static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c) + template + static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) + template + static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template + static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) { - const Type *typed_obj = (const Type *) obj; - return typed_obj->apply (c); + const T *typed_obj = (const T *) obj; + return apply_ (typed_obj, c, external_cache, hb_prioritize); } #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE template - static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) ) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<2>) HB_RETURN (bool, obj->apply_cached (c, external_cache) ) template - static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) - template - static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c) + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) ) + template + static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) ) + template + static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache) { - const Type *typed_obj = (const Type *) obj; - return apply_cached_ (typed_obj, c, hb_prioritize); + const T *typed_obj = (const T *) obj; + return apply_cached_ (typed_obj, c, external_cache, hb_prioritize); } template - static inline auto cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<1>) HB_RETURN (bool, obj->cache_func (c, enter) ) - template - static inline bool cache_func_ (const T *obj, hb_ot_apply_context_t *c, bool enter, hb_priority<0>) { return false; } + static inline auto cache_func_ (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op, + hb_priority<1>) HB_RETURN (bool, T::cache_func (c, op) ) + template + static inline bool cache_func_ (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op HB_UNUSED, + hb_priority<0>) { return false; } template - static inline bool cache_func_to (const void *obj, hb_ot_apply_context_t *c, bool enter) + static inline bool cache_func_to (hb_ot_apply_context_t *c, + hb_ot_subtable_cache_op_t op) { - const Type *typed_obj = (const Type *) obj; - return cache_func_ (typed_obj, c, enter, hb_prioritize); + return cache_func_ (c, op, hb_prioritize); } #endif - typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c); - typedef bool (*hb_cache_func_t) (const void *obj, hb_ot_apply_context_t *c, bool enter); + typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, void *external_cache); + typedef bool (*hb_cache_func_t) (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op); struct hb_applicable_t { @@ -948,6 +1022,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE , hb_apply_func_t apply_cached_func_ , hb_cache_func_t cache_func_ + , void *external_cache_ #endif ) { @@ -956,27 +1031,34 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE apply_cached_func = apply_cached_func_; cache_func = cache_func_; + external_cache = external_cache_; #endif digest.init (); obj_.get_coverage ().collect_coverage (&digest); } +#ifdef HB_NO_OT_LAYOUT_LOOKUP_CACHE bool apply (hb_ot_apply_context_t *c) const { - return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c); + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, nullptr); + } +#else + bool apply (hb_ot_apply_context_t *c) const + { + return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, external_cache); } -#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE bool apply_cached (hb_ot_apply_context_t *c) const { - return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c); + return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c, external_cache); } + bool cache_enter (hb_ot_apply_context_t *c) const { - return cache_func (obj, c, true); + return cache_func (c, hb_ot_subtable_cache_op_t::ENTER); } void cache_leave (hb_ot_apply_context_t *c) const { - cache_func (obj, c, false); + cache_func (c, hb_ot_subtable_cache_op_t::LEAVE); } #endif @@ -986,6 +1068,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE hb_apply_func_t apply_cached_func; hb_cache_func_t cache_func; + void *external_cache; #endif hb_set_digest_t digest; }; @@ -995,12 +1078,23 @@ struct hb_accelerate_subtables_context_t : auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () ) template auto cache_cost (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( 0u ) + + template + auto external_cache_create (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.external_cache_create () ) + template + auto external_cache_create (const T &obj, hb_priority<0>) HB_AUTO_RETURN ( nullptr ) #endif /* Dispatch interface. */ template return_t dispatch (const T &obj) { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + void *external_cache = nullptr; + if (i < 8) + external_cache = external_cache_create (obj, hb_prioritize); +#endif + hb_applicable_t *entry = &array[i++]; entry->init (obj, @@ -1008,6 +1102,7 @@ struct hb_accelerate_subtables_context_t : #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE , apply_cached_to , cache_func_to + , external_cache #endif ); @@ -1021,10 +1116,10 @@ struct hb_accelerate_subtables_context_t : * and we allocate the cache opportunity to the costliest subtable. */ unsigned cost = cache_cost (obj, hb_prioritize); - if (cost > cache_user_cost) + if (cost > subtable_cache_user_cost) { - cache_user_idx = i - 1; - cache_user_cost = cost; + subtable_cache_user_idx = i - 1; + subtable_cache_user_cost = cost; } #endif @@ -1039,8 +1134,8 @@ struct hb_accelerate_subtables_context_t : unsigned i = 0; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - unsigned cache_user_idx = (unsigned) -1; - unsigned cache_user_cost = 0; + unsigned subtable_cache_user_idx = (unsigned) -1; + unsigned subtable_cache_user_cost = 0; #endif }; @@ -1189,38 +1284,50 @@ static inline bool match_class (hb_glyph_info_t &info, unsigned value, const voi const ClassDef &class_def = *reinterpret_cast(data); return class_def.get_class (info.codepoint) == value; } -static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) +static inline unsigned get_class_cached (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = info.syllable(); if (klass < 255) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 255)) info.syllable() = klass; - return klass == value; + return klass; } -static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) +static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached (class_def, info) == value; +} +static inline unsigned get_class_cached1 (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = info.syllable() & 0x0F; if (klass < 15) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 15)) info.syllable() = (info.syllable() & 0xF0) | klass; - return klass == value; + return klass; } -static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) +static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached1 (class_def, info) == value; +} +static inline unsigned get_class_cached2 (const ClassDef &class_def, hb_glyph_info_t &info) { unsigned klass = (info.syllable() & 0xF0) >> 4; if (klass < 15) - return klass == value; - const ClassDef &class_def = *reinterpret_cast(data); + return klass; klass = class_def.get_class (info.codepoint); if (likely (klass < 15)) info.syllable() = (info.syllable() & 0x0F) | (klass << 4); - return klass == value; + return klass; +} +static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data) +{ + const ClassDef &class_def = *reinterpret_cast(data); + return get_class_cached2 (class_def, info) == value; } static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data) { @@ -1259,16 +1366,24 @@ static bool match_input (hb_ot_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_position, - unsigned int *match_positions, unsigned int *p_total_component_count = nullptr) { TRACE_APPLY (nullptr); - if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); - hb_buffer_t *buffer = c->buffer; - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + if (count == 1) + { + *end_position = buffer->idx + 1; + c->match_positions[0] = buffer->idx; + if (p_total_component_count) + *p_total_component_count = _hb_glyph_info_get_lig_num_comps (&buffer->cur()); + return_trace (true); + } + + if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); + + auto &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (input); @@ -1317,7 +1432,10 @@ static bool match_input (hb_ot_apply_context_t *c, return_trace (false); } - match_positions[i] = skippy_iter.idx; + if (unlikely (i + 1 > c->match_positions.length && + !c->match_positions.resize_dirty (i + 1))) + return_trace (false); + c->match_positions.arrayZ[i] = skippy_iter.idx; unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]); unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]); @@ -1347,7 +1465,7 @@ static bool match_input (hb_ot_apply_context_t *c, j--; } - if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES) + if (found && skippy_iter.may_skip (out[j]) == matcher_t::SKIP_YES) ligbase = LIGBASE_MAY_SKIP; else ligbase = LIGBASE_MAY_NOT_SKIP; @@ -1377,13 +1495,12 @@ static bool match_input (hb_ot_apply_context_t *c, *p_total_component_count = total_component_count; } - match_positions[0] = buffer->idx; + c->match_positions.arrayZ[0] = buffer->idx; return_trace (true); } static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - const unsigned int *match_positions, /* Including the first glyph */ unsigned int match_end, hb_codepoint_t lig_glyph, unsigned int total_component_count) @@ -1426,10 +1543,10 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, * https://bugzilla.gnome.org/show_bug.cgi?id=437633 */ - bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[match_positions[0]]); - bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[match_positions[0]]); + bool is_base_ligature = _hb_glyph_info_is_base_glyph (&buffer->info[c->match_positions.arrayZ[0]]); + bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[0]]); for (unsigned int i = 1; i < count; i++) - if (!_hb_glyph_info_is_mark (&buffer->info[match_positions[i]])) + if (!_hb_glyph_info_is_mark (&buffer->info[c->match_positions.arrayZ[i]])) { is_base_ligature = false; is_mark_ligature = false; @@ -1455,13 +1572,14 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, for (unsigned int i = 1; i < count; i++) { - while (buffer->idx < match_positions[i] && buffer->successful) + while (buffer->idx < c->match_positions.arrayZ[i] && buffer->successful) { if (is_ligature) { unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (this_comp == 0) this_comp = last_num_components; + assert (components_so_far >= last_num_components); unsigned int new_lig_comp = components_so_far - last_num_components + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); @@ -1487,6 +1605,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); if (!this_comp) break; + assert (components_so_far >= last_num_components); unsigned new_lig_comp = components_so_far - last_num_components + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); @@ -1508,8 +1627,14 @@ static bool match_backtrack (hb_ot_apply_context_t *c, { TRACE_APPLY (nullptr); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; - skippy_iter.reset (c->buffer->backtrack_len ()); + if (!count) + { + *match_start = c->buffer->backtrack_len (); + return_trace (true); + } + + auto &skippy_iter = c->iter_context; + skippy_iter.reset_back (c->buffer->backtrack_len ()); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (backtrack); @@ -1541,7 +1666,14 @@ static bool match_lookahead (hb_ot_apply_context_t *c, { TRACE_APPLY (nullptr); - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + if (!count) + { + *end_index = start_index; + return_trace (true); + } + + auto &skippy_iter = c->iter_context; + assert (start_index >= 1); skippy_iter.reset (start_index - 1); skippy_iter.set_match_func (match_func, match_data); skippy_iter.set_glyph_data (lookahead); @@ -1691,7 +1823,6 @@ static inline void recurse_lookups (context_t *c, static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int *match_positions, /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_end) @@ -1699,9 +1830,6 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, hb_buffer_t *buffer = c->buffer; int end; - unsigned int *match_positions_input = match_positions; - unsigned int match_positions_count = count; - /* All positions are distance from beginning of *output* buffer. * Adjust. */ { @@ -1711,7 +1839,7 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, int delta = bl - buffer->idx; /* Convert positions to new indexing. */ for (unsigned int j = 0; j < count; j++) - match_positions[j] += delta; + c->match_positions.arrayZ[j] += delta; } for (unsigned int i = 0; i < lookupCount && buffer->successful; i++) @@ -1723,10 +1851,10 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); /* This can happen if earlier recursed lookups deleted many entries. */ - if (unlikely (match_positions[idx] >= orig_len)) + if (unlikely (c->match_positions.arrayZ[idx] >= orig_len)) continue; - if (unlikely (!buffer->move_to (match_positions[idx]))) + if (unlikely (!buffer->move_to (c->match_positions.arrayZ[idx]))) break; if (unlikely (buffer->max_ops <= 0)) @@ -1785,9 +1913,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, */ end += delta; - if (end < int (match_positions[idx])) + if (end < int (c->match_positions.arrayZ[idx])) { - /* End might end up being smaller than match_positions[idx] if the recursed + /* End might end up being smaller than match_positions.arrayZ[idx] if the recursed * lookup ended up removing many items. * Just never rewind end beyond start of current position, since that is * not possible in the recursed lookup. Also adjust delta as such. @@ -1795,8 +1923,8 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 * https://github.com/harfbuzz/harfbuzz/issues/1611 */ - delta += match_positions[idx] - end; - end = match_positions[idx]; + delta += c->match_positions.arrayZ[idx] - end; + end = c->match_positions.arrayZ[idx]; } unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ @@ -1805,27 +1933,9 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, { if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; - if (unlikely (delta + count > match_positions_count)) - { - unsigned new_match_positions_count = hb_max (delta + count, hb_max(match_positions_count, 4u) * 1.5); - if (match_positions == match_positions_input) - { - match_positions = (unsigned int *) hb_malloc (new_match_positions_count * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - break; - memcpy (match_positions, match_positions_input, count * sizeof (match_positions[0])); - match_positions_count = new_match_positions_count; - } - else - { - unsigned int *new_match_positions = (unsigned int *) hb_realloc (match_positions, new_match_positions_count * sizeof (match_positions[0])); - if (unlikely (!new_match_positions)) - break; - match_positions = new_match_positions; - match_positions_count = new_match_positions_count; - } - } - + if (unlikely (count + delta > c->match_positions.length && + !c->match_positions.resize_dirty (count + delta))) + return; } else { @@ -1835,23 +1945,21 @@ static inline void apply_lookup (hb_ot_apply_context_t *c, } /* Shift! */ - memmove (match_positions + next + delta, match_positions + next, - (count - next) * sizeof (match_positions[0])); + memmove (c->match_positions + next + delta, c->match_positions + next, + (count - next) * sizeof (c->match_positions.arrayZ[0])); next += delta; count += delta; /* Fill in new entries. */ for (unsigned int j = idx + 1; j < next; j++) - match_positions[j] = match_positions[j - 1] + 1; + c->match_positions.arrayZ[j] = c->match_positions.arrayZ[j - 1] + 1; /* And fixup the rest. */ for (; next < count; next++) - match_positions[next] += delta; + c->match_positions.arrayZ[next] += delta; } - if (match_positions != match_positions_input) - hb_free (match_positions); - + assert (end >= 0); (void) buffer->move_to (end); } @@ -1944,34 +2052,25 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, } template -HB_ALWAYS_INLINE -static bool context_apply_lookup (hb_ot_apply_context_t *c, - unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT input[], /* Array of input values--start with second glyph */ - unsigned int lookupCount, - const LookupRecord lookupRecord[], - const ContextApplyLookupContext &lookup_context) +static inline bool context_apply_lookup (hb_ot_apply_context_t *c, + unsigned int inputCount, /* Including the first glyph (not matched) */ + const HBUINT input[], /* Array of input values--start with second glyph */ + unsigned int lookupCount, + const LookupRecord lookupRecord[], + const ContextApplyLookupContext &lookup_context) { if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - return false; - } unsigned match_end = 0; bool ret = false; if (match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, - &match_end, match_positions)) + &match_end)) { c->buffer->unsafe_to_break (c->buffer->idx, match_end); apply_lookup (c, - inputCount, match_positions, + inputCount, lookupCount, lookupRecord, match_end); ret = true; @@ -1982,12 +2081,34 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c, ret = false; } - if (unlikely (match_positions != match_positions_stack)) - hb_free (match_positions); - return ret; } +static inline bool context_cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) +{ + switch (op) + { + case hb_ot_subtable_cache_op_t::ENTER: + { + if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) + return false; + auto &info = c->buffer->info; + unsigned count = c->buffer->len; + for (unsigned i = 0; i < count; i++) + info[i].syllable() = 255; + c->new_syllables = 255; + return true; + } + case hb_ot_subtable_cache_op_t::LEAVE: + { + c->new_syllables = (unsigned) -1; + HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); + break; + } + } + return false; +} + template struct Rule { @@ -2203,24 +2324,29 @@ struct RuleSet * * Replicated from LigatureSet::apply(). */ - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + /* We use the iter_context instead of iter_input, to avoid skipping + * default-ignorables and such. + * + * Related: https://github.com/harfbuzz/harfbuzz/issues/4813 + */ + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); - unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; + unsigned unsafe_to = (unsigned) -1, unsafe_to1, unsafe_to2 = 0; hb_glyph_info_t *first = nullptr, *second = nullptr; bool matched = skippy_iter.next (); if (likely (matched)) { - first = &c->buffer->info[skippy_iter.idx]; - unsafe_to = skippy_iter.idx + 1; - if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) { /* Can't use the fast path if eg. the next char is a default-ignorable * or other skippable. */ goto slow; } + + first = &c->buffer->info[skippy_iter.idx]; + unsafe_to1 = skippy_iter.idx + 1; } else { @@ -2236,8 +2362,15 @@ struct RuleSet ; } matched = skippy_iter.next (); - if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) + if (likely (matched)) { + if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) + { + /* Can't use the fast path if eg. the next char is a default-ignorable + * or other skippable. */ + goto slow; + } + second = &c->buffer->info[skippy_iter.idx]; unsafe_to2 = skippy_iter.idx + 1; } @@ -2274,6 +2407,15 @@ struct RuleSet { if (unsafe_to == (unsigned) -1) unsafe_to = unsafe_to1; + + // Skip ahead to next possible first glyph match. + for (; i + 1 < num_rules; i++) + { + const auto &r2 = this+rule.arrayZ[i + 1]; + const auto &input2 = r2.inputZ; + if (r2.inputCount <= 1 || input2.arrayZ[0] != input.arrayZ[0]) + break; + } } } if (likely (unsafe_to != (unsigned) -1)) @@ -2616,37 +2758,38 @@ struct ContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+classDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+classDef).cost (); } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) { - if (enter) - { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else + return context_cache_func (c, op); + } + + struct external_cache_t + { + hb_ot_layout_binary_cache_t coverage; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + cache->coverage.clear (); } + return cache; } - - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply_cached (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, true, external_cache); } + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, false, external_cache); } + bool _apply (hb_ot_apply_context_t *c, bool cached, void *external_cache) const { TRACE_APPLY (this); +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage_binary (c->buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); const ClassDef &class_def = this+classDef; @@ -2655,10 +2798,7 @@ struct ContextFormat2_5 &class_def }; - if (cached && c->buffer->cur().syllable() < 255) - index = c->buffer->cur().syllable (); - else - index = class_def.get_class (c->buffer->cur().codepoint); + index = cached ? get_class_cached (class_def, c->buffer->cur()) : class_def.get_class (c->buffer->cur().codepoint); const RuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -2832,7 +2972,7 @@ struct ContextFormat3 { TRACE_APPLY (this); unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextApplyLookupContext lookup_context = { @@ -2903,9 +3043,9 @@ struct Context template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -2919,7 +3059,7 @@ struct Context protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ContextFormat1_4 format1; ContextFormat2_5 format2; ContextFormat3 format3; @@ -3053,27 +3193,18 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c } template -HB_ALWAYS_INLINE -static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, - unsigned int backtrackCount, - const HBUINT backtrack[], - unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT input[], /* Array of input values--start with second glyph */ - unsigned int lookaheadCount, - const HBUINT lookahead[], - unsigned int lookupCount, - const LookupRecord lookupRecord[], - const ChainContextApplyLookupContext &lookup_context) +static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, + unsigned int backtrackCount, + const HBUINT backtrack[], + unsigned int inputCount, /* Including the first glyph (not matched) */ + const HBUINT input[], /* Array of input values--start with second glyph */ + unsigned int lookaheadCount, + const HBUINT lookahead[], + unsigned int lookupCount, + const LookupRecord lookupRecord[], + const ChainContextApplyLookupContext &lookup_context) { if (unlikely (inputCount > HB_MAX_CONTEXT_LENGTH)) return false; - unsigned match_positions_stack[4]; - unsigned *match_positions = match_positions_stack; - if (unlikely (inputCount > ARRAY_LENGTH (match_positions_stack))) - { - match_positions = (unsigned *) hb_malloc (hb_max (inputCount, 1u) * sizeof (match_positions[0])); - if (unlikely (!match_positions)) - return false; - } unsigned start_index = c->buffer->out_len; unsigned end_index = c->buffer->idx; @@ -3082,15 +3213,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, if (!(match_input (c, inputCount, input, lookup_context.funcs.match[1], lookup_context.match_data[1], - &match_end, match_positions) && (end_index = match_end) + &match_end) && (end_index = match_end) && match_lookahead (c, lookaheadCount, lookahead, lookup_context.funcs.match[2], lookup_context.match_data[2], match_end, &end_index))) { c->buffer->unsafe_to_concat (c->buffer->idx, end_index); - ret = false; - goto done; + return false; } if (!match_backtrack (c, @@ -3099,19 +3229,14 @@ static bool chain_context_apply_lookup (hb_ot_apply_context_t *c, &start_index)) { c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index); - ret = false; - goto done; + return false; } c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); apply_lookup (c, - inputCount, match_positions, + inputCount, lookupCount, lookupRecord, match_end); - done: - - if (unlikely (match_positions != match_positions_stack)) - hb_free (match_positions); return ret; } @@ -3395,33 +3520,29 @@ struct ChainRuleSet * * Replicated from LigatureSet::apply(). */ - /* If the input skippy has non-auto joiners behavior (as in Indic shapers), - * skip this fast path, as we don't distinguish between input & lookahead - * matching in the fast path. + /* We use the iter_context instead of iter_input, to avoid skipping + * default-ignorables and such. * - * https://github.com/harfbuzz/harfbuzz/issues/4813 + * Related: https://github.com/harfbuzz/harfbuzz/issues/4813 */ - if (!c->auto_zwnj || !c->auto_zwj) - goto slow; - - hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + auto &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx); skippy_iter.set_match_func (match_always, nullptr); skippy_iter.set_glyph_data ((HBUINT16 *) nullptr); - unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0; + unsigned unsafe_to = (unsigned) -1, unsafe_to1, unsafe_to2 = 0; hb_glyph_info_t *first = nullptr, *second = nullptr; bool matched = skippy_iter.next (); if (likely (matched)) { - first = &c->buffer->info[skippy_iter.idx]; - unsafe_to1 = skippy_iter.idx + 1; - if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) { /* Can't use the fast path if eg. the next char is a default-ignorable * or other skippable. */ goto slow; } + + first = &c->buffer->info[skippy_iter.idx]; + unsafe_to1 = skippy_iter.idx + 1; } else { @@ -3442,8 +3563,15 @@ struct ChainRuleSet ; } matched = skippy_iter.next (); - if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))) + if (likely (matched)) { + if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])) + { + /* Can't use the fast path if eg. the next char is a default-ignorable + * or other skippable. */ + goto slow; + } + second = &c->buffer->info[skippy_iter.idx]; unsafe_to2 = skippy_iter.idx + 1; } @@ -3459,7 +3587,7 @@ struct ChainRuleSet const auto &input = StructAfter (r.backtrack); const auto &lookahead = StructAfter (input); - unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u); + unsigned lenP1 = input.lenP1; if (lenP1 > 1 ? (!match_input || match_input (*first, input.arrayZ[0], input_data)) @@ -3467,6 +3595,7 @@ struct ChainRuleSet (!lookahead.len || !match_lookahead || match_lookahead (*first, lookahead.arrayZ[0], lookahead_data))) { + lenP1 = hb_max (lenP1, 1u); if (!second || (lenP1 > 2 ? (!match_input || @@ -3489,6 +3618,18 @@ struct ChainRuleSet { if (unsafe_to == (unsigned) -1) unsafe_to = unsafe_to1; + + if (lenP1 > 1) + { + // Skip ahead to next possible first glyph match. + for (; i + 1 < num_rules; i++) + { + const auto &r2 = this+rule.arrayZ[i + 1]; + const auto &input2 = StructAfter (r2.backtrack); + if (input2.lenP1 <= 1 || input2.arrayZ[0] != input.arrayZ[0]) + break; + } + } } } if (likely (unsafe_to != (unsigned) -1)) @@ -3646,7 +3787,7 @@ struct ChainContextFormat1_4 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { @@ -3857,37 +3998,38 @@ struct ChainContextFormat2_5 unsigned cache_cost () const { - unsigned c = (this+lookaheadClassDef).cost () * ruleSet.len; - return c >= 4 ? c : 0; + return (this+inputClassDef).cost () + (this+lookaheadClassDef).cost (); } - bool cache_func (hb_ot_apply_context_t *c, bool enter) const + static bool cache_func (hb_ot_apply_context_t *c, hb_ot_subtable_cache_op_t op) { - if (enter) - { - if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable)) - return false; - auto &info = c->buffer->info; - unsigned count = c->buffer->len; - for (unsigned i = 0; i < count; i++) - info[i].syllable() = 255; - c->new_syllables = 255; - return true; - } - else + return context_cache_func (c, op); + } + + struct external_cache_t + { + hb_ot_layout_binary_cache_t coverage; + }; + void *external_cache_create () const + { + external_cache_t *cache = (external_cache_t *) hb_malloc (sizeof (external_cache_t)); + if (likely (cache)) { - c->new_syllables = (unsigned) -1; - HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable); - return true; + cache->coverage.clear (); } + return cache; } - - bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); } - bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); } - bool _apply (hb_ot_apply_context_t *c, bool cached) const + bool apply_cached (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, true, external_cache); } + bool apply (hb_ot_apply_context_t *c, void *external_cache) const { return _apply (c, false, external_cache); } + bool _apply (hb_ot_apply_context_t *c, bool cached, void *external_cache) const { TRACE_APPLY (this); +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + external_cache_t *cache = (external_cache_t *) external_cache; + unsigned int index = (this+coverage).get_coverage_binary (c->buffer->cur().codepoint, cache ? &cache->coverage : nullptr); +#else unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); +#endif + if (index == NOT_COVERED) return_trace (false); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -3904,11 +4046,9 @@ struct ChainContextFormat2_5 &lookahead_class_def} }; - // Note: Corresponds to match_class_cached2 - if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15) - index = (c->buffer->cur().syllable () & 0xF0) >> 4; - else - index = input_class_def.get_class (c->buffer->cur().codepoint); + index = cached + ? get_class_cached2 (input_class_def, c->buffer->cur()) + : input_class_def.get_class (c->buffer->cur().codepoint); const ChainRuleSet &rule_set = this+ruleSet[index]; return_trace (rule_set.apply (c, lookup_context)); } @@ -4133,7 +4273,7 @@ struct ChainContextFormat3 const auto &input = StructAfter (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return_trace (false); + if (index == NOT_COVERED) return_trace (false); const auto &lookahead = StructAfter (input); const auto &lookup = StructAfter (lookahead); @@ -4236,9 +4376,9 @@ struct ChainContext template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -4252,7 +4392,7 @@ struct ChainContext protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ChainContextFormat1_4 format1; ChainContextFormat2_5 format2; ChainContextFormat3 format3; @@ -4327,7 +4467,7 @@ struct Extension { unsigned int get_type () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_type (); default:return 0; } @@ -4335,7 +4475,7 @@ struct Extension template const X& get_subtable () const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.template get_subtable (); default:return Null (typename T::SubTable); } @@ -4347,7 +4487,7 @@ struct Extension template typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const { - switch (u.format) { + switch (u.format.v) { case 1: hb_barrier (); return u.format1.subset (c); default: return c->default_return_value (); } @@ -4356,9 +4496,9 @@ struct Extension template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.dispatch (c, std::forward (ds)...)); default:return_trace (c->default_return_value ()); } @@ -4366,7 +4506,7 @@ struct Extension protected: union { - HBUINT16 format; /* Format identifier */ + struct { HBUINT16 v; } format; /* Format identifier */ ExtensionFormat1 format1; } u; }; @@ -4403,29 +4543,41 @@ struct hb_ot_layout_lookup_accelerator_t for (auto& subtable : hb_iter (thiz->subtables, count)) thiz->digest.union_ (subtable.digest); + thiz->count = count; + #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx; + thiz->subtable_cache_user_idx = c_accelerate_subtables.subtable_cache_user_idx; + for (unsigned i = 0; i < count; i++) - if (i != thiz->cache_user_idx) - thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; + if (i != thiz->subtable_cache_user_idx) + thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func; #endif return thiz; } + void fini () + { +#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE + for (unsigned i = 0; i < count; i++) + hb_free (subtables[i].external_cache); +#endif + } + bool may_have (hb_codepoint_t g) const { return digest.may_have (g); } #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const + bool apply (hb_ot_apply_context_t *c, bool use_cache) const { + c->lookup_accel = this; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE if (use_cache) { return - + hb_iter (hb_iter (subtables, subtables_count)) + + hb_iter (hb_iter (subtables, count)) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); }) | hb_any ; @@ -4434,7 +4586,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif { return - + hb_iter (hb_iter (subtables, subtables_count)) + + hb_iter (hb_iter (subtables, count)) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); }) | hb_any ; @@ -4445,8 +4597,8 @@ struct hb_ot_layout_lookup_accelerator_t bool cache_enter (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - return cache_user_idx != (unsigned) -1 && - subtables[cache_user_idx].cache_enter (c); + return subtable_cache_user_idx != (unsigned) -1 && + subtables[subtable_cache_user_idx].cache_enter (c); #else return false; #endif @@ -4454,15 +4606,16 @@ struct hb_ot_layout_lookup_accelerator_t void cache_leave (hb_ot_apply_context_t *c) const { #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - subtables[cache_user_idx].cache_leave (c); + subtables[subtable_cache_user_idx].cache_leave (c); #endif } hb_set_digest_t digest; private: + unsigned count = 0; /* Number of subtables in the array. */ #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE - unsigned cache_user_idx = (unsigned) -1; + unsigned subtable_cache_user_idx = (unsigned) -1; #endif hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY]; }; @@ -4837,7 +4990,7 @@ struct GSUBGPOS this->lookup_count = table->get_lookup_count (); - this->accels = (hb_atomic_ptr_t *) hb_calloc (this->lookup_count, sizeof (*accels)); + this->accels = (hb_atomic_t *) hb_calloc (this->lookup_count, sizeof (*accels)); if (unlikely (!this->accels)) { this->lookup_count = 0; @@ -4848,7 +5001,12 @@ struct GSUBGPOS ~accelerator_t () { for (unsigned int i = 0; i < this->lookup_count; i++) - hb_free (this->accels[i]); + { + auto *accel = this->accels[i].get_relaxed (); + if (accel) + accel->fini (); + hb_free (accel); + } hb_free (this->accels); this->table.destroy (); } @@ -4869,6 +5027,7 @@ struct GSUBGPOS if (unlikely (!accels[lookup_index].cmpexch (nullptr, accel))) { + accel->fini (); hb_free (accel); goto retry; } @@ -4879,7 +5038,7 @@ struct GSUBGPOS hb_blob_ptr_t table; unsigned int lookup_count; - hb_atomic_ptr_t *accels; + hb_atomic_t *accels; }; protected: diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout.cc b/thirdparty/harfbuzz/upstream/hb-ot-layout.cc index 66c2eb4d8..f69274bae 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout.cc @@ -131,13 +131,15 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob = font->face->table.kern.get_blob (); - const auto& kern = *font->face->table.kern; + auto &accel = *font->face->table.kern; + hb_blob_t *blob = accel.get_blob (); AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); if (!buffer->message (font, "start table kern")) return; - kern.apply (&c); + c.buffer_glyph_set = accel.scratch.create_buffer_glyph_set (); + accel.apply (&c); + accel.scratch.destroy_buffer_glyph_set (c.buffer_glyph_set); (void) buffer->message (font, "end table kern"); } #endif @@ -246,6 +248,18 @@ OT::GDEF::is_blocklisted (hb_blob_t *blob, /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85 Padauk.ttf * "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */ case HB_CODEPOINT_ENCODE3 (1004, 59092, 14836): + /* 88d2006ca084f04af2df1954ed714a8c71e8400f Courier New.ttf from macOS 15 */ + case HB_CODEPOINT_ENCODE3 (588, 5078, 14418): + /* 608e3ebb6dd1aee521cff08eb07d500a2c59df68 Courier New Bold.ttf from macOS 15 */ + case HB_CODEPOINT_ENCODE3 (588, 5078, 14238): + /* d13221044ff054efd78f1cd8631b853c3ce85676 cour.ttf from Windows 10 */ + case HB_CODEPOINT_ENCODE3 (894, 17162, 33960): + /* 68ed4a22d8067fcf1622ac6f6e2f4d3a2e3ec394 courbd.ttf from Windows 10 */ + case HB_CODEPOINT_ENCODE3 (894, 17154, 34472): + /* 4cdb0259c96b7fd7c103821bb8f08f7cc6b211d7 cour.ttf from Windows 8.1 */ + case HB_CODEPOINT_ENCODE3 (816, 7868, 17052): + /* 920483d8a8ed37f7f0afdabbe7f679aece7c75d8 courbd.ttf from Windows 8.1 */ + case HB_CODEPOINT_ENCODE3 (816, 7868, 17138): return true; } return false; @@ -329,7 +343,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, * @face: The #hb_face_t to work on * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first attachment point to retrieve - * @point_count: (inout) (optional): Input = the maximum number of attachment points to return; + * @point_count: (inout) (nullable): Input = the maximum number of attachment points to return; * Output = the actual number of attachment points returned (may be zero) * @point_array: (out) (array length=point_count): The array of attachment points found for the query * @@ -359,7 +373,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, * @direction: The #hb_direction_t text direction to use * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first caret position to retrieve - * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return; + * @caret_count: (inout) (nullable): Input = the maximum number of caret positions to return; * Output = the actual number of caret positions returned (may be zero) * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query * @@ -430,7 +444,7 @@ get_gsubgpos_table (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first script tag to retrieve - * @script_count: (inout) (optional): Input = the maximum number of script tags to return; + * @script_count: (inout) (nullable): Input = the maximum number of script tags to return; * Output = the actual number of script tags returned (may be zero) * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query * @@ -527,8 +541,8 @@ hb_ot_layout_table_choose_script (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_count: Number of script tags in the array * @script_tags: Array of #hb_tag_t script tags - * @script_index: (out) (optional): The index of the requested script - * @chosen_script: (out) (optional): #hb_tag_t of the requested script + * @script_index: (out) (nullable): The index of the requested script + * @chosen_script: (out) (nullable): #hb_tag_t of the requested script * * Selects an OpenType script for @table_tag from the @script_tags array. * @@ -599,7 +613,7 @@ hb_ot_layout_table_select_script (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table * @@ -669,7 +683,7 @@ hb_ot_layout_table_find_feature (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @start_offset: offset of the first language tag to retrieve - * @language_count: (inout) (optional): Input = the maximum number of language tags to return; + * @language_count: (inout) (nullable): Input = the maximum number of language tags to return; * Output = the actual number of language tags returned (may be zero) * @language_tags: (out) (array length=language_count): Array of language tags found in the table * @@ -897,7 +911,7 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output: the actual number of feature tags returned (may be zero) * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query * @@ -933,7 +947,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (nullable): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query * @@ -1021,7 +1035,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face, * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the requested feature * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query * @@ -1372,10 +1386,10 @@ hb_ot_layout_collect_lookups (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @lookup_index: The index of the feature lookup to query - * @glyphs_before: (out): Array of glyphs preceding the substitution range - * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup - * @glyphs_after: (out): Array of glyphs following the substitution range - * @glyphs_output: (out): Array of glyphs that would be the substituted output of the lookup + * @glyphs_before: (out) (nullable): Array of glyphs preceding the substitution range + * @glyphs_input: (out) (nullable): Array of input glyphs that would be substituted by the lookup + * @glyphs_after: (out) (nullable): Array of glyphs following the substitution range + * @glyphs_output: (out) (nullable): Array of glyphs that would be the substituted output of the lookup * * Fetches a list of all glyphs affected by the specified lookup in the * specified face's GSUB table or GPOS table. @@ -1459,7 +1473,7 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, * @feature_index: The index of the feature to query * @variations_index: The index of the feature variation to query * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (nullable): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query * @@ -1763,15 +1777,15 @@ hb_ot_layout_get_size_params (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. - * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string - * for a user-interface label for this feature. (May be NULL.) - * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string + * @label_id: (out) (nullable): The ‘name’ table name ID that specifies a string + * for a user-interface label for this feature. + * @tooltip_id: (out) (nullable): The ‘name’ table name ID that specifies a string * that an application can use for tooltip text for this - * feature. (May be NULL.) - * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text - * that illustrates the effect of this feature. (May be NULL.) - * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.) - * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify + * feature. + * @sample_id: (out) (nullable): The ‘name’ table name ID that specifies sample text + * that illustrates the effect of this feature. + * @num_named_parameters: (out) (nullable): Number of named parameters. + * @first_param_id: (out) (nullable): The first ‘name’ table name ID used to specify * strings for user-interface labels for the feature * parameters. (Must be zero if numParameters is zero.) * @@ -1838,7 +1852,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. * @start_offset: offset of the first character to retrieve - * @char_count: (inout) (optional): Input = the maximum number of characters to return; + * @char_count: (inout) (nullable): Input = the maximum number of characters to return; * Output = the actual number of characters returned (may be zero) * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. * The Unicode codepoints of the characters for which this feature provides @@ -1901,30 +1915,33 @@ struct GPOSProxy static inline bool apply_forward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel, - unsigned subtable_count) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { - bool use_cache = accel.cache_enter (c); + bool use_hot_subtable_cache = accel.cache_enter (c); bool ret = false; hb_buffer_t *buffer = c->buffer; - while (buffer->idx < buffer->len && buffer->successful) + while (buffer->successful) { - bool applied = false; - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) - { - applied = accel.apply (c, subtable_count, use_cache); - } - - if (applied) + hb_glyph_info_t *info = buffer->info; + unsigned j = buffer->idx; + while (j < buffer->len && + !(accel.digest.may_have (info[j].codepoint) && + (info[j].mask & c->lookup_mask) && + c->check_glyph_property (&info[j], c->lookup_props))) + j++; + if (unlikely (j > buffer->idx && !buffer->next_glyphs (j - buffer->idx))) + break; + if (buffer->idx >= buffer->len) + break; + + if (accel.apply (c, use_hot_subtable_cache)) ret = true; else (void) buffer->next_glyph (); } - if (use_cache) + if (use_hot_subtable_cache) accel.cache_leave (c); return ret; @@ -1932,21 +1949,20 @@ apply_forward (OT::hb_ot_apply_context_t *c, static inline bool apply_backward (OT::hb_ot_apply_context_t *c, - const OT::hb_ot_layout_lookup_accelerator_t &accel, - unsigned subtable_count) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; do { - if (accel.digest.may_have (buffer->cur().codepoint) && - (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props)) - ret |= accel.apply (c, subtable_count, false); + auto &cur = buffer->cur(); + if (accel.digest.may_have (cur.codepoint) && + (cur.mask & c->lookup_mask) && + c->check_glyph_property (&cur, c->lookup_props)) + ret |= accel.apply (c, false); /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; - } while ((int) buffer->idx >= 0); return ret; @@ -1959,7 +1975,6 @@ apply_string (OT::hb_ot_apply_context_t *c, const OT::hb_ot_layout_lookup_accelerator_t &accel) { hb_buffer_t *buffer = c->buffer; - unsigned subtable_count = lookup.get_subtable_count (); if (unlikely (!buffer->len || !c->lookup_mask)) return false; @@ -1975,7 +1990,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->clear_output (); buffer->idx = 0; - ret = apply_forward (c, accel, subtable_count); + ret = apply_forward (c, accel); if (!Proxy::always_inplace) buffer->sync (); @@ -1985,7 +2000,7 @@ apply_string (OT::hb_ot_apply_context_t *c, /* in-place backward substitution/positioning */ assert (!buffer->have_output); buffer->idx = buffer->len - 1; - ret = apply_backward (c, accel, subtable_count); + ret = apply_backward (c, accel); } return ret; @@ -1999,7 +2014,11 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, { const unsigned int table_index = proxy.table_index; unsigned int i = 0; - OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob ()); + + auto *font_data = font->data.ot.get (); + auto *var_store_cache = (OT::hb_scalar_cache_t *) font_data; + + OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob (), var_store_cache); c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func); for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) @@ -2017,11 +2036,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (buffer->messaging () && !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue; - /* c.digest is a digest of all the current glyphs in the buffer - * (plus some past glyphs). - * - * Only try applying the lookup if there is any overlap. */ - if (accel->digest.may_have (c.digest)) + /* Only try applying the lookup if there is any overlap. */ + if (accel->digest.may_intersect (buffer->digest)) { c.set_lookup_index (lookup_index); c.set_lookup_mask (lookup.mask, false); @@ -2047,7 +2063,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, if (stage->pause_func (plan, font, buffer)) { /* Refresh working buffer digest since buffer changed. */ - c.digest = buffer->digest (); + buffer->update_digest (); } } } @@ -2581,6 +2597,7 @@ hb_ot_layout_get_baseline_with_fallback2 (hb_font_t *font, #endif +#ifndef HB_NO_LAYOUT_RARELY_USED struct hb_get_glyph_alternates_dispatch_t : hb_dispatch_context_t { @@ -2600,19 +2617,19 @@ struct hb_get_glyph_alternates_dispatch_t : ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; -#ifndef HB_NO_LAYOUT_RARELY_USED /** * hb_ot_layout_lookup_get_glyph_alternates: * @face: a face. * @lookup_index: index of the feature lookup to query. * @glyph: a glyph id. * @start_offset: starting offset. - * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return; + * @alternate_count: (inout) (nullable): Input = the maximum number of alternate glyphs to return; * Output = the actual number of alternate glyphs returned (may be zero). * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. * Alternate glyphs associated with the glyph id. * - * Fetches alternates of a glyph from a given GSUB lookup index. + * Fetches alternates of a glyph from a given GSUB lookup index. Note that for one-to-one GSUB + * glyph substitutions, this function fetches the substituted glyph. * * Return value: Total number of alternates found in the specific lookup index for the given glyph id. * @@ -2633,6 +2650,64 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, return ret; } +struct hb_collect_glyph_alternates_dispatch_t : + hb_dispatch_context_t +{ + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return false; } + + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( (obj.collect_glyph_alternates (std::forward (ds)...), true) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) +}; + +/** + * hb_ot_layout_lookup_collect_glyph_alternates: + * @face: a face. + * @lookup_index: index of the feature lookup to query. + * @alternate_count: (inout): mapping from glyph index to number of alternates for that glyph. + * @alternate_glyphs: (inout): mapping from encoded glyph index and alternate index, to alternate glyph ids. + * + * Collects alternates of glyphs from a given GSUB lookup index. + * + * For one-to-one GSUB glyph substitutions, this function collects the + * substituted glyph. + * + * For lookups that assign multiple alternates to a glyph, all alternate glyphs are collected. + * + * For other lookup types, nothing is performed and `false` is returned. + * + * The `alternate_count` mapping will contain the number of alternates for each glyph id. + * Upon entry, this mapping should contain the glyph ids as keys, and the number of alternates + * currently known for each glyph id as values. + * + * The `alternate_glyphs` mapping will contain the alternate glyph ids for each glyph id. + * The mapping is encoded in the following way, upon entry and after processing: + * If G is the glyph id, and A0, A1, ..., A(n-1) are the alternate glyph ids, + * the mapping will contain the following entries: (G + (i << 24)) -> A(i) + * for i = 0, 1, ..., n-1 where n is the number of alternates for G as per `alternate_count`. + * + * Return value: `true` if alternates were collected, `false` otherwise. + * Since: 12.1.0 + */ +HB_EXTERN hb_bool_t +hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */) +{ + hb_collect_glyph_alternates_dispatch_t c; + const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); + return lookup.dispatch (&c, alternate_count, alternate_glyphs); +} struct hb_position_single_dispatch_t : hb_dispatch_context_t diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout.h b/thirdparty/harfbuzz/upstream/hb-ot-layout.h index 386b98d58..22060ccf0 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout.h +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout.h @@ -383,6 +383,12 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, unsigned *alternate_count /* IN/OUT */, hb_codepoint_t *alternate_glyphs /* OUT */); +HB_EXTERN hb_bool_t +hb_ot_layout_lookup_collect_glyph_alternates (hb_face_t *face, + unsigned lookup_index, + hb_map_t *alternate_count /* IN/OUT */, + hb_map_t *alternate_glyphs /* IN/OUT */); + HB_EXTERN hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, diff --git a/thirdparty/harfbuzz/upstream/hb-ot-layout.hh b/thirdparty/harfbuzz/upstream/hb-ot-layout.hh index f26bf51ab..945e73567 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-layout.hh @@ -202,7 +202,8 @@ enum hb_unicode_props_flags_t { /* If GEN_CAT=FORMAT, top byte masks: */ UPROPS_MASK_Cf_ZWJ = 0x0100u, UPROPS_MASK_Cf_ZWNJ = 0x0200u, - UPROPS_MASK_Cf_VS = 0x0400u + UPROPS_MASK_Cf_VS = 0x0400u, + UPROPS_MASK_Cf_AAT_DELETED = 0x0800u }; HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); @@ -216,8 +217,6 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (u >= 0x80u) { - buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; - if (unlikely (unicode->is_default_ignorable (u))) { buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; @@ -246,6 +245,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; props |= UPROPS_MASK_CONTINUATION; props |= unicode->modified_combining_class (u)<<8; } @@ -339,6 +339,11 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) !_hb_glyph_info_substituted (info); } static inline void +_hb_glyph_info_set_default_ignorable (hb_glyph_info_t *info) +{ + info->unicode_props() |= UPROPS_MASK_IGNORABLE; +} +static inline void _hb_glyph_info_clear_default_ignorable (hb_glyph_info_t *info) { info->unicode_props() &= ~ UPROPS_MASK_IGNORABLE; @@ -355,12 +360,13 @@ _hb_glyph_info_unhide (hb_glyph_info_t *info) } static inline void -_hb_glyph_info_set_continuation (hb_glyph_info_t *info) +_hb_glyph_info_set_continuation (hb_glyph_info_t *info, hb_buffer_t *buffer) { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS; info->unicode_props() |= UPROPS_MASK_CONTINUATION; } static inline void -_hb_glyph_info_reset_continuation (hb_glyph_info_t *info) +_hb_glyph_info_clear_continuation (hb_glyph_info_t *info) { info->unicode_props() &= ~ UPROPS_MASK_CONTINUATION; } @@ -381,6 +387,8 @@ _hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED, static inline void _hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer) { + // MONOTONE_GRAPHEMES was already applied and is taken care of by _hb_grapheme_group_func. + // So we just check for MONOTONE_CHARACTERS here. buffer->reverse_groups (_hb_grapheme_group_func, buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); } @@ -402,16 +410,16 @@ _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); } static inline bool -_hb_glyph_info_is_joiner (const hb_glyph_info_t *info) +_hb_glyph_info_is_aat_deleted (const hb_glyph_info_t *info) { - return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_AAT_DELETED); } static inline void -_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) +_hb_glyph_info_set_aat_deleted (hb_glyph_info_t *info) { - if (!_hb_glyph_info_is_unicode_format (info)) - return; - info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; + _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT); + info->unicode_props() |= UPROPS_MASK_Cf_AAT_DELETED; + info->unicode_props() |= UPROPS_MASK_HIDDEN; } /* lig_props: aka lig_id / lig_comp @@ -633,9 +641,22 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer) } /* Make sure no one directly touches our props... */ -#undef unicode_props0 -#undef unicode_props1 +#undef unicode_props #undef lig_props #undef glyph_props +static inline void +_hb_collect_glyph_alternates_add (hb_codepoint_t from, + hb_codepoint_t to, + hb_map_t *alternate_count, + hb_map_t *alternate_glyphs) +{ + hb_codepoint_t zero = 0; + hb_codepoint_t *i = &zero; + alternate_count->has (from, &i); + alternate_glyphs->set (from | (*i << 24), to); + alternate_count->set (from, *i + 1); +} + + #endif /* HB_OT_LAYOUT_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-map.cc b/thirdparty/harfbuzz/upstream/hb-ot-map.cc index fac73eb34..952ab3eb1 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-map.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-map.cc @@ -390,5 +390,19 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } } +unsigned int hb_ot_map_t::get_feature_tags (unsigned int start_offset, unsigned int *tag_count, hb_tag_t *tags) const +{ + if (tag_count) + { + auto sub_features = features.as_array ().sub_array (start_offset, tag_count); + if (tags) + { + for (unsigned int i = 0; i < sub_features.length; i++) + tags[i] = sub_features[i].tag; + } + } + + return features.length; +} #endif diff --git a/thirdparty/harfbuzz/upstream/hb-ot-map.hh b/thirdparty/harfbuzz/upstream/hb-ot-map.hh index 8af8129ce..185d133d7 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-map.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-map.hh @@ -166,6 +166,9 @@ struct hb_ot_map_t const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; + HB_INTERNAL unsigned int get_feature_tags (unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) const; public: hb_tag_t chosen_script[2]; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-math-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-math-table.hh index 5839059fd..f79808fa9 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-math-table.hh @@ -69,6 +69,8 @@ struct MathValueRecord struct MathConstants { + friend struct MATH; + MathConstants* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); @@ -1104,6 +1106,24 @@ struct MATH mathVariants.sanitize (c, this)); } + // https://github.com/harfbuzz/harfbuzz/issues/4653 + HB_INTERNAL bool is_bad_cambria (hb_font_t *font) const + { +#ifndef HB_NO_MATH + switch HB_CODEPOINT_ENCODE3 (font->face->table.MATH.get_blob ()->length, + (this+mathConstants).minHeight[1], // displayOperatorMinHeight + (this+mathConstants).minHeight[0]) // delimitedSubFormulaMinHeight + { + /* sha1sum:ab4a4fe054d23061f3c039493d6f665cfda2ecf5 cambria.ttc + * sha1sum:086855301bff644f9d8827b88491fcf73a6d4cb9 cambria.ttc + * sha1sum:b1e5a3feaca2ea3dfcf79ccb377de749ecf60343 cambria.ttc */ + case HB_CODEPOINT_ENCODE3 (25722, 2500, 3000): + return true; + } +#endif + return false; + } + hb_position_t get_constant (hb_ot_math_constant_t constant, hb_font_t *font) const { return (this+mathConstants).get_value (constant, font); } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-math.cc b/thirdparty/harfbuzz/upstream/hb-ot-math.cc index 876ad258e..719a802d5 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-math.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-math.cc @@ -87,6 +87,20 @@ hb_position_t hb_ot_math_get_constant (hb_font_t *font, hb_ot_math_constant_t constant) { + /* https://github.com/harfbuzz/harfbuzz/issues/4653 + * Cambria Math has incorrect value for displayOperatorMinHeight, and + * apparently Microsoft implementation swaps displayOperatorMinHeight and + * delimitedSubFormulaMinHeight, so we do the same if we detect Cambria Math + * with the swapped values. */ + if ((constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT || + constant == HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT) && + font->face->table.MATH->is_bad_cambria (font)) + { + if (constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT) + constant = HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT; + else + constant = HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT; + } return font->face->table.MATH->get_constant(constant, font); } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-os2-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-os2-table.hh index 6c9140226..c00d22b24 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-os2-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-os2-table.hh @@ -284,8 +284,8 @@ struct OS2 os2_prime->usWidthClass = width_class; } - os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ()); - os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_max ()); + os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->os2_info.min_cmap_codepoint); + os2_prime->usLastCharIndex = hb_min (0xFFFFu, c->plan->os2_info.max_cmap_codepoint); if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) return_trace (true); diff --git a/thirdparty/harfbuzz/upstream/hb-ot-post-macroman.hh b/thirdparty/harfbuzz/upstream/hb-ot-post-macroman.hh index b4df8aaee..269b4d3fe 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-post-macroman.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-post-macroman.hh @@ -31,264 +31,264 @@ #endif -_S(".notdef") -_S(".null") -_S("nonmarkingreturn") -_S("space") -_S("exclam") -_S("quotedbl") -_S("numbersign") -_S("dollar") -_S("percent") -_S("ampersand") -_S("quotesingle") -_S("parenleft") -_S("parenright") -_S("asterisk") -_S("plus") -_S("comma") -_S("hyphen") -_S("period") -_S("slash") -_S("zero") -_S("one") -_S("two") -_S("three") -_S("four") -_S("five") -_S("six") -_S("seven") -_S("eight") -_S("nine") -_S("colon") -_S("semicolon") -_S("less") -_S("equal") -_S("greater") -_S("question") -_S("at") -_S("A") -_S("B") -_S("C") -_S("D") -_S("E") -_S("F") -_S("G") -_S("H") -_S("I") -_S("J") -_S("K") -_S("L") -_S("M") -_S("N") -_S("O") -_S("P") -_S("Q") -_S("R") -_S("S") -_S("T") -_S("U") -_S("V") -_S("W") -_S("X") -_S("Y") -_S("Z") -_S("bracketleft") -_S("backslash") -_S("bracketright") -_S("asciicircum") -_S("underscore") -_S("grave") -_S("a") -_S("b") -_S("c") -_S("d") -_S("e") -_S("f") -_S("g") -_S("h") -_S("i") -_S("j") -_S("k") -_S("l") -_S("m") -_S("n") -_S("o") -_S("p") -_S("q") -_S("r") -_S("s") -_S("t") -_S("u") -_S("v") -_S("w") -_S("x") -_S("y") -_S("z") -_S("braceleft") -_S("bar") -_S("braceright") -_S("asciitilde") -_S("Adieresis") -_S("Aring") -_S("Ccedilla") -_S("Eacute") -_S("Ntilde") -_S("Odieresis") -_S("Udieresis") -_S("aacute") -_S("agrave") -_S("acircumflex") -_S("adieresis") -_S("atilde") -_S("aring") -_S("ccedilla") -_S("eacute") -_S("egrave") -_S("ecircumflex") -_S("edieresis") -_S("iacute") -_S("igrave") -_S("icircumflex") -_S("idieresis") -_S("ntilde") -_S("oacute") -_S("ograve") -_S("ocircumflex") -_S("odieresis") -_S("otilde") -_S("uacute") -_S("ugrave") -_S("ucircumflex") -_S("udieresis") -_S("dagger") -_S("degree") -_S("cent") -_S("sterling") -_S("section") -_S("bullet") -_S("paragraph") -_S("germandbls") -_S("registered") -_S("copyright") -_S("trademark") -_S("acute") -_S("dieresis") -_S("notequal") -_S("AE") -_S("Oslash") -_S("infinity") -_S("plusminus") -_S("lessequal") -_S("greaterequal") -_S("yen") -_S("mu") -_S("partialdiff") -_S("summation") -_S("product") -_S("pi") -_S("integral") -_S("ordfeminine") -_S("ordmasculine") -_S("Omega") -_S("ae") -_S("oslash") -_S("questiondown") -_S("exclamdown") -_S("logicalnot") -_S("radical") -_S("florin") -_S("approxequal") -_S("Delta") -_S("guillemotleft") -_S("guillemotright") -_S("ellipsis") -_S("nonbreakingspace") -_S("Agrave") -_S("Atilde") -_S("Otilde") -_S("OE") -_S("oe") -_S("endash") -_S("emdash") -_S("quotedblleft") -_S("quotedblright") -_S("quoteleft") -_S("quoteright") -_S("divide") -_S("lozenge") -_S("ydieresis") -_S("Ydieresis") -_S("fraction") -_S("currency") -_S("guilsinglleft") -_S("guilsinglright") -_S("fi") -_S("fl") -_S("daggerdbl") -_S("periodcentered") -_S("quotesinglbase") -_S("quotedblbase") -_S("perthousand") -_S("Acircumflex") -_S("Ecircumflex") -_S("Aacute") -_S("Edieresis") -_S("Egrave") -_S("Iacute") -_S("Icircumflex") -_S("Idieresis") -_S("Igrave") -_S("Oacute") -_S("Ocircumflex") -_S("apple") -_S("Ograve") -_S("Uacute") -_S("Ucircumflex") -_S("Ugrave") -_S("dotlessi") -_S("circumflex") -_S("tilde") -_S("macron") -_S("breve") -_S("dotaccent") -_S("ring") -_S("cedilla") -_S("hungarumlaut") -_S("ogonek") -_S("caron") -_S("Lslash") -_S("lslash") -_S("Scaron") -_S("scaron") -_S("Zcaron") -_S("zcaron") -_S("brokenbar") -_S("Eth") -_S("eth") -_S("Yacute") -_S("yacute") -_S("Thorn") -_S("thorn") -_S("minus") -_S("multiply") -_S("onesuperior") -_S("twosuperior") -_S("threesuperior") -_S("onehalf") -_S("onequarter") -_S("threequarters") -_S("franc") -_S("Gbreve") -_S("gbreve") -_S("Idotaccent") -_S("Scedilla") -_S("scedilla") -_S("Cacute") -_S("cacute") -_S("Ccaron") -_S("ccaron") -_S("dcroat") +HB_STR(".notdef") +HB_STR(".null") +HB_STR("nonmarkingreturn") +HB_STR("space") +HB_STR("exclam") +HB_STR("quotedbl") +HB_STR("numbersign") +HB_STR("dollar") +HB_STR("percent") +HB_STR("ampersand") +HB_STR("quotesingle") +HB_STR("parenleft") +HB_STR("parenright") +HB_STR("asterisk") +HB_STR("plus") +HB_STR("comma") +HB_STR("hyphen") +HB_STR("period") +HB_STR("slash") +HB_STR("zero") +HB_STR("one") +HB_STR("two") +HB_STR("three") +HB_STR("four") +HB_STR("five") +HB_STR("six") +HB_STR("seven") +HB_STR("eight") +HB_STR("nine") +HB_STR("colon") +HB_STR("semicolon") +HB_STR("less") +HB_STR("equal") +HB_STR("greater") +HB_STR("question") +HB_STR("at") +HB_STR("A") +HB_STR("B") +HB_STR("C") +HB_STR("D") +HB_STR("E") +HB_STR("F") +HB_STR("G") +HB_STR("H") +HB_STR("I") +HB_STR("J") +HB_STR("K") +HB_STR("L") +HB_STR("M") +HB_STR("N") +HB_STR("O") +HB_STR("P") +HB_STR("Q") +HB_STR("R") +HB_STR("S") +HB_STR("T") +HB_STR("U") +HB_STR("V") +HB_STR("W") +HB_STR("X") +HB_STR("Y") +HB_STR("Z") +HB_STR("bracketleft") +HB_STR("backslash") +HB_STR("bracketright") +HB_STR("asciicircum") +HB_STR("underscore") +HB_STR("grave") +HB_STR("a") +HB_STR("b") +HB_STR("c") +HB_STR("d") +HB_STR("e") +HB_STR("f") +HB_STR("g") +HB_STR("h") +HB_STR("i") +HB_STR("j") +HB_STR("k") +HB_STR("l") +HB_STR("m") +HB_STR("n") +HB_STR("o") +HB_STR("p") +HB_STR("q") +HB_STR("r") +HB_STR("s") +HB_STR("t") +HB_STR("u") +HB_STR("v") +HB_STR("w") +HB_STR("x") +HB_STR("y") +HB_STR("z") +HB_STR("braceleft") +HB_STR("bar") +HB_STR("braceright") +HB_STR("asciitilde") +HB_STR("Adieresis") +HB_STR("Aring") +HB_STR("Ccedilla") +HB_STR("Eacute") +HB_STR("Ntilde") +HB_STR("Odieresis") +HB_STR("Udieresis") +HB_STR("aacute") +HB_STR("agrave") +HB_STR("acircumflex") +HB_STR("adieresis") +HB_STR("atilde") +HB_STR("aring") +HB_STR("ccedilla") +HB_STR("eacute") +HB_STR("egrave") +HB_STR("ecircumflex") +HB_STR("edieresis") +HB_STR("iacute") +HB_STR("igrave") +HB_STR("icircumflex") +HB_STR("idieresis") +HB_STR("ntilde") +HB_STR("oacute") +HB_STR("ograve") +HB_STR("ocircumflex") +HB_STR("odieresis") +HB_STR("otilde") +HB_STR("uacute") +HB_STR("ugrave") +HB_STR("ucircumflex") +HB_STR("udieresis") +HB_STR("dagger") +HB_STR("degree") +HB_STR("cent") +HB_STR("sterling") +HB_STR("section") +HB_STR("bullet") +HB_STR("paragraph") +HB_STR("germandbls") +HB_STR("registered") +HB_STR("copyright") +HB_STR("trademark") +HB_STR("acute") +HB_STR("dieresis") +HB_STR("notequal") +HB_STR("AE") +HB_STR("Oslash") +HB_STR("infinity") +HB_STR("plusminus") +HB_STR("lessequal") +HB_STR("greaterequal") +HB_STR("yen") +HB_STR("mu") +HB_STR("partialdiff") +HB_STR("summation") +HB_STR("product") +HB_STR("pi") +HB_STR("integral") +HB_STR("ordfeminine") +HB_STR("ordmasculine") +HB_STR("Omega") +HB_STR("ae") +HB_STR("oslash") +HB_STR("questiondown") +HB_STR("exclamdown") +HB_STR("logicalnot") +HB_STR("radical") +HB_STR("florin") +HB_STR("approxequal") +HB_STR("Delta") +HB_STR("guillemotleft") +HB_STR("guillemotright") +HB_STR("ellipsis") +HB_STR("nonbreakingspace") +HB_STR("Agrave") +HB_STR("Atilde") +HB_STR("Otilde") +HB_STR("OE") +HB_STR("oe") +HB_STR("endash") +HB_STR("emdash") +HB_STR("quotedblleft") +HB_STR("quotedblright") +HB_STR("quoteleft") +HB_STR("quoteright") +HB_STR("divide") +HB_STR("lozenge") +HB_STR("ydieresis") +HB_STR("Ydieresis") +HB_STR("fraction") +HB_STR("currency") +HB_STR("guilsinglleft") +HB_STR("guilsinglright") +HB_STR("fi") +HB_STR("fl") +HB_STR("daggerdbl") +HB_STR("periodcentered") +HB_STR("quotesinglbase") +HB_STR("quotedblbase") +HB_STR("perthousand") +HB_STR("Acircumflex") +HB_STR("Ecircumflex") +HB_STR("Aacute") +HB_STR("Edieresis") +HB_STR("Egrave") +HB_STR("Iacute") +HB_STR("Icircumflex") +HB_STR("Idieresis") +HB_STR("Igrave") +HB_STR("Oacute") +HB_STR("Ocircumflex") +HB_STR("apple") +HB_STR("Ograve") +HB_STR("Uacute") +HB_STR("Ucircumflex") +HB_STR("Ugrave") +HB_STR("dotlessi") +HB_STR("circumflex") +HB_STR("tilde") +HB_STR("macron") +HB_STR("breve") +HB_STR("dotaccent") +HB_STR("ring") +HB_STR("cedilla") +HB_STR("hungarumlaut") +HB_STR("ogonek") +HB_STR("caron") +HB_STR("Lslash") +HB_STR("lslash") +HB_STR("Scaron") +HB_STR("scaron") +HB_STR("Zcaron") +HB_STR("zcaron") +HB_STR("brokenbar") +HB_STR("Eth") +HB_STR("eth") +HB_STR("Yacute") +HB_STR("yacute") +HB_STR("Thorn") +HB_STR("thorn") +HB_STR("minus") +HB_STR("multiply") +HB_STR("onesuperior") +HB_STR("twosuperior") +HB_STR("threesuperior") +HB_STR("onehalf") +HB_STR("onequarter") +HB_STR("threequarters") +HB_STR("franc") +HB_STR("Gbreve") +HB_STR("gbreve") +HB_STR("Idotaccent") +HB_STR("Scedilla") +HB_STR("scedilla") +HB_STR("Cacute") +HB_STR("cacute") +HB_STR("Ccaron") +HB_STR("ccaron") +HB_STR("dcroat") #endif /* HB_OT_POST_MACROMAN_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-post-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-post-table.hh index 18ecea182..2d8acd825 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-post-table.hh @@ -290,7 +290,7 @@ struct post const Array16Of *glyphNameIndex = nullptr; hb_vector_t index_to_offset; const uint8_t *pool = nullptr; - hb_atomic_ptr_t gids_sorted_by_name; + mutable hb_atomic_t gids_sorted_by_name; }; bool has_data () const { return version.to_int (); } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shape-fallback.cc b/thirdparty/harfbuzz/upstream/hb-ot-shape-fallback.cc index b2eedb027..ce7e0c03b 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shape-fallback.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shape-fallback.cc @@ -409,16 +409,13 @@ position_around_base (const hb_ot_shape_plan_t *plan, } static inline void -position_cluster (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - bool adjust_offsets_when_zeroing) +position_cluster_impl (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + bool adjust_offsets_when_zeroing) { - if (end - start < 2) - return; - /* Find the base glyph */ hb_glyph_info_t *info = buffer->info; for (unsigned int i = start; i < end; i++) @@ -427,8 +424,13 @@ position_cluster (const hb_ot_shape_plan_t *plan, /* Find mark glyphs */ unsigned int j; for (j = i + 1; j < end; j++) + { + if (_hb_glyph_info_is_hidden (&info[j]) || + _hb_glyph_info_is_default_ignorable (&info[j])) + continue; if (!_hb_glyph_info_is_unicode_mark (&info[j])) break; + } position_around_base (plan, font, buffer, i, j, adjust_offsets_when_zeroing); @@ -436,6 +438,20 @@ position_cluster (const hb_ot_shape_plan_t *plan, } } +static HB_ALWAYS_INLINE void +position_cluster (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end, + bool adjust_offsets_when_zeroing) +{ + if (end - start < 2) + return; + + position_cluster_impl (plan, font, buffer, start, end, adjust_offsets_when_zeroing); +} + void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, @@ -455,7 +471,9 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]))) { + if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]) && + !_hb_glyph_info_is_hidden (&info[i]) && + !_hb_glyph_info_is_default_ignorable (&info[i]))) { position_cluster (plan, font, buffer, start, i, adjust_offsets_when_zeroing); start = i; } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.cc index 2d093f78b..e9dbcd77a 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.cc @@ -78,14 +78,14 @@ static inline void set_glyph (hb_glyph_info_t &info, hb_font_t *font) { - (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index()); + (void) font->get_nominal_glyph (info.codepoint, &info.normalizer_glyph_index()); } static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { /* This is very confusing indeed. */ - buffer->cur().glyph_index() = glyph; + buffer->cur().normalizer_glyph_index() = glyph; (void) buffer->output_glyph (unichar); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); } @@ -93,7 +93,7 @@ output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) static inline void next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) { - buffer->cur().glyph_index() = glyph; + buffer->cur().normalizer_glyph_index() = glyph; (void) buffer->next_glyph (); } @@ -210,7 +210,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, hb_font_t * const font = c->font; for (; buffer->idx < end - 1 && buffer->successful;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { - if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) + if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().normalizer_glyph_index())) { hb_codepoint_t unicode = buffer->cur().codepoint; (void) buffer->replace_glyphs (2, 1, &unicode); @@ -342,7 +342,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, unsigned int done = font->get_nominal_glyphs (end - buffer->idx, &buffer->cur().codepoint, sizeof (buffer->info[0]), - &buffer->cur().glyph_index(), + &buffer->cur().normalizer_glyph_index(), sizeof (buffer->info[0])); if (unlikely (!buffer->next_glyphs (done))) break; } @@ -456,7 +456,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->out_len--; /* Remove the second composable. */ /* Modify starter and carry on. */ buffer->out_info[starter].codepoint = composed; - buffer->out_info[starter].glyph_index() = glyph; + buffer->out_info[starter].normalizer_glyph_index() = glyph; _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); continue; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.hh b/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.hh index f12cb35c0..2f282f347 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shape-normalize.hh @@ -32,7 +32,7 @@ /* buffer var allocations, used during the normalization process */ -#define glyph_index() var1.u32 +#define normalizer_glyph_index() var1.u32 struct hb_ot_shape_plan_t; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shape.cc b/thirdparty/harfbuzz/upstream/hb-ot-shape.cc index 59b97a799..7b3b854d5 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shape.cc @@ -44,8 +44,12 @@ #include "hb-ot-face.hh" #include "hb-set.hh" +#include "hb-unicode.hh" #include "hb-aat-layout.hh" +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-stat-table.hh" + static inline bool _hb_codepoint_is_regional_indicator (hb_codepoint_t u) @@ -82,13 +86,14 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac props (props), map (face, props) #ifndef HB_NO_AAT_SHAPE + , aat_map (face, props) , apply_morx (_hb_apply_morx (face, props)) #endif { shaper = hb_ot_shaper_categorize (props.script, props.direction, map.chosen_script[0]); script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; - script_fallback_mark_positioning = shaper->fallback_position; + script_fallback_position = shaper->fallback_position; #ifndef HB_NO_AAT_SHAPE /* https://github.com/harfbuzz/harfbuzz/issues/1528 */ @@ -104,6 +109,10 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, key); +#ifndef HB_NO_AAT_SHAPE + if (apply_morx) + aat_map.compile (plan.aat_map); +#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); @@ -121,10 +130,6 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.kern_mask = plan.map.get_mask (kern_tag); plan.requested_kerning = !!plan.kern_mask; #endif -#ifndef HB_NO_AAT_SHAPE - plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k')); - plan.requested_tracking = !!plan.trak_mask; -#endif bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX; bool disable_gpos = plan.shaper->gpos_tag && @@ -174,12 +179,12 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif #ifndef HB_NO_OT_KERN else if (hb_ot_layout_has_kerning (face)) - plan.apply_kern = true; + plan.apply_kern = script_fallback_position; // Not all shapers apply legacy `kern` #endif else {} } - plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); + plan.apply_fallback_kern = script_fallback_position && !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); plan.zero_marks = script_zero_marks && !plan.apply_kerx && @@ -199,7 +204,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, ); plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing && - script_fallback_mark_positioning; + script_fallback_position; #ifndef HB_NO_AAT_SHAPE /* If we're using morx shaping, we cancel mark position adjustment because @@ -208,8 +213,13 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (plan.apply_morx) plan.adjust_mark_positioning_when_zeroing = false; - /* Currently we always apply trak. */ - plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + plan.apply_trak = hb_aat_layout_has_tracking (face) && face->table.STAT->has_data (); +#else + plan.apply_trak = false; +#endif + #endif } @@ -346,13 +356,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, /* Random! */ map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE); -#ifndef HB_NO_AAT_SHAPE - /* Tracking. We enable dummy feature here just to allow disabling - * AAT 'trak' table using features. - * https://github.com/harfbuzz/harfbuzz/issues/1303 */ - map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK); -#endif - map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */ map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ @@ -422,17 +425,21 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) * shaper font data */ -struct hb_ot_font_data_t {}; +struct hb_ot_font_data_t { + OT::hb_scalar_cache_t unused; // Just for alignment +}; hb_ot_font_data_t * -_hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED) +_hb_ot_shaper_font_data_create (hb_font_t *font) { - return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; + const OT::ItemVariationStore &var_store = font->face->table.GDEF->table->get_var_store (); + return (hb_ot_font_data_t *) var_store.create_cache (); } void -_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED) +_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data) { + OT::ItemVariationStore::destroy_cache ((OT::hb_scalar_cache_t *) data); } @@ -477,6 +484,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) { _hb_glyph_info_set_unicode_props (&info[i], buffer); + if (info[i].codepoint < 0x80) + continue; + unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]); if (FLAG_UNSAFE (gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | @@ -491,7 +501,7 @@ hb_set_unicode_props (hb_buffer_t *buffer) if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && hb_in_range (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) { - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } /* Regional_Indicators are hairy as hell... * https://github.com/harfbuzz/harfbuzz/issues/2265 */ @@ -499,18 +509,18 @@ hb_set_unicode_props (hb_buffer_t *buffer) { if (_hb_codepoint_is_regional_indicator (info[i - 1].codepoint) && !_hb_glyph_info_is_continuation (&info[i - 1])) - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } #ifndef HB_NO_EMOJI_SEQUENCES else if (unlikely (_hb_glyph_info_is_zwj (&info[i]))) { - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); if (i + 1 < count && _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint)) { i++; _hb_glyph_info_set_unicode_props (&info[i], buffer); - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); } } #endif @@ -529,7 +539,9 @@ hb_set_unicode_props (hb_buffer_t *buffer) * https://github.com/harfbuzz/harfbuzz/issues/3844 */ else if (unlikely (hb_in_ranges (info[i].codepoint, 0xFF9Eu, 0xFF9Fu, 0xE0020u, 0xE007Fu))) - _hb_glyph_info_set_continuation (&info[i]); + _hb_glyph_info_set_continuation (&info[i], buffer); + else if (unlikely (info[i].codepoint == 0x2044u /* FRACTION SLASH */)) + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH; } } @@ -565,15 +577,11 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS)) return; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - foreach_grapheme (buffer, start, end) - buffer->merge_clusters (start, end); - else - foreach_grapheme (buffer, start, end) - buffer->unsafe_to_break (start, end); + foreach_grapheme (buffer, start, end) + buffer->merge_grapheme_clusters (start, end); } static void @@ -607,14 +615,14 @@ hb_ensure_native_direction (hb_buffer_t *buffer) for (unsigned i = 0; i < count; i++) { auto gc = _hb_glyph_info_get_general_category (&info[i]); - if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) - found_number = true; - else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) + if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) { found_letter = true; break; } - else if (_hb_codepoint_is_regional_indicator (info[i].codepoint)) + else if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + found_number = true; + else if (unlikely (_hb_codepoint_is_regional_indicator (info[i].codepoint))) found_ri = true; } if ((found_number || found_ri) && !found_letter) @@ -626,7 +634,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Ogham fonts are supposed to be implemented BTT or not. Need to research that * first. */ if ((HB_DIRECTION_IS_HORIZONTAL (direction) && - direction != horiz_dir && horiz_dir != HB_DIRECTION_INVALID) || + direction != horiz_dir && HB_DIRECTION_IS_VALID (horiz_dir)) || (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { @@ -640,59 +648,6 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Substitute */ -#ifndef HB_NO_VERTICAL -static hb_codepoint_t -hb_vert_char_for (hb_codepoint_t u) -{ - switch (u >> 8) - { - case 0x20: switch (u) { - case 0x2013u: return 0xfe32u; // EN DASH - case 0x2014u: return 0xfe31u; // EM DASH - case 0x2025u: return 0xfe30u; // TWO DOT LEADER - case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS - } break; - case 0x30: switch (u) { - case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA - case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP - case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET - case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET - case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET - case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET - case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET - case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET - case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET - case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET - case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET - case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET - case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET - case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET - case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET - case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET - } break; - case 0xfe: switch (u) { - case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE - } break; - case 0xff: switch (u) { - case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK - case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS - case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS - case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA - case 0xff1au: return 0xfe13u; // FULLWIDTH COLON - case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON - case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK - case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET - case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET - case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE - case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET - case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET - } break; - } - - return u; -} -#endif - static inline void hb_ot_rotate_chars (const hb_ot_shape_context_t *c) { @@ -718,7 +673,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) { for (unsigned int i = 0; i < count; i++) { - hb_codepoint_t codepoint = hb_vert_char_for (info[i].codepoint); + hb_codepoint_t codepoint = hb_unicode_funcs_t::vertical_char_for (info[i].codepoint); if (unlikely (codepoint != info[i].codepoint && c->font->has_glyph (codepoint))) info[i].codepoint = codepoint; } @@ -733,7 +688,7 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c) return; #endif - if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || + if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH) || !c->plan->has_frac) return; @@ -834,7 +789,13 @@ hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) unsigned int i = 0; for (i = 0; i < count; i++) if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + { + pos[i].x_advance = pos[i].y_advance = 0; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + pos[i].x_offset = 0; + else + pos[i].y_offset = 0; + } } static void @@ -889,11 +850,11 @@ hb_ot_hide_default_ignorables (hb_buffer_t *buffer, static inline void hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { - /* Normalization process sets up glyph_index(), we just copy it. */ + /* Normalization process sets up normalizer_glyph_index(), we just copy it. */ unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].codepoint = info[i].glyph_index(); + info[i].codepoint = info[i].normalizer_glyph_index(); buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; } @@ -931,7 +892,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) hb_ot_rotate_chars (c); - HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); + HB_BUFFER_ALLOCATE_VAR (buffer, normalizer_glyph_index); _hb_ot_shape_normalize (c->plan, buffer, c->font); @@ -943,7 +904,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c) hb_ot_map_glyphs_fast (buffer); - HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); + HB_BUFFER_DEALLOCATE_VAR (buffer, normalizer_glyph_index); } static inline void @@ -958,11 +919,17 @@ hb_ot_substitute_plan (const hb_ot_shape_context_t *c) #ifndef HB_NO_AAT_SHAPE if (unlikely (c->plan->apply_morx)) + { hb_aat_layout_substitute (c->plan, c->font, c->buffer, c->user_features, c->num_user_features); + c->buffer->update_digest (); + } else #endif + { + c->buffer->update_digest (); c->plan->substitute (c->font, buffer); + } } static inline void @@ -1043,23 +1010,16 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) { c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]), &pos[0].x_advance, sizeof(pos[0])); - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->subtract_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->subtract_glyph_h_origins (c->buffer); } else { c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]), &pos[0].y_advance, sizeof(pos[0])); - for (unsigned int i = 0; i < count; i++) - { - c->font->subtract_glyph_v_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); - } + // v_origin defaults to non-zero; apply even if only fallback is there. + c->font->subtract_glyph_v_origins (c->buffer); } if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); @@ -1068,10 +1028,6 @@ hb_ot_position_default (const hb_ot_shape_context_t *c) static inline void hb_ot_position_plan (const hb_ot_shape_context_t *c) { - unsigned int count = c->buffer->len; - hb_glyph_info_t *info = c->buffer->info; - hb_glyph_position_t *pos = c->buffer->pos; - /* If the font has no GPOS and direction is forward, then when * zeroing mark widths, we shift the mark with it, such that the * mark is positioned hanging over the previous glyph. When @@ -1086,12 +1042,9 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->add_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->add_glyph_h_origins (c->buffer); hb_ot_layout_position_start (c->font, c->buffer); @@ -1126,18 +1079,11 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) /* Finish off. Has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c->buffer); -#ifndef HB_NO_AAT_SHAPE - if (c->plan->apply_morx) - hb_aat_layout_zero_width_deleted_glyphs (c->buffer); -#endif hb_ot_layout_position_finish_offsets (c->font, c->buffer); - /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ - if (c->font->has_glyph_h_origin_func ()) - for (unsigned int i = 0; i < count; i++) - c->font->subtract_glyph_h_origin (info[i].codepoint, - &pos[i].x_offset, - &pos[i].y_offset); + // h_origin defaults to zero; only apply it if the font has it. + if (c->font->has_glyph_h_origin_func () || c->font->has_glyph_h_origins_func ()) + c->font->subtract_glyph_h_origins (c->buffer); if (c->plan->fallback_mark_positioning) _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer, @@ -1165,8 +1111,33 @@ hb_propagate_flags (hb_buffer_t *buffer) /* Propagate cluster-level glyph flags to be the same on all cluster glyphs. * Simplifies using them. */ - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS)) + hb_mask_t and_mask = HB_GLYPH_FLAG_DEFINED; + if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0) + and_mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + + hb_glyph_info_t *info = buffer->info; + + if ((buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL) == 0) + { + foreach_cluster (buffer, start, end) + { + if (end - start == 1) + { + info[start].mask &= and_mask; + continue; + } + + unsigned int mask = 0; + for (unsigned int i = start; i < end; i++) + mask |= info[i].mask; + + mask &= and_mask; + + for (unsigned int i = start; i < end; i++) + info[i].mask = mask; + } return; + } /* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things: * @@ -1174,30 +1145,20 @@ hb_propagate_flags (hb_buffer_t *buffer) * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL, * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK. * - * We couldn't make this interaction earlier. It has to be done here. + * We couldn't make this interaction earlier. It has to be done this way. */ - bool flip_tatweel = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL; - - bool clear_concat = (buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0; - - hb_glyph_info_t *info = buffer->info; - foreach_cluster (buffer, start, end) { unsigned int mask = 0; for (unsigned int i = start; i < end; i++) - mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED; + mask |= info[i].mask; - if (flip_tatweel) - { - if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) - mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; - if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) - mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; - } + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL; + if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL) + mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; - if (clear_concat) - mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + mask &= and_mask; for (unsigned int i = start; i < end; i++) info[i].mask = mask; @@ -1238,8 +1199,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; - - c->buffer->leave (); } @@ -1277,6 +1236,36 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, } +/** + * hb_ot_shape_plan_get_feature_tags: + * @shape_plan: A shaping plan + * @start_offset: The index of first feature to retrieve + * @tag_count: (inout): Input = the maximum number of features to return; + * Output = the actual number of features returned (may be zero) + * @tags: (out) (array length=tag_count): The array of enabled feature + * + * Fetches the list of OpenType feature tags enabled for a shaping plan, if possible. + * + * Return value: Total number of feature tagss. + * + * Since: 10.3.0 + */ +unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */) +{ +#ifndef HB_NO_OT_SHAPE + return shape_plan->ot.map.get_feature_tags (start_offset, tag_count, tags); +#else + if (tag_count) + *tag_count = 0; + return 0; +#endif +} + + /* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */ static void add_char (hb_font_t *font, diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shape.h b/thirdparty/harfbuzz/upstream/hb-ot-shape.h index afdff7283..80063f775 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shape.h +++ b/thirdparty/harfbuzz/upstream/hb-ot-shape.h @@ -48,6 +48,12 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, hb_set_t *lookup_indexes /* OUT */); +HB_EXTERN unsigned int +hb_ot_shape_plan_get_feature_tags (hb_shape_plan_t *shape_plan, + unsigned int start_offset, + unsigned int *tag_count, /* IN/OUT */ + hb_tag_t *tags /* OUT */); + HB_END_DECLS #endif /* HB_OT_SHAPE_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shape.hh b/thirdparty/harfbuzz/upstream/hb-ot-shape.hh index f84aa5c49..c30b2cfd4 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shape.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shape.hh @@ -51,7 +51,8 @@ struct hb_ot_shape_plan_key_t bool equal (const hb_ot_shape_plan_key_t *other) { - return 0 == hb_memcmp (this, other, sizeof (*this)); + return variations_index[0] == other->variations_index[0] && + variations_index[1] == other->variations_index[1]; } }; @@ -65,6 +66,7 @@ struct hb_ot_shape_plan_t hb_segment_properties_t props; const struct hb_ot_shaper_t *shaper; hb_ot_map_t map; + hb_aat_map_t aat_map; const void *data; #ifndef HB_NO_OT_SHAPE_FRACTIONS hb_mask_t frac_mask, numr_mask, dnom_mask; @@ -79,22 +81,12 @@ struct hb_ot_shape_plan_t #else static constexpr hb_mask_t kern_mask = 0; #endif -#ifndef HB_NO_AAT_SHAPE - hb_mask_t trak_mask; -#else - static constexpr hb_mask_t trak_mask = 0; -#endif #ifndef HB_NO_OT_KERN bool requested_kerning : 1; #else static constexpr bool requested_kerning = false; #endif -#ifndef HB_NO_AAT_SHAPE - bool requested_tracking : 1; -#else - static constexpr bool requested_tracking = false; -#endif #ifndef HB_NO_OT_SHAPE_FRACTIONS bool has_frac : 1; #else @@ -152,12 +144,13 @@ struct hb_ot_shape_planner_t hb_segment_properties_t props; hb_ot_map_builder_t map; #ifndef HB_NO_AAT_SHAPE + hb_aat_map_builder_t aat_map; bool apply_morx : 1; #else static constexpr bool apply_morx = false; #endif bool script_zero_marks : 1; - bool script_fallback_mark_positioning : 1; + bool script_fallback_position : 1; const struct hb_ot_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-fallback.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-fallback.hh index 66a8bfbd2..b82de35aa 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-fallback.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-fallback.hh @@ -355,6 +355,8 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) { + if (fallback_plan->accel_array[i]) + fallback_plan->accel_array[i]->fini (); hb_free (fallback_plan->accel_array[i]); if (fallback_plan->free_lookups) hb_free (fallback_plan->lookup_array[i]); diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-joining-list.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-joining-list.hh index e38686e3e..79d3014d3 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-joining-list.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT */ #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-pua.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-pua.hh index ba86772f8..7464e5d8a 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-pua.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-pua.hh @@ -9,41 +9,43 @@ #ifndef HB_OT_SHAPER_ARABIC_PUA_HH #define HB_OT_SHAPER_ARABIC_PUA_HH -static const uint8_t -_hb_arabic_u8[464] = +#include "hb.hh" + +#include + +static const uint8_t _hb_arabic_pua_u8[453]= { - 84, 86, 85, 85, 85, 85, 85,213, 16, 34, 34, 34, 34, 34, 35, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 36, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 82, 16, 0, 0, 0, 0, 1, 2, 3, 4, - 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 7, - 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 0, 0, 0, 22, 0, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 16, 34, 34, 34, 35, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 66, 16, 50, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68,101, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 71, 68, 68, 68, 68, 68, 68, 68,152,186, 76, 77, 68,254, 16, 50, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 5, 6, - 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 3, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 7, 0, 0, 8, 0, 0, 0, 9, 0, 0, + 10, 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0, + 22, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 33, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 67, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,101, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,152, + 186, 12, 13, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, + 5, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 13, 0, 0, 0, 0, 0, 14, 0, 0, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 1, 24, 25, 26, 27, 28, 1, 1, 29, 30, 31, 32, + 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 0, 0, 0, 0, 0, 0, + 0, 39, 0, 0, 40, 41, 42, 0, 43, 44, 0, 0, 45, 46, 0, 47, + 48, 49, 0, 0, 0, 0, 50, 0, 0, 51, 52, 0, 53, 54, 55, 56, + 57, 58, 0, 0, 0, 0, 0, 59, 60, 61, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 23, 23, 29, 30, 31, 32, 33, 0, 0, 0, 0, - 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 40, - 41, 42, 0, 43, 44, 0, 0, 45, 46, 0, 47, 48, 49, 0, 0, 0, - 0, 50, 0, 0, 51, 52, 0, 53, 54, 55, 56, 57, 58, 0, 0, 0, - 0, 0, 59, 60, 61, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 66, - 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 0, 65, 0, 0, 66, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, }; -static const uint16_t -_hb_arabic_u16[720] = +static const uint16_t _hb_arabic_pua_u16[717]= { 0, 0, 0, 0, 0, 0, 0, 0,61728,61729,61730, 0, 0,61733, 0, 0, 61736,61737,61738,61739,61790,61741,61742,61743,61872,61873,61874,61875,61876,61877,61878,61879, @@ -65,52 +67,46 @@ _hb_arabic_u16[720] = 61808,61813,61813,61811,61812,61816,61816,61814,61815,61818,61818,61817,61817,61820,61820,61819, 61819,61822,61822,61821,61821,61921,61921,61823,61823,61860,61859,61857,61858,61861,61861,61868, 61867,61864,61863,61862,61862,61888,61889,61886,61887,61890,61891,61885,61884, 0, 0, 0, - 0, 0, 0, 0,61984,61985,61986, 0, 0,61989, 0, 0,61992,61993,61994,61995, - 62046,61997,61998,61999, 0, 0,62010,62011, 0,62013, 0,62015, 0, 0, 0,62043, - 0,62045, 0, 0, 0, 0, 0,61987, 0, 0, 0,61988, 0, 0, 0,61990, - 0, 0, 0,61991,61996, 0, 0, 0, 0, 0, 0,62011, 0, 0, 0,62015, - 0,62165,62021,62019,62170,62023,62169,62017,62028,62161,62032,62036,62040,62048,62052,62053, - 62055,62057,62059,62064,62068,62072,62078,62114,62115,62122,62126,61952,61952,61952,61952,61952, - 62047,62130,62134,62138,62142,62146,62150,62154,62155,62164,62160,62183,62184,62187,62180,62181, - 62186,62185,62182,61952,61952,61952,61952, 0,62000,62001,62002,62003,62004,62005,62006,62007, - 62008,62009, 0,62046,62046, 0, 0, 0,61964,61965,61966,61967,62012,62014, 0, 0, - 61954, 0,61981, 0, 0, 0,61955, 0,61982, 0,61956, 0, 0, 0,62111, 0, - 0, 0, 0,61970,61971,61972,61957, 0,61980, 0, 0, 0, 0, 0,61958, 0, - 61983, 0, 0, 0, 0, 0,62191, 0,62188,62189,62192, 0, 0, 0,61973, 0, - 0,62098, 0, 0,61974, 0, 0,62099, 0, 0,62101, 0, 0,61975, 0, 0, - 62100, 0, 0, 0,62080,62081,62082,62102, 0,62083,62084,62085,62103, 0, 0, 0, - 62106, 0,62107, 0,62108, 0, 0, 0,61976, 0, 0, 0, 0,62086,62087,62088, - 62109,61978,62089,62090,62091,62110,62093,62094, 0,62104, 0, 0, 0, 0,62095,62096, - 62097,62105, 0, 0,61977, 0, 0, 0, 0, 0,62075,62077,61968, 0, 0, 0, - 0,62021,62022,62019,62020,62170,62171,62023,62024,62169,62168,62166,62167,62017,62018,62028, - 62027,62025,62026,62161,62162,62032,62031,62029,62030,62036,62035,62033,62034,62040,62039,62037, - 62038,62048,62044,62041,62042,62052,62051,62049,62050,62053,62054,62055,62056,62057,62058,62059, - 62060,62064,62063,62061,62062,62068,62067,62065,62066,62072,62071,62069,62070,62078,62076,62073, - 62074,62114,62113,62079,62193,62118,62117,62115,62116,62122,62121,62119,62120,62126,62125,62123, - 62124,62130,62129,62127,62128,62134,62133,62131,62132,62138,62137,62135,62136,62142,62141,62139, - 62140,62146,62145,62143,62144,62150,62149,62147,62148,62154,62153,62151,62152,62155,62156,62164, - 62163,62160,62159,62157,62158,62176,62177,62174,62175,62178,62179,62172,62173, 0, 0, 0, + 0,61952,61952,61952,61952,61984,61985,61986, 0, 0,61989, 0, 0,61992,61993,61994, + 61995,62046,61997,61998,61999, 0, 0,62010,62011, 0,62013, 0,62015, 0, 0, 0, + 62043, 0,62045, 0, 0, 0, 0, 0,61987, 0, 0, 0,61988, 0, 0, 0, + 61990, 0, 0, 0,61991,61996, 0, 0, 0, 0, 0, 0,62011, 0, 0, 0, + 62015, 0,62165,62021,62019,62170,62023,62169,62017,62028,62161,62032,62036,62040,62048,62052, + 62053,62055,62057,62059,62064,62068,62072,62078,62114,62115,62122,62126,61952,62047,62130,62134, + 62138,62142,62146,62150,62154,62155,62164,62160,62183,62184,62187,62180,62181,62186,62185,62182, + 61952,61952,61952,61952, 0,62000,62001,62002,62003,62004,62005,62006,62007,62008,62009, 0, + 62046,62046, 0, 0, 0,61964,61965,61966,61967,62012,62014, 0, 0,61954, 0,61981, + 0, 0, 0,61955, 0,61982, 0,61956, 0, 0, 0,62111, 0, 0, 0, 0, + 61970,61971,61972,61957, 0,61980, 0, 0, 0, 0, 0,61958, 0,61983, 0, 0, + 0, 0, 0,62191, 0,62188,62189,62192, 0, 0, 0,61973, 0, 0,62098, 0, + 0,61974, 0, 0,62099, 0, 0,62101, 0, 0,61975, 0, 0,62100, 0, 0, + 0,62080,62081,62082,62102, 0,62083,62084,62085,62103, 0, 0, 0,62106, 0,62107, + 0,62108, 0, 0, 0,61976, 0, 0, 0, 0,62086,62087,62088,62109,61978,62089, + 62090,62091,62110,62093,62094, 0,62104, 0, 0, 0, 0,62095,62096,62097,62105, 0, + 0,61977, 0, 0, 0, 0, 0,62075,62077,61968, 0, 0, 0, 0,62021,62022, + 62019,62020,62170,62171,62023,62024,62169,62168,62166,62167,62017,62018,62028,62027,62025,62026, + 62161,62162,62032,62031,62029,62030,62036,62035,62033,62034,62040,62039,62037,62038,62048,62044, + 62041,62042,62052,62051,62049,62050,62053,62054,62055,62056,62057,62058,62059,62060,62064,62063, + 62061,62062,62068,62067,62065,62066,62072,62071,62069,62070,62078,62076,62073,62074,62114,62113, + 62079,62193,62118,62117,62115,62116,62122,62121,62119,62120,62126,62125,62123,62124,62130,62129, + 62127,62128,62134,62133,62131,62132,62138,62137,62135,62136,62142,62141,62139,62140,62146,62145, + 62143,62144,62150,62149,62147,62148,62154,62153,62151,62152,62155,62156,62164,62163,62160,62159, + 62157,62158,62176,62177,62174,62175,62178,62179,62172,62173, 0, 0, 0, }; -static inline unsigned -_hb_arabic_b2 (const uint8_t* a, unsigned i) -{ - return (a[i>>2]>>((i&3u)<<1))&3u; -} -static inline unsigned -_hb_arabic_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_arabic_pua_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast16_t -_hb_arabic_pua_simp_map (unsigned u) +static inline uint16_t _hb_arabic_pua_simp_map (unsigned u) { - return u<65277u?_hb_arabic_u16[((_hb_arabic_u8[40+(((_hb_arabic_b4(8+_hb_arabic_u8,((_hb_arabic_b2(_hb_arabic_u8,u>>3>>4>>4))<<4)+((u>>3>>4)&15u)))<<4)+((u>>3)&15u))])<<3)+((u)&7u)]:0; + /* packtab: [2^2,2^4,2^4,2^3] */ + return u<65277u ? (uint16_t)(_hb_arabic_pua_u16[((_hb_arabic_pua_u8[31u+((_hb_arabic_pua_b4(_hb_arabic_pua_u8,((((13835058055282164225ULL>>((((((((u)>>3))>>4))>>4))<<1))&3))<<4)+((((((u)>>3))>>4))&15)))<<4)+((((u)>>3))&15)])<<3)+((u)&7)]) : 0; } -static inline uint_fast16_t -_hb_arabic_pua_trad_map (unsigned u) +static inline uint16_t _hb_arabic_pua_trad_map (unsigned u) { - return u<65277u?_hb_arabic_u16[320+(((_hb_arabic_u8[208+(((_hb_arabic_b4(168+_hb_arabic_u8,((_hb_arabic_b4(136+_hb_arabic_u8,u>>2>>4>>4))<<4)+((u>>2>>4)&15u)))<<4)+((u>>2)&15u))])<<2)+((u)&3u))]:0; + /* packtab: [2^4,2^4,2^4,2^2] */ + return u<65277u ? (uint16_t)(_hb_arabic_pua_u16[317u+((_hb_arabic_pua_u8[197u+((_hb_arabic_pua_b4(_hb_arabic_pua_u8+159u,((_hb_arabic_pua_b4(_hb_arabic_pua_u8+127u,((((((u)>>2))>>4))>>4)))<<4)+((((((u)>>2))>>4))&15)))<<4)+((((u)>>2))&15)])<<2)+((u)&3)]) : 0; } #endif /* HB_OT_SHAPER_ARABIC_PUA_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-table.hh index d9917a158..39da24b8b 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic-table.hh @@ -6,232 +6,87 @@ * * on files with these headers: * - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 * UnicodeData.txt does not have a header. */ #ifndef HB_OT_SHAPER_ARABIC_TABLE_HH #define HB_OT_SHAPER_ARABIC_TABLE_HH +#include "hb.hh" -#define A JOINING_GROUP_ALAPH -#define DR JOINING_GROUP_DALATH_RISH -#define C JOINING_TYPE_C -#define D JOINING_TYPE_D -#define L JOINING_TYPE_L -#define R JOINING_TYPE_R -#define T JOINING_TYPE_T -#define U JOINING_TYPE_U -#define X JOINING_TYPE_X +#include -static const uint8_t joining_table[] = +static const uint8_t _hb_arabic_joining_u8[737]= { + 0, 16, 2, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96,135, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 16, 24, 32, 40, 48, 0, 56, 0, 64, 72, 80, 0, + 0, 0, 0, 88, 96,104, 0, 0, 0, 0, 0,112,120, 0, 0, 0, + 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 0, + 0,144, 0, 0, 0, 0, 0,152, 0, 0, 0, 0, 0, 0,160,168, + 176,184,192, 0, 0,200,208, 0, 0, 0, 0, 0, 0, 0, 0,216, + 224, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 10, 11, 12, + 1, 1, 13, 0, 0, 0, 14, 15, 1, 1, 2, 2, 4, 1, 1, 1, + 1, 16, 17, 18, 3, 0, 19, 0, 20, 0, 21, 22, 23, 1, 24, 0, + 0, 0, 25, 1, 26, 1, 27, 28, 4, 0, 29, 1, 1, 1, 30, 0, + 31, 32, 5, 33, 34, 35, 36, 2, 2, 37, 38, 6, 0, 1, 39, 40, + 5, 1, 7, 0, 0, 41, 0, 0, 0, 42, 43, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 7, 44, 1, 1, 1, 1, 45, 0, + 0, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, 6, 0, + 0, 1, 1, 1, 1, 1, 1, 49, 0, 50, 51, 52, 53, 54, 55, 0, + 0, 56, 57, 58, 0, 0, 59, 0, 0, 60, 1, 1, 1, 61, 0, 0, + 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, + 1, 64, 0, 65, 0, 0, 0, 66, 1, 67, 0, 0, 0, 0, 0, 68, + 69, 70, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 72, 73, 0, 0, 0, 0, 0, 0,119,119,119,119, 51, 51, 51, + 51, 34, 34, 34, 34,119,119, 7,119, 34, 51, 51, 51, 35, 51, 51, + 51, 0,119,119,119,115,119,119,119, 0, 0, 0,119,112, 7,119, + 119, 3, 34, 34, 35, 35, 51, 51, 35, 34, 50, 51, 51, 50,115,119, + 119,119,119,119, 51, 39, 34, 32, 34, 50, 35, 34, 34, 34, 34, 35, + 35, 51, 34, 39,119,119,119,119, 34,119, 51,115, 55,119,119,119, + 103,116, 51, 83, 37, 34, 51, 51, 50, 50, 53, 50, 83,119,119, 39, + 51, 35, 34, 51, 51, 51, 35, 50, 51, 35, 35, 50, 51,119, 51, 51, + 51, 51,115,119,119,119,115,119,119, 50, 51, 51, 34, 51, 51, 50, + 34,114,119,119,119, 3, 51, 51, 32, 35,114,119,119, 34, 50, 51, + 3, 48, 51, 51, 50, 51, 34, 2, 50, 35, 50, 51, 51,119,112,119, + 119,119,119,119, 48,119,115,119,112, 0, 0, 96, 54,115,115,119, + 119,119,119, 48,119,119,119,119, 7,119,119,119, 0, 51, 1,119, + 119, 51, 51, 35, 32, 32, 2, 16, 34, 34, 50, 51, 19, 51, 51, 35, + 51, 35, 0,114,119,119, 55, 51, 35, 35, 35, 34, 51, 35, 51, 50, + 34, 35,119,119,119, 39, 34, 50, 3, 49, 51, 51, 51, 51, 50,119, + 119,119, 50,115, 51, 51, 35, 51, 51, 51, 51, 3,119, 55, 51,114, + 119, 51, 51, 34, 51, 51,119,119,119, 3, 51, 34, 2, 35, 50, 35, + 51, 48, 34, 3, 0, 32, 19,119,119, 51, 51,119,119,119,103,119, + 119, +}; -#define joining_offset_0x0600u 0 - - /* Arabic */ - - /* 0600 */ U,U,U,U,U,U,X,X,U,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 0620 */ D,U,R,R,R,R,D,R,D,R,D,D,D,D,D,R,R,R,R,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 0640 */ C,D,D,D,D,D,D,D,R,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 0660 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,D,D,X,R,R,R,U,R,R,R,D,D,D,D,D,D,D,D, - /* 0680 */ D,D,D,D,D,D,D,D,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,D,D,D,D,D,D, - /* 06A0 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 06C0 */ R,D,D,R,R,R,R,R,R,R,R,R,D,R,D,R,D,D,R,R,X,R,X,X,X,X,X,X,X,U,X,X, - /* 06E0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,R,R,X,X,X,X,X,X,X,X,X,X,D,D,D,X,X,D, - - /* Syriac */ - - /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,T,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D, - /* 0720 */ D,D,D,D,D,D,D,D,R,D,DR,D,R,D,D,DR,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 0740 */ X,X,X,X,X,X,X,X,X,X,X,X,X,R,D,D, - - /* Arabic Supplement */ - - /* 0740 */ D,D,D,D,D,D,D,D,D,R,R,R,D,D,D,D, - /* 0760 */ D,D,D,D,D,D,D,D,D,D,D,R,R,D,D,D,D,R,D,R,R,D,D,D,R,R,D,D,D,D,D,D, - - /* FILLER */ - - /* 0780 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 07A0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - - /* NKo */ - - /* 07C0 */ X,X,X,X,X,X,X,X,X,X,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 07E0 */ D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,C,X,X,X,X,X, - - /* FILLER */ - - /* 0800 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 0820 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - - /* Mandaic */ - - /* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,R,R,R,X,X,X,X,X,X,X, - - /* Syriac Supplement */ - - /* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X, - - /* Arabic Extended-B */ - - /* 0860 */ R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R, - /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,X,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - - /* Arabic Extended-A */ - - /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,D,D,D,D,R,D,D,D,D,D,D, - /* 08C0 */ D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 08E0 */ X,X,U, - -#define joining_offset_0x1806u 739 - - /* Mongolian */ - - /* 1800 */ U,D,X,X,C,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 1820 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 1840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X, - /* 1880 */ U,U,U,U,U,T,T,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D, - -#define joining_offset_0x200cu 904 - - /* General Punctuation */ - - /* 2000 */ U,C,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 2020 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 2040 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 2060 */ X,X,X,X,X,X,U,U,U,U, - -#define joining_offset_0xa840u 998 - - /* Phags-pa */ - - /* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U, - -#define joining_offset_0x10ac0u 1050 - - /* Manichaean */ - - /* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D, - /* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R, - -#define joining_offset_0x10b80u 1098 - - /* Psalter Pahlavi */ - - /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U, - -#define joining_offset_0x10d00u 1146 - - /* Hanifi Rohingya */ - - /* 10D00 */ L,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 10D20 */ D,D,R,D, - -#define joining_offset_0x10ec2u 1182 - - /* Arabic Extended-C */ - - /* 10EC0 */ R,D,D, - -#define joining_offset_0x10f30u 1185 - - /* Sogdian */ - - /* 10F20 */ D,D,D,R,D,D,D,D,D,D,D,D,D,D,D,D, - /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R,X,X,X,X,X,X,X,X,X,X,X, - /* 10F60 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - - /* Old Uyghur */ - - /* 10F60 */ D,D,D,D,R,R,D,D,D,D,D,D,D,D,D,D, - /* 10F80 */ D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 10FA0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - - /* Chorasmian */ - - /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, - /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, - -#define joining_offset_0x110bdu 1341 - - /* Kaithi */ - - /* 110A0 */ U,X,X, - /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, - -#define joining_offset_0x1e900u 1358 - - /* Adlam */ - - /* 1E900 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, - -}; /* Table items: 1434; occupancy: 57% */ - +static inline uint8_t _hb_arabic_joining_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1)<<2))&15; +} +static inline uint8_t _hb_arabic_joining_joining_type (unsigned u) +{ + /* packtab: [2^4,2^3,2^3,2^3] */ + return u<125260u ? (uint8_t)(_hb_arabic_joining_b4(_hb_arabic_joining_u8+441u,((_hb_arabic_joining_u8[209u+_hb_arabic_joining_u8[123u+((_hb_arabic_joining_b4(_hb_arabic_joining_u8,((((((u)>>3))>>3))>>3)))<<3)+((((((u)>>3))>>3))&7)]+((((u)>>3))&7)])<<3)+((u)&7))) : 7; +} static unsigned int joining_type (hb_codepoint_t u) { - switch (u >> 12) - { - case 0x0u: - if (hb_in_range (u, 0x0600u, 0x08E2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; - break; - - case 0x1u: - if (hb_in_range (u, 0x1806u, 0x18AAu)) return joining_table[u - 0x1806u + joining_offset_0x1806u]; - break; - - case 0x2u: - if (hb_in_range (u, 0x200Cu, 0x2069u)) return joining_table[u - 0x200Cu + joining_offset_0x200cu]; - break; - - case 0xAu: - if (hb_in_range (u, 0xA840u, 0xA873u)) return joining_table[u - 0xA840u + joining_offset_0xa840u]; - break; - - case 0x10u: - if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; - if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; - if (hb_in_range (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; - if (hb_in_range (u, 0x10EC2u, 0x10EC4u)) return joining_table[u - 0x10EC2u + joining_offset_0x10ec2u]; - if (hb_in_range (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; - break; - - case 0x11u: - if (hb_in_range (u, 0x110BDu, 0x110CDu)) return joining_table[u - 0x110BDu + joining_offset_0x110bdu]; - break; - - case 0x1Eu: - if (hb_in_range (u, 0x1E900u, 0x1E94Bu)) return joining_table[u - 0x1E900u + joining_offset_0x1e900u]; - break; - - default: - break; - } - return X; + return _hb_arabic_joining_joining_type (u); } -#undef A -#undef DR -#undef C -#undef D -#undef L -#undef R -#undef T -#undef U -#undef X - static const uint16_t shaping_table[][4] = { diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic.cc index 4e3b512b4..2a05af146 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-arabic.cc @@ -77,8 +77,8 @@ enum hb_arabic_joining_type_t { JOINING_GROUP_DALATH_RISH = 5, NUM_STATE_MACHINE_COLS = 6, - JOINING_TYPE_T = 7, - JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ + JOINING_TYPE_T = 6, + JOINING_TYPE_X = 7 /* means: use general-category to choose between U or T. */ }; #include "hb-ot-shaper-arabic-table.hh" @@ -260,7 +260,7 @@ struct arabic_shape_plan_t * mask_array[NONE] == 0. */ hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; - hb_atomic_ptr_t fallback_plan; + mutable hb_atomic_t fallback_plan; unsigned int do_fallback : 1; unsigned int has_stch : 1; @@ -561,20 +561,29 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%" PRId32, n_fixed, w_fixed); DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%" PRId32, n_repeating, w_repeating); + static constexpr unsigned STCH_MAX_GLYPHS = 256; + /* Number of additional times to repeat each repeating tile. */ - int n_copies = 0; + unsigned int n_copies = 0; - hb_position_t w_remaining = w_total - w_fixed; - if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0) - n_copies = (sign * w_remaining) / (sign * w_repeating) - 1; + int64_t w_remaining_signed = (int64_t) w_total - w_fixed; + int64_t w_repeating_signed = w_repeating; + if (sign < 0) + { + w_remaining_signed = -w_remaining_signed; + w_repeating_signed = -w_repeating_signed; + } + hb_position_t w_remaining = (hb_position_t) (w_total - w_fixed); + if (w_remaining_signed > w_repeating_signed && w_repeating_signed > 0) + n_copies = w_remaining_signed / w_repeating_signed - 1; /* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */ hb_position_t extra_repeat_overlap = 0; - hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1); + int64_t shortfall = w_remaining_signed - w_repeating_signed * (n_copies + 1); if (shortfall > 0 && n_repeating > 0) { ++n_copies; - hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining; + int64_t excess = (n_copies + 1) * w_repeating_signed - w_remaining_signed; if (excess > 0) { extra_repeat_overlap = excess / (n_copies * n_repeating); @@ -582,10 +591,22 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, } } + unsigned int max_copies = 0; + if (n_repeating > 0) + { + unsigned int base_glyphs = n_fixed + n_repeating; + if (base_glyphs < STCH_MAX_GLYPHS) + max_copies = (STCH_MAX_GLYPHS - base_glyphs) / n_repeating; + } + n_copies = hb_min (n_copies, max_copies); + if (step == MEASURE) { - extra_glyphs_needed += n_copies * n_repeating; - DEBUG_MSG (ARABIC, nullptr, "will add extra %d copies of repeating tiles", n_copies); + unsigned int added_glyphs = 0; + if (unlikely (hb_unsigned_mul_overflows (n_copies, n_repeating, &added_glyphs) || + hb_unsigned_add_overflows (extra_glyphs_needed, added_glyphs, &extra_glyphs_needed))) + break; + DEBUG_MSG (ARABIC, nullptr, "will add extra %u copies of repeating tiles", n_copies); } else { @@ -629,7 +650,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (step == MEASURE) { - if (unlikely (!buffer->ensure (count + extra_glyphs_needed))) + unsigned int total_glyphs = 0; + if (unlikely (hb_unsigned_add_overflows (count, extra_glyphs_needed, &total_glyphs) || + !buffer->ensure (total_glyphs))) break; } else @@ -654,7 +677,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, /* https://www.unicode.org/reports/tr53/ */ -static hb_codepoint_t +static const hb_codepoint_t modifier_combining_marks[] = { 0x0654u, /* ARABIC HAMZA ABOVE */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-hangul.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-hangul.cc index c90476bc4..ce87a9156 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-hangul.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-hangul.cc @@ -298,8 +298,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, end = start + 2; if (unlikely (!buffer->successful)) break; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start, end); + buffer->merge_out_grapheme_clusters (start, end); continue; } } @@ -372,8 +371,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, if (i < end) info[i++].hangul_shaping_feature() = TJMO; - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start, end); + buffer->merge_out_grapheme_clusters (start, end); continue; } else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint))) @@ -429,7 +427,7 @@ const hb_ot_shaper_t _hb_ot_shaper_hangul = HB_TAG_NONE, /* gpos_tag */ HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, - false, /* fallback_position */ + true, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.hh index 353e32d32..6ff65c30a 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.hh @@ -68,6 +68,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_Ra 15u #define indic_syllable_machine_ex_Repha 14u #define indic_syllable_machine_ex_SM 8u +#define indic_syllable_machine_ex_SMPst 57u #define indic_syllable_machine_ex_Symbol 17u #define indic_syllable_machine_ex_V 2u #define indic_syllable_machine_ex_VD 9u @@ -76,251 +77,916 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 80 "hb-ot-shaper-indic-machine.hh" +#line 81 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, - 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, - 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, - 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 5u, 13u, 8u, 8u, 1u, 18u, - 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 3u, 16u, 3u, 16u, 4u, 16u, - 1u, 15u, 3u, 16u, 3u, 16u, 4u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, - 1u, 15u, 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 3u, 16u, 4u, 13u, 3u, 16u, 3u, 16u, - 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, - 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 3u, 16u, 4u, 13u, 4u, 13u, 3u, 16u, 3u, 16u, - 4u, 16u, 1u, 15u, 3u, 16u, 1u, 15u, 5u, 9u, 9u, 9u, 5u, 9u, 1u, 15u, - 1u, 15u, 3u, 13u, 4u, 13u, 5u, 13u, 5u, 13u, 3u, 16u, 4u, 13u, 5u, 9u, - 5u, 9u, 3u, 9u, 5u, 9u, 1u, 16u, 3u, 16u, 1u, 16u, 4u, 13u, 5u, 13u, - 5u, 13u, 9u, 9u, 5u, 9u, 1u, 15u, 3u, 9u, 5u, 9u, 5u, 9u, 9u, 9u, + 8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u, + 8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 8u, 57u, + 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 5u, 57u, 8u, 57u, 1u, 57u, + 3u, 57u, 3u, 57u, 4u, 57u, 1u, 57u, 5u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, + 1u, 57u, 1u, 57u, 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 4u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, + 1u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, + 1u, 57u, 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 4u, 57u, 3u, 57u, 3u, 57u, + 4u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, + 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 4u, 57u, 3u, 57u, 3u, 57u, + 4u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, + 1u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 3u, 57u, 5u, 57u, 1u, 57u, 3u, 57u, 1u, 57u, 4u, 57u, 5u, 57u, + 5u, 57u, 9u, 9u, 5u, 9u, 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 9u, 9u, 5u, 9u, 1u, 15u, 0 }; static const char _indic_syllable_machine_key_spans[] = { - 1, 10, 9, 9, 1, 10, 10, 10, - 1, 9, 9, 1, 10, 10, 10, 10, - 1, 9, 9, 1, 10, 10, 10, 1, - 9, 9, 1, 10, 10, 9, 1, 18, - 14, 14, 13, 15, 5, 5, 1, 5, - 15, 15, 15, 11, 10, 9, 9, 10, - 5, 7, 5, 14, 14, 14, 14, 13, - 15, 14, 14, 13, 15, 5, 1, 5, - 15, 15, 11, 10, 9, 9, 10, 5, - 5, 7, 5, 14, 14, 10, 14, 14, - 13, 15, 14, 15, 5, 1, 5, 15, - 15, 11, 10, 9, 9, 14, 10, 5, - 5, 7, 5, 14, 10, 10, 14, 14, - 13, 15, 14, 15, 5, 1, 5, 15, - 15, 11, 10, 9, 9, 14, 10, 5, - 5, 7, 5, 16, 14, 16, 10, 9, - 9, 1, 5, 15, 7, 5, 5, 1, + 50, 54, 53, 53, 1, 54, 54, 54, + 50, 53, 53, 1, 54, 54, 54, 54, + 50, 53, 53, 1, 54, 54, 54, 50, + 53, 53, 1, 54, 54, 53, 50, 57, + 55, 55, 54, 57, 53, 53, 1, 5, + 57, 57, 57, 55, 54, 53, 53, 54, + 53, 55, 53, 55, 55, 55, 55, 54, + 57, 55, 55, 54, 57, 53, 1, 5, + 57, 57, 55, 54, 53, 53, 54, 53, + 53, 55, 53, 55, 55, 54, 55, 55, + 54, 57, 55, 57, 53, 1, 5, 57, + 57, 55, 54, 53, 53, 55, 54, 53, + 53, 55, 53, 55, 54, 54, 55, 55, + 54, 57, 55, 57, 53, 1, 5, 57, + 57, 55, 54, 53, 53, 55, 54, 53, + 53, 55, 53, 57, 55, 57, 54, 53, + 53, 1, 5, 57, 55, 53, 53, 1, 5, 15 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 13, 23, 33, 35, 46, 57, - 68, 70, 80, 90, 92, 103, 114, 125, - 136, 138, 148, 158, 160, 171, 182, 193, - 195, 205, 215, 217, 228, 239, 249, 251, - 270, 285, 300, 314, 330, 336, 342, 344, - 350, 366, 382, 398, 410, 421, 431, 441, - 452, 458, 466, 472, 487, 502, 517, 532, - 546, 562, 577, 592, 606, 622, 628, 630, - 636, 652, 668, 680, 691, 701, 711, 722, - 728, 734, 742, 748, 763, 778, 789, 804, - 819, 833, 849, 864, 880, 886, 888, 894, - 910, 926, 938, 949, 959, 969, 984, 995, - 1001, 1007, 1015, 1021, 1036, 1047, 1058, 1073, - 1088, 1102, 1118, 1133, 1149, 1155, 1157, 1163, - 1179, 1195, 1207, 1218, 1228, 1238, 1253, 1264, - 1270, 1276, 1284, 1290, 1307, 1322, 1339, 1350, - 1360, 1370, 1372, 1378, 1394, 1402, 1408, 1414, - 1416, 1422 + 0, 51, 106, 160, 214, 216, 271, 326, + 381, 432, 486, 540, 542, 597, 652, 707, + 762, 813, 867, 921, 923, 978, 1033, 1088, + 1139, 1193, 1247, 1249, 1304, 1359, 1413, 1464, + 1522, 1578, 1634, 1689, 1747, 1801, 1855, 1857, + 1863, 1921, 1979, 2037, 2093, 2148, 2202, 2256, + 2311, 2365, 2421, 2475, 2531, 2587, 2643, 2699, + 2754, 2812, 2868, 2924, 2979, 3037, 3091, 3093, + 3099, 3157, 3215, 3271, 3326, 3380, 3434, 3489, + 3543, 3597, 3653, 3707, 3763, 3819, 3874, 3930, + 3986, 4041, 4099, 4155, 4213, 4267, 4269, 4275, + 4333, 4391, 4447, 4502, 4556, 4610, 4666, 4721, + 4775, 4829, 4885, 4939, 4995, 5050, 5105, 5161, + 5217, 5272, 5330, 5386, 5444, 5498, 5500, 5506, + 5564, 5622, 5678, 5733, 5787, 5841, 5897, 5952, + 6006, 6060, 6116, 6170, 6228, 6284, 6342, 6397, + 6451, 6505, 6507, 6513, 6571, 6627, 6681, 6735, + 6737, 6743 }; static const unsigned char _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 3, 4, 5, 0, - 0, 0, 0, 4, 0, 3, 3, 4, - 6, 0, 0, 0, 0, 4, 0, 3, - 3, 4, 5, 0, 0, 0, 0, 4, - 0, 4, 0, 7, 3, 3, 4, 5, - 0, 0, 0, 0, 4, 0, 2, 3, - 3, 4, 5, 0, 0, 0, 8, 4, - 0, 10, 11, 11, 12, 13, 9, 9, - 9, 9, 12, 9, 14, 9, 11, 11, - 12, 15, 9, 9, 9, 9, 12, 9, - 11, 11, 12, 13, 9, 9, 9, 9, - 12, 9, 12, 9, 16, 11, 11, 12, - 13, 9, 9, 9, 9, 12, 9, 10, - 11, 11, 12, 13, 9, 9, 9, 17, - 12, 9, 10, 11, 11, 12, 13, 9, - 9, 9, 18, 12, 9, 20, 21, 21, - 22, 23, 19, 19, 19, 24, 22, 19, - 25, 19, 21, 21, 22, 27, 26, 26, - 26, 26, 22, 26, 21, 21, 22, 23, - 19, 19, 19, 19, 22, 19, 22, 26, - 20, 21, 21, 22, 23, 19, 19, 19, - 19, 22, 19, 28, 21, 21, 22, 23, - 19, 19, 19, 19, 22, 19, 30, 31, - 31, 32, 33, 29, 29, 29, 34, 32, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 2, 3, 3, 4, 5, + 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 3, 3, 4, 6, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 0, + 3, 3, 4, 5, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 4, 0, + 7, 3, 3, 4, 5, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 2, + 3, 3, 4, 5, 0, 0, 0, 8, + 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 10, 11, + 11, 12, 13, 9, 9, 9, 9, 12, + 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, 13, 9, 14, 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, 14, 9, + 11, 11, 12, 15, 9, 9, 9, 9, + 12, 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, 15, 9, 11, 11, + 12, 13, 9, 9, 9, 9, 12, 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, 13, 9, 12, 9, 16, 11, + 11, 12, 13, 9, 9, 9, 9, 12, + 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, 13, 9, 10, 11, 11, + 12, 13, 9, 9, 9, 17, 12, 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, 13, 9, 10, 11, 11, 12, + 13, 9, 9, 9, 18, 12, 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, 13, 9, 20, 21, 21, 22, 23, + 19, 19, 19, 24, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 23, 19, 25, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 25, 19, 21, 21, 22, + 27, 26, 26, 26, 26, 22, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 27, 26, 21, 21, 22, 23, 19, + 19, 19, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 23, + 19, 22, 26, 20, 21, 21, 22, 23, + 19, 19, 19, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 23, 19, 28, 21, 21, 22, 23, 19, + 19, 19, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 23, + 19, 30, 31, 31, 32, 33, 29, 29, + 29, 34, 32, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 33, 29, + 35, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 35, 29, 31, 31, 32, 36, 29, - 29, 29, 29, 32, 29, 31, 31, 32, - 33, 29, 29, 29, 29, 32, 29, 32, + 29, 29, 29, 32, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 36, + 29, 31, 31, 32, 33, 29, 29, 29, + 29, 32, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 33, 29, 32, 29, 30, 31, 31, 32, 33, 29, 29, - 29, 29, 32, 29, 37, 31, 31, 32, - 33, 29, 29, 29, 29, 32, 29, 21, + 29, 29, 32, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 33, 29, + 37, 31, 31, 32, 33, 29, 29, 29, + 29, 32, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 33, 29, 21, 21, 22, 38, 0, 0, 0, 0, 22, - 0, 40, 39, 42, 43, 44, 45, 46, - 47, 22, 23, 48, 49, 49, 24, 22, - 50, 51, 52, 53, 54, 41, 56, 57, - 58, 59, 4, 5, 60, 55, 55, 8, - 4, 55, 55, 61, 55, 62, 57, 63, - 63, 4, 5, 60, 55, 55, 55, 4, - 55, 55, 61, 55, 57, 63, 63, 4, - 5, 60, 55, 55, 55, 4, 55, 55, - 61, 55, 42, 55, 55, 55, 64, 65, - 55, 1, 60, 55, 55, 55, 55, 55, - 42, 55, 66, 66, 55, 1, 60, 55, - 60, 55, 55, 67, 60, 55, 60, 55, - 60, 55, 55, 55, 60, 55, 42, 55, - 68, 55, 66, 66, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 42, 55, - 55, 55, 66, 66, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 42, 55, - 55, 55, 66, 65, 55, 1, 60, 55, - 55, 55, 55, 55, 42, 55, 69, 70, - 71, 71, 4, 5, 60, 55, 55, 55, - 4, 55, 70, 71, 71, 4, 5, 60, - 55, 55, 55, 4, 55, 71, 71, 4, - 5, 60, 55, 55, 55, 4, 55, 60, - 55, 55, 67, 60, 55, 55, 55, 4, - 55, 72, 73, 73, 4, 5, 60, 55, - 55, 55, 4, 55, 64, 74, 55, 1, - 60, 55, 64, 55, 66, 66, 55, 1, - 60, 55, 66, 74, 55, 1, 60, 55, - 56, 57, 63, 63, 4, 5, 60, 55, - 55, 55, 4, 55, 55, 61, 55, 56, - 57, 58, 63, 4, 5, 60, 55, 55, - 8, 4, 55, 55, 61, 55, 76, 77, - 78, 79, 12, 13, 80, 75, 75, 18, - 12, 75, 75, 81, 75, 82, 77, 83, - 79, 12, 13, 80, 75, 75, 75, 12, - 75, 75, 81, 75, 77, 83, 79, 12, - 13, 80, 75, 75, 75, 12, 75, 75, - 81, 75, 84, 75, 75, 75, 85, 86, - 75, 14, 80, 75, 75, 75, 75, 75, - 84, 75, 87, 77, 88, 89, 12, 13, - 80, 75, 75, 17, 12, 75, 75, 81, - 75, 90, 77, 83, 83, 12, 13, 80, - 75, 75, 75, 12, 75, 75, 81, 75, - 77, 83, 83, 12, 13, 80, 75, 75, - 75, 12, 75, 75, 81, 75, 84, 75, - 75, 75, 91, 86, 75, 14, 80, 75, - 75, 75, 75, 75, 84, 75, 80, 75, - 75, 92, 80, 75, 80, 75, 80, 75, - 75, 75, 80, 75, 84, 75, 93, 75, - 91, 91, 75, 14, 80, 75, 75, 75, - 75, 75, 84, 75, 84, 75, 75, 75, - 91, 91, 75, 14, 80, 75, 75, 75, - 75, 75, 84, 75, 94, 95, 96, 96, - 12, 13, 80, 75, 75, 75, 12, 75, - 95, 96, 96, 12, 13, 80, 75, 75, - 75, 12, 75, 96, 96, 12, 13, 80, - 75, 75, 75, 12, 75, 80, 75, 75, - 92, 80, 75, 75, 75, 12, 75, 97, - 98, 98, 12, 13, 80, 75, 75, 75, - 12, 75, 85, 99, 75, 14, 80, 75, - 91, 91, 75, 14, 80, 75, 85, 75, - 91, 91, 75, 14, 80, 75, 91, 99, - 75, 14, 80, 75, 87, 77, 83, 83, - 12, 13, 80, 75, 75, 75, 12, 75, - 75, 81, 75, 87, 77, 88, 83, 12, - 13, 80, 75, 75, 17, 12, 75, 75, - 81, 75, 10, 11, 11, 12, 13, 75, - 75, 75, 75, 12, 75, 76, 77, 83, - 79, 12, 13, 80, 75, 75, 75, 12, - 75, 75, 81, 75, 101, 45, 102, 102, - 22, 23, 48, 100, 100, 100, 22, 100, - 100, 52, 100, 45, 102, 102, 22, 23, - 48, 100, 100, 100, 22, 100, 100, 52, - 100, 103, 100, 100, 100, 104, 105, 100, - 25, 48, 100, 100, 100, 100, 100, 103, - 100, 44, 45, 106, 107, 22, 23, 48, - 100, 100, 24, 22, 100, 100, 52, 100, - 103, 100, 100, 100, 108, 105, 100, 25, - 48, 100, 100, 100, 100, 100, 103, 100, - 48, 100, 100, 109, 48, 100, 48, 100, - 48, 100, 100, 100, 48, 100, 103, 100, - 110, 100, 108, 108, 100, 25, 48, 100, - 100, 100, 100, 100, 103, 100, 103, 100, - 100, 100, 108, 108, 100, 25, 48, 100, - 100, 100, 100, 100, 103, 100, 111, 112, - 113, 113, 22, 23, 48, 100, 100, 100, - 22, 100, 112, 113, 113, 22, 23, 48, - 100, 100, 100, 22, 100, 113, 113, 22, - 23, 48, 100, 100, 100, 22, 100, 48, - 100, 100, 109, 48, 100, 100, 100, 22, - 100, 44, 45, 102, 102, 22, 23, 48, - 100, 100, 100, 22, 100, 100, 52, 100, - 114, 115, 115, 22, 23, 48, 100, 100, - 100, 22, 100, 104, 116, 100, 25, 48, - 100, 108, 108, 100, 25, 48, 100, 104, - 100, 108, 108, 100, 25, 48, 100, 108, - 116, 100, 25, 48, 100, 44, 45, 106, - 102, 22, 23, 48, 100, 100, 24, 22, - 100, 100, 52, 100, 20, 21, 21, 22, - 23, 117, 117, 117, 24, 22, 117, 20, - 21, 21, 22, 23, 117, 117, 117, 117, - 22, 117, 119, 120, 121, 122, 32, 33, - 123, 118, 118, 34, 32, 118, 118, 124, - 118, 125, 120, 122, 122, 32, 33, 123, - 118, 118, 118, 32, 118, 118, 124, 118, - 120, 122, 122, 32, 33, 123, 118, 118, - 118, 32, 118, 118, 124, 118, 126, 118, - 118, 118, 127, 128, 118, 35, 123, 118, - 118, 118, 118, 118, 126, 118, 119, 120, - 121, 49, 32, 33, 123, 118, 118, 34, - 32, 118, 118, 124, 118, 126, 118, 118, - 118, 129, 128, 118, 35, 123, 118, 118, - 118, 118, 118, 126, 118, 123, 118, 118, - 130, 123, 118, 123, 118, 123, 118, 118, - 118, 123, 118, 126, 118, 131, 118, 129, - 129, 118, 35, 123, 118, 118, 118, 118, - 118, 126, 118, 126, 118, 118, 118, 129, - 129, 118, 35, 123, 118, 118, 118, 118, - 118, 126, 118, 132, 133, 134, 134, 32, - 33, 123, 118, 118, 118, 32, 118, 133, - 134, 134, 32, 33, 123, 118, 118, 118, - 32, 118, 134, 134, 32, 33, 123, 118, - 118, 118, 32, 118, 123, 118, 118, 130, - 123, 118, 118, 118, 32, 118, 119, 120, - 122, 122, 32, 33, 123, 118, 118, 118, - 32, 118, 118, 124, 118, 135, 136, 136, - 32, 33, 123, 118, 118, 118, 32, 118, - 127, 137, 118, 35, 123, 118, 129, 129, - 118, 35, 123, 118, 127, 118, 129, 129, - 118, 35, 123, 118, 129, 137, 118, 35, - 123, 118, 42, 43, 44, 45, 106, 102, - 22, 23, 48, 49, 49, 24, 22, 100, - 42, 52, 100, 56, 138, 58, 59, 4, - 5, 60, 55, 55, 8, 4, 55, 55, - 61, 55, 42, 43, 44, 45, 139, 140, - 22, 141, 142, 55, 49, 24, 22, 55, - 42, 52, 55, 20, 143, 143, 22, 141, - 60, 55, 55, 24, 22, 55, 60, 55, - 55, 67, 60, 55, 55, 55, 22, 55, - 142, 55, 55, 144, 142, 55, 55, 55, - 22, 55, 142, 55, 142, 55, 55, 55, - 142, 55, 42, 55, 68, 20, 143, 143, - 22, 141, 60, 55, 55, 55, 22, 55, - 42, 55, 146, 145, 147, 147, 145, 40, - 148, 145, 147, 147, 145, 40, 148, 145, - 148, 145, 145, 149, 148, 145, 148, 145, - 148, 145, 145, 145, 148, 145, 42, 117, - 117, 117, 117, 117, 117, 117, 117, 49, - 117, 117, 117, 117, 42, 117, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 38, 0, 40, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 40, 39, + 42, 43, 44, 45, 46, 47, 22, 23, + 48, 49, 49, 24, 22, 50, 51, 52, + 53, 54, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 55, 41, 57, 58, 59, 60, 4, 5, + 61, 56, 56, 8, 4, 56, 56, 62, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 63, 58, 64, 64, 4, 5, + 61, 56, 56, 56, 4, 56, 56, 62, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 58, 64, 64, 4, 5, 61, + 56, 56, 56, 4, 56, 56, 62, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 5, + 56, 42, 56, 56, 56, 65, 66, 56, + 1, 61, 56, 56, 56, 56, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 67, 67, 56, 1, 61, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 1, + 56, 61, 56, 56, 68, 61, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 68, 56, 61, + 56, 61, 56, 56, 56, 61, 56, 42, + 56, 69, 56, 67, 67, 56, 1, 61, + 56, 56, 56, 56, 56, 42, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 1, + 56, 42, 56, 56, 56, 67, 67, 56, + 1, 61, 56, 56, 56, 56, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 42, 56, 56, 56, 67, + 66, 56, 1, 61, 56, 56, 56, 56, + 56, 42, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 70, 71, 72, + 72, 4, 5, 61, 56, 56, 56, 4, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 5, 56, 71, 72, 72, + 4, 5, 61, 56, 56, 56, 4, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 5, 56, 72, 72, 4, 5, + 61, 56, 56, 56, 4, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 5, 56, 61, 56, 56, 68, 61, 56, + 56, 56, 4, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 68, 56, + 73, 74, 74, 4, 5, 61, 56, 56, + 56, 4, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 5, 56, 65, + 75, 56, 1, 61, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 65, 56, 67, + 67, 56, 1, 61, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 1, 56, 67, 75, 56, + 1, 61, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 1, 56, 57, 58, 64, 64, 4, + 5, 61, 56, 56, 56, 4, 56, 56, + 62, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 5, 56, 57, 58, 59, 64, 4, + 5, 61, 56, 56, 8, 4, 56, 56, + 62, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 5, 56, 77, 78, 79, 80, 12, + 13, 81, 76, 76, 18, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 83, 78, 84, 80, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 78, 84, 80, 12, 13, + 81, 76, 76, 76, 12, 76, 76, 82, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 85, 76, 76, 76, 86, 87, + 76, 14, 81, 76, 76, 76, 76, 76, + 85, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 14, 76, 88, 78, 89, 90, + 12, 13, 81, 76, 76, 17, 12, 76, + 76, 82, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 91, 78, 84, 84, + 12, 13, 81, 76, 76, 76, 12, 76, + 76, 82, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 78, 84, 84, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 85, 76, 76, 76, 92, + 87, 76, 14, 81, 76, 76, 76, 76, + 76, 85, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 81, 76, 76, + 93, 81, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 93, 76, 81, 76, 81, 76, 76, + 76, 81, 76, 85, 76, 94, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 85, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 85, 76, 76, + 76, 92, 92, 76, 14, 81, 76, 76, + 76, 76, 76, 85, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 14, 76, 95, + 96, 97, 97, 12, 13, 81, 76, 76, + 76, 12, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 13, 76, 96, + 97, 97, 12, 13, 81, 76, 76, 76, + 12, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 13, 76, 97, 97, + 12, 13, 81, 76, 76, 76, 12, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 13, 76, 81, 76, 76, 93, + 81, 76, 76, 76, 12, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 93, 76, 98, 99, 99, 12, 13, 81, + 76, 76, 76, 12, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 13, + 76, 86, 100, 76, 14, 81, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 14, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 86, 76, 92, + 92, 76, 14, 81, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 14, 76, 92, 100, 76, + 14, 81, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 14, 76, 88, 78, 84, 84, 12, + 13, 81, 76, 76, 76, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 88, 78, 89, 84, 12, + 13, 81, 76, 76, 17, 12, 76, 76, + 82, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 13, 76, 10, 11, 11, 12, 13, + 76, 76, 76, 76, 12, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 77, 78, 84, 80, 12, 13, + 81, 76, 76, 76, 12, 76, 76, 82, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 13, 76, 102, 45, 103, 103, 22, 23, + 48, 101, 101, 101, 22, 101, 101, 52, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 23, 101, 45, 103, 103, 22, 23, 48, + 101, 101, 101, 22, 101, 101, 52, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 23, + 101, 104, 101, 101, 101, 105, 106, 101, + 25, 48, 101, 101, 101, 101, 101, 104, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 25, 101, 44, 45, 107, 108, 22, + 23, 48, 101, 101, 24, 22, 101, 101, + 52, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 23, 101, 104, 101, 101, 101, 109, + 106, 101, 25, 48, 101, 101, 101, 101, + 101, 104, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 48, 101, 101, + 110, 48, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 110, 101, 48, 101, 48, 101, 101, + 101, 48, 101, 104, 101, 111, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 104, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 104, 101, 101, + 101, 109, 109, 101, 25, 48, 101, 101, + 101, 101, 101, 104, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 25, 101, 112, + 113, 114, 114, 22, 23, 48, 101, 101, + 101, 22, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 23, 101, 113, + 114, 114, 22, 23, 48, 101, 101, 101, + 22, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 23, 101, 114, 114, + 22, 23, 48, 101, 101, 101, 22, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 23, 101, 48, 26, 26, 110, + 48, 26, 26, 26, 22, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 110, 26, 44, 45, 103, 103, 22, 23, + 48, 101, 101, 101, 22, 101, 101, 52, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 23, 101, 115, 116, 116, 22, 23, 48, + 101, 101, 101, 22, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 23, + 101, 105, 117, 101, 25, 48, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 25, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 105, 101, 109, + 109, 101, 25, 48, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 25, 101, 109, 117, 101, + 25, 48, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 25, 101, 44, 45, 107, 103, 22, + 23, 48, 101, 101, 24, 22, 101, 101, + 52, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 23, 101, 20, 21, 21, 22, 23, + 118, 118, 118, 24, 22, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 23, 118, 20, 21, 21, 22, 23, 118, + 118, 118, 118, 22, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 23, + 118, 120, 121, 122, 123, 32, 33, 124, + 119, 119, 34, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 126, 121, 123, 123, 32, 33, 124, + 119, 119, 119, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 121, 123, 123, 32, 33, 124, 119, + 119, 119, 32, 119, 119, 125, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 33, 119, + 127, 119, 119, 119, 128, 129, 119, 35, + 124, 119, 119, 119, 119, 119, 127, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 35, 119, 120, 121, 122, 49, 32, 33, + 124, 119, 119, 34, 32, 119, 119, 125, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 33, 119, 127, 119, 119, 119, 130, 129, + 119, 35, 124, 119, 119, 119, 119, 119, + 127, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 124, 119, 119, 131, + 124, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 131, 119, 124, 119, 124, 119, 119, 119, + 124, 119, 127, 119, 132, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 127, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 127, 119, 119, 119, + 130, 130, 119, 35, 124, 119, 119, 119, + 119, 119, 127, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 35, 119, 133, 134, + 135, 135, 32, 33, 124, 119, 119, 119, + 32, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 33, 119, 134, 135, + 135, 32, 33, 124, 119, 119, 119, 32, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 33, 119, 135, 135, 32, + 33, 124, 119, 119, 119, 32, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 33, 119, 124, 119, 119, 131, 124, + 119, 119, 119, 32, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 131, + 119, 120, 121, 123, 123, 32, 33, 124, + 119, 119, 119, 32, 119, 119, 125, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 33, + 119, 136, 137, 137, 32, 33, 124, 119, + 119, 119, 32, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 33, 119, + 128, 138, 119, 35, 124, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 35, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 128, 119, 130, 130, + 119, 35, 124, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 35, 119, 130, 138, 119, 35, + 124, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, + 35, 119, 42, 43, 44, 45, 107, 103, + 22, 23, 48, 49, 49, 24, 22, 101, + 42, 52, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 23, 101, 57, 139, 59, 60, + 4, 5, 61, 56, 56, 8, 4, 56, + 56, 62, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 5, 56, 42, 43, 44, 45, + 140, 141, 22, 142, 143, 56, 49, 24, + 22, 56, 42, 52, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 142, 56, 20, 144, + 144, 22, 142, 61, 56, 56, 24, 22, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 142, 56, 61, 56, 56, + 68, 61, 56, 56, 56, 22, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 68, 56, 143, 56, 56, 145, 143, + 56, 56, 56, 22, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 145, + 56, 143, 56, 143, 56, 56, 56, 143, + 56, 42, 56, 69, 20, 144, 144, 22, + 142, 61, 56, 56, 56, 22, 56, 42, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 142, 56, 147, 146, 148, 148, 146, + 40, 149, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 40, 146, 148, 148, 146, 40, 149, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 40, + 146, 149, 146, 146, 150, 149, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 150, 146, 149, + 146, 149, 146, 146, 146, 149, 146, 42, + 118, 118, 118, 118, 118, 118, 118, 118, + 49, 118, 118, 118, 118, 42, 118, 0 }; static const unsigned char _indic_syllable_machine_trans_targs[] = { @@ -330,41 +996,41 @@ static const unsigned char _indic_syllable_machine_trans_targs[] = { 93, 84, 31, 19, 98, 31, 107, 24, 113, 116, 117, 108, 26, 122, 127, 31, 134, 31, 32, 53, 79, 81, 100, 101, - 85, 102, 123, 124, 94, 132, 137, 31, - 33, 35, 6, 52, 38, 47, 34, 1, - 36, 40, 0, 39, 41, 44, 45, 3, - 48, 5, 49, 31, 54, 56, 14, 77, - 62, 70, 55, 7, 57, 72, 64, 58, - 13, 76, 59, 8, 63, 65, 67, 68, - 10, 71, 12, 73, 31, 80, 20, 82, - 96, 87, 15, 99, 16, 86, 88, 90, - 91, 18, 95, 21, 97, 31, 31, 103, - 105, 22, 27, 109, 118, 104, 106, 120, - 111, 23, 110, 112, 114, 115, 25, 119, - 28, 121, 125, 126, 131, 128, 129, 29, - 130, 31, 133, 30, 135, 136 + 85, 102, 123, 124, 94, 132, 137, 92, + 31, 33, 35, 6, 52, 38, 47, 34, + 1, 36, 40, 0, 39, 41, 44, 45, + 3, 48, 5, 49, 31, 54, 56, 14, + 77, 62, 70, 55, 7, 57, 72, 64, + 58, 13, 76, 59, 8, 63, 65, 67, + 68, 10, 71, 12, 73, 31, 80, 20, + 82, 96, 87, 15, 99, 16, 86, 88, + 90, 91, 18, 95, 21, 97, 31, 31, + 103, 105, 22, 27, 109, 118, 104, 106, + 120, 111, 23, 110, 112, 114, 115, 25, + 119, 28, 121, 125, 126, 131, 128, 129, + 29, 130, 31, 133, 30, 135, 136 }; static const char _indic_syllable_machine_trans_actions[] = { 1, 0, 2, 0, 2, 0, 0, 2, 2, 3, 2, 0, 2, 0, 0, 0, - 2, 2, 2, 4, 2, 0, 5, 0, + 2, 2, 2, 4, 2, 0, 5, 5, 5, 0, 6, 0, 2, 7, 2, 0, 2, 0, 2, 0, 0, 2, 0, 8, 0, 11, 2, 2, 5, 0, 12, 12, 0, 2, 5, 2, 5, 2, 0, 13, - 2, 0, 0, 2, 0, 2, 2, 0, - 2, 2, 0, 0, 2, 2, 2, 0, - 0, 0, 2, 14, 2, 0, 0, 2, - 0, 2, 2, 0, 2, 2, 2, 2, + 14, 2, 0, 0, 2, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 2, - 0, 0, 0, 2, 15, 5, 0, 5, - 2, 2, 0, 5, 0, 0, 2, 5, - 5, 0, 0, 0, 2, 16, 17, 2, - 0, 0, 0, 0, 2, 2, 2, 2, - 2, 0, 0, 2, 2, 2, 0, 0, - 0, 2, 0, 18, 18, 0, 0, 0, - 0, 19, 2, 0, 0, 0 + 0, 0, 0, 2, 15, 2, 0, 0, + 2, 0, 2, 2, 0, 2, 2, 2, + 2, 0, 2, 2, 0, 0, 2, 2, + 2, 0, 0, 0, 2, 16, 5, 0, + 5, 2, 2, 0, 5, 0, 0, 2, + 5, 5, 0, 0, 0, 2, 17, 18, + 2, 0, 0, 0, 0, 2, 2, 2, + 2, 2, 0, 0, 2, 2, 2, 0, + 0, 0, 2, 0, 19, 19, 0, 0, + 0, 0, 20, 2, 0, 0, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { @@ -414,20 +1080,20 @@ static const short _indic_syllable_machine_eof_trans[] = { 10, 10, 10, 10, 10, 10, 10, 20, 20, 27, 20, 27, 20, 20, 30, 30, 30, 30, 30, 30, 30, 1, 40, 0, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 101, - 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 118, 118, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 101, 56, 56, 56, 56, - 56, 56, 56, 56, 146, 146, 146, 146, - 146, 118 + 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 27, 102, 102, 102, + 102, 102, 102, 102, 119, 119, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 102, 57, 57, 57, 57, + 57, 57, 57, 57, 147, 147, 147, 147, + 147, 119 }; static const int indic_syllable_machine_start = 31; @@ -441,7 +1107,7 @@ static const int indic_syllable_machine_en_main = 31; -#line 118 "hb-ot-shaper-indic-machine.rl" +#line 121 "hb-ot-shaper-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -460,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 464 "hb-ot-shaper-indic-machine.hh" +#line 1130 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -468,7 +1134,7 @@ find_syllables_indic (hb_buffer_t *buffer) act = 0; } -#line 138 "hb-ot-shaper-indic-machine.rl" +#line 141 "hb-ot-shaper-indic-machine.rl" p = 0; @@ -476,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 480 "hb-ot-shaper-indic-machine.hh" +#line 1146 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -490,7 +1156,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 494 "hb-ot-shaper-indic-machine.hh" +#line 1160 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -513,51 +1179,51 @@ _eof_trans: {te = p+1;} break; case 11: -#line 114 "hb-ot-shaper-indic-machine.rl" +#line 117 "hb-ot-shaper-indic-machine.rl" {te = p+1;{ found_syllable (indic_non_indic_cluster); }} break; - case 13: -#line 109 "hb-ot-shaper-indic-machine.rl" + case 14: +#line 111 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_consonant_syllable); }} break; - case 14: -#line 110 "hb-ot-shaper-indic-machine.rl" + case 15: +#line 112 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_vowel_syllable); }} break; - case 17: -#line 111 "hb-ot-shaper-indic-machine.rl" + case 18: +#line 113 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_standalone_cluster); }} break; - case 19: -#line 112 "hb-ot-shaper-indic-machine.rl" + case 20: +#line 114 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_symbol_cluster); }} break; - case 15: -#line 113 "hb-ot-shaper-indic-machine.rl" + case 16: +#line 116 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; - case 16: -#line 114 "hb-ot-shaper-indic-machine.rl" + case 17: +#line 117 "hb-ot-shaper-indic-machine.rl" {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} break; case 1: -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} break; case 3: -#line 110 "hb-ot-shaper-indic-machine.rl" +#line 112 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} break; case 7: -#line 111 "hb-ot-shaper-indic-machine.rl" +#line 113 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} break; case 8: -#line 112 "hb-ot-shaper-indic-machine.rl" +#line 114 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} break; case 4: -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 116 "hb-ot-shaper-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 6: @@ -567,33 +1233,42 @@ _eof_trans: {{p = ((te))-1;} found_syllable (indic_consonant_syllable); } break; case 5: - {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; case 6: + {{p = ((te))-1;} found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + case 7: {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; } } break; - case 18: + case 19: #line 1 "NONE" {te = p+1;} -#line 109 "hb-ot-shaper-indic-machine.rl" +#line 111 "hb-ot-shaper-indic-machine.rl" {act = 1;} break; - case 5: + case 13: #line 1 "NONE" {te = p+1;} -#line 113 "hb-ot-shaper-indic-machine.rl" +#line 115 "hb-ot-shaper-indic-machine.rl" {act = 5;} break; - case 12: + case 5: #line 1 "NONE" {te = p+1;} -#line 114 "hb-ot-shaper-indic-machine.rl" +#line 116 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 597 "hb-ot-shaper-indic-machine.hh" + case 12: +#line 1 "NONE" + {te = p+1;} +#line 117 "hb-ot-shaper-indic-machine.rl" + {act = 7;} + break; +#line 1272 "hb-ot-shaper-indic-machine.hh" } _again: @@ -602,7 +1277,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 606 "hb-ot-shaper-indic-machine.hh" +#line 1281 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) @@ -618,7 +1293,7 @@ _again: } -#line 146 "hb-ot-shaper-indic-machine.rl" +#line 149 "hb-ot-shaper-indic-machine.rl" } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.rl b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.rl index f568a8462..138b35f04 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.rl +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-machine.rl @@ -80,17 +80,19 @@ export Ra = 15; export CM = 16; export Symbol= 17; export CS = 18; +export SMPst = 57; c = (C | Ra); # is_consonant n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier z = ZWJ|ZWNJ; # is_joiner reph = (Ra H | Repha); # possible reph +sm = SM | SMPst; cn = c.ZWJ?.n?; symbol = Symbol.N?; -matra_group = z*.(M | SM? MPst).N?.H?; -syllable_tail = (z?.SM.SM?.ZWNJ?)? (A | VD)*; +matra_group = z*.(M | sm? MPst).N?.H?; +syllable_tail = (z?.sm.sm?.ZWNJ?)? (A | VD)*; halant_group = (z?.H.(ZWJ.N?)?); final_halant_group = halant_group | H.ZWNJ; medial_group = CM?; @@ -110,6 +112,7 @@ main := |* vowel_syllable => { found_syllable (indic_vowel_syllable); }; standalone_cluster => { found_syllable (indic_standalone_cluster); }; symbol_cluster => { found_syllable (indic_symbol_cluster); }; + SMPst => { found_syllable (indic_non_indic_cluster); }; broken_cluster => { found_syllable (indic_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (indic_non_indic_cluster); }; *|; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-table.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-table.cc index adea32efd..e84b73eaf 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-table.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # IndicPositionalCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 + * # IndicSyllabicCategory-17.0.0.txt + * # Date: 2025-08-01, 04:02:23 GMT + * # IndicPositionalCategory-17.0.0.txt + * # Date: 2025-07-29, 13:35:52 GMT + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 */ #include "hb.hh" @@ -48,6 +48,7 @@ #define OT_CM I_Cat(CM) #define OT_Symbol I_Cat(Symbol) #define OT_CS I_Cat(CS) +#define OT_SMPst I_Cat(SMPst) /* khmer */ #define OT_VAbv K_Cat(VAbv) #define OT_VBlw K_Cat(VBlw) @@ -94,7 +95,8 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _OT_R OT_Ra /* 14 chars; Ra */ #define _OT_Rf OT_Repha /* 1 chars; Repha */ #define _OT_Rt OT_Robatic /* 3 chars; Robatic */ -#define _OT_SM OT_SM /* 56 chars; SM */ +#define _OT_SM OT_SM /* 50 chars; SM */ +#define _OT_SP OT_SMPst /* 6 chars; SMPst */ #define _OT_S OT_Symbol /* 22 chars; Symbol */ #define _OT_V OT_V /* 172 chars; V */ #define _OT_VA OT_VAbv /* 18 chars; VAbv */ @@ -128,392 +130,112 @@ static_assert (OT_VPst == M_Cat(VPst), ""); #define _(S,M) INDIC_COMBINE_CATEGORIES (_OT_##S, _POS_##M) -static const uint16_t indic_table[] = { +#include - -#define indic_offset_0x0028u 0 - - - /* Basic Latin */ - - /* 0028 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X), - /* 0030 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0038 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x00b0u 24 - - - /* Latin-1 Supplement */ - - /* 00B0 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), - /* 00B8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 00C0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 00C8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 00D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), - -#define indic_offset_0x0900u 64 - - - /* Devanagari */ - - /* 0900 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C), _(V,C), - /* 0908 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), - /* 0910 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0918 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0920 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0928 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0930 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0938 */ _(C,C), _(C,C), _(M,AS), _(M,AS), _(N,X), _(S,SM), _(M,AS), _(M,LM), - /* 0940 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), - /* 0948 */ _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(H,B), _(M,LM), _(M,AS), - /* 0950 */ _(X,X), _(A,SM), _(A,SM),_(SM,SM),_(SM,SM), _(M,AS), _(M,AS), _(M,AS), - /* 0958 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0960 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0968 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0970 */ _(X,X), _(X,X), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), - /* 0978 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - - /* Bengali */ - - /* 0980 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), - /* 0988 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C), - /* 0990 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0998 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 09A0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 09A8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 09B0 */ _(R,C), _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), - /* 09B8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM), - /* 09C0 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM), - /* 09C8 */ _(M,LM), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(C,C), _(X,X), - /* 09D0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), - /* 09D8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), - /* 09E0 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 09E8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 09F0 */ _(R,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 09F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(X,X),_(SM,SM), _(X,X), - - /* Gurmukhi */ - - /* 0A00 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), - /* 0A08 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), - /* 0A10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0A18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0A20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0A28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0A30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(X,X), - /* 0A38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(X,X), _(M,AP), _(M,LM), - /* 0A40 */_(MP,AP), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), - /* 0A48 */ _(M,AP), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), - /* 0A50 */ _(X,X), _(M,B), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0A58 */ _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), - /* 0A60 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0A68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0A70 */_(SM,SM),_(SM,SM), _(C,C), _(C,C), _(X,X), _(CM,C), _(X,X), _(X,X), - /* 0A78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - - /* Gujarati */ - - /* 0A80 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), - /* 0A88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), - /* 0A90 */ _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0A98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0AA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0AA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0AB0 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), - /* 0AB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,LM), - /* 0AC0 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AS), _(X,X), _(M,AS), - /* 0AC8 */ _(M,AS), _(M,AP), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), - /* 0AD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0AD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0AE0 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0AE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0AF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0AF8 */ _(X,X), _(C,C), _(A,SM), _(N,X), _(A,SM), _(N,X), _(N,X), _(N,X), - - /* Oriya */ - - /* 0B00 */ _(X,X),_(SM,BS),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), - /* 0B08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(V,C), - /* 0B10 */ _(V,C), _(X,X), _(X,X), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0B18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0B20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0B28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0B30 */ _(R,C), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), - /* 0B38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,AP), _(M,A), - /* 0B40 */ _(M,AP), _(M,AS), _(M,AS), _(M,AS), _(M,AS), _(X,X), _(X,X), _(M,LM), - /* 0B48 */ _(M,A), _(X,X), _(X,X), _(M,AP), _(M,AP), _(H,B), _(X,X), _(X,X), - /* 0B50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(N,X), _(M,A), _(M,AP), - /* 0B58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), - /* 0B60 */ _(V,C), _(V,C), _(M,AS), _(M,AS), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0B68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0B70 */ _(X,X), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0B78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - - /* Tamil */ - - /* 0B80 */ _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(V,C), _(V,C), _(V,C), - /* 0B88 */ _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(X,X), _(V,C), _(V,C), - /* 0B90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(X,X), _(X,X), - /* 0B98 */ _(X,X), _(C,C), _(C,C), _(X,X), _(C,C), _(X,X), _(C,C), _(C,C), - /* 0BA0 */ _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), - /* 0BA8 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), - /* 0BB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0BB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), _(M,AP), - /* 0BC0 */ _(M,AS), _(M,AP), _(M,AP), _(X,X), _(X,X), _(X,X), _(M,LM), _(M,LM), - /* 0BC8 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(X,X), _(X,X), - /* 0BD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AP), - /* 0BD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0BE0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0BE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0BF0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0BF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - - /* Telugu */ - - /* 0C00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(V,C), _(V,C), _(V,C), - /* 0C08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), - /* 0C10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0C18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0C20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0C28 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0C30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0C38 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS), - /* 0C40 */ _(M,BS), _(M,BS), _(M,BS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,BS), - /* 0C48 */ _(M,BS), _(X,X), _(M,BS), _(M,BS), _(M,BS), _(H,T), _(X,X), _(X,X), - /* 0C50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,BS), _(M,BS), _(X,X), - /* 0C58 */ _(C,C), _(C,C), _(C,C), _(X,X), _(X,X), _(C,C), _(X,X), _(X,X), - /* 0C60 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0C68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0C70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0C78 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - - /* Kannada */ - - /* 0C80 */ _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(V,C), _(V,C), _(V,C), - /* 0C88 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), - /* 0C90 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0C98 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0CA0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0CA8 */ _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0CB0 */ _(R,C), _(C,C), _(C,C), _(C,C), _(X,X), _(C,C), _(C,C), _(C,C), - /* 0CB8 */ _(C,C), _(C,C), _(X,X), _(X,X), _(N,X), _(S,SM), _(M,BS), _(M,BS), - /* 0CC0 */ _(M,BS), _(M,BS), _(M,BS), _(M,AS), _(M,AS), _(X,X), _(M,BS), _(M,AS), - /* 0CC8 */ _(M,AS), _(X,X), _(M,AS), _(M,AS), _(M,BS), _(H,T), _(X,X), _(X,X), - /* 0CD0 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(M,AS), _(M,AS), _(X,X), - /* 0CD8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(X,X), - /* 0CE0 */ _(V,C), _(V,C), _(M,BS), _(M,BS), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0CE8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0CF0 */ _(X,X), _(CS,C), _(CS,C),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0CF8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - - /* Malayalam */ - - /* 0D00 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(GB,C), _(V,C), _(V,C), _(V,C), - /* 0D08 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(V,C), _(V,C), - /* 0D10 */ _(V,C), _(X,X), _(V,C), _(V,C), _(V,C), _(C,C), _(C,C), _(C,C), - /* 0D18 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0D20 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0D28 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0D30 */ _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 0D38 */ _(C,C), _(C,C), _(C,C), _(M,AS), _(M,AS), _(S,SM), _(M,AP), _(M,AP), - /* 0D40 */ _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(M,AP), _(X,X), _(M,LM), _(M,LM), - /* 0D48 */ _(M,LM), _(X,X), _(M,AP), _(M,AP), _(M,AP), _(H,T), _(Rf,X), _(X,X), - /* 0D50 */ _(X,X), _(X,X), _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(M,AP), - /* 0D58 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), - /* 0D60 */ _(V,C), _(V,C), _(M,AP), _(M,AP), _(X,X), _(X,X), _(GB,C), _(GB,C), - /* 0D68 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 0D70 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 0D78 */ _(X,X), _(X,X), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - -#define indic_offset_0x1000u 1216 - - - /* Myanmar */ - - /* 1000 */ _(C,C), _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), - /* 1008 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1010 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1018 */ _(C,C), _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1020 */ _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), - /* 1028 */ _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R), _(VA,T), _(VA,T), _(VB,B), - /* 1030 */ _(VB,B), _(VL,L), _(A,SM), _(VA,T), _(VA,T), _(VA,T), _(A,SM), _(N,X), - /* 1038 */_(SM,SM), _(H,X), _(As,X), _(MY,X), _(MR,X), _(MW,X), _(MH,X), _(C,C), - /* 1040 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 1048 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(C,C), _(X,X), - /* 1050 */ _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(VR,R), _(VR,R), - /* 1058 */ _(VB,B), _(VB,B), _(R,C), _(C,C), _(C,C), _(C,C), _(MY,X), _(MY,X), - /* 1060 */ _(ML,X), _(C,C), _(VR,R), _(PT,X), _(PT,X), _(C,C), _(C,C), _(VR,R), - /* 1068 */ _(VR,R), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(PT,X), _(C,C), _(C,C), - /* 1070 */ _(C,C), _(VA,T), _(VA,T), _(VA,T), _(VA,T), _(C,C), _(C,C), _(C,C), - /* 1078 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1080 */ _(C,C), _(C,C), _(MW,X), _(VR,R), _(VL,L), _(VA,T), _(VA,T),_(SM,SM), - /* 1088 */_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM),_(SM,SM), _(C,C),_(SM,SM), - /* 1090 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 1098 */ _(GB,C), _(GB,C),_(SM,SM),_(SM,SM),_(SM,SM), _(VA,T), _(X,X), _(X,X), - -#define indic_offset_0x1780u 1376 - - - /* Khmer */ - - /* 1780 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1788 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1790 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 1798 */ _(C,C), _(C,C), _(R,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* 17A0 */ _(C,C), _(C,C), _(C,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), - /* 17A8 */ _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), _(V,C), - /* 17B0 */ _(V,C), _(V,C), _(V,C), _(V,C), _(X,X), _(X,X), _(VR,R), _(VA,T), - /* 17B8 */ _(VA,T), _(VA,T), _(VA,T), _(VB,B), _(VB,B), _(VB,B), _(VA,T), _(VR,R), - /* 17C0 */ _(VR,R), _(VL,L), _(VL,L), _(VL,L), _(VR,R), _(VR,R), _(Xg,X), _(Yg,X), - /* 17C8 */ _(Yg,X), _(Rt,X), _(Rt,X), _(Xg,X), _(Rt,X), _(Xg,X), _(Xg,X), _(Xg,X), - /* 17D0 */ _(Xg,X), _(Xg,X), _(H,X), _(Yg,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 17D8 */ _(X,X), _(GB,C), _(X,X), _(X,X), _(S,SM), _(Yg,X), _(X,X), _(X,X), - /* 17E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 17E8 */ _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x1cd0u 1488 - - - /* Vedic Extensions */ - - /* 1CD0 */ _(A,SM), _(A,SM), _(A,SM), _(X,X), _(A,SM), _(A,SM), _(A,SM), _(A,SM), - /* 1CD8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), - /* 1CE0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), - /* 1CE8 */ _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(A,SM), _(S,SM), _(S,SM), - /* 1CF0 */ _(S,SM), _(S,SM), _(C,C), _(C,C), _(A,SM), _(C,C), _(C,C), _(A,SM), - /* 1CF8 */ _(A,SM), _(A,SM), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x2008u 1536 - - - /* General Punctuation */ - - /* 2008 */ _(X,X), _(X,X), _(X,X), _(X,X),_(ZWNJ,X),_(ZWJ,X), _(X,X), _(X,X), - /* 2010 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), - /* 2018 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 2020 */ _(X,X), _(X,X), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x2070u 1568 - - - /* Superscripts and Subscripts */ - - /* 2070 */ _(X,X), _(X,X), _(X,X), _(X,X),_(SM,SM), _(X,X), _(X,X), _(X,X), - /* 2078 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), - /* 2080 */ _(X,X), _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x25f8u 1592 - - - /* Geometric Shapes */ - - /* 25F8 */ _(X,X), _(X,X), _(X,X), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), - -#define indic_offset_0xa8e0u 1600 - - - /* Devanagari Extended */ - - /* A8E0 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), - /* A8E8 */ _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), _(A,SM), - /* A8F0 */ _(A,SM), _(A,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), _(S,SM), - /* A8F8 */ _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(X,X), _(V,C), _(M,AS), - -#define indic_offset_0xa9e0u 1632 - - - /* Myanmar Extended-B */ - - /* A9E0 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(VA,T), _(X,X), _(C,C), - /* A9E8 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* A9F0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* A9F8 */ _(GB,C), _(GB,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(X,X), - -#define indic_offset_0xaa60u 1664 - - - /* Myanmar Extended-A */ - - /* AA60 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* AA68 */ _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), _(C,C), - /* AA70 */ _(X,X), _(C,C), _(C,C), _(C,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), - /* AA78 */ _(X,X), _(X,X), _(C,C), _(PT,X), _(N,X), _(N,X), _(C,C), _(C,C), - -#define indic_offset_0xfe00u 1696 - - - /* Variation Selectors */ - - /* FE00 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), - /* FE08 */ _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), _(VS,X), - -#define indic_offset_0x11300u 1712 - - - /* Grantha */ - - /* 11300 */ _(X,X),_(SM,SM),_(SM,SM),_(SM,SM), _(X,X), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x11338u 1720 - - /* 11338 */ _(X,X), _(X,X), _(X,X), _(N,X), _(N,X), _(X,X), _(X,X), _(X,X), - -#define indic_offset_0x116d0u 1728 - - - /* Myanmar Extended-C */ - - /* 116D0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 116D8 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(GB,C), - /* 116E0 */ _(GB,C), _(GB,C), _(GB,C), _(GB,C), _(X,X), _(X,X), _(X,X), _(X,X), - -}; /* Table items: 1752; occupancy: 71% */ +static const uint16_t _hb_indic_values[42]= +{ + _(A,SM), _(As,X), _(C,C), _(CM,C), _(CS,C), _(DC,C), _(GB,C), _(H,B), + _(H,T), _(H,X), _(M,A), _(M,AP), _(M,AS), _(M,B), _(M,BS), _(M,LM), + _(MH,X), _(ML,X), _(MP,AP), _(MR,X), _(MW,X), _(MY,X), _(N,X), _(PT,X), + _(R,C), _(Rf,X), _(Rt,X), _(S,SM), _(SM,BS), _(SM,SM), _(SP,SM), _(V,C), + _(VA,T), _(VB,B), _(VL,L), _(VR,R), _(VS,X), _(X,X), _(Xg,X), _(Yg,X), + _(ZWJ,X),_(ZWNJ,X), +}; +static const uint8_t _hb_indic_u8[1220]= +{ + 1, 0, 50, 4, 5, 96, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,186, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, + 0, 0, 0, 0,208,224, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 22, 23, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 0, 0, + 0, 27, 0, 0, 0, 0, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 34, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 25, 2, 10, 0, 0, 0, 0, 26, 0, + 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 29, 11, 30, 1, 1, 1, + 4, 31, 32, 33, 34, 1, 6, 2, 35, 1, 12, 13, 7, 1, 1, 3, + 36, 14, 15, 37, 16, 17, 6, 2, 38, 39, 18, 40, 7, 1, 1, 3, + 41, 42, 43, 44, 45, 46, 19, 2, 47, 0, 18, 48, 49, 1, 1, 3, + 20, 14, 50, 51, 0, 0, 21, 2, 0, 52, 53, 13, 7, 1, 1, 3, + 20, 54, 15, 55, 56, 17, 6, 2, 57, 0, 58, 59, 60, 61, 62, 63, + 4, 64, 65, 66, 16, 0, 19, 2, 0, 0, 67, 8, 9, 1, 1, 3, + 4, 22, 68, 69, 70, 71, 23, 2, 0, 0, 12, 8, 9, 1, 1, 3, + 72, 22, 73, 74, 75, 76, 23, 2, 77, 0, 78, 8, 9, 1, 1, 1, + 4, 79, 80, 81, 82, 83, 21, 2, 0, 84, 85, 1, 1, 86, 87, 88, + 89, 90, 2, 91, 92, 93, 94, 95, 96, 1, 97, 98, 2, 99, 0, 0, + 0, 0, 1, 1, 1,100,101, 11,102,103,104,105,106,107, 2, 10, + 0, 0, 0, 0,108, 5, 5,109,110,111, 0,112,113, 0,114, 0, + 0, 0, 0, 0, 0, 0, 0, 0,115, 0,116, 0, 0, 0, 0, 0, + 0, 0, 0,117, 0, 0, 0, 0, 0,118, 0, 0, 0, 0, 5, 5, + 119,120, 0, 0, 0, 0,121, 1, 2,122, 0, 0, 0, 0, 1, 1, + 123,124, 24, 24, 0, 0, 0, 0, 0, 0,125, 0, 0, 0, 0, 0, + 0,126, 0, 0, 2, 2, 2, 10, 0, 0, 0, 0, 2, 2, 2, 2, + 4, 4, 4, 4, 10, 2, 2, 2, 26, 2, 2, 2, 8, 8, 8, 8, + 6, 18, 0, 4, 20, 14, 24, 2, 6, 6, 20, 6, 20, 6, 24, 2, + 4, 0, 0, 0, 6, 6, 6, 6, 66, 12, 14, 6, 6, 6, 20, 14, + 2, 0, 36, 50, 52, 18, 38, 68, 0, 0, 0, 32, 0, 0, 2, 16, + 56, 12, 14, 6, 0, 0, 0, 4, 44, 2, 16, 2, 6, 22, 0, 4, + 2, 0, 36, 28, 6, 28, 0, 4, 30, 30, 30, 30, 0, 0, 42, 0, + 34, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 42, 12, 12, 6, 6, + 6, 6, 24, 2, 2, 18, 36,112, 18, 18, 18, 18, 18, 18,114,116, + 118,120,122, 18, 0, 6, 6, 6, 44, 10, 0, 2, 54, 32, 46, 10, + 26, 0, 0, 0, 0, 0, 34, 70, 6, 20, 0, 14, 44, 2, 16, 10, + 2, 0, 72, 50,124, 48, 0, 32, 48, 32, 46, 0,126, 0, 0, 0, + 16, 2, 10, 10, 12, 2,128, 0, 6, 6, 6, 14, 6, 14, 24, 2, + 22, 22, 52, 74, 76, 32, 46, 0, 16, 58, 58, 78,130, 12, 14, 6, + 2, 0, 36,132,134, 32, 46, 0, 0, 0, 80,136, 16, 0, 0, 0, + 0, 70, 14, 6, 6, 20, 0, 6, 20, 6, 24, 0, 16, 10, 10, 2, + 0, 16, 10, 0, 2, 10, 0, 2, 2, 0, 0, 22, 76, 48, 0, 82, + 54, 22, 84, 0, 12, 12,138, 6, 28, 60, 38, 28, 86, 28, 88, 0, + 0, 0,140, 86, 2, 10, 16, 0, 26, 2, 16, 2, 28, 60, 38, 60, + 38, 18, 88, 0, 0, 0, 74, 38, 0, 0, 16, 10,142,144, 0, 0, + 12, 12,146, 6, 2,148,150, 22, 22, 22, 48, 82, 54, 22, 84,152, + 0, 0, 2,154, 0, 0, 0, 14, 0, 2, 2, 2, 2, 2, 26, 2, + 2,156, 2, 2, 90, 6, 6, 6, 6,158, 92, 94,160,162, 62, 58, + 164,166,168,170, 4, 4, 0, 10, 2, 6, 6, 96, 98, 26, 2,172, + 174,100,176,178,100,102,102, 2,104, 62,180, 2, 2,182,184,186, + 12, 12, 12,188, 4, 12,190, 0, 2, 26, 2, 2, 2, 90, 6, 6, + 6, 6, 0, 92, 62, 94, 98,192,194,196, 96,198,200,106,106,108, + 108,202, 0, 0, 42, 0,204, 0, 8,206, 8, 8,208, 40,210, 40, + 40, 2,212,214, 8, 34, 0, 0, 0, 0,216, 0, 4, 4, 4, 0, + 0, 34, 0, 0, 0, 0,110, 0, 0, 64,110, 0, 0, 0,218, 0, + 0, 42, 4, 34, 8, 40, 40, 40, 0, 0, 0,220, 2, 2,104, 16, + 4, 2, 2, 10, 16, 2, 4, 34, 0,222, 78, 2, 56, 12, 0, 0, + 0, 80, 72, 0, 37, 37, 2, 2, 6, 6, 31, 31, 0, 0, 2, 37, + 29, 29, 37, 31, 37, 2, 12, 12, 31, 37, 11, 11, 31, 2, 24, 2, + 14, 14, 36, 36, 37, 11, 6, 37, 22, 27, 12, 37, 27, 27, 37, 6, + 24, 37, 11, 7, 11, 37, 11, 15, 11, 12, 15, 37, 37, 29, 0, 22, + 14, 12, 32, 32, 30, 30, 6, 29, 37, 15, 29, 37, 22, 37, 37, 12, + 12, 11, 22, 22, 37, 22, 15, 15, 11, 8, 14, 37, 14, 8, 2, 31, + 35, 32, 32, 33, 35, 35, 33, 33, 35, 23, 23, 23, 2, 32, 26, 38, + 38, 38, 30, 37, 12, 15, 12, 7, 15, 12, 37, 0, 0, 29, 29, 12, + 18, 11, 37, 13, 37, 3, 37, 28, 11, 10, 10, 37, 10, 11, 29, 31, + 37, 14, 37, 4, 4, 29, 6, 31, 2, 12, 12, 27, 25, 37, 2, 11, + 2, 24, 31, 35, 33, 34, 0, 32, 29, 9, 1, 21, 19, 20, 16, 2, + 21, 21, 17, 2, 23, 2, 2, 35, 32, 2, 20, 35, 34, 32, 32, 29, + 2, 29, 29, 32, 32, 35, 35, 34, 34, 34, 38, 39, 39, 26, 9, 39, + 27, 39, 0, 37, 0, 27, 27, 0, 0, 2, 2, 0, 41, 40, 5, 37, + 31, 12, 2, 23, +}; + +static inline uint8_t _hb_indic_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1)<<2))&15; +} +static inline uint8_t _hb_indic_get_categories_index (unsigned u) +{ + /* packtab: [2^4,2^3,2^3,2^2,2^1] */ + return u<71396u ? (uint8_t)(_hb_indic_u8[996u+_hb_indic_u8[488u+((_hb_indic_u8[186u+((_hb_indic_u8[70u+((_hb_indic_b4(_hb_indic_u8,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)])<<3)+((((((u)>>1))>>2))&7)])<<2)+((((u)>>1))&3)]+((u)&1)]) : 37; +} uint16_t hb_indic_get_categories (hb_codepoint_t u) { - switch (u >> 12) - { - case 0x0u: - if (unlikely (u == 0x00A0u)) return _(GB,C); - if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u]; - if (hb_in_range (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u]; - if (hb_in_range (u, 0x0900u, 0x0D7Fu)) return indic_table[u - 0x0900u + indic_offset_0x0900u]; - break; - - case 0x1u: - if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u]; - if (hb_in_range (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u]; - if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u]; - break; - - case 0x2u: - if (unlikely (u == 0x25CCu)) return _(DC,C); - if (hb_in_range (u, 0x2008u, 0x2027u)) return indic_table[u - 0x2008u + indic_offset_0x2008u]; - if (hb_in_range (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u]; - if (hb_in_range (u, 0x25F8u, 0x25FFu)) return indic_table[u - 0x25F8u + indic_offset_0x25f8u]; - break; - - case 0xAu: - if (hb_in_range (u, 0xA8E0u, 0xA8FFu)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u]; - if (hb_in_range (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u]; - if (hb_in_range (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u]; - break; - - case 0xFu: - if (hb_in_range (u, 0xFE00u, 0xFE0Fu)) return indic_table[u - 0xFE00u + indic_offset_0xfe00u]; - break; - - case 0x11u: - if (hb_in_range (u, 0x11300u, 0x11307u)) return indic_table[u - 0x11300u + indic_offset_0x11300u]; - if (hb_in_range (u, 0x11338u, 0x1133Fu)) return indic_table[u - 0x11338u + indic_offset_0x11338u]; - if (hb_in_range (u, 0x116D0u, 0x116E7u)) return indic_table[u - 0x116D0u + indic_offset_0x116d0u]; - break; - - default: - break; - } - return _(X,X); + return _hb_indic_values[_hb_indic_get_categories_index (u)]; } #undef _ @@ -540,6 +262,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef _OT_Rf #undef _OT_Rt #undef _OT_SM +#undef _OT_SP #undef _OT_S #undef _OT_V #undef _OT_VA diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic.cc index f8c970fc3..8501629d7 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-indic.cc @@ -296,12 +296,7 @@ struct indic_shape_plan_t const indic_config_t *config; bool is_old_spec; -#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE - bool uniscribe_bug_compatible; -#else - static constexpr bool uniscribe_bug_compatible = false; -#endif - mutable hb_atomic_int_t virama_glyph; + mutable hb_atomic_t virama_glyph; hb_indic_would_substitute_feature_t rphf; hb_indic_would_substitute_feature_t pref; @@ -327,9 +322,6 @@ data_create_indic (const hb_ot_shape_plan_t *plan) } indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2'); -#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE - indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible; -#endif indic_plan->virama_glyph = -1; /* Use zero-context would_substitute() matching for new-spec of the main @@ -943,17 +935,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, unsigned int start, unsigned int end) { /* We treat placeholder/dotted-circle as if they are consonants, so we - * should just chain. Only if not in compatibility mode that is... */ - - const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; - if (indic_plan->uniscribe_bug_compatible) - { - /* For dotted-circle, this is what Uniscribe does: - * If dotted-circle is the last glyph, it just does nothing. - * Ie. It doesn't form Reph. */ - if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE)) - return; - } + * should just chain... */ initial_reordering_consonant_syllable (plan, face, buffer, start, end); } @@ -1347,8 +1329,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, * Uniscribe doesn't do this. * TEST: U+0930,U+094D,U+0915,U+094B,U+094D */ - if (!indic_plan->uniscribe_bug_compatible && - unlikely (is_halant (info[new_reph_pos]))) + if (unlikely (is_halant (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) if (FLAG_UNSAFE (info[i].indic_category()) & (FLAG (I_Cat(M)) | FLAG (I_Cat(MPst)))) @@ -1451,27 +1432,6 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, else buffer->unsafe_to_break (start - 1, start + 1); } - - - /* - * Finish off the clusters and go home! - */ - if (indic_plan->uniscribe_bug_compatible) - { - switch ((hb_tag_t) plan->props.script) - { - case HB_SCRIPT_TAMIL: - break; - - default: - /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil. - * This means, half forms are submerged into the main consonant's cluster. - * This is unnecessary, and makes cursor positioning harder, but that's what - * Uniscribe does. */ - buffer->merge_clusters (start, end); - break; - } - } } @@ -1501,9 +1461,7 @@ preprocess_text_indic (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font) { - const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; - if (!indic_plan->uniscribe_bug_compatible) - _hb_preprocess_text_vowel_constraints (plan, buffer, font); + _hb_preprocess_text_vowel_constraints (plan, buffer, font); } static bool diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-khmer.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-khmer.cc index 019a28510..eb3b585e8 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-khmer.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-khmer.cc @@ -141,12 +141,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan) * typographical correctness.", hence in overrides... */ map->enable_feature (HB_TAG('c','l','i','g')); - /* Uniscribe does not apply 'kern' in Khmer. */ - if (hb_options ().uniscribe_bug_compatible) - { - map->disable_feature (HB_TAG('k','e','r','n')); - } - map->disable_feature (HB_TAG('l','i','g','a')); } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.hh index f7b456b11..4b8da586d 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.hh @@ -68,6 +68,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_PT 39u #define myanmar_syllable_machine_ex_Ra 15u #define myanmar_syllable_machine_ex_SM 8u +#define myanmar_syllable_machine_ex_SMPst 57u #define myanmar_syllable_machine_ex_VAbv 20u #define myanmar_syllable_machine_ex_VBlw 21u #define myanmar_syllable_machine_ex_VPre 22u @@ -77,35 +78,35 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-myanmar-machine.hh" +#line 82 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { - 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, - 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u, - 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 41u, - 3u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, - 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 41u, 3u, 39u, - 3u, 39u, 3u, 40u, 3u, 39u, 3u, 41u, 3u, 41u, 3u, 39u, 3u, 41u, 3u, 41u, - 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 3u, 41u, 1u, 41u, 1u, 15u, 0 + 1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, 3u, 57u, + 3u, 57u, 3u, 57u, 3u, 57u, 1u, 57u, 1u, 15u, 0 }; static const char _myanmar_syllable_machine_key_spans[] = { - 41, 39, 35, 4, 39, 37, 37, 35, - 35, 37, 37, 39, 35, 15, 37, 37, - 38, 37, 39, 39, 37, 39, 39, 39, - 39, 39, 35, 4, 39, 37, 37, 35, - 35, 37, 37, 39, 35, 15, 39, 37, - 37, 38, 37, 39, 39, 37, 39, 39, - 39, 39, 39, 39, 39, 41, 15 + 57, 55, 53, 53, 55, 53, 55, 55, + 55, 55, 55, 53, 15, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 53, 53, 55, 53, 55, 55, 55, + 55, 55, 53, 15, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 57, 15 }; static const short _myanmar_syllable_machine_index_offsets[] = { - 0, 42, 82, 118, 123, 163, 201, 239, - 275, 311, 349, 387, 427, 463, 479, 517, - 555, 594, 632, 672, 712, 750, 790, 830, - 870, 910, 950, 986, 991, 1031, 1069, 1107, - 1143, 1179, 1217, 1255, 1295, 1331, 1347, 1387, - 1425, 1463, 1502, 1540, 1580, 1620, 1658, 1698, - 1738, 1778, 1818, 1858, 1898, 1938, 1980 + 0, 58, 114, 168, 222, 278, 332, 388, + 444, 500, 556, 612, 666, 682, 738, 794, + 850, 906, 962, 1018, 1074, 1130, 1186, 1242, + 1298, 1354, 1408, 1462, 1518, 1572, 1628, 1684, + 1740, 1796, 1852, 1906, 1922, 1978, 2034, 2090, + 2146, 2202, 2258, 2314, 2370, 2426, 2482, 2538, + 2594, 2650, 2706, 2762, 2820 }; static const char _myanmar_syllable_machine_indicies[] = { @@ -114,273 +115,378 @@ static const char _myanmar_syllable_machine_indicies[] = { 0, 8, 0, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 15, 16, 17, 18, 19, - 20, 0, 22, 23, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 31, - 21, 21, 32, 33, 34, 35, 36, 37, - 38, 21, 24, 24, 21, 25, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 39, 21, 21, - 21, 21, 21, 21, 36, 21, 24, 24, - 21, 25, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 42, 21, 21, 21, 36, - 21, 41, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 21, 43, 21, 24, 24, 21, 25, 36, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 44, 21, - 21, 21, 21, 21, 21, 36, 21, 24, - 24, 21, 25, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 44, 21, 21, 21, 21, 21, - 21, 36, 21, 24, 24, 21, 25, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 36, 21, 22, - 21, 24, 24, 21, 25, 26, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 40, 21, 21, 30, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 36, 21, 22, 21, 24, - 24, 21, 25, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 40, 21, - 21, 30, 21, 21, 21, 21, 21, 21, - 21, 21, 41, 21, 21, 21, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 41, 21, 21, 21, 21, 21, 21, 36, - 21, 41, 21, 24, 24, 21, 25, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 30, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 36, 21, 1, - 1, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 1, 21, 22, - 21, 24, 24, 21, 25, 26, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 27, 28, 21, 30, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 36, 21, 22, 21, 24, - 24, 21, 25, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 28, - 21, 30, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 26, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 27, 28, 29, 30, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 36, - 45, 21, 22, 21, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 36, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 31, 21, 21, - 32, 33, 34, 35, 36, 21, 38, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 45, 21, 21, - 21, 21, 21, 21, 36, 21, 38, 21, - 22, 21, 24, 24, 21, 25, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 27, 28, 29, 30, 21, 21, 21, - 21, 21, 21, 21, 21, 45, 21, 21, - 21, 21, 21, 21, 36, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 21, - 34, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 45, 21, 21, 32, 21, - 21, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 46, 21, 21, 32, 33, - 34, 21, 36, 21, 38, 21, 22, 21, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 33, - 34, 21, 36, 21, 38, 21, 22, 23, - 24, 24, 21, 25, 26, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 27, - 28, 29, 30, 21, 21, 21, 21, 21, - 21, 21, 21, 31, 21, 21, 32, 33, - 34, 35, 36, 21, 38, 21, 48, 48, + 20, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 21, 0, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 38, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 25, 25, 22, 26, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 31, 22, 22, 22, + 22, 22, 22, 22, 22, 40, 22, 22, + 22, 22, 22, 22, 37, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 26, 22, + 25, 25, 22, 26, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 37, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 26, 22, 41, 22, + 25, 25, 22, 26, 37, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 26, 22, 22, 22, 22, + 22, 22, 37, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 26, 22, 25, 25, + 22, 26, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 26, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 44, 22, 22, 22, + 37, 22, 43, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 22, 22, 22, 22, + 37, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 23, 22, 25, 25, + 22, 26, 27, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 42, 22, 22, + 31, 22, 22, 22, 22, 22, 22, 22, + 22, 43, 22, 22, 22, 22, 22, 22, + 37, 22, 43, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 26, 22, 25, 25, 22, 26, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 1, 1, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 1, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 29, 22, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 45, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 22, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 22, 22, 37, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 22, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 33, 22, 22, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 46, + 22, 22, 33, 34, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 22, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 34, 35, 22, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 48, 48, 47, 5, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 12, 47, 47, 47, + 47, 47, 47, 47, 47, 49, 47, 47, + 47, 47, 47, 47, 18, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 5, 47, + 48, 48, 50, 5, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 18, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 5, 50, 51, 47, + 48, 48, 47, 5, 18, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 5, 47, 47, 47, 47, + 47, 47, 18, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 5, 47, 48, 48, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 5, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 53, 47, 47, 54, 47, 47, 47, + 18, 47, 53, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, + 12, 47, 47, 47, 47, 47, 47, 47, + 47, 53, 47, 47, 47, 47, 47, 47, + 18, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 2, 47, 48, 48, + 47, 5, 6, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 52, 47, 47, 12, 47, 47, 47, 47, 47, 47, 47, - 47, 49, 47, 47, 47, 47, 47, 47, - 18, 47, 48, 48, 47, 5, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 47, 53, 47, 47, 47, 47, 47, 47, + 18, 47, 53, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 50, 47, 47, 12, 47, 47, 47, 47, - 47, 47, 47, 47, 51, 47, 47, 52, - 47, 47, 47, 18, 47, 51, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 47, 47, 5, 47, 48, 48, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 12, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 18, 47, 53, 47, 48, - 48, 47, 5, 18, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 54, 47, 47, 47, 47, 47, - 47, 18, 47, 48, 48, 47, 5, 47, + 5, 47, 55, 55, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 55, 47, 2, 3, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 13, + 47, 47, 14, 15, 16, 17, 18, 19, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 54, 47, - 47, 47, 47, 47, 47, 18, 47, 48, - 48, 47, 5, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 18, 47, 2, 47, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 50, 47, 47, 12, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 10, 47, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 18, - 47, 2, 47, 48, 48, 47, 5, 6, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 50, 47, 47, 12, 47, 47, - 47, 47, 47, 47, 47, 47, 51, 47, - 47, 47, 47, 47, 47, 18, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 50, 47, 47, 12, 47, 47, 47, 47, - 47, 47, 47, 47, 51, 47, 47, 47, - 47, 47, 47, 18, 47, 51, 47, 48, - 48, 47, 5, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 12, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 18, 56, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 18, 47, 55, 55, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 55, 47, 2, 3, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 9, 10, 11, 12, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 13, 47, 47, 14, 15, 16, 17, 18, - 19, 20, 47, 2, 47, 48, 48, 47, - 5, 6, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 9, 10, 47, 12, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 18, - 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 10, 47, 12, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 13, + 47, 47, 14, 15, 16, 17, 18, 47, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 18, 47, 2, - 47, 48, 48, 47, 5, 6, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 56, + 47, 47, 47, 47, 47, 47, 18, 47, + 20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 9, 10, 11, 12, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, + 6, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 9, 10, 11, 12, 47, + 47, 47, 47, 47, 47, 47, 47, 56, + 47, 47, 47, 47, 47, 47, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 18, 56, 47, 2, 47, - 48, 48, 47, 5, 6, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 9, - 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 18, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 13, 47, 47, 14, 15, 16, 17, - 18, 47, 20, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 56, 47, 47, 47, 47, 47, 47, - 18, 47, 20, 47, 2, 47, 48, 48, - 47, 5, 6, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 9, 10, 11, - 12, 47, 47, 47, 47, 47, 47, 47, - 47, 56, 47, 47, 47, 47, 47, 47, - 18, 47, 2, 47, 48, 48, 47, 5, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 14, 47, 16, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 56, 47, 47, 14, 47, 47, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 57, 47, 47, 14, 15, 16, 47, 18, 47, - 20, 47, 2, 47, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 47, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 14, 15, 16, 47, 18, 47, - 20, 47, 2, 3, 48, 48, 47, 5, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 2, 3, 48, 48, 47, 5, 6, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 13, 47, 47, 14, 15, 16, 17, 18, 47, - 20, 47, 22, 23, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 58, - 21, 21, 32, 33, 34, 35, 36, 37, - 38, 21, 22, 59, 24, 24, 21, 25, - 26, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 27, 28, 29, 30, 21, - 21, 21, 21, 21, 21, 21, 21, 31, - 21, 21, 32, 33, 34, 35, 36, 21, - 38, 21, 1, 1, 2, 3, 48, 48, + 20, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 5, 47, 23, 24, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 58, + 22, 22, 33, 34, 35, 36, 37, 38, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 23, 59, 25, 25, 22, 26, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 28, 29, 30, 31, 22, + 22, 22, 22, 22, 22, 22, 22, 32, + 22, 22, 33, 34, 35, 36, 37, 22, + 39, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 26, 22, 1, 1, 2, 3, 48, 48, 47, 5, 6, 1, 1, 47, 47, 47, 1, 47, 47, 47, 47, 9, 10, 11, 12, 47, 47, 47, 47, 47, 47, 47, 47, 13, 47, 47, 14, 15, 16, 17, - 18, 19, 20, 47, 1, 1, 60, 60, + 18, 19, 20, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 5, 47, 1, 1, 60, 60, 60, 60, 60, 60, 60, 1, 1, 60, 60, 60, 1, 60, 0 }; static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 26, 37, 0, 27, 29, 51, - 54, 39, 40, 41, 28, 43, 44, 46, - 47, 48, 30, 50, 45, 0, 2, 13, - 0, 3, 5, 14, 15, 16, 4, 18, - 19, 21, 22, 23, 6, 25, 20, 12, - 9, 10, 11, 7, 8, 17, 24, 0, - 0, 36, 33, 34, 35, 31, 32, 38, - 42, 49, 52, 53, 0 + 0, 1, 25, 35, 0, 26, 30, 49, + 52, 37, 38, 39, 29, 41, 42, 44, + 45, 46, 27, 48, 43, 26, 0, 2, + 12, 0, 3, 7, 13, 14, 15, 6, + 17, 18, 20, 21, 22, 4, 24, 19, + 11, 5, 8, 9, 10, 16, 23, 0, + 0, 34, 0, 28, 31, 32, 33, 36, + 40, 47, 50, 51, 0 }; static const char _myanmar_syllable_machine_trans_actions[] = { - 3, 0, 0, 0, 4, 0, 0, 0, + 3, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 7, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, - 8, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9 + 0, 0, 0, 0, 0, 0, 0, 9, + 10, 0, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12 }; static const char _myanmar_syllable_machine_to_state_actions[] = { @@ -390,7 +496,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 }; static const char _myanmar_syllable_machine_from_state_actions[] = { @@ -400,17 +506,17 @@ static const char _myanmar_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 }; static const short _myanmar_syllable_machine_eof_trans[] = { - 0, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 48, 48, 48, 48, 48, 48, + 0, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 48, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 22, 22, 48, 61 + 48, 23, 23, 48, 61 }; static const int myanmar_syllable_machine_start = 0; @@ -424,7 +530,7 @@ static const int myanmar_syllable_machine_en_main = 0; -#line 117 "hb-ot-shaper-myanmar-machine.rl" +#line 118 "hb-ot-shaper-myanmar-machine.rl" #define found_syllable(syllable_type) \ @@ -443,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 447 "hb-ot-shaper-myanmar-machine.hh" +#line 553 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -451,7 +557,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) act = 0; } -#line 137 "hb-ot-shaper-myanmar-machine.rl" +#line 138 "hb-ot-shaper-myanmar-machine.rl" p = 0; @@ -459,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 463 "hb-ot-shaper-myanmar-machine.hh" +#line 569 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +579,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-myanmar-machine.hh" +#line 583 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -491,35 +597,59 @@ _eof_trans: goto _again; switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { - case 6: -#line 110 "hb-ot-shaper-myanmar-machine.rl" + case 8: +#line 111 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} break; case 4: -#line 111 "hb-ot-shaper-myanmar-machine.rl" +#line 112 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; - case 8: -#line 112 "hb-ot-shaper-myanmar-machine.rl" + case 10: +#line 113 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 3: -#line 113 "hb-ot-shaper-myanmar-machine.rl" +#line 114 "hb-ot-shaper-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; - case 5: -#line 110 "hb-ot-shaper-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} - break; case 7: -#line 112 "hb-ot-shaper-myanmar-machine.rl" - {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} +#line 111 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} break; case 9: #line 113 "hb-ot-shaper-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 12: +#line 114 "hb-ot-shaper-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 523 "hb-ot-shaper-myanmar-machine.hh" + case 11: +#line 1 "NONE" + { switch( act ) { + case 2: + {{p = ((te))-1;} found_syllable (myanmar_non_myanmar_cluster); } + break; + case 3: + {{p = ((te))-1;} found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + } + } + break; + case 6: +#line 1 "NONE" + {te = p+1;} +#line 112 "hb-ot-shaper-myanmar-machine.rl" + {act = 2;} + break; + case 5: +#line 1 "NONE" + {te = p+1;} +#line 113 "hb-ot-shaper-myanmar-machine.rl" + {act = 3;} + break; +#line 653 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +658,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 532 "hb-ot-shaper-myanmar-machine.hh" +#line 662 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) @@ -544,7 +674,7 @@ _again: } -#line 145 "hb-ot-shaper-myanmar-machine.rl" +#line 146 "hb-ot-shaper-myanmar-machine.rl" } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.rl b/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.rl index e8d1e788c..0b7a95997 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.rl +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-myanmar-machine.rl @@ -72,6 +72,7 @@ export DOTTEDCIRCLE = 11; export A = 9; export Ra = 15; export CS = 18; +export SMPst= 57; export VAbv = 20; export VBlw = 21; @@ -91,15 +92,15 @@ export ML = 41; # Medial Mon La j = ZWJ|ZWNJ; # Joiners k = (Ra As H); # Kinzi - +sm = SM | SMPst; c = C|Ra; # is_consonant medial_group = MY? As? MR? ((MW MH? ML? | MH ML? | ML) As?)?; main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?; post_vowel_group = VPst MH? ML? As* VAbv* A* (DB As?)?; -pwo_tone_group = PT A* DB? As?; +tone_group = sm | PT A* DB? As?; -complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* SM* j?; +complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* tone_group* j?; syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail); consonant_syllable = (k|CS)? (c|IV|GB|DOTTEDCIRCLE).VS? syllable_tail; @@ -108,7 +109,7 @@ other = any; main := |* consonant_syllable => { found_syllable (myanmar_consonant_syllable); }; - j => { found_syllable (myanmar_non_myanmar_cluster); }; + j | SMPst => { found_syllable (myanmar_non_myanmar_cluster); }; broken_cluster => { found_syllable (myanmar_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (myanmar_non_myanmar_cluster); }; *|; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-thai.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-thai.cc index 6cd67cde3..52566fe29 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-thai.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-thai.cc @@ -163,7 +163,7 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) } -static enum thai_above_state_t +static const enum thai_above_state_t { /* Cluster above looks like: */ T0, /* ⣤ */ T1, /* ⣼ */ @@ -191,7 +191,7 @@ static const struct thai_above_state_machine_edge_t { }; -static enum thai_below_state_t +static const enum thai_below_state_t { B0, /* No descender */ B1, /* Removable descender */ @@ -334,7 +334,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, /* Is SARA AM. Decompose and reorder. */ (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); - _hb_glyph_info_set_continuation (&buffer->prev()); + _hb_glyph_info_set_continuation (&buffer->prev(), buffer); if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break; /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ @@ -356,13 +356,11 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, sizeof (buffer->out_info[0]) * (end - start - 2)); buffer->out_info[start] = t; } - else - { - /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the - * previous cluster. */ - if (start && buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) - buffer->merge_out_clusters (start - 1, end); - } + + /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the + * previous cluster. */ + if (start) + buffer->merge_out_grapheme_clusters (start - 1, end); } buffer->sync (); diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.hh index e9da28d45..65b6adc36 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.hh @@ -166,556 +166,556 @@ static const unsigned char _use_syllable_machine_indicies[] = { 19, 20, 21, 8, 22, 23, 24, 25, 5, 26, 27, 28, 5, 29, 30, 31, 32, 33, 34, 35, 32, 1, 5, 36, - 5, 37, 5, 5, 35, 5, 39, 40, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 39, 51, 52, 53, 54, 38, - 55, 56, 57, 38, 58, 59, 38, 60, - 61, 62, 63, 60, 38, 38, 38, 38, - 64, 38, 38, 63, 38, 39, 40, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 42, 43, 44, 45, 46, 47, 48, 49, - 50, 39, 51, 52, 53, 54, 38, 55, - 56, 57, 38, 38, 38, 38, 60, 61, - 62, 63, 60, 38, 38, 38, 38, 64, - 38, 38, 63, 38, 39, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 38, 43, 44, 45, 46, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 55, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 38, 38, 38, - 43, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 38, 43, 44, 45, 46, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 55, 56, 57, 38, 38, 38, 38, - 38, 61, 62, 63, 65, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 44, 45, 46, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 61, 62, 63, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 45, 46, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 61, 62, 63, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 46, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 61, 62, 63, 38, 41, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 61, 62, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 62, 38, 41, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 55, 56, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 44, 45, 46, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 66, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 41, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 42, 43, 44, 45, - 46, 38, 38, 38, 38, 38, 38, 52, - 53, 54, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 38, 38, 38, 43, 38, 41, 38, 38, - 38, 38, 38, 38, 38, 38, 43, 44, - 45, 46, 38, 38, 38, 38, 38, 38, - 52, 53, 54, 38, 55, 56, 57, 38, - 38, 38, 38, 38, 61, 62, 63, 65, - 38, 38, 38, 38, 43, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 38, 43, - 44, 45, 46, 38, 38, 38, 38, 38, - 38, 38, 53, 54, 38, 55, 56, 57, - 38, 38, 38, 38, 38, 61, 62, 63, - 65, 38, 38, 38, 38, 43, 38, 41, - 38, 38, 38, 38, 38, 38, 38, 38, - 43, 44, 45, 46, 38, 38, 38, 38, - 38, 38, 38, 38, 54, 38, 55, 56, - 57, 38, 38, 38, 38, 38, 61, 62, - 63, 65, 38, 38, 38, 38, 43, 38, - 67, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 42, 43, 44, 45, 46, 38, - 48, 49, 38, 38, 38, 52, 53, 54, - 38, 55, 56, 57, 38, 38, 38, 38, - 38, 61, 62, 63, 65, 38, 38, 38, - 38, 43, 38, 41, 38, 38, 38, 38, - 38, 38, 38, 38, 43, 44, 45, 46, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 55, 56, 57, 38, 38, 38, - 38, 38, 61, 62, 63, 65, 38, 38, - 38, 38, 43, 38, 67, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 42, 43, - 44, 45, 46, 38, 38, 49, 38, 38, - 38, 52, 53, 54, 38, 55, 56, 57, - 38, 38, 38, 38, 38, 61, 62, 63, - 65, 38, 38, 38, 38, 43, 38, 67, - 38, 41, 38, 38, 38, 38, 38, 38, - 38, 42, 43, 44, 45, 46, 38, 38, - 38, 38, 38, 38, 52, 53, 54, 38, - 55, 56, 57, 38, 38, 38, 38, 38, - 61, 62, 63, 65, 38, 38, 38, 38, - 43, 38, 67, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 42, 43, 44, 45, - 46, 47, 48, 49, 38, 38, 38, 52, - 53, 54, 38, 55, 56, 57, 38, 38, - 38, 38, 38, 61, 62, 63, 65, 38, - 38, 38, 38, 43, 38, 39, 40, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 42, 43, 44, 45, 46, 47, 48, 49, - 50, 38, 51, 52, 53, 54, 38, 55, - 56, 57, 38, 38, 38, 38, 60, 61, - 62, 63, 60, 38, 38, 38, 38, 64, - 38, 38, 63, 38, 39, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 41, 38, 39, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 41, 38, 38, 38, 38, 38, 38, 38, - 38, 43, 44, 45, 46, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 55, - 56, 57, 38, 38, 38, 38, 38, 61, - 62, 63, 65, 38, 41, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 58, - 59, 38, 41, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 59, 38, - 4, 69, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 4, 80, 81, 82, - 83, 68, 84, 85, 86, 68, 68, 68, - 68, 87, 88, 89, 90, 91, 68, 68, - 68, 68, 92, 68, 68, 93, 68, 4, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 72, 73, 74, - 75, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 84, 85, 86, 68, 68, - 68, 68, 68, 88, 89, 90, 94, 68, - 68, 68, 68, 72, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 72, 73, - 74, 75, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 84, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 94, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 88, 89, 90, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 74, - 75, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 88, 89, 90, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 75, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 88, 89, - 90, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 88, 89, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 89, 68, 70, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 94, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 73, 74, - 75, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 85, 86, 68, 68, - 68, 68, 68, 88, 89, 90, 94, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 94, 68, 96, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 97, 95, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 73, 74, 75, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 88, 89, 90, 94, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 71, - 72, 73, 74, 75, 68, 68, 68, 68, - 68, 68, 81, 82, 83, 68, 84, 85, - 86, 68, 68, 68, 68, 68, 88, 89, - 90, 94, 68, 68, 68, 68, 72, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 72, 73, 74, 75, 68, 68, 68, - 68, 68, 68, 81, 82, 83, 68, 84, - 85, 86, 68, 68, 68, 68, 68, 88, - 89, 90, 94, 68, 68, 68, 68, 72, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 72, 73, 74, 75, 68, 68, - 68, 68, 68, 68, 68, 82, 83, 68, - 84, 85, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 94, 68, 68, 68, 68, - 72, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 72, 73, 74, 75, 68, - 68, 68, 68, 68, 68, 68, 68, 83, - 68, 84, 85, 86, 68, 68, 68, 68, - 68, 88, 89, 90, 94, 68, 68, 68, - 68, 72, 68, 98, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 71, 72, 73, - 74, 75, 68, 77, 78, 68, 68, 68, - 81, 82, 83, 68, 84, 85, 86, 68, - 68, 68, 68, 68, 88, 89, 90, 94, - 68, 68, 68, 68, 72, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 72, - 73, 74, 75, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 84, 85, 86, - 68, 68, 68, 68, 68, 88, 89, 90, - 94, 68, 68, 68, 68, 72, 68, 98, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 71, 72, 73, 74, 75, 68, 68, - 78, 68, 68, 68, 81, 82, 83, 68, - 84, 85, 86, 68, 68, 68, 68, 68, - 88, 89, 90, 94, 68, 68, 68, 68, - 72, 68, 98, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 71, 72, 73, 74, - 75, 68, 68, 68, 68, 68, 68, 81, - 82, 83, 68, 84, 85, 86, 68, 68, - 68, 68, 68, 88, 89, 90, 94, 68, - 68, 68, 68, 72, 68, 98, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 71, - 72, 73, 74, 75, 76, 77, 78, 68, - 68, 68, 81, 82, 83, 68, 84, 85, - 86, 68, 68, 68, 68, 68, 88, 89, - 90, 94, 68, 68, 68, 68, 72, 68, - 4, 69, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 68, 80, 81, 82, - 83, 68, 84, 85, 86, 68, 68, 68, - 68, 87, 88, 89, 90, 91, 68, 68, - 68, 68, 92, 68, 68, 93, 68, 4, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 100, 99, 4, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 97, 95, 4, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 72, 73, 74, 75, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 84, 85, 86, 68, 68, 68, 68, - 68, 88, 89, 90, 94, 68, 100, 99, - 102, 103, 101, 6, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 105, 104, 106, - 107, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 106, 117, 118, 119, 120, - 68, 121, 122, 123, 68, 58, 59, 68, - 124, 125, 126, 127, 128, 68, 68, 68, - 68, 129, 68, 68, 130, 68, 106, 107, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 106, 117, 118, 119, 120, 68, - 121, 122, 123, 68, 68, 68, 68, 124, - 125, 126, 127, 128, 68, 68, 68, 68, - 129, 68, 68, 130, 68, 106, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 109, 110, 111, 112, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 121, 122, 123, 68, 68, 68, 68, - 68, 125, 126, 127, 131, 68, 68, 68, - 68, 109, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 68, 109, 110, 111, 112, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 121, 122, 123, 68, 68, 68, - 68, 68, 125, 126, 127, 131, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 110, 111, 112, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 125, 126, - 127, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 111, 112, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 125, 126, 127, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 112, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 125, 126, 127, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 125, - 126, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 126, 68, 70, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 110, 111, 112, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 121, 122, 123, - 68, 68, 68, 68, 68, 125, 126, 127, - 131, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 110, 111, 112, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 122, 123, 68, 68, 68, 68, - 68, 125, 126, 127, 131, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 110, 111, 112, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 123, - 68, 68, 68, 68, 68, 125, 126, 127, - 131, 68, 132, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 97, - 95, 70, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 110, 111, 112, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 125, 126, 127, 131, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 108, 109, 110, - 111, 112, 68, 68, 68, 68, 68, 68, - 118, 119, 120, 68, 121, 122, 123, 68, - 68, 68, 68, 68, 125, 126, 127, 131, - 68, 68, 68, 68, 109, 68, 70, 68, - 68, 68, 68, 68, 68, 68, 68, 109, - 110, 111, 112, 68, 68, 68, 68, 68, - 68, 118, 119, 120, 68, 121, 122, 123, - 68, 68, 68, 68, 68, 125, 126, 127, - 131, 68, 68, 68, 68, 109, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 68, - 109, 110, 111, 112, 68, 68, 68, 68, - 68, 68, 68, 119, 120, 68, 121, 122, - 123, 68, 68, 68, 68, 68, 125, 126, - 127, 131, 68, 68, 68, 68, 109, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 109, 110, 111, 112, 68, 68, 68, - 68, 68, 68, 68, 68, 120, 68, 121, - 122, 123, 68, 68, 68, 68, 68, 125, - 126, 127, 131, 68, 68, 68, 68, 109, - 68, 133, 68, 70, 68, 68, 68, 68, - 68, 68, 68, 108, 109, 110, 111, 112, - 68, 114, 115, 68, 68, 68, 118, 119, - 120, 68, 121, 122, 123, 68, 68, 68, - 68, 68, 125, 126, 127, 131, 68, 68, - 68, 68, 109, 68, 70, 68, 68, 68, - 68, 68, 68, 68, 68, 109, 110, 111, - 112, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 121, 122, 123, 68, 68, - 68, 68, 68, 125, 126, 127, 131, 68, - 68, 68, 68, 109, 68, 133, 68, 70, - 68, 68, 68, 68, 68, 68, 68, 108, - 109, 110, 111, 112, 68, 68, 115, 68, - 68, 68, 118, 119, 120, 68, 121, 122, - 123, 68, 68, 68, 68, 68, 125, 126, - 127, 131, 68, 68, 68, 68, 109, 68, - 133, 68, 70, 68, 68, 68, 68, 68, - 68, 68, 108, 109, 110, 111, 112, 68, - 68, 68, 68, 68, 68, 118, 119, 120, - 68, 121, 122, 123, 68, 68, 68, 68, - 68, 125, 126, 127, 131, 68, 68, 68, - 68, 109, 68, 133, 68, 70, 68, 68, - 68, 68, 68, 68, 68, 108, 109, 110, - 111, 112, 113, 114, 115, 68, 68, 68, - 118, 119, 120, 68, 121, 122, 123, 68, - 68, 68, 68, 68, 125, 126, 127, 131, - 68, 68, 68, 68, 109, 68, 106, 107, - 68, 70, 68, 68, 68, 68, 68, 68, - 68, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 68, 117, 118, 119, 120, 68, - 121, 122, 123, 68, 68, 68, 68, 124, - 125, 126, 127, 128, 68, 68, 68, 68, - 129, 68, 68, 130, 68, 106, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 100, 99, 106, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 97, 95, 106, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 70, 68, 68, 68, 68, 68, 68, 68, - 68, 109, 110, 111, 112, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 121, - 122, 123, 68, 68, 68, 68, 68, 125, - 126, 127, 131, 68, 100, 99, 8, 9, - 134, 11, 134, 134, 134, 134, 134, 134, - 134, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 8, 22, 23, 24, 25, 134, - 26, 27, 28, 134, 134, 134, 134, 32, - 33, 34, 35, 32, 134, 134, 134, 134, - 37, 134, 134, 35, 134, 8, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 11, 134, 134, 134, 134, 134, - 134, 134, 134, 14, 15, 16, 17, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 26, 27, 28, 134, 134, 134, 134, - 134, 33, 34, 35, 135, 134, 134, 134, - 134, 14, 134, 11, 134, 134, 134, 134, - 134, 134, 134, 134, 14, 15, 16, 17, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 26, 27, 28, 134, 134, 134, - 134, 134, 33, 34, 35, 135, 134, 11, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 15, 16, 17, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 33, 34, - 35, 134, 11, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 16, 17, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 33, 34, 35, 134, 11, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 17, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 33, 34, 35, 134, - 11, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 33, - 34, 134, 11, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 34, 134, 11, 134, 11, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 15, 16, 17, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 26, 27, 28, - 134, 134, 134, 134, 134, 33, 34, 35, - 135, 134, 11, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 15, 16, 17, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 27, 28, 134, 134, 134, 134, - 134, 33, 34, 35, 135, 134, 11, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 15, 16, 17, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 28, - 134, 134, 134, 134, 134, 33, 34, 35, - 135, 134, 136, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 11, - 134, 11, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 15, 16, 17, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 33, 34, 35, 135, 134, 11, 134, 134, - 134, 134, 134, 134, 134, 13, 14, 15, - 16, 17, 134, 134, 134, 134, 134, 134, - 23, 24, 25, 134, 26, 27, 28, 134, - 134, 134, 134, 134, 33, 34, 35, 135, - 134, 134, 134, 134, 14, 134, 11, 134, - 134, 134, 134, 134, 134, 134, 134, 14, - 15, 16, 17, 134, 134, 134, 134, 134, - 134, 23, 24, 25, 134, 26, 27, 28, - 134, 134, 134, 134, 134, 33, 34, 35, - 135, 134, 134, 134, 134, 14, 134, 11, - 134, 134, 134, 134, 134, 134, 134, 134, - 14, 15, 16, 17, 134, 134, 134, 134, - 134, 134, 134, 24, 25, 134, 26, 27, - 28, 134, 134, 134, 134, 134, 33, 34, - 35, 135, 134, 134, 134, 134, 14, 134, - 11, 134, 134, 134, 134, 134, 134, 134, - 134, 14, 15, 16, 17, 134, 134, 134, - 134, 134, 134, 134, 134, 25, 134, 26, - 27, 28, 134, 134, 134, 134, 134, 33, - 34, 35, 135, 134, 134, 134, 134, 14, - 134, 137, 134, 11, 134, 134, 134, 134, - 134, 134, 134, 13, 14, 15, 16, 17, - 134, 19, 20, 134, 134, 134, 23, 24, - 25, 134, 26, 27, 28, 134, 134, 134, - 134, 134, 33, 34, 35, 135, 134, 134, - 134, 134, 14, 134, 11, 134, 134, 134, - 134, 134, 134, 134, 134, 14, 15, 16, - 17, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 26, 27, 28, 134, 134, - 134, 134, 134, 33, 34, 35, 135, 134, - 134, 134, 134, 14, 134, 137, 134, 11, - 134, 134, 134, 134, 134, 134, 134, 13, - 14, 15, 16, 17, 134, 134, 20, 134, - 134, 134, 23, 24, 25, 134, 26, 27, - 28, 134, 134, 134, 134, 134, 33, 34, - 35, 135, 134, 134, 134, 134, 14, 134, - 137, 134, 11, 134, 134, 134, 134, 134, - 134, 134, 13, 14, 15, 16, 17, 134, - 134, 134, 134, 134, 134, 23, 24, 25, - 134, 26, 27, 28, 134, 134, 134, 134, - 134, 33, 34, 35, 135, 134, 134, 134, - 134, 14, 134, 137, 134, 11, 134, 134, - 134, 134, 134, 134, 134, 13, 14, 15, - 16, 17, 18, 19, 20, 134, 134, 134, - 23, 24, 25, 134, 26, 27, 28, 134, - 134, 134, 134, 134, 33, 34, 35, 135, - 134, 134, 134, 134, 14, 134, 8, 9, - 134, 11, 134, 134, 134, 134, 134, 134, - 134, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 134, 22, 23, 24, 25, 134, - 26, 27, 28, 134, 134, 134, 134, 32, - 33, 34, 35, 32, 134, 134, 134, 134, - 37, 134, 134, 35, 134, 8, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 11, 134, 8, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 11, 134, 134, 134, 134, 134, 134, - 134, 134, 14, 15, 16, 17, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 26, 27, 28, 134, 134, 134, 134, 134, - 33, 34, 35, 135, 134, 138, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 11, - 134, 10, 11, 134, 4, 134, 134, 134, - 4, 134, 134, 134, 134, 134, 8, 9, - 10, 11, 134, 134, 134, 134, 134, 134, - 134, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 8, 22, 23, 24, 25, 134, - 26, 27, 28, 134, 29, 30, 134, 32, - 33, 34, 35, 32, 134, 134, 134, 134, - 37, 134, 134, 35, 134, 11, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 29, 30, 134, 11, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 30, - 134, 4, 139, 139, 139, 4, 139, 141, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 142, 140, 143, 140, 143, - 144, 140, 141, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 1, 142, 142, - 140, 141, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 142, 140, 143, - 140, 141, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 142, 140, 143, - 140, 143, 140, 39, 40, 38, 41, 38, - 38, 38, 38, 38, 38, 38, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 39, - 51, 52, 53, 54, 38, 55, 56, 57, - 38, 58, 59, 38, 60, 61, 62, 63, - 60, 1, 38, 2, 38, 64, 38, 38, - 63, 38, 0 + 5, 37, 5, 5, 38, 5, 40, 41, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 40, 52, 53, 54, 55, 39, + 56, 57, 58, 39, 59, 60, 39, 61, + 62, 63, 64, 61, 39, 39, 39, 39, + 65, 39, 39, 64, 39, 40, 41, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 40, 52, 53, 54, 55, 39, 56, + 57, 58, 39, 39, 39, 39, 61, 62, + 63, 64, 61, 39, 39, 39, 39, 65, + 39, 39, 64, 39, 40, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 44, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 56, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 39, 39, 39, + 44, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 39, 44, 45, 46, 47, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 56, 57, 58, 39, 39, 39, 39, + 39, 62, 63, 64, 66, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 45, 46, 47, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 62, 63, 64, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 62, 63, 64, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 47, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 62, 63, 64, 39, 42, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 62, 63, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 63, 39, 42, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 56, 57, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 67, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 42, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 45, 46, 47, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 62, + 63, 64, 66, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 43, 44, 45, 46, + 47, 39, 39, 39, 39, 39, 39, 53, + 54, 55, 39, 56, 57, 58, 39, 39, + 39, 39, 39, 62, 63, 64, 66, 39, + 39, 39, 39, 44, 39, 42, 39, 39, + 39, 39, 39, 39, 39, 39, 44, 45, + 46, 47, 39, 39, 39, 39, 39, 39, + 53, 54, 55, 39, 56, 57, 58, 39, + 39, 39, 39, 39, 62, 63, 64, 66, + 39, 39, 39, 39, 44, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 39, 44, + 45, 46, 47, 39, 39, 39, 39, 39, + 39, 39, 54, 55, 39, 56, 57, 58, + 39, 39, 39, 39, 39, 62, 63, 64, + 66, 39, 39, 39, 39, 44, 39, 42, + 39, 39, 39, 39, 39, 39, 39, 39, + 44, 45, 46, 47, 39, 39, 39, 39, + 39, 39, 39, 39, 55, 39, 56, 57, + 58, 39, 39, 39, 39, 39, 62, 63, + 64, 66, 39, 39, 39, 39, 44, 39, + 68, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 43, 44, 45, 46, 47, 39, + 49, 50, 39, 39, 39, 53, 54, 55, + 39, 56, 57, 58, 39, 39, 39, 39, + 39, 62, 63, 64, 66, 39, 39, 39, + 39, 44, 39, 42, 39, 39, 39, 39, + 39, 39, 39, 39, 44, 45, 46, 47, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 56, 57, 58, 39, 39, 39, + 39, 39, 62, 63, 64, 66, 39, 39, + 39, 39, 44, 39, 68, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 43, 44, + 45, 46, 47, 39, 39, 50, 39, 39, + 39, 53, 54, 55, 39, 56, 57, 58, + 39, 39, 39, 39, 39, 62, 63, 64, + 66, 39, 39, 39, 39, 44, 39, 68, + 39, 42, 39, 39, 39, 39, 39, 39, + 39, 43, 44, 45, 46, 47, 39, 39, + 39, 39, 39, 39, 53, 54, 55, 39, + 56, 57, 58, 39, 39, 39, 39, 39, + 62, 63, 64, 66, 39, 39, 39, 39, + 44, 39, 68, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 43, 44, 45, 46, + 47, 48, 49, 50, 39, 39, 39, 53, + 54, 55, 39, 56, 57, 58, 39, 39, + 39, 39, 39, 62, 63, 64, 66, 39, + 39, 39, 39, 44, 39, 40, 41, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 43, 44, 45, 46, 47, 48, 49, 50, + 51, 39, 52, 53, 54, 55, 39, 56, + 57, 58, 39, 39, 39, 39, 61, 62, + 63, 64, 61, 39, 39, 39, 39, 65, + 39, 39, 64, 39, 40, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 42, 39, 40, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 42, 39, 39, 39, 39, 39, 39, 39, + 39, 44, 45, 46, 47, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 56, + 57, 58, 39, 39, 39, 39, 39, 62, + 63, 64, 66, 39, 42, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 59, + 60, 39, 42, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 60, 39, + 4, 70, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 4, 81, 82, 83, + 84, 69, 85, 86, 87, 69, 69, 69, + 69, 88, 89, 90, 91, 92, 69, 69, + 69, 69, 93, 69, 69, 94, 69, 4, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 73, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 85, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 69, 69, 69, 73, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 69, 73, 74, + 75, 76, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 85, 86, 87, 69, + 69, 69, 69, 69, 89, 90, 91, 95, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 74, 75, 76, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 89, 90, 91, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 89, 90, 91, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 76, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 89, 90, + 91, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 89, 90, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 90, 69, 71, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 85, + 86, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 97, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 98, 96, 71, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 74, 75, 76, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 89, 90, 91, 95, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 72, + 73, 74, 75, 76, 69, 69, 69, 69, + 69, 69, 82, 83, 84, 69, 85, 86, + 87, 69, 69, 69, 69, 69, 89, 90, + 91, 95, 69, 69, 69, 69, 73, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 73, 74, 75, 76, 69, 69, 69, + 69, 69, 69, 82, 83, 84, 69, 85, + 86, 87, 69, 69, 69, 69, 69, 89, + 90, 91, 95, 69, 69, 69, 69, 73, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 73, 74, 75, 76, 69, 69, + 69, 69, 69, 69, 69, 83, 84, 69, + 85, 86, 87, 69, 69, 69, 69, 69, + 89, 90, 91, 95, 69, 69, 69, 69, + 73, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 73, 74, 75, 76, 69, + 69, 69, 69, 69, 69, 69, 69, 84, + 69, 85, 86, 87, 69, 69, 69, 69, + 69, 89, 90, 91, 95, 69, 69, 69, + 69, 73, 69, 99, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 72, 73, 74, + 75, 76, 69, 78, 79, 69, 69, 69, + 82, 83, 84, 69, 85, 86, 87, 69, + 69, 69, 69, 69, 89, 90, 91, 95, + 69, 69, 69, 69, 73, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 73, + 74, 75, 76, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 85, 86, 87, + 69, 69, 69, 69, 69, 89, 90, 91, + 95, 69, 69, 69, 69, 73, 69, 99, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 72, 73, 74, 75, 76, 69, 69, + 79, 69, 69, 69, 82, 83, 84, 69, + 85, 86, 87, 69, 69, 69, 69, 69, + 89, 90, 91, 95, 69, 69, 69, 69, + 73, 69, 99, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 72, 73, 74, 75, + 76, 69, 69, 69, 69, 69, 69, 82, + 83, 84, 69, 85, 86, 87, 69, 69, + 69, 69, 69, 89, 90, 91, 95, 69, + 69, 69, 69, 73, 69, 99, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 72, + 73, 74, 75, 76, 77, 78, 79, 69, + 69, 69, 82, 83, 84, 69, 85, 86, + 87, 69, 69, 69, 69, 69, 89, 90, + 91, 95, 69, 69, 69, 69, 73, 69, + 4, 70, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 69, 81, 82, 83, + 84, 69, 85, 86, 87, 69, 69, 69, + 69, 88, 89, 90, 91, 92, 69, 69, + 69, 69, 93, 69, 69, 94, 69, 4, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 101, 100, 4, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 98, 96, 4, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 73, 74, 75, 76, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 85, 86, 87, 69, 69, 69, 69, + 69, 89, 90, 91, 95, 69, 101, 100, + 103, 104, 102, 6, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 106, 105, 107, + 108, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 107, 118, 119, 120, 121, + 69, 122, 123, 124, 69, 59, 60, 69, + 125, 126, 127, 128, 129, 69, 69, 69, + 69, 130, 69, 69, 131, 69, 107, 108, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 107, 118, 119, 120, 121, 69, + 122, 123, 124, 69, 69, 69, 69, 125, + 126, 127, 128, 129, 69, 69, 69, 69, + 130, 69, 69, 131, 69, 107, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 110, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 122, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 69, 69, + 69, 110, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 69, 110, 111, 112, 113, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 122, 123, 124, 69, 69, 69, + 69, 69, 126, 127, 128, 132, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 111, 112, 113, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 126, 127, + 128, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 126, 127, 128, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 113, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 126, 127, 128, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 126, + 127, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 127, 69, 71, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 122, 123, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 133, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 98, + 96, 71, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 111, 112, 113, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 126, 127, 128, 132, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 109, 110, 111, + 112, 113, 69, 69, 69, 69, 69, 69, + 119, 120, 121, 69, 122, 123, 124, 69, + 69, 69, 69, 69, 126, 127, 128, 132, + 69, 69, 69, 69, 110, 69, 71, 69, + 69, 69, 69, 69, 69, 69, 69, 110, + 111, 112, 113, 69, 69, 69, 69, 69, + 69, 119, 120, 121, 69, 122, 123, 124, + 69, 69, 69, 69, 69, 126, 127, 128, + 132, 69, 69, 69, 69, 110, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 69, + 110, 111, 112, 113, 69, 69, 69, 69, + 69, 69, 69, 120, 121, 69, 122, 123, + 124, 69, 69, 69, 69, 69, 126, 127, + 128, 132, 69, 69, 69, 69, 110, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 110, 111, 112, 113, 69, 69, 69, + 69, 69, 69, 69, 69, 121, 69, 122, + 123, 124, 69, 69, 69, 69, 69, 126, + 127, 128, 132, 69, 69, 69, 69, 110, + 69, 134, 69, 71, 69, 69, 69, 69, + 69, 69, 69, 109, 110, 111, 112, 113, + 69, 115, 116, 69, 69, 69, 119, 120, + 121, 69, 122, 123, 124, 69, 69, 69, + 69, 69, 126, 127, 128, 132, 69, 69, + 69, 69, 110, 69, 71, 69, 69, 69, + 69, 69, 69, 69, 69, 110, 111, 112, + 113, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 122, 123, 124, 69, 69, + 69, 69, 69, 126, 127, 128, 132, 69, + 69, 69, 69, 110, 69, 134, 69, 71, + 69, 69, 69, 69, 69, 69, 69, 109, + 110, 111, 112, 113, 69, 69, 116, 69, + 69, 69, 119, 120, 121, 69, 122, 123, + 124, 69, 69, 69, 69, 69, 126, 127, + 128, 132, 69, 69, 69, 69, 110, 69, + 134, 69, 71, 69, 69, 69, 69, 69, + 69, 69, 109, 110, 111, 112, 113, 69, + 69, 69, 69, 69, 69, 119, 120, 121, + 69, 122, 123, 124, 69, 69, 69, 69, + 69, 126, 127, 128, 132, 69, 69, 69, + 69, 110, 69, 134, 69, 71, 69, 69, + 69, 69, 69, 69, 69, 109, 110, 111, + 112, 113, 114, 115, 116, 69, 69, 69, + 119, 120, 121, 69, 122, 123, 124, 69, + 69, 69, 69, 69, 126, 127, 128, 132, + 69, 69, 69, 69, 110, 69, 107, 108, + 69, 71, 69, 69, 69, 69, 69, 69, + 69, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 69, 118, 119, 120, 121, 69, + 122, 123, 124, 69, 69, 69, 69, 125, + 126, 127, 128, 129, 69, 69, 69, 69, + 130, 69, 69, 131, 69, 107, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 101, 100, 107, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 98, 96, 107, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 71, 69, 69, 69, 69, 69, 69, 69, + 69, 110, 111, 112, 113, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 122, + 123, 124, 69, 69, 69, 69, 69, 126, + 127, 128, 132, 69, 101, 100, 8, 9, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 8, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 135, 135, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 8, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 14, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 26, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 135, 135, + 135, 14, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 135, 14, 15, 16, 17, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 26, 27, 28, 135, 135, 135, + 135, 135, 33, 34, 38, 136, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 15, 16, 17, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 33, 34, + 38, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 33, 34, 38, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 17, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 33, 34, 38, 135, + 11, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 33, + 34, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 34, 135, 11, 137, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 26, 27, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 138, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 11, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 15, 16, 17, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 33, 34, 38, 136, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 13, 14, 15, + 16, 17, 135, 135, 135, 135, 135, 135, + 23, 24, 25, 135, 26, 27, 28, 135, + 135, 135, 135, 135, 33, 34, 38, 136, + 135, 135, 135, 135, 14, 135, 11, 135, + 135, 135, 135, 135, 135, 135, 135, 14, + 15, 16, 17, 135, 135, 135, 135, 135, + 135, 23, 24, 25, 135, 26, 27, 28, + 135, 135, 135, 135, 135, 33, 34, 38, + 136, 135, 135, 135, 135, 14, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 135, + 14, 15, 16, 17, 135, 135, 135, 135, + 135, 135, 135, 24, 25, 135, 26, 27, + 28, 135, 135, 135, 135, 135, 33, 34, + 38, 136, 135, 135, 135, 135, 14, 135, + 11, 135, 135, 135, 135, 135, 135, 135, + 135, 14, 15, 16, 17, 135, 135, 135, + 135, 135, 135, 135, 135, 25, 135, 26, + 27, 28, 135, 135, 135, 135, 135, 33, + 34, 38, 136, 135, 135, 135, 135, 14, + 135, 139, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 13, 14, 15, 16, 17, + 135, 19, 20, 135, 135, 135, 23, 24, + 25, 135, 26, 27, 28, 135, 135, 135, + 135, 135, 33, 34, 38, 136, 135, 135, + 135, 135, 14, 135, 11, 135, 135, 135, + 135, 135, 135, 135, 135, 14, 15, 16, + 17, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 26, 27, 28, 135, 135, + 135, 135, 135, 33, 34, 38, 136, 135, + 135, 135, 135, 14, 135, 139, 135, 11, + 135, 135, 135, 135, 135, 135, 135, 13, + 14, 15, 16, 17, 135, 135, 20, 135, + 135, 135, 23, 24, 25, 135, 26, 27, + 28, 135, 135, 135, 135, 135, 33, 34, + 38, 136, 135, 135, 135, 135, 14, 135, + 139, 135, 11, 135, 135, 135, 135, 135, + 135, 135, 13, 14, 15, 16, 17, 135, + 135, 135, 135, 135, 135, 23, 24, 25, + 135, 26, 27, 28, 135, 135, 135, 135, + 135, 33, 34, 38, 136, 135, 135, 135, + 135, 14, 135, 139, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 13, 14, 15, + 16, 17, 18, 19, 20, 135, 135, 135, + 23, 24, 25, 135, 26, 27, 28, 135, + 135, 135, 135, 135, 33, 34, 38, 136, + 135, 135, 135, 135, 14, 135, 8, 9, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 135, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 135, 135, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 8, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 11, 135, 8, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 11, 135, 135, 135, 135, 135, 135, + 135, 135, 14, 15, 16, 17, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 26, 27, 28, 135, 135, 135, 135, 135, + 33, 34, 38, 136, 135, 140, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 11, + 135, 10, 11, 135, 4, 135, 135, 135, + 4, 135, 135, 135, 135, 135, 8, 9, + 10, 11, 135, 135, 135, 135, 135, 135, + 135, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 8, 22, 23, 24, 25, 135, + 26, 27, 28, 135, 29, 30, 135, 32, + 33, 34, 38, 32, 135, 135, 135, 135, + 37, 135, 135, 38, 135, 11, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 29, 30, 135, 11, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 30, + 135, 4, 141, 141, 141, 4, 141, 143, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 144, 142, 145, 142, 145, + 146, 142, 143, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 1, 144, 144, + 142, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 144, 142, 145, + 142, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 144, 142, 145, + 142, 145, 142, 40, 41, 39, 42, 39, + 39, 39, 39, 39, 39, 39, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 40, + 52, 53, 54, 55, 39, 56, 57, 58, + 39, 59, 60, 39, 61, 62, 63, 64, + 61, 1, 39, 2, 39, 65, 39, 39, + 64, 39, 0 }; static const char _use_syllable_machine_trans_targs[] = { @@ -723,21 +723,21 @@ static const char _use_syllable_machine_trans_targs[] = { 90, 91, 116, 1, 118, 104, 92, 93, 94, 95, 108, 110, 111, 112, 113, 105, 106, 107, 99, 100, 101, 119, 120, 121, - 114, 96, 97, 98, 126, 115, 1, 3, - 4, 1, 17, 5, 6, 7, 8, 21, - 23, 24, 25, 26, 18, 19, 20, 12, - 13, 14, 29, 30, 27, 9, 10, 11, - 28, 15, 16, 22, 1, 32, 1, 45, - 33, 34, 35, 36, 49, 51, 52, 53, - 54, 46, 47, 48, 40, 41, 42, 55, - 37, 38, 39, 56, 57, 58, 43, 1, - 44, 1, 50, 1, 1, 1, 60, 1, - 1, 1, 62, 63, 76, 64, 65, 66, - 67, 80, 82, 83, 84, 85, 77, 78, - 79, 71, 72, 73, 86, 68, 69, 70, - 87, 88, 89, 74, 75, 81, 1, 102, - 103, 109, 117, 1, 1, 1, 123, 124, - 125 + 114, 96, 97, 98, 126, 115, 98, 1, + 3, 4, 1, 17, 5, 6, 7, 8, + 21, 23, 24, 25, 26, 18, 19, 20, + 12, 13, 14, 29, 30, 27, 9, 10, + 11, 28, 15, 16, 22, 1, 32, 1, + 45, 33, 34, 35, 36, 49, 51, 52, + 53, 54, 46, 47, 48, 40, 41, 42, + 55, 37, 38, 39, 56, 57, 58, 43, + 1, 44, 1, 50, 1, 1, 1, 60, + 1, 1, 1, 62, 63, 76, 64, 65, + 66, 67, 80, 82, 83, 84, 85, 77, + 78, 79, 71, 72, 73, 86, 68, 69, + 70, 87, 88, 89, 74, 75, 81, 1, + 102, 1, 103, 109, 117, 1, 1, 1, + 123, 124, 125 }; static const char _use_syllable_machine_trans_actions[] = { @@ -745,21 +745,21 @@ static const char _use_syllable_machine_trans_actions[] = { 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 7, 0, - 0, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 7, 0, 8, 9, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 10, 0, + 0, 0, 0, 0, 0, 11, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 11, - 0, 12, 0, 13, 14, 15, 0, 16, - 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 14, 0, 15, 16, 17, 0, + 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 19, 0, - 0, 0, 0, 20, 21, 22, 0, 0, - 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 21, + 0, 22, 0, 0, 0, 23, 24, 25, + 0, 0, 0 }; static const char _use_syllable_machine_to_state_actions[] = { @@ -801,22 +801,22 @@ static const char _use_syllable_machine_from_state_actions[] = { }; static const short _use_syllable_machine_eof_trans[] = { - 1, 0, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 96, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 100, - 96, 69, 100, 102, 105, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 96, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 100, 96, - 69, 100, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, - 135, 140, 141, 141, 141, 141, 39 + 1, 0, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 97, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 101, + 97, 70, 101, 103, 106, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 97, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 101, 97, + 70, 101, 136, 136, 136, 136, 136, 136, + 136, 136, 138, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 142, 143, 143, 143, 143, 40 }; static const int use_syllable_machine_start = 1; @@ -830,7 +830,7 @@ static const int use_syllable_machine_en_main = 1; -#line 185 "hb-ot-shaper-use-machine.rl" +#line 186 "hb-ot-shaper-use-machine.rl" #define found_syllable(syllable_type) \ @@ -937,7 +937,7 @@ find_syllables_use (hb_buffer_t *buffer) act = 0; } -#line 285 "hb-ot-shaper-use-machine.rl" +#line 286 "hb-ot-shaper-use-machine.rl" unsigned int syllable_serial = 1; @@ -974,87 +974,111 @@ _eof_trans: goto _again; switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 6: + case 7: #line 1 "NONE" {te = p+1;} break; - case 14: + case 16: #line 173 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_virama_terminated_cluster); }} break; - case 12: + case 14: #line 174 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 10: + case 12: #line 175 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_standard_cluster); }} break; - case 18: + case 20: #line 176 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 16: + case 18: #line 177 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_numeral_cluster); }} break; - case 8: + case 10: #line 178 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_symbol_cluster); }} break; - case 22: + case 25: #line 179 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_hieroglyph_cluster); }} break; case 5: -#line 180 "hb-ot-shaper-use-machine.rl" +#line 181 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; case 4: -#line 181 "hb-ot-shaper-use-machine.rl" +#line 182 "hb-ot-shaper-use-machine.rl" {te = p+1;{ found_syllable (use_non_cluster); }} break; - case 13: + case 15: #line 173 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} break; - case 11: + case 13: #line 174 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 9: + case 11: #line 175 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_standard_cluster); }} break; - case 17: + case 19: #line 176 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 15: + case 17: #line 177 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_numeral_cluster); }} break; - case 7: + case 9: #line 178 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_symbol_cluster); }} break; - case 21: + case 24: #line 179 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} break; - case 19: -#line 180 "hb-ot-shaper-use-machine.rl" + case 21: +#line 181 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} break; - case 20: -#line 181 "hb-ot-shaper-use-machine.rl" + case 23: +#line 182 "hb-ot-shaper-use-machine.rl" {te = p;p--;{ found_syllable (use_non_cluster); }} break; case 1: #line 178 "hb-ot-shaper-use-machine.rl" {{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }} break; -#line 1058 "hb-ot-shaper-use-machine.hh" + case 22: +#line 1 "NONE" + { switch( act ) { + case 8: + {{p = ((te))-1;} found_syllable (use_non_cluster); } + break; + case 9: + {{p = ((te))-1;} found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } + break; + } + } + break; + case 6: +#line 1 "NONE" + {te = p+1;} +#line 180 "hb-ot-shaper-use-machine.rl" + {act = 8;} + break; + case 8: +#line 1 "NONE" + {te = p+1;} +#line 181 "hb-ot-shaper-use-machine.rl" + {act = 9;} + break; +#line 1082 "hb-ot-shaper-use-machine.hh" } _again: @@ -1063,7 +1087,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1067 "hb-ot-shaper-use-machine.hh" +#line 1091 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) @@ -1079,7 +1103,7 @@ _again: } -#line 290 "hb-ot-shaper-use-machine.rl" +#line 291 "hb-ot-shaper-use-machine.rl" } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.rl b/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.rl index f5a2091a3..4460e35e6 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.rl +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-machine.rl @@ -177,6 +177,7 @@ main := |* numeral_cluster ZWNJ? => { found_syllable (use_numeral_cluster); }; symbol_cluster ZWNJ? => { found_syllable (use_symbol_cluster); }; hieroglyph_cluster ZWNJ? => { found_syllable (use_hieroglyph_cluster); }; + FMPst => { found_syllable (use_non_cluster); }; broken_cluster ZWNJ? => { found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }; other => { found_syllable (use_non_cluster); }; *|; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-table.hh index 9cd4469c6..dad4fc8ae 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-use-table.hh @@ -2,22 +2,22 @@ /* * The following table is generated by running: * - * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt + * gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt * * on files with these headers: * - * # IndicSyllabicCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # IndicPositionalCategory-16.0.0.txt - * # Date: 2024-04-30, 21:48:21 GMT - * # ArabicShaping-16.0.0.txt - * # Date: 2024-07-30 - * # DerivedCoreProperties-16.0.0.txt - * # Date: 2024-05-31, 18:09:32 GMT - * # Blocks-16.0.0.txt - * # Date: 2024-02-02 - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # IndicSyllabicCategory-17.0.0.txt + * # Date: 2025-08-01, 04:02:23 GMT + * # IndicPositionalCategory-17.0.0.txt + * # Date: 2025-07-29, 13:35:52 GMT + * # ArabicShaping-17.0.0.txt + * # Date: 2025-08-14 + * # DerivedCoreProperties-17.0.0.txt + * # Date: 2025-07-30, 23:55:08 GMT + * # Blocks-17.0.0.txt + * # Date: 2025-08-01 + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -101,575 +101,574 @@ #ifndef HB_OPTIMIZE_SIZE -static const uint8_t -hb_use_u8[3345] = +#include + +static const uint8_t hb_use_u8[3343]= { - 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 15, 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 4, 2, 2, - 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 2, 2, 17, - 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2, - 2, 34, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 2, 2, 2, - 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 38, 2, 39, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 40, 41, 42, 43, 44, 45, 2, 46, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 48, 2, - 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, - 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 56, 2, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 2, 70, 71, 72, 73, - 2, 74, 2, 75, 76, 77, 78, 2, 2, 79, 80, 81, 82, 2, 83, 84, - 2, 85, 85, 85, 85, 85, 85, 85, 85, 86, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 87, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 89, 90, 2, 2, 2, 91, 2, 2, 2, 92, - 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 94, 94, 94, 95, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, - 2, 2, 2, 98, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 33, 3, 0, 0, 0, 4, 0, 80, 118, 128, 9, 10, 11, 192, 208, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 7, 0, 0, + 8, 9, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 20, + 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 36, 0, 0, 0, + 0, 37, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 44, 45, 46, 47, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, + 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 55, 56, 0, 57, 0, 0, 58, 59, 0, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 0, 73, 74, 75, 76, + 0, 77, 0, 78, 79, 80, 81, 82, 0, 83, 84, 85, 86, 0, 87, 88, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 89, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 90, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 93, 0, 0, 0, 94, 0, 0, 0, 95, + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 97, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, + 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 101, 0, 0, 102, 0, 0, 0, 103, 0, 104, 0, 0, 0, + 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 106, 107, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 99, 2, 2, 100, 2, 2, 2, 101, 2, 102, 2, 2, 2, - 2, 2, 2, 103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 104, 104, 105, 106, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, - 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 11, - 11, 11, 11, 0, 0, 0, 9, 12, 0, 2, 2, 2, 2, 13, 14, 0, - 0, 11, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 17, - 18, 19, 20, 21, 22, 16, 23, 24, 25, 12, 26, 27, 20, 2, 2, 2, - 2, 2, 20, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, - 2, 28, 29, 30, 2, 2, 2, 9, 30, 9, 30, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 9, 0, 2, 2, 0, 17, - 18, 19, 20, 31, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 2, - 30, 2, 0, 0, 0, 0, 0, 9, 36, 12, 15, 30, 2, 2, 9, 0, - 30, 9, 2, 30, 9, 2, 0, 37, 18, 19, 31, 0, 27, 38, 27, 39, - 0, 40, 0, 0, 0, 30, 2, 9, 9, 0, 0, 0, 2, 2, 2, 2, - 2, 41, 42, 43, 0, 0, 0, 0, 0, 12, 15, 30, 2, 2, 2, 2, - 30, 2, 30, 2, 2, 2, 2, 2, 2, 9, 2, 30, 2, 2, 0, 17, - 18, 19, 20, 21, 27, 22, 35, 24, 0, 0, 0, 0, 0, 30, 41, 41, - 44, 12, 29, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 0, 17, - 45, 0, 0, 27, 22, 0, 0, 2, 30, 30, 0, 0, 0, 0, 0, 0, - 0, 0, 46, 30, 2, 2, 9, 0, 2, 9, 2, 2, 0, 30, 9, 9, - 2, 0, 30, 9, 0, 2, 9, 0, 2, 2, 2, 2, 2, 2, 0, 0, - 23, 16, 47, 0, 48, 33, 48, 34, 0, 0, 0, 0, 35, 0, 0, 0, - 0, 15, 29, 49, 2, 2, 2, 9, 2, 9, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 17, 22, 16, 23, 47, 22, 38, 22, 39, - 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, - 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, - 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, - 2, 2, 2, 2, 2, 2, 52, 53, 23, 19, 20, 31, 48, 33, 48, 34, - 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, - 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, - 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, - 25, 0, 23, 0, 0, 0, 0, 0, 0, 2, 0, 2, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 2, 56, 56, 57, 0, 0, - 18, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, - 0, 58, 21, 59, 22, 22, 20, 20, 46, 21, 11, 31, 11, 2, 2, 60, - 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 63, 0, 0, 0, 0, 64, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 65, 45, 59, 66, 22, 22, 67, 68, 69, 70, - 71, 2, 2, 2, 2, 2, 1, 0, 5, 2, 2, 2, 23, 20, 2, 2, - 72, 71, 73, 74, 65, 73, 29, 29, 2, 52, 22, 53, 2, 2, 2, 2, - 2, 2, 75, 76, 77, 29, 29, 78, 79, 2, 2, 2, 2, 2, 29, 45, - 0, 2, 59, 80, 0, 0, 0, 0, 30, 2, 59, 47, 0, 0, 0, 0, - 0, 2, 59, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 9, - 2, 9, 59, 0, 0, 0, 0, 0, 0, 2, 2, 81, 45, 22, 59, 20, - 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, - 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, - 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, - 0, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 9, 22, 80, 45, 22, 94, 61, 0, 0, 95, 96, 95, 95, 97, 98, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 0, 0, 2, 2, 2, 52, 99, 45, 0, - 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, - 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, - 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, - 0, 0, 0, 0, 0, 0, 109, 110, 110, 110, 110, 0, 0, 0, 0, 0, - 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 111, 61, - 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 112, 0, 0, 0, 0, 0, - 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, - 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, - 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 6, 119, - 120, 42, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, - 121, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 122, 0, 0, 0, 0, - 0, 0, 7, 122, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 123, 123, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, - 124, 0, 123, 123, 0, 0, 0, 0, 0, 2, 53, 2, 108, 2, 10, 2, - 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, - 0, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 23, 23, 23, 23, - 23, 23, 23, 126, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 2, 0, 0, 0, 0, 0, 52, 2, 2, 2, 22, 22, 127, 116, - 0, 2, 2, 2, 128, 20, 59, 20, 113, 102, 129, 0, 0, 0, 0, 0, - 0, 11, 130, 2, 2, 2, 2, 2, 2, 2, 131, 23, 22, 20, 48, 132, - 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, - 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, - 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15, - 2, 53, 22, 140, 52, 53, 2, 2, 105, 10, 9, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0, - 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, - 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, - 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 145, - 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, - 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, - 0, 2, 2, 2, 0, 27, 22, 22, 30, 2, 2, 2, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, - 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, - 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, - 0, 149, 150, 151, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, - 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, - 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, - 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 128, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2, - 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, - 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 158, 0, 0, 56, 159, 31, - 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, - 19, 22, 22, 161, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0, - 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, - 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, - 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 30, 0, 9, 2, 2, 2, 30, 45, 59, 20, - 20, 31, 33, 32, 32, 25, 163, 29, 164, 165, 37, 0, 0, 0, 0, 0, - 0, 12, 26, 0, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, - 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 166, 167, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, - 160, 11, 168, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 65, 25, 20, 20, 0, 48, 48, 11, 169, 37, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, - 169, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 170, - 25, 20, 22, 22, 168, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, - 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 169, 37, 0, - 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, - 2, 23, 23, 18, 32, 33, 12, 171, 165, 172, 173, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, - 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, - 2, 2, 174, 175, 11, 15, 176, 61, 177, 0, 0, 1, 147, 0, 0, 0, - 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 178, 178, - 178, 178, 178, 178, 15, 179, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, - 169, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, - 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, - 27, 11, 159, 180, 181, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, - 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, - 0, 2, 182, 66, 47, 0, 0, 0, 0, 11, 183, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 156, 0, 0, 184, 184, 184, 184, 184, 184, 184, - 184, 185, 185, 185, 186, 187, 185, 184, 184, 188, 184, 184, 189, 190, 190, 190, - 190, 190, 190, 190, 0, 0, 0, 0, 0, 184, 184, 184, 184, 184, 191, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, 22, 22, 192, 193, - 194, 11, 11, 11, 46, 0, 0, 0, 0, 29, 74, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 65, 47, 0, 2, 2, 2, 2, 2, 9, 0, - 58, 195, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 30, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, - 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, - 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, - 20, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, - SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, - VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, - VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, - VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, - VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, - MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS, - VMPst, B, VAbv, VAbv, B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, - VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv, - VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, - VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, - FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, - CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, - VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, - VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv, - CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, - SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, - CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, - FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, - IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, - IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, - O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, - VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, - IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, G, G, J, J, J, SB, SE, - J, HR, G, G, HM, HM, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, - VBlw, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 2, 2, 2, 2, 5, 2, 2, 2, 2, 6, 0, 2, 2, 2, 2, + 2, 5, 8, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, + 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, + 0, 2, 2, 2, 2, 5, 0, 0, 0, 2, 2, 2, 2, 2, 5, 0, + 0, 2, 8, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 74, 75, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 2, 2, 2, 2, 2, 2, 2, 17, 6, 13, 29, 33, 29, 45, + 0, 15, 11, 27, 7, 38, 7, 68, 0, 2, 2, 2, 2, 8, 2, 2, + 2, 10, 10, 10, 10, 80, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, + 5, 2, 2, 5, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 5, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, + 0, 9, 41, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 23, 6, 6, 6, 6, 6, 6, 6, + 6, 0, 0, 0, 0, 0, 0, 48, 0, 44, 0, 0, 0, 0, 0, 49, + 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 103, 2, 2, 2, 2, 2, 36, 9, + 9, 9, 9, 0, 0, 0, 5, 31, 0, 2, 2, 2, 2, 50, 51, 0, + 0, 9, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 32, + 19, 17, 6, 18, 7, 15, 11, 67, 22, 31, 52, 25, 6, 2, 2, 2, + 2, 104, 14, 8, 2, 2, 2, 5, 8, 5, 5, 0, 2, 2, 0, 32, + 19, 0, 0, 0, 34, 0, 0, 2, 8, 2, 0, 0, 0, 0, 0, 5, + 105, 31, 24, 8, 2, 2, 5, 0, 8, 5, 2, 8, 5, 2, 0, 35, + 19, 17, 13, 0, 25, 38, 25, 68, 0, 53, 0, 0, 0, 8, 2, 5, + 5, 54, 39, 77, 0, 0, 0, 0, 0, 31, 24, 8, 2, 2, 2, 2, + 8, 5, 2, 8, 2, 2, 0, 32, 19, 17, 6, 18, 25, 7, 34, 67, + 0, 0, 0, 0, 0, 8, 54, 54, 46, 31, 14, 8, 2, 2, 2, 5, + 8, 5, 2, 8, 2, 2, 0, 32, 20, 0, 0, 25, 7, 0, 0, 2, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 26, 8, 2, 2, 5, 0, + 2, 5, 2, 2, 0, 8, 5, 5, 2, 0, 8, 5, 0, 2, 5, 0, + 2, 2, 2, 2, 2, 2, 0, 0, 11, 15, 27, 0, 12, 33, 12, 45, + 0, 0, 0, 0, 34, 0, 0, 0, 0, 24, 14, 55, 2, 2, 2, 5, + 2, 2, 2, 2, 2, 2, 0, 32, 7, 0, 0, 25, 13, 2, 5, 0, + 0, 36, 14, 8, 2, 2, 2, 5, 2, 2, 2, 8, 2, 2, 0, 32, + 20, 0, 0, 34, 27, 0, 0, 0, 5, 106, 78, 0, 0, 0, 0, 0, + 0, 9, 14, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 30, 40, + 11, 17, 6, 13, 12, 33, 12, 45, 107, 0, 0, 0, 34, 0, 0, 0, + 8, 31, 14, 8, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, + 2, 2, 8, 2, 2, 2, 2, 8, 0, 2, 2, 2, 5, 0, 108, 0, + 34, 11, 7, 13, 13, 19, 12, 12, 22, 0, 11, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 2, 2, 69, 69, 109, 0, 0, 19, 56, 18, 21, 7, 7, 6, 6, + 26, 18, 9, 13, 9, 2, 2, 79, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 81, 0, 0, 0, 0, 110, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 23, 20, 21, 57, 7, 7, 111, 82, 112, 113, + 83, 2, 2, 2, 2, 2, 48, 0, 44, 2, 2, 2, 11, 6, 2, 2, + 114, 83, 84, 41, 23, 84, 14, 14, 2, 30, 7, 40, 2, 2, 2, 2, + 2, 2, 115, 58, 116, 14, 14, 117, 85, 2, 2, 2, 2, 2, 14, 20, + 0, 2, 21, 59, 0, 0, 0, 0, 8, 2, 21, 27, 0, 0, 0, 0, + 0, 2, 21, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 5, + 2, 5, 21, 0, 0, 0, 0, 0, 0, 2, 2, 4, 20, 7, 21, 6, + 12, 12, 12, 12, 24, 60, 118, 119, 120, 121, 122, 0, 0, 0, 0, 123, + 0, 5, 0, 0, 8, 0, 124, 4, 125, 39, 39, 126, 86, 2, 2, 2, + 2, 2, 2, 2, 2, 50, 5, 0, 0, 7, 59, 20, 7, 127, 10, 0, + 0, 70, 128, 70, 70, 129, 130, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 2, 2, 14, 0, 0, 0, 2, 2, 2, 30, 71, 20, 0, + 0, 2, 2, 131, 132, 42, 133, 10, 81, 134, 15, 20, 7, 21, 18, 59, + 12, 12, 58, 9, 9, 9, 87, 26, 53, 9, 88, 41, 2, 2, 2, 2, + 2, 2, 2, 89, 7, 6, 6, 7, 12, 12, 7, 61, 2, 2, 2, 5, + 0, 0, 0, 0, 0, 0, 135, 62, 62, 62, 62, 0, 0, 0, 0, 0, + 0, 88, 41, 2, 2, 2, 2, 2, 2, 79, 10, 21, 22, 7, 136, 10, + 2, 2, 2, 2, 89, 7, 11, 20, 20, 42, 137, 0, 0, 0, 0, 0, + 0, 2, 2, 10, 19, 12, 11, 90, 42, 42, 42, 138, 139, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 8, 2, 9, 26, 16, 16, 16, 9, 16, + 16, 24, 16, 16, 16, 52, 0, 53, 0, 0, 0, 140, 78, 9, 44, 0, + 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 49, 142, + 3, 39, 39, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, + 72, 0, 0, 91, 0, 0, 0, 0, 0, 0, 76, 91, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 63, 63, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 143, 0, 63, 63, 0, 0, 0, 0, + 0, 2, 40, 2, 61, 2, 36, 2, 2, 2, 23, 17, 15, 0, 0, 13, + 0, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 144, 11, 11, 11, 11, + 11, 11, 11, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 2, 0, 0, 0, 0, 0, 30, 2, 2, 2, 7, 7, 145, 16, + 0, 2, 2, 2, 47, 6, 21, 6, 90, 42, 146, 0, 0, 0, 0, 0, + 0, 9, 147, 2, 2, 2, 2, 2, 2, 2, 148, 11, 7, 6, 12, 149, + 150, 93, 0, 0, 0, 0, 0, 0, 0, 2, 2, 30, 8, 2, 2, 2, + 2, 2, 2, 2, 2, 36, 7, 21, 71, 58, 151, 94, 152, 0, 0, 0, + 0, 2, 153, 2, 2, 2, 2, 154, 0, 8, 2, 39, 44, 0, 85, 24, + 2, 73, 6, 40, 47, 73, 2, 2, 95, 36, 5, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 155, 18, 22, 0, 0, 156, 96, 0, 0, 0, + 0, 2, 23, 20, 11, 59, 27, 157, 0, 0, 0, 0, 0, 0, 0, 0, + 49, 3, 3, 3, 3, 72, 0, 0, 0, 2, 5, 2, 8, 2, 2, 2, + 2, 2, 8, 2, 2, 2, 8, 5, 0, 47, 6, 25, 13, 0, 0, 158, + 159, 2, 2, 8, 2, 8, 2, 2, 2, 2, 2, 2, 0, 51, 35, 0, + 97, 2, 2, 50, 35, 0, 8, 2, 2, 0, 0, 0, 0, 8, 2, 2, + 5, 2, 2, 9, 54, 0, 0, 0, 0, 2, 2, 2, 0, 25, 7, 7, + 8, 2, 2, 2, 2, 2, 25, 38, 0, 2, 2, 2, 16, 16, 16, 16, + 16, 160, 2, 5, 0, 0, 0, 0, 0, 2, 51, 51, 0, 0, 0, 0, + 0, 5, 2, 2, 5, 2, 2, 2, 2, 8, 2, 5, 0, 8, 2, 0, + 0, 161, 162, 163, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 6, + 6, 6, 7, 7, 93, 0, 0, 0, 0, 0, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 2, 2, 2, 2, 2, 40, 30, 40, 0, 0, 0, 0, + 164, 19, 17, 18, 15, 67, 35, 0, 0, 0, 13, 0, 0, 0, 0, 0, + 0, 9, 55, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 6, 7, 165, + 7, 18, 166, 98, 2, 2, 2, 2, 2, 0, 0, 23, 167, 0, 0, 0, + 0, 2, 50, 0, 0, 0, 0, 0, 0, 2, 23, 22, 6, 6, 6, 7, + 7, 61, 64, 0, 0, 69, 99, 13, 100, 2, 2, 2, 2, 2, 2, 11, + 17, 7, 7, 168, 46, 0, 0, 0, 55, 47, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 5, 5, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, + 8, 2, 2, 2, 2, 2, 2, 2, 36, 19, 17, 18, 7, 169, 13, 0, + 0, 9, 9, 8, 2, 2, 2, 5, 8, 5, 2, 8, 2, 2, 56, 32, + 11, 15, 11, 27, 29, 33, 29, 45, 0, 0, 0, 0, 34, 0, 0, 0, + 2, 2, 11, 0, 9, 9, 9, 26, 0, 9, 9, 26, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 8, 0, 5, 2, 2, 2, 8, 20, 21, 6, + 6, 13, 33, 29, 29, 22, 170, 14, 171, 101, 35, 0, 0, 0, 0, 0, + 0, 31, 52, 0, 0, 0, 0, 0, 0, 2, 2, 23, 22, 6, 6, 6, + 7, 11, 92, 24, 32, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, + 172, 173, 0, 0, 0, 0, 0, 0, 0, 19, 17, 6, 6, 57, 71, 22, + 100, 9, 102, 5, 0, 0, 0, 0, 0, 22, 6, 6, 0, 12, 12, 9, + 65, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, + 0, 11, 17, 6, 6, 18, 15, 60, 65, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 36, 174, 22, 6, 7, 7, 102, 5, 0, 0, + 0, 2, 2, 2, 2, 2, 5, 77, 94, 11, 7, 6, 58, 18, 7, 0, + 0, 2, 2, 2, 5, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 19, + 17, 6, 18, 7, 87, 65, 35, 0, 0, 2, 2, 2, 5, 8, 0, 2, + 2, 2, 2, 8, 5, 2, 2, 2, 2, 11, 11, 19, 29, 33, 31, 175, + 101, 176, 177, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 23, 22, 6, 6, 0, 7, 11, 14, 61, 0, 33, 0, 0, 0, 0, + 0, 30, 6, 7, 7, 7, 73, 2, 2, 2, 178, 95, 9, 24, 179, 10, + 180, 0, 0, 48, 97, 0, 0, 0, 0, 30, 6, 7, 15, 17, 6, 2, + 2, 2, 2, 64, 64, 64, 43, 43, 43, 43, 43, 43, 24, 181, 0, 8, + 0, 15, 6, 15, 15, 0, 0, 0, 0, 7, 6, 6, 13, 7, 7, 9, + 65, 0, 10, 10, 10, 10, 10, 10, 10, 57, 18, 60, 26, 0, 0, 0, + 0, 2, 2, 2, 5, 2, 8, 2, 2, 30, 7, 7, 13, 0, 38, 7, + 25, 9, 99, 182, 183, 0, 0, 0, 0, 2, 2, 2, 8, 5, 2, 2, + 2, 2, 2, 2, 2, 2, 11, 11, 27, 7, 34, 60, 82, 0, 0, 0, + 0, 2, 184, 57, 27, 0, 0, 0, 0, 9, 185, 2, 2, 2, 2, 2, + 2, 2, 2, 11, 7, 6, 13, 0, 12, 15, 96, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 98, 0, 0, 66, 66, 66, 186, 187, 66, 1, + 1, 188, 1, 1, 189, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 190, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 7, 191, 192, 193, 9, 9, 9, 26, 0, 0, 0, + 0, 14, 41, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, 27, + 0, 2, 2, 2, 2, 2, 5, 0, 56, 194, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 0, 0, 0, 53, 16, 52, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 2, 2, 2, 2, 2, 0, 56, 35, 0, 49, 3, 3, 3, 72, 0, + 0, 9, 9, 9, 55, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 26, 2, 2, 2, 2, 2, 2, 9, + 9, 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2, 2, + 6, 2, 2, 46, 46, 46, 86, 0, 0, O, O, G, G, B, B, WJ, + WJ, CGJ, CGJ, B, O, VBlw, VBlw, VAbv, VAbv, O, B,VMAbv,VMAbv, SUB, SUB, VPst, + VPst, VPre, VPre, VBlw, O,VMPst,VMPst, VAbv, VPst,VMBlw,VMBlw, VPst, VBlw, VBlw, VAbv, VPst, + VPre, VPst, VAbv, VAbv, VBlw, VPre, VPst, B, VPst,VMAbv,VMPst, O, VAbv,VMAbv, O, VPst, + O, N, N, O, VPre, B, VAbv, O,VMAbv,CMBlw, B, VPre, O, O, VPst,CMBlw, + O, B,VMAbv, HM, HM, VAbv, O, GB, GB, VAbv, B,VMPst, B, FAbv, FAbv, FBlw, + FBlw, GB, O, VPre, H,CMAbv,CMAbv, B, VBlw, O, GB, O, WJ, B,CMBlw,CMBlw, + CMBlw,VMBlw, O, O,VMBlw,VMAbv,CMAbv,VMAbv, B, O,CMBlw, VBlw, VPre, VPre, VAbv, VBlw, + VPst, VPst,VMAbv, H, B,SMAbv,SMAbv, SB, SE, R, R,VMPst, H, J, J, VPst, + H, VAbv, H, O,FMBlw, FPst, FPst, VAbv, VPre, WJ, O, VBlw, B, O, SB, O, + SE,FMPst,FMPst, O, MBlw, CS,VMPst, B, SUB, O, SUB, SUB, O,VMPst, IS, MBlw, + B, VPst,VMPst, B,VMPst,CMAbv, B, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, VBlw, FAbv,FMPst, + O, H,VMAbv, H, O, MPre, MAbv, VBlw,VMAbv, IS, O, O, IS,CMAbv, O,CMBlw, + VAbv, VPre,VMAbv, IS, R, H,CMBlw, O, CGJ, GB,VMAbv,FMAbv, O, O, CS, R, + O, HVM, O, O,CMAbv,FMBlw, O,VMAbv,VMBlw, VAbv, MPst, MPre, MBlw, MBlw, MBlw, MBlw, + VPst, VAbv,VMPst,VMPst,VMBlw,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B, + FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv, VAbv, SUB,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, B, + MPre, MBlw, SUB, MAbv, SUB, Sk, VPst, O,SMAbv, VPst, IS, RK, RK,VMPre,VMPre,FMAbv, + CMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, O, H, MPst, VPst, VAbv,VMBlw, FPst, VPst, FAbv, + VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, VBlw, MPst, MBlw, O, B, FAbv, FAbv, FPst, B, + VPre, O,VMPst,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, + B, O, HN, VPre, VBlw, VAbv, IS, VPst, B,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv, + CMBlw,FMAbv, B, CS, CS,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, + SUB, SUB, GB,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, J, SB, SE, + J, HR, G, G, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t -hb_use_u16[856] = +static const uint16_t hb_use_u16[864]= { - 0, 0, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, - 0, 0, 0, 0, 10, 13, 0, 0, 14, 10, 10, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32, - 33, 34, 22, 35, 36, 0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41, - 42, 43, 44, 45, 46, 47, 31, 0, 48, 49, 22, 50, 51, 52, 18, 0, - 53, 49, 22, 54, 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 18, 0, - 61, 62, 10, 63, 64, 65, 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, - 73, 74, 75, 76, 77, 0, 0, 0, 10, 10, 78, 79, 80, 81, 82, 83, - 84, 85, 0, 0, 0, 0, 0, 0, 10, 86, 10, 87, 10, 88, 89, 90, - 10, 10, 10, 91, 92, 93, 2, 0, 94, 0, 10, 10, 10, 10, 10, 95, - 96, 10, 97, 0, 0, 0, 0, 0, 98, 99,100,101, 31, 10,102,103, - 10, 10,104, 10,105,106, 0, 0, 10,107, 10, 10, 10,108,109,110, - 2, 2, 0, 0, 0, 0, 0, 0,111, 10, 10,112,113, 2,114,115, - 116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122, 0, 0, 0, - 0, 0, 0, 0, 0,123,124,125, 0, 0, 0, 0, 0, 0, 0,126, - 127,128,129, 0, 0, 0,130,131,132, 0, 0, 0, 0, 0, 0,133, - 0, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0,135, 0, - 0, 0, 0, 10, 10, 10,136,137, 0, 0,138, 0, 0, 0, 0, 0, - 139, 10,140, 0, 10, 10, 10,141,142, 10, 10,143,144, 2,145,146, - 10, 10,147, 10,148,149, 0, 0,150, 10, 10,151,152, 2,153, 99, - 10, 10,154,155,156, 2, 10,157, 10, 10, 10,158,159, 0,160,161, - 0, 0, 0, 0, 10, 10,162, 2,163, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, - 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, - 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, - 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 9, 10,176, 10, - 177, 0, 0, 0, 0, 0, 0, 0, 10, 10,178,173, 0, 0, 0, 0, - 0, 0, 0, 10,179,180, 0, 10,181, 0, 0,182,183, 0, 0, 0, - 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0, 0, 0, - 193, 10,194,195,196, 10, 10,197,190, 10, 10,198,199,106,200,103, - 10, 34,201,202,203, 0, 0, 0,204,205, 95, 10, 10,206,207, 2, - 208, 21, 22,209,210,211,212,213,214, 10, 10,215,216,217,218, 0, - 10, 10, 10,219,220,221,222, 0,200, 10, 10,223,224, 2, 0, 0, - 10, 10,225,226,227,228, 0, 0, 10, 10, 10,229,230, 2, 0, 0, - 10, 10,231,232, 2, 10,141, 0, 10,233,234,104,235, 0, 0, 0, - 10, 10,236,237, 0, 0, 0, 0,238,239, 10,240,241, 2, 0, 0, - 0, 0,242, 10, 10,243,244, 0,245, 10, 10,246,247,248, 10, 10, - 249,250, 0, 0, 0, 0, 0, 0, 22, 10,225,251, 8, 10, 71, 19, - 10,252, 74,253, 0, 0, 0, 0,254, 10, 10,255,256, 2,257, 10, - 258,259, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,260, - 261, 49, 10,262,263,264, 0, 0,265,265,265,265,265,265,265,265, - 265,265,265,266,267,268,265,265,265,265,265,265,265,265,265,269, - 10,270,271, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 10, 10, 10,272, 0, 0, 0, 0, 0, 0, 0, 0,273, 10,274, 2, - 10, 10, 10, 10,275,276,277,277,278,279, 0, 0, 0, 0,280, 0, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,177, 0,281, - 10, 10, 10, 10, 10, 10,106, 71, 95,282, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,283, 10, 10, 71,284,285, 0, 0, 0, - 0, 10,286, 0, 10, 10,287, 2, 0, 0, 0, 0, 0, 10,288, 2, - 0, 0, 0, 0, 0, 10,289,106, 10, 10, 10, 10,290, 2, 0, 0, - 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, - 163,163,163,163,163,163,163,130, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 272, 32, 0, 120, 0, 120, 0, 0, 280, 288, 0, 296, 0, 0, + 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, + 0, 0, 0, 0, 136, 24, 312, 320, 0, 0, 0, 0, 24, 328, 0, 0, + 336, 24, 24, 344, 352, 360, 56, 144, 368, 64, 48, 376, 152, 384, 56, 392, + 400, 64, 48, 408, 416, 424, 72, 432, 440, 112, 48, 448, 456, 0, 56, 464, + 472, 64, 48, 480, 152, 488, 56, 496, 504, 512, 520, 528, 536, 544, 72, 0, + 552, 80, 48, 560, 160, 568, 56, 0, 576, 80, 48, 584, 160, 592, 56, 600, + 608, 80, 24, 616, 624, 632, 56, 0, 640, 648, 24, 656, 664, 672, 72, 680, + 688, 696, 24, 704, 168, 24, 88, 712, 720, 176, 728, 736, 744, 0, 0, 0, + 24, 24, 752, 760, 768, 776, 784, 792, 800, 808, 0, 0, 0, 0, 0, 0, + 24, 816, 24, 824, 24, 832, 840, 848, 24, 24, 24, 856, 864, 872, 32, 0, + 880, 0, 24, 24, 24, 24, 24, 96, 888, 24, 896, 0, 0, 0, 0, 0, + 24, 184, 904, 912, 72, 24, 920, 192, 24, 24, 200, 24, 928, 104, 0, 0, + 24, 936, 24, 24, 24, 944, 952, 960, 32, 32, 0, 0, 0, 0, 0, 0, + 968, 24, 24, 976, 984, 32, 992,1000,1008, 24,1016, 24, 24, 24,1024,1032, + 24, 24,1040,1048,1056, 0, 0, 0, 0, 0, 0, 0, 0,1064,1072,1080, + 0, 0, 0, 0, 0, 0, 0,1088,1096,1104,1112, 0, 0, 0, 16,1120, + 1128, 0, 0, 0, 0, 0, 0,1136, 0, 0, 0, 0,1144, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1152, 0, 0, 0, 0, 24, 24, 24,1160,1168, + 0, 0,1176, 0, 0, 0, 0, 0,1184, 24,1192, 0, 24, 24, 24, 208, + 1200, 24, 24,1208,1216, 32,1224,1232, 24, 24,1240, 24,1248,1256, 0, 0, + 1264, 24, 24,1272,1280, 32,1288, 184, 24, 24,1296,1304,1312, 32, 24,1320, + 24, 24, 24,1328,1336, 0,1344,1352, 0, 0, 0, 0, 24, 24,1360, 32, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1368, + 0, 0, 0, 0, 0, 0, 0,1376, 0, 0, 0, 0, 0, 0, 0, 216, + 216,1384, 112,1392, 0, 0, 0, 0,1400,1408, 24,1416, 96, 0, 0, 0, + 0, 0, 0, 0, 168, 24,1424, 0, 24, 224,1432, 0, 0, 0, 0, 0, + 24, 24,1440, 32, 136, 24,1448, 24, 232, 0, 0, 0, 0, 0, 0, 0, + 24, 24,1456, 224, 0, 0, 0, 0, 0, 0, 0, 24,1464,1472, 0, 24, + 1480, 0, 0,1488,1496, 0, 0, 0,1504, 24, 24,1512,1520,1528,1536,1544, + 240, 24, 24,1552,1560, 0, 0, 0,1568, 24,1576,1584,1592, 24, 24,1600, + 240, 24, 24,1608,1616, 104, 248, 192, 24, 112,1624,1632,1640, 0, 0, 0, + 1648,1656, 96, 24, 24,1664,1672, 32,1680, 64, 48,1688,1696,1704,1712,1720, + 1728, 24, 24,1736,1744,1752,1760, 0, 24, 24, 24,1768,1776,1784,1792, 0, + 248, 24, 24,1800,1808, 32, 0, 0, 24, 24, 256,1816,1824,1832, 0, 0, + 24, 24, 24,1840,1848, 32, 0, 0, 24, 24,1856,1864, 32, 24, 208, 0, + 24,1872,1880, 200,1888, 0, 0, 0, 24, 24,1896,1904, 0, 0, 0, 0, + 1912,1920, 24,1928,1936, 32, 0, 0, 0, 0,1944, 24, 24,1952,1960, 0, + 1968, 24, 24,1976,1984,1992, 24, 24,2000,2008, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,2016, 0, 48, 24, 256,2024, 128, 24, 88, 144, + 24,2032, 176,2040, 0, 0, 0, 0,2048, 24, 24,2056,2064, 32,2072, 24, + 2080,2088, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,2096, + 2104, 80, 24,2112,2120,2128, 0, 0, 8, 8, 8,2136,2144,2152, 8, 8, + 8, 8, 8, 8, 8, 8, 8,2160, 24,2168,2176, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 24, 24, 24,2184, 0, 0, 0, 0, + 0, 0, 0, 0,2192, 24,2200, 32, 24, 24, 24, 24,2208,2216, 264, 264, + 2224,2232, 0, 0, 0, 0,2240, 0, 24, 24, 24, 24, 24, 232, 0,2248, + 24, 24, 24, 24, 24, 24, 104, 88, 96,2256, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,2264, 24, 24, 88,2272,2280, 0, 0, 0, + 0, 24,2288, 0, 24, 24,2296, 32, 0, 0, 0, 0, 0, 24,2304, 32, + 0, 0, 0, 0, 0, 24,2312, 104, 24, 24, 24, 24,2320, 32, 0, 0, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 16, }; -static inline unsigned -hb_use_b4 (const uint8_t* a, unsigned i) +static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast8_t -hb_use_get_category (unsigned u) +static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[2953+(((hb_use_u8[625+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + /* packtab: [2^4,2^5,2^3,2^3,2^1] */ + return u<921600u ? (uint8_t)(hb_use_u8[2953u+((hb_use_u8[625u+hb_use_u16[((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((u)>>1))>>3))>>3))>>5)))<<5)+((((((((u)>>1))>>3))>>3))&31)])<<3)+((((((u)>>1))>>3))&7)]+((((u)>>1))&7)])<<1)+((u)&1)]) : O; } #else -static const uint8_t -hb_use_u8[3657] = +#include + +static const uint8_t hb_use_u8[3663]= { - 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 57, 58, 59, 195, 211, 62, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 15, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 1, - 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, 1, - 1, 20, 1, 1, 1, 1, 21, 1, 22, 1, 1, 1, 1, 1, 23, 24, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, - 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, - 51, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 58, 1, - 59, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60, 61, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 1, - 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 65, 1, 66, 67, 1, 1, 1, 68, 1, 1, 1, 1, 1, - 1, 69, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 37, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 59, 60, 0, 0, 0, 61, 62, 63, 64, 56, 65, 66, - 67, 68, 56, 56, 69, 70, 71, 0, 0, 72, 73, 74, 75, 56, 76, 77, - 0, 78, 56, 79, 80, 81, 0, 0, 0, 82, 83, 84, 85, 86, 87, 56, - 88, 56, 89, 90, 0, 0, 0, 91, 92, 0, 0, 0, 0, 0, 0, 0, - 93, 94, 95, 0, 96, 97, 0, 0, 98, 0, 0, 0, 0, 0, 0, 99, - 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 101, 56, 102, 0, 0, 0, - 0, 0, 103, 0, 0, 0, 0, 0, 0, 104, 105, 56, 106, 107, 108, 109, - 110, 56, 111, 112, 0, 113, 114, 115, 116, 56, 117, 118, 119, 56, 120, 121, - 122, 0, 0, 0, 0, 0, 0, 56, 123, 124, 0, 0, 0, 0, 0, 0, - 125, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 127, 128, 129, 0, - 0, 130, 131, 132, 0, 0, 0, 51, 133, 0, 0, 0, 0, 134, 135, 0, - 0, 56, 136, 7, 137, 138, 0, 0, 0, 0, 0, 0, 0, 56, 139, 0, - 0, 0, 101, 140, 101, 141, 142, 143, 0, 144, 145, 146, 147, 148, 149, 150, - 0, 151, 152, 153, 154, 148, 155, 156, 157, 158, 159, 160, 0, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 56, 173, 174, 175, 176, 177, 178, - 0, 0, 0, 0, 0, 56, 179, 180, 0, 56, 181, 182, 0, 56, 183, 184, - 185, 186, 187, 188, 0, 0, 0, 0, 0, 56, 189, 0, 0, 0, 0, 0, - 0, 190, 191, 192, 0, 0, 193, 194, 195, 196, 197, 198, 56, 199, 0, 0, - 0, 200, 201, 202, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 67, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 211, 212, 213, 214, 0, 0, 0, 0, - 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 217, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 215, 218, 219, 220, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 221, 0, 0, 0, 0, 0, - 0, 0, 0, 222, 223, 0, 0, 0, 0, 56, 56, 224, 225, 226, 0, 0, - 227, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 228, - 229, 56, 56, 56, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, - 0, 56, 233, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 235, 56, - 236, 0, 0, 0, 0, 0, 0, 101, 237, 0, 0, 0, 0, 0, 0, 101, - 238, 56, 56, 239, 0, 0, 0, 0, 0, 240, 240, 240, 240, 240, 240, 240, - 240, 241, 241, 241, 241, 241, 241, 241, 242, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, - 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 10, 11, 11, 11, 11, 0, 0, 0, 9, 12, - 0, 2, 2, 2, 2, 13, 14, 0, 0, 11, 15, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, - 25, 12, 26, 27, 20, 2, 2, 2, 2, 2, 20, 0, 2, 2, 2, 2, - 2, 0, 2, 2, 2, 2, 2, 2, 2, 28, 29, 30, 2, 2, 2, 9, - 30, 9, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, - 2, 9, 9, 0, 2, 2, 0, 17, 18, 19, 20, 31, 32, 33, 32, 34, - 0, 0, 0, 0, 35, 0, 0, 2, 30, 2, 0, 0, 0, 0, 0, 9, - 36, 12, 15, 30, 2, 2, 9, 0, 30, 9, 2, 30, 9, 2, 0, 37, - 18, 19, 31, 0, 27, 38, 27, 39, 0, 40, 0, 0, 0, 30, 2, 9, - 9, 0, 0, 0, 2, 2, 2, 2, 2, 41, 42, 43, 0, 0, 0, 0, - 0, 12, 15, 30, 2, 2, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, - 2, 9, 2, 30, 2, 2, 0, 17, 18, 19, 20, 21, 27, 22, 35, 24, - 0, 0, 0, 0, 0, 30, 41, 41, 44, 12, 29, 30, 2, 2, 2, 9, - 30, 9, 2, 30, 2, 2, 0, 17, 45, 0, 0, 27, 22, 0, 0, 2, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 46, 30, 2, 2, 9, 0, - 2, 9, 2, 2, 0, 30, 9, 9, 2, 0, 30, 9, 0, 2, 9, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 23, 16, 47, 0, 48, 33, 48, 34, - 0, 0, 0, 0, 35, 0, 0, 0, 0, 15, 29, 49, 2, 2, 2, 9, - 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 17, - 22, 16, 23, 47, 22, 38, 22, 39, 0, 0, 0, 27, 31, 2, 9, 0, - 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, - 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, - 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, - 23, 19, 20, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, - 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, - 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, - 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, - 0, 2, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, - 0, 2, 2, 56, 56, 57, 0, 0, 18, 2, 2, 2, 2, 30, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 9, 0, 58, 21, 59, 22, 22, 20, 20, - 46, 21, 11, 31, 11, 2, 2, 60, 61, 61, 61, 61, 61, 62, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 63, - 0, 0, 0, 0, 64, 0, 0, 0, 0, 2, 2, 2, 2, 2, 65, 45, - 59, 66, 22, 22, 67, 68, 69, 70, 71, 2, 2, 2, 2, 2, 1, 0, - 5, 2, 2, 2, 23, 20, 2, 2, 72, 71, 73, 74, 65, 73, 29, 29, - 2, 52, 22, 53, 2, 2, 2, 2, 2, 2, 75, 76, 77, 29, 29, 78, - 79, 2, 2, 2, 2, 2, 29, 45, 0, 2, 59, 80, 0, 0, 0, 0, - 30, 2, 59, 47, 0, 0, 0, 0, 0, 2, 59, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 9, 2, 9, 59, 0, 0, 0, 0, 0, - 0, 2, 2, 81, 45, 22, 59, 20, 48, 48, 48, 48, 15, 82, 83, 84, - 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, - 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, - 2, 2, 2, 2, 2, 13, 9, 0, 0, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 94, 61, 0, - 0, 95, 96, 95, 95, 97, 98, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, - 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, - 0, 2, 2, 2, 52, 99, 45, 0, 0, 2, 2, 100, 101, 102, 103, 61, - 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, - 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, - 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, - 110, 110, 110, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, - 2, 60, 61, 59, 25, 22, 111, 61, 2, 2, 2, 2, 107, 22, 23, 45, - 45, 102, 112, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, - 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, - 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, - 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, - 0, 0, 0, 0, 0, 0, 6, 119, 120, 42, 42, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, - 120, 0, 0, 122, 0, 0, 0, 0, 0, 0, 7, 122, 0, 0, 0, 0, - 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 123, 123, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 30, 0, 0, 0, 0, 0, 0, 0, 124, 0, 123, 123, 0, 0, 0, 0, - 0, 2, 53, 2, 108, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, - 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 125, 23, 23, 23, 23, 23, 23, 23, 126, 0, 0, 0, 0, - 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, - 52, 2, 2, 2, 22, 22, 127, 116, 0, 2, 2, 2, 128, 20, 59, 20, - 113, 102, 129, 0, 0, 0, 0, 0, 0, 11, 130, 2, 2, 2, 2, 2, - 2, 2, 131, 23, 22, 20, 48, 132, 133, 134, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, - 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, - 0, 30, 2, 42, 5, 0, 79, 15, 2, 53, 22, 140, 52, 53, 2, 2, - 105, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, - 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, - 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, - 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, - 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, - 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, - 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, - 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 0, 27, 22, 22, - 30, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, - 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, - 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, - 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 134, 0, 0, 0, - 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, - 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, - 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, - 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 154, - 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, - 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, - 22, 108, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, - 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, - 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, - 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, - 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, - 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, - 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 30, 0, - 9, 2, 2, 2, 30, 45, 59, 20, 20, 31, 33, 32, 32, 25, 163, 29, - 164, 165, 37, 0, 0, 0, 0, 0, 0, 12, 26, 0, 0, 0, 0, 0, - 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 0, 0, 166, 167, 0, 0, 0, 0, 0, 0, - 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 168, 9, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, - 169, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, - 0, 23, 19, 20, 20, 21, 16, 82, 169, 38, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 10, 170, 25, 20, 22, 22, 168, 9, 0, 0, - 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, - 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, - 19, 20, 21, 22, 105, 169, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, - 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 171, - 165, 172, 173, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, - 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 174, 175, 11, 15, 176, 61, - 177, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, - 2, 2, 2, 158, 158, 158, 178, 178, 178, 178, 178, 178, 15, 179, 0, 30, - 0, 22, 20, 20, 31, 22, 22, 11, 169, 0, 61, 61, 61, 61, 61, 61, - 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, - 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 180, 181, 0, 0, 0, - 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, - 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 182, 66, 47, 0, 0, 0, - 0, 11, 183, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, - 48, 16, 143, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 156, 0, - 0, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 186, 187, 185, 184, - 184, 188, 184, 184, 189, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, - 0, 184, 184, 184, 184, 184, 191, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 22, 22, 22, 22, 22, 22, 192, 193, 194, 11, 11, 11, 46, 0, 0, 0, - 0, 29, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 47, - 0, 2, 2, 2, 2, 2, 9, 0, 58, 195, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, - 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, 2, 2, 2, 0, 58, - 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, - 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, - 22, 2, 2, 2, 2, 2, 2, 2, 20, 2, 2, 44, 44, 44, 92, 0, - 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, - FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, - VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, - VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, - O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, - H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, - O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, B, R, O, HVM, - O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, - O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, - B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B, - VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, - FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, - FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, - SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMAbv,SMAbv, VPst, - IS, RK, RK, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, - CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, - VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, - MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, - O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, - B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, - VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv,CMBlw, IS, R,FMAbv, B, CS, - CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, VBlw, - VMAbv, CS, SUB, SUB, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R, - VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, HM, G, - O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, + 33, 3, 0, 0, 0, 4, 0, 80, 118, 128, 9, 10, 11, 192, 208, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 4, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 0, + 13, 14, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, 20, 21, 0, + 0, 22, 0, 0, 0, 0, 23, 0, 24, 0, 0, 0, 0, 0, 25, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, + 32, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 34, 35, 0, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 0, 60, 0, + 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, + 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 66, 67, 0, 68, 69, 0, 0, 0, 70, 0, 0, 0, 0, 0, + 0, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 7, 7, 0, 13, 14, + 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 17, 0, 0, 18, 0, 0, 0, 0, + 0, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 9, 46, 47, 48, + 49, 50, 51, 52, 9, 53, 54, 55, 56, 57, 58, 10, 59, 60, 61, 62, + 0, 3, 63, 64, 65, 66, 0, 0, 0, 67, 68, 69, 70, 3, 71, 72, + 6, 73, 3, 3, 74, 75, 76, 0, 0, 77, 78, 79, 80, 3, 81, 82, + 0, 83, 3, 84, 85, 86, 0, 0, 0, 87, 88, 89, 90, 91, 92, 3, + 93, 3, 94, 95, 0, 0, 0, 96, 97, 0, 0, 0, 0, 0, 0, 0, + 98, 99, 100, 0, 101, 102, 0, 0, 103, 0, 0, 0, 0, 0, 0, 104, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 5, 3, 106, 0, 0, 0, + 0, 0, 107, 0, 0, 0, 0, 0, 0, 108, 109, 3, 110, 111, 112, 113, + 114, 3, 115, 116, 0, 117, 118, 119, 120, 3, 121, 122, 123, 3, 124, 125, + 126, 0, 0, 0, 0, 0, 0, 3, 127, 128, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 131, 132, 133, 0, + 0, 134, 135, 136, 0, 0, 0, 10, 137, 0, 0, 0, 0, 138, 139, 0, + 0, 3, 140, 8, 141, 142, 0, 0, 0, 0, 0, 0, 0, 3, 143, 0, + 0, 0, 5, 144, 5, 145, 146, 147, 0, 148, 149, 150, 151, 11, 152, 153, + 0, 154, 155, 156, 157, 11, 158, 159, 160, 161, 162, 163, 0, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 3, 176, 177, 178, 179, 180, 181, + 0, 0, 0, 0, 0, 3, 182, 183, 0, 3, 184, 185, 0, 3, 186, 187, + 188, 189, 190, 191, 0, 0, 0, 0, 0, 3, 192, 0, 0, 0, 0, 0, + 0, 193, 194, 195, 0, 0, 196, 197, 198, 199, 200, 201, 3, 202, 0, 0, + 0, 0, 0, 0, 203, 0, 0, 0, 0, 204, 205, 206, 207, 208, 209, 0, + 0, 210, 211, 212, 213, 214, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 215, 216, 217, 218, 0, 0, 0, 0, 0, 1, 219, 220, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 221, 222, 223, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 224, 0, 0, 0, 0, 0, + 0, 0, 0, 225, 226, 0, 0, 0, 0, 3, 3, 227, 228, 229, 0, 0, + 230, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 231, + 232, 3, 3, 3, 233, 234, 0, 0, 0, 0, 0, 0, 235, 0, 0, 0, + 0, 3, 236, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 238, 3, + 239, 0, 0, 0, 0, 0, 0, 5, 240, 0, 0, 0, 0, 0, 0, 5, + 241, 3, 3, 242, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 243, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 2, 2, 2, 2, 5, 2, 2, 2, 2, 6, 0, 2, 2, 2, 2, + 2, 5, 8, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, + 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, + 0, 2, 2, 2, 2, 5, 0, 0, 0, 2, 2, 2, 2, 2, 5, 0, + 0, 2, 8, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 74, 75, + 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 2, 2, 2, 2, 2, 2, 2, 17, 6, 13, 29, 33, 29, 45, + 0, 15, 11, 27, 7, 38, 7, 68, 0, 2, 2, 2, 2, 8, 2, 2, + 2, 10, 10, 10, 10, 80, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, + 5, 2, 2, 5, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 5, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, + 0, 9, 41, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 23, 6, 6, 6, 6, 6, 6, 6, + 6, 0, 0, 0, 0, 0, 0, 48, 0, 44, 0, 0, 0, 0, 0, 49, + 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 103, 2, 2, 2, 2, 2, 36, 9, + 9, 9, 9, 0, 0, 0, 5, 31, 0, 2, 2, 2, 2, 50, 51, 0, + 0, 9, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 32, + 19, 17, 6, 18, 7, 15, 11, 67, 22, 31, 52, 25, 6, 2, 2, 2, + 2, 104, 14, 8, 2, 2, 2, 5, 8, 5, 5, 0, 2, 2, 0, 32, + 19, 0, 0, 0, 34, 0, 0, 2, 8, 2, 0, 0, 0, 0, 0, 5, + 105, 31, 24, 8, 2, 2, 5, 0, 8, 5, 2, 8, 5, 2, 0, 35, + 19, 17, 13, 0, 25, 38, 25, 68, 0, 53, 0, 0, 0, 8, 2, 5, + 5, 54, 39, 77, 0, 0, 0, 0, 0, 31, 24, 8, 2, 2, 2, 2, + 8, 5, 2, 8, 2, 2, 0, 32, 19, 17, 6, 18, 25, 7, 34, 67, + 0, 0, 0, 0, 0, 8, 54, 54, 46, 31, 14, 8, 2, 2, 2, 5, + 8, 5, 2, 8, 2, 2, 0, 32, 20, 0, 0, 25, 7, 0, 0, 2, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 26, 8, 2, 2, 5, 0, + 2, 5, 2, 2, 0, 8, 5, 5, 2, 0, 8, 5, 0, 2, 5, 0, + 2, 2, 2, 2, 2, 2, 0, 0, 11, 15, 27, 0, 12, 33, 12, 45, + 0, 0, 0, 0, 34, 0, 0, 0, 0, 24, 14, 55, 2, 2, 2, 5, + 2, 2, 2, 2, 2, 2, 0, 32, 7, 0, 0, 25, 13, 2, 5, 0, + 0, 36, 14, 8, 2, 2, 2, 5, 2, 2, 2, 8, 2, 2, 0, 32, + 20, 0, 0, 34, 27, 0, 0, 0, 5, 106, 78, 0, 0, 0, 0, 0, + 0, 9, 14, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 30, 40, + 11, 17, 6, 13, 12, 33, 12, 45, 107, 0, 0, 0, 34, 0, 0, 0, + 8, 31, 14, 8, 2, 2, 2, 2, 2, 2, 2, 2, 5, 0, 2, 2, + 2, 2, 8, 2, 2, 2, 2, 8, 0, 2, 2, 2, 5, 0, 108, 0, + 34, 11, 7, 13, 13, 19, 12, 12, 22, 0, 11, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 2, 2, 69, 69, 109, 0, 0, 19, 56, 18, 21, 7, 7, 6, 6, + 26, 18, 9, 13, 9, 2, 2, 79, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 81, 0, 0, 0, 0, 110, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 23, 20, 21, 57, 7, 7, 111, 82, 112, 113, + 83, 2, 2, 2, 2, 2, 48, 0, 44, 2, 2, 2, 11, 6, 2, 2, + 114, 83, 84, 41, 23, 84, 14, 14, 2, 30, 7, 40, 2, 2, 2, 2, + 2, 2, 115, 58, 116, 14, 14, 117, 85, 2, 2, 2, 2, 2, 14, 20, + 0, 2, 21, 59, 0, 0, 0, 0, 8, 2, 21, 27, 0, 0, 0, 0, + 0, 2, 21, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 5, + 2, 5, 21, 0, 0, 0, 0, 0, 0, 2, 2, 4, 20, 7, 21, 6, + 12, 12, 12, 12, 24, 60, 118, 119, 120, 121, 122, 0, 0, 0, 0, 123, + 0, 5, 0, 0, 8, 0, 124, 4, 125, 39, 39, 126, 86, 2, 2, 2, + 2, 2, 2, 2, 2, 50, 5, 0, 0, 7, 59, 20, 7, 127, 10, 0, + 0, 70, 128, 70, 70, 129, 130, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 2, 2, 14, 0, 0, 0, 2, 2, 2, 30, 71, 20, 0, + 0, 2, 2, 131, 132, 42, 133, 10, 81, 134, 15, 20, 7, 21, 18, 59, + 12, 12, 58, 9, 9, 9, 87, 26, 53, 9, 88, 41, 2, 2, 2, 2, + 2, 2, 2, 89, 7, 6, 6, 7, 12, 12, 7, 61, 2, 2, 2, 5, + 0, 0, 0, 0, 0, 0, 135, 62, 62, 62, 62, 0, 0, 0, 0, 0, + 0, 88, 41, 2, 2, 2, 2, 2, 2, 79, 10, 21, 22, 7, 136, 10, + 2, 2, 2, 2, 89, 7, 11, 20, 20, 42, 137, 0, 0, 0, 0, 0, + 0, 2, 2, 10, 19, 12, 11, 90, 42, 42, 42, 138, 139, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 8, 2, 9, 26, 16, 16, 16, 9, 16, + 16, 24, 16, 16, 16, 52, 0, 53, 0, 0, 0, 140, 78, 9, 44, 0, + 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 49, 142, + 3, 39, 39, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, + 72, 0, 0, 91, 0, 0, 0, 0, 0, 0, 76, 91, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 63, 63, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, 143, 0, 63, 63, 0, 0, 0, 0, + 0, 2, 40, 2, 61, 2, 36, 2, 2, 2, 23, 17, 15, 0, 0, 13, + 0, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 144, 11, 11, 11, 11, + 11, 11, 11, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 2, 0, 0, 0, 0, 0, 30, 2, 2, 2, 7, 7, 145, 16, + 0, 2, 2, 2, 47, 6, 21, 6, 90, 42, 146, 0, 0, 0, 0, 0, + 0, 9, 147, 2, 2, 2, 2, 2, 2, 2, 148, 11, 7, 6, 12, 149, + 150, 93, 0, 0, 0, 0, 0, 0, 0, 2, 2, 30, 8, 2, 2, 2, + 2, 2, 2, 2, 2, 36, 7, 21, 71, 58, 151, 94, 152, 0, 0, 0, + 0, 2, 153, 2, 2, 2, 2, 154, 0, 8, 2, 39, 44, 0, 85, 24, + 2, 73, 6, 40, 47, 73, 2, 2, 95, 36, 5, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 155, 18, 22, 0, 0, 156, 96, 0, 0, 0, + 0, 2, 23, 20, 11, 59, 27, 157, 0, 0, 0, 0, 0, 0, 0, 0, + 49, 3, 3, 3, 3, 72, 0, 0, 0, 2, 5, 2, 8, 2, 2, 2, + 2, 2, 8, 2, 2, 2, 8, 5, 0, 47, 6, 25, 13, 0, 0, 158, + 159, 2, 2, 8, 2, 8, 2, 2, 2, 2, 2, 2, 0, 51, 35, 0, + 97, 2, 2, 50, 35, 0, 8, 2, 2, 0, 0, 0, 0, 8, 2, 2, + 5, 2, 2, 9, 54, 0, 0, 0, 0, 2, 2, 2, 0, 25, 7, 7, + 8, 2, 2, 2, 2, 2, 25, 38, 0, 2, 2, 2, 16, 16, 16, 16, + 16, 160, 2, 5, 0, 0, 0, 0, 0, 2, 51, 51, 0, 0, 0, 0, + 0, 5, 2, 2, 5, 2, 2, 2, 2, 8, 2, 5, 0, 8, 2, 0, + 0, 161, 162, 163, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 6, + 6, 6, 7, 7, 93, 0, 0, 0, 0, 0, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 2, 2, 2, 2, 2, 40, 30, 40, 0, 0, 0, 0, + 164, 19, 17, 18, 15, 67, 35, 0, 0, 0, 13, 0, 0, 0, 0, 0, + 0, 9, 55, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 6, 7, 165, + 7, 18, 166, 98, 2, 2, 2, 2, 2, 0, 0, 23, 167, 0, 0, 0, + 0, 2, 50, 0, 0, 0, 0, 0, 0, 2, 23, 22, 6, 6, 6, 7, + 7, 61, 64, 0, 0, 69, 99, 13, 100, 2, 2, 2, 2, 2, 2, 11, + 17, 7, 7, 168, 46, 0, 0, 0, 55, 47, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 5, 5, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, + 8, 2, 2, 2, 2, 2, 2, 2, 36, 19, 17, 18, 7, 169, 13, 0, + 0, 9, 9, 8, 2, 2, 2, 5, 8, 5, 2, 8, 2, 2, 56, 32, + 11, 15, 11, 27, 29, 33, 29, 45, 0, 0, 0, 0, 34, 0, 0, 0, + 2, 2, 11, 0, 9, 9, 9, 26, 0, 9, 9, 26, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 8, 0, 5, 2, 2, 2, 8, 20, 21, 6, + 6, 13, 33, 29, 29, 22, 170, 14, 171, 101, 35, 0, 0, 0, 0, 0, + 0, 31, 52, 0, 0, 0, 0, 0, 0, 2, 2, 23, 22, 6, 6, 6, + 7, 11, 92, 24, 32, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, + 172, 173, 0, 0, 0, 0, 0, 0, 0, 19, 17, 6, 6, 57, 71, 22, + 100, 9, 102, 5, 0, 0, 0, 0, 0, 22, 6, 6, 0, 12, 12, 9, + 65, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 6, + 0, 11, 17, 6, 6, 18, 15, 60, 65, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 36, 174, 22, 6, 7, 7, 102, 5, 0, 0, + 0, 2, 2, 2, 2, 2, 5, 77, 94, 11, 7, 6, 58, 18, 7, 0, + 0, 2, 2, 2, 5, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 19, + 17, 6, 18, 7, 87, 65, 35, 0, 0, 2, 2, 2, 5, 8, 0, 2, + 2, 2, 2, 8, 5, 2, 2, 2, 2, 11, 11, 19, 29, 33, 31, 175, + 101, 176, 177, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 23, 22, 6, 6, 0, 7, 11, 14, 61, 0, 33, 0, 0, 0, 0, + 0, 30, 6, 7, 7, 7, 73, 2, 2, 2, 178, 95, 9, 24, 179, 10, + 180, 0, 0, 48, 97, 0, 0, 0, 0, 30, 6, 7, 15, 17, 6, 2, + 2, 2, 2, 64, 64, 64, 43, 43, 43, 43, 43, 43, 24, 181, 0, 8, + 0, 15, 6, 15, 15, 0, 0, 0, 0, 7, 6, 6, 13, 7, 7, 9, + 65, 0, 10, 10, 10, 10, 10, 10, 10, 57, 18, 60, 26, 0, 0, 0, + 0, 2, 2, 2, 5, 2, 8, 2, 2, 30, 7, 7, 13, 0, 38, 7, + 25, 9, 99, 182, 183, 0, 0, 0, 0, 2, 2, 2, 8, 5, 2, 2, + 2, 2, 2, 2, 2, 2, 11, 11, 27, 7, 34, 60, 82, 0, 0, 0, + 0, 2, 184, 57, 27, 0, 0, 0, 0, 9, 185, 2, 2, 2, 2, 2, + 2, 2, 2, 11, 7, 6, 13, 0, 12, 15, 96, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 98, 0, 0, 66, 66, 66, 186, 187, 66, 1, + 1, 188, 1, 1, 189, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 190, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 7, 191, 192, 193, 9, 9, 9, 26, 0, 0, 0, + 0, 14, 41, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, 27, + 0, 2, 2, 2, 2, 2, 5, 0, 56, 194, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 0, 0, 0, 53, 16, 52, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 2, 2, 2, 2, 2, 0, 56, 35, 0, 49, 3, 3, 3, 72, 0, + 0, 9, 9, 9, 55, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 26, 2, 2, 2, 2, 2, 2, 9, + 9, 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2, 2, + 6, 2, 2, 46, 46, 46, 86, 0, 0, O, O, G, G, B, B, WJ, + WJ, CGJ, CGJ, B, O, VBlw, VBlw, VAbv, VAbv, O, B,VMAbv,VMAbv, SUB, SUB, VPst, + VPst, VPre, VPre, VBlw, O,VMPst,VMPst, VAbv, VPst,VMBlw,VMBlw, VPst, VBlw, VBlw, VAbv, VPst, + VPre, VPst, VAbv, VAbv, VBlw, VPre, VPst, B, VPst,VMAbv,VMPst, O, VAbv,VMAbv, O, VPst, + O, N, N, O, VPre, B, VAbv, O,VMAbv,CMBlw, B, VPre, O, O, VPst,CMBlw, + O, B,VMAbv, HM, HM, VAbv, O, GB, GB, VAbv, B,VMPst, B, FAbv, FAbv, FBlw, + FBlw, GB, O, VPre, H,CMAbv,CMAbv, B, VBlw, O, GB, O, WJ, B,CMBlw,CMBlw, + CMBlw,VMBlw, O, O,VMBlw,VMAbv,CMAbv,VMAbv, B, O,CMBlw, VBlw, VPre, VPre, VAbv, VBlw, + VPst, VPst,VMAbv, H, B,SMAbv,SMAbv, SB, SE, R, R,VMPst, H, J, J, VPst, + H, VAbv, H, O,FMBlw, FPst, FPst, VAbv, VPre, WJ, O, VBlw, B, O, SB, O, + SE,FMPst,FMPst, O, MBlw, CS,VMPst, B, SUB, O, SUB, SUB, O,VMPst, IS, MBlw, + B, VPst,VMPst, B,VMPst,CMAbv, B, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, VBlw, FAbv,FMPst, + O, H,VMAbv, H, O, MPre, MAbv, VBlw,VMAbv, IS, O, O, IS,CMAbv, O,CMBlw, + VAbv, VPre,VMAbv, IS, R, H,CMBlw, O, CGJ, GB,VMAbv,FMAbv, O, O, CS, R, + O, HVM, O, O,CMAbv,FMBlw, O,VMAbv,VMBlw, VAbv, MPst, MPre, MBlw, MBlw, MBlw, MBlw, + VPst, VAbv,VMPst,VMPst,VMBlw,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B, + FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv, VAbv, SUB,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, B, + MPre, MBlw, SUB, MAbv, SUB, Sk, VPst, O,SMAbv, VPst, IS, RK, RK,VMPre,VMPre,FMAbv, + CMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, O, H, MPst, VPst, VAbv,VMBlw, FPst, VPst, FAbv, + VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, VBlw, MPst, MBlw, O, B, FAbv, FAbv, FPst, B, + VPre, O,VMPst,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, + B, O, HN, VPre, VBlw, VAbv, IS, VPst, B,VMAbv, H, VAbv,CMBlw,VMPst, O,VMAbv, + CMBlw,FMAbv, B, CS, CS,VMPst, VAbv,VMAbv, VPst, MPst, R, MPst,CMBlw, B,FMBlw, CS, + SUB, SUB, GB,CMAbv, IS, VBlw, IS, R, MBlw, GB, VAbv, R,VMPst, J, SB, SE, + J, HR, G, G, HM, G, O, MPre, MPre, MPst,VMAbv, MBlw, VBlw, O, VBlw, }; -static const uint16_t -hb_use_u16[486] = +static const uint16_t hb_use_u16[488]= { - 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, - 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32, 33, 34, 22, 35, - 36, 0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41, 42, 43, 44, 45, - 46, 47, 31, 0, 48, 49, 22, 50, 51, 52, 18, 0, 53, 49, 22, 54, - 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 61, 62, 10, 63, 64, 65, - 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77, 0, - 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88, - 89, 90, 10, 91, 92, 93, 2, 0, 94, 0, 10, 95, 96, 10, 97, 0, - 98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108, - 109,110, 2, 2,111, 10, 10,112,113, 2,114,115,116, 10,117, 10, - 118,119,120,121,122, 0, 0,123,124,125, 0,126,127,128,129, 0, - 130,131,132, 0, 0,133,134, 0,135, 0, 0, 10,136,137,138, 0, - 139, 10,140, 0, 10,141,142, 10, 10,143,144, 2,145,146,147, 10, - 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, - 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, - 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, - 175, 2,176, 10,177, 0,178,173,179,180,181, 0, 0,182,183, 0, - 184, 10, 10,185,186,187,188,189,190, 10, 10,191,192, 0,193, 10, - 194,195,196, 10, 10,197, 10,198,199,106,200,103, 10, 34,201,202, - 203, 0,204,205, 95, 10, 10,206,207, 2,208, 21, 22,209,210,211, - 212,213,214, 10, 10,215,216,217,218, 0, 10,219,220,221,222, 0, - 200, 10, 10,223,224, 2,225,226,227,228, 10,229,230, 2,231,232, - 2, 10,141, 0, 10,233,234,104,235, 0,236,237,238,239, 10,240, - 241, 2,242, 10, 10,243,244, 0,245, 10, 10,246,247,248,249,250, - 22, 10,225,251, 8, 10, 71, 19, 10,252, 74,253,254, 10, 10,255, - 256, 2,257, 10,258,259, 10,260,261, 49, 10,262,263,264,265,265, - 265,266,267,268,265,269, 10,270,271, 2, 10,272,273, 10,274, 2, - 275,276,277,277,278,279,280, 0, 10,177, 0,281,106, 71, 95,282, - 0,283, 71,284,285, 0,286, 0,287, 2,288, 2,289,106,290, 2, - 130,130,163,163,163,130, + 0, 0, 8, 8, 16, 16, 24, 24, 40, 40, 0, 24, 32, 0, 0, 120, + 136, 24, 56, 0, 168, 24, 240, 24, 272, 32, 280, 288, 0, 296, 304, 0, + 128, 0, 312, 320, 24, 328, 336, 24, 24, 344, 352, 360, 56, 144, 368, 64, + 48, 376, 152, 384, 56, 392, 400, 64, 48, 408, 416, 424, 72, 432, 440, 112, + 48, 448, 456, 0, 56, 464, 472, 64, 48, 480, 152, 488, 56, 496, 504, 512, + 520, 528, 536, 544, 72, 0, 552, 80, 48, 560, 160, 568, 576, 80, 48, 584, + 160, 592, 56, 600, 608, 80, 24, 616, 624, 632, 640, 648, 24, 656, 664, 672, + 72, 680, 688, 696, 24, 704, 88, 712, 720, 176, 728, 736, 744, 0, 752, 760, + 768, 776, 784, 792, 800, 808, 24, 816, 24, 824, 24, 832, 840, 848, 24, 856, + 864, 872, 880, 0, 24, 96, 888, 24, 896, 0, 24, 184, 904, 912, 72, 24, + 920, 192, 200, 24, 928, 104, 24, 936, 24, 944, 952, 960, 32, 32, 968, 24, + 24, 976, 984, 32, 992,1000,1008, 24,1016, 24,1024,1032,1040,1048,1056, 0, + 0,1064,1072,1080, 0,1088,1096,1104,1112, 0, 16,1120,1128, 0, 0,1136, + 1144, 0,1152, 0,1160,1168,1176, 0,1184, 24,1192, 0, 24, 208,1200, 24, + 24,1208,1216, 32,1224,1232,1240, 24,1248,1256,1264, 24, 24,1272,1280, 32, + 1288, 184,1296,1304,1312, 32, 24,1320, 24,1328,1336, 0,1344,1352,1360, 32, + 40, 0, 0,1368, 0,1376, 0, 216, 216,1384, 112,1392,1400,1408, 24,1416, + 96, 0,1424, 0, 24, 224,1432, 0,1440, 32,1448, 24, 232, 0,1456, 224, + 1464,1472,1480, 0, 0,1488,1496, 0,1504, 24, 24,1512,1520,1528,1536,1544, + 24,1552,1560, 0,1568, 24,1576,1584,1592, 24, 24,1600, 24,1608,1616, 104, + 248, 192, 24, 112,1624,1632,1640, 0,1648,1656, 96, 24, 24,1664,1672, 32, + 1680, 64, 48,1688,1696,1704,1712,1720,1728, 24, 24,1736,1744,1752,1760, 0, + 24,1768,1776,1784,1792, 0, 248, 24, 24,1800,1808, 32, 256,1816,1824,1832, + 24,1840,1848, 32,1856,1864, 32, 24, 208, 0, 24,1872,1880, 200,1888, 0, + 1896,1904,1912,1920, 24,1928,1936, 32,1944, 24, 24,1952,1960, 0,1968, 24, + 24,1976,1984,1992,2000,2008,2016, 0, 48, 24, 256,2024, 128, 24, 88, 144, + 24,2032, 176,2040,2048, 24, 24,2056,2064, 32,2072, 24,2080,2088, 24,2096, + 2104, 80, 24,2112,2120,2128, 8,2136,2144,2152, 8,2160, 24,2168,2176, 32, + 24,2184,2192, 24,2200, 32,2208,2216, 264, 264,2224,2232,2240, 0, 24, 232, + 0,2248, 104, 88, 96,2256, 0,2264, 88,2272,2280, 0,2288, 0,2296, 32, + 2304, 32,2312, 104,2320, 32, 40, 16, }; -static inline unsigned -hb_use_b4 (const uint8_t* a, unsigned i) +static inline uint8_t hb_use_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline uint_fast8_t -hb_use_get_category (unsigned u) +static inline uint8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[3265+(((hb_use_u8[937+(((hb_use_u16[((hb_use_u8[369+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + /* packtab: [2^4,2^4,2^3,2^1,2^3,2^1] */ + return u<921600u ? (uint8_t)(hb_use_u8[3273u+((hb_use_u8[945u+hb_use_u16[((hb_use_u8[369u+((hb_use_u8[113u+((hb_use_b4(hb_use_u8,((((((((((u)>>1))>>3))>>1))>>3))>>4)))<<4)+((((((((((u)>>1))>>3))>>1))>>3))&15)])<<3)+((((((((u)>>1))>>3))>>1))&7)])<<1)+((((((u)>>1))>>3))&1)]+((((u)>>1))&7)])<<1)+((u)&1)]) : O; } + #endif + #undef B #undef CGJ #undef CS diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper-vowel-constraints.cc b/thirdparty/harfbuzz/upstream/hb-ot-shaper-vowel-constraints.cc index dbe781e56..eacaaf2ba 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper-vowel-constraints.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper-vowel-constraints.cc @@ -2,7 +2,7 @@ /* * The following functions are generated by running: * - * ./gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt + * gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt * * on files with these headers: * @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-16.0.0.txt - * # Date: 2024-04-30, 21:48:40 GMT + * # Scripts-17.0.0.txt + * # Date: 2025-07-24, 13:28:55 GMT */ #include "hb.hh" @@ -24,7 +24,7 @@ static void _output_dotted_circle (hb_buffer_t *buffer) { (void) buffer->output_glyph (0x25CCu); - _hb_glyph_info_reset_continuation (&buffer->prev()); + _hb_glyph_info_clear_continuation (&buffer->prev()); } static void diff --git a/thirdparty/harfbuzz/upstream/hb-ot-shaper.hh b/thirdparty/harfbuzz/upstream/hb-ot-shaper.hh index 8a094739c..67deb7949 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-shaper.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-shaper.hh @@ -396,6 +396,12 @@ hb_ot_shaper_categorize (hb_script_t script, case HB_SCRIPT_TODHRI: case HB_SCRIPT_TULU_TIGALARI: + /* Unicode-17.0 additions */ + case HB_SCRIPT_BERIA_ERFE: + case HB_SCRIPT_SIDETIC: + case HB_SCRIPT_TAI_YO: + case HB_SCRIPT_TOLONG_SIKI: + /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. * Otherwise, use the specific shaper. diff --git a/thirdparty/harfbuzz/upstream/hb-ot-stat-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-stat-table.hh index 7a46be1ff..ac24dffe0 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-stat-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-stat-table.hh @@ -352,7 +352,7 @@ struct AxisValue { float get_value (unsigned int axis_index) const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_value (); case 2: hb_barrier (); return u.format2.get_value (); @@ -364,7 +364,7 @@ struct AxisValue unsigned int get_axis_index () const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_axis_index (); case 2: hb_barrier (); return u.format2.get_axis_index (); @@ -376,7 +376,7 @@ struct AxisValue hb_ot_name_id_t get_value_name_id () const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.get_value_name_id (); case 2: hb_barrier (); return u.format2.get_value_name_id (); @@ -389,9 +389,9 @@ struct AxisValue template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { - if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); - TRACE_DISPATCH (this, u.format); - switch (u.format) { + if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); + TRACE_DISPATCH (this, u.format.v); + switch (u.format.v) { case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward (ds)...)); case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward (ds)...)); case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward (ds)...)); @@ -403,7 +403,7 @@ struct AxisValue bool keep_axis_value (const hb_array_t axis_records, hb_hashmap_t *user_axes_location) const { - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return u.format1.keep_axis_value (axis_records, user_axes_location); case 2: hb_barrier (); return u.format2.keep_axis_value (axis_records, user_axes_location); @@ -420,7 +420,7 @@ struct AxisValue return_trace (false); hb_barrier (); - switch (u.format) + switch (u.format.v) { case 1: hb_barrier (); return_trace (u.format1.sanitize (c)); case 2: hb_barrier (); return_trace (u.format2.sanitize (c)); @@ -433,14 +433,14 @@ struct AxisValue protected: union { - HBUINT16 format; + struct { HBUINT16 v; } format; AxisValueFormat1 format1; AxisValueFormat2 format2; AxisValueFormat3 format3; AxisValueFormat4 format4; } u; public: - DEFINE_SIZE_UNION (2, format); + DEFINE_SIZE_UNION (2, format.v); }; struct AxisValueOffsetArray: UnsizedArrayOf> diff --git a/thirdparty/harfbuzz/upstream/hb-ot-tag-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-tag-table.hh index 66ba9f1b0..124599e7c 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-tag-table.hh @@ -2,12 +2,12 @@ /* * The following table is generated by running: * - * ./gen-tag-table.py languagetags language-subtag-registry + * gen-tag-table.py languagetags language-subtag-registry * * on files with these headers: * - * - * File-Date: 2024-06-14 + * + * File-Date: 2025-08-25 */ #ifndef HB_OT_TAG_TABLE_HH @@ -221,55 +221,201 @@ static const LangTag ot_languages2[] = { }; #ifndef HB_NO_LANGUAGE_LONG +static const hb_tag_t ot_languages3_blocked[] = { + HB_TAG('a','b','a',' '), /* Abé != Abaza */ + HB_TAG('a','f','k',' '), /* Nanubae != Afrikaans */ + HB_TAG('a','g','w',' '), /* Kahua != Agaw */ + HB_TAG('a','r','i',' '), /* Arikara != Aari */ + HB_TAG('a','r','k',' '), /* Arikapú != Rakhine */ + HB_TAG('b','a','g',' '), /* Tuki != Baghelkhandi */ + HB_TAG('b','a','u',' '), /* Bada (Nigeria) != Baulé */ + HB_TAG('b','b','r',' '), /* Girawa != Berber */ + HB_TAG('b','c','h',' '), /* Bariai != Bench */ + HB_TAG('b','i','l',' '), /* Bile != Bilen */ + HB_TAG('b','k','f',' '), /* Beeke != Blackfoot */ + HB_TAG('b','l','i',' '), /* Bolia != Baluchi */ + HB_TAG('b','l','t',' '), /* Tai Dam != Balti */ + HB_TAG('b','m','b',' '), /* Bembe != Bambara (Bamanankan) */ + HB_TAG('b','m','l',' '), /* Bomboli != Bamileke */ + HB_TAG('b','r','i',' '), /* Mokpwe != Braj Bhasha */ + HB_TAG('b','r','m',' '), /* Barambu != Burmese */ + HB_TAG('b','s','h',' '), /* Kati != Bashkir */ + HB_TAG('b','t','i',' '), /* Burate != Beti */ + HB_TAG('c','h','g',' '), /* Chagatai != Chaha Gurage */ + HB_TAG('c','h','h',' '), /* Chinook != Chattisgarhi */ + HB_TAG('c','r','r',' '), /* Carolina Algonquian != Carrier */ + HB_TAG('c','r','t',' '), /* Iyojwa'ja Chorote != Crimean Tatar */ + HB_TAG('c','s','l',' '), /* Chinese Sign Language != Church Slavonic */ + HB_TAG('d','h','v',' '), /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */ + HB_TAG('d','n','k',' '), /* Dengka != Dinka */ + HB_TAG('d','r','i',' '), /* C'Lela != Dari */ + HB_TAG('d','u','n',' '), /* Dusun Deyah != Dungan */ + HB_TAG('d','z','n',' '), /* Dzando != Dzongkha */ + HB_TAG('e','c','r',' '), /* Eteocretan != Eastern Cree */ + HB_TAG('e','u','q',' '), /* Basque [collection] != Basque */ + HB_TAG('f','a','r',' '), /* Fataleka != Persian */ + HB_TAG('f','o','s',' '), /* Siraya != Faroese */ + HB_TAG('g','a','d',' '), /* Gaddang != Ga */ + HB_TAG('g','a','e',' '), /* Guarequena != Scottish Gaelic */ + HB_TAG('g','a','l',' '), /* Galolen != Galician */ + HB_TAG('g','a','r',' '), /* Galeya != Garshuni */ + HB_TAG('g','a','w',' '), /* Nobonob != Garhwali */ + HB_TAG('g','m','z',' '), /* Mgbolizhia != Gumuz */ + HB_TAG('g','r','o',' '), /* Groma != Garo */ + HB_TAG('g','u','a',' '), /* Shiki != Guarani */ + HB_TAG('h','a','l',' '), /* Halang != Halam (Falam Chin) */ + HB_TAG('h','b','n',' '), /* Heiban != Hammer-Banna */ + HB_TAG('i','r','i',' '), /* Rigwe != Irish */ + HB_TAG('i','s','m',' '), /* Masimasi != Inari Sami */ + HB_TAG('j','a','n',' '), /* Jandai != Japanese */ + HB_TAG('j','i','i',' '), /* Jiiddu != Yiddish */ + HB_TAG('j','u','d',' '), /* Worodougou != Ladino */ + HB_TAG('j','u','l',' '), /* Jirel != Jula */ + HB_TAG('k','a','c',' '), /* Kachin != Kachchi */ + HB_TAG('k','e','b',' '), /* Kélé != Kebena */ + HB_TAG('k','g','e',' '), /* Komering != Khutsuri Georgian */ + HB_TAG('k','h','n',' '), /* Khandesi != Khamti Shan (Microsoft fonts) */ + HB_TAG('k','h','s',' '), /* Kasua != Khanty-Shurishkar */ + HB_TAG('k','h','v',' '), /* Khvarshi != Khanty-Vakhi */ + HB_TAG('k','i','s',' '), /* Kis != Kisii */ + HB_TAG('k','k','n',' '), /* Kon Keu != Kokni */ + HB_TAG('k','l','m',' '), /* Migum != Kalmyk */ + HB_TAG('k','m','n',' '), /* Awtuw != Kumaoni */ + HB_TAG('k','m','o',' '), /* Kwoma != Komo */ + HB_TAG('k','m','s',' '), /* Kamasau != Komso */ + HB_TAG('k','n','r',' '), /* Kaningra != Kanuri */ + HB_TAG('k','o','d',' '), /* Kodi != Kodagu */ + HB_TAG('k','o','h',' '), /* Koyo != Korean Old Hangul */ + HB_TAG('k','o','p',' '), /* Waube != Komi-Permyak */ + HB_TAG('k','o','z',' '), /* Korak != Komi-Zyrian */ + HB_TAG('k','p','l',' '), /* Kpala != Kpelle */ + HB_TAG('k','r','k',' '), /* Kerek != Karakalpak */ + HB_TAG('k','r','m',' '), /* Krim (retired code) != Karaim */ + HB_TAG('k','r','n',' '), /* Sapo != Karen */ + HB_TAG('k','s','i',' '), /* Krisa != Khasi */ + HB_TAG('k','s','m',' '), /* Kumba != Kildin Sami */ + HB_TAG('k','u','i',' '), /* Kuikúro-Kalapálo != Kui */ + HB_TAG('k','u','l',' '), /* Kulere != Kulvi */ + HB_TAG('k','u','y',' '), /* Kuuku-Ya'u != Kuy */ + HB_TAG('k','y','k',' '), /* Kamayo != Koryak */ + HB_TAG('l','a','h',' '), /* Lahnda [macrolanguage] != Lahuli */ + HB_TAG('l','a','k',' '), /* Laka (Nigeria) (retired code) != Lak */ + HB_TAG('l','a','m',' '), /* Lamba != Lambani */ + HB_TAG('l','a','z',' '), /* Aribwatsa != Laz */ + HB_TAG('l','d','k',' '), /* Leelau != Ladakhi */ + HB_TAG('l','m','a',' '), /* East Limba != Low Mari */ + HB_TAG('l','m','b',' '), /* Merei != Limbu */ + HB_TAG('l','m','w',' '), /* Lake Miwok != Lomwe */ + HB_TAG('l','s','b',' '), /* Burundian Sign Language != Lower Sorbian */ + HB_TAG('l','t','h',' '), /* Thur != Lithuanian */ + HB_TAG('l','v','i',' '), /* Lavi != Latvian */ + HB_TAG('m','a','j',' '), /* Jalapa De Díaz Mazatec != Majang */ + HB_TAG('m','a','p',' '), /* Austronesian [collection] != Mapudungun */ + HB_TAG('m','a','w',' '), /* Mampruli != Marwari */ + HB_TAG('m','b','n',' '), /* Macaguán != Mbundu */ + HB_TAG('m','c','h',' '), /* Maquiritari != Manchu */ + HB_TAG('m','c','r',' '), /* Menya != Moose Cree */ + HB_TAG('m','d','e',' '), /* Maba (Chad) != Mende */ + HB_TAG('m','i','z',' '), /* Coatzospan Mixtec != Mizo */ + HB_TAG('m','k','r',' '), /* Malas != Makasar */ + HB_TAG('m','l','e',' '), /* Manambu != Male */ + HB_TAG('m','l','n',' '), /* Malango != Malinke */ + HB_TAG('m','l','r',' '), /* Vame != Malayalam Reformed */ + HB_TAG('m','n','d',' '), /* Mondé != Mandinka */ + HB_TAG('m','n','g',' '), /* Eastern Mnong != Mongolian */ + HB_TAG('m','n','x',' '), /* Manikion != Manx */ + HB_TAG('m','o','k',' '), /* Morori != Moksha */ + HB_TAG('m','o','r',' '), /* Moro != Moroccan */ + HB_TAG('m','t','h',' '), /* Munggui != Maithili */ + HB_TAG('m','t','s',' '), /* Yora != Maltese */ + HB_TAG('m','u','n',' '), /* Munda [collection] != Mundari */ + HB_TAG('n','a','s',' '), /* Naasioi != Naskapi */ + HB_TAG('n','c','r',' '), /* Ncane != N-Cree */ + HB_TAG('n','d','b',' '), /* Kenswei Nsei != Ndebele */ + HB_TAG('n','d','g',' '), /* Ndengereko != Ndonga */ + HB_TAG('n','g','r',' '), /* Engdewu != Nagari */ + HB_TAG('n','i','s',' '), /* Nimi != Nisi */ + HB_TAG('n','k','o',' '), /* Nkonya != N’Ko */ + HB_TAG('n','s','m',' '), /* Sumi Naga != Northern Sami */ + HB_TAG('n','t','o',' '), /* Ntomba != Esperanto */ + HB_TAG('o','r','o',' '), /* Orokolo != Oromo */ + HB_TAG('p','a','a',' '), /* Papuan [collection] != Palestinian Aramaic */ + HB_TAG('p','a','l',' '), /* Pahlavi != Pali */ + HB_TAG('p','a','s',' '), /* Papasena != Pashto */ + HB_TAG('p','i','l',' '), /* Yom != Filipino */ + HB_TAG('p','l','k',' '), /* Kohistani Shina != Polish */ + HB_TAG('r','m','s',' '), /* Romanian Sign Language != Romansh */ + HB_TAG('s','a','d',' '), /* Sandawe != Sadri */ + HB_TAG('s','a','y',' '), /* Saya != Sayisi */ + HB_TAG('s','g','o',' '), /* Songa (retired code) != Sango */ + HB_TAG('s','i','b',' '), /* Sebop != Sibe */ + HB_TAG('s','i','g',' '), /* Paasaal != Silte Gurage */ + HB_TAG('s','k','s',' '), /* Maia != Skolt Sami */ + HB_TAG('s','k','y',' '), /* Sikaiana != Slovak */ + HB_TAG('s','l','a',' '), /* Slavic [collection] != Slavey */ + HB_TAG('s','m','l',' '), /* Central Sama != Somali */ + HB_TAG('s','n','h',' '), /* Shinabo (retired code) != Sinhala (Sinhalese) */ + HB_TAG('s','o','g',' '), /* Sogdian != Sodo Gurage */ + HB_TAG('s','r','b',' '), /* Sora != Serbian */ + HB_TAG('s','r','k',' '), /* Serudung Murut != Saraiki */ + HB_TAG('s','s','l',' '), /* Western Sisaala != South Slavey */ + HB_TAG('s','s','m',' '), /* Semnam != Southern Sami */ + HB_TAG('s','u','r',' '), /* Mwaghavul != Suri */ + HB_TAG('s','v','e',' '), /* Serili != Swedish */ + HB_TAG('s','w','k',' '), /* Malawi Sena != Swahili */ + HB_TAG('t','a','j',' '), /* Eastern Tamang != Tajiki */ + HB_TAG('t','g','n',' '), /* Tandaganon != Tongan */ + HB_TAG('t','g','r',' '), /* Tareng != Tigre */ + HB_TAG('t','g','y',' '), /* Togoyo != Tigrinya */ + HB_TAG('t','k','m',' '), /* Takelma != Turkmen */ + HB_TAG('t','m','n',' '), /* Taman (Indonesia) != Temne */ + HB_TAG('t','n','a',' '), /* Tacana != Tswana */ + HB_TAG('t','n','e',' '), /* Tinoc Kallahan (retired code) != Tundra Enets */ + HB_TAG('t','n','g',' '), /* Tobanga != Tonga */ + HB_TAG('t','r','k',' '), /* Turkic [collection] != Turkish */ + HB_TAG('t','s','g',' '), /* Tausug != Tsonga */ + HB_TAG('t','u','a',' '), /* Wiarumus != Turoyo Aramaic */ + HB_TAG('t','u','l',' '), /* Tula != Tulu */ + HB_TAG('t','u','v',' '), /* Turkana != Tuvin */ + HB_TAG('v','i','t',' '), /* Viti != Vietnamese */ + HB_TAG('w','a','g',' '), /* Wa'ema != Wagdi */ + HB_TAG('x','b','d',' '), /* Bindal != Lü */ + HB_TAG('y','a','k',' '), /* Yakama != Sakha */ + HB_TAG('y','b','a',' '), /* Yala != Yoruba */ + HB_TAG('y','i','m',' '), /* Yimchungru Naga != Yi Modern */ + HB_TAG('z','n','d',' '), /* Zande [collection] != Zande */ +}; + static const LangTag ot_languages3[] = { {HB_TAG('a','a','e',' '), HB_TAG('S','Q','I',' ')}, /* Arbëreshë Albanian -> Albanian */ {HB_TAG('a','a','o',' '), HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */ -/*{HB_TAG('a','a','q',' '), HB_TAG('A','A','Q',' ')},*/ /* Eastern Abnaki -> Eastern Abenaki */ {HB_TAG('a','a','t',' '), HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */ - {HB_TAG('a','b','a',' '), HB_TAG_NONE }, /* Abé != Abaza */ {HB_TAG('a','b','h',' '), HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */ {HB_TAG('a','b','q',' '), HB_TAG('A','B','A',' ')}, /* Abaza */ {HB_TAG('a','b','s',' '), HB_TAG('C','P','P',' ')}, /* Ambonese Malay -> Creoles */ {HB_TAG('a','b','v',' '), HB_TAG('A','R','A',' ')}, /* Baharna Arabic -> Arabic */ - {HB_TAG('a','c','f',' '), HB_TAG('F','A','N',' ')}, /* Saint Lucian Creole French -> French Antillean */ - {HB_TAG('a','c','f',' '), HB_TAG('C','P','P',' ')}, /* Saint Lucian Creole French -> Creoles */ -/*{HB_TAG('a','c','h',' '), HB_TAG('A','C','H',' ')},*/ /* Acoli -> Acholi */ {HB_TAG('a','c','m',' '), HB_TAG('A','R','A',' ')}, /* Mesopotamian Arabic -> Arabic */ {HB_TAG('a','c','q',' '), HB_TAG('A','R','A',' ')}, /* Ta'izzi-Adeni Arabic -> Arabic */ - {HB_TAG('a','c','r',' '), HB_TAG('A','C','R',' ')}, /* Achi */ - {HB_TAG('a','c','r',' '), HB_TAG('M','Y','N',' ')}, /* Achi -> Mayan */ {HB_TAG('a','c','w',' '), HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */ {HB_TAG('a','c','x',' '), HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */ - {HB_TAG('a','c','y',' '), HB_TAG('A','C','Y',' ')}, /* Cypriot Arabic */ - {HB_TAG('a','c','y',' '), HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */ {HB_TAG('a','d','a',' '), HB_TAG('D','N','G',' ')}, /* Adangme -> Dangme */ {HB_TAG('a','d','f',' '), HB_TAG('A','R','A',' ')}, /* Dhofari Arabic -> Arabic */ {HB_TAG('a','d','p',' '), HB_TAG('D','Z','N',' ')}, /* Adap (retired code) -> Dzongkha */ -/*{HB_TAG('a','d','y',' '), HB_TAG('A','D','Y',' ')},*/ /* Adyghe */ {HB_TAG('a','e','b',' '), HB_TAG('A','R','A',' ')}, /* Tunisian Arabic -> Arabic */ {HB_TAG('a','e','c',' '), HB_TAG('A','R','A',' ')}, /* Saidi Arabic -> Arabic */ {HB_TAG('a','f','b',' '), HB_TAG('A','R','A',' ')}, /* Gulf Arabic -> Arabic */ - {HB_TAG('a','f','k',' '), HB_TAG_NONE }, /* Nanubae != Afrikaans */ {HB_TAG('a','f','s',' '), HB_TAG('C','P','P',' ')}, /* Afro-Seminole Creole -> Creoles */ {HB_TAG('a','g','u',' '), HB_TAG('M','Y','N',' ')}, /* Aguacateco -> Mayan */ - {HB_TAG('a','g','w',' '), HB_TAG_NONE }, /* Kahua != Agaw */ {HB_TAG('a','h','g',' '), HB_TAG('A','G','W',' ')}, /* Qimant -> Agaw */ {HB_TAG('a','h','t',' '), HB_TAG('A','T','H',' ')}, /* Ahtena -> Athapaskan */ {HB_TAG('a','i','g',' '), HB_TAG('C','P','P',' ')}, /* Antigua and Barbuda Creole English -> Creoles */ - {HB_TAG('a','i','i',' '), HB_TAG('S','W','A',' ')}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ - {HB_TAG('a','i','i',' '), HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */ -/*{HB_TAG('a','i','o',' '), HB_TAG('A','I','O',' ')},*/ /* Aiton */ {HB_TAG('a','i','w',' '), HB_TAG('A','R','I',' ')}, /* Aari */ {HB_TAG('a','j','p',' '), HB_TAG('A','R','A',' ')}, /* South Levantine Arabic (retired code) -> Arabic */ {HB_TAG('a','j','t',' '), HB_TAG('A','R','A',' ')}, /* Judeo-Tunisian Arabic (retired code) -> Arabic */ - {HB_TAG('a','k','b',' '), HB_TAG('A','K','B',' ')}, /* Batak Angkola */ - {HB_TAG('a','k','b',' '), HB_TAG('B','T','K',' ')}, /* Batak Angkola -> Batak */ {HB_TAG('a','l','n',' '), HB_TAG('S','Q','I',' ')}, /* Gheg Albanian -> Albanian */ {HB_TAG('a','l','s',' '), HB_TAG('S','Q','I',' ')}, /* Tosk Albanian -> Albanian */ -/*{HB_TAG('a','l','t',' '), HB_TAG('A','L','T',' ')},*/ /* Southern Altai -> Altai */ {HB_TAG('a','m','f',' '), HB_TAG('H','B','N',' ')}, /* Hamer-Banna -> Hammer-Banna */ {HB_TAG('a','m','w',' '), HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic -> Syriac */ -/*{HB_TAG('a','n','g',' '), HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */ {HB_TAG('a','o','a',' '), HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */ {HB_TAG('a','p','a',' '), HB_TAG('A','T','H',' ')}, /* Apache [collection] -> Athapaskan */ {HB_TAG('a','p','c',' '), HB_TAG('A','R','A',' ')}, /* Levantine Arabic -> Arabic */ @@ -280,61 +426,39 @@ static const LangTag ot_languages3[] = { {HB_TAG('a','p','m',' '), HB_TAG('A','T','H',' ')}, /* Mescalero-Chiricahua Apache -> Athapaskan */ {HB_TAG('a','p','w',' '), HB_TAG('A','T','H',' ')}, /* Western Apache -> Athapaskan */ {HB_TAG('a','r','b',' '), HB_TAG('A','R','A',' ')}, /* Standard Arabic -> Arabic */ - {HB_TAG('a','r','i',' '), HB_TAG_NONE }, /* Arikara != Aari */ - {HB_TAG('a','r','k',' '), HB_TAG_NONE }, /* Arikapú != Rakhine */ {HB_TAG('a','r','n',' '), HB_TAG('M','A','P',' ')}, /* Mapudungun */ {HB_TAG('a','r','q',' '), HB_TAG('A','R','A',' ')}, /* Algerian Arabic -> Arabic */ {HB_TAG('a','r','s',' '), HB_TAG('A','R','A',' ')}, /* Najdi Arabic -> Arabic */ - {HB_TAG('a','r','y',' '), HB_TAG('M','O','R',' ')}, /* Moroccan Arabic -> Moroccan */ - {HB_TAG('a','r','y',' '), HB_TAG('A','R','A',' ')}, /* Moroccan Arabic -> Arabic */ {HB_TAG('a','r','z',' '), HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */ -/*{HB_TAG('a','s','t',' '), HB_TAG('A','S','T',' ')},*/ /* Asturian */ -/*{HB_TAG('a','t','h',' '), HB_TAG('A','T','H',' ')},*/ /* Athapascan [collection] -> Athapaskan */ {HB_TAG('a','t','j',' '), HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */ -/*{HB_TAG('a','t','s',' '), HB_TAG('A','T','S',' ')},*/ /* Gros Ventre (Atsina) */ {HB_TAG('a','t','v',' '), HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */ {HB_TAG('a','u','j',' '), HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */ {HB_TAG('a','u','z',' '), HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ {HB_TAG('a','v','l',' '), HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ -/*{HB_TAG('a','v','n',' '), HB_TAG('A','V','N',' ')},*/ /* Avatime */ -/*{HB_TAG('a','w','a',' '), HB_TAG('A','W','A',' ')},*/ /* Awadhi */ {HB_TAG('a','y','c',' '), HB_TAG('A','Y','M',' ')}, /* Southern Aymara -> Aymara */ {HB_TAG('a','y','h',' '), HB_TAG('A','R','A',' ')}, /* Hadrami Arabic -> Arabic */ {HB_TAG('a','y','l',' '), HB_TAG('A','R','A',' ')}, /* Libyan Arabic -> Arabic */ {HB_TAG('a','y','n',' '), HB_TAG('A','R','A',' ')}, /* Sanaani Arabic -> Arabic */ {HB_TAG('a','y','p',' '), HB_TAG('A','R','A',' ')}, /* North Mesopotamian Arabic -> Arabic */ {HB_TAG('a','y','r',' '), HB_TAG('A','Y','M',' ')}, /* Central Aymara -> Aymara */ - {HB_TAG('a','z','b',' '), HB_TAG('A','Z','B',' ')}, /* South Azerbaijani -> Torki */ - {HB_TAG('a','z','b',' '), HB_TAG('A','Z','E',' ')}, /* South Azerbaijani -> Azerbaijani */ {HB_TAG('a','z','d',' '), HB_TAG('N','A','H',' ')}, /* Eastern Durango Nahuatl -> Nahuatl */ {HB_TAG('a','z','j',' '), HB_TAG('A','Z','E',' ')}, /* North Azerbaijani -> Azerbaijani */ {HB_TAG('a','z','n',' '), HB_TAG('N','A','H',' ')}, /* Western Durango Nahuatl -> Nahuatl */ {HB_TAG('a','z','z',' '), HB_TAG('N','A','H',' ')}, /* Highland Puebla Nahuatl -> Nahuatl */ {HB_TAG('b','a','d',' '), HB_TAG('B','A','D','0')}, /* Banda [collection] */ - {HB_TAG('b','a','g',' '), HB_TAG_NONE }, /* Tuki != Baghelkhandi */ {HB_TAG('b','a','h',' '), HB_TAG('C','P','P',' ')}, /* Bahamas Creole English -> Creoles */ {HB_TAG('b','a','i',' '), HB_TAG('B','M','L',' ')}, /* Bamileke [collection] */ {HB_TAG('b','a','l',' '), HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */ -/*{HB_TAG('b','a','n',' '), HB_TAG('B','A','N',' ')},*/ /* Balinese */ -/*{HB_TAG('b','a','r',' '), HB_TAG('B','A','R',' ')},*/ /* Bavarian */ - {HB_TAG('b','a','u',' '), HB_TAG_NONE }, /* Bada (Nigeria) != Baulé */ - {HB_TAG('b','b','c',' '), HB_TAG('B','B','C',' ')}, /* Batak Toba */ - {HB_TAG('b','b','c',' '), HB_TAG('B','T','K',' ')}, /* Batak Toba -> Batak */ {HB_TAG('b','b','j',' '), HB_TAG('B','M','L',' ')}, /* Ghomálá' -> Bamileke */ {HB_TAG('b','b','p',' '), HB_TAG('B','A','D','0')}, /* West Central Banda -> Banda */ - {HB_TAG('b','b','r',' '), HB_TAG_NONE }, /* Girawa != Berber */ {HB_TAG('b','b','z',' '), HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic (retired code) -> Arabic */ {HB_TAG('b','c','c',' '), HB_TAG('B','L','I',' ')}, /* Southern Balochi -> Baluchi */ - {HB_TAG('b','c','h',' '), HB_TAG_NONE }, /* Bariai != Bench */ {HB_TAG('b','c','i',' '), HB_TAG('B','A','U',' ')}, /* Baoulé -> Baulé */ {HB_TAG('b','c','l',' '), HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */ {HB_TAG('b','c','q',' '), HB_TAG('B','C','H',' ')}, /* Bench */ {HB_TAG('b','c','r',' '), HB_TAG('A','T','H',' ')}, /* Babine -> Athapaskan */ -/*{HB_TAG('b','d','c',' '), HB_TAG('B','D','C',' ')},*/ /* Emberá-Baudó */ -/*{HB_TAG('b','d','y',' '), HB_TAG('B','D','Y',' ')},*/ /* Bandjalang */ {HB_TAG('b','e','a',' '), HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */ {HB_TAG('b','e','b',' '), HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */ -/*{HB_TAG('b','e','m',' '), HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */ {HB_TAG('b','e','r',' '), HB_TAG('B','B','R',' ')}, /* Berber [collection] */ {HB_TAG('b','e','w',' '), HB_TAG('C','P','P',' ')}, /* Betawi -> Creoles */ {HB_TAG('b','f','l',' '), HB_TAG('B','A','D','0')}, /* Banda-Ndélé -> Banda */ @@ -342,70 +466,35 @@ static const LangTag ot_languages3[] = { {HB_TAG('b','f','t',' '), HB_TAG('B','L','T',' ')}, /* Balti */ {HB_TAG('b','f','u',' '), HB_TAG('L','A','H',' ')}, /* Gahri -> Lahuli */ {HB_TAG('b','f','y',' '), HB_TAG('B','A','G',' ')}, /* Bagheli -> Baghelkhandi */ -/*{HB_TAG('b','g','c',' '), HB_TAG('B','G','C',' ')},*/ /* Haryanvi */ {HB_TAG('b','g','n',' '), HB_TAG('B','L','I',' ')}, /* Western Balochi -> Baluchi */ {HB_TAG('b','g','p',' '), HB_TAG('B','L','I',' ')}, /* Eastern Balochi -> Baluchi */ - {HB_TAG('b','g','q',' '), HB_TAG('B','G','Q',' ')}, /* Bagri */ - {HB_TAG('b','g','q',' '), HB_TAG('R','A','J',' ')}, /* Bagri -> Rajasthani */ {HB_TAG('b','g','r',' '), HB_TAG('Q','I','N',' ')}, /* Bawm Chin -> Chin */ {HB_TAG('b','h','b',' '), HB_TAG('B','H','I',' ')}, /* Bhili */ -/*{HB_TAG('b','h','i',' '), HB_TAG('B','H','I',' ')},*/ /* Bhilali -> Bhili */ {HB_TAG('b','h','k',' '), HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) -> Bikol */ -/*{HB_TAG('b','h','o',' '), HB_TAG('B','H','O',' ')},*/ /* Bhojpuri */ {HB_TAG('b','h','r',' '), HB_TAG('M','L','G',' ')}, /* Bara Malagasy -> Malagasy */ -/*{HB_TAG('b','i','k',' '), HB_TAG('B','I','K',' ')},*/ /* Bikol [macrolanguage] */ - {HB_TAG('b','i','l',' '), HB_TAG_NONE }, /* Bile != Bilen */ {HB_TAG('b','i','n',' '), HB_TAG('E','D','O',' ')}, /* Edo */ {HB_TAG('b','i','u',' '), HB_TAG('Q','I','N',' ')}, /* Biete -> Chin */ -/*{HB_TAG('b','j','j',' '), HB_TAG('B','J','J',' ')},*/ /* Kanauji */ {HB_TAG('b','j','n',' '), HB_TAG('M','L','Y',' ')}, /* Banjar -> Malay */ {HB_TAG('b','j','o',' '), HB_TAG('B','A','D','0')}, /* Mid-Southern Banda -> Banda */ {HB_TAG('b','j','q',' '), HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */ {HB_TAG('b','j','s',' '), HB_TAG('C','P','P',' ')}, /* Bajan -> Creoles */ {HB_TAG('b','j','t',' '), HB_TAG('B','L','N',' ')}, /* Balanta-Ganja -> Balante */ - {HB_TAG('b','k','f',' '), HB_TAG_NONE }, /* Beeke != Blackfoot */ {HB_TAG('b','k','o',' '), HB_TAG('B','M','L',' ')}, /* Kwa' -> Bamileke */ {HB_TAG('b','l','a',' '), HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */ {HB_TAG('b','l','e',' '), HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */ {HB_TAG('b','l','g',' '), HB_TAG('I','B','A',' ')}, /* Balau (retired code) -> Iban */ - {HB_TAG('b','l','i',' '), HB_TAG_NONE }, /* Bolia != Baluchi */ - {HB_TAG('b','l','k',' '), HB_TAG('B','L','K',' ')}, /* Pa’o Karen */ - {HB_TAG('b','l','k',' '), HB_TAG('K','R','N',' ')}, /* Pa'o Karen -> Karen */ {HB_TAG('b','l','n',' '), HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol -> Bikol */ - {HB_TAG('b','l','t',' '), HB_TAG_NONE }, /* Tai Dam != Balti */ - {HB_TAG('b','m','b',' '), HB_TAG_NONE }, /* Bembe != Bambara (Bamanankan) */ - {HB_TAG('b','m','l',' '), HB_TAG_NONE }, /* Bomboli != Bamileke */ {HB_TAG('b','m','m',' '), HB_TAG('M','L','G',' ')}, /* Northern Betsimisaraka Malagasy -> Malagasy */ {HB_TAG('b','p','d',' '), HB_TAG('B','A','D','0')}, /* Banda-Banda -> Banda */ {HB_TAG('b','p','l',' '), HB_TAG('C','P','P',' ')}, /* Broome Pearling Lugger Pidgin -> Creoles */ {HB_TAG('b','p','q',' '), HB_TAG('C','P','P',' ')}, /* Banda Malay -> Creoles */ -/*{HB_TAG('b','p','y',' '), HB_TAG('B','P','Y',' ')},*/ /* Bishnupriya -> Bishnupriya Manipuri */ {HB_TAG('b','q','i',' '), HB_TAG('L','R','C',' ')}, /* Bakhtiari -> Luri */ {HB_TAG('b','q','k',' '), HB_TAG('B','A','D','0')}, /* Banda-Mbrès -> Banda */ {HB_TAG('b','r','a',' '), HB_TAG('B','R','I',' ')}, /* Braj -> Braj Bhasha */ {HB_TAG('b','r','c',' '), HB_TAG('C','P','P',' ')}, /* Berbice Creole Dutch -> Creoles */ -/*{HB_TAG('b','r','h',' '), HB_TAG('B','R','H',' ')},*/ /* Brahui */ - {HB_TAG('b','r','i',' '), HB_TAG_NONE }, /* Mokpwe != Braj Bhasha */ - {HB_TAG('b','r','m',' '), HB_TAG_NONE }, /* Barambu != Burmese */ -/*{HB_TAG('b','r','x',' '), HB_TAG('B','R','X',' ')},*/ /* Bodo (India) */ - {HB_TAG('b','s','h',' '), HB_TAG_NONE }, /* Kati != Bashkir */ -/*{HB_TAG('b','s','k',' '), HB_TAG('B','S','K',' ')},*/ /* Burushaski */ {HB_TAG('b','t','b',' '), HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) (retired code) */ - {HB_TAG('b','t','d',' '), HB_TAG('B','T','D',' ')}, /* Batak Dairi (Pakpak) */ - {HB_TAG('b','t','d',' '), HB_TAG('B','T','K',' ')}, /* Batak Dairi -> Batak */ - {HB_TAG('b','t','i',' '), HB_TAG_NONE }, /* Burate != Beti */ {HB_TAG('b','t','j',' '), HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */ -/*{HB_TAG('b','t','k',' '), HB_TAG('B','T','K',' ')},*/ /* Batak [collection] */ - {HB_TAG('b','t','m',' '), HB_TAG('B','T','M',' ')}, /* Batak Mandailing */ - {HB_TAG('b','t','m',' '), HB_TAG('B','T','K',' ')}, /* Batak Mandailing -> Batak */ {HB_TAG('b','t','o',' '), HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */ - {HB_TAG('b','t','s',' '), HB_TAG('B','T','S',' ')}, /* Batak Simalungun */ - {HB_TAG('b','t','s',' '), HB_TAG('B','T','K',' ')}, /* Batak Simalungun -> Batak */ - {HB_TAG('b','t','x',' '), HB_TAG('B','T','X',' ')}, /* Batak Karo */ - {HB_TAG('b','t','x',' '), HB_TAG('B','T','K',' ')}, /* Batak Karo -> Batak */ - {HB_TAG('b','t','z',' '), HB_TAG('B','T','Z',' ')}, /* Batak Alas-Kluet */ - {HB_TAG('b','t','z',' '), HB_TAG('B','T','K',' ')}, /* Batak Alas-Kluet -> Batak */ -/*{HB_TAG('b','u','g',' '), HB_TAG('B','U','G',' ')},*/ /* Buginese -> Bugis */ {HB_TAG('b','u','m',' '), HB_TAG('B','T','I',' ')}, /* Bulu (Cameroon) -> Beti */ {HB_TAG('b','v','e',' '), HB_TAG('M','L','Y',' ')}, /* Berau Malay -> Malay */ {HB_TAG('b','v','u',' '), HB_TAG('M','L','Y',' ')}, /* Bukit Malay -> Malay */ @@ -415,52 +504,26 @@ static const LangTag ot_languages3[] = { {HB_TAG('b','x','p',' '), HB_TAG('B','T','I',' ')}, /* Bebil -> Beti */ {HB_TAG('b','x','r',' '), HB_TAG('R','B','U',' ')}, /* Russia Buriat -> Russian Buriat */ {HB_TAG('b','y','n',' '), HB_TAG('B','I','L',' ')}, /* Bilin -> Bilen */ - {HB_TAG('b','y','v',' '), HB_TAG('B','Y','V',' ')}, /* Medumba */ - {HB_TAG('b','y','v',' '), HB_TAG('B','M','L',' ')}, /* Medumba -> Bamileke */ {HB_TAG('b','z','c',' '), HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy -> Malagasy */ {HB_TAG('b','z','j',' '), HB_TAG('C','P','P',' ')}, /* Belize Kriol English -> Creoles */ {HB_TAG('b','z','k',' '), HB_TAG('C','P','P',' ')}, /* Nicaragua Creole English -> Creoles */ {HB_TAG('c','a','a',' '), HB_TAG('M','Y','N',' ')}, /* Chortí -> Mayan */ {HB_TAG('c','a','c',' '), HB_TAG('M','Y','N',' ')}, /* Chuj -> Mayan */ - {HB_TAG('c','a','f',' '), HB_TAG('C','R','R',' ')}, /* Southern Carrier -> Carrier */ - {HB_TAG('c','a','f',' '), HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */ - {HB_TAG('c','a','k',' '), HB_TAG('C','A','K',' ')}, /* Kaqchikel */ - {HB_TAG('c','a','k',' '), HB_TAG('M','Y','N',' ')}, /* Kaqchikel -> Mayan */ -/*{HB_TAG('c','a','y',' '), HB_TAG('C','A','Y',' ')},*/ /* Cayuga */ -/*{HB_TAG('c','b','g',' '), HB_TAG('C','B','G',' ')},*/ /* Chimila */ - {HB_TAG('c','b','k',' '), HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */ - {HB_TAG('c','b','k',' '), HB_TAG('C','P','P',' ')}, /* Chavacano -> Creoles */ {HB_TAG('c','b','l',' '), HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */ {HB_TAG('c','c','l',' '), HB_TAG('C','P','P',' ')}, /* Cutchi-Swahili -> Creoles */ {HB_TAG('c','c','m',' '), HB_TAG('C','P','P',' ')}, /* Malaccan Creole Malay -> Creoles */ {HB_TAG('c','c','o',' '), HB_TAG('C','C','H','N')}, /* Comaltepec Chinantec -> Chinantec */ {HB_TAG('c','c','q',' '), HB_TAG('A','R','K',' ')}, /* Chaungtha (retired code) -> Rakhine */ {HB_TAG('c','d','o',' '), HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese, Simplified */ -/*{HB_TAG('c','e','b',' '), HB_TAG('C','E','B',' ')},*/ /* Cebuano */ {HB_TAG('c','e','k',' '), HB_TAG('Q','I','N',' ')}, /* Eastern Khumi Chin -> Chin */ {HB_TAG('c','e','y',' '), HB_TAG('Q','I','N',' ')}, /* Ekai Chin -> Chin */ - {HB_TAG('c','f','m',' '), HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) */ - {HB_TAG('c','f','m',' '), HB_TAG('Q','I','N',' ')}, /* Falam Chin -> Chin */ -/*{HB_TAG('c','g','g',' '), HB_TAG('C','G','G',' ')},*/ /* Chiga */ {HB_TAG('c','h','f',' '), HB_TAG('M','Y','N',' ')}, /* Tabasco Chontal -> Mayan */ - {HB_TAG('c','h','g',' '), HB_TAG_NONE }, /* Chagatai != Chaha Gurage */ - {HB_TAG('c','h','h',' '), HB_TAG_NONE }, /* Chinook != Chattisgarhi */ {HB_TAG('c','h','j',' '), HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */ {HB_TAG('c','h','k',' '), HB_TAG('C','H','K','0')}, /* Chuukese */ - {HB_TAG('c','h','m',' '), HB_TAG('H','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> High Mari */ - {HB_TAG('c','h','m',' '), HB_TAG('L','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> Low Mari */ {HB_TAG('c','h','n',' '), HB_TAG('C','P','P',' ')}, /* Chinook jargon -> Creoles */ -/*{HB_TAG('c','h','o',' '), HB_TAG('C','H','O',' ')},*/ /* Choctaw */ - {HB_TAG('c','h','p',' '), HB_TAG('C','H','P',' ')}, /* Chipewyan */ - {HB_TAG('c','h','p',' '), HB_TAG('S','A','Y',' ')}, /* Chipewyan -> Sayisi */ - {HB_TAG('c','h','p',' '), HB_TAG('A','T','H',' ')}, /* Chipewyan -> Athapaskan */ {HB_TAG('c','h','q',' '), HB_TAG('C','C','H','N')}, /* Quiotepec Chinantec -> Chinantec */ -/*{HB_TAG('c','h','r',' '), HB_TAG('C','H','R',' ')},*/ /* Cherokee */ -/*{HB_TAG('c','h','y',' '), HB_TAG('C','H','Y',' ')},*/ /* Cheyenne */ {HB_TAG('c','h','z',' '), HB_TAG('C','C','H','N')}, /* Ozumacín Chinantec -> Chinantec */ {HB_TAG('c','i','w',' '), HB_TAG('O','J','B',' ')}, /* Chippewa -> Ojibway */ -/*{HB_TAG('c','j','a',' '), HB_TAG('C','J','A',' ')},*/ /* Western Cham */ -/*{HB_TAG('c','j','m',' '), HB_TAG('C','J','M',' ')},*/ /* Eastern Cham */ {HB_TAG('c','j','y',' '), HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese, Simplified */ {HB_TAG('c','k','a',' '), HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin (retired code) -> Chin */ {HB_TAG('c','k','b',' '), HB_TAG('K','U','R',' ')}, /* Central Kurdish -> Kurdish */ @@ -474,7 +537,6 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','l','j',' '), HB_TAG('Q','I','N',' ')}, /* Laitu Chin -> Chin */ {HB_TAG('c','l','s',' '), HB_TAG('S','A','N',' ')}, /* Classical Sanskrit -> Sanskrit */ {HB_TAG('c','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Lautu Chin -> Chin */ -/*{HB_TAG('c','m','i',' '), HB_TAG('C','M','I',' ')},*/ /* Emberá-Chamí */ {HB_TAG('c','m','n',' '), HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese, Simplified */ {HB_TAG('c','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ {HB_TAG('c','n','b',' '), HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */ @@ -488,120 +550,63 @@ static const LangTag ot_languages3[] = { {HB_TAG('c','n','w',' '), HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */ {HB_TAG('c','o','a',' '), HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */ {HB_TAG('c','o','b',' '), HB_TAG('M','Y','N',' ')}, /* Chicomuceltec -> Mayan */ -/*{HB_TAG('c','o','o',' '), HB_TAG('C','O','O',' ')},*/ /* Comox */ -/*{HB_TAG('c','o','p',' '), HB_TAG('C','O','P',' ')},*/ /* Coptic */ {HB_TAG('c','o','q',' '), HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */ {HB_TAG('c','p','a',' '), HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */ {HB_TAG('c','p','e',' '), HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [collection] -> Creoles */ {HB_TAG('c','p','f',' '), HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [collection] -> Creoles */ {HB_TAG('c','p','i',' '), HB_TAG('C','P','P',' ')}, /* Chinese Pidgin English -> Creoles */ -/*{HB_TAG('c','p','p',' '), HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [collection] -> Creoles */ {HB_TAG('c','p','x',' '), HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese, Simplified */ {HB_TAG('c','q','d',' '), HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */ - {HB_TAG('c','q','u',' '), HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ - {HB_TAG('c','q','u',' '), HB_TAG('Q','U','Z',' ')}, /* Chilean Quechua (retired code) -> Quechua */ {HB_TAG('c','r','h',' '), HB_TAG('C','R','T',' ')}, /* Crimean Tatar */ {HB_TAG('c','r','i',' '), HB_TAG('C','P','P',' ')}, /* Sãotomense -> Creoles */ - {HB_TAG('c','r','j',' '), HB_TAG('E','C','R',' ')}, /* Southern East Cree -> Eastern Cree */ - {HB_TAG('c','r','j',' '), HB_TAG('Y','C','R',' ')}, /* Southern East Cree -> Y-Cree */ - {HB_TAG('c','r','j',' '), HB_TAG('C','R','E',' ')}, /* Southern East Cree -> Cree */ - {HB_TAG('c','r','k',' '), HB_TAG('W','C','R',' ')}, /* Plains Cree -> West-Cree */ - {HB_TAG('c','r','k',' '), HB_TAG('Y','C','R',' ')}, /* Plains Cree -> Y-Cree */ - {HB_TAG('c','r','k',' '), HB_TAG('C','R','E',' ')}, /* Plains Cree -> Cree */ - {HB_TAG('c','r','l',' '), HB_TAG('E','C','R',' ')}, /* Northern East Cree -> Eastern Cree */ - {HB_TAG('c','r','l',' '), HB_TAG('Y','C','R',' ')}, /* Northern East Cree -> Y-Cree */ - {HB_TAG('c','r','l',' '), HB_TAG('C','R','E',' ')}, /* Northern East Cree -> Cree */ - {HB_TAG('c','r','m',' '), HB_TAG('M','C','R',' ')}, /* Moose Cree */ - {HB_TAG('c','r','m',' '), HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */ - {HB_TAG('c','r','m',' '), HB_TAG('C','R','E',' ')}, /* Moose Cree -> Cree */ {HB_TAG('c','r','p',' '), HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [collection] -> Creoles */ - {HB_TAG('c','r','r',' '), HB_TAG_NONE }, /* Carolina Algonquian != Carrier */ {HB_TAG('c','r','s',' '), HB_TAG('C','P','P',' ')}, /* Seselwa Creole French -> Creoles */ - {HB_TAG('c','r','t',' '), HB_TAG_NONE }, /* Iyojwa'ja Chorote != Crimean Tatar */ - {HB_TAG('c','r','x',' '), HB_TAG('C','R','R',' ')}, /* Carrier */ - {HB_TAG('c','r','x',' '), HB_TAG('A','T','H',' ')}, /* Carrier -> Athapaskan */ {HB_TAG('c','s','a',' '), HB_TAG('C','C','H','N')}, /* Chiltepec Chinantec -> Chinantec */ -/*{HB_TAG('c','s','b',' '), HB_TAG('C','S','B',' ')},*/ /* Kashubian */ {HB_TAG('c','s','h',' '), HB_TAG('Q','I','N',' ')}, /* Asho Chin -> Chin */ {HB_TAG('c','s','j',' '), HB_TAG('Q','I','N',' ')}, /* Songlai Chin -> Chin */ - {HB_TAG('c','s','l',' '), HB_TAG_NONE }, /* Chinese Sign Language != Church Slavonic */ {HB_TAG('c','s','o',' '), HB_TAG('C','C','H','N')}, /* Sochiapam Chinantec -> Chinantec */ {HB_TAG('c','s','p',' '), HB_TAG('Z','H','S',' ')}, /* Southern Ping Chinese -> Chinese, Simplified */ {HB_TAG('c','s','v',' '), HB_TAG('Q','I','N',' ')}, /* Sumtu Chin -> Chin */ - {HB_TAG('c','s','w',' '), HB_TAG('N','C','R',' ')}, /* Swampy Cree -> N-Cree */ - {HB_TAG('c','s','w',' '), HB_TAG('N','H','C',' ')}, /* Swampy Cree -> Norway House Cree */ - {HB_TAG('c','s','w',' '), HB_TAG('C','R','E',' ')}, /* Swampy Cree -> Cree */ {HB_TAG('c','s','y',' '), HB_TAG('Q','I','N',' ')}, /* Siyin Chin -> Chin */ {HB_TAG('c','t','c',' '), HB_TAG('A','T','H',' ')}, /* Chetco -> Athapaskan */ {HB_TAG('c','t','d',' '), HB_TAG('Q','I','N',' ')}, /* Tedim Chin -> Chin */ {HB_TAG('c','t','e',' '), HB_TAG('C','C','H','N')}, /* Tepinapa Chinantec -> Chinantec */ -/*{HB_TAG('c','t','g',' '), HB_TAG('C','T','G',' ')},*/ /* Chittagonian */ {HB_TAG('c','t','h',' '), HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */ {HB_TAG('c','t','l',' '), HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ -/*{HB_TAG('c','t','o',' '), HB_TAG('C','T','O',' ')},*/ /* Emberá-Catío */ {HB_TAG('c','t','s',' '), HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ -/*{HB_TAG('c','t','t',' '), HB_TAG('C','T','T',' ')},*/ /* Wayanad Chetti */ {HB_TAG('c','t','u',' '), HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */ {HB_TAG('c','u','c',' '), HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */ -/*{HB_TAG('c','u','k',' '), HB_TAG('C','U','K',' ')},*/ /* San Blas Kuna */ {HB_TAG('c','v','n',' '), HB_TAG('C','C','H','N')}, /* Valle Nacional Chinantec -> Chinantec */ - {HB_TAG('c','w','d',' '), HB_TAG('D','C','R',' ')}, /* Woods Cree */ - {HB_TAG('c','w','d',' '), HB_TAG('T','C','R',' ')}, /* Woods Cree -> TH-Cree */ - {HB_TAG('c','w','d',' '), HB_TAG('C','R','E',' ')}, /* Woods Cree -> Cree */ {HB_TAG('c','z','h',' '), HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese, Simplified */ {HB_TAG('c','z','o',' '), HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese, Simplified */ {HB_TAG('c','z','t',' '), HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */ -/*{HB_TAG('d','a','g',' '), HB_TAG('D','A','G',' ')},*/ /* Dagbani */ {HB_TAG('d','a','o',' '), HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */ {HB_TAG('d','a','p',' '), HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */ -/*{HB_TAG('d','a','r',' '), HB_TAG('D','A','R',' ')},*/ /* Dargwa */ -/*{HB_TAG('d','a','x',' '), HB_TAG('D','A','X',' ')},*/ /* Dayi */ {HB_TAG('d','c','r',' '), HB_TAG('C','P','P',' ')}, /* Negerhollands -> Creoles */ - {HB_TAG('d','e','n',' '), HB_TAG('S','L','A',' ')}, /* Slave (Athapascan) [macrolanguage] -> Slavey */ - {HB_TAG('d','e','n',' '), HB_TAG('A','T','H',' ')}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ {HB_TAG('d','e','p',' '), HB_TAG('C','P','P',' ')}, /* Pidgin Delaware -> Creoles */ - {HB_TAG('d','g','o',' '), HB_TAG('D','G','O',' ')}, /* Dogri (individual language) */ - {HB_TAG('d','g','o',' '), HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) */ {HB_TAG('d','g','r',' '), HB_TAG('A','T','H',' ')}, /* Tlicho -> Athapaskan */ {HB_TAG('d','h','d',' '), HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */ -/*{HB_TAG('d','h','g',' '), HB_TAG('D','H','G',' ')},*/ /* Dhangu */ - {HB_TAG('d','h','v',' '), HB_TAG_NONE }, /* Dehu != Divehi (Dhivehi, Maldivian) (deprecated) */ {HB_TAG('d','i','b',' '), HB_TAG('D','N','K',' ')}, /* South Central Dinka -> Dinka */ {HB_TAG('d','i','k',' '), HB_TAG('D','N','K',' ')}, /* Southwestern Dinka -> Dinka */ {HB_TAG('d','i','n',' '), HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ {HB_TAG('d','i','p',' '), HB_TAG('D','N','K',' ')}, /* Northeastern Dinka -> Dinka */ - {HB_TAG('d','i','q',' '), HB_TAG('D','I','Q',' ')}, /* Dimli */ - {HB_TAG('d','i','q',' '), HB_TAG('Z','Z','A',' ')}, /* Dimli -> Zazaki */ {HB_TAG('d','i','w',' '), HB_TAG('D','N','K',' ')}, /* Northwestern Dinka -> Dinka */ {HB_TAG('d','j','e',' '), HB_TAG('D','J','R',' ')}, /* Zarma */ {HB_TAG('d','j','k',' '), HB_TAG('C','P','P',' ')}, /* Eastern Maroon Creole -> Creoles */ {HB_TAG('d','j','r',' '), HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */ {HB_TAG('d','k','s',' '), HB_TAG('D','N','K',' ')}, /* Southeastern Dinka -> Dinka */ {HB_TAG('d','n','g',' '), HB_TAG('D','U','N',' ')}, /* Dungan */ -/*{HB_TAG('d','n','j',' '), HB_TAG('D','N','J',' ')},*/ /* Dan */ - {HB_TAG('d','n','k',' '), HB_TAG_NONE }, /* Dengka != Dinka */ {HB_TAG('d','o','i',' '), HB_TAG('D','G','R',' ')}, /* Dogri (macrolanguage) [macrolanguage] */ {HB_TAG('d','r','h',' '), HB_TAG('M','N','G',' ')}, /* Darkhat (retired code) -> Mongolian */ - {HB_TAG('d','r','i',' '), HB_TAG_NONE }, /* C'Lela != Dari */ - {HB_TAG('d','r','w',' '), HB_TAG('D','R','I',' ')}, /* Darwazi (retired code) -> Dari */ - {HB_TAG('d','r','w',' '), HB_TAG('F','A','R',' ')}, /* Darwazi (retired code) -> Persian */ {HB_TAG('d','s','b',' '), HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ {HB_TAG('d','t','y',' '), HB_TAG('N','E','P',' ')}, /* Dotyali -> Nepali */ -/*{HB_TAG('d','u','j',' '), HB_TAG('D','U','J',' ')},*/ /* Dhuwal (retired code) */ - {HB_TAG('d','u','n',' '), HB_TAG_NONE }, /* Dusun Deyah != Dungan */ {HB_TAG('d','u','p',' '), HB_TAG('M','L','Y',' ')}, /* Duano -> Malay */ {HB_TAG('d','w','k',' '), HB_TAG('K','U','I',' ')}, /* Dawik Kui -> Kui */ {HB_TAG('d','w','u',' '), HB_TAG('D','U','J',' ')}, /* Dhuwal */ {HB_TAG('d','w','y',' '), HB_TAG('D','U','J',' ')}, /* Dhuwaya -> Dhuwal */ {HB_TAG('d','y','u',' '), HB_TAG('J','U','L',' ')}, /* Dyula -> Jula */ - {HB_TAG('d','z','n',' '), HB_TAG_NONE }, /* Dzando != Dzongkha */ - {HB_TAG('e','c','r',' '), HB_TAG_NONE }, /* Eteocretan != Eastern Cree */ -/*{HB_TAG('e','f','i',' '), HB_TAG('E','F','I',' ')},*/ /* Efik */ {HB_TAG('e','k','k',' '), HB_TAG('E','T','I',' ')}, /* Standard Estonian -> Estonian */ {HB_TAG('e','k','y',' '), HB_TAG('K','R','N',' ')}, /* Eastern Kayah -> Karen */ - {HB_TAG('e','m','k',' '), HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */ - {HB_TAG('e','m','k',' '), HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */ -/*{HB_TAG('e','m','p',' '), HB_TAG('E','M','P',' ')},*/ /* Northern Emberá */ {HB_TAG('e','m','y',' '), HB_TAG('M','Y','N',' ')}, /* Epigraphic Mayan -> Mayan */ {HB_TAG('e','n','b',' '), HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */ {HB_TAG('e','n','f',' '), HB_TAG('F','N','E',' ')}, /* Forest Enets */ @@ -609,52 +614,27 @@ static const LangTag ot_languages3[] = { {HB_TAG('e','s','g',' '), HB_TAG('G','O','N',' ')}, /* Aheri Gondi -> Gondi */ {HB_TAG('e','s','i',' '), HB_TAG('I','P','K',' ')}, /* North Alaskan Inupiatun -> Inupiat */ {HB_TAG('e','s','k',' '), HB_TAG('I','P','K',' ')}, /* Northwest Alaska Inupiatun -> Inupiat */ -/*{HB_TAG('e','s','u',' '), HB_TAG('E','S','U',' ')},*/ /* Central Yupik */ {HB_TAG('e','t','o',' '), HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */ - {HB_TAG('e','u','q',' '), HB_TAG_NONE }, /* Basque [collection] != Basque */ {HB_TAG('e','v','e',' '), HB_TAG('E','V','N',' ')}, /* Even */ {HB_TAG('e','v','n',' '), HB_TAG('E','V','K',' ')}, /* Evenki */ {HB_TAG('e','w','o',' '), HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */ {HB_TAG('e','y','o',' '), HB_TAG('K','A','L',' ')}, /* Keiyo -> Kalenjin */ {HB_TAG('f','a','b',' '), HB_TAG('C','P','P',' ')}, /* Fa d'Ambu -> Creoles */ - {HB_TAG('f','a','n',' '), HB_TAG('F','A','N','0')}, /* Fang (Equatorial Guinea) */ - {HB_TAG('f','a','n',' '), HB_TAG('B','T','I',' ')}, /* Fang (Equatorial Guinea) -> Beti */ - {HB_TAG('f','a','r',' '), HB_TAG_NONE }, /* Fataleka != Persian */ - {HB_TAG('f','a','t',' '), HB_TAG('F','A','T',' ')}, /* Fanti */ - {HB_TAG('f','a','t',' '), HB_TAG('A','K','A',' ')}, /* Fanti -> Akan */ {HB_TAG('f','b','l',' '), HB_TAG('B','I','K',' ')}, /* West Albay Bikol -> Bikol */ {HB_TAG('f','f','m',' '), HB_TAG('F','U','L',' ')}, /* Maasina Fulfulde -> Fulah */ {HB_TAG('f','i','l',' '), HB_TAG('P','I','L',' ')}, /* Filipino */ - {HB_TAG('f','l','m',' '), HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) (retired code) */ - {HB_TAG('f','l','m',' '), HB_TAG('Q','I','N',' ')}, /* Falam Chin (retired code) -> Chin */ - {HB_TAG('f','m','p',' '), HB_TAG('F','M','P',' ')}, /* Fe’fe’ */ - {HB_TAG('f','m','p',' '), HB_TAG('B','M','L',' ')}, /* Fe'fe' -> Bamileke */ {HB_TAG('f','n','g',' '), HB_TAG('C','P','P',' ')}, /* Fanagalo -> Creoles */ -/*{HB_TAG('f','o','n',' '), HB_TAG('F','O','N',' ')},*/ /* Fon */ - {HB_TAG('f','o','s',' '), HB_TAG_NONE }, /* Siraya != Faroese */ {HB_TAG('f','p','e',' '), HB_TAG('C','P','P',' ')}, /* Fernando Po Creole English -> Creoles */ -/*{HB_TAG('f','r','c',' '), HB_TAG('F','R','C',' ')},*/ /* Cajun French */ -/*{HB_TAG('f','r','p',' '), HB_TAG('F','R','P',' ')},*/ /* Arpitan */ {HB_TAG('f','u','b',' '), HB_TAG('F','U','L',' ')}, /* Adamawa Fulfulde -> Fulah */ {HB_TAG('f','u','c',' '), HB_TAG('F','U','L',' ')}, /* Pulaar -> Fulah */ {HB_TAG('f','u','e',' '), HB_TAG('F','U','L',' ')}, /* Borgu Fulfulde -> Fulah */ - {HB_TAG('f','u','f',' '), HB_TAG('F','T','A',' ')}, /* Pular -> Futa */ - {HB_TAG('f','u','f',' '), HB_TAG('F','U','L',' ')}, /* Pular -> Fulah */ {HB_TAG('f','u','h',' '), HB_TAG('F','U','L',' ')}, /* Western Niger Fulfulde -> Fulah */ {HB_TAG('f','u','i',' '), HB_TAG('F','U','L',' ')}, /* Bagirmi Fulfulde -> Fulah */ {HB_TAG('f','u','q',' '), HB_TAG('F','U','L',' ')}, /* Central-Eastern Niger Fulfulde -> Fulah */ {HB_TAG('f','u','r',' '), HB_TAG('F','R','L',' ')}, /* Friulian */ - {HB_TAG('f','u','v',' '), HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ - {HB_TAG('f','u','v',' '), HB_TAG('F','U','L',' ')}, /* Nigerian Fulfulde -> Fulah */ {HB_TAG('g','a','a',' '), HB_TAG('G','A','D',' ')}, /* Ga */ {HB_TAG('g','a','c',' '), HB_TAG('C','P','P',' ')}, /* Mixed Great Andamanese -> Creoles */ - {HB_TAG('g','a','d',' '), HB_TAG_NONE }, /* Gaddang != Ga */ - {HB_TAG('g','a','e',' '), HB_TAG_NONE }, /* Guarequena != Scottish Gaelic */ -/*{HB_TAG('g','a','g',' '), HB_TAG('G','A','G',' ')},*/ /* Gagauz */ - {HB_TAG('g','a','l',' '), HB_TAG_NONE }, /* Galolen != Galician */ {HB_TAG('g','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese, Simplified */ - {HB_TAG('g','a','r',' '), HB_TAG_NONE }, /* Galeya != Garshuni */ - {HB_TAG('g','a','w',' '), HB_TAG_NONE }, /* Nobonob != Garhwali */ {HB_TAG('g','a','x',' '), HB_TAG('O','R','O',' ')}, /* Borana-Arsi-Guji Oromo -> Oromo */ {HB_TAG('g','a','z',' '), HB_TAG('O','R','O',' ')}, /* West Central Oromo -> Oromo */ {HB_TAG('g','b','m',' '), HB_TAG('G','A','W',' ')}, /* Garhwali */ @@ -663,69 +643,46 @@ static const LangTag ot_languages3[] = { {HB_TAG('g','c','l',' '), HB_TAG('C','P','P',' ')}, /* Grenadian Creole English -> Creoles */ {HB_TAG('g','c','r',' '), HB_TAG('C','P','P',' ')}, /* Guianese Creole French -> Creoles */ {HB_TAG('g','d','a',' '), HB_TAG('R','A','J',' ')}, /* Gade Lohar -> Rajasthani */ -/*{HB_TAG('g','e','z',' '), HB_TAG('G','E','Z',' ')},*/ /* Geez */ {HB_TAG('g','g','o',' '), HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */ {HB_TAG('g','h','a',' '), HB_TAG('B','B','R',' ')}, /* Ghadamès -> Berber */ {HB_TAG('g','h','c',' '), HB_TAG('I','R','T',' ')}, /* Hiberno-Scottish Gaelic -> Irish Traditional */ {HB_TAG('g','h','k',' '), HB_TAG('K','R','N',' ')}, /* Geko Karen -> Karen */ {HB_TAG('g','h','o',' '), HB_TAG('B','B','R',' ')}, /* Ghomara -> Berber */ {HB_TAG('g','i','b',' '), HB_TAG('C','P','P',' ')}, /* Gibanawa -> Creoles */ -/*{HB_TAG('g','i','h',' '), HB_TAG('G','I','H',' ')},*/ /* Githabul */ {HB_TAG('g','i','l',' '), HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */ {HB_TAG('g','j','u',' '), HB_TAG('R','A','J',' ')}, /* Gujari -> Rajasthani */ - {HB_TAG('g','k','p',' '), HB_TAG('G','K','P',' ')}, /* Guinea Kpelle -> Kpelle (Guinea) */ - {HB_TAG('g','k','p',' '), HB_TAG('K','P','L',' ')}, /* Guinea Kpelle -> Kpelle */ {HB_TAG('g','l','d',' '), HB_TAG('N','A','N',' ')}, /* Nanai */ -/*{HB_TAG('g','l','k',' '), HB_TAG('G','L','K',' ')},*/ /* Gilaki */ - {HB_TAG('g','m','z',' '), HB_TAG_NONE }, /* Mgbolizhia != Gumuz */ {HB_TAG('g','n','b',' '), HB_TAG('Q','I','N',' ')}, /* Gangte -> Chin */ -/*{HB_TAG('g','n','n',' '), HB_TAG('G','N','N',' ')},*/ /* Gumatj */ {HB_TAG('g','n','o',' '), HB_TAG('G','O','N',' ')}, /* Northern Gondi -> Gondi */ {HB_TAG('g','n','w',' '), HB_TAG('G','U','A',' ')}, /* Western Bolivian Guaraní -> Guarani */ -/*{HB_TAG('g','o','g',' '), HB_TAG('G','O','G',' ')},*/ /* Gogo */ {HB_TAG('g','o','m',' '), HB_TAG('K','O','K',' ')}, /* Goan Konkani -> Konkani */ -/*{HB_TAG('g','o','n',' '), HB_TAG('G','O','N',' ')},*/ /* Gondi [macrolanguage] */ {HB_TAG('g','o','q',' '), HB_TAG('C','P','P',' ')}, /* Gorap -> Creoles */ {HB_TAG('g','o','x',' '), HB_TAG('B','A','D','0')}, /* Gobu -> Banda */ {HB_TAG('g','p','e',' '), HB_TAG('C','P','P',' ')}, /* Ghanaian Pidgin English -> Creoles */ - {HB_TAG('g','r','o',' '), HB_TAG_NONE }, /* Groma != Garo */ {HB_TAG('g','r','r',' '), HB_TAG('B','B','R',' ')}, /* Taznatit -> Berber */ {HB_TAG('g','r','t',' '), HB_TAG('G','R','O',' ')}, /* Garo */ {HB_TAG('g','r','u',' '), HB_TAG('S','O','G',' ')}, /* Kistane -> Sodo Gurage */ {HB_TAG('g','s','w',' '), HB_TAG('A','L','S',' ')}, /* Alsatian */ - {HB_TAG('g','u','a',' '), HB_TAG_NONE }, /* Shiki != Guarani */ -/*{HB_TAG('g','u','c',' '), HB_TAG('G','U','C',' ')},*/ /* Wayuu */ -/*{HB_TAG('g','u','f',' '), HB_TAG('G','U','F',' ')},*/ /* Gupapuyngu */ {HB_TAG('g','u','g',' '), HB_TAG('G','U','A',' ')}, /* Paraguayan Guaraní -> Guarani */ {HB_TAG('g','u','i',' '), HB_TAG('G','U','A',' ')}, /* Eastern Bolivian Guaraní -> Guarani */ {HB_TAG('g','u','k',' '), HB_TAG('G','M','Z',' ')}, /* Gumuz */ {HB_TAG('g','u','l',' '), HB_TAG('C','P','P',' ')}, /* Sea Island Creole English -> Creoles */ {HB_TAG('g','u','n',' '), HB_TAG('G','U','A',' ')}, /* Mbyá Guaraní -> Guarani */ -/*{HB_TAG('g','u','z',' '), HB_TAG('G','U','Z',' ')},*/ /* Gusii */ {HB_TAG('g','w','i',' '), HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ {HB_TAG('g','y','n',' '), HB_TAG('C','P','P',' ')}, /* Guyanese Creole English -> Creoles */ - {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ + {HB_TAG('h','a','a',' '), HB_TAG('A','T','H',' ')}, /* Hän -> Athapaskan */ {HB_TAG('h','a','e',' '), HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ {HB_TAG('h','a','i',' '), HB_TAG('H','A','I','0')}, /* Haida [macrolanguage] */ {HB_TAG('h','a','k',' '), HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */ - {HB_TAG('h','a','l',' '), HB_TAG_NONE }, /* Halang != Halam (Falam Chin) */ {HB_TAG('h','a','r',' '), HB_TAG('H','R','I',' ')}, /* Harari */ -/*{HB_TAG('h','a','w',' '), HB_TAG('H','A','W',' ')},*/ /* Hawaiian */ {HB_TAG('h','a','x',' '), HB_TAG('H','A','I','0')}, /* Southern Haida -> Haida */ -/*{HB_TAG('h','a','y',' '), HB_TAG('H','A','Y',' ')},*/ /* Haya */ -/*{HB_TAG('h','a','z',' '), HB_TAG('H','A','Z',' ')},*/ /* Hazaragi */ - {HB_TAG('h','b','n',' '), HB_TAG_NONE }, /* Heiban != Hammer-Banna */ {HB_TAG('h','c','a',' '), HB_TAG('C','P','P',' ')}, /* Andaman Creole Hindi -> Creoles */ {HB_TAG('h','d','n',' '), HB_TAG('H','A','I','0')}, /* Northern Haida -> Haida */ {HB_TAG('h','e','a',' '), HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */ -/*{HB_TAG('h','e','i',' '), HB_TAG('H','E','I',' ')},*/ /* Heiltsuk */ -/*{HB_TAG('h','i','l',' '), HB_TAG('H','I','L',' ')},*/ /* Hiligaynon */ {HB_TAG('h','j','i',' '), HB_TAG('M','L','Y',' ')}, /* Haji -> Malay */ {HB_TAG('h','l','t',' '), HB_TAG('Q','I','N',' ')}, /* Matu Chin -> Chin */ {HB_TAG('h','m','a',' '), HB_TAG('H','M','N',' ')}, /* Southern Mashan Hmong -> Hmong */ {HB_TAG('h','m','c',' '), HB_TAG('H','M','N',' ')}, /* Central Huishui Hmong -> Hmong */ - {HB_TAG('h','m','d',' '), HB_TAG('H','M','D',' ')}, /* Large Flowery Miao -> A-Hmao */ - {HB_TAG('h','m','d',' '), HB_TAG('H','M','N',' ')}, /* Large Flowery Miao -> Hmong */ {HB_TAG('h','m','e',' '), HB_TAG('H','M','N',' ')}, /* Eastern Huishui Hmong -> Hmong */ {HB_TAG('h','m','g',' '), HB_TAG('H','M','N',' ')}, /* Southwestern Guiyang Hmong -> Hmong */ {HB_TAG('h','m','h',' '), HB_TAG('H','M','N',' ')}, /* Southwestern Huishui Hmong -> Hmong */ @@ -733,35 +690,27 @@ static const LangTag ot_languages3[] = { {HB_TAG('h','m','j',' '), HB_TAG('H','M','N',' ')}, /* Ge -> Hmong */ {HB_TAG('h','m','l',' '), HB_TAG('H','M','N',' ')}, /* Luopohe Hmong -> Hmong */ {HB_TAG('h','m','m',' '), HB_TAG('H','M','N',' ')}, /* Central Mashan Hmong -> Hmong */ -/*{HB_TAG('h','m','n',' '), HB_TAG('H','M','N',' ')},*/ /* Hmong [macrolanguage] */ {HB_TAG('h','m','p',' '), HB_TAG('H','M','N',' ')}, /* Northern Mashan Hmong -> Hmong */ {HB_TAG('h','m','q',' '), HB_TAG('H','M','N',' ')}, /* Eastern Qiandong Miao -> Hmong */ {HB_TAG('h','m','r',' '), HB_TAG('Q','I','N',' ')}, /* Hmar -> Chin */ {HB_TAG('h','m','s',' '), HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */ {HB_TAG('h','m','w',' '), HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */ {HB_TAG('h','m','y',' '), HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */ - {HB_TAG('h','m','z',' '), HB_TAG('H','M','Z',' ')}, /* Hmong Shua -> Hmong Shuat */ - {HB_TAG('h','m','z',' '), HB_TAG('H','M','N',' ')}, /* Hmong Shua -> Hmong */ -/*{HB_TAG('h','n','d',' '), HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */ {HB_TAG('h','n','e',' '), HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ {HB_TAG('h','n','j',' '), HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ + {HB_TAG('h','n','m',' '), HB_TAG('Z','H','S',' ')}, /* Hainanese -> Chinese, Simplified */ {HB_TAG('h','n','o',' '), HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ {HB_TAG('h','o','c',' '), HB_TAG('H','O',' ',' ')}, /* Ho */ {HB_TAG('h','o','i',' '), HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */ - {HB_TAG('h','o','j',' '), HB_TAG('H','A','R',' ')}, /* Hadothi -> Harauti */ - {HB_TAG('h','o','j',' '), HB_TAG('R','A','J',' ')}, /* Hadothi -> Rajasthani */ {HB_TAG('h','r','a',' '), HB_TAG('Q','I','N',' ')}, /* Hrangkhol -> Chin */ {HB_TAG('h','r','m',' '), HB_TAG('H','M','N',' ')}, /* Horned Miao -> Hmong */ {HB_TAG('h','s','b',' '), HB_TAG('U','S','B',' ')}, /* Upper Sorbian */ {HB_TAG('h','s','n',' '), HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese, Simplified */ {HB_TAG('h','u','j',' '), HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */ {HB_TAG('h','u','p',' '), HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */ -/*{HB_TAG('h','u','r',' '), HB_TAG('H','U','R',' ')},*/ /* Halkomelem */ {HB_TAG('h','u','s',' '), HB_TAG('M','Y','N',' ')}, /* Huastec -> Mayan */ {HB_TAG('h','w','c',' '), HB_TAG('C','P','P',' ')}, /* Hawai'i Creole English -> Creoles */ {HB_TAG('h','y','w',' '), HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */ -/*{HB_TAG('i','b','a',' '), HB_TAG('I','B','A',' ')},*/ /* Iban */ -/*{HB_TAG('i','b','b',' '), HB_TAG('I','B','B',' ')},*/ /* Ibibio */ {HB_TAG('i','b','y',' '), HB_TAG('I','J','O',' ')}, /* Ibani -> Ijo */ {HB_TAG('i','c','r',' '), HB_TAG('C','P','P',' ')}, /* Islander Creole English -> Creoles */ {HB_TAG('i','d','a',' '), HB_TAG('L','U','H',' ')}, /* Idakho-Isukha-Tiriki -> Luyia */ @@ -771,152 +720,71 @@ static const LangTag ot_languages3[] = { {HB_TAG('i','j','c',' '), HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */ {HB_TAG('i','j','e',' '), HB_TAG('I','J','O',' ')}, /* Biseni -> Ijo */ {HB_TAG('i','j','n',' '), HB_TAG('I','J','O',' ')}, /* Kalabari -> Ijo */ -/*{HB_TAG('i','j','o',' '), HB_TAG('I','J','O',' ')},*/ /* Ijo [collection] */ {HB_TAG('i','j','s',' '), HB_TAG('I','J','O',' ')}, /* Southeast Ijo -> Ijo */ - {HB_TAG('i','k','e',' '), HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */ - {HB_TAG('i','k','e',' '), HB_TAG('I','N','U','K')}, /* Eastern Canadian Inuktitut -> Nunavik Inuktitut */ {HB_TAG('i','k','t',' '), HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */ -/*{HB_TAG('i','l','o',' '), HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */ {HB_TAG('i','n','g',' '), HB_TAG('A','T','H',' ')}, /* Degexit'an -> Athapaskan */ {HB_TAG('i','n','h',' '), HB_TAG('I','N','G',' ')}, /* Ingush */ - {HB_TAG('i','r','i',' '), HB_TAG_NONE }, /* Rigwe != Irish */ -/*{HB_TAG('i','r','u',' '), HB_TAG('I','R','U',' ')},*/ /* Irula */ - {HB_TAG('i','s','m',' '), HB_TAG_NONE }, /* Masimasi != Inari Sami */ {HB_TAG('i','t','z',' '), HB_TAG('M','Y','N',' ')}, /* Itzá -> Mayan */ {HB_TAG('i','x','l',' '), HB_TAG('M','Y','N',' ')}, /* Ixil -> Mayan */ {HB_TAG('j','a','c',' '), HB_TAG('M','Y','N',' ')}, /* Popti' -> Mayan */ {HB_TAG('j','a','k',' '), HB_TAG('M','L','Y',' ')}, /* Jakun -> Malay */ - {HB_TAG('j','a','m',' '), HB_TAG('J','A','M',' ')}, /* Jamaican Creole English -> Jamaican Creole */ - {HB_TAG('j','a','m',' '), HB_TAG('C','P','P',' ')}, /* Jamaican Creole English -> Creoles */ - {HB_TAG('j','a','n',' '), HB_TAG_NONE }, /* Jandai != Japanese */ {HB_TAG('j','a','x',' '), HB_TAG('M','L','Y',' ')}, /* Jambi Malay -> Malay */ {HB_TAG('j','b','e',' '), HB_TAG('B','B','R',' ')}, /* Judeo-Berber -> Berber */ {HB_TAG('j','b','n',' '), HB_TAG('B','B','R',' ')}, /* Nafusi -> Berber */ -/*{HB_TAG('j','b','o',' '), HB_TAG('J','B','O',' ')},*/ /* Lojban */ -/*{HB_TAG('j','c','t',' '), HB_TAG('J','C','T',' ')},*/ /* Krymchak */ -/*{HB_TAG('j','d','t',' '), HB_TAG('J','D','T',' ')},*/ /* Judeo-Tat */ {HB_TAG('j','g','o',' '), HB_TAG('B','M','L',' ')}, /* Ngomba -> Bamileke */ - {HB_TAG('j','i','i',' '), HB_TAG_NONE }, /* Jiiddu != Yiddish */ {HB_TAG('j','k','m',' '), HB_TAG('K','R','N',' ')}, /* Mobwa Karen -> Karen */ {HB_TAG('j','k','p',' '), HB_TAG('K','R','N',' ')}, /* Paku Karen -> Karen */ - {HB_TAG('j','u','d',' '), HB_TAG_NONE }, /* Worodougou != Ladino */ - {HB_TAG('j','u','l',' '), HB_TAG_NONE }, /* Jirel != Jula */ {HB_TAG('j','v','d',' '), HB_TAG('C','P','P',' ')}, /* Javindo -> Creoles */ {HB_TAG('k','a','a',' '), HB_TAG('K','R','K',' ')}, /* Karakalpak */ - {HB_TAG('k','a','b',' '), HB_TAG('K','A','B','0')}, /* Kabyle */ - {HB_TAG('k','a','b',' '), HB_TAG('B','B','R',' ')}, /* Kabyle -> Berber */ - {HB_TAG('k','a','c',' '), HB_TAG_NONE }, /* Kachin != Kachchi */ {HB_TAG('k','a','m',' '), HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {HB_TAG('k','a','r',' '), HB_TAG('K','R','N',' ')}, /* Karen [collection] */ -/*{HB_TAG('k','a','w',' '), HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */ -/*{HB_TAG('k','b','c',' '), HB_TAG('K','B','C',' ')},*/ /* Kadiwéu */ {HB_TAG('k','b','d',' '), HB_TAG('K','A','B',' ')}, /* Kabardian */ {HB_TAG('k','b','y',' '), HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */ - {HB_TAG('k','c','a',' '), HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ - {HB_TAG('k','c','a',' '), HB_TAG('K','H','S',' ')}, /* Khanty -> Khanty-Shurishkar */ - {HB_TAG('k','c','a',' '), HB_TAG('K','H','V',' ')}, /* Khanty -> Khanty-Vakhi */ {HB_TAG('k','c','n',' '), HB_TAG('C','P','P',' ')}, /* Nubi -> Creoles */ -/*{HB_TAG('k','d','e',' '), HB_TAG('K','D','E',' ')},*/ /* Makonde */ {HB_TAG('k','d','r',' '), HB_TAG('K','R','M',' ')}, /* Karaim */ {HB_TAG('k','d','t',' '), HB_TAG('K','U','Y',' ')}, /* Kuy */ - {HB_TAG('k','e','a',' '), HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */ - {HB_TAG('k','e','a',' '), HB_TAG('C','P','P',' ')}, /* Kabuverdianu -> Creoles */ - {HB_TAG('k','e','b',' '), HB_TAG_NONE }, /* Kélé != Kebena */ - {HB_TAG('k','e','k',' '), HB_TAG('K','E','K',' ')}, /* Kekchi */ - {HB_TAG('k','e','k',' '), HB_TAG('M','Y','N',' ')}, /* Kekchí -> Mayan */ {HB_TAG('k','e','x',' '), HB_TAG('K','K','N',' ')}, /* Kukna -> Kokni */ {HB_TAG('k','f','a',' '), HB_TAG('K','O','D',' ')}, /* Kodava -> Kodagu */ {HB_TAG('k','f','r',' '), HB_TAG('K','A','C',' ')}, /* Kachhi -> Kachchi */ {HB_TAG('k','f','x',' '), HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */ {HB_TAG('k','f','y',' '), HB_TAG('K','M','N',' ')}, /* Kumaoni */ - {HB_TAG('k','g','e',' '), HB_TAG_NONE }, /* Komering != Khutsuri Georgian */ {HB_TAG('k','h','a',' '), HB_TAG('K','S','I',' ')}, /* Khasi */ {HB_TAG('k','h','b',' '), HB_TAG('X','B','D',' ')}, /* Lü */ {HB_TAG('k','h','k',' '), HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */ - {HB_TAG('k','h','n',' '), HB_TAG_NONE }, /* Khandesi != Khamti Shan (Microsoft fonts) */ - {HB_TAG('k','h','s',' '), HB_TAG_NONE }, /* Kasua != Khanty-Shurishkar */ - {HB_TAG('k','h','t',' '), HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan */ - {HB_TAG('k','h','t',' '), HB_TAG('K','H','N',' ')}, /* Khamti -> Khamti Shan (Microsoft fonts) */ - {HB_TAG('k','h','v',' '), HB_TAG_NONE }, /* Khvarshi != Khanty-Vakhi */ -/*{HB_TAG('k','h','w',' '), HB_TAG('K','H','W',' ')},*/ /* Khowar */ - {HB_TAG('k','i','s',' '), HB_TAG_NONE }, /* Kis != Kisii */ - {HB_TAG('k','i','u',' '), HB_TAG('K','I','U',' ')}, /* Kirmanjki */ - {HB_TAG('k','i','u',' '), HB_TAG('Z','Z','A',' ')}, /* Kirmanjki -> Zazaki */ {HB_TAG('k','j','b',' '), HB_TAG('M','Y','N',' ')}, /* Q'anjob'al -> Mayan */ -/*{HB_TAG('k','j','d',' '), HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */ {HB_TAG('k','j','h',' '), HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */ -/*{HB_TAG('k','j','j',' '), HB_TAG('K','J','J',' ')},*/ /* Khinalugh -> Khinalug */ - {HB_TAG('k','j','p',' '), HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ - {HB_TAG('k','j','p',' '), HB_TAG('K','R','N',' ')}, /* Pwo Eastern Karen -> Karen */ {HB_TAG('k','j','t',' '), HB_TAG('K','R','N',' ')}, /* Phrae Pwo Karen -> Karen */ -/*{HB_TAG('k','j','z',' '), HB_TAG('K','J','Z',' ')},*/ /* Bumthangkha */ - {HB_TAG('k','k','n',' '), HB_TAG_NONE }, /* Kon Keu != Kokni */ {HB_TAG('k','k','z',' '), HB_TAG('A','T','H',' ')}, /* Kaska -> Athapaskan */ - {HB_TAG('k','l','m',' '), HB_TAG_NONE }, /* Migum != Kalmyk */ {HB_TAG('k','l','n',' '), HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */ {HB_TAG('k','m','b',' '), HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */ - {HB_TAG('k','m','n',' '), HB_TAG_NONE }, /* Awtuw != Kumaoni */ - {HB_TAG('k','m','o',' '), HB_TAG_NONE }, /* Kwoma != Komo */ {HB_TAG('k','m','r',' '), HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */ - {HB_TAG('k','m','s',' '), HB_TAG_NONE }, /* Kamasau != Komso */ {HB_TAG('k','m','v',' '), HB_TAG('C','P','P',' ')}, /* Karipúna Creole French -> Creoles */ {HB_TAG('k','m','w',' '), HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */ -/*{HB_TAG('k','m','z',' '), HB_TAG('K','M','Z',' ')},*/ /* Khorasani Turkish -> Khorasani Turkic */ {HB_TAG('k','n','c',' '), HB_TAG('K','N','R',' ')}, /* Central Kanuri -> Kanuri */ {HB_TAG('k','n','g',' '), HB_TAG('K','O','N','0')}, /* Koongo -> Kongo */ {HB_TAG('k','n','j',' '), HB_TAG('M','Y','N',' ')}, /* Western Kanjobal -> Mayan */ {HB_TAG('k','n','n',' '), HB_TAG('K','O','K',' ')}, /* Konkani */ - {HB_TAG('k','n','r',' '), HB_TAG_NONE }, /* Kaningra != Kanuri */ - {HB_TAG('k','o','d',' '), HB_TAG_NONE }, /* Kodi != Kodagu */ - {HB_TAG('k','o','h',' '), HB_TAG_NONE }, /* Koyo != Korean Old Hangul */ - {HB_TAG('k','o','i',' '), HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ - {HB_TAG('k','o','i',' '), HB_TAG('K','O','M',' ')}, /* Komi-Permyak -> Komi */ -/*{HB_TAG('k','o','k',' '), HB_TAG('K','O','K',' ')},*/ /* Konkani [macrolanguage] */ - {HB_TAG('k','o','p',' '), HB_TAG_NONE }, /* Waube != Komi-Permyak */ -/*{HB_TAG('k','o','s',' '), HB_TAG('K','O','S',' ')},*/ /* Kosraean */ {HB_TAG('k','o','y',' '), HB_TAG('A','T','H',' ')}, /* Koyukon -> Athapaskan */ - {HB_TAG('k','o','z',' '), HB_TAG_NONE }, /* Korak != Komi-Zyrian */ {HB_TAG('k','p','e',' '), HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ - {HB_TAG('k','p','l',' '), HB_TAG_NONE }, /* Kpala != Kpelle */ {HB_TAG('k','p','p',' '), HB_TAG('K','R','N',' ')}, /* Paku Karen (retired code) -> Karen */ - {HB_TAG('k','p','v',' '), HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ - {HB_TAG('k','p','v',' '), HB_TAG('K','O','M',' ')}, /* Komi-Zyrian -> Komi */ {HB_TAG('k','p','y',' '), HB_TAG('K','Y','K',' ')}, /* Koryak */ {HB_TAG('k','q','s',' '), HB_TAG('K','I','S',' ')}, /* Northern Kissi -> Kisii */ {HB_TAG('k','q','y',' '), HB_TAG('K','R','T',' ')}, /* Koorete */ - {HB_TAG('k','r','c',' '), HB_TAG('K','A','R',' ')}, /* Karachay-Balkar -> Karachay */ - {HB_TAG('k','r','c',' '), HB_TAG('B','A','L',' ')}, /* Karachay-Balkar -> Balkar */ - {HB_TAG('k','r','i',' '), HB_TAG('K','R','I',' ')}, /* Krio */ - {HB_TAG('k','r','i',' '), HB_TAG('C','P','P',' ')}, /* Krio -> Creoles */ - {HB_TAG('k','r','k',' '), HB_TAG_NONE }, /* Kerek != Karakalpak */ -/*{HB_TAG('k','r','l',' '), HB_TAG('K','R','L',' ')},*/ /* Karelian */ - {HB_TAG('k','r','m',' '), HB_TAG_NONE }, /* Krim (retired code) != Karaim */ - {HB_TAG('k','r','n',' '), HB_TAG_NONE }, /* Sapo != Karen */ {HB_TAG('k','r','t',' '), HB_TAG('K','N','R',' ')}, /* Tumari Kanuri -> Kanuri */ {HB_TAG('k','r','u',' '), HB_TAG('K','U','U',' ')}, /* Kurukh */ {HB_TAG('k','s','h',' '), HB_TAG('K','S','H','0')}, /* Kölsch -> Ripuarian */ - {HB_TAG('k','s','i',' '), HB_TAG_NONE }, /* Krisa != Khasi */ - {HB_TAG('k','s','m',' '), HB_TAG_NONE }, /* Kumba != Kildin Sami */ {HB_TAG('k','s','s',' '), HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */ - {HB_TAG('k','s','w',' '), HB_TAG('K','S','W',' ')}, /* S’gaw Karen */ - {HB_TAG('k','s','w',' '), HB_TAG('K','R','N',' ')}, /* S'gaw Karen -> Karen */ {HB_TAG('k','t','b',' '), HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */ {HB_TAG('k','t','u',' '), HB_TAG('K','O','N',' ')}, /* Kituba (Democratic Republic of Congo) -> Kikongo */ {HB_TAG('k','t','w',' '), HB_TAG('A','T','H',' ')}, /* Kato -> Athapaskan */ - {HB_TAG('k','u','i',' '), HB_TAG_NONE }, /* Kuikúro-Kalapálo != Kui */ - {HB_TAG('k','u','l',' '), HB_TAG_NONE }, /* Kulere != Kulvi */ -/*{HB_TAG('k','u','m',' '), HB_TAG('K','U','M',' ')},*/ /* Kumyk */ {HB_TAG('k','u','u',' '), HB_TAG('A','T','H',' ')}, /* Upper Kuskokwim -> Athapaskan */ {HB_TAG('k','u','w',' '), HB_TAG('B','A','D','0')}, /* Kpagua -> Banda */ - {HB_TAG('k','u','y',' '), HB_TAG_NONE }, /* Kuuku-Ya'u != Kuy */ {HB_TAG('k','v','b',' '), HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */ {HB_TAG('k','v','l',' '), HB_TAG('K','R','N',' ')}, /* Kayaw -> Karen */ - {HB_TAG('k','v','q',' '), HB_TAG('K','R','N',' ')}, /* Geba Karen -> Karen */ {HB_TAG('k','v','r',' '), HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */ {HB_TAG('k','v','t',' '), HB_TAG('K','R','N',' ')}, /* Lahta Karen -> Karen */ {HB_TAG('k','v','u',' '), HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */ {HB_TAG('k','v','y',' '), HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */ -/*{HB_TAG('k','w','k',' '), HB_TAG('K','W','K',' ')},*/ /* Kwakiutl -> Kwakʼwala */ {HB_TAG('k','w','w',' '), HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */ {HB_TAG('k','w','y',' '), HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ {HB_TAG('k','x','c',' '), HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ @@ -925,193 +793,98 @@ static const LangTag ot_languages3[] = { {HB_TAG('k','x','k',' '), HB_TAG('K','R','N',' ')}, /* Zayein Karen -> Karen */ {HB_TAG('k','x','l',' '), HB_TAG('K','U','U',' ')}, /* Nepali Kurux (retired code) -> Kurukh */ {HB_TAG('k','x','u',' '), HB_TAG('K','U','I',' ')}, /* Kui (India) (retired code) */ - {HB_TAG('k','y','k',' '), HB_TAG_NONE }, /* Kamayo != Koryak */ - {HB_TAG('k','y','u',' '), HB_TAG('K','Y','U',' ')}, /* Western Kayah */ - {HB_TAG('k','y','u',' '), HB_TAG('K','R','N',' ')}, /* Western Kayah -> Karen */ {HB_TAG('l','a','c',' '), HB_TAG('M','Y','N',' ')}, /* Lacandon -> Mayan */ {HB_TAG('l','a','d',' '), HB_TAG('J','U','D',' ')}, /* Ladino */ - {HB_TAG('l','a','h',' '), HB_TAG_NONE }, /* Lahnda [macrolanguage] != Lahuli */ - {HB_TAG('l','a','k',' '), HB_TAG_NONE }, /* Laka (Nigeria) (retired code) != Lak */ - {HB_TAG('l','a','m',' '), HB_TAG_NONE }, /* Lamba != Lambani */ - {HB_TAG('l','a','z',' '), HB_TAG_NONE }, /* Aribwatsa != Laz */ {HB_TAG('l','b','e',' '), HB_TAG('L','A','K',' ')}, /* Lak */ {HB_TAG('l','b','j',' '), HB_TAG('L','D','K',' ')}, /* Ladakhi */ {HB_TAG('l','b','l',' '), HB_TAG('B','I','K',' ')}, /* Libon Bikol -> Bikol */ {HB_TAG('l','c','e',' '), HB_TAG('M','L','Y',' ')}, /* Loncong -> Malay */ {HB_TAG('l','c','f',' '), HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */ {HB_TAG('l','d','i',' '), HB_TAG('K','O','N','0')}, /* Laari -> Kongo */ - {HB_TAG('l','d','k',' '), HB_TAG_NONE }, /* Leelau != Ladakhi */ -/*{HB_TAG('l','e','f',' '), HB_TAG('L','E','F',' ')},*/ /* Lelemi */ -/*{HB_TAG('l','e','z',' '), HB_TAG('L','E','Z',' ')},*/ /* Lezghian -> Lezgi */ {HB_TAG('l','i','f',' '), HB_TAG('L','M','B',' ')}, /* Limbu */ -/*{HB_TAG('l','i','j',' '), HB_TAG('L','I','J',' ')},*/ /* Ligurian */ {HB_TAG('l','i','r',' '), HB_TAG('C','P','P',' ')}, /* Liberian English -> Creoles */ -/*{HB_TAG('l','i','s',' '), HB_TAG('L','I','S',' ')},*/ /* Lisu */ -/*{HB_TAG('l','i','v',' '), HB_TAG('L','I','V',' ')},*/ /* Liv */ {HB_TAG('l','i','w',' '), HB_TAG('M','L','Y',' ')}, /* Col -> Malay */ {HB_TAG('l','i','y',' '), HB_TAG('B','A','D','0')}, /* Banda-Bambari -> Banda */ -/*{HB_TAG('l','j','p',' '), HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */ {HB_TAG('l','k','b',' '), HB_TAG('L','U','H',' ')}, /* Kabras -> Luyia */ -/*{HB_TAG('l','k','i',' '), HB_TAG('L','K','I',' ')},*/ /* Laki */ {HB_TAG('l','k','o',' '), HB_TAG('L','U','H',' ')}, /* Khayo -> Luyia */ {HB_TAG('l','k','s',' '), HB_TAG('L','U','H',' ')}, /* Kisa -> Luyia */ {HB_TAG('l','l','d',' '), HB_TAG('L','A','D',' ')}, /* Ladin */ - {HB_TAG('l','m','a',' '), HB_TAG_NONE }, /* East Limba != Low Mari */ - {HB_TAG('l','m','b',' '), HB_TAG_NONE }, /* Merei != Limbu */ {HB_TAG('l','m','n',' '), HB_TAG('L','A','M',' ')}, /* Lambadi -> Lambani */ -/*{HB_TAG('l','m','o',' '), HB_TAG('L','M','O',' ')},*/ /* Lombard */ - {HB_TAG('l','m','w',' '), HB_TAG_NONE }, /* Lake Miwok != Lomwe */ {HB_TAG('l','n','a',' '), HB_TAG('B','A','D','0')}, /* Langbashe -> Banda */ {HB_TAG('l','n','l',' '), HB_TAG('B','A','D','0')}, /* South Central Banda -> Banda */ -/*{HB_TAG('l','o','m',' '), HB_TAG('L','O','M',' ')},*/ /* Loma (Liberia) */ {HB_TAG('l','o','u',' '), HB_TAG('C','P','P',' ')}, /* Louisiana Creole -> Creoles */ -/*{HB_TAG('l','p','o',' '), HB_TAG('L','P','O',' ')},*/ /* Lipo */ -/*{HB_TAG('l','r','c',' '), HB_TAG('L','R','C',' ')},*/ /* Northern Luri -> Luri */ {HB_TAG('l','r','i',' '), HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */ {HB_TAG('l','r','m',' '), HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */ {HB_TAG('l','r','t',' '), HB_TAG('C','P','P',' ')}, /* Larantuka Malay -> Creoles */ - {HB_TAG('l','s','b',' '), HB_TAG_NONE }, /* Burundian Sign Language != Lower Sorbian */ {HB_TAG('l','s','m',' '), HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */ {HB_TAG('l','t','g',' '), HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */ - {HB_TAG('l','t','h',' '), HB_TAG_NONE }, /* Thur != Lithuanian */ {HB_TAG('l','t','o',' '), HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ {HB_TAG('l','t','s',' '), HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ -/*{HB_TAG('l','u','a',' '), HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ -/*{HB_TAG('l','u','o',' '), HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */ - {HB_TAG('l','u','s',' '), HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ - {HB_TAG('l','u','s',' '), HB_TAG('Q','I','N',' ')}, /* Lushai -> Chin */ + {HB_TAG('l','u','h',' '), HB_TAG('Z','H','S',' ')}, /* Leizhou Chinese -> Chinese, Simplified */ {HB_TAG('l','u','y',' '), HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ {HB_TAG('l','u','z',' '), HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ - {HB_TAG('l','v','i',' '), HB_TAG_NONE }, /* Lavi != Latvian */ {HB_TAG('l','v','s',' '), HB_TAG('L','V','I',' ')}, /* Standard Latvian -> Latvian */ {HB_TAG('l','w','g',' '), HB_TAG('L','U','H',' ')}, /* Wanga -> Luyia */ {HB_TAG('l','z','h',' '), HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese, Traditional */ {HB_TAG('l','z','z',' '), HB_TAG('L','A','Z',' ')}, /* Laz */ -/*{HB_TAG('m','a','d',' '), HB_TAG('M','A','D',' ')},*/ /* Madurese -> Madura */ -/*{HB_TAG('m','a','g',' '), HB_TAG('M','A','G',' ')},*/ /* Magahi */ {HB_TAG('m','a','i',' '), HB_TAG('M','T','H',' ')}, /* Maithili */ - {HB_TAG('m','a','j',' '), HB_TAG_NONE }, /* Jalapa De Díaz Mazatec != Majang */ {HB_TAG('m','a','k',' '), HB_TAG('M','K','R',' ')}, /* Makasar */ - {HB_TAG('m','a','m',' '), HB_TAG('M','A','M',' ')}, /* Mam */ - {HB_TAG('m','a','m',' '), HB_TAG('M','Y','N',' ')}, /* Mam -> Mayan */ {HB_TAG('m','a','n',' '), HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */ - {HB_TAG('m','a','p',' '), HB_TAG_NONE }, /* Austronesian [collection] != Mapudungun */ - {HB_TAG('m','a','w',' '), HB_TAG_NONE }, /* Mampruli != Marwari */ - {HB_TAG('m','a','x',' '), HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */ - {HB_TAG('m','a','x',' '), HB_TAG('C','P','P',' ')}, /* North Moluccan Malay -> Creoles */ {HB_TAG('m','b','f',' '), HB_TAG('C','P','P',' ')}, /* Baba Malay -> Creoles */ - {HB_TAG('m','b','n',' '), HB_TAG_NONE }, /* Macaguán != Mbundu */ -/*{HB_TAG('m','b','o',' '), HB_TAG('M','B','O',' ')},*/ /* Mbo (Cameroon) */ - {HB_TAG('m','c','h',' '), HB_TAG_NONE }, /* Maquiritari != Manchu */ {HB_TAG('m','c','m',' '), HB_TAG('C','P','P',' ')}, /* Malaccan Creole Portuguese -> Creoles */ - {HB_TAG('m','c','r',' '), HB_TAG_NONE }, /* Menya != Moose Cree */ {HB_TAG('m','c','t',' '), HB_TAG('B','T','I',' ')}, /* Mengisa -> Beti */ - {HB_TAG('m','d','e',' '), HB_TAG_NONE }, /* Maba (Chad) != Mende */ {HB_TAG('m','d','f',' '), HB_TAG('M','O','K',' ')}, /* Moksha */ -/*{HB_TAG('m','d','r',' '), HB_TAG('M','D','R',' ')},*/ /* Mandar */ {HB_TAG('m','d','y',' '), HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */ {HB_TAG('m','e','n',' '), HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ {HB_TAG('m','e','o',' '), HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */ -/*{HB_TAG('m','e','r',' '), HB_TAG('M','E','R',' ')},*/ /* Meru */ -/*{HB_TAG('m','e','v',' '), HB_TAG('M','E','V',' ')},*/ /* Mano */ - {HB_TAG('m','f','a',' '), HB_TAG('M','F','A',' ')}, /* Pattani Malay */ - {HB_TAG('m','f','a',' '), HB_TAG('M','L','Y',' ')}, /* Pattani Malay -> Malay */ {HB_TAG('m','f','b',' '), HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */ - {HB_TAG('m','f','e',' '), HB_TAG('M','F','E',' ')}, /* Morisyen */ - {HB_TAG('m','f','e',' '), HB_TAG('C','P','P',' ')}, /* Morisyen -> Creoles */ {HB_TAG('m','f','p',' '), HB_TAG('C','P','P',' ')}, /* Makassar Malay -> Creoles */ {HB_TAG('m','g','a',' '), HB_TAG('S','G','A',' ')}, /* Middle Irish (900-1200) -> Old Irish */ {HB_TAG('m','h','c',' '), HB_TAG('M','Y','N',' ')}, /* Mocho -> Mayan */ {HB_TAG('m','h','r',' '), HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */ {HB_TAG('m','h','v',' '), HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */ - {HB_TAG('m','i','n',' '), HB_TAG('M','I','N',' ')}, /* Minangkabau */ - {HB_TAG('m','i','n',' '), HB_TAG('M','L','Y',' ')}, /* Minangkabau -> Malay */ - {HB_TAG('m','i','z',' '), HB_TAG_NONE }, /* Coatzospan Mixtec != Mizo */ {HB_TAG('m','k','n',' '), HB_TAG('C','P','P',' ')}, /* Kupang Malay -> Creoles */ - {HB_TAG('m','k','r',' '), HB_TAG_NONE }, /* Malas != Makasar */ {HB_TAG('m','k','u',' '), HB_TAG('M','N','K',' ')}, /* Konyanka Maninka -> Maninka */ -/*{HB_TAG('m','k','w',' '), HB_TAG('M','K','W',' ')},*/ /* Kituba (Congo) */ - {HB_TAG('m','l','e',' '), HB_TAG_NONE }, /* Manambu != Male */ - {HB_TAG('m','l','n',' '), HB_TAG_NONE }, /* Malango != Malinke */ - {HB_TAG('m','l','q',' '), HB_TAG('M','L','N',' ')}, /* Western Maninkakan -> Malinke */ - {HB_TAG('m','l','q',' '), HB_TAG('M','N','K',' ')}, /* Western Maninkakan -> Maninka */ - {HB_TAG('m','l','r',' '), HB_TAG_NONE }, /* Vame != Malayalam Reformed */ {HB_TAG('m','m','r',' '), HB_TAG('H','M','N',' ')}, /* Western Xiangxi Miao -> Hmong */ {HB_TAG('m','n','c',' '), HB_TAG('M','C','H',' ')}, /* Manchu */ - {HB_TAG('m','n','d',' '), HB_TAG_NONE }, /* Mondé != Mandinka */ - {HB_TAG('m','n','g',' '), HB_TAG_NONE }, /* Eastern Mnong != Mongolian */ {HB_TAG('m','n','h',' '), HB_TAG('B','A','D','0')}, /* Mono (Democratic Republic of Congo) -> Banda */ -/*{HB_TAG('m','n','i',' '), HB_TAG('M','N','I',' ')},*/ /* Manipuri */ - {HB_TAG('m','n','k',' '), HB_TAG('M','N','D',' ')}, /* Mandinka */ - {HB_TAG('m','n','k',' '), HB_TAG('M','N','K',' ')}, /* Mandinka -> Maninka */ {HB_TAG('m','n','p',' '), HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese, Simplified */ {HB_TAG('m','n','s',' '), HB_TAG('M','A','N',' ')}, /* Mansi */ - {HB_TAG('m','n','w',' '), HB_TAG('M','O','N',' ')}, /* Mon */ - {HB_TAG('m','n','w',' '), HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */ - {HB_TAG('m','n','x',' '), HB_TAG_NONE }, /* Manikion != Manx */ {HB_TAG('m','o','d',' '), HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */ -/*{HB_TAG('m','o','h',' '), HB_TAG('M','O','H',' ')},*/ /* Mohawk */ - {HB_TAG('m','o','k',' '), HB_TAG_NONE }, /* Morori != Moksha */ {HB_TAG('m','o','p',' '), HB_TAG('M','Y','N',' ')}, /* Mopán Maya -> Mayan */ - {HB_TAG('m','o','r',' '), HB_TAG_NONE }, /* Moro != Moroccan */ -/*{HB_TAG('m','o','s',' '), HB_TAG('M','O','S',' ')},*/ /* Mossi */ {HB_TAG('m','p','e',' '), HB_TAG('M','A','J',' ')}, /* Majang */ {HB_TAG('m','q','g',' '), HB_TAG('M','L','Y',' ')}, /* Kota Bangun Kutai Malay -> Malay */ {HB_TAG('m','r','h',' '), HB_TAG('Q','I','N',' ')}, /* Mara Chin -> Chin */ {HB_TAG('m','r','j',' '), HB_TAG('H','M','A',' ')}, /* Western Mari -> High Mari */ {HB_TAG('m','s','c',' '), HB_TAG('M','N','K',' ')}, /* Sankaran Maninka -> Maninka */ {HB_TAG('m','s','h',' '), HB_TAG('M','L','G',' ')}, /* Masikoro Malagasy -> Malagasy */ - {HB_TAG('m','s','i',' '), HB_TAG('M','L','Y',' ')}, /* Sabah Malay -> Malay */ - {HB_TAG('m','s','i',' '), HB_TAG('C','P','P',' ')}, /* Sabah Malay -> Creoles */ - {HB_TAG('m','t','h',' '), HB_TAG_NONE }, /* Munggui != Maithili */ {HB_TAG('m','t','r',' '), HB_TAG('M','A','W',' ')}, /* Mewari -> Marwari */ - {HB_TAG('m','t','s',' '), HB_TAG_NONE }, /* Yora != Maltese */ {HB_TAG('m','u','d',' '), HB_TAG('C','P','P',' ')}, /* Mednyj Aleut -> Creoles */ {HB_TAG('m','u','i',' '), HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */ - {HB_TAG('m','u','n',' '), HB_TAG_NONE }, /* Munda [collection] != Mundari */ {HB_TAG('m','u','p',' '), HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */ {HB_TAG('m','u','q',' '), HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */ -/*{HB_TAG('m','u','s',' '), HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */ {HB_TAG('m','v','b',' '), HB_TAG('A','T','H',' ')}, /* Mattole -> Athapaskan */ {HB_TAG('m','v','e',' '), HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */ {HB_TAG('m','v','f',' '), HB_TAG('M','N','G',' ')}, /* Peripheral Mongolian -> Mongolian */ {HB_TAG('m','w','k',' '), HB_TAG('M','N','K',' ')}, /* Kita Maninkakan -> Maninka */ -/*{HB_TAG('m','w','l',' '), HB_TAG('M','W','L',' ')},*/ /* Mirandese */ {HB_TAG('m','w','q',' '), HB_TAG('Q','I','N',' ')}, /* Mün Chin -> Chin */ {HB_TAG('m','w','r',' '), HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */ - {HB_TAG('m','w','w',' '), HB_TAG('M','W','W',' ')}, /* Hmong Daw */ - {HB_TAG('m','w','w',' '), HB_TAG('H','M','N',' ')}, /* Hmong Daw -> Hmong */ {HB_TAG('m','y','m',' '), HB_TAG('M','E','N',' ')}, /* Me’en */ -/*{HB_TAG('m','y','n',' '), HB_TAG('M','Y','N',' ')},*/ /* Mayan [collection] */ {HB_TAG('m','y','q',' '), HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */ {HB_TAG('m','y','v',' '), HB_TAG('E','R','Z',' ')}, /* Erzya */ {HB_TAG('m','z','b',' '), HB_TAG('B','B','R',' ')}, /* Tumzabt -> Berber */ -/*{HB_TAG('m','z','n',' '), HB_TAG('M','Z','N',' ')},*/ /* Mazanderani */ {HB_TAG('m','z','s',' '), HB_TAG('C','P','P',' ')}, /* Macanese -> Creoles */ - {HB_TAG('n','a','g',' '), HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */ - {HB_TAG('n','a','g',' '), HB_TAG('C','P','P',' ')}, /* Naga Pidgin -> Creoles */ -/*{HB_TAG('n','a','h',' '), HB_TAG('N','A','H',' ')},*/ /* Nahuatl [collection] */ {HB_TAG('n','a','n',' '), HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese, Simplified */ -/*{HB_TAG('n','a','p',' '), HB_TAG('N','A','P',' ')},*/ /* Neapolitan */ - {HB_TAG('n','a','s',' '), HB_TAG_NONE }, /* Naasioi != Naskapi */ {HB_TAG('n','a','z',' '), HB_TAG('N','A','H',' ')}, /* Coatepec Nahuatl -> Nahuatl */ {HB_TAG('n','c','h',' '), HB_TAG('N','A','H',' ')}, /* Central Huasteca Nahuatl -> Nahuatl */ {HB_TAG('n','c','i',' '), HB_TAG('N','A','H',' ')}, /* Classical Nahuatl -> Nahuatl */ {HB_TAG('n','c','j',' '), HB_TAG('N','A','H',' ')}, /* Northern Puebla Nahuatl -> Nahuatl */ {HB_TAG('n','c','l',' '), HB_TAG('N','A','H',' ')}, /* Michoacán Nahuatl -> Nahuatl */ - {HB_TAG('n','c','r',' '), HB_TAG_NONE }, /* Ncane != N-Cree */ {HB_TAG('n','c','x',' '), HB_TAG('N','A','H',' ')}, /* Central Puebla Nahuatl -> Nahuatl */ - {HB_TAG('n','d','b',' '), HB_TAG_NONE }, /* Kenswei Nsei != Ndebele */ -/*{HB_TAG('n','d','c',' '), HB_TAG('N','D','C',' ')},*/ /* Ndau */ - {HB_TAG('n','d','g',' '), HB_TAG_NONE }, /* Ndengereko != Ndonga */ -/*{HB_TAG('n','d','s',' '), HB_TAG('N','D','S',' ')},*/ /* Low Saxon */ {HB_TAG('n','e','f',' '), HB_TAG('C','P','P',' ')}, /* Nefamese -> Creoles */ -/*{HB_TAG('n','e','w',' '), HB_TAG('N','E','W',' ')},*/ /* Newari */ -/*{HB_TAG('n','g','a',' '), HB_TAG('N','G','A',' ')},*/ /* Ngbaka */ {HB_TAG('n','g','l',' '), HB_TAG('L','M','W',' ')}, /* Lomwe */ {HB_TAG('n','g','m',' '), HB_TAG('C','P','P',' ')}, /* Ngatik Men's Creole -> Creoles */ {HB_TAG('n','g','o',' '), HB_TAG('S','X','T',' ')}, /* Ngoni (retired code) -> Sutu */ - {HB_TAG('n','g','r',' '), HB_TAG_NONE }, /* Engdewu != Nagari */ {HB_TAG('n','g','u',' '), HB_TAG('N','A','H',' ')}, /* Guerrero Nahuatl -> Nahuatl */ {HB_TAG('n','h','c',' '), HB_TAG('N','A','H',' ')}, /* Tabasco Nahuatl -> Nahuatl */ {HB_TAG('n','h','d',' '), HB_TAG('G','U','A',' ')}, /* Chiripá -> Guarani */ @@ -1130,12 +903,9 @@ static const LangTag ot_languages3[] = { {HB_TAG('n','h','y',' '), HB_TAG('N','A','H',' ')}, /* Northern Oaxaca Nahuatl -> Nahuatl */ {HB_TAG('n','h','z',' '), HB_TAG('N','A','H',' ')}, /* Santa María La Alta Nahuatl -> Nahuatl */ {HB_TAG('n','i','q',' '), HB_TAG('K','A','L',' ')}, /* Nandi -> Kalenjin */ - {HB_TAG('n','i','s',' '), HB_TAG_NONE }, /* Nimi != Nisi */ -/*{HB_TAG('n','i','u',' '), HB_TAG('N','I','U',' ')},*/ /* Niuean */ {HB_TAG('n','i','v',' '), HB_TAG('G','I','L',' ')}, /* Gilyak */ {HB_TAG('n','j','t',' '), HB_TAG('C','P','P',' ')}, /* Ndyuka-Trio Pidgin -> Creoles */ {HB_TAG('n','j','z',' '), HB_TAG('N','I','S',' ')}, /* Nyishi -> Nisi */ - {HB_TAG('n','k','o',' '), HB_TAG_NONE }, /* Nkonya != N’Ko */ {HB_TAG('n','k','x',' '), HB_TAG('I','J','O',' ')}, /* Nkoroo -> Ijo */ {HB_TAG('n','l','a',' '), HB_TAG('B','M','L',' ')}, /* Ngombale -> Bamileke */ {HB_TAG('n','l','e',' '), HB_TAG('L','U','H',' ')}, /* East Nyala -> Luyia */ @@ -1144,321 +914,145 @@ static const LangTag ot_languages3[] = { {HB_TAG('n','n','h',' '), HB_TAG('B','M','L',' ')}, /* Ngiemboon -> Bamileke */ {HB_TAG('n','n','z',' '), HB_TAG('B','M','L',' ')}, /* Nda'nda' -> Bamileke */ {HB_TAG('n','o','d',' '), HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */ -/*{HB_TAG('n','o','e',' '), HB_TAG('N','O','E',' ')},*/ /* Nimadi */ -/*{HB_TAG('n','o','g',' '), HB_TAG('N','O','G',' ')},*/ /* Nogai */ -/*{HB_TAG('n','o','v',' '), HB_TAG('N','O','V',' ')},*/ /* Novial */ {HB_TAG('n','p','i',' '), HB_TAG('N','E','P',' ')}, /* Nepali */ {HB_TAG('n','p','l',' '), HB_TAG('N','A','H',' ')}, /* Southeastern Puebla Nahuatl -> Nahuatl */ {HB_TAG('n','q','o',' '), HB_TAG('N','K','O',' ')}, /* N’Ko */ {HB_TAG('n','s','k',' '), HB_TAG('N','A','S',' ')}, /* Naskapi */ - {HB_TAG('n','s','m',' '), HB_TAG_NONE }, /* Sumi Naga != Northern Sami */ -/*{HB_TAG('n','s','o',' '), HB_TAG('N','S','O',' ')},*/ /* Northern Sotho */ {HB_TAG('n','s','u',' '), HB_TAG('N','A','H',' ')}, /* Sierra Negra Nahuatl -> Nahuatl */ - {HB_TAG('n','t','o',' '), HB_TAG_NONE }, /* Ntomba != Esperanto */ {HB_TAG('n','u','e',' '), HB_TAG('B','A','D','0')}, /* Ngundu -> Banda */ {HB_TAG('n','u','u',' '), HB_TAG('B','A','D','0')}, /* Ngbundu -> Banda */ {HB_TAG('n','u','z',' '), HB_TAG('N','A','H',' ')}, /* Tlamacazapa Nahuatl -> Nahuatl */ {HB_TAG('n','w','e',' '), HB_TAG('B','M','L',' ')}, /* Ngwe -> Bamileke */ {HB_TAG('n','y','d',' '), HB_TAG('L','U','H',' ')}, /* Nyore -> Luyia */ -/*{HB_TAG('n','y','m',' '), HB_TAG('N','Y','M',' ')},*/ /* Nyamwezi */ {HB_TAG('n','y','n',' '), HB_TAG('N','K','L',' ')}, /* Nyankole */ -/*{HB_TAG('n','z','a',' '), HB_TAG('N','Z','A',' ')},*/ /* Tigon Mbembe -> Mbembe Tigon */ -/*{HB_TAG('o','j','b',' '), HB_TAG('O','J','B',' ')},*/ /* Northwestern Ojibwa -> Ojibway */ {HB_TAG('o','j','c',' '), HB_TAG('O','J','B',' ')}, /* Central Ojibwa -> Ojibway */ {HB_TAG('o','j','g',' '), HB_TAG('O','J','B',' ')}, /* Eastern Ojibwa -> Ojibway */ - {HB_TAG('o','j','s',' '), HB_TAG('O','C','R',' ')}, /* Severn Ojibwa -> Oji-Cree */ - {HB_TAG('o','j','s',' '), HB_TAG('O','J','B',' ')}, /* Severn Ojibwa -> Ojibway */ {HB_TAG('o','j','w',' '), HB_TAG('O','J','B',' ')}, /* Western Ojibwa -> Ojibway */ {HB_TAG('o','k','d',' '), HB_TAG('I','J','O',' ')}, /* Okodia -> Ijo */ {HB_TAG('o','k','i',' '), HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */ {HB_TAG('o','k','m',' '), HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ {HB_TAG('o','k','r',' '), HB_TAG('I','J','O',' ')}, /* Kirike -> Ijo */ -/*{HB_TAG('o','n','e',' '), HB_TAG('O','N','E',' ')},*/ /* Oneida */ -/*{HB_TAG('o','n','o',' '), HB_TAG('O','N','O',' ')},*/ /* Onondaga */ {HB_TAG('o','n','x',' '), HB_TAG('C','P','P',' ')}, /* Onin Based Pidgin -> Creoles */ {HB_TAG('o','o','r',' '), HB_TAG('C','P','P',' ')}, /* Oorlams -> Creoles */ {HB_TAG('o','r','c',' '), HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */ {HB_TAG('o','r','n',' '), HB_TAG('M','L','Y',' ')}, /* Orang Kanaq -> Malay */ - {HB_TAG('o','r','o',' '), HB_TAG_NONE }, /* Orokolo != Oromo */ {HB_TAG('o','r','r',' '), HB_TAG('I','J','O',' ')}, /* Oruma -> Ijo */ {HB_TAG('o','r','s',' '), HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ {HB_TAG('o','r','y',' '), HB_TAG('O','R','I',' ')}, /* Odia */ {HB_TAG('o','t','w',' '), HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ {HB_TAG('o','u','a',' '), HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */ - {HB_TAG('p','a','a',' '), HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */ -/*{HB_TAG('p','a','g',' '), HB_TAG('P','A','G',' ')},*/ /* Pangasinan */ - {HB_TAG('p','a','l',' '), HB_TAG_NONE }, /* Pahlavi != Pali */ -/*{HB_TAG('p','a','m',' '), HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */ - {HB_TAG('p','a','p',' '), HB_TAG('P','A','P','0')}, /* Papiamento -> Papiamentu */ - {HB_TAG('p','a','p',' '), HB_TAG('C','P','P',' ')}, /* Papiamento -> Creoles */ - {HB_TAG('p','a','s',' '), HB_TAG_NONE }, /* Papasena != Pashto */ -/*{HB_TAG('p','a','u',' '), HB_TAG('P','A','U',' ')},*/ /* Palauan */ {HB_TAG('p','b','t',' '), HB_TAG('P','A','S',' ')}, /* Southern Pashto -> Pashto */ {HB_TAG('p','b','u',' '), HB_TAG('P','A','S',' ')}, /* Northern Pashto -> Pashto */ -/*{HB_TAG('p','c','c',' '), HB_TAG('P','C','C',' ')},*/ /* Bouyei */ -/*{HB_TAG('p','c','d',' '), HB_TAG('P','C','D',' ')},*/ /* Picard */ {HB_TAG('p','c','e',' '), HB_TAG('P','L','G',' ')}, /* Ruching Palaung -> Palaung */ {HB_TAG('p','c','k',' '), HB_TAG('Q','I','N',' ')}, /* Paite Chin -> Chin */ {HB_TAG('p','c','m',' '), HB_TAG('C','P','P',' ')}, /* Nigerian Pidgin -> Creoles */ -/*{HB_TAG('p','d','c',' '), HB_TAG('P','D','C',' ')},*/ /* Pennsylvania German */ {HB_TAG('p','d','u',' '), HB_TAG('K','R','N',' ')}, /* Kayan -> Karen */ {HB_TAG('p','e','a',' '), HB_TAG('C','P','P',' ')}, /* Peranakan Indonesian -> Creoles */ {HB_TAG('p','e','l',' '), HB_TAG('M','L','Y',' ')}, /* Pekal -> Malay */ {HB_TAG('p','e','s',' '), HB_TAG('F','A','R',' ')}, /* Iranian Persian -> Persian */ {HB_TAG('p','e','y',' '), HB_TAG('C','P','P',' ')}, /* Petjo -> Creoles */ - {HB_TAG('p','g','a',' '), HB_TAG('A','R','A',' ')}, /* Sudanese Creole Arabic -> Arabic */ - {HB_TAG('p','g','a',' '), HB_TAG('C','P','P',' ')}, /* Sudanese Creole Arabic -> Creoles */ -/*{HB_TAG('p','h','k',' '), HB_TAG('P','H','K',' ')},*/ /* Phake */ - {HB_TAG('p','i','h',' '), HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk -> Norfolk */ - {HB_TAG('p','i','h',' '), HB_TAG('C','P','P',' ')}, /* Pitcairn-Norfolk -> Creoles */ - {HB_TAG('p','i','l',' '), HB_TAG_NONE }, /* Yom != Filipino */ {HB_TAG('p','i','s',' '), HB_TAG('C','P','P',' ')}, /* Pijin -> Creoles */ {HB_TAG('p','k','h',' '), HB_TAG('Q','I','N',' ')}, /* Pankhu -> Chin */ {HB_TAG('p','k','o',' '), HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */ {HB_TAG('p','l','g',' '), HB_TAG('P','L','G','0')}, /* Pilagá */ - {HB_TAG('p','l','k',' '), HB_TAG_NONE }, /* Kohistani Shina != Polish */ {HB_TAG('p','l','l',' '), HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */ {HB_TAG('p','l','n',' '), HB_TAG('C','P','P',' ')}, /* Palenquero -> Creoles */ {HB_TAG('p','l','p',' '), HB_TAG('P','A','P',' ')}, /* Palpa (retired code) */ {HB_TAG('p','l','t',' '), HB_TAG('M','L','G',' ')}, /* Plateau Malagasy -> Malagasy */ {HB_TAG('p','m','l',' '), HB_TAG('C','P','P',' ')}, /* Lingua Franca -> Creoles */ -/*{HB_TAG('p','m','s',' '), HB_TAG('P','M','S',' ')},*/ /* Piemontese */ {HB_TAG('p','m','y',' '), HB_TAG('C','P','P',' ')}, /* Papuan Malay -> Creoles */ -/*{HB_TAG('p','n','b',' '), HB_TAG('P','N','B',' ')},*/ /* Western Panjabi */ {HB_TAG('p','o','c',' '), HB_TAG('M','Y','N',' ')}, /* Poqomam -> Mayan */ - {HB_TAG('p','o','h',' '), HB_TAG('P','O','H',' ')}, /* Poqomchi' -> Pocomchi */ - {HB_TAG('p','o','h',' '), HB_TAG('M','Y','N',' ')}, /* Poqomchi' -> Mayan */ -/*{HB_TAG('p','o','n',' '), HB_TAG('P','O','N',' ')},*/ /* Pohnpeian */ {HB_TAG('p','o','v',' '), HB_TAG('C','P','P',' ')}, /* Upper Guinea Crioulo -> Creoles */ {HB_TAG('p','p','a',' '), HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */ {HB_TAG('p','r','e',' '), HB_TAG('C','P','P',' ')}, /* Principense -> Creoles */ -/*{HB_TAG('p','r','o',' '), HB_TAG('P','R','O',' ')},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */ {HB_TAG('p','r','p',' '), HB_TAG('G','U','J',' ')}, /* Parsi (retired code) -> Gujarati */ - {HB_TAG('p','r','s',' '), HB_TAG('D','R','I',' ')}, /* Dari */ - {HB_TAG('p','r','s',' '), HB_TAG('F','A','R',' ')}, /* Dari -> Persian */ {HB_TAG('p','s','e',' '), HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */ {HB_TAG('p','s','t',' '), HB_TAG('P','A','S',' ')}, /* Central Pashto -> Pashto */ {HB_TAG('p','u','b',' '), HB_TAG('Q','I','N',' ')}, /* Purum -> Chin */ {HB_TAG('p','u','z',' '), HB_TAG('Q','I','N',' ')}, /* Purum Naga (retired code) -> Chin */ - {HB_TAG('p','w','o',' '), HB_TAG('P','W','O',' ')}, /* Pwo Western Karen -> Western Pwo Karen */ - {HB_TAG('p','w','o',' '), HB_TAG('K','R','N',' ')}, /* Pwo Western Karen -> Karen */ {HB_TAG('p','w','w',' '), HB_TAG('K','R','N',' ')}, /* Pwo Northern Karen -> Karen */ - {HB_TAG('q','u','b',' '), HB_TAG('Q','W','H',' ')}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ - {HB_TAG('q','u','b',' '), HB_TAG('Q','U','Z',' ')}, /* Huallaga Huánuco Quechua -> Quechua */ - {HB_TAG('q','u','c',' '), HB_TAG('Q','U','C',' ')}, /* K’iche’ */ - {HB_TAG('q','u','c',' '), HB_TAG('M','Y','N',' ')}, /* K'iche' -> Mayan */ - {HB_TAG('q','u','d',' '), HB_TAG('Q','V','I',' ')}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','u','d',' '), HB_TAG('Q','U','Z',' ')}, /* Calderón Highland Quichua -> Quechua */ {HB_TAG('q','u','f',' '), HB_TAG('Q','U','Z',' ')}, /* Lambayeque Quechua -> Quechua */ - {HB_TAG('q','u','g',' '), HB_TAG('Q','V','I',' ')}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','u','g',' '), HB_TAG('Q','U','Z',' ')}, /* Chimborazo Highland Quichua -> Quechua */ - {HB_TAG('q','u','h',' '), HB_TAG('Q','U','H',' ')}, /* South Bolivian Quechua -> Quechua (Bolivia) */ - {HB_TAG('q','u','h',' '), HB_TAG('Q','U','Z',' ')}, /* South Bolivian Quechua -> Quechua */ {HB_TAG('q','u','k',' '), HB_TAG('Q','U','Z',' ')}, /* Chachapoyas Quechua -> Quechua */ - {HB_TAG('q','u','l',' '), HB_TAG('Q','U','H',' ')}, /* North Bolivian Quechua -> Quechua (Bolivia) */ - {HB_TAG('q','u','l',' '), HB_TAG('Q','U','Z',' ')}, /* North Bolivian Quechua -> Quechua */ {HB_TAG('q','u','m',' '), HB_TAG('M','Y','N',' ')}, /* Sipacapense -> Mayan */ - {HB_TAG('q','u','p',' '), HB_TAG('Q','V','I',' ')}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ - {HB_TAG('q','u','p',' '), HB_TAG('Q','U','Z',' ')}, /* Southern Pastaza Quechua -> Quechua */ - {HB_TAG('q','u','r',' '), HB_TAG('Q','W','H',' ')}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ - {HB_TAG('q','u','r',' '), HB_TAG('Q','U','Z',' ')}, /* Yanahuanca Pasco Quechua -> Quechua */ - {HB_TAG('q','u','s',' '), HB_TAG('Q','U','H',' ')}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */ - {HB_TAG('q','u','s',' '), HB_TAG('Q','U','Z',' ')}, /* Santiago del Estero Quichua -> Quechua */ {HB_TAG('q','u','v',' '), HB_TAG('M','Y','N',' ')}, /* Sacapulteco -> Mayan */ - {HB_TAG('q','u','w',' '), HB_TAG('Q','V','I',' ')}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','u','w',' '), HB_TAG('Q','U','Z',' ')}, /* Tena Lowland Quichua -> Quechua */ - {HB_TAG('q','u','x',' '), HB_TAG('Q','W','H',' ')}, /* Yauyos Quechua -> Quechua (Peru) */ - {HB_TAG('q','u','x',' '), HB_TAG('Q','U','Z',' ')}, /* Yauyos Quechua -> Quechua */ {HB_TAG('q','u','y',' '), HB_TAG('Q','U','Z',' ')}, /* Ayacucho Quechua -> Quechua */ -/*{HB_TAG('q','u','z',' '), HB_TAG('Q','U','Z',' ')},*/ /* Cusco Quechua -> Quechua */ - {HB_TAG('q','v','a',' '), HB_TAG('Q','W','H',' ')}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','a',' '), HB_TAG('Q','U','Z',' ')}, /* Ambo-Pasco Quechua -> Quechua */ {HB_TAG('q','v','c',' '), HB_TAG('Q','U','Z',' ')}, /* Cajamarca Quechua -> Quechua */ {HB_TAG('q','v','e',' '), HB_TAG('Q','U','Z',' ')}, /* Eastern Apurímac Quechua -> Quechua */ - {HB_TAG('q','v','h',' '), HB_TAG('Q','W','H',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','h',' '), HB_TAG('Q','U','Z',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua */ - {HB_TAG('q','v','i',' '), HB_TAG('Q','V','I',' ')}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','v','i',' '), HB_TAG('Q','U','Z',' ')}, /* Imbabura Highland Quichua -> Quechua */ - {HB_TAG('q','v','j',' '), HB_TAG('Q','V','I',' ')}, /* Loja Highland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','v','j',' '), HB_TAG('Q','U','Z',' ')}, /* Loja Highland Quichua -> Quechua */ - {HB_TAG('q','v','l',' '), HB_TAG('Q','W','H',' ')}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','l',' '), HB_TAG('Q','U','Z',' ')}, /* Cajatambo North Lima Quechua -> Quechua */ - {HB_TAG('q','v','m',' '), HB_TAG('Q','W','H',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','m',' '), HB_TAG('Q','U','Z',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua */ - {HB_TAG('q','v','n',' '), HB_TAG('Q','W','H',' ')}, /* North Junín Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','n',' '), HB_TAG('Q','U','Z',' ')}, /* North Junín Quechua -> Quechua */ - {HB_TAG('q','v','o',' '), HB_TAG('Q','V','I',' ')}, /* Napo Lowland Quechua -> Quechua (Ecuador) */ - {HB_TAG('q','v','o',' '), HB_TAG('Q','U','Z',' ')}, /* Napo Lowland Quechua -> Quechua */ - {HB_TAG('q','v','p',' '), HB_TAG('Q','W','H',' ')}, /* Pacaraos Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','p',' '), HB_TAG('Q','U','Z',' ')}, /* Pacaraos Quechua -> Quechua */ {HB_TAG('q','v','s',' '), HB_TAG('Q','U','Z',' ')}, /* San Martín Quechua -> Quechua */ - {HB_TAG('q','v','w',' '), HB_TAG('Q','W','H',' ')}, /* Huaylla Wanca Quechua -> Quechua (Peru) */ - {HB_TAG('q','v','w',' '), HB_TAG('Q','U','Z',' ')}, /* Huaylla Wanca Quechua -> Quechua */ - {HB_TAG('q','v','z',' '), HB_TAG('Q','V','I',' ')}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','v','z',' '), HB_TAG('Q','U','Z',' ')}, /* Northern Pastaza Quichua -> Quechua */ - {HB_TAG('q','w','a',' '), HB_TAG('Q','W','H',' ')}, /* Corongo Ancash Quechua -> Quechua (Peru) */ - {HB_TAG('q','w','a',' '), HB_TAG('Q','U','Z',' ')}, /* Corongo Ancash Quechua -> Quechua */ {HB_TAG('q','w','c',' '), HB_TAG('Q','U','Z',' ')}, /* Classical Quechua -> Quechua */ - {HB_TAG('q','w','h',' '), HB_TAG('Q','W','H',' ')}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ - {HB_TAG('q','w','h',' '), HB_TAG('Q','U','Z',' ')}, /* Huaylas Ancash Quechua -> Quechua */ - {HB_TAG('q','w','s',' '), HB_TAG('Q','W','H',' ')}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ - {HB_TAG('q','w','s',' '), HB_TAG('Q','U','Z',' ')}, /* Sihuas Ancash Quechua -> Quechua */ {HB_TAG('q','w','t',' '), HB_TAG('A','T','H',' ')}, /* Kwalhioqua-Tlatskanai -> Athapaskan */ - {HB_TAG('q','x','a',' '), HB_TAG('Q','W','H',' ')}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','a',' '), HB_TAG('Q','U','Z',' ')}, /* Chiquián Ancash Quechua -> Quechua */ - {HB_TAG('q','x','c',' '), HB_TAG('Q','W','H',' ')}, /* Chincha Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','c',' '), HB_TAG('Q','U','Z',' ')}, /* Chincha Quechua -> Quechua */ - {HB_TAG('q','x','h',' '), HB_TAG('Q','W','H',' ')}, /* Panao Huánuco Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','h',' '), HB_TAG('Q','U','Z',' ')}, /* Panao Huánuco Quechua -> Quechua */ - {HB_TAG('q','x','l',' '), HB_TAG('Q','V','I',' ')}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','x','l',' '), HB_TAG('Q','U','Z',' ')}, /* Salasaca Highland Quichua -> Quechua */ - {HB_TAG('q','x','n',' '), HB_TAG('Q','W','H',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','n',' '), HB_TAG('Q','U','Z',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua */ - {HB_TAG('q','x','o',' '), HB_TAG('Q','W','H',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','o',' '), HB_TAG('Q','U','Z',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua */ {HB_TAG('q','x','p',' '), HB_TAG('Q','U','Z',' ')}, /* Puno Quechua -> Quechua */ - {HB_TAG('q','x','r',' '), HB_TAG('Q','V','I',' ')}, /* Cañar Highland Quichua -> Quechua (Ecuador) */ - {HB_TAG('q','x','r',' '), HB_TAG('Q','U','Z',' ')}, /* Cañar Highland Quichua -> Quechua */ - {HB_TAG('q','x','t',' '), HB_TAG('Q','W','H',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','t',' '), HB_TAG('Q','U','Z',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua */ {HB_TAG('q','x','u',' '), HB_TAG('Q','U','Z',' ')}, /* Arequipa-La Unión Quechua -> Quechua */ - {HB_TAG('q','x','w',' '), HB_TAG('Q','W','H',' ')}, /* Jauja Wanca Quechua -> Quechua (Peru) */ - {HB_TAG('q','x','w',' '), HB_TAG('Q','U','Z',' ')}, /* Jauja Wanca Quechua -> Quechua */ {HB_TAG('r','a','g',' '), HB_TAG('L','U','H',' ')}, /* Logooli -> Luyia */ -/*{HB_TAG('r','a','j',' '), HB_TAG('R','A','J',' ')},*/ /* Rajasthani [macrolanguage] */ {HB_TAG('r','a','l',' '), HB_TAG('Q','I','N',' ')}, /* Ralte -> Chin */ -/*{HB_TAG('r','a','r',' '), HB_TAG('R','A','R',' ')},*/ /* Rarotongan */ {HB_TAG('r','b','b',' '), HB_TAG('P','L','G',' ')}, /* Rumai Palaung -> Palaung */ {HB_TAG('r','b','l',' '), HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */ {HB_TAG('r','c','f',' '), HB_TAG('C','P','P',' ')}, /* Réunion Creole French -> Creoles */ -/*{HB_TAG('r','e','j',' '), HB_TAG('R','E','J',' ')},*/ /* Rejang */ -/*{HB_TAG('r','h','g',' '), HB_TAG('R','H','G',' ')},*/ /* Rohingya */ -/*{HB_TAG('r','i','a',' '), HB_TAG('R','I','A',' ')},*/ /* Riang (India) */ - {HB_TAG('r','i','f',' '), HB_TAG('R','I','F',' ')}, /* Tarifit */ - {HB_TAG('r','i','f',' '), HB_TAG('B','B','R',' ')}, /* Tarifit -> Berber */ -/*{HB_TAG('r','i','t',' '), HB_TAG('R','I','T',' ')},*/ /* Ritharrngu -> Ritarungo */ {HB_TAG('r','k','i',' '), HB_TAG('A','R','K',' ')}, /* Rakhine */ -/*{HB_TAG('r','k','w',' '), HB_TAG('R','K','W',' ')},*/ /* Arakwal */ {HB_TAG('r','m','c',' '), HB_TAG('R','O','Y',' ')}, /* Carpathian Romani -> Romany */ {HB_TAG('r','m','f',' '), HB_TAG('R','O','Y',' ')}, /* Kalo Finnish Romani -> Romany */ {HB_TAG('r','m','l',' '), HB_TAG('R','O','Y',' ')}, /* Baltic Romani -> Romany */ {HB_TAG('r','m','n',' '), HB_TAG('R','O','Y',' ')}, /* Balkan Romani -> Romany */ {HB_TAG('r','m','o',' '), HB_TAG('R','O','Y',' ')}, /* Sinte Romani -> Romany */ - {HB_TAG('r','m','s',' '), HB_TAG_NONE }, /* Romanian Sign Language != Romansh */ {HB_TAG('r','m','w',' '), HB_TAG('R','O','Y',' ')}, /* Welsh Romani -> Romany */ - {HB_TAG('r','m','y',' '), HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ - {HB_TAG('r','m','y',' '), HB_TAG('R','O','Y',' ')}, /* Vlax Romani -> Romany */ {HB_TAG('r','m','z',' '), HB_TAG('A','R','K',' ')}, /* Marma -> Rakhine */ {HB_TAG('r','o','m',' '), HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ {HB_TAG('r','o','p',' '), HB_TAG('C','P','P',' ')}, /* Kriol -> Creoles */ {HB_TAG('r','t','c',' '), HB_TAG('Q','I','N',' ')}, /* Rungtu Chin -> Chin */ -/*{HB_TAG('r','t','m',' '), HB_TAG('R','T','M',' ')},*/ /* Rotuman */ {HB_TAG('r','u','e',' '), HB_TAG('R','S','Y',' ')}, /* Rusyn */ -/*{HB_TAG('r','u','p',' '), HB_TAG('R','U','P',' ')},*/ /* Aromanian */ {HB_TAG('r','w','r',' '), HB_TAG('M','A','W',' ')}, /* Marwari (India) */ - {HB_TAG('s','a','d',' '), HB_TAG_NONE }, /* Sandawe != Sadri */ {HB_TAG('s','a','h',' '), HB_TAG('Y','A','K',' ')}, /* Yakut -> Sakha */ {HB_TAG('s','a','m',' '), HB_TAG('P','A','A',' ')}, /* Samaritan Aramaic -> Palestinian Aramaic */ -/*{HB_TAG('s','a','s',' '), HB_TAG('S','A','S',' ')},*/ /* Sasak */ -/*{HB_TAG('s','a','t',' '), HB_TAG('S','A','T',' ')},*/ /* Santali */ - {HB_TAG('s','a','y',' '), HB_TAG_NONE }, /* Saya != Sayisi */ {HB_TAG('s','c','f',' '), HB_TAG('C','P','P',' ')}, /* San Miguel Creole French -> Creoles */ {HB_TAG('s','c','h',' '), HB_TAG('Q','I','N',' ')}, /* Sakachep -> Chin */ {HB_TAG('s','c','i',' '), HB_TAG('C','P','P',' ')}, /* Sri Lankan Creole Malay -> Creoles */ {HB_TAG('s','c','k',' '), HB_TAG('S','A','D',' ')}, /* Sadri */ -/*{HB_TAG('s','c','n',' '), HB_TAG('S','C','N',' ')},*/ /* Sicilian */ -/*{HB_TAG('s','c','o',' '), HB_TAG('S','C','O',' ')},*/ /* Scots */ - {HB_TAG('s','c','s',' '), HB_TAG('S','C','S',' ')}, /* North Slavey */ - {HB_TAG('s','c','s',' '), HB_TAG('S','L','A',' ')}, /* North Slavey -> Slavey */ - {HB_TAG('s','c','s',' '), HB_TAG('A','T','H',' ')}, /* North Slavey -> Athapaskan */ {HB_TAG('s','d','c',' '), HB_TAG('S','R','D',' ')}, /* Sassarese Sardinian -> Sardinian */ {HB_TAG('s','d','h',' '), HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */ {HB_TAG('s','d','n',' '), HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */ {HB_TAG('s','d','s',' '), HB_TAG('B','B','R',' ')}, /* Sened -> Berber */ -/*{HB_TAG('s','e','e',' '), HB_TAG('S','E','E',' ')},*/ /* Seneca */ {HB_TAG('s','e','h',' '), HB_TAG('S','N','A',' ')}, /* Sena */ {HB_TAG('s','e','k',' '), HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ -/*{HB_TAG('s','e','l',' '), HB_TAG('S','E','L',' ')},*/ /* Selkup */ {HB_TAG('s','e','z',' '), HB_TAG('Q','I','N',' ')}, /* Senthang Chin -> Chin */ - {HB_TAG('s','f','m',' '), HB_TAG('S','F','M',' ')}, /* Small Flowery Miao */ - {HB_TAG('s','f','m',' '), HB_TAG('H','M','N',' ')}, /* Small Flowery Miao -> Hmong */ -/*{HB_TAG('s','g','a',' '), HB_TAG('S','G','A',' ')},*/ /* Old Irish (to 900) */ {HB_TAG('s','g','c',' '), HB_TAG('K','A','L',' ')}, /* Kipsigis -> Kalenjin */ - {HB_TAG('s','g','o',' '), HB_TAG_NONE }, /* Songa (retired code) != Sango */ -/*{HB_TAG('s','g','s',' '), HB_TAG('S','G','S',' ')},*/ /* Samogitian */ {HB_TAG('s','g','w',' '), HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */ - {HB_TAG('s','h','i',' '), HB_TAG('S','H','I',' ')}, /* Tachelhit */ - {HB_TAG('s','h','i',' '), HB_TAG('B','B','R',' ')}, /* Tachelhit -> Berber */ {HB_TAG('s','h','l',' '), HB_TAG('Q','I','N',' ')}, /* Shendu -> Chin */ -/*{HB_TAG('s','h','n',' '), HB_TAG('S','H','N',' ')},*/ /* Shan */ {HB_TAG('s','h','u',' '), HB_TAG('A','R','A',' ')}, /* Chadian Arabic -> Arabic */ {HB_TAG('s','h','y',' '), HB_TAG('B','B','R',' ')}, /* Tachawit -> Berber */ - {HB_TAG('s','i','b',' '), HB_TAG_NONE }, /* Sebop != Sibe */ -/*{HB_TAG('s','i','d',' '), HB_TAG('S','I','D',' ')},*/ /* Sidamo */ - {HB_TAG('s','i','g',' '), HB_TAG_NONE }, /* Paasaal != Silte Gurage */ {HB_TAG('s','i','z',' '), HB_TAG('B','B','R',' ')}, /* Siwi -> Berber */ -/*{HB_TAG('s','j','a',' '), HB_TAG('S','J','A',' ')},*/ /* Epena */ + {HB_TAG('s','j','c',' '), HB_TAG('Z','H','S',' ')}, /* Shaojiang Chinese -> Chinese, Simplified */ {HB_TAG('s','j','d',' '), HB_TAG('K','S','M',' ')}, /* Kildin Sami */ {HB_TAG('s','j','o',' '), HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ {HB_TAG('s','j','s',' '), HB_TAG('B','B','R',' ')}, /* Senhaja De Srair -> Berber */ {HB_TAG('s','k','g',' '), HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */ {HB_TAG('s','k','r',' '), HB_TAG('S','R','K',' ')}, /* Saraiki */ - {HB_TAG('s','k','s',' '), HB_TAG_NONE }, /* Maia != Skolt Sami */ {HB_TAG('s','k','w',' '), HB_TAG('C','P','P',' ')}, /* Skepi Creole Dutch -> Creoles */ - {HB_TAG('s','k','y',' '), HB_TAG_NONE }, /* Sikaiana != Slovak */ - {HB_TAG('s','l','a',' '), HB_TAG_NONE }, /* Slavic [collection] != Slavey */ {HB_TAG('s','m','a',' '), HB_TAG('S','S','M',' ')}, /* Southern Sami */ {HB_TAG('s','m','d',' '), HB_TAG('M','B','N',' ')}, /* Sama (retired code) -> Mbundu */ {HB_TAG('s','m','j',' '), HB_TAG('L','S','M',' ')}, /* Lule Sami */ - {HB_TAG('s','m','l',' '), HB_TAG_NONE }, /* Central Sama != Somali */ {HB_TAG('s','m','n',' '), HB_TAG('I','S','M',' ')}, /* Inari Sami */ {HB_TAG('s','m','s',' '), HB_TAG('S','K','S',' ')}, /* Skolt Sami */ {HB_TAG('s','m','t',' '), HB_TAG('Q','I','N',' ')}, /* Simte -> Chin */ {HB_TAG('s','n','b',' '), HB_TAG('I','B','A',' ')}, /* Sebuyau (retired code) -> Iban */ - {HB_TAG('s','n','h',' '), HB_TAG_NONE }, /* Shinabo (retired code) != Sinhala (Sinhalese) */ -/*{HB_TAG('s','n','k',' '), HB_TAG('S','N','K',' ')},*/ /* Soninke */ - {HB_TAG('s','o','g',' '), HB_TAG_NONE }, /* Sogdian != Sodo Gurage */ -/*{HB_TAG('s','o','p',' '), HB_TAG('S','O','P',' ')},*/ /* Songe */ {HB_TAG('s','p','v',' '), HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia */ {HB_TAG('s','p','y',' '), HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ - {HB_TAG('s','r','b',' '), HB_TAG_NONE }, /* Sora != Serbian */ {HB_TAG('s','r','c',' '), HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ - {HB_TAG('s','r','k',' '), HB_TAG_NONE }, /* Serudung Murut != Saraiki */ {HB_TAG('s','r','m',' '), HB_TAG('C','P','P',' ')}, /* Saramaccan -> Creoles */ {HB_TAG('s','r','n',' '), HB_TAG('C','P','P',' ')}, /* Sranan Tongo -> Creoles */ {HB_TAG('s','r','o',' '), HB_TAG('S','R','D',' ')}, /* Campidanese Sardinian -> Sardinian */ -/*{HB_TAG('s','r','r',' '), HB_TAG('S','R','R',' ')},*/ /* Serer */ {HB_TAG('s','r','s',' '), HB_TAG('A','T','H',' ')}, /* Sarsi -> Athapaskan */ {HB_TAG('s','s','h',' '), HB_TAG('A','R','A',' ')}, /* Shihhi Arabic -> Arabic */ - {HB_TAG('s','s','l',' '), HB_TAG_NONE }, /* Western Sisaala != South Slavey */ - {HB_TAG('s','s','m',' '), HB_TAG_NONE }, /* Semnam != Southern Sami */ {HB_TAG('s','t','a',' '), HB_TAG('C','P','P',' ')}, /* Settla -> Creoles */ -/*{HB_TAG('s','t','q',' '), HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */ -/*{HB_TAG('s','t','r',' '), HB_TAG('S','T','R',' ')},*/ /* Straits Salish */ {HB_TAG('s','t','v',' '), HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */ -/*{HB_TAG('s','u','k',' '), HB_TAG('S','U','K',' ')},*/ /* Sukuma */ {HB_TAG('s','u','q',' '), HB_TAG('S','U','R',' ')}, /* Suri */ - {HB_TAG('s','u','r',' '), HB_TAG_NONE }, /* Mwaghavul != Suri */ -/*{HB_TAG('s','v','a',' '), HB_TAG('S','V','A',' ')},*/ /* Svan */ {HB_TAG('s','v','c',' '), HB_TAG('C','P','P',' ')}, /* Vincentian Creole English -> Creoles */ - {HB_TAG('s','v','e',' '), HB_TAG_NONE }, /* Serili != Swedish */ {HB_TAG('s','w','b',' '), HB_TAG('C','M','R',' ')}, /* Maore Comorian -> Comorian */ {HB_TAG('s','w','c',' '), HB_TAG('S','W','K',' ')}, /* Congo Swahili -> Swahili */ {HB_TAG('s','w','h',' '), HB_TAG('S','W','K',' ')}, /* Swahili */ - {HB_TAG('s','w','k',' '), HB_TAG_NONE }, /* Malawi Sena != Swahili */ {HB_TAG('s','w','n',' '), HB_TAG('B','B','R',' ')}, /* Sawknah -> Berber */ {HB_TAG('s','w','v',' '), HB_TAG('M','A','W',' ')}, /* Shekhawati -> Marwari */ -/*{HB_TAG('s','x','u',' '), HB_TAG('S','X','U',' ')},*/ /* Upper Saxon */ {HB_TAG('s','y','c',' '), HB_TAG('S','Y','R',' ')}, /* Classical Syriac -> Syriac */ -/*{HB_TAG('s','y','l',' '), HB_TAG('S','Y','L',' ')},*/ /* Sylheti */ -/*{HB_TAG('s','y','r',' '), HB_TAG('S','Y','R',' ')},*/ /* Syriac [macrolanguage] */ -/*{HB_TAG('s','z','l',' '), HB_TAG('S','Z','L',' ')},*/ /* Silesian */ {HB_TAG('t','a','a',' '), HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */ -/*{HB_TAG('t','a','b',' '), HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */ - {HB_TAG('t','a','j',' '), HB_TAG_NONE }, /* Eastern Tamang != Tajiki */ - {HB_TAG('t','a','q',' '), HB_TAG('T','A','Q',' ')}, /* Tamasheq */ - {HB_TAG('t','a','q',' '), HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */ - {HB_TAG('t','a','q',' '), HB_TAG('B','B','R',' ')}, /* Tamasheq -> Berber */ {HB_TAG('t','a','s',' '), HB_TAG('C','P','P',' ')}, /* Tay Boi -> Creoles */ {HB_TAG('t','a','u',' '), HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */ {HB_TAG('t','c','b',' '), HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */ @@ -1468,115 +1062,54 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','c','s',' '), HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */ {HB_TAG('t','c','y',' '), HB_TAG('T','U','L',' ')}, /* Tulu */ {HB_TAG('t','c','z',' '), HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ -/*{HB_TAG('t','d','c',' '), HB_TAG('T','D','C',' ')},*/ /* Emberá-Tadó */ -/*{HB_TAG('t','d','d',' '), HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */ {HB_TAG('t','d','x',' '), HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ {HB_TAG('t','e','c',' '), HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */ {HB_TAG('t','e','m',' '), HB_TAG('T','M','N',' ')}, /* Timne -> Temne */ -/*{HB_TAG('t','e','t',' '), HB_TAG('T','E','T',' ')},*/ /* Tetum */ {HB_TAG('t','e','z',' '), HB_TAG('B','B','R',' ')}, /* Tetserret -> Berber */ {HB_TAG('t','f','n',' '), HB_TAG('A','T','H',' ')}, /* Tanaina -> Athapaskan */ {HB_TAG('t','g','h',' '), HB_TAG('C','P','P',' ')}, /* Tobagonian Creole English -> Creoles */ {HB_TAG('t','g','j',' '), HB_TAG('N','I','S',' ')}, /* Tagin -> Nisi */ - {HB_TAG('t','g','n',' '), HB_TAG_NONE }, /* Tandaganon != Tongan */ - {HB_TAG('t','g','r',' '), HB_TAG_NONE }, /* Tareng != Tigre */ {HB_TAG('t','g','x',' '), HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */ - {HB_TAG('t','g','y',' '), HB_TAG_NONE }, /* Togoyo != Tigrinya */ -/*{HB_TAG('t','h','p',' '), HB_TAG('T','H','P',' ')},*/ /* Thompson */ {HB_TAG('t','h','t',' '), HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */ - {HB_TAG('t','h','v',' '), HB_TAG('T','H','V',' ')}, /* Tahaggart Tamahaq */ - {HB_TAG('t','h','v',' '), HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */ - {HB_TAG('t','h','v',' '), HB_TAG('B','B','R',' ')}, /* Tahaggart Tamahaq -> Berber */ - {HB_TAG('t','h','z',' '), HB_TAG('T','H','Z',' ')}, /* Tayart Tamajeq */ - {HB_TAG('t','h','z',' '), HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */ - {HB_TAG('t','h','z',' '), HB_TAG('B','B','R',' ')}, /* Tayart Tamajeq -> Berber */ {HB_TAG('t','i','a',' '), HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */ {HB_TAG('t','i','g',' '), HB_TAG('T','G','R',' ')}, /* Tigre */ -/*{HB_TAG('t','i','v',' '), HB_TAG('T','I','V',' ')},*/ /* Tiv */ -/*{HB_TAG('t','j','l',' '), HB_TAG('T','J','L',' ')},*/ /* Tai Laing */ {HB_TAG('t','j','o',' '), HB_TAG('B','B','R',' ')}, /* Temacine Tamazight -> Berber */ {HB_TAG('t','k','g',' '), HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ - {HB_TAG('t','k','m',' '), HB_TAG_NONE }, /* Takelma != Turkmen */ -/*{HB_TAG('t','l','i',' '), HB_TAG('T','L','I',' ')},*/ /* Tlingit */ -/*{HB_TAG('t','l','y',' '), HB_TAG('T','L','Y',' ')},*/ /* Talysh */ {HB_TAG('t','m','g',' '), HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */ - {HB_TAG('t','m','h',' '), HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ - {HB_TAG('t','m','h',' '), HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */ - {HB_TAG('t','m','n',' '), HB_TAG_NONE }, /* Taman (Indonesia) != Temne */ {HB_TAG('t','m','w',' '), HB_TAG('M','L','Y',' ')}, /* Temuan -> Malay */ - {HB_TAG('t','n','a',' '), HB_TAG_NONE }, /* Tacana != Tswana */ - {HB_TAG('t','n','e',' '), HB_TAG_NONE }, /* Tinoc Kallahan (retired code) != Tundra Enets */ - {HB_TAG('t','n','f',' '), HB_TAG('D','R','I',' ')}, /* Tangshewi (retired code) -> Dari */ - {HB_TAG('t','n','f',' '), HB_TAG('F','A','R',' ')}, /* Tangshewi (retired code) -> Persian */ - {HB_TAG('t','n','g',' '), HB_TAG_NONE }, /* Tobanga != Tonga */ {HB_TAG('t','o','d',' '), HB_TAG('T','O','D','0')}, /* Toma */ {HB_TAG('t','o','i',' '), HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */ {HB_TAG('t','o','j',' '), HB_TAG('M','Y','N',' ')}, /* Tojolabal -> Mayan */ {HB_TAG('t','o','l',' '), HB_TAG('A','T','H',' ')}, /* Tolowa -> Athapaskan */ {HB_TAG('t','o','r',' '), HB_TAG('B','A','D','0')}, /* Togbo-Vara Banda -> Banda */ - {HB_TAG('t','p','i',' '), HB_TAG('T','P','I',' ')}, /* Tok Pisin */ - {HB_TAG('t','p','i',' '), HB_TAG('C','P','P',' ')}, /* Tok Pisin -> Creoles */ {HB_TAG('t','r','f',' '), HB_TAG('C','P','P',' ')}, /* Trinidadian Creole English -> Creoles */ - {HB_TAG('t','r','k',' '), HB_TAG_NONE }, /* Turkic [collection] != Turkish */ - {HB_TAG('t','r','u',' '), HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */ - {HB_TAG('t','r','u',' '), HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */ - {HB_TAG('t','s','g',' '), HB_TAG_NONE }, /* Tausug != Tsonga */ -/*{HB_TAG('t','s','j',' '), HB_TAG('T','S','J',' ')},*/ /* Tshangla */ {HB_TAG('t','t','c',' '), HB_TAG('M','Y','N',' ')}, /* Tektiteko -> Mayan */ {HB_TAG('t','t','m',' '), HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */ - {HB_TAG('t','t','q',' '), HB_TAG('T','T','Q',' ')}, /* Tawallammat Tamajaq */ - {HB_TAG('t','t','q',' '), HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ - {HB_TAG('t','t','q',' '), HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */ - {HB_TAG('t','u','a',' '), HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */ - {HB_TAG('t','u','l',' '), HB_TAG_NONE }, /* Tula != Tulu */ -/*{HB_TAG('t','u','m',' '), HB_TAG('T','U','M',' ')},*/ /* Tumbuka */ -/*{HB_TAG('t','u','s',' '), HB_TAG('T','U','S',' ')},*/ /* Tuscarora */ {HB_TAG('t','u','u',' '), HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ - {HB_TAG('t','u','v',' '), HB_TAG_NONE }, /* Turkana != Tuvin */ {HB_TAG('t','u','y',' '), HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ -/*{HB_TAG('t','v','l',' '), HB_TAG('T','V','L',' ')},*/ /* Tuvalu */ {HB_TAG('t','v','y',' '), HB_TAG('C','P','P',' ')}, /* Timor Pidgin -> Creoles */ {HB_TAG('t','x','c',' '), HB_TAG('A','T','H',' ')}, /* Tsetsaut -> Athapaskan */ {HB_TAG('t','x','y',' '), HB_TAG('M','L','G',' ')}, /* Tanosy Malagasy -> Malagasy */ {HB_TAG('t','y','v',' '), HB_TAG('T','U','V',' ')}, /* Tuvinian -> Tuvin */ -/*{HB_TAG('t','y','z',' '), HB_TAG('T','Y','Z',' ')},*/ /* Tày */ {HB_TAG('t','z','h',' '), HB_TAG('M','Y','N',' ')}, /* Tzeltal -> Mayan */ {HB_TAG('t','z','j',' '), HB_TAG('M','Y','N',' ')}, /* Tz'utujil -> Mayan */ - {HB_TAG('t','z','m',' '), HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight -> Tamazight */ - {HB_TAG('t','z','m',' '), HB_TAG('B','B','R',' ')}, /* Central Atlas Tamazight -> Berber */ - {HB_TAG('t','z','o',' '), HB_TAG('T','Z','O',' ')}, /* Tzotzil */ - {HB_TAG('t','z','o',' '), HB_TAG('M','Y','N',' ')}, /* Tzotzil -> Mayan */ {HB_TAG('u','b','l',' '), HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */ -/*{HB_TAG('u','d','i',' '), HB_TAG('U','D','I',' ')},*/ /* Udi */ -/*{HB_TAG('u','d','m',' '), HB_TAG('U','D','M',' ')},*/ /* Udmurt */ {HB_TAG('u','k','i',' '), HB_TAG('K','U','I',' ')}, /* Kui (India) */ {HB_TAG('u','l','n',' '), HB_TAG('C','P','P',' ')}, /* Unserdeutsch -> Creoles */ -/*{HB_TAG('u','m','b',' '), HB_TAG('U','M','B',' ')},*/ /* Umbundu */ {HB_TAG('u','n','r',' '), HB_TAG('M','U','N',' ')}, /* Mundari */ {HB_TAG('u','r','k',' '), HB_TAG('M','L','Y',' ')}, /* Urak Lawoi' -> Malay */ {HB_TAG('u','s','p',' '), HB_TAG('M','Y','N',' ')}, /* Uspanteco -> Mayan */ {HB_TAG('u','z','n',' '), HB_TAG('U','Z','B',' ')}, /* Northern Uzbek -> Uzbek */ {HB_TAG('u','z','s',' '), HB_TAG('U','Z','B',' ')}, /* Southern Uzbek -> Uzbek */ {HB_TAG('v','a','p',' '), HB_TAG('Q','I','N',' ')}, /* Vaiphei -> Chin */ -/*{HB_TAG('v','e','c',' '), HB_TAG('V','E','C',' ')},*/ /* Venetian */ {HB_TAG('v','i','c',' '), HB_TAG('C','P','P',' ')}, /* Virgin Islands Creole English -> Creoles */ - {HB_TAG('v','i','t',' '), HB_TAG_NONE }, /* Viti != Vietnamese */ {HB_TAG('v','k','k',' '), HB_TAG('M','L','Y',' ')}, /* Kaur -> Malay */ {HB_TAG('v','k','p',' '), HB_TAG('C','P','P',' ')}, /* Korlai Creole Portuguese -> Creoles */ {HB_TAG('v','k','t',' '), HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */ {HB_TAG('v','l','s',' '), HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {HB_TAG('v','m','w',' '), HB_TAG('M','A','K',' ')}, /* Makhuwa */ - {HB_TAG('v','r','o',' '), HB_TAG('V','R','O',' ')}, /* Võro */ - {HB_TAG('v','r','o',' '), HB_TAG('E','T','I',' ')}, /* Võro -> Estonian */ {HB_TAG('v','s','n',' '), HB_TAG('S','A','N',' ')}, /* Vedic Sanskrit -> Sanskrit */ - {HB_TAG('w','a','g',' '), HB_TAG_NONE }, /* Wa'ema != Wagdi */ -/*{HB_TAG('w','a','r',' '), HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ -/*{HB_TAG('w','b','l',' '), HB_TAG('W','B','L',' ')},*/ /* Wakhi */ {HB_TAG('w','b','m',' '), HB_TAG('W','A',' ',' ')}, /* Wa */ - {HB_TAG('w','b','r',' '), HB_TAG('W','A','G',' ')}, /* Wagdi */ - {HB_TAG('w','b','r',' '), HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */ -/*{HB_TAG('w','c','i',' '), HB_TAG('W','C','I',' ')},*/ /* Waci Gbe */ -/*{HB_TAG('w','d','t',' '), HB_TAG('W','D','T',' ')},*/ /* Wendat */ {HB_TAG('w','e','a',' '), HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */ {HB_TAG('w','e','s',' '), HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */ {HB_TAG('w','e','u',' '), HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */ @@ -1586,62 +1119,31 @@ static const LangTag ot_languages3[] = { {HB_TAG('w','n','i',' '), HB_TAG('C','M','R',' ')}, /* Ndzwani Comorian -> Comorian */ {HB_TAG('w','r','y',' '), HB_TAG('M','A','W',' ')}, /* Merwari -> Marwari */ {HB_TAG('w','s','g',' '), HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */ -/*{HB_TAG('w','t','m',' '), HB_TAG('W','T','M',' ')},*/ /* Mewati */ {HB_TAG('w','u','u',' '), HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese, Simplified */ - {HB_TAG('w','y','a',' '), HB_TAG('W','D','T',' ')}, /* Wyandot (retired code) -> Wendat */ - {HB_TAG('w','y','a',' '), HB_TAG('W','Y','N',' ')}, /* Wyandot (retired code) */ -/*{HB_TAG('w','y','n',' '), HB_TAG('W','Y','N',' ')},*/ /* Wyandot */ - {HB_TAG('x','a','l',' '), HB_TAG('K','L','M',' ')}, /* Kalmyk */ - {HB_TAG('x','a','l',' '), HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */ {HB_TAG('x','a','n',' '), HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */ - {HB_TAG('x','b','d',' '), HB_TAG_NONE }, /* Bindal != Lü */ -/*{HB_TAG('x','j','b',' '), HB_TAG('X','J','B',' ')},*/ /* Minjungbal -> Minjangbal */ -/*{HB_TAG('x','k','f',' '), HB_TAG('X','K','F',' ')},*/ /* Khengkha */ {HB_TAG('x','m','g',' '), HB_TAG('B','M','L',' ')}, /* Mengaka -> Bamileke */ - {HB_TAG('x','m','m',' '), HB_TAG('M','L','Y',' ')}, /* Manado Malay -> Malay */ - {HB_TAG('x','m','m',' '), HB_TAG('C','P','P',' ')}, /* Manado Malay -> Creoles */ {HB_TAG('x','m','v',' '), HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */ {HB_TAG('x','m','w',' '), HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */ {HB_TAG('x','n','j',' '), HB_TAG('S','X','T',' ')}, /* Ngoni (Tanzania) -> Sutu */ {HB_TAG('x','n','q',' '), HB_TAG('S','X','T',' ')}, /* Ngoni (Mozambique) -> Sutu */ {HB_TAG('x','n','r',' '), HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri (macrolanguage) */ -/*{HB_TAG('x','o','g',' '), HB_TAG('X','O','G',' ')},*/ /* Soga */ - {HB_TAG('x','p','e',' '), HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */ - {HB_TAG('x','p','e',' '), HB_TAG('K','P','L',' ')}, /* Liberia Kpelle -> Kpelle */ - {HB_TAG('x','s','l',' '), HB_TAG('S','S','L',' ')}, /* South Slavey */ - {HB_TAG('x','s','l',' '), HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */ - {HB_TAG('x','s','l',' '), HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */ {HB_TAG('x','s','t',' '), HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */ -/*{HB_TAG('x','u','b',' '), HB_TAG('X','U','B',' ')},*/ /* Betta Kurumba -> Bette Kuruma */ -/*{HB_TAG('x','u','j',' '), HB_TAG('X','U','J',' ')},*/ /* Jennu Kurumba -> Jennu Kuruma */ {HB_TAG('x','u','p',' '), HB_TAG('A','T','H',' ')}, /* Upper Umpqua -> Athapaskan */ {HB_TAG('x','w','o',' '), HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */ {HB_TAG('y','a','j',' '), HB_TAG('B','A','D','0')}, /* Banda-Yangere -> Banda */ - {HB_TAG('y','a','k',' '), HB_TAG_NONE }, /* Yakama != Sakha */ -/*{HB_TAG('y','a','o',' '), HB_TAG('Y','A','O',' ')},*/ /* Yao */ -/*{HB_TAG('y','a','p',' '), HB_TAG('Y','A','P',' ')},*/ /* Yapese */ - {HB_TAG('y','b','a',' '), HB_TAG_NONE }, /* Yala != Yoruba */ {HB_TAG('y','b','b',' '), HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */ {HB_TAG('y','b','d',' '), HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ - {HB_TAG('y','c','r',' '), HB_TAG_NONE }, /* Yilan Creole != Y-Cree */ + {HB_TAG('y','c','r',' '), HB_TAG('C','P','P',' ')}, /* Yilan Creole -> Creoles */ {HB_TAG('y','d','d',' '), HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ -/*{HB_TAG('y','g','p',' '), HB_TAG('Y','G','P',' ')},*/ /* Gepo */ {HB_TAG('y','i','h',' '), HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ - {HB_TAG('y','i','m',' '), HB_TAG_NONE }, /* Yimchungru Naga != Yi Modern */ -/*{HB_TAG('y','n','a',' '), HB_TAG('Y','N','A',' ')},*/ /* Aluo */ {HB_TAG('y','o','s',' '), HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */ {HB_TAG('y','u','a',' '), HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */ {HB_TAG('y','u','e',' '), HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */ -/*{HB_TAG('y','u','f',' '), HB_TAG('Y','U','F',' ')},*/ /* Havasupai-Walapai-Yavapai */ -/*{HB_TAG('y','w','q',' '), HB_TAG('Y','W','Q',' ')},*/ /* Wuding-Luquan Yi */ {HB_TAG('z','c','h',' '), HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ {HB_TAG('z','d','j',' '), HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ -/*{HB_TAG('z','e','a',' '), HB_TAG('Z','E','A',' ')},*/ /* Zeeuws -> Zealandic */ {HB_TAG('z','e','h',' '), HB_TAG('Z','H','A',' ')}, /* Eastern Hongshuihe Zhuang -> Zhuang */ {HB_TAG('z','e','n',' '), HB_TAG('B','B','R',' ')}, /* Zenaga -> Berber */ {HB_TAG('z','g','b',' '), HB_TAG('Z','H','A',' ')}, /* Guibei Zhuang -> Zhuang */ - {HB_TAG('z','g','h',' '), HB_TAG('Z','G','H',' ')}, /* Standard Moroccan Tamazight */ - {HB_TAG('z','g','h',' '), HB_TAG('B','B','R',' ')}, /* Standard Moroccan Tamazight -> Berber */ {HB_TAG('z','g','m',' '), HB_TAG('Z','H','A',' ')}, /* Minz Zhuang -> Zhuang */ {HB_TAG('z','g','n',' '), HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */ {HB_TAG('z','h','d',' '), HB_TAG('Z','H','A',' ')}, /* Dai Zhuang -> Zhuang */ @@ -1653,7 +1155,6 @@ static const LangTag ot_languages3[] = { {HB_TAG('z','l','q',' '), HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */ {HB_TAG('z','m','i',' '), HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */ {HB_TAG('z','m','z',' '), HB_TAG('B','A','D','0')}, /* Mbandja -> Banda */ - {HB_TAG('z','n','d',' '), HB_TAG_NONE }, /* Zande [collection] != Zande */ {HB_TAG('z','n','e',' '), HB_TAG('Z','N','D',' ')}, /* Zande */ {HB_TAG('z','o','m',' '), HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */ {HB_TAG('z','q','e',' '), HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */ @@ -1664,9 +1165,439 @@ static const LangTag ot_languages3[] = { {HB_TAG('z','y','j',' '), HB_TAG('Z','H','A',' ')}, /* Youjiang Zhuang -> Zhuang */ {HB_TAG('z','y','n',' '), HB_TAG('Z','H','A',' ')}, /* Yongnan Zhuang -> Zhuang */ {HB_TAG('z','y','p',' '), HB_TAG('Q','I','N',' ')}, /* Zyphe Chin -> Chin */ -/*{HB_TAG('z','z','a',' '), HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */ {HB_TAG('z','z','j',' '), HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */ }; + +static const hb_tag_t ot_languages3_multi_values[] = { + HB_TAG('F','A','N',' '), /* Saint Lucian Creole French -> French Antillean */ + HB_TAG('C','P','P',' '), /* Saint Lucian Creole French -> Creoles */ + HB_TAG('A','C','R',' '), /* Achi */ + HB_TAG('M','Y','N',' '), /* Achi -> Mayan */ + HB_TAG('A','C','Y',' '), /* Cypriot Arabic */ + HB_TAG('A','R','A',' '), /* Cypriot Arabic -> Arabic */ + HB_TAG('S','W','A',' '), /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ + HB_TAG('S','Y','R',' '), /* Assyrian Neo-Aramaic -> Syriac */ + HB_TAG('A','K','B',' '), /* Batak Angkola */ + HB_TAG('B','T','K',' '), /* Batak Angkola -> Batak */ + HB_TAG('M','O','R',' '), /* Moroccan Arabic -> Moroccan */ + HB_TAG('A','R','A',' '), /* Moroccan Arabic -> Arabic */ + HB_TAG('A','Z','B',' '), /* South Azerbaijani -> Torki */ + HB_TAG('A','Z','E',' '), /* South Azerbaijani -> Azerbaijani */ + HB_TAG('B','B','C',' '), /* Batak Toba */ + HB_TAG('B','T','K',' '), /* Batak Toba -> Batak */ + HB_TAG('B','G','Q',' '), /* Bagri */ + HB_TAG('R','A','J',' '), /* Bagri -> Rajasthani */ + HB_TAG('B','L','K',' '), /* Pa’o Karen */ + HB_TAG('K','R','N',' '), /* Pa'o Karen -> Karen */ + HB_TAG('B','T','D',' '), /* Batak Dairi (Pakpak) */ + HB_TAG('B','T','K',' '), /* Batak Dairi -> Batak */ + HB_TAG('B','T','M',' '), /* Batak Mandailing */ + HB_TAG('B','T','K',' '), /* Batak Mandailing -> Batak */ + HB_TAG('B','T','S',' '), /* Batak Simalungun */ + HB_TAG('B','T','K',' '), /* Batak Simalungun -> Batak */ + HB_TAG('B','T','X',' '), /* Batak Karo */ + HB_TAG('B','T','K',' '), /* Batak Karo -> Batak */ + HB_TAG('B','T','Z',' '), /* Batak Alas-Kluet */ + HB_TAG('B','T','K',' '), /* Batak Alas-Kluet -> Batak */ + HB_TAG('B','Y','V',' '), /* Medumba */ + HB_TAG('B','M','L',' '), /* Medumba -> Bamileke */ + HB_TAG('C','R','R',' '), /* Southern Carrier -> Carrier */ + HB_TAG('A','T','H',' '), /* Southern Carrier -> Athapaskan */ + HB_TAG('C','A','K',' '), /* Kaqchikel */ + HB_TAG('M','Y','N',' '), /* Kaqchikel -> Mayan */ + HB_TAG('C','B','K',' '), /* Chavacano -> Zamboanga Chavacano */ + HB_TAG('C','P','P',' '), /* Chavacano -> Creoles */ + HB_TAG('H','A','L',' '), /* Halam (Falam Chin) */ + HB_TAG('Q','I','N',' '), /* Falam Chin -> Chin */ + HB_TAG('H','M','A',' '), /* Mari (Russia) [macrolanguage] -> High Mari */ + HB_TAG('L','M','A',' '), /* Mari (Russia) [macrolanguage] -> Low Mari */ + HB_TAG('C','H','P',' '), /* Chipewyan */ + HB_TAG('S','A','Y',' '), /* Chipewyan -> Sayisi */ + HB_TAG('A','T','H',' '), /* Chipewyan -> Athapaskan */ + HB_TAG('Q','U','H',' '), /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ + HB_TAG('Q','U','Z',' '), /* Chilean Quechua (retired code) -> Quechua */ + HB_TAG('E','C','R',' '), /* Southern East Cree -> Eastern Cree */ + HB_TAG('Y','C','R',' '), /* Southern East Cree -> Y-Cree */ + HB_TAG('C','R','E',' '), /* Southern East Cree -> Cree */ + HB_TAG('W','C','R',' '), /* Plains Cree -> West-Cree */ + HB_TAG('Y','C','R',' '), /* Plains Cree -> Y-Cree */ + HB_TAG('C','R','E',' '), /* Plains Cree -> Cree */ + HB_TAG('E','C','R',' '), /* Northern East Cree -> Eastern Cree */ + HB_TAG('Y','C','R',' '), /* Northern East Cree -> Y-Cree */ + HB_TAG('C','R','E',' '), /* Northern East Cree -> Cree */ + HB_TAG('M','C','R',' '), /* Moose Cree */ + HB_TAG('L','C','R',' '), /* Moose Cree -> L-Cree */ + HB_TAG('C','R','E',' '), /* Moose Cree -> Cree */ + HB_TAG('C','R','R',' '), /* Carrier */ + HB_TAG('A','T','H',' '), /* Carrier -> Athapaskan */ + HB_TAG('N','C','R',' '), /* Swampy Cree -> N-Cree */ + HB_TAG('N','H','C',' '), /* Swampy Cree -> Norway House Cree */ + HB_TAG('C','R','E',' '), /* Swampy Cree -> Cree */ + HB_TAG('D','C','R',' '), /* Woods Cree */ + HB_TAG('T','C','R',' '), /* Woods Cree -> TH-Cree */ + HB_TAG('C','R','E',' '), /* Woods Cree -> Cree */ + HB_TAG('S','L','A',' '), /* Slave (Athapascan) [macrolanguage] -> Slavey */ + HB_TAG('A','T','H',' '), /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ + HB_TAG('D','G','O',' '), /* Dogri (individual language) */ + HB_TAG('D','G','R',' '), /* Dogri (macrolanguage) */ + HB_TAG('D','I','Q',' '), /* Dimli */ + HB_TAG('Z','Z','A',' '), /* Dimli -> Zazaki */ + HB_TAG('D','R','I',' '), /* Darwazi (retired code) -> Dari */ + HB_TAG('F','A','R',' '), /* Darwazi (retired code) -> Persian */ + HB_TAG('E','M','K',' '), /* Eastern Maninkakan */ + HB_TAG('M','N','K',' '), /* Eastern Maninkakan -> Maninka */ + HB_TAG('F','A','N','0'), /* Fang (Equatorial Guinea) */ + HB_TAG('B','T','I',' '), /* Fang (Equatorial Guinea) -> Beti */ + HB_TAG('F','A','T',' '), /* Fanti */ + HB_TAG('A','K','A',' '), /* Fanti -> Akan */ + HB_TAG('H','A','L',' '), /* Halam (Falam Chin) (retired code) */ + HB_TAG('Q','I','N',' '), /* Falam Chin (retired code) -> Chin */ + HB_TAG('F','M','P',' '), /* Fe’fe’ */ + HB_TAG('B','M','L',' '), /* Fe'fe' -> Bamileke */ + HB_TAG('F','T','A',' '), /* Pular -> Futa */ + HB_TAG('F','U','L',' '), /* Pular -> Fulah */ + HB_TAG('F','U','V',' '), /* Nigerian Fulfulde */ + HB_TAG('F','U','L',' '), /* Nigerian Fulfulde -> Fulah */ + HB_TAG('G','K','P',' '), /* Guinea Kpelle -> Kpelle (Guinea) */ + HB_TAG('K','P','L',' '), /* Guinea Kpelle -> Kpelle */ + HB_TAG('H','M','D',' '), /* Large Flowery Miao -> A-Hmao */ + HB_TAG('H','M','N',' '), /* Large Flowery Miao -> Hmong */ + HB_TAG('H','M','Z',' '), /* Hmong Shua -> Hmong Shuat */ + HB_TAG('H','M','N',' '), /* Hmong Shua -> Hmong */ + HB_TAG('H','A','R',' '), /* Hadothi -> Harauti */ + HB_TAG('R','A','J',' '), /* Hadothi -> Rajasthani */ + HB_TAG('I','N','U',' '), /* Eastern Canadian Inuktitut -> Inuktitut */ + HB_TAG('I','N','U','K'), /* Eastern Canadian Inuktitut -> Nunavik Inuktitut */ + HB_TAG('J','A','M',' '), /* Jamaican Creole English -> Jamaican Creole */ + HB_TAG('C','P','P',' '), /* Jamaican Creole English -> Creoles */ + HB_TAG('K','A','B','0'), /* Kabyle */ + HB_TAG('B','B','R',' '), /* Kabyle -> Berber */ + HB_TAG('K','H','K',' '), /* Khanty -> Khanty-Kazim */ + HB_TAG('K','H','S',' '), /* Khanty -> Khanty-Shurishkar */ + HB_TAG('K','H','V',' '), /* Khanty -> Khanty-Vakhi */ + HB_TAG('K','E','A',' '), /* Kabuverdianu (Crioulo) */ + HB_TAG('C','P','P',' '), /* Kabuverdianu -> Creoles */ + HB_TAG('K','E','K',' '), /* Kekchi */ + HB_TAG('M','Y','N',' '), /* Kekchí -> Mayan */ + HB_TAG('K','H','T',' '), /* Khamti -> Khamti Shan */ + HB_TAG('K','H','N',' '), /* Khamti -> Khamti Shan (Microsoft fonts) */ + HB_TAG('K','I','U',' '), /* Kirmanjki */ + HB_TAG('Z','Z','A',' '), /* Kirmanjki -> Zazaki */ + HB_TAG('K','J','P',' '), /* Pwo Eastern Karen -> Eastern Pwo Karen */ + HB_TAG('K','R','N',' '), /* Pwo Eastern Karen -> Karen */ + HB_TAG('K','O','P',' '), /* Komi-Permyak */ + HB_TAG('K','O','M',' '), /* Komi-Permyak -> Komi */ + HB_TAG('K','O','Z',' '), /* Komi-Zyrian */ + HB_TAG('K','O','M',' '), /* Komi-Zyrian -> Komi */ + HB_TAG('K','A','R',' '), /* Karachay-Balkar -> Karachay */ + HB_TAG('B','A','L',' '), /* Karachay-Balkar -> Balkar */ + HB_TAG('K','R','I',' '), /* Krio */ + HB_TAG('C','P','P',' '), /* Krio -> Creoles */ + HB_TAG('K','S','W',' '), /* S’gaw Karen */ + HB_TAG('K','R','N',' '), /* S'gaw Karen -> Karen */ + HB_TAG('K','V','Q',' '), /* Geba Karen */ + HB_TAG('K','R','N',' '), /* Geba Karen -> Karen */ + HB_TAG('K','Y','U',' '), /* Western Kayah */ + HB_TAG('K','R','N',' '), /* Western Kayah -> Karen */ + HB_TAG('M','I','Z',' '), /* Lushai -> Mizo */ + HB_TAG('Q','I','N',' '), /* Lushai -> Chin */ + HB_TAG('M','A','M',' '), /* Mam */ + HB_TAG('M','Y','N',' '), /* Mam -> Mayan */ + HB_TAG('M','L','Y',' '), /* North Moluccan Malay -> Malay */ + HB_TAG('C','P','P',' '), /* North Moluccan Malay -> Creoles */ + HB_TAG('M','F','A',' '), /* Pattani Malay */ + HB_TAG('M','L','Y',' '), /* Pattani Malay -> Malay */ + HB_TAG('M','F','E',' '), /* Morisyen */ + HB_TAG('C','P','P',' '), /* Morisyen -> Creoles */ + HB_TAG('M','I','N',' '), /* Minangkabau */ + HB_TAG('M','L','Y',' '), /* Minangkabau -> Malay */ + HB_TAG('M','L','N',' '), /* Western Maninkakan -> Malinke */ + HB_TAG('M','N','K',' '), /* Western Maninkakan -> Maninka */ + HB_TAG('M','N','D',' '), /* Mandinka */ + HB_TAG('M','N','K',' '), /* Mandinka -> Maninka */ + HB_TAG('M','O','N',' '), /* Mon */ + HB_TAG('M','O','N','T'), /* Mon -> Thailand Mon */ + HB_TAG('M','L','Y',' '), /* Sabah Malay -> Malay */ + HB_TAG('C','P','P',' '), /* Sabah Malay -> Creoles */ + HB_TAG('M','W','W',' '), /* Hmong Daw */ + HB_TAG('H','M','N',' '), /* Hmong Daw -> Hmong */ + HB_TAG('N','A','G',' '), /* Naga Pidgin -> Naga-Assamese */ + HB_TAG('C','P','P',' '), /* Naga Pidgin -> Creoles */ + HB_TAG('O','C','R',' '), /* Severn Ojibwa -> Oji-Cree */ + HB_TAG('O','J','B',' '), /* Severn Ojibwa -> Ojibway */ + HB_TAG('P','A','P','0'), /* Papiamento -> Papiamentu */ + HB_TAG('C','P','P',' '), /* Papiamento -> Creoles */ + HB_TAG('A','R','A',' '), /* Sudanese Creole Arabic -> Arabic */ + HB_TAG('C','P','P',' '), /* Sudanese Creole Arabic -> Creoles */ + HB_TAG('P','I','H',' '), /* Pitcairn-Norfolk -> Norfolk */ + HB_TAG('C','P','P',' '), /* Pitcairn-Norfolk -> Creoles */ + HB_TAG('P','O','H',' '), /* Poqomchi' -> Pocomchi */ + HB_TAG('M','Y','N',' '), /* Poqomchi' -> Mayan */ + HB_TAG('D','R','I',' '), /* Dari */ + HB_TAG('F','A','R',' '), /* Dari -> Persian */ + HB_TAG('P','W','O',' '), /* Pwo Western Karen -> Western Pwo Karen */ + HB_TAG('K','R','N',' '), /* Pwo Western Karen -> Karen */ + HB_TAG('Q','W','H',' '), /* Huallaga Huánuco Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Huallaga Huánuco Quechua -> Quechua */ + HB_TAG('Q','U','C',' '), /* K’iche’ */ + HB_TAG('M','Y','N',' '), /* K'iche' -> Mayan */ + HB_TAG('Q','V','I',' '), /* Calderón Highland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Calderón Highland Quichua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Chimborazo Highland Quichua -> Quechua */ + HB_TAG('Q','U','H',' '), /* South Bolivian Quechua -> Quechua (Bolivia) */ + HB_TAG('Q','U','Z',' '), /* South Bolivian Quechua -> Quechua */ + HB_TAG('Q','U','H',' '), /* North Bolivian Quechua -> Quechua (Bolivia) */ + HB_TAG('Q','U','Z',' '), /* North Bolivian Quechua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Southern Pastaza Quechua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Southern Pastaza Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Yanahuanca Pasco Quechua -> Quechua */ + HB_TAG('Q','U','H',' '), /* Santiago del Estero Quichua -> Quechua (Bolivia) */ + HB_TAG('Q','U','Z',' '), /* Santiago del Estero Quichua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Tena Lowland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Tena Lowland Quichua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Yauyos Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Yauyos Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Ambo-Pasco Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Ambo-Pasco Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Imbabura Highland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Imbabura Highland Quichua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Loja Highland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Loja Highland Quichua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Cajatambo North Lima Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Cajatambo North Lima Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Margos-Yarowilca-Lauricocha Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* North Junín Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* North Junín Quechua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Napo Lowland Quechua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Napo Lowland Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Pacaraos Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Pacaraos Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Huaylla Wanca Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Huaylla Wanca Quechua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Northern Pastaza Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Northern Pastaza Quichua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Corongo Ancash Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Corongo Ancash Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Huaylas Ancash Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Huaylas Ancash Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Sihuas Ancash Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Sihuas Ancash Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Chiquián Ancash Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Chiquián Ancash Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Chincha Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Chincha Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Panao Huánuco Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Panao Huánuco Quechua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Salasaca Highland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Salasaca Highland Quichua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Northern Conchucos Ancash Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Southern Conchucos Ancash Quechua -> Quechua */ + HB_TAG('Q','V','I',' '), /* Cañar Highland Quichua -> Quechua (Ecuador) */ + HB_TAG('Q','U','Z',' '), /* Cañar Highland Quichua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Santa Ana de Tusi Pasco Quechua -> Quechua */ + HB_TAG('Q','W','H',' '), /* Jauja Wanca Quechua -> Quechua (Peru) */ + HB_TAG('Q','U','Z',' '), /* Jauja Wanca Quechua -> Quechua */ + HB_TAG('R','I','F',' '), /* Tarifit */ + HB_TAG('B','B','R',' '), /* Tarifit -> Berber */ + HB_TAG('R','M','Y',' '), /* Vlax Romani */ + HB_TAG('R','O','Y',' '), /* Vlax Romani -> Romany */ + HB_TAG('S','C','S',' '), /* North Slavey */ + HB_TAG('S','L','A',' '), /* North Slavey -> Slavey */ + HB_TAG('A','T','H',' '), /* North Slavey -> Athapaskan */ + HB_TAG('S','F','M',' '), /* Small Flowery Miao */ + HB_TAG('H','M','N',' '), /* Small Flowery Miao -> Hmong */ + HB_TAG('S','H','I',' '), /* Tachelhit */ + HB_TAG('B','B','R',' '), /* Tachelhit -> Berber */ + HB_TAG('T','A','Q',' '), /* Tamasheq */ + HB_TAG('T','M','H',' '), /* Tamasheq -> Tamashek */ + HB_TAG('B','B','R',' '), /* Tamasheq -> Berber */ + HB_TAG('T','H','V',' '), /* Tahaggart Tamahaq */ + HB_TAG('T','M','H',' '), /* Tahaggart Tamahaq -> Tamashek */ + HB_TAG('B','B','R',' '), /* Tahaggart Tamahaq -> Berber */ + HB_TAG('T','H','Z',' '), /* Tayart Tamajeq */ + HB_TAG('T','M','H',' '), /* Tayart Tamajeq -> Tamashek */ + HB_TAG('B','B','R',' '), /* Tayart Tamajeq -> Berber */ + HB_TAG('T','M','H',' '), /* Tamashek [macrolanguage] */ + HB_TAG('B','B','R',' '), /* Tamashek [macrolanguage] -> Berber */ + HB_TAG('D','R','I',' '), /* Tangshewi (retired code) -> Dari */ + HB_TAG('F','A','R',' '), /* Tangshewi (retired code) -> Persian */ + HB_TAG('T','P','I',' '), /* Tok Pisin */ + HB_TAG('C','P','P',' '), /* Tok Pisin -> Creoles */ + HB_TAG('T','U','A',' '), /* Turoyo -> Turoyo Aramaic */ + HB_TAG('S','Y','R',' '), /* Turoyo -> Syriac */ + HB_TAG('T','T','Q',' '), /* Tawallammat Tamajaq */ + HB_TAG('T','M','H',' '), /* Tawallammat Tamajaq -> Tamashek */ + HB_TAG('B','B','R',' '), /* Tawallammat Tamajaq -> Berber */ + HB_TAG('T','Z','M',' '), /* Central Atlas Tamazight -> Tamazight */ + HB_TAG('B','B','R',' '), /* Central Atlas Tamazight -> Berber */ + HB_TAG('T','Z','O',' '), /* Tzotzil */ + HB_TAG('M','Y','N',' '), /* Tzotzil -> Mayan */ + HB_TAG('V','R','O',' '), /* Võro */ + HB_TAG('E','T','I',' '), /* Võro -> Estonian */ + HB_TAG('W','A','G',' '), /* Wagdi */ + HB_TAG('R','A','J',' '), /* Wagdi -> Rajasthani */ + HB_TAG('W','D','T',' '), /* Wyandot (retired code) -> Wendat */ + HB_TAG('W','Y','N',' '), /* Wyandot (retired code) */ + HB_TAG('K','L','M',' '), /* Kalmyk */ + HB_TAG('T','O','D',' '), /* Kalmyk -> Todo */ + HB_TAG('M','L','Y',' '), /* Manado Malay -> Malay */ + HB_TAG('C','P','P',' '), /* Manado Malay -> Creoles */ + HB_TAG('X','P','E',' '), /* Liberia Kpelle -> Kpelle (Liberia) */ + HB_TAG('K','P','L',' '), /* Liberia Kpelle -> Kpelle */ + HB_TAG('S','S','L',' '), /* South Slavey */ + HB_TAG('S','L','A',' '), /* South Slavey -> Slavey */ + HB_TAG('A','T','H',' '), /* South Slavey -> Athapaskan */ + HB_TAG('Z','G','H',' '), /* Standard Moroccan Tamazight */ + HB_TAG('B','B','R',' '), /* Standard Moroccan Tamazight -> Berber */ +}; + +static const LangTagRange ot_languages3_multi[] = { + {HB_TAG('a','c','f',' '), 0, 2}, /* Saint Lucian Creole French -> French Antillean */ + {HB_TAG('a','c','r',' '), 2, 2}, /* Achi */ + {HB_TAG('a','c','y',' '), 4, 2}, /* Cypriot Arabic */ + {HB_TAG('a','i','i',' '), 6, 2}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ + {HB_TAG('a','k','b',' '), 8, 2}, /* Batak Angkola */ + {HB_TAG('a','r','y',' '), 10, 2}, /* Moroccan Arabic -> Moroccan */ + {HB_TAG('a','z','b',' '), 12, 2}, /* South Azerbaijani -> Torki */ + {HB_TAG('b','b','c',' '), 14, 2}, /* Batak Toba */ + {HB_TAG('b','g','q',' '), 16, 2}, /* Bagri */ + {HB_TAG('b','l','k',' '), 18, 2}, /* Pa’o Karen */ + {HB_TAG('b','t','d',' '), 20, 2}, /* Batak Dairi (Pakpak) */ + {HB_TAG('b','t','m',' '), 22, 2}, /* Batak Mandailing */ + {HB_TAG('b','t','s',' '), 24, 2}, /* Batak Simalungun */ + {HB_TAG('b','t','x',' '), 26, 2}, /* Batak Karo */ + {HB_TAG('b','t','z',' '), 28, 2}, /* Batak Alas-Kluet */ + {HB_TAG('b','y','v',' '), 30, 2}, /* Medumba */ + {HB_TAG('c','a','f',' '), 32, 2}, /* Southern Carrier -> Carrier */ + {HB_TAG('c','a','k',' '), 34, 2}, /* Kaqchikel */ + {HB_TAG('c','b','k',' '), 36, 2}, /* Chavacano -> Zamboanga Chavacano */ + {HB_TAG('c','f','m',' '), 38, 2}, /* Halam (Falam Chin) */ + {HB_TAG('c','h','m',' '), 40, 2}, /* Mari (Russia) [macrolanguage] -> High Mari */ + {HB_TAG('c','h','p',' '), 42, 3}, /* Chipewyan */ + {HB_TAG('c','q','u',' '), 45, 2}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ + {HB_TAG('c','r','j',' '), 47, 3}, /* Southern East Cree -> Eastern Cree */ + {HB_TAG('c','r','k',' '), 50, 3}, /* Plains Cree -> West-Cree */ + {HB_TAG('c','r','l',' '), 53, 3}, /* Northern East Cree -> Eastern Cree */ + {HB_TAG('c','r','m',' '), 56, 3}, /* Moose Cree */ + {HB_TAG('c','r','x',' '), 59, 2}, /* Carrier */ + {HB_TAG('c','s','w',' '), 61, 3}, /* Swampy Cree -> N-Cree */ + {HB_TAG('c','w','d',' '), 64, 3}, /* Woods Cree */ + {HB_TAG('d','e','n',' '), 67, 2}, /* Slave (Athapascan) [macrolanguage] -> Slavey */ + {HB_TAG('d','g','o',' '), 69, 2}, /* Dogri (individual language) */ + {HB_TAG('d','i','q',' '), 71, 2}, /* Dimli */ + {HB_TAG('d','r','w',' '), 73, 2}, /* Darwazi (retired code) -> Dari */ + {HB_TAG('e','m','k',' '), 75, 2}, /* Eastern Maninkakan */ + {HB_TAG('f','a','n',' '), 77, 2}, /* Fang (Equatorial Guinea) */ + {HB_TAG('f','a','t',' '), 79, 2}, /* Fanti */ + {HB_TAG('f','l','m',' '), 81, 2}, /* Halam (Falam Chin) (retired code) */ + {HB_TAG('f','m','p',' '), 83, 2}, /* Fe’fe’ */ + {HB_TAG('f','u','f',' '), 85, 2}, /* Pular -> Futa */ + {HB_TAG('f','u','v',' '), 87, 2}, /* Nigerian Fulfulde */ + {HB_TAG('g','k','p',' '), 89, 2}, /* Guinea Kpelle -> Kpelle (Guinea) */ + {HB_TAG('h','m','d',' '), 91, 2}, /* Large Flowery Miao -> A-Hmao */ + {HB_TAG('h','m','z',' '), 93, 2}, /* Hmong Shua -> Hmong Shuat */ + {HB_TAG('h','o','j',' '), 95, 2}, /* Hadothi -> Harauti */ + {HB_TAG('i','k','e',' '), 97, 2}, /* Eastern Canadian Inuktitut -> Inuktitut */ + {HB_TAG('j','a','m',' '), 99, 2}, /* Jamaican Creole English -> Jamaican Creole */ + {HB_TAG('k','a','b',' '), 101, 2}, /* Kabyle */ + {HB_TAG('k','c','a',' '), 103, 3}, /* Khanty -> Khanty-Kazim */ + {HB_TAG('k','e','a',' '), 106, 2}, /* Kabuverdianu (Crioulo) */ + {HB_TAG('k','e','k',' '), 108, 2}, /* Kekchi */ + {HB_TAG('k','h','t',' '), 110, 2}, /* Khamti -> Khamti Shan */ + {HB_TAG('k','i','u',' '), 112, 2}, /* Kirmanjki */ + {HB_TAG('k','j','p',' '), 114, 2}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ + {HB_TAG('k','o','i',' '), 116, 2}, /* Komi-Permyak */ + {HB_TAG('k','p','v',' '), 118, 2}, /* Komi-Zyrian */ + {HB_TAG('k','r','c',' '), 120, 2}, /* Karachay-Balkar -> Karachay */ + {HB_TAG('k','r','i',' '), 122, 2}, /* Krio */ + {HB_TAG('k','s','w',' '), 124, 2}, /* S’gaw Karen */ + {HB_TAG('k','v','q',' '), 126, 2}, /* Geba Karen */ + {HB_TAG('k','y','u',' '), 128, 2}, /* Western Kayah */ + {HB_TAG('l','u','s',' '), 130, 2}, /* Lushai -> Mizo */ + {HB_TAG('m','a','m',' '), 132, 2}, /* Mam */ + {HB_TAG('m','a','x',' '), 134, 2}, /* North Moluccan Malay -> Malay */ + {HB_TAG('m','f','a',' '), 136, 2}, /* Pattani Malay */ + {HB_TAG('m','f','e',' '), 138, 2}, /* Morisyen */ + {HB_TAG('m','i','n',' '), 140, 2}, /* Minangkabau */ + {HB_TAG('m','l','q',' '), 142, 2}, /* Western Maninkakan -> Malinke */ + {HB_TAG('m','n','k',' '), 144, 2}, /* Mandinka */ + {HB_TAG('m','n','w',' '), 146, 2}, /* Mon */ + {HB_TAG('m','s','i',' '), 148, 2}, /* Sabah Malay -> Malay */ + {HB_TAG('m','w','w',' '), 150, 2}, /* Hmong Daw */ + {HB_TAG('n','a','g',' '), 152, 2}, /* Naga Pidgin -> Naga-Assamese */ + {HB_TAG('o','j','s',' '), 154, 2}, /* Severn Ojibwa -> Oji-Cree */ + {HB_TAG('p','a','p',' '), 156, 2}, /* Papiamento -> Papiamentu */ + {HB_TAG('p','g','a',' '), 158, 2}, /* Sudanese Creole Arabic -> Arabic */ + {HB_TAG('p','i','h',' '), 160, 2}, /* Pitcairn-Norfolk -> Norfolk */ + {HB_TAG('p','o','h',' '), 162, 2}, /* Poqomchi' -> Pocomchi */ + {HB_TAG('p','r','s',' '), 164, 2}, /* Dari */ + {HB_TAG('p','w','o',' '), 166, 2}, /* Pwo Western Karen -> Western Pwo Karen */ + {HB_TAG('q','u','b',' '), 168, 2}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ + {HB_TAG('q','u','c',' '), 170, 2}, /* K’iche’ */ + {HB_TAG('q','u','d',' '), 172, 2}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','u','g',' '), 174, 2}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','u','h',' '), 176, 2}, /* South Bolivian Quechua -> Quechua (Bolivia) */ + {HB_TAG('q','u','l',' '), 178, 2}, /* North Bolivian Quechua -> Quechua (Bolivia) */ + {HB_TAG('q','u','p',' '), 180, 2}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ + {HB_TAG('q','u','r',' '), 182, 2}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ + {HB_TAG('q','u','s',' '), 184, 2}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */ + {HB_TAG('q','u','w',' '), 186, 2}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','u','x',' '), 188, 2}, /* Yauyos Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','a',' '), 190, 2}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','h',' '), 192, 2}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','i',' '), 194, 2}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','v','j',' '), 196, 2}, /* Loja Highland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','v','l',' '), 198, 2}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','m',' '), 200, 2}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','n',' '), 202, 2}, /* North Junín Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','o',' '), 204, 2}, /* Napo Lowland Quechua -> Quechua (Ecuador) */ + {HB_TAG('q','v','p',' '), 206, 2}, /* Pacaraos Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','w',' '), 208, 2}, /* Huaylla Wanca Quechua -> Quechua (Peru) */ + {HB_TAG('q','v','z',' '), 210, 2}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','w','a',' '), 212, 2}, /* Corongo Ancash Quechua -> Quechua (Peru) */ + {HB_TAG('q','w','h',' '), 214, 2}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ + {HB_TAG('q','w','s',' '), 216, 2}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','a',' '), 218, 2}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','c',' '), 220, 2}, /* Chincha Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','h',' '), 222, 2}, /* Panao Huánuco Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','l',' '), 224, 2}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','x','n',' '), 226, 2}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','o',' '), 228, 2}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','r',' '), 230, 2}, /* Cañar Highland Quichua -> Quechua (Ecuador) */ + {HB_TAG('q','x','t',' '), 232, 2}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ + {HB_TAG('q','x','w',' '), 234, 2}, /* Jauja Wanca Quechua -> Quechua (Peru) */ + {HB_TAG('r','i','f',' '), 236, 2}, /* Tarifit */ + {HB_TAG('r','m','y',' '), 238, 2}, /* Vlax Romani */ + {HB_TAG('s','c','s',' '), 240, 3}, /* North Slavey */ + {HB_TAG('s','f','m',' '), 243, 2}, /* Small Flowery Miao */ + {HB_TAG('s','h','i',' '), 245, 2}, /* Tachelhit */ + {HB_TAG('t','a','q',' '), 247, 3}, /* Tamasheq */ + {HB_TAG('t','h','v',' '), 250, 3}, /* Tahaggart Tamahaq */ + {HB_TAG('t','h','z',' '), 253, 3}, /* Tayart Tamajeq */ + {HB_TAG('t','m','h',' '), 256, 2}, /* Tamashek [macrolanguage] */ + {HB_TAG('t','n','f',' '), 258, 2}, /* Tangshewi (retired code) -> Dari */ + {HB_TAG('t','p','i',' '), 260, 2}, /* Tok Pisin */ + {HB_TAG('t','r','u',' '), 262, 2}, /* Turoyo -> Turoyo Aramaic */ + {HB_TAG('t','t','q',' '), 264, 3}, /* Tawallammat Tamajaq */ + {HB_TAG('t','z','m',' '), 267, 2}, /* Central Atlas Tamazight -> Tamazight */ + {HB_TAG('t','z','o',' '), 269, 2}, /* Tzotzil */ + {HB_TAG('v','r','o',' '), 271, 2}, /* Võro */ + {HB_TAG('w','b','r',' '), 273, 2}, /* Wagdi */ + {HB_TAG('w','y','a',' '), 275, 2}, /* Wyandot (retired code) -> Wendat */ + {HB_TAG('x','a','l',' '), 277, 2}, /* Kalmyk */ + {HB_TAG('x','m','m',' '), 279, 2}, /* Manado Malay -> Malay */ + {HB_TAG('x','p','e',' '), 281, 2}, /* Liberia Kpelle -> Kpelle (Liberia) */ + {HB_TAG('x','s','l',' '), 283, 3}, /* South Slavey */ + {HB_TAG('z','g','h',' '), 286, 2}, /* Standard Moroccan Tamazight */ +}; #endif /** @@ -2377,6 +2308,26 @@ out: *count = i; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hant-hk", 10)) + { + /* Hainanese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant-mo", 10)) + { + /* Hainanese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hant-hk", 10)) { /* Xiang Chinese; Han (Traditional variant); Hong Kong */ @@ -2411,6 +2362,20 @@ out: *count = 1; return true; } + if (lang_matches (&lang_str[1], limit, "nm-hans", 7)) + { + /* Hainanese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "nm-hant", 7)) + { + /* Hainanese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "sn-hans", 7)) { /* Xiang Chinese; Han (Simplified variant) */ @@ -2455,6 +2420,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Hainanese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Hainanese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "nm-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Hainanese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (0 == strncmp (&lang_str[1], "sn-", 3) && subtag_matches (lang_str, limit, "-hk", 3)) { @@ -2516,6 +2511,40 @@ out: } break; case 'l': + if (lang_matches (&lang_str[1], limit, "uh-hant-hk", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant-mo", 10)) + { + /* Leizhou Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hans", 7)) + { + /* Leizhou Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "uh-hant", 7)) + { + /* Leizhou Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } if (lang_matches (&lang_str[1], limit, "zh-hans", 7)) { /* Literary Chinese; Han (Simplified variant) */ @@ -2523,6 +2552,36 @@ out: *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Leizhou Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Leizhou Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "uh-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Leizhou Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } break; case 'm': if (lang_matches (&lang_str[1], limit, "np-hant-hk", 10)) @@ -2694,6 +2753,72 @@ out: return true; } break; + case 's': + if (lang_matches (&lang_str[1], limit, "jc-hant-hk", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant-mo", 10)) + { + /* Shaojiang Chinese; Han (Traditional variant); Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hans", 7)) + { + /* Shaojiang Chinese; Han (Simplified variant) */ + tags[0] = HB_TAG('Z','H','S',' '); /* Chinese, Simplified */ + *count = 1; + return true; + } + if (lang_matches (&lang_str[1], limit, "jc-hant", 7)) + { + /* Shaojiang Chinese; Han (Traditional variant) */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-hk", 3)) + { + /* Shaojiang Chinese; Hong Kong */ + tags[0] = HB_TAG('Z','H','H',' '); /* Chinese, Traditional, Hong Kong SAR */ + *count = 1; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-mo", 3)) + { + /* Shaojiang Chinese; Macao */ + unsigned int i; + hb_tag_t possible_tags[] = { + HB_TAG('Z','H','T','M'), /* Chinese, Traditional, Macao SAR */ + HB_TAG('Z','H','H',' '), /* Chinese, Traditional, Hong Kong SAR */ + }; + for (i = 0; i < 2 && i < *count; i++) + tags[i] = possible_tags[i]; + *count = i; + return true; + } + if (0 == strncmp (&lang_str[1], "jc-", 3) + && subtag_matches (lang_str, limit, "-tw", 3)) + { + /* Shaojiang Chinese; Taiwan, Province of China */ + tags[0] = HB_TAG('Z','H','T',' '); /* Chinese, Traditional */ + *count = 1; + return true; + } + break; case 'w': if (lang_matches (&lang_str[1], limit, "uu-hant-hk", 10)) { @@ -2998,7 +3123,7 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) case HB_TAG('Z','H','T','M'): /* Chinese, Traditional, Macao SAR */ return hb_language_from_string ("zh-MO", -1); /* Chinese [macrolanguage]; Macao */ case HB_TAG('Z','Z','A',' '): /* Zazaki */ - return hb_language_from_string ("zza", -1); /* Zazaki [macrolanguage] */ + return hb_language_from_string ("zza", -1); /* Zaza [macrolanguage] */ default: return HB_LANGUAGE_INVALID; } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-tag.cc b/thirdparty/harfbuzz/upstream/hb-ot-tag.cc index 0c63756b1..900f37ab4 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-tag.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-tag.cc @@ -234,6 +234,29 @@ lang_matches (const char *lang_str, (lang_str[spec_len] == '\0' || lang_str[spec_len] == '-'); } +static bool +bfind_tag (const hb_tag_t *array, + unsigned len, + hb_tag_t key) +{ + unsigned min = 0; + unsigned max = len; + + while (min < max) + { + unsigned mid = min + (max - min) / 2; + hb_tag_t val = array[mid]; + if (key < val) + max = mid; + else if (key > val) + min = mid + 1; + else + return true; + } + + return false; +} + struct LangTag { hb_tag_t language; @@ -247,6 +270,20 @@ struct LangTag { return cmp (that->language); } }; +struct LangTagRange +{ + hb_tag_t language; + uint16_t offset; + uint8_t count; + + int cmp (hb_tag_t a) const + { + return a < this->language ? -1 : a > this->language ? +1 : 0; + } + int cmp (const LangTagRange *that) const + { return cmp (that->language); } +}; + #include "hb-ot-tag-table.hh" /* The corresponding languages IDs for the following IDs are unclear, @@ -307,46 +344,84 @@ hb_ot_tags_from_language (const char *lang_str, lang_str = s + 1; } #endif - const LangTag *ot_languages = nullptr; - unsigned ot_languages_len = 0; const char *dash = strchr (lang_str, '-'); unsigned first_len = dash ? dash - lang_str : limit - lang_str; + hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len); + if (first_len == 2) { - ot_languages = ot_languages2; - ot_languages_len = ARRAY_LENGTH (ot_languages2); + static hb_atomic_t last_tag_idx_2 = 0; /* Poor man's cache. */ + unsigned tag_idx = last_tag_idx_2; + + if (likely (tag_idx < ARRAY_LENGTH (ot_languages2) && + ot_languages2[tag_idx].language == lang_tag) || + hb_sorted_array (ot_languages2).bfind (lang_tag, &tag_idx)) + { + last_tag_idx_2 = tag_idx; + unsigned int i; + while (tag_idx != 0 && + ot_languages2[tag_idx].language == ot_languages2[tag_idx - 1].language) + tag_idx--; + for (i = 0; + i < *count && + tag_idx + i < ARRAY_LENGTH (ot_languages2) && + ot_languages2[tag_idx + i].tag != HB_TAG_NONE && + ot_languages2[tag_idx + i].language == ot_languages2[tag_idx].language; + i++) + tags[i] = ot_languages2[tag_idx + i].tag; + *count = i; + return; + } } #ifndef HB_NO_LANGUAGE_LONG else if (first_len == 3) { - ot_languages = ot_languages3; - ot_languages_len = ARRAY_LENGTH (ot_languages3); - } -#endif + static hb_atomic_t last_tag_idx_3 = 0; /* Poor man's cache. */ + unsigned tag_idx = last_tag_idx_3; - hb_tag_t lang_tag = hb_tag_from_string (lang_str, first_len); + if (likely (tag_idx < ARRAY_LENGTH (ot_languages3) && + ot_languages3[tag_idx].language == lang_tag) || + hb_sorted_array (ot_languages3).bfind (lang_tag, &tag_idx)) + { + last_tag_idx_3 = tag_idx; + if (*count) + { + tags[0] = ot_languages3[tag_idx].tag; + *count = 1; + } + else + *count = 0; + return; + } - static hb_atomic_int_t last_tag_idx; /* Poor man's cache. */ - unsigned tag_idx = last_tag_idx; + static hb_atomic_t last_tag_idx_3_multi = 0; /* Poor man's cache. */ + unsigned multi_tag_idx = last_tag_idx_3_multi; - if (likely (tag_idx < ot_languages_len && ot_languages[tag_idx].language == lang_tag) || - hb_sorted_array (ot_languages, ot_languages_len).bfind (lang_tag, &tag_idx)) - { - last_tag_idx = tag_idx; - unsigned int i; - while (tag_idx != 0 && - ot_languages[tag_idx].language == ot_languages[tag_idx - 1].language) - tag_idx--; - for (i = 0; - i < *count && - tag_idx + i < ot_languages_len && - ot_languages[tag_idx + i].tag != HB_TAG_NONE && - ot_languages[tag_idx + i].language == ot_languages[tag_idx].language; - i++) - tags[i] = ot_languages[tag_idx + i].tag; - *count = i; + if (likely (multi_tag_idx < ARRAY_LENGTH (ot_languages3_multi) && + ot_languages3_multi[multi_tag_idx].language == lang_tag) || + hb_sorted_array (ot_languages3_multi).bfind (lang_tag, &multi_tag_idx)) + { + last_tag_idx_3_multi = multi_tag_idx; + const LangTagRange &range = ot_languages3_multi[multi_tag_idx]; + unsigned int i; + for (i = 0; i < *count && i < range.count; i++) + tags[i] = ot_languages3_multi_values[range.offset + i]; + *count = i; + return; + } + + if (bfind_tag (ot_languages3_blocked, ARRAY_LENGTH (ot_languages3_blocked), lang_tag)) + { + *count = 0; + return; + } + + /* Assume it's ISO-639-3 and upper-case and use it. */ + tags[0] = lang_tag & ~0x20202000u; + *count = 1; return; } +#endif } #ifndef HB_NO_LANGUAGE_LONG @@ -525,6 +600,13 @@ hb_ot_tag_to_language (hb_tag_t tag) hb_tag_to_string (ot_languages3[i].language, buf); return hb_language_from_string (buf, 3); } + for (i = 0; i < ARRAY_LENGTH (ot_languages3_multi); i++) + for (unsigned int j = 0; j < ot_languages3_multi[i].count; j++) + if (ot_languages3_multi_values[ot_languages3_multi[i].offset + j] == tag) + { + hb_tag_to_string (ot_languages3_multi[i].language, buf); + return hb_language_from_string (buf, 3); + } #endif /* Return a custom language in the form of "x-hbot-AABBCCDD". @@ -642,6 +724,23 @@ test_langs_sorted () abort(); } } + for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages3_multi); i++) + { + int c = ot_languages3_multi[i].cmp (&ot_languages3_multi[i - 1]); + if (c > 0) + { + fprintf (stderr, "ot_languages3_multi not sorted at index %u: %08x %d %08x\n", + i, ot_languages3_multi[i-1].language, c, ot_languages3_multi[i].language); + abort(); + } + } + for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages3_blocked); i++) + if (ot_languages3_blocked[i] < ot_languages3_blocked[i - 1]) + { + fprintf (stderr, "ot_languages3_blocked not sorted at index %u: %08x < %08x\n", + i, ot_languages3_blocked[i], ot_languages3_blocked[i - 1]); + abort(); + } #endif } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-var-avar-table.hh index 75ea338e2..98ce46e61 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-var-avar-table.hh @@ -143,10 +143,13 @@ struct AxisValueMap struct SegmentMaps : Array16Of { - int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const + float map_float (float value, unsigned int from_offset = 0, unsigned int to_offset = 1) const { -#define fromCoord coords[from_offset].to_int () -#define toCoord coords[to_offset].to_int () +#define fromCoord coords[from_offset].to_float () +#define toCoord coords[to_offset].to_float () + + const auto *map = arrayZ; + /* The following special-cases are not part of OpenType, which requires * that at least -1, 0, and +1 must be mapped. But we include these as * part of a better error recovery scheme. */ @@ -155,47 +158,98 @@ struct SegmentMaps : Array16Of if (!len) return value; else /* len == 1*/ - return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; + return value - map[0].fromCoord + map[0].toCoord; } - if (value <= arrayZ[0].fromCoord) - return value - arrayZ[0].fromCoord + arrayZ[0].toCoord; + // At least two mappings now. + + /* CoreText is wild... + * PingFangUI avar needs all this special-casing... + * So we implement an extended version of the spec here, + * which is more robust and more likely to be compatible with + * the wild. */ + + unsigned start = 0; + unsigned end = len; + if (map[start].fromCoord == -1 && map[start].toCoord == -1 && map[start+1].fromCoord == -1) + start++; + if (map[end-1].fromCoord == +1 && map[end-1].toCoord == +1 && map[end-2].fromCoord == +1) + end--; + + /* Look for exact match first, and do lots of special-casing. */ + unsigned i; + for (i = start; i < end; i++) + if (value == map[i].fromCoord) + break; + if (i < end) + { + // There's at least one exact match. See if there are more. + unsigned j = i; + for (; j + 1 < end; j++) + if (value != map[j + 1].fromCoord) + break; + + // [i,j] inclusive are all exact matches: + + // If there's only one, return it. This is the only spec-compliant case. + if (i == j) + return map[i].toCoord; + // If there's exactly three, return the middle one. + if (i + 2 == j) + return map[i + 1].toCoord; + + // Ignore the middle ones. Return the one mapping closer to 0. + if (value < 0) return map[j].toCoord; + if (value > 0) return map[i].toCoord; + + // Mapping 0? CoreText seems confused. It seems to prefer 0 here... + // So we'll just return the smallest one. lol + return fabsf (map[i].toCoord) < fabsf (map[j].toCoord) ? map[i].toCoord : map[j].toCoord; + + // Mapping 0? Return one not mapping to 0. + if (map[i].toCoord == 0) + return map[j].toCoord; + else + return map[i].toCoord; + } - unsigned int i; - unsigned int count = len - 1; - for (i = 1; i < count && value > arrayZ[i].fromCoord; i++) - ; + /* There's at least two and we're not an exact match. Prepare to lerp. */ - if (value >= arrayZ[i].fromCoord) - return value - arrayZ[i].fromCoord + arrayZ[i].toCoord; + // Find the segment we're in. + for (i = start; i < end; i++) + if (value < map[i].fromCoord) + break; - if (unlikely (arrayZ[i-1].fromCoord == arrayZ[i].fromCoord)) - return arrayZ[i-1].toCoord; + if (i == 0) + { + // Value before all segments; Shift. + return value - map[0].fromCoord + map[0].toCoord; + } + if (i == end) + { + // Value after all segments; Shift. + return value - map[end - 1].fromCoord + map[end - 1].toCoord; + } + + // Actually interpolate. + auto &before = map[i-1]; + auto &after = map[i]; + float denom = after.fromCoord - before.fromCoord; // Can't be zero by now. + return before.toCoord + ((after.toCoord - before.toCoord) * (value - before.fromCoord)) / denom; - int denom = arrayZ[i].fromCoord - arrayZ[i-1].fromCoord; - return roundf (arrayZ[i-1].toCoord + ((float) (arrayZ[i].toCoord - arrayZ[i-1].toCoord) * - (value - arrayZ[i-1].fromCoord)) / denom); #undef toCoord #undef fromCoord } - int unmap (int value) const { return map (value, 1, 0); } + float unmap_float (float value) const { return map_float (value, 1, 0); } + + // TODO Kill this. Triple unmap_axis_range (const Triple& axis_range) const { - F2DOT14 val, unmapped_val; - - val.set_float (axis_range.minimum); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_min = unmapped_val.to_float (); - - val.set_float (axis_range.middle); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_middle = unmapped_val.to_float (); - - val.set_float (axis_range.maximum); - unmapped_val.set_int (unmap (val.to_int ())); - float unmapped_max = unmapped_val.to_float (); + float unmapped_min = unmap_float (axis_range.minimum); + float unmapped_middle = unmap_float (axis_range.middle); + float unmapped_max = unmap_float (axis_range.maximum); return Triple{(double) unmapped_min, (double) unmapped_middle, (double) unmapped_max}; } @@ -203,6 +257,11 @@ struct SegmentMaps : Array16Of bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const { TRACE_SUBSET (this); + + /* This function cannot work on avar2 table (and currently doesn't). + * We should instead keep the design coords in the shape plan and use + * those. unmap_axis_range needs to be killed. */ + /* avar mapped normalized axis range*/ Triple *axis_range; if (!c->plan->axes_location.has (axis_tag, &axis_range)) @@ -304,14 +363,14 @@ struct avar return_trace (true); } - void map_coords (int *coords, unsigned int coords_length) const + void map_coords_16_16 (int *coords, unsigned int coords_length) const { unsigned int count = hb_min (coords_length, axisCount); const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) { - coords[i] = map->map (coords[i]); + coords[i] = roundf (map->map_float (coords[i] / 65536.f) * 65536.f); map = &StructAfter (*map); } @@ -329,15 +388,20 @@ struct avar const auto &var_store = this+v2.varStore; auto *var_store_cache = var_store.create_cache (); + hb_vector_t coords_2_14; + coords_2_14.resize (coords_length); + for (unsigned i = 0; i < coords_length; i++) + coords_2_14[i] = roundf (coords[i] / 4.f); // 16.16 -> 2.14 + hb_vector_t out; out.alloc (coords_length); for (unsigned i = 0; i < coords_length; i++) { int v = coords[i]; uint32_t varidx = varidx_map.map (i); - float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache); - v += roundf (delta); - v = hb_clamp (v, -(1<<14), +(1<<14)); + float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache); + v += roundf (delta * 4); // 2.14 -> 16.16 + v = hb_clamp (v, -(1<<16), +(1<<16)); out.push (v); } for (unsigned i = 0; i < coords_length; i++) @@ -347,16 +411,54 @@ struct avar #endif } - void unmap_coords (int *coords, unsigned int coords_length) const + bool has_v2_data () const { return version.major > 1; } + + // axis normalization is done in 2.14 here + // TODO: deprecate this API once fonttools is updated to use 16.16 normalization + bool map_coords_2_14 (float *coords, unsigned int coords_length) const { + hb_vector_t coords_2_14; + if (!coords_2_14.resize (coords_length)) return false; unsigned int count = hb_min (coords_length, axisCount); const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) { - coords[i] = map->unmap (coords[i]); + int v = roundf (map->map_float (coords[i]) * 16384.f); + coords_2_14[i] = v; + coords[i] = v / 16384.f; map = &StructAfter (*map); } + +#ifndef HB_NO_AVAR2 + if (version.major < 2) + return true; + hb_barrier (); + + for (; count < axisCount; count++) + map = &StructAfter (*map); + + const auto &v2 = * (const avarV2Tail *) map; + + const auto &varidx_map = this+v2.varIdxMap; + const auto &var_store = this+v2.varStore; + auto *var_store_cache = var_store.create_cache (); + + for (unsigned i = 0; i < coords_length; i++) + { + int v = coords_2_14[i]; + uint32_t varidx = varidx_map.map (i); + float delta = var_store.get_delta (varidx, coords_2_14.arrayZ, coords_2_14.length, var_store_cache); + v += roundf (delta); + v = hb_clamp (v, -(1<<16), +(1<<16)); + coords[i] = v / 16384.f; + } + + OT::ItemVariationStore::destroy_cache (var_store_cache); + return true; +#else + return version.major < 2; +#endif } bool subset (hb_subset_context_t *c) const diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var-common.hh b/thirdparty/harfbuzz/upstream/hb-ot-var-common.hh index efbbfb25d..74ce1b285 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-var-common.hh @@ -27,24 +27,35 @@ #define HB_OT_VAR_COMMON_HH #include "hb-ot-layout-common.hh" +#include "hb-alloc-pool.hh" #include "hb-priority-queue.hh" #include "hb-subset-instancer-iup.hh" namespace OT { +using rebase_tent_result_scratch_t = hb_pair_t; /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */ struct TupleVariationHeader { friend struct tuple_delta_t; - unsigned get_size (unsigned axis_count) const - { return min_size + get_all_tuples (axis_count).get_size (); } + unsigned get_size (unsigned axis_count_times_2) const + { + // This function is super hot in mega-var-fonts with hundreds of masters. + unsigned ti = tupleIndex; + if (unlikely ((ti & (TupleIndex::EmbeddedPeakTuple | TupleIndex::IntermediateRegion)))) + { + unsigned count = ((ti & TupleIndex::EmbeddedPeakTuple) != 0) + ((ti & TupleIndex::IntermediateRegion) != 0) * 2; + return min_size + count * axis_count_times_2; + } + return min_size; + } unsigned get_data_size () const { return varDataSize; } - const TupleVariationHeader &get_next (unsigned axis_count) const - { return StructAtOffset (this, get_size (axis_count)); } + const TupleVariationHeader &get_next (unsigned axis_count_times_2) const + { return StructAtOffset (this, get_size (axis_count_times_2)); } bool unpack_axis_tuples (unsigned axis_count, const hb_array_t shared_tuples, @@ -53,7 +64,7 @@ struct TupleVariationHeader { const F2DOT14 *peak_tuple = nullptr; if (has_peak ()) - peak_tuple = get_peak_tuple (axis_count).arrayZ; + peak_tuple = get_peak_tuple (axis_count); else { unsigned int index = get_index (); @@ -68,8 +79,8 @@ struct TupleVariationHeader if (has_interm) { - start_tuple = get_start_tuple (axis_count).arrayZ; - end_tuple = get_end_tuple (axis_count).arrayZ; + start_tuple = get_start_tuple (axis_count); + end_tuple = get_end_tuple (axis_count); } for (unsigned i = 0; i < axis_count; i++) @@ -98,88 +109,109 @@ struct TupleVariationHeader return true; } + HB_ALWAYS_INLINE double calculate_scalar (hb_array_t coords, unsigned int coord_count, const hb_array_t shared_tuples, - const hb_vector_t> *shared_tuple_active_idx = nullptr) const + hb_scalar_cache_t *shared_tuple_scalar_cache = nullptr) const { + unsigned tuple_index = tupleIndex; + const F2DOT14 *peak_tuple; - unsigned start_idx = 0; - unsigned end_idx = coord_count; - unsigned step = 1; + bool has_interm = tuple_index & TupleIndex::IntermediateRegion; // Inlined for performance - if (has_peak ()) - peak_tuple = get_peak_tuple (coord_count).arrayZ; + if (unlikely (tuple_index & TupleIndex::EmbeddedPeakTuple)) // Inlined for performance + { + peak_tuple = get_peak_tuple (coord_count); + shared_tuple_scalar_cache = nullptr; + } else { - unsigned int index = get_index (); - if (unlikely ((index + 1) * coord_count > shared_tuples.length)) - return 0.0; - peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ; + unsigned int index = tuple_index & TupleIndex::TupleIndexMask; // Inlined for performance - if (shared_tuple_active_idx) + float scalar; + if (shared_tuple_scalar_cache && + shared_tuple_scalar_cache->get (index, &scalar)) { - if (unlikely (index >= shared_tuple_active_idx->length)) - return 0.0; - auto _ = (*shared_tuple_active_idx).arrayZ[index]; - if (_.second != -1) - { - start_idx = _.first; - end_idx = _.second + 1; - step = _.second - _.first; - } - else if (_.first != -1) - { - start_idx = _.first; - end_idx = start_idx + 1; - } + if (has_interm && (scalar != 0 && scalar != 1.f)) + shared_tuple_scalar_cache = nullptr; + else + return (double) scalar; } + + if (unlikely ((index + 1) * coord_count > shared_tuples.length)) + return 0.0; + peak_tuple = shared_tuples.arrayZ + (coord_count * index); + } const F2DOT14 *start_tuple = nullptr; const F2DOT14 *end_tuple = nullptr; - bool has_interm = has_intermediate (); + if (has_interm) { - start_tuple = get_start_tuple (coord_count).arrayZ; - end_tuple = get_end_tuple (coord_count).arrayZ; + start_tuple = get_start_tuple (coord_count); + end_tuple = get_end_tuple (coord_count); } double scalar = 1.0; - for (unsigned int i = start_idx; i < end_idx; i += step) +#ifndef HB_OPTIMIZE_SIZE +#if HB_FAST_NUM_ACCESS + bool skip = coord_count >= 16; +#endif +#endif + for (unsigned int i = 0; i < coord_count; i++) { +#ifndef HB_OPTIMIZE_SIZE +#if HB_FAST_NUM_ACCESS + if (skip) + { + while (i + 4 <= coord_count && * (HBUINT64LE *) &peak_tuple[i] == 0) + i += 4; + while (i < coord_count && peak_tuple[i].to_int () == 0) + i += 1; + if (i >= coord_count) + break; + } +#endif +#endif + int peak = peak_tuple[i].to_int (); if (!peak) continue; int v = coords[i]; + if (!v) { scalar = 0.0; break; } if (v == peak) continue; if (has_interm) { + shared_tuple_scalar_cache = nullptr; int start = start_tuple[i].to_int (); int end = end_tuple[i].to_int (); if (unlikely (start > peak || peak > end || (start < 0 && end > 0 && peak))) continue; - if (v < start || v > end) return 0.0; + if (v < start || v > end) { scalar = 0.0; break; } if (v < peak) { if (peak != start) scalar *= (double) (v - start) / (peak - start); } else { if (peak != end) scalar *= (double) (end - v) / (end - peak); } } - else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.0; + else if (v < hb_min (0, peak) || v > hb_max (0, peak)) { scalar = 0.0; break; } else scalar *= (double) v / peak; } + if (shared_tuple_scalar_cache) + shared_tuple_scalar_cache->set (get_index (), scalar); return scalar; } - bool has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; } - bool has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; } - bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; } - unsigned get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; } + bool has_peak () const { return tupleIndex & TupleIndex::EmbeddedPeakTuple; } + bool has_intermediate () const { return tupleIndex & TupleIndex::IntermediateRegion; } + bool has_private_points () const { return tupleIndex & TupleIndex::PrivatePointNumbers; } + unsigned get_index () const { return tupleIndex & TupleIndex::TupleIndexMask; } protected: - struct TuppleIndex : HBUINT16 + struct TupleIndex : HBUINT16 { enum Flags { EmbeddedPeakTuple = 0x8000u, @@ -188,22 +220,24 @@ struct TupleVariationHeader TupleIndexMask = 0x0FFFu }; - TuppleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } + TupleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } DEFINE_SIZE_STATIC (2); }; hb_array_t get_all_tuples (unsigned axis_count) const { return StructAfter> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); } - hb_array_t get_peak_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (0, axis_count); } - hb_array_t get_start_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); } - hb_array_t get_end_tuple (unsigned axis_count) const - { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); } + const F2DOT14* get_all_tuples_base (unsigned axis_count) const + { return StructAfter> (tupleIndex).arrayZ; } + const F2DOT14* get_peak_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count); } + const F2DOT14* get_start_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count) + has_peak () * axis_count; } + const F2DOT14* get_end_tuple (unsigned axis_count) const + { return get_all_tuples_base (axis_count) + has_peak () * axis_count + axis_count; } HBUINT16 varDataSize; /* The size in bytes of the serialized * data for this tuple variation table. */ - TuppleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). + TupleIndex tupleIndex; /* A packed field. The high 4 bits are flags (see below). The low 12 bits are an index into a shared tuple records array. */ /* UnsizedArrayOf peakTuple - optional */ @@ -221,6 +255,21 @@ struct TupleVariationHeader DEFINE_SIZE_MIN (4); }; +struct optimize_scratch_t +{ + iup_scratch_t iup; + hb_vector_t opt_indices; + hb_vector_t rounded_x_deltas; + hb_vector_t rounded_y_deltas; + hb_vector_t opt_deltas_x; + hb_vector_t opt_deltas_y; + hb_vector_t opt_point_data; + hb_vector_t opt_deltas_data; + hb_vector_t point_data; + hb_vector_t deltas_data; + hb_vector_t rounded_deltas; +}; + struct tuple_delta_t { static constexpr bool realloc_move = true; // Watch out when adding new members! @@ -231,9 +280,9 @@ struct tuple_delta_t /* indices_length = point_count, indice[i] = 1 means point i is referenced */ hb_vector_t indices; - hb_vector_t deltas_x; + hb_vector_t deltas_x; /* empty for cvar tuples */ - hb_vector_t deltas_y; + hb_vector_t deltas_y; /* compiled data: header and deltas * compiled point data is saved in a hashmap within tuple_variations_t cause @@ -241,11 +290,12 @@ struct tuple_delta_t hb_vector_t compiled_tuple_header; hb_vector_t compiled_deltas; - /* compiled peak coords, empty for non-gvar tuples */ - hb_vector_t compiled_peak_coords; + hb_vector_t compiled_peak_coords; + hb_vector_t compiled_interm_coords; - tuple_delta_t () = default; + tuple_delta_t (hb_alloc_pool_t *pool = nullptr) {} tuple_delta_t (const tuple_delta_t& o) = default; + tuple_delta_t& operator = (const tuple_delta_t& o) = default; friend void swap (tuple_delta_t& a, tuple_delta_t& b) noexcept { @@ -267,6 +317,18 @@ struct tuple_delta_t return *this; } + void copy_from (const tuple_delta_t& o, hb_alloc_pool_t *pool = nullptr) + { + axis_tuples = o.axis_tuples; + indices.duplicate_vector_from_pool (pool, o.indices); + deltas_x.duplicate_vector_from_pool (pool, o.deltas_x); + deltas_y.duplicate_vector_from_pool (pool, o.deltas_y); + compiled_tuple_header.duplicate_vector_from_pool (pool, o.compiled_tuple_header); + compiled_deltas.duplicate_vector_from_pool (pool, o.compiled_deltas); + compiled_peak_coords.duplicate_vector_from_pool (pool, o.compiled_peak_coords); + compiled_interm_coords.duplicate_vector_from_pool (pool, o.compiled_interm_coords); + } + void remove_axis (hb_tag_t axis_tag) { axis_tuples.del (axis_tag); } @@ -299,9 +361,9 @@ struct tuple_delta_t return *this; } - tuple_delta_t& operator *= (double scalar) + tuple_delta_t& operator *= (float scalar) { - if (scalar == 1.0) + if (scalar == 1.0f) return *this; unsigned num = indices.length; @@ -321,31 +383,51 @@ struct tuple_delta_t return *this; } - hb_vector_t change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, - TripleDistances axis_triple_distances) const + void change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit, + TripleDistances axis_triple_distances, + hb_vector_t& out, + rebase_tent_result_scratch_t &scratch, + hb_alloc_pool_t *pool = nullptr) { - hb_vector_t out; + // May move *this out. + + out.reset (); Triple *tent; if (!axis_tuples.has (axis_tag, &tent)) { - out.push (*this); - return out; + out.push (std::move (*this)); + return; } if ((tent->minimum < 0.0 && tent->maximum > 0.0) || !(tent->minimum <= tent->middle && tent->middle <= tent->maximum)) - return out; + return; if (tent->middle == 0.0) { - out.push (*this); - return out; + out.push (std::move (*this)); + return; } - rebase_tent_result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances); - for (auto &t : solutions) + if (!axis_limit.is_point () && + !(-1.0 <= axis_limit.minimum && + axis_limit.minimum <= axis_limit.middle && + axis_limit.middle <= axis_limit.maximum && + axis_limit.maximum <= +1.0)) + return; + + rebase_tent_result_t &solutions = scratch.first; + rebase_tent (*tent, axis_limit, axis_triple_distances, solutions, scratch.second); + for (unsigned i = 0; i < solutions.length; i++) { - tuple_delta_t new_var = *this; + auto &t = solutions.arrayZ[i]; + + tuple_delta_t new_var; + if (i < solutions.length - 1) + new_var.copy_from (*this, pool); + else + new_var = std::move (*this); + if (t.second == Triple ()) new_var.remove_axis (axis_tag); else @@ -354,38 +436,76 @@ struct tuple_delta_t new_var *= t.first; out.push (std::move (new_var)); } - - return out; } - bool compile_peak_coords (const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) + bool compile_coords (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map, + hb_alloc_pool_t *pool= nullptr) { - unsigned axis_count = axes_index_map.get_population (); - if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size))) + unsigned cur_axis_count = axes_index_map.get_population (); + if (pool) + { + if (unlikely (!compiled_peak_coords.allocate_from_pool (pool, cur_axis_count))) + return false; + } + else if (unlikely (!compiled_peak_coords.resize (cur_axis_count))) return false; + hb_array_t start_coords, end_coords; + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + unsigned j = 0; for (unsigned i = 0; i < orig_axis_count; i++) { if (!axes_index_map.has (i)) continue; hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - F2DOT14 peak_coord; + Triple *coords = nullptr; if (axis_tuples.has (axis_tag, &coords)) - peak_coord.set_float (coords->middle); - else - peak_coord.set_int (0); + { + float min_val = coords->minimum; + float val = coords->middle; + float max_val = coords->maximum; + + compiled_peak_coords.arrayZ[j].set_float (val); + + if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) + { + if (!compiled_interm_coords) + { + if (pool) + { + if (unlikely (!compiled_interm_coords.allocate_from_pool (pool, 2 * cur_axis_count))) + return false; + } + else if (unlikely (!compiled_interm_coords.resize (2 * cur_axis_count))) + return false; + start_coords = compiled_interm_coords.as_array ().sub_array (0, cur_axis_count); + end_coords = compiled_interm_coords.as_array ().sub_array (cur_axis_count); + + for (unsigned k = 0; k < j; k++) + { + signed peak = compiled_peak_coords.arrayZ[k].to_int (); + if (!peak) continue; + start_coords.arrayZ[k].set_int (hb_min (peak, 0)); + end_coords.arrayZ[k].set_int (hb_max (peak, 0)); + } + } + + } + + if (compiled_interm_coords) + { + start_coords.arrayZ[j].set_float (min_val); + end_coords.arrayZ[j].set_float (max_val); + } + } - /* push F2DOT14 value into char vector */ - int16_t val = peak_coord.to_int (); - compiled_peak_coords.push (static_cast (val >> 8)); - compiled_peak_coords.push (static_cast (val & 0xFF)); + j++; } - return !compiled_peak_coords.in_error (); + return !compiled_peak_coords.in_error () && !compiled_interm_coords.in_error (); } /* deltas should be compiled already before we compile tuple @@ -394,7 +514,8 @@ struct tuple_delta_t bool compile_tuple_var_header (const hb_map_t& axes_index_map, unsigned points_data_length, const hb_map_t& axes_old_index_tag_map, - const hb_hashmap_t*, unsigned>* shared_tuples_idx_map) + const hb_hashmap_t*, unsigned>* shared_tuples_idx_map, + hb_alloc_pool_t *pool = nullptr) { /* compiled_deltas could be empty after iup delta optimization, we can skip * compiling this tuple and return true */ @@ -403,7 +524,7 @@ struct tuple_delta_t unsigned cur_axis_count = axes_index_map.get_population (); /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */ unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4; - if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false; + if (unlikely (!compiled_tuple_header.allocate_from_pool (pool, alloc_len, false))) return false; unsigned flag = 0; /* skip the first 4 header bytes: variationDataSize+tupleIndex */ @@ -411,6 +532,9 @@ struct tuple_delta_t F2DOT14* end = reinterpret_cast (compiled_tuple_header.end ()); hb_array_t coords (p, end - p); + if (!shared_tuples_idx_map) + compile_coords (axes_index_map, axes_old_index_tag_map); // non-gvar tuples do not have compiled coords yet + /* encode peak coords */ unsigned peak_count = 0; unsigned *shared_tuple_idx; @@ -421,16 +545,16 @@ struct tuple_delta_t } else { - peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); + peak_count = encode_peak_coords(coords, flag); if (!peak_count) return false; } /* encode interim coords, it's optional so returned num could be 0 */ - unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); + unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag); /* pointdata length = 0 implies "use shared points" */ if (points_data_length) - flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; + flag |= TupleVariationHeader::TupleIndex::PrivatePointNumbers; unsigned serialized_data_size = points_data_length + compiled_deltas.length; TupleVariationHeader *o = reinterpret_cast (compiled_tuple_header.begin ()); @@ -438,105 +562,63 @@ struct tuple_delta_t o->tupleIndex = flag; unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size); - return compiled_tuple_header.resize (total_header_len); + compiled_tuple_header.shrink_back_to_pool (pool, total_header_len); + return true; } unsigned encode_peak_coords (hb_array_t peak_coords, - unsigned& flag, - const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) const + unsigned& flag) const { - unsigned orig_axis_count = axes_old_index_tag_map.get_population (); - auto it = peak_coords.iter (); - unsigned count = 0; - for (unsigned i = 0; i < orig_axis_count; i++) - { - if (!axes_index_map.has (i)) /* axis pinned */ - continue; - hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - if (!axis_tuples.has (axis_tag, &coords)) - (*it).set_int (0); - else - (*it).set_float (coords->middle); - it++; - count++; - } - flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple; - return count; + hb_memcpy (&peak_coords[0], &compiled_peak_coords[0], compiled_peak_coords.length * sizeof (compiled_peak_coords[0])); + flag |= TupleVariationHeader::TupleIndex::EmbeddedPeakTuple; + return compiled_peak_coords.length; } /* if no need to encode intermediate coords, then just return p */ unsigned encode_interm_coords (hb_array_t coords, - unsigned& flag, - const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) const + unsigned& flag) const { - unsigned orig_axis_count = axes_old_index_tag_map.get_population (); - unsigned cur_axis_count = axes_index_map.get_population (); - - auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter (); - auto end_coords_iter = coords.sub_array (cur_axis_count).iter (); - bool encode_needed = false; - unsigned count = 0; - for (unsigned i = 0; i < orig_axis_count; i++) - { - if (!axes_index_map.has (i)) /* axis pinned */ - continue; - hb_tag_t axis_tag = axes_old_index_tag_map.get (i); - Triple *coords; - float min_val = 0.f, val = 0.f, max_val = 0.f; - if (axis_tuples.has (axis_tag, &coords)) - { - min_val = coords->minimum; - val = coords->middle; - max_val = coords->maximum; - } - - (*start_coords_iter).set_float (min_val); - (*end_coords_iter).set_float (max_val); - - start_coords_iter++; - end_coords_iter++; - count += 2; - if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f)) - encode_needed = true; - } - - if (encode_needed) + if (compiled_interm_coords) { - flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion; - return count; + hb_memcpy (&coords[0], &compiled_interm_coords[0], compiled_interm_coords.length * sizeof (compiled_interm_coords[0])); + flag |= TupleVariationHeader::TupleIndex::IntermediateRegion; } - return 0; + return compiled_interm_coords.length; } - bool compile_deltas () - { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas); } + bool compile_deltas (hb_vector_t &rounded_deltas_scratch, + hb_alloc_pool_t *pool = nullptr) + { return compile_deltas (indices, deltas_x, deltas_y, compiled_deltas, rounded_deltas_scratch, pool); } - static bool compile_deltas (const hb_vector_t &point_indices, - const hb_vector_t &x_deltas, - const hb_vector_t &y_deltas, - hb_vector_t &compiled_deltas /* OUT */) + static bool compile_deltas (hb_array_t point_indices, + hb_array_t x_deltas, + hb_array_t y_deltas, + hb_vector_t &compiled_deltas, /* OUT */ + hb_vector_t &rounded_deltas, /* scratch */ + hb_alloc_pool_t *pool = nullptr) { - hb_vector_t rounded_deltas; - if (unlikely (!rounded_deltas.alloc (point_indices.length))) + if (unlikely (!rounded_deltas.resize_dirty (point_indices.length))) return false; + unsigned j = 0; for (unsigned i = 0; i < point_indices.length; i++) { if (!point_indices[i]) continue; - int rounded_delta = (int) roundf (x_deltas.arrayZ[i]); - rounded_deltas.push (rounded_delta); + rounded_deltas.arrayZ[j++] = (int) roundf (x_deltas.arrayZ[i]); } + rounded_deltas.resize (j); if (!rounded_deltas) return true; - /* allocate enough memories 5 * num_deltas */ - unsigned alloc_len = 5 * rounded_deltas.length; + /* Allocate enough memory: this is the correct bound: + * Worst case scenario is that each delta has to be encoded in 4 bytes, and there + * are runs of 64 items each. Any delta encoded in less than 4 bytes (2, 1, or 0) + * is still smaller than the 4-byte encoding even with their control byte. + * The initial 2 is to handle length==0, for both x and y deltas. */ + unsigned alloc_len = 2 + 4 * rounded_deltas.length + (rounded_deltas.length + 63) / 64; if (y_deltas) alloc_len *= 2; - if (unlikely (!compiled_deltas.resize (alloc_len))) return false; + if (unlikely (!compiled_deltas.allocate_from_pool (pool, alloc_len, false))) return false; unsigned encoded_len = compile_deltas (compiled_deltas, rounded_deltas); @@ -557,28 +639,30 @@ struct tuple_delta_t if (j != rounded_deltas.length) return false; encoded_len += compile_deltas (compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas); } - return compiled_deltas.resize (encoded_len); + compiled_deltas.shrink_back_to_pool (pool, encoded_len); + return true; } static unsigned compile_deltas (hb_array_t encoded_bytes, hb_array_t deltas) { - return TupleValues::compile (deltas, encoded_bytes); + return TupleValues::compile_unsafe (deltas, encoded_bytes); } - bool calc_inferred_deltas (const contour_point_vector_t& orig_points) + bool calc_inferred_deltas (const contour_point_vector_t& orig_points, + hb_vector_t &scratch) { unsigned point_count = orig_points.length; if (point_count != indices.length) return false; unsigned ref_count = 0; - hb_vector_t end_points; + + hb_vector_t &end_points = scratch.reset (); for (unsigned i = 0; i < point_count; i++) { - if (indices.arrayZ[i]) - ref_count++; + ref_count += indices.arrayZ[i]; if (orig_points.arrayZ[i].is_end_point) end_points.push (i); } @@ -587,7 +671,7 @@ struct tuple_delta_t return true; if (unlikely (end_points.in_error ())) return false; - hb_set_t inferred_idxes; + hb_bit_set_t inferred_idxes; unsigned start_point = 0; for (unsigned end_point : end_points) { @@ -629,11 +713,11 @@ struct tuple_delta_t deltas_x.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].x, (double) orig_points.arrayZ[prev].x, (double) orig_points.arrayZ[next].x, - deltas_x.arrayZ[prev], deltas_x.arrayZ[next]); + (double) deltas_x.arrayZ[prev], (double) deltas_x.arrayZ[next]); deltas_y.arrayZ[i] = infer_delta ((double) orig_points.arrayZ[i].y, (double) orig_points.arrayZ[prev].y, (double) orig_points.arrayZ[next].y, - deltas_y.arrayZ[prev], deltas_y.arrayZ[next]); + (double) deltas_y.arrayZ[prev], (double) deltas_y.arrayZ[next]); inferred_idxes.add (i); if (--unref_count == 0) goto no_more_gaps; } @@ -661,6 +745,7 @@ struct tuple_delta_t bool optimize (const contour_point_vector_t& contour_points, bool is_composite, + optimize_scratch_t &scratch, double tolerance = 0.5 + 1e-10) { unsigned count = contour_points.length; @@ -668,22 +753,21 @@ struct tuple_delta_t deltas_y.length != count) return false; - hb_vector_t opt_indices; - hb_vector_t rounded_x_deltas, rounded_y_deltas; + hb_vector_t &opt_indices = scratch.opt_indices.reset (); + hb_vector_t &rounded_x_deltas = scratch.rounded_x_deltas; + hb_vector_t &rounded_y_deltas = scratch.rounded_y_deltas; - if (unlikely (!rounded_x_deltas.alloc (count) || - !rounded_y_deltas.alloc (count))) + if (unlikely (!rounded_x_deltas.resize_dirty (count) || + !rounded_y_deltas.resize_dirty (count))) return false; for (unsigned i = 0; i < count; i++) { - int rounded_x_delta = (int) roundf (deltas_x.arrayZ[i]); - int rounded_y_delta = (int) roundf (deltas_y.arrayZ[i]); - rounded_x_deltas.push (rounded_x_delta); - rounded_y_deltas.push (rounded_y_delta); + rounded_x_deltas.arrayZ[i] = (int) roundf (deltas_x.arrayZ[i]); + rounded_y_deltas.arrayZ[i] = (int) roundf (deltas_y.arrayZ[i]); } - if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, tolerance)) + if (!iup_delta_optimize (contour_points, rounded_x_deltas, rounded_y_deltas, opt_indices, scratch.iup, tolerance)) return false; unsigned ref_count = 0; @@ -692,7 +776,8 @@ struct tuple_delta_t if (ref_count == count) return true; - hb_vector_t opt_deltas_x, opt_deltas_y; + hb_vector_t &opt_deltas_x = scratch.opt_deltas_x.reset (); + hb_vector_t &opt_deltas_y = scratch.opt_deltas_y.reset (); bool is_comp_glyph_wo_deltas = (is_composite && ref_count == 0); if (is_comp_glyph_wo_deltas) { @@ -705,34 +790,31 @@ struct tuple_delta_t opt_indices.arrayZ[i] = false; } - hb_vector_t opt_point_data; + hb_vector_t &opt_point_data = scratch.opt_point_data.reset (); if (!compile_point_set (opt_indices, opt_point_data)) return false; - hb_vector_t opt_deltas_data; + hb_vector_t &opt_deltas_data = scratch.opt_deltas_data.reset (); if (!compile_deltas (opt_indices, is_comp_glyph_wo_deltas ? opt_deltas_x : deltas_x, is_comp_glyph_wo_deltas ? opt_deltas_y : deltas_y, - opt_deltas_data)) + opt_deltas_data, + scratch.rounded_deltas)) return false; - hb_vector_t point_data; + hb_vector_t &point_data = scratch.point_data.reset (); if (!compile_point_set (indices, point_data)) return false; - hb_vector_t deltas_data; - if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data)) + hb_vector_t &deltas_data = scratch.deltas_data.reset (); + if (!compile_deltas (indices, deltas_x, deltas_y, deltas_data, scratch.rounded_deltas)) return false; if (opt_point_data.length + opt_deltas_data.length < point_data.length + deltas_data.length) { - indices.fini (); indices = std::move (opt_indices); if (is_comp_glyph_wo_deltas) { - deltas_x.fini (); deltas_x = std::move (opt_deltas_x); - - deltas_y.fini (); deltas_y = std::move (opt_deltas_y); } } @@ -757,7 +839,7 @@ struct tuple_delta_t /* allocate enough memories: 2 bytes for count + 3 bytes for each point */ unsigned num_bytes = 2 + 3 *num_points; - if (unlikely (!compiled_points.resize (num_bytes, false))) + if (unlikely (!compiled_points.resize_dirty (num_bytes))) return false; unsigned pos = 0; @@ -821,7 +903,7 @@ struct tuple_delta_t else compiled_points.arrayZ[header_pos] = (run_length - 1) | 0x80; } - return compiled_points.resize (pos, false); + return compiled_points.resize_dirty (pos); } static double infer_delta (double target_val, double prev_val, double next_val, double prev_delta, double next_delta) @@ -841,6 +923,7 @@ struct tuple_delta_t { return (i >= end) ? start : (i + 1); } }; +template struct TupleVariationData { bool sanitize (hb_sanitize_context_t *c) const @@ -851,15 +934,15 @@ struct TupleVariationData return_trace (c->check_struct (this)); } - unsigned get_size (unsigned axis_count) const + unsigned get_size (unsigned axis_count_times_2) const { unsigned total_size = min_size; unsigned count = tupleVarCount.get_count (); const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header()); for (unsigned i = 0; i < count; i++) { - total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size (); - tuple_var_header = &tuple_var_header->get_next (axis_count); + total_size += tuple_var_header->get_size (axis_count_times_2) + tuple_var_header->get_data_size (); + tuple_var_header = &tuple_var_header->get_next (axis_count_times_2); } return total_size; @@ -875,7 +958,7 @@ struct TupleVariationData private: /* referenced point set->compiled point data map */ - hb_hashmap_t*, hb_vector_t> point_data_map; + hb_hashmap_t*, hb_vector_t> point_data_map; /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t*, unsigned> point_set_count_map; @@ -883,11 +966,11 @@ struct TupleVariationData * shared_points_bytes is a pointer to some value in the point_data_map, * which will be freed during map destruction. Save it for serialization, so * no need to do find_shared_points () again */ - hb_vector_t *shared_points_bytes = nullptr; + hb_vector_t *shared_points_bytes = nullptr; - /* total compiled byte size as TupleVariationData format, initialized to its - * min_size: 4 */ - unsigned compiled_byte_size = 4; + /* total compiled byte size as TupleVariationData format, initialized to 0 */ + unsigned compiled_byte_size = 0; + bool needs_padding = false; /* for gvar iup delta optimization: whether this is a composite glyph */ bool is_composite = false; @@ -924,8 +1007,12 @@ struct TupleVariationData const hb_map_t *axes_old_index_tag_map, const hb_vector_t &shared_indices, const hb_array_t shared_tuples, - bool is_composite_glyph) + hb_alloc_pool_t *pool = nullptr, + bool is_composite_glyph = false) { + hb_vector_t private_indices; + hb_vector_t deltas_x; + hb_vector_t deltas_y; do { const HBUINT8 *p = iterator.get_serialized_data (); @@ -933,12 +1020,12 @@ struct TupleVariationData if (unlikely (!iterator.var_data_bytes.check_range (p, length))) return false; - hb_hashmap_t axis_tuples; + hb_hashmap_t axis_tuples; if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples) || axis_tuples.is_empty ()) return false; - hb_vector_t private_indices; + private_indices.reset (); bool has_private_points = iterator.current_tuple->has_private_points (); const HBUINT8 *end = p + length; if (has_private_points && @@ -949,27 +1036,24 @@ struct TupleVariationData bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? point_count : indices.length; - hb_vector_t deltas_x; - - if (unlikely (!deltas_x.resize (num_deltas, false) || + if (unlikely (!deltas_x.resize_dirty (num_deltas) || !TupleVariationData::decompile_deltas (p, deltas_x, end))) return false; - hb_vector_t deltas_y; if (is_gvar) { - if (unlikely (!deltas_y.resize (num_deltas, false) || + if (unlikely (!deltas_y.resize_dirty (num_deltas) || !TupleVariationData::decompile_deltas (p, deltas_y, end))) return false; } tuple_delta_t var; var.axis_tuples = std::move (axis_tuples); - if (unlikely (!var.indices.resize (point_count) || - !var.deltas_x.resize (point_count, false))) + if (unlikely (!var.indices.allocate_from_pool (pool, point_count) || + !var.deltas_x.allocate_from_pool (pool, point_count, false))) return false; - if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false))) + if (is_gvar && unlikely (!var.deltas_y.allocate_from_pool (pool, point_count, false))) return false; for (unsigned i = 0; i < num_deltas; i++) @@ -1011,8 +1095,8 @@ struct TupleVariationData /* In VarData, deltas are organized in rows, convert them into * column(region) based tuples, resize deltas_x first */ tuple_delta_t tuple; - if (!tuple.deltas_x.resize (item_count, false) || - !tuple.indices.resize (item_count, false)) + if (!tuple.deltas_x.resize_dirty (item_count) || + !tuple.indices.resize_dirty (item_count)) return false; for (unsigned i = 0; i < item_count; i++) @@ -1040,7 +1124,8 @@ struct TupleVariationData } bool change_tuple_variations_axis_limits (const hb_hashmap_t& normalized_axes_location, - const hb_hashmap_t& axes_triple_distances) + const hb_hashmap_t& axes_triple_distances, + hb_alloc_pool_t *pool = nullptr) { /* sort axis_tag/axis_limits, make result deterministic */ hb_vector_t axis_tags; @@ -1049,6 +1134,10 @@ struct TupleVariationData for (auto t : normalized_axes_location.keys ()) axis_tags.push (t); + // Reused vectors for reduced malloc pressure. + rebase_tent_result_scratch_t scratch; + hb_vector_t out; + axis_tags.qsort (_cmp_axis_tag); for (auto axis_tag : axis_tags) { @@ -1060,9 +1149,10 @@ struct TupleVariationData axis_triple_distances = axes_triple_distances.get (axis_tag); hb_vector_t new_vars; - for (const tuple_delta_t& var : tuple_vars) + for (tuple_delta_t& var : tuple_vars) { - hb_vector_t out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances); + // This may move var out. + var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances, out, scratch, pool); if (!out) continue; unsigned new_len = new_vars.length + out.length; @@ -1073,7 +1163,6 @@ struct TupleVariationData for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); } - tuple_vars.fini (); tuple_vars = std::move (new_vars); } return true; @@ -1084,9 +1173,12 @@ struct TupleVariationData bool merge_tuple_variations (contour_point_vector_t* contour_points = nullptr) { hb_vector_t new_vars; + // The pre-allocation is essential for address stability of pointers + // we store in the hashmap. + if (unlikely (!new_vars.alloc (tuple_vars.length))) + return false; hb_hashmap_t*, unsigned> m; - unsigned i = 0; - for (const tuple_delta_t& var : tuple_vars) + for (tuple_delta_t& var : tuple_vars) { /* if all axes are pinned, drop the tuple variation */ if (var.axis_tuples.is_empty ()) @@ -1106,13 +1198,17 @@ struct TupleVariationData } else { - new_vars.push (var); - if (!m.set (&(var.axis_tuples), i)) + auto *new_var = new_vars.push (); + if (unlikely (new_vars.in_error ())) + return false; + hb_swap (*new_var, var); + if (unlikely (!m.set (&(new_var->axis_tuples), new_vars.length - 1))) return false; - i++; } } - tuple_vars.fini (); + m.fini (); // Just in case, since it points into new_vars data. + // Shouldn't be necessary though, since we only move new_vars, not its + // contents. tuple_vars = std::move (new_vars); return true; } @@ -1172,20 +1268,22 @@ struct TupleVariationData } } - bool calc_inferred_deltas (const contour_point_vector_t& contour_points) + bool calc_inferred_deltas (const contour_point_vector_t& contour_points, + hb_vector_t &scratch) { for (tuple_delta_t& var : tuple_vars) - if (!var.calc_inferred_deltas (contour_points)) + if (!var.calc_inferred_deltas (contour_points, scratch)) return false; return true; } - bool iup_optimize (const contour_point_vector_t& contour_points) + bool iup_optimize (const contour_point_vector_t& contour_points, + optimize_scratch_t &scratch) { for (tuple_delta_t& var : tuple_vars) { - if (!var.optimize (contour_points, is_composite)) + if (!var.optimize (contour_points, is_composite, scratch)) return false; } return true; @@ -1194,16 +1292,21 @@ struct TupleVariationData public: bool instantiate (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances, + optimize_scratch_t &scratch, + hb_alloc_pool_t *pool = nullptr, contour_point_vector_t* contour_points = nullptr, bool optimize = false) { if (!tuple_vars) return true; - if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) + if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances, pool)) return false; /* compute inferred deltas only for gvar */ if (contour_points) - if (!calc_inferred_deltas (*contour_points)) - return false; + { + hb_vector_t scratch; + if (!calc_inferred_deltas (*contour_points, scratch)) + return false; + } /* if iup delta opt is on, contour_points can't be null */ if (optimize && !contour_points) @@ -1212,30 +1315,41 @@ struct TupleVariationData if (!merge_tuple_variations (optimize ? contour_points : nullptr)) return false; - if (optimize && !iup_optimize (*contour_points)) return false; + if (optimize && !iup_optimize (*contour_points, scratch)) return false; return !tuple_vars.in_error (); } bool compile_bytes (const hb_map_t& axes_index_map, const hb_map_t& axes_old_index_tag_map, bool use_shared_points, - const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr) + bool is_gvar = false, + const hb_hashmap_t*, unsigned>* shared_tuples_idx_map = nullptr, + hb_alloc_pool_t *pool = nullptr) { + // return true for empty glyph + if (!tuple_vars) + return true; + // compile points set and store data in hashmap if (!compile_all_point_sets ()) return false; + /* total compiled byte size as TupleVariationData format, initialized to its + * min_size: 4 */ + compiled_byte_size += 4; + if (use_shared_points) { find_shared_points (); if (shared_points_bytes) compiled_byte_size += shared_points_bytes->length; } + hb_vector_t rounded_deltas_scratch; // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_vector_t *points_data; + hb_vector_t *points_data; if (unlikely (!point_data_map.has (points_set, &points_data))) return false; @@ -1244,15 +1358,23 @@ struct TupleVariationData * this tuple */ if (!points_data->length) continue; - if (!tuple.compile_deltas ()) + if (!tuple.compile_deltas (rounded_deltas_scratch, pool)) return false; unsigned points_data_length = (points_data != shared_points_bytes) ? points_data->length : 0; if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, - shared_tuples_idx_map)) + shared_tuples_idx_map, + pool)) return false; compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } + + if (is_gvar && (compiled_byte_size % 2)) + { + needs_padding = true; + compiled_byte_size += 1; + } + return true; } @@ -1273,20 +1395,20 @@ struct TupleVariationData TRACE_SERIALIZE (this); if (is_gvar && shared_points_bytes) { - hb_bytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); + hb_ubytes_t s (shared_points_bytes->arrayZ, shared_points_bytes->length); s.copy (c); } for (const auto& tuple: tuple_vars) { const hb_vector_t* points_set = &(tuple.indices); - hb_vector_t *point_data; + hb_vector_t *point_data; if (!point_data_map.has (points_set, &point_data)) return_trace (false); if (!is_gvar || point_data != shared_points_bytes) { - hb_bytes_t s (point_data->arrayZ, point_data->length); + hb_ubytes_t s (point_data->arrayZ, point_data->length); s.copy (c); } @@ -1295,7 +1417,7 @@ struct TupleVariationData } /* padding for gvar */ - if (is_gvar && (compiled_byte_size % 2)) + if (is_gvar && needs_padding) { HBUINT8 pad; pad = 0; @@ -1313,8 +1435,9 @@ struct TupleVariationData { var_data_bytes = var_data_bytes_; var_data = var_data_bytes_.as (); - index = 0; + tuples_left = var_data->tupleVarCount.get_count (); axis_count = axis_count_; + axis_count_times_2 = axis_count_ * 2; current_tuple = &var_data->get_tuple_var_header (); data_offset = 0; table_base = table_base_; @@ -1332,30 +1455,42 @@ struct TupleVariationData return true; } - bool is_valid () const + bool is_valid () { - return (index < var_data->tupleVarCount.get_count ()) && - var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) && - var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (), - current_tuple->get_size (axis_count))); + if (unlikely (tuples_left <= 0)) + return false; + + current_tuple_size = TupleVariationHeader::min_size; + if (unlikely (!var_data_bytes.check_end ((const char *) current_tuple + current_tuple_size))) + return false; + + current_tuple_size = current_tuple->get_size (axis_count_times_2); + if (unlikely (!var_data_bytes.check_end ((const char *) current_tuple + current_tuple_size))) + return false; + + return true; } + HB_ALWAYS_INLINE bool move_to_next () { data_offset += current_tuple->get_data_size (); - current_tuple = ¤t_tuple->get_next (axis_count); - index++; + current_tuple = &StructAtOffset (current_tuple, current_tuple_size); + tuples_left--; return is_valid (); } + // TODO: Make it return (sanitized) hb_bytes_t const HBUINT8 *get_serialized_data () const { return &(table_base+var_data->data) + data_offset; } private: + signed tuples_left; const TupleVariationData *var_data; - unsigned int index; unsigned int axis_count; + unsigned int axis_count_times_2; unsigned int data_offset; + unsigned int current_tuple_size; const void *table_base; public: @@ -1394,7 +1529,7 @@ struct TupleVariationData if (unlikely (p + 1 > end)) return false; count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++; } - if (unlikely (!points.resize (count, false))) return false; + if (unlikely (!points.resize_dirty (count))) return false; unsigned n = 0; unsigned i = 0; @@ -1429,12 +1564,14 @@ struct TupleVariationData } template + HB_ALWAYS_INLINE static bool decompile_deltas (const HBUINT8 *&p /* IN/OUT */, hb_vector_t &deltas /* IN/OUT */, const HBUINT8 *end, - bool consume_all = false) + bool consume_all = false, + unsigned start = 0) { - return TupleValues::decompile (p, deltas, end, consume_all); + return TupleValues::decompile (p, deltas, end, consume_all, start); } bool has_data () const { return tupleVarCount; } @@ -1446,6 +1583,7 @@ struct TupleVariationData const hb_vector_t &shared_indices, const hb_array_t shared_tuples, tuple_variations_t& tuple_variations, /* OUT */ + hb_alloc_pool_t *pool = nullptr, bool is_composite_glyph = false) const { return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount, @@ -1453,6 +1591,7 @@ struct TupleVariationData axes_old_index_tag_map, shared_indices, shared_tuples, + pool, is_composite_glyph); } @@ -1505,15 +1644,16 @@ struct TupleVariationData * low 12 bits are the number of tuple variation tables * for this glyph. The number of tuple variation tables * can be any number between 1 and 4095. */ - Offset16To + OffsetTo data; /* Offset from the start of the base table * to the serialized data. */ /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */ public: - DEFINE_SIZE_MIN (4); + DEFINE_SIZE_MIN (2 + OffType::static_size); }; -using tuple_variations_t = TupleVariationData::tuple_variations_t; +// TODO: Move tuple_variations_t to outside of TupleVariationData +using tuple_variations_t = TupleVariationData::tuple_variations_t; struct item_variations_t { using region_t = const hb_hashmap_t*; @@ -1567,6 +1707,16 @@ struct item_variations_t const hb_map_t& get_varidx_map () const { return varidx_map; } + bool add_vardata_encoding_for_testing (hb_vector_t*> &&rows, + unsigned num_cols) + { + encodings.push (delta_row_encoding_t (std::move (rows), num_cols)); + return !encodings.in_error (); + } + + bool compile_varidx_map_for_testing (const hb_hashmap_t*>& front_mapping) + { return compile_varidx_map (front_mapping); } + bool instantiate (const ItemVariationStore& varStore, const hb_subset_plan_t *plan, bool optimize=true, @@ -1616,8 +1766,9 @@ struct item_variations_t bool instantiate_tuple_vars (const hb_hashmap_t& normalized_axes_location, const hb_hashmap_t& axes_triple_distances) { + optimize_scratch_t scratch; for (tuple_variations_t& tuple_vars : vars) - if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances)) + if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances, scratch)) return false; if (!build_region_list ()) return false; @@ -1702,30 +1853,28 @@ struct item_variations_t struct combined_gain_idx_tuple_t { - int gain; - unsigned idx_1; - unsigned idx_2; + uint64_t encoded; combined_gain_idx_tuple_t () = default; - combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j) - :gain (gain_), idx_1 (i), idx_2 (j) {} + combined_gain_idx_tuple_t (unsigned gain, unsigned i, unsigned j) + : encoded ((uint64_t (0xFFFFFF - gain) << 40) | (uint64_t (i) << 20) | uint64_t (j)) + { + assert (gain < 0xFFFFFF); + assert (i < 0xFFFFFFF && j < 0xFFFFFFF); + } bool operator < (const combined_gain_idx_tuple_t& o) { - if (gain != o.gain) - return gain < o.gain; - - if (idx_1 != o.idx_1) - return idx_1 < o.idx_1; - - return idx_2 < o.idx_2; + return encoded < o.encoded; } bool operator <= (const combined_gain_idx_tuple_t& o) { - if (*this < o) return true; - return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2; + return encoded <= o.encoded; } + + unsigned idx_1 () const { return (encoded >> 20) & 0xFFFFF; }; + unsigned idx_2 () const { return encoded & 0xFFFFF; }; }; bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) @@ -1747,9 +1896,9 @@ struct item_variations_t hb_hashmap_t*> front_mapping; unsigned start_row = 0; hb_vector_t encoding_objs; - hb_hashmap_t, unsigned> chars_idx_map; /* delta_rows map, used for filtering out duplicate rows */ + hb_vector_t *> major_rows; hb_hashmap_t*, unsigned> delta_rows_map; for (unsigned major = 0; major < vars.length; major++) { @@ -1757,6 +1906,9 @@ struct item_variations_t * (row based) delta */ const tuple_variations_t& tuples = vars[major]; unsigned num_rows = var_data_num_rows[major]; + + if (!num_rows) continue; + for (const tuple_delta_t& tuple: tuples.tuple_vars) { if (tuple.deltas_x.length != num_rows) @@ -1771,81 +1923,66 @@ struct item_variations_t { int rounded_delta = roundf (tuple.deltas_x[i]); delta_rows[start_row + i][*col_idx] += rounded_delta; - if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535)) - has_long = true; + has_long |= rounded_delta < -65536 || rounded_delta > 65535; } } - if (!optimize) - { - /* assemble a delta_row_encoding_t for this subtable, skip optimization so - * chars is not initialized, we only need delta rows for serialization */ - delta_row_encoding_t obj; - for (unsigned r = start_row; r < start_row + num_rows; r++) - obj.add_row (&(delta_rows.arrayZ[r])); - - encodings.push (std::move (obj)); - start_row += num_rows; - continue; - } - + major_rows.reset (); for (unsigned minor = 0; minor < num_rows; minor++) { - const hb_vector_t& row = delta_rows[start_row + minor]; - if (use_no_variation_idx) - { - bool all_zeros = true; - for (int delta : row) - { - if (delta != 0) - { - all_zeros = false; - break; - } - } - if (all_zeros) - continue; - } + const hb_vector_t& row = delta_rows[start_row + minor]; + if (use_no_variation_idx) + { + bool all_zeros = true; + for (int delta : row) + { + if (delta != 0) + { + all_zeros = false; + break; + } + } + if (all_zeros) + continue; + } - if (!front_mapping.set ((major<<16) + minor, &row)) - return false; + if (!front_mapping.set ((major<<16) + minor, &row)) + return false; - hb_vector_t chars = delta_row_encoding_t::get_row_chars (row); - if (!chars) return false; + if (delta_rows_map.has (&row)) + continue; - if (delta_rows_map.has (&row)) - continue; + delta_rows_map.set (&row, 1); - delta_rows_map.set (&row, 1); - unsigned *obj_idx; - if (chars_idx_map.has (chars, &obj_idx)) - { - delta_row_encoding_t& obj = encoding_objs[*obj_idx]; - if (!obj.add_row (&row)) - return false; - } - else - { - if (!chars_idx_map.set (chars, encoding_objs.length)) - return false; - delta_row_encoding_t obj (std::move (chars), &row); - encoding_objs.push (std::move (obj)); - } + major_rows.push (&row); } + if (major_rows) + encoding_objs.push (delta_row_encoding_t (std::move (major_rows), num_cols)); + start_row += num_rows; } /* return directly if no optimization, maintain original VariationIndex so * varidx_map would be empty */ - if (!optimize) return !encodings.in_error (); + if (!optimize) + { + encodings = std::move (encoding_objs); + return !encodings.in_error (); + } - /* sort encoding_objs */ + /* NOTE: Fonttools instancer always optimizes VarStore from scratch. This + * is too costly for large fonts. So, instead, we retain the encodings of + * the original VarStore, and just try to combine them if possible. This + * is a compromise between optimization and performance and practically + * works very well. */ + + // This produces slightly smaller results in some cases. encoding_objs.qsort (); - /* main algorithm: repeatedly pick 2 best encodings to combine, and combine - * them */ - hb_priority_queue_t queue; + /* main algorithm: repeatedly pick 2 best encodings to combine, and combine them */ + using item_t = hb_priority_queue_t::item_t; + hb_vector_t queue_items; unsigned num_todos = encoding_objs.length; for (unsigned i = 0; i < num_todos; i++) { @@ -1853,16 +1990,18 @@ struct item_variations_t { int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]); if (combining_gain > 0) - queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0); + queue_items.push (item_t (combined_gain_idx_tuple_t (combining_gain, i, j), 0)); } } - hb_set_t removed_todo_idxes; + hb_priority_queue_t queue (std::move (queue_items)); + + hb_bit_set_t removed_todo_idxes; while (queue) { auto t = queue.pop_minimum ().first; - unsigned i = t.idx_1; - unsigned j = t.idx_2; + unsigned i = t.idx_1 (); + unsigned j = t.idx_2 (); if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j)) continue; @@ -1873,40 +2012,36 @@ struct item_variations_t removed_todo_idxes.add (i); removed_todo_idxes.add (j); - hb_vector_t combined_chars; - if (!combined_chars.alloc (encoding.chars.length)) - return false; - - for (unsigned idx = 0; idx < encoding.chars.length; idx++) - { - uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]); - combined_chars.push (v); - } - - delta_row_encoding_t combined_encoding_obj (std::move (combined_chars)); - for (const auto& row : hb_concat (encoding.items, other_encoding.items)) - combined_encoding_obj.add_row (row); + encoding.merge (other_encoding); for (unsigned idx = 0; idx < encoding_objs.length; idx++) { if (removed_todo_idxes.has (idx)) continue; const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx]; - if (obj.chars == combined_chars) + // In the unlikely event that the same encoding exists already, combine it. + if (obj.width == encoding.width && obj.chars == encoding.chars) { + // This is straight port from fonttools algorithm. I added this branch there + // because I thought it can happen. But looks like we never get in here in + // practice. I'm not confident enough to remove it though; in theory it can + // happen. I think it's just that our tests are not extensive enough to hit + // this path. + for (const auto& row : obj.items) - combined_encoding_obj.add_row (row); + encoding.add_row (row); removed_todo_idxes.add (idx); continue; } - int combined_gain = combined_encoding_obj.gain_from_merging (obj); + int combined_gain = encoding.gain_from_merging (obj); if (combined_gain > 0) - queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0); + queue.insert (combined_gain_idx_tuple_t (combined_gain, idx, encoding_objs.length), 0); } - encoding_objs.push (std::move (combined_encoding_obj)); + auto moved_encoding = std::move (encoding); + encoding_objs.push (moved_encoding); } int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population (); @@ -1919,9 +2054,6 @@ struct item_variations_t encodings.push (std::move (encoding_objs.arrayZ[i])); } - /* sort again based on width, make result deterministic */ - encodings.qsort (delta_row_encoding_t::cmp_width); - return compile_varidx_map (front_mapping); } @@ -1931,27 +2063,46 @@ struct item_variations_t { /* full encoding_row -> new VarIdxes mapping */ hb_hashmap_t*, unsigned> back_mapping; + hb_vector_t split_encodings; - for (unsigned major = 0; major < encodings.length; major++) + for (unsigned i = 0; i < encodings.length; i++) { - delta_row_encoding_t& encoding = encodings[major]; + delta_row_encoding_t& encoding = encodings[i]; /* just sanity check, this shouldn't happen */ if (encoding.is_empty ()) return false; unsigned num_rows = encoding.items.length; + unsigned num_cols = encoding.chars.length; /* sort rows, make result deterministic */ encoding.items.qsort (_cmp_row); - /* compile old to new var_idxes mapping */ - for (unsigned minor = 0; minor < num_rows; minor++) + for (unsigned start = 0; start < num_rows; start += 0xFFFFu) { - unsigned new_varidx = (major << 16) + minor; - back_mapping.set (encoding.items.arrayZ[minor], new_varidx); + unsigned chunk_len = hb_min (num_rows - start, 0xFFFFu); + hb_vector_t*> rows; + + if (!rows.alloc (chunk_len)) + return false; + + unsigned major = split_encodings.length; + for (unsigned minor = 0; minor < chunk_len; minor++) + { + const hb_vector_t *row = encoding.items.arrayZ[start + minor]; + rows.push (row); + if (!back_mapping.set (row, (major << 16) + minor)) + return false; + } + + split_encodings.push (delta_row_encoding_t (std::move (rows), num_cols)); } } + encodings = std::move (split_encodings); + if (encodings.in_error () || back_mapping.in_error ()) + return false; + for (auto _ : front_mapping.iter ()) { unsigned old_varidx = _.first; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var-cvar-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-var-cvar-table.hh index 3931382f1..358a95539 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var-cvar-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-var-cvar-table.hh @@ -50,7 +50,7 @@ struct cvar tupleVariationData.sanitize (c)); } - const TupleVariationData* get_tuple_var_data (void) const + const TupleVariationData<>* get_tuple_var_data (void) const { return &tupleVariationData; } bool decompile_tuple_variations (unsigned axis_count, @@ -58,15 +58,15 @@ struct cvar hb_blob_t *blob, bool is_gvar, const hb_map_t *axes_old_index_tag_map, - TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const + TupleVariationData<>::tuple_variations_t& tuple_variations /* OUT */) const { hb_vector_t shared_indices; - TupleVariationData::tuple_iterator_t iterator; + TupleVariationData<>::tuple_iterator_t iterator; hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, this, shared_indices, &iterator)) return false; - + return tupleVariationData.decompile_tuple_variations (point_count, is_gvar, iterator, axes_old_index_tag_map, shared_indices, @@ -77,16 +77,16 @@ struct cvar static bool calculate_cvt_deltas (unsigned axis_count, hb_array_t coords, unsigned num_cvt_item, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base, hb_vector_t& cvt_deltas /* OUT */) { if (!coords) return true; hb_vector_t shared_indices; - TupleVariationData::tuple_iterator_t iterator; - unsigned var_data_length = tuple_var_data->get_size (axis_count); + TupleVariationData<>::tuple_iterator_t iterator; + unsigned var_data_length = tuple_var_data->get_size (axis_count * 2); hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast (tuple_var_data), var_data_length); - if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, base, + if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base, shared_indices, &iterator)) return true; /* isn't applied at all */ @@ -107,14 +107,14 @@ struct cvar bool has_private_points = iterator.current_tuple->has_private_points (); if (has_private_points && - !TupleVariationData::decompile_points (p, private_indices, end)) + !TupleVariationData<>::decompile_points (p, private_indices, end)) return false; const hb_vector_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length; - if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false; - if (unlikely (!TupleVariationData::decompile_deltas (p, unpacked_deltas, end))) return false; + if (unlikely (!unpacked_deltas.resize_dirty (num_deltas))) return false; + if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false; for (unsigned int i = 0; i < num_deltas; i++) { @@ -129,7 +129,7 @@ struct cvar } bool serialize (hb_serialize_context_t *c, - TupleVariationData::tuple_variations_t& tuple_variations) const + TupleVariationData<>::tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); if (!tuple_variations) return_trace (false); @@ -144,7 +144,7 @@ struct cvar if (c->plan->all_axes_pinned) return_trace (false); - OT::TupleVariationData::tuple_variations_t tuple_variations; + OT::TupleVariationData<>::tuple_variations_t tuple_variations; unsigned axis_count = c->plan->axes_old_index_tag_map.get_population (); const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -158,7 +158,8 @@ struct cvar tuple_variations)) return_trace (false); - if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) + optimize_scratch_t scratch; + if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances, scratch)) return_trace (false); if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map, @@ -169,7 +170,7 @@ struct cvar } static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan, - const TupleVariationData *tuple_var_data, + const TupleVariationData<> *tuple_var_data, const void *base) { const hb_tag_t cvt = HB_TAG('c','v','t',' '); @@ -209,7 +210,7 @@ struct cvar protected: FixedVersion<>version; /* Version of the CVT variation table * initially set to 0x00010000u */ - TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */ + TupleVariationData<> tupleVariationData; /* TupleVariationDate for cvar table */ public: DEFINE_SIZE_MIN (8); }; diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-var-fvar-table.hh index 2cd9afbb7..4b4410f9b 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-var-fvar-table.hh @@ -78,7 +78,7 @@ struct InstanceRecord return false; if (!axes_location->has (*axis_tag)) continue; - + Triple axis_limit = axes_location->get (*axis_tag); if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit)) return false; @@ -106,7 +106,7 @@ struct InstanceRecord { if (!axis_coord_pinned_or_within_axis_range (coords, i, *axis_limit)) return_trace (false); - + //skip pinned axis if (axis_limit->is_point ()) continue; @@ -179,7 +179,7 @@ struct AxisRecord hb_tag_t get_axis_tag () const { return axisTag; } - int normalize_axis_value (float v) const + float normalize_axis_value (float v) const { float min_value, default_value, max_value; get_coordinates (min_value, default_value, max_value); @@ -189,23 +189,9 @@ struct AxisRecord if (v == default_value) return 0; else if (v < default_value) - v = (v - default_value) / (default_value - min_value); - else - v = (v - default_value) / (max_value - default_value); - return roundf (v * 16384.f); - } - - float unnormalize_axis_value (int v) const - { - float min_value, default_value, max_value; - get_coordinates (min_value, default_value, max_value); - - if (v == 0) - return default_value; - else if (v < 0) - return v * (default_value - min_value) / 16384.f + default_value; + return (v - default_value) / (default_value - min_value); else - return v * (max_value - default_value) / 16384.f + default_value; + return (v - default_value) / (max_value - default_value); } hb_ot_name_id_t get_name_id () const { return axisNameID; } @@ -341,12 +327,9 @@ struct fvar return axes.lfind (tag, &i) && ((void) axes[i].get_axis_info (i, info), true); } - int normalize_axis_value (unsigned int axis_index, float v) const + float normalize_axis_value (unsigned int axis_index, float v) const { return get_axes ()[axis_index].normalize_axis_value (v); } - float unnormalize_axis_value (unsigned int axis_index, int v) const - { return get_axes ()[axis_index].unnormalize_axis_value (v); } - unsigned int get_instance_count () const { return instanceCount; } hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-var-gvar-table.hh index b021a00f6..a4959dbc4 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-var-gvar-table.hh @@ -28,6 +28,7 @@ #ifndef HB_OT_VAR_GVAR_TABLE_HH #define HB_OT_VAR_GVAR_TABLE_HH +#include "hb-decycler.hh" #include "hb-open-type.hh" #include "hb-ot-var-common.hh" @@ -36,23 +37,43 @@ * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar */ #define HB_OT_TAG_gvar HB_TAG('g','v','a','r') +#define HB_OT_TAG_GVAR HB_TAG('G','V','A','R') -namespace OT { +struct hb_glyf_scratch_t +{ + // glyf + contour_point_vector_t all_points; + contour_point_vector_t comp_points; + hb_decycler_t decycler; + + // gvar + contour_point_vector_t orig_points; + hb_vector_t x_deltas; + hb_vector_t y_deltas; + contour_point_vector_t deltas; + hb_vector_t shared_indices; + hb_vector_t private_indices; +}; -struct GlyphVariationData : TupleVariationData -{}; +namespace OT { +template struct glyph_variations_t { - using tuple_variations_t = TupleVariationData::tuple_variations_t; + // TODO: Move tuple_variations_t to outside of TupleVariationData + using tuple_variations_t = typename TupleVariationData::tuple_variations_t; + using GlyphVariationData = TupleVariationData; + hb_vector_t glyph_variations; - hb_vector_t compiled_shared_tuples; + hb_vector_t compiled_shared_tuples; private: unsigned shared_tuples_count = 0; /* shared coords-> index map after instantiation */ - hb_hashmap_t*, unsigned> shared_tuples_idx_map; + hb_hashmap_t*, unsigned> shared_tuples_idx_map; + + hb_alloc_pool_t pool; public: unsigned compiled_shared_tuples_count () const @@ -72,7 +93,7 @@ struct glyph_variations_t const hb_subset_plan_t *plan, const hb_hashmap_t& new_gid_var_data_map) { - if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true))) + if (unlikely (!glyph_variations.alloc_exact (plan->new_to_old_gid_list.length))) return false; auto it = hb_iter (plan->new_to_old_gid_list); @@ -86,10 +107,11 @@ struct glyph_variations_t hb_bytes_t var_data = new_gid_var_data_map.get (new_gid); const GlyphVariationData* p = reinterpret_cast (var_data.arrayZ); - hb_vector_t shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + typename GlyphVariationData::tuple_iterator_t iterator; tuple_variations_t tuple_vars; + hb_vector_t shared_indices; + /* in case variation data is empty, push an empty struct into the vector, * keep the vector in sync with the new_to_old_gid_list */ if (!var_data || ! p->has_data () || !all_contour_points->length || @@ -108,6 +130,7 @@ struct glyph_variations_t iterator, &(plan->axes_old_index_tag_map), shared_indices, shared_tuples, tuple_vars, /* OUT */ + &pool, is_composite_glyph)) return false; glyph_variations.push (std::move (tuple_vars)); @@ -119,6 +142,7 @@ struct glyph_variations_t { unsigned count = plan->new_to_old_gid_list.length; bool iup_optimize = false; + optimize_scratch_t scratch; iup_optimize = plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS; for (unsigned i = 0; i < count; i++) { @@ -126,7 +150,7 @@ struct glyph_variations_t contour_point_vector_t *all_points; if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) return false; - if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points, iup_optimize)) + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, scratch, &pool, all_points, iup_optimize)) return false; } return true; @@ -140,7 +164,9 @@ struct glyph_variations_t for (tuple_variations_t& vars: glyph_variations) if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, true, /* use shared points*/ - &shared_tuples_idx_map)) + true, + &shared_tuples_idx_map, + &pool)) return false; return true; @@ -151,20 +177,21 @@ struct glyph_variations_t { /* key is pointer to compiled_peak_coords inside each tuple, hashing * function will always deref pointers first */ - hb_hashmap_t*, unsigned> coords_count_map; + hb_hashmap_t*, unsigned> coords_count_map; /* count the num of shared coords */ for (tuple_variations_t& vars: glyph_variations) { for (tuple_delta_t& var : vars.tuple_vars) { - if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map)) + if (!var.compile_coords (axes_index_map, axes_old_index_tag_map, &pool)) return false; - unsigned* count; - if (coords_count_map.has (&(var.compiled_peak_coords), &count)) - coords_count_map.set (&(var.compiled_peak_coords), *count + 1); + unsigned *count; + unsigned hash = hb_hash (&var.compiled_peak_coords); + if (coords_count_map.has_with_hash (&(var.compiled_peak_coords), hash, &count)) + (*count)++; else - coords_count_map.set (&(var.compiled_peak_coords), 1); + coords_count_map.set_with_hash (&(var.compiled_peak_coords), hash, 1); } } @@ -172,66 +199,45 @@ struct glyph_variations_t return false; /* add only those coords that are used more than once into the vector and sort */ - hb_vector_t*> shared_coords; - if (unlikely (!shared_coords.alloc (coords_count_map.get_population ()))) - return false; - - for (const auto _ : coords_count_map.iter ()) - { - if (_.second == 1) continue; - shared_coords.push (_.first); - } + hb_vector_t*, unsigned>> shared_coords { + + hb_iter (coords_count_map) + | hb_filter ([] (const hb_pair_t*, unsigned>& p) { return p.second > 1; }) + }; + if (unlikely (shared_coords.in_error ())) return false; /* no shared tuples: no coords are used more than once */ if (!shared_coords) return true; /* sorting based on the coords frequency first (high to low), then compare * the coords bytes */ - hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t*), _cmp_coords, (void *) (&coords_count_map)); + shared_coords.qsort (_cmp_coords); /* build shared_coords->idx map and shared tuples byte array */ shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length); - unsigned len = shared_tuples_count * (shared_coords[0]->length); + unsigned len = shared_tuples_count * (shared_coords[0].first->length); if (unlikely (!compiled_shared_tuples.alloc (len))) return false; for (unsigned i = 0; i < shared_tuples_count; i++) { - shared_tuples_idx_map.set (shared_coords[i], i); + shared_tuples_idx_map.set (shared_coords[i].first, i); /* add a concat() in hb_vector_t? */ - for (char c : shared_coords[i]->iter ()) + for (auto c : shared_coords[i].first->iter ()) compiled_shared_tuples.push (c); } return true; } - static int _cmp_coords (const void *pa, const void *pb, void *arg) + static int _cmp_coords (const void *pa, const void *pb) { - const hb_hashmap_t*, unsigned>* coords_count_map = - reinterpret_cast*, unsigned>*> (arg); + const hb_pair_t *, unsigned> *a = (const hb_pair_t *, unsigned> *) pa; + const hb_pair_t *, unsigned> *b = (const hb_pair_t *, unsigned> *) pb; - /* shared_coords is hb_vector_t*> so casting pa/pb - * to be a pointer to a pointer */ - const hb_vector_t** a = reinterpret_cast**> (const_cast(pa)); - const hb_vector_t** b = reinterpret_cast**> (const_cast(pb)); + if (a->second != b->second) + return b->second - a->second; // high to low - bool has_a = coords_count_map->has (*a); - bool has_b = coords_count_map->has (*b); - - if (has_a && has_b) - { - unsigned a_num = coords_count_map->get (*a); - unsigned b_num = coords_count_map->get (*b); - - if (a_num != b_num) - return b_num - a_num; - - return (*b)->as_array().cmp ((*a)->as_array ()); - } - else if (has_a) return -1; - else if (has_b) return 1; - else return 0; + return b->first->as_array().cmp (a->first->as_array ()); } templatestart_embed (); + GlyphVariationData* cur_glyph = c->start_embed (); if (!cur_glyph) return_trace (false); for (auto &_ : it) { @@ -272,7 +278,7 @@ struct glyph_variations_t if (idx >= glyph_variations.length) return_trace (false); if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false); - TupleVariationData* next_glyph = c->start_embed (); + GlyphVariationData* next_glyph = c->start_embed (); glyph_offset += (char *) next_glyph - (char *) cur_glyph; if (long_offset) @@ -295,9 +301,14 @@ struct glyph_variations_t } }; -struct gvar +template +struct gvar_GVAR { - static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar; + static constexpr hb_tag_t tableTag = TableTag; + + using GlyphVariationData = TupleVariationData; + + bool has_data () const { return version.to_int () != 0; } bool sanitize_shallow (hb_sanitize_context_t *c) const { @@ -316,7 +327,7 @@ struct gvar { return sanitize_shallow (c); } bool decompile_glyph_variations (hb_subset_context_t *c, - glyph_variations_t& glyph_vars /* OUT */) const + glyph_variations_t& glyph_vars /* OUT */) const { hb_hashmap_t new_gid_var_data_map; auto it = hb_iter (c->plan->new_to_old_gid_list); @@ -343,14 +354,14 @@ struct gvar template bool serialize (hb_serialize_context_t *c, - const glyph_variations_t& glyph_vars, + const glyph_variations_t& glyph_vars, Iterator it, unsigned axis_count, unsigned num_glyphs, bool force_long_offsets) const { TRACE_SERIALIZE (this); - gvar *out = c->allocate_min (); + gvar_GVAR *out = c->allocate_min (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -376,9 +387,9 @@ struct gvar out->sharedTuples = 0; else { - hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); + hb_array_t shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); if (!shared_tuples.arrayZ) return_trace (false); - out->sharedTuples = shared_tuples.arrayZ - (char *) out; + out->sharedTuples = (const char *) shared_tuples.arrayZ - (char *) out; } char *glyph_var_data = c->start_embed (); @@ -392,7 +403,7 @@ struct gvar bool instantiate (hb_subset_context_t *c) const { TRACE_SUBSET (this); - glyph_variations_t glyph_vars; + glyph_variations_t glyph_vars; if (!decompile_glyph_variations (c, glyph_vars)) return_trace (false); @@ -422,7 +433,7 @@ struct gvar unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; - gvar *out = c->serializer->allocate_min (); + gvar_GVAR *out = c->serializer->allocate_min (); if (unlikely (!out)) return_trace (false); out->version.major = 1; @@ -437,10 +448,18 @@ struct gvar if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) it++; unsigned int subset_data_size = 0; + unsigned padding_size = 0; for (auto &_ : it) { hb_codepoint_t old_gid = _.second; - subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; + unsigned glyph_data_size = get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length; + if (glyph_data_size % 2) + { + glyph_data_size++; + padding_size++; + } + + subset_data_size += glyph_data_size; } /* According to the spec: If the short format (Offset16) is used for offsets, @@ -469,6 +488,8 @@ struct gvar /* This ordering relative to the shared tuples array, which puts the glyphVariationData last in the table, is required when HB_SUBSET_FLAGS_IFTB_REQUIREMENTS is set */ + if (long_offset) + subset_data_size -= padding_size; char *subset_data = c->serializer->allocate_size (subset_data_size, false); if (!subset_data) return_trace (false); out->dataZ = subset_data - (char *) out; @@ -507,8 +528,16 @@ struct gvar old_gid); hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length); - subset_data += var_data_bytes.length; - glyph_offset += var_data_bytes.length; + unsigned glyph_data_size = var_data_bytes.length; + subset_data += glyph_data_size; + glyph_offset += glyph_data_size; + + if (!long_offset && (glyph_data_size % 2)) + { + *subset_data = 0; + subset_data++; + glyph_offset++; + } if (long_offset) ((HBUINT32 *) subset_offsets)[gid] = glyph_offset; @@ -556,41 +585,24 @@ struct gvar public: struct accelerator_t { + + hb_scalar_cache_t *create_cache () const + { + return hb_scalar_cache_t::create (table->sharedTupleCount); + } + + static void destroy_cache (hb_scalar_cache_t *cache) + { + hb_scalar_cache_t::destroy (cache); + } + + bool has_data () const { return table->has_data (); } + accelerator_t (hb_face_t *face) { - table = hb_sanitize_context_t ().reference_table (face); + table = hb_sanitize_context_t ().reference_table (face); /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; - - /* For shared tuples that only have one axis active, shared the index of - * that axis as a cache. This will speed up caclulate_scalar() a lot - * for fonts with lots of axes and many "monovar" tuples. */ - hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); - unsigned count = table->sharedTupleCount; - if (unlikely (!shared_tuple_active_idx.resize (count, false))) return; - unsigned axis_count = table->axisCount; - for (unsigned i = 0; i < count; i++) - { - hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count); - int idx1 = -1, idx2 = -1; - for (unsigned j = 0; j < axis_count; j++) - { - const F2DOT14 &peak = tuple.arrayZ[j]; - if (peak.to_int () != 0) - { - if (idx1 == -1) - idx1 = j; - else if (idx2 == -1) - idx2 = j; - else - { - idx1 = idx2 = -1; - break; - } - } - } - shared_tuple_active_idx.arrayZ[i] = {idx1, idx2}; - } } ~accelerator_t () { table.destroy (); } @@ -622,46 +634,148 @@ struct gvar static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end) { return (i >= end) ? start : (i + 1); } +#ifndef HB_OPTIMIZE_SIZE + template +#endif + static bool decompile_deltas_add_to_points (const HBUINT8 *&p /* IN/OUT */, + hb_array_t points, + float scalar, + const HBUINT8 *end, + unsigned start +#ifdef HB_OPTIMIZE_SIZE + , bool is_x +#endif + ) + { + unsigned i = 0; + unsigned count = points.length; + while (i < count) + { + if (unlikely (p + 1 > end)) return false; + unsigned control = *p++; + unsigned run_count = (control & TupleValues::VALUE_RUN_COUNT_MASK) + 1; + unsigned stop = i + run_count; + if (unlikely (stop > count)) return false; + + unsigned skip = i < start ? hb_min (start - i, run_count) : 0; + i += skip; + + switch (control & TupleValues::VALUES_SIZE_MASK) + { + case TupleValues::VALUES_ARE_ZEROS: + i = stop; + break; + case TupleValues::VALUES_ARE_WORDS: + { + if (unlikely (p + run_count * HBINT16::static_size > end)) return false; + p += skip * HBINT16::static_size; + const auto *pp = (const HBINT16 *) p; + for (; i < stop; i++) + { + float v = *pp++ * scalar; + if (is_x) points.arrayZ[i].x += v; + else points.arrayZ[i].y += v; + } + p = (const HBUINT8 *) pp; + } + break; + case TupleValues::VALUES_ARE_LONGS: + { + if (unlikely (p + run_count * HBINT32::static_size > end)) return false; + p += skip * HBINT32::static_size; + const auto *pp = (const HBINT32 *) p; + for (; i < stop; i++) + { + float v = *pp++ * scalar; + if (is_x) points.arrayZ[i].x += v; + else points.arrayZ[i].y += v; + } + p = (const HBUINT8 *) pp; + } + break; + case TupleValues::VALUES_ARE_BYTES: + { + if (unlikely (p + run_count > end)) return false; + p += skip * HBINT8::static_size; + const auto *pp = (const HBINT8 *) p; + for (; i < stop; i++) + { + float v = *pp++ * scalar; + if (is_x) points.arrayZ[i].x += v; + else points.arrayZ[i].y += v; + } + p = (const HBUINT8 *) pp; + } + break; + } + } + return true; + } public: bool apply_deltas_to_points (hb_codepoint_t glyph, hb_array_t coords, const hb_array_t points, + hb_glyf_scratch_t &scratch, + hb_scalar_cache_t *gvar_cache = nullptr, bool phantom_only = false) const { if (unlikely (glyph >= glyphCount)) return true; hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph); if (!var_data_bytes.as ()->has_data ()) return true; - hb_vector_t shared_indices; - GlyphVariationData::tuple_iterator_t iterator; + + auto &shared_indices = scratch.shared_indices; + shared_indices.clear (); + + typename GlyphVariationData::tuple_iterator_t iterator; if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount, var_data_bytes.arrayZ, shared_indices, &iterator)) return true; /* so isn't applied at all */ + bool any_private_points = false; + bool private_points_checked = false; + /* Save original points for inferred delta calculation */ - contour_point_vector_t orig_points_vec; // Populated lazily + auto &orig_points_vec = scratch.orig_points; + orig_points_vec.clear (); // Populated lazily auto orig_points = orig_points_vec.as_array (); /* flag is used to indicate referenced point */ - contour_point_vector_t deltas_vec; // Populated lazily + auto &deltas_vec = scratch.deltas; + deltas_vec.clear (); // Populated lazily auto deltas = deltas_vec.as_array (); - hb_vector_t end_points; // Populated lazily - unsigned num_coords = table->axisCount; hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords); - hb_vector_t private_indices; - hb_vector_t x_deltas; - hb_vector_t y_deltas; + auto &private_indices = scratch.private_indices; + auto &x_deltas = scratch.x_deltas; + auto &y_deltas = scratch.y_deltas; + unsigned count = points.length; bool flush = false; + do { float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples, - &shared_tuple_active_idx); + gvar_cache); + if (scalar == 0.f) continue; + + if (!private_points_checked) + { + auto scan = iterator; + do + { + if (scan.current_tuple->has_private_points ()) + { + any_private_points = true; + break; + } + } while (scan.move_to_next ()); + private_points_checked = true; + } const HBUINT8 *p = iterator.get_serialized_data (); unsigned int length = iterator.current_tuple->get_data_size (); if (unlikely (!iterator.var_data_bytes.check_range (p, length))) @@ -669,7 +783,7 @@ struct gvar if (!deltas) { - if (unlikely (!deltas_vec.resize (count, false))) return false; + if (unlikely (!deltas_vec.resize_dirty (count))) return false; deltas = deltas_vec.as_array (); hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, (phantom_only ? 4 : count) * sizeof (deltas[0])); @@ -684,11 +798,25 @@ struct gvar const hb_array_t &indices = has_private_points ? private_indices : shared_indices; bool apply_to_all = (indices.length == 0); - unsigned int num_deltas = apply_to_all ? points.length : indices.length; - if (unlikely (!x_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end))) return false; - if (unlikely (!y_deltas.resize (num_deltas, false))) return false; - if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end))) return false; + unsigned num_deltas = apply_to_all ? points.length : indices.length; + unsigned start_deltas = (apply_to_all && phantom_only && num_deltas >= 4 ? num_deltas - 4 : 0); + + if (apply_to_all && !any_private_points) + { +#ifdef HB_OPTIMIZE_SIZE + if (unlikely (!decompile_deltas_add_to_points (p, points, scalar, end, start_deltas, true))) return false; + if (unlikely (!decompile_deltas_add_to_points (p, points, scalar, end, start_deltas, false))) return false; +#else + if (unlikely (!decompile_deltas_add_to_points (p, points, scalar, end, start_deltas))) return false; + if (unlikely (!decompile_deltas_add_to_points (p, points, scalar, end, start_deltas))) return false; +#endif + continue; + } + + if (unlikely (!x_deltas.resize_dirty (num_deltas))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, x_deltas, end, false, start_deltas))) return false; + if (unlikely (!y_deltas.resize_dirty (num_deltas))) return false; + if (unlikely (!GlyphVariationData::decompile_deltas (p, y_deltas, end, false, start_deltas))) return false; if (!apply_to_all) { @@ -703,8 +831,6 @@ struct gvar { for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) points.arrayZ[i].translate (deltas.arrayZ[i]); - flush = false; - } hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0, (phantom_only ? 4 : count) * sizeof (deltas[0])); @@ -725,8 +851,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -737,10 +863,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -750,8 +875,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i] * scalar; - delta.y += y_deltas.arrayZ[i] * scalar; + delta.add_delta (x_deltas.arrayZ[i] * scalar, + y_deltas.arrayZ[i] * scalar); } } else @@ -759,10 +884,9 @@ struct gvar if (apply_to_all) for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++) { - unsigned int pt_index = i; - auto &delta = deltas.arrayZ[pt_index]; - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + auto &delta = deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } else for (unsigned int i = 0; i < num_deltas; i++) @@ -772,8 +896,8 @@ struct gvar if (phantom_only && pt_index < count - 4) continue; auto &delta = deltas.arrayZ[pt_index]; delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */ - delta.x += x_deltas.arrayZ[i]; - delta.y += y_deltas.arrayZ[i]; + delta.add_delta (x_deltas.arrayZ[i], + y_deltas.arrayZ[i]); } } } @@ -781,17 +905,14 @@ struct gvar /* infer deltas for unreferenced points */ if (!apply_to_all && !phantom_only) { - if (!end_points) - { - for (unsigned i = 0; i < count; ++i) - if (points.arrayZ[i].is_end_point) - end_points.push (i); - if (unlikely (end_points.in_error ())) return false; - } - unsigned start_point = 0; - for (unsigned end_point : end_points) + unsigned end_point = 0; + while (true) { + while (end_point < count && !points.arrayZ[end_point].is_end_point) + end_point++; + if (unlikely (end_point == count)) break; + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ unsigned unref_count = 0; for (unsigned i = start_point; i < end_point + 1; i++) @@ -834,7 +955,7 @@ struct gvar } } no_more_gaps: - start_point = end_point + 1; + start_point = end_point = end_point + 1; } } @@ -854,9 +975,8 @@ struct gvar unsigned int get_axis_count () const { return table->axisCount; } private: - hb_blob_ptr_t table; + hb_blob_ptr_t table; unsigned glyphCount; - hb_vector_t> shared_tuple_active_idx; }; protected: @@ -872,7 +992,7 @@ struct gvar NNOffset32To> sharedTuples; /* Offset from the start of this table to the shared tuple records. * Array of tuple records shared across all glyph variation data tables. */ - HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of + GidOffsetType glyphCountX; /* The number of glyphs in this font. This must match the number of * glyphs stored elsewhere in the font. */ HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the @@ -887,9 +1007,15 @@ struct gvar DEFINE_SIZE_ARRAY (20, offsetZ); }; +using gvar = gvar_GVAR; +using GVAR = gvar_GVAR; + struct gvar_accelerator_t : gvar::accelerator_t { gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {} }; +struct GVAR_accelerator_t : GVAR::accelerator_t { + GVAR_accelerator_t (hb_face_t *face) : GVAR::accelerator_t (face) {} +}; } /* namespace OT */ diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-var-hvar-table.hh index 33a4e1a40..ce1f9dcba 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-var-hvar-table.hh @@ -42,57 +42,62 @@ struct index_map_subset_plan_t VORG_INDEX }; - void init (const DeltaSetIndexMap &index_map, + void init (const DeltaSetIndexMap *index_map, hb_inc_bimap_t &outer_map, hb_vector_t &inner_sets, const hb_subset_plan_t *plan, bool bypass_empty = true) { map_count = 0; - outer_bit_count = 0; - inner_bit_count = 1; max_inners.init (); output_map.init (); - if (bypass_empty && !index_map.get_map_count ()) return; + if (bypass_empty && (!index_map || !index_map->get_map_count ())) return; unsigned int last_val = (unsigned int)-1; hb_codepoint_t last_gid = HB_CODEPOINT_INVALID; - outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); max_inners.resize (inner_sets.length); for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; /* Search backwards for a map value different from the last map value */ auto &new_to_old_gid_list = plan->new_to_old_gid_list; unsigned count = new_to_old_gid_list.length; - for (unsigned j = count; j; j--) + if (!index_map) { - hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; - hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; - - unsigned int v = index_map.map (old_gid); - if (last_gid == HB_CODEPOINT_INVALID) + map_count = new_to_old_gid_list.tail ().first + 1; + } + else + { + for (unsigned j = count; j; j--) { - last_val = v; - last_gid = gid; - continue; + hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first; + hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second; + + unsigned int v = index_map->map (old_gid); + if (last_gid == HB_CODEPOINT_INVALID) + { + last_val = v; + last_gid = gid; + continue; + } + if (v != last_val) + break; + + last_gid = gid; } - if (v != last_val) - break; - - last_gid = gid; + + if (unlikely (last_gid == (hb_codepoint_t)-1)) return; + map_count = last_gid + 1; } - if (unlikely (last_gid == (hb_codepoint_t)-1)) return; - map_count = last_gid + 1; for (auto _ : plan->new_to_old_gid_list) { hb_codepoint_t gid = _.first; if (gid >= map_count) break; hb_codepoint_t old_gid = _.second; - unsigned int v = index_map.map (old_gid); + unsigned int v = index_map ? index_map->map (old_gid): old_gid; unsigned int outer = v >> 16; unsigned int inner = v & 0xFFFF; outer_map.add (outer); @@ -113,6 +118,9 @@ struct index_map_subset_plan_t const hb_vector_t &inner_maps, const hb_subset_plan_t *plan) { + outer_bit_count = 1; + inner_bit_count = 1; + for (unsigned int i = 0; i < max_inners.length; i++) { if (inner_maps[i].get_population () == 0) continue; @@ -128,9 +136,13 @@ struct index_map_subset_plan_t if (unlikely (new_gid >= map_count)) break; - uint32_t v = input_map->map (old_gid); - unsigned int outer = v >> 16; - output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); + uint32_t v = input_map? input_map->map (old_gid) : old_gid; + unsigned outer = v >> 16; + unsigned new_outer = outer_map[outer]; + unsigned bit_count = (new_outer == 0) ? 1 : hb_bit_storage (new_outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + output_map.arrayZ[new_gid] = (new_outer << 16) | (inner_maps[outer][v & 0xFFFF]); } } @@ -156,7 +168,7 @@ struct index_map_subset_plan_t unsigned outer = (*new_varidx) >> 16; unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer); outer_bit_count = hb_max (bit_count, outer_bit_count); - + unsigned inner = (*new_varidx) & 0xFFFF; bit_count = (inner == 0) ? 1 : hb_bit_storage (inner); inner_bit_count = hb_max (bit_count, inner_bit_count); @@ -204,8 +216,8 @@ struct hvarvvar_subset_plan_t if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return; bool retain_adv_map = false; - index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false); - if (index_maps[0] == &Null (DeltaSetIndexMap)) + index_map_plans[0].init (index_maps[0], outer_map, inner_sets, plan, false); + if (!index_maps[0]) { retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; outer_map.add (0); @@ -215,7 +227,7 @@ struct hvarvvar_subset_plan_t } for (unsigned int i = 1; i < index_maps.length; i++) - index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan); + index_map_plans[i].init (index_maps[i], outer_map, inner_sets, plan); outer_map.sort (); @@ -284,6 +296,8 @@ struct HVARVVAR static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; + bool has_data () const { return version.major != 0; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -301,9 +315,14 @@ struct HVARVVAR void listup_index_maps (hb_vector_t &index_maps) const { - index_maps.push (&(this+advMap)); - index_maps.push (&(this+lsbMap)); - index_maps.push (&(this+rsbMap)); + if (advMap) index_maps.push (&(this+advMap)); + else index_maps.push (nullptr); + + if (lsbMap) index_maps.push (&(this+lsbMap)); + else index_maps.push (nullptr); + + if (rsbMap) index_maps.push (&(this+rsbMap)); + else index_maps.push (nullptr); } bool serialize_index_maps (hb_serialize_context_t *c, @@ -382,9 +401,10 @@ struct HVARVVAR hvar_plan.index_map_plans.as_array ())); } + HB_ALWAYS_INLINE float get_advance_delta_unscaled (hb_codepoint_t glyph, const int *coords, unsigned int coord_count, - ItemVariationStore::cache_t *store_cache = nullptr) const + hb_scalar_cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, @@ -392,16 +412,6 @@ struct HVARVVAR store_cache); } - bool get_lsb_delta_unscaled (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - float *lsb) const - { - if (!lsbMap) return false; - uint32_t varidx = (this+lsbMap).map (glyph); - *lsb = (this+varStore).get_delta (varidx, coords, coord_count); - return true; - } - public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ @@ -435,7 +445,8 @@ struct VVAR : HVARVVAR { void listup_index_maps (hb_vector_t &index_maps) const { HVARVVAR::listup_index_maps (index_maps); - index_maps.push (&(this+vorgMap)); + if (vorgMap) index_maps.push (&(this+vorgMap)); + else index_maps.push (nullptr); } bool serialize_index_maps (hb_serialize_context_t *c, @@ -454,14 +465,16 @@ struct VVAR : HVARVVAR { bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset (c); } - bool get_vorg_delta_unscaled (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count, - float *delta) const + HB_ALWAYS_INLINE + float get_vorg_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + hb_scalar_cache_t *store_cache = nullptr) const { - if (!vorgMap) return false; + if (!vorgMap) return 0.f; uint32_t varidx = (this+vorgMap).map (glyph); - *delta = (this+varStore).get_delta (varidx, coords, coord_count); - return true; + return (this+varStore).get_delta (varidx, + coords, coord_count, + store_cache); } protected: diff --git a/thirdparty/harfbuzz/upstream/hb-ot-var.cc b/thirdparty/harfbuzz/upstream/hb-ot-var.cc index f000f2726..72ef9fbbd 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-var.cc +++ b/thirdparty/harfbuzz/upstream/hb-ot-var.cc @@ -70,7 +70,7 @@ hb_ot_var_has_data (hb_face_t *face) * hb_ot_var_get_axis_count: * @face: The #hb_face_t to work on * - * Fetches the number of OpenType variation axes included in the face. + * Fetches the number of OpenType variation axes included in the face. * * Return value: the number of variation axes defined * @@ -117,7 +117,7 @@ hb_ot_var_get_axes (hb_face_t *face, * in the specified face. * * Since: 1.4.2 - * Deprecated: 2.2.0 - use hb_ot_var_find_axis_info() instead + * Deprecated: 2.2.0: use hb_ot_var_find_axis_info() instead **/ hb_bool_t hb_ot_var_find_axis (hb_face_t *face, @@ -183,7 +183,7 @@ hb_ot_var_find_axis_info (hb_face_t *face, * hb_ot_var_get_named_instance_count: * @face: The #hb_face_t to work on * - * Fetches the number of named instances included in the face. + * Fetches the number of named instances included in the face. * * Return value: the number of named instances defined * @@ -263,7 +263,7 @@ hb_ot_var_named_instance_get_design_coords (hb_face_t *face, * @face: The #hb_face_t to work on * @variations: The array of variations to normalize * @variations_length: The number of variations to normalize - * @coords: (out) (array length=coords_length): The array of normalized coordinates + * @coords: (out) (array length=coords_length): The array of normalized coordinates * @coords_length: The length of the coordinate array * * Normalizes all of the coordinates in the given list of variation axes. @@ -286,10 +286,14 @@ hb_ot_var_normalize_variations (hb_face_t *face, hb_ot_var_axis_info_t info; if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && info.axis_index < coords_length) - coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); + coords[info.axis_index] = roundf (fvar.normalize_axis_value (info.axis_index, variations[i].value) * 65536.0f); } - face->table.avar->map_coords (coords, coords_length); + face->table.avar->map_coords_16_16 (coords, coords_length); + + // Round to 2.14 + for (unsigned i = 0; i < coords_length; i++) + coords[i] = (coords[i] + 2) >> 2; } /** @@ -309,6 +313,10 @@ hb_ot_var_normalize_variations (hb_face_t *face, * Any additional scaling defined in the face's `avar` table is also * applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar * + * Note: @coords_length must be the same as the number of axes in the face, as + * for example returned by hb_ot_var_get_axis_count(). + * Otherwise, the behavior is undefined. + * * Since: 1.4.2 **/ void @@ -319,9 +327,13 @@ hb_ot_var_normalize_coords (hb_face_t *face, { const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < coords_length; i++) - normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); + normalized_coords[i] = roundf (fvar.normalize_axis_value (i, design_coords[i]) * 65536.0f); + + face->table.avar->map_coords_16_16 (normalized_coords, coords_length); - face->table.avar->map_coords (normalized_coords, coords_length); + // Round to 2.14 + for (unsigned i = 0; i < coords_length; i++) + normalized_coords[i] = (normalized_coords[i] + 2) >> 2; } diff --git a/thirdparty/harfbuzz/upstream/hb-ot-vorg-table.hh b/thirdparty/harfbuzz/upstream/hb-ot-vorg-table.hh index 95ae8ef55..1ba9ca269 100644 --- a/thirdparty/harfbuzz/upstream/hb-ot-vorg-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ot-vorg-table.hh @@ -61,6 +61,7 @@ struct VORG bool has_data () const { return version.to_int (); } + HB_ALWAYS_INLINE int get_y_origin (hb_codepoint_t glyph) const { unsigned int i; diff --git a/thirdparty/harfbuzz/upstream/hb-outline.cc b/thirdparty/harfbuzz/upstream/hb-outline.cc index 29b1f530d..75ee3041a 100644 --- a/thirdparty/harfbuzz/upstream/hb-outline.cc +++ b/thirdparty/harfbuzz/upstream/hb-outline.cc @@ -84,6 +84,21 @@ void hb_outline_t::replay (hb_draw_funcs_t *pen, void *pen_data) const } } +void hb_outline_t::translate (float dx, float dy) +{ + for (auto &p : points) + { + p.x += dx; + p.y += dy; + } +} + +void hb_outline_t::slant (float slant_xy) +{ + for (auto &p : points) + p.x += slant_xy * p.y; +} + float hb_outline_t::control_area () const { float a = 0; diff --git a/thirdparty/harfbuzz/upstream/hb-outline.hh b/thirdparty/harfbuzz/upstream/hb-outline.hh index c43c06596..ed1057b8a 100644 --- a/thirdparty/harfbuzz/upstream/hb-outline.hh +++ b/thirdparty/harfbuzz/upstream/hb-outline.hh @@ -69,6 +69,8 @@ struct hb_outline_t HB_INTERNAL void replay (hb_draw_funcs_t *pen, void *pen_data) const; HB_INTERNAL float control_area () const; + HB_INTERNAL void translate (float dx, float dy); + HB_INTERNAL void slant (float slant_xy); HB_INTERNAL void embolden (float x_strength, float y_strength, float x_shift, float y_shift); diff --git a/thirdparty/harfbuzz/upstream/hb-paint-bounded.cc b/thirdparty/harfbuzz/upstream/hb-paint-bounded.cc new file mode 100644 index 000000000..ca1b61615 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-paint-bounded.cc @@ -0,0 +1,207 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb.hh" + +#ifndef HB_NO_PAINT + +#include "hb-paint-bounded.hh" + +#include "hb-machinery.hh" + + +/* + * This file implements boundedness computation of COLRv1 fonts as described in: + * + * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness + */ + +static void +hb_paint_bounded_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_clip (); +} + +static void +hb_paint_bounded_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + float xmin, float ymin, float xmax, float ymax, + void *user_data) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_clip (); +} + +static void +hb_paint_bounded_pop_clip (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->pop_clip (); +} + +static void +hb_paint_bounded_push_group (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_group (); +} + +static void +hb_paint_bounded_pop_group (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->pop_group (mode); +} + +static hb_bool_t +hb_paint_bounded_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_blob_t *blob HB_UNUSED, + unsigned int width HB_UNUSED, + unsigned int height HB_UNUSED, + hb_tag_t format HB_UNUSED, + float slant HB_UNUSED, + hb_glyph_extents_t *glyph_extents, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->push_clip (); + c->paint (); + c->pop_clip (); + + return true; +} + +static void +hb_paint_bounded_paint_color (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_bool_t use_foreground HB_UNUSED, + hb_color_t color HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static void +hb_paint_bounded_paint_linear_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, + float x1 HB_UNUSED, float y1 HB_UNUSED, + float x2 HB_UNUSED, float y2 HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static void +hb_paint_bounded_paint_radial_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float x0 HB_UNUSED, float y0 HB_UNUSED, float r0 HB_UNUSED, + float x1 HB_UNUSED, float y1 HB_UNUSED, float r1 HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static void +hb_paint_bounded_paint_sweep_gradient (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line HB_UNUSED, + float cx HB_UNUSED, float cy HB_UNUSED, + float start_angle HB_UNUSED, + float end_angle HB_UNUSED, + void *user_data HB_UNUSED) +{ + hb_paint_bounded_context_t *c = (hb_paint_bounded_context_t *) paint_data; + + c->paint (); +} + +static inline void free_static_paint_bounded_funcs (); + +static struct hb_paint_bounded_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t +{ + static hb_paint_funcs_t *create () + { + hb_paint_funcs_t *funcs = hb_paint_funcs_create (); + + hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_paint_bounded_push_clip_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_paint_bounded_push_clip_rectangle, nullptr, nullptr); + hb_paint_funcs_set_pop_clip_func (funcs, hb_paint_bounded_pop_clip, nullptr, nullptr); + hb_paint_funcs_set_push_group_func (funcs, hb_paint_bounded_push_group, nullptr, nullptr); + hb_paint_funcs_set_pop_group_func (funcs, hb_paint_bounded_pop_group, nullptr, nullptr); + hb_paint_funcs_set_color_func (funcs, hb_paint_bounded_paint_color, nullptr, nullptr); + hb_paint_funcs_set_image_func (funcs, hb_paint_bounded_paint_image, nullptr, nullptr); + hb_paint_funcs_set_linear_gradient_func (funcs, hb_paint_bounded_paint_linear_gradient, nullptr, nullptr); + hb_paint_funcs_set_radial_gradient_func (funcs, hb_paint_bounded_paint_radial_gradient, nullptr, nullptr); + hb_paint_funcs_set_sweep_gradient_func (funcs, hb_paint_bounded_paint_sweep_gradient, nullptr, nullptr); + + hb_paint_funcs_make_immutable (funcs); + + hb_atexit (free_static_paint_bounded_funcs); + + return funcs; + } +} static_paint_bounded_funcs; + +static inline +void free_static_paint_bounded_funcs () +{ + static_paint_bounded_funcs.free_instance (); +} + +hb_paint_funcs_t * +hb_paint_bounded_get_funcs () +{ + return static_paint_bounded_funcs.get_unconst (); +} + + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-paint-bounded.hh b/thirdparty/harfbuzz/upstream/hb-paint-bounded.hh new file mode 100644 index 000000000..2fbef3ada --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-paint-bounded.hh @@ -0,0 +1,117 @@ +/* + * Copyright © 2022 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_PAINT_BOUNDED_HH +#define HB_PAINT_BOUNDED_HH + +#include "hb.hh" +#include "hb-paint.h" + +#include "hb-geometry.hh" + + +typedef struct hb_paint_bounded_context_t hb_paint_bounded_context_t; + +struct hb_paint_bounded_context_t +{ + void clear () + { + clips = 0; + bounded = true; + groups.clear (); + } + + hb_paint_bounded_context_t () + { + clear (); + } + + bool is_bounded () + { + return bounded; + } + + void push_clip () + { + clips++; + } + + void pop_clip () + { + if (clips == 0) return; + clips--; + } + + void push_group () + { + groups.push (bounded); + bounded = true; + } + + void pop_group (hb_paint_composite_mode_t mode) + { + const bool src_bounded = bounded; + bounded = groups.pop (); + bool &backdrop_bounded = bounded; + + // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite + switch ((int) mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: + backdrop_bounded = true; + break; + case HB_PAINT_COMPOSITE_MODE_SRC: + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: + backdrop_bounded = src_bounded; + break; + case HB_PAINT_COMPOSITE_MODE_DEST: + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: + break; + case HB_PAINT_COMPOSITE_MODE_SRC_IN: + case HB_PAINT_COMPOSITE_MODE_DEST_IN: + backdrop_bounded = backdrop_bounded && src_bounded; + break; + default: + backdrop_bounded = backdrop_bounded || src_bounded; + break; + } + } + + void paint () + { + if (!clips) + bounded = false; + } + + protected: + bool bounded; // true if current drawing bounded + unsigned clips; // number of active clips + hb_vector_t groups; // true if group bounded +}; + +HB_INTERNAL hb_paint_funcs_t * +hb_paint_bounded_get_funcs (); + + +#endif /* HB_PAINT_BOUNDED_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-paint-extents.cc b/thirdparty/harfbuzz/upstream/hb-paint-extents.cc index 2393322b7..11339a76a 100644 --- a/thirdparty/harfbuzz/upstream/hb-paint-extents.cc +++ b/thirdparty/harfbuzz/upstream/hb-paint-extents.cc @@ -28,14 +28,13 @@ #include "hb-paint-extents.hh" -#include "hb-draw.h" +#include "hb-draw.hh" #include "hb-machinery.hh" /* - * This file implements bounds-extraction as well as boundedness - * computation of COLRv1 fonts as described in: + * This file implements bounds-extraction computation of COLRv1 fonts as described in: * * https://learn.microsoft.com/en-us/typography/opentype/spec/colr#glyph-metrics-and-boundedness */ @@ -50,7 +49,7 @@ hb_paint_extents_push_transform (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - c->push_transform (hb_transform_t {xx, yx, xy, yy, dx, dy}); + c->push_transform (hb_transform_t<> {xx, yx, xy, yy, dx, dy}); } static void @@ -63,93 +62,6 @@ hb_paint_extents_pop_transform (hb_paint_funcs_t *funcs HB_UNUSED, c->pop_transform (); } -static void -hb_draw_extents_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (to_x, to_y); -} - -static void -hb_draw_extents_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (to_x, to_y); -} - -static void -hb_draw_extents_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float control_x, float control_y, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (control_x, control_y); - extents->add_point (to_x, to_y); -} - -static void -hb_draw_extents_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, - void *data, - hb_draw_state_t *st, - float control1_x, float control1_y, - float control2_x, float control2_y, - float to_x, float to_y, - void *user_data HB_UNUSED) -{ - hb_extents_t *extents = (hb_extents_t *) data; - - extents->add_point (control1_x, control1_y); - extents->add_point (control2_x, control2_y); - extents->add_point (to_x, to_y); -} - -static inline void free_static_draw_extents_funcs (); - -static struct hb_draw_extents_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t -{ - static hb_draw_funcs_t *create () - { - hb_draw_funcs_t *funcs = hb_draw_funcs_create (); - - hb_draw_funcs_set_move_to_func (funcs, hb_draw_extents_move_to, nullptr, nullptr); - hb_draw_funcs_set_line_to_func (funcs, hb_draw_extents_line_to, nullptr, nullptr); - hb_draw_funcs_set_quadratic_to_func (funcs, hb_draw_extents_quadratic_to, nullptr, nullptr); - hb_draw_funcs_set_cubic_to_func (funcs, hb_draw_extents_cubic_to, nullptr, nullptr); - - hb_draw_funcs_make_immutable (funcs); - - hb_atexit (free_static_draw_extents_funcs); - - return funcs; - } -} static_draw_extents_funcs; - -static inline -void free_static_draw_extents_funcs () -{ - static_draw_extents_funcs.free_instance (); -} - -static hb_draw_funcs_t * -hb_draw_extents_get_funcs () -{ - return static_draw_extents_funcs.get_unconst (); -} - static void hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data, @@ -159,7 +71,7 @@ hb_paint_extents_push_clip_glyph (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents; + hb_extents_t<> extents; hb_draw_funcs_t *draw_extent_funcs = hb_draw_extents_get_funcs (); hb_font_draw_glyph (font, glyph, draw_extent_funcs, &extents); c->push_clip (extents); @@ -173,7 +85,7 @@ hb_paint_extents_push_clip_rectangle (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents = {xmin, ymin, xmax, ymax}; + hb_extents_t<> extents = {xmin, ymin, xmax, ymax}; c->push_clip (extents); } @@ -221,10 +133,13 @@ hb_paint_extents_paint_image (hb_paint_funcs_t *funcs HB_UNUSED, { hb_paint_extents_context_t *c = (hb_paint_extents_context_t *) paint_data; - hb_extents_t extents = {(float) glyph_extents->x_bearing, - (float) glyph_extents->y_bearing + glyph_extents->height, - (float) glyph_extents->x_bearing + glyph_extents->width, - (float) glyph_extents->y_bearing}; + if (!glyph_extents) + return false; // Happens with SVG images. + + hb_extents_t<> extents = {(float) glyph_extents->x_bearing, + (float) glyph_extents->y_bearing + glyph_extents->height, + (float) glyph_extents->x_bearing + glyph_extents->width, + (float) glyph_extents->y_bearing}; c->push_clip (extents); c->paint (); c->pop_clip (); diff --git a/thirdparty/harfbuzz/upstream/hb-paint-extents.hh b/thirdparty/harfbuzz/upstream/hb-paint-extents.hh index 2d4491e07..0e18e3f8a 100644 --- a/thirdparty/harfbuzz/upstream/hb-paint-extents.hh +++ b/thirdparty/harfbuzz/upstream/hb-paint-extents.hh @@ -35,26 +35,35 @@ typedef struct hb_paint_extents_context_t hb_paint_extents_context_t; struct hb_paint_extents_context_t { + void clear () + { + transforms.clear (); + clips.clear (); + groups.clear (); + + transforms.push (hb_transform_t<>{}); + clips.push (hb_bounds_t<>{hb_bounds_t<>::UNBOUNDED}); + groups.push (hb_bounds_t<>{hb_bounds_t<>::EMPTY}); + } + hb_paint_extents_context_t () { - transforms.push (hb_transform_t{}); - clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED}); - groups.push (hb_bounds_t{hb_bounds_t::EMPTY}); + clear (); } - hb_extents_t get_extents () + hb_extents_t<> get_extents () { return groups.tail().extents; } bool is_bounded () { - return groups.tail().status != hb_bounds_t::UNBOUNDED; + return groups.tail().status != hb_bounds_t<>::UNBOUNDED; } - void push_transform (const hb_transform_t &trans) + void push_transform (const hb_transform_t<> &trans) { - hb_transform_t t = transforms.tail (); + hb_transform_t<> t = transforms.tail (); t.multiply (trans); transforms.push (t); } @@ -64,13 +73,13 @@ struct hb_paint_extents_context_t transforms.pop (); } - void push_clip (hb_extents_t extents) + void push_clip (hb_extents_t<> extents) { /* Transform extents and push a new clip. */ - const hb_transform_t &t = transforms.tail (); + const hb_transform_t<> &t = transforms.tail (); t.transform_extents (extents); - auto bounds = hb_bounds_t {extents}; + auto bounds = hb_bounds_t<> {extents}; bounds.intersect (clips.tail ()); clips.push (bounds); @@ -83,19 +92,19 @@ struct hb_paint_extents_context_t void push_group () { - groups.push (hb_bounds_t {hb_bounds_t::EMPTY}); + groups.push (hb_bounds_t<> {hb_bounds_t<>::EMPTY}); } void pop_group (hb_paint_composite_mode_t mode) { - const hb_bounds_t src_bounds = groups.pop (); - hb_bounds_t &backdrop_bounds = groups.tail (); + const hb_bounds_t<> src_bounds = groups.pop (); + hb_bounds_t<> &backdrop_bounds = groups.tail (); // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#format-32-paintcomposite switch ((int) mode) { case HB_PAINT_COMPOSITE_MODE_CLEAR: - backdrop_bounds.status = hb_bounds_t::EMPTY; + backdrop_bounds.status = hb_bounds_t<>::EMPTY; break; case HB_PAINT_COMPOSITE_MODE_SRC: case HB_PAINT_COMPOSITE_MODE_SRC_OUT: @@ -116,16 +125,16 @@ struct hb_paint_extents_context_t void paint () { - const hb_bounds_t &clip = clips.tail (); - hb_bounds_t &group = groups.tail (); + const hb_bounds_t<> &clip = clips.tail (); + hb_bounds_t<> &group = groups.tail (); group.union_ (clip); } protected: - hb_vector_t transforms; - hb_vector_t clips; - hb_vector_t groups; + hb_vector_t> transforms; + hb_vector_t> clips; + hb_vector_t> groups; }; HB_INTERNAL hb_paint_funcs_t * diff --git a/thirdparty/harfbuzz/upstream/hb-paint.cc b/thirdparty/harfbuzz/upstream/hb-paint.cc index 8eb24eb28..ffdd3c3a5 100644 --- a/thirdparty/harfbuzz/upstream/hb-paint.cc +++ b/thirdparty/harfbuzz/upstream/hb-paint.cc @@ -87,7 +87,7 @@ hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, unsigned int width, unsigned int height, hb_tag_t format, - float slant_xy, + float slant_xy_deprecated, hb_glyph_extents_t *extents, void *user_data) { return false; } @@ -464,6 +464,42 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy); } +/** + * hb_paint_push_font_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @font: a font + * + * Push the transform reflecting the font's scale and slant + * settings onto the paint functions. + * + * Since: 11.0.0 + */ +void +hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font) +{ + funcs->push_font_transform (paint_data, font); +} + +/** + * hb_paint_push_inverse_font_transform: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @font: a font + * + * Push the inverse of the transform reflecting the font's + * scale and slant settings onto the paint functions. + * + * Since: 11.0.0 + */ +void +hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font) +{ + funcs->push_inverse_font_transform (paint_data, font); +} + /** * hb_paint_pop_transform: * @funcs: paint functions @@ -579,7 +615,7 @@ hb_paint_color (hb_paint_funcs_t *funcs, void *paint_data, * @width: width of the raster image in pixels, or 0 * @height: height of the raster image in pixels, or 0 * @format: the image format as a tag - * @slant: the synthetic slant ratio to be applied to the image during rendering + * @slant: Deprecated. set to 0.0 * @extents: (nullable): the extents of the glyph * * Perform a "image" paint operation. @@ -592,10 +628,10 @@ hb_paint_image (hb_paint_funcs_t *funcs, void *paint_data, unsigned int width, unsigned int height, hb_tag_t format, - float slant, + HB_UNUSED float slant, hb_glyph_extents_t *extents) { - funcs->image (paint_data, image, width, height, format, slant, extents); + funcs->image (paint_data, image, width, height, format, 0.f, extents); } /** @@ -646,7 +682,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, float x0, float y0, float r0, float x1, float y1, float r1) { - funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); + funcs->radial_gradient (paint_data, color_line, x0, y0, r0, x1, y1, r1); } /** @@ -706,14 +742,14 @@ hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, /** * hb_paint_custom_palette_color: - * @funcs: paint functions - * @paint_data: associated data passed by the caller - * @color_index: color index - * @color: (out): fetched color + * @funcs: paint functions. + * @paint_data: associated data passed by the caller. + * @color_index: color index to fetch. + * @color: (out): fetched color. * - * Gets the custom palette color for @color_index. + * Gets the custom palette override color for @color_index. * - * Return value: `true` if found, `false` otherwise + * Return value: `true` if a custom color is provided, `false` otherwise. * * Since: 7.0.0 */ diff --git a/thirdparty/harfbuzz/upstream/hb-paint.h b/thirdparty/harfbuzz/upstream/hb-paint.h index b0cd384e2..787118c46 100644 --- a/thirdparty/harfbuzz/upstream/hb-paint.h +++ b/thirdparty/harfbuzz/upstream/hb-paint.h @@ -146,7 +146,7 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, * * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index. * - * Return value: %true if the glyph was painted, %false otherwise. + * Return value: `true` if the glyph was painted, `false` otherwise. * * Since: 8.2.0 */ @@ -167,8 +167,10 @@ typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs, * A virtual method for the #hb_paint_funcs_t to clip * subsequent paint calls to the outline of a glyph. * - * The coordinates of the glyph outline are interpreted according - * to the current transform. + * The coordinates of the glyph outline are expected in the + * current @font scale (ie. the results of calling + * hb_font_draw_glyph() with @font). The outline is + * transformed by the current transform. * * This clip is applied in addition to the current clip, * and remains in effect until a matching call to @@ -281,7 +283,7 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @width: width of the raster image in pixels, or 0 * @height: height of the raster image in pixels, or 0 * @format: the image format as a tag - * @slant: the synthetic slant ratio to be applied to the image during rendering + * @slant: Deprecated. Always set to 0.0. * @extents: (nullable): glyph extents for desired rendering * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * @@ -682,23 +684,24 @@ typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs, /** * hb_paint_custom_palette_color_func_t: - * @funcs: paint functions object - * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() - * @color_index: the color index - * @color: (out): fetched color - * @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func() + * @funcs: paint functions object. + * @paint_data: data accompanying the paint functions in hb_font_paint_glyph(). + * @color_index: color index to fetch. + * @color: (out): fetched color. + * @user_data: user data pointer passed to hb_paint_funcs_set_custom_palette_color_func(). * - * A virtual method for the #hb_paint_funcs_t to fetch a color from the custom - * color palette. + * A virtual method for #hb_paint_funcs_t to fetch a custom palette override + * color for @color_index. * - * Custom palette colors override the colors from the fonts selected color - * palette. It is not necessary to override all palette entries; for entries - * that should be taken from the font palette, return `false`. + * Custom palette colors override colors from the font's selected color palette. + * It is not necessary to override all palette entries; return `false` for + * entries that should be taken from the font palette. * - * This function might get called multiple times, but the custom palette is - * expected to remain unchanged for duration of a hb_font_paint_glyph() call. + * This function might be called multiple times, but the custom palette is + * expected to remain unchanged for the duration of one + * hb_font_paint_glyph() call. * - * Return value: `true` if found, `false` otherwise + * Return value: `true` if a custom color is provided, `false` otherwise. * * Since: 7.0.0 */ @@ -932,12 +935,12 @@ hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs, /** * hb_paint_funcs_set_custom_palette_color_func: - * @funcs: A paint functions struct - * @func: (closure user_data) (destroy destroy) (scope notified): The custom-palette-color callback - * @user_data: Data to pass to @func - * @destroy: (nullable): Function to call when @user_data is no longer needed + * @funcs: a paint functions struct. + * @func: (closure user_data) (destroy destroy) (scope notified): custom-palette-color callback. + * @user_data: data to pass to @func. + * @destroy: (nullable): function to call when @user_data is no longer needed. * - * Sets the custom-palette-color callback on the paint functions struct. + * Sets the custom-palette-color callback on @funcs. * * Since: 7.0.0 */ @@ -956,6 +959,14 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, float xy, float yy, float dx, float dy); +HB_EXTERN void +hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font); + +HB_EXTERN void +hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data, + const hb_font_t *font); + HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); diff --git a/thirdparty/harfbuzz/upstream/hb-paint.hh b/thirdparty/harfbuzz/upstream/hb-paint.hh index 56b790dbe..bbeeb0319 100644 --- a/thirdparty/harfbuzz/upstream/hb-paint.hh +++ b/thirdparty/harfbuzz/upstream/hb-paint.hh @@ -28,6 +28,7 @@ #include "hb.hh" #include "hb-face.hh" #include "hb-font.hh" +#include "hb-geometry.hh" #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ @@ -72,7 +73,11 @@ struct hb_paint_funcs_t float xx, float yx, float xy, float yy, float dx, float dy) - { func.push_transform (this, paint_data, + { + // Handle -0.f to avoid -0.f == 0.f in the transform matrix. + if (dx == -0.f) dx = 0.f; + if (dy == -0.f) dy = 0.f; + func.push_transform (this, paint_data, xx, yx, xy, yy, dx, dy, !user_data ? nullptr : user_data->push_transform); } void pop_transform (void *paint_data) @@ -157,77 +162,84 @@ struct hb_paint_funcs_t /* Internal specializations. */ - void push_root_transform (void *paint_data, + void push_font_transform (void *paint_data, const hb_font_t *font) { float upem = font->face->get_upem (); int xscale = font->x_scale, yscale = font->y_scale; - float slant = font->slant_xy; push_transform (paint_data, - xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0); + xscale/upem, 0, + 0, yscale/upem, + 0, 0); } - void push_inverse_root_transform (void *paint_data, - hb_font_t *font) + void push_inverse_font_transform (void *paint_data, + const hb_font_t *font) { float upem = font->face->get_upem (); int xscale = font->x_scale ? font->x_scale : upem; int yscale = font->y_scale ? font->y_scale : upem; - float slant = font->slant_xy; push_transform (paint_data, - upem/xscale, 0, -slant * upem/xscale, upem/yscale, 0, 0); + upem/xscale, 0, + 0, upem/yscale, + 0, 0); } - HB_NODISCARD - bool push_translate (void *paint_data, - float dx, float dy) + void push_transform (void *paint_data, hb_transform_t t) { - if (!dx && !dy) - return false; + push_transform (paint_data, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0); + } + void push_translate (void *paint_data, + float dx, float dy) + { push_transform (paint_data, - 1.f, 0.f, 0.f, 1.f, dx, dy); - return true; + hb_transform_t::translation (dx, dy)); } - HB_NODISCARD - bool push_scale (void *paint_data, + void push_scale (void *paint_data, float sx, float sy) { - if (sx == 1.f && sy == 1.f) - return false; - push_transform (paint_data, - sx, 0.f, 0.f, sy, 0.f, 0.f); - return true; + hb_transform_t::scaling (sx, sy)); + } + void push_scale_around_center (void *paint_data, + float sx, float sy, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::scaling_around_center (sx, sy, cx, cy)); } - HB_NODISCARD - bool push_rotate (void *paint_data, + void push_rotate (void *paint_data, float a) { - if (!a) - return false; + push_transform (paint_data, + hb_transform_t::rotation (a * HB_PI)); + } - float cc = cosf (a * HB_PI); - float ss = sinf (a * HB_PI); - push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f); - return true; + void push_rotate_around_center (void *paint_data, + float a, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::rotation_around_center (a * HB_PI, cx, cy)); } - HB_NODISCARD - bool push_skew (void *paint_data, + void push_skew (void *paint_data, float sx, float sy) { - if (!sx && !sy) - return false; - - float x = tanf (-sx * HB_PI); - float y = tanf (+sy * HB_PI); - push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f); - return true; + push_transform (paint_data, + hb_transform_t::skewing (-sx * HB_PI, sy * HB_PI)); + } + void push_skew_around_center (void *paint_data, + float sx, float sy, + float cx, float cy) + { + push_transform (paint_data, + hb_transform_t::skewing_around_center (-sx * HB_PI, sy * HB_PI, cx, cy)); } }; DECLARE_NULL_INSTANCE (hb_paint_funcs_t); diff --git a/thirdparty/harfbuzz/upstream/hb-priority-queue.hh b/thirdparty/harfbuzz/upstream/hb-priority-queue.hh index 274d5df4c..753e86b8c 100644 --- a/thirdparty/harfbuzz/upstream/hb-priority-queue.hh +++ b/thirdparty/harfbuzz/upstream/hb-priority-queue.hh @@ -45,12 +45,22 @@ template struct hb_priority_queue_t { - private: + public: typedef hb_pair_t item_t; + + private: hb_vector_t heap; public: + hb_priority_queue_t () = default; + hb_priority_queue_t (hb_vector_t&& other) : heap (std::move (other)) + { + // Heapify the vector. + for (int i = (heap.length / 2) - 1; i >= 0; i--) + bubble_down (i); + } + void reset () { heap.resize (0); } bool in_error () const { return heap.in_error (); } diff --git a/thirdparty/harfbuzz/upstream/hb-raster-draw.cc b/thirdparty/harfbuzz/upstream/hb-raster-draw.cc new file mode 100644 index 000000000..ba11965af --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-draw.cc @@ -0,0 +1,1386 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-raster-image.hh" +#include "hb-geometry.hh" +#include "hb-machinery.hh" + +#if defined(__aarch64__) || defined(_M_ARM64) +#include +#define HB_RASTER_NEON 1 +#elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) +#include +#define HB_RASTER_SSE2 1 +#endif + + +/* Fixed-point precision for sub-pixel coordinates. + 8 bits = 24.8: 256 sub-pixel units per pixel. */ +#define HB_RASTER_PIXEL_BITS 8 +#define HB_RASTER_ONE_PIXEL (1 << HB_RASTER_PIXEL_BITS) +#define HB_RASTER_PIXEL_MASK (HB_RASTER_ONE_PIXEL - 1) +/* Full-coverage alpha = 2 * ONE_PIXEL^2 */ +#define HB_RASTER_FULL_COVERAGE (2 * HB_RASTER_ONE_PIXEL * HB_RASTER_ONE_PIXEL) +/* Flatness threshold for Bézier flattening: max deviation in pixels */ +#define HB_RASTER_FLAT_THRESH 0.25f + + +/* Normalized edge: yH > yL always */ +struct hb_raster_edge_t +{ + int32_t xL, yL; /* lower endpoint (fixed-point) */ + int32_t xH, yH; /* upper endpoint (fixed-point) */ + int64_t slope; /* dx/dy in 16.16 fixed point: ((int64_t)dx << 16) / dy */ + int32_t wind; /* +1 or -1 */ +}; + +/* hb_raster_draw_t — outline rasterizer */ +struct hb_raster_draw_t +{ + hb_object_header_t header; + + /* Configuration */ + hb_transform_t<> transform = {1, 0, 0, 1, 0, 0}; + float x_scale_factor = 1.f; + float y_scale_factor = 1.f; + hb_raster_extents_t fixed_extents = {}; + bool has_extents = false; + + /* Accumulated geometry */ + hb_vector_t edges; + + /* Scratch — reused across render() calls */ + hb_vector_t row_area; + hb_vector_t row_cover; + hb_vector_t> edge_buckets; + hb_vector_t active_edges; + + /* Recycled image for zero-malloc render */ + hb_raster_image_t *recycled_image = nullptr; +}; + +static HB_ALWAYS_INLINE void +hb_raster_draw_transform_point (const hb_raster_draw_t *draw, + float x, float y, + float &tx, float &ty) +{ + tx = x; ty = y; + draw->transform.transform_point (tx, ty); + tx /= draw->x_scale_factor; + ty /= draw->y_scale_factor; +} + + +/* hb_raster_draw_t */ + +/** + * hb_raster_draw_create_or_fail: + * + * Creates a new rasterizer object. + * + * Return value: (transfer full): + * A newly allocated #hb_raster_draw_t with a reference count of 1. The + * initial reference count should be released with hb_raster_draw_destroy() + * when you are done using the #hb_raster_draw_t, or `NULL` on + * allocation failure. + * + * Since: 13.0.0 + **/ +hb_raster_draw_t * +hb_raster_draw_create_or_fail (void) +{ + hb_raster_draw_t *draw = hb_object_create (); + return draw; +} + +/** + * hb_raster_draw_reference: (skip) + * @draw: a rasterizer + * + * Increases the reference count on @draw by one. + * + * This prevents @draw from being destroyed until a matching + * call to hb_raster_draw_destroy() is made. + * + * Return value: (transfer full): + * The referenced #hb_raster_draw_t. + * + * Since: 13.0.0 + **/ +hb_raster_draw_t * +hb_raster_draw_reference (hb_raster_draw_t *draw) +{ + return hb_object_reference (draw); +} + +/** + * hb_raster_draw_destroy: (skip) + * @draw: a rasterizer + * + * Decreases the reference count on @draw by one. When the + * reference count reaches zero, the rasterizer is freed. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_destroy (hb_raster_draw_t *draw) +{ + if (!hb_object_should_destroy (draw)) + return; + + hb_raster_image_destroy (draw->recycled_image); + hb_object_actually_destroy (draw); + hb_free (draw); +} + +/** + * hb_raster_draw_set_user_data: (skip) + * @draw: a rasterizer + * @key: the user-data key + * @data: a pointer to the user data + * @destroy: (nullable): a callback to call when @data is not needed anymore + * @replace: whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified rasterizer. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_draw_set_user_data (hb_raster_draw_t *draw, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (draw, key, data, destroy, replace); +} + +/** + * hb_raster_draw_get_user_data: (skip) + * @draw: a rasterizer + * @key: the user-data key + * + * Fetches the user-data associated with the specified key, + * attached to the specified rasterizer. + * + * Return value: (transfer none): + * A pointer to the user data + * + * Since: 13.0.0 + **/ +void * +hb_raster_draw_get_user_data (hb_raster_draw_t *draw, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (draw, key); +} + +/** + * hb_raster_draw_set_transform: + * @draw: a rasterizer + * @xx: xx component of the transform matrix + * @yx: yx component of the transform matrix + * @xy: xy component of the transform matrix + * @yy: yy component of the transform matrix + * @dx: x translation + * @dy: y translation + * + * Sets a 2×3 affine transform applied to all incoming draw + * coordinates before rasterization. The default is the identity. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_set_transform (hb_raster_draw_t *draw, + float xx, float yx, + float xy, float yy, + float dx, float dy) +{ + draw->transform = {xx, yx, xy, yy, dx, dy}; +} + +/** + * hb_raster_draw_set_scale_factor: + * @draw: a rasterizer + * @x_scale_factor: x-axis minification factor + * @y_scale_factor: y-axis minification factor + * + * Sets post-transform minification factors applied during rasterization. + * Factors larger than 1 shrink the output in pixels. The default is 1. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_set_scale_factor (hb_raster_draw_t *draw, + float x_scale_factor, + float y_scale_factor) +{ + draw->x_scale_factor = x_scale_factor > 0.f ? x_scale_factor : 1.f; + draw->y_scale_factor = y_scale_factor > 0.f ? y_scale_factor : 1.f; +} + +/** + * hb_raster_draw_get_scale_factor: + * @draw: a rasterizer + * @x_scale_factor: (out) (nullable): x-axis minification factor + * @y_scale_factor: (out) (nullable): y-axis minification factor + * + * Fetches the current post-transform minification factors. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_get_scale_factor (hb_raster_draw_t *draw, + float *x_scale_factor, + float *y_scale_factor) +{ + if (x_scale_factor) *x_scale_factor = draw->x_scale_factor; + if (y_scale_factor) *y_scale_factor = draw->y_scale_factor; +} + +/** + * hb_raster_draw_get_transform: + * @draw: a rasterizer + * @xx: (out) (nullable): xx component of the transform matrix + * @yx: (out) (nullable): yx component of the transform matrix + * @xy: (out) (nullable): xy component of the transform matrix + * @yy: (out) (nullable): yy component of the transform matrix + * @dx: (out) (nullable): x translation + * @dy: (out) (nullable): y translation + * + * Fetches the current affine transform of the rasterizer. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_get_transform (hb_raster_draw_t *draw, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy) +{ + if (xx) *xx = draw->transform.xx; + if (yx) *yx = draw->transform.yx; + if (xy) *xy = draw->transform.xy; + if (yy) *yy = draw->transform.yy; + if (dx) *dx = draw->transform.x0; + if (dy) *dy = draw->transform.y0; +} + +/** + * hb_raster_draw_set_extents: + * @draw: a rasterizer + * @extents: the desired output extents + * + * Overrides the output image extents for the next render. When set, + * hb_raster_draw_render() uses the given extents instead of + * auto-computing them from the accumulated geometry. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_set_extents (hb_raster_draw_t *draw, + const hb_raster_extents_t *extents) +{ + draw->fixed_extents = *extents; + draw->has_extents = true; +} + +/** + * hb_raster_draw_get_extents: + * @draw: a rasterizer + * @extents: (out) (nullable): where to write current extents + * + * Gets currently configured output extents. + * + * Return value: `true` if extents are set, `false` otherwise. + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_draw_get_extents (hb_raster_draw_t *draw, + hb_raster_extents_t *extents) +{ + if (!draw->has_extents) + return false; + + if (extents) + *extents = draw->fixed_extents; + return true; +} + +/** + * hb_raster_draw_set_glyph_extents: + * @draw: a rasterizer + * @glyph_extents: glyph extents from hb_font_get_glyph_extents() + * + * Transforms @glyph_extents with the rasterizer's current transform and + * sets the resulting pixel extents for the next render. + * + * This is equivalent to computing a transformed bounding box in pixel + * space and calling hb_raster_draw_set_extents(). + * + * Return value: `true` if transformed extents are non-empty and set; + * `false` otherwise. + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_draw_set_glyph_extents (hb_raster_draw_t *draw, + const hb_glyph_extents_t *glyph_extents) +{ + float x0 = (float) glyph_extents->x_bearing; + float y0 = (float) glyph_extents->y_bearing; + float x1 = (float) glyph_extents->x_bearing + glyph_extents->width; + float y1 = (float) glyph_extents->y_bearing + glyph_extents->height; + + float xmin = hb_min (x0, x1); + float xmax = hb_max (x0, x1); + float ymin = hb_min (y0, y1); + float ymax = hb_max (y0, y1); + + float px[4] = {xmin, xmin, xmax, xmax}; + float py[4] = {ymin, ymax, ymin, ymax}; + + float tx, ty; + hb_raster_draw_transform_point (draw, px[0], py[0], tx, ty); + float tx_min = tx, tx_max = tx; + float ty_min = ty, ty_max = ty; + + for (unsigned i = 1; i < 4; i++) + { + hb_raster_draw_transform_point (draw, px[i], py[i], tx, ty); + tx_min = hb_min (tx_min, tx); + tx_max = hb_max (tx_max, tx); + ty_min = hb_min (ty_min, ty); + ty_max = hb_max (ty_max, ty); + } + + int ex0 = (int) floorf (tx_min); + int ey0 = (int) floorf (ty_min); + int ex1 = (int) ceilf (tx_max); + int ey1 = (int) ceilf (ty_max); + + if (ex1 <= ex0 || ey1 <= ey0) + { + draw->fixed_extents = {}; + draw->has_extents = false; + return false; + } + + draw->fixed_extents = { + ex0, ey0, + (unsigned) (ex1 - ex0), + (unsigned) (ey1 - ey0), + 0 + }; + draw->has_extents = true; + return true; +} + +/** + * hb_raster_draw_reset: + * @draw: a rasterizer + * + * Resets the rasterizer to its initial state, clearing all accumulated + * geometry, the transform, and fixed extents. The object can then be + * reused for a new glyph. + * + * Internal scratch buffers and recycled image cache are preserved for + * reuse across subsequent renders. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_reset (hb_raster_draw_t *draw) +{ + draw->transform = {1, 0, 0, 1, 0, 0}; + draw->x_scale_factor = 1.f; + draw->y_scale_factor = 1.f; + draw->fixed_extents = {}; + draw->has_extents = false; + draw->edges.clear (); + draw->active_edges.clear (); +} + +/** + * hb_raster_draw_recycle_image: + * @draw: a rasterizer + * @image: a raster image to recycle + * + * Recycles @image for reuse by a subsequent hb_raster_draw_render() + * call, avoiding per-render memory allocation. The caller transfers + * ownership of @image to @draw and must not use it afterwards. + * + * If @draw already holds a recycled image, the previously recycled + * image is destroyed. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_recycle_image (hb_raster_draw_t *draw, + hb_raster_image_t *image) +{ + hb_raster_image_destroy (draw->recycled_image); + draw->recycled_image = image; +} + + +/* + * Draw callbacks — flatten on the fly into hb_raster_edge_t + */ + +static inline void +transform_point (const hb_raster_draw_t *draw, + float x, float y, + float &tx, float &ty) +{ + hb_raster_draw_transform_point (draw, x, y, tx, ty); +} + +static void +emit_segment (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1) +{ + int32_t X0 = (int32_t) roundf (x0 * HB_RASTER_ONE_PIXEL); + int32_t Y0 = (int32_t) roundf (y0 * HB_RASTER_ONE_PIXEL); + int32_t X1 = (int32_t) roundf (x1 * HB_RASTER_ONE_PIXEL); + int32_t Y1 = (int32_t) roundf (y1 * HB_RASTER_ONE_PIXEL); + + if (Y0 == Y1) return; /* horizontal — skip */ + + hb_raster_edge_t e; + if (Y0 < Y1) { + e.xL = X0; e.yL = Y0; e.xH = X1; e.yH = Y1; e.wind = +1; + } else { + e.xL = X1; e.yL = Y1; e.xH = X0; e.yH = Y0; e.wind = -1; + } + e.slope = ((int64_t) (e.xH - e.xL) << 16) / (e.yH - e.yL); + + draw->edges.push (e); +} + +/* Quadratic Bézier flattener — iterative de Casteljau at t=0.5. */ +static inline void +flatten_quadratic_recursive (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1, + float x2, float y2, + int depth = 0) +{ + struct quad_node_t + { + float x0, y0, x1, y1, x2, y2; + int depth; + }; + + quad_node_t stack[16]; + unsigned top = 0; + + while (true) + { + bool is_flat; + if (false) + { + /* Old behavior: midpoint deviation from chord midpoint. */ + float mx = x0 * 0.25f + x1 * 0.5f + x2 * 0.25f; + float my = y0 * 0.25f + y1 * 0.5f + y2 * 0.25f; + float chord_mx = (x0 + x2) * 0.5f; + float chord_my = (y0 + y2) * 0.5f; + float dx = mx - chord_mx; + float dy = my - chord_my; + static const float flat_thresh = HB_RASTER_FLAT_THRESH * HB_RASTER_FLAT_THRESH; + is_flat = (dx * dx + dy * dy) <= flat_thresh; + } + else + { + /* FreeType behavior: control-point deviation from chord center. */ + const float flat_thresh = 0.25f; + float dx = x0 + x2 - 2.f * x1; + float dy = y0 + y2 - 2.f * y1; + if (dx < 0) dx = -dx; + if (dy < 0) dy = -dy; + is_flat = dx <= flat_thresh && dy <= flat_thresh; + } + + if (depth >= 16 || is_flat) + { + emit_segment (draw, x0, y0, x2, y2); + if (!top) return; + const quad_node_t &n = stack[--top]; + x0 = n.x0; y0 = n.y0; + x1 = n.x1; y1 = n.y1; + x2 = n.x2; y2 = n.y2; + depth = n.depth; + continue; + } + + float x01 = (x0 + x1) * 0.5f, y01 = (y0 + y1) * 0.5f; + float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f; + float xm = (x01 + x12) * 0.5f, ym = (y01 + y12) * 0.5f; + + /* Depth is capped at 16, so stack capacity 16 is sufficient. */ + stack[top++] = {xm, ym, x12, y12, x2, y2, depth + 1}; + x2 = xm; y2 = ym; + x1 = x01; y1 = y01; + depth++; + } +} + +/* Quadratic Bézier flattener using forward differencing. + The error (midpoint deviation) shrinks exactly 4× per de Casteljau + subdivision, so we compute the subdivision count upfront and iterate + with constant-cost additions instead of recursive branching. */ +static inline void +flatten_quadratic_fd (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1, + float x2, float y2) +{ + /* Deviation of curve midpoint from chord midpoint (squared). */ + float devx = (x0 - 2 * x1 + x2) * 0.25f; + float devy = (y0 - 2 * y1 + y2) * 0.25f; + float err2 = devx * devx + devy * devy; + + static const float flat_thresh = HB_RASTER_FLAT_THRESH * HB_RASTER_FLAT_THRESH; + + if (err2 <= flat_thresh) + { + emit_segment (draw, x0, y0, x2, y2); + return; + } + + /* err² shrinks 16× per subdivision level. Find n such that + err2 / 16^n <= flat_thresh, i.e. n = ceil(log₁₆(err2/flat_thresh)). */ + unsigned n = 1; + { + float ratio = err2 / flat_thresh; + while (ratio > 16.f) { ratio *= (1.f / 16.f); n++; } + if (n > 16) n = 16; + } + unsigned N = 1u << n; /* number of line segments */ + float h = 1.f / N; + + /* Quadratic: B(t) = a·t² + b·t + c + Forward differences with step h: + d²f = 2·a·h² (constant) + df₀ = a·h² + b·h + f₀ = c = P₀ */ + float ax = x0 - 2 * x1 + x2; + float ay = y0 - 2 * y1 + y2; + float bx = 2 * (x1 - x0); + float by = 2 * (y1 - y0); + + float d2fx = 2 * ax * h * h; + float d2fy = 2 * ay * h * h; + float dfx = ax * h * h + bx * h; + float dfy = ay * h * h + by * h; + float fx = x0; + float fy = y0; + + for (unsigned i = 1; i < N; i++) + { + float nx = fx + dfx; + float ny = fy + dfy; + emit_segment (draw, fx, fy, nx, ny); + fx = nx; + fy = ny; + dfx += d2fx; + dfy += d2fy; + } + /* Last segment uses exact endpoint to avoid drift. */ + emit_segment (draw, fx, fy, x2, y2); +} + +static void +flatten_quadratic (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1, + float x2, float y2) +{ + if (false) + flatten_quadratic_fd (draw, x0, y0, x1, y1, x2, y2); + else + flatten_quadratic_recursive (draw, x0, y0, x1, y1, x2, y2); +} + +/* For cubic B(t), the max deviation from its chord on [0,1] is bounded by: + max||B(t)-L(t)|| <= max_t ||B''(t)|| / 8. + B''(t) is linear, so max norm is attained at t=0 or t=1: + B''(0)=6*(P0-2P1+P2), B''(1)=6*(P1-2P2+P3). */ +static inline float +cubic_chord_error_bound2 (float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3) +{ + float d20x = x0 - 2 * x1 + x2; + float d20y = y0 - 2 * y1 + y2; + float d21x = x1 - 2 * x2 + x3; + float d21y = y1 - 2 * y2 + y3; + float m0 = d20x * d20x + d20y * d20y; + float m1 = d21x * d21x + d21y * d21y; + float m = m0 > m1 ? m0 : m1; + /* (max||B''||/8)^2 = (6/8)^2 * max||d2||^2 = (3/4)^2 * m. */ + return m * (9.f / 16.f); +} + +/* Cubic Bézier flattener — iterative de Casteljau at t=0.5. */ +static inline void +flatten_cubic_recursive (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3, + int depth = 0) +{ + struct cubic_node_t + { + float x0, y0, x1, y1, x2, y2, x3, y3; + int depth; + }; + + cubic_node_t stack[16]; + unsigned top = 0; + + while (true) + { + bool is_flat; + if (false) + { + /* Old behavior: curvature/chord-error bound. */ + float err2 = cubic_chord_error_bound2 (x0, y0, x1, y1, x2, y2, x3, y3); + static const float flat_thresh = HB_RASTER_FLAT_THRESH * HB_RASTER_FLAT_THRESH; + is_flat = err2 <= flat_thresh; + } + else + { + /* FreeType behavior: chord-trisection distance test. */ + const float flat_thresh = 0.5f; + + float d10x = 2.f * x0 - 3.f * x1 + x3; + float d10y = 2.f * y0 - 3.f * y1 + y3; + float d20x = x0 - 3.f * x2 + 2.f * x3; + float d20y = y0 - 3.f * y2 + 2.f * y3; + + if (d10x < 0) d10x = -d10x; + if (d10y < 0) d10y = -d10y; + if (d20x < 0) d20x = -d20x; + if (d20y < 0) d20y = -d20y; + + is_flat = d10x <= flat_thresh && + d10y <= flat_thresh && + d20x <= flat_thresh && + d20y <= flat_thresh; + } + + if (depth >= 16 || is_flat) + { + emit_segment (draw, x0, y0, x3, y3); + if (!top) return; + const cubic_node_t &n = stack[--top]; + x0 = n.x0; y0 = n.y0; + x1 = n.x1; y1 = n.y1; + x2 = n.x2; y2 = n.y2; + x3 = n.x3; y3 = n.y3; + depth = n.depth; + continue; + } + + float x01 = (x0 + x1) * 0.5f, y01 = (y0 + y1) * 0.5f; + float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f; + float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f; + float x012 = (x01 + x12) * 0.5f, y012 = (y01 + y12) * 0.5f; + float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f; + float xm = (x012 + x123) * 0.5f, ym = (y012 + y123) * 0.5f; + + /* Depth is capped at 16, so stack capacity 16 is sufficient. */ + stack[top++] = {xm, ym, x123, y123, x23, y23, x3, y3, depth + 1}; + x3 = xm; y3 = ym; + x2 = x012; y2 = y012; + x1 = x01; y1 = y01; + depth++; + } +} + +/* Cubic Bézier flattener using forward differencing. + Use a curvature-based chord-error bound (max||B''||/8), then choose a + uniform subdivision count n such that the bound drops below threshold. + The cubic adds a constant third difference d³f = 6·a·h³. */ +static inline void +flatten_cubic_fd (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3) +{ + float err2 = cubic_chord_error_bound2 (x0, y0, x1, y1, x2, y2, x3, y3); + + static const float flat_thresh = HB_RASTER_FLAT_THRESH * HB_RASTER_FLAT_THRESH; + + if (err2 <= flat_thresh) + { + emit_segment (draw, x0, y0, x3, y3); + return; + } + + /* The bound scales with h², so err² shrinks 16× per subdivision level. */ + unsigned n = 1; + { + float ratio = err2 / flat_thresh; + while (ratio > 16.f) { ratio *= (1.f / 16.f); n++; } + if (n > 16) n = 16; + } + unsigned N = 1u << n; + float h = 1.f / N; + + /* Cubic: B(t) = a·t³ + b·t² + c·t + d + a = -P₀ + 3P₁ - 3P₂ + P₃ + b = 3P₀ - 6P₁ + 3P₂ + c = 3(P₁ - P₀) + d = P₀ + Forward differences with step h: + d³f = 6·a·h³ (constant) + d²f₀ = 6·a·h³ + 2·b·h² + d¹f₀ = a·h³ + b·h² + c·h + f₀ = d = P₀ */ + float ax = -x0 + 3*x1 - 3*x2 + x3; + float ay = -y0 + 3*y1 - 3*y2 + y3; + float bx = 3*x0 - 6*x1 + 3*x2; + float by = 3*y0 - 6*y1 + 3*y2; + float cx = 3*(x1 - x0); + float cy = 3*(y1 - y0); + + float h2 = h * h, h3 = h2 * h; + float d3fx = 6 * ax * h3; + float d3fy = 6 * ay * h3; + float d2fx = d3fx + 2 * bx * h2; + float d2fy = d3fy + 2 * by * h2; + float dfx = ax * h3 + bx * h2 + cx * h; + float dfy = ay * h3 + by * h2 + cy * h; + float fx = x0; + float fy = y0; + + for (unsigned i = 1; i < N; i++) + { + float nx = fx + dfx; + float ny = fy + dfy; + emit_segment (draw, fx, fy, nx, ny); + fx = nx; fy = ny; + dfx += d2fx; dfy += d2fy; + d2fx += d3fx; d2fy += d3fy; + } + /* Last segment uses exact endpoint to avoid drift. */ + emit_segment (draw, fx, fy, x3, y3); +} + +static void +flatten_cubic (hb_raster_draw_t *draw, + float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3) +{ + if (false) + flatten_cubic_fd (draw, x0, y0, x1, y1, x2, y2, x3, y3); + else + flatten_cubic_recursive (draw, x0, y0, x1, y1, x2, y2, x3, y3); +} + + +/* Draw callback implementations */ + +static void +hb_raster_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st HB_UNUSED, + float to_x HB_UNUSED, float to_y HB_UNUSED, + void *user_data HB_UNUSED) +{ + /* no-op: state tracked by hb_draw_state_t */ +} + +static void +hb_raster_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_raster_draw_t *draw = (hb_raster_draw_t *) draw_data; + + float tx0, ty0, tx1, ty1; + transform_point (draw, st->current_x, st->current_y, tx0, ty0); + transform_point (draw, to_x, to_y, tx1, ty1); + emit_segment (draw, tx0, ty0, tx1, ty1); +} + +static void +hb_raster_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st, + float control_x, float control_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_raster_draw_t *draw = (hb_raster_draw_t *) draw_data; + + float tx0, ty0, tx1, ty1, tx2, ty2; + transform_point (draw, st->current_x, st->current_y, tx0, ty0); + transform_point (draw, control_x, control_y, tx1, ty1); + transform_point (draw, to_x, to_y, tx2, ty2); + flatten_quadratic (draw, tx0, ty0, tx1, ty1, tx2, ty2); +} + +static void +hb_raster_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_raster_draw_t *draw = (hb_raster_draw_t *) draw_data; + + float tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3; + transform_point (draw, st->current_x, st->current_y, tx0, ty0); + transform_point (draw, control1_x, control1_y, tx1, ty1); + transform_point (draw, control2_x, control2_y, tx2, ty2); + transform_point (draw, to_x, to_y, tx3, ty3); + flatten_cubic (draw, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3); +} + +static void +hb_raster_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data HB_UNUSED, + hb_draw_state_t *st HB_UNUSED, + void *user_data HB_UNUSED) +{ + /* no-op: hb_draw_funcs_t already emits closing line_to before us */ +} + + +/* Lazy-loader singleton for draw funcs */ + +static inline void free_static_raster_draw_funcs (); + +static struct hb_raster_draw_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t +{ + static hb_draw_funcs_t *create () + { + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + + hb_draw_funcs_set_move_to_func (funcs, hb_raster_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, hb_raster_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, hb_raster_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, hb_raster_cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, hb_raster_close_path, nullptr, nullptr); + + hb_draw_funcs_make_immutable (funcs); + + hb_atexit (free_static_raster_draw_funcs); + + return funcs; + } +} static_raster_draw_funcs; + +static inline void +free_static_raster_draw_funcs () +{ + static_raster_draw_funcs.free_instance (); +} + +/** + * hb_raster_draw_get_funcs: + * + * Fetches the singleton #hb_draw_funcs_t that feeds outline data + * into an #hb_raster_draw_t. Pass the #hb_raster_draw_t as the + * @draw_data argument when calling the draw functions. + * + * Return value: (transfer none): + * The rasterizer draw functions + * + * Since: 13.0.0 + **/ +hb_draw_funcs_t * +hb_raster_draw_get_funcs (void) +{ + return static_raster_draw_funcs.get_unconst (); +} + +/** + * hb_raster_draw_glyph: + * @draw: a rasterizer + * @font: font to draw from + * @glyph: glyph ID to draw + * @pen_x: glyph origin x in font coordinates (pre-transform) + * @pen_y: glyph origin y in font coordinates (pre-transform) + * + * Convenience wrapper to draw one glyph at (@pen_x, @pen_y) using the + * rasterizer's current transform. The pen coordinates are applied before + * minification and are transformed by the current affine transform. + * + * Since: 13.0.0 + **/ +void +hb_raster_draw_glyph (hb_raster_draw_t *draw, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y) +{ + float xx = draw->transform.xx; + float yx = draw->transform.yx; + float xy = draw->transform.xy; + float yy = draw->transform.yy; + float dx = draw->transform.x0; + float dy = draw->transform.y0; + + hb_raster_draw_set_transform (draw, + xx, yx, xy, yy, + dx + xx * pen_x + xy * pen_y, + dy + yx * pen_x + yy * pen_y); + hb_font_draw_glyph (font, glyph, hb_raster_draw_get_funcs (), draw); + hb_raster_draw_set_transform (draw, xx, yx, xy, yy, dx, dy); +} + + +/* + * Analytic coverage rasterizer + * + * For each line-segment edge and each pixel row it crosses, we compute + * exact area/cover contributions per pixel cell. A left-to-right sweep + * then converts accumulated (area, cover) into alpha values. + * + * Coordinates are fixed-point. + * + * cover[x] = Σ dy · wind — signed vertical extent per cell + * area[x] = Σ (fx₀+fx₁)·dy·wind — twice the signed trapezoidal area + * + * Sweep: + * cover_accum += cover[x] + * α = min(|cover_accum·128 − area[x]|, 8192) · 255 / 8192 + */ + +/* Add one edge piece's area/cover into a single cell. */ +static HB_ALWAYS_INLINE void +cell_add (int32_t *area, int16_t *cover, unsigned width, int col, + int32_t fx0, int32_t fy0, int32_t fx1, int32_t fy1, int32_t wind, + unsigned &x_min, unsigned &x_max) +{ + if (unlikely ((unsigned) col >= width)) + { + if (unlikely (col < 0)) + { + /* Edge is to the left of the surface. The winding contribution + * still carries into the visible region, so add the cover delta + * to column 0. Area is not added since the edge doesn't cross + * column 0's cell. */ + int32_t dy = fy1 - fy0; + cover[0] += (int16_t) (dy * wind); + x_min = hb_min (x_min, 0u); + x_max = hb_max (x_max, 0u); + } + return; + } + int32_t dy = fy1 - fy0; + area[col] += (fx0 + fx1) * dy * wind; + cover[col] += (int16_t) (dy * wind); + x_min = hb_min (x_min, (unsigned) col); + x_max = hb_max (x_max, (unsigned) col); +} + +/* Walk one edge through the pixel cells of a single pixel row, + accumulating area/cover. py is the integer pixel-row index. */ +static HB_ALWAYS_INLINE void +edge_sweep_row (int32_t *area, + int16_t *cover, + unsigned width, + int x_org, + int32_t y_top, + const hb_raster_edge_t &edge, + unsigned &x_min, + unsigned &x_max) +{ + int32_t y_bot = y_top + HB_RASTER_ONE_PIXEL; + + int32_t ey0 = hb_max (edge.yL, y_top); + int32_t ey1 = hb_min (edge.yH, y_bot); + if (ey0 >= ey1) return; + + /* X at clipped endpoints (fixed-point) */ + int32_t x0 = edge.xL + (int32_t) ((int64_t) (ey0 - edge.yL) * edge.slope >> 16); + int32_t x1 = edge.xL + (int32_t) ((int64_t) (ey1 - edge.yL) * edge.slope >> 16); + + /* Fractional y within this pixel row [0, ONE_PIXEL] */ + int32_t fy0 = ey0 - y_top; + int32_t fy1 = ey1 - y_top; + + int32_t cx0 = x0 >> HB_RASTER_PIXEL_BITS; + int32_t fx0 = x0 & HB_RASTER_PIXEL_MASK; + int32_t cx1 = x1 >> HB_RASTER_PIXEL_BITS; + int32_t fx1 = x1 & HB_RASTER_PIXEL_MASK; + int32_t wind = edge.wind; + + /* Fast path: both endpoints in the same pixel column. */ + if (cx0 == cx1) + { + cell_add (area, cover, width, cx0 - x_org, fx0, fy0, fx1, fy1, wind, x_min, x_max); + return; + } + + int32_t total_dx = x1 - x0; + int32_t total_dy = fy1 - fy0; + + /* fy increment per pixel column (constant since x_b advances by ONE_PIXEL). */ + int32_t delta_fy = (int32_t) ((int64_t) HB_RASTER_ONE_PIXEL * total_dy / total_dx); + + if (total_dx > 0) + { + /* Left-to-right edge. */ + int32_t x_b = (cx0 + 1) << HB_RASTER_PIXEL_BITS; + int32_t fy_b = fy0 + (int32_t) ((int64_t) (x_b - x0) * total_dy / total_dx); + cell_add (area, cover, width, cx0 - x_org, fx0, fy0, HB_RASTER_ONE_PIXEL, fy_b, wind, x_min, x_max); + + int32_t fy_prev = fy_b; + for (int32_t cx = cx0 + 1; cx < cx1; cx++) + { + fy_b = fy_prev + delta_fy; + cell_add (area, cover, width, cx - x_org, 0, fy_prev, HB_RASTER_ONE_PIXEL, fy_b, wind, x_min, x_max); + fy_prev = fy_b; + } + + cell_add (area, cover, width, cx1 - x_org, 0, fy_prev, fx1, fy1, wind, x_min, x_max); + } + else + { + /* Right-to-left edge. */ + int32_t x_b = cx0 << HB_RASTER_PIXEL_BITS; + int32_t fy_b = fy0 + (int32_t) ((int64_t) (x_b - x0) * total_dy / total_dx); + cell_add (area, cover, width, cx0 - x_org, fx0, fy0, 0, fy_b, wind, x_min, x_max); + + int32_t fy_prev = fy_b; + for (int32_t cx = cx0 - 1; cx > cx1; cx--) + { + fy_b = fy_prev - delta_fy; + cell_add (area, cover, width, cx - x_org, HB_RASTER_ONE_PIXEL, fy_prev, 0, fy_b, wind, x_min, x_max); + fy_prev = fy_b; + } + + cell_add (area, cover, width, cx1 - x_org, HB_RASTER_ONE_PIXEL, fy_prev, fx1, fy1, wind, x_min, x_max); + } +} + +/* Convert cover-delta + area to alpha bytes, then clear. + Returns final cover accumulator over [x_min, x_max]. */ +static int32_t +sweep_row_to_alpha (uint8_t *__restrict row_buf, + int32_t *__restrict area, + int16_t *__restrict cover, + unsigned x_min, + unsigned x_max) +{ + const int32_t cover_scale = 2 * HB_RASTER_ONE_PIXEL; + int32_t cover_accum = 0; + unsigned x = x_min; + +#ifdef HB_RASTER_NEON + int32x4_t clamp_v = vdupq_n_s32 (HB_RASTER_FULL_COVERAGE); + int32x4_t bias_v = vdupq_n_s32 (HB_RASTER_FULL_COVERAGE / 2); + int32x4_t zero32 = vdupq_n_s32 (0); + int16x8_t zero16 = vdupq_n_s16 (0); + for (; x + 7 <= x_max; x += 8) + { + int32_t ctmp[8]; + for (unsigned i = 0; i < 8; i++) + { + cover_accum += cover[x + i]; + ctmp[i] = cover_accum * cover_scale; + } + + int32x4_t c0 = vld1q_s32 (ctmp + 0); + int32x4_t c1 = vld1q_s32 (ctmp + 4); + int32x4_t a0 = vld1q_s32 (area + x); + int32x4_t a1 = vld1q_s32 (area + x + 4); + + int32x4_t v0 = vabsq_s32 (vsubq_s32 (c0, a0)); + int32x4_t v1 = vabsq_s32 (vsubq_s32 (c1, a1)); + + v0 = vminq_s32 (v0, clamp_v); + v1 = vminq_s32 (v1, clamp_v); + + int32x4_t r0 = vshrq_n_s32 (vmlaq_n_s32 (bias_v, v0, 255), 2 * HB_RASTER_PIXEL_BITS + 1); + int32x4_t r1 = vshrq_n_s32 (vmlaq_n_s32 (bias_v, v1, 255), 2 * HB_RASTER_PIXEL_BITS + 1); + + int16x4_t h0 = vmovn_s32 (r0); + int16x4_t h1 = vmovn_s32 (r1); + int16x8_t h = vcombine_s16 (h0, h1); + uint8x8_t b = vqmovun_s16 (h); + vst1_u8 (row_buf + x, b); + + vst1q_s32 (area + x, zero32); + vst1q_s32 (area + x + 4, zero32); + vst1q_s16 (cover + x, zero16); + } +#elif defined(HB_RASTER_SSE2) + __m128i clamp_v = _mm_set1_epi32 (HB_RASTER_FULL_COVERAGE); + __m128i bias_v = _mm_set1_epi32 (HB_RASTER_FULL_COVERAGE / 2); + __m128i zero_v = _mm_setzero_si128 (); + for (; x + 7 <= x_max; x += 8) + { + int32_t ctmp[8]; + for (unsigned i = 0; i < 8; i++) + { + cover_accum += cover[x + i]; + ctmp[i] = cover_accum * cover_scale; + } + + __m128i c0 = _mm_loadu_si128 ((__m128i *) (void *) (ctmp + 0)); + __m128i c1 = _mm_loadu_si128 ((__m128i *) (void *) (ctmp + 4)); + __m128i a0 = _mm_loadu_si128 ((__m128i *) (void *) (area + x)); + __m128i a1 = _mm_loadu_si128 ((__m128i *) (void *) (area + x + 4)); + + __m128i v0 = _mm_sub_epi32 (c0, a0); + __m128i v1 = _mm_sub_epi32 (c1, a1); + + __m128i s0 = _mm_srai_epi32 (v0, 31); + __m128i s1 = _mm_srai_epi32 (v1, 31); + v0 = _mm_sub_epi32 (_mm_xor_si128 (v0, s0), s0); + v1 = _mm_sub_epi32 (_mm_xor_si128 (v1, s1), s1); + + __m128i lt0 = _mm_cmplt_epi32 (v0, clamp_v); + __m128i lt1 = _mm_cmplt_epi32 (v1, clamp_v); + v0 = _mm_or_si128 (_mm_and_si128 (lt0, v0), _mm_andnot_si128 (lt0, clamp_v)); + v1 = _mm_or_si128 (_mm_and_si128 (lt1, v1), _mm_andnot_si128 (lt1, clamp_v)); + + __m128i r0 = _mm_srai_epi32 (_mm_add_epi32 (_mm_sub_epi32 (_mm_slli_epi32 (v0, 8), v0), bias_v), 2 * HB_RASTER_PIXEL_BITS + 1); + __m128i r1 = _mm_srai_epi32 (_mm_add_epi32 (_mm_sub_epi32 (_mm_slli_epi32 (v1, 8), v1), bias_v), 2 * HB_RASTER_PIXEL_BITS + 1); + + __m128i h = _mm_packs_epi32 (r0, r1); + __m128i b = _mm_packus_epi16 (h, h); + _mm_storel_epi64 ((__m128i *) (void *) (row_buf + x), b); + + _mm_storeu_si128 ((__m128i *) (void *) (area + x), zero_v); + _mm_storeu_si128 ((__m128i *) (void *) (area + x + 4), zero_v); + _mm_storeu_si128 ((__m128i *) (void *) (cover + x), zero_v); + } +#endif + + for (; x <= x_max; x++) + { + cover_accum += cover[x]; + int32_t val = cover_accum * cover_scale - area[x]; + int32_t alpha = val < 0 ? -val : val; + if (alpha > HB_RASTER_FULL_COVERAGE) alpha = HB_RASTER_FULL_COVERAGE; + row_buf[x] = (uint8_t) (((unsigned) alpha * 255 + HB_RASTER_FULL_COVERAGE / 2) >> (2 * HB_RASTER_PIXEL_BITS + 1)); + area[x] = 0; + cover[x] = 0; + } + + return cover_accum; +} + + +/** + * hb_raster_draw_render: + * @draw: a rasterizer + * + * Rasterizes the accumulated outline geometry into a new + * #hb_raster_image_t. After rendering, the accumulated edges are + * cleared so the rasterizer can be reused. Output format is always + * @HB_RASTER_FORMAT_A8. + * + * Return value: (transfer full): + * A rendered #hb_raster_image_t. Returns `NULL` on allocation/configuration + * failure. If no geometry was accumulated, returns an empty image. + * + * Since: 13.0.0 + **/ +hb_raster_image_t * +hb_raster_draw_render (hb_raster_draw_t *draw) +{ + /* ── 1. Compute result extents ─────────────────────────────────── */ + hb_raster_extents_t ext; + + if (draw->has_extents) + { + ext = draw->fixed_extents; + } + else + { + /* Auto-size from edge bounding box */ + if (draw->edges.length == 0) + { + /* No edges: produce 0×0 image */ + ext = { 0, 0, 0, 0, 0 }; + } + else + { + int32_t xmin = draw->edges.arrayZ[0].xL, xmax = draw->edges.arrayZ[0].xL; + int32_t ymin = draw->edges.arrayZ[0].yL, ymax = draw->edges.arrayZ[0].yH; + + for (const auto &e : draw->edges) + { + xmin = hb_min (xmin, hb_min (e.xL, e.xH)); + xmax = hb_max (xmax, hb_max (e.xL, e.xH)); + ymin = hb_min (ymin, e.yL); + ymax = hb_max (ymax, e.yH); + } + + /* Convert fixed-point → pixels (floor for min, ceil for max) */ + int x0 = xmin >> HB_RASTER_PIXEL_BITS; + int y0 = ymin >> HB_RASTER_PIXEL_BITS; + int x1 = (xmax + HB_RASTER_PIXEL_MASK) >> HB_RASTER_PIXEL_BITS; + int y1 = (ymax + HB_RASTER_PIXEL_MASK) >> HB_RASTER_PIXEL_BITS; + + ext.x_origin = x0; + ext.y_origin = y0; + ext.width = (unsigned) hb_max (0, x1 - x0); + ext.height = (unsigned) hb_max (0, y1 - y0); + ext.stride = 0; /* filled below */ + } + } + + /* ── 2. Compute stride ─────────────────────────────────────────── */ + if (ext.stride == 0) + ext.stride = (ext.width + 3u) & ~3u; + + /* ── 3. Allocate or reuse image ─────────────────────────────────── */ + hb_raster_image_t *image; + if (draw->recycled_image) + { + image = draw->recycled_image; + draw->recycled_image = nullptr; + } + else + { + image = hb_raster_image_create_or_fail (); + if (unlikely (!image)) goto fail; + } + + if (unlikely (!image->configure (HB_RASTER_FORMAT_A8, ext))) + { + hb_raster_image_destroy (image); + image = nullptr; + goto fail; + } + image->clear (); + + /* ── 4. Bucket edges by starting row and rasterize scanlines ──── */ + if (draw->edges.length && ext.width && ext.height) + { + if (unlikely (!draw->row_area.resize_dirty (ext.width) || + !draw->row_cover.resize_dirty (ext.width))) + goto fail; + hb_memset (draw->row_area.arrayZ, 0, ext.width * sizeof (int32_t)); + hb_memset (draw->row_cover.arrayZ, 0, ext.width * sizeof (int16_t)); + + /* Bucket edges by their starting pixel row. + Only grow the outer vector; clear inner vectors without freeing. */ + unsigned old_buckets = draw->edge_buckets.length; + if (ext.height > old_buckets) + { + if (unlikely (!draw->edge_buckets.resize (ext.height))) + goto fail; + } + for (unsigned i = 0; i < hb_min (ext.height, old_buckets); i++) + draw->edge_buckets.arrayZ[i].clear (); + /* New buckets (if any) are already empty from resize's zero-init. */ + + for (unsigned i = 0; i < draw->edges.length; i++) + { + int row = (draw->edges.arrayZ[i].yL >> HB_RASTER_PIXEL_BITS) - ext.y_origin; + if (row < 0) row = 0; + if ((unsigned) row >= ext.height) continue; + draw->edge_buckets.arrayZ[row].push (i); + } + + /* Scanline loop with active edge list. */ + draw->active_edges.clear (); + + for (unsigned row = 0; row < ext.height; row++) + { + int32_t y_top = (ext.y_origin + (int) row) << HB_RASTER_PIXEL_BITS; + + /* Add new edges from this row's bucket. */ + draw->active_edges.extend (draw->edge_buckets.arrayZ[row]); + + /* Process active edges and compact live ones in one linear pass. */ + unsigned x_min = ext.width, x_max = 0; + unsigned write = 0; + unsigned active_len = draw->active_edges.length; + for (unsigned j = 0; j < active_len; j++) + { + unsigned edge_idx = draw->active_edges.arrayZ[j]; + const auto &e = draw->edges.arrayZ[edge_idx]; + if (e.yH <= y_top) + continue; + + edge_sweep_row (draw->row_area.arrayZ, draw->row_cover.arrayZ, + ext.width, ext.x_origin, y_top, e, x_min, x_max); + draw->active_edges.arrayZ[write++] = edge_idx; + } + draw->active_edges.resize (write); + + if (x_min <= x_max) + { + int32_t cover_accum = sweep_row_to_alpha (image->buffer.arrayZ + row * ext.stride, + draw->row_area.arrayZ, draw->row_cover.arrayZ, + x_min, x_max); + + /* If cover doesn't cancel, memset the constant-alpha tail. */ + if (cover_accum != 0) + { + int32_t alpha = cover_accum * (2 * HB_RASTER_ONE_PIXEL); + alpha = alpha < 0 ? -alpha : alpha; + if (alpha > HB_RASTER_FULL_COVERAGE) alpha = HB_RASTER_FULL_COVERAGE; + uint8_t byte = (uint8_t) (((unsigned) alpha * 255 + HB_RASTER_FULL_COVERAGE / 2) >> (2 * HB_RASTER_PIXEL_BITS + 1)); + + uint8_t *row_buf = image->buffer.arrayZ + row * ext.stride; + hb_memset (row_buf + x_max + 1, byte, ext.width - 1 - x_max); + } + } + } + } + +done: + /* ── 6. Reset one-shot state ────────────────────────────────────── */ + draw->edges.clear (); + draw->has_extents = false; + draw->fixed_extents = {}; + + return image; + +fail: + hb_raster_image_destroy (image); + image = nullptr; + goto done; +} diff --git a/thirdparty/harfbuzz/upstream/hb-raster-image.cc b/thirdparty/harfbuzz/upstream/hb-raster-image.cc new file mode 100644 index 000000000..bfe78dea2 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-image.cc @@ -0,0 +1,967 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-raster-image.hh" + +#include + +#ifdef HAVE_PNG +#include +#endif + +#ifdef HAVE_PNG +struct hb_raster_png_read_blob_t +{ + const uint8_t *data = nullptr; + size_t size = 0; + size_t offset = 0; +}; + +static void +hb_raster_png_error (png_structp png, + png_const_charp msg HB_UNUSED) +{ + png_longjmp (png, 1); +} + +static void +hb_raster_png_warning (png_structp png HB_UNUSED, + png_const_charp msg HB_UNUSED) +{} + +static void +hb_raster_png_read_blob (png_structp png, png_bytep out, png_size_t length) +{ + hb_raster_png_read_blob_t *r = (hb_raster_png_read_blob_t *) png_get_io_ptr (png); + + if (!r || !r->data || length > r->size - r->offset) + png_error (png, "read error"); + + hb_memcpy (out, r->data + r->offset, length); + r->offset += length; +} + +struct hb_raster_png_write_blob_t +{ + hb_vector_t data; +}; + +static void +hb_raster_png_write_blob (png_structp png, png_bytep in, png_size_t length) +{ + hb_raster_png_write_blob_t *w = (hb_raster_png_write_blob_t *) png_get_io_ptr (png); + if (!w) + png_error (png, "write error"); + + unsigned old_length = w->data.length; + if (!w->data.resize_dirty ((int) (old_length + length))) + png_error (png, "write error"); + + hb_memcpy (w->data.arrayZ + old_length, in, length); +} + +static void +hb_raster_png_flush_blob (png_structp png HB_UNUSED) +{} +#endif + + +/* + * Image compositing + */ + +/* Unpack premultiplied pixel to float RGBA [0,1]. */ +static inline void +unpack_to_float (uint32_t px, float &r, float &g, float &b, float &a) +{ + b = (px & 0xFF) / 255.f; + g = ((px >> 8) & 0xFF) / 255.f; + r = ((px >> 16) & 0xFF) / 255.f; + a = (px >> 24) / 255.f; +} + +/* Pack float RGBA [0,1] premultiplied back to uint32_t. */ +static inline uint32_t +pack_from_float (float r, float g, float b, float a) +{ + return hb_raster_pack_pixel ((uint8_t) (hb_clamp (b, 0.f, 1.f) * 255.f + 0.5f), + (uint8_t) (hb_clamp (g, 0.f, 1.f) * 255.f + 0.5f), + (uint8_t) (hb_clamp (r, 0.f, 1.f) * 255.f + 0.5f), + (uint8_t) (hb_clamp (a, 0.f, 1.f) * 255.f + 0.5f)); +} + +/* Separable blend mode functions: operate on unpremultiplied [0,1] channels. */ +static inline float +blend_multiply (float sc, float dc) { return sc * dc; } +static inline float +blend_screen (float sc, float dc) { return sc + dc - sc * dc; } +static inline float +blend_overlay (float sc, float dc) +{ return dc <= 0.5f ? 2.f * sc * dc : 1.f - 2.f * (1.f - sc) * (1.f - dc); } +static inline float +blend_darken (float sc, float dc) { return hb_min (sc, dc); } +static inline float +blend_lighten (float sc, float dc) { return hb_max (sc, dc); } +static inline float +blend_color_dodge (float sc, float dc) +{ + if (dc <= 0.f) return 0.f; + if (sc >= 1.f) return 1.f; + return hb_min (1.f, dc / (1.f - sc)); +} +static inline float +blend_color_burn (float sc, float dc) +{ + if (dc >= 1.f) return 1.f; + if (sc <= 0.f) return 0.f; + return 1.f - hb_min (1.f, (1.f - dc) / sc); +} +static inline float +blend_hard_light (float sc, float dc) +{ return sc <= 0.5f ? 2.f * sc * dc : 1.f - 2.f * (1.f - sc) * (1.f - dc); } +static inline float +blend_soft_light (float sc, float dc) +{ + if (sc <= 0.5f) + return dc - (1.f - 2.f * sc) * dc * (1.f - dc); + float d = (dc <= 0.25f) ? ((16.f * dc - 12.f) * dc + 4.f) * dc + : sqrtf (dc); + return dc + (2.f * sc - 1.f) * (d - dc); +} +static inline float +blend_difference (float sc, float dc) { return fabsf (sc - dc); } +static inline float +blend_exclusion (float sc, float dc) { return sc + dc - 2.f * sc * dc; } + +/* Apply a separable blend mode per-pixel. + * Both src and dst are premultiplied BGRA32. */ +static inline uint32_t +apply_separable_blend (uint32_t src, uint32_t dst, + float (*blend_fn)(float, float)) +{ + float sr, sg, sb, sa; + float dr, dg, db, da; + unpack_to_float (src, sr, sg, sb, sa); + unpack_to_float (dst, dr, dg, db, da); + + float usr = sa > 0.f ? sr / sa : 0.f; + float usg = sa > 0.f ? sg / sa : 0.f; + float usb = sa > 0.f ? sb / sa : 0.f; + float udr = da > 0.f ? dr / da : 0.f; + float udg = da > 0.f ? dg / da : 0.f; + float udb = da > 0.f ? db / da : 0.f; + + float br = blend_fn (usr, udr); + float bg = blend_fn (usg, udg); + float bb = blend_fn (usb, udb); + + float ra = sa + da - sa * da; + float rr = sa * da * br + sa * (1.f - da) * usr + (1.f - sa) * da * udr; + float rg = sa * da * bg + sa * (1.f - da) * usg + (1.f - sa) * da * udg; + float rb = sa * da * bb + sa * (1.f - da) * usb + (1.f - sa) * da * udb; + + return pack_from_float (rr, rg, rb, ra); +} + +/* HSL helpers */ +static inline float +hsl_luminosity (float r, float g, float b) +{ return 0.299f * r + 0.587f * g + 0.114f * b; } + +static inline float +hsl_saturation (float r, float g, float b) +{ return hb_max (hb_max (r, g), b) - hb_min (hb_min (r, g), b); } + +static inline void +hsl_clip_color (float &r, float &g, float &b) +{ + float l = hsl_luminosity (r, g, b); + float mn = hb_min (hb_min (r, g), b); + float mx = hb_max (hb_max (r, g), b); + if (mn < 0.f) + { + float d = l - mn; + if (d > 0.f) { r = l + (r - l) * l / d; g = l + (g - l) * l / d; b = l + (b - l) * l / d; } + } + if (mx > 1.f) + { + float d = mx - l; + if (d > 0.f) { r = l + (r - l) * (1.f - l) / d; g = l + (g - l) * (1.f - l) / d; b = l + (b - l) * (1.f - l) / d; } + } +} + +static inline void +hsl_set_luminosity (float &r, float &g, float &b, float l) +{ + float d = l - hsl_luminosity (r, g, b); + r += d; g += d; b += d; + hsl_clip_color (r, g, b); +} + +static inline void +hsl_set_saturation_inner (float &mn, float &mid, float &mx, float s) +{ + if (mx > mn) + { + mid = (mid - mn) * s / (mx - mn); + mx = s; + } + else + mid = mx = 0.f; + mn = 0.f; +} + +static inline void +hsl_set_saturation (float &r, float &g, float &b, float s) +{ + if (r <= g) + { + if (g <= b) hsl_set_saturation_inner (r, g, b, s); + else if (r <= b) hsl_set_saturation_inner (r, b, g, s); + else hsl_set_saturation_inner (b, r, g, s); + } + else + { + if (r <= b) hsl_set_saturation_inner (g, r, b, s); + else if (g <= b) hsl_set_saturation_inner (g, b, r, s); + else hsl_set_saturation_inner (b, g, r, s); + } +} + +static inline uint32_t +apply_hsl_blend (uint32_t src, uint32_t dst, + hb_paint_composite_mode_t mode) +{ + float sr, sg, sb, sa; + float dr, dg, db, da; + unpack_to_float (src, sr, sg, sb, sa); + unpack_to_float (dst, dr, dg, db, da); + + float usr = sa > 0.f ? sr / sa : 0.f; + float usg = sa > 0.f ? sg / sa : 0.f; + float usb = sa > 0.f ? sb / sa : 0.f; + float udr = da > 0.f ? dr / da : 0.f; + float udg = da > 0.f ? dg / da : 0.f; + float udb = da > 0.f ? db / da : 0.f; + + float br = udr, bg = udg, bb = udb; + + if (mode == HB_PAINT_COMPOSITE_MODE_HSL_HUE) + { + br = usr; bg = usg; bb = usb; + hsl_set_saturation (br, bg, bb, hsl_saturation (udr, udg, udb)); + hsl_set_luminosity (br, bg, bb, hsl_luminosity (udr, udg, udb)); + } + else if (mode == HB_PAINT_COMPOSITE_MODE_HSL_SATURATION) + { + br = udr; bg = udg; bb = udb; + hsl_set_saturation (br, bg, bb, hsl_saturation (usr, usg, usb)); + hsl_set_luminosity (br, bg, bb, hsl_luminosity (udr, udg, udb)); + } + else if (mode == HB_PAINT_COMPOSITE_MODE_HSL_COLOR) + { + br = usr; bg = usg; bb = usb; + hsl_set_luminosity (br, bg, bb, hsl_luminosity (udr, udg, udb)); + } + else /* HSL_LUMINOSITY */ + { + br = udr; bg = udg; bb = udb; + hsl_set_luminosity (br, bg, bb, hsl_luminosity (usr, usg, usb)); + } + + float ra = sa + da - sa * da; + float rr = sa * da * br + sa * (1.f - da) * usr + (1.f - sa) * da * udr; + float rg = sa * da * bg + sa * (1.f - da) * usg + (1.f - sa) * da * udg; + float rb = sa * da * bb + sa * (1.f - da) * usb + (1.f - sa) * da * udb; + + return pack_from_float (rr, rg, rb, ra); +} + +/* Composite per-pixel with full blend mode support. */ +static inline uint32_t +composite_pixel (uint32_t src, uint32_t dst, + hb_paint_composite_mode_t mode) +{ + uint8_t sa = (uint8_t) (src >> 24); + uint8_t da = (uint8_t) (dst >> 24); + + switch (mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: + return 0; + case HB_PAINT_COMPOSITE_MODE_SRC: + return src; + case HB_PAINT_COMPOSITE_MODE_DEST: + return dst; + case HB_PAINT_COMPOSITE_MODE_SRC_OVER: + return hb_raster_src_over (src, dst); + case HB_PAINT_COMPOSITE_MODE_DEST_OVER: + return hb_raster_src_over (dst, src); + case HB_PAINT_COMPOSITE_MODE_SRC_IN: + return hb_raster_alpha_mul (src, da); + case HB_PAINT_COMPOSITE_MODE_DEST_IN: + return hb_raster_alpha_mul (dst, sa); + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: + return hb_raster_alpha_mul (src, 255 - da); + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: + return hb_raster_alpha_mul (dst, 255 - sa); + case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: + { + /* Fa=Da, Fb=1-Sa */ + uint32_t a = hb_raster_alpha_mul (src, da); + uint32_t b = hb_raster_alpha_mul (dst, 255 - sa); + uint8_t rb = (uint8_t) hb_min (255u, (unsigned) (a & 0xFF) + (b & 0xFF)); + uint8_t rg = (uint8_t) hb_min (255u, (unsigned) ((a >> 8) & 0xFF) + ((b >> 8) & 0xFF)); + uint8_t rr = (uint8_t) hb_min (255u, (unsigned) ((a >> 16) & 0xFF) + ((b >> 16) & 0xFF)); + uint8_t ra = (uint8_t) hb_min (255u, (unsigned) (a >> 24) + (b >> 24)); + return hb_raster_pack_pixel (rb, rg, rr, ra); + } + case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: + { + uint32_t a = hb_raster_alpha_mul (dst, sa); + uint32_t b = hb_raster_alpha_mul (src, 255 - da); + uint8_t rb = (uint8_t) hb_min (255u, (unsigned) (a & 0xFF) + (b & 0xFF)); + uint8_t rg = (uint8_t) hb_min (255u, (unsigned) ((a >> 8) & 0xFF) + ((b >> 8) & 0xFF)); + uint8_t rr = (uint8_t) hb_min (255u, (unsigned) ((a >> 16) & 0xFF) + ((b >> 16) & 0xFF)); + uint8_t ra = (uint8_t) hb_min (255u, (unsigned) (a >> 24) + (b >> 24)); + return hb_raster_pack_pixel (rb, rg, rr, ra); + } + case HB_PAINT_COMPOSITE_MODE_XOR: + { + uint32_t a = hb_raster_alpha_mul (src, 255 - da); + uint32_t b = hb_raster_alpha_mul (dst, 255 - sa); + uint8_t rb = (uint8_t) hb_min (255u, (unsigned) (a & 0xFF) + (b & 0xFF)); + uint8_t rg = (uint8_t) hb_min (255u, (unsigned) ((a >> 8) & 0xFF) + ((b >> 8) & 0xFF)); + uint8_t rr = (uint8_t) hb_min (255u, (unsigned) ((a >> 16) & 0xFF) + ((b >> 16) & 0xFF)); + uint8_t ra = (uint8_t) hb_min (255u, (unsigned) (a >> 24) + (b >> 24)); + return hb_raster_pack_pixel (rb, rg, rr, ra); + } + case HB_PAINT_COMPOSITE_MODE_PLUS: + { + uint8_t rb = (uint8_t) hb_min (255u, (unsigned) (src & 0xFF) + (dst & 0xFF)); + uint8_t rg = (uint8_t) hb_min (255u, (unsigned) ((src >> 8) & 0xFF) + ((dst >> 8) & 0xFF)); + uint8_t rr = (uint8_t) hb_min (255u, (unsigned) ((src >> 16) & 0xFF) + ((dst >> 16) & 0xFF)); + uint8_t ra = (uint8_t) hb_min (255u, (unsigned) (src >> 24) + (dst >> 24)); + return hb_raster_pack_pixel (rb, rg, rr, ra); + } + + case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return apply_separable_blend (src, dst, blend_multiply); + case HB_PAINT_COMPOSITE_MODE_SCREEN: return apply_separable_blend (src, dst, blend_screen); + case HB_PAINT_COMPOSITE_MODE_OVERLAY: return apply_separable_blend (src, dst, blend_overlay); + case HB_PAINT_COMPOSITE_MODE_DARKEN: return apply_separable_blend (src, dst, blend_darken); + case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return apply_separable_blend (src, dst, blend_lighten); + case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return apply_separable_blend (src, dst, blend_color_dodge); + case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return apply_separable_blend (src, dst, blend_color_burn); + case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return apply_separable_blend (src, dst, blend_hard_light); + case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return apply_separable_blend (src, dst, blend_soft_light); + case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return apply_separable_blend (src, dst, blend_difference); + case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return apply_separable_blend (src, dst, blend_exclusion); + + case HB_PAINT_COMPOSITE_MODE_HSL_HUE: + case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: + case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: + case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: + return apply_hsl_blend (src, dst, mode); + + default: + return hb_raster_src_over (src, dst); + } +} + +/* hb_raster_image_t */ + +unsigned +hb_raster_image_t::bytes_per_pixel (hb_raster_format_t format) +{ + return format == HB_RASTER_FORMAT_BGRA32 ? 4u : 1u; +} + +bool +hb_raster_image_t::configure (hb_raster_format_t format, + hb_raster_extents_t extents) +{ + if (format != HB_RASTER_FORMAT_A8 && + format != HB_RASTER_FORMAT_BGRA32) + format = HB_RASTER_FORMAT_A8; + + unsigned bpp = bytes_per_pixel (format); + if (extents.width > UINT_MAX / bpp) + return false; + + unsigned min_stride = extents.width * bpp; + if (extents.stride == 0 || extents.stride < min_stride) + extents.stride = min_stride; + + if (extents.height && extents.stride > (size_t) -1 / extents.height) + return false; + + size_t buf_size = (size_t) extents.stride * extents.height; + if (buf_size > HB_RASTER_MAX_BUFFER_SIZE) + return false; + if (unlikely (!buffer.resize_dirty (buf_size))) + return false; + + this->format = format; + this->extents = extents; + return true; +} + +bool +hb_raster_image_t::deserialize_from_png (hb_blob_t *blob) +{ +#ifndef HAVE_PNG + return false; +#else + if (!blob) + return false; + + unsigned blob_len = 0; + const uint8_t *blob_data = (const uint8_t *) hb_blob_get_data (blob, &blob_len); + if (!blob_data || !blob_len) + return false; + + png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, nullptr, + hb_raster_png_error, + hb_raster_png_warning); + if (!png) + return false; + + png_infop info = png_create_info_struct (png); + if (!info) + { + png_destroy_read_struct (&png, nullptr, nullptr); + return false; + } + + hb_raster_png_read_blob_t reader; + reader.data = blob_data; + reader.size = (size_t) blob_len; + reader.offset = 0; + hb_vector_t rgba; + hb_vector_t rows; + if (setjmp (png_jmpbuf (png))) + { + png_destroy_read_struct (&png, &info, nullptr); + rgba.fini (); + rows.fini (); + return false; + } + + png_set_read_fn (png, &reader, hb_raster_png_read_blob); + png_read_info (png, info); + + png_uint_32 w = 0, h = 0; + int bit_depth = 0, color_type = 0; + int interlace_type = 0, compression_type = 0, filter_method = 0; + png_get_IHDR (png, info, &w, &h, &bit_depth, &color_type, + &interlace_type, &compression_type, &filter_method); + + if (!w || !h || w > (png_uint_32) INT_MAX || h > (png_uint_32) INT_MAX) + { + png_destroy_read_struct (&png, &info, nullptr); + return false; + } + + bool has_trns = png_get_valid (png, info, PNG_INFO_tRNS); + + if (bit_depth == 16) + png_set_strip_16 (png); + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb (png); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand_gray_1_2_4_to_8 (png); + if (has_trns) + png_set_tRNS_to_alpha (png); + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb (png); + if (!(color_type & PNG_COLOR_MASK_ALPHA) && !has_trns) + png_set_add_alpha (png, 0xff, PNG_FILLER_AFTER); + if (interlace_type != PNG_INTERLACE_NONE) + png_set_interlace_handling (png); + + png_read_update_info (png, info); + + if (png_get_bit_depth (png, info) != 8 || png_get_channels (png, info) != 4) + { + png_destroy_read_struct (&png, &info, nullptr); + return false; + } + + png_size_t rowbytes = png_get_rowbytes (png, info); + if (rowbytes < (png_size_t) w * 4u) + { + png_destroy_read_struct (&png, &info, nullptr); + return false; + } + + size_t rgba_size = (size_t) rowbytes * (size_t) h; + if (h && rgba_size / (size_t) h != (size_t) rowbytes) + { + png_destroy_read_struct (&png, &info, nullptr); + return false; + } + + if (!rgba.resize (rgba_size)) + { + png_destroy_read_struct (&png, &info, nullptr); + return false; + } + + if (!rows.resize ((unsigned) h)) + { + png_destroy_read_struct (&png, &info, nullptr); + return false; + } + + for (unsigned y = 0; y < (unsigned) h; y++) + rows[y] = (png_bytep) (rgba.arrayZ + (size_t) y * (size_t) rowbytes); + + png_read_image (png, rows.arrayZ); + png_read_end (png, nullptr); + png_destroy_read_struct (&png, &info, nullptr); + + hb_raster_image_t decoded; + hb_raster_extents_t decoded_extents = {0, 0, (unsigned) w, (unsigned) h, 0}; + if (!decoded.configure (HB_RASTER_FORMAT_BGRA32, decoded_extents)) + return false; + + for (unsigned y = 0; y < (unsigned) h; y++) + { + hb_packed_t *dst = (hb_packed_t *) (decoded.buffer.arrayZ + (size_t) ((unsigned) h - 1 - y) * decoded.extents.stride); + const uint8_t *src = rgba.arrayZ + (size_t) y * (size_t) rowbytes; + for (unsigned x = 0; x < (unsigned) w; x++) + { + uint8_t r = src[4 * x + 0]; + uint8_t g = src[4 * x + 1]; + uint8_t b = src[4 * x + 2]; + uint8_t a = src[4 * x + 3]; + dst[x] = hb_packed_t ((uint32_t) hb_raster_div255 (b * a) + | ((uint32_t) hb_raster_div255 (g * a) << 8) + | ((uint32_t) hb_raster_div255 (r * a) << 16) + | ((uint32_t) a << 24)); + } + } + + hb_swap (buffer, decoded.buffer); + hb_swap (this->extents, decoded.extents); + hb_swap (format, decoded.format); + return true; +#endif +} + +hb_blob_t * +hb_raster_image_t::serialize_to_png_or_fail () const +{ +#ifndef HAVE_PNG + return nullptr; +#else + if (format != HB_RASTER_FORMAT_BGRA32 || !extents.width || !extents.height) + return nullptr; + + png_structp png = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, + hb_raster_png_error, + hb_raster_png_warning); + if (!png) + return nullptr; + + png_infop info = png_create_info_struct (png); + if (!info) + { + png_destroy_write_struct (&png, nullptr); + return nullptr; + } + + hb_raster_png_write_blob_t writer; + hb_vector_t rgba; + hb_vector_t rows; + if (setjmp (png_jmpbuf (png))) + { + png_destroy_write_struct (&png, &info); + writer.data.fini (); + rgba.fini (); + rows.fini (); + return nullptr; + } + + png_set_write_fn (png, &writer, hb_raster_png_write_blob, hb_raster_png_flush_blob); + png_set_IHDR (png, info, + extents.width, extents.height, + 8, PNG_COLOR_TYPE_RGBA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + png_write_info (png, info); + + size_t rowbytes = (size_t) extents.width * 4u; + size_t rgba_size = rowbytes * (size_t) extents.height; + if (extents.height && rgba_size / (size_t) extents.height != rowbytes) + { + png_destroy_write_struct (&png, &info); + return nullptr; + } + + if (!rgba.resize (rgba_size)) + { + png_destroy_write_struct (&png, &info); + return nullptr; + } + + if (!rows.resize (extents.height)) + { + png_destroy_write_struct (&png, &info); + return nullptr; + } + + for (unsigned y = 0; y < extents.height; y++) + { + uint8_t *dst = rgba.arrayZ + (size_t) y * rowbytes; + const uint8_t *src = buffer.arrayZ + (size_t) (extents.height - 1 - y) * extents.stride; + + for (unsigned x = 0; x < extents.width; x++) + { + uint32_t px; + hb_memcpy (&px, src + x * 4, 4); + uint8_t b = (uint8_t) (px & 0xFF); + uint8_t g = (uint8_t) ((px >> 8) & 0xFF); + uint8_t r = (uint8_t) ((px >> 16) & 0xFF); + uint8_t a = (uint8_t) (px >> 24); + + dst[4 * x + 3] = a; + if (a) + { + dst[4 * x + 0] = (uint8_t) hb_min (255u, ((unsigned) r * 255u + a / 2u) / a); + dst[4 * x + 1] = (uint8_t) hb_min (255u, ((unsigned) g * 255u + a / 2u) / a); + dst[4 * x + 2] = (uint8_t) hb_min (255u, ((unsigned) b * 255u + a / 2u) / a); + } + else + dst[4 * x + 0] = dst[4 * x + 1] = dst[4 * x + 2] = 0; + } + + rows[y] = (png_bytep) dst; + } + + png_write_image (png, rows.arrayZ); + png_write_end (png, info); + png_destroy_write_struct (&png, &info); + + unsigned length = 0; + char *data = writer.data.steal (&length); + if (!data && length) + return nullptr; + + hb_blob_t *blob = hb_blob_create_or_fail (data, length, + HB_MEMORY_MODE_WRITABLE, + data, hb_free); + if (!blob) + hb_free (data); + return blob; +#endif +} + +void +hb_raster_image_t::clear () +{ + size_t buf_size = (size_t) extents.stride * extents.height; + hb_memset (buffer.arrayZ, 0, buf_size); +} + +const uint8_t * +hb_raster_image_t::get_buffer () const +{ + return buffer.arrayZ; +} + +void +hb_raster_image_t::composite_from (const hb_raster_image_t *src, + hb_paint_composite_mode_t mode) +{ + unsigned w = extents.width; + unsigned h = extents.height; + unsigned stride = extents.stride; + + for (unsigned y = 0; y < h; y++) + { + hb_packed_t *dp = (hb_packed_t *) (buffer.arrayZ + y * stride); + const hb_packed_t *sp = (const hb_packed_t *) (src->buffer.arrayZ + y * stride); + for (unsigned x = 0; x < w; x++) + dp[x] = hb_packed_t (composite_pixel ((uint32_t) sp[x], (uint32_t) dp[x], mode)); + } +} + +/* Composite src image onto dst image. + * Both images must have the same extents and BGRA32 format. */ +void +hb_raster_image_composite (hb_raster_image_t *dst, + const hb_raster_image_t *src, + hb_paint_composite_mode_t mode) +{ + dst->composite_from (src, mode); +} + +/** + * hb_raster_image_create_or_fail: + * + * Creates a new raster image object. + * + * Return value: (transfer full): + * A newly allocated #hb_raster_image_t with a reference count of 1, + * or `NULL` on allocation failure. + * + * The returned image can be released with hb_raster_image_destroy(), or + * transferred for reuse with hb_raster_draw_recycle_image() or + * hb_raster_paint_recycle_image(). + * + * Since: 13.0.0 + **/ +hb_raster_image_t * +hb_raster_image_create_or_fail (void) +{ + return hb_object_create (); +} + +/** + * hb_raster_image_reference: (skip) + * @image: a raster image + * + * Increases the reference count on @image by one. + * + * This prevents @image from being destroyed until a matching + * call to hb_raster_image_destroy() is made. + * + * Return value: (transfer full): + * The referenced #hb_raster_image_t. + * + * Since: 13.0.0 + **/ +hb_raster_image_t * +hb_raster_image_reference (hb_raster_image_t *image) +{ + return hb_object_reference (image); +} + +/** + * hb_raster_image_destroy: (skip) + * @image: a raster image + * + * Decreases the reference count on @image by one. When the + * reference count reaches zero, the image and its pixel buffer + * are freed. + * + * Since: 13.0.0 + **/ +void +hb_raster_image_destroy (hb_raster_image_t *image) +{ + if (!hb_object_destroy (image)) return; + hb_free (image); +} + +/** + * hb_raster_image_set_user_data: (skip) + * @image: a raster image + * @key: the user-data key + * @data: a pointer to the user data + * @destroy: (nullable): a callback to call when @data is not needed anymore + * @replace: whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified raster image. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_image_set_user_data (hb_raster_image_t *image, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (image, key, data, destroy, replace); +} + +/** + * hb_raster_image_get_user_data: (skip) + * @image: a raster image + * @key: the user-data key + * + * Fetches the user-data associated with the specified key, + * attached to the specified raster image. + * + * Return value: (transfer none): + * A pointer to the user data + * + * Since: 13.0.0 + **/ +void * +hb_raster_image_get_user_data (hb_raster_image_t *image, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (image, key); +} + +/** + * hb_raster_image_configure: + * @image: a raster image + * @format: the pixel format + * @extents: (nullable): desired image extents + * + * Configures @image format and extents together, resizing backing storage + * at most once. This function does not clear pixel contents. + * + * Passing `NULL` for @extents clears extents and releases the backing + * allocation. + * + * Return value: `true` if configuration succeeds, `false` on allocation + * failure + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_image_configure (hb_raster_image_t *image, + hb_raster_format_t format, + const hb_raster_extents_t *extents) +{ + if (unlikely (!extents)) + { + image->extents = {}; + image->buffer.resize_exact (0); + return true; + } + return image->configure (format, *extents); +} + +/** + * hb_raster_image_clear: + * @image: a raster image + * + * Clears @image pixels to zero while keeping current extents and format. + * + * Since: 13.0.0 + **/ +void +hb_raster_image_clear (hb_raster_image_t *image) +{ + image->clear (); +} + +/** + * hb_raster_image_get_buffer: + * @image: a raster image + * + * Fetches the raw pixel buffer of @image. The buffer layout is + * described by the extents obtained from hb_raster_image_get_extents() + * and the format from hb_raster_image_get_format(). Rows are stored + * bottom-to-top. + * + * Return value: (transfer none) (array): + * The pixel buffer, or `NULL` + * + * Since: 13.0.0 + **/ +const uint8_t * +hb_raster_image_get_buffer (hb_raster_image_t *image) +{ + return image->get_buffer (); +} + +/** + * hb_raster_image_get_extents: + * @image: a raster image + * @extents: (out) (nullable): the image extents + * + * Fetches the pixel-buffer extents of @image. + * + * Since: 13.0.0 + **/ +void +hb_raster_image_get_extents (hb_raster_image_t *image, + hb_raster_extents_t *extents) +{ + if (extents) + *extents = image->extents; +} + +/** + * hb_raster_image_get_format: + * @image: a raster image + * + * Fetches the pixel format of @image. + * + * Return value: + * The #hb_raster_format_t of the image + * + * Since: 13.0.0 + **/ +hb_raster_format_t +hb_raster_image_get_format (hb_raster_image_t *image) +{ + return image->format; +} + +/** + * hb_raster_image_deserialize_from_png_or_fail: + * @image: a raster image + * @png: PNG data + * + * Replaces @image contents by deserializing a PNG blob into a + * #HB_RASTER_FORMAT_BGRA32 raster image. + * + * On success, @image extents are reset to pixel extents with origin + * `(0, 0)`. Rows in the resulting image buffer are stored bottom-to-top. + * On failure, @image is left unchanged. + * + * Return value: `true` if deserialization succeeded, `false` otherwise + * + * Since: 13.1.0 + **/ +hb_bool_t +hb_raster_image_deserialize_from_png_or_fail (hb_raster_image_t *image, + hb_blob_t *png) +{ + return image->deserialize_from_png (png); +} + +/** + * hb_raster_image_serialize_to_png_or_fail: + * @image: a raster image + * + * Serializes @image to a PNG blob. + * + * Currently only #HB_RASTER_FORMAT_BGRA32 images are supported. + * + * Return value: (transfer full): + * A newly allocated PNG #hb_blob_t, or `NULL` on failure + * + * Since: 13.1.0 + **/ +hb_blob_t * +hb_raster_image_serialize_to_png_or_fail (hb_raster_image_t *image) +{ + return image->serialize_to_png_or_fail (); +} diff --git a/thirdparty/harfbuzz/upstream/hb-raster-image.hh b/thirdparty/harfbuzz/upstream/hb-raster-image.hh new file mode 100644 index 000000000..d2e81ba10 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-image.hh @@ -0,0 +1,63 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_IMAGE_HH +#define HB_RASTER_IMAGE_HH + +#include "hb.hh" +#include "hb-raster-utils.hh" +#include "hb-raster.h" +#include "hb-object.hh" +#include "hb-vector.hh" + + +/* hb_raster_image_t — pixel artifact */ +struct hb_raster_image_t +{ + hb_object_header_t header; + + hb_vector_t buffer; + hb_raster_extents_t extents = {}; + hb_raster_format_t format = HB_RASTER_FORMAT_A8; + + HB_INTERNAL static unsigned bytes_per_pixel (hb_raster_format_t format); + HB_INTERNAL bool configure (hb_raster_format_t format, hb_raster_extents_t extents); + HB_INTERNAL bool deserialize_from_png (hb_blob_t *png); + HB_INTERNAL hb_blob_t *serialize_to_png_or_fail () const; + HB_INTERNAL void clear (); + HB_INTERNAL const uint8_t *get_buffer () const; + HB_INTERNAL void composite_from (const hb_raster_image_t *src, + hb_paint_composite_mode_t mode); +}; + +/* Composite src image onto dst. */ +HB_INTERNAL void +hb_raster_image_composite (hb_raster_image_t *dst, + const hb_raster_image_t *src, + hb_paint_composite_mode_t mode); + + +#endif /* HB_RASTER_IMAGE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-paint.cc b/thirdparty/harfbuzz/upstream/hb-raster-paint.cc new file mode 100644 index 000000000..84657cdd6 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-paint.cc @@ -0,0 +1,2253 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-raster-paint.hh" +#include "hb-raster-svg.hh" +#include "hb-machinery.hh" + +#include + + +/* + * Pixel helpers (paint-specific) + */ + +/* Convert unpremultiplied hb_color_t (BGRA order) to premultiplied BGRA32 pixel. */ +static inline uint32_t +color_to_premul_pixel (hb_color_t color) +{ + uint8_t a = hb_color_get_alpha (color); + uint8_t r = hb_raster_div255 (hb_color_get_red (color) * a); + uint8_t g = hb_raster_div255 (hb_color_get_green (color) * a); + uint8_t b = hb_raster_div255 (hb_color_get_blue (color) * a); + return (uint32_t) b | ((uint32_t) g << 8) | ((uint32_t) r << 16) | ((uint32_t) a << 24); +} + +/* Bilinear sample from a premultiplied BGRA32 image. */ +static inline uint32_t +hb_raster_sample_bilinear_premul (const hb_packed_t *src, + unsigned width, + unsigned height, + float x, + float y) +{ + int x0 = (int) floorf (x); + int y0 = (int) floorf (y); + int x1 = x0 + 1; + int y1 = y0 + 1; + if (x1 >= (int) width) x1 = (int) width - 1; + if (y1 >= (int) height) y1 = (int) height - 1; + + float tx = x - x0; + float ty = y - y0; + float omtx = 1.f - tx; + float omty = 1.f - ty; + + uint32_t p00 = (uint32_t) src[(size_t) y0 * width + (size_t) x0]; + uint32_t p10 = (uint32_t) src[(size_t) y0 * width + (size_t) x1]; + uint32_t p01 = (uint32_t) src[(size_t) y1 * width + (size_t) x0]; + uint32_t p11 = (uint32_t) src[(size_t) y1 * width + (size_t) x1]; + + float w00 = omtx * omty; + float w10 = tx * omty; + float w01 = omtx * ty; + float w11 = tx * ty; + + float b = ((p00 >> 0) & 0xff) * w00 + ((p10 >> 0) & 0xff) * w10 + + ((p01 >> 0) & 0xff) * w01 + ((p11 >> 0) & 0xff) * w11; + float g = ((p00 >> 8) & 0xff) * w00 + ((p10 >> 8) & 0xff) * w10 + + ((p01 >> 8) & 0xff) * w01 + ((p11 >> 8) & 0xff) * w11; + float r = ((p00 >> 16) & 0xff) * w00 + ((p10 >> 16) & 0xff) * w10 + + ((p01 >> 16) & 0xff) * w01 + ((p11 >> 16) & 0xff) * w11; + float a = ((p00 >> 24) & 0xff) * w00 + ((p10 >> 24) & 0xff) * w10 + + ((p01 >> 24) & 0xff) * w01 + ((p11 >> 24) & 0xff) * w11; + + return (uint32_t) (b + 0.5f) + | ((uint32_t) (g + 0.5f) << 8) + | ((uint32_t) (r + 0.5f) << 16) + | ((uint32_t) (a + 0.5f) << 24); +} + + +/* + * Paint callbacks + */ + +/* Lazy initialization: set up root surface, initial clip and transform. + * Called from every paint callback that needs state. + * hb_font_paint_glyph() does NOT wrap with push/pop_transform, + * so the first callback could be push_clip_glyph or paint_color. */ +static void +ensure_initialized (hb_raster_paint_t *c) +{ + if (c->surface_stack.length) return; + + /* Root surface */ + hb_raster_image_t *root = c->acquire_surface (); + if (unlikely (!root)) return; + if (unlikely (!c->surface_stack.push_or_fail (root))) + { + c->release_surface (root); + return; + } + + /* Initial transform */ + if (unlikely (!c->transform_stack.push_or_fail (c->base_transform))) + { + c->release_surface (c->surface_stack.pop ()); + return; + } + + /* Initial clip: full coverage rectangle */ + hb_raster_clip_t clip; + clip.init_full (c->fixed_extents.width, c->fixed_extents.height); + if (unlikely (!c->clip_stack.push_or_fail (std::move (clip)))) + { + c->transform_stack.pop (); + c->release_surface (c->surface_stack.pop ()); + return; + } +} + +static void +hb_raster_paint_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + float xx, float yx, + float xy, float yy, + float dx, float dy, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + if (unlikely (!c->transform_stack.length)) return; + + hb_transform_t<> t = c->current_transform (); + t.multiply ({xx, yx, xy, yy, dx, dy}); + (void) c->transform_stack.push (t); +} + +static void +hb_raster_paint_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + c->transform_stack.pop (); +} + +static hb_bool_t +hb_raster_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_font_t *font HB_UNUSED, + void *user_data HB_UNUSED) +{ + return false; +} + +typedef void (*hb_raster_paint_clip_mask_emit_t) (hb_raster_draw_t *rdr, void *user_data); + +static void +hb_raster_paint_push_empty_clip (hb_raster_paint_t *c, unsigned w, unsigned h) +{ + hb_raster_clip_t new_clip = c->acquire_clip (w, h); + new_clip.init_full (w, h); + new_clip.is_rect = true; + new_clip.rect_x0 = new_clip.rect_y0 = 0; + new_clip.rect_x1 = new_clip.rect_y1 = 0; + new_clip.min_x = new_clip.min_y = new_clip.max_x = new_clip.max_y = 0; + (void) c->clip_stack.push (std::move (new_clip)); +} + +static void +hb_raster_paint_push_clip_from_emitter (hb_raster_paint_t *c, + hb_raster_paint_clip_mask_emit_t emit, + void *emit_data) +{ + ensure_initialized (c); + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return; + + unsigned w = surf->extents.width; + unsigned h = surf->extents.height; + + hb_raster_clip_t new_clip = c->acquire_clip (w, h); + + hb_raster_draw_t *rdr = c->clip_rdr; + hb_transform_t<> t = c->current_effective_transform (); + hb_raster_draw_set_transform (rdr, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0); + emit (rdr, emit_data); + hb_raster_image_t *mask_img = hb_raster_draw_render (rdr); + + if (unlikely (!mask_img)) + { + hb_raster_paint_push_empty_clip (c, w, h); + return; + } + + /* Allocate alpha buffer and intersect with previous clip */ + size_t clip_size = (size_t) new_clip.stride * h; + if (unlikely (clip_size > HB_RASTER_MAX_BUFFER_SIZE || + !new_clip.alpha.resize ((unsigned) clip_size))) + { + hb_raster_draw_recycle_image (rdr, mask_img); + hb_raster_paint_push_empty_clip (c, w, h); + return; + } + + const uint8_t *mask_buf = hb_raster_image_get_buffer (mask_img); + hb_raster_extents_t mask_ext; + hb_raster_image_get_extents (mask_img, &mask_ext); + const hb_raster_clip_t &old_clip = c->current_clip (); + + /* Convert mask extents from surface coordinates to clip-buffer coordinates. */ + int mask_x0 = mask_ext.x_origin - surf->extents.x_origin; + int mask_y0 = mask_ext.y_origin - surf->extents.y_origin; + int mask_x1 = mask_x0 + (int) mask_ext.width; + int mask_y1 = mask_y0 + (int) mask_ext.height; + + int ix0_i = hb_max ((int) old_clip.min_x, hb_max (mask_x0, 0)); + int iy0_i = hb_max ((int) old_clip.min_y, hb_max (mask_y0, 0)); + int ix1_i = hb_min ((int) old_clip.max_x, hb_min (mask_x1, (int) w)); + int iy1_i = hb_min ((int) old_clip.max_y, hb_min (mask_y1, (int) h)); + + if (ix0_i >= ix1_i || iy0_i >= iy1_i) + { + hb_raster_draw_recycle_image (rdr, mask_img); + hb_raster_paint_push_empty_clip (c, w, h); + return; + } + + unsigned ix0 = (unsigned) ix0_i; + unsigned iy0 = (unsigned) iy0_i; + unsigned ix1 = (unsigned) ix1_i; + unsigned iy1 = (unsigned) iy1_i; + + new_clip.min_x = w; new_clip.min_y = h; + new_clip.max_x = 0; new_clip.max_y = 0; + + if (old_clip.is_rect) + { + for (unsigned y = iy0; y < iy1; y++) + { + const uint8_t *mask_row = mask_buf + (unsigned) ((int) y - mask_y0) * mask_ext.stride; + uint8_t *out_row = new_clip.alpha.arrayZ + y * new_clip.stride; + unsigned row_min = ix1; + unsigned row_max = ix0; + unsigned mx = (unsigned) ((int) ix0 - mask_x0); + for (unsigned x = ix0; x < ix1; x++) + { + uint8_t a = mask_row[mx++]; + out_row[x] = a; + if (a && row_min == ix1) + { + row_min = x; + row_max = x + 1; + } + else if (a) + row_max = x + 1; + } + if (row_min < row_max) + { + new_clip.min_x = hb_min (new_clip.min_x, row_min); + new_clip.min_y = hb_min (new_clip.min_y, y); + new_clip.max_x = hb_max (new_clip.max_x, row_max); + new_clip.max_y = hb_max (new_clip.max_y, y + 1); + } + } + } + else + { + for (unsigned y = iy0; y < iy1; y++) + { + const uint8_t *old_row = old_clip.alpha.arrayZ + y * old_clip.stride; + const uint8_t *mask_row = mask_buf + (unsigned) ((int) y - mask_y0) * mask_ext.stride; + uint8_t *out_row = new_clip.alpha.arrayZ + y * new_clip.stride; + unsigned row_min = ix1; + unsigned row_max = ix0; + for (unsigned x = ix0; x < ix1; x++) + { + unsigned mx = (unsigned) ((int) x - mask_x0); + uint8_t a = hb_raster_div255 (mask_row[mx] * old_row[x]); + out_row[x] = a; + if (a) + { + row_min = hb_min (row_min, x); + row_max = x + 1; + } + } + if (row_min < row_max) + { + new_clip.min_x = hb_min (new_clip.min_x, row_min); + new_clip.min_y = hb_min (new_clip.min_y, y); + new_clip.max_x = hb_max (new_clip.max_x, row_max); + new_clip.max_y = hb_max (new_clip.max_y, y + 1); + } + } + } + + hb_raster_draw_recycle_image (rdr, mask_img); + if (unlikely (!c->clip_stack.push_or_fail (std::move (new_clip)))) + hb_raster_paint_push_empty_clip (c, w, h); +} + +struct hb_raster_paint_glyph_clip_data_t +{ + hb_codepoint_t glyph; + hb_font_t *font; +}; + +static void +hb_raster_paint_emit_clip_glyph_mask (hb_raster_draw_t *rdr, void *user_data) +{ + hb_raster_paint_glyph_clip_data_t *data = (hb_raster_paint_glyph_clip_data_t *) user_data; + /* Let draw-render choose tight glyph extents; we map by mask origin below. */ + hb_font_draw_glyph (data->font, data->glyph, hb_raster_draw_get_funcs (), rdr); +} + +static void +hb_raster_paint_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + hb_raster_paint_glyph_clip_data_t data = {glyph, font}; + hb_raster_paint_push_clip_from_emitter (c, hb_raster_paint_emit_clip_glyph_mask, &data); +} + +/* Push clip from arbitrary path emitter (used by SVG rasterizer). + * Identical to push_clip_glyph but calls user func instead of hb_font_draw_glyph. */ +struct hb_raster_paint_path_clip_data_t +{ + hb_raster_svg_path_func_t func; + void *user_data; +}; + +static void +hb_raster_paint_emit_clip_path_mask (hb_raster_draw_t *rdr, void *user_data) +{ + hb_raster_paint_path_clip_data_t *data = (hb_raster_paint_path_clip_data_t *) user_data; + data->func (hb_raster_draw_get_funcs (), rdr, data->user_data); +} + +void +hb_raster_paint_push_clip_path (hb_raster_paint_t *c, + hb_raster_svg_path_func_t func, + void *user_data) +{ + hb_raster_paint_path_clip_data_t data = {func, user_data}; + hb_raster_paint_push_clip_from_emitter (c, hb_raster_paint_emit_clip_path_mask, &data); +} + +static void +hb_raster_paint_push_clip_rectangle (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + float xmin, float ymin, + float xmax, float ymax, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + if (!c->surface_stack.length) return; + + hb_transform_t<> t = c->current_effective_transform (); + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return; + + unsigned w = surf->extents.width; + unsigned h = surf->extents.height; + bool is_axis_aligned = (t.xy == 0.f && t.yx == 0.f); + + /* Transform the four corners to pixel space */ + float cx[4], cy[4]; + cx[0] = xmin; cy[0] = ymin; + cx[1] = xmax; cy[1] = ymin; + cx[2] = xmax; cy[2] = ymax; + cx[3] = xmin; cy[3] = ymax; + for (unsigned i = 0; i < 4; i++) + t.transform_point (cx[i], cy[i]); + + /* Compute bounding box in pixel coords */ + float fmin_x = cx[0], fmin_y = cy[0], fmax_x = cx[0], fmax_y = cy[0]; + for (unsigned i = 1; i < 4; i++) + { + fmin_x = hb_min (fmin_x, cx[i]); fmin_y = hb_min (fmin_y, cy[i]); + fmax_x = hb_max (fmax_x, cx[i]); fmax_y = hb_max (fmax_y, cy[i]); + } + + int px0 = (int) floorf (fmin_x) - surf->extents.x_origin; + int py0 = (int) floorf (fmin_y) - surf->extents.y_origin; + int px1 = (int) ceilf (fmax_x) - surf->extents.x_origin; + int py1 = (int) ceilf (fmax_y) - surf->extents.y_origin; + + /* Clamp to surface bounds */ + px0 = hb_max (px0, 0); + py0 = hb_max (py0, 0); + px1 = hb_min (px1, (int) w); + py1 = hb_min (py1, (int) h); + + const hb_raster_clip_t &old_clip = c->current_clip (); + + hb_raster_clip_t new_clip = c->acquire_clip (w, h); + + if (is_axis_aligned && old_clip.is_rect) + { + /* Fast path: axis-aligned rect-on-rect intersection */ + new_clip.is_rect = true; + new_clip.rect_x0 = hb_max (px0, old_clip.rect_x0); + new_clip.rect_y0 = hb_max (py0, old_clip.rect_y0); + new_clip.rect_x1 = hb_min (px1, old_clip.rect_x1); + new_clip.rect_y1 = hb_min (py1, old_clip.rect_y1); + new_clip.update_bounds_from_rect (); + } + else + { + /* General case: rasterize transformed quad as alpha mask */ + new_clip.is_rect = false; + size_t clip_size = (size_t) new_clip.stride * h; + if (unlikely (clip_size > HB_RASTER_MAX_BUFFER_SIZE || + !new_clip.alpha.resize ((unsigned) clip_size))) + { + hb_raster_paint_push_empty_clip (c, w, h); + return; + } + hb_memset (new_clip.alpha.arrayZ, 0, (unsigned) clip_size); + + /* Convert quad corners to pixel-relative coords */ + float qx[4], qy[4]; + int ox = surf->extents.x_origin; + int oy = surf->extents.y_origin; + for (unsigned i = 0; i < 4; i++) + { + qx[i] = cx[i] - ox; + qy[i] = cy[i] - oy; + } + + /* For each pixel in the bounding box, test if inside the quad + * using cross-product edge tests (winding order). */ + unsigned iy0 = (unsigned) hb_max (py0, (int) old_clip.min_y); + unsigned iy1 = (unsigned) hb_min (py1, (int) old_clip.max_y); + unsigned ix0 = (unsigned) hb_max (px0, (int) old_clip.min_x); + unsigned ix1 = (unsigned) hb_min (px1, (int) old_clip.max_x); + new_clip.min_x = w; new_clip.min_y = h; + new_clip.max_x = 0; new_clip.max_y = 0; + + /* Precompute edge normals for point-in-quad test. + * Edge i goes from corner i to corner (i+1)%4. + * Normal = (dy, -dx); inside test: dot(normal, p-corner) >= 0 */ + float enx[4], eny[4], ed[4]; + for (unsigned i = 0; i < 4; i++) + { + unsigned j = (i + 1) & 3; + float edx = qx[j] - qx[i], edy = qy[j] - qy[i]; + enx[i] = edy; /* normal x */ + eny[i] = -edx; /* normal y */ + ed[i] = enx[i] * qx[i] + eny[i] * qy[i]; /* distance threshold */ + } + float area2 = 0.f; + for (unsigned i = 0; i < 4; i++) + { + unsigned j = (i + 1) & 3; + area2 += qx[i] * qy[j] - qx[j] * qy[i]; + } + bool ccw = area2 >= 0.f; + + if (old_clip.is_rect) + { + for (unsigned y = iy0; y < iy1; y++) + for (unsigned x = ix0; x < ix1; x++) + { + float px_f = x + 0.5f, py_f = y + 0.5f; + /* Test if pixel center is inside the quad */ + bool inside = true; + for (unsigned i = 0; i < 4; i++) + { + float d = enx[i] * px_f + eny[i] * py_f; + if (ccw ? d < ed[i] : d > ed[i]) + { + inside = false; + break; + } + } + uint8_t a = inside ? 255 : 0; + new_clip.alpha[y * new_clip.stride + x] = a; + if (a) + { + new_clip.min_x = hb_min (new_clip.min_x, x); + new_clip.min_y = hb_min (new_clip.min_y, y); + new_clip.max_x = hb_max (new_clip.max_x, x + 1); + new_clip.max_y = hb_max (new_clip.max_y, y + 1); + } + } + } + else + { + for (unsigned y = iy0; y < iy1; y++) + { + const uint8_t *old_row = old_clip.alpha.arrayZ + y * old_clip.stride; + for (unsigned x = ix0; x < ix1; x++) + { + float px_f = x + 0.5f, py_f = y + 0.5f; + /* Test if pixel center is inside the quad */ + bool inside = true; + for (unsigned i = 0; i < 4; i++) + { + float d = enx[i] * px_f + eny[i] * py_f; + if (ccw ? d < ed[i] : d > ed[i]) + { + inside = false; + break; + } + } + uint8_t a = inside ? old_row[x] : 0; + new_clip.alpha[y * new_clip.stride + x] = a; + if (a) + { + new_clip.min_x = hb_min (new_clip.min_x, x); + new_clip.min_y = hb_min (new_clip.min_y, y); + new_clip.max_x = hb_max (new_clip.max_x, x + 1); + new_clip.max_y = hb_max (new_clip.max_y, y + 1); + } + } + } + } + } + + if (unlikely (!c->clip_stack.push_or_fail (std::move (new_clip)))) + hb_raster_paint_push_empty_clip (c, surf->extents.width, surf->extents.height); +} + +static void +hb_raster_paint_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + if (!c->clip_stack.length) return; + c->release_clip (c->clip_stack.pop ()); +} + +static void +hb_raster_paint_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + hb_raster_image_t *new_surf = c->acquire_surface (); + if (unlikely (!new_surf)) return; + if (unlikely (!c->surface_stack.push_or_fail (new_surf))) + c->release_surface (new_surf); +} + +static void +hb_raster_paint_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_paint_composite_mode_t mode, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + if (c->surface_stack.length < 2) return; + + hb_raster_image_t *src = c->surface_stack.pop (); + hb_raster_image_t *dst = c->current_surface (); + + if (dst && src) + hb_raster_image_composite (dst, src, mode); + + c->release_surface (src); +} + +static void +hb_raster_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_bool_t is_foreground, + hb_color_t color, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return; + + if (is_foreground) + { + /* Use foreground color, modulating alpha */ + color = HB_COLOR (hb_color_get_blue (c->foreground), + hb_color_get_green (c->foreground), + hb_color_get_red (c->foreground), + hb_raster_div255 (hb_color_get_alpha (c->foreground) * + hb_color_get_alpha (color))); + } + + uint32_t premul = color_to_premul_pixel (color); + uint8_t premul_a = (uint8_t) (premul >> 24); + const hb_raster_clip_t &clip = c->current_clip (); + + unsigned stride = surf->extents.stride; + if (clip.min_x >= clip.max_x || clip.min_y >= clip.max_y) return; + if (premul_a == 0) return; + + if (likely (!clip.is_rect)) + { + for (unsigned y = clip.min_y; y < clip.max_y; y++) + { + hb_packed_t *__restrict row = (hb_packed_t *) (surf->buffer.arrayZ + y * stride); + const uint8_t *__restrict clip_row = clip.alpha.arrayZ + y * clip.stride; + for (unsigned x = clip.min_x; x < clip.max_x; x++) + { + uint8_t clip_alpha = clip_row[x]; + if (clip_alpha == 0) continue; + if (clip_alpha == 255) + { + if (premul_a == 255) + row[x] = hb_packed_t (premul); + else + row[x] = hb_packed_t (hb_raster_src_over (premul, (uint32_t) row[x])); + } + else + { + uint32_t src = hb_raster_alpha_mul (premul, clip_alpha); + row[x] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[x])); + } + } + } + } + else + { + for (unsigned y = clip.min_y; y < clip.max_y; y++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + y * stride); + for (unsigned x = clip.min_x; x < clip.max_x; x++) + row[x] = hb_packed_t (hb_raster_src_over (premul, (uint32_t) row[x])); + } + } +} + +static hb_bool_t +hb_raster_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_blob_t *blob, + unsigned width, + unsigned height, + hb_tag_t format, + float slant HB_UNUSED, + hb_glyph_extents_t *extents, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + /* Handle SVG format */ + if (format == HB_PAINT_IMAGE_FORMAT_SVG) + return hb_raster_svg_render (c, blob, c->svg_glyph, c->svg_font, + c->svg_palette, c->foreground); + + unsigned src_width = width; + unsigned src_height = height; + const hb_packed_t *src_data = nullptr; + hb_raster_image_t decoded_png; + + if (format == HB_PAINT_IMAGE_FORMAT_BGRA) + { + if (src_width == 0 || src_height == 0) + return false; + if (src_width > (unsigned) INT_MAX || src_height > (unsigned) INT_MAX) + return false; + + unsigned data_len; + const uint8_t *data = (const uint8_t *) hb_blob_get_data (blob, &data_len); + size_t pixel_count = (size_t) src_width * (size_t) src_height; + if (src_width && pixel_count / src_width != src_height) + return false; + if (pixel_count > (size_t) -1 / 4u) + return false; + size_t required_size = pixel_count * 4u; + if (!data || (size_t) data_len < required_size) + return false; + + src_data = (const hb_packed_t *) data; + } + else if (format == HB_PAINT_IMAGE_FORMAT_PNG) + { +#ifdef HAVE_PNG + if (!decoded_png.deserialize_from_png (blob)) + return false; + src_width = decoded_png.extents.width; + src_height = decoded_png.extents.height; + src_data = (const hb_packed_t *) decoded_png.buffer.arrayZ; +#else + return false; +#endif + } + else + return false; + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return false; + if (!extents) return false; + + const hb_raster_clip_t &clip = c->current_clip (); + hb_transform_t<> t = c->current_effective_transform (); + + /* Compute inverse transform for sampling */ + float det = t.xx * t.yy - t.xy * t.yx; + if (fabsf (det) < 1e-10f) return false; + float inv_det = 1.f / det; + float inv_xx = t.yy * inv_det; + float inv_xy = -t.xy * inv_det; + float inv_yx = -t.yx * inv_det; + float inv_yy = t.xx * inv_det; + float inv_x0 = (t.xy * t.y0 - t.yy * t.x0) * inv_det; + float inv_y0 = (t.yx * t.x0 - t.xx * t.y0) * inv_det; + + unsigned surf_stride = surf->extents.stride; + int ox = surf->extents.x_origin; + int oy = surf->extents.y_origin; + + /* Image source rectangle in glyph space */ + float img_x = extents->x_bearing; + float img_y = extents->y_bearing; + float img_sx = (float) extents->width / src_width; + float img_sy = (float) extents->height / src_height; + if (fabsf (img_sx) < 1e-10f || fabsf (img_sy) < 1e-10f) + return false; + + if (clip.is_rect) + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * surf_stride); + float gx = inv_xx * (float) ((int) clip.min_x + ox) + inv_xy * (float) ((int) py + oy) + inv_x0; + float gy = inv_yx * (float) ((int) clip.min_x + ox) + inv_yy * (float) ((int) py + oy) + inv_y0; + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + /* Map glyph space to image texel; bilinear reconstruction. */ + float ix = (gx - img_x) / img_sx; + float iy = (float) (src_height - 1) - (gy - img_y) / img_sy; + + if (ix < 0.f || iy < 0.f || + ix > (float) (src_width - 1) || iy > (float) (src_height - 1)) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + + uint32_t src_px = hb_raster_sample_bilinear_premul (src_data, src_width, src_height, + ix, iy); + row[px] = hb_packed_t (hb_raster_src_over (src_px, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + else + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * surf_stride); + const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride; + float gx = inv_xx * (float) ((int) clip.min_x + ox) + inv_xy * (float) ((int) py + oy) + inv_x0; + float gy = inv_yx * (float) ((int) clip.min_x + ox) + inv_yy * (float) ((int) py + oy) + inv_y0; + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + + /* Map glyph space to image texel; bilinear reconstruction. */ + float ix = (gx - img_x) / img_sx; + float iy = (float) (src_height - 1) - (gy - img_y) / img_sy; + + if (ix < 0.f || iy < 0.f || + ix > (float) (src_width - 1) || iy > (float) (src_height - 1)) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + + uint32_t src_px = hb_raster_sample_bilinear_premul (src_data, src_width, src_height, + ix, iy); + src_px = hb_raster_alpha_mul (src_px, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src_px, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + + return true; +} + + +/* + * Gradient helpers + */ + +#define PREALLOCATED_COLOR_STOPS 16 +#define GRADIENT_LUT_SIZE 256 +#define GRADIENT_LUT_MIN_PIXELS (64u * 64u) + +static int +cmp_color_stop (const void *p1, const void *p2) +{ + const hb_color_stop_t *c1 = (const hb_color_stop_t *) p1; + const hb_color_stop_t *c2 = (const hb_color_stop_t *) p2; + if (c1->offset < c2->offset) return -1; + if (c1->offset > c2->offset) return 1; + return 0; +} + +static bool +get_color_stops (hb_raster_paint_t *c, + hb_color_line_t *color_line, + unsigned *count, + hb_color_stop_t **stops) +{ + unsigned len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr); + if (len > *count) + { + if (unlikely (!c->scratch_color_stops.resize (len))) + return false; + *stops = c->scratch_color_stops.arrayZ; + } + hb_color_line_get_color_stops (color_line, 0, &len, *stops); + for (unsigned i = 0; i < len; i++) + if ((*stops)[i].is_foreground) + (*stops)[i].color = HB_COLOR (hb_color_get_blue (c->foreground), + hb_color_get_green (c->foreground), + hb_color_get_red (c->foreground), + hb_raster_div255 (hb_color_get_alpha (c->foreground) * + hb_color_get_alpha ((*stops)[i].color))); + + *count = len; + return true; +} + +static void +normalize_color_line (hb_color_stop_t *stops, + unsigned len, + float *omin, float *omax) +{ + hb_qsort (stops, len, sizeof (hb_color_stop_t), cmp_color_stop); + + float mn = stops[0].offset, mx = stops[0].offset; + for (unsigned i = 1; i < len; i++) + { + mn = hb_min (mn, stops[i].offset); + mx = hb_max (mx, stops[i].offset); + } + if (mn != mx) + for (unsigned i = 0; i < len; i++) + stops[i].offset = (stops[i].offset - mn) / (mx - mn); + + *omin = mn; + *omax = mx; +} + +/* Evaluate color at normalized position t, interpolating in premultiplied space. */ +static uint32_t +evaluate_color_line (const hb_color_stop_t *stops, unsigned len, float t, + hb_paint_extend_t extend) +{ + /* Apply extend mode */ + if (extend == HB_PAINT_EXTEND_PAD) + { + t = hb_clamp (t, 0.f, 1.f); + } + else if (extend == HB_PAINT_EXTEND_REPEAT) + { + t = t - floorf (t); + } + else /* REFLECT */ + { + if (t < 0) t = -t; + int period = (int) floorf (t); + float frac = t - (float) period; + t = (period & 1) ? 1.f - frac : frac; + } + + /* Find bounding stops */ + if (t <= stops[0].offset) + return color_to_premul_pixel (stops[0].color); + if (t >= stops[len - 1].offset) + return color_to_premul_pixel (stops[len - 1].color); + + unsigned i; + for (i = 0; i < len - 1; i++) + if (t < stops[i + 1].offset) + break; + + float range = stops[i + 1].offset - stops[i].offset; + float k = range > 0.f ? (t - stops[i].offset) / range : 0.f; + + /* Interpolate in premultiplied [0,255] space */ + hb_color_t c0 = stops[i].color; + hb_color_t c1 = stops[i + 1].color; + + float a0 = hb_color_get_alpha (c0) / 255.f; + float r0 = hb_color_get_red (c0) / 255.f * a0; + float g0 = hb_color_get_green (c0) / 255.f * a0; + float b0 = hb_color_get_blue (c0) / 255.f * a0; + + float a1 = hb_color_get_alpha (c1) / 255.f; + float r1 = hb_color_get_red (c1) / 255.f * a1; + float g1 = hb_color_get_green (c1) / 255.f * a1; + float b1 = hb_color_get_blue (c1) / 255.f * a1; + + float a = a0 + k * (a1 - a0); + float r = r0 + k * (r1 - r0); + float g = g0 + k * (g1 - g0); + float b = b0 + k * (b1 - b0); + + uint8_t pa = (uint8_t) (a * 255.f + 0.5f); + uint8_t pr = (uint8_t) (r * 255.f + 0.5f); + uint8_t pg = (uint8_t) (g * 255.f + 0.5f); + uint8_t pb = (uint8_t) (b * 255.f + 0.5f); + + return (uint32_t) pb | ((uint32_t) pg << 8) | ((uint32_t) pr << 16) | ((uint32_t) pa << 24); +} + +static HB_ALWAYS_INLINE float +normalize_gradient_t (float t, hb_paint_extend_t extend) +{ + if (extend == HB_PAINT_EXTEND_PAD) + return hb_clamp (t, 0.f, 1.f); + if (extend == HB_PAINT_EXTEND_REPEAT) + { + t = t - floorf (t); + return t < 0.f ? t + 1.f : t; + } + + /* REFLECT */ + if (t < 0.f) t = -t; + int period = (int) floorf (t); + float frac = t - (float) period; + return (period & 1) ? 1.f - frac : frac; +} + +static void +build_gradient_lut (const hb_color_stop_t *stops, + unsigned len, + uint32_t *lut) +{ + for (unsigned i = 0; i < GRADIENT_LUT_SIZE; i++) + { + float t = (float) i / (GRADIENT_LUT_SIZE - 1); + lut[i] = evaluate_color_line (stops, len, t, HB_PAINT_EXTEND_PAD); + } +} + +static HB_ALWAYS_INLINE uint32_t +lookup_gradient_lut (const uint32_t *lut, + float t, + hb_paint_extend_t extend) +{ + float u = normalize_gradient_t (t, extend); + unsigned idx = (unsigned) (u * (GRADIENT_LUT_SIZE - 1) + 0.5f); + return lut[idx]; +} + +static void +reduce_anchors (float x0, float y0, + float x1, float y1, + float x2, float y2, + float *xx0, float *yy0, + float *xx1, float *yy1) +{ + float q2x = x2 - x0, q2y = y2 - y0; + float q1x = x1 - x0, q1y = y1 - y0; + float s = q2x * q2x + q2y * q2y; + if (s < 0.000001f) + { + *xx0 = x0; *yy0 = y0; + *xx1 = x1; *yy1 = y1; + return; + } + float k = (q2x * q1x + q2y * q1y) / s; + *xx0 = x0; + *yy0 = y0; + *xx1 = x1 - k * q2x; + *yy1 = y1 - k * q2y; +} + + +/* + * Gradient paint callbacks + */ + +static void +hb_raster_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return; + + unsigned len = PREALLOCATED_COLOR_STOPS; + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; + + if (unlikely (!get_color_stops (c, color_line, &len, &stops))) + return; + float mn, mx; + normalize_color_line (stops, len, &mn, &mx); + + hb_paint_extend_t extend = hb_color_line_get_extend (color_line); + const hb_raster_clip_t &clip = c->current_clip (); + unsigned clip_w = clip.max_x > clip.min_x ? clip.max_x - clip.min_x : 0; + unsigned clip_h = clip.max_y > clip.min_y ? clip.max_y - clip.min_y : 0; + bool use_lut = (uint64_t) clip_w * clip_h >= GRADIENT_LUT_MIN_PIXELS; + uint32_t lut[GRADIENT_LUT_SIZE]; + if (use_lut) + build_gradient_lut (stops, len, lut); + + /* Reduce 3-point anchor to 2-point gradient axis */ + float lx0, ly0, lx1, ly1; + reduce_anchors (x0, y0, x1, y1, x2, y2, &lx0, &ly0, &lx1, &ly1); + + /* Apply normalization to endpoints */ + float gx0 = lx0 + mn * (lx1 - lx0); + float gy0 = ly0 + mn * (ly1 - ly0); + float gx1 = lx0 + mx * (lx1 - lx0); + float gy1 = ly0 + mx * (ly1 - ly0); + + /* Inverse transform: pixel → glyph space */ + hb_transform_t<> t = c->current_effective_transform (); + float det = t.xx * t.yy - t.xy * t.yx; + if (fabsf (det) < 1e-10f) goto done; + + { + float inv_det = 1.f / det; + float inv_xx = t.yy * inv_det; + float inv_xy = -t.xy * inv_det; + float inv_yx = -t.yx * inv_det; + float inv_yy = t.xx * inv_det; + float inv_x0 = (t.xy * t.y0 - t.yy * t.x0) * inv_det; + float inv_y0 = (t.yx * t.x0 - t.xx * t.y0) * inv_det; + + /* Gradient direction vector and denominator for projection */ + float dx = gx1 - gx0, dy = gy1 - gy0; + float denom = dx * dx + dy * dy; + if (denom < 1e-10f) goto done; + float inv_denom = 1.f / denom; + + unsigned stride = surf->extents.stride; + int ox = surf->extents.x_origin; + int oy = surf->extents.y_origin; + + if (clip.is_rect) + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * stride); + float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0; + float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0; + if (use_lut) + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom; + uint32_t src = lookup_gradient_lut (lut, proj_t, extend); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + else + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom; + uint32_t src = evaluate_color_line (stops, len, proj_t, extend); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + } + else + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * stride); + const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride; + float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0; + float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0; + if (use_lut) + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom; + uint32_t src = lookup_gradient_lut (lut, proj_t, extend); + src = hb_raster_alpha_mul (src, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + else + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float proj_t = ((gx - gx0) * dx + (gy - gy0) * dy) * inv_denom; + uint32_t src = evaluate_color_line (stops, len, proj_t, extend); + src = hb_raster_alpha_mul (src, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + } + } + +done: + (void) stops_; +} + +static void +hb_raster_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return; + + unsigned len = PREALLOCATED_COLOR_STOPS; + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; + + if (unlikely (!get_color_stops (c, color_line, &len, &stops))) + return; + float mn, mx; + normalize_color_line (stops, len, &mn, &mx); + + hb_paint_extend_t extend = hb_color_line_get_extend (color_line); + const hb_raster_clip_t &clip = c->current_clip (); + unsigned clip_w = clip.max_x > clip.min_x ? clip.max_x - clip.min_x : 0; + unsigned clip_h = clip.max_y > clip.min_y ? clip.max_y - clip.min_y : 0; + bool use_lut = (uint64_t) clip_w * clip_h >= GRADIENT_LUT_MIN_PIXELS; + uint32_t lut[GRADIENT_LUT_SIZE]; + if (use_lut) + build_gradient_lut (stops, len, lut); + + /* Apply normalization to circle parameters */ + float cx0 = x0 + mn * (x1 - x0); + float cy0 = y0 + mn * (y1 - y0); + float cr0 = r0 + mn * (r1 - r0); + float cx1 = x0 + mx * (x1 - x0); + float cy1 = y0 + mx * (y1 - y0); + float cr1 = r0 + mx * (r1 - r0); + + /* Inverse transform */ + hb_transform_t<> t = c->current_effective_transform (); + float det = t.xx * t.yy - t.xy * t.yx; + if (fabsf (det) < 1e-10f) goto done; + + { + float inv_det = 1.f / det; + float inv_xx = t.yy * inv_det; + float inv_xy = -t.xy * inv_det; + float inv_yx = -t.yx * inv_det; + float inv_yy = t.xx * inv_det; + float inv_x0 = (t.xy * t.y0 - t.yy * t.x0) * inv_det; + float inv_y0 = (t.yx * t.x0 - t.xx * t.y0) * inv_det; + + /* Precompute quadratic coefficients for radial gradient: + * |p - c0 - t*(c1-c0)|^2 = (r0 + t*(r1-r0))^2 + * + * Expanding gives At^2 + Bt + C = 0 where: + * cdx = c1.x - c0.x, cdy = c1.y - c0.y, dr = r1 - r0 + * A = cdx^2 + cdy^2 - dr^2 + * B = -2*(px-c0.x)*cdx - 2*(py-c0.y)*cdy - 2*r0*dr + * C = (px-c0.x)^2 + (py-c0.y)^2 - r0^2 + */ + float cdx = cx1 - cx0, cdy = cy1 - cy0; + float dr = cr1 - cr0; + float A = cdx * cdx + cdy * cdy - dr * dr; + + unsigned stride = surf->extents.stride; + int ox = surf->extents.x_origin; + int oy = surf->extents.y_origin; + + if (clip.is_rect) + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * stride); + float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0; + float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0; + if (use_lut) + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + float dpx = gx - cx0, dpy = gy - cy0; + float B = -2.f * (dpx * cdx + dpy * cdy + cr0 * dr); + float C = dpx * dpx + dpy * dpy - cr0 * cr0; + + float grad_t; + if (fabsf (A) > 1e-10f) + { + float disc = B * B - 4.f * A * C; + if (disc < 0.f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float sq = sqrtf (disc); + /* Pick the larger root (t closer to 1 = outer circle) */ + float t1 = (-B + sq) / (2.f * A); + float t2 = (-B - sq) / (2.f * A); + /* Choose the root that gives a positive radius */ + if (cr0 + t1 * dr >= 0.f) + grad_t = t1; + else + grad_t = t2; + } + else + { + /* Linear case: Bt + C = 0 */ + if (fabsf (B) < 1e-10f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + grad_t = -C / B; + } + + uint32_t src = lookup_gradient_lut (lut, grad_t, extend); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + else + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + float dpx = gx - cx0, dpy = gy - cy0; + float B = -2.f * (dpx * cdx + dpy * cdy + cr0 * dr); + float C = dpx * dpx + dpy * dpy - cr0 * cr0; + + float grad_t; + if (fabsf (A) > 1e-10f) + { + float disc = B * B - 4.f * A * C; + if (disc < 0.f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float sq = sqrtf (disc); + float t1 = (-B + sq) / (2.f * A); + float t2 = (-B - sq) / (2.f * A); + grad_t = (cr0 + t1 * dr >= 0.f) ? t1 : t2; + } + else + { + if (fabsf (B) < 1e-10f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + grad_t = -C / B; + } + + uint32_t src = evaluate_color_line (stops, len, grad_t, extend); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + } + else + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * stride); + const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride; + float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0; + float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0; + if (use_lut) + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float dpx = gx - cx0, dpy = gy - cy0; + float B = -2.f * (dpx * cdx + dpy * cdy + cr0 * dr); + float C = dpx * dpx + dpy * dpy - cr0 * cr0; + + float grad_t; + if (fabsf (A) > 1e-10f) + { + float disc = B * B - 4.f * A * C; + if (disc < 0.f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float sq = sqrtf (disc); + float t1 = (-B + sq) / (2.f * A); + float t2 = (-B - sq) / (2.f * A); + grad_t = (cr0 + t1 * dr >= 0.f) ? t1 : t2; + } + else + { + if (fabsf (B) < 1e-10f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + grad_t = -C / B; + } + + uint32_t src = lookup_gradient_lut (lut, grad_t, extend); + src = hb_raster_alpha_mul (src, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + else + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float dpx = gx - cx0, dpy = gy - cy0; + float B = -2.f * (dpx * cdx + dpy * cdy + cr0 * dr); + float C = dpx * dpx + dpy * dpy - cr0 * cr0; + + float grad_t; + if (fabsf (A) > 1e-10f) + { + float disc = B * B - 4.f * A * C; + if (disc < 0.f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float sq = sqrtf (disc); + float t1 = (-B + sq) / (2.f * A); + float t2 = (-B - sq) / (2.f * A); + grad_t = (cr0 + t1 * dr >= 0.f) ? t1 : t2; + } + else + { + if (fabsf (B) < 1e-10f) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + grad_t = -C / B; + } + + uint32_t src = evaluate_color_line (stops, len, grad_t, extend); + src = hb_raster_alpha_mul (src, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + } + } + +done: + (void) stops_; +} + +static void +hb_raster_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_color_line_t *color_line, + float cx, float cy, + float start_angle, + float end_angle, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + + ensure_initialized (c); + + hb_raster_image_t *surf = c->current_surface (); + if (unlikely (!surf)) return; + + unsigned len = PREALLOCATED_COLOR_STOPS; + hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS]; + hb_color_stop_t *stops = stops_; + + if (unlikely (!get_color_stops (c, color_line, &len, &stops))) + return; + float mn, mx; + normalize_color_line (stops, len, &mn, &mx); + + hb_paint_extend_t extend = hb_color_line_get_extend (color_line); + const hb_raster_clip_t &clip = c->current_clip (); + unsigned clip_w = clip.max_x > clip.min_x ? clip.max_x - clip.min_x : 0; + unsigned clip_h = clip.max_y > clip.min_y ? clip.max_y - clip.min_y : 0; + bool use_lut = (uint64_t) clip_w * clip_h >= GRADIENT_LUT_MIN_PIXELS; + uint32_t lut[GRADIENT_LUT_SIZE]; + if (use_lut) + build_gradient_lut (stops, len, lut); + + /* Apply normalization to angle range */ + float a0 = start_angle + mn * (end_angle - start_angle); + float a1 = start_angle + mx * (end_angle - start_angle); + float angle_range = a1 - a0; + + /* Inverse transform */ + hb_transform_t<> t = c->current_effective_transform (); + float det = t.xx * t.yy - t.xy * t.yx; + if (fabsf (det) < 1e-10f || fabsf (angle_range) < 1e-10f) goto done; + + { + float inv_det = 1.f / det; + float inv_xx = t.yy * inv_det; + float inv_xy = -t.xy * inv_det; + float inv_yx = -t.yx * inv_det; + float inv_yy = t.xx * inv_det; + float inv_x0 = (t.xy * t.y0 - t.yy * t.x0) * inv_det; + float inv_y0 = (t.yx * t.x0 - t.xx * t.y0) * inv_det; + + float inv_angle_range = 1.f / angle_range; + + unsigned stride = surf->extents.stride; + int ox = surf->extents.x_origin; + int oy = surf->extents.y_origin; + + if (clip.is_rect) + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * stride); + float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0; + float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0; + if (use_lut) + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + float angle = atan2f (gy - cy, gx - cx); + if (angle < 0) angle += (float) HB_2_PI; + float grad_t = (angle - a0) * inv_angle_range; + uint32_t src = lookup_gradient_lut (lut, grad_t, extend); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + else + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + float angle = atan2f (gy - cy, gx - cx); + if (angle < 0) angle += (float) HB_2_PI; + float grad_t = (angle - a0) * inv_angle_range; + uint32_t src = evaluate_color_line (stops, len, grad_t, extend); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + } + else + { + for (unsigned py = clip.min_y; py < clip.max_y; py++) + { + hb_packed_t *row = (hb_packed_t *) (surf->buffer.arrayZ + py * stride); + const uint8_t *clip_row = clip.alpha.arrayZ + py * clip.stride; + float gx = inv_xx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_xy * ((float) ((int) py + oy) + 0.5f) + inv_x0; + float gy = inv_yx * ((float) ((int) clip.min_x + ox) + 0.5f) + inv_yy * ((float) ((int) py + oy) + 0.5f) + inv_y0; + if (use_lut) + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float angle = atan2f (gy - cy, gx - cx); + if (angle < 0) angle += (float) HB_2_PI; + float grad_t = (angle - a0) * inv_angle_range; + uint32_t src = lookup_gradient_lut (lut, grad_t, extend); + src = hb_raster_alpha_mul (src, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + else + { + for (unsigned px = clip.min_x; px < clip.max_x; px++) + { + uint8_t clip_alpha = clip_row[px]; + if (clip_alpha == 0) + { + gx += inv_xx; + gy += inv_yx; + continue; + } + float angle = atan2f (gy - cy, gx - cx); + if (angle < 0) angle += (float) HB_2_PI; + float grad_t = (angle - a0) * inv_angle_range; + uint32_t src = evaluate_color_line (stops, len, grad_t, extend); + src = hb_raster_alpha_mul (src, clip_alpha); + row[px] = hb_packed_t (hb_raster_src_over (src, (uint32_t) row[px])); + gx += inv_xx; + gy += inv_yx; + } + } + } + } + } + +done: + (void) stops_; +} + +static hb_bool_t +hb_raster_paint_custom_palette_color (hb_paint_funcs_t *funcs HB_UNUSED, + void *paint_data, + unsigned int color_index, + hb_color_t *color, + void *user_data HB_UNUSED) +{ + hb_raster_paint_t *c = (hb_raster_paint_t *) paint_data; + if (likely (c->custom_palette && hb_map_has (c->custom_palette, color_index))) + { + *color = hb_map_get (c->custom_palette, color_index); + return true; + } + return false; +} + + +/* + * Lazy-loader singleton for paint funcs + */ + +static inline void free_static_raster_paint_funcs (); + +static struct hb_raster_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t +{ + static hb_paint_funcs_t *create () + { + hb_paint_funcs_t *funcs = hb_paint_funcs_create (); + + hb_paint_funcs_set_push_transform_func (funcs, hb_raster_paint_push_transform, nullptr, nullptr); + hb_paint_funcs_set_pop_transform_func (funcs, hb_raster_paint_pop_transform, nullptr, nullptr); + hb_paint_funcs_set_color_glyph_func (funcs, hb_raster_paint_color_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_raster_paint_push_clip_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_raster_paint_push_clip_rectangle, nullptr, nullptr); + hb_paint_funcs_set_pop_clip_func (funcs, hb_raster_paint_pop_clip, nullptr, nullptr); + hb_paint_funcs_set_push_group_func (funcs, hb_raster_paint_push_group, nullptr, nullptr); + hb_paint_funcs_set_pop_group_func (funcs, hb_raster_paint_pop_group, nullptr, nullptr); + hb_paint_funcs_set_color_func (funcs, hb_raster_paint_color, nullptr, nullptr); + hb_paint_funcs_set_image_func (funcs, hb_raster_paint_image, nullptr, nullptr); + hb_paint_funcs_set_linear_gradient_func (funcs, hb_raster_paint_linear_gradient, nullptr, nullptr); + hb_paint_funcs_set_radial_gradient_func (funcs, hb_raster_paint_radial_gradient, nullptr, nullptr); + hb_paint_funcs_set_sweep_gradient_func (funcs, hb_raster_paint_sweep_gradient, nullptr, nullptr); + hb_paint_funcs_set_custom_palette_color_func (funcs, hb_raster_paint_custom_palette_color, nullptr, nullptr); + + hb_paint_funcs_make_immutable (funcs); + + hb_atexit (free_static_raster_paint_funcs); + + return funcs; + } +} static_raster_paint_funcs; + +static inline void +free_static_raster_paint_funcs () +{ + static_raster_paint_funcs.free_instance (); +} + + +/* + * Public API + */ + +/** + * hb_raster_paint_create_or_fail: + * + * Creates a new color-glyph paint context. + * + * Return value: (transfer full): + * A newly allocated #hb_raster_paint_t, or `NULL` on allocation failure. + * + * Since: 13.0.0 + **/ +hb_raster_paint_t * +hb_raster_paint_create_or_fail (void) +{ + hb_raster_paint_t *paint = hb_object_create (); + if (unlikely (!paint)) + return nullptr; + + paint->clip_rdr = hb_raster_draw_create_or_fail (); + if (unlikely (!paint->clip_rdr)) + { + hb_free (paint); + return nullptr; + } + + return paint; +} + +/** + * hb_raster_paint_reference: (skip) + * @paint: a paint context + * + * Increases the reference count on @paint by one. + * + * Return value: (transfer full): + * The referenced #hb_raster_paint_t. + * + * Since: 13.0.0 + **/ +hb_raster_paint_t * +hb_raster_paint_reference (hb_raster_paint_t *paint) +{ + return hb_object_reference (paint); +} + +/** + * hb_raster_paint_destroy: (skip) + * @paint: a paint context + * + * Decreases the reference count on @paint by one. When the + * reference count reaches zero, the paint context is freed. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_destroy (hb_raster_paint_t *paint) +{ + if (!hb_object_should_destroy (paint)) + return; + + hb_map_destroy (paint->custom_palette); + hb_raster_draw_destroy (paint->clip_rdr); + for (auto *s : paint->surface_stack) + hb_raster_image_destroy (s); + for (auto *s : paint->surface_cache) + hb_raster_image_destroy (s); + hb_object_actually_destroy (paint); + hb_free (paint); +} + +/** + * hb_raster_paint_set_user_data: (skip) + * @paint: a paint context + * @key: the user-data key + * @data: a pointer to the user data + * @destroy: (nullable): a callback to call when @data is not needed anymore + * @replace: whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the specified paint context. + * + * Return value: `true` if success, `false` otherwise + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_paint_set_user_data (hb_raster_paint_t *paint, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (paint, key, data, destroy, replace); +} + +/** + * hb_raster_paint_get_user_data: (skip) + * @paint: a paint context + * @key: the user-data key + * + * Fetches the user-data associated with the specified key, + * attached to the specified paint context. + * + * Return value: (transfer none): + * A pointer to the user data + * + * Since: 13.0.0 + **/ +void * +hb_raster_paint_get_user_data (hb_raster_paint_t *paint, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (paint, key); +} + +/** + * hb_raster_paint_set_transform: + * @paint: a paint context + * @xx: xx component of the transform matrix + * @yx: yx component of the transform matrix + * @xy: xy component of the transform matrix + * @yy: yy component of the transform matrix + * @dx: x translation + * @dy: y translation + * + * Sets the base 2×3 affine transform that maps from glyph-space + * coordinates to pixel-space coordinates. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_set_transform (hb_raster_paint_t *paint, + float xx, float yx, + float xy, float yy, + float dx, float dy) +{ + paint->base_transform = {xx, yx, xy, yy, dx, dy}; +} + +/** + * hb_raster_paint_get_transform: + * @paint: a paint context + * @xx: (out) (nullable): xx component of the transform matrix + * @yx: (out) (nullable): yx component of the transform matrix + * @xy: (out) (nullable): xy component of the transform matrix + * @yy: (out) (nullable): yy component of the transform matrix + * @dx: (out) (nullable): x translation + * @dy: (out) (nullable): y translation + * + * Gets the current base 2x3 affine transform. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_get_transform (hb_raster_paint_t *paint, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy) +{ + if (xx) *xx = paint->base_transform.xx; + if (yx) *yx = paint->base_transform.yx; + if (xy) *xy = paint->base_transform.xy; + if (yy) *yy = paint->base_transform.yy; + if (dx) *dx = paint->base_transform.x0; + if (dy) *dy = paint->base_transform.y0; +} + +/** + * hb_raster_paint_set_scale_factor: + * @paint: a paint context + * @x_scale_factor: x-axis minification factor + * @y_scale_factor: y-axis minification factor + * + * Sets post-transform minification factors applied during painting. + * Factors larger than 1 shrink the output in pixels. The default is 1. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_set_scale_factor (hb_raster_paint_t *paint, + float x_scale_factor, + float y_scale_factor) +{ + paint->x_scale_factor = x_scale_factor > 0.f ? x_scale_factor : 1.f; + paint->y_scale_factor = y_scale_factor > 0.f ? y_scale_factor : 1.f; +} + +/** + * hb_raster_paint_get_scale_factor: + * @paint: a paint context + * @x_scale_factor: (out) (nullable): x-axis minification factor + * @y_scale_factor: (out) (nullable): y-axis minification factor + * + * Fetches the current post-transform minification factors. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_get_scale_factor (hb_raster_paint_t *paint, + float *x_scale_factor, + float *y_scale_factor) +{ + if (x_scale_factor) *x_scale_factor = paint->x_scale_factor; + if (y_scale_factor) *y_scale_factor = paint->y_scale_factor; +} + +/** + * hb_raster_paint_set_extents: + * @paint: a paint context + * @extents: the desired output extents + * + * Sets the output image extents (pixel rectangle). + * + * Call this before hb_font_paint_glyph() for each render. + * A common pattern is: + * |[ + * hb_glyph_extents_t gext; + * if (hb_font_get_glyph_extents (font, gid, &gext)) + * hb_raster_paint_set_glyph_extents (paint, &gext); + * ]| + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_set_extents (hb_raster_paint_t *paint, + const hb_raster_extents_t *extents) +{ + paint->fixed_extents = *extents; + paint->has_extents = true; + if (paint->fixed_extents.stride == 0) + paint->fixed_extents.stride = paint->fixed_extents.width * 4; +} + +/** + * hb_raster_paint_get_extents: + * @paint: a paint context + * @extents: (out) (nullable): where to write current extents + * + * Gets currently configured output extents. + * + * Return value: `true` if extents are set, `false` otherwise. + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_paint_get_extents (hb_raster_paint_t *paint, + hb_raster_extents_t *extents) +{ + if (!paint->has_extents) + return false; + + if (extents) + *extents = paint->fixed_extents; + return true; +} + +/** + * hb_raster_paint_set_glyph_extents: + * @paint: a paint context + * @glyph_extents: glyph extents from hb_font_get_glyph_extents() + * + * Transforms @glyph_extents with the paint context's base transform and + * sets the resulting output image extents. + * + * This is equivalent to computing a transformed bounding box in pixel + * space and calling hb_raster_paint_set_extents(). + * + * Return value: `true` if transformed extents are non-empty and set; + * `false` otherwise. + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_paint_set_glyph_extents (hb_raster_paint_t *paint, + const hb_glyph_extents_t *glyph_extents) +{ + float x0 = (float) glyph_extents->x_bearing; + float y0 = (float) glyph_extents->y_bearing; + float x1 = (float) glyph_extents->x_bearing + glyph_extents->width; + float y1 = (float) glyph_extents->y_bearing + glyph_extents->height; + + float xmin = hb_min (x0, x1); + float xmax = hb_max (x0, x1); + float ymin = hb_min (y0, y1); + float ymax = hb_max (y0, y1); + + float px[4] = {xmin, xmin, xmax, xmax}; + float py[4] = {ymin, ymax, ymin, ymax}; + + hb_transform_t<> t = paint->base_transform; + paint->apply_scale_factor (t); + + float tx, ty; + t.transform_point (px[0], py[0]); + tx = px[0]; ty = py[0]; + float tx_min = tx, tx_max = tx; + float ty_min = ty, ty_max = ty; + + for (unsigned i = 1; i < 4; i++) + { + t.transform_point (px[i], py[i]); + tx_min = hb_min (tx_min, px[i]); + tx_max = hb_max (tx_max, px[i]); + ty_min = hb_min (ty_min, py[i]); + ty_max = hb_max (ty_max, py[i]); + } + + int ex0 = (int) floorf (tx_min); + int ey0 = (int) floorf (ty_min); + int ex1 = (int) ceilf (tx_max); + int ey1 = (int) ceilf (ty_max); + + if (ex1 <= ex0 || ey1 <= ey0) + { + paint->fixed_extents = {}; + paint->has_extents = false; + return false; + } + + paint->fixed_extents = { + ex0, ey0, + (unsigned) (ex1 - ex0), + (unsigned) (ey1 - ey0), + 0 + }; + paint->has_extents = true; + if (paint->fixed_extents.stride == 0) + paint->fixed_extents.stride = paint->fixed_extents.width * 4; + return true; +} + +/** + * hb_raster_paint_set_foreground: + * @paint: a paint context + * @foreground: the foreground color + * + * Sets the foreground color used when paint callbacks request it + * (e.g. `is_foreground` in color stops or solid fills). + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_set_foreground (hb_raster_paint_t *paint, + hb_color_t foreground) +{ + paint->foreground = foreground; +} + +/** + * hb_raster_paint_clear_custom_palette_colors: + * @paint: a paint context. + * + * Clears all custom palette color overrides previously set on @paint. + * + * After this call, palette lookups use the selected font palette without + * custom override entries. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_clear_custom_palette_colors (hb_raster_paint_t *paint) +{ + if (paint->custom_palette) + hb_map_clear (paint->custom_palette); +} + +/** + * hb_raster_paint_set_custom_palette_color: + * @paint: a paint context. + * @color_index: color index to override. + * @color: replacement color. + * + * Overrides one font palette color entry for subsequent paint operations. + * Overrides are keyed by @color_index and persist on @paint until cleared + * (or replaced for the same index). + * + * These overrides are consulted by paint operations that resolve CPAL + * entries. + * + * Return value: `true` if the override was set; `false` on allocation failure. + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_paint_set_custom_palette_color (hb_raster_paint_t *paint, + unsigned int color_index, + hb_color_t color) +{ + if (unlikely (!paint->custom_palette)) + { + paint->custom_palette = hb_map_create (); + if (unlikely (!paint->custom_palette)) + return false; + } + hb_map_set (paint->custom_palette, color_index, color); + return hb_map_allocation_successful (paint->custom_palette); +} + +/** + * hb_raster_paint_get_funcs: + * + * Fetches the singleton #hb_paint_funcs_t that renders color glyphs + * into an #hb_raster_paint_t. Pass the #hb_raster_paint_t as the + * @paint_data argument when calling hb_font_paint_glyph(). + * + * Return value: (transfer none): + * The rasterizer paint functions + * + * Since: 13.0.0 + **/ +hb_paint_funcs_t * +hb_raster_paint_get_funcs (void) +{ + return static_raster_paint_funcs.get_unconst (); +} + +/** + * hb_raster_paint_glyph: + * @paint: a paint context + * @font: font to paint from + * @glyph: glyph ID to paint + * @pen_x: glyph origin x in font coordinates (pre-transform) + * @pen_y: glyph origin y in font coordinates (pre-transform) + * @palette: palette index + * @foreground: foreground color + * + * Convenience wrapper to paint one color glyph at (@pen_x, @pen_y) using + * the paint context's current transform. The pen coordinates are applied + * before minification and transformed by the current affine transform. + * + * Return value: `true` if painting succeeded, `false` otherwise. + * + * Since: 13.0.0 + **/ +hb_bool_t +hb_raster_paint_glyph (hb_raster_paint_t *paint, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y, + unsigned palette, + hb_color_t foreground) +{ + float xx = paint->base_transform.xx; + float yx = paint->base_transform.yx; + float xy = paint->base_transform.xy; + float yy = paint->base_transform.yy; + float dx = paint->base_transform.x0; + float dy = paint->base_transform.y0; + + float tx = dx + xx * pen_x + xy * pen_y; + float ty = dy + yx * pen_x + yy * pen_y; + + if (!paint->has_extents) + { + hb_glyph_extents_t ge; + if (hb_font_get_glyph_extents (font, glyph, &ge)) + { + hb_raster_paint_set_transform (paint, xx, yx, xy, yy, tx, ty); + hb_raster_paint_set_glyph_extents (paint, &ge); + } + } + + hb_raster_paint_set_transform (paint, xx, yx, xy, yy, tx, ty); + paint->svg_glyph = glyph; + paint->svg_font = font; + paint->svg_palette = palette; + hb_bool_t ret = hb_font_paint_glyph_or_fail (font, glyph, + hb_raster_paint_get_funcs (), paint, + palette, foreground); + paint->svg_glyph = 0; + paint->svg_font = nullptr; + paint->svg_palette = 0; + hb_raster_paint_set_transform (paint, xx, yx, xy, yy, dx, dy); + return ret; +} + +/** + * hb_raster_paint_render: + * @paint: a paint context + * + * Extracts the rendered image after hb_font_paint_glyph() has + * completed. The paint context's surface stack is consumed and + * the result returned as a new #hb_raster_image_t. Output format is + * always @HB_RASTER_FORMAT_BGRA32. + * + * Call hb_font_paint_glyph() before calling this function. + * hb_raster_paint_set_extents() or hb_raster_paint_set_glyph_extents() + * must be called before painting; otherwise this function returns `NULL`. + * Internal drawing state is cleared here so the same object can + * be reused without client-side clearing. + * + * Return value: (transfer full): + * A rendered #hb_raster_image_t. Returns `NULL` if extents were not set + * or if allocation/configuration fails. If extents were set but nothing + * was painted, returns an empty image. + * + * Since: 13.0.0 + **/ +hb_raster_image_t * +hb_raster_paint_render (hb_raster_paint_t *paint) +{ + hb_raster_image_t *result = nullptr; + + if (unlikely (!paint->has_extents)) + goto fail; + + if (paint->surface_stack.length) + { + result = paint->surface_stack[0]; + /* Release any remaining group surfaces (shouldn't happen with + * well-formed paint calls, but be safe). */ + for (unsigned i = 1; i < paint->surface_stack.length; i++) + paint->release_surface (paint->surface_stack[i]); + paint->surface_stack.clear (); + } + else + { + result = paint->acquire_surface (); + if (unlikely (!result)) + goto fail; + } + + /* Clean up stacks and reset auto-extents for next glyph. */ + paint->transform_stack.clear (); + paint->release_all_clips (); + hb_raster_draw_reset (paint->clip_rdr); + paint->has_extents = false; + paint->fixed_extents = {}; + + return result; + +fail: + paint->transform_stack.clear (); + paint->release_all_clips (); + for (auto *s : paint->surface_stack) + paint->release_surface (s); + paint->surface_stack.clear (); + hb_raster_draw_reset (paint->clip_rdr); + paint->has_extents = false; + paint->fixed_extents = {}; + return nullptr; +} + +/** + * hb_raster_paint_reset: + * @paint: a paint context + * + * Resets the paint context to its initial state, clearing all + * configuration while preserving internal image caches. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_reset (hb_raster_paint_t *paint) +{ + paint->base_transform = {1, 0, 0, 1, 0, 0}; + paint->x_scale_factor = 1.f; + paint->y_scale_factor = 1.f; + paint->fixed_extents = {}; + paint->has_extents = false; + paint->foreground = HB_COLOR (0, 0, 0, 255); + hb_raster_paint_clear_custom_palette_colors (paint); + paint->transform_stack.clear (); + paint->release_all_clips (); + for (auto *s : paint->surface_stack) + paint->release_surface (s); + paint->surface_stack.clear (); +} + +/** + * hb_raster_paint_recycle_image: + * @paint: a paint context + * @image: a raster image to recycle + * + * Recycles @image for reuse by subsequent render calls. + * The caller transfers ownership of @image to @paint. + * + * Since: 13.0.0 + **/ +void +hb_raster_paint_recycle_image (hb_raster_paint_t *paint, + hb_raster_image_t *image) +{ + paint->release_surface (image); +} diff --git a/thirdparty/harfbuzz/upstream/hb-raster-paint.hh b/thirdparty/harfbuzz/upstream/hb-raster-paint.hh new file mode 100644 index 000000000..1d6bb18a4 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-paint.hh @@ -0,0 +1,205 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_PAINT_HH +#define HB_RASTER_PAINT_HH + +#include "hb.hh" + +#include "hb-raster-image.hh" +#include "hb-geometry.hh" + +/* hb_raster_clip_t — alpha mask for clipping */ +struct hb_raster_clip_t +{ + hb_vector_t alpha; /* A8 mask, same extents as root surface */ + unsigned width = 0; + unsigned height = 0; + unsigned stride = 0; + + /* Fast path: simple rectangle (no alpha buffer needed) */ + bool is_rect = true; + int rect_x0 = 0, rect_y0 = 0; + int rect_x1 = 0, rect_y1 = 0; + + /* Bounding box of non-zero alpha region (valid for both rect and mask) */ + unsigned min_x = 0, min_y = 0; + unsigned max_x = 0, max_y = 0; + + void init_full (unsigned w, unsigned h) + { + width = w; + height = h; + stride = (w + 3u) & ~3u; + is_rect = true; + rect_x0 = 0; + rect_y0 = 0; + rect_x1 = (int) w; + rect_y1 = (int) h; + min_x = 0; + min_y = 0; + max_x = w; + max_y = h; + } + + void update_bounds_from_rect () + { + min_x = (unsigned) hb_max (rect_x0, 0); + min_y = (unsigned) hb_max (rect_y0, 0); + max_x = (unsigned) hb_max (hb_min (rect_x1, (int) width), 0); + max_y = (unsigned) hb_max (hb_min (rect_y1, (int) height), 0); + } + + uint8_t get_alpha (unsigned x, unsigned y) const + { + if (is_rect) + return ((int) x >= rect_x0 && (int) x < rect_x1 && + (int) y >= rect_y0 && (int) y < rect_y1) ? 255 : 0; + if (x >= width || y >= height) return 0; + return alpha[y * stride + x]; + } +}; + + +/* hb_raster_paint_t — color glyph paint context */ +struct hb_raster_paint_t +{ + hb_object_header_t header; + + /* Configuration */ + hb_transform_t<> base_transform = {1, 0, 0, 1, 0, 0}; + float x_scale_factor = 1.f; + float y_scale_factor = 1.f; + hb_raster_extents_t fixed_extents = {}; + bool has_extents = false; + hb_color_t foreground = HB_COLOR (0, 0, 0, 255); + hb_map_t *custom_palette = nullptr; + + /* SVG rendering state */ + hb_codepoint_t svg_glyph = 0; + hb_font_t *svg_font = nullptr; + unsigned svg_palette = 0; + + /* Stacks */ + hb_vector_t> transform_stack; + hb_vector_t clip_stack; + hb_vector_t clip_cache; + hb_vector_t surface_stack; + + /* Cached surface pool (freelist for reuse across push/pop group) */ + hb_vector_t surface_cache; + hb_vector_t scratch_color_stops; + + /* Internal rasterizer for clip-to-glyph */ + hb_raster_draw_t *clip_rdr = nullptr; + + /* Helpers */ + + hb_raster_image_t *acquire_surface () + { + hb_raster_image_t *img; + if (surface_cache.length) + img = surface_cache.pop (); + else + { + img = hb_raster_image_create_or_fail (); + if (unlikely (!img)) return nullptr; + } + + if (unlikely (!img->configure (HB_RASTER_FORMAT_BGRA32, fixed_extents))) + { + hb_raster_image_destroy (img); + return nullptr; + } + img->clear (); + return img; + } + + void release_surface (hb_raster_image_t *img) + { + if (!surface_cache.push_or_fail (img)) + hb_raster_image_destroy (img); + } + + hb_raster_clip_t acquire_clip (unsigned w, unsigned h) + { + hb_raster_clip_t clip; + if (clip_cache.length) + clip = clip_cache.pop (); + clip.width = w; + clip.height = h; + clip.stride = (w + 3u) & ~3u; + clip.is_rect = false; + return clip; + } + + void release_clip (hb_raster_clip_t &&clip) + { + if (clip.alpha.arrayZ) + clip_cache.push (std::move (clip)); + } + + void release_all_clips () + { + while (clip_stack.length) + release_clip (clip_stack.pop ()); + } + + hb_raster_image_t *current_surface () + { + return surface_stack.length ? surface_stack.tail () : nullptr; + } + + hb_raster_clip_t ¤t_clip () + { + return clip_stack.tail (); + } + + hb_transform_t<> ¤t_transform () + { + return transform_stack.tail (); + } + + void apply_scale_factor (hb_transform_t<> &t) const + { + t.xx /= x_scale_factor; + t.xy /= x_scale_factor; + t.x0 /= x_scale_factor; + t.yx /= y_scale_factor; + t.yy /= y_scale_factor; + t.y0 /= y_scale_factor; + } + + hb_transform_t<> current_effective_transform () + { + hb_transform_t<> t = current_transform (); + apply_scale_factor (t); + return t; + } +}; + + +#endif /* HB_RASTER_PAINT_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-base.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-base.cc new file mode 100644 index 000000000..760b9aea7 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-base.cc @@ -0,0 +1,501 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-base.hh" +#include "hb-raster-svg-parse.hh" + +void +svg_parse_style_props (hb_svg_str_t style, hb_svg_style_props_t *out) +{ + if (style.is_null ()) return; + const char *p = style.data; + const char *end = style.data + style.len; + while (p < end) + { + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || *p == ';')) + p++; + if (p >= end) break; + const char *name_start = p; + while (p < end && *p != ':' && *p != ';') + p++; + const char *name_end = p; + while (name_end > name_start && + (name_end[-1] == ' ' || name_end[-1] == '\t' || name_end[-1] == '\n' || name_end[-1] == '\r')) + name_end--; + if (p >= end || *p != ':') + { + while (p < end && *p != ';') p++; + continue; + } + p++; /* skip ':' */ + const char *value_start = p; + while (p < end && *p != ';') + p++; + const char *value_end = p; + while (value_start < value_end && + (*value_start == ' ' || *value_start == '\t' || *value_start == '\n' || *value_start == '\r')) + value_start++; + while (value_end > value_start && + (value_end[-1] == ' ' || value_end[-1] == '\t' || value_end[-1] == '\n' || value_end[-1] == '\r')) + value_end--; + + hb_svg_str_t prop_name = {name_start, (unsigned) (name_end - name_start)}; + hb_svg_str_t prop_value = {value_start, (unsigned) (value_end - value_start)}; + if (prop_name.len) + { + switch (hb_svg_ascii_lower (prop_name.data[0])) + { + case 'c': + if (prop_name.len == 9 && prop_name.eq_ascii_ci ("clip-path")) out->clip_path = prop_value; + else if (prop_name.len == 5 && prop_name.eq_ascii_ci ("color")) out->color = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("cx")) out->cx = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("cy")) out->cy = prop_value; + break; + case 'd': + if (prop_name.len == 7 && prop_name.eq_ascii_ci ("display")) out->display = prop_value; + else if (prop_name.len == 1 && prop_name.eq_ascii_ci ("d")) out->d = prop_value; + break; + case 'f': + if (prop_name.len == 4 && prop_name.eq_ascii_ci ("fill")) out->fill = prop_value; + else if (prop_name.len == 12 && prop_name.eq_ascii_ci ("fill-opacity")) out->fill_opacity = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("fx")) out->fx = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("fy")) out->fy = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("fr")) out->fr = prop_value; + break; + case 'g': + if ((prop_name.len == 13 && prop_name.eq_ascii_ci ("gradientunits")) || + (prop_name.len == 14 && prop_name.eq_ascii_ci ("gradient-units"))) out->gradient_units = prop_value; + else if ((prop_name.len == 17 && prop_name.eq_ascii_ci ("gradienttransform")) || + (prop_name.len == 18 && prop_name.eq_ascii_ci ("gradient-transform"))) out->gradient_transform = prop_value; + break; + case 'h': + if (prop_name.len == 6 && prop_name.eq_ascii_ci ("height")) out->height = prop_value; + break; + case 'o': + if (prop_name.len == 7 && prop_name.eq_ascii_ci ("opacity")) out->opacity = prop_value; + else if (prop_name.len == 6 && prop_name.eq_ascii_ci ("offset")) out->offset = prop_value; + break; + case 'p': + if (prop_name.len == 6 && prop_name.eq_ascii_ci ("points")) out->points = prop_value; + break; + case 'r': + if (prop_name.len == 1 && prop_name.eq_ascii_ci ("r")) out->r = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("rx")) out->rx = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("ry")) out->ry = prop_value; + break; + case 's': + if (prop_name.len == 10 && prop_name.eq_ascii_ci ("stop-color")) out->stop_color = prop_value; + else if (prop_name.len == 12 && prop_name.eq_ascii_ci ("stop-opacity")) out->stop_opacity = prop_value; + else if ((prop_name.len == 12 && prop_name.eq_ascii_ci ("spreadmethod")) || + (prop_name.len == 13 && prop_name.eq_ascii_ci ("spread-method"))) out->spread_method = prop_value; + break; + case 't': + if (prop_name.len == 9 && prop_name.eq_ascii_ci ("transform")) out->transform = prop_value; + break; + case 'v': + if (prop_name.len == 10 && prop_name.eq_ascii_ci ("visibility")) out->visibility = prop_value; + break; + case 'w': + if (prop_name.len == 5 && prop_name.eq_ascii_ci ("width")) out->width = prop_value; + break; + case 'x': + if (prop_name.len == 1 && prop_name.eq_ascii_ci ("x")) out->x = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("x1")) out->x1 = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("x2")) out->x2 = prop_value; + break; + case 'y': + if (prop_name.len == 1 && prop_name.eq_ascii_ci ("y")) out->y = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("y1")) out->y1 = prop_value; + else if (prop_name.len == 2 && prop_name.eq_ascii_ci ("y2")) out->y2 = prop_value; + break; + default: + break; + } + } + + if (p < end && *p == ';') p++; + } +} + +float +svg_parse_number_or_percent (hb_svg_str_t s, bool *is_percent) +{ + if (is_percent) *is_percent = false; + s = s.trim (); + if (!s.len) return 0.f; + if (s.data[s.len - 1] == '%') + { + if (is_percent) *is_percent = true; + hb_svg_str_t n = {s.data, s.len - 1}; + return n.to_float () / 100.f; + } + return s.to_float (); +} + +hb_svg_str_t +hb_raster_svg_find_href_attr (const hb_svg_xml_parser_t &parser) +{ + hb_svg_str_t href = parser.find_attr ("href"); + if (href.is_null ()) + href = parser.find_attr ("xlink:href"); + return href; +} + +bool +hb_raster_svg_parse_id_ref (hb_svg_str_t s, + hb_svg_str_t *out_id, + hb_svg_str_t *out_tail) +{ + if (out_id) *out_id = {}; + if (out_tail) *out_tail = {}; + s = s.trim (); + + if (s.len && s.data[0] == '#') + { + hb_svg_str_t id = {s.data + 1, s.len - 1}; + id = id.trim (); + if (!id.len) + return false; + if (out_id) *out_id = id; + return true; + } + + if (!s.starts_with_ascii_ci ("url(")) + return false; + + const char *p = s.data + 4; + const char *end = s.data + s.len; + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) p++; + + const char *q = p; + char quote = 0; + while (q < end) + { + char c = *q; + if (quote) + { + if (c == quote) quote = 0; + } + else + { + if (c == '"' || c == '\'') quote = c; + else if (c == ')') break; + } + q++; + } + if (q >= end || *q != ')') + return false; + + hb_svg_str_t id = {(const char *) p, (unsigned) (q - p)}; + id = id.trim (); + if (id.len >= 2 && + ((id.data[0] == '\'' && id.data[id.len - 1] == '\'') || + (id.data[0] == '"' && id.data[id.len - 1] == '"'))) + { + id.data++; + id.len -= 2; + } + id = id.trim (); + if (id.len && id.data[0] == '#') + { + id.data++; + id.len--; + } + id = id.trim (); + if (!id.len) + return false; + + if (out_id) *out_id = id; + if (out_tail) + { + const char *tail = q + 1; + while (tail < end && (*tail == ' ' || *tail == '\t' || *tail == '\n' || *tail == '\r')) tail++; + *out_tail = {(const char *) tail, (unsigned) (end - tail)}; + } + return true; +} + +bool +hb_raster_svg_parse_local_id_ref (hb_svg_str_t s, + hb_svg_str_t *out_id, + hb_svg_str_t *out_tail) +{ + if (out_id) *out_id = {}; + if (out_tail) *out_tail = {}; + s = s.trim (); + + if (s.len && s.data[0] == '#') + { + hb_svg_str_t id = {s.data + 1, s.len - 1}; + id = id.trim (); + if (!id.len) + return false; + if (out_id) *out_id = id; + return true; + } + + if (!s.starts_with_ascii_ci ("url(")) + return false; + + hb_svg_str_t id; + if (!hb_raster_svg_parse_id_ref (s, &id, out_tail)) + return false; + + const char *p = s.data + 4; + const char *end = s.data + s.len; + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) p++; + if (p < end && (*p == '\'' || *p == '"')) + { + p++; + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) p++; + if (p >= end || *p != '#') + return false; + } + else if (p >= end || *p != '#') + return false; + + if (out_id) *out_id = id; + return true; +} + +bool +hb_raster_svg_find_element_by_id (const char *doc_start, + unsigned doc_len, + const OT::SVG::accelerator_t *svg_accel, + const OT::SVG::svg_doc_cache_t *doc_cache, + hb_svg_str_t id, + const char **found) +{ + *found = nullptr; + if (!doc_start || !doc_len || !id.len) + return false; + + if (doc_cache && svg_accel) + { + unsigned start = 0, end = 0; + OT::SVG::svg_id_span_t key = {id.data, id.len}; + if (svg_accel->doc_cache_find_id_span (doc_cache, key, &start, &end)) + { + if (start < doc_len && end <= doc_len && start < end) + { + *found = doc_start + start; + return true; + } + } + } + + hb_svg_xml_parser_t search (doc_start, doc_len); + while (true) + { + hb_svg_token_type_t tok = search.next (); + if (tok == SVG_TOKEN_EOF) break; + if (tok != SVG_TOKEN_OPEN_TAG && tok != SVG_TOKEN_SELF_CLOSE_TAG) continue; + hb_svg_str_t attr_id = search.find_attr ("id"); + if (attr_id.len == id.len && 0 == memcmp (attr_id.data, id.data, id.len)) + { + *found = search.tag_start; + return true; + } + } + return false; +} + +bool +hb_raster_svg_parse_viewbox (hb_svg_str_t viewbox_str, + float *x, + float *y, + float *w, + float *h) +{ + if (!viewbox_str.len) + return false; + hb_svg_float_parser_t vb_fp (viewbox_str); + float vb_x = vb_fp.next_float (); + float vb_y = vb_fp.next_float (); + float vb_w = vb_fp.next_float (); + float vb_h = vb_fp.next_float (); + if (vb_w <= 0.f || vb_h <= 0.f) + return false; + if (x) *x = vb_x; + if (y) *y = vb_y; + if (w) *w = vb_w; + if (h) *h = vb_h; + return true; +} + +static inline float +svg_align_offset (hb_svg_str_t align, + float leftover, + char axis) +{ + if (leftover <= 0.f) return 0.f; + if ((axis == 'x' && align.starts_with_ascii_ci ("xMin")) || + (axis == 'y' && (align.eq_ascii_ci ("xMinYMin") || + align.eq_ascii_ci ("xMidYMin") || + align.eq_ascii_ci ("xMaxYMin")))) + return 0.f; + if ((axis == 'x' && align.starts_with_ascii_ci ("xMax")) || + (axis == 'y' && (align.eq_ascii_ci ("xMinYMax") || + align.eq_ascii_ci ("xMidYMax") || + align.eq_ascii_ci ("xMaxYMax")))) + return leftover; + return leftover * 0.5f; +} + +bool +hb_raster_svg_compute_viewbox_transform (float viewport_w, + float viewport_h, + float vb_x, + float vb_y, + float vb_w, + float vb_h, + hb_svg_str_t preserve_aspect_ratio, + hb_svg_transform_t *out) +{ + if (!(viewport_w > 0.f && viewport_h > 0.f && vb_w > 0.f && vb_h > 0.f)) + return false; + + hb_svg_str_t par = preserve_aspect_ratio.trim (); + if (par.starts_with_ascii_ci ("defer")) + { + const char *p = par.data + 5; + const char *end = par.data + par.len; + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) p++; + par = hb_svg_str_t (p, (unsigned) (end - p)); + } + if (!par.len) + par = hb_svg_str_t ("xMidYMid meet", 12); + + bool is_none = false; + bool is_slice = false; + hb_svg_str_t align = par; + const char *p = par.data; + const char *end = par.data + par.len; + while (p < end && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r') p++; + align = hb_svg_str_t (par.data, (unsigned) (p - par.data)).trim (); + + if (par.starts_with_ascii_ci ("none")) + is_none = true; + else if (align.starts_with_ascii_ci ("x")) + { + const char *mode = p; + while (mode < end && (*mode == ' ' || *mode == '\t' || *mode == '\n' || *mode == '\r')) mode++; + if (mode < end && hb_svg_str_t (mode, (unsigned) (end - mode)).starts_with_ascii_ci ("slice")) + is_slice = true; + } + + hb_svg_transform_t t; + if (is_none) + { + t.xx = viewport_w / vb_w; + t.yy = viewport_h / vb_h; + t.dx = -vb_x * t.xx; + t.dy = -vb_y * t.yy; + *out = t; + return true; + } + + float sx = viewport_w / vb_w; + float sy = viewport_h / vb_h; + float s = is_slice ? hb_max (sx, sy) : hb_min (sx, sy); + float scaled_w = vb_w * s; + float scaled_h = vb_h * s; + float leftover_x = viewport_w - scaled_w; + float leftover_y = viewport_h - scaled_h; + + if (!align.starts_with_ascii_ci ("x")) + align = hb_svg_str_t ("xMidYMid", 8); + + t.xx = s; + t.yy = s; + t.dx = svg_align_offset (align, leftover_x, 'x') - vb_x * s; + t.dy = svg_align_offset (align, leftover_y, 'y') - vb_y * s; + *out = t; + return true; +} + +bool +hb_raster_svg_compute_use_target_viewbox_transform (hb_svg_xml_parser_t &target_parser, + float use_w, + float use_h, + hb_svg_transform_t *out) +{ + if (!(target_parser.tag_name.eq ("svg") || target_parser.tag_name.eq ("symbol"))) + return false; + + float viewport_w = use_w; + float viewport_h = use_h; + hb_svg_style_props_t target_style_props; + svg_parse_style_props (target_parser.find_attr ("style"), &target_style_props); + if (viewport_w <= 0.f) + viewport_w = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (target_parser, target_style_props.width, "width")); + if (viewport_h <= 0.f) + viewport_h = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (target_parser, target_style_props.height, "height")); + + float vb_x = 0.f, vb_y = 0.f, vb_w = 0.f, vb_h = 0.f; + if (!hb_raster_svg_parse_viewbox (target_parser.find_attr ("viewBox"), &vb_x, &vb_y, &vb_w, &vb_h)) + return false; + + if (!(viewport_w > 0.f && viewport_h > 0.f)) + { + viewport_w = vb_w; + viewport_h = vb_h; + } + + return hb_raster_svg_compute_viewbox_transform (viewport_w, viewport_h, vb_x, vb_y, vb_w, vb_h, + target_parser.find_attr ("preserveAspectRatio"), + out); +} + +void +hb_raster_svg_parse_use_geometry (hb_svg_xml_parser_t &parser, + float *x, + float *y, + float *w, + float *h) +{ + hb_svg_style_props_t style_props; + svg_parse_style_props (parser.find_attr ("style"), &style_props); + + if (x) *x = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, style_props.x, "x")); + if (y) *y = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, style_props.y, "y")); + if (w) *w = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, style_props.width, "width")); + if (h) *h = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, style_props.height, "height")); +} + +float +hb_raster_svg_parse_non_percent_length (hb_svg_str_t s) +{ + bool is_percent = false; + float v = svg_parse_number_or_percent (s, &is_percent); + return is_percent ? 0.f : v; +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-base.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-base.hh new file mode 100644 index 000000000..9570f9cb4 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-base.hh @@ -0,0 +1,228 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_BASE_HH +#define HB_RASTER_SVG_BASE_HH + +#include "hb.hh" +#include "OT/Color/svg/svg.hh" + +#include +#include +#include + +static inline char +hb_svg_ascii_lower (char c) +{ + if (c >= 'A' && c <= 'Z') + return c + ('a' - 'A'); + return c; +} + +struct hb_svg_str_t +{ + const char *data; + unsigned len; + + hb_svg_str_t () : data (nullptr), len (0) {} + hb_svg_str_t (const char *d, unsigned l) : data (d), len (l) {} + + bool is_null () const { return !data; } + + bool eq (const char *s) const + { + unsigned slen = (unsigned) strlen (s); + return len == slen && memcmp (data, s, len) == 0; + } + + bool starts_with (const char *prefix) const + { + unsigned plen = (unsigned) strlen (prefix); + return len >= plen && memcmp (data, prefix, plen) == 0; + } + + bool eq_ascii_ci (const char *lit) const + { + unsigned n = (unsigned) strlen (lit); + if (len != n) return false; + for (unsigned i = 0; i < n; i++) + if (hb_svg_ascii_lower (data[i]) != hb_svg_ascii_lower (lit[i])) + return false; + return true; + } + + bool starts_with_ascii_ci (const char *lit) const + { + unsigned n = (unsigned) strlen (lit); + if (len < n) return false; + for (unsigned i = 0; i < n; i++) + if (hb_svg_ascii_lower (data[i]) != hb_svg_ascii_lower (lit[i])) + return false; + return true; + } + + float to_float () const + { + if (!data || !len) return 0.f; + char buf[64]; + unsigned n = hb_min (len, (unsigned) sizeof (buf) - 1); + memcpy (buf, data, n); + buf[n] = '\0'; + float v = strtof (buf, nullptr); + return std::isfinite (v) ? v : 0.f; + } + + hb_svg_str_t trim_left () const + { + const char *p = data; + unsigned l = len; + while (l && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) + { + p++; + l--; + } + return {p, l}; + } + + hb_svg_str_t trim () const + { + hb_svg_str_t s = trim_left (); + while (s.len && (s.data[s.len - 1] == ' ' || s.data[s.len - 1] == '\t' || + s.data[s.len - 1] == '\n' || s.data[s.len - 1] == '\r')) + s.len--; + return s; + } +}; + +struct hb_svg_style_props_t +{ + hb_svg_str_t fill; + hb_svg_str_t fill_opacity; + hb_svg_str_t opacity; + hb_svg_str_t transform; + hb_svg_str_t clip_path; + hb_svg_str_t display; + hb_svg_str_t color; + hb_svg_str_t visibility; + hb_svg_str_t offset; + hb_svg_str_t stop_color; + hb_svg_str_t stop_opacity; + hb_svg_str_t spread_method; + hb_svg_str_t gradient_units; + hb_svg_str_t gradient_transform; + hb_svg_str_t x; + hb_svg_str_t y; + hb_svg_str_t width; + hb_svg_str_t height; + hb_svg_str_t cx; + hb_svg_str_t cy; + hb_svg_str_t r; + hb_svg_str_t fx; + hb_svg_str_t fy; + hb_svg_str_t fr; + hb_svg_str_t rx; + hb_svg_str_t ry; + hb_svg_str_t x1; + hb_svg_str_t y1; + hb_svg_str_t x2; + hb_svg_str_t y2; + hb_svg_str_t points; + hb_svg_str_t d; +}; + +struct hb_svg_xml_parser_t; +struct hb_svg_transform_t; + +HB_INTERNAL void svg_parse_style_props (hb_svg_str_t style, hb_svg_style_props_t *out); +HB_INTERNAL float svg_parse_number_or_percent (hb_svg_str_t s, bool *is_percent); +HB_INTERNAL hb_svg_str_t hb_raster_svg_find_href_attr (const hb_svg_xml_parser_t &parser); +HB_INTERNAL bool hb_raster_svg_parse_id_ref (hb_svg_str_t s, + hb_svg_str_t *out_id, + hb_svg_str_t *out_tail); +HB_INTERNAL bool hb_raster_svg_parse_local_id_ref (hb_svg_str_t s, + hb_svg_str_t *out_id, + hb_svg_str_t *out_tail); +HB_INTERNAL bool hb_raster_svg_find_element_by_id (const char *doc_start, + unsigned doc_len, + const OT::SVG::accelerator_t *svg_accel, + const OT::SVG::svg_doc_cache_t *doc_cache, + hb_svg_str_t id, + const char **found); +HB_INTERNAL bool hb_raster_svg_parse_viewbox (hb_svg_str_t viewbox_str, + float *x, + float *y, + float *w, + float *h); +HB_INTERNAL bool hb_raster_svg_compute_viewbox_transform (float viewport_w, + float viewport_h, + float vb_x, + float vb_y, + float vb_w, + float vb_h, + hb_svg_str_t preserve_aspect_ratio, + hb_svg_transform_t *out); +HB_INTERNAL bool hb_raster_svg_compute_use_target_viewbox_transform (hb_svg_xml_parser_t &target_parser, + float use_w, + float use_h, + hb_svg_transform_t *out); +HB_INTERNAL void hb_raster_svg_parse_use_geometry (hb_svg_xml_parser_t &parser, + float *x, + float *y, + float *w, + float *h); +HB_INTERNAL float hb_raster_svg_parse_non_percent_length (hb_svg_str_t s); +static inline float +svg_parse_float_clamped01 (hb_svg_str_t s) +{ + return hb_clamp (s.to_float (), 0.f, 1.f); +} + +static inline bool +svg_str_is_inherit (hb_svg_str_t s) +{ + return s.trim ().eq_ascii_ci ("inherit"); +} + +static inline bool +svg_str_is_none (hb_svg_str_t s) +{ + return s.trim ().eq_ascii_ci ("none"); +} + +static inline bool +hb_raster_svg_tag_is_container (hb_svg_str_t tag) +{ + return tag.eq ("g") || tag.eq ("a") || tag.eq ("svg") || tag.eq ("symbol"); +} + + +static inline bool +hb_raster_svg_tag_is_container_or_use (hb_svg_str_t tag) +{ + return hb_raster_svg_tag_is_container (tag) || tag.eq ("use"); +} + +#endif /* HB_RASTER_SVG_BASE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.cc new file mode 100644 index 000000000..2bc39b63b --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.cc @@ -0,0 +1,109 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-bbox.hh" + +static void +svg_bbox_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st HB_UNUSED, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + ((hb_extents_t<> *) draw_data)->add_point (to_x, to_y); +} + +static void +svg_bbox_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st HB_UNUSED, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + ((hb_extents_t<> *) draw_data)->add_point (to_x, to_y); +} + +static void +svg_bbox_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st HB_UNUSED, + float control_x, float control_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t<> *ext = (hb_extents_t<> *) draw_data; + ext->add_point (control_x, control_y); + ext->add_point (to_x, to_y); +} + +static void +svg_bbox_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, + void *draw_data, + hb_draw_state_t *st HB_UNUSED, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *user_data HB_UNUSED) +{ + hb_extents_t<> *ext = (hb_extents_t<> *) draw_data; + ext->add_point (control1_x, control1_y); + ext->add_point (control2_x, control2_y); + ext->add_point (to_x, to_y); +} + +static hb_draw_funcs_t * +svg_bbox_draw_funcs () +{ + static hb_draw_funcs_t *funcs = nullptr; + if (unlikely (!funcs)) + { + funcs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (funcs, svg_bbox_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, svg_bbox_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, svg_bbox_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, svg_bbox_cubic_to, nullptr, nullptr); + hb_draw_funcs_make_immutable (funcs); + } + return funcs; +} + +bool +hb_raster_svg_compute_shape_bbox (const hb_svg_shape_emit_data_t &shape, + hb_extents_t<> *bbox) +{ + hb_extents_t<> ext; + hb_svg_shape_emit_data_t tmp = shape; + hb_raster_svg_shape_path_emit (svg_bbox_draw_funcs (), &ext, &tmp); + if (ext.is_empty ()) return false; + *bbox = ext; + return true; +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/test-machinery.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.hh similarity index 66% rename from thirdparty/harfbuzz/upstream/test-machinery.cc rename to thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.hh index 7fc9c24b5..46802e6d7 100644 --- a/thirdparty/harfbuzz/upstream/test-machinery.cc +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-bbox.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Behdad Esfahbod + * Copyright © 2026 Behdad Esfahbod * * This is part of HarfBuzz, a text shaping library. * @@ -20,27 +20,20 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod */ +#ifndef HB_RASTER_SVG_BBOX_HH +#define HB_RASTER_SVG_BBOX_HH + #include "hb.hh" -#include "hb-machinery.hh" -struct hb_intp_lazy_loader_t : hb_lazy_loader_t -{ - static int* create () { return nullptr; } - static void destroy (int* l) {} - static int* get_null () { return nullptr; } -}; +#include "hb-geometry.hh" +#include "hb-raster-svg-parse.hh" -struct hb_void_lazy_loader_t : hb_lazy_loader_t -{ - static void* create () { return nullptr; } - static void destroy (void* l) {} - static void* get_null () { return nullptr; } -}; +HB_INTERNAL bool +hb_raster_svg_compute_shape_bbox (const hb_svg_shape_emit_data_t &shape, + hb_extents_t<> *bbox); -int -main (int argc, char **argv) -{ - return 0; -} +#endif /* HB_RASTER_SVG_BBOX_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-clip.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-clip.cc new file mode 100644 index 000000000..19714eab4 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-clip.cc @@ -0,0 +1,528 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-clip.hh" + +#include "hb-raster.h" +#include "hb-raster-paint.hh" +#include "hb-raster-svg.hh" +#include "hb-raster-svg-base.hh" +#include "hb-decycler.hh" + +#include + +static inline bool +svg_transform_is_identity (const hb_svg_transform_t &t) +{ + return t.xx == 1.f && t.yx == 0.f && + t.xy == 0.f && t.yy == 1.f && + t.dx == 0.f && t.dy == 0.f; +} + +static bool +svg_parse_element_transform (hb_svg_xml_parser_t &parser, + hb_svg_transform_t *out) +{ + hb_svg_style_props_t style_props; + svg_parse_style_props (parser.find_attr ("style"), &style_props); + hb_svg_str_t transform = svg_pick_attr_or_style (parser, style_props.transform, "transform"); + if (!transform.len) + return false; + hb_raster_svg_parse_transform (transform, out); + return true; +} + +struct hb_svg_clip_collect_context_t +{ + hb_svg_defs_t *defs; + hb_svg_clip_path_def_t *clip; + const char *doc_start; + unsigned doc_len; + const OT::SVG::accelerator_t *svg_accel; + const OT::SVG::svg_doc_cache_t *doc_cache; + hb_decycler_t *use_decycler; + bool *had_alloc_failure; +}; + +static inline void +svg_clip_append_shape (hb_svg_clip_collect_context_t *ctx, + const hb_svg_shape_emit_data_t &shape, + const hb_svg_transform_t &transform) +{ + hb_svg_clip_shape_t clip_shape; + clip_shape.shape = shape; + if (!svg_transform_is_identity (transform)) + { + clip_shape.has_transform = true; + clip_shape.transform = transform; + } + if (likely (ctx->defs->clip_shapes.push_or_fail (clip_shape))) + ctx->clip->shape_count++; + else if (ctx->had_alloc_failure) + *ctx->had_alloc_failure = true; +} + +static inline bool +svg_resolve_element_visibility (hb_svg_xml_parser_t &parser, + bool parent_visible) +{ + hb_svg_style_props_t style_props; + svg_parse_style_props (parser.find_attr ("style"), &style_props); + hb_svg_str_t display_str = svg_pick_attr_or_style (parser, style_props.display, "display"); + hb_svg_str_t visibility_str = svg_pick_attr_or_style (parser, style_props.visibility, "visibility"); + if (display_str.trim ().eq_ascii_ci ("none")) + return false; + hb_svg_str_t vis_trim = visibility_str.trim (); + if (!vis_trim.len || vis_trim.eq_ascii_ci ("inherit")) + return parent_visible; + if (vis_trim.eq_ascii_ci ("hidden") || + vis_trim.eq_ascii_ci ("collapse")) + return false; + if (vis_trim.eq_ascii_ci ("visible")) + return true; + return parent_visible; +} + +static void +svg_clip_collect_ref_element (hb_svg_clip_collect_context_t *ctx, + hb_svg_xml_parser_t &parser, + const hb_svg_transform_t &base_transform, + unsigned depth, + bool suppress_viewbox_once = false, + bool parent_visible = true, + bool allow_symbol_once = false); + +static void +svg_clip_collect_use_target (hb_svg_clip_collect_context_t *ctx, + hb_svg_xml_parser_t &use_parser, + const hb_svg_transform_t &base_transform, + unsigned depth) +{ + const unsigned SVG_MAX_CLIP_USE_DEPTH = 64; + if (depth >= SVG_MAX_CLIP_USE_DEPTH) + return; + + hb_svg_str_t href = hb_raster_svg_find_href_attr (use_parser); + hb_svg_str_t ref_id; + if (!hb_raster_svg_parse_local_id_ref (href, &ref_id, nullptr)) + return; + + const char *found = nullptr; + if (!hb_raster_svg_find_element_by_id (ctx->doc_start, ctx->doc_len, + ctx->svg_accel, ctx->doc_cache, + ref_id, &found)) + return; + + hb_decycler_node_t node (*ctx->use_decycler); + if (unlikely (!node.visit ((uintptr_t) found))) + return; + + hb_svg_transform_t effective = base_transform; + float use_x = 0.f, use_y = 0.f, use_w = 0.f, use_h = 0.f; + hb_raster_svg_parse_use_geometry (use_parser, &use_x, &use_y, &use_w, &use_h); + if (use_x != 0.f || use_y != 0.f) + { + hb_svg_transform_t tr; + tr.dx = use_x; + tr.dy = use_y; + effective.multiply (tr); + } + + unsigned remaining = ctx->doc_len - (unsigned) (found - ctx->doc_start); + hb_svg_xml_parser_t ref_parser (found, remaining); + hb_svg_token_type_t rt = ref_parser.next (); + if (rt != SVG_TOKEN_OPEN_TAG && rt != SVG_TOKEN_SELF_CLOSE_TAG) + return; + + bool viewport_mapped = false; + hb_svg_transform_t vb_t; + if (hb_raster_svg_compute_use_target_viewbox_transform (ref_parser, use_w, use_h, &vb_t)) + { + effective.multiply (vb_t); + viewport_mapped = true; + } + + bool allow_symbol = ref_parser.tag_name.eq ("symbol"); + svg_clip_collect_ref_element (ctx, ref_parser, effective, depth + 1, + viewport_mapped, true, allow_symbol); +} + +static void +svg_clip_collect_ref_element (hb_svg_clip_collect_context_t *ctx, + hb_svg_xml_parser_t &parser, + const hb_svg_transform_t &base_transform, + unsigned depth, + bool suppress_viewbox_once, + bool parent_visible, + bool allow_symbol_once) +{ + const unsigned SVG_MAX_CLIP_REF_DEPTH = 64; + if (depth >= SVG_MAX_CLIP_REF_DEPTH) + { + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + + bool is_visible = svg_resolve_element_visibility (parser, parent_visible); + if (!is_visible) + { + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + + /* Definitions are not directly renderable clip geometry. */ + if (parser.tag_name.eq ("defs")) + { + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + if (parser.tag_name.eq ("symbol") && !allow_symbol_once) + { + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + if (parser.tag_name.eq ("symbol")) + allow_symbol_once = false; + + hb_svg_transform_t effective = base_transform; + hb_svg_style_props_t geom_style_props; + svg_parse_style_props (parser.find_attr ("style"), &geom_style_props); + hb_svg_transform_t local_t; + if (svg_parse_element_transform (parser, &local_t)) + effective.multiply (local_t); + if (parser.tag_name.eq ("svg")) + { + float svg_x = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.x, "x")); + float svg_y = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.y, "y")); + if (svg_x != 0.f || svg_y != 0.f) + { + hb_svg_transform_t tr; + tr.dx = svg_x; + tr.dy = svg_y; + effective.multiply (tr); + } + + if (!suppress_viewbox_once) + { + float vb_x = 0.f, vb_y = 0.f, vb_w = 0.f, vb_h = 0.f; + if (hb_raster_svg_parse_viewbox (parser.find_attr ("viewBox"), + &vb_x, &vb_y, &vb_w, &vb_h)) + { + float viewport_w = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.width, "width")); + float viewport_h = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.height, "height")); + if (!(viewport_w > 0.f && viewport_h > 0.f)) + { + viewport_w = vb_w; + viewport_h = vb_h; + } + hb_svg_transform_t vb_t; + if (hb_raster_svg_compute_viewbox_transform (viewport_w, viewport_h, + vb_x, vb_y, vb_w, vb_h, + parser.find_attr ("preserveAspectRatio"), + &vb_t)) + effective.multiply (vb_t); + } + suppress_viewbox_once = false; + } + } + + hb_svg_shape_emit_data_t shape; + if (hb_raster_svg_parse_shape_tag (parser, &shape)) + { + svg_clip_append_shape (ctx, shape, effective); + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + + if (parser.tag_name.eq ("use")) + { + svg_clip_collect_use_target (ctx, parser, effective, depth + 1); + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + + bool is_container = hb_raster_svg_tag_is_container (parser.tag_name); + if (!is_container || parser.self_closing) + { + if (!parser.self_closing) + svg_skip_subtree (parser); + return; + } + + int inner_depth = 1; + while (inner_depth > 0) + { + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_EOF) break; + if (tok == SVG_TOKEN_CLOSE_TAG) + { + inner_depth--; + continue; + } + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + svg_clip_collect_ref_element (ctx, parser, effective, depth + 1, false, is_visible, false); + } +} + +void +hb_raster_svg_process_clip_path_def (hb_svg_defs_t *defs, + hb_svg_xml_parser_t &parser, + hb_svg_token_type_t tok, + const char *doc_start, + unsigned doc_len, + const OT::SVG::accelerator_t *svg_accel, + const OT::SVG::svg_doc_cache_t *doc_cache) +{ + hb_svg_clip_path_def_t clip; + hb_svg_str_t id = parser.find_attr ("id"); + hb_svg_str_t units = parser.find_attr ("clipPathUnits").trim (); + if (units.eq_ascii_ci ("objectBoundingBox")) + clip.units_user_space = false; + else if (units.eq_ascii_ci ("userSpaceOnUse")) + clip.units_user_space = true; + else + clip.units_user_space = true; + + hb_svg_transform_t cp_t; + if (svg_parse_element_transform (parser, &cp_t)) + { + clip.has_clip_transform = true; + clip.clip_transform = cp_t; + } + + clip.first_shape = defs->clip_shapes.length; + clip.shape_count = 0; + + if (tok == SVG_TOKEN_OPEN_TAG) + { + const unsigned SVG_MAX_CLIP_DEPTH = 64; + hb_svg_transform_t inherited[SVG_MAX_CLIP_DEPTH]; + bool inherited_visibility[SVG_MAX_CLIP_DEPTH]; + inherited[0] = hb_svg_transform_t (); + inherited[1] = hb_svg_transform_t (); + inherited_visibility[0] = true; + inherited_visibility[1] = true; + hb_decycler_t use_decycler; + + int cdepth = 1; + bool had_alloc_failure = false; + hb_svg_clip_collect_context_t collect_ctx = { + defs, &clip, + doc_start, doc_len, svg_accel, doc_cache, + &use_decycler, &had_alloc_failure + }; + while (cdepth > 0) + { + hb_svg_token_type_t ct = parser.next (); + if (ct == SVG_TOKEN_EOF) break; + if (ct == SVG_TOKEN_CLOSE_TAG) { cdepth--; continue; } + if (ct == SVG_TOKEN_OPEN_TAG || ct == SVG_TOKEN_SELF_CLOSE_TAG) + { + if (parser.tag_name.eq ("symbol")) + { + if (ct == SVG_TOKEN_OPEN_TAG) + { + int skip_depth = 1; + while (skip_depth > 0) + { + hb_svg_token_type_t st = parser.next (); + if (st == SVG_TOKEN_EOF) break; + if (st == SVG_TOKEN_CLOSE_TAG) skip_depth--; + else if (st == SVG_TOKEN_OPEN_TAG) skip_depth++; + } + } + continue; + } + + if (parser.tag_name.eq ("defs")) + { + if (ct == SVG_TOKEN_OPEN_TAG) + { + int skip_depth = 1; + while (skip_depth > 0) + { + hb_svg_token_type_t st = parser.next (); + if (st == SVG_TOKEN_EOF) break; + if (st == SVG_TOKEN_CLOSE_TAG) skip_depth--; + else if (st == SVG_TOKEN_OPEN_TAG) skip_depth++; + } + } + continue; + } + + bool parent_visible = (unsigned) cdepth < SVG_MAX_CLIP_DEPTH + ? inherited_visibility[cdepth] + : true; + bool is_visible = svg_resolve_element_visibility (parser, parent_visible); + bool is_hidden = !is_visible; + if (is_hidden) + { + if (ct == SVG_TOKEN_OPEN_TAG) + { + int skip_depth = 1; + while (skip_depth > 0) + { + hb_svg_token_type_t st = parser.next (); + if (st == SVG_TOKEN_EOF) break; + if (st == SVG_TOKEN_CLOSE_TAG) skip_depth--; + else if (st == SVG_TOKEN_OPEN_TAG) skip_depth++; + } + } + continue; + } + + hb_svg_transform_t effective = (unsigned) cdepth < SVG_MAX_CLIP_DEPTH + ? inherited[cdepth] + : hb_svg_transform_t (); + + hb_svg_transform_t local; + bool has_local_transform = svg_parse_element_transform (parser, &local); + if (has_local_transform) + { + effective.multiply (local); + } + + if (parser.tag_name.eq ("use")) + { + svg_clip_collect_use_target (&collect_ctx, parser, effective, 0); + } + else + { + hb_svg_shape_emit_data_t shape; + if (hb_raster_svg_parse_shape_tag (parser, &shape)) + svg_clip_append_shape (&collect_ctx, shape, effective); + } + + if (ct == SVG_TOKEN_OPEN_TAG) + { + if ((unsigned) (cdepth + 1) < SVG_MAX_CLIP_DEPTH) + { + inherited[cdepth + 1] = effective; + inherited_visibility[cdepth + 1] = is_visible; + } + cdepth++; + } + } + } + if (had_alloc_failure) + id = {}; + } + + if (id.len) + (void) defs->add_clip_path (hb_bytes_t (id.data, id.len), clip); +} + +struct hb_svg_clip_emit_data_t +{ + const hb_svg_defs_t *defs; + const hb_svg_clip_path_def_t *clip; + hb_transform_t<> base_transform; + hb_transform_t<> bbox_transform; + bool has_bbox_transform = false; +}; + +static inline hb_transform_t<> +svg_to_hb_transform (const hb_svg_transform_t &t) +{ + return hb_transform_t<> (t.xx, t.yx, t.xy, t.yy, t.dx, t.dy); +} + +static void +svg_clip_path_emit (hb_draw_funcs_t *dfuncs, + void *draw_data, + void *user_data) +{ + hb_raster_draw_t *rdr = (hb_raster_draw_t *) draw_data; + hb_svg_clip_emit_data_t *ed = (hb_svg_clip_emit_data_t *) user_data; + const hb_svg_clip_path_def_t *clip = ed->clip; + + for (unsigned i = 0; i < clip->shape_count; i++) + { + const hb_svg_clip_shape_t &s = ed->defs->clip_shapes[clip->first_shape + i]; + hb_transform_t<> t = ed->base_transform; + if (ed->has_bbox_transform) + t.multiply (ed->bbox_transform); + if (clip->has_clip_transform) + t.multiply (svg_to_hb_transform (clip->clip_transform)); + if (s.has_transform) + t.multiply (svg_to_hb_transform (s.transform)); + + hb_raster_draw_set_transform (rdr, t.xx, t.yx, t.xy, t.yy, t.x0, t.y0); + + hb_svg_shape_emit_data_t shape = s.shape; + hb_raster_svg_shape_path_emit (dfuncs, draw_data, &shape); + } +} + +bool +hb_raster_svg_push_clip_path_ref (hb_raster_paint_t *paint, + hb_svg_defs_t *defs, + hb_svg_str_t clip_path_str, + const hb_extents_t<> *object_bbox) +{ + if (clip_path_str.is_null ()) return false; + hb_svg_str_t trimmed = clip_path_str.trim (); + if (!trimmed.len || trimmed.eq_ascii_ci ("none")) return false; + + hb_svg_str_t clip_id; + if (!hb_raster_svg_parse_local_id_ref (trimmed, &clip_id, nullptr)) + return false; + + const hb_svg_clip_path_def_t *clip = defs->find_clip_path (hb_bytes_t (clip_id.data, clip_id.len)); + if (!clip) return false; + + hb_svg_clip_emit_data_t ed; + ed.defs = defs; + ed.clip = clip; + ed.base_transform = paint->current_effective_transform (); + + if (!clip->units_user_space) + { + if (!object_bbox || object_bbox->is_empty ()) + return false; + float w = object_bbox->xmax - object_bbox->xmin; + float h = object_bbox->ymax - object_bbox->ymin; + if (!(std::isfinite (w) && std::isfinite (h)) || w <= 0.f || h <= 0.f) + return false; + ed.has_bbox_transform = true; + ed.bbox_transform = hb_transform_t<> (w, 0, 0, h, object_bbox->xmin, object_bbox->ymin); + } + + hb_raster_paint_push_clip_path (paint, svg_clip_path_emit, &ed); + return true; +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-clip.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-clip.hh new file mode 100644 index 000000000..0b89cc8f0 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-clip.hh @@ -0,0 +1,53 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_CLIP_HH +#define HB_RASTER_SVG_CLIP_HH + +#include "hb.hh" + +#include "OT/Color/svg/svg.hh" +#include "hb-paint.hh" +#include "hb-raster-svg-defs.hh" + +struct hb_raster_paint_t; + +HB_INTERNAL void +hb_raster_svg_process_clip_path_def (hb_svg_defs_t *defs, + hb_svg_xml_parser_t &parser, + hb_svg_token_type_t tok, + const char *doc_start, + unsigned doc_len, + const OT::SVG::accelerator_t *svg_accel, + const OT::SVG::svg_doc_cache_t *doc_cache); + +HB_INTERNAL bool +hb_raster_svg_push_clip_path_ref (hb_raster_paint_t *paint, + hb_svg_defs_t *defs, + hb_svg_str_t clip_path_str, + const hb_extents_t<> *object_bbox); + +#endif /* HB_RASTER_SVG_CLIP_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-color.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-color.cc new file mode 100644 index 000000000..a13634dd4 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-color.cc @@ -0,0 +1,340 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-color.hh" + +#include "hb-raster.h" +#include "hb-raster-svg-base.hh" +#include "hb-ot-color.h" + +#include +#include + +struct hb_svg_named_color_t +{ + const char *name; + uint32_t rgb; /* 0xRRGGBB */ +}; + +static const hb_svg_named_color_t svg_named_colors[] = { + {"aliceblue", 0xF0F8FF}, + {"antiquewhite", 0xFAEBD7}, + {"aqua", 0x00FFFF}, + {"aquamarine", 0x7FFFD4}, + {"azure", 0xF0FFFF}, + {"beige", 0xF5F5DC}, + {"bisque", 0xFFE4C4}, + {"black", 0x000000}, + {"blanchedalmond", 0xFFEBCD}, + {"blue", 0x0000FF}, + {"blueviolet", 0x8A2BE2}, + {"brown", 0xA52A2A}, + {"burlywood", 0xDEB887}, + {"cadetblue", 0x5F9EA0}, + {"chartreuse", 0x7FFF00}, + {"chocolate", 0xD2691E}, + {"coral", 0xFF7F50}, + {"cornflowerblue", 0x6495ED}, + {"cornsilk", 0xFFF8DC}, + {"crimson", 0xDC143C}, + {"cyan", 0x00FFFF}, + {"darkblue", 0x00008B}, + {"darkcyan", 0x008B8B}, + {"darkgoldenrod", 0xB8860B}, + {"darkgray", 0xA9A9A9}, + {"darkgreen", 0x006400}, + {"darkgrey", 0xA9A9A9}, + {"darkkhaki", 0xBDB76B}, + {"darkmagenta", 0x8B008B}, + {"darkolivegreen", 0x556B2F}, + {"darkorange", 0xFF8C00}, + {"darkorchid", 0x9932CC}, + {"darkred", 0x8B0000}, + {"darksalmon", 0xE9967A}, + {"darkseagreen", 0x8FBC8F}, + {"darkslateblue", 0x483D8B}, + {"darkslategray", 0x2F4F4F}, + {"darkslategrey", 0x2F4F4F}, + {"darkturquoise", 0x00CED1}, + {"darkviolet", 0x9400D3}, + {"deeppink", 0xFF1493}, + {"deepskyblue", 0x00BFFF}, + {"dimgray", 0x696969}, + {"dimgrey", 0x696969}, + {"dodgerblue", 0x1E90FF}, + {"firebrick", 0xB22222}, + {"floralwhite", 0xFFFAF0}, + {"forestgreen", 0x228B22}, + {"fuchsia", 0xFF00FF}, + {"gainsboro", 0xDCDCDC}, + {"ghostwhite", 0xF8F8FF}, + {"gold", 0xFFD700}, + {"goldenrod", 0xDAA520}, + {"gray", 0x808080}, + {"green", 0x008000}, + {"greenyellow", 0xADFF2F}, + {"grey", 0x808080}, + {"honeydew", 0xF0FFF0}, + {"hotpink", 0xFF69B4}, + {"indianred", 0xCD5C5C}, + {"indigo", 0x4B0082}, + {"ivory", 0xFFFFF0}, + {"khaki", 0xF0E68C}, + {"lavender", 0xE6E6FA}, + {"lavenderblush", 0xFFF0F5}, + {"lawngreen", 0x7CFC00}, + {"lemonchiffon", 0xFFFACD}, + {"lightblue", 0xADD8E6}, + {"lightcoral", 0xF08080}, + {"lightcyan", 0xE0FFFF}, + {"lightgoldenrodyellow", 0xFAFAD2}, + {"lightgray", 0xD3D3D3}, + {"lightgreen", 0x90EE90}, + {"lightgrey", 0xD3D3D3}, + {"lightpink", 0xFFB6C1}, + {"lightsalmon", 0xFFA07A}, + {"lightseagreen", 0x20B2AA}, + {"lightskyblue", 0x87CEFA}, + {"lightslategray", 0x778899}, + {"lightslategrey", 0x778899}, + {"lightsteelblue", 0xB0C4DE}, + {"lightyellow", 0xFFFFE0}, + {"lime", 0x00FF00}, + {"limegreen", 0x32CD32}, + {"linen", 0xFAF0E6}, + {"magenta", 0xFF00FF}, + {"maroon", 0x800000}, + {"mediumaquamarine", 0x66CDAA}, + {"mediumblue", 0x0000CD}, + {"mediumorchid", 0xBA55D3}, + {"mediumpurple", 0x9370DB}, + {"mediumseagreen", 0x3CB371}, + {"mediumslateblue", 0x7B68EE}, + {"mediumspringgreen", 0x00FA9A}, + {"mediumturquoise", 0x48D1CC}, + {"mediumvioletred", 0xC71585}, + {"midnightblue", 0x191970}, + {"mintcream", 0xF5FFFA}, + {"mistyrose", 0xFFE4E1}, + {"moccasin", 0xFFE4B5}, + {"navajowhite", 0xFFDEAD}, + {"navy", 0x000080}, + {"oldlace", 0xFDF5E6}, + {"olive", 0x808000}, + {"olivedrab", 0x6B8E23}, + {"orange", 0xFFA500}, + {"orangered", 0xFF4500}, + {"orchid", 0xDA70D6}, + {"palegoldenrod", 0xEEE8AA}, + {"palegreen", 0x98FB98}, + {"paleturquoise", 0xAFEEEE}, + {"palevioletred", 0xDB7093}, + {"papayawhip", 0xFFEFD5}, + {"peachpuff", 0xFFDAB9}, + {"peru", 0xCD853F}, + {"pink", 0xFFC0CB}, + {"plum", 0xDDA0DD}, + {"powderblue", 0xB0E0E6}, + {"purple", 0x800080}, + {"rebeccapurple", 0x663399}, + {"red", 0xFF0000}, + {"rosybrown", 0xBC8F8F}, + {"royalblue", 0x4169E1}, + {"saddlebrown", 0x8B4513}, + {"salmon", 0xFA8072}, + {"sandybrown", 0xF4A460}, + {"seagreen", 0x2E8B57}, + {"seashell", 0xFFF5EE}, + {"sienna", 0xA0522D}, + {"silver", 0xC0C0C0}, + {"skyblue", 0x87CEEB}, + {"slateblue", 0x6A5ACD}, + {"slategray", 0x708090}, + {"slategrey", 0x708090}, + {"snow", 0xFFFAFA}, + {"springgreen", 0x00FF7F}, + {"steelblue", 0x4682B4}, + {"tan", 0xD2B48C}, + {"teal", 0x008080}, + {"thistle", 0xD8BFD8}, + {"tomato", 0xFF6347}, + {"turquoise", 0x40E0D0}, + {"violet", 0xEE82EE}, + {"wheat", 0xF5DEB3}, + {"white", 0xFFFFFF}, + {"whitesmoke", 0xF5F5F5}, + {"yellow", 0xFFFF00}, + {"yellowgreen", 0x9ACD32}, +}; + +static int +hexval (char c) +{ + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} + +/* Parse SVG color value; returns HB_COLOR with alpha = 255. + * Sets *is_none if "none". */ +hb_color_t +hb_raster_svg_parse_color (hb_svg_str_t s, + hb_paint_funcs_t *pfuncs, + void *paint_data, + hb_color_t foreground, + hb_face_t *face, + unsigned palette, + bool *is_none) +{ + *is_none = false; + s = s.trim (); + if (!s.len) { *is_none = true; return HB_COLOR (0, 0, 0, 0); } + + if (s.eq_ascii_ci ("none") || s.eq_ascii_ci ("transparent")) + { + *is_none = true; + return HB_COLOR (0, 0, 0, 0); + } + + if (s.eq_ascii_ci ("currentColor")) + return foreground; + + /* var(--colorN) → CPAL palette color */ + if (s.starts_with_ascii_ci ("var(")) + { + const char *p = s.data + 4; + const char *e = s.data + s.len; + while (p < e && *p == ' ') p++; + if (p + 7 < e && p[0] == '-' && p[1] == '-' && p[2] == 'c' && + p[3] == 'o' && p[4] == 'l' && p[5] == 'o' && p[6] == 'r') + { + p += 7; + unsigned color_index = 0; + while (p < e && *p >= '0' && *p <= '9') + color_index = color_index * 10 + (*p++ - '0'); + + hb_color_t palette_color; + if (hb_paint_custom_palette_color (pfuncs, paint_data, color_index, &palette_color)) + return palette_color; + + unsigned count = 1; + hb_ot_color_palette_get_colors (face, palette, color_index, &count, &palette_color); + if (count) + return palette_color; + } + + /* Fallback value after comma: var(--colorN, fallback) */ + p = s.data + 4; + while (p < e && *p != ',') p++; + if (p < e) + { + p++; + while (p < e && *p == ' ') p++; + const char *val_start = p; + /* Find closing paren */ + while (e > val_start && *(e - 1) != ')') e--; + if (e > val_start) e--; + hb_svg_str_t fallback = {val_start, (unsigned) (e - val_start)}; + return hb_raster_svg_parse_color (fallback, pfuncs, paint_data, foreground, face, palette, is_none); + } + + return foreground; + } + + /* #RGB or #RRGGBB */ + if (s.data[0] == '#') + { + if (s.len == 4) /* #RGB */ + { + int r = hexval (s.data[1]); + int g = hexval (s.data[2]); + int b = hexval (s.data[3]); + if (r < 0 || g < 0 || b < 0) return HB_COLOR (0, 0, 0, 255); + return HB_COLOR (b * 17, g * 17, r * 17, 255); + } + if (s.len == 7) /* #RRGGBB */ + { + int r = hexval (s.data[1]) * 16 + hexval (s.data[2]); + int g = hexval (s.data[3]) * 16 + hexval (s.data[4]); + int b = hexval (s.data[5]) * 16 + hexval (s.data[6]); + return HB_COLOR (b, g, r, 255); + } + return HB_COLOR (0, 0, 0, 255); + } + + /* rgb(r, g, b) or rgb(r%, g%, b%) */ + if (s.starts_with ("rgb")) + { + const char *p = s.data + 3; + const char *e = s.data + s.len; + while (p < e && *p != '(') p++; + if (p < e) p++; + + auto read_component = [&] () -> int { + while (p < e && (*p == ' ' || *p == ',')) p++; + char buf[32]; + unsigned n = 0; + while (p < e && n < sizeof (buf) - 1 && ((*p >= '0' && *p <= '9') || *p == '.' || *p == '-')) + buf[n++] = *p++; + bool is_pct = (p < e && *p == '%'); + if (is_pct) p++; + buf[n] = '\0'; + float val = strtof (buf, nullptr); + if (is_pct) val = val * 255.f / 100.f; + return hb_clamp ((int) (val + 0.5f), 0, 255); + }; + + int r = read_component (); + int g = read_component (); + int b = read_component (); + return HB_COLOR (b, g, r, 255); + } + + /* Named colors (case-insensitive comparison) */ + { + char lower[32]; + unsigned n = hb_min (s.len, (unsigned) sizeof (lower) - 1); + for (unsigned i = 0; i < n; i++) + lower[i] = (s.data[i] >= 'A' && s.data[i] <= 'Z') ? s.data[i] + 32 : s.data[i]; + lower[n] = '\0'; + + for (unsigned i = 0; i < ARRAY_LENGTH (svg_named_colors); i++) + if (strcmp (lower, svg_named_colors[i].name) == 0) + { + uint32_t rgb = svg_named_colors[i].rgb; + return HB_COLOR (rgb & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 16) & 0xFF, 255); + } + } + + return HB_COLOR (0, 0, 0, 255); +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/test-unicode-ranges.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-color.hh similarity index 59% rename from thirdparty/harfbuzz/upstream/test-unicode-ranges.cc rename to thirdparty/harfbuzz/upstream/hb-raster-svg-color.hh index 27b5b9e71..893072e14 100644 --- a/thirdparty/harfbuzz/upstream/test-unicode-ranges.cc +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-color.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2018 Google, Inc. + * Copyright © 2026 Behdad Esfahbod * * This is part of HarfBuzz, a text shaping library. * @@ -21,46 +21,24 @@ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * Google Author(s): Garret Rieger + * Author(s): Behdad Esfahbod */ -#include "hb.hh" -#include "hb-ot-os2-unicode-ranges.hh" - -static void -test (hb_codepoint_t cp, unsigned int bit) -{ - if (OT::_hb_ot_os2_get_unicode_range_bit (cp) != bit) - { - fprintf (stderr, "got incorrect bit (%u) for cp 0x%X. Should have been %u.", - OT::_hb_ot_os2_get_unicode_range_bit (cp), - cp, - bit); - abort(); - } -} +#ifndef HB_RASTER_SVG_COLOR_HH +#define HB_RASTER_SVG_COLOR_HH -static void -test_get_unicode_range_bit () -{ - test (0x0000, 0); - test (0x0042, 0); - test (0x007F, 0); - test (0x0080, 1); - - test (0x30A0, 50); - test (0x30B1, 50); - test (0x30FF, 50); +#include "hb.hh" - test (0x10FFFD, 90); +#include "hb-face.hh" +#include "hb-raster-svg-base.hh" - test (0x30000, -1); - test (0x110000, -1); -} +HB_INTERNAL hb_color_t +hb_raster_svg_parse_color (hb_svg_str_t s, + hb_paint_funcs_t *pfuncs, + void *paint_data, + hb_color_t foreground, + hb_face_t *face, + unsigned palette, + bool *is_none); -int -main () -{ - test_get_unicode_range_bit (); - return 0; -} +#endif /* HB_RASTER_SVG_COLOR_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-context.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-context.hh new file mode 100644 index 000000000..5882cab17 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-context.hh @@ -0,0 +1,113 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_CONTEXT_HH +#define HB_RASTER_SVG_CONTEXT_HH + +#include "hb.hh" + +#include "OT/Color/svg/svg.hh" +#include "hb-decycler.hh" +#include "hb-raster-paint.hh" +#include "hb-raster-svg-base.hh" +#include "hb-raster-svg-defs.hh" + +struct hb_svg_fill_context_t +{ + hb_raster_paint_t *paint; + hb_paint_funcs_t *pfuncs; + hb_font_t *font; + unsigned palette; + hb_svg_defs_t *defs; +}; + +struct hb_svg_use_context_t +{ + hb_raster_paint_t *paint; + hb_paint_funcs_t *pfuncs; + + const char *doc_start; + unsigned doc_len; + const OT::SVG::accelerator_t *svg_accel; + const OT::SVG::svg_doc_cache_t *doc_cache; + hb_decycler_t *use_decycler; +}; + +struct hb_svg_render_context_t +{ + hb_raster_paint_t *paint; + hb_paint_funcs_t *pfuncs; + hb_font_t *font; + unsigned palette; + hb_color_t foreground; + hb_svg_defs_t defs; + int depth = 0; + + const char *doc_start; + unsigned doc_len; + const OT::SVG::accelerator_t *svg_accel = nullptr; + const OT::SVG::svg_doc_cache_t *doc_cache = nullptr; + hb_decycler_t use_decycler; + bool suppress_viewbox_once = false; + bool allow_symbol_render_once = false; + + void push_transform (float xx, float yx, float xy, float yy, float dx, float dy) + { + hb_paint_push_transform (pfuncs, paint, xx, yx, xy, yy, dx, dy); + } + void pop_transform () + { + hb_paint_pop_transform (pfuncs, paint); + } + void push_group () + { + hb_paint_push_group (pfuncs, paint); + } + void pop_group (hb_paint_composite_mode_t mode) + { + hb_paint_pop_group (pfuncs, paint, mode); + } + void paint_color (hb_color_t color) + { + hb_paint_color (pfuncs, paint, false, color); + } + void pop_clip () + { + hb_paint_pop_clip (pfuncs, paint); + } +}; + +struct hb_svg_cascade_t +{ + hb_svg_str_t fill; + float fill_opacity = 1.f; + hb_svg_str_t clip_path; + hb_color_t color = HB_COLOR (0, 0, 0, 255); + bool visibility = true; + float opacity = 1.f; +}; + +#endif /* HB_RASTER_SVG_CONTEXT_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.cc new file mode 100644 index 000000000..3b90b457e --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.cc @@ -0,0 +1,108 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-defs-scan.hh" + +#include "hb-raster-svg-clip.hh" +#include "hb-raster-svg-gradient.hh" + +static inline bool +hb_raster_svg_process_defs_child_tag (const hb_svg_defs_scan_context_t *ctx, + hb_svg_xml_parser_t &parser, + hb_svg_token_type_t tok) +{ + if (parser.tag_name.eq ("linearGradient")) + { + hb_raster_svg_process_gradient_def (ctx->defs, parser, tok, SVG_GRADIENT_LINEAR, + ctx->pfuncs, ctx->paint_data, + ctx->foreground, ctx->face, + ctx->palette); + return true; + } + if (parser.tag_name.eq ("radialGradient")) + { + hb_raster_svg_process_gradient_def (ctx->defs, parser, tok, SVG_GRADIENT_RADIAL, + ctx->pfuncs, ctx->paint_data, + ctx->foreground, ctx->face, + ctx->palette); + return true; + } + if (parser.tag_name.eq ("clipPath")) + { + hb_raster_svg_process_clip_path_def (ctx->defs, parser, tok, + ctx->doc_start, ctx->doc_len, + ctx->svg_accel, ctx->doc_cache); + return true; + } + return false; +} + +void +hb_raster_svg_process_defs_element (const hb_svg_defs_scan_context_t *ctx, + hb_svg_xml_parser_t &parser) +{ + int depth = 1; + + while (depth > 0) + { + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_EOF) break; + + if (tok == SVG_TOKEN_CLOSE_TAG) + { + depth--; + continue; + } + + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + { + if (!hb_raster_svg_process_defs_child_tag (ctx, parser, tok) && + tok == SVG_TOKEN_OPEN_TAG) + depth++; + } + } +} + +void +hb_raster_svg_collect_defs (const hb_svg_defs_scan_context_t *ctx, + const char *data, + unsigned data_len) +{ + hb_svg_xml_parser_t parser (data, data_len); + while (true) + { + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_EOF) break; + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + hb_raster_svg_process_defs_child_tag (ctx, parser, tok); + } +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/test-multimap.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.hh similarity index 54% rename from thirdparty/harfbuzz/upstream/test-multimap.cc rename to thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.hh index 8cd8f5285..bddad1f74 100644 --- a/thirdparty/harfbuzz/upstream/test-multimap.cc +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs-scan.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Behdad Esfahbod + * Copyright © 2026 Behdad Esfahbod * * This is part of HarfBuzz, a text shaping library. * @@ -20,40 +20,39 @@ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod */ -#include "hb.hh" -#include "hb-multimap.hh" - -int -main (int argc, char **argv) -{ - hb_multimap_t m; - - assert (m.get (10).length == 0); +#ifndef HB_RASTER_SVG_DEFS_SCAN_HH +#define HB_RASTER_SVG_DEFS_SCAN_HH - m.add (10, 11); - assert (m.get (10).length == 1); - - m.add (10, 12); - assert (m.get (10).length == 2); - - m.add (10, 13); - assert (m.get (10).length == 3); - assert (m.get (10)[0] == 11); - assert (m.get (10)[1] == 12); - assert (m.get (10)[2] == 13); +#include "hb.hh" - assert (m.get (11).length == 0); - m.add (11, 14); - assert (m.get (10).length == 3); - assert (m.get (11).length == 1); - assert (m.get (12).length == 0); - assert (m.get (10)[0] == 11); - assert (m.get (10)[1] == 12); - assert (m.get (10)[2] == 13); - assert (m.get (11)[0] == 14); - assert (m.get (12)[0] == 0); // Array fallback value +#include "OT/Color/svg/svg.hh" +#include "hb-raster-svg-defs.hh" - return 0; -} +struct hb_svg_defs_scan_context_t +{ + hb_svg_defs_t *defs; + hb_paint_funcs_t *pfuncs; + void *paint_data; + hb_color_t foreground; + hb_face_t *face; + unsigned palette; + const char *doc_start; + unsigned doc_len; + const OT::SVG::accelerator_t *svg_accel; + const OT::SVG::svg_doc_cache_t *doc_cache; +}; + +HB_INTERNAL void +hb_raster_svg_process_defs_element (const hb_svg_defs_scan_context_t *ctx, + hb_svg_xml_parser_t &parser); + +HB_INTERNAL void +hb_raster_svg_collect_defs (const hb_svg_defs_scan_context_t *ctx, + const char *data, + unsigned data_len); + +#endif /* HB_RASTER_SVG_DEFS_SCAN_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-defs.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs.cc new file mode 100644 index 000000000..034144167 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs.cc @@ -0,0 +1,121 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-defs.hh" + +#include + +hb_svg_defs_t::~hb_svg_defs_t () +{ + for (unsigned i = 0; i < owned_id_strings.length; i++) + hb_free (owned_id_strings.arrayZ[i]); +} + +bool +hb_svg_defs_t::add_id_mapping (hb_hashmap_t *map, + hb_bytes_t id, + unsigned idx) +{ + if (!id.length) + return false; + if (map->has (id)) + return true; + + unsigned n = (unsigned) id.length; + char *owned = (char *) hb_malloc (n + 1); + if (unlikely (!owned)) + return false; + hb_memcpy (owned, id.arrayZ, n); + owned[n] = '\0'; + if (unlikely (!owned_id_strings.push_or_fail (owned))) + { + hb_free (owned); + return false; + } + + hb_bytes_t owned_key = hb_bytes_t (owned, n); + if (unlikely (!map->set (owned_key, idx))) + return false; + return true; +} + +bool +hb_svg_defs_t::add_gradient (hb_bytes_t id, const hb_svg_gradient_t &grad) +{ + unsigned idx = gradients.length; + gradients.push (grad); + if (unlikely (gradients.in_error ())) + return false; + + if (unlikely (!add_id_mapping (&gradient_by_id, id, idx))) + { + gradients.pop (); + return false; + } + return true; +} + +const hb_svg_gradient_t * +hb_svg_defs_t::find_gradient (hb_bytes_t id) const +{ + if (!id.length) return nullptr; + unsigned *idx = nullptr; + if (gradient_by_id.has (id, &idx)) + return &gradients[*idx]; + return nullptr; +} + +bool +hb_svg_defs_t::add_clip_path (hb_bytes_t id, const hb_svg_clip_path_def_t &clip) +{ + unsigned idx = clip_paths.length; + clip_paths.push (clip); + if (unlikely (clip_paths.in_error ())) + return false; + + if (unlikely (!add_id_mapping (&clip_path_by_id, id, idx))) + { + clip_paths.pop (); + return false; + } + return true; +} + +const hb_svg_clip_path_def_t * +hb_svg_defs_t::find_clip_path (hb_bytes_t id) const +{ + if (!id.length) return nullptr; + unsigned *idx = nullptr; + if (clip_path_by_id.has (id, &idx)) + return &clip_paths[*idx]; + return nullptr; +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-defs.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs.hh new file mode 100644 index 000000000..525d67519 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-defs.hh @@ -0,0 +1,108 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_DEFS_HH +#define HB_RASTER_SVG_DEFS_HH + +#include "hb.hh" + +#include "hb-map.hh" +#include "hb-raster-svg-parse.hh" + +enum hb_svg_gradient_type_t +{ + SVG_GRADIENT_LINEAR, + SVG_GRADIENT_RADIAL +}; + +struct hb_svg_gradient_stop_t +{ + float offset; + hb_color_t color; + bool is_current_color = false; +}; + +struct hb_svg_gradient_t +{ + hb_svg_gradient_type_t type; + + hb_paint_extend_t spread = HB_PAINT_EXTEND_PAD; + bool has_spread = false; + hb_svg_transform_t gradient_transform; + bool has_gradient_transform = false; + bool units_user_space = false; + bool has_units_user_space = false; + + float x1 = 0, y1 = 0, x2 = 1, y2 = 0; + bool has_x1 = false, has_y1 = false, has_x2 = false, has_y2 = false; + + float cx = 0.5f, cy = 0.5f, r = 0.5f; + float fx = -1.f, fy = -1.f, fr = 0.f; + bool has_cx = false, has_cy = false, has_r = false; + bool has_fx = false, has_fy = false, has_fr = false; + + hb_vector_t stops; + + hb_bytes_t href_id = {}; +}; + +struct hb_svg_clip_path_def_t +{ + unsigned first_shape = 0; + unsigned shape_count = 0; + hb_svg_transform_t clip_transform; + bool has_clip_transform = false; + bool units_user_space = true; +}; + +struct hb_svg_clip_shape_t +{ + hb_svg_shape_emit_data_t shape; + hb_svg_transform_t transform; + bool has_transform = false; +}; + +struct hb_svg_defs_t +{ + hb_vector_t gradients; + hb_vector_t clip_shapes; + hb_vector_t clip_paths; + hb_hashmap_t gradient_by_id; + hb_hashmap_t clip_path_by_id; + hb_vector_t owned_id_strings; + + HB_INTERNAL ~hb_svg_defs_t (); + + HB_INTERNAL bool add_id_mapping (hb_hashmap_t *map, + hb_bytes_t id, + unsigned idx); + HB_INTERNAL bool add_gradient (hb_bytes_t id, const hb_svg_gradient_t &grad); + HB_INTERNAL const hb_svg_gradient_t *find_gradient (hb_bytes_t id) const; + HB_INTERNAL bool add_clip_path (hb_bytes_t id, const hb_svg_clip_path_def_t &clip); + HB_INTERNAL const hb_svg_clip_path_def_t *find_clip_path (hb_bytes_t id) const; +}; + +#endif /* HB_RASTER_SVG_DEFS_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-fill.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-fill.cc new file mode 100644 index 000000000..98991ec50 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-fill.cc @@ -0,0 +1,300 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-fill.hh" + +#include "hb-raster-svg-base.hh" +#include "hb-raster-svg-color.hh" +#include "hb-decycler.hh" + +#include + +struct hb_svg_color_line_data_t +{ + const hb_svg_gradient_t *grad; + hb_paint_extend_t extend; + float alpha_scale; + hb_color_t current_color; +}; + +static unsigned +svg_color_line_get_stops (hb_color_line_t *color_line HB_UNUSED, + void *color_line_data, + unsigned int start, + unsigned int *count, + hb_color_stop_t *color_stops, + void *user_data HB_UNUSED) +{ + hb_svg_color_line_data_t *cl = (hb_svg_color_line_data_t *) color_line_data; + const hb_svg_gradient_t *grad = cl->grad; + unsigned total = grad->stops.length; + + if (count) + { + unsigned n = hb_min (*count, total > start ? total - start : 0u); + for (unsigned i = 0; i < n; i++) + { + const hb_svg_gradient_stop_t &stop = grad->stops[start + i]; + color_stops[i].offset = stop.offset; + color_stops[i].is_foreground = false; + hb_color_t c = stop.is_current_color ? cl->current_color : stop.color; + if (stop.is_current_color) + { + uint8_t a = (uint8_t) hb_raster_div255 (hb_color_get_alpha (c) * hb_color_get_alpha (stop.color)); + c = HB_COLOR (hb_color_get_blue (c), + hb_color_get_green (c), + hb_color_get_red (c), + a); + } + if (cl->alpha_scale < 1.f) + { + uint8_t a = (uint8_t) hb_clamp ((int) (hb_color_get_alpha (c) * cl->alpha_scale + 0.5f), 0, 255); + c = HB_COLOR (hb_color_get_blue (c), + hb_color_get_green (c), + hb_color_get_red (c), + a); + } + color_stops[i].color = c; + } + *count = n; + } + return total; +} + +static hb_paint_extend_t +svg_color_line_get_extend (hb_color_line_t *color_line HB_UNUSED, + void *color_line_data, + void *user_data HB_UNUSED) +{ + hb_svg_color_line_data_t *cl = (hb_svg_color_line_data_t *) color_line_data; + return cl->extend; +} + +static bool +svg_parse_paint_url_with_fallback (hb_svg_str_t s, + hb_svg_str_t *out_id, + hb_svg_str_t *fallback) +{ + if (out_id) *out_id = {}; + hb_svg_str_t id; + if (!hb_raster_svg_parse_local_id_ref (s, &id, fallback)) + return false; + if (!s.trim ().starts_with_ascii_ci ("url(")) + return false; + if (out_id) *out_id = id; + return id.len > 0; +} + +void +hb_raster_svg_emit_fill (const hb_svg_fill_context_t *ctx, + hb_svg_str_t fill_str, + float fill_opacity, + const hb_extents_t<> *object_bbox, + hb_color_t current_color) +{ + bool is_none = false; + + hb_svg_str_t url_id; + hb_svg_str_t fallback_paint; + bool has_url_paint = svg_parse_paint_url_with_fallback (fill_str, &url_id, &fallback_paint); + + const hb_svg_gradient_t *grad = has_url_paint ? ctx->defs->find_gradient (hb_bytes_t (url_id.data, url_id.len)) : nullptr; + if (has_url_paint && !grad) + { + if (fallback_paint.len) + hb_raster_svg_emit_fill (ctx, fallback_paint, fill_opacity, object_bbox, current_color); + return; + } + if (grad) + { + const unsigned SVG_MAX_GRADIENT_REF_DEPTH = 1024; + hb_vector_t chain; + hb_decycler_t decycler; + const hb_svg_gradient_t *cur = grad; + while (cur) + { + if (chain.length >= SVG_MAX_GRADIENT_REF_DEPTH) + break; + + hb_decycler_node_t node (decycler); + if (unlikely (!node.visit ((uintptr_t) cur))) + break; + + if (unlikely (!chain.push_or_fail (cur))) + { + if (fallback_paint.len) + hb_raster_svg_emit_fill (ctx, fallback_paint, fill_opacity, object_bbox, current_color); + return; + } + + if (!cur->href_id.length) break; + const hb_svg_gradient_t *next = ctx->defs->find_gradient (cur->href_id); + if (!next) break; + cur = next; + } + if (!chain.length) + { + if (fallback_paint.len) + hb_raster_svg_emit_fill (ctx, fallback_paint, fill_opacity, object_bbox, current_color); + return; + } + + if (!chain.length) { + if (fallback_paint.len) + hb_raster_svg_emit_fill (ctx, fallback_paint, fill_opacity, object_bbox, current_color); + return; + } + hb_svg_gradient_t effective = *chain.arrayZ[chain.length - 1]; + for (int i = (int) chain.length - 2; i >= 0; i--) + { + const hb_svg_gradient_t *g = chain.arrayZ[i]; + effective.type = g->type; + if (g->stops.length) effective.stops = g->stops; + if (g->has_spread) { effective.spread = g->spread; effective.has_spread = true; } + if (g->has_units_user_space) + { + effective.units_user_space = g->units_user_space; + effective.has_units_user_space = true; + } + if (g->has_gradient_transform) + { + effective.gradient_transform = g->gradient_transform; + effective.has_gradient_transform = true; + } + if (g->has_x1) { effective.x1 = g->x1; effective.has_x1 = true; } + if (g->has_y1) { effective.y1 = g->y1; effective.has_y1 = true; } + if (g->has_x2) { effective.x2 = g->x2; effective.has_x2 = true; } + if (g->has_y2) { effective.y2 = g->y2; effective.has_y2 = true; } + if (g->has_cx) { effective.cx = g->cx; effective.has_cx = true; } + if (g->has_cy) { effective.cy = g->cy; effective.has_cy = true; } + if (g->has_r) { effective.r = g->r; effective.has_r = true; } + if (g->has_fx) { effective.fx = g->fx; effective.has_fx = true; } + if (g->has_fy) { effective.fy = g->fy; effective.has_fy = true; } + if (g->has_fr) { effective.fr = g->fr; effective.has_fr = true; } + } + if (!effective.stops.length) + { + if (fallback_paint.len) + hb_raster_svg_emit_fill (ctx, fallback_paint, fill_opacity, object_bbox, current_color); + return; + } + + hb_svg_color_line_data_t cl_data; + cl_data.grad = &effective; + cl_data.extend = effective.spread; + cl_data.alpha_scale = hb_clamp (fill_opacity, 0.f, 1.f); + cl_data.current_color = current_color; + + hb_color_line_t cl = { + &cl_data, + svg_color_line_get_stops, nullptr, + svg_color_line_get_extend, nullptr + }; + + bool has_bbox_transform = !effective.units_user_space && object_bbox && !object_bbox->is_empty (); + if (has_bbox_transform) + { + float w = object_bbox->xmax - object_bbox->xmin; + float h = object_bbox->ymax - object_bbox->ymin; + if (std::isfinite (w) && std::isfinite (h) && w > 0.f && h > 0.f) + hb_paint_push_transform (ctx->pfuncs, ctx->paint, w, 0, 0, h, object_bbox->xmin, object_bbox->ymin); + else + has_bbox_transform = false; + } + + if (effective.has_gradient_transform) + hb_paint_push_transform (ctx->pfuncs, ctx->paint, + effective.gradient_transform.xx, + effective.gradient_transform.yx, + effective.gradient_transform.xy, + effective.gradient_transform.yy, + effective.gradient_transform.dx, + effective.gradient_transform.dy); + + if (effective.type == SVG_GRADIENT_LINEAR) + { + hb_paint_linear_gradient (ctx->pfuncs, ctx->paint, &cl, + effective.x1, effective.y1, + effective.x2, effective.y2, + effective.x2 - (effective.y2 - effective.y1), + effective.y2 + (effective.x2 - effective.x1)); + } + else + { + if (!std::isfinite (effective.r) || effective.r < 0.f) + { + if (effective.has_gradient_transform) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); + if (has_bbox_transform) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); + if (fallback_paint.len) + hb_raster_svg_emit_fill (ctx, fallback_paint, fill_opacity, object_bbox, current_color); + return; + } + + float fx = effective.has_fx ? effective.fx : effective.cx; + float fy = effective.has_fy ? effective.fy : effective.cy; + float fr = effective.has_fr ? effective.fr : 0.f; + if (!std::isfinite (fr) || fr < 0.f) + fr = 0.f; + fr = hb_min (fr, effective.r); + + hb_paint_radial_gradient (ctx->pfuncs, ctx->paint, &cl, + fx, fy, fr, + effective.cx, effective.cy, effective.r); + } + + if (effective.has_gradient_transform) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); + if (has_bbox_transform) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); + + return; + } + + hb_color_t color = hb_raster_svg_parse_color (fill_str, + ctx->pfuncs, + ctx->paint, + current_color, + hb_font_get_face (ctx->font), + ctx->palette, + &is_none); + if (is_none) return; + + if (fill_opacity < 1.f) + color = HB_COLOR (hb_color_get_blue (color), + hb_color_get_green (color), + hb_color_get_red (color), + (uint8_t) (hb_color_get_alpha (color) * fill_opacity + 0.5f)); + + hb_paint_color (ctx->pfuncs, ctx->paint, false, color); +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-fill.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-fill.hh new file mode 100644 index 000000000..ce4ceecd9 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-fill.hh @@ -0,0 +1,41 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_FILL_HH +#define HB_RASTER_SVG_FILL_HH + +#include "hb.hh" + +#include "hb-raster-svg-context.hh" + +HB_INTERNAL void +hb_raster_svg_emit_fill (const hb_svg_fill_context_t *ctx, + hb_svg_str_t fill_str, + float fill_opacity, + const hb_extents_t<> *object_bbox, + hb_color_t current_color); + +#endif /* HB_RASTER_SVG_FILL_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.cc new file mode 100644 index 000000000..cf9e51df1 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.cc @@ -0,0 +1,245 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-gradient.hh" + +#include "hb-raster-svg-base.hh" + +static bool +svg_parse_gradient_stop (hb_svg_xml_parser_t &parser, + hb_svg_gradient_t &grad, + hb_paint_funcs_t *pfuncs, + void *paint_data, + hb_color_t foreground, + hb_face_t *face, + unsigned palette) +{ + const unsigned SVG_MAX_GRADIENT_STOPS = 1024; + if (grad.stops.length >= SVG_MAX_GRADIENT_STOPS) + return true; + + hb_svg_attr_view_t attrs (parser); + hb_svg_str_t style = attrs.get ("style"); + hb_svg_style_props_t style_props; + svg_parse_style_props (style, &style_props); + hb_svg_str_t offset_str = svg_pick_attr_or_style (parser, style_props.offset, "offset"); + hb_svg_str_t color_str = svg_pick_attr_or_style (parser, style_props.stop_color, "stop-color"); + hb_svg_str_t opacity_str = svg_pick_attr_or_style (parser, style_props.stop_opacity, "stop-opacity"); + hb_svg_str_t display_str = svg_pick_attr_or_style (parser, style_props.display, "display"); + hb_svg_str_t visibility_str = svg_pick_attr_or_style (parser, style_props.visibility, "visibility"); + + if (display_str.trim ().eq_ascii_ci ("none")) + return true; + hb_svg_str_t visibility_trim = visibility_str.trim (); + if (visibility_trim.eq_ascii_ci ("hidden") || + visibility_trim.eq_ascii_ci ("collapse")) + return true; + + float offset = 0; + if (offset_str.len) + offset = hb_clamp (svg_parse_number_or_percent (offset_str, nullptr), 0.f, 1.f); + if (grad.stops.length) + offset = hb_max (offset, grad.stops.arrayZ[grad.stops.length - 1].offset); + + bool is_none = false; + hb_color_t color = HB_COLOR (0, 0, 0, 255); + bool is_current_color = false; + if (color_str.len && !svg_str_is_inherit (color_str)) + { + is_current_color = color_str.trim ().eq_ascii_ci ("currentColor"); + color = hb_raster_svg_parse_color (color_str, pfuncs, paint_data, foreground, face, palette, &is_none); + } + + if (opacity_str.len && !svg_str_is_inherit (opacity_str)) + { + float opacity = svg_parse_float_clamped01 (opacity_str); + color = HB_COLOR (hb_color_get_blue (color), + hb_color_get_green (color), + hb_color_get_red (color), + (uint8_t) (hb_color_get_alpha (color) * opacity + 0.5f)); + } + + hb_svg_gradient_stop_t stop; + stop.offset = offset; + stop.color = color; + stop.is_current_color = is_current_color; + return grad.stops.push_or_fail (stop); +} + +static void +svg_parse_gradient_attrs (hb_svg_xml_parser_t &parser, + hb_svg_gradient_t &grad) +{ + hb_svg_style_props_t style_props; + svg_parse_style_props (parser.find_attr ("style"), &style_props); + + hb_svg_str_t spread_str = svg_pick_attr_or_style (parser, style_props.spread_method, "spreadMethod").trim (); + if (spread_str.eq_ascii_ci ("reflect")) + { + grad.spread = HB_PAINT_EXTEND_REFLECT; + grad.has_spread = true; + } + else if (spread_str.eq_ascii_ci ("repeat")) + { + grad.spread = HB_PAINT_EXTEND_REPEAT; + grad.has_spread = true; + } + else if (spread_str.eq_ascii_ci ("pad")) + { + grad.spread = HB_PAINT_EXTEND_PAD; + grad.has_spread = true; + } + + hb_svg_str_t units_str = svg_pick_attr_or_style (parser, style_props.gradient_units, "gradientUnits").trim (); + if (units_str.eq_ascii_ci ("userSpaceOnUse")) + { + grad.units_user_space = true; + grad.has_units_user_space = true; + } + else if (units_str.eq_ascii_ci ("objectBoundingBox")) + { + grad.units_user_space = false; + grad.has_units_user_space = true; + } + + hb_svg_str_t transform_str = svg_pick_attr_or_style (parser, style_props.gradient_transform, "gradientTransform"); + if (transform_str.len) + { + grad.has_gradient_transform = true; + hb_raster_svg_parse_transform (transform_str, &grad.gradient_transform); + } + + hb_svg_str_t href = hb_raster_svg_find_href_attr (parser); + if (href.len) + { + hb_svg_str_t href_id; + if (hb_raster_svg_parse_local_id_ref (href, &href_id, nullptr)) + grad.href_id = hb_bytes_t (href_id.data, href_id.len); + } +} + +static void +svg_parse_gradient_geometry_attrs (hb_svg_xml_parser_t &parser, + hb_svg_gradient_t &grad) +{ + hb_svg_style_props_t style_props; + svg_parse_style_props (parser.find_attr ("style"), &style_props); + if (grad.type == SVG_GRADIENT_LINEAR) + { + hb_svg_str_t x1_str = svg_pick_attr_or_style (parser, style_props.x1, "x1"); + hb_svg_str_t y1_str = svg_pick_attr_or_style (parser, style_props.y1, "y1"); + hb_svg_str_t x2_str = svg_pick_attr_or_style (parser, style_props.x2, "x2"); + hb_svg_str_t y2_str = svg_pick_attr_or_style (parser, style_props.y2, "y2"); + if (x1_str.len) { grad.x1 = svg_parse_number_or_percent (x1_str, nullptr); grad.has_x1 = true; } + if (y1_str.len) { grad.y1 = svg_parse_number_or_percent (y1_str, nullptr); grad.has_y1 = true; } + if (x2_str.len) { grad.x2 = svg_parse_number_or_percent (x2_str, nullptr); grad.has_x2 = true; } + if (y2_str.len) { grad.y2 = svg_parse_number_or_percent (y2_str, nullptr); grad.has_y2 = true; } + + if (!grad.has_x2) + grad.x2 = 1.f; + } + else + { + hb_svg_str_t cx_str = svg_pick_attr_or_style (parser, style_props.cx, "cx"); + hb_svg_str_t cy_str = svg_pick_attr_or_style (parser, style_props.cy, "cy"); + hb_svg_str_t r_str = svg_pick_attr_or_style (parser, style_props.r, "r"); + hb_svg_str_t fx_str = svg_pick_attr_or_style (parser, style_props.fx, "fx"); + hb_svg_str_t fy_str = svg_pick_attr_or_style (parser, style_props.fy, "fy"); + hb_svg_str_t fr_str = svg_pick_attr_or_style (parser, style_props.fr, "fr"); + + if (cx_str.len) { grad.cx = svg_parse_number_or_percent (cx_str, nullptr); grad.has_cx = true; } + if (cy_str.len) { grad.cy = svg_parse_number_or_percent (cy_str, nullptr); grad.has_cy = true; } + if (r_str.len) { grad.r = svg_parse_number_or_percent (r_str, nullptr); grad.has_r = true; } + if (fx_str.len) { grad.fx = svg_parse_number_or_percent (fx_str, nullptr); grad.has_fx = true; } + if (fy_str.len) { grad.fy = svg_parse_number_or_percent (fy_str, nullptr); grad.has_fy = true; } + if (fr_str.len) { grad.fr = svg_parse_number_or_percent (fr_str, nullptr); grad.has_fr = true; } + } +} + +static void +svg_parse_gradient_children (hb_svg_defs_t *defs, + hb_svg_xml_parser_t &parser, + hb_svg_gradient_t &grad, + hb_svg_str_t *id, + hb_paint_funcs_t *pfuncs, + void *paint_data, + hb_color_t foreground, + hb_face_t *face, + unsigned palette) +{ + int gdepth = 1; + bool had_alloc_failure = false; + while (gdepth > 0) + { + hb_svg_token_type_t gt = parser.next (); + if (gt == SVG_TOKEN_EOF) break; + if (gt == SVG_TOKEN_CLOSE_TAG) { gdepth--; continue; } + if ((gt == SVG_TOKEN_OPEN_TAG || gt == SVG_TOKEN_SELF_CLOSE_TAG) && + parser.tag_name.eq ("stop")) + if (unlikely (!svg_parse_gradient_stop (parser, grad, + pfuncs, paint_data, + foreground, face, + palette))) + had_alloc_failure = true; + if (gt == SVG_TOKEN_OPEN_TAG && !parser.tag_name.eq ("stop")) + gdepth++; + } + if (had_alloc_failure || defs->gradients.in_error ()) + *id = {}; +} + +void +hb_raster_svg_process_gradient_def (hb_svg_defs_t *defs, + hb_svg_xml_parser_t &parser, + hb_svg_token_type_t tok, + hb_svg_gradient_type_t type, + hb_paint_funcs_t *pfuncs, + void *paint_data, + hb_color_t foreground, + hb_face_t *face, + unsigned palette) +{ + hb_svg_gradient_t grad; + grad.type = type; + svg_parse_gradient_geometry_attrs (parser, grad); + svg_parse_gradient_attrs (parser, grad); + + hb_svg_str_t id = parser.find_attr ("id"); + if (tok == SVG_TOKEN_OPEN_TAG) + svg_parse_gradient_children (defs, parser, grad, &id, + pfuncs, paint_data, + foreground, face, + palette); + + if (id.len) + (void) defs->add_gradient (hb_bytes_t (id.data, id.len), grad); +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.hh new file mode 100644 index 000000000..0b1e6fd0c --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-gradient.hh @@ -0,0 +1,46 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_GRADIENT_HH +#define HB_RASTER_SVG_GRADIENT_HH + +#include "hb.hh" + +#include "hb-raster-svg-color.hh" +#include "hb-raster-svg-defs.hh" + +HB_INTERNAL void +hb_raster_svg_process_gradient_def (hb_svg_defs_t *defs, + hb_svg_xml_parser_t &parser, + hb_svg_token_type_t tok, + hb_svg_gradient_type_t type, + hb_paint_funcs_t *pfuncs, + void *paint_data, + hb_color_t foreground, + hb_face_t *face, + unsigned palette); + +#endif /* HB_RASTER_SVG_GRADIENT_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-parse.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-parse.cc new file mode 100644 index 000000000..0bdb47106 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-parse.cc @@ -0,0 +1,668 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-parse.hh" + +#include +bool +hb_raster_svg_parse_transform (hb_svg_str_t s, hb_svg_transform_t *out) +{ + hb_svg_float_parser_t fp (s); + + while (fp.p < fp.end) + { + fp.skip_ws_comma (); + if (fp.p >= fp.end) break; + + const char *start = fp.p; + while (fp.p < fp.end && *fp.p != '(') fp.p++; + hb_svg_str_t func_name = {start, (unsigned) (fp.p - start)}; + + while (func_name.len && (func_name.data[func_name.len - 1] == ' ' || + func_name.data[func_name.len - 1] == '\t')) + func_name.len--; + + if (fp.p >= fp.end) break; + fp.p++; + + hb_svg_transform_t t; + + if (func_name.eq_ascii_ci ("matrix")) + { + t.xx = fp.next_float (); + t.yx = fp.next_float (); + t.xy = fp.next_float (); + t.yy = fp.next_float (); + t.dx = fp.next_float (); + t.dy = fp.next_float (); + } + else if (func_name.eq_ascii_ci ("translate")) + { + t.dx = fp.next_float (); + fp.skip_ws_comma (); + if (fp.p < fp.end && *fp.p != ')') + t.dy = fp.next_float (); + } + else if (func_name.eq_ascii_ci ("scale")) + { + t.xx = fp.next_float (); + fp.skip_ws_comma (); + if (fp.p < fp.end && *fp.p != ')') + t.yy = fp.next_float (); + else + t.yy = t.xx; + } + else if (func_name.eq_ascii_ci ("rotate")) + { + float angle = fp.next_float () * (float) M_PI / 180.f; + float cs = cosf (angle), sn = sinf (angle); + fp.skip_ws_comma (); + if (fp.p < fp.end && *fp.p != ')') + { + float cx = fp.next_float (); + float cy = fp.next_float (); + t.xx = cs; t.yx = sn; + t.xy = -sn; t.yy = cs; + t.dx = cx - cs * cx + sn * cy; + t.dy = cy - sn * cx - cs * cy; + } + else + { + t.xx = cs; t.yx = sn; + t.xy = -sn; t.yy = cs; + } + } + else if (func_name.eq_ascii_ci ("skewX")) + { + float angle = fp.next_float () * (float) M_PI / 180.f; + t.xy = tanf (angle); + } + else if (func_name.eq_ascii_ci ("skewY")) + { + float angle = fp.next_float () * (float) M_PI / 180.f; + t.yx = tanf (angle); + } + + while (fp.p < fp.end && *fp.p != ')') fp.p++; + if (fp.p < fp.end) fp.p++; + + out->multiply (t); + } + return true; +} + +static void +svg_arc_to_cubics (hb_draw_funcs_t *dfuncs, void *draw_data, hb_draw_state_t *st, + float cx, float cy, + float rx, float ry, + float phi, float theta1, float dtheta) +{ + int n_segs = (int) ceilf (fabsf (dtheta) / ((float) M_PI / 2.f)); + if (n_segs < 1) n_segs = 1; + float seg_angle = dtheta / n_segs; + + float cos_phi = cosf (phi); + float sin_phi = sinf (phi); + + for (int i = 0; i < n_segs; i++) + { + float t1 = theta1 + i * seg_angle; + float t2 = t1 + seg_angle; + float alpha = sinf (seg_angle) * + (sqrtf (4.f + 3.f * tanf (seg_angle / 2.f) * tanf (seg_angle / 2.f)) - 1.f) / 3.f; + + float cos_t1 = cosf (t1), sin_t1 = sinf (t1); + float cos_t2 = cosf (t2), sin_t2 = sinf (t2); + + float e1x = rx * cos_t1, e1y = ry * sin_t1; + float e2x = rx * cos_t2, e2y = ry * sin_t2; + float d1x = -rx * sin_t1, d1y = ry * cos_t1; + float d2x = -rx * sin_t2, d2y = ry * cos_t2; + + float cp1x = e1x + alpha * d1x; + float cp1y = e1y + alpha * d1y; + float cp2x = e2x - alpha * d2x; + float cp2y = e2y - alpha * d2y; + + float r_cp1x = cos_phi * cp1x - sin_phi * cp1y + cx; + float r_cp1y = sin_phi * cp1x + cos_phi * cp1y + cy; + float r_cp2x = cos_phi * cp2x - sin_phi * cp2y + cx; + float r_cp2y = sin_phi * cp2x + cos_phi * cp2y + cy; + float r_e2x = cos_phi * e2x - sin_phi * e2y + cx; + float r_e2y = sin_phi * e2x + cos_phi * e2y + cy; + + hb_draw_cubic_to (dfuncs, draw_data, st, + r_cp1x, r_cp1y, + r_cp2x, r_cp2y, + r_e2x, r_e2y); + } +} + +static void +svg_arc_endpoint_to_center (float x1, float y1, float x2, float y2, + float rx, float ry, float phi_deg, + bool large_arc, bool sweep, + float *cx_out, float *cy_out, + float *theta1_out, float *dtheta_out, + float *rx_out, float *ry_out) +{ + float phi = phi_deg * (float) M_PI / 180.f; + float cos_phi = cosf (phi), sin_phi = sinf (phi); + + float mx = (x1 - x2) / 2.f; + float my = (y1 - y2) / 2.f; + float x1p = cos_phi * mx + sin_phi * my; + float y1p = -sin_phi * mx + cos_phi * my; + + rx = fabsf (rx); ry = fabsf (ry); + if (rx < 1e-10f || ry < 1e-10f) + { + *cx_out = (x1 + x2) / 2.f; + *cy_out = (y1 + y2) / 2.f; + *theta1_out = 0; + *dtheta_out = 0; + *rx_out = rx; *ry_out = ry; + return; + } + + float x1p2 = x1p * x1p, y1p2 = y1p * y1p; + float rx2 = rx * rx, ry2 = ry * ry; + float lambda = x1p2 / rx2 + y1p2 / ry2; + if (lambda > 1.f) + { + float sl = sqrtf (lambda); + rx *= sl; ry *= sl; + rx2 = rx * rx; ry2 = ry * ry; + } + + float num = rx2 * ry2 - rx2 * y1p2 - ry2 * x1p2; + float den = rx2 * y1p2 + ry2 * x1p2; + float sq = (den > 0.f) ? sqrtf (hb_max (num / den, 0.f)) : 0.f; + if (large_arc == sweep) sq = -sq; + + float cxp = sq * rx * y1p / ry; + float cyp = -sq * ry * x1p / rx; + + float cx = cos_phi * cxp - sin_phi * cyp + (x1 + x2) / 2.f; + float cy = sin_phi * cxp + cos_phi * cyp + (y1 + y2) / 2.f; + + auto angle = [] (float ux, float uy, float vx, float vy) -> float { + float dot = ux * vx + uy * vy; + float len = sqrtf ((ux * ux + uy * uy) * (vx * vx + vy * vy)); + if (!(len > 0.f) || !std::isfinite (len)) + return 0.f; + float a = acosf (hb_clamp (dot / len, -1.f, 1.f)); + if (ux * vy - uy * vx < 0.f) a = -a; + return a; + }; + + float theta1 = angle (1.f, 0.f, (x1p - cxp) / rx, (y1p - cyp) / ry); + float dtheta = angle ((x1p - cxp) / rx, (y1p - cyp) / ry, + (-x1p - cxp) / rx, (-y1p - cyp) / ry); + + if (!sweep && dtheta > 0.f) dtheta -= 2.f * (float) M_PI; + if (sweep && dtheta < 0.f) dtheta += 2.f * (float) M_PI; + + *cx_out = cx; *cy_out = cy; + *theta1_out = theta1; *dtheta_out = dtheta; + *rx_out = rx; *ry_out = ry; +} + +void +hb_raster_svg_parse_path_data (hb_svg_str_t d, hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; + hb_svg_float_parser_t fp (d); + + float cur_x = 0, cur_y = 0; + float start_x = 0, start_y = 0; + float last_cx = 0, last_cy = 0; + char last_cmd = 0; + char cmd = 0; + unsigned segments = 0; + + while (fp.p < fp.end) + { + if (unlikely (segments++ >= HB_SVG_MAX_PATH_SEGMENTS)) + break; + fp.skip_ws_comma (); + if (fp.p >= fp.end) break; + + char c = *fp.p; + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) + { + cmd = c; + fp.p++; + } + + switch (cmd) + { + case 'M': case 'm': + { + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 'm') { x += cur_x; y += cur_y; } + hb_draw_move_to (dfuncs, draw_data, &st, x, y); + cur_x = start_x = x; + cur_y = start_y = y; + cmd = (cmd == 'M') ? 'L' : 'l'; + last_cmd = 'M'; + continue; + } + case 'L': case 'l': + { + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 'l') { x += cur_x; y += cur_y; } + hb_draw_line_to (dfuncs, draw_data, &st, x, y); + cur_x = x; cur_y = y; + break; + } + case 'H': case 'h': + { + float x = fp.next_float (); + if (cmd == 'h') x += cur_x; + hb_draw_line_to (dfuncs, draw_data, &st, x, cur_y); + cur_x = x; + break; + } + case 'V': case 'v': + { + float y = fp.next_float (); + if (cmd == 'v') y += cur_y; + hb_draw_line_to (dfuncs, draw_data, &st, cur_x, y); + cur_y = y; + break; + } + case 'C': case 'c': + { + float x1 = fp.next_float (); + float y1 = fp.next_float (); + float x2 = fp.next_float (); + float y2 = fp.next_float (); + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 'c') + { x1 += cur_x; y1 += cur_y; x2 += cur_x; y2 += cur_y; x += cur_x; y += cur_y; } + hb_draw_cubic_to (dfuncs, draw_data, &st, x1, y1, x2, y2, x, y); + last_cx = x2; last_cy = y2; + cur_x = x; cur_y = y; + break; + } + case 'S': case 's': + { + float cx1, cy1; + if (last_cmd == 'C' || last_cmd == 'c' || last_cmd == 'S' || last_cmd == 's') + { cx1 = 2 * cur_x - last_cx; cy1 = 2 * cur_y - last_cy; } + else + { cx1 = cur_x; cy1 = cur_y; } + float x2 = fp.next_float (); + float y2 = fp.next_float (); + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 's') + { x2 += cur_x; y2 += cur_y; x += cur_x; y += cur_y; } + hb_draw_cubic_to (dfuncs, draw_data, &st, cx1, cy1, x2, y2, x, y); + last_cx = x2; last_cy = y2; + cur_x = x; cur_y = y; + break; + } + case 'Q': case 'q': + { + float x1 = fp.next_float (); + float y1 = fp.next_float (); + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 'q') + { x1 += cur_x; y1 += cur_y; x += cur_x; y += cur_y; } + hb_draw_quadratic_to (dfuncs, draw_data, &st, x1, y1, x, y); + last_cx = x1; last_cy = y1; + cur_x = x; cur_y = y; + break; + } + case 'T': case 't': + { + float cx1, cy1; + if (last_cmd == 'Q' || last_cmd == 'q' || last_cmd == 'T' || last_cmd == 't') + { cx1 = 2 * cur_x - last_cx; cy1 = 2 * cur_y - last_cy; } + else + { cx1 = cur_x; cy1 = cur_y; } + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 't') { x += cur_x; y += cur_y; } + hb_draw_quadratic_to (dfuncs, draw_data, &st, cx1, cy1, x, y); + last_cx = cx1; last_cy = cy1; + cur_x = x; cur_y = y; + break; + } + case 'A': case 'a': + { + float rx = fp.next_float (); + float ry = fp.next_float (); + float x_rot = fp.next_float (); + bool large_arc = fp.next_flag (); + bool sweep = fp.next_flag (); + float x = fp.next_float (); + float y = fp.next_float (); + if (cmd == 'a') { x += cur_x; y += cur_y; } + + if (fabsf (x - cur_x) < 1e-6f && fabsf (y - cur_y) < 1e-6f) + { + cur_x = x; cur_y = y; + break; + } + + float cx, cy, theta1, dtheta, adj_rx, adj_ry; + svg_arc_endpoint_to_center (cur_x, cur_y, x, y, + rx, ry, x_rot, + large_arc, sweep, + &cx, &cy, &theta1, &dtheta, + &adj_rx, &adj_ry); + + float phi = x_rot * (float) M_PI / 180.f; + svg_arc_to_cubics (dfuncs, draw_data, &st, + cx, cy, adj_rx, adj_ry, phi, theta1, dtheta); + cur_x = x; cur_y = y; + break; + } + case 'Z': case 'z': + hb_draw_close_path (dfuncs, draw_data, &st); + cur_x = start_x; + cur_y = start_y; + break; + + default: + fp.p++; + continue; + } + + last_cmd = cmd; + } +} + +static void +svg_rect_to_path (float x, float y, float w, float h, float rx, float ry, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; + if (rx < 0.f || ry < 0.f) + return; + + if (rx <= 0 && ry <= 0) + { + hb_draw_move_to (dfuncs, draw_data, &st, x, y); + hb_draw_line_to (dfuncs, draw_data, &st, x + w, y); + hb_draw_line_to (dfuncs, draw_data, &st, x + w, y + h); + hb_draw_line_to (dfuncs, draw_data, &st, x, y + h); + hb_draw_close_path (dfuncs, draw_data, &st); + return; + } + + if (rx <= 0) rx = ry; + if (ry <= 0) ry = rx; + rx = hb_min (rx, w / 2); + ry = hb_min (ry, h / 2); + + float kx = rx * 0.5522847498f; + float ky = ry * 0.5522847498f; + + hb_draw_move_to (dfuncs, draw_data, &st, x + rx, y); + hb_draw_line_to (dfuncs, draw_data, &st, x + w - rx, y); + hb_draw_cubic_to (dfuncs, draw_data, &st, + x + w - rx + kx, y, + x + w, y + ry - ky, + x + w, y + ry); + hb_draw_line_to (dfuncs, draw_data, &st, x + w, y + h - ry); + hb_draw_cubic_to (dfuncs, draw_data, &st, + x + w, y + h - ry + ky, + x + w - rx + kx, y + h, + x + w - rx, y + h); + hb_draw_line_to (dfuncs, draw_data, &st, x + rx, y + h); + hb_draw_cubic_to (dfuncs, draw_data, &st, + x + rx - kx, y + h, + x, y + h - ry + ky, + x, y + h - ry); + hb_draw_line_to (dfuncs, draw_data, &st, x, y + ry); + hb_draw_cubic_to (dfuncs, draw_data, &st, + x, y + ry - ky, + x + rx - kx, y, + x + rx, y); + hb_draw_close_path (dfuncs, draw_data, &st); +} + +static void +svg_circle_to_path (float cx, float cy, float r, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; + float k = r * 0.5522847498f; + + hb_draw_move_to (dfuncs, draw_data, &st, cx + r, cy); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx + r, cy + k, + cx + k, cy + r, + cx, cy + r); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx - k, cy + r, + cx - r, cy + k, + cx - r, cy); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx - r, cy - k, + cx - k, cy - r, + cx, cy - r); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx + k, cy - r, + cx + r, cy - k, + cx + r, cy); + hb_draw_close_path (dfuncs, draw_data, &st); +} + +static void +svg_ellipse_to_path (float cx, float cy, float rx, float ry, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; + float kx = rx * 0.5522847498f; + float ky = ry * 0.5522847498f; + + hb_draw_move_to (dfuncs, draw_data, &st, cx + rx, cy); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx + rx, cy + ky, + cx + kx, cy + ry, + cx, cy + ry); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx - kx, cy + ry, + cx - rx, cy + ky, + cx - rx, cy); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx - rx, cy - ky, + cx - kx, cy - ry, + cx, cy - ry); + hb_draw_cubic_to (dfuncs, draw_data, &st, + cx + kx, cy - ry, + cx + rx, cy - ky, + cx + rx, cy); + hb_draw_close_path (dfuncs, draw_data, &st); +} + +static void +svg_line_to_path (float x1, float y1, float x2, float y2, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; + hb_draw_move_to (dfuncs, draw_data, &st, x1, y1); + hb_draw_line_to (dfuncs, draw_data, &st, x2, y2); +} + +static void +svg_polygon_to_path (hb_svg_str_t points, bool close, + hb_draw_funcs_t *dfuncs, void *draw_data) +{ + hb_draw_state_t st = HB_DRAW_STATE_DEFAULT; + hb_svg_float_parser_t fp (points); + bool first = true; + while (fp.has_more ()) + { + float x = fp.next_float (); + float y = fp.next_float (); + if (first) + { + hb_draw_move_to (dfuncs, draw_data, &st, x, y); + first = false; + } + else + hb_draw_line_to (dfuncs, draw_data, &st, x, y); + } + if (close && !first) + hb_draw_close_path (dfuncs, draw_data, &st); +} + +void +hb_raster_svg_shape_path_emit (hb_draw_funcs_t *dfuncs, void *draw_data, void *user_data) +{ + hb_svg_shape_emit_data_t *shape = (hb_svg_shape_emit_data_t *) user_data; + switch (shape->type) + { + case hb_svg_shape_emit_data_t::SHAPE_PATH: + hb_raster_svg_parse_path_data (shape->str_data, dfuncs, draw_data); + break; + case hb_svg_shape_emit_data_t::SHAPE_RECT: + svg_rect_to_path (shape->params[0], shape->params[1], + shape->params[2], shape->params[3], + shape->params[4], shape->params[5], + dfuncs, draw_data); + break; + case hb_svg_shape_emit_data_t::SHAPE_CIRCLE: + svg_circle_to_path (shape->params[0], shape->params[1], shape->params[2], + dfuncs, draw_data); + break; + case hb_svg_shape_emit_data_t::SHAPE_ELLIPSE: + svg_ellipse_to_path (shape->params[0], shape->params[1], + shape->params[2], shape->params[3], + dfuncs, draw_data); + break; + case hb_svg_shape_emit_data_t::SHAPE_LINE: + svg_line_to_path (shape->params[0], shape->params[1], + shape->params[2], shape->params[3], + dfuncs, draw_data); + break; + case hb_svg_shape_emit_data_t::SHAPE_POLYLINE: + svg_polygon_to_path (shape->str_data, false, dfuncs, draw_data); + break; + case hb_svg_shape_emit_data_t::SHAPE_POLYGON: + svg_polygon_to_path (shape->str_data, true, dfuncs, draw_data); + break; + } +} + +bool +hb_raster_svg_parse_shape_tag (hb_svg_xml_parser_t &parser, + hb_svg_shape_emit_data_t *shape) +{ + hb_svg_attr_view_t attrs (parser); + hb_svg_style_props_t style_props; + svg_parse_style_props (attrs.get ("style"), &style_props); + hb_svg_str_t tag = parser.tag_name; + if (tag.eq ("path")) + { + hb_svg_str_t d = svg_pick_attr_or_style (parser, style_props.d, "d"); + if (!d.len) return false; + shape->type = hb_svg_shape_emit_data_t::SHAPE_PATH; + shape->str_data = d; + return true; + } + if (tag.eq ("rect")) + { + float w = svg_parse_float (svg_pick_attr_or_style (parser, style_props.width, "width")); + float h = svg_parse_float (svg_pick_attr_or_style (parser, style_props.height, "height")); + if (w <= 0 || h <= 0) return false; + float rx = svg_parse_float (svg_pick_attr_or_style (parser, style_props.rx, "rx")); + float ry = svg_parse_float (svg_pick_attr_or_style (parser, style_props.ry, "ry")); + if (rx < 0.f || ry < 0.f) return false; + shape->type = hb_svg_shape_emit_data_t::SHAPE_RECT; + shape->params[0] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.x, "x")); + shape->params[1] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.y, "y")); + shape->params[2] = w; + shape->params[3] = h; + shape->params[4] = rx; + shape->params[5] = ry; + return true; + } + if (tag.eq ("circle")) + { + float r = svg_parse_float (svg_pick_attr_or_style (parser, style_props.r, "r")); + if (r <= 0) return false; + shape->type = hb_svg_shape_emit_data_t::SHAPE_CIRCLE; + shape->params[0] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.cx, "cx")); + shape->params[1] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.cy, "cy")); + shape->params[2] = r; + return true; + } + if (tag.eq ("ellipse")) + { + float rx = svg_parse_float (svg_pick_attr_or_style (parser, style_props.rx, "rx")); + float ry = svg_parse_float (svg_pick_attr_or_style (parser, style_props.ry, "ry")); + if (rx <= 0 || ry <= 0) return false; + shape->type = hb_svg_shape_emit_data_t::SHAPE_ELLIPSE; + shape->params[0] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.cx, "cx")); + shape->params[1] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.cy, "cy")); + shape->params[2] = rx; + shape->params[3] = ry; + return true; + } + if (tag.eq ("line")) + { + shape->type = hb_svg_shape_emit_data_t::SHAPE_LINE; + shape->params[0] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.x1, "x1")); + shape->params[1] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.y1, "y1")); + shape->params[2] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.x2, "x2")); + shape->params[3] = svg_parse_float (svg_pick_attr_or_style (parser, style_props.y2, "y2")); + return true; + } + if (tag.eq ("polyline")) + { + hb_svg_str_t points = svg_pick_attr_or_style (parser, style_props.points, "points"); + if (!points.len) return false; + shape->type = hb_svg_shape_emit_data_t::SHAPE_POLYLINE; + shape->str_data = points; + return true; + } + if (tag.eq ("polygon")) + { + hb_svg_str_t points = svg_pick_attr_or_style (parser, style_props.points, "points"); + if (!points.len) return false; + shape->type = hb_svg_shape_emit_data_t::SHAPE_POLYGON; + shape->str_data = points; + return true; + } + return false; +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-parse.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg-parse.hh new file mode 100644 index 000000000..21c782c18 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-parse.hh @@ -0,0 +1,368 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_PARSE_HH +#define HB_RASTER_SVG_PARSE_HH + +#include "hb.hh" + +#include "hb-raster-svg-base.hh" +#include "hb-draw.h" + +#include +#include + +enum hb_svg_token_type_t +{ + SVG_TOKEN_OPEN_TAG, + SVG_TOKEN_CLOSE_TAG, + SVG_TOKEN_SELF_CLOSE_TAG, + SVG_TOKEN_TEXT, + SVG_TOKEN_EOF +}; + +struct hb_svg_attr_t +{ + hb_svg_str_t name; + hb_svg_str_t value; +}; + +struct hb_svg_xml_parser_t +{ + enum { SVG_MAX_ATTRS_PER_TAG = 256 }; + + const char *p; + const char *end; + const char *tag_start = nullptr; + + hb_svg_str_t tag_name; + hb_vector_t attrs; + bool self_closing; + + hb_svg_xml_parser_t (const char *data, unsigned len) + : p (data), end (data + len), self_closing (false) {} + + void skip_ws () + { + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) + p++; + } + + hb_svg_str_t read_name () + { + const char *start = p; + while (p < end && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' && + *p != '>' && *p != '/' && *p != '=') + p++; + return {start, (unsigned) (p - start)}; + } + + hb_svg_str_t read_attr_value () + { + if (p >= end) return {}; + char quote = *p; + if (quote != '"' && quote != '\'') return {}; + p++; + const char *start = p; + while (p < end && *p != quote) + p++; + hb_svg_str_t val = {start, (unsigned) (p - start)}; + if (p < end) p++; /* skip closing quote */ + return val; + } + + void parse_attrs () + { + attrs.clear (); + while (p < end) + { + skip_ws (); + if (p >= end || *p == '>' || *p == '/') break; + hb_svg_str_t name = read_name (); + if (!name.len) { p++; continue; } + skip_ws (); + if (p < end && *p == '=') + { + p++; + skip_ws (); + hb_svg_str_t val = read_attr_value (); + if (attrs.length < SVG_MAX_ATTRS_PER_TAG) + { + hb_svg_attr_t attr = {name, val}; + attrs.push (attr); + } + } + else + { + if (attrs.length < SVG_MAX_ATTRS_PER_TAG) + { + hb_svg_attr_t attr = {name, {}}; + attrs.push (attr); + } + } + } + } + + hb_svg_token_type_t next () + { + while (p < end) + { + if (*p != '<') + { + while (p < end && *p != '<') p++; + continue; + } + + tag_start = p; + p++; /* skip '<' */ + if (p >= end) return SVG_TOKEN_EOF; + + if (*p == '!') + { + if (p + 2 < end && p[1] == '-' && p[2] == '-') + { + p += 3; + while (p + 2 < end && !(p[0] == '-' && p[1] == '-' && p[2] == '>')) + p++; + if (p + 2 < end) p += 3; + } + else + { + while (p < end && *p != '>') p++; + if (p < end) p++; + } + continue; + } + if (*p == '?') + { + while (p + 1 < end && !(p[0] == '?' && p[1] == '>')) + p++; + if (p + 1 < end) p += 2; + continue; + } + + if (*p == '/') + { + p++; + tag_name = read_name (); + while (p < end && *p != '>') p++; + if (p < end) p++; + attrs.clear (); + self_closing = false; + return SVG_TOKEN_CLOSE_TAG; + } + + tag_name = read_name (); + parse_attrs (); + + self_closing = false; + skip_ws (); + if (p < end && *p == '/') + { + self_closing = true; + p++; + } + if (p < end && *p == '>') + p++; + + return self_closing ? SVG_TOKEN_SELF_CLOSE_TAG : SVG_TOKEN_OPEN_TAG; + } + return SVG_TOKEN_EOF; + } + + hb_svg_str_t find_attr (const char *name) const + { + for (unsigned i = 0; i < attrs.length; i++) + if (attrs[i].name.eq (name)) + return attrs[i].value; + return {}; + } +}; + +static inline void +svg_skip_subtree (hb_svg_xml_parser_t &parser) +{ + int depth = 1; + while (depth > 0) + { + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_EOF) break; + if (tok == SVG_TOKEN_CLOSE_TAG) depth--; + else if (tok == SVG_TOKEN_OPEN_TAG) depth++; + } +} + +static inline hb_svg_str_t +svg_pick_attr_or_style (const hb_svg_xml_parser_t &parser, + hb_svg_str_t style_value, + const char *attr_name) +{ + return style_value.is_null () ? parser.find_attr (attr_name) : style_value; +} + +struct hb_svg_attr_view_t +{ + const hb_svg_xml_parser_t &parser; + enum { CACHE_SIZE = 16 }; + struct entry_t + { + const char *name = nullptr; + hb_svg_str_t value; + }; + entry_t cache[CACHE_SIZE]; + unsigned cache_len = 0; + + hb_svg_attr_view_t (const hb_svg_xml_parser_t &p) : parser (p) {} + + hb_svg_str_t get (const char *name) + { + for (unsigned i = 0; i < cache_len; i++) + if (strcmp (cache[i].name, name) == 0) + return cache[i].value; + + hb_svg_str_t value = parser.find_attr (name); + if (cache_len < CACHE_SIZE) + { + cache[cache_len].name = name; + cache[cache_len].value = value; + cache_len++; + } + return value; + } +}; + +struct hb_svg_transform_t +{ + float xx = 1, yx = 0, xy = 0, yy = 1, dx = 0, dy = 0; + + void multiply (const hb_svg_transform_t &other) + { + float nxx = xx * other.xx + xy * other.yx; + float nyx = yx * other.xx + yy * other.yx; + float nxy = xx * other.xy + xy * other.yy; + float nyy = yx * other.xy + yy * other.yy; + float ndx = xx * other.dx + xy * other.dy + dx; + float ndy = yx * other.dx + yy * other.dy + dy; + xx = nxx; yx = nyx; xy = nxy; yy = nyy; dx = ndx; dy = ndy; + } +}; + +struct hb_svg_float_parser_t +{ + const char *p; + const char *end; + + hb_svg_float_parser_t (hb_svg_str_t s) : p (s.data), end (s.data + s.len) {} + + void skip_ws_comma () + { + while (p < end && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || *p == ',')) + p++; + } + + bool has_more () const { return p < end; } + + float next_float () + { + skip_ws_comma (); + if (p >= end) return 0.f; + const char *start = p; + char buf[64]; + unsigned n = 0; + bool has_digit = false; + if (p < end && (*p == '-' || *p == '+')) + buf[n++] = *p++; + while (p < end && n < sizeof (buf) - 1 && *p >= '0' && *p <= '9') + { + buf[n++] = *p++; + has_digit = true; + } + if (p < end && n < sizeof (buf) - 1 && *p == '.') + { + buf[n++] = *p++; + while (p < end && n < sizeof (buf) - 1 && *p >= '0' && *p <= '9') + { + buf[n++] = *p++; + has_digit = true; + } + } + if (p < end && n < sizeof (buf) - 1 && (*p == 'e' || *p == 'E')) + { + buf[n++] = *p++; + if (p < end && n < sizeof (buf) - 1 && (*p == '+' || *p == '-')) + buf[n++] = *p++; + bool has_exp_digit = false; + while (p < end && n < sizeof (buf) - 1 && *p >= '0' && *p <= '9') + { + buf[n++] = *p++; + has_exp_digit = true; + } + if (!has_exp_digit) + { + p = start; + has_digit = false; + } + } + if (!has_digit) + { + if (p < end) p++; + return 0.f; + } + buf[n] = '\0'; + float v = strtof (buf, nullptr); + return std::isfinite (v) ? v : 0.f; + } + + bool next_flag () + { + skip_ws_comma (); + if (p >= end) return false; + bool v = *p != '0'; + p++; + return v; + } +}; + +static inline float +svg_parse_float (hb_svg_str_t s) +{ + return s.to_float (); +} + +struct hb_svg_shape_emit_data_t +{ + enum { SHAPE_PATH, SHAPE_RECT, SHAPE_CIRCLE, SHAPE_ELLIPSE, + SHAPE_LINE, SHAPE_POLYLINE, SHAPE_POLYGON } type; + hb_svg_str_t str_data; + float params[6]; +}; + +HB_INTERNAL bool hb_raster_svg_parse_transform (hb_svg_str_t s, hb_svg_transform_t *out); +HB_INTERNAL void hb_raster_svg_parse_path_data (hb_svg_str_t d, hb_draw_funcs_t *dfuncs, void *draw_data); +HB_INTERNAL void hb_raster_svg_shape_path_emit (hb_draw_funcs_t *dfuncs, void *draw_data, void *user_data); +HB_INTERNAL bool hb_raster_svg_parse_shape_tag (hb_svg_xml_parser_t &parser, hb_svg_shape_emit_data_t *shape); + +#endif /* HB_RASTER_SVG_PARSE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-render.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-render.cc new file mode 100644 index 000000000..d07ce040c --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-render.cc @@ -0,0 +1,548 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-face.hh" +#include "hb-raster-svg.hh" +#include "hb-raster-svg-base.hh" +#include "hb-raster-svg-parse.hh" +#include "hb-raster-svg-context.hh" +#include "hb-raster-svg-defs-scan.hh" +#include "hb-raster-svg-gradient.hh" +#include "hb-raster-svg-clip.hh" +#include "hb-raster-svg-bbox.hh" +#include "hb-raster-svg-fill.hh" +#include "hb-raster-svg-use.hh" +#include "OT/Color/svg/svg.hh" + +#include +#include + +#ifndef HB_NO_RASTER_SVG + +#define SVG_MAX_DEPTH 32 + +/* + * 11. Element renderer — recursive SVG rendering + */ + +static void svg_render_element (hb_svg_render_context_t *ctx, + hb_svg_xml_parser_t &parser, + const struct hb_svg_cascade_t &inherited); + +/* Gradient def parsing lives in hb-raster-svg-gradient.* */ + +/* Clip-path defs and push helpers live in hb-raster-svg-clip.* */ + +/* Render a single shape element */ +static void +svg_render_shape (hb_svg_render_context_t *ctx, + hb_svg_shape_emit_data_t &shape, + const hb_svg_cascade_t &state, + hb_svg_str_t transform_str) +{ + bool has_transform = transform_str.len > 0; + bool has_opacity = state.opacity < 1.f; + bool has_clip_path = false; + + if (has_opacity) + ctx->push_group (); + + if (has_transform) + { + hb_svg_transform_t t; + hb_raster_svg_parse_transform (transform_str, &t); + ctx->push_transform (t.xx, t.yx, t.xy, t.yy, t.dx, t.dy); + } + + hb_extents_t<> bbox; + bool has_bbox = hb_raster_svg_compute_shape_bbox (shape, &bbox); + has_clip_path = hb_raster_svg_push_clip_path_ref (ctx->paint, &ctx->defs, state.clip_path, + has_bbox ? &bbox : nullptr); + + /* Clip with shape path, then fill */ + hb_raster_paint_push_clip_path (ctx->paint, hb_raster_svg_shape_path_emit, &shape); + + /* Default fill is black */ + if (state.fill.is_null ()) + { + hb_color_t black = HB_COLOR (0, 0, 0, 255); + if (state.fill_opacity < 1.f) + black = HB_COLOR (0, 0, 0, (uint8_t) (255 * state.fill_opacity + 0.5f)); + ctx->paint_color (black); + } + else + { + hb_svg_fill_context_t fill_ctx = {ctx->paint, ctx->pfuncs, ctx->font, ctx->palette, &ctx->defs}; + hb_raster_svg_emit_fill (&fill_ctx, state.fill, state.fill_opacity, has_bbox ? &bbox : nullptr, state.color); + } + + ctx->pop_clip (); + if (has_clip_path) + ctx->pop_clip (); + + if (has_transform) + ctx->pop_transform (); + + if (has_opacity) + ctx->pop_group (HB_PAINT_COMPOSITE_MODE_SRC_OVER); +} + +static void +svg_render_container_element (hb_svg_render_context_t *ctx, + hb_svg_xml_parser_t &parser, + hb_svg_str_t tag, + bool self_closing, + const hb_svg_cascade_t &state, + hb_svg_str_t transform_str, + hb_svg_str_t clip_path_str) +{ + bool has_transform = transform_str.len > 0; + bool has_opacity = state.opacity < 1.f; + bool has_clip = false; + bool has_viewbox = false; + bool has_viewbox_transform = false; + bool has_svg_translate = false; + float svg_x = 0.f, svg_y = 0.f; + float viewport_w = 0.f, viewport_h = 0.f; + hb_svg_transform_t viewbox_t; + float vb_x = 0, vb_y = 0, vb_w = 0, vb_h = 0; + + if (tag.eq ("svg") || tag.eq ("symbol")) + { + hb_svg_style_props_t geom_style_props; + svg_parse_style_props (parser.find_attr ("style"), &geom_style_props); + + if (tag.eq ("svg")) + { + svg_x = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.x, "x")); + svg_y = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.y, "y")); + has_svg_translate = (svg_x != 0.f || svg_y != 0.f); + } + + hb_svg_str_t viewbox_str = parser.find_attr ("viewBox"); + if (hb_raster_svg_parse_viewbox (viewbox_str, &vb_x, &vb_y, &vb_w, &vb_h)) + { + has_viewbox = true; + + if (tag.eq ("svg")) + { + viewport_w = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.width, "width")); + viewport_h = hb_raster_svg_parse_non_percent_length (svg_pick_attr_or_style (parser, geom_style_props.height, "height")); + if (!(viewport_w > 0.f && viewport_h > 0.f)) + { + if (ctx->depth == 1) + { + unsigned upem = hb_font_get_face (ctx->font)->get_upem (); + viewport_w = (float) upem; + viewport_h = (float) upem; + } + else + { + viewport_w = vb_w; + viewport_h = vb_h; + } + } + has_viewbox_transform = + hb_raster_svg_compute_viewbox_transform (viewport_w, viewport_h, + vb_x, vb_y, vb_w, vb_h, + parser.find_attr ("preserveAspectRatio"), + &viewbox_t); + } + } + } + + if (ctx->suppress_viewbox_once) + { + has_viewbox = false; + has_viewbox_transform = false; + ctx->suppress_viewbox_once = false; + } + + if (has_opacity) + ctx->push_group (); + + if (has_transform) + { + hb_svg_transform_t t; + hb_raster_svg_parse_transform (transform_str, &t); + ctx->push_transform (t.xx, t.yx, t.xy, t.yy, t.dx, t.dy); + } + + if (has_svg_translate) + ctx->push_transform (1, 0, 0, 1, svg_x, svg_y); + + if (has_viewbox_transform) + ctx->push_transform (viewbox_t.xx, viewbox_t.yx, viewbox_t.xy, viewbox_t.yy, + viewbox_t.dx, viewbox_t.dy); + else if (has_viewbox && vb_w > 0 && vb_h > 0) + ctx->push_transform (1, 0, 0, 1, -vb_x, -vb_y); + + has_clip = hb_raster_svg_push_clip_path_ref (ctx->paint, &ctx->defs, clip_path_str, nullptr); + + if (!self_closing) + { + int depth = 1; + while (depth > 0) + { + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_EOF) break; + + if (tok == SVG_TOKEN_CLOSE_TAG) + { + depth--; + continue; + } + + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + { + hb_svg_str_t child_tag = parser.tag_name; + if (parser.tag_name.eq ("defs")) + { + if (tok != SVG_TOKEN_SELF_CLOSE_TAG) + { + hb_svg_defs_scan_context_t scan_ctx = { + &ctx->defs, ctx->pfuncs, ctx->paint, + ctx->foreground, hb_font_get_face (ctx->font), + ctx->palette, + ctx->doc_start, ctx->doc_len, + ctx->svg_accel, ctx->doc_cache + }; + hb_raster_svg_process_defs_element (&scan_ctx, parser); + } + continue; + } + svg_render_element (ctx, parser, state); + if (tok == SVG_TOKEN_OPEN_TAG && + !hb_raster_svg_tag_is_container_or_use (child_tag)) + { + /* Skip children of non-container elements we don't handle. */ + int skip_depth = 1; + while (skip_depth > 0) + { + hb_svg_token_type_t st = parser.next (); + if (st == SVG_TOKEN_EOF) break; + if (st == SVG_TOKEN_CLOSE_TAG) skip_depth--; + else if (st == SVG_TOKEN_OPEN_TAG) skip_depth++; + } + } + } + } + } + + if (has_viewbox_transform || (has_viewbox && vb_w > 0 && vb_h > 0)) + ctx->pop_transform (); + + if (has_svg_translate) + ctx->pop_transform (); + + if (has_clip) + ctx->pop_clip (); + + if (has_transform) + ctx->pop_transform (); + + if (has_opacity) + ctx->pop_group (HB_PAINT_COMPOSITE_MODE_SRC_OVER); +} + +static bool +svg_render_primitive_shape_element (hb_svg_render_context_t *ctx, + hb_svg_xml_parser_t &parser, + const hb_svg_cascade_t &state, + hb_svg_str_t transform_str) +{ + hb_svg_str_t tag = parser.tag_name; + if (!(tag.eq ("path") || tag.eq ("rect") || tag.eq ("circle") || + tag.eq ("ellipse") || tag.eq ("line") || tag.eq ("polyline") || + tag.eq ("polygon"))) + return false; + + hb_svg_shape_emit_data_t shape; + if (hb_raster_svg_parse_shape_tag (parser, &shape)) + svg_render_shape (ctx, shape, state, transform_str); + return true; +} + +static void +svg_render_use_callback (void *render_user, + hb_svg_xml_parser_t &parser, + const void *state, + bool viewport_mapped) +{ + hb_svg_render_context_t *ctx = (hb_svg_render_context_t *) render_user; + bool old_suppress = ctx->suppress_viewbox_once; + bool old_allow_symbol = ctx->allow_symbol_render_once; + if (viewport_mapped) + ctx->suppress_viewbox_once = true; + if (parser.tag_name.eq ("symbol")) + ctx->allow_symbol_render_once = true; + svg_render_element (ctx, parser, *(const hb_svg_cascade_t *) state); + ctx->suppress_viewbox_once = old_suppress; + ctx->allow_symbol_render_once = old_allow_symbol; +} + +/* Render one element (may be a container or shape) */ +static void +svg_render_element (hb_svg_render_context_t *ctx, + hb_svg_xml_parser_t &parser, + const hb_svg_cascade_t &inherited) +{ + if (ctx->depth >= SVG_MAX_DEPTH) return; + + const HB_UNUSED unsigned transform_depth = ctx->paint->transform_stack.length; + const HB_UNUSED unsigned clip_depth = ctx->paint->clip_stack.length; + const HB_UNUSED unsigned surface_depth = ctx->paint->surface_stack.length; + + ctx->depth++; + + hb_svg_str_t tag = parser.tag_name; + bool self_closing = parser.self_closing; + + /* Extract common attributes */ + hb_svg_str_t style = parser.find_attr ("style"); + hb_svg_style_props_t style_props; + svg_parse_style_props (style, &style_props); + hb_svg_str_t fill_attr = svg_pick_attr_or_style (parser, style_props.fill, "fill"); + hb_svg_str_t fill_opacity_str = svg_pick_attr_or_style (parser, style_props.fill_opacity, "fill-opacity"); + hb_svg_str_t opacity_str = svg_pick_attr_or_style (parser, style_props.opacity, "opacity"); + hb_svg_str_t transform_str = svg_pick_attr_or_style (parser, style_props.transform, "transform"); + hb_svg_str_t clip_path_attr = svg_pick_attr_or_style (parser, style_props.clip_path, "clip-path"); + hb_svg_str_t display_str = svg_pick_attr_or_style (parser, style_props.display, "display"); + hb_svg_str_t color_str = svg_pick_attr_or_style (parser, style_props.color, "color"); + hb_svg_str_t visibility_str = svg_pick_attr_or_style (parser, style_props.visibility, "visibility"); + + hb_svg_cascade_t state = inherited; + state.fill = (fill_attr.is_null () || svg_str_is_inherit (fill_attr)) ? inherited.fill : fill_attr; + state.fill_opacity = (fill_opacity_str.len && !svg_str_is_inherit (fill_opacity_str)) + ? svg_parse_float_clamped01 (fill_opacity_str) + : inherited.fill_opacity; + state.opacity = (opacity_str.len && !svg_str_is_inherit (opacity_str) && !svg_str_is_none (opacity_str)) + ? svg_parse_float_clamped01 (opacity_str) + : (svg_str_is_inherit (opacity_str) ? inherited.opacity : 1.f); + state.clip_path = (clip_path_attr.is_null () || svg_str_is_inherit (clip_path_attr)) + ? inherited.clip_path + : clip_path_attr; + if (svg_str_is_inherit (transform_str) || svg_str_is_none (transform_str)) + transform_str = {}; + state.color = inherited.color; + bool is_none = false; + if (color_str.len && !color_str.trim ().eq_ascii_ci ("inherit")) + state.color = hb_raster_svg_parse_color (color_str, ctx->pfuncs, ctx->paint, + inherited.color, hb_font_get_face (ctx->font), + ctx->palette, &is_none); + state.visibility = inherited.visibility; + hb_svg_str_t visibility_trim = visibility_str.trim (); + if (visibility_trim.len && !visibility_trim.eq_ascii_ci ("inherit")) + state.visibility = !(visibility_trim.eq_ascii_ci ("hidden") || + visibility_trim.eq_ascii_ci ("collapse")); + + if (display_str.trim ().eq_ascii_ci ("none")) + { + if (!self_closing) + svg_skip_subtree (parser); + ctx->depth--; + assert (ctx->paint->transform_stack.length == transform_depth); + assert (ctx->paint->clip_stack.length == clip_depth); + assert (ctx->paint->surface_stack.length == surface_depth); + return; + } + if (!state.visibility) + { + if (!self_closing) + svg_skip_subtree (parser); + ctx->depth--; + assert (ctx->paint->transform_stack.length == transform_depth); + assert (ctx->paint->clip_stack.length == clip_depth); + assert (ctx->paint->surface_stack.length == surface_depth); + return; + } + + if (tag.eq ("symbol") && !ctx->allow_symbol_render_once) + { + if (!self_closing) + svg_skip_subtree (parser); + ctx->depth--; + assert (ctx->paint->transform_stack.length == transform_depth); + assert (ctx->paint->clip_stack.length == clip_depth); + assert (ctx->paint->surface_stack.length == surface_depth); + return; + } + if (tag.eq ("symbol")) + ctx->allow_symbol_render_once = false; + + if (hb_raster_svg_tag_is_container (tag)) + svg_render_container_element (ctx, parser, tag, self_closing, + state, transform_str, state.clip_path); + else if (svg_render_primitive_shape_element (ctx, parser, state, transform_str)) + ; + else if (tag.eq ("use")) + { + hb_svg_use_context_t use_ctx = {ctx->paint, ctx->pfuncs, + ctx->doc_start, ctx->doc_len, + ctx->svg_accel, ctx->doc_cache, + &ctx->use_decycler}; + hb_raster_svg_render_use_element (&use_ctx, parser, &state, transform_str, + svg_render_use_callback, ctx); + } + + ctx->depth--; + + assert (ctx->paint->transform_stack.length == transform_depth); + assert (ctx->paint->clip_stack.length == clip_depth); + assert (ctx->paint->surface_stack.length == surface_depth); +} + + +/* + * 12. Entry point + */ + +hb_bool_t +hb_raster_svg_render (hb_raster_paint_t *paint, + hb_blob_t *blob, + hb_codepoint_t glyph, + hb_font_t *font, + unsigned palette, + hb_color_t foreground) +{ + bool ret = false; + hb_blob_t *render_blob = nullptr; + hb_face_t *face HB_UNUSED = hb_font_get_face (font); + const OT::SVG::svg_doc_cache_t *doc_cache = nullptr; +#ifndef HB_NO_SVG + unsigned doc_index = 0; + hb_codepoint_t start_glyph = HB_CODEPOINT_INVALID; + hb_codepoint_t end_glyph = HB_CODEPOINT_INVALID; +#endif + hb_paint_funcs_t *pfuncs = hb_raster_paint_get_funcs (); + hb_svg_render_context_t ctx; + hb_svg_cascade_t initial_state; + hb_svg_defs_scan_context_t scan_ctx; + bool found_glyph = false; +#ifndef HB_NO_SVG + unsigned glyph_start = 0, glyph_end = 0; +#endif + + unsigned data_len = 0; + const char *data = nullptr; + render_blob = OT::hb_ot_svg_reference_normalized_blob (blob, &data, &data_len); + if (!render_blob || !data_len) + goto done; + +#ifndef HB_NO_SVG + if (face && + hb_ot_color_glyph_get_svg_document_index (face, glyph, &doc_index) && + hb_ot_color_get_svg_document_glyph_range (face, doc_index, &start_glyph, &end_glyph)) + doc_cache = face->table.SVG->get_or_create_doc_cache (render_blob, data, data_len, + doc_index, start_glyph, end_glyph); + + if (doc_cache) + data = face->table.SVG->doc_cache_get_svg (doc_cache, &data_len); +#endif + + ctx.paint = paint; + ctx.pfuncs = pfuncs; + ctx.font = font; + ctx.palette = palette; + ctx.foreground = foreground; + ctx.doc_start = data; + ctx.doc_len = data_len; +#ifndef HB_NO_SVG + ctx.svg_accel = face ? face->table.SVG.get () : nullptr; +#endif + ctx.doc_cache = doc_cache; + + initial_state.color = foreground; + + scan_ctx = { + &ctx.defs, ctx.pfuncs, ctx.paint, + ctx.foreground, hb_font_get_face (ctx.font), + ctx.palette, + ctx.doc_start, ctx.doc_len, + ctx.svg_accel, ctx.doc_cache + }; + hb_raster_svg_collect_defs (&scan_ctx, data, data_len); + +#ifndef HB_NO_SVG + if (doc_cache && face->table.SVG->doc_cache_get_glyph_span (doc_cache, glyph, &glyph_start, &glyph_end)) + { + hb_svg_xml_parser_t parser (data + glyph_start, glyph_end - glyph_start); + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + { + hb_paint_push_font_transform (ctx.pfuncs, ctx.paint, font); + ctx.push_transform (1, 0, 0, -1, 0, 0); + svg_render_element (&ctx, parser, initial_state); + ctx.pop_transform (); + hb_paint_pop_transform (ctx.pfuncs, ctx.paint); + found_glyph = true; + } + } +#endif + if (!found_glyph) + { + /* Fallback for malformed/uncached docs: linear scan by glyph id. */ + char glyph_id_str[32]; + int glyph_id_len = snprintf (glyph_id_str, sizeof (glyph_id_str), "glyph%u", glyph); + if (glyph_id_len <= 0 || (unsigned) glyph_id_len >= sizeof (glyph_id_str)) + return false; + hb_svg_xml_parser_t parser (data, data_len); + while (true) + { + hb_svg_token_type_t tok = parser.next (); + if (tok == SVG_TOKEN_EOF) break; + + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + { + hb_svg_str_t id = parser.find_attr ("id"); + if (id.len) + { + if (id.len == (unsigned) glyph_id_len && + 0 == hb_memcmp (id.data, glyph_id_str, (unsigned) glyph_id_len)) + { + hb_paint_push_font_transform (ctx.pfuncs, ctx.paint, font); + ctx.push_transform (1, 0, 0, -1, 0, 0); + svg_render_element (&ctx, parser, initial_state); + ctx.pop_transform (); + hb_paint_pop_transform (ctx.pfuncs, ctx.paint); + found_glyph = true; + break; + } + } + } + } + } + + ret = found_glyph; + +done: + hb_blob_destroy (render_blob); + return ret; +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg-use.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-use.cc new file mode 100644 index 000000000..b64961230 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-use.cc @@ -0,0 +1,104 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_NO_RASTER_SVG + +#include "hb.hh" + +#include "hb-raster-svg-use.hh" + +#include "hb-raster-svg-base.hh" + +void +hb_raster_svg_render_use_element (const hb_svg_use_context_t *ctx, + hb_svg_xml_parser_t &parser, + const void *state, + hb_svg_str_t transform_str, + hb_svg_use_render_cb_t render_cb, + void *render_user) +{ + hb_svg_str_t href = hb_raster_svg_find_href_attr (parser); + + hb_svg_str_t ref_id; + if (!hb_raster_svg_parse_local_id_ref (href, &ref_id, nullptr)) + return; + + float use_x = 0.f, use_y = 0.f, use_w = 0.f, use_h = 0.f; + hb_raster_svg_parse_use_geometry (parser, &use_x, &use_y, &use_w, &use_h); + + bool has_translate = (use_x != 0.f || use_y != 0.f); + bool has_use_transform = transform_str.len > 0; + + if (has_use_transform) + { + hb_svg_transform_t t; + hb_raster_svg_parse_transform (transform_str, &t); + hb_paint_push_transform (ctx->pfuncs, ctx->paint, t.xx, t.yx, t.xy, t.yy, t.dx, t.dy); + } + + if (has_translate) + hb_paint_push_transform (ctx->pfuncs, ctx->paint, 1, 0, 0, 1, use_x, use_y); + + const char *found = nullptr; + hb_raster_svg_find_element_by_id (ctx->doc_start, ctx->doc_len, ctx->svg_accel, ctx->doc_cache, + ref_id, &found); + + if (found) + { + bool can_render = true; + hb_decycler_node_t node (*ctx->use_decycler); + if (unlikely (!node.visit ((uintptr_t) found))) + can_render = false; + + if (can_render) + { + unsigned remaining = ctx->doc_start + ctx->doc_len - found; + hb_svg_xml_parser_t ref_parser (found, remaining); + hb_svg_token_type_t tok = ref_parser.next (); + if (tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) + { + bool has_viewport_scale = false; + hb_svg_transform_t t; + if (hb_raster_svg_compute_use_target_viewbox_transform (ref_parser, use_w, use_h, &t)) + { + hb_paint_push_transform (ctx->pfuncs, ctx->paint, t.xx, t.yx, t.xy, t.yy, t.dx, t.dy); + has_viewport_scale = true; + } + render_cb (render_user, ref_parser, state, has_viewport_scale); + if (has_viewport_scale) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); + } + } + } + + if (has_translate) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); + + if (has_use_transform) + hb_paint_pop_transform (ctx->pfuncs, ctx->paint); +} + +#endif /* !HB_NO_RASTER_SVG */ diff --git a/thirdparty/harfbuzz/upstream/test-gpos-size-params.cc b/thirdparty/harfbuzz/upstream/hb-raster-svg-use.hh similarity index 56% rename from thirdparty/harfbuzz/upstream/test-gpos-size-params.cc rename to thirdparty/harfbuzz/upstream/hb-raster-svg-use.hh index b96381ddc..aa81f4a01 100644 --- a/thirdparty/harfbuzz/upstream/test-gpos-size-params.cc +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg-use.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2010,2011 Google, Inc. + * Copyright © 2026 Behdad Esfahbod * * This is part of HarfBuzz, a text shaping library. * @@ -21,42 +21,28 @@ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * Google Author(s): Behdad Esfahbod + * Author(s): Behdad Esfahbod */ -#include "hb.hh" - -#include "hb.h" -#include "hb-ot.h" - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif +#ifndef HB_RASTER_SVG_USE_HH +#define HB_RASTER_SVG_USE_HH -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file\n", argv[0]); - exit (1); - } - - /* Create the face */ - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_blob_destroy (blob); - blob = nullptr; +#include "hb.hh" - bool ret = true; +#include "hb-raster-svg-context.hh" +#include "hb-raster-svg-parse.hh" -#ifndef HB_NO_LAYOUT_FEATURE_PARAMS - unsigned int p[5]; - ret = hb_ot_layout_get_size_params (face, p, p+1, (p+2), p+3, p+4); - printf ("%g %u %u %g %g\n", p[0]/10., p[1], p[2], p[3]/10., p[4]/10.); -#endif +typedef void (*hb_svg_use_render_cb_t) (void *render_user, + hb_svg_xml_parser_t &parser, + const void *state, + bool viewport_mapped); - hb_face_destroy (face); +HB_INTERNAL void +hb_raster_svg_render_use_element (const hb_svg_use_context_t *ctx, + hb_svg_xml_parser_t &parser, + const void *state, + hb_svg_str_t transform_str, + hb_svg_use_render_cb_t render_cb, + void *render_user); - return !ret; -} +#endif /* HB_RASTER_SVG_USE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-svg.hh b/thirdparty/harfbuzz/upstream/hb-raster-svg.hh new file mode 100644 index 000000000..3b723f7c6 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-svg.hh @@ -0,0 +1,68 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_SVG_HH +#define HB_RASTER_SVG_HH + +#include "hb.hh" + +struct hb_raster_paint_t; + +/* Callback type: emits SVG path draw commands to the given draw funcs */ +typedef void (*hb_raster_svg_path_func_t) (hb_draw_funcs_t *dfuncs, + void *draw_data, + void *user_data); + +/* Push clip from arbitrary path (reuses push_clip_glyph logic) */ +HB_INTERNAL void +hb_raster_paint_push_clip_path (hb_raster_paint_t *c, + hb_raster_svg_path_func_t func, + void *user_data); + +/* Render SVG document for a specific glyph */ +#ifndef HB_NO_RASTER_SVG +HB_INTERNAL hb_bool_t +hb_raster_svg_render (hb_raster_paint_t *paint, + hb_blob_t *blob, + hb_codepoint_t glyph, + hb_font_t *font, + unsigned palette, + hb_color_t foreground); +#else +static inline hb_bool_t +hb_raster_svg_render (hb_raster_paint_t *paint HB_UNUSED, + hb_blob_t *blob HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + hb_font_t *font HB_UNUSED, + unsigned palette HB_UNUSED, + hb_color_t foreground HB_UNUSED) +{ + return false; +} +#endif + + +#endif /* HB_RASTER_SVG_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster-utils.hh b/thirdparty/harfbuzz/upstream/hb-raster-utils.hh new file mode 100644 index 000000000..852aee844 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster-utils.hh @@ -0,0 +1,81 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_HH +#define HB_RASTER_HH + +#include "hb.hh" + +/* Shared pixel helpers (used by paint and image compositing). */ + +static HB_ALWAYS_INLINE uint8_t +hb_raster_div255 (unsigned a) +{ + if (true) + { + // An approximation. Slightly faster. + // https://github.com/linebender/vello/blob/ab58009c8289e83689cd0effc4e34d1c6e8b51f5/sparse_strips/vello_cpu/src/util.rs#L10-L63 + return (a + 255) >> 8; + } + + return (uint8_t) ((a + 128 + ((a + 128) >> 8)) >> 8); +} + +static HB_ALWAYS_INLINE uint32_t +hb_raster_pack_pixel (uint8_t b, uint8_t g, uint8_t r, uint8_t a) +{ + return (uint32_t) b | ((uint32_t) g << 8) | ((uint32_t) r << 16) | ((uint32_t) a << 24); +} + +/* SRC_OVER: premultiplied src over premultiplied dst. */ +static HB_ALWAYS_INLINE uint32_t +hb_raster_src_over (uint32_t src, uint32_t dst) +{ + uint8_t sa = (uint8_t) (src >> 24); + if (sa == 255) return src; + if (sa == 0) return dst; + unsigned inv_sa = 255 - sa; + uint8_t rb = hb_raster_div255 ((dst & 0xFF) * inv_sa) + (uint8_t) (src & 0xFF); + uint8_t rg = hb_raster_div255 (((dst >> 8) & 0xFF) * inv_sa) + (uint8_t) ((src >> 8) & 0xFF); + uint8_t rr = hb_raster_div255 (((dst >> 16) & 0xFF) * inv_sa) + (uint8_t) ((src >> 16) & 0xFF); + uint8_t ra = hb_raster_div255 (((dst >> 24) & 0xFF) * inv_sa) + sa; + return (uint32_t) rb | ((uint32_t) rg << 8) | ((uint32_t) rr << 16) | ((uint32_t) ra << 24); +} + +/* Scale a premultiplied pixel by an alpha [0,255]. */ +static HB_ALWAYS_INLINE uint32_t +hb_raster_alpha_mul (uint32_t px, unsigned a) +{ + if (a == 255) return px; + if (a == 0) return 0; + uint8_t rb = hb_raster_div255 ((px & 0xFF) * a); + uint8_t rg = hb_raster_div255 (((px >> 8) & 0xFF) * a); + uint8_t rr = hb_raster_div255 (((px >> 16) & 0xFF) * a); + uint8_t ra = hb_raster_div255 (((px >> 24) & 0xFF) * a); + return (uint32_t) rb | ((uint32_t) rg << 8) | ((uint32_t) rr << 16) | ((uint32_t) ra << 24); +} + +#endif /* HB_RASTER_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-raster.cc b/thirdparty/harfbuzz/upstream/hb-raster.cc new file mode 100644 index 000000000..97ba6e664 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster.cc @@ -0,0 +1,68 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-raster.h" + +/** + * SECTION:hb-raster + * @title: hb-raster + * @short_description: Glyph rasterization + * @include: hb-raster.h + * + * Functions for rasterizing glyph outlines into pixel buffers. + * + * #hb_raster_draw_t rasterizes outline geometry and always outputs + * @HB_RASTER_FORMAT_A8. Typical flow: + * + * |[ + * hb_raster_draw_t *draw = hb_raster_draw_create_or_fail (); + * hb_raster_draw_set_scale_factor (draw, 64.f, 64.f); + * hb_raster_draw_set_transform (draw, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f); + * hb_raster_draw_set_glyph_extents (draw, &glyph_extents); + * hb_raster_draw_glyph (draw, font, gid, pen_x, pen_y); + * hb_raster_image_t *mask = hb_raster_draw_render (draw); + * ]| + * + * #hb_raster_paint_t renders color paint graphs and always outputs + * @HB_RASTER_FORMAT_BGRA32. Typical flow: + * + * |[ + * hb_raster_paint_t *paint = hb_raster_paint_create_or_fail (); + * hb_raster_paint_set_scale_factor (paint, 64.f, 64.f); + * hb_raster_paint_set_transform (paint, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f); + * hb_raster_paint_set_foreground (paint, foreground); + * hb_glyph_extents_t glyph_extents; + * hb_font_get_glyph_extents (font, gid, &glyph_extents); + * hb_raster_paint_set_glyph_extents (paint, &glyph_extents); + * hb_raster_paint_glyph (paint, font, gid, pen_x, pen_y, 0, foreground); + * hb_raster_image_t *img = hb_raster_paint_render (paint); + * ]| + * + * In both modes, set extents explicitly (or via glyph extents) before + * rendering to avoid implicit allocations and to get deterministic bounds. + **/ diff --git a/thirdparty/harfbuzz/upstream/hb-raster.h b/thirdparty/harfbuzz/upstream/hb-raster.h new file mode 100644 index 000000000..296e171b0 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-raster.h @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_RASTER_H +#define HB_RASTER_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/* Shared types */ + +/** + * hb_raster_format_t: + * @HB_RASTER_FORMAT_A8: 8-bit alpha-only coverage + * @HB_RASTER_FORMAT_BGRA32: 32-bit BGRA color + * + * Pixel format for raster images. + * + * Since: 13.0.0 + */ +typedef enum { + HB_RASTER_FORMAT_A8 = 0, + HB_RASTER_FORMAT_BGRA32 = 1, +} hb_raster_format_t; + +/** + * hb_raster_extents_t: + * @x_origin: X coordinate of the left edge of the image in glyph space + * @y_origin: Y coordinate of the bottom edge of the image in glyph space + * @width: Width in pixels + * @height: Height in pixels + * @stride: Bytes per row; 0 means auto-calculate on input, filled on output + * + * Pixel-buffer extents for raster operations. + * + * Since: 13.0.0 + */ +typedef struct hb_raster_extents_t { + int x_origin, y_origin; + unsigned int width, height; + unsigned int stride; +} hb_raster_extents_t; + + +/* hb_raster_image_t */ + +/** + * hb_raster_image_t: + * + * An opaque raster image object holding a pixel buffer produced by + * hb_raster_draw_render(). Use hb_raster_image_get_buffer() and + * hb_raster_image_get_extents() to access the pixels. + * + * Since: 13.0.0 + **/ +typedef struct hb_raster_image_t hb_raster_image_t; + +HB_EXTERN hb_raster_image_t * +hb_raster_image_create_or_fail (void); + +HB_EXTERN hb_raster_image_t * +hb_raster_image_reference (hb_raster_image_t *image); + +HB_EXTERN void +hb_raster_image_destroy (hb_raster_image_t *image); + +HB_EXTERN hb_bool_t +hb_raster_image_set_user_data (hb_raster_image_t *image, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace); + +HB_EXTERN void * +hb_raster_image_get_user_data (hb_raster_image_t *image, + hb_user_data_key_t *key); + +HB_EXTERN hb_bool_t +hb_raster_image_configure (hb_raster_image_t *image, + hb_raster_format_t format, + const hb_raster_extents_t *extents); + +HB_EXTERN void +hb_raster_image_clear (hb_raster_image_t *image); + +HB_EXTERN const uint8_t * +hb_raster_image_get_buffer (hb_raster_image_t *image); + +HB_EXTERN void +hb_raster_image_get_extents (hb_raster_image_t *image, + hb_raster_extents_t *extents); + +HB_EXTERN hb_raster_format_t +hb_raster_image_get_format (hb_raster_image_t *image); + +HB_EXTERN hb_bool_t +hb_raster_image_deserialize_from_png_or_fail (hb_raster_image_t *image, + hb_blob_t *png); + +HB_EXTERN hb_blob_t * +hb_raster_image_serialize_to_png_or_fail (hb_raster_image_t *image); + + +/* hb_raster_draw_t */ + +/** + * hb_raster_draw_t: + * + * An opaque outline rasterizer object. Accumulates glyph outlines + * via #hb_draw_funcs_t callbacks obtained from hb_raster_draw_get_funcs(), + * then produces an #hb_raster_image_t with hb_raster_draw_render(). + * + * Since: 13.0.0 + **/ +typedef struct hb_raster_draw_t hb_raster_draw_t; + +HB_EXTERN hb_raster_draw_t * +hb_raster_draw_create_or_fail (void); + +HB_EXTERN hb_raster_draw_t * +hb_raster_draw_reference (hb_raster_draw_t *draw); + +HB_EXTERN void +hb_raster_draw_destroy (hb_raster_draw_t *draw); + +HB_EXTERN hb_bool_t +hb_raster_draw_set_user_data (hb_raster_draw_t *draw, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace); + +HB_EXTERN void * +hb_raster_draw_get_user_data (hb_raster_draw_t *draw, + hb_user_data_key_t *key); + +HB_EXTERN void +hb_raster_draw_set_transform (hb_raster_draw_t *draw, + float xx, float yx, + float xy, float yy, + float dx, float dy); + +HB_EXTERN void +hb_raster_draw_set_scale_factor (hb_raster_draw_t *draw, + float x_scale_factor, + float y_scale_factor); + +HB_EXTERN void +hb_raster_draw_get_scale_factor (hb_raster_draw_t *draw, + float *x_scale_factor, + float *y_scale_factor); + +HB_EXTERN void +hb_raster_draw_get_transform (hb_raster_draw_t *draw, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy); + +HB_EXTERN void +hb_raster_draw_set_extents (hb_raster_draw_t *draw, + const hb_raster_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_raster_draw_get_extents (hb_raster_draw_t *draw, + hb_raster_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_raster_draw_set_glyph_extents (hb_raster_draw_t *draw, + const hb_glyph_extents_t *glyph_extents); + +HB_EXTERN hb_draw_funcs_t * +hb_raster_draw_get_funcs (void); + +HB_EXTERN void +hb_raster_draw_glyph (hb_raster_draw_t *draw, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y); + +HB_EXTERN hb_raster_image_t * +hb_raster_draw_render (hb_raster_draw_t *draw); + +HB_EXTERN void +hb_raster_draw_reset (hb_raster_draw_t *draw); + +HB_EXTERN void +hb_raster_draw_recycle_image (hb_raster_draw_t *draw, + hb_raster_image_t *image); + + + +/* hb_raster_paint_t */ + +/** + * hb_raster_paint_t: + * + * An opaque color-glyph paint context. Implements #hb_paint_funcs_t + * callbacks that render COLRv0/v1 color glyphs into a BGRA32 + * #hb_raster_image_t. + * + * Since: 13.0.0 + **/ +typedef struct hb_raster_paint_t hb_raster_paint_t; + +HB_EXTERN hb_raster_paint_t * +hb_raster_paint_create_or_fail (void); + +HB_EXTERN hb_raster_paint_t * +hb_raster_paint_reference (hb_raster_paint_t *paint); + +HB_EXTERN void +hb_raster_paint_destroy (hb_raster_paint_t *paint); + +HB_EXTERN hb_bool_t +hb_raster_paint_set_user_data (hb_raster_paint_t *paint, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace); + +HB_EXTERN void * +hb_raster_paint_get_user_data (hb_raster_paint_t *paint, + hb_user_data_key_t *key); + +HB_EXTERN void +hb_raster_paint_set_transform (hb_raster_paint_t *paint, + float xx, float yx, + float xy, float yy, + float dx, float dy); + +HB_EXTERN void +hb_raster_paint_get_transform (hb_raster_paint_t *paint, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy); + +HB_EXTERN void +hb_raster_paint_set_scale_factor (hb_raster_paint_t *paint, + float x_scale_factor, + float y_scale_factor); + +HB_EXTERN void +hb_raster_paint_get_scale_factor (hb_raster_paint_t *paint, + float *x_scale_factor, + float *y_scale_factor); + +HB_EXTERN void +hb_raster_paint_set_extents (hb_raster_paint_t *paint, + const hb_raster_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_raster_paint_get_extents (hb_raster_paint_t *paint, + hb_raster_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_raster_paint_set_glyph_extents (hb_raster_paint_t *paint, + const hb_glyph_extents_t *glyph_extents); + +HB_EXTERN void +hb_raster_paint_set_foreground (hb_raster_paint_t *paint, + hb_color_t foreground); + +HB_EXTERN void +hb_raster_paint_clear_custom_palette_colors (hb_raster_paint_t *paint); + +HB_EXTERN hb_bool_t +hb_raster_paint_set_custom_palette_color (hb_raster_paint_t *paint, + unsigned int color_index, + hb_color_t color); + +HB_EXTERN hb_paint_funcs_t * +hb_raster_paint_get_funcs (void); + +HB_EXTERN hb_bool_t +hb_raster_paint_glyph (hb_raster_paint_t *paint, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y, + unsigned palette, + hb_color_t foreground); + +HB_EXTERN hb_raster_image_t * +hb_raster_paint_render (hb_raster_paint_t *paint); + +HB_EXTERN void +hb_raster_paint_reset (hb_raster_paint_t *paint); + +HB_EXTERN void +hb_raster_paint_recycle_image (hb_raster_paint_t *paint, + hb_raster_image_t *image); + + +HB_END_DECLS + +#endif /* HB_RASTER_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-repacker.hh b/thirdparty/harfbuzz/upstream/hb-repacker.hh index cb4fdeead..7d118b521 100644 --- a/thirdparty/harfbuzz/upstream/hb-repacker.hh +++ b/thirdparty/harfbuzz/upstream/hb-repacker.hh @@ -217,11 +217,17 @@ bool _try_isolating_subgraphs (const hb_vector_t& over unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u); if (roots_to_isolate.get_population () > maximum_to_move) { // Only move at most half of the roots in a space at a time. - unsigned extra = roots_to_isolate.get_population () - maximum_to_move; - while (extra--) { - uint32_t root = HB_SET_VALUE_INVALID; - roots_to_isolate.previous (&root); - roots_to_isolate.del (root); + // + // Note: this was ported from non-stable ids to stable ids. So to retain the same behaviour + // with regards to which roots are removed from the set we need to remove them in the topological + // order, not the object id order. + int extra = roots_to_isolate.get_population () - maximum_to_move; + for (unsigned id : sorted_graph.ordering_) { + if (!extra) break; + if (roots_to_isolate.has(id)) { + roots_to_isolate.del(id); + extra--; + } } } @@ -266,7 +272,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf result = sorted_graph.duplicate(&parents, r.child); } - if (result == (unsigned) -1) return result; + if (result == (unsigned) -1) return false; if (parents.get_population() > 1) { // If the duplicated node has more than one parent pre-emptively raise it's priority to the maximum. @@ -283,7 +289,7 @@ bool _resolve_shared_overflow(const hb_vector_t& overf sorted_graph.vertices_[result].give_max_priority(); } - return result; + return true; } static inline @@ -302,8 +308,11 @@ bool _process_overflows (const hb_vector_t& overflows, { // The child object is shared, we may be able to eliminate the overflow // by duplicating it. - if (!_resolve_shared_overflow(overflows, i, sorted_graph)) continue; - return true; + if (_resolve_shared_overflow(overflows, i, sorted_graph)) + return true; + + // Sometimes we can't duplicate a node which looks shared because it's not actually shared + // (eg. all links from the same parent) in this case continue on to other resolution options. } if (child.is_leaf () && !priority_bumped_parents.has (r.parent)) diff --git a/thirdparty/harfbuzz/upstream/hb-sanitize.hh b/thirdparty/harfbuzz/upstream/hb-sanitize.hh index 408649c76..7c03d0090 100644 --- a/thirdparty/harfbuzz/upstream/hb-sanitize.hh +++ b/thirdparty/harfbuzz/upstream/hb-sanitize.hh @@ -64,16 +64,13 @@ * * - Cast blob content to T*, call sanitize() method of it, * - If sanitize succeeded, return blob. - * - Otherwise, if blob is not writable, try making it writable, - * or copy if cannot be made writable in-place, - * - Call sanitize() again. Return blob if sanitize succeeded. * - Return empty blob otherwise. * * * === The sanitize() contract === * - * The sanitize() method of each object type shall return true if it's safe to - * call other methods of the object, and %false otherwise. + * The sanitize() method of each object type shall return `true` if it's safe to + * call other methods of the object, and `false` otherwise. * * Note that what sanitize() checks for might align with what the specification * describes as valid table data, but does not have to be. In particular, we @@ -98,6 +95,12 @@ * structure is so complicated that by checking all offsets at sanitize() time, * we make the code much simpler in other methods, as offsets and referenced * objects do not need to be validated at each use site. + * + * Note: + * Sanitize was named so because it used to try to recover from errors by + * modifying the data to make it valid. This is no longer the case, as it + * could make HarfBuzz hallucinate new rules if there was aliasing in the + * data. However, the name stuck. See: https://behdad.github.io/harfbust/ */ /* This limits sanitizing time on really broken fonts. */ @@ -120,12 +123,12 @@ struct hb_sanitize_context_t : hb_dispatch_context_t { - hb_sanitize_context_t () : - start (nullptr), end (nullptr), + hb_sanitize_context_t (const char *start_ = nullptr, const char *end_ = nullptr) : + start (start_), end (end_), length (0), max_ops (0), max_subtables (0), recursion_depth (0), - writable (false), edit_count (0), + writable (false), blob (nullptr), num_glyphs (65536), num_glyphs_set (false), @@ -212,14 +215,22 @@ struct hb_sanitize_context_t : void reset_object () { - this->start = this->blob->data; - this->end = this->start + this->blob->length; + if (this->blob) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; + } this->length = this->end - this->start; assert (this->start <= this->end); /* Must not overflow. */ } - void start_processing () + void start_processing (const char *start_ = nullptr, const char *end_ = nullptr) { + if (start_) + { + this->start = start_; + this->end = end_; + } reset_object (); unsigned m; if (unlikely (hb_unsigned_mul_overflows (this->end - this->start, HB_SANITIZE_MAX_OPS_FACTOR, &m))) @@ -228,7 +239,6 @@ struct hb_sanitize_context_t : this->max_ops = hb_clamp (m, (unsigned) HB_SANITIZE_MAX_OPS_MIN, (unsigned) HB_SANITIZE_MAX_OPS_MAX); - this->edit_count = 0; this->debug_depth = 0; this->recursion_depth = 0; @@ -241,8 +251,8 @@ struct hb_sanitize_context_t : void end_processing () { DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, - "end [%p..%p] %u edit requests", - this->start, this->end, this->edit_count); + "end [%p..%p]", + this->start, this->end); hb_blob_destroy (this->blob); this->blob = nullptr; @@ -250,9 +260,6 @@ struct hb_sanitize_context_t : this->length = 0; } - unsigned get_edit_count () { return edit_count; } - - bool check_ops(unsigned count) { /* Avoid underflow */ @@ -396,35 +403,6 @@ struct hb_sanitize_context_t : return likely (this->check_point ((const char *) obj + obj->min_size)); } - bool may_edit (const void *base, unsigned int len) - { - if (this->edit_count >= HB_SANITIZE_MAX_EDITS) - return false; - - const char *p = (const char *) base; - this->edit_count++; - - DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, - "may_edit(%u) [%p..%p] (%u bytes) in [%p..%p] -> %s", - this->edit_count, - p, p + len, len, - this->start, this->end, - this->writable ? "GRANTED" : "DENIED"); - - return this->writable; - } - - template - bool try_set (const Type *obj, const ValueType &v) - { - if (this->may_edit (obj, hb_static_size (Type))) - { - * const_cast (obj) = v; - return true; - } - return false; - } - template hb_blob_t *sanitize_blob (hb_blob_t *blob) { @@ -432,7 +410,6 @@ struct hb_sanitize_context_t : init (blob); - retry: DEBUG_MSG_FUNC (SANITIZE, start, "start"); start_processing (); @@ -446,36 +423,6 @@ struct hb_sanitize_context_t : Type *t = reinterpret_cast (const_cast (start)); sane = t->sanitize (this); - if (sane) - { - if (edit_count) - { - DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %u edits; going for second round", edit_count); - - /* sanitize again to ensure no toe-stepping */ - edit_count = 0; - sane = t->sanitize (this); - if (edit_count) { - DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count); - sane = false; - } - } - } - else - { - if (edit_count && !writable) { - start = hb_blob_get_data_writable (blob, nullptr); - end = start + blob->length; - - if (start) - { - writable = true; - /* ok, we made it writable by relocating. try again */ - DEBUG_MSG_FUNC (SANITIZE, start, "retry"); - goto retry; - } - } - } end_processing (); @@ -506,7 +453,6 @@ struct hb_sanitize_context_t : private: int recursion_depth; bool writable; - unsigned int edit_count; hb_blob_t *blob; unsigned int num_glyphs; bool num_glyphs_set; diff --git a/thirdparty/harfbuzz/upstream/hb-script-list.h b/thirdparty/harfbuzz/upstream/hb-script-list.h new file mode 100644 index 000000000..d500d5ae6 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-script-list.h @@ -0,0 +1,496 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) +#error "Include instead." +#endif + +#ifndef HB_SCRIPT_LIST_H +#define HB_SCRIPT_LIST_H + +/* This file belongs to the middle of hb-common.h. + * The reason it has been surgically extracted is because + * FreeType imports types and enums from hb-common.h, + * and since this enum is large and growing, we want to + * make it easy to just copy the file over to FreeType. + * https://github.com/harfbuzz/harfbuzz/issues/5271 + */ + +/* Dummy lines to make our checks happy. */ +#if 0 +#include "hb-common.h" +HB_BEGIN_DECLS +HB_END_DECLS +#endif + + +/** + * hb_script_t: + * @HB_SCRIPT_COMMON: `Zyyy` + * @HB_SCRIPT_INHERITED: `Zinh` + * @HB_SCRIPT_UNKNOWN: `Zzzz` + * @HB_SCRIPT_ARABIC: `Arab` + * @HB_SCRIPT_ARMENIAN: `Armn` + * @HB_SCRIPT_BENGALI: `Beng` + * @HB_SCRIPT_CYRILLIC: `Cyrl` + * @HB_SCRIPT_DEVANAGARI: `Deva` + * @HB_SCRIPT_GEORGIAN: `Geor` + * @HB_SCRIPT_GREEK: `Grek` + * @HB_SCRIPT_GUJARATI: `Gujr` + * @HB_SCRIPT_GURMUKHI: `Guru` + * @HB_SCRIPT_HANGUL: `Hang` + * @HB_SCRIPT_HAN: `Hani` + * @HB_SCRIPT_HEBREW: `Hebr` + * @HB_SCRIPT_HIRAGANA: `Hira` + * @HB_SCRIPT_KANNADA: `Knda` + * @HB_SCRIPT_KATAKANA: `Kana` + * @HB_SCRIPT_LAO: `Laoo` + * @HB_SCRIPT_LATIN: `Latn` + * @HB_SCRIPT_MALAYALAM: `Mlym` + * @HB_SCRIPT_ORIYA: `Orya` + * @HB_SCRIPT_TAMIL: `Taml` + * @HB_SCRIPT_TELUGU: `Telu` + * @HB_SCRIPT_THAI: `Thai` + * @HB_SCRIPT_TIBETAN: `Tibt` + * @HB_SCRIPT_BOPOMOFO: `Bopo` + * @HB_SCRIPT_BRAILLE: `Brai` + * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` + * @HB_SCRIPT_CHEROKEE: `Cher` + * @HB_SCRIPT_ETHIOPIC: `Ethi` + * @HB_SCRIPT_KHMER: `Khmr` + * @HB_SCRIPT_MONGOLIAN: `Mong` + * @HB_SCRIPT_MYANMAR: `Mymr` + * @HB_SCRIPT_OGHAM: `Ogam` + * @HB_SCRIPT_RUNIC: `Runr` + * @HB_SCRIPT_SINHALA: `Sinh` + * @HB_SCRIPT_SYRIAC: `Syrc` + * @HB_SCRIPT_THAANA: `Thaa` + * @HB_SCRIPT_YI: `Yiii` + * @HB_SCRIPT_DESERET: `Dsrt` + * @HB_SCRIPT_GOTHIC: `Goth` + * @HB_SCRIPT_OLD_ITALIC: `Ital` + * @HB_SCRIPT_BUHID: `Buhd` + * @HB_SCRIPT_HANUNOO: `Hano` + * @HB_SCRIPT_TAGALOG: `Tglg` + * @HB_SCRIPT_TAGBANWA: `Tagb` + * @HB_SCRIPT_CYPRIOT: `Cprt` + * @HB_SCRIPT_LIMBU: `Limb` + * @HB_SCRIPT_LINEAR_B: `Linb` + * @HB_SCRIPT_OSMANYA: `Osma` + * @HB_SCRIPT_SHAVIAN: `Shaw` + * @HB_SCRIPT_TAI_LE: `Tale` + * @HB_SCRIPT_UGARITIC: `Ugar` + * @HB_SCRIPT_BUGINESE: `Bugi` + * @HB_SCRIPT_COPTIC: `Copt` + * @HB_SCRIPT_GLAGOLITIC: `Glag` + * @HB_SCRIPT_KHAROSHTHI: `Khar` + * @HB_SCRIPT_NEW_TAI_LUE: `Talu` + * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` + * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` + * @HB_SCRIPT_TIFINAGH: `Tfng` + * @HB_SCRIPT_BALINESE: `Bali` + * @HB_SCRIPT_CUNEIFORM: `Xsux` + * @HB_SCRIPT_NKO: `Nkoo` + * @HB_SCRIPT_PHAGS_PA: `Phag` + * @HB_SCRIPT_PHOENICIAN: `Phnx` + * @HB_SCRIPT_CARIAN: `Cari` + * @HB_SCRIPT_CHAM: `Cham` + * @HB_SCRIPT_KAYAH_LI: `Kali` + * @HB_SCRIPT_LEPCHA: `Lepc` + * @HB_SCRIPT_LYCIAN: `Lyci` + * @HB_SCRIPT_LYDIAN: `Lydi` + * @HB_SCRIPT_OL_CHIKI: `Olck` + * @HB_SCRIPT_REJANG: `Rjng` + * @HB_SCRIPT_SAURASHTRA: `Saur` + * @HB_SCRIPT_SUNDANESE: `Sund` + * @HB_SCRIPT_VAI: `Vaii` + * @HB_SCRIPT_AVESTAN: `Avst` + * @HB_SCRIPT_BAMUM: `Bamu` + * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` + * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` + * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` + * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` + * @HB_SCRIPT_JAVANESE: `Java` + * @HB_SCRIPT_KAITHI: `Kthi` + * @HB_SCRIPT_LISU: `Lisu` + * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` + * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` + * @HB_SCRIPT_OLD_TURKIC: `Orkh` + * @HB_SCRIPT_SAMARITAN: `Samr` + * @HB_SCRIPT_TAI_THAM: `Lana` + * @HB_SCRIPT_TAI_VIET: `Tavt` + * @HB_SCRIPT_BATAK: `Batk` + * @HB_SCRIPT_BRAHMI: `Brah` + * @HB_SCRIPT_MANDAIC: `Mand` + * @HB_SCRIPT_CHAKMA: `Cakm` + * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` + * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` + * @HB_SCRIPT_MIAO: `Plrd` + * @HB_SCRIPT_SHARADA: `Shrd` + * @HB_SCRIPT_SORA_SOMPENG: `Sora` + * @HB_SCRIPT_TAKRI: `Takr` + * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 + * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 + * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 + * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 + * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 + * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 + * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 + * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 + * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 + * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 + * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 + * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 + * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 + * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 + * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 + * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 + * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 + * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 + * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 + * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 + * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 + * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 + * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 + * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 + * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 + * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 + * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 + * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 + * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 + * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 + * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 + * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 + * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 + * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 + * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 + * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 + * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 + * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 + * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 + * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 + * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 + * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 + * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 + * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 + * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 + * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 + * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 + * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 + * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 + * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 + * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 + * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 + * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 + * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 + * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0 + * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0 + * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0 + * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 + * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 + * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 + * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 + * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 + * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 + * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 + * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 + * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 + * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 + * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 + * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 + * @HB_SCRIPT_BERIA_ERFE: `Berf`, Since: 11.5.0 + * @HB_SCRIPT_SIDETIC: `Sidt`, Since: 11.5.0 + * @HB_SCRIPT_TAI_YO: `Tayo`, Since: 11.5.0 + * @HB_SCRIPT_TOLONG_SIKI: `Tols`, Since: 11.5.0 + * @HB_SCRIPT_INVALID: No script set + * + * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding + * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). + * + * See also the Script (sc) property of the Unicode Character Database. + * + **/ + +/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ +typedef enum +{ + HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/ + HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/ + HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/ + + HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/ + HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/ + HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/ + HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/ + HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/ + HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/ + HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/ + HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/ + HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/ + HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/ + HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/ + HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/ + HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/ + HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/ + HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/ + HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/ + HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/ + HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/ + HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/ + HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/ + HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/ + HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/ + + HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/ + + HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/ + HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/ + HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/ + HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/ + HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/ + HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/ + HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/ + HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/ + HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/ + HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/ + HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/ + HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/ + HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/ + HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/ + + HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/ + HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/ + HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/ + + HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/ + HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/ + HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/ + HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/ + + HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/ + HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/ + HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/ + HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/ + HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/ + HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/ + HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/ + + HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/ + HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/ + HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/ + HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/ + HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/ + HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/ + HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/ + HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/ + + HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/ + HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/ + HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/ + HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/ + HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/ + + HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/ + HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/ + HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/ + HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/ + HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/ + HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/ + HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/ + HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/ + HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/ + HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/ + HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/ + + HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/ + HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/ + HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/ + HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/ + HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/ + HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/ + HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/ + HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/ + HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/ + HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/ + HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/ + HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/ + HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/ + + HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/ + HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/ + HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/ + + HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/ + HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/ + HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/ + HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/ + HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/ + HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ + HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ + + /* + * Since: 0.9.30 + */ + HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ + HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ + HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ + HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/ + HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/ + HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/ + HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/ + HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/ + HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ + HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ + HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ + HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/ + HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ + HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ + HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ + HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ + HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ + HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ + HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/ + HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ + HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/ + HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ + HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ + + HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/ + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/ + HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/ + HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/ + HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/ + HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/ + + /* + * Since 1.3.0 + */ + HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/ + HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/ + HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/ + HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/ + HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/ + HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/ + + /* + * Since 1.6.0 + */ + HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/ + HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/ + HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/ + HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/ + + /* + * Since 1.8.0 + */ + HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/ + HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/ + HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/ + HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/ + HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/ + HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/ + HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/ + + /* + * Since 2.4.0 + */ + HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/ + HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/ + HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/ + HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/ + + /* + * Since 2.6.7 + */ + HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ + HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ + HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ + HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ + + /* + * Since 3.0.0 + */ + HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/ + HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/ + HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/ + HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/ + HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/ + + /* + * Since 3.4.0 + */ + HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'), + + /* + * Since 5.2.0 + */ + HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ + HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ + + /* + * Since 10.0.0 + */ + HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ + HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ + HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ + HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ + HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ + HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ + HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + + /* + * Since 11.5.0 + */ + HB_SCRIPT_BERIA_ERFE = HB_TAG ('B','e','r','f'), /*17.0*/ + HB_SCRIPT_SIDETIC = HB_TAG ('S','i','d','t'), /*17.0*/ + HB_SCRIPT_TAI_YO = HB_TAG ('T','a','y','o'), /*17.0*/ + HB_SCRIPT_TOLONG_SIKI = HB_TAG ('T','o','l','s'), /*17.0*/ + + /* No script set. */ + HB_SCRIPT_INVALID = HB_TAG_NONE, + + /*< private >*/ + + /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t + * without risking undefined behavior. We have two, for historical reasons. + * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed + * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. + * + * See this thread for technicalities: + * + * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html + */ + _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ + _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ + +} hb_script_t; + + +#endif /* HB_SCRIPT_LIST_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-serialize.hh b/thirdparty/harfbuzz/upstream/hb-serialize.hh index e988451eb..92c795705 100644 --- a/thirdparty/harfbuzz/upstream/hb-serialize.hh +++ b/thirdparty/harfbuzz/upstream/hb-serialize.hh @@ -34,11 +34,9 @@ #include "hb.hh" #include "hb-blob.hh" #include "hb-map.hh" -#include "hb-pool.hh" +#include "hb-free-pool.hh" -#ifdef HB_EXPERIMENTAL_API -#include "hb-subset-repacker.h" -#endif +#include "hb-subset-serialize.h" /* * Serialize @@ -75,21 +73,19 @@ struct hb_serialize_context_t object_t () = default; -#ifdef HB_EXPERIMENTAL_API - object_t (const hb_object_t &o) + object_t (const hb_subset_serialize_object_t &o) { head = o.head; tail = o.tail; next = nullptr; - real_links.alloc (o.num_real_links, true); + real_links.alloc_exact (o.num_real_links); for (unsigned i = 0 ; i < o.num_real_links; i++) real_links.push (o.real_links[i]); - virtual_links.alloc (o.num_virtual_links, true); + virtual_links.alloc_exact (o.num_virtual_links); for (unsigned i = 0; i < o.num_virtual_links; i++) virtual_links.push (o.virtual_links[i]); } -#endif bool add_virtual_link (objidx_t objidx) { @@ -148,8 +144,7 @@ struct hb_serialize_context_t link_t () = default; -#ifdef HB_EXPERIMENTAL_API - link_t (const hb_link_t &o) + link_t (const hb_subset_serialize_link_t &o) { width = o.width; is_signed = 0; @@ -158,7 +153,6 @@ struct hb_serialize_context_t bias = 0; objidx = o.objidx; } -#endif HB_INTERNAL static int cmp (const void* a, const void* b) { @@ -178,7 +172,7 @@ struct hb_serialize_context_t auto all_links () const HB_AUTO_RETURN (( hb_concat (real_links, virtual_links) )); auto all_links_writer () HB_AUTO_RETURN - (( hb_concat (real_links.writer (), virtual_links.writer ()) )); + (( hb_concat (real_links.writer (), virtual_links.writer ()) )); }; struct snapshot_t @@ -400,6 +394,7 @@ struct hb_serialize_context_t { merge_virtual_links (obj, objidx); obj->fini (); + object_pool.release (obj); return objidx; } } @@ -463,9 +458,11 @@ struct hb_serialize_context_t while (packed.length > 1 && packed.tail ()->head < tail) { - packed_map.del (packed.tail ()); - assert (!packed.tail ()->next); - packed.tail ()->fini (); + object_t *obj = packed.tail (); + packed_map.del (obj); + assert (!obj->next); + obj->fini (); + object_pool.release (obj); packed.pop (); } if (packed.length > 1) @@ -727,7 +724,7 @@ struct hb_serialize_context_t hb_requires (hb_is_iterator (Iterator)), typename ...Ts> void copy_all (Iterator it, Ts&&... ds) - { for (decltype (*it) _ : it) copy (_, std::forward (ds)...); } + { for (decltype (*it) _ : it) copy (_, ds...); } template hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } @@ -797,7 +794,8 @@ struct hb_serialize_context_t template void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) { - auto &off = * ((BEInt *) (parent->head + link.position)); + // XXX We should stop assuming big-endian! + auto &off = * ((HBInt *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); } @@ -817,7 +815,7 @@ struct hb_serialize_context_t } /* Object memory pool. */ - hb_pool_t object_pool; + hb_free_pool_t object_pool; /* Stack of currently under construction objects. */ object_t *current; diff --git a/thirdparty/harfbuzz/upstream/hb-set-digest.hh b/thirdparty/harfbuzz/upstream/hb-set-digest.hh index b718b94e6..419afa881 100644 --- a/thirdparty/harfbuzz/upstream/hb-set-digest.hh +++ b/thirdparty/harfbuzz/upstream/hb-set-digest.hh @@ -31,11 +31,10 @@ #include "hb-machinery.hh" /* - * The set-digests here implement various "filters" that support - * "approximate member query". Conceptually these are like Bloom - * Filter and Quotient Filter, however, much smaller, faster, and - * designed to fit the requirements of our uses for glyph coverage - * queries. + * The set-digests implement "filters" that support "approximate + * member query". Conceptually these are like Bloom Filter and + * Quotient Filter, however, much smaller, faster, and designed + * to fit the requirements of our uses for glyph coverage queries. * * Our filters are highly accurate if the lookup covers fairly local * set of glyphs, but fully flooded and ineffective if coverage is @@ -56,53 +55,68 @@ * - For each glyph, if it doesn't match the subtable digest, * skip it. * - * The main filter we use is a combination of three bits-pattern + * The filter we use is a combination of three bits-pattern * filters. A bits-pattern filter checks a number of bits (5 or 6) - * of the input number (glyph-id in this case) and checks whether + * of the input number (glyph-id in most cases) and checks whether * its pattern is amongst the patterns of any of the accepted values. - * The accepted patterns are represented as a "long" integer. The + * The accepted patterns are represented as a "long" integer. Each * check is done using four bitwise operations only. */ -template -struct hb_set_digest_bits_pattern_t +static constexpr unsigned hb_set_digest_shifts[] = {4, 0, 6}; + +struct hb_set_digest_t { + // No science in these. Intuition and testing only. + using mask_t = uint64_t; + + static constexpr unsigned n = ARRAY_LENGTH_CONST (hb_set_digest_shifts); static constexpr unsigned mask_bytes = sizeof (mask_t); static constexpr unsigned mask_bits = sizeof (mask_t) * 8; - static constexpr unsigned num_bits = 0 - + (mask_bytes >= 1 ? 3 : 0) - + (mask_bytes >= 2 ? 1 : 0) - + (mask_bytes >= 4 ? 1 : 0) - + (mask_bytes >= 8 ? 1 : 0) - + (mask_bytes >= 16? 1 : 0) - + 0; + static constexpr hb_codepoint_t mb1 = mask_bits - 1; + static constexpr mask_t one = 1; + static constexpr mask_t all = (mask_t) -1; - static_assert ((shift < sizeof (hb_codepoint_t) * 8), ""); - static_assert ((shift + num_bits <= sizeof (hb_codepoint_t) * 8), ""); - - void init () { mask = 0; } + void init () + { for (unsigned i = 0; i < n; i++) masks[i] = 0; } - static hb_set_digest_bits_pattern_t full () { hb_set_digest_bits_pattern_t d; d.mask = (mask_t) -1; return d; } + void clear () { init (); } - void union_ (const hb_set_digest_bits_pattern_t &o) { mask |= o.mask; } + static hb_set_digest_t full () + { + hb_set_digest_t d; + for (unsigned i = 0; i < n; i++) d.masks[i] = all; + return d; + } - void add (hb_codepoint_t g) { mask |= mask_for (g); } + void union_ (const hb_set_digest_t &o) + { for (unsigned i = 0; i < n; i++) masks[i] |= o.masks[i]; } bool add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (mask == (mask_t) -1) return false; - if ((b >> shift) - (a >> shift) >= mask_bits - 1) - { - mask = (mask_t) -1; - return false; - } - else + bool ret; + + ret = false; + for (unsigned i = 0; i < n; i++) + if (masks[i] != all) + ret = true; + if (!ret) return false; + + ret = false; + for (unsigned i = 0; i < n; i++) { - mask_t ma = mask_for (a); - mask_t mb = mask_for (b); - mask |= mb + (mb - ma) - (mb < ma); - return true; + mask_t shift = hb_set_digest_shifts[i]; + if ((b >> shift) - (a >> shift) >= mb1) + masks[i] = all; + else + { + mask_t ma = one << ((a >> shift) & mb1); + mask_t mb = one << ((b >> shift) & mb1); + masks[i] |= mb + (mb - ma) - (mb < ma); + ret = true; + } } + return ret; } template @@ -125,103 +139,37 @@ struct hb_set_digest_bits_pattern_t template bool add_sorted_array (const hb_sorted_array_t& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_bits_pattern_t &o) const - { return mask & o.mask; } - - bool may_have (hb_codepoint_t g) const - { return mask & mask_for (g); } - bool operator [] (hb_codepoint_t g) const { return may_have (g); } - private: - - static mask_t mask_for (hb_codepoint_t g) - { return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); } - mask_t mask = 0; -}; - -template -struct hb_set_digest_combiner_t -{ - void init () - { - head.init (); - tail.init (); - } - - static hb_set_digest_combiner_t full () { hb_set_digest_combiner_t d; d.head = head_t::full(); d.tail = tail_t::full (); return d; } - - void union_ (const hb_set_digest_combiner_t &o) - { - head.union_ (o.head); - tail.union_(o.tail); - } void add (hb_codepoint_t g) { - head.add (g); - tail.add (g); - } - - bool add_range (hb_codepoint_t a, hb_codepoint_t b) - { - return (int) head.add_range (a, b) | (int) tail.add_range (a, b); - } - template - void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - head.add_array (array, count, stride); - tail.add_array (array, count, stride); - } - template - void add_array (const hb_array_t& arr) { add_array (&arr, arr.len ()); } - template - bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - return head.add_sorted_array (array, count, stride) && - tail.add_sorted_array (array, count, stride); + for (unsigned i = 0; i < n; i++) + masks[i] |= one << ((g >> hb_set_digest_shifts[i]) & mb1); } - template - bool add_sorted_array (const hb_sorted_array_t& arr) { return add_sorted_array (&arr, arr.len ()); } - bool may_have (const hb_set_digest_combiner_t &o) const + HB_ALWAYS_INLINE + bool may_have (hb_codepoint_t g) const { - return head.may_have (o.head) && tail.may_have (o.tail); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & (one << ((g >> hb_set_digest_shifts[i]) & mb1)))) + return false; + return true; } - bool may_have (hb_codepoint_t g) const + bool may_intersect (const hb_set_digest_t &o) const { - return head.may_have (g) && tail.may_have (g); + for (unsigned i = 0; i < n; i++) + if (!(masks[i] & o.masks[i])) + return false; + return true; } - bool operator [] (hb_codepoint_t g) const - { return may_have (g); } - private: - head_t head; - tail_t tail; -}; - -/* - * hb_set_digest_t - * - * This is a combination of digests that performs "best". - * There is not much science to this: it's a result of intuition - * and testing. - */ -using hb_set_digest_t = - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t, - hb_set_digest_combiner_t - < - hb_set_digest_bits_pattern_t, - hb_set_digest_bits_pattern_t - > - > -; + mask_t masks[n] = {}; +}; #endif /* HB_SET_DIGEST_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-set.hh b/thirdparty/harfbuzz/upstream/hb-set.hh index f6013a414..5cd983c00 100644 --- a/thirdparty/harfbuzz/upstream/hb-set.hh +++ b/thirdparty/harfbuzz/upstream/hb-set.hh @@ -30,6 +30,7 @@ #include "hb.hh" #include "hb-bit-set-invertible.hh" +#include "hb-bit-vector.hh" // Just to include template @@ -106,6 +107,7 @@ struct hb_sparseset_t void del_range (hb_codepoint_t a, hb_codepoint_t b) { s.del_range (a, b); } bool get (hb_codepoint_t g) const { return s.get (g); } + bool may_have (hb_codepoint_t g) const { return get (g); } /* Has interface. */ bool operator [] (hb_codepoint_t k) const { return get (k); } @@ -120,6 +122,9 @@ struct hb_sparseset_t hb_sparseset_t& operator << (const hb_codepoint_pair_t& range) { add_range (range.first, range.second); return *this; } + bool may_intersect (const hb_sparseset_t &other) const + { return s.may_intersect (other.s); } + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const { return s.intersects (first, last); } diff --git a/thirdparty/harfbuzz/upstream/hb-shape-plan.cc b/thirdparty/harfbuzz/upstream/hb-shape-plan.cc index 78ebb4769..e24a8b5b8 100644 --- a/thirdparty/harfbuzz/upstream/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/upstream/hb-shape-plan.cc @@ -213,7 +213,7 @@ hb_shape_plan_create (hb_face_t *face, * @num_coords: The number of variation-space coordinates * @shaper_list: (array zero-terminated=1): List of shapers to try * - * The variable-font version of #hb_shape_plan_create. + * The variable-font version of #hb_shape_plan_create. * Constructs a shaping plan for a combination of @face, @user_features, @props, * and @shaper_list, plus the variation-space coordinates @coords. * @@ -237,7 +237,7 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); - if (unlikely (props->direction == HB_DIRECTION_INVALID)) + if (unlikely (!HB_DIRECTION_IS_VALID (props->direction))) return hb_shape_plan_get_empty (); hb_shape_plan_t *shape_plan; @@ -335,7 +335,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the given shaping plan. + * Attaches a user-data key/data pair to the given shaping plan. * * Return value: `true` if success, `false` otherwise. * @@ -356,7 +356,7 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, * @shape_plan: A shaping plan * @key: The user-data key to query * - * Fetches the user data associated with the specified key, + * Fetches the user data associated with the specified key, * attached to the specified shaping plan. * * Return value: (transfer none): A pointer to the user data @@ -509,7 +509,7 @@ hb_shape_plan_create_cached (hb_face_t *face, * @num_coords: The number of variation-space coordinates * @shaper_list: (array zero-terminated=1): List of shapers to try * - * The variable-font version of #hb_shape_plan_create_cached. + * The variable-font version of #hb_shape_plan_create_cached. * Creates a cached shaping plan suitable for reuse, for a combination * of @face, @user_features, @props, and @shaper_list, plus the * variation-space coordinates @coords. diff --git a/thirdparty/harfbuzz/upstream/hb-shape.cc b/thirdparty/harfbuzz/upstream/hb-shape.cc index 844f7b9e8..2a8086fde 100644 --- a/thirdparty/harfbuzz/upstream/hb-shape.cc +++ b/thirdparty/harfbuzz/upstream/hb-shape.cc @@ -91,8 +91,10 @@ void free_static_shaper_list () * * Retrieves the list of shapers supported by HarfBuzz. * - * Return value: (transfer none) (array zero-terminated=1): an array of - * constant strings + * Return value: (transfer none) (array zero-terminated=1): a + * `NULL`-terminated array of supported shapers constant string. + * The returned array is owned by HarfBuzz and should not be + * modified or freed. * * Since: 0.9.2 **/ @@ -147,14 +149,11 @@ hb_shape_full (hb_font_t *font, hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); - if (buffer->max_ops <= 0) - buffer->shaping_failed = true; - hb_shape_plan_destroy (shape_plan); if (text_buffer) { - if (res && buffer->successful && !buffer->shaping_failed + if (res && buffer->successful && text_buffer->successful && !buffer->verify (text_buffer, font, @@ -197,6 +196,7 @@ hb_shape (hb_font_t *font, #ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR static float buffer_advance (hb_buffer_t *buffer) @@ -438,7 +438,7 @@ hb_shape_justify (hb_font_t *font, return true; } - +#endif #endif diff --git a/thirdparty/harfbuzz/upstream/hb-shape.h b/thirdparty/harfbuzz/upstream/hb-shape.h index d4d4fdfd2..b09bf0587 100644 --- a/thirdparty/harfbuzz/upstream/hb-shape.h +++ b/thirdparty/harfbuzz/upstream/hb-shape.h @@ -53,6 +53,7 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list); +#ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t hb_shape_justify (hb_font_t *font, hb_buffer_t *buffer, @@ -64,6 +65,7 @@ hb_shape_justify (hb_font_t *font, float *advance, /* IN/OUT */ hb_tag_t *var_tag, /* OUT */ float *var_value /* OUT */); +#endif HB_EXTERN const char ** hb_shape_list_shapers (void); diff --git a/thirdparty/harfbuzz/upstream/hb-shaper-list.hh b/thirdparty/harfbuzz/upstream/hb-shaper-list.hh index f079caf4d..cb386f268 100644 --- a/thirdparty/harfbuzz/upstream/hb-shaper-list.hh +++ b/thirdparty/harfbuzz/upstream/hb-shaper-list.hh @@ -57,6 +57,14 @@ HB_SHAPER_IMPLEMENT (directwrite) HB_SHAPER_IMPLEMENT (coretext) #endif +#ifdef HAVE_HARFRUST +HB_SHAPER_IMPLEMENT (harfrust) +#endif + +#ifdef HAVE_KBTS +HB_SHAPER_IMPLEMENT (kbts) +#endif + #ifndef HB_NO_FALLBACK_SHAPE HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */ #endif diff --git a/thirdparty/harfbuzz/upstream/hb-static.cc b/thirdparty/harfbuzz/upstream/hb-static.cc index c9bd0a61b..06cc80b5f 100644 --- a/thirdparty/harfbuzz/upstream/hb-static.cc +++ b/thirdparty/harfbuzz/upstream/hb-static.cc @@ -41,6 +41,7 @@ #include "hb-ot-maxp-table.hh" #ifndef HB_NO_VISIBILITY + #include "hb-ot-name-language-static.hh" uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {}; @@ -112,27 +113,4 @@ hb_face_t::load_upem () const return ret; } - -#ifndef HB_NO_VAR -bool -_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, - int *lsb) -{ - return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); -} - -unsigned -_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) -{ - return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); -} -#endif - -bool -_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb) -{ - return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb); -} - - #endif diff --git a/thirdparty/harfbuzz/upstream/hb-string-array.hh b/thirdparty/harfbuzz/upstream/hb-string-array.hh index e7ac11923..3a714889c 100644 --- a/thirdparty/harfbuzz/upstream/hb-string-array.hh +++ b/thirdparty/harfbuzz/upstream/hb-string-array.hh @@ -45,25 +45,25 @@ static const union HB_STRING_ARRAY_TYPE_NAME { * but C++ does not allow that. * https://stackoverflow.com/q/28433862 */ -#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; +#define HB_STR(s) char HB_PASTE (str, __LINE__)[sizeof (s)]; #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR } st; char str[HB_VAR_ARRAY]; } HB_STRING_ARRAY_POOL_NAME = { { -#define _S(s) s, +#define HB_STR(s) s, #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR } }; static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] = { -#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), +#define HB_STR(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)), #include HB_STRING_ARRAY_LIST -#undef _S +#undef HB_STR sizeof (HB_STRING_ARRAY_TYPE_NAME) }; diff --git a/thirdparty/harfbuzz/upstream/hb-subset-cff-common.cc b/thirdparty/harfbuzz/upstream/hb-subset-cff-common.cc index 5e4ea5fe7..96e148afc 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-cff-common.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-cff-common.cc @@ -68,7 +68,6 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, /* use hb_set to determine the subset of font dicts */ hb_set_t set; hb_codepoint_t prev_fd = CFF_UNDEF_CODE; - hb_pair_t last_range {0, 0}; auto it = hb_iter (plan->new_to_old_gid_list); auto _ = *it; for (hb_codepoint_t gid = 0; gid < subset_num_glyphs; gid++) @@ -84,9 +83,8 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */ old_glyph = gid; } - if (old_glyph >= last_range.second) - last_range = src.get_fd_range (old_glyph); - unsigned fd = last_range.first; + auto fd_range = src.get_fd_range (old_glyph); + unsigned fd = fd_range.first; if (fd != prev_fd) { @@ -96,7 +94,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, fdselect_ranges.push (code_pair_t { fd, gid }); if (gid == old_glyph) - gid = hb_min (_.first - 1, last_range.second - 1); + gid = hb_min (_.first - 1, fd_range.second - 1); } } diff --git a/thirdparty/harfbuzz/upstream/hb-subset-cff-common.hh b/thirdparty/harfbuzz/upstream/hb-subset-cff-common.hh index 4039f9c95..3140b9ca3 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-cff-common.hh +++ b/thirdparty/harfbuzz/upstream/hb-subset-cff-common.hh @@ -321,11 +321,31 @@ struct cff_font_dict_op_serializer_t : op_serializer_t } }; +/* CharString command for specialization */ +struct cs_command_t +{ + hb_vector_t args; + hb_vector_t mask_bytes; /* For hintmask/cntrmask payload bytes. */ + op_code_t op; + + cs_command_t () : op (OpCode_Invalid) {} + cs_command_t (op_code_t op_) : op (op_) {} +}; + +typedef hb_vector_t *cs_command_vec_t; + struct flatten_param_t { + flatten_param_t (str_buff_t &flatStr_, + bool drop_hints_, + const hb_subset_plan_t *plan_, + cs_command_vec_t commands_ = nullptr) + : flatStr (flatStr_), drop_hints (drop_hints_), plan (plan_), commands (commands_) {} + str_buff_t &flatStr; bool drop_hints; const hb_subset_plan_t *plan; + cs_command_vec_t commands; /* Optional: capture parsed commands for specialization */ }; template @@ -335,7 +355,8 @@ struct subr_flattener_t const hb_subset_plan_t *plan_) : acc (acc_), plan (plan_) {} - bool flatten (str_buff_vec_t &flat_charstrings) + bool flatten (str_buff_vec_t &flat_charstrings, + hb_vector_t> *command_capture = nullptr) { unsigned count = plan->num_output_glyphs (); if (!flat_charstrings.resize_exact (count)) @@ -361,7 +382,8 @@ struct subr_flattener_t flatten_param_t param = { flat_charstrings.arrayZ[i], (bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING), - plan + plan, + command_capture ? &(*command_capture)[i] : nullptr }; if (unlikely (!interp.interpret (param))) return false; @@ -570,7 +592,7 @@ struct cff_subset_accelerator_t parsed_cs_str_vec_t parsed_charstrings; parsed_cs_str_vec_t parsed_global_subrs; hb_vector_t parsed_local_subrs; - mutable hb_atomic_ptr_t glyph_to_sid_map; + mutable hb_atomic_t glyph_to_sid_map; private: hb_blob_t* original_blob; @@ -861,8 +883,7 @@ struct subr_subsetter_t { // Hack to point vector to static string. auto &b = buffArray.arrayZ[last]; - b.length = 1; - b.arrayZ = const_cast(endchar_str); + b.set_storage (const_cast(endchar_str), 1); } last++; // Skip over gid @@ -877,8 +898,7 @@ struct subr_subsetter_t { // Hack to point vector to static string. auto &b = buffArray.arrayZ[last]; - b.length = 1; - b.arrayZ = const_cast(endchar_str); + b.set_storage (const_cast(endchar_str), 1); } return true; @@ -1128,7 +1148,7 @@ struct subr_subsetter_t if (opstr.op == OpCode_callsubr || opstr.op == OpCode_callgsubr) size += 3; } - if (!buff.alloc (buff.length + size, true)) + if (!buff.alloc_exact (buff.length + size)) return false; for (auto &opstr : str.values) diff --git a/thirdparty/harfbuzz/upstream/hb-subset-cff1.cc b/thirdparty/harfbuzz/upstream/hb-subset-cff1.cc index e9dd5d642..d080e0a27 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-cff1.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-cff1.cc @@ -45,7 +45,7 @@ struct remap_sid_t void alloc (unsigned size) { map.alloc (size); - vector.alloc (size, true); + vector.alloc_exact (size); } bool in_error () const diff --git a/thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.cc b/thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.cc new file mode 100644 index 000000000..6a65bf5d8 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.cc @@ -0,0 +1,40 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +/* + * CFF2 to CFF1 Converter + * + * The actual implementation is in hb-subset-cff2.cc where it has access + * to the full cff2_subset_plan definition. + * + * This file just exists to keep the build system happy. + */ + +#include "hb.hh" + +#ifndef HB_NO_SUBSET_CFF + +#include "hb-subset-cff2-to-cff1.hh" + +#endif /* HB_NO_SUBSET_CFF */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.hh b/thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.hh new file mode 100644 index 000000000..6022c0061 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-cff2-to-cff1.hh @@ -0,0 +1,177 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_SUBSET_CFF2_TO_CFF1_HH +#define HB_SUBSET_CFF2_TO_CFF1_HH + +#include "hb.hh" + +#ifndef HB_NO_SUBSET_CFF + +#include "hb-ot-cff1-table.hh" +#include "hb-ot-cff2-table.hh" +#include "hb-subset-cff-common.hh" + +namespace OT { + // Forward declarations - these are defined in hb-subset-cff2.cc + struct cff2_subset_plan; +} + +namespace CFF { + +// Forward declaration +struct cff2_top_dict_values_t; + +// Default font name for converted CFF1 fonts +static constexpr const char CFF1_DEFAULT_FONT_NAME[] = "CFF1Font"; + +/* + * CFF2 to CFF1 Converter + * + * Converts an instantiated (pinned) CFF2 variable font to CFF1 format. + * This is used when instantiating a variable font to a static instance. + * + * IMPLEMENTATION STATUS: + * ✓ CFF1 structure (Header, Name INDEX, String INDEX, Top DICT INDEX) + * ✓ ROS operator (makes font CID-keyed: "Adobe-Identity-0") + * ✓ FDArray and FDSelect in Top DICT (required for CID fonts) + * ✓ FDSelect3 format (compact range-based, 8 bytes for single-FD fonts) + * ✓ CID Charset with identity mapping (format 2) + * ✓ FontBBox from head table (xMin, yMin, xMax, yMax) + * ✓ Width optimization (defaultWidthX/nominalWidthX with O(n) algorithm) + * ✓ Width encoding in CharStrings (prepended if != defaultWidthX) + * ✓ CharString specialization (h/v operators, combined when possible) + * ✓ Stack depth control (generalize→specialize with maxstack=48) + * ✓ CharStrings with endchar operators (CFF1 requires, CFF2 doesn't) + * ✓ Private DICT instantiation (blend operators evaluated) + * ✓ Desubroutinized path (CharStrings are flattened, no subroutines) + * ✓ OTS validation passes + * ✓ HarfBuzz rendering works + * + * FUTURE ENHANCEMENTS: + * - Curve operator specialization (hhcurveto, vvcurveto, etc.) + * - Peephole optimization (minor additional size savings) + * + * Key conversions: + * - Version: 2 -> 1 + * - Add Name INDEX (required in CFF1) + * - Wrap Top DICT in an INDEX (inline in CFF2, indexed in CFF1) + * - Add String INDEX ("Adobe", "Identity" for ROS operator) + * - Add ROS operator to Top DICT (makes it CID-keyed) + * - Add FDSelect to Top DICT (required in CFF1 even with single FD) + * - Add endchar to CharStrings (required in CFF1, optional in CFF2) + */ + +struct cff1_subset_plan_from_cff2_t +{ + // Inherits most data from cff2_subset_plan + const OT::cff2_subset_plan *cff2_plan; + + // CFF1-specific additions + hb_vector_t fontName; // Single font name for Name INDEX + + bool create (const OT::cff2_subset_plan &cff2_plan_) + { + cff2_plan = &cff2_plan_; + + // Create a simple font name (CFF1 requires a Name INDEX) + fontName.resize (strlen (CFF1_DEFAULT_FONT_NAME)); + if (fontName.in_error ()) return false; + memcpy (fontName.arrayZ, CFF1_DEFAULT_FONT_NAME, strlen (CFF1_DEFAULT_FONT_NAME)); + + return true; + } +}; + +/* CFF1 Top DICT operator serializer that adds ROS and removes CFF2-specific ops */ +struct cff1_from_cff2_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<> +{ + bool serialize (hb_serialize_context_t *c, + const op_str_t &opstr, + const cff_sub_table_info_t &info) const + { + TRACE_SERIALIZE (this); + + switch (opstr.op) + { + case OpCode_vstore: + // CFF2-only operator, skip it + return_trace (true); + + case OpCode_CharStrings: + return_trace (FontDict::serialize_link4_op(c, opstr.op, info.char_strings_link, whence_t::Absolute)); + + case OpCode_FDArray: + case OpCode_FDSelect: + // These are explicitly serialized in the main function to ensure they're present + // even if CFF2 doesn't have them. Skip them here to avoid duplication. + return_trace (true); + + default: + return_trace (copy_opstr (c, opstr)); + } + } + + // Serialize ROS operator to make this a CID-keyed font + bool serialize_ros (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + + // ROS = Registry-Ordering-Supplement + // We use "Adobe", "Identity", 0 for maximum compatibility + + // Allocate space and encode directly + // Registry: SID for "Adobe" (custom string at index 0 = SID 391) + // Ordering: SID for "Identity" (custom string at index 1 = SID 392) + // Supplement: 0 + // Note: CFF standard strings end at SID 390, custom strings start at 391 + + str_buff_t buff; + str_encoder_t encoder (buff); + + encoder.encode_int (391); // Registry SID ("Adobe" in our String INDEX) + encoder.encode_int (392); // Ordering SID ("Identity" in our String INDEX) + encoder.encode_int (0); // Supplement + encoder.encode_op (OpCode_ROS); + + if (encoder.in_error ()) + return_trace (false); + + auto bytes = buff.as_bytes (); + return_trace (c->embed (bytes.arrayZ, bytes.length)); + } +}; + +/* Main serialization function */ +HB_INTERNAL bool +serialize_cff2_to_cff1 (hb_serialize_context_t *c, + OT::cff2_subset_plan &plan, + const cff2_top_dict_values_t &cff2_topDict, + const OT::cff2::accelerator_subset_t &acc); + +} /* namespace CFF */ + +#endif /* HB_NO_SUBSET_CFF */ + +#endif /* HB_SUBSET_CFF2_TO_CFF1_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-cff2.cc b/thirdparty/harfbuzz/upstream/hb-subset-cff2.cc index eb5cb0c62..262eeb1ab 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-cff2.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-cff2.cc @@ -34,6 +34,7 @@ #include "hb-subset-plan.hh" #include "hb-subset-cff-common.hh" #include "hb-cff2-interp-cs.hh" +#include "hb-subset-cff2-to-cff1.hh" using namespace CFF; @@ -73,6 +74,56 @@ struct cff2_cs_opset_flatten_t : cff2_cs_opset_t &env, flatten_param_t& param) { + /* Optionally capture command for specialization (before flushing, to preserve args) */ + if (param.commands) + { + bool skip_command = false; + + switch (op) + { + case OpCode_return: + case OpCode_endchar: + skip_command = true; + break; + + case OpCode_hstem: + case OpCode_hstemhm: + case OpCode_vstem: + case OpCode_vstemhm: + case OpCode_hintmask: + case OpCode_cntrmask: + if (param.drop_hints) + skip_command = true; + break; + + default: + break; + } + + if (!skip_command) + { + cs_command_t cmd (op); + /* Capture resolved blend values */ + for (unsigned int i = 0; i < env.argStack.get_count ();) + { + const blend_arg_t &arg = env.argStack[i]; + if (arg.blending ()) + { + /* For blend args, capture only the resolved default value */ + cmd.args.push (arg); + /* Skip over the multiple blend values */ + i += arg.numValues; + } + else + { + cmd.args.push (arg); + i++; + } + } + param.commands->push (cmd); + } + } + switch (op) { case OpCode_return: @@ -167,6 +218,22 @@ struct cff2_cs_opset_flatten_t : cff2_cs_opset_t &env, flatten_param_t& param) { SUPER::flush_hintmask (op, env, param); + /* Preserve hintmask payload in captured commands for specializer re-encoding. */ + if (param.commands && !param.drop_hints && param.commands->length > 0) + { + auto &cmd = param.commands->tail (); + if (cmd.op == op) + { + cmd.mask_bytes.resize (env.hintmask_size); + if (unlikely (cmd.mask_bytes.in_error ())) + { + env.set_error (); + return; + } + for (unsigned int i = 0; i < env.hintmask_size; i++) + cmd.mask_bytes[i] = env.str_ref[i]; + } + } if (!param.drop_hints) { str_encoder_t encoder (param.flatStr); @@ -436,9 +503,15 @@ struct cff2_subset_plan drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; pinned = (bool) plan->normalized_coords; + normalized_coords = plan->normalized_coords; + head_maxp_info = plan->head_maxp_info; + hmtx_map = &plan->hmtx_map; desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE || pinned; // For instancing we need this path + /* Enable command capture for CFF2→CFF1 conversion (for specialization) */ + capture_commands = pinned; + #ifdef HB_EXPERIMENTAL_API min_charstrings_off_size = (plan->flags & HB_SUBSET_FLAGS_IFTB_REQUIREMENTS) ? 4 : 0; #else @@ -450,8 +523,21 @@ struct cff2_subset_plan /* Flatten global & local subrs */ subr_flattener_t, cff2_cs_opset_flatten_t> flattener(acc, plan); - if (!flattener.flatten (subset_charstrings)) - return false; + + /* Enable command capture if requested (for specialization) */ + if (capture_commands) + { + if (!charstring_commands.resize_exact (num_glyphs)) + return false; + + if (!flattener.flatten (subset_charstrings, &charstring_commands)) + return false; + } + else + { + if (!flattener.flatten (subset_charstrings)) + return false; + } } else { @@ -518,9 +604,483 @@ struct cff2_subset_plan bool desubroutinize = false; unsigned min_charstrings_off_size = 0; + + hb_array_t normalized_coords; // For instantiation + head_maxp_info_t head_maxp_info; // For FontBBox + const hb_hashmap_t> *hmtx_map; // For widths + + // Width optimization results (for CFF1 conversion) + unsigned default_width = 0; + unsigned nominal_width = 0; + + // Command capture for specialization (CFF2→CFF1 conversion) + bool capture_commands = false; + hb_vector_t> charstring_commands; }; } // namespace OT +/* + * CFF2 to CFF1 Converter Implementation + */ + +#include "hb-cff-width-optimizer.hh" +#include "hb-cff-specializer.hh" + +/* Serialize charstrings using CFF1 format with widths */ +static bool +_serialize_cff1_charstrings (hb_serialize_context_t *c, + OT::cff2_subset_plan &plan, + unsigned default_width, + unsigned nominal_width) +{ + c->push (); + + // CFF1 requires: + // 1. Width at the beginning (if != defaultWidthX) + // 2. endchar at the end + str_buff_vec_t cff1_charstrings; + if (unlikely (!cff1_charstrings.resize (plan.subset_charstrings.length))) + { + c->pop_discard (); + return false; + } + + for (unsigned i = 0; i < plan.subset_charstrings.length; i++) + { + // Get width for this glyph from hmtx_map + unsigned width = 0; + if (plan.hmtx_map->has (i)) + width = plan.hmtx_map->get (i).first; + + // Encode width if different from default + str_encoder_t encoder (cff1_charstrings[i]); + if (width != default_width) + { + int delta = (int) width - (int) nominal_width; + encoder.encode_int (delta); + } + + // Use specialized commands if available, otherwise use binary + if (plan.capture_commands && i < plan.charstring_commands.length && + plan.charstring_commands[i].length > 0) + { + // Specialize and encode commands + auto &commands = plan.charstring_commands[i]; + CFF::specialize_commands (commands, 48); /* maxstack=48 for CFF1 */ + if (unlikely (!CFF::encode_commands (commands, cff1_charstrings[i]))) + { + c->pop_discard (); + return false; + } + } + else + { + // Use binary CharString + const str_buff_t &cs = plan.subset_charstrings[i]; + for (unsigned j = 0; j < cs.length; j++) + cff1_charstrings[i].push (cs[j]); + } + + // Check if it already ends with endchar (0x0e) or return (0x0b) + if (cff1_charstrings[i].length == 0 || + (cff1_charstrings[i].tail () != 0x0e && cff1_charstrings[i].tail () != 0x0b)) + { + // Append endchar operator + if (unlikely (!cff1_charstrings[i].push_or_fail (0x0e))) + { + c->pop_discard (); + return false; + } + } + } + + unsigned data_size = 0; + unsigned total_size = CFF1CharStrings::total_size (cff1_charstrings, &data_size); + if (unlikely (!c->start_zerocopy (total_size))) + { + c->pop_discard (); + return false; + } + + auto *cs = c->start_embed (); + if (unlikely (!cs->serialize (c, cff1_charstrings))) + { + c->pop_discard (); + return false; + } + + plan.info.char_strings_link = c->pop_pack (false); + return true; +} + +/* Serialize CID Charset (format 2 range: gid 0-N -> cid 0-N) */ +static bool +_serialize_cff1_charset (hb_serialize_context_t *c, + unsigned int num_glyphs, + objidx_t &charset_link) +{ + // For CID fonts, create a simple identity charset + // Format 2: one range covering all glyphs (except .notdef) + c->push (); + + auto *charset = c->start_embed (); + if (unlikely (!charset)) + { + c->pop_discard (); + return false; + } + + // Create a single range for CID 1 to num_glyphs-1 + hb_vector_t ranges; + if (num_glyphs > 1) + { + code_pair_t range; + range.code = 1; // first CID + range.glyph = num_glyphs - 2; // nLeft (covers glyphs 1 to num_glyphs-1) + ranges.push (range); + } + + if (unlikely (!charset->serialize (c, 2, num_glyphs, ranges))) + { + c->pop_discard (); + return false; + } + + charset_link = c->pop_pack (); + return true; +} + +/* CFF2 to CFF1 serialization */ +namespace CFF { + +bool +serialize_cff2_to_cff1 (hb_serialize_context_t *c, + OT::cff2_subset_plan &plan, + const cff2_top_dict_values_t &cff2_topDict, + const OT::cff2::accelerator_subset_t &acc) +{ + TRACE_SERIALIZE (this); + + /* + * CFF1 Serialization Order (reverse, as HarfBuzz packs from end): + * 1. CharStrings + * 2. Private DICs & Local Subrs + * 3. FDArray + * 4. FDSelect + * 5. Charset + * 6. Global Subrs + * 7. String INDEX + * 8. Top DICT INDEX + * 9. Name INDEX + * 10. Header + */ + + // 0. Optimize width encoding (for all FDs) + { + // Collect widths from hmtx_map + hb_vector_t widths; + widths.alloc (plan.num_glyphs); + + for (unsigned gid = 0; gid < plan.num_glyphs; gid++) + { + unsigned width = 0; + if (plan.hmtx_map->has (gid)) + width = plan.hmtx_map->get (gid).first; + widths.push (width); + } + + // Optimize defaultWidthX and nominalWidthX + CFF::optimize_widths (widths, plan.default_width, plan.nominal_width); + } + + // 1. CharStrings (with widths prepended) + if (!_serialize_cff1_charstrings (c, plan, plan.default_width, plan.nominal_width)) + return_trace (false); + + // 2. Private DICs & Local Subrs (same as CFF2) + hb_vector_t private_dict_infos; + if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) + return_trace (false); + + for (int i = (int)acc.privateDicts.length; --i >= 0;) + { + if (plan.fdmap.has (i)) + { + objidx_t subrs_link = 0; + + if (plan.subset_localsubrs[i].length > 0) + { + auto *dest = c->push (); + if (likely (dest->serialize (c, plan.subset_localsubrs[i]))) + subrs_link = c->pop_pack (false); + else + { + c->pop_discard (); + return_trace (false); + } + } + + auto *pd = c->push (); + // Use the CFF2 Private DICT serializer which instantiates blends when pinned=true + cff2_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned, + acc.varStore, plan.normalized_coords); + if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link))) + { + // Add defaultWidthX and nominalWidthX for CFF1 + str_buff_t width_ops; + str_encoder_t encoder (width_ops); + encoder.encode_int (plan.default_width); + encoder.encode_op (OpCode_defaultWidthX); + encoder.encode_int (plan.nominal_width); + encoder.encode_op (OpCode_nominalWidthX); + + if (!encoder.in_error () && c->embed (width_ops.as_bytes ().arrayZ, width_ops.length)) + { + unsigned fd = plan.fdmap[i]; + private_dict_infos[fd].size = c->length (); + private_dict_infos[fd].link = c->pop_pack (); + } + else + { + c->pop_discard (); + return_trace (false); + } + } + else + { + c->pop_discard (); + return_trace (false); + } + } + } + + // 3. FDArray - serialize CFF2 font dicts as CFF1 + { + auto *fda = c->push> (); + cff_font_dict_op_serializer_t fontSzr; + auto it = + + hb_zip (+ hb_iter (acc.fontDicts) + | hb_filter ([&] (const cff2_font_dict_values_t &_) + { return plan.fdmap.has (&_ - &acc.fontDicts[0]); }), + hb_iter (private_dict_infos)) + ; + // Explicitly specify template parameters: DICTVAL, INFO + bool success = fda->serialize (c, it, fontSzr); + if (success) + plan.info.fd_array_link = c->pop_pack (false); + else + { + c->pop_discard (); + return_trace (false); + } + } + + // 4. FDSelect (required in CFF1 CID-keyed fonts) + // CFF1 requires FDSelect for all CID-keyed fonts, even with just one FD + // CFF2 makes it optional when there's only one FD + if (acc.fdSelect != &Null (CFF2FDSelect)) + { + c->push (); + if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, + *(const FDSelect *)acc.fdSelect, + plan.orig_fdcount, + plan.subset_fdselect_format, + plan.subset_fdselect_size, + plan.subset_fdselect_ranges))) + plan.info.fd_select.link = c->pop_pack (); + else + { + c->pop_discard (); + return_trace (false); + } + } + else + { + // Create a range-based FDSelect3 mapping all glyphs to FD 0 + // Format: format(1) + nRanges(2) + range(3) + sentinel(2) = 8 bytes + c->push (); + + // Format byte + HBUINT8 format; + format = 3; + if (unlikely (!c->embed (format))) + { + c->pop_discard (); + return_trace (false); + } + + // nRanges + HBUINT16 nRanges; + nRanges = 1; + if (unlikely (!c->embed (nRanges))) + { + c->pop_discard (); + return_trace (false); + } + + // Single range: {first: 0, fd: 0} + FDSelect3_Range range; + range.first = 0; + range.fd = 0; + if (unlikely (!c->embed (range))) + { + c->pop_discard (); + return_trace (false); + } + + // Sentinel (number of glyphs) + HBUINT16 sentinel; + sentinel = plan.num_glyphs; + if (unlikely (!c->embed (sentinel))) + { + c->pop_discard (); + return_trace (false); + } + + plan.info.fd_select.link = c->pop_pack (); + } + + // 5. Charset (CID charset for identity mapping) + objidx_t charset_link; + if (!_serialize_cff1_charset (c, plan.num_glyphs, charset_link)) + return_trace (false); + + // 6. Global Subrs + { + auto *dest = c->push (); + if (likely (dest->serialize (c, plan.subset_globalsubrs))) + c->pop_pack (false); + else + { + c->pop_discard (); + return_trace (false); + } + } + + // 7. String INDEX - Add "Adobe" and "Identity" for ROS operator + { + const char *adobe_str = "Adobe"; + const char *identity_str = "Identity"; + unsigned adobe_len = 5; // strlen("Adobe") + unsigned identity_len = 8; // strlen("Identity") + + // Build strings array + hb_vector_t strings; + strings.alloc (2); + strings.push (hb_ubytes_t ((const unsigned char *) adobe_str, adobe_len)); + strings.push (hb_ubytes_t ((const unsigned char *) identity_str, identity_len)); + + // Serialize as CFF INDEX + auto *dest = c->push (); + if (likely (dest->serialize (c, strings))) + c->pop_pack (false); + else + { + c->pop_discard (); + return_trace (false); + } + } + + // 8. CFF Header + OT::cff1 *cff = c->allocate_min (); + if (unlikely (!cff)) return_trace (false); + + /* header */ + cff->version.major = 0x01; + cff->version.minor = 0x00; + cff->nameIndex = cff->min_size; + cff->offSize = 4; /* unused? */ + + // 9. Name INDEX (single entry) + { + unsigned name_len = strlen (CFF1_DEFAULT_FONT_NAME); + + CFF1Index *idx = c->start_embed (); + if (unlikely (!idx)) return_trace (false); + + if (unlikely (!idx->serialize_header (c, hb_iter (&name_len, 1), name_len))) + return_trace (false); + + if (unlikely (!c->embed (CFF1_DEFAULT_FONT_NAME, name_len))) + return_trace (false); + } + + // 10. Top DICT INDEX + { + // Serialize the Top DICT data first + c->push (); + cff1_from_cff2_top_dict_op_serializer_t topSzr; + + // Serialize ROS first + if (unlikely (!topSzr.serialize_ros (c))) + { + c->pop_discard (); + return_trace (false); + } + + // Serialize FontBBox from head table + { + str_buff_t bbox_buff; + str_encoder_t encoder (bbox_buff); + + encoder.encode_int (plan.head_maxp_info.xMin); + encoder.encode_int (plan.head_maxp_info.yMin); + encoder.encode_int (plan.head_maxp_info.xMax); + encoder.encode_int (plan.head_maxp_info.yMax); + encoder.encode_op (OpCode_FontBBox); + + if (encoder.in_error () || !c->embed (bbox_buff.as_bytes ().arrayZ, bbox_buff.length)) + { + c->pop_discard (); + return_trace (false); + } + } + + // Serialize charset operator + if (charset_link && unlikely (!FontDict::serialize_link4_op (c, OpCode_charset, charset_link, whence_t::Absolute))) + { + c->pop_discard (); + return_trace (false); + } + + // Serialize FDSelect operator (required for CID-keyed CFF1 fonts) + if (plan.info.fd_select.link && unlikely (!FontDict::serialize_link4_op (c, OpCode_FDSelect, plan.info.fd_select.link, whence_t::Absolute))) + { + c->pop_discard (); + return_trace (false); + } + + // Serialize FDArray operator (required for CID-keyed CFF1 fonts) + if (plan.info.fd_array_link && unlikely (!FontDict::serialize_link4_op (c, OpCode_FDArray, plan.info.fd_array_link, whence_t::Absolute))) + { + c->pop_discard (); + return_trace (false); + } + + // Serialize other operators from CFF2 TopDict + for (const auto &opstr : cff2_topDict.values) + { + if (unlikely (!topSzr.serialize (c, opstr, plan.info))) + { + c->pop_discard (); + return_trace (false); + } + } + + unsigned top_size = c->length (); + c->pop_pack (false); + + // Serialize INDEX header + auto *dest = c->start_embed (); + if (unlikely (!dest->serialize_header (c, hb_iter (&top_size, 1), top_size))) + return_trace (false); + } + + return_trace (true); +} + +} /* namespace CFF */ + static bool _serialize_cff2_charstrings (hb_serialize_context_t *c, cff2_subset_plan &plan, const OT::cff2::accelerator_subset_t &acc) @@ -669,6 +1229,38 @@ OT::cff2::accelerator_subset_t::subset (hb_subset_context_t *c) const cff2_subset_plan cff2_plan; if (unlikely (!cff2_plan.create (*this, c->plan))) return false; + + // If instantiating (pinned) and downgrade flag is set, convert to CFF1 + if (cff2_plan.pinned && (c->plan->flags & HB_SUBSET_FLAGS_DOWNGRADE_CFF2)) + { + // Serialize CFF1 to the subsetter's serializer + // If we run out of room, returning true will cause subsetter to retry with larger buffer + bool result = CFF::serialize_cff2_to_cff1 (c->serializer, cff2_plan, topDict, *this); + + if (c->serializer->ran_out_of_room ()) + return true; // Subsetter will retry with larger buffer + + if (result && !c->serializer->in_error ()) + { + // Success - end serialization to resolve links + c->serializer->end_serialize (); + + // Copy the serialized CFF1 data and add as CFF table + hb_blob_t *cff_blob = c->serializer->copy_blob (); + if (cff_blob) + { + c->plan->add_table (HB_TAG('C','F','F',' '), cff_blob); + hb_blob_destroy (cff_blob); + + // Return false to signal CFF2 table is not needed + return false; + } + } + + // Conversion failed - don't fall back, fail hard for debugging + return false; + } + return serialize (c->serializer, cff2_plan, c->plan->normalized_coords.as_array ()); } diff --git a/thirdparty/harfbuzz/upstream/hb-subset-input.cc b/thirdparty/harfbuzz/upstream/hb-subset-input.cc index b874949df..a3c3b9295 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-input.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-input.cc @@ -534,7 +534,6 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, * * Note: input min value can not be bigger than input max value. If the input * default value is not within the new min/max range, it'll be clamped. - * Note: currently it supports gvar and cvar tables only. * * Return value: `true` if success, `false` otherwise * @@ -597,6 +596,144 @@ hb_subset_input_get_axis_range (hb_subset_input_t *input, *axis_max_value = triple->maximum; return true; } + +/** + * hb_subset_axis_range_from_string: + * @str: a string to parse + * @len: length of @str, or -1 if str is NULL terminated + * @axis_min_value: (out): the axis min value to initialize with the parsed value + * @axis_max_value: (out): the axis max value to initialize with the parsed value + * @axis_def_value: (out): the axis default value to initialize with the parse + * value + * + * Parses a string into a subset axis range(min, def, max). + * Axis positions string is in the format of min:def:max or min:max + * When parsing axis positions, empty values as meaning the existing value for that part + * E.g: :300:500 + * Specifies min = existing, def = 300, max = 500 + * In the output axis_range, if a value should be set to it's default value, + * then it will be set to NaN + * + * Return value: + * `true` if @str is successfully parsed, `false` otherwise + * + * Since: 10.2.0 + */ +HB_EXTERN hb_bool_t +hb_subset_axis_range_from_string (const char *str, int len, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value) +{ + if (len < 0) + len = strlen (str); + + const char *end = str + len; + const char* part = strpbrk (str, ":"); + if (!part) + { + // Single value. + if (strcmp (str, "drop") == 0) + { + *axis_min_value = NAN; + *axis_def_value = NAN; + *axis_max_value = NAN; + return true; + } + + double v; + if (!hb_parse_double (&str, end, &v)) return false; + + *axis_min_value = v; + *axis_def_value = v; + *axis_max_value = v; + return true; + } + + float values[3]; + int count = 0; + for (int i = 0; i < 3; i++) { + count++; + if (!*str || part == str) + { + values[i] = NAN; + + if (part == NULL) break; + str = part + 1; + part = strpbrk (str, ":"); + continue; + } + + double v; + if (!hb_parse_double (&str, part, &v)) return false; + values[i] = v; + + if (part == NULL) break; + str = part + 1; + part = strpbrk (str, ":"); + } + + if (count == 2) + { + *axis_min_value = values[0]; + *axis_def_value = NAN; + *axis_max_value = values[1]; + return true; + } + else if (count == 3) + { + *axis_min_value = values[0]; + *axis_def_value = values[1]; + *axis_max_value = values[2]; + return true; + } + return false; +} + +/** + * hb_subset_axis_range_to_string: + * @input: a #hb_subset_input_t object. + * @axis_tag: an axis to convert + * @buf: (array length=size) (out caller-allocates): output string + * @size: the allocated size of @buf + * + * Converts an axis range into a `NULL`-terminated string in the format + * understood by hb_subset_axis_range_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. + * + * Since: 10.2.0 + */ +HB_EXTERN void +hb_subset_axis_range_to_string (hb_subset_input_t *input, + hb_tag_t axis_tag, + char *buf, unsigned size) +{ + if (unlikely (!size)) return; + Triple* triple; + if (!input->axes_location.has(axis_tag, &triple)) { + return; + } + + char s[128]; + unsigned len = 0; + + hb_locale_t clocale HB_UNUSED; + hb_locale_t oldlocale HB_UNUSED; + oldlocale = hb_uselocale (clocale = newlocale (LC_ALL_MASK, "C", NULL)); + len += hb_max (0, snprintf (s, ARRAY_LENGTH (s) - len, "%g", (double) triple->minimum)); + s[len++] = ':'; + + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) triple->middle)); + s[len++] = ':'; + + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) triple->maximum)); + (void) hb_uselocale (((void) freelocale (clocale), oldlocale)); + + assert (len < ARRAY_LENGTH (s)); + len = hb_min (len, size - 1); + hb_memcpy (buf, s, len); + buf[len] = '\0'; +} #endif /** @@ -731,7 +868,7 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, src = hb_utf8_t::next (src, src_end, &unicode, replacement); if (unicode >= 0x0080u) { - printf ("Non-ascii character detected, ignored...This API supports ascii characters only for mac platform\n"); + // Non-ascii character detected, ignored... return false; } } diff --git a/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.cc b/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.cc index 074657aca..f81ecfba8 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.cc @@ -24,6 +24,10 @@ #include "hb-subset-instancer-iup.hh" +#include "hb-bit-page.hh" + +using hb_iup_set_t = hb_bit_page_t; + /* This file is a straight port of the following: * * https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/varLib/iup.py @@ -37,7 +41,7 @@ constexpr static unsigned MAX_LOOKBACK = 8; static void _iup_contour_bound_forced_set (const hb_array_t contour_points, const hb_array_t x_deltas, const hb_array_t y_deltas, - hb_set_t& forced_set, /* OUT */ + hb_iup_set_t& forced_set, /* OUT */ double tolerance = 0.0) { unsigned len = contour_points.length; @@ -136,7 +140,7 @@ static bool rotate_array (const hb_array_t& org_array, { unsigned n = org_array.length; if (!n) return true; - if (unlikely (!out.resize (n, false))) + if (unlikely (!out.resize_dirty (n))) return false; unsigned item_size = hb_static_size (T); @@ -150,10 +154,10 @@ static bool rotate_array (const hb_array_t& org_array, return true; } -static bool rotate_set (const hb_set_t& org_set, +static bool rotate_set (const hb_iup_set_t& org_set, int k, unsigned n, - hb_set_t& out) + hb_iup_set_t& out) { if (!n) return false; k %= n; @@ -162,14 +166,14 @@ static bool rotate_set (const hb_set_t& org_set, if (k == 0) { - out.set (org_set); + out = org_set; } else { - for (auto v : org_set) + for (unsigned v : org_set) out.add ((v + k) % n); } - return !out.in_error (); + return true; } /* Given two reference coordinates (start and end of contour_points array), @@ -180,32 +184,39 @@ static bool _iup_segment (const hb_array_t contour_points const contour_point_t& p1, const contour_point_t& p2, int p1_dx, int p2_dx, int p1_dy, int p2_dy, + double tolerance_sq, hb_vector_t& interp_x_deltas, /* OUT */ hb_vector_t& interp_y_deltas /* OUT */) { unsigned n = contour_points.length; - if (unlikely (!interp_x_deltas.resize (n, false) || - !interp_y_deltas.resize (n, false))) + if (unlikely (!interp_x_deltas.resize_dirty (n) || + !interp_y_deltas.resize_dirty (n))) return false; for (unsigned j = 0; j < 2; j++) { + float contour_point_t::* xp; double x1, x2, d1, d2; + const int *in; double *out; if (j == 0) { + xp = &contour_point_t::x; x1 = static_cast (p1.x); x2 = static_cast (p2.x); d1 = p1_dx; d2 = p2_dx; + in = x_deltas.arrayZ; out = interp_x_deltas.arrayZ; } else { + xp = &contour_point_t::y; x1 = static_cast (p1.y); x2 = static_cast (p2.y); d1 = p1_dy; d2 = p2_dy; + in = y_deltas.arrayZ; out = interp_y_deltas.arrayZ; } @@ -233,7 +244,7 @@ static bool _iup_segment (const hb_array_t contour_points double scale = (d2 - d1) / (x2 - x1); for (unsigned i = 0; i < n; i++) { - double x = (j == 0 ? static_cast (contour_points.arrayZ[i].x) : static_cast (contour_points.arrayZ[i].y)); + double x = (double) (contour_points.arrayZ[i].*xp); double d; if (x <= x1) d = d1; @@ -243,6 +254,9 @@ static bool _iup_segment (const hb_array_t contour_points d = d1 + (x - x1) * scale; out[i] = d; + double err = d - in[i]; + if (err * err > tolerance_sq) + return false; } } return true; @@ -254,11 +268,13 @@ static bool _can_iup_in_between (const hb_array_t contour const contour_point_t& p1, const contour_point_t& p2, int p1_dx, int p2_dx, int p1_dy, int p2_dy, - double tolerance) + double tolerance_sq, + hb_vector_t &interp_x_deltas, /* scratch */ + hb_vector_t &interp_y_deltas /* scratch */) { - hb_vector_t interp_x_deltas, interp_y_deltas; if (!_iup_segment (contour_points, x_deltas, y_deltas, p1, p2, p1_dx, p2_dx, p1_dy, p2_dy, + tolerance_sq, interp_x_deltas, interp_y_deltas)) return false; @@ -268,8 +284,8 @@ static bool _can_iup_in_between (const hb_array_t contour { double dx = static_cast (x_deltas.arrayZ[i]) - interp_x_deltas.arrayZ[i]; double dy = static_cast (y_deltas.arrayZ[i]) - interp_y_deltas.arrayZ[i]; - - if (sqrt (dx * dx + dy * dy) > tolerance) + + if (dx * dx + dy * dy > tolerance_sq) return false; } return true; @@ -278,15 +294,17 @@ static bool _can_iup_in_between (const hb_array_t contour static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, - const hb_set_t& forced_set, - double tolerance, + const hb_iup_set_t& forced_set, + double tolerance_sq, unsigned lookback, hb_vector_t& costs, /* OUT */ - hb_vector_t& chain /* OUT */) + hb_vector_t& chain, /* OUT */ + hb_vector_t &interp_x_deltas_scratch, + hb_vector_t &interp_y_deltas_scratch) { unsigned n = contour_points.length; - if (unlikely (!costs.resize (n, false) || - !chain.resize (n, false))) + if (unlikely (!costs.resize_dirty (n) || + !chain.resize_dirty (n))) return false; lookback = hb_min (lookback, MAX_LOOKBACK); @@ -294,7 +312,7 @@ static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_poin for (unsigned i = 0; i < n; i++) { unsigned best_cost = (i == 0 ? 1 : costs.arrayZ[i-1] + 1); - + costs.arrayZ[i] = best_cost; chain.arrayZ[i] = (i == 0 ? -1 : i - 1); @@ -315,7 +333,8 @@ static bool _iup_contour_optimize_dp (const contour_point_vector_t& contour_poin contour_points.arrayZ[p1], contour_points.arrayZ[i], x_deltas.arrayZ[p1], x_deltas.arrayZ[i], y_deltas.arrayZ[p1], y_deltas.arrayZ[i], - tolerance)) + tolerance_sq, + interp_x_deltas_scratch, interp_y_deltas_scratch)) { best_cost = cost; costs.arrayZ[i] = best_cost; @@ -333,7 +352,8 @@ static bool _iup_contour_optimize (const hb_array_t conto const hb_array_t x_deltas, const hb_array_t y_deltas, hb_array_t opt_indices, /* OUT */ - double tolerance = 0.0) + double tolerance, + iup_scratch_t &scratch) { unsigned n = contour_points.length; if (opt_indices.length != n || @@ -341,12 +361,16 @@ static bool _iup_contour_optimize (const hb_array_t conto y_deltas.length != n) return false; + if (unlikely (n > hb_iup_set_t::PAGE_BITS)) + return true; // Refuse to work + bool all_within_tolerance = true; + double tolerance_sq = tolerance * tolerance; for (unsigned i = 0; i < n; i++) { int dx = x_deltas.arrayZ[i]; int dy = y_deltas.arrayZ[i]; - if (sqrt ((double) dx * dx + (double) dy * dy) > tolerance) + if ((double) dx * dx + (double) dy * dy > tolerance_sq) { all_within_tolerance = false; break; @@ -382,33 +406,36 @@ static bool _iup_contour_optimize (const hb_array_t conto } /* else, solve the general problem using Dynamic Programming */ - hb_set_t forced_set; + hb_iup_set_t forced_set; _iup_contour_bound_forced_set (contour_points, x_deltas, y_deltas, forced_set, tolerance); + hb_vector_t &costs = scratch.costs.reset (); + hb_vector_t &chain = scratch.chain.reset (); + if (!forced_set.is_empty ()) { int k = n - 1 - forced_set.get_max (); if (k < 0) return false; - hb_vector_t rot_x_deltas, rot_y_deltas; - contour_point_vector_t rot_points; - hb_set_t rot_forced_set; + hb_vector_t &rot_x_deltas = scratch.rot_x_deltas.reset (); + hb_vector_t &rot_y_deltas = scratch.rot_y_deltas.reset (); + contour_point_vector_t &rot_points = scratch.rot_points; + rot_points.reset (); + hb_iup_set_t rot_forced_set; if (!rotate_array (contour_points, k, rot_points) || !rotate_array (x_deltas, k, rot_x_deltas) || !rotate_array (y_deltas, k, rot_y_deltas) || !rotate_set (forced_set, k, n, rot_forced_set)) return false; - hb_vector_t costs; - hb_vector_t chain; - if (!_iup_contour_optimize_dp (rot_points, rot_x_deltas, rot_y_deltas, - rot_forced_set, tolerance, n, - costs, chain)) + rot_forced_set, tolerance_sq, n, + costs, chain, + scratch.interp_x_deltas, scratch.interp_y_deltas)) return false; - hb_set_t solution; + hb_iup_set_t solution; int index = n - 1; while (index != -1) { @@ -423,7 +450,7 @@ static bool _iup_contour_optimize (const hb_array_t conto for (unsigned i : solution) opt_indices.arrayZ[i] = true; - hb_vector_t rot_indices; + hb_vector_t &rot_indices = scratch.rot_indices.reset (); const hb_array_t opt_indices_array (opt_indices.arrayZ, opt_indices.length); rotate_array (opt_indices_array, -k, rot_indices); @@ -435,9 +462,9 @@ static bool _iup_contour_optimize (const hb_array_t conto hb_vector_t repeat_x_deltas, repeat_y_deltas; contour_point_vector_t repeat_points; - if (unlikely (!repeat_x_deltas.resize (n * 2, false) || - !repeat_y_deltas.resize (n * 2, false) || - !repeat_points.resize (n * 2, false))) + if (unlikely (!repeat_x_deltas.resize_dirty (n * 2) || + !repeat_y_deltas.resize_dirty (n * 2) || + !repeat_points.resize_dirty (n * 2))) return false; unsigned contour_point_size = hb_static_size (contour_point_t); @@ -453,19 +480,18 @@ static bool _iup_contour_optimize (const hb_array_t conto hb_memcpy ((void *) (repeat_points.arrayZ + n), (const void *) contour_points.arrayZ, n * contour_point_size); } - hb_vector_t costs; - hb_vector_t chain; if (!_iup_contour_optimize_dp (repeat_points, repeat_x_deltas, repeat_y_deltas, - forced_set, tolerance, n, - costs, chain)) + forced_set, tolerance_sq, n, + costs, chain, + scratch.interp_x_deltas, scratch.interp_y_deltas)) return false; unsigned best_cost = n + 1; int len = costs.length; - hb_set_t best_sol; + hb_iup_set_t best_sol; for (int start = n - 1; start < len; start++) { - hb_set_t solution; + hb_iup_set_t solution; int i = start; int lookback = start - (int) n; while (i > lookback) @@ -479,7 +505,7 @@ static bool _iup_contour_optimize (const hb_array_t conto unsigned cost = costs.arrayZ[start] - cost_i; if (cost <= best_cost) { - best_sol.set (solution); + best_sol = solution; best_cost = cost; } } @@ -496,12 +522,14 @@ bool iup_delta_optimize (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, hb_vector_t& opt_indices, /* OUT */ + iup_scratch_t &scratch, double tolerance) { if (!opt_indices.resize (contour_points.length)) return false; - hb_vector_t end_points; + hb_vector_t &end_points = scratch.end_points.reset (); + unsigned count = contour_points.length; if (unlikely (!end_points.alloc (count))) return false; @@ -524,7 +552,8 @@ bool iup_delta_optimize (const contour_point_vector_t& contour_points, x_deltas.as_array ().sub_array (start, len), y_deltas.as_array ().sub_array (start, len), opt_indices.as_array ().sub_array (start, len), - tolerance)) + tolerance, + scratch)) return false; start = end + 1; } diff --git a/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.hh b/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.hh index 01987bd25..32d38c04f 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.hh +++ b/thirdparty/harfbuzz/upstream/hb-subset-instancer-iup.hh @@ -26,12 +26,27 @@ #define HB_SUBSET_INSTANCER_IUP_HH #include "hb-subset-plan.hh" + +struct iup_scratch_t +{ + hb_vector_t end_points; + hb_vector_t interp_x_deltas; + hb_vector_t interp_y_deltas; + hb_vector_t costs; + hb_vector_t chain; + hb_vector_t rot_indices; + hb_vector_t rot_x_deltas; + hb_vector_t rot_y_deltas; + contour_point_vector_t rot_points; +}; + /* given contour points and deltas, optimize a set of referenced points within error * tolerance. Returns optimized referenced point indices */ HB_INTERNAL bool iup_delta_optimize (const contour_point_vector_t& contour_points, const hb_vector_t& x_deltas, const hb_vector_t& y_deltas, hb_vector_t& opt_indices, /* OUT */ + iup_scratch_t &scratch, double tolerance = 0.0); #endif /* HB_SUBSET_INSTANCER_IUP_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.cc b/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.cc index ec0157599..03c59dc80 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.cc @@ -62,9 +62,10 @@ static inline double supportScalar (double coord, const Triple &tent) return (end - coord) / (end - peak); } -static inline rebase_tent_result_t -_solve (Triple tent, Triple axisLimit, bool negative = false) +static inline void +_solve (Triple tent, Triple axisLimit, rebase_tent_result_t &out, bool negative = false) { + out.reset(); double axisMin = axisLimit.minimum; double axisDef = axisLimit.middle; double axisMax = axisLimit.maximum; @@ -75,14 +76,12 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) // Mirror the problem such that axisDef <= peak if (axisDef > peak) { - rebase_tent_result_t vec = _solve (_reverse_negate (tent), - _reverse_negate (axisLimit), - !negative); + _solve (_reverse_negate (tent), _reverse_negate (axisLimit), out, !negative); - for (auto &p : vec) + for (auto &p : out) p = hb_pair (p.first, _reverse_negate (p.second)); - return vec; + return; } // axisDef <= peak @@ -98,7 +97,7 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) * axisMin axisDef axisMax lower upper */ if (axisMax <= lower && axisMax < peak) - return rebase_tent_result_t{}; // No overlap + return; // No overlap /* case 2: Only the peak and outermost bound fall outside the new limit; * we keep the deltaset, update peak and outermost bound and scale deltas @@ -133,18 +132,18 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) double mult = supportScalar (axisMax, tent); tent = Triple{lower, axisMax, axisMax}; - rebase_tent_result_t vec = _solve (tent, axisLimit); + _solve (tent, axisLimit, out); - for (auto &p : vec) + for (auto &p : out) p = hb_pair (p.first * mult, p.second); - return vec; + return; } // lower <= axisDef <= peak <= axisMax double gain = supportScalar (axisDef, tent); - rebase_tent_result_t out {hb_pair (gain, Triple{})}; + out.push(hb_pair (gain, Triple{})); // First, the positive side @@ -362,8 +361,6 @@ _solve (Triple tent, Triple axisLimit, bool negative = false) out.push (hb_pair (scalar1 - gain, loc1)); out.push (hb_pair (scalar2 - gain, loc2)); } - - return out; } static inline TripleDistances _reverse_triple_distances (const TripleDistances &v) @@ -405,18 +402,31 @@ double renormalizeValue (double v, const Triple &triple, return (-v_distance) /total_distance; } -rebase_tent_result_t -rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances) +void +rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances, + rebase_tent_result_t &out, + rebase_tent_result_t &scratch) { - assert (-1.0 <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.0); - assert (-2.0 <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.0); - assert (tent.middle != 0.0); + if (unlikely (!(-1.0 <= axisLimit.minimum && + axisLimit.minimum <= axisLimit.middle && + axisLimit.middle <= axisLimit.maximum && + axisLimit.maximum <= +1.0) || + !(-2.0 <= tent.minimum && + tent.minimum <= tent.middle && + tent.middle <= tent.maximum && + tent.maximum <= +2.0) || + tent.middle == 0.0)) + { + out.reset (); + return; + } - rebase_tent_result_t sols = _solve (tent, axisLimit); + rebase_tent_result_t &sols = scratch; + _solve (tent, axisLimit, sols); auto n = [&axisLimit, &axis_triple_distances] (double v) { return renormalizeValue (v, axisLimit, axis_triple_distances); }; - rebase_tent_result_t out; + out.reset(); for (auto &p : sols) { if (!p.first) continue; @@ -429,6 +439,4 @@ rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distance out.push (hb_pair (p.first, Triple{n (t.minimum), n (t.middle), n (t.maximum)})); } - - return out; } diff --git a/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.hh b/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.hh index 9aac9fcc7..3462d3cf6 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.hh +++ b/thirdparty/harfbuzz/upstream/hb-subset-instancer-solver.hh @@ -42,10 +42,9 @@ struct TripleDistances double positive; }; -struct Triple { - - Triple () : - minimum (0.0), middle (0.0), maximum (0.0) {} +struct Triple +{ + Triple () = default; Triple (double minimum_, double middle_, double maximum_) : minimum (minimum_), middle (middle_), maximum (maximum_) {} @@ -81,10 +80,9 @@ struct Triple { return current; } - - double minimum; - double middle; - double maximum; + double minimum = 0; + double middle = 0; + double maximum = 0; }; using rebase_tent_result_item_t = hb_pair_t; @@ -107,8 +105,10 @@ HB_INTERNAL double renormalizeValue (double v, const Triple &triple, * If tent value is Triple{}, that is a special deltaset that should * be always-enabled (called "gain"). */ -HB_INTERNAL rebase_tent_result_t rebase_tent (Triple tent, - Triple axisLimit, - TripleDistances axis_triple_distances); +HB_INTERNAL void rebase_tent (Triple tent, + Triple axisLimit, + TripleDistances axis_triple_distances, + rebase_tent_result_t &out, + rebase_tent_result_t &scratch); #endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-plan-layout.cc b/thirdparty/harfbuzz/upstream/hb-subset-plan-layout.cc new file mode 100644 index 000000000..ba4a57b5c --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-plan-layout.cc @@ -0,0 +1,420 @@ +/* + * Copyright © 2023 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Qunxin Liu, Roderick Sheeter + */ + +#include "hb-subset-plan.hh" + +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-layout-gsub-table.hh" + +using OT::Layout::GSUB; +using OT::Layout::GPOS; + +#ifndef HB_NO_SUBSET_LAYOUT + +void +remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map) +{ + hb_blob_ptr_t gdef = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) + { + gdef.destroy (); + return; + } + + hb_set_t used_mark_sets; + gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); + gdef.destroy (); + + remap_indexes (&used_mark_sets, &used_mark_sets_map); +} + +/* + * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates. + * Returns true if anything was removed (not including duplicates). + */ +static bool _filter_tag_list(hb_vector_t* tags, /* IN/OUT */ + const hb_set_t* filter) +{ + hb_vector_t out; + out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator. + + bool removed = false; + hb_set_t visited; + + for (hb_tag_t tag : *tags) + { + if (!tag) continue; + if (visited.has (tag)) continue; + + if (!filter->has (tag)) + { + removed = true; + continue; + } + + visited.add (tag); + out.push (tag); + } + + // The collect function needs a null element to signal end of the array. + out.push (HB_TAG_NONE); + + hb_swap (out, *tags); + return removed; +} + +template +static void _collect_layout_indices (hb_subset_plan_t *plan, + const T& table, + hb_set_t *lookup_indices, /* OUT */ + hb_set_t *feature_indices, /* OUT */ + hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ + hb_hashmap_t *feature_substitutes_map, /* OUT */ + hb_set_t& catch_all_record_feature_idxes, /* OUT */ + hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) +{ + unsigned num_features = table.get_feature_count (); + hb_vector_t features; + if (!plan->check_success (features.resize (num_features))) return; + table.get_feature_tags (0, &num_features, features.arrayZ); + bool retain_all_features = !_filter_tag_list (&features, &plan->layout_features); + + unsigned num_scripts = table.get_script_count (); + hb_vector_t scripts; + if (!plan->check_success (scripts.resize (num_scripts))) return; + table.get_script_tags (0, &num_scripts, scripts.arrayZ); + bool retain_all_scripts = !_filter_tag_list (&scripts, &plan->layout_scripts); + + if (!plan->check_success (!features.in_error ()) || !features + || !plan->check_success (!scripts.in_error ()) || !scripts) + return; + + hb_ot_layout_collect_features (plan->source, + T::tableTag, + retain_all_scripts ? nullptr : scripts.arrayZ, + nullptr, + retain_all_features ? nullptr : features.arrayZ, + feature_indices); + +#ifndef HB_NO_VAR + // collect feature substitutes with variations + if (!plan->user_axes_location.is_empty ()) + { + hb_hashmap_t, unsigned> conditionset_map; + OT::hb_collect_feature_substitutes_with_var_context_t c = + { + &plan->axes_old_index_tag_map, + &plan->axes_location, + feature_record_cond_idx_map, + feature_substitutes_map, + catch_all_record_feature_idxes, + feature_indices, + false, + false, + false, + 0, + &conditionset_map + }; + table.collect_feature_substitutes_with_variations (&c); + } +#endif + + for (unsigned feature_index : *feature_indices) + { + const OT::Feature* f = &(table.get_feature (feature_index)); + const OT::Feature **p = nullptr; + if (feature_substitutes_map->has (feature_index, &p)) + f = *p; + + f->add_lookup_indexes_to (lookup_indices); + } + +#ifndef HB_NO_VAR + if (catch_all_record_feature_idxes) + { + for (unsigned feature_index : catch_all_record_feature_idxes) + { + const OT::Feature& f = table.get_feature (feature_index); + f.add_lookup_indexes_to (lookup_indices); + const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); + catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); + } + } + + // If all axes are pinned then all feature variations will be dropped so there's no need + // to collect lookups from them. + if (!plan->all_axes_pinned) + table.feature_variation_collect_lookups (feature_indices, + plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, + lookup_indices); +#endif +} + + +static inline void +_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, + const hb_map_t *lookup_indices, + const hb_set_t *feature_indices, + const hb_hashmap_t *feature_substitutes_map, + hb_map_t *duplicate_feature_map /* OUT */) +{ + if (feature_indices->is_empty ()) return; + hb_hashmap_t> unique_features; + //find out duplicate features after subset + for (unsigned i : feature_indices->iter ()) + { + hb_tag_t t = g.get_feature_tag (i); + if (t == HB_MAP_VALUE_INVALID) continue; + if (!unique_features.has (t)) + { + if (unlikely (!unique_features.set (t, hb::unique_ptr {hb_set_create ()}))) + return; + if (unique_features.has (t)) + unique_features.get (t)->add (i); + duplicate_feature_map->set (i, i); + continue; + } + + bool found = false; + + hb_set_t* same_tag_features = unique_features.get (t); + for (unsigned other_f_index : same_tag_features->iter ()) + { + const OT::Feature* f = &(g.get_feature (i)); + const OT::Feature **p = nullptr; + if (feature_substitutes_map->has (i, &p)) + f = *p; + + const OT::Feature* other_f = &(g.get_feature (other_f_index)); + if (feature_substitutes_map->has (other_f_index, &p)) + other_f = *p; + + auto f_iter = + + hb_iter (f->lookupIndex) + | hb_filter (lookup_indices) + ; + + auto other_f_iter = + + hb_iter (other_f->lookupIndex) + | hb_filter (lookup_indices) + ; + + bool is_equal = true; + for (; f_iter && other_f_iter; f_iter++, other_f_iter++) + { + unsigned a = *f_iter; + unsigned b = *other_f_iter; + if (a != b) { is_equal = false; break; } + } + + if (is_equal == false || f_iter || other_f_iter) continue; + + found = true; + duplicate_feature_map->set (i, other_f_index); + break; + } + + if (found == false) + { + same_tag_features->add (i); + duplicate_feature_map->set (i, i); + } + } +} + +static void +remap_feature_indices (const hb_set_t &feature_indices, + const hb_map_t &duplicate_feature_map, + const hb_hashmap_t>& catch_all_record_idx_feature_map, + hb_map_t *mapping, /* OUT */ + hb_map_t *mapping_w_duplicates /* OUT */) +{ + unsigned i = 0; + for (const auto _ : feature_indices) + { + // retain those features in case we need to insert a catch-all record to reinstate the old features + if (catch_all_record_idx_feature_map.has (_)) + { + mapping->set (_, i); + mapping_w_duplicates->set (_, i); + i++; + } + else + { + uint32_t f_idx = duplicate_feature_map.get (_); + uint32_t *new_idx; + if (mapping-> has (f_idx, &new_idx)) + { + mapping_w_duplicates->set (_, *new_idx); + } + else + { + mapping->set (_, i); + mapping_w_duplicates->set (_, i); + i++; + } + } + } +} + +template +static void +_closure_glyphs_lookups_features (hb_subset_plan_t *plan, + hb_set_t *gids_to_retain, + hb_map_t *lookups, + hb_map_t *features, + hb_map_t *features_w_duplicates, + script_langsys_map *langsys_map, + hb_hashmap_t> *feature_record_cond_idx_map, + hb_hashmap_t *feature_substitutes_map, + hb_set_t &catch_all_record_feature_idxes, + hb_hashmap_t>& catch_all_record_idx_feature_map) +{ + hb_blob_ptr_t table = plan->source_table (); + hb_tag_t table_tag = table->tableTag; + hb_set_t lookup_indices, feature_indices; + _collect_layout_indices (plan, + *table, + &lookup_indices, + &feature_indices, + feature_record_cond_idx_map, + feature_substitutes_map, + catch_all_record_feature_idxes, + catch_all_record_idx_feature_map); + + if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) + hb_ot_layout_lookups_substitute_closure (plan->source, + &lookup_indices, + gids_to_retain); + table->closure_lookups (plan->source, + gids_to_retain, + &lookup_indices); + remap_indexes (&lookup_indices, lookups); + + // prune features + table->prune_features (lookups, + plan->user_axes_location.is_empty () ? nullptr : feature_record_cond_idx_map, + feature_substitutes_map, + &feature_indices); + hb_map_t duplicate_feature_map; + _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map); + + feature_indices.clear (); + table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices); + remap_feature_indices (feature_indices, duplicate_feature_map, catch_all_record_idx_feature_map, features, features_w_duplicates); + + table.destroy (); +} + +void layout_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables) +{ + if (!drop_tables->has (HB_OT_TAG_GPOS)) + { + hb_blob_ptr_t gpos = plan->source_table (); + gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); + gpos.destroy (); + } + if (!drop_tables->has (HB_OT_TAG_GSUB)) + { + hb_blob_ptr_t gsub = plan->source_table (); + gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); + gsub.destroy (); + } +} + +void +layout_populate_gids_to_retain (hb_subset_plan_t* plan, + hb_set_t* drop_tables) { + if (!drop_tables->has (HB_OT_TAG_GSUB)) + // closure all glyphs/lookups/features needed for GSUB substitutions. + _closure_glyphs_lookups_features ( + plan, + &plan->_glyphset_gsub, + &plan->gsub_lookups, + &plan->gsub_features, + &plan->gsub_features_w_duplicates, + &plan->gsub_langsys, + &plan->gsub_feature_record_cond_idx_map, + &plan->gsub_feature_substitutes_map, + plan->gsub_old_features, + plan->gsub_old_feature_idx_tag_map); + + if (!drop_tables->has (HB_OT_TAG_GPOS)) + _closure_glyphs_lookups_features ( + plan, + &plan->_glyphset_gsub, + &plan->gpos_lookups, + &plan->gpos_features, + &plan->gpos_features_w_duplicates, + &plan->gpos_langsys, + &plan->gpos_feature_record_cond_idx_map, + &plan->gpos_feature_substitutes_map, + plan->gpos_old_features, + plan->gpos_old_feature_idx_tag_map); +} + +#ifndef HB_NO_VAR +void +collect_layout_variation_indices (hb_subset_plan_t* plan) +{ + hb_blob_ptr_t gdef = plan->source_table (); + hb_blob_ptr_t gpos = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_var_store ()) + { + gdef.destroy (); + gpos.destroy (); + return; + } + + hb_set_t varidx_set; + OT::hb_collect_variation_indices_context_t c (&varidx_set, + &plan->_glyphset_gsub, + &plan->gpos_lookups); + gdef->collect_variation_indices (&c); + + if (hb_ot_layout_has_positioning (plan->source)) + gpos->collect_variation_indices (&c); + + remap_variation_indices (gdef->get_var_store (), + varidx_set, plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->layout_variation_idx_delta_map); + + unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); + generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); + + gdef.destroy (); + gpos.destroy (); +} +#endif + +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-subset-plan-member-list.hh b/thirdparty/harfbuzz/upstream/hb-subset-plan-member-list.hh index ade8278c4..398fe81ec 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-plan-member-list.hh +++ b/thirdparty/harfbuzz/upstream/hb-subset-plan-member-list.hh @@ -81,6 +81,10 @@ HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpo HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features) HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features) +//active features(with duplicates) old index -> new index mapping +HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features_w_duplicates) +HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features_w_duplicates) + //active feature variation records/condition index with variations HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gsub_feature_record_cond_idx_map) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), gpos_feature_record_cond_idx_map) diff --git a/thirdparty/harfbuzz/upstream/hb-subset-plan-var.cc b/thirdparty/harfbuzz/upstream/hb-subset-plan-var.cc new file mode 100644 index 000000000..fe29127d9 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-plan-var.cc @@ -0,0 +1,449 @@ +/* + * Copyright © 2023 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Qunxin Liu, Roderick Sheeter + */ + + #include "hb-ot-layout-common.hh" +#include "hb-subset-plan.hh" + + #include "hb-ot-var-common.hh" + #include "hb-ot-layout-base-table.hh" + #include "hb-ot-glyf-table.hh" + #include "hb-ot-var-fvar-table.hh" + #include "hb-ot-var-avar-table.hh" + #include "hb-ot-cff2-table.hh" + + #ifndef HB_NO_VAR + + void + generate_varstore_inner_maps (const hb_set_t& varidx_set, + unsigned subtable_count, + hb_vector_t &inner_maps /* OUT */) + { + if (varidx_set.is_empty () || subtable_count == 0) return; + + if (unlikely (!inner_maps.resize (subtable_count))) return; + for (unsigned idx : varidx_set) + { + uint16_t major = idx >> 16; + uint16_t minor = idx & 0xFFFF; + + if (major >= subtable_count) + continue; + inner_maps[major].add (minor); + } + } + + static inline hb_font_t* + _get_hb_font_with_variations (const hb_subset_plan_t *plan) + { + hb_font_t *font = hb_font_create (plan->source); + + hb_vector_t vars; + if (!vars.alloc (plan->user_axes_location.get_population ())) { + hb_font_destroy (font); + return nullptr; + } + + for (auto _ : plan->user_axes_location) + { + hb_variation_t var; + var.tag = _.first; + var.value = _.second.middle; + vars.push (var); + } + + hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); + return font; + } + + template + void + remap_variation_indices (const ItemVarStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */) + { + if (&var_store == &Null (OT::ItemVariationStore)) return; + unsigned subtable_count = var_store.get_sub_table_count (); + auto *store_cache = var_store.create_cache (); + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (variation_indices.get_min ()) >> 16; + for (unsigned idx : variation_indices) + { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); + ++new_minor; + last_major = major; + } + var_store.destroy_cache (store_cache); + } + + template + void + remap_variation_indices (const OT::ItemVariationStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */); + + #ifndef HB_NO_BASE + void + collect_base_variation_indices (hb_subset_plan_t* plan) + { + hb_blob_ptr_t base = plan->source_table (); + if (!base->has_var_store ()) + { + base.destroy (); + return; + } + + hb_set_t varidx_set; + base->collect_variation_indices (plan, varidx_set); + const OT::ItemVariationStore &var_store = base->get_var_store (); + unsigned subtable_count = var_store.get_sub_table_count (); + + + remap_variation_indices (var_store, varidx_set, + plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->base_variation_idx_map); + generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); + + base.destroy (); + } + + #endif + +bool +normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) +{ + if (plan->user_axes_location.is_empty ()) + return true; + + hb_array_t axes = face->table.fvar->get_axes (); + if (!plan->check_success (plan->normalized_coords.resize (axes.length))) + return false; + + bool has_avar = face->table.avar->has_data (); + hb_vector_t normalized_mins; + hb_vector_t normalized_defaults; + hb_vector_t normalized_maxs; + if (has_avar) + { + if (!plan->check_success (normalized_mins.resize (axes.length)) || + !plan->check_success (normalized_defaults.resize (axes.length)) || + !plan->check_success (normalized_maxs.resize (axes.length))) + return false; + } + + bool axis_not_pinned = false; + unsigned new_axis_idx = 0; + unsigned last_idx = 0; + for (const auto& _ : + hb_enumerate (axes)) + { + unsigned i = _.first; + const OT::AxisRecord &axis = _.second; + hb_tag_t axis_tag = axis.get_axis_tag (); + plan->axes_old_index_tag_map.set (i, axis_tag); + + if (!plan->user_axes_location.has (axis_tag) || + !plan->user_axes_location.get (axis_tag).is_point ()) + { + axis_not_pinned = true; + plan->axes_index_map.set (i, new_axis_idx); + plan->axis_tags.push (axis_tag); + new_axis_idx++; + } + + Triple *axis_range; + if (plan->user_axes_location.has (axis_tag, &axis_range)) + { + plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ()); + + float normalized_min = axis.normalize_axis_value (axis_range->minimum); + float normalized_default = axis.normalize_axis_value (axis_range->middle); + float normalized_max = axis.normalize_axis_value (axis_range->maximum); + + // TODO(behdad): Spec says axis normalization should be done in 16.16; + // We used to do it in 2.14, but that's not correct. I fixed this in + // the fvar/avar code, but keeping 2.14 here for now to keep tests + // happy. We might need to adjust fonttools as well. + // I'm only fairly confident in the above statement. Anyway, + // we should look deeper into this, and also update fonttools if + // needed. + + // Round to 2.14 + normalized_min = roundf (normalized_min * 16384.f) / 16384.f; + normalized_default = roundf (normalized_default * 16384.f) / 16384.f; + normalized_max = roundf (normalized_max * 16384.f) / 16384.f; + + if (has_avar) + { + normalized_mins[i] = normalized_min; + normalized_defaults[i] = normalized_default; + normalized_maxs[i] = normalized_max; + last_idx = i; + } + else + { + plan->axes_location.set (axis_tag, Triple ((double) normalized_min, + (double) normalized_default, + (double) normalized_max)); + if (normalized_default == -0.f) + normalized_default = 0.f; // Normalize -0 to 0 + if (normalized_default != 0.f) + plan->pinned_at_default = false; + + plan->normalized_coords[i] = roundf (normalized_default * 16384.f); + } + } + } + plan->all_axes_pinned = !axis_not_pinned; + + // TODO: use avar map_coords_16_16() when normalization is changed to 16.16 + // in fonttools + if (has_avar) + { + const OT::avar* avar_table = face->table.avar; + if (avar_table->has_v2_data () && !plan->all_axes_pinned) + { + DEBUG_MSG (SUBSET, nullptr, "Partial-instancing avar2 table is not supported."); + return false; + } + + unsigned coords_len = last_idx + 1; + if (!plan->check_success (avar_table->map_coords_2_14 (normalized_mins.arrayZ, coords_len)) || + !plan->check_success (avar_table->map_coords_2_14 (normalized_defaults.arrayZ, coords_len)) || + !plan->check_success (avar_table->map_coords_2_14 (normalized_maxs.arrayZ, coords_len))) + return false; + + for (const auto& _ : + hb_enumerate (axes)) + { + unsigned i = _.first; + hb_tag_t axis_tag = _.second.get_axis_tag (); + if (plan->user_axes_location.has (axis_tag)) + { + plan->axes_location.set (axis_tag, Triple ((double) normalized_mins[i], + (double) normalized_defaults[i], + (double) normalized_maxs[i])); + float normalized_default = normalized_defaults[i]; + if (normalized_default == -0.f) + normalized_default = 0.f; // Normalize -0 to 0 + if (normalized_default != 0.f) + plan->pinned_at_default = false; + + plan->normalized_coords[i] = roundf (normalized_default * 16384.f); + } + } + } + return true; +} + +void +update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) +{ + if (!plan->normalized_coords) return; + OT::cff2::accelerator_t cff2 (plan->source); + if (!cff2.is_valid ()) return; + + hb_font_t *font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font != nullptr))) + { + hb_font_destroy (font); + return; + } + + hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; + OT::hmtx_accelerator_t _hmtx (plan->source); + OT::hb_scalar_cache_t *hvar_store_cache = nullptr; + if (_hmtx.has_data () && _hmtx.var_table.get_length ()) + hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); + + OT::vmtx_accelerator_t _vmtx (plan->source); + OT::hb_scalar_cache_t *vvar_store_cache = nullptr; + if (_vmtx.has_data () && _vmtx.var_table.get_length ()) + vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); + + for (auto p : *plan->glyph_map) + { + hb_codepoint_t old_gid = p.first; + hb_codepoint_t new_gid = p.second; + if (!cff2.get_extents (font, old_gid, &extents)) continue; + bool has_bounds_info = true; + if (extents.x_bearing == 0 && extents.width == 0 && + extents.height == 0 && extents.y_bearing == 0) + has_bounds_info = false; + + if (has_bounds_info) + { + plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing); + plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width); + plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing); + plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height); + } + + if (_hmtx.has_data ()) + { + int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid); + if (_hmtx.var_table.get_length ()) + hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, + hvar_store_cache)); + int lsb = extents.x_bearing; + if (!has_bounds_info) + { + _hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); + } + plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); + plan->bounds_width_vec[new_gid] = extents.width; + } + + if (_vmtx.has_data ()) + { + int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid); + if (_vmtx.var_table.get_length ()) + vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, + vvar_store_cache)); + hb_position_t vorg_x = 0; + hb_position_t vorg_y = 0; + int tsb = 0; + if (has_bounds_info && + hb_font_get_glyph_v_origin (font, old_gid, &vorg_x, &vorg_y)) + { + tsb = vorg_y - extents.y_bearing; + } else { + _vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb); + } + + plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); + plan->bounds_height_vec[new_gid] = extents.height; + } + } + hb_font_destroy (font); + if (hvar_store_cache) + _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache); + if (vvar_store_cache) + _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); +} + +bool +get_instance_glyphs_contour_points (hb_subset_plan_t *plan) +{ + /* contour_points vector only needed for updating gvar table (infer delta and + * iup delta optimization) during partial instancing */ + if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) + return true; + + OT::glyf_accelerator_t glyf (plan->source); + + for (auto &_ : plan->new_to_old_gid_list) + { + hb_codepoint_t new_gid = _.first; + contour_point_vector_t all_points; + if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + continue; + } + + hb_codepoint_t old_gid = _.second; + auto glyph = glyf.glyph_for_gid (old_gid); + if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) + return false; + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + + /* composite new gids are only needed by iup delta optimization */ + if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) + plan->composite_new_gids.add (new_gid); + } + return true; +} + +template +void +remap_colrv1_delta_set_index_indices (const DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */) +{ + if (!index_map.get_map_count ()) + return; + + hb_hashmap_t> delta_set_idx_delta_map; + unsigned new_delta_set_idx = 0; + for (unsigned delta_set_idx : delta_set_idxes) + { + unsigned var_idx = index_map.map (delta_set_idx); + unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + int delta = 0; + + if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + { + hb_pair_t *new_varidx_delta; + if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; + + new_varidx = hb_first (*new_varidx_delta); + delta = hb_second (*new_varidx_delta); + } + + new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); + delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); + new_delta_set_idx++; + } + variation_idx_delta_map = std::move (delta_set_idx_delta_map); +} + +template void +remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */); + + #endif diff --git a/thirdparty/harfbuzz/upstream/hb-subset-plan.cc b/thirdparty/harfbuzz/upstream/hb-subset-plan.cc index 59020dbe8..767c1bf2d 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-plan.cc @@ -29,27 +29,21 @@ #include "hb-map.hh" #include "hb-multimap.hh" #include "hb-set.hh" +#include "hb-subset.h" +#include "hb-unicode.h" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-gdef-table.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-layout-gsub-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "OT/Color/COLR/COLR.hh" #include "OT/Color/COLR/colrv1-closure.hh" #include "OT/Color/CPAL/CPAL.hh" #include "hb-ot-var-fvar-table.hh" -#include "hb-ot-var-avar-table.hh" #include "hb-ot-stat-table.hh" #include "hb-ot-math-table.hh" -using OT::Layout::GSUB; -using OT::Layout::GPOS; - - hb_subset_accelerator_t::~hb_subset_accelerator_t () { if (cmap_cache && destroy_cmap_cache) @@ -63,7 +57,6 @@ hb_subset_accelerator_t::~hb_subset_accelerator_t () } -typedef hb_hashmap_t> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline bool _add_cff_seac_components (const OT::cff1::accelerator_subset_t &cff, @@ -98,414 +91,14 @@ _remap_palette_indexes (const hb_set_t *palette_indexes, } } -static void -_remap_indexes (const hb_set_t *indexes, - hb_map_t *mapping /* OUT */) +void +remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */) { for (auto _ : + hb_enumerate (indexes->iter ())) mapping->set (_.second, _.first); - -} - -#ifndef HB_NO_SUBSET_LAYOUT - -/* - * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates. - * Returns true if anything was removed (not including duplicates). - */ -static bool _filter_tag_list(hb_vector_t* tags, /* IN/OUT */ - const hb_set_t* filter) -{ - hb_vector_t out; - out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator. - - bool removed = false; - hb_set_t visited; - - for (hb_tag_t tag : *tags) - { - if (!tag) continue; - if (visited.has (tag)) continue; - - if (!filter->has (tag)) - { - removed = true; - continue; - } - - visited.add (tag); - out.push (tag); - } - - // The collect function needs a null element to signal end of the array. - out.push (HB_TAG_NONE); - - hb_swap (out, *tags); - return removed; -} - -template -static void _collect_layout_indices (hb_subset_plan_t *plan, - const T& table, - hb_set_t *lookup_indices, /* OUT */ - hb_set_t *feature_indices, /* OUT */ - hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ - hb_hashmap_t *feature_substitutes_map, /* OUT */ - hb_set_t& catch_all_record_feature_idxes, /* OUT */ - hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) -{ - unsigned num_features = table.get_feature_count (); - hb_vector_t features; - if (!plan->check_success (features.resize (num_features))) return; - table.get_feature_tags (0, &num_features, features.arrayZ); - bool retain_all_features = !_filter_tag_list (&features, &plan->layout_features); - - unsigned num_scripts = table.get_script_count (); - hb_vector_t scripts; - if (!plan->check_success (scripts.resize (num_scripts))) return; - table.get_script_tags (0, &num_scripts, scripts.arrayZ); - bool retain_all_scripts = !_filter_tag_list (&scripts, &plan->layout_scripts); - - if (!plan->check_success (!features.in_error ()) || !features - || !plan->check_success (!scripts.in_error ()) || !scripts) - return; - - hb_ot_layout_collect_features (plan->source, - T::tableTag, - retain_all_scripts ? nullptr : scripts.arrayZ, - nullptr, - retain_all_features ? nullptr : features.arrayZ, - feature_indices); - -#ifndef HB_NO_VAR - // collect feature substitutes with variations - if (!plan->user_axes_location.is_empty ()) - { - hb_hashmap_t, unsigned> conditionset_map; - OT::hb_collect_feature_substitutes_with_var_context_t c = - { - &plan->axes_old_index_tag_map, - &plan->axes_location, - feature_record_cond_idx_map, - feature_substitutes_map, - catch_all_record_feature_idxes, - feature_indices, - false, - false, - false, - 0, - &conditionset_map - }; - table.collect_feature_substitutes_with_variations (&c); - } -#endif - - for (unsigned feature_index : *feature_indices) - { - const OT::Feature* f = &(table.get_feature (feature_index)); - const OT::Feature **p = nullptr; - if (feature_substitutes_map->has (feature_index, &p)) - f = *p; - - f->add_lookup_indexes_to (lookup_indices); - } - -#ifndef HB_NO_VAR - if (catch_all_record_feature_idxes) - { - for (unsigned feature_index : catch_all_record_feature_idxes) - { - const OT::Feature& f = table.get_feature (feature_index); - f.add_lookup_indexes_to (lookup_indices); - const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); - catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); - } - } - - // If all axes are pinned then all feature variations will be dropped so there's no need - // to collect lookups from them. - if (!plan->all_axes_pinned) - table.feature_variation_collect_lookups (feature_indices, - plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, - lookup_indices); -#endif -} - - -static inline void -_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, - const hb_map_t *lookup_indices, - const hb_set_t *feature_indices, - const hb_hashmap_t *feature_substitutes_map, - hb_map_t *duplicate_feature_map /* OUT */) -{ - if (feature_indices->is_empty ()) return; - hb_hashmap_t> unique_features; - //find out duplicate features after subset - for (unsigned i : feature_indices->iter ()) - { - hb_tag_t t = g.get_feature_tag (i); - if (t == HB_MAP_VALUE_INVALID) continue; - if (!unique_features.has (t)) - { - if (unlikely (!unique_features.set (t, hb::unique_ptr {hb_set_create ()}))) - return; - if (unique_features.has (t)) - unique_features.get (t)->add (i); - duplicate_feature_map->set (i, i); - continue; - } - - bool found = false; - - hb_set_t* same_tag_features = unique_features.get (t); - for (unsigned other_f_index : same_tag_features->iter ()) - { - const OT::Feature* f = &(g.get_feature (i)); - const OT::Feature **p = nullptr; - if (feature_substitutes_map->has (i, &p)) - f = *p; - - const OT::Feature* other_f = &(g.get_feature (other_f_index)); - if (feature_substitutes_map->has (other_f_index, &p)) - other_f = *p; - - auto f_iter = - + hb_iter (f->lookupIndex) - | hb_filter (lookup_indices) - ; - - auto other_f_iter = - + hb_iter (other_f->lookupIndex) - | hb_filter (lookup_indices) - ; - - bool is_equal = true; - for (; f_iter && other_f_iter; f_iter++, other_f_iter++) - { - unsigned a = *f_iter; - unsigned b = *other_f_iter; - if (a != b) { is_equal = false; break; } - } - - if (is_equal == false || f_iter || other_f_iter) continue; - - found = true; - duplicate_feature_map->set (i, other_f_index); - break; - } - - if (found == false) - { - same_tag_features->add (i); - duplicate_feature_map->set (i, i); - } - } -} - -template -static inline void -_closure_glyphs_lookups_features (hb_subset_plan_t *plan, - hb_set_t *gids_to_retain, - hb_map_t *lookups, - hb_map_t *features, - script_langsys_map *langsys_map, - hb_hashmap_t> *feature_record_cond_idx_map, - hb_hashmap_t *feature_substitutes_map, - hb_set_t &catch_all_record_feature_idxes, - hb_hashmap_t>& catch_all_record_idx_feature_map) -{ - hb_blob_ptr_t table = plan->source_table (); - hb_tag_t table_tag = table->tableTag; - hb_set_t lookup_indices, feature_indices; - _collect_layout_indices (plan, - *table, - &lookup_indices, - &feature_indices, - feature_record_cond_idx_map, - feature_substitutes_map, - catch_all_record_feature_idxes, - catch_all_record_idx_feature_map); - - if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) - hb_ot_layout_lookups_substitute_closure (plan->source, - &lookup_indices, - gids_to_retain); - table->closure_lookups (plan->source, - gids_to_retain, - &lookup_indices); - _remap_indexes (&lookup_indices, lookups); - - // prune features - table->prune_features (lookups, - plan->user_axes_location.is_empty () ? nullptr : feature_record_cond_idx_map, - feature_substitutes_map, - &feature_indices); - hb_map_t duplicate_feature_map; - _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map); - - feature_indices.clear (); - table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices); - _remap_indexes (&feature_indices, features); - - table.destroy (); -} - -#endif - -#ifndef HB_NO_VAR -static inline void -_generate_varstore_inner_maps (const hb_set_t& varidx_set, - unsigned subtable_count, - hb_vector_t &inner_maps /* OUT */) -{ - if (varidx_set.is_empty () || subtable_count == 0) return; - - if (unlikely (!inner_maps.resize (subtable_count))) return; - for (unsigned idx : varidx_set) - { - uint16_t major = idx >> 16; - uint16_t minor = idx & 0xFFFF; - - if (major >= subtable_count) - continue; - inner_maps[major].add (minor); - } -} - -static inline hb_font_t* -_get_hb_font_with_variations (const hb_subset_plan_t *plan) -{ - hb_font_t *font = hb_font_create (plan->source); - - hb_vector_t vars; - if (!vars.alloc (plan->user_axes_location.get_population ())) { - hb_font_destroy (font); - return nullptr; - } - - for (auto _ : plan->user_axes_location) - { - hb_variation_t var; - var.tag = _.first; - var.value = _.second.middle; - vars.push (var); - } - -#ifndef HB_NO_VAR - hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); -#endif - return font; -} - -static inline void -_remap_variation_indices (const OT::ItemVariationStore &var_store, - const hb_set_t &variation_indices, - const hb_vector_t& normalized_coords, - bool calculate_delta, /* not pinned at default */ - bool no_variations, /* all axes pinned */ - hb_hashmap_t> &variation_idx_delta_map /* OUT */) -{ - if (&var_store == &Null (OT::ItemVariationStore)) return; - unsigned subtable_count = var_store.get_sub_table_count (); - float *store_cache = var_store.create_cache (); - - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (variation_indices.get_min ()) >> 16; - for (unsigned idx : variation_indices) - { - int delta = 0; - if (calculate_delta) - delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, - normalized_coords.length, store_cache)); - - if (no_variations) - { - variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - continue; - } - - uint16_t major = idx >> 16; - if (major >= subtable_count) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); - ++new_minor; - last_major = major; - } - var_store.destroy_cache (store_cache); -} - -static inline void -_collect_layout_variation_indices (hb_subset_plan_t* plan) -{ - hb_blob_ptr_t gdef = plan->source_table (); - hb_blob_ptr_t gpos = plan->source_table (); - - if (!gdef->has_data () || !gdef->has_var_store ()) - { - gdef.destroy (); - gpos.destroy (); - return; - } - - hb_set_t varidx_set; - OT::hb_collect_variation_indices_context_t c (&varidx_set, - &plan->_glyphset_gsub, - &plan->gpos_lookups); - gdef->collect_variation_indices (&c); - - if (hb_ot_layout_has_positioning (plan->source)) - gpos->collect_variation_indices (&c); - - _remap_variation_indices (gdef->get_var_store (), - varidx_set, plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - plan->layout_variation_idx_delta_map); - - unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); - _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); - - gdef.destroy (); - gpos.destroy (); -} - -#ifndef HB_NO_BASE -static inline void -_collect_base_variation_indices (hb_subset_plan_t* plan) -{ - hb_blob_ptr_t base = plan->source_table (); - if (!base->has_var_store ()) - { - base.destroy (); - return; - } - - hb_set_t varidx_set; - base->collect_variation_indices (plan, varidx_set); - const OT::ItemVariationStore &var_store = base->get_var_store (); - unsigned subtable_count = var_store.get_sub_table_count (); - - - _remap_variation_indices (var_store, varidx_set, - plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - plan->base_variation_idx_map); - _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); - - base.destroy (); } -#endif -#endif - static inline void _cmap_closure (hb_face_t *face, const hb_set_t *unicodes, @@ -515,41 +108,6 @@ _cmap_closure (hb_face_t *face, cmap.table->closure_glyphs (unicodes, glyphset); } -#ifndef HB_NO_VAR -static void -_remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, - const hb_set_t &delta_set_idxes, - hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ - hb_map_t &new_deltaset_idx_varidx_map /* OUT */) -{ - if (!index_map.get_map_count ()) - return; - - hb_hashmap_t> delta_set_idx_delta_map; - unsigned new_delta_set_idx = 0; - for (unsigned delta_set_idx : delta_set_idxes) - { - unsigned var_idx = index_map.map (delta_set_idx); - unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - int delta = 0; - - if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) - { - hb_pair_t *new_varidx_delta; - if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; - - new_varidx = hb_first (*new_varidx_delta); - delta = hb_second (*new_varidx_delta); - } - - new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); - delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); - new_delta_set_idx++; - } - variation_idx_delta_map = std::move (delta_set_idx_delta_map); -} -#endif - static void _colr_closure (hb_subset_plan_t* plan, hb_set_t *glyphs_colred) { @@ -569,7 +127,7 @@ static void _colr_closure (hb_subset_plan_t* plan, colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices, &delta_set_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); - _remap_indexes (&layer_indices, &plan->colrv1_layers); + remap_indexes (&layer_indices, &plan->colrv1_layers); _remap_palette_indexes (&palette_indices, &plan->colr_palettes); #ifndef HB_NO_VAR @@ -578,7 +136,7 @@ static void _colr_closure (hb_subset_plan_t* plan, const OT::ItemVariationStore &var_store = colr.get_var_store (); // generated inner_maps is used by ItemVariationStore serialize(), which is subset only unsigned subtable_count = var_store.get_sub_table_count (); - _generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); + generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); /* colr variation indices mapping during planning phase: * generate colrv1_variation_idx_delta_map. When delta set index map is not @@ -590,7 +148,7 @@ static void _colr_closure (hb_subset_plan_t* plan, * instancing. */ if (!plan->all_axes_pinned) { - _remap_variation_indices (var_store, + remap_variation_indices (var_store, variation_indices, plan->normalized_coords, false, /* no need to calculate delta for COLR during planning */ @@ -598,7 +156,7 @@ static void _colr_closure (hb_subset_plan_t* plan, plan->colrv1_variation_idx_delta_map); if (colr.has_delta_set_index_map ()) - _remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), + remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), delta_set_indices, plan->colrv1_variation_idx_delta_map, plan->colrv1_new_deltaset_idx_varidx_map); @@ -616,25 +174,6 @@ _math_closure (hb_subset_plan_t *plan, math.destroy (); } -static inline void -_remap_used_mark_sets (hb_subset_plan_t *plan, - hb_map_t& used_mark_sets_map) -{ - hb_blob_ptr_t gdef = plan->source_table (); - - if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) - { - gdef.destroy (); - return; - } - - hb_set_t used_mark_sets; - gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); - gdef.destroy (); - - _remap_indexes (&used_mark_sets, &used_mark_sets_map); -} - static inline void _remove_invalid_gids (hb_set_t *glyphs, unsigned int num_glyphs) @@ -672,14 +211,46 @@ _fill_unicode_and_glyph_map(hb_subset_plan_t *plan, _fill_unicode_and_glyph_map(plan, unicode_iterator, unicode_to_gid_for_iterator, unicode_to_gid_for_iterator); } +/* + * Finds additional unicode codepoints which are reachable from the input unicode set. + * Currently this adds in mirrored variants (needed for bidi) of any input unicodes. + */ +static hb_set_t +_unicode_closure (const hb_set_t* unicodes, bool bidi_closure) { + // TODO: we may want to also consider pulling in reachable unicode composition and decompositions. + // see: https://github.com/harfbuzz/harfbuzz/issues/2283 + hb_set_t out = *unicodes; + if (!bidi_closure) return out; + + if (out.is_inverted()) { + // don't closure inverted sets, they are asking to specifically exclude certain codepoints. + // otherwise everything is already included. + return out; + } + + auto unicode_funcs = hb_unicode_funcs_get_default (); + for (hb_codepoint_t cp : *unicodes) { + hb_codepoint_t mirror = hb_unicode_mirroring(unicode_funcs, cp); + if (unlikely (mirror != cp)) { + out.add(mirror); + } + } + + return out; +} + static void -_populate_unicodes_to_retain (const hb_set_t *unicodes, +_populate_unicodes_to_retain (const hb_set_t *unicodes_in, const hb_set_t *glyphs, hb_subset_plan_t *plan) { + hb_set_t unicodes = _unicode_closure(unicodes_in, + !(plan->flags & HB_SUBSET_FLAGS_NO_BIDI_CLOSURE)); + OT::cmap::accelerator_t cmap (plan->source); unsigned size_threshold = plan->source->get_num_glyphs (); - if (glyphs->is_empty () && unicodes->get_population () < size_threshold) + + if (glyphs->is_empty () && unicodes.get_population () < size_threshold) { const hb_map_t* unicode_to_gid = nullptr; @@ -689,9 +260,9 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // This is approach to collection is faster, but can only be used if glyphs // are not being explicitly added to the subset and the input unicodes set is // not excessively large (eg. an inverted set). - plan->unicode_to_new_gid_list.alloc (unicodes->get_population ()); + plan->unicode_to_new_gid_list.alloc (unicodes.get_population ()); if (!unicode_to_gid) { - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { hb_codepoint_t gid; if (!cmap.get_nominal_glyph (cp, &gid)) { return HB_MAP_VALUE_INVALID; @@ -703,7 +274,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // the map. This code is mostly duplicated from above to avoid doing // conditionals on the presence of the unicode_to_gid map each // iteration. - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { return unicode_to_gid->get (cp); }); } @@ -720,7 +291,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, if (!plan->accelerator) { cmap.collect_mapping (&cmap_unicodes_storage, &unicode_glyphid_map_storage); - plan->unicode_to_new_gid_list.alloc (hb_min(unicodes->get_population () + plan->unicode_to_new_gid_list.alloc (hb_min(unicodes.get_population () + glyphs->get_population (), cmap_unicodes->get_population ())); } else { @@ -729,10 +300,10 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, } if (plan->accelerator && - unicodes->get_population () < cmap_unicodes->get_population () && + unicodes.get_population () < cmap_unicodes->get_population () && glyphs->get_population () < cmap_unicodes->get_population ()) { - plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ()); + plan->codepoint_to_glyph->alloc (unicodes.get_population () + glyphs->get_population ()); auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; @@ -747,7 +318,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, }); } - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { /* Don't double-add entry. */ if (plan->codepoint_to_glyph->has (cp)) return HB_MAP_VALUE_INVALID; @@ -768,7 +339,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, { _fill_unicode_and_glyph_map(plan, hb_range(first, last + 1), [&] (hb_codepoint_t cp) { hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) + if (!unicodes.has (cp) && !glyphs->has (gid)) return HB_MAP_VALUE_INVALID; return gid; }, @@ -797,6 +368,21 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, plan->unicodes.add_sorted_array (&arr.arrayZ->first, arr.length, sizeof (*arr.arrayZ)); plan->_glyphset_gsub.add_array (&arr.arrayZ->second, arr.length, sizeof (*arr.arrayZ)); } + + // Variation selectors don't have glyphs associated with them in the cmap so they will have been filtered out above + // but should still be retained. Add them back here. + + // However, the min and max codepoints for OS/2 should be calculated without considering variation selectors, + // so record those first. + plan->os2_info.min_cmap_codepoint = plan->unicodes.get_min(); + plan->os2_info.max_cmap_codepoint = plan->unicodes.get_max(); + + hb_set_t variation_selectors_to_retain; + cmap.collect_variation_selectors(&variation_selectors_to_retain); + + variation_selectors_to_retain.iter() + | hb_filter(unicodes) + | hb_sink(&plan->unicodes) + ; } static unsigned @@ -832,7 +418,8 @@ _nameid_closure (hb_subset_plan_t* plan, hb_set_t* drop_tables) { #ifndef HB_NO_STYLE - plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); + if (!drop_tables->has (HB_OT_TAG_STAT)) + plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids); #endif #ifndef HB_NO_VAR if (!plan->all_axes_pinned) @@ -844,18 +431,7 @@ _nameid_closure (hb_subset_plan_t* plan, #endif #ifndef HB_NO_SUBSET_LAYOUT - if (!drop_tables->has (HB_OT_TAG_GPOS)) - { - hb_blob_ptr_t gpos = plan->source_table (); - gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); - gpos.destroy (); - } - if (!drop_tables->has (HB_OT_TAG_GSUB)) - { - hb_blob_ptr_t gsub = plan->source_table (); - gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); - gsub.destroy (); - } + layout_nameid_closure(plan, drop_tables); #endif } @@ -877,31 +453,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _cmap_closure (plan->source, &plan->unicodes, &plan->_glyphset_gsub); #ifndef HB_NO_SUBSET_LAYOUT - if (!drop_tables->has (HB_OT_TAG_GSUB)) - // closure all glyphs/lookups/features needed for GSUB substitutions. - _closure_glyphs_lookups_features ( - plan, - &plan->_glyphset_gsub, - &plan->gsub_lookups, - &plan->gsub_features, - &plan->gsub_langsys, - &plan->gsub_feature_record_cond_idx_map, - &plan->gsub_feature_substitutes_map, - plan->gsub_old_features, - plan->gsub_old_feature_idx_tag_map); - - if (!drop_tables->has (HB_OT_TAG_GPOS)) - _closure_glyphs_lookups_features ( - plan, - &plan->_glyphset_gsub, - &plan->gpos_lookups, - &plan->gpos_features, - &plan->gpos_langsys, - &plan->gpos_feature_record_cond_idx_map, - &plan->gpos_feature_substitutes_map, - plan->gpos_old_features, - plan->gpos_old_feature_idx_tag_map); + layout_populate_gids_to_retain(plan, drop_tables); #endif + _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); plan->_glyphset_mathed = plan->_glyphset_gsub; @@ -946,8 +500,10 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ()); #ifndef HB_NO_VAR +#ifndef HB_NO_SUBSET_LAYOUT if (!drop_tables->has (HB_OT_TAG_GDEF)) - _collect_layout_variation_indices (plan); + collect_layout_variation_indices (plan); +#endif #endif } @@ -1061,193 +617,6 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, return true; } -#ifndef HB_NO_VAR -static void -_normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) -{ - if (plan->user_axes_location.is_empty ()) - return; - - hb_array_t axes = face->table.fvar->get_axes (); - plan->normalized_coords.resize (axes.length); - - bool has_avar = face->table.avar->has_data (); - const OT::SegmentMaps *seg_maps = nullptr; - unsigned avar_axis_count = 0; - if (has_avar) - { - seg_maps = face->table.avar->get_segment_maps (); - avar_axis_count = face->table.avar->get_axis_count(); - } - - bool axis_not_pinned = false; - unsigned old_axis_idx = 0, new_axis_idx = 0; - for (const auto& axis : axes) - { - hb_tag_t axis_tag = axis.get_axis_tag (); - plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag); - - if (!plan->user_axes_location.has (axis_tag) || - !plan->user_axes_location.get (axis_tag).is_point ()) - { - axis_not_pinned = true; - plan->axes_index_map.set (old_axis_idx, new_axis_idx); - plan->axis_tags.push (axis_tag); - new_axis_idx++; - } - - Triple *axis_range; - if (plan->user_axes_location.has (axis_tag, &axis_range)) - { - plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ()); - - int normalized_min = axis.normalize_axis_value (axis_range->minimum); - int normalized_default = axis.normalize_axis_value (axis_range->middle); - int normalized_max = axis.normalize_axis_value (axis_range->maximum); - - if (has_avar && old_axis_idx < avar_axis_count) - { - normalized_min = seg_maps->map (normalized_min); - normalized_default = seg_maps->map (normalized_default); - normalized_max = seg_maps->map (normalized_max); - } - plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.0), - static_cast (normalized_default / 16384.0), - static_cast (normalized_max / 16384.0))); - - if (normalized_default != 0) - plan->pinned_at_default = false; - - plan->normalized_coords[old_axis_idx] = normalized_default; - } - - old_axis_idx++; - - if (has_avar && old_axis_idx < avar_axis_count) - seg_maps = &StructAfter (*seg_maps); - } - plan->all_axes_pinned = !axis_not_pinned; -} - -static void -_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) -{ - if (!plan->normalized_coords) return; - OT::cff2::accelerator_t cff2 (plan->source); - if (!cff2.is_valid ()) return; - - hb_font_t *font = _get_hb_font_with_variations (plan); - if (unlikely (!plan->check_success (font != nullptr))) - { - hb_font_destroy (font); - return; - } - - hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; - OT::hmtx_accelerator_t _hmtx (plan->source); - float *hvar_store_cache = nullptr; - if (_hmtx.has_data () && _hmtx.var_table.get_length ()) - hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); - - OT::vmtx_accelerator_t _vmtx (plan->source); - float *vvar_store_cache = nullptr; - if (_vmtx.has_data () && _vmtx.var_table.get_length ()) - vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); - - for (auto p : *plan->glyph_map) - { - hb_codepoint_t old_gid = p.first; - hb_codepoint_t new_gid = p.second; - if (!cff2.get_extents (font, old_gid, &extents)) continue; - bool has_bounds_info = true; - if (extents.x_bearing == 0 && extents.width == 0 && - extents.height == 0 && extents.y_bearing == 0) - has_bounds_info = false; - - if (has_bounds_info) - { - plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing); - plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width); - plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing); - plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height); - } - - if (_hmtx.has_data ()) - { - int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid); - if (_hmtx.var_table.get_length ()) - hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, - hvar_store_cache)); - int lsb = extents.x_bearing; - if (!has_bounds_info) - { - if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - continue; - } - plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); - plan->bounds_width_vec[new_gid] = extents.width; - } - - if (_vmtx.has_data ()) - { - int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid); - if (_vmtx.var_table.get_length ()) - vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, - vvar_store_cache)); - - int tsb = extents.y_bearing; - if (!has_bounds_info) - { - if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb)) - continue; - } - plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); - plan->bounds_height_vec[new_gid] = extents.height; - } - } - hb_font_destroy (font); - if (hvar_store_cache) - _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache); - if (vvar_store_cache) - _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); -} - -static bool -_get_instance_glyphs_contour_points (hb_subset_plan_t *plan) -{ - /* contour_points vector only needed for updating gvar table (infer delta and - * iup delta optimization) during partial instancing */ - if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) - return true; - - OT::glyf_accelerator_t glyf (plan->source); - - for (auto &_ : plan->new_to_old_gid_list) - { - hb_codepoint_t new_gid = _.first; - contour_point_vector_t all_points; - if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) - { - if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) - return false; - continue; - } - - hb_codepoint_t old_gid = _.second; - auto glyph = glyf.glyph_for_gid (old_gid); - if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) - return false; - if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) - return false; - - /* composite new gids are only needed by iup delta optimization */ - if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) - plan->composite_new_gids.add (new_gid); - } - return true; -} -#endif - hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, const hb_subset_input_t *input) { @@ -1308,7 +677,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - _normalize_axes_location (face, this); + if (!check_success (normalize_axes_location (face, this))) + return; #endif _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this); @@ -1329,6 +699,15 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; } +#ifdef HB_EXPERIMENTAL_API + if ((input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) && + (input->flags & HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS)) { + // We've been requested to maintain the num glyphs count from the + // input face. + _num_output_glyphs = source->get_num_glyphs (); + } +#endif + _create_glyph_map_gsub ( &_glyphset_gsub, glyph_map, @@ -1342,20 +721,22 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second); } - bounds_width_vec.resize (_num_output_glyphs, false); + bounds_width_vec.resize_dirty (_num_output_glyphs); for (auto &v : bounds_width_vec) v = 0xFFFFFFFF; - bounds_height_vec.resize (_num_output_glyphs, false); + bounds_height_vec.resize_dirty (_num_output_glyphs); for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; +#ifndef HB_NO_SUBSET_LAYOUT if (!drop_tables.has (HB_OT_TAG_GDEF)) - _remap_used_mark_sets (this, used_mark_sets_map); + remap_used_mark_sets (this, used_mark_sets_map); +#endif #ifndef HB_NO_VAR #ifndef HB_NO_BASE if (!drop_tables.has (HB_OT_TAG_BASE)) - _collect_base_variation_indices (this); + collect_base_variation_indices (this); #endif #endif @@ -1363,8 +744,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - _update_instance_metrics_map_from_cff2 (this); - if (!check_success (_get_instance_glyphs_contour_points (this))) + update_instance_metrics_map_from_cff2 (this); + if (!check_success (get_instance_glyphs_contour_points (this))) return; #endif diff --git a/thirdparty/harfbuzz/upstream/hb-subset-plan.hh b/thirdparty/harfbuzz/upstream/hb-subset-plan.hh index 19a9fa691..2a935b8f1 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/upstream/hb-subset-plan.hh @@ -41,6 +41,13 @@ namespace OT { struct Feature; } +struct os2_info_t { + hb_codepoint_t min_cmap_codepoint; + hb_codepoint_t max_cmap_codepoint; +}; + +typedef struct os2_info_t os2_info_t; + struct head_maxp_info_t { head_maxp_info_t () @@ -88,7 +95,6 @@ struct contour_point_t HB_ALWAYS_INLINE void translate (const contour_point_t &p) { x += p.x; y += p.y; } - float x; float y; uint8_t flag; @@ -97,19 +103,9 @@ struct contour_point_t struct contour_point_vector_t : hb_vector_t { - void extend (const hb_array_t &a) - { - unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length, false))) - return; - auto arrayZ = this->arrayZ + old_len; - unsigned count = a.length; - hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); - } - - bool add_deltas (const hb_vector_t deltas_x, - const hb_vector_t deltas_y, - const hb_vector_t indices) + bool add_deltas (hb_array_t deltas_x, + hb_array_t deltas_y, + hb_array_t indices) { if (indices.length != deltas_x.length || indices.length != deltas_y.length) @@ -180,6 +176,8 @@ struct hb_subset_plan_t //recalculated head/maxp table info after instancing mutable head_maxp_info_t head_maxp_info; + os2_info_t os2_info; + const hb_subset_accelerator_t* accelerator; hb_subset_accelerator_t* inprogress_accelerator; @@ -298,5 +296,76 @@ struct hb_subset_plan_t } }; +// hb-subset-plan implementation is split into multiple files to keep +// compile times more reasonable: +// - hb-subset-plan.cc +// - hb-subset-plan-layout.cc +// - hb-subset-plan-var.cc +// +// The functions below are those needed to connect the split files +// above together. +HB_INTERNAL void +remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */); + + +#ifndef HB_NO_VAR +template +HB_INTERNAL void +remap_variation_indices (const ItemVarStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */); + + +template +HB_INTERNAL void +remap_colrv1_delta_set_index_indices (const DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */); + + +HB_INTERNAL void +generate_varstore_inner_maps (const hb_set_t& varidx_set, + unsigned subtable_count, + hb_vector_t &inner_maps /* OUT */); + +HB_INTERNAL bool +normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan); + +HB_INTERNAL void +update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan); + +HB_INTERNAL bool +get_instance_glyphs_contour_points (hb_subset_plan_t *plan); + +#ifndef HB_NO_BASE +HB_INTERNAL void +collect_base_variation_indices (hb_subset_plan_t* plan); +#endif +#endif + +#ifndef HB_NO_SUBSET_LAYOUT +typedef hb_hashmap_t> script_langsys_map; + +HB_INTERNAL void +remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map); + +HB_INTERNAL void +layout_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables); + +HB_INTERNAL void +layout_populate_gids_to_retain (hb_subset_plan_t* plan, + hb_set_t* drop_tables); + +HB_INTERNAL void +collect_layout_variation_indices (hb_subset_plan_t* plan); +#endif + #endif /* HB_SUBSET_PLAN_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-repacker.h b/thirdparty/harfbuzz/upstream/hb-subset-repacker.h deleted file mode 100644 index 245cf6076..000000000 --- a/thirdparty/harfbuzz/upstream/hb-subset-repacker.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright © 2022 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ - -#ifndef HB_SUBSET_REPACKER_H -#define HB_SUBSET_REPACKER_H - -#include "hb.h" - -HB_BEGIN_DECLS - -#ifdef HB_EXPERIMENTAL_API -/* - * struct hb_link_t - * width: offsetSize in bytes - * position: position of the offset field in bytes - * from beginning of subtable - * objidx: index of subtable - */ -struct hb_link_t -{ - unsigned width; - unsigned position; - unsigned objidx; -}; - -typedef struct hb_link_t hb_link_t; - -/* - * struct hb_object_t - * head: start of object data - * tail: end of object data - * num_real_links: num of offset field in the object - * real_links: pointer to array of offset info - * num_virtual_links: num of objects that must be packed - * after current object in the final serialized order - * virtual_links: array of virtual link info - */ -struct hb_object_t -{ - char *head; - char *tail; - unsigned num_real_links; - hb_link_t *real_links; - unsigned num_virtual_links; - hb_link_t *virtual_links; -}; - -typedef struct hb_object_t hb_object_t; - -HB_EXTERN hb_blob_t* -hb_subset_repack_or_fail (hb_tag_t table_tag, - hb_object_t* hb_objects, - unsigned num_hb_objs); - -#endif - -HB_END_DECLS - -#endif /* HB_SUBSET_REPACKER_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-repacker.cc b/thirdparty/harfbuzz/upstream/hb-subset-serialize.cc similarity index 68% rename from thirdparty/harfbuzz/upstream/hb-subset-repacker.cc rename to thirdparty/harfbuzz/upstream/hb-subset-serialize.cc index 6a29b35be..dc7613654 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset-repacker.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset-serialize.cc @@ -22,37 +22,36 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * */ -#include "hb-repacker.hh" -#ifdef HB_EXPERIMENTAL_API +#include "hb.hh" + +#include "hb-subset-serialize.h" +#include "hb-repacker.hh" /** - * hb_subset_repack_or_fail: + * hb_subset_serialize_or_fail: * @table_tag: tag of the table being packed, needed to allow table specific optimizations. - * @hb_objects: raw array of struct hb_object_t, which provides + * @hb_objects: raw array of struct hb_subset_serialize_object_t, which provides * object graph info - * @num_hb_objs: number of hb_object_t in the hb_objects array. + * @num_hb_objs: number of hb_subset_serialize_object_t in the hb_objects array. * - * Given the input object graph info, repack a table to eliminate - * offset overflows. A nullptr is returned if the repacking attempt fails. + * Given the input object graph info, repack a table to eliminate offset overflows and + * serialize it into a continuous array of bytes. A nullptr is returned if the serializing attempt fails. * Table specific optimizations (eg. extension promotion in GSUB/GPOS) may be performed. * Passing HB_TAG_NONE will disable table specific optimizations. * - * XSince: EXPERIMENTAL + * Since: 10.2.0 **/ -hb_blob_t* hb_subset_repack_or_fail (hb_tag_t table_tag, - hb_object_t* hb_objects, - unsigned num_hb_objs) +HB_EXTERN hb_blob_t * +hb_subset_serialize_or_fail (hb_tag_t table_tag, + hb_subset_serialize_object_t *hb_objects, + unsigned num_hb_objs) { - hb_vector_t packed; + hb_vector_t packed; packed.alloc (num_hb_objs + 1); packed.push (nullptr); for (unsigned i = 0 ; i < num_hb_objs ; i++) packed.push (&(hb_objects[i])); - return hb_resolve_overflows (packed, - table_tag, - 20, - true); + return hb_resolve_overflows (packed, table_tag, 20, true); } -#endif diff --git a/thirdparty/harfbuzz/upstream/hb-subset-serialize.h b/thirdparty/harfbuzz/upstream/hb-subset-serialize.h new file mode 100644 index 000000000..9035d4ced --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-serialize.h @@ -0,0 +1,83 @@ +/* + * Copyright © 2022 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + */ + +#ifndef HB_SUBSET_SERIALIZE_H +#define HB_SUBSET_SERIALIZE_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/** + * hb_subset_serialize_link_t: + * @width: offsetSize in bytes + * @position: position of the offset field in bytes from + * beginning of subtable + * @objidx: index of subtable + * + * Represents a link between two objects in the object graph + * to be serialized. + * + * Since: 10.2.0 + */ +typedef struct hb_subset_serialize_link_t { + unsigned int width; + unsigned int position; + unsigned int objidx; +} hb_subset_serialize_link_t; + +/** + * hb_subset_serialize_object_t: + * @head: start of object data + * @tail: end of object data + * @num_real_links: number of offset field in the object + * @real_links: array of offset info + * @num_virtual_links: number of objects that must be packed + * after current object in the final + * serialized order + * @virtual_links: array of virtual link info + * + * Represents an object in the object graph to be serialized. + * + * Since: 10.2.0 + */ +typedef struct hb_subset_serialize_object_t { + char *head; + char *tail; + unsigned int num_real_links; + hb_subset_serialize_link_t *real_links; + unsigned int num_virtual_links; + hb_subset_serialize_link_t *virtual_links; +} hb_subset_serialize_object_t; + +HB_EXTERN hb_blob_t * +hb_subset_serialize_or_fail (hb_tag_t table_tag, + hb_subset_serialize_object_t *hb_objects, + unsigned num_hb_objs); + + +HB_END_DECLS + +#endif /* HB_SUBSET_SERIALIZE_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset-table-cff.cc b/thirdparty/harfbuzz/upstream/hb-subset-table-cff.cc new file mode 100644 index 000000000..3984cfb86 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-table-cff.cc @@ -0,0 +1,143 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-cff1-table.hh" +#include "hb-ot-cff2-table.hh" +#include "hb-ot-vorg-table.hh" + + +#ifndef HB_NO_SUBSET_CFF +template<> +struct hb_subset_plan_t::source_table_loader +{ + auto operator () (hb_subset_plan_t *plan) + HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : + plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : + plan->cff1_accel) +}; +template<> +struct hb_subset_plan_t::source_table_loader +{ + auto operator () (hb_subset_plan_t *plan) + HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : + plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : + plan->cff2_accel) +}; +#endif + + +bool _hb_subset_table_cff (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_SUBSET_CFF + switch (tag) + { + case HB_TAG('C','F','F',' '): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','F','F','2'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('V','O','R','G'): *success = _hb_subset_table (plan, buf); return true; + } +#endif + return false; +} + + +#ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_CFF + +template +static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; + if (!bytes) { + return hb_blob_get_empty (); + } + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = (const char*) bytes.arrayZ - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); +} + +template +static hb_blob_t* get_charstrings_index(accel_t& accel) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + const char* charstrings_start = (const char*) accel.charStrings; + unsigned charstrings_length = accel.charStrings->get_size(); + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = charstrings_start - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); +} + +/** + * hb_subset_cff_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff1, glyph_index); +} + +/** + * hb_subset_cff_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF CharStrings INDEX from the CFF table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff1); +} + +/** + * hb_subset_cff2_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff2, glyph_index); +} + +/** + * hb_subset_cff2_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff2); +} +#endif +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-subset-table-color.cc b/thirdparty/harfbuzz/upstream/hb-subset-table-color.cc new file mode 100644 index 000000000..e44305e7d --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-table-color.cc @@ -0,0 +1,21 @@ +#include "hb-subset-table.hh" + +#include "OT/Color/sbix/sbix.hh" +#include "OT/Color/CPAL/CPAL.hh" +#include "OT/Color/COLR/COLR.hh" +#include "OT/Color/CBDT/CBDT.hh" + +bool _hb_subset_table_color (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_COLOR + switch (tag) + { + case HB_TAG('s','b','i','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','O','L','R'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','P','A','L'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','B','L','C'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('C','B','D','T'): *success = true; return true; /* skip CBDT, handled by CBLC */ + } +#endif + return false; +} diff --git a/thirdparty/harfbuzz/upstream/hb-subset-table-layout.cc b/thirdparty/harfbuzz/upstream/hb-subset-table-layout.cc new file mode 100644 index 000000000..765422e36 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-table-layout.cc @@ -0,0 +1,22 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout-gsub-table.hh" +#include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-layout-base-table.hh" +#include "hb-ot-math-table.hh" + +bool _hb_subset_table_layout (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_SUBSET_LAYOUT + switch (tag) + { + case HB_TAG('G','D','E','F'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('G','S','U','B'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('G','P','O','S'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('B','A','S','E'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('M','A','T','H'): *success = _hb_subset_table (plan, buf); return true; + } +#endif + return false; +} diff --git a/thirdparty/harfbuzz/upstream/hb-subset-table-other.cc b/thirdparty/harfbuzz/upstream/hb-subset-table-other.cc new file mode 100644 index 000000000..3b7ff4b32 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-table-other.cc @@ -0,0 +1,31 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" +#include "hb-ot-hdmx-table.hh" +#include "hb-ot-hhea-table.hh" +#include "hb-ot-hmtx-table.hh" +#include "hb-ot-maxp-table.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-name-table.hh" +#include "hb-ot-post-table.hh" + +bool _hb_subset_table_other (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ + switch (tag) + { + case HB_TAG('g','l','y','f'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('h','d','m','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('n','a','m','e'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('h','h','e','a'): *success = true; return true; /* skip hhea, handled by hmtx */ + case HB_TAG('h','m','t','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('v','h','e','a'): *success = true; return true; /* skip vhea, handled by vmtx */ + case HB_TAG('v','m','t','x'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('m','a','x','p'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('l','o','c','a'): *success = true; return true; /* skip loca, handled by glyf */ + case HB_TAG('c','m','a','p'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('O','S','/','2'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('p','o','s','t'): *success = _hb_subset_table (plan, buf); return true; + } + return false; +} diff --git a/thirdparty/harfbuzz/upstream/hb-subset-table-var.cc b/thirdparty/harfbuzz/upstream/hb-subset-table-var.cc new file mode 100644 index 000000000..b569b08a0 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-table-var.cc @@ -0,0 +1,45 @@ +#include "hb-subset-table.hh" + +#include "hb-ot-var-hvar-table.hh" +#include "hb-ot-var-gvar-table.hh" +#include "hb-ot-var-fvar-table.hh" +#include "hb-ot-var-avar-table.hh" +#include "hb-ot-var-cvar-table.hh" +#include "hb-ot-var-mvar-table.hh" + +bool _hb_subset_table_var (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success) +{ +#ifndef HB_NO_VAR + switch (tag) + { + case HB_TAG('H','V','A','R'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('V','V','A','R'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('g','v','a','r'): *success = _hb_subset_table (plan, buf); return true; + case HB_TAG('f','v','a','r'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + case HB_TAG('a','v','a','r'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + case HB_TAG('c','v','a','r'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + case HB_TAG('M','V','A','R'): + if (plan->user_axes_location.is_empty ()) + *success = _hb_subset_table_passthrough (plan, tag); + else + *success = _hb_subset_table (plan, buf); + return true; + } +#endif + return false; +} diff --git a/thirdparty/harfbuzz/upstream/hb-subset-table.hh b/thirdparty/harfbuzz/upstream/hb-subset-table.hh new file mode 100644 index 000000000..66588ec6f --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-subset-table.hh @@ -0,0 +1,217 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Roderick Sheeter + */ + +#ifndef HB_SUBSET_TABLE_HH +#define HB_SUBSET_TABLE_HH + + +#include "hb.hh" + +#include "hb-subset.hh" +#include "hb-repacker.hh" + + +template +static bool +_hb_subset_table_try (const TableType *table, + hb_vector_t* buf, + hb_subset_context_t* c /* OUT */) +{ + c->serializer->start_serialize (); + if (c->serializer->in_error ()) return false; + + bool needed = table->subset (c); + if (!c->serializer->ran_out_of_room ()) + { + c->serializer->end_serialize (); + return needed; + } + + unsigned buf_size = buf->allocated; + buf_size = buf_size * 2 + 16; + + + + + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", + HB_UNTAG (c->table_tag), buf_size); + + if (unlikely (buf_size > c->source_blob->length * 256 || + !buf->alloc_exact (buf_size))) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", + HB_UNTAG (c->table_tag), buf_size); + return needed; + } + + c->serializer->reset (buf->arrayZ, buf->allocated); + return _hb_subset_table_try (table, buf, c); +} + +static HB_UNUSED unsigned +_hb_subset_estimate_table_size (hb_subset_plan_t *plan, + unsigned table_len, + hb_tag_t table_tag) +{ + unsigned src_glyphs = plan->source->get_num_glyphs (); + unsigned dst_glyphs = plan->glyphset ()->get_population (); + + unsigned bulk = 8192; + /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's + * because those are expensive to subset, so giving them more room is fine. */ + bool same_size = table_tag == HB_TAG('G','S','U','B') || + table_tag == HB_TAG('G','P','O','S') || + table_tag == HB_TAG('G','D','E','F') || + table_tag == HB_TAG('n','a','m','e'); + + if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) + { + if (table_tag == HB_TAG('C','F','F',' ')) + { + /* Add some extra room for the CFF charset. */ + bulk += src_glyphs * 16; + } + else if (table_tag == HB_TAG('C','F','F','2')) + { + /* Just extra CharString offsets. */ + bulk += src_glyphs * 4; + } + } + + if (unlikely (!src_glyphs) || same_size) + return bulk + table_len; + + return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); +} + +/* + * Repack the serialization buffer if any offset overflows exist. + */ +static HB_UNUSED hb_blob_t* +_hb_subset_repack (hb_tag_t tag, const hb_serialize_context_t& c) +{ + if (!c.offset_overflow ()) + return c.copy_blob (); + + hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); + + if (unlikely (!result)) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", + HB_UNTAG (tag)); + return nullptr; + } + + return result; +} + +template +static HB_UNUSED auto _hb_do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) + +template +static HB_UNUSED void _hb_do_destroy (T &t, hb_priority<0>) {} + +template +static bool +_hb_subset_table (hb_subset_plan_t *plan, hb_vector_t &buf) +{ + auto &&source_blob = plan->source_table (); + auto *table = source_blob.get (); + + hb_tag_t tag = TableType::tableTag; + hb_blob_t *blob = source_blob.get_blob(); + if (unlikely (!blob || !blob->data)) + { + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); + _hb_do_destroy (source_blob, hb_prioritize); + return false; + } + + unsigned buf_size = _hb_subset_estimate_table_size (plan, blob->length, TableType::tableTag); + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); + if (unlikely (!buf.alloc (buf_size))) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); + _hb_do_destroy (source_blob, hb_prioritize); + return false; + } + + bool needed = false; + hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); + { + hb_subset_context_t c (blob, plan, &serializer, tag); + needed = _hb_subset_table_try (table, &buf, &c); + } + _hb_do_destroy (source_blob, hb_prioritize); + + if (serializer.in_error () && !serializer.only_offset_overflow ()) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); + return false; + } + + if (!needed) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); + return true; + } + + bool result = false; + hb_blob_t *dest_blob = _hb_subset_repack (tag, serializer); + if (dest_blob) + { + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c final subset table size: %u bytes.", + HB_UNTAG (tag), dest_blob->length); + result = plan->add_table (tag, dest_blob); + hb_blob_destroy (dest_blob); + } + + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", + HB_UNTAG (tag), result ? "success" : "FAILED!"); + return result; +} + +static HB_UNUSED bool +_hb_subset_table_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) +{ + hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); + bool result = plan->add_table (tag, source_table); + hb_blob_destroy (source_table); + return result; +} + + +HB_INTERNAL bool _hb_subset_table_layout (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_var (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_cff (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_color (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); +HB_INTERNAL bool _hb_subset_table_other (hb_subset_plan_t *plan, hb_vector_t &buf, hb_tag_t tag, bool *success); + + +#endif /* HB_SUBSET_TABLE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-subset.cc b/thirdparty/harfbuzz/upstream/hb-subset.cc index 7cea9f183..d1ca60e63 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset.cc +++ b/thirdparty/harfbuzz/upstream/hb-subset.cc @@ -25,65 +25,19 @@ */ #include "hb.hh" + #include "hb-open-type.hh" +#include "hb-open-file.hh" #include "hb-subset.hh" +#include "hb-subset-table.hh" +#include "hb-subset-accelerator.hh" -#include "hb-open-file.hh" #include "hb-ot-cmap-table.hh" -#include "hb-ot-glyf-table.hh" -#include "hb-ot-hdmx-table.hh" -#include "hb-ot-head-table.hh" -#include "hb-ot-hhea-table.hh" -#include "hb-ot-hmtx-table.hh" -#include "hb-ot-maxp-table.hh" -#include "OT/Color/CBDT/CBDT.hh" -#include "OT/Color/COLR/COLR.hh" -#include "OT/Color/CPAL/CPAL.hh" -#include "OT/Color/sbix/sbix.hh" -#include "hb-ot-os2-table.hh" -#include "hb-ot-post-table.hh" -#include "hb-ot-post-table-v2subset.hh" -#include "hb-ot-cff1-table.hh" -#include "hb-ot-cff2-table.hh" -#include "hb-ot-vorg-table.hh" -#include "hb-ot-name-table.hh" -#include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-gsub-table.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-var-avar-table.hh" #include "hb-ot-var-cvar-table.hh" -#include "hb-ot-var-fvar-table.hh" -#include "hb-ot-var-gvar-table.hh" -#include "hb-ot-var-hvar-table.hh" -#include "hb-ot-var-mvar-table.hh" -#include "hb-ot-math-table.hh" +#include "hb-ot-head-table.hh" #include "hb-ot-stat-table.hh" -#include "hb-repacker.hh" -#include "hb-subset-accelerator.hh" - -using OT::Layout::GSUB; -using OT::Layout::GPOS; - - -#ifndef HB_NO_SUBSET_CFF -template<> -struct hb_subset_plan_t::source_table_loader -{ - auto operator () (hb_subset_plan_t *plan) - HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel : - plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel : - plan->cff1_accel) -}; -template<> -struct hb_subset_plan_t::source_table_loader -{ - auto operator () (hb_subset_plan_t *plan) - HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel : - plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel : - plan->cff2_accel) -}; -#endif +#include "hb-ot-post-table-v2subset.hh" /** @@ -116,56 +70,56 @@ hb_user_data_key_t _hb_subset_accelerator_user_data_key = {}; * if we are unable to list the tables in a face. */ static hb_tag_t known_tables[] { - HB_TAG ('a', 'v', 'a', 'r'), - HB_OT_TAG_BASE, - HB_OT_TAG_CBDT, - HB_OT_TAG_CBLC, - HB_OT_TAG_CFF1, - HB_OT_TAG_CFF2, - HB_OT_TAG_cmap, - HB_OT_TAG_COLR, - HB_OT_TAG_CPAL, - HB_TAG ('c', 'v', 'a', 'r'), - HB_TAG ('c', 'v', 't', ' '), - HB_TAG ('D', 'S', 'I', 'G'), - HB_TAG ('E', 'B', 'D', 'T'), - HB_TAG ('E', 'B', 'L', 'C'), - HB_TAG ('E', 'B', 'S', 'C'), - HB_TAG ('f', 'p', 'g', 'm'), - HB_TAG ('f', 'v', 'a', 'r'), - HB_TAG ('g', 'a', 's', 'p'), - HB_OT_TAG_GDEF, - HB_OT_TAG_glyf, - HB_OT_TAG_GPOS, - HB_OT_TAG_GSUB, - HB_OT_TAG_gvar, - HB_OT_TAG_hdmx, - HB_OT_TAG_head, - HB_OT_TAG_hhea, - HB_OT_TAG_hmtx, - HB_OT_TAG_HVAR, - HB_OT_TAG_JSTF, - HB_TAG ('k', 'e', 'r', 'n'), - HB_OT_TAG_loca, - HB_TAG ('L', 'T', 'S', 'H'), - HB_OT_TAG_MATH, - HB_OT_TAG_maxp, - HB_TAG ('M', 'E', 'R', 'G'), - HB_TAG ('m', 'e', 't', 'a'), - HB_TAG ('M', 'V', 'A', 'R'), - HB_TAG ('P', 'C', 'L', 'T'), - HB_OT_TAG_post, - HB_TAG ('p', 'r', 'e', 'p'), - HB_OT_TAG_sbix, - HB_TAG ('S', 'T', 'A', 'T'), - HB_TAG ('S', 'V', 'G', ' '), - HB_TAG ('V', 'D', 'M', 'X'), - HB_OT_TAG_vhea, - HB_OT_TAG_vmtx, - HB_OT_TAG_VORG, - HB_OT_TAG_VVAR, - HB_OT_TAG_name, - HB_OT_TAG_OS2 + HB_TAG('a','v','a','r'), + HB_TAG('B','A','S','E'), + HB_TAG('C','B','D','T'), + HB_TAG('C','B','L','C'), + HB_TAG('C','F','F',' '), + HB_TAG('C','F','F','2'), + HB_TAG('c','m','a','p'), + HB_TAG('C','O','L','R'), + HB_TAG('C','P','A','L'), + HB_TAG('c','v','a','r'), + HB_TAG('c','v','t',' '), + HB_TAG('D','S','I','G'), + HB_TAG('E','B','D','T'), + HB_TAG('E','B','L','C'), + HB_TAG('E','B','S','C'), + HB_TAG('f','p','g','m'), + HB_TAG('f','v','a','r'), + HB_TAG('g','a','s','p'), + HB_TAG('G','D','E','F'), + HB_TAG('g','l','y','f'), + HB_TAG('G','P','O','S'), + HB_TAG('G','S','U','B'), + HB_TAG('g','v','a','r'), + HB_TAG('h','d','m','x'), + HB_TAG('h','e','a','d'), + HB_TAG('h','h','e','a'), + HB_TAG('h','m','t','x'), + HB_TAG('H','V','A','R'), + HB_TAG('J','S','T','F'), + HB_TAG('k','e','r','n'), + HB_TAG('l','o','c','a'), + HB_TAG('L','T','S','H'), + HB_TAG('M','A','T','H'), + HB_TAG('m','a','x','p'), + HB_TAG('M','E','R','G'), + HB_TAG('m','e','t','a'), + HB_TAG('M','V','A','R'), + HB_TAG('P','C','L','T'), + HB_TAG('p','o','s','t'), + HB_TAG('p','r','e','p'), + HB_TAG('s','b','i','x'), + HB_TAG('S','T','A','T'), + HB_TAG('S','V','G',' '), + HB_TAG('V','D','M','X'), + HB_TAG('v','h','e','a'), + HB_TAG('v','m','t','x'), + HB_TAG('V','O','R','G'), + HB_TAG('V','V','A','R'), + HB_TAG('n','a','m','e'), + HB_TAG('O','S','/','2') }; static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag) @@ -213,169 +167,6 @@ _get_table_tags (const hb_subset_plan_t* plan, } -static unsigned -_plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned table_len, - hb_tag_t table_tag) -{ - unsigned src_glyphs = plan->source->get_num_glyphs (); - unsigned dst_glyphs = plan->glyphset ()->get_population (); - - unsigned bulk = 8192; - /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's - * because those are expensive to subset, so giving them more room is fine. */ - bool same_size = table_tag == HB_OT_TAG_GSUB || - table_tag == HB_OT_TAG_GPOS || - table_tag == HB_OT_TAG_name; - - if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS) - { - if (table_tag == HB_OT_TAG_CFF1) - { - /* Add some extra room for the CFF charset. */ - bulk += src_glyphs * 16; - } - else if (table_tag == HB_OT_TAG_CFF2) - { - /* Just extra CharString offsets. */ - bulk += src_glyphs * 4; - } - } - - if (unlikely (!src_glyphs) || same_size) - return bulk + table_len; - - return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); -} - -/* - * Repack the serialization buffer if any offset overflows exist. - */ -static hb_blob_t* -_repack (hb_tag_t tag, const hb_serialize_context_t& c) -{ - if (!c.offset_overflow ()) - return c.copy_blob (); - - hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); - - if (unlikely (!result)) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", - HB_UNTAG (tag)); - return nullptr; - } - - return result; -} - -template -static -bool -_try_subset (const TableType *table, - hb_vector_t* buf, - hb_subset_context_t* c /* OUT */) -{ - c->serializer->start_serialize (); - if (c->serializer->in_error ()) return false; - - bool needed = table->subset (c); - if (!c->serializer->ran_out_of_room ()) - { - c->serializer->end_serialize (); - return needed; - } - - unsigned buf_size = buf->allocated; - buf_size = buf_size * 2 + 16; - - - - - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", - HB_UNTAG (c->table_tag), buf_size); - - if (unlikely (buf_size > c->source_blob->length * 16 || - !buf->alloc (buf_size, true))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", - HB_UNTAG (c->table_tag), buf_size); - return needed; - } - - c->serializer->reset (buf->arrayZ, buf->allocated); - return _try_subset (table, buf, c); -} - -template -static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ()) - -template -static void _do_destroy (T &t, hb_priority<0>) {} - -template -static bool -_subset (hb_subset_plan_t *plan, hb_vector_t &buf) -{ - auto &&source_blob = plan->source_table (); - auto *table = source_blob.get (); - - hb_tag_t tag = TableType::tableTag; - hb_blob_t *blob = source_blob.get_blob(); - if (unlikely (!blob || !blob->data)) - { - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - _do_destroy (source_blob, hb_prioritize); - return false; - } - - unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag); - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); - if (unlikely (!buf.alloc (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - _do_destroy (source_blob, hb_prioritize); - return false; - } - - bool needed = false; - hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); - { - hb_subset_context_t c (blob, plan, &serializer, tag); - needed = _try_subset (table, &buf, &c); - } - _do_destroy (source_blob, hb_prioritize); - - if (serializer.in_error () && !serializer.only_offset_overflow ()) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); - return false; - } - - if (!needed) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); - return true; - } - - bool result = false; - hb_blob_t *dest_blob = _repack (tag, serializer); - if (dest_blob) - { - DEBUG_MSG (SUBSET, nullptr, - "OT::%c%c%c%c final subset table size: %u bytes.", - HB_UNTAG (tag), dest_blob->length); - result = plan->add_table (tag, dest_blob); - hb_blob_destroy (dest_blob); - } - - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", - HB_UNTAG (tag), result ? "success" : "FAILED!"); - return result; -} - static bool _is_table_present (hb_face_t *source, hb_tag_t tag) { @@ -407,34 +198,34 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) switch (tag) { - case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */ + case HB_TAG('c','v','a','r'): /* hint table, fallthrough */ return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING); - case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */ - case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */ - case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ - case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */ - case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */ + case HB_TAG('c','v','t',' '): /* hint table, fallthrough */ + case HB_TAG('f','p','g','m'): /* hint table, fallthrough */ + case HB_TAG('p','r','e','p'): /* hint table, fallthrough */ + case HB_TAG('h','d','m','x'): /* hint table, fallthrough */ + case HB_TAG('V','D','M','X'): /* hint table, fallthrough */ return plan->flags & HB_SUBSET_FLAGS_NO_HINTING; #ifdef HB_NO_SUBSET_LAYOUT // Drop Layout Tables if requested. - case HB_OT_TAG_GDEF: - case HB_OT_TAG_GPOS: - case HB_OT_TAG_GSUB: - case HB_TAG ('m','o','r','x'): - case HB_TAG ('m','o','r','t'): - case HB_TAG ('k','e','r','x'): - case HB_TAG ('k','e','r','n'): + case HB_TAG('G','D','E','F'): + case HB_TAG('G','P','O','S'): + case HB_TAG('G','S','U','B'): + case HB_TAG('m','o','r','x'): + case HB_TAG('m','o','r','t'): + case HB_TAG('k','e','r','x'): + case HB_TAG('k','e','r','n'): return true; #endif - case HB_TAG ('a','v','a','r'): - case HB_TAG ('f','v','a','r'): - case HB_TAG ('g','v','a','r'): - case HB_OT_TAG_HVAR: - case HB_OT_TAG_VVAR: - case HB_TAG ('M','V','A','R'): + case HB_TAG('a','v','a','r'): + case HB_TAG('f','v','a','r'): + case HB_TAG('g','v','a','r'): + case HB_TAG('H','V','A','R'): + case HB_TAG('V','V','A','R'): + case HB_TAG('M','V','A','R'): return plan->all_axes_pinned; default: @@ -442,15 +233,6 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) } } -static bool -_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) -{ - hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); - bool result = plan->add_table (tag, source_table); - hb_blob_destroy (source_table); - return result; -} - static bool _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, const hb_set_t &subsetted_tags, @@ -458,13 +240,13 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, { switch (tag) { - case HB_OT_TAG_hmtx: - case HB_OT_TAG_vmtx: - case HB_OT_TAG_maxp: - case HB_OT_TAG_OS2: - return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); - case HB_OT_TAG_GPOS: - return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); + case HB_TAG('h','m','t','x'): + case HB_TAG('v','m','t','x'): + case HB_TAG('m','a','x','p'): + case HB_TAG('O','S','/','2'): + return !plan->normalized_coords || !pending_subset_tags.has (HB_TAG('g','l','y','f')); + case HB_TAG('G','P','O','S'): + return plan->all_axes_pinned || !pending_subset_tags.has (HB_TAG('G','D','E','F')); default: return true; } @@ -476,88 +258,48 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) { if (plan->no_subset_tables.has (tag)) { - return _passthrough (plan, tag); + return _hb_subset_table_passthrough (plan, tag); } DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag)); + + bool success; + if (_hb_subset_table_layout (plan, buf, tag, &success) || + _hb_subset_table_var (plan, buf, tag, &success) || + _hb_subset_table_cff (plan, buf, tag, &success) || + _hb_subset_table_color (plan, buf, tag, &success) || + _hb_subset_table_other (plan, buf, tag, &success)) + return success; + + switch (tag) { - case HB_OT_TAG_glyf: return _subset (plan, buf); - case HB_OT_TAG_hdmx: return _subset (plan, buf); - case HB_OT_TAG_name: return _subset (plan, buf); - case HB_OT_TAG_head: - if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf)) + case HB_TAG('h','e','a','d'): + if (_is_table_present (plan->source, HB_TAG('g','l','y','f')) && !_should_drop_table (plan, HB_TAG('g','l','y','f'))) return true; /* skip head, handled by glyf */ - return _subset (plan, buf); - case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */ - case HB_OT_TAG_hmtx: return _subset (plan, buf); - case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */ - case HB_OT_TAG_vmtx: return _subset (plan, buf); - case HB_OT_TAG_maxp: return _subset (plan, buf); - case HB_OT_TAG_sbix: return _subset (plan, buf); - case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */ - case HB_OT_TAG_cmap: return _subset (plan, buf); - case HB_OT_TAG_OS2 : return _subset (plan, buf); - case HB_OT_TAG_post: return _subset (plan, buf); - case HB_OT_TAG_COLR: return _subset (plan, buf); - case HB_OT_TAG_CPAL: return _subset (plan, buf); - case HB_OT_TAG_CBLC: return _subset (plan, buf); - case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ - case HB_OT_TAG_MATH: return _subset (plan, buf); - case HB_OT_TAG_BASE: return _subset (plan, buf); - -#ifndef HB_NO_SUBSET_CFF - case HB_OT_TAG_CFF1: return _subset (plan, buf); - case HB_OT_TAG_CFF2: return _subset (plan, buf); - case HB_OT_TAG_VORG: return _subset (plan, buf); -#endif + return _hb_subset_table (plan, buf); -#ifndef HB_NO_SUBSET_LAYOUT - case HB_OT_TAG_GDEF: return _subset (plan, buf); - case HB_OT_TAG_GSUB: return _subset (plan, buf); - case HB_OT_TAG_GPOS: return _subset (plan, buf); - case HB_OT_TAG_gvar: return _subset (plan, buf); - case HB_OT_TAG_HVAR: return _subset (plan, buf); - case HB_OT_TAG_VVAR: return _subset (plan, buf); -#endif + case HB_TAG('S','T','A','T'): + if (!plan->user_axes_location.is_empty ()) return _hb_subset_table (plan, buf); + else return _hb_subset_table_passthrough (plan, tag); + case HB_TAG('c','v','t',' '): #ifndef HB_NO_VAR - case HB_OT_TAG_fvar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_avar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_cvar: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); - case HB_OT_TAG_MVAR: - if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); - return _subset (plan, buf); -#endif - - case HB_OT_TAG_STAT: - if (!plan->user_axes_location.is_empty ()) return _subset (plan, buf); - else return _passthrough (plan, tag); - - case HB_TAG ('c', 'v', 't', ' '): -#ifndef HB_NO_VAR - if (_is_table_present (plan->source, HB_OT_TAG_cvar) && + if (_is_table_present (plan->source, HB_TAG('c','v','a','r')) && plan->normalized_coords && !plan->pinned_at_default) { auto &cvar = *plan->source->table.cvar; return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar); } #endif - return _passthrough (plan, tag); + return _hb_subset_table_passthrough (plan, tag); + } - default: - if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) - return _passthrough (plan, tag); + if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) + return _hb_subset_table_passthrough (plan, tag); - // Drop table - return true; - } + // Drop table + return true; } static void _attach_accelerator_data (hb_subset_plan_t* plan, @@ -707,4 +449,4 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) end: return success ? hb_face_reference (plan->dest) : nullptr; -} +} \ No newline at end of file diff --git a/thirdparty/harfbuzz/upstream/hb-subset.h b/thirdparty/harfbuzz/upstream/hb-subset.h index 365c21a63..2b9b2a226 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset.h +++ b/thirdparty/harfbuzz/upstream/hb-subset.h @@ -71,13 +71,22 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * in the final subset. * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in * OS/2 will not be recalculated. - * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout + * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set do not perform glyph closure on layout * substitution rules (GSUB). Since: 7.2.0. * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the * remaining gvar table's deltas. Since: 8.5.0 + * @HB_SUBSET_FLAGS_NO_BIDI_CLOSURE: If set do not pull mirrored versions of input + * codepoints into the subset. Since: 11.1.0 * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL + * @HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS: If this flag is set along side + * HB_SUBSET_FLAGS_RETAIN_GIDS then the number of glyphs in the font won't + * be reduced as a result of subsetting. If necessary empty glyphs will be + * included at the end of the font to keep the number of glyphs unchanged. + * @HB_SUBSET_FLAGS_DOWNGRADE_CFF2: If set and instantiating a variable font, + * convert the output CFF2 table to CFF1. This enables compatibility with older + * renderers that don't support CFF2. Since: REPLACEME * * List of boolean properties that can be configured on the subset input. * @@ -96,9 +105,12 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000400u, + HB_SUBSET_FLAGS_NO_BIDI_CLOSURE = 0x00000800u, #ifdef HB_EXPERIMENTAL_API - HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000800u, + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00001000u, + HB_SUBSET_FLAGS_RETAIN_NUM_GLYPHS = 0x00002000u, #endif + HB_SUBSET_FLAGS_DOWNGRADE_CFF2 = 0x00004000u, } hb_subset_flags_t; /** @@ -203,6 +215,18 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, float axis_max_value, float axis_def_value); +HB_EXTERN hb_bool_t +hb_subset_axis_range_from_string (const char *str, int len, + float *axis_min_value, + float *axis_max_value, + float *axis_def_value); + +HB_EXTERN void +hb_subset_axis_range_to_string (hb_subset_input_t *input, + hb_tag_t axis_tag, + char *buf, + unsigned size); + #ifdef HB_EXPERIMENTAL_API HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, @@ -212,6 +236,23 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, unsigned language_id, const char *name_str, int str_len); + + +/* +* Raw outline data access +*/ + +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data (hb_face_t* face, hb_codepoint_t glyph_index); + +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face); + +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data (hb_face_t* face, hb_codepoint_t glyph_index); + +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face); #endif HB_EXTERN hb_face_t * diff --git a/thirdparty/harfbuzz/upstream/hb-subset.hh b/thirdparty/harfbuzz/upstream/hb-subset.hh index 4f192aae4..fca378de1 100644 --- a/thirdparty/harfbuzz/upstream/hb-subset.hh +++ b/thirdparty/harfbuzz/upstream/hb-subset.hh @@ -70,5 +70,4 @@ struct hb_subset_context_t : table_tag (table_tag_) {} }; - #endif /* HB_SUBSET_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-ucd-table.hh b/thirdparty/harfbuzz/upstream/hb-ucd-table.hh index 8731a0bcf..d2d23cf59 100644 --- a/thirdparty/harfbuzz/upstream/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-ucd-table.hh @@ -2,9 +2,9 @@ /* * The following table is generated by running: * - * ./gen-ucd-table.py ucd.nounihan.grouped.xml + * ./gen-ucd-table.py ucd.nounihan.grouped.xml hb-script-list.h * - * on file with this description: Unicode 16.0.0 + * on file with this description: Unicode 17.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -12,8 +12,9 @@ #include "hb.hh" -static const hb_script_t -_hb_ucd_sc_map[172] = +#include + +static const hb_script_t _hb_ucd_sc_map[176]= { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -101,1417 +102,1187 @@ _hb_ucd_sc_map[172] = HB_SCRIPT_GURUNG_KHEMA, HB_SCRIPT_KIRAT_RAI, HB_SCRIPT_OL_ONAL, HB_SCRIPT_SUNUWAR, HB_SCRIPT_TODHRI, HB_SCRIPT_TULU_TIGALARI, + HB_SCRIPT_BERIA_ERFE, HB_SCRIPT_SIDETIC, + HB_SCRIPT_TAI_YO, HB_SCRIPT_TOLONG_SIKI, }; -static const uint16_t -_hb_ucd_dm1_p0_map[825] = +static const uint16_t _hb_ucd_dm1_p0_map[825]= { - 0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u, - 0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu, - 0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu, - 0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u, - 0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu, - 0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au, - 0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u, - 0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u, - 0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u, - 0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu, - 0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu, - 0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu, - 0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u, - 0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu, - 0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu, - 0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u, - 0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du, - 0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu, - 0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u, - 0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u, - 0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu, - 0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u, - 0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu, - 0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u, - 0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u, - 0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu, - 0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u, - 0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u, - 0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u, - 0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u, - 0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu, - 0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u, - 0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u, - 0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u, - 0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu, - 0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u, - 0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u, - 0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu, - 0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u, - 0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u, - 0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au, - 0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u, - 0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u, - 0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u, - 0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu, - 0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u, - 0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u, - 0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u, - 0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u, - 0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u, - 0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u, - 0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u, - 0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu, - 0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u, - 0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au, - 0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au, - 0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu, - 0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu, - 0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu, - 0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u, - 0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u, - 0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u, - 0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u, - 0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u, - 0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u, - 0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u, - 0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu, - 0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu, - 0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u, - 0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu, - 0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u, - 0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu, - 0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u, - 0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u, - 0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au, - 0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u, - 0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u, - 0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu, - 0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u, - 0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu, - 0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u, - 0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u, - 0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u, - 0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u, - 0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu, - 0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u, - 0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u, - 0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu, - 0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu, - 0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu, - 0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u, - 0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u, - 0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u, - 0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u, - 0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u, - 0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u, - 0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u, - 0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu, - 0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u, - 0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu, - 0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u, - 0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u, - 0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu, - 0x9F9Cu, + 0x003B, 0x004B, 0x0060, 0x00B4, 0x00B7, 0x00C5, 0x02B9, 0x0300, + 0x0301, 0x0313, 0x0385, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, + 0x038E, 0x038F, 0x0390, 0x03A9, 0x03AC, 0x03AD, 0x03AE, 0x03AF, + 0x03B0, 0x03B9, 0x03CC, 0x03CD, 0x03CE, 0x2002, 0x2003, 0x3008, + 0x3009, 0x349E, 0x34B9, 0x34BB, 0x34DF, 0x3515, 0x36EE, 0x36FC, + 0x3781, 0x382F, 0x3862, 0x387C, 0x38C7, 0x38E3, 0x391C, 0x393A, + 0x3A2E, 0x3A6C, 0x3AE4, 0x3B08, 0x3B19, 0x3B49, 0x3B9D, 0x3C18, + 0x3C4E, 0x3D33, 0x3D96, 0x3EAC, 0x3EB8, 0x3F1B, 0x3FFC, 0x4008, + 0x4018, 0x4039, 0x4046, 0x4096, 0x40E3, 0x412F, 0x4202, 0x4227, + 0x42A0, 0x4301, 0x4334, 0x4359, 0x43D5, 0x43D9, 0x440B, 0x446B, + 0x452B, 0x455D, 0x4561, 0x456B, 0x45D7, 0x45F9, 0x4635, 0x46BE, + 0x46C7, 0x4995, 0x49E6, 0x4A6E, 0x4A76, 0x4AB2, 0x4B33, 0x4BCE, + 0x4CCE, 0x4CED, 0x4CF8, 0x4D56, 0x4E0D, 0x4E26, 0x4E32, 0x4E38, + 0x4E39, 0x4E3D, 0x4E41, 0x4E82, 0x4E86, 0x4EAE, 0x4EC0, 0x4ECC, + 0x4EE4, 0x4F60, 0x4F80, 0x4F86, 0x4F8B, 0x4FAE, 0x4FBB, 0x4FBF, + 0x5002, 0x502B, 0x507A, 0x5099, 0x50CF, 0x50DA, 0x50E7, 0x5140, + 0x5145, 0x514D, 0x5154, 0x5164, 0x5167, 0x5168, 0x5169, 0x516D, + 0x5177, 0x5180, 0x518D, 0x5192, 0x5195, 0x5197, 0x51A4, 0x51AC, + 0x51B5, 0x51B7, 0x51C9, 0x51CC, 0x51DC, 0x51DE, 0x51F5, 0x5203, + 0x5207, 0x5217, 0x5229, 0x523A, 0x523B, 0x5246, 0x5272, 0x5277, + 0x5289, 0x529B, 0x52A3, 0x52B3, 0x52C7, 0x52C9, 0x52D2, 0x52DE, + 0x52E4, 0x52F5, 0x52FA, 0x5305, 0x5306, 0x5317, 0x533F, 0x5349, + 0x5351, 0x535A, 0x5373, 0x5375, 0x537D, 0x537F, 0x53C3, 0x53CA, + 0x53DF, 0x53E5, 0x53EB, 0x53F1, 0x5406, 0x540F, 0x541D, 0x5438, + 0x5442, 0x5448, 0x5468, 0x549E, 0x54A2, 0x54BD, 0x54F6, 0x5510, + 0x5553, 0x5555, 0x5563, 0x5584, 0x5587, 0x5599, 0x559D, 0x55AB, + 0x55B3, 0x55C0, 0x55C2, 0x55E2, 0x5606, 0x5651, 0x5668, 0x5674, + 0x56F9, 0x5716, 0x5717, 0x578B, 0x57CE, 0x57F4, 0x580D, 0x5831, + 0x5832, 0x5840, 0x585A, 0x585E, 0x58A8, 0x58AC, 0x58B3, 0x58D8, + 0x58DF, 0x58EE, 0x58F2, 0x58F7, 0x5906, 0x591A, 0x5922, 0x5944, + 0x5948, 0x5951, 0x5954, 0x5962, 0x5973, 0x59D8, 0x59EC, 0x5A1B, + 0x5A27, 0x5A62, 0x5A66, 0x5AB5, 0x5B08, 0x5B28, 0x5B3E, 0x5B85, + 0x5BC3, 0x5BD8, 0x5BE7, 0x5BEE, 0x5BF3, 0x5BFF, 0x5C06, 0x5C22, + 0x5C3F, 0x5C60, 0x5C62, 0x5C64, 0x5C65, 0x5C6E, 0x5C8D, 0x5CC0, + 0x5D19, 0x5D43, 0x5D50, 0x5D6B, 0x5D6E, 0x5D7C, 0x5DB2, 0x5DBA, + 0x5DE1, 0x5DE2, 0x5DFD, 0x5E28, 0x5E3D, 0x5E69, 0x5E74, 0x5EA6, + 0x5EB0, 0x5EB3, 0x5EB6, 0x5EC9, 0x5ECA, 0x5ED2, 0x5ED3, 0x5ED9, + 0x5EEC, 0x5EFE, 0x5F04, 0x5F22, 0x5F53, 0x5F62, 0x5F69, 0x5F6B, + 0x5F8B, 0x5F9A, 0x5FA9, 0x5FAD, 0x5FCD, 0x5FD7, 0x5FF5, 0x5FF9, + 0x6012, 0x601C, 0x6075, 0x6081, 0x6094, 0x60C7, 0x60D8, 0x60E1, + 0x6108, 0x6144, 0x6148, 0x614C, 0x614E, 0x6160, 0x6168, 0x617A, + 0x618E, 0x6190, 0x61A4, 0x61AF, 0x61B2, 0x61DE, 0x61F2, 0x61F6, + 0x6200, 0x6210, 0x621B, 0x622E, 0x6234, 0x625D, 0x62B1, 0x62C9, + 0x62CF, 0x62D3, 0x62D4, 0x62FC, 0x62FE, 0x633D, 0x6350, 0x6368, + 0x637B, 0x6383, 0x63A0, 0x63A9, 0x63C4, 0x63C5, 0x63E4, 0x641C, + 0x6422, 0x6452, 0x6469, 0x6477, 0x647E, 0x649A, 0x649D, 0x64C4, + 0x654F, 0x6556, 0x656C, 0x6578, 0x6599, 0x65C5, 0x65E2, 0x65E3, + 0x6613, 0x6649, 0x6674, 0x6688, 0x6691, 0x669C, 0x66B4, 0x66C6, + 0x66F4, 0x66F8, 0x6700, 0x6717, 0x671B, 0x6721, 0x674E, 0x6753, + 0x6756, 0x675E, 0x677B, 0x6785, 0x6797, 0x67F3, 0x67FA, 0x6817, + 0x681F, 0x6852, 0x6881, 0x6885, 0x688E, 0x68A8, 0x6914, 0x6942, + 0x69A3, 0x69EA, 0x6A02, 0x6A13, 0x6AA8, 0x6AD3, 0x6ADB, 0x6B04, + 0x6B21, 0x6B54, 0x6B72, 0x6B77, 0x6B79, 0x6B9F, 0x6BAE, 0x6BBA, + 0x6BBB, 0x6C4E, 0x6C67, 0x6C88, 0x6CBF, 0x6CCC, 0x6CCD, 0x6CE5, + 0x6D16, 0x6D1B, 0x6D1E, 0x6D34, 0x6D3E, 0x6D41, 0x6D69, 0x6D6A, + 0x6D77, 0x6D78, 0x6D85, 0x6DCB, 0x6DDA, 0x6DEA, 0x6DF9, 0x6E1A, + 0x6E2F, 0x6E6E, 0x6E9C, 0x6EBA, 0x6EC7, 0x6ECB, 0x6ED1, 0x6EDB, + 0x6F0F, 0x6F22, 0x6F23, 0x6F6E, 0x6FC6, 0x6FEB, 0x6FFE, 0x701B, + 0x701E, 0x7039, 0x704A, 0x7070, 0x7077, 0x707D, 0x7099, 0x70AD, + 0x70C8, 0x70D9, 0x7145, 0x7149, 0x716E, 0x719C, 0x71CE, 0x71D0, + 0x7210, 0x721B, 0x7228, 0x722B, 0x7235, 0x7250, 0x7262, 0x7280, + 0x7295, 0x72AF, 0x72C0, 0x72FC, 0x732A, 0x7375, 0x737A, 0x7387, + 0x738B, 0x73A5, 0x73B2, 0x73DE, 0x7406, 0x7409, 0x7422, 0x7447, + 0x745C, 0x7469, 0x7471, 0x7485, 0x7489, 0x7498, 0x74CA, 0x7506, + 0x7524, 0x753B, 0x753E, 0x7559, 0x7565, 0x7570, 0x75E2, 0x7610, + 0x761D, 0x761F, 0x7642, 0x7669, 0x76CA, 0x76DB, 0x76E7, 0x76F4, + 0x7701, 0x771E, 0x771F, 0x7740, 0x774A, 0x778B, 0x77A7, 0x784E, + 0x786B, 0x788C, 0x7891, 0x78CA, 0x78CC, 0x78FB, 0x792A, 0x793C, + 0x793E, 0x7948, 0x7949, 0x7950, 0x7956, 0x795D, 0x795E, 0x7965, + 0x797F, 0x798D, 0x798E, 0x798F, 0x79AE, 0x79CA, 0x79EB, 0x7A1C, + 0x7A40, 0x7A4A, 0x7A4F, 0x7A81, 0x7AB1, 0x7ACB, 0x7AEE, 0x7B20, + 0x7BC0, 0x7BC6, 0x7BC9, 0x7C3E, 0x7C60, 0x7C7B, 0x7C92, 0x7CBE, + 0x7CD2, 0x7CD6, 0x7CE3, 0x7CE7, 0x7CE8, 0x7D00, 0x7D10, 0x7D22, + 0x7D2F, 0x7D5B, 0x7D63, 0x7DA0, 0x7DBE, 0x7DC7, 0x7DF4, 0x7E02, + 0x7E09, 0x7E37, 0x7E41, 0x7E45, 0x7F3E, 0x7F72, 0x7F79, 0x7F7A, + 0x7F85, 0x7F95, 0x7F9A, 0x7FBD, 0x7FFA, 0x8001, 0x8005, 0x8046, + 0x8060, 0x806F, 0x8070, 0x807E, 0x808B, 0x80AD, 0x80B2, 0x8103, + 0x813E, 0x81D8, 0x81E8, 0x81ED, 0x8201, 0x8204, 0x8218, 0x826F, + 0x8279, 0x828B, 0x8291, 0x829D, 0x82B1, 0x82B3, 0x82BD, 0x82E5, + 0x82E6, 0x831D, 0x8323, 0x8336, 0x8352, 0x8353, 0x8363, 0x83AD, + 0x83BD, 0x83C9, 0x83CA, 0x83CC, 0x83DC, 0x83E7, 0x83EF, 0x83F1, + 0x843D, 0x8449, 0x8457, 0x84EE, 0x84F1, 0x84F3, 0x84FC, 0x8516, + 0x8564, 0x85CD, 0x85FA, 0x8606, 0x8612, 0x862D, 0x863F, 0x8650, + 0x865C, 0x8667, 0x8669, 0x8688, 0x86A9, 0x86E2, 0x870E, 0x8728, + 0x876B, 0x8779, 0x8786, 0x87BA, 0x87E1, 0x8801, 0x881F, 0x884C, + 0x8860, 0x8863, 0x88C2, 0x88CF, 0x88D7, 0x88DE, 0x88E1, 0x88F8, + 0x88FA, 0x8910, 0x8941, 0x8964, 0x8986, 0x898B, 0x8996, 0x8AA0, + 0x8AAA, 0x8ABF, 0x8ACB, 0x8AD2, 0x8AD6, 0x8AED, 0x8AF8, 0x8AFE, + 0x8B01, 0x8B39, 0x8B58, 0x8B80, 0x8B8A, 0x8C48, 0x8C55, 0x8CAB, + 0x8CC1, 0x8CC2, 0x8CC8, 0x8CD3, 0x8D08, 0x8D1B, 0x8D77, 0x8DBC, + 0x8DCB, 0x8DEF, 0x8DF0, 0x8ECA, 0x8ED4, 0x8F26, 0x8F2A, 0x8F38, + 0x8F3B, 0x8F62, 0x8F9E, 0x8FB0, 0x8FB6, 0x9023, 0x9038, 0x9072, + 0x907C, 0x908F, 0x9094, 0x90CE, 0x90DE, 0x90F1, 0x90FD, 0x9111, + 0x911B, 0x916A, 0x9199, 0x91B4, 0x91CC, 0x91CF, 0x91D1, 0x9234, + 0x9238, 0x9276, 0x927C, 0x92D7, 0x92D8, 0x9304, 0x934A, 0x93F9, + 0x9415, 0x958B, 0x95AD, 0x95B7, 0x962E, 0x964B, 0x964D, 0x9675, + 0x9678, 0x967C, 0x9686, 0x96A3, 0x96B7, 0x96B8, 0x96C3, 0x96E2, + 0x96E3, 0x96F6, 0x96F7, 0x9723, 0x9732, 0x9748, 0x9756, 0x97DB, + 0x97E0, 0x97FF, 0x980B, 0x9818, 0x9829, 0x983B, 0x985E, 0x98E2, + 0x98EF, 0x98FC, 0x9928, 0x9929, 0x99A7, 0x99C2, 0x99F1, 0x99FE, + 0x9A6A, 0x9B12, 0x9B6F, 0x9C40, 0x9C57, 0x9CFD, 0x9D67, 0x9DB4, + 0x9DFA, 0x9E1E, 0x9E7F, 0x9E97, 0x9E9F, 0x9EBB, 0x9ECE, 0x9EF9, + 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x9F3B, 0x9F43, 0x9F8D, 0x9F8E, + 0x9F9C, }; -static const uint16_t -_hb_ucd_dm1_p2_map[110] = +static const uint16_t _hb_ucd_dm1_p2_map[110]= { - 0x0122u, 0x051Cu, 0x0525u, 0x054Bu, 0x063Au, 0x0804u, 0x08DEu, 0x0A2Cu, - 0x0B63u, 0x14E4u, 0x16A8u, 0x16EAu, 0x19C8u, 0x1B18u, 0x1D0Bu, 0x1DE4u, - 0x1DE6u, 0x2183u, 0x219Fu, 0x2331u, 0x26D4u, 0x2844u, 0x284Au, 0x2B0Cu, - 0x2BF1u, 0x300Au, 0x32B8u, 0x335Fu, 0x3393u, 0x339Cu, 0x33C3u, 0x33D5u, - 0x346Du, 0x36A3u, 0x38A7u, 0x3A8Du, 0x3AFAu, 0x3CBCu, 0x3D1Eu, 0x3ED1u, - 0x3F5Eu, 0x3F8Eu, 0x4263u, 0x42EEu, 0x43ABu, 0x4608u, 0x4735u, 0x4814u, - 0x4C36u, 0x4C92u, 0x4FA1u, 0x4FB8u, 0x5044u, 0x50F2u, 0x50F3u, 0x5119u, - 0x5133u, 0x5249u, 0x541Du, 0x5626u, 0x569Au, 0x56C5u, 0x597Cu, 0x5AA7u, - 0x5BABu, 0x5C80u, 0x5CD0u, 0x5F86u, 0x61DAu, 0x6228u, 0x6247u, 0x62D9u, - 0x633Eu, 0x64DAu, 0x6523u, 0x65A8u, 0x67A7u, 0x67B5u, 0x6B3Cu, 0x6C36u, - 0x6CD5u, 0x6D6Bu, 0x6F2Cu, 0x6FB1u, 0x70D2u, 0x73CAu, 0x7667u, 0x78AEu, - 0x7966u, 0x7CA8u, 0x7ED3u, 0x7F2Fu, 0x85D2u, 0x85EDu, 0x872Eu, 0x8BFAu, - 0x8D77u, 0x9145u, 0x91DFu, 0x921Au, 0x940Au, 0x9496u, 0x95B6u, 0x9B30u, - 0xA0CEu, 0xA105u, 0xA20Eu, 0xA291u, 0xA392u, 0xA600u, + 0x0122, 0x051C, 0x0525, 0x054B, 0x063A, 0x0804, 0x08DE, 0x0A2C, + 0x0B63, 0x14E4, 0x16A8, 0x16EA, 0x19C8, 0x1B18, 0x1D0B, 0x1DE4, + 0x1DE6, 0x2183, 0x219F, 0x2331, 0x26D4, 0x2844, 0x284A, 0x2B0C, + 0x2BF1, 0x300A, 0x32B8, 0x335F, 0x3393, 0x339C, 0x33C3, 0x33D5, + 0x346D, 0x36A3, 0x38A7, 0x3A8D, 0x3AFA, 0x3CBC, 0x3D1E, 0x3ED1, + 0x3F5E, 0x3F8E, 0x4263, 0x42EE, 0x43AB, 0x4608, 0x4735, 0x4814, + 0x4C36, 0x4C92, 0x4FA1, 0x4FB8, 0x5044, 0x50F2, 0x50F3, 0x5119, + 0x5133, 0x5249, 0x541D, 0x5626, 0x569A, 0x56C5, 0x597C, 0x5AA7, + 0x5BAB, 0x5C80, 0x5CD0, 0x5F86, 0x61DA, 0x6228, 0x6247, 0x62D9, + 0x633E, 0x64DA, 0x6523, 0x65A8, 0x67A7, 0x67B5, 0x6B3C, 0x6C36, + 0x6CD5, 0x6D6B, 0x6F2C, 0x6FB1, 0x70D2, 0x73CA, 0x7667, 0x78AE, + 0x7966, 0x7CA8, 0x7ED3, 0x7F2F, 0x85D2, 0x85ED, 0x872E, 0x8BFA, + 0x8D77, 0x9145, 0x91DF, 0x921A, 0x940A, 0x9496, 0x95B6, 0x9B30, + 0xA0CE, 0xA105, 0xA20E, 0xA291, 0xA392, 0xA600, }; -static const uint32_t -_hb_ucd_dm2_u32_map[638] = +static const uint32_t _hb_ucd_dm2_u32_map[638]= { - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Cu, 0x0338u, 0x226Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Du, 0x0338u, 0x2260u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x003Eu, 0x0338u, 0x226Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0300u, 0x00C0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0301u, 0x00C1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0302u, 0x00C2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0303u, 0x00C3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0304u, 0x0100u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0306u, 0x0102u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0307u, 0x0226u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0308u, 0x00C4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0309u, 0x1EA2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Au, 0x00C5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Cu, 0x01CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Fu, 0x0200u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0311u, 0x0202u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0323u, 0x1EA0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0325u, 0x1E00u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0328u, 0x0104u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0307u, 0x1E02u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0323u, 0x1E04u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0331u, 0x1E06u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0301u, 0x0106u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0302u, 0x0108u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0307u, 0x010Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x030Cu, 0x010Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0327u, 0x00C7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0307u, 0x1E0Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x030Cu, 0x010Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0323u, 0x1E0Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0327u, 0x1E10u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x032Du, 0x1E12u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0331u, 0x1E0Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0300u, 0x00C8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0301u, 0x00C9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0302u, 0x00CAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0303u, 0x1EBCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0304u, 0x0112u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0306u, 0x0114u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0307u, 0x0116u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0308u, 0x00CBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0309u, 0x1EBAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Cu, 0x011Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Fu, 0x0204u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0311u, 0x0206u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0323u, 0x1EB8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0327u, 0x0228u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0328u, 0x0118u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x032Du, 0x1E18u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0330u, 0x1E1Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0046u, 0x0307u, 0x1E1Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0301u, 0x01F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0302u, 0x011Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0304u, 0x1E20u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0306u, 0x011Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0307u, 0x0120u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x030Cu, 0x01E6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0327u, 0x0122u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0302u, 0x0124u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0307u, 0x1E22u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0308u, 0x1E26u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x030Cu, 0x021Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0323u, 0x1E24u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0327u, 0x1E28u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x032Eu, 0x1E2Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0300u, 0x00CCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0301u, 0x00CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0302u, 0x00CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0303u, 0x0128u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0304u, 0x012Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0306u, 0x012Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0307u, 0x0130u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0308u, 0x00CFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0309u, 0x1EC8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Cu, 0x01CFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Fu, 0x0208u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0311u, 0x020Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0323u, 0x1ECAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0328u, 0x012Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0330u, 0x1E2Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Au, 0x0302u, 0x0134u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0301u, 0x1E30u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x030Cu, 0x01E8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0323u, 0x1E32u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0327u, 0x0136u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0331u, 0x1E34u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0301u, 0x0139u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x030Cu, 0x013Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0323u, 0x1E36u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0327u, 0x013Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x032Du, 0x1E3Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0331u, 0x1E3Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0301u, 0x1E3Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0307u, 0x1E40u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0323u, 0x1E42u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0300u, 0x01F8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0301u, 0x0143u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0303u, 0x00D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0307u, 0x1E44u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x030Cu, 0x0147u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0323u, 0x1E46u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0327u, 0x0145u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x032Du, 0x1E4Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0331u, 0x1E48u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0300u, 0x00D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0301u, 0x00D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0302u, 0x00D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0303u, 0x00D5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0304u, 0x014Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0306u, 0x014Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0307u, 0x022Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0308u, 0x00D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0309u, 0x1ECEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Bu, 0x0150u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Cu, 0x01D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Fu, 0x020Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0311u, 0x020Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x031Bu, 0x01A0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0323u, 0x1ECCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0328u, 0x01EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0301u, 0x1E54u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0307u, 0x1E56u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0301u, 0x0154u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0307u, 0x1E58u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Cu, 0x0158u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Fu, 0x0210u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0311u, 0x0212u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0323u, 0x1E5Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0327u, 0x0156u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0331u, 0x1E5Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0301u, 0x015Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0302u, 0x015Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0307u, 0x1E60u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x030Cu, 0x0160u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0323u, 0x1E62u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0326u, 0x0218u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0327u, 0x015Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0307u, 0x1E6Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x030Cu, 0x0164u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0323u, 0x1E6Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0326u, 0x021Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0327u, 0x0162u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x032Du, 0x1E70u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0331u, 0x1E6Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0300u, 0x00D9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0301u, 0x00DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0302u, 0x00DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0303u, 0x0168u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0304u, 0x016Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0306u, 0x016Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0308u, 0x00DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0309u, 0x1EE6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Au, 0x016Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Bu, 0x0170u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Cu, 0x01D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Fu, 0x0214u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0311u, 0x0216u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x031Bu, 0x01AFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0323u, 0x1EE4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0324u, 0x1E72u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0328u, 0x0172u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x032Du, 0x1E76u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0330u, 0x1E74u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0303u, 0x1E7Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0323u, 0x1E7Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0300u, 0x1E80u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0301u, 0x1E82u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0302u, 0x0174u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0307u, 0x1E86u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0308u, 0x1E84u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0323u, 0x1E88u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0307u, 0x1E8Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0308u, 0x1E8Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0300u, 0x1EF2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0301u, 0x00DDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0302u, 0x0176u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0303u, 0x1EF8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0304u, 0x0232u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0307u, 0x1E8Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0308u, 0x0178u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0309u, 0x1EF6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0323u, 0x1EF4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0301u, 0x0179u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0302u, 0x1E90u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0307u, 0x017Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x030Cu, 0x017Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0323u, 0x1E92u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0331u, 0x1E94u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0300u, 0x00E0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0301u, 0x00E1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0302u, 0x00E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0303u, 0x00E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0304u, 0x0101u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0306u, 0x0103u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0307u, 0x0227u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0308u, 0x00E4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0309u, 0x1EA3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Au, 0x00E5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Cu, 0x01CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Fu, 0x0201u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0311u, 0x0203u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0323u, 0x1EA1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0325u, 0x1E01u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0328u, 0x0105u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0307u, 0x1E03u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0323u, 0x1E05u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0331u, 0x1E07u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0301u, 0x0107u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0302u, 0x0109u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0307u, 0x010Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x030Cu, 0x010Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0327u, 0x00E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0307u, 0x1E0Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x030Cu, 0x010Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0323u, 0x1E0Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0327u, 0x1E11u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x032Du, 0x1E13u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0331u, 0x1E0Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0300u, 0x00E8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0301u, 0x00E9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0302u, 0x00EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0303u, 0x1EBDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0304u, 0x0113u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0306u, 0x0115u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0307u, 0x0117u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0308u, 0x00EBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0309u, 0x1EBBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Cu, 0x011Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Fu, 0x0205u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0311u, 0x0207u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0323u, 0x1EB9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0327u, 0x0229u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0328u, 0x0119u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x032Du, 0x1E19u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0330u, 0x1E1Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0066u, 0x0307u, 0x1E1Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0301u, 0x01F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0302u, 0x011Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0304u, 0x1E21u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0306u, 0x011Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0307u, 0x0121u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x030Cu, 0x01E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0327u, 0x0123u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0302u, 0x0125u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0307u, 0x1E23u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0308u, 0x1E27u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x030Cu, 0x021Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0323u, 0x1E25u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0327u, 0x1E29u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x032Eu, 0x1E2Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0331u, 0x1E96u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0300u, 0x00ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0301u, 0x00EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0302u, 0x00EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0303u, 0x0129u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0304u, 0x012Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0306u, 0x012Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0308u, 0x00EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0309u, 0x1EC9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Cu, 0x01D0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Fu, 0x0209u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0311u, 0x020Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0323u, 0x1ECBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0328u, 0x012Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0330u, 0x1E2Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x0302u, 0x0135u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x030Cu, 0x01F0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0301u, 0x1E31u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x030Cu, 0x01E9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0323u, 0x1E33u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0327u, 0x0137u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0331u, 0x1E35u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0301u, 0x013Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x030Cu, 0x013Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0323u, 0x1E37u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0327u, 0x013Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x032Du, 0x1E3Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0331u, 0x1E3Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0301u, 0x1E3Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0307u, 0x1E41u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0323u, 0x1E43u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0300u, 0x01F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0301u, 0x0144u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0303u, 0x00F1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0307u, 0x1E45u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x030Cu, 0x0148u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0323u, 0x1E47u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0327u, 0x0146u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x032Du, 0x1E4Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0331u, 0x1E49u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0300u, 0x00F2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0301u, 0x00F3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0302u, 0x00F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0303u, 0x00F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0304u, 0x014Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0306u, 0x014Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0307u, 0x022Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0308u, 0x00F6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0309u, 0x1ECFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Bu, 0x0151u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Cu, 0x01D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Fu, 0x020Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0311u, 0x020Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x031Bu, 0x01A1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0323u, 0x1ECDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0328u, 0x01EBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0301u, 0x1E55u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0307u, 0x1E57u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0301u, 0x0155u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0307u, 0x1E59u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Cu, 0x0159u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Fu, 0x0211u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0311u, 0x0213u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0323u, 0x1E5Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0327u, 0x0157u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0331u, 0x1E5Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0301u, 0x015Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0302u, 0x015Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0307u, 0x1E61u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x030Cu, 0x0161u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0323u, 0x1E63u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0326u, 0x0219u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0327u, 0x015Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0307u, 0x1E6Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0308u, 0x1E97u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x030Cu, 0x0165u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0323u, 0x1E6Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0326u, 0x021Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0327u, 0x0163u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x032Du, 0x1E71u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0331u, 0x1E6Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0300u, 0x00F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0301u, 0x00FAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0302u, 0x00FBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0303u, 0x0169u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0304u, 0x016Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0306u, 0x016Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0308u, 0x00FCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0309u, 0x1EE7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Au, 0x016Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Bu, 0x0171u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Cu, 0x01D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Fu, 0x0215u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0311u, 0x0217u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x031Bu, 0x01B0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0323u, 0x1EE5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0324u, 0x1E73u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0328u, 0x0173u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x032Du, 0x1E77u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0330u, 0x1E75u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0303u, 0x1E7Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0323u, 0x1E7Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0300u, 0x1E81u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0301u, 0x1E83u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0302u, 0x0175u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0307u, 0x1E87u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0308u, 0x1E85u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x030Au, 0x1E98u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0323u, 0x1E89u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0307u, 0x1E8Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0308u, 0x1E8Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0300u, 0x1EF3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0301u, 0x00FDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0302u, 0x0177u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0303u, 0x1EF9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0304u, 0x0233u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0307u, 0x1E8Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0308u, 0x00FFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0309u, 0x1EF7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x030Au, 0x1E99u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0323u, 0x1EF5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0301u, 0x017Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0302u, 0x1E91u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0307u, 0x017Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x030Cu, 0x017Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0323u, 0x1E93u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0331u, 0x1E95u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0300u, 0x1FEDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0301u, 0x0385u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0342u, 0x1FC1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0300u, 0x1EA6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0301u, 0x1EA4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0303u, 0x1EAAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0309u, 0x1EA8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4u, 0x0304u, 0x01DEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5u, 0x0301u, 0x01FAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0301u, 0x01FCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0304u, 0x01E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7u, 0x0301u, 0x1E08u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0300u, 0x1EC0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0301u, 0x1EBEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0303u, 0x1EC4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0309u, 0x1EC2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00CFu, 0x0301u, 0x1E2Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0300u, 0x1ED2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0301u, 0x1ED0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0303u, 0x1ED6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0309u, 0x1ED4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0301u, 0x1E4Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0304u, 0x022Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0308u, 0x1E4Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6u, 0x0304u, 0x022Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8u, 0x0301u, 0x01FEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0300u, 0x01DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0301u, 0x01D7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0304u, 0x01D5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x030Cu, 0x01D9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0300u, 0x1EA7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0301u, 0x1EA5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0303u, 0x1EABu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0309u, 0x1EA9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4u, 0x0304u, 0x01DFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5u, 0x0301u, 0x01FBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0301u, 0x01FDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0304u, 0x01E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7u, 0x0301u, 0x1E09u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0300u, 0x1EC1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0301u, 0x1EBFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0303u, 0x1EC5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0309u, 0x1EC3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00EFu, 0x0301u, 0x1E2Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0300u, 0x1ED3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0301u, 0x1ED1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0303u, 0x1ED7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0309u, 0x1ED5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0301u, 0x1E4Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0304u, 0x022Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0308u, 0x1E4Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6u, 0x0304u, 0x022Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8u, 0x0301u, 0x01FFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0300u, 0x01DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0301u, 0x01D8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0304u, 0x01D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x030Cu, 0x01DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0300u, 0x1EB0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0301u, 0x1EAEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0303u, 0x1EB4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0309u, 0x1EB2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0300u, 0x1EB1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0301u, 0x1EAFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0303u, 0x1EB5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0309u, 0x1EB3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0300u, 0x1E14u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0301u, 0x1E16u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0300u, 0x1E15u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0301u, 0x1E17u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0300u, 0x1E50u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0301u, 0x1E52u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0300u, 0x1E51u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0301u, 0x1E53u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x015Au, 0x0307u, 0x1E64u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x015Bu, 0x0307u, 0x1E65u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0160u, 0x0307u, 0x1E66u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0161u, 0x0307u, 0x1E67u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0168u, 0x0301u, 0x1E78u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0169u, 0x0301u, 0x1E79u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x016Au, 0x0308u, 0x1E7Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x016Bu, 0x0308u, 0x1E7Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x017Fu, 0x0307u, 0x1E9Bu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0300u, 0x1EDCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0301u, 0x1EDAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0303u, 0x1EE0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0309u, 0x1EDEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0323u, 0x1EE2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0300u, 0x1EDDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0301u, 0x1EDBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0303u, 0x1EE1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0309u, 0x1EDFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0323u, 0x1EE3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0300u, 0x1EEAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0301u, 0x1EE8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0303u, 0x1EEEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0309u, 0x1EECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0323u, 0x1EF0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0300u, 0x1EEBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0301u, 0x1EE9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0303u, 0x1EEFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0309u, 0x1EEDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0323u, 0x1EF1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7u, 0x030Cu, 0x01EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01EAu, 0x0304u, 0x01ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x01EBu, 0x0304u, 0x01EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0226u, 0x0304u, 0x01E0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0227u, 0x0304u, 0x01E1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0228u, 0x0306u, 0x1E1Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0229u, 0x0306u, 0x1E1Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x022Eu, 0x0304u, 0x0230u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x022Fu, 0x0304u, 0x0231u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0292u, 0x030Cu, 0x01EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0308u, 0x0301u, 0x0000u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0300u, 0x1FBAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0301u, 0x0386u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0304u, 0x1FB9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0306u, 0x1FB8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0313u, 0x1F08u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0314u, 0x1F09u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0345u, 0x1FBCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0300u, 0x1FC8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0301u, 0x0388u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0313u, 0x1F18u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0314u, 0x1F19u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0300u, 0x1FCAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0301u, 0x0389u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0313u, 0x1F28u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0314u, 0x1F29u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0345u, 0x1FCCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0300u, 0x1FDAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0301u, 0x038Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0304u, 0x1FD9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0306u, 0x1FD8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0308u, 0x03AAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0313u, 0x1F38u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0314u, 0x1F39u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0300u, 0x1FF8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0301u, 0x038Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0313u, 0x1F48u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0314u, 0x1F49u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1u, 0x0314u, 0x1FECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0300u, 0x1FEAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0301u, 0x038Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0304u, 0x1FE9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0306u, 0x1FE8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0308u, 0x03ABu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0314u, 0x1F59u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0300u, 0x1FFAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0301u, 0x038Fu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0313u, 0x1F68u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0314u, 0x1F69u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0345u, 0x1FFCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03ACu, 0x0345u, 0x1FB4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03AEu, 0x0345u, 0x1FC4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0300u, 0x1F70u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0301u, 0x03ACu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0304u, 0x1FB1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0306u, 0x1FB0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0313u, 0x1F00u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0314u, 0x1F01u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0342u, 0x1FB6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0345u, 0x1FB3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0300u, 0x1F72u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0301u, 0x03ADu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0313u, 0x1F10u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0314u, 0x1F11u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0300u, 0x1F74u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0301u, 0x03AEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0313u, 0x1F20u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0314u, 0x1F21u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0342u, 0x1FC6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0345u, 0x1FC3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0300u, 0x1F76u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0301u, 0x03AFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0304u, 0x1FD1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0306u, 0x1FD0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0308u, 0x03CAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0313u, 0x1F30u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0314u, 0x1F31u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0342u, 0x1FD6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0300u, 0x1F78u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0301u, 0x03CCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0313u, 0x1F40u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0314u, 0x1F41u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0313u, 0x1FE4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0314u, 0x1FE5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0300u, 0x1F7Au), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0301u, 0x03CDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0304u, 0x1FE1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0306u, 0x1FE0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0308u, 0x03CBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0313u, 0x1F50u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0314u, 0x1F51u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0342u, 0x1FE6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0300u, 0x1F7Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0301u, 0x03CEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0313u, 0x1F60u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0314u, 0x1F61u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0342u, 0x1FF6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0345u, 0x1FF3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0300u, 0x1FD2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0301u, 0x0390u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0342u, 0x1FD7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0300u, 0x1FE2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0301u, 0x03B0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0342u, 0x1FE7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03CEu, 0x0345u, 0x1FF4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0301u, 0x03D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0308u, 0x03D4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0406u, 0x0308u, 0x0407u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0306u, 0x04D0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0308u, 0x04D2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0413u, 0x0301u, 0x0403u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0300u, 0x0400u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0306u, 0x04D6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0308u, 0x0401u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0306u, 0x04C1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0308u, 0x04DCu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0417u, 0x0308u, 0x04DEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0300u, 0x040Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0304u, 0x04E2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0306u, 0x0419u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0308u, 0x04E4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x041Au, 0x0301u, 0x040Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x041Eu, 0x0308u, 0x04E6u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0304u, 0x04EEu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0306u, 0x040Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0308u, 0x04F0u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x030Bu, 0x04F2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0427u, 0x0308u, 0x04F4u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x042Bu, 0x0308u, 0x04F8u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x042Du, 0x0308u, 0x04ECu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0306u, 0x04D1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0308u, 0x04D3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0433u, 0x0301u, 0x0453u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0300u, 0x0450u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0306u, 0x04D7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0308u, 0x0451u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0306u, 0x04C2u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0308u, 0x04DDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0437u, 0x0308u, 0x04DFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0300u, 0x045Du), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0304u, 0x04E3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0306u, 0x0439u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0308u, 0x04E5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x043Au, 0x0301u, 0x045Cu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x043Eu, 0x0308u, 0x04E7u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0304u, 0x04EFu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0306u, 0x045Eu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0308u, 0x04F1u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x030Bu, 0x04F3u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0447u, 0x0308u, 0x04F5u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x044Bu, 0x0308u, 0x04F9u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x044Du, 0x0308u, 0x04EDu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0456u, 0x0308u, 0x0457u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0474u, 0x030Fu, 0x0476u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x0475u, 0x030Fu, 0x0477u), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8u, 0x0308u, 0x04DAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9u, 0x0308u, 0x04DBu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8u, 0x0308u, 0x04EAu), - HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu), + HB_CODEPOINT_ENCODE3_11_7_14 (0x003C, 0x0338, 0x226E),HB_CODEPOINT_ENCODE3_11_7_14 (0x003D, 0x0338, 0x2260), + HB_CODEPOINT_ENCODE3_11_7_14 (0x003E, 0x0338, 0x226F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0300, 0x00C0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0301, 0x00C1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0302, 0x00C2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0303, 0x00C3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0304, 0x0100), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0306, 0x0102),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0307, 0x0226), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0308, 0x00C4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0309, 0x1EA2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030A, 0x00C5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030C, 0x01CD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x030F, 0x0200),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0311, 0x0202), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0323, 0x1EA0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0325, 0x1E00), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0041, 0x0328, 0x0104),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0307, 0x1E02), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0323, 0x1E04),HB_CODEPOINT_ENCODE3_11_7_14 (0x0042, 0x0331, 0x1E06), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0301, 0x0106),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0302, 0x0108), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0307, 0x010A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x030C, 0x010C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0043, 0x0327, 0x00C7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0307, 0x1E0A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x030C, 0x010E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0323, 0x1E0C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0327, 0x1E10),HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x032D, 0x1E12), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0044, 0x0331, 0x1E0E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0300, 0x00C8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0301, 0x00C9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0302, 0x00CA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0303, 0x1EBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0304, 0x0112), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0306, 0x0114),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0307, 0x0116), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0308, 0x00CB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0309, 0x1EBA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030C, 0x011A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x030F, 0x0204), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0311, 0x0206),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0323, 0x1EB8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0327, 0x0228),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0328, 0x0118), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x032D, 0x1E18),HB_CODEPOINT_ENCODE3_11_7_14 (0x0045, 0x0330, 0x1E1A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0046, 0x0307, 0x1E1E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0301, 0x01F4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0302, 0x011C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0304, 0x1E20), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0306, 0x011E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0307, 0x0120), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x030C, 0x01E6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0047, 0x0327, 0x0122), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0302, 0x0124),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0307, 0x1E22), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0308, 0x1E26),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x030C, 0x021E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0323, 0x1E24),HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x0327, 0x1E28), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0048, 0x032E, 0x1E2A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0300, 0x00CC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0301, 0x00CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0302, 0x00CE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0303, 0x0128),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0304, 0x012A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0306, 0x012C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0307, 0x0130), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0308, 0x00CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0309, 0x1EC8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030C, 0x01CF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x030F, 0x0208), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0311, 0x020A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0323, 0x1ECA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0328, 0x012E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0049, 0x0330, 0x1E2C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004A, 0x0302, 0x0134),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0301, 0x1E30), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x030C, 0x01E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0323, 0x1E32), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0327, 0x0136),HB_CODEPOINT_ENCODE3_11_7_14 (0x004B, 0x0331, 0x1E34), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0301, 0x0139),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x030C, 0x013D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0323, 0x1E36),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0327, 0x013B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x032D, 0x1E3C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004C, 0x0331, 0x1E3A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0301, 0x1E3E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0307, 0x1E40), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004D, 0x0323, 0x1E42),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0300, 0x01F8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0301, 0x0143),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0303, 0x00D1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0307, 0x1E44),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x030C, 0x0147), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0323, 0x1E46),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0327, 0x0145), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x032D, 0x1E4A),HB_CODEPOINT_ENCODE3_11_7_14 (0x004E, 0x0331, 0x1E48), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0300, 0x00D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0301, 0x00D3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0302, 0x00D4),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0303, 0x00D5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0304, 0x014C),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0306, 0x014E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0307, 0x022E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0308, 0x00D6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0309, 0x1ECE),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030B, 0x0150), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030C, 0x01D1),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x030F, 0x020C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0311, 0x020E),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x031B, 0x01A0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0323, 0x1ECC),HB_CODEPOINT_ENCODE3_11_7_14 (0x004F, 0x0328, 0x01EA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0301, 0x1E54),HB_CODEPOINT_ENCODE3_11_7_14 (0x0050, 0x0307, 0x1E56), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0301, 0x0154),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0307, 0x1E58), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030C, 0x0158),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x030F, 0x0210), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0311, 0x0212),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0323, 0x1E5A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0327, 0x0156),HB_CODEPOINT_ENCODE3_11_7_14 (0x0052, 0x0331, 0x1E5E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0301, 0x015A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0302, 0x015C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0307, 0x1E60),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x030C, 0x0160), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0323, 0x1E62),HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0326, 0x0218), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0053, 0x0327, 0x015E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0307, 0x1E6A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x030C, 0x0164),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0323, 0x1E6C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0326, 0x021A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0327, 0x0162), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x032D, 0x1E70),HB_CODEPOINT_ENCODE3_11_7_14 (0x0054, 0x0331, 0x1E6E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0300, 0x00D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0301, 0x00DA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0302, 0x00DB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0303, 0x0168), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0304, 0x016A),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0306, 0x016C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0308, 0x00DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0309, 0x1EE6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030A, 0x016E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030B, 0x0170), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030C, 0x01D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x030F, 0x0214), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0311, 0x0216),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x031B, 0x01AF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0323, 0x1EE4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0324, 0x1E72), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0328, 0x0172),HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x032D, 0x1E76), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0055, 0x0330, 0x1E74),HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0303, 0x1E7C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0056, 0x0323, 0x1E7E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0300, 0x1E80), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0301, 0x1E82),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0302, 0x0174), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0307, 0x1E86),HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0308, 0x1E84), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0057, 0x0323, 0x1E88),HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0307, 0x1E8A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0058, 0x0308, 0x1E8C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0300, 0x1EF2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0301, 0x00DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0302, 0x0176), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0303, 0x1EF8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0304, 0x0232), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0307, 0x1E8E),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0308, 0x0178), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0309, 0x1EF6),HB_CODEPOINT_ENCODE3_11_7_14 (0x0059, 0x0323, 0x1EF4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0301, 0x0179),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0302, 0x1E90), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0307, 0x017B),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x030C, 0x017D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0323, 0x1E92),HB_CODEPOINT_ENCODE3_11_7_14 (0x005A, 0x0331, 0x1E94), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0300, 0x00E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0301, 0x00E1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0302, 0x00E2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0303, 0x00E3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0304, 0x0101),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0306, 0x0103), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0307, 0x0227),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0308, 0x00E4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0309, 0x1EA3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030A, 0x00E5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030C, 0x01CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x030F, 0x0201), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0311, 0x0203),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0323, 0x1EA1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0325, 0x1E01),HB_CODEPOINT_ENCODE3_11_7_14 (0x0061, 0x0328, 0x0105), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0307, 0x1E03),HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0323, 0x1E05), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0062, 0x0331, 0x1E07),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0301, 0x0107), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0302, 0x0109),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0307, 0x010B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x030C, 0x010D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0063, 0x0327, 0x00E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0307, 0x1E0B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x030C, 0x010F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0323, 0x1E0D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0327, 0x1E11), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x032D, 0x1E13),HB_CODEPOINT_ENCODE3_11_7_14 (0x0064, 0x0331, 0x1E0F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0300, 0x00E8),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0301, 0x00E9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0302, 0x00EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0303, 0x1EBD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0304, 0x0113),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0306, 0x0115), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0307, 0x0117),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0308, 0x00EB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0309, 0x1EBB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030C, 0x011B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x030F, 0x0205),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0311, 0x0207), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0323, 0x1EB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0327, 0x0229), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0328, 0x0119),HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x032D, 0x1E19), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0065, 0x0330, 0x1E1B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0066, 0x0307, 0x1E1F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0301, 0x01F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0302, 0x011D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0304, 0x1E21),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0306, 0x011F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0307, 0x0121),HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x030C, 0x01E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0067, 0x0327, 0x0123),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0302, 0x0125), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0307, 0x1E23),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0308, 0x1E27), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x030C, 0x021F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0323, 0x1E25), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0327, 0x1E29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x032E, 0x1E2B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0068, 0x0331, 0x1E96),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0300, 0x00EC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0301, 0x00ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0302, 0x00EE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0303, 0x0129),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0304, 0x012B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0306, 0x012D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0308, 0x00EF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0309, 0x1EC9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030C, 0x01D0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x030F, 0x0209),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0311, 0x020B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0323, 0x1ECB),HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0328, 0x012F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0069, 0x0330, 0x1E2D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x0302, 0x0135), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006A, 0x030C, 0x01F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0301, 0x1E31), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x030C, 0x01E9),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0323, 0x1E33), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0327, 0x0137),HB_CODEPOINT_ENCODE3_11_7_14 (0x006B, 0x0331, 0x1E35), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0301, 0x013A),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x030C, 0x013E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0323, 0x1E37),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0327, 0x013C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x032D, 0x1E3D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006C, 0x0331, 0x1E3B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0301, 0x1E3F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0307, 0x1E41), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006D, 0x0323, 0x1E43),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0300, 0x01F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0301, 0x0144),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0303, 0x00F1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0307, 0x1E45),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x030C, 0x0148), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0323, 0x1E47),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0327, 0x0146), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x032D, 0x1E4B),HB_CODEPOINT_ENCODE3_11_7_14 (0x006E, 0x0331, 0x1E49), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0300, 0x00F2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0301, 0x00F3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0302, 0x00F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0303, 0x00F5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0304, 0x014D),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0306, 0x014F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0307, 0x022F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0308, 0x00F6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0309, 0x1ECF),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030B, 0x0151), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030C, 0x01D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x030F, 0x020D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0311, 0x020F),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x031B, 0x01A1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0323, 0x1ECD),HB_CODEPOINT_ENCODE3_11_7_14 (0x006F, 0x0328, 0x01EB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0301, 0x1E55),HB_CODEPOINT_ENCODE3_11_7_14 (0x0070, 0x0307, 0x1E57), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0301, 0x0155),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0307, 0x1E59), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030C, 0x0159),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x030F, 0x0211), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0311, 0x0213),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0323, 0x1E5B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0327, 0x0157),HB_CODEPOINT_ENCODE3_11_7_14 (0x0072, 0x0331, 0x1E5F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0301, 0x015B),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0302, 0x015D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0307, 0x1E61),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x030C, 0x0161), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0323, 0x1E63),HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0326, 0x0219), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0073, 0x0327, 0x015F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0307, 0x1E6B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0308, 0x1E97),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x030C, 0x0165), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0323, 0x1E6D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0326, 0x021B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0327, 0x0163),HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x032D, 0x1E71), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0074, 0x0331, 0x1E6F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0300, 0x00F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0301, 0x00FA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0302, 0x00FB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0303, 0x0169),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0304, 0x016B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0306, 0x016D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0308, 0x00FC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0309, 0x1EE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030A, 0x016F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030B, 0x0171),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030C, 0x01D4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x030F, 0x0215),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0311, 0x0217), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x031B, 0x01B0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0323, 0x1EE5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0324, 0x1E73),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0328, 0x0173), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x032D, 0x1E77),HB_CODEPOINT_ENCODE3_11_7_14 (0x0075, 0x0330, 0x1E75), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0303, 0x1E7D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0076, 0x0323, 0x1E7F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0300, 0x1E81),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0301, 0x1E83), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0302, 0x0175),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0307, 0x1E87), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0308, 0x1E85),HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x030A, 0x1E98), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0077, 0x0323, 0x1E89),HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0307, 0x1E8B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0078, 0x0308, 0x1E8D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0300, 0x1EF3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0301, 0x00FD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0302, 0x0177), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0303, 0x1EF9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0304, 0x0233), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0307, 0x1E8F),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0308, 0x00FF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0309, 0x1EF7),HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x030A, 0x1E99), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0079, 0x0323, 0x1EF5),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0301, 0x017A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0302, 0x1E91),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0307, 0x017C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x030C, 0x017E),HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0323, 0x1E93), + HB_CODEPOINT_ENCODE3_11_7_14 (0x007A, 0x0331, 0x1E95),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0300, 0x1FED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0301, 0x0385),HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8, 0x0342, 0x1FC1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0300, 0x1EA6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0301, 0x1EA4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0303, 0x1EAA),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2, 0x0309, 0x1EA8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4, 0x0304, 0x01DE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5, 0x0301, 0x01FA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0301, 0x01FC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6, 0x0304, 0x01E2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7, 0x0301, 0x1E08),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0300, 0x1EC0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0301, 0x1EBE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0303, 0x1EC4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00CA, 0x0309, 0x1EC2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00CF, 0x0301, 0x1E2E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0300, 0x1ED2),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0301, 0x1ED0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0303, 0x1ED6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4, 0x0309, 0x1ED4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0301, 0x1E4C),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0304, 0x022C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5, 0x0308, 0x1E4E),HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6, 0x0304, 0x022A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8, 0x0301, 0x01FE),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0300, 0x01DB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0301, 0x01D7),HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x0304, 0x01D5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00DC, 0x030C, 0x01D9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0300, 0x1EA7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0301, 0x1EA5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0303, 0x1EAB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2, 0x0309, 0x1EA9),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4, 0x0304, 0x01DF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5, 0x0301, 0x01FB),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0301, 0x01FD), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6, 0x0304, 0x01E3),HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7, 0x0301, 0x1E09), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0300, 0x1EC1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0301, 0x1EBF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0303, 0x1EC5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00EA, 0x0309, 0x1EC3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00EF, 0x0301, 0x1E2F),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0300, 0x1ED3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0301, 0x1ED1),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0303, 0x1ED7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4, 0x0309, 0x1ED5),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0301, 0x1E4D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0304, 0x022D),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5, 0x0308, 0x1E4F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6, 0x0304, 0x022B),HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8, 0x0301, 0x01FF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0300, 0x01DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0301, 0x01D8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x0304, 0x01D6),HB_CODEPOINT_ENCODE3_11_7_14 (0x00FC, 0x030C, 0x01DA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0300, 0x1EB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0301, 0x1EAE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0303, 0x1EB4),HB_CODEPOINT_ENCODE3_11_7_14 (0x0102, 0x0309, 0x1EB2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0300, 0x1EB1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0301, 0x1EAF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0303, 0x1EB5),HB_CODEPOINT_ENCODE3_11_7_14 (0x0103, 0x0309, 0x1EB3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0300, 0x1E14),HB_CODEPOINT_ENCODE3_11_7_14 (0x0112, 0x0301, 0x1E16), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0300, 0x1E15),HB_CODEPOINT_ENCODE3_11_7_14 (0x0113, 0x0301, 0x1E17), + HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0300, 0x1E50),HB_CODEPOINT_ENCODE3_11_7_14 (0x014C, 0x0301, 0x1E52), + HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0300, 0x1E51),HB_CODEPOINT_ENCODE3_11_7_14 (0x014D, 0x0301, 0x1E53), + HB_CODEPOINT_ENCODE3_11_7_14 (0x015A, 0x0307, 0x1E64),HB_CODEPOINT_ENCODE3_11_7_14 (0x015B, 0x0307, 0x1E65), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0160, 0x0307, 0x1E66),HB_CODEPOINT_ENCODE3_11_7_14 (0x0161, 0x0307, 0x1E67), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0168, 0x0301, 0x1E78),HB_CODEPOINT_ENCODE3_11_7_14 (0x0169, 0x0301, 0x1E79), + HB_CODEPOINT_ENCODE3_11_7_14 (0x016A, 0x0308, 0x1E7A),HB_CODEPOINT_ENCODE3_11_7_14 (0x016B, 0x0308, 0x1E7B), + HB_CODEPOINT_ENCODE3_11_7_14 (0x017F, 0x0307, 0x1E9B),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0300, 0x1EDC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0301, 0x1EDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0303, 0x1EE0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0309, 0x1EDE),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0, 0x0323, 0x1EE2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0300, 0x1EDD),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0301, 0x1EDB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0303, 0x1EE1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0309, 0x1EDF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1, 0x0323, 0x1EE3),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0300, 0x1EEA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0301, 0x1EE8),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0303, 0x1EEE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0309, 0x1EEC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01AF, 0x0323, 0x1EF0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0300, 0x1EEB),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0301, 0x1EE9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0303, 0x1EEF),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0309, 0x1EED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0, 0x0323, 0x1EF1),HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7, 0x030C, 0x01EE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x01EA, 0x0304, 0x01EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x01EB, 0x0304, 0x01ED), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0226, 0x0304, 0x01E0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0227, 0x0304, 0x01E1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0228, 0x0306, 0x1E1C),HB_CODEPOINT_ENCODE3_11_7_14 (0x0229, 0x0306, 0x1E1D), + HB_CODEPOINT_ENCODE3_11_7_14 (0x022E, 0x0304, 0x0230),HB_CODEPOINT_ENCODE3_11_7_14 (0x022F, 0x0304, 0x0231), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0292, 0x030C, 0x01EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0308, 0x0301, 0x0000), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0300, 0x1FBA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0301, 0x0386), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0304, 0x1FB9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0306, 0x1FB8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0313, 0x1F08),HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0314, 0x1F09), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0391, 0x0345, 0x1FBC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0300, 0x1FC8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0301, 0x0388),HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0313, 0x1F18), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0395, 0x0314, 0x1F19),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0300, 0x1FCA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0301, 0x0389),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0313, 0x1F28), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0314, 0x1F29),HB_CODEPOINT_ENCODE3_11_7_14 (0x0397, 0x0345, 0x1FCC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0300, 0x1FDA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0301, 0x038A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0304, 0x1FD9),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0306, 0x1FD8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0308, 0x03AA),HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0313, 0x1F38), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0399, 0x0314, 0x1F39),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0300, 0x1FF8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0301, 0x038C),HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0313, 0x1F48), + HB_CODEPOINT_ENCODE3_11_7_14 (0x039F, 0x0314, 0x1F49),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1, 0x0314, 0x1FEC), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0300, 0x1FEA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0301, 0x038E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0304, 0x1FE9),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0306, 0x1FE8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0308, 0x03AB),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5, 0x0314, 0x1F59), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0300, 0x1FFA),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0301, 0x038F), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0313, 0x1F68),HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0314, 0x1F69), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9, 0x0345, 0x1FFC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03AC, 0x0345, 0x1FB4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03AE, 0x0345, 0x1FC4),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0300, 0x1F70), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0301, 0x03AC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0304, 0x1FB1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0306, 0x1FB0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0313, 0x1F00), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0314, 0x1F01),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0342, 0x1FB6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1, 0x0345, 0x1FB3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0300, 0x1F72), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0301, 0x03AD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0313, 0x1F10), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5, 0x0314, 0x1F11),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0300, 0x1F74), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0301, 0x03AE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0313, 0x1F20), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0314, 0x1F21),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0342, 0x1FC6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7, 0x0345, 0x1FC3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0300, 0x1F76), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0301, 0x03AF),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0304, 0x1FD1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0306, 0x1FD0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0308, 0x03CA), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0313, 0x1F30),HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0314, 0x1F31), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9, 0x0342, 0x1FD6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0300, 0x1F78), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0301, 0x03CC),HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0313, 0x1F40), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03BF, 0x0314, 0x1F41),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0313, 0x1FE4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1, 0x0314, 0x1FE5),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0300, 0x1F7A), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0301, 0x03CD),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0304, 0x1FE1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0306, 0x1FE0),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0308, 0x03CB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0313, 0x1F50),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0314, 0x1F51), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5, 0x0342, 0x1FE6),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0300, 0x1F7C), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0301, 0x03CE),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0313, 0x1F60), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0314, 0x1F61),HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0342, 0x1FF6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9, 0x0345, 0x1FF3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0300, 0x1FD2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0301, 0x0390),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CA, 0x0342, 0x1FD7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0300, 0x1FE2),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0301, 0x03B0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03CB, 0x0342, 0x1FE7),HB_CODEPOINT_ENCODE3_11_7_14 (0x03CE, 0x0345, 0x1FF4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0301, 0x03D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2, 0x0308, 0x03D4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0406, 0x0308, 0x0407),HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0306, 0x04D0), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0410, 0x0308, 0x04D2),HB_CODEPOINT_ENCODE3_11_7_14 (0x0413, 0x0301, 0x0403), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0300, 0x0400),HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0306, 0x04D6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0415, 0x0308, 0x0401),HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0306, 0x04C1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0416, 0x0308, 0x04DC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0417, 0x0308, 0x04DE), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0300, 0x040D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0304, 0x04E2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0306, 0x0419),HB_CODEPOINT_ENCODE3_11_7_14 (0x0418, 0x0308, 0x04E4), + HB_CODEPOINT_ENCODE3_11_7_14 (0x041A, 0x0301, 0x040C),HB_CODEPOINT_ENCODE3_11_7_14 (0x041E, 0x0308, 0x04E6), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0304, 0x04EE),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0306, 0x040E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x0308, 0x04F0),HB_CODEPOINT_ENCODE3_11_7_14 (0x0423, 0x030B, 0x04F2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0427, 0x0308, 0x04F4),HB_CODEPOINT_ENCODE3_11_7_14 (0x042B, 0x0308, 0x04F8), + HB_CODEPOINT_ENCODE3_11_7_14 (0x042D, 0x0308, 0x04EC),HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0306, 0x04D1), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0430, 0x0308, 0x04D3),HB_CODEPOINT_ENCODE3_11_7_14 (0x0433, 0x0301, 0x0453), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0300, 0x0450),HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0306, 0x04D7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0435, 0x0308, 0x0451),HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0306, 0x04C2), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0436, 0x0308, 0x04DD),HB_CODEPOINT_ENCODE3_11_7_14 (0x0437, 0x0308, 0x04DF), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0300, 0x045D),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0304, 0x04E3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0306, 0x0439),HB_CODEPOINT_ENCODE3_11_7_14 (0x0438, 0x0308, 0x04E5), + HB_CODEPOINT_ENCODE3_11_7_14 (0x043A, 0x0301, 0x045C),HB_CODEPOINT_ENCODE3_11_7_14 (0x043E, 0x0308, 0x04E7), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0304, 0x04EF),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0306, 0x045E), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x0308, 0x04F1),HB_CODEPOINT_ENCODE3_11_7_14 (0x0443, 0x030B, 0x04F3), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0447, 0x0308, 0x04F5),HB_CODEPOINT_ENCODE3_11_7_14 (0x044B, 0x0308, 0x04F9), + HB_CODEPOINT_ENCODE3_11_7_14 (0x044D, 0x0308, 0x04ED),HB_CODEPOINT_ENCODE3_11_7_14 (0x0456, 0x0308, 0x0457), + HB_CODEPOINT_ENCODE3_11_7_14 (0x0474, 0x030F, 0x0476),HB_CODEPOINT_ENCODE3_11_7_14 (0x0475, 0x030F, 0x0477), + HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8, 0x0308, 0x04DA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9, 0x0308, 0x04DB), + HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8, 0x0308, 0x04EA),HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9, 0x0308, 0x04EB), }; -static const uint64_t -_hb_ucd_dm2_u64_map[408] = +static const uint64_t _hb_ucd_dm2_u64_map[408]= { - HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D2u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D3u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D4u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05B9u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D8u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05B4u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BFu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05DCu, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05DEu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E0u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E1u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E3u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BFu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E6u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E7u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E8u, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C2u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x05EAu, 0x05BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x05F2u, 0x05B7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0627u, 0x0653u, 0x0622u), HB_CODEPOINT_ENCODE3 (0x0627u, 0x0654u, 0x0623u), - HB_CODEPOINT_ENCODE3 (0x0627u, 0x0655u, 0x0625u), HB_CODEPOINT_ENCODE3 (0x0648u, 0x0654u, 0x0624u), - HB_CODEPOINT_ENCODE3 (0x064Au, 0x0654u, 0x0626u), HB_CODEPOINT_ENCODE3 (0x06C1u, 0x0654u, 0x06C2u), - HB_CODEPOINT_ENCODE3 (0x06D2u, 0x0654u, 0x06D3u), HB_CODEPOINT_ENCODE3 (0x06D5u, 0x0654u, 0x06C0u), - HB_CODEPOINT_ENCODE3 (0x0915u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0916u, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0917u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x091Cu, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0921u, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0922u, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0928u, 0x093Cu, 0x0929u), HB_CODEPOINT_ENCODE3 (0x092Bu, 0x093Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x092Fu, 0x093Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0930u, 0x093Cu, 0x0931u), - HB_CODEPOINT_ENCODE3 (0x0933u, 0x093Cu, 0x0934u), HB_CODEPOINT_ENCODE3 (0x09A1u, 0x09BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x09A2u, 0x09BCu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x09AFu, 0x09BCu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09BEu, 0x09CBu), HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09D7u, 0x09CCu), - HB_CODEPOINT_ENCODE3 (0x0A16u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A17u, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0A1Cu, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A2Bu, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0A32u, 0x0A3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0A38u, 0x0A3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0B21u, 0x0B3Cu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0B22u, 0x0B3Cu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B3Eu, 0x0B4Bu), HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B56u, 0x0B48u), - HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B57u, 0x0B4Cu), HB_CODEPOINT_ENCODE3 (0x0B92u, 0x0BD7u, 0x0B94u), - HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BBEu, 0x0BCAu), HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BD7u, 0x0BCCu), - HB_CODEPOINT_ENCODE3 (0x0BC7u, 0x0BBEu, 0x0BCBu), HB_CODEPOINT_ENCODE3 (0x0C46u, 0x0C56u, 0x0C48u), - HB_CODEPOINT_ENCODE3 (0x0CBFu, 0x0CD5u, 0x0CC0u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CC2u, 0x0CCAu), - HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD5u, 0x0CC7u), HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD6u, 0x0CC8u), - HB_CODEPOINT_ENCODE3 (0x0CCAu, 0x0CD5u, 0x0CCBu), HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D3Eu, 0x0D4Au), - HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D57u, 0x0D4Cu), HB_CODEPOINT_ENCODE3 (0x0D47u, 0x0D3Eu, 0x0D4Bu), - HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCAu, 0x0DDAu), HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCFu, 0x0DDCu), - HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DDFu, 0x0DDEu), HB_CODEPOINT_ENCODE3 (0x0DDCu, 0x0DCAu, 0x0DDDu), - HB_CODEPOINT_ENCODE3 (0x0F40u, 0x0FB5u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F42u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F4Cu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F51u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F56u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F5Bu, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F72u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F74u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F90u, 0x0FB5u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0F92u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0F9Cu, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FA1u, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FA6u, 0x0FB7u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FABu, 0x0FB7u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x0FB2u, 0x0F80u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x0FB3u, 0x0F80u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1025u, 0x102Eu, 0x1026u), - HB_CODEPOINT_ENCODE3 (0x1B05u, 0x1B35u, 0x1B06u), HB_CODEPOINT_ENCODE3 (0x1B07u, 0x1B35u, 0x1B08u), - HB_CODEPOINT_ENCODE3 (0x1B09u, 0x1B35u, 0x1B0Au), HB_CODEPOINT_ENCODE3 (0x1B0Bu, 0x1B35u, 0x1B0Cu), - HB_CODEPOINT_ENCODE3 (0x1B0Du, 0x1B35u, 0x1B0Eu), HB_CODEPOINT_ENCODE3 (0x1B11u, 0x1B35u, 0x1B12u), - HB_CODEPOINT_ENCODE3 (0x1B3Au, 0x1B35u, 0x1B3Bu), HB_CODEPOINT_ENCODE3 (0x1B3Cu, 0x1B35u, 0x1B3Du), - HB_CODEPOINT_ENCODE3 (0x1B3Eu, 0x1B35u, 0x1B40u), HB_CODEPOINT_ENCODE3 (0x1B3Fu, 0x1B35u, 0x1B41u), - HB_CODEPOINT_ENCODE3 (0x1B42u, 0x1B35u, 0x1B43u), HB_CODEPOINT_ENCODE3 (0x1E36u, 0x0304u, 0x1E38u), - HB_CODEPOINT_ENCODE3 (0x1E37u, 0x0304u, 0x1E39u), HB_CODEPOINT_ENCODE3 (0x1E5Au, 0x0304u, 0x1E5Cu), - HB_CODEPOINT_ENCODE3 (0x1E5Bu, 0x0304u, 0x1E5Du), HB_CODEPOINT_ENCODE3 (0x1E62u, 0x0307u, 0x1E68u), - HB_CODEPOINT_ENCODE3 (0x1E63u, 0x0307u, 0x1E69u), HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0302u, 0x1EACu), - HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0306u, 0x1EB6u), HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0302u, 0x1EADu), - HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0306u, 0x1EB7u), HB_CODEPOINT_ENCODE3 (0x1EB8u, 0x0302u, 0x1EC6u), - HB_CODEPOINT_ENCODE3 (0x1EB9u, 0x0302u, 0x1EC7u), HB_CODEPOINT_ENCODE3 (0x1ECCu, 0x0302u, 0x1ED8u), - HB_CODEPOINT_ENCODE3 (0x1ECDu, 0x0302u, 0x1ED9u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0300u, 0x1F02u), - HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0301u, 0x1F04u), HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0342u, 0x1F06u), - HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0345u, 0x1F80u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0300u, 0x1F03u), - HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0301u, 0x1F05u), HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0342u, 0x1F07u), - HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0345u, 0x1F81u), HB_CODEPOINT_ENCODE3 (0x1F02u, 0x0345u, 0x1F82u), - HB_CODEPOINT_ENCODE3 (0x1F03u, 0x0345u, 0x1F83u), HB_CODEPOINT_ENCODE3 (0x1F04u, 0x0345u, 0x1F84u), - HB_CODEPOINT_ENCODE3 (0x1F05u, 0x0345u, 0x1F85u), HB_CODEPOINT_ENCODE3 (0x1F06u, 0x0345u, 0x1F86u), - HB_CODEPOINT_ENCODE3 (0x1F07u, 0x0345u, 0x1F87u), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0300u, 0x1F0Au), - HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0301u, 0x1F0Cu), HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0342u, 0x1F0Eu), - HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0345u, 0x1F88u), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0300u, 0x1F0Bu), - HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0301u, 0x1F0Du), HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0342u, 0x1F0Fu), - HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0345u, 0x1F89u), HB_CODEPOINT_ENCODE3 (0x1F0Au, 0x0345u, 0x1F8Au), - HB_CODEPOINT_ENCODE3 (0x1F0Bu, 0x0345u, 0x1F8Bu), HB_CODEPOINT_ENCODE3 (0x1F0Cu, 0x0345u, 0x1F8Cu), - HB_CODEPOINT_ENCODE3 (0x1F0Du, 0x0345u, 0x1F8Du), HB_CODEPOINT_ENCODE3 (0x1F0Eu, 0x0345u, 0x1F8Eu), - HB_CODEPOINT_ENCODE3 (0x1F0Fu, 0x0345u, 0x1F8Fu), HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0300u, 0x1F12u), - HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0301u, 0x1F14u), HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0300u, 0x1F13u), - HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0301u, 0x1F15u), HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0300u, 0x1F1Au), - HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0301u, 0x1F1Cu), HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0300u, 0x1F1Bu), - HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0301u, 0x1F1Du), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0300u, 0x1F22u), - HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0301u, 0x1F24u), HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0342u, 0x1F26u), - HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0345u, 0x1F90u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0300u, 0x1F23u), - HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0301u, 0x1F25u), HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0342u, 0x1F27u), - HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0345u, 0x1F91u), HB_CODEPOINT_ENCODE3 (0x1F22u, 0x0345u, 0x1F92u), - HB_CODEPOINT_ENCODE3 (0x1F23u, 0x0345u, 0x1F93u), HB_CODEPOINT_ENCODE3 (0x1F24u, 0x0345u, 0x1F94u), - HB_CODEPOINT_ENCODE3 (0x1F25u, 0x0345u, 0x1F95u), HB_CODEPOINT_ENCODE3 (0x1F26u, 0x0345u, 0x1F96u), - HB_CODEPOINT_ENCODE3 (0x1F27u, 0x0345u, 0x1F97u), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0300u, 0x1F2Au), - HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0301u, 0x1F2Cu), HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0342u, 0x1F2Eu), - HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0345u, 0x1F98u), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0300u, 0x1F2Bu), - HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0301u, 0x1F2Du), HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0342u, 0x1F2Fu), - HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0345u, 0x1F99u), HB_CODEPOINT_ENCODE3 (0x1F2Au, 0x0345u, 0x1F9Au), - HB_CODEPOINT_ENCODE3 (0x1F2Bu, 0x0345u, 0x1F9Bu), HB_CODEPOINT_ENCODE3 (0x1F2Cu, 0x0345u, 0x1F9Cu), - HB_CODEPOINT_ENCODE3 (0x1F2Du, 0x0345u, 0x1F9Du), HB_CODEPOINT_ENCODE3 (0x1F2Eu, 0x0345u, 0x1F9Eu), - HB_CODEPOINT_ENCODE3 (0x1F2Fu, 0x0345u, 0x1F9Fu), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0300u, 0x1F32u), - HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0301u, 0x1F34u), HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0342u, 0x1F36u), - HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0300u, 0x1F33u), HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0301u, 0x1F35u), - HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0342u, 0x1F37u), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0300u, 0x1F3Au), - HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0301u, 0x1F3Cu), HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0342u, 0x1F3Eu), - HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0300u, 0x1F3Bu), HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0301u, 0x1F3Du), - HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0342u, 0x1F3Fu), HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0300u, 0x1F42u), - HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0301u, 0x1F44u), HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0300u, 0x1F43u), - HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0301u, 0x1F45u), HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0300u, 0x1F4Au), - HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0301u, 0x1F4Cu), HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0300u, 0x1F4Bu), - HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0301u, 0x1F4Du), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0300u, 0x1F52u), - HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0301u, 0x1F54u), HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0342u, 0x1F56u), - HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0300u, 0x1F53u), HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0301u, 0x1F55u), - HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0342u, 0x1F57u), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0300u, 0x1F5Bu), - HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0301u, 0x1F5Du), HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0342u, 0x1F5Fu), - HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0300u, 0x1F62u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0301u, 0x1F64u), - HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0342u, 0x1F66u), HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0345u, 0x1FA0u), - HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0300u, 0x1F63u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0301u, 0x1F65u), - HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0342u, 0x1F67u), HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0345u, 0x1FA1u), - HB_CODEPOINT_ENCODE3 (0x1F62u, 0x0345u, 0x1FA2u), HB_CODEPOINT_ENCODE3 (0x1F63u, 0x0345u, 0x1FA3u), - HB_CODEPOINT_ENCODE3 (0x1F64u, 0x0345u, 0x1FA4u), HB_CODEPOINT_ENCODE3 (0x1F65u, 0x0345u, 0x1FA5u), - HB_CODEPOINT_ENCODE3 (0x1F66u, 0x0345u, 0x1FA6u), HB_CODEPOINT_ENCODE3 (0x1F67u, 0x0345u, 0x1FA7u), - HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0300u, 0x1F6Au), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0301u, 0x1F6Cu), - HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0342u, 0x1F6Eu), HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0345u, 0x1FA8u), - HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0300u, 0x1F6Bu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0301u, 0x1F6Du), - HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0342u, 0x1F6Fu), HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0345u, 0x1FA9u), - HB_CODEPOINT_ENCODE3 (0x1F6Au, 0x0345u, 0x1FAAu), HB_CODEPOINT_ENCODE3 (0x1F6Bu, 0x0345u, 0x1FABu), - HB_CODEPOINT_ENCODE3 (0x1F6Cu, 0x0345u, 0x1FACu), HB_CODEPOINT_ENCODE3 (0x1F6Du, 0x0345u, 0x1FADu), - HB_CODEPOINT_ENCODE3 (0x1F6Eu, 0x0345u, 0x1FAEu), HB_CODEPOINT_ENCODE3 (0x1F6Fu, 0x0345u, 0x1FAFu), - HB_CODEPOINT_ENCODE3 (0x1F70u, 0x0345u, 0x1FB2u), HB_CODEPOINT_ENCODE3 (0x1F74u, 0x0345u, 0x1FC2u), - HB_CODEPOINT_ENCODE3 (0x1F7Cu, 0x0345u, 0x1FF2u), HB_CODEPOINT_ENCODE3 (0x1FB6u, 0x0345u, 0x1FB7u), - HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0300u, 0x1FCDu), HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0301u, 0x1FCEu), - HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0342u, 0x1FCFu), HB_CODEPOINT_ENCODE3 (0x1FC6u, 0x0345u, 0x1FC7u), - HB_CODEPOINT_ENCODE3 (0x1FF6u, 0x0345u, 0x1FF7u), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0300u, 0x1FDDu), - HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0301u, 0x1FDEu), HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0342u, 0x1FDFu), - HB_CODEPOINT_ENCODE3 (0x2190u, 0x0338u, 0x219Au), HB_CODEPOINT_ENCODE3 (0x2192u, 0x0338u, 0x219Bu), - HB_CODEPOINT_ENCODE3 (0x2194u, 0x0338u, 0x21AEu), HB_CODEPOINT_ENCODE3 (0x21D0u, 0x0338u, 0x21CDu), - HB_CODEPOINT_ENCODE3 (0x21D2u, 0x0338u, 0x21CFu), HB_CODEPOINT_ENCODE3 (0x21D4u, 0x0338u, 0x21CEu), - HB_CODEPOINT_ENCODE3 (0x2203u, 0x0338u, 0x2204u), HB_CODEPOINT_ENCODE3 (0x2208u, 0x0338u, 0x2209u), - HB_CODEPOINT_ENCODE3 (0x220Bu, 0x0338u, 0x220Cu), HB_CODEPOINT_ENCODE3 (0x2223u, 0x0338u, 0x2224u), - HB_CODEPOINT_ENCODE3 (0x2225u, 0x0338u, 0x2226u), HB_CODEPOINT_ENCODE3 (0x223Cu, 0x0338u, 0x2241u), - HB_CODEPOINT_ENCODE3 (0x2243u, 0x0338u, 0x2244u), HB_CODEPOINT_ENCODE3 (0x2245u, 0x0338u, 0x2247u), - HB_CODEPOINT_ENCODE3 (0x2248u, 0x0338u, 0x2249u), HB_CODEPOINT_ENCODE3 (0x224Du, 0x0338u, 0x226Du), - HB_CODEPOINT_ENCODE3 (0x2261u, 0x0338u, 0x2262u), HB_CODEPOINT_ENCODE3 (0x2264u, 0x0338u, 0x2270u), - HB_CODEPOINT_ENCODE3 (0x2265u, 0x0338u, 0x2271u), HB_CODEPOINT_ENCODE3 (0x2272u, 0x0338u, 0x2274u), - HB_CODEPOINT_ENCODE3 (0x2273u, 0x0338u, 0x2275u), HB_CODEPOINT_ENCODE3 (0x2276u, 0x0338u, 0x2278u), - HB_CODEPOINT_ENCODE3 (0x2277u, 0x0338u, 0x2279u), HB_CODEPOINT_ENCODE3 (0x227Au, 0x0338u, 0x2280u), - HB_CODEPOINT_ENCODE3 (0x227Bu, 0x0338u, 0x2281u), HB_CODEPOINT_ENCODE3 (0x227Cu, 0x0338u, 0x22E0u), - HB_CODEPOINT_ENCODE3 (0x227Du, 0x0338u, 0x22E1u), HB_CODEPOINT_ENCODE3 (0x2282u, 0x0338u, 0x2284u), - HB_CODEPOINT_ENCODE3 (0x2283u, 0x0338u, 0x2285u), HB_CODEPOINT_ENCODE3 (0x2286u, 0x0338u, 0x2288u), - HB_CODEPOINT_ENCODE3 (0x2287u, 0x0338u, 0x2289u), HB_CODEPOINT_ENCODE3 (0x2291u, 0x0338u, 0x22E2u), - HB_CODEPOINT_ENCODE3 (0x2292u, 0x0338u, 0x22E3u), HB_CODEPOINT_ENCODE3 (0x22A2u, 0x0338u, 0x22ACu), - HB_CODEPOINT_ENCODE3 (0x22A8u, 0x0338u, 0x22ADu), HB_CODEPOINT_ENCODE3 (0x22A9u, 0x0338u, 0x22AEu), - HB_CODEPOINT_ENCODE3 (0x22ABu, 0x0338u, 0x22AFu), HB_CODEPOINT_ENCODE3 (0x22B2u, 0x0338u, 0x22EAu), - HB_CODEPOINT_ENCODE3 (0x22B3u, 0x0338u, 0x22EBu), HB_CODEPOINT_ENCODE3 (0x22B4u, 0x0338u, 0x22ECu), - HB_CODEPOINT_ENCODE3 (0x22B5u, 0x0338u, 0x22EDu), HB_CODEPOINT_ENCODE3 (0x2ADDu, 0x0338u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x3046u, 0x3099u, 0x3094u), HB_CODEPOINT_ENCODE3 (0x304Bu, 0x3099u, 0x304Cu), - HB_CODEPOINT_ENCODE3 (0x304Du, 0x3099u, 0x304Eu), HB_CODEPOINT_ENCODE3 (0x304Fu, 0x3099u, 0x3050u), - HB_CODEPOINT_ENCODE3 (0x3051u, 0x3099u, 0x3052u), HB_CODEPOINT_ENCODE3 (0x3053u, 0x3099u, 0x3054u), - HB_CODEPOINT_ENCODE3 (0x3055u, 0x3099u, 0x3056u), HB_CODEPOINT_ENCODE3 (0x3057u, 0x3099u, 0x3058u), - HB_CODEPOINT_ENCODE3 (0x3059u, 0x3099u, 0x305Au), HB_CODEPOINT_ENCODE3 (0x305Bu, 0x3099u, 0x305Cu), - HB_CODEPOINT_ENCODE3 (0x305Du, 0x3099u, 0x305Eu), HB_CODEPOINT_ENCODE3 (0x305Fu, 0x3099u, 0x3060u), - HB_CODEPOINT_ENCODE3 (0x3061u, 0x3099u, 0x3062u), HB_CODEPOINT_ENCODE3 (0x3064u, 0x3099u, 0x3065u), - HB_CODEPOINT_ENCODE3 (0x3066u, 0x3099u, 0x3067u), HB_CODEPOINT_ENCODE3 (0x3068u, 0x3099u, 0x3069u), - HB_CODEPOINT_ENCODE3 (0x306Fu, 0x3099u, 0x3070u), HB_CODEPOINT_ENCODE3 (0x306Fu, 0x309Au, 0x3071u), - HB_CODEPOINT_ENCODE3 (0x3072u, 0x3099u, 0x3073u), HB_CODEPOINT_ENCODE3 (0x3072u, 0x309Au, 0x3074u), - HB_CODEPOINT_ENCODE3 (0x3075u, 0x3099u, 0x3076u), HB_CODEPOINT_ENCODE3 (0x3075u, 0x309Au, 0x3077u), - HB_CODEPOINT_ENCODE3 (0x3078u, 0x3099u, 0x3079u), HB_CODEPOINT_ENCODE3 (0x3078u, 0x309Au, 0x307Au), - HB_CODEPOINT_ENCODE3 (0x307Bu, 0x3099u, 0x307Cu), HB_CODEPOINT_ENCODE3 (0x307Bu, 0x309Au, 0x307Du), - HB_CODEPOINT_ENCODE3 (0x309Du, 0x3099u, 0x309Eu), HB_CODEPOINT_ENCODE3 (0x30A6u, 0x3099u, 0x30F4u), - HB_CODEPOINT_ENCODE3 (0x30ABu, 0x3099u, 0x30ACu), HB_CODEPOINT_ENCODE3 (0x30ADu, 0x3099u, 0x30AEu), - HB_CODEPOINT_ENCODE3 (0x30AFu, 0x3099u, 0x30B0u), HB_CODEPOINT_ENCODE3 (0x30B1u, 0x3099u, 0x30B2u), - HB_CODEPOINT_ENCODE3 (0x30B3u, 0x3099u, 0x30B4u), HB_CODEPOINT_ENCODE3 (0x30B5u, 0x3099u, 0x30B6u), - HB_CODEPOINT_ENCODE3 (0x30B7u, 0x3099u, 0x30B8u), HB_CODEPOINT_ENCODE3 (0x30B9u, 0x3099u, 0x30BAu), - HB_CODEPOINT_ENCODE3 (0x30BBu, 0x3099u, 0x30BCu), HB_CODEPOINT_ENCODE3 (0x30BDu, 0x3099u, 0x30BEu), - HB_CODEPOINT_ENCODE3 (0x30BFu, 0x3099u, 0x30C0u), HB_CODEPOINT_ENCODE3 (0x30C1u, 0x3099u, 0x30C2u), - HB_CODEPOINT_ENCODE3 (0x30C4u, 0x3099u, 0x30C5u), HB_CODEPOINT_ENCODE3 (0x30C6u, 0x3099u, 0x30C7u), - HB_CODEPOINT_ENCODE3 (0x30C8u, 0x3099u, 0x30C9u), HB_CODEPOINT_ENCODE3 (0x30CFu, 0x3099u, 0x30D0u), - HB_CODEPOINT_ENCODE3 (0x30CFu, 0x309Au, 0x30D1u), HB_CODEPOINT_ENCODE3 (0x30D2u, 0x3099u, 0x30D3u), - HB_CODEPOINT_ENCODE3 (0x30D2u, 0x309Au, 0x30D4u), HB_CODEPOINT_ENCODE3 (0x30D5u, 0x3099u, 0x30D6u), - HB_CODEPOINT_ENCODE3 (0x30D5u, 0x309Au, 0x30D7u), HB_CODEPOINT_ENCODE3 (0x30D8u, 0x3099u, 0x30D9u), - HB_CODEPOINT_ENCODE3 (0x30D8u, 0x309Au, 0x30DAu), HB_CODEPOINT_ENCODE3 (0x30DBu, 0x3099u, 0x30DCu), - HB_CODEPOINT_ENCODE3 (0x30DBu, 0x309Au, 0x30DDu), HB_CODEPOINT_ENCODE3 (0x30EFu, 0x3099u, 0x30F7u), - HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u), HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u), - HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu), HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu), - HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u), HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x105D2u, 0x0307u, 0x105C9u), HB_CODEPOINT_ENCODE3 (0x105DAu, 0x0307u, 0x105E4u), - HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu), - HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu), - HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu), - HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x11382u, 0x113C9u, 0x11383u), - HB_CODEPOINT_ENCODE3 (0x11384u, 0x113BBu, 0x11385u),HB_CODEPOINT_ENCODE3 (0x1138Bu, 0x113C2u, 0x1138Eu), - HB_CODEPOINT_ENCODE3 (0x11390u, 0x113C9u, 0x11391u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113B8u, 0x113C7u), - HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C2u, 0x113C5u),HB_CODEPOINT_ENCODE3 (0x113C2u, 0x113C9u, 0x113C8u), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu), - HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu), - HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),HB_CODEPOINT_ENCODE3 (0x11935u, 0x11930u, 0x11938u), - HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Eu, 0x16121u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x1611Fu, 0x16123u), - HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16120u, 0x16125u),HB_CODEPOINT_ENCODE3 (0x1611Eu, 0x16129u, 0x16122u), - HB_CODEPOINT_ENCODE3 (0x16121u, 0x1611Fu, 0x16126u),HB_CODEPOINT_ENCODE3 (0x16121u, 0x16120u, 0x16128u), - HB_CODEPOINT_ENCODE3 (0x16122u, 0x1611Fu, 0x16127u),HB_CODEPOINT_ENCODE3 (0x16129u, 0x1611Fu, 0x16124u), - HB_CODEPOINT_ENCODE3 (0x16D63u, 0x16D67u, 0x16D69u),HB_CODEPOINT_ENCODE3 (0x16D67u, 0x16D67u, 0x16D68u), - HB_CODEPOINT_ENCODE3 (0x16D69u, 0x16D67u, 0x16D6Au), HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), - HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u), + HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B7, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D0, 0x05B8, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D0, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D1, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D2, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D3, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D4, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D5, 0x05B9, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D5, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D8, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05D9, 0x05B4, 0x0000), HB_CODEPOINT_ENCODE3 (0x05D9, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DB, 0x05BF, 0x0000), HB_CODEPOINT_ENCODE3 (0x05DC, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05DE, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E0, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E1, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E3, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E4, 0x05BF, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E6, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E7, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E8, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0x05E9, 0x05C2, 0x0000), + HB_CODEPOINT_ENCODE3 (0x05EA, 0x05BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x05F2, 0x05B7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0627, 0x0653, 0x0622), HB_CODEPOINT_ENCODE3 (0x0627, 0x0654, 0x0623), + HB_CODEPOINT_ENCODE3 (0x0627, 0x0655, 0x0625), HB_CODEPOINT_ENCODE3 (0x0648, 0x0654, 0x0624), + HB_CODEPOINT_ENCODE3 (0x064A, 0x0654, 0x0626), HB_CODEPOINT_ENCODE3 (0x06C1, 0x0654, 0x06C2), + HB_CODEPOINT_ENCODE3 (0x06D2, 0x0654, 0x06D3), HB_CODEPOINT_ENCODE3 (0x06D5, 0x0654, 0x06C0), + HB_CODEPOINT_ENCODE3 (0x0915, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0916, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0917, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x091C, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0921, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0922, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0928, 0x093C, 0x0929), HB_CODEPOINT_ENCODE3 (0x092B, 0x093C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x092F, 0x093C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0930, 0x093C, 0x0931), + HB_CODEPOINT_ENCODE3 (0x0933, 0x093C, 0x0934), HB_CODEPOINT_ENCODE3 (0x09A1, 0x09BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x09A2, 0x09BC, 0x0000), HB_CODEPOINT_ENCODE3 (0x09AF, 0x09BC, 0x0000), + HB_CODEPOINT_ENCODE3 (0x09C7, 0x09BE, 0x09CB), HB_CODEPOINT_ENCODE3 (0x09C7, 0x09D7, 0x09CC), + HB_CODEPOINT_ENCODE3 (0x0A16, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A17, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0A1C, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A2B, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0A32, 0x0A3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0A38, 0x0A3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0B21, 0x0B3C, 0x0000), HB_CODEPOINT_ENCODE3 (0x0B22, 0x0B3C, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B3E, 0x0B4B), HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B56, 0x0B48), + HB_CODEPOINT_ENCODE3 (0x0B47, 0x0B57, 0x0B4C), HB_CODEPOINT_ENCODE3 (0x0B92, 0x0BD7, 0x0B94), + HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BBE, 0x0BCA), HB_CODEPOINT_ENCODE3 (0x0BC6, 0x0BD7, 0x0BCC), + HB_CODEPOINT_ENCODE3 (0x0BC7, 0x0BBE, 0x0BCB), HB_CODEPOINT_ENCODE3 (0x0C46, 0x0C56, 0x0C48), + HB_CODEPOINT_ENCODE3 (0x0CBF, 0x0CD5, 0x0CC0), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CC2, 0x0CCA), + HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD5, 0x0CC7), HB_CODEPOINT_ENCODE3 (0x0CC6, 0x0CD6, 0x0CC8), + HB_CODEPOINT_ENCODE3 (0x0CCA, 0x0CD5, 0x0CCB), HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D3E, 0x0D4A), + HB_CODEPOINT_ENCODE3 (0x0D46, 0x0D57, 0x0D4C), HB_CODEPOINT_ENCODE3 (0x0D47, 0x0D3E, 0x0D4B), + HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCA, 0x0DDA), HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DCF, 0x0DDC), + HB_CODEPOINT_ENCODE3 (0x0DD9, 0x0DDF, 0x0DDE), HB_CODEPOINT_ENCODE3 (0x0DDC, 0x0DCA, 0x0DDD), + HB_CODEPOINT_ENCODE3 (0x0F40, 0x0FB5, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F42, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F4C, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F51, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F56, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F5B, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F72, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F74, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F71, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F90, 0x0FB5, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0F92, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0F9C, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FA1, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FA6, 0x0FB7, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FAB, 0x0FB7, 0x0000), HB_CODEPOINT_ENCODE3 (0x0FB2, 0x0F80, 0x0000), + HB_CODEPOINT_ENCODE3 (0x0FB3, 0x0F80, 0x0000), HB_CODEPOINT_ENCODE3 (0x1025, 0x102E, 0x1026), + HB_CODEPOINT_ENCODE3 (0x1B05, 0x1B35, 0x1B06), HB_CODEPOINT_ENCODE3 (0x1B07, 0x1B35, 0x1B08), + HB_CODEPOINT_ENCODE3 (0x1B09, 0x1B35, 0x1B0A), HB_CODEPOINT_ENCODE3 (0x1B0B, 0x1B35, 0x1B0C), + HB_CODEPOINT_ENCODE3 (0x1B0D, 0x1B35, 0x1B0E), HB_CODEPOINT_ENCODE3 (0x1B11, 0x1B35, 0x1B12), + HB_CODEPOINT_ENCODE3 (0x1B3A, 0x1B35, 0x1B3B), HB_CODEPOINT_ENCODE3 (0x1B3C, 0x1B35, 0x1B3D), + HB_CODEPOINT_ENCODE3 (0x1B3E, 0x1B35, 0x1B40), HB_CODEPOINT_ENCODE3 (0x1B3F, 0x1B35, 0x1B41), + HB_CODEPOINT_ENCODE3 (0x1B42, 0x1B35, 0x1B43), HB_CODEPOINT_ENCODE3 (0x1E36, 0x0304, 0x1E38), + HB_CODEPOINT_ENCODE3 (0x1E37, 0x0304, 0x1E39), HB_CODEPOINT_ENCODE3 (0x1E5A, 0x0304, 0x1E5C), + HB_CODEPOINT_ENCODE3 (0x1E5B, 0x0304, 0x1E5D), HB_CODEPOINT_ENCODE3 (0x1E62, 0x0307, 0x1E68), + HB_CODEPOINT_ENCODE3 (0x1E63, 0x0307, 0x1E69), HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0302, 0x1EAC), + HB_CODEPOINT_ENCODE3 (0x1EA0, 0x0306, 0x1EB6), HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0302, 0x1EAD), + HB_CODEPOINT_ENCODE3 (0x1EA1, 0x0306, 0x1EB7), HB_CODEPOINT_ENCODE3 (0x1EB8, 0x0302, 0x1EC6), + HB_CODEPOINT_ENCODE3 (0x1EB9, 0x0302, 0x1EC7), HB_CODEPOINT_ENCODE3 (0x1ECC, 0x0302, 0x1ED8), + HB_CODEPOINT_ENCODE3 (0x1ECD, 0x0302, 0x1ED9), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0300, 0x1F02), + HB_CODEPOINT_ENCODE3 (0x1F00, 0x0301, 0x1F04), HB_CODEPOINT_ENCODE3 (0x1F00, 0x0342, 0x1F06), + HB_CODEPOINT_ENCODE3 (0x1F00, 0x0345, 0x1F80), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0300, 0x1F03), + HB_CODEPOINT_ENCODE3 (0x1F01, 0x0301, 0x1F05), HB_CODEPOINT_ENCODE3 (0x1F01, 0x0342, 0x1F07), + HB_CODEPOINT_ENCODE3 (0x1F01, 0x0345, 0x1F81), HB_CODEPOINT_ENCODE3 (0x1F02, 0x0345, 0x1F82), + HB_CODEPOINT_ENCODE3 (0x1F03, 0x0345, 0x1F83), HB_CODEPOINT_ENCODE3 (0x1F04, 0x0345, 0x1F84), + HB_CODEPOINT_ENCODE3 (0x1F05, 0x0345, 0x1F85), HB_CODEPOINT_ENCODE3 (0x1F06, 0x0345, 0x1F86), + HB_CODEPOINT_ENCODE3 (0x1F07, 0x0345, 0x1F87), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0300, 0x1F0A), + HB_CODEPOINT_ENCODE3 (0x1F08, 0x0301, 0x1F0C), HB_CODEPOINT_ENCODE3 (0x1F08, 0x0342, 0x1F0E), + HB_CODEPOINT_ENCODE3 (0x1F08, 0x0345, 0x1F88), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0300, 0x1F0B), + HB_CODEPOINT_ENCODE3 (0x1F09, 0x0301, 0x1F0D), HB_CODEPOINT_ENCODE3 (0x1F09, 0x0342, 0x1F0F), + HB_CODEPOINT_ENCODE3 (0x1F09, 0x0345, 0x1F89), HB_CODEPOINT_ENCODE3 (0x1F0A, 0x0345, 0x1F8A), + HB_CODEPOINT_ENCODE3 (0x1F0B, 0x0345, 0x1F8B), HB_CODEPOINT_ENCODE3 (0x1F0C, 0x0345, 0x1F8C), + HB_CODEPOINT_ENCODE3 (0x1F0D, 0x0345, 0x1F8D), HB_CODEPOINT_ENCODE3 (0x1F0E, 0x0345, 0x1F8E), + HB_CODEPOINT_ENCODE3 (0x1F0F, 0x0345, 0x1F8F), HB_CODEPOINT_ENCODE3 (0x1F10, 0x0300, 0x1F12), + HB_CODEPOINT_ENCODE3 (0x1F10, 0x0301, 0x1F14), HB_CODEPOINT_ENCODE3 (0x1F11, 0x0300, 0x1F13), + HB_CODEPOINT_ENCODE3 (0x1F11, 0x0301, 0x1F15), HB_CODEPOINT_ENCODE3 (0x1F18, 0x0300, 0x1F1A), + HB_CODEPOINT_ENCODE3 (0x1F18, 0x0301, 0x1F1C), HB_CODEPOINT_ENCODE3 (0x1F19, 0x0300, 0x1F1B), + HB_CODEPOINT_ENCODE3 (0x1F19, 0x0301, 0x1F1D), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0300, 0x1F22), + HB_CODEPOINT_ENCODE3 (0x1F20, 0x0301, 0x1F24), HB_CODEPOINT_ENCODE3 (0x1F20, 0x0342, 0x1F26), + HB_CODEPOINT_ENCODE3 (0x1F20, 0x0345, 0x1F90), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0300, 0x1F23), + HB_CODEPOINT_ENCODE3 (0x1F21, 0x0301, 0x1F25), HB_CODEPOINT_ENCODE3 (0x1F21, 0x0342, 0x1F27), + HB_CODEPOINT_ENCODE3 (0x1F21, 0x0345, 0x1F91), HB_CODEPOINT_ENCODE3 (0x1F22, 0x0345, 0x1F92), + HB_CODEPOINT_ENCODE3 (0x1F23, 0x0345, 0x1F93), HB_CODEPOINT_ENCODE3 (0x1F24, 0x0345, 0x1F94), + HB_CODEPOINT_ENCODE3 (0x1F25, 0x0345, 0x1F95), HB_CODEPOINT_ENCODE3 (0x1F26, 0x0345, 0x1F96), + HB_CODEPOINT_ENCODE3 (0x1F27, 0x0345, 0x1F97), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0300, 0x1F2A), + HB_CODEPOINT_ENCODE3 (0x1F28, 0x0301, 0x1F2C), HB_CODEPOINT_ENCODE3 (0x1F28, 0x0342, 0x1F2E), + HB_CODEPOINT_ENCODE3 (0x1F28, 0x0345, 0x1F98), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0300, 0x1F2B), + HB_CODEPOINT_ENCODE3 (0x1F29, 0x0301, 0x1F2D), HB_CODEPOINT_ENCODE3 (0x1F29, 0x0342, 0x1F2F), + HB_CODEPOINT_ENCODE3 (0x1F29, 0x0345, 0x1F99), HB_CODEPOINT_ENCODE3 (0x1F2A, 0x0345, 0x1F9A), + HB_CODEPOINT_ENCODE3 (0x1F2B, 0x0345, 0x1F9B), HB_CODEPOINT_ENCODE3 (0x1F2C, 0x0345, 0x1F9C), + HB_CODEPOINT_ENCODE3 (0x1F2D, 0x0345, 0x1F9D), HB_CODEPOINT_ENCODE3 (0x1F2E, 0x0345, 0x1F9E), + HB_CODEPOINT_ENCODE3 (0x1F2F, 0x0345, 0x1F9F), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0300, 0x1F32), + HB_CODEPOINT_ENCODE3 (0x1F30, 0x0301, 0x1F34), HB_CODEPOINT_ENCODE3 (0x1F30, 0x0342, 0x1F36), + HB_CODEPOINT_ENCODE3 (0x1F31, 0x0300, 0x1F33), HB_CODEPOINT_ENCODE3 (0x1F31, 0x0301, 0x1F35), + HB_CODEPOINT_ENCODE3 (0x1F31, 0x0342, 0x1F37), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0300, 0x1F3A), + HB_CODEPOINT_ENCODE3 (0x1F38, 0x0301, 0x1F3C), HB_CODEPOINT_ENCODE3 (0x1F38, 0x0342, 0x1F3E), + HB_CODEPOINT_ENCODE3 (0x1F39, 0x0300, 0x1F3B), HB_CODEPOINT_ENCODE3 (0x1F39, 0x0301, 0x1F3D), + HB_CODEPOINT_ENCODE3 (0x1F39, 0x0342, 0x1F3F), HB_CODEPOINT_ENCODE3 (0x1F40, 0x0300, 0x1F42), + HB_CODEPOINT_ENCODE3 (0x1F40, 0x0301, 0x1F44), HB_CODEPOINT_ENCODE3 (0x1F41, 0x0300, 0x1F43), + HB_CODEPOINT_ENCODE3 (0x1F41, 0x0301, 0x1F45), HB_CODEPOINT_ENCODE3 (0x1F48, 0x0300, 0x1F4A), + HB_CODEPOINT_ENCODE3 (0x1F48, 0x0301, 0x1F4C), HB_CODEPOINT_ENCODE3 (0x1F49, 0x0300, 0x1F4B), + HB_CODEPOINT_ENCODE3 (0x1F49, 0x0301, 0x1F4D), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0300, 0x1F52), + HB_CODEPOINT_ENCODE3 (0x1F50, 0x0301, 0x1F54), HB_CODEPOINT_ENCODE3 (0x1F50, 0x0342, 0x1F56), + HB_CODEPOINT_ENCODE3 (0x1F51, 0x0300, 0x1F53), HB_CODEPOINT_ENCODE3 (0x1F51, 0x0301, 0x1F55), + HB_CODEPOINT_ENCODE3 (0x1F51, 0x0342, 0x1F57), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0300, 0x1F5B), + HB_CODEPOINT_ENCODE3 (0x1F59, 0x0301, 0x1F5D), HB_CODEPOINT_ENCODE3 (0x1F59, 0x0342, 0x1F5F), + HB_CODEPOINT_ENCODE3 (0x1F60, 0x0300, 0x1F62), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0301, 0x1F64), + HB_CODEPOINT_ENCODE3 (0x1F60, 0x0342, 0x1F66), HB_CODEPOINT_ENCODE3 (0x1F60, 0x0345, 0x1FA0), + HB_CODEPOINT_ENCODE3 (0x1F61, 0x0300, 0x1F63), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0301, 0x1F65), + HB_CODEPOINT_ENCODE3 (0x1F61, 0x0342, 0x1F67), HB_CODEPOINT_ENCODE3 (0x1F61, 0x0345, 0x1FA1), + HB_CODEPOINT_ENCODE3 (0x1F62, 0x0345, 0x1FA2), HB_CODEPOINT_ENCODE3 (0x1F63, 0x0345, 0x1FA3), + HB_CODEPOINT_ENCODE3 (0x1F64, 0x0345, 0x1FA4), HB_CODEPOINT_ENCODE3 (0x1F65, 0x0345, 0x1FA5), + HB_CODEPOINT_ENCODE3 (0x1F66, 0x0345, 0x1FA6), HB_CODEPOINT_ENCODE3 (0x1F67, 0x0345, 0x1FA7), + HB_CODEPOINT_ENCODE3 (0x1F68, 0x0300, 0x1F6A), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0301, 0x1F6C), + HB_CODEPOINT_ENCODE3 (0x1F68, 0x0342, 0x1F6E), HB_CODEPOINT_ENCODE3 (0x1F68, 0x0345, 0x1FA8), + HB_CODEPOINT_ENCODE3 (0x1F69, 0x0300, 0x1F6B), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0301, 0x1F6D), + HB_CODEPOINT_ENCODE3 (0x1F69, 0x0342, 0x1F6F), HB_CODEPOINT_ENCODE3 (0x1F69, 0x0345, 0x1FA9), + HB_CODEPOINT_ENCODE3 (0x1F6A, 0x0345, 0x1FAA), HB_CODEPOINT_ENCODE3 (0x1F6B, 0x0345, 0x1FAB), + HB_CODEPOINT_ENCODE3 (0x1F6C, 0x0345, 0x1FAC), HB_CODEPOINT_ENCODE3 (0x1F6D, 0x0345, 0x1FAD), + HB_CODEPOINT_ENCODE3 (0x1F6E, 0x0345, 0x1FAE), HB_CODEPOINT_ENCODE3 (0x1F6F, 0x0345, 0x1FAF), + HB_CODEPOINT_ENCODE3 (0x1F70, 0x0345, 0x1FB2), HB_CODEPOINT_ENCODE3 (0x1F74, 0x0345, 0x1FC2), + HB_CODEPOINT_ENCODE3 (0x1F7C, 0x0345, 0x1FF2), HB_CODEPOINT_ENCODE3 (0x1FB6, 0x0345, 0x1FB7), + HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0300, 0x1FCD), HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0301, 0x1FCE), + HB_CODEPOINT_ENCODE3 (0x1FBF, 0x0342, 0x1FCF), HB_CODEPOINT_ENCODE3 (0x1FC6, 0x0345, 0x1FC7), + HB_CODEPOINT_ENCODE3 (0x1FF6, 0x0345, 0x1FF7), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0300, 0x1FDD), + HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0301, 0x1FDE), HB_CODEPOINT_ENCODE3 (0x1FFE, 0x0342, 0x1FDF), + HB_CODEPOINT_ENCODE3 (0x2190, 0x0338, 0x219A), HB_CODEPOINT_ENCODE3 (0x2192, 0x0338, 0x219B), + HB_CODEPOINT_ENCODE3 (0x2194, 0x0338, 0x21AE), HB_CODEPOINT_ENCODE3 (0x21D0, 0x0338, 0x21CD), + HB_CODEPOINT_ENCODE3 (0x21D2, 0x0338, 0x21CF), HB_CODEPOINT_ENCODE3 (0x21D4, 0x0338, 0x21CE), + HB_CODEPOINT_ENCODE3 (0x2203, 0x0338, 0x2204), HB_CODEPOINT_ENCODE3 (0x2208, 0x0338, 0x2209), + HB_CODEPOINT_ENCODE3 (0x220B, 0x0338, 0x220C), HB_CODEPOINT_ENCODE3 (0x2223, 0x0338, 0x2224), + HB_CODEPOINT_ENCODE3 (0x2225, 0x0338, 0x2226), HB_CODEPOINT_ENCODE3 (0x223C, 0x0338, 0x2241), + HB_CODEPOINT_ENCODE3 (0x2243, 0x0338, 0x2244), HB_CODEPOINT_ENCODE3 (0x2245, 0x0338, 0x2247), + HB_CODEPOINT_ENCODE3 (0x2248, 0x0338, 0x2249), HB_CODEPOINT_ENCODE3 (0x224D, 0x0338, 0x226D), + HB_CODEPOINT_ENCODE3 (0x2261, 0x0338, 0x2262), HB_CODEPOINT_ENCODE3 (0x2264, 0x0338, 0x2270), + HB_CODEPOINT_ENCODE3 (0x2265, 0x0338, 0x2271), HB_CODEPOINT_ENCODE3 (0x2272, 0x0338, 0x2274), + HB_CODEPOINT_ENCODE3 (0x2273, 0x0338, 0x2275), HB_CODEPOINT_ENCODE3 (0x2276, 0x0338, 0x2278), + HB_CODEPOINT_ENCODE3 (0x2277, 0x0338, 0x2279), HB_CODEPOINT_ENCODE3 (0x227A, 0x0338, 0x2280), + HB_CODEPOINT_ENCODE3 (0x227B, 0x0338, 0x2281), HB_CODEPOINT_ENCODE3 (0x227C, 0x0338, 0x22E0), + HB_CODEPOINT_ENCODE3 (0x227D, 0x0338, 0x22E1), HB_CODEPOINT_ENCODE3 (0x2282, 0x0338, 0x2284), + HB_CODEPOINT_ENCODE3 (0x2283, 0x0338, 0x2285), HB_CODEPOINT_ENCODE3 (0x2286, 0x0338, 0x2288), + HB_CODEPOINT_ENCODE3 (0x2287, 0x0338, 0x2289), HB_CODEPOINT_ENCODE3 (0x2291, 0x0338, 0x22E2), + HB_CODEPOINT_ENCODE3 (0x2292, 0x0338, 0x22E3), HB_CODEPOINT_ENCODE3 (0x22A2, 0x0338, 0x22AC), + HB_CODEPOINT_ENCODE3 (0x22A8, 0x0338, 0x22AD), HB_CODEPOINT_ENCODE3 (0x22A9, 0x0338, 0x22AE), + HB_CODEPOINT_ENCODE3 (0x22AB, 0x0338, 0x22AF), HB_CODEPOINT_ENCODE3 (0x22B2, 0x0338, 0x22EA), + HB_CODEPOINT_ENCODE3 (0x22B3, 0x0338, 0x22EB), HB_CODEPOINT_ENCODE3 (0x22B4, 0x0338, 0x22EC), + HB_CODEPOINT_ENCODE3 (0x22B5, 0x0338, 0x22ED), HB_CODEPOINT_ENCODE3 (0x2ADD, 0x0338, 0x0000), + HB_CODEPOINT_ENCODE3 (0x3046, 0x3099, 0x3094), HB_CODEPOINT_ENCODE3 (0x304B, 0x3099, 0x304C), + HB_CODEPOINT_ENCODE3 (0x304D, 0x3099, 0x304E), HB_CODEPOINT_ENCODE3 (0x304F, 0x3099, 0x3050), + HB_CODEPOINT_ENCODE3 (0x3051, 0x3099, 0x3052), HB_CODEPOINT_ENCODE3 (0x3053, 0x3099, 0x3054), + HB_CODEPOINT_ENCODE3 (0x3055, 0x3099, 0x3056), HB_CODEPOINT_ENCODE3 (0x3057, 0x3099, 0x3058), + HB_CODEPOINT_ENCODE3 (0x3059, 0x3099, 0x305A), HB_CODEPOINT_ENCODE3 (0x305B, 0x3099, 0x305C), + HB_CODEPOINT_ENCODE3 (0x305D, 0x3099, 0x305E), HB_CODEPOINT_ENCODE3 (0x305F, 0x3099, 0x3060), + HB_CODEPOINT_ENCODE3 (0x3061, 0x3099, 0x3062), HB_CODEPOINT_ENCODE3 (0x3064, 0x3099, 0x3065), + HB_CODEPOINT_ENCODE3 (0x3066, 0x3099, 0x3067), HB_CODEPOINT_ENCODE3 (0x3068, 0x3099, 0x3069), + HB_CODEPOINT_ENCODE3 (0x306F, 0x3099, 0x3070), HB_CODEPOINT_ENCODE3 (0x306F, 0x309A, 0x3071), + HB_CODEPOINT_ENCODE3 (0x3072, 0x3099, 0x3073), HB_CODEPOINT_ENCODE3 (0x3072, 0x309A, 0x3074), + HB_CODEPOINT_ENCODE3 (0x3075, 0x3099, 0x3076), HB_CODEPOINT_ENCODE3 (0x3075, 0x309A, 0x3077), + HB_CODEPOINT_ENCODE3 (0x3078, 0x3099, 0x3079), HB_CODEPOINT_ENCODE3 (0x3078, 0x309A, 0x307A), + HB_CODEPOINT_ENCODE3 (0x307B, 0x3099, 0x307C), HB_CODEPOINT_ENCODE3 (0x307B, 0x309A, 0x307D), + HB_CODEPOINT_ENCODE3 (0x309D, 0x3099, 0x309E), HB_CODEPOINT_ENCODE3 (0x30A6, 0x3099, 0x30F4), + HB_CODEPOINT_ENCODE3 (0x30AB, 0x3099, 0x30AC), HB_CODEPOINT_ENCODE3 (0x30AD, 0x3099, 0x30AE), + HB_CODEPOINT_ENCODE3 (0x30AF, 0x3099, 0x30B0), HB_CODEPOINT_ENCODE3 (0x30B1, 0x3099, 0x30B2), + HB_CODEPOINT_ENCODE3 (0x30B3, 0x3099, 0x30B4), HB_CODEPOINT_ENCODE3 (0x30B5, 0x3099, 0x30B6), + HB_CODEPOINT_ENCODE3 (0x30B7, 0x3099, 0x30B8), HB_CODEPOINT_ENCODE3 (0x30B9, 0x3099, 0x30BA), + HB_CODEPOINT_ENCODE3 (0x30BB, 0x3099, 0x30BC), HB_CODEPOINT_ENCODE3 (0x30BD, 0x3099, 0x30BE), + HB_CODEPOINT_ENCODE3 (0x30BF, 0x3099, 0x30C0), HB_CODEPOINT_ENCODE3 (0x30C1, 0x3099, 0x30C2), + HB_CODEPOINT_ENCODE3 (0x30C4, 0x3099, 0x30C5), HB_CODEPOINT_ENCODE3 (0x30C6, 0x3099, 0x30C7), + HB_CODEPOINT_ENCODE3 (0x30C8, 0x3099, 0x30C9), HB_CODEPOINT_ENCODE3 (0x30CF, 0x3099, 0x30D0), + HB_CODEPOINT_ENCODE3 (0x30CF, 0x309A, 0x30D1), HB_CODEPOINT_ENCODE3 (0x30D2, 0x3099, 0x30D3), + HB_CODEPOINT_ENCODE3 (0x30D2, 0x309A, 0x30D4), HB_CODEPOINT_ENCODE3 (0x30D5, 0x3099, 0x30D6), + HB_CODEPOINT_ENCODE3 (0x30D5, 0x309A, 0x30D7), HB_CODEPOINT_ENCODE3 (0x30D8, 0x3099, 0x30D9), + HB_CODEPOINT_ENCODE3 (0x30D8, 0x309A, 0x30DA), HB_CODEPOINT_ENCODE3 (0x30DB, 0x3099, 0x30DC), + HB_CODEPOINT_ENCODE3 (0x30DB, 0x309A, 0x30DD), HB_CODEPOINT_ENCODE3 (0x30EF, 0x3099, 0x30F7), + HB_CODEPOINT_ENCODE3 (0x30F0, 0x3099, 0x30F8), HB_CODEPOINT_ENCODE3 (0x30F1, 0x3099, 0x30F9), + HB_CODEPOINT_ENCODE3 (0x30F2, 0x3099, 0x30FA), HB_CODEPOINT_ENCODE3 (0x30FD, 0x3099, 0x30FE), + HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C1, 0x0000), HB_CODEPOINT_ENCODE3 (0xFB49, 0x05C2, 0x0000), + HB_CODEPOINT_ENCODE3 (0x105D2, 0x0307, 0x105C9), HB_CODEPOINT_ENCODE3 (0x105DA, 0x0307, 0x105E4), + HB_CODEPOINT_ENCODE3 (0x11099, 0x110BA, 0x1109A),HB_CODEPOINT_ENCODE3 (0x1109B, 0x110BA, 0x1109C), + HB_CODEPOINT_ENCODE3 (0x110A5, 0x110BA, 0x110AB),HB_CODEPOINT_ENCODE3 (0x11131, 0x11127, 0x1112E), + HB_CODEPOINT_ENCODE3 (0x11132, 0x11127, 0x1112F),HB_CODEPOINT_ENCODE3 (0x11347, 0x1133E, 0x1134B), + HB_CODEPOINT_ENCODE3 (0x11347, 0x11357, 0x1134C),HB_CODEPOINT_ENCODE3 (0x11382, 0x113C9, 0x11383), + HB_CODEPOINT_ENCODE3 (0x11384, 0x113BB, 0x11385),HB_CODEPOINT_ENCODE3 (0x1138B, 0x113C2, 0x1138E), + HB_CODEPOINT_ENCODE3 (0x11390, 0x113C9, 0x11391),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113B8, 0x113C7), + HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C2, 0x113C5),HB_CODEPOINT_ENCODE3 (0x113C2, 0x113C9, 0x113C8), + HB_CODEPOINT_ENCODE3 (0x114B9, 0x114B0, 0x114BC),HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BA, 0x114BB), + HB_CODEPOINT_ENCODE3 (0x114B9, 0x114BD, 0x114BE),HB_CODEPOINT_ENCODE3 (0x115B8, 0x115AF, 0x115BA), + HB_CODEPOINT_ENCODE3 (0x115B9, 0x115AF, 0x115BB),HB_CODEPOINT_ENCODE3 (0x11935, 0x11930, 0x11938), + HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611E, 0x16121),HB_CODEPOINT_ENCODE3 (0x1611E, 0x1611F, 0x16123), + HB_CODEPOINT_ENCODE3 (0x1611E, 0x16120, 0x16125),HB_CODEPOINT_ENCODE3 (0x1611E, 0x16129, 0x16122), + HB_CODEPOINT_ENCODE3 (0x16121, 0x1611F, 0x16126),HB_CODEPOINT_ENCODE3 (0x16121, 0x16120, 0x16128), + HB_CODEPOINT_ENCODE3 (0x16122, 0x1611F, 0x16127),HB_CODEPOINT_ENCODE3 (0x16129, 0x1611F, 0x16124), + HB_CODEPOINT_ENCODE3 (0x16D63, 0x16D67, 0x16D69),HB_CODEPOINT_ENCODE3 (0x16D67, 0x16D67, 0x16D68), + HB_CODEPOINT_ENCODE3 (0x16D69, 0x16D67, 0x16D6A), HB_CODEPOINT_ENCODE3 (0x1D157, 0x1D165, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D158, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16E, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D16F, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D170, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D171, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D15F, 0x1D172, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1B9, 0x1D165, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BA, 0x1D165, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BB, 0x1D16F, 0x0000), + HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16E, 0x0000), HB_CODEPOINT_ENCODE3 (0x1D1BC, 0x1D16F, 0x0000), }; #ifndef HB_OPTIMIZE_SIZE -static const uint8_t -_hb_ucd_u8[17612] = +#include + +static const uint8_t _hb_ucd_u8[19845]= { - 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, - 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, - 46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, - 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, - 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, - 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, - 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, - 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, - 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, - 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, - 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, - 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, - 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, - 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, - 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, - 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, - 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, - 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, - 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, - 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, - 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, - 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, - 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, - 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, - 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, - 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, - 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, - 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, - 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, - 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, - 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, - 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, - 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, - 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, - 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, - 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, - 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, - 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, - 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, - 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, - 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, - 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, - 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, - 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, - 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, - 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, - 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, - 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, - 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, - 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, - 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, - 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, - 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, - 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, - 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, - 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, - 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, - 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, - 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, - 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, - 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, - 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, - 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, - 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, - 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, - 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, - 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, - 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, - 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, - 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, - 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, - 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, - 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, - 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, - 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, - 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, - 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, - 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, - 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, - 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, - 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, - 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, - 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, - 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, - 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, - 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, - 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, - 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, - 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, - 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, - 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, - 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, - 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, - 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, - 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, - 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, - 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, - 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, - 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, - 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, - 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, - 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, - 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, - 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, - 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, - 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, - 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, - 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, - 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, - 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, - 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, - 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, - 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, - 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, - 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, - 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, - 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, - 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, - 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, - 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, - 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, - 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, - 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, - 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, - 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, - 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, - 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, - 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, - 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, - 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, - 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, - 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, - 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, - 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, - 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, - 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, - 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, - 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, - 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, - 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, - 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, - 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, - 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, - 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, - 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, - 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, - 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, - 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, - 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, - 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, - 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, - 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, - 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, - 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, - 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, - 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, - 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, - 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, - 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, - 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, - 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, - 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, - 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, - 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, - 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, - 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, - 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, - 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, - 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, - 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, - 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, - 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, - 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 32, 2, 33, 34, 35, 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 2, 58, 59, 0, 0, 0, 0, 60, 2, 2, 61, 2, 2, 2, 2, 2, + 2, 62, 2, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 2, 65, 66, 67, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, 0, 0, 0, 0, 72, 0, + 0, 0, 0, 0, 0, 0, 73, 74, 75, 76, 77, 78, 4, 79, 0, 80, + 81, 82, 83, 84, 85, 0, 86, 87, 88, 89, 4, 90, 91, 92, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 94, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 96, 2, 97, 0, 0, 0, 0, 2, 98, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,100, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,102, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, + 11, 11, 11, 11, 11, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, + 13, 13, 13, 13, 13, 13, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 14, + 1, 1, 1, 1, 14, 1, 1, 1, 18, 18, 18, 18, 18, 18, 18, 18, + 1, 5, 0, 11, 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 14, 0, + 1, 1, 1, 1, 14, 0, 0, 0, 6, 6, 6, 6, 7, 7, 7, 7, + 1, 1, 1, 1, 1, 14, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 14, 0, 0, 0, 0, + 1, 1, 1, 14, 1, 1, 1, 14, 3, 3, 3, 3, 3, 3, 0, 0, + 28, 28, 28, 28, 28, 28, 28, 28, 11, 11, 11, 11, 11, 1, 1, 1, + 14, 17, 1, 1, 1, 1, 1, 1, 14, 0, 0, 0, 0, 0, 0, 0, + 14, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 0, + 3, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 29, 0, + 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 6, 6, 6, + 0, 0, 0, 11, 11, 11, 11, 11, 17, 1, 1, 1, 1, 1, 1, 1, + 11, 11, 11, 11, 11, 10, 10, 10, 1, 1, 1, 0, 0, 0, 0, 0, + 5, 46, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 41, 41, 41, 41, + 3, 3, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 0, 0, 12, + 1, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 49, 10, 10, 10, 10, 10, 10, 10, 7, 6, 6, 6, 6, 6, 6, 6, + 44, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, + 3, 3, 3, 3, 0, 0, 0, 0, 11, 11, 11, 11, 11, 12, 9, 77, + 88, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,102,103,104, + 89, 6, 6, 6, 6, 6, 6, 6, 22, 22, 22, 22, 22, 22, 22, 22, + 26, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 5, 5, 5, 5, 5, + 5, 20, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, + 11, 11, 11, 11, 11, 12, 12, 12, 1, 1, 1, 1, 14, 1, 1, 0, + 14, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, + 10, 10, 10, 10, 10, 10, 51, 0,115, 1, 1, 1, 1, 1, 1, 1, + 5, 5, 5, 5, 5, 5, 5, 0, 1, 1, 1, 1, 13, 13, 13, 12, + 6, 6, 6, 0, 7, 7, 7, 0, 30, 30, 30, 30, 30, 30, 30, 30, + 3, 3, 3, 3, 3, 29, 0, 0, 3, 3, 3, 3, 3, 3, 3, 29, + 10, 10, 10, 10, 10, 3, 3, 3, 75, 10, 10, 10, 10, 10, 10, 10, + 3, 3, 3, 29, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 7, 7, 7, 7, 7, 32, 7, 7, 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 51, 0, 0, 0, 1, 1, 1, 1, 1, 1, 86, 10, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 15, 19, + 1, 1, 1, 1, 1, 1, 1, 34, 1, 1, 1, 1, 1, 1, 1, 5, + 15, 15, 15, 15, 15, 15, 15, 15, 1, 14, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 23, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, + 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, + 3, 3, 3, 3, 29, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 87, 12,100, 12, 27,101, 76, 12, 6, 6, 6, 6, 6,105,106,135, + 87, 30, 30, 66,107,136,137,108, 50, 10, 89, 12,138,139, 10, 78, + 7, 7, 7, 59, 7, 7, 7, 8, 6, 6, 6, 60, 6, 6, 6, 6, + 8, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 6, 8, 8, 8, + 8, 8, 8, 8, 7, 21, 21, 6, 21, 8, 8, 7, 21, 7, 6, 7, + 7, 21, 8, 7, 8, 6, 7, 21, 8, 8, 8, 7, 21, 6, 8, 7, + 21, 7, 21, 21, 8, 67, 8, 6, 1, 1,109, 21,110,109, 21, 21, + 21, 21, 21, 21, 21, 21, 6, 8, 21,110, 8, 7, 8, 8, 8, 8, + 8, 8, 6, 6, 6, 7, 21, 8, 21, 21, 7, 8, 8, 8, 8, 8, + 6, 6, 1, 6, 6, 6, 6, 6, 13, 22, 22, 13, 13, 13, 13, 13, + 13, 22, 22, 22, 22, 22, 22, 22, 13, 13, 68, 22, 22, 22, 68, 68, + 8, 8, 68, 8, 0, 69, 6, 88, 0, 0, 22,140, 7, 32, 32, 7, + 21, 7, 7, 7, 7, 7, 7, 7, 7, 39, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 21, 6, 7, 8, 6, 8, 8, 8, 8, + 6, 6, 8, 90, 21, 8, 21, 7, 8, 43, 5, 5, 79, 8, 8, 8, + 7, 21, 21, 21, 21, 21, 21, 6, 39, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 32, 54, 12, 12, 12, 6, 6, 6, 6,111,141, 44, 70, + 5, 5, 5, 5, 5, 5, 5,142, 71, 36, 5, 71, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 14, 0, 17, 1, 40, 33, 0, 0, 0, 0, 0, + 18, 18, 18, 9, 77, 80, 12, 3, 5, 5, 5, 5, 5, 36,143, 12, + 52, 1, 1, 1, 1, 24, 5, 5, 11, 11, 11, 11, 11, 12, 12, 1, + 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 53, 5, 5, 5,144, 43, + 5, 5, 81, 72, 55, 5, 5, 1, 11, 11, 11, 11, 11, 1, 56, 82, + 12, 12, 12, 12, 12, 12, 12, 73, 24, 1, 1, 1, 1, 1, 1, 1, + 5, 5, 5, 5, 5, 23, 17, 1, 25, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 24, 5, 5, 5, 5, 13, 66, 12, 61, 26, 30, + 1, 1, 1, 5, 5, 72, 5, 5, 5, 5, 72, 5, 72, 5, 5, 0, + 12, 12, 12, 12, 12, 12, 12, 33, 1, 1, 1, 1, 24, 5, 0, 33, + 1, 1, 1, 1,145, 1, 1, 1, 18, 0, 0, 26, 5, 5, 5, 5, + 1, 1, 1, 1, 45, 5, 5, 5, 5, 91, 5, 5, 5, 5, 5, 5, + 1, 1, 1, 1, 1, 20, 25, 15, 19, 5, 5, 5, 20, 15, 19, 15, + 24, 5, 5, 5, 1, 1, 1, 1, 1, 5, 12, 11, 11, 11, 11, 11, + 62, 1, 1, 1, 1, 1, 1, 1, 24, 15, 17, 1, 1, 1, 14, 17, + 14, 14, 0, 1, 1, 0, 25, 15, 19, 5, 23, 35, 37, 35, 19, 14, + 0, 0, 0, 35, 0, 0, 1, 17, 1, 30, 10, 10, 10, 70, 40, 23, + 26, 20, 17, 1, 1, 14, 0, 17, 14, 1, 17, 14, 1, 0, 23, 15, + 19, 23, 0, 26, 23, 26, 5, 0, 26, 0, 0, 0, 17, 1, 14, 14, + 5, 1, 24, 33, 0, 0, 0, 0, 26, 20, 17, 1, 1, 1, 1, 17, + 14, 1, 17, 1, 1, 0, 25, 15, 19, 5, 5, 26, 20, 35, 19, 0, + 80, 0, 0, 0, 17, 5, 5, 5, 26, 15, 17, 1, 1, 1, 14, 17, + 14, 1, 17, 1, 1, 0, 25, 19, 19, 5, 23, 35, 37, 35, 19, 0, + 0, 0, 26, 20, 0, 0, 1, 17, 82, 10, 10, 10, 0, 0, 0, 0, + 0, 25, 17, 1, 1, 14, 0, 1, 14, 1, 1, 0, 17, 14, 14, 1, + 0, 17, 14, 0, 1, 14, 0, 1, 1, 1, 1, 1, 1, 0, 0, 15, + 20, 37, 0, 15, 37, 15, 19, 0, 14, 0, 0, 35, 0, 0, 0, 0, + 10, 63, 3, 3, 70, 29, 0, 0, 20, 15, 25, 1, 1, 1, 14, 1, + 1, 1, 1, 1, 1, 0, 25, 5, 20, 15, 37, 5, 23, 5, 5, 0, + 0, 0, 26, 23, 1, 14, 1, 0, 0, 0, 0, 38, 10, 10, 10, 63, + 24, 15, 53, 1, 1, 1, 14, 1, 1, 1, 17, 1, 1, 0, 25, 19, + 15, 15, 37, 20, 37, 15, 5, 0, 0, 0, 35, 37, 0, 0, 1, 14, + 17, 34, 0, 0, 0, 0, 0, 0, 5, 15, 1, 1, 1, 1, 14, 1, + 1, 1, 1, 1, 1, 24, 25, 15, 19, 5, 23, 15, 37, 15, 19, 56, + 0, 0, 1, 34, 10, 10, 10,112, 10, 10, 10, 10, 63, 1, 1, 1, + 26, 15, 17, 1, 1, 1, 1, 1, 1, 1, 1, 14, 0, 1, 1, 1, + 1, 17, 1, 1, 1, 1, 17, 0, 1, 1, 1, 14, 0, 23, 0, 35, + 15, 5, 23, 23, 15, 15, 15, 15, 0, 15, 33, 0, 0, 0, 0, 0, + 24, 1, 5, 5, 5, 23, 0,113, 1, 1, 1, 72, 5, 5, 5, 36, + 11, 11, 11, 11, 11, 12, 0, 0, 17, 14, 14, 1, 1, 14, 1, 1, + 1, 1, 17, 17, 1, 1, 1, 1, 24, 1, 5, 5, 5, 5, 25, 0, + 1, 1, 14, 61, 5, 5, 5, 23, 11, 11, 11, 11, 11, 0, 1, 1, + 56, 3, 12, 12, 12, 12, 12, 12, 12, 57, 57, 3, 5, 3, 3, 3, + 10, 10, 43, 43, 43, 27, 27, 15, 1, 1, 1, 1, 17, 1, 1, 1, + 26, 5, 5, 5, 5, 5, 5, 20, 5, 5, 36, 5, 1, 1, 24, 5, + 5, 5, 5, 5, 26, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 3, + 3, 3, 3, 55, 3, 3, 29, 3, 12, 12, 57, 3, 66, 33, 0, 0, + 1, 1, 1, 1, 1, 34, 19, 5, 20, 5, 5, 5, 19, 20, 19, 25, + 1, 1, 1, 15, 5, 1, 1, 5, 25, 15, 46, 34, 15, 15, 15, 1, + 24, 5, 25, 1, 1, 1, 1, 1, 1, 20, 19, 20, 15, 15, 19, 34, + 11, 11, 11, 11, 11, 15, 19, 3, 7, 7, 7, 39, 0, 0, 39, 0, + 6, 6, 6, 6, 6,111, 69, 6, 1, 1, 1, 14, 14, 1, 1, 0, + 14, 1, 1, 0, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 26, 5, + 12, 12, 12, 12,114, 10, 10, 10, 7, 7, 7, 0, 6, 6, 6, 0, + 1, 1, 1, 1, 1, 1, 56, 53,146, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1,147,116, 0, 1, 1, 1, 1, 1, 40, 12, 16, + 148, 1, 1, 1, 14, 0, 0, 0, 1, 5, 20, 0, 0, 0, 0, 17, + 1, 5, 83, 33, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 14, 1, 14, 5, 0, 0, 0, 0, 0, 0, + 1, 1, 5, 19, 5, 5, 5, 15, 15, 15, 15, 20, 19, 5, 5, 5, + 5, 5, 12, 62, 12, 80, 24, 0, 10, 10, 10, 10, 10, 0, 0, 0, + 12, 12, 12, 92, 12, 71, 5, 91, 1, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 24, 14, 0, 0, + 5, 20, 15, 19, 20, 15, 0, 0, 15, 20, 15, 15, 19, 5, 0, 0, + 29, 0, 12, 11, 11, 11, 11, 11, 1, 1, 14, 0, 0, 0, 0, 0, + 11, 11, 11, 11, 11, 51, 0, 3, 1, 1, 1, 24, 20, 19, 0, 12, + 1, 1, 34, 20, 5, 5, 5, 23, 20, 20, 19, 5, 5, 5, 20, 15, + 15, 19, 5, 5, 5, 5, 23, 26, 12, 12, 12, 62, 12, 12, 12, 0, + 5, 5, 5, 5, 5, 5, 5, 93, 5, 5, 5, 5, 5, 5, 0, 0, + 5, 5, 46, 1, 1, 1, 1, 1, 1, 1, 20, 5, 5, 20, 20, 15, + 15, 20, 46, 1, 1, 1, 14, 12, 57, 3, 3, 3, 3, 43, 5, 5, + 5, 5, 3, 3, 3, 3, 66, 12, 34, 5, 5, 15, 5, 19, 5, 1, + 1, 1, 1, 20, 5, 15, 19, 19, 5, 15, 0, 0, 0, 0, 12, 12, + 1, 1, 15, 15, 15, 15, 5, 5, 5, 5, 15, 5, 0, 38, 12, 12, + 11, 11, 11, 11, 11, 0, 17, 1, 6, 6, 6, 6, 21, 47, 0, 0, + 7, 7, 7, 7, 7, 32, 39, 7, 12, 12, 12, 12, 0, 0, 0, 0, + 5, 36, 5, 5, 5, 5, 5, 5, 20, 5, 5, 5, 25, 1, 24, 1, + 1, 1, 25, 34, 5, 14, 0, 0, 6, 6, 6, 6, 6, 6, 13, 13, + 13, 13, 13, 13, 13, 69, 6, 6, 6, 6, 6, 6, 69, 6, 6, 6, + 6, 6, 6, 6, 6,117, 13, 13, 8, 8, 8, 6, 6, 6, 6, 8, + 6, 6, 6, 6, 39, 39, 39, 39, 6, 6, 6, 6, 6, 6, 6, 0, + 6, 6, 47, 6, 7, 7, 94,118, 22, 6, 47, 6, 7, 7, 94, 22, + 6, 6, 0, 6, 7, 7,149, 22, 6, 6, 6, 6, 7, 7,150, 22, + 0, 6, 47, 6, 7, 7, 94,151, 74, 74, 74, 74, 74,152, 18, 18, + 84, 84, 84, 12, 58,119, 58,119, 12, 12, 12, 12,153, 18, 18,154, + 12, 12, 12, 12,120,121, 12,122,123, 12, 64, 65, 12, 12, 12, 12, + 12, 77,123, 12, 12, 12, 12,155, 18, 18,156, 18, 18, 18, 18, 18, + 157, 0, 10, 10, 10, 9, 64,158, 10, 10, 10, 10, 10, 9, 64,116, + 13, 13, 13, 13, 13, 13, 61, 0, 30, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5,159, 79, 93, 79, 93, 5, 5, 5, 5, 5, + 23, 0, 0, 0, 0, 0, 0, 0, 3, 85, 3, 95, 3, 21, 7, 6, + 7, 8, 95, 3, 90, 7, 7, 3, 3, 3, 85, 85, 85, 7, 7,160, + 7, 7, 67, 1,124, 3, 6, 7, 9, 9, 90, 6, 6, 50, 3,125, + 16,161,162, 16,126, 3, 0, 0, 9, 9, 48, 3, 3, 9, 3, 3, + 48, 50, 3, 48, 3, 3, 3, 48, 3, 3, 3, 3, 3, 3, 3, 9, + 3, 48, 48, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, + 3, 3, 3, 3, 27, 27, 3, 3, 9, 3, 3, 3,163,164, 3, 3, + 3, 3, 3, 3, 3, 3, 48, 3, 3, 3, 3, 3, 3, 50, 9, 9, + 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 9, + 9, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, + 3, 3, 3, 3, 3, 10, 10, 10, 3, 3, 3, 50, 3, 3, 3, 3, + 50, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, + 3, 3, 3, 3, 3, 3, 3, 50, 3, 3, 3, 3, 27, 27, 27, 27, + 27, 27, 27, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, + 9, 9, 64,127, 9, 9, 9, 9, 9, 9, 9, 27, 27, 27, 27, 27, + 9, 64, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,127, 9, 9, 9, + 9, 9, 9, 9, 27, 27, 9, 9, 9, 9, 9, 9, 9, 9, 27, 9, + 9, 9, 48, 50, 9, 9, 48, 3, 3, 3, 0, 3, 3, 3, 3, 3, + 8, 7, 8, 21, 21, 21, 21, 7, 8, 8, 21, 6, 6, 6, 13, 7, + 8, 8,125, 3, 3, 95, 21,165, 5, 8, 0, 0, 38, 12,114, 12, + 6, 6, 6, 42, 0, 0, 42, 0, 1, 1, 1, 1, 0, 0, 0, 54, + 33, 0, 0, 0, 0, 0, 0, 26, 12, 58, 58, 12,120,121, 58, 12, + 12, 12, 12, 76, 12, 92, 58, 12, 58, 27, 27, 27, 27, 12, 12, 62, + 12, 12, 12, 12, 12, 84, 12, 12, 92,166, 12, 12, 12, 12, 12, 12, + 3, 12, 96, 31, 31, 31,167, 0, 3, 3, 3, 3, 3, 44, 3, 3, + 87, 12,168,128, 27, 27, 27, 27, 27, 3, 27, 27, 27, 27,129,169, + 170, 16, 16, 16, 16, 5, 5, 15,130, 13, 13, 3, 16,171, 40, 3, + 1, 1, 1, 14, 26,172,131, 52, 1, 1, 1, 1, 1, 40, 13, 52, + 0, 0, 17, 1, 1, 1, 1, 1, 3, 10, 10, 3, 3, 3, 3, 3, + 3, 3, 3, 0, 0, 0, 0, 44, 3, 3, 3, 3, 10, 10, 10, 10, + 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,132, 12, + 11, 11, 11, 11, 11, 1, 0, 0, 8, 8, 8, 8, 8, 8, 8, 24, + 79,173, 5, 5, 5, 5, 5, 62, 8, 8, 8, 8, 8, 8, 13, 5, + 1, 1, 1, 16, 16, 16, 16, 16, 5, 12, 12, 12, 0, 0, 0, 0, + 22, 22, 22,131, 13, 13, 13, 13, 22, 8, 8, 8, 8, 8, 8, 8, + 6, 8, 8, 8, 8, 8, 8, 8, 69, 6, 6, 6, 21, 21, 21, 8, + 8, 8, 8, 8, 68,174, 21, 67, 8, 8, 6, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 7, 7, 8, 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 7, 7, 21, 21, 8, 8, 8, 8, 8, 8, 8, 8, 32, 0, + 54, 13,175, 67, 13, 67, 1, 1, 1, 25, 1, 25, 1, 24, 1, 1, + 1, 34, 19, 20, 3, 3, 23, 0, 10, 10, 10, 3, 97, 0, 0, 0, + 1, 1, 12, 12, 0, 0, 0, 0, 15, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 5, 0, 0, 0, 0, 12, + 5, 1, 1, 1, 12, 53, 53, 24, 1, 1, 1, 5, 5, 5, 5, 12, + 1, 1, 1, 24, 5, 5, 5, 5, 5, 15, 0, 0, 0, 0, 0, 38, + 1, 24, 15, 5, 5, 15, 5, 15, 83, 12, 12, 12, 12, 12, 12, 54, + 1, 1, 24, 52, 1, 1, 1, 1, 11, 11, 11, 11, 11, 1, 1, 14, + 1, 1, 1, 1, 24, 5, 5, 20, 19, 20, 19, 23, 0, 0, 0, 0, + 1, 24, 1, 1, 1, 1, 20, 0, 11, 11, 11, 11, 11, 0, 12, 12, + 52, 1, 1, 56, 3, 34, 20, 1, 25, 5, 25, 24, 25, 1, 1, 5, + 24, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 45, 12, + 1, 1, 1, 1, 1, 34, 5, 15, 12, 45,176, 23, 0, 0, 0, 0, + 17, 1, 1, 14, 17, 1, 1, 14, 17, 1, 1, 14, 0, 0, 0, 0, + 6, 6, 6, 6, 6,118, 13, 13, 6, 6, 6, 6,117, 22, 0, 0, + 1, 34, 19, 15, 20, 83, 19, 0, 1, 1, 1, 14, 0, 17, 1, 1, + 6, 6, 6, 47, 0, 0, 0, 0, 0, 42, 6, 6, 0, 0, 17, 25, + 1, 1, 1, 1,177, 1, 1, 1, 1, 1, 1, 14, 1, 1, 14, 14, + 1, 17, 14, 1, 1, 1, 1, 1, 1, 22, 22, 22, 22, 22, 22, 22, + 22,107, 3, 3, 3, 3, 3, 3, 3, 82, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 31, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 97, 3, + 12, 12, 12, 96, 65, 0, 0, 0, 76,178,179, 31, 31, 31, 31, 31, + 31, 31, 65, 96, 65, 12,122,180, 12, 33, 12, 12,129, 31, 31, 65, + 12,181, 9, 98, 80, 12, 0, 0, 1, 1, 14, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 14, 73, 38, 12,100, 12, 27,101, 76, 12, + 6, 6, 6, 6, 6,105,106, 64, 65, 27, 12, 1, 1, 1, 1, 1, + 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 14, 0, + 30,182, 70,183, 50, 9, 48, 29, 0, 0, 0, 0, 73, 18, 3, 0, + 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 14, 1, 17, + 12, 33, 0, 49, 10, 10, 10, 10, 10, 10, 0, 44, 3, 3, 3, 3, + 16, 16,126, 10, 63, 3, 3, 3, 3, 3, 3, 3, 3, 10, 3, 29, + 3, 3, 3, 3, 3, 3, 43, 0,133, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 0, 0, 10, 10, 0, 0, 0, 0, 17, 1, + 128, 1, 1, 1, 1, 99, 0, 0, 1, 1, 1, 5, 5, 23, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 0, 0, 1, 1, 1, 1, + 184, 16, 16, 0, 0, 0, 0, 0, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 38, 7, 32, 7, 42, 6, 6, 6, 6, + 6, 42, 6, 6, 6, 6, 6, 6, 6, 42, 6, 6, 6, 42, 47, 0, + 13, 13, 13, 54, 13, 13, 13, 13, 61, 13, 13, 13, 13, 61, 0, 0, + 1, 1, 1, 0, 14, 1, 1, 1, 1, 1, 1, 17, 14, 0, 14, 17, + 1, 1, 1, 38, 10, 10, 10, 10, 1, 1, 1, 56, 75, 10, 10, 10, + 0, 0, 0, 49, 10, 10, 10, 10, 1, 14, 1, 0, 0, 49, 10, 10, + 1, 1, 1, 10, 10, 10, 0, 38, 1, 1, 1, 1, 1, 0, 0, 38, + 1, 1, 1, 1, 0, 0, 10, 1, 24, 5, 26, 23, 0, 0, 5, 5, + 1, 1, 17, 1, 17, 1, 1, 1, 1, 1, 1, 0, 5, 23, 0, 26, + 12, 12, 12, 12, 33, 0, 0, 0, 1, 1, 1, 1, 1, 1, 86, 78, + 1, 1, 1, 1, 82, 1, 1, 1, 1, 1, 24, 23, 0, 49, 10, 10, + 12, 12, 12, 33, 0, 0, 0, 0, 1, 1, 1, 0, 38, 12, 12, 12, + 1, 1, 1, 0, 10, 10, 10, 10, 1, 14, 0, 0, 10, 10, 10, 10, + 1, 0, 0, 0, 38, 12, 33, 0, 0, 0, 0, 0, 49, 10, 10, 10, + 7, 32, 0, 0, 0, 0, 0, 0, 6, 47, 0, 0, 0, 10, 10, 10, + 1, 1, 5, 5, 0, 0, 0, 0, 11, 11, 11, 11, 11, 1, 1, 52, + 7, 7, 7, 0, 26, 5, 5,130, 6, 6, 6, 0, 0, 0, 0, 9, + 10, 10, 10, 10, 10, 10, 10, 51, 1, 1, 1, 1, 1, 26,185, 0, + 0, 1, 45, 1, 0, 0, 0, 0, 57, 3, 3, 3, 29, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 10, 10, 10,112, 0, 0, 0, 0, + 133, 10, 78, 12, 12, 0, 0, 0, 1, 5, 5, 12, 12, 0, 0, 0, + 1, 1, 86, 10, 10, 10, 0, 0, 19, 46, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 36, 12, 12, 12, 0, + 10, 10, 10, 11, 11, 11, 11, 11, 25, 24, 25, 0, 0, 0, 0, 26, + 15, 19, 5, 20, 19, 36,186, 12, 12, 23, 0, 0, 0, 0, 73, 0, + 5, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 24, 5, 5, 19, 5, + 5, 5, 23, 11, 11, 11, 11, 11, 12, 12, 34, 46, 0, 0, 0, 0, + 1, 24, 12, 14, 0, 0, 0, 0, 1, 34, 15, 5, 5, 5, 5, 20, + 46, 1, 40, 12, 71, 5, 36, 19, 11, 11, 11, 11, 11, 40, 40, 12, + 10, 10, 51, 0, 0, 0, 0, 0, 5, 15, 20, 5, 12, 12, 12, 25, + 24, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 14, 14, 1, 1, 17, + 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 40, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 24, 15, 19, 5, 5, 5, 23, 0, 0, + 5, 15, 17, 1, 1, 1, 14, 17, 14, 1, 17, 1, 1, 26, 25, 15, + 20, 15, 37, 35, 37, 35, 15, 0, 14, 0, 0, 35, 0, 0, 17, 1, + 1, 15, 0, 5, 5, 5, 23, 0, 5, 5, 23, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 17, 0, 14, 1, 1, 1, 17, 15, 19, 5, 5, + 23, 37, 35, 35, 15, 37, 15, 20, 25, 25, 12, 38, 33, 0, 0, 0, + 26, 23, 0, 0, 0, 0, 0, 0, 1, 1, 34, 15, 5, 5, 5, 5, + 15, 5, 20, 25, 1, 40, 12, 12, 11, 11, 11, 11, 11, 12, 38, 25, + 15, 19, 5, 5, 20, 20, 15, 19, 20, 5, 1, 53, 0, 0, 0, 0, + 15, 5, 5, 0, 15, 15, 5, 19, 36, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 1, 1, 5, 0, 15, 19, 5, 5, 5, 20, 19, 19, + 36, 12, 14, 0, 0, 0, 0, 0, 12, 12, 12, 12, 12, 12, 33, 0, + 1, 1, 1, 1, 1, 24, 19, 15, 5, 5, 5, 19, 40, 0, 0, 0, + 11, 11, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 14, 26, 19, + 15, 5, 5, 19, 5, 5, 0, 0, 11, 11, 11, 11, 11, 10, 12, 57, + 5, 5, 5, 5, 19, 36, 0, 0, 10, 51, 0, 0, 0, 0, 0, 17, + 1, 1, 1, 14, 17, 0, 1, 1, 1, 1, 17, 14, 1, 1, 1, 1, + 15, 15, 15, 35, 37, 26, 20, 25, 46, 19, 12, 33, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 1, 1, 1, 34, 15, 5, 5, 0, 5, 15, 15, + 25, 53, 37, 0, 0, 0, 0, 0, 24, 5, 5, 5, 5, 25, 1, 1, + 1, 24, 5, 5, 20, 24, 5, 36, 12, 12, 12, 71, 0, 0, 0, 0, + 24, 5, 5, 20, 19, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, + 5, 5, 5, 20, 5, 12, 53, 12, 12, 33, 0, 0, 0, 0, 0, 0, + 12, 12, 12, 12, 12, 0, 0, 0, 20, 5, 20, 20, 0, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 23, 5, 5, 5, 19, + 40, 12, 12, 0, 0, 0, 0, 0, 12, 1, 1, 1, 1, 1, 1, 1, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 35, 5, 5, 5, + 20, 5, 19, 23, 0, 0, 0, 0, 1, 1, 1, 14, 1, 17, 1, 1, + 24, 5, 5, 23, 0, 23, 5, 26, 5, 5, 5, 24, 0, 0, 0, 0, + 1, 1, 1, 17, 14, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 37, + 5, 35, 19, 19, 14, 0, 0, 0, 1, 1, 1, 1, 45, 1, 0, 0, + 1, 24, 20, 83, 33, 0, 0, 0, 5, 34, 1, 1, 1, 1, 1, 1, + 1, 1, 15, 5, 5, 23, 0, 15, 20, 36, 12, 12, 12, 12, 12, 12, + 11, 11, 11, 11, 11, 23, 0, 0, 10, 10, 63, 3, 3, 3, 70, 30, + 97, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 38, + 16, 16, 16, 16, 16, 16, 16, 99, 12, 12, 33, 0, 0, 0, 0, 0, + 40, 33, 0, 0, 0, 0, 0, 0, 25, 1, 1, 24, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 15, 19, 5, + 5, 5, 36, 0, 0, 0, 0, 0, 5, 5, 5, 36, 12, 12, 3, 3, + 13, 13, 57, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 49, 10, 10, + 10, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 17, 1, + 13, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45,132, 12, + 10, 10, 10, 78, 12, 33, 0, 0, 7, 7, 7, 7, 32, 42, 6, 6, + 6, 6, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 14, 0, 26, + 34, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 26, + 5, 81, 13, 13, 13, 13, 13, 13, 13, 62, 23, 0, 0, 0, 0, 0, + 15, 13, 16, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 13, 13, 54, 13, 13, 13, 54, 61, 0, 14, 0, 0, 0, 0, 0, 0, + 1, 14, 17, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 43, 36, 18, 18, 0, 0, 0, 0, 0, 0, + 11, 11, 11, 11, 11, 3, 29, 0, 3, 3, 0, 0, 0, 3, 3, 3, + 98, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 29, 44, 3, 3, 3, + 3, 3,134, 19, 5, 3,134, 15, 15,187, 18, 18, 18, 91, 5, 5, + 5, 55, 43, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, + 3, 5, 55, 0, 0, 0, 0, 0, 6, 6, 47, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 32, 7, 0, 32, 39, 32, 39, 7, 32, 7, + 7, 7, 7, 6, 6, 42, 42, 6, 6, 6, 42, 6, 6, 6, 6, 6, + 6, 6, 7, 39, 7, 32, 39, 7, 7, 7, 32, 7, 7, 7, 32, 6, + 6, 6, 6, 6, 7, 39, 7, 32, 7, 7, 32, 32, 0, 7, 7, 7, + 32, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 7, 7, 7, 7, + 59, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 60, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 59, 6, 6, + 6, 6, 60, 6, 6, 6, 7, 7, 7, 7, 59, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 60, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 59, 6, 6, 6, 6, 60, 6, 6, 6, + 7, 7, 7, 7, 59, 6, 6, 6, 6, 60, 6, 6, 6, 8, 0, 11, + 5, 5, 5, 55, 3, 43, 5, 5, 5, 5, 5, 5, 5, 5, 55, 3, + 3, 3, 43, 3, 3, 3, 3, 3, 3, 3, 55, 66, 12, 12, 0, 0, + 0, 0, 0, 0, 0, 26, 5, 5, 6, 6, 6, 6, 6,124, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 47, 0, 0, 42, 6, 6, 47, 0, 0, + 5, 5, 5, 23, 5, 5, 5, 5, 5, 5, 5, 5, 23, 26, 5, 5, + 5, 26, 23, 5, 5, 23, 0, 0, 13, 13, 13, 13, 13, 13, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 5, 5, 5, 81, 13, 13, 13, 0, + 11, 11, 11, 11, 11, 0, 0, 56, 1, 1, 1, 1, 1, 1, 1, 23, + 1, 1, 1, 1, 1, 1, 5, 5, 11, 11, 11, 11, 11, 0, 0,113, + 1, 1, 1, 1, 1, 45, 5, 5,188, 11, 11, 11, 11,189, 0, 38, + 1, 24, 1, 25, 1, 1, 1, 5, 1, 1, 24, 0, 0, 0, 0, 45, + 1, 1, 1, 14, 1, 1, 17, 14, 1, 1, 14, 49, 10, 10, 10, 10, + 6, 6, 5, 5, 5, 81, 0, 0, 10, 10, 10, 10, 10, 10, 75, 10, + 190, 10, 51, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 75, + 10, 10, 10, 10, 10, 10, 10, 0, 1, 1, 17, 1, 1, 1, 1, 1, + 17, 14, 14, 17, 17, 1, 1, 1, 1, 14, 1, 1, 17, 17, 0, 0, + 0, 14, 0, 17, 17, 17, 17, 1, 17, 14, 14, 17, 17, 17, 17, 17, + 17, 14, 14, 17, 1, 14, 1, 1, 1, 14, 1, 1, 17, 1, 14, 14, + 1, 1, 1, 1, 1, 17, 1, 1, 17, 1, 17, 1, 1, 17, 1, 1, + 9, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 63, 3, + 0, 0, 0, 3, 3, 3, 3, 3, 3, 29, 0, 0, 0, 0, 0, 0, + 3, 3, 3, 3, 3,108, 22, 22, 3, 3, 3, 3, 29, 0, 3, 3, + 9, 9, 9, 9, 98, 0, 0, 0, 3, 3, 3, 3, 3, 29, 0, 3, + 3, 3, 3, 29, 29, 0, 44, 3, 3, 3, 3, 3, 3, 3, 29, 44, + 3, 3, 3, 3, 3, 29, 0, 44, 3, 29, 3, 3, 3, 3, 3, 3, + 11, 11, 11, 11, 11, 29, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 7, 7, 3, 3, 26, 26, + 4, 4, 12, 12, 5, 5, 9, 9, 9, 5, 25, 25, 15, 15, 13, 13, + 21, 21, 6, 6, 7, 2, 10, 10, 14, 14, 2, 7, 1, 1, 10, 12, + 12, 10, 5, 9, 24, 24, 12, 2, 7, 12, 12, 7, 2, 12, 22, 18, + 0, 0, 26, 2, 23, 23, 18, 22, 9, 2, 21, 2, 7, 10, 2, 10, + 12, 21, 10, 2, 2, 21, 2, 9, 7, 21, 8, 8, 2, 5, 26, 12, + 2, 26, 7, 6, 10, 7, 5, 2, 25, 26, 2, 15, 26, 25, 15, 2, + 6, 7, 21, 7, 2, 6, 12, 26, 7, 26, 21, 26, 20, 19, 9, 25, + 5, 25, 6, 2, 21, 6, 15, 26, 25, 22, 18, 21, 26, 21, 5, 7, + 6, 24, 6, 5, 26, 23, 21, 12, 6, 12, 2, 1, 29, 29, 26, 15, + 21, 17, 25, 21, 15, 21, 11, 11, 21, 23, 12, 6, 26, 7, 10, 21, + 17, 17, 9, 26, 7, 15, 29, 21, 21, 9, 24, 5, 25, 9, 1, 12, + 17, 21, 11, 12, 8, 24, 26, 9, 21, 22, 23, 26, 25, 2, 14, 2, + 23, 21, 21, 25, 9, 22, 21, 18, 24, 16, 5, 22, 25, 18, 24, 26, + 26, 24, 9, 8, 8, 5, 5, 21, 15, 7, 2, 23, 21, 15, 17, 7, + 18, 2, 5, 6, 5, 24, 22, 20, 21, 20, 19, 21, 21, 16, 16, 21, + 7, 5, 5, 26, 14, 15, 18, 25, 7, 14, 17, 22, 17, 6, 24, 6, + 6, 21, 12, 15, 26, 10, 25, 0, 7, 20, 25, 1, 24, 15, 7, 19, + 9, 21, 17, 2, 17, 12, 1, 21, 12, 1, 24, 7, 29, 7, 7, 22, + 14, 7, 2, 24, 9, 24, 24, 2, 29, 1, 27, 28, 1, 29, 21, 29, + 1, 2, 15, 6, 18, 6, 12, 11, 26, 5, 14, 9, 5, 14, 26, 22, + 18, 26, 5, 12, 22, 21, 18, 17, 26, 6, 18, 18, 26, 14, 14, 6, + 12, 24, 11, 21, 24, 9, 6, 9, 6, 10, 7, 25, 17, 16, 16, 22, + 16, 16, 25, 17, 25, 24, 23, 2, 21, 14, 12, 17, 21, 1, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1527,1104 +1298,1177 @@ _hb_ucd_u8[17612] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, - 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, - 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, - 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, - 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, - 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, - 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, - 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, - 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, - 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, - 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, - 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, - 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, - 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, - 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, - 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, - 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, - 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, - 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, - 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, - 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, - 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, - 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, - 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, - 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, - 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, - 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, - 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, - 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, - 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, - 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, - 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, - 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, - 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, - 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, - 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, - 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, - 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, - 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, - 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, - 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, - 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, - 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, - 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, - 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, - 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, - 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, - 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, - 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, - 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, - 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, - 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, - 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, - 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, - 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, - 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, - 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, - 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, - 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, - 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, - 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, - 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, - 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, - 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, - 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17, - 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, - 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, - 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, - 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, - 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, - 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, - 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, - 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, - 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, - 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, - 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, - 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, - 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, - 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, - 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, - 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, - 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 17, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 20, 20, 20, 20, 20, - 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, 33, - 34, 35, 34, 34, 36, 37, 20, 20, 20, 20, 20, 20, 38, 20, 39, 40, - 41, 41, 41, 41, 41, 42, 43, 44, 20, 20, 20, 20, 20, 20, 20, 45, - 46, 20, 20, 47, 20, 20, 20, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 20, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 60, 13, 13, - 13, 61, 62, 13, 13, 13, 13, 63, 13, 13, 13, 13, 13, 13, 64, 65, - 20, 20, 66, 20, 13, 13, 13, 13, 67, 13, 13, 13, 68, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, - 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, - 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 2, 2, 2, 2, 2, 3, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, - 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, - 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, - 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, - 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, - 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, - 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, - 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, - 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, - 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, - 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, - 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, - 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, - 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, - 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, - 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, - 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, - 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, - 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, - 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, - 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, - 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, - 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, - 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, - 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, - 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, - 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, - 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, - 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, - 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, - 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, - 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, - 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, - 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, - 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 62, 62, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, - 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, - 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, - 73, 73, 73, 73, 73, 73, 6, 6, 6, 2, 2, 2, 2, 2, 8, 8, - 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, - 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, - 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, - 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, - 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, - 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, - 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, - 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 19, 19, - 2, 19, 2, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, - 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, 75, 75, 75, 75, - 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 12, 12, - 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, - 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, 2, 2, 68, 68, - 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 2, 2, 30, - 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, 87, - 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 12, 12, - 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 13, 13, - 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, - 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, - 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, - 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, - 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, - 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, - 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, - 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, - 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, - 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, - 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161, - 161,161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161, - 161, 2,161,161, 2,161,161,161, 2,161,161,161,161,161,161,161, - 2,161,161, 2, 2, 2,170,170,170,170,170,170,170,170,170,170, - 170,170, 2, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, - 110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, 19, - 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, - 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, - 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, - 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, - 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, - 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, - 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, - 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, - 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, - 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, - 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, - 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2,165,165, - 165,165,165,165,165,165,165,165,165,165,165,165, 2, 2, 2,165, - 165,165,165,165,165,165, 2, 2, 2, 2, 2, 2,165,165,156,156, - 156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3,147,147,147,147,147,147,147,147,148,148, - 148,148,148,148,148,148,148,148, 2, 2, 2, 2, 2, 2,158,158, - 158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153, - 153,153,153,153,153,153,153,153,153,153, 2, 2, 2, 2,149,149, - 149,149,149,149,149,149,149,149,149,149,149,149,149, 2, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, - 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101, 2, - 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, 2, 2, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, 96, 96,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111, 2,100,100, - 100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 2, 2, 2,108,108,108,108,108,108,108,108,108,108, - 2,108,108,108,108,108,108,108, 2, 2, 2, 2, 2, 2,129,129, - 129,129,129,129,129, 2,129, 2,129,129,129,129, 2,129,129,129, - 129,129,129,129,129,129,129,129,129,129,129,129, 2,129,129,129, - 2, 2, 2, 2, 2, 2,109,109,109,109,109,109,109,109,109,109, - 109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, 2, 2,107,107, - 107,107, 2,107,107,107,107,107,107,107,107, 2, 2,107,107, 2, - 2,107,107,107,107,107,107,107,107,107,107,107,107,107,107, 2, - 107,107,107,107,107,107,107, 2,107,107, 2,107,107,107,107,107, - 2, 1,107,107,107,107,107, 2, 2,107,107,107, 2, 2,107, 2, - 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107,107,107,107,107, - 107,107, 2, 2,107,107,107,107,107,107,107, 2, 2, 2,171,171, - 171,171,171,171,171,171,171,171, 2,171, 2, 2,171, 2,171,171, - 171,171,171,171, 2,171,171, 2,171, 2, 2,171, 2,171,171,171, - 171, 2,171,171,171,171,171, 2, 2, 2, 2, 2, 2, 2, 2,171, - 171, 2, 2, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, - 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, - 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, - 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, - 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102, - 102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, - 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126,126, - 126,126,126,126,126, 2,142,142,142,142,142,142,142,142,142,142, - 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, - 125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125,154,154, - 154,154,154,154,154, 2, 2,154, 2, 2,154,154,154,154,154,154, - 154,154, 2,154,154, 2,154,154,154,154,154,154,154,154,154,154, - 154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154,154, - 2, 2, 2, 2, 2, 2,150,150,150,150,150,150,150,150, 2, 2, - 150,150,150,150,150,150,150,150,150,150,150, 2, 2, 2,141,141, - 141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140, - 140, 2, 2, 2, 2, 2,121,121,121,121,121,121,121,121,121, 2, - 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2,169,169, - 169,169,169,169,169,169,169,169, 2, 2, 2, 2, 2, 2,133,133, - 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133, - 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133, - 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2, - 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134, - 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, - 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, - 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143, - 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, - 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, - 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, - 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, - 2, 2, 2, 2, 2, 2,163,163,163,163,163,163,163,163,163, 2, - 163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163,163, - 163, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, - 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, - 63, 63, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, - 157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 2, 2, 80, 80, 80, 2, 2, 2, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2,166,166, - 166,166,166,166,166,166,166,166, 2, 2, 2, 2, 2, 2, 79, 2, - 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, - 159,159,159,159,159,159,159,159,159,159,159,159,159, 2,159,159, - 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, - 103,103,103,103, 2, 2,119,119,119,119,119,119,119,119,119,119, - 119,119,119,119, 2, 2,119,119, 2,119,119,119,119,119, 2, 2, - 2, 2, 2,119,119,119,167,167,167,167,167,167,167,167,167,167, - 2, 2, 2, 2, 2, 2,146,146,146,146,146,146,146,146,146,146, - 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, - 13, 13,155, 2, 2, 2,136,136,136,136,136,136,136,136,155,155, - 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, - 2, 2, 2, 2, 2,155,136, 2, 2, 2, 2, 2, 2, 2, 17, 17, - 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, 15, - 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, - 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, 2, - 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, - 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, - 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, - 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131, - 131,131,131,131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, - 2,131,131,131,131,131, 2,131,131,131,131,131,131,131, 2, 2, - 2, 2, 2, 19, 19, 19, 56, 56, 56, 56, 56, 56, 56, 2, 56, 2, - 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, - 56, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 6,151,151,151,151,151,151,151,151,151,151, - 151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151,151, - 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, - 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, - 2, 2, 2, 2, 2,152,164,164,164,164,164,164,164,164,164,164, - 2, 2, 2, 2, 2, 2,168,168,168,168,168,168,168,168,168,168, - 168, 2, 2, 2, 2,168, 30, 30, 30, 30, 2, 30, 30, 2,113,113, - 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, - 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, - 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, - 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, - 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 0, 13, 2, 2, 2, 2, 2, 2, 2, 13, 13, - 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, - 9, 9, 9, 14, 9, 9, 15, 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, 16, 17, 9, 9, 9, 9, - 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, 22, 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, 23, 9, - 9, 9, 9, 9, 24, 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, 25, 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, 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, 26, 27, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, - 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, - 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, - 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, - 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, - 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, - 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0, - 110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131, - 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147, - 148,149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160, - 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, 0, 0, 0,166, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 167, 0, 0, 0,168,169, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,173, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,174, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,176,177, 0, 0, 0, 0,178,179, 0, 0, 0,180,181,182,183, - 184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199, - 200,201,202,203,204,205,206,207,208,209,210,211,212,213, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 0, 19, 0, 20, 21, 0, + 0, 22, 23, 24, 25, 26, 0, 0, 0, 0, 27, 28, 29, 30, 0, 31, + 0, 32, 33, 0, 2, 34, 0, 0, 2, 1, 35, 0, 2, 1, 0, 0, + 2, 1, 0, 0, 2, 1, 0, 0, 0, 1, 0, 0, 2, 36, 0, 0, + 2, 1, 0, 0, 37, 1, 0, 0, 0, 38, 0, 0, 39, 40, 0, 0, + 41, 42, 0, 43, 44, 0, 45, 46, 0, 47, 0, 0, 48, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 51, 4, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 55, 0, 0, 56, 0, + 57, 58, 59, 0, 60, 5, 61, 0, 62, 0, 63, 0, 64, 0, 0, 0, + 0, 65, 66, 0, 0, 0, 0, 0, 0, 67, 68, 0, 0, 0, 0, 0, + 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 71, 0, 0, 0, 3, 0, 0, 0, 72, 0, 73, 0, 0, 74, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, + 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 6, 78, 0, 0, 0, + 0, 5, 79, 0, 80, 81, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, + 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, + 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 0, 90, 91, 0, 0, 0, + 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 93, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 95, 0, 96, 0, 0, 97, 0, 98, 0, 0, 0, 0, 0, 6, 99, 0, + 9, 0, 0,100,101, 0, 7, 0, 0,102, 0, 0,103, 0, 0, 0, + 0, 0,104, 0,105, 1,106, 0, 0,107, 0, 0, 0,108, 0, 0, + 0,109, 0, 0, 0, 0, 0, 0, 3,110, 0, 0, 3, 0, 0, 0, + 111, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0,113,114, 0, 0, 0, 0, 8, 0, 4,115, 0,116, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0,117, 0,118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,121, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 0, 0, 0, 0,123, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,124,125,126, 0, 0, 0, 0,127, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129, 0, 0,130, + 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 131, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,133, 0, 0, 0, 0, 0, 0, 0,134, 0, 0, 0, 0, 0, + 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,136, 0, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 1, 12, 0, 0, 1, 1, + 1, 1, 1, 49, 50, 5, 51, 52, 53, 5, 5, 22, 32, 23, 1, 54, + 24, 55, 16, 33, 56, 57, 58, 1, 1, 1, 0, 0, 0, 0, 6, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 7, 60, 1, 34, 5, + 7, 61, 62, 63, 64, 65, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 68, 0, 0, 0, 69, 70, 71, 35, 1, 25, 0, 0, + 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 26, 16, 26, + 73, 27, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, + 0, 0, 36, 25, 75, 37, 7, 37, 76, 0, 0, 0, 0, 0, 0, 0, + 6, 1, 7, 0, 0, 17, 0, 0, 0, 0, 0, 8, 38, 1, 1, 13, + 13, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, + 0, 0, 0, 6, 18, 1, 0, 0, 8, 16, 5, 1, 1, 1, 77, 7, + 36, 18, 78, 7, 35, 1, 0, 0, 0, 4, 79, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 4, 0, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 3, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 85, 86, 0, 0, 0, + 0, 0, 87, 88, 89, 90, 91, 92, 0, 0, 0, 0, 0, 0, 0, 93, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 28, 0, 0, 0, + 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, + 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 14, 0, 0, 20, 0, 0, + 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, + 0, 0, 0, 6, 29, 0, 3, 0, 0, 0, 0, 13, 1, 96, 0, 0, + 0, 0, 1, 18, 33, 97, 25, 23, 7, 1, 1, 1, 1, 27, 1, 7, + 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 6, 23, 1, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, + 0, 0, 12, 32, 24, 5, 99, 22, 42, 17, 0, 10, 11, 0, 7, 1, + 7,100,101, 1, 1, 1, 1, 1, 1, 1, 1,102,103,104, 0, 0, + 0, 0,105, 1,106, 10, 20,107,108, 5, 10, 0, 0, 0, 0, 0, + 0, 6, 11, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 109,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 0, 0, 0, + 0, 6, 0, 1, 1, 11, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, + 0, 0, 11, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 1, + 1, 1, 11, 0, 0, 0, 0, 0, 43, 40, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 44,112, 10, 8, 20, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, + 0, 0, 0, 0, 0,113, 1, 16, 5, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 12, 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,115, 2, 0,116, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 13, 11, 0, 0, 0, 0, 0, 0, + 6, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 39, 0, 45, + 16, 18, 29, 0, 0, 0, 46, 27, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 2, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 3, 0, 0, 3, 0, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 31, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 9, 0, 8, 1, 10, 1, 10, 0, 0, 0, 0, + 0, 30, 3, 0, 0, 0, 14, 21, 0, 0, 0, 0, 0, 19, 47, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 28, 15, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 21, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 28, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 22, 42, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,119, 0,120,121,122,123, 0, 43, 5, 48, 13, + 34, 0, 0, 0, 0, 0, 0, 0, 8, 11, 0, 0, 0, 0, 8, 10, + 0, 0, 0, 0, 0, 0, 1, 12, 1, 1, 1, 1, 26, 1, 38, 44, + 12, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, + 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0,124, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 6, 19, + 0, 8, 0, 20, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 1, + 125, 0, 0, 0, 0, 0,230,230,230,230, 0, 0, 0, 9, 9, 0, + 0, 0, 0, 9, 0, 0,220,220,220,220, 0, 0, 0,230,230,230, + 220,230, 0, 0,230,230, 7, 0, 0, 0,230, 0, 0, 0,230,230, + 0, 0,230,230,230, 0, 0,230,230,230, 0, 0, 9, 0, 0, 0, + 0, 7,230,230,230,220, 0,220, 0, 0,230,220,220,220, 0, 0, + 230, 0, 0,230, 0, 0, 0, 0, 7, 0, 1, 1, 1, 1,220,230, + 230,230,220,220,230,230,220,230,230,220,230, 0, 0,230,230,220, + 0, 0, 0, 9, 9, 0,220, 0, 0, 0, 0, 0, 9, 9, 0, 9, + 7, 0, 1,220,220,220,220,220,220,230,230,230,220,220,230,220, + 220,230,230,220,230,230,220,230,220,230,230,230, 0,230, 0,220, + 220,220,220,220, 0, 0, 9, 9, 0, 0, 1, 0, 0, 0, 0, 0, + 0,220,230, 0,230,230, 0, 0,220,220, 0, 0,230,220, 0, 0, + 9, 7,220,220,220, 0,230,232,220,220,220,220,232,216,220,202, + 202,220,220,220,220,202,202,220,220,220,230,240,230,220,230,220, + 220, 0,232,220,220,230,233,234,234,233,234,234,233,230, 0,220, + 230,230,230,230,222,220,230,222,228,230, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, + 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, + 34,230, 35, 0, 0, 0,230, 0,220,230, 0, 36, 0, 0,220,220, + 230,220,220,230,230, 0,230,230, 0,220, 27, 28, 29,230, 0,230, + 220,230, 0, 84, 91, 0,103,103, 9, 0,107,107,107,107,118,118, + 9, 0,122,122,122,122, 0,220, 0,220, 0,216, 0, 0, 0,129, + 130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0, + 230,230, 9, 0,230,230, 0, 0,220, 0, 0,228, 0, 0, 0,222, + 230,220,230, 0, 0,220,230,220, 0,220,230,230,230,234,230, 0, + 1, 1,230,234,214,220,202,230,230,230,230,230,232,228,228,220, + 218,230,233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, + 1,230,220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, + 8, 0,220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1, + 220, 0, 0,230,220, 0, 0, 7, 9, 0, 6, 6, 0, 0, 0, 0, + 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216, + 216, 0,232,232,220,230,230,230, 7, 0, 1, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 3, 0, 0, 0, 0, 4,101, 0,112,128,169, + 0, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,237, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 1, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, + 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, + 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 2, 1, 40, 41, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 36, 0, 0, + 8, 0, 0, 0, 0, 44, 0, 0, 52, 0, 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0, 24, 48, 0, 0, + 0, 0, 0, 0, 28, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 28, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 60, 64, 0, 68, 0, 72, 76, 80, 0, 0, 0, 0, 0, 8, 84, 88, + 0, 92, 16, 8, 0, 0, 0, 4, 4, 16, 4, 4, 4, 4, 4, 4, + 4, 24, 20, 0, 96, 0, 16,100,104, 0, 4, 4,108, 0, 0, 0, + 40,112, 8, 16, 4, 4, 4, 4, 4, 8,116,120,124,128, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 8, 0, 0, 24, 20,132, 36, 0, 28, 0,136, 16, 4, + 4, 4, 0, 0, 0, 0, 24, 12, 12,140,144, 12,148, 0,152, 8, + 4, 4, 0, 0,156, 0, 8, 8, 0, 24, 20, 8, 4, 0, 0, 0, + 8, 0, 0,160, 8, 8, 0, 0, 24, 20, 0, 8, 0, 8, 0, 8, + 0, 0, 0, 0, 40, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 16, + 4,164, 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 0,168,172,176, + 0,180, 0, 24, 20, 0, 0, 0, 0, 0, 0, 0, 0,184, 16, 8, + 28, 8, 0, 0, 0, 8, 4, 4, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 40, 12, 48, 0, 0, 4, 4, 8, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 40, 20, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32,188,192, 0, 0, 0, 0, 0, 0, 0, 4, 5, + 6, 7, 8, 9, 10, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 12, 13, 2, 2, 2, 2, 14, 0, 0, 0, 0, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 25, 26, 3, 3, 3, 27, + 0, 0, 0, 28, 29, 30, 0, 31, 32, 33, 34, 35, 36, 37, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 38, 1, 1, 39, 1, 40, 1, 1, 1, 41, 0, 42, 1, 1, + 43, 1, 1, 1, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20, + 21, 8, 8, 8, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 2, 2, 51, 52, 53, 54, 9, 9, 9, 9, 9, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 8, 8, 70, 71, 72, + 73, 74, 75, 5, 5, 5, 5, 76, 5, 5, 5, 5, 5, 5, 5, 15, + 15, 5, 5, 5, 5, 77, 5, 78, 79, 80, 81, 82, 83, 1, 84, 85, + 86, 87, 88, 89, 90, 91, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 92, 1, 1, 1, 1, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 93, 16, 16, 94, 95, 96, 97, 98, + 99,100,101,102,103,104,105, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,106, 0, + 0, 1, 1,107,108,109, 13, 13, 13,110,111,112,113,114,115,116, + 117,118,119, 0,120,121,122,123,124,125,126, 17, 17,127,128,129, + 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, + 146,147,148,149,150,151,152,153,154, 0,155,156,157,158, 0,159, + 160,161,162,163,164,165,166,167,168,169,170, 0,171,172,173, 7, + 7, 7, 7, 7, 7, 7,174,175, 7,176, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,177, 4, + 4, 4, 4, 4, 4, 4, 4,178, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4,179, 11, 11, 11, 11,180, 0, 0, 0, 0, + 0,181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 12, 12, 12,182,183,184,185, 0, 0,186, 0,187,188,189,190, 3, + 3, 3, 3, 3, 3, 14, 14, 14,191,192,193, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,195, + 196,197, 18, 18,198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,199,200, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5,201, 5, 5, 5,202,203,204, 5, + 205,206,207,208,209,210, 0,211,212,213, 5, 5,214, 5,215, 10, + 10, 10, 10, 10,216, 0, 0, 0, 0, 0, 0, 0, 0,217, 0,218, + 219,220, 0, 0,221, 0, 0, 0,222, 0,223, 0,224, 0,225,226, + 227,228, 0, 0, 0, 0, 0,229,230,231, 0,232,233, 0, 0,234, + 235, 5,236,237, 0, 5, 5, 5, 5, 5, 5, 5,238, 5,239,240, + 241, 5, 5,242,243, 5,244, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,245, 1, 1,246, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,247, 1, 1, 1, + 1, 1, 1, 1, 1, 1,248, 1, 1, 1, 1,249, 0, 0, 0, 1, + 1, 1, 1,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1,251, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1,252, 0, 0, 0, 0, 0, 0, 0,253, + 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 12, + 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0,136, + 136,136,136,136,136,136,136, 80, 80, 80, 80, 80, 80, 80, 80, 19, + 19, 19, 19, 19, 19, 19, 19, 3, 3, 3, 3, 3, 3, 3, 3, 63, + 63, 63, 63, 63, 63, 63, 63, 39, 39, 39, 39, 39, 39, 39, 39, 28, + 28, 28, 28, 28, 28, 28, 28, 79, 79, 79, 79, 79, 79, 79, 79,131, + 131,131,131,131,131,131,131, 1, 1, 1, 1, 1, 1, 1, 1,127, + 127,127,127,127,127,127,127, 6, 6, 6, 6, 6, 6, 6, 6,155, + 155,155,155,155,155,155,155,139,139,139,139,139,139,139,139, 9, + 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 30, + 30, 30, 30, 30, 30, 30, 30,110,110,110,110,110,110,110,110, 77, + 77, 77, 77, 77, 77, 77, 77, 17, 17, 17, 17, 17, 17, 17, 17, 27, + 27, 27, 27, 27, 27, 27, 27, 33, 33, 33, 33, 33, 33, 33, 33,113, + 113,113,113,113,113,113,113, 49, 49, 49, 49, 49, 49, 49, 49, 25, + 25, 25, 25, 25, 25, 25, 25, 29, 29, 29, 29, 29, 29, 29, 29, 7, + 7, 7, 7, 7, 7, 7, 7, 32, 32, 32, 32, 32, 32, 32, 32, 8, + 8, 8, 8, 8, 8, 8, 8, 99, 99, 99, 99, 99, 99, 99, 99, 31, + 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 2,105, + 105,105,105,105,105,105,105, 55, 55, 55, 55, 55, 55, 55, 55, 62, + 62, 62, 62, 62, 62, 62, 62, 56, 56, 56, 56, 56, 56, 56, 56, 91, + 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 2, 2, 2, 2,100, + 100,100,100,100,100,100,100,119,119,119,119,119,119,119,119, 14, + 14, 14, 14, 14, 14, 14, 14,130,130,130,130,130,130,130,130, 94, + 94, 94, 94, 94, 94, 94, 94,157,157,157,157,157,157,157,157,137, + 137,137,137,137,137,137,137,146,146,146,146,146,146,146,146, 20, + 20, 20, 20, 20, 20, 20, 20, 35, 35, 35, 35, 35, 35, 35, 35, 0, + 0, 0, 0, 0, 0, 2, 2, 84, 84, 84, 84, 84, 84, 84, 84, 40, + 40, 40, 40, 40, 40, 40, 40, 97, 97, 97, 97, 97, 97, 97, 97,124, + 124,124,124,124,124,124,124,123,123,123,123,123,123,123,123,125, + 125,125,125,125,125,125,125,140,140,140,140,140,140,140,140,159, + 159,159,159,159,159,159,159,132,132,132,132,132,132,132,132, 37, + 37, 37, 37, 37, 37, 37, 37, 22, 22, 22, 22, 22, 22, 22, 22, 24, + 24, 24, 24, 24, 24, 24, 24, 58, 58, 58, 58, 58, 58, 58, 58, 76, + 76, 76, 76, 76, 76, 76, 76, 26, 26, 26, 26, 26, 26, 26, 26, 75, + 75, 75, 75, 75, 75, 75, 75, 89, 89, 89, 89, 89, 89, 89, 89,114, + 114,114,114,114,114,114,114,141,141,141,141,141,141,141,141,133, + 133,133,133,133,133,133,133,163,163,163,163,163,163,163,163, 4, + 4, 4, 4, 4, 4, 4, 4, 70, 70, 70, 70, 70, 70, 70, 70, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2, 2, 68, + 68, 68, 68, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 87, + 87, 87, 87, 87, 87, 87, 87,135,135,135,135,135,135,135,135, 85, + 85, 85, 85, 85, 85, 85, 85, 96, 96, 96, 96, 96, 96, 96, 96,109, + 109,109,109,109,109,109,109,102,102,102,102,102,102,102,102, 64, + 64, 64, 64, 64, 64, 64, 64, 61, 61, 61, 61, 61, 61, 61, 61, 65, + 65, 65, 65, 65, 65, 65, 65, 2, 0, 0, 0, 0, 0, 0, 0,108, + 108,108,108,108,108,108,108,142,142,142,142,142,142,142,142,121, + 121,121,121,121,121,121,121,166,166,166,166,166,166,166,166,167, + 167,167,167,167,167,167,167, 0, 2, 2, 2, 2, 2, 2, 2,151, + 151,151,151,151,151,151,151,152,152,152,152,152,152,152,152, 38, + 38, 38, 38, 38, 38, 38, 38, 90, 90, 90, 90, 90, 90, 90, 90, 23, + 23, 23, 23, 23, 23, 23, 23, 36, 36, 36, 36, 36, 36, 36, 36, 30, + 2, 30, 30, 30, 30, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 93, + 93, 93, 93, 93, 93, 93, 93, 73, 73, 73, 73, 73, 73, 73, 73, 9, + 9, 9, 9, 9, 9, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 86, + 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 2, 2, 2, 67, + 67, 67, 67, 67, 67, 67, 67, 51, 51, 51, 51, 51, 51, 51, 51,104, + 104,104,104,104,104,104,104,170,170,170,170,170,170,170,170, 78, + 78, 78, 78, 78, 78, 78, 78,144,144,144,144,144,144,144,144,165, + 165,165,165,165,165,165,165,171,171,171,171,171,171,171,171,126, + 126,126,126,126,126,126,126,150,150,150,150,150,150,150,150,134, + 134,134,134,134,134,134,134,138,138,138,138,138,138,138,138,175, + 175,175,175,175,175,175,175, 18, 18, 18, 18, 18, 18, 18, 18, 0, + 0, 0, 0, 0, 2, 0, 0, 60, 60, 60, 60, 60, 60, 60, 60, 69, + 69, 69, 69, 69, 69, 69, 69,118,118,118,118,118,118,118,118, 59, + 59, 59, 59, 59, 59, 59, 59,106,106,106,106,106,106,106,106,156, + 156,156,156,156,156,156,156,147,147,147,147,147,147,147,147,148, + 148,148,148,148,148,148,148,169,169,169,169,169,169,169,169,172, + 172,172,172,172,172,172,172,164,164,164,164,164,164,164,164,168, + 168,168,168,168,168,168,168,174,174,174,174,174,174,174,174, 0, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 21, 21, 21, 21, 21, 21, 21, 21, 16, + 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 12, 12, 12, 2, 74, + 74, 74, 74, 74, 74, 74, 74, 42, 42, 42, 42, 42, 42, 42, 42, 50, + 50, 50, 50, 50, 50, 50, 50,161,161,161,161,161,161,161,161, 47, + 47, 47, 47, 47, 47, 47, 47,120,120,120,120,120,120,120,120,116, + 116,116,116,116,116,116,116, 98, 98, 98, 98, 98, 98, 98, 98, 57, + 57, 57, 57, 57, 57, 57, 57, 88, 88, 88, 88, 88, 88, 88, 88,117, + 117,117,117,117,117,117,117,112,112,112,112,112,112,112,112,101, + 101,101,101,101,101,101,101,111,111,111,111,111,111,111,111,154, + 154,154,154,154,154,154,154,143,143,143,143,143,143,143,143,115, + 115,115,115,115,115,115,115, 0, 0, 19, 0, 0, 0, 0, 0, 95, + 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 11, 11, 11, 11, 11, 10, + 10, 10, 10, 10, 10, 10, 10, 22, 22, 22, 2, 2, 2, 22, 22, 2, + 25, 25, 25, 25, 25, 25, 25, 34, 34, 34, 34, 34, 34, 34, 34, 52, + 52, 52, 52, 52, 52, 52, 52, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 0, 0, 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 30, 30, 2, 2, + 2, 12, 12, 12, 12, 12, 12, 71, 71, 71, 71, 71, 71, 71, 71, 41, + 41, 41, 41, 41, 41, 41, 41, 53, 53, 53, 53, 53, 53, 53, 53, 81, + 81, 81, 81, 81, 81, 81, 81, 66, 66, 66, 66, 66, 66, 66, 66, 72, + 72, 72, 72, 72, 72, 72, 72,173,173,173,173,173,173,173,173, 83, + 83, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82, 82, 82, 82, 82,158, + 158,158,158,158,158,158,158,153,153,153,153,153,153,153,153,145, + 145,145,145,145,145,145,145,103,103,103,103,103,103,103,103,160, + 160,160,160,160,160,160,160, 2, 3, 3, 2, 3, 2, 2, 3, 3, + 3, 3, 2, 3, 3, 3, 3, 19, 19, 19, 19, 19, 19, 19, 0, 2, + 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 0, 3, 3, 5, + 5, 5, 5, 5, 2, 2, 5, 11, 11, 11, 2, 2, 2, 2, 11, 10, + 10, 10, 10, 10, 10, 2, 10, 21, 21, 21, 21, 21, 2, 2, 21, 22, + 2, 22, 22, 22, 22, 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, + 2, 23, 23, 23, 23, 23, 23, 16, 16, 16, 16, 16, 2, 16, 16, 16, + 2, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 20, + 2, 20, 20, 20, 20, 20, 20, 36, 36, 36, 36, 36, 36, 36, 2, 25, + 25, 25, 25, 25, 2, 25, 25, 8, 8, 8, 8, 8, 8, 2, 8, 2, + 2, 2, 2, 2, 8, 2, 2, 29, 29, 29, 29, 29, 29, 2, 2, 45, + 45, 45, 45, 45, 45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 44, 43, + 43, 43, 43, 43, 43, 43, 43, 31, 31, 2, 2, 2, 2, 2, 2, 48, + 48, 48, 48, 2, 2, 2, 2, 91, 91, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 2, 2, 9, 9, 9, 9, 9, 2, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, + 0, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 61, 0, + 17, 17, 17, 17, 17, 17, 17, 12, 12, 12, 12, 2, 2, 2, 2, 13, + 13, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 2, 0, + 0, 0, 2, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 2, 2, 0, + 0, 0, 2, 2, 2, 2, 0,135,135,135,135, 2, 2, 2, 2,161, + 161,161, 2,161,161,161,161,161,161, 2,161,161,161,161,161, 19, + 19, 19, 2, 2, 2, 2, 2,128,128,128,128,128,128,128,128, 57, + 2, 2, 2, 2, 2, 2, 2,112,112,112,112,112,112,112, 2,122, + 122,122,122,122,122,122,122,130,130,130, 2, 2, 2, 2, 2,165, + 165,165,165,165,165, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,149, + 149,149,149,149,149,149,149, 94, 94, 94, 94, 94, 94, 2, 2,129, + 129,129,129,129,129,129,129,107,107,107,107,107, 2, 2,107,107, + 107,107,107,107,107,107,107,107,107,107,107,107, 2, 2, 2,171, + 171,171,171,171,171, 2,171,123,123,123,123,123,123, 2, 2,102, + 102, 2, 2, 2, 2, 2, 2,154,154,154,154,154,154,154, 2, 2, + 2,150,150,150,150,150,150,169,169, 2, 2, 2, 2, 2, 2,138, + 138,138,138,138,138,138, 2,103,103,103,103,103,103, 2, 2,119, + 119, 2,119,119,119,119,119, 2, 2, 0, 0, 0, 0, 0, 0, 3, + 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 19, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, + 0, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 2, + 2, 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, + 9, 9, 2, 9, 2, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, + 9, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 4, + 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 14, 14, + 14, 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, + 3, 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, + 37, 37, 2, 2, 37, 37, 37, 38, 38, 2, 2, 2, 2, 2, 2, 64, + 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 2, 2, 90, + 90, 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 37, + 37, 37, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, + 3, 0, 3, 3, 3, 3, 3, 7, 1, 1, 1, 1, 7, 7, 7, 7, + 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, + 2, 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, + 2, 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, + 2, 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, + 2, 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, + 2, 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, + 11, 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, + 10, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, + 2, 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, + 10, 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, + 10, 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, + 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, + 2, 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 22, 22, 2, 22, 22, 22, 2, 22, 22, 2, 22, 2, 22, 22, 2, + 2, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 2, 22, 22, 22, + 2, 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, + 22, 22, 2, 2, 2, 2, 2, 23, 23, 2, 2, 23, 23, 23, 23, 23, + 2, 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, + 23, 23, 2, 23, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, + 2, 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 2, 16, 16, 16, 16, + 16, 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, + 2, 2, 2, 2, 16, 16, 2, 2, 2, 2, 2, 16, 16, 16, 2, 16, + 16, 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 2, + 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, + 36, 36, 36, 2, 36, 36, 36, 2, 2, 36, 36, 36, 36, 36, 36, 36, + 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, + 2, 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, + 2, 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, + 24, 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, + 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, + 18, 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, + 18, 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, + 25, 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 0, 0, 0, 0, + 25, 25, 2, 2, 2, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 30, + 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, + 30, 2, 2, 2, 2, 2, 2, 34, 34, 34, 34, 34, 2, 2, 2, 35, + 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, + 45, 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, + 44, 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 2, 2, 2, 2, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, + 2, 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 2, 2, 32, + 32, 0, 0, 32, 0, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, + 2, 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, + 28, 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, + 2, 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 2, 2, 52, + 52, 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 2, 2, 2, 2, 58, + 58, 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, + 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, + 91, 91, 91, 91, 2, 2, 91, 91, 91, 91, 91, 91, 91, 2, 2, 1, + 1, 1, 1, 2, 2, 2, 2, 62, 62, 62, 62, 62, 2, 62, 62, 93, + 93, 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 2, + 2, 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 6, + 6, 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, + 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, + 1, 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, + 9, 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 2, + 9, 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 0, + 0, 0, 0, 1, 1, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 1, 2, 2, 2, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 55, + 55, 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, + 2, 2, 2, 2, 2, 2, 2, 13, 13, 2, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, + 13, 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 17, + 17, 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 2, + 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 0, 12, + 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, + 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 77, + 77, 77, 77, 2, 2, 2, 2, 0, 0, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 19, 19, 19, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 60, + 60, 60, 60, 60, 2, 2, 2, 75, 75, 75, 75, 75, 75, 2, 2, 2, + 2, 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, + 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, + 84, 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, + 33, 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, + 68, 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, + 92, 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, 92, 92, 87, + 87, 87, 87, 87, 87, 87, 2, 19, 19, 19, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 87, + 87, 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 12, 12, 12, 12, 12, 2, 2, 2, 4, 4, 4, 4, 4, 2, + 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, + 14, 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, + 3, 3, 3, 3, 3, 0, 0, 1, 1, 1, 1, 1, 1, 6, 6, 3, + 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, + 2, 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, + 49, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, + 49, 49, 2, 49, 49, 2, 49, 49, 49, 49, 2, 2, 2, 2, 2, 0, + 0, 0, 0, 2, 2, 2, 0, 9, 2, 2, 2, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, + 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, + 42, 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, + 41, 41, 2, 2, 2, 2, 2,118,118,118, 2, 2, 2, 2, 2, 53, + 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 2, 2, 2, 2, 59, + 59, 59, 59, 59, 59, 2, 2, 50, 50, 50, 50, 50, 50, 2, 2, 50, + 50, 2, 2, 2, 2, 2, 2,104,104,104,104, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,104,161,161,161, 2,161,161, 2,161,161, + 161, 2,161,161, 2, 2, 2,170,170,170,170, 2, 2, 2, 2,110, + 110,110,110,110,110,110, 2,110,110,110,110,110,110, 2, 2, 19, + 19, 19, 19, 19, 19, 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 47, + 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, + 81, 81, 81, 81, 81, 2, 81,116,116,116,116,116,116,116, 2, 2, + 2, 2, 2, 2, 2, 2,116,128,128,128, 2,128,128, 2, 2, 2, + 2, 2,128,128,128,128,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, + 72, 2, 2, 2, 2, 2, 72,173,173, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, + 57, 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, + 57, 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 2, + 2, 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 2, 2, 2, + 78, 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 2, 2, 82, + 82, 82, 2, 2, 2, 2, 2,122,122, 2, 2, 2, 2, 2, 2, 2, + 122,122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, + 2, 2, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144, + 144, 2, 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165, 2, + 2, 2, 2, 2, 2,165,165, 3, 3, 3, 3, 3, 3, 3, 2,156, + 156, 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 3, + 2, 2, 2, 2, 2, 2, 2,148,148, 2, 2, 2, 2, 2, 2,158, + 158, 2, 2, 2, 2, 2, 2,153,153,153,153, 2, 2, 2, 2,149, + 149,149,149,149,149,149, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, + 2, 2, 2, 2, 2, 2, 94, 85, 85, 85, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 85, 2, 2,101, 2, 2, 2, 2, 2, 2, 2,101, + 101, 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111, + 111,111,111,111,111,111, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 2, 2, 2,108,108, 2,108,108,108,108,108,108, + 108, 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, + 2,129,129,129,129, 2,129,129,129,129,129,129,129, 2,129,129, + 129, 2, 2, 2, 2, 2, 2,109,109,109, 2, 2, 2, 2, 2,109, + 109, 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107, + 2, 2,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, + 2,107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, + 2, 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, + 2, 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,171, + 171, 2,171, 2, 2,171, 2,171, 2,171, 2, 2,171, 2,171,171, + 171,171, 2,171,171,171,171,171, 2, 2, 2, 2, 2, 2, 2, 2, + 171,171, 2, 2, 2, 2, 2,137,137,137,137, 2,137,137,137,137, + 137, 2, 2, 2, 2, 2, 2,124,124, 2, 2, 2, 2, 2, 2,114, + 114,114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, + 32, 32, 32, 32, 2, 2, 2, 33, 33, 33, 33, 2, 2, 2, 2,126, + 126,126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,126, + 126,126,126,126,126,126, 2,142,142,142,142, 2, 2, 2, 2,125, + 125,125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,125, 2, + 154, 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154, + 154,154,154,154,154, 2,154,154, 2, 2,154,154,154,154,154,154, + 154, 2, 2, 2, 2, 2, 2,150,150,150,150,150, 2, 2, 2,140, + 140,140, 2, 2, 2, 2, 2,121, 2, 2, 2, 2, 2, 2, 2, 7, + 7, 2, 2, 2, 2, 2, 2,133, 2,133,133,133,133,133,133,133, + 133,133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133, + 133,133,133,133, 2, 2, 2, 2, 2,134,134,134,134,134,134, 2, + 134,134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138, + 138, 2,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138, + 138, 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, + 2,143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143, + 143, 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143, + 143, 2, 2, 2, 2, 2, 2,175,175,175,175, 2, 2, 2, 2,175, + 175, 2, 2, 2, 2, 2, 2,145, 2, 2, 2, 2, 2, 2, 2,163, + 2,163,163,163,163,163,163,163,163,163, 2, 2, 2,163,163,163, + 163,163, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, + 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, + 63, 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, + 63, 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157, + 157,157, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 2, 2, 80, + 80, 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127, 2,166, + 166, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115, + 115,115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159, + 159,159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,119, + 119,119,119,119,119, 2, 2, 2, 2, 2, 2, 2,119,119,119,167, + 167, 2, 2, 2, 2, 2, 2,146,146,146, 2, 2, 2, 2, 2,172, + 2, 2,172,172,172,172,172,172,172,172,172, 2, 2, 2, 2, 99, + 99, 99, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136, + 139, 13, 13,155, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 2,155, + 155,155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136, + 136,136,136,136,136,136, 2,136,136,136, 2, 2, 2, 2, 2, 17, + 17, 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, 17, 2, 17, + 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, + 2, 15, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 17, 2, 2, 2, + 2, 2, 2, 17, 17, 17, 17,139,139,139,139, 2, 2, 2, 2,105, + 105,105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, + 2, 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 1, + 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0,131, + 131,131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2, + 131,131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, + 56, 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, + 56, 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, + 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151, + 151,151,151,151, 2, 2, 2,151,151,151,151,151,151, 2, 2,151, + 151, 2, 2, 2, 2,151,151,160,160,160,160,160,160,160, 2,152, + 152, 2, 2, 2, 2, 2,152,164,164, 2, 2, 2, 2, 2, 2,168, + 168,168, 2, 2, 2, 2,168,174,174,174,174,174,174,174, 2,174, + 174,174,174,174,174, 2, 2, 2, 2, 2, 2, 2, 2,174,174, 30, + 30, 30, 30, 2, 30, 30, 2,113,113,113,113,113, 2, 2,113,113, + 113,113,113,113,113,113, 2,132,132,132,132, 2, 2, 2, 2,132, + 132, 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, + 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, + 2, 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, + 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 2, + 3, 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, + 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, + 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 0, 0, 0, 10, 0, 11, 12, 13, 0, 0, 0, 14, 0, 0, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 17, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 19, + 20, 21, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, + 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, + 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, + 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, + 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, + 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, + 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, + 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, + 0,107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, + 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123, + 124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138, + 139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154, + 155,156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,162, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, + 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, + 0,170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0, + 178,179, 0, 0, 0,180,181,182,183,184,185,186,187,188,189,190, + 191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, + 207,208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, }; -static const uint16_t -_hb_ucd_u16[10400] = +static const uint16_t _hb_ucd_u16[10784]= { - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, - 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, - 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32, - 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, - 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, - 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, - 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, - 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, - 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, - 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 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, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 224, 224, 768, 424, 432, 440, 448, 776, 224, 224, 784, 792, 72, 800, 40, 808, + 48, 48, 48, 816, 824, 48, 48, 832, 840, 848, 856, 864, 872, 880, 48, 888, + 48, 48, 48, 896, 904, 40, 40, 40, 40, 912, 40, 96, 920, 928, 936, 456, + 64, 64, 64, 64, 64, 64, 64, 944, 952, 960, 968, 40, 976, 984, 48, 992, + 72, 72, 72, 40, 40, 40, 48, 48,1000, 48, 48, 48,1008, 48, 48, 48, + 48, 48, 48,1016, 72,1024, 40, 40,1032, 464, 64,1040,1048, 8,1056,1064, + 1072,1080, 8, 8,1088, 64,1096,1104, 8, 8, 8, 8, 8,1112,1120,1128, + 1136,1144, 8, 64,1152, 8, 8, 8, 8, 8, 472,1160, 232, 8,1168,1176, + 8,1184,1192,1200, 8,1208, 176, 8,1216,1224, 8, 8,1232, 64,1240, 64, + 480, 8, 8,1248,1256,1264,1272,1280,1288, 240, 128,1296,1304,1312, 144,1320, + 1328, 240, 128,1336,1344,1352, 304,1360,1368, 488, 128,1376,1384, 248, 144,1392, + 1400, 240, 128,1408,1416,1424, 144,1432,1440,1448,1456,1464,1472,1480, 304,1488, + 1496, 256, 128,1504,1512,1520, 144,1528,1536, 256, 128,1544,1552,1560, 144,1568, + 1576, 256, 8,1584,1592,1600, 144,1608,1616,1624, 8,1632,1640,1648, 304,1656, + 312, 8, 8,1664,1672,1680, 0, 0,1688, 8,1696,1704,1712,1720, 0, 0, + 1728,1736, 320,1744,1752, 8, 152,1760,1768,1776, 64,1784,1792,1800, 0, 0, + 8, 8,1808,1816, 496,1824,1832,1840,1848,1856, 72, 72,1864, 40, 40,1872, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 504,1880, 8, 8, 504, 8, 8,1888, 512, 520, 8, 8, + 8, 512, 8, 8, 8,1896,1904, 528, 8, 264, 72, 72, 72, 72, 72,1912, + 536, 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,1920, 8,1928,1936, 8, 8, 8, 8,1944,1952, + 8,1960, 8,1968, 8,1976,1984,1992, 8, 8, 8,2000,2008,2016, 80,2024, + 2032, 80, 8, 8,2040, 8, 8, 160,2048, 8,2056, 8, 8, 8, 8, 328, + 8, 120,2064,2072,2080, 8, 112,2088, 8, 8, 184, 8, 192,2096, 24, 24, + 8,2104, 8, 8, 8,2112,2120,2128, 80, 80,2136,2144, 64, 544,2152, 0, + 2160, 8, 8,2168,2176, 496,2184,2192, 336, 8,2200, 232, 8, 8,2208,2216, + 8, 8,2224,2232,2240, 232, 8, 552,2248, 72, 72,2256,2264,2272,2280,2288, + 40, 40,2296, 96, 96, 96,2304,2312, 40,2320, 96, 96, 64, 64, 64, 64, + 48, 48, 48, 48, 48, 48, 48, 48, 48,2328, 48, 48, 48, 48, 48, 48, + 168, 560, 168, 168, 560,2336, 168,2344, 344, 344, 344,2352,2360,2368,2376,2384, + 2392,2400,2408,2416,2424,2432,2440,2448,2456,2464, 568, 568,2472,2480,2488,2496, + 2504,2512,2520,2528,2536, 88, 104, 104,2544,2552,2560, 24,2568,2576, 24,2584, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 2592, 24,2600, 24, 24, 24, 24,2608, 24,2616, 56,2624, 24,2632,2640, 24, + 24, 24, 264, 0, 576, 0, 88, 88, 88,2648, 24, 24, 24, 24,2656, 88, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,2664,2672, 24, 24,2680, + 24, 24, 24, 24, 24, 24,2688, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24,2696,2704, 88,2712, 24, 24,2720, 56,2728, 56, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 56, 56, 56, 56, 56, 56, 56, 56,2736,2744, 56, 56, 56,2752, 56,2760, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 24, 24, 24, 56,2768, 24, 24,2776, 24, 24, 24, 24, 24, 24, 24, 24, + 72, 72, 72, 40, 40, 40,2784,2792, 48, 48, 48, 48, 48, 48,2800,2808, + 40, 40,2816, 8, 8, 8,2824,2832, 8, 200, 208, 208, 208, 208, 64, 64, + 2840,2848,2856,2864,2872,2880, 0, 0, 24,2888, 24, 24, 24, 24, 24, 352, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 272, 0, 24, + 2896,2904,2912,2920, 312, 8, 8, 8, 8,2928, 536, 8, 8, 8, 8,2936, + 2944, 8, 8, 312, 8, 8, 8, 8, 120,2952, 8, 8, 24, 24,2960, 8, + 24, 584, 592, 24,2968, 600, 24, 24, 592, 24, 24, 600, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 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, 24, 24, 24, 24, + 8,2976, 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, 152, 24, 24, 24, 608, 8, 8, 552, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 2984, 8,2992, 0, 48, 48,3000,3008, 48,3016, 8, 8, 8, 8,3024,3032, + 456,3040,3048,3056, 48, 48, 48,3064,3072,3080,3088,3096,3104,3112, 0,3120, + 3128, 8,3136,3144, 8, 8, 8,3152,3160, 8, 8,3168,3176, 80, 64,3184, + 232, 8,3192, 8,3200,3208, 8, 152, 480, 8, 8,3216,3224, 360,3232,3240, + 8, 8,3248,3256,3264,3272, 8,3280, 8, 8, 8,3288,3296,3304,3312,3320, + 3328,3336, 208, 40, 40,3344,3352, 40, 40, 40, 40, 40, 8, 8,3360, 80, + 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, 368, 8,3368, 8, 8, 184, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 112, 8, 8, 8, 8, 8, 8, 192, 0, 0, + 3376,3384,3392,3400,3408, 8, 8, 8, 8, 8, 8,3416,3424,3432, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8,3440, 24, 8, 8, 8, 8,3448, 8, 8,3456, 0, 0,3464, + 64,3472, 64,3480,3488,3496,3504,3512, 8, 8, 8, 8, 8, 8, 8,3520, + 3528, 424, 432, 440, 448,3536,3544,3552, 8,3560, 8, 120,3568,3576,3584,3592, + 3600, 8, 520,3608, 112, 112, 0, 0, 8, 8, 8, 8, 8, 8, 8, 176, + 3616, 88, 88,3624, 104, 104, 104,3632,3640, 280, 376, 0, 0, 24, 24,3648, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 152, 8, 8, 8, 248,3656,3664, + 8, 8,3672, 8,3680, 8, 8,3688, 8,3696, 8, 8,3704,3712, 0, 0, + 72, 72,3720, 40, 40, 8, 8, 8, 8, 112, 80, 72, 72,3728, 40,3736, + 8, 8, 616, 8, 8, 8,3744, 624, 624,3752,3760,3768, 8, 8, 8, 368, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 200, 8, 328, 616, 0,3776, 96, 96,3784, 0, 0, 0, 0, + 3792, 8, 8,3800, 8,3808, 8,3816, 8, 120,3824, 0, 0, 0, 8,3832, + 8,3840, 8,3848, 8, 192, 0, 0, 8, 8, 8,3856, 88, 632, 88, 88, + 3864,3872, 8,3880, 640,3888, 8,3896, 8, 648, 0, 0,3904, 8,3912,3920, + 8, 8, 8,3928, 8,3936, 8,3944, 8,3952,3960, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 160, 0, 0, 0, 72, 72, 72,3968, 40, 40, 40,3976, + 8, 8,3984, 80,3992, 72,4000, 40,4008, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 88,4016, 8, 8,4024, 656,4032,4040, 0,4048, + 8, 648,4056, 8, 472,4064, 0, 8,4072, 0, 0, 8,4080, 0, 8, 200, + 4088, 8, 8,4096,4104, 632,4112,4120, 336, 8, 8,4128,4136, 8, 160, 80, + 4144, 8,4152,4160,4168, 8, 8,4176, 336, 8, 8,4184,4192,4200, 384,4208, + 8, 488, 664,4216,4224, 0, 0, 0,4232,4240,4248, 8, 8,4256,4264, 80, + 4272, 240, 128,4280,4288,4296,4304,4312,4320, 8, 8,4328,4336,4344,4352, 0, + 8, 8, 8,4360,4368,4376, 656, 0, 8, 8, 8,4384,4392, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 672,4400,4408,4416, 0, 0, + 8, 8, 8,4424,4432, 80,4440, 0, 8, 8,4448,4456, 80, 288,4464, 0, + 8,4472,4480,4488, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 664,4496, 0, 0, 0, 0, 0, 0, 72, 72, 40, 40, 320,4504, + 4512,4520, 8,4528,4536, 80, 0, 0, 0, 0,4544, 8, 8,4552,4560, 0, + 4568, 8, 8,4576,4584,4592, 8, 8,4600,4608,4616, 8, 8, 8, 8, 160, + 4624, 0, 0, 0, 0, 0,4632, 0, 0, 0, 0, 0, 8, 8,4640, 80, + 128, 8, 672,4648,4656, 320, 528,4664, 8,4672,4680,4688, 0, 0, 0, 0, + 4696, 8, 8,4704,4712, 80,4720, 8,4728,4736, 80, 8, 8,4744, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,4752, + 4760, 256, 8,4768,4776,4784, 0, 0, 0, 0, 0, 248, 88,4792,4800,4808, + 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, 192, 0, 0, 0, 0, 0, 0, + 104, 104, 104, 104, 104, 104,4816,4824, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8,4832, + 8, 8, 8, 136,4840,4848, 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, 176, + 8, 8, 8, 8, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 680,4856, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 160, 8, 120, 360, 8, 8, 8, 8, 120, 80, 8, 112,4864, + 8, 8, 8,4872,4880,4888,4896,4904, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,4912, 8,4920, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72, 72, 40, 40, 88,4928, 72,4936, 40,4944, 0, 0, + 8, 8, 8, 8,4952,4960, 688, 688,4968,4976, 0, 0, 0, 0,4984,4992, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 328, 0,5000, + 8, 120, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 696, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,5008, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 696,5016, 0,5024,5032, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 184, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 8, 8, 176, 152, 160,5040,5048, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5056, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5064, 24, 376, 24,5072, + 64, 64, 544, 64, 704, 24, 24, 24, 24, 24, 24, 24, 352, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 272, + 24, 24,5080, 24, 24, 24,5088,5096,5104, 24,5112, 24, 24, 24, 576, 0, + 24, 24, 24, 24,5120, 0, 0, 0, 0, 0, 0, 0, 88, 712, 88, 712, + 24, 24, 24, 24, 24, 608, 88, 640, 0, 0, 0, 0, 0, 0, 0, 0, + 72, 296, 40, 720, 728,5128, 168, 72, 392,5136,5144,5152,5160, 72, 296, 40, + 5168,5176, 40,5184,5192,5200, 736, 72, 744, 40, 72, 296, 40, 720, 728, 40, + 168, 72, 392, 736, 72, 744, 40, 72, 296, 40,5208, 72,5216,5224,5232,5240, + 40,5248, 72,5256,5264,5272,5280, 40,5288, 72,5296, 40,5304, 288, 288, 288, + 64, 64, 64,5312, 64, 64,5320,5328,5336,5344, 464, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5352,5360,5368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5376,5384,5392, 96, 96, 96,5400, 0,5408, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 152,5416,5424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,5432, 0, 8, 8,5440,5448, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,5456, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 680,5464, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120,5472,5480, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,5488, 120, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,5496, 704, 0, 0, + 72, 72, 392, 40,5504, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 384, 88, 88,5512,5520, 0, 0, 0, 0, + 384, 88,5528,5536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5544, 8,5552,5560,5568,5576,5584,5592,5600, 184,5608, 184, 0, 0, 0,5616, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 216, 24, 24, 24, 24, 24, 24, 352, 584, 400, 400, 400, 24, 272, + 5624, 24, 24, 24, 24, 24, 24, 24, 24, 24, 408, 0, 0, 0,5632, 24, + 5640, 24, 24, 216, 752, 760, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5648, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5656, 280, 280, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 264, 216, 376, + 216, 24, 24, 24, 416, 264, 24, 24, 416, 24, 408, 216, 760,5664, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 416, 408, 280,5672, 24, 24, 24,5680,5688,5696, 752, + 24, 24, 24, 24, 24, 24, 24, 24, 24,5704, 24, 24, 24, 24, 24,5712, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 112, 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, 112, 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, 248, 8, + 8, 8, 8, 8, 8, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 176, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 192, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5720, 0, 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,5728, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, - 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, - 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, - 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, - 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, - 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, - 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, - 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, - 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, - 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, 140, 209, - 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, - 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, - 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, - 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, - 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, - 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, - 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, - 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, - 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, - 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, - 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, - 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, - 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, - 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, - 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, - 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, - 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, - 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, - 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, - 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, - 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, - 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, - 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, - 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, - 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, - 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, - 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, - 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, - 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, - 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, - 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, - 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, - 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, - 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, - 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, - 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, - 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, - 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, - 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, - 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, - 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, - 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, - 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, - 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, - 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, - 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, - 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, - 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, - 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, - 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, - 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, - 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, - 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, - 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, - 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, - 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, - 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, - 11, 11, 12, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 57, 58, 59, 60, 60, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 7, 4, 4, 4, 4, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 110, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 114, 0, - 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 124, 125, 126, 126, 126, 127, - 128, 129, 130, 131, 132, 60, 133, 134, 135, 136, 0, 137, 138, 139, 0, 0, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 0, 126, 126, 126, 126, 126, 126, 126, 126, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 141, 142, 143, 143, 143, 143, 144, 11, 145, 146, 147, 4, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 166, 167, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 126, 126, 126, 126, 126, 169, 126, 170, 171, 172, 19, 173, - 19, 19, 19, 19, 174, 19, 175, 176, 177, 178, 19, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 168, 168, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 206, 206, 206, 207, 208, 209, 168, - 210, 211, 212, 213, 214, 168, 215, 216, 217, 218, 219, 220, 221, 222, 223, 168, - 224, 225, 226, 227, 228, 229, 230, 168, 168, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 168, 168, 258, 259, 260, 261, 262, 263, 264, 265, 168, 168, - 266, 168, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 168, 168, 278, - 279, 280, 281, 168, 282, 283, 284, 168, 168, 168, 168, 285, 286, 287, 288, 289, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, 168, - 290, 292, 290, 290, 290, 293, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 294, 295, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 297, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 298, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 301, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 302, 302, 302, 302, 302, 302, 302, 302, 303, 304, 305, 306, 307, 308, 309, 168, - 168, 168, 168, 168, 168, 310, 168, 168, 168, 311, 312, 168, 313, 314, 315, 316, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 318, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, 319, 319, 319, 319, - 319, 319, 319, 320, 321, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 322, - 323, 324, 324, 324, 325, 326, 327, 327, 327, 327, 327, 328, 168, 168, 168, 168, - 329, 330, 331, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 333, 168, 334, 335, 0, 336, - 0, 0, 0, 337, 338, 339, 340, 341, 189, 342, 168, 343, 0, 344, 168, 168, - 0, 345, 346, 347, 348, 349, 0, 0, 0, 0, 350, 0, 0, 0, 0, 351, - 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 354, 168, 168, 168, - 355, 356, 357, 168, 358, 359, 168, 168, 168, 168, 360, 361, 168, 168, 168, 168, - 168, 168, 168, 362, 168, 168, 168, 363, 168, 168, 168, 168, 168, 168, 168, 364, - 365, 365, 365, 366, 367, 368, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 369, 370, 168, 371, 168, 168, 168, 372, 373, 374, 375, 168, 168, 168, 168, - 376, 0, 377, 378, 0, 0, 379, 380, 381, 382, 168, 168, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 384, 0, 385, - 386, 387, 388, 389, 0, 0, 0, 0, 0, 390, 391, 392, 0, 0, 393, 332, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 394, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 395, 126, 126, 126, - 396, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 397, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 398, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, - 126, 126, 126, 126, 126, 126, 126, 126, 399, 168, 168, 168, 168, 168, 168, 168, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 400, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 401, 168, - 402, 0, 168, 168, 7, 7, 7, 403, 0, 1, 2, 3, 4, 4, 4, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, - 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, - 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, - 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, - 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, - 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, - 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, - 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, - 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, - 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, - 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, - 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, - 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, - 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, - 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, - 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, - 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, - 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, - 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, - 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, - 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, - 197, 198, 198, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 200, - 198, 198, 198, 198, 198, 201, 178, 178, 178, 178, 178, 178, 178, 178, 202, 26, - 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, - 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, - 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, - 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, - 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 222, - 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, - 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, - 18, 232, 165, 165, 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, - 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, - 2, 2, 2, 2, 2, 2, 2, 245, 14, 14, 246, 246, 14, 14, 14, 14, - 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 14, 14, 14, 14, 248, 14, - 248, 14, 249, 250, 14, 14, 251, 252, 0, 253, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, 0, 0, 0, 0, - 259, 26, 9, 9, 9, 9, 260, 26, 0, 0, 0, 0, 261, 262, 4, 0, - 0, 263, 0, 0, 2, 2, 2, 2, 2, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, - 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 268, 0, - 0, 0, 269, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, - 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 276, 26, 26, 26, 26, - 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, - 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, - 0, 0, 0, 0, 276, 296, 290, 290, 169, 169, 169, 295, 0, 0, 0, 0, - 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 290, 290, 290, 290, 290, 298, - 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 303, 303, 304, 26, 26, 18, 18, 18, 18, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, - 2, 307, 2, 2, 2, 2, 2, 2, 2, 308, 309, 258, 26, 26, 310, 2, - 311, 311, 311, 311, 311, 312, 0, 265, 313, 313, 313, 313, 313, 313, 313, 26, - 314, 314, 314, 314, 314, 314, 314, 314, 315, 316, 314, 317, 53, 53, 53, 53, - 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, - 328, 328, 328, 328, 328, 328, 329, 26, 328, 330, 328, 331, 164, 164, 164, 164, - 332, 332, 332, 332, 332, 332, 332, 332, 333, 26, 26, 334, 335, 335, 336, 26, - 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, 339, 340, 176, 176, - 176, 176, 176, 176, 176, 176, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, - 169, 169, 169, 169, 343, 26, 169, 169, 295, 344, 169, 169, 169, 169, 169, 343, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 280, 277, 277, - 277, 277, 277, 345, 26, 26, 26, 26, 346, 26, 347, 348, 25, 25, 349, 350, - 351, 25, 31, 31, 31, 31, 31, 31, 352, 26, 353, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 354, 31, 31, 355, 31, 31, 31, 31, 31, - 31, 356, 26, 26, 26, 26, 31, 31, 9, 9, 0, 265, 9, 357, 0, 0, - 0, 0, 358, 0, 257, 359, 360, 31, 31, 31, 31, 31, 31, 31, 31, 361, - 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, - 290, 290, 290, 364, 169, 169, 169, 295, 365, 365, 365, 366, 257, 257, 26, 367, - 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, - 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, - 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, - 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, - 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, - 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, - 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, - 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, - 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, - 407, 408, 409, 407, 410, 407, 410, 411, 412, 412, 412, 412, 412, 412, 413, 26, - 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 415, 26, - 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, - 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, - 428, 428, 428, 429, 430, 428, 26, 26, 26, 26, 26, 26, 431, 431, 432, 433, - 434, 434, 434, 435, 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, - 439, 439, 441, 439, 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, - 446, 449, 446, 449, 450, 450, 450, 450, 451, 451, 451, 451, 26, 26, 26, 26, - 452, 452, 452, 452, 453, 454, 453, 26, 455, 455, 455, 455, 455, 455, 456, 457, - 458, 458, 459, 458, 460, 460, 461, 460, 462, 462, 463, 464, 26, 465, 26, 26, - 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, 26, 26, 26, 26, 26, 26, - 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 468, 468, 468, 468, 469, 470, - 471, 471, 471, 471, 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, - 474, 476, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, - 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, 26, 26, 26, 481, - 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, 26, 26, 485, 485, - 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, 489, 489, 490, 26, - 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, - 495, 495, 495, 495, 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, - 501, 501, 501, 501, 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, - 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 137, 507, 26, - 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, 26, 26, 26, 26, - 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, - 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, - 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, - 541, 541, 541, 541, 541, 541, 541, 541, 541, 26, 541, 542, 26, 26, 26, 26, - 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, 26, 26, 26, 26, - 545, 545, 545, 545, 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, - 549, 549, 549, 549, 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, - 552, 552, 552, 553, 552, 554, 552, 552, 555, 26, 26, 26, 26, 26, 26, 26, - 556, 556, 556, 556, 556, 556, 556, 557, 26, 26, 26, 26, 558, 558, 558, 558, - 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, - 561, 26, 564, 567, 26, 26, 26, 26, 26, 26, 26, 26, 568, 569, 568, 568, - 568, 568, 568, 569, 570, 26, 26, 26, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 26, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, - 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 26, 26, 26, 26, - 577, 577, 577, 577, 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, - 582, 26, 579, 579, 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, - 588, 589, 590, 590, 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, - 595, 596, 597, 598, 595, 599, 26, 26, 26, 26, 26, 26, 600, 600, 600, 601, - 602, 602, 603, 602, 602, 602, 602, 604, 602, 602, 602, 605, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, - 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 610, 26, 26, 26, 26, - 609, 609, 609, 609, 609, 611, 612, 26, 613, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, - 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 616, 616, 616, 616, - 616, 616, 616, 616, 616, 616, 616, 618, 619, 619, 619, 619, 619, 619, 619, 619, - 620, 26, 26, 26, 26, 26, 26, 26, 621, 621, 621, 621, 621, 621, 621, 622, - 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 623, - 624, 624, 624, 625, 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, - 627, 629, 630, 630, 630, 631, 631, 26, 632, 632, 632, 632, 632, 632, 632, 632, - 633, 26, 632, 634, 634, 632, 632, 635, 632, 632, 26, 26, 26, 26, 26, 26, - 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, 638, 638, 638, 638, - 638, 638, 638, 639, 26, 26, 26, 26, 640, 640, 640, 640, 640, 640, 640, 640, - 640, 641, 640, 640, 640, 640, 640, 640, 640, 642, 640, 640, 26, 26, 26, 26, - 26, 26, 26, 26, 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 644, - 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, 645, 645, 645, 645, - 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 649, 650, 651, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 652, 26, 653, 26, - 26, 26, 654, 26, 655, 26, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 658, 658, 658, - 658, 658, 658, 658, 658, 659, 658, 660, 658, 661, 658, 662, 359, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 265, 0, 0, 0, 0, 0, 0, 359, 26, - 9, 9, 9, 9, 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, - 359, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 276, 26, - 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 664, 665, 0, 666, - 667, 668, 0, 0, 0, 669, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, - 246, 26, 26, 26, 26, 26, 26, 26, 0, 0, 359, 26, 0, 0, 359, 26, - 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 0, - 0, 0, 0, 254, 670, 671, 0, 672, 673, 0, 0, 0, 0, 0, 0, 0, - 269, 674, 254, 254, 0, 0, 0, 675, 676, 677, 678, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 680, 26, 681, 682, 679, 26, 26, - 2, 2, 2, 346, 683, 419, 26, 26, 684, 270, 270, 685, 686, 687, 18, 18, - 18, 18, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, 26, 26, 26, 26, - 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 26, 26, - 26, 26, 694, 694, 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, - 26, 26, 698, 698, 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, - 26, 26, 26, 26, 172, 702, 170, 172, 703, 703, 703, 703, 703, 703, 703, 703, - 704, 703, 705, 26, 26, 26, 26, 26, 706, 706, 706, 706, 706, 706, 706, 706, - 706, 707, 706, 708, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, - 0, 0, 0, 0, 0, 0, 376, 26, 362, 0, 0, 0, 0, 0, 0, 276, - 709, 31, 31, 31, 710, 711, 712, 713, 714, 715, 710, 716, 710, 712, 712, 717, - 31, 718, 31, 719, 720, 718, 31, 719, 26, 26, 26, 26, 26, 26, 721, 26, - 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 359, 26, 0, 257, 362, 0, - 362, 0, 362, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, - 26, 26, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, - 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, - 0, 0, 0, 0, 0, 0, 257, 725, 0, 0, 0, 265, 0, 359, 259, 26, - 0, 359, 0, 0, 0, 0, 0, 0, 0, 26, 0, 265, 0, 0, 0, 0, - 0, 26, 0, 0, 0, 276, 0, 359, 265, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 359, 26, 0, 276, 0, 376, 0, 726, 0, 0, 0, 0, 0, 0, - 257, 722, 0, 727, 0, 265, 0, 259, 0, 0, 358, 0, 0, 0, 0, 0, - 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 345, - 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 345, 26, 277, 277, - 277, 277, 277, 277, 728, 26, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, - 277, 729, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, - 730, 26, 26, 26, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 24, 24, 24, 24, 24, 24, 24, 24,1104, 48, 48,1112,1104, 48, 48,1112, + 24, 24, 24, 24, 24,1288, 24,1288, 48, 48,1512, 48, 48, 48,1512, 48, + 48, 48, 48, 48, 48, 48, 48,2048, 24, 24, 24, 24,2056,2064, 24, 24, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,2072,2080, + 2088,2096, 144, 144,2104, 144, 144, 144, 144, 144, 144, 144,2112, 296, 144, 144, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 2120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120,1520, 592, 592, 592,2128,1520, 592, 592, 592, 592, + 592,2136,2144, 352, 352, 352, 352, 352, 352, 0, 352, 352, 352,2152,2160, 0, + 1528,2168, 56,2176, 56, 56, 56, 56,2184,2192,2200, 56, 56, 56,2208, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,1528, 56, 56, 56, 56, + 496,2216, 496, 496, 496, 496, 496, 496, 496,2224, 56, 56, 56, 56, 56, 56, + 784, 784, 784, 784, 784, 784,2232, 0, 688, 688, 688, 688, 688, 688, 688,2240, + 792, 792, 792, 792, 792,2248, 792,2256,1296,1296,1296,2264, 496,2272, 56, 56, + 56, 56,2280, 56, 56, 56, 56, 56, 56, 56, 56, 56,2288, 56, 56, 56, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,2296, 240,2304, 240, 240, 240, + 2312,1536,2320,1120,1120,2328,2336,2344,1536,2352,2360,2368,2376,1120,1120,2384, + 2392,1544,2400,1304,1304,2408,2416,2424,1544,2432,2440,2448,2456,1304,2464, 0, + 2472,1552,2480,1312,1312,2488,2496,2504,1552,2512,2520, 0,2528,1312,2536,2544, + 2552,1560,2560,1128,1128,2568,2576,2584,1560,2592,2600,2608,2616,1128,1128, 0, + 2624,1320,1568,2632,2640,1320, 504,2648,1320,1568,2656, 0,2664, 504, 504,2672, + 800,1576,1584, 800, 800,1584, 800,2680,1576,2688,2696,2704,2712, 800,2720, 800, + 1136,1592,1600,1136,1136,1600,2728,2736,1592,2744,2752,2760,2768,1136,2776, 0, + 400,1608,1616, 400, 400, 400, 400, 400,1608,1616,2784, 400,2792, 400, 400, 400, + 2800, 808,1624,2808, 808, 808,2816,2824,1624,2832,2840, 808,2848, 808,2856, 0, + 2864, 512, 512, 512, 512, 512, 512,2872, 512, 512, 512,2880, 0, 0, 0, 0, + 2888,2896, 984, 984,2904, 984, 984,2912,2920,2928, 984,2936, 0, 0, 0, 0, + 224, 224, 224, 224, 224, 224, 224, 224, 224,1328, 224, 224, 224,2944,1328, 224, + 224, 224, 224,1328, 224, 224, 224,1632, 224,1632,2952,2960, 0, 0, 0, 0, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 256, 256, 256, 256,1640,1648, 256, 256, 256, 256, 256,2968, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 816, 280, 816, 160, 160, 160, 160, + 160, 816, 160, 160, 160, 160, 816, 280, 816, 160, 280, 160, 160, 160, 160, 160, + 160, 160, 816, 160, 160, 160, 160, 160, 160, 160, 160,2976, 160, 160, 160,2984, + 160, 160, 160,2992, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,1656,1656, + 1336,1336,1336,3000, 408, 408, 408, 408, 408, 408, 408, 408, 408,3008, 408,3016, + 1664,1664,3024,3032,1672,1672,3040, 0,1680,1680,3048, 0,3056,3064,3072, 0, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272,3080, 272,1688, 272,1688, + 3088, 248, 248,3096, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,3104, + 248, 248, 248, 248, 248,3112, 80, 80, 80, 80, 80, 80, 80, 80,3120, 0, + 824, 824, 824,3128, 824,1696, 824,1696,3136, 824,1344,1344,1344,3144,3152, 0, + 520, 520, 520, 520, 520,3160, 520, 520, 520,3168, 520,3176, 272, 272, 272, 272, + 1352,1352,1352,3184, 320, 320, 320, 320, 320, 320, 320,3192, 320, 320, 320,3200, + 320,1704, 320,1704, 320,3208, 104, 104, 104, 104, 104,1712, 104,3216, 0, 0, + 304, 304, 304, 304, 304, 304, 304, 304, 304,3224, 304, 304, 304, 304, 304, 304, + 528, 528, 528, 528, 528, 528, 528, 528, 832, 832, 832, 832, 832, 832,3232,3240, + 600, 600, 600, 600, 600, 600, 600,3248, 600,3256, 840, 840, 840, 840, 840, 840, + 120,3264, 256, 256, 256, 256, 256,3272, 528, 0,3280, 104,3288,3296,3304,3312, + 48, 48, 48, 48,3320,3328, 48, 48, 48, 48, 48,3336,3344,3352, 48,3360, + 48, 48, 48, 48, 48, 48, 48,3368, 104, 104, 104, 104, 104, 104, 104, 104, + 144, 144, 848, 848, 144, 144, 144, 144, 848, 848, 144,3376, 144, 144, 144, 848, + 144, 144, 144, 144, 144, 144,1720, 144,1720, 144,3384,3392, 144, 144,3400,1728, + 24,3408, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 992, 24,3416,3424, + 24, 608, 48,1736, 24, 24, 24, 24, 616, 0, 104, 104, 104, 104,3432, 0, + 24, 24, 24, 24,3440,3448,1288, 24, 24,3456, 24, 24, 48, 48, 48, 48, + 48,3464, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 616, 0, 0, 24,1360, 0, 0, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,1744, 24, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 48, 48, 48, 48, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,3472,3480, + 256, 256, 256, 256,1640,1648, 696, 696, 696, 696, 696, 696, 696,1752,3488,1752, + 160, 160, 280, 0, 280, 280, 280, 280, 280, 280, 280, 280, 120, 120, 120, 120, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 416, 0, 0, 0, 0, + 8, 8, 8,3496, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,3504, 0, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 856, 0, 0, 0, 24, 24, + 3512, 24, 24, 24,3520,3528, 24,3536,3544, 152, 152, 152, 152, 152, 152, 152, + 152, 152,3552,3560,1760, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184,3568, + 3576, 536, 536, 536, 536, 536,3584, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16,1144, 24, 24, 536, 536, 536, 536, 24, 24, 24, 24, 416,3592, 184, 184, + 16, 16, 16,1144, 24, 24, 24, 24, 24, 24, 24, 24, 16, 16, 16,3600, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 184, 184, 184, 184, 184,3608, + 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 24, 24, 24, 24, 24, + 8, 8, 8, 8, 8, 8, 8, 8, 24, 24, 24, 24, 24, 24, 24, 24, + 72,3616, 72, 72, 72, 72, 72, 72,3624, 0, 864, 864, 864, 864, 864, 864, + 176, 176, 176, 176, 176,3632, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 0, + 24, 24, 24, 24,3640, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48,3648, 48, 48, 48, 48, 48, 48, 48, 48, 48,1736, 0, 0,3656, 48, + 1000,1000,1000,1000,1000,3664, 24, 616, 704, 704, 704, 704, 704, 704, 704, 0, + 544, 544, 544, 544, 544, 544, 544, 544,3672,3680, 544,3688, 240, 240, 240, 240, + 1008,1008,1008,1008,1008,3696,1152,1152,1152,1152,3704,3712, 16, 16, 16,3720, + 424, 424, 424, 424, 424, 424, 424, 424, 424,3728, 424,3736, 200, 200, 200,3744, + 624, 624, 624, 624, 624, 624,3752, 0, 624,3760, 624,3768, 200, 200, 200, 200, + 632, 632, 632, 632, 632, 632, 632, 632,3776, 0, 0,3784, 640, 640,3792, 0, + 1368,1368,1368, 0, 280, 280, 48, 48, 48, 48, 48,3800,3808,3816, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 640, 640, 640, 640, 640,3824, 640,3832, + 16, 16, 16, 16,1768, 0, 16, 16,1144,3840, 16, 16, 16, 16, 16,1768, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 856, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,1776, 0, 0, 0, 0, + 1784, 0,3848,3856, 352, 352,3864,3872,3880, 352, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56,3888, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 0, 0, 0, 0, 56, 56, + 104, 104, 24, 616, 104,3896, 24, 24, 24, 24,1792, 24, 608, 328,3904, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,3912, + 712, 24, 24, 24,1104, 48, 48,1112,1104, 48, 48,1112,3920, 184,1760, 184, + 184, 184, 184,3928, 16, 16, 16,1144,1376,1376,1376,3936, 608, 608, 0,3944, + 216,3952, 216, 216,3960, 216, 216,3968, 216,1800, 216,1800, 0, 0, 0, 0, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216,3976, + 1808, 24, 24, 24, 24, 24,3984, 24, 144, 144, 144, 144, 144, 144, 144, 144, + 144,1728, 24, 872,3992, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24,4000, + 1384,1384,1384,4008, 880, 880, 880, 880, 880, 880,4016, 0,4024, 24, 24, 328, + 1160,1160,1160,1160,4032,4040,1392,1392,1392,4048,1016,1016,1016,1016,1016,4056, + 1400,1400,1400,4064,1024,1024,1024,1024,4072,1024,4080, 0, 0, 0, 0, 0, + 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, 888, 888, 888, 888, 888, 888, + 1168,1168,1168,4088,1168,4096, 648, 648, 648, 648,1816, 648, 648, 648, 648,1816, + 1032,1032,1032,1032,1032, 0, 896, 896, 896, 896, 896, 896,4104,4112,1176,1824, + 1176,1824,4120,1176,1832,1176,1832,4128, 904, 904, 904, 904, 904, 904,4136, 0, + 168, 168, 168, 168, 168, 168,4144, 0, 168, 168,4152, 0, 168, 0, 0, 0, + 4160, 48, 48, 48, 48, 48,4168,1840, 0, 0, 0, 0, 0, 0, 0, 0, + 4176,4184,1184,1184,1184,1184,4192,4200,1408,1408,4208,1408,1192,1192,1192,1192, + 1200,1200,1200,4216,4224,1200, 0, 0, 0, 0, 0, 0,1848,1848,4232,4240, + 1416,1416,1416,4248,1424,1424,1424,4256,1432,1432,1432,4264, 0, 0, 0, 0, + 1208,1208,1208,1208, 440, 440, 440,4272, 440, 440,4280, 440, 440, 440, 440, 440, + 4288,4296,4304,4312,1216,1216,4320,4328,1216,1856,1216,1856,1224,1224,1224,1224, + 1232,1232,1232,1232, 0, 0, 0, 0,1240,1240,1240,1240,1864,4336,1864, 0, + 912, 912, 912, 912, 912, 912,4344,4352,1440,1440,4360,1440,1448,1448,4368,1448, + 1872,1872,4376,4384, 0,4392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 552, 552, 552, 552, 552, 552, 552, 552, 552,4400, 0, 0, 0, 0, 0, 0, + 360, 360, 360, 360, 360, 360,1880, 0, 360, 360, 360, 360, 360, 360,1880,4408, + 920, 920, 920, 920, 920, 0, 920,4416, 928, 928, 928, 928,1888,4424, 928, 928, + 1888,4432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56,4440, + 1040,1040,1040,1040,1040,4448,4456, 0,1896, 0, 56,4464, 0, 0, 0,1896, + 1048,1048,1048,1048,1048, 0,1056,1056,1056,1056,1056,4472, 0, 0,1456,1456, + 1456,4480, 0, 0, 0, 0,1464,1464,1464,4488, 0, 0,1904,1904,4496, 0, + 368, 368, 368, 368, 368, 368, 368, 368, 368,1912,4504, 368, 368, 368,1912,4512, + 656, 656, 656, 656, 656, 656, 656, 656,4520,4528,1248,1248,1248,4536,1248,4544, + 664, 664, 664, 664, 664, 664,4552, 664, 664, 0,1256,1256,1256,1256,4560, 0, + 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336,4568, 808,4576, 0, + 720, 720,4584, 720, 720, 720, 720, 720,4592, 0, 0, 0, 0, 0, 0, 0, + 4600,4608,1920,4616,1920,4624, 672, 672, 672, 672, 672, 672, 672,4632, 672,4640, + 4648,1928,4656,1936,1936,4664,4672,4680,1928,4688,4696,4704,4712,1944,1944, 0, + 936,4720, 936, 936, 936, 936,1952, 936,4728,4736,1952,4744,4752, 0, 0, 0, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384,4760,4768, 0, 0, 0, + 448, 448, 448, 448, 448, 448, 448, 448, 448, 0, 448,4776, 0, 0, 0, 0, + 456, 456, 456, 456, 456, 456,1960, 456, 456, 456, 456,1960, 0, 0, 0, 0, + 560, 560, 560, 560, 560, 560, 560, 560,4784, 0, 560,4792, 248,4800, 0, 0, + 680, 680, 680, 680, 680, 680, 680,1968, 680,1968, 200, 200,4808, 0, 0, 0, + 944, 944, 944,4816, 944,4824, 944, 944,4832, 0, 0, 0, 0, 0, 0, 0, + 728, 728, 728, 728, 728, 728, 728,4840, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 464, 464, 464, 464, 464, 464, 464, 464, 464, 464,4848,4856, + 1976,4864,4872,1264,1264,1264,4880,4888,1976, 0,1264,4896, 0, 0, 0, 0, + 0, 0, 0, 0, 952,1984, 952, 952, 952, 952, 952,1984,4904, 0, 0, 0, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 0, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472,4912, 0, 80, 80, 736, 736, 736, 736, 736, 736, 736,4920, + 240,4928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1064,1064,1064,1064,1992, 0,1064,1992, + 576,4936, 576, 576, 576, 576,4944, 576,4952, 0, 576, 576, 576,4960, 960, 960, + 960, 960,4968, 960, 960,4976,4984, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2000,4992, 968, 968, 968, 968,2000,5000, 968, 0, 968,5008,5016,5024,1272,1272, + 1272,5032,5040,5048,1272,5056, 976, 976, 976, 976, 976,5064, 976,5072, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1472,1472,1472,5080, + 584, 584,5088, 584, 584, 584, 584,5096, 584, 584, 584,5104, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,5112, 0, 504, 504, 504, 504, 504, 504,5120,5128, + 64, 64, 64,5136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,5144,5152, 0, + 64, 64, 64, 64, 64, 64, 64, 64,5160, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, 376,5168, 0, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,5176, 0, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,5184, + 112, 112, 112, 112, 112, 112, 112, 112,5192, 0, 0, 0, 0, 0, 0, 0, + 744, 744, 744, 744, 744, 744, 744,5200, 0, 0, 0, 0, 0, 0, 0, 0, + 88, 88, 88, 88, 88, 88, 88,5208,1280,1280,1280,5216,1280,5224, 480, 480, + 480, 480, 480, 480, 480, 480, 480,5232, 480,5240,1480,1480,1480,2008,2008, 0, + 344, 344, 344, 344, 344, 344, 344, 344,5248, 0, 344,2016,2016, 344, 344,5256, + 344, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 752, 752, 752, 752, 752, 752, 752,5264, + 0, 0, 0, 0, 0, 0, 0, 0, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392,5272,1072,1072,1072,5280,1072,1072,5288, 0, 0, 0, 0, 0, + 264, 264, 264, 264, 264, 264, 264, 264, 264,5296, 264, 264, 264, 264, 264, 264, + 264,5304, 264, 264, 0, 0, 0, 0, 0, 0, 0, 0,5312, 0,5320, 0, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,5328, 0, 0, 0, 0,5336, + 32, 32, 32,5344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,5352, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,5360,5368, + 5376, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152,5384, 0,5392, 0, 0, 0,5400, 0,5408, 0, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,5416, + 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288,5424, 288,5432, + 288,5440, 288,5448, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 872, + 24, 24, 24, 24, 24, 24, 328,2024, 24, 24, 760, 0, 24, 24, 760, 0, + 104, 104, 104, 104, 104,1712, 104, 104,5456, 0, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 328, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 416, 0, + 24, 24, 24, 24, 608, 712, 24, 24, 24, 24, 24, 24,5464,5472, 24,5480, + 5488,5496, 24, 24, 24,5504, 24, 24, 24, 24, 24, 24, 24,1360, 0, 0, + 144, 144, 144, 144, 144, 144, 144, 144, 848, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 328, 0, 24, 24, 328, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 608, 0, 24, 24, 24, 760, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 992, 24, 24, 24, 24, 24, + 24, 24, 24, 992,5512,5520, 24,5528,5536, 24, 24, 24, 24, 24, 24, 24, + 5544,5552, 992, 992, 24, 24, 24,5560,5568,2024,5576, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 416, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24,1744, 24, 24, 24, 24, 24, 24, + 96,5584, 0,5592,5600, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48,1784,5608,1840, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5616, 312, 312,5624,5632,5640, 120, 120, 120, 120, 120, 120, 120,5648, 0, 0, + 0,5656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 768, 768, 768, 768, 768,5664, 768,5672, 768,5680, 0, 0, 0, 0, 0, 0, + 0, 0,1488,1488,1488,5688, 0, 0, 776, 776, 776, 776, 776, 776, 776,5696, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1080,1080,1080,1080,1080,5704, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1088,1088,1088,1088,1088,5712, + 0, 0, 0, 0, 0, 0, 0, 0,1096,1096,1096,5720,1096,1096,5728,5736, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280,5744, 160, 280, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208,5752, 208,5760, 0, 0, 0, 0, 0, + 488, 488, 488, 488, 488, 488, 488, 488, 488,5768, 488,5776, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 712, 24, + 24, 24, 24, 24, 24, 24, 872, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 712, 24, 24, 24, 24, 24, 24, 416, 0, 0, 0, 0, 0, 0, 0, 0, + 5784, 56, 56, 56,1496,5792,1504,5800,5808,5816,1496,5824,1496,1504,1504,5832, + 56,2032, 56,2040,5840,2032, 56,2040, 0, 0, 0, 0, 0, 0,5848, 0, + 24, 24, 24, 24, 24, 328, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 328, 0, 24, 608, 712, 24, 712, 24, 712, 24, 24, 24, 416, 0, + 24, 24, 24, 24, 24, 416, 0, 0, 0, 0, 0, 0,5856, 24, 24, 24, + 5864, 0, 24, 24, 24, 24, 24, 328, 24, 760, 616, 0, 416, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5872, 24, 872, 24, 872, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 616, 24, 328, 760, 0, + 24, 328, 24, 24, 24, 24, 24, 24, 24, 0, 24, 616, 24, 24, 24, 24, + 24, 0, 24, 24, 24, 416, 24, 328, 616, 0, 24, 760, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 24, 416, 24, 872, + 24,5880, 24, 24, 24, 24, 24, 24, 608,5888, 24,5896, 24,1808, 24, 760, + 24, 24,1792, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,1360, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, + 8, 8, 8, 856, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 856, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,5904, 0, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 856, 0, 0, 0, 0, + 8, 8, 8, 856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 8, 8, 8, 8, 8,5912, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,1776, + 5920, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -2840,489 +2684,492 @@ _hb_ucd_u16[10400] = 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[196] = +static const int16_t _hb_ucd_i16[196]= { - 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, - 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, - 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, + 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 0, 0, -1, 1, -1, 1, + 0, 0, 1, -1, -1, 1, -1, 0, 0, 0, 0, 1, 0, 1, -1, 0, + 0, 0, 0, 2, 0, -2, 0, 0, 0, 1, -1, 1, 2, 0, -2, 0, + -1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 3, 3, 3, -3, -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, - 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, - 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, - 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, + 1824, 0, 0, 0, 0, 0, 2104, 0, 2108, 2106, 0, 2106, 1316, 0, 0, 0, + -1, -138, 0, 0, 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, + -8, -7, -7, 0, 1, -1, 0, 2,-1316, 1, -1, 0, -1, 3, 1, -1, -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, -1, 0, 1, -1, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + /* packtab: [2^8,2^5,2^3,2^1] */ + return u<1114110u ? (uint8_t)(_hb_ucd_u8[7912u+((_hb_ucd_u8[2176u+_hb_ucd_u16[((_hb_ucd_u8[((((((u)>>1))>>3))>>5)])<<5)+((((((u)>>1))>>3))&31)]+((((u)>>1))&7)])<<1)+((u)&1)]) : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + /* packtab: [2^8,2^4,2^3,2^2] */ + return u<125259u ? (uint8_t)(_hb_ucd_u8[10370u+((_hb_ucd_u8[9270u+((_hb_ucd_u8[8539u+((_hb_ucd_u8[8294u+((((((u)>>2))>>3))>>4)])<<4)+((((((u)>>2))>>3))&15)])<<3)+((((u)>>2))&7)])<<2)+((u)&3)]) : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9252+(((_hb_ucd_u8[9132+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + /* packtab: [2^4,2^3,2^3,2^2] */ + return u<65380u ? (int16_t)(_hb_ucd_i16[_hb_ucd_u8[11118u+((_hb_ucd_u8[11002u+((_hb_ucd_b4(_hb_ucd_u8+10874u,((((((u)>>2))>>3))>>3)))<<3)+((((((u)>>2))>>3))&7)])<<3)+((((u)>>2))&7)]+((u)&3)]) : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[10486+(((_hb_ucd_u16[3744+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9588+(u>>3>>3>>4)])<<4)+((u>>3>>3)&15u))])<<3)+((u>>3)&7u))])<<3)+((u)&7u))]:2; + /* packtab: [2^8,2^4,2^4,2^3] */ + return u<918000u ? (uint8_t)(_hb_ucd_u8[12639u+_hb_ucd_u16[3296u+((_hb_ucd_u8[11903u+((_hb_ucd_u8[11454u+((((((u)>>3))>>4))>>4)])<<4)+((((((u)>>3))>>4))&15)])<<4)+((((u)>>3))&15)]+((u)&7)]) : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6976+(((_hb_ucd_u8[16716+(((_hb_ucd_u8[16334+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + /* packtab: [2^8,2^5,2^4] */ + return u<195102u ? (uint16_t)(_hb_ucd_u16[7360u+((_hb_ucd_u8[18949u+((_hb_ucd_u8[18567u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)]) : 0; } #elif !defined(HB_NO_UCD_UNASSIGNED) -static const uint8_t -_hb_ucd_u8[17524] = +#include + +static const uint8_t _hb_ucd_u8[14763]= { - 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 18, 19, 20, 21, 22, 23, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 25, 26, 5, 27, 28, - 5, 29, 30, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 31, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 33, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 17, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 33, 41, 42, 43, 44, 45, - 46, 47, 48, 39, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 50, 17, 17, 17, 51, 17, 52, 53, 54, 55, 56, 57, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 58, 59, 59, 59, 59, 59, 59, 59, 59, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 17, 61, 62, 17, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 17, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 17, 17, 17, 97, 98, 99,100,100,100,100,100,100,100,100,100,101, - 17, 17, 17, 17,102, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,103, 17, 17,104,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,105,100,100,100,100,100,100, 17, 17,106,107,100,108,109,110, - 17, 17, 17, 17, 17, 17, 17,111, 17, 17, 17, 17,112,113,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,114, - 17,115,116,100,100,100,100,100,100,100,100,100,117,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,118, 39,119,120, - 121,122,123,124,125,126,127,128, 39, 39,129,100,100,100,100,130, - 131,132,133,100,134,135,100,136,137,138,100,100,139,140,141,100, - 142,143,144,145, 39, 39,146,147,148, 39,149,150,100,100,100,100, - 17, 17, 17, 17, 17, 17,151, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,152,153, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,154, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,155, 17, 17,156,100, - 100,100,100,100,100,100,100,100, 17, 17,157,100,100,100,100,100, - 17, 17, 17,158, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17,159,100,100,100,100,100,100,100,100,100,100,100,100, - 160,161,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,162, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,163, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, - 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, - 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, - 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, - 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, - 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, - 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10, - 44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11, - 32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52, 2, 2, 2, - 16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62, - 36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65, 8, 9, 66, 2, 67, - 43, 43, 43, 43, 43, 60, 68, 2, 69, 36, 36, 36, 36, 70, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 77, 78, 2, 2, 2, 2, 2, 2, 2, 79, - 70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, - 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, - 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, - 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 57, 43, 43, 43, 43, - 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, - 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, - 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, - 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, - 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, - 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, - 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, - 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, - 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, - 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, - 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, - 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, - 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, - 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, - 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, - 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, - 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, - 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, - 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, - 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, - 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, - 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, - 62, 94, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, - 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, - 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, - 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, - 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, - 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, - 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, - 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, - 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, - 36, 36, 61, 81, 43, 43, 43, 80, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, - 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, - 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, - 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, - 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, - 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, - 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, - 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, - 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, - 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, - 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, - 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, - 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, - 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, - 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, - 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, - 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, - 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, - 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, - 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 2, - 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 2, - 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, - 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, - 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, - 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34,110, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, - 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, - 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, - 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, - 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, - 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, - 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, - 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, - 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, - 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, - 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, - 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, - 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, - 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, - 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, - 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, - 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, - 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, - 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, - 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, - 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, - 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, - 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,129,147, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,129,148,148,148,148,148,148, - 148,148,148,148,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,144, 26, 8, 8,144, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,140, 67, 67,138, 34,149, 43, 32, 44, 44, 93, 2, 99, 2, - 16, 16, 16,150, 44, 44,150, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,121,121, 2,125,126,121, 2, - 2, 2, 2, 6, 2,108,121, 2,121, 4, 4, 4, 4, 2, 2, 88, - 2, 2, 2, 2, 2,120, 2, 2,108,151, 2, 2, 2, 2, 2, 2, - 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, - 67, 67, 67, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, - 67, 67, 67, 92, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,164, 2, - 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, - 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, - 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 44, 32,150,150, 32, 32, 32, 47, 44, - 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, - 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, - 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, - 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, - 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, - 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, - 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, - 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, - 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, - 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, - 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, - 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, - 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, - 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, - 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, - 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, - 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, - 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, - 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, - 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, - 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, - 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, - 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, - 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, - 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, - 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, - 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, - 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, - 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, - 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, - 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, - 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, - 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, - 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, - 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, - 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, - 7, 7, 7, 7, 7, 36, 36, 69, 11, 11, 11, 44, 57, 43, 43,159, - 16, 16, 16, 44, 44, 44, 44, 8, 27, 27, 27, 27, 27, 27, 27,100, - 36, 36, 36, 36, 36, 57,184, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 44, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, - 27, 27, 27, 95, 44, 44, 44, 44,180, 27, 30, 2, 2, 44, 44, 44, - 36, 43, 43, 2, 2, 44, 44, 44, 36, 36,183, 27, 27, 27, 44, 44, - 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, - 43, 43, 43, 60, 2, 2, 2, 44, 27, 27, 27, 7, 7, 7, 7, 7, - 71, 70, 71, 44, 44, 44, 44, 57, 86, 87, 43, 85, 87, 60,185, 2, - 2, 80, 44, 44, 44, 44, 79, 44, 43, 71, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 70, 43, 43, 87, 43, 43, 43, 80, 7, 7, 7, 7, 7, - 2, 2, 94, 98, 44, 44, 44, 44, 36, 70, 2, 61, 44, 44, 44, 44, - 36, 94, 86, 43, 43, 43, 43, 85, 98, 36, 63, 2, 59, 43, 60, 87, - 7, 7, 7, 7, 7, 63, 63, 2,179, 27, 27, 27, 27, 27, 27, 27, - 27, 27,100, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 86, 87, - 43, 86, 85, 43, 2, 2, 2, 71, 70, 44, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, - 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, - 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 62, 44, 61, - 36, 36, 36, 62, 86, 87, 43, 43, 80, 90, 89, 89, 86, 90, 86, 85, - 71, 71, 2, 93, 64, 44, 44, 44, 57, 80, 44, 44, 44, 44, 44, 44, - 36, 36, 94, 86, 43, 43, 43, 43, 86, 43, 85, 71, 36, 63, 2, 2, - 7, 7, 7, 7, 7, 2, 93, 71, 86, 87, 43, 43, 85, 85, 86, 87, - 85, 43, 36, 72, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 94, - 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 44, 86, 87, 43, 43, 43, 85, 87, 87, - 60, 2, 61, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 2, 64, 44, - 36, 36, 36, 36, 36, 70, 87, 86, 43, 43, 43, 87, 63, 44, 44, 44, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 61, 57, 87, 86, 43, 43, 87, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, - 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, - 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 2, 2, 2, 2, 2, 44, 44, 44, - 63, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, - 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, - 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, - 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, - 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, - 43, 94, 36, 36, 36, 36, 36, 36, 36, 36, 86, 43, 43, 80, 44, 86, - 85, 60, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 80, 44, 44, - 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, - 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65, 71, 36, 36, 70, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 43, - 43, 43, 43, 43, 43, 86, 87, 43, 43, 43, 60, 44, 44, 44, 44, 44, - 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, - 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 62, 36, 40, 69, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83,164, 2, 27, 27, 27, 30, 2, 64, 44, 44, - 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, - 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, - 86, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 62, - 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, - 44, 61, 44, 44, 44, 44, 44, 44, 36, 61, 62, 44, 44, 44, 44, 44, - 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, - 65, 65, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43, 44, - 43, 43, 43, 80, 44, 44, 44, 44, 67, 67, 67, 92, 55, 67, 67, 67, - 67, 67,186, 87, 43, 67,186, 86, 86,187, 65, 65, 65, 84, 43, 43, - 43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,110, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,150,150, 16, - 16, 16,150, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 43, 43, 43, 76, 67, 50, 43, 43, - 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, - 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, - 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, - 44, 44,150, 16, 16,110, 44, 44, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 57, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 36, 80, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 44, 44, 96, 36, 36, 36, 36, 36, 83, 43, 43, - 188, 7, 7, 7, 7,189, 44, 93, 36, 36, 36, 61, 36, 36, 62, 61, - 36, 36, 61,179, 27, 27, 27, 27, 16, 16, 43, 43, 43, 74, 44, 44, - 27, 27, 27, 27, 27, 27,163, 27,190, 27,100, 44, 44, 44, 44, 44, - 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, - 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, - 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, - 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, - 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, - 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 44, 44, 55, 67, 67, 67, 92, 44, 44, 44, 67, - 67, 67, 67, 67, 67, 67, 92, 55, 67, 92, 67, 67, 67, 67, 67, 67, - 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, - 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, - 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, - 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, - 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, - 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, - 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, - 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, - 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, - 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, - 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, - 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, - 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, - 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, - 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, + 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 8, 2, 2, 9, 1, 10, + 11, 12, 13, 14, 15, 0, 16, 2, 17, 0, 18, 19, 20, 21, 22, 23, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 25, 26, 2, 27, 28, + 2, 29, 2, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 2, 23, 24, 25, 2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 5, 38, 39, 40, 41, 42, 3, 43, 5, 44, 45, 46, 47, 48, + 49, 50, 51, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 2, 2, + 53, 2, 2, 2, 54, 2, 55, 56, 57, 58, 59, 60, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 61, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 62, 63, 2, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 2, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 2, 2, 2, 98, 99,100, 0, 0, 0, 0, 0, 0, 0, 0, 0,101, + 2, 2, 2, 2,102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2,103, 2, 2,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,105, 0, 0, 0, 0, 0, 0, 2, 2,106,107, 0,108,109,110, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,111,112, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113, + 2,114,115, 0, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 3,118,119, + 120,121,122,123,124,125,126,127, 3, 3,128, 0, 0, 0, 0,129, + 130,131,132, 0,133,134,135,136,137,138, 0, 0,139,140,141, 0, + 142,143,144,145, 3, 3,146,147,148, 3,149,150, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2,151, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2,152, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,153, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,154, 2, 2,155, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,156, 0, 0, 0, 0, 0, + 2, 2, 2,157, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2,158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 159,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,161, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, + 11, 11, 11, 11, 11, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, + 13, 13, 13, 13, 13, 13, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 14, + 1, 1, 1, 1, 14, 1, 1, 1, 18, 18, 18, 18, 18, 18, 18, 18, + 1, 5, 0, 11, 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 14, 0, + 1, 1, 1, 1, 14, 0, 0, 0, 6, 6, 6, 6, 7, 7, 7, 7, + 1, 1, 1, 1, 1, 14, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 14, 0, 0, 0, 0, + 1, 1, 1, 14, 1, 1, 1, 14, 3, 3, 3, 3, 3, 3, 0, 0, + 28, 28, 28, 28, 28, 28, 28, 28, 11, 11, 11, 11, 11, 1, 1, 1, + 14, 17, 1, 1, 1, 1, 1, 1, 14, 0, 0, 0, 0, 0, 0, 0, + 14, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 0, + 3, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 29, 0, + 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 6, 6, 6, + 0, 0, 0, 11, 11, 11, 11, 11, 17, 1, 1, 1, 1, 1, 1, 1, + 11, 11, 11, 11, 11, 10, 10, 10, 1, 1, 1, 0, 0, 0, 0, 0, + 5, 46, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 41, 41, 41, 41, + 3, 3, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 0, 0, 12, + 1, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 49, 10, 10, 10, 10, 10, 10, 10, 7, 6, 6, 6, 6, 6, 6, 6, + 44, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, + 3, 3, 3, 3, 0, 0, 0, 0, 11, 11, 11, 11, 11, 12, 9, 77, + 88, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,102,103,104, + 89, 6, 6, 6, 6, 6, 6, 6, 22, 22, 22, 22, 22, 22, 22, 22, + 26, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 5, 5, 5, 5, 5, + 5, 20, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, + 11, 11, 11, 11, 11, 12, 12, 12, 1, 1, 1, 1, 14, 1, 1, 0, + 14, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, + 10, 10, 10, 10, 10, 10, 51, 0,115, 1, 1, 1, 1, 1, 1, 1, + 5, 5, 5, 5, 5, 5, 5, 0, 1, 1, 1, 1, 13, 13, 13, 12, + 6, 6, 6, 0, 7, 7, 7, 0, 30, 30, 30, 30, 30, 30, 30, 30, + 3, 3, 3, 3, 3, 29, 0, 0, 3, 3, 3, 3, 3, 3, 3, 29, + 10, 10, 10, 10, 10, 3, 3, 3, 75, 10, 10, 10, 10, 10, 10, 10, + 3, 3, 3, 29, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 7, 7, 7, 7, 7, 32, 7, 7, 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 51, 0, 0, 0, 1, 1, 1, 1, 1, 1, 86, 10, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 15, 19, + 1, 1, 1, 1, 1, 1, 1, 34, 1, 1, 1, 1, 1, 1, 1, 5, + 15, 15, 15, 15, 15, 15, 15, 15, 1, 14, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 23, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, + 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, + 3, 3, 3, 3, 29, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 87, 12,100, 12, 27,101, 76, 12, 6, 6, 6, 6, 6,105,106,135, + 87, 30, 30, 66,107,136,137,108, 50, 10, 89, 12,138,139, 10, 78, + 7, 7, 7, 59, 7, 7, 7, 8, 6, 6, 6, 60, 6, 6, 6, 6, + 8, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 6, 8, 8, 8, + 8, 8, 8, 8, 7, 21, 21, 6, 21, 8, 8, 7, 21, 7, 6, 7, + 7, 21, 8, 7, 8, 6, 7, 21, 8, 8, 8, 7, 21, 6, 8, 7, + 21, 7, 21, 21, 8, 67, 8, 6, 1, 1,109, 21,110,109, 21, 21, + 21, 21, 21, 21, 21, 21, 6, 8, 21,110, 8, 7, 8, 8, 8, 8, + 8, 8, 6, 6, 6, 7, 21, 8, 21, 21, 7, 8, 8, 8, 8, 8, + 6, 6, 1, 6, 6, 6, 6, 6, 13, 22, 22, 13, 13, 13, 13, 13, + 13, 22, 22, 22, 22, 22, 22, 22, 13, 13, 68, 22, 22, 22, 68, 68, + 8, 8, 68, 8, 0, 69, 6, 88, 0, 0, 22,140, 7, 32, 32, 7, + 21, 7, 7, 7, 7, 7, 7, 7, 7, 39, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 21, 6, 7, 8, 6, 8, 8, 8, 8, + 6, 6, 8, 90, 21, 8, 21, 7, 8, 43, 5, 5, 79, 8, 8, 8, + 7, 21, 21, 21, 21, 21, 21, 6, 39, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 32, 54, 12, 12, 12, 6, 6, 6, 6,111,141, 44, 70, + 5, 5, 5, 5, 5, 5, 5,142, 71, 36, 5, 71, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 14, 0, 17, 1, 40, 33, 0, 0, 0, 0, 0, + 18, 18, 18, 9, 77, 80, 12, 3, 5, 5, 5, 5, 5, 36,143, 12, + 52, 1, 1, 1, 1, 24, 5, 5, 11, 11, 11, 11, 11, 12, 12, 1, + 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 53, 5, 5, 5,144, 43, + 5, 5, 81, 72, 55, 5, 5, 1, 11, 11, 11, 11, 11, 1, 56, 82, + 12, 12, 12, 12, 12, 12, 12, 73, 24, 1, 1, 1, 1, 1, 1, 1, + 5, 5, 5, 5, 5, 23, 17, 1, 25, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 24, 5, 5, 5, 5, 13, 66, 12, 61, 26, 30, + 1, 1, 1, 5, 5, 72, 5, 5, 5, 5, 72, 5, 72, 5, 5, 0, + 12, 12, 12, 12, 12, 12, 12, 33, 1, 1, 1, 1, 24, 5, 0, 33, + 1, 1, 1, 1,145, 1, 1, 1, 18, 0, 0, 26, 5, 5, 5, 5, + 1, 1, 1, 1, 45, 5, 5, 5, 5, 91, 5, 5, 5, 5, 5, 5, + 1, 1, 1, 1, 1, 20, 25, 15, 19, 5, 5, 5, 20, 15, 19, 15, + 24, 5, 5, 5, 1, 1, 1, 1, 1, 5, 12, 11, 11, 11, 11, 11, + 62, 1, 1, 1, 1, 1, 1, 1, 24, 15, 17, 1, 1, 1, 14, 17, + 14, 14, 0, 1, 1, 0, 25, 15, 19, 5, 23, 35, 37, 35, 19, 14, + 0, 0, 0, 35, 0, 0, 1, 17, 1, 30, 10, 10, 10, 70, 40, 23, + 26, 20, 17, 1, 1, 14, 0, 17, 14, 1, 17, 14, 1, 0, 23, 15, + 19, 23, 0, 26, 23, 26, 5, 0, 26, 0, 0, 0, 17, 1, 14, 14, + 5, 1, 24, 33, 0, 0, 0, 0, 26, 20, 17, 1, 1, 1, 1, 17, + 14, 1, 17, 1, 1, 0, 25, 15, 19, 5, 5, 26, 20, 35, 19, 0, + 80, 0, 0, 0, 17, 5, 5, 5, 26, 15, 17, 1, 1, 1, 14, 17, + 14, 1, 17, 1, 1, 0, 25, 19, 19, 5, 23, 35, 37, 35, 19, 0, + 0, 0, 26, 20, 0, 0, 1, 17, 82, 10, 10, 10, 0, 0, 0, 0, + 0, 25, 17, 1, 1, 14, 0, 1, 14, 1, 1, 0, 17, 14, 14, 1, + 0, 17, 14, 0, 1, 14, 0, 1, 1, 1, 1, 1, 1, 0, 0, 15, + 20, 37, 0, 15, 37, 15, 19, 0, 14, 0, 0, 35, 0, 0, 0, 0, + 10, 63, 3, 3, 70, 29, 0, 0, 20, 15, 25, 1, 1, 1, 14, 1, + 1, 1, 1, 1, 1, 0, 25, 5, 20, 15, 37, 5, 23, 5, 5, 0, + 0, 0, 26, 23, 1, 14, 1, 0, 0, 0, 0, 38, 10, 10, 10, 63, + 24, 15, 53, 1, 1, 1, 14, 1, 1, 1, 17, 1, 1, 0, 25, 19, + 15, 15, 37, 20, 37, 15, 5, 0, 0, 0, 35, 37, 0, 0, 1, 14, + 17, 34, 0, 0, 0, 0, 0, 0, 5, 15, 1, 1, 1, 1, 14, 1, + 1, 1, 1, 1, 1, 24, 25, 15, 19, 5, 23, 15, 37, 15, 19, 56, + 0, 0, 1, 34, 10, 10, 10,112, 10, 10, 10, 10, 63, 1, 1, 1, + 26, 15, 17, 1, 1, 1, 1, 1, 1, 1, 1, 14, 0, 1, 1, 1, + 1, 17, 1, 1, 1, 1, 17, 0, 1, 1, 1, 14, 0, 23, 0, 35, + 15, 5, 23, 23, 15, 15, 15, 15, 0, 15, 33, 0, 0, 0, 0, 0, + 24, 1, 5, 5, 5, 23, 0,113, 1, 1, 1, 72, 5, 5, 5, 36, + 11, 11, 11, 11, 11, 12, 0, 0, 17, 14, 14, 1, 1, 14, 1, 1, + 1, 1, 17, 17, 1, 1, 1, 1, 24, 1, 5, 5, 5, 5, 25, 0, + 1, 1, 14, 61, 5, 5, 5, 23, 11, 11, 11, 11, 11, 0, 1, 1, + 56, 3, 12, 12, 12, 12, 12, 12, 12, 57, 57, 3, 5, 3, 3, 3, + 10, 10, 43, 43, 43, 27, 27, 15, 1, 1, 1, 1, 17, 1, 1, 1, + 26, 5, 5, 5, 5, 5, 5, 20, 5, 5, 36, 5, 1, 1, 24, 5, + 5, 5, 5, 5, 26, 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 3, + 3, 3, 3, 55, 3, 3, 29, 3, 12, 12, 57, 3, 66, 33, 0, 0, + 1, 1, 1, 1, 1, 34, 19, 5, 20, 5, 5, 5, 19, 20, 19, 25, + 1, 1, 1, 15, 5, 1, 1, 5, 25, 15, 46, 34, 15, 15, 15, 1, + 24, 5, 25, 1, 1, 1, 1, 1, 1, 20, 19, 20, 15, 15, 19, 34, + 11, 11, 11, 11, 11, 15, 19, 3, 7, 7, 7, 39, 0, 0, 39, 0, + 6, 6, 6, 6, 6,111, 69, 6, 1, 1, 1, 14, 14, 1, 1, 0, + 14, 1, 1, 0, 1, 1, 1, 14, 1, 1, 1, 1, 1, 14, 26, 5, + 12, 12, 12, 12,114, 10, 10, 10, 7, 7, 7, 0, 6, 6, 6, 0, + 1, 1, 1, 1, 1, 1, 56, 53,146, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1,147,116, 0, 1, 1, 1, 1, 1, 40, 12, 16, + 148, 1, 1, 1, 14, 0, 0, 0, 1, 5, 20, 0, 0, 0, 0, 17, + 1, 5, 83, 33, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 14, 1, 14, 5, 0, 0, 0, 0, 0, 0, + 1, 1, 5, 19, 5, 5, 5, 15, 15, 15, 15, 20, 19, 5, 5, 5, + 5, 5, 12, 62, 12, 80, 24, 0, 10, 10, 10, 10, 10, 0, 0, 0, + 12, 12, 12, 92, 12, 71, 5, 91, 1, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 24, 14, 0, 0, + 5, 20, 15, 19, 20, 15, 0, 0, 15, 20, 15, 15, 19, 5, 0, 0, + 29, 0, 12, 11, 11, 11, 11, 11, 1, 1, 14, 0, 0, 0, 0, 0, + 11, 11, 11, 11, 11, 51, 0, 3, 1, 1, 1, 24, 20, 19, 0, 12, + 1, 1, 34, 20, 5, 5, 5, 23, 20, 20, 19, 5, 5, 5, 20, 15, + 15, 19, 5, 5, 5, 5, 23, 26, 12, 12, 12, 62, 12, 12, 12, 0, + 5, 5, 5, 5, 5, 5, 5, 93, 5, 5, 5, 5, 5, 5, 0, 0, + 5, 5, 46, 1, 1, 1, 1, 1, 1, 1, 20, 5, 5, 20, 20, 15, + 15, 20, 46, 1, 1, 1, 14, 12, 57, 3, 3, 3, 3, 43, 5, 5, + 5, 5, 3, 3, 3, 3, 66, 12, 34, 5, 5, 15, 5, 19, 5, 1, + 1, 1, 1, 20, 5, 15, 19, 19, 5, 15, 0, 0, 0, 0, 12, 12, + 1, 1, 15, 15, 15, 15, 5, 5, 5, 5, 15, 5, 0, 38, 12, 12, + 11, 11, 11, 11, 11, 0, 17, 1, 6, 6, 6, 6, 21, 47, 0, 0, + 7, 7, 7, 7, 7, 32, 39, 7, 12, 12, 12, 12, 0, 0, 0, 0, + 5, 36, 5, 5, 5, 5, 5, 5, 20, 5, 5, 5, 25, 1, 24, 1, + 1, 1, 25, 34, 5, 14, 0, 0, 6, 6, 6, 6, 6, 6, 13, 13, + 13, 13, 13, 13, 13, 69, 6, 6, 6, 6, 6, 6, 69, 6, 6, 6, + 6, 6, 6, 6, 6,117, 13, 13, 8, 8, 8, 6, 6, 6, 6, 8, + 6, 6, 6, 6, 39, 39, 39, 39, 6, 6, 6, 6, 6, 6, 6, 0, + 6, 6, 47, 6, 7, 7, 94,118, 22, 6, 47, 6, 7, 7, 94, 22, + 6, 6, 0, 6, 7, 7,149, 22, 6, 6, 6, 6, 7, 7,150, 22, + 0, 6, 47, 6, 7, 7, 94,151, 74, 74, 74, 74, 74,152, 18, 18, + 84, 84, 84, 12, 58,119, 58,119, 12, 12, 12, 12,153, 18, 18,154, + 12, 12, 12, 12,120,121, 12,122,123, 12, 64, 65, 12, 12, 12, 12, + 12, 77,123, 12, 12, 12, 12,155, 18, 18,156, 18, 18, 18, 18, 18, + 157, 0, 10, 10, 10, 9, 64,158, 10, 10, 10, 10, 10, 9, 64,116, + 13, 13, 13, 13, 13, 13, 61, 0, 30, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5,159, 79, 93, 79, 93, 5, 5, 5, 5, 5, + 23, 0, 0, 0, 0, 0, 0, 0, 3, 85, 3, 95, 3, 21, 7, 6, + 7, 8, 95, 3, 90, 7, 7, 3, 3, 3, 85, 85, 85, 7, 7,160, + 7, 7, 67, 1,124, 3, 6, 7, 9, 9, 90, 6, 6, 50, 3,125, + 16,161,162, 16,126, 3, 0, 0, 9, 9, 48, 3, 3, 9, 3, 3, + 48, 50, 3, 48, 3, 3, 3, 48, 3, 3, 3, 3, 3, 3, 3, 9, + 3, 48, 48, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, + 3, 3, 3, 3, 27, 27, 3, 3, 9, 3, 3, 3,163,164, 3, 3, + 3, 3, 3, 3, 3, 3, 48, 3, 3, 3, 3, 3, 3, 50, 9, 9, + 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 9, + 9, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 10, 10, 3, 3, + 3, 3, 3, 3, 3, 10, 10, 10, 3, 3, 3, 50, 3, 3, 3, 3, + 50, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 9, 9, 9, + 3, 3, 3, 3, 3, 3, 3, 50, 3, 3, 3, 3, 27, 27, 27, 27, + 27, 27, 27, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, + 9, 9, 64,127, 9, 9, 9, 9, 9, 9, 9, 27, 27, 27, 27, 27, + 9, 64, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,127, 9, 9, 9, + 9, 9, 9, 9, 27, 27, 9, 9, 9, 9, 9, 9, 9, 9, 27, 9, + 9, 9, 48, 50, 9, 9, 48, 3, 3, 3, 0, 3, 3, 3, 3, 3, + 8, 7, 8, 21, 21, 21, 21, 7, 8, 8, 21, 6, 6, 6, 13, 7, + 8, 8,125, 3, 3, 95, 21,165, 5, 8, 0, 0, 38, 12,114, 12, + 6, 6, 6, 42, 0, 0, 42, 0, 1, 1, 1, 1, 0, 0, 0, 54, + 33, 0, 0, 0, 0, 0, 0, 26, 12, 58, 58, 12,120,121, 58, 12, + 12, 12, 12, 76, 12, 92, 58, 12, 58, 27, 27, 27, 27, 12, 12, 62, + 12, 12, 12, 12, 12, 84, 12, 12, 92,166, 12, 12, 12, 12, 12, 12, + 3, 12, 96, 31, 31, 31,167, 0, 3, 3, 3, 3, 3, 44, 3, 3, + 87, 12,168,128, 27, 27, 27, 27, 27, 3, 27, 27, 27, 27,129,169, + 170, 16, 16, 16, 16, 5, 5, 15,130, 13, 13, 3, 16,171, 40, 3, + 1, 1, 1, 14, 26,172,131, 52, 1, 1, 1, 1, 1, 40, 13, 52, + 0, 0, 17, 1, 1, 1, 1, 1, 3, 10, 10, 3, 3, 3, 3, 3, + 3, 3, 3, 0, 0, 0, 0, 44, 3, 3, 3, 3, 10, 10, 10, 10, + 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,132, 12, + 11, 11, 11, 11, 11, 1, 0, 0, 8, 8, 8, 8, 8, 8, 8, 24, + 79,173, 5, 5, 5, 5, 5, 62, 8, 8, 8, 8, 8, 8, 13, 5, + 1, 1, 1, 16, 16, 16, 16, 16, 5, 12, 12, 12, 0, 0, 0, 0, + 22, 22, 22,131, 13, 13, 13, 13, 22, 8, 8, 8, 8, 8, 8, 8, + 6, 8, 8, 8, 8, 8, 8, 8, 69, 6, 6, 6, 21, 21, 21, 8, + 8, 8, 8, 8, 68,174, 21, 67, 8, 8, 6, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 7, 7, 8, 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 7, 7, 21, 21, 8, 8, 8, 8, 8, 8, 8, 8, 32, 0, + 54, 13,175, 67, 13, 67, 1, 1, 1, 25, 1, 25, 1, 24, 1, 1, + 1, 34, 19, 20, 3, 3, 23, 0, 10, 10, 10, 3, 97, 0, 0, 0, + 1, 1, 12, 12, 0, 0, 0, 0, 15, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 5, 0, 0, 0, 0, 12, + 5, 1, 1, 1, 12, 53, 53, 24, 1, 1, 1, 5, 5, 5, 5, 12, + 1, 1, 1, 24, 5, 5, 5, 5, 5, 15, 0, 0, 0, 0, 0, 38, + 1, 24, 15, 5, 5, 15, 5, 15, 83, 12, 12, 12, 12, 12, 12, 54, + 1, 1, 24, 52, 1, 1, 1, 1, 11, 11, 11, 11, 11, 1, 1, 14, + 1, 1, 1, 1, 24, 5, 5, 20, 19, 20, 19, 23, 0, 0, 0, 0, + 1, 24, 1, 1, 1, 1, 20, 0, 11, 11, 11, 11, 11, 0, 12, 12, + 52, 1, 1, 56, 3, 34, 20, 1, 25, 5, 25, 24, 25, 1, 1, 5, + 24, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 45, 12, + 1, 1, 1, 1, 1, 34, 5, 15, 12, 45,176, 23, 0, 0, 0, 0, + 17, 1, 1, 14, 17, 1, 1, 14, 17, 1, 1, 14, 0, 0, 0, 0, + 6, 6, 6, 6, 6,118, 13, 13, 6, 6, 6, 6,117, 22, 0, 0, + 1, 34, 19, 15, 20, 83, 19, 0, 1, 1, 1, 14, 0, 17, 1, 1, + 6, 6, 6, 47, 0, 0, 0, 0, 0, 42, 6, 6, 0, 0, 17, 25, + 1, 1, 1, 1,177, 1, 1, 1, 1, 1, 1, 14, 1, 1, 14, 14, + 1, 17, 14, 1, 1, 1, 1, 1, 1, 22, 22, 22, 22, 22, 22, 22, + 22,107, 3, 3, 3, 3, 3, 3, 3, 82, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 31, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 97, 3, + 12, 12, 12, 96, 65, 0, 0, 0, 76,178,179, 31, 31, 31, 31, 31, + 31, 31, 65, 96, 65, 12,122,180, 12, 33, 12, 12,129, 31, 31, 65, + 12,181, 9, 98, 80, 12, 0, 0, 1, 1, 14, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 14, 73, 38, 12,100, 12, 27,101, 76, 12, + 6, 6, 6, 6, 6,105,106, 64, 65, 27, 12, 1, 1, 1, 1, 1, + 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 14, 0, + 30,182, 70,183, 50, 9, 48, 29, 0, 0, 0, 0, 73, 18, 3, 0, + 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 14, 1, 17, + 12, 33, 0, 49, 10, 10, 10, 10, 10, 10, 0, 44, 3, 3, 3, 3, + 16, 16,126, 10, 63, 3, 3, 3, 3, 3, 3, 3, 3, 10, 3, 29, + 3, 3, 3, 3, 3, 3, 43, 0,133, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 0, 0, 10, 10, 0, 0, 0, 0, 17, 1, + 128, 1, 1, 1, 1, 99, 0, 0, 1, 1, 1, 5, 5, 23, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 0, 0, 1, 1, 1, 1, + 184, 16, 16, 0, 0, 0, 0, 0, 7, 7, 7, 7, 6, 6, 6, 6, + 7, 7, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 38, 7, 32, 7, 42, 6, 6, 6, 6, + 6, 42, 6, 6, 6, 6, 6, 6, 6, 42, 6, 6, 6, 42, 47, 0, + 13, 13, 13, 54, 13, 13, 13, 13, 61, 13, 13, 13, 13, 61, 0, 0, + 1, 1, 1, 0, 14, 1, 1, 1, 1, 1, 1, 17, 14, 0, 14, 17, + 1, 1, 1, 38, 10, 10, 10, 10, 1, 1, 1, 56, 75, 10, 10, 10, + 0, 0, 0, 49, 10, 10, 10, 10, 1, 14, 1, 0, 0, 49, 10, 10, + 1, 1, 1, 10, 10, 10, 0, 38, 1, 1, 1, 1, 1, 0, 0, 38, + 1, 1, 1, 1, 0, 0, 10, 1, 24, 5, 26, 23, 0, 0, 5, 5, + 1, 1, 17, 1, 17, 1, 1, 1, 1, 1, 1, 0, 5, 23, 0, 26, + 12, 12, 12, 12, 33, 0, 0, 0, 1, 1, 1, 1, 1, 1, 86, 78, + 1, 1, 1, 1, 82, 1, 1, 1, 1, 1, 24, 23, 0, 49, 10, 10, + 12, 12, 12, 33, 0, 0, 0, 0, 1, 1, 1, 0, 38, 12, 12, 12, + 1, 1, 1, 0, 10, 10, 10, 10, 1, 14, 0, 0, 10, 10, 10, 10, + 1, 0, 0, 0, 38, 12, 33, 0, 0, 0, 0, 0, 49, 10, 10, 10, + 7, 32, 0, 0, 0, 0, 0, 0, 6, 47, 0, 0, 0, 10, 10, 10, + 1, 1, 5, 5, 0, 0, 0, 0, 11, 11, 11, 11, 11, 1, 1, 52, + 7, 7, 7, 0, 26, 5, 5,130, 6, 6, 6, 0, 0, 0, 0, 9, + 10, 10, 10, 10, 10, 10, 10, 51, 1, 1, 1, 1, 1, 26,185, 0, + 0, 1, 45, 1, 0, 0, 0, 0, 57, 3, 3, 3, 29, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 5, 5, 10, 10, 10,112, 0, 0, 0, 0, + 133, 10, 78, 12, 12, 0, 0, 0, 1, 5, 5, 12, 12, 0, 0, 0, + 1, 1, 86, 10, 10, 10, 0, 0, 19, 46, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 36, 12, 12, 12, 0, + 10, 10, 10, 11, 11, 11, 11, 11, 25, 24, 25, 0, 0, 0, 0, 26, + 15, 19, 5, 20, 19, 36,186, 12, 12, 23, 0, 0, 0, 0, 73, 0, + 5, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 24, 5, 5, 19, 5, + 5, 5, 23, 11, 11, 11, 11, 11, 12, 12, 34, 46, 0, 0, 0, 0, + 1, 24, 12, 14, 0, 0, 0, 0, 1, 34, 15, 5, 5, 5, 5, 20, + 46, 1, 40, 12, 71, 5, 36, 19, 11, 11, 11, 11, 11, 40, 40, 12, + 10, 10, 51, 0, 0, 0, 0, 0, 5, 15, 20, 5, 12, 12, 12, 25, + 24, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 14, 14, 1, 1, 17, + 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 40, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 24, 15, 19, 5, 5, 5, 23, 0, 0, + 5, 15, 17, 1, 1, 1, 14, 17, 14, 1, 17, 1, 1, 26, 25, 15, + 20, 15, 37, 35, 37, 35, 15, 0, 14, 0, 0, 35, 0, 0, 17, 1, + 1, 15, 0, 5, 5, 5, 23, 0, 5, 5, 23, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 17, 0, 14, 1, 1, 1, 17, 15, 19, 5, 5, + 23, 37, 35, 35, 15, 37, 15, 20, 25, 25, 12, 38, 33, 0, 0, 0, + 26, 23, 0, 0, 0, 0, 0, 0, 1, 1, 34, 15, 5, 5, 5, 5, + 15, 5, 20, 25, 1, 40, 12, 12, 11, 11, 11, 11, 11, 12, 38, 25, + 15, 19, 5, 5, 20, 20, 15, 19, 20, 5, 1, 53, 0, 0, 0, 0, + 15, 5, 5, 0, 15, 15, 5, 19, 36, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 1, 1, 5, 0, 15, 19, 5, 5, 5, 20, 19, 19, + 36, 12, 14, 0, 0, 0, 0, 0, 12, 12, 12, 12, 12, 12, 33, 0, + 1, 1, 1, 1, 1, 24, 19, 15, 5, 5, 5, 19, 40, 0, 0, 0, + 11, 11, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 14, 26, 19, + 15, 5, 5, 19, 5, 5, 0, 0, 11, 11, 11, 11, 11, 10, 12, 57, + 5, 5, 5, 5, 19, 36, 0, 0, 10, 51, 0, 0, 0, 0, 0, 17, + 1, 1, 1, 14, 17, 0, 1, 1, 1, 1, 17, 14, 1, 1, 1, 1, + 15, 15, 15, 35, 37, 26, 20, 25, 46, 19, 12, 33, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 1, 1, 1, 34, 15, 5, 5, 0, 5, 15, 15, + 25, 53, 37, 0, 0, 0, 0, 0, 24, 5, 5, 5, 5, 25, 1, 1, + 1, 24, 5, 5, 20, 24, 5, 36, 12, 12, 12, 71, 0, 0, 0, 0, + 24, 5, 5, 20, 19, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, + 5, 5, 5, 20, 5, 12, 53, 12, 12, 33, 0, 0, 0, 0, 0, 0, + 12, 12, 12, 12, 12, 0, 0, 0, 20, 5, 20, 20, 0, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 23, 5, 5, 5, 19, + 40, 12, 12, 0, 0, 0, 0, 0, 12, 1, 1, 1, 1, 1, 1, 1, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 35, 5, 5, 5, + 20, 5, 19, 23, 0, 0, 0, 0, 1, 1, 1, 14, 1, 17, 1, 1, + 24, 5, 5, 23, 0, 23, 5, 26, 5, 5, 5, 24, 0, 0, 0, 0, + 1, 1, 1, 17, 14, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 37, + 5, 35, 19, 19, 14, 0, 0, 0, 1, 1, 1, 1, 45, 1, 0, 0, + 1, 24, 20, 83, 33, 0, 0, 0, 5, 34, 1, 1, 1, 1, 1, 1, + 1, 1, 15, 5, 5, 23, 0, 15, 20, 36, 12, 12, 12, 12, 12, 12, + 11, 11, 11, 11, 11, 23, 0, 0, 10, 10, 63, 3, 3, 3, 70, 30, + 97, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 38, + 16, 16, 16, 16, 16, 16, 16, 99, 12, 12, 33, 0, 0, 0, 0, 0, + 40, 33, 0, 0, 0, 0, 0, 0, 25, 1, 1, 24, 5, 5, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 15, 19, 5, + 5, 5, 36, 0, 0, 0, 0, 0, 5, 5, 5, 36, 12, 12, 3, 3, + 13, 13, 57, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 49, 10, 10, + 10, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 17, 1, + 13, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45,132, 12, + 10, 10, 10, 78, 12, 33, 0, 0, 7, 7, 7, 7, 32, 42, 6, 6, + 6, 6, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 14, 0, 26, + 34, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 26, + 5, 81, 13, 13, 13, 13, 13, 13, 13, 62, 23, 0, 0, 0, 0, 0, + 15, 13, 16, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, + 13, 13, 54, 13, 13, 13, 54, 61, 0, 14, 0, 0, 0, 0, 0, 0, + 1, 14, 17, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 43, 36, 18, 18, 0, 0, 0, 0, 0, 0, + 11, 11, 11, 11, 11, 3, 29, 0, 3, 3, 0, 0, 0, 3, 3, 3, + 98, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 29, 44, 3, 3, 3, + 3, 3,134, 19, 5, 3,134, 15, 15,187, 18, 18, 18, 91, 5, 5, + 5, 55, 43, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 5, 5, 3, + 3, 5, 55, 0, 0, 0, 0, 0, 6, 6, 47, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 32, 7, 0, 32, 39, 32, 39, 7, 32, 7, + 7, 7, 7, 6, 6, 42, 42, 6, 6, 6, 42, 6, 6, 6, 6, 6, + 6, 6, 7, 39, 7, 32, 39, 7, 7, 7, 32, 7, 7, 7, 32, 6, + 6, 6, 6, 6, 7, 39, 7, 32, 7, 7, 32, 32, 0, 7, 7, 7, + 32, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 7, 7, 7, 7, + 59, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 60, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 59, 6, 6, + 6, 6, 60, 6, 6, 6, 7, 7, 7, 7, 59, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 60, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 59, 6, 6, 6, 6, 60, 6, 6, 6, + 7, 7, 7, 7, 59, 6, 6, 6, 6, 60, 6, 6, 6, 8, 0, 11, + 5, 5, 5, 55, 3, 43, 5, 5, 5, 5, 5, 5, 5, 5, 55, 3, + 3, 3, 43, 3, 3, 3, 3, 3, 3, 3, 55, 66, 12, 12, 0, 0, + 0, 0, 0, 0, 0, 26, 5, 5, 6, 6, 6, 6, 6,124, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 47, 0, 0, 42, 6, 6, 47, 0, 0, + 5, 5, 5, 23, 5, 5, 5, 5, 5, 5, 5, 5, 23, 26, 5, 5, + 5, 26, 23, 5, 5, 23, 0, 0, 13, 13, 13, 13, 13, 13, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 5, 5, 5, 81, 13, 13, 13, 0, + 11, 11, 11, 11, 11, 0, 0, 56, 1, 1, 1, 1, 1, 1, 1, 23, + 1, 1, 1, 1, 1, 1, 5, 5, 11, 11, 11, 11, 11, 0, 0,113, + 1, 1, 1, 1, 1, 45, 5, 5,188, 11, 11, 11, 11,189, 0, 38, + 1, 24, 1, 25, 1, 1, 1, 5, 1, 1, 24, 0, 0, 0, 0, 45, + 1, 1, 1, 14, 1, 1, 17, 14, 1, 1, 14, 49, 10, 10, 10, 10, + 6, 6, 5, 5, 5, 81, 0, 0, 10, 10, 10, 10, 10, 10, 75, 10, + 190, 10, 51, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 75, + 10, 10, 10, 10, 10, 10, 10, 0, 1, 1, 17, 1, 1, 1, 1, 1, + 17, 14, 14, 17, 17, 1, 1, 1, 1, 14, 1, 1, 17, 17, 0, 0, + 0, 14, 0, 17, 17, 17, 17, 1, 17, 14, 14, 17, 17, 17, 17, 17, + 17, 14, 14, 17, 1, 14, 1, 1, 1, 14, 1, 1, 17, 1, 14, 14, + 1, 1, 1, 1, 1, 17, 1, 1, 17, 1, 17, 1, 1, 17, 1, 1, + 9, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 63, 3, + 0, 0, 0, 3, 3, 3, 3, 3, 3, 29, 0, 0, 0, 0, 0, 0, + 3, 3, 3, 3, 3,108, 22, 22, 3, 3, 3, 3, 29, 0, 3, 3, + 9, 9, 9, 9, 98, 0, 0, 0, 3, 3, 3, 3, 3, 29, 0, 3, + 3, 3, 3, 29, 29, 0, 44, 3, 3, 3, 3, 3, 3, 3, 29, 44, + 3, 3, 3, 3, 3, 29, 0, 44, 3, 29, 3, 3, 3, 3, 3, 3, + 11, 11, 11, 11, 11, 29, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 7, 7, 3, 3, 26, 26, + 4, 4, 12, 12, 5, 5, 9, 9, 9, 5, 25, 25, 15, 15, 13, 13, + 21, 21, 6, 6, 7, 2, 10, 10, 14, 14, 2, 7, 1, 1, 10, 12, + 12, 10, 5, 9, 24, 24, 12, 2, 7, 12, 12, 7, 2, 12, 22, 18, + 0, 0, 26, 2, 23, 23, 18, 22, 9, 2, 21, 2, 7, 10, 2, 10, + 12, 21, 10, 2, 2, 21, 2, 9, 7, 21, 8, 8, 2, 5, 26, 12, + 2, 26, 7, 6, 10, 7, 5, 2, 25, 26, 2, 15, 26, 25, 15, 2, + 6, 7, 21, 7, 2, 6, 12, 26, 7, 26, 21, 26, 20, 19, 9, 25, + 5, 25, 6, 2, 21, 6, 15, 26, 25, 22, 18, 21, 26, 21, 5, 7, + 6, 24, 6, 5, 26, 23, 21, 12, 6, 12, 2, 1, 29, 29, 26, 15, + 21, 17, 25, 21, 15, 21, 11, 11, 21, 23, 12, 6, 26, 7, 10, 21, + 17, 17, 9, 26, 7, 15, 29, 21, 21, 9, 24, 5, 25, 9, 1, 12, + 17, 21, 11, 12, 8, 24, 26, 9, 21, 22, 23, 26, 25, 2, 14, 2, + 23, 21, 21, 25, 9, 22, 21, 18, 24, 16, 5, 22, 25, 18, 24, 26, + 26, 24, 9, 8, 8, 5, 5, 21, 15, 7, 2, 23, 21, 15, 17, 7, + 18, 2, 5, 6, 5, 24, 22, 20, 21, 20, 19, 21, 21, 16, 16, 21, + 7, 5, 5, 26, 14, 15, 18, 25, 7, 14, 17, 22, 17, 6, 24, 6, + 6, 21, 12, 15, 26, 10, 25, 0, 7, 20, 25, 1, 24, 15, 7, 19, + 9, 21, 17, 2, 17, 12, 1, 21, 12, 1, 24, 7, 29, 7, 7, 22, + 14, 7, 2, 24, 9, 24, 24, 2, 29, 1, 27, 28, 1, 29, 21, 29, + 1, 2, 15, 6, 18, 6, 12, 11, 26, 5, 14, 9, 5, 14, 26, 22, + 18, 26, 5, 12, 22, 21, 18, 17, 26, 6, 18, 18, 26, 14, 14, 6, + 12, 24, 11, 21, 24, 9, 6, 9, 6, 10, 7, 25, 17, 16, 16, 22, + 16, 16, 25, 17, 25, 24, 23, 2, 21, 14, 12, 17, 21, 1, 10, 1, 7, 13, 13, 2, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3338,2543 +3185,2448 @@ _hb_ucd_u8[17524] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, - 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, - 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, - 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, - 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, - 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, - 0, 0, 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, - 0, 78, 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, - 86, 87, 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, - 93, 0, 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, - 0, 0, 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, - 0,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104, - 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, - 0, 0, 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, - 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, - 0,118, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, - 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, - 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, - 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, - 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, - 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, - 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, - 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, - 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, - 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, - 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, - 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, - 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, - 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, - 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, - 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, - 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, - 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0, - 103, 0, 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107, - 108, 0, 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, - 33, 0,112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0, - 117, 0, 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, - 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, - 0,122, 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, - 0, 0, 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, - 0,128, 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0, - 134,135,136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, - 0, 0,138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, - 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, - 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, - 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, - 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, - 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, - 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, - 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, - 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, - 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, - 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, - 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, - 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, - 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, - 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, - 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, - 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, - 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, - 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, - 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, - 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, - 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, - 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, - 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, - 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, - 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, - 0, 38, 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0, - 115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, - 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, - 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, - 0, 0, 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, - 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, - 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, - 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, - 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, - 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, - 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, - 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, - 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, - 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, - 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, - 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, - 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, - 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, - 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, - 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, - 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, - 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, - 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, - 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, - 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, - 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, - 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, - 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, - 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, - 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, - 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, - 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, - 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, - 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, - 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, - 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, - 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 9, 16, 17, 18, 9, 19, 20, 21, 22, 23, 24, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 25, 26, 27, 5, 28, 29, 5, 30, 31, 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, 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, 32, 0, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 1, 29, 30, 31, - 32, 32, 33, 32, 32, 32, 34, 32, 32, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, - 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 44, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, - 95, 96, 97, 98, 56, 56, 56, 56, 56, 56, 56, 56, 56, 99,100,100, - 100,100,101,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,102,103,103,104, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,105, - 56, 56, 56, 56, 56, 56,106,106,107,108, 56,109,110,111,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112,113,112,112,112,114,115,116, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,117,118,119, - 120, 56, 56, 56, 56, 56, 56, 56, 56, 56,121, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,122, 32,123,124,125,126, - 127,128,129,130,131,132,133,133,134, 56, 56, 56, 56,135,136,137, - 138, 56,139,140, 56,141,142,143, 56, 56,144,145,146, 56,147,148, - 149, 32, 32, 32,150,151,152, 32,153,154, 56, 56, 56, 56, 44, 44, - 44, 44, 44, 44,155, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44,156,157, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,158, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44,159, 44, 44,160, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 44, 44,161, 56, 56, 56, 56, 56, 44, 44, - 44,162, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44,163, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,164,165, - 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, + 0, 0, 0, 0, 0, 0, 41, 42, 43, 44, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 9, 0, 0, + 0, 10, 11, 12, 13, 0, 14, 15, 16, 0, 17, 18, 19, 20, 21, 1, + 22, 1, 23, 1, 2, 1, 2, 1, 2, 0, 2, 1, 24, 1, 2, 25, + 2, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 36, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 38, + 0, 0, 39, 0, 0, 40, 0, 41, 0, 0, 0, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 0, 0, 51, 0, 0, 0, 52, 0, 0, 0, 53, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 3, 0, 55, 56, 0, 57, 0, 0, + 0, 0, 0, 0, 58, 59, 60, 0, 0, 0, 0, 61, 0, 0, 62, 63, + 64, 4, 65, 0, 0, 66, 67, 0, 0, 0, 68, 0, 0, 0, 0, 69, + 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 71, 0, 0, 0, 72, 0, 73, 0, 0, 74, 0, 0, 75, 0, + 0, 0, 0, 0, 0, 0, 0, 76, 77, 0, 0, 0, 0, 78, 79, 0, + 80, 81, 0, 0, 82, 5, 0, 83, 4, 0, 84, 85, 0, 0, 86, 87, + 88, 0, 89, 0, 90, 0, 91, 0, 0, 3, 92, 3, 0, 93, 0, 94, + 0, 0, 0, 5, 0, 0, 0, 95, 96, 0, 97, 98, 99,100, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105, 6, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, + 0, 0, 0,111, 0,112, 0, 6, 0, 0, 0, 0, 0,113,114, 0, + 0, 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0, + 0, 0, 0, 0, 0, 0,118, 0,119, 0, 0, 0, 0, 0, 0, 0, + 2, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, + 14, 0, 0, 0, 16, 3, 17, 18, 19, 20, 21, 22, 0, 23, 0, 0, + 0, 0, 24, 25, 26, 27, 0, 0, 0, 0, 28, 0, 0, 29, 30, 0, + 31, 0, 32, 33, 0, 0, 34, 0, 35, 36, 0, 0, 0, 0, 0, 37, + 38, 0, 39, 40, 0, 0, 41, 0, 0, 0, 42, 0, 0, 43, 44, 45, + 46, 1, 47, 0, 0, 1, 0, 0, 7, 1, 48, 0, 0, 0, 0, 0, + 49, 50, 0, 0, 0, 0, 0, 0, 51, 52, 0, 0, 0, 0, 0, 0, + 53, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 57, 58, 0, 0, + 0, 59, 0, 0, 0, 0, 0, 0, 60, 12, 0, 0, 0, 0, 61, 0, + 0, 0, 62, 0, 5, 0, 63, 0, 0, 0, 0, 64, 0, 0, 0, 0, + 65, 0, 66, 0, 0, 0, 0, 6, 67, 0, 0, 0, 68, 69, 70, 71, + 0, 0, 0, 0, 72, 5, 0, 73, 74, 0, 0, 75, 0, 0, 0, 76, + 77, 0, 0, 0, 78, 0, 79, 80, 81, 82, 83, 3, 84, 0, 85, 86, + 87, 0, 0, 8, 9, 0, 0, 3, 3, 0, 0, 88, 0, 0, 89, 0, + 0, 0, 0, 8, 90, 0, 91, 0, 0, 0, 0, 0, 9, 10, 0, 92, + 0, 5, 0, 3, 9, 0, 0, 93, 0, 0, 94, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 95, 96, 0, 0, 10, 0, 0, 1, 0, 0, 97, 0, + 0, 0, 0, 98, 0, 0, 0, 0, 12, 0, 0, 13, 0, 0, 0, 0, + 99,100, 0, 0,101, 0, 0,102, 0, 0, 0,103, 0, 0, 0,104, + 0, 0, 0,105, 0, 0, 0, 0,106,107, 13, 0, 0,108, 0, 0, + 0, 10, 0, 0,109,110, 0, 0,111,112, 0, 0, 0, 0, 0, 0, + 113, 0, 0,114, 0, 0, 0, 0,115, 1, 0,116,117,118, 6, 0, + 0,119, 7, 0, 0,120, 0, 0, 0,121, 0, 0, 0, 0, 0, 0, + 122, 0, 0,123, 0, 0, 0, 0,124, 11, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 5, 15, 0, 0, 0, 0,125, 0, 0,126, 0, 0, + 0, 0, 15, 0, 0,127, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, + 128, 0, 0, 0,129, 0,130, 0, 0, 0, 0,131,132,133, 0,134, + 0,135, 0, 0, 0,136,137,138, 0, 8, 0, 0, 0, 0, 0, 7, + 0, 0, 0,139, 0, 0, 0,140, 0, 0, 0,141, 0, 0, 0,142, + 143, 0,144, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, + 0, 9, 1, 1, 1, 1, 0, 0, 0, 2, 0, 3, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 19, 0, 0, 0, 6, 11, 0, 0, 0, 0, 14, + 0, 0, 15, 0, 0, 0, 0, 0, 0, 17, 29, 0, 0, 0, 0, 0, + 31, 0, 0, 2, 0, 0, 1, 12, 0, 0, 1, 49, 50, 5, 51, 52, + 53, 5, 5, 22, 32, 23, 1, 54, 24, 55, 16, 33, 56, 57, 58, 1, + 1, 1, 6, 1, 0, 0, 59, 7, 60, 1, 34, 5, 7, 61, 62, 63, + 64, 65, 66, 67, 0, 0, 1, 1, 68, 0, 0, 0, 69, 70, 71, 35, + 1, 25, 72, 0, 0, 0, 0, 8, 1, 26, 16, 26, 73, 27, 74, 0, + 0, 0, 36, 25, 75, 37, 7, 37, 76, 0, 0, 0, 6, 1, 7, 0, + 0, 17, 0, 8, 38, 1, 1, 13, 13, 11, 0, 0, 39, 0, 0, 6, + 18, 1, 0, 0, 8, 16, 5, 1, 1, 1, 77, 7, 36, 18, 78, 7, + 35, 1, 79, 10, 0, 0, 0, 80, 0, 0, 0, 0, 2, 3, 0, 0, + 14, 0, 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 83, 0, 0, 0, + 84, 0, 0, 0, 40, 0, 0, 85, 86, 0, 87, 88, 89, 90, 91, 92, + 0, 0, 0, 93, 0, 0, 0, 15, 28, 0, 0, 0, 0, 13, 0, 41, + 0, 0, 14, 0, 0, 20, 0, 0, 94, 0, 0, 0, 95, 0, 0, 6, + 29, 0, 0, 13, 1, 96, 1, 18, 33, 97, 25, 23, 7, 1, 1, 1, + 1, 27, 1, 7, 98, 0, 0, 9, 0, 0, 0, 0, 6, 23, 1, 0, + 0, 0, 0, 0, 30, 0, 0, 21, 0, 0, 30, 0, 0, 0, 0, 15, + 0, 0, 12, 32, 24, 5, 99, 22, 42, 17, 0, 10, 11, 0, 7, 1, + 7,100,101, 1, 1, 1, 1,102,103,104,105, 1,106, 10, 20,107, + 108, 5, 10, 0, 0, 0, 0, 0,109,110, 0, 0,111, 0, 0, 1, + 1, 11, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 43, 40, 2, 0, + 0, 0, 44,112, 10, 8, 20, 0, 0, 0, 0, 0, 0,113, 1, 16, + 5, 24, 0, 8, 12, 0, 0, 0, 0,114, 0, 0,115, 2, 0,116, + 0, 0, 0, 1, 0, 0, 0, 0, 13, 11, 0, 0, 6, 10, 0, 0, + 45, 39, 0, 45, 16, 18, 46, 27, 0, 0, 3, 0, 0, 2, 12, 0, + 0, 0, 2, 3, 0, 0, 3, 0, 21, 0, 0, 31, 0, 0, 0, 0, + 117, 0, 0, 0, 15, 9, 0, 8, 1, 10, 1, 10, 0, 0, 0, 0, + 0, 30, 14, 21, 0, 0, 47, 0, 0, 0, 9, 0, 0, 0, 0, 47, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 28, 0, 0, 4, 0, 21, 41, + 0, 0, 28, 0, 0, 0, 22, 42, 0, 0,118, 0, 0, 0, 0, 0, + 0,119, 0,120,121,122,123, 0, 43, 5, 48, 13, 34, 0, 0, 0, + 8, 11, 8, 10, 0, 0, 1, 12, 1, 1, 1, 1, 26, 1, 38, 44, + 12, 0, 0, 0, 0, 1, 0, 0, 0,124, 0, 0, 0, 46, 6, 19, + 0, 8, 0, 20, 0, 0, 5, 48, 0, 0, 0, 1,125, 0, 0, 0, + 0,230,230,230,230, 0, 0, 0, 9, 9, 0, 0, 0, 0, 9, 0, + 0,220,220,220,220, 0, 0, 0,230,230,230,220,230, 0, 0,230, + 230, 7, 0, 0, 0,230, 0, 0, 0,230,230, 0, 0,230,230,230, + 0, 0,230,230,230, 0, 0, 9, 0, 0, 0, 0, 7,230,230,230, + 220, 0,220, 0, 0,230,220,220,220, 0, 0,230, 0, 0,230, 0, + 0, 0, 0, 7, 0, 1, 1, 1, 1,220,230,230,230,220,220,230, + 230,220,230,230,220,230, 0, 0,230,230,220, 0, 0, 0, 9, 9, + 0,220, 0, 0, 0, 0, 0, 9, 9, 0, 9, 7, 0, 1,220,220, + 220,220,220,220,230,230,230,220,220,230,220,220,230,230,220,230, + 230,220,230,220,230,230,230, 0,230, 0,220,220,220,220,220, 0, + 0, 9, 9, 0, 0, 1, 0, 0, 0, 0, 0, 0,220,230, 0,230, + 230, 0, 0,220,220, 0, 0,230,220, 0, 0, 9, 7,220,220,220, + 0,230,232,220,220,220,220,232,216,220,202,202,220,220,220,220, + 202,202,220,220,220,230,240,230,220,230,220,220, 0,232,220,220, + 230,233,234,234,233,234,234,233,230, 0,220,230,230,230,230,222, + 220,230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, + 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, + 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, 35, 0, 0, + 0,230, 0,220,230, 0, 36, 0, 0,220,220,230,220,220,230,230, + 0,230,230, 0,220, 27, 28, 29,230, 0,230,220,230, 0, 84, 91, + 0,103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122, + 122, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, + 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230, + 230, 0, 0,220, 0, 0,228, 0, 0, 0,222,230,220,230, 0, 0, + 220,230,220, 0,220,230,230,230,234,230, 0, 1, 1,230,234,214, + 220,202,230,230,230,230,230,232,228,228,220,218,230,233,220,230, + 220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, + 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0,220, 0, 0, + 230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230,220, + 0, 0, 7, 9, 0, 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, + 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,232,232,220, + 230,230,230, 7, 0, 1, 0, 0, 32, 0, 48, 0, 0, 84, 96,135, + 144, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 40, + 0, 0, 0, 0, 0, 48, 56, 64, 0, 0, 0, 0, 0, 72, 80, 88, + 96,104, 0, 0, 0, 0, 0, 0, 0, 0,112, 0,120, 0, 0, 0, + 0, 0, 0,128,136,144,152,160,168, 0, 0, 0,176,184,192, 0, + 0, 0, 0, 0, 0,200, 0, 0, 0, 0, 0, 0, 0, 0,208, 0, + 0,216,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 0, 36, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 64, 0, 68, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 72, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 0, + 0, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 76, 80, 84, 88, + 0, 0, 12, 92, 96, 28, 0,100,104, 4, 4, 4,108, 44,112,116, + 120, 4,124, 0,128,132, 4, 4, 48,136,140, 0, 32, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 4, 48, 0, 52,144, 20,148,152, + 4, 0, 0,156,160,164,168,172, 4, 0,176, 56, 60,180, 32, 0, + 16,184, 56, 0, 0, 0, 0, 0, 52, 12, 12, 0, 0, 0, 0, 12, + 0, 0,188, 8, 8, 8, 8,192,196, 8, 8, 8, 8,200,204,208, + 212, 60, 44, 0, 0, 0, 0, 0, 0, 0,216, 28,220, 0, 12, 4, + 16, 0, 0, 0, 0,224,228, 0, 0, 0, 0, 0, 4,232, 32, 0, + 0, 0, 0, 0, 0, 0,236, 12, 0, 0, 0, 0, 16, 0, 36, 0, + 0, 0, 24, 0, 0, 0,240,244, 0, 0, 0, 0, 2, 2, 2, 2, + 4, 4, 4, 4, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 6, 8, + 0, 10, 12, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 14, 16, + 6, 8, 0, 0, 4, 8, 0, 0, 2, 2, 2, 0, 0, 6, 4, 8, + 2, 0, 2, 0, 0, 0, 0, 6, 0, 20, 0, 0, 0, 22, 0, 0, + 0, 6, 8, 0, 24, 26, 28, 0, 0, 0, 30, 0, 0, 0, 0, 32, + 34, 36, 38, 0, 0, 40, 42, 0, 0, 0, 18, 0, 0, 0, 2, 2, + 2, 2, 0, 2, 2, 2, 0, 6, 44, 0, 0, 0, 0, 2, 0, 46, + 48, 50, 0, 0, 52, 0, 0, 0, 6, 4, 54, 0, 2, 0, 0, 2, + 2, 56, 58, 60, 0, 62, 64, 18, 2, 10, 12, 0, 0, 0, 66, 8, + 0, 2, 2, 2, 0, 6, 4, 4, 4, 4, 68, 2, 70, 4, 4, 4, + 8, 72, 0, 0, 74, 76, 2, 0, 78, 0, 0, 0, 4, 8, 2, 0, + 0, 0, 80, 0, 6, 4, 4, 4, 4, 8, 0, 2, 2, 2, 2, 6, + 4, 4, 4, 8, 0, 0, 0, 82, 0, 84, 86, 0, 0, 0, 2, 88, + 0, 0, 0, 90, 6, 8, 2, 0, 0, 0, 6, 4, 4, 4, 8, 0, + 2, 0, 2, 2, 6, 4, 4, 8, 0, 10, 12, 6, 8, 2, 0, 0, + 4, 5, 6, 7, 8, 9, 10, 1, 1, 11, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 12, 13, 2, 2, 2, 2, 14, 0, 0, 0, 0, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 25, 26, 3, 3, + 3, 27, 0, 0, 0, 28, 29, 30, 0, 31, 32, 33, 34, 35, 36, 37, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 38, 1, 1, 39, 1, 40, 1, 1, 1, 41, 0, 42, + 1, 1, 43, 1, 1, 1, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 20, 21, 8, 8, 8, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 2, 2, 51, 52, 53, 54, 9, 9, 9, 9, 9, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 8, 8, 70, + 71, 72, 73, 74, 75, 5, 5, 5, 5, 76, 5, 5, 5, 5, 5, 5, + 5, 15, 15, 5, 5, 5, 5, 77, 5, 78, 79, 80, 81, 82, 83, 1, + 84, 85, 86, 87, 88, 89, 90, 91, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 92, 1, 1, 1, + 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 93, 16, 16, 94, 95, 96, + 97, 98, 99,100,101,102,103,104,105, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 106, 0, 0, 1, 1,107,108,109, 13, 13, 13,110,111,112,113,114, + 115,116,117,118,119, 0,120,121,122,123,124,125,126, 17, 17,127, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154, 0,155,156,157,158, + 0,159,160,161,162,163,164,165,166,167,168,169,170, 0,171,172, + 173, 7, 7, 7, 7, 7, 7, 7,174,175, 7,176, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 177, 4, 4, 4, 4, 4, 4, 4, 4,178, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, - 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, - 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, - 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, - 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, - 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, - 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, - 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, - 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, - 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, - 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 62, 62, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 6, - 6, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, - 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, - 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, - 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, - 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, - 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, - 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, - 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, - 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, - 86, 86, 86, 86, 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 2, 2, 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, - 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 2, 2, - 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, - 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, - 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, - 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, - 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, - 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, - 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, 12, 12, 2, 2, - 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, - 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 2, - 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 41, 2, 2, 2, 2, 2,118,118,118,118,118,118,118,118,118,118, - 118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, - 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 50, 50, - 2, 2, 2, 2, 2, 2,135,135,135,135,135,135,135,135,135,135, - 135,135, 2, 2, 2, 2,106,106,106,106,106,106,106,106,104,104, - 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, - 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, - 2,161,161,161,161,161,161,161, 2,161,161, 2, 2, 2,170,170, - 170,170,170,170,170,170,170,170,170,170, 2, 2, 2, 2,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 2, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, 2, 2, 47, 47, - 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, - 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 2, 81,120,120,120,120,120,120,120,120,116,116, - 116,116,116,116,116,116,116,116,116,116,116,116,116, 2, 2, 2, - 2, 2, 2, 2, 2,116,128,128,128,128,128,128,128,128,128,128, - 128, 2,128,128, 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, - 98, 98, 98, 98, 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, - 2, 2, 97, 97, 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, - 57, 57, 2, 57, 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, - 57, 57, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, - 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, - 88, 88, 88, 88, 88, 88,117,117,117,117,117,117,117,117,112,112, - 112,112,112,112,112,112,112,112,112,112,112,112,112, 2, 2, 2, - 2,112,112,112,112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122, - 122,122,122,122,122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122, - 122,122,122, 2, 2, 2, 2,122,122,122,122,122,122,122, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130, - 130,130,130,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, - 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, - 2, 2, 2, 2, 2, 2,165,165,165,165,165,165,165,165,165,165, - 165,165,165,165, 2, 2, 2,165,165,165,165,165,165,165, 2, 2, - 2, 2, 2, 2,165,165,156,156,156,156,156,156,156,156,156,156, - 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 2, 2, 2, 2, 2, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,171,171,171,171,171,171,171,171,171,171, - 2,171, 2, 2,171, 2,171,171,171,171,171,171, 2,171,171, 2, - 171, 2, 2,171, 2,171,171,171,171, 2,171,171,171,171,171, 2, - 2, 2, 2, 2, 2, 2, 2,171,171, 2, 2, 2, 2, 2,137,137, - 137,137,137,137,137,137,137,137,137,137, 2,137,137,137,137,137, - 2, 2, 2, 2, 2, 2,124,124,124,124,124,124,124,124,124,124, - 2, 2, 2, 2, 2, 2,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123, 2, 2,114,114,114,114,114,114,114,114,114,114, - 114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, - 2, 2, 2, 2, 2, 2, 33, 33, 33, 33, 2, 2, 2, 2,126,126, - 126,126,126,126,126,126,126,126,126, 2, 2,126,126,126,126,126, - 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2, 7, 7, - 2, 2, 2, 2, 2, 2,169,169,169,169,169,169,169,169,169,169, - 2, 2, 2, 2, 2, 2,133,133,133,133,133,133,133,133,133, 2, - 133,133,133,133,133,133,133,133,133,133,133,133,133, 2,133,133, - 133,133,133,133, 2, 2,133,133,133,133,133, 2, 2, 2,134,134, - 134,134,134,134,134,134, 2, 2,134,134,134,134,134,134, 2,134, - 134,134,134,134,134,134,134,134,134,134,134,134,134, 2,138,138, - 138,138,138,138,138, 2,138,138, 2,138,138,138,138,138,138,138, - 138,138,138,138,138,138, 2, 2,138, 2,138,138, 2,138,138,138, - 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, 2,143,143, 2, - 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, - 143,143,143,143,143, 2,143,143, 2,143,143,143,143,143,143, 2, - 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, 2, 2,145,145, - 145,145,145,145,145,145,145, 2, 2, 2, 2, 2, 2, 2,163,163, - 163,163,163,163,163,163,163, 2,163,163,163,163,163,163,163,163, - 163, 2, 2, 2,163,163,163,163,163, 2, 2, 2, 2, 2, 86, 2, - 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, - 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2,157,157, - 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 2, 80, 80, - 80, 2, 2, 2, 2, 2,127,127,127,127,127,127,127,127,127,127, - 127,127,127,127,127, 2,166,166,166,166,166,166,166,166,166,166, - 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2,115,115, - 115,115,115,115,115,115,115,115,115,115,115,115,115, 2,115,115, - 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, - 159,159,159,159,159, 2,159,159, 2, 2, 2, 2, 2, 2,103,103, - 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, - 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,167,167, - 167,167,167,167,167,167,167,167, 2, 2, 2, 2, 2, 2,146,146, - 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, - 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, - 155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2,155,136, 2, - 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, - 17, 2, 2, 2, 2, 2, 2, 2, 15, 2, 2, 2, 2, 2, 15, 15, - 15, 2, 2, 17, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17,139,139, - 139,139,139,139,139,139,139,139,139,139, 2, 2, 2, 2,105,105, - 105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2,105,105, - 105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, 2, 2,105,105, - 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 2, 2, 2, 2, 2, 19, 19, 19, 56, 56, - 56, 56, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2, 6, 6, - 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,160,160, - 160,160,160,160,160,160,160,160,160,160,160,160,160, 2,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164,164,164,164,164, 2, 2, 2, 2, 2, 2,168,168, - 168,168,168,168,168,168,168,168,168, 2, 2, 2, 2,168, 30, 30, - 30, 30, 2, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, - 113,113,113, 2, 2,113,113,113,113,113,113,113,113, 2,132,132, - 132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, - 2, 2, 2, 2,132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, - 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, - 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, - 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, - 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 13, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, - 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 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, 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, - 21, 9, 22, 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, 23, 9, 9, 9, 9, 9, 24, 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, 25, 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, 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, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, - 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, - 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, - 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, - 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, - 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, - 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, - 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, - 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 162, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, - 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0, - 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178, - 179, 0, 0, 0,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, - 208,209,210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, + 4, 4, 4, 4, 4, 4, 4, 4,179, 11, 11, 11, 11,180, 0, 0, + 0, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 12, 12, 12, 12,182,183,184,185, 0, 0,186, 0,187,188,189, + 190, 3, 3, 3, 3, 3, 3, 14, 14, 14,191,192,193, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 194,195,196,197, 18, 18,198, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,199,200, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,201, 5, 5, 5,202,203, + 204, 5,205,206,207,208,209,210, 0,211,212,213, 5, 5,214, 5, + 215, 10, 10, 10, 10, 10,216, 0, 0, 0, 0, 0, 0, 0, 0,217, + 0,218,219,220, 0, 0,221, 0, 0, 0,222, 0,223, 0,224, 0, + 225,226,227,228, 0, 0, 0, 0, 0,229,230,231, 0,232,233, 0, + 0,234,235, 5,236,237, 0, 5, 5, 5, 5, 5, 5, 5,238, 5, + 239,240,241, 5, 5,242,243, 5,244, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,245, 1, + 1,246, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,247, 1, + 1, 1, 1, 1, 1, 1, 1, 1,248, 1, 1, 1, 1,249, 0, 0, + 0, 1, 1, 1, 1,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1,251, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1,252, 0, 0, 0, 0, 0, 0, + 0,253, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 13, 13, 13, 13, 12, 12, 12, 12, 0, 0, 0, + 0,136,136,136,136, 80, 80, 80, 80, 19, 19, 19, 19, 3, 3, 3, + 3, 63, 63, 63, 63, 39, 39, 39, 39, 28, 28, 28, 28,131,131,131, + 131, 79, 79, 79, 79, 1, 1, 1, 1,127,127,127,127, 6, 6, 6, + 6,155,155,155,155, 9, 9, 9, 9, 30, 30, 30, 30,139,139,139, + 139, 15, 15, 15, 15,110,110,110,110, 77, 77, 77, 77, 17, 17, 17, + 17, 27, 27, 27, 27, 33, 33, 33, 33,113,113,113,113, 49, 49, 49, + 49, 25, 25, 25, 25, 29, 29, 29, 29, 7, 7, 7, 7, 8, 8, 8, + 8, 32, 32, 32, 32, 99, 99, 99, 99, 31, 31, 31, 31,105,105,105, + 105, 55, 55, 55, 55, 62, 62, 62, 62, 56, 56, 56, 56, 91, 91, 91, + 91,119,119,119,119, 14, 14, 14, 14, 94, 94, 94, 94, 20, 20, 20, + 20,100,100,100,100,130,130,130,130,157,157,157,157,137,137,137, + 137, 97, 97, 97, 97,123,123,123,123,133,133,133,133,146,146,146, + 146, 84, 84, 84, 84,159,159,159,159,132,132,132,132, 4, 4, 4, + 4, 36, 36, 36, 36, 24, 24, 24, 24, 30, 30, 30, 2, 35, 35, 35, + 35, 40, 40, 40, 40,124,124,124,124,125,125,125,125,140,140,140, + 140, 37, 37, 37, 37, 58, 58, 58, 58, 0, 0, 2, 2, 75, 75, 75, + 75, 68, 68, 68, 68,114,114,114,114,163,163,163,163, 22, 22, 22, + 22, 23, 23, 23, 23, 76, 76, 76, 76, 0, 0, 0, 2, 26, 26, 26, + 26, 87, 87, 87, 87,135,135,135,135, 89, 89, 89, 89,141,141,141, + 141, 70, 70, 70, 70, 92, 92, 92, 92, 96, 96, 96, 96, 5, 5, 5, + 5, 18, 18, 18, 18, 48, 48, 48, 48, 85, 85, 85, 85,109,109,109, + 109,102,102,102,102,151,151,151,151, 16, 16, 16, 16, 0, 2, 2, + 2,165,165,165,165,108,108,108,108,171,171,171,171,142,142,142, + 142,150,150,150,150,134,134,134,134,138,138,138,138, 64, 64, 64, + 64, 90, 90, 90, 90, 21, 21, 21, 21, 93, 93, 93, 93, 61, 61, 61, + 61, 65, 65, 65, 65, 78, 78, 78, 78,126,126,126,126,154,154,154, + 154,121,121,121,121,166,166,166,166,167,167,167,167,152,152,152, + 152, 10, 10, 10, 10, 2, 0, 0, 0,104,104,104,104,170,170,170, + 170, 57, 57, 57, 57,107,107,107,107,175,175,175,175, 38, 38, 38, + 38, 73, 73, 73, 73, 86, 86, 86, 86, 67, 67, 67, 67, 59, 59, 59, + 59, 51, 51, 51, 51,161,161,161,161,144,144,144,144,143,143,143, + 143,172,172,172,172,174,174,174,174, 60, 60, 60, 60, 69, 69, 69, + 69, 47, 47, 47, 47,112,112,112,112,118,118,118,118,106,106,106, + 106,156,156,156,156,147,147,147,147,148,148,148,148,169,169,169, + 169,164,164,164,164,168,168,168,168, 11, 11, 11, 11, 74, 74, 74, + 74, 42, 42, 42, 42, 50, 50, 50, 50,116,116,116,116,111,111,111, + 111,115,115,115,115, 52, 52, 52, 52, 13, 13, 2, 2,120,120,120, + 120, 98, 98, 98, 98, 88, 88, 88, 88,117,117,117,117,101,101,101, + 101,103,103,103,103, 19, 19, 19, 0, 95, 95, 95, 95, 30, 30, 2, + 2, 34, 34, 34, 34, 54, 54, 54, 54, 0, 2, 0, 0, 71, 71, 71, + 71, 53, 53, 53, 53, 81, 81, 81, 81, 66, 66, 66, 66, 83, 83, 83, + 83,153,153,153,153,160,160,160,160, 2, 2, 22, 22, 30, 2, 30, + 30, 9, 9, 2, 2, 2, 2, 0, 0, 41, 41, 41, 41, 72, 72, 72, + 72,173,173,173,173, 82, 82, 82, 82,158,158,158,158,129,129,129, + 129,145,145,145,145, 2, 3, 3, 3, 23, 2, 23, 23, 16, 2, 16, + 16, 2, 2, 2, 0, 45, 45, 45, 45, 44, 44, 44, 44, 43, 43, 43, + 43,128,128,128,128,122,122,122,122,149,149,149,149, 0, 19, 19, + 19, 0, 0, 19, 0, 9, 2, 9, 9, 5, 2, 2, 5, 2, 10, 10, + 10, 10, 10, 2, 10, 2, 21, 21, 21, 21, 2, 2, 21, 22, 22, 22, + 2, 22, 22, 2, 2, 20, 2, 20, 20, 2, 30, 30, 30, 12, 12, 12, + 2, 19, 19, 19, 2, 2, 2, 12, 12,161,161, 2,161, 3, 3, 3, + 2,107, 2, 2,107, 2, 3, 2, 3, 19, 0, 0, 0, 2, 2, 9, + 9, 9, 9, 9, 2, 2, 4, 4, 4, 2, 11, 11, 11, 11, 11, 11, + 2, 11, 2, 11, 11, 10, 10, 2, 2, 22, 2, 22, 22, 2, 2, 2, + 22, 23, 23, 2, 2, 2, 36, 36, 36, 2, 2, 36, 36, 2, 25, 25, + 25, 46, 46, 46, 46, 31, 31, 2, 2, 91, 91, 2, 2, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 17, 17, 17, 49, 49, 49, 2,161,161,161, + 2, 2,107,107,107,107, 2, 2, 2,171,171, 2,171, 0, 0, 2, + 0, 2, 3, 3, 2, 3, 2, 2, 3, 4, 4, 4, 2, 2, 14, 14, + 14, 14, 14, 14, 2, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, + 0, 37, 37, 37, 2, 3, 3, 2, 2, 2, 2, 2, 3, 2, 2, 5, + 5, 5, 5, 5, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 2, + 2, 10, 2, 10, 10, 21, 2, 21, 21, 21, 21, 2, 2, 22, 2, 2, + 2, 2, 16, 16, 16, 16, 16, 2, 2, 36, 36, 36, 2, 36, 2, 2, + 2, 18, 18, 18, 2, 18, 18, 2, 2, 25, 2, 25, 25, 8, 8, 2, + 8, 2, 8, 2, 2, 29, 29, 2, 2, 46, 2, 46, 46, 32, 2, 2, + 2, 1, 1, 2, 2, 1, 1, 1, 0, 19, 19, 9, 9, 2, 9, 2, + 9, 0, 0, 0, 19, 19, 2, 2, 2, 0, 0, 19, 19, 2, 2, 2, + 61, 15, 15, 15, 2, 17, 17, 17, 0, 2, 19, 19, 19, 75, 75, 2, + 2, 12, 2, 2, 2, 68, 68, 2, 2, 87, 87, 2, 2, 49, 49, 2, + 2, 50, 50, 2, 2, 2, 57, 57, 57, 57, 2, 2, 2,112,112,112, + 2, 2,122,122,122,130,130,130, 2,165,165, 2, 2,156,156, 2, + 2, 2, 2, 3, 3, 94, 94, 2, 2,129,129, 2,129,107, 2,107, + 107,123,123, 2, 2,102,102, 2, 2,126,126,126, 2,154,154,154, + 2, 2, 2,150,150,169,169, 2, 2,138,138,138, 2,138,138, 2, + 138,143,143, 2,143,163,163,163, 2,103,103, 2, 2,119,119, 2, + 119, 2, 2, 2, 99, 13, 13, 13, 2,136,136,136, 2,105, 2, 2, + 2, 0, 0, 0, 1, 56, 56, 56, 2,151,151, 2, 2, 3, 3, 2, + 3, 0, 0, 26, 26, 0, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, + 0, 9, 9, 2, 9, 9, 9, 55, 55, 6, 1, 1, 6, 2, 2, 2, + 14, 14, 2, 2, 2, 3, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, + 3, 37, 37, 2, 37, 2, 37, 37, 37, 38, 38, 2, 2, 64, 64, 64, + 2, 2, 64, 64, 64, 90, 90, 2, 2, 90, 90, 90, 2, 2, 2, 95, + 2, 3, 3, 0, 3, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, + 7, 2, 5, 5, 5, 5, 2, 5, 5, 5, 2, 5, 2, 5, 5, 2, + 2, 2, 2, 2, 5, 5, 5, 2, 5, 2, 11, 11, 2, 2, 11, 2, + 2, 11, 2, 11, 2, 2, 2, 11, 11, 10, 2, 2, 2, 2, 2, 10, + 10, 21, 21, 2, 21, 2, 2, 21, 21, 2, 22, 22, 22, 2, 22, 22, + 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 2, 23, 23, 2, 2, 2, + 23, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 16, 16, 2, 2, 20, + 20, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, + 36, 36, 2, 36, 2, 2, 24, 24, 24, 24, 24, 24, 2, 2, 18, 18, + 2, 18, 2, 18, 18, 2, 18, 2, 18, 18, 2, 18, 2, 25, 2, 2, + 2, 25, 0, 0, 0, 0, 25, 25, 2, 8, 8, 8, 0, 30, 2, 2, + 2, 34, 2, 2, 2, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, + 2, 45, 45, 2, 2, 2, 2, 2, 45, 44, 0, 0, 2, 32, 32, 0, + 0, 32, 0, 32, 32, 32, 32, 2, 2, 32, 32, 32, 2, 28, 28, 2, + 2, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, 2, 2, 52, 2, 2, + 2, 58, 58, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 2, 2, 54, + 54, 91, 91, 91, 2, 91, 2, 2, 91, 62, 2, 62, 62, 2, 2, 2, + 70, 70, 70, 2, 2, 2, 70, 70, 70, 6, 6, 6, 2, 8, 8, 8, + 2, 2, 8, 8, 8, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, + 2, 9, 9, 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, 9, + 19, 6, 19, 19, 19, 19, 19, 19, 9, 2, 9, 9, 9, 0, 19, 2, + 2, 1, 2, 2, 2, 0, 0, 9, 0, 2, 55, 55, 55, 61, 2, 2, + 2, 13, 13, 2, 13, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, + 1, 1, 1, 12, 12, 2, 15, 15, 15, 2, 1, 1, 0, 0, 15, 15, + 15, 2, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 0, 39, 2, 2, + 2, 39, 39, 39, 2, 60, 2, 2, 2, 2, 2, 75, 75, 69, 69, 0, + 69, 2, 2, 2, 74, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, 84, + 84, 33, 33, 33, 2, 68, 68, 68, 2, 92, 92, 92, 2, 2, 2, 2, + 92, 87, 87, 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, 2, + 12, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, + 14, 3, 3, 0, 0, 1, 1, 6, 6, 3, 2, 3, 3, 3, 2, 2, + 0, 0, 0, 17, 17, 17, 17, 0, 0, 2, 49, 49, 49, 49, 49, 2, + 49, 9, 2, 2, 2, 0, 1, 2, 2, 71, 2, 2, 2, 67, 2, 2, + 2, 2, 42, 42, 42, 41, 41, 41, 2,118,118,118, 2, 53, 53, 2, + 53, 59, 59, 2, 2, 2, 2, 2,104,161, 2, 2, 2,110,110,110, + 2,110,110, 2, 2, 19, 19, 2, 19, 19, 2, 19, 19, 47, 47, 2, + 2, 47, 2, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, + 47, 81, 81, 2, 81,116,116,116, 2, 2, 2, 2,116,128,128,128, + 2,128,128, 2, 2, 2, 2, 2,128, 2, 2, 2, 66, 72, 72, 2, + 2, 2, 2, 2, 72,173,173, 2, 2, 2, 2, 97, 97, 2, 57, 57, + 2, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 2, 2, 2, + 112, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83, 2, 2, 82, 82, 82, + 2,122,122, 2, 2,122, 2, 2, 2, 89, 2, 2, 2, 2, 2,130, + 130,144,144, 2, 2, 2,165,165,165, 2, 2,165,165,156,156, 2, + 156, 3, 2, 2, 2,148,148, 2, 2,158,158, 2, 2,149,149,149, + 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, 85, 2, 2, 85, 2, + 2,101, 2, 2, 2,101,101, 2, 2, 96, 2, 96, 96,111,111,111, + 2,108,108, 2,108,108,108, 2, 2,129,129,129, 2,129, 2,129, + 129,129,129, 2, 2,109,109,109, 2,109,109, 2, 2,107,107, 2, + 1,107,107, 2, 2, 2, 2, 2,107, 2, 2,107,107, 2, 2,171, + 2,171, 2,171, 2, 2,171, 2,171,171,171,171, 2,171, 2, 2, + 2, 2,171,171, 2, 2,137,137,137,137,137, 2, 2,124,124, 2, + 2,114, 2, 2, 2,114,114, 2, 2, 2,126,126,126,125,125,125, + 2, 2, 2, 2,125, 2,154, 2, 2, 2,154,154, 2,154,154, 2, + 154,154, 2, 2,154,154,154, 2, 2,150, 2, 2, 2,140,140,140, + 2,121, 2, 2, 2, 7, 7, 2, 2,133, 2,133,133,133,133,133, + 2,133,133, 2, 2,133, 2, 2, 2, 2, 2,134,134, 2,134,134, + 134,134,134,134, 2, 2, 2,138, 2,138,138, 2, 2,143, 2,143, + 143,143,143,143, 2,143, 2, 2, 2,143,143, 2, 2,175,175, 2, + 2,145, 2, 2, 2,163, 2,163,163, 2, 2,163,163, 86, 2, 2, + 2, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2, 2, 2,157,157,157, + 2, 80, 80, 2, 2, 80, 80, 80, 2,127,127,127, 2,166,166, 2, + 2, 79, 2, 2, 2,115,115,115, 2,115,115, 2, 2, 2, 2,115, + 115,159,159,159, 2,159,159, 2, 2,119,119, 2, 2, 2,119,119, + 119,167,167, 2, 2,146,146,146, 2,172, 2, 2,172, 99, 99, 99, + 2,136,139, 13, 13,155, 2, 2, 2,155,155, 2, 2, 2, 2, 2, + 155, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, 17, + 2, 2, 2, 15, 2, 2, 17, 2, 2,105,105,105, 2,105,105, 2, + 2, 1, 1, 1, 2, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, 0, + 2, 2, 0, 0, 2, 0, 2, 0, 2, 2, 2, 2,131, 2,131,131, + 131, 56, 2, 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, + 2, 2, 2, 2, 6,151, 2, 2, 2, 2, 2,151,151,160,160,160, + 2,152,152, 2, 2, 2, 2, 2,152,164,164, 2, 2,168,168,168, + 2, 2, 2, 2,168,174,174,174, 2,174,174, 2, 2, 2, 2,174, + 174, 2, 30, 30, 2,113, 2, 2,113,113,113,113, 2,132,132, 2, + 2, 2, 2,132,132, 2, 2, 3, 2, 3, 2, 3, 2, 15, 0, 0, + 2, 0, 2, 2, 0, 13, 2, 2, 2, 2, 0, 2, 2, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 10, 0, 11, 12, 13, 0, + 0, 0, 14, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 0, 0, 0, 0, 18, + 0, 0, 0, 0, 0, 19, 20, 21, 0, 22, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, + 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, + 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, + 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, + 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, + 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, + 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, + 0, 0, 0, 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, + 0,111,112,113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, + 119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131,132, + 133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148, + 149,150,151,152,153,154,155,156,157, 0, 0, 0,158,159,160,161, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,162, 0,163, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,164,165, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, + 0, 0, 0,168,169, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,173, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,174, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 176,177, 0, 0, 0, 0,178,179, 0, 0, 0,180,181,182,183,184, + 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200, + 201,202,203,204,205,206,207,208,209,210,211,212,213, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -static const uint16_t -_hb_ucd_u16[9668] = +static const uint16_t _hb_ucd_u16[10877]= { - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, - 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, - 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32, - 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, - 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, - 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, - 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, - 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, - 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, - 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, - 48, 171, 48, 48, 48, 173, 174, 175, 48, 176, 9, 9, 9, 9, 9, 177, - 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, - 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, - 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, - 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, - 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, - 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, - 209, 209, 176, 140, 287, 140, 271, 271, 271, 288, 209, 209, 209, 209, 289, 271, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 271, 296, 209, 209, 297, 279, 298, 279, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 279, 279, 279, 279, 279, 279, 279, 279, 299, 300, 279, 279, 279, 301, 279, 302, - 209, 209, 209, 279, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, - 9, 9, 9, 11, 11, 11, 306, 307, 13, 13, 13, 13, 13, 13, 308, 309, - 11, 11, 310, 48, 48, 48, 311, 312, 48, 313, 314, 314, 314, 314, 32, 32, - 315, 316, 317, 318, 319, 320, 140, 140, 209, 321, 209, 209, 209, 209, 209, 322, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, 140, 209, - 324, 325, 326, 327, 136, 48, 48, 48, 48, 328, 178, 48, 48, 48, 48, 329, - 330, 48, 48, 136, 48, 48, 48, 48, 200, 331, 48, 48, 209, 209, 332, 48, - 209, 333, 334, 209, 335, 336, 209, 209, 334, 209, 209, 336, 209, 209, 209, 209, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, - 48, 337, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 338, 48, 48, 229, - 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, - 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, - 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, - 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, - 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, - 383, 384, 314, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, - 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, - 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, - 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, - 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, - 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, - 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, - 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, - 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, - 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 48, 48, 48, 388, - 48, 48, 48, 313, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, - 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, - 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, - 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, - 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, - 48, 48, 475, 192, 476, 9, 477, 11, 478, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 271, 479, 48, 48, 480, 481, 482, 140, 140, 483, - 48, 464, 484, 48, 62, 485, 140, 48, 486, 140, 140, 48, 487, 140, 48, 313, - 488, 48, 48, 489, 490, 457, 491, 492, 222, 48, 48, 493, 494, 48, 196, 192, - 495, 48, 496, 497, 498, 48, 48, 499, 222, 48, 48, 500, 501, 502, 503, 504, - 48, 97, 505, 506, 507, 140, 140, 140, 508, 509, 510, 48, 48, 511, 512, 192, - 513, 83, 84, 514, 515, 516, 517, 518, 519, 48, 48, 520, 521, 522, 523, 140, - 48, 48, 48, 524, 525, 526, 481, 140, 48, 48, 48, 527, 528, 192, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 529, 530, 531, 532, 140, 140, - 48, 48, 48, 533, 534, 192, 535, 140, 48, 48, 536, 537, 192, 538, 539, 140, - 48, 540, 541, 542, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 505, 543, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 544, - 545, 546, 48, 547, 548, 192, 140, 140, 140, 140, 549, 48, 48, 550, 551, 140, - 552, 48, 48, 553, 554, 555, 48, 48, 556, 557, 558, 48, 48, 48, 48, 196, - 559, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 560, 192, - 84, 48, 529, 561, 562, 148, 175, 563, 48, 564, 565, 566, 140, 140, 140, 140, - 567, 48, 48, 568, 569, 192, 570, 48, 571, 572, 192, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 573, - 574, 115, 48, 575, 576, 577, 140, 140, 140, 140, 140, 100, 271, 578, 579, 580, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, - 272, 272, 272, 272, 272, 272, 581, 582, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 583, - 48, 48, 48, 584, 585, 586, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 71, - 48, 48, 48, 48, 313, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 587, 588, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 589, - 48, 48, 48, 590, 591, 592, 593, 594, 48, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 595, 48, 596, 192, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 9, 9, 11, 11, 271, 597, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 598, 599, 600, 600, 601, 602, 140, 140, 140, 140, 603, 604, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 605, - 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 606, - 48, 48, 607, 608, 140, 609, 610, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 611, 612, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 192, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, 140, - 32, 32, 613, 32, 614, 209, 209, 209, 209, 209, 209, 209, 322, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 323, - 209, 209, 615, 209, 209, 209, 616, 617, 618, 209, 619, 209, 209, 209, 287, 140, - 209, 209, 209, 209, 620, 140, 140, 140, 140, 140, 140, 140, 271, 621, 271, 621, - 209, 209, 209, 209, 209, 338, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, - 9, 622, 11, 623, 624, 625, 241, 9, 626, 627, 628, 629, 630, 9, 622, 11, - 631, 632, 11, 633, 634, 635, 636, 9, 637, 11, 9, 622, 11, 623, 624, 11, - 241, 9, 626, 636, 9, 637, 11, 9, 622, 11, 638, 9, 639, 640, 641, 642, - 11, 643, 9, 644, 645, 646, 647, 11, 648, 9, 649, 11, 650, 538, 538, 538, - 32, 32, 32, 651, 32, 32, 652, 653, 654, 655, 45, 140, 140, 140, 140, 140, - 656, 657, 658, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 659, 660, 661, 27, 27, 27, 662, 140, 663, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 151, 664, 665, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 666, 140, 48, 48, 667, 668, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 669, 192, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 587, 670, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 671, 200, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 672, 614, 140, 140, - 9, 9, 626, 11, 673, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 503, 271, 271, 674, 675, 140, 140, 140, 140, - 503, 271, 676, 677, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 678, 48, 679, 680, 681, 682, 683, 684, 685, 206, 686, 206, 140, 140, 140, 687, - 209, 209, 688, 209, 209, 209, 209, 209, 209, 322, 333, 689, 689, 689, 209, 323, - 690, 209, 209, 209, 209, 209, 209, 209, 209, 209, 691, 140, 140, 140, 692, 209, - 693, 209, 209, 688, 694, 695, 323, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 696, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 697, 426, 426, - 209, 209, 209, 209, 209, 209, 209, 698, 209, 209, 209, 209, 209, 176, 688, 427, - 688, 209, 209, 209, 699, 176, 209, 209, 699, 209, 691, 688, 695, 140, 140, 140, - 209, 209, 209, 209, 209, 322, 691, 426, 700, 209, 209, 209, 701, 702, 176, 694, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 703, 209, 209, 209, 209, 209, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, - 48, 48, 48, 207, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 481, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 48, - 48, 48, 48, 48, 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 704, 140, 584, 584, 584, 584, 584, 584, 140, 140, 140, 140, 140, 140, 140, 140, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 705, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 706, - 0, 0, 1, 1, 0, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 5, 0, 6, 7, 7, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 13, 14, 13, 13, 13, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 23, 23, 26, 23, 27, 28, 29, 23, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 23, 23, 39, 40, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 82, 86, 86, 87, 88, 89, 90, 91, 82, - 92, 92, 92, 92, 92, 93, 94, 95, 96, 96, 96, 96, 96, 96, 96, 96, - 97, 97, 98, 97, 99, 100, 101, 97, 102, 97, 103, 104, 105, 106, 106, 107, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 110, 111, - 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 120, 122, 108, 123, - 124, 125, 126, 127, 128, 129, 130, 116, 131, 132, 133, 134, 135, 136, 137, 82, - 138, 138, 139, 138, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 4, 151, 152, 153, 4, 154, 7, 7, 155, 11, 156, 157, 11, 158, 159, 160, - 161, 0, 0, 162, 163, 0, 164, 165, 0, 166, 167, 4, 168, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, - 171, 171, 171, 171, 171, 171, 171, 171, 0, 0, 0, 172, 173, 0, 0, 0, - 174, 174, 174, 4, 175, 175, 175, 176, 93, 177, 178, 179, 180, 181, 181, 13, - 0, 0, 182, 82, 183, 184, 184, 185, 184, 184, 184, 184, 184, 184, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 96, 96, 198, 199, 0, 200, - 201, 0, 0, 202, 0, 0, 203, 204, 194, 194, 205, 0, 0, 0, 0, 0, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 0, 0, - 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 206, 208, 209, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 13, 13, 13, 212, 212, 213, - 0, 214, 4, 4, 215, 4, 216, 217, 218, 219, 220, 221, 222, 222, 223, 40, - 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 92, 234, 234, 235, 236, - 237, 238, 239, 240, 106, 106, 241, 242, 96, 96, 96, 96, 96, 243, 244, 245, - 82, 82, 82, 82, 82, 82, 82, 82, 184, 184, 184, 246, 184, 184, 247, 82, - 248, 249, 250, 23, 23, 23, 251, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 252, 23, 23, 253, 23, 254, 255, 256, 257, 258, 259, 23, 23, 23, 260, - 261, 1, 1, 262, 263, 201, 264, 265, 266, 267, 268, 82, 269, 269, 269, 270, - 271, 272, 11, 11, 273, 274, 187, 275, 82, 82, 82, 82, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 82, 287, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 303, 304, 305, 306, 307, 82, 82, 308, 309, 310, 311, 312, 313, 82, 314, - 315, 316, 82, 82, 317, 318, 319, 320, 321, 322, 323, 324, 325, 82, 326, 327, - 328, 329, 330, 331, 332, 333, 82, 82, 334, 334, 335, 82, 336, 337, 336, 338, - 339, 340, 341, 342, 343, 82, 82, 82, 82, 82, 82, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 357, 358, 359, 360, 360, 361, 362, - 363, 364, 365, 366, 367, 367, 367, 368, 369, 370, 371, 82, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 384, 385, 386, 387, 387, 388, 82, - 82, 82, 82, 82, 389, 390, 391, 82, 392, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 82, 82, 82, 82, 82, 402, 403, 82, 82, 82, 404, 404, 405, - 406, 407, 408, 82, 82, 409, 410, 411, 412, 412, 413, 414, 414, 415, 416, 417, - 418, 82, 82, 82, 82, 82, 419, 420, 421, 422, 423, 424, 425, 426, 82, 82, - 427, 428, 429, 430, 431, 432, 82, 82, 82, 82, 82, 82, 82, 82, 82, 433, - 434, 435, 436, 82, 82, 437, 438, 439, 440, 440, 440, 440, 440, 440, 440, 440, - 440, 440, 440, 440, 441, 82, 82, 82, 440, 440, 440, 442, 440, 440, 440, 440, - 440, 440, 443, 82, 82, 82, 82, 82, 82, 82, 82, 82, 444, 445, 445, 446, - 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 447, 447, 447, 447, 447, - 447, 447, 447, 447, 447, 447, 447, 449, 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 451, 82, 82, 82, 82, 82, 452, 453, 82, 82, 82, 82, 82, 82, - 212, 212, 212, 212, 212, 212, 212, 212, 212, 454, 455, 456, 457, 458, 459, 460, - 461, 461, 462, 463, 464, 82, 82, 82, 82, 82, 465, 466, 82, 82, 82, 82, - 82, 82, 467, 467, 468, 82, 82, 82, 469, 469, 470, 469, 471, 82, 82, 472, - 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, - 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 477, - 478, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 479, - 480, 191, 191, 191, 191, 191, 191, 191, 191, 481, 482, 483, 484, 484, 484, 484, - 484, 484, 484, 484, 484, 484, 484, 485, 486, 486, 486, 487, 488, 489, 82, 82, - 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 491, 82, 82, - 7, 492, 493, 0, 0, 0, 489, 82, 0, 0, 0, 0, 0, 0, 0, 494, - 0, 495, 0, 496, 497, 498, 0, 170, 11, 11, 499, 82, 82, 82, 491, 491, - 0, 0, 500, 501, 82, 82, 82, 82, 0, 0, 502, 0, 503, 504, 505, 0, - 506, 507, 508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, - 0, 0, 0, 0, 0, 0, 510, 0, 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 511, 512, 513, 82, 82, 514, 515, 82, 82, 82, 82, 82, 82, - 516, 517, 13, 518, 519, 82, 82, 82, 520, 521, 522, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 523, 524, 525, 526, 82, 82, 82, 82, 82, 82, 527, 528, - 82, 82, 82, 82, 82, 82, 529, 530, 82, 82, 82, 82, 82, 82, 82, 531, - 532, 532, 532, 532, 532, 532, 533, 82, 534, 534, 535, 82, 82, 82, 82, 82, - 82, 82, 82, 536, 0, 537, 82, 82, 261, 182, 82, 82, 82, 82, 82, 82, - 538, 539, 540, 541, 542, 543, 82, 544, 0, 545, 0, 0, 491, 546, 547, 494, - 0, 0, 0, 0, 0, 548, 82, 549, 550, 551, 552, 553, 82, 82, 82, 82, - 0, 0, 0, 0, 0, 0, 554, 555, 0, 0, 0, 556, 0, 0, 490, 557, - 545, 0, 558, 0, 559, 560, 561, 82, 0, 0, 491, 562, 563, 0, 564, 565, - 0, 0, 0, 0, 258, 0, 0, 490, 184, 184, 184, 184, 184, 184, 184, 82, - 184, 247, 184, 184, 184, 184, 184, 184, 566, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 567, 184, 184, 184, 184, 184, 184, 184, 184, 184, 568, - 184, 184, 566, 82, 82, 82, 82, 82, 566, 82, 82, 82, 82, 82, 82, 82, - 184, 184, 569, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 570, 82, 82, - 571, 0, 0, 0, 82, 82, 82, 82, 7, 7, 7, 7, 7, 7, 7, 572, - 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 4, 2, 2, 5, 2, - 2, 2, 2, 2, 2, 2, 2, 6, 7, 8, 0, 0, 9, 9, 9, 9, - 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, - 16, 17, 14, 14, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 29, 37, 38, 37, 37, - 37, 37, 37, 37, 37, 39, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 52, 31, 31, 31, - 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, - 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, - 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, - 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, - 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, - 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, - 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, - 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, - 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, - 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, - 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, - 153, 152, 152, 154, 155, 156, 152, 157, 158, 158, 158, 158, 158, 159, 158, 158, - 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, - 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, - 169, 169, 169, 169, 170, 170, 170, 170, 170, 171, 172, 171, 170, 171, 170, 170, - 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 171, 170, 170, 170, 170, 173, - 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 177, 177, - 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, 181, 182, 181, 183, - 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, - 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, - 198, 198, 198, 198, 198, 198, 198, 200, 198, 201, 178, 178, 178, 178, 202, 26, - 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, - 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 214, 214, 214, 215, - 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, - 216, 220, 9, 9, 9, 221, 26, 26, 222, 222, 222, 222, 222, 223, 222, 222, - 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, 228, 228, 228, 228, - 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, 18, 232, 165, 165, - 165, 165, 165, 233, 224, 26, 234, 9, 235, 236, 237, 238, 239, 240, 2, 2, - 2, 2, 2, 241, 242, 243, 2, 244, 2, 2, 2, 245, 14, 14, 246, 246, - 246, 246, 14, 247, 14, 14, 14, 246, 14, 14, 248, 14, 248, 14, 249, 250, - 14, 14, 251, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 2, 258, - 259, 26, 9, 9, 9, 9, 260, 26, 261, 262, 4, 0, 0, 263, 0, 0, - 2, 264, 0, 0, 0, 265, 26, 26, 0, 266, 26, 26, 267, 267, 267, 267, - 0, 0, 268, 0, 0, 0, 269, 0, 270, 270, 270, 270, 17, 17, 17, 17, - 17, 17, 271, 272, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, - 170, 170, 172, 26, 172, 172, 172, 172, 0, 0, 0, 276, 277, 277, 277, 278, - 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 280, 26, 26, 26, 0, 0, - 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, - 292, 293, 293, 293, 293, 293, 294, 169, 169, 295, 0, 0, 293, 293, 293, 293, - 276, 296, 290, 290, 169, 169, 169, 295, 169, 169, 169, 297, 0, 0, 290, 290, - 290, 290, 290, 298, 290, 290, 290, 0, 299, 299, 299, 299, 299, 300, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 304, 26, 26, - 305, 305, 305, 305, 305, 305, 305, 26, 306, 2, 2, 2, 2, 307, 2, 2, - 2, 308, 309, 258, 26, 26, 310, 2, 311, 311, 311, 311, 311, 312, 0, 265, - 313, 313, 313, 313, 313, 313, 313, 26, 314, 314, 314, 314, 315, 316, 314, 317, - 318, 318, 318, 318, 318, 319, 320, 320, 320, 320, 321, 322, 169, 169, 169, 323, - 324, 324, 324, 324, 324, 325, 324, 326, 164, 164, 164, 327, 328, 328, 328, 328, - 328, 328, 329, 26, 328, 330, 328, 331, 332, 332, 332, 332, 333, 26, 26, 334, - 335, 335, 336, 26, 337, 337, 337, 26, 172, 172, 2, 2, 2, 2, 2, 338, - 339, 340, 176, 176, 335, 335, 335, 335, 335, 341, 335, 342, 343, 26, 169, 169, - 295, 344, 169, 169, 169, 169, 169, 343, 277, 280, 277, 277, 277, 277, 277, 345, - 346, 26, 347, 348, 25, 25, 349, 350, 351, 25, 31, 31, 352, 26, 353, 31, - 31, 31, 31, 354, 31, 31, 355, 31, 31, 356, 26, 26, 26, 26, 31, 31, - 9, 9, 0, 265, 9, 357, 0, 0, 0, 0, 358, 0, 257, 359, 360, 31, - 31, 31, 31, 361, 362, 0, 0, 0, 363, 290, 289, 290, 290, 290, 290, 364, - 365, 365, 365, 366, 257, 257, 26, 367, 368, 369, 368, 368, 370, 368, 368, 371, - 368, 372, 368, 372, 368, 368, 368, 368, 368, 368, 368, 373, 374, 0, 0, 0, - 0, 0, 375, 0, 14, 252, 0, 376, 377, 26, 26, 26, 0, 0, 0, 378, - 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 359, - 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, - 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 396, 396, 396, 396, - 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, 398, 399, 398, 400, 401, 401, - 401, 401, 402, 401, 401, 401, 401, 402, 403, 403, 403, 403, 403, 26, 404, 404, - 404, 404, 404, 404, 405, 406, 407, 408, 407, 408, 409, 407, 410, 407, 410, 411, - 412, 412, 412, 412, 412, 412, 413, 26, 414, 414, 414, 414, 414, 414, 415, 26, - 414, 414, 416, 26, 414, 26, 26, 26, 417, 2, 2, 2, 2, 2, 418, 419, - 420, 421, 422, 422, 422, 422, 423, 424, 425, 425, 426, 425, 427, 427, 427, 427, - 428, 428, 428, 429, 430, 428, 26, 26, 431, 431, 432, 433, 434, 434, 434, 435, - 436, 436, 436, 437, 438, 438, 438, 438, 439, 439, 439, 440, 439, 439, 441, 439, - 439, 439, 439, 439, 442, 443, 444, 445, 446, 446, 447, 448, 446, 449, 446, 449, - 450, 450, 450, 450, 451, 451, 451, 451, 452, 452, 452, 452, 453, 454, 453, 26, - 455, 455, 455, 455, 455, 455, 456, 457, 458, 458, 459, 458, 460, 460, 461, 460, - 462, 462, 463, 464, 26, 465, 26, 26, 466, 466, 466, 466, 466, 467, 26, 26, - 468, 468, 468, 468, 468, 468, 469, 26, 468, 468, 469, 470, 471, 471, 471, 471, - 471, 26, 471, 472, 473, 473, 473, 473, 474, 475, 473, 473, 474, 476, 26, 26, - 31, 31, 31, 50, 477, 477, 477, 477, 477, 478, 479, 26, 480, 26, 26, 26, - 26, 26, 26, 481, 482, 482, 482, 482, 482, 26, 483, 483, 483, 483, 483, 484, - 26, 26, 485, 485, 485, 486, 26, 26, 26, 26, 487, 487, 487, 488, 26, 26, - 489, 489, 490, 26, 491, 491, 491, 491, 491, 492, 493, 491, 491, 491, 492, 494, - 495, 495, 495, 495, 496, 497, 498, 498, 498, 499, 498, 500, 501, 501, 501, 501, - 501, 501, 502, 501, 501, 26, 503, 503, 503, 503, 504, 26, 505, 505, 505, 505, - 506, 137, 507, 26, 508, 508, 509, 508, 508, 508, 508, 508, 510, 26, 26, 26, - 511, 512, 513, 514, 513, 515, 516, 516, 516, 516, 516, 516, 516, 517, 516, 518, - 519, 520, 521, 522, 522, 523, 524, 525, 520, 526, 527, 528, 529, 530, 530, 26, - 531, 532, 531, 531, 531, 531, 533, 531, 534, 535, 533, 536, 537, 26, 26, 26, - 538, 538, 538, 538, 538, 538, 538, 539, 540, 26, 26, 26, 541, 541, 541, 541, - 541, 26, 541, 542, 543, 543, 543, 543, 543, 543, 544, 543, 543, 543, 543, 544, - 545, 545, 545, 545, 546, 26, 545, 547, 198, 548, 26, 26, 549, 549, 549, 549, - 549, 549, 549, 550, 549, 550, 164, 164, 551, 26, 26, 26, 552, 552, 552, 553, - 552, 554, 552, 552, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 557, - 558, 558, 558, 558, 558, 558, 559, 560, 561, 562, 563, 564, 564, 564, 565, 566, - 561, 26, 564, 567, 568, 569, 568, 568, 568, 568, 568, 569, 570, 26, 26, 26, - 571, 571, 571, 571, 571, 26, 572, 572, 572, 572, 572, 572, 573, 26, 178, 178, - 574, 574, 574, 574, 574, 574, 574, 575, 53, 576, 26, 26, 577, 577, 577, 577, - 578, 26, 577, 578, 579, 580, 579, 579, 579, 579, 581, 579, 582, 26, 579, 579, - 579, 583, 584, 584, 584, 584, 585, 584, 584, 586, 587, 26, 588, 589, 590, 590, - 590, 590, 588, 591, 590, 26, 590, 592, 593, 594, 595, 595, 595, 596, 597, 598, - 595, 599, 26, 26, 600, 600, 600, 601, 602, 602, 603, 602, 602, 602, 602, 604, - 602, 602, 602, 605, 26, 26, 606, 26, 108, 108, 108, 108, 108, 108, 607, 608, - 609, 609, 609, 609, 609, 609, 609, 610, 609, 611, 612, 26, 613, 26, 26, 26, - 26, 26, 614, 614, 614, 614, 614, 614, 614, 614, 615, 26, 616, 616, 616, 616, - 616, 616, 617, 26, 616, 616, 616, 618, 619, 619, 619, 619, 620, 26, 26, 26, - 621, 621, 621, 621, 621, 621, 621, 622, 305, 305, 305, 623, 624, 624, 624, 625, - 624, 626, 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, 627, 629, 630, 630, - 630, 631, 631, 26, 632, 632, 632, 632, 633, 26, 632, 634, 634, 632, 632, 635, - 632, 632, 26, 26, 636, 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, 638, - 638, 638, 638, 639, 640, 640, 640, 640, 640, 641, 640, 640, 640, 642, 640, 640, - 643, 26, 345, 26, 644, 644, 644, 644, 644, 644, 644, 26, 645, 645, 645, 645, - 645, 645, 646, 26, 26, 26, 26, 647, 644, 648, 26, 26, 26, 26, 649, 650, - 651, 286, 286, 286, 652, 26, 653, 26, 26, 26, 654, 26, 655, 26, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 657, 658, 658, 658, 658, 658, 659, 658, 660, - 658, 661, 658, 662, 359, 26, 26, 26, 0, 0, 0, 265, 0, 0, 359, 26, - 9, 663, 9, 9, 221, 26, 0, 0, 0, 0, 276, 26, 257, 362, 0, 0, - 664, 665, 0, 666, 667, 668, 0, 0, 0, 669, 0, 0, 246, 26, 26, 26, - 0, 0, 257, 26, 0, 0, 0, 259, 0, 0, 254, 0, 0, 0, 0, 254, - 670, 671, 0, 672, 673, 0, 0, 0, 269, 674, 254, 254, 0, 0, 0, 675, - 676, 677, 678, 0, 276, 0, 0, 0, 0, 268, 0, 0, 679, 679, 679, 679, - 679, 680, 26, 681, 682, 679, 26, 26, 2, 2, 2, 346, 683, 419, 26, 26, - 684, 270, 270, 685, 686, 687, 18, 18, 18, 688, 26, 26, 26, 689, 26, 26, - 690, 690, 690, 690, 690, 691, 690, 692, 690, 693, 26, 26, 26, 26, 694, 694, - 694, 695, 26, 26, 696, 696, 696, 696, 696, 696, 696, 697, 26, 26, 698, 698, - 698, 698, 698, 699, 26, 26, 700, 700, 700, 700, 700, 701, 172, 702, 170, 172, - 703, 703, 703, 703, 704, 703, 705, 26, 706, 706, 706, 706, 706, 707, 706, 708, - 26, 26, 362, 0, 0, 0, 376, 26, 709, 31, 31, 31, 710, 711, 712, 713, - 714, 715, 710, 716, 710, 712, 712, 717, 31, 718, 31, 719, 720, 718, 31, 719, - 26, 26, 721, 26, 0, 359, 0, 0, 0, 257, 362, 0, 362, 0, 362, 0, - 0, 276, 26, 26, 722, 0, 0, 0, 723, 26, 0, 0, 0, 0, 0, 359, - 0, 259, 265, 26, 276, 26, 26, 26, 0, 0, 0, 724, 0, 376, 0, 376, - 0, 0, 257, 725, 0, 359, 259, 26, 0, 26, 0, 265, 0, 26, 0, 0, - 0, 276, 0, 359, 265, 26, 26, 26, 0, 276, 0, 376, 0, 726, 0, 0, - 257, 722, 0, 727, 0, 265, 0, 259, 277, 277, 277, 280, 345, 26, 277, 277, - 728, 26, 277, 277, 277, 729, 277, 277, 277, 277, 26, 26, 730, 26, 26, 26, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976, - 1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082, - 1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161, - 1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269, - 1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, - 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, - 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191, - 1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025, - 1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0, - 1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252, - 1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271, - 1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120, - 1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339, - 1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241, - 1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348, - 1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197, - 1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, - 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364, - 1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0, - 1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458, - 1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503, - 1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0, - 1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, - 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0, - 1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571, - 1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573, - 1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, - 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, - 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617, - 1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628, - 1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, - 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638, - 1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644, - 1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, - 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653, - 1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0, - 1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0, - 1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, - 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0, - 1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0, - 1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, - 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, - 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170, - 1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185, - 1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213, - 1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224, - 1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249, - 1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259, - 1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393, - 1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295, - 1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, - 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345, - 1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, - 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198, - 1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401, - 1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410, - 1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, - 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719, - 1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735, - 1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755, - 1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774, - 1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783, - 1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, - 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812, - 1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28, - 1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724, - 1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760, - 1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817, - 1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12, - 1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14, - 1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, - 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17, - 1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18, - 1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 224, 224, 768, 424, 432, 440, 448, 776, 224, 224, 784, 792, 72, 800, 40, 808, + 48, 48, 48, 816, 824, 48, 48, 832, 840, 848, 856, 864, 872, 880, 48, 888, + 48, 48, 48, 896, 904, 40, 40, 40, 40, 912, 40, 96, 920, 928, 936, 456, + 64, 64, 64, 64, 64, 64, 64, 944, 952, 960, 968, 40, 976, 984, 48, 992, + 72, 72, 72, 40, 40, 40, 48, 48,1000, 48, 48, 48,1008, 48, 48, 48, + 48, 48, 48,1016, 72,1024, 40, 40,1032, 464, 64,1040,1048, 8,1056,1064, + 1072,1080, 8, 8,1088, 64,1096,1104, 8, 8, 8, 8, 8,1112,1120,1128, + 1136,1144, 8, 64,1152, 8, 8, 8, 8, 8, 472,1160, 232, 8,1168,1176, + 8,1184,1192,1200, 8,1208, 176, 8,1216,1224, 8, 8,1232, 64,1240, 64, + 480, 8, 8,1248,1256,1264,1272,1280,1288, 240, 128,1296,1304,1312, 144,1320, + 1328, 240, 128,1336,1344,1352, 304,1360,1368, 488, 128,1376,1384, 248, 144,1392, + 1400, 240, 128,1408,1416,1424, 144,1432,1440,1448,1456,1464,1472,1480, 304,1488, + 1496, 256, 128,1504,1512,1520, 144,1528,1536, 256, 128,1544,1552,1560, 144,1568, + 1576, 256, 8,1584,1592,1600, 144,1608,1616,1624, 8,1632,1640,1648, 304,1656, + 312, 8, 8,1664,1672,1680, 0, 0,1688, 8,1696,1704,1712,1720, 0, 0, + 1728,1736, 320,1744,1752, 8, 152,1760,1768,1776, 64,1784,1792,1800, 0, 0, + 8, 8,1808,1816, 496,1824,1832,1840,1848,1856, 72, 72,1864, 40, 40,1872, + 8, 8, 8, 8, 504,1880, 8, 8, 504, 8, 8,1888, 512, 520, 8, 8, + 8, 512, 8, 8, 8,1896,1904, 528, 8, 264, 72, 72, 72, 72, 72,1912, + 536, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8,1920, 8,1928,1936, 8, 8, 8, 8,1944,1952, + 8,1960, 8,1968, 8,1976,1984,1992, 8, 8, 8,2000,2008,2016, 80,2024, + 2032, 80, 8, 8,2040, 8, 8, 160,2048, 8,2056, 8, 8, 8, 8, 328, + 8, 120,2064,2072,2080, 8, 112,2088, 8, 8, 184, 8, 192,2096, 24, 24, + 8,2104, 8, 8, 8,2112,2120,2128, 80, 80,2136,2144, 64, 544,2152, 0, + 2160, 8, 8,2168,2176, 496,2184,2192, 336, 8,2200, 232, 8, 8,2208,2216, + 8, 8,2224,2232,2240, 232, 8, 552,2248, 72, 72,2256,2264,2272,2280,2288, + 40, 40,2296, 96, 96, 96,2304,2312, 40,2320, 96, 96, 64, 64, 64, 64, + 48, 48, 48, 48, 48, 48, 48, 48, 48,2328, 48, 48, 48, 48, 48, 48, + 168, 560, 168, 168, 560,2336, 168,2344, 344, 344, 344,2352,2360,2368,2376,2384, + 2392,2400,2408,2416,2424,2432,2440,2448,2456,2464, 568, 568,2472,2480,2488,2496, + 2504,2512,2520,2528,2536, 88, 104, 104,2544,2552,2560, 24,2568,2576, 24,2584, + 2592, 24,2600, 24, 24, 24, 24,2608, 24,2616, 56,2624, 24,2632,2640, 24, + 24, 24, 264, 0, 576, 0, 88, 88, 88,2648, 24, 24, 24, 24,2656, 88, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,2664,2672, 24, 24,2680, + 24, 24, 24, 24, 24, 24,2688, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24,2696,2704, 88,2712, 24, 24,2720, 56,2728, 56, + 56, 56, 56, 56, 56, 56, 56, 56,2736,2744, 56, 56, 56,2752, 56,2760, + 24, 24, 24, 56,2768, 24, 24,2776, 24, 24, 24, 24, 24, 24, 24, 24, + 72, 72, 72, 40, 40, 40,2784,2792, 48, 48, 48, 48, 48, 48,2800,2808, + 40, 40,2816, 8, 8, 8,2824,2832, 8, 200, 208, 208, 208, 208, 64, 64, + 2840,2848,2856,2864,2872,2880, 0, 0, 24,2888, 24, 24, 24, 24, 24, 352, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 272, 0, 24, + 2896,2904,2912,2920, 312, 8, 8, 8, 8,2928, 536, 8, 8, 8, 8,2936, + 2944, 8, 8, 312, 8, 8, 8, 8, 120,2952, 8, 8, 24, 24,2960, 8, + 24, 584, 592, 24,2968, 600, 24, 24, 592, 24, 24, 600, 24, 24, 24, 24, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 24, 24, 24, 24, + 8,2976, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 152, 24, 24, 24, 608, 8, 8, 552, + 2984, 8,2992, 0, 48, 48,3000,3008, 48,3016, 8, 8, 8, 8,3024,3032, + 456,3040,3048,3056, 48, 48, 48,3064,3072,3080,3088,3096,3104,3112, 0,3120, + 3128, 8,3136,3144, 8, 8, 8,3152,3160, 8, 8,3168,3176, 80, 64,3184, + 232, 8,3192, 8,3200,3208, 8, 152, 480, 8, 8,3216,3224, 360,3232,3240, + 8, 8,3248,3256,3264,3272, 8,3280, 8, 8, 8,3288,3296,3304,3312,3320, + 3328,3336, 208, 40, 40,3344,3352, 40, 40, 40, 40, 40, 8, 8,3360, 80, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 368, 8,3368, 8, 8, 184, + 8, 8, 8, 8, 8, 8, 112, 8, 8, 8, 8, 8, 8, 192, 0, 0, + 3376,3384,3392,3400,3408, 8, 8, 8, 8, 8, 8,3416,3424,3432, 8, 8, + 8, 8, 8,3440, 24, 8, 8, 8, 8,3448, 8, 8,3456, 0, 0,3464, + 64,3472, 64,3480,3488,3496,3504,3512, 8, 8, 8, 8, 8, 8, 8,3520, + 3528, 424, 432, 440, 448,3536,3544,3552, 8,3560, 8, 120,3568,3576,3584,3592, + 3600, 8, 520,3608, 112, 112, 0, 0, 8, 8, 8, 8, 8, 8, 8, 176, + 3616, 88, 88,3624, 104, 104, 104,3632,3640, 280, 376, 0, 0, 24, 24,3648, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 152, 8, 8, 8, 248,3656,3664, + 8, 8,3672, 8,3680, 8, 8,3688, 8,3696, 8, 8,3704,3712, 0, 0, + 72, 72,3720, 40, 40, 8, 8, 8, 8, 112, 80, 72, 72,3728, 40,3736, + 8, 8, 616, 8, 8, 8,3744, 624, 624,3752,3760,3768, 8, 8, 8, 368, + 8, 8, 8, 200, 8, 328, 616, 0,3776, 96, 96,3784, 0, 0, 0, 0, + 3792, 8, 8,3800, 8,3808, 8,3816, 8, 120,3824, 0, 0, 0, 8,3832, + 8,3840, 8,3848, 8, 192, 0, 0, 8, 8, 8,3856, 88, 632, 88, 88, + 3864,3872, 8,3880, 640,3888, 8,3896, 8, 648, 0, 0,3904, 8,3912,3920, + 8, 8, 8,3928, 8,3936, 8,3944, 8,3952,3960, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 160, 0, 0, 0, 72, 72, 72,3968, 40, 40, 40,3976, + 8, 8,3984, 80,3992, 72,4000, 40,4008, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 88,4016, 8, 8,4024, 656,4032,4040, 0,4048, + 8, 648,4056, 8, 472,4064, 0, 8,4072, 0, 0, 8,4080, 0, 8, 200, + 4088, 8, 8,4096,4104, 632,4112,4120, 336, 8, 8,4128,4136, 8, 160, 80, + 4144, 8,4152,4160,4168, 8, 8,4176, 336, 8, 8,4184,4192,4200, 384,4208, + 8, 488, 664,4216,4224, 0, 0, 0,4232,4240,4248, 8, 8,4256,4264, 80, + 4272, 240, 128,4280,4288,4296,4304,4312,4320, 8, 8,4328,4336,4344,4352, 0, + 8, 8, 8,4360,4368,4376, 656, 0, 8, 8, 8,4384,4392, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 672,4400,4408,4416, 0, 0, + 8, 8, 8,4424,4432, 80,4440, 0, 8, 8,4448,4456, 80, 288,4464, 0, + 8,4472,4480,4488, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 664,4496, 0, 0, 0, 0, 0, 0, 72, 72, 40, 40, 320,4504, + 4512,4520, 8,4528,4536, 80, 0, 0, 0, 0,4544, 8, 8,4552,4560, 0, + 4568, 8, 8,4576,4584,4592, 8, 8,4600,4608,4616, 8, 8, 8, 8, 160, + 4624, 0, 0, 0, 0, 0,4632, 0, 0, 0, 0, 0, 8, 8,4640, 80, + 128, 8, 672,4648,4656, 320, 528,4664, 8,4672,4680,4688, 0, 0, 0, 0, + 4696, 8, 8,4704,4712, 80,4720, 8,4728,4736, 80, 8, 8,4744, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,4752, + 4760, 256, 8,4768,4776,4784, 0, 0, 0, 0, 0, 248, 88,4792,4800,4808, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 192, 0, 0, 0, 0, 0, 0, + 104, 104, 104, 104, 104, 104,4816,4824, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8,4832, + 8, 8, 8, 136,4840,4848, 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, 176, + 8, 8, 8, 8, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 680,4856, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 160, 8, 120, 360, 8, 8, 8, 8, 120, 80, 8, 112,4864, + 8, 8, 8,4872,4880,4888,4896,4904, 8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,4912, 8,4920, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 72, 72, 40, 40, 88,4928, 72,4936, 40,4944, 0, 0, + 8, 8, 8, 8,4952,4960, 688, 688,4968,4976, 0, 0, 0, 0,4984,4992, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 328, 0,5000, + 8, 120, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 696, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,5008, + 8, 8, 696,5016, 0,5024,5032, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 184, + 8, 8, 8, 8, 8, 8, 176, 152, 160,5040,5048, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5056, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5064, 24, 376, 24,5072, + 64, 64, 544, 64, 704, 24, 24, 24, 24, 24, 24, 24, 352, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 272, + 24, 24,5080, 24, 24, 24,5088,5096,5104, 24,5112, 24, 24, 24, 576, 0, + 24, 24, 24, 24,5120, 0, 0, 0, 0, 0, 0, 0, 88, 712, 88, 712, + 24, 24, 24, 24, 24, 608, 88, 640, 0, 0, 0, 0, 0, 0, 0, 0, + 72, 296, 40, 720, 728,5128, 168, 72, 392,5136,5144,5152,5160, 72, 296, 40, + 5168,5176, 40,5184,5192,5200, 736, 72, 744, 40, 72, 296, 40, 720, 728, 40, + 168, 72, 392, 736, 72, 744, 40, 72, 296, 40,5208, 72,5216,5224,5232,5240, + 40,5248, 72,5256,5264,5272,5280, 40,5288, 72,5296, 40,5304, 288, 288, 288, + 64, 64, 64,5312, 64, 64,5320,5328,5336,5344, 464, 0, 0, 0, 0, 0, + 5352,5360,5368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5376,5384,5392, 96, 96, 96,5400, 0,5408, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 152,5416,5424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,5432, 0, 8, 8,5440,5448, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,5456, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 680,5464, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120,5472,5480, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,5488, 120, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,5496, 704, 0, 0, + 72, 72, 392, 40,5504, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 384, 88, 88,5512,5520, 0, 0, 0, 0, + 384, 88,5528,5536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5544, 8,5552,5560,5568,5576,5584,5592,5600, 184,5608, 184, 0, 0, 0,5616, + 24, 24, 216, 24, 24, 24, 24, 24, 24, 352, 584, 400, 400, 400, 24, 272, + 5624, 24, 24, 24, 24, 24, 24, 24, 24, 24, 408, 0, 0, 0,5632, 24, + 5640, 24, 24, 216, 752, 760, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5648, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,5656, 280, 280, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 264, 216, 376, + 216, 24, 24, 24, 416, 264, 24, 24, 416, 24, 408, 216, 760,5664, 0, 0, + 24, 24, 24, 24, 24, 416, 408, 280,5672, 24, 24, 24,5680,5688,5696, 752, + 24, 24, 24, 24, 24, 24, 24, 24, 24,5704, 24, 24, 24, 24, 24,5712, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, + 8, 112, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 112, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 248, 8, + 8, 8, 8, 8, 8, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 176, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 192, 0, 0, 0, 0, 0, 0, 0, 0, + 5720, 0, 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,5728, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, + 20, 20, 20, 20, 20, 20, 20, 20, 12, 12, 12, 12, 12, 12, 12, 12, + 24, 24, 24, 24, 24, 24, 24, 24, 28, 28, 28, 28, 28, 28, 28, 28, + 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 48, 48, 48, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, + 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 36, + 64, 64, 64, 64, 64, 64, 64, 64, 92, 92, 92, 92, 92, 92, 92, 92, + 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, + 68, 68, 68, 68, 68, 68, 68, 68, 56, 56, 56, 56, 56, 56, 56, 56, + 12, 12, 12, 12, 228, 232, 228, 232, 12, 12, 468, 468, 32, 472, 32, 472, + 32, 32, 32, 692, 12, 12, 696, 12, 56, 56, 56, 56, 56, 56, 56, 700, + 704, 72, 708, 72, 72, 72, 712, 72, 60, 60, 60, 60, 60, 60, 60, 60, + 716, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 720, 308, 724, 308, 308, + 728, 732, 236, 236, 736, 236, 740, 744, 748, 752, 36, 36, 756, 760, 36, 764, + 36, 36, 36, 36, 36, 768, 36, 36, 772, 312, 312, 312, 776, 36, 36, 36, + 316, 316, 316, 780, 320, 320, 320, 784, 476, 476, 788, 792, 796, 800, 804, 36, + 36, 808, 36, 36, 36, 36, 812, 36, 112, 112, 112, 112, 112, 816, 820, 112, + 824, 828, 832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, + 888, 892, 896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, + 952, 956, 960, 964, 968, 972, 976, 980, 984, 988, 992, 996,1000,1004,1008,1012, + 1016,1020,1024,1028,1032,1036,1040,1044,1048,1052, 324, 324,1056,1060,1064, 324, + 1068,1072,1076,1080,1084,1088,1092,1096,1100, 328, 328,1104, 328,1108, 0, 0, + 1112,1116,1120,1124,1128,1132, 0, 0, 128, 128, 128, 128, 480, 128,1136,1140, + 128, 480, 128, 484, 484,1144, 0, 0, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 116, 116, 488, 116, 116,1148, 88, 88, 88, 88, 492,1152, 88, 88, + 492, 88, 88,1156, 496,1160, 88, 88, 88, 496, 88, 88, 88,1164, 88,1168, + 88,1172, 108, 108, 108, 108, 108,1176,1180,1184, 240, 240, 240, 240,1188,1192, + 1196,1200,1204,1208,1212,1216,1220,1224, 132, 132, 132, 132, 132,1228, 500, 500, + 1232,1236, 136, 136, 136, 136, 136,1240, 136, 136,1244, 40, 40, 40, 40,1248, + 1252,1256, 504, 504,1260,1264,1268,1272, 332, 332,1276, 332,1280,1284, 132, 132, + 1288,1292, 244, 244, 244,1296, 244,1300, 508, 508,1304, 56, 56, 512,1308, 0, + 140, 140, 140, 140,1312, 140, 140, 140, 248, 248, 248, 248, 336, 336, 336,1316, + 340, 340, 340,1320,1324, 344, 344, 344,1328, 116, 116,1332,1336,1340,1344,1348, + 32, 32,1352, 32, 32,1356,1360,1364, 32, 32, 32,1368, 56, 56, 56, 56, + 72, 516, 72, 72, 516,1372, 72,1376, 72, 72, 72, 520, 520,1380, 72,1384, + 1388, 12, 12, 12, 12, 12, 524,1392, 528, 532, 12, 12, 348, 56, 56,1396, + 12, 12,1400,1404,1408, 12, 32, 32,1412, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 176, 0, 352, 0, 12, 12, 12, 12, 12, 12, 12, 12, 12,1416, + 148, 148, 148, 148, 148, 148, 32, 32, 144, 144, 144, 144, 144, 144, 144,1420, + 116, 116, 488, 356, 356, 356,1424,1428, 88,1432, 180, 180, 180, 180, 60, 60, + 12, 12, 12, 12, 12, 184, 0, 0, 4,1436, 4, 4, 4, 4, 4,1440, + 4, 4, 4, 4, 4,1444, 0, 12,1448, 12,1452,1456,1460, 76, 76, 76, + 76,1464, 536, 100, 100, 100, 100,1468,1472, 252, 252,1476, 8, 8, 8, 8, + 360, 12, 252, 252, 12, 12,1480, 100, 8, 360, 12, 12, 12, 12, 8,1484, + 12, 12, 12, 12, 12, 100, 100,1488, 100, 100, 100, 100, 100,1492, 12, 12, + 4, 4, 4, 4, 12, 12, 12, 12,1496, 24, 24, 24,1500, 364, 364, 364, + 84, 84,1504, 0, 60, 60, 60, 60, 60, 60, 44, 44, 44, 44, 44,1508, + 12, 12,1512, 32, 32, 32, 32, 32,1516, 32, 32, 32, 32, 532, 0,1520, + 540, 540,1524, 176, 368, 368, 368,1528, 256, 256, 256, 256,1532,1536, 112, 112, + 544, 544,1540, 548, 548,1544, 8,1548, 260, 260, 260, 260,1552,1556, 96,1560, + 372, 372, 372,1564,1568,1572, 96, 96, 264, 264, 264, 264,1576,1580, 376,1584, + 1588,1592, 180, 32, 32,1596,1600, 108, 108, 108, 108, 108, 376, 376,1604,1608, + 8, 8,1612, 8,1616, 8, 8,1620, 4, 4, 4, 4, 4, 4, 188, 4, + 4, 4, 4, 4, 4, 552, 0, 0,1624,1628, 236,1632,1636, 36, 36, 36, + 36, 36, 36,1640, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 0, 36, + 56, 176,1644, 12, 12, 556,1648,1652, 36, 36, 36, 36, 36, 36, 36,1656, + 152, 12, 228, 232, 228, 232,1660, 536, 100,1664, 8, 360,1668,1672,1676,1680, + 1684, 120,1688,1692, 560, 560, 0, 0, 120, 120, 120, 120, 120, 120, 120,1696, + 1700, 12, 12,1704, 72, 72, 72, 72,1708, 192,1712, 0, 0, 12, 12,1716, + 1720,1724, 380, 380, 380,1728,1732, 156, 564, 564,1736,1740,1744, 568, 568,1748, + 1752,1756, 572, 572,1760,1764, 0, 0, 196, 196, 196, 196, 196, 384, 384, 384, + 1768,1772,1776, 388, 388,1780, 388,1784, 576, 576,1788, 392, 392, 392,1792, 580, + 580,1796,1800,1804, 396, 396, 396,1808, 80, 80, 80,1812, 80,1816,1820, 0, + 1824, 32, 32,1828, 0, 0, 0, 0,1832, 584, 584,1836,1840,1844, 588, 588, + 1848,1852,1856, 0, 0, 0,1860,1864,1868,1872,1876,1880,1884,1888, 0, 0, + 592, 592, 268,1892, 268,1896, 268, 268,1900,1904,1908,1912, 596, 596, 600, 600, + 604, 604, 0, 0, 608, 608,1916,1920, 400, 400, 400,1924,1928,1932,1936,1940, + 1944,1948,1952, 0, 0, 0, 0, 0, 272, 272, 272, 272,1956, 0, 0, 0, + 160, 160, 160,1960, 160, 160, 160,1964, 612, 612,1968,1972, 404, 404,1976, 404, + 1980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,1984, + 616, 616,1988,1992,1996,2000, 0,2004, 620, 620,2008, 624, 624,2012, 0,2016, + 2020, 0, 0,2024,2028, 0,2032,2036, 200, 200, 200, 200,2040,2044, 200,2048, + 276, 276, 276, 276,2052,2056,2060,2064, 408, 408, 408,2068,2072, 628, 628,2076, + 164, 164, 164, 164, 164, 164,2080,2084, 412,2088, 412, 412,2092, 0, 0, 0, + 2096,2100,2104, 416, 416, 416,2108,2112,2116,2120,2124,2128,2132,2136,2140,2144, + 2148, 632, 632,2152,2156,2160,2164, 0, 204, 204, 204, 204, 204,2168,2172, 0, + 280, 280, 280, 280,2176,2180, 0, 0, 284, 284, 284,2184, 284,2188, 0, 0, + 288, 288, 288, 288,2192,2196,2200, 0, 420, 420, 420, 636, 636, 96,2204, 0, + 640,2208,2212, 640,2216, 0, 0, 0, 424, 424, 424,2220, 0, 0, 0, 0, + 0, 0, 208, 208, 208, 208, 208,2224,2228,2232,2236,2240,2244,2248, 0, 0, + 0, 0, 644, 648, 648, 644,2252, 0, 292, 292, 292, 292,2256, 212, 212, 212, + 212, 212,2260, 40, 428, 428, 428,2264,2268, 0, 0, 0, 0, 0,2272, 0, + 0, 0, 0, 0, 652, 652,2276,2280,2284, 432, 432,2288,2292, 432,2296, 656, + 656,2300,2304,2308, 0, 0, 0, 0,2312, 660, 660,2316,2320,2324,2328,2332, + 2336,2340,2344, 664, 664,2348,2352, 0, 0, 0, 0, 0, 0, 0,2356,2360, + 436,2364, 436,2368, 436,2372, 0, 0, 0, 0, 0,2376, 440, 440, 440,2380, + 28,2384, 0, 0, 0, 0, 0, 0, 28, 28, 28, 28, 28, 28,2388,2392, + 28, 28, 28, 28,2396, 0, 0, 0, 0, 168, 168, 168, 168, 168, 168,2400, + 20, 20, 20, 20, 20,2404, 20, 20, 20, 20, 20, 20, 20, 20, 20,2408, + 52, 52, 52, 52,2412, 0, 0, 0, 444, 444, 444,2416, 0, 0, 0, 0, + 44, 44, 44,2420,2424,2428,2432, 296, 296, 296, 296,2436,2440,2444,2448,2452, + 216, 216, 216, 216,2456,2460,2464,2468, 216, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 448, 448, 448,2472, 0, 0, 0, 0, 220, 220, 220, 220, + 220,2476, 668,2480, 668,2484, 0, 0, 124, 124, 124, 124,2488, 124, 124, 124, + 2492, 124, 0, 0, 0, 0,2496,2500, 64, 64, 64, 64, 64,2504, 0,2508, + 16,2512, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16,2516, + 0, 0, 0, 0, 0, 0, 0,2520,2524, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,2528,2532, 0,2536,2540, 68, + 68, 68, 68, 68, 68, 68, 68,2544, 172, 172, 172, 172, 172, 172,2548,2552, + 2556,2560, 224, 0, 0, 0, 0, 0, 12, 12, 12, 12, 12, 12, 12, 192, + 12, 12, 12,2564, 12, 452, 12, 452, 56, 56, 512, 56,2568, 12, 12, 12, + 12, 12, 12, 12, 224, 0, 0, 0, 12, 12, 12, 12, 12, 12, 12, 456, + 12, 12,2572, 12, 12, 12,2576,2580,2584, 12,2588, 12, 12, 12, 352, 0, + 72, 72, 72, 72,2592, 0, 0, 0, 0, 0, 0, 0, 12, 224, 12, 224, + 12, 12, 12, 12, 12,2596, 12, 300, 12, 12, 12, 12, 12, 524, 12, 12, + 12,2600,2604,2608,2612, 12, 12, 12,2616,2620, 12,2624,2628,2632, 12, 12, + 12, 12,2636, 12, 12, 12, 12, 12, 12, 12, 12, 12,2640, 12, 12, 12, + 2644,2648,2652, 0, 0, 0, 0, 0, 32,2656,2660, 0, 0, 0, 0, 0, + 2664,2668,2672, 60, 60, 60,2676, 0,2680, 0, 0, 0, 0, 0, 0, 0, + 672, 672,2684,2688,2692, 0, 0, 0, 0,2696,2700, 0, 460, 460, 460,2704, + 0, 0, 0, 0, 0, 676, 676,2708, 0, 0, 0, 0, 0, 680, 680,2712, + 0, 0, 0, 0, 684,2716, 684,2720, 0, 0, 0, 0, 0, 0,2724,2728, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,2732,2736, 0, 0, + 304, 304, 304, 304,2740,2744, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, + 12, 12, 12,2748, 0, 0, 0, 0, 152, 12, 12, 184, 0, 0, 0, 0, + 2752, 36,2756,2760,2764,2768,2772,2776,2780, 688,2784, 688, 0, 0, 0,2788, + 12, 12, 156, 12, 12, 12, 12, 12, 12, 224, 528, 152, 152, 152, 12, 456, + 12, 12, 184, 0, 0, 0,2792, 12,2796, 12, 12, 156, 300, 348, 456, 0, + 12, 12, 12, 12, 12,2800, 192, 192, 12, 12, 12, 12, 12, 176, 156, 452, + 156, 12, 12, 12, 464, 176, 12, 12, 464, 12, 184, 156, 348, 300, 0, 0, + 12, 12, 12, 12, 12, 464, 184, 192,2804, 12, 12, 12,2808,2812,2816, 300, + 12, 556, 12, 12, 12, 12, 12, 352, 4, 4, 4, 4, 4, 4, 0, 0, + 4, 188, 4, 4, 4, 4, 4, 4, 4, 4, 188, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4,2820, 4, 4, 4, 4, 4, 4, 188, 0, 0, + 4, 188, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4,2824, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 552,2828, 0, 12, 12, 12, 12, 12, 12, + 0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12, + 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, 32, 32, 32, 32, + 24, 24, 24, 24, 28, 28, 28, 28, 40, 40, 40, 40, 48, 48, 48, 48, + 44, 44, 44, 44, 56, 56, 56, 56, 52, 52, 52, 52, 60, 60, 60, 60, + 64, 64, 64, 64, 76, 76, 76, 76, 68, 68, 68, 68, 80, 80, 80, 80, + 84, 84, 84, 84, 88, 88, 88, 88, 72, 72, 72, 72, 96, 96, 96, 96, + 100, 100, 100, 100, 92, 92, 92, 92, 104, 104, 104, 104, 116, 116, 116, 116, + 120, 120, 120, 120, 124, 124, 124, 124, 108, 108, 108, 108, 132, 132, 132, 132, + 112, 112, 112, 112, 136, 136, 136, 136, 128, 128, 128, 128, 148, 148, 148, 148, + 144, 144, 144, 144, 152, 152, 152, 152, 452, 12, 12, 12, 12, 12, 12, 0, + 180, 180, 180, 180, 176, 176, 176, 176, 184, 184, 184, 184, 140, 140, 140, 140, + 12, 12, 264, 0, 72, 232, 72, 232, 12, 12, 12, 264, 4, 4, 4, 600, + 12, 12, 12, 364, 240, 240, 240, 240, 168, 168, 168, 168, 188, 188, 188, 188, + 248, 248, 248, 248, 252, 252, 252, 252, 160, 160, 160, 160, 204, 204, 204, 204, + 12, 0, 0, 0, 764, 24, 24, 24, 24, 24, 628, 12, 164, 164, 164, 164, + 236, 236, 236, 236, 156, 156, 156, 156, 292, 292, 292, 292, 300, 300, 300, 300, + 268, 268, 268, 268, 208, 208, 208, 208, 324, 324, 324, 324, 192, 192, 192, 192, + 312, 312, 312, 312, 344, 344, 344, 344, 244, 244, 244, 244, 196, 196, 196, 196, + 276, 276, 276, 276, 316, 316, 316, 316, 212, 212, 212, 212, 12, 12, 364, 0, + 216, 216, 216, 216, 220, 220, 220, 220, 256, 256, 256, 256, 476, 476, 476, 476, + 396, 396, 396, 396, 172, 172, 172, 172, 228, 228, 228, 228, 260, 260, 260, 260, + 408, 408, 408, 408, 320, 320, 320, 320, 480, 480, 480, 480, 264, 0, 0, 0, + 12, 12, 296, 0, 412, 412, 412, 412, 8, 8, 8, 812, 484, 484, 484, 484, + 416, 416, 416, 416, 272, 272, 272, 272, 304, 304, 304, 304, 488, 488, 488, 488, + 496, 496, 496, 496, 308, 308, 308, 308, 456, 456, 456, 456, 460, 460, 460, 460, + 420, 420, 420, 420, 368, 368, 368, 368, 328, 328, 328, 328, 372, 372, 372, 372, + 348, 348, 348, 348, 352, 352, 352, 352, 380, 380, 380, 380, 432, 432, 432, 432, + 200, 200, 200, 200, 280, 280, 280, 280, 284, 284, 284, 284, 436, 436, 436, 436, + 440, 440, 440, 440, 364, 0, 0, 0, 12, 264, 0, 0, 444, 444, 444, 444, + 12, 12, 0, 0, 12, 12, 768, 12, 24, 628, 24, 24, 400, 400, 400, 400, + 112, 112, 892, 112, 112, 112, 112,1048, 124,1052, 0,1056, 72, 72, 684, 636, + 684, 636, 72, 72, 136, 136, 900, 0, 340, 340, 340, 0, 156, 156, 904, 0, + 52, 52, 52,1072, 68, 688, 68, 688, 68, 772, 68, 68, 12, 648, 12, 12, + 12, 12, 12, 296, 24, 24, 24,1092, 916, 92, 92, 92, 520, 520, 520, 520, + 524, 524, 524, 524, 572, 572, 572, 572, 4, 4, 600, 0, 296, 12, 12, 12, + 108, 108, 108,1132, 576, 576, 576, 576, 536, 536, 536, 536, 492, 492, 492, 492, + 540, 540, 540, 540, 500, 500, 924, 500, 528, 528, 528, 528, 604, 604, 604, 604, + 608, 608, 608, 608, 464, 464,1144, 0, 612, 612, 612, 612, 616, 616, 616, 616, + 532, 532, 532, 532, 504, 504, 504, 504, 544, 544, 544, 544, 548, 548, 548, 548, + 552, 552, 552, 552, 588, 588, 588, 588, 376, 376, 376, 376, 352, 352,1188, 0, + 424, 424, 424, 424, 384, 384,1200, 384, 384, 384, 384, 384, 556, 556, 556, 556, + 388, 388, 388, 388, 392, 392, 392, 392, 472, 472, 472, 472, 512, 512, 512, 512, + 356, 356, 356, 356, 560, 560, 560, 560, 564, 564, 564, 564, 516, 516, 516, 516, + 28, 28, 28, 0, 24, 24, 840, 12, 24, 840,1264, 12, 68,1268, 844,1272, + 0,1276, 848, 772,1280, 68, 68, 68,1284, 144, 144, 144, 60,1288, 60, 60, + 852, 220, 220, 220, 220, 952, 852, 220, 220, 220, 952, 852, 956, 164, 164, 164, + 164, 164, 0, 0, 164, 164, 960,1292, 164,1296, 0, 0, 28, 964, 28, 968, + 28, 28, 972, 972, 968, 28,1300, 52, 52,1304, 28, 28,1308, 28, 28, 28, + 28, 28, 28, 964, 256, 256, 256,1312, 256, 256, 976,1316,1320, 0, 0, 0, + 396, 396,1324,1328, 400, 400, 400,1332, 400, 400, 400,1336, 632, 632, 632, 632, + 632, 632, 632,1340, 256, 256, 976, 0, 980, 984, 28, 28,1344, 28, 28, 28, + 1348,1352, 120, 120, 120,1356, 120, 120, 332,1360, 332, 776, 776, 332, 332, 332, + 332, 332,1364, 332,1368, 988,1372, 332, 332, 776, 776, 992, 0,1376, 0,1380, + 332, 988, 332, 332, 332, 332, 332, 992, 856, 856, 860, 996,1000, 568, 568, 568, + 568, 568, 864, 568, 864,1384,1004, 864, 860, 996,1000,1004,1388, 0, 856,1392, + 0,1396, 568, 568, 568, 860, 0, 0, 780, 780, 448, 784, 784, 448, 448, 448, + 448, 448,1008, 448,1008, 780, 868, 448, 448, 784, 784, 868,1400, 0, 0, 0, + 448,1404, 448, 448, 868, 0, 780, 448, 788, 788, 404, 792, 792, 404, 404, 404, + 404, 404,1012, 404,1012, 788,1016, 404, 404, 792, 792,1016, 0, 788, 0,1408, + 404,1412, 404, 404, 404, 404, 0, 0, 680,1416, 796, 680, 872, 800,1420, 872, + 876,1020, 796, 680, 284, 284, 800, 680, 796, 680, 872, 800,1020, 876, 0, 0, + 0, 680, 284, 284, 284, 284, 796, 0, 288, 288, 288, 728, 728, 288, 288, 288, + 288, 288, 728, 288, 288, 288, 880, 288, 288, 728, 728, 880, 0,1424,1428, 880, + 288,1432, 288, 288, 0,1436, 288, 288, 360, 360, 360, 732, 732, 360, 360, 360, + 360, 360, 732, 360, 360,1024,1028, 360, 360, 732, 732,1028, 0,1440, 0,1444, + 360,1448, 360, 360,1024, 0, 0, 0, 172, 172, 172, 804, 804, 172, 172, 172, + 172, 804, 804, 172, 0, 172, 172, 172, 172,1452, 172, 172, 884, 884, 224, 224, + 224,1032, 888, 224, 224, 224, 224, 224,1456, 224, 224,1460, 224,1032,1464,1468, + 224,1472, 224, 224, 0, 888, 224, 224, 888,1036, 0, 0,1476, 228, 228, 228, + 228, 228,1480, 736, 228, 228, 228, 0,1484,1488,1040, 336, 336, 336, 336, 336, + 336,1492, 336, 336, 336, 336, 336,1044, 336,1496, 336,1040, 336, 336,1044, 336, + 112, 112, 112,1500, 892, 112, 112, 112, 112,1504,1508, 0, 124, 124,1512, 124, + 72, 232, 684, 636, 684, 636, 72, 232, 72, 232, 72, 72, 72, 72, 232, 808, + 72, 72, 72,1516, 72, 72, 636, 0, 116,1060, 116,1060, 640, 640, 640, 640, + 640, 640, 640,1520, 236, 236,1524,1528, 236, 236,1532, 0, 740, 740, 740, 740, + 740,1536, 0,1540, 744, 744, 744, 744, 744,1544, 0, 0, 748, 748, 748, 748, + 748, 0, 0, 0, 896, 896, 896,1064,1064, 0, 0, 0, 136, 136, 136, 900, + 1548,1552, 128, 128, 128, 128,1556, 0, 128, 128,1068, 0, 128, 128,1560, 0, + 40,1564, 0, 0, 340, 340, 340, 340, 340, 340, 340,1568,1572, 340, 340, 340, + 596, 596, 596, 596, 596, 596, 596,1576, 596,1580, 0, 0, 260, 260, 260, 0, + 260, 260,1584, 0, 260, 260,1588,1592, 644, 644, 644, 644, 644, 644, 644,1596, + 156, 156, 156,1600, 156, 156, 156,1604, 156, 156, 156, 904, 52, 52, 52, 0, + 148, 148, 148,1608, 408, 0, 0, 408, 320, 320,1612, 320, 320, 320,1616,1620, + 60, 60,1624, 0, 124, 124,1628,1632, 292, 292, 0, 0,1076, 52, 52, 52, + 1636, 52, 908,1640, 12, 908,1644, 0, 24,1080,1648, 24, 24, 24, 24,1652, + 1656,1080,1660, 24, 24, 24,1664, 24, 24, 24, 24,1668, 68, 68,1084,1084, + 68, 68, 68, 688, 68, 844, 68,1672, 844, 772, 68, 848, 12, 12, 12, 912, + 1676, 12, 12,1088,1680, 0, 0, 0, 12,1684,1096, 12, 768, 12, 12, 12, + 12, 12, 12, 768, 24, 24, 840, 0, 12, 692, 12, 12, 144, 0,1688, 144, + 412, 412, 0,1100,1692, 0, 0,1100, 72, 232, 0, 0, 4, 4,1696, 4, + 4, 0, 0, 0, 4, 600, 0, 0, 12,1700, 12, 12,1704, 4,1708,1712, + 12, 12, 4, 12,1716, 80, 80, 80, 80,1104,1720,1724, 92, 92,1108, 916, + 0,1728, 300, 300,1732, 8, 8, 8, 12, 264, 0, 736, 8, 8, 8,1736, + 92, 92, 92,1108, 92, 92, 12, 12, 36, 36, 36,1740, 36,1744, 0, 0, + 88, 88, 88, 0, 48, 48, 0, 0,1096, 24, 24, 24, 24, 24,1088, 24, + 1112, 24, 24, 24, 520, 520, 520,1748, 416, 416, 0, 0, 268,1116, 0,1752, + 268, 268,1116, 0, 524, 524, 524,1756, 572, 0, 0,1760, 8, 8, 8,1120, + 208, 208, 208,1764, 208, 208,1768,1772, 100, 100, 100,1776, 272,1780, 0, 0, + 272, 272, 272,1124, 272, 272,1124, 272,1784, 0, 0, 0, 0, 0,1788, 324, + 304,1792, 0, 0, 808, 232, 808, 232, 808, 232, 0, 0, 24, 24, 628, 24, + 24,1796,1800, 0, 304, 304, 304,1128, 304, 304,1128, 0, 8, 0, 0, 0, + 8, 812,1804, 8, 8, 8, 8, 0, 24, 816, 0, 0,1808, 220, 0, 956, + 164, 960, 164,1812,1816,1820, 164, 164, 28, 28, 28,1824, 52, 52, 52,1828, + 12, 296, 12, 0, 28,1832, 28, 28, 28, 28, 28,1836, 12,1840, 92, 92, + 92, 92, 92,1844, 820, 8, 820, 8, 820, 8, 820,1120, 12, 296, 12, 296, + 0, 0, 452, 264, 108, 108, 108,1848, 108, 920, 108, 108, 108, 108, 920,1852, + 108, 108, 920, 0, 296, 736, 12, 12, 12, 736, 12, 12, 68, 68, 68, 848, + 1856, 0, 0, 0, 12, 12, 12,1860, 652, 652, 652, 652, 652, 652, 652,1864, + 1868, 0, 0, 0, 908, 12, 12, 12, 576, 0, 0,1872, 696, 696, 696, 696, + 696, 696,1876, 0, 536, 536,1880, 0, 656, 656, 656, 656, 656, 656, 656,1884, + 492, 0, 492, 492, 492,1888, 0, 0, 580, 580, 580, 580, 580, 580, 580,1136, + 580, 580,1136, 0, 308, 0, 308, 308, 308, 308, 308, 0, 540, 540, 0, 0, + 456, 0, 0,1892, 924, 824, 500, 500, 824, 500, 500, 500, 824, 500, 824,1896, + 460, 0, 0, 0, 84,1900, 0, 0, 84,1904, 0, 0, 84, 84, 0, 0, + 24,1908, 24, 24,1912, 24, 816, 0, 528,1916,1920, 528, 528,1924,1928,1932, + 660, 660, 660, 660, 660,1936, 660, 660, 584, 584, 584, 584, 584, 584, 584,1940, + 0,1944, 584, 584, 752, 752, 752, 752,1948,1952,1956, 752, 664, 664, 664, 664, + 664, 664, 664,1960, 700, 700, 700, 700, 700, 700,1964,1968, 704, 704, 704, 704, + 704, 704,1972, 0, 192, 192, 0, 192,1976, 192, 192, 192, 464,1980, 0, 464, + 464,1140,1140, 464, 464, 464, 464, 464, 464,1984,1988,1992, 532,1148,1996, 532, + 532,1148, 0, 0, 420,2000,2004, 420, 668, 668, 668, 668, 668,2008, 668, 668, + 708, 708, 708, 708,2012, 0, 708, 708, 756, 756, 756, 756,2016, 0,1152,2020, + 0, 0,1152, 756, 312, 312,2024, 0,1156, 0, 0, 0,1156, 0,2028, 180, + 504, 504, 0, 0, 504, 504,2032, 0, 368,1160,2036, 368, 368,1160, 0,2040, + 28, 28, 28, 828, 544, 544,2044,1164,1164, 0, 0, 0,1168, 28, 0, 0, + 28, 28,2048, 0, 0, 0,1168, 28, 548, 548, 0, 0, 552, 552,2052, 0, + 712, 712, 712, 712, 712, 712,2056, 0, 672, 672, 672, 672, 672, 672, 672, 0, + 760, 760, 760, 760, 760,2060, 0, 0, 168, 168, 168,1172,2064, 168, 168, 168, + 168,1172, 0,2068,2072, 0, 0,2076, 620, 620, 620, 620, 620, 620,2080, 0, + 620, 620,2084, 0, 328,2088, 328, 328, 328, 328, 0, 0, 588,2092, 0, 0, + 884, 224, 224, 224, 224,1036, 0, 0,2096, 372, 372, 372,2100, 0, 0, 0, + 716,2104,2108,1176, 716, 716, 716,1176, 716, 716,2112, 0, 348, 348,2116, 0, + 348, 348,2120, 0, 468, 928, 468, 832, 832, 468, 468, 468, 468, 468,1180, 468, + 1180, 928,2124, 468, 468, 832, 832,2128, 932,2132, 0, 928, 468,2136, 468, 932, + 468, 932, 0, 0, 376, 376, 936,2140, 376, 936, 376, 376,2144,2148,2152, 376, + 376, 936,2156, 0,2160, 0, 0, 0, 188, 188, 188,2164,2168, 0, 0, 0, + 244, 244, 0, 0, 244, 244,2172, 0, 196,1184, 196, 196, 196, 196, 196,1184, + 276,2176, 0, 0, 276, 276,2180, 0, 128, 128, 128,1068, 100, 0, 0, 0, + 424, 424,1192,2184, 424, 424, 424, 0, 424,1192, 0, 0, 380, 380, 380, 0, + 2188, 0, 0,2192, 428,1196,2196, 428, 428,2200, 428, 428, 428, 428, 428, 428, + 428,2204,2208, 428, 428,1196, 0, 0, 428, 428,2212, 0, 384,2216, 0, 0, + 316, 316, 0, 0,2220, 0, 0, 0, 432, 432,2224, 0, 120, 120,2228, 0, + 176, 176, 0, 0,1204, 0, 0, 0, 556, 556,1204, 0, 200, 200,2232, 200, + 200,2236, 200, 200, 200,2240, 0, 0, 200, 200, 200,2244,2248, 388, 388, 388, + 388, 388,2252, 388, 388,2256, 0, 0, 392,1208,1212, 392, 392,1208,2260,1212, + 392, 392, 0, 0, 392, 392,2264, 0, 508,1216,2268, 508, 508, 508, 508, 508, + 508, 508, 508,2272,1216, 508,2276, 0, 508, 508,2280, 0, 472, 472, 472, 0, + 472, 472,2284, 0, 720, 720, 720, 720, 720, 720,2288, 0,2292, 280, 280, 280, + 280, 280,1220,2296, 280, 280,1220, 0,2300, 0, 0, 0, 800, 0, 0, 876, + 32, 32,2304, 0, 32, 32, 32,2308, 32,2312, 0, 0, 32, 0, 0, 0, + 2316, 0, 0, 0, 20,2320, 0, 0, 20, 20,2324, 0, 56,2328, 0, 0, + 436, 436,2332, 0, 48, 48,2336, 0, 592, 592, 592, 592, 592, 592, 592,2340, + 592, 592,2344,2348, 212, 212, 212,2352, 212, 212,2356, 0, 624, 624, 624, 624, + 624, 624, 624,1224, 624,1224, 0, 0, 160,2360, 0, 0, 160, 160,1228, 160, + 1228, 160, 160, 160, 160, 160, 0,2364, 440, 440,2368, 0, 204, 204,2372, 0, + 512, 512,2376, 512, 512, 0, 0, 0, 132, 132,2380,1232, 132, 132, 0,1232, + 2384,2388, 0, 0, 4,1236, 0, 0, 64,2392, 0, 0, 0, 0, 0,2396, + 16, 16, 16,1240,1240, 0, 0, 0, 92,2400, 92,2404,2408, 80, 80, 80, + 2412, 0, 0, 0,2416, 0, 0, 0,1104,2420, 0, 0, 0, 92, 0, 0, + 76, 76, 76, 0, 140, 140,2424, 0, 140, 140, 140,1244, 140, 140,1244, 0, + 140, 140,2428, 140, 12, 0, 692, 12, 52,2432, 0, 0, 12, 296, 452, 12, + 12,1248, 912, 12, 12, 12,1248, 52,1076,2436, 52, 12, 12, 12,2440, 912, + 68, 688, 0, 0, 12, 296, 0, 0, 12, 12, 12, 648,2444,2448, 452, 648, + 12, 12, 940, 452, 12, 452, 12, 12, 12, 940, 296, 452, 12, 648, 12, 648, + 12, 12, 940, 296, 12,2452, 692, 12, 648, 12, 12, 12, 12, 264, 12, 12, + 12, 12, 12, 692, 44, 44, 44, 0, 0, 0,2456, 44,2460, 44, 44, 44, + 24, 24, 24, 816, 0,1112, 816, 0, 152,1252, 152, 152, 152, 152,2464, 152, + 2468,2472,1252, 0, 60, 60, 60,2476, 0, 0, 0,2480, 356, 356, 356,2484, + 356, 356, 356,1256, 356, 356,1256,2488, 676, 676, 676, 676, 676, 676, 676,2492, + 444, 444,2496,2500, 560, 560,2504, 0, 564, 564,2508,2512, 516, 516, 516,2516, + 516,2520, 0,2524, 72, 232, 72,2528, 72, 72, 72, 232, 104,2532, 104, 104, + 104,2536, 0, 0, 216, 216, 216, 0, 216, 216,2540,2544, 12, 364, 0, 0, + 28, 724, 28, 28, 944, 948, 724, 28, 828, 28, 836, 0,2548, 984, 836, 724, + 944, 948, 836, 836, 944, 948, 828, 28, 828, 28, 724,2552, 28, 28,1260, 28, + 724, 724,1260, 28, 980, 0, 0, 0, 0, 692, 12, 12,2556, 0, 0, 0, + 12, 12, 364, 12, 12, 12, 296, 692, 12, 296, 364, 452, 12, 12, 12,2560, + 12, 12, 296, 736,2564, 0, 0, 0, 4, 4,1236, 0,2568, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, + 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040, + 1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126, + 1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226, + 1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944, + 1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973, + 1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993, + 1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, + 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0, + 1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, + 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077, + 1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096, + 1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236, + 1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323, + 1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, + 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951, + 1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062, + 1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, + 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113, + 1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, + 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0, - 1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, - 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, - 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0, + 1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0, + 1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0, + 1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, + 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524, + 1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533, + 1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541, + 1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606, + 1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872, - 1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, + 1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, + 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0, + 1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, + 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, + 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0, + 1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, + 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0, - 1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, - 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0, - 1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0, - 1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, - 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0, - 1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, - 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, - 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, - 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, - 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, - 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, - 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, - 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, - 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, - 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, - 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, - 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, - 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, - 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, - 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, - 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, - 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, - 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, - 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, - 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, - 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, - 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, - 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, - 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, - 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, - 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, - 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, - 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, - 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, - 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, - 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, + 1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, + 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603, - 1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589, - 1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582, - 1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, - 1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, + 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0, + 1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955, + 1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967, + 1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995, + 1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019, + 1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030, + 1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383, + 1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070, + 1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095, + 1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102, + 1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122, + 1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947, + 1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373, + 1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328, + 1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330, + 1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399, + 1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109, + 1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701, + 1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729, + 1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737, + 1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765, + 1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777, + 1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785, + 1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794, + 1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, + 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709, + 1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745, + 1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802, + 1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822, + 1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823, + 1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, + 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, + 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824, + 1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943, - 1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, - 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953, - 1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, - 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, + 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, + 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, + 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, + 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, + 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, + 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865, + 1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, + 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, + 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0, + 1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, + 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, + 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, + 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0, + 1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, + 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, + 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, + 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, + 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, + 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, + 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, + 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, + 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, + 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, + 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, + 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, + 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, + 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, + 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, + 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, + 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, + 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, + 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, + 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, + 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, + 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, + 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, + 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, + 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, + 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, + 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, + 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, + 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, + 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, + 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, + 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579, + 1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0, + 1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, 0, 0, 0, + 1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976, - 1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, - 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, - 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, - 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, - 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, - 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, - 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, - 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, - 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, - 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, - 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, - 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, - 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, - 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, - 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, - 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, - 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, - 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, - 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, - 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, - 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, - 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, - 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, - 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, - 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, - 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, - 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, - 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, - 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, - 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, - 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, - 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, - 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, - 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, - 821, 935, 0, 0, + 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, 0,1958,1961, + 1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970,1971,1972,1973, + 1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979,1981, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, + 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, + 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, + 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, + 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, + 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, + 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, + 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, + 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, + 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, + 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, + 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, + 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, + 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, + 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, + 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, + 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, + 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, + 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, + 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, + 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, + 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, + 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, + 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, + 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, + 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, + 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, + 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, + 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, + 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, + 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, + 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, + 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, + 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, + 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[92] = +static const int16_t _hb_ucd_i16[92]= { - 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, - 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, - 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, + 0, 0, 1, -1, -1, 1, 0, 1, -1, 0, 0, 2, 0, -2, 2, 0, + -2, 0, -7, 0, 0, 16, 0, -16, 3, 3, 3, -3, -3, -3, 0, 2016, + 0, 2527, 1923, 1914, 1918, 0, 2250, 0, 0, 138, 0, 7, 1824, 0, 2104, 0, 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6472+(((_hb_ucd_u8[816+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>4>>4])<<4)+((u>>1>>3>>4)&15u))])<<4)+((u>>1>>3)&15u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + /* packtab: [2^8,2^4,2^4,2^3,2^1] */ + return u<1114110u ? (uint8_t)(_hb_ucd_u8[6536u+((_hb_ucd_u8[800u+_hb_ucd_u16[((_hb_ucd_u8[272u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>4))>>4)])<<4)+((((((((u)>>1))>>3))>>4))&15)])<<4)+((((((u)>>1))>>3))&15)]+((((u)>>1))&7)])<<1)+((u)&1)]) : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8504+(((_hb_ucd_u8[7936+(((_hb_ucd_u8[7460+(((_hb_ucd_u8[7100+(((_hb_ucd_u8[6854+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + /* packtab: [2^8,2^3,2^2,2^2,2^2] */ + return u<125259u ? (uint8_t)(_hb_ucd_u8[8589u+((_hb_ucd_u8[8006u+((_hb_ucd_u8[7529u+((_hb_ucd_u8[7163u+((_hb_ucd_u8[6918u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)]) : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9396+(((_hb_ucd_u8[9164+(((_hb_ucd_u8[9068+(((_hb_ucd_b4(9004+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + /* packtab: [2^4,2^3,2^3,2^2,2^1] */ + return u<65380u ? (int16_t)(_hb_ucd_i16[_hb_ucd_u8[9480u+_hb_ucd_u8[9251u+_hb_ucd_u8[9157u+((_hb_ucd_b4(_hb_ucd_u8+9093u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)]+((((((u)>>1))>>2))&7)]+((((u)>>1))&3)]+((u)&1)]) : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[10398+(((_hb_ucd_u16[3952+(((_hb_ucd_u16[2624+(((_hb_ucd_u8[9870+(((_hb_ucd_u8[9644+(u>>3>>2>>3>>4)])<<4)+((u>>3>>2>>3)&15u))])<<3)+((u>>3>>2)&7u))])<<2)+((u>>3)&3u))])<<3)+((u)&7u))]:2; + /* packtab: [2^8,2^4,2^3,2^2,2^2] */ + return u<918000u ? (uint8_t)(_hb_ucd_u8[10913u+_hb_ucd_u16[4624u+_hb_ucd_u16[2592u+((_hb_ucd_u8[10177u+((_hb_ucd_u8[9728u+((((((((u)>>2))>>2))>>3))>>4)])<<4)+((((((((u)>>2))>>2))>>3))&15)])<<3)+((((((u)>>2))>>2))&7)]+((((u)>>2))&3)]+((u)&3)]) : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6244+(((_hb_ucd_u8[16628+(((_hb_ucd_u8[16246+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + /* packtab: [2^8,2^5,2^4] */ + return u<195102u ? (uint16_t)(_hb_ucd_u16[7453u+((_hb_ucd_u8[13867u+((_hb_ucd_u8[13485u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)]) : 0; } #else -static const uint8_t -_hb_ucd_u8[13730] = +#include + +static const uint8_t _hb_ucd_u8[13905]= { - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 7, 21, 22, 22, 22, 23, 24, 7, 7, - 7, 25, 22, 22, 22, 26, 27, 28, 22, 29, 30, 31, 32, 33, 34, 35, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 22, 36, - 7, 7, 7, 7, 37, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 38, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, - 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, - 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, - 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, - 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, - 120,121,122,123,124,125,126,127, 34,128,129,130,131,132,133,134, - 135,136,137,138,139,140,141,142,143,144,111,145,146,147,148,111, - 149,150,151,152,153,154,155,156,157,158,159,160,111,161,162,163, - 34, 34, 34, 34, 34, 34, 34, 34,164, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,165, - 34, 34, 34, 34, 34, 34, 34, 34,166, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,167,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34,168,169,170, 34,111,111,171,111,172,173,174,175, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, - 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,176,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 67,177, 67, 67, 67, 67,178, 67, - 67, 67,179,180,181,131, 65,111,182,183,184,185,186,187,188,189, - 67, 67, 67, 67,190,191,111,111,111,111,111,111,111,111,192,111, - 193,194,195,111,111,196,111,111,111,197,111,198,111,111,111, 34, - 34,199,200,111,111,111,111,111,131,201,202,111, 34,203,111,111, - 67, 67,204, 67, 67,111, 67,205, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67,177,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, - 206,111,194,194,111,111,111,111,111,111,111,111,111,111,111,111, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, - 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, - 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, - 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, - 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, - 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, - 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10, - 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11, - 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53, - 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55, - 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61, - 43, 43, 43, 43, 43, 57, 62, 2, 63, 36, 36, 36, 36, 64, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 65, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 66, 43, 43, 43, 67, 47, 43, 43, 68, 69, 70, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 71, 72, 2, 2, 2, 2, 2, 2, 2, 73, - 64, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 65, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36, - 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, - 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, - 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, - 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 75, 43, 43, 43, 43, - 36, 36, 36, 36, 76, 43, 43, 43, 43, 75, 43, 43, 43, 43, 43, 43, - 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, - 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, - 64, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 78, - 79, 43, 43, 77, 78, 78, 79, 36, 36, 36, 36, 82, 78, 78, 36, 36, - 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43, - 43, 77, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 78, - 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 65, 36, 36, 36, - 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 64, 2, 2, 2, 2, 2, - 79, 43, 43, 43, 77, 78, 79, 43, 60, 20, 20, 20, 83, 43, 43, 43, - 43, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 79, - 79, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 77, 78, 78, 36, 36, - 72, 27, 27, 27, 27, 27, 27, 27, 43, 65, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 78, 77, 78, 78, 78, 78, 78, 79, 43, - 36, 36, 36, 82, 78, 78, 78, 78, 78, 78, 78, 7, 7, 7, 7, 7, - 27, 84, 61, 61, 53, 61, 61, 61, 77, 78, 65, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 65, 43, 77, 78, 78, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 85, 27, 27, 27, 84, - 64, 78, 66, 36, 36, 36, 36, 36, 78, 78, 78, 77, 78, 78, 43, 43, - 43, 43, 77, 78, 78, 78, 81, 36, 86, 82, 78, 78, 78, 78, 78, 78, - 43, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 78, - 79, 43, 43, 78, 78, 78, 79, 71, 61, 61, 36, 82, 27, 27, 27, 87, - 27, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 77, - 78, 43, 43, 43, 78, 78, 78, 78, 7, 78, 2, 2, 2, 2, 2, 2, - 64, 36, 43, 43, 43, 43, 43, 88, 36, 36, 36, 69, 43, 43, 43, 57, - 7, 7, 7, 7, 7, 2, 2, 2, 64, 36, 43, 43, 43, 43, 65, 36, - 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36, - 71, 61, 2, 2, 2, 2, 2, 2, 2, 89, 89, 61, 43, 61, 61, 61, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 78, - 64, 43, 43, 43, 43, 43, 43, 77, 43, 43, 57, 43, 36, 36, 64, 43, - 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 70, 61, 61, 61, 61, - 2, 2, 89, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 82, 79, 43, - 77, 43, 43, 43, 79, 77, 79, 65, 36, 36, 36, 78, 43, 36, 36, 43, - 65, 78, 81, 82, 78, 78, 78, 36, 64, 43, 65, 36, 36, 36, 36, 36, - 36, 77, 79, 77, 78, 78, 79, 82, 7, 7, 7, 7, 7, 78, 79, 61, - 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 64, 43, - 2, 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16, - 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 71, 66, - 92, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 94, 94, - 36, 36, 36, 36, 36, 58, 2, 95, 96, 36, 36, 36, 36, 36, 36, 36, - 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, - 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, - 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 75, - 36, 76, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, - 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, - 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, - 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, - 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, - 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 2, - 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, - 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, - 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, - 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, - 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16, 34, 16, 16, 16, 43, 57, 43, 43, 43, 43, 43, 43, - 77, 43, 43, 43, 65, 36, 64, 36, 36, 36, 65, 82, 43, 36, 36, 36, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, - 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16,100, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16,101,101,101,101, - 16, 16, 16, 16, 11, 11,102,103, 41, 16, 16, 16, 11, 11,102, 41, - 16, 16, 16, 16, 11, 11,104, 41,105,105,105,105,105,106, 59, 59, - 51, 51, 51, 2,107,108,107,108, 2, 2, 2, 2,109, 59, 59,110, - 2, 2, 2, 2,111,112, 2,113,114, 2,115,116, 2, 2, 2, 2, - 2, 9,114, 2, 2, 2, 2,117, 59, 59, 59, 59, 59, 59, 59, 59, - 118, 40, 27, 27, 27, 8,115,119, 27, 27, 27, 27, 27, 8,115, 94, - 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,120, 48, - 99, 48, 99, 43, 43, 43, 43, 43, 61,121, 61,122, 61, 34, 11, 16, - 11, 32,122, 61, 46, 11, 11, 61, 61, 61,121,121,121, 11, 11,123, - 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,124, - 95, 95, 95, 95, 95, 95, 95, 95, 95,125,126, 95,127, 61, 61, 61, - 8, 8,128, 61, 61, 8, 61, 61,128, 26, 61,128, 61, 61, 61,128, - 61, 61, 61, 61, 61, 61, 61, 8, 61,128,128, 61, 61, 61, 61, 61, - 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,129,130, 61, 61, - 61, 61, 61, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 26, 8, 8, - 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, - 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, - 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, - 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, - 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, - 8, 8,115,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,115,132,132,132,132,132,132,132,132,132,132,131, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,128, 26, 8, 8,128, 61, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,124, 61, 61,122, 34,133, - 43, 32, 16, 16, 50, 2, 90, 2, 36, 36, 36, 36, 36, 36, 36, 76, - 2, 2, 2, 2, 2, 2, 2, 56, 2,107,107, 2,111,112,107, 2, - 2, 2, 2, 6, 2, 98,107, 2,107, 4, 4, 4, 4, 2, 2, 80, - 2, 2, 2, 2, 2, 51, 2, 2, 98,134, 2, 2, 2, 2, 2, 2, - 61, 2,135,132,132,132,136, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 1, 2,137,138, 4, 4, 4, 4, 4, 61, 4, 4, 4, 4,139, 94, - 140, 95, 95, 95, 95, 43, 43, 78,141, 40, 40, 61, 95,142, 58, 61, - 72, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64,143,144, 63, - 36, 36, 36, 36, 36, 58, 40, 63, 61, 27, 27, 61, 61, 61, 61, 61, - 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, - 145, 27, 27, 27, 27, 27, 27, 27, 36, 36, 76, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36,146, 2, 32, 32, 32, 32, 32, 32, 32, 64, - 48,147, 43, 43, 43, 43, 43, 80, 32, 32, 32, 32, 32, 32, 40, 43, - 36, 36, 36, 95, 95, 95, 95, 95, 43, 2, 2, 2, 2, 2, 2, 2, - 41, 41, 41,144, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, - 16, 32, 32, 32, 32, 32, 32, 32, 44, 16, 16, 16, 34, 34, 34, 32, - 32, 32, 32, 32, 42,148, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, - 32, 32, 11, 11, 34, 34, 32, 16, 32, 16, 16, 32, 32, 32, 11, 11, - 11, 40,149, 35, 40, 35, 36, 36, 36, 65, 36, 65, 36, 64, 36, 36, - 36, 82, 79, 77, 61, 61, 43, 43, 27, 27, 27, 61,150, 61, 61, 61, - 36, 36, 2, 2, 2, 2, 2, 2, 78, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 78, 78, 78, 78, 78, 78, 78, 78, 43, 43, 43, 43, 43, 2, - 43, 36, 36, 36, 2, 66, 66, 64, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 64, 43, 43, 43, 43, 43, 78, 78, 78, 78, 78, 78, 97, - 36, 64, 78, 43, 43, 78, 43, 78, 97, 2, 2, 2, 2, 2, 2, 80, - 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 64, 63, 36, 36, 36, 36, - 36, 36, 36, 36, 64, 43, 43, 77, 79, 77, 79, 43, 43, 43, 43, 43, - 36, 64, 36, 36, 36, 36, 77, 78, 7, 7, 7, 7, 7, 7, 2, 2, - 63, 36, 36, 71, 61, 82, 77, 36, 65, 43, 65, 64, 65, 36, 36, 43, - 36, 36, 36, 36, 36, 36, 76, 2, 36, 36, 36, 36, 36, 82, 43, 78, - 2, 76,151, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,103, 40, 40, - 16, 16, 16, 16,100, 41, 41, 41, 36, 82, 79, 78, 77, 97, 79, 43, - 152,152,152,152,152,152,152,152,153,153,153,153,153,153,153,153, - 16, 16, 16, 16, 16, 16, 35, 65, 36, 36, 36, 36,154, 36, 36, 36, - 36, 41, 41, 41, 41, 41, 41, 41, 41, 74, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,132, 36, 36, 36, 36, 36, 36, 36, 71, - 36, 36, 36, 36, 36, 36,150, 61, 2, 2, 2,135,116, 2, 2, 2, - 6,155,156,132,132,132,132,132,132,132,116,135,116, 2,113,157, - 2, 2, 2, 2,139,132,132,116, 2,158, 8, 8, 60, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36,159, 2, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,115,116, 4, 2, 36, 36, 36, 36, 36, - 63, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 20,160, 53, 20, 26, 8,128, 61, 61, 61, 61, 61,161, 59, 61, 61, - 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, - 95, 95,127, 27, 84, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, - 61, 61, 61, 61, 61, 61, 47, 43,162,162,162,162,162,162,162,162, - 163, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 87, 36, - 138, 36, 36, 36, 36, 95, 95, 95, 36, 36, 36, 36, 36, 36, 36, 58, - 164, 95, 95, 95, 95, 95, 95, 95, 11, 11, 11, 32, 16, 16, 16, 16, - 36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 71,145, 27, 27, 27, - 36, 36, 36,165, 27, 27, 27, 27, 36, 36, 36, 36, 36,165, 27, 27, - 36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36, - 64, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36,165, 30, 36, 36, 36, 36, 36, 36,165, 27, - 36, 36, 36, 36, 72, 36, 36, 36, 36, 36, 64, 43, 43,163, 27, 27, - 36, 36, 36, 36, 58, 2, 2, 2, 36, 36, 36, 36, 27, 27, 27, 27, - 16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43, - 7, 7, 7, 7, 7, 36, 36, 63, 11, 11, 11, 11,166, 43, 43,141, - 16, 16, 16, 16, 16, 16, 16, 8, 36, 36, 36, 36, 36, 64,167, 51, - 36, 36, 36, 36, 36, 36, 43, 43, 27, 27, 27, 87, 36, 36, 36, 36, - 163, 27, 30, 2, 2, 2, 2, 2, 36, 43, 43, 2, 2, 2, 2, 2, - 36, 36,165, 27, 27, 27, 27, 27, 79, 81, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 7, 7, 7, 7, 7, 65, 64, 65, 36, 36, 36, 36, 64, - 78, 79, 43, 77, 79, 57, 73, 2, 2, 43, 43, 43, 43, 43, 67, 59, - 36, 36, 36, 64, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, - 2, 2, 82, 81, 36, 36, 36, 36, 36, 64, 2, 36, 36, 36, 36, 36, - 36, 82, 78, 43, 43, 43, 43, 77, 81, 36, 58, 2, 56, 43, 57, 79, - 7, 7, 7, 7, 7, 58, 58, 2, 90, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 36, 36, 36, 36, 78, 79, 43, 78, 77, 43, 2, 2, 2, 65, - 36, 36, 36, 36, 36, 36, 36, 64, 77, 78, 78, 78, 78, 78, 78, 78, - 36, 36, 36, 82, 78, 78, 81, 36, 36, 78, 78, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 78, 79, 43, 43, 43, 78, 78, 78, 78, 78, 78, 77, - 65, 65, 2, 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 43, 43, - 36, 36, 82, 78, 43, 43, 43, 43, 78, 43, 77, 65, 36, 58, 2, 2, - 7, 7, 7, 7, 7, 2, 2, 65, 78, 79, 43, 43, 77, 77, 78, 79, - 77, 43, 36, 66, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 82, - 78, 43, 43, 43, 78, 78, 43, 79, 57, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 43, 78, 79, 43, 43, 43, 77, 79, 79, - 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 79, 78, - 43, 43, 43, 79, 58, 2, 2, 2, 36, 36, 36, 36, 36, 36, 64, 79, - 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, - 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, - 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, - 82, 78, 43, 43, 43, 43, 78, 78, 65, 66, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, - 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, - 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, - 43, 43, 43, 77, 43, 2, 66, 2, 58, 2, 2, 2, 2, 2, 2, 2, - 43, 43, 43, 43, 43, 43, 43, 79, 2, 36, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, - 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, - 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, - 43, 82, 36, 36, 36, 36, 36, 36, 36, 36, 78, 43, 43, 43, 43, 78, - 77, 57, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 43, 43, 43, - 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 21, 65, 36, 36, 64, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 78, 79, 43, - 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, - 40, 40, 89, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,168, 27, 27, - 27, 87, 36, 36, 36, 36, 36, 36, 40, 63, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 76,146, 2, 27, 27, 27, 30, 2, 2, 2, 2, - 82, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, - 43, 68, 40, 40, 40, 40, 40, 40, 40, 80, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,169, 79, 43, 61,169, 78, - 78,170, 59, 59, 59, 75, 43, 43, 43, 70, 47, 43, 43, 43, 61, 61, - 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 70, 61, 61, 61, 61, 61, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, - 43, 43, 43, 70, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 70, 61, - 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 70, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 56, 43, 43, 16, 16, 16, 16, 16, 39, 16, 16, - 43, 43, 43, 68, 40, 40, 40, 40, 7, 7, 7, 7, 7, 7, 7, 71, - 7, 7, 7, 7, 7, 7, 7,171, 36, 36, 36, 36, 36, 76, 43, 43, - 172, 7, 7, 7, 7, 7, 7, 85, 16, 16, 43, 43, 43, 68, 40, 40, - 27, 27, 27, 27, 27, 27,145, 27,173, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 84, 61, - 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, - 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, - 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, - 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 24, 7, 1, 12, - 7, 6, 12, 10, 10, 10, 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, - 15, 26, 13, 21, 13, 7, 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, - 29, 7, 7, 22, 18, 18, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, - 5, 6, 8, 8, 8, 24, 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, - 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, - 18, 21, 21, 29, 15, 6, 18, 6, 12, 11, 9, 26, 26, 9, 26, 5, - 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, - 18, 22, 5, 12, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, - 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, - 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, - 16, 22, 16, 16, 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, - 21, 14, 7, 15, 9, 12, 12, 17, 13, 15, 26, 10, 10, 1, 13, 23, - 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, - 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, + 4, 5, 6, 7, 8, 9, 10, 2, 2, 11, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 12, 13, 2, 2, 2, 2, 2, 14, 1, 1, 1, 15, + 16, 17, 18, 19, 20, 21, 22, 2, 3, 0, 0, 0, 23, 24, 2, 2, + 2, 25, 0, 0, 0, 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, 35, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0, 36, + 2, 2, 2, 2, 2, 2, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 2, 2, 2, 2, 45, 46, 47, 2, 2, 2, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 5, 5, 72, 73, 8, 74, 3, 75, 76, 3, 77, 78, + 3, 3, 5, 79, 5, 5, 80, 3, 81, 82, 83, 84, 85, 3, 3, 3, + 86, 87, 2, 88, 89, 90, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 2, 2, 2, + 92, 2, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 94, 95, 96, 97, + 98, 99,100,101,102,103,104,105, 2, 2, 2, 2, 2, 2, 2, 2, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 2, 2, 2, 2,106,107, 2, 2,108,109,110,111,112,113, + 2, 2,114,115, 0,116,117,118,119,120,121,122, 2, 2, 2, 9, + 123,124,125,126,127,128,129,130, 2,131,132,133, 6,134,135,136, + 137,138,139,140,141,142,143,144,145,146, 0,147,148,149,150, 0, + 151,152,153,154,155,156,157,158,159,160,161,162, 0,163,164,165, + 2, 2, 2, 2, 2, 2, 2, 2,166, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, + 2, 2, 2, 2, 2, 2, 2, 2,168, 2, 2, 2, 2, 2, 2, 2, + 0, 0,169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2,170,171,172, 2, 0, 0,173, 0,174,175,176,177, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2,178, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 3, 3, 3,179,180, 3, + 3, 3,181,182,183, 6, 8, 0,184,185,186,187,188,189,190,191, + 3, 3, 3, 3,192,193, 0, 0, 0, 0, 0, 0, 0, 0,194, 0, + 195, 7,196, 0, 0,197, 0, 0, 0,198, 0,199, 0,200, 0, 2, + 2,201,202, 0, 0, 0, 0, 0, 6,203,204, 0, 2,205, 0, 0, + 3, 3,206, 3, 3, 0, 3,207, 3, 3, 3, 3, 3, 3, 3, 3, + 3,208, 3, 3, 3, 3, 3, 10, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, + 209, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 11, 11, 11, 11, 11, 11, 11, 11, + 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, + 9, 9, 9, 9, 9, 9, 9, 9, 13, 13, 13, 13, 13, 13, 13, 13, + 10, 10, 10, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 6, 6, 6, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 1, 1, 1, 1, 4, 4, 9, 9, 9, 9, 9, + 25, 25, 25, 25, 25, 25, 25, 25, 14, 14, 14, 14, 14, 14, 14, 14, + 8, 8, 8, 8, 8, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, + 1, 1, 1, 4, 4, 4, 4, 4, 4, 14, 30, 1, 1, 1, 1, 1, + 9, 9, 9, 9, 9, 10, 10, 10, 9, 9, 9, 9, 9, 7, 7, 7, + 8, 8, 8, 8, 6, 6, 6, 6, 1, 4, 4, 4, 4, 4, 4, 4, + 4, 30, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 32, 32, 32, 32, + 24, 24, 24, 24, 24, 24, 24, 24, 9, 9, 9, 9, 9, 9, 9, 10, + 1, 1, 1, 1, 1, 1, 1, 29, 21, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 1, 29, 10, 10, 10, 29, 10, 10, 10, 10, 10, 10, 10, + 1, 1, 1, 1, 1, 1, 1, 4, 6, 6, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 8, 8, + 8, 8, 8, 6, 6, 6, 6, 6, 9, 9, 9, 9, 9, 10, 11, 65, + 73, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 86, 87, 88, + 74, 6, 6, 6, 6, 6, 6, 6, 20, 20, 20, 20, 20, 20, 20, 20, + 19, 8, 8, 8, 8, 8, 8, 8, 22, 1, 1, 1, 1, 1, 1, 1, + 21, 1, 1, 1, 1, 1, 1, 1, 4, 17, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 22, 14, 4, 17, 30, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 22, 18, 4, 22, 1, 1, 1, 1, 1, 1, + 14, 14, 14, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 21, 22, 14, + 10, 10, 10, 10, 60, 7, 7, 7,100, 1, 1, 1, 1, 1, 1, 1, + 14, 18, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 13, 13, 13, 10, + 20, 6, 6, 6, 8, 8, 79, 20, 6, 6, 6, 6, 8, 8,103, 20, + 26, 26, 26, 26, 26, 26, 26, 26, 7, 7, 7, 7, 7, 3, 3, 3, + 63, 7, 7, 7, 7, 7, 7, 7, 1, 1, 34, 1, 1, 1, 1, 1, + 1, 1, 1, 46, 7, 7, 7, 7, 1, 1, 1, 1, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 1, 46, 7, 1, 1, 1, 1, 7, 7, 7, 7, + 1, 1, 1, 1, 1, 1, 14, 18, 1, 1, 1, 1, 1, 1, 1, 21, + 1, 1, 1, 1, 1, 1, 1, 27, 9, 9, 9, 9, 9, 3, 3, 3, + 72, 10, 84, 10, 23, 85, 64, 10, 6, 6, 6, 6, 6, 89, 90,119, + 72, 24, 24, 47, 91,120,121, 92, 36, 7, 74, 10,122,123, 7, 54, + 8, 8, 8, 48, 8, 8, 8, 12, 6, 6, 6, 49, 6, 6, 6, 6, + 12, 12, 12, 12, 19, 19, 19, 19, 19, 19, 19, 19, 6, 12, 12, 12, + 12, 12, 12, 12, 8, 19, 19, 6, 19, 12, 12, 8, 19, 8, 6, 8, + 8, 19, 12, 8, 12, 6, 8, 19, 12, 12, 12, 8, 19, 6, 12, 8, + 19, 8, 19, 19, 12, 50, 12, 6, 1, 1, 93, 19, 94, 93, 19, 19, + 19, 19, 19, 19, 19, 19, 6, 12, 19, 94, 12, 8, 12, 12, 12, 12, + 12, 12, 6, 6, 6, 8, 19, 12, 19, 19, 8, 12, 12, 12, 12, 12, + 6, 6, 1, 6, 6, 6, 6, 6, 13, 20, 20, 13, 13, 13, 13, 13, + 13, 20, 20, 20, 20, 20, 20, 20, 13, 13, 55, 20, 20, 20, 55, 55, + 12, 12, 55, 12, 6, 56, 6, 73, 20, 20, 20,124, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 19, + 6, 8, 12, 6, 12, 12, 12, 12, 6, 6, 12, 75, 19, 12, 19, 8, + 12, 33, 4, 4, 66, 12, 12, 12, 8, 19, 19, 19, 19, 19, 19, 6, + 8, 8, 8, 8, 95, 10, 10, 10, 6, 6, 6, 6, 76, 26,125, 57, + 126, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,127, + 37, 31, 4, 37, 4, 4, 4, 4, 1, 29, 10, 10, 10, 10, 10, 10, + 15, 15, 15, 11, 65, 67, 10, 3, 4, 4, 4, 4, 4, 31,128, 10, + 38, 1, 1, 1, 1, 21, 4, 4, 9, 9, 9, 9, 9, 10, 10, 1, + 1, 1, 39, 4, 4, 4, 96, 33, 4, 4, 68, 51, 40, 4, 4, 1, + 9, 9, 9, 9, 9, 1, 41, 58, 10, 10, 10, 10, 10, 10, 10, 97, + 4, 4, 4, 4, 4, 4, 22, 1, 1, 1, 1, 1, 1, 21, 4, 4, + 4, 4, 13, 47, 10, 13, 51, 24, 1, 1, 1, 4, 4, 51, 4, 4, + 4, 4, 51, 4, 51, 4, 4, 4, 1, 1, 1, 1, 21, 4, 4, 10, + 1, 1, 1, 1,129, 1, 1, 1, 15, 15, 15, 69, 4, 4, 4, 4, + 1, 1, 1, 1, 34, 4, 4, 4, 4, 69, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 17, 22, 14, 18, 4, 4, 4, 17, 14, 18, 14, + 21, 4, 4, 4, 1, 1, 1, 1, 1, 4, 10, 9, 9, 9, 9, 9, + 42, 1, 1, 1, 1, 1, 1, 1, 21, 14, 30, 1, 1, 1, 1, 1, + 18, 4, 4, 17, 14, 14, 18, 1, 1, 1, 1, 27, 14, 14, 1, 1, + 1, 24, 7, 7, 7, 57, 29, 4, 1, 1, 1, 1, 1, 1, 4, 14, + 18, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 1, 1, 1, + 1, 1, 1, 9, 9, 9, 9, 9, 4, 1, 21, 10, 10, 10, 10, 10, + 18, 4, 4, 4, 17, 14, 18, 4, 67, 24, 24, 24,130, 4, 4, 4, + 18, 4, 4, 17, 14, 14, 18, 4, 4, 4, 4, 17, 14, 14, 1, 1, + 58, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 14, + 17, 14, 14, 14, 14, 14, 18, 4, 1, 1, 1, 27, 14, 14, 14, 14, + 7, 43, 3, 3, 57, 3, 3, 3, 17, 14, 22, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 22, 4, 17, 14, 14, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 1, 1, 1, 1, 9, 9, 9, 98, 7, 7, 7, 43, + 21, 14, 39, 1, 1, 1, 1, 1, 14, 14, 14, 17, 14, 14, 4, 4, + 4, 4, 17, 14, 14, 14, 1, 1, 99, 27, 14, 14, 14, 14, 14, 14, + 4, 14, 1, 1, 1, 1, 1, 1, 18, 4, 4, 14, 14, 14, 18, 41, + 3, 3, 1, 27, 7, 7, 7, 59, 7, 7, 7, 7, 43, 1, 1, 1, + 1, 1, 1, 1, 1, 4, 4, 17, 14, 4, 4, 4, 14, 14, 14, 14, + 9, 14, 10, 10, 10, 10, 10, 10, 21, 1, 4, 4, 4, 4, 4,131, + 1, 1, 1, 51, 4, 4, 4, 31, 21, 1, 4, 4, 4, 4, 22, 1, + 1, 1, 1, 13, 4, 4, 4, 4, 9, 9, 9, 9, 9, 9, 1, 1, + 41, 3, 10, 10, 10, 10, 10, 10, 10, 44, 44, 3, 4, 3, 3, 3, + 7, 7, 33, 33, 33, 23, 23, 14, 21, 4, 4, 4, 4, 4, 4, 17, + 4, 4, 31, 4, 1, 1, 21, 4, 4, 4, 4, 4, 4, 4, 4, 3, + 3, 3, 3, 40, 3, 3, 3, 3, 10, 10, 44, 3, 47, 10, 10, 10, + 1, 1, 1, 1, 1, 27, 18, 4, 17, 4, 4, 4, 18, 17, 18, 22, + 1, 1, 1, 14, 4, 1, 1, 4, 22, 14, 30, 27, 14, 14, 14, 1, + 21, 4, 22, 1, 1, 1, 1, 1, 1, 17, 18, 17, 14, 14, 18, 27, + 9, 9, 9, 9, 9, 14, 18, 3, 6, 6, 6, 6, 6, 76, 56, 6, + 1, 1, 1, 1, 1, 1, 21, 4, 1, 1, 1, 1, 1, 1, 41, 39, + 132, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,133, 70, 70, + 1, 1, 1, 1, 1, 29, 10, 16,134, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 17, 14, 14, 14, 14, 30, 1, 4, 61, 10, 10, 10, 10, 10, + 1, 1, 4, 18, 4, 4, 4, 14, 14, 14, 14, 17, 18, 4, 4, 4, + 4, 4, 10, 42, 10, 67, 21, 4, 10, 10, 10, 77, 10, 37, 4, 69, + 1, 34, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 1, 1, 1, + 1, 1, 1, 1, 21, 1, 1, 1, 4, 17, 14, 18, 17, 14, 14, 14, + 14, 17, 14, 14, 18, 4, 4, 4, 3, 3, 10, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 7, 7, 3, 1, 1, 1, 21, 17, 18, 4, 10, + 1, 1, 27, 17, 4, 4, 4, 4, 17, 17, 18, 4, 4, 4, 17, 14, + 10, 10, 10, 42, 10, 10, 10, 10, 4, 4, 4, 4, 4, 4, 4, 78, + 4, 4, 30, 1, 1, 1, 1, 1, 1, 1, 17, 4, 4, 17, 17, 14, + 14, 17, 30, 1, 1, 1, 1, 10, 44, 3, 3, 3, 3, 33, 4, 4, + 4, 4, 3, 3, 3, 3, 47, 10, 27, 4, 4, 14, 4, 18, 4, 1, + 1, 1, 1, 17, 4, 14, 18, 18, 4, 14, 14, 14, 14, 14, 10, 10, + 1, 1, 14, 14, 14, 14, 4, 4, 4, 4, 14, 4, 4, 31, 10, 10, + 9, 9, 9, 9, 9, 9, 99, 1, 6, 6, 6, 6, 19, 6, 6, 6, + 4, 31, 4, 4, 4, 4, 4, 4, 17, 4, 4, 4, 22, 1, 21, 1, + 1, 1, 22, 27, 4, 1, 1, 1, 6, 6, 6, 6, 6, 6, 13, 13, + 13, 13, 13, 13, 13, 56, 6, 6, 6, 6, 6, 6, 56, 6, 6, 6, + 6, 6, 6, 6, 6,101, 13, 13, 12, 12, 12, 6, 6, 6, 6, 12, + 6, 6, 6, 6, 19, 8, 8, 8, 6, 6, 6, 6, 8, 8, 79,102, + 62, 62, 62, 62, 62,135, 15, 15, 26, 26, 26, 10, 45,104, 45,104, + 10, 10, 10, 10,136, 15, 15,137, 10, 10, 10, 10,105,106, 10,107, + 108, 10, 52, 53, 10, 10, 10, 10, 10, 65,108, 10, 10, 10, 10,138, + 139, 13, 7, 7, 7, 11, 52,140, 7, 7, 7, 7, 7, 11, 52, 70, + 4, 4, 4, 4, 4, 4,141, 66, 78, 66, 78, 4, 4, 4, 4, 4, + 3, 71, 3, 80, 3, 19, 8, 6, 8, 12, 80, 3, 75, 8, 8, 3, + 3, 3, 71, 71, 71, 8, 8,142, 8, 8, 50, 1,109, 3, 6, 8, + 11, 11, 75, 6, 6, 36, 3,110, 16,143,144, 16,111, 3, 3, 3, + 11, 11, 35, 3, 3, 11, 3, 3, 35, 36, 3, 35, 3, 3, 3, 35, + 3, 3, 3, 3, 3, 3, 3, 11, 3, 35, 35, 3, 3, 3, 3, 3, + 3, 3, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3, 23, 23, 3, 3, + 11, 3, 3, 3,145,146, 3, 3, 3, 3, 3, 3, 3, 3, 35, 3, + 3, 3, 3, 3, 3, 36, 11, 11, 11, 11, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 11, 11, 11, 3, 3, 3, 3, 3, 3, 3, + 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, + 3, 3, 3, 36, 3, 3, 3, 3, 36, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 11, 11, 11, 11, 3, 3, 3, 3, 3, 3, 3, 36, + 3, 3, 3, 3, 23, 23, 23, 23, 23, 23, 23, 7, 7, 7, 7, 7, + 7, 7, 3, 3, 3, 3, 3, 3, 11, 11, 52,112, 11, 11, 11, 11, + 11, 11, 11, 23, 23, 23, 23, 23, 11, 52, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28,112, 11, 11, 11, 11, 11, 11, 11, 23, 23, 11, 11, + 11, 11, 11, 11, 11, 11, 23, 11, 11, 11, 35, 36, 11, 11, 35, 3, + 12, 8, 12, 19, 19, 19, 19, 8, 12, 12, 19, 6, 6, 6, 13, 8, + 12, 12,110, 3, 3, 80, 19,147, 4, 12, 6, 6, 76, 10, 60, 10, + 1, 1, 1, 1, 1, 1, 1, 34, 10, 10, 10, 10, 10, 10, 10, 37, + 10, 45, 45, 10,105,106, 45, 10, 10, 10, 10, 64, 10, 77, 45, 10, + 45, 23, 23, 23, 23, 10, 10, 42, 10, 10, 10, 10, 10, 26, 10, 10, + 77,148, 10, 10, 10, 10, 10, 10, 3, 10, 81, 28, 28, 28,149, 26, + 72, 10,150,113, 23, 23, 23, 23, 23, 3, 23, 23, 23, 23,114, 70, + 151, 16, 16, 16, 16, 4, 4, 14,115, 13, 13, 3, 16,152, 29, 3, + 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21,153,116, 38, + 1, 1, 1, 1, 1, 29, 13, 38, 3, 7, 7, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1,117, 10, + 12, 12, 12, 12, 12, 12, 12, 21, 66,154, 4, 4, 4, 4, 4, 42, + 12, 12, 12, 12, 12, 12, 13, 4, 1, 1, 1, 16, 16, 16, 16, 16, + 4, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20,116, 13, 13, 13, 13, + 20, 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, + 56, 6, 6, 6, 19, 19, 19, 12, 12, 12, 12, 12, 55,155, 19, 50, + 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 12, + 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 19, 19, 12, 12, + 12, 12, 12, 12, 12, 12, 8, 8, 95, 13,156, 50, 13, 50, 1, 1, + 1, 22, 1, 22, 1, 21, 1, 1, 1, 27, 18, 17, 3, 3, 4, 4, + 7, 7, 7, 3, 82, 3, 3, 3, 1, 1, 10, 10, 10, 10, 10, 10, + 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 14, 14, + 14, 14, 4, 4, 4, 4, 4, 10, 4, 1, 1, 1, 10, 39, 39, 21, + 1, 1, 1, 4, 4, 4, 4, 10, 1, 1, 1, 21, 4, 4, 4, 4, + 4, 14, 14, 14, 14, 14, 14, 61, 1, 21, 14, 4, 4, 14, 4, 14, + 61, 10, 10, 10, 10, 10, 10, 42, 1, 1, 21, 38, 1, 1, 1, 1, + 1, 1, 1, 1, 21, 4, 4, 17, 18, 17, 18, 4, 4, 4, 4, 4, + 1, 21, 1, 1, 1, 1, 17, 14, 9, 9, 9, 9, 9, 9, 10, 10, + 38, 1, 1, 41, 3, 27, 17, 1, 22, 4, 22, 21, 22, 1, 1, 4, + 1, 1, 1, 1, 1, 1, 34, 10, 1, 1, 1, 1, 1, 27, 4, 14, + 10, 34,157, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6,102, 13, 13, + 6, 6, 6, 6,101, 20, 20, 20, 1, 27, 18, 14, 17, 61, 18, 4, + 6, 6, 6, 6, 6, 6, 50, 22, 1, 1, 1, 1,158, 1, 1, 1, + 1, 20, 20, 20, 20, 20, 20, 20, 20, 91, 3, 3, 3, 3, 3, 3, + 3, 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 82, 3, 10, 10, 10, 81, 53, 10, 10, 10, + 64,159,160, 28, 28, 28, 28, 28, 28, 28, 53, 81, 53, 10,107,161, + 10, 10, 10, 10,114, 28, 28, 53, 10,162, 11, 11, 67, 10, 10, 10, + 1, 1, 1, 1, 1, 1, 1,163, 10, 10, 84, 10, 23, 85, 64, 10, + 6, 6, 6, 6, 6, 89, 90, 52, 53, 23, 10, 1, 1, 1, 1, 1, + 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, + 24,164, 57, 24, 36, 11, 35, 3, 3, 3, 3, 3,165, 15, 3, 3, + 10, 10, 10, 60, 7, 7, 7, 7, 7, 7, 7, 43, 3, 3, 3, 3, + 16, 16,111, 7, 43, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3, + 3, 3, 3, 3, 3, 3, 33, 4, 83, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 59, 1,113, 1, 1, 1, 1, 16, 16, 16, + 166, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 12, 6, 6, 6, 6, + 1, 1, 1, 29, 7, 7, 7, 7, 1, 1, 1, 41, 63, 7, 7, 7, + 1, 1, 1, 1, 1, 46, 7, 7, 1, 1, 1, 7, 7, 7, 7, 54, + 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 46, 54, + 1, 1, 1, 1, 58, 1, 1, 1, 1, 1, 21, 4, 4, 83, 7, 7, + 6, 6, 6, 6, 6, 7, 7, 7, 1, 1, 4, 4, 4, 4, 4, 4, + 9, 9, 9, 9, 9, 1, 1, 38, 8, 8, 8, 8,167, 4, 4,115, + 6, 6, 6, 6, 6, 6, 6, 11, 1, 1, 1, 1, 1, 21,168, 26, + 44, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, + 7, 7, 7, 59, 1, 1, 1, 1, 83, 7, 54, 10, 10, 10, 10, 10, + 1, 4, 4, 10, 10, 10, 10, 10, 1, 1, 46, 7, 7, 7, 7, 7, + 18, 30, 1, 1, 1, 1, 1, 1, 4, 4, 4, 31, 10, 10, 10, 10, + 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, + 22, 21, 22, 1, 1, 1, 1, 21, 14, 18, 4, 17, 18, 31, 97, 10, + 10, 4, 4, 4, 4, 4, 96, 15, 1, 1, 1, 21, 4, 4, 18, 4, + 4, 4, 4, 9, 9, 9, 9, 9, 10, 10, 27, 30, 1, 1, 1, 1, + 1, 21, 10, 1, 1, 1, 1, 1, 1, 27, 14, 4, 4, 4, 4, 17, + 30, 1, 29, 10, 37, 4, 31, 18, 9, 9, 9, 9, 9, 29, 29, 10, + 60, 7, 7, 7, 7, 7, 7, 7, 4, 14, 17, 4, 10, 10, 10, 22, + 17, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 27, 14, 14, 30, 1, + 1, 14, 14, 4, 4, 4, 4, 4, 1, 1, 1, 1, 14, 18, 4, 4, + 4, 14, 14, 14, 14, 14, 14, 17, 22, 22, 10, 10, 10, 10, 10, 10, + 37, 4, 4, 4, 4, 4, 4, 4, 1, 1, 27, 14, 4, 4, 4, 4, + 14, 4, 17, 22, 1, 29, 10, 10, 9, 9, 9, 9, 9, 10, 10, 22, + 14, 18, 4, 4, 17, 17, 14, 18, 17, 4, 1, 39, 1, 1, 1, 1, + 14, 4, 4, 4, 14, 14, 4, 18, 31, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 1, 1, 4, 4, 14, 18, 4, 4, 4, 17, 18, 18, + 31, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 14, + 4, 4, 4, 18, 29, 10, 10, 10, 1, 1, 1, 1, 1, 1, 21, 18, + 14, 4, 4, 18, 4, 4, 4, 4, 9, 9, 9, 9, 9, 7, 10, 44, + 4, 4, 4, 4, 18, 31, 10, 10, 7, 7, 7, 7, 7, 7, 7, 59, + 14, 14, 14, 14, 14, 18, 17, 22, 30, 18, 10, 10, 10, 10, 10, 10, + 27, 14, 4, 4, 4, 4, 14, 14, 22, 39, 14, 14, 14, 14, 14, 14, + 21, 4, 4, 4, 4, 22, 1, 1, 1, 21, 4, 4, 17, 21, 4, 31, + 10, 10, 10, 37, 4, 4, 4, 4, 21, 4, 4, 17, 18, 4, 1, 1, + 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 17, 4, 10, 39, 10, + 17, 4, 17, 17, 14, 14, 14, 14, 4, 4, 4, 4, 4, 4, 4, 18, + 10, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 17, 4, 4, 4, + 17, 4, 18, 4, 4, 4, 4, 4, 4, 4, 4, 21, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 14, 14, 14, 4, 17, 18, 18, 1, 1, 1, 1, + 1, 1, 1, 1, 34, 1, 1, 1, 1, 21, 17, 61, 10, 10, 10, 10, + 4, 27, 1, 1, 1, 1, 1, 1, 1, 1, 14, 4, 4, 4, 4, 14, + 17, 31, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 4, 4, 4, + 7, 7, 43, 3, 3, 3, 57, 24, 82, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 47, 22, 1, 1, 21, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 14, 18, 4, 4, 4, 31, 10, 10, 10, 10, 10, + 4, 4, 4, 31, 10, 10, 3, 3, 13, 13, 44, 3, 3, 3, 3, 3, + 9, 9, 9, 9, 9,169, 7, 7, 7, 59, 1, 1, 1, 1, 1, 1, + 13, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 34,117, 10, + 7, 7, 7, 54, 10, 10, 10, 10, 8, 8, 8, 8, 8, 12, 6, 6, + 27, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, + 4, 68, 13, 13, 13, 13, 13, 13, 13, 42, 4, 4, 4, 4, 4, 4, + 14, 13, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 33, 31, + 3, 3,118, 18, 4, 3,118, 14, 14,170, 15, 15, 15, 69, 4, 4, + 4, 40, 33, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 3, + 3, 4, 40, 3, 3, 3, 3, 3, 48, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 49, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 48, 6, 6, 6, 6, 49, 6, 6, 6, 8, 8, + 8, 8, 48, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 49, + 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 48, + 6, 6, 6, 6, 49, 6, 6, 6, 8, 8, 8, 8, 48, 6, 6, 6, + 6, 49, 6, 6, 6, 12, 6, 9, 4, 4, 4, 40, 3, 33, 4, 4, + 4, 4, 4, 4, 4, 4, 40, 3, 3, 3, 33, 3, 3, 3, 3, 3, + 3, 3, 40, 47, 10, 10, 10, 10, 10, 10, 10, 10, 10, 37, 4, 4, + 6, 6, 6, 6, 6,109, 6, 6, 4, 4, 4, 68, 13, 13, 13, 13, + 9, 9, 9, 9, 9, 9, 9, 41, 1, 1, 1, 1, 1, 1, 4, 4, + 9, 9, 9, 9, 9, 9, 9,171, 1, 1, 1, 1, 1, 34, 4, 4, + 172, 9, 9, 9, 9, 9, 9, 98, 1, 21, 1, 22, 1, 1, 1, 4, + 1, 1, 21, 4, 4, 4, 4, 34, 6, 6, 4, 4, 4, 68, 13, 13, + 7, 7, 7, 7, 7, 7, 63, 7,173, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 63, 7, 7, 7, 7, 7, 7, 43, 3, + 3, 3, 3, 3, 3, 92, 20, 20, 2, 2, 7, 7, 3, 3, 26, 26, + 12, 12, 4, 4, 5, 5, 15, 15, 9, 9, 13, 13, 21, 21, 25, 25, + 9, 5, 6, 6, 10, 10, 1, 1, 14, 14, 12, 10, 10, 12, 5, 9, + 24, 24, 7, 12, 12, 7, 22, 18, 23, 23, 0, 0, 17, 17, 7, 10, + 18, 22, 7, 21, 10, 7, 12, 21, 8, 8, 26, 12, 7, 6, 25, 26, + 26, 25, 21, 12, 6, 7, 21, 7, 12, 26, 7, 26, 21, 6, 15, 26, + 21, 26, 20, 19, 7, 15, 26, 21, 9, 25, 5, 25, 5, 7, 6, 12, + 25, 22, 18, 21, 15, 21, 6, 24, 6, 5, 26, 23, 26, 7, 15, 7, + 21, 15, 10, 21, 29, 29, 26, 15, 21, 17, 25, 21, 11, 11, 21, 23, + 12, 6, 1, 12, 18, 18, 9, 26, 29, 21, 21, 9, 24, 5, 25, 9, + 5, 21, 17, 21, 11, 12, 8, 24, 26, 9, 21, 22, 23, 26, 12, 15, + 23, 21, 21, 25, 9, 22, 21, 18, 24, 16, 5, 22, 25, 18, 24, 26, + 26, 24, 9, 8, 8, 5, 9, 6, 12, 1, 21, 1, 13, 21, 13, 7, + 17, 7, 5, 6, 5, 24, 9, 24, 22, 20, 21, 20, 19, 21, 21, 16, + 16, 21, 7, 5, 5, 26, 14, 15, 18, 25, 7, 14, 17, 22, 17, 6, + 24, 6, 6, 21, 26, 10, 25, 0, 7, 20, 25, 1, 24, 15, 7, 19, + 9, 21, 17, 26, 23, 12, 17, 12, 1, 21, 24, 7, 23, 7, 12, 23, + 29, 7, 7, 22, 14, 7, 29, 1, 27, 28, 1, 29, 21, 29, 15, 6, + 18, 6, 12, 11, 26, 5, 14, 9, 5, 14, 26, 22, 18, 26, 5, 12, + 22, 21, 18, 17, 26, 6, 26, 14, 14, 6, 12, 24, 11, 21, 24, 9, + 6, 9, 6, 10, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, + 25, 24, 26, 1, 21, 14, 9, 12, 12, 17, 13, 15, 10, 1, 13, 23, + 7, 13, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, + 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 0, 0, 36, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, - 0, 0, 0, 0, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, - 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, - 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, - 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, - 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, - 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, - 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, - 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 76, 77, 0, 78, - 79, 0, 0, 80, 81, 0, 82, 62, 0, 83, 84, 0, 0, 85, 86, 87, - 0, 88, 0, 89, 0, 90, 0, 0, 51, 91, 51, 0, 92, 0, 93, 0, - 0, 0, 81, 0, 0, 0, 94, 95, 0, 96, 97, 98, 99, 0, 0, 0, - 0, 0, 51, 0, 0, 0, 0,100,101, 0, 0, 0, 0, 0, 0,102, - 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0,104,105, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, 0, - 0, 0,111, 0,112, 0,105, 0, 0, 0, 0, 0,113,114, 0, 0, - 0, 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0,118, - 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, - 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, - 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, - 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, - 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, - 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, - 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, - 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, - 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, - 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, - 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, - 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, - 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, - 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, - 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, - 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, - 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, - 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, - 99, 0, 0, 0,100, 0, 0, 0, 0,101,102, 93, 0, 0,103, 0, - 0, 0, 84, 0, 0,104, 0, 0, 0,105,106, 0, 0,107,108, 0, - 0, 0, 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 33, 0, - 112,113,114, 57, 0, 0,115, 35, 0, 0,116, 0, 0, 0,117, 0, - 0, 0, 0, 0, 0,118, 0, 0,119, 0, 0, 0, 0,120, 88, 0, - 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,121, 0, 0, 0, 0,122, - 0, 0,123, 0, 0, 0, 0,121, 0, 0,124, 0, 0, 0, 0, 0, - 79, 0, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0,127, 0,128, - 0, 0, 0, 0,129,130,131, 0,132, 0,133, 0, 0, 0,134,135, - 136, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 0, - 138, 0, 0, 0,139, 0, 0,140, 0, 0,141, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, - 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, - 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, - 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, - 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, - 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, 0, 19, 52, 1, 0, 0, - 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, - 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, - 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, - 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, - 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, - 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, - 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, - 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, - 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, - 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, - 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, - 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, - 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0, - 101,102, 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, - 0, 0, 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, - 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, - 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0, - 109, 61, 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 49, 50, 0, 0, - 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, 62, 0, - 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, - 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, 0, 38, - 1, 58, 1, 58, 0, 0, 0, 0, 0, 88, 63, 89, 0, 0,115, 0, - 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, - 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, - 0, 0, 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, - 0,117, 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, - 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, - 87, 0, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,112, 4,122, - 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230,230,232, - 220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220, - 220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220,220,230, - 230,230,230,240,230,220,220,220,230,230,230,220,220, 0,230,230, - 230,220,220,220,220,230,232,220,220,230,233,234,234,233,234,234, - 233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230,230,230, - 222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0,230,220, - 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, - 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, 0, 0, - 230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, 0, 36, - 0, 0,230,220,230,230,220,220,230,220,220,230,220,230,220,230, - 230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230,230,230, - 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, 27, 28, - 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, - 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, - 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, - 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, - 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, - 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, 0,228, - 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220,230,220, - 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0,230, 0, - 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230,230,230, - 232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, 1, 1, - 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228,232,222, - 224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230,220, 0, - 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230, - 220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, 0, 7, - 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, 0,216, - 216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0,220,220, - 220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, 17, 49, - 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, - 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, - 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, - 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, - 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, - 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, - 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, - 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, - 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, - 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, - 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, - 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, - 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, - 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, - 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, - 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, - 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, - 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, - 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, - 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, - 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, - 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, - 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, - 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, - 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, - 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, - 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, - 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, - 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, - 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, - 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, - 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 3, 3, 3, 3, 3, 3, - 3, 15, 3, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, - 18, 17, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 25, 25, 26, 27, - 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 31, - 31, 31, 31, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 57, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 58, 31, 31, 31, - 59, 60, 61, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 64, 65, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 66, 67, 68, 31, 31, 31, 31, 69, 31, 31, 31, 31, 31, - 31, 31, 17, 70, 71, 72, 17, 17, 73, 74, 31, 75, 76, 77, 78, 79, - 80, 31, 81, 82, 17, 83, 17, 17, 17, 17, 31, 31, 23, 23, 23, 23, - 23, 23, 23, 84, 31, 31, 31, 31, 23, 84, 31, 31, 23, 23, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 85, 0, 0, 1, - 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, - 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 11, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 19, 27, - 28, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, - 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 42, 43, 44, 44, 45, 46, - 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 49, 50, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 51, - 60, 61, 62, 63, 64, 65, 66, 7, 67, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 7, 4, 4, 4, 4, 77, 77, 77, 77, 78, 79, 80, 81, - 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, - 0, 0, 0, 0, 86, 87, 88, 88, 89, 90, 48, 91, 0, 0, 92, 92, - 92, 92, 92, 93, 94, 95, 96, 97, 98, 47, 99,100,101,102, 0,103, - 104,105, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 0,106,106,106,106,106,106,106,106,106,106,106,107, - 108,108,108,108,108, 11,109,110,111, 4,112, 4,113,114,115,116, - 117,118,119,120,121,122,123,124,125,126, 50,127, 47, 47, 47, 47, - 47, 47, 47, 47,128,128,128,128,128,128,128,128,128,128,128,128, - 92, 92, 92, 92, 92, 92, 92, 92,129,130, 19, 19, 19, 19, 19, 19, - 131, 19, 19, 19,132,133, 19,134,135,136,137,101,138,138,138,138, - 0, 77,139,140,128,128,141,142,143,144,145,146,147,148,149,150, - 151,152,153,154,155,155,155,155,155,155, 4, 4,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,170,171,171,172,172, - 173,174,174,174, 19, 19,175,176,177,178,179,180,181,181,182,183, - 184,185,186,187,188,188,189,190,191,192,193,193,194,194,195,195, - 128,128,196,196,197,198,199,200,201,201,128,128,202,202,203,203, - 204,204,205,205,206,207,208,209, 28, 28,210,210,211,212,213,213, - 214,215,216,216,128,128,217,217,218,218,219, 34,220,220,220,220, - 220,220,220,220,220,220,220,220,220,220,128,128,128,128,128,128, - 128,128,221,221,222,222,222,222,222,222,222,222,223,223,223,223, - 223,223,223,223,223,223,128,128,128,128,128,128,128,128,128,128, - 224,224,128,128,110,110,110,110,110,110,110,110,110,225,226,227, - 228,228,228,228,128,128,128,128,229,229,128,128,230,230,230,230, - 231,231,231,232,233,233,233,233,233,233,233,233,233,233,233,233, - 234,234,234,234,234,234,234,234,233,233,128,128,128,128,128,128, - 128,128,104,104,235,236,236,236,237,238,239,239,239,239,239,239, - 128,128,128,128,240,240,241, 0,128,128,128,128, 0, 0, 0, 0, - 7,242, 0, 0, 0, 0, 0, 0, 0,243,244, 0, 77, 77, 0, 0, - 0, 0,128,128,245,245,245,245,245,245,245,245,245,245,245,245, - 128,128,128,128,128,128,128,128, 4, 4,128,128,246, 11, 11, 11, - 247,247,128,128,128,128,248,249,128,128,128,128,128,128,250,250, - 128,128,251,251,128,128,128,128,128,128, 48, 48,252,252,252,252, - 253,253,128,128, 0, 0, 0, 0, 0, 0,128,128, 19, 19, 19, 19, - 128,128,128,128,254, 0,128,128, 0, 0, 0, 0, 92, 92,128,128, - 128,128,128,128, 0, 0,128,128, 7, 7, 7, 7, 0, 0, 0, 0, - 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, - 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, - 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 14, 13, 13, 13, - 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, - 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, - 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, - 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 31, 21, 32, 32, 32, 32, - 32, 33, 34, 32, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, - 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, - 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44, - 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49, - 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 53, 53, 53, 53, - 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 57, 57, - 57, 57, 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64, - 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 67, 67, 67, 67, - 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 8, 72, 72, 72, 72, 73, 73, 73, 73, - 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, - 73, 77, 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84, - 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, - 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, - 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, - 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 13, 13, 94, 94, 94, 94, - 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102, - 102,102,102,103,104,104,104,105, 52, 0,104,104, 0, 0, 0,102, - 52, 52, 0, 0, 0, 0, 52,106, 0,102,102,107,102,102,102,102, - 102,108, 0, 0,109,109,109,109,109,110,110,110,111,111,111,111, - 13, 13,112,112,112,112,112,112, 0, 0,113, 4,114, 4, 4, 4, - 115,115,115, 0,116,116,116,116,117,117,117,117,117,117, 32, 32, - 118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, 49, 49, - 123,123,123,123,123,123, 49, 49,124,124,124,124,124,124,125,125, - 53, 53, 53, 4, 4,126,127, 54,125,125,125,125,128,128,128,128, - 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21,130, 8, 0,131, 0, - 0, 0, 0, 21, 21, 21, 21,132, 0, 0, 1, 2, 1, 2,133,101, - 102,134, 52, 52,135,135,135,135, 11, 0, 11, 11, 11, 0, 0,136, - 137,137,138,138,138,138,139, 0,140,140,140,141,141,142,142,142, - 143,143,144,144,144,144,144,144,145,145,145,145,145,146,146,146, - 147,147,147,148,148,148,148,148,149,149,149,150,150,150,150,151, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,156,156,157,157,157,157,157,157,158,158,159,159,160,160, - 160,160,160,160,161,161,162,162,162,162,162,162,163,163,163,163, - 163,163,164,164,165,165,165,165,166,166,166,166,167,167,167,167, - 168,168,169,169,170,170,170,170,171,171,171,171,172,172,172,172, - 173,173,173,173,174,174,174,174,175,175,175,175,176, 21, 21, 21, - 177,177,177,178,178,178,178,179,179,179,179,180,180,180,181,181, - 182,182,182,182,183,183,183,183,183,184,184,184,185,185,185,185, - 185,186,186,186,187,187,187,187,187,187,188, 43,189,189,189,189, - 190,190,190,191,191,191,191,191,192,192,192,193,192,192,192,192, - 194,194,194,194,195,195,195,195,196,196,196,196,197,197,197,197, - 198,198,198,198,198,198, 66, 66,199,199,199,199,199, 49, 49, 49, - 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, - 204,204,204,204,205,205,205,205,205,206,206,206,206,206,206, 55, - 207,207,207,207,208,208,208,208,209,209,209,209,209,209,209,210, - 210,210,210,210,211,211,211,211,211,211,212,212,212,212,212,212, - 213,213,213,213,214,214,214,214,110,110,110,110,215,215,215,215, - 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, - 220,220,220,221,221,221,221,221,221,222,222,222,223,223,223,223, - 224,224,224,224,225,225,225,225,226,226,226,226,226,226,227, 94, - 228,228,228,228,229,229,229,229,230, 99, 99, 99, 99, 99, 99, 99, - 99, 99,102,231, 99,232,102,233,233,233,233,233,234,234,234,234, - 234,234, 0, 0, 8, 0, 0, 0, 0, 0,235,236,237, 0,238, 0, - 239,239,239,239, 91, 91, 91, 13,240,240,240,240,241,241,241,241, - 242,242,242,242,243,243,243,243,244,244,244,244,245,245,245,245, - 246,246,246,246,247, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, - 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, - 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, - 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, - 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, - 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, - 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, - 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, - 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, - 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, - 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, - 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, - 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, - 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, - 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, - 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, - 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, - 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, - 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, - 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, - 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, - 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, - 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99, - 100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0,100, 0, - 105,106,106,106,106,106,106,106,106,106,107,105,108,109,109,109, - 109,109,109,109,109,109,110,108,111,111,111,111,112, 55, 55, 55, - 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114,114,114, - 115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, 2, 2, - 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120,120,120, - 121,121,121,121,121,121,121,122,123,123,123,123,124,124,124,124, - 124,124,124,125,126,126,126,126,127,127,127,127,128,128,128,128, - 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, 17, 18, - 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109, - 109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139,139,139, - 140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142,142,142, - 143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146, - 147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150, - 151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154, - 155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158, - 159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162, - 163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166, - 167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170, - 171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174, - 175,175,175,175,176,176,176,176,177, 20, 20, 20,178,178,178,178, - 179,179,179,179,180,180,180,180,181,181,181,181,182,182,182,182, - 183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186, - 187,187,187,187,188,188,188,188,189, 45, 45, 45,190,190,190,190, - 191,191,191,191,192,192,192,192,193,193,193,193,193,193,194,193, - 195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198, - 199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202, - 203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206, - 207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210, - 211,211,211,211,212,212,212,212,213,213,213,213,214,214,214,214, - 215,215,215,215,216,216,216,216,217,217,217,217,218,218,218,218, - 219,219,219,219,220,220,220,220,221,221,221,221,222,222,222,222, - 223,223,223,223,224,224,224,224,225,225,225,225,226,226,226,226, - 227,227,227,227,228,229,229,229,230,230,230,230,229,229,229,229, - 231,106,106,106,232,106,106,106,106,233,109,109,234,234,234,234, - 235,235,235,235, 0,236, 86, 0, 0, 0,236, 7, 82,138, 7, 0, - 0, 0,237, 86,238,238,238,238,239,239,239,239,240,240,240,240, - 241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244, - 245,245,245,245,246, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, - 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, - 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, - 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, - 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, - 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, - 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, - 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, - 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, - 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, - 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, - 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, - 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, - 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, - 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, - 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, - 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, - 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, - 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, - 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, - 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, - 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, - 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, - 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, - 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, - 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, - 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, - 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, - 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, - 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, - 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, - 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, - 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, - 106,106,106,106,104,104,104,104,161,161,161,161,170,170,170,170, - 110,110,110,110, 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120, - 116,116,116,116,128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, - 98, 98, 98, 98, 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88, - 117,117,117,117,112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, - 82, 82, 82, 82,122,122,122,122, 89, 89, 89, 89,130,130,130,130, - 144,144,144,144,165,165,165,165,156,156,156,156,156,156, 3, 3, - 147,147,147,147,148,148,148,148,158,158,158,158,153,153,153,153, - 149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, - 96, 96, 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36, - 108,108,108,108,129,129,129,129,109,109,109,109,107,107,107,107, - 107,107,107, 1,171,171,171,171,137,137,137,137,124,124,124,124, - 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, - 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, - 141,141,141,141,140,140,140,140,121,121,121,121,169,169,169,169, - 133,133,133,133,134,134,134,134,138,138,138,138,143,143,143,143, - 145,145,145,145,163,163,163,163, 63, 63, 63, 63,157,157,157,157, - 80, 80, 80, 80,127,127,127,127,166,166,166,166,115,115,115,115, - 159,159,159,159,103,103,103,103,119,119,119,119,167,167,167,167, - 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, - 136,136,136,136, 17, 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, - 139,139,139,139,105,105,105,105, 0, 0, 0, 1, 0, 0, 1, 1, - 131,131,131,131,151,151,151,151,160,160,160,160,152,152,152,152, - 164,164,164,164,168,168,168,168,113,113,113,113,132,132,132,132, - 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, - 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 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, - 16, 17, 9, 9, 9, 9, 18, 9, 9, 9, 9, 9, 19, 20, 21, 9, - 22, 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, 23, 9, 9, 9, 9, 9, 24, 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, 25, 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, 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, - 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, - 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, - 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, - 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, - 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, - 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, - 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, - 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, - 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, - 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, - 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0, - 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, - 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, - 0, 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193, - 194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, - 210,211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 3, 4, + 0, 0, 0, 0, 41, 42, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 9, 0, 0, 0, 10, + 11, 12, 13, 0, 14, 15, 16, 0, 17, 18, 19, 20, 21, 1, 22, 1, + 23, 1, 2, 1, 2, 1, 2, 0, 2, 1, 24, 1, 2, 25, 2, 0, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 36, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 38, 0, 0, + 39, 0, 0, 40, 0, 41, 0, 0, 0, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 0, 0, 51, 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 3, 0, 55, 56, 0, 57, 0, 0, 0, 0, + 0, 0, 58, 59, 60, 0, 0, 0, 0, 61, 0, 0, 62, 63, 64, 4, + 65, 0, 0, 66, 67, 0, 0, 0, 68, 0, 0, 0, 0, 69, 0, 0, + 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 71, 0, 0, 0, 72, 0, 73, 0, 0, 74, 0, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 76, 77, 0, 0, 0, 0, 78, 79, 0, 80, 81, + 0, 0, 82, 5, 0, 83, 4, 0, 84, 85, 0, 0, 86, 87, 88, 0, + 89, 0, 90, 0, 91, 0, 0, 3, 92, 3, 0, 93, 0, 94, 0, 0, + 0, 5, 0, 0, 0, 95, 96, 0, 97, 98, 99,100, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0,103, 0, + 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,106, 0, 0,107, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,108,109, 0, 0,110, 0, 0, 0, 0, 0, + 0,111, 0,112, 0, 6, 0, 0, 0, 0, 0,113,114, 0, 0, 0, + 0, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0, + 0, 0, 0, 0,118, 0,119, 0, 0, 0, 0, 0, 0, 0, 2, 1, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 14, 0, + 0, 0, 16, 3, 17, 18, 19, 20, 21, 22, 0, 23, 0, 0, 0, 0, + 24, 25, 26, 27, 0, 0, 0, 0, 28, 0, 0, 29, 30, 0, 31, 0, + 32, 33, 0, 0, 34, 0, 35, 36, 0, 0, 0, 0, 0, 37, 38, 0, + 39, 40, 0, 0, 41, 0, 0, 0, 42, 0, 0, 43, 44, 45, 46, 1, + 47, 0, 0, 1, 0, 0, 7, 1, 48, 0, 0, 0, 0, 0, 49, 50, + 0, 0, 0, 0, 0, 0, 51, 52, 0, 0, 0, 0, 0, 0, 53, 54, + 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 57, 58, 0, 0, 0, 59, + 0, 0, 0, 0, 0, 0, 60, 12, 0, 0, 0, 0, 61, 0, 0, 0, + 62, 0, 5, 0, 63, 0, 0, 0, 0, 64, 0, 0, 0, 0, 65, 0, + 66, 0, 0, 0, 0, 6, 67, 0, 0, 0, 68, 69, 70, 71, 0, 0, + 0, 0, 72, 5, 0, 73, 74, 0, 0, 75, 0, 0, 0, 76, 77, 0, + 0, 0, 78, 0, 79, 80, 81, 82, 83, 3, 84, 0, 85, 86, 87, 0, + 0, 8, 9, 0, 0, 3, 3, 0, 0, 88, 0, 0, 89, 0, 0, 0, + 0, 8, 90, 0, 91, 0, 0, 0, 0, 0, 9, 10, 0, 92, 0, 5, + 0, 3, 9, 0, 0, 93, 0, 0, 94, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 95, 96, 0, 0, 10, 0, 0, 1, 0, 0, 97, 0, 0, 0, + 0, 98, 0, 0, 0, 0, 12, 0, 0, 13, 0, 0, 0, 0, 99,100, + 0, 0,101, 0, 0,102, 0, 0, 0,103, 0, 0, 0,104, 0, 0, + 0,105, 0, 0, 0, 0,106,107, 13, 0, 0,108, 0, 0, 0, 10, + 0, 0,109,110, 0, 0,111,112, 0, 0, 0, 0, 0, 0,113, 0, + 0,114, 0, 0, 0, 0,115, 1, 0,116,117,118, 6, 0, 0,119, + 7, 0, 0,120, 0, 0, 0,121, 0, 0, 0, 0, 0, 0,122, 0, + 0,123, 0, 0, 0, 0,124, 11, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 5, 15, 0, 0, 0, 0,125, 0, 0,126, 0, 0, 0, 0, + 15, 0, 0,127, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,128, 0, + 0, 0,129, 0,130, 0, 0, 0, 0,131,132,133, 0,134, 0,135, + 0, 0, 0,136,137,138, 0, 8, 0, 0, 0, 0, 0, 7, 0, 0, + 0,139, 0, 0, 0,140, 0, 0, 0,141, 0, 0, 0,142,143, 0, + 144, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 9, + 1, 1, 1, 1, 0, 0, 0, 2, 0, 3, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 19, 0, 0, 0, 6, 11, 0, 0, 0, 0, 14, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 17, 29, 0, 0, 0, 0, 0, 31, 0, + 0, 2, 0, 0, 1, 12, 0, 0, 1, 49, 50, 5, 51, 52, 53, 5, + 5, 22, 32, 23, 1, 54, 24, 55, 16, 33, 56, 57, 58, 1, 1, 1, + 6, 1, 0, 0, 59, 7, 60, 1, 34, 5, 7, 61, 62, 63, 64, 65, + 66, 67, 0, 0, 1, 1, 68, 0, 0, 0, 69, 70, 71, 35, 1, 25, + 72, 0, 0, 0, 0, 8, 1, 26, 16, 26, 73, 27, 74, 0, 0, 0, + 36, 25, 75, 37, 7, 37, 76, 0, 0, 0, 6, 1, 7, 0, 0, 17, + 0, 8, 38, 1, 1, 13, 13, 11, 0, 0, 39, 0, 0, 6, 18, 1, + 0, 0, 8, 16, 5, 1, 1, 1, 77, 7, 36, 18, 78, 7, 35, 1, + 79, 10, 0, 0, 0, 80, 0, 0, 0, 0, 2, 3, 0, 0, 14, 0, + 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 83, 0, 0, 0, 84, 0, + 0, 0, 40, 0, 0, 85, 86, 0, 87, 88, 89, 90, 91, 92, 0, 0, + 0, 93, 0, 0, 0, 15, 28, 0, 0, 0, 0, 13, 0, 41, 0, 0, + 14, 0, 0, 20, 0, 0, 94, 0, 0, 0, 95, 0, 0, 6, 29, 0, + 0, 13, 1, 96, 1, 18, 33, 97, 25, 23, 7, 1, 1, 1, 1, 27, + 1, 7, 98, 0, 0, 9, 0, 0, 0, 0, 6, 23, 1, 0, 0, 0, + 0, 0, 30, 0, 0, 21, 0, 0, 30, 0, 0, 0, 0, 15, 0, 0, + 12, 32, 24, 5, 99, 22, 42, 17, 0, 10, 11, 0, 7, 1, 7,100, + 101, 1, 1, 1, 1,102,103,104,105, 1,106, 10, 20,107,108, 5, + 10, 0, 0, 0, 0, 0,109,110, 0, 0,111, 0, 0, 1, 1, 11, + 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 43, 40, 2, 0, 0, 0, + 44,112, 10, 8, 20, 0, 0, 0, 0, 0, 0,113, 1, 16, 5, 24, + 0, 8, 12, 0, 0, 0, 0,114, 0, 0,115, 2, 0,116, 0, 0, + 0, 1, 0, 0, 0, 0, 13, 11, 0, 0, 6, 10, 0, 0, 45, 39, + 0, 45, 16, 18, 46, 27, 0, 0, 3, 0, 0, 2, 12, 0, 0, 0, + 2, 3, 0, 0, 3, 0, 21, 0, 0, 31, 0, 0, 0, 0,117, 0, + 0, 0, 15, 9, 0, 8, 1, 10, 1, 10, 0, 0, 0, 0, 0, 30, + 14, 21, 0, 0, 47, 0, 0, 0, 9, 0, 0, 0, 0, 47, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 28, 0, 0, 4, 0, 21, 41, 0, 0, + 28, 0, 0, 0, 22, 42, 0, 0,118, 0, 0, 0, 0, 0, 0,119, + 0,120,121,122,123, 0, 43, 5, 48, 13, 34, 0, 0, 0, 8, 11, + 8, 10, 0, 0, 1, 12, 1, 1, 1, 1, 26, 1, 38, 44, 12, 0, + 0, 0, 0, 1, 0, 0, 0,124, 0, 0, 0, 46, 6, 19, 0, 8, + 0, 20, 0, 0, 5, 48, 0, 0, 0, 1,125, 0, 0, 0, 0,230, + 230,230,230, 0, 0, 0, 9, 9, 0, 0, 0, 0, 9, 0, 0,220, + 220,220,220, 0, 0, 0,230,230,230,220,230, 0, 0,230,230, 7, + 0, 0, 0,230, 0, 0, 0,230,230, 0, 0,230,230,230, 0, 0, + 230,230,230, 0, 0, 9, 0, 0, 0, 0, 7,230,230,230,220, 0, + 220, 0, 0,230,220,220,220, 0, 0,230, 0, 0,230, 0, 0, 0, + 0, 7, 0, 1, 1, 1, 1,220,230,230,230,220,220,230,230,220, + 230,230,220,230, 0, 0,230,230,220, 0, 0, 0, 9, 9, 0,220, + 0, 0, 0, 0, 0, 9, 9, 0, 9, 7, 0, 1,220,220,220,220, + 220,220,230,230,230,220,220,230,220,220,230,230,220,230,230,220, + 230,220,230,230,230, 0,230, 0,220,220,220,220,220, 0, 0, 9, + 9, 0, 0, 1, 0, 0, 0, 0, 0, 0,220,230, 0,230,230, 0, + 0,220,220, 0, 0,230,220, 0, 0, 9, 7,220,220,220, 0,230, + 232,220,220,220,220,232,216,220,202,202,220,220,220,220,202,202, + 220,220,220,230,240,230,220,230,220,220, 0,232,220,220,230,233, + 234,234,233,234,234,233,230, 0,220,230,230,230,230,222,220,230, + 222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, + 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, + 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230, 35, 0, 0, 0,230, + 0,220,230, 0, 36, 0, 0,220,220,230,220,220,230,230, 0,230, + 230, 0,220, 27, 28, 29,230, 0,230,220,230, 0, 84, 91, 0,103, + 103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, 0, + 220, 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, + 0,130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, + 0,220, 0, 0,228, 0, 0, 0,222,230,220,230, 0, 0,220,230, + 220, 0,220,230,230,230,234,230, 0, 1, 1,230,234,214,220,202, + 230,230,230,230,230,232,228,228,220,218,230,233,220,230,220,230, + 230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, + 0,218,228,232,222,224,224, 0, 8, 8, 0,220, 0, 0,230, 0, + 0, 26, 0, 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, + 7, 9, 0, 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, + 1, 0, 0, 0,226,216,216,216,216,216, 0,232,232,220,230,230, + 230, 7, 0, 1, 0, 0, 32, 0, 48, 0, 0, 84, 96,135,144, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,176, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 40, 0, 0, + 0, 0, 0, 48, 56, 64, 0, 0, 0, 0, 0, 72, 80, 88, 96,104, + 0, 0, 0, 0, 0, 0, 0, 0,112, 0,120, 0, 0, 0, 0, 0, + 0,128,136,144,152,160,168, 0, 0, 0,176,184,192, 0, 0, 0, + 0, 0, 0,200, 0, 0, 0, 0, 0, 0, 0, 0,208, 0, 0,216, + 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, + 36, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 64, 0, + 68, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 72, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 40, 20, 0, 0, 0, 0, 0, 0, + 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 76, 80, 84, 88, 0, 0, + 12, 92, 96, 28, 0,100,104, 4, 4, 4,108, 44,112,116,120, 4, + 124, 0,128,132, 4, 4, 48,136,140, 0, 32, 0, 0, 0, 40, 0, + 0, 0, 0, 0, 0, 0, 4, 48, 0, 52,144, 20,148,152, 4, 0, + 0,156,160,164,168,172, 4, 0,176, 56, 60,180, 32, 0, 16,184, + 56, 0, 0, 0, 0, 0, 52, 12, 12, 0, 0, 0, 0, 12, 0, 0, + 188, 8, 8, 8, 8,192,196, 8, 8, 8, 8,200,204,208,212, 60, + 44, 0, 0, 0, 0, 0, 0, 0,216, 28,220, 0, 12, 4, 16, 0, + 0, 0, 0,224,228, 0, 0, 0, 0, 0, 4,232, 32, 0, 0, 0, + 0, 0, 0, 0,236, 12, 0, 0, 0, 0, 16, 0, 36, 0, 0, 0, + 24, 0, 0, 0,240,244, 0, 0, 0, 0, 2, 2, 2, 2, 4, 4, + 4, 4, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 6, 8, 0, 10, + 12, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 14, 16, 6, 8, + 0, 0, 4, 8, 0, 0, 2, 2, 2, 0, 0, 6, 4, 8, 2, 0, + 2, 0, 0, 0, 0, 6, 0, 20, 0, 0, 0, 22, 0, 0, 0, 6, + 8, 0, 24, 26, 28, 0, 0, 0, 30, 0, 0, 0, 0, 32, 34, 36, + 38, 0, 0, 40, 42, 0, 0, 0, 18, 0, 0, 0, 2, 2, 2, 2, + 0, 2, 2, 2, 0, 6, 44, 0, 0, 0, 0, 2, 0, 46, 48, 50, + 0, 0, 52, 0, 0, 0, 6, 4, 54, 0, 2, 0, 0, 2, 2, 56, + 58, 60, 0, 62, 64, 18, 2, 10, 12, 0, 0, 0, 66, 8, 0, 2, + 2, 2, 0, 6, 4, 4, 4, 4, 68, 2, 70, 4, 4, 4, 8, 72, + 0, 0, 74, 76, 2, 0, 78, 0, 0, 0, 4, 8, 2, 0, 0, 0, + 80, 0, 6, 4, 4, 4, 4, 8, 0, 2, 2, 2, 2, 6, 4, 4, + 4, 8, 0, 0, 0, 82, 0, 84, 86, 0, 0, 0, 2, 88, 0, 0, + 0, 90, 6, 8, 2, 0, 0, 0, 6, 4, 4, 4, 8, 0, 2, 0, + 2, 2, 6, 4, 4, 8, 0, 10, 12, 6, 8, 2, 0, 0, 50, 84, + 118,152, 17,161, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 5, 16, 17, 18, 1, 1, 1, 1, 1, 1, 19, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 20, 21, 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 0, 35, 4, 4, 4, 4, 4, 36, 0, 0, 0, + 0, 0, 0, 37, 0, 38, 39, 3, 3, 3, 3, 3, 3, 40, 41, 0, + 0, 0, 0, 0, 0, 0, 42, 43, 0, 0, 44, 0, 0, 0, 45, 46, + 5, 47, 48, 49, 50, 51, 52, 53, 5, 5, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 6, 0, 0, 6, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 54, 0, 0, 55, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, + 3, 3, 3, 1, 1, 1, 1, 1, 0, 0, 0, 26, 27, 8, 8, 8, + 28, 29, 30, 19, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 2, 2, 13, + 13, 13, 56, 11, 11, 11, 11, 11, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 8, 8, 16, 16, 72, 73, 74, 75, 3, + 3, 3, 3, 20, 20, 3, 3, 3, 3, 3, 3, 76, 77, 78, 79, 3, + 1, 1, 80, 81, 82, 83, 84, 85, 86, 87, 3, 1, 1, 1, 88, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 89, 21, 21, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, 0, 0, 1, 1, 1, + 1,102, 9, 9, 9,103, 9,104,105,106,107, 22, 22,108,109, 0, + 110,111,112,113,114,115,116, 17, 17, 17, 8,117,118,119,120,121, + 122,123,124,125,126,127,128, 9,129,130,131,132,133,134,135,136, + 137,138,139,140,141, 0,142,143,144,145, 0,146,147,148,149,150, + 151,152,153,154,155,156,157, 0,158,159,160, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,161, 12, 12, 12, 12, 12, 0, 0, 0, 0, 0,162, 0, 0, + 0, 0, 0, 14, 14, 14, 14,163,164, 23, 23, 0, 0,165, 0,166, + 167,168,169, 4, 4, 4, 4, 4, 4, 15, 15, 15, 15, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,170,171,172,173, 18, 18, + 18, 0, 0,174,175, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, + 3,176, 3, 3, 3,177,178, 16, 3, 3, 0, 10, 10, 10, 10, 10, + 10, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,179, 19,180, 0, 0, + 181, 0, 0, 0,182, 0,183, 0,184, 0, 13, 24, 24,185, 0, 0, + 0, 0, 0, 3, 3, 3, 0, 9, 9, 0, 0, 3, 3, 3, 3,186, + 0, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 25, 25, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 7, + 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 12, 12, 12, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 18, 18, 18, 18, 18, 18, 18, 18, 17, + 17, 17, 17, 17, 17, 17, 17, 20, 20, 20, 20, 20, 20, 20, 20, 19, + 19, 19, 19, 19, 19, 19, 19, 15, 15, 15, 15, 15, 15, 15, 15, 25, + 25, 25, 25, 25, 25, 25, 25, 23, 23, 23, 23, 23, 23, 23, 23, 26, + 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, + 28, 28, 28, 28, 28, 28, 28, 14, 14, 14, 14, 14, 14, 14, 14, 3, + 3, 3, 3,118,119,118,119, 3, 3,156,156, 7,157, 7,157, 7, + 7, 7,158, 3, 3,180, 3, 14, 14, 14, 14, 14, 14, 14,181,182, + 17, 17, 17, 17, 17,183, 17,184, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15,185,100,100,100,100,100,186, 40, 40, 40, 40, 40, 40,187, + 188, 6, 6,189,190, 6,191, 6, 6, 6, 6, 6,192, 6, 6, 85, + 85, 85, 85, 85, 6, 6, 6,120,120,120,120,121,121,121,121,122, + 122,122,122,159,159, 85, 6, 6, 6, 6, 6, 6, 6,193, 6, 30, + 30, 30, 30, 30,194,195, 30, 45, 45, 45, 45, 45, 45, 45, 45, 46, + 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 48, + 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, 32, 49, + 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 51, + 51, 51, 51, 51, 51, 51, 51, 41, 41, 41, 41, 41, 41, 41, 41, 81, + 81, 81,196, 81, 81, 81, 81, 52, 52, 52, 52, 52, 52, 52, 52, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,197, 29, 29, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 35, 35, 35, 35, 35,198, 12, + 12, 36, 36, 36, 36, 36, 36,160,160,101,101,101,101,199,101,161, + 161,200,201,162,162,163,163, 37, 37, 37, 37, 37, 37, 37, 37,202, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 11, 11, 11, 11, 11,102, + 102,102,102,102,140,140,140, 86, 86, 86, 86, 86, 86, 37, 37,164, + 164, 42, 42, 42, 42, 42, 42, 42, 42, 42, 14, 14, 14, 14, 14, 53, + 53, 53, 53, 53, 53, 53, 53,103,103,103,103,123,123,123,123,104, + 104,104,104,104,141,141,141, 15, 35, 35, 35,103,203,204,205, 7, + 7,206, 7, 7,207,208,209, 7, 7, 7,210, 14, 14, 14, 14,211, + 3, 3, 3, 3, 3, 3,212, 3, 7, 3, 3, 3, 14, 14, 14, 3, + 3,213,214,215, 3, 7, 7,158, 3, 3, 3, 3, 3, 3, 3, 43, + 43, 43, 43, 43, 43, 7, 7, 54, 54, 54, 54, 54, 54, 54, 54, 35, + 35, 35,105,105,105,105,105, 12, 12, 12, 12, 12, 12, 15, 15, 1, + 1, 1, 1, 1, 1, 1, 3,216, 3,217,218,219, 22, 22, 22, 22, + 220,165, 21, 21, 21, 21,221,106,106,106,222, 2, 2, 2, 2, 2, + 3,106,106, 3, 3, 3, 21, 2, 2, 3, 3, 3, 3, 2,223, 3, + 3, 3, 3, 3, 21, 21,224, 21, 21, 21, 21, 21,225, 3, 3, 1, + 1, 1, 1, 3, 3, 3, 3, 9, 9, 9, 9, 9, 82, 82, 82, 23, + 23, 23, 23, 15, 15, 15, 15, 15, 15, 13, 13, 13, 13, 13, 13, 3, + 3,226, 7, 7, 7, 7, 7,227, 7, 7, 7, 7, 7, 7, 7,142, + 142,142, 3,124,124,124,124, 87, 87, 87, 87, 87, 87, 30, 30,166, + 166,228,143,143,143, 2, 2,107,107,107,107,229,107, 24, 24, 88, + 88, 88, 88, 88, 88, 24, 24, 89, 89, 89, 89, 89, 89, 90, 90, 12, + 12, 12, 7, 7,230,231, 36, 36, 36, 36, 36, 90, 90, 90, 90, 7, + 232, 40, 40, 40, 6, 6, 6, 6, 6, 6,233, 6, 6, 6, 6, 14, + 3,234, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6,235, 3, + 3,118,119,118,119,236,165, 21,237, 2, 2, 2, 2, 3, 3, 3, + 3, 3, 3, 17, 17, 17, 17, 17, 3, 17, 17, 17, 3, 3,238,167, + 167,125,125,125,125,239, 3,144,144,144,168,168,145,145,145,169, + 169, 91, 91, 91, 91, 91, 91,108,108,108,108,108,146,146,146,147, + 147,147,109,109,109,109,109,148,148,148,126,126,126,126,110,110, + 110,110,110,127,127,127,127,128,128,128,128,170,170,171,171, 92, + 92, 92, 92, 92, 92,172,172,173,173,174,174,129,129,129,129,175, + 175, 93, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 94,176,176,130, + 130,130,130,131,131,131,131,132,132,132,132,177,177,178,178, 55, + 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 57, + 57, 57, 57, 57, 57, 57, 57,133,133,133,133, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34,134,134,134,134,240, 6, 6, 6,149, + 149,149,135,135,135,135,136,136,136,136,150,150,150,179,179, 58, + 58, 58, 58, 58, 58, 58, 58,111,111,111,111,111,151,151,151,112, + 112,112,112,112,152,152,152, 59, 59, 59, 59, 59, 59,241, 41, 60, + 60, 60, 60, 60, 60, 60, 60,153,153,153,113,113,113,113,113, 83, + 83, 83,242, 83, 83, 83, 83, 61, 61, 61, 61, 61, 61, 61, 61, 62, + 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 64, + 64, 64, 64, 64, 64, 64, 64, 95, 95, 95, 95, 95, 95, 33, 33,114, + 114,114,114,114, 24, 24, 24, 65, 65, 65, 65, 65, 65, 65, 65, 66, + 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 68, + 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69,115, + 115,115,115,115, 96, 96, 96, 96, 96, 96, 11,137,137,137,137, 30, + 30, 30, 30, 30, 30, 59, 59, 70, 70, 70, 70, 70, 70, 70, 70, 84, + 84, 84, 84, 84, 84, 84, 44, 44, 44, 44, 44, 44, 44, 44, 44, 97, + 97, 97, 97, 97, 97,116,116,116,116,116,117,117,117,117,117, 71, + 71, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 82, + 82, 82, 82, 32, 32, 32, 32, 73, 73, 73, 73, 73, 73, 73, 73, 74, + 74, 74, 74, 74, 74, 74, 74, 13, 13, 13, 13,154,154,154, 98, 98, + 98, 98, 98, 98,155,155,155, 75, 75, 75, 75, 75, 75, 75, 75, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 99, 99, 99, 99, 99, 99, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,243, 1, 21, + 21, 21, 21, 21, 21, 21, 21,244, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 21,245, 22,246, 21, 19, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 3, 3, 3, 3, 3, 3, 14, + 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3,247,248,249, + 3,250, 3, 3, 3, 3, 3, 43, 43, 43, 15, 15, 15, 15, 15, 76, + 76, 76, 76, 76, 76, 76, 76,138,138,138,138,139,139,139,139, 77, + 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 79, + 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, 80,251, + 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 2, + 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, + 10, 10, 10, 11, 11, 11, 11, 13, 13, 13, 13, 14, 14, 14, 14, 12, + 12, 12, 12, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, + 18, 18, 18, 21, 21, 21, 21, 22, 22, 22, 22, 19, 19, 19, 19, 20, + 20, 20, 20, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, + 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, + 30, 30, 30, 31, 31, 31, 31, 33, 33, 33, 33, 32, 32, 32, 32, 34, + 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, + 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, + 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 46, 46, 46, 46, 47, + 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, + 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 45, + 45, 45, 45, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, + 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 62, + 62, 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65, 66, + 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69, 70, + 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, + 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, + 78, 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 83, + 83, 83, 83, 82, 82, 82, 82, 84, 84, 84, 84, 86, 86, 86, 86, 87, + 87, 87, 87, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 91, + 91, 91, 91, 92, 92, 92, 92, 93, 93, 93, 93, 94, 94, 94, 94, 95, + 95, 95, 95, 96, 96, 96, 96, 97, 97, 97, 97, 98, 98, 98, 98, 99, + 99, 99, 99,100,100,100,100, 85, 85, 85, 85,102,102,102,102,103, + 103,103,103,104,104,104,104,105,105,105,105,106,106,106,106,107, + 107,107,107,101,101,101,101,108,108,108,108,109,109,109,109,110, + 110,110,110,111,111,111,111,112,112,112,112,113,113,113,113,114, + 114,114,114,115,115,115,115,116,116,116,116,117,117,117,117,175, + 7, 7, 7, 7, 7,174, 3,118,118,118,118,119,119,119,119,120, + 120,120,120,121,121,121,121,122,122,122,122,123,123,123,123,124, + 124,124,124,125,125,125,125,126,126,126,126,127,127,127,127,128, + 128,128,128,129,129,129,129,130,130,130,130,131,131,131,131,132, + 132,132,132,133,133,133,133,134,134,134,134,135,135,135,135,136, + 136,136,136,137,137,137,137,138,138,138,138,139,139,139,139,140, + 140,140,140,141,141,141,141,142,142,142,142,143,143,143,143,144, + 144,144,144,145,145,145,145,146,146,146,146,147,147,147,147,148, + 148,148,148,149,149,149,149,150,150,150,150,151,151,151,151,152, + 152,152,152,153,153,153,153, 3, 3,177, 3, 7,174, 7, 7, 7, + 7,179, 3,155,155,155,155,156,156,156,156,157,157,157,157,158, + 158,158,158,159,159,159,159,160,160,160,160,182, 19, 19, 19,154, + 154,154,154,161,161,161,161,162,162,162,162,163,163,163,163,164, + 164,164,164,165,165,165,165,166,166,166,166,167,167,167,167,168, + 168,168,168,169,169,169,169,170,170,170,170,171,171,171,171,172, + 172,172,172,173,173,173,173, 7,179,194, 3, 17,195, 17,196, 17, + 197, 17, 17,198, 45, 45, 45, 15,199, 15, 15,200, 85, 85, 85,183, + 40, 40, 40, 6,184, 6,185, 6, 6,180,180,185, 6,201, 12, 12, + 202, 6, 6,203, 6, 6, 6, 6, 6, 6,184,204, 6, 6, 6,205, + 206, 30, 30, 30,207, 30, 30, 81, 81, 81,208, 29,209,210, 29, 35, + 35,211, 35,102,102,212,213,176,176,176,176,176,214, 3, 3,215, + 216, 32, 32,186, 12, 12, 12,217, 12,181,218, 3,181,178, 3, 7, + 187,219, 7, 7, 7, 7,220,221,187,222, 7, 7, 7,223, 7, 7, + 7, 7,224, 3, 3, 3,178,175, 3, 3,188, 3,225,189, 3,177, + 3, 3, 3, 3, 3, 3,177, 3,226, 3, 3,227, 1,228,229, 3, + 3, 1, 3,190, 20, 20, 20, 20, 20,230,190, 19, 19,191,182,231, + 2, 2, 2, 2, 2, 2,232, 19, 19, 19,191, 19, 19, 3, 3,189, + 7, 7, 7, 7, 7,188, 7,154,154,154,233,101,101,101,234, 7, + 7,174, 7, 7,235,236, 3,237, 85, 85,183, 6, 6, 6,238, 12, + 12, 12,239, 6, 6, 6,180, 3,240, 19, 19, 19, 19, 19,241, 3, + 3, 3,192,181, 3, 3, 3,242, 6, 6, 6,243, 41, 41, 41, 82, + 82,244, 82,245, 18, 18, 18,246, 20, 20, 20,247, 20, 20, 20, 20, + 248, 19, 19, 3,193,178, 3, 3, 3,193, 12,186,192, 12, 3, 3, + 3,249,178,250, 3, 3, 3, 2, 2, 2, 2, 13, 13, 13, 13, 12, + 12, 12, 12, 0, 0, 0, 0,136,136,136,136, 80, 80, 80, 80, 3, + 3, 3, 3, 19, 19, 19, 19, 63, 63, 63, 63, 39, 39, 39, 39,131, + 131,131,131, 28, 28, 28, 28, 1, 1, 1, 1, 30, 30, 30, 30, 79, + 79, 79, 79, 6, 6, 6, 6,127,127,127,127, 9, 9, 9, 9,155, + 155,155,155, 17, 17, 17, 17, 15, 15, 15, 15,139,139,139,139,110, + 110,110,110, 77, 77, 77, 77, 33, 33, 33, 33, 27, 27, 27, 27, 49, + 49, 49, 49,119,119,119,119,113,113,113,113, 25, 25, 25, 25, 7, + 7, 7, 7, 99, 99, 99, 99, 32, 32, 32, 32, 22, 22, 22, 22,165, + 165,165,165, 8, 8, 8, 8, 29, 29, 29, 29, 31, 31, 31, 31,146, + 146,146,146,105,105,105,105, 14, 14, 14, 14, 36, 36, 36, 36, 91, + 91, 91, 91, 56, 56, 56, 56,134,134,134,134, 55, 55, 55, 55, 5, + 5, 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 23, + 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 18, 18, 18, 18, 62, + 62, 62, 62,122,122,122,122, 89, 89, 89, 89,130,130,130,130, 94, + 94, 94, 94,100,100,100,100,108,108,108,108,171,171,171,171,137, + 137,137,137,124,124,124,124,123,123,123,123,126,126,126,126,142, + 142,142,142,125,125,125,125,154,154,154,154,150,150,150,150,169, + 169,169,169,145,145,145,145,163,163,163,163,157,157,157,157,166, + 166,166,166,167,167,167,167,151,151,151,151,164,164,164,164,168, + 168,168,168,174,174,174,174,132,132,132,132, 24, 24, 24, 24,107, + 107,107,107, 86, 86, 86, 86,133,133,133,133, 4, 4, 4, 4, 37, + 37, 37, 37, 58, 58, 58, 58, 75, 75, 75, 75, 68, 68, 68, 68, 92, + 92, 92, 92, 87, 87, 87, 87, 59, 59, 59, 59,116,116,116,116, 97, + 97, 97, 97, 57, 57, 57, 57,114,114,114,114,140,140,140,140,138, + 138,138,138,159,159,159,159,172,172,172,172, 84, 84, 84, 84, 35, + 35, 35, 35, 48, 48, 48, 48, 76, 76, 76, 76, 70, 70, 70, 70, 61, + 61, 61, 61, 26, 26, 26, 26, 40, 40, 40, 40,135,135,135,135,161, + 161,161,161, 85, 85, 85, 85, 96, 96, 96, 96,109,109,109,109,102, + 102,102,102,141,141,141,141,143,143,143,143,175,175,175,175, 38, + 38, 38, 38, 64, 64, 64, 64, 90, 90, 90, 90, 93, 93, 93, 93, 65, + 65, 65, 65, 67, 67, 67, 67,104,104,104,104,170,170,170,170, 47, + 47, 47, 47,173,173,173,173,117,117,117,117,112,112,112,112, 78, + 78, 78, 78,144,144,144,144,156,156,156,156,148,148,148,148,158, + 158,158,158,121,121,121,121,160,160,160,160,152,152,152,152, 52, + 52, 52, 52, 73, 73, 73, 73, 60, 60, 60, 60, 74, 74, 74, 74, 42, + 42, 42, 42,118,118,118,118, 51, 51, 51, 51, 50, 50, 50, 50,106, + 106,106,106,147,147,147,147,153,153,153,153,101,101,101,101,111, + 111,111,111,129,129,129,129,115,115,115,115,103,103,103,103, 69, + 69, 69, 69, 95, 95, 95, 95, 34, 34, 34, 34, 45, 45, 45, 45, 43, + 43, 43, 43, 46, 46, 46, 46, 54, 54, 54, 54, 71, 71, 71, 71, 41, + 41, 41, 41, 53, 53, 53, 53, 81, 81, 81, 81,120,120,120,120,128, + 128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 88, + 88, 88, 88, 83, 83, 83, 83, 82, 82, 82, 82,149,149,149,149, 19, + 19, 19, 0, 0, 19, 19, 19, 44, 44, 44, 44, 0, 0, 19, 0, 1, + 1, 0, 0, 19, 0, 0, 0, 3, 3, 3, 0, 1, 0, 0, 0, 0, + 17, 17, 17, 4, 14, 14, 14, 3, 0, 3, 3, 0, 3, 3, 3, 1, + 1, 1, 0, 19, 19, 9, 9, 0, 0, 0, 19, 0, 0, 19, 19, 0, + 15, 15, 15, 17, 17, 17, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, + 0, 26, 26, 0, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 9, + 9, 55, 55, 6, 1, 1, 6, 6, 4, 4, 4, 3, 3, 3, 1, 1, + 1, 3, 3, 1, 3, 3, 3, 3, 3, 0, 3, 7, 1, 1, 1, 1, + 7, 7, 7, 0, 0, 7, 7, 24, 24, 24, 0, 25, 0, 0, 0, 0, + 25, 25, 25, 8, 8, 8, 0, 35, 35, 35, 0, 0, 0, 35, 35, 44, + 0, 0, 0, 32, 32, 0, 0, 32, 0, 32, 32, 1, 0, 1, 1, 0, + 1, 0, 0, 9, 9, 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, + 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 0, 0, 9, 0, 0, + 13, 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 15, + 1, 1, 0, 26, 12, 12, 12, 12, 12, 12, 0, 69, 69, 0, 69, 84, + 84, 84, 0, 19, 9, 19, 19, 19, 19, 0, 0, 19, 19, 19, 4, 3, + 3, 0, 0, 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0,156, + 156, 3, 3,100, 36, 36, 36,107,107,107, 1,136,139, 13, 13, 17, + 15, 15, 15, 17, 17, 15, 15, 15, 17, 17, 17, 0, 0, 1, 1, 15, + 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, + 10, 0, 11, 12, 13, 0, 0, 0, 14, 0, 0, 15, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 17, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 19, 20, 21, 0, 22, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, + 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, + 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, + 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, + 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, + 102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, + 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, + 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0, + 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142, + 143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, + 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, 0,163, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,164,165, 0, 0, 0, 0, + 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,167, 0, 0, 0,168,169, 0, 0,170, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,176,177, 0, 0, 0, 0,178,179, 0, 0, + 0,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194, + 195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210, + 211,212,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, }; -static const uint16_t -_hb_ucd_u16[5080] = +static const uint16_t _hb_ucd_u16[5104]= { - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, - 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, - 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, - 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32, - 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83, - 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91, - 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102, - 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111, - 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119, - 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47, - 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66, - 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145, - 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153, - 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145, - 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47, - 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, - 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, - 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, - 47, 47, 184, 185, 186, 61, 47, 187, 188, 9, 9, 9, 66, 189, 190, 191, - 11, 11, 192, 27, 27, 27, 193, 194, 11, 195, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 196, 13, 13, 13, 13, 13, 13, - 197, 197, 197, 197, 197, 198, 197, 11, 199, 199, 199, 200, 201, 202, 202, 201, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 27, 212, 212, 212, 213, 214, 32, - 215, 216, 217, 218, 219, 145, 220, 220, 221, 222, 223, 146, 224, 225, 146, 226, - 227, 227, 227, 227, 227, 227, 227, 227, 228, 146, 229, 146, 146, 146, 146, 230, - 146, 231, 227, 232, 146, 233, 234, 146, 146, 146, 146, 146, 146, 146, 145, 145, - 145, 235, 146, 146, 146, 146, 236, 145, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 237, 238, 146, 146, 239, 146, 146, 146, 146, 146, 146, 240, 146, - 146, 146, 146, 146, 146, 146, 241, 242, 145, 243, 146, 146, 244, 227, 245, 227, - 246, 247, 227, 227, 227, 248, 227, 249, 146, 146, 146, 227, 250, 146, 146, 146, - 9, 9, 9, 11, 11, 11, 251, 252, 13, 13, 13, 13, 13, 13, 253, 254, - 11, 11, 11, 47, 47, 47, 255, 256, 47, 47, 47, 47, 47, 47, 32, 32, - 257, 258, 259, 260, 261, 262, 263, 263, 264, 265, 266, 267, 268, 47, 47, 47, - 47, 269, 148, 47, 47, 47, 47, 270, 47, 271, 47, 47, 146, 146, 146, 47, - 146, 146, 272, 146, 273, 274, 146, 146, 272, 146, 146, 274, 146, 146, 146, 146, - 47, 47, 47, 47, 146, 146, 146, 146, 47, 275, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 47, 47, 187, 276, 47, 61, 47, 13, 13, 277, 278, - 13, 279, 47, 47, 47, 47, 280, 281, 31, 282, 283, 284, 13, 13, 13, 285, - 286, 287, 288, 289, 290, 291, 9, 292, 293, 47, 294, 295, 47, 47, 47, 296, - 297, 47, 47, 298, 299, 160, 32, 300, 61, 47, 301, 47, 302, 303, 47, 47, - 72, 47, 47, 304, 305, 306, 307, 61, 47, 47, 308, 309, 310, 311, 47, 312, - 47, 47, 47, 313, 58, 314, 315, 316, 47, 47, 47, 11, 11, 317, 318, 11, - 11, 11, 11, 11, 47, 47, 319, 160, 320, 320, 320, 320, 320, 320, 320, 320, - 321, 321, 321, 321, 321, 321, 321, 321, 11, 322, 323, 47, 47, 47, 47, 47, - 47, 47, 47, 324, 31, 325, 47, 47, 47, 47, 47, 326, 146, 47, 47, 47, - 47, 47, 47, 47, 327, 146, 146, 328, 32, 329, 32, 330, 331, 332, 333, 47, - 47, 47, 47, 47, 47, 47, 47, 334, 335, 2, 3, 4, 5, 336, 337, 338, - 47, 339, 47, 47, 47, 47, 340, 341, 342, 145, 145, 343, 220, 220, 220, 344, - 345, 146, 146, 146, 146, 146, 146, 346, 347, 347, 347, 347, 347, 347, 347, 347, - 47, 47, 47, 47, 47, 47, 348, 145, 47, 47, 349, 47, 350, 47, 47, 60, - 47, 351, 47, 47, 47, 352, 220, 220, 9, 9, 147, 11, 11, 47, 47, 47, - 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 351, 9, - 9, 353, 11, 11, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, - 47, 47, 47, 47, 47, 354, 47, 355, 47, 47, 356, 145, 145, 145, 47, 357, - 47, 358, 47, 351, 66, 66, 66, 66, 47, 47, 47, 359, 145, 145, 145, 145, - 360, 47, 47, 361, 145, 66, 47, 362, 47, 363, 145, 145, 364, 47, 365, 66, - 47, 47, 47, 366, 47, 367, 47, 367, 47, 366, 144, 145, 145, 145, 145, 145, - 9, 9, 9, 9, 11, 11, 11, 368, 47, 47, 369, 160, 370, 9, 371, 11, - 372, 227, 227, 227, 227, 227, 227, 227, 145, 145, 145, 145, 145, 145, 145, 145, - 47, 47, 373, 47, 47, 47, 47, 374, 47, 363, 375, 47, 60, 376, 66, 47, - 377, 66, 66, 47, 378, 145, 47, 47, 379, 47, 47, 361, 380, 381, 382, 383, - 180, 47, 47, 384, 385, 47, 47, 160, 97, 47, 386, 387, 388, 47, 47, 389, - 180, 47, 47, 390, 391, 392, 393, 145, 47, 47, 394, 395, 360, 32, 32, 32, - 47, 47, 366, 47, 47, 396, 172, 160, 92, 47, 47, 113, 397, 398, 399, 32, - 47, 47, 47, 400, 401, 402, 403, 32, 47, 47, 47, 404, 405, 406, 47, 47, - 47, 47, 47, 407, 408, 160, 160, 160, 47, 47, 409, 410, 411, 412, 32, 32, - 47, 47, 47, 413, 414, 160, 66, 66, 47, 47, 415, 416, 160, 160, 160, 160, - 47, 417, 418, 419, 47, 47, 47, 47, 47, 47, 394, 420, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 128, 421, 47, 47, 47, 422, 423, 160, 160, 160, - 47, 47, 47, 47, 47, 424, 425, 426, 427, 47, 47, 428, 429, 430, 47, 47, - 431, 432, 66, 47, 47, 47, 47, 47, 66, 66, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 47, 47, 433, 160, 47, 47, 409, 434, 433, 128, 145, 435, - 47, 156, 436, 437, 32, 32, 32, 32, 47, 47, 47, 360, 438, 160, 47, 47, - 439, 440, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 441, - 442, 47, 47, 443, 444, 445, 32, 32, 47, 47, 47, 47, 145, 446, 447, 448, - 220, 220, 220, 220, 220, 220, 220, 66, 47, 47, 47, 47, 47, 47, 47, 433, - 47, 47, 47, 209, 449, 32, 47, 47, 47, 450, 451, 160, 160, 160, 160, 160, - 47, 47, 47, 47, 47, 47, 306, 47, 47, 47, 47, 47, 160, 47, 47, 452, - 47, 47, 47, 453, 454, 455, 456, 47, 27, 27, 27, 27, 457, 47, 458, 160, - 9, 9, 9, 9, 9, 9, 11, 11, 145, 459, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 396, 460, 426, 426, 461, 462, 27, 27, 27, 27, 463, 426, - 47, 464, 209, 209, 209, 209, 209, 209, 146, 146, 146, 146, 146, 146, 146, 160, - 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 465, 466, - 467, 146, 468, 146, 146, 146, 146, 146, 146, 146, 146, 146, 469, 146, 146, 146, - 9, 470, 11, 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, - 471, 472, 11, 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 471, 472, 11, - 197, 9, 473, 474, 9, 475, 11, 9, 470, 11, 197, 9, 476, 477, 478, 479, - 11, 480, 9, 481, 482, 483, 484, 11, 485, 9, 486, 11, 487, 160, 160, 160, - 32, 32, 32, 488, 32, 32, 489, 490, 491, 492, 32, 32, 32, 32, 32, 32, - 493, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 27, 27, 27, 27, 27, - 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 494, 495, 146, 146, 146, - 47, 47, 450, 32, 47, 47, 374, 496, 47, 47, 47, 47, 47, 47, 497, 160, - 47, 47, 47, 47, 47, 47, 450, 498, 47, 47, 47, 47, 356, 32, 32, 32, - 9, 9, 473, 11, 499, 306, 66, 66, 145, 145, 500, 501, 145, 145, 145, 145, - 145, 145, 502, 145, 145, 145, 145, 145, 47, 47, 47, 47, 47, 47, 47, 227, - 503, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 504, - 209, 209, 209, 209, 209, 209, 209, 209, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, - 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, - 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, - 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, - 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, - 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, - 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, - 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, - 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, - 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, - 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, - 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, - 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, - 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, - 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, - 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, - 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, - 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, - 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, - 1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, - 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, - 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, - 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, - 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, - 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 8, 8, 8, 8, 8, 8, 8, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 64, 64, 64, 64, 64, 64, 64, 64, + 56, 56, 56, 56, 56, 56, 56, 56, 40, 40, 40, 40, 40, 40, 40, 40, + 24, 24, 24, 24, 24, 24, 56, 56, 96, 96, 96, 96, 96, 96, 96, 96, + 24, 24, 24, 24, 24, 24, 24, 592, 152, 152, 600, 336, 344, 352, 360, 608, + 152, 152, 616, 624, 72, 632, 48, 640, 80, 80, 80, 648, 656, 80, 80, 664, + 672, 680, 688, 696, 704, 712, 80, 720, 80, 80, 80, 728, 736, 48, 48, 48, + 48, 744, 48, 96, 752, 760, 768, 368, 40, 40, 40, 40, 40, 40, 40, 776, + 784, 376, 792, 48, 800, 808, 80, 816, 72, 72, 72, 48, 48, 48, 80, 80, + 824, 80, 80, 80, 832, 80, 80, 80, 80, 80, 80, 376, 72, 840, 48, 48, + 848, 856, 40, 864, 872, 8, 8, 880, 888, 896, 8, 8, 904, 40, 912, 384, + 8, 8, 8, 8, 8, 920, 928, 936, 944, 392, 8, 40, 952, 8, 8, 8, + 8, 8, 184, 384, 136, 8, 960, 968, 8, 976, 984, 104, 8, 992, 8, 8, + 1000,1008, 8, 8,1016, 40,1024, 40, 400, 8, 8,1032,1040,1048,1056,1064, + 1072, 8, 8, 408,1080,1088, 144,1096, 416, 8, 8,1104,1112,1120,1128,1136, + 416, 8, 8, 408,1144, 8, 144,1152, 192, 8, 8, 424,1160,1168, 144,1176, + 432, 8, 8,1184,1192,1200, 440,1208,1216, 8, 8,1224,1232,1240, 144,1248, + 1256, 8, 8, 424,1264,1272, 144,1280,1288, 8, 8, 448,1296,1304, 144,1312, + 192, 8, 8, 8,1320,1328, 440,1336, 8, 8, 8,1344,1352, 200, 104, 104, + 8, 8, 8,1360,1368,1376, 8, 8,1384,1392, 208,1400, 8, 8, 8,1408, + 1416, 40, 40,1424,1432,1440, 104, 104, 8, 8,1448,1456, 200,1464,1472,1480, + 1488,1496, 72, 72, 72, 48, 48,1504, 8, 8, 8, 8, 8,1512, 456, 56, + 8, 24, 72, 72, 72, 72, 72, 216, 464, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8,1520, 8,1528,1536, 8, 8, 8, 8,1544,1552, + 8,1560, 8,1568, 8, 224, 8, 224, 8, 8, 8,1576,1584,1592, 88, 56, + 1600, 88, 8, 8,1608, 8, 8, 8,1616, 8,1624, 8, 8, 8, 8, 8, + 8, 8,1632,1640,1648, 8, 8, 8, 8, 8, 8, 8, 8,1656, 24, 24, + 8,1664, 8, 8, 8,1672,1680, 472, 88, 88,1688,1696, 40, 40, 40, 40, + 1704, 8, 8,1712,1720, 200,1728,1736, 232, 8,1744, 136, 8, 8,1752,1760, + 8, 8,1768,1776,1784, 136, 8, 480,1792, 72, 72, 72, 104,1800,1808,1816, + 48, 48,1824, 96, 96, 96,1832,1840, 48,1848, 96, 96, 40, 40, 40, 40, + 80, 80, 80, 80, 80, 80, 80, 80, 80,1856, 80, 80, 80, 80, 80, 80, + 128, 128, 128, 128, 128,1864, 128, 48, 240, 240, 240,1872, 488, 496, 496, 488, + 1880,1888,1896,1904,1912,1920, 112,1928,1936, 96, 248, 248, 248,1944,1952, 40, + 1960,1968,1976,1984,1992, 56, 120, 120,2000,2008,2016, 24,2024,2032, 24,2040, + 2048, 24,2056, 24, 24, 24, 24,2064, 24,2072, 64,2080, 24,2088,2096, 24, + 56,2104, 24, 24, 24, 24,2112, 56, 24, 24, 24,2120,2128, 24, 24,2136, + 24, 24, 24, 24, 24, 24,2144, 24, 24, 24, 24, 24, 24, 24,2152,2160, + 56,2168, 24, 24,2176, 64,2184, 64,2192,2200, 64, 64, 64,2208, 64,2216, + 24, 24, 24, 64,2224, 24, 24, 24, 72, 72, 72, 48, 48, 48,2232,2240, + 80, 80, 80, 80, 80, 80,2248,2256, 48, 48, 48, 8, 8, 8,2264,2272, + 8, 8, 8, 8, 8, 8, 40, 40,2280,2288,2296,2304,2312,2320, 504, 504, + 2328,2336,2344,2352,2360, 8, 8, 8, 8,2368, 464, 8, 8, 8, 8,2376, + 8,2384, 8, 8, 24, 24, 24, 8, 24, 24, 512, 24,2392, 520, 24, 24, + 512, 24, 24, 520, 24, 24, 24, 24, 8, 8, 8, 8, 24, 24, 24, 24, + 8, 528, 8, 8, 8, 8, 8, 8, 8, 24, 24, 24, 24, 8, 8, 480, + 2400, 8, 136, 8, 80, 80,2408,2416, 80,2424, 8, 8, 8, 8,2432,2440, + 368,2448,2456,2464, 80, 80, 80,2472,2480,2488,2496,2504,2512,2520, 72,2528, + 2536, 8,2544,2552, 8, 8, 8,2560,2568, 8, 8,2576,2584, 88, 40,2592, + 136, 8,2600, 8,2608,2616, 8, 8, 400, 8, 8,2624,2632, 256,2640, 136, + 8, 8,2648,2656,2664,2672, 8,2680, 8, 8, 8,2688, 392,2696,2704,2712, + 8, 8, 8, 48, 48,2720,2728, 48, 48, 48, 48, 48, 8, 8,2736, 88, + 48,2744,2752, 8, 8, 8, 8, 8, 8, 8, 8,2760,2768,2776, 8, 8, + 8, 8, 8,2784, 24, 8, 8, 8, 8,2792, 8, 8,2800, 24, 24,2808, + 40,2816, 40,2824,2832,2840,2848, 8, 8, 8, 8, 8, 8, 8, 8,2856, + 2864, 336, 344, 352, 360,2872,2880,2888, 8,2896, 8, 8, 8, 8,2904,2912, + 2920, 56, 56,2928, 120, 120, 120,2936,2944, 24, 24, 24, 24, 24, 24,2952, + 8, 8, 8, 8, 8, 8,2960, 56, 8, 8,2968, 8,2976, 8, 8, 184, + 8, 264, 8, 8, 8,2984, 120, 120, 72, 72, 216, 48, 48, 8, 8, 8, + 8, 8, 88, 72, 72, 216, 48, 48, 8, 8, 8, 8, 8, 8, 264, 72, + 72,2992, 48, 48, 8, 8, 8, 8, 8, 8, 8, 8, 8,3000, 8,3008, + 8, 8, 536, 56, 56, 56, 8,3016, 8,3024, 8, 264, 8, 8, 8, 8, + 8, 8, 8,3032, 56, 56, 56, 56, 272, 8, 8, 544, 56, 104, 8,3040, + 8, 552, 56, 56,3048, 8,3056, 104, 8, 8, 8, 280, 8, 560, 8, 560, + 8, 280, 456, 56, 56, 56, 56, 56, 72, 72, 72, 72, 48, 48, 48,3064, + 8, 8,3072, 88,3080, 72,3088, 48,3096, 64, 64, 64, 64, 64, 64, 64, + 8, 8,3104, 8, 528,3112, 24,3120, 8, 552,3128, 8, 184,3136, 104, 8, + 3144, 104, 104, 8,3152, 56, 8, 8,3160, 8, 8, 544,3168,3176,3184,3192, + 232, 8, 8,3200,3208, 8, 8, 88, 432, 8,3216,3224,3232, 8, 8,3240, + 232, 8, 8,3248,3256,3264,3272, 56, 8, 8, 568,3280, 272, 40, 40, 40, + 8, 8, 280, 8, 8, 576, 472, 88, 192, 8, 8, 448,3288,3296,3304, 40, + 8, 8, 8,3312,3320,3328,3336, 40, 8, 8, 8,3344,3352,3360, 8, 8, + 8, 8, 8,3368,3376, 88, 88, 88, 8, 8, 584,3384,3392,3400, 40, 40, + 8, 8, 8,3408,3416, 88, 104, 104, 8, 8,3424,3432, 88, 88, 88, 88, + 8,3440,3448,3456, 8, 8, 8, 8, 8, 8, 568,3464, 104, 104, 104, 104, + 72, 72, 72, 72, 48, 48, 208,3472, 8, 8, 8,3480,3488, 88, 88, 88, + 8, 8, 8, 8, 8,3496,3504, 160,3512, 8, 8,3520,3528,3536, 8, 8, + 3544,3552, 104, 8, 8, 8, 8, 8, 104, 104, 104, 104, 104, 104,3560, 160, + 8, 8, 8, 8, 8, 8, 288, 88, 8, 8, 584,3568, 288, 208, 56,3576, + 8, 224,3584,3592, 40, 40, 40, 40, 8, 8, 8, 272,3600, 88, 8, 8, + 3608,3616, 88, 8, 8,3624, 88, 88, 8, 8, 8, 8, 8, 8, 8,3632, + 3640, 8, 8,3648,3656,3664, 40, 40, 8, 8, 8, 8, 56,3672,3680,3688, + 120, 120, 120, 120, 120, 120, 120, 104, 8, 8, 8, 8, 8, 8, 8, 288, + 8, 8, 8, 112,3696, 40, 8, 8, 8, 296,3704, 88, 88, 88, 88, 88, + 8, 8, 8, 8, 8, 8, 256, 8, 8, 8, 8, 8, 88, 8, 8,3712, + 8, 8, 8,3720,3728,3736,3744, 8, 96, 96, 96, 96,3752, 8,3760, 88, + 72, 72, 72, 72, 72, 72, 48, 48, 56,3768, 72,3776, 48, 48, 48, 48, + 8, 8, 8, 8, 576,3784, 160, 160,3792,3800, 96, 96, 96, 96,3808,3816, + 8,3824, 112, 112, 112, 112, 112, 112, 24, 24, 24, 24, 24, 24, 24, 64, + 40, 40, 40, 40, 40, 24, 24, 24, 24, 24, 24, 24, 24, 24,3832,3840, + 3848, 24,3856, 24, 24, 24, 24, 24, 24, 24, 24, 24,3864, 24, 24, 24, + 72, 168, 48, 304, 312, 48, 128, 72, 176, 320, 72, 328, 48, 72, 168, 48, + 304, 312, 48, 128, 72, 176, 320, 72, 328, 48, 72, 168, 48, 304, 312, 48, + 128, 72, 176, 320, 72, 328, 48, 72, 168, 48, 128, 72,3872,3880,3888,3896, + 48,3904, 72,3912,3920,3928,3936, 48,3944, 72,3952, 48,3960, 88, 88, 88, + 40, 40, 40,3968, 40, 40,3976,3984,3992,4000, 40, 40, 40, 40, 40, 40, + 4008, 48, 48, 48, 48, 48, 48, 48, 40, 40, 40, 96, 96, 96, 96, 96, + 8, 8, 8,4016,4024, 24, 24, 24, 8, 8, 296, 40, 8, 8,4032,4040, + 8, 8, 8, 8, 8, 8,4048, 88, 8, 8, 8, 8, 8, 8, 296,4056, + 8, 8, 8, 8, 8, 8,4064,4072, 8, 8, 8, 8, 536, 40, 40, 40, + 72, 72, 176, 48,4080, 256, 104, 104, 56, 56,4088,4096, 56, 56, 56, 56, + 56, 56,4104, 56, 56, 56, 56, 56, 8, 8, 8, 8, 8, 8, 8, 64, + 4112, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,4120, + 24, 24, 24, 24, 24, 64, 64, 64, 112, 112, 112, 112, 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, - 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, - 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, - 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, - 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, - 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, - 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, - 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, - 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, - 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, - 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, - 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, - 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, - 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, - 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, - 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, - 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, - 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, - 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, - 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, - 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, - 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, - 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, - 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, - 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, - 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, - 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, - 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, - 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, - 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, - 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, - 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, - 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, - 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, - 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, - 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, - 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, - 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, - 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, - 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, - 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, - 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, - 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, - 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, - 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, - 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, - 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, - 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, - 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, - 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, - 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, - 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, - 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, - 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, - 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, - 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, - 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, - 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, - 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, - 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, - 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, - 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, - 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, - 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, - 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, - 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, - 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, - 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, - 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, - 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, - 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, - 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, - 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, - 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, - 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, - 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, - 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, - 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, - 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, - 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, - 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, - 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, - 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1937, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1938, 0,1939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1943,1944, 0, 0, 0, 0, 0, 0,1945, 0,1946, 0, 0, - 0, 0, 0, 0, 0, 0,1947, 0, 0,1948, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1950, 0,1949, - 1951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1953,1952, 0,1954, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1955,1956, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1957, 0, 0, 0, 0, 0, 0, 0, 0,1958,1961,1959,1965,1960,1962,1964, - 1963, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1967,1966,1968, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1969,1970,1971,1972,1973,1974,1975, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1976,1977,1978,1980,1979,1981, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, - 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, - 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, - 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, - 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, - 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, - 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, - 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, - 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, - 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, - 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, - 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, - 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, - 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, - 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, - 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, - 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, - 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, - 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, - 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, - 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, - 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, - 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, - 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, - 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, - 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, - 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, - 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, - 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, - 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, - 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, - 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, - 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, - 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, - 817, 818, 819, 820, 821, 935, 0, 0, + 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, + 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, + 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, + 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, + 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, + 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, + 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, + 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, + 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, + 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, + 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, + 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, + 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, + 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, + 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, + 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, + 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, + 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, + 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, + 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, + 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, + 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, + 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, + 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, + 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, + 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, + 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, + 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, + 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, + 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, + 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, + 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, + 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, + 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, + 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, + 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, + 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, + 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, + 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, + 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, + 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, + 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, + 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, + 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, + 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, + 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, + 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, + 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, + 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, + 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, + 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, + 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, + 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, + 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, + 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, + 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, + 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, + 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, + 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, + 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, + 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, + 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, + 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, + 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, + 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, + 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, + 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, + 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, + 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, + 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, + 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, + 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, + 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, + 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, + 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, + 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, + 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, + 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, + 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, + 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, + 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, + 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, + 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, + 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, + 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, + 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, + 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, + 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, + 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, + 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, + 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, + 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, + 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, + 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, + 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, + 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, + 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, + 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, + 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, + 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, + 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, + 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, + 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, + 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, + 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, + 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, + 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, + 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, + 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, + 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, + 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, + 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, + 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, + 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, + 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, + 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0,1939, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1940, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1943,1944, 0, 0, 0, + 0, 0, 0,1945, 0,1946, 0, 0, 0, 0, 0, 0, 0, 0,1947, 0, + 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1950, 0,1949,1951, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1953,1952, 0,1954, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1955,1956, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1957, 0, 0, 0, 0, 0, 0, 0, + 0,1958,1961,1959,1965,1960,1962,1964,1963, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1967,1966,1968, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1969,1970, + 1971,1972,1973,1974,1975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1976,1977,1978,1980,1979, + 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, + 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, + 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, + 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, + 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, + 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, + 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, + 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, + 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, + 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, + 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, + 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, + 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, + 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, + 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, + 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, + 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, + 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, + 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, + 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, + 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, + 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, + 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, + 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, + 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, + 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, + 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, + 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, + 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, + 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, + 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, + 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, + 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, + 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; -static const int16_t -_hb_ucd_i16[92] = +static const int16_t _hb_ucd_i16[92]= { - 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, - 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, - 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, + 0, 0, 1, -1, -1, 1, 0, 1, -1, 0, 0, 2, 0, -2, 2, 0, + -2, 0, -7, 0, 0, 16, 0, -16, 3, 3, 3, -3, -3, -3, 0, 2016, + 0, 2527, 1923, 1914, 1918, 0, 2250, 0, 0, 138, 0, 7, 1824, 0, 2104, 0, 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, }; -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) +static inline uint8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[5208+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + /* packtab: [2^8,2^4,2^3,2^3,2^1] */ + return u<1114112u ? (uint8_t)(_hb_ucd_u8[5288u+((_hb_ucd_u8[1160u+_hb_ucd_u16[((_hb_ucd_u8[544u+((_hb_ucd_u8[((((((((u)>>1))>>3))>>3))>>4)])<<4)+((((((((u)>>1))>>3))>>3))&15)])<<3)+((((((u)>>1))>>3))&7)]+((((u)>>1))&7)])<<1)+((u)&1)]) : 2; } -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) +static inline uint8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[7206+(((_hb_ucd_u8[6638+(((_hb_ucd_u8[6162+(((_hb_ucd_u8[5802+(((_hb_ucd_u8[5556+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + /* packtab: [2^8,2^3,2^2,2^2,2^2] */ + return u<125259u ? (uint8_t)(_hb_ucd_u8[7307u+((_hb_ucd_u8[6724u+((_hb_ucd_u8[6247u+((_hb_ucd_u8[5881u+((_hb_ucd_u8[5636u+((((((((u)>>2))>>2))>>2))>>3)])<<3)+((((((((u)>>2))>>2))>>2))&7)])<<2)+((((((u)>>2))>>2))&3)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)]) : 0; } -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_ucd_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) +static inline int16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[8098+(((_hb_ucd_u8[7866+(((_hb_ucd_u8[7770+(((_hb_ucd_b4(7706+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + /* packtab: [2^4,2^3,2^3,2^2,2^1] */ + return u<65380u ? (int16_t)(_hb_ucd_i16[_hb_ucd_u8[8198u+_hb_ucd_u8[7969u+_hb_ucd_u8[7875u+((_hb_ucd_b4(_hb_ucd_u8+7811u,((((((((u)>>1))>>2))>>3))>>3)))<<3)+((((((((u)>>1))>>2))>>3))&7)]+((((((u)>>1))>>2))&7)]+((((u)>>1))&3)]+((u)&1)]) : 0; } -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) +static inline uint8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11464+(((_hb_ucd_u8[10472+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[8764+(((_hb_ucd_u8[8460+(((_hb_ucd_u8[8346+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + /* packtab: [2^4,2^4,2^3,2^3,2^2,2^2] */ + return u<918016u ? (uint8_t)(_hb_ucd_u8[11623u+((_hb_ucd_u8[10615u+((_hb_ucd_u8[9119u+((_hb_ucd_u8[8675u+((_hb_ucd_u8[8475u+((_hb_ucd_b4(_hb_ucd_u8+8446u,((((((((((u)>>2))>>2))>>3))>>3))>>4)))<<4)+((((((((((u)>>2))>>2))>>3))>>3))&15)])<<3)+((((((((u)>>2))>>2))>>3))&7)])<<3)+((((((u)>>2))>>2))&7)])<<2)+((((u)>>2))&3)])<<2)+((u)&3)]) : 2; } -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) +static inline uint16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1656+(((_hb_ucd_u8[12834+(((_hb_ucd_u8[12452+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + /* packtab: [2^8,2^5,2^4] */ + return u<195102u ? (uint16_t)(_hb_ucd_u16[1680u+((_hb_ucd_u8[13009u+((_hb_ucd_u8[12627u+((((u)>>4))>>5)])<<5)+((((u)>>4))&31)])<<4)+((u)&15)]) : 0; } -#endif +#endif #endif /* HB_UCD_TABLE_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-unicode-emoji-table.hh b/thirdparty/harfbuzz/upstream/hb-unicode-emoji-table.hh index 4bc8d64c2..720095254 100644 --- a/thirdparty/harfbuzz/upstream/hb-unicode-emoji-table.hh +++ b/thirdparty/harfbuzz/upstream/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2024-05-01, 21:25:24 GMT - * # © 2024 Unicode®, Inc. + * # Date: 2025-07-25, 17:54:31 GMT + * # © 2025 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use and license, see https://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Used with Emoji Version 16.0 and subsequent minor revisions (if any) + * # Version: 17.0 * # * # For documentation and usage, see https://www.unicode.org/reports/tr51 */ @@ -23,54 +23,63 @@ #include "hb-unicode.hh" -static const uint8_t -_hb_emoji_u8[464] = +#include + +static const uint8_t _hb_emoji_u8[624]= { - 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,118,152, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 0, 3, 4, 0, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, 12, - 0, 0, 13, 0, 0, 0, 14, 0, 15, 0, 0, 0, 0, 16, 0, 0, - 17, 17, 18, 19, 20, 17, 17, 21, 17, 17, 22, 17, 23, 17, 24, 25, - 26, 27, 28, 17, 17, 17, 0, 0, 17, 17, 17, 17, 17, 17, 17, 29, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 4, 0, 0, - 5, 6, 0, 0, 7, 8, 0, 0, 8, 0, 9, 10, 0, 0, 11, 0, - 0, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 18, 19, 20, 21, - 22, 23, 0, 0, 0, 24, 0, 0, 25, 0, 26, 0, 0, 27, 0, 0, - 28, 0, 0, 0, 16, 16, 16, 16, 29, 9, 0, 30, 31, 32, 16, 33, - 34, 35, 36, 16, 16, 16, 16, 37, 16, 38, 39, 16, 16, 16, 40, 0, - 0, 0, 0, 41, 0, 0, 42, 16, 43, 0, 44, 0, 45, 46, 16, 16, - 47, 48, 49, 16, 16, 16, 16, 38, 0, 0, 0, 0, 0, 66, 0, 0, - 0, 0, 0, 16, 0, 2, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, - 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, 0,128, 0, 0, - 0,254, 15, 7, 4, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, - 0, 0, 0,120,191,255,247,255,255,255,255,255, 63, 0,255,255, - 63,255, 87, 32, 2, 1, 24, 0,144, 80,184, 0,248, 0, 0, 0, - 0, 0,224, 0, 2, 0, 1,128, 0, 0, 48, 0,224, 0, 0, 24, - 0, 0, 33, 0, 0, 0, 1, 32, 0, 0,128, 2, 0,224, 0, 0, - 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, 63, 0, 0, 0, - 254,255, 0, 4, 0,128,252,247, 0,254,255,255,255,255,255, 7, - 255,255,255, 63,192,255,255,255,255,255, 0, 0, 0, 0,240,255, - 0, 0,224,255, 0,240, 0, 0, 0,255, 0,252, 0,255, 0, 0, - 0,192,255,255, 0,240,255,255,255,255,255,247,191,255,255,255, + 1, 0, 0, 0, 50, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 7, 0, 0, 8, + 0, 0, 0, 9, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, + 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0, 0, + 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, + 24, 0, 25, 26, 0, 27, 28, 29, 30, 31, 1, 1, 32, 1, 33, 34, + 1, 1, 1, 35, 36, 37, 38, 39, 1, 40, 1, 41, 0, 0, 0, 42, + 43, 44, 45, 46, 47, 48, 1, 1, 0, 49, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255, + 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 2, + 0, 0,240, 3, 0, 6, 0, 0, 0, 0, 0, 12, 0, 1, 0, 0, + 0,128, 0, 0, 0,254, 15, 7, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, 0, 0, 0,120, + 31, 64, 50, 33, 77,196, 0, 7, 5,255, 15,128,105, 1, 0,200, + 0, 0,252, 26,131, 12, 3, 96, 48,193, 26, 0, 0, 6,191, 39, + 36,191, 84, 32, 2, 1, 24, 0,144, 80,184, 0, 24, 0, 0, 0, + 0, 0,224, 0, 2, 0, 1,128, 0, 0, 0, 0, 0, 0, 48, 0, + 224, 0, 0, 24, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 32, 0, 0,128, 2, 0, 0, 0, 0, + 16, 0, 0, 0, 0,240, 0, 0, 0, 0,240,255, 0,128, 1, 0, + 1,128, 1, 0, 0, 0,192,255, 0, 0, 0, 0, 0, 0, 3,192, + 0, 64,254, 7, 0,192,255,255,255,255,255,255, 63, 0, 0, 0, + 254,255, 0, 4, 0,128,252,247, 0,254,255,255,192,255,255,255, + 255,255,255,255,243,255,255,255,255,255,207,206,255,255,255,255, + 255,255,255,255,255,255,185, 7,255,255,255,255,255,255,255,191, + 255,255,255,255,255,255,255, 63, 0,126,255,255,255,128,249, 7, + 128, 60, 97, 0, 48, 1, 6, 16, 28, 0, 14,112, 10,129, 8,252, + 255,255, 0, 0, 0, 0, 0, 0, 63,248,231,255, 63,250,249,255, + 0, 0, 0,252,255,255,255,255, 0,240, 0, 0, 0, 0, 0, 0, + 0,255, 0,252, 0, 0, 0, 0, 0,255, 0, 0, 0,192, 0,240, + 252,255, 0,254,255,255,255,255, 0,240,255,255,255,255,255,247, + 191,255,255,255,255,255,255,255, 0, 0, 0,255, 0,192,255,255, }; -static inline unsigned -_hb_emoji_b4 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_emoji_b4 (const uint8_t* a, unsigned i) { - return (a[i>>1]>>((i&1u)<<2))&15u; + return (a[i>>1]>>((i&1)<<2))&15; } -static inline unsigned -_hb_emoji_b1 (const uint8_t* a, unsigned i) +static inline uint8_t _hb_emoji_b1 (const uint8_t* a, unsigned i) { - return (a[i>>3]>>((i&7u)<<0))&1u; + return (a[i>>3]>>((i&7)<<0))&1; } -static inline uint_fast8_t -_hb_emoji_is_Extended_Pictographic (unsigned u) +static inline uint8_t _hb_emoji_is_Extended_Pictographic (unsigned u) { - return u<131070u?_hb_emoji_b1(264+_hb_emoji_u8,((_hb_emoji_u8[144+(((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>5>>2>>3))<<3)+((u>>5>>2)&7u))])<<2)+((u>>5)&3u))])<<5)+((u)&31u)):0; + /* packtab: [2^4,2^4,2^6] */ + return u<131070u ? (uint8_t)(_hb_emoji_b1(_hb_emoji_u8+224u,((_hb_emoji_u8[64u+((_hb_emoji_b4(_hb_emoji_u8,((((u)>>6))>>4)))<<4)+((((u)>>6))&15)])<<6)+((u)&63))) : 0; } diff --git a/thirdparty/harfbuzz/upstream/hb-unicode.hh b/thirdparty/harfbuzz/upstream/hb-unicode.hh index 39aaee5ba..485f3f527 100644 --- a/thirdparty/harfbuzz/upstream/hb-unicode.hh +++ b/thirdparty/harfbuzz/upstream/hb-unicode.hh @@ -241,6 +241,57 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } } + static hb_codepoint_t + vertical_char_for (hb_codepoint_t u) + { + switch (u >> 8) + { + case 0x20: switch (u) { + case 0x2013u: return 0xfe32u; // EN DASH + case 0x2014u: return 0xfe31u; // EM DASH + case 0x2025u: return 0xfe30u; // TWO DOT LEADER + case 0x2026u: return 0xfe19u; // HORIZONTAL ELLIPSIS + } break; + case 0x30: switch (u) { + case 0x3001u: return 0xfe11u; // IDEOGRAPHIC COMMA + case 0x3002u: return 0xfe12u; // IDEOGRAPHIC FULL STOP + case 0x3008u: return 0xfe3fu; // LEFT ANGLE BRACKET + case 0x3009u: return 0xfe40u; // RIGHT ANGLE BRACKET + case 0x300au: return 0xfe3du; // LEFT DOUBLE ANGLE BRACKET + case 0x300bu: return 0xfe3eu; // RIGHT DOUBLE ANGLE BRACKET + case 0x300cu: return 0xfe41u; // LEFT CORNER BRACKET + case 0x300du: return 0xfe42u; // RIGHT CORNER BRACKET + case 0x300eu: return 0xfe43u; // LEFT WHITE CORNER BRACKET + case 0x300fu: return 0xfe44u; // RIGHT WHITE CORNER BRACKET + case 0x3010u: return 0xfe3bu; // LEFT BLACK LENTICULAR BRACKET + case 0x3011u: return 0xfe3cu; // RIGHT BLACK LENTICULAR BRACKET + case 0x3014u: return 0xfe39u; // LEFT TORTOISE SHELL BRACKET + case 0x3015u: return 0xfe3au; // RIGHT TORTOISE SHELL BRACKET + case 0x3016u: return 0xfe17u; // LEFT WHITE LENTICULAR BRACKET + case 0x3017u: return 0xfe18u; // RIGHT WHITE LENTICULAR BRACKET + } break; + case 0xfe: switch (u) { + case 0xfe4fu: return 0xfe34u; // WAVY LOW LINE + } break; + case 0xff: switch (u) { + case 0xff01u: return 0xfe15u; // FULLWIDTH EXCLAMATION MARK + case 0xff08u: return 0xfe35u; // FULLWIDTH LEFT PARENTHESIS + case 0xff09u: return 0xfe36u; // FULLWIDTH RIGHT PARENTHESIS + case 0xff0cu: return 0xfe10u; // FULLWIDTH COMMA + case 0xff1au: return 0xfe13u; // FULLWIDTH COLON + case 0xff1bu: return 0xfe14u; // FULLWIDTH SEMICOLON + case 0xff1fu: return 0xfe16u; // FULLWIDTH QUESTION MARK + case 0xff3bu: return 0xfe47u; // FULLWIDTH LEFT SQUARE BRACKET + case 0xff3du: return 0xfe48u; // FULLWIDTH RIGHT SQUARE BRACKET + case 0xff3fu: return 0xfe33u; // FULLWIDTH LOW LINE + case 0xff5bu: return 0xfe37u; // FULLWIDTH LEFT CURLY BRACKET + case 0xff5du: return 0xfe38u; // FULLWIDTH RIGHT CURLY BRACKET + } break; + } + + return u; + } + struct { #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS diff --git a/thirdparty/harfbuzz/upstream/hb-utf.hh b/thirdparty/harfbuzz/upstream/hb-utf.hh index 1120bd1cc..e85b97377 100644 --- a/thirdparty/harfbuzz/upstream/hb-utf.hh +++ b/thirdparty/harfbuzz/upstream/hb-utf.hh @@ -37,7 +37,7 @@ struct hb_utf8_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 4; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end, hb_codepoint_t *unicode, @@ -106,7 +106,7 @@ struct hb_utf8_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start, hb_codepoint_t *unicode, @@ -185,7 +185,7 @@ struct hb_utf16_xe_t typedef TCodepoint codepoint_t; static constexpr unsigned max_len = 2; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end, hb_codepoint_t *unicode, @@ -217,7 +217,7 @@ struct hb_utf16_xe_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start, hb_codepoint_t *unicode, @@ -294,7 +294,7 @@ struct hb_utf32_xe_t typedef TCodepoint codepoint_t; static constexpr unsigned max_len = 1; - static const TCodepoint * + static inline const TCodepoint * next (const TCodepoint *text, const TCodepoint *end HB_UNUSED, hb_codepoint_t *unicode, @@ -306,7 +306,7 @@ struct hb_utf32_xe_t return text; } - static const TCodepoint * + static inline const TCodepoint * prev (const TCodepoint *text, const TCodepoint *start HB_UNUSED, hb_codepoint_t *unicode, @@ -353,7 +353,7 @@ struct hb_latin1_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 1; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, @@ -363,7 +363,7 @@ struct hb_latin1_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, @@ -405,7 +405,7 @@ struct hb_ascii_t typedef uint8_t codepoint_t; static constexpr unsigned max_len = 1; - static const codepoint_t * + static inline const codepoint_t * next (const codepoint_t *text, const codepoint_t *end HB_UNUSED, hb_codepoint_t *unicode, @@ -417,7 +417,7 @@ struct hb_ascii_t return text; } - static const codepoint_t * + static inline const codepoint_t * prev (const codepoint_t *text, const codepoint_t *start HB_UNUSED, hb_codepoint_t *unicode, @@ -458,19 +458,21 @@ struct hb_ascii_t template static inline const typename utf_t::codepoint_t * hb_utf_offset_to_pointer (const typename utf_t::codepoint_t *start, + const typename utf_t::codepoint_t *text, + unsigned text_len, signed offset) { hb_codepoint_t unicode; while (offset-- > 0) start = utf_t::next (start, - start + utf_t::max_len, + text + text_len, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); while (offset++ < 0) start = utf_t::prev (start, - start - utf_t::max_len, + text, &unicode, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT); diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-draw.cc b/thirdparty/harfbuzz/upstream/hb-vector-svg-draw.cc new file mode 100644 index 000000000..82f31b4f9 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-draw.cc @@ -0,0 +1,740 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-vector.h" +#include "hb-blob.hh" +#include "hb-geometry.hh" +#include "hb-machinery.hh" +#include "hb-map.hh" +#include "hb-vector-svg-path.hh" +#include "hb-vector-svg-subset.hh" +#include "hb-vector-svg-utils.hh" + +#include +#include +#include + +#include "hb-vector-svg.hh" + +HB_UNUSED static inline bool +hb_svg_buffer_contains (const hb_vector_t &buf, const char *needle) +{ + unsigned nlen = (unsigned) strlen (needle); + if (!nlen || buf.length < nlen) + return false; + + for (unsigned i = 0; i + nlen <= buf.length; i++) + if (buf.arrayZ[i] == needle[0] && + !memcmp (buf.arrayZ + i, needle, nlen)) + return true; + return false; +} + +struct hb_vector_draw_t +{ + hb_object_header_t header; + + hb_vector_format_t format = HB_VECTOR_FORMAT_SVG; + hb_transform_t<> transform = {1, 0, 0, 1, 0, 0}; + float x_scale_factor = 1.f; + float y_scale_factor = 1.f; + hb_vector_extents_t extents = {0, 0, 0, 0}; + bool has_extents = false; + unsigned precision = 2; + bool flat = false; + + hb_vector_t defs; + hb_vector_t body; + hb_vector_t path; + hb_set_t *defined_glyphs = nullptr; + hb_blob_t *recycled_blob = nullptr; + + void append_xy (float x, float y) + { + float tx, ty; + hb_svg_transform_point (transform, x_scale_factor, y_scale_factor, x, y, &tx, &ty); + hb_svg_append_num (&path, tx, precision); + hb_svg_append_c (&path, ','); + hb_svg_append_num (&path, ty, precision); + } +}; + +static void +hb_vector_draw_move_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float to_x, float to_y, + void *) +{ + auto *d = (hb_vector_draw_t *) draw_data; + hb_svg_append_c (&d->path, 'M'); + d->append_xy (to_x, to_y); +} + +static void +hb_vector_draw_line_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float to_x, float to_y, + void *) +{ + auto *d = (hb_vector_draw_t *) draw_data; + hb_svg_append_c (&d->path, 'L'); + d->append_xy (to_x, to_y); +} + +static void +hb_vector_draw_quadratic_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float cx, float cy, + float to_x, float to_y, + void *) +{ + auto *d = (hb_vector_draw_t *) draw_data; + hb_svg_append_c (&d->path, 'Q'); + d->append_xy (cx, cy); + hb_svg_append_c (&d->path, ' '); + d->append_xy (to_x, to_y); +} + +static void +hb_vector_draw_cubic_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float c1x, float c1y, + float c2x, float c2y, + float to_x, float to_y, + void *) +{ + auto *d = (hb_vector_draw_t *) draw_data; + hb_svg_append_c (&d->path, 'C'); + d->append_xy (c1x, c1y); + hb_svg_append_c (&d->path, ' '); + d->append_xy (c2x, c2y); + hb_svg_append_c (&d->path, ' '); + d->append_xy (to_x, to_y); +} + +static void +hb_vector_draw_close_path (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + void *) +{ + auto *d = (hb_vector_draw_t *) draw_data; + hb_svg_append_c (&d->path, 'Z'); +} + +static inline void free_static_vector_draw_funcs (); + +static struct hb_vector_draw_funcs_lazy_loader_t + : hb_draw_funcs_lazy_loader_t +{ + static hb_draw_funcs_t *create () + { + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) hb_vector_draw_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) hb_vector_draw_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) hb_vector_draw_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) hb_vector_draw_cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) hb_vector_draw_close_path, nullptr, nullptr); + hb_draw_funcs_make_immutable (funcs); + hb_atexit (free_static_vector_draw_funcs); + return funcs; + } +} static_vector_draw_funcs; + +static inline void +free_static_vector_draw_funcs () +{ + static_vector_draw_funcs.free_instance (); +} + +static hb_draw_funcs_t * +hb_vector_draw_funcs_get () +{ + return static_vector_draw_funcs.get_unconst (); +} + +/** + * hb_vector_draw_create_or_fail: + * @format: output format. + * + * Creates a new draw context for vector output. + * + * Return value: (nullable): a newly allocated #hb_vector_draw_t, or `NULL` on failure. + * + * Since: 13.0.0 + */ +hb_vector_draw_t * +hb_vector_draw_create_or_fail (hb_vector_format_t format) +{ + if (format != HB_VECTOR_FORMAT_SVG) + return nullptr; + + hb_vector_draw_t *draw = hb_object_create (); + if (unlikely (!draw)) + return nullptr; + draw->format = format; + draw->defined_glyphs = hb_set_create (); + draw->defs.alloc (2048); + draw->body.alloc (8192); + draw->path.alloc (2048); + return draw; +} + +/** + * hb_vector_draw_reference: + * @draw: a draw context. + * + * Increases the reference count of @draw. + * + * Return value: (transfer full): referenced @draw. + * + * Since: 13.0.0 + */ +hb_vector_draw_t * +hb_vector_draw_reference (hb_vector_draw_t *draw) +{ + return hb_object_reference (draw); +} + +/** + * hb_vector_draw_destroy: + * @draw: a draw context. + * + * Decreases the reference count of @draw and destroys it when it reaches zero. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_destroy (hb_vector_draw_t *draw) +{ + if (!hb_object_should_destroy (draw)) + return; + + hb_blob_destroy (draw->recycled_blob); + hb_set_destroy (draw->defined_glyphs); + hb_object_actually_destroy (draw); + hb_free (draw); +} + +/** + * hb_vector_draw_set_user_data: + * @draw: a draw context. + * @key: user-data key. + * @data: user-data value. + * @destroy: (nullable): destroy callback for @data. + * @replace: whether to replace an existing value for @key. + * + * Attaches user data to @draw. + * + * Return value: `true` on success, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_draw_set_user_data (hb_vector_draw_t *draw, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (draw, key, data, destroy, replace); +} + +/** + * hb_vector_draw_get_user_data: + * @draw: a draw context. + * @key: user-data key. + * + * Gets previously attached user data from @draw. + * + * Return value: (nullable): user-data value associated with @key. + * + * Since: 13.0.0 + */ +void * +hb_vector_draw_get_user_data (hb_vector_draw_t *draw, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (draw, key); +} + +/** + * hb_vector_draw_set_transform: + * @draw: a draw context. + * @xx: transform xx component. + * @yx: transform yx component. + * @xy: transform xy component. + * @yy: transform yy component. + * @dx: transform x translation. + * @dy: transform y translation. + * + * Sets the affine transform used when drawing glyphs. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_set_transform (hb_vector_draw_t *draw, + float xx, float yx, + float xy, float yy, + float dx, float dy) +{ + draw->transform = {xx, yx, xy, yy, dx, dy}; +} + +/** + * hb_vector_draw_get_transform: + * @draw: a draw context. + * @xx: (out) (nullable): transform xx component. + * @yx: (out) (nullable): transform yx component. + * @xy: (out) (nullable): transform xy component. + * @yy: (out) (nullable): transform yy component. + * @dx: (out) (nullable): transform x translation. + * @dy: (out) (nullable): transform y translation. + * + * Gets the affine transform used when drawing glyphs. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_get_transform (hb_vector_draw_t *draw, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy) +{ + if (xx) *xx = draw->transform.xx; + if (yx) *yx = draw->transform.yx; + if (xy) *xy = draw->transform.xy; + if (yy) *yy = draw->transform.yy; + if (dx) *dx = draw->transform.x0; + if (dy) *dy = draw->transform.y0; +} + +/** + * hb_vector_draw_set_scale_factor: + * @draw: a draw context. + * @x_scale_factor: x scale factor. + * @y_scale_factor: y scale factor. + * + * Sets additional output scaling factors. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_set_scale_factor (hb_vector_draw_t *draw, + float x_scale_factor, + float y_scale_factor) +{ + draw->x_scale_factor = x_scale_factor > 0.f ? x_scale_factor : 1.f; + draw->y_scale_factor = y_scale_factor > 0.f ? y_scale_factor : 1.f; +} + +/** + * hb_vector_draw_get_scale_factor: + * @draw: a draw context. + * @x_scale_factor: (out) (nullable): x scale factor. + * @y_scale_factor: (out) (nullable): y scale factor. + * + * Gets additional output scaling factors. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_get_scale_factor (hb_vector_draw_t *draw, + float *x_scale_factor, + float *y_scale_factor) +{ + if (x_scale_factor) *x_scale_factor = draw->x_scale_factor; + if (y_scale_factor) *y_scale_factor = draw->y_scale_factor; +} + +/** + * hb_vector_draw_set_extents: + * @draw: a draw context. + * @extents: (nullable): output extents to set or expand. + * + * Sets or expands output extents on @draw. Passing `NULL` clears extents. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_set_extents (hb_vector_draw_t *draw, + const hb_vector_extents_t *extents) +{ + if (!extents) + { + draw->extents = {0, 0, 0, 0}; + draw->has_extents = false; + return; + } + + if (!(extents->width > 0.f && extents->height > 0.f)) + return; + + if (draw->has_extents) + { + float x0 = hb_min (draw->extents.x, extents->x); + float y0 = hb_min (draw->extents.y, extents->y); + float x1 = hb_max (draw->extents.x + draw->extents.width, + extents->x + extents->width); + float y1 = hb_max (draw->extents.y + draw->extents.height, + extents->y + extents->height); + draw->extents = {x0, y0, x1 - x0, y1 - y0}; + } + else + { + draw->extents = *extents; + draw->has_extents = true; + } +} + +/** + * hb_vector_draw_get_extents: + * @draw: a draw context. + * @extents: (out) (nullable): where to store current output extents. + * + * Gets current output extents from @draw. + * + * Return value: `true` if extents are set, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_draw_get_extents (hb_vector_draw_t *draw, + hb_vector_extents_t *extents) +{ + if (!draw->has_extents) + return false; + + if (extents) + *extents = draw->extents; + return true; +} + +/** + * hb_vector_draw_set_glyph_extents: + * @draw: a draw context. + * @glyph_extents: glyph extents in font units. + * + * Expands @draw extents using @glyph_extents under the current transform. + * + * Return value: `true` on success, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_draw_set_glyph_extents (hb_vector_draw_t *draw, + const hb_glyph_extents_t *glyph_extents) +{ + hb_bool_t has_extents = draw->has_extents; + hb_bool_t ret = hb_svg_set_glyph_extents_common (draw->transform, + draw->x_scale_factor, + draw->y_scale_factor, + glyph_extents, + &draw->extents, + &has_extents); + draw->has_extents = has_extents; + return ret; +} + +/** + * hb_vector_draw_get_funcs: + * + * Gets draw callbacks implemented by the vector draw backend. + * + * Return value: (transfer none): immutable #hb_draw_funcs_t singleton. + * + * Since: 13.0.0 + */ +hb_draw_funcs_t * +hb_vector_draw_get_funcs (void) +{ + return hb_vector_draw_funcs_get (); +} + +/** + * hb_vector_draw_glyph: + * @draw: a draw context. + * @font: font object. + * @glyph: glyph ID. + * @pen_x: glyph x origin before context transform. + * @pen_y: glyph y origin before context transform. + * @extents_mode: extents update mode. + * + * Draws one glyph into @draw. + * + * Return value: `true` if glyph data was emitted, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_draw_glyph (hb_vector_draw_t *draw, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y, + hb_vector_extents_mode_t extents_mode) +{ + if (draw->format != HB_VECTOR_FORMAT_SVG) + return false; + + if (extents_mode == HB_VECTOR_EXTENTS_MODE_EXPAND) + { + hb_glyph_extents_t ge; + if (hb_font_get_glyph_extents (font, glyph, &ge)) + { + float xx = draw->transform.xx; + float yx = draw->transform.yx; + float xy = draw->transform.xy; + float yy = draw->transform.yy; + float tx = draw->transform.x0 + xx * pen_x + xy * pen_y; + float ty = draw->transform.y0 + yx * pen_x + yy * pen_y; + hb_transform_t<> extents_transform = {xx, yx, -xy, -yy, tx, ty}; + + hb_bool_t has_extents = draw->has_extents; + hb_svg_set_glyph_extents_common (extents_transform, + draw->x_scale_factor, + draw->y_scale_factor, + &ge, + &draw->extents, + &has_extents); + draw->has_extents = has_extents; + } + } + + bool needs_def = !draw->flat && !hb_set_has (draw->defined_glyphs, glyph); + if (needs_def) + { + draw->path.clear (); + hb_svg_path_sink_t sink = {&draw->path, draw->precision}; + hb_font_draw_glyph (font, glyph, hb_svg_path_draw_funcs_get (), &sink); + if (!draw->path.length) + return false; + hb_svg_append_str (&draw->defs, "defs, glyph); + hb_svg_append_str (&draw->defs, "\" d=\""); + hb_svg_append_len (&draw->defs, draw->path.arrayZ, draw->path.length); + hb_svg_append_str (&draw->defs, "\"/>\n"); + hb_set_add (draw->defined_glyphs, glyph); + } + + if (draw->flat) + { + draw->path.clear (); + hb_svg_path_sink_t sink = {&draw->path, draw->precision}; + hb_font_draw_glyph (font, glyph, hb_svg_path_draw_funcs_get (), &sink); + + if (!draw->path.length) + return false; + + float xx = draw->transform.xx; + float yx = draw->transform.yx; + float xy = draw->transform.xy; + float yy = draw->transform.yy; + float tx = draw->transform.x0 + xx * pen_x + xy * pen_y; + float ty = draw->transform.y0 + yx * pen_x + yy * pen_y; + + hb_svg_append_str (&draw->body, "body, draw->path.arrayZ, draw->path.length); + hb_svg_append_str (&draw->body, "\" transform=\""); + hb_svg_append_instance_transform (&draw->body, + draw->precision, + draw->x_scale_factor, + draw->y_scale_factor, + xx, yx, xy, yy, tx, ty); + hb_svg_append_str (&draw->body, "\"/>\n"); + return true; + } + + float xx = draw->transform.xx; + float yx = draw->transform.yx; + float xy = draw->transform.xy; + float yy = draw->transform.yy; + float tx = draw->transform.x0 + xx * pen_x + xy * pen_y; + float ty = draw->transform.y0 + yx * pen_x + yy * pen_y; + + hb_svg_append_str (&draw->body, "body, glyph); + hb_svg_append_str (&draw->body, "\" transform=\""); + hb_svg_append_instance_transform (&draw->body, + draw->precision, + draw->x_scale_factor, + draw->y_scale_factor, + xx, yx, xy, yy, tx, ty); + hb_svg_append_str (&draw->body, "\"/>\n"); + return true; +} + +/** + * hb_vector_svg_set_flat: + * @draw: a draw context. + * @flat: whether to flatten geometry and disable reuse. + * + * Enables or disables SVG draw flattening. + * + * Since: 13.0.0 + */ +void +hb_vector_svg_set_flat (hb_vector_draw_t *draw, + hb_bool_t flat) +{ + draw->flat = !!flat; +} + +/** + * hb_vector_svg_set_precision: + * @draw: a draw context. + * @precision: decimal precision. + * + * Sets numeric output precision for SVG draw output. + * + * Since: 13.0.0 + */ +void +hb_vector_svg_set_precision (hb_vector_draw_t *draw, + unsigned precision) +{ + draw->precision = hb_min (precision, 12u); +} + +/** + * hb_vector_draw_render: + * @draw: a draw context. + * + * Renders accumulated draw content to an SVG blob. + * + * Return value: (transfer full) (nullable): output blob, or `NULL` if rendering cannot proceed. + * + * Since: 13.0.0 + */ +hb_blob_t * +hb_vector_draw_render (hb_vector_draw_t *draw) +{ + if (draw->format != HB_VECTOR_FORMAT_SVG) + return nullptr; + if (!draw->has_extents) + return nullptr; + + hb_vector_t out; + hb_svg_recover_recycled_buffer (draw->recycled_blob, &out); + unsigned estimated = draw->defs.length + + (draw->body.length ? draw->body.length : draw->path.length) + + 256; + out.alloc (estimated); + hb_svg_append_str (&out, "extents.x, draw->precision); + hb_svg_append_c (&out, ' '); + hb_svg_append_num (&out, draw->extents.y, draw->precision); + hb_svg_append_c (&out, ' '); + hb_svg_append_num (&out, draw->extents.width, draw->precision); + hb_svg_append_c (&out, ' '); + hb_svg_append_num (&out, draw->extents.height, draw->precision); + hb_svg_append_str (&out, "\" width=\""); + hb_svg_append_num (&out, draw->extents.width, draw->precision); + hb_svg_append_str (&out, "\" height=\""); + hb_svg_append_num (&out, draw->extents.height, draw->precision); + hb_svg_append_str (&out, "\">\n"); + + if (draw->defs.length) + { + hb_svg_append_str (&out, "\n"); + hb_svg_append_len (&out, draw->defs.arrayZ, draw->defs.length); + hb_svg_append_str (&out, "\n"); + } + + if (draw->body.length) + { + hb_svg_append_len (&out, draw->body.arrayZ, draw->body.length); + } + else if (draw->path.length) + { + hb_svg_append_str (&out, "path.arrayZ, draw->path.length); + hb_svg_append_str (&out, "\"/>\n"); + } + + hb_svg_append_str (&out, "\n"); + + hb_blob_t *blob = hb_svg_blob_from_buffer (&draw->recycled_blob, &out); + + draw->path.clear (); + draw->defs.clear (); + draw->body.clear (); + hb_set_clear (draw->defined_glyphs); + draw->has_extents = false; + draw->extents = {0, 0, 0, 0}; + + return blob; +} + +/** + * hb_vector_draw_reset: + * @draw: a draw context. + * + * Resets @draw state and clears accumulated content. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_reset (hb_vector_draw_t *draw) +{ + draw->transform = {1, 0, 0, 1, 0, 0}; + draw->x_scale_factor = 1.f; + draw->y_scale_factor = 1.f; + draw->extents = {0, 0, 0, 0}; + draw->has_extents = false; + draw->precision = 2; + draw->flat = false; + draw->defs.clear (); + draw->body.clear (); + draw->path.clear (); + hb_set_clear (draw->defined_glyphs); +} + +/** + * hb_vector_draw_recycle_blob: + * @draw: a draw context. + * @blob: (nullable): previously rendered blob to recycle. + * + * Provides a blob for internal buffer reuse by later render calls. + * + * Since: 13.0.0 + */ +void +hb_vector_draw_recycle_blob (hb_vector_draw_t *draw, + hb_blob_t *blob) +{ + hb_blob_destroy (draw->recycled_blob); + draw->recycled_blob = nullptr; + if (!blob || blob == hb_blob_get_empty ()) + return; + draw->recycled_blob = blob; +} diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-paint.cc b/thirdparty/harfbuzz/upstream/hb-vector-svg-paint.cc new file mode 100644 index 000000000..b23efb7e3 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-paint.cc @@ -0,0 +1,1830 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-vector.h" +#include "hb-blob.hh" +#include "hb-geometry.hh" +#include "hb-machinery.hh" +#include "hb-map.hh" +#include "hb-vector-svg-path.hh" +#include "hb-vector-svg-subset.hh" +#include "hb-vector-svg-utils.hh" + +#include +#include +#include + +#include "hb-vector-svg.hh" + +struct hb_svg_color_glyph_cache_key_t +{ + hb_codepoint_t glyph = HB_CODEPOINT_INVALID; + unsigned palette = 0; + hb_color_t foreground = 0; + + hb_svg_color_glyph_cache_key_t () = default; + hb_svg_color_glyph_cache_key_t (hb_codepoint_t g, unsigned p, hb_color_t f) + : glyph (g), palette (p), foreground (f) {} + + bool operator == (const hb_svg_color_glyph_cache_key_t &o) const + { + return glyph == o.glyph && + palette == o.palette && + foreground == o.foreground; + } + + uint32_t hash () const + { + uint32_t h = hb_hash (glyph); + h = h * 31u + hb_hash (palette); + h = h * 31u + hb_hash (foreground); + return h; + } +}; + +struct hb_vector_paint_t +{ + hb_object_header_t header; + + hb_vector_format_t format = HB_VECTOR_FORMAT_SVG; + hb_transform_t<> transform = {1, 0, 0, 1, 0, 0}; + float x_scale_factor = 1.f; + float y_scale_factor = 1.f; + hb_vector_extents_t extents = {0, 0, 0, 0}; + bool has_extents = false; + + hb_color_t foreground = HB_COLOR (0, 0, 0, 255); + int palette = 0; + hb_hashmap_t custom_palette_colors; + unsigned precision = 2; + bool flat = false; + + hb_vector_t defs; + hb_vector_t path; + hb_vector_t> group_stack; + uint64_t transform_group_open_mask = 0; + unsigned transform_group_depth = 0; + unsigned transform_group_overflow_depth = 0; + + unsigned clip_rect_counter = 0; + unsigned gradient_counter = 0; + unsigned color_glyph_counter = 0; + hb_set_t *defined_outlines = nullptr; + hb_set_t *defined_clips = nullptr; + hb_hashmap_t defined_color_glyphs; + hb_vector_t color_stops_scratch; + hb_vector_t subset_body_scratch; + hb_vector_t captured_scratch; + hb_blob_t *recycled_blob = nullptr; + bool current_color_glyph_has_svg_image = false; + hb_codepoint_t current_svg_image_glyph = HB_CODEPOINT_INVALID; + hb_face_t *current_face = nullptr; + unsigned svg_image_counter = 0; + + hb_vector_t ¤t_body () { return group_stack.tail (); } + + void append_global_transform_prefix (hb_vector_t *buf) + { + if (transform.xx == 1.f && transform.yx == 0.f && + transform.xy == 0.f && transform.yy == 1.f && + transform.x0 == 0.f && transform.y0 == 0.f && + x_scale_factor == 1.f && y_scale_factor == 1.f) + return; + + unsigned sprec = hb_svg_scale_precision (precision); + hb_svg_append_str (buf, "\n"); + } + + void append_global_transform_suffix (hb_vector_t *buf) + { + if (transform.xx == 1.f && transform.yx == 0.f && + transform.xy == 0.f && transform.yy == 1.f && + transform.x0 == 0.f && transform.y0 == 0.f && + x_scale_factor == 1.f && y_scale_factor == 1.f) + return; + hb_svg_append_str (buf, "\n"); + } +}; + +static inline uint64_t +hb_svg_pack_color_glyph_cache_entry (unsigned def_id, + bool image_like) +{ + return ((uint64_t) def_id << 1) | (image_like ? 1ull : 0ull); +} + +static inline unsigned +hb_svg_cache_entry_def_id (uint64_t v) +{ + return (unsigned) (v >> 1); +} + +static inline bool +hb_svg_cache_entry_image_like (uint64_t v) +{ + return !!(v & 1ull); +} + +static inline hb_svg_color_glyph_cache_key_t +hb_svg_color_glyph_cache_key (hb_codepoint_t glyph, + unsigned palette, + hb_color_t foreground) +{ + return {glyph, palette, foreground}; +} + +static hb_bool_t +hb_svg_get_color_stops (hb_vector_paint_t *paint, + hb_color_line_t *color_line, + hb_vector_t *stops) +{ + unsigned len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr); + if (unlikely (!stops->resize (len))) + return false; + hb_color_line_get_color_stops (color_line, 0, &len, stops->arrayZ); + + for (unsigned i = 0; i < len; i++) + if (stops->arrayZ[i].is_foreground) + stops->arrayZ[i].color = HB_COLOR (hb_color_get_blue (paint->foreground), + hb_color_get_green (paint->foreground), + hb_color_get_red (paint->foreground), + (unsigned) hb_color_get_alpha (stops->arrayZ[i].color) * + hb_color_get_alpha (paint->foreground) / 255); + return true; +} + +static const char * +hb_svg_extend_mode_str (hb_paint_extend_t ext) +{ + switch (ext) + { + case HB_PAINT_EXTEND_PAD: return "pad"; + case HB_PAINT_EXTEND_REPEAT: return "repeat"; + case HB_PAINT_EXTEND_REFLECT: return "reflect"; + default: return "pad"; + } +} + +static int +hb_svg_color_stop_cmp (const void *a, const void *b) +{ + const hb_color_stop_t *x = (const hb_color_stop_t *) a; + const hb_color_stop_t *y = (const hb_color_stop_t *) b; + if (x->offset < y->offset) return -1; + if (x->offset > y->offset) return 1; + return 0; +} + +static void +hb_svg_emit_color_stops (hb_vector_paint_t *paint, + hb_vector_t *buf, + hb_vector_t *stops) +{ + for (unsigned i = 0; i < stops->length; i++) + { + hb_color_t c = stops->arrayZ[i].color; + hb_svg_append_str (buf, "arrayZ[i].offset, 4); + hb_svg_append_str (buf, "\" stop-color=\"rgb("); + hb_svg_append_unsigned (buf, hb_color_get_red (c)); + hb_svg_append_c (buf, ','); + hb_svg_append_unsigned (buf, hb_color_get_green (c)); + hb_svg_append_c (buf, ','); + hb_svg_append_unsigned (buf, hb_color_get_blue (c)); + hb_svg_append_str (buf, ")\""); + if (hb_color_get_alpha (c) != 255) + { + hb_svg_append_str (buf, " stop-opacity=\""); + hb_svg_append_num (buf, hb_color_get_alpha (c) / 255.f, 4); + hb_svg_append_c (buf, '"'); + } + hb_svg_append_str (buf, "/>\n"); + } +} + +static const char * +hb_svg_composite_mode_str (hb_paint_composite_mode_t mode) +{ + switch (mode) + { + case HB_PAINT_COMPOSITE_MODE_CLEAR: + case HB_PAINT_COMPOSITE_MODE_SRC: + case HB_PAINT_COMPOSITE_MODE_DEST: + case HB_PAINT_COMPOSITE_MODE_DEST_OVER: + case HB_PAINT_COMPOSITE_MODE_SRC_IN: + case HB_PAINT_COMPOSITE_MODE_DEST_IN: + case HB_PAINT_COMPOSITE_MODE_SRC_OUT: + case HB_PAINT_COMPOSITE_MODE_DEST_OUT: + case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: + case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: + case HB_PAINT_COMPOSITE_MODE_XOR: + case HB_PAINT_COMPOSITE_MODE_PLUS: + return nullptr; + case HB_PAINT_COMPOSITE_MODE_SRC_OVER: return "normal"; + case HB_PAINT_COMPOSITE_MODE_SCREEN: return "screen"; + case HB_PAINT_COMPOSITE_MODE_OVERLAY: return "overlay"; + case HB_PAINT_COMPOSITE_MODE_DARKEN: return "darken"; + case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return "lighten"; + case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return "color-dodge"; + case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return "color-burn"; + case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return "hard-light"; + case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return "soft-light"; + case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return "difference"; + case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return "exclusion"; + case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return "multiply"; + case HB_PAINT_COMPOSITE_MODE_HSL_HUE: return "hue"; + case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: return "saturation"; + case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: return "color"; + case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: return "luminosity"; + default: return nullptr; + } +} + +struct hb_svg_point_t { float x, y; }; +struct hb_svg_rgba_t { float r, g, b, a; }; + +static inline float +hb_svg_lerp (float a, float b, float t) +{ return a + (b - a) * t; } + +static inline float +hb_svg_clamp01 (float v) +{ + if (v < 0.f) return 0.f; + if (v > 1.f) return 1.f; + return v; +} + +static inline hb_svg_rgba_t +hb_svg_rgba_from_hb_color (hb_color_t c) +{ + return {(float) hb_color_get_red (c) / 255.f, + (float) hb_color_get_green (c) / 255.f, + (float) hb_color_get_blue (c) / 255.f, + (float) hb_color_get_alpha (c) / 255.f}; +} + +static inline hb_color_t +hb_svg_hb_color_from_rgba (const hb_svg_rgba_t &c) +{ + unsigned r = (unsigned) roundf (hb_svg_clamp01 (c.r) * 255.f); + unsigned g = (unsigned) roundf (hb_svg_clamp01 (c.g) * 255.f); + unsigned b = (unsigned) roundf (hb_svg_clamp01 (c.b) * 255.f); + unsigned a = (unsigned) roundf (hb_svg_clamp01 (c.a) * 255.f); + return HB_COLOR (b, g, r, a); +} + +static inline hb_svg_rgba_t +hb_svg_lerp_rgba (const hb_svg_rgba_t &c0, + const hb_svg_rgba_t &c1, + float t) +{ + return {hb_svg_lerp (c0.r, c1.r, t), + hb_svg_lerp (c0.g, c1.g, t), + hb_svg_lerp (c0.b, c1.b, t), + hb_svg_lerp (c0.a, c1.a, t)}; +} + +static inline float hb_svg_dot (const hb_svg_point_t &p, const hb_svg_point_t &q) { return p.x * q.x + p.y * q.y; } +static inline hb_svg_point_t hb_svg_add (const hb_svg_point_t &p, const hb_svg_point_t &q) { return {p.x + q.x, p.y + q.y}; } +static inline hb_svg_point_t hb_svg_sub (const hb_svg_point_t &p, const hb_svg_point_t &q) { return {p.x - q.x, p.y - q.y}; } +static inline hb_svg_point_t hb_svg_scale (const hb_svg_point_t &p, float f) { return {p.x * f, p.y * f}; } + +static inline hb_svg_point_t +hb_svg_normalize (const hb_svg_point_t &p) +{ + float len = sqrtf (hb_svg_dot (p, p)); + if (len == 0.f) return {0.f, 0.f}; + return hb_svg_scale (p, 1.f / len); +} + +static void +hb_svg_add_sweep_patch (hb_vector_t *body, + unsigned precision, + float cx, float cy, float radius, + float a0, const hb_svg_rgba_t &c0_in, + float a1, const hb_svg_rgba_t &c1_in) +{ + static const float max_angle = HB_PI / 16.f; + hb_svg_point_t center = {cx, cy}; + int num_splits = (int) ceilf (fabsf (a1 - a0) / max_angle); + if (num_splits < 1) num_splits = 1; + + hb_svg_point_t p0 = {cosf (a0), sinf (a0)}; + hb_svg_rgba_t color0 = c0_in; + + for (int a = 0; a < num_splits; a++) + { + float k = (a + 1.f) / num_splits; + float angle1 = hb_svg_lerp (a0, a1, k); + hb_svg_rgba_t color1 = hb_svg_lerp_rgba (c0_in, c1_in, k); + + hb_svg_point_t p1 = {cosf (angle1), sinf (angle1)}; + hb_svg_point_t sp0 = hb_svg_add (center, hb_svg_scale (p0, radius)); + hb_svg_point_t sp1 = hb_svg_add (center, hb_svg_scale (p1, radius)); + + hb_svg_point_t A = hb_svg_normalize (hb_svg_add (p0, p1)); + hb_svg_point_t U = {-A.y, A.x}; + float up0 = hb_svg_dot (U, p0); + float up1 = hb_svg_dot (U, p1); + if (fabsf (up0) < 1e-6f || fabsf (up1) < 1e-6f) + { + p0 = p1; + color0 = color1; + continue; + } + hb_svg_point_t C0 = hb_svg_add (A, hb_svg_scale (U, hb_svg_dot (hb_svg_sub (p0, A), p0) / up0)); + hb_svg_point_t C1 = hb_svg_add (A, hb_svg_scale (U, hb_svg_dot (hb_svg_sub (p1, A), p1) / up1)); + + hb_svg_point_t sc0 = hb_svg_add (center, hb_svg_scale (hb_svg_add (C0, hb_svg_scale (hb_svg_sub (C0, p0), 0.33333f)), radius)); + hb_svg_point_t sc1 = hb_svg_add (center, hb_svg_scale (hb_svg_add (C1, hb_svg_scale (hb_svg_sub (C1, p1), 0.33333f)), radius)); + + hb_svg_rgba_t mid_color = hb_svg_lerp_rgba (color0, color1, 0.5f); + hb_color_t mid = hb_svg_hb_color_from_rgba (mid_color); + + hb_svg_append_str (body, "\n"); + + p0 = p1; + color0 = color1; + } +} + +static void +hb_svg_add_sweep_gradient_patches (hb_vector_t *body, + unsigned precision, + hb_color_stop_t *stops, + unsigned n_stops, + hb_paint_extend_t extend, + float cx, float cy, float radius, + float start_angle, float end_angle) +{ + if (!n_stops) return; + + hb_svg_rgba_t colors_buf[16]; + float angles_buf[16]; + hb_svg_rgba_t *colors = colors_buf; + float *angles = angles_buf; + bool dynamic = false; + + if (start_angle == end_angle) + { + if (extend == HB_PAINT_EXTEND_PAD) + { + if (start_angle > 0.f) + { + hb_svg_rgba_t c = hb_svg_rgba_from_hb_color (stops[0].color); + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, 0.f, c, start_angle, c); + } + if (end_angle < HB_2_PI) + { + hb_svg_rgba_t c = hb_svg_rgba_from_hb_color (stops[n_stops - 1].color); + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, end_angle, c, HB_2_PI, c); + } + } + return; + } + + if (end_angle < start_angle) + { + float tmp = start_angle; start_angle = end_angle; end_angle = tmp; + for (unsigned i = 0; i < n_stops - 1 - i; i++) + { + hb_color_stop_t t = stops[i]; + stops[i] = stops[n_stops - 1 - i]; + stops[n_stops - 1 - i] = t; + } + for (unsigned i = 0; i < n_stops; i++) + stops[i].offset = 1.f - stops[i].offset; + } + + if (n_stops > 16) + { + angles = (float *) hb_malloc (sizeof (float) * n_stops); + colors = (hb_svg_rgba_t *) hb_malloc (sizeof (hb_svg_rgba_t) * n_stops); + if (!angles || !colors) + { + hb_free (angles); + hb_free (colors); + return; + } + dynamic = true; + } + + for (unsigned i = 0; i < n_stops; i++) + { + angles[i] = start_angle + stops[i].offset * (end_angle - start_angle); + colors[i] = hb_svg_rgba_from_hb_color (stops[i].color); + } + + if (extend == HB_PAINT_EXTEND_PAD) + { + unsigned pos; + hb_svg_rgba_t color0 = colors[0]; + for (pos = 0; pos < n_stops; pos++) + { + if (angles[pos] >= 0) + { + if (pos > 0) + { + float f = (0.f - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + color0 = hb_svg_lerp_rgba (colors[pos - 1], colors[pos], f); + } + break; + } + } + if (pos == n_stops) + { + color0 = colors[n_stops - 1]; + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, 0.f, color0, HB_2_PI, color0); + goto done; + } + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, 0.f, color0, angles[pos], colors[pos]); + for (pos++; pos < n_stops; pos++) + { + if (angles[pos] <= HB_2_PI) + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, angles[pos - 1], colors[pos - 1], angles[pos], colors[pos]); + else + { + float f = (HB_2_PI - angles[pos - 1]) / (angles[pos] - angles[pos - 1]); + hb_svg_rgba_t color1 = hb_svg_lerp_rgba (colors[pos - 1], colors[pos], f); + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, angles[pos - 1], colors[pos - 1], HB_2_PI, color1); + break; + } + } + if (pos == n_stops) + { + color0 = colors[n_stops - 1]; + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, angles[n_stops - 1], color0, HB_2_PI, color0); + goto done; + } + } + else + { + float span = angles[n_stops - 1] - angles[0]; + if (fabsf (span) < 1e-6f) + goto done; + + int k = 0; + if (angles[0] >= 0) + { + float ss = angles[0]; + while (ss > 0) + { + if (span > 0) { ss -= span; k--; } + else { ss += span; k++; } + } + } + else + { + float ee = angles[n_stops - 1]; + while (ee < 0) + { + if (span > 0) { ee += span; k++; } + else { ee -= span; k--; } + } + } + + span = fabsf (span); + for (int l = k; l < 1000; l++) + { + for (unsigned i = 1; i < n_stops; i++) + { + float a0_l, a1_l; + const hb_svg_rgba_t *col0, *col1; + if ((l % 2 != 0) && (extend == HB_PAINT_EXTEND_REFLECT)) + { + a0_l = angles[0] + angles[n_stops - 1] - angles[n_stops - i] + l * span; + a1_l = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span; + col0 = &colors[n_stops - i]; + col1 = &colors[n_stops - 1 - i]; + } + else + { + a0_l = angles[i - 1] + l * span; + a1_l = angles[i] + l * span; + col0 = &colors[i - 1]; + col1 = &colors[i]; + } + + if (a1_l < 0.f) continue; + if (a0_l < 0.f) + { + float f = (0.f - a0_l) / (a1_l - a0_l); + hb_svg_rgba_t c = hb_svg_lerp_rgba (*col0, *col1, f); + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, 0.f, c, a1_l, *col1); + } + else if (a1_l >= HB_2_PI) + { + float f = (HB_2_PI - a0_l) / (a1_l - a0_l); + hb_svg_rgba_t c = hb_svg_lerp_rgba (*col0, *col1, f); + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, a0_l, *col0, HB_2_PI, c); + goto done; + } + else + hb_svg_add_sweep_patch (body, precision, cx, cy, radius, a0_l, *col0, a1_l, *col1); + } + } + } + +done: + if (dynamic) + { + hb_free (angles); + hb_free (colors); + } +} + + +static void hb_vector_paint_push_transform (hb_paint_funcs_t *, void *, + float, float, float, float, float, float, + void *); +static void hb_vector_paint_pop_transform (hb_paint_funcs_t *, void *, void *); +static void hb_vector_paint_push_clip_glyph (hb_paint_funcs_t *, void *, hb_codepoint_t, hb_font_t *, void *); +static void hb_vector_paint_push_clip_rectangle (hb_paint_funcs_t *, void *, float, float, float, float, void *); +static void hb_vector_paint_pop_clip (hb_paint_funcs_t *, void *, void *); +static void hb_vector_paint_color (hb_paint_funcs_t *, void *, hb_bool_t, hb_color_t, void *); +static hb_bool_t hb_vector_paint_image (hb_paint_funcs_t *, void *, hb_blob_t *, unsigned, unsigned, hb_tag_t, float, hb_glyph_extents_t *, void *); +static void hb_vector_paint_linear_gradient (hb_paint_funcs_t *, void *, hb_color_line_t *, float, float, float, float, float, float, void *); +static void hb_vector_paint_radial_gradient (hb_paint_funcs_t *, void *, hb_color_line_t *, float, float, float, float, float, float, void *); +static void hb_vector_paint_sweep_gradient (hb_paint_funcs_t *, void *, hb_color_line_t *, float, float, float, float, void *); +static void hb_vector_paint_push_group (hb_paint_funcs_t *, void *, void *); +static void hb_vector_paint_pop_group (hb_paint_funcs_t *, void *, hb_paint_composite_mode_t, void *); +static hb_bool_t hb_vector_paint_color_glyph (hb_paint_funcs_t *, void *, hb_codepoint_t, hb_font_t *, void *); +static hb_bool_t hb_vector_paint_custom_palette_color (hb_paint_funcs_t *, void *, unsigned, hb_color_t *, void *); + +static inline void free_static_vector_paint_funcs (); +static struct hb_vector_paint_funcs_lazy_loader_t + : hb_paint_funcs_lazy_loader_t +{ + static hb_paint_funcs_t *create () + { + hb_paint_funcs_t *funcs = hb_paint_funcs_create (); + hb_paint_funcs_set_push_transform_func (funcs, (hb_paint_push_transform_func_t) hb_vector_paint_push_transform, nullptr, nullptr); + hb_paint_funcs_set_pop_transform_func (funcs, (hb_paint_pop_transform_func_t) hb_vector_paint_pop_transform, nullptr, nullptr); + hb_paint_funcs_set_push_clip_glyph_func (funcs, (hb_paint_push_clip_glyph_func_t) hb_vector_paint_push_clip_glyph, nullptr, nullptr); + hb_paint_funcs_set_push_clip_rectangle_func (funcs, (hb_paint_push_clip_rectangle_func_t) hb_vector_paint_push_clip_rectangle, nullptr, nullptr); + hb_paint_funcs_set_pop_clip_func (funcs, (hb_paint_pop_clip_func_t) hb_vector_paint_pop_clip, nullptr, nullptr); + hb_paint_funcs_set_color_func (funcs, (hb_paint_color_func_t) hb_vector_paint_color, nullptr, nullptr); + hb_paint_funcs_set_image_func (funcs, (hb_paint_image_func_t) hb_vector_paint_image, nullptr, nullptr); + hb_paint_funcs_set_linear_gradient_func (funcs, (hb_paint_linear_gradient_func_t) hb_vector_paint_linear_gradient, nullptr, nullptr); + hb_paint_funcs_set_radial_gradient_func (funcs, (hb_paint_radial_gradient_func_t) hb_vector_paint_radial_gradient, nullptr, nullptr); + hb_paint_funcs_set_sweep_gradient_func (funcs, (hb_paint_sweep_gradient_func_t) hb_vector_paint_sweep_gradient, nullptr, nullptr); + hb_paint_funcs_set_push_group_func (funcs, (hb_paint_push_group_func_t) hb_vector_paint_push_group, nullptr, nullptr); + hb_paint_funcs_set_pop_group_func (funcs, (hb_paint_pop_group_func_t) hb_vector_paint_pop_group, nullptr, nullptr); + hb_paint_funcs_set_color_glyph_func (funcs, (hb_paint_color_glyph_func_t) hb_vector_paint_color_glyph, nullptr, nullptr); + hb_paint_funcs_set_custom_palette_color_func (funcs, (hb_paint_custom_palette_color_func_t) hb_vector_paint_custom_palette_color, nullptr, nullptr); + hb_paint_funcs_make_immutable (funcs); + hb_atexit (free_static_vector_paint_funcs); + return funcs; + } +} static_vector_paint_funcs; + +static inline void +free_static_vector_paint_funcs () +{ + static_vector_paint_funcs.free_instance (); +} + +static hb_paint_funcs_t * +hb_vector_paint_funcs_get () +{ + return static_vector_paint_funcs.get_unconst (); +} + +static hb_bool_t +hb_vector_paint_ensure_initialized (hb_vector_paint_t *paint) +{ + if (paint->group_stack.length) + return true; + if (unlikely (!paint->group_stack.push_or_fail ())) + return false; + paint->group_stack.tail ().alloc (4096); + return !paint->group_stack.in_error (); +} + +static void +hb_vector_paint_push_transform (hb_paint_funcs_t *, + void *paint_data, + float xx, float yx, + float xy, float yy, + float dx, float dy, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + if (unlikely (paint->transform_group_overflow_depth)) + { + paint->transform_group_overflow_depth++; + return; + } + if (unlikely (paint->transform_group_depth >= 64)) + { + paint->transform_group_overflow_depth = 1; + return; + } + + hb_bool_t opened = + !(fabsf (xx - 1.f) < 1e-6f && fabsf (yx) < 1e-6f && + fabsf (xy) < 1e-6f && fabsf (yy - 1.f) < 1e-6f && + fabsf (dx) < 1e-6f && fabsf (dy) < 1e-6f); + paint->transform_group_open_mask = (paint->transform_group_open_mask << 1) | (opened ? 1ull : 0ull); + paint->transform_group_depth++; + + if (!opened) + return; + + auto &body = paint->current_body (); + unsigned sprec = hb_svg_scale_precision (paint->precision); + hb_svg_append_str (&body, "precision); + hb_svg_append_c (&body, ','); + hb_svg_append_num (&body, dy, paint->precision); + hb_svg_append_str (&body, ")\">\n"); +} + +static void +hb_vector_paint_pop_transform (hb_paint_funcs_t *, + void *paint_data, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + if (unlikely (paint->transform_group_overflow_depth)) + { + paint->transform_group_overflow_depth--; + return; + } + if (!paint->transform_group_depth) + return; + paint->transform_group_depth--; + hb_bool_t opened = !!(paint->transform_group_open_mask & 1ull); + paint->transform_group_open_mask >>= 1; + if (opened) + hb_svg_append_str (&paint->current_body (), "\n"); +} + +static void +hb_vector_paint_push_clip_glyph (hb_paint_funcs_t *, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + if (!hb_set_has (paint->defined_outlines, glyph)) + { + hb_set_add (paint->defined_outlines, glyph); + paint->path.clear (); + hb_svg_path_sink_t sink = {&paint->path, paint->precision}; + hb_font_draw_glyph (font, glyph, hb_svg_path_draw_funcs_get (), &sink); + hb_svg_append_str (&paint->defs, "defs, glyph); + hb_svg_append_str (&paint->defs, "\" d=\""); + hb_svg_append_len (&paint->defs, paint->path.arrayZ, paint->path.length); + hb_svg_append_str (&paint->defs, "\"/>\n"); + } + + if (!hb_set_has (paint->defined_clips, glyph)) + { + hb_set_add (paint->defined_clips, glyph); + hb_svg_append_str (&paint->defs, "defs, glyph); + hb_svg_append_str (&paint->defs, "\">defs, glyph); + hb_svg_append_str (&paint->defs, "\"/>\n"); + } + + hb_svg_append_str (&paint->current_body (), "current_body (), glyph); + hb_svg_append_str (&paint->current_body (), ")\">\n"); +} + +static void +hb_vector_paint_push_clip_rectangle (hb_paint_funcs_t *, + void *paint_data, + float xmin, float ymin, + float xmax, float ymax, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + unsigned clip_id = paint->clip_rect_counter++; + hb_svg_append_str (&paint->defs, "defs, clip_id); + hb_svg_append_str (&paint->defs, "\">defs, xmin, paint->precision); + hb_svg_append_str (&paint->defs, "\" y=\""); + hb_svg_append_num (&paint->defs, ymin, paint->precision); + hb_svg_append_str (&paint->defs, "\" width=\""); + hb_svg_append_num (&paint->defs, xmax - xmin, paint->precision); + hb_svg_append_str (&paint->defs, "\" height=\""); + hb_svg_append_num (&paint->defs, ymax - ymin, paint->precision); + hb_svg_append_str (&paint->defs, "\"/>\n"); + + hb_svg_append_str (&paint->current_body (), "current_body (), clip_id); + hb_svg_append_str (&paint->current_body (), ")\">\n"); +} + +static void +hb_vector_paint_pop_clip (hb_paint_funcs_t *, + void *paint_data, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + hb_svg_append_str (&paint->current_body (), "\n"); +} + +static void +hb_vector_paint_color (hb_paint_funcs_t *, + void *paint_data, + hb_bool_t is_foreground, + hb_color_t color, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + hb_color_t c = color; + if (is_foreground) + c = HB_COLOR (hb_color_get_blue (paint->foreground), + hb_color_get_green (paint->foreground), + hb_color_get_red (paint->foreground), + (unsigned) hb_color_get_alpha (paint->foreground) * hb_color_get_alpha (color) / 255); + + auto &body = paint->current_body (); + hb_svg_append_str (&body, "\n"); +} + +static hb_bool_t +hb_vector_paint_image (hb_paint_funcs_t *, + void *paint_data, + hb_blob_t *image, + unsigned width, + unsigned height, + hb_tag_t format, + float slant HB_UNUSED, + hb_glyph_extents_t *extents, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return false; + + auto &body = paint->current_body (); + if (format == HB_TAG ('s','v','g',' ')) + { + paint->current_color_glyph_has_svg_image = true; + + paint->subset_body_scratch.clear (); + bool subset_ok = hb_svg_subset_glyph_image (paint->current_face, + image, + paint->current_svg_image_glyph, + &paint->svg_image_counter, + &paint->defs, + &paint->subset_body_scratch); + if (unlikely (!subset_ok)) + return false; + + if (extents) + { + hb_svg_append_str (&body, "x_bearing, paint->precision); + hb_svg_append_c (&body, ','); + hb_svg_append_num (&body, (float) extents->y_bearing, paint->precision); + hb_svg_append_str (&body, ") scale("); + hb_svg_append_num (&body, (float) extents->width / width, paint->precision); + hb_svg_append_c (&body, ','); + hb_svg_append_num (&body, (float) extents->height / height, paint->precision); + hb_svg_append_str (&body, ")\">\n"); + } + + hb_svg_append_len (&body, + paint->subset_body_scratch.arrayZ, + paint->subset_body_scratch.length); + hb_svg_append_c (&body, '\n'); + + if (extents) + hb_svg_append_str (&body, "\n"); + + return true; + } + + if (format == HB_TAG ('p','n','g',' ')) + { + if (!extents || !width || !height) + return false; + + unsigned len = 0; + const char *png_data = hb_blob_get_data (image, &len); + if (!png_data || !len) + return false; + + hb_svg_append_str (&body, "x_bearing, paint->precision); + hb_svg_append_c (&body, ','); + hb_svg_append_num (&body, (float) extents->y_bearing, paint->precision); + hb_svg_append_str (&body, ") scale("); + hb_svg_append_num (&body, (float) extents->width / width, paint->precision); + hb_svg_append_c (&body, ','); + hb_svg_append_num (&body, (float) extents->height / height, paint->precision); + hb_svg_append_str (&body, ")\">\n"); + + hb_svg_append_str (&body, "precision); + hb_svg_append_str (&body, "\" height=\""); + hb_svg_append_num (&body, (float) height, paint->precision); + hb_svg_append_str (&body, "\"/>\n\n"); + + return true; + } + + return false; +} + +static void +hb_vector_paint_linear_gradient (hb_paint_funcs_t *, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, + float x1, float y1, + float x2, float y2, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + hb_vector_t &stops = paint->color_stops_scratch; + if (!hb_svg_get_color_stops (paint, color_line, &stops) || !stops.length) + return; + + qsort (stops.arrayZ, stops.length, sizeof (hb_color_stop_t), hb_svg_color_stop_cmp); + + unsigned grad_id = paint->gradient_counter++; + + hb_svg_append_str (&paint->defs, "defs, grad_id); + hb_svg_append_str (&paint->defs, "\" gradientUnits=\"userSpaceOnUse\" x1=\""); + hb_svg_append_num (&paint->defs, x0, paint->precision); + hb_svg_append_str (&paint->defs, "\" y1=\""); + hb_svg_append_num (&paint->defs, y0, paint->precision); + hb_svg_append_str (&paint->defs, "\" x2=\""); + hb_svg_append_num (&paint->defs, x1 + (x1 - x2), paint->precision); + hb_svg_append_str (&paint->defs, "\" y2=\""); + hb_svg_append_num (&paint->defs, y1 + (y1 - y2), paint->precision); + hb_svg_append_str (&paint->defs, "\" spreadMethod=\""); + hb_svg_append_str (&paint->defs, hb_svg_extend_mode_str (hb_color_line_get_extend (color_line))); + hb_svg_append_str (&paint->defs, "\">\n"); + hb_svg_emit_color_stops (paint, &paint->defs, &stops); + hb_svg_append_str (&paint->defs, "\n"); + + hb_svg_append_str (&paint->current_body (), + "current_body (), grad_id); + hb_svg_append_str (&paint->current_body (), ")\"/>\n"); +} + +static void +hb_vector_paint_radial_gradient (hb_paint_funcs_t *, + void *paint_data, + hb_color_line_t *color_line, + float x0, float y0, float r0, + float x1, float y1, float r1, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + hb_vector_t &stops = paint->color_stops_scratch; + if (!hb_svg_get_color_stops (paint, color_line, &stops) || !stops.length) + return; + + qsort (stops.arrayZ, stops.length, sizeof (hb_color_stop_t), hb_svg_color_stop_cmp); + + unsigned grad_id = paint->gradient_counter++; + + hb_svg_append_str (&paint->defs, "defs, grad_id); + hb_svg_append_str (&paint->defs, "\" gradientUnits=\"userSpaceOnUse\" cx=\""); + hb_svg_append_num (&paint->defs, x1, paint->precision); + hb_svg_append_str (&paint->defs, "\" cy=\""); + hb_svg_append_num (&paint->defs, y1, paint->precision); + hb_svg_append_str (&paint->defs, "\" r=\""); + hb_svg_append_num (&paint->defs, r1, paint->precision); + hb_svg_append_str (&paint->defs, "\" fx=\""); + hb_svg_append_num (&paint->defs, x0, paint->precision); + hb_svg_append_str (&paint->defs, "\" fy=\""); + hb_svg_append_num (&paint->defs, y0, paint->precision); + if (r0 > 0) + { + hb_svg_append_str (&paint->defs, "\" fr=\""); + hb_svg_append_num (&paint->defs, r0, paint->precision); + } + hb_svg_append_str (&paint->defs, "\" spreadMethod=\""); + hb_svg_append_str (&paint->defs, hb_svg_extend_mode_str (hb_color_line_get_extend (color_line))); + hb_svg_append_str (&paint->defs, "\">\n"); + hb_svg_emit_color_stops (paint, &paint->defs, &stops); + hb_svg_append_str (&paint->defs, "\n"); + + hb_svg_append_str (&paint->current_body (), + "current_body (), grad_id); + hb_svg_append_str (&paint->current_body (), ")\"/>\n"); +} + +static void +hb_vector_paint_sweep_gradient (hb_paint_funcs_t *, + void *paint_data, + hb_color_line_t *color_line, + float cx, float cy, + float start_angle, float end_angle, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + + hb_vector_t &stops = paint->color_stops_scratch; + if (!hb_svg_get_color_stops (paint, color_line, &stops) || !stops.length) + return; + + qsort (stops.arrayZ, stops.length, sizeof (hb_color_stop_t), hb_svg_color_stop_cmp); + hb_svg_add_sweep_gradient_patches (&paint->current_body (), + paint->precision, + stops.arrayZ, + stops.length, + hb_color_line_get_extend (color_line), + cx, cy, + 32767.f, + start_angle, + end_angle); +} + +static void +hb_vector_paint_push_group (hb_paint_funcs_t *, + void *paint_data, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + paint->group_stack.push_or_fail (hb_vector_t {}); +} + +static void +hb_vector_paint_pop_group (hb_paint_funcs_t *, + void *paint_data, + hb_paint_composite_mode_t mode, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return; + if (paint->group_stack.length < 2) + return; + + hb_vector_t group = paint->group_stack.pop (); + auto &body = paint->current_body (); + + const char *blend = hb_svg_composite_mode_str (mode); + if (blend) + { + hb_svg_append_str (&body, "\n"); + hb_svg_append_len (&body, group.arrayZ, group.length); + hb_svg_append_str (&body, "\n"); + } + else + hb_svg_append_len (&body, group.arrayZ, group.length); +} + +static hb_bool_t +hb_vector_paint_color_glyph (hb_paint_funcs_t *, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *) +{ + auto *paint = (hb_vector_paint_t *) paint_data; + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return false; + hb_codepoint_t old_gid = paint->current_svg_image_glyph; + hb_face_t *old_face = paint->current_face; + paint->current_svg_image_glyph = glyph; + paint->current_face = hb_font_get_face (font); + hb_font_paint_glyph (font, glyph, + hb_vector_paint_funcs_get (), + paint, + paint->palette, + paint->foreground); + paint->current_svg_image_glyph = old_gid; + paint->current_face = old_face; + return true; +} + + + +/** + * hb_vector_paint_create_or_fail: + * @format: output format. + * + * Creates a new paint context for vector output. + * + * Return value: (nullable): a newly allocated #hb_vector_paint_t, or `NULL` on failure. + * + * Since: 13.0.0 + */ +hb_vector_paint_t * +hb_vector_paint_create_or_fail (hb_vector_format_t format) +{ + if (format != HB_VECTOR_FORMAT_SVG) + return nullptr; + + hb_vector_paint_t *paint = hb_object_create (); + if (unlikely (!paint)) + return nullptr; + paint->format = format; + + paint->defined_outlines = hb_set_create (); + paint->defined_clips = hb_set_create (); + paint->defs.alloc (4096); + paint->path.alloc (2048); + paint->subset_body_scratch.alloc (2048); + paint->captured_scratch.alloc (4096); + paint->color_stops_scratch.alloc (16); + + return paint; +} + +/** + * hb_vector_paint_reference: + * @paint: a paint context. + * + * Increases the reference count of @paint. + * + * Return value: (transfer full): referenced @paint. + * + * Since: 13.0.0 + */ +hb_vector_paint_t * +hb_vector_paint_reference (hb_vector_paint_t *paint) +{ + return hb_object_reference (paint); +} + +/** + * hb_vector_paint_destroy: + * @paint: a paint context. + * + * Decreases the reference count of @paint and destroys it when it reaches zero. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_destroy (hb_vector_paint_t *paint) +{ + if (!hb_object_should_destroy (paint)) + return; + + hb_blob_destroy (paint->recycled_blob); + hb_set_destroy (paint->defined_outlines); + hb_set_destroy (paint->defined_clips); + hb_object_actually_destroy (paint); + hb_free (paint); +} + +/** + * hb_vector_paint_set_user_data: + * @paint: a paint context. + * @key: user-data key. + * @data: user-data value. + * @destroy: (nullable): destroy callback for @data. + * @replace: whether to replace an existing value for @key. + * + * Attaches user data to @paint. + * + * Return value: `true` on success, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_paint_set_user_data (hb_vector_paint_t *paint, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (paint, key, data, destroy, replace); +} + +/** + * hb_vector_paint_get_user_data: + * @paint: a paint context. + * @key: user-data key. + * + * Gets previously attached user data from @paint. + * + * Return value: (nullable): user-data value associated with @key. + * + * Since: 13.0.0 + */ +void * +hb_vector_paint_get_user_data (hb_vector_paint_t *paint, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (paint, key); +} + +/** + * hb_vector_paint_set_transform: + * @paint: a paint context. + * @xx: transform xx component. + * @yx: transform yx component. + * @xy: transform xy component. + * @yy: transform yy component. + * @dx: transform x translation. + * @dy: transform y translation. + * + * Sets the affine transform used when painting glyphs. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_set_transform (hb_vector_paint_t *paint, + float xx, float yx, + float xy, float yy, + float dx, float dy) +{ + paint->transform = {xx, yx, xy, yy, dx, dy}; +} + +/** + * hb_vector_paint_get_transform: + * @paint: a paint context. + * @xx: (out) (nullable): transform xx component. + * @yx: (out) (nullable): transform yx component. + * @xy: (out) (nullable): transform xy component. + * @yy: (out) (nullable): transform yy component. + * @dx: (out) (nullable): transform x translation. + * @dy: (out) (nullable): transform y translation. + * + * Gets the affine transform used when painting glyphs. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_get_transform (hb_vector_paint_t *paint, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy) +{ + if (xx) *xx = paint->transform.xx; + if (yx) *yx = paint->transform.yx; + if (xy) *xy = paint->transform.xy; + if (yy) *yy = paint->transform.yy; + if (dx) *dx = paint->transform.x0; + if (dy) *dy = paint->transform.y0; +} + +/** + * hb_vector_paint_set_scale_factor: + * @paint: a paint context. + * @x_scale_factor: x scale factor. + * @y_scale_factor: y scale factor. + * + * Sets additional output scaling factors. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_set_scale_factor (hb_vector_paint_t *paint, + float x_scale_factor, + float y_scale_factor) +{ + paint->x_scale_factor = x_scale_factor > 0.f ? x_scale_factor : 1.f; + paint->y_scale_factor = y_scale_factor > 0.f ? y_scale_factor : 1.f; +} + +/** + * hb_vector_paint_get_scale_factor: + * @paint: a paint context. + * @x_scale_factor: (out) (nullable): x scale factor. + * @y_scale_factor: (out) (nullable): y scale factor. + * + * Gets additional output scaling factors. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_get_scale_factor (hb_vector_paint_t *paint, + float *x_scale_factor, + float *y_scale_factor) +{ + if (x_scale_factor) *x_scale_factor = paint->x_scale_factor; + if (y_scale_factor) *y_scale_factor = paint->y_scale_factor; +} + +/** + * hb_vector_paint_set_extents: + * @paint: a paint context. + * @extents: (nullable): output extents to set or expand. + * + * Sets or expands output extents on @paint. Passing `NULL` clears extents. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_set_extents (hb_vector_paint_t *paint, + const hb_vector_extents_t *extents) +{ + if (!extents) + { + paint->extents = {0, 0, 0, 0}; + paint->has_extents = false; + return; + } + + if (!(extents->width > 0.f && extents->height > 0.f)) + return; + + if (paint->has_extents) + { + float x0 = hb_min (paint->extents.x, extents->x); + float y0 = hb_min (paint->extents.y, extents->y); + float x1 = hb_max (paint->extents.x + paint->extents.width, + extents->x + extents->width); + float y1 = hb_max (paint->extents.y + paint->extents.height, + extents->y + extents->height); + paint->extents = {x0, y0, x1 - x0, y1 - y0}; + } + else + { + paint->extents = *extents; + paint->has_extents = true; + } +} + +/** + * hb_vector_paint_get_extents: + * @paint: a paint context. + * @extents: (out) (nullable): where to store current output extents. + * + * Gets current output extents from @paint. + * + * Return value: `true` if extents are set, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_paint_get_extents (hb_vector_paint_t *paint, + hb_vector_extents_t *extents) +{ + if (!paint->has_extents) + return false; + + if (extents) + *extents = paint->extents; + return true; +} + +/** + * hb_vector_paint_set_glyph_extents: + * @paint: a paint context. + * @glyph_extents: glyph extents in font units. + * + * Expands @paint extents using @glyph_extents under the current transform. + * + * Return value: `true` on success, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_paint_set_glyph_extents (hb_vector_paint_t *paint, + const hb_glyph_extents_t *glyph_extents) +{ + hb_bool_t has_extents = paint->has_extents; + hb_bool_t ret = hb_svg_set_glyph_extents_common (paint->transform, + paint->x_scale_factor, + paint->y_scale_factor, + glyph_extents, + &paint->extents, + &has_extents); + paint->has_extents = has_extents; + return ret; +} + +/** + * hb_vector_paint_set_foreground: + * @paint: a paint context. + * @foreground: foreground color used for COLR foreground paints. + * + * Sets fallback foreground color used by paint operations. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_set_foreground (hb_vector_paint_t *paint, + hb_color_t foreground) +{ + paint->foreground = foreground; +} + +/** + * hb_vector_paint_set_palette: + * @paint: a paint context. + * @palette: palette index for color glyph painting. + * + * Sets the color palette index used by paint operations. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_set_palette (hb_vector_paint_t *paint, + int palette) +{ + paint->palette = palette; +} + +/** + * hb_vector_paint_set_custom_palette_color: + * @paint: a paint context. + * @color_index: color index to override. + * @color: replacement color. + * + * Overrides one font palette color entry for subsequent paint operations. + * Overrides are keyed by @color_index and persist on @paint until cleared + * (or replaced for the same index). + * + * These overrides are consulted by paint operations that resolve CPAL + * entries, including SVG glyph content using `var(--colorN)`. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_set_custom_palette_color (hb_vector_paint_t *paint, + unsigned color_index, + hb_color_t color) +{ + paint->custom_palette_colors.set (color_index, color); +} + +/** + * hb_vector_paint_clear_custom_palette_colors: + * @paint: a paint context. + * + * Clears all custom palette color overrides previously set on @paint. + * + * After this call, palette lookups use the selected font palette without + * custom override entries. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_clear_custom_palette_colors (hb_vector_paint_t *paint) +{ + paint->custom_palette_colors.clear (); +} + +/** + * hb_vector_paint_get_funcs: + * + * Gets paint callbacks implemented by the vector paint backend. + * + * Return value: (transfer none): immutable #hb_paint_funcs_t singleton. + * + * Since: 13.0.0 + */ +hb_paint_funcs_t * +hb_vector_paint_get_funcs (void) +{ + return hb_vector_paint_funcs_get (); +} + +static hb_bool_t +hb_vector_paint_custom_palette_color (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + unsigned color_index, + hb_color_t *color, + void *user_data HB_UNUSED) +{ + hb_vector_paint_t *paint = (hb_vector_paint_t *) paint_data; + if (!paint || !color) + return false; + + hb_color_t *value = nullptr; + if (!paint->custom_palette_colors.has (color_index, &value) || !value) + return false; + *color = *value; + return true; +} + +/** + * hb_vector_paint_glyph: + * @paint: a paint context. + * @font: font object. + * @glyph: glyph ID. + * @pen_x: glyph x origin before context transform. + * @pen_y: glyph y origin before context transform. + * @extents_mode: extents update mode. + * + * Paints one color glyph into @paint. + * + * Return value: `true` if glyph paint data was emitted, `false` otherwise. + * + * Since: 13.0.0 + */ +hb_bool_t +hb_vector_paint_glyph (hb_vector_paint_t *paint, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y, + hb_vector_extents_mode_t extents_mode) +{ + float xx = paint->transform.xx; + float yx = paint->transform.yx; + float xy = paint->transform.xy; + float yy = paint->transform.yy; + float tx = paint->transform.x0 + xx * pen_x + xy * pen_y; + float ty = paint->transform.y0 + yx * pen_x + yy * pen_y; + + if (extents_mode == HB_VECTOR_EXTENTS_MODE_EXPAND) + { + hb_glyph_extents_t ge; + if (hb_font_get_glyph_extents (font, glyph, &ge)) + { + hb_bool_t has_extents = paint->has_extents; + hb_transform_t<> extents_transform = {xx, yx, -xy, -yy, tx, ty}; + hb_bool_t ret = hb_svg_set_glyph_extents_common (extents_transform, + paint->x_scale_factor, + paint->y_scale_factor, + &ge, + &paint->extents, + &has_extents); + paint->has_extents = has_extents; + (void) ret; + } + } + + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return false; + + bool can_cache = !paint->flat; + hb_svg_color_glyph_cache_key_t cache_key = hb_svg_color_glyph_cache_key (glyph, + (unsigned) paint->palette, + paint->foreground); + if (can_cache) + { + if (paint->defined_color_glyphs.has (cache_key)) + { + uint64_t entry = paint->defined_color_glyphs.get (cache_key); + unsigned def_id = hb_svg_cache_entry_def_id (entry); + bool image_like = hb_svg_cache_entry_image_like (entry); + auto &body = paint->current_body (); + hb_svg_append_str (&body, "precision, + paint->x_scale_factor, + paint->y_scale_factor, + tx, ty); + else + hb_svg_append_instance_transform (&body, paint->precision, + paint->x_scale_factor, + paint->y_scale_factor, + xx, yx, xy, yy, tx, ty); + hb_svg_append_str (&body, "\"/>\n"); + return true; + } + } + + bool has_svg_image = false; + if (can_cache) + { + if (unlikely (!paint->group_stack.push_or_fail (hb_vector_t {}))) + return false; + paint->current_color_glyph_has_svg_image = false; + } + + if (can_cache) + { + hb_codepoint_t old_gid = paint->current_svg_image_glyph; + hb_face_t *old_face = paint->current_face; + paint->current_svg_image_glyph = glyph; + paint->current_face = hb_font_get_face (font); + hb_bool_t ret = hb_font_paint_glyph_or_fail (font, glyph, + hb_vector_paint_get_funcs (), paint, + (unsigned) paint->palette, + paint->foreground); + paint->current_svg_image_glyph = old_gid; + paint->current_face = old_face; + if (unlikely (!ret)) + { + paint->group_stack.pop (); + return false; + } + + paint->captured_scratch = paint->group_stack.pop (); + has_svg_image = paint->current_color_glyph_has_svg_image; + if (unlikely (!paint->captured_scratch.length)) + return false; + + unsigned def_id = paint->color_glyph_counter++; + if (unlikely (!paint->defined_color_glyphs.set (cache_key, + hb_svg_pack_color_glyph_cache_entry (def_id, + has_svg_image)))) + return false; + + hb_svg_append_str (&paint->defs, "defs, def_id); + hb_svg_append_str (&paint->defs, "\">\n"); + hb_svg_append_len (&paint->defs, + paint->captured_scratch.arrayZ, + paint->captured_scratch.length); + hb_svg_append_str (&paint->defs, "\n"); + + auto &body = paint->current_body (); + hb_svg_append_str (&body, "precision, + paint->x_scale_factor, + paint->y_scale_factor, + tx, ty); + else + hb_svg_append_instance_transform (&body, paint->precision, + paint->x_scale_factor, + paint->y_scale_factor, + xx, yx, xy, yy, tx, ty); + hb_svg_append_str (&body, "\"/>\n"); + return true; + } + + auto &body = paint->current_body (); + hb_svg_append_str (&body, "precision, + paint->x_scale_factor, + paint->y_scale_factor, + xx, yx, xy, yy, tx, ty); + hb_svg_append_str (&body, "\">\n"); + hb_codepoint_t old_gid = paint->current_svg_image_glyph; + hb_face_t *old_face = paint->current_face; + paint->current_svg_image_glyph = glyph; + paint->current_face = hb_font_get_face (font); + hb_bool_t ret = hb_font_paint_glyph_or_fail (font, glyph, + hb_vector_paint_get_funcs (), paint, + (unsigned) paint->palette, + paint->foreground); + paint->current_svg_image_glyph = old_gid; + paint->current_face = old_face; + hb_svg_append_str (&body, "\n"); + return ret; +} + +/** + * hb_vector_svg_paint_set_flat: + * @paint: a paint context. + * @flat: whether to flatten paint output and disable glyph-group reuse. + * + * Enables or disables SVG paint flattening. + * + * Since: 13.0.0 + */ +void +hb_vector_svg_paint_set_flat (hb_vector_paint_t *paint, + hb_bool_t flat) +{ + paint->flat = !!flat; +} + +/** + * hb_vector_svg_paint_set_precision: + * @paint: a paint context. + * @precision: decimal precision. + * + * Sets numeric output precision for SVG paint output. + * + * Since: 13.0.0 + */ +void +hb_vector_svg_paint_set_precision (hb_vector_paint_t *paint, + unsigned precision) +{ + paint->precision = hb_min (precision, 12u); +} + +static void +hb_vector_paint_clear_render_state (hb_vector_paint_t *paint) +{ + paint->extents = {0, 0, 0, 0}; + paint->has_extents = false; + + paint->defs.clear (); + paint->path.clear (); + paint->group_stack.clear (); + paint->transform_group_open_mask = 0; + paint->transform_group_depth = 0; + paint->transform_group_overflow_depth = 0; + paint->clip_rect_counter = 0; + paint->gradient_counter = 0; + paint->color_glyph_counter = 0; + paint->current_color_glyph_has_svg_image = false; + paint->current_svg_image_glyph = HB_CODEPOINT_INVALID; + paint->current_face = nullptr; + paint->svg_image_counter = 0; + hb_set_clear (paint->defined_outlines); + hb_set_clear (paint->defined_clips); + paint->defined_color_glyphs.clear (); + paint->color_stops_scratch.clear (); + paint->subset_body_scratch.clear (); + paint->captured_scratch.clear (); +} + +/** + * hb_vector_paint_render: + * @paint: a paint context. + * + * Renders accumulated paint content to an SVG blob. + * + * Return value: (transfer full) (nullable): output blob, or `NULL` if rendering cannot proceed. + * + * Since: 13.0.0 + */ +hb_blob_t * +hb_vector_paint_render (hb_vector_paint_t *paint) +{ + if (paint->format != HB_VECTOR_FORMAT_SVG) + return nullptr; + if (!paint->has_extents) + return nullptr; + + if (unlikely (!hb_vector_paint_ensure_initialized (paint))) + return nullptr; + + hb_vector_t out; + hb_svg_recover_recycled_buffer (paint->recycled_blob, &out); + unsigned estimated = paint->defs.length + + paint->group_stack.arrayZ[0].length + + 320; + out.alloc (estimated); + hb_svg_append_str (&out, "extents.x, paint->precision); + hb_svg_append_c (&out, ' '); + hb_svg_append_num (&out, paint->extents.y, paint->precision); + hb_svg_append_c (&out, ' '); + hb_svg_append_num (&out, paint->extents.width, paint->precision); + hb_svg_append_c (&out, ' '); + hb_svg_append_num (&out, paint->extents.height, paint->precision); + hb_svg_append_str (&out, "\" width=\""); + hb_svg_append_num (&out, paint->extents.width, paint->precision); + hb_svg_append_str (&out, "\" height=\""); + hb_svg_append_num (&out, paint->extents.height, paint->precision); + hb_svg_append_str (&out, "\">\n"); + + if (paint->defs.length) + { + hb_svg_append_str (&out, "\n"); + hb_svg_append_len (&out, paint->defs.arrayZ, paint->defs.length); + hb_svg_append_str (&out, "\n"); + } + + paint->append_global_transform_prefix (&out); + hb_svg_append_len (&out, paint->group_stack.arrayZ[0].arrayZ, paint->group_stack.arrayZ[0].length); + paint->append_global_transform_suffix (&out); + + hb_svg_append_str (&out, "\n"); + + hb_blob_t *blob = hb_svg_blob_from_buffer (&paint->recycled_blob, &out); + + hb_vector_paint_clear_render_state (paint); + + return blob; +} + +/** + * hb_vector_paint_reset: + * @paint: a paint context. + * + * Resets @paint state and clears accumulated content. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_reset (hb_vector_paint_t *paint) +{ + paint->transform = {1, 0, 0, 1, 0, 0}; + paint->x_scale_factor = 1.f; + paint->y_scale_factor = 1.f; + paint->foreground = HB_COLOR (0, 0, 0, 255); + paint->palette = 0; + paint->precision = 2; + paint->flat = false; + hb_vector_paint_clear_render_state (paint); +} + +/** + * hb_vector_paint_recycle_blob: + * @paint: a paint context. + * @blob: (nullable): previously rendered blob to recycle. + * + * Provides a blob for internal buffer reuse by later render calls. + * + * Since: 13.0.0 + */ +void +hb_vector_paint_recycle_blob (hb_vector_paint_t *paint, + hb_blob_t *blob) +{ + hb_blob_destroy (paint->recycled_blob); + paint->recycled_blob = nullptr; + if (!blob || blob == hb_blob_get_empty ()) + return; + paint->recycled_blob = blob; +} diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-path.cc b/thirdparty/harfbuzz/upstream/hb-vector-svg-path.cc new file mode 100644 index 000000000..286bc31a6 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-path.cc @@ -0,0 +1,144 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-machinery.hh" +#include "hb-vector-svg-path.hh" +#include "hb-vector-svg-utils.hh" + +static void +hb_svg_path_move_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float to_x, float to_y, + void *) +{ + auto *s = (hb_svg_path_sink_t *) draw_data; + hb_svg_append_c (s->path, 'M'); + hb_svg_append_num (s->path, to_x, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, to_y, s->precision); +} + +static void +hb_svg_path_line_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float to_x, float to_y, + void *) +{ + auto *s = (hb_svg_path_sink_t *) draw_data; + hb_svg_append_c (s->path, 'L'); + hb_svg_append_num (s->path, to_x, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, to_y, s->precision); +} + +static void +hb_svg_path_quadratic_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float cx, float cy, + float to_x, float to_y, + void *) +{ + auto *s = (hb_svg_path_sink_t *) draw_data; + hb_svg_append_c (s->path, 'Q'); + hb_svg_append_num (s->path, cx, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, cy, s->precision); + hb_svg_append_c (s->path, ' '); + hb_svg_append_num (s->path, to_x, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, to_y, s->precision); +} + +static void +hb_svg_path_cubic_to (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + float c1x, float c1y, + float c2x, float c2y, + float to_x, float to_y, + void *) +{ + auto *s = (hb_svg_path_sink_t *) draw_data; + hb_svg_append_c (s->path, 'C'); + hb_svg_append_num (s->path, c1x, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, c1y, s->precision); + hb_svg_append_c (s->path, ' '); + hb_svg_append_num (s->path, c2x, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, c2y, s->precision); + hb_svg_append_c (s->path, ' '); + hb_svg_append_num (s->path, to_x, s->precision); + hb_svg_append_c (s->path, ','); + hb_svg_append_num (s->path, to_y, s->precision); +} + +static void +hb_svg_path_close_path (hb_draw_funcs_t *, + void *draw_data, + hb_draw_state_t *, + void *) +{ + auto *s = (hb_svg_path_sink_t *) draw_data; + hb_svg_append_c (s->path, 'Z'); +} + +static inline void +free_static_svg_path_draw_funcs (); + +static struct hb_svg_path_draw_funcs_lazy_loader_t + : hb_draw_funcs_lazy_loader_t +{ + static hb_draw_funcs_t *create () + { + hb_draw_funcs_t *funcs = hb_draw_funcs_create (); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) hb_svg_path_move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) hb_svg_path_line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) hb_svg_path_quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) hb_svg_path_cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) hb_svg_path_close_path, nullptr, nullptr); + hb_draw_funcs_make_immutable (funcs); + hb_atexit (free_static_svg_path_draw_funcs); + return funcs; + } +} static_svg_path_draw_funcs; + +static inline void +free_static_svg_path_draw_funcs () +{ + static_svg_path_draw_funcs.free_instance (); +} + +hb_draw_funcs_t * +hb_svg_path_draw_funcs_get (void) +{ + return static_svg_path_draw_funcs.get_unconst (); +} diff --git a/thirdparty/harfbuzz/upstream/test-serialize.cc b/thirdparty/harfbuzz/upstream/hb-vector-svg-path.hh similarity index 68% rename from thirdparty/harfbuzz/upstream/test-serialize.cc rename to thirdparty/harfbuzz/upstream/hb-vector-svg-path.hh index 4c90abb11..7e3b25c19 100644 --- a/thirdparty/harfbuzz/upstream/test-serialize.cc +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-path.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2022 Behdad Esfahbod + * Copyright © 2026 Behdad Esfahbod * * This is part of HarfBuzz, a text shaping library. * @@ -21,32 +21,23 @@ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * + * Author(s): Behdad Esfahbod */ -#include "hb.hh" -#include "hb-serialize.hh" -#include "hb-ot-layout-common.hh" +#ifndef HB_VECTOR_SVG_PATH_HH +#define HB_VECTOR_SVG_PATH_HH -using OT::Layout::Common::Coverage; +#include "hb.hh" +#include "hb-vector.hh" +#include "hb-draw.h" -int -main (int argc, char **argv) +struct hb_svg_path_sink_t { - char buf[16384]; - - hb_serialize_context_t s (buf, sizeof (buf)); - - hb_sorted_vector_t v{1, 2, 5}; - - auto c = s.start_serialize (); - - c->serialize (&s, hb_iter (v)); - - s.end_serialize (); + hb_vector_t *path; + unsigned precision; +}; - hb_bytes_t bytes = s.copy_bytes (); - assert (bytes.length == 10); - bytes.fini (); +HB_INTERNAL hb_draw_funcs_t * +hb_svg_path_draw_funcs_get (void); - return 0; -} +#endif /* HB_VECTOR_SVG_PATH_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-subset.cc b/thirdparty/harfbuzz/upstream/hb-vector-svg-subset.cc new file mode 100644 index 000000000..b46f4047b --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-subset.cc @@ -0,0 +1,454 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-face.hh" +#include "hb-vector-svg-subset.hh" +#ifndef HB_NO_SVG +#include "OT/Color/svg/svg.hh" +#include "hb-raster-svg-parse.hh" +#endif +#include "hb-vector-svg-utils.hh" +#include "hb-map.hh" +#include "hb-ot-color.h" + +#include +#include +#include + +#ifndef HB_NO_SVG +#include "hb-vector-svg.hh" + +static bool +hb_svg_append_with_prefix (hb_vector_t *out, + const char *s, + unsigned n, + const char *prefix, + unsigned prefix_len) +{ + unsigned i = 0; + while (i < n) + { + if (i + 4 <= n && !memcmp (s + i, "id=\"", 4)) + { + if (!hb_svg_append_len (out, s + i, 4)) return false; + i += 4; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '"') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 4 <= n && !memcmp (s + i, "id='", 4)) + { + if (!hb_svg_append_len (out, s + i, 4)) return false; + i += 4; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '\'') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 7 <= n && !memcmp (s + i, "href=\"#", 7)) + { + if (!hb_svg_append_len (out, s + i, 7)) return false; + i += 7; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '"') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 7 <= n && !memcmp (s + i, "href='#", 7)) + { + if (!hb_svg_append_len (out, s + i, 7)) return false; + i += 7; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '\'') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 13 <= n && !memcmp (s + i, "xlink:href=\"#", 13)) + { + if (!hb_svg_append_len (out, s + i, 13)) return false; + i += 13; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '"') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 13 <= n && !memcmp (s + i, "xlink:href='#", 13)) + { + if (!hb_svg_append_len (out, s + i, 13)) return false; + i += 13; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '\'') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 5 <= n && !memcmp (s + i, "url(#", 5)) + { + if (!hb_svg_append_len (out, s + i, 5)) return false; + i += 5; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != ')') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 6 <= n && !memcmp (s + i, "url(\"#", 6)) + { + if (!hb_svg_append_len (out, s + i, 6)) return false; + i += 6; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '"') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (i + 6 <= n && !memcmp (s + i, "url('#", 6)) + { + if (!hb_svg_append_len (out, s + i, 6)) return false; + i += 6; + if (!hb_svg_append_len (out, prefix, prefix_len)) return false; + while (i < n && s[i] != '\'') + { + if (!hb_svg_append_c (out, s[i])) return false; + i++; + } + continue; + } + if (!hb_svg_append_c (out, s[i])) + return false; + i++; + } + return true; +} + +static bool +hb_svg_add_unique_id (hb_vector_t *v, + hb_hashmap_t *seen_ids, + const char *p, + unsigned n) +{ + if (!n) return true; + OT::SVG::svg_id_span_t key = {p, n}; + if (seen_ids->has (key)) + return true; + if (unlikely (!seen_ids->set (key, true))) + return false; + auto *slot = v->push (); + if (unlikely (v->in_error ())) + return false; + *slot = key; + return true; +} + +static bool +hb_svg_collect_refs (const char *s, + unsigned n, + hb_vector_t *ids, + hb_hashmap_t *seen_ids) +{ + unsigned i = 0; + while (i < n) + { + if (i + 7 <= n && !memcmp (s + i, "href=\"#", 7)) + { + i += 7; + unsigned b = i; + while (i < n && s[i] != '"' && s[i] != '\'' && s[i] != ' ' && s[i] != '>') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + if (i + 7 <= n && !memcmp (s + i, "href='#", 7)) + { + i += 7; + unsigned b = i; + while (i < n && s[i] != '\'' && s[i] != '"' && s[i] != ' ' && s[i] != '>') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + if (i + 13 <= n && !memcmp (s + i, "xlink:href=\"#", 13)) + { + i += 13; + unsigned b = i; + while (i < n && s[i] != '"' && s[i] != '\'' && s[i] != ' ' && s[i] != '>') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + if (i + 13 <= n && !memcmp (s + i, "xlink:href='#", 13)) + { + i += 13; + unsigned b = i; + while (i < n && s[i] != '\'' && s[i] != '"' && s[i] != ' ' && s[i] != '>') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + if (i + 5 <= n && !memcmp (s + i, "url(#", 5)) + { + i += 5; + unsigned b = i; + while (i < n && s[i] != ')') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + if (i + 6 <= n && !memcmp (s + i, "url(\"#", 6)) + { + i += 6; + unsigned b = i; + while (i < n && s[i] != '"') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + if (i + 6 <= n && !memcmp (s + i, "url('#", 6)) + { + i += 6; + unsigned b = i; + while (i < n && s[i] != '\'') i++; + if (i > b && unlikely (!hb_svg_add_unique_id (ids, seen_ids, s + b, i - b))) return false; + continue; + } + i++; + } + return true; +} + +static bool +hb_svg_find_root_open_tag (const char *svg, + unsigned len, + unsigned *root_open_len, + bool *missing_viewport) +{ + hb_svg_xml_parser_t parser (svg, len); + hb_svg_token_type_t tok = parser.next (); + if (!((tok == SVG_TOKEN_OPEN_TAG || tok == SVG_TOKEN_SELF_CLOSE_TAG) && + parser.tag_name.eq ("svg"))) + return false; + + if (missing_viewport) + { + *missing_viewport = + parser.find_attr ("width").is_null () || + parser.find_attr ("height").is_null (); + } + + if (root_open_len) + *root_open_len = (unsigned) (parser.p - parser.tag_start); + return true; +} + +bool +hb_svg_subset_glyph_image (hb_face_t *face, + hb_blob_t *image, + hb_codepoint_t glyph, + unsigned *image_counter, + hb_vector_t *defs_dst, + hb_vector_t *body_dst) +{ + bool ret = false; + hb_blob_t *normalized_image = nullptr; + unsigned len = 0; + const char *svg = nullptr; + unsigned doc_index = 0; + hb_codepoint_t start_glyph = HB_CODEPOINT_INVALID; + hb_codepoint_t end_glyph = HB_CODEPOINT_INVALID; + const OT::SVG::svg_doc_cache_t *doc_cache = nullptr; + unsigned glyph_start = 0, glyph_end = 0; + const hb_vector_t *defs_entries = nullptr; + hb_vector_t needed_ids; + hb_hashmap_t needed_ids_set; + hb_vector_t chosen_defs; + hb_vector_t chosen_def_marks; + unsigned root_open_len = 0; + bool glyph_is_root_svg = false; + bool root_missing_viewport = false; + char prefix[32]; + int prefix_len = 0; + + if (glyph == HB_CODEPOINT_INVALID || !image_counter || !defs_dst || !body_dst) + goto done; + + normalized_image = OT::hb_ot_svg_reference_normalized_blob (image, &svg, &len); + if (!normalized_image || !svg || !len) + goto done; + + if (!hb_ot_color_glyph_get_svg_document_index (face, glyph, &doc_index)) + goto done; + + if (!hb_ot_color_get_svg_document_glyph_range (face, doc_index, &start_glyph, &end_glyph)) + goto done; + + doc_cache = face->table.SVG->get_or_create_doc_cache (normalized_image, svg, len, + doc_index, start_glyph, end_glyph); + if (!doc_cache) + goto done; + svg = face->table.SVG->doc_cache_get_svg (doc_cache, &len); + + if (!face->table.SVG->doc_cache_get_glyph_span (doc_cache, glyph, &glyph_start, &glyph_end)) + goto done; + + defs_entries = face->table.SVG->doc_cache_get_defs_entries (doc_cache); + if (!hb_svg_find_root_open_tag (svg, len, &root_open_len, &root_missing_viewport)) + goto done; + glyph_is_root_svg = glyph_start == 0; + + needed_ids.alloc (16); + if (!hb_svg_collect_refs (svg + glyph_start, glyph_end - glyph_start, + &needed_ids, &needed_ids_set)) + goto done; + + chosen_defs.alloc (16); + if (unlikely (!chosen_def_marks.resize ((int) defs_entries->length))) + goto done; + hb_memset (chosen_def_marks.arrayZ, 0, defs_entries->length); + for (unsigned qi = 0; qi < needed_ids.length; qi++) + { + const auto &need = needed_ids.arrayZ[qi]; + for (unsigned i = 0; i < defs_entries->length; i++) + { + const auto &e = defs_entries->arrayZ[i]; + if (e.id.len == need.len && !memcmp (e.id.p, need.p, need.len)) + { + if (!chosen_def_marks.arrayZ[i]) + { + chosen_def_marks.arrayZ[i] = 1; + if (unlikely (!chosen_defs.push_or_fail (i))) + goto done; + if (!hb_svg_collect_refs (svg + e.start, e.end - e.start, + &needed_ids, &needed_ids_set)) + goto done; + } + break; + } + } + } + + prefix_len = snprintf (prefix, sizeof (prefix), "hbimg%u_", (*image_counter)++); + if (prefix_len <= 0 || (unsigned) prefix_len >= sizeof (prefix)) + goto done; + + body_dst->alloc (body_dst->length + (glyph_end - glyph_start) + 64); + + for (unsigned i = 0; i < chosen_defs.length; i++) + { + const auto &e = defs_entries->arrayZ[chosen_defs.arrayZ[i]]; + if (!hb_svg_append_with_prefix (defs_dst, svg + e.start, e.end - e.start, prefix, (unsigned) prefix_len)) + goto done; + if (!hb_svg_append_c (defs_dst, '\n')) + goto done; + } + + if (glyph_is_root_svg && root_missing_viewport && root_open_len > 1) + { + unsigned upem = face->get_upem (); + if (!hb_svg_append_with_prefix (body_dst, + svg + glyph_start, + root_open_len - 1, + prefix, + (unsigned) prefix_len)) + goto done; + if (!hb_svg_append_str (body_dst, " width=\"")) + goto done; + if (!hb_svg_append_unsigned (body_dst, upem)) + goto done; + if (!hb_svg_append_str (body_dst, "\" height=\"")) + goto done; + if (!hb_svg_append_unsigned (body_dst, upem)) + goto done; + if (!hb_svg_append_str (body_dst, "\" overflow=\"visible")) + goto done; + if (!hb_svg_append_c (body_dst, '"')) + goto done; + if (!hb_svg_append_c (body_dst, '>')) + goto done; + ret = hb_svg_append_with_prefix (body_dst, + svg + glyph_start + root_open_len, + glyph_end - glyph_start - root_open_len, + prefix, + (unsigned) prefix_len); + } + else if (glyph_is_root_svg && root_open_len > 1) + { + if (!hb_svg_append_with_prefix (body_dst, + svg + glyph_start, + root_open_len - 1, + prefix, + (unsigned) prefix_len)) + goto done; + if (!hb_svg_append_str (body_dst, " overflow=\"visible\"")) + goto done; + if (!hb_svg_append_c (body_dst, '>')) + goto done; + ret = hb_svg_append_with_prefix (body_dst, + svg + glyph_start + root_open_len, + glyph_end - glyph_start - root_open_len, + prefix, + (unsigned) prefix_len); + } + else + ret = hb_svg_append_with_prefix (body_dst, + svg + glyph_start, + glyph_end - glyph_start, + prefix, + (unsigned) prefix_len); + +done: + hb_blob_destroy (normalized_image); + return ret; +} +#else +bool +hb_svg_subset_glyph_image (hb_face_t *face HB_UNUSED, + hb_blob_t *image HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + unsigned *image_counter HB_UNUSED, + hb_vector_t *defs_dst HB_UNUSED, + hb_vector_t *body_dst HB_UNUSED) +{ + return false; +} +#endif diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-subset.hh b/thirdparty/harfbuzz/upstream/hb-vector-svg-subset.hh new file mode 100644 index 000000000..32cb66c8d --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-subset.hh @@ -0,0 +1,44 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_VECTOR_SVG_SUBSET_HH +#define HB_VECTOR_SVG_SUBSET_HH + +#include "hb.hh" +#include "hb-vector.hh" +#include "hb-blob.hh" +#include "hb-face.h" + +HB_INTERNAL bool +hb_svg_subset_glyph_image (hb_face_t *face, + hb_blob_t *image, + hb_codepoint_t glyph, + unsigned *image_counter, + hb_vector_t *defs_dst, + hb_vector_t *body_dst); + + +#endif /* HB_VECTOR_SVG_SUBSET_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-utils.cc b/thirdparty/harfbuzz/upstream/hb-vector-svg-utils.cc new file mode 100644 index 000000000..766b98e7f --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-utils.cc @@ -0,0 +1,92 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-machinery.hh" +#include "hb-vector-svg-utils.hh" + +#include + +struct hb_svg_decimal_point_t +{ + char value[8]; +}; + +static hb_svg_decimal_point_t hb_svg_decimal_point_default = {{'.', '\0'}}; + +static inline void free_static_svg_decimal_point (); + +static struct hb_svg_decimal_point_lazy_loader_t + : hb_lazy_loader_t +{ + static hb_svg_decimal_point_t *create () + { + auto *p = (hb_svg_decimal_point_t *) hb_calloc (1, sizeof (hb_svg_decimal_point_t)); + if (!p) + return nullptr; + + p->value[0] = '.'; + p->value[1] = '\0'; + +#ifndef HB_NO_SETLOCALE + lconv *lc = nullptr; +#ifdef HAVE_LOCALECONV_L + hb_locale_t current_locale = hb_uselocale ((hb_locale_t) 0); + if (current_locale) + lc = localeconv_l (current_locale); +#endif + if (!lc) + lc = localeconv (); + if (lc && lc->decimal_point && lc->decimal_point[0]) + { + strncpy (p->value, lc->decimal_point, sizeof (p->value) - 1); + p->value[sizeof (p->value) - 1] = '\0'; + } +#endif + + hb_atexit (free_static_svg_decimal_point); + return p; + } + + static void destroy (hb_svg_decimal_point_t *p) + { hb_free (p); } + + static const hb_svg_decimal_point_t *get_null () + { return &hb_svg_decimal_point_default; } +} static_svg_decimal_point; + +static inline void +free_static_svg_decimal_point () +{ + static_svg_decimal_point.free_instance (); +} + +const char * +hb_svg_decimal_point_get (void) +{ + return static_svg_decimal_point.get_unconst ()->value; +} diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg-utils.hh b/thirdparty/harfbuzz/upstream/hb-vector-svg-utils.hh new file mode 100644 index 000000000..138b51b66 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg-utils.hh @@ -0,0 +1,129 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_VECTOR_SVG_UTILS_HH +#define HB_VECTOR_SVG_UTILS_HH + +#include "hb.hh" +#include "hb-vector.hh" +#include +#include +#include + +HB_INTERNAL const char * +hb_svg_decimal_point_get (void); + +static inline bool +hb_svg_append_len (hb_vector_t *buf, + const char *s, + unsigned len) +{ + unsigned old_len = buf->length; + if (unlikely (!buf->resize_dirty ((int) (old_len + len)))) + return false; + hb_memcpy (buf->arrayZ + old_len, s, len); + return true; +} + +static inline bool +hb_svg_append_c (hb_vector_t *buf, char c) +{ + return buf->push_or_fail (c); +} + +static inline void +hb_svg_append_num (hb_vector_t *buf, + float v, + unsigned precision, + bool keep_nonzero = false) +{ + unsigned effective_precision = precision; + if (effective_precision > 12) + effective_precision = 12; + if (keep_nonzero && v != 0.f) + while (effective_precision < 12) + { + float rounded_zero_threshold = 0.5f; + for (unsigned i = 0; i < effective_precision; i++) + rounded_zero_threshold *= 0.1f; + if (fabsf (v) >= rounded_zero_threshold) + break; + effective_precision++; + } + + float rounded_zero_threshold = 0.5f; + for (unsigned i = 0; i < effective_precision; i++) + rounded_zero_threshold *= 0.1f; + if (fabsf (v) < rounded_zero_threshold) + v = 0.f; + + if (!(v == v) || !std::isfinite (v)) + { + hb_svg_append_c (buf, '0'); + return; + } + + static const char float_formats[13][6] = { + "%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f", + "%.7f", "%.8f", "%.9f", "%.10f", "%.11f", "%.12f", + }; + char out[128]; + snprintf (out, sizeof (out), float_formats[effective_precision], (double) v); + + const char *decimal_point = hb_svg_decimal_point_get (); + + if (decimal_point[0] != '.' || decimal_point[1] != '\0') + { + char *p = strstr (out, decimal_point); + if (p) + { + unsigned dp_len = (unsigned) strlen (decimal_point); + unsigned tail_len = (unsigned) strlen (p + dp_len); + memmove (p + 1, p + dp_len, tail_len + 1); + *p = '.'; + } + } + + char *dot = strchr (out, '.'); + if (dot) + { + char *end = out + strlen (out) - 1; + while (end > dot && *end == '0') + *end-- = '\0'; + if (end == dot) + *end = '\0'; + } + + hb_svg_append_len (buf, out, (unsigned) strlen (out)); +} + +static inline unsigned +hb_svg_scale_precision (unsigned precision) +{ + return precision < 7 ? 7 : precision; +} + +#endif /* HB_VECTOR_SVG_UTILS_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-vector-svg.hh b/thirdparty/harfbuzz/upstream/hb-vector-svg.hh new file mode 100644 index 000000000..418d5bc46 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector-svg.hh @@ -0,0 +1,366 @@ +#ifndef HB_VECTOR_SVG_HH +#define HB_VECTOR_SVG_HH + +#include "hb-vector.h" + +static inline bool +hb_svg_append_str (hb_vector_t *buf, const char *s) +{ + return hb_svg_append_len (buf, s, (unsigned) strlen (s)); +} + +static inline bool +hb_svg_append_unsigned (hb_vector_t *buf, unsigned v) +{ + char tmp[10]; + unsigned n = 0; + do { + tmp[n++] = (char) ('0' + (v % 10)); + v /= 10; + } while (v); + + unsigned old_len = buf->length; + if (unlikely (!buf->resize_dirty ((int) (old_len + n)))) + return false; + + for (unsigned i = 0; i < n; i++) + buf->arrayZ[old_len + i] = tmp[n - 1 - i]; + return true; +} + +static inline bool +hb_svg_append_hex_byte (hb_vector_t *buf, unsigned v) +{ + static const char hex[] = "0123456789ABCDEF"; + char tmp[2] = {hex[(v >> 4) & 15], hex[v & 15]}; + return hb_svg_append_len (buf, tmp, 2); +} + +static inline bool +hb_svg_append_base64 (hb_vector_t *buf, + const uint8_t *data, + unsigned len) +{ + static const char b64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + unsigned out_len = ((len + 2) / 3) * 4; + unsigned old_len = buf->length; + if (unlikely (!buf->resize_dirty ((int) (old_len + out_len)))) + return false; + + char *dst = buf->arrayZ + old_len; + unsigned di = 0; + unsigned i = 0; + while (i + 2 < len) + { + unsigned v = ((unsigned) data[i] << 16) | + ((unsigned) data[i + 1] << 8) | + ((unsigned) data[i + 2]); + dst[di++] = b64[(v >> 18) & 63]; + dst[di++] = b64[(v >> 12) & 63]; + dst[di++] = b64[(v >> 6) & 63]; + dst[di++] = b64[v & 63]; + i += 3; + } + + if (i < len) + { + unsigned v = (unsigned) data[i] << 16; + if (i + 1 < len) + v |= (unsigned) data[i + 1] << 8; + dst[di++] = b64[(v >> 18) & 63]; + dst[di++] = b64[(v >> 12) & 63]; + dst[di++] = (i + 1 < len) ? b64[(v >> 6) & 63] : '='; + dst[di++] = '='; + } + + return true; +} + +struct hb_svg_blob_meta_t +{ + char *data; + int allocated; + bool transferred; + bool in_replace; +}; + +static hb_user_data_key_t hb_svg_blob_meta_user_data_key; + +static inline void +hb_svg_blob_meta_set_buffer (hb_svg_blob_meta_t *meta, + char *data, + int allocated) +{ + meta->data = data; + meta->allocated = allocated; + meta->transferred = false; +} + +static inline void +hb_svg_blob_meta_release_buffer (hb_svg_blob_meta_t *meta) +{ + if (!meta) + return; + if (!meta->transferred && meta->data) + hb_free (meta->data); + meta->data = nullptr; + meta->allocated = 0; + meta->transferred = true; +} + +static inline void +hb_svg_blob_meta_destroy (void *data) +{ + auto *meta = (hb_svg_blob_meta_t *) data; + hb_svg_blob_meta_release_buffer (meta); + if (meta->in_replace) + { + meta->in_replace = false; + return; + } + hb_free (meta); +} + +static inline hb_blob_t * +hb_svg_blob_from_buffer (hb_blob_t **recycled_blob, + hb_vector_t *buf) +{ + unsigned len = 0; + int allocated = 0; + char *data = buf->steal (&len, &allocated); + if (!data) + return nullptr; + + hb_blob_t *blob = nullptr; + if (*recycled_blob) + blob = *recycled_blob; + bool reused_blob = blob && blob != hb_blob_get_empty (); + bool new_meta = false; + auto *meta = reused_blob + ? (hb_svg_blob_meta_t *) hb_blob_get_user_data (blob, &hb_svg_blob_meta_user_data_key) + : nullptr; + if (!meta) + { + meta = (hb_svg_blob_meta_t *) hb_malloc (sizeof (hb_svg_blob_meta_t)); + if (!meta) + { + hb_free (data); + return nullptr; + } + meta->data = nullptr; + meta->allocated = 0; + meta->transferred = true; + meta->in_replace = false; + new_meta = true; + } + + if (reused_blob) + { + meta->in_replace = true; + blob->replace_buffer (data, len, HB_MEMORY_MODE_WRITABLE, meta, hb_svg_blob_meta_destroy); + hb_svg_blob_meta_set_buffer (meta, data, allocated); + } + else + { + hb_svg_blob_meta_set_buffer (meta, data, allocated); + blob = hb_blob_create_or_fail (data, len, HB_MEMORY_MODE_WRITABLE, meta, hb_svg_blob_meta_destroy); + if (unlikely (!blob)) + return nullptr; + } + + if (unlikely (blob == hb_blob_get_empty ())) + { + if (new_meta) + hb_free (meta); + hb_free (data); + return nullptr; + } + + if (new_meta && + !hb_blob_set_user_data (blob, + &hb_svg_blob_meta_user_data_key, + meta, + nullptr, + true)) + { + if (!reused_blob) + hb_blob_destroy (blob); + return nullptr; + } + + if (*recycled_blob) + *recycled_blob = nullptr; + + return blob; +} + +static inline void +hb_svg_recover_recycled_buffer (hb_blob_t *blob, + hb_vector_t *buf) +{ + if (!blob) + return; + + auto *meta = (hb_svg_blob_meta_t *) hb_blob_get_user_data (blob, &hb_svg_blob_meta_user_data_key); + if (!meta || meta->transferred || !meta->data) + return; + + buf->recycle_buffer (meta->data, 0, meta->allocated); + meta->data = nullptr; + meta->allocated = 0; + meta->transferred = true; +} + +static inline void +hb_svg_append_color (hb_vector_t *buf, + hb_color_t color, + bool with_alpha) +{ + static const char hex[] = "0123456789ABCDEF"; + unsigned r = hb_color_get_red (color); + unsigned g = hb_color_get_green (color); + unsigned b = hb_color_get_blue (color); + unsigned a = hb_color_get_alpha (color); + hb_svg_append_c (buf, '#'); + if (((r >> 4) == (r & 0xF)) && + ((g >> 4) == (g & 0xF)) && + ((b >> 4) == (b & 0xF))) + { + hb_svg_append_c (buf, hex[r & 0xF]); + hb_svg_append_c (buf, hex[g & 0xF]); + hb_svg_append_c (buf, hex[b & 0xF]); + } + else + { + hb_svg_append_hex_byte (buf, r); + hb_svg_append_hex_byte (buf, g); + hb_svg_append_hex_byte (buf, b); + } + if (with_alpha && a != 255) + { + hb_svg_append_str (buf, "\" fill-opacity=\""); + hb_svg_append_num (buf, a / 255.f, 4); + } +} + +static inline void +hb_svg_transform_point (const hb_transform_t<> &t, + float x_scale_factor, + float y_scale_factor, + float x, float y, + float *tx, float *ty) +{ + float xx = x, yy = y; + t.transform_point (xx, yy); + *tx = xx / (x_scale_factor > 0 ? x_scale_factor : 1.f); + *ty = yy / (y_scale_factor > 0 ? y_scale_factor : 1.f); +} + +static inline hb_bool_t +hb_svg_set_glyph_extents_common (const hb_transform_t<> &transform, + float x_scale_factor, + float y_scale_factor, + const hb_glyph_extents_t *glyph_extents, + hb_vector_extents_t *extents, + hb_bool_t *has_extents) +{ + float x0 = (float) glyph_extents->x_bearing; + float y0 = (float) glyph_extents->y_bearing; + float x1 = x0 + glyph_extents->width; + float y1 = y0 + glyph_extents->height; + + float px[4] = {x0, x0, x1, x1}; + float py[4] = {y0, y1, y0, y1}; + + float tx, ty; + hb_svg_transform_point (transform, x_scale_factor, y_scale_factor, px[0], py[0], &tx, &ty); + float tx_min = tx, tx_max = tx; + float ty_min = ty, ty_max = ty; + + for (unsigned i = 1; i < 4; i++) + { + hb_svg_transform_point (transform, x_scale_factor, y_scale_factor, px[i], py[i], &tx, &ty); + tx_min = hb_min (tx_min, tx); + tx_max = hb_max (tx_max, tx); + ty_min = hb_min (ty_min, ty); + ty_max = hb_max (ty_max, ty); + } + + if (tx_max <= tx_min || ty_max <= ty_min) + return false; + + if (*has_extents) + { + float x0 = hb_min (extents->x, tx_min); + float y0 = hb_min (extents->y, ty_min); + float x1 = hb_max (extents->x + extents->width, tx_max); + float y1 = hb_max (extents->y + extents->height, ty_max); + *extents = {x0, y0, x1 - x0, y1 - y0}; + } + else + { + *extents = {tx_min, ty_min, tx_max - tx_min, ty_max - ty_min}; + *has_extents = true; + } + return true; +} + +static inline void +hb_svg_append_instance_transform (hb_vector_t *out, + unsigned precision, + float x_scale_factor, + float y_scale_factor, + float xx, float yx, + float xy, float yy, + float tx, float ty) +{ + unsigned sprec = hb_svg_scale_precision (precision); + if (xx == 1.f && yx == 0.f && xy == 0.f && yy == 1.f) + { + float sx = 1.f / x_scale_factor; + float sy = 1.f / y_scale_factor; + hb_svg_append_str (out, "translate("); + hb_svg_append_num (out, tx / x_scale_factor, precision); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, -ty / y_scale_factor, precision); + hb_svg_append_str (out, ") scale("); + hb_svg_append_num (out, sx, sprec, true); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, -sy, sprec, true); + hb_svg_append_c (out, ')'); + } + else + { + hb_svg_append_str (out, "matrix("); + hb_svg_append_num (out, xx / x_scale_factor, sprec, true); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, yx / y_scale_factor, sprec, true); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, -xy / x_scale_factor, sprec, true); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, -yy / y_scale_factor, sprec, true); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, tx / x_scale_factor, precision); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, -ty / y_scale_factor, precision); + hb_svg_append_c (out, ')'); + } +} + +static inline void +hb_svg_append_image_instance_translate (hb_vector_t *out, + unsigned precision, + float x_scale_factor, + float y_scale_factor, + float tx, float ty) +{ + hb_svg_append_str (out, "translate("); + hb_svg_append_num (out, tx / x_scale_factor, precision); + hb_svg_append_c (out, ','); + hb_svg_append_num (out, -ty / y_scale_factor, precision); + hb_svg_append_c (out, ')'); +} + +#endif /* HB_VECTOR_SVG_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb-vector.cc b/thirdparty/harfbuzz/upstream/hb-vector.cc new file mode 100644 index 000000000..2b4222535 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector.cc @@ -0,0 +1,41 @@ +/* + * Copyright © 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#include "hb.hh" + +#include "hb-vector.h" + +/** + * SECTION:hb-vector + * @title: hb-vector + * @short_description: Glyph vector conversion + * @include: hb-vector.h + * + * Functions for converting glyph draw and paint callbacks to vector output. + * + * The initial backend is SVG. Extents must be set before calling render + * functions; otherwise render returns `NULL`. + **/ diff --git a/thirdparty/harfbuzz/upstream/hb-vector.h b/thirdparty/harfbuzz/upstream/hb-vector.h new file mode 100644 index 000000000..dd32f2ec8 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-vector.h @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2026 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author(s): Behdad Esfahbod + */ + +#ifndef HB_VECTOR_H +#define HB_VECTOR_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/** + * hb_vector_format_t: + * @HB_VECTOR_FORMAT_INVALID: Invalid format. + * @HB_VECTOR_FORMAT_SVG: SVG output. + * + * Output format for vector conversion. + * + * Since: 13.0.0 + */ +typedef enum { + HB_VECTOR_FORMAT_INVALID = HB_TAG_NONE, + HB_VECTOR_FORMAT_SVG = HB_TAG ('s','v','g',' '), +} hb_vector_format_t; + +/** + * hb_vector_extents_t: + * @x: Left edge of the output coordinate system. + * @y: Top edge of the output coordinate system. + * @width: Width of the output coordinate system. + * @height: Height of the output coordinate system. + * + * Vector output extents, mapped to SVG viewBox. + * + * Since: 13.0.0 + */ +typedef struct hb_vector_extents_t { + float x, y; + float width, height; +} hb_vector_extents_t; + +/** + * hb_vector_extents_mode_t: + * @HB_VECTOR_EXTENTS_MODE_NONE: Do not update extents. + * @HB_VECTOR_EXTENTS_MODE_EXPAND: Union glyph ink extents into current extents. + * + * Controls whether convenience glyph APIs update context extents. + * + * Since: 13.0.0 + */ +typedef enum { + HB_VECTOR_EXTENTS_MODE_NONE = 0, + HB_VECTOR_EXTENTS_MODE_EXPAND = 1, +} hb_vector_extents_mode_t; + +/** + * hb_vector_draw_t: + * + * Opaque draw context for vector outline conversion. + * + * Since: 13.0.0 + */ +typedef struct hb_vector_draw_t hb_vector_draw_t; + +/** + * hb_vector_paint_t: + * + * Opaque paint context for vector color-glyph conversion. + * + * Since: 13.0.0 + */ +typedef struct hb_vector_paint_t hb_vector_paint_t; + +/* hb_vector_draw_t */ + +HB_EXTERN hb_vector_draw_t * +hb_vector_draw_create_or_fail (hb_vector_format_t format); + +HB_EXTERN hb_vector_draw_t * +hb_vector_draw_reference (hb_vector_draw_t *draw); + +HB_EXTERN void +hb_vector_draw_destroy (hb_vector_draw_t *draw); + +HB_EXTERN hb_bool_t +hb_vector_draw_set_user_data (hb_vector_draw_t *draw, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace); + +HB_EXTERN void * +hb_vector_draw_get_user_data (hb_vector_draw_t *draw, + hb_user_data_key_t *key); + +HB_EXTERN void +hb_vector_draw_set_transform (hb_vector_draw_t *draw, + float xx, float yx, + float xy, float yy, + float dx, float dy); + +HB_EXTERN void +hb_vector_draw_get_transform (hb_vector_draw_t *draw, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy); + +HB_EXTERN void +hb_vector_draw_set_scale_factor (hb_vector_draw_t *draw, + float x_scale_factor, + float y_scale_factor); + +HB_EXTERN void +hb_vector_draw_get_scale_factor (hb_vector_draw_t *draw, + float *x_scale_factor, + float *y_scale_factor); + +HB_EXTERN void +hb_vector_draw_set_extents (hb_vector_draw_t *draw, + const hb_vector_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_vector_draw_get_extents (hb_vector_draw_t *draw, + hb_vector_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_vector_draw_set_glyph_extents (hb_vector_draw_t *draw, + const hb_glyph_extents_t *glyph_extents); + +HB_EXTERN hb_draw_funcs_t * +hb_vector_draw_get_funcs (void); + +HB_EXTERN hb_bool_t +hb_vector_draw_glyph (hb_vector_draw_t *draw, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y, + hb_vector_extents_mode_t extents_mode); + +HB_EXTERN void +hb_vector_svg_set_flat (hb_vector_draw_t *draw, + hb_bool_t flat); + +HB_EXTERN void +hb_vector_svg_set_precision (hb_vector_draw_t *draw, + unsigned precision); + +HB_EXTERN hb_blob_t * +hb_vector_draw_render (hb_vector_draw_t *draw); + +HB_EXTERN void +hb_vector_draw_reset (hb_vector_draw_t *draw); + +HB_EXTERN void +hb_vector_draw_recycle_blob (hb_vector_draw_t *draw, + hb_blob_t *blob); + + +/* hb_vector_paint_t */ + +HB_EXTERN hb_vector_paint_t * +hb_vector_paint_create_or_fail (hb_vector_format_t format); + +HB_EXTERN hb_vector_paint_t * +hb_vector_paint_reference (hb_vector_paint_t *paint); + +HB_EXTERN void +hb_vector_paint_destroy (hb_vector_paint_t *paint); + +HB_EXTERN hb_bool_t +hb_vector_paint_set_user_data (hb_vector_paint_t *paint, + hb_user_data_key_t *key, + void *data, + hb_destroy_func_t destroy, + hb_bool_t replace); + +HB_EXTERN void * +hb_vector_paint_get_user_data (hb_vector_paint_t *paint, + hb_user_data_key_t *key); + +HB_EXTERN void +hb_vector_paint_set_transform (hb_vector_paint_t *paint, + float xx, float yx, + float xy, float yy, + float dx, float dy); + +HB_EXTERN void +hb_vector_paint_get_transform (hb_vector_paint_t *paint, + float *xx, float *yx, + float *xy, float *yy, + float *dx, float *dy); + +HB_EXTERN void +hb_vector_paint_set_scale_factor (hb_vector_paint_t *paint, + float x_scale_factor, + float y_scale_factor); + +HB_EXTERN void +hb_vector_paint_get_scale_factor (hb_vector_paint_t *paint, + float *x_scale_factor, + float *y_scale_factor); + +HB_EXTERN void +hb_vector_paint_set_extents (hb_vector_paint_t *paint, + const hb_vector_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_vector_paint_get_extents (hb_vector_paint_t *paint, + hb_vector_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_vector_paint_set_glyph_extents (hb_vector_paint_t *paint, + const hb_glyph_extents_t *glyph_extents); + +HB_EXTERN void +hb_vector_paint_set_foreground (hb_vector_paint_t *paint, + hb_color_t foreground); + +HB_EXTERN void +hb_vector_paint_set_palette (hb_vector_paint_t *paint, + int palette); + +HB_EXTERN void +hb_vector_paint_set_custom_palette_color (hb_vector_paint_t *paint, + unsigned color_index, + hb_color_t color); + +HB_EXTERN void +hb_vector_paint_clear_custom_palette_colors (hb_vector_paint_t *paint); + +HB_EXTERN hb_paint_funcs_t * +hb_vector_paint_get_funcs (void); + +HB_EXTERN hb_bool_t +hb_vector_paint_glyph (hb_vector_paint_t *paint, + hb_font_t *font, + hb_codepoint_t glyph, + float pen_x, + float pen_y, + hb_vector_extents_mode_t extents_mode); + +HB_EXTERN void +hb_vector_svg_paint_set_flat (hb_vector_paint_t *paint, + hb_bool_t flat); + +HB_EXTERN void +hb_vector_svg_paint_set_precision (hb_vector_paint_t *paint, + unsigned precision); + +HB_EXTERN hb_blob_t * +hb_vector_paint_render (hb_vector_paint_t *paint); + +HB_EXTERN void +hb_vector_paint_reset (hb_vector_paint_t *paint); + +HB_EXTERN void +hb_vector_paint_recycle_blob (hb_vector_paint_t *paint, + hb_blob_t *blob); + +HB_END_DECLS + +#endif /* HB_VECTOR_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-vector.hh b/thirdparty/harfbuzz/upstream/hb-vector.hh index c0cc7063f..71c0c27a1 100644 --- a/thirdparty/harfbuzz/upstream/hb-vector.hh +++ b/thirdparty/harfbuzz/upstream/hb-vector.hh @@ -32,6 +32,12 @@ #include "hb-meta.hh" #include "hb-null.hh" +// Change to 1 to force inline vector allocs, to see callsite in malloc-stats tool. +#if 0 +#define HB_ALWAYS_INLINE_VECTOR_ALLOCS HB_ALWAYS_INLINE +#else +#define HB_ALWAYS_INLINE_VECTOR_ALLOCS +#endif template @@ -45,6 +51,7 @@ struct hb_vector_t using c_array_t = typename std::conditional, hb_array_t>::type; hb_vector_t () = default; + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (std::initializer_list lst) : hb_vector_t () { alloc (lst.size (), true); @@ -53,28 +60,28 @@ struct hb_vector_t } template - hb_vector_t (const Iterable &o) : hb_vector_t () + explicit hb_vector_t (const Iterable &o) : hb_vector_t () { - auto iter = hb_iter (o); - if (iter.is_random_access_iterator || iter.has_fast_len) - alloc (hb_len (iter), true); - hb_copy (iter, *this); + extend (o, true); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (const hb_vector_t &o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o.as_array ()); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } + HB_ALWAYS_INLINE_VECTOR_ALLOCS hb_vector_t (c_array_t o) : hb_vector_t () { - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return; copy_array (o); } @@ -87,6 +94,64 @@ struct hb_vector_t } ~hb_vector_t () { fini (); } + template + void + set_storage (Type (&array)[n]) + { set_storage (array, n); } + void + set_storage (hb_array_t array) + { set_storage (array.arrayZ, array.length); } + template + void + set_storage (Type *array, unsigned n) + { + assert (allocated == 0); + assert (length == 0); + + arrayZ = array; + length = n; + } + + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + void extend (const Iterable &o, bool exact=false) + { + auto iter = hb_iter (o); + if (iter.is_random_access_iterator || iter.has_fast_len) + { + if (unlikely (!alloc (length + hb_len (iter), exact))) + return; + unsigned count = hb_len (iter); + for (unsigned i = 0; i < count; i++) + push_has_room (*iter++); + } + while (iter) + { + if (unlikely (!alloc (length + 1))) + return; + unsigned room = allocated - length; + for (unsigned i = 0; i < room && iter; i++) + push_has_room (*iter++); + } + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + void extend (array_t o, bool exact=false) + { + alloc (length + o.length, exact); + if (unlikely (in_error ())) return; + copy_array (o); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + void extend (c_array_t o, bool exact=false) + { + alloc (length + o.length, exact); + if (unlikely (in_error ())) return; + copy_array (o); + } + public: int allocated = 0; /* < 0 means allocation failed. */ unsigned int length = 0; @@ -104,10 +169,7 @@ struct hb_vector_t void fini () { - /* We allow a hack to make the vector point to a foreign array - * by the user. In that case length/arrayZ are non-zero but - * allocated is zero. Don't free anything. */ - if (allocated) + if (is_owned ()) { shrink_vector (0); hb_free (arrayZ); @@ -115,11 +177,41 @@ struct hb_vector_t init (); } - void reset () + HB_ALWAYS_INLINE_VECTOR_ALLOCS + hb_vector_t &reset () { if (unlikely (in_error ())) reset_error (); resize (0); + return *this; + } + + /* Transfer ownership of the backing storage to caller. + * Returns nullptr if storage is not owned by this vector. */ + Type * + steal (unsigned *len = nullptr, int *allocated_out = nullptr) + { + if (!is_owned ()) + return nullptr; + if (len) + *len = length; + if (allocated_out) + *allocated_out = allocated; + Type *p = arrayZ; + init (); + return p; + } + + /* Adopt a previously detached owned buffer. */ + void + recycle_buffer (Type *buffer, + unsigned len, + int allocated_len) + { + fini (); + arrayZ = buffer; + length = len; + allocated = allocated_len; } friend void swap (hb_vector_t& a, hb_vector_t& b) noexcept @@ -132,9 +224,10 @@ struct hb_vector_t hb_vector_t& operator = (const hb_vector_t &o) { reset (); - alloc (o.length, true); + alloc_exact (o.length); if (unlikely (in_error ())) return *this; + length = 0; copy_array (o.as_array ()); return *this; @@ -204,13 +297,16 @@ struct hb_vector_t Type * operator + (unsigned int i) { return arrayZ + i; } const Type * operator + (unsigned int i) const { return arrayZ + i; } + HB_ALWAYS_INLINE_VECTOR_ALLOCS Type *push () { if (unlikely (!resize (length + 1))) return std::addressof (Crap (Type)); return std::addressof (arrayZ[length - 1]); } - template Type *push (Args&&... args) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push (Args&&... args) { if (unlikely ((int) length >= allocated && !alloc (length + 1))) // If push failed to allocate then don't copy v, since this may cause @@ -218,11 +314,28 @@ struct hb_vector_t // reference to it. return std::addressof (Crap (Type)); + return push_has_room (std::forward (args)...); + } + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool push_or_fail (Args&&... args) + { + return push (std::forward (args)...) != std::addressof (Crap (Type)); + } + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + Type *push_has_room (Args&&... args) + { /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); return new (p) Type (std::forward (args)...); } + bool is_owned () const + { + return allocated != 0 && allocated != -1; + } + bool in_error () const { return allocated < 0; } void set_error () { @@ -234,27 +347,40 @@ struct hb_vector_t assert (allocated < 0); allocated = -(allocated + 1); } + void ensure_error () + { + if (!in_error ()) + set_error (); + } - template Type * - realloc_vector (unsigned new_allocated, hb_priority<0>) + _realloc (unsigned new_allocated) { if (!new_allocated) { - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); return nullptr; } + if (!allocated && arrayZ) + { + /* If we have a non-null arrayZ but allocated is 0, then we are + * reallocating from a foreign array. */ + Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type)); + if (unlikely (!new_array)) + return nullptr; + hb_memcpy ((void *) new_array, (const void *) arrayZ, length * sizeof (Type)); + return new_array; + } return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); } - template Type * - realloc_vector (unsigned new_allocated, hb_priority<0>) + _malloc_move (unsigned new_allocated) { if (!new_allocated) { - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); return nullptr; } Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type)); @@ -266,22 +392,33 @@ struct hb_vector_t new_array[i] = std::move (arrayZ[i]); arrayZ[i].~Type (); } - hb_free (arrayZ); + if (is_owned ()) + hb_free (arrayZ); } return new_array; } + + template + Type * + realloc_vector (unsigned new_allocated, hb_priority<0>) + { + return _realloc (new_allocated); + } + template + Type * + realloc_vector (unsigned new_allocated, hb_priority<0>) + { + return _malloc_move (new_allocated); + } /* Specialization for types that can be moved using realloc(). */ template Type * realloc_vector (unsigned new_allocated, hb_priority<1>) { - if (!new_allocated) - { - hb_free (arrayZ); - return nullptr; - } - return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); + return _realloc (new_allocated); } template + void + copy_array (hb_array_t other) + { + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; + } template void copy_array (hb_array_t other) { - length = other.length; - if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long)) - /* This runs faster because of alignment. */ - for (unsigned i = 0; i < length; i++) - arrayZ[i] = other.arrayZ[i]; - else - hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size); + hb_memcpy ((void *) (arrayZ + length), (const void *) other.arrayZ, other.length * item_size); + length += other.length; } template other) { - length = 0; - while (length < other.length) - { - length++; - new (std::addressof (arrayZ[length - 1])) Type (other.arrayZ[length - 1]); - } + for (unsigned i = 0; i < other.length; i++) + new (std::addressof (arrayZ[length + i])) Type (other.arrayZ[i]); + length += other.length; } template other) { - length = 0; - while (length < other.length) + for (unsigned i = 0; i < other.length; i++) { - length++; - new (std::addressof (arrayZ[length - 1])) Type (); - arrayZ[length - 1] = other.arrayZ[length - 1]; + new (std::addressof (arrayZ[length + i])) Type (); + arrayZ[length + i] = other.arrayZ[i]; } + length += other.length; } void shrink_vector (unsigned size) { assert (size <= length); - if (!std::is_trivially_destructible::value) + if (!hb_is_trivially_destructible(Type)) { unsigned count = length - size; - Type *p = arrayZ + length - 1; + Type *p = arrayZ + length; while (count--) - p--->~Type (); + (--p)->~Type (); } length = size; } @@ -376,6 +512,7 @@ struct hb_vector_t } /* Allocate for size but don't adjust length. */ + HB_ALWAYS_INLINE_VECTOR_ALLOCS bool alloc (unsigned int size, bool exact=false) { if (unlikely (in_error ())) @@ -402,7 +539,6 @@ struct hb_vector_t new_allocated += (new_allocated >> 1) + 8; } - /* Reallocate */ bool overflows = @@ -432,8 +568,64 @@ struct hb_vector_t return true; } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool alloc_exact (unsigned int size) + { + return alloc (size, true); + } + + HB_ALWAYS_INLINE_VECTOR_ALLOCS + void clear () + { + resize (0); + } + + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool allocate_from_pool (allocator_t *allocator, unsigned size, unsigned int initialize = true) + { + if (allocator) + { + assert (!length && !allocated); + arrayZ = (Type *) allocator->alloc (size * sizeof (Type), alignof (Type)); + if (unlikely (!arrayZ)) + { + set_error (); + return false; + } + if (initialize) + grow_vector (size, hb_prioritize); + else + length = size; + return true; + } + return resize_full ((int) size, initialize, true); + } - bool resize (int size_, bool initialize = true, bool exact = false) + template + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool duplicate_vector_from_pool (allocator_t *allocator, const hb_vector_t &other) + { + if (unlikely (!allocate_from_pool (allocator, other.length, false))) + return false; + length = 0; + copy_array (other.as_array ()); + return true; + } + + template + void shrink_back_to_pool (allocator_t *allocator, int size) + { + unsigned orig_length = length; + + shrink (size, false); + + if (allocator && !is_owned ()) + allocator->discard (arrayZ + length, (orig_length - length) * sizeof (Type)); + } + + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_full (int size_, bool initialize, bool exact) { unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; if (!alloc (size, exact)) @@ -453,9 +645,20 @@ struct hb_vector_t length = size; return true; } - bool resize_exact (int size_, bool initialize = true) + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize (int size_) + { + return resize_full (size_, true, false); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_dirty (int size_) + { + return resize_full (size_, false, false); + } + HB_ALWAYS_INLINE_VECTOR_ALLOCS + bool resize_exact (int size_) { - return resize (size_, initialize, true); + return resize_full (size_, true, true); } Type pop () @@ -496,8 +699,8 @@ struct hb_vector_t shrink_vector (size); - if (shrink_memory) - alloc (size, true); /* To force shrinking memory if needed. */ + if (is_owned () && shrink_memory) + alloc_exact (size); /* To force shrinking memory if needed. */ } diff --git a/thirdparty/harfbuzz/upstream/hb-version.h b/thirdparty/harfbuzz/upstream/hb-version.h index 1083bc9c9..fe844a3a8 100644 --- a/thirdparty/harfbuzz/upstream/hb-version.h +++ b/thirdparty/harfbuzz/upstream/hb-version.h @@ -41,7 +41,7 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 10 +#define HB_VERSION_MAJOR 13 /** * HB_VERSION_MINOR: * @@ -53,14 +53,14 @@ HB_BEGIN_DECLS * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 0 +#define HB_VERSION_MICRO 1 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "10.1.0" +#define HB_VERSION_STRING "13.1.1" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/harfbuzz/upstream/hb-version.h.in b/thirdparty/harfbuzz/upstream/hb-version.h.in deleted file mode 100644 index abcb73f41..000000000 --- a/thirdparty/harfbuzz/upstream/hb-version.h.in +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright © 2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) -#error "Include instead." -#endif - -#ifndef HB_VERSION_H -#define HB_VERSION_H - -#include "hb-common.h" - -HB_BEGIN_DECLS - - -/** - * HB_VERSION_MAJOR: - * - * The major component of the library version available at compile-time. - */ -#define HB_VERSION_MAJOR @HB_VERSION_MAJOR@ -/** - * HB_VERSION_MINOR: - * - * The minor component of the library version available at compile-time. - */ -#define HB_VERSION_MINOR @HB_VERSION_MINOR@ -/** - * HB_VERSION_MICRO: - * - * The micro component of the library version available at compile-time. - */ -#define HB_VERSION_MICRO @HB_VERSION_MICRO@ - -/** - * HB_VERSION_STRING: - * - * A string literal containing the library version available at compile-time. - */ -#define HB_VERSION_STRING "@HB_VERSION@" - -/** - * HB_VERSION_ATLEAST: - * @major: the major component of the version number - * @minor: the minor component of the version number - * @micro: the micro component of the version number - * - * Tests the library version at compile-time against a minimum value, - * as three integer components. - */ -#define HB_VERSION_ATLEAST(major,minor,micro) \ - ((major)*10000+(minor)*100+(micro) <= \ - HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) - - -HB_EXTERN void -hb_version (unsigned int *major, - unsigned int *minor, - unsigned int *micro); - -HB_EXTERN const char * -hb_version_string (void); - -HB_EXTERN hb_bool_t -hb_version_atleast (unsigned int major, - unsigned int minor, - unsigned int micro); - - -HB_END_DECLS - -#endif /* HB_VERSION_H */ diff --git a/thirdparty/harfbuzz/upstream/hb-wasm-shape.cc b/thirdparty/harfbuzz/upstream/hb-wasm-shape.cc index a8b91879a..f83329e1c 100644 --- a/thirdparty/harfbuzz/upstream/hb-wasm-shape.cc +++ b/thirdparty/harfbuzz/upstream/hb-wasm-shape.cc @@ -113,7 +113,7 @@ struct hb_wasm_shape_plan_t { struct hb_wasm_face_data_t { hb_blob_t *wasm_blob; wasm_module_t wasm_module; - mutable hb_atomic_ptr_t plan; + mutable hb_atomic_t plan; }; static bool diff --git a/thirdparty/harfbuzz/upstream/hb-zlib.cc b/thirdparty/harfbuzz/upstream/hb-zlib.cc new file mode 100644 index 000000000..2703e943d --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-zlib.cc @@ -0,0 +1,98 @@ +#ifndef HB_ZLIB_CC +#define HB_ZLIB_CC + +#include "hb.hh" + +#include "hb-zlib.hh" + +#ifdef HAVE_ZLIB +#include +#endif + +hb_blob_t * +hb_blob_decompress_gzip (hb_blob_t *blob, + unsigned max_output_len) +{ +#ifndef HAVE_ZLIB + return nullptr; +#else + unsigned compressed_len = 0; + const uint8_t *compressed = (const uint8_t *) hb_blob_get_data (blob, &compressed_len); + if (!compressed || !compressed_len) + return nullptr; + + z_stream stream = {}; + stream.next_in = (Bytef *) compressed; + stream.avail_in = compressed_len; + + if (inflateInit2 (&stream, 16 + MAX_WBITS) != Z_OK) + return nullptr; + + uint32_t expected_size = 0; + hb_gzip_get_uncompressed_size ((const char *) compressed, + compressed_len, + &expected_size); + + size_t allocated = hb_min ((size_t) hb_max (expected_size, 4096u), + (size_t) max_output_len); + char *output = (char *) hb_malloc (allocated); + if (!output) + { + inflateEnd (&stream); + return nullptr; + } + + int status = Z_OK; + while (true) + { + size_t produced = (size_t) stream.total_out; + if (unlikely (produced >= (size_t) max_output_len)) + goto fail; + + if (produced == allocated) + { + size_t new_allocated = hb_min (allocated * 2, (size_t) max_output_len); + if (unlikely (new_allocated <= allocated)) + goto fail; + + char *new_output = (char *) hb_realloc (output, new_allocated); + if (unlikely (!new_output)) + goto fail; + + output = new_output; + allocated = new_allocated; + } + + stream.next_out = (Bytef *) output + stream.total_out; + stream.avail_out = (uInt) (allocated - (size_t) stream.total_out); + + status = inflate (&stream, Z_FINISH); + if (status == Z_STREAM_END) + break; + + if ((status == Z_OK || status == Z_BUF_ERROR) && stream.avail_out == 0) + continue; + + goto fail; + } + + inflateEnd (&stream); + + if (unlikely ((size_t) stream.total_out > (size_t) max_output_len)) + goto fail_free; + + return hb_blob_create_or_fail (output, + (unsigned) stream.total_out, + HB_MEMORY_MODE_WRITABLE, + output, + hb_free); + +fail: + inflateEnd (&stream); +fail_free: + hb_free (output); + return nullptr; +#endif +} + +#endif /* HB_ZLIB_CC */ diff --git a/thirdparty/harfbuzz/upstream/hb-zlib.hh b/thirdparty/harfbuzz/upstream/hb-zlib.hh new file mode 100644 index 000000000..3b8eb791a --- /dev/null +++ b/thirdparty/harfbuzz/upstream/hb-zlib.hh @@ -0,0 +1,37 @@ +#ifndef HB_ZLIB_HH +#define HB_ZLIB_HH + +#include "hb-blob.hh" + +static inline bool +hb_blob_is_gzip (const char *data, + unsigned data_len) +{ + return data_len >= 3 && + (unsigned char) data[0] == 0x1Fu && + (unsigned char) data[1] == 0x8Bu && + (unsigned char) data[2] == 0x08u; +} + +static inline bool +hb_gzip_get_uncompressed_size (const char *data, + unsigned data_len, + uint32_t *size) +{ + if (data_len < 4) + return false; + + const unsigned char *trailer = (const unsigned char *) data + data_len - 4; + if (size) + *size = (uint32_t) trailer[0] | + ((uint32_t) trailer[1] << 8) | + ((uint32_t) trailer[2] << 16) | + ((uint32_t) trailer[3] << 24); + return true; +} + +HB_INTERNAL hb_blob_t * +hb_blob_decompress_gzip (hb_blob_t *blob, + unsigned max_output_len); + +#endif /* HB_ZLIB_HH */ diff --git a/thirdparty/harfbuzz/upstream/hb.hh b/thirdparty/harfbuzz/upstream/hb.hh index fe466fe1f..2ebae65f2 100644 --- a/thirdparty/harfbuzz/upstream/hb.hh +++ b/thirdparty/harfbuzz/upstream/hb.hh @@ -109,11 +109,21 @@ #pragma GCC diagnostic warning "-Wformat-signedness" #pragma GCC diagnostic warning "-Wignored-pragma-optimize" #pragma GCC diagnostic warning "-Wlogical-op" -#pragma GCC diagnostic warning "-Wmaybe-uninitialized" #pragma GCC diagnostic warning "-Wmissing-format-attribute" +#pragma GCC diagnostic warning "-Wpessimizing-move" #pragma GCC diagnostic warning "-Wundef" #pragma GCC diagnostic warning "-Wunsafe-loop-optimizations" #pragma GCC diagnostic warning "-Wunused-but-set-variable" +#ifdef __clang__ +// The following are too buggy on gcc +// https://github.com/harfbuzz/harfbuzz/issues/5589 +// https://github.com/harfbuzz/harfbuzz/pull/5367 +#pragma GCC diagnostic warning "-Wmaybe-uninitialized" +#pragma GCC diagnostic warning "-Wuninitialized" +#else +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif #endif /* Ignored currently, but should be fixed at some point. */ @@ -131,9 +141,11 @@ #pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wcast-function-type-strict" // https://github.com/harfbuzz/harfbuzz/pull/3859#issuecomment-1295409126 #pragma GCC diagnostic ignored "-Wdangling-reference" // https://github.com/harfbuzz/harfbuzz/issues/4043 +#pragma GCC diagnostic ignored "-Wdangling-pointer" // Trigerred by hb_decycler_node_t(). #pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#pragma GCC diagnostic ignored "-Wold-style-cast" #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang #pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834 #pragma GCC diagnostic ignored "-Wstrict-aliasing" @@ -229,33 +241,6 @@ #define HB_PASTE(a,b) HB_PASTE1(a,b) -/* Compile-time custom allocator support. */ - -#if !defined(HB_CUSTOM_MALLOC) \ - && defined(hb_malloc_impl) \ - && defined(hb_calloc_impl) \ - && defined(hb_realloc_impl) \ - && defined(hb_free_impl) -#define HB_CUSTOM_MALLOC -#endif - -#ifdef HB_CUSTOM_MALLOC -extern "C" void* hb_malloc_impl(size_t size); -extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); -extern "C" void* hb_realloc_impl(void *ptr, size_t size); -extern "C" void hb_free_impl(void *ptr); -#define hb_malloc hb_malloc_impl -#define hb_calloc hb_calloc_impl -#define hb_realloc hb_realloc_impl -#define hb_free hb_free_impl -#else -#define hb_malloc malloc -#define hb_calloc calloc -#define hb_realloc realloc -#define hb_free free -#endif - - /* * Compiler attributes */ @@ -264,6 +249,8 @@ extern "C" void hb_free_impl(void *ptr); // clang defines it so no need. #ifdef __has_builtin #define hb_has_builtin __has_builtin +#elif defined(_MSC_VER) +#define hb_has_builtin(x) 0 #else #define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5)) #endif @@ -281,7 +268,9 @@ extern "C" void hb_free_impl(void *ptr); #define __attribute__(x) #endif -#if defined(__GNUC__) && (__GNUC__ >= 3) +#if defined(__MINGW32__) && (__GNUC__ >= 3) && !defined(__clang__) +#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (gnu_printf, format_idx, arg_idx))) +#elif defined(__GNUC__) && (__GNUC__ >= 3) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else #define HB_PRINTF_FUNC(format_idx, arg_idx) @@ -337,6 +326,10 @@ extern "C" void hb_free_impl(void *ptr); #endif #endif +#ifndef HB_HOT +#define HB_HOT __attribute__((hot)) +#endif + /* * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch @@ -488,7 +481,7 @@ static int HB_UNUSED _hb_errno = 0; # define hb_atexit atexit # else template struct hb_atexit_t { ~hb_atexit_t () { function (); } }; -# define hb_atexit(f) static hb_atexit_t _hb_atexit_##__LINE__; +# define hb_atexit(f) static hb_atexit_t _hb_atexit_##__LINE__ # endif #endif #endif @@ -533,9 +526,32 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); /* Pie time. */ // https://github.com/harfbuzz/harfbuzz/issues/4166 -#define HB_PI 3.14159265358979f +#define HB_PI 3.14159265358979323846f #define HB_2_PI (2.f * HB_PI) +/* Compile-time custom allocator support. */ + +#if !defined(HB_CUSTOM_MALLOC) \ + && defined(hb_malloc_impl) \ + && defined(hb_calloc_impl) \ + && defined(hb_realloc_impl) \ + && defined(hb_free_impl) +#define HB_CUSTOM_MALLOC +#endif + +#ifdef HB_CUSTOM_MALLOC +extern "C" void* hb_malloc_impl(size_t size); +extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); +extern "C" void* hb_realloc_impl(void *ptr, size_t size); +extern "C" void hb_free_impl(void *ptr); +#else +#define hb_malloc_impl malloc +#define hb_calloc_impl calloc +#define hb_realloc_impl realloc +#define hb_free_impl free +#endif + + /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include @@ -553,4 +569,13 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #include "hb-vector.hh" // Requires: hb-array hb-null #include "hb-object.hh" // Requires: hb-atomic hb-mutex hb-vector + +/* Our src/test-*.cc use hb_assert(), such that it's not compiled out under NDEBUG. + * https://github.com/harfbuzz/harfbuzz/issues/5418 */ +#define hb_always_assert(x) \ + HB_STMT_START { \ + if (!(x)) { fprintf(stderr, "Assertion failed: %s, at %s:%d\n", #x, __FILE__, __LINE__); abort(); } \ + } HB_STMT_END + + #endif /* HB_HH */ diff --git a/thirdparty/harfbuzz/upstream/justify.py b/thirdparty/harfbuzz/upstream/justify.py deleted file mode 100644 index db2fb7010..000000000 --- a/thirdparty/harfbuzz/upstream/justify.py +++ /dev/null @@ -1,288 +0,0 @@ -import gi - -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk, HarfBuzz as hb - - -POOL = {} - - -def move_to_f(funcs, draw_data, st, to_x, to_y, user_data): - context = POOL[draw_data] - context.move_to(to_x, to_y) - - -def line_to_f(funcs, draw_data, st, to_x, to_y, user_data): - context = POOL[draw_data] - context.line_to(to_x, to_y) - - -def cubic_to_f( - funcs, - draw_data, - st, - control1_x, - control1_y, - control2_x, - control2_y, - to_x, - to_y, - user_data, -): - context = POOL[draw_data] - context.curve_to(control1_x, control1_y, control2_x, control2_y, to_x, to_y) - - -def close_path_f(funcs, draw_data, st, user_data): - context = POOL[draw_data] - context.close_path() - - -DFUNCS = hb.draw_funcs_create() -hb.draw_funcs_set_move_to_func(DFUNCS, move_to_f, None) -hb.draw_funcs_set_line_to_func(DFUNCS, line_to_f, None) -hb.draw_funcs_set_cubic_to_func(DFUNCS, cubic_to_f, None) -hb.draw_funcs_set_close_path_func(DFUNCS, close_path_f, None) - - -def push_transform_f(funcs, paint_data, xx, yx, xy, yy, dx, dy, user_data): - raise NotImplementedError - - -def pop_transform_f(funcs, paint_data, user_data): - raise NotImplementedError - - -def color_f(funcs, paint_data, is_foreground, color, user_data): - context = POOL[paint_data] - r = hb.color_get_red(color) / 255 - g = hb.color_get_green(color) / 255 - b = hb.color_get_blue(color) / 255 - a = hb.color_get_alpha(color) / 255 - context.set_source_rgba(r, g, b, a) - context.paint() - - -def push_clip_rectangle_f(funcs, paint_data, xmin, ymin, xmax, ymax, user_data): - context = POOL[paint_data] - context.save() - context.rectangle(xmin, ymin, xmax, ymax) - context.clip() - - -def push_clip_glyph_f(funcs, paint_data, glyph, font, user_data): - context = POOL[paint_data] - context.save() - context.new_path() - hb.font_draw_glyph(font, glyph, DFUNCS, paint_data) - context.close_path() - context.clip() - - -def pop_clip_f(funcs, paint_data, user_data): - context = POOL[paint_data] - context.restore() - - -def push_group_f(funcs, paint_data, user_data): - raise NotImplementedError - - -def pop_group_f(funcs, paint_data, mode, user_data): - raise NotImplementedError - - -PFUNCS = hb.paint_funcs_create() -hb.paint_funcs_set_push_transform_func(PFUNCS, push_transform_f, None) -hb.paint_funcs_set_pop_transform_func(PFUNCS, pop_transform_f, None) -hb.paint_funcs_set_color_func(PFUNCS, color_f, None) -hb.paint_funcs_set_push_clip_glyph_func(PFUNCS, push_clip_glyph_f, None) -hb.paint_funcs_set_push_clip_rectangle_func(PFUNCS, push_clip_rectangle_f, None) -hb.paint_funcs_set_pop_clip_func(PFUNCS, pop_clip_f, None) -hb.paint_funcs_set_push_group_func(PFUNCS, push_group_f, None) -hb.paint_funcs_set_pop_group_func(PFUNCS, pop_group_f, None) - - -def makebuffer(words): - buf = hb.buffer_create() - - text = " ".join(words) - hb.buffer_add_codepoints(buf, [ord(c) for c in text], 0, len(text)) - - hb.buffer_guess_segment_properties(buf) - - return buf - - -def justify(face, words, advance, target_advance): - font = hb.font_create(face) - buf = makebuffer(words) - - wiggle = 5 - shrink = target_advance - wiggle < advance - expand = target_advance + wiggle > advance - - ret, advance, tag, value = hb.shape_justify( - font, - buf, - None, - None, - target_advance, - target_advance, - advance, - ) - - if not ret: - return False, buf, None - - if tag: - variation = hb.variation_t() - variation.tag = tag - variation.value = value - else: - variation = None - - if shrink and advance > target_advance + wiggle: - return False, buf, variation - if expand and advance < target_advance - wiggle: - return False, buf, variation - - return True, buf, variation - - -def shape(face, words): - font = hb.font_create(face) - buf = makebuffer(words) - hb.shape(font, buf) - positions = hb.buffer_get_glyph_positions(buf) - advance = sum(p.x_advance for p in positions) - return buf, advance - - -def typeset(face, text, target_advance): - lines = [] - words = [] - for word in text.split(): - words.append(word) - buf, advance = shape(face, words) - if advance > target_advance: - # Shrink - ret, buf, variation = justify(face, words, advance, target_advance) - if ret: - lines.append((buf, variation)) - words = [] - # If if fails, pop the last word and shrink, and hope for the best. - # A too short line is better than too long. - elif len(words) > 1: - words.pop() - _, buf, variation = justify(face, words, advance, target_advance) - lines.append((buf, variation)) - words = [word] - # But if it is one word, meh. - else: - lines.append((buf, variation)) - words = [] - - # Justify last line - if words: - _, buf, variation = justify(face, words, advance, target_advance) - lines.append((buf, variation)) - - return lines - - -def render(face, text, context, width, height, fontsize): - font = hb.font_create(face) - - margin = fontsize * 2 - scale = fontsize / hb.face_get_upem(face) - target_advance = (width - (margin * 2)) / scale - - lines = typeset(face, text, target_advance) - - _, extents = hb.font_get_h_extents(font) - lineheight = extents.ascender - extents.descender + extents.line_gap - lineheight *= scale - - context.save() - context.translate(0, margin) - context.set_font_size(12) - context.set_source_rgb(1, 0, 0) - for buf, variation in lines: - rtl = hb.buffer_get_direction(buf) == hb.direction_t.RTL - if rtl: - hb.buffer_reverse(buf) - infos = hb.buffer_get_glyph_infos(buf) - positions = hb.buffer_get_glyph_positions(buf) - advance = sum(p.x_advance for p in positions) - - context.translate(0, lineheight) - context.save() - - context.save() - context.move_to(0, -20) - if variation: - tag = hb.tag_to_string(variation.tag).decode("ascii") - context.show_text(f" {tag}={variation.value:g}") - context.move_to(0, 0) - context.show_text(f" {advance:g}/{target_advance:g}") - context.restore() - - if variation: - hb.font_set_variations(font, [variation]) - - context.translate(margin, 0) - context.scale(scale, -scale) - - if rtl: - context.translate(target_advance, 0) - - for info, pos in zip(infos, positions): - if rtl: - context.translate(-pos.x_advance, pos.y_advance) - context.save() - context.translate(pos.x_offset, pos.y_offset) - hb.font_paint_glyph(font, info.codepoint, PFUNCS, id(context), 0, 0x0000FF) - context.restore() - if not rtl: - context.translate(+pos.x_advance, pos.y_advance) - - context.restore() - context.restore() - - -def main(fontpath, textpath): - fontsize = 70 - - blob = hb.blob_create_from_file(fontpath) - face = hb.face_create(blob, 0) - - with open(textpath) as f: - text = f.read() - - def on_draw(da, context): - alloc = da.get_allocation() - POOL[id(context)] = context - render(face, text, context, alloc.width, alloc.height, fontsize) - del POOL[id(context)] - - drawingarea = Gtk.DrawingArea() - drawingarea.connect("draw", on_draw) - - win = Gtk.Window() - win.connect("destroy", Gtk.main_quit) - win.set_default_size(1000, 700) - win.add(drawingarea) - - win.show_all() - Gtk.main() - - -if __name__ == "__main__": - import argparse - - parser = argparse.ArgumentParser(description="HarfBuzz justification demo.") - parser.add_argument("fontfile", help="font file") - parser.add_argument("textfile", help="text") - args = parser.parse_args() - main(args.fontfile, args.textfile) diff --git a/thirdparty/harfbuzz/upstream/main.cc b/thirdparty/harfbuzz/upstream/main.cc deleted file mode 100644 index 33ea2c9b5..000000000 --- a/thirdparty/harfbuzz/upstream/main.cc +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright © 2007,2008,2009 Red Hat, Inc. - * Copyright © 2018,2019,2020 Ebrahim Byagowi - * Copyright © 2018 Khaled Hosny - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Red Hat Author(s): Behdad Esfahbod - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "hb.h" -#include "hb-ot.h" - -#include -#include -#include -#include - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif - -#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) -static void -svg_dump (hb_face_t *face, unsigned face_index) -{ - unsigned glyph_count = hb_face_get_glyph_count (face); - - for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id); - - if (hb_blob_get_length (blob) == 0) continue; - - unsigned length; - const char *data = hb_blob_get_data (blob, &length); - - char output_path[255]; - snprintf (output_path, sizeof output_path, - "out/svg-%u-%u.svg%s", - glyph_id, - face_index, - // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405 - (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : ""); - - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); - - hb_blob_destroy (blob); - } -} - -/* _png API is so easy to use unlike the below code, don't get confused */ -static void -png_dump (hb_face_t *face, unsigned face_index) -{ - unsigned glyph_count = hb_face_get_glyph_count (face); - hb_font_t *font = hb_font_create (face); - - /* scans the font for strikes */ - unsigned sample_glyph_id; - /* we don't care about different strikes for different glyphs at this point */ - for (sample_glyph_id = 0; sample_glyph_id < glyph_count; ++sample_glyph_id) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); - unsigned blob_length = hb_blob_get_length (blob); - hb_blob_destroy (blob); - if (blob_length != 0) - break; - } - - unsigned upem = hb_face_get_upem (face); - unsigned blob_length = 0; - unsigned strike = 0; - for (unsigned ppem = 1; ppem < upem; ++ppem) - { - hb_font_set_ppem (font, ppem, ppem); - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id); - unsigned new_blob_length = hb_blob_get_length (blob); - hb_blob_destroy (blob); - if (new_blob_length != blob_length) - { - for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id) - { - hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id); - - if (hb_blob_get_length (blob) == 0) continue; - - unsigned length; - const char *data = hb_blob_get_data (blob, &length); - - char output_path[255]; - snprintf (output_path, sizeof output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index); - - FILE *f = fopen (output_path, "wb"); - fwrite (data, 1, length, f); - fclose (f); - - hb_blob_destroy (blob); - } - - strike++; - blob_length = new_blob_length; - } - } - - hb_font_destroy (font); -} - -struct draw_data_t -{ - FILE *f; - hb_position_t ascender; -}; - -static void -move_to (hb_draw_funcs_t *, draw_data_t *draw_data, - hb_draw_state_t *, - float to_x, float to_y, - void *) -{ - fprintf (draw_data->f, "M%g,%g", to_x, draw_data->ascender - to_y); -} - -static void -line_to (hb_draw_funcs_t *, draw_data_t *draw_data, - hb_draw_state_t *, - float to_x, float to_y, - void *) -{ - fprintf (draw_data->f, "L%g,%g", to_x, draw_data->ascender - to_y); -} - -static void -quadratic_to (hb_draw_funcs_t *, draw_data_t *draw_data, - hb_draw_state_t *, - float control_x, float control_y, - float to_x, float to_y, - void *) -{ - fprintf (draw_data->f, "Q%g,%g %g,%g", control_x, draw_data->ascender - control_y, - to_x, draw_data->ascender - to_y); -} - -static void -cubic_to (hb_draw_funcs_t *, draw_data_t *draw_data, - hb_draw_state_t *, - float control1_x, float control1_y, - float control2_x, float control2_y, - float to_x, float to_y, - void *) -{ - fprintf (draw_data->f, "C%g,%g %g,%g %g,%g", control1_x, draw_data->ascender - control1_y, - control2_x, draw_data->ascender - control2_y, - to_x, draw_data->ascender - to_y); -} - -static void -close_path (hb_draw_funcs_t *, draw_data_t *draw_data, - hb_draw_state_t *, - void *) -{ - fprintf (draw_data->f, "Z"); -} - -static void -layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index) -{ - hb_face_t *face = hb_font_get_face (font); - unsigned palette_count = hb_ot_color_palette_get_count (face); - for (unsigned palette = 0; palette < palette_count; ++palette) - { - unsigned num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr); - if (!num_colors) continue; - - hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t)); - hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors); - if (!num_colors) - { - free (colors); - continue; - } - - unsigned num_glyphs = hb_face_get_glyph_count (face); - for (hb_codepoint_t gid = 0; gid < num_glyphs; ++gid) - { - unsigned num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr); - if (!num_layers) continue; - - hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t)); - - hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers); - if (num_layers) - { - hb_font_extents_t font_extents; - hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); - hb_glyph_extents_t extents = {0, 0, 0, 0}; - if (!hb_font_get_glyph_extents (font, gid, &extents)) - { - printf ("Skip gid: %u\n", gid); - continue; - } - - char output_path[255]; - snprintf (output_path, sizeof output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index); - FILE *f = fopen (output_path, "wb"); - fprintf (f, "\n", - extents.x_bearing, 0, - extents.x_bearing + extents.width, -extents.height); - draw_data_t draw_data; - draw_data.ascender = extents.y_bearing; - draw_data.f = f; - - for (unsigned layer = 0; layer < num_layers; ++layer) - { - hb_color_t color = 0x000000FF; - if (layers[layer].color_index != 0xFFFF) - color = colors[layers[layer].color_index]; - fprintf (f, "\n"); - } - - fprintf (f, ""); - fclose (f); - } - free (layers); - } - - free (colors); - } -} - -static void -dump_glyphs (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index) -{ - unsigned num_glyphs = hb_face_get_glyph_count (hb_font_get_face (font)); - for (unsigned gid = 0; gid < num_glyphs; ++gid) - { - hb_font_extents_t font_extents; - hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); - hb_glyph_extents_t extents = {0, 0, 0, 0}; - if (!hb_font_get_glyph_extents (font, gid, &extents)) - { - printf ("Skip gid: %u\n", gid); - continue; - } - - char output_path[255]; - snprintf (output_path, sizeof output_path, "out/%u-%u.svg", face_index, gid); - FILE *f = fopen (output_path, "wb"); - fprintf (f, ""); - fclose (f); - } -} - -static void -dump_glyphs (hb_blob_t *blob, const char *font_name) -{ - FILE *font_name_file = fopen ("out/.dumped_font_name", "r"); - if (font_name_file) - { - fprintf (stderr, "Purge or rename ./out folder if you like to run a glyph dump,\n" - "run it like `rm -rf out && mkdir out && src/main font-file.ttf`\n"); - return; - } - - font_name_file = fopen ("out/.dumped_font_name", "w"); - if (!font_name_file) - { - fprintf (stderr, "./out is not accessible as a folder, create it please\n"); - return; - } - fwrite (font_name, 1, strlen (font_name), font_name_file); - fclose (font_name_file); - - hb_draw_funcs_t *funcs = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, nullptr, nullptr); - hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, nullptr, nullptr); - hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, nullptr, nullptr); - hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, nullptr, nullptr); - hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, nullptr, nullptr); - - unsigned num_faces = hb_face_count (blob); - for (unsigned face_index = 0; face_index < num_faces; ++face_index) - { - hb_face_t *face = hb_face_create (blob, face_index); - hb_font_t *font = hb_font_create (face); - - if (hb_ot_color_has_png (face)) - printf ("Dumping png (CBDT/sbix)...\n"); - png_dump (face, face_index); - - if (hb_ot_color_has_svg (face)) - printf ("Dumping svg (SVG )...\n"); - svg_dump (face, face_index); - - if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face)) - printf ("Dumping layered color glyphs (COLR/CPAL)...\n"); - layered_glyph_dump (font, funcs, face_index); - - dump_glyphs (font, funcs, face_index); - - hb_font_destroy (font); - hb_face_destroy (face); - } - - hb_draw_funcs_destroy (funcs); -} -#endif - -#ifndef MAIN_CC_NO_PRIVATE_API -/* Only this part of this mini app uses private API */ -#include "hb-static.cc" -#include "hb-open-file.hh" -#include "hb-ot-layout-gdef-table.hh" -#include "hb-ot-layout-gsubgpos.hh" - -using namespace OT; - -static void -print_layout_info_using_private_api (hb_blob_t *blob) -{ - const char *font_data = hb_blob_get_data (blob, nullptr); - hb_blob_t *font_blob = hb_sanitize_context_t ().sanitize_blob (blob); - const OpenTypeFontFile* sanitized = font_blob->as (); - if (!font_blob->data) - { - printf ("Sanitization of the file wasn't successful. Exit"); - exit (1); - } - const OpenTypeFontFile& ot = *sanitized; - - switch (ot.get_tag ()) - { - case OpenTypeFontFile::TrueTypeTag: - printf ("OpenType font with TrueType outlines\n"); - break; - case OpenTypeFontFile::CFFTag: - printf ("OpenType font with CFF (Type1) outlines\n"); - break; - case OpenTypeFontFile::TTCTag: - printf ("TrueType Collection of OpenType fonts\n"); - break; - case OpenTypeFontFile::TrueTag: - printf ("Obsolete Apple TrueType font\n"); - break; - case OpenTypeFontFile::Typ1Tag: - printf ("Obsolete Apple Type1 font in SFNT container\n"); - break; - case OpenTypeFontFile::DFontTag: - printf ("DFont Mac Resource Fork\n"); - break; - default: - printf ("Unknown font format\n"); - break; - } - - unsigned num_faces = hb_face_count (blob); - printf ("%u font(s) found in file\n", num_faces); - for (unsigned n_font = 0; n_font < num_faces; ++n_font) - { - const OpenTypeFontFace &font = ot.get_face (n_font); - printf ("Font %u of %u:\n", n_font, num_faces); - - unsigned num_tables = font.get_table_count (); - printf (" %u table(s) found in font\n", num_tables); - for (unsigned n_table = 0; n_table < num_tables; ++n_table) - { - const OpenTypeTable &table = font.get_table (n_table); - printf (" Table %2u of %2u: %.4s (0x%08x+0x%08x)\n", n_table, num_tables, - (const char *) table.tag, - (unsigned) table.offset, - (unsigned) table.length); - - switch (table.tag) - { - - case HB_OT_TAG_GSUB: - case HB_OT_TAG_GPOS: - { - - const GSUBGPOS &g = *reinterpret_cast (font_data + table.offset); - - unsigned num_scripts = g.get_script_count (); - printf (" %u script(s) found in table\n", num_scripts); - for (unsigned n_script = 0; n_script < num_scripts; ++n_script) - { - const Script &script = g.get_script (n_script); - printf (" Script %2u of %2u: %.4s\n", n_script, num_scripts, - (const char *) g.get_script_tag (n_script)); - - if (!script.has_default_lang_sys ()) - printf (" No default language system\n"); - int num_langsys = script.get_lang_sys_count (); - printf (" %d language system(s) found in script\n", num_langsys); - for (int n_langsys = script.has_default_lang_sys () ? -1 : 0; n_langsys < num_langsys; ++n_langsys) - { - const LangSys &langsys = n_langsys == -1 - ? script.get_default_lang_sys () - : script.get_lang_sys (n_langsys); - if (n_langsys == -1) - printf (" Default Language System\n"); - else - printf (" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys, - (const char *) script.get_lang_sys_tag (n_langsys)); - if (!langsys.has_required_feature ()) - printf (" No required feature\n"); - else - printf (" Required feature index: %u\n", - langsys.get_required_feature_index ()); - - unsigned num_features = langsys.get_feature_count (); - printf (" %u feature(s) found in language system\n", num_features); - for (unsigned n_feature = 0; n_feature < num_features; ++n_feature) - { - printf (" Feature index %2u of %2u: %u\n", n_feature, num_features, - langsys.get_feature_index (n_feature)); - } - } - } - - unsigned num_features = g.get_feature_count (); - printf (" %u feature(s) found in table\n", num_features); - for (unsigned n_feature = 0; n_feature < num_features; ++n_feature) - { - const Feature &feature = g.get_feature (n_feature); - unsigned num_lookups = feature.get_lookup_count (); - printf (" Feature %2u of %2u: %c%c%c%c\n", n_feature, num_features, - HB_UNTAG (g.get_feature_tag (n_feature))); - - printf (" %u lookup(s) found in feature\n", num_lookups); - for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup) { - printf (" Lookup index %2u of %2u: %u\n", n_lookup, num_lookups, - feature.get_lookup_index (n_lookup)); - } - } - - unsigned num_lookups = g.get_lookup_count (); - printf (" %u lookup(s) found in table\n", num_lookups); - for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup) - { - const Lookup &lookup = g.get_lookup (n_lookup); - printf (" Lookup %2u of %2u: type %u, props 0x%04X\n", n_lookup, num_lookups, - lookup.get_type (), lookup.get_props ()); - } - - } - break; - - case GDEF::tableTag: - { - - const GDEF &gdef = *reinterpret_cast (font_data + table.offset); - - printf (" Has %sglyph classes\n", - gdef.has_glyph_classes () ? "" : "no "); - printf (" Has %smark attachment types\n", - gdef.has_mark_attachment_types () ? "" : "no "); - printf (" Has %sattach list\n", - gdef.has_attach_list () ? "" : "no "); - printf (" Has %slig carets\n", - gdef.has_lig_carets () ? "" : "no "); - printf (" Has %smark glyph sets\n", - gdef.has_mark_glyph_sets () ? "" : "no "); - break; - } - } - } - } -} -/* end of private API use */ -#endif - -int -main (int argc, char **argv) -{ - if (argc != 2) - { - fprintf (stderr, "usage: %s font-file.ttf\n\n" - "This tools is unsupported and crashes on bad data.\nDon't use it.\n", argv[0]); - exit (1); - } - - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob)); -#ifndef MAIN_CC_NO_PRIVATE_API - print_layout_info_using_private_api (blob); -#endif -#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW) - dump_glyphs (blob, argv[1]); -#endif - hb_blob_destroy (blob); - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/meson.build b/thirdparty/harfbuzz/upstream/meson.build deleted file mode 100644 index 5ca15d90e..000000000 --- a/thirdparty/harfbuzz/upstream/meson.build +++ /dev/null @@ -1,1048 +0,0 @@ -fs = import('fs') - -hb_version_h = configure_file( - command: [find_program('gen-hb-version.py'), meson.project_version(), '@OUTPUT@', '@INPUT@'], - input: 'hb-version.h.in', - output: 'hb-version.h', - install: true, - install_dir: get_option('includedir') / meson.project_name()) - -# Base and default-included sources and headers -hb_base_sources = files( - 'hb-aat-layout-ankr-table.hh', - 'hb-aat-layout-bsln-table.hh', - 'hb-aat-layout-common.hh', - 'hb-aat-layout-feat-table.hh', - 'hb-aat-layout-just-table.hh', - 'hb-aat-layout-kerx-table.hh', - 'hb-aat-layout-morx-table.hh', - 'hb-aat-layout-opbd-table.hh', - 'hb-aat-layout-trak-table.hh', - 'hb-aat-layout.cc', - 'hb-aat-layout.hh', - 'hb-aat-ltag-table.hh', - 'hb-aat-map.cc', - 'hb-aat-map.hh', - 'hb-algs.hh', - 'hb-array.hh', - 'hb-atomic.hh', - 'hb-bimap.hh', - 'hb-bit-page.hh', - 'hb-blob.cc', - 'hb-blob.hh', - 'hb-buffer-serialize.cc', - 'hb-buffer-verify.cc', - 'hb-buffer.cc', - 'hb-buffer.hh', - 'hb-cache.hh', - 'hb-cff-interp-common.hh', - 'hb-cff-interp-cs-common.hh', - 'hb-cff-interp-dict-common.hh', - 'hb-cff1-interp-cs.hh', - 'hb-cff2-interp-cs.hh', - 'hb-common.cc', - 'hb-config.hh', - 'hb-debug.hh', - 'hb-dispatch.hh', - 'hb-draw.cc', - 'hb-draw.hh', - 'hb-geometry.hh', - 'hb-paint.cc', - 'hb-paint.hh', - 'hb-paint-extents.cc', - 'hb-paint-extents.hh', - 'hb-face.cc', - 'hb-face.hh', - 'hb-face-builder.cc', - 'hb-fallback-shape.cc', - 'hb-font.cc', - 'hb-font.hh', - 'hb-iter.hh', - 'hb-kern.hh', - 'hb-limits.hh', - 'hb-machinery.hh', - 'hb-map.cc', - 'hb-map.hh', - 'hb-meta.hh', - 'hb-ms-feature-ranges.hh', - 'hb-multimap.hh', - 'hb-mutex.hh', - 'hb-null.hh', - 'hb-number.cc', - 'hb-number.hh', - 'hb-object.hh', - 'hb-open-file.hh', - 'hb-open-type.hh', - 'hb-ot-cff-common.hh', - 'hb-ot-cff1-std-str.hh', - 'hb-ot-cff1-table.cc', - 'hb-ot-cff1-table.hh', - 'hb-ot-cff2-table.cc', - 'hb-ot-cff2-table.hh', - 'hb-ot-cmap-table.hh', - 'hb-ot-color.cc', - 'hb-ot-face-table-list.hh', - 'hb-ot-face.cc', - 'hb-ot-face.hh', - 'hb-ot-font.cc', - 'hb-ot-gasp-table.hh', - 'hb-ot-glyf-table.hh', - 'hb-ot-hdmx-table.hh', - 'hb-ot-head-table.hh', - 'hb-ot-hhea-table.hh', - 'hb-ot-hmtx-table.hh', - 'hb-ot-kern-table.hh', - 'hb-ot-layout-base-table.hh', - 'hb-ot-layout-common.hh', - 'hb-ot-layout-gdef-table.hh', - 'hb-ot-layout-gpos-table.hh', - 'hb-ot-layout-gsub-table.hh', - 'hb-outline.hh', - 'hb-outline.cc', - 'OT/Color/CBDT/CBDT.hh', - 'OT/Color/COLR/COLR.hh', - 'OT/Color/CPAL/CPAL.hh', - 'OT/Color/sbix/sbix.hh', - 'OT/Color/svg/svg.hh', - 'OT/glyf/glyf.hh', - 'OT/glyf/glyf-helpers.hh', - 'OT/glyf/loca.hh', - 'OT/glyf/path-builder.hh', - 'OT/glyf/Glyph.hh', - 'OT/glyf/GlyphHeader.hh', - 'OT/glyf/SimpleGlyph.hh', - 'OT/glyf/CompositeGlyph.hh', - 'OT/glyf/SubsetGlyph.hh', - 'OT/Layout/types.hh', - 'OT/Layout/Common/Coverage.hh', - 'OT/Layout/Common/CoverageFormat1.hh', - 'OT/Layout/Common/CoverageFormat2.hh', - 'OT/Layout/Common/RangeRecord.hh', - 'OT/Layout/GDEF/GDEF.hh', - 'OT/Layout/GPOS/AnchorFormat1.hh', - 'OT/Layout/GPOS/AnchorFormat2.hh', - 'OT/Layout/GPOS/AnchorFormat3.hh', - 'OT/Layout/GPOS/Anchor.hh', - 'OT/Layout/GPOS/AnchorMatrix.hh', - 'OT/Layout/GPOS/ChainContextPos.hh', - 'OT/Layout/GPOS/Common.hh', - 'OT/Layout/GPOS/ContextPos.hh', - 'OT/Layout/GPOS/CursivePosFormat1.hh', - 'OT/Layout/GPOS/CursivePos.hh', - 'OT/Layout/GPOS/ExtensionPos.hh', - 'OT/Layout/GPOS/GPOS.hh', - 'OT/Layout/GPOS/LigatureArray.hh', - 'OT/Layout/GPOS/MarkArray.hh', - 'OT/Layout/GPOS/MarkBasePosFormat1.hh', - 'OT/Layout/GPOS/MarkBasePos.hh', - 'OT/Layout/GPOS/MarkLigPosFormat1.hh', - 'OT/Layout/GPOS/MarkLigPos.hh', - 'OT/Layout/GPOS/MarkMarkPosFormat1.hh', - 'OT/Layout/GPOS/MarkMarkPos.hh', - 'OT/Layout/GPOS/MarkRecord.hh', - 'OT/Layout/GPOS/PairPosFormat1.hh', - 'OT/Layout/GPOS/PairPosFormat2.hh', - 'OT/Layout/GPOS/PairPos.hh', - 'OT/Layout/GPOS/PairSet.hh', - 'OT/Layout/GPOS/PairValueRecord.hh', - 'OT/Layout/GPOS/PosLookup.hh', - 'OT/Layout/GPOS/PosLookupSubTable.hh', - 'OT/Layout/GPOS/SinglePosFormat1.hh', - 'OT/Layout/GPOS/SinglePosFormat2.hh', - 'OT/Layout/GPOS/SinglePos.hh', - 'OT/Layout/GPOS/ValueFormat.hh', - 'OT/Layout/GSUB/AlternateSet.hh', - 'OT/Layout/GSUB/AlternateSubstFormat1.hh', - 'OT/Layout/GSUB/AlternateSubst.hh', - 'OT/Layout/GSUB/ChainContextSubst.hh', - 'OT/Layout/GSUB/Common.hh', - 'OT/Layout/GSUB/ContextSubst.hh', - 'OT/Layout/GSUB/ExtensionSubst.hh', - 'OT/Layout/GSUB/GSUB.hh', - 'OT/Layout/GSUB/Ligature.hh', - 'OT/Layout/GSUB/LigatureSet.hh', - 'OT/Layout/GSUB/LigatureSubstFormat1.hh', - 'OT/Layout/GSUB/LigatureSubst.hh', - 'OT/Layout/GSUB/MultipleSubstFormat1.hh', - 'OT/Layout/GSUB/MultipleSubst.hh', - 'OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh', - 'OT/Layout/GSUB/ReverseChainSingleSubst.hh', - 'OT/Layout/GSUB/Sequence.hh', - 'OT/Layout/GSUB/SingleSubstFormat1.hh', - 'OT/Layout/GSUB/SingleSubstFormat2.hh', - 'OT/Layout/GSUB/SingleSubst.hh', - 'OT/Layout/GSUB/SubstLookup.hh', - 'OT/Layout/GSUB/SubstLookupSubTable.hh', - 'OT/name/name.hh', - 'OT/Var/VARC/coord-setter.hh', - 'OT/Var/VARC/VARC.cc', - 'OT/Var/VARC/VARC.hh', - 'hb-ot-layout-gsubgpos.hh', - 'hb-ot-layout-jstf-table.hh', - 'hb-ot-layout.cc', - 'hb-ot-layout.hh', - 'hb-ot-map.cc', - 'hb-ot-map.hh', - 'hb-ot-math-table.hh', - 'hb-ot-math.cc', - 'hb-ot-maxp-table.hh', - 'hb-ot-meta-table.hh', - 'hb-ot-meta.cc', - 'hb-ot-metrics.cc', - 'hb-ot-metrics.hh', - 'hb-ot-name-language-static.hh', - 'hb-ot-name-language.hh', - 'hb-ot-name-table.hh', - 'hb-ot-name.cc', - 'hb-ot-os2-table.hh', - 'hb-ot-os2-unicode-ranges.hh', - 'hb-ot-post-macroman.hh', - 'hb-ot-post-table.hh', - 'hb-ot-shaper-arabic-fallback.hh', - 'hb-ot-shaper-arabic-joining-list.hh', - 'hb-ot-shaper-arabic-pua.hh', - 'hb-ot-shaper-arabic-table.hh', - 'hb-ot-shaper-arabic-win1256.hh', - 'hb-ot-shaper-arabic.cc', - 'hb-ot-shaper-arabic.hh', - 'hb-ot-shaper-default.cc', - 'hb-ot-shaper-hangul.cc', - 'hb-ot-shaper-hebrew.cc', - 'hb-ot-shaper-indic-table.cc', - 'hb-ot-shaper-indic.cc', - 'hb-ot-shaper-indic.hh', - 'hb-ot-shaper-khmer.cc', - 'hb-ot-shaper-myanmar.cc', - 'hb-ot-shaper-syllabic.cc', - 'hb-ot-shaper-syllabic.hh', - 'hb-ot-shaper-thai.cc', - 'hb-ot-shaper-use-table.hh', - 'hb-ot-shaper-use.cc', - 'hb-ot-shaper-vowel-constraints.cc', - 'hb-ot-shaper-vowel-constraints.hh', - 'hb-ot-shaper.hh', - 'hb-ot-shape-fallback.cc', - 'hb-ot-shape-fallback.hh', - 'hb-ot-shape-normalize.cc', - 'hb-ot-shape-normalize.hh', - 'hb-ot-shape.cc', - 'hb-ot-shape.hh', - 'hb-ot-stat-table.hh', - 'hb-ot-tag-table.hh', - 'hb-ot-tag.cc', - 'hb-ot-var-avar-table.hh', - 'hb-ot-var-common.hh', - 'hb-ot-var-cvar-table.hh', - 'hb-ot-var-fvar-table.hh', - 'hb-ot-var-gvar-table.hh', - 'hb-ot-var-hvar-table.hh', - 'hb-ot-var-mvar-table.hh', - 'hb-ot-var-varc-table.hh', - 'hb-ot-var.cc', - 'hb-ot-vorg-table.hh', - 'hb-pool.hh', - 'hb-sanitize.hh', - 'hb-serialize.hh', - 'hb-set-digest.hh', - 'hb-set.cc', - 'hb-set.hh', - 'hb-shape-plan.cc', - 'hb-shape-plan.hh', - 'hb-shape.cc', - 'hb-shaper-impl.hh', - 'hb-shaper-list.hh', - 'hb-shaper.cc', - 'hb-shaper.hh', - 'hb-static.cc', - 'hb-string-array.hh', - 'hb-style.cc', - 'hb-ucd-table.hh', - 'hb-ucd.cc', - 'hb-unicode-emoji-table.hh', - 'hb-unicode.cc', - 'hb-unicode.hh', - 'hb-utf.hh', - 'hb-vector.hh', - 'hb.hh', -) - -hb_base_ragel_generated_sources = files( - 'hb-buffer-deserialize-json.hh', - 'hb-buffer-deserialize-text-glyphs.hh', - 'hb-buffer-deserialize-text-unicode.hh', - 'hb-number-parser.hh', - 'hb-ot-shaper-indic-machine.hh', - 'hb-ot-shaper-khmer-machine.hh', - 'hb-ot-shaper-myanmar-machine.hh', - 'hb-ot-shaper-use-machine.hh', -) -hb_base_ragel_sources = [ - 'hb-buffer-deserialize-json.rl', - 'hb-buffer-deserialize-text-glyphs.rl', - 'hb-buffer-deserialize-text-unicode.rl', - 'hb-number-parser.rl', - 'hb-ot-shaper-indic-machine.rl', - 'hb-ot-shaper-khmer-machine.rl', - 'hb-ot-shaper-myanmar-machine.rl', - 'hb-ot-shaper-use-machine.rl', -] - -hb_base_headers = files( - 'hb-aat-layout.h', - 'hb-aat.h', - 'hb-blob.h', - 'hb-buffer.h', - 'hb-common.h', - 'hb-cplusplus.hh', - 'hb-deprecated.h', - 'hb-draw.h', - 'hb-paint.h', - 'hb-face.h', - 'hb-font.h', - 'hb-map.h', - 'hb-ot-color.h', - 'hb-ot-deprecated.h', - 'hb-ot-font.h', - 'hb-ot-layout.h', - 'hb-ot-math.h', - 'hb-ot-meta.h', - 'hb-ot-metrics.h', - 'hb-ot-name.h', - 'hb-ot-shape.h', - 'hb-ot-var.h', - 'hb-ot.h', - 'hb-set.h', - 'hb-shape-plan.h', - 'hb-shape.h', - 'hb-style.h', - 'hb-unicode.h', - 'hb.h', -) -hb_base_headers += hb_version_h - -# Optional Sources and Headers with external deps - -hb_ft_sources = files('hb-ft.cc', 'hb-ft-colr.hh') -hb_ft_headers = files('hb-ft.h') - -hb_glib_sources = files('hb-glib.cc') -hb_glib_headers = files('hb-glib.h') - -hb_graphite2_sources = files('hb-graphite2.cc') -hb_graphite2_headers = files('hb-graphite2.h') - -hb_wasm_sources = files( - 'hb-wasm-api.cc', - 'hb-wasm-api.hh', - 'hb-wasm-api-blob.hh', - 'hb-wasm-api-buffer.hh', - 'hb-wasm-api-common.hh', - 'hb-wasm-api-face.hh', - 'hb-wasm-api-font.hh', - 'hb-wasm-api-shape.hh', - 'hb-wasm-shape.cc', -) -hb_wasm_headers = files() - -# System-dependent sources and headers - -hb_coretext_sources = files('hb-coretext-shape.cc', 'hb-coretext-font.cc') -hb_coretext_headers = files('hb-coretext.h') - -hb_directwrite_sources = files('hb-directwrite.cc') -hb_directwrite_headers = files('hb-directwrite.h') - -hb_gdi_sources = files('hb-gdi.cc') -hb_gdi_headers = files('hb-gdi.h') - -hb_uniscribe_sources = files('hb-uniscribe.cc') -hb_uniscribe_headers = files('hb-uniscribe.h') - -# Sources for libharfbuzz-gobject and libharfbuzz-icu -hb_icu_sources = files('hb-icu.cc') -hb_icu_headers = files('hb-icu.h') - -# Sources for libharfbuzz-subset -hb_subset_sources = files( - 'hb-number.cc', - 'hb-number.hh', - 'hb-ot-cff1-table.cc', - 'hb-ot-cff2-table.cc', - 'hb-static.cc', - 'hb-subset-accelerator.hh', - 'hb-subset-cff-common.cc', - 'hb-subset-cff-common.hh', - 'hb-subset-cff1.cc', - 'hb-subset-cff2.cc', - 'hb-subset-input.cc', - 'hb-subset-input.hh', - 'hb-subset-instancer-iup.hh', - 'hb-subset-instancer-iup.cc', - 'hb-subset-instancer-solver.hh', - 'hb-subset-instancer-solver.cc', - 'hb-subset-plan.cc', - 'hb-subset-plan.hh', - 'hb-subset-plan-member-list.hh', - 'hb-subset-repacker.cc', - 'graph/gsubgpos-context.cc', - 'graph/gsubgpos-context.hh', - 'graph/gsubgpos-graph.hh', - 'graph/pairpos-graph.hh', - 'graph/markbasepos-graph.hh', - 'graph/coverage-graph.hh', - 'graph/classdef-graph.hh', - 'graph/split-helpers.hh', - 'hb-subset.cc', - 'hb-subset.hh', -) - -hb_subset_headers = files( - 'hb-subset.h', - 'hb-subset-repacker.h' -) - -hb_gobject_sources = files( - 'hb-gobject-structs.cc' -) - -hb_gobject_headers = files( - 'hb-gobject.h', - 'hb-gobject-structs.h', -) - -ragel = find_program('ragel', version: '6.10', required: false) -has_ragel = ragel.found() -if not has_ragel and get_option('ragel_subproject') - ragel = subproject('ragel').get_variable('ragel') - has_ragel = true -endif -if not has_ragel - if not meson.is_subproject() - warning('You have to install ragel if you are going to develop HarfBuzz itself') - endif -else - ragel_helper = find_program('gen-ragel-artifacts.py') - foreach rl : hb_base_ragel_sources - hh = rl.split('.')[0] + '.hh' - custom_target('@0@'.format(hh), - build_by_default: true, - input: rl, - output: hh, - command: [ragel_helper, ragel, '@OUTPUT@', meson.current_source_dir(), '@INPUT@'], - ) - endforeach -endif - -custom_target('harfbuzz.cc', - build_by_default: true, - output: 'harfbuzz.cc', - input: hb_base_sources + hb_glib_sources + hb_ft_sources + - hb_graphite2_sources + hb_uniscribe_sources + hb_gdi_sources + - hb_directwrite_sources + hb_coretext_sources + hb_wasm_sources, - command: [find_program('gen-harfbuzzcc.py'), - '@OUTPUT@', meson.current_source_dir(), '@INPUT@'], -) - -incsrc = include_directories('.') - -hb_sources = hb_base_sources + hb_base_ragel_generated_sources -hb_headers = hb_base_headers - -harfbuzz_deps = [thread_dep, m_dep] + harfbuzz_extra_deps - -if get_option('with_libstdcxx') - chosen_linker = 'cpp' -else - # Use a C linker, not C++; Don't link to libstdc++ - chosen_linker = 'c' -endif -libharfbuzz_link_language = chosen_linker - -if conf.get('HAVE_FREETYPE', 0) == 1 - hb_sources += hb_ft_sources - hb_headers += hb_ft_headers - harfbuzz_deps += [freetype_dep] -endif - -if conf.get('HAVE_GLIB', 0) == 1 - hb_sources += hb_glib_sources - hb_headers += hb_glib_headers - harfbuzz_deps += [glib_dep] -endif - -# We set those here to not include the sources below that are of no use to -# GObject Introspection -gir_sources = hb_sources + hb_gobject_sources -gir_headers = hb_headers + hb_gobject_headers - -if conf.get('HAVE_GDI', 0) == 1 - hb_sources += hb_gdi_sources - hb_headers += hb_gdi_headers - harfbuzz_deps += gdi_uniscribe_deps -endif - -if conf.get('HAVE_GRAPHITE2', 0) == 1 - hb_sources += hb_graphite2_sources - hb_headers += hb_graphite2_headers - harfbuzz_deps += [graphite2_dep, graphite_dep] -endif - -if conf.get('HAVE_WASM', 0) == 1 - hb_sources += hb_wasm_sources - hb_headers += hb_wasm_headers - harfbuzz_deps += wasm_dep - #harfbuzz_deps += llvm_dep -endif - -if conf.get('HAVE_UNISCRIBE', 0) == 1 - hb_sources += hb_uniscribe_sources - hb_headers += hb_uniscribe_headers -endif - -if conf.get('HAVE_DIRECTWRITE', 0) == 1 - hb_sources += hb_directwrite_sources - hb_headers += hb_directwrite_headers - # hb-directwrite needs a C++ linker - libharfbuzz_link_language = 'cpp' -endif - -if conf.get('HAVE_CORETEXT', 0) == 1 - hb_sources += hb_coretext_sources - hb_headers += hb_coretext_headers - harfbuzz_deps += coretext_deps -endif - -have_icu = conf.get('HAVE_ICU', 0) == 1 -have_icu_builtin = conf.get('HAVE_ICU_BUILTIN', 0) == 1 -if have_icu and have_icu_builtin - hb_sources += hb_icu_sources - hb_headers += hb_icu_headers - harfbuzz_deps += [icu_dep] -endif - -features = [ - 'CAIRO', - 'CORETEXT', - 'DIRECTWRITE', - 'FREETYPE', - 'GDI', - 'GLIB', - 'GOBJECT', - 'GRAPHITE', - 'ICU', - 'UNISCRIBE', - 'WASM', -] - -hb_enabled_features = configuration_data() -hb_supported_features = configuration_data() -foreach feature : features - key = 'HB_HAS_@0@'.format(feature) - hb_enabled_features.set(key, conf.get('HAVE_@0@'.format(feature), false)) - hb_supported_features.set(key, 1) -endforeach - -# The enabled features. This file is installed. -hb_features_h = configure_file(input: 'hb-features.h.in', - output: 'hb-features.h', - configuration: hb_enabled_features, - install: true, - install_dir: get_option('includedir') / meson.project_name()) - -# This file is generated to convince gtk-doc to generate documentation for all -# HB_HAS_* macros, whether they are enabled for the current build or not. -# This file should not be installed. -hb_supported_features_h = configure_file(input: 'hb-features.h.in', - output: 'hb-supported-features.h', - configuration: hb_supported_features, - install: false) - - -# Base and default-included sources and headers -gen_def = find_program('gen-def.py') -gen_def_cmd = [gen_def, '@OUTPUT@', '@INPUT@'] -if get_option('experimental_api') - gen_def_cmd += '--experimental-api' -endif - -# harfbuzz -harfbuzz_def = custom_target('harfbuzz.def', - command: gen_def_cmd, - input: hb_headers, - output: 'harfbuzz.def') -defs_list = [harfbuzz_def] - -version = '0.@0@.0'.format(hb_version_int) - -extra_hb_cpp_args = [] -if cpp.get_define('_MSC_FULL_VER') != '' - if get_option('default_library') != 'static' - extra_hb_cpp_args += '-DHB_DLL_EXPORT' - endif - hb_so_version = '' -else - hb_so_version = '0' -endif - -if get_option('fuzzer_ldflags') != '' - extra_hb_cpp_args += ['-DHB_CUSTOM_MALLOC'] - hb_sources += 'failing-alloc.c' - hb_subset_sources += 'failing-alloc.c' - hb_icu_sources += 'failing-alloc.c' - hb_gobject_sources += 'failing-alloc.c' -endif - -darwin_versions = [hb_version_int, '@0@.0.0'.format(hb_version_int)] - -libharfbuzz = library('harfbuzz', hb_sources, - include_directories: incconfig, - dependencies: harfbuzz_deps, - cpp_args: cpp_args + extra_hb_cpp_args, - soversion: hb_so_version, - version: version, - install: true, - darwin_versions: darwin_versions, - link_language: libharfbuzz_link_language, -) - -libharfbuzz_dep = declare_dependency( - link_with: libharfbuzz, - include_directories: incsrc, - dependencies: harfbuzz_deps) -meson.override_dependency('harfbuzz', libharfbuzz_dep) - -# harfbuzz-subset -harfbuzz_subset_def = custom_target('harfbuzz-subset.def', - command: gen_def_cmd, - input: hb_subset_headers, - output: 'harfbuzz-subset.def') -defs_list += [harfbuzz_subset_def] - -libharfbuzz_subset = library('harfbuzz-subset', hb_subset_sources, - include_directories: incconfig, - dependencies: [m_dep], - link_with: [libharfbuzz], - cpp_args: cpp_args + extra_hb_cpp_args, - soversion: hb_so_version, - version: version, - install: true, - darwin_versions: darwin_versions, - link_language: chosen_linker, -) - -custom_target('harfbuzz-subset.cc', - build_by_default: true, - output: 'harfbuzz-subset.cc', - input: hb_base_sources + hb_subset_sources, - command: [find_program('gen-harfbuzzcc.py'), - '@OUTPUT@', meson.current_source_dir(), '@INPUT@'], -) - -libharfbuzz_subset_dep = declare_dependency( - link_with: libharfbuzz_subset, - include_directories: incsrc, - dependencies: [m_dep]) -meson.override_dependency('harfbuzz-subset', libharfbuzz_subset_dep) - -libharfbuzz_cairo_dep = null_dep -if conf.get('HAVE_CAIRO', 0) == 1 - hb_cairo_sources = [ - 'hb-cairo.cc', - 'hb-cairo-utils.cc', - 'hb-static.cc' - ] - - hb_cairo_headers = [ - 'hb-cairo.h', - ] - - cairo_dep = dependency('cairo') - - libharfbuzz_cairo = library('harfbuzz-cairo', hb_cairo_sources, - include_directories: incconfig, - dependencies: [m_dep, cairo_dep], - link_with: [libharfbuzz], - cpp_args: cpp_args + extra_hb_cpp_args, - soversion: hb_so_version, - version: version, - install: true, - darwin_versions: darwin_versions, - link_language: chosen_linker, - ) - - install_headers(hb_cairo_headers, subdir: meson.project_name()) - - libharfbuzz_cairo_dep = declare_dependency( - link_with: libharfbuzz_cairo, - include_directories: incsrc, - dependencies: [m_dep, cairo_dep]) - meson.override_dependency('harfbuzz-cairo', libharfbuzz_cairo_dep) - - harfbuzz_cairo_def = custom_target('harfbuzz-cairo.def', - command: gen_def_cmd, - input: hb_cairo_headers, - output: 'harfbuzz-cairo.def') - defs_list += [harfbuzz_cairo_def] - - pkgmod.generate(libharfbuzz_cairo, - description: 'HarfBuzz cairo support', - requires: ['harfbuzz = @0@'.format(meson.project_version())], - subdirs: [meson.project_name()], - version: meson.project_version(), - ) -endif - -if get_option('tests').enabled() - # TODO: Microsoft LINK gives the following because extern, non dllexport - # symbols can only be used when linking against a static library - # error LNK2019: unresolved external symbol "unsigned __int64 const * const _hb_NullPool" - if cpp.get_define('_MSC_FULL_VER') == '' - noinst_programs = { - 'main': 'main.cc', - 'test-basics': 'test.cc', - 'test-buffer-serialize': 'test-buffer-serialize.cc', - 'test-ot-meta': 'test-ot-meta.cc', - 'test-ot-name': 'test-ot-name.cc', - 'test-ot-glyphname': 'test-ot-glyphname.cc', - 'test-ot-gpos-size-params': 'test-gpos-size-params.cc', - 'test-ot-gsub-get-alternates': 'test-gsub-get-alternates.cc', - 'test-ot-gsub-would-substitute': 'test-gsub-would-substitute.cc', - 'test-use-table': 'test-use-table.cc', - } - foreach name, source : noinst_programs - executable(name, source, - include_directories: incconfig, - cpp_args: cpp_args + ['-UNDEBUG'], - dependencies: libharfbuzz_dep, - install: false, - ) - endforeach - endif - - compiled_tests = { - 'test-algs': ['test-algs.cc', 'hb-static.cc'], - 'test-array': ['test-array.cc'], - 'test-bimap': ['test-bimap.cc', 'hb-static.cc'], - 'test-cff': ['test-cff.cc', 'hb-static.cc'], - 'test-classdef-graph': ['graph/test-classdef-graph.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], - 'test-iter': ['test-iter.cc', 'hb-static.cc'], - 'test-machinery': ['test-machinery.cc', 'hb-static.cc'], - 'test-map': ['test-map.cc', 'hb-static.cc'], - 'test-multimap': ['test-multimap.cc', 'hb-static.cc'], - 'test-number': ['test-number.cc', 'hb-number.cc'], - 'test-ot-tag': ['hb-ot-tag.cc'], - 'test-set': ['test-set.cc', 'hb-static.cc'], - 'test-serialize': ['test-serialize.cc', 'hb-static.cc'], - 'test-vector': ['test-vector.cc', 'hb-static.cc'], - 'test-repacker': ['test-repacker.cc', 'hb-static.cc', 'graph/gsubgpos-context.cc'], - 'test-instancer-solver': ['test-subset-instancer-solver.cc', 'hb-subset-instancer-solver.cc', 'hb-static.cc'], - 'test-priority-queue': ['test-priority-queue.cc', 'hb-static.cc'], - 'test-tuple-varstore': ['test-tuple-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-subset-instancer-iup.cc', 'hb-static.cc'], - 'test-item-varstore': ['test-item-varstore.cc', 'hb-subset-instancer-solver.cc', 'hb-subset-instancer-iup.cc', 'hb-static.cc'], - 'test-unicode-ranges': ['test-unicode-ranges.cc'], - } - foreach name, source : compiled_tests - if cpp.get_define('_MSC_FULL_VER') != '' and source.contains('hb-static.cc') - # TODO: Microsoft compilers cannot link tests using hb-static.cc, fix them - continue - endif - test(name, executable(name, source, - include_directories: incconfig, - cpp_args: cpp_args + ['-DMAIN', '-UNDEBUG'], - dependencies: libharfbuzz_dep, - install: false, - ), suite: ['src']) - endforeach -endif - -pkgmod.generate(libharfbuzz, - description: 'HarfBuzz text shaping library', - subdirs: [meson.project_name()], - version: meson.project_version(), -) - -pkgmod.generate(libharfbuzz_subset, - description: 'HarfBuzz font subsetter', - requires: ['harfbuzz = @0@'.format(meson.project_version())], - subdirs: [meson.project_name()], - version: meson.project_version(), -) - -libharfbuzz_icu_dep = null_dep -if have_icu and not have_icu_builtin - harfbuzz_icu_def = custom_target('harfbuzz-icu.def', - command: gen_def_cmd, - input: [hb_icu_headers], - output: 'harfbuzz-icu.def') - defs_list += [harfbuzz_icu_def] - - libharfbuzz_icu = library('harfbuzz-icu', [hb_icu_sources, hb_icu_headers], - include_directories: incconfig, - dependencies: icu_dep, - link_with: [libharfbuzz], - cpp_args: cpp_args + extra_hb_cpp_args, - soversion: hb_so_version, - version: version, - install: true, - darwin_versions: darwin_versions, - # ICU links to stdc++ anyway so the default linker is good - # link_language: chosen_linker, - ) - - libharfbuzz_icu_dep = declare_dependency( - link_with: libharfbuzz_icu, - include_directories: incsrc, - dependencies: icu_dep) - meson.override_dependency('harfbuzz-icu', libharfbuzz_icu_dep) - - pkgmod.generate(libharfbuzz_icu, - description: 'HarfBuzz text shaping library ICU integration', - requires: ['harfbuzz = @0@'.format(meson.project_version())], - subdirs: [meson.project_name()], - version: meson.project_version(), - ) - - install_headers(hb_icu_headers, subdir: meson.project_name()) -endif - -have_gobject = conf.get('HAVE_GOBJECT', 0) == 1 - -# This code (especially PACKAGE_INIT) kept similar to what CMake's own -# configure_package_config_file() generates, see -# https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:configure_package_config_file - -cmake_config = configuration_data() -cmake_config_dir = cmake_package_install_dir / 'harfbuzz' - -have_fs_relative_to = meson.version().version_compare('>=1.3.0') - -if not have_fs_relative_to - relative_to = find_program('relative_to.py') -endif - -if have_fs_relative_to - cmake_package_prefix_dir = fs.relative_to(get_option('prefix'), get_option('prefix') / cmake_config_dir) -else - cmake_package_prefix_dir = run_command(relative_to, get_option('prefix'), get_option('prefix') / cmake_config_dir, check: true).stdout().strip() -endif - -cmake_package_prefix_dir = '${CMAKE_CURRENT_LIST_DIR}/@0@'.format(cmake_package_prefix_dir) - -# Make all the relevant paths relative to our prefix, so we can later append -# them onto ${PACKAGE_PREFIX_DIR} to get the correct paths. - -cmake_install_includedir = get_option('includedir') - -if fs.is_absolute(cmake_install_includedir) - if have_fs_relative_to - cmake_install_includedir = fs.relative_to(cmake_install_includedir, get_option('prefix')) - else - cmake_install_includedir = run_command(relative_to, cmake_install_includedir, get_option('prefix'), check: true).stdout().strip() - endif -endif - -cmake_install_libdir = get_option('libdir') - -if fs.is_absolute(cmake_install_libdir) - if have_fs_relative_to - cmake_install_libdir = fs.relative_to(cmake_install_libdir, get_option('prefix')) - else - cmake_install_libdir = run_command(relative_to, cmake_install_libdir, get_option('prefix'), check: true).stdout().strip() - endif -endif - -cmake_config.set('PACKAGE_INIT', ''' -get_filename_component(PACKAGE_PREFIX_DIR "@0@" ABSOLUTE) - -macro(set_and_check _var _file) - set(${_var} "${_file}") - if(NOT EXISTS "${_file}") - message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") - endif() -endmacro() - -macro(check_required_components _NAME) - foreach(comp ${${_NAME}_FIND_COMPONENTS}) - if(NOT ${_NAME}_${comp}_FOUND) - if(${_NAME}_FIND_REQUIRED_${comp}) - set(${_NAME}_FOUND FALSE) - endif() - endif() - endforeach() -endmacro() -'''.format(cmake_package_prefix_dir)) - -cmake_config.set('PACKAGE_CMAKE_INSTALL_INCLUDEDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_includedir)) -cmake_config.set('PACKAGE_CMAKE_INSTALL_LIBDIR', '${PACKAGE_PREFIX_DIR}/@0@'.format(cmake_install_libdir)) -cmake_config.set('PACKAGE_INCLUDE_INSTALL_DIR', '${PACKAGE_PREFIX_DIR}/@0@/@1@'.format(cmake_install_includedir, meson.project_name())) -cmake_config.set('HB_HAVE_GOBJECT', have_gobject ? 'YES' : 'NO') -cmake_config.set('HB_LIBRARY_TYPE', get_option('default_library') == 'static' ? 'STATIC' : 'SHARED') - -if get_option('default_library') == 'static' - cmake_config.set('HB_LIB_PREFIX', '${CMAKE_STATIC_LIBRARY_PREFIX}') - cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_STATIC_LIBRARY_SUFFIX}') -elif host_machine.system() == 'darwin' - cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}') - cmake_config.set('HB_LIB_SUFFIX', '.@0@${CMAKE_SHARED_LIBRARY_SUFFIX}'.format(hb_so_version)) -elif host_machine.system() == 'windows' - cmake_config.set('HB_LIB_PREFIX', '${CMAKE_IMPORT_LIBRARY_PREFIX}') - cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_IMPORT_LIBRARY_SUFFIX}') -else - cmake_config.set('HB_LIB_PREFIX', '${CMAKE_SHARED_LIBRARY_PREFIX}') - cmake_config.set('HB_LIB_SUFFIX', '${CMAKE_SHARED_LIBRARY_SUFFIX}.@0@'.format(version)) -endif - -configure_file(input: 'harfbuzz-config.cmake.in', - output: 'harfbuzz-config.cmake', - configuration: cmake_config, - install_dir: cmake_config_dir, -) - -gobject_enums_c = [] -gobject_enums_h = [] -libharfbuzz_gobject_dep = null_dep -if have_gobject - gnome = import('gnome') - - h_templ = configure_file( - input: 'hb-gobject-enums.h.tmpl', - output: 'hb-gobject-enums-tmp.h.tmpl', - copy: true) - - cc_templ = configure_file( - input: 'hb-gobject-enums.cc.tmpl', - output: 'hb-gobject-enums-tmp.cc.tmpl', - copy: true) - - enums = gnome.mkenums('hb-gobject', - sources: hb_headers, - h_template: h_templ, - c_template: cc_templ, - identifier_prefix: 'hb_', - symbol_prefix: 'hb_gobject', - ) - - gobject_enums_c = custom_target('hb-gobject-enums.cc', - input: enums[0], - output: 'hb-gobject-enums.cc', - command: [find_program('fix_get_types.py'), '@INPUT@', '@OUTPUT@'] - ) - - gobject_enums_h = custom_target('hb-gobject-enums.h', - input: enums[1], - output: 'hb-gobject-enums.h', - command: [find_program('fix_get_types.py'), '@INPUT@', '@OUTPUT@'], - install: true, - install_dir: get_option('prefix') / get_option('includedir') / meson.project_name(), - ) - - hb_gobject_sources += [gobject_enums_c] - - harfbuzz_gobject_def = custom_target('harfbuzz-gobject.def', - command: gen_def_cmd, - input: [hb_gobject_headers, gobject_enums_h], - output: 'harfbuzz-gobject.def') - defs_list += [harfbuzz_gobject_def] - - libharfbuzz_gobject = library('harfbuzz-gobject', [hb_gobject_sources, gobject_enums_c, gobject_enums_h], - include_directories: incconfig, - dependencies: [glib_dep, gobject_dep], - link_with: [libharfbuzz], - cpp_args: cpp_args + extra_hb_cpp_args, - soversion: hb_so_version, - version: version, - install: true, - darwin_versions: darwin_versions, - link_language: chosen_linker, - ) - - gir = find_program('g-ir-scanner', required: get_option('introspection')) - build_gir = gir.found() and (not meson.is_cross_build() or get_option('introspection').enabled()) - - build_gir = build_gir and get_option('default_library') != 'static' - if not build_gir and get_option('introspection').enabled() - error('Introspection support is requested but the default library option should be shared or both') - endif - - if build_gir - conf.set('HAVE_INTROSPECTION', 1) - hb_gen_files_gir = gnome.generate_gir([libharfbuzz_gobject, libharfbuzz], - sources: [gir_headers, gir_sources, gobject_enums_h], - dependencies: libharfbuzz_dep, - namespace: 'HarfBuzz', - nsversion: '0.0', - identifier_prefix: 'hb_', - symbol_prefix: ['hb', 'hb_gobject'], - includes: ['GObject-2.0', 'freetype2-2.0'], - export_packages: ['harfbuzz-gobject', 'harfbuzz'], - header: 'hb-gobject.h', - install: true, - extra_args: ['--cflags-begin', - '-DHB_NO_SINGLE_HEADER_ERROR', - '-DHAVE_GOBJECT', - '-DHB_EXTERN=', - '--cflags-end']) - endif - - libharfbuzz_gobject_dep = declare_dependency( - link_with: libharfbuzz_gobject, - include_directories: incsrc, - sources: build_gir ? hb_gen_files_gir : hb_gobject_sources, - dependencies: [glib_dep, gobject_dep]) - meson.override_dependency('harfbuzz-gobject', libharfbuzz_gobject_dep) - - pkgmod.generate(libharfbuzz_gobject, - description: 'HarfBuzz text shaping library GObject integration', - requires: ['harfbuzz = @0@'.format(meson.project_version()), 'glib-2.0', 'gobject-2.0'], - subdirs: [meson.project_name()], - version: meson.project_version(), - ) - - install_headers(hb_gobject_headers, subdir: meson.project_name()) -else - if get_option('introspection').enabled() - error('introspection requires gobject to be enabled') - endif -endif - -if get_option('tests').enabled() - dist_check_script = [ - 'check-c-linkage-decls', - 'check-externs', - 'check-header-guards', - 'check-includes', - ] - - env = environment() - env.set('srcdir', meson.current_source_dir()) - env.set('base_srcdir', meson.source_root()) - env.set('builddir', meson.current_build_dir()) - env.set('libs', meson.current_build_dir()) # TODO: Merge this with builddir after autotools removal - HBSOURCES = [] - foreach f : hb_sources - HBSOURCES += '@0@'.format(f) - endforeach - env.set('HBSOURCES', ' '.join(HBSOURCES)) - HBHEADERS = [] - foreach f : hb_headers - HBHEADERS += '@0@'.format(f) - endforeach - env.set('HBHEADERS', ' '.join(HBHEADERS)) - - if cpp.get_argument_syntax() != 'msvc' and not meson.is_cross_build() # ensure the local tools are usable - dist_check_script += ['check-static-inits', 'check-symbols'] - if get_option('wasm').disabled() and not get_option('with_libstdcxx') - dist_check_script += ['check-libstdc++'] - endif - endif - - foreach name : dist_check_script - test(name, find_program(name + '.py'), - env: env, - depends: name == 'check-symbols' ? defs_list : [], - suite: ['src'], - ) - endforeach -endif - -install_headers(hb_headers + hb_subset_headers, subdir: meson.project_name()) diff --git a/thirdparty/harfbuzz/upstream/ms-use/COPYING b/thirdparty/harfbuzz/upstream/ms-use/COPYING deleted file mode 100644 index 9e841e7a2..000000000 --- a/thirdparty/harfbuzz/upstream/ms-use/COPYING +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft 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 diff --git a/thirdparty/harfbuzz/upstream/ms-use/IndicPositionalCategory-Additional.txt b/thirdparty/harfbuzz/upstream/ms-use/IndicPositionalCategory-Additional.txt deleted file mode 100644 index 4b0c7f200..000000000 --- a/thirdparty/harfbuzz/upstream/ms-use/IndicPositionalCategory-Additional.txt +++ /dev/null @@ -1,123 +0,0 @@ -# Override values For Indic_Positional_Category -# Not derivable -# Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 -# Updated for Unicode 10.0 by Andrew Glass 2017-07-25 -# Ammended for Unicode 10.0 by Andrew Glass 2018-09-21 -# Updated for L2/19-083 by Andrew Glass 2019-05-06 -# Updated for Unicode 12.1 by Andrew Glass 2019-05-30 -# Updated for Unicode 13.0 by Andrew Glass 2020-07-28 -# Updated for Unicode 14.0 by Andrew Glass 2021-09-28 -# Updated for Unicode 15.0 by Andrew Glass 2022-09-16 -# Updated for Unicode 15.1 by Andrew Glass 2023-09-14 -# Updated for Unicode 16.0 by Andrew Glass 2024-09-11 - -# ================================================ -# ================================================ -# OVERRIDES TO ASSIGNED VALUES -# ================================================ -# ================================================ - -# Indic_Positional_Category=Bottom -0F72 ; Bottom # Mn TIBETAN VOWEL SIGN I # Not really below, but need to override to fit into Universal model -0F7A..0F7D ; Bottom # Mn [4] TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN OO # Not really below, but need to override to fit into Universal model -0F80 ; Bottom # Mn TIBETAN VOWEL SIGN REVERSED I # Not really below, but need to override to fit into Universal model -A9BF ; Bottom # Mc JAVANESE CONSONANT SIGN CAKRA -10A38 ; Bottom # Mn KHAROSHTHI SIGN BAR ABOVE # Overriden, ccc controls order USE issue #26 -11127..11129 ; Bottom # Mn [3] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN II -1112D ; Bottom # Mn CHAKMA VOWEL SIGN AI -11130 ; Bottom # Mn CHAKMA VOWEL SIGN OI -1BF2..1BF3 ; Bottom # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN # see USE issue #20 - -# ================================================ - -# Indic_Positional_Category=Left -1C29 ; Left # Mc LEPCHA VOWEL SIGN OO # Reduced from Top_And_Left - -# ================================================ - - -# Indic_Positional_Category=Right -A9BE ; Right # Mc JAVANESE CONSONANT SIGN PENGKAL # Reduced from Bottom_And_Right -10A0C ; Right # Mn KHAROSHTHI VOWEL LENGTH MARK # Follows vowels and precedes vowel modifiers -11942 ; Right # Mc DIVES AKURU MEDIAL RA # Reduced from Bottom_And_Right - -# ================================================ - -# Indic_Positional_Category=Top -0F74 ; Top # Mn TIBETAN VOWEL SIGN U # Not really above, but need to override to fit into Universal model -1A18 ; Top # Mn BUGINESE VOWEL SIGN U # Workaround to allow below to occur before above by treating all below marks as above -AA35   ; Top # Mn       CHAM CONSONANT SIGN -1112A..1112B ; Top # Mn [2] CHAKMA VOWEL SIGN U..CHAKMA VOWEL SIGN UU # see USE issue #25 -11131..11132 ; Top # Mn [2] CHAKMA O MARK..CHAKMA AU MARK # see USE issue #25 -1E4EC..1E4EF ; Top # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH # 1E4EE is below, but made to for ccc - -# ================================================ - -# Indic_Positional_Category=Top_And_Right -0E33 ; Top_And_Right # Lo THAI CHARACTER SARA AM # IPC has Right, which seems to be a mistake. -0EB3 ; Top_And_Right # Lo LAO VOWEL SIGN AM # IPC has Right, which seems to be a mistake. - -# ================================================ -# ================================================ -# VALUES NOT ASSIGNED IN Indic_Positional_Category -# ================================================ -# ================================================ - -# Indic_Positional_Category=Bottom -0859..085B ; Bottom # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -18A9 ; Bottom # Mn MONGOLIAN LETTER ALI GALI DAGALGA -10AE5 ; Bottom # Mn MANICHAEAN ABBREVIATION MARK ABOVE # Overriden, ccc controls order -10AE6 ; Bottom # Mn MANICHAEAN ABBREVIATION MARK BELOW -10F46..10F47 ; Bottom # Mn [2] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING TWO DOTS BELOW -10F48..10F4A ; Bottom # Mn [3] SOGDIAN COMBINING DOT ABOVE..SOGDIAN COMBINING CURVE ABOVE # Overriden, ccc controls order -10F4B ; Bottom # Mn SOGDIAN COMBINING CURVE BELOW -10F4C ; Bottom # Mn SOGDIAN COMBINING HOOK ABOVE # Overriden, ccc controls order -10F4D..10F50 ; Bottom # Mn [4] SOGDIAN COMBINING HOOK BELOW..SOGDIAN COMBINING STROKE BELOW -10F82 ; Bottom # Mn OLD UYGHUR COMBINING DOT ABOVE # Overriden, ccc controls order -10F83 ; Bottom # Mn OLD UYGHUR COMBINING DOT BELOW -10F84 ; Bottom # Mn OLD UYGHUR COMBINING TWO DOTS ABOVE # Overriden, ccc controls order -10F85 ; Bottom # Mn OLD UYGHUR COMBINING TWO DOTS BELOW -113CF ; Bottom # Mc TULU-TIGALARI SIGN LOOPED VIRAMA # Issue #17 -16F4F ; Bottom # Mn MIAO SIGN CONSONANT MODIFIER BAR -16F51..16F87 ; Bottom # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI -16F8F..16F92 ; Bottom # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW -1E5EE ; Bottom # Mn OL ONAL SIGN MU # Not really below, but need to override to fit into Universal model -1E5EF ; Bottom # Mn OL ONAL SIGN IKIR - -# ================================================ - -# Indic_Positional_Category=Left -103C ; Left # Mc MYANMAR CONSONANT SIGN MEDIAL RA - -# ================================================ - -# Indic_Positional_Category=Top -07EB..07F3 ; Top # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE -07FD ; Top # Mn NKO DANTAYALAN # Not really top, but assigned here to allow ccc to control mark order -1885..1886 ; Top # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA -1B6C ; Top # Mn BALINESE MUSICAL SYMBOL COMBINING ENDEP -1CF8..1CF9 ; Top # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE -10D24..10D27 ; Top # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI -10EAB..10EAC ; Top # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK -10D69..10D6D ; Top # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK -16B30..16B36 ; Top # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM -1E130..1E136 ; Top # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D -1E2AE ; Top # Mn TOTO SIGN RISING TONE -1E2EC..1E2EF ; Top # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI -1E944..1E94A ; Top # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA - -# ================================================ - -# Indic_Positional_Category=Overstruck -1BC9D..1BC9E ; Overstruck # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK - -# ================================================ -# ================================================ -# Deliberately suppressed -# ================================================ -# ================================================ - -# Indic_Positional_Category=NA -180B..180D ; NA # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE -180F ; NA # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR -2D7F ; NA # Mn TIFINAGH CONSONANT JOINER diff --git a/thirdparty/harfbuzz/upstream/ms-use/IndicShapingInvalidCluster.txt b/thirdparty/harfbuzz/upstream/ms-use/IndicShapingInvalidCluster.txt deleted file mode 100644 index 9e0edd34c..000000000 --- a/thirdparty/harfbuzz/upstream/ms-use/IndicShapingInvalidCluster.txt +++ /dev/null @@ -1,113 +0,0 @@ -# IndicShapingInvalidCluster.txt -# Date: 2015-03-12, 21:17:00 GMT [AG] -# Date: 2019-11-08, 23:22:00 GMT [AG] -# -# This file defines the following property: -# -# Indic_Shaping_Invalid_Cluster -# -# Scope: This file enumerates sequences of characters that should be treated as invalid clusters - - 0905 0946 ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN SHORT E - 0905 093E ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN AA - 0930 094D 0907 ; # DEVANAGARI LETTER RA, DEVANAGARI SIGN VIRAMA, DEVANAGARI LETTER I - 0909 0941 ; # DEVANAGARI LETTER U, DEVANAGARI VOWEL SIGN U - 090F 0945 ; # DEVANAGARI LETTER E, DEVANAGARI VOWEL SIGN CANDRA E - 090F 0946 ; # DEVANAGARI LETTER E, DEVANAGARI VOWEL SIGN SHORT E - 090F 0947 ; # DEVANAGARI LETTER E, DEVANAGARI VOWEL SIGN E - 0905 0949 ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN CANDRA O - 0906 0945 ; # DEVANAGARI LETTER AA, DEVANAGARI VOWEL SIGN CANDRA E - 0905 094A ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN SHORT O - 0906 0946 ; # DEVANAGARI LETTER AA, DEVANAGARI VOWEL SIGN SHORT E - 0905 094B ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN O - 0906 0947 ; # DEVANAGARI LETTER AA, DEVANAGARI VOWEL SIGN E - 0905 094C ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN AU - 0906 0948 ; # DEVANAGARI LETTER AA, DEVANAGARI VOWEL SIGN AI - 0905 0945 ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN CANDRA E - 0905 093A ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN OE - 0905 093B ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN OOE - 0906 093A ; # DEVANAGARI LETTER AA, DEVANAGARI VOWEL SIGN OE - 0905 094F ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN AW - 0905 0956 ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN UE - 0905 0957 ; # DEVANAGARI LETTER A, DEVANAGARI VOWEL SIGN UUE - 0985 09BE ; # BENGALI LETTER A, BENGALI VOWEL SIGN AA - 098B 09C3 ; # BENGALI LETTER VOCALIC R, BENGALI VOWEL SIGN VOCALIC R - 098C 09E2 ; # BENGALI LETTER VOCALIC L, BENGALI VOWEL SIGN VOCALIC L - 0A05 0A3E ; # GURMUKHI LETTER A, GURMUKHI VOWEL SIGN AA - 0A72 0A3F ; # GURMUKHI IRI, GURMUKHI VOWEL SIGN I - 0A72 0A40 ; # GURMUKHI IRI, GURMUKHI VOWEL SIGN II - 0A73 0A41 ; # GURMUKHI URA, GURMUKHI VOWEL SIGN U - 0A73 0A42 ; # GURMUKHI URA, GURMUKHI VOWEL SIGN UU - 0A72 0A47 ; # GURMUKHI IRI, GURMUKHI VOWEL SIGN EE - 0A05 0A48 ; # GURMUKHI LETTER A, GURMUKHI VOWEL SIGN AI - 0A73 0A4B ; # GURMUKHI URA, GURMUKHI VOWEL SIGN OO - 0A05 0A4C ; # GURMUKHI LETTER A, GURMUKHI VOWEL SIGN AU - 0A85 0ABE ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN AA - 0A85 0AC5 ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN CANDRA E - 0A85 0AC7 ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN E - 0A85 0AC8 ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN AI - 0A85 0AC9 ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN CANDRA O - 0A85 0ACB ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN O - 0A85 0ABE 0AC5 ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN AA, GUJARATI VOWEL SIGN CANDRA E - 0A85 0ACC ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN AU - 0A85 0ABE 0AC8 ; # GUJARATI LETTER A, GUJARATI VOWEL SIGN AA, GUJARATI VOWEL SIGN AI - 0AC5 0ABE ; # GUJARATI VOWEL SIGN CANDRA E, GUJARATI VOWEL SIGN AA - 0B05 0B3E ; # ORIYA LETTER A, ORIYA VOWEL SIGN AA - 0B0F 0B57 ; # ORIYA LETTER E, ORIYA AU LENGTH MARK - 0B13 0B57 ; # ORIYA LETTER O, ORIYA AU LENGTH MARK - 0B85 0BC2 ; # TAMIL LETTER A, TAMIL VOWEL SIGN UU - 0C12 0C55 ; # TELUGU LETTER O, TELUGU LENGTH MARK - 0C12 0C4C ; # TELUGU LETTER O, TELUGU VOWEL SIGN AU - 0C3F 0C55 ; # TELUGU VOWEL SIGN I, TELUGU LENGTH MARK - 0C46 0C55 ; # TELUGU VOWEL SIGN E, TELUGU LENGTH MARK - 0C4A 0C55 ; # TELUGU VOWEL SIGN O, TELUGU LENGTH MARK - 0C89 0CBE ; # KANNADA LETTER U, KANNADA VOWEL SIGN AA - 0C92 0CCC ; # KANNADA LETTER O, KANNADA VOWEL SIGN AU - 0C8B 0CBE ; # KANNADA LETTER VOCALIC R, KANNADA VOWEL SIGN AA - 0D07 0D57 ; # MALAYALAM LETTER I, MALAYALAM AU LENGTH MARK - 0D09 0D57 ; # MALAYALAM LETTER U, MALAYALAM AU LENGTH MARK - 0D0E 0D46 ; # MALAYALAM LETTER E, MALAYALAM VOWEL SIGN E - 0D12 0D3E ; # MALAYALAM LETTER O, MALAYALAM VOWEL SIGN AA - 0D12 0D57 ; # MALAYALAM LETTER O, MALAYALAM AU LENGTH MARK - 0D85 0DCF ; # SINHALA LETTER AYANNA, SINHALA VOWEL SIGN AELA-PILLA - 0D85 0DD0 ; # SINHALA LETTER AYANNA, SINHALA VOWEL SIGN KETTI AEDA-PILLA - 0D85 0DD1 ; # SINHALA LETTER AYANNA, SINHALA VOWEL SIGN DIGA AEDA-PILLA - 0D8B 0DDF ; # SINHALA LETTER UYANNA, SINHALA VOWEL SIGN GAYANUKITTA - 0D8D 0DD8 ; # SINHALA LETTER IRUYANNA, SINHALA VOWEL SIGN GAETTA-PILLA - 0D8F 0DDF ; # SINHALA LETTER ILUYANNA, SINHALA VOWEL SIGN GAYANUKITTA - 0D91 0DCA ; # SINHALA LETTER EYANNA, SINHALA SIGN AL-LAKUNA - 0D91 0DD9 ; # SINHALA LETTER EYANNA, SINHALA VOWEL SIGN KOMBUVA - 0D91 0DDA ; # SINHALA LETTER EYANNA, SINHALA VOWEL SIGN DIGA KOMBUVA - 0D91 0DDC ; # SINHALA LETTER EYANNA, SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA - 0D91 0DDD ; # SINHALA LETTER EYANNA, SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA - 0D91 0DDE ; # SINHALA LETTER EYANNA, SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA - 0D94 0DDF ; # SINHALA LETTER OYANNA, SINHALA VOWEL SIGN GAYANUKITTA - 11005 11038 ; # BRAHMI LETTER A, BRAHMI VOWEL SIGN AA - 1100B 1103E ; # BRAHMI LETTER VOCALIC R, BRAHMI VOWEL SIGN VOCALIC R - 1100F 11042 ; # BRAHMI LETTER E, BRAHMI VOWEL SIGN E - 11680 116AD ; # TAKRI LETTER A, TAKRI VOWEL SIGN AA - 11686 116B2 ; # TAKRI LETTER E, TAKRI VOWEL SIGN E - 11680 116B4 ; # TAKRI LETTER A, TAKRI VOWEL SIGN O - 11680 116B5 ; # TAKRI LETTER A, TAKRI VOWEL SIGN AU - 11200 1122C ; # KHOJKI LETTER A, KHOJKI VOWEL SIGN AA - 11240 1122E ; # KHOJKI LETTER SHORT I, KHOJKI VOWEL SIGN II - 11206 1122C ; # KHOJKI LETTER O, KHOJKI VOWEL SIGN AA - 11200 11231 ; # KHOJKI LETTER A, KHOJKI VOWEL SIGN AI - 11200 11233 ; # KHOJKI LETTER A, KHOJKI VOWEL SIGN AU - 11200 1122C 11231 ; # KHOJKI LETTER A, KHOJKI VOWEL SIGN AA, KHOJKI VOWEL SIGN AI - 1122C 11230 ; # KHOJKI VOWEL SIGN AA, KHOJKI VOWEL SIGN E - 1122C 11231 ; # KHOJKI VOWEL SIGN AA, KHOJKI VOWEL SIGN AI - 112B0 112E0 ; # KHUDAWADI LETTER A, KHUDAWADI VOWEL SIGN AA - 112B0 112E5 ; # KHUDAWADI LETTER A, KHUDAWADI VOWEL SIGN E - 112B0 112E6 ; # KHUDAWADI LETTER A, KHUDAWADI VOWEL SIGN AI - 112B0 112E7 ; # KHUDAWADI LETTER A, KHUDAWADI VOWEL SIGN O - 112B0 112E8 ; # KHUDAWADI LETTER A, KHUDAWADI VOWEL SIGN AU - 11481 114B0 ; # TIRHUTA LETTER A, TIRHUTA VOWEL SIGN AA - 114AA 114B5 ; # TIRHUTA LETTER LA, TIRHUTA VOWEL SIGN VOCALIC R - 114AA 114B6 ; # TIRHUTA LETTER LA, TIRHUTA VOWEL SIGN VOCALIC RR - 1148B 114BA ; # TIRHUTA LETTER E, TIRHUTA VOWEL SIGN SHORT E - 1148D 114BA ; # TIRHUTA LETTER O, TIRHUTA VOWEL SIGN SHORT E - 11600 11639 ; # MODI LETTER A, MODI VOWEL SIGN E - 11600 1163A ; # MODI LETTER A, MODI VOWEL SIGN AI - 11601 11639 ; # MODI LETTER AA, MODI VOWEL SIGN E - 11601 1163A ; # MODI LETTER AA, MODI VOWEL SIGN AI diff --git a/thirdparty/harfbuzz/upstream/ms-use/IndicSyllabicCategory-Additional.txt b/thirdparty/harfbuzz/upstream/ms-use/IndicSyllabicCategory-Additional.txt deleted file mode 100644 index fcd22e63d..000000000 --- a/thirdparty/harfbuzz/upstream/ms-use/IndicSyllabicCategory-Additional.txt +++ /dev/null @@ -1,278 +0,0 @@ -# Override values For Indic_Syllabic_Category -# Not derivable -# Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 -# Updated for Unicode 10.0 by Andrew Glass 2017-07-25 -# Updated for Unicode 12.1 by Andrew Glass 2019-05-24 -# Updated for Unicode 13.0 by Andrew Glass 2020-07-28 -# Updated for Unicode 14.0 by Andrew Glass 2021-09-25 -# Updated for Unicode 15.0 by Andrew Glass 2022-09-16 -# Updated for Unicode 15.1 by Andrew Glass 2023-09-14 -# Updated for Unicode 16.0 by Andrew Glass 2024-09-11 - -# ================================================ -# OVERRIDES TO ASSIGNED VALUES -# ================================================ - -# Indic_Syllabic_Category=Bindu -193A ; Bindu # Mn LIMBU SIGN KEMPHRENG -AA29 ; Bindu # Mn CHAM VOWEL SIGN AA -10A0D ; Bindu # Mn KHAROSHTHI SIGN DOUBLE RING BELOW -113CE ; Bindu # Mn TULU-TIGALARI SIGN VIRAMA - -# ================================================ - -# Indic_Syllabic_Category=Consonant -19C1..19C7 ; Consonant # Lo [7] NEW TAI LUE LETTER FINAL V..NEW TAI LUE LETTER FINAL B # Reassigned to avoid clustering with a base consonant -25CC ; Consonant # So DOTTED CIRCLE #Reassigned to allow it to cluster as a generic base - -# ================================================ - -# Indic_Syllabic_Category=Consonant_Dead -0F7F ; Consonant_Dead # Mc TIBETAN SIGN RNAM BCAD # reassigned so that visarga can form an independent cluster, but see #19 - -# ================================================ - -# Indic_Syllabic_Category=Consonant_With_Stacker -11A3A ; Consonant_With_Stacker # Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA - -# ================================================ - -# Indic_Syllabic_Category=Consonant_Subjoined -11A3B..11A3E ; Consonant_Subjoined # Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA - -# ================================================ - -# Indic_Syllabic_Category=Consonant_Final_Modifier -1C36 ; Consonant_Final_Modifier # Mn LEPCHA SIGN RAN - -# ================================================ - -# Indic_Syllabic_Category=Gemination_Mark -11134 ; Gemination_Mark # Mc CHAKMA MAAYYAA - -# ================================================ - -# Indic_Syllabic_Category=Nukta -0F71 ; Nukta # Mn TIBETAN VOWEL SIGN AA # Reassigned to get this before an above vowel, but see #22 -113CF ; Nukta # Mc TULU-TIGALARI SIGN LOOPED VIRAMA - -# ================================================ - -# Indic_Syllabic_Category=Tone_Mark -1A7B..1A7C ; Tone_Mark # Mn [2] TAI THAM SIGN MAI SAM..TAI THAM SIGN KHUEN-LUE KARAN -1A7F ; Tone_Mark # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT - -# ================================================ - -# Indic_Syllabic_Category=Vowel_Independent -AAB1 ; Vowel_Independent # Lo TAI VIET VOWEL AA -AABA ; Vowel_Independent # Lo TAI VIET VOWEL UA -AABD ; Vowel_Independent # Lo TAI VIET VOWEL AN - -# ================================================ -# ================================================ -# VALUES NOT ASSIGNED IN Indic_Syllabic_Category -# ================================================ -# ================================================ - -# Indic_Syllabic_Category=Consonant -0800..0815 ; Consonant # Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF -0840..0858 ; Consonant # Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN -0F00..0F01 ; Consonant # Lo [2] TIBETAN SYLLABLE OM..TIBETAN MARK GTER YIG MGO TRUNCATED -0F04..0F06 ; Consonant # Po TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK CARET YIG MGO PHUR SHAD MA -1800 ; Consonant # Po MONGOLIAN BIRGA # Reassigned so that legacy Birga + MFVS sequences still work -1807 ; Consonant # Po MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER -180A ; Consonant # Po MONGOLIAN NIRUGU -1820..1842 ; Consonant # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI -1843 ; Consonant # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN -1844..1878 ; Consonant # Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS -2D30..2D67 ; Consonant # Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO -2D6F ; Consonant # Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK -10570..1057A ; Consonant # Lo [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA -1057C..1058A ; Consonant # Lo [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE -1058C..10592 ; Consonant # Lo [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE -10594..10595 ; Consonant # Lo [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE -10597..105A1 ; Consonant # Lo [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA -105A3..105B1 ; Consonant # Lo [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE -105B3..105B9 ; Consonant # Lo [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE -105BB..105BC ; Consonant # Lo [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE -10AC0..10AC7 ; Consonant # Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW -10AC9..10AE4 ; Consonant # Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW -10D00..10D23 ; Consonant # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA -10D4A..10D4F ; Consonant # Lo [6] GARAY VOWEL SIGN A..GARAY SUKUN -10D50..10D65 ; Consonant # Lu [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA -10D70..10D85 ; Consonant # Ll [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA -10D6F ; Consonant # Lm GARAY REDUPLICATION MARK -10E80..10EA9 ; Consonant # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET -10EB0..10EB1 ; Consonant # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE -10F30..10F45 ; Consonant # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN -10F70..10F81 ; Consonant # Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH -111DA ; Consonant # Lo SHARADA EKAM -16B00..16B2F ; Consonant # Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU -16F00..16F4A ; Consonant # Lo [75] MIAO LETTER PA..MIAO LETTER RTE -16FE4 ; Consonant # Mn KHITAN SMALL SCRIPT FILLER # Avoids Mn pushing this into VOWEL class -18B00..18CD5 ; Consonant # Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18CFF ; Consonant # Lo KHITAN SMALL SCRIPT CHARACTER-18CFF -1BC00..1BC6A ; Consonant # Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M -1BC70..1BC7C ; Consonant # Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK -1BC80..1BC88 ; Consonant # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL -1BC90..1BC99 ; Consonant # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW -1E100..1E12C ; Consonant # Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W -1E137..1E13D ; Consonant # Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER -1E14E ; Consonant # Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ -1E14F ; Consonant # So NYIAKENG PUACHUE HMONG CIRCLED CA -1E290..1E2AD ; Consonant # Lo [30] TOTO LETTER PA..TOTO LETTER A -1E2C0..1E2EB ; Consonant # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH -1E4D0..1E4EA ; Consonant # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL -1E4EB ; Consonant # Lm NAG MUNDARI SIGN OJOD -1E5D0..1E5ED ; Consonant # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG -1E5F0 ; Consonant # Lo OL ONAL SIGN HODDOND -1E900..1E921 ; Consonant # Lu [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA -1E922..1E943 ; Consonant # Ll [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -1E94B ; Consonant # Lm ADLAM NASALIZATION MARK - -# ================================================ - -# Indic_Syllabic_Category=Consonant_Placeholder -1880..1884 ; Consonant_Placeholder # Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA - -# ================================================ - -# Indic_Syllabic_Category=Gemination_Mark -10D27 ; Gemination_Mark # Mn HANIFI ROHINGYA SIGN TASSI - -# ================================================ - -# Indic_Syllabic_Category=Modifying_Letter -FE00..FE0F ; Modifying_Letter # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16# Need to treat them as isolated bases so they don't merge with a cluster in invalid scenarios -16F50 ; Modifying_Letter # Lo MIAO LETTER NASALIZATION - -# ================================================ - -# Indic_Syllabic_Category=Nukta -0859..085B ; Nukta # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -0F39 ; Nukta # Mn TIBETAN MARK TSA -PHRU # NOW IN UNICODE 10.0 -1885..1886 ; Nukta # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA -18A9 ; Nukta # Mn MONGOLIAN LETTER ALI GALI DAGALGA -10AE5..10AE6 ; Nukta # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW -16F4F ; Nukta # Mn MIAO SIGN CONSONANT MODIFIER BAR -1BC9D..1BC9E ; Nukta # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK -1E944..1E94A ; Nukta # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA -10F82..10F85 ; Nukta # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW - -# ================================================ - -# Indic_Syllabic_Category=Number -10D30..10D39 ; Number # Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE -10F51..10F54 ; Number # No [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED -16AC0..16AC9 ; Number # Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE -1E140..1E149 ; Number # Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE -1E2F0..1E2F9 ; Number # Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE -1E4F0..1E4F9 ; Number # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE -1E5F1..1E5FA ; Number # Nd [10] OL ONAL DIGIT ZERO..OL ONAL DIGIT NINE -1E950..1E959 ; Number # Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE - -# ================================================ - -# Indic_Syllabic_Category=Tone_Mark -07EB..07F3 ; Tone_Mark # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE -07FD ; Tone_Mark # Mn NKO DANTAYALAN -0F86..0F87 ; Tone_Mark # Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS -17CF ; Tone_Mark # Mn KHMER SIGN AHSDA -10D24..10D26 ; Tone_Mark # Mn [3] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TANA -10F46..10F50 ; Tone_Mark # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW -16B30..16B36 ; Tone_Mark # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM -16F8F..16F92 ; Tone_Mark # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW -1E130..1E136 ; Tone_Mark # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D -1E2AE ; Tone_Mark # Mn TOTO SIGN RISING TONE -1E2EC..1E2EF ; Tone_Mark # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI - -# ================================================ - -# Indic_Syllabic_Category=Virama -2D7F ; Virama # Mn TIFINAGH CONSONANT JOINER - -# ================================================ - -# Indic_Syllabic_Category=Vowel_Dependent -0B55 ; Vowel_Dependent # Mn ORIYA SIGN OVERLINE -10D69..10D6D ; Vowel_Dependent # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK -10EAB..10EAC ; Vowel_Dependent # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK -16F51..16F87 ; Vowel_Dependent # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI -1E4EC..1E4EF ; Vowel_Dependent # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH -1E5EE..1E5EF ; Vowel_Dependent # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR - -# ================================================ - -# Indic_Syllabic_Category=Cantillation_Mark - -1CF8..1CF9 ; Cantillation_Mark # Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE - -# ================================================ - -# Indic_Syllabic_Category=Symbol_Modifier -1B6B..1B73 ; Symbol_Modifier # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG - -# ================================================ -# ================================================ -# PROPERTIES NOT ASSIGNED IN Indic_Syllabic_Category -# ================================================ -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph -13000..1342F ; Hieroglyph # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D -1343C..1343F ; Hieroglyph # Cf [4] EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE..END WALLED ENCLOSURE -13441..13446 ; Hieroglyph # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..HIEROGLYPH WIDE LOST SIGN -13460..143FA ; Hieroglyph # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Joiner -13430..13436 ; Hieroglyph_Joiner # Cf [7] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH OVERLAY MIDDLE -13439..1343B ; Hieroglyph_Joiner # Cf [3] EGYPTIAN HIEROGLYPH INSERT AT MIDDLE..EGYPTIAN HIEROGLYPH INSERT AT BOTTOM - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Mark_Begin -005B ; Hieroglyph_Mark_Begin # Ps LEFT SQUARE BRACKET -007B ; Hieroglyph_Mark_Begin # Ps LEFT CURLY BRACKET -27E6 ; Hieroglyph_Mark_Begin # Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET -27E8 ; Hieroglyph_Mark_Begin # Ps MATHEMATICAL LEFT ANGLE BRACKET -2E22 ; Hieroglyph_Mark_Begin # Ps TOP LEFT HALF BRACKET -2E24 ; Hieroglyph_Mark_Begin # Ps BOTTOM LEFT HALF BRACKET - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Mark_End -005D ; Hieroglyph_Mark_End # Pe RIGHT SQUARE BRACKET -007D ; Hieroglyph_Mark_End # Pe RIGHT CURLY BRACKET -27E7 ; Hieroglyph_Mark_End # Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET -27E9 ; Hieroglyph_Mark_End # Pe MATHEMATICAL RIGHT ANGLE BRACKET -2E23 ; Hieroglyph_Mark_End # Pe TOP RIGHT HALF BRACKET -2E25 ; Hieroglyph_Mark_End # Pe BOTTOM RIGHT HALF BRACKET - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Segment_Begin -13437 ; Hieroglyph_Segment_Begin # Cf EGYPTIAN HIEROGLYPH BEGIN SEGMENT - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Segment_End -13438 ; Hieroglyph_Segment_End # Cf EGYPTIAN HIEROGLYPH END SEGMENT - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Mirror -13440 ; Hieroglyph_Mirror # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY - -# ================================================ - -# USE, Extended_Syllabic_Category=Hieroglyph_Modifier -13447..13455 ; Hieroglyph_Modifier # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED - -# ================================================ - -# eof - - diff --git a/thirdparty/harfbuzz/upstream/relative_to.py b/thirdparty/harfbuzz/upstream/relative_to.py deleted file mode 100755 index b660d2793..000000000 --- a/thirdparty/harfbuzz/upstream/relative_to.py +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env python3 - -import sys -from os import path - -print(path.relpath(sys.argv[1], sys.argv[2])) diff --git a/thirdparty/harfbuzz/upstream/sample.py b/thirdparty/harfbuzz/upstream/sample.py deleted file mode 100755 index 5d04e803f..000000000 --- a/thirdparty/harfbuzz/upstream/sample.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import array -import gi -gi.require_version('HarfBuzz', '0.0') -from gi.repository import HarfBuzz as hb -from gi.repository import GLib - -fontdata = open (sys.argv[1], 'rb').read () -text = sys.argv[2] -# Need to create GLib.Bytes explicitly until this bug is fixed: -# https://bugzilla.gnome.org/show_bug.cgi?id=729541 -blob = hb.glib_blob_create (GLib.Bytes.new (fontdata)) -face = hb.face_create (blob, 0) -del blob -font = hb.font_create (face) -upem = hb.face_get_upem (face) -del face -hb.font_set_scale (font, upem, upem) -#hb.ft_font_set_funcs (font) -hb.ot_font_set_funcs (font) - -buf = hb.buffer_create () -class Debugger (object): - def message (self, buf, font, msg, data, _x_what_is_this): - print (msg) - return True -debugger = Debugger () -hb.buffer_set_message_func (buf, debugger.message, 1, 0) - -## -## Add text to buffer -## -# -# See https://github.com/harfbuzz/harfbuzz/pull/271 -# -# If you do not care about cluster values reflecting Python -# string indices, then this is quickest way to add text to -# buffer: -# hb.buffer_add_utf8 (buf, text.encode('utf-8'), 0, -1) -# Otherwise, then following handles both narrow and wide -# Python builds (the first item in the array is BOM, so we skip it): -if sys.maxunicode == 0x10FFFF: - hb.buffer_add_utf32 (buf, array.array ('I', text.encode ('utf-32'))[1:], 0, -1) -else: - hb.buffer_add_utf16 (buf, array.array ('H', text.encode ('utf-16'))[1:], 0, -1) - - -hb.buffer_guess_segment_properties (buf) - -hb.shape (font, buf, []) -del font - -infos = hb.buffer_get_glyph_infos (buf) -positions = hb.buffer_get_glyph_positions (buf) - -for info, pos in zip (infos, positions): - gid = info.codepoint - cluster = info.cluster - x_advance = pos.x_advance - x_offset = pos.x_offset - y_offset = pos.y_offset - - print ("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset)) diff --git a/thirdparty/harfbuzz/upstream/test-algs.cc b/thirdparty/harfbuzz/upstream/test-algs.cc deleted file mode 100644 index 450a7c439..000000000 --- a/thirdparty/harfbuzz/upstream/test-algs.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright © 2019 Facebook, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Facebook Author(s): Behdad Esfahbod - */ - -#include "hb.hh" -#include "hb-algs.hh" -#include "hb-set.hh" - - -static char * -test_func (int a, char **b) -{ - return b ? b[a] : nullptr; -} - -struct A -{ - void a () {} -}; - -int -main (int argc, char **argv) -{ - int i = 1; - auto p = hb_pair (1, i); - - p.second = 2; - assert (i == 2); - - const int c = 3; - auto pc = hb_pair (1, c); - assert (pc.second == 3); - - auto q = p; - assert (&q != &p); - q.second = 4; - assert (i == 4); - - hb_invoke (test_func, 0, nullptr); - - A a; - hb_invoke (&A::a, a); - - assert (1 == hb_min (8, 1)); - assert (8 == hb_max (8, 1)); - - int x = 1, y = 2; - hb_min (x, 3); - hb_min (3, x); - hb_min (x, 4 + 3); - int &z = hb_min (x, y); - z = 3; - assert (x == 3); - - hb_pair_t xp = hb_pair_t (nullptr, 0); - xp = hb_pair_t (nullptr, 1); - xp = hb_pair_t (nullptr, 1); - - assert (3 == hb_partial (hb_min, 3) (4)); - assert (3 == hb_partial<1> (hb_min, 4) (3)); - - auto M0 = hb_partial<2> (hb_max, 0); - assert (M0 (-2) == 0); - assert (M0 (+2) == 2); - - assert (hb_add (2) (5) == 7); - assert (hb_add (5) (2) == 7); - - x = 1; - assert (++hb_inc (x) == 3); - assert (x == 3); - - hb_set_t set1 {1}; - hb_set_t set2 {2}; - - assert (hb_hash (set1) != hb_hash (set2)); - assert (hb_hash (set1) == hb_hash (hb_set_t {1})); - assert (hb_hash (set1) != hb_hash (hb_set_t {})); - assert (hb_hash (set1) != hb_hash (hb_set_t {2})); - assert (hb_hash (set2) == hb_hash (hb_set_t {2})); - - /* hb_hash, unlike std::hash, dereferences pointers. */ - assert (hb_hash (set1) == hb_hash (&set1)); - assert (hb_hash (set1) == hb_hash (hb::shared_ptr {hb_set_reference (&set1)})); - assert (hb_hash (set1) == hb_hash (hb::unique_ptr {hb_set_reference (&set1)})); - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-array.cc b/thirdparty/harfbuzz/upstream/test-array.cc deleted file mode 100644 index 28cd02364..000000000 --- a/thirdparty/harfbuzz/upstream/test-array.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Garret Rieger - */ - -#include "hb.hh" -#include "hb-array.hh" - -static void -test_reverse () -{ - int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - hb_array_t a (values, 9); - a.reverse(); - - int expected_values[] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; - hb_array_t expected (expected_values, 9); - assert (a == expected); -} - -static void -test_reverse_range () -{ - int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - hb_array_t a (values, 9); - a.reverse(2, 6); - - int expected_values[] = {1, 2, 6, 5, 4, 3, 7, 8, 9}; - hb_array_t expected (expected_values, 9); - assert (a == expected); -} - -static void -test_reverse_invalid () -{ - int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - hb_array_t a (values, 9); - - a.reverse(4, 3); - a.reverse(2, 3); - a.reverse(5, 5); - a.reverse(12, 15); - - int expected_values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - hb_array_t expected (expected_values, 9); - assert (a == expected); -} - -int -main (int argc, char **argv) -{ - /* The following fails on MSVC. */ - // assert (sizeof (hb_array_t) == sizeof (hb_sorted_array_t)); - - test_reverse (); - test_reverse_range (); - test_reverse_invalid (); -} diff --git a/thirdparty/harfbuzz/upstream/test-bimap.cc b/thirdparty/harfbuzz/upstream/test-bimap.cc deleted file mode 100644 index 1253d0c1d..000000000 --- a/thirdparty/harfbuzz/upstream/test-bimap.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright © 2019 Adobe, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Adobe Author(s): Michiharu Ariza - */ - -#include "hb.hh" -#include "hb-bimap.hh" - -int -main (int argc, char **argv) -{ - hb_bimap_t bm; - - assert (bm.is_empty () == true); - bm.set (1, 4); - bm.set (2, 5); - bm.set (3, 6); - assert (bm.get_population () == 3); - assert (bm.has (1) == true); - assert (bm.has (4) == false); - assert (bm[2] == 5); - assert (bm.backward (6) == 3); - bm.del (1); - assert (bm.has (1) == false); - assert (bm.has (3) == true); - bm.clear (); - assert (bm.get_population () == 0); - - hb_inc_bimap_t ibm; - - assert (ibm.add (13) == 0); - assert (ibm.add (8) == 1); - assert (ibm.add (10) == 2); - assert (ibm.add (8) == 1); - assert (ibm.add (7) == 3); - assert (ibm.get_population () == 4); - assert (ibm[7] == 3); - - ibm.sort (); - assert (ibm.get_population () == 4); - assert (ibm[7] == 0); - assert (ibm[13] == 3); - - ibm.identity (3); - assert (ibm.get_population () == 3); - assert (ibm[0] == 0); - assert (ibm[1] == 1); - assert (ibm[2] == 2); - assert (ibm.backward (0) == 0); - assert (ibm.backward (1) == 1); - assert (ibm.backward (2) == 2); - assert (ibm.has (4) == false); - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-buffer-serialize.cc b/thirdparty/harfbuzz/upstream/test-buffer-serialize.cc deleted file mode 100644 index aced1c8d1..000000000 --- a/thirdparty/harfbuzz/upstream/test-buffer-serialize.cc +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright © 2010,2011,2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" - -#include "hb.h" -#include "hb-ot.h" -#ifdef HAVE_FREETYPE -#include "hb-ft.h" -#endif - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif - -int -main (int argc, char **argv) -{ - bool ret = true; - -#ifndef HB_NO_BUFFER_SERIALIZE - - if (argc < 2) - argv[1] = (char *) "/dev/null"; - - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_blob_destroy (blob); - blob = nullptr; - - unsigned int upem = hb_face_get_upem (face); - hb_font_t *font = hb_font_create (face); - hb_face_destroy (face); - hb_font_set_scale (font, upem, upem); - - hb_buffer_t *buf; - buf = hb_buffer_create (); - - char line[BUFSIZ], out[BUFSIZ]; - while (fgets (line, sizeof(line), stdin)) - { - hb_buffer_clear_contents (buf); - - while (true) - { - const char *p = line; - if (!hb_buffer_deserialize_glyphs (buf, - p, -1, &p, - font, - HB_BUFFER_SERIALIZE_FORMAT_TEXT)) - { - ret = false; - break; - } - - if (*p == '\n') - break; - if (p == line) - { - ret = false; - break; - } - - unsigned len = strlen (p); - memmove (line, p, len); - if (!fgets (line + len, sizeof(line) - len, stdin)) - line[len] = '\0'; - } - - unsigned count = hb_buffer_get_length (buf); - for (unsigned offset = 0; offset < count;) - { - unsigned len; - offset += hb_buffer_serialize_glyphs (buf, offset, count, - out, sizeof (out), &len, - font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, - HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS); - fwrite (out, 1, len, stdout); - } - fputs ("\n", stdout); - } - - hb_buffer_destroy (buf); - - hb_font_destroy (font); - -#endif - - return !ret; -} diff --git a/thirdparty/harfbuzz/upstream/test-cff.cc b/thirdparty/harfbuzz/upstream/test-cff.cc deleted file mode 100644 index 38ddba3c4..000000000 --- a/thirdparty/harfbuzz/upstream/test-cff.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright © 2024 David Corbett - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "hb.hh" -#include "hb-ot-cff-common.hh" -#include "hb-subset-cff-common.hh" - -int -main (int argc, char **argv) -{ - /* Test encode_num_tp */ - { - CFF::str_buff_t buff; - CFF::str_encoder_t encoder (buff); - CFF::number_t number; - struct num_tp_test { - double input; - unsigned length; - unsigned char output[7]; - }; - struct num_tp_test num_tp_tests[] = { - { -9.399999999999999, 4, { 0x1E, 0xE9, 0xA4, 0xFF } }, // -9.4 - { 9.399999999999999999, 3, { 0x1E, 0x9A, 0x4F } }, // 9.4 - { 456.8, 4, { 0x1E, 0x45, 0x6A, 0x8F } }, // 456.8 - { 98765.37e2, 5, { 0x1E, 0x98, 0x76, 0x53, 0x7F } }, // 9876537 - { 1234567890.0, 7, { 0x1E, 0x12, 0x34, 0x56, 0x79, 0xB2, 0xFF } }, // 12345679E2 - { 9.876537e-4, 7, { 0x1E, 0x98, 0x76, 0x53, 0x7C, 0x10, 0xFF } }, // 9876537E-10 - { 9.876537e4, 6, { 0x1E, 0x98, 0x76, 0x5A, 0x37, 0xFF } }, // 98765.37 - { 1e8, 3, { 0x1E, 0x1B, 0x8F } }, // 1E8 - { 1e-5, 3, { 0x1E, 0x1C, 0x5F } }, // 1E-5 - { 1.2e8, 4, { 0x1E, 0x12, 0xB7, 0xFF } }, // 12E7 - { 1.2345e-5, 5, { 0x1E, 0x12, 0x34, 0x5C, 0x9F } }, // 12345E-9 - { 9.0987654e8, 6, { 0x1E, 0x90, 0x98, 0x76, 0x54, 0x0F } }, // 909876540 - { 0.1, 3, { 0x1E, 0xA1, 0xFF } }, // .1 - { -0.1, 3, { 0x1E, 0xEA, 0x1F } }, // -.1 - { 0.01, 3, { 0x1E, 0x1C, 0x2F } }, // 1E-2 - { -0.01, 4, { 0x1E, 0xE1, 0xC2, 0xFF } }, // -1E-2 - { 0.0123, 4, { 0x1E, 0x12, 0x3C, 0x4F } }, // 123E-4 - { -0.0123, 5, { 0x1E, 0xE1, 0x23, 0xC4, 0xFF } }, // -123E-4 - }; - for (size_t t = 0; t < sizeof num_tp_tests / sizeof num_tp_tests[0]; t++) - { - struct num_tp_test num_tp_test = num_tp_tests[t]; - number.set_real (num_tp_test.input); - encoder.encode_num_tp (number); - assert (buff.length == num_tp_test.length); - for (unsigned i = 0; i < buff.length; i++) - assert (buff[i] == num_tp_test.output[i]); - encoder.reset (); - } - } - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-gsub-get-alternates.cc b/thirdparty/harfbuzz/upstream/test-gsub-get-alternates.cc deleted file mode 100644 index 555440c59..000000000 --- a/thirdparty/harfbuzz/upstream/test-gsub-get-alternates.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright © 2010,2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include -#include - -#include -#include - -int -main (int argc, char **argv) -{ - if (argc != 3) { - fprintf (stderr, "usage: %s font-file text\n", argv[0]); - exit (1); - } - - /* Create the face */ - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_blob_destroy (blob); - blob = nullptr; - - hb_font_t *font = hb_font_create (face); - hb_buffer_t *buffer = hb_buffer_create (); - - hb_buffer_add_utf8 (buffer, argv[2], -1, 0, -1); - hb_buffer_guess_segment_properties (buffer); - hb_shape (font, buffer, NULL, 0); - - hb_tag_t features[] = {HB_TAG('a','a','l','t'), HB_TAG_NONE}; - hb_set_t *lookup_indexes = hb_set_create (); - hb_ot_layout_collect_lookups (face, - HB_OT_TAG_GSUB, - NULL, NULL, - features, - lookup_indexes); - printf ("lookups %u\n", hb_set_get_population (lookup_indexes)); - - unsigned count; - hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &count); - for (unsigned i = 0; i < count; i++) - { - unsigned alt_count = 0; - for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; - hb_set_next (lookup_indexes, &lookup_index);) - if ((alt_count = hb_ot_layout_lookup_get_glyph_alternates (face, - lookup_index, - info[i].codepoint, - 0, - NULL, - NULL))) - break; - printf ("glyph %u alt count %u\n", info[i].codepoint, alt_count); - } - - hb_set_destroy (lookup_indexes); - hb_buffer_destroy (buffer); - hb_font_destroy (font); - hb_face_destroy (face); - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-gsub-would-substitute.cc b/thirdparty/harfbuzz/upstream/test-gsub-would-substitute.cc deleted file mode 100644 index 87123030e..000000000 --- a/thirdparty/harfbuzz/upstream/test-gsub-would-substitute.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2010,2011 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" - -#include "hb.h" -#include "hb-ot.h" - -#ifdef HAVE_FREETYPE -#include "hb-ft.h" -#endif - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif - -int -main (int argc, char **argv) -{ - if (argc != 4 && argc != 5) { - fprintf (stderr, "usage: %s font-file lookup-index first-glyph [second-glyph]\n", argv[0]); - exit (1); - } - - /* Create the face */ - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_blob_destroy (blob); - blob = nullptr; - - hb_font_t *font = hb_font_create (face); -#ifdef HAVE_FREETYPE - hb_ft_font_set_funcs (font); -#endif - - unsigned int len = argc - 3; - hb_codepoint_t glyphs[2]; - if (!hb_font_glyph_from_string (font, argv[3], -1, &glyphs[0]) || - (argc > 4 && - !hb_font_glyph_from_string (font, argv[4], -1, &glyphs[1]))) - return 2; - return !hb_ot_layout_lookup_would_substitute (face, strtol (argv[2], nullptr, 0), glyphs, len, false); -} diff --git a/thirdparty/harfbuzz/upstream/test-item-varstore.cc b/thirdparty/harfbuzz/upstream/test-item-varstore.cc deleted file mode 100644 index bf0a10043..000000000 --- a/thirdparty/harfbuzz/upstream/test-item-varstore.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ -#include "hb-ot-var-common.hh" -#include "hb-ot-var-hvar-table.hh" -// HVAR table data from SourceSerif4Variable-Roman_subset.otf -const char hvar_data[] = "\x0\x1\x0\x0\x0\x0\x0\x14\x0\x0\x0\xc4\x0\x0\x0\x0\x0\x0\x0\x0\x0\x1\x0\x0\x0\x10\x0\x2\x0\x0\x0\x74\x0\x0\x0\x7a\x0\x2\x0\x8\xc0\x0\xc0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x40\x0\x40\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\xc0\x0\xc0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x40\x0\x40\x0\xc0\x0\xc0\x0\x0\x0\xc0\x0\xc0\x0\x0\x0\xc0\x0\xc0\x0\x0\x0\x0\x0\x40\x0\x40\x0\x0\x0\x40\x0\x40\x0\xc0\x0\xc0\x0\x0\x0\x0\x0\x40\x0\x40\x0\x0\x0\x40\x0\x40\x0\x0\x1\x0\x0\x0\x0\x0\x4\x0\x0\x0\x8\x0\x0\x0\x1\x0\x2\x0\x3\x0\x4\x0\x5\x0\x6\x0\x7\xf9\xf\x2f\xbf\xfb\xfb\x35\xf9\x4\x4\xf3\xb4\xf2\xfb\x2e\xf3\x4\x4\xe\xad\xfa\x1\x1a\x1\x15\x22\x59\xd6\xe3\xf6\x6\xf5\x0\x1\x0\x5\x0\x4\x7\x5\x6"; - -static void -test_item_variations () -{ - const OT::HVAR* hvar_table = reinterpret_cast (hvar_data); - - hb_tag_t axis_tag = HB_TAG ('w', 'g', 'h', 't'); - hb_map_t axis_idx_tag_map; - axis_idx_tag_map.set (0, axis_tag); - - axis_tag = HB_TAG ('o', 'p', 's', 'z'); - axis_idx_tag_map.set (1, axis_tag); - - OT::item_variations_t item_vars; - const OT::ItemVariationStore& src_var_store = hvar_table+(hvar_table->varStore); - bool result = item_vars.create_from_item_varstore (src_var_store, axis_idx_tag_map); - - assert (result); - - /* partial instancing wght=300:800 */ - hb_hashmap_t normalized_axes_location; - normalized_axes_location.set (axis_tag, Triple (-0.512817, 0.0, 0.7000120)); - - hb_hashmap_t axes_triple_distances; - axes_triple_distances.set (axis_tag, TripleDistances (200.0, 500.0)); - - result = item_vars.instantiate_tuple_vars (normalized_axes_location, axes_triple_distances); - assert (result); - result = item_vars.as_item_varstore (false); - assert (result); - assert (item_vars.get_region_list().length == 8); -} - -int -main (int argc, char **argv) -{ - test_item_variations (); -} diff --git a/thirdparty/harfbuzz/upstream/test-iter.cc b/thirdparty/harfbuzz/upstream/test-iter.cc deleted file mode 100644 index bb966d4c9..000000000 --- a/thirdparty/harfbuzz/upstream/test-iter.cc +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright © 2018 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" -#include "hb-iter.hh" - -#include "hb-array.hh" -#include "hb-set.hh" -#include "hb-ot-layout-common.hh" - -template -struct array_iter_t : hb_iter_with_fallback_t, T&> -{ - array_iter_t (hb_array_t arr_) : arr (arr_) {} - - typedef T& __item_t__; - static constexpr bool is_random_access_iterator = true; - T& __item_at__ (unsigned i) const { return arr[i]; } - void __forward__ (unsigned n) { arr += n; } - void __rewind__ (unsigned n) { arr -= n; } - unsigned __len__ () const { return arr.length; } - bool operator != (const array_iter_t& o) { return arr != o.arr; } - - private: - hb_array_t arr; -}; - -template -struct some_array_t -{ - some_array_t (hb_array_t arr_) : arr (arr_) {} - - typedef array_iter_t iter_t; - array_iter_t iter () { return array_iter_t (arr); } - operator array_iter_t () { return iter (); } - operator hb_iter_t> () { return iter (); } - - private: - hb_array_t arr; -}; - - -template -static void -test_iterator_non_default_constructable (Iter it) -{ - /* Iterate over a copy of it. */ - for (auto c = it.iter (); c; c++) - *c; - - /* Same. */ - for (auto c = +it; c; c++) - *c; - - /* Range-based for over a copy. */ - for (auto _ : +it) - (void) _; - - it += it.len (); - it = it + 10; - it = 10 + it; - - assert (*it == it[0]); - - static_assert (true || it.is_random_access_iterator, ""); - static_assert (true || it.is_sorted_iterator, ""); -} - -template -static void -test_iterator (Iter it) -{ - Iter default_constructed; - assert (!default_constructed); - - test_iterator_non_default_constructable (it); -} - -template -static void -test_iterable (const Iterable &lst = Null (Iterable)) -{ - for (auto _ : lst) - (void) _; - - // Test that can take iterator from. - test_iterator (lst.iter ()); -} - -template -static void check_sequential (It it) -{ - int i = 1; - for (int v : +it) { - assert (v == i++); - } -} - -static void test_concat () -{ - hb_vector_t a = {1, 2, 3}; - hb_vector_t b = {4, 5}; - - hb_vector_t c = {}; - hb_vector_t d = {1, 2, 3, 4, 5}; - - auto it1 = hb_concat (a, b); - assert (it1.len () == 5); - assert (it1.is_random_access_iterator); - auto it2 = hb_concat (c, d); - assert (it2.len () == 5); - auto it3 = hb_concat (d, c); - assert (it3.len () == 5); - for (int i = 0; i < 5; i++) { - assert(it1[i] == i + 1); - assert(it2[i] == i + 1); - assert(it3[i] == i + 1); - } - - check_sequential (it1); - check_sequential (it2); - check_sequential (it3); - - auto it4 = +it1; - it4 += 0; - assert (*it4 == 1); - - it4 += 2; - assert (*it4 == 3); - assert (it4); - assert (it4.len () == 3); - - it4 += 2; - assert (*it4 == 5); - assert (it4); - assert (it4.len () == 1); - - it4++; - assert (!it4); - assert (it4.len () == 0); - - auto it5 = +it1; - it5 += 3; - assert (*it5 == 4); - - hb_set_t s_a = {1, 2, 3}; - hb_set_t s_b = {4, 5}; - auto it6 = hb_concat (s_a, s_b); - assert (!it6.is_random_access_iterator); - check_sequential (it6); - assert (it6.len () == 5); - - it6 += 0; - assert (*it6 == 1); - - it6 += 3; - assert (*it6 == 4); - assert (it6); - assert (it6.len () == 2); -} - -int -main (int argc, char **argv) -{ - const int src[10] = {}; - int dst[20]; - hb_vector_t v; - - array_iter_t s (src); /* Implicit conversion from static array. */ - array_iter_t s2 (v); /* Implicit conversion from vector. */ - array_iter_t t (dst); - - static_assert (array_iter_t::is_random_access_iterator, ""); - - some_array_t a (src); - - s2 = s; - - hb_iter (src); - hb_iter (src, 2); - - hb_fill (t, 42); - hb_copy (s, t); - hb_copy (a.iter (), t); - - test_iterable (v); - hb_set_t st; - st << 1 << 15 << 43; - test_iterable (st); - hb_sorted_array_t sa; - (void) static_cast, hb_sorted_array_t::item_t>&> (sa); - (void) static_cast, hb_sorted_array_t::__item_t__>&> (sa); - (void) static_cast, int&>&>(sa); - (void) static_cast>&>(sa); - (void) static_cast, int&>&> (sa); - test_iterable (sa); - - test_iterable> (); - test_iterable> (); - test_iterable> (); - test_iterable (); - test_iterable> (); - - test_iterator (hb_zip (st, v)); - test_iterator_non_default_constructable (hb_enumerate (st)); - test_iterator_non_default_constructable (hb_enumerate (st, -5)); - test_iterator_non_default_constructable (hb_enumerate (hb_iter (st))); - test_iterator_non_default_constructable (hb_enumerate (hb_iter (st) + 1)); - test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); - test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_lidentity)); - - assert (true == hb_all (st)); - assert (false == hb_all (st, 42u)); - assert (true == hb_any (st)); - assert (false == hb_any (st, 14u)); - assert (true == hb_any (st, 14u, [] (unsigned _) { return _ - 1u; })); - assert (true == hb_any (st, [] (unsigned _) { return _ == 15u; })); - assert (true == hb_any (st, 15u)); - assert (false == hb_none (st)); - assert (false == hb_none (st, 15u)); - assert (true == hb_none (st, 17u)); - - hb_array_t> pa; - pa->as_array (); - - hb_map_t m; - - hb_iter (st); - hb_iter (&st); - - + hb_iter (src) - | hb_map (m) - | hb_map (&m) - | hb_filter () - | hb_filter (st) - | hb_filter (&st) - | hb_filter (hb_bool) - | hb_filter (hb_bool, hb_identity) - | hb_sink (st) - ; - - + hb_iter (src) - | hb_sink (hb_array (dst)) - ; - - + hb_iter (src) - | hb_apply (&st) - ; - - + hb_iter (src) - | hb_map ([] (int i) { return 1; }) - | hb_reduce ([=] (int acc, int value) { return acc; }, 2) - ; - - using map_pair_t = hb_item_type; - + hb_iter (m) - | hb_map ([] (map_pair_t p) { return p.first * p.second; }) - ; - - m.keys (); - using map_key_t = decltype (*m.keys()); - + hb_iter (m.keys ()) - | hb_filter ([] (map_key_t k) { return k < 42; }) - | hb_drain - ; - - m.values (); - using map_value_t = decltype (*m.values()); - + hb_iter (m.values ()) - | hb_filter ([] (map_value_t k) { return k < 42; }) - | hb_drain - ; - - unsigned int temp1 = 10; - unsigned int temp2 = 0; - hb_map_t *result = - + hb_iter (src) - | hb_map ([&] (int i) -> hb_set_t * - { - hb_set_t *set = hb_set_create (); - for (unsigned int i = 0; i < temp1; ++i) - hb_set_add (set, i); - temp1++; - return set; - }) - | hb_reduce ([&] (hb_map_t *acc, hb_set_t *value) -> hb_map_t * - { - hb_map_set (acc, temp2++, hb_set_get_population (value)); - /* This is not a memory managed language, take care! */ - hb_set_destroy (value); - return acc; - }, hb_map_create ()) - ; - /* The result should be something like 0->10, 1->11, ..., 9->19 */ - assert (hb_map_get (result, 9) == 19); - hb_map_destroy (result); - - /* Like above, but passing hb_set_t instead of hb_set_t * */ - temp1 = 10; - temp2 = 0; - result = - + hb_iter (src) - | hb_map ([&] (int i) -> hb_set_t - { - hb_set_t set; - for (unsigned int i = 0; i < temp1; ++i) - hb_set_add (&set, i); - temp1++; - return set; - }) - | hb_reduce ([&] (hb_map_t *acc, hb_set_t value) -> hb_map_t * - { - hb_map_set (acc, temp2++, hb_set_get_population (&value)); - return acc; - }, hb_map_create ()) - ; - /* The result should be something like 0->10, 1->11, ..., 9->19 */ - assert (hb_map_get (result, 9) == 19); - hb_map_destroy (result); - - unsigned int temp3 = 0; - + hb_iter(src) - | hb_map([&] (int i) { return ++temp3; }) - | hb_reduce([&] (float acc, int value) { return acc + value; }, 0) - ; - - + hb_iter (src) - | hb_drain - ; - - t << 1; - long vl; - s >> vl; - - hb_iota (); - hb_iota (3); - hb_iota (3, 2); - assert ((&vl) + 1 == *++hb_iota (&vl, hb_inc)); - hb_range (); - hb_repeat (7u); - hb_repeat (nullptr); - hb_repeat (vl) | hb_chop (3); - assert (hb_len (hb_range (10) | hb_take (3)) == 3); - assert (hb_range (9).len () == 9); - assert (hb_range (2, 9).len () == 7); - assert (hb_range (2, 9, 3).len () == 3); - assert (hb_range (2, 8, 3).len () == 2); - assert (hb_range (2, 7, 3).len () == 2); - assert (hb_range (-2, -9, -3).len () == 3); - assert (hb_range (-2, -8, -3).len () == 2); - assert (hb_range (-2, -7, -3).len () == 2); - - test_concat (); - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-map.cc b/thirdparty/harfbuzz/upstream/test-map.cc deleted file mode 100644 index cb722eb92..000000000 --- a/thirdparty/harfbuzz/upstream/test-map.cc +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright © 2021 Behdad Esfahbod - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "hb.hh" -#include "hb-map.hh" -#include "hb-set.hh" -#include - -int -main (int argc, char **argv) -{ - - /* Test copy constructor. */ - { - hb_map_t v1; - v1.set (1, 2); - hb_map_t v2 {v1}; - assert (v1.get_population () == 1); - assert (v2.get_population () == 1); - assert (v1[1] == 2); - assert (v2[1] == 2); - } - - /* Test copy assignment. */ - { - hb_map_t v1; - v1.set (1, 2); - hb_map_t v2 = v1; - assert (v1.get_population () == 1); - assert (v2.get_population () == 1); - assert (v1[1] == 2); - assert (v2[1] == 2); - } - - /* Test move constructor. */ - { - hb_map_t s {}; - s.set (1, 2); - hb_map_t v (std::move (s)); - assert (s.get_population () == 0); - assert (v.get_population () == 1); - } - - /* Test move assignment. */ - { - hb_map_t s {}; - s.set (1, 2); - hb_map_t v; - v = std::move (s); - assert (s.get_population () == 0); - assert (v.get_population () == 1); - } - - /* Test initializing from iterable. */ - { - hb_map_t s; - - s.set (1, 2); - s.set (3, 4); - - hb_vector_t v (s); - hb_map_t v0 (v); - hb_map_t v1 (s); - hb_map_t v2 (std::move (s)); - - assert (s.get_population () == 0); - assert (v0.get_population () == 2); - assert (v1.get_population () == 2); - assert (v2.get_population () == 2); - } - - /* Test call fini() twice. */ - { - hb_map_t s; - for (int i = 0; i < 16; i++) - s.set(i, i+1); - s.fini(); - } - - /* Test initializing from iterator. */ - { - hb_map_t s; - - s.set (1, 2); - s.set (3, 4); - - hb_map_t v (hb_iter (s)); - - assert (v.get_population () == 2); - } - - /* Test initializing from initializer list and swapping. */ - { - using pair_t = hb_codepoint_pair_t; - hb_map_t v1 {pair_t{1,2}, pair_t{4,5}}; - hb_map_t v2 {pair_t{3,4}}; - hb_swap (v1, v2); - assert (v1.get_population () == 1); - assert (v2.get_population () == 2); - } - - /* Test class key / value types. */ - { - hb_hashmap_t m1; - hb_hashmap_t m2; - hb_hashmap_t m3; - assert (m1.get_population () == 0); - assert (m2.get_population () == 0); - assert (m3.get_population () == 0); - } - - { - hb_hashmap_t m0; - hb_hashmap_t m1; - hb_hashmap_t m2; - hb_hashmap_t m3; - - std::string s; - for (unsigned i = 1; i < 1000; i++) - { - s += "x"; - m0.set (i, i); - m1.set (s, i); - m2.set (i, s); - m3.set (s, s); - } - } - - /* Test hashing maps. */ - { - using pair = hb_codepoint_pair_t; - - hb_hashmap_t m1; - - m1.set (hb_map_t (), hb_map_t {}); - m1.set (hb_map_t (), hb_map_t {pair (1u, 2u)}); - m1.set (hb_map_t {pair (1u, 2u)}, hb_map_t {pair (2u, 3u)}); - - assert (m1.get (hb_map_t ()) == hb_map_t {pair (1u, 2u)}); - assert (m1.get (hb_map_t {pair (1u, 2u)}) == hb_map_t {pair (2u, 3u)}); - } - - /* Test hashing sets. */ - { - hb_hashmap_t m1; - - m1.set (hb_set_t (), hb_set_t ()); - m1.set (hb_set_t (), hb_set_t {1}); - m1.set (hb_set_t {1, 1000}, hb_set_t {2}); - - assert (m1.get (hb_set_t ()) == hb_set_t {1}); - assert (m1.get (hb_set_t {1000, 1}) == hb_set_t {2}); - } - - /* Test hashing vectors. */ - { - using vector_t = hb_vector_t; - - hb_hashmap_t m1; - - m1.set (vector_t (), vector_t {1}); - m1.set (vector_t {1}, vector_t {2}); - - m1 << hb_pair_t {vector_t {2}, vector_t ()}; - - assert (m1.get (vector_t ()) == vector_t {1}); - assert (m1.get (vector_t {1}) == vector_t {2}); - } - - /* Test moving values */ - { - using vector_t = hb_vector_t; - - hb_hashmap_t m1; - vector_t v {3}; - assert (v.length == 1); - m1 << hb_pair_t {vector_t {3}, v}; - assert (v.length == 1); - m1 << hb_pair_t {vector_t {4}, std::move (v)}; - assert (v.length == 0); - m1 << hb_pair_t {vector_t {4}, vector_t {5}}; - m1 << hb_pair_t {vector_t {4}, vector_t {5}}; - - hb_hashmap_t m2; - vector_t v2 {3}; - m2.set (vector_t {4}, v2); - assert (v2.length == 1); - m2.set (vector_t {5}, std::move (v2)); - assert (v2.length == 0); - } - - /* Test hb::shared_ptr. */ - { - hb_hashmap_t, hb::shared_ptr> m; - - m.set (hb::shared_ptr (hb_set_get_empty ()), - hb::shared_ptr (hb_set_get_empty ())); - m.get (hb::shared_ptr (hb_set_get_empty ())); - m.iter (); - m.keys (); - m.values (); - m.iter_ref (); - m.keys_ref (); - m.values_ref (); - } - /* Test hb::unique_ptr. */ - { - hb_hashmap_t, hb::unique_ptr> m; - - m.set (hb::unique_ptr (hb_set_get_empty ()), - hb::unique_ptr (hb_set_get_empty ())); - m.get (hb::unique_ptr (hb_set_get_empty ())); - hb::unique_ptr *v; - m.has (hb::unique_ptr (hb_set_get_empty ()), &v); - m.iter_ref (); - m.keys_ref (); - m.values_ref (); - } - /* Test hashmap with complex shared_ptrs as keys. */ - { - hb_hashmap_t, unsigned> m; - - hb_map_t *m1 = hb_map_create (); - hb_map_t *m2 = hb_map_create (); - m1->set (1,3); - m2->set (1,3); - - hb::shared_ptr p1 {m1}; - hb::shared_ptr p2 {m2}; - m.set (p1,1); - - assert (m.has (p2)); - - m1->set (2,4); - assert (!m.has (p2)); - } - /* Test value type with hb_bytes_t. */ - { - hb_hashmap_t m; - char c_str[] = "Test"; - hb_bytes_t bytes (c_str); - - m.set (1, bytes); - assert (m.has (1)); - assert (m.get (1) == hb_bytes_t {"Test"}); - } - /* Test operators. */ - { - hb_map_t m1, m2, m3; - m1.set (1, 2); - m1.set (2, 4); - m2.set (1, 2); - m2.set (2, 4); - m3.set (1, 3); - m3.set (3, 5); - - assert (m1 == m2); - assert (m1 != m3); - assert (!(m2 == m3)); - - m2 = m3; - assert (m2.has (1)); - assert (!m2.has (2)); - assert (m2.has (3)); - - assert (m3.has (3)); - } - /* Test reset. */ - { - hb_hashmap_t m; - m.set (1, hb_set_t {1, 2, 3}); - m.reset (); - } - /* Test iteration. */ - { - hb_map_t m; - m.set (1, 1); - m.set (4, 3); - m.set (5, 5); - m.set (2, 1); - m.set (3, 2); - m.set (6, 8); - - hb_codepoint_t k; - hb_codepoint_t v; - unsigned pop = 0; - for (signed i = -1; - m.next (&i, &k, &v);) - { - pop++; - if (k == 1) assert (v == 1); - else if (k == 2) assert (v == 1); - else if (k == 3) assert (v == 2); - else if (k == 4) assert (v == 3); - else if (k == 5) assert (v == 5); - else if (k == 6) assert (v == 8); - else assert (false); - } - assert (pop == m.get_population ()); - } - /* Test update */ - { - hb_map_t m1, m2; - m1.set (1, 2); - m1.set (2, 4); - m2.set (1, 3); - - m1.update (m2); - assert (m1.get_population () == 2); - assert (m1[1] == 3); - assert (m1[2] == 4); - } - /* Test keys / values */ - { - hb_map_t m; - m.set (1, 1); - m.set (4, 3); - m.set (5, 5); - m.set (2, 1); - m.set (3, 2); - m.set (6, 8); - - hb_set_t keys; - hb_set_t values; - - hb_copy (m.keys (), keys); - hb_copy (m.values (), values); - - assert (keys.is_equal (hb_set_t ({1, 2, 3, 4, 5, 6}))); - assert (values.is_equal (hb_set_t ({1, 1, 2, 3, 5, 8}))); - - assert (keys.is_equal (hb_set_t (m.keys ()))); - assert (values.is_equal (hb_set_t (m.values ()))); - } - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-number.cc b/thirdparty/harfbuzz/upstream/test-number.cc deleted file mode 100644 index 57835288c..000000000 --- a/thirdparty/harfbuzz/upstream/test-number.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright © 2019 Ebrahim Byagowi - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ - -#include "hb.hh" -#include "hb-number.hh" - - -int -main (int argc, char **argv) -{ - { - const char str[] = "123"; - const char *pp = str; - const char *end = str + 3; - - int pv; - assert (hb_parse_int (&pp, end, &pv)); - assert (pv == 123); - assert (pp - str == 3); - assert (end - pp == 0); - assert (!*end); - } - - { - const char str[] = "123"; - const char *pp = str; - const char *end = str + strlen (str); - - unsigned int pv; - assert (hb_parse_uint (&pp, end, &pv)); - assert (pv == 123); - assert (pp - str == 3); - assert (end - pp == 0); - assert (!*end); - } - - { - const char str[] = "12F"; - const char *pp = str; - const char *end = str + 3; - - unsigned int pv; - assert (hb_parse_uint (&pp, end, &pv, true, 16)); - assert (pv == 0x12F); - assert (pp - str == 3); - assert (end - pp == 0); - assert (!*end); - } - - { - const char str[] = "12Fq"; - const char *pp = str; - const char *end = str + 4; - - unsigned int pv; - assert (!hb_parse_uint (&pp, end, &pv, true, 16)); - assert (hb_parse_uint (&pp, end, &pv, false, 16)); - assert (pv == 0x12F); - assert (pp - str == 3); - assert (end - pp == 1); - assert (!*end); - } - - { - const char str[] = "-123"; - const char *pp = str; - const char *end = str + 4; - - int pv; - assert (hb_parse_int (&pp, end, &pv)); - assert (pv == -123); - assert (pp - str == 4); - assert (end - pp == 0); - assert (!*end); - } - - { - const char str[] = "123"; - const char *pp = str; - assert (ARRAY_LENGTH (str) == 4); - const char *end = str + ARRAY_LENGTH (str); - - unsigned int pv; - assert (hb_parse_uint (&pp, end, &pv)); - assert (pv == 123); - assert (pp - str == 3); - assert (end - pp == 1); - } - - { - const char str[] = "123\0"; - const char *pp = str; - assert (ARRAY_LENGTH (str) == 5); - const char *end = str + ARRAY_LENGTH (str); - - unsigned int pv; - assert (hb_parse_uint (&pp, end, &pv)); - assert (pv == 123); - assert (pp - str == 3); - assert (end - pp == 2); - } - - { - const char str[] = "123V"; - const char *pp = str; - assert (ARRAY_LENGTH (str) == 5); - const char *end = str + ARRAY_LENGTH (str); - - unsigned int pv; - assert (hb_parse_uint (&pp, end, &pv)); - assert (pv == 123); - assert (pp - str == 3); - assert (end - pp == 2); - } - - { - const char str[] = ".123"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str); - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == 123); - assert (pp - str == 4); - assert (end - pp == 1); - } - - { - const char str[] = "0.123"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str) - 1; - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == 123); - assert (pp - str == 5); - assert (end - pp == 0); - } - - { - const char str[] = "0.123e0"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str) - 1; - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == 123); - assert (pp - str == 7); - assert (end - pp == 0); - } - - { - const char str[] = "123e-3"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str) - 1; - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == 123); - assert (pp - str == 6); - assert (end - pp == 0); - } - - { - const char str[] = ".000123e+3"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str) - 1; - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == 123); - assert (pp - str == 10); - assert (end - pp == 0); - } - - { - const char str[] = "-.000000123e6"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str) - 1; - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == -123); - assert (pp - str == 13); - assert (end - pp == 0); - - } - - { - const char str[] = "-1.23E-1"; - const char *pp = str; - const char *end = str + ARRAY_LENGTH (str) - 1; - - double pv; - assert (hb_parse_double (&pp, end, &pv)); - assert ((int) roundf (pv * 1000.) == -123); - assert (pp - str == 8); - assert (end - pp == 0); - } - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-ot-glyphname.cc b/thirdparty/harfbuzz/upstream/test-ot-glyphname.cc deleted file mode 100644 index ec6e149a5..000000000 --- a/thirdparty/harfbuzz/upstream/test-ot-glyphname.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright © 2019 Adobe, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Adobe Author(s): Michiharu Ariza - */ - -#include "hb.hh" -#include "hb-ot.h" - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif - -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file\n", argv[0]); - exit (1); - } - - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_font_t *font = hb_font_create (face); - hb_blob_destroy (blob); - blob = nullptr; - - - const unsigned int num_glyphs = hb_face_get_glyph_count (face); - int result = 1; - - for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) - { - char buf[64]; - unsigned int buf_size = sizeof (buf); - if (hb_font_get_glyph_name (font, gid, buf, buf_size)) - { - hb_codepoint_t gid_inv; - if (hb_font_get_glyph_from_name(font, buf, strlen (buf), &gid_inv)) - { - if (gid == gid_inv) - { - printf ("%u <-> %s\n", gid, buf); - } - else - { - printf ("%u -> %s -> %u\n", gid, buf, gid_inv); - result = 0; - } - } - else - { - printf ("%u -> %s -> ?\n", gid, buf); - result = 0; - } - } - else - { - printf ("%u -> ?\n", gid); - result = 0; - } - } - - hb_font_destroy (font); - hb_face_destroy (face); - - return !result; -} diff --git a/thirdparty/harfbuzz/upstream/test-ot-meta.cc b/thirdparty/harfbuzz/upstream/test-ot-meta.cc deleted file mode 100644 index 6daacc47d..000000000 --- a/thirdparty/harfbuzz/upstream/test-ot-meta.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright © 2019 Ebrahim Byagowi - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "hb.hh" -#include "hb-ot.h" - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif - -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file\n", argv[0]); - exit (1); - } - - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_blob_destroy (blob); - blob = nullptr; - - unsigned int count = 0; - -#ifndef HB_NO_META - count = hb_ot_meta_get_entry_tags (face, 0, nullptr, nullptr); - - hb_ot_meta_tag_t *tags = (hb_ot_meta_tag_t *) - malloc (sizeof (hb_ot_meta_tag_t) * count); - hb_ot_meta_get_entry_tags (face, 0, &count, tags); - for (unsigned i = 0; i < count; ++i) - { - hb_blob_t *entry = hb_ot_meta_reference_entry (face, tags[i]); - printf ("%c%c%c%c, size: %u: %.*s\n", - HB_UNTAG (tags[i]), hb_blob_get_length (entry), - (int) hb_blob_get_length (entry), hb_blob_get_data (entry, nullptr)); - hb_blob_destroy (entry); - } - free (tags); -#endif - - hb_face_destroy (face); - - return !count; -} diff --git a/thirdparty/harfbuzz/upstream/test-ot-name.cc b/thirdparty/harfbuzz/upstream/test-ot-name.cc deleted file mode 100644 index bfa654a7c..000000000 --- a/thirdparty/harfbuzz/upstream/test-ot-name.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright © 2018 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb.hh" -#include "hb-ot.h" - -#ifdef HB_NO_OPEN -#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty () -#endif - -int -main (int argc, char **argv) -{ - if (argc != 2) { - fprintf (stderr, "usage: %s font-file\n", argv[0]); - exit (1); - } - - hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]); - assert (blob); - hb_face_t *face = hb_face_create (blob, 0 /* first face */); - hb_blob_destroy (blob); - blob = nullptr; - - unsigned int count = 0; - -#ifndef HB_NO_NAME - const hb_ot_name_entry_t *entries = hb_ot_name_list_names (face, &count); - - for (unsigned int i = 0; i < count; i++) - { - printf ("%u %s ", - entries[i].name_id, - hb_language_to_string (entries[i].language)); - - char buf[64]; - unsigned int buf_size = sizeof (buf); - hb_ot_name_get_utf8 (face, - entries[i].name_id, - entries[i].language, - &buf_size, - buf); - - printf ("%s\n", buf); - } -#endif - - hb_face_destroy (face); - - return count ? 0 : 1; -} diff --git a/thirdparty/harfbuzz/upstream/test-priority-queue.cc b/thirdparty/harfbuzz/upstream/test-priority-queue.cc deleted file mode 100644 index 67ee5ee4c..000000000 --- a/thirdparty/harfbuzz/upstream/test-priority-queue.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Garret Rieger - */ - -#include "hb.hh" -#include "hb-priority-queue.hh" - -static void -test_insert () -{ - hb_priority_queue_t queue; - assert (queue.is_empty ()); - - queue.insert (10, 0); - assert (!queue.is_empty ()); - assert (queue.minimum () == hb_pair (10, 0)); - - queue.insert (20, 1); - assert (queue.minimum () == hb_pair (10, 0)); - - queue.insert (5, 2); - assert (queue.minimum () == hb_pair (5, 2)); - - queue.insert (15, 3); - assert (queue.minimum () == hb_pair (5, 2)); - - queue.insert (1, 4); - assert (queue.minimum () == hb_pair (1, 4)); -} - -static void -test_extract () -{ - hb_priority_queue_t queue; - queue.insert (0, 0); - queue.insert (60, 6); - queue.insert (30, 3); - queue.insert (40 ,4); - queue.insert (20, 2); - queue.insert (50, 5); - queue.insert (70, 7); - queue.insert (10, 1); - - for (int i = 0; i < 8; i++) - { - assert (!queue.is_empty ()); - assert (queue.minimum () == hb_pair (i * 10, i)); - assert (queue.pop_minimum () == hb_pair (i * 10, i)); - } - - assert (queue.is_empty ()); -} - -int -main (int argc, char **argv) -{ - test_insert (); - test_extract (); -} diff --git a/thirdparty/harfbuzz/upstream/test-repacker.cc b/thirdparty/harfbuzz/upstream/test-repacker.cc deleted file mode 100644 index 7f89fbfa3..000000000 --- a/thirdparty/harfbuzz/upstream/test-repacker.cc +++ /dev/null @@ -1,2304 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Garret Rieger - */ - -#include - -#include "hb-repacker.hh" -#include "hb-open-type.hh" -#include "graph/serialize.hh" - -static void extend (const char* value, - unsigned len, - hb_serialize_context_t* c) -{ - char* obj = c->allocate_size (len); - hb_memcpy (obj, value, len); -} - -static void start_object(const char* tag, - unsigned len, - hb_serialize_context_t* c) -{ - c->push (); - extend (tag, len, c); -} - -static unsigned add_object(const char* tag, - unsigned len, - hb_serialize_context_t* c) -{ - start_object (tag, len, c); - return c->pop_pack (false); -} - - -static void add_offset (unsigned id, - hb_serialize_context_t* c) -{ - OT::Offset16* offset = c->start_embed (); - c->extend_min (offset); - c->add_link (*offset, id); -} - -static void add_24_offset (unsigned id, - hb_serialize_context_t* c) -{ - OT::Offset24* offset = c->start_embed (); - c->extend_min (offset); - c->add_link (*offset, id); -} - -static void add_wide_offset (unsigned id, - hb_serialize_context_t* c) -{ - OT::Offset32* offset = c->start_embed (); - c->extend_min (offset); - c->add_link (*offset, id); -} - -static void add_gsubgpos_header (unsigned lookup_list, - hb_serialize_context_t* c) -{ - char header[] = { - 0, 1, // major - 0, 0, // minor - 0, 0, // script list - 0, 0, // feature list - }; - - start_object (header, 8, c); - add_offset (lookup_list, c); - c->pop_pack (false); -} - -static unsigned add_lookup_list (const unsigned* lookups, - char count, - hb_serialize_context_t* c) -{ - char lookup_count[] = {0, count}; - start_object ((char *) &lookup_count, 2, c); - - for (int i = 0; i < count; i++) - add_offset (lookups[i], c); - - return c->pop_pack (false); -} - -static void start_lookup (int8_t type, - int8_t num_subtables, - hb_serialize_context_t* c) -{ - char lookup[] = { - 0, (char)type, // type - 0, 0, // flag - 0, (char)num_subtables, // num subtables - }; - - start_object (lookup, 6, c); -} - -static unsigned finish_lookup (hb_serialize_context_t* c) -{ - char filter[] = {0, 0}; - extend (filter, 2, c); - return c->pop_pack (false); -} - -static unsigned add_extension (unsigned child, - uint8_t type, - hb_serialize_context_t* c) -{ - char ext[] = { - 0, 1, - 0, (char) type, - }; - - start_object (ext, 4, c); - add_wide_offset (child, c); - - return c->pop_pack (false); - -} - -// Adds coverage table fro [start, end] -static unsigned add_coverage (unsigned start, unsigned end, - hb_serialize_context_t* c) -{ - if (end - start == 1) - { - uint8_t coverage[] = { - 0, 1, // format - 0, 2, // count - - (uint8_t) ((start >> 8) & 0xFF), - (uint8_t) (start & 0xFF), // glyph[0] - - (uint8_t) ((end >> 8) & 0xFF), - (uint8_t) (end & 0xFF), // glyph[1] - }; - return add_object ((char*) coverage, 8, c); - } - - uint8_t coverage[] = { - 0, 2, // format - 0, 1, // range count - - (uint8_t) ((start >> 8) & 0xFF), - (uint8_t) (start & 0xFF), // start - - (uint8_t) ((end >> 8) & 0xFF), - (uint8_t) (end & 0xFF), // end - - 0, 0, - }; - return add_object ((char*) coverage, 10, c); -} - - -template -static unsigned add_coverage (It it, - hb_serialize_context_t* c) -{ - c->push (); - OT::Layout::Common::Coverage_serialize (c, it); - return c->pop_pack (false); -} - -// Adds a class that maps glyphs from [start_glyph, end_glyph) -// to classes 1...n -static unsigned add_class_def (uint16_t start_glyph, - uint16_t end_glyph, - hb_serialize_context_t* c) -{ - unsigned count = end_glyph - start_glyph; - uint8_t header[] = { - 0, 1, // format - - (uint8_t) ((start_glyph >> 8) & 0xFF), - (uint8_t) (start_glyph & 0xFF), // start_glyph - - (uint8_t) ((count >> 8) & 0xFF), - (uint8_t) (count & 0xFF), // count - }; - - start_object ((char*) header, 6, c); - for (uint16_t i = 1; i <= count; i++) - { - uint8_t class_value[] = { - (uint8_t) ((i >> 8) & 0xFF), - (uint8_t) (i & 0xFF), // count - }; - extend ((char*) class_value, 2, c); - } - - return c->pop_pack (false); -} - -static unsigned add_pair_pos_1 (unsigned* pair_sets, - char count, - unsigned coverage, - hb_serialize_context_t* c) -{ - char format[] = { - 0, 1 - }; - - start_object (format, 2, c); - add_offset (coverage, c); - - char value_format[] = { - 0, 0, - 0, 0, - 0, count, - }; - extend (value_format, 6, c); - - for (char i = 0; i < count; i++) - add_offset (pair_sets[(unsigned) i], c); - - return c->pop_pack (false); -} - -static unsigned add_pair_pos_2 (unsigned starting_class, - unsigned coverage, - unsigned class_def_1, uint16_t class_def_1_count, - unsigned class_def_2, uint16_t class_def_2_count, - unsigned* device_tables, - hb_serialize_context_t* c) -{ - uint8_t format[] = { - 0, 2 - }; - - start_object ((char*) format, 2, c); - add_offset (coverage, c); - - unsigned num_values = 4; - uint8_t format1 = 0x01 | 0x02 | 0x08; - uint8_t format2 = 0x04; - if (device_tables) { - format2 |= 0x20; - num_values += 1; - } - uint8_t value_format[] = { - 0, format1, - 0, format2, - }; - - extend ((char*) value_format, 4, c); - - add_offset (class_def_1, c); - add_offset (class_def_2, c); - - uint8_t class_counts[] = { - (uint8_t) ((class_def_1_count >> 8) & 0xFF), - (uint8_t) (class_def_1_count & 0xFF), - (uint8_t) ((class_def_2_count >> 8) & 0xFF), - (uint8_t) (class_def_2_count & 0xFF), - }; - extend ((char*) class_counts, 4, c); - - unsigned num_bytes_per_record = class_def_2_count * num_values * 2; - uint8_t* record = (uint8_t*) calloc (1, num_bytes_per_record); - int device_index = 0; - for (uint16_t i = 0; i < class_def_1_count; i++) - { - - for (uint16_t j = 0; j < class_def_2_count; j++) - { - for (int k = 0; k < 4; k++) { - uint8_t value[] = { - (uint8_t) (i + starting_class), - (uint8_t) (i + starting_class), - }; - extend ((char*) value, 2, c); - } - - if (device_tables) { - add_offset (device_tables[device_index++], c); - } - } - } - free (record); - - return c->pop_pack (false); -} - -static unsigned add_mark_base_pos_1 (unsigned mark_coverage, - unsigned base_coverage, - unsigned mark_array, - unsigned base_array, - unsigned class_count, - hb_serialize_context_t* c) -{ - uint8_t format[] = { - 0, 1 - }; - - start_object ((char*) format, 2, c); - add_offset (mark_coverage, c); - add_offset (base_coverage, c); - - uint8_t count[] = { - (uint8_t) ((class_count >> 8) & 0xFF), - (uint8_t) (class_count & 0xFF), - }; - extend ((char*) count, 2, c); - - add_offset (mark_array, c); - add_offset (base_array, c); - - return c->pop_pack (false); -} - -template -struct MarkBasePosBuffers -{ - unsigned base_anchors[class_count * base_count]; - unsigned mark_anchors[mark_count]; - uint8_t anchor_buffers[class_count * base_count + 100]; - uint8_t class_buffer[class_count * 2]; - - MarkBasePosBuffers(hb_serialize_context_t* c) - { - for (unsigned i = 0; i < sizeof(anchor_buffers) / 2; i++) - { - OT::HBUINT16* value = (OT::HBUINT16*) (&anchor_buffers[2*i]); - *value = i; - } - - for (unsigned i = 0; i < class_count * base_count; i++) - { - base_anchors[i] = add_object ((char*) &anchor_buffers[i], 100, c); - if (i < class_count) { - class_buffer[i*2] = (uint8_t) ((i >> 8) & 0xFF); - class_buffer[i*2 + 1] = (uint8_t) (i & 0xFF); - } - } - - for (unsigned i = 0; i < mark_count; i++) - { - mark_anchors[i] = add_object ((char*) &anchor_buffers[i], 4, c); - } - } - - unsigned create_mark_base_pos_1 (unsigned table_index, hb_serialize_context_t* c) - { - unsigned class_per_table = class_count / table_count; - unsigned mark_per_class = mark_count / class_count; - unsigned start_class = class_per_table * table_index; - unsigned end_class = class_per_table * (table_index + 1) - 1; - - // baseArray - uint8_t base_count_buffer[] = { - (uint8_t) ((base_count >> 8) & 0xFF), - (uint8_t) (base_count & 0xFF), - - }; - start_object ((char*) base_count_buffer, 2, c); - for (unsigned base = 0; base < base_count; base++) - { - for (unsigned klass = start_class; klass <= end_class; klass++) - { - unsigned i = base * class_count + klass; - add_offset (base_anchors[i], c); - } - } - unsigned base_array = c->pop_pack (false); - - // markArray - unsigned num_marks = class_per_table * mark_per_class; - uint8_t mark_count_buffer[] = { - (uint8_t) ((num_marks >> 8) & 0xFF), - (uint8_t) (num_marks & 0xFF), - }; - start_object ((char*) mark_count_buffer, 2, c); - for (unsigned mark = 0; mark < mark_count; mark++) - { - unsigned klass = mark % class_count; - if (klass < start_class || klass > end_class) continue; - klass -= start_class; - - extend ((char*) &class_buffer[2 * klass], 2, c); - add_offset (mark_anchors[mark], c); - } - unsigned mark_array = c->pop_pack (false); - - // markCoverage - auto it = - + hb_range ((hb_codepoint_t) mark_count) - | hb_filter ([&] (hb_codepoint_t mark) { - unsigned klass = mark % class_count; - return klass >= class_per_table * table_index && - klass < class_per_table * (table_index + 1); - }) - ; - unsigned mark_coverage = add_coverage (it, c); - - // baseCoverage - unsigned base_coverage = add_coverage (10, 10 + base_count - 1, c); - - return add_mark_base_pos_1 (mark_coverage, - base_coverage, - mark_array, - base_array, - class_per_table, - c); - } -}; - -static void run_resolve_overflow_test (const char* name, - hb_serialize_context_t& overflowing, - hb_serialize_context_t& expected, - unsigned num_iterations = 0, - bool recalculate_extensions = false, - hb_tag_t tag = HB_TAG ('G', 'S', 'U', 'B'), - bool check_binary_equivalence = false) -{ - printf (">>> Testing overflowing resolution for %s\n", - name); - - graph_t graph (overflowing.object_graph ()); - - graph_t expected_graph (expected.object_graph ()); - if (graph::will_overflow (expected_graph)) - { - if (check_binary_equivalence) { - printf("when binary equivalence checking is enabled, the expected graph cannot overflow."); - assert(!check_binary_equivalence); - } - expected_graph.assign_spaces (); - expected_graph.sort_shortest_distance (); - } - - // Check that overflow resolution succeeds - assert (overflowing.offset_overflow ()); - assert (hb_resolve_graph_overflows (tag, - num_iterations, - recalculate_extensions, - graph)); - - // Check the graphs can be serialized. - hb_blob_t* out1 = graph::serialize (graph); - assert (out1); - hb_blob_t* out2 = graph::serialize (expected_graph); - assert (out2); - if (check_binary_equivalence) { - unsigned l1, l2; - const char* d1 = hb_blob_get_data(out1, &l1); - const char* d2 = hb_blob_get_data(out2, &l2); - - bool match = (l1 == l2) && (memcmp(d1, d2, l1) == 0); - if (!match) { - printf("## Result:\n"); - graph.print(); - printf("## Expected:\n"); - expected_graph.print(); - assert(match); - } - } - - hb_blob_destroy (out1); - hb_blob_destroy (out2); - - // Check the graphs are equivalent - graph.normalize (); - expected_graph.normalize (); - if (!(graph == expected_graph)) { - printf("## Expected:\n"); - expected_graph.print(); - printf("## Result:\n"); - graph.print(); - } - assert (graph == expected_graph); -} - -static void add_virtual_offset (unsigned id, - hb_serialize_context_t* c) -{ - c->add_virtual_link (id); -} - -static void -populate_serializer_simple (hb_serialize_context_t* c) -{ - c->start_serialize (); - - unsigned obj_1 = add_object ("ghi", 3, c); - unsigned obj_2 = add_object ("def", 3, c); - - start_object ("abc", 3, c); - add_offset (obj_2, c); - add_offset (obj_1, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_overflow (hb_serialize_context_t* c) -{ - std::string large_string(50000, 'a'); - c->start_serialize (); - - unsigned obj_1 = add_object (large_string.c_str(), 10000, c); - unsigned obj_2 = add_object (large_string.c_str(), 20000, c); - unsigned obj_3 = add_object (large_string.c_str(), 50000, c); - - start_object ("abc", 3, c); - add_offset (obj_3, c); - add_offset (obj_2, c); - add_offset (obj_1, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_priority_overflow (hb_serialize_context_t* c) -{ - std::string large_string(50000, 'a'); - c->start_serialize (); - - unsigned obj_e = add_object ("e", 1, c); - unsigned obj_d = add_object ("d", 1, c); - - start_object (large_string.c_str (), 50000, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object (large_string.c_str (), 20000, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_priority_overflow_expected (hb_serialize_context_t* c) -{ - std::string large_string(50000, 'a'); - c->start_serialize (); - - unsigned obj_e = add_object ("e", 1, c); - - start_object (large_string.c_str (), 50000, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - unsigned obj_d = add_object ("d", 1, c); - - start_object (large_string.c_str (), 20000, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - - -static void -populate_serializer_with_dedup_overflow (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_1 = add_object ("def", 3, c); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_1, c); - unsigned obj_2 = c->pop_pack (false); - - start_object (large_string.c_str(), 10000, c); - add_offset (obj_2, c); - add_offset (obj_1, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_multiple_dedup_overflow (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned leaf = add_object("def", 3, c); - - constexpr unsigned num_mid_nodes = 20; - unsigned mid_nodes[num_mid_nodes]; - for (unsigned i = 0; i < num_mid_nodes; i++) { - start_object(large_string.c_str(), 10000 + i, c); - add_offset(leaf, c); - mid_nodes[i] = c->pop_pack(false); - } - - start_object("abc", 3, c); - for (unsigned i = 0; i < num_mid_nodes; i++) { - add_wide_offset(mid_nodes[i], c); - } - c->pop_pack(false); - - c->end_serialize(); -} - -static void -populate_serializer_with_isolation_overflow (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_4 = add_object ("4", 1, c); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_4, c); - unsigned obj_3 = c->pop_pack (false); - - start_object (large_string.c_str(), 10000, c); - add_offset (obj_4, c); - unsigned obj_2 = c->pop_pack (false); - - start_object ("1", 1, c); - add_wide_offset (obj_3, c); - add_offset (obj_2, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_isolation_overflow_complex (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_f = add_object ("f", 1, c); - - start_object ("e", 1, c); - add_offset (obj_f, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("d", 1, c); - add_offset (obj_e, c); - unsigned obj_d = c->pop_pack (false); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_d, c); - unsigned obj_h = c->pop_pack (false); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_c, c); - add_offset (obj_h, c); - unsigned obj_b = c->pop_pack (false); - - start_object (large_string.c_str(), 10000, c); - add_offset (obj_d, c); - unsigned obj_g = c->pop_pack (false); - - start_object (large_string.c_str(), 11000, c); - add_offset (obj_d, c); - unsigned obj_i = c->pop_pack (false); - - start_object ("a", 1, c); - add_wide_offset (obj_b, c); - add_offset (obj_g, c); - add_offset (obj_i, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_isolation_overflow_complex_expected (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - - // space 1 - - unsigned obj_f_prime = add_object ("f", 1, c); - - start_object ("e", 1, c); - add_offset (obj_f_prime, c); - unsigned obj_e_prime = c->pop_pack (false); - - start_object ("d", 1, c); - add_offset (obj_e_prime, c); - unsigned obj_d_prime = c->pop_pack (false); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_d_prime, c); - unsigned obj_h = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e_prime, c); - unsigned obj_c = c->pop_pack (false); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_c, c); - add_offset (obj_h, c); - unsigned obj_b = c->pop_pack (false); - - // space 0 - - unsigned obj_f = add_object ("f", 1, c); - - start_object ("e", 1, c); - add_offset (obj_f, c); - unsigned obj_e = c->pop_pack (false); - - - start_object ("d", 1, c); - add_offset (obj_e, c); - unsigned obj_d = c->pop_pack (false); - - start_object (large_string.c_str(), 11000, c); - add_offset (obj_d, c); - unsigned obj_i = c->pop_pack (false); - - start_object (large_string.c_str(), 10000, c); - add_offset (obj_d, c); - unsigned obj_g = c->pop_pack (false); - - start_object ("a", 1, c); - add_wide_offset (obj_b, c); - add_offset (obj_g, c); - add_offset (obj_i, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_isolation_overflow_spaces (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_d = add_object ("f", 1, c); - unsigned obj_e = add_object ("f", 1, c); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (); - - start_object (large_string.c_str(), 60000, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (); - - - start_object ("a", 1, c); - add_wide_offset (obj_b, c); - add_wide_offset (obj_c, c); - c->pop_pack (); - - c->end_serialize(); -} - -static void -populate_serializer_with_repack_last (hb_serialize_context_t* c, bool with_overflow) -{ - std::string large_string(70000, 'c'); - c->start_serialize (); - c->push(); - - // Obj E - unsigned obj_e_1, obj_e_2; - if (with_overflow) { - obj_e_1 = add_object("a", 1, c); - obj_e_2 = obj_e_1; - } else { - obj_e_2 = add_object("a", 1, c); - } - - // Obj D - c->push(); - add_offset(obj_e_2, c); - extend(large_string.c_str(), 30000, c); - unsigned obj_d = c->pop_pack(false); - - add_offset(obj_d, c); - assert(c->last_added_child_index() == obj_d); - - if (!with_overflow) { - obj_e_1 = add_object("a", 1, c); - } - - // Obj C - c->push(); - add_offset(obj_e_1, c); - extend(large_string.c_str(), 40000, c); - unsigned obj_c = c->pop_pack(false); - - add_offset(obj_c, c); - - // Obj B - unsigned obj_b = add_object("b", 1, c); - add_offset(obj_b, c); - - // Obj A - c->repack_last(obj_d); - c->pop_pack(false); - - c->end_serialize(); -} - -static void -populate_serializer_spaces (hb_serialize_context_t* c, bool with_overflow) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_i; - - if (with_overflow) - obj_i = add_object ("i", 1, c); - - // Space 2 - unsigned obj_h = add_object ("h", 1, c); - - start_object (large_string.c_str(), 30000, c); - add_offset (obj_h, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_e, c); - unsigned obj_b = c->pop_pack (false); - - // Space 1 - if (!with_overflow) - obj_i = add_object ("i", 1, c); - - start_object (large_string.c_str(), 30000, c); - add_offset (obj_i, c); - unsigned obj_g = c->pop_pack (false); - - start_object (large_string.c_str(), 30000, c); - add_offset (obj_i, c); - unsigned obj_f = c->pop_pack (false); - - start_object ("d", 1, c); - add_offset (obj_g, c); - unsigned obj_d = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_f, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("a", 1, c); - add_wide_offset (obj_b, c); - add_wide_offset (obj_c, c); - add_wide_offset (obj_d, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_spaces_16bit_connection (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_g = add_object ("g", 1, c); - unsigned obj_h = add_object ("h", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_g, c); - unsigned obj_e = c->pop_pack (false); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_h, c); - unsigned obj_f = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("d", 1, c); - add_offset (obj_f, c); - unsigned obj_d = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_e, c); - add_offset (obj_h, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_wide_offset (obj_c, c); - add_wide_offset (obj_d, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_spaces_16bit_connection_expected (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_g_prime = add_object ("g", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_g_prime, c); - unsigned obj_e_prime = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e_prime, c); - unsigned obj_c = c->pop_pack (false); - - unsigned obj_h_prime = add_object ("h", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_h_prime, c); - unsigned obj_f = c->pop_pack (false); - - start_object ("d", 1, c); - add_offset (obj_f, c); - unsigned obj_d = c->pop_pack (false); - - unsigned obj_g = add_object ("g", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_g, c); - unsigned obj_e = c->pop_pack (false); - - unsigned obj_h = add_object ("h", 1, c); - - start_object ("b", 1, c); - add_offset (obj_e, c); - add_offset (obj_h, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_wide_offset (obj_c, c); - add_wide_offset (obj_d, c); - c->pop_pack (false); - - c->end_serialize (); -} - -static void -populate_serializer_short_and_wide_subgraph_root (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_e = add_object ("e", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_c, c); - unsigned obj_d = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_c, c); - add_offset (obj_e, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_wide_offset (obj_c, c); - add_wide_offset (obj_d, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_short_and_wide_subgraph_root_expected (hb_serialize_context_t* c) -{ - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_e_prime = add_object ("e", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_e_prime, c); - unsigned obj_c_prime = c->pop_pack (false); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_c_prime, c); - unsigned obj_d = c->pop_pack (false); - - unsigned obj_e = add_object ("e", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - - start_object ("b", 1, c); - add_offset (obj_c, c); - add_offset (obj_e, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_wide_offset (obj_c_prime, c); - add_wide_offset (obj_d, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_split_spaces (hb_serialize_context_t* c) -{ - // Overflow needs to be resolved by splitting the single space - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_f = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f, c); - unsigned obj_d = c->pop_pack (false); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("a", 1, c); - add_wide_offset (obj_b, c); - add_wide_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_split_spaces_2 (hb_serialize_context_t* c) -{ - // Overflow needs to be resolved by splitting the single space - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_f = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f, c); - unsigned obj_d = c->pop_pack (false); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_wide_offset (obj_b, c); - add_wide_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c) -{ - // Overflow needs to be resolved by splitting the single space - - std::string large_string(70000, 'a'); - c->start_serialize (); - - unsigned obj_f_prime = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f_prime, c); - unsigned obj_d = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - unsigned obj_f = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("a", 1, c); - add_wide_offset (obj_b, c); - add_wide_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_split_spaces_expected_2 (hb_serialize_context_t* c) -{ - // Overflow needs to be resolved by splitting the single space - - std::string large_string(70000, 'a'); - c->start_serialize (); - - // Space 2 - - unsigned obj_f_double_prime = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f_double_prime, c); - unsigned obj_d_prime = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_d_prime, c); - unsigned obj_b_prime = c->pop_pack (false); - - // Space 1 - - unsigned obj_f_prime = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f_prime, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - // Space 0 - - unsigned obj_f = add_object ("f", 1, c); - - start_object (large_string.c_str(), 40000, c); - add_offset (obj_f, c); - unsigned obj_d = c->pop_pack (false); - - start_object ("b", 1, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - // Root - start_object ("a", 1, c); - add_offset (obj_b, c); - add_wide_offset (obj_b_prime, c); - add_wide_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_complex_2 (hb_serialize_context_t* c) -{ - c->start_serialize (); - - unsigned obj_5 = add_object ("mn", 2, c); - - unsigned obj_4 = add_object ("jkl", 3, c); - - start_object ("ghi", 3, c); - add_offset (obj_4, c); - unsigned obj_3 = c->pop_pack (false); - - start_object ("def", 3, c); - add_offset (obj_3, c); - unsigned obj_2 = c->pop_pack (false); - - start_object ("abc", 3, c); - add_offset (obj_2, c); - add_offset (obj_4, c); - add_offset (obj_5, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_complex_3 (hb_serialize_context_t* c) -{ - c->start_serialize (); - - unsigned obj_6 = add_object ("opqrst", 6, c); - - unsigned obj_5 = add_object ("mn", 2, c); - - start_object ("jkl", 3, c); - add_offset (obj_6, c); - unsigned obj_4 = c->pop_pack (false); - - start_object ("ghi", 3, c); - add_offset (obj_4, c); - unsigned obj_3 = c->pop_pack (false); - - start_object ("def", 3, c); - add_offset (obj_3, c); - unsigned obj_2 = c->pop_pack (false); - - start_object ("abc", 3, c); - add_offset (obj_2, c); - add_offset (obj_4, c); - add_offset (obj_5, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_virtual_link (hb_serialize_context_t* c) -{ - c->start_serialize (); - - unsigned obj_d = add_object ("d", 1, c); - - start_object ("b", 1, c); - add_offset (obj_d, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("e", 1, c); - add_virtual_offset (obj_b, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("c", 1, c); - add_offset (obj_e, c); - unsigned obj_c = c->pop_pack (false); - - start_object ("a", 1, c); - add_offset (obj_b, c); - add_offset (obj_c, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_24_and_32_bit_offsets (hb_serialize_context_t* c) -{ - std::string large_string(60000, 'a'); - c->start_serialize (); - - unsigned obj_f = add_object ("f", 1, c); - unsigned obj_g = add_object ("g", 1, c); - unsigned obj_j = add_object ("j", 1, c); - unsigned obj_k = add_object ("k", 1, c); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_f, c); - unsigned obj_c = c->pop_pack (false); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_g, c); - unsigned obj_d = c->pop_pack (false); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_j, c); - unsigned obj_h = c->pop_pack (false); - - start_object (large_string.c_str (), 40000, c); - add_offset (obj_k, c); - unsigned obj_i = c->pop_pack (false); - - start_object ("e", 1, c); - add_wide_offset (obj_h, c); - add_wide_offset (obj_i, c); - unsigned obj_e = c->pop_pack (false); - - start_object ("b", 1, c); - add_24_offset (obj_c, c); - add_24_offset (obj_d, c); - add_24_offset (obj_e, c); - unsigned obj_b = c->pop_pack (false); - - start_object ("a", 1, c); - add_24_offset (obj_b, c); - c->pop_pack (false); - - c->end_serialize(); -} - -static void -populate_serializer_with_extension_promotion (hb_serialize_context_t* c, - int num_extensions = 0, - bool shared_subtables = false) -{ - constexpr int num_lookups = 5; - constexpr int num_subtables = num_lookups * 2; - unsigned int lookups[num_lookups]; - unsigned int subtables[num_subtables]; - unsigned int extensions[num_subtables]; - - std::string large_string(60000, 'a'); - c->start_serialize (); - - - for (int i = num_subtables - 1; i >= 0; i--) - subtables[i] = add_object(large_string.c_str (), 15000 + i, c); - - for (int i = num_subtables - 1; - i >= (num_lookups - num_extensions) * 2; - i--) - { - extensions[i] = add_extension (subtables[i], 5, c); - } - - for (int i = num_lookups - 1; i >= 0; i--) - { - bool is_ext = (i >= (num_lookups - num_extensions)); - - start_lookup (is_ext ? (char) 7 : (char) 5, - shared_subtables && i > 2 ? 3 : 2, - c); - - if (is_ext) { - if (shared_subtables && i > 2) { - add_offset (extensions[i * 2 - 1], c); - } - add_offset (extensions[i * 2], c); - add_offset (extensions[i * 2 + 1], c); - } else { - if (shared_subtables && i > 2) { - add_offset (subtables[i * 2 - 1], c); - } - add_offset (subtables[i * 2], c); - add_offset (subtables[i * 2 + 1], c); - } - - lookups[i] = finish_lookup (c); - } - - unsigned lookup_list = add_lookup_list (lookups, num_lookups, c); - - add_gsubgpos_header (lookup_list, c); - - c->end_serialize(); -} - -template -static void -populate_serializer_with_large_pair_pos_1 (hb_serialize_context_t* c, - bool as_extension = false) -{ - std::string large_string(60000, 'a'); - c->start_serialize (); - - constexpr int total_pair_set = num_pair_pos_1 * num_pair_set; - unsigned pair_set[total_pair_set]; - unsigned coverage[num_pair_pos_1]; - unsigned pair_pos_1[num_pair_pos_1]; - - for (int i = num_pair_pos_1 - 1; i >= 0; i--) - { - for (int j = (i + 1) * num_pair_set - 1; j >= i * num_pair_set; j--) - pair_set[j] = add_object (large_string.c_str (), 30000 + j, c); - - coverage[i] = add_coverage (i * num_pair_set, - (i + 1) * num_pair_set - 1, c); - - pair_pos_1[i] = add_pair_pos_1 (&pair_set[i * num_pair_set], - num_pair_set, - coverage[i], - c); - } - - unsigned pair_pos_2 = add_object (large_string.c_str(), 200, c); - - if (as_extension) { - pair_pos_2 = add_extension (pair_pos_2, 2, c); - for (int i = num_pair_pos_1 - 1; i >= 0; i--) - pair_pos_1[i] = add_extension (pair_pos_1[i], 2, c); - } - - start_lookup (as_extension ? 9 : 2, 1 + num_pair_pos_1, c); - - for (int i = 0; i < num_pair_pos_1; i++) - add_offset (pair_pos_1[i], c); - add_offset (pair_pos_2, c); - - unsigned lookup = finish_lookup (c); - - unsigned lookup_list = add_lookup_list (&lookup, 1, c); - - add_gsubgpos_header (lookup_list, c); - - c->end_serialize(); -} - -template -static void -populate_serializer_with_large_pair_pos_2 (hb_serialize_context_t* c, - bool as_extension = false, - bool with_device_tables = false, - bool extra_table = true) -{ - std::string large_string(100000, 'a'); - c->start_serialize (); - - unsigned coverage[num_pair_pos_2]; - unsigned class_def_1[num_pair_pos_2]; - unsigned class_def_2[num_pair_pos_2]; - unsigned pair_pos_2[num_pair_pos_2]; - - unsigned* device_tables = (unsigned*) calloc (num_pair_pos_2 * num_class_1 * num_class_2, - sizeof(unsigned)); - - // Total glyphs = num_class_1 * num_pair_pos_2 - for (int i = num_pair_pos_2 - 1; i >= 0; i--) - { - unsigned start_glyph = 5 + i * num_class_1; - if (num_class_2 >= num_class_1) - { - class_def_2[i] = add_class_def (11, - 10 + num_class_2, c); - class_def_1[i] = add_class_def (start_glyph + 1, - start_glyph + num_class_1, - c); - } else { - class_def_1[i] = add_class_def (start_glyph + 1, - start_glyph + num_class_1, - c); - class_def_2[i] = add_class_def (11, - 10 + num_class_2, c); - } - - coverage[i] = add_coverage (start_glyph, - start_glyph + num_class_1 - 1, - c); - - if (with_device_tables) - { - for(int j = (i + 1) * num_class_1 * num_class_2 - 1; - j >= i * num_class_1 * num_class_2; - j--) - { - uint8_t table[] = { - (uint8_t) ((j >> 8) & 0xFF), - (uint8_t) (j & 0xFF), - }; - device_tables[j] = add_object ((char*) table, 2, c); - } - } - - pair_pos_2[i] = add_pair_pos_2 (1 + i * num_class_1, - coverage[i], - class_def_1[i], num_class_1, - class_def_2[i], num_class_2, - with_device_tables - ? &device_tables[i * num_class_1 * num_class_2] - : nullptr, - c); - } - - - unsigned pair_pos_1 = 0; - if (extra_table) pair_pos_1 = add_object (large_string.c_str(), 100000, c); - - if (as_extension) { - for (int i = num_pair_pos_2 - 1; i >= 0; i--) - pair_pos_2[i] = add_extension (pair_pos_2[i], 2, c); - - if (extra_table) - pair_pos_1 = add_extension (pair_pos_1, 2, c); - } - - start_lookup (as_extension ? 9 : 2, 1 + num_pair_pos_2, c); - - if (extra_table) - add_offset (pair_pos_1, c); - - for (int i = 0; i < num_pair_pos_2; i++) - add_offset (pair_pos_2[i], c); - - unsigned lookup = finish_lookup (c); - - unsigned lookup_list = add_lookup_list (&lookup, 1, c); - - add_gsubgpos_header (lookup_list, c); - - c->end_serialize(); - - free (device_tables); -} - -template -static void -populate_serializer_with_large_mark_base_pos_1 (hb_serialize_context_t* c) -{ - c->start_serialize (); - - MarkBasePosBuffers buffers (c); - - unsigned mark_base_pos[table_count]; - for (unsigned i = 0; i < table_count; i++) - mark_base_pos[i] = buffers.create_mark_base_pos_1 (i, c); - - for (int i = 0; i < table_count; i++) - mark_base_pos[i] = add_extension (mark_base_pos[i], 4, c); - - start_lookup (9, table_count, c); - - for (int i = 0; i < table_count; i++) - add_offset (mark_base_pos[i], c); - - unsigned lookup = finish_lookup (c); - - unsigned lookup_list = add_lookup_list (&lookup, 1, c); - - add_gsubgpos_header (lookup_list, c); - - c->end_serialize(); -} - -static void test_sort_shortest () -{ - size_t buffer_size = 100; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_complex_2 (&c); - - graph_t graph (c.object_graph ()); - graph.sort_shortest_distance (); - assert (!graph.in_error ()); - - assert(strncmp (graph.object (4).head, "abc", 3) == 0); - assert(graph.object (4).real_links.length == 3); - assert(graph.object (4).real_links[0].objidx == 2); - assert(graph.object (4).real_links[1].objidx == 0); - assert(graph.object (4).real_links[2].objidx == 3); - - assert(strncmp (graph.object (3).head, "mn", 2) == 0); - assert(graph.object (3).real_links.length == 0); - - assert(strncmp (graph.object (2).head, "def", 3) == 0); - assert(graph.object (2).real_links.length == 1); - assert(graph.object (2).real_links[0].objidx == 1); - - assert(strncmp (graph.object (1).head, "ghi", 3) == 0); - assert(graph.object (1).real_links.length == 1); - assert(graph.object (1).real_links[0].objidx == 0); - - assert(strncmp (graph.object (0).head, "jkl", 3) == 0); - assert(graph.object (0).real_links.length == 0); - - free (buffer); -} - -static void test_duplicate_leaf () -{ - size_t buffer_size = 100; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_complex_2 (&c); - - graph_t graph (c.object_graph ()); - graph.duplicate (4, 1); - - assert(strncmp (graph.object (5).head, "abc", 3) == 0); - assert(graph.object (5).real_links.length == 3); - assert(graph.object (5).real_links[0].objidx == 3); - assert(graph.object (5).real_links[1].objidx == 4); - assert(graph.object (5).real_links[2].objidx == 0); - - assert(strncmp (graph.object (4).head, "jkl", 3) == 0); - assert(graph.object (4).real_links.length == 0); - - assert(strncmp (graph.object (3).head, "def", 3) == 0); - assert(graph.object (3).real_links.length == 1); - assert(graph.object (3).real_links[0].objidx == 2); - - assert(strncmp (graph.object (2).head, "ghi", 3) == 0); - assert(graph.object (2).real_links.length == 1); - assert(graph.object (2).real_links[0].objidx == 1); - - assert(strncmp (graph.object (1).head, "jkl", 3) == 0); - assert(graph.object (1).real_links.length == 0); - - assert(strncmp (graph.object (0).head, "mn", 2) == 0); - assert(graph.object (0).real_links.length == 0); - - free (buffer); -} - -static void test_duplicate_interior () -{ - size_t buffer_size = 100; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_complex_3 (&c); - - graph_t graph (c.object_graph ()); - graph.duplicate (3, 2); - - assert(strncmp (graph.object (6).head, "abc", 3) == 0); - assert(graph.object (6).real_links.length == 3); - assert(graph.object (6).real_links[0].objidx == 4); - assert(graph.object (6).real_links[1].objidx == 2); - assert(graph.object (6).real_links[2].objidx == 1); - - assert(strncmp (graph.object (5).head, "jkl", 3) == 0); - assert(graph.object (5).real_links.length == 1); - assert(graph.object (5).real_links[0].objidx == 0); - - assert(strncmp (graph.object (4).head, "def", 3) == 0); - assert(graph.object (4).real_links.length == 1); - assert(graph.object (4).real_links[0].objidx == 3); - - assert(strncmp (graph.object (3).head, "ghi", 3) == 0); - assert(graph.object (3).real_links.length == 1); - assert(graph.object (3).real_links[0].objidx == 5); - - assert(strncmp (graph.object (2).head, "jkl", 3) == 0); - assert(graph.object (2).real_links.length == 1); - assert(graph.object (2).real_links[0].objidx == 0); - - assert(strncmp (graph.object (1).head, "mn", 2) == 0); - assert(graph.object (1).real_links.length == 0); - - assert(strncmp (graph.object (0).head, "opqrst", 6) == 0); - assert(graph.object (0).real_links.length == 0); - - free (buffer); -} - -static void -test_serialize () -{ - size_t buffer_size = 100; - void* buffer_1 = malloc (buffer_size); - hb_serialize_context_t c1 (buffer_1, buffer_size); - populate_serializer_simple (&c1); - hb_bytes_t expected = c1.copy_bytes (); - - graph_t graph (c1.object_graph ()); - hb_blob_t* out = graph::serialize (graph); - free (buffer_1); - - hb_bytes_t actual = out->as_bytes (); - assert (actual == expected); - expected.fini (); - hb_blob_destroy (out); -} - -static void test_will_overflow_1 () -{ - size_t buffer_size = 100; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_complex_2 (&c); - graph_t graph (c.object_graph ()); - - assert (!graph::will_overflow (graph, nullptr)); - - free (buffer); -} - -static void test_will_overflow_2 () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_overflow (&c); - graph_t graph (c.object_graph ()); - - assert (graph::will_overflow (graph, nullptr)); - - free (buffer); -} - -static void test_will_overflow_3 () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_dedup_overflow (&c); - graph_t graph (c.object_graph ()); - - assert (graph::will_overflow (graph, nullptr)); - - free (buffer); -} - -static void test_resolve_overflows_via_sort () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_overflow (&c); - graph_t graph (c.object_graph ()); - - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE); - assert (out); - hb_bytes_t result = out->as_bytes (); - assert (result.length == (80000 + 3 + 3 * 2)); - - free (buffer); - hb_blob_destroy (out); -} - -static void test_resolve_overflows_via_duplication () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_dedup_overflow (&c); - graph_t graph (c.object_graph ()); - - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE); - assert (out); - hb_bytes_t result = out->as_bytes (); - assert (result.length == (10000 + 2 * 2 + 60000 + 2 + 3 * 2)); - - free (buffer); - hb_blob_destroy (out); -} - -static void test_resolve_overflows_via_multiple_duplications () -{ - size_t buffer_size = 300000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_multiple_dedup_overflow (&c); - graph_t graph (c.object_graph ()); - - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE, 5); - assert (out); - - free (buffer); - hb_blob_destroy (out); -} - -static void test_resolve_overflows_via_space_assignment () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_spaces (&c, true); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_spaces (&e, false); - - run_resolve_overflow_test ("test_resolve_overflows_via_space_assignment", - c, - e); - - free (buffer); - free (expected_buffer); -} - -static void test_resolve_overflows_via_isolation () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_isolation_overflow (&c); - graph_t graph (c.object_graph ()); - - assert (c.offset_overflow ()); - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0); - assert (out); - hb_bytes_t result = out->as_bytes (); - assert (result.length == (1 + 10000 + 60000 + 1 + 1 - + 4 + 3 * 2)); - - free (buffer); - hb_blob_destroy (out); -} - -static void test_resolve_overflows_via_isolation_with_recursive_duplication () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_isolation_overflow_complex (&c); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_isolation_overflow_complex_expected (&e); - - run_resolve_overflow_test ("test_resolve_overflows_via_isolation_with_recursive_duplication", - c, - e); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_overflows_via_isolating_16bit_space () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_spaces_16bit_connection (&c); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_spaces_16bit_connection_expected (&e); - - run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space", - c, - e); - - free (buffer); - free (expected_buffer); -} - -static void test_resolve_overflows_via_isolating_16bit_space_2 () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_short_and_wide_subgraph_root (&c); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_short_and_wide_subgraph_root_expected (&e); - - run_resolve_overflow_test ("test_resolve_overflows_via_isolating_16bit_space_2", - c, - e); - - free (buffer); - free (expected_buffer); -} - -static void test_resolve_overflows_via_isolation_spaces () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_isolation_overflow_spaces (&c); - graph_t graph (c.object_graph ()); - - assert (c.offset_overflow ()); - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0); - assert (out); - hb_bytes_t result = out->as_bytes (); - - unsigned expected_length = 3 + 2 * 60000; // objects - expected_length += 2 * 4 + 2 * 2; // links - assert (result.length == expected_length); - - free (buffer); - hb_blob_destroy (out); -} - -static void test_resolve_mixed_overflows_via_isolation_spaces () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_24_and_32_bit_offsets (&c); - graph_t graph (c.object_graph ()); - - assert (c.offset_overflow ()); - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), 0); - assert (out); - hb_bytes_t result = out->as_bytes (); - - unsigned expected_length = - // Objects - 7 + - 4 * 40000; - - expected_length += - // Links - 2 * 4 + // 32 - 4 * 3 + // 24 - 4 * 2; // 16 - - assert (result.length == expected_length); - - free (buffer); - hb_blob_destroy (out); -} - -static void test_resolve_with_extension_promotion () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_extension_promotion (&c); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_extension_promotion (&e, 3); - - run_resolve_overflow_test ("test_resolve_with_extension_promotion", - c, - e, - 20, - true); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_shared_extension_promotion () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_extension_promotion (&c, 0, true); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_extension_promotion (&e, 3, true); - - run_resolve_overflow_test ("test_resolve_with_extension_promotion", - c, - e, - 20, - true); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_basic_pair_pos_1_split () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_pair_pos_1 <1, 4>(&c); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_pair_pos_1 <2, 2>(&e, true); - - run_resolve_overflow_test ("test_resolve_with_basic_pair_pos_1_split", - c, - e, - 20, - true, - HB_TAG('G', 'P', 'O', 'S')); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_extension_pair_pos_1_split () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_pair_pos_1 <1, 4>(&c, true); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_pair_pos_1 <2, 2>(&e, true); - - run_resolve_overflow_test ("test_resolve_with_extension_pair_pos_1_split", - c, - e, - 20, - true, - HB_TAG('G', 'P', 'O', 'S')); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_basic_pair_pos_2_split () -{ - size_t buffer_size = 300000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <1, 4, 3000>(&c); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <2, 2, 3000>(&e, true); - - run_resolve_overflow_test ("test_resolve_with_basic_pair_pos_2_split", - c, - e, - 20, - true, - HB_TAG('G', 'P', 'O', 'S')); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_close_to_limit_pair_pos_2_split () -{ - size_t buffer_size = 300000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <1, 1636, 10>(&c, true, false, false); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <2, 818, 10>(&e, true, false, false); - - run_resolve_overflow_test ("test_resolve_with_close_to_limit_pair_pos_2_split", - c, - e, - 20, - true, - HB_TAG('G', 'P', 'O', 'S')); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_pair_pos_2_split_with_device_tables () -{ - size_t buffer_size = 300000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <1, 4, 2000>(&c, false, true); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_pair_pos_2 <2, 2, 2000>(&e, true, true); - - run_resolve_overflow_test ("test_resolve_with_pair_pos_2_split_with_device_tables", - c, - e, - 20, - true, - HB_TAG('G', 'P', 'O', 'S')); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_with_basic_mark_base_pos_1_split () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_large_mark_base_pos_1 <40, 10, 110, 1>(&c); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_large_mark_base_pos_1 <40, 10, 110, 2>(&e); - - run_resolve_overflow_test ("test_resolve_with_basic_mark_base_pos_1_split", - c, - e, - 20, - true, - HB_TAG('G', 'P', 'O', 'S')); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_overflows_via_splitting_spaces () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_split_spaces (&c); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_split_spaces_expected (&e); - - run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces", - c, - e, - 1); - - free (buffer); - free (expected_buffer); - -} - -static void test_resolve_overflows_via_splitting_spaces_2 () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_split_spaces_2 (&c); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_split_spaces_expected_2 (&e); - - run_resolve_overflow_test ("test_resolve_overflows_via_splitting_spaces_2", - c, - e, - 1); - free (buffer); - free (expected_buffer); -} - -static void test_resolve_overflows_via_priority () -{ - size_t buffer_size = 160000; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_priority_overflow (&c); - - void* expected_buffer = malloc (buffer_size); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_priority_overflow_expected (&e); - - run_resolve_overflow_test ("test_resolve_overflows_via_priority", - c, - e, - 3); - free (buffer); - free (expected_buffer); -} - - -static void test_virtual_link () -{ - size_t buffer_size = 100; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_virtual_link (&c); - - hb_blob_t* out = hb_resolve_overflows (c.object_graph (), HB_TAG_NONE); - assert (out); - - hb_bytes_t result = out->as_bytes (); - assert (result.length == 5 + 4 * 2); - assert (result[0] == 'a'); - assert (result[5] == 'c'); - assert (result[8] == 'e'); - assert (result[9] == 'b'); - assert (result[12] == 'd'); - - free (buffer); - hb_blob_destroy (out); -} - -static void -test_shared_node_with_virtual_links () -{ - size_t buffer_size = 100; - void* buffer = malloc (buffer_size); - hb_serialize_context_t c (buffer, buffer_size); - - c.start_serialize (); - - unsigned obj_b = add_object ("b", 1, &c); - unsigned obj_c = add_object ("c", 1, &c); - - start_object ("d", 1, &c); - add_virtual_offset (obj_b, &c); - unsigned obj_d_1 = c.pop_pack (); - - start_object ("d", 1, &c); - add_virtual_offset (obj_c, &c); - unsigned obj_d_2 = c.pop_pack (); - - assert (obj_d_1 == obj_d_2); - - start_object ("a", 1, &c); - add_offset (obj_b, &c); - add_offset (obj_c, &c); - add_offset (obj_d_1, &c); - add_offset (obj_d_2, &c); - c.pop_pack (); - c.end_serialize (); - - assert(c.object_graph() [obj_d_1]->virtual_links.length == 2); - assert(c.object_graph() [obj_d_1]->virtual_links[0].objidx == obj_b); - assert(c.object_graph() [obj_d_1]->virtual_links[1].objidx == obj_c); - free(buffer); -} - -static void -test_repack_last () -{ - size_t buffer_size = 200000; - void* buffer = malloc (buffer_size); - assert (buffer); - hb_serialize_context_t c (buffer, buffer_size); - populate_serializer_with_repack_last (&c, true); - - void* expected_buffer = malloc (buffer_size); - assert (expected_buffer); - hb_serialize_context_t e (expected_buffer, buffer_size); - populate_serializer_with_repack_last (&e, false); - - run_resolve_overflow_test ("test_repack_last", - c, - e, - 20, - false, - HB_TAG('a', 'b', 'c', 'd'), - true); - - free (buffer); - free (expected_buffer); -} - -// TODO(garretrieger): update will_overflow tests to check the overflows array. -// TODO(garretrieger): add tests for priority raising. - -int -main (int argc, char **argv) -{ - test_serialize (); - test_sort_shortest (); - test_will_overflow_1 (); - test_will_overflow_2 (); - test_will_overflow_3 (); - test_resolve_overflows_via_sort (); - test_resolve_overflows_via_duplication (); - test_resolve_overflows_via_multiple_duplications (); - test_resolve_overflows_via_priority (); - test_resolve_overflows_via_space_assignment (); - test_resolve_overflows_via_isolation (); - test_resolve_overflows_via_isolation_with_recursive_duplication (); - test_resolve_overflows_via_isolation_spaces (); - test_resolve_overflows_via_isolating_16bit_space (); - test_resolve_overflows_via_isolating_16bit_space_2 (); - test_resolve_overflows_via_splitting_spaces (); - test_resolve_overflows_via_splitting_spaces_2 (); - test_resolve_mixed_overflows_via_isolation_spaces (); - test_duplicate_leaf (); - test_duplicate_interior (); - test_virtual_link (); - test_repack_last(); - test_shared_node_with_virtual_links (); - test_resolve_with_extension_promotion (); - test_resolve_with_shared_extension_promotion (); - test_resolve_with_basic_pair_pos_1_split (); - test_resolve_with_extension_pair_pos_1_split (); - test_resolve_with_basic_pair_pos_2_split (); - test_resolve_with_pair_pos_2_split_with_device_tables (); - test_resolve_with_close_to_limit_pair_pos_2_split (); - test_resolve_with_basic_mark_base_pos_1_split (); - - // TODO(grieger): have run overflow tests compare graph equality not final packed binary. - // TODO(grieger): split test where multiple subtables in one lookup are split to test link ordering. - // TODO(grieger): split test where coverage table in subtable that is being split is shared. - // TODO(grieger): test with extensions already mixed in as well. - // TODO(grieger): test two layer ext promotion setup. - // TODO(grieger): test sorting by subtables per byte in ext. promotion. -} diff --git a/thirdparty/harfbuzz/upstream/test-set.cc b/thirdparty/harfbuzz/upstream/test-set.cc deleted file mode 100644 index 853aed406..000000000 --- a/thirdparty/harfbuzz/upstream/test-set.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright © 2021 Behdad Esfahbod - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "hb.hh" -#include "hb-set.hh" - -int -main (int argc, char **argv) -{ - - /* Test copy constructor. */ - { - hb_set_t v1 {1, 2}; - hb_set_t v2 {v1}; - assert (v1.get_population () == 2); - assert (hb_len (hb_iter (v1)) == 2); - assert (v2.get_population () == 2); - } - - /* Test copy assignment. */ - { - hb_set_t v1 {1, 2}; - hb_set_t v2; - v2 = v1; - assert (v1.get_population () == 2); - assert (v2.get_population () == 2); - } - - /* Test move constructor. */ - { - hb_set_t s {1, 2}; - hb_set_t v (std::move (s)); - assert (s.get_population () == 0); - assert (hb_len (hb_iter (s)) == 0); - assert (v.get_population () == 2); - } - - /* Test move assignment. */ - { - hb_set_t s = hb_set_t {1, 2}; - hb_set_t v; - v = std::move (s); - assert (s.get_population () == 0); - assert (v.get_population () == 2); - } - - /* Test initializing from iterable. */ - { - hb_set_t s; - - s.add (18); - s.add (12); - - hb_vector_t v (s); - hb_set_t v0 (v); - hb_set_t v1 (s); - hb_set_t v2 (std::move (s)); - - assert (s.get_population () == 0); - assert (v0.get_population () == 2); - assert (v1.get_population () == 2); - assert (v2.get_population () == 2); - } - - /* Test initializing from iterator. */ - { - hb_set_t s; - - s.add (18); - s << 12; - - /* Sink a range. */ - s << hb_codepoint_pair_t {1, 3}; - - hb_set_t v (hb_iter (s)); - - assert (v.get_population () == 5); - } - - /* Test initializing from initializer list and swapping. */ - { - hb_set_t v1 {1, 2, 3}; - hb_set_t v2 {4, 5}; - hb_swap (v1, v2); - assert (v1.get_population () == 2); - assert (v2.get_population () == 3); - } - - /* Test inverted sets. */ - { - hb_set_t s; - s.invert(); - s.del (5); - - hb_codepoint_t start = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID; - assert (s.next_range (&start, &last)); - assert (start == 0); - assert (last == 4); - assert (s.next_range (&start, &last)); - assert (start == 6); - assert (last == HB_SET_VALUE_INVALID - 1); - assert (!s.next_range (&start, &last)); - - start = HB_SET_VALUE_INVALID; - last = HB_SET_VALUE_INVALID; - assert (s.previous_range (&start, &last)); - assert (start == 6); - assert (last == HB_SET_VALUE_INVALID - 1); - assert (s.previous_range (&start, &last)); - assert (start == 0); - assert (last == 4); - assert (!s.previous_range (&start, &last)); - - assert (s.is_inverted ()); - /* Inverted set returns true for invalid value; oh well. */ - assert (s.has (HB_SET_VALUE_INVALID)); - } - - /* Adding HB_SET_VALUE_INVALID */ - { - hb_set_t s; - - s.add(HB_SET_VALUE_INVALID); - assert(!s.has(HB_SET_VALUE_INVALID)); - - s.clear(); - assert(!s.add_range(HB_SET_VALUE_INVALID - 2, HB_SET_VALUE_INVALID)); - assert(!s.has(HB_SET_VALUE_INVALID)); - - hb_codepoint_t array[] = {(unsigned) HB_SET_VALUE_INVALID, 0, 2}; - s.clear(); - s.add_array(array, 3); - assert(!s.has(HB_SET_VALUE_INVALID)); - assert(s.has(2)); - - hb_codepoint_t sorted_array[] = {0, 2, (unsigned) HB_SET_VALUE_INVALID}; - s.clear(); - s.add_sorted_array(sorted_array, 3); - assert(!s.has(HB_SET_VALUE_INVALID)); - assert(s.has(2)); - } - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-subset-instancer-solver.cc b/thirdparty/harfbuzz/upstream/test-subset-instancer-solver.cc deleted file mode 100644 index 06b71bdc1..000000000 --- a/thirdparty/harfbuzz/upstream/test-subset-instancer-solver.cc +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright © 2023 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Qunxin Liu - */ - -#include -#include "hb-subset-instancer-solver.hh" - -static inline bool approx (Triple a, Triple b) -{ - return abs (a.minimum - b.minimum) < 0.000001 && - abs (a.middle - b.middle) < 0.000001 && - abs (a.maximum - b.maximum) < 0.000001; -} - -static inline bool approx (double a, double b) -{ return abs (a - b) < 0.000001; } - -/* tests ported from - * https://github.com/fonttools/fonttools/blob/main/Tests/varLib/instancer/solver_test.py */ -int -main (int argc, char **argv) -{ - TripleDistances default_axis_distances{1.0, 1.0}; - /* Case 1 */ - { - /* pin axis*/ - Triple tent (0.0, 1.0, 1.0); - Triple axis_range (0.0, 0.0, 0.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 0); - } - - { - /* pin axis*/ - Triple tent (0.0, 1.0, 1.0); - Triple axis_range (0.5, 0.5, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 0.5); - assert (out[0].second == Triple ()); - } - - { - /* tent falls outside the new axis range */ - Triple tent (0.3, 0.5, 0.8); - Triple axis_range (0.1, 0.2, 0.3); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 0); - } - - /* Case 2 */ - { - Triple tent (0.0, 1.0, 1.0); - Triple axis_range (-1.0, 0.0, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 0.5); - assert (out[0].second == Triple (0.0, 1.0, 1.0)); - } - - /* Case 2 */ - { - Triple tent (0.0, 1.0, 1.0); - Triple axis_range (-1.0, 0.0, 0.75); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 0.75); - assert (out[0].second == Triple (0.0, 1.0, 1.0)); - } - - /* Without gain: */ - /* Case 3 */ - { - Triple tent (0.0, 0.2, 1.0); - Triple axis_range (-1.0, 0.0, 0.8); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (0.0, 0.25, 1.0)); - assert (approx (out[1].first, 0.250)); - assert (out[1].second == Triple (0.25, 1.0, 1.0)); - } - - /* Case 3 boundary */ - { - Triple tent (0.0, 0.4, 1.0); - Triple axis_range (-1.0, 0.0, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (0.0, 0.8, 1.0)); - assert (approx (out[1].first, 2.5/3)); - assert (out[1].second == Triple (0.8, 1.0, 1.0)); - } - - /* Case 4 */ - { - Triple tent (0.0, 0.25, 1.0); - Triple axis_range (-1.0, 0.0, 0.4); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (0.0, 0.625, 1.0)); - assert (approx (out[1].first, 0.80)); - assert (out[1].second == Triple (0.625, 1.0, 1.0)); - } - - /* Case 4 */ - { - Triple tent (0.25, 0.3, 1.05); - Triple axis_range (0.0, 0.2, 0.4); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (approx (out[0].second, Triple (0.25, 0.5, 1.0))); - assert (approx (out[1].first, 2.6 / 3)); - assert (approx (out[1].second, Triple (0.5, 1.0, 1.0))); - } - - /* Case 4 boundary */ - { - Triple tent (0.25, 0.5, 1.0); - Triple axis_range (0.0, 0.25, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (0.0, 1.0, 1.0)); - } - - /* With gain */ - /* Case 3a/1neg */ - { - Triple tent (0.0, 0.5, 1.0); - Triple axis_range (0.0, 0.5, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 3); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (out[1].first == -1.0); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - assert (out[2].first == -1.0); - assert (out[2].second == Triple (-1.0, -1.0, 0.0)); - } - - { - Triple tent (0.0, 0.5, 1.0); - Triple axis_range (0.0, 0.5, 0.75); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 3); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (out[1].first == -0.5); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - assert (out[2].first == -1.0); - assert (out[2].second == Triple (-1.0, -1.0, 0.0)); - } - - { - Triple tent (0.0, 0.50, 1.0); - Triple axis_range (0.0, 0.25, 0.8); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 4); - assert (out[0].first == 0.5); - assert (out[0].second == Triple ()); - assert (out[1].first == 0.5); - assert (approx (out[1].second, Triple (0.0, 0.454545, 0.909091))); - assert (approx (out[2].first, -0.1)); - assert (approx (out[2].second, Triple (0.909091, 1.0, 1.0))); - assert (out[3].first == -0.5); - assert (out[3].second == Triple (-1.0, -1.0, 0.0)); - } - - /* Case 3a/1neg */ - { - Triple tent (0.0, 0.5, 2.0); - Triple axis_range (0.2, 0.5, 0.8); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 3); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (approx (out[1].first, -0.2)); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - assert (approx (out[2].first, -0.6)); - assert (out[2].second == Triple (-1.0, -1.0, 0.0)); - } - - /* Case 3a/1neg */ - { - Triple tent (0.0, 0.5, 2.0); - Triple axis_range (0.2, 0.5, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 3); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (approx (out[1].first, -1.0/3)); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - assert (approx (out[2].first, -0.6)); - assert (out[2].second == Triple (-1.0, -1.0, 0.0)); - } - - /* Case 3 */ - { - Triple tent (0.0, 0.5, 1.0); - Triple axis_range (0.25, 0.25, 0.75); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 0.5); - assert (out[0].second == Triple ()); - assert (out[1].first == 0.5); - assert (out[1].second == Triple (0.0, 0.5, 1.0)); - } - - /* Case 1neg */ - { - Triple tent (0.0, 0.5, 1.0); - Triple axis_range (0.0, 0.25, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 3); - assert (out[0].first == 0.5); - assert (out[0].second == Triple ()); - assert (out[1].first == 0.5); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - assert (out[2].first == -0.5); - assert (out[2].second == Triple (-1.0, -1.0, 0.0)); - } - - /* Case 2neg */ - { - Triple tent (0.05, 0.55, 1.0); - Triple axis_range (0.0, 0.25, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 4); - assert (approx (out[0].first, 0.4)); - assert (out[0].second == Triple ()); - assert (approx (out[1].first, 0.5)); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - assert (approx (out[2].first, -0.4)); - assert (out[2].second == Triple (-1.0, -0.8, 0.0)); - assert (approx (out[3].first, -0.4)); - assert (out[3].second == Triple (-1.0, -1.0, -0.8)); - } - - /* Case 2neg, other side */ - { - Triple tent (-1.0, -0.55, -0.05); - Triple axis_range (-0.5, -0.25, 0.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 4); - assert (approx (out[0].first, 0.4)); - assert (out[0].second == Triple ()); - assert (approx (out[1].first, 0.5)); - assert (out[1].second == Triple (-1.0, -1.0, 0.0)); - assert (approx (out[2].first, -0.4)); - assert (out[2].second == Triple (0.0, 0.8, 1.0)); - assert (approx (out[3].first, -0.4)); - assert (out[3].second == Triple (0.8, 1.0, 1.0)); - } - - /* Misc corner cases */ - { - Triple tent (0.5, 0.5, 0.5); - Triple axis_range (0.5, 0.5, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - } - - { - Triple tent (0.3, 0.5, 0.7); - Triple axis_range (0.1, 0.5, 0.9); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 5); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (out[1].first == -1.0); - assert (approx(out[1].second, Triple (0.0, 0.5, 1.0))); - assert (out[2].first == -1.0); - assert (approx(out[2].second, Triple (0.5, 1.0, 1.0))); - assert (out[3].first == -1.0); - assert (approx (out[3].second, Triple (-1.0, -0.5, 0.0))); - assert (out[4].first == -1.0); - assert (approx (out[4].second, Triple (-1.0, -1.0, -0.5))); - } - - { - Triple tent (0.5, 0.5, 0.5); - Triple axis_range (0.25, 0.25, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (1.0, 1.0, 1.0)); - } - - { - Triple tent (0.5, 0.5, 0.5); - Triple axis_range (0.25, 0.35, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (1.0, 1.0, 1.0)); - } - - { - Triple tent (0.5, 0.5, 0.55); - Triple axis_range (0.25, 0.35, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (1.0, 1.0, 1.0)); - } - - { - Triple tent (0.5, 0.5, 1.0); - Triple axis_range (0.5, 0.5, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (out[1].first == -1.0); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - } - - { - Triple tent (0.25, 0.5, 1.0); - Triple axis_range (0.5, 0.5, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (out[1].first == -1.0); - assert (out[1].second == Triple (0.0, 1.0, 1.0)); - } - - { - Triple tent (0.0, 0.2, 1.0); - Triple axis_range (0.0, 0.0, 0.5); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 2); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (0.0, 0.4, 1.0)); - assert (out[1].first == 0.625); - assert (out[1].second == Triple (0.4, 1.0, 1.0)); - } - - - { - Triple tent (0.0, 0.5, 1.0); - Triple axis_range (-1.0, 0.25, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 5); - assert (out[0].first == 0.5); - assert (out[0].second == Triple ()); - assert (out[1].first == 0.5); - assert (out[1].second == Triple (0.0, 1.0/3, 2.0/3)); - assert (out[2].first == -0.5); - assert (out[2].second == Triple (2.0/3, 1.0, 1.0)); - assert (out[3].first == -0.5); - assert (out[3].second == Triple (-1.0, -0.2, 0.0)); - assert (out[4].first == -0.5); - assert (out[4].second == Triple (-1.0, -1.0, -0.2)); - } - - { - Triple tent (0.5, 0.5, 0.5); - Triple axis_range (0.0, 0.5, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 5); - assert (out[0].first == 1.0); - assert (out[0].second == Triple ()); - assert (out[1].first == -1.0); - assert (out[1].second == Triple (0.0, 2/(double) (1 << 14), 1.0)); - assert (out[2].first == -1.0); - assert (out[2].second == Triple (2/(double) (1 << 14), 1.0, 1.0)); - assert (out[3].first == -1.0); - assert (out[3].second == Triple (-1.0, -2/(double) (1 << 14), 0.0)); - assert (out[4].first == -1.0); - assert (out[4].second == Triple (-1.0, -1.0, -2/(double) (1 << 14))); - } - - { - Triple tent (0.0, 1.0, 1.0); - Triple axis_range (-1.0, -0.5, 1.0); - rebase_tent_result_t out = rebase_tent (tent, axis_range, default_axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (1.0/3, 1.0, 1.0)); - } - - { - Triple tent (0.0, 1.0, 1.0); - Triple axis_range (-1.0, -0.5, 1.0); - TripleDistances axis_distances{2.0, 1.0}; - rebase_tent_result_t out = rebase_tent (tent, axis_range, axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (out[0].second == Triple (0.5, 1.0, 1.0)); - } - - { - Triple tent (0.6, 0.7, 0.8); - Triple axis_range (-1.0, 0.2, 1.0); - TripleDistances axis_distances{1.0, 1.0}; - rebase_tent_result_t out = rebase_tent (tent, axis_range, axis_distances); - assert (out.length == 1); - assert (out[0].first == 1.0); - assert (approx (out[0].second, Triple (0.5, 0.625, 0.75))); - } -} diff --git a/thirdparty/harfbuzz/upstream/test-tuple-varstore.cc b/thirdparty/harfbuzz/upstream/test-tuple-varstore.cc deleted file mode 100644 index 1e07d27d3..000000000 --- a/thirdparty/harfbuzz/upstream/test-tuple-varstore.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ -#include "hb-ot-var-cvar-table.hh" - -// cvar table data from Multi-ABC.ttf -const unsigned char cvar_data[] = "\x0\x1\x0\x0\x0\x2\x0\x14\x0\x51\xa0\x0\xc0\x0\x0\x54\xa0\x0\x40\x0\x2a\x29\x17\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\xd\xff\x0\xfd\x1\x0\xff\x0\xfd\x1\x0\xdb\xdb\xe6\xe6\x82\x0\xfd\x84\x6\xfd\x0\x2\xe3\xe3\xec\xec\x82\x4\x1\xe3\xe3\xec\xec\x82\x0\x1\x2a\x29\x17\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\xd\x1\x0\x5\xfd\x0\x1\x0\x5\xfd\x0\x61\x61\x44\x44\x82\x0\x5\x81\x9\x1\xff\x1\x7\xff\xfb\x49\x49\x35\x35\x82\x4\xff\x49\x49\x35\x35\x82\x0\xff"; - -static void -test_decompile_cvar () -{ - const OT::cvar* cvar_table = reinterpret_cast (cvar_data); - unsigned point_count = 65; - unsigned axis_count = 1; - - hb_tag_t axis_tag = HB_TAG ('w', 'g', 'h', 't'); - hb_map_t axis_idx_tag_map; - axis_idx_tag_map.set (0, axis_tag); - - OT::TupleVariationData::tuple_variations_t tuple_variations; - hb_vector_t shared_indices; - OT::TupleVariationData::tuple_iterator_t iterator; - - const OT::TupleVariationData* tuple_var_data = reinterpret_cast (cvar_data + 4); - - unsigned len = sizeof (cvar_data); - hb_bytes_t var_data_bytes{(const char* ) cvar_data + 4, len - 4}; - bool result = OT::TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, cvar_table, - shared_indices, &iterator); - assert (result); - - result = tuple_var_data->decompile_tuple_variations (point_count, false, iterator, &axis_idx_tag_map, - shared_indices, hb_array (), - tuple_variations); - - assert (result); - assert (tuple_variations.tuple_vars.length == 2); - for (unsigned i = 0; i < 2; i++) - { - assert (tuple_variations.tuple_vars[i].axis_tuples.get_population () == 1); - assert (!tuple_variations.tuple_vars[i].deltas_y); - assert (tuple_variations.tuple_vars[i].indices.length == 65); - assert (tuple_variations.tuple_vars[i].indices.length == tuple_variations.tuple_vars[i].deltas_x.length); - } - assert (tuple_variations.tuple_vars[0].axis_tuples.get (axis_tag) == Triple (-1.0, -1.0, 0.0)); - assert (tuple_variations.tuple_vars[1].axis_tuples.get (axis_tag) == Triple (0.0, 1.0, 1.0)); - - hb_vector_t deltas_1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -3.0, 1.0, 0.0, -1.0, 0.0, -3.0, 1.0, 0.0, -37.0, -37.0, -26.0, -26.0, 0.0, 0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 0.0, -3.0, 0.0, 2.0, -29.0, -29.0, -20.0, -20.0, 0.0, 0.0, 0.0, 1.0, -29.0, -29.0, -20.0, -20.0, 0.0, 0.0, 0.0, 1.0}; - for (unsigned i = 0; i < 65; i++) - { - if (i < 23) - assert (tuple_variations.tuple_vars[0].indices[i] == 0); - else - { - assert (tuple_variations.tuple_vars[0].indices[i] == 1); - assert (tuple_variations.tuple_vars[0].deltas_x[i] == deltas_1[i]); - } - } - - hb_vector_t deltas_2 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 5.0, -3.0, 0.0, 1.0, 0.0, 5.0, -3.0, 0.0, 97.0, 97.0, 68.0, 68.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 1.0, -1.0, 1.0, 7.0, -1.0, -5.0, 73.0, 73.0, 53.0, 53.0, 0.0, 0.0, 0.0, -1.0, 73.0, 73.0, 53.0, 53.0, 0.0, 0.0, 0.0, -1.0}; - for (unsigned i = 0 ; i < 65; i++) - { - if (i < 23) - assert (tuple_variations.tuple_vars[1].indices[i] == 0); - else - { - assert (tuple_variations.tuple_vars[1].indices[i] == 1); - assert (tuple_variations.tuple_vars[1].deltas_x[i] == deltas_2[i]); - } - } - - /* partial instancing wght=300:800 */ - hb_hashmap_t normalized_axes_location; - normalized_axes_location.set (axis_tag, Triple (-0.512817, 0.0, 0.700012)); - - hb_hashmap_t axes_triple_distances; - axes_triple_distances.set (axis_tag, TripleDistances (1.0, 1.0)); - - tuple_variations.instantiate (normalized_axes_location, axes_triple_distances); - - assert (tuple_variations.tuple_vars[0].indices.length == 65); - assert (tuple_variations.tuple_vars[1].indices.length == 65); - assert (!tuple_variations.tuple_vars[0].deltas_y); - assert (!tuple_variations.tuple_vars[1].deltas_y); - assert (tuple_variations.tuple_vars[0].axis_tuples.get (axis_tag) == Triple (-1.0, -1.0, 0.0)); - assert (tuple_variations.tuple_vars[1].axis_tuples.get (axis_tag) == Triple (0.0, 1.0, 1.0)); - - hb_vector_t rounded_deltas_1 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1, 0.0, -2, 1, 0.0, -1, 0.0, -2, 1, 0.0, -19, -19, -13, -13, 0.0, 0.0, 0.0, -2, 0.0, 0.0, 0.0, 0.0, 0.0, -2, 0.0, 1, -15, -15, -10.0, -10.0, 0.0, 0.0, 0.0, 1, -15, -15, -10.0, -10.0, 0.0, 0.0, 0.0, 1}; - - hb_vector_t rounded_deltas_2 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, 0.0, 4, -2, 0.0, 1, 0.0, 4, -2, 0.0, 68, 68, 48, 48, 0.0, 0.0, 0.0, 4, 0.0, 0.0, 1, -1, 1, 5, -1, -4, 51, 51, 37, 37, 0.0, 0.0, 0.0, -1, 51, 51, 37, 37, 0.0, 0.0, 0.0, -1}; - - for (unsigned i = 0; i < 65; i++) - { - if (i < 23) - { - assert (tuple_variations.tuple_vars[0].indices[i] == 0); - assert (tuple_variations.tuple_vars[1].indices[i] == 0); - } - else - { - assert (tuple_variations.tuple_vars[0].indices[i] == 1); - assert (tuple_variations.tuple_vars[1].indices[i] == 1); - assert (roundf (tuple_variations.tuple_vars[0].deltas_x[i]) == rounded_deltas_1[i]); - assert (roundf (tuple_variations.tuple_vars[1].deltas_x[i]) == rounded_deltas_2[i]); - } - } - - hb_map_t axes_index_map; - axes_index_map.set (0, 0); - bool res = tuple_variations.compile_bytes (axes_index_map, axis_idx_tag_map, false); - assert (res); - assert (tuple_variations.tuple_vars[0].compiled_tuple_header.length == 6); - const unsigned char tuple_var_header_1[] = "\x0\x51\xa0\x0\xc0\x0"; - for (unsigned i = 0; i < 6; i++) - assert(tuple_variations.tuple_vars[0].compiled_tuple_header.arrayZ[i] == tuple_var_header_1[i]); - - assert (tuple_variations.tuple_vars[1].compiled_tuple_header.length == 6); - const unsigned char tuple_var_header_2[] = "\x0\x54\xa0\x0\x40\x0"; - for (unsigned i = 0; i < 6; i++) - assert(tuple_variations.tuple_vars[1].compiled_tuple_header.arrayZ[i] == tuple_var_header_2[i]); - - assert (tuple_variations.tuple_vars[0].compiled_deltas.length == 37); - assert (tuple_variations.tuple_vars[1].compiled_deltas.length == 40); - const unsigned char compiled_deltas_1[] = "\x0d\xff\x00\xfe\x01\x00\xff\x00\xfe\x01\x00\xed\xed\xf3\xf3\x82\x00\xfe\x84\x06\xfe\x00\x01\xf1\xf1\xf6\xf6\x82\x04\x01\xf1\xf1\xf6\xf6\x82\x00\x01"; - for (unsigned i = 0; i < 37; i++) - assert (tuple_variations.tuple_vars[0].compiled_deltas.arrayZ[i] == compiled_deltas_1[i]); - - const unsigned char compiled_deltas_2[] = "\x0d\x01\x00\x04\xfe\x00\x01\x00\x04\xfe\x00\x44\x44\x30\x30\x82\x00\x04\x81\x09\x01\xff\x01\x05\xff\xfc\x33\x33\x25\x25\x82\x04\xff\x33\x33\x25\x25\x82\x00\xff"; - for (unsigned i = 0; i < 40; i++) - assert (tuple_variations.tuple_vars[1].compiled_deltas.arrayZ[i] == compiled_deltas_2[i]); -} - -int -main (int argc, char **argv) -{ - test_decompile_cvar (); -} diff --git a/thirdparty/harfbuzz/upstream/test-use-table.cc b/thirdparty/harfbuzz/upstream/test-use-table.cc deleted file mode 100644 index 70d2d41f4..000000000 --- a/thirdparty/harfbuzz/upstream/test-use-table.cc +++ /dev/null @@ -1,18 +0,0 @@ -#include "hb-ot-shaper-use-table.hh" - -int main (int argc, char **argv) -{ - if (argc != 2) - { - for (unsigned u = 0; u < 0x10FFFFu; u++) - printf ("U+%04X %d\n", u, hb_use_get_category (u)); - return 0; - } - - hb_codepoint_t u; - sscanf (argv[1], "%x", &u); - - printf ("%d\n", hb_use_get_category (u)); - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/test-vector.cc b/thirdparty/harfbuzz/upstream/test-vector.cc deleted file mode 100644 index cc8ceabd1..000000000 --- a/thirdparty/harfbuzz/upstream/test-vector.cc +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright © 2021 Behdad Esfahbod - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ - -#include "hb.hh" -#include "hb-vector.hh" -#include "hb-set.hh" -#include "hb-map.hh" -#include - - -int -main (int argc, char **argv) -{ - assert (sizeof (hb_vector_t) == sizeof (hb_sorted_vector_t)); - - /* Test copy constructor. */ - { - hb_vector_t v1 {1, 2}; - hb_vector_t v2 {v1}; - hb_vector_t V2 {v1}; - assert (v1.length == 2); - assert (v1[0] == 1); - assert (v1[1] == 2); - assert (v2.length == 2); - assert (v2[0] == 1); - assert (v2[1] == 2); - } - - /* Test copy assignment. */ - { - hb_vector_t v1 {1, 2}; - hb_vector_t v2 = v1; - hb_vector_t V2 = v1; - assert (v1.length == 2); - assert (v1[0] == 1); - assert (v1[1] == 2); - assert (v2.length == 2); - assert (v2[0] == 1); - assert (v2[1] == 2); - } - - /* Test move constructor. */ - { - hb_vector_t s {1, 2}; - hb_sorted_vector_t S {1, 2}; - hb_vector_t v (std::move (s)); - hb_sorted_vector_t V (std::move (S)); - assert (s.length == 0); - assert (S.length == 0); - assert (v.length == 2); - assert (v[0] == 1); - assert (v[1] == 2); - } - - /* Test move assignment. */ - { - hb_vector_t s {1, 2}; - hb_sorted_vector_t S {1, 2}; - hb_vector_t v; - hb_sorted_vector_t V; - v = std::move (s); - V = std::move (S); - assert (s.length == 0); - assert (S.length == 0); - assert (v.length == 2); - assert (V.length == 2); - assert (v[0] == 1); - assert (v[1] == 2); - } - - /* Test initializing from iterable. */ - { - hb_set_t s; - - s.add (18); - s.add (12); - - hb_vector_t v (s); - hb_sorted_vector_t V (s); - - assert (v.length == 2); - assert (V.length == 2); - assert (v[0] == 12); - assert (V[0] == 12); - assert (v[1] == 18); - assert (V[1] == 18); - } - - /* Test initializing from iterator. */ - { - hb_set_t s; - - s.add (18); - s.add (12); - - hb_vector_t v (hb_iter (s)); - hb_vector_t V (hb_iter (s)); - - assert (v.length == 2); - assert (V.length == 2); - assert (v[0] == 12); - assert (V[0] == 12); - assert (v[1] == 18); - assert (V[1] == 18); - } - - /* Test initializing from initializer list and swapping. */ - { - hb_vector_t v1 {1, 2, 3}; - hb_vector_t v2 {4, 5}; - hb_swap (v1, v2); - assert (v1.length == 2); - assert (v1[0] == 4); - assert (v2.length == 3); - assert (v2[2] == 3); - } - - /* Test initializing sorted-vector from initializer list and swapping. */ - { - hb_sorted_vector_t v1 {1, 2, 3}; - hb_sorted_vector_t v2 {4, 5}; - hb_swap (v1, v2); - assert (v1.length == 2); - assert (v1[0] == 4); - assert (v2.length == 3); - assert (v2[2] == 3); - } - - { - hb_vector_t v; - - std::string s; - for (unsigned i = 1; i < 100; i++) - { - s += "x"; - v.push (s); - } - - hb_vector_t v2; - - v2 = v; - - v2.remove_ordered (50); - v2.remove_unordered (50); - } - - { - hb_vector_t v; - hb_set_t s {1, 5, 7}; - v.push (s); - v << s; - assert (s.get_population () == 3); - v << std::move (s); - assert (s.get_population () == 0); - } - - { - hb_vector_t v; - hb_map_t m; - v.push (m); - } - { - hb_vector_t v; - hb_map_t m; - v.push (m); - } - - return 0; -} diff --git a/thirdparty/harfbuzz/upstream/update-unicode-tables.make b/thirdparty/harfbuzz/upstream/update-unicode-tables.make deleted file mode 100755 index 6f5b490f7..000000000 --- a/thirdparty/harfbuzz/upstream/update-unicode-tables.make +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env -S make -f - -all: packtab \ - hb-ot-shaper-arabic-joining-list.hh \ - hb-ot-shaper-arabic-table.hh hb-unicode-emoji-table.hh \ - hb-ot-shaper-indic-table.cc hb-ot-tag-table.hh \ - hb-ucd-table.hh hb-ot-shaper-use-table.hh \ - hb-ot-shaper-vowel-constraints.cc - -.PHONY: all clean packtab - -hb-ot-shaper-arabic-joining-list.hh: gen-arabic-joining-list.py ArabicShaping.txt Scripts.txt - ./$^ > $@ || ($(RM) $@; false) -hb-ot-shaper-arabic-table.hh: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt - ./$^ > $@ || ($(RM) $@; false) -hb-unicode-emoji-table.hh: gen-emoji-table.py emoji-data.txt emoji-test.txt - ./$^ > $@ || ($(RM) $@; false) -hb-ot-shaper-indic-table.cc: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt - ./$^ > $@ || ($(RM) $@; false) -hb-ot-tag-table.hh: gen-tag-table.py languagetags language-subtag-registry - ./$^ > $@ || ($(RM) $@; false) -hb-ucd-table.hh: gen-ucd-table.py ucd.nounihan.grouped.zip hb-common.h - ./$^ > $@ || ($(RM) $@; false) -hb-ot-shaper-use-table.hh: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt ms-use/IndicSyllabicCategory-Additional.txt ms-use/IndicPositionalCategory-Additional.txt - ./$^ > $@ || ($(RM) $@; false) -hb-ot-shaper-vowel-constraints.cc: gen-vowel-constraints.py ms-use/IndicShapingInvalidCluster.txt Scripts.txt - ./$^ > $@ || ($(RM) $@; false) - -packtab: - /usr/bin/env python3 -c "import packTab" 2>/dev/null || /usr/bin/env python3 -m pip install git+https://github.com/harfbuzz/packtab - -ArabicShaping.txt Blocks.txt DerivedCoreProperties.txt IndicPositionalCategory.txt IndicSyllabicCategory.txt Scripts.txt UnicodeData.txt: - curl -O https://unicode.org/Public/UCD/latest/ucd/$@ -emoji-data.txt: - curl -O https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt -emoji-test.txt: - curl -O https://www.unicode.org/Public/emoji/latest/emoji-test.txt -languagetags: - curl -O https://learn.microsoft.com/en-us/typography/opentype/spec/languagetags -language-subtag-registry: - curl -O https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry -ucd.nounihan.grouped.zip: - curl -O https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip - -clean: - $(RM) \ - ArabicShaping.txt UnicodeData.txt Blocks.txt emoji-data.txt \ - IndicSyllabicCategory.txt IndicPositionalCategory.txt \ - languagetags language-subtag-registry ucd.nounihan.grouped.zip Scripts.txt diff --git a/thirdparty/harfbuzz/upstream/wasm/graphite/shape.cc b/thirdparty/harfbuzz/upstream/wasm/graphite/shape.cc new file mode 100644 index 000000000..f445049a4 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/wasm/graphite/shape.cc @@ -0,0 +1,250 @@ +#define HB_WASM_INTERFACE(ret_t, name) __attribute__((export_name(#name))) ret_t name + +#include + +#include + +#include +#include + +void debugprint1 (char *s, int32_t); +void debugprint2 (char *s, int32_t, int32_t); + +static const void *copy_table (const void *data, unsigned int tag, size_t *len) +{ + face_t *face = (face_t *) data; + blob_t blob = BLOB_INIT; + if (!face_copy_table (face, tag, &blob)) + abort (); + + *len = blob.length; + return blob.data; +} + +static void free_table (const void *data, const void *table_data) +{ + blob_t blob; + blob.length = 0; // Doesn't matter + blob.data = (char *) table_data; + blob_free (&blob); +} + +void * +shape_plan_create (face_t *face) +{ + const gr_face_ops ops = {sizeof (gr_face_ops), ©_table, &free_table}; + gr_face *grface = gr_make_face_with_ops (face, &ops, gr_face_preloadAll); + return grface; +} + +void +shape_plan_destroy (void *data) +{ + gr_face_destroy ((gr_face *) data); +} + +bool_t +shape (void *shape_plan, + font_t *font, + buffer_t *buffer, + const feature_t *features, + uint32_t num_features) +{ + face_t *face = font_get_face (font); + gr_face *grface = (gr_face *) shape_plan; + + direction_t direction = buffer_get_direction (buffer); + direction_t horiz_dir = script_get_horizontal_direction (buffer_get_script (buffer)); + /* TODO vertical: + * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType + * Ogham fonts are supposed to be implemented BTT or not. Need to research that + * first. */ + if ((DIRECTION_IS_HORIZONTAL (direction) && + direction != horiz_dir && horiz_dir != DIRECTION_INVALID) || + (DIRECTION_IS_VERTICAL (direction) && + direction != DIRECTION_TTB)) + { + buffer_reverse_clusters (buffer); + direction = DIRECTION_REVERSE (direction); + } + + buffer_contents_t contents = BUFFER_CONTENTS_INIT; + if (!buffer_copy_contents (buffer, &contents)) + return false; + + gr_segment *seg = nullptr; + const gr_slot *is; + unsigned int ci = 0, ic = 0; + unsigned int curradvx = 0, curradvy = 0; + unsigned length = contents.length; + + uint32_t *chars = (uint32_t *) malloc (length * sizeof (uint32_t)); + if (!chars) + return false; + for (unsigned int i = 0; i < contents.length; ++i) + chars[i] = contents.info[i].codepoint; + + seg = gr_make_seg (nullptr, grface, + 0, // https://github.com/harfbuzz/harfbuzz/issues/3439#issuecomment-1442650148 + nullptr, + gr_utf32, chars, contents.length, + 2 | (direction == DIRECTION_RTL ? 1 : 0)); + + free (chars); + + if (!seg) + return false; + + unsigned int glyph_count = gr_seg_n_slots (seg); + + struct cluster_t { + unsigned int base_char; + unsigned int num_chars; + unsigned int base_glyph; + unsigned int num_glyphs; + unsigned int cluster; + int advance; + }; + + length = glyph_count; + if (!buffer_contents_realloc (&contents, length)) + return false; + cluster_t *clusters = (cluster_t *) malloc (length * sizeof (cluster_t)); + uint32_t *gids = (uint32_t *) malloc (length * sizeof (uint32_t)); + if (!clusters || !gids) + { + free (clusters); + free (gids); + return false; + } + + memset (clusters, 0, sizeof (clusters[0]) * length); + codepoint_t *pg = gids; + clusters[0].cluster = contents.info[0].cluster; + unsigned int upem = face_get_upem (face); + int32_t font_x_scale, font_y_scale; + font_get_scale (font, &font_x_scale, &font_y_scale); + float xscale = (float) font_x_scale / upem; + float yscale = (float) font_y_scale / upem; + yscale *= yscale / xscale; + unsigned int curradv = 0; + if (DIRECTION_IS_BACKWARD (direction)) + { + curradv = gr_slot_origin_X(gr_seg_first_slot(seg)) * xscale; + clusters[0].advance = gr_seg_advance_X(seg) * xscale - curradv; + } + else + clusters[0].advance = 0; + for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++) + { + unsigned int before = gr_slot_before (is); + unsigned int after = gr_slot_after (is); + *pg = gr_slot_gid (is); + pg++; + while (clusters[ci].base_char > before && ci) + { + clusters[ci-1].num_chars += clusters[ci].num_chars; + clusters[ci-1].num_glyphs += clusters[ci].num_glyphs; + clusters[ci-1].advance += clusters[ci].advance; + ci--; + } + + if (gr_slot_can_insert_before (is) && clusters[ci].num_chars && before >= clusters[ci].base_char + clusters[ci].num_chars) + { + cluster_t *c = clusters + ci + 1; + c->base_char = clusters[ci].base_char + clusters[ci].num_chars; + c->cluster = contents.info[c->base_char].cluster; + c->num_chars = before - c->base_char; + c->base_glyph = ic; + c->num_glyphs = 0; + if (DIRECTION_IS_BACKWARD (direction)) + { + c->advance = curradv - gr_slot_origin_X(is) * xscale; + curradv -= c->advance; + } + else + { + auto origin_X = gr_slot_origin_X (is) * xscale; + c->advance = 0; + clusters[ci].advance += origin_X - curradv; + curradv = origin_X; + } + ci++; + } + clusters[ci].num_glyphs++; + + if (clusters[ci].base_char + clusters[ci].num_chars < after + 1) + clusters[ci].num_chars = after + 1 - clusters[ci].base_char; + } + + if (DIRECTION_IS_BACKWARD (direction)) + clusters[ci].advance += curradv; + else + clusters[ci].advance += gr_seg_advance_X(seg) * xscale - curradv; + ci++; + + for (unsigned int i = 0; i < ci; ++i) + { + for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j) + { + glyph_info_t *info = &contents.info[clusters[i].base_glyph + j]; + info->codepoint = gids[clusters[i].base_glyph + j]; + info->cluster = clusters[i].cluster; + info->var1 = (unsigned) clusters[i].advance; // all glyphs in the cluster get the same advance + } + } + contents.length = glyph_count; + + /* Positioning. */ + unsigned int currclus = 0xFFFFFFFF; + const glyph_info_t *info = contents.info; + glyph_position_t *pPos = contents.pos; + if (!DIRECTION_IS_BACKWARD (direction)) + { + curradvx = 0; + for (is = gr_seg_first_slot (seg); is; pPos++, ++info, is = gr_slot_next_in_segment (is)) + { + pPos->x_offset = gr_slot_origin_X (is) * xscale - curradvx; + pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; + if (info->cluster != currclus) { + pPos->x_advance = (int) info->var1; + curradvx += pPos->x_advance; + currclus = info->cluster; + } else + pPos->x_advance = 0.; + + pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale; + curradvy += pPos->y_advance; + } + buffer_set_contents (buffer, &contents); + } + else + { + curradvx = gr_seg_advance_X(seg) * xscale; + for (is = gr_seg_first_slot (seg); is; pPos++, info++, is = gr_slot_next_in_segment (is)) + { + if (info->cluster != currclus) + { + pPos->x_advance = (int) info->var1; + curradvx -= pPos->x_advance; + currclus = info->cluster; + } else + pPos->x_advance = 0.; + + pPos->y_advance = gr_slot_advance_Y (is, grface, nullptr) * yscale; + curradvy -= pPos->y_advance; + pPos->x_offset = gr_slot_origin_X (is) * xscale - (int) info->var1 - curradvx + pPos->x_advance; + pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; + } + buffer_set_contents (buffer, &contents); + buffer_reverse_clusters (buffer); + } + + gr_seg_destroy (seg); + free (clusters); + free (gids); + + bool ret = glyph_count; + + return ret; +} diff --git a/thirdparty/harfbuzz/upstream/wasm/sample/c/shape-fallback.cc b/thirdparty/harfbuzz/upstream/wasm/sample/c/shape-fallback.cc new file mode 100644 index 000000000..7787bbae7 --- /dev/null +++ b/thirdparty/harfbuzz/upstream/wasm/sample/c/shape-fallback.cc @@ -0,0 +1,60 @@ +#define HB_WASM_INTERFACE(ret_t, name) __attribute__((export_name(#name))) ret_t name + +#include + +extern "C" { +void debugprint (const char *s); +void debugprint1 (const char *s, int32_t); +void debugprint2 (const char *s, int32_t, int32_t); +} + +bool_t +shape (void *shape_plan, + font_t *font, + buffer_t *buffer, + const feature_t *features, + uint32_t num_features) +{ + face_t *face = font_get_face (font); + + blob_t blob = BLOB_INIT; + face_copy_table (face, TAG ('c','m','a','p'), &blob); + + debugprint1 ("cmap length", blob.length); + + blob_free (&blob); + + buffer_contents_t contents = BUFFER_CONTENTS_INIT; + if (!buffer_copy_contents (buffer, &contents)) + return false; + + debugprint1 ("buffer length", contents.length); + + glyph_outline_t outline = GLYPH_OUTLINE_INIT; + + for (unsigned i = 0; i < contents.length; i++) + { + char name[64]; + + debugprint1 ("glyph at", i); + + font_glyph_to_string (font, contents.info[i].codepoint, name, sizeof (name)); + + debugprint (name); + + contents.info[i].codepoint = font_get_glyph (font, contents.info[i].codepoint, 0); + contents.pos[i].x_advance = font_get_glyph_h_advance (font, contents.info[i].codepoint); + + font_copy_glyph_outline (font, contents.info[i].codepoint, &outline); + debugprint1 ("num outline points", outline.n_points); + debugprint1 ("num outline contours", outline.n_contours); + } + + glyph_outline_free (&outline); + + bool_t ret = buffer_set_contents (buffer, &contents); + + buffer_contents_free (&contents); + + return ret; +} diff --git a/thirdparty/harfbuzz/upstream/wasm/sample/c/shape-ot.cc b/thirdparty/harfbuzz/upstream/wasm/sample/c/shape-ot.cc new file mode 100644 index 000000000..9081cfebc --- /dev/null +++ b/thirdparty/harfbuzz/upstream/wasm/sample/c/shape-ot.cc @@ -0,0 +1,18 @@ +#define HB_WASM_INTERFACE(ret_t, name) __attribute__((export_name(#name))) ret_t name + +#include + +extern "C" { +void debugprint1 (const char *s, int32_t); +void debugprint2 (const char *s, int32_t, int32_t); +} + +bool_t +shape (void *shape_plan, + font_t *font, + buffer_t *buffer, + const feature_t *features, + uint32_t num_features) +{ + return shape_with (font, buffer, features, num_features, "ot"); +} diff --git a/thirdparty/libhydrogen/libhydrogen.c b/thirdparty/libhydrogen/libhydrogen.c new file mode 100644 index 000000000..fc8272399 --- /dev/null +++ b/thirdparty/libhydrogen/libhydrogen.c @@ -0,0 +1,24 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "libhydrogen.h" + +#include "upstream/libhydrogen.c" diff --git a/thirdparty/libhydrogen/libhydrogen.h b/thirdparty/libhydrogen/libhydrogen.h new file mode 100644 index 000000000..d06e234a6 --- /dev/null +++ b/thirdparty/libhydrogen/libhydrogen.h @@ -0,0 +1,45 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +/* + ============================================================================== + + BEGIN_YUP_MODULE_DECLARATION + + ID: libhydrogen + vendor: libhydrogen + version: 0.1 + name: libhydrogen + description: Small cryptographic library used by Rive scripting for signed content verification. + website: https://github.com/jedisct1/libhydrogen + license: ISC + + defines: HYDRO_SIGN_VERIFY_ONLY=1 + searchpaths: upstream + + END_YUP_MODULE_DECLARATION + + ============================================================================== +*/ + +#pragma once + +#include "upstream/libhydrogen.h" diff --git a/thirdparty/libhydrogen/upstream/impl/common.h b/thirdparty/libhydrogen/upstream/impl/common.h new file mode 100644 index 000000000..44175d130 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/common.h @@ -0,0 +1,334 @@ +#if defined(__linux__) && defined(__KERNEL__) +# define TLS /* Danger: at most one call into hydro_*() at a time */ +# define CHAR_BIT 8 +# define abort BUG +# define uint_fast16_t uint16_t +# define errno hydro_errno +static int errno; +#else +# include +# include +# include +# include +# include +# include +#endif + +#if defined (__CHERIOT__) +static int errno; +#endif + +#if !defined(__unix__) && (defined(__APPLE__) || defined(__linux__)) +# define __unix__ 1 +#endif +#ifndef __GNUC__ +# define __restrict__ +#endif + +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define NATIVE_BIG_ENDIAN +#endif +#ifndef NATIVE_BIG_ENDIAN +# ifndef NATIVE_LITTLE_ENDIAN +# define NATIVE_LITTLE_ENDIAN +# endif +#endif + +#ifndef TLS +# if defined(_WIN32) && !defined(__GNUC__) +# define TLS __declspec(thread) +# elif (defined(__clang__) || defined(__GNUC__)) && defined(__unix__) && !defined(__TINYC__) +# define TLS __thread +# else +# define TLS +# endif +#endif + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +#ifdef __OpenBSD__ +# define HAVE_EXPLICIT_BZERO 1 +#elif defined(__GLIBC__) && defined(__GLIBC_PREREQ) && defined(_GNU_SOURCE) +# if __GLIBC_PREREQ(2, 25) +# define HAVE_EXPLICIT_BZERO 1 +# endif +#endif + +#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1]) + +#define ROTL32(x, b) (uint32_t)(((x) << (b)) | ((x) >> (32 - (b)))) +#define ROTL64(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) +#define ROTR32(x, b) (uint32_t)(((x) >> (b)) | ((x) << (32 - (b)))) +#define ROTR64(x, b) (uint64_t)(((x) >> (b)) | ((x) << (64 - (b)))) + +#define LOAD64_LE(SRC) load64_le(SRC) +static inline uint64_t +load64_le(const uint8_t src[8]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[0]; + w |= (uint64_t) src[1] << 8; + w |= (uint64_t) src[2] << 16; + w |= (uint64_t) src[3] << 24; + w |= (uint64_t) src[4] << 32; + w |= (uint64_t) src[5] << 40; + w |= (uint64_t) src[6] << 48; + w |= (uint64_t) src[7] << 56; + return w; +#endif +} + +#define STORE64_LE(DST, W) store64_le((DST), (W)) +static inline void +store64_le(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; + w >>= 8; + dst[1] = (uint8_t) w; + w >>= 8; + dst[2] = (uint8_t) w; + w >>= 8; + dst[3] = (uint8_t) w; + w >>= 8; + dst[4] = (uint8_t) w; + w >>= 8; + dst[5] = (uint8_t) w; + w >>= 8; + dst[6] = (uint8_t) w; + w >>= 8; + dst[7] = (uint8_t) w; +#endif +} + +#define LOAD32_LE(SRC) load32_le(SRC) +static inline uint32_t +load32_le(const uint8_t src[4]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[0]; + w |= (uint32_t) src[1] << 8; + w |= (uint32_t) src[2] << 16; + w |= (uint32_t) src[3] << 24; + return w; +#endif +} + +#define STORE32_LE(DST, W) store32_le((DST), (W)) +static inline void +store32_le(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; + w >>= 8; + dst[1] = (uint8_t) w; + w >>= 8; + dst[2] = (uint8_t) w; + w >>= 8; + dst[3] = (uint8_t) w; +#endif +} + +#define LOAD16_LE(SRC) load16_le(SRC) +static inline uint16_t +load16_le(const uint8_t src[2]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint16_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint16_t w = (uint16_t) src[0]; + w |= (uint16_t) src[1] << 8; + return w; +#endif +} + +#define STORE16_LE(DST, W) store16_le((DST), (W)) +static inline void +store16_le(uint8_t dst[2], uint16_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; + w >>= 8; + dst[1] = (uint8_t) w; +#endif +} + +/* ----- */ + +#define LOAD64_BE(SRC) load64_be(SRC) +static inline uint64_t +load64_be(const uint8_t src[8]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[7]; + w |= (uint64_t) src[6] << 8; + w |= (uint64_t) src[5] << 16; + w |= (uint64_t) src[4] << 24; + w |= (uint64_t) src[3] << 32; + w |= (uint64_t) src[2] << 40; + w |= (uint64_t) src[1] << 48; + w |= (uint64_t) src[0] << 56; + return w; +#endif +} + +#define STORE64_BE(DST, W) store64_be((DST), (W)) +static inline void +store64_be(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[7] = (uint8_t) w; + w >>= 8; + dst[6] = (uint8_t) w; + w >>= 8; + dst[5] = (uint8_t) w; + w >>= 8; + dst[4] = (uint8_t) w; + w >>= 8; + dst[3] = (uint8_t) w; + w >>= 8; + dst[2] = (uint8_t) w; + w >>= 8; + dst[1] = (uint8_t) w; + w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define LOAD32_BE(SRC) load32_be(SRC) +static inline uint32_t +load32_be(const uint8_t src[4]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[3]; + w |= (uint32_t) src[2] << 8; + w |= (uint32_t) src[1] << 16; + w |= (uint32_t) src[0] << 24; + return w; +#endif +} + +#define STORE32_BE(DST, W) store32_be((DST), (W)) +static inline void +store32_be(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[3] = (uint8_t) w; + w >>= 8; + dst[2] = (uint8_t) w; + w >>= 8; + dst[1] = (uint8_t) w; + w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define LOAD16_BE(SRC) load16_be(SRC) +static inline uint16_t +load16_be(const uint8_t src[2]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint16_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint16_t w = (uint16_t) src[1]; + w |= (uint16_t) src[0] << 8; + return w; +#endif +} + +#define STORE16_BE(DST, W) store16_be((DST), (W)) +static inline void +store16_be(uint8_t dst[2], uint16_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[1] = (uint8_t) w; + w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +static inline void +mem_cpy(void *__restrict__ dst_, const void *__restrict__ src_, size_t n) +{ + unsigned char *dst = (unsigned char *) dst_; + const unsigned char *src = (const unsigned char *) src_; + size_t i; + + for (i = 0; i < n; i++) { + dst[i] = src[i]; + } +} + +static inline void +mem_zero(void *dst_, size_t n) +{ + unsigned char *dst = (unsigned char *) dst_; + size_t i; + + for (i = 0; i < n; i++) { + dst[i] = 0; + } +} + +static inline void +mem_xor(void *__restrict__ dst_, const void *__restrict__ src_, size_t n) +{ + unsigned char *dst = (unsigned char *) dst_; + const unsigned char *src = (const unsigned char *) src_; + size_t i; + + for (i = 0; i < n; i++) { + dst[i] ^= src[i]; + } +} + +static inline void +mem_xor2(void *__restrict__ dst_, const void *__restrict__ src1_, const void *__restrict__ src2_, + size_t n) +{ + unsigned char *dst = (unsigned char *) dst_; + const unsigned char *src1 = (const unsigned char *) src1_; + const unsigned char *src2 = (const unsigned char *) src2_; + size_t i; + + for (i = 0; i < n; i++) { + dst[i] = src1[i] ^ src2[i]; + } +} + +static const uint8_t zero[64] = { 0 }; diff --git a/thirdparty/libhydrogen/upstream/impl/core.h b/thirdparty/libhydrogen/upstream/impl/core.h new file mode 100644 index 000000000..0498ee5a2 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/core.h @@ -0,0 +1,221 @@ +int +hydro_init(void) +{ + hydro_random_ensure_initialized(); + return 0; +} + +void +hydro_memzero(void *pnt, size_t len) +{ +#ifdef HAVE_EXPLICIT_BZERO + explicit_bzero(pnt, len); +#else + volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile) pnt; + size_t i = (size_t) 0U; + + while (i < len) { + pnt_[i++] = 0U; + } +#endif +} + +void +hydro_increment(uint8_t *n, size_t len) +{ + size_t i; + uint_fast16_t c = 1U; + + for (i = 0; i < len; i++) { + c += (uint_fast16_t) n[i]; + n[i] = (uint8_t) c; + c >>= 8; + } +} + +char * +hydro_bin2hex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len) +{ + size_t i = (size_t) 0U; + unsigned int x; + int b; + int c; + + if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) { + abort(); + } + while (i < bin_len) { + c = bin[i] & 0xf; + b = bin[i] >> 4; + x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 | + (unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U)); + hex[i * 2U] = (char) x; + x >>= 8; + hex[i * 2U + 1U] = (char) x; + i++; + } + hex[i * 2U] = 0U; + + return hex; +} + +int +hydro_hex2bin(uint8_t *bin, size_t bin_maxlen, const char *hex, size_t hex_len, const char *ignore, + const char **hex_end_p) +{ + size_t bin_pos = (size_t) 0U; + size_t hex_pos = (size_t) 0U; + int ret = 0; + unsigned char c; + unsigned char c_alpha0, c_alpha; + unsigned char c_num0, c_num; + uint8_t c_acc = 0U; + uint8_t c_val; + unsigned char state = 0U; + + while (hex_pos < hex_len) { + c = (unsigned char) hex[hex_pos]; + c_num = c ^ 48U; + c_num0 = (c_num - 10U) >> 8; + c_alpha = (c & ~32U) - 55U; + c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8; + if ((c_num0 | c_alpha0) == 0U) { + if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) { + hex_pos++; + continue; + } + break; + } + c_val = (uint8_t) ((c_num0 & c_num) | (c_alpha0 & c_alpha)); + if (bin_pos >= bin_maxlen) { + ret = -1; + errno = ERANGE; + break; + } + if (state == 0U) { + c_acc = c_val * 16U; + } else { + bin[bin_pos++] = c_acc | c_val; + } + state = ~state; + hex_pos++; + } + if (state != 0U) { + hex_pos--; + errno = EINVAL; + ret = -1; + } + if (ret != 0) { + bin_pos = (size_t) 0U; + } + if (hex_end_p != NULL) { + *hex_end_p = &hex[hex_pos]; + } else if (hex_pos != hex_len) { + errno = EINVAL; + ret = -1; + } + if (ret != 0) { + return ret; + } + return (int) bin_pos; +} + +bool +hydro_equal(const void *b1_, const void *b2_, size_t len) +{ + const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_; + const uint8_t *b2 = (const uint8_t *) b2_; + size_t i; + uint8_t d = (uint8_t) 0U; + + if (b1 == b2) { + d = ~d; + } + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (bool) (1 & ((d - 1) >> 8)); +} + +int +hydro_compare(const uint8_t *b1_, const uint8_t *b2_, size_t len) +{ + const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_; + const uint8_t *b2 = (const uint8_t *) b2_; + uint8_t gt = 0U; + uint8_t eq = 1U; + size_t i; + + i = len; + while (i != 0U) { + i--; + gt |= ((b2[i] - b1[i]) >> 8) & eq; + eq &= ((b2[i] ^ b1[i]) - 1) >> 8; + } + return (int) (gt + gt + eq) - 1; +} + +int +hydro_pad(unsigned char *buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen) +{ + unsigned char *tail; + size_t i; + size_t xpadlen; + size_t xpadded_len; + volatile unsigned char mask; + unsigned char barrier_mask; + + if (blocksize <= 0U || max_buflen > INT_MAX) { + return -1; + } + xpadlen = blocksize - 1U; + if ((blocksize & (blocksize - 1U)) == 0U) { + xpadlen -= unpadded_buflen & (blocksize - 1U); + } else { + xpadlen -= unpadded_buflen % blocksize; + } + if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) { + return -1; + } + xpadded_len = unpadded_buflen + xpadlen; + if (xpadded_len >= max_buflen) { + return -1; + } + tail = &buf[xpadded_len]; + mask = 0U; + for (i = 0; i < blocksize; i++) { + barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT)); + *(tail - i) = ((*(tail - i)) & mask) | (0x80 & barrier_mask); + mask |= barrier_mask; + } + return (int) (xpadded_len + 1); +} + +int +hydro_unpad(const unsigned char *buf, size_t padded_buflen, size_t blocksize) +{ + const unsigned char *tail; + unsigned char acc = 0U; + unsigned char c; + unsigned char valid = 0U; + volatile size_t pad_len = 0U; + size_t i; + size_t is_barrier; + + if (padded_buflen < blocksize || blocksize <= 0U) { + return -1; + } + tail = &buf[padded_buflen - 1U]; + + for (i = 0U; i < blocksize; i++) { + c = *(tail - i); + is_barrier = (((acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U)) >> 8) & 1U; + acc |= c; + pad_len |= i & (1U + ~is_barrier); + valid |= (unsigned char) is_barrier; + } + if (valid == 0) { + return -1; + } + return (int) (padded_buflen - 1 - pad_len); +} diff --git a/thirdparty/libhydrogen/upstream/impl/gimli-core.h b/thirdparty/libhydrogen/upstream/impl/gimli-core.h new file mode 100644 index 000000000..83ee82ab8 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/gimli-core.h @@ -0,0 +1,25 @@ +#ifdef __SSE2__ +# include "gimli-core/sse2.h" +#else +# include "gimli-core/portable.h" +#endif + +static void +gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag) +{ + state_u8[gimli_BLOCKBYTES - 1] ^= tag; +#ifndef NATIVE_LITTLE_ENDIAN + uint32_t state_u32[12]; + int i; + + for (i = 0; i < 12; i++) { + state_u32[i] = LOAD32_LE(&state_u8[i * 4]); + } + gimli_core(state_u32); + for (i = 0; i < 12; i++) { + STORE32_LE(&state_u8[i * 4], state_u32[i]); + } +#else + gimli_core((uint32_t *) (void *) state_u8); /* state_u8 must be properly aligned */ +#endif +} diff --git a/thirdparty/libhydrogen/upstream/impl/gimli-core/portable.h b/thirdparty/libhydrogen/upstream/impl/gimli-core/portable.h new file mode 100644 index 000000000..db6b84cef --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/gimli-core/portable.h @@ -0,0 +1,39 @@ +static void +gimli_core(uint32_t state[gimli_BLOCKBYTES / 4]) +{ + unsigned int round; + unsigned int column; + uint32_t x; + uint32_t y; + uint32_t z; + + for (round = 24; round > 0; round--) { + for (column = 0; column < 4; column++) { + x = ROTL32(state[column], 24); + y = ROTL32(state[4 + column], 9); + z = state[8 + column]; + + state[8 + column] = x ^ (z << 1) ^ ((y & z) << 2); + state[4 + column] = y ^ x ^ ((x | z) << 1); + state[column] = z ^ y ^ ((x & y) << 3); + } + switch (round & 3) { + case 0: + x = state[0]; + state[0] = state[1]; + state[1] = x; + x = state[2]; + state[2] = state[3]; + state[3] = x; + state[0] ^= ((uint32_t) 0x9e377900 | round); + break; + case 2: + x = state[0]; + state[0] = state[2]; + state[2] = x; + x = state[1]; + state[1] = state[3]; + state[3] = x; + } + } +} diff --git a/thirdparty/libhydrogen/upstream/impl/gimli-core/sse2.h b/thirdparty/libhydrogen/upstream/impl/gimli-core/sse2.h new file mode 100644 index 000000000..0e6fce6b7 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/gimli-core/sse2.h @@ -0,0 +1,112 @@ +#include +#ifdef __SSSE3__ +# include +#endif + +#define S 9 + +static inline __m128i +shift(__m128i x, int bits) +{ + return _mm_slli_epi32(x, bits); +} + +static inline __m128i +rotate(__m128i x, int bits) +{ + return _mm_slli_epi32(x, bits) | _mm_srli_epi32(x, 32 - bits); +} + +#ifdef __SSSE3__ +static inline __m128i +rotate24(__m128i x) +{ + return _mm_shuffle_epi8(x, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)); +} +#else +static inline __m128i +rotate24(__m128i x) +{ + uint8_t _hydro_attr_aligned_(16) x8[16], y8[16]; + + _mm_storeu_si128((__m128i *) (void *) x8, x); + + y8[0] = x8[1]; + y8[1] = x8[2]; + y8[2] = x8[3]; + y8[3] = x8[0]; + y8[4] = x8[5]; + y8[5] = x8[6]; + y8[6] = x8[7]; + y8[7] = x8[4]; + y8[8] = x8[9]; + y8[9] = x8[10]; + y8[10] = x8[11]; + y8[11] = x8[8]; + y8[12] = x8[13]; + y8[13] = x8[14]; + y8[14] = x8[15]; + y8[15] = x8[12]; + + return _mm_loadu_si128((const __m128i *) (const void *) y8); +} +#endif + +static const uint32_t _hydro_attr_aligned_(16) coeffs[24] = { + 0x9e377904, 0, 0, 0, 0x9e377908, 0, 0, 0, 0x9e37790c, 0, 0, 0, + 0x9e377910, 0, 0, 0, 0x9e377914, 0, 0, 0, 0x9e377918, 0, 0, 0, +}; + +static void +gimli_core(uint32_t state[gimli_BLOCKBYTES / 4]) +{ + __m128i x = _mm_loadu_si128((const __m128i *) (const void *) &state[0]); + __m128i y = _mm_loadu_si128((const __m128i *) (const void *) &state[4]); + __m128i z = _mm_loadu_si128((const __m128i *) (const void *) &state[8]); + __m128i newy; + __m128i newz; + int round; + + for (round = 5; round >= 0; round--) { + x = rotate24(x); + y = rotate(y, S); + newz = x ^ shift(z, 1) ^ shift(y & z, 2); + newy = y ^ x ^ shift(x | z, 1); + x = z ^ y ^ shift(x & y, 3); + y = newy; + z = newz; + + x = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)); + x ^= ((const __m128i *) (const void *) coeffs)[round]; + + x = rotate24(x); + y = rotate(y, S); + newz = x ^ shift(z, 1) ^ shift(y & z, 2); + newy = y ^ x ^ shift(x | z, 1); + x = z ^ y ^ shift(x & y, 3); + y = newy; + z = newz; + + x = rotate24(x); + y = rotate(y, S); + newz = x ^ shift(z, 1) ^ shift(y & z, 2); + newy = y ^ x ^ shift(x | z, 1); + x = z ^ y ^ shift(x & y, 3); + y = newy; + z = newz; + + x = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2)); + + x = rotate24(x); + y = rotate(y, S); + newz = x ^ shift(z, 1) ^ shift(y & z, 2); + newy = y ^ x ^ shift(x | z, 1); + x = z ^ y ^ shift(x & y, 3); + y = newy; + z = newz; + } + + _mm_storeu_si128((__m128i *) (void *) &state[0], x); + _mm_storeu_si128((__m128i *) (void *) &state[4], y); + _mm_storeu_si128((__m128i *) (void *) &state[8], z); +} diff --git a/thirdparty/libhydrogen/upstream/impl/hash.h b/thirdparty/libhydrogen/upstream/impl/hash.h new file mode 100644 index 000000000..0773ae675 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/hash.h @@ -0,0 +1,144 @@ +int +hydro_hash_update(hydro_hash_state *state, const void *in_, size_t in_len) +{ + const uint8_t *in = (const uint8_t *) in_; + uint8_t *buf = (uint8_t *) (void *) state->state; + size_t left; + size_t ps; + size_t i; + + while (in_len > 0) { + left = gimli_RATE - state->buf_off; + if ((ps = in_len) > left) { + ps = left; + } + for (i = 0; i < ps; i++) { + buf[state->buf_off + i] ^= in[i]; + } + in += ps; + in_len -= ps; + state->buf_off += (uint8_t) ps; + if (state->buf_off == gimli_RATE) { + gimli_core_u8(buf, 0); + state->buf_off = 0; + } + } + return 0; +} + +/* pad(str_enc("kmac") || str_enc(context)) || pad(str_enc(k)) || + msg || right_enc(msg_len) || 0x00 */ + +int +hydro_hash_init(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES], + const uint8_t key[hydro_hash_KEYBYTES]) +{ + uint8_t block[64] = { 4, 'k', 'm', 'a', 'c', 8 }; + size_t p; + + COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - gimli_RATE - 1); + COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8); + mem_zero(block + 14, sizeof block - 14); + memcpy(block + 6, ctx, 8); + if (key != NULL) { + block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES; + memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES); + p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1); + } else { + block[gimli_RATE] = (uint8_t) 0; + p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1); + } + mem_zero(state, sizeof *state); + hydro_hash_update(state, block, p); + + return 0; +} + +/* pad(str_enc("tmac") || str_enc(context)) || pad(str_enc(k)) || + pad(right_enc(tweak)) || msg || right_enc(msg_len) || 0x00 */ + +static int +hydro_hash_init_with_tweak(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES], + uint64_t tweak, const uint8_t key[hydro_hash_KEYBYTES]) +{ + uint8_t block[80] = { 4, 't', 'm', 'a', 'c', 8 }; + size_t p; + + COMPILER_ASSERT(hydro_hash_KEYBYTES <= sizeof block - 2 * gimli_RATE - 1); + COMPILER_ASSERT(hydro_hash_CONTEXTBYTES == 8); + mem_zero(block + 14, sizeof block - 14); + memcpy(block + 6, ctx, 8); + if (key != NULL) { + block[gimli_RATE] = (uint8_t) hydro_hash_KEYBYTES; + memcpy(block + gimli_RATE + 1, key, hydro_hash_KEYBYTES); + p = (gimli_RATE + 1 + hydro_hash_KEYBYTES + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1); + } else { + block[gimli_RATE] = (uint8_t) 0; + p = (gimli_RATE + 1 + 0 + (gimli_RATE - 1)) & ~(size_t) (gimli_RATE - 1); + } + block[p] = (uint8_t) sizeof tweak; + STORE64_LE(&block[p + 1], tweak); + p += gimli_RATE; + mem_zero(state, sizeof *state); + hydro_hash_update(state, block, p); + + return 0; +} + +int +hydro_hash_final(hydro_hash_state *state, uint8_t *out, size_t out_len) +{ + uint8_t lc[4]; + uint8_t *buf = (uint8_t *) (void *) state->state; + size_t i; + size_t lc_len; + size_t leftover; + + if (out_len == 0) { + /* allow callers to finalize without producing output */ + } else if (out_len < hydro_hash_BYTES_MIN || out_len > hydro_hash_BYTES_MAX || out == NULL) { + return -1; + } + COMPILER_ASSERT(hydro_hash_BYTES_MAX <= 0xffff); + lc[1] = (uint8_t) out_len; + lc[2] = (uint8_t) (out_len >> 8); + lc[3] = 0; + lc_len = (size_t) (1 + (lc[2] != 0)); + lc[0] = (uint8_t) lc_len; + hydro_hash_update(state, lc, 1 + lc_len + 1); + gimli_pad_u8(buf, state->buf_off, gimli_DOMAIN_XOF); + for (i = 0; i < out_len / gimli_RATE; i++) { + gimli_core_u8(buf, 0); + memcpy(out + i * gimli_RATE, buf, gimli_RATE); + } + leftover = out_len % gimli_RATE; + if (leftover != 0) { + gimli_core_u8(buf, 0); + mem_cpy(out + i * gimli_RATE, buf, leftover); + } + state->buf_off = gimli_RATE; + + return 0; +} + +int +hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len, + const char ctx[hydro_hash_CONTEXTBYTES], const uint8_t key[hydro_hash_KEYBYTES]) +{ + hydro_hash_state st; + const uint8_t *in = (const uint8_t *) in_; + + if (hydro_hash_init(&st, ctx, key) != 0 || hydro_hash_update(&st, in, in_len) != 0 || + hydro_hash_final(&st, out, out_len) != 0) { + return -1; + } + return 0; +} + +#if !HYDRO_DISABLE_RANDOM +void +hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES]) +{ + hydro_random_buf(key, hydro_hash_KEYBYTES); +} +#endif diff --git a/thirdparty/libhydrogen/upstream/impl/hydrogen_p.h b/thirdparty/libhydrogen/upstream/impl/hydrogen_p.h new file mode 100644 index 000000000..2a4d95864 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/hydrogen_p.h @@ -0,0 +1,85 @@ +static int hydro_random_init(void); + +/* ---------------- */ + +#define gimli_BLOCKBYTES 48 +#define gimli_CAPACITY 32 +#define gimli_RATE 16 + +#define gimli_TAG_HEADER 0x01 +#define gimli_TAG_PAYLOAD 0x02 +#define gimli_TAG_FINAL 0x08 +#define gimli_TAG_FINAL0 0xf8 +#define gimli_TAG_KEY0 0xfe +#define gimli_TAG_KEY 0xff + +#define gimli_DOMAIN_AEAD 0x0 +#define gimli_DOMAIN_XOF 0xf + +static void gimli_core_u8(uint8_t state_u8[gimli_BLOCKBYTES], uint8_t tag); + +static inline void +gimli_pad_u8(uint8_t buf[gimli_BLOCKBYTES], size_t pos, uint8_t domain) +{ + buf[pos] ^= (domain << 1) | 1; + buf[gimli_RATE - 1] ^= 0x80; +} + +static inline void +hydro_mem_ct_zero_u32(uint32_t *dst_, size_t n) +{ + volatile uint32_t *volatile dst = (volatile uint32_t *volatile) (void *) dst_; + size_t i; + + for (i = 0; i < n; i++) { + dst[i] = 0; + } +} + +static inline uint32_t hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2, + size_t n) _hydro_attr_warn_unused_result_; + +static inline uint32_t +hydro_mem_ct_cmp_u32(const uint32_t *b1_, const uint32_t *b2, size_t n) +{ + const volatile uint32_t *volatile b1 = (const volatile uint32_t *volatile) (const void *) b1_; + size_t i; + uint32_t cv = 0; + + for (i = 0; i < n; i++) { + cv |= b1[i] ^ b2[i]; + } + return cv; +} + +/* ---------------- */ + +static int hydro_hash_init_with_tweak(hydro_hash_state *state, + const char ctx[hydro_hash_CONTEXTBYTES], uint64_t tweak, + const uint8_t key[hydro_hash_KEYBYTES]); + +/* ---------------- */ + +#define hydro_secretbox_NONCEBYTES 20 +#define hydro_secretbox_MACBYTES 16 + +/* ---------------- */ + +#define hydro_x25519_BYTES 32 +#define hydro_x25519_PUBLICKEYBYTES 32 +#define hydro_x25519_SECRETKEYBYTES 32 + +static int hydro_x25519_scalarmult(uint8_t out[hydro_x25519_BYTES], + const uint8_t scalar[hydro_x25519_SECRETKEYBYTES], + const uint8_t x1[hydro_x25519_PUBLICKEYBYTES], + bool clamp) _hydro_attr_warn_unused_result_; + +#if !HYDRO_SIGN_VERIFY_ONLY || !HYDRO_DISABLE_KX +static inline int hydro_x25519_scalarmult_base(uint8_t pk[hydro_x25519_PUBLICKEYBYTES], + const uint8_t sk[hydro_x25519_SECRETKEYBYTES]) + _hydro_attr_warn_unused_result_; + +static inline void +hydro_x25519_scalarmult_base_uniform(uint8_t pk[hydro_x25519_PUBLICKEYBYTES], + const uint8_t sk[hydro_x25519_SECRETKEYBYTES]); +#endif diff --git a/thirdparty/libhydrogen/upstream/impl/kdf.h b/thirdparty/libhydrogen/upstream/impl/kdf.h new file mode 100644 index 000000000..22a222cde --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/kdf.h @@ -0,0 +1,20 @@ +int +hydro_kdf_derive_from_key(uint8_t *subkey, size_t subkey_len, uint64_t subkey_id, + const char ctx[hydro_kdf_CONTEXTBYTES], + const uint8_t key[hydro_kdf_KEYBYTES]) +{ + hydro_hash_state st; + + COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES); + COMPILER_ASSERT(hydro_kdf_KEYBYTES >= hydro_hash_KEYBYTES); + if (hydro_hash_init_with_tweak(&st, ctx, subkey_id, key) != 0) { + return -1; + } + return hydro_hash_final(&st, subkey, subkey_len); +} + +void +hydro_kdf_keygen(uint8_t key[hydro_kdf_KEYBYTES]) +{ + hydro_random_buf(key, hydro_kdf_KEYBYTES); +} diff --git a/thirdparty/libhydrogen/upstream/impl/kx.h b/thirdparty/libhydrogen/upstream/impl/kx.h new file mode 100644 index 000000000..97f94532e --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/kx.h @@ -0,0 +1,535 @@ +#define hydro_kx_AEAD_KEYBYTES hydro_hash_KEYBYTES +#define hydro_kx_AEAD_MACBYTES 16 + +#define hydro_kx_CONTEXT "hydro_kx" + +static void +hydro_kx_aead_init(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t k[hydro_kx_AEAD_KEYBYTES], + hydro_kx_state *state) +{ + static const uint8_t prefix[] = { 6, 'k', 'x', 'x', '2', '5', '6', 0 }; + + hydro_hash_final(&state->h_st, k, hydro_kx_AEAD_KEYBYTES); + + mem_zero(aead_state + sizeof prefix, gimli_BLOCKBYTES - sizeof prefix); + memcpy(aead_state, prefix, sizeof prefix); + gimli_core_u8(aead_state, gimli_TAG_HEADER); + + COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == 2 * gimli_RATE); + mem_xor(aead_state, k, gimli_RATE); + gimli_core_u8(aead_state, gimli_TAG_KEY); + mem_xor(aead_state, k + gimli_RATE, gimli_RATE); + gimli_core_u8(aead_state, gimli_TAG_KEY); +} + +static void +hydro_kx_aead_final(uint8_t *aead_state, const uint8_t key[hydro_kx_AEAD_KEYBYTES]) +{ + COMPILER_ASSERT(hydro_kx_AEAD_KEYBYTES == gimli_CAPACITY); + mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES); + gimli_core_u8(aead_state, gimli_TAG_FINAL); + mem_xor(aead_state + gimli_RATE, key, hydro_kx_AEAD_KEYBYTES); + gimli_core_u8(aead_state, gimli_TAG_FINAL); +} + +static void +hydro_kx_aead_xor_enc(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in, + size_t inlen) +{ + size_t i; + size_t leftover; + + for (i = 0; i < inlen / gimli_RATE; i++) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE); + memcpy(aead_state, &out[i * gimli_RATE], gimli_RATE); + gimli_core_u8(aead_state, gimli_TAG_PAYLOAD); + } + leftover = inlen % gimli_RATE; + if (leftover != 0) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover); + mem_cpy(aead_state, &out[i * gimli_RATE], leftover); + } + gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD); + gimli_core_u8(aead_state, gimli_TAG_PAYLOAD); +} + +static void +hydro_kx_aead_xor_dec(uint8_t aead_state[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in, + size_t inlen) +{ + size_t i; + size_t leftover; + + for (i = 0; i < inlen / gimli_RATE; i++) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, gimli_RATE); + memcpy(aead_state, &in[i * gimli_RATE], gimli_RATE); + gimli_core_u8(aead_state, gimli_TAG_PAYLOAD); + } + leftover = inlen % gimli_RATE; + if (leftover != 0) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], aead_state, leftover); + mem_cpy(aead_state, &in[i * gimli_RATE], leftover); + } + gimli_pad_u8(aead_state, leftover, gimli_DOMAIN_AEAD); + gimli_core_u8(aead_state, gimli_TAG_PAYLOAD); +} + +static void +hydro_kx_aead_encrypt(hydro_kx_state *state, uint8_t *c, const uint8_t *m, size_t mlen) +{ + _hydro_attr_aligned_(16) uint8_t aead_state[gimli_BLOCKBYTES]; + uint8_t k[hydro_kx_AEAD_KEYBYTES]; + uint8_t *mac = &c[0]; + uint8_t *ct = &c[hydro_kx_AEAD_MACBYTES]; + + hydro_kx_aead_init(aead_state, k, state); + hydro_kx_aead_xor_enc(aead_state, ct, m, mlen); + hydro_kx_aead_final(aead_state, k); + COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY); + memcpy(mac, aead_state + gimli_RATE, hydro_kx_AEAD_MACBYTES); + hydro_hash_update(&state->h_st, c, mlen + hydro_kx_AEAD_MACBYTES); +} + +static int hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, + size_t clen) _hydro_attr_warn_unused_result_; + +static int +hydro_kx_aead_decrypt(hydro_kx_state *state, uint8_t *m, const uint8_t *c, size_t clen) +{ + _hydro_attr_aligned_(16) uint32_t int_state[gimli_BLOCKBYTES / 4]; + uint32_t pub_mac[hydro_kx_AEAD_MACBYTES / 4]; + uint8_t k[hydro_kx_AEAD_KEYBYTES]; + uint8_t *aead_state = (uint8_t *) (void *) int_state; + const uint8_t *mac; + const uint8_t *ct; + size_t mlen; + uint32_t cv; + + if (clen < hydro_kx_AEAD_MACBYTES) { + return -1; + } + mac = &c[0]; + ct = &c[hydro_kx_AEAD_MACBYTES]; + mlen = clen - hydro_kx_AEAD_MACBYTES; + memcpy(pub_mac, mac, sizeof pub_mac); + hydro_kx_aead_init(aead_state, k, state); + hydro_hash_update(&state->h_st, c, clen); + hydro_kx_aead_xor_dec(aead_state, m, ct, mlen); + hydro_kx_aead_final(aead_state, k); + COMPILER_ASSERT(hydro_kx_AEAD_MACBYTES <= gimli_CAPACITY); + COMPILER_ASSERT(gimli_RATE % 4 == 0); + cv = hydro_mem_ct_cmp_u32(int_state + gimli_RATE / 4, pub_mac, hydro_kx_AEAD_MACBYTES / 4); + hydro_mem_ct_zero_u32(int_state, gimli_BLOCKBYTES / 4); + if (cv != 0) { + mem_zero(m, mlen); + return -1; + } + return 0; +} + +/* -- */ + +void +hydro_kx_keygen(hydro_kx_keypair *static_kp) +{ + hydro_random_buf(static_kp->sk, hydro_kx_SECRETKEYBYTES); + if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) { + abort(); + } +} + +void +hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp, const uint8_t seed[hydro_kx_SEEDBYTES]) +{ + COMPILER_ASSERT(hydro_kx_SEEDBYTES >= hydro_random_SEEDBYTES); + hydro_random_buf_deterministic(static_kp->sk, hydro_kx_SECRETKEYBYTES, seed); + if (hydro_x25519_scalarmult_base(static_kp->pk, static_kp->sk) != 0) { + abort(); + } +} + +static void +hydro_kx_init_state(hydro_kx_state *state, const char *name) +{ + mem_zero(state, sizeof *state); + hydro_hash_init(&state->h_st, hydro_kx_CONTEXT, NULL); + hydro_hash_update(&state->h_st, name, strlen(name)); + hydro_hash_final(&state->h_st, NULL, 0); +} + +static void +hydro_kx_final(hydro_kx_state *state, uint8_t session_k1[hydro_kx_SESSIONKEYBYTES], + uint8_t session_k2[hydro_kx_SESSIONKEYBYTES]) +{ + uint8_t kdf_key[hydro_kdf_KEYBYTES]; + + hydro_hash_final(&state->h_st, kdf_key, sizeof kdf_key); + hydro_kdf_derive_from_key(session_k1, hydro_kx_SESSIONKEYBYTES, 0, hydro_kx_CONTEXT, kdf_key); + hydro_kdf_derive_from_key(session_k2, hydro_kx_SESSIONKEYBYTES, 1, hydro_kx_CONTEXT, kdf_key); +} + +static int +hydro_kx_dh(hydro_kx_state *state, const uint8_t sk[hydro_x25519_SECRETKEYBYTES], + const uint8_t pk[hydro_x25519_PUBLICKEYBYTES]) +{ + uint8_t dh_result[hydro_x25519_BYTES]; + + if (hydro_x25519_scalarmult(dh_result, sk, pk, 1) != 0) { + return -1; + } + hydro_hash_update(&state->h_st, dh_result, hydro_x25519_BYTES); + + return 0; +} + +static void +hydro_kx_eph_keygen(hydro_kx_state *state, hydro_kx_keypair *kp) +{ + hydro_kx_keygen(kp); + hydro_hash_update(&state->h_st, kp->pk, sizeof kp->pk); +} + +/* NOISE_N */ + +int +hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]) +{ + hydro_kx_state state; + uint8_t *packet1_eph_pk = &packet1[0]; + uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + + if (psk == NULL) { + psk = zero; + } + hydro_kx_init_state(&state, "Noise_Npsk0_hydro1"); + hydro_hash_update(&state.h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES); + + hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES); + hydro_kx_eph_keygen(&state, &state.eph_kp); + if (hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(&state, packet1_mac, NULL, 0); + memcpy(packet1_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk); + + hydro_kx_final(&state, kp->rx, kp->tx); + + return 0; +} + +int +hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp) +{ + hydro_kx_state state; + const uint8_t *peer_eph_pk = &packet1[0]; + const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + + if (psk == NULL) { + psk = zero; + } + hydro_kx_init_state(&state, "Noise_Npsk0_hydro1"); + hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES); + + hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES); + hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES); + if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 || + hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + hydro_kx_final(&state, kp->tx, kp->rx); + + return 0; +} + +/* NOISE_KK */ + +int +hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const hydro_kx_keypair *static_kp) +{ + uint8_t *packet1_eph_pk = &packet1[0]; + uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + + hydro_kx_init_state(state, "Noise_KK_hydro1"); + hydro_hash_update(&state->h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES); + hydro_hash_update(&state->h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES); + + hydro_kx_eph_keygen(state, &state->eph_kp); + if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 || + hydro_kx_dh(state, static_kp->sk, peer_static_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0); + memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk); + + return 0; +} + +int +hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES], + const uint8_t packet1[hydro_kx_KK_PACKET1BYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const hydro_kx_keypair *static_kp) +{ + hydro_kx_state state; + const uint8_t *peer_eph_pk = &packet1[0]; + const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + uint8_t *packet2_eph_pk = &packet2[0]; + uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES]; + + hydro_kx_init_state(&state, "Noise_KK_hydro1"); + hydro_hash_update(&state.h_st, peer_static_pk, hydro_kx_PUBLICKEYBYTES); + hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES); + + hydro_hash_update(&state.h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES); + if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 || + hydro_kx_dh(&state, static_kp->sk, peer_static_pk) != 0 || + hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + + hydro_kx_eph_keygen(&state, &state.eph_kp); + if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0 || + hydro_kx_dh(&state, state.eph_kp.sk, peer_static_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0); + hydro_kx_final(&state, kp->tx, kp->rx); + memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk); + + return 0; +} + +int +hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp, + const uint8_t packet2[hydro_kx_KK_PACKET2BYTES], const hydro_kx_keypair *static_kp) +{ + const uint8_t *peer_eph_pk = packet2; + const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES]; + + hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES); + if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 || + hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) { + return -1; + } + + if (hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + hydro_kx_final(state, kp->rx, kp->tx); + + return 0; +} + +/* NOISE_XX */ + +int +hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES]) +{ + uint8_t *packet1_eph_pk = &packet1[0]; + uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + + if (psk == NULL) { + psk = zero; + } + hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1"); + + hydro_kx_eph_keygen(state, &state->eph_kp); + hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES); + memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk); + hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0); + + return 0; +} + +int +hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES], + const uint8_t packet1[hydro_kx_XX_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES], + const hydro_kx_keypair *static_kp) +{ + const uint8_t *peer_eph_pk = &packet1[0]; + const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + uint8_t *packet2_eph_pk = &packet2[0]; + uint8_t *packet2_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES]; + uint8_t *packet2_mac = + &packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES]; + + if (psk == NULL) { + psk = zero; + } + hydro_kx_init_state(state, "Noise_XXpsk0+psk3_hydro1"); + + hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES); + hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES); + if (hydro_kx_aead_decrypt(state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + + hydro_kx_eph_keygen(state, &state->eph_kp); + if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(state, packet2_enc_static_pk, static_kp->pk, sizeof static_kp->pk); + if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(state, packet2_mac, NULL, 0); + + memcpy(packet2_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk); + + return 0; +} + +int +hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp, + uint8_t packet3[hydro_kx_XX_PACKET3BYTES], + uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const uint8_t packet2[hydro_kx_XX_PACKET2BYTES], const uint8_t psk[hydro_kx_PSKBYTES], + const hydro_kx_keypair *static_kp) +{ + uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES]; + const uint8_t *peer_eph_pk = &packet2[0]; + const uint8_t *peer_enc_static_pk = &packet2[hydro_kx_PUBLICKEYBYTES]; + const uint8_t *packet2_mac = + &packet2[hydro_kx_PUBLICKEYBYTES + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES]; + uint8_t *packet3_enc_static_pk = &packet3[0]; + uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES]; + + if (psk == NULL) { + psk = zero; + } + if (peer_static_pk == NULL) { + peer_static_pk = peer_static_pk_; + } + hydro_hash_update(&state->h_st, peer_eph_pk, hydro_kx_PUBLICKEYBYTES); + if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 || + hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk, + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 || + hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0 || + hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + + hydro_kx_aead_encrypt(state, packet3_enc_static_pk, static_kp->pk, sizeof static_kp->pk); + if (hydro_kx_dh(state, static_kp->sk, peer_eph_pk) != 0) { + return -1; + } + hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES); + hydro_kx_aead_encrypt(state, packet3_mac, NULL, 0); + hydro_kx_final(state, kp->rx, kp->tx); + + return 0; +} + +int +hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp, + uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const uint8_t packet3[hydro_kx_XX_PACKET3BYTES], const uint8_t psk[hydro_kx_PSKBYTES]) +{ + uint8_t peer_static_pk_[hydro_kx_PUBLICKEYBYTES]; + const uint8_t *peer_enc_static_pk = &packet3[0]; + const uint8_t *packet3_mac = &packet3[hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES]; + + if (psk == NULL) { + psk = zero; + } + if (peer_static_pk == NULL) { + peer_static_pk = peer_static_pk_; + } + if (hydro_kx_aead_decrypt(state, peer_static_pk, peer_enc_static_pk, + hydro_kx_PUBLICKEYBYTES + hydro_kx_AEAD_MACBYTES) != 0 || + hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) { + return -1; + } + hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES); + if (hydro_kx_aead_decrypt(state, NULL, packet3_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + hydro_kx_final(state, kp->tx, kp->rx); + + return 0; +} + +/* NOISE_NK */ + +int +hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]) +{ + uint8_t *packet1_eph_pk = &packet1[0]; + uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + + if (psk == NULL) { + psk = zero; + } + hydro_kx_init_state(state, "Noise_NKpsk0_hydro1"); + hydro_hash_update(&state->h_st, peer_static_pk, hydro_x25519_PUBLICKEYBYTES); + + hydro_hash_update(&state->h_st, psk, hydro_kx_PSKBYTES); + hydro_kx_eph_keygen(state, &state->eph_kp); + if (hydro_kx_dh(state, state->eph_kp.sk, peer_static_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(state, packet1_mac, NULL, 0); + memcpy(packet1_eph_pk, state->eph_kp.pk, sizeof state->eph_kp.pk); + + return 0; +} + +int +hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES], + const uint8_t packet1[hydro_kx_NK_PACKET1BYTES], const uint8_t psk[hydro_kx_PSKBYTES], + const hydro_kx_keypair *static_kp) +{ + hydro_kx_state state; + const uint8_t *peer_eph_pk = &packet1[0]; + const uint8_t *packet1_mac = &packet1[hydro_kx_PUBLICKEYBYTES]; + uint8_t *packet2_eph_pk = &packet2[0]; + uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES]; + + if (psk == NULL) { + psk = zero; + } + hydro_kx_init_state(&state, "Noise_NKpsk0_hydro1"); + hydro_hash_update(&state.h_st, static_kp->pk, hydro_kx_PUBLICKEYBYTES); + + hydro_hash_update(&state.h_st, psk, hydro_kx_PSKBYTES); + hydro_hash_update(&state.h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES); + if (hydro_kx_dh(&state, static_kp->sk, peer_eph_pk) != 0 || + hydro_kx_aead_decrypt(&state, NULL, packet1_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + + hydro_kx_eph_keygen(&state, &state.eph_kp); + if (hydro_kx_dh(&state, state.eph_kp.sk, peer_eph_pk) != 0) { + return -1; + } + hydro_kx_aead_encrypt(&state, packet2_mac, NULL, 0); + hydro_kx_final(&state, kp->tx, kp->rx); + memcpy(packet2_eph_pk, state.eph_kp.pk, sizeof state.eph_kp.pk); + + return 0; +} + +int +hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp, + const uint8_t packet2[hydro_kx_NK_PACKET2BYTES]) +{ + const uint8_t *peer_eph_pk = &packet2[0]; + const uint8_t *packet2_mac = &packet2[hydro_kx_PUBLICKEYBYTES]; + + hydro_hash_update(&state->h_st, peer_eph_pk, hydro_x25519_PUBLICKEYBYTES); + if (hydro_kx_dh(state, state->eph_kp.sk, peer_eph_pk) != 0 || + hydro_kx_aead_decrypt(state, NULL, packet2_mac, hydro_kx_AEAD_MACBYTES) != 0) { + return -1; + } + hydro_kx_final(state, kp->rx, kp->tx); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/pwhash.h b/thirdparty/libhydrogen/upstream/impl/pwhash.h new file mode 100644 index 000000000..2598f4723 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/pwhash.h @@ -0,0 +1,281 @@ +#define hydro_pwhash_ENC_ALGBYTES 1 +#define hydro_pwhash_HASH_ALGBYTES 1 +#define hydro_pwhash_THREADSBYTES 1 +#define hydro_pwhash_OPSLIMITBYTES 8 +#define hydro_pwhash_MEMLIMITBYTES 8 +#define hydro_pwhash_HASHBYTES 32 +#define hydro_pwhash_SALTBYTES 16 +#define hydro_pwhash_PARAMSBYTES \ + (hydro_pwhash_HASH_ALGBYTES + hydro_pwhash_THREADSBYTES + hydro_pwhash_OPSLIMITBYTES + \ + hydro_pwhash_MEMLIMITBYTES + hydro_pwhash_SALTBYTES + hydro_pwhash_HASHBYTES) +#define hydro_pwhash_ENC_ALG 0x01 +#define hydro_pwhash_HASH_ALG 0x01 +#define hydro_pwhash_CONTEXT "hydro_pw" + +static int +_hydro_pwhash_hash(uint8_t out[hydro_random_SEEDBYTES], size_t h_len, + const uint8_t salt[hydro_pwhash_SALTBYTES], const char *passwd, + size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit, + size_t memlimit, uint8_t threads) +{ + _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES]; + hydro_hash_state h_st; + uint8_t tmp64_u8[8]; + uint64_t i; + uint8_t tmp8; + + COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES >= hydro_hash_KEYBYTES); + hydro_hash_init(&h_st, ctx, master_key); + + STORE64_LE(tmp64_u8, (uint64_t) passwd_len); + hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8); + hydro_hash_update(&h_st, passwd, passwd_len); + + hydro_hash_update(&h_st, salt, hydro_pwhash_SALTBYTES); + + tmp8 = hydro_pwhash_HASH_ALG; + hydro_hash_update(&h_st, &tmp8, 1); + + hydro_hash_update(&h_st, &threads, 1); + + STORE64_LE(tmp64_u8, (uint64_t) memlimit); + hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8); + + STORE64_LE(tmp64_u8, (uint64_t) h_len); + hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8); + + hydro_hash_final(&h_st, (uint8_t *) (void *) &state, sizeof state); + + gimli_core_u8(state, 1); + COMPILER_ASSERT(gimli_RATE >= 8); + for (i = 0; i < opslimit; i++) { + mem_zero(state, gimli_RATE); + STORE64_LE(state, i); + gimli_core_u8(state, 0); + } + mem_zero(state, gimli_RATE); + + COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY); + memcpy(out, state + gimli_RATE, hydro_random_SEEDBYTES); + hydro_memzero(state, sizeof state); + + return 0; +} + +void +hydro_pwhash_keygen(uint8_t master_key[hydro_pwhash_MASTERKEYBYTES]) +{ + hydro_random_buf(master_key, hydro_pwhash_MASTERKEYBYTES); +} + +int +hydro_pwhash_deterministic(uint8_t *h, size_t h_len, const char *passwd, size_t passwd_len, + const char ctx[hydro_pwhash_CONTEXTBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit, + size_t memlimit, uint8_t threads) +{ + uint8_t seed[hydro_random_SEEDBYTES]; + + COMPILER_ASSERT(sizeof zero >= hydro_pwhash_SALTBYTES); + COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES); + + (void) memlimit; + if (_hydro_pwhash_hash(seed, h_len, zero, passwd, passwd_len, ctx, master_key, opslimit, + memlimit, threads) != 0) { + return -1; + } + hydro_random_buf_deterministic(h, h_len, seed); + hydro_memzero(seed, sizeof seed); + + return 0; +} + +int +hydro_pwhash_create(uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, size_t passwd_len, + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit, + size_t memlimit, uint8_t threads) +{ + uint8_t *const enc_alg = &stored[0]; + uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES]; + uint8_t *const hash_alg = &secretbox[hydro_secretbox_HEADERBYTES]; + uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES]; + uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES]; + uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES]; + uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES]; + uint8_t *const h = &salt[hydro_pwhash_SALTBYTES]; + + COMPILER_ASSERT(hydro_pwhash_STOREDBYTES >= hydro_pwhash_ENC_ALGBYTES + + hydro_secretbox_HEADERBYTES + + hydro_pwhash_PARAMSBYTES); + (void) memlimit; + mem_zero(stored, hydro_pwhash_STOREDBYTES); + *enc_alg = hydro_pwhash_ENC_ALG; + *hash_alg = hydro_pwhash_HASH_ALG; + *threads_u8 = threads; + STORE64_LE(opslimit_u8, opslimit); + STORE64_LE(memlimit_u8, (uint64_t) memlimit); + hydro_random_buf(salt, hydro_pwhash_SALTBYTES); + + COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES); + if (_hydro_pwhash_hash(h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len, + hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) != 0) { + return -1; + } + COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES == hydro_secretbox_KEYBYTES); + + return hydro_secretbox_encrypt(secretbox, hash_alg, hydro_pwhash_PARAMSBYTES, + (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key); +} + +static int +_hydro_pwhash_verify(uint8_t computed_h[hydro_pwhash_HASHBYTES], + const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, + size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max) +{ + const uint8_t *const enc_alg = &stored[0]; + const uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES]; + + uint8_t params[hydro_pwhash_PARAMSBYTES]; + uint8_t *const hash_alg = ¶ms[0]; + uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES]; + uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES]; + uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES]; + uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES]; + uint8_t *const h = &salt[hydro_pwhash_SALTBYTES]; + + uint64_t opslimit; + size_t memlimit; + uint8_t threads; + + (void) memlimit; + if (*enc_alg != hydro_pwhash_ENC_ALG) { + return -1; + } + if (hydro_secretbox_decrypt(params, secretbox, + hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES, + (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) { + return -1; + } + if (*hash_alg != hydro_pwhash_HASH_ALG || (opslimit = LOAD64_LE(opslimit_u8)) > opslimit_max || + (memlimit = (size_t) LOAD64_LE(memlimit_u8)) > memlimit_max || + (threads = *threads_u8) > threads_max) { + return -1; + } + if (_hydro_pwhash_hash(computed_h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len, + hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) == 0 && + hydro_equal(computed_h, h, hydro_pwhash_HASHBYTES) == 1) { + return 0; + } + return -1; +} + +int +hydro_pwhash_verify(const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, + size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max) +{ + uint8_t computed_h[hydro_pwhash_HASHBYTES]; + int ret; + + ret = _hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max, + memlimit_max, threads_max); + hydro_memzero(computed_h, sizeof computed_h); + + return ret; +} + +int +hydro_pwhash_derive_static_key(uint8_t *static_key, size_t static_key_len, + const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, + size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max) +{ + uint8_t computed_h[hydro_pwhash_HASHBYTES]; + + if (_hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max, + memlimit_max, threads_max) != 0) { + hydro_memzero(computed_h, sizeof computed_h); + return -1; + } + COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES <= hydro_pwhash_CONTEXTBYTES); + COMPILER_ASSERT(hydro_kdf_KEYBYTES <= hydro_pwhash_HASHBYTES); + hydro_kdf_derive_from_key(static_key, static_key_len, 0, ctx, computed_h); + hydro_memzero(computed_h, sizeof computed_h); + + return 0; +} + +int +hydro_pwhash_reencrypt(uint8_t stored[hydro_pwhash_STOREDBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + const uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES]) +{ + uint8_t *const enc_alg = &stored[0]; + uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES]; + uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES]; + + if (*enc_alg != hydro_pwhash_ENC_ALG) { + return -1; + } + if (hydro_secretbox_decrypt(secretbox, secretbox, + hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES, + (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) { + return -1; + } + memmove(params, secretbox, hydro_pwhash_PARAMSBYTES); + return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg, + hydro_pwhash_CONTEXT, new_master_key); +} + +int +hydro_pwhash_upgrade(uint8_t stored[hydro_pwhash_STOREDBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit, + size_t memlimit, uint8_t threads) +{ + uint8_t *const enc_alg = &stored[0]; + uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES]; + uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES]; + uint8_t *const hash_alg = ¶ms[0]; + uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES]; + uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES]; + uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES]; + uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES]; + uint8_t *const h = &salt[hydro_pwhash_SALTBYTES]; + + _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES]; + uint64_t i; + uint64_t opslimit_prev; + + if (*enc_alg != hydro_pwhash_ENC_ALG) { + return -1; + } + if (hydro_secretbox_decrypt(secretbox, secretbox, + hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES, + (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) { + return -1; + } + memmove(params, secretbox, hydro_pwhash_PARAMSBYTES); + opslimit_prev = LOAD64_LE(opslimit_u8); + if (*hash_alg != hydro_pwhash_HASH_ALG) { + mem_zero(stored, hydro_pwhash_STOREDBYTES); + return -1; + } + COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY); + memcpy(state + gimli_RATE, h, hydro_random_SEEDBYTES); + for (i = opslimit_prev; i < opslimit; i++) { + mem_zero(state, gimli_RATE); + STORE64_LE(state, i); + gimli_core_u8(state, 0); + } + mem_zero(state, gimli_RATE); + memcpy(h, state + gimli_RATE, hydro_random_SEEDBYTES); + *threads_u8 = threads; + STORE64_LE(opslimit_u8, opslimit); + STORE64_LE(memlimit_u8, (uint64_t) memlimit); + + return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg, + hydro_pwhash_CONTEXT, master_key); +} diff --git a/thirdparty/libhydrogen/upstream/impl/random.h b/thirdparty/libhydrogen/upstream/impl/random.h new file mode 100644 index 000000000..bb18c5c54 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random.h @@ -0,0 +1,157 @@ +static TLS struct { + _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES]; + uint64_t counter; + uint8_t initialized; + uint8_t available; +} hydro_random_context; + +#if defined(AVR) && !defined(__unix__) +# include "random/avr.h" +#elif (defined(ESP32) || defined(ESP8266)) && !defined(__unix__) +# include "random/esp32.h" +#elif defined(PARTICLE) && defined(PLATFORM_ID) && PLATFORM_ID > 2 && !defined(__unix__) +# include "random/particle.h" +#elif defined(__ZEPHYR__) +# include "random/zephyr.h" +#elif (defined(NRF52832_XXAA) || defined(NRF52832_XXAB)) && !defined(__unix__) +# include "random/nrf52832.h" +#elif defined(_WIN32) +# include "random/windows.h" +#elif defined(__wasi__) +# include "random/wasi.h" +#elif defined(__linux__) && defined(__KERNEL__) +# include "random/linux_kernel.h" +#elif defined(__unix__) +# include "random/unix.h" +#elif defined(TARGET_LIKE_MBED) +# include "random/mbed.h" +#elif defined(RIOT_VERSION) +# include "random/riot.h" +#elif defined(STM32F4) || defined(STM32L4) +# include "random/stm32.h" +#elif defined(__RTTHREAD__) +# include "random/rtthread.h" +#elif defined(CH32V30x_D8) || defined(CH32V30x_D8C) +# include "random/ch32.h" +#elif defined(CHIBIOS) +# include "random/chibios.h" +#elif defined(__CHERIOT__) +# include "random/cheriot.h" +#else +# error Unsupported platform +#endif + +static void +hydro_random_ensure_initialized(void) +{ + if (hydro_random_context.initialized == 0) { + if (hydro_random_init() != 0) { + abort(); + } + gimli_core_u8(hydro_random_context.state, 0); + hydro_random_ratchet(); + hydro_random_context.initialized = 1; + } +} + +void +hydro_random_ratchet(void) +{ + mem_zero(hydro_random_context.state, gimli_RATE); + STORE64_LE(hydro_random_context.state, hydro_random_context.counter); + hydro_random_context.counter++; + gimli_core_u8(hydro_random_context.state, 0); + hydro_random_context.available = gimli_RATE; +} + +uint32_t +hydro_random_u32(void) +{ + uint32_t v; + + hydro_random_ensure_initialized(); + if (hydro_random_context.available < 4) { + hydro_random_ratchet(); + } + memcpy(&v, &hydro_random_context.state[gimli_RATE - hydro_random_context.available], 4); + hydro_random_context.available -= 4; + + return v; +} + +uint32_t +hydro_random_uniform(const uint32_t upper_bound) +{ + uint32_t min; + uint32_t r; + + if (upper_bound < 2U) { + return 0; + } + min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */ + do { + r = hydro_random_u32(); + } while (r < min); + /* r is now clamped to a set whose size mod upper_bound == 0 + * the worst case (2**31+1) requires 2 attempts on average */ + + return r % upper_bound; +} + +void +hydro_random_buf(void *out, size_t out_len) +{ + uint8_t *p = (uint8_t *) out; + size_t i; + size_t leftover; + + hydro_random_ensure_initialized(); + for (i = 0; i < out_len / gimli_RATE; i++) { + gimli_core_u8(hydro_random_context.state, 0); + memcpy(p + i * gimli_RATE, hydro_random_context.state, gimli_RATE); + } + leftover = out_len % gimli_RATE; + if (leftover != 0) { + gimli_core_u8(hydro_random_context.state, 0); + mem_cpy(p + i * gimli_RATE, hydro_random_context.state, leftover); + } + hydro_random_ratchet(); +} + +void +hydro_random_buf_deterministic(void *out, size_t out_len, + const uint8_t seed[hydro_random_SEEDBYTES]) +{ + static const uint8_t prefix[] = { 7, 'd', 'r', 'b', 'g', '2', '5', '6' }; + _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES]; + uint8_t *p = (uint8_t *) out; + size_t i; + size_t leftover; + + mem_zero(state, gimli_BLOCKBYTES); + COMPILER_ASSERT(sizeof prefix + 8 <= gimli_RATE); + memcpy(state, prefix, sizeof prefix); + STORE64_LE(state + sizeof prefix, (uint64_t) out_len); + gimli_core_u8(state, 1); + COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_RATE * 2); + mem_xor(state, seed, gimli_RATE); + gimli_core_u8(state, 2); + mem_xor(state, seed + gimli_RATE, gimli_RATE); + gimli_core_u8(state, 2); + for (i = 0; i < out_len / gimli_RATE; i++) { + gimli_core_u8(state, 0); + memcpy(p + i * gimli_RATE, state, gimli_RATE); + } + leftover = out_len % gimli_RATE; + if (leftover != 0) { + gimli_core_u8(state, 0); + mem_cpy(p + i * gimli_RATE, state, leftover); + } +} + +void +hydro_random_reseed(void) +{ + hydro_random_context.initialized = 0; + hydro_random_ensure_initialized(); +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/avr.h b/thirdparty/libhydrogen/upstream/impl/random/avr.h new file mode 100644 index 000000000..a02ebc249 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/avr.h @@ -0,0 +1,63 @@ +#include + +static bool +hydro_random_rbit(uint16_t x) +{ + uint8_t x8; + + x8 = ((uint8_t) (x >> 8)) ^ (uint8_t) x; + x8 = (x8 >> 4) ^ (x8 & 0xf); + x8 = (x8 >> 2) ^ (x8 & 0x3); + x8 = (x8 >> 1) ^ x8; + + return (bool) (x8 & 1); +} + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + uint16_t tc; + bool a, b; + + cli(); + MCUSR = 0; + WDTCSR |= _BV(WDCE) | _BV(WDE); + WDTCSR = _BV(WDIE); + sei(); + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + delay(1); + tc = TCNT1; + hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc); + a = hydro_random_rbit(tc); + delay(1); + tc = TCNT1; + b = hydro_random_rbit(tc); + hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc); + if (a == b) { + continue; + } + hydro_hash_update(&st, (const uint8_t *) &b, sizeof b); + ebits++; + } + + cli(); + MCUSR = 0; + WDTCSR |= _BV(WDCE) | _BV(WDE); + WDTCSR = 0; + sei(); + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} + +ISR(WDT_vect) +{ +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/ch32.h b/thirdparty/libhydrogen/upstream/impl/random/ch32.h new file mode 100644 index 000000000..263579c4e --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/ch32.h @@ -0,0 +1,35 @@ +#if defined(CH32V30x_D8) || defined(CH32V30x_D8C) +# include +#else +# error CH32 implementation missing! +#endif + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + + // Enable RNG clock source + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_RNG, ENABLE); + + // RNG Peripheral enable + RNG_Cmd(ENABLE); + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET) + ; + uint32_t r = RNG_GetRandomNumber(); + + hydro_hash_update(&st, (const uint32_t *) &r, sizeof r); + ebits += 32; + } + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/cheriot.h b/thirdparty/libhydrogen/upstream/impl/random/cheriot.h new file mode 100644 index 000000000..298a79f0d --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/cheriot.h @@ -0,0 +1,22 @@ +uint32_t rand_32(); + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + uint32_t r = rand_32(); + hydro_hash_update(&st, (const uint32_t *) &r, sizeof r); + ebits += 32; + } + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} \ No newline at end of file diff --git a/thirdparty/libhydrogen/upstream/impl/random/chibios.h b/thirdparty/libhydrogen/upstream/impl/random/chibios.h new file mode 100644 index 000000000..9a1bea47f --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/chibios.h @@ -0,0 +1,23 @@ +#include +#include +#include + +/* Declarations from ChibiOS HAL TRNG module */ + +extern struct hal_trng_driver TRNGD1; + +void trngStart(struct hal_trng_driver *, const void *); +bool trngGenerate(struct hal_trng_driver *, size_t size, uint8_t *); + +static int +hydro_random_init(void) +{ + trngStart(&TRNGD1, NULL); + + if (trngGenerate(&TRNGD1, sizeof hydro_random_context.state, hydro_random_context.state)) { + return -1; + } + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/esp32.h b/thirdparty/libhydrogen/upstream/impl/random/esp32.h new file mode 100644 index 000000000..145ec61c9 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/esp32.h @@ -0,0 +1,32 @@ +// Important: RF *must* be activated on ESP board +// https://techtutorialsx.com/2017/12/22/esp32-arduino-random-number-generation/ +#ifdef ESP32 +# include +#endif + +#ifdef ARDUINO +# include +#endif + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + uint32_t r = esp_random(); + + delay(10); + hydro_hash_update(&st, (const uint32_t *) &r, sizeof r); + ebits += 32; + } + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/linux_kernel.h b/thirdparty/libhydrogen/upstream/impl/random/linux_kernel.h new file mode 100644 index 000000000..09e020e30 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/linux_kernel.h @@ -0,0 +1,8 @@ +static int +hydro_random_init(void) +{ + get_random_bytes(&hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/mbed.h b/thirdparty/libhydrogen/upstream/impl/random/mbed.h new file mode 100644 index 000000000..8b63fa159 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/mbed.h @@ -0,0 +1,44 @@ +#include +#include + +#if defined(MBEDTLS_ENTROPY_C) + +static int +hydro_random_init(void) +{ + mbedtls_entropy_context entropy; + uint16_t pos = 0; + + mbedtls_entropy_init(&entropy); + + // Pull data directly out of the entropy pool for the state, as it's small enough. + if (mbedtls_entropy_func(&entropy, (uint8_t *) &hydro_random_context.counter, + sizeof hydro_random_context.counter) != 0) { + return -1; + } + // mbedtls_entropy_func can't provide more than MBEDTLS_ENTROPY_BLOCK_SIZE in one go. + // This constant depends of mbedTLS configuration (whether the PRNG is backed by SHA256/SHA512 + // at this time) Therefore, if necessary, we get entropy multiple times. + + do { + const uint8_t dataLeftToConsume = gimli_BLOCKBYTES - pos; + const uint8_t currentChunkSize = (dataLeftToConsume > MBEDTLS_ENTROPY_BLOCK_SIZE) + ? MBEDTLS_ENTROPY_BLOCK_SIZE + : dataLeftToConsume; + + // Forces mbedTLS to fetch fresh entropy, then get some to feed libhydrogen. + if (mbedtls_entropy_gather(&entropy) != 0 || + mbedtls_entropy_func(&entropy, &hydro_random_context.state[pos], currentChunkSize) != + 0) { + return -1; + } + pos += MBEDTLS_ENTROPY_BLOCK_SIZE; + } while (pos < gimli_BLOCKBYTES); + + mbedtls_entropy_free(&entropy); + + return 0; +} +#else +# error Need an entropy source +#endif diff --git a/thirdparty/libhydrogen/upstream/impl/random/nrf52832.h b/thirdparty/libhydrogen/upstream/impl/random/nrf52832.h new file mode 100644 index 000000000..0b6232e7d --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/nrf52832.h @@ -0,0 +1,41 @@ +// Important: The SoftDevice *must* be activated to enable reading from the RNG +// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Frng.html + +#include + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + const uint8_t total_bytes = 32; + uint8_t remaining_bytes = total_bytes; + uint8_t available_bytes; + uint8_t rand_buffer[32]; + + hydro_hash_init(&st, ctx, NULL); + + for (;;) { + if (sd_rand_application_bytes_available_get(&available_bytes) != NRF_SUCCESS) { + return -1; + } + if (available_bytes > 0) { + if (available_bytes > remaining_bytes) { + available_bytes = remaining_bytes; + } + if (sd_rand_application_vector_get(rand_buffer, available_bytes) != NRF_SUCCESS) { + return -1; + } + hydro_hash_update(&st, rand_buffer, total_bytes); + remaining_bytes -= available_bytes; + } + if (remaining_bytes <= 0) { + break; + } + delay(10); + } + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/particle.h b/thirdparty/libhydrogen/upstream/impl/random/particle.h new file mode 100644 index 000000000..bd3a57e43 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/particle.h @@ -0,0 +1,26 @@ +// Note: All particle platforms except for the Spark Core have a HW RNG. Only allow building on +// supported platforms for now. PLATFORM_ID definitions: +// https://github.com/particle-iot/device-os/blob/mesh-develop/hal/shared/platforms.h + +#include + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + uint32_t r = HAL_RNG_GetRandomNumber(); + hydro_hash_update(&st, (const uint32_t *) &r, sizeof r); + ebits += 32; + } + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/riot.h b/thirdparty/libhydrogen/upstream/impl/random/riot.h new file mode 100644 index 000000000..06522ba34 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/riot.h @@ -0,0 +1,10 @@ +#include + +static int +hydro_random_init(void) +{ + random_bytes(hydro_random_context.state, sizeof(hydro_random_context.state)); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/rtthread.h b/thirdparty/libhydrogen/upstream/impl/random/rtthread.h new file mode 100644 index 000000000..e83b4a39d --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/rtthread.h @@ -0,0 +1,38 @@ +#include +#include + +#define DBG_TAG "libhydrogen" +#define DBG_LVL DBG_LOG +#include + +static int +hydrogen_init(void) +{ + if (hydro_init() != 0) { + abort(); + } + LOG_I("libhydrogen initialized"); + return 0; +} +INIT_APP_EXPORT(hydrogen_init); + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + uint32_t r = rt_hwcrypto_rng_update(); + hydro_hash_update(&st, (const uint32_t *) &r, sizeof r); + ebits += 32; + } + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/stm32.h b/thirdparty/libhydrogen/upstream/impl/random/stm32.h new file mode 100644 index 000000000..80907759c --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/stm32.h @@ -0,0 +1,63 @@ + +// Use hardware RNG peripheral +// Working with HAL, LL Driver (untested) +#if defined(STM32F4) || defined(STM32L4) + +# if defined(STM32F4) +# include "stm32f4xx.h" +# elif defined(STM32L4) +# include "stm32l4xx_hal_rng.h" + +static RNG_HandleTypeDef RngHandle; +# endif + +static int +hydro_random_init(void) +{ + const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; + hydro_hash_state st; + uint16_t ebits = 0; + + __IO uint32_t tmpreg; + +# if defined(STM32F4) + // Enable RNG clock source + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN); + + // Delay after an RCC peripheral clock enabling + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN); + UNUSED(tmpreg); + + // RNG Peripheral enable + SET_BIT(RNG->CR, RNG_CR_RNGEN); +# elif defined(STM32L4) + RngHandle.Instance = RNG; + HAL_RNG_Init(&RngHandle); +# endif + + hydro_hash_init(&st, ctx, NULL); + + while (ebits < 256) { + uint32_t r = 0; +# if defined(STM32F4) + while (!(READ_BIT(RNG->SR, RNG_SR_DRDY))) { + } + + r = RNG->DR; +# elif defined(STM32L4) + if (HAL_RNG_GenerateRandomNumber(&RngHandle, &r) != HAL_OK) { + continue; + } +# endif + hydro_hash_update(&st, (const uint32_t *) &r, sizeof r); + ebits += 32; + } + + hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} +#else +# error SMT32 implementation missing! +#endif diff --git a/thirdparty/libhydrogen/upstream/impl/random/unix.h b/thirdparty/libhydrogen/upstream/impl/random/unix.h new file mode 100644 index 000000000..7744d843c --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/unix.h @@ -0,0 +1,85 @@ +#include +#include +#ifdef __linux__ +# include +#endif +#include +#include + +#ifdef __linux__ +static int +hydro_random_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +#endif + +static ssize_t +hydro_random_safe_read(const int fd, void *const buf_, size_t len) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + do { + while ((readnb = read(fd, buf, len)) < (ssize_t) 0 && (errno == EINTR || errno == EAGAIN)) { + } + if (readnb < (ssize_t) 0) { + return readnb; + } + if (readnb == (ssize_t) 0) { + break; + } + len -= (size_t) readnb; + buf += readnb; + } while (len > (ssize_t) 0); + + return (ssize_t) (buf - (unsigned char *) buf_); +} + +static int +hydro_random_init(void) +{ + uint8_t tmp[gimli_BLOCKBYTES + 8]; + int fd; + int ret = -1; + +#ifdef __linux__ + if (hydro_random_block_on_dev_random() != 0) { + return -1; + } +#endif + do { + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1 && errno != EINTR) { + return -1; + } + } while (fd == -1); + if (hydro_random_safe_read(fd, tmp, sizeof tmp) == (ssize_t) sizeof tmp) { + memcpy(hydro_random_context.state, tmp, gimli_BLOCKBYTES); + memcpy(&hydro_random_context.counter, tmp + gimli_BLOCKBYTES, 8); + hydro_memzero(tmp, sizeof tmp); + ret = 0; + } + ret |= close(fd); + + return ret; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/wasi.h b/thirdparty/libhydrogen/upstream/impl/random/wasi.h new file mode 100644 index 000000000..172e0e2d9 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/wasi.h @@ -0,0 +1,12 @@ +#include + +static int +hydro_random_init(void) +{ + if (getentropy(hydro_random_context.state, sizeof hydro_random_context.state) != 0) { + return -1; + } + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/windows.h b/thirdparty/libhydrogen/upstream/impl/random/windows.h new file mode 100644 index 000000000..32a6721c8 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/windows.h @@ -0,0 +1,20 @@ +#include +#define RtlGenRandom SystemFunction036 +#if defined(__cplusplus) +extern "C" +#endif + BOOLEAN NTAPI + RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +#pragma comment(lib, "advapi32.lib") + +static int +hydro_random_init(void) +{ + if (!RtlGenRandom((PVOID) hydro_random_context.state, + (ULONG) sizeof hydro_random_context.state)) { + return -1; + } + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/random/zephyr.h b/thirdparty/libhydrogen/upstream/impl/random/zephyr.h new file mode 100644 index 000000000..6a2baf4dd --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/random/zephyr.h @@ -0,0 +1,13 @@ +#include + +static int +hydro_random_init(void) +{ + if (sys_csrand_get(&hydro_random_context.state, sizeof hydro_random_context.state) != 0) { + return -1; + } + + hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); + + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/secretbox.h b/thirdparty/libhydrogen/upstream/impl/secretbox.h new file mode 100644 index 000000000..9aa113749 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/secretbox.h @@ -0,0 +1,236 @@ +#define hydro_secretbox_IVBYTES 20 +#define hydro_secretbox_SIVBYTES 20 +#define hydro_secretbox_MACBYTES 16 + +void +hydro_secretbox_keygen(uint8_t key[hydro_secretbox_KEYBYTES]) +{ + hydro_random_buf(key, hydro_secretbox_KEYBYTES); +} + +static void +hydro_secretbox_xor_enc(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in, + size_t inlen) +{ + size_t i; + size_t leftover; + + for (i = 0; i < inlen / gimli_RATE; i++) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE); + memcpy(buf, &out[i * gimli_RATE], gimli_RATE); + gimli_core_u8(buf, gimli_TAG_PAYLOAD); + } + leftover = inlen % gimli_RATE; + if (leftover != 0) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover); + mem_cpy(buf, &out[i * gimli_RATE], leftover); + } + gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD); + gimli_core_u8(buf, gimli_TAG_PAYLOAD); +} + +static void +hydro_secretbox_xor_dec(uint8_t buf[gimli_BLOCKBYTES], uint8_t *out, const uint8_t *in, + size_t inlen) +{ + size_t i; + size_t leftover; + + for (i = 0; i < inlen / gimli_RATE; i++) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, gimli_RATE); + memcpy(buf, &in[i * gimli_RATE], gimli_RATE); + gimli_core_u8(buf, gimli_TAG_PAYLOAD); + } + leftover = inlen % gimli_RATE; + if (leftover != 0) { + mem_xor2(&out[i * gimli_RATE], &in[i * gimli_RATE], buf, leftover); + mem_cpy(buf, &in[i * gimli_RATE], leftover); + } + gimli_pad_u8(buf, leftover, gimli_DOMAIN_AEAD); + gimli_core_u8(buf, gimli_TAG_PAYLOAD); +} + +static void +hydro_secretbox_setup(uint8_t buf[gimli_BLOCKBYTES], uint64_t msg_id, + const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES], + const uint8_t iv[hydro_secretbox_IVBYTES], uint8_t key_tag) +{ + static const uint8_t prefix[] = { 6, 's', 'b', 'x', '2', '5', '6', 8 }; + uint8_t msg_id_le[8]; + + mem_zero(buf, gimli_BLOCKBYTES); + COMPILER_ASSERT(hydro_secretbox_CONTEXTBYTES == 8); + COMPILER_ASSERT(sizeof prefix + hydro_secretbox_CONTEXTBYTES <= gimli_RATE); + memcpy(buf, prefix, sizeof prefix); + memcpy(buf + sizeof prefix, ctx, hydro_secretbox_CONTEXTBYTES); + COMPILER_ASSERT(sizeof prefix + hydro_secretbox_CONTEXTBYTES == gimli_RATE); + gimli_core_u8(buf, gimli_TAG_HEADER); + + COMPILER_ASSERT(hydro_secretbox_KEYBYTES == 2 * gimli_RATE); + mem_xor(buf, key, gimli_RATE); + gimli_core_u8(buf, key_tag); + mem_xor(buf, key + gimli_RATE, gimli_RATE); + gimli_core_u8(buf, key_tag); + + COMPILER_ASSERT(hydro_secretbox_IVBYTES < gimli_RATE * 2); + buf[0] ^= hydro_secretbox_IVBYTES; + mem_xor(&buf[1], iv, gimli_RATE - 1); + gimli_core_u8(buf, gimli_TAG_HEADER); + mem_xor(buf, iv + gimli_RATE - 1, hydro_secretbox_IVBYTES - (gimli_RATE - 1)); + STORE64_LE(msg_id_le, msg_id); + COMPILER_ASSERT(hydro_secretbox_IVBYTES - gimli_RATE + 8 <= gimli_RATE); + mem_xor(buf + hydro_secretbox_IVBYTES - gimli_RATE, msg_id_le, 8); + gimli_core_u8(buf, gimli_TAG_HEADER); +} + +static void +hydro_secretbox_final(uint8_t *buf, const uint8_t key[hydro_secretbox_KEYBYTES], uint8_t tag) +{ + COMPILER_ASSERT(hydro_secretbox_KEYBYTES == gimli_CAPACITY); + mem_xor(buf + gimli_RATE, key, hydro_secretbox_KEYBYTES); + gimli_core_u8(buf, tag); + mem_xor(buf + gimli_RATE, key, hydro_secretbox_KEYBYTES); + gimli_core_u8(buf, tag); +} + +static int +hydro_secretbox_encrypt_iv(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id, + const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES], + const uint8_t iv[hydro_secretbox_IVBYTES]) +{ + _hydro_attr_aligned_(16) uint32_t state[gimli_BLOCKBYTES / 4]; + uint8_t *buf = (uint8_t *) (void *) state; + const uint8_t *m = (const uint8_t *) m_; + uint8_t *siv = &c[0]; + uint8_t *mac = &c[hydro_secretbox_SIVBYTES]; + uint8_t *ct = &c[hydro_secretbox_SIVBYTES + hydro_secretbox_MACBYTES]; + size_t i; + size_t leftover; + + if (c == m) { + memmove(c + hydro_secretbox_HEADERBYTES, m, mlen); + m = c + hydro_secretbox_HEADERBYTES; + } + + /* first pass: compute the SIV */ + + hydro_secretbox_setup(buf, msg_id, ctx, key, iv, gimli_TAG_KEY0); + for (i = 0; i < mlen / gimli_RATE; i++) { + mem_xor(buf, &m[i * gimli_RATE], gimli_RATE); + gimli_core_u8(buf, gimli_TAG_PAYLOAD); + } + leftover = mlen % gimli_RATE; + if (leftover != 0) { + mem_xor(buf, &m[i * gimli_RATE], leftover); + } + gimli_pad_u8(buf, leftover, gimli_DOMAIN_XOF); + gimli_core_u8(buf, gimli_TAG_PAYLOAD); + + hydro_secretbox_final(buf, key, gimli_TAG_FINAL0); + COMPILER_ASSERT(hydro_secretbox_SIVBYTES <= gimli_CAPACITY); + memcpy(siv, buf + gimli_RATE, hydro_secretbox_SIVBYTES); + + /* second pass: encrypt the message, mix the key, squeeze an extra block for + * the MAC */ + + COMPILER_ASSERT(hydro_secretbox_SIVBYTES == hydro_secretbox_IVBYTES); + hydro_secretbox_setup(buf, msg_id, ctx, key, siv, gimli_TAG_KEY); + hydro_secretbox_xor_enc(buf, ct, m, mlen); + + hydro_secretbox_final(buf, key, gimli_TAG_FINAL); + COMPILER_ASSERT(hydro_secretbox_MACBYTES <= gimli_CAPACITY); + memcpy(mac, buf + gimli_RATE, hydro_secretbox_MACBYTES); + + return 0; +} + +void +hydro_secretbox_probe_create(uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c, + size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]) +{ + const uint8_t *mac; + + if (c_len < hydro_secretbox_HEADERBYTES) { + abort(); + } + mac = &c[hydro_secretbox_SIVBYTES]; + COMPILER_ASSERT(hydro_secretbox_CONTEXTBYTES >= hydro_hash_CONTEXTBYTES); + COMPILER_ASSERT(hydro_secretbox_KEYBYTES >= hydro_hash_KEYBYTES); + hydro_hash_hash(probe, hydro_secretbox_PROBEBYTES, mac, hydro_secretbox_MACBYTES, ctx, key); +} + +int +hydro_secretbox_probe_verify(const uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c, + size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]) +{ + uint8_t computed_probe[hydro_secretbox_PROBEBYTES]; + const uint8_t *mac; + + if (c_len < hydro_secretbox_HEADERBYTES) { + return -1; + } + mac = &c[hydro_secretbox_SIVBYTES]; + hydro_hash_hash(computed_probe, hydro_secretbox_PROBEBYTES, mac, hydro_secretbox_MACBYTES, ctx, + key); + if (hydro_equal(computed_probe, probe, hydro_secretbox_PROBEBYTES) == 1) { + return 0; + } + hydro_memzero(computed_probe, hydro_secretbox_PROBEBYTES); + return -1; +} + +int +hydro_secretbox_encrypt(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id, + const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]) +{ + uint8_t iv[hydro_secretbox_IVBYTES]; + + hydro_random_buf(iv, sizeof iv); + + return hydro_secretbox_encrypt_iv(c, m_, mlen, msg_id, ctx, key, iv); +} + +int +hydro_secretbox_decrypt(void *m_, const uint8_t *c, size_t clen, uint64_t msg_id, + const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]) +{ + _hydro_attr_aligned_(16) uint32_t state[gimli_BLOCKBYTES / 4]; + uint32_t pub_mac[hydro_secretbox_MACBYTES / 4]; + uint8_t *buf = (uint8_t *) (void *) state; + const uint8_t *siv; + const uint8_t *mac; + const uint8_t *ct; + uint8_t *m = (uint8_t *) m_; + size_t mlen; + uint32_t cv; + + if (clen < hydro_secretbox_HEADERBYTES) { + return -1; + } + siv = &c[0]; + mac = &c[hydro_secretbox_SIVBYTES]; + ct = &c[hydro_secretbox_SIVBYTES + hydro_secretbox_MACBYTES]; + + mlen = clen - hydro_secretbox_HEADERBYTES; + memcpy(pub_mac, mac, sizeof pub_mac); + COMPILER_ASSERT(hydro_secretbox_SIVBYTES == hydro_secretbox_IVBYTES); + hydro_secretbox_setup(buf, msg_id, ctx, key, siv, gimli_TAG_KEY); + hydro_secretbox_xor_dec(buf, m, ct, mlen); + + hydro_secretbox_final(buf, key, gimli_TAG_FINAL); + COMPILER_ASSERT(hydro_secretbox_MACBYTES <= gimli_CAPACITY); + COMPILER_ASSERT(gimli_RATE % 4 == 0); + cv = hydro_mem_ct_cmp_u32(state + gimli_RATE / 4, pub_mac, hydro_secretbox_MACBYTES / 4); + hydro_mem_ct_zero_u32(state, gimli_BLOCKBYTES / 4); + if (cv != 0) { + mem_zero(m, mlen); + return -1; + } + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/sign.h b/thirdparty/libhydrogen/upstream/impl/sign.h new file mode 100644 index 000000000..93f5a212e --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/sign.h @@ -0,0 +1,217 @@ +#define hydro_sign_CHALLENGEBYTES 32 +#define hydro_sign_NONCEBYTES 32 +#define hydro_sign_PREHASHBYTES 64 + +#if !HYDRO_SIGN_VERIFY_ONLY +static void +hydro_sign_p2(uint8_t sig[hydro_x25519_BYTES], const uint8_t challenge[hydro_sign_CHALLENGEBYTES], + const uint8_t eph_sk[hydro_x25519_BYTES], const uint8_t sk[hydro_x25519_BYTES]) +{ + hydro_x25519_scalar_t scalar1, scalar2, scalar3; + + COMPILER_ASSERT(hydro_sign_CHALLENGEBYTES == hydro_x25519_BYTES); + hydro_x25519_swapin(scalar1, eph_sk); + hydro_x25519_swapin(scalar2, sk); + hydro_x25519_swapin(scalar3, challenge); + hydro_x25519_sc_montmul(scalar1, scalar2, scalar3); + mem_zero(scalar2, sizeof scalar2); + hydro_x25519_sc_montmul(scalar2, scalar1, hydro_x25519_sc_r2); + hydro_x25519_swapout(sig, scalar2); +} +#endif + +static void +hydro_sign_challenge(uint8_t challenge[hydro_sign_CHALLENGEBYTES], + const uint8_t nonce[hydro_sign_NONCEBYTES], + const uint8_t pk[hydro_sign_PUBLICKEYBYTES], + const uint8_t prehash[hydro_sign_PREHASHBYTES]) +{ + hydro_hash_state st; + + hydro_hash_init(&st, (const char *) zero, NULL); + hydro_hash_update(&st, nonce, hydro_sign_NONCEBYTES); + hydro_hash_update(&st, pk, hydro_sign_PUBLICKEYBYTES); + hydro_hash_update(&st, prehash, hydro_sign_PREHASHBYTES); + hydro_hash_final(&st, challenge, hydro_sign_CHALLENGEBYTES); +} + +#if !HYDRO_SIGN_VERIFY_ONLY +static int +hydro_sign_prehash(uint8_t csig[hydro_sign_BYTES], const uint8_t prehash[hydro_sign_PREHASHBYTES], + const uint8_t sk[hydro_sign_SECRETKEYBYTES]) +{ + hydro_hash_state st; + uint8_t challenge[hydro_sign_CHALLENGEBYTES]; + const uint8_t *pk = &sk[hydro_x25519_SECRETKEYBYTES]; + uint8_t *nonce = &csig[0]; + uint8_t *sig = &csig[hydro_sign_NONCEBYTES]; + uint8_t *eph_sk = sig; + + hydro_random_buf(eph_sk, hydro_x25519_SECRETKEYBYTES); + COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES == hydro_hash_KEYBYTES); + hydro_hash_init(&st, (const char *) zero, sk); + hydro_hash_update(&st, eph_sk, hydro_x25519_SECRETKEYBYTES); + hydro_hash_update(&st, prehash, hydro_sign_PREHASHBYTES); + hydro_hash_final(&st, eph_sk, hydro_x25519_SECRETKEYBYTES); + + hydro_x25519_scalarmult_base_uniform(nonce, eph_sk); + hydro_sign_challenge(challenge, nonce, pk, prehash); + + COMPILER_ASSERT(hydro_sign_BYTES == hydro_sign_NONCEBYTES + hydro_x25519_SECRETKEYBYTES); + COMPILER_ASSERT(hydro_x25519_SECRETKEYBYTES <= hydro_sign_CHALLENGEBYTES); + hydro_sign_p2(sig, challenge, eph_sk, sk); + + return 0; +} +#endif + +static int +hydro_sign_verify_core(hydro_x25519_fe xs[5], const hydro_x25519_limb_t *other1, + const uint8_t other2[hydro_x25519_BYTES]) +{ + hydro_x25519_limb_t *z2 = xs[1], *x3 = xs[2], *z3 = xs[3]; + hydro_x25519_fe xo2; + const hydro_x25519_limb_t sixteen = 16; + + hydro_x25519_swapin(xo2, other2); + memcpy(x3, other1, 2 * sizeof(hydro_x25519_fe)); + hydro_x25519_ladder_part1(xs); + + /* Here z2 = t2^2 */ + hydro_x25519_mul1(z2, other1); + hydro_x25519_mul1(z2, other1 + hydro_x25519_NLIMBS); + hydro_x25519_mul1(z2, xo2); + + hydro_x25519_mul(z2, z2, &sixteen, 1); + + hydro_x25519_mul1(z3, xo2); + hydro_x25519_sub(z3, z3, x3); + hydro_x25519_sqr1(z3); + + /* check equality */ + hydro_x25519_sub(z3, z3, z2); + + /* canon(z2): both sides are zero. canon(z3): the two sides are equal. */ + /* Reject sigs where both sides are zero. */ + return hydro_x25519_canon(z2) | ~hydro_x25519_canon(z3); +} + +static int +hydro_sign_verify_p2(const uint8_t sig[hydro_x25519_BYTES], + const uint8_t challenge[hydro_sign_CHALLENGEBYTES], + const uint8_t nonce[hydro_sign_NONCEBYTES], + const uint8_t pk[hydro_x25519_BYTES]) +{ + hydro_x25519_fe xs[7]; + + hydro_x25519_core(xs, challenge, pk, 0); + hydro_x25519_core(xs + 2, sig, hydro_x25519_BASE_POINT, 0); + + return hydro_sign_verify_core(xs + 2, xs[0], nonce); +} + +static int +hydro_sign_verify_challenge(const uint8_t csig[hydro_sign_BYTES], + const uint8_t challenge[hydro_sign_CHALLENGEBYTES], + const uint8_t pk[hydro_sign_PUBLICKEYBYTES]) +{ + const uint8_t *nonce = &csig[0]; + const uint8_t *sig = &csig[hydro_sign_NONCEBYTES]; + + return hydro_sign_verify_p2(sig, challenge, nonce, pk); +} + +#if !HYDRO_SIGN_VERIFY_ONLY +void +hydro_sign_keygen(hydro_sign_keypair *kp) +{ + uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES]; + + COMPILER_ASSERT(hydro_sign_SECRETKEYBYTES == + hydro_x25519_SECRETKEYBYTES + hydro_x25519_PUBLICKEYBYTES); + COMPILER_ASSERT(hydro_sign_PUBLICKEYBYTES == hydro_x25519_PUBLICKEYBYTES); + hydro_random_buf(kp->sk, hydro_x25519_SECRETKEYBYTES); + hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk); + memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES); +} + +void +hydro_sign_keygen_deterministic(hydro_sign_keypair *kp, const uint8_t seed[hydro_sign_SEEDBYTES]) +{ + uint8_t *pk_copy = &kp->sk[hydro_x25519_SECRETKEYBYTES]; + + COMPILER_ASSERT(hydro_sign_SEEDBYTES >= hydro_random_SEEDBYTES); + hydro_random_buf_deterministic(kp->sk, hydro_x25519_SECRETKEYBYTES, seed); + hydro_x25519_scalarmult_base_uniform(kp->pk, kp->sk); + memcpy(pk_copy, kp->pk, hydro_x25519_PUBLICKEYBYTES); +} +#endif + +int +hydro_sign_init(hydro_sign_state *state, const char ctx[hydro_sign_CONTEXTBYTES]) +{ + return hydro_hash_init(&state->hash_st, ctx, NULL); +} + +int +hydro_sign_update(hydro_sign_state *state, const void *m_, size_t mlen) +{ + return hydro_hash_update(&state->hash_st, m_, mlen); +} + +#if !HYDRO_SIGN_VERIFY_ONLY +int +hydro_sign_final_create(hydro_sign_state *state, uint8_t csig[hydro_sign_BYTES], + const uint8_t sk[hydro_sign_SECRETKEYBYTES]) +{ + uint8_t prehash[hydro_sign_PREHASHBYTES]; + + hydro_hash_final(&state->hash_st, prehash, sizeof prehash); + + return hydro_sign_prehash(csig, prehash, sk); +} +#endif + +int +hydro_sign_final_verify(hydro_sign_state *state, const uint8_t csig[hydro_sign_BYTES], + const uint8_t pk[hydro_sign_PUBLICKEYBYTES]) +{ + uint8_t challenge[hydro_sign_CHALLENGEBYTES]; + uint8_t prehash[hydro_sign_PREHASHBYTES]; + const uint8_t *nonce = &csig[0]; + + hydro_hash_final(&state->hash_st, prehash, sizeof prehash); + hydro_sign_challenge(challenge, nonce, pk, prehash); + + return hydro_sign_verify_challenge(csig, challenge, pk); +} + +#if !HYDRO_SIGN_VERIFY_ONLY +int +hydro_sign_create(uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen, + const char ctx[hydro_sign_CONTEXTBYTES], + const uint8_t sk[hydro_sign_SECRETKEYBYTES]) +{ + hydro_sign_state st; + + if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 || + hydro_sign_final_create(&st, csig, sk) != 0) { + return -1; + } + return 0; +} +#endif + +int +hydro_sign_verify(const uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen, + const char ctx[hydro_sign_CONTEXTBYTES], + const uint8_t pk[hydro_sign_PUBLICKEYBYTES]) +{ + hydro_sign_state st; + + if (hydro_sign_init(&st, ctx) != 0 || hydro_sign_update(&st, m_, mlen) != 0 || + hydro_sign_final_verify(&st, csig, pk) != 0) { + return -1; + } + return 0; +} diff --git a/thirdparty/libhydrogen/upstream/impl/x25519.h b/thirdparty/libhydrogen/upstream/impl/x25519.h new file mode 100644 index 000000000..ebdf851de --- /dev/null +++ b/thirdparty/libhydrogen/upstream/impl/x25519.h @@ -0,0 +1,390 @@ +/* + * Based on Michael Hamburg's STROBE reference implementation. + * Copyright (c) 2015-2016 Cryptography Research, Inc. + * MIT License (MIT) + */ + +#if defined(__GNUC__) && defined(__SIZEOF_INT128__) +# define hydro_x25519_WBITS 64 +#else +# define hydro_x25519_WBITS 32 +#endif + +#if hydro_x25519_WBITS == 64 +typedef uint64_t hydro_x25519_limb_t; +typedef __uint128_t hydro_x25519_dlimb_t; +typedef __int128_t hydro_x25519_sdlimb_t; +# define hydro_x25519_eswap_limb(X) LOAD64_LE((const uint8_t *) &(X)) +# define hydro_x25519_LIMB(x) x##ull +#elif hydro_x25519_WBITS == 32 +typedef uint32_t hydro_x25519_limb_t; +typedef uint64_t hydro_x25519_dlimb_t; +typedef int64_t hydro_x25519_sdlimb_t; +# define hydro_x25519_eswap_limb(X) LOAD32_LE((const uint8_t *) &(X)) +# define hydro_x25519_LIMB(x) (uint32_t)(x##ull), (uint32_t) ((x##ull) >> 32) +#else +# error "Need to know hydro_x25519_WBITS" +#endif + +#define hydro_x25519_NLIMBS (256 / hydro_x25519_WBITS) +typedef hydro_x25519_limb_t hydro_x25519_fe[hydro_x25519_NLIMBS]; + +typedef hydro_x25519_limb_t hydro_x25519_scalar_t[hydro_x25519_NLIMBS]; + +static const hydro_x25519_limb_t hydro_x25519_MONTGOMERY_FACTOR = + (hydro_x25519_limb_t) 0xd2b51da312547e1bull; + +static const hydro_x25519_scalar_t hydro_x25519_sc_p = { hydro_x25519_LIMB(0x5812631a5cf5d3ed), + hydro_x25519_LIMB(0x14def9dea2f79cd6), + hydro_x25519_LIMB(0x0000000000000000), + hydro_x25519_LIMB(0x1000000000000000) }; + +static const hydro_x25519_scalar_t hydro_x25519_sc_r2 = { hydro_x25519_LIMB(0xa40611e3449c0f01), + hydro_x25519_LIMB(0xd00e1ba768859347), + hydro_x25519_LIMB(0xceec73d217f5be65), + hydro_x25519_LIMB(0x0399411b7c309a3d) }; + +static const uint8_t hydro_x25519_BASE_POINT[hydro_x25519_BYTES] = { 9 }; + +static const hydro_x25519_limb_t hydro_x25519_a24[1] = { 121665 }; + +static inline hydro_x25519_limb_t +hydro_x25519_umaal(hydro_x25519_limb_t *carry, hydro_x25519_limb_t acc, hydro_x25519_limb_t mand, + hydro_x25519_limb_t mier) +{ + hydro_x25519_dlimb_t tmp = (hydro_x25519_dlimb_t) mand * mier + acc + *carry; + + *carry = tmp >> hydro_x25519_WBITS; + return (hydro_x25519_limb_t) tmp; +} + +static inline hydro_x25519_limb_t +hydro_x25519_adc(hydro_x25519_limb_t *carry, hydro_x25519_limb_t acc, hydro_x25519_limb_t mand) +{ + hydro_x25519_dlimb_t total = (hydro_x25519_dlimb_t) *carry + acc + mand; + + *carry = total >> hydro_x25519_WBITS; + return (hydro_x25519_limb_t) total; +} + +static inline hydro_x25519_limb_t +hydro_x25519_adc0(hydro_x25519_limb_t *carry, hydro_x25519_limb_t acc) +{ + hydro_x25519_dlimb_t total = (hydro_x25519_dlimb_t) *carry + acc; + + *carry = total >> hydro_x25519_WBITS; + return (hydro_x25519_limb_t) total; +} + +static void +hydro_x25519_propagate(hydro_x25519_fe x, hydro_x25519_limb_t over) +{ + hydro_x25519_limb_t carry; + int i; + + over = x[hydro_x25519_NLIMBS - 1] >> (hydro_x25519_WBITS - 1) | over << 1; + x[hydro_x25519_NLIMBS - 1] &= ~((hydro_x25519_limb_t) 1 << (hydro_x25519_WBITS - 1)); + carry = over * 19; + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + x[i] = hydro_x25519_adc0(&carry, x[i]); + } +} + +static void +hydro_x25519_add(hydro_x25519_fe out, const hydro_x25519_fe a, const hydro_x25519_fe b) +{ + hydro_x25519_limb_t carry = 0; + int i; + + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + out[i] = hydro_x25519_adc(&carry, a[i], b[i]); + } + hydro_x25519_propagate(out, carry); +} + +static void +hydro_x25519_sub(hydro_x25519_fe out, const hydro_x25519_fe a, const hydro_x25519_fe b) +{ + hydro_x25519_sdlimb_t carry = -76; + int i; + + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + out[i] = (hydro_x25519_limb_t) (carry = carry + a[i] - b[i]); + carry >>= hydro_x25519_WBITS; + } + hydro_x25519_propagate(out, (hydro_x25519_limb_t) (2 + carry)); +} + +static void +hydro_x25519_swapin(hydro_x25519_limb_t *x, const uint8_t *in) +{ + int i; + + memcpy(x, in, sizeof(hydro_x25519_fe)); + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + x[i] = hydro_x25519_eswap_limb(x[i]); + } +} + +static void +hydro_x25519_swapout(uint8_t *out, hydro_x25519_limb_t *x) +{ + int i; + + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + x[i] = hydro_x25519_eswap_limb(x[i]); + } + memcpy(out, x, sizeof(hydro_x25519_fe)); +} + +static void +hydro_x25519_mul(hydro_x25519_fe out, const hydro_x25519_fe a, const hydro_x25519_limb_t b[], + const int nb) +{ + hydro_x25519_limb_t accum[2 * hydro_x25519_NLIMBS] = { 0 }; + hydro_x25519_limb_t carry2; + int i, j; + + for (i = 0; i < nb; i++) { + hydro_x25519_limb_t mand = b[i]; + carry2 = 0; + + for (j = 0; j < hydro_x25519_NLIMBS; j++) { + accum[i + j] = hydro_x25519_umaal(&carry2, accum[i + j], mand, a[j]); + } + accum[i + j] = carry2; + } + carry2 = 0; + for (j = 0; j < hydro_x25519_NLIMBS; j++) { + const hydro_x25519_limb_t mand = 38; + + out[j] = hydro_x25519_umaal(&carry2, accum[j], mand, accum[j + hydro_x25519_NLIMBS]); + } + hydro_x25519_propagate(out, carry2); +} + +static void +hydro_x25519_sqr(hydro_x25519_fe out, const hydro_x25519_fe a) +{ + hydro_x25519_mul(out, a, a, hydro_x25519_NLIMBS); +} + +static void +hydro_x25519_mul1(hydro_x25519_fe out, const hydro_x25519_fe a) +{ + hydro_x25519_mul(out, a, out, hydro_x25519_NLIMBS); +} + +static void +hydro_x25519_sqr1(hydro_x25519_fe a) +{ + hydro_x25519_mul1(a, a); +} + +static void +hydro_x25519_condswap(hydro_x25519_limb_t a[2 * hydro_x25519_NLIMBS], + hydro_x25519_limb_t b[2 * hydro_x25519_NLIMBS], hydro_x25519_limb_t doswap) +{ + int i; + + for (i = 0; i < 2 * hydro_x25519_NLIMBS; i++) { + hydro_x25519_limb_t xorv = (a[i] ^ b[i]) & doswap; + a[i] ^= xorv; + b[i] ^= xorv; + } +} + +static int +hydro_x25519_canon(hydro_x25519_fe x) +{ + hydro_x25519_sdlimb_t carry; + hydro_x25519_limb_t carry0 = 19; + hydro_x25519_limb_t res; + int i; + + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + x[i] = hydro_x25519_adc0(&carry0, x[i]); + } + hydro_x25519_propagate(x, carry0); + carry = -19; + res = 0; + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + res |= x[i] = (hydro_x25519_limb_t) (carry += x[i]); + carry >>= hydro_x25519_WBITS; + } + return ((hydro_x25519_dlimb_t) res - 1) >> hydro_x25519_WBITS; +} + +static void +hydro_x25519_ladder_part1(hydro_x25519_fe xs[5]) +{ + hydro_x25519_limb_t *x2 = xs[0], *z2 = xs[1], *x3 = xs[2], *z3 = xs[3], *t1 = xs[4]; + + hydro_x25519_add(t1, x2, z2); // t1 = A + hydro_x25519_sub(z2, x2, z2); // z2 = B + hydro_x25519_add(x2, x3, z3); // x2 = C + hydro_x25519_sub(z3, x3, z3); // z3 = D + hydro_x25519_mul1(z3, t1); // z3 = DA + hydro_x25519_mul1(x2, z2); // x3 = BC + hydro_x25519_add(x3, z3, x2); // x3 = DA+CB + hydro_x25519_sub(z3, z3, x2); // z3 = DA-CB + hydro_x25519_sqr1(t1); // t1 = AA + hydro_x25519_sqr1(z2); // z2 = BB + hydro_x25519_sub(x2, t1, z2); // x2 = E = AA-BB + hydro_x25519_mul(z2, x2, hydro_x25519_a24, // z2 = E*a24 + sizeof(hydro_x25519_a24) / sizeof(hydro_x25519_a24[0])); + hydro_x25519_add(z2, z2, t1); // z2 = E*a24 + AA +} + +static void +hydro_x25519_ladder_part2(hydro_x25519_fe xs[5], const hydro_x25519_fe x1) +{ + hydro_x25519_limb_t *x2 = xs[0], *z2 = xs[1], *x3 = xs[2], *z3 = xs[3], *t1 = xs[4]; + + hydro_x25519_sqr1(z3); // z3 = (DA-CB)^2 + hydro_x25519_mul1(z3, x1); // z3 = x1 * (DA-CB)^2 + hydro_x25519_sqr1(x3); // x3 = (DA+CB)^2 + hydro_x25519_mul1(z2, x2); // z2 = AA*(E*a24+AA) + hydro_x25519_sub(x2, t1, x2); // x2 = BB again + hydro_x25519_mul1(x2, t1); // x2 = AA*BB +} + +static void +hydro_x25519_core(hydro_x25519_fe xs[5], const uint8_t scalar[hydro_x25519_BYTES], + const uint8_t *x1, bool clamp) +{ + hydro_x25519_limb_t swap; + hydro_x25519_limb_t *x2 = xs[0], *x3 = xs[2], *z3 = xs[3]; + hydro_x25519_fe x1i; + int i; + + hydro_x25519_swapin(x1i, x1); + x1 = (const uint8_t *) x1i; + swap = 0; + mem_zero(xs, 4 * sizeof(hydro_x25519_fe)); + x2[0] = z3[0] = 1; + memcpy(x3, x1, sizeof(hydro_x25519_fe)); + for (i = 255; i >= 0; i--) { + uint8_t bytei = scalar[i / 8]; + hydro_x25519_limb_t doswap; + hydro_x25519_fe x1_dup; + + if (clamp) { + if (i / 8 == 0) { + bytei &= ~7; + } else if (i / 8 == hydro_x25519_BYTES - 1) { + bytei &= 0x7F; + bytei |= 0x40; + } + } + doswap = 1U + ~(hydro_x25519_limb_t) ((bytei >> (i % 8)) & 1); + hydro_x25519_condswap(x2, x3, swap ^ doswap); + swap = doswap; + hydro_x25519_ladder_part1(xs); + memcpy(x1_dup, x1, sizeof x1_dup); + hydro_x25519_ladder_part2(xs, x1_dup); + } + hydro_x25519_condswap(x2, x3, swap); +} + +static int +hydro_x25519_scalarmult(uint8_t out[hydro_x25519_BYTES], + const uint8_t scalar[hydro_x25519_SECRETKEYBYTES], + const uint8_t x1[hydro_x25519_PUBLICKEYBYTES], bool clamp) +{ + hydro_x25519_fe xs[5]; + hydro_x25519_limb_t *x2, *z2, *z3; + hydro_x25519_limb_t *prev; + int i; + int ret; + + hydro_x25519_core(xs, scalar, x1, clamp); + + /* Precomputed inversion chain */ + x2 = xs[0]; + z2 = xs[1]; + z3 = xs[3]; + prev = z2; + + /* Raise to the p-2 = 0x7f..ffeb */ + for (i = 253; i >= 0; i--) { + hydro_x25519_sqr(z3, prev); + prev = z3; + if (i >= 8 || (0xeb >> i & 1)) { + hydro_x25519_mul1(z3, z2); + } + } + + /* Here prev = z3 */ + /* x2 /= z2 */ + hydro_x25519_mul1(x2, z3); + ret = hydro_x25519_canon(x2); + hydro_x25519_swapout(out, x2); + + if (clamp == 0) { + return 0; + } + return ret; +} + +static inline int +hydro_x25519_scalarmult_base(uint8_t pk[hydro_x25519_PUBLICKEYBYTES], + const uint8_t sk[hydro_x25519_SECRETKEYBYTES]) +{ + return hydro_x25519_scalarmult(pk, sk, hydro_x25519_BASE_POINT, 1); +} + +#if !HYDRO_SIGN_VERIFY_ONLY || !HYDRO_DISABLE_KX +static inline void +hydro_x25519_scalarmult_base_uniform(uint8_t pk[hydro_x25519_PUBLICKEYBYTES], + const uint8_t sk[hydro_x25519_SECRETKEYBYTES]) +{ + if (hydro_x25519_scalarmult(pk, sk, hydro_x25519_BASE_POINT, 0) != 0) { + abort(); + } +} +#endif + +#if !HYDRO_SIGN_VERIFY_ONLY +static void +hydro_x25519_sc_montmul(hydro_x25519_scalar_t out, const hydro_x25519_scalar_t a, + const hydro_x25519_scalar_t b) +{ + hydro_x25519_limb_t hic = 0; + int i, j; + + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + hydro_x25519_limb_t carry = 0, carry2 = 0, mand = a[i], + mand2 = hydro_x25519_MONTGOMERY_FACTOR; + + for (j = 0; j < hydro_x25519_NLIMBS; j++) { + hydro_x25519_limb_t acc = out[j]; + + acc = hydro_x25519_umaal(&carry, acc, mand, b[j]); + if (j == 0) { + mand2 *= acc; + } + acc = hydro_x25519_umaal(&carry2, acc, mand2, hydro_x25519_sc_p[j]); + if (j > 0) { + out[j - 1] = acc; + } + } + + /* Add two carry registers and high carry */ + out[hydro_x25519_NLIMBS - 1] = hydro_x25519_adc(&hic, carry, carry2); + } + + /* Reduce */ + hydro_x25519_sdlimb_t scarry = 0; + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + out[i] = (hydro_x25519_limb_t) (scarry = scarry + out[i] - hydro_x25519_sc_p[i]); + scarry >>= hydro_x25519_WBITS; + } + hydro_x25519_limb_t need_add = (hydro_x25519_limb_t) - (scarry + hic); + + hydro_x25519_limb_t carry = 0; + for (i = 0; i < hydro_x25519_NLIMBS; i++) { + out[i] = hydro_x25519_umaal(&carry, out[i], need_add, hydro_x25519_sc_p[i]); + } +} +#endif diff --git a/thirdparty/libhydrogen/upstream/libhydrogen.c b/thirdparty/libhydrogen/upstream/libhydrogen.c new file mode 100644 index 000000000..8fe2a7418 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/libhydrogen.c @@ -0,0 +1,29 @@ +#include "libhydrogen.h" + +#include "impl/common.h" +#include "impl/hydrogen_p.h" + +#if !HYDRO_DISABLE_RANDOM +# include "impl/random.h" +#endif + +#include "impl/core.h" +#include "impl/gimli-core.h" + +#include "impl/hash.h" +#if !HYDRO_DISABLE_KDF +# include "impl/kdf.h" +#endif +#if !HYDRO_DISABLE_SECRETBOX +# include "impl/secretbox.h" +#endif + +#include "impl/x25519.h" + +#if !HYDRO_DISABLE_KX +# include "impl/kx.h" +#endif +#if !HYDRO_DISABLE_PWHASH +# include "impl/pwhash.h" +#endif +#include "impl/sign.h" diff --git a/thirdparty/libhydrogen/upstream/libhydrogen.h b/thirdparty/libhydrogen/upstream/libhydrogen.h new file mode 100644 index 000000000..b40033c07 --- /dev/null +++ b/thirdparty/libhydrogen/upstream/libhydrogen.h @@ -0,0 +1,409 @@ +#ifndef libhydrogen_H +#define libhydrogen_H + +#if !(defined(__linux__) && defined(__KERNEL__)) +# include +# include +# include +#endif + +#if !defined(__cplusplus) && defined(__GNUC__) +# pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#endif + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#if defined(__clang__) || defined(__GNUC__) +# define _hydro_attr_(X) __attribute__(X) +#else +# define _hydro_attr_(X) +#endif +#define _hydro_attr_deprecated_ _hydro_attr_((deprecated)) +#define _hydro_attr_malloc_ _hydro_attr_((malloc)) +#define _hydro_attr_noinline_ _hydro_attr_((noinline)) +#define _hydro_attr_noreturn_ _hydro_attr_((noreturn)) +#define _hydro_attr_warn_unused_result_ _hydro_attr_((warn_unused_result)) +#define _hydro_attr_weak_ _hydro_attr_((weak)) + +#if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define _hydro_attr_aligned_(X) __declspec(align(X)) +#elif defined(__clang__) || defined(__GNUC__) +# define _hydro_attr_aligned_(X) _hydro_attr_((aligned(X))) +#else +# define _hydro_attr_aligned_(X) +#endif + +#define HYDRO_VERSION_MAJOR 1 +#define HYDRO_VERSION_MINOR 0 + +/* Feature configuration flags + * Define these before including libhydrogen.h to disable features + * and reduce code size. + * + * Example: #define HYDRO_SIGN_VERIFY_ONLY 1 + */ +#ifndef HYDRO_SIGN_VERIFY_ONLY +# define HYDRO_SIGN_VERIFY_ONLY 0 +#endif + +#ifndef HYDRO_DISABLE_KX +# define HYDRO_DISABLE_KX 0 +#endif + +#ifndef HYDRO_DISABLE_SECRETBOX +# define HYDRO_DISABLE_SECRETBOX 0 +#endif + +#ifndef HYDRO_DISABLE_KDF +# define HYDRO_DISABLE_KDF 0 +#endif + +#ifndef HYDRO_DISABLE_PWHASH +# define HYDRO_DISABLE_PWHASH 0 +#endif + +#ifndef HYDRO_DISABLE_RANDOM +# define HYDRO_DISABLE_RANDOM 0 +#endif + +/* Automatically disable unused modules when verify-only mode is enabled. + * Verification only needs hash and X25519 operations, not random, KDF, + * secretbox, KX, or pwhash. + */ +#if HYDRO_SIGN_VERIFY_ONLY +# ifndef HYDRO_DISABLE_RANDOM +# define HYDRO_DISABLE_RANDOM 1 +# endif +# ifndef HYDRO_DISABLE_KDF +# define HYDRO_DISABLE_KDF 1 +# endif +# ifndef HYDRO_DISABLE_SECRETBOX +# define HYDRO_DISABLE_SECRETBOX 1 +# endif +# ifndef HYDRO_DISABLE_KX +# define HYDRO_DISABLE_KX 1 +# endif +# ifndef HYDRO_DISABLE_PWHASH +# define HYDRO_DISABLE_PWHASH 1 +# endif +#endif + +int hydro_init(void); + +/* ---------------- */ + +#if !HYDRO_DISABLE_RANDOM +# define hydro_random_SEEDBYTES 32 + +uint32_t hydro_random_u32(void); + +uint32_t hydro_random_uniform(const uint32_t upper_bound); + +void hydro_random_buf(void *out, size_t out_len); + +void hydro_random_buf_deterministic(void *out, size_t out_len, + const uint8_t seed[hydro_random_SEEDBYTES]); + +void hydro_random_ratchet(void); + +void hydro_random_reseed(void); +#endif + +/* ---------------- */ + +#define hydro_hash_BYTES 32 +#define hydro_hash_BYTES_MAX 65535 +#define hydro_hash_BYTES_MIN 16 +#define hydro_hash_CONTEXTBYTES 8 +#define hydro_hash_KEYBYTES 32 + +typedef struct hydro_hash_state { + uint32_t state[12]; + uint8_t buf_off; + uint8_t align[3]; +} hydro_hash_state; + +void hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES]); + +int hydro_hash_init(hydro_hash_state *state, const char ctx[hydro_hash_CONTEXTBYTES], + const uint8_t key[hydro_hash_KEYBYTES]); + +int hydro_hash_update(hydro_hash_state *state, const void *in_, size_t in_len); + +int hydro_hash_final(hydro_hash_state *state, uint8_t *out, size_t out_len); + +int hydro_hash_hash(uint8_t *out, size_t out_len, const void *in_, size_t in_len, + const char ctx[hydro_hash_CONTEXTBYTES], + const uint8_t key[hydro_hash_KEYBYTES]); + +#if !HYDRO_DISABLE_RANDOM +void hydro_hash_keygen(uint8_t key[hydro_hash_KEYBYTES]); +#endif + +/* ---------------- */ + +#if !HYDRO_DISABLE_SECRETBOX +# define hydro_secretbox_CONTEXTBYTES 8 +# define hydro_secretbox_HEADERBYTES (20 + 16) +# define hydro_secretbox_KEYBYTES 32 +# define hydro_secretbox_PROBEBYTES 16 + +void hydro_secretbox_keygen(uint8_t key[hydro_secretbox_KEYBYTES]); + +int hydro_secretbox_encrypt(uint8_t *c, const void *m_, size_t mlen, uint64_t msg_id, + const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]); + +int hydro_secretbox_decrypt(void *m_, const uint8_t *c, size_t clen, uint64_t msg_id, + const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]) + _hydro_attr_warn_unused_result_; + +void hydro_secretbox_probe_create(uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c, + size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]); + +int hydro_secretbox_probe_verify(const uint8_t probe[hydro_secretbox_PROBEBYTES], const uint8_t *c, + size_t c_len, const char ctx[hydro_secretbox_CONTEXTBYTES], + const uint8_t key[hydro_secretbox_KEYBYTES]) + _hydro_attr_warn_unused_result_; +#endif + +/* ---------------- */ + +#if !HYDRO_DISABLE_KDF +# define hydro_kdf_CONTEXTBYTES 8 +# define hydro_kdf_KEYBYTES 32 +# define hydro_kdf_BYTES_MAX 65535 +# define hydro_kdf_BYTES_MIN 16 + +void hydro_kdf_keygen(uint8_t key[hydro_kdf_KEYBYTES]); + +int hydro_kdf_derive_from_key(uint8_t *subkey, size_t subkey_len, uint64_t subkey_id, + const char ctx[hydro_kdf_CONTEXTBYTES], + const uint8_t key[hydro_kdf_KEYBYTES]); +#endif + +/* ---------------- */ + +#define hydro_sign_BYTES 64 +#define hydro_sign_CONTEXTBYTES 8 +#define hydro_sign_PUBLICKEYBYTES 32 +#define hydro_sign_SECRETKEYBYTES 64 +#define hydro_sign_SEEDBYTES 32 + +typedef struct hydro_sign_state { + hydro_hash_state hash_st; +} hydro_sign_state; + +typedef struct hydro_sign_keypair { + uint8_t pk[hydro_sign_PUBLICKEYBYTES]; + uint8_t sk[hydro_sign_SECRETKEYBYTES]; +} hydro_sign_keypair; + +#if !HYDRO_SIGN_VERIFY_ONLY +void hydro_sign_keygen(hydro_sign_keypair *kp); + +void hydro_sign_keygen_deterministic(hydro_sign_keypair *kp, + const uint8_t seed[hydro_sign_SEEDBYTES]); +#endif + +int hydro_sign_init(hydro_sign_state *state, const char ctx[hydro_sign_CONTEXTBYTES]); + +int hydro_sign_update(hydro_sign_state *state, const void *m_, size_t mlen); + +#if !HYDRO_SIGN_VERIFY_ONLY +int hydro_sign_final_create(hydro_sign_state *state, uint8_t csig[hydro_sign_BYTES], + const uint8_t sk[hydro_sign_SECRETKEYBYTES]); +#endif + +int hydro_sign_final_verify(hydro_sign_state *state, const uint8_t csig[hydro_sign_BYTES], + const uint8_t pk[hydro_sign_PUBLICKEYBYTES]) + _hydro_attr_warn_unused_result_; + +#if !HYDRO_SIGN_VERIFY_ONLY +int hydro_sign_create(uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen, + const char ctx[hydro_sign_CONTEXTBYTES], + const uint8_t sk[hydro_sign_SECRETKEYBYTES]); +#endif + +int hydro_sign_verify(const uint8_t csig[hydro_sign_BYTES], const void *m_, size_t mlen, + const char ctx[hydro_sign_CONTEXTBYTES], + const uint8_t pk[hydro_sign_PUBLICKEYBYTES]) _hydro_attr_warn_unused_result_; + +/* ---------------- */ + +#if !HYDRO_DISABLE_KX +# define hydro_kx_SESSIONKEYBYTES 32 +# define hydro_kx_PUBLICKEYBYTES 32 +# define hydro_kx_SECRETKEYBYTES 32 +# define hydro_kx_PSKBYTES 32 +# define hydro_kx_SEEDBYTES 32 + +typedef struct hydro_kx_keypair { + uint8_t pk[hydro_kx_PUBLICKEYBYTES]; + uint8_t sk[hydro_kx_SECRETKEYBYTES]; +} hydro_kx_keypair; + +typedef struct hydro_kx_session_keypair { + uint8_t rx[hydro_kx_SESSIONKEYBYTES]; + uint8_t tx[hydro_kx_SESSIONKEYBYTES]; +} hydro_kx_session_keypair; + +typedef struct hydro_kx_state { + hydro_kx_keypair eph_kp; + hydro_hash_state h_st; +} hydro_kx_state; + +void hydro_kx_keygen(hydro_kx_keypair *static_kp); + +void hydro_kx_keygen_deterministic(hydro_kx_keypair *static_kp, + const uint8_t seed[hydro_kx_SEEDBYTES]); + +/* NOISE_N */ + +# define hydro_kx_N_PACKET1BYTES (32 + 16) + +int hydro_kx_n_1(hydro_kx_session_keypair *kp, uint8_t packet1[hydro_kx_N_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]); + +int hydro_kx_n_2(hydro_kx_session_keypair *kp, const uint8_t packet1[hydro_kx_N_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp); + +/* NOISE_KK */ + +# define hydro_kx_KK_PACKET1BYTES (32 + 16) +# define hydro_kx_KK_PACKET2BYTES (32 + 16) + +int hydro_kx_kk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_KK_PACKET1BYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const hydro_kx_keypair *static_kp); + +int hydro_kx_kk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_KK_PACKET2BYTES], + const uint8_t packet1[hydro_kx_KK_PACKET1BYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const hydro_kx_keypair *static_kp); + +int hydro_kx_kk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp, + const uint8_t packet2[hydro_kx_KK_PACKET2BYTES], + const hydro_kx_keypair *static_kp); + +/* NOISE_XX */ + +# define hydro_kx_XX_PACKET1BYTES (32 + 16) +# define hydro_kx_XX_PACKET2BYTES (32 + 32 + 16 + 16) +# define hydro_kx_XX_PACKET3BYTES (32 + 16 + 16) + +int hydro_kx_xx_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_XX_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES]); + +int hydro_kx_xx_2(hydro_kx_state *state, uint8_t packet2[hydro_kx_XX_PACKET2BYTES], + const uint8_t packet1[hydro_kx_XX_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp); + +int hydro_kx_xx_3(hydro_kx_state *state, hydro_kx_session_keypair *kp, + uint8_t packet3[hydro_kx_XX_PACKET3BYTES], + uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const uint8_t packet2[hydro_kx_XX_PACKET2BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp); + +int hydro_kx_xx_4(hydro_kx_state *state, hydro_kx_session_keypair *kp, + uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES], + const uint8_t packet3[hydro_kx_XX_PACKET3BYTES], + const uint8_t psk[hydro_kx_PSKBYTES]); + +/* NOISE_NK */ + +# define hydro_kx_NK_PACKET1BYTES (32 + 16) +# define hydro_kx_NK_PACKET2BYTES (32 + 16) + +int hydro_kx_nk_1(hydro_kx_state *state, uint8_t packet1[hydro_kx_NK_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], + const uint8_t peer_static_pk[hydro_kx_PUBLICKEYBYTES]); + +int hydro_kx_nk_2(hydro_kx_session_keypair *kp, uint8_t packet2[hydro_kx_NK_PACKET2BYTES], + const uint8_t packet1[hydro_kx_NK_PACKET1BYTES], + const uint8_t psk[hydro_kx_PSKBYTES], const hydro_kx_keypair *static_kp); + +int hydro_kx_nk_3(hydro_kx_state *state, hydro_kx_session_keypair *kp, + const uint8_t packet2[hydro_kx_NK_PACKET2BYTES]); +#endif + +/* ---------------- */ + +#if !HYDRO_DISABLE_PWHASH +# define hydro_pwhash_CONTEXTBYTES 8 +# define hydro_pwhash_MASTERKEYBYTES 32 +# define hydro_pwhash_STOREDBYTES 128 + +void hydro_pwhash_keygen(uint8_t master_key[hydro_pwhash_MASTERKEYBYTES]); + +int hydro_pwhash_deterministic(uint8_t *h, size_t h_len, const char *passwd, size_t passwd_len, + const char ctx[hydro_pwhash_CONTEXTBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit, size_t memlimit, uint8_t threads); + +int hydro_pwhash_create(uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, + size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit, size_t memlimit, uint8_t threads); + +int hydro_pwhash_verify(const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, + size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max); + +int hydro_pwhash_derive_static_key(uint8_t *static_key, size_t static_key_len, + const uint8_t stored[hydro_pwhash_STOREDBYTES], + const char *passwd, size_t passwd_len, + const char ctx[hydro_pwhash_CONTEXTBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max); + +int hydro_pwhash_reencrypt(uint8_t stored[hydro_pwhash_STOREDBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], + const uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES]); + +int hydro_pwhash_upgrade(uint8_t stored[hydro_pwhash_STOREDBYTES], + const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit, + size_t memlimit, uint8_t threads); +#endif + +/* ---------------- */ + +void hydro_memzero(void *pnt, size_t len); + +void hydro_increment(uint8_t *n, size_t len); + +bool hydro_equal(const void *b1_, const void *b2_, size_t len); + +int hydro_compare(const uint8_t *b1_, const uint8_t *b2_, size_t len); + +char *hydro_bin2hex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len); + +int hydro_hex2bin(uint8_t *bin, size_t bin_maxlen, const char *hex, size_t hex_len, + const char *ignore, const char **hex_end_p); + +int hydro_pad(unsigned char *buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen); + +int hydro_unpad(const unsigned char *buf, size_t padded_buflen, size_t blocksize); + +/* ---------------- */ + +#define HYDRO_HWTYPE_ATMEGA328 1 + +#ifndef HYDRO_HWTYPE +# ifdef __AVR__ +# define HYDRO_HWTYPE HYDRO_HWTYPE_ATMEGA328 +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/libpng/libpng.c b/thirdparty/libpng/libpng.c index c09d3b605..e6f8ce228 100644 --- a/thirdparty/libpng/libpng.c +++ b/thirdparty/libpng/libpng.c @@ -21,21 +21,59 @@ #include "libpng.h" +#if defined (__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers" +#endif + #include "upstream/png.c" #include "upstream/pngerror.c" #include "upstream/pngget.c" #include "upstream/pngmem.c" #include "upstream/pngread.c" + +#define png_pass_start yup_pngpread_pass_start +#define png_pass_inc yup_pngpread_pass_inc +#define png_pass_ystart yup_pngpread_pass_ystart +#define png_pass_yinc yup_pngpread_pass_yinc #include "upstream/pngpread.c" +#undef png_pass_start +#undef png_pass_inc +#undef png_pass_ystart +#undef png_pass_yinc + #include "upstream/pngrio.c" #include "upstream/pngrtran.c" + +#define png_pass_start yup_pngrutil_pass_start +#define png_pass_inc yup_pngrutil_pass_inc +#define png_pass_ystart yup_pngrutil_pass_ystart +#define png_pass_yinc yup_pngrutil_pass_yinc #include "upstream/pngrutil.c" +#undef png_pass_start +#undef png_pass_inc +#undef png_pass_ystart +#undef png_pass_yinc + #include "upstream/pngset.c" #include "upstream/pngtrans.c" #include "upstream/pngwio.c" #include "upstream/pngwrite.c" #include "upstream/pngwtran.c" + +#define png_pass_start yup_pngwutil_pass_start +#define png_pass_inc yup_pngwutil_pass_inc +#define png_pass_ystart yup_pngwutil_pass_ystart +#define png_pass_yinc yup_pngwutil_pass_yinc #include "upstream/pngwutil.c" +#undef png_pass_start +#undef png_pass_inc +#undef png_pass_ystart +#undef png_pass_yinc + +#if defined (__clang__) + #pragma clang diagnostic pop +#endif #if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64) #include "upstream/arm/arm_init.c" diff --git a/thirdparty/libpng/upstream/LICENSE b/thirdparty/libpng/upstream/LICENSE index 1cd265543..1b765ae9f 100644 --- a/thirdparty/libpng/upstream/LICENSE +++ b/thirdparty/libpng/upstream/LICENSE @@ -1,134 +1,134 @@ -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE -========================================= - -PNG Reference Library License version 2 ---------------------------------------- - - * Copyright (c) 1995-2024 The PNG Reference Library Authors. - * Copyright (c) 2018-2024 Cosmin Truta. - * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. - * Copyright (c) 1996-1997 Andreas Dilger. - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - -The software is supplied "as is", without warranty of any kind, -express or implied, including, without limitation, the warranties -of merchantability, fitness for a particular purpose, title, and -non-infringement. In no event shall the Copyright owners, or -anyone distributing the software, be liable for any damages or -other liability, whether in contract, tort or otherwise, arising -from, out of, or in connection with the software, or the use or -other dealings in the software, even if advised of the possibility -of such damage. - -Permission is hereby granted to use, copy, modify, and distribute -this software, or portions hereof, for any purpose, without fee, -subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you - must not claim that you wrote the original software. If you - use this software in a product, an acknowledgment in the product - documentation would be appreciated, but is not required. - - 2. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 3. This Copyright notice may not be removed or altered from any - source or altered source distribution. - - -PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) ------------------------------------------------------------------------ - -libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are -Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are -derived from libpng-1.0.6, and are distributed according to the same -disclaimer and license as libpng-1.0.6 with the following individuals -added to the list of Contributing Authors: - - Simon-Pierre Cadieux - Eric S. Raymond - Mans Rullgard - Cosmin Truta - Gilles Vollant - James Yu - Mandar Sahastrabuddhe - Google Inc. - Vadim Barkov - -and with the following additions to the disclaimer: - - There is no warranty against interference with your enjoyment of - the library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is - with the user. - -Some files in the "contrib" directory and some configure-generated -files that are distributed with libpng have other copyright owners, and -are released under other open source licenses. - -libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are -Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from -libpng-0.96, and are distributed according to the same disclaimer and -license as libpng-0.96, with the following individuals added to the -list of Contributing Authors: - - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik - -libpng versions 0.89, June 1996, through 0.96, May 1997, are -Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, -and are distributed according to the same disclaimer and license as -libpng-0.88, with the following individuals added to the list of -Contributing Authors: - - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner - -Some files in the "scripts" directory have other copyright owners, -but are released under this license. - -libpng versions 0.5, May 1995, through 0.88, January 1996, are -Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - -For the purposes of this copyright and license, "Contributing Authors" -is defined as the following set of individuals: - - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner - -The PNG Reference Library is supplied "AS IS". The Contributing -Authors and Group 42, Inc. disclaim all warranties, expressed or -implied, including, without limitation, the warranties of -merchantability and of fitness for any purpose. The Contributing -Authors and Group 42, Inc. assume no liability for direct, indirect, -incidental, special, exemplary, or consequential damages, which may -result from the use of the PNG Reference Library, even if advised of -the possibility of such damage. - -Permission is hereby granted to use, copy, modify, and distribute this -source code, or portions hereof, for any purpose, without fee, subject -to the following restrictions: - - 1. The origin of this source code must not be misrepresented. - - 2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. - - 3. This Copyright notice may not be removed or altered from any - source or altered source distribution. - -The Contributing Authors and Group 42, Inc. specifically permit, -without fee, and encourage the use of this source code as a component -to supporting the PNG file format in commercial products. If you use -this source code in a product, acknowledgment is not required but would -be appreciated. +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE +========================================= + +PNG Reference Library License version 2 +--------------------------------------- + + * Copyright (c) 1995-2026 The PNG Reference Library Authors. + * Copyright (c) 2018-2026 Cosmin Truta. + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * Copyright (c) 1996-1997 Andreas Dilger. + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + +The software is supplied "as is", without warranty of any kind, +express or implied, including, without limitation, the warranties +of merchantability, fitness for a particular purpose, title, and +non-infringement. In no event shall the Copyright owners, or +anyone distributing the software, be liable for any damages or +other liability, whether in contract, tort or otherwise, arising +from, out of, or in connection with the software, or the use or +other dealings in the software, even if advised of the possibility +of such damage. + +Permission is hereby granted to use, copy, modify, and distribute +this software, or portions hereof, for any purpose, without fee, +subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you + use this software in a product, an acknowledgment in the product + documentation would be appreciated, but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) +----------------------------------------------------------------------- + +libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are +Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are +derived from libpng-1.0.6, and are distributed according to the same +disclaimer and license as libpng-1.0.6 with the following individuals +added to the list of Contributing Authors: + + Simon-Pierre Cadieux + Eric S. Raymond + Mans Rullgard + Cosmin Truta + Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of + the library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. + +Some files in the "contrib" directory and some configure-generated +files that are distributed with libpng have other copyright owners, and +are released under other open source licenses. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from +libpng-0.96, and are distributed according to the same disclaimer and +license as libpng-0.96, with the following individuals added to the +list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, +and are distributed according to the same disclaimer and license as +libpng-0.88, with the following individuals added to the list of +Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +Some files in the "scripts" directory have other copyright owners, +but are released under this license. + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing +Authors and Group 42, Inc. disclaim all warranties, expressed or +implied, including, without limitation, the warranties of +merchantability and of fitness for any purpose. The Contributing +Authors and Group 42, Inc. assume no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the PNG Reference Library, even if advised of +the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + + 1. The origin of this source code must not be misrepresented. + + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, +without fee, and encourage the use of this source code as a component +to supporting the PNG file format in commercial products. If you use +this source code in a product, acknowledgment is not required but would +be appreciated. diff --git a/thirdparty/libpng/upstream/arm/arm_init.c b/thirdparty/libpng/upstream/arm/arm_init.c index 1fd84008f..0ea9c836c 100644 --- a/thirdparty/libpng/upstream/arm/arm_init.c +++ b/thirdparty/libpng/upstream/arm/arm_init.c @@ -1,139 +1,138 @@ - -/* arm_init.c - NEON optimised filter functions - * - * Copyright (c) 2018-2022 Cosmin Truta - * Copyright (c) 2014,2016 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* This module requires POSIX 1003.1 functions. */ -#define _POSIX_SOURCE 1 - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -#if PNG_ARM_NEON_OPT > 0 -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ -/* WARNING: it is strongly recommended that you do not build libpng with - * run-time checks for CPU features if at all possible. In the case of the ARM - * NEON instructions there is no processor-specific way of detecting the - * presence of the required support, therefore run-time detection is extremely - * OS specific. - * - * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing - * a fragment of C source code which defines the png_have_neon function. There - * are a number of implementations in contrib/arm-neon, but the only one that - * has partial support is contrib/arm-neon/linux.c - a generic Linux - * implementation which reads /proc/cpufino. - */ -#include /* for sig_atomic_t */ - -#ifndef PNG_ARM_NEON_FILE -# if defined(__aarch64__) || defined(_M_ARM64) - /* ARM Neon is expected to be unconditionally available on ARM64. */ -# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64" -# elif defined(__ARM_NEON__) || defined(__ARM_NEON) - /* ARM Neon is expected to be available on the target CPU architecture. */ -# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch" -# elif defined(__linux__) -# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" -# else -# error "No support for run-time ARM Neon checking; use compile-time options" -# endif -#endif - -static int png_have_neon(png_structp png_ptr); -#ifdef PNG_ARM_NEON_FILE -# include PNG_ARM_NEON_FILE -#endif -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifndef PNG_ALIGNED_MEMORY_SUPPORTED -# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" -#endif - -void -png_init_filter_functions_neon(png_structp pp, unsigned int bpp) -{ - /* The switch statement is compiled in for ARM_NEON_API, the call to - * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined - * the check is only performed if the API has not set the NEON option on - * or off explicitly. In this case the check controls what happens. - * - * If the CHECK is not compiled in and the option is UNSET the behavior prior - * to 1.6.7 was to use the NEON code - this was a bug caused by having the - * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, - * as documented in png.h - */ - png_debug(1, "in png_init_filter_functions_neon"); -#ifdef PNG_ARM_NEON_API_SUPPORTED - switch ((pp->options >> PNG_ARM_NEON) & 3) - { - case PNG_OPTION_UNSET: - /* Allow the run-time check to execute if it has been enabled - - * thus both API and CHECK can be turned on. If it isn't supported - * this case will fall through to the 'default' below, which just - * returns. - */ -#endif /* PNG_ARM_NEON_API_SUPPORTED */ -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED - { - static volatile sig_atomic_t no_neon = -1; /* not checked */ - - if (no_neon < 0) - no_neon = !png_have_neon(pp); - - if (no_neon) - return; - } -#ifdef PNG_ARM_NEON_API_SUPPORTED - break; -#endif -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifdef PNG_ARM_NEON_API_SUPPORTED - default: /* OFF or INVALID */ - return; - - case PNG_OPTION_ON: - /* Option turned on */ - break; - } -#endif - - /* IMPORTANT: any new external functions used here must be declared using - * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the - * 'prefix' option to configure works: - * - * ./configure --with-libpng-prefix=foobar_ - * - * Verify you have got this right by running the above command, doing a build - * and examining pngprefix.h; it must contain a #define for every external - * function you add. (Notice that this happens automatically for the - * initialization function.) - */ - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; - - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_neon; - } - - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_neon; - } -} -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* READ */ +/* arm_init.c - NEON optimised filter functions + * + * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2014,2016 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* This module requires POSIX 1003.1 functions. */ +#define _POSIX_SOURCE 1 + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#if PNG_ARM_NEON_OPT > 0 +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ +/* WARNING: it is strongly recommended that you do not build libpng with + * run-time checks for CPU features if at all possible. In the case of the ARM + * NEON instructions there is no processor-specific way of detecting the + * presence of the required support, therefore run-time detection is extremely + * OS specific. + * + * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing + * a fragment of C source code which defines the png_have_neon function. There + * are a number of implementations in contrib/arm-neon, but the only one that + * has partial support is contrib/arm-neon/linux.c - a generic Linux + * implementation which reads /proc/cpufino. + */ +#include /* for sig_atomic_t */ + +#ifndef PNG_ARM_NEON_FILE +# if defined(__aarch64__) || defined(_M_ARM64) + /* ARM Neon is expected to be unconditionally available on ARM64. */ +# error PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64 +# elif defined(__ARM_NEON__) || defined(__ARM_NEON) + /* ARM Neon is expected to be available on the target CPU architecture. */ +# error PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch +# elif defined(__linux__) +# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" +# else +# error No support for run-time ARM Neon checking; use compile-time options +# endif +#endif + +static int png_have_neon(png_structp png_ptr); +#ifdef PNG_ARM_NEON_FILE +# include PNG_ARM_NEON_FILE +#endif +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifndef PNG_ALIGNED_MEMORY_SUPPORTED +# error ALIGNED_MEMORY is required; please define PNG_ALIGNED_MEMORY_SUPPORTED +#endif + +void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ + /* The switch statement is compiled in for ARM_NEON_API, the call to + * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined + * the check is only performed if the API has not set the NEON option on + * or off explicitly. In this case the check controls what happens. + * + * If the CHECK is not compiled in and the option is UNSET the behavior prior + * to 1.6.7 was to use the NEON code - this was a bug caused by having the + * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, + * as documented in png.h + */ + png_debug(1, "in png_init_filter_functions_neon"); +#ifdef PNG_ARM_NEON_API_SUPPORTED + switch ((pp->options >> PNG_ARM_NEON) & 3) + { + case PNG_OPTION_UNSET: + /* Allow the run-time check to execute if it has been enabled - + * thus both API and CHECK can be turned on. If it isn't supported + * this case will fall through to the 'default' below, which just + * returns. + */ +#endif /* PNG_ARM_NEON_API_SUPPORTED */ +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED + { + static volatile sig_atomic_t no_neon = -1; /* not checked */ + + if (no_neon < 0) + no_neon = !png_have_neon(pp); + + if (no_neon) + return; + } +#ifdef PNG_ARM_NEON_API_SUPPORTED + break; +#endif +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifdef PNG_ARM_NEON_API_SUPPORTED + default: /* OFF or INVALID */ + return; + + case PNG_OPTION_ON: + /* Option turned on */ + break; + } +#endif + + /* IMPORTANT: any new external functions used here must be declared using + * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the + * 'prefix' option to configure works: + * + * ./configure --with-libpng-prefix=foobar_ + * + * Verify you have got this right by running the above command, doing a build + * and examining pngprefix.h; it must contain a #define for every external + * function you add. (Notice that this happens automatically for the + * initialization function.) + */ + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_neon; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_neon; + } +} +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/arm/filter_neon.S b/thirdparty/libpng/upstream/arm/filter_neon.S deleted file mode 100644 index e7ce7e31e..000000000 --- a/thirdparty/libpng/upstream/arm/filter_neon.S +++ /dev/null @@ -1,61 +0,0 @@ - -/* filter_neon.S - placeholder file - * - * Copyright (c) 2024 Cosmin Truta - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* IMPORTANT NOTE: - * - * Historically, the hand-coded assembler implementation of Neon optimizations - * in this module had not been in sync with the intrinsics-based implementation - * in filter_neon_intrinsics.c and palette_neon_intrinsics.c, at least since - * the introduction of riffled palette optimizations. Moreover, the assembler - * code used to work on 32-bit ARM only, and it caused problems, even if empty, - * on 64-bit ARM. - * - * All references to this module from our internal build scripts and projects - * have been removed. - * - * For the external projects that might still expect this module to be present, - * we leave this stub in place, for the remaining lifetime of libpng-1.6.x. - * Everything should continue to function normally, as long as there are no - * deliberate attempts to use the old hand-made assembler code. A build error - * will be raised otherwise. - */ - -/* This is required to get the symbol renames, which are #defines, and the - * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. - */ -#define PNG_VERSION_INFO_ONLY -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED -#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ -#if PNG_ARM_NEON_OPT > 0 - -#if defined(__clang__) -#define GNUC_VERSION 0 /* not gcc, although it might pretend to be */ -#elif defined(__GNUC__) -#define GNUC_MAJOR (__GNUC__ + 0) -#define GNUC_MINOR (__GNUC_MINOR__ + 0) -#define GNUC_PATCHLEVEL (__GNUC_PATCHLEVEL__ + 0) -#define GNUC_VERSION (GNUC_MAJOR * 10000 + GNUC_MINOR * 100 + GNUC_PATCHLEVEL) -#else -#define GNUC_VERSION 0 /* not gcc */ -#endif - -#if (GNUC_VERSION > 0) && (GNUC_VERSION < 40300) -#error "PNG_ARM_NEON is not supported with gcc versions earlier than 4.3.0" -#elif GNUC_VERSION == 40504 -#error "PNG_ARM_NEON is not supported with gcc version 4.5.4" -#else -#error "Please use 'arm/*_neon_intrinsics.c' for PNG_ARM_NEON support" -#endif - -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 */ -#endif /* READ */ diff --git a/thirdparty/libpng/upstream/arm/filter_neon_intrinsics.c b/thirdparty/libpng/upstream/arm/filter_neon_intrinsics.c index 740f8a907..6c3f1184a 100644 --- a/thirdparty/libpng/upstream/arm/filter_neon_intrinsics.c +++ b/thirdparty/libpng/upstream/arm/filter_neon_intrinsics.c @@ -1,402 +1,401 @@ - -/* filter_neon_intrinsics.c - NEON optimised filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2014,2016 Glenn Randers-Pehrson - * Written by James Yu , October 2013. - * Based on filter_neon.S, written by Mans Rullgard, 2011. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* This code requires -mfpu=neon on the command line: */ -#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ - -#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) -# include -#else -# include -#endif - -/* libpng row pointers are not necessarily aligned to any particular boundary, - * however this code will only work with appropriate alignment. arm/arm_init.c - * checks for this (and will not compile unless it is done). This code uses - * variants of png_aligncast to avoid compiler warnings. - */ -#define png_ptr(type,pointer) png_aligncast(type *,pointer) -#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) - -/* The following relies on a variable 'temp_pointer' being declared with type - * 'type'. This is written this way just to hide the GCC strict aliasing - * warning; note that the code is safe because there never is an alias between - * the input and output pointers. - * - * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly - * to vst4_lane_u32, because of an internal compiler error inside MSVC. - * To avoid this compiler bug, we use a temporary variable (vdest_val) to store - * the result of png_ldr. - */ -#define png_ldr(type,pointer)\ - (temp_pointer = png_ptr(type,pointer), *temp_pointer) - -#if PNG_ARM_NEON_OPT > 0 - -void -png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - png_debug(1, "in png_read_filter_row_up_neon"); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint8x16_t qrp, qpp; - - qrp = vld1q_u8(rp); - qpp = vld1q_u8(pp); - qrp = vaddq_u8(qrp, qpp); - vst1q_u8(rp, qrp); - } -} - -void -png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp = vld1q_u8(rp); - uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); - uint8x8x2_t vrp = *vrpt; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_sub3_neon"); - - for (; rp < rp_stop;) - { - uint8x8_t vtmp1, vtmp2; - uint32x2_t *temp_pointer; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t, &vtmp); - vrp = *vrpt; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } - - PNG_UNUSED(prev_row) -} - -void -png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_sub4_neon"); - - for (; rp < rp_stop; rp += 16) - { - uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); - uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); - uint8x8x4_t vrp = *vrpt; - uint32x2x4_t *temp_pointer; - uint32x2x4_t vdest_val; - - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); - - vdest_val = png_ldr(uint32x2x4_t, &vdest); - vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); - } - - PNG_UNUSED(prev_row) -} - -void -png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - png_debug(1, "in png_read_filter_row_avg3_neon"); - - for (; rp < rp_stop; pp += 12) - { - uint8x8_t vtmp1, vtmp2, vtmp3; - - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); - - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } -} - -void -png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_avg4_neon"); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - uint32x2x4_t vdest_val; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vdest_val = png_ldr(uint32x2x4_t, &vdest); - vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); - } -} - -static uint8x8_t -paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) -{ - uint8x8_t d, e; - uint16x8_t p1, pa, pb, pc; - - p1 = vaddl_u8(a, b); /* a + b */ - pc = vaddl_u8(c, c); /* c * 2 */ - pa = vabdl_u8(b, c); /* pa */ - pb = vabdl_u8(a, c); /* pb */ - pc = vabdq_u16(p1, pc); /* pc */ - - p1 = vcleq_u16(pa, pb); /* pa <= pb */ - pa = vcleq_u16(pa, pc); /* pa <= pc */ - pb = vcleq_u16(pb, pc); /* pb <= pc */ - - p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ - - d = vmovn_u16(pb); - e = vmovn_u16(p1); - - d = vbsl_u8(d, b, c); - e = vbsl_u8(e, a, d); - - return e; -} - -void -png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - png_debug(1, "in png_read_filter_row_paeth3_neon"); - - for (; rp < rp_stop; pp += 12) - { - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - uint8x8_t vtmp1, vtmp2, vtmp3; - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); - vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); - vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vlast = vtmp2; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } -} - -void -png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_paeth4_neon"); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - uint32x2x4_t vdest_val; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vlast = vpp.val[3]; - - vdest_val = png_ldr(uint32x2x4_t, &vdest); - vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); - } -} - -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ -#endif /* READ */ +/* filter_neon_intrinsics.c - NEON optimised filter functions + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2014,2016 Glenn Randers-Pehrson + * Written by James Yu , October 2013. + * Based on filter_neon.S, written by Mans Rullgard, 2011. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* This code requires -mfpu=neon on the command line: */ +#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ + +#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) +# include +#else +# include +#endif + +/* libpng row pointers are not necessarily aligned to any particular boundary, + * however this code will only work with appropriate alignment. arm/arm_init.c + * checks for this (and will not compile unless it is done). This code uses + * variants of png_aligncast to avoid compiler warnings. + */ +#define png_ptr(type,pointer) png_aligncast(type *,pointer) +#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) + +/* The following relies on a variable 'temp_pointer' being declared with type + * 'type'. This is written this way just to hide the GCC strict aliasing + * warning; note that the code is safe because there never is an alias between + * the input and output pointers. + * + * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly + * to vst4_lane_u32, because of an internal compiler error inside MSVC. + * To avoid this compiler bug, we use a temporary variable (vdest_val) to store + * the result of png_ldr. + */ +#define png_ldr(type,pointer)\ + (temp_pointer = png_ptr(type,pointer), *temp_pointer) + +#if PNG_ARM_NEON_OPT > 0 + +void +png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + png_debug(1, "in png_read_filter_row_up_neon"); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint8x16_t qrp, qpp; + + qrp = vld1q_u8(rp); + qpp = vld1q_u8(pp); + qrp = vaddq_u8(qrp, qpp); + vst1q_u8(rp, qrp); + } +} + +void +png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp = vld1q_u8(rp); + uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); + uint8x8x2_t vrp = *vrpt; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_sub3_neon"); + + for (; rp < rp_stop;) + { + uint8x8_t vtmp1, vtmp2; + uint32x2_t *temp_pointer; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t, &vtmp); + vrp = *vrpt; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_sub4_neon"); + + for (; rp < rp_stop; rp += 16) + { + uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); + uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); + uint8x8x4_t vrp = *vrpt; + uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; + + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + png_debug(1, "in png_read_filter_row_avg3_neon"); + + for (; rp < rp_stop; pp += 12) + { + uint8x8_t vtmp1, vtmp2, vtmp3; + + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); + + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_avg4_neon"); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); + } +} + +static uint8x8_t +paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) +{ + uint8x8_t d, e; + uint16x8_t p1, pa, pb, pc; + + p1 = vaddl_u8(a, b); /* a + b */ + pc = vaddl_u8(c, c); /* c * 2 */ + pa = vabdl_u8(b, c); /* pa */ + pb = vabdl_u8(a, c); /* pb */ + pc = vabdq_u16(p1, pc); /* pc */ + + p1 = vcleq_u16(pa, pb); /* pa <= pb */ + pa = vcleq_u16(pa, pc); /* pa <= pc */ + pb = vcleq_u16(pb, pc); /* pb <= pc */ + + p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ + + d = vmovn_u16(pb); + e = vmovn_u16(p1); + + d = vbsl_u8(d, b, c); + e = vbsl_u8(e, a, d); + + return e; +} + +void +png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + png_debug(1, "in png_read_filter_row_paeth3_neon"); + + for (; rp < rp_stop; pp += 12) + { + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + uint8x8_t vtmp1, vtmp2, vtmp3; + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); + vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); + vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vlast = vtmp2; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + png_debug(1, "in png_read_filter_row_paeth4_neon"); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vlast = vpp.val[3]; + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); + } +} + +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/arm/palette_neon_intrinsics.c b/thirdparty/libpng/upstream/arm/palette_neon_intrinsics.c index db0ae69f6..0967ea1ae 100644 --- a/thirdparty/libpng/upstream/arm/palette_neon_intrinsics.c +++ b/thirdparty/libpng/upstream/arm/palette_neon_intrinsics.c @@ -1,151 +1,147 @@ - -/* palette_neon_intrinsics.c - NEON optimised palette expansion functions - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 2017-2018 Arm Holdings. All rights reserved. - * Written by Richard Townsend , February 2017. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#if PNG_ARM_NEON_IMPLEMENTATION == 1 - -#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) -# include -#else -# include -#endif - -/* Build an RGBA8 palette from the separate RGB and alpha palettes. */ -void -png_riffle_palette_neon(png_structrp png_ptr) -{ - png_const_colorp palette = png_ptr->palette; - png_bytep riffled_palette = png_ptr->riffled_palette; - png_const_bytep trans_alpha = png_ptr->trans_alpha; - int num_trans = png_ptr->num_trans; - int i; - - /* Initially black, opaque. */ - uint8x16x4_t w = {{ - vdupq_n_u8(0x00), - vdupq_n_u8(0x00), - vdupq_n_u8(0x00), - vdupq_n_u8(0xff), - }}; - - png_debug(1, "in png_riffle_palette_neon"); - - /* First, riffle the RGB colours into an RGBA8 palette. - * The alpha component is set to opaque for now. - */ - for (i = 0; i < 256; i += 16) - { - uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); - w.val[0] = v.val[0]; - w.val[1] = v.val[1]; - w.val[2] = v.val[2]; - vst4q_u8(riffled_palette + (i << 2), w); - } - - /* Fix up the missing transparency values. */ - for (i = 0; i < num_trans; i++) - riffled_palette[(i << 2) + 3] = trans_alpha[i]; -} - -/* Expands a palettized row into RGBA8. */ -int -png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info, - png_const_bytep row, png_bytepp ssp, png_bytepp ddp) -{ - png_uint_32 row_width = row_info->width; - const png_uint_32 *riffled_palette = - (const png_uint_32 *)png_ptr->riffled_palette; - const png_uint_32 pixels_per_chunk = 4; - png_uint_32 i; - - png_debug(1, "in png_do_expand_palette_rgba8_neon"); - - PNG_UNUSED(row) - if (row_width < pixels_per_chunk) - return 0; - - /* This function originally gets the last byte of the output row. - * The NEON part writes forward from a given position, so we have - * to seek this back by 4 pixels x 4 bytes. - */ - *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); - - for (i = 0; i < row_width; i += pixels_per_chunk) - { - uint32x4_t cur; - png_bytep sp = *ssp - i, dp = *ddp - (i << 2); - cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); - cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); - cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); - cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); - vst1q_u32((void *)dp, cur); - } - if (i != row_width) - { - /* Remove the amount that wasn't processed. */ - i -= pixels_per_chunk; - } - - /* Decrement output pointers. */ - *ssp = *ssp - i; - *ddp = *ddp - (i << 2); - return i; -} - -/* Expands a palettized row into RGB8. */ -int -png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info, - png_const_bytep row, png_bytepp ssp, png_bytepp ddp) -{ - png_uint_32 row_width = row_info->width; - png_const_bytep palette = (png_const_bytep)png_ptr->palette; - const png_uint_32 pixels_per_chunk = 8; - png_uint_32 i; - - png_debug(1, "in png_do_expand_palette_rgb8_neon"); - - PNG_UNUSED(row) - if (row_width <= pixels_per_chunk) - return 0; - - /* Seeking this back by 8 pixels x 3 bytes. */ - *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); - - for (i = 0; i < row_width; i += pixels_per_chunk) - { - uint8x8x3_t cur; - png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); - cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); - vst3_u8((void *)dp, cur); - } - - if (i != row_width) - { - /* Remove the amount that wasn't processed. */ - i -= pixels_per_chunk; - } - - /* Decrement output pointers. */ - *ssp = *ssp - i; - *ddp = *ddp - ((i << 1) + i); - return i; -} - -#endif /* PNG_ARM_NEON_IMPLEMENTATION */ +/* palette_neon_intrinsics.c - NEON optimised palette expansion functions + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 2017-2018 Arm Holdings. All rights reserved. + * Written by Richard Townsend , February 2017. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#if PNG_ARM_NEON_IMPLEMENTATION == 1 + +#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) +# include +#else +# include +#endif + +/* Build an RGBA8 palette from the separate RGB and alpha palettes. */ +void +png_riffle_palette_neon(png_structrp png_ptr) +{ + png_const_colorp palette = png_ptr->palette; + png_bytep riffled_palette = png_ptr->riffled_palette; + png_const_bytep trans_alpha = png_ptr->trans_alpha; + int num_trans = png_ptr->num_trans; + int i; + + /* Initially black, opaque. */ + uint8x16x4_t w = {{ + vdupq_n_u8(0x00), + vdupq_n_u8(0x00), + vdupq_n_u8(0x00), + vdupq_n_u8(0xff), + }}; + + png_debug(1, "in png_riffle_palette_neon"); + + /* First, riffle the RGB colours into an RGBA8 palette. + * The alpha component is set to opaque for now. + */ + for (i = 0; i < 256; i += 16) + { + uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); + w.val[0] = v.val[0]; + w.val[1] = v.val[1]; + w.val[2] = v.val[2]; + vst4q_u8(riffled_palette + i * 4, w); + } + + /* Fix up the missing transparency values. */ + for (i = 0; i < num_trans; i++) + riffled_palette[i * 4 + 3] = trans_alpha[i]; +} + +/* Expands a palettized row into RGBA8. */ +int +png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info, + png_const_bytep row, png_bytepp ssp, png_bytepp ddp) +{ + png_uint_32 row_width = row_info->width; + const png_uint_32 *riffled_palette = + png_aligncastconst(png_const_uint_32p, png_ptr->riffled_palette); + const png_uint_32 pixels_per_chunk = 4; + png_uint_32 i; + + png_debug(1, "in png_do_expand_palette_rgba8_neon"); + + PNG_UNUSED(row) + if (row_width < pixels_per_chunk) + return 0; + + /* This function originally gets the last byte of the output row. + * The NEON part writes forward from a given position, so we have + * to seek this back by 4 pixels x 4 bytes. + */ + *ddp = *ddp - (pixels_per_chunk * 4 - 1); + + for (i = 0; i + pixels_per_chunk <= row_width; i += pixels_per_chunk) + { + uint32x4_t cur; + png_bytep sp = *ssp - i, dp = *ddp - i * 4; + cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); + cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); + cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); + cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); + vst1q_u32((void *)dp, cur); + } + + /* Undo the pre-adjustment of *ddp before the pointer handoff, + * so the scalar fallback in pngrtran.c receives a dp that points + * to the correct position. + */ + *ddp = *ddp + (pixels_per_chunk * 4 - 1); + *ssp = *ssp - i; + *ddp = *ddp - i * 4; + return i; +} + +/* Expands a palettized row into RGB8. */ +int +png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info, + png_const_bytep row, png_bytepp ssp, png_bytepp ddp) +{ + png_uint_32 row_width = row_info->width; + png_const_bytep palette = (png_const_bytep)png_ptr->palette; + const png_uint_32 pixels_per_chunk = 8; + png_uint_32 i; + + png_debug(1, "in png_do_expand_palette_rgb8_neon"); + + PNG_UNUSED(row) + if (row_width <= pixels_per_chunk) + return 0; + + /* Seeking this back by 8 pixels x 3 bytes. */ + *ddp = *ddp - (pixels_per_chunk * 3 - 1); + + for (i = 0; i + pixels_per_chunk <= row_width; i += pixels_per_chunk) + { + uint8x8x3_t cur; + png_bytep sp = *ssp - i, dp = *ddp - i * 3; + cur = vld3_dup_u8(palette + *(sp - 7) * 3); + cur = vld3_lane_u8(palette + *(sp - 6) * 3, cur, 1); + cur = vld3_lane_u8(palette + *(sp - 5) * 3, cur, 2); + cur = vld3_lane_u8(palette + *(sp - 4) * 3, cur, 3); + cur = vld3_lane_u8(palette + *(sp - 3) * 3, cur, 4); + cur = vld3_lane_u8(palette + *(sp - 2) * 3, cur, 5); + cur = vld3_lane_u8(palette + *(sp - 1) * 3, cur, 6); + cur = vld3_lane_u8(palette + *(sp - 0) * 3, cur, 7); + vst3_u8((void *)dp, cur); + } + + /* Undo the pre-adjustment of *ddp before the pointer handoff, + * so the scalar fallback in pngrtran.c receives a dp that points + * to the correct position. + */ + *ddp = *ddp + (pixels_per_chunk * 3 - 1); + *ssp = *ssp - i; + *ddp = *ddp - i * 3; + return i; +} + +#endif /* PNG_ARM_NEON_IMPLEMENTATION */ diff --git a/thirdparty/libpng/upstream/contrib/.editorconfig b/thirdparty/libpng/upstream/contrib/.editorconfig deleted file mode 100644 index 20f51a160..000000000 --- a/thirdparty/libpng/upstream/contrib/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -# https://editorconfig.org - -root = false - -[*.[ch]] -max_doc_length = unset -max_line_length = unset diff --git a/thirdparty/libpng/upstream/contrib/arm-neon/README b/thirdparty/libpng/upstream/contrib/arm-neon/README deleted file mode 100644 index 1a1a6ee1c..000000000 --- a/thirdparty/libpng/upstream/contrib/arm-neon/README +++ /dev/null @@ -1,83 +0,0 @@ -OPERATING SYSTEM SPECIFIC ARM NEON DETECTION --------------------------------------------- - -Detection of the ability to execute ARM NEON on an ARM processor requires -operating system support. (The information is not available in user mode.) - -HOW TO USE THIS ---------------- - -This directory contains C code fragments that can be included in arm/arm_init.c -by setting the macro PNG_ARM_NEON_FILE to the file name in "" or <> at build -time. This setting is not recorded in pnglibconf.h and can be changed simply by -rebuilding arm/arm_init.o with the required macro definition. - -For any of this code to be used the ARM NEON code must be enabled and run time -checks must be supported. I.e.: - -#if PNG_ARM_NEON_OPT > 0 -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED - -This is done in a 'configure' build by passing configure the argument: - - --enable-arm-neon=check - -Apart from the basic Linux implementation in contrib/arm-neon/linux.c this code -is unsupported. That means that it is not even compiled on a regular basis and -may be broken in any given minor release. - -FILE FORMAT ------------ - -Each file documents its testing status as of the last time it was tested (which -may have been a long time ago): - -STATUS: one of: - SUPPORTED: This indicates that the file is included in the regularly - performed test builds and bugs are fixed when discovered. - COMPILED: This indicates that the code did compile at least once. See the - more detailed description for the extent to which the result was - successful. - TESTED: This means the code was fully compiled into the libpng test programs - and these were run at least once. - -BUG REPORTS: an email address to which to send reports of problems - -The file is a fragment of C code. It should not define any 'extern' symbols; -everything should be static. It must define the function: - -static int png_have_neon(png_structp png_ptr); - -That function must return 1 if ARM NEON instructions are supported, 0 if not. -It must not execute png_error unless it detects a bug. A png_error will prevent -the reading of the PNG and in the future, writing too. - -BUG REPORTS ------------ - -If you mail a bug report for any file that is not SUPPORTED there may only be -limited response. Consider fixing it and sending a patch to fix the problem - -this is more likely to result in action. - -CONTRIBUTIONS -------------- - -You may send contributions of new implementations to -png-mng-implement@sourceforge.net. Please write code in strict C90 C where -possible. Obviously OS dependencies are to be expected. If you submit code you -must have the authors permission and it must have a license that is acceptable -to the current maintainer; in particular that license must permit modification -and redistribution. - -Please try to make the contribution a single file and give the file a clear and -unambiguous name that identifies the target OS. If multiple files really are -required put them all in a sub-directory. - -You must also be prepared to handle bug reports from users of the code, either -by joining the png-mng-implement mailing list or by providing an email for the -"BUG REPORTS" entry or both. Please make sure that the header of the file -contains the STATUS and BUG REPORTS fields as above. - -Please list the OS requirements as precisely as possible. Ideally you should -also list the environment in which the code has been tested and certainly list -any environments where you suspect it might not work. diff --git a/thirdparty/libpng/upstream/contrib/arm-neon/android-ndk.c b/thirdparty/libpng/upstream/contrib/arm-neon/android-ndk.c deleted file mode 100644 index 8bdb3caab..000000000 --- a/thirdparty/libpng/upstream/contrib/arm-neon/android-ndk.c +++ /dev/null @@ -1,39 +0,0 @@ -/* contrib/arm-neon/android-ndk.c - * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by John Bowler, 2014. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * SEE contrib/arm-neon/README before reporting bugs - * - * STATUS: COMPILED, UNTESTED - * BUG REPORTS: png-mng-implement@sourceforge.net - * - * png_have_neon implemented for the Android NDK, see: - * - * Documentation: - * http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html - * https://code.google.com/p/android/issues/detail?id=49065 - * - * NOTE: this requires that libpng is built against the Android NDK and linked - * with an implementation of the Android ARM 'cpu-features' library. The code - * has been compiled only, not linked: no version of the library has been found, - * only the header files exist in the NDK. - */ - -#include - -static int -png_have_neon(png_structp png_ptr) -{ - /* This is a whole lot easier than the linux code, however it is probably - * implemented as below, therefore it is better to cache the result (these - * function calls may be slow!) - */ - PNG_UNUSED(png_ptr) - return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0; -} diff --git a/thirdparty/libpng/upstream/contrib/arm-neon/linux-auxv.c b/thirdparty/libpng/upstream/contrib/arm-neon/linux-auxv.c deleted file mode 100644 index 9ddb26ce8..000000000 --- a/thirdparty/libpng/upstream/contrib/arm-neon/linux-auxv.c +++ /dev/null @@ -1,120 +0,0 @@ -/* contrib/arm-neon/linux-auxv.c - * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * SEE contrib/arm-neon/README before reporting bugs - * - * STATUS: COMPILED, TESTED - * BUG REPORTS: png-mng-implement@sourceforge.net - * - * png_have_neon implemented for Linux versions which allow access to - * /proc/self/auxv. This is probably faster, cleaner and safer than the code to - * read /proc/cpuinfo in contrib/arm-neon/linux, however it is yet another piece - * of potentially untested code and has more complex dependencies than the code - * to read cpuinfo. - * - * This generic __linux__ implementation requires reading /proc/self/auxv and - * looking at each element for one that records NEON capabilities. - */ - -#include /* for POSIX 1003.1 */ -#include /* for EINTR */ - -#include -#include -#include -#include -#include - -/* A read call may be interrupted, in which case it returns -1 and sets errno to - * EINTR if nothing was done, otherwise (if something was done) a partial read - * may result. - */ -static size_t -safe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes) -{ - size_t ntotal = 0; - char *buffer = png_voidcast(char*, buffer_in); - - while (nbytes > 0) - { - unsigned int nread; - int iread; - - /* Passing nread > INT_MAX to read is implementation defined in POSIX - * 1003.1, therefore despite the unsigned argument portable code must - * limit the value to INT_MAX! - */ - if (nbytes > INT_MAX) - nread = INT_MAX; - - else - nread = (unsigned int)/*SAFE*/nbytes; - - iread = read(fd, buffer, nread); - - if (iread == -1) - { - /* This is the devil in the details, a read can terminate early with 0 - * bytes read because of EINTR, yet it still returns -1 otherwise end - * of file cannot be distinguished. - */ - if (errno != EINTR) - { - png_warning(png_ptr, "/proc read failed"); - return 0; /* I.e., a permanent failure */ - } - } - - else if (iread < 0) - { - /* Not a valid 'read' result: */ - png_warning(png_ptr, "OS /proc read bug"); - return 0; - } - - else if (iread > 0) - { - /* Continue reading until a permanent failure, or EOF */ - buffer += iread; - nbytes -= (unsigned int)/*SAFE*/iread; - ntotal += (unsigned int)/*SAFE*/iread; - } - - else - return ntotal; - } - - return ntotal; /* nbytes == 0 */ -} - -static int -png_have_neon(png_structp png_ptr) -{ - int fd = open("/proc/self/auxv", O_RDONLY); - Elf32_auxv_t aux; - - /* Failsafe: failure to open means no NEON */ - if (fd == -1) - { - png_warning(png_ptr, "/proc/self/auxv open failed"); - return 0; - } - - while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux) - { - if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0) - { - close(fd); - return 1; - } - } - - close(fd); - return 0; -} diff --git a/thirdparty/libpng/upstream/contrib/arm-neon/linux.c b/thirdparty/libpng/upstream/contrib/arm-neon/linux.c deleted file mode 100644 index e3dbe10be..000000000 --- a/thirdparty/libpng/upstream/contrib/arm-neon/linux.c +++ /dev/null @@ -1,161 +0,0 @@ -/* contrib/arm-neon/linux.c - * - * Copyright (c) 2014, 2017 Glenn Randers-Pehrson - * Written by John Bowler, 2014, 2017. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * SEE contrib/arm-neon/README before reporting bugs - * - * STATUS: SUPPORTED - * BUG REPORTS: png-mng-implement@sourceforge.net - * - * png_have_neon implemented for Linux by reading the widely available - * pseudo-file /proc/cpuinfo. - * - * This code is strict ANSI-C and is probably moderately portable; it does - * however use and it assumes that /proc/cpuinfo is never localized. - */ - -#include - -static int -png_have_neon(png_structp png_ptr) -{ - FILE *f = fopen("/proc/cpuinfo", "rb"); - - if (f != NULL) - { - /* This is a simple state machine which reads the input byte-by-byte until - * it gets a match on the 'neon' feature or reaches the end of the stream. - */ - static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 }; - static const char ch_neon[] = { 78, 69, 79, 78 }; - - enum - { - StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine - } state; - int counter; - - for (state=StartLine, counter=0;;) - { - int ch = fgetc(f); - - if (ch == EOF) - { - /* EOF means error or end-of-file, return false; neon at EOF is - * assumed to be a mistake. - */ - fclose(f); - return 0; - } - - switch (state) - { - case StartLine: - /* Match spaces at the start of line */ - if (ch <= 32) /* skip control characters and space */ - break; - - counter=0; - state = Feature; - /* FALLTHROUGH */ - - case Feature: - /* Match 'FEATURE', ASCII case insensitive. */ - if ((ch & ~0x20) == ch_feature[counter]) - { - if (++counter == (sizeof ch_feature)) - state = Colon; - break; - } - - /* did not match 'feature' */ - state = SkipLine; - /* FALLTHROUGH */ - - case SkipLine: - skipLine: - /* Skip everything until we see linefeed or carriage return */ - if (ch != 10 && ch != 13) - break; - - state = StartLine; - break; - - case Colon: - /* Match any number of space or tab followed by ':' */ - if (ch == 32 || ch == 9) - break; - - if (ch == 58) /* i.e. ':' */ - { - state = StartTag; - break; - } - - /* Either a bad line format or a 'feature' prefix followed by - * other characters. - */ - state = SkipLine; - goto skipLine; - - case StartTag: - /* Skip space characters before a tag */ - if (ch == 32 || ch == 9) - break; - - state = Neon; - counter = 0; - /* FALLTHROUGH */ - - case Neon: - /* Look for 'neon' tag */ - if ((ch & ~0x20) == ch_neon[counter]) - { - if (++counter == (sizeof ch_neon)) - state = HaveNeon; - break; - } - - state = SkipTag; - /* FALLTHROUGH */ - - case SkipTag: - /* Skip non-space characters */ - if (ch == 10 || ch == 13) - state = StartLine; - - else if (ch == 32 || ch == 9) - state = StartTag; - break; - - case HaveNeon: - /* Have seen a 'neon' prefix, but there must be a space or new - * line character to terminate it. - */ - if (ch == 10 || ch == 13 || ch == 32 || ch == 9) - { - fclose(f); - return 1; - } - - state = SkipTag; - break; - - default: - png_error(png_ptr, "png_have_neon: internal error (bug)"); - } - } - } - -#ifdef PNG_WARNINGS_SUPPORTED - else - png_warning(png_ptr, "/proc/cpuinfo open failed"); -#endif - - return 0; -} diff --git a/thirdparty/libpng/upstream/example.c b/thirdparty/libpng/upstream/example.c new file mode 100644 index 000000000..6af8f6f90 --- /dev/null +++ b/thirdparty/libpng/upstream/example.c @@ -0,0 +1,1040 @@ +#if 0 /* in case someone actually tries to compile this */ + +/* example.c - an example of using libpng + * + * Maintained 2018-2025 Cosmin Truta + * Maintained 1998-2016 Glenn Randers-Pehrson + * Maintained 1996-1997 Andreas Dilger + * Written 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * To the extent possible under law, the authors have waived + * all copyright and related or neighboring rights to this file. + * This work is published from: United States, Canada. + */ + +/* This is an example of how to use libpng to read and write PNG files. + * The file libpng-manual.txt is much more verbose then this. If you have + * not read it, do so first. This was designed to be a starting point of an + * implementation. This is not officially part of libpng, is hereby placed + * in the public domain, and therefore does not require a copyright notice. + * + * This file does not currently compile, because it is missing certain + * parts, like allocating memory to hold an image. You will have to + * supply these parts to get it to compile. For an example of a minimal + * working PNG reader/writer, see pngtest.c, included in this distribution; + * see also the programs in the contrib directory. + */ + +/* The simple, but restricted approach to reading a PNG file or data stream + * requires just two function calls, as in the following complete program. + * Writing a file needs just one function call, so long as the data has an + * appropriate layout. + * + * The following code reads PNG image data from a file and writes it, in a + * potentially new format, to a new file. While this code will compile, there + * is minimal (insufficient) error checking. For a more realistic version, + * see contrib/examples/pngtopng.c + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, const char **argv) +{ + if (argc == 3) + { + png_image image; /* The control structure used by libpng */ + + /* Initialize the 'png_image' structure. */ + memset(&image, 0, (sizeof image)); + image.version = PNG_IMAGE_VERSION; + + /* The first argument is the file to read: */ + if (png_image_begin_read_from_file(&image, argv[1]) != 0) + { + png_bytep buffer; + + /* Set the format in which to read the PNG file; this code chooses a + * simple sRGB format with a non-associated alpha channel, adequate to + * store most images. + */ + image.format = PNG_FORMAT_RGBA; + + /* Now allocate enough memory to hold the image in this format; the + * PNG_IMAGE_SIZE macro uses the information about the image (width, + * height and format) stored in 'image'. + */ + buffer = malloc(PNG_IMAGE_SIZE(image)); + + /* If enough memory was available, read the image in the desired + * format, then write the result out to the new file. 'background' is + * not necessary when reading the image, because the alpha channel is + * preserved; if it were to be removed, for example if we requested + * PNG_FORMAT_RGB, then either a solid background color would have to + * be supplied, or the output buffer would have to be initialized to + * the actual background of the image. + * + * The fourth argument to png_image_finish_read is the 'row_stride' - + * this is the number of components allocated for the image in each + * row. It has to be at least as big as the value returned by + * PNG_IMAGE_ROW_STRIDE, but if you just allocate space for the + * default, minimum size, using PNG_IMAGE_SIZE as above, you can pass + * zero. + * + * The final argument is a pointer to a buffer for the colormap; + * colormaps have exactly the same format as a row of image pixels + * (so you choose what format to make the colormap by setting + * image.format). A colormap is only returned if + * PNG_FORMAT_FLAG_COLORMAP is also set in image.format, so in this + * case NULL is passed as the final argument. If you do want to force + * all images into an index/color-mapped format, then you can use: + * + * PNG_IMAGE_COLORMAP_SIZE(image) + * + * to find the maximum size of the colormap in bytes. + */ + if (buffer != NULL && + png_image_finish_read(&image, NULL/*background*/, buffer, + 0/*row_stride*/, NULL/*colormap*/) != 0) + { + /* Now write the image out to the second argument. In the write + * call 'convert_to_8bit' allows 16-bit data to be squashed down to + * 8 bits; this isn't necessary here because the original read was + * to the 8-bit format. + */ + if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/, + buffer, 0/*row_stride*/, NULL/*colormap*/) != 0) + { + /* The image has been written successfully. */ + exit(0); + } + } + else + { + /* Calling png_image_free is optional unless the simplified API was + * not run to completion. In this case, if there wasn't enough + * memory for 'buffer', we didn't complete the read, so we must + * free the image: + */ + if (buffer == NULL) + png_image_free(&image); + else + free(buffer); + } + } + + /* Something went wrong reading or writing the image. libpng stores a + * textual message in the 'png_image' structure: + */ + fprintf(stderr, "pngtopng: error: %s\n", image.message); + exit(1); + } + + fprintf(stderr, "pngtopng: usage: pngtopng input-file output-file\n"); + exit(2); +} + +/* That's it ;-) Of course you probably want to do more with PNG files than + * just converting them all to 32-bit RGBA PNG files; you can do that between + * the call to png_image_finish_read and png_image_write_to_file. You can also + * ask for the image data to be presented in a number of different formats. + * You do this by simply changing the 'format' parameter set before allocating + * the buffer. + * + * The format parameter consists of five flags that define various aspects of + * the image. You can simply add these together to get the format, or you can + * use one of the predefined macros from png.h (as above): + * + * PNG_FORMAT_FLAG_COLOR: if set, the image will have three color components + * per pixel (red, green and blue); if not set, the image will just have one + * luminance (grayscale) component. + * + * PNG_FORMAT_FLAG_ALPHA: if set, each pixel in the image will have an + * additional alpha value; a linear value that describes the degree the + * image pixel covers (overwrites) the contents of the existing pixel on the + * display. + * + * PNG_FORMAT_FLAG_LINEAR: if set, the components of each pixel will be + * returned as a series of 16-bit linear values; if not set, the components + * will be returned as a series of 8-bit values encoded according to the + * sRGB standard. The 8-bit format is the normal format for images intended + * for direct display, because almost all display devices do the inverse of + * the sRGB transformation to the data they receive. The 16-bit format is + * more common for scientific data and image data that must be further + * processed; because it is linear, simple math can be done on the component + * values. Regardless of the setting of this flag, the alpha channel is + * always linear, although it will be 8 bits or 16 bits wide as specified by + * the flag. + * + * PNG_FORMAT_FLAG_BGR: if set, the components of a color pixel will be + * returned in the order blue, then green, then red. If not set, the pixel + * components are in the order red, then green, then blue. + * + * PNG_FORMAT_FLAG_AFIRST: if set, the alpha channel (if present) precedes the + * color or grayscale components. If not set, the alpha channel follows the + * components. + * + * You do not have to read directly from a file. You can read from memory or, + * on systems that support , from a FILE object. This is controlled + * by the particular png_image_begin_read_from_ function you call at the start. + * Likewise, on write, you can write to a FILE object if your system supports + * . The macro PNG_STDIO_SUPPORTED indicates if stdio is available + * and accessible from your libpng build. + * + * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data, you may need to write it + * in the 8-bit format for display. You do this by setting the convert_to_8bit + * flag to 'true'. + * + * Don't repeatedly convert between the 8-bit and 16-bit forms. There is + * significant data loss when 16-bit data is converted to the 8-bit encoding, + * and the current libpng implementation of conversion to 16-bit is also + * significantly lossy. The latter will be fixed in the future, but the former + * is unavoidable - the 8-bit format just doesn't have enough resolution. + */ + +/* If your program needs more information from the PNG data it reads, or if you + * need to do more complex transformations, or minimize transformations, on the + * data you read, then you must use one of the several lower level libpng + * interfaces. + * + * All these interfaces require that you do your own error handling - your + * program must be able to arrange for control to return to your own code, any + * time libpng encounters a problem. There are several ways to do this, but + * the standard way is to use the interface to establish a return + * point within your own code. You must do this if you do not use the + * simplified interface (above). + * + * The first step is to include the header files you need, including the libpng + * header file. Include any standard headers and feature test macros your + * program requires before including png.h: + */ +#include + + /* The png_jmpbuf() macro, used in error handling, became available in + * libpng version 1.0.6. If you want to be able to run your code with older + * versions of libpng, you must define the macro yourself (but only if it + * is not already defined by libpng!) + */ + +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) ((png_ptr)->png_jmpbuf) +#endif + +/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp() + * returns zero if the image is a PNG, and nonzero otherwise. + * + * The function check_if_png() shown here, but not used, returns nonzero (true) + * if the file can be opened and is a PNG, and 0 (false) otherwise. + * + * If this call is successful, and you are going to keep the file open, + * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once + * you have created the png_ptr, so that libpng knows your application + * has read that many bytes from the start of the file. Make sure you + * don't call png_set_sig_bytes() with more than 8 bytes read or give it + * an incorrect number of bytes read, or you will either have read too + * many bytes (your fault), or you are telling libpng to read the wrong + * number of magic bytes (also your fault). + * + * Many applications already read the first 2 or 4 bytes from the start + * of the image to determine the file type, so it would be easiest just + * to pass the bytes to png_sig_cmp(), or even skip that if you know + * you have a PNG file, and call png_set_sig_bytes(). + */ +#define PNG_BYTES_TO_CHECK 4 +int check_if_png(char *file_name, FILE **fp) +{ + char buf[PNG_BYTES_TO_CHECK]; + + /* Open the prospective PNG file. */ + if ((*fp = fopen(file_name, "rb")) == NULL) + return 0; + + /* Read in some of the signature bytes. */ + if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK) + return 0; + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. + * Return true if they match. + */ + return png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK) == 0; +} + +/* Read a PNG file. You may want to return an error code if the read + * fails (depending upon the failure). There are two "prototypes" given + * here - one where we are given the filename, and we need to open the + * file, and the other where we are given an open file (possibly with + * some or all of the magic bytes read - see comments above). + */ +#ifdef open_file /* prototype 1 */ +void read_png(char *file_name) /* We need to open the file */ +{ + png_structp png_ptr; + png_infop info_ptr; + int sig_read = 0; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + FILE *fp; + + if ((fp = fopen(file_name, "rb")) == NULL) + return ERROR; + +#else no_open_file /* prototype 2 */ +void read_png(FILE *fp, int sig_read) /* File is already open */ +{ + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; +#endif no_open_file /* Only use one prototype! */ + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also supply the + * the compiler header file version, so that we know if the application + * was compiled with a compatible version of the library. REQUIRED. + */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + + if (png_ptr == NULL) + { + fclose(fp); + return ERROR; + } + + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return ERROR; + } + + /* Set error handling if you are using the setjmp/longjmp method (this is + * the normal method of doing things with libpng). REQUIRED unless you + * set up your own error handlers in the png_create_read_struct() earlier. + */ + if (setjmp(png_jmpbuf(png_ptr))) + { + /* Free all of the memory associated with the png_ptr and info_ptr. */ + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fclose(fp); + /* If we get here, we had a problem reading the file. */ + return ERROR; + } + + /* One of the following I/O initialization methods is REQUIRED. */ +#ifdef streams /* PNG file I/O method 1 */ + /* Set up the input control if you are using standard C streams. */ + png_init_io(png_ptr, fp); + +#else no_streams /* PNG file I/O method 2 */ + /* If you are using replacement read functions, instead of calling + * png_init_io(), you would call: + */ + png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn); + /* where user_io_ptr is a structure you want available to the callbacks. */ +#endif no_streams /* Use only one I/O method! */ + + /* If we have already read some of the signature */ + png_set_sig_bytes(png_ptr, sig_read); + +#ifdef hilevel + /* If you have enough memory to read in the entire image at once, + * and you need to specify only transforms that can be controlled + * with one of the PNG_TRANSFORM_* bits (this presently excludes + * quantizing, filling, setting background, and doing gamma + * adjustment), then you can read the entire image (including + * pixels) into the info structure with this call: + */ + png_read_png(png_ptr, info_ptr, png_transforms, NULL); + +#else + /* OK, you're doing it the hard way, with the lower-level functions. */ + + /* The call to png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). REQUIRED. + */ + png_read_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + &interlace_type, NULL, NULL); + + /* Set up the data transformations you want. Note that these are all + * optional. Only call them if you want/need them. Many of the + * transformations only work on specific types of images, and many + * are mutually exclusive. + */ + + /* Tell libpng to strip 16 bits/color files down to 8 bits/color. + * Use accurate scaling if it's available, otherwise just chop off the + * low byte. + */ +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_set_scale_16(png_ptr); +#else + png_set_strip_16(png_ptr); +#endif + + /* Strip alpha bytes from the input data without combining with the + * background (not recommended). + */ + png_set_strip_alpha(png_ptr); + + /* Extract multiple pixels with bit depths of 1, 2 or 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + png_set_packing(png_ptr); + + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). + */ + png_set_packswap(png_ptr); + + /* Expand paletted colors into true RGB triplets. */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + /* Expand grayscale images to the full 8 bits from 1, 2 or 4 bits/pixel. */ + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand_gray_1_2_4_to_8(png_ptr); + + /* Expand paletted or RGB images with transparency to full alpha channels + * so the data will be available as RGBA quartets. + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0) + png_set_tRNS_to_alpha(png_ptr); + + /* Set the background color to draw transparent and alpha images over. + * It is possible to set the red, green and blue components directly + * for paletted images, instead of supplying a palette index. Note that, + * even if the PNG file supplies a background, you are not required to + * use it - you should use the (solid) application background if it has one. + */ + png_color_16 my_background, *image_background; + + if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + + /* Some suggestions as to how to get a screen gamma value. + * + * Note that screen gamma is the display_exponent, which includes + * the CRT_exponent and any correction for viewing conditions. + */ + if (/* We have a user-defined screen gamma value */) + screen_gamma = user-defined screen_gamma; + /* This is one way that applications share the same screen gamma value. */ + else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL) + screen_gamma = atof(gamma_str); + /* If we don't have another value */ + else + { + screen_gamma = PNG_DEFAULT_sRGB; /* A good guess for a PC monitor + in a dimly lit room */ + screen_gamma = PNG_GAMMA_MAC_18 or 1.0; /* Good guesses for Mac + systems */ + } + + /* Tell libpng to handle the gamma conversion for you. The final call + * is a good guess for PC generated images, but it should be configurable + * by the user at run time. Gamma correction support in your application + * is strongly recommended. + */ + + int intent; + + if (png_get_sRGB(png_ptr, info_ptr, &intent) != 0) + png_set_gamma(png_ptr, screen_gamma, PNG_DEFAULT_sRGB); + else + { + double image_gamma; + if (png_get_gAMA(png_ptr, info_ptr, &image_gamma) != 0) + png_set_gamma(png_ptr, screen_gamma, image_gamma); + else + png_set_gamma(png_ptr, screen_gamma, 0.45455); + } + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + /* Quantize RGB files down to 8-bit palette, or reduce palettes + * to the number of colors available on your screen. + */ + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + int num_palette; + png_colorp palette; + + /* This reduces the image to the application-supplied palette. */ + if (/* We have our own palette */) + { + /* An array of colors to which the image should be quantized. */ + png_color std_color_cube[MAX_SCREEN_COLORS]; + png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS, + MAX_SCREEN_COLORS, NULL, 0); + } + /* This reduces the image to the palette supplied in the file. */ + else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) != 0) + { + png_uint_16p histogram = NULL; + png_get_hIST(png_ptr, info_ptr, &histogram); + png_set_quantize(png_ptr, palette, num_palette, + max_screen_colors, histogram, 0); + } + } +#endif /* READ_QUANTIZE */ + + /* Invert monochrome files to have 0 as white and 1 as black. */ + png_set_invert_mono(png_ptr); + + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT) != 0) + { + png_color_8p sig_bit_p; + png_get_sBIT(png_ptr, info_ptr, &sig_bit_p); + png_set_shift(png_ptr, sig_bit_p); + } + + /* Flip the RGB pixels to BGR (or RGBA to BGRA). */ + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + png_set_bgr(png_ptr); + + /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR). */ + png_set_swap_alpha(png_ptr); + + /* Swap bytes of 16-bit files to least significant byte first. */ + png_set_swap(png_ptr); + + /* Add filler (or alpha) byte (before/after each RGB triplet). */ + png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER); + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Turn on interlace handling. REQUIRED if you are not using + * png_read_image(). To see how to handle interlacing passes, + * see the png_read_row() method below: + */ + number_passes = png_set_interlace_handling(png_ptr); +#else /* !READ_INTERLACING */ + number_passes = 1; +#endif /* READ_INTERLACING */ + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (i.e. you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* Allocate the memory to hold the image using the fields of info_ptr. */ + png_bytep row_pointers[height]; + for (row = 0; row < height; row++) + row_pointers[row] = NULL; /* Clear the pointer array */ + for (row = 0; row < height; row++) + row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, + info_ptr)); + + /* Now it's time to read the image. One of these methods is REQUIRED. */ +#ifdef entire /* Read the entire image in one go */ + png_read_image(png_ptr, row_pointers); + +#else no_entire /* Read the image one or more scanlines at a time */ + /* The other way to read images - deal with interlacing: */ + for (pass = 0; pass < number_passes; pass++) + { +#ifdef single /* Read the image a single row at a time */ + for (y = 0; y < height; y++) + png_read_rows(png_ptr, &row_pointers[y], NULL, 1); + +#else no_single /* Read the image several rows at a time */ + for (y = 0; y < height; y += number_of_rows) + { +#ifdef sparkle /* Read the image using the "sparkle" effect. */ + png_read_rows(png_ptr, &row_pointers[y], NULL, + number_of_rows); +#else no_sparkle /* Read the image using the "rectangle" effect */ + png_read_rows(png_ptr, NULL, &row_pointers[y], + number_of_rows); +#endif no_sparkle /* Use only one of these two methods */ + } + + /* If you want to display the image after every pass, do so here. */ +#endif no_single /* Use only one of these two methods */ + } +#endif no_entire /* Use only one of these two methods */ + + /* Read rest of file, and get additional chunks in info_ptr. REQUIRED. */ + png_read_end(png_ptr, info_ptr); +#endif hilevel + + /* At this point you have read the entire image. */ + + /* Clean up after the read, and free any memory allocated. REQUIRED. */ + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + /* Close the file. */ + fclose(fp); + + /* That's it! */ + return OK; +} + +/* Progressively read a file */ + +int +initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr) +{ + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible, in case we are using dynamically + * linked libraries. + */ + *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + if (*png_ptr == NULL) + { + *info_ptr = NULL; + return ERROR; + } + *info_ptr = png_create_info_struct(png_ptr); + if (*info_ptr == NULL) + { + png_destroy_read_struct(png_ptr, info_ptr, NULL); + return ERROR; + } + if (setjmp(png_jmpbuf((*png_ptr)))) + { + png_destroy_read_struct(png_ptr, info_ptr, NULL); + return ERROR; + } + + /* You will need to provide all three function callbacks, + * even if you aren't using all of them. + * If you aren't using all functions, you can specify NULL + * parameters. Even when all three functions are NULL, + * you need to call png_set_progressive_read_fn(). + * These functions shouldn't be dependent on global or + * static variables if you are decoding several images + * simultaneously. You should store stream specific data + * in a separate struct, given as the second parameter, + * and retrieve the pointer from inside the callbacks using + * the function png_get_progressive_ptr(png_ptr). + */ + png_set_progressive_read_fn(*png_ptr, (void *)stream_data, + info_callback, row_callback, end_callback); + return OK; +} + +int +process_data(png_structp *png_ptr, png_infop *info_ptr, + png_bytep buffer, png_uint_32 length) +{ + if (setjmp(png_jmpbuf((*png_ptr)))) + { + /* Free the png_ptr and info_ptr memory on error. */ + png_destroy_read_struct(png_ptr, info_ptr, NULL); + return ERROR; + } + + /* Give chunks of data as they arrive from the data stream + * (in order, of course). + * On segmented machines, don't give it any more than 64K. + * The library seems to run fine with sizes of 4K, although + * you can give it much less if necessary. (I assume you can + * give it chunks of 1 byte, but I haven't tried with less + * than 256 bytes yet.) When this function returns, you may + * want to display any rows that were generated in the row + * callback, if you aren't already displaying them there. + */ + png_process_data(*png_ptr, *info_ptr, buffer, length); + return OK; +} + +info_callback(png_structp png_ptr, png_infop info) +{ + /* Do any setup here, including setting any of the transformations + * mentioned in the Reading PNG files section. For now, you _must_ + * call either png_start_read_image() or png_read_update_info() + * after all the transformations are set (even if you don't set + * any). You may start getting rows before png_process_data() + * returns, so this is your last chance to prepare for that. + */ +} + +row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) +{ + /* This function is called for every row in the image. If the + * image is interlaced, and you turned on the interlace handler, + * this function will be called for every row in every pass. + * + * In this function you will receive a pointer to new row data from + * libpng called new_row that is to replace a corresponding row (of + * the same data format) in a buffer allocated by your application. + * + * The new row data pointer "new_row" may be NULL, indicating there is + * no new data to be replaced (in cases of interlace loading). + * + * If new_row is not NULL, then you need to call + * png_progressive_combine_row(), to replace the corresponding row as + * shown below: + */ + + /* Get pointer to corresponding row in our PNG read buffer. */ + png_bytep old_row = ((png_bytep *)our_data)[row_num]; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* If both rows are allocated, then copy the new row + * data to the corresponding row data. + */ + if (old_row != NULL && new_row != NULL) + png_progressive_combine_row(png_ptr, old_row, new_row); + + /* The rows and passes are called in order, so you don't really + * need the row_num and pass, but I'm supplying them because it + * may make your life easier. + * + * For the non-NULL rows of interlaced images, you must call + * png_progressive_combine_row() passing in the new row and the + * old row, as demonstrated above. You can call this function for + * NULL rows (it will just return) and for non-interlaced images + * (it just does the memcpy for you) if it will make the code + * easier. Thus, you can just do this for all cases: + */ + png_progressive_combine_row(png_ptr, old_row, new_row); + + /* where old_row is what was displayed for previous rows. Note + * that the first pass (pass == 0 really) will completely cover + * the old row, so the rows do not have to be initialized. After + * the first pass (and only for interlaced images), you will have + * to pass the current row as new_row, and the function will combine + * the old row and the new row. + */ +#endif /* READ_INTERLACING */ +} + +end_callback(png_structp png_ptr, png_infop info) +{ + /* This function is called when the whole image has been read, + * including any chunks after the image (up to and including + * the IEND). You will usually have the same info chunk as you + * had in the header, although some data may have been added + * to the comments and time fields. + * + * Most people won't do much here, perhaps setting a flag that + * marks the image as finished. + */ +} + +/* Write a png file */ +void write_png(char *file_name /* , ... other image information ... */) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_colorp palette; + + /* Open the file */ + fp = fopen(file_name, "wb"); + if (fp == NULL) + return ERROR; + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible with the one used at compile time, + * in case we are using dynamically linked libraries. REQUIRED. + */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + png_voidp user_error_ptr, user_error_fn, user_warning_fn); + if (png_ptr == NULL) + { + fclose(fp); + return ERROR; + } + + /* Allocate/initialize the image information data. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(fp); + png_destroy_write_struct(&png_ptr, NULL); + return ERROR; + } + + /* Set up error handling. REQUIRED if you aren't supplying your own + * error handling functions in the png_create_write_struct() call. + */ + if (setjmp(png_jmpbuf(png_ptr))) + { + /* If we get here, we had a problem writing the file. */ + fclose(fp); + png_destroy_write_struct(&png_ptr, &info_ptr); + return ERROR; + } + + /* One of the following I/O initialization functions is REQUIRED. */ + +#ifdef streams /* I/O initialization method 1 */ + /* Set up the output control if you are using standard C streams. */ + png_init_io(png_ptr, fp); + +#else no_streams /* I/O initialization method 2 */ + /* If you are using replacement write functions, instead of calling + * png_init_io(), you would call: + */ + png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn, + user_IO_flush_function); + /* where user_io_ptr is a structure you want available to the callbacks. */ +#endif no_streams /* Only use one initialization method */ + +#ifdef hilevel + /* This is the easy way. Use it if you already have all the + * image info living in the structure. You could "|" many + * PNG_TRANSFORM flags into the png_transforms integer here. + */ + png_write_png(png_ptr, info_ptr, png_transforms, NULL); + +#else + /* This is the hard way. */ + + /* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8 or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. + * REQUIRED. + */ + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, + PNG_COLOR_TYPE_???, PNG_INTERLACE_????, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* Set the palette if there is one. REQUIRED for indexed-color images. */ + palette = (png_colorp)png_malloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))); + /* ... Set palette colors ... */ + png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); + /* You must not free palette here, because png_set_PLTE only makes a link + * to the palette that you allocated. Wait until you are about to destroy + * the png structure. + */ + + /* Optional significant bit (sBIT) chunk. */ + png_color_8 sig_bit; + + /* If we are dealing with a grayscale image then */ + sig_bit.gray = true_bit_depth; + + /* Otherwise, if we are dealing with a color image then */ + sig_bit.red = true_red_bit_depth; + sig_bit.green = true_green_bit_depth; + sig_bit.blue = true_blue_bit_depth; + + /* If the image has an alpha channel then */ + sig_bit.alpha = true_alpha_bit_depth; + + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + + /* Optional gamma chunk is strongly suggested if you have any guess + * as to the correct gamma of the image. + */ + png_set_gAMA(png_ptr, info_ptr, gamma); + + /* Optionally write comments into the image. */ + { + png_text text_ptr[3]; + + char key0[] = "Title"; + char text0[] = "Mona Lisa"; + text_ptr[0].key = key0; + text_ptr[0].text = text0; + text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[0].itxt_length = 0; + text_ptr[0].lang = NULL; + text_ptr[0].lang_key = NULL; + + char key1[] = "Author"; + char text1[] = "Leonardo DaVinci"; + text_ptr[1].key = key1; + text_ptr[1].text = text1; + text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[1].itxt_length = 0; + text_ptr[1].lang = NULL; + text_ptr[1].lang_key = NULL; + + char key2[] = "Description"; + char text2[] = ""; + text_ptr[2].key = key2; + text_ptr[2].text = text2; + text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; + text_ptr[2].itxt_length = 0; + text_ptr[2].lang = NULL; + text_ptr[2].lang_key = NULL; + + png_set_text(write_ptr, write_info_ptr, text_ptr, 3); + } + + /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs. */ + + /* Note that if sRGB is present, the gAMA and cHRM chunks must be ignored + * on read and, if your application chooses to write them, they must + * be written in accordance with the sRGB profile. + */ + + /* Write the file header information. REQUIRED. */ + png_write_info(png_ptr, info_ptr); + + /* If you want, you can write the info in two steps, in case you need to + * write your private chunk ahead of PLTE: + * + * png_write_info_before_PLTE(write_ptr, write_info_ptr); + * write_my_chunk(); + * png_write_info(png_ptr, info_ptr); + * + * However, given the level of known- and unknown-chunk support in 1.2.0 + * and up, this should no longer be necessary. + */ + + /* Once we write out the header, the compression type on the text + * chunk gets changed to PNG_TEXT_COMPRESSION_NONE_WR or + * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again + * at the end. + */ + + /* Set up the transformations you want. Note that these are + * all optional. Only call them if you want them. + */ + + /* Invert monochrome pixels. */ + png_set_invert_mono(png_ptr); + + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + png_set_shift(png_ptr, &sig_bit); + + /* Pack pixels into bytes. */ + png_set_packing(png_ptr); + + /* Swap location of alpha bytes from ARGB to RGBA. */ + png_set_swap_alpha(png_ptr); + + /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into + * RGB (4 channels -> 3 channels). The second parameter is not used. + */ + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + + /* Flip BGR pixels to RGB. */ + png_set_bgr(png_ptr); + + /* Swap bytes of 16-bit files to most significant byte first. */ + png_set_swap(png_ptr); + + /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats. */ + png_set_packswap(png_ptr); + + /* Turn on interlace handling if you are not using png_write_image(). */ + if (interlacing != 0) + number_passes = png_set_interlace_handling(png_ptr); + else + number_passes = 1; + + /* The easiest way to write the image (you may have a different memory + * layout, however, so choose what fits your needs best). You need to + * use the first method if you aren't handling interlacing yourself. + */ + png_uint_32 k, height, width; + + /* In this example, "image" is a one-dimensional array of bytes. */ + + /* Guard against integer overflow. */ + if (height > PNG_SIZE_MAX / (width * bytes_per_pixel)) + png_error(png_ptr, "Image data buffer would be too large"); + + png_byte image[height * width * bytes_per_pixel]; + png_bytep row_pointers[height]; + + if (height > PNG_UINT_32_MAX / (sizeof (png_bytep))) + png_error(png_ptr, "Image is too tall to process in memory"); + + /* Set up pointers into your "image" byte array. */ + for (k = 0; k < height; k++) + row_pointers[k] = image + k * width * bytes_per_pixel; + + /* One of the following output methods is REQUIRED. */ + +#ifdef entire /* Write out the entire image data in one call */ + png_write_image(png_ptr, row_pointers); + + /* The other way to write the image - deal with interlacing. */ + +#else no_entire /* Write out the image data by one or more scanlines */ + + /* The number of passes is either 1 for non-interlaced images, + * or 7 for interlaced images. + */ + for (pass = 0; pass < number_passes; pass++) + { + /* Write a few rows at a time. */ + png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows); + + /* If you are only writing one row at a time, this works. */ + for (y = 0; y < height; y++) + png_write_rows(png_ptr, &row_pointers[y], 1); + } +#endif no_entire /* Use only one output method */ + + /* You can write optional chunks like tEXt, zTXt, and tIME at the end + * as well. Shouldn't be necessary in 1.2.0 and up, as all the public + * chunks are supported, and you can use png_set_unknown_chunks() to + * register unknown chunks into the info structure to be written out. + */ + + /* It is REQUIRED to call this to finish writing the rest of the file. */ + png_write_end(png_ptr, info_ptr); +#endif hilevel + + /* If you png_malloced a palette, free it here. + * (Don't free info_ptr->palette, as shown in versions 1.0.5m and earlier of + * this example; if libpng mallocs info_ptr->palette, libpng will free it). + * If you allocated it with malloc() instead of png_malloc(), use free() + * instead of png_free(). + */ + png_free(png_ptr, palette); + palette = NULL; + + /* Similarly, if you png_malloced any data that you passed in with + * png_set_something(), such as a hist or trans array, free it here, + * when you can be sure that libpng is through with it. + */ + png_free(png_ptr, trans); + trans = NULL; + + /* Whenever you use png_free(), it is a good idea to set the pointer to + * NULL in case your application inadvertently tries to png_free() it + * again. When png_free() sees a NULL it returns without action, avoiding + * the double-free problem. + */ + + /* Clean up after the write, and free any allocated memory. */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + /* Close the file. */ + fclose(fp); + + /* That's it! */ + return OK; +} + +#endif /* if 0 */ diff --git a/thirdparty/libpng/upstream/intel/filter_sse2_intrinsics.c b/thirdparty/libpng/upstream/intel/filter_sse2_intrinsics.c index c145f1190..0f3c97a52 100644 --- a/thirdparty/libpng/upstream/intel/filter_sse2_intrinsics.c +++ b/thirdparty/libpng/upstream/intel/filter_sse2_intrinsics.c @@ -1,391 +1,408 @@ - -/* filter_sse2_intrinsics.c - SSE2 optimized filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2016-2017 Glenn Randers-Pehrson - * Written by Mike Klein and Matt Sarett - * Derived from arm/filter_neon_intrinsics.c - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -#if PNG_INTEL_SSE_IMPLEMENTATION > 0 - -#include - -/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d). - * They're positioned like this: - * prev: c b - * row: a d - * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be - * whichever of a, b, or c is closest to p=a+b-c. - */ - -static __m128i load4(const void* p) { - int tmp; - memcpy(&tmp, p, sizeof(tmp)); - return _mm_cvtsi32_si128(tmp); -} - -static void store4(void* p, __m128i v) { - int tmp = _mm_cvtsi128_si32(v); - memcpy(p, &tmp, sizeof(int)); -} - -static __m128i load3(const void* p) { - png_uint_32 tmp = 0; - memcpy(&tmp, p, 3); - return _mm_cvtsi32_si128(tmp); -} - -static void store3(void* p, __m128i v) { - int tmp = _mm_cvtsi128_si32(v); - memcpy(p, &tmp, 3); -} - -void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Sub filter predicts each pixel as the previous pixel, a. - * There is no pixel to the left of the first pixel. It's encoded directly. - * That works with our main loop if we just say that left pixel was zero. - */ - size_t rb; - - __m128i a, d = _mm_setzero_si128(); - - png_debug(1, "in png_read_filter_row_sub3_sse2"); - - rb = row_info->rowbytes; - while (rb >= 4) { - a = d; d = load4(row); - d = _mm_add_epi8(d, a); - store3(row, d); - - row += 3; - rb -= 3; - } - if (rb > 0) { - a = d; d = load3(row); - d = _mm_add_epi8(d, a); - store3(row, d); - - row += 3; - rb -= 3; - } - PNG_UNUSED(prev) -} - -void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Sub filter predicts each pixel as the previous pixel, a. - * There is no pixel to the left of the first pixel. It's encoded directly. - * That works with our main loop if we just say that left pixel was zero. - */ - size_t rb; - - __m128i a, d = _mm_setzero_si128(); - - png_debug(1, "in png_read_filter_row_sub4_sse2"); - - rb = row_info->rowbytes+4; - while (rb > 4) { - a = d; d = load4(row); - d = _mm_add_epi8(d, a); - store4(row, d); - - row += 4; - rb -= 4; - } - PNG_UNUSED(prev) -} - -void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Avg filter predicts each pixel as the (truncated) average of a and b. - * There's no pixel to the left of the first pixel. Luckily, it's - * predicted to be half of the pixel above it. So again, this works - * perfectly with our loop if we make sure a starts at zero. - */ - - size_t rb; - - const __m128i zero = _mm_setzero_si128(); - - __m128i b; - __m128i a, d = zero; - - png_debug(1, "in png_read_filter_row_avg3_sse2"); - rb = row_info->rowbytes; - while (rb >= 4) { - __m128i avg; - b = load4(prev); - a = d; d = load4(row ); - - /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ - avg = _mm_avg_epu8(a,b); - /* ...but we can fix it up by subtracting off 1 if it rounded up. */ - avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), - _mm_set1_epi8(1))); - d = _mm_add_epi8(d, avg); - store3(row, d); - - prev += 3; - row += 3; - rb -= 3; - } - if (rb > 0) { - __m128i avg; - b = load3(prev); - a = d; d = load3(row ); - - /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ - avg = _mm_avg_epu8(a,b); - /* ...but we can fix it up by subtracting off 1 if it rounded up. */ - avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), - _mm_set1_epi8(1))); - - d = _mm_add_epi8(d, avg); - store3(row, d); - - prev += 3; - row += 3; - rb -= 3; - } -} - -void png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Avg filter predicts each pixel as the (truncated) average of a and b. - * There's no pixel to the left of the first pixel. Luckily, it's - * predicted to be half of the pixel above it. So again, this works - * perfectly with our loop if we make sure a starts at zero. - */ - size_t rb; - const __m128i zero = _mm_setzero_si128(); - __m128i b; - __m128i a, d = zero; - - png_debug(1, "in png_read_filter_row_avg4_sse2"); - - rb = row_info->rowbytes+4; - while (rb > 4) { - __m128i avg; - b = load4(prev); - a = d; d = load4(row ); - - /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ - avg = _mm_avg_epu8(a,b); - /* ...but we can fix it up by subtracting off 1 if it rounded up. */ - avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), - _mm_set1_epi8(1))); - - d = _mm_add_epi8(d, avg); - store4(row, d); - - prev += 4; - row += 4; - rb -= 4; - } -} - -/* Returns |x| for 16-bit lanes. */ -static __m128i abs_i16(__m128i x) { -#if PNG_INTEL_SSE_IMPLEMENTATION >= 2 - return _mm_abs_epi16(x); -#else - /* Read this all as, return x<0 ? -x : x. - * To negate two's complement, you flip all the bits then add 1. - */ - __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128()); - - /* Flip negative lanes. */ - x = _mm_xor_si128(x, is_negative); - - /* +1 to negative lanes, else +0. */ - x = _mm_sub_epi16(x, is_negative); - return x; -#endif -} - -/* Bytewise c ? t : e. */ -static __m128i if_then_else(__m128i c, __m128i t, __m128i e) { -#if PNG_INTEL_SSE_IMPLEMENTATION >= 3 - return _mm_blendv_epi8(e,t,c); -#else - return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e)); -#endif -} - -void png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* Paeth tries to predict pixel d using the pixel to the left of it, a, - * and two pixels from the previous row, b and c: - * prev: c b - * row: a d - * The Paeth function predicts d to be whichever of a, b, or c is nearest to - * p=a+b-c. - * - * The first pixel has no left context, and so uses an Up filter, p = b. - * This works naturally with our main loop's p = a+b-c if we force a and c - * to zero. - * Here we zero b and d, which become c and a respectively at the start of - * the loop. - */ - size_t rb; - const __m128i zero = _mm_setzero_si128(); - __m128i c, b = zero, - a, d = zero; - - png_debug(1, "in png_read_filter_row_paeth3_sse2"); - - rb = row_info->rowbytes; - while (rb >= 4) { - /* It's easiest to do this math (particularly, deal with pc) with 16-bit - * intermediates. - */ - __m128i pa,pb,pc,smallest,nearest; - c = b; b = _mm_unpacklo_epi8(load4(prev), zero); - a = d; d = _mm_unpacklo_epi8(load4(row ), zero); - - /* (p-a) == (a+b-c - a) == (b-c) */ - - pa = _mm_sub_epi16(b,c); - - /* (p-b) == (a+b-c - b) == (a-c) */ - pb = _mm_sub_epi16(a,c); - - /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ - pc = _mm_add_epi16(pa,pb); - - pa = abs_i16(pa); /* |p-a| */ - pb = abs_i16(pb); /* |p-b| */ - pc = abs_i16(pc); /* |p-c| */ - - smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); - - /* Paeth breaks ties favoring a over b over c. */ - nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, - if_then_else(_mm_cmpeq_epi16(smallest, pb), b, - c)); - - /* Note `_epi8`: we need addition to wrap modulo 255. */ - d = _mm_add_epi8(d, nearest); - store3(row, _mm_packus_epi16(d,d)); - - prev += 3; - row += 3; - rb -= 3; - } - if (rb > 0) { - /* It's easiest to do this math (particularly, deal with pc) with 16-bit - * intermediates. - */ - __m128i pa,pb,pc,smallest,nearest; - c = b; b = _mm_unpacklo_epi8(load3(prev), zero); - a = d; d = _mm_unpacklo_epi8(load3(row ), zero); - - /* (p-a) == (a+b-c - a) == (b-c) */ - pa = _mm_sub_epi16(b,c); - - /* (p-b) == (a+b-c - b) == (a-c) */ - pb = _mm_sub_epi16(a,c); - - /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ - pc = _mm_add_epi16(pa,pb); - - pa = abs_i16(pa); /* |p-a| */ - pb = abs_i16(pb); /* |p-b| */ - pc = abs_i16(pc); /* |p-c| */ - - smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); - - /* Paeth breaks ties favoring a over b over c. */ - nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, - if_then_else(_mm_cmpeq_epi16(smallest, pb), b, - c)); - - /* Note `_epi8`: we need addition to wrap modulo 255. */ - d = _mm_add_epi8(d, nearest); - store3(row, _mm_packus_epi16(d,d)); - - prev += 3; - row += 3; - rb -= 3; - } -} - -void png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* Paeth tries to predict pixel d using the pixel to the left of it, a, - * and two pixels from the previous row, b and c: - * prev: c b - * row: a d - * The Paeth function predicts d to be whichever of a, b, or c is nearest to - * p=a+b-c. - * - * The first pixel has no left context, and so uses an Up filter, p = b. - * This works naturally with our main loop's p = a+b-c if we force a and c - * to zero. - * Here we zero b and d, which become c and a respectively at the start of - * the loop. - */ - size_t rb; - const __m128i zero = _mm_setzero_si128(); - __m128i pa,pb,pc,smallest,nearest; - __m128i c, b = zero, - a, d = zero; - - png_debug(1, "in png_read_filter_row_paeth4_sse2"); - - rb = row_info->rowbytes+4; - while (rb > 4) { - /* It's easiest to do this math (particularly, deal with pc) with 16-bit - * intermediates. - */ - c = b; b = _mm_unpacklo_epi8(load4(prev), zero); - a = d; d = _mm_unpacklo_epi8(load4(row ), zero); - - /* (p-a) == (a+b-c - a) == (b-c) */ - pa = _mm_sub_epi16(b,c); - - /* (p-b) == (a+b-c - b) == (a-c) */ - pb = _mm_sub_epi16(a,c); - - /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ - pc = _mm_add_epi16(pa,pb); - - pa = abs_i16(pa); /* |p-a| */ - pb = abs_i16(pb); /* |p-b| */ - pc = abs_i16(pc); /* |p-c| */ - - smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); - - /* Paeth breaks ties favoring a over b over c. */ - nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, - if_then_else(_mm_cmpeq_epi16(smallest, pb), b, - c)); - - /* Note `_epi8`: we need addition to wrap modulo 255. */ - d = _mm_add_epi8(d, nearest); - store4(row, _mm_packus_epi16(d,d)); - - prev += 4; - row += 4; - rb -= 4; - } -} - -#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ -#endif /* READ */ +/* filter_sse2_intrinsics.c - SSE2 optimized filter functions + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2016-2017 Glenn Randers-Pehrson + * Written by Mike Klein and Matt Sarett + * Derived from arm/filter_neon_intrinsics.c + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +#if PNG_INTEL_SSE_IMPLEMENTATION > 0 + +#include + +/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d). + * They're positioned like this: + * prev: c b + * row: a d + * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be + * whichever of a, b, or c is closest to p=a+b-c. + */ + +static __m128i +load4(const void *p) +{ + int tmp; + memcpy(&tmp, p, sizeof(tmp)); + return _mm_cvtsi32_si128(tmp); +} + +static void +store4(void *p, __m128i v) +{ + int tmp = _mm_cvtsi128_si32(v); + memcpy(p, &tmp, sizeof(int)); +} + +static __m128i +load3(const void *p) +{ + png_uint_32 tmp = 0; + memcpy(&tmp, p, 3); + return _mm_cvtsi32_si128(tmp); +} + +static void +store3(void *p, __m128i v) +{ + int tmp = _mm_cvtsi128_si32(v); + memcpy(p, &tmp, 3); +} + +void +png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Sub filter predicts each pixel as the previous pixel, a. + * There is no pixel to the left of the first pixel. It's encoded directly. + * That works with our main loop if we just say that left pixel was zero. + */ + size_t rb; + + __m128i a, d = _mm_setzero_si128(); + + png_debug(1, "in png_read_filter_row_sub3_sse2"); + + rb = row_info->rowbytes; + while (rb >= 4) { + a = d; d = load4(row); + d = _mm_add_epi8(d, a); + store3(row, d); + + row += 3; + rb -= 3; + } + if (rb > 0) { + a = d; d = load3(row); + d = _mm_add_epi8(d, a); + store3(row, d); + + row += 3; + rb -= 3; + } + PNG_UNUSED(prev) +} + +void +png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Sub filter predicts each pixel as the previous pixel, a. + * There is no pixel to the left of the first pixel. It's encoded directly. + * That works with our main loop if we just say that left pixel was zero. + */ + size_t rb; + + __m128i a, d = _mm_setzero_si128(); + + png_debug(1, "in png_read_filter_row_sub4_sse2"); + + rb = row_info->rowbytes+4; + while (rb > 4) { + a = d; d = load4(row); + d = _mm_add_epi8(d, a); + store4(row, d); + + row += 4; + rb -= 4; + } + PNG_UNUSED(prev) +} + +void +png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Avg filter predicts each pixel as the (truncated) average of a and b. + * There's no pixel to the left of the first pixel. Luckily, it's + * predicted to be half of the pixel above it. So again, this works + * perfectly with our loop if we make sure a starts at zero. + */ + + size_t rb; + + const __m128i zero = _mm_setzero_si128(); + + __m128i b; + __m128i a, d = zero; + + png_debug(1, "in png_read_filter_row_avg3_sse2"); + rb = row_info->rowbytes; + while (rb >= 4) { + __m128i avg; + b = load4(prev); + a = d; d = load4(row ); + + /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ + avg = _mm_avg_epu8(a,b); + /* ...but we can fix it up by subtracting off 1 if it rounded up. */ + avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), + _mm_set1_epi8(1))); + d = _mm_add_epi8(d, avg); + store3(row, d); + + prev += 3; + row += 3; + rb -= 3; + } + if (rb > 0) { + __m128i avg; + b = load3(prev); + a = d; d = load3(row ); + + /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ + avg = _mm_avg_epu8(a,b); + /* ...but we can fix it up by subtracting off 1 if it rounded up. */ + avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), + _mm_set1_epi8(1))); + + d = _mm_add_epi8(d, avg); + store3(row, d); + + prev += 3; + row += 3; + rb -= 3; + } +} + +void +png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* The Avg filter predicts each pixel as the (truncated) average of a and b. + * There's no pixel to the left of the first pixel. Luckily, it's + * predicted to be half of the pixel above it. So again, this works + * perfectly with our loop if we make sure a starts at zero. + */ + size_t rb; + const __m128i zero = _mm_setzero_si128(); + __m128i b; + __m128i a, d = zero; + + png_debug(1, "in png_read_filter_row_avg4_sse2"); + + rb = row_info->rowbytes+4; + while (rb > 4) { + __m128i avg; + b = load4(prev); + a = d; d = load4(row ); + + /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ + avg = _mm_avg_epu8(a,b); + /* ...but we can fix it up by subtracting off 1 if it rounded up. */ + avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), + _mm_set1_epi8(1))); + + d = _mm_add_epi8(d, avg); + store4(row, d); + + prev += 4; + row += 4; + rb -= 4; + } +} + +/* Returns |x| for 16-bit lanes. */ +static __m128i +abs_i16(__m128i x) +{ +#if PNG_INTEL_SSE_IMPLEMENTATION >= 2 + return _mm_abs_epi16(x); +#else + /* Read this all as, return x<0 ? -x : x. + * To negate two's complement, you flip all the bits then add 1. + */ + __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128()); + + /* Flip negative lanes. */ + x = _mm_xor_si128(x, is_negative); + + /* +1 to negative lanes, else +0. */ + x = _mm_sub_epi16(x, is_negative); + return x; +#endif +} + +/* Bytewise c ? t : e. */ +static __m128i +if_then_else(__m128i c, __m128i t, __m128i e) +{ +#if PNG_INTEL_SSE_IMPLEMENTATION >= 3 + return _mm_blendv_epi8(e,t,c); +#else + return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e)); +#endif +} + +void +png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* Paeth tries to predict pixel d using the pixel to the left of it, a, + * and two pixels from the previous row, b and c: + * prev: c b + * row: a d + * The Paeth function predicts d to be whichever of a, b, or c is nearest to + * p=a+b-c. + * + * The first pixel has no left context, and so uses an Up filter, p = b. + * This works naturally with our main loop's p = a+b-c if we force a and c + * to zero. + * Here we zero b and d, which become c and a respectively at the start of + * the loop. + */ + size_t rb; + const __m128i zero = _mm_setzero_si128(); + __m128i c, b = zero, + a, d = zero; + + png_debug(1, "in png_read_filter_row_paeth3_sse2"); + + rb = row_info->rowbytes; + while (rb >= 4) { + /* It's easiest to do this math (particularly, deal with pc) with 16-bit + * intermediates. + */ + __m128i pa,pb,pc,smallest,nearest; + c = b; b = _mm_unpacklo_epi8(load4(prev), zero); + a = d; d = _mm_unpacklo_epi8(load4(row ), zero); + + /* (p-a) == (a+b-c - a) == (b-c) */ + + pa = _mm_sub_epi16(b,c); + + /* (p-b) == (a+b-c - b) == (a-c) */ + pb = _mm_sub_epi16(a,c); + + /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ + pc = _mm_add_epi16(pa,pb); + + pa = abs_i16(pa); /* |p-a| */ + pb = abs_i16(pb); /* |p-b| */ + pc = abs_i16(pc); /* |p-c| */ + + smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); + + /* Paeth breaks ties favoring a over b over c. */ + nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, + if_then_else(_mm_cmpeq_epi16(smallest, pb), b, + c)); + + /* Note `_epi8`: we need addition to wrap modulo 255. */ + d = _mm_add_epi8(d, nearest); + store3(row, _mm_packus_epi16(d,d)); + + prev += 3; + row += 3; + rb -= 3; + } + if (rb > 0) { + /* It's easiest to do this math (particularly, deal with pc) with 16-bit + * intermediates. + */ + __m128i pa,pb,pc,smallest,nearest; + c = b; b = _mm_unpacklo_epi8(load3(prev), zero); + a = d; d = _mm_unpacklo_epi8(load3(row ), zero); + + /* (p-a) == (a+b-c - a) == (b-c) */ + pa = _mm_sub_epi16(b,c); + + /* (p-b) == (a+b-c - b) == (a-c) */ + pb = _mm_sub_epi16(a,c); + + /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ + pc = _mm_add_epi16(pa,pb); + + pa = abs_i16(pa); /* |p-a| */ + pb = abs_i16(pb); /* |p-b| */ + pc = abs_i16(pc); /* |p-c| */ + + smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); + + /* Paeth breaks ties favoring a over b over c. */ + nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, + if_then_else(_mm_cmpeq_epi16(smallest, pb), b, + c)); + + /* Note `_epi8`: we need addition to wrap modulo 255. */ + d = _mm_add_epi8(d, nearest); + store3(row, _mm_packus_epi16(d,d)); + + prev += 3; + row += 3; + rb -= 3; + } +} + +void +png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row, + png_const_bytep prev) +{ + /* Paeth tries to predict pixel d using the pixel to the left of it, a, + * and two pixels from the previous row, b and c: + * prev: c b + * row: a d + * The Paeth function predicts d to be whichever of a, b, or c is nearest to + * p=a+b-c. + * + * The first pixel has no left context, and so uses an Up filter, p = b. + * This works naturally with our main loop's p = a+b-c if we force a and c + * to zero. + * Here we zero b and d, which become c and a respectively at the start of + * the loop. + */ + size_t rb; + const __m128i zero = _mm_setzero_si128(); + __m128i pa,pb,pc,smallest,nearest; + __m128i c, b = zero, + a, d = zero; + + png_debug(1, "in png_read_filter_row_paeth4_sse2"); + + rb = row_info->rowbytes+4; + while (rb > 4) { + /* It's easiest to do this math (particularly, deal with pc) with 16-bit + * intermediates. + */ + c = b; b = _mm_unpacklo_epi8(load4(prev), zero); + a = d; d = _mm_unpacklo_epi8(load4(row ), zero); + + /* (p-a) == (a+b-c - a) == (b-c) */ + pa = _mm_sub_epi16(b,c); + + /* (p-b) == (a+b-c - b) == (a-c) */ + pb = _mm_sub_epi16(a,c); + + /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ + pc = _mm_add_epi16(pa,pb); + + pa = abs_i16(pa); /* |p-a| */ + pb = abs_i16(pb); /* |p-b| */ + pc = abs_i16(pc); /* |p-c| */ + + smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); + + /* Paeth breaks ties favoring a over b over c. */ + nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, + if_then_else(_mm_cmpeq_epi16(smallest, pb), b, + c)); + + /* Note `_epi8`: we need addition to wrap modulo 255. */ + d = _mm_add_epi8(d, nearest); + store4(row, _mm_packus_epi16(d,d)); + + prev += 4; + row += 4; + rb -= 4; + } +} + +#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/intel/intel_init.c b/thirdparty/libpng/upstream/intel/intel_init.c index 8d1beee99..9e4610d25 100644 --- a/thirdparty/libpng/upstream/intel/intel_init.c +++ b/thirdparty/libpng/upstream/intel/intel_init.c @@ -1,52 +1,51 @@ - -/* intel_init.c - SSE2 optimized filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2016-2017 Glenn Randers-Pehrson - * Written by Mike Klein and Matt Sarett, Google, Inc. - * Derived from arm/arm_init.c - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED -#if PNG_INTEL_SSE_IMPLEMENTATION > 0 - -void -png_init_filter_functions_sse2(png_structp pp, unsigned int bpp) -{ - /* The techniques used to implement each of these filters in SSE operate on - * one pixel at a time. - * So they generally speed up 3bpp images about 3x, 4bpp images about 4x. - * They can scale up to 6 and 8 bpp images and down to 2 bpp images, - * but they'd not likely have any benefit for 1bpp images. - * Most of these can be implemented using only MMX and 64-bit registers, - * but they end up a bit slower than using the equally-ubiquitous SSE2. - */ - png_debug(1, "in png_init_filter_functions_sse2"); - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_sse2; - } - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_sse2; - } - - /* No need optimize PNG_FILTER_VALUE_UP. The compiler should - * autovectorize. - */ -} - -#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ -#endif /* PNG_READ_SUPPORTED */ +/* intel_init.c - SSE2 optimized filter functions + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2016-2017 Glenn Randers-Pehrson + * Written by Mike Klein and Matt Sarett, Google, Inc. + * Derived from arm/arm_init.c + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED +#if PNG_INTEL_SSE_IMPLEMENTATION > 0 + +void +png_init_filter_functions_sse2(png_structp pp, unsigned int bpp) +{ + /* The techniques used to implement each of these filters in SSE operate on + * one pixel at a time. + * So they generally speed up 3bpp images about 3x, 4bpp images about 4x. + * They can scale up to 6 and 8 bpp images and down to 2 bpp images, + * but they'd not likely have any benefit for 1bpp images. + * Most of these can be implemented using only MMX and 64-bit registers, + * but they end up a bit slower than using the equally-ubiquitous SSE2. + */ + png_debug(1, "in png_init_filter_functions_sse2"); + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_sse2; + } + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_sse2; + } + + /* No need optimize PNG_FILTER_VALUE_UP. The compiler should + * autovectorize. + */ +} + +#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/thirdparty/libpng/upstream/png.c b/thirdparty/libpng/upstream/png.c index 78bd27364..6cb809a49 100644 --- a/thirdparty/libpng/upstream/png.c +++ b/thirdparty/libpng/upstream/png.c @@ -1,4566 +1,4044 @@ - -/* png.c - location for general purpose libpng functions - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_44 Your_png_h_is_not_version_1_6_44; - -/* Tells libpng that we have already handled the first "num_bytes" bytes - * of the PNG file signature. If the PNG data is embedded into another - * stream we can set num_bytes = 8 so that libpng will not attempt to read - * or write any of the magic bytes before it starts on the IHDR. - */ - -#ifdef PNG_READ_SUPPORTED -void PNGAPI -png_set_sig_bytes(png_structrp png_ptr, int num_bytes) -{ - unsigned int nb = (unsigned int)num_bytes; - - png_debug(1, "in png_set_sig_bytes"); - - if (png_ptr == NULL) - return; - - if (num_bytes < 0) - nb = 0; - - if (nb > 8) - png_error(png_ptr, "Too many bytes for PNG signature"); - - png_ptr->sig_bytes = (png_byte)nb; -} - -/* Checks whether the supplied bytes match the PNG signature. We allow - * checking less than the full 8-byte signature so that those apps that - * already read the first few bytes of a file to determine the file type - * can simply check the remaining bytes for extra assurance. Returns - * an integer less than, equal to, or greater than zero if sig is found, - * respectively, to be less than, to match, or be greater than the correct - * PNG signature (this is the same behavior as strcmp, memcmp, etc). - */ -int PNGAPI -png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) -{ - static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - - if (num_to_check > 8) - num_to_check = 8; - - else if (num_to_check < 1) - return -1; - - if (start > 7) - return -1; - - if (start + num_to_check > 8) - num_to_check = 8 - start; - - return memcmp(&sig[start], &png_signature[start], num_to_check); -} - -#endif /* READ */ - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Function to allocate memory for zlib */ -PNG_FUNCTION(voidpf /* PRIVATE */, -png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) -{ - png_alloc_size_t num_bytes = size; - - if (png_ptr == NULL) - return NULL; - - if (items >= (~(png_alloc_size_t)0)/size) - { - png_warning (png_voidcast(png_structrp, png_ptr), - "Potential overflow in png_zalloc()"); - return NULL; - } - - num_bytes *= items; - return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); -} - -/* Function to free memory for zlib */ -void /* PRIVATE */ -png_zfree(voidpf png_ptr, voidpf ptr) -{ - png_free(png_voidcast(png_const_structrp,png_ptr), ptr); -} - -/* Reset the CRC variable to 32 bits of 1's. Care must be taken - * in case CRC is > 32 bits to leave the top bits 0. - */ -void /* PRIVATE */ -png_reset_crc(png_structrp png_ptr) -{ - /* The cast is safe because the crc is a 32-bit value. */ - png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); -} - -/* Calculate the CRC over a section of data. We can only pass as - * much data to this routine as the largest single buffer size. We - * also check that this data will actually be used before going to the - * trouble of calculating it. - */ -void /* PRIVATE */ -png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length) -{ - int need_crc = 1; - - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - - /* 'uLong' is defined in zlib.h as unsigned long; this means that on some - * systems it is a 64-bit value. crc32, however, returns 32 bits so the - * following cast is safe. 'uInt' may be no more than 16 bits, so it is - * necessary to perform a loop here. - */ - if (need_crc != 0 && length > 0) - { - uLong crc = png_ptr->crc; /* Should never issue a warning */ - - do - { - uInt safe_length = (uInt)length; -#ifndef __COVERITY__ - if (safe_length == 0) - safe_length = (uInt)-1; /* evil, but safe */ -#endif - - crc = crc32(crc, ptr, safe_length); - - /* The following should never issue compiler warnings; if they do the - * target system has characteristics that will probably violate other - * assumptions within the libpng code. - */ - ptr += safe_length; - length -= safe_length; - } - while (length > 0); - - /* And the following is always safe because the crc is only 32 bits. */ - png_ptr->crc = (png_uint_32)crc; - } -} - -/* Check a user supplied version number, called from both read and write - * functions that create a png_struct. - */ -int -png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) -{ - /* Libpng versions 1.0.0 and later are binary compatible if the version - * string matches through the second '.'; we must recompile any - * applications that use any older library version. - */ - - if (user_png_ver != NULL) - { - int i = -1; - int found_dots = 0; - - do - { - i++; - if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i]) - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - if (user_png_ver[i] == '.') - found_dots++; - } while (found_dots < 2 && user_png_ver[i] != 0 && - PNG_LIBPNG_VER_STRING[i] != 0); - } - - else - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - - if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0) - { -#ifdef PNG_WARNINGS_SUPPORTED - size_t pos = 0; - char m[128]; - - pos = png_safecat(m, (sizeof m), pos, - "Application built with libpng-"); - pos = png_safecat(m, (sizeof m), pos, user_png_ver); - pos = png_safecat(m, (sizeof m), pos, " but running with "); - pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING); - PNG_UNUSED(pos) - - png_warning(png_ptr, m); -#endif - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags = 0; -#endif - - return 0; - } - - /* Success return. */ - return 1; -} - -/* Generic function to create a png_struct for either read or write - this - * contains the common initialization. - */ -PNG_FUNCTION(png_structp /* PRIVATE */, -png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_struct create_struct; -# ifdef PNG_SETJMP_SUPPORTED - jmp_buf create_jmp_buf; -# endif - - /* This temporary stack-allocated structure is used to provide a place to - * build enough context to allow the user provided memory allocator (if any) - * to be called. - */ - memset(&create_struct, 0, (sizeof create_struct)); - - /* Added at libpng-1.2.6 */ -# ifdef PNG_USER_LIMITS_SUPPORTED - create_struct.user_width_max = PNG_USER_WIDTH_MAX; - create_struct.user_height_max = PNG_USER_HEIGHT_MAX; - -# ifdef PNG_USER_CHUNK_CACHE_MAX - /* Added at libpng-1.2.43 and 1.4.0 */ - create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; -# endif - -# ifdef PNG_USER_CHUNK_MALLOC_MAX - /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists - * in png_struct regardless. - */ - create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; -# endif -# endif - - /* The following two API calls simply set fields in png_struct, so it is safe - * to do them now even though error handling is not yet set up. - */ -# ifdef PNG_USER_MEM_SUPPORTED - png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); -# else - PNG_UNUSED(mem_ptr) - PNG_UNUSED(malloc_fn) - PNG_UNUSED(free_fn) -# endif - - /* (*error_fn) can return control to the caller after the error_ptr is set, - * this will result in a memory leak unless the error_fn does something - * extremely sophisticated. The design lacks merit but is implicit in the - * API. - */ - png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); - -# ifdef PNG_SETJMP_SUPPORTED - if (!setjmp(create_jmp_buf)) -# endif - { -# ifdef PNG_SETJMP_SUPPORTED - /* Temporarily fake out the longjmp information until we have - * successfully completed this function. This only works if we have - * setjmp() support compiled in, but it is safe - this stuff should - * never happen. - */ - create_struct.jmp_buf_ptr = &create_jmp_buf; - create_struct.jmp_buf_size = 0; /*stack allocation*/ - create_struct.longjmp_fn = longjmp; -# endif - /* Call the general version checker (shared with read and write code): - */ - if (png_user_version_check(&create_struct, user_png_ver) != 0) - { - png_structrp png_ptr = png_voidcast(png_structrp, - png_malloc_warn(&create_struct, (sizeof *png_ptr))); - - if (png_ptr != NULL) - { - /* png_ptr->zstream holds a back-pointer to the png_struct, so - * this can only be done now: - */ - create_struct.zstream.zalloc = png_zalloc; - create_struct.zstream.zfree = png_zfree; - create_struct.zstream.opaque = png_ptr; - -# ifdef PNG_SETJMP_SUPPORTED - /* Eliminate the local error handling: */ - create_struct.jmp_buf_ptr = NULL; - create_struct.jmp_buf_size = 0; - create_struct.longjmp_fn = 0; -# endif - - *png_ptr = create_struct; - - /* This is the successful return point */ - return png_ptr; - } - } - } - - /* A longjmp because of a bug in the application storage allocator or a - * simple failure to allocate the png_struct. - */ - return NULL; -} - -/* Allocate the memory for an info_struct for the application. */ -PNG_FUNCTION(png_infop,PNGAPI -png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) -{ - png_inforp info_ptr; - - png_debug(1, "in png_create_info_struct"); - - if (png_ptr == NULL) - return NULL; - - /* Use the internal API that does not (or at least should not) error out, so - * that this call always returns ok. The application typically sets up the - * error handling *after* creating the info_struct because this is the way it - * has always been done in 'example.c'. - */ - info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, - (sizeof *info_ptr))); - - if (info_ptr != NULL) - memset(info_ptr, 0, (sizeof *info_ptr)); - - return info_ptr; -} - -/* This function frees the memory associated with a single info struct. - * Normally, one would use either png_destroy_read_struct() or - * png_destroy_write_struct() to free an info struct, but this may be - * useful for some applications. From libpng 1.6.0 this function is also used - * internally to implement the png_info release part of the 'struct' destroy - * APIs. This ensures that all possible approaches free the same data (all of - * it). - */ -void PNGAPI -png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) -{ - png_inforp info_ptr = NULL; - - png_debug(1, "in png_destroy_info_struct"); - - if (png_ptr == NULL) - return; - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (info_ptr != NULL) - { - /* Do this first in case of an error below; if the app implements its own - * memory management this can lead to png_free calling png_error, which - * will abort this routine and return control to the app error handler. - * An infinite loop may result if it then tries to free the same info - * ptr. - */ - *info_ptr_ptr = NULL; - - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - memset(info_ptr, 0, (sizeof *info_ptr)); - png_free(png_ptr, info_ptr); - } -} - -/* Initialize the info structure. This is now an internal function (0.89) - * and applications using it are urged to use png_create_info_struct() - * instead. Use deprecated in 1.6.0, internal use removed (used internally it - * is just a memset). - * - * NOTE: it is almost inconceivable that this API is used because it bypasses - * the user-memory mechanism and the user error handling/warning mechanisms in - * those cases where it does anything other than a memset. - */ -PNG_FUNCTION(void,PNGAPI -png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), - PNG_DEPRECATED) -{ - png_inforp info_ptr = *ptr_ptr; - - png_debug(1, "in png_info_init_3"); - - if (info_ptr == NULL) - return; - - if ((sizeof (png_info)) > png_info_struct_size) - { - *ptr_ptr = NULL; - /* The following line is why this API should not be used: */ - free(info_ptr); - info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, - (sizeof *info_ptr))); - if (info_ptr == NULL) - return; - *ptr_ptr = info_ptr; - } - - /* Set everything to 0 */ - memset(info_ptr, 0, (sizeof *info_ptr)); -} - -void PNGAPI -png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, - int freer, png_uint_32 mask) -{ - png_debug(1, "in png_data_freer"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (freer == PNG_DESTROY_WILL_FREE_DATA) - info_ptr->free_me |= mask; - - else if (freer == PNG_USER_WILL_FREE_DATA) - info_ptr->free_me &= ~mask; - - else - png_error(png_ptr, "Unknown freer parameter in png_data_freer"); -} - -void PNGAPI -png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, - int num) -{ - png_debug(1, "in png_free_data"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -#ifdef PNG_TEXT_SUPPORTED - /* Free text item num or (if num == -1) all text items */ - if (info_ptr->text != NULL && - ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->text[num].key); - info_ptr->text[num].key = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->num_text; i++) - png_free(png_ptr, info_ptr->text[i].key); - - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; - info_ptr->num_text = 0; - info_ptr->max_text = 0; - } - } -#endif - -#ifdef PNG_tRNS_SUPPORTED - /* Free any tRNS entry */ - if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0) - { - info_ptr->valid &= ~PNG_INFO_tRNS; - png_free(png_ptr, info_ptr->trans_alpha); - info_ptr->trans_alpha = NULL; - info_ptr->num_trans = 0; - } -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* Free any sCAL entry */ - if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->scal_s_width); - png_free(png_ptr, info_ptr->scal_s_height); - info_ptr->scal_s_width = NULL; - info_ptr->scal_s_height = NULL; - info_ptr->valid &= ~PNG_INFO_sCAL; - } -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* Free any pCAL entry */ - if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - info_ptr->pcal_purpose = NULL; - info_ptr->pcal_units = NULL; - - if (info_ptr->pcal_params != NULL) - { - int i; - - for (i = 0; i < info_ptr->pcal_nparams; i++) - png_free(png_ptr, info_ptr->pcal_params[i]); - - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } - info_ptr->valid &= ~PNG_INFO_pCAL; - } -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* Free any profile entry */ - if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->iccp_name); - png_free(png_ptr, info_ptr->iccp_profile); - info_ptr->iccp_name = NULL; - info_ptr->iccp_profile = NULL; - info_ptr->valid &= ~PNG_INFO_iCCP; - } -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ - if (info_ptr->splt_palettes != NULL && - ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->splt_palettes[num].name); - png_free(png_ptr, info_ptr->splt_palettes[num].entries); - info_ptr->splt_palettes[num].name = NULL; - info_ptr->splt_palettes[num].entries = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->splt_palettes_num; i++) - { - png_free(png_ptr, info_ptr->splt_palettes[i].name); - png_free(png_ptr, info_ptr->splt_palettes[i].entries); - } - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = NULL; - info_ptr->splt_palettes_num = 0; - info_ptr->valid &= ~PNG_INFO_sPLT; - } - } -#endif - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks != NULL && - ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->unknown_chunks[num].data); - info_ptr->unknown_chunks[num].data = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->unknown_chunks_num; i++) - png_free(png_ptr, info_ptr->unknown_chunks[i].data); - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; - info_ptr->unknown_chunks_num = 0; - } - } -#endif - -#ifdef PNG_eXIf_SUPPORTED - /* Free any eXIf entry */ - if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0) - { -# ifdef PNG_READ_eXIf_SUPPORTED - if (info_ptr->eXIf_buf) - { - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - } -# endif - if (info_ptr->exif) - { - png_free(png_ptr, info_ptr->exif); - info_ptr->exif = NULL; - } - info_ptr->valid &= ~PNG_INFO_eXIf; - } -#endif - -#ifdef PNG_hIST_SUPPORTED - /* Free any hIST entry */ - if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->hist); - info_ptr->hist = NULL; - info_ptr->valid &= ~PNG_INFO_hIST; - } -#endif - - /* Free any PLTE entry that was internally allocated */ - if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->palette); - info_ptr->palette = NULL; - info_ptr->valid &= ~PNG_INFO_PLTE; - info_ptr->num_palette = 0; - } - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Free any image bits attached to the info structure */ - if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) - { - if (info_ptr->row_pointers != NULL) - { - png_uint_32 row; - for (row = 0; row < info_ptr->height; row++) - png_free(png_ptr, info_ptr->row_pointers[row]); - - png_free(png_ptr, info_ptr->row_pointers); - info_ptr->row_pointers = NULL; - } - info_ptr->valid &= ~PNG_INFO_IDAT; - } -#endif - - if (num != -1) - mask &= ~PNG_FREE_MUL; - - info_ptr->free_me &= ~mask; -} -#endif /* READ || WRITE */ - -/* This function returns a pointer to the io_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy() or png_read_destroy() are called. - */ -png_voidp PNGAPI -png_get_io_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return png_ptr->io_ptr; -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -# ifdef PNG_STDIO_SUPPORTED -/* Initialize the default input/output functions for the PNG file. If you - * use your own read or write routines, you can call either png_set_read_fn() - * or png_set_write_fn() instead of png_init_io(). If you have defined - * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a - * function of your own because "FILE *" isn't necessarily available. - */ -void PNGAPI -png_init_io(png_structrp png_ptr, png_FILE_p fp) -{ - png_debug(1, "in png_init_io"); - - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = (png_voidp)fp; -} -# endif - -# ifdef PNG_SAVE_INT_32_SUPPORTED -/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 - * defines a cast of a signed integer to an unsigned integer either to preserve - * the value, if it is positive, or to calculate: - * - * (UNSIGNED_MAX+1) + integer - * - * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the - * negative integral value is added the result will be an unsigned value - * corresponding to the 2's complement representation. - */ -void PNGAPI -png_save_int_32(png_bytep buf, png_int_32 i) -{ - png_save_uint_32(buf, (png_uint_32)i); -} -# endif - -# ifdef PNG_TIME_RFC1123_SUPPORTED -/* Convert the supplied time into an RFC 1123 string suitable for use in - * a "Creation Time" or other text-based time string. - */ -int PNGAPI -png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) -{ - static const char short_months[12][4] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - if (out == NULL) - return 0; - - if (ptime->year > 9999 /* RFC1123 limitation */ || - ptime->month == 0 || ptime->month > 12 || - ptime->day == 0 || ptime->day > 31 || - ptime->hour > 23 || ptime->minute > 59 || - ptime->second > 60) - return 0; - - { - size_t pos = 0; - char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */ - -# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) -# define APPEND_NUMBER(format, value)\ - APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) -# define APPEND(ch) if (pos < 28) out[pos++] = (ch) - - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); - APPEND(' '); - APPEND_STRING(short_months[(ptime->month - 1)]); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); - APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ - PNG_UNUSED (pos) - -# undef APPEND -# undef APPEND_NUMBER -# undef APPEND_STRING - } - - return 1; -} - -# if PNG_LIBPNG_VER < 10700 -/* To do: remove the following from libpng-1.7 */ -/* Original API that uses a private buffer in png_struct. - * Deprecated because it causes png_struct to carry a spurious temporary - * buffer (png_struct::time_buffer), better to have the caller pass this in. - */ -png_const_charp PNGAPI -png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) -{ - if (png_ptr != NULL) - { - /* The only failure above if png_ptr != NULL is from an invalid ptime */ - if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0) - png_warning(png_ptr, "Ignoring invalid time value"); - - else - return png_ptr->time_buffer; - } - - return NULL; -} -# endif /* LIBPNG_VER < 10700 */ -# endif /* TIME_RFC1123 */ - -#endif /* READ || WRITE */ - -png_const_charp PNGAPI -png_get_copyright(png_const_structrp png_ptr) -{ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef PNG_STRING_COPYRIGHT - return PNG_STRING_COPYRIGHT -#else - return PNG_STRING_NEWLINE \ - "libpng version 1.6.44" PNG_STRING_NEWLINE \ - "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ - PNG_STRING_NEWLINE \ - "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ - "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE; -#endif -} - -/* The following return the library version as a short string in the - * format 1.0.0 through 99.99.99zz. To get the version of *.h files - * used with your application, print out PNG_LIBPNG_VER_STRING, which - * is defined in png.h. - * Note: now there is no difference between png_get_libpng_ver() and - * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, - * it is guaranteed that png.c uses the correct version of png.h. - */ -png_const_charp PNGAPI -png_get_libpng_ver(png_const_structrp png_ptr) -{ - /* Version of *.c files used when building libpng */ - return png_get_header_ver(png_ptr); -} - -png_const_charp PNGAPI -png_get_header_ver(png_const_structrp png_ptr) -{ - /* Version of *.h files used when building libpng */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ - return PNG_LIBPNG_VER_STRING; -} - -png_const_charp PNGAPI -png_get_header_version(png_const_structrp png_ptr) -{ - /* Returns longer string containing both version and date */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef __STDC__ - return PNG_HEADER_VERSION_STRING -# ifndef PNG_READ_SUPPORTED - " (NO READ SUPPORT)" -# endif - PNG_STRING_NEWLINE; -#else - return PNG_HEADER_VERSION_STRING; -#endif -} - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -/* NOTE: this routine is not used internally! */ -/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth - * large of png_color. This lets grayscale images be treated as - * paletted. Most useful for gamma correction and simplification - * of code. This API is not used internally. - */ -void PNGAPI -png_build_grayscale_palette(int bit_depth, png_colorp palette) -{ - int num_palette; - int color_inc; - int i; - int v; - - png_debug(1, "in png_do_build_grayscale_palette"); - - if (palette == NULL) - return; - - switch (bit_depth) - { - case 1: - num_palette = 2; - color_inc = 0xff; - break; - - case 2: - num_palette = 4; - color_inc = 0x55; - break; - - case 4: - num_palette = 16; - color_inc = 0x11; - break; - - case 8: - num_palette = 256; - color_inc = 1; - break; - - default: - num_palette = 0; - color_inc = 0; - break; - } - - for (i = 0, v = 0; i < num_palette; i++, v += color_inc) - { - palette[i].red = (png_byte)(v & 0xff); - palette[i].green = (png_byte)(v & 0xff); - palette[i].blue = (png_byte)(v & 0xff); - } -} -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) -{ - /* Check chunk_name and return "keep" value if it's on the list, else 0 */ - png_const_bytep p, p_end; - - if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) - return PNG_HANDLE_CHUNK_AS_DEFAULT; - - p_end = png_ptr->chunk_list; - p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ - - /* The code is the fifth byte after each four byte string. Historically this - * code was always searched from the end of the list, this is no longer - * necessary because the 'set' routine handles duplicate entries correctly. - */ - do /* num_chunk_list > 0, so at least one */ - { - p -= 5; - - if (memcmp(chunk_name, p, 4) == 0) - return p[4]; - } - while (p > p_end); - - /* This means that known chunks should be processed and unknown chunks should - * be handled according to the value of png_ptr->unknown_default; this can be - * confusing because, as a result, there are two levels of defaulting for - * unknown chunks. - */ - return PNG_HANDLE_CHUNK_AS_DEFAULT; -} - -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -int /* PRIVATE */ -png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) -{ - png_byte chunk_string[5]; - - PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); - return png_handle_as_unknown(png_ptr, chunk_string); -} -#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ -#endif /* SET_UNKNOWN_CHUNKS */ - -#ifdef PNG_READ_SUPPORTED -/* This function, added to libpng-1.0.6g, is untested. */ -int PNGAPI -png_reset_zstream(png_structrp png_ptr) -{ - if (png_ptr == NULL) - return Z_STREAM_ERROR; - - /* WARNING: this resets the window bits to the maximum! */ - return inflateReset(&png_ptr->zstream); -} -#endif /* READ */ - -/* This function was added to libpng-1.0.7 */ -png_uint_32 PNGAPI -png_access_version_number(void) -{ - /* Version of *.c files used when building libpng */ - return (png_uint_32)PNG_LIBPNG_VER; -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. - * If it doesn't 'ret' is used to set it to something appropriate, even in cases - * like Z_OK or Z_STREAM_END where the error code is apparently a success code. - */ -void /* PRIVATE */ -png_zstream_error(png_structrp png_ptr, int ret) -{ - /* Translate 'ret' into an appropriate error string, priority is given to the - * one in zstream if set. This always returns a string, even in cases like - * Z_OK or Z_STREAM_END where the error code is a success code. - */ - if (png_ptr->zstream.msg == NULL) switch (ret) - { - default: - case Z_OK: - png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); - break; - - case Z_STREAM_END: - /* Normal exit */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); - break; - - case Z_NEED_DICT: - /* This means the deflate stream did not have a dictionary; this - * indicates a bogus PNG. - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); - break; - - case Z_ERRNO: - /* gz APIs only: should not happen */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); - break; - - case Z_STREAM_ERROR: - /* internal libpng error */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); - break; - - case Z_DATA_ERROR: - png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); - break; - - case Z_MEM_ERROR: - png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); - break; - - case Z_BUF_ERROR: - /* End of input or output; not a problem if the caller is doing - * incremental read or write. - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); - break; - - case Z_VERSION_ERROR: - png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); - break; - - case PNG_UNEXPECTED_ZLIB_RETURN: - /* Compile errors here mean that zlib now uses the value co-opted in - * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above - * and change pngpriv.h. Note that this message is "... return", - * whereas the default/Z_OK one is "... return code". - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); - break; - } -} - -/* png_convert_size: a PNGAPI but no longer in png.h, so deleted - * at libpng 1.5.5! - */ - -/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ -static int -png_colorspace_check_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA, int from) - /* This is called to check a new gamma value against an existing one. The - * routine returns false if the new gamma value should not be written. - * - * 'from' says where the new gamma value comes from: - * - * 0: the new gamma value is the libpng estimate for an ICC profile - * 1: the new gamma value comes from a gAMA chunk - * 2: the new gamma value comes from an sRGB chunk - */ -{ - png_fixed_point gtest; - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || - png_gamma_significant(gtest) != 0)) - { - /* Either this is an sRGB image, in which case the calculated gamma - * approximation should match, or this is an image with a profile and the - * value libpng calculates for the gamma of the profile does not match the - * value recorded in the file. The former, sRGB, case is an error, the - * latter is just a warning. - */ - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) - { - png_chunk_report(png_ptr, "gamma value does not match sRGB", - PNG_CHUNK_ERROR); - /* Do not overwrite an sRGB value */ - return from == 2; - } - - else /* sRGB tag not involved */ - { - png_chunk_report(png_ptr, "gamma value does not match libpng estimate", - PNG_CHUNK_WARNING); - return from == 1; - } - } - - return 1; -} - -void /* PRIVATE */ -png_colorspace_set_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA) -{ - /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is asymmetrical it is - * possible for 1/gamma to overflow the limit of 21474 and this means the - * gamma value must be at least 5/100000 and hence at most 20000.0. For - * safety the limits here are a little narrower. The values are 0.00016 to - * 6250.0, which are truly ridiculous gamma values (and will produce - * displays that are all black or all white.) - * - * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk - * handling code, which only required the value to be >0. - */ - png_const_charp errmsg; - - if (gAMA < 16 || gAMA > 625000000) - errmsg = "gamma value out of range"; - -# ifdef PNG_READ_gAMA_SUPPORTED - /* Allow the application to set the gamma value more than once */ - else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) - errmsg = "duplicate"; -# endif - - /* Do nothing if the colorspace is already invalid */ - else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return; - - else - { - if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, - 1/*from gAMA*/) != 0) - { - /* Store this gamma value. */ - colorspace->gamma = gAMA; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); - } - - /* At present if the check_gamma test fails the gamma of the colorspace is - * not updated however the colorspace is not invalidated. This - * corresponds to the case where the existing gamma comes from an sRGB - * chunk or profile. An error message has already been output. - */ - return; - } - - /* Error exit - errmsg has been set. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); -} - -void /* PRIVATE */ -png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - /* Everything is invalid */ - info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| - PNG_INFO_iCCP); - -# ifdef PNG_COLORSPACE_SUPPORTED - /* Clean up the iCCP profile now if it won't be used. */ - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); -# else - PNG_UNUSED(png_ptr) -# endif - } - - else - { -# ifdef PNG_COLORSPACE_SUPPORTED - /* Leave the INFO_iCCP flag set if the pngset.c code has already set - * it; this allows a PNG to contain a profile which matches sRGB and - * yet still have that profile retrievable by the application. - */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) - info_ptr->valid |= PNG_INFO_sRGB; - - else - info_ptr->valid &= ~PNG_INFO_sRGB; - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - info_ptr->valid |= PNG_INFO_cHRM; - - else - info_ptr->valid &= ~PNG_INFO_cHRM; -# endif - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) - info_ptr->valid |= PNG_INFO_gAMA; - - else - info_ptr->valid &= ~PNG_INFO_gAMA; - } -} - -#ifdef PNG_READ_SUPPORTED -void /* PRIVATE */ -png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if (info_ptr == NULL) /* reduce code size; check here not in the caller */ - return; - - info_ptr->colorspace = png_ptr->colorspace; - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif -#endif /* GAMMA */ - -#ifdef PNG_COLORSPACE_SUPPORTED -static int -png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1, - png_int_32 addend2) { - /* Safely add three integers. Returns 0 on success, 1 on overlow. - * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore - * relying on addition of two positive values producing a negative one is not - * safe. - */ - int addend0 = *addend0_and_result; - if (0x7fffffff - addend0 < addend1) - return 1; - addend0 += addend1; - if (0x7fffffff - addend1 < addend2) - return 1; - *addend0_and_result = addend0 + addend2; - return 0; -} - -/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for - * cHRM, as opposed to using chromaticities. These internal APIs return - * non-zero on a parameter error. The X, Y and Z values are required to be - * positive and less than 1.0. - */ -static int -png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) -{ - png_int_32 d, dred, dgreen, dwhite, whiteX, whiteY; - - /* 'd' in each of the blocks below is just X+Y+Z for each component, - * x, y and z are X,Y,Z/(X+Y+Z). - */ - d = XYZ->red_X; - if (png_safe_add(&d, XYZ->red_Y, XYZ->red_Z)) - return 1; - if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) - return 1; - dred = d; - whiteX = XYZ->red_X; - whiteY = XYZ->red_Y; - - d = XYZ->green_X; - if (png_safe_add(&d, XYZ->green_Y, XYZ->green_Z)) - return 1; - if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) - return 1; - dgreen = d; - whiteX += XYZ->green_X; - whiteY += XYZ->green_Y; - - d = XYZ->blue_X; - if (png_safe_add(&d, XYZ->blue_Y, XYZ->blue_Z)) - return 1; - if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) - return 1; - whiteX += XYZ->blue_X; - whiteY += XYZ->blue_Y; - - /* The reference white is simply the sum of the end-point (X,Y,Z) vectors so - * the fillowing calculates (X+Y+Z) of the reference white (media white, - * encoding white) itself: - */ - if (png_safe_add(&d, dred, dgreen)) - return 1; - - dwhite = d; - - if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) - return 1; - if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) - return 1; - - return 0; -} - -static int -png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) -{ - png_fixed_point red_inverse, green_inverse, blue_scale; - png_fixed_point left, right, denominator; - - /* The reverse calculation is more difficult because the original tristimulus - * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 - * derived values were recorded in the cHRM chunk; - * (red,green,blue,white)x(x,y). This loses one degree of freedom and - * therefore an arbitrary ninth value has to be introduced to undo the - * original transformations. - * - * Think of the original end-points as points in (X,Y,Z) space. The - * chromaticity values (c) have the property: - * - * C - * c = --------- - * X + Y + Z - * - * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the - * three chromaticity values (x,y,z) for each end-point obey the - * relationship: - * - * x + y + z = 1 - * - * This describes the plane in (X,Y,Z) space that intersects each axis at the - * value 1.0; call this the chromaticity plane. Thus the chromaticity - * calculation has scaled each end-point so that it is on the x+y+z=1 plane - * and chromaticity is the intersection of the vector from the origin to the - * (X,Y,Z) value with the chromaticity plane. - * - * To fully invert the chromaticity calculation we would need the three - * end-point scale factors, (red-scale, green-scale, blue-scale), but these - * were not recorded. Instead we calculated the reference white (X,Y,Z) and - * recorded the chromaticity of this. The reference white (X,Y,Z) would have - * given all three of the scale factors since: - * - * color-C = color-c * color-scale - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * But cHRM records only white-x and white-y, so we have lost the white scale - * factor: - * - * white-C = white-c*white-scale - * - * To handle this the inverse transformation makes an arbitrary assumption - * about white-scale: - * - * Assume: white-Y = 1.0 - * Hence: white-scale = 1/white-y - * Or: red-Y + green-Y + blue-Y = 1.0 - * - * Notice the last statement of the assumption gives an equation in three of - * the nine values we want to calculate. 8 more equations come from the - * above routine as summarised at the top above (the chromaticity - * calculation): - * - * Given: color-x = color-X / (color-X + color-Y + color-Z) - * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 - * - * This is 9 simultaneous equations in the 9 variables "color-C" and can be - * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix - * determinants, however this is not as bad as it seems because only 28 of - * the total of 90 terms in the various matrices are non-zero. Nevertheless - * Cramer's rule is notoriously numerically unstable because the determinant - * calculation involves the difference of large, but similar, numbers. It is - * difficult to be sure that the calculation is stable for real world values - * and it is certain that it becomes unstable where the end points are close - * together. - * - * So this code uses the perhaps slightly less optimal but more - * understandable and totally obvious approach of calculating color-scale. - * - * This algorithm depends on the precision in white-scale and that is - * (1/white-y), so we can immediately see that as white-y approaches 0 the - * accuracy inherent in the cHRM chunk drops off substantially. - * - * libpng arithmetic: a simple inversion of the above equations - * ------------------------------------------------------------ - * - * white_scale = 1/white-y - * white-X = white-x * white-scale - * white-Y = 1.0 - * white-Z = (1 - white-x - white-y) * white_scale - * - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * This gives us three equations in (red-scale,green-scale,blue-scale) where - * all the coefficients are now known: - * - * red-x*red-scale + green-x*green-scale + blue-x*blue-scale - * = white-x/white-y - * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 - * red-z*red-scale + green-z*green-scale + blue-z*blue-scale - * = (1 - white-x - white-y)/white-y - * - * In the last equation color-z is (1 - color-x - color-y) so we can add all - * three equations together to get an alternative third: - * - * red-scale + green-scale + blue-scale = 1/white-y = white-scale - * - * So now we have a Cramer's rule solution where the determinants are just - * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve - * multiplication of three coefficients so we can't guarantee to avoid - * overflow in the libpng fixed point representation. Using Cramer's rule in - * floating point is probably a good choice here, but it's not an option for - * fixed point. Instead proceed to simplify the first two equations by - * eliminating what is likely to be the largest value, blue-scale: - * - * blue-scale = white-scale - red-scale - green-scale - * - * Hence: - * - * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = - * (white-x - blue-x)*white-scale - * - * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = - * 1 - blue-y*white-scale - * - * And now we can trivially solve for (red-scale,green-scale): - * - * green-scale = - * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale - * ----------------------------------------------------------- - * green-x - blue-x - * - * red-scale = - * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale - * --------------------------------------------------------- - * red-y - blue-y - * - * Hence: - * - * red-scale = - * ( (green-x - blue-x) * (white-y - blue-y) - - * (green-y - blue-y) * (white-x - blue-x) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * green-scale = - * ( (red-y - blue-y) * (white-x - blue-x) - - * (red-x - blue-x) * (white-y - blue-y) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * Accuracy: - * The input values have 5 decimal digits of accuracy. The values are all in - * the range 0 < value < 1, so simple products are in the same range but may - * need up to 10 decimal digits to preserve the original precision and avoid - * underflow. Because we are using a 32-bit signed representation we cannot - * match this; the best is a little over 9 decimal digits, less than 10. - * - * The approach used here is to preserve the maximum precision within the - * signed representation. Because the red-scale calculation above uses the - * difference between two products of values that must be in the range -1..+1 - * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The - * factor is irrelevant in the calculation because it is applied to both - * numerator and denominator. - * - * Note that the values of the differences of the products of the - * chromaticities in the above equations tend to be small, for example for - * the sRGB chromaticities they are: - * - * red numerator: -0.04751 - * green numerator: -0.08788 - * denominator: -0.2241 (without white-y multiplication) - * - * The resultant Y coefficients from the chromaticities of some widely used - * color space definitions are (to 15 decimal places): - * - * sRGB - * 0.212639005871510 0.715168678767756 0.072192315360734 - * Kodak ProPhoto - * 0.288071128229293 0.711843217810102 0.000085653960605 - * Adobe RGB - * 0.297344975250536 0.627363566255466 0.075291458493998 - * Adobe Wide Gamut RGB - * 0.258728243040113 0.724682314948566 0.016589442011321 - */ - /* By the argument, above overflow should be impossible here. The return - * value of 2 indicates an internal error to the caller. - */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) - return 1; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) - return 1; - denominator = left - right; - - /* Now find the red numerator. */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) - return 1; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) - return 1; - - /* Overflow is possible here and it indicates an extreme set of PNG cHRM - * chunk values. This calculation actually returns the reciprocal of the - * scale value because this allows us to delay the multiplication of white-y - * into the denominator, which tends to produce a small number. - */ - if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || - red_inverse <= xy->whitey /* r+g+b scales = white scale */) - return 1; - - /* Similarly for green_inverse: */ - if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) - return 1; - if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) - return 1; - if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || - green_inverse <= xy->whitey) - return 1; - - /* And the blue scale, the checks above guarantee this can't overflow but it - * can still produce 0 for extreme cHRM values. - */ - blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - - png_reciprocal(green_inverse); - if (blue_scale <= 0) - return 1; - - - /* And fill in the png_XYZ: */ - if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, - red_inverse) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, - green_inverse) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, - PNG_FP_1) == 0) - return 1; - - return 0; /*success*/ -} - -static int -png_XYZ_normalize(png_XYZ *XYZ) -{ - png_int_32 Y, Ytemp; - - /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. */ - Ytemp = XYZ->red_Y; - if (png_safe_add(&Ytemp, XYZ->green_Y, XYZ->blue_Y)) - return 1; - - Y = Ytemp; - - if (Y != PNG_FP_1) - { - if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) - return 1; - } - - return 0; -} - -static int -png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) -{ - /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ - if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || - PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || - PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || - PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || - PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || - PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || - PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || - PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) - return 0; - return 1; -} - -/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM - * chunk chromaticities. Earlier checks used to simply look for the overflow - * condition (where the determinant of the matrix to solve for XYZ ends up zero - * because the chromaticity values are not all distinct.) Despite this it is - * theoretically possible to produce chromaticities that are apparently valid - * but that rapidly degrade to invalid, potentially crashing, sets because of - * arithmetic inaccuracies when calculations are performed on them. The new - * check is to round-trip xy -> XYZ -> xy and then check that the result is - * within a small percentage of the original. - */ -static int -png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) -{ - int result; - png_xy xy_test; - - /* As a side-effect this routine also returns the XYZ endpoints. */ - result = png_XYZ_from_xy(XYZ, xy); - if (result != 0) - return result; - - result = png_xy_from_XYZ(&xy_test, XYZ); - if (result != 0) - return result; - - if (png_colorspace_endpoints_match(xy, &xy_test, - 5/*actually, the math is pretty accurate*/) != 0) - return 0; - - /* Too much slip */ - return 1; -} - -/* This is the check going the other way. The XYZ is modified to normalize it - * (another side-effect) and the xy chromaticities are returned. - */ -static int -png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) -{ - int result; - png_XYZ XYZtemp; - - result = png_XYZ_normalize(XYZ); - if (result != 0) - return result; - - result = png_xy_from_XYZ(xy, XYZ); - if (result != 0) - return result; - - XYZtemp = *XYZ; - return png_colorspace_check_xy(&XYZtemp, xy); -} - -/* Used to check for an endpoint match against sRGB */ -static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ -{ - /* color x y */ - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000, - /* white */ 31270, 32900 -}; - -static int -png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, - int preferred) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* The consistency check is performed on the chromaticities; this factors out - * variations because of the normalization (or not) of the end point Y - * values. - */ - if (preferred < 2 && - (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* The end points must be reasonably close to any we already have. The - * following allows an error of up to +/-.001 - */ - if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, - 100) == 0) - { - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "inconsistent chromaticities"); - return 0; /* failed */ - } - - /* Only overwrite with preferred values */ - if (preferred == 0) - return 1; /* ok, but no change */ - } - - colorspace->end_points_xy = *xy; - colorspace->end_points_XYZ = *XYZ; - colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; - - /* The end points are normally quoted to two decimal digits, so allow +/-0.01 - * on this test. - */ - if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) - colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; - - else - colorspace->flags &= PNG_COLORSPACE_CANCEL( - PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - return 2; /* ok and changed */ -} - -int /* PRIVATE */ -png_colorspace_set_chromaticities(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, int preferred) -{ - /* We must check the end points to ensure they are reasonable - in the past - * color management systems have crashed as a result of getting bogus - * colorant values, while this isn't the fault of libpng it is the - * responsibility of libpng because PNG carries the bomb and libpng is in a - * position to protect against it. - */ - png_XYZ XYZ; - - switch (png_colorspace_check_xy(&XYZ, xy)) - { - case 0: /* success */ - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, - preferred); - - case 1: - /* We can't invert the chromaticities so we can't produce value XYZ - * values. Likely as not a color management system will fail too. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid chromaticities"); - break; - - default: - /* libpng is broken; this should be a warning but if it happens we - * want error reports so for the moment it is an error. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_error(png_ptr, "internal error checking chromaticities"); - } - - return 0; /* failed */ -} - -int /* PRIVATE */ -png_colorspace_set_endpoints(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) -{ - png_XYZ XYZ = *XYZ_in; - png_xy xy; - - switch (png_colorspace_check_XYZ(&xy, &XYZ)) - { - case 0: - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, - preferred); - - case 1: - /* End points are invalid. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid end points"); - break; - - default: - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_error(png_ptr, "internal error checking chromaticities"); - } - - return 0; /* failed */ -} - -#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) -/* Error message generation */ -static char -png_icc_tag_char(png_uint_32 byte) -{ - byte &= 0xff; - if (byte >= 32 && byte <= 126) - return (char)byte; - else - return '?'; -} - -static void -png_icc_tag_name(char *name, png_uint_32 tag) -{ - name[0] = '\''; - name[1] = png_icc_tag_char(tag >> 24); - name[2] = png_icc_tag_char(tag >> 16); - name[3] = png_icc_tag_char(tag >> 8); - name[4] = png_icc_tag_char(tag ); - name[5] = '\''; -} - -static int -is_ICC_signature_char(png_alloc_size_t it) -{ - return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || - (it >= 97 && it <= 122); -} - -static int -is_ICC_signature(png_alloc_size_t it) -{ - return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && - is_ICC_signature_char((it >> 16) & 0xff) && - is_ICC_signature_char((it >> 8) & 0xff) && - is_ICC_signature_char(it & 0xff); -} - -static int -png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_alloc_size_t value, png_const_charp reason) -{ - size_t pos; - char message[196]; /* see below for calculation */ - - if (colorspace != NULL) - colorspace->flags |= PNG_COLORSPACE_INVALID; - - pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ - pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ - pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ - if (is_ICC_signature(value) != 0) - { - /* So 'value' is at most 4 bytes and the following cast is safe */ - png_icc_tag_name(message+pos, (png_uint_32)value); - pos += 6; /* total +8; less than the else clause */ - message[pos++] = ':'; - message[pos++] = ' '; - } -# ifdef PNG_WARNINGS_SUPPORTED - else - { - char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ - - pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); - pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ - } -# endif - /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ - pos = png_safecat(message, (sizeof message), pos, reason); - PNG_UNUSED(pos) - - /* This is recoverable, but make it unconditionally an app_error on write to - * avoid writing invalid ICC profiles into PNG files (i.e., we handle them - * on read, with a warning, but on write unless the app turns off - * application errors the PNG won't be written.) - */ - png_chunk_report(png_ptr, message, - (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); - - return 0; -} -#endif /* sRGB || iCCP */ - -#ifdef PNG_sRGB_SUPPORTED -int /* PRIVATE */ -png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, - int intent) -{ - /* sRGB sets known gamma, end points and (from the chunk) intent. */ - /* IMPORTANT: these are not necessarily the values found in an ICC profile - * because ICC profiles store values adapted to a D50 environment; it is - * expected that the ICC profile mediaWhitePointTag will be D50; see the - * checks and code elsewhere to understand this better. - * - * These XYZ values, which are accurate to 5dp, produce rgb to gray - * coefficients of (6968,23435,2366), which are reduced (because they add up - * to 32769 not 32768) to (6968,23434,2366). These are the values that - * libpng has traditionally used (and are the best values given the 15bit - * algorithm used by the rgb to gray code.) - */ - static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ - { - /* color X Y Z */ - /* red */ 41239, 21264, 1933, - /* green */ 35758, 71517, 11919, - /* blue */ 18048, 7219, 95053 - }; - - /* Do nothing if the colorspace is already invalidated. */ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* Check the intent, then check for existing settings. It is valid for the - * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must - * be consistent with the correct values. If, however, this function is - * called below because an iCCP chunk matches sRGB then it is quite - * conceivable that an older app recorded incorrect gAMA and cHRM because of - * an incorrect calculation based on the values in the profile - this does - * *not* invalidate the profile (though it still produces an error, which can - * be ignored.) - */ - if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (png_alloc_size_t)intent, "invalid sRGB rendering intent"); - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && - colorspace->rendering_intent != intent) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (png_alloc_size_t)intent, "inconsistent rendering intents"); - - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) - { - png_benign_error(png_ptr, "duplicate sRGB information ignored"); - return 0; - } - - /* If the standard sRGB cHRM chunk does not match the one from the PNG file - * warn but overwrite the value with the correct one. - */ - if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && - !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, - 100)) - png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", - PNG_CHUNK_ERROR); - - /* This check is just done for the error reporting - the routine always - * returns true when the 'from' argument corresponds to sRGB (2). - */ - (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, - 2/*from sRGB*/); - - /* intent: bugs in GCC force 'int' to be used as the parameter type. */ - colorspace->rendering_intent = (png_uint_16)intent; - colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; - - /* endpoints */ - colorspace->end_points_xy = sRGB_xy; - colorspace->end_points_XYZ = sRGB_XYZ; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - /* gamma */ - colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; - colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Finally record that we have an sRGB profile */ - colorspace->flags |= - (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); - - return 1; /* set */ -} -#endif /* sRGB */ - -#ifdef PNG_iCCP_SUPPORTED -/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value - * is XYZ(0.9642,1.0,0.8249), which scales to: - * - * (63189.8112, 65536, 54060.6464) - */ -static const png_byte D50_nCIEXYZ[12] = - { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; - -static int /* bool */ -icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) -{ - if (profile_length < 132) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "too short"); - return 1; -} - -#ifdef PNG_READ_iCCP_SUPPORTED -int /* PRIVATE */ -png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) -{ - if (!icc_check_length(png_ptr, colorspace, name, profile_length)) - return 0; - - /* This needs to be here because the 'normal' check is in - * png_decompress_chunk, yet this happens after the attempt to - * png_malloc_base the required data. We only need this on read; on write - * the caller supplies the profile buffer so libpng doesn't allocate it. See - * the call to icc_check_length below (the write case). - */ -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - else if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds application limits"); -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds libpng limits"); -# else /* !SET_USER_LIMITS */ - /* This will get compiled out on all 32-bit and better systems. */ - else if (PNG_SIZE_MAX < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds system limits"); -# endif /* !SET_USER_LIMITS */ - - return 1; -} -#endif /* READ_iCCP */ - -int /* PRIVATE */ -png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile/* first 132 bytes only */, int color_type) -{ - png_uint_32 temp; - - /* Length check; this cannot be ignored in this code because profile_length - * is used later to check the tag table, so even if the profile seems over - * long profile_length from the caller must be correct. The caller can fix - * this up on read or write by just passing in the profile header length. - */ - temp = png_get_uint_32(profile); - if (temp != profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "length does not match profile"); - - temp = (png_uint_32) (*(profile+8)); - if (temp > 3 && (profile_length & 3)) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "invalid length"); - - temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ - if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ - profile_length < 132+12*temp) /* truncated tag table */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "tag count too large"); - - /* The 'intent' must be valid or we can't store it, ICC limits the intent to - * 16 bits. - */ - temp = png_get_uint_32(profile+64); - if (temp >= 0xffff) /* The ICC limit */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid rendering intent"); - - /* This is just a warning because the profile may be valid in future - * versions. - */ - if (temp >= PNG_sRGB_INTENT_LAST) - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "intent outside defined range"); - - /* At this point the tag table can't be checked because it hasn't necessarily - * been loaded; however, various header fields can be checked. These checks - * are for values permitted by the PNG spec in an ICC profile; the PNG spec - * restricts the profiles that can be passed in an iCCP chunk (they must be - * appropriate to processing PNG data!) - */ - - /* Data checks (could be skipped). These checks must be independent of the - * version number; however, the version number doesn't accommodate changes in - * the header fields (just the known tags and the interpretation of the - * data.) - */ - temp = png_get_uint_32(profile+36); /* signature 'ascp' */ - if (temp != 0x61637370) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid signature"); - - /* Currently the PCS illuminant/adopted white point (the computational - * white point) are required to be D50, - * however the profile contains a record of the illuminant so perhaps ICC - * expects to be able to change this in the future (despite the rationale in - * the introduction for using a fixed PCS adopted white.) Consequently the - * following is just a warning. - */ - if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) - (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, - "PCS illuminant is not D50"); - - /* The PNG spec requires this: - * "If the iCCP chunk is present, the image samples conform to the colour - * space represented by the embedded ICC profile as defined by the - * International Color Consortium [ICC]. The colour space of the ICC profile - * shall be an RGB colour space for colour images (PNG colour types 2, 3, and - * 6), or a greyscale colour space for greyscale images (PNG colour types 0 - * and 4)." - * - * This checking code ensures the embedded profile (on either read or write) - * conforms to the specification requirements. Notice that an ICC 'gray' - * color-space profile contains the information to transform the monochrome - * data to XYZ or L*a*b (according to which PCS the profile uses) and this - * should be used in preference to the standard libpng K channel replication - * into R, G and B channels. - * - * Previously it was suggested that an RGB profile on grayscale data could be - * handled. However it it is clear that using an RGB profile in this context - * must be an error - there is no specification of what it means. Thus it is - * almost certainly more correct to ignore the profile. - */ - temp = png_get_uint_32(profile+16); /* data colour space field */ - switch (temp) - { - case 0x52474220: /* 'RGB ' */ - if ((color_type & PNG_COLOR_MASK_COLOR) == 0) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "RGB color space not permitted on grayscale PNG"); - break; - - case 0x47524159: /* 'GRAY' */ - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "Gray color space not permitted on RGB PNG"); - break; - - default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid ICC profile color space"); - } - - /* It is up to the application to check that the profile class matches the - * application requirements; the spec provides no guidance, but it's pretty - * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer - * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these - * cases. Issue an error for device link or abstract profiles - these don't - * contain the records necessary to transform the color-space to anything - * other than the target device (and not even that for an abstract profile). - * Profiles of these classes may not be embedded in images. - */ - temp = png_get_uint_32(profile+12); /* profile/device class */ - switch (temp) - { - case 0x73636e72: /* 'scnr' */ - case 0x6d6e7472: /* 'mntr' */ - case 0x70727472: /* 'prtr' */ - case 0x73706163: /* 'spac' */ - /* All supported */ - break; - - case 0x61627374: /* 'abst' */ - /* May not be embedded in an image */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid embedded Abstract ICC profile"); - - case 0x6c696e6b: /* 'link' */ - /* DeviceLink profiles cannot be interpreted in a non-device specific - * fashion, if an app uses the AToB0Tag in the profile the results are - * undefined unless the result is sent to the intended device, - * therefore a DeviceLink profile should not be found embedded in a - * PNG. - */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected DeviceLink ICC profile class"); - - case 0x6e6d636c: /* 'nmcl' */ - /* A NamedColor profile is also device specific, however it doesn't - * contain an AToB0 tag that is open to misinterpretation. Almost - * certainly it will fail the tests below. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unexpected NamedColor ICC profile class"); - break; - - default: - /* To allow for future enhancements to the profile accept unrecognized - * profile classes with a warning, these then hit the test below on the - * tag content to ensure they are backward compatible with one of the - * understood profiles. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unrecognized ICC profile class"); - break; - } - - /* For any profile other than a device link one the PCS must be encoded - * either in XYZ or Lab. - */ - temp = png_get_uint_32(profile+20); - switch (temp) - { - case 0x58595a20: /* 'XYZ ' */ - case 0x4c616220: /* 'Lab ' */ - break; - - default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected ICC PCS encoding"); - } - - return 1; -} - -int /* PRIVATE */ -png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */) -{ - png_uint_32 tag_count = png_get_uint_32(profile+128); - png_uint_32 itag; - png_const_bytep tag = profile+132; /* The first tag */ - - /* First scan all the tags in the table and add bits to the icc_info value - * (temporarily in 'tags'). - */ - for (itag=0; itag < tag_count; ++itag, tag += 12) - { - png_uint_32 tag_id = png_get_uint_32(tag+0); - png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ - png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ - - /* The ICC specification does not exclude zero length tags, therefore the - * start might actually be anywhere if there is no data, but this would be - * a clear abuse of the intent of the standard so the start is checked for - * being in range. All defined tag types have an 8 byte header - a 4 byte - * type signature then 0. - */ - - /* This is a hard error; potentially it can cause read outside the - * profile. - */ - if (tag_start > profile_length || tag_length > profile_length - tag_start) - return png_icc_profile_error(png_ptr, colorspace, name, tag_id, - "ICC profile tag outside profile"); - - if ((tag_start & 3) != 0) - { - /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is - * only a warning here because libpng does not care about the - * alignment. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, - "ICC profile tag start not a multiple of 4"); - } - } - - return 1; /* success, maybe with warnings */ -} - -#ifdef PNG_sRGB_SUPPORTED -#if PNG_sRGB_PROFILE_CHECKS >= 0 -/* Information about the known ICC sRGB profiles */ -static const struct -{ - png_uint_32 adler, crc, length; - png_uint_32 md5[4]; - png_byte have_md5; - png_byte is_broken; - png_uint_16 intent; - -# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) -# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ - { adler, crc, length, md5, broke, intent }, - -} png_sRGB_checks[] = -{ - /* This data comes from contrib/tools/checksum-icc run on downloads of - * all four ICC sRGB profiles from www.color.org. - */ - /* adler32, crc32, MD5[4], intent, date, length, file-name */ - PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, - PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, - "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") - - /* ICC sRGB v2 perceptual no black-compensation: */ - PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, - PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, - "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") - - PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, - PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, - "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") - - /* ICC sRGB v4 perceptual */ - PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, - PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, - "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") - - /* The following profiles have no known MD5 checksum. If there is a match - * on the (empty) MD5 the other fields are used to attempt a match and - * a warning is produced. The first two of these profiles have a 'cprt' tag - * which suggests that they were also made by Hewlett Packard. - */ - PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, - "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") - - /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not - * match the D50 PCS illuminant in the header (it is in fact the D65 values, - * so the white point is recorded as the un-adapted value.) The profiles - * below only differ in one byte - the intent - and are basically the same as - * the previous profile except for the mediaWhitePointTag error and a missing - * chromaticAdaptationTag. - */ - PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") - - PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") -}; - -static int -png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, - png_const_bytep profile, uLong adler) -{ - /* The quick check is to verify just the MD5 signature and trust the - * rest of the data. Because the profile has already been verified for - * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' - * field too, so if the profile has been edited with an intent not defined - * by sRGB (but maybe defined by a later ICC specification) the read of - * the profile will fail at that point. - */ - - png_uint_32 length = 0; - png_uint_32 intent = 0x10000; /* invalid */ -#if PNG_sRGB_PROFILE_CHECKS > 1 - uLong crc = 0; /* the value for 0 length data */ -#endif - unsigned int i; - -#ifdef PNG_SET_OPTION_SUPPORTED - /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ - if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) == - PNG_OPTION_ON) - return 0; -#endif - - for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) - { - if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && - png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && - png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && - png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) - { - /* This may be one of the old HP profiles without an MD5, in that - * case we can only use the length and Adler32 (note that these - * are not used by default if there is an MD5!) - */ -# if PNG_sRGB_PROFILE_CHECKS == 0 - if (png_sRGB_checks[i].have_md5 != 0) - return 1+png_sRGB_checks[i].is_broken; -# endif - - /* Profile is unsigned or more checks have been configured in. */ - if (length == 0) - { - length = png_get_uint_32(profile); - intent = png_get_uint_32(profile+64); - } - - /* Length *and* intent must match */ - if (length == (png_uint_32) png_sRGB_checks[i].length && - intent == (png_uint_32) png_sRGB_checks[i].intent) - { - /* Now calculate the adler32 if not done already. */ - if (adler == 0) - { - adler = adler32(0, NULL, 0); - adler = adler32(adler, profile, length); - } - - if (adler == png_sRGB_checks[i].adler) - { - /* These basic checks suggest that the data has not been - * modified, but if the check level is more than 1 perform - * our own crc32 checksum on the data. - */ -# if PNG_sRGB_PROFILE_CHECKS > 1 - if (crc == 0) - { - crc = crc32(0, NULL, 0); - crc = crc32(crc, profile, length); - } - - /* So this check must pass for the 'return' below to happen. - */ - if (crc == png_sRGB_checks[i].crc) -# endif - { - if (png_sRGB_checks[i].is_broken != 0) - { - /* These profiles are known to have bad data that may cause - * problems if they are used, therefore attempt to - * discourage their use, skip the 'have_md5' warning below, - * which is made irrelevant by this error. - */ - png_chunk_report(png_ptr, "known incorrect sRGB profile", - PNG_CHUNK_ERROR); - } - - /* Warn that this being done; this isn't even an error since - * the profile is perfectly valid, but it would be nice if - * people used the up-to-date ones. - */ - else if (png_sRGB_checks[i].have_md5 == 0) - { - png_chunk_report(png_ptr, - "out-of-date sRGB profile with no signature", - PNG_CHUNK_WARNING); - } - - return 1+png_sRGB_checks[i].is_broken; - } - } - -# if PNG_sRGB_PROFILE_CHECKS > 0 - /* The signature matched, but the profile had been changed in some - * way. This probably indicates a data error or uninformed hacking. - * Fall through to "no match". - */ - png_chunk_report(png_ptr, - "Not recognizing known sRGB profile that has been edited", - PNG_CHUNK_WARNING); - break; -# endif - } - } - } - - return 0; /* no match */ -} - -void /* PRIVATE */ -png_icc_set_sRGB(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_bytep profile, uLong adler) -{ - /* Is this profile one of the known ICC sRGB profiles? If it is, just set - * the sRGB information. - */ - if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) - (void)png_colorspace_set_sRGB(png_ptr, colorspace, - (int)/*already checked*/png_get_uint_32(profile+64)); -} -#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ -#endif /* sRGB */ - -int /* PRIVATE */ -png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, - int color_type) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && - png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, - color_type) != 0 && - png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, - profile) != 0) - { -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* If no sRGB support, don't try storing sRGB information */ - png_icc_set_sRGB(png_ptr, colorspace, profile, 0); -# endif - return 1; - } - - /* Failure case */ - return 0; -} -#endif /* iCCP */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void /* PRIVATE */ -png_colorspace_set_rgb_coefficients(png_structrp png_ptr) -{ - /* Set the rgb_to_gray coefficients from the colorspace. */ - if (png_ptr->rgb_to_gray_coefficients_set == 0 && - (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* png_set_background has not been called, get the coefficients from the Y - * values of the colorspace colorants. - */ - png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; - png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; - png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; - png_fixed_point total = r+g+b; - - if (total > 0 && - r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && - g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && - b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && - r+g+b <= 32769) - { - /* We allow 0 coefficients here. r+g+b may be 32769 if two or - * all of the coefficients were rounded up. Handle this by - * reducing the *largest* coefficient by 1; this matches the - * approach used for the default coefficients in pngrtran.c - */ - int add = 0; - - if (r+g+b > 32768) - add = -1; - else if (r+g+b < 32768) - add = 1; - - if (add != 0) - { - if (g >= r && g >= b) - g += add; - else if (r >= g && r >= b) - r += add; - else - b += add; - } - - /* Check for an internal error. */ - if (r+g+b != 32768) - png_error(png_ptr, - "internal error handling cHRM coefficients"); - - else - { - png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; - png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; - } - } - - /* This is a png_error at present even though it could be ignored - - * it should never happen, but it is important that if it does, the - * bug is fixed. - */ - else - png_error(png_ptr, "internal error handling cHRM->XYZ"); - } -} -#endif /* READ_RGB_TO_GRAY */ - -#endif /* COLORSPACE */ - -void /* PRIVATE */ -png_check_IHDR(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - int error = 0; - - /* Check for width and height valid values */ - if (width == 0) - { - png_warning(png_ptr, "Image width is zero in IHDR"); - error = 1; - } - - if (width > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image width in IHDR"); - error = 1; - } - - /* The bit mask on the first line below must be at least as big as a - * png_uint_32. "~7U" is not adequate on 16-bit systems because it will - * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the - * type of the result at least as bit (in bits) as the RHS of the > operator - * which also avoids a common warning on 64-bit systems that the comparison - * of (png_uint_32) against the constant value on the RHS will always be - * false. - */ - if (((width + 7) & ~(png_alloc_size_t)7) > - (((PNG_SIZE_MAX - - 48 /* big_row_buf hack */ - - 1) /* filter byte */ - / 8) /* 8-byte RGBA pixels */ - - 1)) /* extra max_pixel_depth pad */ - { - /* The size of the row must be within the limits of this architecture. - * Because the read code can perform arbitrary transformations the - * maximum size is checked here. Because the code in png_read_start_row - * adds extra space "for safety's sake" in several places a conservative - * limit is used here. - * - * NOTE: it would be far better to check the size that is actually used, - * but the effect in the real world is minor and the changes are more - * extensive, therefore much more dangerous and much more difficult to - * write in a way that avoids compiler warnings. - */ - png_warning(png_ptr, "Image width is too large for this architecture"); - error = 1; - } - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (width > png_ptr->user_width_max) -#else - if (width > PNG_USER_WIDTH_MAX) -#endif - { - png_warning(png_ptr, "Image width exceeds user limit in IHDR"); - error = 1; - } - - if (height == 0) - { - png_warning(png_ptr, "Image height is zero in IHDR"); - error = 1; - } - - if (height > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image height in IHDR"); - error = 1; - } - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (height > png_ptr->user_height_max) -#else - if (height > PNG_USER_HEIGHT_MAX) -#endif - { - png_warning(png_ptr, "Image height exceeds user limit in IHDR"); - error = 1; - } - - /* Check other values */ - if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && - bit_depth != 8 && bit_depth != 16) - { - png_warning(png_ptr, "Invalid bit depth in IHDR"); - error = 1; - } - - if (color_type < 0 || color_type == 1 || - color_type == 5 || color_type > 6) - { - png_warning(png_ptr, "Invalid color type in IHDR"); - error = 1; - } - - if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || - ((color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) - { - png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); - error = 1; - } - - if (interlace_type >= PNG_INTERLACE_LAST) - { - png_warning(png_ptr, "Unknown interlace method in IHDR"); - error = 1; - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Unknown compression method in IHDR"); - error = 1; - } - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Accept filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not read a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && - png_ptr->mng_features_permitted != 0) - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - - if (filter_type != PNG_FILTER_TYPE_BASE) - { - if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA))) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } - - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) - { - png_warning(png_ptr, "Invalid filter method in IHDR"); - error = 1; - } - } - -#else - if (filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } -#endif - - if (error == 1) - png_error(png_ptr, "Invalid IHDR data"); -} - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* ASCII to fp functions */ -/* Check an ASCII formatted floating point value, see the more detailed - * comments in pngpriv.h - */ -/* The following is used internally to preserve the sticky flags */ -#define png_fp_add(state, flags) ((state) |= (flags)) -#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) - -int /* PRIVATE */ -png_check_fp_number(png_const_charp string, size_t size, int *statep, - size_t *whereami) -{ - int state = *statep; - size_t i = *whereami; - - while (i < size) - { - int type; - /* First find the type of the next character */ - switch (string[i]) - { - case 43: type = PNG_FP_SAW_SIGN; break; - case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; - case 46: type = PNG_FP_SAW_DOT; break; - case 48: type = PNG_FP_SAW_DIGIT; break; - case 49: case 50: case 51: case 52: - case 53: case 54: case 55: case 56: - case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; - case 69: - case 101: type = PNG_FP_SAW_E; break; - default: goto PNG_FP_End; - } - - /* Now deal with this type according to the current - * state, the type is arranged to not overlap the - * bits of the PNG_FP_STATE. - */ - switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) - { - case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: - if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, type); - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DOT: - /* Ok as trailer, ok as lead of fraction. */ - if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ - goto PNG_FP_End; - - else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ - png_fp_add(state, type); - - else - png_fp_set(state, PNG_FP_FRACTION | type); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: - if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - - png_fp_add(state, type | PNG_FP_WAS_VALID); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_E: - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: - goto PNG_FP_End; ** no sign in fraction */ - - /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: - goto PNG_FP_End; ** Because SAW_DOT is always set */ - - case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: - png_fp_add(state, type | PNG_FP_WAS_VALID); - break; - - case PNG_FP_FRACTION + PNG_FP_SAW_E: - /* This is correct because the trailing '.' on an - * integer is handled above - so we can only get here - * with the sequence ".E" (with no preceding digits). - */ - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: - if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, PNG_FP_SAW_SIGN); - - break; - - /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: - goto PNG_FP_End; */ - - case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: - png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); - - break; - - /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: - goto PNG_FP_End; */ - - default: goto PNG_FP_End; /* I.e. break 2 */ - } - - /* The character seems ok, continue. */ - ++i; - } - -PNG_FP_End: - /* Here at the end, update the state and return the correct - * return code. - */ - *statep = state; - *whereami = i; - - return (state & PNG_FP_SAW_DIGIT) != 0; -} - - -/* The same but for a complete string. */ -int -png_check_fp_string(png_const_charp string, size_t size) -{ - int state=0; - size_t char_index=0; - - if (png_check_fp_number(string, size, &state, &char_index) != 0 && - (char_index == size || string[char_index] == 0)) - return state /* must be non-zero - see above */; - - return 0; /* i.e. fail */ -} -#endif /* pCAL || sCAL */ - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -/* Utility used below - a simple accurate power of ten from an integral - * exponent. - */ -static double -png_pow10(int power) -{ - int recip = 0; - double d = 1; - - /* Handle negative exponent with a reciprocal at the end because - * 10 is exact whereas .1 is inexact in base 2 - */ - if (power < 0) - { - if (power < DBL_MIN_10_EXP) return 0; - recip = 1; power = -power; - } - - if (power > 0) - { - /* Decompose power bitwise. */ - double mult = 10; - do - { - if (power & 1) d *= mult; - mult *= mult; - power >>= 1; - } - while (power > 0); - - if (recip != 0) d = 1/d; - } - /* else power is 0 and d is 1 */ - - return d; -} - -/* Function to format a floating point value in ASCII with a given - * precision. - */ -void /* PRIVATE */ -png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, - double fp, unsigned int precision) -{ - /* We use standard functions from math.h, but not printf because - * that would require stdio. The caller must supply a buffer of - * sufficient size or we will png_error. The tests on size and - * the space in ascii[] consumed are indicated below. - */ - if (precision < 1) - precision = DBL_DIG; - - /* Enforce the limit of the implementation precision too. */ - if (precision > DBL_DIG+1) - precision = DBL_DIG+1; - - /* Basic sanity checks */ - if (size >= precision+5) /* See the requirements below. */ - { - if (fp < 0) - { - fp = -fp; - *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ - --size; - } - - if (fp >= DBL_MIN && fp <= DBL_MAX) - { - int exp_b10; /* A base 10 exponent */ - double base; /* 10^exp_b10 */ - - /* First extract a base 10 exponent of the number, - * the calculation below rounds down when converting - * from base 2 to base 10 (multiply by log10(2) - - * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to - * be increased. Note that the arithmetic shift - * performs a floor() unlike C arithmetic - using a - * C multiply would break the following for negative - * exponents. - */ - (void)frexp(fp, &exp_b10); /* exponent to base 2 */ - - exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ - - /* Avoid underflow here. */ - base = png_pow10(exp_b10); /* May underflow */ - - while (base < DBL_MIN || base < fp) - { - /* And this may overflow. */ - double test = png_pow10(exp_b10+1); - - if (test <= DBL_MAX) - { - ++exp_b10; base = test; - } - - else - break; - } - - /* Normalize fp and correct exp_b10, after this fp is in the - * range [.1,1) and exp_b10 is both the exponent and the digit - * *before* which the decimal point should be inserted - * (starting with 0 for the first digit). Note that this - * works even if 10^exp_b10 is out of range because of the - * test on DBL_MAX above. - */ - fp /= base; - while (fp >= 1) - { - fp /= 10; ++exp_b10; - } - - /* Because of the code above fp may, at this point, be - * less than .1, this is ok because the code below can - * handle the leading zeros this generates, so no attempt - * is made to correct that here. - */ - - { - unsigned int czero, clead, cdigits; - char exponent[10]; - - /* Allow up to two leading zeros - this will not lengthen - * the number compared to using E-n. - */ - if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ - { - czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */ - exp_b10 = 0; /* Dot added below before first output. */ - } - else - czero = 0; /* No zeros to add */ - - /* Generate the digit list, stripping trailing zeros and - * inserting a '.' before a digit if the exponent is 0. - */ - clead = czero; /* Count of leading zeros */ - cdigits = 0; /* Count of digits in list. */ - - do - { - double d; - - fp *= 10; - /* Use modf here, not floor and subtract, so that - * the separation is done in one step. At the end - * of the loop don't break the number into parts so - * that the final digit is rounded. - */ - if (cdigits+czero+1 < precision+clead) - fp = modf(fp, &d); - - else - { - d = floor(fp + .5); - - if (d > 9) - { - /* Rounding up to 10, handle that here. */ - if (czero > 0) - { - --czero; d = 1; - if (cdigits == 0) --clead; - } - else - { - while (cdigits > 0 && d > 9) - { - int ch = *--ascii; - - if (exp_b10 != (-1)) - ++exp_b10; - - else if (ch == 46) - { - ch = *--ascii; ++size; - /* Advance exp_b10 to '1', so that the - * decimal point happens after the - * previous digit. - */ - exp_b10 = 1; - } - - --cdigits; - d = ch - 47; /* I.e. 1+(ch-48) */ - } - - /* Did we reach the beginning? If so adjust the - * exponent but take into account the leading - * decimal point. - */ - if (d > 9) /* cdigits == 0 */ - { - if (exp_b10 == (-1)) - { - /* Leading decimal point (plus zeros?), if - * we lose the decimal point here it must - * be reentered below. - */ - int ch = *--ascii; - - if (ch == 46) - { - ++size; exp_b10 = 1; - } - - /* Else lost a leading zero, so 'exp_b10' is - * still ok at (-1) - */ - } - else - ++exp_b10; - - /* In all cases we output a '1' */ - d = 1; - } - } - } - fp = 0; /* Guarantees termination below. */ - } - - if (d == 0) - { - ++czero; - if (cdigits == 0) ++clead; - } - else - { - /* Included embedded zeros in the digit count. */ - cdigits += czero - clead; - clead = 0; - - while (czero > 0) - { - /* exp_b10 == (-1) means we just output the decimal - * place - after the DP don't adjust 'exp_b10' any - * more! - */ - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) - { - *ascii++ = 46; --size; - } - /* PLUS 1: TOTAL 4 */ - --exp_b10; - } - *ascii++ = 48; --czero; - } - - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) - { - *ascii++ = 46; --size; /* counted above */ - } - - --exp_b10; - } - *ascii++ = (char)(48 + (int)d); ++cdigits; - } - } - while (cdigits+czero < precision+clead && fp > DBL_MIN); - - /* The total output count (max) is now 4+precision */ - - /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At this - * point, exp_b10==(-1) is effectively a flag: it got - * to '-1' because of the decrement, after outputting - * the decimal point above. (The exponent required is - * *not* -1.) - */ - if (exp_b10 >= (-1) && exp_b10 <= 2) - { - /* The following only happens if we didn't output the - * leading zeros above for negative exponent, so this - * doesn't add to the digit requirement. Note that the - * two zeros here can only be output if the two leading - * zeros were *not* output, so this doesn't increase - * the output count. - */ - while (exp_b10-- > 0) *ascii++ = 48; - - *ascii = 0; - - /* Total buffer requirement (including the '\0') is - * 5+precision - see check at the start. - */ - return; - } - - /* Here if an exponent is required, adjust size for - * the digits we output but did not count. The total - * digit output here so far is at most 1+precision - no - * decimal point and no leading or trailing zeros have - * been output. - */ - size -= cdigits; - - *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */ - - /* The following use of an unsigned temporary avoids ambiguities in - * the signed arithmetic on exp_b10 and permits GCC at least to do - * better optimization. - */ - { - unsigned int uexp_b10; - - if (exp_b10 < 0) - { - *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */ - uexp_b10 = 0U-exp_b10; - } - - else - uexp_b10 = 0U+exp_b10; - - cdigits = 0; - - while (uexp_b10 > 0) - { - exponent[cdigits++] = (char)(48 + uexp_b10 % 10); - uexp_b10 /= 10; - } - } - - /* Need another size check here for the exponent digits, so - * this need not be considered above. - */ - if (size > cdigits) - { - while (cdigits > 0) *ascii++ = exponent[--cdigits]; - - *ascii = 0; - - return; - } - } - } - else if (!(fp >= DBL_MIN)) - { - *ascii++ = 48; /* '0' */ - *ascii = 0; - return; - } - else - { - *ascii++ = 105; /* 'i' */ - *ascii++ = 110; /* 'n' */ - *ascii++ = 102; /* 'f' */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} -# endif /* FLOATING_POINT */ - -# ifdef PNG_FIXED_POINT_SUPPORTED -/* Function to format a fixed point value in ASCII. - */ -void /* PRIVATE */ -png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, - size_t size, png_fixed_point fp) -{ - /* Require space for 10 decimal digits, a decimal point, a minus sign and a - * trailing \0, 13 characters: - */ - if (size > 12) - { - png_uint_32 num; - - /* Avoid overflow here on the minimum integer. */ - if (fp < 0) - { - *ascii++ = 45; num = (png_uint_32)(-fp); - } - else - num = (png_uint_32)fp; - - if (num <= 0x80000000) /* else overflowed */ - { - unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10] = {0}; - - while (num) - { - /* Split the low digit off num: */ - unsigned int tmp = num/10; - num -= tmp*10; - digits[ndigits++] = (char)(48 + num); - /* Record the first non-zero digit, note that this is a number - * starting at 1, it's not actually the array index. - */ - if (first == 16 && num > 0) - first = ndigits; - num = tmp; - } - - if (ndigits > 0) - { - while (ndigits > 5) *ascii++ = digits[--ndigits]; - /* The remaining digits are fractional digits, ndigits is '5' or - * smaller at this point. It is certainly not zero. Check for a - * non-zero fractional digit: - */ - if (first <= 5) - { - unsigned int i; - *ascii++ = 46; /* decimal point */ - /* ndigits may be <5 for small numbers, output leading zeros - * then ndigits digits to first: - */ - i = 5; - while (ndigits < i) - { - *ascii++ = 48; --i; - } - while (ndigits >= first) *ascii++ = digits[--ndigits]; - /* Don't output the trailing zeros! */ - } - } - else - *ascii++ = 48; - - /* And null terminate the string: */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} -# endif /* FIXED_POINT */ -#endif /* SCAL */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_sCAL_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) -png_fixed_point -png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) -{ - double r = floor(100000 * fp + .5); - - if (r > 2147483647. || r < -2147483648.) - png_fixed_error(png_ptr, text); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(text) -# endif - - return (png_fixed_point)r; -} -#endif - -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* muldiv functions */ -/* This API takes signed arguments and rounds the result to the nearest - * integer (or, for a fixed point number - the standard argument - to - * the nearest .00001). Overflow and divide by zero are signalled in - * the result, a boolean - true on success, false on overflow. - */ -int -png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - /* Return a * times / divisor, rounded. */ - if (divisor != 0) - { - if (a == 0 || times == 0) - { - *res = 0; - return 1; - } - else - { -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a; - r *= times; - r /= divisor; - r = floor(r+.5); - - /* A png_fixed_point is a 32-bit integer. */ - if (r <= 2147483647. && r >= -2147483648.) - { - *res = (png_fixed_point)r; - return 1; - } -#else - int negative = 0; - png_uint_32 A, T, D; - png_uint_32 s16, s32, s00; - - if (a < 0) - negative = 1, A = -a; - else - A = a; - - if (times < 0) - negative = !negative, T = -times; - else - T = times; - - if (divisor < 0) - negative = !negative, D = -divisor; - else - D = divisor; - - /* Following can't overflow because the arguments only - * have 31 bits each, however the result may be 32 bits. - */ - s16 = (A >> 16) * (T & 0xffff) + - (A & 0xffff) * (T >> 16); - /* Can't overflow because the a*times bit is only 30 - * bits at most. - */ - s32 = (A >> 16) * (T >> 16) + (s16 >> 16); - s00 = (A & 0xffff) * (T & 0xffff); - - s16 = (s16 & 0xffff) << 16; - s00 += s16; - - if (s00 < s16) - ++s32; /* carry */ - - if (s32 < D) /* else overflow */ - { - /* s32.s00 is now the 64-bit product, do a standard - * division, we know that s32 < D, so the maximum - * required shift is 31. - */ - int bitshift = 32; - png_fixed_point result = 0; /* NOTE: signed */ - - while (--bitshift >= 0) - { - png_uint_32 d32, d00; - - if (bitshift > 0) - d32 = D >> (32-bitshift), d00 = D << bitshift; - - else - d32 = 0, d00 = D; - - if (s32 > d32) - { - if (s00 < d00) --s32; /* carry */ - s32 -= d32, s00 -= d00, result += 1<= d00) - s32 = 0, s00 -= d00, result += 1<= (D >> 1)) - ++result; - - if (negative != 0) - result = -result; - - /* Check for overflow. */ - if ((negative != 0 && result <= 0) || - (negative == 0 && result >= 0)) - { - *res = result; - return 1; - } - } -#endif - } - } - - return 0; -} -#endif /* READ_GAMMA || INCH_CONVERSIONS */ - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* The following is for when the caller doesn't much care about the - * result. - */ -png_fixed_point -png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - png_fixed_point result; - - if (png_muldiv(&result, a, times, divisor) != 0) - return result; - - png_warning(png_ptr, "fixed point overflow ignored"); - return 0; -} -#endif - -#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ -/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ -png_fixed_point -png_reciprocal(png_fixed_point a) -{ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(1E10/a+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, 100000, 100000, a) != 0) - return res; -#endif - - return 0; /* error/overflow */ -} - -/* This is the shared test on whether a gamma value is 'significant' - whether - * it is worth doing gamma correction. - */ -int /* PRIVATE */ -png_gamma_significant(png_fixed_point gamma_val) -{ - return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || - gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; -} -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -#ifdef PNG_16BIT_SUPPORTED -/* A local convenience routine. */ -static png_fixed_point -png_product2(png_fixed_point a, png_fixed_point b) -{ - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a * 1E-5; - r *= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, a, b, 100000) != 0) - return res; -#endif - - return 0; /* overflow */ -} -#endif /* 16BIT */ - -/* The inverse of the above. */ -png_fixed_point -png_reciprocal2(png_fixed_point a, png_fixed_point b) -{ - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - if (a != 0 && b != 0) - { - double r = 1E15/a; - r /= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; - } -#else - /* This may overflow because the range of png_fixed_point isn't symmetric, - * but this API is only used for the product of file and screen gamma so it - * doesn't matter that the smallest number it can produce is 1/21474, not - * 1/100000 - */ - png_fixed_point res = png_product2(a, b); - - if (res != 0) - return png_reciprocal(res); -#endif - - return 0; /* overflow */ -} -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ -#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* Fixed point gamma. - * - * The code to calculate the tables used below can be found in the shell script - * contrib/tools/intgamma.sh - * - * To calculate gamma this code implements fast log() and exp() calls using only - * fixed point arithmetic. This code has sufficient precision for either 8-bit - * or 16-bit sample values. - * - * The tables used here were calculated using simple 'bc' programs, but C double - * precision floating point arithmetic would work fine. - * - * 8-bit log table - * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to - * 255, so it's the base 2 logarithm of a normalized 8-bit floating point - * mantissa. The numbers are 32-bit fractions. - */ -static const png_uint_32 -png_8bit_l2[128] = -{ - 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, - 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, - 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, - 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, - 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, - 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, - 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, - 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, - 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, - 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, - 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, - 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, - 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, - 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, - 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, - 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, - 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, - 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, - 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, - 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, - 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, - 24347096U, 0U - -#if 0 - /* The following are the values for 16-bit tables - these work fine for the - * 8-bit conversions but produce very slightly larger errors in the 16-bit - * log (about 1.2 as opposed to 0.7 absolute error in the final value). To - * use these all the shifts below must be adjusted appropriately. - */ - 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, - 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, - 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, - 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, - 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, - 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, - 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, - 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, - 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, - 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, - 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, - 1119, 744, 372 -#endif -}; - -static png_int_32 -png_log8bit(unsigned int x) -{ - unsigned int lg2 = 0; - /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, - * because the log is actually negate that means adding 1. The final - * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 - * input), return -1 for the overflow (log 0) case, - so the result is - * always at most 19 bits. - */ - if ((x &= 0xff) == 0) - return -1; - - if ((x & 0xf0) == 0) - lg2 = 4, x <<= 4; - - if ((x & 0xc0) == 0) - lg2 += 2, x <<= 2; - - if ((x & 0x80) == 0) - lg2 += 1, x <<= 1; - - /* result is at most 19 bits, so this cast is safe: */ - return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); -} - -/* The above gives exact (to 16 binary places) log2 values for 8-bit images, - * for 16-bit images we use the most significant 8 bits of the 16-bit value to - * get an approximation then multiply the approximation by a correction factor - * determined by the remaining up to 8 bits. This requires an additional step - * in the 16-bit case. - * - * We want log2(value/65535), we have log2(v'/255), where: - * - * value = v' * 256 + v'' - * = v' * f - * - * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 - * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less - * than 258. The final factor also needs to correct for the fact that our 8-bit - * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. - * - * This gives a final formula using a calculated value 'x' which is value/v' and - * scaling by 65536 to match the above table: - * - * log2(x/257) * 65536 - * - * Since these numbers are so close to '1' we can use simple linear - * interpolation between the two end values 256/257 (result -368.61) and 258/257 - * (result 367.179). The values used below are scaled by a further 64 to give - * 16-bit precision in the interpolation: - * - * Start (256): -23591 - * Zero (257): 0 - * End (258): 23499 - */ -#ifdef PNG_16BIT_SUPPORTED -static png_int_32 -png_log16bit(png_uint_32 x) -{ - unsigned int lg2 = 0; - - /* As above, but now the input has 16 bits. */ - if ((x &= 0xffff) == 0) - return -1; - - if ((x & 0xff00) == 0) - lg2 = 8, x <<= 8; - - if ((x & 0xf000) == 0) - lg2 += 4, x <<= 4; - - if ((x & 0xc000) == 0) - lg2 += 2, x <<= 2; - - if ((x & 0x8000) == 0) - lg2 += 1, x <<= 1; - - /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional - * value. - */ - lg2 <<= 28; - lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; - - /* Now we need to interpolate the factor, this requires a division by the top - * 8 bits. Do this with maximum precision. - */ - x = ((x << 16) + (x >> 9)) / (x >> 8); - - /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, - * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly - * 16 bits to interpolate to get the low bits of the result. Round the - * answer. Note that the end point values are scaled by 64 to retain overall - * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust - * the overall scaling by 6-12. Round at every step. - */ - x -= 1U << 24; - - if (x <= 65536U) /* <= '257' */ - lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); - - else - lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); - - /* Safe, because the result can't have more than 20 bits: */ - return (png_int_32)((lg2 + 2048) >> 12); -} -#endif /* 16BIT */ - -/* The 'exp()' case must invert the above, taking a 20-bit fixed point - * logarithmic value and returning a 16 or 8-bit number as appropriate. In - * each case only the low 16 bits are relevant - the fraction - since the - * integer bits (the top 4) simply determine a shift. - * - * The worst case is the 16-bit distinction between 65535 and 65534. This - * requires perhaps spurious accuracy in the decoding of the logarithm to - * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance - * of getting this accuracy in practice. - * - * To deal with this the following exp() function works out the exponent of the - * fractional part of the logarithm by using an accurate 32-bit value from the - * top four fractional bits then multiplying in the remaining bits. - */ -static const png_uint_32 -png_32bit_exp[16] = -{ - /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ - 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, - 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, - 2553802834U, 2445529972U, 2341847524U, 2242560872U -}; - -/* Adjustment table; provided to explain the numbers in the code below. */ -#if 0 -for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} - 11 44937.64284865548751208448 - 10 45180.98734845585101160448 - 9 45303.31936980687359311872 - 8 45364.65110595323018870784 - 7 45395.35850361789624614912 - 6 45410.72259715102037508096 - 5 45418.40724413220722311168 - 4 45422.25021786898173001728 - 3 45424.17186732298419044352 - 2 45425.13273269940811464704 - 1 45425.61317555035558641664 - 0 45425.85339951654943850496 -#endif - -static png_uint_32 -png_exp(png_fixed_point x) -{ - if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ - { - /* Obtain a 4-bit approximation */ - png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f]; - - /* Incorporate the low 12 bits - these decrease the returned value by - * multiplying by a number less than 1 if the bit is set. The multiplier - * is determined by the above table and the shift. Notice that the values - * converge on 45426 and this is used to allow linear interpolation of the - * low bits. - */ - if (x & 0x800) - e -= (((e >> 16) * 44938U) + 16U) >> 5; - - if (x & 0x400) - e -= (((e >> 16) * 45181U) + 32U) >> 6; - - if (x & 0x200) - e -= (((e >> 16) * 45303U) + 64U) >> 7; - - if (x & 0x100) - e -= (((e >> 16) * 45365U) + 128U) >> 8; - - if (x & 0x080) - e -= (((e >> 16) * 45395U) + 256U) >> 9; - - if (x & 0x040) - e -= (((e >> 16) * 45410U) + 512U) >> 10; - - /* And handle the low 6 bits in a single block. */ - e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; - - /* Handle the upper bits of x. */ - e >>= x >> 16; - return e; - } - - /* Check for overflow */ - if (x <= 0) - return png_32bit_exp[0]; - - /* Else underflow */ - return 0; -} - -static png_byte -png_exp8bit(png_fixed_point lg2) -{ - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the - * second, rounding, step can't overflow because of the first, subtraction, - * step. - */ - x -= x >> 8; - return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff); -} - -#ifdef PNG_16BIT_SUPPORTED -static png_uint_16 -png_exp16bit(png_fixed_point lg2) -{ - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ - x -= x >> 16; - return (png_uint_16)((x + 32767U) >> 16); -} -#endif /* 16BIT */ -#endif /* FLOATING_ARITHMETIC */ - -png_byte -png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value > 0 && value < 255) - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly - * convert this to a floating point value. This includes values that - * would overflow if 'value' were to be converted to 'int'. - * - * Apparently GCC, however, does an intermediate conversion to (int) - * on some (ARM) but not all (x86) platforms, possibly because of - * hardware FP limitations. (E.g. if the hardware conversion always - * assumes the integer register contains a signed value.) This results - * in ANSI-C undefined behavior for large values. - * - * Other implementations on the same machine might actually be ANSI-C90 - * conformant and therefore compile spurious extra code for the large - * values. - * - * We can be reasonably sure that an unsigned to float conversion - * won't be faster than an int to float one. Therefore this code - * assumes responsibility for the undefined behavior, which it knows - * can't happen because of the check above. - * - * Note the argument to this routine is an (unsigned int) because, on - * 16-bit platforms, it is assigned a value which might be out of - * range for an (int); that would result in undefined behavior in the - * caller if the *argument* ('value') were to be declared (int). - */ - double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5); - return (png_byte)r; -# else - png_int_32 lg2 = png_log8bit(value); - png_fixed_point res; - - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp8bit(res); - - /* Overflow. */ - value = 0; -# endif - } - - return (png_byte)(value & 0xff); -} - -#ifdef PNG_16BIT_SUPPORTED -png_uint_16 -png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value > 0 && value < 65535) - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* The same (unsigned int)->(double) constraints apply here as above, - * however in this case the (unsigned int) to (int) conversion can - * overflow on an ANSI-C90 compliant system so the cast needs to ensure - * that this is not possible. - */ - double r = floor(65535*pow((png_int_32)value/65535., - gamma_val*.00001)+.5); - return (png_uint_16)r; -# else - png_int_32 lg2 = png_log16bit(value); - png_fixed_point res; - - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp16bit(res); - - /* Overflow. */ - value = 0; -# endif - } - - return (png_uint_16)value; -} -#endif /* 16BIT */ - -/* This does the right thing based on the bit_depth field of the - * png_struct, interpreting values as 8-bit or 16-bit. While the result - * is nominally a 16-bit value if bit depth is 8 then the result is - * 8-bit (as are the arguments.) - */ -png_uint_16 /* PRIVATE */ -png_gamma_correct(png_structrp png_ptr, unsigned int value, - png_fixed_point gamma_val) -{ - if (png_ptr->bit_depth == 8) - return png_gamma_8bit_correct(value, gamma_val); - -#ifdef PNG_16BIT_SUPPORTED - else - return png_gamma_16bit_correct(value, gamma_val); -#else - /* should not reach this */ - return 0; -#endif /* 16BIT */ -} - -#ifdef PNG_16BIT_SUPPORTED -/* Internal function to build a single 16-bit table - the table consists of - * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount - * to shift the input values right (or 16-number_of_signifiant_bits). - * - * The caller is responsible for ensuring that the table gets cleaned up on - * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument - * should be somewhere that will be cleaned. - */ -static void -png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - unsigned int shift, png_fixed_point gamma_val) -{ - /* Various values derived from 'shift': */ - unsigned int num = 1U << (8U - shift); -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* CSE the division and work round wacky GCC warnings (see the comments - * in png_gamma_8bit_correct for where these come from.) - */ - double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1); -#endif - unsigned int max = (1U << (16U - shift)) - 1U; - unsigned int max_by_2 = 1U << (15U - shift); - unsigned int i; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); - - for (i = 0; i < num; i++) - { - png_uint_16p sub_table = table[i] = - (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); - - /* The 'threshold' test is repeated here because it can arise for one of - * the 16-bit tables even if the others don't hit it. - */ - if (png_gamma_significant(gamma_val) != 0) - { - /* The old code would overflow at the end and this would cause the - * 'pow' function to return a result >1, resulting in an - * arithmetic error. This code follows the spec exactly; ig is - * the recovered input sample, it always has 8-16 bits. - * - * We want input * 65535/max, rounded, the arithmetic fits in 32 - * bits (unsigned) so long as max <= 32767. - */ - unsigned int j; - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Inline the 'max' scaling operation: */ - /* See png_gamma_8bit_correct for why the cast to (int) is - * required here. - */ - double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5); - sub_table[j] = (png_uint_16)d; -# else - if (shift != 0) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); -# endif - } - } - else - { - /* We must still build a table, but do it the fast way. */ - unsigned int j; - - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; - - if (shift != 0) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = (png_uint_16)ig; - } - } - } -} - -/* NOTE: this function expects the *inverse* of the overall gamma transformation - * required. - */ -static void -png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - unsigned int shift, png_fixed_point gamma_val) -{ - unsigned int num = 1U << (8U - shift); - unsigned int max = (1U << (16U - shift))-1U; - unsigned int i; - png_uint_32 last; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); - - /* 'num' is the number of tables and also the number of low bits of low - * bits of the input 16-bit value used to select a table. Each table is - * itself indexed by the high 8 bits of the value. - */ - for (i = 0; i < num; i++) - table[i] = (png_uint_16p)png_malloc(png_ptr, - 256 * (sizeof (png_uint_16))); - - /* 'gamma_val' is set to the reciprocal of the value calculated above, so - * pow(out,g) is an *input* value. 'last' is the last input value set. - * - * In the loop 'i' is used to find output values. Since the output is - * 8-bit there are only 256 possible values. The tables are set up to - * select the closest possible output value for each input by finding - * the input value at the boundary between each pair of output values - * and filling the table up to that boundary with the lower output - * value. - * - * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit - * values the code below uses a 16-bit value in i; the values start at - * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last - * entries are filled with 255). Start i at 128 and fill all 'last' - * table entries <= 'max' - */ - last = 0; - for (i = 0; i < 255; ++i) /* 8-bit output value */ - { - /* Find the corresponding maximum input value */ - png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ - - /* Find the boundary value in 16 bits: */ - png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); - - /* Adjust (round) to (16-shift) bits: */ - bound = (bound * max + 32768U)/65535U + 1U; - - while (last < bound) - { - table[last & (0xffU >> shift)][last >> (8U - shift)] = out; - last++; - } - } - - /* And fill in the final entries. */ - while (last < (num << 8)) - { - table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; - last++; - } -} -#endif /* 16BIT */ - -/* Build a single 8-bit table: same as the 16-bit case but much simpler (and - * typically much faster). Note that libpng currently does no sBIT processing - * (apparently contrary to the spec) so a 256-entry table is always generated. - */ -static void -png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - png_fixed_point gamma_val) -{ - unsigned int i; - png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); - - if (png_gamma_significant(gamma_val) != 0) - for (i=0; i<256; i++) - table[i] = png_gamma_8bit_correct(i, gamma_val); - - else - for (i=0; i<256; ++i) - table[i] = (png_byte)(i & 0xff); -} - -/* Used from png_read_destroy and below to release the memory used by the gamma - * tables. - */ -void /* PRIVATE */ -png_destroy_gamma_table(png_structrp png_ptr) -{ - png_free(png_ptr, png_ptr->gamma_table); - png_ptr->gamma_table = NULL; - -#ifdef PNG_16BIT_SUPPORTED - if (png_ptr->gamma_16_table != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_table[i]); - } - png_free(png_ptr, png_ptr->gamma_16_table); - png_ptr->gamma_16_table = NULL; - } -#endif /* 16BIT */ - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_free(png_ptr, png_ptr->gamma_from_1); - png_ptr->gamma_from_1 = NULL; - png_free(png_ptr, png_ptr->gamma_to_1); - png_ptr->gamma_to_1 = NULL; - -#ifdef PNG_16BIT_SUPPORTED - if (png_ptr->gamma_16_from_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_from_1[i]); - } - png_free(png_ptr, png_ptr->gamma_16_from_1); - png_ptr->gamma_16_from_1 = NULL; - } - if (png_ptr->gamma_16_to_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_to_1[i]); - } - png_free(png_ptr, png_ptr->gamma_16_to_1); - png_ptr->gamma_16_to_1 = NULL; - } -#endif /* 16BIT */ -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -} - -/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit - * tables, we don't make a full table if we are reducing to 8-bit in - * the future. Note also how the gamma_16 tables are segmented so that - * we don't need to allocate > 64K chunks for a full 16-bit table. - */ -void /* PRIVATE */ -png_build_gamma_table(png_structrp png_ptr, int bit_depth) -{ - png_debug(1, "in png_build_gamma_table"); - - /* Remove any existing table; this copes with multiple calls to - * png_read_update_info. The warning is because building the gamma tables - * multiple times is a performance hit - it's harmless but the ability to - * call png_read_update_info() multiple times is new in 1.5.6 so it seems - * sensible to warn if the app introduces such a hit. - */ - if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) - { - png_warning(png_ptr, "gamma table being rebuilt"); - png_destroy_gamma_table(png_ptr); - } - - if (bit_depth <= 8) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, - png_ptr->screen_gamma > 0 ? - png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->colorspace.gamma)); - - png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? - png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -#ifdef PNG_16BIT_SUPPORTED - else - { - png_byte shift, sig_bit; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - sig_bit = png_ptr->sig_bit.red; - - if (png_ptr->sig_bit.green > sig_bit) - sig_bit = png_ptr->sig_bit.green; - - if (png_ptr->sig_bit.blue > sig_bit) - sig_bit = png_ptr->sig_bit.blue; - } - else - sig_bit = png_ptr->sig_bit.gray; - - /* 16-bit gamma code uses this equation: - * - * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] - * - * Where 'iv' is the input color value and 'ov' is the output value - - * pow(iv, gamma). - * - * Thus the gamma table consists of up to 256 256-entry tables. The table - * is selected by the (8-gamma_shift) most significant of the low 8 bits - * of the color value then indexed by the upper 8 bits: - * - * table[low bits][high 8 bits] - * - * So the table 'n' corresponds to all those 'iv' of: - * - * ..<(n+1 << gamma_shift)-1> - * - */ - if (sig_bit > 0 && sig_bit < 16U) - /* shift == insignificant bits */ - shift = (png_byte)((16U - sig_bit) & 0xff); - - else - shift = 0; /* keep all 16 bits */ - - if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - { - /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively - * the significant bits in the *input* when the output will - * eventually be 8 bits. By default it is 11. - */ - if (shift < (16U - PNG_MAX_GAMMA_8)) - shift = (16U - PNG_MAX_GAMMA_8); - } - - if (shift > 8U) - shift = 8U; /* Guarantees at least one table! */ - - png_ptr->gamma_shift = shift; - - /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now - * PNG_COMPOSE). This effectively smashed the background calculation for - * 16-bit output because the 8-bit table assumes the result will be - * reduced to 8 bits. - */ - if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - - else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->colorspace.gamma)); - - /* Notice that the '16 from 1' table should be full precision, however - * the lookup on this table still uses gamma_shift, so it can't be. - * TODO: fix this. - */ - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -#endif /* 16BIT */ -} -#endif /* READ_GAMMA */ - -/* HARDWARE OR SOFTWARE OPTION SUPPORT */ -#ifdef PNG_SET_OPTION_SUPPORTED -int PNGAPI -png_set_option(png_structrp png_ptr, int option, int onoff) -{ - if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && - (option & 1) == 0) - { - png_uint_32 mask = 3U << option; - png_uint_32 setting = (2U + (onoff != 0)) << option; - png_uint_32 current = png_ptr->options; - - png_ptr->options = (png_uint_32)((current & ~mask) | setting); - - return (int)(current & mask) >> option; - } - - return PNG_OPTION_INVALID; -} -#endif - -/* sRGB support */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* sRGB conversion tables; these are machine generated with the code in - * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the - * specification (see the article at https://en.wikipedia.org/wiki/SRGB) - * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. - * The sRGB to linear table is exact (to the nearest 16-bit linear fraction). - * The inverse (linear to sRGB) table has accuracies as follows: - * - * For all possible (255*65535+1) input values: - * - * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact - * - * For the input values corresponding to the 65536 16-bit values: - * - * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact - * - * In all cases the inexact readings are only off by one. - */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* The convert-to-sRGB table is only currently required for read. */ -const png_uint_16 png_sRGB_table[256] = -{ - 0,20,40,60,80,99,119,139, - 159,179,199,219,241,264,288,313, - 340,367,396,427,458,491,526,562, - 599,637,677,718,761,805,851,898, - 947,997,1048,1101,1156,1212,1270,1330, - 1391,1453,1517,1583,1651,1720,1790,1863, - 1937,2013,2090,2170,2250,2333,2418,2504, - 2592,2681,2773,2866,2961,3058,3157,3258, - 3360,3464,3570,3678,3788,3900,4014,4129, - 4247,4366,4488,4611,4736,4864,4993,5124, - 5257,5392,5530,5669,5810,5953,6099,6246, - 6395,6547,6700,6856,7014,7174,7335,7500, - 7666,7834,8004,8177,8352,8528,8708,8889, - 9072,9258,9445,9635,9828,10022,10219,10417, - 10619,10822,11028,11235,11446,11658,11873,12090, - 12309,12530,12754,12980,13209,13440,13673,13909, - 14146,14387,14629,14874,15122,15371,15623,15878, - 16135,16394,16656,16920,17187,17456,17727,18001, - 18277,18556,18837,19121,19407,19696,19987,20281, - 20577,20876,21177,21481,21787,22096,22407,22721, - 23038,23357,23678,24002,24329,24658,24990,25325, - 25662,26001,26344,26688,27036,27386,27739,28094, - 28452,28813,29176,29542,29911,30282,30656,31033, - 31412,31794,32179,32567,32957,33350,33745,34143, - 34544,34948,35355,35764,36176,36591,37008,37429, - 37852,38278,38706,39138,39572,40009,40449,40891, - 41337,41785,42236,42690,43147,43606,44069,44534, - 45002,45473,45947,46423,46903,47385,47871,48359, - 48850,49344,49841,50341,50844,51349,51858,52369, - 52884,53401,53921,54445,54971,55500,56032,56567, - 57105,57646,58190,58737,59287,59840,60396,60955, - 61517,62082,62650,63221,63795,64372,64952,65535 -}; -#endif /* SIMPLIFIED_READ */ - -/* The base/delta tables are required for both read and write (but currently - * only the simplified versions.) - */ -const png_uint_16 png_sRGB_base[512] = -{ - 128,1782,3383,4644,5675,6564,7357,8074, - 8732,9346,9921,10463,10977,11466,11935,12384, - 12816,13233,13634,14024,14402,14769,15125,15473, - 15812,16142,16466,16781,17090,17393,17690,17981, - 18266,18546,18822,19093,19359,19621,19879,20133, - 20383,20630,20873,21113,21349,21583,21813,22041, - 22265,22487,22707,22923,23138,23350,23559,23767, - 23972,24175,24376,24575,24772,24967,25160,25352, - 25542,25730,25916,26101,26284,26465,26645,26823, - 27000,27176,27350,27523,27695,27865,28034,28201, - 28368,28533,28697,28860,29021,29182,29341,29500, - 29657,29813,29969,30123,30276,30429,30580,30730, - 30880,31028,31176,31323,31469,31614,31758,31902, - 32045,32186,32327,32468,32607,32746,32884,33021, - 33158,33294,33429,33564,33697,33831,33963,34095, - 34226,34357,34486,34616,34744,34873,35000,35127, - 35253,35379,35504,35629,35753,35876,35999,36122, - 36244,36365,36486,36606,36726,36845,36964,37083, - 37201,37318,37435,37551,37668,37783,37898,38013, - 38127,38241,38354,38467,38580,38692,38803,38915, - 39026,39136,39246,39356,39465,39574,39682,39790, - 39898,40005,40112,40219,40325,40431,40537,40642, - 40747,40851,40955,41059,41163,41266,41369,41471, - 41573,41675,41777,41878,41979,42079,42179,42279, - 42379,42478,42577,42676,42775,42873,42971,43068, - 43165,43262,43359,43456,43552,43648,43743,43839, - 43934,44028,44123,44217,44311,44405,44499,44592, - 44685,44778,44870,44962,45054,45146,45238,45329, - 45420,45511,45601,45692,45782,45872,45961,46051, - 46140,46229,46318,46406,46494,46583,46670,46758, - 46846,46933,47020,47107,47193,47280,47366,47452, - 47538,47623,47709,47794,47879,47964,48048,48133, - 48217,48301,48385,48468,48552,48635,48718,48801, - 48884,48966,49048,49131,49213,49294,49376,49458, - 49539,49620,49701,49782,49862,49943,50023,50103, - 50183,50263,50342,50422,50501,50580,50659,50738, - 50816,50895,50973,51051,51129,51207,51285,51362, - 51439,51517,51594,51671,51747,51824,51900,51977, - 52053,52129,52205,52280,52356,52432,52507,52582, - 52657,52732,52807,52881,52956,53030,53104,53178, - 53252,53326,53400,53473,53546,53620,53693,53766, - 53839,53911,53984,54056,54129,54201,54273,54345, - 54417,54489,54560,54632,54703,54774,54845,54916, - 54987,55058,55129,55199,55269,55340,55410,55480, - 55550,55620,55689,55759,55828,55898,55967,56036, - 56105,56174,56243,56311,56380,56448,56517,56585, - 56653,56721,56789,56857,56924,56992,57059,57127, - 57194,57261,57328,57395,57462,57529,57595,57662, - 57728,57795,57861,57927,57993,58059,58125,58191, - 58256,58322,58387,58453,58518,58583,58648,58713, - 58778,58843,58908,58972,59037,59101,59165,59230, - 59294,59358,59422,59486,59549,59613,59677,59740, - 59804,59867,59930,59993,60056,60119,60182,60245, - 60308,60370,60433,60495,60558,60620,60682,60744, - 60806,60868,60930,60992,61054,61115,61177,61238, - 61300,61361,61422,61483,61544,61605,61666,61727, - 61788,61848,61909,61969,62030,62090,62150,62211, - 62271,62331,62391,62450,62510,62570,62630,62689, - 62749,62808,62867,62927,62986,63045,63104,63163, - 63222,63281,63340,63398,63457,63515,63574,63632, - 63691,63749,63807,63865,63923,63981,64039,64097, - 64155,64212,64270,64328,64385,64443,64500,64557, - 64614,64672,64729,64786,64843,64900,64956,65013, - 65070,65126,65183,65239,65296,65352,65409,65465 -}; - -const png_byte png_sRGB_delta[512] = -{ - 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, - 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, - 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, - 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, - 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, - 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, - 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, - 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, - 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, - 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, - 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, - 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, - 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, - 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,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,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,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; -#endif /* SIMPLIFIED READ/WRITE sRGB support */ - -/* SIMPLIFIED READ/WRITE SUPPORT */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -static int -png_image_free_function(png_voidp argument) -{ - png_imagep image = png_voidcast(png_imagep, argument); - png_controlp cp = image->opaque; - png_control c; - - /* Double check that we have a png_ptr - it should be impossible to get here - * without one. - */ - if (cp->png_ptr == NULL) - return 0; - - /* First free any data held in the control structure. */ -# ifdef PNG_STDIO_SUPPORTED - if (cp->owned_file != 0) - { - FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); - cp->owned_file = 0; - - /* Ignore errors here. */ - if (fp != NULL) - { - cp->png_ptr->io_ptr = NULL; - (void)fclose(fp); - } - } -# endif - - /* Copy the control structure so that the original, allocated, version can be - * safely freed. Notice that a png_error here stops the remainder of the - * cleanup, but this is probably fine because that would indicate bad memory - * problems anyway. - */ - c = *cp; - image->opaque = &c; - png_free(c.png_ptr, cp); - - /* Then the structures, calling the correct API. */ - if (c.for_write != 0) - { -# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED - png_destroy_write_struct(&c.png_ptr, &c.info_ptr); -# else - png_error(c.png_ptr, "simplified write not supported"); -# endif - } - else - { -# ifdef PNG_SIMPLIFIED_READ_SUPPORTED - png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); -# else - png_error(c.png_ptr, "simplified read not supported"); -# endif - } - - /* Success. */ - return 1; -} - -void PNGAPI -png_image_free(png_imagep image) -{ - /* Safely call the real function, but only if doing so is safe at this point - * (if not inside an error handling context). Otherwise assume - * png_safe_execute will call this API after the return. - */ - if (image != NULL && image->opaque != NULL && - image->opaque->error_buf == NULL) - { - png_image_free_function(image); - image->opaque = NULL; - } -} - -int /* PRIVATE */ -png_image_error(png_imagep image, png_const_charp error_message) -{ - /* Utility to log an error. */ - png_safecat(image->message, (sizeof image->message), 0, error_message); - image->warning_or_error |= PNG_IMAGE_ERROR; - png_image_free(image); - return 0; -} - -#endif /* SIMPLIFIED READ/WRITE */ -#endif /* READ || WRITE */ +/* png.c - location for general purpose libpng functions + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +/* Generate a compiler error if there is an old png.h in the search path. */ +typedef png_libpng_version_1_6_59_git Your_png_h_is_not_version_1_6_59_git; + +/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the + * corresponding macro definitions. This causes a compile time failure if + * something is wrong but generates no code. + * + * (1) The first check is that the PNG_CHUNK(cHNK, index) 'index' values must + * increment from 0 to the last value. + */ +#define PNG_CHUNK(cHNK, index) != (index) || ((index)+1) + +#if 0 PNG_KNOWN_CHUNKS < 0 +# error PNG_KNOWN_CHUNKS chunk definitions are not in order +#endif + +#undef PNG_CHUNK + +/* (2) The chunk name macros, png_cHNK, must all be valid and defined. Since + * this is a preprocessor test undefined pp-tokens come out as zero and will + * fail this test. + */ +#define PNG_CHUNK(cHNK, index) !PNG_CHUNK_NAME_VALID(png_ ## cHNK) || + +#if PNG_KNOWN_CHUNKS 0 +# error png_cHNK not defined for some known cHNK +#endif + +#undef PNG_CHUNK + +/* Tells libpng that we have already handled the first "num_bytes" bytes + * of the PNG file signature. If the PNG data is embedded into another + * stream we can set num_bytes = 8 so that libpng will not attempt to read + * or write any of the magic bytes before it starts on the IHDR. + */ + +#ifdef PNG_READ_SUPPORTED +void PNGAPI +png_set_sig_bytes(png_structrp png_ptr, int num_bytes) +{ + unsigned int nb = (unsigned int)num_bytes; + + png_debug(1, "in png_set_sig_bytes"); + + if (png_ptr == NULL) + return; + + if (num_bytes < 0) + nb = 0; + + if (nb > 8) + png_error(png_ptr, "Too many bytes for PNG signature"); + + png_ptr->sig_bytes = (png_byte)nb; +} + +/* Checks whether the supplied bytes match the PNG signature. We allow + * checking less than the full 8-byte signature so that those apps that + * already read the first few bytes of a file to determine the file type + * can simply check the remaining bytes for extra assurance. Returns + * an integer less than, equal to, or greater than zero if sig is found, + * respectively, to be less than, to match, or be greater than the correct + * PNG signature (this is the same behavior as strcmp, memcmp, etc). + */ +int PNGAPI +png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) +{ + static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + + if (num_to_check > 8) + num_to_check = 8; + + else if (num_to_check < 1) + return -1; + + if (start > 7) + return -1; + + if (start + num_to_check > 8) + num_to_check = 8 - start; + + return memcmp(&sig[start], &png_signature[start], num_to_check); +} + +#endif /* READ */ + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Function to allocate memory for zlib */ +PNG_FUNCTION(voidpf /* PRIVATE */, +png_zalloc,(voidpf png_ptr, uInt items, uInt size), + PNG_ALLOCATED) +{ + png_alloc_size_t num_bytes = size; + + if (png_ptr == NULL) + return NULL; + + /* This check against overflow is vestigial, dating back from + * the old times when png_zalloc used to be an exported function. + * We're still keeping it here for now, as an extra-cautious + * prevention against programming errors inside zlib, although it + * should rather be a debug-time assertion instead. + */ + if (size != 0 && items >= (~(png_alloc_size_t)0) / size) + { + png_warning(png_voidcast(png_structrp, png_ptr), + "Potential overflow in png_zalloc()"); + return NULL; + } + + num_bytes *= items; + return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); +} + +/* Function to free memory for zlib */ +void /* PRIVATE */ +png_zfree(voidpf png_ptr, voidpf ptr) +{ + png_free(png_voidcast(png_const_structrp,png_ptr), ptr); +} + +/* Reset the CRC variable to 32 bits of 1's. Care must be taken + * in case CRC is > 32 bits to leave the top bits 0. + */ +void /* PRIVATE */ +png_reset_crc(png_structrp png_ptr) +{ + /* The cast is safe because the crc is a 32-bit value. */ + png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); +} + +/* Calculate the CRC over a section of data. We can only pass as + * much data to this routine as the largest single buffer size. We + * also check that this data will actually be used before going to the + * trouble of calculating it. + */ +void /* PRIVATE */ +png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length) +{ + int need_crc = 1; + + if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + + else /* critical */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) + need_crc = 0; + } + + /* 'uLong' is defined in zlib.h as unsigned long; this means that on some + * systems it is a 64-bit value. crc32, however, returns 32 bits so the + * following cast is safe. 'uInt' may be no more than 16 bits, so it is + * necessary to perform a loop here. + */ + if (need_crc != 0 && length > 0) + { + uLong crc = png_ptr->crc; /* Should never issue a warning */ + + do + { + uInt safe_length = (uInt)length; +#ifndef __COVERITY__ + if (safe_length == 0) + safe_length = (uInt)-1; /* evil, but safe */ +#endif + + crc = crc32(crc, ptr, safe_length); + + /* The following should never issue compiler warnings; if they do the + * target system has characteristics that will probably violate other + * assumptions within the libpng code. + */ + ptr += safe_length; + length -= safe_length; + } + while (length > 0); + + /* And the following is always safe because the crc is only 32 bits. */ + png_ptr->crc = (png_uint_32)crc; + } +} + +/* Check a user supplied version number, called from both read and write + * functions that create a png_struct. + */ +int +png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) +{ + /* Libpng versions 1.0.0 and later are binary compatible if the version + * string matches through the second '.'; we must recompile any + * applications that use any older library version. + */ + + if (user_png_ver != NULL) + { + int i = -1; + int found_dots = 0; + + do + { + i++; + if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + if (user_png_ver[i] == '.') + found_dots++; + } while (found_dots < 2 && user_png_ver[i] != 0 && + PNG_LIBPNG_VER_STRING[i] != 0); + } + + else + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + + if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0) + { +#ifdef PNG_WARNINGS_SUPPORTED + size_t pos = 0; + char m[128]; + + pos = png_safecat(m, (sizeof m), pos, + "Application built with libpng-"); + pos = png_safecat(m, (sizeof m), pos, user_png_ver); + pos = png_safecat(m, (sizeof m), pos, " but running with "); + pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING); + PNG_UNUSED(pos) + + png_warning(png_ptr, m); +#endif + + return 0; + } + + /* Success return. */ + return 1; +} + +/* Generic function to create a png_struct for either read or write - this + * contains the common initialization. + */ +PNG_FUNCTION(png_structp /* PRIVATE */, +png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED) +{ + png_struct create_struct; +# ifdef PNG_SETJMP_SUPPORTED + jmp_buf create_jmp_buf; +# endif + + /* This temporary stack-allocated structure is used to provide a place to + * build enough context to allow the user provided memory allocator (if any) + * to be called. + */ + memset(&create_struct, 0, (sizeof create_struct)); + +# ifdef PNG_USER_LIMITS_SUPPORTED + create_struct.user_width_max = PNG_USER_WIDTH_MAX; + create_struct.user_height_max = PNG_USER_HEIGHT_MAX; + +# ifdef PNG_USER_CHUNK_CACHE_MAX + create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; +# endif + +# if PNG_USER_CHUNK_MALLOC_MAX > 0 /* default to compile-time limit */ + create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; + + /* No compile-time limit, so initialize to the system limit: */ +# elif defined PNG_MAX_MALLOC_64K /* legacy system limit */ + create_struct.user_chunk_malloc_max = 65536U; + +# else /* modern system limit SIZE_MAX (C99) */ + create_struct.user_chunk_malloc_max = PNG_SIZE_MAX; +# endif +# endif + + /* The following two API calls simply set fields in png_struct, so it is safe + * to do them now even though error handling is not yet set up. + */ +# ifdef PNG_USER_MEM_SUPPORTED + png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); +# else + PNG_UNUSED(mem_ptr) + PNG_UNUSED(malloc_fn) + PNG_UNUSED(free_fn) +# endif + + /* (*error_fn) can return control to the caller after the error_ptr is set, + * this will result in a memory leak unless the error_fn does something + * extremely sophisticated. The design lacks merit but is implicit in the + * API. + */ + png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); + +# ifdef PNG_SETJMP_SUPPORTED + if (!setjmp(create_jmp_buf)) +# endif + { +# ifdef PNG_SETJMP_SUPPORTED + /* Temporarily fake out the longjmp information until we have + * successfully completed this function. This only works if we have + * setjmp() support compiled in, but it is safe - this stuff should + * never happen. + */ + create_struct.jmp_buf_ptr = &create_jmp_buf; + create_struct.jmp_buf_size = 0; /*stack allocation*/ + create_struct.longjmp_fn = longjmp; +# endif + /* Call the general version checker (shared with read and write code): + */ + if (png_user_version_check(&create_struct, user_png_ver) != 0) + { + png_structrp png_ptr = png_voidcast(png_structrp, + png_malloc_warn(&create_struct, (sizeof *png_ptr))); + + if (png_ptr != NULL) + { + /* png_ptr->zstream holds a back-pointer to the png_struct, so + * this can only be done now: + */ + create_struct.zstream.zalloc = png_zalloc; + create_struct.zstream.zfree = png_zfree; + create_struct.zstream.opaque = png_ptr; + +# ifdef PNG_SETJMP_SUPPORTED + /* Eliminate the local error handling: */ + create_struct.jmp_buf_ptr = NULL; + create_struct.jmp_buf_size = 0; + create_struct.longjmp_fn = 0; +# endif + + *png_ptr = create_struct; + + /* This is the successful return point */ + return png_ptr; + } + } + } + + /* A longjmp because of a bug in the application storage allocator or a + * simple failure to allocate the png_struct. + */ + return NULL; +} + +/* Allocate the memory for an info_struct for the application. */ +PNG_FUNCTION(png_infop,PNGAPI +png_create_info_struct,(png_const_structrp png_ptr), + PNG_ALLOCATED) +{ + png_inforp info_ptr; + + png_debug(1, "in png_create_info_struct"); + + if (png_ptr == NULL) + return NULL; + + /* Use the internal API that does not (or at least should not) error out, so + * that this call always returns ok. The application typically sets up the + * error handling *after* creating the info_struct because this is the way it + * has always been done in 'example.c'. + */ + info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, + (sizeof *info_ptr))); + + if (info_ptr != NULL) + memset(info_ptr, 0, (sizeof *info_ptr)); + + return info_ptr; +} + +/* This function frees the memory associated with a single info struct. + * Normally, one would use either png_destroy_read_struct() or + * png_destroy_write_struct() to free an info struct, but this may be + * useful for some applications. From libpng 1.6.0 this function is also used + * internally to implement the png_info release part of the 'struct' destroy + * APIs. This ensures that all possible approaches free the same data (all of + * it). + */ +void PNGAPI +png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) +{ + png_inforp info_ptr = NULL; + + png_debug(1, "in png_destroy_info_struct"); + + if (png_ptr == NULL) + return; + + if (info_ptr_ptr != NULL) + info_ptr = *info_ptr_ptr; + + if (info_ptr != NULL) + { + /* Do this first in case of an error below; if the app implements its own + * memory management this can lead to png_free calling png_error, which + * will abort this routine and return control to the app error handler. + * An infinite loop may result if it then tries to free the same info + * ptr. + */ + *info_ptr_ptr = NULL; + + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + memset(info_ptr, 0, (sizeof *info_ptr)); + png_free(png_ptr, info_ptr); + } +} + +/* Initialize the info structure. This is now an internal function (0.89) + * and applications using it are urged to use png_create_info_struct() + * instead. Use deprecated in 1.6.0, internal use removed (used internally it + * is just a memset). + * + * NOTE: it is almost inconceivable that this API is used because it bypasses + * the user-memory mechanism and the user error handling/warning mechanisms in + * those cases where it does anything other than a memset. + */ +PNG_FUNCTION(void,PNGAPI +png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), + PNG_DEPRECATED) +{ + png_inforp info_ptr = *ptr_ptr; + + png_debug(1, "in png_info_init_3"); + + if (info_ptr == NULL) + return; + + if ((sizeof (png_info)) > png_info_struct_size) + { + *ptr_ptr = NULL; + /* The following line is why this API should not be used: */ + free(info_ptr); + info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, + (sizeof *info_ptr))); + if (info_ptr == NULL) + return; + *ptr_ptr = info_ptr; + } + + /* Set everything to 0 */ + memset(info_ptr, 0, (sizeof *info_ptr)); +} + +void PNGAPI +png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, + int freer, png_uint_32 mask) +{ + png_debug(1, "in png_data_freer"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (freer == PNG_DESTROY_WILL_FREE_DATA) + info_ptr->free_me |= mask; + + else if (freer == PNG_USER_WILL_FREE_DATA) + info_ptr->free_me &= ~mask; + + else + png_error(png_ptr, "Unknown freer parameter in png_data_freer"); +} + +void PNGAPI +png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, + int num) +{ + png_debug(1, "in png_free_data"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + +#ifdef PNG_TEXT_SUPPORTED + /* Free text item num or (if num == -1) all text items */ + if (info_ptr->text != NULL && + ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) + { + if (num != -1) + { + png_free(png_ptr, info_ptr->text[num].key); + info_ptr->text[num].key = NULL; + } + + else + { + int i; + + for (i = 0; i < info_ptr->num_text; i++) + png_free(png_ptr, info_ptr->text[i].key); + + png_free(png_ptr, info_ptr->text); + info_ptr->text = NULL; + info_ptr->num_text = 0; + info_ptr->max_text = 0; + } + } +#endif + +#ifdef PNG_tRNS_SUPPORTED + /* Free any tRNS entry */ + if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0) + { + info_ptr->valid &= ~PNG_INFO_tRNS; + png_free(png_ptr, info_ptr->trans_alpha); + info_ptr->trans_alpha = NULL; + info_ptr->num_trans = 0; + } +#endif + +#ifdef PNG_sCAL_SUPPORTED + /* Free any sCAL entry */ + if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0) + { + png_free(png_ptr, info_ptr->scal_s_width); + png_free(png_ptr, info_ptr->scal_s_height); + info_ptr->scal_s_width = NULL; + info_ptr->scal_s_height = NULL; + info_ptr->valid &= ~PNG_INFO_sCAL; + } +#endif + +#ifdef PNG_pCAL_SUPPORTED + /* Free any pCAL entry */ + if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0) + { + png_free(png_ptr, info_ptr->pcal_purpose); + png_free(png_ptr, info_ptr->pcal_units); + info_ptr->pcal_purpose = NULL; + info_ptr->pcal_units = NULL; + + if (info_ptr->pcal_params != NULL) + { + int i; + + for (i = 0; i < info_ptr->pcal_nparams; i++) + png_free(png_ptr, info_ptr->pcal_params[i]); + + png_free(png_ptr, info_ptr->pcal_params); + info_ptr->pcal_params = NULL; + } + info_ptr->valid &= ~PNG_INFO_pCAL; + } +#endif + +#ifdef PNG_iCCP_SUPPORTED + /* Free any profile entry */ + if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0) + { + png_free(png_ptr, info_ptr->iccp_name); + png_free(png_ptr, info_ptr->iccp_profile); + info_ptr->iccp_name = NULL; + info_ptr->iccp_profile = NULL; + info_ptr->valid &= ~PNG_INFO_iCCP; + } +#endif + +#ifdef PNG_sPLT_SUPPORTED + /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ + if (info_ptr->splt_palettes != NULL && + ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) + { + if (num != -1) + { + png_free(png_ptr, info_ptr->splt_palettes[num].name); + png_free(png_ptr, info_ptr->splt_palettes[num].entries); + info_ptr->splt_palettes[num].name = NULL; + info_ptr->splt_palettes[num].entries = NULL; + } + + else + { + int i; + + for (i = 0; i < info_ptr->splt_palettes_num; i++) + { + png_free(png_ptr, info_ptr->splt_palettes[i].name); + png_free(png_ptr, info_ptr->splt_palettes[i].entries); + } + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = NULL; + info_ptr->splt_palettes_num = 0; + info_ptr->valid &= ~PNG_INFO_sPLT; + } + } +#endif + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + if (info_ptr->unknown_chunks != NULL && + ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) + { + if (num != -1) + { + png_free(png_ptr, info_ptr->unknown_chunks[num].data); + info_ptr->unknown_chunks[num].data = NULL; + } + + else + { + int i; + + for (i = 0; i < info_ptr->unknown_chunks_num; i++) + png_free(png_ptr, info_ptr->unknown_chunks[i].data); + + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = NULL; + info_ptr->unknown_chunks_num = 0; + } + } +#endif + +#ifdef PNG_eXIf_SUPPORTED + /* Free any eXIf entry */ + if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0) + { + if (info_ptr->exif) + { + png_free(png_ptr, info_ptr->exif); + info_ptr->exif = NULL; + } + info_ptr->valid &= ~PNG_INFO_eXIf; + } +#endif + +#ifdef PNG_hIST_SUPPORTED + /* Free any hIST entry */ + if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) + { + png_free(png_ptr, info_ptr->hist); + info_ptr->hist = NULL; + info_ptr->valid &= ~PNG_INFO_hIST; + } +#endif + + /* Free any PLTE entry that was internally allocated */ + if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0) + { + png_free(png_ptr, info_ptr->palette); + info_ptr->palette = NULL; + info_ptr->valid &= ~PNG_INFO_PLTE; + info_ptr->num_palette = 0; + } + +#ifdef PNG_INFO_IMAGE_SUPPORTED + /* Free any image bits attached to the info structure */ + if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) + { + if (info_ptr->row_pointers != NULL) + { + png_uint_32 row; + for (row = 0; row < info_ptr->height; row++) + png_free(png_ptr, info_ptr->row_pointers[row]); + + png_free(png_ptr, info_ptr->row_pointers); + info_ptr->row_pointers = NULL; + } + info_ptr->valid &= ~PNG_INFO_IDAT; + } +#endif + + if (num != -1) + mask &= ~PNG_FREE_MUL; + + info_ptr->free_me &= ~mask; +} +#endif /* READ || WRITE */ + +/* This function returns a pointer to the io_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy() or png_read_destroy() are called. + */ +png_voidp PNGAPI +png_get_io_ptr(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return png_ptr->io_ptr; +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +# ifdef PNG_STDIO_SUPPORTED +/* Initialize the default input/output functions for the PNG file. If you + * use your own read or write routines, you can call either png_set_read_fn() + * or png_set_write_fn() instead of png_init_io(). If you have defined + * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a + * function of your own because "FILE *" isn't necessarily available. + */ +void PNGAPI +png_init_io(png_structrp png_ptr, FILE *fp) +{ + png_debug(1, "in png_init_io"); + + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = (png_voidp)fp; +} +# endif + +# ifdef PNG_SAVE_INT_32_SUPPORTED +/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 + * defines a cast of a signed integer to an unsigned integer either to preserve + * the value, if it is positive, or to calculate: + * + * (UNSIGNED_MAX+1) + integer + * + * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the + * negative integral value is added the result will be an unsigned value + * corresponding to the 2's complement representation. + */ +void PNGAPI +png_save_int_32(png_bytep buf, png_int_32 i) +{ + png_save_uint_32(buf, (png_uint_32)i); +} +# endif + +# ifdef PNG_TIME_RFC1123_SUPPORTED +/* Convert the supplied time into an RFC 1123 string suitable for use in + * a "Creation Time" or other text-based time string. + */ +int PNGAPI +png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) +{ + static const char short_months[12][4] = + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + if (out == NULL) + return 0; + + if (ptime->year > 9999 /* RFC1123 limitation */ || + ptime->month == 0 || ptime->month > 12 || + ptime->day == 0 || ptime->day > 31 || + ptime->hour > 23 || ptime->minute > 59 || + ptime->second > 60) + return 0; + + { + size_t pos = 0; + char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */ + +# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) +# define APPEND_NUMBER(format, value)\ + APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) +# define APPEND(ch) if (pos < 28) out[pos++] = (ch) + + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); + APPEND(' '); + APPEND_STRING(short_months[(ptime->month - 1)]); + APPEND(' '); + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); + APPEND(' '); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); + APPEND(':'); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); + APPEND(':'); + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); + APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ + PNG_UNUSED (pos) + +# undef APPEND +# undef APPEND_NUMBER +# undef APPEND_STRING + } + + return 1; +} + +# if PNG_LIBPNG_VER < 10700 +/* To do: remove the following from libpng-1.7 */ +/* Original API that uses a private buffer in png_struct. + * Deprecated because it causes png_struct to carry a spurious temporary + * buffer (png_struct::time_buffer), better to have the caller pass this in. + */ +png_const_charp PNGAPI +png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) +{ + if (png_ptr != NULL) + { + /* The only failure above if png_ptr != NULL is from an invalid ptime */ + if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0) + png_warning(png_ptr, "Ignoring invalid time value"); + + else + return png_ptr->time_buffer; + } + + return NULL; +} +# endif /* LIBPNG_VER < 10700 */ +# endif /* TIME_RFC1123 */ + +#endif /* READ || WRITE */ + +png_const_charp PNGAPI +png_get_copyright(png_const_structrp png_ptr) +{ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ +#ifdef PNG_STRING_COPYRIGHT + return PNG_STRING_COPYRIGHT +#else + return PNG_STRING_NEWLINE \ + "libpng version 1.6.59.git" PNG_STRING_NEWLINE \ + "Copyright (c) 2018-2026 Cosmin Truta" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ + PNG_STRING_NEWLINE \ + "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ + "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ + PNG_STRING_NEWLINE; +#endif +} + +/* The following return the library version as a short string in the + * format 1.0.0 through 99.99.99zz. To get the version of *.h files + * used with your application, print out PNG_LIBPNG_VER_STRING, which + * is defined in png.h. + * Note: now there is no difference between png_get_libpng_ver() and + * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, + * it is guaranteed that png.c uses the correct version of png.h. + */ +png_const_charp PNGAPI +png_get_libpng_ver(png_const_structrp png_ptr) +{ + /* Version of *.c files used when building libpng */ + return png_get_header_ver(png_ptr); +} + +png_const_charp PNGAPI +png_get_header_ver(png_const_structrp png_ptr) +{ + /* Version of *.h files used when building libpng */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ + return PNG_LIBPNG_VER_STRING; +} + +png_const_charp PNGAPI +png_get_header_version(png_const_structrp png_ptr) +{ + /* Returns longer string containing both version and date */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ +#ifdef __STDC__ + return PNG_HEADER_VERSION_STRING +# ifndef PNG_READ_SUPPORTED + " (NO READ SUPPORT)" +# endif + PNG_STRING_NEWLINE; +#else + return PNG_HEADER_VERSION_STRING; +#endif +} + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +/* NOTE: this routine is not used internally! */ +/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth + * large of png_color. This lets grayscale images be treated as + * paletted. Most useful for gamma correction and simplification + * of code. This API is not used internally. + */ +void PNGAPI +png_build_grayscale_palette(int bit_depth, png_colorp palette) +{ + int num_palette; + int color_inc; + int i; + int v; + + png_debug(1, "in png_do_build_grayscale_palette"); + + if (palette == NULL) + return; + + switch (bit_depth) + { + case 1: + num_palette = 2; + color_inc = 0xff; + break; + + case 2: + num_palette = 4; + color_inc = 0x55; + break; + + case 4: + num_palette = 16; + color_inc = 0x11; + break; + + case 8: + num_palette = 256; + color_inc = 1; + break; + + default: + num_palette = 0; + color_inc = 0; + break; + } + + for (i = 0, v = 0; i < num_palette; i++, v += color_inc) + { + palette[i].red = (png_byte)(v & 0xff); + palette[i].green = (png_byte)(v & 0xff); + palette[i].blue = (png_byte)(v & 0xff); + } +} +#endif + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +int PNGAPI +png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) +{ + /* Check chunk_name and return "keep" value if it's on the list, else 0 */ + png_const_bytep p, p_end; + + if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) + return PNG_HANDLE_CHUNK_AS_DEFAULT; + + p_end = png_ptr->chunk_list; + p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ + + /* The code is the fifth byte after each four byte string. Historically this + * code was always searched from the end of the list, this is no longer + * necessary because the 'set' routine handles duplicate entries correctly. + */ + do /* num_chunk_list > 0, so at least one */ + { + p -= 5; + + if (memcmp(chunk_name, p, 4) == 0) + return p[4]; + } + while (p > p_end); + + /* This means that known chunks should be processed and unknown chunks should + * be handled according to the value of png_ptr->unknown_default; this can be + * confusing because, as a result, there are two levels of defaulting for + * unknown chunks. + */ + return PNG_HANDLE_CHUNK_AS_DEFAULT; +} + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +int /* PRIVATE */ +png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) +{ + png_byte chunk_string[5]; + + PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); + return png_handle_as_unknown(png_ptr, chunk_string); +} +#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ +#endif /* SET_UNKNOWN_CHUNKS */ + +#ifdef PNG_READ_SUPPORTED +/* This function, added to libpng-1.0.6g, is untested. */ +int PNGAPI +png_reset_zstream(png_structrp png_ptr) +{ + if (png_ptr == NULL) + return Z_STREAM_ERROR; + + /* WARNING: this resets the window bits to the maximum! */ + return inflateReset(&png_ptr->zstream); +} +#endif /* READ */ + +/* This function was added to libpng-1.0.7 */ +png_uint_32 PNGAPI +png_access_version_number(void) +{ + /* Version of *.c files used when building libpng */ + return (png_uint_32)PNG_LIBPNG_VER; +} + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. + * If it doesn't 'ret' is used to set it to something appropriate, even in cases + * like Z_OK or Z_STREAM_END where the error code is apparently a success code. + */ +void /* PRIVATE */ +png_zstream_error(png_structrp png_ptr, int ret) +{ + /* Translate 'ret' into an appropriate error string, priority is given to the + * one in zstream if set. This always returns a string, even in cases like + * Z_OK or Z_STREAM_END where the error code is a success code. + */ + if (png_ptr->zstream.msg == NULL) switch (ret) + { + default: + case Z_OK: + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); + break; + + case Z_STREAM_END: + /* Normal exit */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); + break; + + case Z_NEED_DICT: + /* This means the deflate stream did not have a dictionary; this + * indicates a bogus PNG. + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); + break; + + case Z_ERRNO: + /* gz APIs only: should not happen */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); + break; + + case Z_STREAM_ERROR: + /* internal libpng error */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); + break; + + case Z_DATA_ERROR: + png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); + break; + + case Z_MEM_ERROR: + png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); + break; + + case Z_BUF_ERROR: + /* End of input or output; not a problem if the caller is doing + * incremental read or write. + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); + break; + + case Z_VERSION_ERROR: + png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); + break; + + case PNG_UNEXPECTED_ZLIB_RETURN: + /* Compile errors here mean that zlib now uses the value co-opted in + * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above + * and change pngpriv.h. Note that this message is "... return", + * whereas the default/Z_OK one is "... return code". + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); + break; + } +} + +#ifdef PNG_COLORSPACE_SUPPORTED +static png_int_32 +png_fp_add(png_int_32 addend0, png_int_32 addend1, int *error) +{ + /* Safely add two fixed point values setting an error flag and returning 0.5 + * on overflow. + * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore + * relying on addition of two positive values producing a negative one is not + * safe. + */ + if (addend0 > 0) + { + if (0x7fffffff - addend0 >= addend1) + return addend0+addend1; + } + else if (addend0 < 0) + { + if (-0x7fffffff - addend0 <= addend1) + return addend0+addend1; + } + else + return addend1; + + *error = 1; + return PNG_FP_1/2; +} + +static png_int_32 +png_fp_sub(png_int_32 addend0, png_int_32 addend1, int *error) +{ + /* As above but calculate addend0-addend1. */ + if (addend1 > 0) + { + if (-0x7fffffff + addend1 <= addend0) + return addend0-addend1; + } + else if (addend1 < 0) + { + if (0x7fffffff + addend1 >= addend0) + return addend0-addend1; + } + else + return addend0; + + *error = 1; + return PNG_FP_1/2; +} + +static int +png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1, + png_int_32 addend2) +{ + /* Safely add three integers. Returns 0 on success, 1 on overflow. Does not + * set the result on overflow. + */ + int error = 0; + int result = png_fp_add(*addend0_and_result, + png_fp_add(addend1, addend2, &error), + &error); + if (!error) *addend0_and_result = result; + return error; +} + +/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for + * cHRM, as opposed to using chromaticities. These internal APIs return + * non-zero on a parameter error. The X, Y and Z values are required to be + * positive and less than 1.0. + */ +int /* PRIVATE */ +png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) +{ + /* NOTE: returns 0 on success, 1 means error. */ + png_int_32 d, dred, dgreen, dblue, dwhite, whiteX, whiteY; + + /* 'd' in each of the blocks below is just X+Y+Z for each component, + * x, y and z are X,Y,Z/(X+Y+Z). + */ + d = XYZ->red_X; + if (png_safe_add(&d, XYZ->red_Y, XYZ->red_Z)) + return 1; + dred = d; + if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, dred) == 0) + return 1; + if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, dred) == 0) + return 1; + + d = XYZ->green_X; + if (png_safe_add(&d, XYZ->green_Y, XYZ->green_Z)) + return 1; + dgreen = d; + if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, dgreen) == 0) + return 1; + if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, dgreen) == 0) + return 1; + + d = XYZ->blue_X; + if (png_safe_add(&d, XYZ->blue_Y, XYZ->blue_Z)) + return 1; + dblue = d; + if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, dblue) == 0) + return 1; + if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, dblue) == 0) + return 1; + + /* The reference white is simply the sum of the end-point (X,Y,Z) vectors so + * the following calculates (X+Y+Z) of the reference white (media white, + * encoding white) itself: + */ + d = dblue; + if (png_safe_add(&d, dred, dgreen)) + return 1; + dwhite = d; + + /* Find the white X,Y values from the sum of the red, green and blue X,Y + * values. + */ + d = XYZ->red_X; + if (png_safe_add(&d, XYZ->green_X, XYZ->blue_X)) + return 1; + whiteX = d; + + d = XYZ->red_Y; + if (png_safe_add(&d, XYZ->green_Y, XYZ->blue_Y)) + return 1; + whiteY = d; + + if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) + return 1; + if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) + return 1; + + return 0; +} + +int /* PRIVATE */ +png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) +{ + /* NOTE: returns 0 on success, 1 means error. */ + png_fixed_point red_inverse, green_inverse, blue_scale; + png_fixed_point left, right, denominator; + + /* Check xy and, implicitly, z. Note that wide gamut color spaces typically + * have end points with 0 tristimulus values (these are impossible end + * points, but they are used to cover the possible colors). We check + * xy->whitey against 5, not 0, to avoid a possible integer overflow. + * + * The limits here will *not* accept ACES AP0, where bluey is -7700 + * (-0.0770) because the PNG spec itself requires the xy values to be + * unsigned. whitey is also required to be 5 or more to avoid overflow. + * + * Instead the upper limits have been relaxed to accommodate ACES AP1 where + * redz ends up as -600 (-0.006). ProPhotoRGB was already "in range." + * The new limit accommodates the AP0 and AP1 ranges for z but not AP0 redy. + */ + const png_fixed_point fpLimit = PNG_FP_1+(PNG_FP_1/10); + if (xy->redx < 0 || xy->redx > fpLimit) return 1; + if (xy->redy < 0 || xy->redy > fpLimit-xy->redx) return 1; + if (xy->greenx < 0 || xy->greenx > fpLimit) return 1; + if (xy->greeny < 0 || xy->greeny > fpLimit-xy->greenx) return 1; + if (xy->bluex < 0 || xy->bluex > fpLimit) return 1; + if (xy->bluey < 0 || xy->bluey > fpLimit-xy->bluex) return 1; + if (xy->whitex < 0 || xy->whitex > fpLimit) return 1; + if (xy->whitey < 5 || xy->whitey > fpLimit-xy->whitex) return 1; + + /* The reverse calculation is more difficult because the original tristimulus + * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 + * derived values were recorded in the cHRM chunk; + * (red,green,blue,white)x(x,y). This loses one degree of freedom and + * therefore an arbitrary ninth value has to be introduced to undo the + * original transformations. + * + * Think of the original end-points as points in (X,Y,Z) space. The + * chromaticity values (c) have the property: + * + * C + * c = --------- + * X + Y + Z + * + * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the + * three chromaticity values (x,y,z) for each end-point obey the + * relationship: + * + * x + y + z = 1 + * + * This describes the plane in (X,Y,Z) space that intersects each axis at the + * value 1.0; call this the chromaticity plane. Thus the chromaticity + * calculation has scaled each end-point so that it is on the x+y+z=1 plane + * and chromaticity is the intersection of the vector from the origin to the + * (X,Y,Z) value with the chromaticity plane. + * + * To fully invert the chromaticity calculation we would need the three + * end-point scale factors, (red-scale, green-scale, blue-scale), but these + * were not recorded. Instead we calculated the reference white (X,Y,Z) and + * recorded the chromaticity of this. The reference white (X,Y,Z) would have + * given all three of the scale factors since: + * + * color-C = color-c * color-scale + * white-C = red-C + green-C + blue-C + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale + * + * But cHRM records only white-x and white-y, so we have lost the white scale + * factor: + * + * white-C = white-c*white-scale + * + * To handle this the inverse transformation makes an arbitrary assumption + * about white-scale: + * + * Assume: white-Y = 1.0 + * Hence: white-scale = 1/white-y + * Or: red-Y + green-Y + blue-Y = 1.0 + * + * Notice the last statement of the assumption gives an equation in three of + * the nine values we want to calculate. 8 more equations come from the + * above routine as summarised at the top above (the chromaticity + * calculation): + * + * Given: color-x = color-X / (color-X + color-Y + color-Z) + * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 + * + * This is 9 simultaneous equations in the 9 variables "color-C" and can be + * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix + * determinants, however this is not as bad as it seems because only 28 of + * the total of 90 terms in the various matrices are non-zero. Nevertheless + * Cramer's rule is notoriously numerically unstable because the determinant + * calculation involves the difference of large, but similar, numbers. It is + * difficult to be sure that the calculation is stable for real world values + * and it is certain that it becomes unstable where the end points are close + * together. + * + * So this code uses the perhaps slightly less optimal but more + * understandable and totally obvious approach of calculating color-scale. + * + * This algorithm depends on the precision in white-scale and that is + * (1/white-y), so we can immediately see that as white-y approaches 0 the + * accuracy inherent in the cHRM chunk drops off substantially. + * + * libpng arithmetic: a simple inversion of the above equations + * ------------------------------------------------------------ + * + * white_scale = 1/white-y + * white-X = white-x * white-scale + * white-Y = 1.0 + * white-Z = (1 - white-x - white-y) * white_scale + * + * white-C = red-C + green-C + blue-C + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale + * + * This gives us three equations in (red-scale,green-scale,blue-scale) where + * all the coefficients are now known: + * + * red-x*red-scale + green-x*green-scale + blue-x*blue-scale + * = white-x/white-y + * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 + * red-z*red-scale + green-z*green-scale + blue-z*blue-scale + * = (1 - white-x - white-y)/white-y + * + * In the last equation color-z is (1 - color-x - color-y) so we can add all + * three equations together to get an alternative third: + * + * red-scale + green-scale + blue-scale = 1/white-y = white-scale + * + * So now we have a Cramer's rule solution where the determinants are just + * 3x3 - far more tractable. Unfortunately 3x3 determinants still involve + * multiplication of three coefficients so we can't guarantee to avoid + * overflow in the libpng fixed point representation. Using Cramer's rule in + * floating point is probably a good choice here, but it's not an option for + * fixed point. Instead proceed to simplify the first two equations by + * eliminating what is likely to be the largest value, blue-scale: + * + * blue-scale = white-scale - red-scale - green-scale + * + * Hence: + * + * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = + * (white-x - blue-x)*white-scale + * + * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = + * 1 - blue-y*white-scale + * + * And now we can trivially solve for (red-scale,green-scale): + * + * green-scale = + * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale + * ----------------------------------------------------------- + * green-x - blue-x + * + * red-scale = + * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale + * --------------------------------------------------------- + * red-y - blue-y + * + * Hence: + * + * red-scale = + * ( (green-x - blue-x) * (white-y - blue-y) - + * (green-y - blue-y) * (white-x - blue-x) ) / white-y + * ------------------------------------------------------------------------- + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) + * + * green-scale = + * ( (red-y - blue-y) * (white-x - blue-x) - + * (red-x - blue-x) * (white-y - blue-y) ) / white-y + * ------------------------------------------------------------------------- + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) + * + * Accuracy: + * The input values have 5 decimal digits of accuracy. + * + * In the previous implementation the values were all in the range 0 < value + * < 1, so simple products are in the same range but may need up to 10 + * decimal digits to preserve the original precision and avoid underflow. + * Because we are using a 32-bit signed representation we cannot match this; + * the best is a little over 9 decimal digits, less than 10. + * + * This range has now been extended to allow values up to 1.1, or 110,000 in + * fixed point. + * + * The approach used here is to preserve the maximum precision within the + * signed representation. Because the red-scale calculation above uses the + * difference between two products of values that must be in the range + * -1.1..+1.1 it is sufficient to divide the product by 8; + * ceil(121,000/32767*2). The factor is irrelevant in the calculation + * because it is applied to both numerator and denominator. + * + * Note that the values of the differences of the products of the + * chromaticities in the above equations tend to be small, for example for + * the sRGB chromaticities they are: + * + * red numerator: -0.04751 + * green numerator: -0.08788 + * denominator: -0.2241 (without white-y multiplication) + * + * The resultant Y coefficients from the chromaticities of some widely used + * color space definitions are (to 15 decimal places): + * + * sRGB + * 0.212639005871510 0.715168678767756 0.072192315360734 + * Kodak ProPhoto + * 0.288071128229293 0.711843217810102 0.000085653960605 + * Adobe RGB + * 0.297344975250536 0.627363566255466 0.075291458493998 + * Adobe Wide Gamut RGB + * 0.258728243040113 0.724682314948566 0.016589442011321 + */ + { + int error = 0; + + /* By the argument above overflow should be impossible here, however the + * code now simply returns a failure code. The xy subtracts in the + * arguments to png_muldiv are *not* checked for overflow because the + * checks at the start guarantee they are in the range 0..110000 and + * png_fixed_point is a 32-bit signed number. + */ + if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 8) == 0) + return 1; + if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 8) == + 0) + return 1; + denominator = png_fp_sub(left, right, &error); + if (error) return 1; + + /* Now find the red numerator. */ + if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 8) == 0) + return 1; + if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 8) == + 0) + return 1; + + /* Overflow is possible here and it indicates an extreme set of PNG cHRM + * chunk values. This calculation actually returns the reciprocal of the + * scale value because this allows us to delay the multiplication of + * white-y into the denominator, which tends to produce a small number. + */ + if (png_muldiv(&red_inverse, xy->whitey, denominator, + png_fp_sub(left, right, &error)) == 0 || error || + red_inverse <= xy->whitey /* r+g+b scales = white scale */) + return 1; + + /* Similarly for green_inverse: */ + if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 8) == 0) + return 1; + if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 8) == 0) + return 1; + if (png_muldiv(&green_inverse, xy->whitey, denominator, + png_fp_sub(left, right, &error)) == 0 || error || + green_inverse <= xy->whitey) + return 1; + + /* And the blue scale, the checks above guarantee this can't overflow but + * it can still produce 0 for extreme cHRM values. + */ + blue_scale = png_fp_sub(png_fp_sub(png_reciprocal(xy->whitey), + png_reciprocal(red_inverse), &error), + png_reciprocal(green_inverse), &error); + if (error || blue_scale <= 0) + return 1; + } + + /* And fill in the png_XYZ. Again the subtracts are safe because of the + * checks on the xy values at the start (the subtracts just calculate the + * corresponding z values.) + */ + if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) + return 1; + if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) + return 1; + if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, + red_inverse) == 0) + return 1; + + if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) + return 1; + if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) + return 1; + if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, + green_inverse) == 0) + return 1; + + if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) + return 1; + if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) + return 1; + if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, + PNG_FP_1) == 0) + return 1; + + return 0; /*success*/ +} +#endif /* COLORSPACE */ + +#ifdef PNG_READ_iCCP_SUPPORTED +/* Error message generation */ +static char +png_icc_tag_char(png_uint_32 byte) +{ + byte &= 0xff; + if (byte >= 32 && byte <= 126) + return (char)byte; + else + return '?'; +} + +static void +png_icc_tag_name(char *name, png_uint_32 tag) +{ + name[0] = '\''; + name[1] = png_icc_tag_char(tag >> 24); + name[2] = png_icc_tag_char(tag >> 16); + name[3] = png_icc_tag_char(tag >> 8); + name[4] = png_icc_tag_char(tag ); + name[5] = '\''; +} + +static int +is_ICC_signature_char(png_alloc_size_t it) +{ + return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || + (it >= 97 && it <= 122); +} + +static int +is_ICC_signature(png_alloc_size_t it) +{ + return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && + is_ICC_signature_char((it >> 16) & 0xff) && + is_ICC_signature_char((it >> 8) & 0xff) && + is_ICC_signature_char(it & 0xff); +} + +static int +png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name, + png_alloc_size_t value, png_const_charp reason) +{ + size_t pos; + char message[196]; /* see below for calculation */ + + pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ + pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ + pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ + if (is_ICC_signature(value) != 0) + { + /* So 'value' is at most 4 bytes and the following cast is safe */ + png_icc_tag_name(message+pos, (png_uint_32)value); + pos += 6; /* total +8; less than the else clause */ + message[pos++] = ':'; + message[pos++] = ' '; + } +# ifdef PNG_WARNINGS_SUPPORTED + else + { + char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ + + pos = png_safecat(message, (sizeof message), pos, + png_format_number(number, number+(sizeof number), + PNG_NUMBER_FORMAT_x, value)); + pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ + } +# endif + /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ + pos = png_safecat(message, (sizeof message), pos, reason); + PNG_UNUSED(pos) + + png_chunk_benign_error(png_ptr, message); + + return 0; +} + +/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value + * is XYZ(0.9642,1.0,0.8249), which scales to: + * + * (63189.8112, 65536, 54060.6464) + */ +static const png_byte D50_nCIEXYZ[12] = + { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; + +static int /* bool */ +icc_check_length(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length) +{ + if (profile_length < 132) + return png_icc_profile_error(png_ptr, name, profile_length, "too short"); + return 1; +} + +int /* PRIVATE */ +png_icc_check_length(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length) +{ + if (!icc_check_length(png_ptr, name, profile_length)) + return 0; + + /* This needs to be here because the 'normal' check is in + * png_decompress_chunk, yet this happens after the attempt to + * png_malloc_base the required data. We only need this on read; on write + * the caller supplies the profile buffer so libpng doesn't allocate it. See + * the call to icc_check_length below (the write case). + */ + if (profile_length > png_chunk_max(png_ptr)) + return png_icc_profile_error(png_ptr, name, profile_length, + "profile too long"); + + return 1; +} + +int /* PRIVATE */ +png_icc_check_header(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length, + png_const_bytep profile/* first 132 bytes only */, int color_type) +{ + png_uint_32 temp; + + /* Length check; this cannot be ignored in this code because profile_length + * is used later to check the tag table, so even if the profile seems over + * long profile_length from the caller must be correct. The caller can fix + * this up on read or write by just passing in the profile header length. + */ + temp = png_get_uint_32(profile); + if (temp != profile_length) + return png_icc_profile_error(png_ptr, name, temp, + "length does not match profile"); + + temp = (png_uint_32) (*(profile+8)); + if (temp > 3 && (profile_length & 3)) + return png_icc_profile_error(png_ptr, name, profile_length, + "invalid length"); + + temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ + if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ + profile_length < 132+12*temp) /* truncated tag table */ + return png_icc_profile_error(png_ptr, name, temp, + "tag count too large"); + + /* The 'intent' must be valid or we can't store it, ICC limits the intent to + * 16 bits. + */ + temp = png_get_uint_32(profile+64); + if (temp >= 0xffff) /* The ICC limit */ + return png_icc_profile_error(png_ptr, name, temp, + "invalid rendering intent"); + + /* This is just a warning because the profile may be valid in future + * versions. + */ + if (temp >= PNG_sRGB_INTENT_LAST) + (void)png_icc_profile_error(png_ptr, name, temp, + "intent outside defined range"); + + /* At this point the tag table can't be checked because it hasn't necessarily + * been loaded; however, various header fields can be checked. These checks + * are for values permitted by the PNG spec in an ICC profile; the PNG spec + * restricts the profiles that can be passed in an iCCP chunk (they must be + * appropriate to processing PNG data!) + */ + + /* Data checks (could be skipped). These checks must be independent of the + * version number; however, the version number doesn't accommodate changes in + * the header fields (just the known tags and the interpretation of the + * data.) + */ + temp = png_get_uint_32(profile+36); /* signature 'ascp' */ + if (temp != 0x61637370) + return png_icc_profile_error(png_ptr, name, temp, + "invalid signature"); + + /* Currently the PCS illuminant/adopted white point (the computational + * white point) are required to be D50, + * however the profile contains a record of the illuminant so perhaps ICC + * expects to be able to change this in the future (despite the rationale in + * the introduction for using a fixed PCS adopted white.) Consequently the + * following is just a warning. + */ + if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) + (void)png_icc_profile_error(png_ptr, name, 0/*no tag value*/, + "PCS illuminant is not D50"); + + /* The PNG spec requires this: + * "If the iCCP chunk is present, the image samples conform to the colour + * space represented by the embedded ICC profile as defined by the + * International Color Consortium [ICC]. The colour space of the ICC profile + * shall be an RGB colour space for colour images (PNG colour types 2, 3, and + * 6), or a greyscale colour space for greyscale images (PNG colour types 0 + * and 4)." + * + * This checking code ensures the embedded profile (on either read or write) + * conforms to the specification requirements. Notice that an ICC 'gray' + * color-space profile contains the information to transform the monochrome + * data to XYZ or L*a*b (according to which PCS the profile uses) and this + * should be used in preference to the standard libpng K channel replication + * into R, G and B channels. + * + * Previously it was suggested that an RGB profile on grayscale data could be + * handled. However it is clear that using an RGB profile in this context + * must be an error - there is no specification of what it means. Thus it is + * almost certainly more correct to ignore the profile. + */ + temp = png_get_uint_32(profile+16); /* data colour space field */ + switch (temp) + { + case 0x52474220: /* 'RGB ' */ + if ((color_type & PNG_COLOR_MASK_COLOR) == 0) + return png_icc_profile_error(png_ptr, name, temp, + "RGB color space not permitted on grayscale PNG"); + break; + + case 0x47524159: /* 'GRAY' */ + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + return png_icc_profile_error(png_ptr, name, temp, + "Gray color space not permitted on RGB PNG"); + break; + + default: + return png_icc_profile_error(png_ptr, name, temp, + "invalid ICC profile color space"); + } + + /* It is up to the application to check that the profile class matches the + * application requirements; the spec provides no guidance, but it's pretty + * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer + * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these + * cases. Issue an error for device link or abstract profiles - these don't + * contain the records necessary to transform the color-space to anything + * other than the target device (and not even that for an abstract profile). + * Profiles of these classes may not be embedded in images. + */ + temp = png_get_uint_32(profile+12); /* profile/device class */ + switch (temp) + { + case 0x73636e72: /* 'scnr' */ + case 0x6d6e7472: /* 'mntr' */ + case 0x70727472: /* 'prtr' */ + case 0x73706163: /* 'spac' */ + /* All supported */ + break; + + case 0x61627374: /* 'abst' */ + /* May not be embedded in an image */ + return png_icc_profile_error(png_ptr, name, temp, + "invalid embedded Abstract ICC profile"); + + case 0x6c696e6b: /* 'link' */ + /* DeviceLink profiles cannot be interpreted in a non-device specific + * fashion, if an app uses the AToB0Tag in the profile the results are + * undefined unless the result is sent to the intended device, + * therefore a DeviceLink profile should not be found embedded in a + * PNG. + */ + return png_icc_profile_error(png_ptr, name, temp, + "unexpected DeviceLink ICC profile class"); + + case 0x6e6d636c: /* 'nmcl' */ + /* A NamedColor profile is also device specific, however it doesn't + * contain an AToB0 tag that is open to misinterpretation. Almost + * certainly it will fail the tests below. + */ + (void)png_icc_profile_error(png_ptr, name, temp, + "unexpected NamedColor ICC profile class"); + break; + + default: + /* To allow for future enhancements to the profile accept unrecognized + * profile classes with a warning, these then hit the test below on the + * tag content to ensure they are backward compatible with one of the + * understood profiles. + */ + (void)png_icc_profile_error(png_ptr, name, temp, + "unrecognized ICC profile class"); + break; + } + + /* For any profile other than a device link one the PCS must be encoded + * either in XYZ or Lab. + */ + temp = png_get_uint_32(profile+20); + switch (temp) + { + case 0x58595a20: /* 'XYZ ' */ + case 0x4c616220: /* 'Lab ' */ + break; + + default: + return png_icc_profile_error(png_ptr, name, temp, + "unexpected ICC PCS encoding"); + } + + return 1; +} + +int /* PRIVATE */ +png_icc_check_tag_table(png_const_structrp png_ptr, png_const_charp name, + png_uint_32 profile_length, + png_const_bytep profile /* header plus whole tag table */) +{ + png_uint_32 tag_count = png_get_uint_32(profile+128); + png_uint_32 itag; + png_const_bytep tag = profile+132; /* The first tag */ + + /* First scan all the tags in the table and add bits to the icc_info value + * (temporarily in 'tags'). + */ + for (itag=0; itag < tag_count; ++itag, tag += 12) + { + png_uint_32 tag_id = png_get_uint_32(tag+0); + png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ + png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ + + /* The ICC specification does not exclude zero length tags, therefore the + * start might actually be anywhere if there is no data, but this would be + * a clear abuse of the intent of the standard so the start is checked for + * being in range. All defined tag types have an 8 byte header - a 4 byte + * type signature then 0. + */ + + /* This is a hard error; potentially it can cause read outside the + * profile. + */ + if (tag_start > profile_length || tag_length > profile_length - tag_start) + return png_icc_profile_error(png_ptr, name, tag_id, + "ICC profile tag outside profile"); + + if ((tag_start & 3) != 0) + { + /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is + * only a warning here because libpng does not care about the + * alignment. + */ + (void)png_icc_profile_error(png_ptr, name, tag_id, + "ICC profile tag start not a multiple of 4"); + } + } + + return 1; /* success, maybe with warnings */ +} +#endif /* READ_iCCP */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +#if (defined PNG_READ_mDCV_SUPPORTED) || (defined PNG_READ_cHRM_SUPPORTED) +static int +have_chromaticities(png_const_structrp png_ptr) +{ + /* Handle new PNGv3 chunks and the precedence rules to determine whether + * png_struct::chromaticities must be processed. Only required for RGB to + * gray. + * + * mDCV: this is the mastering colour space and it is independent of the + * encoding so it needs to be used regardless of the encoded space. + * + * cICP: first in priority but not yet implemented - the chromaticities come + * from the 'primaries'. + * + * iCCP: not supported by libpng (so ignored) + * + * sRGB: the defaults match sRGB + * + * cHRM: calculate the coefficients + */ +# ifdef PNG_READ_mDCV_SUPPORTED + if (png_has_chunk(png_ptr, mDCV)) + return 1; +# define check_chromaticities 1 +# endif /*mDCV*/ + +# ifdef PNG_READ_sRGB_SUPPORTED + if (png_has_chunk(png_ptr, sRGB)) + return 0; +# endif /*sRGB*/ + +# ifdef PNG_READ_cHRM_SUPPORTED + if (png_has_chunk(png_ptr, cHRM)) + return 1; +# define check_chromaticities 1 +# endif /*cHRM*/ + + return 0; /* sRGB defaults */ +} +#endif /* READ_mDCV || READ_cHRM */ + +void /* PRIVATE */ +png_set_rgb_coefficients(png_structrp png_ptr) +{ + /* Set the rgb_to_gray coefficients from the colorspace if available. Note + * that '_set' means that png_rgb_to_gray was called **and** it successfully + * set up the coefficients. + */ + if (png_ptr->rgb_to_gray_coefficients_set == 0) + { +# if check_chromaticities + png_XYZ xyz; + + if (have_chromaticities(png_ptr) && + png_XYZ_from_xy(&xyz, &png_ptr->chromaticities) == 0) + { + /* png_set_rgb_to_gray has not set the coefficients, get them from the + * Y * values of the colorspace colorants. + */ + png_fixed_point r = xyz.red_Y; + png_fixed_point g = xyz.green_Y; + png_fixed_point b = xyz.blue_Y; + png_fixed_point total = r+g+b; + + if (total > 0 && + r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && + g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && + b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && + r+g+b <= 32769) + { + /* We allow 0 coefficients here. r+g+b may be 32769 if two or + * all of the coefficients were rounded up. Handle this by + * reducing the *largest* coefficient by 1; this matches the + * approach used for the default coefficients in pngrtran.c + */ + int add = 0; + + if (r+g+b > 32768) + add = -1; + else if (r+g+b < 32768) + add = 1; + + if (add != 0) + { + if (g >= r && g >= b) + g += add; + else if (r >= g && r >= b) + r += add; + else + b += add; + } + + /* Check for an internal error. */ + if (r+g+b != 32768) + png_error(png_ptr, + "internal error handling cHRM coefficients"); + + else + { + png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; + png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; + } + } + } + else +# endif /* check_chromaticities */ + { + /* Use the historical REC 709 (etc) values: */ + png_ptr->rgb_to_gray_red_coeff = 6968; + png_ptr->rgb_to_gray_green_coeff = 23434; + /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ + } + } +} +#endif /* READ_RGB_TO_GRAY */ + +void /* PRIVATE */ +png_check_IHDR(png_const_structrp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + int error = 0; + + /* Check for width and height valid values */ + if (width == 0) + { + png_warning(png_ptr, "Image width is zero in IHDR"); + error = 1; + } + + if (width > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image width in IHDR"); + error = 1; + } + + /* The bit mask on the first line below must be at least as big as a + * png_uint_32. "~7U" is not adequate on 16-bit systems because it will + * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the + * type of the result at least as bit (in bits) as the RHS of the > operator + * which also avoids a common warning on 64-bit systems that the comparison + * of (png_uint_32) against the constant value on the RHS will always be + * false. + */ + if (((width + 7) & ~(png_alloc_size_t)7) > + (((PNG_SIZE_MAX + - 48 /* big_row_buf hack */ + - 1) /* filter byte */ + / 8) /* 8-byte RGBA pixels */ + - 1)) /* extra max_pixel_depth pad */ + { + /* The size of the row must be within the limits of this architecture. + * Because the read code can perform arbitrary transformations the + * maximum size is checked here. Because the code in png_read_start_row + * adds extra space "for safety's sake" in several places a conservative + * limit is used here. + * + * NOTE: it would be far better to check the size that is actually used, + * but the effect in the real world is minor and the changes are more + * extensive, therefore much more dangerous and much more difficult to + * write in a way that avoids compiler warnings. + */ + png_warning(png_ptr, "Image width is too large for this architecture"); + error = 1; + } + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (width > png_ptr->user_width_max) +#else + if (width > PNG_USER_WIDTH_MAX) +#endif + { + png_warning(png_ptr, "Image width exceeds user limit in IHDR"); + error = 1; + } + + if (height == 0) + { + png_warning(png_ptr, "Image height is zero in IHDR"); + error = 1; + } + + if (height > PNG_UINT_31_MAX) + { + png_warning(png_ptr, "Invalid image height in IHDR"); + error = 1; + } + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (height > png_ptr->user_height_max) +#else + if (height > PNG_USER_HEIGHT_MAX) +#endif + { + png_warning(png_ptr, "Image height exceeds user limit in IHDR"); + error = 1; + } + + /* Check other values */ + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && + bit_depth != 8 && bit_depth != 16) + { + png_warning(png_ptr, "Invalid bit depth in IHDR"); + error = 1; + } + + if (color_type < 0 || color_type == 1 || + color_type == 5 || color_type > 6) + { + png_warning(png_ptr, "Invalid color type in IHDR"); + error = 1; + } + + if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || + ((color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) + { + png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); + error = 1; + } + + if (interlace_type >= PNG_INTERLACE_LAST) + { + png_warning(png_ptr, "Unknown interlace method in IHDR"); + error = 1; + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Unknown compression method in IHDR"); + error = 1; + } + +#ifdef PNG_MNG_FEATURES_SUPPORTED + /* Accept filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not read a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && + png_ptr->mng_features_permitted != 0) + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + + if (filter_type != PNG_FILTER_TYPE_BASE) + { + if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + { + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } + + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) + { + png_warning(png_ptr, "Invalid filter method in IHDR"); + error = 1; + } + } + +#else + if (filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Unknown filter method in IHDR"); + error = 1; + } +#endif + + if (error == 1) + png_error(png_ptr, "Invalid IHDR data"); +} + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* ASCII to fp functions */ +/* Check an ASCII formatted floating point value, see the more detailed + * comments in pngpriv.h + */ +/* The following is used internally to preserve the sticky flags */ +#define png_fp_add(state, flags) ((state) |= (flags)) +#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) + +int /* PRIVATE */ +png_check_fp_number(png_const_charp string, size_t size, int *statep, + size_t *whereami) +{ + int state = *statep; + size_t i = *whereami; + + while (i < size) + { + int type; + /* First find the type of the next character */ + switch (string[i]) + { + case 43: type = PNG_FP_SAW_SIGN; break; + case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; + case 46: type = PNG_FP_SAW_DOT; break; + case 48: type = PNG_FP_SAW_DIGIT; break; + case 49: case 50: case 51: case 52: + case 53: case 54: case 55: case 56: + case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; + case 69: + case 101: type = PNG_FP_SAW_E; break; + default: goto PNG_FP_End; + } + + /* Now deal with this type according to the current + * state, the type is arranged to not overlap the + * bits of the PNG_FP_STATE. + */ + switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) + { + case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: + if ((state & PNG_FP_SAW_ANY) != 0) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, type); + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DOT: + /* Ok as trailer, ok as lead of fraction. */ + if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ + goto PNG_FP_End; + + else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ + png_fp_add(state, type); + + else + png_fp_set(state, PNG_FP_FRACTION | type); + + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: + if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + + png_fp_add(state, type | PNG_FP_WAS_VALID); + + break; + + case PNG_FP_INTEGER + PNG_FP_SAW_E: + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: + goto PNG_FP_End; ** no sign in fraction */ + + /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: + goto PNG_FP_End; ** Because SAW_DOT is always set */ + + case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: + png_fp_add(state, type | PNG_FP_WAS_VALID); + break; + + case PNG_FP_FRACTION + PNG_FP_SAW_E: + /* This is correct because the trailing '.' on an + * integer is handled above - so we can only get here + * with the sequence ".E" (with no preceding digits). + */ + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: + if ((state & PNG_FP_SAW_ANY) != 0) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, PNG_FP_SAW_SIGN); + + break; + + /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: + goto PNG_FP_End; */ + + case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); + + break; + + /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: + goto PNG_FP_End; */ + + default: goto PNG_FP_End; /* I.e. break 2 */ + } + + /* The character seems ok, continue. */ + ++i; + } + +PNG_FP_End: + /* Here at the end, update the state and return the correct + * return code. + */ + *statep = state; + *whereami = i; + + return (state & PNG_FP_SAW_DIGIT) != 0; +} + + +/* The same but for a complete string. */ +int +png_check_fp_string(png_const_charp string, size_t size) +{ + int state = 0; + size_t char_index = 0; + + if (png_check_fp_number(string, size, &state, &char_index) != 0 && + (char_index == size || string[char_index] == 0)) + return state /* must be non-zero - see above */; + + return 0; /* i.e. fail */ +} +#endif /* pCAL || sCAL */ + +#ifdef PNG_sCAL_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +/* Utility used below - a simple accurate power of ten from an integral + * exponent. + */ +static double +png_pow10(int power) +{ + int recip = 0; + double d = 1; + + /* Handle negative exponent with a reciprocal at the end because + * 10 is exact whereas .1 is inexact in base 2 + */ + if (power < 0) + { + if (power < DBL_MIN_10_EXP) return 0; + recip = 1; power = -power; + } + + if (power > 0) + { + /* Decompose power bitwise. */ + double mult = 10; + do + { + if (power & 1) d *= mult; + mult *= mult; + power >>= 1; + } + while (power > 0); + + if (recip != 0) d = 1/d; + } + /* else power is 0 and d is 1 */ + + return d; +} + +/* Function to format a floating point value in ASCII with a given + * precision. + */ +void /* PRIVATE */ +png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, + double fp, unsigned int precision) +{ + /* We use standard functions from math.h, but not printf because + * that would require stdio. The caller must supply a buffer of + * sufficient size or we will png_error. The tests on size and + * the space in ascii[] consumed are indicated below. + */ + if (precision < 1) + precision = DBL_DIG; + + /* Enforce the limit of the implementation precision too. */ + if (precision > DBL_DIG+1) + precision = DBL_DIG+1; + + /* Basic sanity checks */ + if (size >= precision+5) /* See the requirements below. */ + { + if (fp < 0) + { + fp = -fp; + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ + --size; + } + + if (fp >= DBL_MIN && fp <= DBL_MAX) + { + int exp_b10; /* A base 10 exponent */ + double base; /* 10^exp_b10 */ + + /* First extract a base 10 exponent of the number, + * the calculation below rounds down when converting + * from base 2 to base 10 (multiply by log10(2) - + * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to + * be increased. Note that the arithmetic shift + * performs a floor() unlike C arithmetic - using a + * C multiply would break the following for negative + * exponents. + */ + (void)frexp(fp, &exp_b10); /* exponent to base 2 */ + + exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ + + /* Avoid underflow here. */ + base = png_pow10(exp_b10); /* May underflow */ + + while (base < DBL_MIN || base < fp) + { + /* And this may overflow. */ + double test = png_pow10(exp_b10+1); + + if (test <= DBL_MAX) + { + ++exp_b10; base = test; + } + + else + break; + } + + /* Normalize fp and correct exp_b10, after this fp is in the + * range [.1,1) and exp_b10 is both the exponent and the digit + * *before* which the decimal point should be inserted + * (starting with 0 for the first digit). Note that this + * works even if 10^exp_b10 is out of range because of the + * test on DBL_MAX above. + */ + fp /= base; + while (fp >= 1) + { + fp /= 10; ++exp_b10; + } + + /* Because of the code above fp may, at this point, be + * less than .1, this is ok because the code below can + * handle the leading zeros this generates, so no attempt + * is made to correct that here. + */ + + { + unsigned int czero, clead, cdigits; + char exponent[10]; + + /* Allow up to two leading zeros - this will not lengthen + * the number compared to using E-n. + */ + if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ + { + czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */ + exp_b10 = 0; /* Dot added below before first output. */ + } + else + czero = 0; /* No zeros to add */ + + /* Generate the digit list, stripping trailing zeros and + * inserting a '.' before a digit if the exponent is 0. + */ + clead = czero; /* Count of leading zeros */ + cdigits = 0; /* Count of digits in list. */ + + do + { + double d; + + fp *= 10; + /* Use modf here, not floor and subtract, so that + * the separation is done in one step. At the end + * of the loop don't break the number into parts so + * that the final digit is rounded. + */ + if (cdigits+czero+1 < precision+clead) + fp = modf(fp, &d); + + else + { + d = floor(fp + .5); + + if (d > 9) + { + /* Rounding up to 10, handle that here. */ + if (czero > 0) + { + --czero; d = 1; + if (cdigits == 0) --clead; + } + else + { + while (cdigits > 0 && d > 9) + { + int ch = *--ascii; + + if (exp_b10 != (-1)) + ++exp_b10; + + else if (ch == 46) + { + ch = *--ascii; ++size; + /* Advance exp_b10 to '1', so that the + * decimal point happens after the + * previous digit. + */ + exp_b10 = 1; + } + + --cdigits; + d = ch - 47; /* I.e. 1+(ch-48) */ + } + + /* Did we reach the beginning? If so adjust the + * exponent but take into account the leading + * decimal point. + */ + if (d > 9) /* cdigits == 0 */ + { + if (exp_b10 == (-1)) + { + /* Leading decimal point (plus zeros?), if + * we lose the decimal point here it must + * be reentered below. + */ + int ch = *--ascii; + + if (ch == 46) + { + ++size; exp_b10 = 1; + } + + /* Else lost a leading zero, so 'exp_b10' is + * still ok at (-1) + */ + } + else + ++exp_b10; + + /* In all cases we output a '1' */ + d = 1; + } + } + } + fp = 0; /* Guarantees termination below. */ + } + + if (d == 0) + { + ++czero; + if (cdigits == 0) ++clead; + } + else + { + /* Included embedded zeros in the digit count. */ + cdigits += czero - clead; + clead = 0; + + while (czero > 0) + { + /* exp_b10 == (-1) means we just output the decimal + * place - after the DP don't adjust 'exp_b10' any + * more! + */ + if (exp_b10 != (-1)) + { + if (exp_b10 == 0) + { + *ascii++ = 46; --size; + } + /* PLUS 1: TOTAL 4 */ + --exp_b10; + } + *ascii++ = 48; --czero; + } + + if (exp_b10 != (-1)) + { + if (exp_b10 == 0) + { + *ascii++ = 46; --size; /* counted above */ + } + + --exp_b10; + } + *ascii++ = (char)(48 + (int)d); ++cdigits; + } + } + while (cdigits+czero < precision+clead && fp > DBL_MIN); + + /* The total output count (max) is now 4+precision */ + + /* Check for an exponent, if we don't need one we are + * done and just need to terminate the string. At this + * point, exp_b10==(-1) is effectively a flag: it got + * to '-1' because of the decrement, after outputting + * the decimal point above. (The exponent required is + * *not* -1.) + */ + if (exp_b10 >= (-1) && exp_b10 <= 2) + { + /* The following only happens if we didn't output the + * leading zeros above for negative exponent, so this + * doesn't add to the digit requirement. Note that the + * two zeros here can only be output if the two leading + * zeros were *not* output, so this doesn't increase + * the output count. + */ + while (exp_b10-- > 0) *ascii++ = 48; + + *ascii = 0; + + /* Total buffer requirement (including the '\0') is + * 5+precision - see check at the start. + */ + return; + } + + /* Here if an exponent is required, adjust size for + * the digits we output but did not count. The total + * digit output here so far is at most 1+precision - no + * decimal point and no leading or trailing zeros have + * been output. + */ + size -= cdigits; + + *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */ + + /* The following use of an unsigned temporary avoids ambiguities in + * the signed arithmetic on exp_b10 and permits GCC at least to do + * better optimization. + */ + { + unsigned int uexp_b10; + + if (exp_b10 < 0) + { + *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */ + uexp_b10 = 0U-exp_b10; + } + + else + uexp_b10 = 0U+exp_b10; + + cdigits = 0; + + while (uexp_b10 > 0) + { + exponent[cdigits++] = (char)(48 + uexp_b10 % 10); + uexp_b10 /= 10; + } + } + + /* Need another size check here for the exponent digits, so + * this need not be considered above. + */ + if (size > cdigits) + { + while (cdigits > 0) *ascii++ = exponent[--cdigits]; + + *ascii = 0; + + return; + } + } + } + else if (!(fp >= DBL_MIN)) + { + *ascii++ = 48; /* '0' */ + *ascii = 0; + return; + } + else + { + *ascii++ = 105; /* 'i' */ + *ascii++ = 110; /* 'n' */ + *ascii++ = 102; /* 'f' */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} +# endif /* FLOATING_POINT */ + +# ifdef PNG_FIXED_POINT_SUPPORTED +/* Function to format a fixed point value in ASCII. + */ +void /* PRIVATE */ +png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, + size_t size, png_fixed_point fp) +{ + /* Require space for 10 decimal digits, a decimal point, a minus sign and a + * trailing \0, 13 characters: + */ + if (size > 12) + { + png_uint_32 num; + + /* Avoid overflow here on the minimum integer. */ + if (fp < 0) + { + *ascii++ = 45; num = (png_uint_32)(-fp); + } + else + num = (png_uint_32)fp; + + if (num <= 0x80000000) /* else overflowed */ + { + unsigned int ndigits = 0, first = 16 /* flag value */; + char digits[10] = {0}; + + while (num) + { + /* Split the low digit off num: */ + unsigned int tmp = num/10; + num -= tmp*10; + digits[ndigits++] = (char)(48 + num); + /* Record the first non-zero digit, note that this is a number + * starting at 1, it's not actually the array index. + */ + if (first == 16 && num > 0) + first = ndigits; + num = tmp; + } + + if (ndigits > 0) + { + while (ndigits > 5) *ascii++ = digits[--ndigits]; + /* The remaining digits are fractional digits, ndigits is '5' or + * smaller at this point. It is certainly not zero. Check for a + * non-zero fractional digit: + */ + if (first <= 5) + { + unsigned int i; + *ascii++ = 46; /* decimal point */ + /* ndigits may be <5 for small numbers, output leading zeros + * then ndigits digits to first: + */ + i = 5; + while (ndigits < i) + { + *ascii++ = 48; --i; + } + while (ndigits >= first) *ascii++ = digits[--ndigits]; + /* Don't output the trailing zeros! */ + } + } + else + *ascii++ = 48; + + /* And null terminate the string: */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} +# endif /* FIXED_POINT */ +#endif /* SCAL */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ + (defined(PNG_sCAL_SUPPORTED) && \ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) +png_fixed_point +png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) +{ + double r = floor(100000 * fp + .5); + + if (r > 2147483647. || r < -2147483648.) + png_fixed_error(png_ptr, text); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(text) +# endif + + return (png_fixed_point)r; +} +#endif + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ + (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED)) +png_uint_32 +png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text) +{ + double r = floor(10000 * fp + .5); + + if (r > 2147483647. || r < 0) + png_fixed_error(png_ptr, text); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(text) +# endif + + return (png_uint_32)r; +} +#endif + + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) +/* muldiv functions */ +/* This API takes signed arguments and rounds the result to the nearest + * integer (or, for a fixed point number - the standard argument - to + * the nearest .00001). Overflow and divide by zero are signalled in + * the result, a boolean - true on success, false on overflow. + */ +int /* PRIVATE */ +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, + png_int_32 divisor) +{ + /* Return a * times / divisor, rounded. */ + if (divisor != 0) + { + if (a == 0 || times == 0) + { + *res = 0; + return 1; + } + else + { +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a; + r *= times; + r /= divisor; + r = floor(r+.5); + + /* A png_fixed_point is a 32-bit integer. */ + if (r <= 2147483647. && r >= -2147483648.) + { + *res = (png_fixed_point)r; + return 1; + } +#else + int negative = 0; + png_uint_32 A, T, D; + png_uint_32 s16, s32, s00; + + if (a < 0) + negative = 1, A = -a; + else + A = a; + + if (times < 0) + negative = !negative, T = -times; + else + T = times; + + if (divisor < 0) + negative = !negative, D = -divisor; + else + D = divisor; + + /* Following can't overflow because the arguments only + * have 31 bits each, however the result may be 32 bits. + */ + s16 = (A >> 16) * (T & 0xffff) + + (A & 0xffff) * (T >> 16); + /* Can't overflow because the a*times bit is only 30 + * bits at most. + */ + s32 = (A >> 16) * (T >> 16) + (s16 >> 16); + s00 = (A & 0xffff) * (T & 0xffff); + + s16 = (s16 & 0xffff) << 16; + s00 += s16; + + if (s00 < s16) + ++s32; /* carry */ + + if (s32 < D) /* else overflow */ + { + /* s32.s00 is now the 64-bit product, do a standard + * division, we know that s32 < D, so the maximum + * required shift is 31. + */ + int bitshift = 32; + png_fixed_point result = 0; /* NOTE: signed */ + + while (--bitshift >= 0) + { + png_uint_32 d32, d00; + + if (bitshift > 0) + d32 = D >> (32-bitshift), d00 = D << bitshift; + + else + d32 = 0, d00 = D; + + if (s32 > d32) + { + if (s00 < d00) --s32; /* carry */ + s32 -= d32, s00 -= d00, result += 1<= d00) + s32 = 0, s00 -= d00, result += 1<= (D >> 1)) + ++result; + + if (negative != 0) + result = -result; + + /* Check for overflow. */ + if ((negative != 0 && result <= 0) || + (negative == 0 && result >= 0)) + { + *res = result; + return 1; + } + } +#endif + } + } + + return 0; +} + +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ +png_fixed_point +png_reciprocal(png_fixed_point a) +{ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(1E10/a+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, 100000, 100000, a) != 0) + return res; +#endif + + return 0; /* error/overflow */ +} +#endif /* READ_GAMMA || COLORSPACE || INCH_CONVERSIONS || READ_pHYS */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* This is the shared test on whether a gamma value is 'significant' - whether + * it is worth doing gamma correction. + */ +int /* PRIVATE */ +png_gamma_significant(png_fixed_point gamma_val) +{ + /* sRGB: 1/2.2 == 0.4545(45) + * AdobeRGB: 1/(2+51/256) ~= 0.45471 5dp + * + * So the correction from AdobeRGB to sRGB (output) is: + * + * 2.2/(2+51/256) == 1.00035524 + * + * I.e. vanishingly small (<4E-4) but still detectable in 16-bit linear (+/- + * 23). Note that the Adobe choice seems to be something intended to give an + * exact number with 8 binary fractional digits - it is the closest to 2.2 + * that is possible a base 2 .8p representation. + */ + return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || + gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; +} + +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* A local convenience routine. */ +static png_fixed_point +png_product2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is a * b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* Should now be unused */ + double r = a * 1E-5; + r *= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, a, b, 100000) != 0) + return res; +#endif + + return 0; /* overflow */ +} +#endif /* FLOATING_ARITHMETIC */ + +png_fixed_point +png_reciprocal2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + if (a != 0 && b != 0) + { + double r = 1E15/a; + r /= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; + } +#else + /* This may overflow because the range of png_fixed_point isn't symmetric, + * but this API is only used for the product of file and screen gamma so it + * doesn't matter that the smallest number it can produce is 1/21474, not + * 1/100000 + */ + png_fixed_point res = png_product2(a, b); + + if (res != 0) + return png_reciprocal(res); +#endif + + return 0; /* overflow */ +} +#endif /* READ_GAMMA */ + +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* Fixed point gamma. + * + * The code to calculate the tables used below can be found in the shell script + * contrib/tools/intgamma.sh + * + * To calculate gamma this code implements fast log() and exp() calls using only + * fixed point arithmetic. This code has sufficient precision for either 8-bit + * or 16-bit sample values. + * + * The tables used here were calculated using simple 'bc' programs, but C double + * precision floating point arithmetic would work fine. + * + * 8-bit log table + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to + * 255, so it's the base 2 logarithm of a normalized 8-bit floating point + * mantissa. The numbers are 32-bit fractions. + */ +static const png_uint_32 +png_8bit_l2[128] = +{ + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, + 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, + 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, + 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, + 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, + 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, + 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, + 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, + 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, + 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, + 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, + 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, + 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, + 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, + 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, + 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, + 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, + 24347096U, 0U + +#if 0 + /* The following are the values for 16-bit tables - these work fine for the + * 8-bit conversions but produce very slightly larger errors in the 16-bit + * log (about 1.2 as opposed to 0.7 absolute error in the final value). To + * use these all the shifts below must be adjusted appropriately. + */ + 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, + 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, + 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, + 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, + 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, + 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, + 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, + 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, + 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, + 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, + 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, + 1119, 744, 372 +#endif +}; + +static png_int_32 +png_log8bit(unsigned int x) +{ + unsigned int lg2 = 0; + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, + * because the log is actually negate that means adding 1. The final + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 + * input), return -1 for the overflow (log 0) case, - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) + return -1; + + if ((x & 0xf0) == 0) + lg2 = 4, x <<= 4; + + if ((x & 0xc0) == 0) + lg2 += 2, x <<= 2; + + if ((x & 0x80) == 0) + lg2 += 1, x <<= 1; + + /* result is at most 19 bits, so this cast is safe: */ + return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); +} + +/* The above gives exact (to 16 binary places) log2 values for 8-bit images, + * for 16-bit images we use the most significant 8 bits of the 16-bit value to + * get an approximation then multiply the approximation by a correction factor + * determined by the remaining up to 8 bits. This requires an additional step + * in the 16-bit case. + * + * We want log2(value/65535), we have log2(v'/255), where: + * + * value = v' * 256 + v'' + * = v' * f + * + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less + * than 258. The final factor also needs to correct for the fact that our 8-bit + * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. + * + * This gives a final formula using a calculated value 'x' which is value/v' and + * scaling by 65536 to match the above table: + * + * log2(x/257) * 65536 + * + * Since these numbers are so close to '1' we can use simple linear + * interpolation between the two end values 256/257 (result -368.61) and 258/257 + * (result 367.179). The values used below are scaled by a further 64 to give + * 16-bit precision in the interpolation: + * + * Start (256): -23591 + * Zero (257): 0 + * End (258): 23499 + */ +#ifdef PNG_16BIT_SUPPORTED +static png_int_32 +png_log16bit(png_uint_32 x) +{ + unsigned int lg2 = 0; + + /* As above, but now the input has 16 bits. */ + if ((x &= 0xffff) == 0) + return -1; + + if ((x & 0xff00) == 0) + lg2 = 8, x <<= 8; + + if ((x & 0xf000) == 0) + lg2 += 4, x <<= 4; + + if ((x & 0xc000) == 0) + lg2 += 2, x <<= 2; + + if ((x & 0x8000) == 0) + lg2 += 1, x <<= 1; + + /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional + * value. + */ + lg2 <<= 28; + lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; + + /* Now we need to interpolate the factor, this requires a division by the top + * 8 bits. Do this with maximum precision. + */ + x = ((x << 16) + (x >> 9)) / (x >> 8); + + /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, + * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly + * 16 bits to interpolate to get the low bits of the result. Round the + * answer. Note that the end point values are scaled by 64 to retain overall + * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust + * the overall scaling by 6-12. Round at every step. + */ + x -= 1U << 24; + + if (x <= 65536U) /* <= '257' */ + lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); + + else + lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); + + /* Safe, because the result can't have more than 20 bits: */ + return (png_int_32)((lg2 + 2048) >> 12); +} +#endif /* 16BIT */ + +/* The 'exp()' case must invert the above, taking a 20-bit fixed point + * logarithmic value and returning a 16 or 8-bit number as appropriate. In + * each case only the low 16 bits are relevant - the fraction - since the + * integer bits (the top 4) simply determine a shift. + * + * The worst case is the 16-bit distinction between 65535 and 65534. This + * requires perhaps spurious accuracy in the decoding of the logarithm to + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance + * of getting this accuracy in practice. + * + * To deal with this the following exp() function works out the exponent of the + * fractional part of the logarithm by using an accurate 32-bit value from the + * top four fractional bits then multiplying in the remaining bits. + */ +static const png_uint_32 +png_32bit_exp[16] = +{ + /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, + 2553802834U, 2445529972U, 2341847524U, 2242560872U +}; + +/* Adjustment table; provided to explain the numbers in the code below. */ +#if 0 +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} + 11 44937.64284865548751208448 + 10 45180.98734845585101160448 + 9 45303.31936980687359311872 + 8 45364.65110595323018870784 + 7 45395.35850361789624614912 + 6 45410.72259715102037508096 + 5 45418.40724413220722311168 + 4 45422.25021786898173001728 + 3 45424.17186732298419044352 + 2 45425.13273269940811464704 + 1 45425.61317555035558641664 + 0 45425.85339951654943850496 +#endif + +static png_uint_32 +png_exp(png_fixed_point x) +{ + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ + { + /* Obtain a 4-bit approximation */ + png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f]; + + /* Incorporate the low 12 bits - these decrease the returned value by + * multiplying by a number less than 1 if the bit is set. The multiplier + * is determined by the above table and the shift. Notice that the values + * converge on 45426 and this is used to allow linear interpolation of the + * low bits. + */ + if (x & 0x800) + e -= (((e >> 16) * 44938U) + 16U) >> 5; + + if (x & 0x400) + e -= (((e >> 16) * 45181U) + 32U) >> 6; + + if (x & 0x200) + e -= (((e >> 16) * 45303U) + 64U) >> 7; + + if (x & 0x100) + e -= (((e >> 16) * 45365U) + 128U) >> 8; + + if (x & 0x080) + e -= (((e >> 16) * 45395U) + 256U) >> 9; + + if (x & 0x040) + e -= (((e >> 16) * 45410U) + 512U) >> 10; + + /* And handle the low 6 bits in a single block. */ + e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; + + /* Handle the upper bits of x. */ + e >>= x >> 16; + return e; + } + + /* Check for overflow */ + if (x <= 0) + return png_32bit_exp[0]; + + /* Else underflow */ + return 0; +} + +static png_byte +png_exp8bit(png_fixed_point lg2) +{ + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + + /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the + * second, rounding, step can't overflow because of the first, subtraction, + * step. + */ + x -= x >> 8; + return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff); +} + +#ifdef PNG_16BIT_SUPPORTED +static png_uint_16 +png_exp16bit(png_fixed_point lg2) +{ + /* Get a 32-bit value: */ + png_uint_32 x = png_exp(lg2); + + /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ + x -= x >> 16; + return (png_uint_16)((x + 32767U) >> 16); +} +#endif /* 16BIT */ +#endif /* FLOATING_ARITHMETIC */ + +png_byte +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) +{ + if (value > 0 && value < 255) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly + * convert this to a floating point value. This includes values that + * would overflow if 'value' were to be converted to 'int'. + * + * Apparently GCC, however, does an intermediate conversion to (int) + * on some (ARM) but not all (x86) platforms, possibly because of + * hardware FP limitations. (E.g. if the hardware conversion always + * assumes the integer register contains a signed value.) This results + * in ANSI-C undefined behavior for large values. + * + * Other implementations on the same machine might actually be ANSI-C90 + * conformant and therefore compile spurious extra code for the large + * values. + * + * We can be reasonably sure that an unsigned to float conversion + * won't be faster than an int to float one. Therefore this code + * assumes responsibility for the undefined behavior, which it knows + * can't happen because of the check above. + * + * Note the argument to this routine is an (unsigned int) because, on + * 16-bit platforms, it is assigned a value which might be out of + * range for an (int); that would result in undefined behavior in the + * caller if the *argument* ('value') were to be declared (int). + */ + double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5); + return (png_byte)r; +# else + png_int_32 lg2 = png_log8bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) + return png_exp8bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_byte)(value & 0xff); +} + +#ifdef PNG_16BIT_SUPPORTED +png_uint_16 +png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) +{ + if (value > 0 && value < 65535) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* The same (unsigned int)->(double) constraints apply here as above, + * however in this case the (unsigned int) to (int) conversion can + * overflow on an ANSI-C90 compliant system so the cast needs to ensure + * that this is not possible. + */ + double r = floor(65535*pow((png_int_32)value/65535., + gamma_val*.00001)+.5); + return (png_uint_16)r; +# else + png_int_32 lg2 = png_log16bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) + return png_exp16bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_uint_16)value; +} +#endif /* 16BIT */ + +/* This does the right thing based on the bit_depth field of the + * png_struct, interpreting values as 8-bit or 16-bit. While the result + * is nominally a 16-bit value if bit depth is 8 then the result is + * 8-bit (as are the arguments.) + */ +png_uint_16 /* PRIVATE */ +png_gamma_correct(png_structrp png_ptr, unsigned int value, + png_fixed_point gamma_val) +{ + if (png_ptr->bit_depth == 8) + return png_gamma_8bit_correct(value, gamma_val); + +#ifdef PNG_16BIT_SUPPORTED + else + return png_gamma_16bit_correct(value, gamma_val); +#else + /* should not reach this */ + return 0; +#endif /* 16BIT */ +} + +#ifdef PNG_16BIT_SUPPORTED +/* Internal function to build a single 16-bit table - the table consists of + * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount + * to shift the input values right (or 16-number_of_signifiant_bits). + * + * The caller is responsible for ensuring that the table gets cleaned up on + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument + * should be somewhere that will be cleaned. + */ +static void +png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, + unsigned int shift, png_fixed_point gamma_val) +{ + /* Various values derived from 'shift': */ + unsigned int num = 1U << (8U - shift); +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* CSE the division and work round wacky GCC warnings (see the comments + * in png_gamma_8bit_correct for where these come from.) + */ + double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1); +#endif + unsigned int max = (1U << (16U - shift)) - 1U; + unsigned int max_by_2 = 1U << (15U - shift); + unsigned int i; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); + + for (i = 0; i < num; i++) + { + png_uint_16p sub_table = table[i] = + (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); + + /* The 'threshold' test is repeated here because it can arise for one of + * the 16-bit tables even if the others don't hit it. + */ + if (png_gamma_significant(gamma_val) != 0) + { + /* The old code would overflow at the end and this would cause the + * 'pow' function to return a result >1, resulting in an + * arithmetic error. This code follows the spec exactly; ig is + * the recovered input sample, it always has 8-16 bits. + * + * We want input * 65535/max, rounded, the arithmetic fits in 32 + * bits (unsigned) so long as max <= 32767. + */ + unsigned int j; + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Inline the 'max' scaling operation: */ + /* See png_gamma_8bit_correct for why the cast to (int) is + * required here. + */ + double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5); + sub_table[j] = (png_uint_16)d; +# else + if (shift != 0) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); +# endif + } + } + else + { + /* We must still build a table, but do it the fast way. */ + unsigned int j; + + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; + + if (shift != 0) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = (png_uint_16)ig; + } + } + } +} + +/* NOTE: this function expects the *inverse* of the overall gamma transformation + * required. + */ +static void +png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, + unsigned int shift, png_fixed_point gamma_val) +{ + unsigned int num = 1U << (8U - shift); + unsigned int max = (1U << (16U - shift))-1U; + unsigned int i; + png_uint_32 last; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); + + /* 'num' is the number of tables and also the number of low bits of low + * bits of the input 16-bit value used to select a table. Each table is + * itself indexed by the high 8 bits of the value. + */ + for (i = 0; i < num; i++) + table[i] = (png_uint_16p)png_malloc(png_ptr, + 256 * (sizeof (png_uint_16))); + + /* 'gamma_val' is set to the reciprocal of the value calculated above, so + * pow(out,g) is an *input* value. 'last' is the last input value set. + * + * In the loop 'i' is used to find output values. Since the output is + * 8-bit there are only 256 possible values. The tables are set up to + * select the closest possible output value for each input by finding + * the input value at the boundary between each pair of output values + * and filling the table up to that boundary with the lower output + * value. + * + * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit + * values the code below uses a 16-bit value in i; the values start at + * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last + * entries are filled with 255). Start i at 128 and fill all 'last' + * table entries <= 'max' + */ + last = 0; + for (i = 0; i < 255; ++i) /* 8-bit output value */ + { + /* Find the corresponding maximum input value */ + png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ + + /* Find the boundary value in 16 bits: */ + png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); + + /* Adjust (round) to (16-shift) bits: */ + bound = (bound * max + 32768U)/65535U + 1U; + + while (last < bound) + { + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; + last++; + } + } + + /* And fill in the final entries. */ + while (last < (num << 8)) + { + table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; + last++; + } +} +#endif /* 16BIT */ + +/* Build a single 8-bit table: same as the 16-bit case but much simpler (and + * typically much faster). Note that libpng currently does no sBIT processing + * (apparently contrary to the spec) so a 256-entry table is always generated. + */ +static void +png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, + png_fixed_point gamma_val) +{ + unsigned int i; + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + + if (png_gamma_significant(gamma_val) != 0) + for (i=0; i<256; i++) + table[i] = png_gamma_8bit_correct(i, gamma_val); + + else + for (i=0; i<256; ++i) + table[i] = (png_byte)(i & 0xff); +} + +/* Used from png_read_destroy and below to release the memory used by the gamma + * tables. + */ +void /* PRIVATE */ +png_destroy_gamma_table(png_structrp png_ptr) +{ + png_free(png_ptr, png_ptr->gamma_table); + png_ptr->gamma_table = NULL; + +#ifdef PNG_16BIT_SUPPORTED + if (png_ptr->gamma_16_table != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_table[i]); + } + png_free(png_ptr, png_ptr->gamma_16_table); + png_ptr->gamma_16_table = NULL; + } +#endif /* 16BIT */ + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_free(png_ptr, png_ptr->gamma_from_1); + png_ptr->gamma_from_1 = NULL; + png_free(png_ptr, png_ptr->gamma_to_1); + png_ptr->gamma_to_1 = NULL; + +#ifdef PNG_16BIT_SUPPORTED + if (png_ptr->gamma_16_from_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_from_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_from_1); + png_ptr->gamma_16_from_1 = NULL; + } + if (png_ptr->gamma_16_to_1 != NULL) + { + int i; + int istop = (1 << (8 - png_ptr->gamma_shift)); + for (i = 0; i < istop; i++) + { + png_free(png_ptr, png_ptr->gamma_16_to_1[i]); + } + png_free(png_ptr, png_ptr->gamma_16_to_1); + png_ptr->gamma_16_to_1 = NULL; + } +#endif /* 16BIT */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +} + +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit + * tables, we don't make a full table if we are reducing to 8-bit in + * the future. Note also how the gamma_16 tables are segmented so that + * we don't need to allocate > 64K chunks for a full 16-bit table. + * + * TODO: move this to pngrtran.c and make it static. Better yet create + * pngcolor.c and put all the PNG_COLORSPACE stuff in there. + */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +# define GAMMA_TRANSFORMS 1 /* #ifdef CSE */ +#else +# define GAMMA_TRANSFORMS 0 +#endif + +void /* PRIVATE */ +png_build_gamma_table(png_structrp png_ptr, int bit_depth) +{ + png_fixed_point file_gamma, screen_gamma; + png_fixed_point correction; +# if GAMMA_TRANSFORMS + png_fixed_point file_to_linear, linear_to_screen; +# endif + + png_debug(1, "in png_build_gamma_table"); + + /* Remove any existing table; this copes with multiple calls to + * png_read_update_info. The warning is because building the gamma tables + * multiple times is a performance hit - it's harmless but the ability to + * call png_read_update_info() multiple times is new in 1.5.6 so it seems + * sensible to warn if the app introduces such a hit. + */ + if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) + { + png_warning(png_ptr, "gamma table being rebuilt"); + png_destroy_gamma_table(png_ptr); + } + + /* The following fields are set, finally, in png_init_read_transformations. + * If file_gamma is 0 (unset) nothing can be done otherwise if screen_gamma + * is 0 (unset) there is no gamma correction but to/from linear is possible. + */ + file_gamma = png_ptr->file_gamma; + screen_gamma = png_ptr->screen_gamma; +# if GAMMA_TRANSFORMS + file_to_linear = png_reciprocal(file_gamma); +# endif + + if (screen_gamma > 0) + { +# if GAMMA_TRANSFORMS + linear_to_screen = png_reciprocal(screen_gamma); +# endif + correction = png_reciprocal2(screen_gamma, file_gamma); + } + else /* screen gamma unknown */ + { +# if GAMMA_TRANSFORMS + linear_to_screen = file_gamma; +# endif + correction = PNG_FP_1; + } + + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, correction); + +#if GAMMA_TRANSFORMS + if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, file_to_linear); + + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + linear_to_screen); + } +#endif /* GAMMA_TRANSFORMS */ + } +#ifdef PNG_16BIT_SUPPORTED + else + { + png_byte shift, sig_bit; + + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + sig_bit = png_ptr->sig_bit.red; + + if (png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + + if (png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + sig_bit = png_ptr->sig_bit.gray; + + /* 16-bit gamma code uses this equation: + * + * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] + * + * Where 'iv' is the input color value and 'ov' is the output value - + * pow(iv, gamma). + * + * Thus the gamma table consists of up to 256 256-entry tables. The table + * is selected by the (8-gamma_shift) most significant of the low 8 bits + * of the color value then indexed by the upper 8 bits: + * + * table[low bits][high 8 bits] + * + * So the table 'n' corresponds to all those 'iv' of: + * + * ..<(n+1 << gamma_shift)-1> + * + */ + if (sig_bit > 0 && sig_bit < 16U) + /* shift == insignificant bits */ + shift = (png_byte)((16U - sig_bit) & 0xff); + + else + shift = 0; /* keep all 16 bits */ + + if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) + { + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will + * eventually be 8 bits. By default it is 11. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + } + + if (shift > 8U) + shift = 8U; /* Guarantees at least one table! */ + + png_ptr->gamma_shift = shift; + + /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now + * PNG_COMPOSE). This effectively smashed the background calculation for + * 16-bit output because the 8-bit table assumes the result will be + * reduced to 8 bits. + */ + if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_reciprocal(correction)); + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + correction); + +# if GAMMA_TRANSFORMS + if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + file_to_linear); + + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, so it can't be. + * TODO: fix this. + */ + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, + linear_to_screen); + } +#endif /* GAMMA_TRANSFORMS */ + } +#endif /* 16BIT */ +} +#endif /* READ_GAMMA */ + +/* HARDWARE OR SOFTWARE OPTION SUPPORT */ +#ifdef PNG_SET_OPTION_SUPPORTED +int PNGAPI +png_set_option(png_structrp png_ptr, int option, int onoff) +{ + if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && + (option & 1) == 0) + { + png_uint_32 mask = 3U << option; + png_uint_32 setting = (2U + (onoff != 0)) << option; + png_uint_32 current = png_ptr->options; + + png_ptr->options = (png_uint_32)((current & ~mask) | setting); + + return (int)(current & mask) >> option; + } + + return PNG_OPTION_INVALID; +} +#endif + +/* sRGB support */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/* sRGB conversion tables; these are machine generated with the code in + * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the + * specification (see the article at https://en.wikipedia.org/wiki/SRGB) + * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. + * The sRGB to linear table is exact (to the nearest 16-bit linear fraction). + * The inverse (linear to sRGB) table has accuracies as follows: + * + * For all possible (255*65535+1) input values: + * + * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact + * + * For the input values corresponding to the 65536 16-bit values: + * + * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact + * + * In all cases the inexact readings are only off by one. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* The convert-to-sRGB table is only currently required for read. */ +const png_uint_16 png_sRGB_table[256] = +{ + 0,20,40,60,80,99,119,139, + 159,179,199,219,241,264,288,313, + 340,367,396,427,458,491,526,562, + 599,637,677,718,761,805,851,898, + 947,997,1048,1101,1156,1212,1270,1330, + 1391,1453,1517,1583,1651,1720,1790,1863, + 1937,2013,2090,2170,2250,2333,2418,2504, + 2592,2681,2773,2866,2961,3058,3157,3258, + 3360,3464,3570,3678,3788,3900,4014,4129, + 4247,4366,4488,4611,4736,4864,4993,5124, + 5257,5392,5530,5669,5810,5953,6099,6246, + 6395,6547,6700,6856,7014,7174,7335,7500, + 7666,7834,8004,8177,8352,8528,8708,8889, + 9072,9258,9445,9635,9828,10022,10219,10417, + 10619,10822,11028,11235,11446,11658,11873,12090, + 12309,12530,12754,12980,13209,13440,13673,13909, + 14146,14387,14629,14874,15122,15371,15623,15878, + 16135,16394,16656,16920,17187,17456,17727,18001, + 18277,18556,18837,19121,19407,19696,19987,20281, + 20577,20876,21177,21481,21787,22096,22407,22721, + 23038,23357,23678,24002,24329,24658,24990,25325, + 25662,26001,26344,26688,27036,27386,27739,28094, + 28452,28813,29176,29542,29911,30282,30656,31033, + 31412,31794,32179,32567,32957,33350,33745,34143, + 34544,34948,35355,35764,36176,36591,37008,37429, + 37852,38278,38706,39138,39572,40009,40449,40891, + 41337,41785,42236,42690,43147,43606,44069,44534, + 45002,45473,45947,46423,46903,47385,47871,48359, + 48850,49344,49841,50341,50844,51349,51858,52369, + 52884,53401,53921,54445,54971,55500,56032,56567, + 57105,57646,58190,58737,59287,59840,60396,60955, + 61517,62082,62650,63221,63795,64372,64952,65535 +}; +#endif /* SIMPLIFIED_READ */ + +/* The base/delta tables are required for both read and write (but currently + * only the simplified versions.) + */ +const png_uint_16 png_sRGB_base[512] = +{ + 128,1782,3383,4644,5675,6564,7357,8074, + 8732,9346,9921,10463,10977,11466,11935,12384, + 12816,13233,13634,14024,14402,14769,15125,15473, + 15812,16142,16466,16781,17090,17393,17690,17981, + 18266,18546,18822,19093,19359,19621,19879,20133, + 20383,20630,20873,21113,21349,21583,21813,22041, + 22265,22487,22707,22923,23138,23350,23559,23767, + 23972,24175,24376,24575,24772,24967,25160,25352, + 25542,25730,25916,26101,26284,26465,26645,26823, + 27000,27176,27350,27523,27695,27865,28034,28201, + 28368,28533,28697,28860,29021,29182,29341,29500, + 29657,29813,29969,30123,30276,30429,30580,30730, + 30880,31028,31176,31323,31469,31614,31758,31902, + 32045,32186,32327,32468,32607,32746,32884,33021, + 33158,33294,33429,33564,33697,33831,33963,34095, + 34226,34357,34486,34616,34744,34873,35000,35127, + 35253,35379,35504,35629,35753,35876,35999,36122, + 36244,36365,36486,36606,36726,36845,36964,37083, + 37201,37318,37435,37551,37668,37783,37898,38013, + 38127,38241,38354,38467,38580,38692,38803,38915, + 39026,39136,39246,39356,39465,39574,39682,39790, + 39898,40005,40112,40219,40325,40431,40537,40642, + 40747,40851,40955,41059,41163,41266,41369,41471, + 41573,41675,41777,41878,41979,42079,42179,42279, + 42379,42478,42577,42676,42775,42873,42971,43068, + 43165,43262,43359,43456,43552,43648,43743,43839, + 43934,44028,44123,44217,44311,44405,44499,44592, + 44685,44778,44870,44962,45054,45146,45238,45329, + 45420,45511,45601,45692,45782,45872,45961,46051, + 46140,46229,46318,46406,46494,46583,46670,46758, + 46846,46933,47020,47107,47193,47280,47366,47452, + 47538,47623,47709,47794,47879,47964,48048,48133, + 48217,48301,48385,48468,48552,48635,48718,48801, + 48884,48966,49048,49131,49213,49294,49376,49458, + 49539,49620,49701,49782,49862,49943,50023,50103, + 50183,50263,50342,50422,50501,50580,50659,50738, + 50816,50895,50973,51051,51129,51207,51285,51362, + 51439,51517,51594,51671,51747,51824,51900,51977, + 52053,52129,52205,52280,52356,52432,52507,52582, + 52657,52732,52807,52881,52956,53030,53104,53178, + 53252,53326,53400,53473,53546,53620,53693,53766, + 53839,53911,53984,54056,54129,54201,54273,54345, + 54417,54489,54560,54632,54703,54774,54845,54916, + 54987,55058,55129,55199,55269,55340,55410,55480, + 55550,55620,55689,55759,55828,55898,55967,56036, + 56105,56174,56243,56311,56380,56448,56517,56585, + 56653,56721,56789,56857,56924,56992,57059,57127, + 57194,57261,57328,57395,57462,57529,57595,57662, + 57728,57795,57861,57927,57993,58059,58125,58191, + 58256,58322,58387,58453,58518,58583,58648,58713, + 58778,58843,58908,58972,59037,59101,59165,59230, + 59294,59358,59422,59486,59549,59613,59677,59740, + 59804,59867,59930,59993,60056,60119,60182,60245, + 60308,60370,60433,60495,60558,60620,60682,60744, + 60806,60868,60930,60992,61054,61115,61177,61238, + 61300,61361,61422,61483,61544,61605,61666,61727, + 61788,61848,61909,61969,62030,62090,62150,62211, + 62271,62331,62391,62450,62510,62570,62630,62689, + 62749,62808,62867,62927,62986,63045,63104,63163, + 63222,63281,63340,63398,63457,63515,63574,63632, + 63691,63749,63807,63865,63923,63981,64039,64097, + 64155,64212,64270,64328,64385,64443,64500,64557, + 64614,64672,64729,64786,64843,64900,64956,65013, + 65070,65126,65183,65239,65296,65352,65409,65465 +}; + +const png_byte png_sRGB_delta[512] = +{ + 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, + 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, + 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, + 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, + 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, + 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, + 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, + 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,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,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,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; +#endif /* SIMPLIFIED READ/WRITE sRGB support */ + +/* SIMPLIFIED READ/WRITE SUPPORT */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +static int +png_image_free_function(png_voidp argument) +{ + png_imagep image = png_voidcast(png_imagep, argument); + png_controlp cp = image->opaque; + png_control c; + + /* Double check that we have a png_ptr - it should be impossible to get here + * without one. + */ + if (cp->png_ptr == NULL) + return 0; + + /* First free any data held in the control structure. */ +# ifdef PNG_STDIO_SUPPORTED + if (cp->owned_file != 0) + { + FILE *fp = png_voidcast(FILE *, cp->png_ptr->io_ptr); + cp->owned_file = 0; + + /* Ignore errors here. */ + if (fp != NULL) + { + cp->png_ptr->io_ptr = NULL; + (void)fclose(fp); + } + } +# endif + + /* Copy the control structure so that the original, allocated, version can be + * safely freed. Notice that a png_error here stops the remainder of the + * cleanup, but this is probably fine because that would indicate bad memory + * problems anyway. + */ + c = *cp; + image->opaque = &c; + png_free(c.png_ptr, cp); + + /* Then the structures, calling the correct API. */ + if (c.for_write != 0) + { +# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED + png_destroy_write_struct(&c.png_ptr, &c.info_ptr); +# else + png_error(c.png_ptr, "simplified write not supported"); +# endif + } + else + { +# ifdef PNG_SIMPLIFIED_READ_SUPPORTED + png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); +# else + png_error(c.png_ptr, "simplified read not supported"); +# endif + } + + /* Success. */ + return 1; +} + +void PNGAPI +png_image_free(png_imagep image) +{ + /* Safely call the real function, but only if doing so is safe at this point + * (if not inside an error handling context). Otherwise assume + * png_safe_execute will call this API after the return. + */ + if (image != NULL && image->opaque != NULL && + image->opaque->error_buf == NULL) + { + png_image_free_function(image); + image->opaque = NULL; + } +} + +int /* PRIVATE */ +png_image_error(png_imagep image, png_const_charp error_message) +{ + /* Utility to log an error. */ + png_safecat(image->message, (sizeof image->message), 0, error_message); + image->warning_or_error |= PNG_IMAGE_ERROR; + png_image_free(image); + return 0; +} + +#endif /* SIMPLIFIED READ/WRITE */ +#endif /* READ || WRITE */ diff --git a/thirdparty/libpng/upstream/png.h b/thirdparty/libpng/upstream/png.h index 3c56e1356..57f484512 100644 --- a/thirdparty/libpng/upstream/png.h +++ b/thirdparty/libpng/upstream/png.h @@ -1,3250 +1,3526 @@ - -/* png.h - header file for PNG reference library - * - * libpng version 1.6.44 - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. (See LICENSE, below.) - * - * Authors and maintainers: - * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.35, July 2018: - * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.44, September 2024: - * Cosmin Truta - * See also "Contributing Authors", below. - */ - -/* - * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE - * ========================================= - * - * PNG Reference Library License version 2 - * --------------------------------------- - * - * * Copyright (c) 1995-2024 The PNG Reference Library Authors. - * * Copyright (c) 2018-2024 Cosmin Truta. - * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. - * * Copyright (c) 1996-1997 Andreas Dilger. - * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * The software is supplied "as is", without warranty of any kind, - * express or implied, including, without limitation, the warranties - * of merchantability, fitness for a particular purpose, title, and - * non-infringement. In no event shall the Copyright owners, or - * anyone distributing the software, be liable for any damages or - * other liability, whether in contract, tort or otherwise, arising - * from, out of, or in connection with the software, or the use or - * other dealings in the software, even if advised of the possibility - * of such damage. - * - * Permission is hereby granted to use, copy, modify, and distribute - * this software, or portions hereof, for any purpose, without fee, - * subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you - * use this software in a product, an acknowledgment in the product - * documentation would be appreciated, but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. - * - * - * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) - * ----------------------------------------------------------------------- - * - * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are - * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are - * derived from libpng-1.0.6, and are distributed according to the same - * disclaimer and license as libpng-1.0.6 with the following individuals - * added to the list of Contributing Authors: - * - * Simon-Pierre Cadieux - * Eric S. Raymond - * Mans Rullgard - * Cosmin Truta - * Gilles Vollant - * James Yu - * Mandar Sahastrabuddhe - * Google Inc. - * Vadim Barkov - * - * and with the following additions to the disclaimer: - * - * There is no warranty against interference with your enjoyment of - * the library or against infringement. There is no warranty that our - * efforts or the library will fulfill any of your particular purposes - * or needs. This library is provided with all faults, and the entire - * risk of satisfactory quality, performance, accuracy, and effort is - * with the user. - * - * Some files in the "contrib" directory and some configure-generated - * files that are distributed with libpng have other copyright owners, and - * are released under other open source licenses. - * - * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are - * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from - * libpng-0.96, and are distributed according to the same disclaimer and - * license as libpng-0.96, with the following individuals added to the - * list of Contributing Authors: - * - * Tom Lane - * Glenn Randers-Pehrson - * Willem van Schaik - * - * libpng versions 0.89, June 1996, through 0.96, May 1997, are - * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, - * and are distributed according to the same disclaimer and license as - * libpng-0.88, with the following individuals added to the list of - * Contributing Authors: - * - * John Bowler - * Kevin Bracey - * Sam Bushell - * Magnus Holmgren - * Greg Roelofs - * Tom Tanner - * - * Some files in the "scripts" directory have other copyright owners, - * but are released under this license. - * - * libpng versions 0.5, May 1995, through 0.88, January 1996, are - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * For the purposes of this copyright and license, "Contributing Authors" - * is defined as the following set of individuals: - * - * Andreas Dilger - * Dave Martindale - * Guy Eric Schalnat - * Paul Schmidt - * Tim Wegner - * - * The PNG Reference Library is supplied "AS IS". The Contributing - * Authors and Group 42, Inc. disclaim all warranties, expressed or - * implied, including, without limitation, the warranties of - * merchantability and of fitness for any purpose. The Contributing - * Authors and Group 42, Inc. assume no liability for direct, indirect, - * incidental, special, exemplary, or consequential damages, which may - * result from the use of the PNG Reference Library, even if advised of - * the possibility of such damage. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * source code, or portions hereof, for any purpose, without fee, subject - * to the following restrictions: - * - * 1. The origin of this source code must not be misrepresented. - * - * 2. Altered versions must be plainly marked as such and must not - * be misrepresented as being the original source. - * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. - * - * The Contributing Authors and Group 42, Inc. specifically permit, - * without fee, and encourage the use of this source code as a component - * to supporting the PNG file format in commercial products. If you use - * this source code in a product, acknowledgment is not required but would - * be appreciated. - * - * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. - * - * TRADEMARK - * ========= - * - * The name "libpng" has not been registered by the Copyright owners - * as a trademark in any jurisdiction. However, because libpng has - * been distributed and maintained world-wide, continually since 1995, - * the Copyright owners claim "common-law trademark protection" in any - * jurisdiction where common-law trademark is recognized. - */ - -/* - * A "png_get_copyright" function is available, for convenient use in "about" - * boxes and the like: - * - * printf("%s", png_get_copyright(NULL)); - * - * Also, the PNG logo (in PNG format, of course) is supplied in the - * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). - */ - -/* - * The contributing authors would like to thank all those who helped - * with testing, bug fixes, and patience. This wouldn't have been - * possible without all of you. - * - * Thanks to Frank J. T. Wojcik for helping with the documentation. - */ - -/* Note about libpng version numbers: - * - * Due to various miscommunications, unforeseen code incompatibilities - * and occasional factors outside the authors' control, version numbering - * on the library has not always been consistent and straightforward. - * The following table summarizes matters since version 0.89c, which was - * the first widely used release: - * - * source png.h png.h shared-lib - * version string int version - * ------- ------ ----- ---------- - * 0.89c "1.0 beta 3" 0.89 89 1.0.89 - * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] - * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] - * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] - * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] - * 0.97c 0.97 97 2.0.97 - * 0.98 0.98 98 2.0.98 - * 0.99 0.99 98 2.0.99 - * 0.99a-m 0.99 99 2.0.99 - * 1.00 1.00 100 2.1.0 [100 should be 10000] - * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] - * 1.0.1 png.h string is 10001 2.1.0 - * 1.0.1a-e identical to the 10002 from here on, the shared library - * 1.0.2 source version) 10002 is 2.V where V is the source code - * 1.0.2a-b 10003 version, except as noted. - * 1.0.3 10003 - * 1.0.3a-d 10004 - * 1.0.4 10004 - * 1.0.4a-f 10005 - * 1.0.5 (+ 2 patches) 10005 - * 1.0.5a-d 10006 - * 1.0.5e-r 10100 (not source compatible) - * 1.0.5s-v 10006 (not binary compatible) - * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) - * 1.0.6d-f 10007 (still binary incompatible) - * 1.0.6g 10007 - * 1.0.6h 10007 10.6h (testing xy.z so-numbering) - * 1.0.6i 10007 10.6i - * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) - * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) - * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) - * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) - * 1.0.7 1 10007 (still compatible) - * ... - * 1.0.69 10 10069 10.so.0.69[.0] - * ... - * 1.2.59 13 10259 12.so.0.59[.0] - * ... - * 1.4.20 14 10420 14.so.0.20[.0] - * ... - * 1.5.30 15 10530 15.so.15.30[.0] - * ... - * 1.6.44 16 10644 16.so.16.44[.0] - * - * Henceforth the source version will match the shared-library major and - * minor numbers; the shared-library major version number will be used for - * changes in backward compatibility, as it is intended. - * The PNG_LIBPNG_VER macro, which is not used within libpng but is - * available for applications, is an unsigned integer of the form XYYZZ - * corresponding to the source version X.Y.Z (leading zeros in Y and Z). - * Beta versions were given the previous public release number plus a - * letter, until version 1.0.6j; from then on they were given the upcoming - * public release number plus "betaNN" or "rcNN". - * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled - * application is loaded with a different version of the library. - * - * See libpng.txt or libpng.3 for more information. The PNG specification - * is available as a W3C Recommendation and as an ISO/IEC Standard; see - * - */ - -#ifndef PNG_H -#define PNG_H - -/* This is not the place to learn how to use libpng. The file libpng-manual.txt - * describes how to use libpng, and the file example.c summarizes it - * with some code on which to build. This file is useful for looking - * at the actual function definitions and structure components. If that - * file has been stripped from your copy of libpng, you can find it at - * - * - * If you just need to read a PNG file and don't want to read the documentation - * skip to the end of this file and read the section entitled 'simplified API'. - */ - -/* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.44" -#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" - -/* The versions of shared library builds should stay in sync, going forward */ -#define PNG_LIBPNG_VER_SHAREDLIB 16 -#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ -#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ - -/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ -#define PNG_LIBPNG_VER_MAJOR 1 -#define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 44 - -/* This should be zero for a public release, or non-zero for a - * development version. - */ -#define PNG_LIBPNG_VER_BUILD 0 - -/* Release Status */ -#define PNG_LIBPNG_BUILD_ALPHA 1 -#define PNG_LIBPNG_BUILD_BETA 2 -#define PNG_LIBPNG_BUILD_RC 3 -#define PNG_LIBPNG_BUILD_STABLE 4 -#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 - -/* Release-Specific Flags */ -#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with - PNG_LIBPNG_BUILD_STABLE only */ -#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_SPECIAL */ -#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_PRIVATE */ - -#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE - -/* Careful here. At one time, Guy wanted to use 082, but that - * would be octal. We must not include leading zeros. - * Versions 0.7 through 1.0.0 were in the range 0 to 100 here - * (only version 1.0.0 was mis-numbered 100 instead of 10000). - * From version 1.0.1 it is: - * XXYYZZ, where XX=major, YY=minor, ZZ=release - */ -#define PNG_LIBPNG_VER 10644 /* 1.6.44 */ - -/* Library configuration: these options cannot be changed after - * the library has been built. - */ -#ifndef PNGLCONF_H -/* If pnglibconf.h is missing, you can - * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h - */ -# include "pnglibconf.h" -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Machine specific configuration. */ -# include "pngconf.h" -#endif - -/* - * Added at libpng-1.2.8 - * - * Ref MSDN: Private as priority over Special - * VS_FF_PRIVATEBUILD File *was not* built using standard release - * procedures. If this value is given, the StringFileInfo block must - * contain a PrivateBuild string. - * - * VS_FF_SPECIALBUILD File *was* built by the original company using - * standard release procedures but is a variation of the standard - * file of the same version number. If this value is given, the - * StringFileInfo block must contain a SpecialBuild string. - */ - -#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) -#else -# ifdef PNG_LIBPNG_SPECIALBUILD -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) -# else -# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) -# endif -#endif - -#ifndef PNG_VERSION_INFO_ONLY - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Version information for C files, stored in png.c. This had better match - * the version above. - */ -#define png_libpng_ver png_get_header_ver(NULL) - -/* This file is arranged in several sections: - * - * 1. [omitted] - * 2. Any configuration options that can be specified by for the application - * code when it is built. (Build time configuration is in pnglibconf.h) - * 3. Type definitions (base types are defined in pngconf.h), structure - * definitions. - * 4. Exported library functions. - * 5. Simplified API. - * 6. Implementation options. - * - * The library source code has additional files (principally pngpriv.h) that - * allow configuration of the library. - */ - -/* Section 1: [omitted] */ - -/* Section 2: run time configuration - * See pnglibconf.h for build time configuration - * - * Run time configuration allows the application to choose between - * implementations of certain arithmetic APIs. The default is set - * at build time and recorded in pnglibconf.h, but it is safe to - * override these (and only these) settings. Note that this won't - * change what the library does, only application code, and the - * settings can (and probably should) be made on a per-file basis - * by setting the #defines before including png.h - * - * Use macros to read integers from PNG data or use the exported - * functions? - * PNG_USE_READ_MACROS: use the macros (see below) Note that - * the macros evaluate their argument multiple times. - * PNG_NO_USE_READ_MACROS: call the relevant library function. - * - * Use the alternative algorithm for compositing alpha samples that - * does not use division? - * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' - * algorithm. - * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. - * - * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is - * false? - * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error - * APIs to png_warning. - * Otherwise the calls are mapped to png_error. - */ - -/* Section 3: type definitions, including structures and compile time - * constants. - * See pngconf.h for base types that vary by machine/system - */ - -/* This triggers a compiler error in png.c, if png.c and png.h - * do not agree upon the version number. - */ -typedef char* png_libpng_version_1_6_44; - -/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. - * - * png_struct is the cache of information used while reading or writing a single - * PNG file. One of these is always required, although the simplified API - * (below) hides the creation and destruction of it. - */ -typedef struct png_struct_def png_struct; -typedef const png_struct * png_const_structp; -typedef png_struct * png_structp; -typedef png_struct * * png_structpp; - -/* png_info contains information read from or to be written to a PNG file. One - * or more of these must exist while reading or creating a PNG file. The - * information is not used by libpng during read but is used to control what - * gets written when a PNG file is created. "png_get_" function calls read - * information during read and "png_set_" functions calls write information - * when creating a PNG. - * been moved into a separate header file that is not accessible to - * applications. Read libpng-manual.txt or libpng.3 for more info. - */ -typedef struct png_info_def png_info; -typedef png_info * png_infop; -typedef const png_info * png_const_infop; -typedef png_info * * png_infopp; - -/* Types with names ending 'p' are pointer types. The corresponding types with - * names ending 'rp' are identical pointer types except that the pointer is - * marked 'restrict', which means that it is the only pointer to the object - * passed to the function. Applications should not use the 'restrict' types; - * it is always valid to pass 'p' to a pointer with a function argument of the - * corresponding 'rp' type. Different compilers have different rules with - * regard to type matching in the presence of 'restrict'. For backward - * compatibility libpng callbacks never have 'restrict' in their parameters and, - * consequentially, writing portable application code is extremely difficult if - * an attempt is made to use 'restrict'. - */ -typedef png_struct * PNG_RESTRICT png_structrp; -typedef const png_struct * PNG_RESTRICT png_const_structrp; -typedef png_info * PNG_RESTRICT png_inforp; -typedef const png_info * PNG_RESTRICT png_const_inforp; - -/* Three color definitions. The order of the red, green, and blue, (and the - * exact size) is not important, although the size of the fields need to - * be png_byte or png_uint_16 (as defined below). - */ -typedef struct png_color_struct -{ - png_byte red; - png_byte green; - png_byte blue; -} png_color; -typedef png_color * png_colorp; -typedef const png_color * png_const_colorp; -typedef png_color * * png_colorpp; - -typedef struct png_color_16_struct -{ - png_byte index; /* used for palette files */ - png_uint_16 red; /* for use in red green blue files */ - png_uint_16 green; - png_uint_16 blue; - png_uint_16 gray; /* for use in grayscale files */ -} png_color_16; -typedef png_color_16 * png_color_16p; -typedef const png_color_16 * png_const_color_16p; -typedef png_color_16 * * png_color_16pp; - -typedef struct png_color_8_struct -{ - png_byte red; /* for use in red green blue files */ - png_byte green; - png_byte blue; - png_byte gray; /* for use in grayscale files */ - png_byte alpha; /* for alpha channel files */ -} png_color_8; -typedef png_color_8 * png_color_8p; -typedef const png_color_8 * png_const_color_8p; -typedef png_color_8 * * png_color_8pp; - -/* - * The following two structures are used for the in-core representation - * of sPLT chunks. - */ -typedef struct png_sPLT_entry_struct -{ - png_uint_16 red; - png_uint_16 green; - png_uint_16 blue; - png_uint_16 alpha; - png_uint_16 frequency; -} png_sPLT_entry; -typedef png_sPLT_entry * png_sPLT_entryp; -typedef const png_sPLT_entry * png_const_sPLT_entryp; -typedef png_sPLT_entry * * png_sPLT_entrypp; - -/* When the depth of the sPLT palette is 8 bits, the color and alpha samples - * occupy the LSB of their respective members, and the MSB of each member - * is zero-filled. The frequency member always occupies the full 16 bits. - */ - -typedef struct png_sPLT_struct -{ - png_charp name; /* palette name */ - png_byte depth; /* depth of palette samples */ - png_sPLT_entryp entries; /* palette entries */ - png_int_32 nentries; /* number of palette entries */ -} png_sPLT_t; -typedef png_sPLT_t * png_sPLT_tp; -typedef const png_sPLT_t * png_const_sPLT_tp; -typedef png_sPLT_t * * png_sPLT_tpp; - -#ifdef PNG_TEXT_SUPPORTED -/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, - * and whether that contents is compressed or not. The "key" field - * points to a regular zero-terminated C string. The "text" fields can be a - * regular C string, an empty string, or a NULL pointer. - * However, the structure returned by png_get_text() will always contain - * the "text" field as a regular zero-terminated C string (possibly - * empty), never a NULL pointer, so it can be safely used in printf() and - * other string-handling functions. Note that the "itxt_length", "lang", and - * "lang_key" members of the structure only exist when the library is built - * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by - * default without iTXt support. Also note that when iTXt *is* supported, - * the "lang" and "lang_key" fields contain NULL pointers when the - * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or - * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the - * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" - * which is always 0 or 1, or its "compression method" which is always 0. - */ -typedef struct png_text_struct -{ - int compression; /* compression value: - -1: tEXt, none - 0: zTXt, deflate - 1: iTXt, none - 2: iTXt, deflate */ - png_charp key; /* keyword, 1-79 character description of "text" */ - png_charp text; /* comment, may be an empty string (ie "") - or a NULL pointer */ - size_t text_length; /* length of the text string */ - size_t itxt_length; /* length of the itxt string */ - png_charp lang; /* language code, 0-79 characters - or a NULL pointer */ - png_charp lang_key; /* keyword translated UTF-8 string, 0 or more - chars or a NULL pointer */ -} png_text; -typedef png_text * png_textp; -typedef const png_text * png_const_textp; -typedef png_text * * png_textpp; -#endif - -/* Supported compression types for text in PNG files (tEXt, and zTXt). - * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ -#define PNG_TEXT_COMPRESSION_NONE_WR -3 -#define PNG_TEXT_COMPRESSION_zTXt_WR -2 -#define PNG_TEXT_COMPRESSION_NONE -1 -#define PNG_TEXT_COMPRESSION_zTXt 0 -#define PNG_ITXT_COMPRESSION_NONE 1 -#define PNG_ITXT_COMPRESSION_zTXt 2 -#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ - -/* png_time is a way to hold the time in an machine independent way. - * Two conversions are provided, both from time_t and struct tm. There - * is no portable way to convert to either of these structures, as far - * as I know. If you know of a portable way, send it to me. As a side - * note - PNG has always been Year 2000 compliant! - */ -typedef struct png_time_struct -{ - png_uint_16 year; /* full year, as in, 1995 */ - png_byte month; /* month of year, 1 - 12 */ - png_byte day; /* day of month, 1 - 31 */ - png_byte hour; /* hour of day, 0 - 23 */ - png_byte minute; /* minute of hour, 0 - 59 */ - png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ -} png_time; -typedef png_time * png_timep; -typedef const png_time * png_const_timep; -typedef png_time * * png_timepp; - -#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_USER_CHUNKS_SUPPORTED) -/* png_unknown_chunk is a structure to hold queued chunks for which there is - * no specific support. The idea is that we can use this to queue - * up private chunks for output even though the library doesn't actually - * know about their semantics. - * - * The data in the structure is set by libpng on read and used on write. - */ -typedef struct png_unknown_chunk_t -{ - png_byte name[5]; /* Textual chunk name with '\0' terminator */ - png_byte *data; /* Data, should not be modified on read! */ - size_t size; - - /* On write 'location' must be set using the flag values listed below. - * Notice that on read it is set by libpng however the values stored have - * more bits set than are listed below. Always treat the value as a - * bitmask. On write set only one bit - setting multiple bits may cause the - * chunk to be written in multiple places. - */ - png_byte location; /* mode of operation at read time */ -} -png_unknown_chunk; - -typedef png_unknown_chunk * png_unknown_chunkp; -typedef const png_unknown_chunk * png_const_unknown_chunkp; -typedef png_unknown_chunk * * png_unknown_chunkpp; -#endif - -/* Flag values for the unknown chunk location byte. */ -#define PNG_HAVE_IHDR 0x01 -#define PNG_HAVE_PLTE 0x02 -#define PNG_AFTER_IDAT 0x08 - -/* Maximum positive integer used in PNG is (2^31)-1 */ -#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) -#define PNG_UINT_32_MAX ((png_uint_32)(-1)) -#define PNG_SIZE_MAX ((size_t)(-1)) - -/* These are constants for fixed point values encoded in the - * PNG specification manner (x100000) - */ -#define PNG_FP_1 100000 -#define PNG_FP_HALF 50000 -#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) -#define PNG_FP_MIN (-PNG_FP_MAX) - -/* These describe the color_type field in png_info. */ -/* color type masks */ -#define PNG_COLOR_MASK_PALETTE 1 -#define PNG_COLOR_MASK_COLOR 2 -#define PNG_COLOR_MASK_ALPHA 4 - -/* color types. Note that not all combinations are legal */ -#define PNG_COLOR_TYPE_GRAY 0 -#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) -#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) -#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) -#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) -/* aliases */ -#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA -#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA - -/* This is for compression type. PNG 1.0-1.2 only define the single type. */ -#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ -#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE - -/* This is for filter type. PNG 1.0-1.2 only define the single type. */ -#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ -#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ -#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE - -/* These are for the interlacing type. These values should NOT be changed. */ -#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ -#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ -#define PNG_INTERLACE_LAST 2 /* Not a valid value */ - -/* These are for the oFFs chunk. These values should NOT be changed. */ -#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ -#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ -#define PNG_OFFSET_LAST 2 /* Not a valid value */ - -/* These are for the pCAL chunk. These values should NOT be changed. */ -#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ -#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ -#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ -#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ -#define PNG_EQUATION_LAST 4 /* Not a valid value */ - -/* These are for the sCAL chunk. These values should NOT be changed. */ -#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ -#define PNG_SCALE_METER 1 /* meters per pixel */ -#define PNG_SCALE_RADIAN 2 /* radians per pixel */ -#define PNG_SCALE_LAST 3 /* Not a valid value */ - -/* These are for the pHYs chunk. These values should NOT be changed. */ -#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ -#define PNG_RESOLUTION_METER 1 /* pixels/meter */ -#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ - -/* These are for the sRGB chunk. These values should NOT be changed. */ -#define PNG_sRGB_INTENT_PERCEPTUAL 0 -#define PNG_sRGB_INTENT_RELATIVE 1 -#define PNG_sRGB_INTENT_SATURATION 2 -#define PNG_sRGB_INTENT_ABSOLUTE 3 -#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ - -/* This is for text chunks */ -#define PNG_KEYWORD_MAX_LENGTH 79 - -/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ -#define PNG_MAX_PALETTE_LENGTH 256 - -/* These determine if an ancillary chunk's data has been successfully read - * from the PNG header, or if the application has filled in the corresponding - * data in the info_struct to be written into the output file. The values - * of the PNG_INFO_ defines should NOT be changed. - */ -#define PNG_INFO_gAMA 0x0001U -#define PNG_INFO_sBIT 0x0002U -#define PNG_INFO_cHRM 0x0004U -#define PNG_INFO_PLTE 0x0008U -#define PNG_INFO_tRNS 0x0010U -#define PNG_INFO_bKGD 0x0020U -#define PNG_INFO_hIST 0x0040U -#define PNG_INFO_pHYs 0x0080U -#define PNG_INFO_oFFs 0x0100U -#define PNG_INFO_tIME 0x0200U -#define PNG_INFO_pCAL 0x0400U -#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */ -#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */ -#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */ -#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */ -#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ -#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */ - -/* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using - * the routines for other purposes. - */ -typedef struct png_row_info_struct -{ - png_uint_32 width; /* width of row */ - size_t rowbytes; /* number of bytes in row */ - png_byte color_type; /* color type of row */ - png_byte bit_depth; /* bit depth of row */ - png_byte channels; /* number of channels (1, 2, 3, or 4) */ - png_byte pixel_depth; /* bits per pixel (depth * channels) */ -} png_row_info; - -typedef png_row_info * png_row_infop; -typedef png_row_info * * png_row_infopp; - -/* These are the function types for the I/O functions and for the functions - * that allow the user to override the default I/O functions with his or her - * own. The png_error_ptr type should match that of user-supplied warning - * and error functions, while the png_rw_ptr type should match that of the - * user read/write data functions. Note that the 'write' function must not - * modify the buffer it is passed. The 'read' function, on the other hand, is - * expected to return the read data in the buffer. - */ -typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); -typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t)); -typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); -typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, - int)); -typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, - int)); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); -typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); - -/* The following callback receives png_uint_32 row_number, int pass for the - * png_bytep data of the row. When transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, - png_uint_32, int)); -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, - png_bytep)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, - png_unknown_chunkp)); -#endif -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -/* not used anywhere */ -/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This must match the function definition in , and the application - * must include this before png.h to obtain the definition of jmp_buf. The - * function is required to be PNG_NORETURN, but this is not checked. If the - * function does return the application will crash via an abort() or similar - * system level call. - * - * If you get a warning here while building the library you may need to make - * changes to ensure that pnglibconf.h records the calling convention used by - * your compiler. This may be very difficult - try using a different compiler - * to build the library! - */ -PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef); -#endif - -/* Transform masks for the high-level interface */ -#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ -#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ -#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ -#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ -#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ -#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ -#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ -#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ -#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ -#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ -#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ -#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ -#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ -/* Added to libpng-1.2.34 */ -#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER -#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ -/* Added to libpng-1.4.0 */ -#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ -/* Added to libpng-1.5.4 */ -#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */ -#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ -#endif - -/* Flags for MNG supported features */ -#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 -#define PNG_FLAG_MNG_FILTER_64 0x04 -#define PNG_ALL_MNG_FEATURES 0x05 - -/* NOTE: prior to 1.5 these functions had no 'API' style declaration, - * this allowed the zlib default functions to be used on Windows - * platforms. In 1.5 the zlib default malloc (which just calls malloc and - * ignores the first argument) should be completely compatible with the - * following. - */ -typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, - png_alloc_size_t)); -typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); - -/* Section 4: exported functions - * Here are the function definitions most commonly used. This is not - * the place to find out how to use libpng. See libpng-manual.txt for the - * full explanation, see example.c for the summary. This just provides - * a simple one line description of the use of each function. - * - * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in - * pngconf.h and in the *.dfn files in the scripts directory. - * - * PNG_EXPORT(ordinal, type, name, (args)); - * - * ordinal: ordinal that is used while building - * *.def files. The ordinal value is only - * relevant when preprocessing png.h with - * the *.dfn files for building symbol table - * entries, and are removed by pngconf.h. - * type: return type of the function - * name: function name - * args: function arguments, with types - * - * When we wish to append attributes to a function prototype we use - * the PNG_EXPORTA() macro instead. - * - * PNG_EXPORTA(ordinal, type, name, (args), attributes); - * - * ordinal, type, name, and args: same as in PNG_EXPORT(). - * attributes: function attributes - */ - -/* Returns the version number of the library */ -PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); - -/* Tell lib we have already handled the first magic bytes. - * Handling more than 8 bytes from the beginning of the file is an error. - */ -PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); - -/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a - * PNG file. Returns zero if the supplied bytes match the 8-byte PNG - * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (i.e. return non-zero). - */ -PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, - size_t num_to_check)); - -/* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0). - */ -#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */ - -/* Allocate and initialize png_ptr struct for reading, and any other memory. */ -PNG_EXPORTA(4, png_structp, png_create_read_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn), - PNG_ALLOCATED); - -/* Allocate and initialize png_ptr struct for writing, and any other memory */ -PNG_EXPORTA(5, png_structp, png_create_write_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn), - PNG_ALLOCATED); - -PNG_EXPORT(6, size_t, png_get_compression_buffer_size, - (png_const_structrp png_ptr)); - -PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, - size_t size)); - -/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp - * match up. - */ -#ifdef PNG_SETJMP_SUPPORTED -/* This function returns the jmp_buf built in to *png_ptr. It must be - * supplied with an appropriate 'longjmp' function to use on that jmp_buf - * unless the default error function is overridden in which case NULL is - * acceptable. The size of the jmp_buf is checked against the actual size - * allocated by the library - the call will return NULL on a mismatch - * indicating an ABI mismatch. - */ -PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, - png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); -# define png_jmpbuf(png_ptr) \ - (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) -#else -# define png_jmpbuf(png_ptr) \ - (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) -#endif -/* This function should be used by libpng applications in place of - * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it - * will use it; otherwise it will call PNG_ABORT(). This function was - * added in libpng-1.5.0. - */ -PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), - PNG_NORETURN); - -#ifdef PNG_READ_SUPPORTED -/* Reset the compression stream */ -PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); -#endif - -/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(11, png_structp, png_create_read_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -PNG_EXPORTA(12, png_structp, png_create_write_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -#endif - -/* Write the PNG file signature. */ -PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); - -/* Write a PNG chunk - size, type, (optional) data, CRC. */ -PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep - chunk_name, png_const_bytep data, size_t length)); - -/* Write the start of a PNG chunk - length and chunk name. */ -PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, - png_const_bytep chunk_name, png_uint_32 length)); - -/* Write the data of a PNG chunk started with png_write_chunk_start(). */ -PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, - png_const_bytep data, size_t length)); - -/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ -PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); - -/* Allocate and initialize the info structure */ -PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), - PNG_ALLOCATED); - -/* DEPRECATED: this function allowed init structures to be created using the - * default allocation method (typically malloc). Use is deprecated in 1.6.0 and - * the API will be removed in the future. - */ -PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, - size_t png_info_struct_size), PNG_DEPRECATED); - -/* Writes all the PNG information before the image. */ -PNG_EXPORT(20, void, png_write_info_before_PLTE, - (png_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(21, void, png_write_info, - (png_structrp png_ptr, png_const_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. */ -PNG_EXPORT(22, void, png_read_info, - (png_structrp png_ptr, png_inforp info_ptr)); -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED - /* Convert to a US string format: there is no localization support in this - * routine. The original implementation used a 29 character buffer in - * png_struct, this will be removed in future versions. - */ -#if PNG_LIBPNG_VER < 10700 -/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ -PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, - png_const_timep ptime),PNG_DEPRECATED); -#endif -PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], - png_const_timep ptime)); -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED -/* Convert from a struct tm to png_time */ -PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, - const struct tm * ttime)); - -/* Convert from time_t to png_time. Uses gmtime() */ -PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); -#endif /* CONVERT_tIME */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ -PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); -PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); -PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); -PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion - * of a tRNS chunk if present. - */ -PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Use blue, green, red order for pixels. */ -PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand the grayscale to 24-bit RGB if necessary. */ -PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB to grayscale. */ -#define PNG_ERROR_ACTION_NONE 1 -#define PNG_ERROR_ACTION_WARN 2 -#define PNG_ERROR_ACTION_ERROR 3 -#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ - -PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, - int error_action, double red, double green)) -PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, - int error_action, png_fixed_point red, png_fixed_point green)) - -PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp - png_ptr)); -#endif - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, - png_colorp palette)); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* How the alpha channel is interpreted - this affects how the color channels - * of a PNG file are returned to the calling application when an alpha channel, - * or a tRNS chunk in a palette file, is present. - * - * This has no effect on the way pixels are written into a PNG output - * datastream. The color samples in a PNG datastream are never premultiplied - * with the alpha samples. - * - * The default is to return data according to the PNG specification: the alpha - * channel is a linear measure of the contribution of the pixel to the - * corresponding composited pixel, and the color channels are unassociated - * (not premultiplied). The gamma encoded color channels must be scaled - * according to the contribution and to do this it is necessary to undo - * the encoding, scale the color values, perform the composition and re-encode - * the values. This is the 'PNG' mode. - * - * The alternative is to 'associate' the alpha with the color information by - * storing color channel values that have been scaled by the alpha. - * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes - * (the latter being the two common names for associated alpha color channels). - * - * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha - * value is equal to the maximum value. - * - * The final choice is to gamma encode the alpha channel as well. This is - * broken because, in practice, no implementation that uses this choice - * correctly undoes the encoding before handling alpha composition. Use this - * choice only if other serious errors in the software or hardware you use - * mandate it; the typical serious error is for dark halos to appear around - * opaque areas of the composited PNG image because of arithmetic overflow. - * - * The API function png_set_alpha_mode specifies which of these choices to use - * with an enumerated 'mode' value and the gamma of the required output: - */ -#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ -#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ -#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ -#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ -#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ -#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ - -PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, - double output_gamma)) -PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, - int mode, png_fixed_point output_gamma)) -#endif - -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) -/* The output_gamma value is a screen gamma in libpng terminology: it expresses - * how to decode the output values, not how they are encoded. - */ -#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ -#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ -#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ -#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ -#endif - -/* The following are examples of calls to png_set_alpha_mode to achieve the - * required overall gamma correction and, where necessary, alpha - * premultiplication. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * This is the default libpng handling of the alpha channel - it is not - * pre-multiplied into the color components. In addition the call states - * that the output is for a sRGB system and causes all PNG files without gAMA - * chunks to be assumed to be encoded using sRGB. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * In this case the output is assumed to be something like an sRGB conformant - * display preceded by a power-law lookup table of power 1.45. This is how - * early Mac systems behaved. - * - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); - * This is the classic Jim Blinn approach and will work in academic - * environments where everything is done by the book. It has the shortcoming - * of assuming that input PNG data with no gamma information is linear - this - * is unlikely to be correct unless the PNG files where generated locally. - * Most of the time the output precision will be so low as to show - * significant banding in dark areas of the image. - * - * png_set_expand_16(pp); - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); - * This is a somewhat more realistic Jim Blinn inspired approach. PNG files - * are assumed to have the sRGB encoding if not marked with a gamma value and - * the output is always 16 bits per component. This permits accurate scaling - * and processing of the data. If you know that your input PNG files were - * generated locally you might need to replace PNG_DEFAULT_sRGB with the - * correct value for your system. - * - * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); - * If you just need to composite the PNG image onto an existing background - * and if you control the code that does this you can use the optimization - * setting. In this case you just copy completely opaque pixels to the - * output. For pixels that are not completely transparent (you just skip - * those) you do the composition math using png_composite or png_composite_16 - * below then encode the resultant 8-bit or 16-bit values to match the output - * encoding. - * - * Other cases - * If neither the PNG nor the standard linear encoding work for you because - * of the software or hardware you use then you have a big problem. The PNG - * case will probably result in halos around the image. The linear encoding - * will probably result in a washed out, too bright, image (it's actually too - * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably - * substantially reduce the halos. Alternatively try: - * - * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); - * This option will also reduce the halos, but there will be slight dark - * halos round the opaque parts of the image where the background is light. - * In the OPTIMIZED mode the halos will be light halos where the background - * is dark. Take your pick - the halos are unavoidable unless you can get - * your hardware/software fixed! (The OPTIMIZED approach is slightly - * faster.) - * - * When the default gamma of PNG files doesn't match the output gamma. - * If you have PNG files with no gamma information png_set_alpha_mode allows - * you to provide a default gamma, but it also sets the output gamma to the - * matching value. If you know your PNG files have a gamma that doesn't - * match the output you can take advantage of the fact that - * png_set_alpha_mode always sets the output gamma but only sets the PNG - * default if it is not already set: - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * The first call sets both the default and the output gamma values, the - * second call overrides the output gamma without changing the default. This - * is easier than achieving the same effect with png_set_gamma. You must use - * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will - * fire if more than one call to png_set_alpha_mode and png_set_background is - * made in the same read operation, however multiple calls with PNG_ALPHA_PNG - * are ignored. - */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ -PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, - int flags)); -/* The values of the PNG_FILLER_ defines should NOT be changed */ -# define PNG_FILLER_BEFORE 0 -# define PNG_FILLER_AFTER 1 -/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ -PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, - png_uint_32 filler, int flags)); -#endif /* READ_FILLER || WRITE_FILLER */ - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swap bytes in 16-bit depth files. */ -PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ -PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Swap packing order of pixels in bytes. */ -PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -/* Converts files to legal bit depths. */ -PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p - true_bits)); -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* Have the code handle the interlacing. Returns the number of passes. - * MUST be called before png_read_update_info or png_start_read_image, - * otherwise it will not have the desired effect. Note that it is still - * necessary to call png_read_row or png_read_rows png_get_image_height - * times for each pass. -*/ -PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -/* Invert monochrome files */ -PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS by replacing with a background color. Prior to - * libpng-1.5.4 this API must not be called before the PNG file header has been - * read. Doing so will result in unexpected behavior and possible warnings or - * errors if the PNG file contains a bKGD chunk. - */ -PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma)) -PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma)) -#endif -#ifdef PNG_READ_BACKGROUND_SUPPORTED -# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 -# define PNG_BACKGROUND_GAMMA_SCREEN 1 -# define PNG_BACKGROUND_GAMMA_FILE 2 -# define PNG_BACKGROUND_GAMMA_UNIQUE 3 -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale a 16-bit depth file down to 8-bit, accurately. */ -PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */ -/* Strip the second byte of information from a 16-bit depth file. */ -PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Turn on quantizing, and reduce the palette to the number of colors - * available. - */ -PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, - png_colorp palette, int num_palette, int maximum_colors, - png_const_uint_16p histogram, int full_quantize)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* The threshold on gamma processing is configurable but hard-wired into the - * library. The following is the floating point variant. - */ -#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) - -/* Handle gamma correction. Screen_gamma=(display_exponent). - * NOTE: this API simply sets the screen and file gamma values. It will - * therefore override the value for gamma in a PNG file if it is called after - * the file header has been read - use with care - call before reading the PNG - * file for best results! - * - * These routines accept the same gamma values as png_set_alpha_mode (described - * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either - * API (floating point or fixed.) Notice, however, that the 'file_gamma' value - * is the inverse of a 'screen gamma' value. - */ -PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, - double screen_gamma, double override_file_gamma)) -PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, - png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Set how many lines between output flushes - 0 for no flushing */ -PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); -/* Flush the current PNG output buffer */ -PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); -#endif - -/* Optional update palette with requested transformations */ -PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); - -/* Optional call to update the users info structure */ -PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, - png_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. */ -PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read a row of data. */ -PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, - png_bytep display_row)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the whole image into memory at once. */ -PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); -#endif - -/* Write a row of image data */ -PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, - png_const_bytep row)); - -/* Write a few rows of image data: (*row) is not written; however, the type - * is declared as writeable to maintain compatibility with previous versions - * of libpng and to allow the 'display_row' array from read_rows to be passed - * unchanged to write_rows. - */ -PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows)); - -/* Write the image data */ -PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); - -/* Write the end of the PNG file. */ -PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, - png_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. */ -PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); -#endif - -/* Free any memory associated with the png_info_struct */ -PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, - png_infopp info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr)); - -/* Set the libpng method of handling chunk CRC errors */ -PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, - int ancil_action)); - -/* Values for png_set_crc_action() say how to handle CRC errors in - * ancillary and critical chunks, and whether to use the data contained - * therein. Note that it is impossible to "discard" data in a critical - * chunk. For versions prior to 0.90, the action was always error/quit, - * whereas in version 0.90 and later, the action for CRC errors in ancillary - * chunks is warn/discard. These values should NOT be changed. - * - * value action:critical action:ancillary - */ -#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ -#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ -#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ -#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ -#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ -#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ - -#ifdef PNG_WRITE_SUPPORTED -/* These functions give the user control over the scan-line filtering in - * libpng and the compression methods used by zlib. These functions are - * mainly useful for testing, as the defaults should work with most users. - * Those users who are tight on memory or want faster performance at the - * expense of compression can modify them. See the compression library - * header file (zlib.h) for an explanation of the compression functions. - */ - -/* Set the filtering method(s) used by libpng. Currently, the only valid - * value for "method" is 0. - */ -PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, - int filters)); -#endif /* WRITE */ - -/* Flags for png_set_filter() to say which filters to use. The flags - * are chosen so that they don't conflict with real filter types - * below, in case they are supplied instead of the #defined constants. - * These values should NOT be changed. - */ -#define PNG_NO_FILTERS 0x00 -#define PNG_FILTER_NONE 0x08 -#define PNG_FILTER_SUB 0x10 -#define PNG_FILTER_UP 0x20 -#define PNG_FILTER_AVG 0x40 -#define PNG_FILTER_PAETH 0x80 -#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP) -#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH) - -/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. - * These defines should NOT be changed. - */ -#define PNG_FILTER_VALUE_NONE 0 -#define PNG_FILTER_VALUE_SUB 1 -#define PNG_FILTER_VALUE_UP 2 -#define PNG_FILTER_VALUE_AVG 3 -#define PNG_FILTER_VALUE_PAETH 4 -#define PNG_FILTER_VALUE_LAST 5 - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ -PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, - int heuristic_method, int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs)) -PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, - (png_structrp png_ptr, int heuristic_method, int num_weights, - png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs)) -#endif /* WRITE_WEIGHTED_FILTER */ - -/* The following are no longer used and will be removed from libpng-1.7: */ -#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ -#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ -#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ -#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ - -/* Set the library compression level. Currently, valid values range from - * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 - * (0 - no compression, 9 - "maximal" compression). Note that tests have - * shown that zlib compression levels 3-6 usually perform as well as level 9 - * for PNG images, and do considerably fewer calculations. In the future, - * these values may not correspond directly to the zlib compression levels. - */ -#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, - int level)); - -PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, - int mem_level)); - -PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, - int strategy)); - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, - int window_bits)); - -PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, - int method)); -#endif /* WRITE_CUSTOMIZE_COMPRESSION */ - -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -/* Also set zlib parameters for compressing non-IDAT chunks */ -PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, - int level)); - -PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, - int mem_level)); - -PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, - int strategy)); - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -PNG_EXPORT(225, void, png_set_text_compression_window_bits, - (png_structrp png_ptr, int window_bits)); - -PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, - int method)); -#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ -#endif /* WRITE */ - -/* These next functions are called for input/output, memory, and error - * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, - * and call standard C I/O routines such as fread(), fwrite(), and - * fprintf(). These functions can be made to use other I/O routines - * at run time for those applications that need to handle I/O in a - * different manner by calling png_set_???_fn(). See libpng-manual.txt for - * more information. - */ - -#ifdef PNG_STDIO_SUPPORTED -/* Initialize the input/output for the PNG file to the default functions. */ -PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); -#endif - -/* Replace the (error and abort), and warning functions with user - * supplied functions. If no messages are to be printed you must still - * write and use replacement functions. The replacement error_fn should - * still do a longjmp to the last setjmp location if you are using this - * method of error handling. If error_fn or warning_fn is NULL, the - * default function will be used. - */ - -PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, - png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); - -/* Return the user pointer associated with the error functions */ -PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); - -/* Replace the default data output functions with a user supplied one(s). - * If buffered output is not used, then output_flush_fn can be set to NULL. - * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time - * output_flush_fn will be ignored (and thus can be NULL). - * It is probably a mistake to use NULL for output_flush_fn if - * write_data_fn is not also NULL unless you have built libpng with - * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's - * default flush function, which uses the standard *FILE structure, will - * be used. - */ -PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); - -/* Replace the default data input function with a user supplied one. */ -PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn)); - -/* Return the user pointer associated with the I/O functions */ -PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); - -PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, - png_read_status_ptr read_row_fn)); - -PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, - png_write_status_ptr write_row_fn)); - -#ifdef PNG_USER_MEM_SUPPORTED -/* Replace the default memory allocation functions with user supplied one(s). */ -PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)); -/* Return the user pointer associated with the memory functions */ -PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr read_user_transform_fn)); -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr write_user_transform_fn)); -#endif - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, - png_voidp user_transform_ptr, int user_transform_depth, - int user_transform_channels)); -/* Return the user pointer associated with the user transform functions */ -PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, - (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -/* Return information about the row currently being processed. Note that these - * APIs do not fail but will return unexpected results if called outside a user - * transform callback. Also note that when transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); -PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -/* This callback is called only for *unknown* chunks. If - * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known - * chunks to be treated as unknown, however in this case the callback must do - * any processing required by the chunk (e.g. by calling the appropriate - * png_set_ APIs.) - * - * There is no write support - on write, by default, all the chunks in the - * 'unknown' list are written in the specified position. - * - * The integer return from the callback function is interpreted thus: - * - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the chunk will be saved. A critical - * chunk will cause an error at this point unless it is to be saved. - * positive: The chunk was handled, libpng will ignore/discard it. - * - * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about - * how this behavior will change in libpng 1.7 - */ -PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, - png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* Sets the function callbacks for the push reader, and a pointer to a - * user-defined structure available to the callback functions. - */ -PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, - png_voidp progressive_ptr, png_progressive_info_ptr info_fn, - png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); - -/* Returns the user pointer associated with the push read functions */ -PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, - (png_const_structrp png_ptr)); - -/* Function to be called when data becomes available */ -PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, - png_inforp info_ptr, png_bytep buffer, size_t buffer_size)); - -/* A function which may be called *only* within png_process_data to stop the - * processing of any more data. The function returns the number of bytes - * remaining, excluding any that libpng has cached internally. A subsequent - * call to png_process_data must supply these bytes again. If the argument - * 'save' is set to true the routine will first save all the pending data and - * will always return 0. - */ -PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save)); - -/* A function which may be called *only* outside (after) a call to - * png_process_data. It returns the number of bytes of data to skip in the - * input. Normally it will return 0, but if it returns a non-zero value the - * application must skip than number of bytes of input data and pass the - * following data to the next call to png_process_data. - */ -PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); - -/* Function that combines rows. 'new_row' is a flag that should come from - * the callback and be non-NULL if anything needs to be done; the library - * stores its own version of the new data internally and ignores the passed - * in value. - */ -PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, - png_bytep old_row, png_const_bytep new_row)); -#endif /* PROGRESSIVE_READ */ - -PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); -/* Added at libpng version 1.4.0 */ -PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Added at libpng version 1.2.4 */ -PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Frees a pointer allocated by png_malloc() */ -PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); - -/* Free data that was allocated internally */ -PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 free_me, int num)); - -/* Reassign the responsibility for freeing existing data, whether allocated - * by libpng or by the application; this works on the png_info structure passed - * in, without changing the state for other png_info structures. - */ -PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, - png_inforp info_ptr, int freer, png_uint_32 mask)); - -/* Assignments for png_data_freer */ -#define PNG_DESTROY_WILL_FREE_DATA 1 -#define PNG_SET_WILL_FREE_DATA 1 -#define PNG_USER_WILL_FREE_DATA 2 -/* Flags for png_ptr->free_me and info_ptr->free_me */ -#define PNG_FREE_HIST 0x0008U -#define PNG_FREE_ICCP 0x0010U -#define PNG_FREE_SPLT 0x0020U -#define PNG_FREE_ROWS 0x0040U -#define PNG_FREE_PCAL 0x0080U -#define PNG_FREE_SCAL 0x0100U -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_FREE_UNKN 0x0200U -#endif -/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */ -#define PNG_FREE_PLTE 0x1000U -#define PNG_FREE_TRNS 0x2000U -#define PNG_FREE_TEXT 0x4000U -#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */ -#define PNG_FREE_ALL 0xffffU -#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ - -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); -PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, - png_voidp ptr), PNG_DEPRECATED); -#endif - -#ifdef PNG_ERROR_TEXT_SUPPORTED -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); - -/* The same, but the chunk name is prepended to the error string. */ -PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); - -#else -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); -# define png_error(s1,s2) png_err(s1) -# define png_chunk_error(s1,s2) png_err(s1) -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* Non-fatal error in libpng. Can continue, but may have a problem. */ -PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); - -/* Non-fatal error in libpng, chunk name is prepended to message. */ -PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); -#else -# define png_warning(s1,s2) ((void)(s1)) -# define png_chunk_warning(s1,s2) ((void)(s1)) -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Benign error in libpng. Can continue, but may have a problem. - * User can choose whether to handle as a fatal error or as a warning. */ -PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); - -#ifdef PNG_READ_SUPPORTED -/* Same, chunk name is prepended to message (only during read) */ -PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); -#endif - -PNG_EXPORT(109, void, png_set_benign_errors, - (png_structrp png_ptr, int allowed)); -#else -# ifdef PNG_ALLOW_BENIGN_ERRORS -# define png_benign_error png_warning -# define png_chunk_benign_error png_chunk_warning -# else -# define png_benign_error png_error -# define png_chunk_benign_error png_chunk_error -# endif -#endif - -/* The png_set_ functions are for storing values in the png_info_struct. - * Similarly, the png_get_ calls are used to read values from the - * png_info_struct, either storing the parameters in the passed variables, or - * setting pointers into the png_info_struct where the data is stored. The - * png_get_ functions return a non-zero value if the data was available - * in info_ptr, or return zero and do not change any of the parameters if the - * data was not available. - * - * These functions should be used instead of directly accessing png_info - * to avoid problems with future changes in the size and internal layout of - * png_info_struct. - */ -/* Returns "flag" if chunk data is valid in info_ptr. */ -PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 flag)); - -/* Returns number of bytes needed to hold a transformed row. */ -PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -#ifdef PNG_INFO_IMAGE_SUPPORTED -/* Returns row_pointers, which is an array of pointers to scanlines that was - * returned from png_read_png(). - */ -PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Set row_pointers, which is an array of pointers to scanlines for use - * by png_write_png(). - */ -PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytepp row_pointers)); -#endif - -/* Returns number of color channels in image. */ -PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Returns image width in pixels. */ -PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image height in pixels. */ -PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image bit_depth. */ -PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image color_type. */ -PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image filter_type. */ -PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image interlace_type. */ -PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image compression_type. */ -PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image resolution in pixels per meter, from pHYs chunk data. */ -PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -/* Returns pixel aspect ratio, computed from pHYs chunk data. */ -PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) - -/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ -PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -#endif /* EASY_ACCESS */ - -#ifdef PNG_READ_SUPPORTED -/* Returns pointer to signature string read from PNG header */ -PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, - png_inforp info_ptr, png_color_16p *background)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_color_16p background)); -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, - double *red_y, double *green_x, double *green_y, double *blue_x, - double *blue_y)) -PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, - double *green_X, double *green_Y, double *green_Z, double *blue_X, - double *blue_Y, double *blue_Z)) -PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_white_x, png_fixed_point *int_white_y, - png_fixed_point *int_red_x, png_fixed_point *int_red_y, - png_fixed_point *int_green_x, png_fixed_point *int_green_y, - png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) -PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z)) -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, - png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, double green_x, - double green_y, double blue_x, double blue_y)) -PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, - png_inforp info_ptr, double red_X, double red_Y, double red_Z, - double green_X, double green_Y, double green_Z, double blue_X, - double blue_Y, double blue_Z)) -PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_white_x, - png_fixed_point int_white_y, png_fixed_point int_red_x, - png_fixed_point int_red_y, png_fixed_point int_green_x, - png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)) -PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z)) -#endif - -#ifdef PNG_eXIf_SUPPORTED -PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep *exif)); -PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep exif)); - -PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif)); -PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif)); -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *file_gamma)) -PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_file_gamma)) -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, - png_inforp info_ptr, double file_gamma)) -PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_file_gamma)) -#endif - -#ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_16p *hist)); -PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_uint_16p hist)); -#endif - -PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, - int *bit_depth, int *color_type, int *interlace_method, - int *compression_method, int *filter_method)); - -PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_method, int compression_method, - int filter_method)); - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, - int *unit_type)); -#endif - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, - png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, - int unit_type)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, - png_int_32 *X1, int *type, int *nparams, png_charp *units, - png_charpp *params)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, - int type, int nparams, png_const_charp units, png_charpp params)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); -#endif - -PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, - png_inforp info_ptr, png_colorp *palette, int *num_palette)); - -PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, - png_inforp info_ptr, png_const_colorp palette, int num_palette)); - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_color_8p *sig_bit)); -#endif - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_color_8p sig_bit)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *file_srgb_intent)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, - png_inforp info_ptr, int srgb_intent)); -PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, - png_inforp info_ptr, int srgb_intent)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, - png_inforp info_ptr, png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_sPLT_tpp entries)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); -#endif - -#ifdef PNG_TEXT_SUPPORTED -/* png_get_text also returns the number of text chunks in *num_text */ -PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, - png_inforp info_ptr, png_textp *text_ptr, int *num_text)); -#endif - -/* Note while png_set_text() will accept a structure whose text, - * language, and translated keywords are NULL pointers, the structure - * returned by png_get_text will always contain regular - * zero-terminated C strings. They might be empty strings but - * they will never be NULL pointers. - */ - -#ifdef PNG_TEXT_SUPPORTED -PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_textp text_ptr, int num_text)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, - png_inforp info_ptr, png_timep *mod_time)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_timep mod_time)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, - png_color_16p *trans_color)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, - png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, - png_const_color_16p trans_color)); -#endif - -#ifdef PNG_sCAL_SUPPORTED -PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *unit, double *width, double *height)) -#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ - defined(PNG_FLOATING_POINT_SUPPORTED) -/* NOTE: this API is currently implemented using floating point arithmetic, - * consequently it can only be used on systems with floating point support. - * In any case the range of values supported by png_fixed_point is small and it - * is highly recommended that png_get_sCAL_s be used instead. - */ -PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, - png_fixed_point *width, png_fixed_point *height)) -#endif -PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, - (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, - png_charpp swidth, png_charpp sheight)); - -PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, double width, double height)) -PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, png_fixed_point width, - png_fixed_point height)) -PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, - png_const_charp swidth, png_const_charp sheight)); -#endif /* sCAL */ - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -/* Provide the default handling for all unknown chunks or, optionally, for - * specific unknown chunks. - * - * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was - * ignored and the default was used, the per-chunk setting only had an effect on - * write. If you wish to have chunk-specific handling on read in code that must - * work on earlier versions you must use a user chunk callback to specify the - * desired handling (keep or discard.) - * - * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The - * parameter is interpreted as follows: - * - * READ: - * PNG_HANDLE_CHUNK_AS_DEFAULT: - * Known chunks: do normal libpng processing, do not keep the chunk (but - * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) - * Unknown chunks: for a specific chunk use the global default, when used - * as the default discard the chunk data. - * PNG_HANDLE_CHUNK_NEVER: - * Discard the chunk data. - * PNG_HANDLE_CHUNK_IF_SAFE: - * Keep the chunk data if the chunk is not critical else raise a chunk - * error. - * PNG_HANDLE_CHUNK_ALWAYS: - * Keep the chunk data. - * - * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, - * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent - * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks - * it simply resets the behavior to the libpng default. - * - * INTERACTION WITH USER CHUNK CALLBACKS: - * The per-chunk handling is always used when there is a png_user_chunk_ptr - * callback and the callback returns 0; the chunk is then always stored *unless* - * it is critical and the per-chunk setting is other than ALWAYS. Notice that - * the global default is *not* used in this case. (In effect the per-chunk - * value is incremented to at least IF_SAFE.) - * - * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and - * per-chunk defaults will be honored. If you want to preserve the current - * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE - * as the default - if you don't do this libpng 1.6 will issue a warning. - * - * If you want unhandled unknown chunks to be discarded in libpng 1.6 and - * earlier simply return '1' (handled). - * - * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: - * If this is *not* set known chunks will always be handled by libpng and - * will never be stored in the unknown chunk list. Known chunks listed to - * png_set_keep_unknown_chunks will have no effect. If it is set then known - * chunks listed with a keep other than AS_DEFAULT will *never* be processed - * by libpng, in addition critical chunks must either be processed by the - * callback or saved. - * - * The IHDR and IEND chunks must not be listed. Because this turns off the - * default handling for chunks that would otherwise be recognized the - * behavior of libpng transformations may well become incorrect! - * - * WRITE: - * When writing chunks the options only apply to the chunks specified by - * png_set_unknown_chunks (below), libpng will *always* write known chunks - * required by png_set_ calls and will always write the core critical chunks - * (as required for PLTE). - * - * Each chunk in the png_set_unknown_chunks list is looked up in the - * png_set_keep_unknown_chunks list to find the keep setting, this is then - * interpreted as follows: - * - * PNG_HANDLE_CHUNK_AS_DEFAULT: - * Write safe-to-copy chunks and write other chunks if the global - * default is set to _ALWAYS, otherwise don't write this chunk. - * PNG_HANDLE_CHUNK_NEVER: - * Do not write the chunk. - * PNG_HANDLE_CHUNK_IF_SAFE: - * Write the chunk if it is safe-to-copy, otherwise do not write it. - * PNG_HANDLE_CHUNK_ALWAYS: - * Write the chunk. - * - * Note that the default behavior is effectively the opposite of the read case - - * in read unknown chunks are not stored by default, in write they are written - * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different - * - on write the safe-to-copy bit is checked, on read the critical bit is - * checked and on read if the chunk is critical an error will be raised. - * - * num_chunks: - * =========== - * If num_chunks is positive, then the "keep" parameter specifies the manner - * for handling only those chunks appearing in the chunk_list array, - * otherwise the chunk list array is ignored. - * - * If num_chunks is 0 the "keep" parameter specifies the default behavior for - * unknown chunks, as described above. - * - * If num_chunks is negative, then the "keep" parameter specifies the manner - * for handling all unknown chunks plus all chunks recognized by libpng - * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to - * be processed by libpng. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, - int keep, png_const_bytep chunk_list, int num_chunks)); -#endif /* HANDLE_AS_UNKNOWN */ - -/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; - * the result is therefore true (non-zero) if special handling is required, - * false for the default handling. - */ -PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, - png_const_bytep chunk_name)); -#endif /* SET_UNKNOWN_CHUNKS */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, - int num_unknowns)); - /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added - * unknowns to the location currently stored in the png_struct. This is - * invariably the wrong value on write. To fix this call the following API - * for each chunk in the list with the correct location. If you know your - * code won't be compiled on earlier versions you can rely on - * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing - * the correct thing. - */ - -PNG_EXPORT(175, void, png_set_unknown_chunk_location, - (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); - -PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, - png_inforp info_ptr, png_unknown_chunkpp entries)); -#endif - -/* Png_free_data() will turn off the "valid" flag for anything it frees. - * If you need to turn it off for a chunk that your application has freed, - * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); - */ -PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, - png_inforp info_ptr, int mask)); - -#ifdef PNG_INFO_IMAGE_SUPPORTED -/* The "params" pointer is currently not used and is for future expansion. */ -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); -#endif -#ifdef PNG_WRITE_SUPPORTED -PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); -#endif -#endif - -PNG_EXPORT(180, png_const_charp, png_get_copyright, - (png_const_structrp png_ptr)); -PNG_EXPORT(181, png_const_charp, png_get_header_ver, - (png_const_structrp png_ptr)); -PNG_EXPORT(182, png_const_charp, png_get_header_version, - (png_const_structrp png_ptr)); -PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, - (png_const_structrp png_ptr)); - -#ifdef PNG_MNG_FEATURES_SUPPORTED -PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, - png_uint_32 mng_features_permitted)); -#endif - -/* For use in png_set_keep_unknown, added to version 1.2.6 */ -#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 -#define PNG_HANDLE_CHUNK_NEVER 1 -#define PNG_HANDLE_CHUNK_IF_SAFE 2 -#define PNG_HANDLE_CHUNK_ALWAYS 3 -#define PNG_HANDLE_CHUNK_LAST 4 - -/* Strip the prepended error numbers ("#nnn ") from error and warning - * messages before passing them to the error or warning handler. - */ -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, - png_uint_32 strip_mode)); -#endif - -/* Added in libpng-1.2.6 */ -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, - png_uint_32 user_width_max, png_uint_32 user_height_max)); -PNG_EXPORT(187, png_uint_32, png_get_user_width_max, - (png_const_structrp png_ptr)); -PNG_EXPORT(188, png_uint_32, png_get_user_height_max, - (png_const_structrp png_ptr)); -/* Added in libpng-1.4.0 */ -PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, - png_uint_32 user_chunk_cache_max)); -PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, - (png_const_structrp png_ptr)); -/* Added in libpng-1.4.1 */ -PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, - png_alloc_size_t user_chunk_cache_max)); -PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, - (png_const_structrp png_ptr)); -#endif - -#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) -PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_FP_EXPORT(196, float, png_get_x_offset_inches, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#endif - -PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, - png_const_inforp info_ptr)) -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#endif - -# ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -# endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ - -/* Added in libpng-1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); - -/* Removed from libpng 1.6; use png_get_io_chunk_type. */ -PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), - PNG_DEPRECATED) - -PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, - (png_const_structrp png_ptr)); - -/* The flags returned by png_get_io_state() are the following: */ -# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ -# define PNG_IO_READING 0x0001 /* currently reading */ -# define PNG_IO_WRITING 0x0002 /* currently writing */ -# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ -# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ -# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ -# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ -# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ -# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ -#endif /* IO_STATE */ - -/* Interlace support. The following macros are always defined so that if - * libpng interlace handling is turned off the macros may be used to handle - * interlaced images within the application. - */ -#define PNG_INTERLACE_ADAM7_PASSES 7 - -/* Two macros to return the first row and first column of the original, - * full, image which appears in a given pass. 'pass' is in the range 0 - * to 6 and the result is in the range 0 to 7. - */ -#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) -#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) - -/* A macro to return the offset between pixels in the output row for a pair of - * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that - * follows. Note that ROW_OFFSET is the offset from one row to the next whereas - * COL_OFFSET is from one column to the next, within a row. - */ -#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) -#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) - -/* Two macros to help evaluate the number of rows or columns in each - * pass. This is expressed as a shift - effectively log2 of the number or - * rows or columns in each 8x8 tile of the original image. - */ -#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) -#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) - -/* Hence two macros to determine the number of rows or columns in a given - * pass of an image given its height or width. In fact these macros may - * return non-zero even though the sub-image is empty, because the other - * dimension may be empty for a small image. - */ -#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) -#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) - -/* For the reader row callbacks (both progressive and sequential) it is - * necessary to find the row in the output image given a row in an interlaced - * image, so two more macros: - */ -#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ - (((y_in)<>(((7-(off))-(pass))<<2)) & 0xF) | \ - ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) - -#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ - ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) -#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ - ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) - -#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED -/* With these routines we avoid an integer divide, which will be slower on - * most machines. However, it does take more operations than the corresponding - * divide method, so it may be slower on a few RISC systems. There are two - * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. - * - * Note that the rounding factors are NOT supposed to be the same! 128 and - * 32768 are correct for the NODIV code; 127 and 32767 are correct for the - * standard method. - * - * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] - */ - - /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ - -# define png_composite(composite, fg, alpha, bg) \ - { \ - png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ - * (png_uint_16)(alpha) \ - + (png_uint_16)(bg)*(png_uint_16)(255 \ - - (png_uint_16)(alpha)) + 128); \ - (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \ - } - -# define png_composite_16(composite, fg, alpha, bg) \ - { \ - png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ - * (png_uint_32)(alpha) \ - + (png_uint_32)(bg)*(65535 \ - - (png_uint_32)(alpha)) + 32768); \ - (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \ - } - -#else /* Standard method using integer division */ - -# define png_composite(composite, fg, alpha, bg) \ - (composite) = \ - (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ - 127) / 255)) - -# define png_composite_16(composite, fg, alpha, bg) \ - (composite) = \ - (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ - (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ - 32767) / 65535)) -#endif /* READ_COMPOSITE_NODIV */ - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); -PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); -PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); -#endif - -PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, - png_const_bytep buf)); -/* No png_get_int_16 -- may be added if there's a real need for it. */ - -/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); -#endif -#ifdef PNG_SAVE_INT_32_SUPPORTED -PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); -#endif - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); -/* No png_save_int_16 -- may be added if there's a real need for it. */ -#endif - -#ifdef PNG_USE_READ_MACROS -/* Inline macros to do direct reads of bytes from the input buffer. - * The png_get_int_32() routine assumes we are using two's complement - * format for negative values, which is almost certainly true. - */ -# define PNG_get_uint_32(buf) \ - (((png_uint_32)(*(buf)) << 24) + \ - ((png_uint_32)(*((buf) + 1)) << 16) + \ - ((png_uint_32)(*((buf) + 2)) << 8) + \ - ((png_uint_32)(*((buf) + 3)))) - - /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the - * function) incorrectly returned a value of type png_uint_32. - */ -# define PNG_get_uint_16(buf) \ - ((png_uint_16) \ - (((unsigned int)(*(buf)) << 8) + \ - ((unsigned int)(*((buf) + 1))))) - -# define PNG_get_int_32(buf) \ - ((png_int_32)((*(buf) & 0x80) \ - ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \ - : (png_int_32)png_get_uint_32(buf))) - -/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, - * but defining a macro name prefixed with PNG_PREFIX. - */ -# ifndef PNG_PREFIX -# define png_get_uint_32(buf) PNG_get_uint_32(buf) -# define png_get_uint_16(buf) PNG_get_uint_16(buf) -# define png_get_int_32(buf) PNG_get_int_32(buf) -# endif -#else -# ifdef PNG_PREFIX - /* No macros; revert to the (redefined) function */ -# define PNG_get_uint_32 (png_get_uint_32) -# define PNG_get_uint_16 (png_get_uint_16) -# define PNG_get_int_32 (png_get_int_32) -# endif -#endif - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -PNG_EXPORT(242, void, png_set_check_for_invalid_index, - (png_structrp png_ptr, int allowed)); -# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, - png_const_infop info_ptr)); -# endif -#endif /* CHECK_FOR_INVALID_INDEX */ - -/******************************************************************************* - * Section 5: SIMPLIFIED API - ******************************************************************************* - * - * Please read the documentation in libpng-manual.txt (TODO: write said - * documentation) if you don't understand what follows. - * - * The simplified API hides the details of both libpng and the PNG file format - * itself. It allows PNG files to be read into a very limited number of - * in-memory bitmap formats or to be written from the same formats. If these - * formats do not accommodate your needs then you can, and should, use the more - * sophisticated APIs above - these support a wide variety of in-memory formats - * and a wide variety of sophisticated transformations to those formats as well - * as a wide variety of APIs to manipulate ancillary information. - * - * To read a PNG file using the simplified API: - * - * 1) Declare a 'png_image' structure (see below) on the stack, set the - * version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL - * (this is REQUIRED, your program may crash if you don't do it.) - * 2) Call the appropriate png_image_begin_read... function. - * 3) Set the png_image 'format' member to the required sample format. - * 4) Allocate a buffer for the image and, if required, the color-map. - * 5) Call png_image_finish_read to read the image and, if required, the - * color-map into your buffers. - * - * There are no restrictions on the format of the PNG input itself; all valid - * color types, bit depths, and interlace methods are acceptable, and the - * input image is transformed as necessary to the requested in-memory format - * during the png_image_finish_read() step. The only caveat is that if you - * request a color-mapped image from a PNG that is full-color or makes - * complex use of an alpha channel the transformation is extremely lossy and the - * result may look terrible. - * - * To write a PNG file using the simplified API: - * - * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. - * 2) Initialize the members of the structure that describe the image, setting - * the 'format' member to the format of the image samples. - * 3) Call the appropriate png_image_write... function with a pointer to the - * image and, if necessary, the color-map to write the PNG data. - * - * png_image is a structure that describes the in-memory format of an image - * when it is being read or defines the in-memory format of an image that you - * need to write: - */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) - -#define PNG_IMAGE_VERSION 1 - -typedef struct png_control *png_controlp; -typedef struct -{ - png_controlp opaque; /* Initialize to NULL, free with png_image_free */ - png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ - png_uint_32 width; /* Image width in pixels (columns) */ - png_uint_32 height; /* Image height in pixels (rows) */ - png_uint_32 format; /* Image format as defined below */ - png_uint_32 flags; /* A bit mask containing informational flags */ - png_uint_32 colormap_entries; - /* Number of entries in the color-map */ - - /* In the event of an error or warning the following field will be set to a - * non-zero value and the 'message' field will contain a '\0' terminated - * string with the libpng error or warning message. If both warnings and - * an error were encountered, only the error is recorded. If there - * are multiple warnings, only the first one is recorded. - * - * The upper 30 bits of this value are reserved, the low two bits contain - * a value as follows: - */ -# define PNG_IMAGE_WARNING 1 -# define PNG_IMAGE_ERROR 2 - /* - * The result is a two-bit code such that a value more than 1 indicates - * a failure in the API just called: - * - * 0 - no warning or error - * 1 - warning - * 2 - error - * 3 - error preceded by warning - */ -# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) - - png_uint_32 warning_or_error; - - char message[64]; -} png_image, *png_imagep; - -/* The samples of the image have one to four channels whose components have - * original values in the range 0 to 1.0: - * - * 1: A single gray or luminance channel (G). - * 2: A gray/luminance channel and an alpha channel (GA). - * 3: Three red, green, blue color channels (RGB). - * 4: Three color channels and an alpha channel (RGBA). - * - * The components are encoded in one of two ways: - * - * a) As a small integer, value 0..255, contained in a single byte. For the - * alpha channel the original value is simply value/255. For the color or - * luminance channels the value is encoded according to the sRGB specification - * and matches the 8-bit format expected by typical display devices. - * - * The color/gray channels are not scaled (pre-multiplied) by the alpha - * channel and are suitable for passing to color management software. - * - * b) As a value in the range 0..65535, contained in a 2-byte integer. All - * channels can be converted to the original value by dividing by 65535; all - * channels are linear. Color channels use the RGB encoding (RGB end-points) of - * the sRGB specification. This encoding is identified by the - * PNG_FORMAT_FLAG_LINEAR flag below. - * - * When the simplified API needs to convert between sRGB and linear colorspaces, - * the actual sRGB transfer curve defined in the sRGB specification (see the - * article at ) is used, not the gamma=1/2.2 - * approximation used elsewhere in libpng. - * - * When an alpha channel is present it is expected to denote pixel coverage - * of the color or luminance channels and is returned as an associated alpha - * channel: the color/gray channels are scaled (pre-multiplied) by the alpha - * value. - * - * The samples are either contained directly in the image data, between 1 and 8 - * bytes per pixel according to the encoding, or are held in a color-map indexed - * by bytes in the image data. In the case of a color-map the color-map entries - * are individual samples, encoded as above, and the image data has one byte per - * pixel to select the relevant sample from the color-map. - */ - -/* PNG_FORMAT_* - * - * #defines to be used in png_image::format. Each #define identifies a - * particular layout of sample data and, if present, alpha values. There are - * separate defines for each of the two component encodings. - * - * A format is built up using single bit flag values. All combinations are - * valid. Formats can be built up from the flag values or you can use one of - * the predefined values below. When testing formats always use the FORMAT_FLAG - * macros to test for individual features - future versions of the library may - * add new flags. - * - * When reading or writing color-mapped images the format should be set to the - * format of the entries in the color-map then png_image_{read,write}_colormap - * called to read or write the color-map and set the format correctly for the - * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! - * - * NOTE: libpng can be built with particular features disabled. If you see - * compiler errors because the definition of one of the following flags has been - * compiled out it is because libpng does not have the required support. It is - * possible, however, for the libpng configuration to enable the format on just - * read or just write; in that case you may see an error at run time. You can - * guard against this by checking for the definition of the appropriate - * "_SUPPORTED" macro, one of: - * - * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED - */ -#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ -#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ -#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2-byte channels else 1-byte */ -#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ - -#ifdef PNG_FORMAT_BGR_SUPPORTED -# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ -#endif - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED -# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ -#endif - -#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */ - -/* Commonly used formats have predefined macros. - * - * First the single byte (sRGB) formats: - */ -#define PNG_FORMAT_GRAY 0 -#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA -#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) -#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR -#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) -#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) -#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) - -/* Then the linear 2-byte formats. When naming these "Y" is used to - * indicate a luminance (gray) channel. - */ -#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR -#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) -#define PNG_FORMAT_LINEAR_RGB_ALPHA \ - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) - -/* With color-mapped formats the image data is one byte for each pixel, the byte - * is an index into the color-map which is formatted as above. To obtain a - * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP - * to one of the above definitions, or you can use one of the definitions below. - */ -#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) - -/* PNG_IMAGE macros - * - * These are convenience macros to derive information from a png_image - * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the - * actual image sample values - either the entries in the color-map or the - * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values - * for the pixels and will always return 1 for color-mapped formats. The - * remaining macros return information about the rows in the image and the - * complete image. - * - * NOTE: All the macros that take a png_image::format parameter are compile time - * constants if the format parameter is, itself, a constant. Therefore these - * macros can be used in array declarations and case labels where required. - * Similarly the macros are also pre-processor constants (sizeof is not used) so - * they can be used in #if tests. - * - * First the information about the samples. - */ -#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ - (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) - /* Return the total number of channels in a given format: 1..4 */ - -#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ - ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) - /* Return the size in bytes of a single component of a pixel or color-map - * entry (as appropriate) in the image: 1 or 2. - */ - -#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) - /* This is the size of the sample data for one sample. If the image is - * color-mapped it is the size of one color-map entry (and image pixels are - * one byte in size), otherwise it is the size of one image pixel. - */ - -#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) - /* The maximum size of the color-map required by the format expressed in a - * count of components. This can be used to compile-time allocate a - * color-map: - * - * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; - * - * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; - * - * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the - * information from one of the png_image_begin_read_ APIs and dynamically - * allocate the required memory. - */ - -/* Corresponding information about the pixels */ -#define PNG_IMAGE_PIXEL_(test,fmt)\ - (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) - -#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ - PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) - /* The number of separate channels (components) in a pixel; 1 for a - * color-mapped image. - */ - -#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ - PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) - /* The size, in bytes, of each component in a pixel; 1 for a color-mapped - * image. - */ - -#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) - /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ - -/* Information about the whole row, or whole image */ -#define PNG_IMAGE_ROW_STRIDE(image)\ - (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) - /* Return the total number of components in a single row of the image; this - * is the minimum 'row stride', the minimum count of components between each - * row. For a color-mapped image this is the minimum number of bytes in a - * row. - * - * WARNING: this macro overflows for some images with more than one component - * and very large image widths. libpng will refuse to process an image where - * this macro would overflow. - */ - -#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ - (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) - /* Return the size, in bytes, of an image buffer given a png_image and a row - * stride - the number of components to leave space for in each row. - * - * WARNING: this macro overflows a 32-bit integer for some large PNG images, - * libpng will refuse to process an image where such an overflow would occur. - */ - -#define PNG_IMAGE_SIZE(image)\ - PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) - /* Return the size, in bytes, of the image in memory given just a png_image; - * the row stride is the minimum stride required for the image. - */ - -#define PNG_IMAGE_COLORMAP_SIZE(image)\ - (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) - /* Return the size, in bytes, of the color-map of this image. If the image - * format is not a color-map format this will return a size sufficient for - * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if - * you don't want to allocate a color-map in this case. - */ - -/* PNG_IMAGE_FLAG_* - * - * Flags containing additional information about the image are held in the - * 'flags' field of png_image. - */ -#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 - /* This indicates that the RGB values of the in-memory bitmap do not - * correspond to the red, green and blue end-points defined by sRGB. - */ - -#define PNG_IMAGE_FLAG_FAST 0x02 - /* On write emphasise speed over compression; the resultant PNG file will be - * larger but will be produced significantly faster, particular for large - * images. Do not use this option for images which will be distributed, only - * used it when producing intermediate files that will be read back in - * repeatedly. For a typical 24-bit image the option will double the read - * speed at the cost of increasing the image size by 25%, however for many - * more compressible images the PNG file can be 10 times larger with only a - * slight speed gain. - */ - -#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 - /* On read if the image is a 16-bit per component image and there is no gAMA - * or sRGB chunk assume that the components are sRGB encoded. Notice that - * images output by the simplified API always have gamma information; setting - * this flag only affects the interpretation of 16-bit images from an - * external source. It is recommended that the application expose this flag - * to the user; the user can normally easily recognize the difference between - * linear and sRGB encoding. This flag has no effect on write - the data - * passed to the write APIs must have the correct encoding (as defined - * above.) - * - * If the flag is not set (the default) input 16-bit per component data is - * assumed to be linear. - * - * NOTE: the flag can only be set after the png_image_begin_read_ call, - * because that call initializes the 'flags' field. - */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* READ APIs - * --------- - * - * The png_image passed to the read APIs must have been initialized by setting - * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) - */ -#ifdef PNG_STDIO_SUPPORTED -PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, - const char *file_name)); - /* The named file is opened for read and the image header is filled in - * from the PNG header in the file. - */ - -PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, - FILE* file)); - /* The PNG header is read from the stdio FILE object. */ -#endif /* STDIO */ - -PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, - png_const_voidp memory, size_t size)); - /* The PNG header is read from the given memory buffer. */ - -PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, - png_const_colorp background, void *buffer, png_int_32 row_stride, - void *colormap)); - /* Finish reading the image into the supplied buffer and clean up the - * png_image structure. - * - * row_stride is the step, in byte or 2-byte units as appropriate, - * between adjacent rows. A positive stride indicates that the top-most row - * is first in the buffer - the normal top-down arrangement. A negative - * stride indicates that the bottom-most row is first in the buffer. - * - * background need only be supplied if an alpha channel must be removed from - * a png_byte format and the removal is to be done by compositing on a solid - * color; otherwise it may be NULL and any composition will be done directly - * onto the buffer. The value is an sRGB color to use for the background, - * for grayscale output the green channel is used. - * - * background must be supplied when an alpha channel must be removed from a - * single byte color-mapped output format, in other words if: - * - * 1) The original format from png_image_begin_read_from_* had - * PNG_FORMAT_FLAG_ALPHA set. - * 2) The format set by the application does not. - * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and - * PNG_FORMAT_FLAG_LINEAR *not* set. - * - * For linear output removing the alpha channel is always done by compositing - * on black and background is ignored. - * - * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must - * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. - * image->colormap_entries will be updated to the actual number of entries - * written to the colormap; this may be less than the original value. - */ - -PNG_EXPORT(238, void, png_image_free, (png_imagep image)); - /* Free any data allocated by libpng in image->opaque, setting the pointer to - * NULL. May be called at any time after the structure is initialized. - */ -#endif /* SIMPLIFIED_READ */ - -#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -/* WRITE APIS - * ---------- - * For write you must initialize a png_image structure to describe the image to - * be written. To do this use memset to set the whole structure to 0 then - * initialize fields describing your image. - * - * version: must be set to PNG_IMAGE_VERSION - * opaque: must be initialized to NULL - * width: image width in pixels - * height: image height in rows - * format: the format of the data (image and color-map) you wish to write - * flags: set to 0 unless one of the defined flags applies; set - * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB - * values do not correspond to the colors in sRGB. - * colormap_entries: set to the number of entries in the color-map (0 to 256) - */ -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, - const char *file, int convert_to_8bit, const void *buffer, - png_int_32 row_stride, const void *colormap)); - /* Write the image to the named file. */ - -PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, - int convert_to_8_bit, const void *buffer, png_int_32 row_stride, - const void *colormap)); - /* Write the image to the given (FILE*). */ -#endif /* SIMPLIFIED_WRITE_STDIO */ - -/* With all write APIs if image is in one of the linear formats with 16-bit - * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG - * gamma encoded according to the sRGB specification, otherwise a 16-bit linear - * encoded PNG file is written. - * - * With color-mapped data formats the colormap parameter point to a color-map - * with at least image->colormap_entries encoded in the specified format. If - * the format is linear the written PNG color-map will be converted to sRGB - * regardless of the convert_to_8_bit flag. - * - * With all APIs row_stride is handled as in the read APIs - it is the spacing - * from one row to the next in component sized units (1 or 2 bytes) and if - * negative indicates a bottom-up row layout in the buffer. If row_stride is - * zero, libpng will calculate it for you from the image width and number of - * channels. - * - * Note that the write API does not support interlacing, sub-8-bit pixels or - * most ancillary chunks. If you need to write text chunks (e.g. for copyright - * notices) you need to use one of the other APIs. - */ - -PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, - png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit, - const void *buffer, png_int_32 row_stride, const void *colormap)); - /* Write the image to the given memory buffer. The function both writes the - * whole PNG data stream to *memory and updates *memory_bytes with the count - * of bytes written. - * - * 'memory' may be NULL. In this case *memory_bytes is not read however on - * success the number of bytes which would have been written will still be - * stored in *memory_bytes. On failure *memory_bytes will contain 0. - * - * If 'memory' is not NULL it must point to memory[*memory_bytes] of - * writeable memory. - * - * If the function returns success memory[*memory_bytes] (if 'memory' is not - * NULL) contains the written PNG data. *memory_bytes will always be less - * than or equal to the original value. - * - * If the function returns false and *memory_bytes was not changed an error - * occurred during write. If *memory_bytes was changed, or is not 0 if - * 'memory' was NULL, the write would have succeeded but for the memory - * buffer being too small. *memory_bytes contains the required number of - * bytes and will be bigger that the original value. - */ - -#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\ - row_stride, colormap)\ - png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\ - row_stride, colormap) - /* Return the amount of memory in 'size' required to compress this image. - * The png_image structure 'image' must be filled in as in the above - * function and must not be changed before the actual write call, the buffer - * and all other parameters must also be identical to that in the final - * write call. The 'size' variable need not be initialized. - * - * NOTE: the macro returns true/false, if false is returned 'size' will be - * set to zero and the write failed and probably will fail if tried again. - */ - -/* You can pre-allocate the buffer by making sure it is of sufficient size - * regardless of the amount of compression achieved. The buffer size will - * always be bigger than the original image and it will never be filled. The - * following macros are provided to assist in allocating the buffer. - */ -#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height) - /* The number of uncompressed bytes in the PNG byte encoding of the image; - * uncompressing the PNG IDAT data will give this number of bytes. - * - * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this - * macro can because of the extra bytes used in the PNG byte encoding. You - * need to avoid this macro if your image size approaches 2^30 in width or - * height. The same goes for the remainder of these macros; they all produce - * bigger numbers than the actual in-memory image size. - */ -#ifndef PNG_ZLIB_MAX_SIZE -# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U) - /* An upper bound on the number of compressed bytes given 'b' uncompressed - * bytes. This is based on deflateBounds() in zlib; different - * implementations of zlib compression may conceivably produce more data so - * if your zlib implementation is not zlib itself redefine this macro - * appropriately. - */ -#endif - -#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\ - PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image)) - /* An upper bound on the size of the data in the PNG IDAT chunks. */ - -#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\ - ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\ - (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\ - 12U+3U*(image).colormap_entries/*PLTE data*/+\ - (((image).format&PNG_FORMAT_FLAG_ALPHA)?\ - 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\ - 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size)) - /* A helper for the following macro; if your compiler cannot handle the - * following macro use this one with the result of - * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most - * compilers should handle this just fine.) - */ - -#define PNG_IMAGE_PNG_SIZE_MAX(image)\ - PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image)) - /* An upper bound on the total length of the PNG data stream for 'image'. - * The result is of type png_alloc_size_t, on 32-bit systems this may - * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will - * run out of buffer space but return a corrected size which should work. - */ -#endif /* SIMPLIFIED_WRITE */ -/******************************************************************************* - * END OF SIMPLIFIED API - ******************************************************************************/ -#endif /* SIMPLIFIED_{READ|WRITE} */ - -/******************************************************************************* - * Section 6: IMPLEMENTATION OPTIONS - ******************************************************************************* - * - * Support for arbitrary implementation-specific optimizations. The API allows - * particular options to be turned on or off. 'Option' is the number of the - * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given - * by the PNG_OPTION_ defines below. - * - * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions, - * are detected at run time, however sometimes it may be impossible - * to do this in user mode, in which case it is necessary to discover - * the capabilities in an OS specific way. Such capabilities are - * listed here when libpng has support for them and must be turned - * ON by the application if present. - * - * SOFTWARE: sometimes software optimizations actually result in performance - * decrease on some architectures or systems, or with some sets of - * PNG images. 'Software' options allow such optimizations to be - * selected at run time. - */ -#ifdef PNG_SET_OPTION_SUPPORTED -#ifdef PNG_ARM_NEON_API_SUPPORTED -# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ -#endif -#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ -#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ -#ifdef PNG_MIPS_MSA_API_SUPPORTED -# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ -#endif -#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED -# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */ -#endif -#ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions - * supported */ -#endif -#ifdef PNG_MIPS_MMI_API_SUPPORTED -# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */ -#endif - -#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */ - -/* Return values: NOTE: there are four values and 'off' is *not* zero */ -#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ -#define PNG_OPTION_INVALID 1 /* Option number out of range */ -#define PNG_OPTION_OFF 2 -#define PNG_OPTION_ON 3 - -PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, - int onoff)); -#endif /* SET_OPTION */ - -/******************************************************************************* - * END OF HARDWARE AND SOFTWARE OPTIONS - ******************************************************************************/ - -/* Maintainer: Put new public prototypes here ^, in libpng.3, in project - * defs, and in scripts/symbols.def. - */ - -/* The last ordinal number (this is the *last* one already used; the next - * one to use is one more than this.) - */ -#ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(249); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -/* Do not put anything past this line */ -#endif /* PNG_H */ +/* png.h - header file for PNG reference library + * + * libpng version 1.6.59.git + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. (See LICENSE, below.) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.6.35, July 2018: + * Glenn Randers-Pehrson + * libpng versions 1.6.36, December 2018, through 1.6.58, April 2026: + * Cosmin Truta + * See also "Contributing Authors", below. + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE + * ========================================= + * + * PNG Reference Library License version 2 + * --------------------------------------- + * + * * Copyright (c) 1995-2026 The PNG Reference Library Authors. + * * Copyright (c) 2018-2026 Cosmin Truta. + * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * * Copyright (c) 1996-1997 Andreas Dilger. + * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * The software is supplied "as is", without warranty of any kind, + * express or implied, including, without limitation, the warranties + * of merchantability, fitness for a particular purpose, title, and + * non-infringement. In no event shall the Copyright owners, or + * anyone distributing the software, be liable for any damages or + * other liability, whether in contract, tort or otherwise, arising + * from, out of, or in connection with the software, or the use or + * other dealings in the software, even if advised of the possibility + * of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute + * this software, or portions hereof, for any purpose, without fee, + * subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you + * use this software in a product, an acknowledgment in the product + * documentation would be appreciated, but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must + * not be misrepresented as being the original software. + * + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. + * + * + * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) + * ----------------------------------------------------------------------- + * + * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are + * derived from libpng-1.0.6, and are distributed according to the same + * disclaimer and license as libpng-1.0.6 with the following individuals + * added to the list of Contributing Authors: + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Mans Rullgard + * Cosmin Truta + * Gilles Vollant + * James Yu + * Mandar Sahastrabuddhe + * Google Inc. + * Vadim Barkov + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of + * the library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is + * with the user. + * + * Some files in the "contrib" directory and some configure-generated + * files that are distributed with libpng have other copyright owners, and + * are released under other open source licenses. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from + * libpng-0.96, and are distributed according to the same disclaimer and + * license as libpng-0.96, with the following individuals added to the + * list of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, + * and are distributed according to the same disclaimer and license as + * libpng-0.88, with the following individuals added to the list of + * Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * Some files in the "scripts" directory have other copyright owners, + * but are released under this license. + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing + * Authors and Group 42, Inc. disclaim all warranties, expressed or + * implied, including, without limitation, the warranties of + * merchantability and of fitness for any purpose. The Contributing + * Authors and Group 42, Inc. assume no liability for direct, indirect, + * incidental, special, exemplary, or consequential damages, which may + * result from the use of the PNG Reference Library, even if advised of + * the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and must not + * be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, + * without fee, and encourage the use of this source code as a component + * to supporting the PNG file format in commercial products. If you use + * this source code in a product, acknowledgment is not required but would + * be appreciated. + * + * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. + * + * TRADEMARK + * ========= + * + * The name "libpng" has not been registered by the Copyright owners + * as a trademark in any jurisdiction. However, because libpng has + * been distributed and maintained world-wide, continually since 1995, + * the Copyright owners claim "common-law trademark protection" in any + * jurisdiction where common-law trademark is recognized. + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s", png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * ... + * 1.0.69 10 10069 10.so.0.69[.0] + * ... + * 1.2.59 13 10259 12.so.0.59[.0] + * ... + * 1.4.20 14 10420 14.so.0.20[.0] + * ... + * 1.5.30 15 10530 15.so.15.30[.0] + * ... + * 1.6.58 16 10658 16.so.16.58[.0] + * + * Henceforth the source version will match the shared-library major and + * minor numbers; the shared-library major version number will be used for + * changes in backward compatibility, as it is intended. + * The PNG_LIBPNG_VER macro, which is not used within libpng but is + * available for applications, is an unsigned integer of the form XYYZZ + * corresponding to the source version X.Y.Z (leading zeros in Y and Z). + * Beta versions were given the previous public release number plus a + * letter, until version 1.0.6j; from then on they were given the upcoming + * public release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as a W3C Recommendation and as an ISO/IEC Standard; see + * + */ + +#ifndef PNG_H +#define PNG_H + +/* This is not the place to learn how to use libpng. The file libpng-manual.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking + * at the actual function definitions and structure components. If that + * file has been stripped from your copy of libpng, you can find it at + * + * + * If you just need to read a PNG file and don't want to read the documentation + * skip to the end of this file and read the section entitled 'simplified API'. + */ + +/* Version information for png.h - this should match the version in png.c */ +#define PNG_LIBPNG_VER_STRING "1.6.59.git" +#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" + +/* The versions of shared library builds should stay in sync, going forward */ +#define PNG_LIBPNG_VER_SHAREDLIB 16 +#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ +#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ + +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ +#define PNG_LIBPNG_VER_MAJOR 1 +#define PNG_LIBPNG_VER_MINOR 6 +#define PNG_LIBPNG_VER_RELEASE 59 + +/* This should be zero for a public release, or non-zero for a + * development version. + */ +#define PNG_LIBPNG_VER_BUILD 1 + +/* Release Status */ +#define PNG_LIBPNG_BUILD_ALPHA 1 +#define PNG_LIBPNG_BUILD_BETA 2 +#define PNG_LIBPNG_BUILD_RC 3 +#define PNG_LIBPNG_BUILD_STABLE 4 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 + +/* Release-Specific Flags */ +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with + PNG_LIBPNG_BUILD_STABLE only */ +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_SPECIAL */ +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA + +/* Careful here. At one time, Guy wanted to use 082, but that + * would be octal. We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here + * (only version 1.0.0 was mis-numbered 100 instead of 10000). + * From version 1.0.1 it is: + * XXYYZZ, where XX=major, YY=minor, ZZ=release + */ +#define PNG_LIBPNG_VER 10659 /* 1.6.59.git */ + +/* Library configuration: these options cannot be changed after + * the library has been built. + */ +#ifndef PNGLCONF_H +/* If pnglibconf.h is missing, you can + * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h + */ +# include "pnglibconf.h" +#endif + +#ifndef PNG_VERSION_INFO_ONLY +/* Machine specific configuration. */ +# include "pngconf.h" +#endif + +/* + * Added at libpng-1.2.8 + * + * Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# ifdef PNG_LIBPNG_SPECIALBUILD +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#define png_libpng_ver png_get_header_ver(NULL) + +/* This file is arranged in several sections: + * + * 1. [omitted] + * 2. Any configuration options that can be specified by for the application + * code when it is built. (Build time configuration is in pnglibconf.h) + * 3. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 4. Exported library functions. + * 5. Simplified API. + * 6. Implementation options. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. + */ + +/* Section 1: [omitted] */ + +/* Section 2: run time configuration + * See pnglibconf.h for build time configuration + * + * Run time configuration allows the application to choose between + * implementations of certain arithmetic APIs. The default is set + * at build time and recorded in pnglibconf.h, but it is safe to + * override these (and only these) settings. Note that this won't + * change what the library does, only application code, and the + * settings can (and probably should) be made on a per-file basis + * by setting the #defines before including png.h + * + * Use macros to read integers from PNG data or use the exported + * functions? + * PNG_USE_READ_MACROS: use the macros (see below) Note that + * the macros evaluate their argument multiple times. + * PNG_NO_USE_READ_MACROS: call the relevant library function. + * + * Use the alternative algorithm for compositing alpha samples that + * does not use division? + * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' + * algorithm. + * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. + * + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is + * false? + * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error + * APIs to png_warning. + * Otherwise the calls are mapped to png_error. + */ + +/* Section 3: type definitions, including structures and compile time + * constants. + * See pngconf.h for base types that vary by machine/system + */ + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef char *png_libpng_version_1_6_59_git; + +/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. + * + * png_struct is the cache of information used while reading or writing a single + * PNG file. One of these is always required, although the simplified API + * (below) hides the creation and destruction of it. + */ +typedef struct png_struct_def png_struct; +typedef const png_struct * png_const_structp; +typedef png_struct * png_structp; +typedef png_struct * * png_structpp; + +/* png_info contains information read from or to be written to a PNG file. One + * or more of these must exist while reading or creating a PNG file. The + * information is not used by libpng during read but is used to control what + * gets written when a PNG file is created. "png_get_" function calls read + * information during read and "png_set_" functions calls write information + * when creating a PNG. + * been moved into a separate header file that is not accessible to + * applications. Read libpng-manual.txt or libpng.3 for more info. + */ +typedef struct png_info_def png_info; +typedef png_info * png_infop; +typedef const png_info * png_const_infop; +typedef png_info * * png_infopp; + +/* Types with names ending 'p' are pointer types. The corresponding types with + * names ending 'rp' are identical pointer types except that the pointer is + * marked 'restrict', which means that it is the only pointer to the object + * passed to the function. Applications should not use the 'restrict' types; + * it is always valid to pass 'p' to a pointer with a function argument of the + * corresponding 'rp' type. Different compilers have different rules with + * regard to type matching in the presence of 'restrict'. For backward + * compatibility libpng callbacks never have 'restrict' in their parameters and, + * consequentially, writing portable application code is extremely difficult if + * an attempt is made to use 'restrict'. + */ +typedef png_struct * PNG_RESTRICT png_structrp; +typedef const png_struct * PNG_RESTRICT png_const_structrp; +typedef png_info * PNG_RESTRICT png_inforp; +typedef const png_info * PNG_RESTRICT png_const_inforp; + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color * png_colorp; +typedef const png_color * png_const_colorp; +typedef png_color * * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 * png_color_16p; +typedef const png_color_16 * png_const_color_16p; +typedef png_color_16 * * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 * png_color_8p; +typedef const png_color_8 * png_const_color_8p; +typedef png_color_8 * * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry * png_sPLT_entryp; +typedef const png_sPLT_entry * png_const_sPLT_entryp; +typedef png_sPLT_entry * * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t * png_sPLT_tp; +typedef const png_sPLT_t * png_const_sPLT_tp; +typedef png_sPLT_t * * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text" fields can be a + * regular C string, an empty string, or a NULL pointer. + * However, the structure returned by png_get_text() will always contain + * the "text" field as a regular zero-terminated C string (possibly + * empty), never a NULL pointer, so it can be safely used in printf() and + * other string-handling functions. Note that the "itxt_length", "lang", and + * "lang_key" members of the structure only exist when the library is built + * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by + * default without iTXt support. Also note that when iTXt *is* supported, + * the "lang" and "lang_key" fields contain NULL pointers when the + * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or + * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the + * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" + * which is always 0 or 1, or its "compression method" which is always 0. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + size_t text_length; /* length of the text string */ + size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +} png_text; +typedef png_text * png_textp; +typedef const png_text * png_const_textp; +typedef png_text * * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time * png_timep; +typedef const png_time * png_const_timep; +typedef png_time * * png_timepp; + +#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_USER_CHUNKS_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + * + * The data in the structure is set by libpng on read and used on write. + */ +typedef struct png_unknown_chunk_t +{ + png_byte name[5]; /* Textual chunk name with '\0' terminator */ + png_byte *data; /* Data, should not be modified on read! */ + size_t size; + + /* On write 'location' must be set using the flag values listed below. + * Notice that on read it is set by libpng however the values stored have + * more bits set than are listed below. Always treat the value as a + * bitmask. On write set only one bit - setting multiple bits may cause the + * chunk to be written in multiple places. + */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; + +typedef png_unknown_chunk * png_unknown_chunkp; +typedef const png_unknown_chunk * png_const_unknown_chunkp; +typedef png_unknown_chunk * * png_unknown_chunkpp; +#endif + +/* Flag values for the unknown chunk location byte. */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_AFTER_IDAT 0x08 + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((size_t)(-1)) + +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 +#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) +#define PNG_FP_MIN (-PNG_FP_MAX) + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_ defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001U +#define PNG_INFO_sBIT 0x0002U +#define PNG_INFO_cHRM 0x0004U +#define PNG_INFO_PLTE 0x0008U +#define PNG_INFO_tRNS 0x0010U +#define PNG_INFO_bKGD 0x0020U +#define PNG_INFO_hIST 0x0040U +#define PNG_INFO_pHYs 0x0080U +#define PNG_INFO_oFFs 0x0100U +#define PNG_INFO_tIME 0x0200U +#define PNG_INFO_pCAL 0x0400U +#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ +#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */ +#define PNG_INFO_cICP 0x20000U /* PNGv3: 1.6.45 */ +#define PNG_INFO_cLLI 0x40000U /* PNGv3: 1.6.45 */ +#define PNG_INFO_mDCV 0x80000U /* PNGv3: 1.6.45 */ +/* APNG: these chunks are stored as unknown, these flags are never set + * however they are provided as a convenience for implementors of APNG and + * avoids any merge conflicts. + * + * Private chunks: these chunk names violate the chunk name recommendations + * because the chunk definitions have no signature and because the private + * chunks with these names have been reserved. Private definitions should + * avoid them. + */ +#define PNG_INFO_acTL 0x100000U /* PNGv3: 1.6.45: unknown */ +#define PNG_INFO_fcTL 0x200000U /* PNGv3: 1.6.45: unknown */ +#define PNG_INFO_fdAT 0x400000U /* PNGv3: 1.6.45: unknown */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + size_t rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info * png_row_infop; +typedef png_row_info * * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. + */ +typedef PNG_CALLBACK(void, *png_error_ptr, + (png_structp, png_const_charp)); +typedef PNG_CALLBACK(void, *png_rw_ptr, + (png_structp, png_bytep, size_t)); +typedef PNG_CALLBACK(void, *png_flush_ptr, + (png_structp)); +typedef PNG_CALLBACK(void, *png_read_status_ptr, + (png_structp, png_uint_32, int)); +typedef PNG_CALLBACK(void, *png_write_status_ptr, + (png_structp, png_uint_32, int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, + (png_structp, png_infop)); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, + (png_structp, png_infop)); + +/* The following callback receives png_uint_32 row_number, int pass for the + * png_bytep data of the row. When transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, + (png_structp, png_bytep, png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +typedef PNG_CALLBACK(void, *png_user_transform_ptr, + (png_structp, png_row_infop, png_bytep)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, + (png_structp, png_unknown_chunkp)); +#endif +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED +/* not used anywhere */ +/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This must match the function definition in , and the application + * must include this before png.h to obtain the definition of jmp_buf. The + * function is required to be PNG_NORETURN, but this is not checked. If the + * function does return the application will crash via an abort() or similar + * system level call. + * + * If you get a warning here while building the library you may need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! + */ +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ +/* Added to libpng-1.4.0 */ +#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ +/* Added to libpng-1.5.4 */ +#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ +#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */ +#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ +#endif + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. + */ +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, + (png_structp, png_alloc_size_t)); +typedef PNG_CALLBACK(void, *png_free_ptr, + (png_structp, png_voidp)); + +/* Section 4: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes + */ + +/* Returns the version number of the library */ +PNG_EXPORT(1, png_uint_32, png_access_version_number, + (void)); + +/* Tell lib we have already handled the first magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +PNG_EXPORT(2, void, png_set_sig_bytes, + (png_structrp png_ptr, int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (i.e. return non-zero). + */ +PNG_EXPORT(3, int, png_sig_cmp, + (png_const_bytep sig, size_t start, size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0). + */ +#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */ + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); + +PNG_EXPORT(6, size_t, png_get_compression_buffer_size, + (png_const_structrp png_ptr)); + +PNG_EXPORT(7, void, png_set_compression_buffer_size, + (png_structrp png_ptr, size_t size)); + +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp + * match up. + */ +#ifdef PNG_SETJMP_SUPPORTED +/* This function returns the jmp_buf built in to *png_ptr. It must be + * supplied with an appropriate 'longjmp' function to use on that jmp_buf + * unless the default error function is overridden in which case NULL is + * acceptable. The size of the jmp_buf is checked against the actual size + * allocated by the library - the call will return NULL on a mismatch + * indicating an ABI mismatch. + */ +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, + (png_structrp png_ptr, png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); +# define png_jmpbuf(png_ptr) \ + (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) +#endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, + (png_const_structrp png_ptr, int val), + PNG_NORETURN); + +#ifdef PNG_READ_SUPPORTED +/* Reset the compression stream */ +PNG_EXPORTA(10, int, png_reset_zstream, + (png_structrp png_ptr), + PNG_DEPRECATED); +#endif + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(11, png_structp, png_create_read_struct_2, + (png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, png_create_write_struct_2, + (png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +#endif + +/* Write the PNG file signature. */ +PNG_EXPORT(13, void, png_write_sig, + (png_structrp png_ptr)); + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +PNG_EXPORT(14, void, png_write_chunk, + (png_structrp png_ptr, + png_const_bytep chunk_name, png_const_bytep data, size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +PNG_EXPORT(15, void, png_write_chunk_start, + (png_structrp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +PNG_EXPORT(16, void, png_write_chunk_data, + (png_structrp png_ptr, + png_const_bytep data, size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +PNG_EXPORT(17, void, png_write_chunk_end, + (png_structrp png_ptr)); + +/* Allocate and initialize the info structure */ +PNG_EXPORTA(18, png_infop, png_create_info_struct, + (png_const_structrp png_ptr), + PNG_ALLOCATED); + +/* DEPRECATED: this function allowed init structures to be created using the + * default allocation method (typically malloc). Use is deprecated in 1.6.0 and + * the API will be removed in the future. + */ +PNG_EXPORTA(19, void, png_info_init_3, + (png_infopp info_ptr, size_t png_info_struct_size), + PNG_DEPRECATED); + +/* Writes all the PNG information before the image. */ +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. */ +PNG_EXPORT(22, void, png_read_info, + (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +#ifdef PNG_TIME_RFC1123_SUPPORTED + /* Convert to a US string format: there is no localization support in this + * routine. The original implementation used a 29 character buffer in + * png_struct, this will be removed in future versions. + */ +#if PNG_LIBPNG_VER < 10700 +/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ +PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, + (png_structrp png_ptr, png_const_timep ptime), + PNG_DEPRECATED); +#endif +PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, + (char out[29], png_const_timep ptime)); +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED +/* Convert from a struct tm to png_time */ +PNG_EXPORT(24, void, png_convert_from_struct_tm, + (png_timep ptime, const struct tm * ttime)); + +/* Convert from time_t to png_time. Uses gmtime() */ +PNG_EXPORT(25, void, png_convert_from_time_t, + (png_timep ptime, time_t ttime)); +#endif /* CONVERT_tIME */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +PNG_EXPORT(26, void, png_set_expand, + (png_structrp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, + (png_structrp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, + (png_structrp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, + (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion + * of a tRNS chunk if present. + */ +PNG_EXPORT(221, void, png_set_expand_16, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +PNG_EXPORT(30, void, png_set_bgr, + (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand the grayscale to 24-bit RGB if necessary. */ +PNG_EXPORT(31, void, png_set_gray_to_rgb, + (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB to grayscale. */ +#define PNG_ERROR_ACTION_NONE 1 +#define PNG_ERROR_ACTION_WARN 2 +#define PNG_ERROR_ACTION_ERROR 3 +#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ + +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, + (png_structrp png_ptr, + int error_action, double red, double green)) +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, + (png_structrp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)) + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED +PNG_EXPORT(35, void, png_build_grayscale_palette, + (int bit_depth, png_colorp palette)); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* How the alpha channel is interpreted - this affects how the color channels + * of a PNG file are returned to the calling application when an alpha channel, + * or a tRNS chunk in a palette file, is present. + * + * This has no effect on the way pixels are written into a PNG output + * datastream. The color samples in a PNG datastream are never premultiplied + * with the alpha samples. + * + * The default is to return data according to the PNG specification: the alpha + * channel is a linear measure of the contribution of the pixel to the + * corresponding composited pixel, and the color channels are unassociated + * (not premultiplied). The gamma encoded color channels must be scaled + * according to the contribution and to do this it is necessary to undo + * the encoding, scale the color values, perform the composition and re-encode + * the values. This is the 'PNG' mode. + * + * The alternative is to 'associate' the alpha with the color information by + * storing color channel values that have been scaled by the alpha. + * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes + * (the latter being the two common names for associated alpha color channels). + * + * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha + * value is equal to the maximum value. + * + * The final choice is to gamma encode the alpha channel as well. This is + * broken because, in practice, no implementation that uses this choice + * correctly undoes the encoding before handling alpha composition. Use this + * choice only if other serious errors in the software or hardware you use + * mandate it; the typical serious error is for dark halos to appear around + * opaque areas of the composited PNG image because of arithmetic overflow. + * + * The API function png_set_alpha_mode specifies which of these choices to use + * with an enumerated 'mode' value and the gamma of the required output: + */ +#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ +#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ +#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ +#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ +#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ + +PNG_FP_EXPORT(227, void, png_set_alpha_mode, + (png_structrp png_ptr, int mode, double output_gamma)) +PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, + (png_structrp png_ptr, int mode, png_fixed_point output_gamma)) +#endif + +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* The output_gamma value is a screen gamma in libpng terminology: it expresses + * how to decode the output values, not how they are encoded. + */ +#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ +#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ +#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ +#endif + +/* The following are examples of calls to png_set_alpha_mode to achieve the + * required overall gamma correction and, where necessary, alpha + * premultiplication. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * This is the default libpng handling of the alpha channel - it is not + * pre-multiplied into the color components. In addition the call states + * that the output is for a sRGB system and causes all PNG files without gAMA + * chunks to be assumed to be encoded using sRGB. + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * In this case the output is assumed to be something like an sRGB conformant + * display preceded by a power-law lookup table of power 1.45. This is how + * early Mac systems behaved. + * + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); + * This is the classic Jim Blinn approach and will work in academic + * environments where everything is done by the book. It has the shortcoming + * of assuming that input PNG data with no gamma information is linear - this + * is unlikely to be correct unless the PNG files where generated locally. + * Most of the time the output precision will be so low as to show + * significant banding in dark areas of the image. + * + * png_set_expand_16(pp); + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); + * This is a somewhat more realistic Jim Blinn inspired approach. PNG files + * are assumed to have the sRGB encoding if not marked with a gamma value and + * the output is always 16 bits per component. This permits accurate scaling + * and processing of the data. If you know that your input PNG files were + * generated locally you might need to replace PNG_DEFAULT_sRGB with the + * correct value for your system. + * + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); + * If you just need to composite the PNG image onto an existing background + * and if you control the code that does this you can use the optimization + * setting. In this case you just copy completely opaque pixels to the + * output. For pixels that are not completely transparent (you just skip + * those) you do the composition math using png_composite or png_composite_16 + * below then encode the resultant 8-bit or 16-bit values to match the output + * encoding. + * + * Other cases + * If neither the PNG nor the standard linear encoding work for you because + * of the software or hardware you use then you have a big problem. The PNG + * case will probably result in halos around the image. The linear encoding + * will probably result in a washed out, too bright, image (it's actually too + * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably + * substantially reduce the halos. Alternatively try: + * + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); + * This option will also reduce the halos, but there will be slight dark + * halos round the opaque parts of the image where the background is light. + * In the OPTIMIZED mode the halos will be light halos where the background + * is dark. Take your pick - the halos are unavoidable unless you can get + * your hardware/software fixed! (The OPTIMIZED approach is slightly + * faster.) + * + * When the default gamma of PNG files doesn't match the output gamma. + * If you have PNG files with no gamma information png_set_alpha_mode allows + * you to provide a default gamma, but it also sets the output gamma to the + * matching value. If you know your PNG files have a gamma that doesn't + * match the output you can take advantage of the fact that + * png_set_alpha_mode always sets the output gamma but only sets the PNG + * default if it is not already set: + * + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); + * The first call sets both the default and the output gamma values, the + * second call overrides the output gamma without changing the default. This + * is easier than achieving the same effect with png_set_gamma. You must use + * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will + * fire if more than one call to png_set_alpha_mode and png_set_background is + * made in the same read operation, however multiple calls with PNG_ALPHA_PNG + * are ignored. + */ + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +PNG_EXPORT(36, void, png_set_strip_alpha, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXPORT(37, void, png_set_swap_alpha, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXPORT(38, void, png_set_invert_alpha, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ +PNG_EXPORT(39, void, png_set_filler, + (png_structrp png_ptr, png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +# define PNG_FILLER_BEFORE 0 +# define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ +PNG_EXPORT(40, void, png_set_add_alpha, + (png_structrp png_ptr, png_uint_32 filler, int flags)); +#endif /* READ_FILLER || WRITE_FILLER */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +PNG_EXPORT(41, void, png_set_swap, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +PNG_EXPORT(42, void, png_set_packing, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +PNG_EXPORT(43, void, png_set_packswap, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +PNG_EXPORT(44, void, png_set_shift, + (png_structrp png_ptr, png_const_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, + (png_structrp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +PNG_EXPORT(46, void, png_set_invert_mono, + (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS by replacing with a background color. Prior to + * libpng-1.5.4 this API must not be called before the PNG file header has been + * read. Doing so will result in unexpected behavior and possible warnings or + * errors if the PNG file contains a bKGD chunk. + */ +PNG_FP_EXPORT(47, void, png_set_background, + (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)) +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, + (png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)) +#endif +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +# define PNG_BACKGROUND_GAMMA_SCREEN 1 +# define PNG_BACKGROUND_GAMMA_FILE 2 +# define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale a 16-bit depth file down to 8-bit, accurately. */ +PNG_EXPORT(229, void, png_set_scale_16, + (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */ +/* Strip the second byte of information from a 16-bit depth file. */ +PNG_EXPORT(48, void, png_set_strip_16, + (png_structrp png_ptr)); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Turn on quantizing, and reduce the palette to the number of colors + * available. + */ +PNG_EXPORT(49, void, png_set_quantize, + (png_structrp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_const_uint_16p histogram, int full_quantize)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) + +/* Handle gamma correction. Screen_gamma=(display_exponent). + * NOTE: this API simply sets the screen and file gamma values. It will + * therefore override the value for gamma in a PNG file if it is called after + * the file header has been read - use with care - call before reading the PNG + * file for best results! + * + * These routines accept the same gamma values as png_set_alpha_mode (described + * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either + * API (floating point or fixed.) Notice, however, that the 'file_gamma' value + * is the inverse of a 'screen gamma' value. + */ +PNG_FP_EXPORT(50, void, png_set_gamma, + (png_structrp png_ptr, + double screen_gamma, double override_file_gamma)) +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, + (png_structrp png_ptr, + png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set how many lines between output flushes - 0 for no flushing */ +PNG_EXPORT(51, void, png_set_flush, + (png_structrp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +PNG_EXPORT(52, void, png_write_flush, + (png_structrp png_ptr)); +#endif + +/* Optional update palette with requested transformations */ +PNG_EXPORT(53, void, png_start_read_image, + (png_structrp png_ptr)); + +/* Optional call to update the users info structure */ +PNG_EXPORT(54, void, png_read_update_info, + (png_structrp png_ptr, png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. */ +PNG_EXPORT(55, void, png_read_rows, + (png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read a row of data. */ +PNG_EXPORT(56, void, png_read_row, + (png_structrp png_ptr, png_bytep row, png_bytep display_row)); +#endif + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the whole image into memory at once. */ +PNG_EXPORT(57, void, png_read_image, + (png_structrp png_ptr, png_bytepp image)); +#endif + +/* Write a row of image data */ +PNG_EXPORT(58, void, png_write_row, + (png_structrp png_ptr, png_const_bytep row)); + +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, + (png_structrp png_ptr, png_bytepp row, png_uint_32 num_rows)); + +/* Write the image data */ +PNG_EXPORT(60, void, png_write_image, + (png_structrp png_ptr, png_bytepp image)); + +/* Write the end of the PNG file. */ +PNG_EXPORT(61, void, png_write_end, + (png_structrp png_ptr, png_inforp info_ptr)); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. */ +PNG_EXPORT(62, void, png_read_end, + (png_structrp png_ptr, png_inforp info_ptr)); +#endif + +/* Free any memory associated with the png_info_struct */ +PNG_EXPORT(63, void, png_destroy_info_struct, + (png_const_structrp png_ptr, png_infopp info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(64, void, png_destroy_read_struct, + (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* Free any memory associated with the png_struct and the png_info_structs */ +PNG_EXPORT(65, void, png_destroy_write_struct, + (png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* Set the libpng method of handling chunk CRC errors */ +PNG_EXPORT(66, void, png_set_crc_action, + (png_structrp png_ptr, int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +#ifdef PNG_WRITE_SUPPORTED +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explanation of the compression functions. + */ + +/* Set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +PNG_EXPORT(67, void, png_set_filter, + (png_structrp png_ptr, int method, int filters)); +#endif /* WRITE */ + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP) +#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, + (png_structrp png_ptr, + int heuristic_method, int num_weights, + png_const_doublep filter_weights, + png_const_doublep filter_costs)) +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structrp png_ptr, + int heuristic_method, int num_weights, + png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs)) +#endif /* WRITE_WEIGHTED_FILTER */ + +/* The following are no longer used and will be removed from libpng-1.7: */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer calculations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +PNG_EXPORT(69, void, png_set_compression_level, + (png_structrp png_ptr, int level)); + +PNG_EXPORT(70, void, png_set_compression_mem_level, + (png_structrp png_ptr, int mem_level)); + +PNG_EXPORT(71, void, png_set_compression_strategy, + (png_structrp png_ptr, int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(72, void, png_set_compression_window_bits, + (png_structrp png_ptr, int window_bits)); + +PNG_EXPORT(73, void, png_set_compression_method, + (png_structrp png_ptr, int method)); +#endif /* WRITE_CUSTOMIZE_COMPRESSION */ + +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +/* Also set zlib parameters for compressing non-IDAT chunks */ +PNG_EXPORT(222, void, png_set_text_compression_level, + (png_structrp png_ptr, int level)); + +PNG_EXPORT(223, void, png_set_text_compression_mem_level, + (png_structrp png_ptr, int mem_level)); + +PNG_EXPORT(224, void, png_set_text_compression_strategy, + (png_structrp png_ptr, int strategy)); + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +PNG_EXPORT(225, void, png_set_text_compression_window_bits, + (png_structrp png_ptr, int window_bits)); + +PNG_EXPORT(226, void, png_set_text_compression_method, + (png_structrp png_ptr, int method)); +#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ +#endif /* WRITE */ + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng-manual.txt for + * more information. + */ + +#ifdef PNG_STDIO_SUPPORTED +/* Initialize the input/output for the PNG file to the default functions. */ +PNG_EXPORT(74, void, png_init_io, + (png_structrp png_ptr, FILE *fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +PNG_EXPORT(75, void, png_set_error_fn, + (png_structrp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +PNG_EXPORT(76, png_voidp, png_get_error_ptr, + (png_const_structrp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. + */ +PNG_EXPORT(77, void, png_set_write_fn, + (png_structrp png_ptr, + png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +PNG_EXPORT(78, void, png_set_read_fn, + (png_structrp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +PNG_EXPORT(79, png_voidp, png_get_io_ptr, + (png_const_structrp png_ptr)); + +PNG_EXPORT(80, void, png_set_read_status_fn, + (png_structrp png_ptr, png_read_status_ptr read_row_fn)); + +PNG_EXPORT(81, void, png_set_write_status_fn, + (png_structrp png_ptr, png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +PNG_EXPORT(82, void, png_set_mem_fn, + (png_structrp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(84, void, png_set_read_user_transform_fn, + (png_structrp png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +PNG_EXPORT(85, void, png_set_write_user_transform_fn, + (png_structrp png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +PNG_EXPORT(86, void, png_set_user_transform_info, + (png_structrp png_ptr, + png_voidp user_transform_ptr, + int user_transform_depth, int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +/* Return information about the row currently being processed. Note that these + * APIs do not fail but will return unexpected results if called outside a user + * transform callback. Also note that when transforming an interlaced image the + * row number is the row number within the sub-image of the interlace pass, so + * the value will increase to the height of the sub-image (not the full image) + * then reset to 0 for the next pass. + * + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to + * find the output pixel (x,y) given an interlaced sub-image pixel + * (row,col,pass). (See below for these macros.) + */ +PNG_EXPORT(217, png_uint_32, png_get_current_row_number, + (png_const_structrp)); +PNG_EXPORT(218, png_byte, png_get_current_pass_number, + (png_const_structrp)); +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +/* This callback is called only for *unknown* chunks. If + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known + * chunks to be treated as unknown, however in this case the callback must do + * any processing required by the chunk (e.g. by calling the appropriate + * png_set_ APIs.) + * + * There is no write support - on write, by default, all the chunks in the + * 'unknown' list are written in the specified position. + * + * The integer return from the callback function is interpreted thus: + * + * negative: An error occurred; png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be saved. A critical + * chunk will cause an error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + * + * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about + * how this behavior will change in libpng 1.7 + */ +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, + (png_structrp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, + (png_const_structrp png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +PNG_EXPORT(90, void, png_set_progressive_read_fn, + (png_structrp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); + +/* Returns the user pointer associated with the push read functions */ +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, + (png_const_structrp png_ptr)); + +/* Function to be called when data becomes available */ +PNG_EXPORT(92, void, png_process_data, + (png_structrp png_ptr, + png_inforp info_ptr, png_bytep buffer, size_t buffer_size)); + +/* A function which may be called *only* within png_process_data to stop the + * processing of any more data. The function returns the number of bytes + * remaining, excluding any that libpng has cached internally. A subsequent + * call to png_process_data must supply these bytes again. If the argument + * 'save' is set to true the routine will first save all the pending data and + * will always return 0. + */ +PNG_EXPORT(219, size_t, png_process_data_pause, + (png_structrp, int save)); + +/* A function which may be called *only* outside (after) a call to + * png_process_data. It returns the number of bytes of data to skip in the + * input. Normally it will return 0, but if it returns a non-zero value the + * application must skip than number of bytes of input data and pass the + * following data to the next call to png_process_data. + */ +PNG_EXPORT(220, png_uint_32, png_process_data_skip, + (png_structrp)); + +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. + */ +PNG_EXPORT(93, void, png_progressive_combine_row, + (png_const_structrp png_ptr, + png_bytep old_row, png_const_bytep new_row)); +#endif /* PROGRESSIVE_READ */ + +PNG_EXPORTA(94, png_voidp, png_malloc, + (png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); +/* Added at libpng version 1.4.0 */ +PNG_EXPORTA(95, png_voidp, png_calloc, + (png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); + +/* Added at libpng version 1.2.4 */ +PNG_EXPORTA(96, png_voidp, png_malloc_warn, + (png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); + +/* Frees a pointer allocated by png_malloc() */ +PNG_EXPORT(97, void, png_free, + (png_const_structrp png_ptr, png_voidp ptr)); + +/* Free data that was allocated internally */ +PNG_EXPORT(98, void, png_free_data, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 free_me, int num)); + +/* Reassign the responsibility for freeing existing data, whether allocated + * by libpng or by the application; this works on the png_info structure passed + * in, without changing the state for other png_info structures. + */ +PNG_EXPORT(99, void, png_data_freer, + (png_const_structrp png_ptr, png_inforp info_ptr, + int freer, png_uint_32 mask)); + +/* Assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008U +#define PNG_FREE_ICCP 0x0010U +#define PNG_FREE_SPLT 0x0020U +#define PNG_FREE_ROWS 0x0040U +#define PNG_FREE_PCAL 0x0080U +#define PNG_FREE_SCAL 0x0100U +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_FREE_UNKN 0x0200U +#endif +/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */ +#define PNG_FREE_PLTE 0x1000U +#define PNG_FREE_TRNS 0x2000U +#define PNG_FREE_TEXT 0x4000U +#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */ +#define PNG_FREE_ALL 0xffffU +#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +PNG_EXPORTA(100, png_voidp, png_malloc_default, + (png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED PNG_DEPRECATED); +PNG_EXPORTA(101, void, png_free_default, + (png_const_structrp png_ptr, png_voidp ptr), + PNG_DEPRECATED); +#endif + +#ifdef PNG_ERROR_TEXT_SUPPORTED +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(102, void, png_error, + (png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN); + +/* The same, but the chunk name is prepended to the error string. */ +PNG_EXPORTA(103, void, png_chunk_error, + (png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN); + +#else +/* Fatal error in PNG image of libpng - can't continue */ +PNG_EXPORTA(104, void, png_err, + (png_const_structrp png_ptr), + PNG_NORETURN); +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +PNG_EXPORT(105, void, png_warning, + (png_const_structrp png_ptr, png_const_charp warning_message)); + +/* Non-fatal error in libpng, chunk name is prepended to message. */ +PNG_EXPORT(106, void, png_chunk_warning, + (png_const_structrp png_ptr, png_const_charp warning_message)); +#else +# define png_warning(s1,s2) ((void)(s1)) +# define png_chunk_warning(s1,s2) ((void)(s1)) +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Benign error in libpng. Can continue, but may have a problem. + * User can choose whether to handle as a fatal error or as a warning. */ +PNG_EXPORT(107, void, png_benign_error, + (png_const_structrp png_ptr, png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Same, chunk name is prepended to message (only during read) */ +PNG_EXPORT(108, void, png_chunk_benign_error, + (png_const_structrp png_ptr, png_const_charp warning_message)); +#endif + +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structrp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif +#endif + +/* The png_set_ functions are for storing values in the png_info_struct. + * Similarly, the png_get_ calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_ functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +PNG_EXPORT(110, png_uint_32, png_get_valid, + (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +PNG_EXPORT(111, size_t, png_get_rowbytes, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* Returns row_pointers, which is an array of pointers to scanlines that was + * returned from png_read_png(). + */ +PNG_EXPORT(112, png_bytepp, png_get_rows, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Set row_pointers, which is an array of pointers to scanlines for use + * by png_write_png(). + */ +PNG_EXPORT(113, void, png_set_rows, + (png_const_structrp png_ptr, png_inforp info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +PNG_EXPORT(114, png_byte, png_get_channels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +PNG_EXPORT(115, png_uint_32, png_get_image_width, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image height in pixels. */ +PNG_EXPORT(116, png_uint_32, png_get_image_height, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image bit_depth. */ +PNG_EXPORT(117, png_byte, png_get_bit_depth, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image color_type. */ +PNG_EXPORT(118, png_byte, png_get_color_type, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image filter_type. */ +PNG_EXPORT(119, png_byte, png_get_filter_type, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image interlace_type. */ +PNG_EXPORT(120, png_byte, png_get_interlace_type, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image compression_type. */ +PNG_EXPORT(121, png_byte, png_get_compression_type, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +#endif /* EASY_ACCESS */ + +#ifdef PNG_READ_SUPPORTED +/* Returns pointer to signature string read from PNG header */ +PNG_EXPORT(130, png_const_bytep, png_get_signature, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(131, png_uint_32, png_get_bKGD, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_color_16p *background)); +#endif + +#ifdef PNG_bKGD_SUPPORTED +PNG_EXPORT(132, void, png_set_bKGD, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_16p background)); +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + double *white_x, double *white_y, + double *red_x, double *red_y, + double *green_x, double *green_y, + double *blue_x, double *blue_y)) +PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + double *red_X, double *red_Y, double *red_Z, + double *green_X, double *green_Y, double *green_Z, + double *blue_X, double *blue_Y, double *blue_Z)) +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_white_x, png_fixed_point *int_white_y, + png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, + png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) +PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, + png_fixed_point *int_green_X, png_fixed_point *int_green_Y, + png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z)) +#endif + +#ifdef PNG_cHRM_SUPPORTED +PNG_FP_EXPORT(135, void, png_set_cHRM, + (png_const_structrp png_ptr, png_inforp info_ptr, + double white_x, double white_y, + double red_x, double red_y, + double green_x, double green_y, + double blue_x, double blue_y)) +PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, + (png_const_structrp png_ptr, png_inforp info_ptr, + double red_X, double red_Y, double red_Z, + double green_X, double green_Y, double green_Z, + double blue_X, double blue_Y, double blue_Z)) +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, + png_fixed_point int_green_x, png_fixed_point int_green_y, + png_fixed_point int_blue_x, png_fixed_point int_blue_y)) +PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, + png_fixed_point int_green_X, png_fixed_point int_green_Y, + png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z)) +#endif + +#ifdef PNG_cICP_SUPPORTED +PNG_EXPORT(250, png_uint_32, png_get_cICP, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_bytep colour_primaries, png_bytep transfer_function, + png_bytep matrix_coefficients, png_bytep video_full_range_flag)); +#endif + +#ifdef PNG_cICP_SUPPORTED +PNG_EXPORT(251, void, png_set_cICP, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_byte colour_primaries, png_byte transfer_function, + png_byte matrix_coefficients, png_byte video_full_range_flag)); +#endif + +#ifdef PNG_cLLI_SUPPORTED +PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + double *maximum_content_light_level, + double *maximum_frame_average_light_level)) +PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + /* The values below are in cd/m2 (nits) and are scaled by 10,000; not + * 100,000 as in the case of png_fixed_point. + */ + png_uint_32p maximum_content_light_level_scaled_by_10000, + png_uint_32p maximum_frame_average_light_level_scaled_by_10000)) +#endif + +#ifdef PNG_cLLI_SUPPORTED +PNG_FP_EXPORT(254, void, png_set_cLLI, + (png_const_structrp png_ptr, png_inforp info_ptr, + double maximum_content_light_level, + double maximum_frame_average_light_level)) +PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed, + (png_const_structrp png_ptr, png_inforp info_ptr, + /* The values below are in cd/m2 (nits) and are scaled by 10,000; not + * 100,000 as in the case of png_fixed_point. + */ + png_uint_32 maximum_content_light_level_scaled_by_10000, + png_uint_32 maximum_frame_average_light_level_scaled_by_10000)) +#endif + +#ifdef PNG_eXIf_SUPPORTED +PNG_EXPORT(246, png_uint_32, png_get_eXIf, + (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *exif)); +PNG_EXPORT(247, void, png_set_eXIf, + (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep exif)); + +PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *num_exif, png_bytep *exif)); +PNG_EXPORT(249, void, png_set_eXIf_1, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 num_exif, png_bytep exif)); +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + double *file_gamma)) +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_file_gamma)) +#endif + +#ifdef PNG_gAMA_SUPPORTED +PNG_FP_EXPORT(139, void, png_set_gAMA, + (png_const_structrp png_ptr, png_inforp info_ptr, + double file_gamma)) +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point int_file_gamma)) +#endif + +#ifdef PNG_hIST_SUPPORTED +PNG_EXPORT(141, png_uint_32, png_get_hIST, + (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_16p *hist)); +PNG_EXPORT(142, void, png_set_hIST, + (png_const_structrp png_ptr, png_inforp info_ptr, png_const_uint_16p hist)); +#endif + +PNG_EXPORT(143, png_uint_32, png_get_IHDR, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, + int *interlace_method, int *compression_method, int *filter_method)); + +PNG_EXPORT(144, void, png_set_IHDR, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 width, png_uint_32 height, + int bit_depth, int color_type, + int interlace_method, int compression_method, int filter_method)); + +#ifdef PNG_mDCV_SUPPORTED +PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + /* The chromaticities of the mastering display. As cHRM, but independent of + * the encoding endpoints in cHRM, or cICP, or iCCP. These values will + * always be in the range 0 to 1.3107. + */ + double *white_x, double *white_y, + double *red_x, double *red_y, + double *green_x, double *green_y, + double *blue_x, double *blue_y, + /* Mastering display luminance in cd/m2 (nits). */ + double *mastering_display_maximum_luminance, + double *mastering_display_minimum_luminance)) + +PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_white_x, png_fixed_point *int_white_y, + png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, + png_fixed_point *int_blue_x, png_fixed_point *int_blue_y, + /* Mastering display luminance in cd/m2 (nits) multiplied (scaled) by + * 10,000. + */ + png_uint_32p mastering_display_maximum_luminance_scaled_by_10000, + png_uint_32p mastering_display_minimum_luminance_scaled_by_10000)) +#endif + +#ifdef PNG_mDCV_SUPPORTED +PNG_FP_EXPORT(258, void, png_set_mDCV, + (png_const_structrp png_ptr, png_inforp info_ptr, + /* The chromaticities of the mastering display. As cHRM, but independent of + * the encoding endpoints in cHRM, or cICP, or iCCP. + */ + double white_x, double white_y, + double red_x, double red_y, + double green_x, double green_y, + double blue_x, double blue_y, + /* Mastering display luminance in cd/m2 (nits). */ + double mastering_display_maximum_luminance, + double mastering_display_minimum_luminance)) + +PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, + (png_const_structrp png_ptr, png_inforp info_ptr, + /* The admissible range of these values is not the full range of a PNG + * fixed point value. Negative values cannot be encoded and the maximum + * value is about 1.3 */ + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, + png_fixed_point int_green_x, png_fixed_point int_green_y, + png_fixed_point int_blue_x, png_fixed_point int_blue_y, + /* These are PNG unsigned 4 byte values: 31-bit unsigned values. The MSB + * must be zero. + */ + png_uint_32 mastering_display_maximum_luminance_scaled_by_10000, + png_uint_32 mastering_display_minimum_luminance_scaled_by_10000)) +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(145, png_uint_32, png_get_oFFs, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); +#endif + +#ifdef PNG_oFFs_SUPPORTED +PNG_EXPORT(146, void, png_set_oFFs, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(147, png_uint_32, png_get_pCAL, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#ifdef PNG_pCAL_SUPPORTED +PNG_EXPORT(148, void, png_set_pCAL, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_const_charp units, png_charpp params)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(149, png_uint_32, png_get_pHYs, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(150, void, png_set_pHYs, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +PNG_EXPORT(151, png_uint_32, png_get_PLTE, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_colorp *palette, int *num_palette)); + +PNG_EXPORT(152, void, png_set_PLTE, + (png_structrp png_ptr, png_inforp info_ptr, + png_const_colorp palette, int num_palette)); + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(153, png_uint_32, png_get_sBIT, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_color_8p *sig_bit)); +#endif + +#ifdef PNG_sBIT_SUPPORTED +PNG_EXPORT(154, void, png_set_sBIT, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_8p sig_bit)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(155, png_uint_32, png_get_sRGB, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + int *file_srgb_intent)); +#endif + +#ifdef PNG_sRGB_SUPPORTED +PNG_EXPORT(156, void, png_set_sRGB, + (png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, + (png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(158, png_uint_32, png_get_iCCP, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen)); +#endif + +#ifdef PNG_iCCP_SUPPORTED +PNG_EXPORT(159, void, png_set_iCCP, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(160, int, png_get_sPLT, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_sPLT_tpp entries)); +#endif + +#ifdef PNG_sPLT_SUPPORTED +PNG_EXPORT(161, void, png_set_sPLT, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_sPLT_tp entries, int nentries)); +#endif + +#ifdef PNG_TEXT_SUPPORTED +/* png_get_text also returns the number of text chunks in *num_text */ +PNG_EXPORT(162, int, png_get_text, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_textp *text_ptr, int *num_text)); +#endif + +/* Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#ifdef PNG_TEXT_SUPPORTED +PNG_EXPORT(163, void, png_set_text, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_textp text_ptr, int num_text)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(164, png_uint_32, png_get_tIME, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_timep *mod_time)); +#endif + +#ifdef PNG_tIME_SUPPORTED +PNG_EXPORT(165, void, png_set_tIME, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_timep mod_time)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(166, png_uint_32, png_get_tRNS, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_bytep *trans_alpha, int *num_trans, + png_color_16p *trans_color)); +#endif + +#ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, + (png_structrp png_ptr, png_inforp info_ptr, + png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); +#endif + +#ifdef PNG_sCAL_SUPPORTED +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, double *width, double *height)) +#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ + defined(PNG_FLOATING_POINT_SUPPORTED) +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height)) +#endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, + (png_const_structrp png_ptr, png_inforp info_ptr, + int unit, double width, double height)) +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, + (png_const_structrp png_ptr, png_inforp info_ptr, + int unit, png_fixed_point width, png_fixed_point height)) +PNG_EXPORT(171, void, png_set_sCAL_s, + (png_const_structrp png_ptr, png_inforp info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight)); +#endif /* sCAL */ + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +/* Provide the default handling for all unknown chunks or, optionally, for + * specific unknown chunks. + * + * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was + * ignored and the default was used, the per-chunk setting only had an effect on + * write. If you wish to have chunk-specific handling on read in code that must + * work on earlier versions you must use a user chunk callback to specify the + * desired handling (keep or discard.) + * + * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The + * parameter is interpreted as follows: + * + * READ: + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Known chunks: do normal libpng processing, do not keep the chunk (but + * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + * Unknown chunks: for a specific chunk use the global default, when used + * as the default discard the chunk data. + * PNG_HANDLE_CHUNK_NEVER: + * Discard the chunk data. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Keep the chunk data if the chunk is not critical else raise a chunk + * error. + * PNG_HANDLE_CHUNK_ALWAYS: + * Keep the chunk data. + * + * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, + * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent + * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks + * it simply resets the behavior to the libpng default. + * + * INTERACTION WITH USER CHUNK CALLBACKS: + * The per-chunk handling is always used when there is a png_user_chunk_ptr + * callback and the callback returns 0; the chunk is then always stored *unless* + * it is critical and the per-chunk setting is other than ALWAYS. Notice that + * the global default is *not* used in this case. (In effect the per-chunk + * value is incremented to at least IF_SAFE.) + * + * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and + * per-chunk defaults will be honored. If you want to preserve the current + * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE + * as the default - if you don't do this libpng 1.6 will issue a warning. + * + * If you want unhandled unknown chunks to be discarded in libpng 1.6 and + * earlier simply return '1' (handled). + * + * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: + * If this is *not* set known chunks will always be handled by libpng and + * will never be stored in the unknown chunk list. Known chunks listed to + * png_set_keep_unknown_chunks will have no effect. If it is set then known + * chunks listed with a keep other than AS_DEFAULT will *never* be processed + * by libpng, in addition critical chunks must either be processed by the + * callback or saved. + * + * The IHDR and IEND chunks must not be listed. Because this turns off the + * default handling for chunks that would otherwise be recognized the + * behavior of libpng transformations may well become incorrect! + * + * WRITE: + * When writing chunks the options only apply to the chunks specified by + * png_set_unknown_chunks (below), libpng will *always* write known chunks + * required by png_set_ calls and will always write the core critical chunks + * (as required for PLTE). + * + * Each chunk in the png_set_unknown_chunks list is looked up in the + * png_set_keep_unknown_chunks list to find the keep setting, this is then + * interpreted as follows: + * + * PNG_HANDLE_CHUNK_AS_DEFAULT: + * Write safe-to-copy chunks and write other chunks if the global + * default is set to _ALWAYS, otherwise don't write this chunk. + * PNG_HANDLE_CHUNK_NEVER: + * Do not write the chunk. + * PNG_HANDLE_CHUNK_IF_SAFE: + * Write the chunk if it is safe-to-copy, otherwise do not write it. + * PNG_HANDLE_CHUNK_ALWAYS: + * Write the chunk. + * + * Note that the default behavior is effectively the opposite of the read case - + * in read unknown chunks are not stored by default, in write they are written + * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different + * - on write the safe-to-copy bit is checked, on read the critical bit is + * checked and on read if the chunk is critical an error will be raised. + * + * num_chunks: + * =========== + * If num_chunks is positive, then the "keep" parameter specifies the manner + * for handling only those chunks appearing in the chunk_list array, + * otherwise the chunk list array is ignored. + * + * If num_chunks is 0 the "keep" parameter specifies the default behavior for + * unknown chunks, as described above. + * + * If num_chunks is negative, then the "keep" parameter specifies the manner + * for handling all unknown chunks plus all chunks recognized by libpng + * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to + * be processed by libpng. + */ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, + (png_structrp png_ptr, + int keep, png_const_bytep chunk_list, int num_chunks)); +#endif /* HANDLE_AS_UNKNOWN */ + +/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; + * the result is therefore true (non-zero) if special handling is required, + * false for the default handling. + */ +PNG_EXPORT(173, int, png_handle_as_unknown, + (png_const_structrp png_ptr, png_const_bytep chunk_name)); +#endif /* SET_UNKNOWN_CHUNKS */ + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +PNG_EXPORT(174, void, png_set_unknown_chunks, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_const_unknown_chunkp unknowns, int num_unknowns)); + /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added + * unknowns to the location currently stored in the png_struct. This is + * invariably the wrong value on write. To fix this call the following API + * for each chunk in the list with the correct location. If you know your + * code won't be compiled on earlier versions you can rely on + * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing + * the correct thing. + */ + +PNG_EXPORT(175, void, png_set_unknown_chunk_location, + (png_const_structrp png_ptr, png_inforp info_ptr, + int chunk, int location)); + +PNG_EXPORT(176, int, png_get_unknown_chunks, + (png_const_structrp png_ptr, png_inforp info_ptr, + png_unknown_chunkpp entries)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + * If you need to turn it off for a chunk that your application has freed, + * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); + */ +PNG_EXPORT(177, void, png_set_invalid, + (png_const_structrp png_ptr, png_inforp info_ptr, int mask)); + +#ifdef PNG_INFO_IMAGE_SUPPORTED +/* The "params" pointer is currently not used and is for future expansion. */ +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +PNG_EXPORT(178, void, png_read_png, + (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#ifdef PNG_WRITE_SUPPORTED +PNG_EXPORT(179, void, png_write_png, + (png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params)); +#endif +#endif + +PNG_EXPORT(180, png_const_charp, png_get_copyright, + (png_const_structrp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, + (png_const_structrp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, + (png_const_structrp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, + (png_const_structrp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, + (png_structrp png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 +#define PNG_HANDLE_CHUNK_LAST 4 + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. + */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +PNG_EXPORT(185, void, png_set_strip_error_numbers, + (png_structrp png_ptr, png_uint_32 strip_mode)); +#endif + +/* Added in libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +PNG_EXPORT(186, void, png_set_user_limits, + (png_structrp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, + (png_const_structrp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.0 */ +PNG_EXPORT(189, void, png_set_chunk_cache_max, + (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, + (png_const_structrp png_ptr)); +/* Added in libpng-1.4.1 */ +PNG_EXPORT(191, void, png_set_chunk_malloc_max, + (png_structrp png_ptr, png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_const_structrp png_ptr)); +#endif + +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, + (png_const_structrp png_ptr, png_const_inforp info_ptr)); + +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_const_structrp png_ptr, png_const_inforp info_ptr)) +#endif + +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, + (png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +# endif /* pHYs */ +#endif /* INCH_CONVERSIONS */ + +/* Added in libpng-1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +PNG_EXPORT(199, png_uint_32, png_get_io_state, + (png_const_structrp png_ptr)); + +/* Removed from libpng 1.6; use png_get_io_chunk_type. */ +PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, + (png_structrp png_ptr), + PNG_DEPRECATED) + +PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, + (png_const_structrp png_ptr)); + +/* The flags returned by png_get_io_state() are the following: */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +#endif /* IO_STATE */ + +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. + */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* A macro to return the offset between pixels in the output row for a pair of + * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that + * follows. Note that ROW_OFFSET is the offset from one row to the next whereas + * COL_OFFSET is from one column to the next, within a row. + */ +#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) +#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) + +/* For the reader row callbacks (both progressive and sequential) it is + * necessary to find the row in the output image given a row in an interlaced + * image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ + (((y_in)<>(((7-(off))-(pass))<<2)) & 0xF) | \ + ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { \ + png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ + * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 \ + - (png_uint_16)(alpha)) + 128); \ + (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \ + } + +# define png_composite_16(composite, fg, alpha, bg) \ + { \ + png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ + * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(65535 \ + - (png_uint_32)(alpha)) + 32768); \ + (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \ + } + +#else /* Standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = \ + (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + 127) / 255)) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = \ + (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ + 32767) / 65535)) +#endif /* READ_COMPOSITE_NODIV */ + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, + (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, + (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, + (png_const_bytep buf)); +#endif + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, + (png_const_structrp png_ptr, png_const_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, + (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, + (png_bytep buf, png_int_32 i)); +#endif + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, + (png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif + +#ifdef PNG_USE_READ_MACROS +/* Inline macros to do direct reads of bytes from the input buffer. + * The png_get_int_32() routine assumes we are using two's complement + * format for negative values, which is almost certainly true. + */ +# define PNG_get_uint_32(buf) \ + (((png_uint_32)(*(buf)) << 24) + \ + ((png_uint_32)(*((buf) + 1)) << 16) + \ + ((png_uint_32)(*((buf) + 2)) << 8) + \ + ((png_uint_32)(*((buf) + 3)))) + + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ +# define PNG_get_uint_16(buf) \ + ((png_uint_16) \ + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) + +# define PNG_get_int_32(buf) \ + ((png_int_32)((*(buf) & 0x80) \ + ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \ + : (png_int_32)png_get_uint_32(buf))) + +/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, + * but defining a macro name prefixed with PNG_PREFIX. + */ +# ifndef PNG_PREFIX +# define png_get_uint_32(buf) PNG_get_uint_32(buf) +# define png_get_uint_16(buf) PNG_get_uint_16(buf) +# define png_get_int_32(buf) PNG_get_int_32(buf) +# endif +#else +# ifdef PNG_PREFIX + /* No macros; revert to the (redefined) function */ +# define PNG_get_uint_32 (png_get_uint_32) +# define PNG_get_uint_16 (png_get_uint_16) +# define PNG_get_int_32 (png_get_int_32) +# endif +#endif + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +PNG_EXPORT(242, void, png_set_check_for_invalid_index, + (png_structrp png_ptr, int allowed)); +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +PNG_EXPORT(243, int, png_get_palette_max, + (png_const_structp png_ptr, png_const_infop info_ptr)); +# endif +#endif /* CHECK_FOR_INVALID_INDEX */ + +/******************************************************************************* + * Section 5: SIMPLIFIED API + ******************************************************************************* + * + * Please read the documentation in libpng-manual.txt (TODO: write said + * documentation) if you don't understand what follows. + * + * The simplified API hides the details of both libpng and the PNG file format + * itself. It allows PNG files to be read into a very limited number of + * in-memory bitmap formats or to be written from the same formats. If these + * formats do not accommodate your needs then you can, and should, use the more + * sophisticated APIs above - these support a wide variety of in-memory formats + * and a wide variety of sophisticated transformations to those formats as well + * as a wide variety of APIs to manipulate ancillary information. + * + * To read a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure (see below) on the stack, set the + * version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL + * (this is REQUIRED, your program may crash if you don't do it.) + * 2) Call the appropriate png_image_begin_read... function. + * 3) Set the png_image 'format' member to the required sample format. + * 4) Allocate a buffer for the image and, if required, the color-map. + * 5) Call png_image_finish_read to read the image and, if required, the + * color-map into your buffers. + * + * There are no restrictions on the format of the PNG input itself; all valid + * color types, bit depths, and interlace methods are acceptable, and the + * input image is transformed as necessary to the requested in-memory format + * during the png_image_finish_read() step. The only caveat is that if you + * request a color-mapped image from a PNG that is full-color or makes + * complex use of an alpha channel the transformation is extremely lossy and the + * result may look terrible. + * + * To write a PNG file using the simplified API: + * + * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. + * 2) Initialize the members of the structure that describe the image, setting + * the 'format' member to the format of the image samples. + * 3) Call the appropriate png_image_write... function with a pointer to the + * image and, if necessary, the color-map to write the PNG data. + * + * png_image is a structure that describes the in-memory format of an image + * when it is being read or defines the in-memory format of an image that you + * need to write: + */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) + +#define PNG_IMAGE_VERSION 1 + +typedef struct png_control *png_controlp; +typedef struct +{ + png_controlp opaque; /* Initialize to NULL, free with png_image_free */ + png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ + png_uint_32 width; /* Image width in pixels (columns) */ + png_uint_32 height; /* Image height in pixels (rows) */ + png_uint_32 format; /* Image format as defined below */ + png_uint_32 flags; /* A bit mask containing informational flags */ + png_uint_32 colormap_entries; + /* Number of entries in the color-map */ + + /* In the event of an error or warning the following field will be set to a + * non-zero value and the 'message' field will contain a '\0' terminated + * string with the libpng error or warning message. If both warnings and + * an error were encountered, only the error is recorded. If there + * are multiple warnings, only the first one is recorded. + * + * The upper 30 bits of this value are reserved, the low two bits contain + * a value as follows: + */ +# define PNG_IMAGE_WARNING 1 +# define PNG_IMAGE_ERROR 2 + /* + * The result is a two-bit code such that a value more than 1 indicates + * a failure in the API just called: + * + * 0 - no warning or error + * 1 - warning + * 2 - error + * 3 - error preceded by warning + */ +# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) + + png_uint_32 warning_or_error; + + char message[64]; +} png_image, *png_imagep; + +/* The samples of the image have one to four channels whose components have + * original values in the range 0 to 1.0: + * + * 1: A single gray or luminance channel (G). + * 2: A gray/luminance channel and an alpha channel (GA). + * 3: Three red, green, blue color channels (RGB). + * 4: Three color channels and an alpha channel (RGBA). + * + * The components are encoded in one of two ways: + * + * a) As a small integer, value 0..255, contained in a single byte. For the + * alpha channel the original value is simply value/255. For the color or + * luminance channels the value is encoded according to the sRGB specification + * and matches the 8-bit format expected by typical display devices. + * + * The color/gray channels are not scaled (pre-multiplied) by the alpha + * channel and are suitable for passing to color management software. + * + * b) As a value in the range 0..65535, contained in a 2-byte integer. All + * channels can be converted to the original value by dividing by 65535; all + * channels are linear. Color channels use the RGB encoding (RGB end-points) of + * the sRGB specification. This encoding is identified by the + * PNG_FORMAT_FLAG_LINEAR flag below. + * + * When the simplified API needs to convert between sRGB and linear colorspaces, + * the actual sRGB transfer curve defined in the sRGB specification (see the + * article at ) is used, not the gamma=1/2.2 + * approximation used elsewhere in libpng. + * + * When an alpha channel is present it is expected to denote pixel coverage + * of the color or luminance channels and is returned as an associated alpha + * channel: the color/gray channels are scaled (pre-multiplied) by the alpha + * value. + * + * The samples are either contained directly in the image data, between 1 and 8 + * bytes per pixel according to the encoding, or are held in a color-map indexed + * by bytes in the image data. In the case of a color-map the color-map entries + * are individual samples, encoded as above, and the image data has one byte per + * pixel to select the relevant sample from the color-map. + */ + +/* PNG_FORMAT_* + * + * #defines to be used in png_image::format. Each #define identifies a + * particular layout of sample data and, if present, alpha values. There are + * separate defines for each of the two component encodings. + * + * A format is built up using single bit flag values. All combinations are + * valid. Formats can be built up from the flag values or you can use one of + * the predefined values below. When testing formats always use the FORMAT_FLAG + * macros to test for individual features - future versions of the library may + * add new flags. + * + * When reading or writing color-mapped images the format should be set to the + * format of the entries in the color-map then png_image_{read,write}_colormap + * called to read or write the color-map and set the format correctly for the + * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! + * + * NOTE: libpng can be built with particular features disabled. If you see + * compiler errors because the definition of one of the following flags has been + * compiled out it is because libpng does not have the required support. It is + * possible, however, for the libpng configuration to enable the format on just + * read or just write; in that case you may see an error at run time. You can + * guard against this by checking for the definition of the appropriate + * "_SUPPORTED" macro, one of: + * + * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED + */ +#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ +#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ +#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2-byte channels else 1-byte */ +#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ + +#ifdef PNG_FORMAT_BGR_SUPPORTED +# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ +#endif + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED +# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ +#endif + +#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */ + +/* Commonly used formats have predefined macros. + * + * First the single byte (sRGB) formats: + */ +#define PNG_FORMAT_GRAY 0 +#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA +#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR +#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) +#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) +#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) + +/* Then the linear 2-byte formats. When naming these "Y" is used to + * indicate a luminance (gray) channel. + */ +#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR +#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) +#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) +#define PNG_FORMAT_LINEAR_RGB_ALPHA \ + (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) + +/* With color-mapped formats the image data is one byte for each pixel, the byte + * is an index into the color-map which is formatted as above. To obtain a + * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP + * to one of the above definitions, or you can use one of the definitions below. + */ +#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) +#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) + +/* PNG_IMAGE macros + * + * These are convenience macros to derive information from a png_image + * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the + * actual image sample values - either the entries in the color-map or the + * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values + * for the pixels and will always return 1 for color-mapped formats. The + * remaining macros return information about the rows in the image and the + * complete image. + * + * NOTE: All the macros that take a png_image::format parameter are compile time + * constants if the format parameter is, itself, a constant. Therefore these + * macros can be used in array declarations and case labels where required. + * Similarly the macros are also pre-processor constants (sizeof is not used) so + * they can be used in #if tests. + * + * First the information about the samples. + */ +#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ + (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) + /* Return the total number of channels in a given format: 1..4 */ + +#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ + ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) + /* Return the size in bytes of a single component of a pixel or color-map + * entry (as appropriate) in the image: 1 or 2. + */ + +#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) + /* This is the size of the sample data for one sample. If the image is + * color-mapped it is the size of one color-map entry (and image pixels are + * one byte in size), otherwise it is the size of one image pixel. + */ + +#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ + (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) + /* The maximum size of the color-map required by the format expressed in a + * count of components. This can be used to compile-time allocate a + * color-map: + * + * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; + * + * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; + * + * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the + * information from one of the png_image_begin_read_ APIs and dynamically + * allocate the required memory. + */ + +/* Corresponding information about the pixels */ +#define PNG_IMAGE_PIXEL_(test,fmt)\ + (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) + +#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) + /* The number of separate channels (components) in a pixel; 1 for a + * color-mapped image. + */ + +#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ + PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) + /* The size, in bytes, of each component in a pixel; 1 for a color-mapped + * image. + */ + +#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) + /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ + +/* Information about the whole row, or whole image */ +#define PNG_IMAGE_ROW_STRIDE(image)\ + (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) + /* Return the total number of components in a single row of the image; this + * is the minimum 'row stride', the minimum count of components between each + * row. For a color-mapped image this is the minimum number of bytes in a + * row. + * + * WARNING: this macro overflows for some images with more than one component + * and very large image widths. libpng will refuse to process an image where + * this macro would overflow. + */ + +#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ + (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) + /* Return the size, in bytes, of an image buffer given a png_image and a row + * stride - the number of components to leave space for in each row. + * + * WARNING: this macro overflows a 32-bit integer for some large PNG images, + * libpng will refuse to process an image where such an overflow would occur. + */ + +#define PNG_IMAGE_SIZE(image)\ + PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) + /* Return the size, in bytes, of the image in memory given just a png_image; + * the row stride is the minimum stride required for the image. + */ + +#define PNG_IMAGE_COLORMAP_SIZE(image)\ + (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) + /* Return the size, in bytes, of the color-map of this image. If the image + * format is not a color-map format this will return a size sufficient for + * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if + * you don't want to allocate a color-map in this case. + */ + +/* PNG_IMAGE_FLAG_* + * + * Flags containing additional information about the image are held in the + * 'flags' field of png_image. + */ +#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 + /* This indicates that the RGB values of the in-memory bitmap do not + * correspond to the red, green and blue end-points defined by sRGB. + */ + +#define PNG_IMAGE_FLAG_FAST 0x02 + /* On write emphasise speed over compression; the resultant PNG file will be + * larger but will be produced significantly faster, particular for large + * images. Do not use this option for images which will be distributed, only + * used it when producing intermediate files that will be read back in + * repeatedly. For a typical 24-bit image the option will double the read + * speed at the cost of increasing the image size by 25%, however for many + * more compressible images the PNG file can be 10 times larger with only a + * slight speed gain. + */ + +#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 + /* On read if the image is a 16-bit per component image and there is no gAMA + * or sRGB chunk assume that the components are sRGB encoded. Notice that + * images output by the simplified API always have gamma information; setting + * this flag only affects the interpretation of 16-bit images from an + * external source. It is recommended that the application expose this flag + * to the user; the user can normally easily recognize the difference between + * linear and sRGB encoding. This flag has no effect on write - the data + * passed to the write APIs must have the correct encoding (as defined + * above.) + * + * If the flag is not set (the default) input 16-bit per component data is + * assumed to be linear. + * + * NOTE: the flag can only be set after the png_image_begin_read_ call, + * because that call initializes the 'flags' field. + */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* READ APIs + * --------- + * + * The png_image passed to the read APIs must have been initialized by setting + * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) + */ +#ifdef PNG_STDIO_SUPPORTED +PNG_EXPORT(234, int, png_image_begin_read_from_file, + (png_imagep image, const char *file_name)); + /* The named file is opened for read and the image header is filled in + * from the PNG header in the file. + */ + +PNG_EXPORT(235, int, png_image_begin_read_from_stdio, + (png_imagep image, FILE *file)); + /* The PNG header is read from the stdio FILE object. */ +#endif /* STDIO */ + +PNG_EXPORT(236, int, png_image_begin_read_from_memory, + (png_imagep image, png_const_voidp memory, size_t size)); + /* The PNG header is read from the given memory buffer. */ + +PNG_EXPORT(237, int, png_image_finish_read, + (png_imagep image, + png_const_colorp background, void *buffer, png_int_32 row_stride, + void *colormap)); + /* Finish reading the image into the supplied buffer and clean up the + * png_image structure. + * + * row_stride is the step, in byte or 2-byte units as appropriate, + * between adjacent rows. A positive stride indicates that the top-most row + * is first in the buffer - the normal top-down arrangement. A negative + * stride indicates that the bottom-most row is first in the buffer. + * + * background need only be supplied if an alpha channel must be removed from + * a png_byte format and the removal is to be done by compositing on a solid + * color; otherwise it may be NULL and any composition will be done directly + * onto the buffer. The value is an sRGB color to use for the background, + * for grayscale output the green channel is used. + * + * background must be supplied when an alpha channel must be removed from a + * single byte color-mapped output format, in other words if: + * + * 1) The original format from png_image_begin_read_from_* had + * PNG_FORMAT_FLAG_ALPHA set. + * 2) The format set by the application does not. + * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and + * PNG_FORMAT_FLAG_LINEAR *not* set. + * + * For linear output removing the alpha channel is always done by compositing + * on black and background is ignored. + * + * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must + * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. + * image->colormap_entries will be updated to the actual number of entries + * written to the colormap; this may be less than the original value. + */ + +PNG_EXPORT(238, void, png_image_free, + (png_imagep image)); + /* Free any data allocated by libpng in image->opaque, setting the pointer to + * NULL. May be called at any time after the structure is initialized. + */ +#endif /* SIMPLIFIED_READ */ + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +/* WRITE APIS + * ---------- + * For write you must initialize a png_image structure to describe the image to + * be written. To do this use memset to set the whole structure to 0 then + * initialize fields describing your image. + * + * version: must be set to PNG_IMAGE_VERSION + * opaque: must be initialized to NULL + * width: image width in pixels + * height: image height in rows + * format: the format of the data (image and color-map) you wish to write + * flags: set to 0 unless one of the defined flags applies; set + * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB + * values do not correspond to the colors in sRGB. + * colormap_entries: set to the number of entries in the color-map (0 to 256) + */ +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED +PNG_EXPORT(239, int, png_image_write_to_file, + (png_imagep image, + const char *file, int convert_to_8bit, const void *buffer, + png_int_32 row_stride, const void *colormap)); + /* Write the image to the named file. */ + +PNG_EXPORT(240, int, png_image_write_to_stdio, + (png_imagep image, + FILE *file, int convert_to_8_bit, const void *buffer, + png_int_32 row_stride, const void *colormap)); + /* Write the image to the given FILE object. */ +#endif /* SIMPLIFIED_WRITE_STDIO */ + +/* With all write APIs if image is in one of the linear formats with 16-bit + * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG + * gamma encoded according to the sRGB specification, otherwise a 16-bit linear + * encoded PNG file is written. + * + * With color-mapped data formats the colormap parameter point to a color-map + * with at least image->colormap_entries encoded in the specified format. If + * the format is linear the written PNG color-map will be converted to sRGB + * regardless of the convert_to_8_bit flag. + * + * With all APIs row_stride is handled as in the read APIs - it is the spacing + * from one row to the next in component sized units (1 or 2 bytes) and if + * negative indicates a bottom-up row layout in the buffer. If row_stride is + * zero, libpng will calculate it for you from the image width and number of + * channels. + * + * Note that the write API does not support interlacing, sub-8-bit pixels or + * most ancillary chunks. If you need to write text chunks (e.g. for copyright + * notices) you need to use one of the other APIs. + */ + +PNG_EXPORT(245, int, png_image_write_to_memory, + (png_imagep image, + void *memory, png_alloc_size_t * PNG_RESTRICT memory_bytes, + int convert_to_8_bit, + const void *buffer, png_int_32 row_stride, const void *colormap)); + /* Write the image to the given memory buffer. The function both writes the + * whole PNG data stream to *memory and updates *memory_bytes with the count + * of bytes written. + * + * 'memory' may be NULL. In this case *memory_bytes is not read however on + * success the number of bytes which would have been written will still be + * stored in *memory_bytes. On failure *memory_bytes will contain 0. + * + * If 'memory' is not NULL it must point to memory[*memory_bytes] of + * writeable memory. + * + * If the function returns success memory[*memory_bytes] (if 'memory' is not + * NULL) contains the written PNG data. *memory_bytes will always be less + * than or equal to the original value. + * + * If the function returns false and *memory_bytes was not changed an error + * occurred during write. If *memory_bytes was changed, or is not 0 if + * 'memory' was NULL, the write would have succeeded but for the memory + * buffer being too small. *memory_bytes contains the required number of + * bytes and will be bigger that the original value. + */ + +#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\ + row_stride, colormap)\ + png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\ + row_stride, colormap) + /* Return the amount of memory in 'size' required to compress this image. + * The png_image structure 'image' must be filled in as in the above + * function and must not be changed before the actual write call, the buffer + * and all other parameters must also be identical to that in the final + * write call. The 'size' variable need not be initialized. + * + * NOTE: the macro returns true/false, if false is returned 'size' will be + * set to zero and the write failed and probably will fail if tried again. + */ + +/* You can pre-allocate the buffer by making sure it is of sufficient size + * regardless of the amount of compression achieved. The buffer size will + * always be bigger than the original image and it will never be filled. The + * following macros are provided to assist in allocating the buffer. + */ +#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height) + /* The number of uncompressed bytes in the PNG byte encoding of the image; + * uncompressing the PNG IDAT data will give this number of bytes. + * + * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this + * macro can because of the extra bytes used in the PNG byte encoding. You + * need to avoid this macro if your image size approaches 2^30 in width or + * height. The same goes for the remainder of these macros; they all produce + * bigger numbers than the actual in-memory image size. + */ +#ifndef PNG_ZLIB_MAX_SIZE +# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U) + /* An upper bound on the number of compressed bytes given 'b' uncompressed + * bytes. This is based on deflateBounds() in zlib; different + * implementations of zlib compression may conceivably produce more data so + * if your zlib implementation is not zlib itself redefine this macro + * appropriately. + */ +#endif + +#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\ + PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image)) + /* An upper bound on the size of the data in the PNG IDAT chunks. */ + +#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\ + ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\ + (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\ + 12U+3U*(image).colormap_entries/*PLTE data*/+\ + (((image).format&PNG_FORMAT_FLAG_ALPHA)?\ + 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\ + 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size)) + /* A helper for the following macro; if your compiler cannot handle the + * following macro use this one with the result of + * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most + * compilers should handle this just fine.) + */ + +#define PNG_IMAGE_PNG_SIZE_MAX(image)\ + PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image)) + /* An upper bound on the total length of the PNG data stream for 'image'. + * The result is of type png_alloc_size_t, on 32-bit systems this may + * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will + * run out of buffer space but return a corrected size which should work. + */ +#endif /* SIMPLIFIED_WRITE */ +/******************************************************************************* + * END OF SIMPLIFIED API + ******************************************************************************/ +#endif /* SIMPLIFIED_{READ|WRITE} */ + +/******************************************************************************* + * Section 6: IMPLEMENTATION OPTIONS + ******************************************************************************* + * + * Support for arbitrary implementation-specific optimizations. The API allows + * particular options to be turned on or off. 'Option' is the number of the + * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given + * by the PNG_OPTION_ defines below. + * + * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions, + * are detected at run time, however sometimes it may be impossible + * to do this in user mode, in which case it is necessary to discover + * the capabilities in an OS specific way. Such capabilities are + * listed here when libpng has support for them and must be turned + * ON by the application if present. + * + * SOFTWARE: sometimes software optimizations actually result in performance + * decrease on some architectures or systems, or with some sets of + * PNG images. 'Software' options allow such optimizations to be + * selected at run time. + */ +#ifdef PNG_SET_OPTION_SUPPORTED + +/* HARDWARE: ARM Neon SIMD instructions supported */ +#ifdef PNG_ARM_NEON_API_SUPPORTED +# define PNG_ARM_NEON 0 +#endif + +/* SOFTWARE: Force maximum window */ +#define PNG_MAXIMUM_INFLATE_WINDOW 2 + +/* SOFTWARE: Check ICC profile for sRGB */ +#define PNG_SKIP_sRGB_CHECK_PROFILE 4 + +/* HARDWARE: MIPS MSA SIMD instructions supported */ +#ifdef PNG_MIPS_MSA_API_SUPPORTED +# define PNG_MIPS_MSA 6 +#endif + +/* SOFTWARE: Disable Adler32 check on IDAT */ +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED +# define PNG_IGNORE_ADLER32 8 +#endif + +/* HARDWARE: PowerPC VSX SIMD instructions supported */ +#ifdef PNG_POWERPC_VSX_API_SUPPORTED +# define PNG_POWERPC_VSX 10 +#endif + +/* HARDWARE: MIPS MMI SIMD instructions supported */ +#ifdef PNG_MIPS_MMI_API_SUPPORTED +# define PNG_MIPS_MMI 12 +#endif + +/* HARDWARE: RISC-V RVV SIMD instructions supported */ +#ifdef PNG_RISCV_RVV_API_SUPPORTED +# define PNG_RISCV_RVV 14 +#endif + +/* Next option - numbers must be even */ +#define PNG_OPTION_NEXT 16 + +/* Return values: NOTE: there are four values and 'off' is *not* zero */ +#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ +#define PNG_OPTION_INVALID 1 /* Option number out of range */ +#define PNG_OPTION_OFF 2 +#define PNG_OPTION_ON 3 + +PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, + int onoff)); +#endif /* SET_OPTION */ + +/******************************************************************************* + * END OF HARDWARE AND SOFTWARE OPTIONS + ******************************************************************************/ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, in project + * defs, and in scripts/symbols.def. + */ + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(259); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* Do not put anything past this line */ +#endif /* PNG_H */ diff --git a/thirdparty/libpng/upstream/pngconf.h b/thirdparty/libpng/upstream/pngconf.h index 5819c7d3a..6b607ab1f 100644 --- a/thirdparty/libpng/upstream/pngconf.h +++ b/thirdparty/libpng/upstream/pngconf.h @@ -1,623 +1,615 @@ - -/* pngconf.h - machine-configurable file for libpng - * - * libpng version 1.6.44 - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * Any machine specific code is near the front of this file, so if you - * are configuring libpng for a machine, you may want to read the section - * starting here down to where it starts to typedef png_color, png_text, - * and png_info. - */ - -#ifndef PNGCONF_H -#define PNGCONF_H - -#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ - -/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C - * compiler for correct compilation. The following header files are required by - * the standard. If your compiler doesn't provide these header files, or they - * do not match the standard, you will need to provide/improve them. - */ -#include -#include - -/* Library header files. These header files are all defined by ISOC90; libpng - * expects conformant implementations, however, an ISOC90 conformant system need - * not provide these header files if the functionality cannot be implemented. - * In this case it will be necessary to disable the relevant parts of libpng in - * the build of pnglibconf.h. - * - * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not - * include this unnecessary header file. - */ - -#ifdef PNG_STDIO_SUPPORTED - /* Required for the definition of FILE: */ -# include -#endif - -#ifdef PNG_SETJMP_SUPPORTED - /* Required for the definition of jmp_buf and the declaration of longjmp: */ -# include -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED - /* Required for struct tm: */ -# include -#endif - -#endif /* PNG_BUILDING_SYMBOL_TABLE */ - -/* Prior to 1.6.0, it was possible to turn off 'const' in declarations, - * using PNG_NO_CONST. This is no longer supported. - */ -#define PNG_CONST const /* backward compatibility only */ - -/* This controls optimization of the reading of 16-bit and 32-bit - * values from PNG files. It can be set on a per-app-file basis: it - * just changes whether a macro is used when the function is called. - * The library builder sets the default; if read functions are not - * built into the library the macro implementation is forced on. - */ -#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED -# define PNG_USE_READ_MACROS -#endif -#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) -# if PNG_DEFAULT_READ_MACROS -# define PNG_USE_READ_MACROS -# endif -#endif - -/* COMPILER SPECIFIC OPTIONS. - * - * These options are provided so that a variety of difficult compilers - * can be used. Some are fixed at build time (e.g. PNG_API_RULE - * below) but still have compiler specific implementations, others - * may be changed on a per-file basis when compiling against libpng. - */ - -/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect - * against legacy (pre ISOC90) compilers that did not understand function - * prototypes. [Deprecated.] - */ -#ifndef PNGARG -# define PNGARG(arglist) arglist -#endif - -/* Function calling conventions. - * ============================= - * Normally it is not necessary to specify to the compiler how to call - * a function - it just does it - however on x86 systems derived from - * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems - * and some others) there are multiple ways to call a function and the - * default can be changed on the compiler command line. For this reason - * libpng specifies the calling convention of every exported function and - * every function called via a user supplied function pointer. This is - * done in this file by defining the following macros: - * - * PNGAPI Calling convention for exported functions. - * PNGCBAPI Calling convention for user provided (callback) functions. - * PNGCAPI Calling convention used by the ANSI-C library (required - * for longjmp callbacks and sometimes used internally to - * specify the calling convention for zlib). - * - * These macros should never be overridden. If it is necessary to - * change calling convention in a private build this can be done - * by setting PNG_API_RULE (which defaults to 0) to one of the values - * below to select the correct 'API' variants. - * - * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. - * This is correct in every known environment. - * PNG_API_RULE=1 Use the operating system convention for PNGAPI and - * the 'C' calling convention (from PNGCAPI) for - * callbacks (PNGCBAPI). This is no longer required - * in any known environment - if it has to be used - * please post an explanation of the problem to the - * libpng mailing list. - * - * These cases only differ if the operating system does not use the C - * calling convention, at present this just means the above cases - * (x86 DOS/Windows systems) and, even then, this does not apply to - * Cygwin running on those systems. - * - * Note that the value must be defined in pnglibconf.h so that what - * the application uses to call the library matches the conventions - * set when building the library. - */ - -/* Symbol export - * ============= - * When building a shared library it is almost always necessary to tell - * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' - * is used to mark the symbols. On some systems these symbols can be - * extracted at link time and need no special processing by the compiler, - * on other systems the symbols are flagged by the compiler and just - * the declaration requires a special tag applied (unfortunately) in a - * compiler dependent way. Some systems can do either. - * - * A small number of older systems also require a symbol from a DLL to - * be flagged to the program that calls it. This is a problem because - * we do not know in the header file included by application code that - * the symbol will come from a shared library, as opposed to a statically - * linked one. For this reason the application must tell us by setting - * the magic flag PNG_USE_DLL to turn on the special processing before - * it includes png.h. - * - * Four additional macros are used to make this happen: - * - * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from - * the build or imported if PNG_USE_DLL is set - compiler - * and system specific. - * - * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to - * 'type', compiler specific. - * - * PNG_DLL_EXPORT Set to the magic to use during a libpng build to - * make a symbol exported from the DLL. Not used in the - * public header files; see pngpriv.h for how it is used - * in the libpng build. - * - * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come - * from a DLL - used to define PNG_IMPEXP when - * PNG_USE_DLL is set. - */ - -/* System specific discovery. - * ========================== - * This code is used at build time to find PNG_IMPEXP, the API settings - * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL - * import processing is possible. On Windows systems it also sets - * compiler-specific macros to the values required to change the calling - * conventions of the various functions. - */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \ - defined(__CYGWIN__) - /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or - * MinGW on any architecture currently supported by Windows. Also includes - * Watcom builds but these need special treatment because they are not - * compatible with GCC or Visual C because of different calling conventions. - */ -# if PNG_API_RULE == 2 - /* If this line results in an error, either because __watcall is not - * understood or because of a redefine just below you cannot use *this* - * build of the library with the compiler you are using. *This* build was - * build using Watcom and applications must also be built using Watcom! - */ -# define PNGCAPI __watcall -# endif - -# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) -# define PNGCAPI __cdecl -# if PNG_API_RULE == 1 - /* If this line results in an error __stdcall is not understood and - * PNG_API_RULE should not have been set to '1'. - */ -# define PNGAPI __stdcall -# endif -# else - /* An older compiler, or one not detected (erroneously) above, - * if necessary override on the command line to get the correct - * variants for the compiler. - */ -# ifndef PNGCAPI -# define PNGCAPI _cdecl -# endif -# if PNG_API_RULE == 1 && !defined(PNGAPI) -# define PNGAPI _stdcall -# endif -# endif /* compiler/api */ - - /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ - -# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) -# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" -# endif - -# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ - (defined(__BORLANDC__) && __BORLANDC__ < 0x500) - /* older Borland and MSC - * compilers used '__export' and required this to be after - * the type. - */ -# ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP -# endif -# define PNG_DLL_EXPORT __export -# else /* newer compiler */ -# define PNG_DLL_EXPORT __declspec(dllexport) -# ifndef PNG_DLL_IMPORT -# define PNG_DLL_IMPORT __declspec(dllimport) -# endif -# endif /* compiler */ - -#else /* !Windows */ -# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) -# define PNGAPI _System -# else /* !Windows/x86 && !OS/2 */ - /* Use the defaults, or define PNG*API on the command line (but - * this will have to be done for every compile!) - */ -# endif /* other system, !OS/2 */ -#endif /* !Windows/x86 */ - -/* Now do all the defaulting . */ -#ifndef PNGCAPI -# define PNGCAPI -#endif -#ifndef PNGCBAPI -# define PNGCBAPI PNGCAPI -#endif -#ifndef PNGAPI -# define PNGAPI PNGCAPI -#endif - -/* PNG_IMPEXP may be set on the compilation system command line or (if not set) - * then in an internal header file when building the library, otherwise (when - * using the library) it is set here. - */ -#ifndef PNG_IMPEXP -# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) - /* This forces use of a DLL, disallowing static linking */ -# define PNG_IMPEXP PNG_DLL_IMPORT -# endif - -# ifndef PNG_IMPEXP -# define PNG_IMPEXP -# endif -#endif - -/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat - * 'attributes' as a storage class - the attributes go at the start of the - * function definition, and attributes are always appended regardless of the - * compiler. This considerably simplifies these macros but may cause problems - * if any compilers both need function attributes and fail to handle them as - * a storage class (this is unlikely.) - */ -#ifndef PNG_FUNCTION -# define PNG_FUNCTION(type, name, args, attributes) attributes type name args -#endif - -#ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type -#endif - - /* The ordinal value is only relevant when preprocessing png.h for symbol - * table entries, so we discard it here. See the .dfn files in the - * scripts directory. - */ - -#ifndef PNG_EXPORTA -# define PNG_EXPORTA(ordinal, type, name, args, attributes) \ - PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), args, \ - PNG_LINKAGE_API attributes) -#endif - -/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, - * so make something non-empty to satisfy the requirement: - */ -#define PNG_EMPTY /*empty list*/ - -#define PNG_EXPORT(ordinal, type, name, args) \ - PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) - -/* Use PNG_REMOVED to comment out a removed interface. */ -#ifndef PNG_REMOVED -# define PNG_REMOVED(ordinal, type, name, args, attributes) -#endif - -#ifndef PNG_CALLBACK -# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) args -#endif - -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. - * - * Added at libpng-1.2.41. - */ - -#ifndef PNG_NO_PEDANTIC_WARNINGS -# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED -# define PNG_PEDANTIC_WARNINGS_SUPPORTED -# endif -#endif - -#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED - /* Support for compiler specific function attributes. These are used - * so that where compiler support is available, incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng - * version 1.2.41. Disabling these removes the warnings but may also produce - * less efficient code. - */ -# if defined(__clang__) && defined(__has_attribute) - /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ -# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# if !defined(PNG_PRIVATE) -# ifdef __has_extension -# if __has_extension(attribute_unavailable_with_message) -# define PNG_PRIVATE __attribute__((__unavailable__(\ - "This function is not exported by libpng."))) -# endif -# endif -# endif -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif - -# elif defined(__GNUC__) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if __GNUC__ >= 3 -# ifndef PNG_ALLOCATED -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# ifndef PNG_PRIVATE -# if 0 /* Doesn't work so we use deprecated instead*/ -# define PNG_PRIVATE \ - __attribute__((warning("This function is not exported by libpng."))) -# else -# define PNG_PRIVATE \ - __attribute__((__deprecated__)) -# endif -# endif -# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ -# endif /* __GNUC__ >= 3 */ - -# elif defined(_MSC_VER) && (_MSC_VER >= 1300) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* not supported */ -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __declspec(noreturn) -# endif -# ifndef PNG_ALLOCATED -# if (_MSC_VER >= 1400) -# define PNG_ALLOCATED __declspec(restrict) -# endif -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __declspec(deprecated) -# endif -# ifndef PNG_PRIVATE -# define PNG_PRIVATE __declspec(deprecated) -# endif -# ifndef PNG_RESTRICT -# if (_MSC_VER >= 1400) -# define PNG_RESTRICT __restrict -# endif -# endif - -# elif defined(__WATCOMC__) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif -#endif /* PNG_PEDANTIC_WARNINGS */ - -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ -#endif -#ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ -#endif -#ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ -#endif -#ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE /* This is a private libpng function */ -#endif -#ifndef PNG_RESTRICT -# define PNG_RESTRICT /* The C99 "restrict" feature */ -#endif - -#ifndef PNG_FP_EXPORT /* A floating point API. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No floating point APIs */ -# define PNG_FP_EXPORT(ordinal, type, name, args) -# endif -#endif -#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ -# ifdef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No fixed point APIs */ -# define PNG_FIXED_EXPORT(ordinal, type, name, args) -# endif -#endif - -#ifndef PNG_BUILDING_SYMBOL_TABLE -/* Some typedefs to get us started. These should be safe on most of the common - * platforms. - * - * png_uint_32 and png_int_32 may, currently, be larger than required to hold a - * 32-bit value however this is not normally advisable. - * - * png_uint_16 and png_int_16 should always be two bytes in size - this is - * verified at library build time. - * - * png_byte must always be one byte in size. - * - * The checks below use constants from limits.h, as defined by the ISOC90 - * standard. - */ -#if CHAR_BIT == 8 && UCHAR_MAX == 255 - typedef unsigned char png_byte; -#else -# error "libpng requires 8-bit bytes" -#endif - -#if INT_MIN == -32768 && INT_MAX == 32767 - typedef int png_int_16; -#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 - typedef short png_int_16; -#else -# error "libpng requires a signed 16-bit type" -#endif - -#if UINT_MAX == 65535 - typedef unsigned int png_uint_16; -#elif USHRT_MAX == 65535 - typedef unsigned short png_uint_16; -#else -# error "libpng requires an unsigned 16-bit type" -#endif - -#if INT_MIN < -2147483646 && INT_MAX > 2147483646 - typedef int png_int_32; -#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 - typedef long int png_int_32; -#else -# error "libpng requires a signed 32-bit (or more) type" -#endif - -#if UINT_MAX > 4294967294U - typedef unsigned int png_uint_32; -#elif ULONG_MAX > 4294967294U - typedef unsigned long int png_uint_32; -#else -# error "libpng requires an unsigned 32-bit (or more) type" -#endif - -/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t. - * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant - * behavior of sizeof and ptrdiff_t are required. - * The legacy typedefs are provided here for backwards compatibility. - */ -typedef size_t png_size_t; -typedef ptrdiff_t png_ptrdiff_t; - -/* libpng needs to know the maximum value of 'size_t' and this controls the - * definition of png_alloc_size_t, below. This maximum value of size_t limits - * but does not control the maximum allocations the library makes - there is - * direct application control of this through png_set_user_limits(). - */ -#ifndef PNG_SMALL_SIZE_T - /* Compiler specific tests for systems where size_t is known to be less than - * 32 bits (some of these systems may no longer work because of the lack of - * 'far' support; see above.) - */ -# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ - (defined(_MSC_VER) && defined(MAXSEG_64K)) -# define PNG_SMALL_SIZE_T -# endif -#endif - -/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller - * than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are - * not necessary; in fact, it is recommended not to use them at all, so that - * the compiler can complain when something turns out to be problematic. - * - * Casts in the other direction (from png_alloc_size_t to size_t or - * png_uint_32) should be explicitly applied; however, we do not expect to - * encounter practical situations that require such conversions. - * - * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than - * 4294967295 - i.e. less than the maximum value of png_uint_32. - */ -#ifdef PNG_SMALL_SIZE_T - typedef png_uint_32 png_alloc_size_t; -#else - typedef size_t png_alloc_size_t; -#endif - -/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler - * implementations of Intel CPU specific support of user-mode segmented address - * spaces, where 16-bit pointers address more than 65536 bytes of memory using - * separate 'segment' registers. The implementation requires two different - * types of pointer (only one of which includes the segment value.) - * - * If required this support is available in version 1.2 of libpng and may be - * available in versions through 1.5, although the correctness of the code has - * not been verified recently. - */ - -/* Typedef for floating-point numbers that are converted to fixed-point with a - * multiple of 100,000, e.g., gamma - */ -typedef png_int_32 png_fixed_point; - -/* Add typedefs for pointers */ -typedef void * png_voidp; -typedef const void * png_const_voidp; -typedef png_byte * png_bytep; -typedef const png_byte * png_const_bytep; -typedef png_uint_32 * png_uint_32p; -typedef const png_uint_32 * png_const_uint_32p; -typedef png_int_32 * png_int_32p; -typedef const png_int_32 * png_const_int_32p; -typedef png_uint_16 * png_uint_16p; -typedef const png_uint_16 * png_const_uint_16p; -typedef png_int_16 * png_int_16p; -typedef const png_int_16 * png_const_int_16p; -typedef char * png_charp; -typedef const char * png_const_charp; -typedef png_fixed_point * png_fixed_point_p; -typedef const png_fixed_point * png_const_fixed_point_p; -typedef size_t * png_size_tp; -typedef const size_t * png_const_size_tp; - -#ifdef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double * png_doublep; -typedef const double * png_const_doublep; -#endif - -/* Pointers to pointers; i.e. arrays */ -typedef png_byte * * png_bytepp; -typedef png_uint_32 * * png_uint_32pp; -typedef png_int_32 * * png_int_32pp; -typedef png_uint_16 * * png_uint_16pp; -typedef png_int_16 * * png_int_16pp; -typedef const char * * png_const_charpp; -typedef char * * png_charpp; -typedef png_fixed_point * * png_fixed_point_pp; -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double * * png_doublepp; -#endif - -/* Pointers to pointers to pointers; i.e., pointer to array */ -typedef char * * * png_charppp; - -#endif /* PNG_BUILDING_SYMBOL_TABLE */ - -#endif /* PNGCONF_H */ +/* pngconf.h - machine-configurable file for libpng + * + * libpng version 1.6.59.git + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ + +/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C + * compiler for correct compilation. The following header files are required by + * the standard. If your compiler doesn't provide these header files, or they + * do not match the standard, you will need to provide/improve them. + */ +#include +#include + +/* Library header files. These header files are all defined by ISOC90; libpng + * expects conformant implementations, however, an ISOC90 conformant system need + * not provide these header files if the functionality cannot be implemented. + * In this case it will be necessary to disable the relevant parts of libpng in + * the build of pnglibconf.h. + * + * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not + * include this unnecessary header file. + */ + +#ifdef PNG_STDIO_SUPPORTED + /* Required for the definition of FILE: */ +# include +#endif + +#ifdef PNG_SETJMP_SUPPORTED + /* Required for the definition of jmp_buf and the declaration of longjmp: */ +# include +#endif + +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* Required for struct tm: */ +# include +#endif + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +/* Prior to 1.6.0, it was possible to turn off 'const' in declarations, + * using PNG_NO_CONST. This is no longer supported. + */ +#define PNG_CONST const /* backward compatibility only */ + +/* This controls optimization of the reading of 16-bit and 32-bit + * values from PNG files. It can be set on a per-app-file basis: it + * just changes whether a macro is used when the function is called. + * The library builder sets the default; if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. + * + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. + */ + +/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect + * against legacy (pre ISOC90) compilers that did not understand function + * prototypes. [Deprecated.] + */ +#ifndef PNGARG +# define PNGARG(arglist) arglist +#endif + +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows systems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. + */ + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. Not used in the + * public header files; see pngpriv.h for how it is used + * in the libpng build. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \ + defined(__CYGWIN__) + /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or + * MinGW on any architecture currently supported by Windows. Also includes + * Watcom builds but these need special treatment because they are not + * compatible with GCC or Visual C because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 + /* If this line results in an error __stdcall is not understood and + * PNG_API_RULE should not have been set to '1'. + */ +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) +# error PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed +# endif + +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif + +#else /* !Windows */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* PNG_IMPEXP may be set on the compilation system command line or (if not set) + * then in an internal header file when building the library, otherwise (when + * using the library) it is set here. + */ +#ifndef PNG_IMPEXP +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP +# endif +#endif + +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat + * 'attributes' as a storage class - the attributes go at the start of the + * function definition, and attributes are always appended regardless of the + * compiler. This considerably simplifies these macros but may cause problems + * if any compilers both need function attributes and fail to handle them as + * a storage class (this is unlikely.) + */ +#ifndef PNG_FUNCTION +# define PNG_FUNCTION(type, name, args, attributes) attributes type name args +#endif + +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type +#endif + + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ + +#ifndef PNG_EXPORTA +# define PNG_EXPORTA(ordinal, type, name, args, attributes) \ + PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), args, \ + PNG_LINKAGE_API attributes) +#endif + +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, + * so make something non-empty to satisfy the requirement: + */ +#define PNG_EMPTY /*empty list*/ + +#define PNG_EXPORT(ordinal, type, name, args) \ + PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) args +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. + * + * Added at libpng-1.2.41. + */ + +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif + +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available, incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. Disabling these removes the warnings but may also produce + * less efficient code. + */ +# if defined(__clang__) && defined(__has_attribute) + /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ +# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# if !defined(PNG_PRIVATE) +# ifdef __has_extension +# if __has_extension(attribute_unavailable_with_message) +# define PNG_PRIVATE __attribute__((__unavailable__(\ + "This function is not exported by libpng."))) +# endif +# endif +# endif +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif + +# elif defined(__GNUC__) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# if __GNUC__ >= 3 +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif +# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ +# endif /* __GNUC__ >= 3 */ + +# elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* not supported */ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_ALLOCATED +# if (_MSC_VER >= 1400) +# define PNG_ALLOCATED __declspec(restrict) +# endif +# endif +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif +# ifndef PNG_RESTRICT +# if (_MSC_VER >= 1400) +# define PNG_RESTRICT __restrict +# endif +# endif + +# elif defined(__WATCOMC__) +# ifndef PNG_RESTRICT +# define PNG_RESTRICT __restrict +# endif +# endif +#endif /* PNG_PEDANTIC_WARNINGS */ + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ +#endif +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ +#endif +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ +#endif +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ +#endif +#ifndef PNG_RESTRICT +# define PNG_RESTRICT /* The C99 "restrict" feature */ +#endif + +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif +#endif +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args); +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif +#endif + +#ifndef PNG_BUILDING_SYMBOL_TABLE +/* Some typedefs to get us started. These should be safe on most of the common + * platforms. + * + * png_uint_32 and png_int_32 may, currently, be larger than required to hold a + * 32-bit value however this is not normally advisable. + * + * png_uint_16 and png_int_16 should always be two bytes in size - this is + * verified at library build time. + * + * png_byte must always be one byte in size. + * + * The checks below use constants from limits.h, as defined by the ISOC90 + * standard. + */ +#if CHAR_BIT == 8 && UCHAR_MAX == 255 + typedef unsigned char png_byte; +#else +# error libpng requires 8-bit bytes +#endif + +#if INT_MIN == -32768 && INT_MAX == 32767 + typedef int png_int_16; +#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 + typedef short png_int_16; +#else +# error libpng requires a signed 16-bit integer type +#endif + +#if UINT_MAX == 65535 + typedef unsigned int png_uint_16; +#elif USHRT_MAX == 65535 + typedef unsigned short png_uint_16; +#else +# error libpng requires an unsigned 16-bit integer type +#endif + +#if INT_MIN < -2147483646 && INT_MAX > 2147483646 + typedef int png_int_32; +#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 + typedef long int png_int_32; +#else +# error libpng requires a signed 32-bit (or longer) integer type +#endif + +#if UINT_MAX > 4294967294U + typedef unsigned int png_uint_32; +#elif ULONG_MAX > 4294967294U + typedef unsigned long int png_uint_32; +#else +# error libpng requires an unsigned 32-bit (or longer) integer type +#endif + +/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t. + * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant + * behavior of sizeof and ptrdiff_t are required. + * The legacy typedefs are provided here for backwards compatibility. + */ +typedef size_t png_size_t; +typedef ptrdiff_t png_ptrdiff_t; + +/* libpng needs to know the maximum value of 'size_t' and this controls the + * definition of png_alloc_size_t, below. This maximum value of size_t limits + * but does not control the maximum allocations the library makes - there is + * direct application control of this through png_set_user_limits(). + */ +#ifndef PNG_SMALL_SIZE_T + /* Compiler specific tests for systems where size_t is known to be less than + * 32 bits (some of these systems may no longer work because of the lack of + * 'far' support; see above.) + */ +# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ + (defined(_MSC_VER) && defined(MAXSEG_64K)) +# define PNG_SMALL_SIZE_T +# endif +#endif + +/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller + * than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are + * not necessary; in fact, it is recommended not to use them at all, so that + * the compiler can complain when something turns out to be problematic. + * + * Casts in the other direction (from png_alloc_size_t to size_t or + * png_uint_32) should be explicitly applied; however, we do not expect to + * encounter practical situations that require such conversions. + * + * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than + * 4294967295 - i.e. less than the maximum value of png_uint_32. + */ +#ifdef PNG_SMALL_SIZE_T + typedef png_uint_32 png_alloc_size_t; +#else + typedef size_t png_alloc_size_t; +#endif + +/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler + * implementations of Intel CPU specific support of user-mode segmented address + * spaces, where 16-bit pointers address more than 65536 bytes of memory using + * separate 'segment' registers. The implementation requires two different + * types of pointer (only one of which includes the segment value.) + * + * If required this support is available in version 1.2 of libpng and may be + * available in versions through 1.5, although the correctness of the code has + * not been verified recently. + */ + +/* Typedef for floating-point numbers that are converted to fixed-point with a + * multiple of 100,000, e.g., gamma + */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void * png_voidp; +typedef const void * png_const_voidp; +typedef png_byte * png_bytep; +typedef const png_byte * png_const_bytep; +typedef png_uint_32 * png_uint_32p; +typedef const png_uint_32 * png_const_uint_32p; +typedef png_int_32 * png_int_32p; +typedef const png_int_32 * png_const_int_32p; +typedef png_uint_16 * png_uint_16p; +typedef const png_uint_16 * png_const_uint_16p; +typedef png_int_16 * png_int_16p; +typedef const png_int_16 * png_const_int_16p; +typedef char * png_charp; +typedef const char * png_const_charp; +typedef png_fixed_point * png_fixed_point_p; +typedef const png_fixed_point * png_const_fixed_point_p; +typedef size_t * png_size_tp; +typedef const size_t * png_const_size_tp; + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * png_doublep; +typedef const double * png_const_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte * * png_bytepp; +typedef png_uint_32 * * png_uint_32pp; +typedef png_int_32 * * png_int_32pp; +typedef png_uint_16 * * png_uint_16pp; +typedef png_int_16 * * png_int_16pp; +typedef const char * * png_const_charpp; +typedef char * * png_charpp; +typedef png_fixed_point * * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double * * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char * * * png_charppp; + +#ifdef PNG_STDIO_SUPPORTED +/* With PNG_STDIO_SUPPORTED it was possible to use I/O streams that were + * not necessarily stdio FILE streams, to allow building Windows applications + * before Win32 and Windows CE applications before WinCE 3.0, but that kind + * of support has long been discontinued. + */ +typedef FILE * png_FILE_p; /* [Deprecated] */ +#endif + +#endif /* PNG_BUILDING_SYMBOL_TABLE */ + +#endif /* PNGCONF_H */ diff --git a/thirdparty/libpng/upstream/pngdebug.h b/thirdparty/libpng/upstream/pngdebug.h index 5530c0c92..0337918ae 100644 --- a/thirdparty/libpng/upstream/pngdebug.h +++ b/thirdparty/libpng/upstream/pngdebug.h @@ -1,153 +1,153 @@ - -/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* Define PNG_DEBUG at compile time for debugging information. Higher - * numbers for PNG_DEBUG mean more debugging information. This has - * only been added since version 0.95 so it is not implemented throughout - * libpng yet, but more support will be added as needed. - * - * png_debug[1-2]?(level, message ,arg{0-2}) - * Expands to a statement (either a simple expression or a compound - * do..while(0) statement) that outputs a message with parameter - * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG - * is undefined, 0 or 1 every png_debug expands to a simple expression - * (actually ((void)0)). - * - * level: level of detail of message, starting at 0. A level 'n' - * message is preceded by 'n' 3-space indentations (not implemented - * on Microsoft compilers unless PNG_DEBUG_FILE is also - * defined, to allow debug DLL compilation with no standard IO). - * message: a printf(3) style text string. A trailing '\n' is added - * to the message. - * arg: 0 to 2 arguments for printf(3) style substitution in message. - */ -#ifndef PNGDEBUG_H -#define PNGDEBUG_H -/* These settings control the formatting of messages in png.c and pngerror.c */ -/* Moved to pngdebug.h at 1.5.0 */ -# ifndef PNG_LITERAL_SHARP -# define PNG_LITERAL_SHARP 0x23 -# endif -# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET -# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b -# endif -# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET -# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d -# endif -# ifndef PNG_STRING_NEWLINE -# define PNG_STRING_NEWLINE "\n" -# endif - -#ifdef PNG_DEBUG -# if (PNG_DEBUG > 0) -# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) -# include -# if (PNG_DEBUG > 1) -# ifndef _DEBUG -# define _DEBUG -# endif -# ifndef png_debug -# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) -# endif -# endif -# else /* PNG_DEBUG_FILE || !_MSC_VER */ -# ifndef PNG_STDIO_SUPPORTED -# include /* not included yet */ -# endif -# ifndef PNG_DEBUG_FILE -# define PNG_DEBUG_FILE stderr -# endif /* PNG_DEBUG_FILE */ - -# if (PNG_DEBUG > 1) -# ifdef __STDC__ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\ - } while (0) -# endif -# else /* __STDC __ */ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1,p2); \ - } while (0) -# endif -# endif /* __STDC __ */ -# endif /* (PNG_DEBUG > 1) */ - -# endif /* _MSC_VER */ -# endif /* (PNG_DEBUG > 0) */ -#endif /* PNG_DEBUG */ -#ifndef png_debug -# define png_debug(l, m) ((void)0) -#endif -#ifndef png_debug1 -# define png_debug1(l, m, p1) ((void)0) -#endif -#ifndef png_debug2 -# define png_debug2(l, m, p1, p2) ((void)0) -#endif -#endif /* PNGDEBUG_H */ +/* pngdebug.h - internal debugging macros for libpng + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#ifndef PNGPRIV_H +# error This file must not be included by applications; please include +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + * + * png_debug[1-2]?(level, message ,arg{0-2}) + * Expands to a statement (either a simple expression or a compound + * do..while(0) statement) that outputs a message with parameter + * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG + * is undefined, 0 or 1 every png_debug expands to a simple expression + * (actually ((void)0)). + * + * level: level of detail of message, starting at 0. A level 'n' + * message is preceded by 'n' 3-space indentations (not implemented + * on Microsoft compilers unless PNG_DEBUG_FILE is also + * defined, to allow debug DLL compilation with no standard IO). + * message: a printf(3) style text string. A trailing '\n' is added + * to the message. + * arg: 0 to 2 arguments for printf(3) style substitution in message. + */ +#ifndef PNGDEBUG_H +#define PNGDEBUG_H +/* These settings control the formatting of messages in png.c and pngerror.c */ +/* Moved to pngdebug.h at 1.5.0 */ +# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET +# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b +# endif +# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET +# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d +# endif +# ifndef PNG_STRING_NEWLINE +# define PNG_STRING_NEWLINE "\n" +# endif + +#ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +# include +# if (PNG_DEBUG > 1) +# ifndef _DEBUG +# define _DEBUG +# endif +# ifndef png_debug +# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) +# endif +# endif +# else /* PNG_DEBUG_FILE || !_MSC_VER */ +# ifndef PNG_STDIO_SUPPORTED +# include /* not included yet */ +# endif +# ifndef PNG_DEBUG_FILE +# define PNG_DEBUG_FILE stderr +# endif /* PNG_DEBUG_FILE */ + +# if (PNG_DEBUG > 1) +# ifdef __STDC__ +# ifndef png_debug +# define png_debug(l,m) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ + (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ + } while (0) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ + (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \ + } while (0) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ + (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\ + } while (0) +# endif +# else /* __STDC __ */ +# ifndef png_debug +# define png_debug(l,m) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format); \ + } while (0) +# endif +# ifndef png_debug1 +# define png_debug1(l,m,p1) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1); \ + } while (0) +# endif +# ifndef png_debug2 +# define png_debug2(l,m,p1,p2) \ + do { \ + int num_tabs=l; \ + char format[256]; \ + snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ + m,PNG_STRING_NEWLINE); \ + fprintf(PNG_DEBUG_FILE,format,p1,p2); \ + } while (0) +# endif +# endif /* __STDC __ */ +# endif /* (PNG_DEBUG > 1) */ + +# endif /* _MSC_VER */ +# endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +# define png_debug(l, m) ((void)0) +#endif +#ifndef png_debug1 +# define png_debug1(l, m, p1) ((void)0) +#endif +#ifndef png_debug2 +# define png_debug2(l, m, p1, p2) ((void)0) +#endif +#endif /* PNGDEBUG_H */ diff --git a/thirdparty/libpng/upstream/pngerror.c b/thirdparty/libpng/upstream/pngerror.c index db852f078..72dc20ea8 100644 --- a/thirdparty/libpng/upstream/pngerror.c +++ b/thirdparty/libpng/upstream/pngerror.c @@ -1,958 +1,850 @@ - -/* pngerror.c - stub functions for i/o and memory allocation - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all error handling. Users who - * need special error handling are expected to write replacement functions - * and use png_set_error_fn() to use those functions. See the instructions - * at each function. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -static PNG_FUNCTION(void /* PRIVATE */, -png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -static void /* PRIVATE */ -png_default_warning(png_const_structrp png_ptr, - png_const_charp warning_message); -#endif /* WARNINGS */ - -/* This function is called whenever there is a fatal error. This function - * should not be changed. If there is a need to handle errors differently, - * you should supply a replacement error function and use png_set_error_fn() - * to replace the error function at run-time. - */ -#ifdef PNG_ERROR_TEXT_SUPPORTED -PNG_FUNCTION(void,PNGAPI -png_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - char msg[16]; - if (png_ptr != NULL) - { - if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) - { - if (*error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - for (offset = 1; offset<15; offset++) - if (error_message[offset] == ' ') - break; - - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - int i; - for (i = 0; i < offset - 1; i++) - msg[i] = error_message[i + 1]; - msg[i - 1] = '\0'; - error_message = msg; - } - - else - error_message += offset; - } - - else - { - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - msg[0] = '0'; - msg[1] = '\0'; - error_message = msg; - } - } - } - } -#endif - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), - error_message); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, error_message); -} -#else -PNG_FUNCTION(void,PNGAPI -png_err,(png_const_structrp png_ptr),PNG_NORETURN) -{ - /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed - * erroneously as '\0', instead of the empty string "". This was - * apparently an error, introduced in libpng-1.2.20, and png_default_error - * will crash in this case. - */ - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, ""); -} -#endif /* ERROR_TEXT */ - -/* Utility to safely appends strings to a buffer. This never errors out so - * error checking is not required in the caller. - */ -size_t -png_safecat(png_charp buffer, size_t bufsize, size_t pos, - png_const_charp string) -{ - if (buffer != NULL && pos < bufsize) - { - if (string != NULL) - while (*string != '\0' && pos < bufsize-1) - buffer[pos++] = *string++; - - buffer[pos] = '\0'; - } - - return pos; -} - -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. - */ -png_charp -png_format_number(png_const_charp start, png_charp end, int format, - png_alloc_size_t number) -{ - int count = 0; /* number of digits output */ - int mincount = 1; /* minimum number required */ - int output = 0; /* digit output (for the fixed point format) */ - - *--end = '\0'; - - /* This is written so that the loop always runs at least once, even with - * number zero. - */ - while (end > start && (number != 0 || count < mincount)) - { - - static const char digits[] = "0123456789ABCDEF"; - - switch (format) - { - case PNG_NUMBER_FORMAT_fixed: - /* Needs five digits (the fraction) */ - mincount = 5; - if (output != 0 || number % 10 != 0) - { - *--end = digits[number % 10]; - output = 1; - } - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02u: - /* Expects at least 2 digits. */ - mincount = 2; - /* FALLTHROUGH */ - - case PNG_NUMBER_FORMAT_u: - *--end = digits[number % 10]; - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02x: - /* This format expects at least two digits */ - mincount = 2; - /* FALLTHROUGH */ - - case PNG_NUMBER_FORMAT_x: - *--end = digits[number & 0xf]; - number >>= 4; - break; - - default: /* an error */ - number = 0; - break; - } - - /* Keep track of the number of digits added */ - ++count; - - /* Float a fixed number here: */ - if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) - { - /* End of the fraction, but maybe nothing was output? In that case - * drop the decimal point. If the number is a true zero handle that - * here. - */ - if (output != 0) - *--end = '.'; - else if (number == 0) /* and !output */ - *--end = '0'; - } - } - - return end; -} -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called whenever there is a non-fatal error. This function - * should not be changed. If there is a need to handle warnings differently, - * you should supply a replacement warning function and use - * png_set_error_fn() to replace the warning function at run-time. - */ -void PNGAPI -png_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ - int offset = 0; - if (png_ptr != NULL) - { -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) -#endif - { - if (*warning_message == PNG_LITERAL_SHARP) - { - for (offset = 1; offset < 15; offset++) - if (warning_message[offset] == ' ') - break; - } - } - } - if (png_ptr != NULL && png_ptr->warning_fn != NULL) - (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), - warning_message + offset); - else - png_default_warning(png_ptr, warning_message + offset); -} - -/* These functions support 'formatted' warning messages with up to - * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter - * is introduced by @, where 'number' starts at 1. This follows the - * standard established by X/Open for internationalizable error messages. - */ -void -png_warning_parameter(png_warning_parameters p, int number, - png_const_charp string) -{ - if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) - (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); -} - -void -png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, - png_alloc_size_t value) -{ - char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; - png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); -} - -void -png_warning_parameter_signed(png_warning_parameters p, int number, int format, - png_int_32 value) -{ - png_alloc_size_t u; - png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; - - /* Avoid overflow by doing the negate in a png_alloc_size_t: */ - u = (png_alloc_size_t)value; - if (value < 0) - u = ~u + 1; - - str = PNG_FORMAT_NUMBER(buffer, format, u); - - if (value < 0 && str > buffer) - *--str = '-'; - - png_warning_parameter(p, number, str); -} - -void -png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, - png_const_charp message) -{ - /* The internal buffer is just 192 bytes - enough for all our messages, - * overflow doesn't happen because this code checks! If someone figures - * out how to send us a message longer than 192 bytes, all that will - * happen is that the message will be truncated appropriately. - */ - size_t i = 0; /* Index in the msg[] buffer: */ - char msg[192]; - - /* Each iteration through the following loop writes at most one character - * to msg[i++] then returns here to validate that there is still space for - * the trailing '\0'. It may (in the case of a parameter) read more than - * one character from message[]; it must check for '\0' and continue to the - * test if it finds the end of string. - */ - while (i<(sizeof msg)-1 && *message != '\0') - { - /* '@' at end of string is now just printed (previously it was skipped); - * it is an error in the calling code to terminate the string with @. - */ - if (p != NULL && *message == '@' && message[1] != '\0') - { - int parameter_char = *++message; /* Consume the '@' */ - static const char valid_parameters[] = "123456789"; - int parameter = 0; - - /* Search for the parameter digit, the index in the string is the - * parameter to use. - */ - while (valid_parameters[parameter] != parameter_char && - valid_parameters[parameter] != '\0') - ++parameter; - - /* If the parameter digit is out of range it will just get printed. */ - if (parameter < PNG_WARNING_PARAMETER_COUNT) - { - /* Append this parameter */ - png_const_charp parm = p[parameter]; - png_const_charp pend = p[parameter] + (sizeof p[parameter]); - - /* No need to copy the trailing '\0' here, but there is no guarantee - * that parm[] has been initialized, so there is no guarantee of a - * trailing '\0': - */ - while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) - msg[i++] = *parm++; - - /* Consume the parameter digit too: */ - ++message; - continue; - } - - /* else not a parameter and there is a character after the @ sign; just - * copy that. This is known not to be '\0' because of the test above. - */ - } - - /* At this point *message can't be '\0', even in the bad parameter case - * above where there is a lone '@' at the end of the message string. - */ - msg[i++] = *message++; - } - - /* i is always less than (sizeof msg), so: */ - msg[i] = '\0'; - - /* And this is the formatted message. It may be larger than - * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these - * are not (currently) formatted. - */ - png_warning(png_ptr, msg); -} -#endif /* WARNINGS */ - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) -{ - if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) - { -# ifdef PNG_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - png_ptr->chunk_name != 0) - png_chunk_warning(png_ptr, error_message); - else -# endif - png_warning(png_ptr, error_message); - } - - else - { -# ifdef PNG_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - png_ptr->chunk_name != 0) - png_chunk_error(png_ptr, error_message); - else -# endif - png_error(png_ptr, error_message); - } - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} - -void /* PRIVATE */ -png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) -{ - if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} - -void /* PRIVATE */ -png_app_error(png_const_structrp png_ptr, png_const_charp error_message) -{ - if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} -#endif /* BENIGN_ERRORS */ - -#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */ -#if defined(PNG_WARNINGS_SUPPORTED) || \ - (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) -/* These utilities are used internally to build an error message that relates - * to the current chunk. The chunk name comes from png_ptr->chunk_name, - * which is used to prefix the message. The message is limited in length - * to 63 bytes. The name characters are output as hex digits wrapped in [] - * if the character is invalid. - */ -#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -static const char png_digit[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' -}; - -static void /* PRIVATE */ -png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp - error_message) -{ - png_uint_32 chunk_name = png_ptr->chunk_name; - int iout = 0, ishift = 24; - - while (ishift >= 0) - { - int c = (int)(chunk_name >> ishift) & 0xff; - - ishift -= 8; - if (isnonalpha(c) != 0) - { - buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; - buffer[iout++] = png_digit[(c & 0xf0) >> 4]; - buffer[iout++] = png_digit[c & 0x0f]; - buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; - } - - else - { - buffer[iout++] = (char)c; - } - } - - if (error_message == NULL) - buffer[iout] = '\0'; - - else - { - int iin = 0; - - buffer[iout++] = ':'; - buffer[iout++] = ' '; - - while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') - buffer[iout++] = error_message[iin++]; - - /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ - buffer[iout] = '\0'; - } -} -#endif /* WARNINGS || ERROR_TEXT */ - -#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_FUNCTION(void,PNGAPI -png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) - png_error(png_ptr, error_message); - - else - { - png_format_buffer(png_ptr, msg, error_message); - png_error(png_ptr, msg); - } -} -#endif /* READ && ERROR_TEXT */ - -#ifdef PNG_WARNINGS_SUPPORTED -void PNGAPI -png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) - png_warning(png_ptr, warning_message); - - else - { - png_format_buffer(png_ptr, msg, warning_message); - png_warning(png_ptr, msg); - } -} -#endif /* WARNINGS */ - -#ifdef PNG_READ_SUPPORTED -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp - error_message) -{ - if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) - png_chunk_warning(png_ptr, error_message); - - else - png_chunk_error(png_ptr, error_message); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} -#endif -#endif /* READ */ - -void /* PRIVATE */ -png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) -{ -# ifndef PNG_WARNINGS_SUPPORTED - PNG_UNUSED(message) -# endif - - /* This is always supported, but for just read or just write it - * unconditionally does the right thing. - */ -# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -# endif - -# ifdef PNG_READ_SUPPORTED - { - if (error < PNG_CHUNK_ERROR) - png_chunk_warning(png_ptr, message); - - else - png_chunk_benign_error(png_ptr, message); - } -# endif - -# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) - else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) -# endif - -# ifdef PNG_WRITE_SUPPORTED - { - if (error < PNG_CHUNK_WRITE_ERROR) - png_app_warning(png_ptr, message); - - else - png_app_error(png_ptr, message); - } -# endif -} - -#ifdef PNG_ERROR_TEXT_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_FUNCTION(void, -png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) -{ -# define fixed_message "fixed point overflow in " -# define fixed_message_ln ((sizeof fixed_message)-1) - unsigned int iin; - char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; - memcpy(msg, fixed_message, fixed_message_ln); - iin = 0; - if (name != NULL) - while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) - { - msg[fixed_message_ln + iin] = name[iin]; - ++iin; - } - msg[fixed_message_ln + iin] = 0; - png_error(png_ptr, msg); -} -#endif -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This API only exists if ANSI-C style error handling is used, - * otherwise it is necessary for png_default_error to be overridden. - */ -jmp_buf* PNGAPI -png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, - size_t jmp_buf_size) -{ - /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value - * and it must not change after that. Libpng doesn't care how big the - * buffer is, just that it doesn't change. - * - * If the buffer size is no *larger* than the size of jmp_buf when libpng is - * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 - * semantics that this call will not fail. If the size is larger, however, - * the buffer is allocated and this may fail, causing the function to return - * NULL. - */ - if (png_ptr == NULL) - return NULL; - - if (png_ptr->jmp_buf_ptr == NULL) - { - png_ptr->jmp_buf_size = 0; /* not allocated */ - - if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) - png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; - - else - { - png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, - png_malloc_warn(png_ptr, jmp_buf_size)); - - if (png_ptr->jmp_buf_ptr == NULL) - return NULL; /* new NULL return on OOM */ - - png_ptr->jmp_buf_size = jmp_buf_size; - } - } - - else /* Already allocated: check the size */ - { - size_t size = png_ptr->jmp_buf_size; - - if (size == 0) - { - size = (sizeof png_ptr->jmp_buf_local); - if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) - { - /* This is an internal error in libpng: somehow we have been left - * with a stack allocated jmp_buf when the application regained - * control. It's always possible to fix this up, but for the moment - * this is a png_error because that makes it easy to detect. - */ - png_error(png_ptr, "Libpng jmp_buf still allocated"); - /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ - } - } - - if (size != jmp_buf_size) - { - png_warning(png_ptr, "Application jmp_buf size changed"); - return NULL; /* caller will probably crash: no choice here */ - } - } - - /* Finally fill in the function, now we have a satisfactory buffer. It is - * valid to change the function on every call. - */ - png_ptr->longjmp_fn = longjmp_fn; - return png_ptr->jmp_buf_ptr; -} - -void /* PRIVATE */ -png_free_jmpbuf(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - jmp_buf *jb = png_ptr->jmp_buf_ptr; - - /* A size of 0 is used to indicate a local, stack, allocation of the - * pointer; used here and in png.c - */ - if (jb != NULL && png_ptr->jmp_buf_size > 0) - { - - /* This stuff is so that a failure to free the error control structure - * does not leave libpng in a state with no valid error handling: the - * free always succeeds, if there is an error it gets ignored. - */ - if (jb != &png_ptr->jmp_buf_local) - { - /* Make an internal, libpng, jmp_buf to return here */ - jmp_buf free_jmp_buf; - - if (!setjmp(free_jmp_buf)) - { - png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ - png_ptr->jmp_buf_size = 0; /* stack allocation */ - png_ptr->longjmp_fn = longjmp; - png_free(png_ptr, jb); /* Return to setjmp on error */ - } - } - } - - /* *Always* cancel everything out: */ - png_ptr->jmp_buf_size = 0; - png_ptr->jmp_buf_ptr = NULL; - png_ptr->longjmp_fn = 0; - } -} -#endif - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static PNG_FUNCTION(void /* PRIVATE */, -png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - /* Check on NULL only added in 1.5.4 */ - if (error_message != NULL && *error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - char error_number[16]; - for (offset = 0; offset<15; offset++) - { - error_number[offset] = error_message[offset + 1]; - if (error_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - error_number[offset - 1] = '\0'; - fprintf(stderr, "libpng error no. %s: %s", - error_number, error_message + offset + 1); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng error: %s, offset=%d", - error_message, offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -#endif - { - fprintf(stderr, "libpng error: %s", error_message ? error_message : - "undefined"); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(error_message) /* Make compiler happy */ -#endif - png_longjmp(png_ptr, 1); -} - -PNG_FUNCTION(void,PNGAPI -png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) -{ -#ifdef PNG_SETJMP_SUPPORTED - if (png_ptr != NULL && png_ptr->longjmp_fn != NULL && - png_ptr->jmp_buf_ptr != NULL) - png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(val) -#endif - - /* If control reaches this point, png_longjmp() must not return. The only - * choice is to terminate the whole process (or maybe the thread); to do - * this the ANSI-C abort() function is used unless a different method is - * implemented by overriding the default configuration setting for - * PNG_ABORT(). - */ - PNG_ABORT(); -} - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want them to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -static void /* PRIVATE */ -png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED -# ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (*warning_message == PNG_LITERAL_SHARP) - { - int offset; - char warning_number[16]; - for (offset = 0; offset < 15; offset++) - { - warning_number[offset] = warning_message[offset + 1]; - if (warning_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - warning_number[offset + 1] = '\0'; - fprintf(stderr, "libpng warning no. %s: %s", - warning_number, warning_message + offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng warning: %s", - warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -# endif - - { - fprintf(stderr, "libpng warning: %s", warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(warning_message) /* Make compiler happy */ -#endif - PNG_UNUSED(png_ptr) /* Make compiler happy */ -} -#endif /* WARNINGS */ - -/* This function is called when the application wants to use another method - * of handling errors and warnings. Note that the error function MUST NOT - * return to the calling routine or serious problems will occur. The return - * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) - */ -void PNGAPI -png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->error_ptr = error_ptr; - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#else - PNG_UNUSED(warning_fn) -#endif -} - - -/* This function returns a pointer to the error_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_error_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return (png_voidp)png_ptr->error_ptr; -} - - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -void PNGAPI -png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) -{ - if (png_ptr != NULL) - { - png_ptr->flags &= - ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | - PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); - } -} -#endif - -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) - /* Currently the above both depend on SETJMP_SUPPORTED, however it would be - * possible to implement without setjmp support just so long as there is some - * way to handle the error return here: - */ -PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI -png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - png_const_structrp png_ptr = png_nonconst_ptr; - png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); - - /* An error is always logged here, overwriting anything (typically a warning) - * that is already there: - */ - if (image != NULL) - { - png_safecat(image->message, (sizeof image->message), 0, error_message); - image->warning_or_error |= PNG_IMAGE_ERROR; - - /* Retrieve the jmp_buf from within the png_control, making this work for - * C++ compilation too is pretty tricky: C++ wants a pointer to the first - * element of a jmp_buf, but C doesn't tell us the type of that. - */ - if (image->opaque != NULL && image->opaque->error_buf != NULL) - longjmp(png_control_jmp_buf(image->opaque), 1); - - /* Missing longjmp buffer, the following is to help debugging: */ - { - size_t pos = png_safecat(image->message, (sizeof image->message), 0, - "bad longjmp: "); - png_safecat(image->message, (sizeof image->message), pos, - error_message); - } - } - - /* Here on an internal programming error. */ - abort(); -} - -#ifdef PNG_WARNINGS_SUPPORTED -void /* PRIVATE */ PNGCBAPI -png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) -{ - png_const_structrp png_ptr = png_nonconst_ptr; - png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); - - /* A warning is only logged if there is no prior warning or error. */ - if (image->warning_or_error == 0) - { - png_safecat(image->message, (sizeof image->message), 0, warning_message); - image->warning_or_error |= PNG_IMAGE_WARNING; - } -} -#endif - -int /* PRIVATE */ -png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg) -{ - png_voidp saved_error_buf = image->opaque->error_buf; - jmp_buf safe_jmpbuf; - int result; - - /* Safely execute function(arg), with png_error returning back here. */ - if (setjmp(safe_jmpbuf) == 0) - { - image->opaque->error_buf = safe_jmpbuf; - result = function(arg); - image->opaque->error_buf = saved_error_buf; - return result; - } - - /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */ - image->opaque->error_buf = saved_error_buf; - png_image_free(image); - return 0; -} -#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ -#endif /* READ || WRITE */ +/* pngerror.c - stub functions for i/o and memory allocation + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all error handling. Users who + * need special error handling are expected to write replacement functions + * and use png_set_error_fn() to use those functions. See the instructions + * at each function. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +static PNG_FUNCTION(void /* PRIVATE */, +png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN); + +#ifdef PNG_WARNINGS_SUPPORTED +static void /* PRIVATE */ +png_default_warning(png_const_structrp png_ptr, + png_const_charp warning_message); +#endif /* WARNINGS */ + +/* This function is called whenever there is a fatal error. This function + * should not be changed. If there is a need to handle errors differently, + * you should supply a replacement error function and use png_set_error_fn() + * to replace the error function at run-time. + */ +#ifdef PNG_ERROR_TEXT_SUPPORTED +PNG_FUNCTION(void,PNGAPI +png_error,(png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), + error_message); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, error_message); +} +#else +PNG_FUNCTION(void,PNGAPI +png_err,(png_const_structrp png_ptr), + PNG_NORETURN) +{ + /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed + * erroneously as '\0', instead of the empty string "". This was + * apparently an error, introduced in libpng-1.2.20, and png_default_error + * will crash in this case. + */ + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); + + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, ""); +} +#endif /* ERROR_TEXT */ + +/* Utility to safely appends strings to a buffer. This never errors out so + * error checking is not required in the caller. + */ +size_t +png_safecat(png_charp buffer, size_t bufsize, size_t pos, + png_const_charp string) +{ + if (buffer != NULL && pos < bufsize) + { + if (string != NULL) + while (*string != '\0' && pos < bufsize-1) + buffer[pos++] = *string++; + + buffer[pos] = '\0'; + } + + return pos; +} + +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) +/* Utility to dump an unsigned value into a buffer, given a start pointer and + * and end pointer (which should point just *beyond* the end of the buffer!) + * Returns the pointer to the start of the formatted string. + */ +png_charp +png_format_number(png_const_charp start, png_charp end, int format, + png_alloc_size_t number) +{ + int count = 0; /* number of digits output */ + int mincount = 1; /* minimum number required */ + int output = 0; /* digit output (for the fixed point format) */ + + *--end = '\0'; + + /* This is written so that the loop always runs at least once, even with + * number zero. + */ + while (end > start && (number != 0 || count < mincount)) + { + + static const char digits[] = "0123456789ABCDEF"; + + switch (format) + { + case PNG_NUMBER_FORMAT_fixed: + /* Needs five digits (the fraction) */ + mincount = 5; + if (output != 0 || number % 10 != 0) + { + *--end = digits[number % 10]; + output = 1; + } + number /= 10; + break; + + case PNG_NUMBER_FORMAT_02u: + /* Expects at least 2 digits. */ + mincount = 2; + /* FALLTHROUGH */ + + case PNG_NUMBER_FORMAT_u: + *--end = digits[number % 10]; + number /= 10; + break; + + case PNG_NUMBER_FORMAT_02x: + /* This format expects at least two digits */ + mincount = 2; + /* FALLTHROUGH */ + + case PNG_NUMBER_FORMAT_x: + *--end = digits[number & 0xf]; + number >>= 4; + break; + + default: /* an error */ + number = 0; + break; + } + + /* Keep track of the number of digits added */ + ++count; + + /* Float a fixed number here: */ + if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) + { + /* End of the fraction, but maybe nothing was output? In that case + * drop the decimal point. If the number is a true zero handle that + * here. + */ + if (output != 0) + *--end = '.'; + else if (number == 0) /* and !output */ + *--end = '0'; + } + } + + return end; +} +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* This function is called whenever there is a non-fatal error. This function + * should not be changed. If there is a need to handle warnings differently, + * you should supply a replacement warning function and use + * png_set_error_fn() to replace the warning function at run-time. + */ +void PNGAPI +png_warning(png_const_structrp png_ptr, png_const_charp warning_message) +{ + int offset = 0; + if (png_ptr != NULL && png_ptr->warning_fn != NULL) + (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), + warning_message + offset); + else + png_default_warning(png_ptr, warning_message + offset); +} + +/* These functions support 'formatted' warning messages with up to + * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter + * is introduced by @, where 'number' starts at 1. This follows the + * standard established by X/Open for internationalizable error messages. + */ +void +png_warning_parameter(png_warning_parameters p, int number, + png_const_charp string) +{ + if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) + (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); +} + +void +png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, + png_alloc_size_t value) +{ + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; + png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); +} + +void +png_warning_parameter_signed(png_warning_parameters p, int number, int format, + png_int_32 value) +{ + png_alloc_size_t u; + png_charp str; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; + + /* Avoid overflow by doing the negate in a png_alloc_size_t: */ + u = (png_alloc_size_t)value; + if (value < 0) + u = ~u + 1; + + str = PNG_FORMAT_NUMBER(buffer, format, u); + + if (value < 0 && str > buffer) + *--str = '-'; + + png_warning_parameter(p, number, str); +} + +void +png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, + png_const_charp message) +{ + /* The internal buffer is just 192 bytes - enough for all our messages, + * overflow doesn't happen because this code checks! If someone figures + * out how to send us a message longer than 192 bytes, all that will + * happen is that the message will be truncated appropriately. + */ + size_t i = 0; /* Index in the msg[] buffer: */ + char msg[192]; + + /* Each iteration through the following loop writes at most one character + * to msg[i++] then returns here to validate that there is still space for + * the trailing '\0'. It may (in the case of a parameter) read more than + * one character from message[]; it must check for '\0' and continue to the + * test if it finds the end of string. + */ + while (i<(sizeof msg)-1 && *message != '\0') + { + /* '@' at end of string is now just printed (previously it was skipped); + * it is an error in the calling code to terminate the string with @. + */ + if (p != NULL && *message == '@' && message[1] != '\0') + { + int parameter_char = *++message; /* Consume the '@' */ + static const char valid_parameters[] = "123456789"; + int parameter = 0; + + /* Search for the parameter digit, the index in the string is the + * parameter to use. + */ + while (valid_parameters[parameter] != parameter_char && + valid_parameters[parameter] != '\0') + ++parameter; + + /* If the parameter digit is out of range it will just get printed. */ + if (parameter < PNG_WARNING_PARAMETER_COUNT) + { + /* Append this parameter */ + png_const_charp parm = p[parameter]; + png_const_charp pend = p[parameter] + (sizeof p[parameter]); + + /* No need to copy the trailing '\0' here, but there is no guarantee + * that parm[] has been initialized, so there is no guarantee of a + * trailing '\0': + */ + while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) + msg[i++] = *parm++; + + /* Consume the parameter digit too: */ + ++message; + continue; + } + + /* else not a parameter and there is a character after the @ sign; just + * copy that. This is known not to be '\0' because of the test above. + */ + } + + /* At this point *message can't be '\0', even in the bad parameter case + * above where there is a lone '@' at the end of the message string. + */ + msg[i++] = *message++; + } + + /* i is always less than (sizeof msg), so: */ + msg[i] = '\0'; + + /* And this is the formatted message. It may be larger than + * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these + * are not (currently) formatted. + */ + png_warning(png_ptr, msg); +} +#endif /* WARNINGS */ + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) +{ + if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) + { +# ifdef PNG_READ_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + png_ptr->chunk_name != 0) + png_chunk_warning(png_ptr, error_message); + else +# endif + png_warning(png_ptr, error_message); + } + + else + { +# ifdef PNG_READ_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + png_ptr->chunk_name != 0) + png_chunk_error(png_ptr, error_message); + else +# endif + png_error(png_ptr, error_message); + } + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} + +void /* PRIVATE */ +png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) +{ + if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} + +void /* PRIVATE */ +png_app_error(png_const_structrp png_ptr, png_const_charp error_message) +{ + if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) + png_warning(png_ptr, error_message); + else + png_error(png_ptr, error_message); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} +#endif /* BENIGN_ERRORS */ + +#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */ +#if defined(PNG_WARNINGS_SUPPORTED) || \ + (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) +/* These utilities are used internally to build an error message that relates + * to the current chunk. The chunk name comes from png_ptr->chunk_name, + * which is used to prefix the message. The message is limited in length + * to 63 bytes. The name characters are output as hex digits wrapped in [] + * if the character is invalid. + */ +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) +static const char png_digit[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' +}; + +static void /* PRIVATE */ +png_format_buffer(png_const_structrp png_ptr, png_charp buffer, + png_const_charp error_message) +{ + png_uint_32 chunk_name = png_ptr->chunk_name; + int iout = 0, ishift = 24; + + while (ishift >= 0) + { + int c = (int)(chunk_name >> ishift) & 0xff; + + ishift -= 8; + if (isnonalpha(c) != 0) + { + buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; + buffer[iout++] = png_digit[(c & 0xf0) >> 4]; + buffer[iout++] = png_digit[c & 0x0f]; + buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; + } + + else + { + buffer[iout++] = (char)c; + } + } + + if (error_message == NULL) + buffer[iout] = '\0'; + + else + { + int iin = 0; + + buffer[iout++] = ':'; + buffer[iout++] = ' '; + + while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') + buffer[iout++] = error_message[iin++]; + + /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ + buffer[iout] = '\0'; + } +} +#endif /* WARNINGS || ERROR_TEXT */ + +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_FUNCTION(void,PNGAPI +png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) + png_error(png_ptr, error_message); + + else + { + png_format_buffer(png_ptr, msg, error_message); + png_error(png_ptr, msg); + } +} +#endif /* READ && ERROR_TEXT */ + +#ifdef PNG_WARNINGS_SUPPORTED +void PNGAPI +png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) +{ + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) + png_warning(png_ptr, warning_message); + + else + { + png_format_buffer(png_ptr, msg, warning_message); + png_warning(png_ptr, msg); + } +} +#endif /* WARNINGS */ + +#ifdef PNG_READ_SUPPORTED +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_chunk_benign_error(png_const_structrp png_ptr, + png_const_charp error_message) +{ + if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) + png_chunk_warning(png_ptr, error_message); + + else + png_chunk_error(png_ptr, error_message); + +# ifndef PNG_ERROR_TEXT_SUPPORTED + PNG_UNUSED(error_message) +# endif +} +#endif +#endif /* READ */ + +void /* PRIVATE */ +png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) +{ +# ifndef PNG_WARNINGS_SUPPORTED + PNG_UNUSED(message) +# endif + + /* This is always supported, but for just read or just write it + * unconditionally does the right thing. + */ +# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) +# endif + +# ifdef PNG_READ_SUPPORTED + { + if (error < PNG_CHUNK_ERROR) + png_chunk_warning(png_ptr, message); + + else + png_chunk_benign_error(png_ptr, message); + } +# endif + +# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) + else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) +# endif + +# ifdef PNG_WRITE_SUPPORTED + { + if (error < PNG_CHUNK_WRITE_ERROR) + png_app_warning(png_ptr, message); + + else + png_app_error(png_ptr, message); + } +# endif +} + +#ifdef PNG_ERROR_TEXT_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_FUNCTION(void, +png_fixed_error,(png_const_structrp png_ptr, png_const_charp name), + PNG_NORETURN) +{ +# define fixed_message "fixed point overflow in " +# define fixed_message_ln ((sizeof fixed_message)-1) + unsigned int iin; + char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; + memcpy(msg, fixed_message, fixed_message_ln); + iin = 0; + if (name != NULL) + while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) + { + msg[fixed_message_ln + iin] = name[iin]; + ++iin; + } + msg[fixed_message_ln + iin] = 0; + png_error(png_ptr, msg); +} +#endif +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This API only exists if ANSI-C style error handling is used, + * otherwise it is necessary for png_default_error to be overridden. + */ +jmp_buf* PNGAPI +png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, + size_t jmp_buf_size) +{ + /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value + * and it must not change after that. Libpng doesn't care how big the + * buffer is, just that it doesn't change. + * + * If the buffer size is no *larger* than the size of jmp_buf when libpng is + * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 + * semantics that this call will not fail. If the size is larger, however, + * the buffer is allocated and this may fail, causing the function to return + * NULL. + */ + if (png_ptr == NULL) + return NULL; + + if (png_ptr->jmp_buf_ptr == NULL) + { + png_ptr->jmp_buf_size = 0; /* not allocated */ + + if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) + png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; + + else + { + png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, + png_malloc_warn(png_ptr, jmp_buf_size)); + + if (png_ptr->jmp_buf_ptr == NULL) + return NULL; /* new NULL return on OOM */ + + png_ptr->jmp_buf_size = jmp_buf_size; + } + } + + else /* Already allocated: check the size */ + { + size_t size = png_ptr->jmp_buf_size; + + if (size == 0) + { + size = (sizeof png_ptr->jmp_buf_local); + if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) + { + /* This is an internal error in libpng: somehow we have been left + * with a stack allocated jmp_buf when the application regained + * control. It's always possible to fix this up, but for the moment + * this is a png_error because that makes it easy to detect. + */ + png_error(png_ptr, "Libpng jmp_buf still allocated"); + /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ + } + } + + if (size != jmp_buf_size) + { + png_warning(png_ptr, "Application jmp_buf size changed"); + return NULL; /* caller will probably crash: no choice here */ + } + } + + /* Finally fill in the function, now we have a satisfactory buffer. It is + * valid to change the function on every call. + */ + png_ptr->longjmp_fn = longjmp_fn; + return png_ptr->jmp_buf_ptr; +} + +void /* PRIVATE */ +png_free_jmpbuf(png_structrp png_ptr) +{ + if (png_ptr != NULL) + { + jmp_buf *jb = png_ptr->jmp_buf_ptr; + + /* A size of 0 is used to indicate a local, stack, allocation of the + * pointer; used here and in png.c + */ + if (jb != NULL && png_ptr->jmp_buf_size > 0) + { + + /* This stuff is so that a failure to free the error control structure + * does not leave libpng in a state with no valid error handling: the + * free always succeeds, if there is an error it gets ignored. + */ + if (jb != &png_ptr->jmp_buf_local) + { + /* Make an internal, libpng, jmp_buf to return here */ + jmp_buf free_jmp_buf; + + if (!setjmp(free_jmp_buf)) + { + png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ + png_ptr->jmp_buf_size = 0; /* stack allocation */ + png_ptr->longjmp_fn = longjmp; + png_free(png_ptr, jb); /* Return to setjmp on error */ + } + } + } + + /* *Always* cancel everything out: */ + png_ptr->jmp_buf_size = 0; + png_ptr->jmp_buf_ptr = NULL; + png_ptr->longjmp_fn = 0; + } +} +#endif + +/* This is the default error handling function. Note that replacements for + * this function MUST NOT RETURN, or the program will likely crash. This + * function is used by default, or if the program supplies NULL for the + * error function pointer in png_set_error_fn(). + */ +static PNG_FUNCTION(void /* PRIVATE */, +png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), + PNG_NORETURN) +{ +#ifdef PNG_CONSOLE_IO_SUPPORTED + fprintf(stderr, "libpng error: %s", error_message ? error_message : + "undefined"); + fprintf(stderr, PNG_STRING_NEWLINE); +#else + PNG_UNUSED(error_message) /* Make compiler happy */ +#endif + png_longjmp(png_ptr, 1); +} + +PNG_FUNCTION(void,PNGAPI +png_longjmp,(png_const_structrp png_ptr, int val), + PNG_NORETURN) +{ +#ifdef PNG_SETJMP_SUPPORTED + if (png_ptr != NULL && png_ptr->longjmp_fn != NULL && + png_ptr->jmp_buf_ptr != NULL) + png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(val) +#endif + + /* If control reaches this point, png_longjmp() must not return. The only + * choice is to terminate the whole process (or maybe the thread); to do + * this the ANSI-C abort() function is used unless a different method is + * implemented by overriding the default configuration setting for + * PNG_ABORT(). + */ + PNG_ABORT(); +} + +#ifdef PNG_WARNINGS_SUPPORTED +/* This function is called when there is a warning, but the library thinks + * it can continue anyway. Replacement functions don't have to do anything + * here if you don't want them to. In the default configuration, png_ptr is + * not used, but it is passed in case it may be useful. + */ +static void /* PRIVATE */ +png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) +{ +#ifdef PNG_CONSOLE_IO_SUPPORTED + fprintf(stderr, "libpng warning: %s", warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); +#else + PNG_UNUSED(warning_message) /* Make compiler happy */ +#endif + PNG_UNUSED(png_ptr) /* Make compiler happy */ +} +#endif /* WARNINGS */ + +/* This function is called when the application wants to use another method + * of handling errors and warnings. Note that the error function MUST NOT + * return to the calling routine or serious problems will occur. The return + * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) + */ +void PNGAPI +png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->error_ptr = error_ptr; + png_ptr->error_fn = error_fn; +#ifdef PNG_WARNINGS_SUPPORTED + png_ptr->warning_fn = warning_fn; +#else + PNG_UNUSED(warning_fn) +#endif +} + + +/* This function returns a pointer to the error_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy and png_read_destroy are called. + */ +png_voidp PNGAPI +png_get_error_ptr(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return (png_voidp)png_ptr->error_ptr; +} + + +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +void PNGAPI +png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) +{ + PNG_UNUSED(png_ptr) + PNG_UNUSED(strip_mode) +} +#endif + +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) + /* Currently the above both depend on SETJMP_SUPPORTED, however it would be + * possible to implement without setjmp support just so long as there is some + * way to handle the error return here: + */ +PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI +png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), + PNG_NORETURN) +{ + png_const_structrp png_ptr = png_nonconst_ptr; + png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); + + /* An error is always logged here, overwriting anything (typically a warning) + * that is already there: + */ + if (image != NULL) + { + png_safecat(image->message, (sizeof image->message), 0, error_message); + image->warning_or_error |= PNG_IMAGE_ERROR; + + /* Retrieve the jmp_buf from within the png_control, making this work for + * C++ compilation too is pretty tricky: C++ wants a pointer to the first + * element of a jmp_buf, but C doesn't tell us the type of that. + */ + if (image->opaque != NULL && image->opaque->error_buf != NULL) + longjmp(png_control_jmp_buf(image->opaque), 1); + + /* Missing longjmp buffer, the following is to help debugging: */ + { + size_t pos = png_safecat(image->message, (sizeof image->message), 0, + "bad longjmp: "); + png_safecat(image->message, (sizeof image->message), pos, + error_message); + } + } + + /* Here on an internal programming error. */ + abort(); +} + +#ifdef PNG_WARNINGS_SUPPORTED +void /* PRIVATE */ PNGCBAPI +png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) +{ + png_const_structrp png_ptr = png_nonconst_ptr; + png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); + + /* A warning is only logged if there is no prior warning or error. */ + if (image->warning_or_error == 0) + { + png_safecat(image->message, (sizeof image->message), 0, warning_message); + image->warning_or_error |= PNG_IMAGE_WARNING; + } +} +#endif + +int /* PRIVATE */ +png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg) +{ + const png_voidp saved_error_buf = image->opaque->error_buf; + jmp_buf safe_jmpbuf; + + /* Safely execute function(arg), with png_error returning back here. */ + if (setjmp(safe_jmpbuf) == 0) + { + int result; + + image->opaque->error_buf = safe_jmpbuf; + result = function(arg); + image->opaque->error_buf = saved_error_buf; + + if (result) + return 1; /* success */ + } + + /* The function failed either because of a caught png_error and a regular + * return of false above or because of an uncaught png_error from the + * function itself. Ensure that the error_buf is always set back to the + * value saved above: + */ + image->opaque->error_buf = saved_error_buf; + + /* On the final false return, when about to return control to the caller, the + * image is freed (png_image_free does this check but it is duplicated here + * for clarity: + */ + if (saved_error_buf == NULL) + png_image_free(image); + + return 0; /* failure */ +} +#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ +#endif /* READ || WRITE */ diff --git a/thirdparty/libpng/upstream/pngget.c b/thirdparty/libpng/upstream/pngget.c index 7d2f0c045..9c7e8a12d 100644 --- a/thirdparty/libpng/upstream/pngget.c +++ b/thirdparty/libpng/upstream/pngget.c @@ -1,1267 +1,1369 @@ - -/* pngget.c - retrieval of values from info struct - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -png_uint_32 PNGAPI -png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 flag) -{ - if (png_ptr != NULL && info_ptr != NULL) - { -#ifdef PNG_READ_tRNS_SUPPORTED - /* png_handle_PLTE() may have canceled a valid tRNS chunk but left the - * 'valid' flag for the detection of duplicate chunks. Do not report a - * valid tRNS chunk in this case. - */ - if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0) - return 0; -#endif - - return info_ptr->valid & flag; - } - - return 0; -} - -size_t PNGAPI -png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->rowbytes; - - return 0; -} - -#ifdef PNG_INFO_IMAGE_SUPPORTED -png_bytepp PNGAPI -png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->row_pointers; - - return 0; -} -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Easy access to info, added in libpng-0.99 */ -png_uint_32 PNGAPI -png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->width; - - return 0; -} - -png_uint_32 PNGAPI -png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->height; - - return 0; -} - -png_byte PNGAPI -png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->bit_depth; - - return 0; -} - -png_byte PNGAPI -png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->color_type; - - return 0; -} - -png_byte PNGAPI -png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->filter_type; - - return 0; -} - -png_byte PNGAPI -png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->interlace_type; - - return 0; -} - -png_byte PNGAPI -png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->compression_type; - - return 0; -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - png_debug(1, "in png_get_x_pixels_per_meter"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return info_ptr->x_pixels_per_unit; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - png_debug(1, "in png_get_y_pixels_per_meter"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return info_ptr->y_pixels_per_unit; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -png_uint_32 PNGAPI -png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - png_debug(1, "in png_get_pixels_per_meter"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && - info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return info_ptr->x_pixels_per_unit; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - png_debug(1, "in png_get_pixel_aspect_ratio"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (info_ptr->x_pixels_per_unit != 0) - return (float)info_ptr->y_pixels_per_unit - / (float)info_ptr->x_pixels_per_unit; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (float)0.0; -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - png_debug(1, "in png_get_pixel_aspect_ratio_fixed"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0 && - info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && - info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && - info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) - { - png_fixed_point res; - - /* The following casts work because a PNG 4 byte integer only has a valid - * range of 0..2^31-1; otherwise the cast might overflow. - */ - if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, - (png_int_32)info_ptr->x_pixels_per_unit) != 0) - return res; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} -#endif - -png_int_32 PNGAPI -png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - png_debug(1, "in png_get_x_offset_microns"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return info_ptr->x_offset; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -png_int_32 PNGAPI -png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - png_debug(1, "in png_get_y_offset_microns"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return info_ptr->y_offset; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -png_int_32 PNGAPI -png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - png_debug(1, "in png_get_x_offset_pixels"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return info_ptr->x_offset; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -png_int_32 PNGAPI -png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - png_debug(1, "in png_get_y_offset_pixels"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return info_ptr->y_offset; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} - -#ifdef PNG_INCH_CONVERSIONS_SUPPORTED -static png_uint_32 -ppi_from_ppm(png_uint_32 ppm) -{ -#if 0 - /* The conversion is *(2.54/100), in binary (32 digits): - * .00000110100000001001110101001001 - */ - png_uint_32 t1001, t1101; - ppm >>= 1; /* .1 */ - t1001 = ppm + (ppm >> 3); /* .1001 */ - t1101 = t1001 + (ppm >> 1); /* .1101 */ - ppm >>= 20; /* .000000000000000000001 */ - t1101 += t1101 >> 15; /* .1101000000000001101 */ - t1001 >>= 11; /* .000000000001001 */ - t1001 += t1001 >> 12; /* .000000000001001000000001001 */ - ppm += t1001; /* .000000000001001000001001001 */ - ppm += t1101; /* .110100000001001110101001001 */ - return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ -#else - /* The argument is a PNG unsigned integer, so it is not permitted - * to be bigger than 2^31. - */ - png_fixed_point result; - if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, - 5000) != 0) - return (png_uint_32)result; - - /* Overflow. */ - return 0; -#endif -} - -png_uint_32 PNGAPI -png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); -} - -#ifdef PNG_FIXED_POINT_SUPPORTED -static png_fixed_point -png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) -{ - /* Convert from meters * 1,000,000 to inches * 100,000, meters to - * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. - * Notice that this can overflow - a warning is output and 0 is - * returned. - */ - return png_muldiv_warn(png_ptr, microns, 500, 127); -} - -png_fixed_point PNGAPI -png_get_x_offset_inches_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_x_offset_microns(png_ptr, info_ptr)); -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_y_offset_inches_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_y_offset_microns(png_ptr, info_ptr)); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - - if (*unit_type == 1) - { - if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); - if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); - } - } - } - - return retval; -} -#endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ - -/* png_get_channels really belongs in here, too, but it's been around longer */ - -#endif /* EASY_ACCESS */ - - -png_byte PNGAPI -png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->channels; - - return 0; -} - -#ifdef PNG_READ_SUPPORTED -png_const_bytep PNGAPI -png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->signature; - - return NULL; -} -#endif - -#ifdef PNG_bKGD_SUPPORTED -png_uint_32 PNGAPI -png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_16p *background) -{ - png_debug1(1, "in %s retrieval function", "bKGD"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_bKGD) != 0 && - background != NULL) - { - *background = &(info_ptr->background); - return PNG_INFO_bKGD; - } - - return 0; -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the - * same time to correct the rgb grayscale coefficient defaults obtained from the - * cHRM chunk in 1.5.4 - */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *white_x, double *white_y, double *red_x, double *red_y, - double *green_x, double *green_y, double *blue_x, double *blue_y) -{ - png_debug1(1, "in %s retrieval function", "cHRM"); - - /* Quiet API change: this code used to only return the end points if a cHRM - * chunk was present, but the end points can also come from iCCP or sRGB - * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and - * the png_set_ APIs merely check that set end points are mutually - * consistent. - */ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (white_x != NULL) - *white_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); - if (white_y != NULL) - *white_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); - if (red_x != NULL) - *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, - "cHRM red X"); - if (red_y != NULL) - *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, - "cHRM red Y"); - if (green_x != NULL) - *green_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); - if (green_y != NULL) - *green_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); - if (blue_x != NULL) - *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, - "cHRM blue X"); - if (blue_y != NULL) - *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, - "cHRM blue Y"); - return PNG_INFO_cHRM; - } - - return 0; -} - -png_uint_32 PNGAPI -png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *red_X, double *red_Y, double *red_Z, double *green_X, - double *green_Y, double *green_Z, double *blue_X, double *blue_Y, - double *blue_Z) -{ - png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (red_X != NULL) - *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, - "cHRM red X"); - if (red_Y != NULL) - *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, - "cHRM red Y"); - if (red_Z != NULL) - *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, - "cHRM red Z"); - if (green_X != NULL) - *green_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); - if (green_Y != NULL) - *green_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); - if (green_Z != NULL) - *green_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); - if (blue_X != NULL) - *blue_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); - if (blue_Y != NULL) - *blue_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); - if (blue_Z != NULL) - *blue_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return PNG_INFO_cHRM; - } - - return 0; -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z) -{ - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (int_red_X != NULL) - *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; - if (int_red_Y != NULL) - *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; - if (int_red_Z != NULL) - *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; - if (int_green_X != NULL) - *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; - if (int_green_Y != NULL) - *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; - if (int_green_Z != NULL) - *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; - if (int_blue_X != NULL) - *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; - if (int_blue_Y != NULL) - *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; - if (int_blue_Z != NULL) - *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; - return PNG_INFO_cHRM; - } - - return 0; -} - -png_uint_32 PNGAPI -png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) -{ - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (white_x != NULL) - *white_x = info_ptr->colorspace.end_points_xy.whitex; - if (white_y != NULL) - *white_y = info_ptr->colorspace.end_points_xy.whitey; - if (red_x != NULL) - *red_x = info_ptr->colorspace.end_points_xy.redx; - if (red_y != NULL) - *red_y = info_ptr->colorspace.end_points_xy.redy; - if (green_x != NULL) - *green_x = info_ptr->colorspace.end_points_xy.greenx; - if (green_y != NULL) - *green_y = info_ptr->colorspace.end_points_xy.greeny; - if (blue_x != NULL) - *blue_x = info_ptr->colorspace.end_points_xy.bluex; - if (blue_y != NULL) - *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return PNG_INFO_cHRM; - } - - return 0; -} -# endif -#endif - -#ifdef PNG_gAMA_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) - { - *file_gamma = info_ptr->colorspace.gamma; - return PNG_INFO_gAMA; - } - - return 0; -} -# endif - -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA(float)"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) - { - *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, - "png_get_gAMA"); - return PNG_INFO_gAMA; - } - - return 0; -} -# endif -#endif - -#ifdef PNG_sRGB_SUPPORTED -png_uint_32 PNGAPI -png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *file_srgb_intent) -{ - png_debug1(1, "in %s retrieval function", "sRGB"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) - { - *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return PNG_INFO_sRGB; - } - - return 0; -} -#endif - -#ifdef PNG_iCCP_SUPPORTED -png_uint_32 PNGAPI -png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen) -{ - png_debug1(1, "in %s retrieval function", "iCCP"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_iCCP) != 0 && - name != NULL && profile != NULL && proflen != NULL) - { - *name = info_ptr->iccp_name; - *profile = info_ptr->iccp_profile; - *proflen = png_get_uint_32(info_ptr->iccp_profile); - /* This is somewhat irrelevant since the profile data returned has - * actually been uncompressed. - */ - if (compression_type != NULL) - *compression_type = PNG_COMPRESSION_TYPE_BASE; - return PNG_INFO_iCCP; - } - - return 0; - -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -int PNGAPI -png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, - png_sPLT_tpp spalettes) -{ - png_debug1(1, "in %s retrieval function", "sPLT"); - - if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) - { - *spalettes = info_ptr->splt_palettes; - return info_ptr->splt_palettes_num; - } - - return 0; -} -#endif - -#ifdef PNG_eXIf_SUPPORTED -png_uint_32 PNGAPI -png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep *exif) -{ - png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1"); - PNG_UNUSED(info_ptr) - PNG_UNUSED(exif) - return 0; -} - -png_uint_32 PNGAPI -png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *num_exif, png_bytep *exif) -{ - png_debug1(1, "in %s retrieval function", "eXIf"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL) - { - *num_exif = info_ptr->num_exif; - *exif = info_ptr->exif; - return PNG_INFO_eXIf; - } - - return 0; -} -#endif - -#ifdef PNG_hIST_SUPPORTED -png_uint_32 PNGAPI -png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_16p *hist) -{ - png_debug1(1, "in %s retrieval function", "hIST"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) - { - *hist = info_ptr->hist; - return PNG_INFO_hIST; - } - - return 0; -} -#endif - -png_uint_32 PNGAPI -png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, - int *color_type, int *interlace_type, int *compression_type, - int *filter_type) -{ - png_debug1(1, "in %s retrieval function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return 0; - - if (width != NULL) - *width = info_ptr->width; - - if (height != NULL) - *height = info_ptr->height; - - if (bit_depth != NULL) - *bit_depth = info_ptr->bit_depth; - - if (color_type != NULL) - *color_type = info_ptr->color_type; - - if (compression_type != NULL) - *compression_type = info_ptr->compression_type; - - if (filter_type != NULL) - *filter_type = info_ptr->filter_type; - - if (interlace_type != NULL) - *interlace_type = info_ptr->interlace_type; - - /* This is redundant if we can be sure that the info_ptr values were all - * assigned in png_set_IHDR(). We do the check anyhow in case an - * application has ignored our advice not to mess with the members - * of info_ptr directly. - */ - png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - - return 1; -} - -#ifdef PNG_oFFs_SUPPORTED -png_uint_32 PNGAPI -png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) -{ - png_debug1(1, "in %s retrieval function", "oFFs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0 && - offset_x != NULL && offset_y != NULL && unit_type != NULL) - { - *offset_x = info_ptr->x_offset; - *offset_y = info_ptr->y_offset; - *unit_type = (int)info_ptr->offset_unit_type; - return PNG_INFO_oFFs; - } - - return 0; -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -png_uint_32 PNGAPI -png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, - png_charp *units, png_charpp *params) -{ - png_debug1(1, "in %s retrieval function", "pCAL"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pCAL) != 0 && - purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && - nparams != NULL && units != NULL && params != NULL) - { - *purpose = info_ptr->pcal_purpose; - *X0 = info_ptr->pcal_X0; - *X1 = info_ptr->pcal_X1; - *type = (int)info_ptr->pcal_type; - *nparams = (int)info_ptr->pcal_nparams; - *units = info_ptr->pcal_units; - *params = info_ptr->pcal_params; - return PNG_INFO_pCAL; - } - - return 0; -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ - defined(PNG_FLOATING_POINT_SUPPORTED) -png_uint_32 PNGAPI -png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_fixed_point *width, png_fixed_point *height) -{ - png_debug1(1, "in %s retrieval function", "sCAL"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - /*TODO: make this work without FP support; the API is currently eliminated - * if neither floating point APIs nor internal floating point arithmetic - * are enabled. - */ - *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); - *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), - "sCAL height"); - return PNG_INFO_sCAL; - } - - return 0; -} -# endif /* FLOATING_ARITHMETIC */ -# endif /* FIXED_POINT */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, double *width, double *height) -{ - png_debug1(1, "in %s retrieval function", "sCAL(float)"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = atof(info_ptr->scal_s_width); - *height = atof(info_ptr->scal_s_height); - return PNG_INFO_sCAL; - } - - return 0; -} -# endif /* FLOATING POINT */ -png_uint_32 PNGAPI -png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_charpp width, png_charpp height) -{ - png_debug1(1, "in %s retrieval function", "sCAL(str)"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = info_ptr->scal_s_width; - *height = info_ptr->scal_s_height; - return PNG_INFO_sCAL; - } - - return 0; -} -#endif /* sCAL */ - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - } - } - - return retval; -} -#endif /* pHYs */ - -png_uint_32 PNGAPI -png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, - png_colorp *palette, int *num_palette) -{ - png_debug1(1, "in %s retrieval function", "PLTE"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL) - { - *palette = info_ptr->palette; - *num_palette = info_ptr->num_palette; - png_debug1(3, "num_palette = %d", *num_palette); - return PNG_INFO_PLTE; - } - - return 0; -} - -#ifdef PNG_sBIT_SUPPORTED -png_uint_32 PNGAPI -png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_8p *sig_bit) -{ - png_debug1(1, "in %s retrieval function", "sBIT"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) - { - *sig_bit = &(info_ptr->sig_bit); - return PNG_INFO_sBIT; - } - - return 0; -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -int PNGAPI -png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, - png_textp *text_ptr, int *num_text) -{ - if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) - { - png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx", - (unsigned long)png_ptr->chunk_name); - - if (text_ptr != NULL) - *text_ptr = info_ptr->text; - - if (num_text != NULL) - *num_text = info_ptr->num_text; - - return info_ptr->num_text; - } - - if (num_text != NULL) - *num_text = 0; - - return 0; -} -#endif - -#ifdef PNG_tIME_SUPPORTED -png_uint_32 PNGAPI -png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, - png_timep *mod_time) -{ - png_debug1(1, "in %s retrieval function", "tIME"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) - { - *mod_time = &(info_ptr->mod_time); - return PNG_INFO_tIME; - } - - return 0; -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -png_uint_32 PNGAPI -png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) -{ - png_uint_32 retval = 0; - - png_debug1(1, "in %s retrieval function", "tRNS"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (trans_alpha != NULL) - { - *trans_alpha = info_ptr->trans_alpha; - retval |= PNG_INFO_tRNS; - } - - if (trans_color != NULL) - *trans_color = &(info_ptr->trans_color); - } - - else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ - { - if (trans_color != NULL) - { - *trans_color = &(info_ptr->trans_color); - retval |= PNG_INFO_tRNS; - } - - if (trans_alpha != NULL) - *trans_alpha = NULL; - } - - if (num_trans != NULL) - { - *num_trans = info_ptr->num_trans; - retval |= PNG_INFO_tRNS; - } - } - - return retval; -} -#endif - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, - png_unknown_chunkpp unknowns) -{ - if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) - { - *unknowns = info_ptr->unknown_chunks; - return info_ptr->unknown_chunks_num; - } - - return 0; -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -png_byte PNGAPI -png_get_rgb_to_gray_status(png_const_structrp png_ptr) -{ - return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); -} -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -png_voidp PNGAPI -png_get_user_chunk_ptr(png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_ptr : NULL); -} -#endif - -size_t PNGAPI -png_get_compression_buffer_size(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return 0; - -#ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -#endif - { -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - return png_ptr->IDAT_read_size; -#else - return PNG_IDAT_READ_SIZE; -#endif - } - -#ifdef PNG_WRITE_SUPPORTED - else - return png_ptr->zbuffer_size; -#endif -} - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* These functions were added to libpng 1.2.6 and were enabled - * by default in libpng-1.4.0 */ -png_uint_32 PNGAPI -png_get_user_width_max(png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_width_max : 0); -} - -png_uint_32 PNGAPI -png_get_user_height_max(png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_height_max : 0); -} - -/* This function was added to libpng 1.4.0 */ -png_uint_32 PNGAPI -png_get_chunk_cache_max(png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_cache_max : 0); -} - -/* This function was added to libpng 1.4.1 */ -png_alloc_size_t PNGAPI -png_get_chunk_malloc_max(png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); -} -#endif /* SET_USER_LIMITS */ - -/* These functions were added to libpng 1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -png_uint_32 PNGAPI -png_get_io_state(png_const_structrp png_ptr) -{ - return png_ptr->io_state; -} - -png_uint_32 PNGAPI -png_get_io_chunk_type(png_const_structrp png_ptr) -{ - return png_ptr->chunk_name; -} -#endif /* IO_STATE */ - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -int PNGAPI -png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return png_ptr->num_palette_max; - - return -1; -} -# endif -#endif - -#endif /* READ || WRITE */ +/* pngget.c - retrieval of values from info struct + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +png_uint_32 PNGAPI +png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 flag) +{ + if (png_ptr != NULL && info_ptr != NULL) + { +#ifdef PNG_READ_tRNS_SUPPORTED + /* png_handle_PLTE() may have canceled a valid tRNS chunk but left the + * 'valid' flag for the detection of duplicate chunks. Do not report a + * valid tRNS chunk in this case. + */ + if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0) + return 0; +#endif + + return info_ptr->valid & flag; + } + + return 0; +} + +size_t PNGAPI +png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->rowbytes; + + return 0; +} + +#ifdef PNG_INFO_IMAGE_SUPPORTED +png_bytepp PNGAPI +png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->row_pointers; + + return 0; +} +#endif + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Easy access to info, added in libpng-0.99 */ +png_uint_32 PNGAPI +png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->width; + + return 0; +} + +png_uint_32 PNGAPI +png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->height; + + return 0; +} + +png_byte PNGAPI +png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->bit_depth; + + return 0; +} + +png_byte PNGAPI +png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->color_type; + + return 0; +} + +png_byte PNGAPI +png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->filter_type; + + return 0; +} + +png_byte PNGAPI +png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->interlace_type; + + return 0; +} + +png_byte PNGAPI +png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->compression_type; + + return 0; +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_meter(png_const_structrp png_ptr, + png_const_inforp info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_x_pixels_per_meter"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return info_ptr->x_pixels_per_unit; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_meter(png_const_structrp png_ptr, + png_const_inforp info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_y_pixels_per_meter"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return info_ptr->y_pixels_per_unit; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +png_uint_32 PNGAPI +png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ +#ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_pixels_per_meter"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && + info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) + return info_ptr->x_pixels_per_unit; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_pixel_aspect_ratio(png_const_structrp png_ptr, + png_const_inforp info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (info_ptr->x_pixels_per_unit != 0) + return (float)info_ptr->y_pixels_per_unit + / (float)info_ptr->x_pixels_per_unit; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return (float)0.0; +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, + png_const_inforp info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio_fixed"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0 && + info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && + info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && + info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) + { + png_fixed_point res; + + /* The following casts work because a PNG 4 byte integer only has a valid + * range of 0..2^31-1; otherwise the cast might overflow. + */ + if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, + (png_int_32)info_ptr->x_pixels_per_unit) != 0) + return res; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} +#endif + +png_int_32 PNGAPI +png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_microns"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return info_ptr->x_offset; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +png_int_32 PNGAPI +png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_microns"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return info_ptr->y_offset; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +png_int_32 PNGAPI +png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_pixels"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return info_ptr->x_offset; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +png_int_32 PNGAPI +png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ +#ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_pixels"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_oFFs) != 0) + { + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return info_ptr->y_offset; + } +#else + PNG_UNUSED(png_ptr) + PNG_UNUSED(info_ptr) +#endif + + return 0; +} + +#ifdef PNG_INCH_CONVERSIONS_SUPPORTED +static png_uint_32 +ppi_from_ppm(png_uint_32 ppm) +{ +#if 0 + /* The conversion is *(2.54/100), in binary (32 digits): + * .00000110100000001001110101001001 + */ + png_uint_32 t1001, t1101; + ppm >>= 1; /* .1 */ + t1001 = ppm + (ppm >> 3); /* .1001 */ + t1101 = t1001 + (ppm >> 1); /* .1101 */ + ppm >>= 20; /* .000000000000000000001 */ + t1101 += t1101 >> 15; /* .1101000000000001101 */ + t1001 >>= 11; /* .000000000001001 */ + t1001 += t1001 >> 12; /* .000000000001001000000001001 */ + ppm += t1001; /* .000000000001001000001001001 */ + ppm += t1101; /* .110100000001001110101001001 */ + return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ +#else + /* The argument is a PNG unsigned integer, so it is not permitted + * to be bigger than 2^31. + */ + png_fixed_point result; + if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, + 5000) != 0) + return (png_uint_32)result; + + /* Overflow. */ + return 0; +#endif +} + +png_uint_32 PNGAPI +png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); +} + +png_uint_32 PNGAPI +png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); +} + +png_uint_32 PNGAPI +png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); +} + +#ifdef PNG_FIXED_POINT_SUPPORTED +static png_fixed_point +png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) +{ + /* Convert from meters * 1,000,000 to inches * 100,000, meters to + * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. + * Notice that this can overflow - a warning is output and 0 is + * returned. + */ + png_fixed_point result; + + if (png_muldiv(&result, microns, 500, 127) != 0) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); + return 0; +} + +png_fixed_point PNGAPI +png_get_x_offset_inches_fixed(png_const_structrp png_ptr, + png_const_inforp info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_x_offset_microns(png_ptr, info_ptr)); +} +#endif /* FIXED_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_y_offset_inches_fixed(png_const_structrp png_ptr, + png_const_inforp info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_y_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +float PNGAPI +png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); +} +#endif + +#ifdef PNG_pHYs_SUPPORTED +png_uint_32 PNGAPI +png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "pHYs"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + + if (*unit_type == 1) + { + if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); + if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); + } + } + } + + return retval; +} +#endif /* pHYs */ +#endif /* INCH_CONVERSIONS */ + +/* png_get_channels really belongs in here, too, but it's been around longer */ + +#endif /* EASY_ACCESS */ + + +png_byte PNGAPI +png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->channels; + + return 0; +} + +#ifdef PNG_READ_SUPPORTED +png_const_bytep PNGAPI +png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return info_ptr->signature; + + return NULL; +} +#endif + +#ifdef PNG_bKGD_SUPPORTED +png_uint_32 PNGAPI +png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, + png_color_16p *background) +{ + png_debug1(1, "in %s retrieval function", "bKGD"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_bKGD) != 0 && + background != NULL) + { + *background = &(info_ptr->background); + return PNG_INFO_bKGD; + } + + return 0; +} +#endif + +#ifdef PNG_cHRM_SUPPORTED +/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the + * same time to correct the rgb grayscale coefficient defaults obtained from the + * cHRM chunk in 1.5.4 + */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *whitex, double *whitey, double *redx, double *redy, + double *greenx, double *greeny, double *bluex, double *bluey) +{ + png_debug1(1, "in %s retrieval function", "cHRM"); + + /* PNGv3: this just returns the values store from the cHRM, if any. */ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cHRM) != 0) + { + if (whitex != NULL) + *whitex = png_float(png_ptr, info_ptr->cHRM.whitex, "cHRM wx"); + if (whitey != NULL) + *whitey = png_float(png_ptr, info_ptr->cHRM.whitey, "cHRM wy"); + if (redx != NULL) + *redx = png_float(png_ptr, info_ptr->cHRM.redx, "cHRM rx"); + if (redy != NULL) + *redy = png_float(png_ptr, info_ptr->cHRM.redy, "cHRM ry"); + if (greenx != NULL) + *greenx = png_float(png_ptr, info_ptr->cHRM.greenx, "cHRM gx"); + if (greeny != NULL) + *greeny = png_float(png_ptr, info_ptr->cHRM.greeny, "cHRM gy"); + if (bluex != NULL) + *bluex = png_float(png_ptr, info_ptr->cHRM.bluex, "cHRM bx"); + if (bluey != NULL) + *bluey = png_float(png_ptr, info_ptr->cHRM.bluey, "cHRM by"); + return PNG_INFO_cHRM; + } + + return 0; +} + +png_uint_32 PNGAPI +png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *red_X, double *red_Y, double *red_Z, double *green_X, + double *green_Y, double *green_Z, double *blue_X, double *blue_Y, + double *blue_Z) +{ + png_XYZ XYZ; + png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cHRM) != 0 && + png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0) + { + if (red_X != NULL) + *red_X = png_float(png_ptr, XYZ.red_X, "cHRM red X"); + if (red_Y != NULL) + *red_Y = png_float(png_ptr, XYZ.red_Y, "cHRM red Y"); + if (red_Z != NULL) + *red_Z = png_float(png_ptr, XYZ.red_Z, "cHRM red Z"); + if (green_X != NULL) + *green_X = png_float(png_ptr, XYZ.green_X, "cHRM green X"); + if (green_Y != NULL) + *green_Y = png_float(png_ptr, XYZ.green_Y, "cHRM green Y"); + if (green_Z != NULL) + *green_Z = png_float(png_ptr, XYZ.green_Z, "cHRM green Z"); + if (blue_X != NULL) + *blue_X = png_float(png_ptr, XYZ.blue_X, "cHRM blue X"); + if (blue_Y != NULL) + *blue_Y = png_float(png_ptr, XYZ.blue_Y, "cHRM blue Y"); + if (blue_Z != NULL) + *blue_Z = png_float(png_ptr, XYZ.blue_Z, "cHRM blue Z"); + return PNG_INFO_cHRM; + } + + return 0; +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *int_red_X, png_fixed_point *int_red_Y, + png_fixed_point *int_red_Z, png_fixed_point *int_green_X, + png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, + png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, + png_fixed_point *int_blue_Z) +{ + png_XYZ XYZ; + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cHRM) != 0U && + png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0) + { + if (int_red_X != NULL) *int_red_X = XYZ.red_X; + if (int_red_Y != NULL) *int_red_Y = XYZ.red_Y; + if (int_red_Z != NULL) *int_red_Z = XYZ.red_Z; + if (int_green_X != NULL) *int_green_X = XYZ.green_X; + if (int_green_Y != NULL) *int_green_Y = XYZ.green_Y; + if (int_green_Z != NULL) *int_green_Z = XYZ.green_Z; + if (int_blue_X != NULL) *int_blue_X = XYZ.blue_X; + if (int_blue_Y != NULL) *int_blue_Y = XYZ.blue_Y; + if (int_blue_Z != NULL) *int_blue_Z = XYZ.blue_Z; + return PNG_INFO_cHRM; + } + + return 0; +} + +png_uint_32 PNGAPI +png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *whitex, png_fixed_point *whitey, png_fixed_point *redx, + png_fixed_point *redy, png_fixed_point *greenx, png_fixed_point *greeny, + png_fixed_point *bluex, png_fixed_point *bluey) +{ + png_debug1(1, "in %s retrieval function", "cHRM"); + + /* PNGv3: this just returns the values store from the cHRM, if any. */ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cHRM) != 0) + { + if (whitex != NULL) *whitex = info_ptr->cHRM.whitex; + if (whitey != NULL) *whitey = info_ptr->cHRM.whitey; + if (redx != NULL) *redx = info_ptr->cHRM.redx; + if (redy != NULL) *redy = info_ptr->cHRM.redy; + if (greenx != NULL) *greenx = info_ptr->cHRM.greenx; + if (greeny != NULL) *greeny = info_ptr->cHRM.greeny; + if (bluex != NULL) *bluex = info_ptr->cHRM.bluex; + if (bluey != NULL) *bluey = info_ptr->cHRM.bluey; + return PNG_INFO_cHRM; + } + + return 0; +} +# endif +#endif + +#ifdef PNG_gAMA_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA"); + + /* PNGv3 compatibility: only report gAMA if it is really present. */ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_gAMA) != 0) + { + if (file_gamma != NULL) *file_gamma = info_ptr->gamma; + return PNG_INFO_gAMA; + } + + return 0; +} +# endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA(float)"); + + /* PNGv3 compatibility: only report gAMA if it is really present. */ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_gAMA) != 0) + { + if (file_gamma != NULL) + *file_gamma = png_float(png_ptr, info_ptr->gamma, "gAMA"); + + return PNG_INFO_gAMA; + } + + return 0; +} +# endif +#endif + +#ifdef PNG_sRGB_SUPPORTED +png_uint_32 PNGAPI +png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *file_srgb_intent) +{ + png_debug1(1, "in %s retrieval function", "sRGB"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sRGB) != 0) + { + if (file_srgb_intent != NULL) + *file_srgb_intent = info_ptr->rendering_intent; + return PNG_INFO_sRGB; + } + + return 0; +} +#endif + +#ifdef PNG_iCCP_SUPPORTED +png_uint_32 PNGAPI +png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, + png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen) +{ + png_debug1(1, "in %s retrieval function", "iCCP"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_iCCP) != 0 && + name != NULL && profile != NULL && proflen != NULL) + { + *name = info_ptr->iccp_name; + *profile = info_ptr->iccp_profile; + *proflen = png_get_uint_32(info_ptr->iccp_profile); + /* This is somewhat irrelevant since the profile data returned has + * actually been uncompressed. + */ + if (compression_type != NULL) + *compression_type = PNG_COMPRESSION_TYPE_BASE; + return PNG_INFO_iCCP; + } + + return 0; +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +int PNGAPI +png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, + png_sPLT_tpp spalettes) +{ + png_debug1(1, "in %s retrieval function", "sPLT"); + + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + { + *spalettes = info_ptr->splt_palettes; + return info_ptr->splt_palettes_num; + } + + return 0; +} +#endif + +#ifdef PNG_cICP_SUPPORTED +png_uint_32 PNGAPI +png_get_cICP(png_const_structrp png_ptr, + png_const_inforp info_ptr, png_bytep colour_primaries, + png_bytep transfer_function, png_bytep matrix_coefficients, + png_bytep video_full_range_flag) +{ + png_debug1(1, "in %s retrieval function", "cICP"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cICP) != 0 && + colour_primaries != NULL && transfer_function != NULL && + matrix_coefficients != NULL && video_full_range_flag != NULL) + { + *colour_primaries = info_ptr->cicp_colour_primaries; + *transfer_function = info_ptr->cicp_transfer_function; + *matrix_coefficients = info_ptr->cicp_matrix_coefficients; + *video_full_range_flag = info_ptr->cicp_video_full_range_flag; + return (PNG_INFO_cICP); + } + + return 0; +} +#endif + +#ifdef PNG_cLLI_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cLLI_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32p maxCLL, + png_uint_32p maxFALL) +{ + png_debug1(1, "in %s retrieval function", "cLLI"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cLLI) != 0) + { + if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL; + if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL; + return PNG_INFO_cLLI; + } + + return 0; +} +# endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_cLLI(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *maxCLL, double *maxFALL) +{ + png_debug1(1, "in %s retrieval function", "cLLI(float)"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_cLLI) != 0) + { + if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL * .0001; + if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL * .0001; + return PNG_INFO_cLLI; + } + + return 0; +} +# endif +#endif /* cLLI */ + +#ifdef PNG_mDCV_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_mDCV_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_fixed_point *white_x, png_fixed_point *white_y, + png_fixed_point *red_x, png_fixed_point *red_y, + png_fixed_point *green_x, png_fixed_point *green_y, + png_fixed_point *blue_x, png_fixed_point *blue_y, + png_uint_32p mastering_maxDL, png_uint_32p mastering_minDL) +{ + png_debug1(1, "in %s retrieval function", "mDCV"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_mDCV) != 0) + { + if (white_x != NULL) *white_x = info_ptr->mastering_white_x * 2; + if (white_y != NULL) *white_y = info_ptr->mastering_white_y * 2; + if (red_x != NULL) *red_x = info_ptr->mastering_red_x * 2; + if (red_y != NULL) *red_y = info_ptr->mastering_red_y * 2; + if (green_x != NULL) *green_x = info_ptr->mastering_green_x * 2; + if (green_y != NULL) *green_y = info_ptr->mastering_green_y * 2; + if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * 2; + if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * 2; + if (mastering_maxDL != NULL) *mastering_maxDL = info_ptr->mastering_maxDL; + if (mastering_minDL != NULL) *mastering_minDL = info_ptr->mastering_minDL; + return PNG_INFO_mDCV; + } + + return 0; +} +# endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_mDCV(png_const_structrp png_ptr, png_const_inforp info_ptr, + double *white_x, double *white_y, double *red_x, double *red_y, + double *green_x, double *green_y, double *blue_x, double *blue_y, + double *mastering_maxDL, double *mastering_minDL) +{ + png_debug1(1, "in %s retrieval function", "mDCV(float)"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_mDCV) != 0) + { + if (white_x != NULL) *white_x = info_ptr->mastering_white_x * .00002; + if (white_y != NULL) *white_y = info_ptr->mastering_white_y * .00002; + if (red_x != NULL) *red_x = info_ptr->mastering_red_x * .00002; + if (red_y != NULL) *red_y = info_ptr->mastering_red_y * .00002; + if (green_x != NULL) *green_x = info_ptr->mastering_green_x * .00002; + if (green_y != NULL) *green_y = info_ptr->mastering_green_y * .00002; + if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * .00002; + if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * .00002; + if (mastering_maxDL != NULL) + *mastering_maxDL = info_ptr->mastering_maxDL * .0001; + if (mastering_minDL != NULL) + *mastering_minDL = info_ptr->mastering_minDL * .0001; + return PNG_INFO_mDCV; + } + + return 0; +} +# endif /* FLOATING_POINT */ +#endif /* mDCV */ + +#ifdef PNG_eXIf_SUPPORTED +png_uint_32 PNGAPI +png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytep *exif) +{ + png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1"); + PNG_UNUSED(info_ptr) + PNG_UNUSED(exif) + return 0; +} + +png_uint_32 PNGAPI +png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *num_exif, png_bytep *exif) +{ + png_debug1(1, "in %s retrieval function", "eXIf"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL) + { + *num_exif = info_ptr->num_exif; + *exif = info_ptr->exif; + return PNG_INFO_eXIf; + } + + return 0; +} +#endif + +#ifdef PNG_hIST_SUPPORTED +png_uint_32 PNGAPI +png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_16p *hist) +{ + png_debug1(1, "in %s retrieval function", "hIST"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) + { + *hist = info_ptr->hist; + return PNG_INFO_hIST; + } + + return 0; +} +#endif + +png_uint_32 PNGAPI +png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, + int *color_type, int *interlace_type, int *compression_type, + int *filter_type) +{ + png_debug1(1, "in %s retrieval function", "IHDR"); + + if (png_ptr == NULL || info_ptr == NULL) + return 0; + + if (width != NULL) + *width = info_ptr->width; + + if (height != NULL) + *height = info_ptr->height; + + if (bit_depth != NULL) + *bit_depth = info_ptr->bit_depth; + + if (color_type != NULL) + *color_type = info_ptr->color_type; + + if (compression_type != NULL) + *compression_type = info_ptr->compression_type; + + if (filter_type != NULL) + *filter_type = info_ptr->filter_type; + + if (interlace_type != NULL) + *interlace_type = info_ptr->interlace_type; + + /* This is redundant if we can be sure that the info_ptr values were all + * assigned in png_set_IHDR(). We do the check anyhow in case an + * application has ignored our advice not to mess with the members + * of info_ptr directly. + */ + png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_type); + + return 1; +} + +#ifdef PNG_oFFs_SUPPORTED +png_uint_32 PNGAPI +png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) +{ + png_debug1(1, "in %s retrieval function", "oFFs"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_oFFs) != 0 && + offset_x != NULL && offset_y != NULL && unit_type != NULL) + { + *offset_x = info_ptr->x_offset; + *offset_y = info_ptr->y_offset; + *unit_type = (int)info_ptr->offset_unit_type; + return PNG_INFO_oFFs; + } + + return 0; +} +#endif + +#ifdef PNG_pCAL_SUPPORTED +png_uint_32 PNGAPI +png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params) +{ + png_debug1(1, "in %s retrieval function", "pCAL"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pCAL) != 0 && + purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && + nparams != NULL && units != NULL && params != NULL) + { + *purpose = info_ptr->pcal_purpose; + *X0 = info_ptr->pcal_X0; + *X1 = info_ptr->pcal_X1; + *type = (int)info_ptr->pcal_type; + *nparams = (int)info_ptr->pcal_nparams; + *units = info_ptr->pcal_units; + *params = info_ptr->pcal_params; + return PNG_INFO_pCAL; + } + + return 0; +} +#endif + +#ifdef PNG_sCAL_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ + defined(PNG_FLOATING_POINT_SUPPORTED) +png_uint_32 PNGAPI +png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height) +{ + png_debug1(1, "in %s retrieval function", "sCAL"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL) != 0) + { + *unit = info_ptr->scal_unit; + /*TODO: make this work without FP support; the API is currently eliminated + * if neither floating point APIs nor internal floating point arithmetic + * are enabled. + */ + *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); + *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), + "sCAL height"); + return PNG_INFO_sCAL; + } + + return 0; +} +# endif /* FLOATING_ARITHMETIC */ +# endif /* FIXED_POINT */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, double *width, double *height) +{ + png_debug1(1, "in %s retrieval function", "sCAL(float)"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL) != 0) + { + *unit = info_ptr->scal_unit; + *width = atof(info_ptr->scal_s_width); + *height = atof(info_ptr->scal_s_height); + return PNG_INFO_sCAL; + } + + return 0; +} +# endif /* FLOATING POINT */ +png_uint_32 PNGAPI +png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, + int *unit, png_charpp width, png_charpp height) +{ + png_debug1(1, "in %s retrieval function", "sCAL(str)"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL) != 0) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_s_width; + *height = info_ptr->scal_s_height; + return PNG_INFO_sCAL; + } + + return 0; +} +#endif /* sCAL */ + +#ifdef PNG_pHYs_SUPPORTED +png_uint_32 PNGAPI +png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) +{ + png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "pHYs"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_pHYs) != 0) + { + if (res_x != NULL) + { + *res_x = info_ptr->x_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (res_y != NULL) + { + *res_y = info_ptr->y_pixels_per_unit; + retval |= PNG_INFO_pHYs; + } + + if (unit_type != NULL) + { + *unit_type = (int)info_ptr->phys_unit_type; + retval |= PNG_INFO_pHYs; + } + } + + return retval; +} +#endif /* pHYs */ + +png_uint_32 PNGAPI +png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, + png_colorp *palette, int *num_palette) +{ + png_debug1(1, "in %s retrieval function", "PLTE"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL) + { + *palette = info_ptr->palette; + *num_palette = info_ptr->num_palette; + png_debug1(3, "num_palette = %d", *num_palette); + return PNG_INFO_PLTE; + } + + return 0; +} + +#ifdef PNG_sBIT_SUPPORTED +png_uint_32 PNGAPI +png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, + png_color_8p *sig_bit) +{ + png_debug1(1, "in %s retrieval function", "sBIT"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) + { + *sig_bit = &(info_ptr->sig_bit); + return PNG_INFO_sBIT; + } + + return 0; +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +int PNGAPI +png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, + png_textp *text_ptr, int *num_text) +{ + if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) + { + png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx", + (unsigned long)png_ptr->chunk_name); + + if (text_ptr != NULL) + *text_ptr = info_ptr->text; + + if (num_text != NULL) + *num_text = info_ptr->num_text; + + return info_ptr->num_text; + } + + if (num_text != NULL) + *num_text = 0; + + return 0; +} +#endif + +#ifdef PNG_tIME_SUPPORTED +png_uint_32 PNGAPI +png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, + png_timep *mod_time) +{ + png_debug1(1, "in %s retrieval function", "tIME"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) + { + *mod_time = &(info_ptr->mod_time); + return PNG_INFO_tIME; + } + + return 0; +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +png_uint_32 PNGAPI +png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) +{ + png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "tRNS"); + + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_tRNS) != 0) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (trans_alpha != NULL) + { + *trans_alpha = info_ptr->trans_alpha; + retval |= PNG_INFO_tRNS; + } + + if (trans_color != NULL) + *trans_color = &(info_ptr->trans_color); + } + + else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ + { + if (trans_color != NULL) + { + *trans_color = &(info_ptr->trans_color); + retval |= PNG_INFO_tRNS; + } + + if (trans_alpha != NULL) + *trans_alpha = NULL; + } + + if (num_trans != NULL) + { + *num_trans = info_ptr->num_trans; + retval |= PNG_INFO_tRNS; + } + } + + return retval; +} +#endif + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +int PNGAPI +png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, + png_unknown_chunkpp unknowns) +{ + if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) + { + *unknowns = info_ptr->unknown_chunks; + return info_ptr->unknown_chunks_num; + } + + return 0; +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +png_byte PNGAPI +png_get_rgb_to_gray_status(png_const_structrp png_ptr) +{ + return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); +} +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +png_voidp PNGAPI +png_get_user_chunk_ptr(png_const_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_ptr : NULL); +} +#endif + +size_t PNGAPI +png_get_compression_buffer_size(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return 0; + +#ifdef PNG_WRITE_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) +#endif + { +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED + return png_ptr->IDAT_read_size; +#else + return PNG_IDAT_READ_SIZE; +#endif + } + +#ifdef PNG_WRITE_SUPPORTED + else + return png_ptr->zbuffer_size; +#endif +} + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* These functions were added to libpng 1.2.6 and were enabled + * by default in libpng-1.4.0 */ +png_uint_32 PNGAPI +png_get_user_width_max(png_const_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_width_max : 0); +} + +png_uint_32 PNGAPI +png_get_user_height_max(png_const_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_height_max : 0); +} + +/* This function was added to libpng 1.4.0 */ +png_uint_32 PNGAPI +png_get_chunk_cache_max(png_const_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_cache_max : 0); +} + +/* This function was added to libpng 1.4.1 */ +png_alloc_size_t PNGAPI +png_get_chunk_malloc_max(png_const_structrp png_ptr) +{ + return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); +} +#endif /* SET_USER_LIMITS */ + +/* These functions were added to libpng 1.4.0 */ +#ifdef PNG_IO_STATE_SUPPORTED +png_uint_32 PNGAPI +png_get_io_state(png_const_structrp png_ptr) +{ + return png_ptr->io_state; +} + +png_uint_32 PNGAPI +png_get_io_chunk_type(png_const_structrp png_ptr) +{ + return png_ptr->chunk_name; +} +#endif /* IO_STATE */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +# ifdef PNG_GET_PALETTE_MAX_SUPPORTED +int PNGAPI +png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) +{ + if (png_ptr != NULL && info_ptr != NULL) + return png_ptr->num_palette_max; + + return -1; +} +# endif +#endif + +#endif /* READ || WRITE */ diff --git a/thirdparty/libpng/upstream/pnginfo.h b/thirdparty/libpng/upstream/pnginfo.h index dbbc35bc1..584a42f95 100644 --- a/thirdparty/libpng/upstream/pnginfo.h +++ b/thirdparty/libpng/upstream/pnginfo.h @@ -1,267 +1,263 @@ - -/* pnginfo.h - header file for PNG reference library - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - - /* png_info is a structure that holds the information in a PNG file so - * that the application can find out the characteristics of the image. - * If you are reading the file, this structure will tell you what is - * in the PNG file. If you are writing the file, fill in the information - * you want to put into the PNG file, using png_set_*() functions, then - * call png_write_info(). - * - * The names chosen should be very close to the PNG specification, so - * consult that document for information about the meaning of each field. - * - * With libpng < 0.95, it was only possible to directly set and read the - * the values in the png_info_struct, which meant that the contents and - * order of the values had to remain fixed. With libpng 0.95 and later, - * however, there are now functions that abstract the contents of - * png_info_struct from the application, so this makes it easier to use - * libpng with dynamic libraries, and even makes it possible to use - * libraries that don't have all of the libpng ancillary chunk-handing - * functionality. In libpng-1.5.0 this was moved into a separate private - * file that is not visible to applications. - * - * The following members may have allocated storage attached that should be - * cleaned up before the structure is discarded: palette, trans, text, - * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, - * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these - * are automatically freed when the info structure is deallocated, if they were - * allocated internally by libpng. This behavior can be changed by means - * of the png_data_freer() function. - * - * More allocation details: all the chunk-reading functions that - * change these members go through the corresponding png_set_* - * functions. A function to clear these members is available: see - * png_free_data(). The png_set_* functions do not depend on being - * able to point info structure members to any of the storage they are - * passed (they make their own copies), EXCEPT that the png_set_text - * functions use the same storage passed to them in the text_ptr or - * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns - * functions do not make their own copies. - */ -#ifndef PNGINFO_H -#define PNGINFO_H - -struct png_info_def -{ - /* The following are necessary for every PNG file */ - png_uint_32 width; /* width of image in pixels (from IHDR) */ - png_uint_32 height; /* height of image in pixels (from IHDR) */ - png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ - size_t rowbytes; /* bytes needed to hold an untransformed row */ - png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ - png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ - png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ - png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ - png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ - /* The following three should have been named *_method not *_type */ - png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ - png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ - png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - - /* The following are set by png_set_IHDR, called from the application on - * write, but the are never actually used by the write code. - */ - png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte spare_byte; /* to align the data, and for future use */ - -#ifdef PNG_READ_SUPPORTED - /* This is never set during write */ - png_byte signature[8]; /* magic bytes read by libpng from start of file */ -#endif - - /* The rest of the data is optional. If you are reading, check the - * valid field to see if the information in these are valid. If you - * are writing, set the valid field to those chunks you want written, - * and initialize the appropriate fields below. - */ - -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are - * defined. When COLORSPACE is switched on all the colorspace-defining - * chunks should be enabled, when GAMMA is switched on all the gamma-defining - * chunks should be enabled. If this is not done it becomes possible to read - * inconsistent PNG files and assign a probably incorrect interpretation to - * the information. (In other words, by carefully choosing which chunks to - * recognize the system configuration can select an interpretation for PNG - * files containing ambiguous data and this will result in inconsistent - * behavior between different libpng builds!) - */ - png_colorspace colorspace; -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* iCCP chunk data. */ - png_charp iccp_name; /* profile name */ - png_bytep iccp_profile; /* International Color Consortium profile data */ - png_uint_32 iccp_proflen; /* ICC profile data length */ -#endif - -#ifdef PNG_TEXT_SUPPORTED - /* The tEXt, and zTXt chunks contain human-readable textual data in - * uncompressed, compressed, and optionally compressed forms, respectively. - * The data in "text" is an array of pointers to uncompressed, - * null-terminated C strings. Each chunk has a keyword that describes the - * textual data contained in that chunk. Keywords are not required to be - * unique, and the text string may be empty. Any number of text chunks may - * be in an image. - */ - int num_text; /* number of comments read or comments to write */ - int max_text; /* current size of text array */ - png_textp text; /* array of comments read or comments to write */ -#endif /* TEXT */ - -#ifdef PNG_tIME_SUPPORTED - /* The tIME chunk holds the last time the displayed image data was - * modified. See the png_time struct for the contents of this struct. - */ - png_time mod_time; -#endif - -#ifdef PNG_sBIT_SUPPORTED - /* The sBIT chunk specifies the number of significant high-order bits - * in the pixel data. Values are in the range [1, bit_depth], and are - * only specified for the channels in the pixel data. The contents of - * the low-order bits is not specified. Data is valid if - * (valid & PNG_INFO_sBIT) is non-zero. - */ - png_color_8 sig_bit; /* significant bits in color channels */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ -defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The tRNS chunk supplies transparency data for paletted images and - * other image types that don't need a full alpha channel. There are - * "num_trans" transparency values for a paletted image, stored in the - * same order as the palette colors, starting from index 0. Values - * for the data are in the range [0, 255], ranging from fully transparent - * to fully opaque, respectively. For non-paletted images, there is a - * single color specified that should be treated as fully transparent. - * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. - */ - png_bytep trans_alpha; /* alpha values for paletted image */ - png_color_16 trans_color; /* transparent color for non-palette image */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The bKGD chunk gives the suggested image background color if the - * display program does not have its own background color and the image - * is needs to composited onto a background before display. The colors - * in "background" are normally in the same color space/depth as the - * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. - */ - png_color_16 background; -#endif - -#ifdef PNG_oFFs_SUPPORTED - /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards - * and downwards from the top-left corner of the display, page, or other - * application-specific co-ordinate space. See the PNG_OFFSET_ defines - * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. - */ - png_int_32 x_offset; /* x offset on page */ - png_int_32 y_offset; /* y offset on page */ - png_byte offset_unit_type; /* offset units type */ -#endif - -#ifdef PNG_pHYs_SUPPORTED - /* The pHYs chunk gives the physical pixel density of the image for - * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ - * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. - */ - png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ - png_uint_32 y_pixels_per_unit; /* vertical pixel density */ - png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ -#endif - -#ifdef PNG_eXIf_SUPPORTED - int num_exif; /* Added at libpng-1.6.31 */ - png_bytep exif; -# ifdef PNG_READ_eXIf_SUPPORTED - png_bytep eXIf_buf; /* Added at libpng-1.6.32 */ -# endif -#endif - -#ifdef PNG_hIST_SUPPORTED - /* The hIST chunk contains the relative frequency or importance of the - * various palette entries, so that a viewer can intelligently select a - * reduced-color palette, if required. Data is an array of "num_palette" - * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) - * is non-zero. - */ - png_uint_16p hist; -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* The pCAL chunk describes a transformation between the stored pixel - * values and original physical data values used to create the image. - * The integer range [0, 2^bit_depth - 1] maps to the floating-point - * range given by [pcal_X0, pcal_X1], and are further transformed by a - * (possibly non-linear) transformation function given by "pcal_type" - * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ - * defines below, and the PNG-Group's PNG extensions document for a - * complete description of the transformations and how they should be - * implemented, and for a description of the ASCII parameter strings. - * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. - */ - png_charp pcal_purpose; /* pCAL chunk description string */ - png_int_32 pcal_X0; /* minimum value */ - png_int_32 pcal_X1; /* maximum value */ - png_charp pcal_units; /* Latin-1 string giving physical units */ - png_charpp pcal_params; /* ASCII strings containing parameter values */ - png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ - png_byte pcal_nparams; /* number of parameters given in pcal_params */ -#endif - -/* New members added in libpng-1.0.6 */ - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunks that the library doesn't recognize. */ - png_unknown_chunkp unknown_chunks; - - /* The type of this field is limited by the type of - * png_struct::user_chunk_cache_max, else overflow can occur. - */ - int unknown_chunks_num; -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Data on sPLT chunks (there may be more than one). */ - png_sPLT_tp splt_palettes; - int splt_palettes_num; /* Match type returned by png_get API */ -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* The sCAL chunk describes the actual physical dimensions of the - * subject matter of the graphic. The chunk contains a unit specification - * a byte value, and two ASCII strings representing floating-point - * values. The values are width and height corresponding to one pixel - * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is - * non-zero. - */ - png_byte scal_unit; /* unit of physical scale */ - png_charp scal_s_width; /* string containing height */ - png_charp scal_s_height; /* string containing width */ -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) - non-zero */ - /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ - png_bytepp row_pointers; /* the image bits */ -#endif - -}; -#endif /* PNGINFO_H */ +/* pnginfo.h - internal structures for libpng + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#ifndef PNGPRIV_H +# error This file must not be included by applications; please include +#endif + +/* INTERNAL, PRIVATE definition of a PNG. + * + * png_info is a modifiable description of a PNG datastream. The fields inside + * this structure are accessed through png_get_() functions and modified + * using png_set_() functions. + * + * Some functions in libpng do directly access members of png_info. However, + * this should be avoided. png_struct objects contain members which hold + * caches, sometimes optimised, of the values from png_info objects, and + * png_info is not passed to the functions which read and write image data. + */ +#ifndef PNGINFO_H +#define PNGINFO_H + +struct png_info_def +{ + /* The following are necessary for every PNG file */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ + size_t rowbytes; /* bytes needed to hold an untransformed row */ + png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ + png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ + png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ + png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ + png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ + /* The following three should have been named *_method not *_type */ + png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ + png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ + png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + + /* The following are set by png_set_IHDR, called from the application on + * write, but the are never actually used by the write code. + */ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte spare_byte; /* to align the data, and for future use */ + +#ifdef PNG_READ_SUPPORTED + /* This is never set during write */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ +#endif + + /* The rest of the data is optional. If you are reading, check the + * valid field to see if the information in these are valid. If you + * are writing, set the valid field to those chunks you want written, + * and initialize the appropriate fields below. + */ + +#ifdef PNG_cICP_SUPPORTED + /* cICP chunk data */ + png_byte cicp_colour_primaries; + png_byte cicp_transfer_function; + png_byte cicp_matrix_coefficients; + png_byte cicp_video_full_range_flag; +#endif + +#ifdef PNG_iCCP_SUPPORTED + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_bytep iccp_profile; /* International Color Consortium profile data */ + png_uint_32 iccp_proflen; /* ICC profile data length */ +#endif + +#ifdef PNG_cLLI_SUPPORTED + png_uint_32 maxCLL; /* cd/m2 (nits) * 10,000 */ + png_uint_32 maxFALL; +#endif + +#ifdef PNG_mDCV_SUPPORTED + png_uint_16 mastering_red_x; /* CIE (xy) x * 50,000 */ + png_uint_16 mastering_red_y; + png_uint_16 mastering_green_x; + png_uint_16 mastering_green_y; + png_uint_16 mastering_blue_x; + png_uint_16 mastering_blue_y; + png_uint_16 mastering_white_x; + png_uint_16 mastering_white_y; + png_uint_32 mastering_maxDL; /* cd/m2 (nits) * 10,000 */ + png_uint_32 mastering_minDL; +#endif + +#ifdef PNG_TEXT_SUPPORTED + /* The tEXt, and zTXt chunks contain human-readable textual data in + * uncompressed, compressed, and optionally compressed forms, respectively. + * The data in "text" is an array of pointers to uncompressed, + * null-terminated C strings. Each chunk has a keyword that describes the + * textual data contained in that chunk. Keywords are not required to be + * unique, and the text string may be empty. Any number of text chunks may + * be in an image. + */ + int num_text; /* number of comments read or comments to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read or comments to write */ +#endif /* TEXT */ + +#ifdef PNG_tIME_SUPPORTED + /* The tIME chunk holds the last time the displayed image data was + * modified. See the png_time struct for the contents of this struct. + */ + png_time mod_time; +#endif + +#ifdef PNG_sBIT_SUPPORTED + /* The sBIT chunk specifies the number of significant high-order bits + * in the pixel data. Values are in the range [1, bit_depth], and are + * only specified for the channels in the pixel data. The contents of + * the low-order bits is not specified. Data is valid if + * (valid & PNG_INFO_sBIT) is non-zero. + */ + png_color_8 sig_bit; /* significant bits in color channels */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ +defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The tRNS chunk supplies transparency data for paletted images and + * other image types that don't need a full alpha channel. There are + * "num_trans" transparency values for a paletted image, stored in the + * same order as the palette colors, starting from index 0. Values + * for the data are in the range [0, 255], ranging from fully transparent + * to fully opaque, respectively. For non-paletted images, there is a + * single color specified that should be treated as fully transparent. + * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. + */ + png_bytep trans_alpha; /* alpha values for paletted image */ + png_color_16 trans_color; /* transparent color for non-palette image */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The bKGD chunk gives the suggested image background color if the + * display program does not have its own background color and the image + * is needs to composited onto a background before display. The colors + * in "background" are normally in the same color space/depth as the + * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. + */ + png_color_16 background; +#endif + +#ifdef PNG_oFFs_SUPPORTED + /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards + * and downwards from the top-left corner of the display, page, or other + * application-specific co-ordinate space. See the PNG_OFFSET_ defines + * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. + */ + png_int_32 x_offset; /* x offset on page */ + png_int_32 y_offset; /* y offset on page */ + png_byte offset_unit_type; /* offset units type */ +#endif + +#ifdef PNG_pHYs_SUPPORTED + /* The pHYs chunk gives the physical pixel density of the image for + * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ + * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. + */ + png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ + png_uint_32 y_pixels_per_unit; /* vertical pixel density */ + png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ +#endif + +#ifdef PNG_eXIf_SUPPORTED + png_uint_32 num_exif; /* Added at libpng-1.6.31 */ + png_bytep exif; +#endif + +#ifdef PNG_hIST_SUPPORTED + /* The hIST chunk contains the relative frequency or importance of the + * various palette entries, so that a viewer can intelligently select a + * reduced-color palette, if required. Data is an array of "num_palette" + * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) + * is non-zero. + */ + png_uint_16p hist; +#endif + +#ifdef PNG_pCAL_SUPPORTED + /* The pCAL chunk describes a transformation between the stored pixel + * values and original physical data values used to create the image. + * The integer range [0, 2^bit_depth - 1] maps to the floating-point + * range given by [pcal_X0, pcal_X1], and are further transformed by a + * (possibly non-linear) transformation function given by "pcal_type" + * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ + * defines below, and the PNG-Group's PNG extensions document for a + * complete description of the transformations and how they should be + * implemented, and for a description of the ASCII parameter strings. + * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. + */ + png_charp pcal_purpose; /* pCAL chunk description string */ + png_int_32 pcal_X0; /* minimum value */ + png_int_32 pcal_X1; /* maximum value */ + png_charp pcal_units; /* Latin-1 string giving physical units */ + png_charpp pcal_params; /* ASCII strings containing parameter values */ + png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ + png_byte pcal_nparams; /* number of parameters given in pcal_params */ +#endif + +/* New members added in libpng-1.0.6 */ + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + /* Storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + + /* The type of this field is limited by the type of + * png_struct::user_chunk_cache_max, else overflow can occur. + */ + int unknown_chunks_num; +#endif + +#ifdef PNG_sPLT_SUPPORTED + /* Data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; + int splt_palettes_num; /* Match type returned by png_get API */ +#endif + +#ifdef PNG_sCAL_SUPPORTED + /* The sCAL chunk describes the actual physical dimensions of the + * subject matter of the graphic. The chunk contains a unit specification + * a byte value, and two ASCII strings representing floating-point + * values. The values are width and height corresponding to one pixel + * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is + * non-zero. + */ + png_byte scal_unit; /* unit of physical scale */ + png_charp scal_s_width; /* string containing height */ + png_charp scal_s_height; /* string containing width */ +#endif + +#ifdef PNG_INFO_IMAGE_SUPPORTED + /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) + non-zero */ + /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ + png_bytepp row_pointers; /* the image bits */ +#endif + +#ifdef PNG_cHRM_SUPPORTED + png_xy cHRM; +#endif + +#ifdef PNG_gAMA_SUPPORTED + png_fixed_point gamma; +#endif + +#ifdef PNG_sRGB_SUPPORTED + int rendering_intent; +#endif +}; +#endif /* PNGINFO_H */ diff --git a/thirdparty/libpng/upstream/pnglibconf.h b/thirdparty/libpng/upstream/pnglibconf.h new file mode 100644 index 000000000..f21b34952 --- /dev/null +++ b/thirdparty/libpng/upstream/pnglibconf.h @@ -0,0 +1,199 @@ +#ifndef PNGLCONF_H +#define PNGLCONF_H + +#define PNG_LINKAGE_API +#define PNG_LINKAGE_FUNCTION +#define PNG_NO_EXTERN + +#define PNG_16BIT_SUPPORTED +#define PNG_ALIGNED_MEMORY_SUPPORTED +#define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_BENIGN_READ_ERRORS_SUPPORTED +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_COLORSPACE_SUPPORTED +#define PNG_CONSOLE_IO_SUPPORTED +#define PNG_EASY_ACCESS_SUPPORTED +#define PNG_FIXED_POINT_SUPPORTED +#define PNG_FLOATING_ARITHMETIC_SUPPORTED +#define PNG_FLOATING_POINT_SUPPORTED +#define PNG_FORMAT_AFIRST_SUPPORTED +#define PNG_FORMAT_BGR_SUPPORTED +#define PNG_GAMMA_SUPPORTED +#define PNG_GET_PALETTE_MAX_SUPPORTED +#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +#define PNG_INCH_CONVERSIONS_SUPPORTED +#define PNG_INFO_IMAGE_SUPPORTED +#define PNG_IO_STATE_SUPPORTED +#define PNG_POINTER_INDEXING_SUPPORTED +#define PNG_PROGRESSIVE_READ_SUPPORTED +#define PNG_READ_16BIT_SUPPORTED +#define PNG_READ_ALPHA_MODE_SUPPORTED +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_READ_BACKGROUND_SUPPORTED +#define PNG_READ_BGR_SUPPORTED +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED +#define PNG_READ_COMPRESSED_TEXT_SUPPORTED +#define PNG_READ_EXPAND_16_SUPPORTED +#define PNG_READ_EXPAND_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_GAMMA_SUPPORTED +#define PNG_READ_GET_PALETTE_MAX_SUPPORTED +#define PNG_READ_GRAY_TO_RGB_SUPPORTED +#define PNG_READ_INTERLACING_SUPPORTED +#define PNG_READ_INT_FUNCTIONS_SUPPORTED +#define PNG_READ_INVERT_ALPHA_SUPPORTED +#define PNG_READ_INVERT_SUPPORTED +#define PNG_READ_OPT_PLTE_SUPPORTED +#define PNG_READ_PACKSWAP_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_QUANTIZE_SUPPORTED +#define PNG_READ_RGB_TO_GRAY_SUPPORTED +#define PNG_READ_SCALE_16_TO_8_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_STRIP_ALPHA_SUPPORTED +#define PNG_READ_SUPPORTED +#define PNG_READ_SWAP_ALPHA_SUPPORTED +#define PNG_READ_SWAP_SUPPORTED +#define PNG_READ_TEXT_SUPPORTED +#define PNG_READ_TRANSFORMS_SUPPORTED +#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_READ_USER_CHUNKS_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_READ_bKGD_SUPPORTED +#define PNG_READ_cHRM_SUPPORTED +#define PNG_READ_gAMA_SUPPORTED +#define PNG_READ_hIST_SUPPORTED +#define PNG_READ_iCCP_SUPPORTED +#define PNG_READ_iTXt_SUPPORTED +#define PNG_READ_oFFs_SUPPORTED +#define PNG_READ_pCAL_SUPPORTED +#define PNG_READ_pHYs_SUPPORTED +#define PNG_READ_sBIT_SUPPORTED +#define PNG_READ_sCAL_SUPPORTED +#define PNG_READ_sPLT_SUPPORTED +#define PNG_READ_sRGB_SUPPORTED +#define PNG_READ_tEXt_SUPPORTED +#define PNG_READ_tIME_SUPPORTED +#define PNG_READ_tRNS_SUPPORTED +#define PNG_READ_zTXt_SUPPORTED +#define PNG_SAVE_INT_32_SUPPORTED +#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED +#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED +#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_SET_USER_LIMITS_SUPPORTED +#define PNG_SETJMP_SUPPORTED +#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED +#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED +#define PNG_STDIO_SUPPORTED +#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_TEXT_SUPPORTED +#define PNG_TIME_RFC1123_SUPPORTED +#define PNG_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_USER_CHUNKS_SUPPORTED +#define PNG_USER_LIMITS_SUPPORTED +#define PNG_USER_TRANSFORM_INFO_SUPPORTED +#define PNG_USER_TRANSFORM_PTR_SUPPORTED +#define PNG_WARNINGS_SUPPORTED +#define PNG_WRITE_16BIT_SUPPORTED +#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#define PNG_WRITE_BGR_SUPPORTED +#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED +#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +#define PNG_WRITE_FILLER_SUPPORTED +#define PNG_WRITE_FILTER_SUPPORTED +#define PNG_WRITE_FLUSH_SUPPORTED +#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED +#define PNG_WRITE_INTERLACING_SUPPORTED +#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED +#define PNG_WRITE_INVERT_ALPHA_SUPPORTED +#define PNG_WRITE_INVERT_SUPPORTED +#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED +#define PNG_WRITE_PACKSWAP_SUPPORTED +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED +#define PNG_WRITE_SUPPORTED +#define PNG_WRITE_SWAP_ALPHA_SUPPORTED +#define PNG_WRITE_SWAP_SUPPORTED +#define PNG_WRITE_TEXT_SUPPORTED +#define PNG_WRITE_TRANSFORMS_SUPPORTED +#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +#define PNG_WRITE_USER_TRANSFORM_SUPPORTED +#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#define PNG_WRITE_bKGD_SUPPORTED +#define PNG_WRITE_cHRM_SUPPORTED +#define PNG_WRITE_gAMA_SUPPORTED +#define PNG_WRITE_hIST_SUPPORTED +#define PNG_WRITE_iCCP_SUPPORTED +#define PNG_WRITE_iTXt_SUPPORTED +#define PNG_WRITE_oFFs_SUPPORTED +#define PNG_WRITE_pCAL_SUPPORTED +#define PNG_WRITE_pHYs_SUPPORTED +#define PNG_WRITE_sBIT_SUPPORTED +#define PNG_WRITE_sCAL_SUPPORTED +#define PNG_WRITE_sPLT_SUPPORTED +#define PNG_WRITE_sRGB_SUPPORTED +#define PNG_WRITE_tEXt_SUPPORTED +#define PNG_WRITE_tIME_SUPPORTED +#define PNG_WRITE_tRNS_SUPPORTED +#define PNG_WRITE_zTXt_SUPPORTED +#define PNG_bKGD_SUPPORTED +#define PNG_cHRM_SUPPORTED +#define PNG_gAMA_SUPPORTED +#define PNG_hIST_SUPPORTED +#define PNG_iCCP_SUPPORTED +#define PNG_iTXt_SUPPORTED +#define PNG_oFFs_SUPPORTED +#define PNG_pCAL_SUPPORTED +#define PNG_pHYs_SUPPORTED +#define PNG_sBIT_SUPPORTED +#define PNG_sCAL_SUPPORTED +#define PNG_sPLT_SUPPORTED +#define PNG_sRGB_SUPPORTED +#define PNG_tEXt_SUPPORTED +#define PNG_tIME_SUPPORTED +#define PNG_tRNS_SUPPORTED +#define PNG_zTXt_SUPPORTED + +#define PNG_API_RULE 0 +#define PNG_CALLOC_SUPPORTED +#define PNG_COST_SHIFT 3 +#define PNG_DEFAULT_READ_MACROS 1 +#define PNG_GAMMA_THRESHOLD_FIXED 5000 +#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE +#define PNG_INFLATE_BUF_SIZE 1024 +#define PNG_MAX_GAMMA_8 11 +#define PNG_QUANTIZE_BLUE_BITS 5 +#define PNG_QUANTIZE_GREEN_BITS 5 +#define PNG_QUANTIZE_RED_BITS 5 +#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) +#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 +#define PNG_WEIGHT_SHIFT 8 +#define PNG_ZBUF_SIZE 8192 +#define PNG_Z_DEFAULT_COMPRESSION (-1) +#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 +#define PNG_Z_DEFAULT_STRATEGY 1 +#define PNG_sCAL_PRECISION 5 +#define PNG_sRGB_PROFILE_CHECKS 2 +#define PNG_USER_WIDTH_MAX 1000000 +#define PNG_USER_HEIGHT_MAX 1000000 + +#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64) +#define PNG_ARM_NEON_OPT 1 +#else +#define PNG_ARM_NEON_OPT 0 +#endif + +#if defined(__SSE2__) || defined(_M_X64) || defined(_M_IX86) +#define PNG_INTEL_SSE_OPT 1 +#else +#define PNG_INTEL_SSE_OPT 0 +#endif + +#endif diff --git a/thirdparty/libpng/upstream/pngmem.c b/thirdparty/libpng/upstream/pngmem.c index 5780e7640..b7adff82f 100644 --- a/thirdparty/libpng/upstream/pngmem.c +++ b/thirdparty/libpng/upstream/pngmem.c @@ -1,284 +1,287 @@ - -/* pngmem.c - stub functions for memory allocation - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all memory allocation. Users who - * need special memory handling are expected to supply replacement - * functions for png_malloc() and png_free(), and to use - * png_create_read_struct_2() and png_create_write_struct_2() to - * identify the replacement functions. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Free a png_struct */ -void /* PRIVATE */ -png_destroy_png_struct(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - /* png_free might call png_error and may certainly call - * png_get_mem_ptr, so fake a temporary png_struct to support this. - */ - png_struct dummy_struct = *png_ptr; - memset(png_ptr, 0, (sizeof *png_ptr)); - png_free(&dummy_struct, png_ptr); - -# ifdef PNG_SETJMP_SUPPORTED - /* We may have a jmp_buf left to deallocate. */ - png_free_jmpbuf(&dummy_struct); -# endif - } -} - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more than 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - ret = png_malloc(png_ptr, size); - - if (ret != NULL) - memset(ret, 0, size); - - return ret; -} - -/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of - * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. - * Checking and error handling must happen outside this routine; it returns NULL - * if the allocation cannot be done (for any reason.) - */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) -{ - /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS - * allocators have also been removed in 1.6.0, so any 16-bit system now has - * to implement a user memory handler. This checks to be sure it isn't - * called with big numbers. - */ -#ifndef PNG_USER_MEM_SUPPORTED - PNG_UNUSED(png_ptr) -#endif - - /* Some compilers complain that this is always true. However, it - * can be false when integer overflow happens. - */ - if (size > 0 && size <= PNG_SIZE_MAX -# ifdef PNG_MAX_MALLOC_64K - && size <= 65536U -# endif - ) - { -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr != NULL && png_ptr->malloc_fn != NULL) - return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); - - else -#endif - return malloc((size_t)size); /* checked for truncation above */ - } - - else - return NULL; -} - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ - defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 - * that arises because of the checks in png_realloc_array that are repeated in - * png_malloc_array. - */ -static png_voidp -png_malloc_array_checked(png_const_structrp png_ptr, int nelements, - size_t element_size) -{ - png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */ - - if (req <= PNG_SIZE_MAX/element_size) - return png_malloc_base(png_ptr, req * element_size); - - /* The failure case when the request is too large */ - return NULL; -} - -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_malloc_array,(png_const_structrp png_ptr, int nelements, - size_t element_size),PNG_ALLOCATED) -{ - if (nelements <= 0 || element_size == 0) - png_error(png_ptr, "internal error: array alloc"); - - return png_malloc_array_checked(png_ptr, nelements, element_size); -} - -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, - int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) -{ - /* These are internal errors: */ - if (add_elements <= 0 || element_size == 0 || old_elements < 0 || - (old_array == NULL && old_elements > 0)) - png_error(png_ptr, "internal error: array realloc"); - - /* Check for overflow on the elements count (so the caller does not have to - * check.) - */ - if (add_elements <= INT_MAX - old_elements) - { - png_voidp new_array = png_malloc_array_checked(png_ptr, - old_elements+add_elements, element_size); - - if (new_array != NULL) - { - /* Because png_malloc_array worked the size calculations below cannot - * overflow. - */ - if (old_elements > 0) - memcpy(new_array, old_array, element_size*(unsigned)old_elements); - - memset((char*)new_array + element_size*(unsigned)old_elements, 0, - element_size*(unsigned)add_elements); - - return new_array; - } - } - - return NULL; /* error */ -} -#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ - -/* Various functions that have different error handling are derived from this. - * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate - * function png_malloc_default is also provided. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - if (png_ptr == NULL) - return NULL; - - ret = png_malloc_base(png_ptr, size); - - if (ret == NULL) - png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ - - return ret; -} - -#ifdef PNG_USER_MEM_SUPPORTED -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED PNG_DEPRECATED) -{ - png_voidp ret; - - if (png_ptr == NULL) - return NULL; - - /* Passing 'NULL' here bypasses the application provided memory handler. */ - ret = png_malloc_base(NULL/*use malloc*/, size); - - if (ret == NULL) - png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ - - return ret; -} -#endif /* USER_MEM */ - -/* This function was added at libpng version 1.2.3. The png_malloc_warn() - * function will issue a png_warning and return NULL instead of issuing a - * png_error, if it fails to allocate the requested memory. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) -{ - if (png_ptr != NULL) - { - png_voidp ret = png_malloc_base(png_ptr, size); - - if (ret != NULL) - return ret; - - png_warning(png_ptr, "Out of memory"); - } - - return NULL; -} - -/* Free a pointer allocated by png_malloc(). If ptr is NULL, return - * without taking any action. - */ -void PNGAPI -png_free(png_const_structrp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL || ptr == NULL) - return; - -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->free_fn != NULL) - png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); - - else - png_free_default(png_ptr, ptr); -} - -PNG_FUNCTION(void,PNGAPI -png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED) -{ - if (png_ptr == NULL || ptr == NULL) - return; -#endif /* USER_MEM */ - - free(ptr); -} - -#ifdef PNG_USER_MEM_SUPPORTED -/* This function is called when the application wants to use another method - * of allocating and freeing memory. - */ -void PNGAPI -png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr - malloc_fn, png_free_ptr free_fn) -{ - if (png_ptr != NULL) - { - png_ptr->mem_ptr = mem_ptr; - png_ptr->malloc_fn = malloc_fn; - png_ptr->free_fn = free_fn; - } -} - -/* This function returns a pointer to the mem_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_mem_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return png_ptr->mem_ptr; -} -#endif /* USER_MEM */ -#endif /* READ || WRITE */ +/* pngmem.c - stub functions for memory allocation + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all memory allocation. Users who + * need special memory handling are expected to supply replacement + * functions for png_malloc() and png_free(), and to use + * png_create_read_struct_2() and png_create_write_struct_2() to + * identify the replacement functions. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) +/* Free a png_struct */ +void /* PRIVATE */ +png_destroy_png_struct(png_structrp png_ptr) +{ + if (png_ptr != NULL) + { + /* png_free might call png_error and may certainly call + * png_get_mem_ptr, so fake a temporary png_struct to support this. + */ + png_struct dummy_struct = *png_ptr; + memset(png_ptr, 0, (sizeof *png_ptr)); + png_free(&dummy_struct, png_ptr); + +# ifdef PNG_SETJMP_SUPPORTED + /* We may have a jmp_buf left to deallocate. */ + png_free_jmpbuf(&dummy_struct); +# endif + } +} + +/* Allocate memory. For reasonable files, size should never exceed + * 64K. However, zlib may allocate more than 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + */ +PNG_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED) +{ + png_voidp ret; + + ret = png_malloc(png_ptr, size); + + if (ret != NULL) + memset(ret, 0, size); + + return ret; +} + +/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of + * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. + * Checking and error handling must happen outside this routine; it returns NULL + * if the allocation cannot be done (for any reason.) + */ +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED) +{ + /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS + * allocators have also been removed in 1.6.0, so any 16-bit system now has + * to implement a user memory handler. This checks to be sure it isn't + * called with big numbers. + */ +# ifdef PNG_MAX_MALLOC_64K + /* This is support for legacy systems which had segmented addressing + * limiting the maximum allocation size to 65536. It takes precedence + * over PNG_SIZE_MAX which is set to 65535 on true 16-bit systems. + * + * TODO: libpng-1.8: finally remove both cases. + */ + if (size > 65536U) return NULL; +# endif + + /* This is checked too because the system malloc call below takes a (size_t). + */ + if (size > PNG_SIZE_MAX) return NULL; + +# ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr != NULL && png_ptr->malloc_fn != NULL) + return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); +# else + PNG_UNUSED(png_ptr) +# endif + + /* Use the system malloc */ + return malloc((size_t)/*SAFE*/size); /* checked for truncation above */ +} + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ + defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) +/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 + * that arises because of the checks in png_realloc_array that are repeated in + * png_malloc_array. + */ +static png_voidp +png_malloc_array_checked(png_const_structrp png_ptr, int nelements, + size_t element_size) +{ + png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */ + + if (req <= PNG_SIZE_MAX/element_size) + return png_malloc_base(png_ptr, req * element_size); + + /* The failure case when the request is too large */ + return NULL; +} + +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_malloc_array,(png_const_structrp png_ptr, int nelements, + size_t element_size), + PNG_ALLOCATED) +{ + if (nelements <= 0 || element_size == 0) + png_error(png_ptr, "internal error: array alloc"); + + return png_malloc_array_checked(png_ptr, nelements, element_size); +} + +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, + int old_elements, int add_elements, size_t element_size), + PNG_ALLOCATED) +{ + /* These are internal errors: */ + if (add_elements <= 0 || element_size == 0 || old_elements < 0 || + (old_array == NULL && old_elements > 0)) + png_error(png_ptr, "internal error: array realloc"); + + /* Check for overflow on the elements count (so the caller does not have to + * check.) + */ + if (add_elements <= INT_MAX - old_elements) + { + png_voidp new_array = png_malloc_array_checked(png_ptr, + old_elements+add_elements, element_size); + + if (new_array != NULL) + { + /* Because png_malloc_array worked the size calculations below cannot + * overflow. + */ + if (old_elements > 0) + memcpy(new_array, old_array, element_size*(unsigned)old_elements); + + memset((char*)new_array + element_size*(unsigned)old_elements, 0, + element_size*(unsigned)add_elements); + + return new_array; + } + } + + return NULL; /* error */ +} +#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ + +/* Various functions that have different error handling are derived from this. + * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate + * function png_malloc_default is also provided. + */ +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED) +{ + png_voidp ret; + + if (png_ptr == NULL) + return NULL; + + ret = png_malloc_base(png_ptr, size); + + if (ret == NULL) + png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ + + return ret; +} + +#ifdef PNG_USER_MEM_SUPPORTED +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED PNG_DEPRECATED) +{ + png_voidp ret; + + if (png_ptr == NULL) + return NULL; + + /* Passing 'NULL' here bypasses the application provided memory handler. */ + ret = png_malloc_base(NULL/*use malloc*/, size); + + if (ret == NULL) + png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ + + return ret; +} +#endif /* USER_MEM */ + +/* This function was added at libpng version 1.2.3. The png_malloc_warn() + * function will issue a png_warning and return NULL instead of issuing a + * png_error, if it fails to allocate the requested memory. + */ +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED) +{ + if (png_ptr != NULL) + { + png_voidp ret = png_malloc_base(png_ptr, size); + + if (ret != NULL) + return ret; + + png_warning(png_ptr, "Out of memory"); + } + + return NULL; +} + +/* Free a pointer allocated by png_malloc(). If ptr is NULL, return + * without taking any action. + */ +void PNGAPI +png_free(png_const_structrp png_ptr, png_voidp ptr) +{ + if (png_ptr == NULL || ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr->free_fn != NULL) + png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); + + else + png_free_default(png_ptr, ptr); +} + +PNG_FUNCTION(void,PNGAPI +png_free_default,(png_const_structrp png_ptr, png_voidp ptr), + PNG_DEPRECATED) +{ + if (png_ptr == NULL || ptr == NULL) + return; +#endif /* USER_MEM */ + + free(ptr); +} + +#ifdef PNG_USER_MEM_SUPPORTED +/* This function is called when the application wants to use another method + * of allocating and freeing memory. + */ +void PNGAPI +png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn) +{ + if (png_ptr != NULL) + { + png_ptr->mem_ptr = mem_ptr; + png_ptr->malloc_fn = malloc_fn; + png_ptr->free_fn = free_fn; + } +} + +/* This function returns a pointer to the mem_ptr associated with the user + * functions. The application should free any memory associated with this + * pointer before png_write_destroy and png_read_destroy are called. + */ +png_voidp PNGAPI +png_get_mem_ptr(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return png_ptr->mem_ptr; +} +#endif /* USER_MEM */ +#endif /* READ || WRITE */ diff --git a/thirdparty/libpng/upstream/pngpread.c b/thirdparty/libpng/upstream/pngpread.c index f741a1412..37aa432ae 100644 --- a/thirdparty/libpng/upstream/pngpread.c +++ b/thirdparty/libpng/upstream/pngpread.c @@ -1,1104 +1,945 @@ - -/* pngpread.c - read a png file in push mode - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - -/* Push model modes */ -#define PNG_READ_SIG_MODE 0 -#define PNG_READ_CHUNK_MODE 1 -#define PNG_READ_IDAT_MODE 2 -#define PNG_READ_tEXt_MODE 4 -#define PNG_READ_zTXt_MODE 5 -#define PNG_READ_DONE_MODE 6 -#define PNG_READ_iTXt_MODE 7 -#define PNG_ERROR_MODE 8 - -#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ -if (png_ptr->push_length + 4 > png_ptr->buffer_size) \ - { png_push_save_buffer(png_ptr); return; } -#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ -if (png_ptr->buffer_size < N) \ - { png_push_save_buffer(png_ptr); return; } - -void PNGAPI -png_process_data(png_structrp png_ptr, png_inforp info_ptr, - png_bytep buffer, size_t buffer_size) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_push_restore_buffer(png_ptr, buffer, buffer_size); - - while (png_ptr->buffer_size) - { - png_process_some_data(png_ptr, info_ptr); - } -} - -size_t PNGAPI -png_process_data_pause(png_structrp png_ptr, int save) -{ - if (png_ptr != NULL) - { - /* It's easiest for the caller if we do the save; then the caller doesn't - * have to supply the same data again: - */ - if (save != 0) - png_push_save_buffer(png_ptr); - else - { - /* This includes any pending saved bytes: */ - size_t remaining = png_ptr->buffer_size; - png_ptr->buffer_size = 0; - - /* So subtract the saved buffer size, unless all the data - * is actually 'saved', in which case we just return 0 - */ - if (png_ptr->save_buffer_size < remaining) - return remaining - png_ptr->save_buffer_size; - } - } - - return 0; -} - -png_uint_32 PNGAPI -png_process_data_skip(png_structrp png_ptr) -{ -/* TODO: Deprecate and remove this API. - * Somewhere the implementation of this seems to have been lost, - * or abandoned. It was only to support some internal back-door access - * to png_struct) in libpng-1.4.x. - */ - png_app_warning(png_ptr, -"png_process_data_skip is not implemented in any current version of libpng"); - return 0; -} - -/* What we do with the incoming data depends on what we were previously - * doing before we ran out of data... - */ -void /* PRIVATE */ -png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr == NULL) - return; - - switch (png_ptr->process_mode) - { - case PNG_READ_SIG_MODE: - { - png_push_read_sig(png_ptr, info_ptr); - break; - } - - case PNG_READ_CHUNK_MODE: - { - png_push_read_chunk(png_ptr, info_ptr); - break; - } - - case PNG_READ_IDAT_MODE: - { - png_push_read_IDAT(png_ptr); - break; - } - - default: - { - png_ptr->buffer_size = 0; - break; - } - } -} - -/* Read any remaining signature bytes from the stream and compare them with - * the correct PNG signature. It is possible that this routine is called - * with bytes already read from the signature, either because they have been - * checked by the calling application, or because of multiple calls to this - * routine. - */ -void /* PRIVATE */ -png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) -{ - size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */ - size_t num_to_check = 8 - num_checked; - - if (png_ptr->buffer_size < num_to_check) - { - num_to_check = png_ptr->buffer_size; - } - - png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), - num_to_check); - png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) - png_error(png_ptr, "Not a PNG file"); - - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - else - { - if (png_ptr->sig_bytes >= 8) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } - } -} - -void /* PRIVATE */ -png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 chunk_name; -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int keep; /* unknown handling method */ -#endif - - /* First we make sure we have enough data for the 4-byte chunk name - * and the 4-byte chunk length before proceeding with decoding the - * chunk data. To fully decode each of these chunks, we also make - * sure we have enough data in the buffer for the 4-byte CRC at the - * end of every chunk (except IDAT, which is handled separately). - */ - if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) - { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - - PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - png_check_chunk_length(png_ptr, png_ptr->push_length); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - } - - chunk_name = png_ptr->chunk_name; - - if (chunk_name == png_IDAT) - { - if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - - /* If we reach an IDAT chunk, this means we have read all of the - * header chunks, and we can start reading the image (or if this - * is called after the image has been read - we have an error). - */ - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - png_error(png_ptr, "Missing PLTE before IDAT"); - - png_ptr->process_mode = PNG_READ_IDAT_MODE; - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) - if (png_ptr->push_length == 0) - return; - - png_ptr->mode |= PNG_HAVE_IDAT; - - if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "Too many IDATs found"); - } - - if (chunk_name == png_IHDR) - { - if (png_ptr->push_length != 13) - png_error(png_ptr, "Invalid IHDR length"); - - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_IEND) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); - - png_ptr->process_mode = PNG_READ_DONE_MODE; - png_push_have_end(png_ptr, info_ptr); - } - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); - - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - } -#endif - - else if (chunk_name == png_PLTE) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_IDAT) - { - png_ptr->idat_size = png_ptr->push_length; - png_ptr->process_mode = PNG_READ_IDAT_MODE; - png_push_have_info(png_ptr, info_ptr); - png_ptr->zstream.avail_out = - (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1; - png_ptr->zstream.next_out = png_ptr->row_buf; - return; - } - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (png_ptr->chunk_name == png_gAMA) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - else if (png_ptr->chunk_name == png_sBIT) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - else if (png_ptr->chunk_name == png_cHRM) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_eXIf_SUPPORTED - else if (png_ptr->chunk_name == png_eXIf) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - else if (png_ptr->chunk_name == png_iCCP) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - - else - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, - PNG_HANDLE_CHUNK_AS_DEFAULT); - } - - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -} - -void PNGCBAPI -png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length) -{ - png_bytep ptr; - - if (png_ptr == NULL) - return; - - ptr = buffer; - if (png_ptr->save_buffer_size != 0) - { - size_t save_size; - - if (length < png_ptr->save_buffer_size) - save_size = length; - - else - save_size = png_ptr->save_buffer_size; - - memcpy(ptr, png_ptr->save_buffer_ptr, save_size); - length -= save_size; - ptr += save_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - if (length != 0 && png_ptr->current_buffer_size != 0) - { - size_t save_size; - - if (length < png_ptr->current_buffer_size) - save_size = length; - - else - save_size = png_ptr->current_buffer_size; - - memcpy(ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } -} - -void /* PRIVATE */ -png_push_save_buffer(png_structrp png_ptr) -{ - if (png_ptr->save_buffer_size != 0) - { - if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) - { - size_t i, istop; - png_bytep sp; - png_bytep dp; - - istop = png_ptr->save_buffer_size; - for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; - i < istop; i++, sp++, dp++) - { - *dp = *sp; - } - } - } - if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > - png_ptr->save_buffer_max) - { - size_t new_max; - png_bytep old_buffer; - - if (png_ptr->save_buffer_size > PNG_SIZE_MAX - - (png_ptr->current_buffer_size + 256)) - { - png_error(png_ptr, "Potential overflow of save_buffer"); - } - - new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; - old_buffer = png_ptr->save_buffer; - png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, - (size_t)new_max); - - if (png_ptr->save_buffer == NULL) - { - png_free(png_ptr, old_buffer); - png_error(png_ptr, "Insufficient memory for save_buffer"); - } - - if (old_buffer) - memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); - else if (png_ptr->save_buffer_size) - png_error(png_ptr, "save_buffer error"); - png_free(png_ptr, old_buffer); - png_ptr->save_buffer_max = new_max; - } - if (png_ptr->current_buffer_size) - { - memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, - png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); - png_ptr->save_buffer_size += png_ptr->current_buffer_size; - png_ptr->current_buffer_size = 0; - } - png_ptr->save_buffer_ptr = png_ptr->save_buffer; - png_ptr->buffer_size = 0; -} - -void /* PRIVATE */ -png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, - size_t buffer_length) -{ - png_ptr->current_buffer = buffer; - png_ptr->current_buffer_size = buffer_length; - png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; - png_ptr->current_buffer_ptr = png_ptr->current_buffer; -} - -void /* PRIVATE */ -png_push_read_IDAT(png_structrp png_ptr) -{ - if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) - { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - - /* TODO: this code can be commoned up with the same code in push_read */ - PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - - if (png_ptr->chunk_name != png_IDAT) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - png_error(png_ptr, "Not enough compressed data"); - - return; - } - - png_ptr->idat_size = png_ptr->push_length; - } - - if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) - { - size_t save_size = png_ptr->save_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; - - /* We want the smaller of 'idat_size' and 'current_buffer_size', but they - * are of different types and we don't know which variable has the fewest - * bits. Carefully select the smaller and cast it to the type of the - * larger - this cannot overflow. Do not cast in the following test - it - * will break on either 16-bit or 64-bit platforms. - */ - if (idat_size < save_size) - save_size = (size_t)idat_size; - - else - idat_size = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_ptr->idat_size -= idat_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - - if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) - { - size_t save_size = png_ptr->current_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; - - /* We want the smaller of 'idat_size' and 'current_buffer_size', but they - * are of different types and we don't know which variable has the fewest - * bits. Carefully select the smaller and cast it to the type of the - * larger - this cannot overflow. - */ - if (idat_size < save_size) - save_size = (size_t)idat_size; - - else - idat_size = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_ptr->idat_size -= idat_size; - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } - - if (png_ptr->idat_size == 0) - { - PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_crc_finish(png_ptr, 0); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->zowner = 0; - } -} - -void /* PRIVATE */ -png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, - size_t buffer_length) -{ - /* The caller checks for a non-zero buffer length. */ - if (!(buffer_length > 0) || buffer == NULL) - png_error(png_ptr, "No IDAT data (internal error)"); - - /* This routine must process all the data it has been given - * before returning, calling the row callback as required to - * handle the uncompressed results. - */ - png_ptr->zstream.next_in = buffer; - /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ - png_ptr->zstream.avail_in = (uInt)buffer_length; - - /* Keep going until the decompressed data is all processed - * or the stream marked as finished. - */ - while (png_ptr->zstream.avail_in > 0 && - (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - { - int ret; - - /* We have data for zlib, but we must check that zlib - * has someplace to put the results. It doesn't matter - * if we don't expect any results -- it may be the input - * data is just the LZ end code. - */ - if (!(png_ptr->zstream.avail_out > 0)) - { - /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ - png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1); - - png_ptr->zstream.next_out = png_ptr->row_buf; - } - - /* Using Z_SYNC_FLUSH here means that an unterminated - * LZ stream (a stream with a missing end code) can still - * be handled, otherwise (Z_NO_FLUSH) a future zlib - * implementation might defer output and therefore - * change the current behavior (see comments in inflate.c - * for why this doesn't happen at present with zlib 1.2.5). - */ - ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); - - /* Check for any failure before proceeding. */ - if (ret != Z_OK && ret != Z_STREAM_END) - { - /* Terminate the decompression. */ - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - png_ptr->zowner = 0; - - /* This may be a truncated stream (missing or - * damaged end code). Treat that as a warning. - */ - if (png_ptr->row_number >= png_ptr->num_rows || - png_ptr->pass > 6) - png_warning(png_ptr, "Truncated compressed data in IDAT"); - - else - { - if (ret == Z_DATA_ERROR) - png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch"); - else - png_error(png_ptr, "Decompression error in IDAT"); - } - - /* Skip the check on unprocessed input */ - return; - } - - /* Did inflate output any data? */ - if (png_ptr->zstream.next_out != png_ptr->row_buf) - { - /* Is this unexpected data after the last row? - * If it is, artificially terminate the LZ output - * here. - */ - if (png_ptr->row_number >= png_ptr->num_rows || - png_ptr->pass > 6) - { - /* Extra data. */ - png_warning(png_ptr, "Extra compressed data in IDAT"); - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - png_ptr->zowner = 0; - - /* Do no more processing; skip the unprocessed - * input check below. - */ - return; - } - - /* Do we have a complete row? */ - if (png_ptr->zstream.avail_out == 0) - png_push_process_row(png_ptr); - } - - /* And check for the end of the stream. */ - if (ret == Z_STREAM_END) - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - } - - /* All the data should have been processed, if anything - * is left at this point we have bytes of IDAT data - * after the zlib end code. - */ - if (png_ptr->zstream.avail_in > 0) - png_warning(png_ptr, "Extra compression data in IDAT"); -} - -void /* PRIVATE */ -png_push_process_row(png_structrp png_ptr) -{ - /* 1.5.6: row_info moved out of png_struct to a local here. */ - png_row_info row_info; - - row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ - row_info.color_type = png_ptr->color_type; - row_info.bit_depth = png_ptr->bit_depth; - row_info.channels = png_ptr->channels; - row_info.pixel_depth = png_ptr->pixel_depth; - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { - if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) - png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); - else - png_error(png_ptr, "bad adaptive filter value"); - } - - /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before - * 1.5.6, while the buffer really is this big in current versions of libpng - * it may not be in the future, so this was changed just to copy the - * interlaced row count: - */ - memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations != 0) - png_do_read_transformations(png_ptr, &row_info); -#endif - - /* The transformed pixel depth should match the depth now in row_info. */ - if (png_ptr->transformed_pixel_depth == 0) - { - png_ptr->transformed_pixel_depth = row_info.pixel_depth; - if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) - png_error(png_ptr, "progressive row overflow"); - } - - else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) - png_error(png_ptr, "internal progressive row size calculation error"); - - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Expand interlaced rows to full size */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - if (png_ptr->pass < 6) - png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); - - switch (png_ptr->pass) - { - case 0: - { - int i; - for (i = 0; i < 8 && png_ptr->pass == 0; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ - } - - if (png_ptr->pass == 2) /* Pass 1 might be empty */ - { - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - if (png_ptr->pass == 4 && png_ptr->height <= 4) - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - if (png_ptr->pass == 6 && png_ptr->height <= 4) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - case 1: - { - int i; - for (i = 0; i < 8 && png_ptr->pass == 1; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 2) /* Skip top 4 generated rows */ - { - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 2: - { - int i; - - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 4) /* Pass 3 might be empty */ - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 3: - { - int i; - - for (i = 0; i < 4 && png_ptr->pass == 3; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 4) /* Skip top two generated rows */ - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 4: - { - int i; - - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 6) /* Pass 5 might be empty */ - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - case 5: - { - int i; - - for (i = 0; i < 2 && png_ptr->pass == 5; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 6) /* Skip top generated row */ - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - default: - case 6: - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - - if (png_ptr->pass != 6) - break; - - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - } - else -#endif - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } -} - -void /* PRIVATE */ -png_read_push_finish_row(png_structrp png_ptr) -{ -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - - /* Height of interlace block. This is not currently used - if you need - * it, uncomment it here and in png.h - static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; - */ -#endif - - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { - png_ptr->pass++; - if ((png_ptr->pass == 1 && png_ptr->width < 5) || - (png_ptr->pass == 3 && png_ptr->width < 3) || - (png_ptr->pass == 5 && png_ptr->width < 2)) - png_ptr->pass++; - - if (png_ptr->pass > 7) - png_ptr->pass--; - - if (png_ptr->pass >= 7) - break; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - if ((png_ptr->transformations & PNG_INTERLACE) != 0) - break; - - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - - } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); - } -#endif /* READ_INTERLACING */ -} - -void /* PRIVATE */ -png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr->info_fn != NULL) - (*(png_ptr->info_fn))(png_ptr, info_ptr); -} - -void /* PRIVATE */ -png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr->end_fn != NULL) - (*(png_ptr->end_fn))(png_ptr, info_ptr); -} - -void /* PRIVATE */ -png_push_have_row(png_structrp png_ptr, png_bytep row) -{ - if (png_ptr->row_fn != NULL) - (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, - (int)png_ptr->pass); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -void PNGAPI -png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, - png_const_bytep new_row) -{ - if (png_ptr == NULL) - return; - - /* new_row is a flag here - if it is NULL then the app callback was called - * from an empty row (see the calls to png_struct::row_fn below), otherwise - * it must be png_ptr->row_buf+1 - */ - if (new_row != NULL) - png_combine_row(png_ptr, old_row, 1/*blocky display*/); -} -#endif /* READ_INTERLACING */ - -void PNGAPI -png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->info_fn = info_fn; - png_ptr->row_fn = row_fn; - png_ptr->end_fn = end_fn; - - png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); -} - -png_voidp PNGAPI -png_get_progressive_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return png_ptr->io_ptr; -} -#endif /* PROGRESSIVE_READ */ +/* pngpread.c - read a png file in push mode + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + +/* Push model modes */ +#define PNG_READ_SIG_MODE 0 +#define PNG_READ_CHUNK_MODE 1 +#define PNG_READ_IDAT_MODE 2 +#define PNG_READ_tEXt_MODE 4 +#define PNG_READ_zTXt_MODE 5 +#define PNG_READ_DONE_MODE 6 +#define PNG_READ_iTXt_MODE 7 +#define PNG_ERROR_MODE 8 + +#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ +if (png_ptr->push_length + 4 > png_ptr->buffer_size) \ + { png_push_save_buffer(png_ptr); return; } +#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ +if (png_ptr->buffer_size < N) \ + { png_push_save_buffer(png_ptr); return; } + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */ + +/* Start of interlace block */ +static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; +/* Offset to next interlace block */ +static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +/* Start of interlace block in the y direction */ +static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; +/* Offset to next interlace block in the y direction */ +static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + +/* TODO: Move these arrays to a common utility module to avoid duplication. */ +#endif + +void PNGAPI +png_process_data(png_structrp png_ptr, png_inforp info_ptr, + png_bytep buffer, size_t buffer_size) +{ + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_push_restore_buffer(png_ptr, buffer, buffer_size); + + while (png_ptr->buffer_size) + { + png_process_some_data(png_ptr, info_ptr); + } +} + +size_t PNGAPI +png_process_data_pause(png_structrp png_ptr, int save) +{ + if (png_ptr != NULL) + { + /* It's easiest for the caller if we do the save; then the caller doesn't + * have to supply the same data again: + */ + if (save != 0) + png_push_save_buffer(png_ptr); + else + { + /* This includes any pending saved bytes: */ + size_t remaining = png_ptr->buffer_size; + png_ptr->buffer_size = 0; + + /* So subtract the saved buffer size, unless all the data + * is actually 'saved', in which case we just return 0 + */ + if (png_ptr->save_buffer_size < remaining) + return remaining - png_ptr->save_buffer_size; + } + } + + return 0; +} + +png_uint_32 PNGAPI +png_process_data_skip(png_structrp png_ptr) +{ +/* TODO: Deprecate and remove this API. + * Somewhere the implementation of this seems to have been lost, + * or abandoned. It was only to support some internal back-door access + * to png_struct) in libpng-1.4.x. + */ + png_app_warning(png_ptr, +"png_process_data_skip is not implemented in any current version of libpng"); + return 0; +} + +/* What we do with the incoming data depends on what we were previously + * doing before we ran out of data... + */ +void /* PRIVATE */ +png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) +{ + if (png_ptr == NULL) + return; + + switch (png_ptr->process_mode) + { + case PNG_READ_SIG_MODE: + { + png_push_read_sig(png_ptr, info_ptr); + break; + } + + case PNG_READ_CHUNK_MODE: + { + png_push_read_chunk(png_ptr, info_ptr); + break; + } + + case PNG_READ_IDAT_MODE: + { + png_push_read_IDAT(png_ptr); + break; + } + + default: + { + png_ptr->buffer_size = 0; + break; + } + } +} + +/* Read any remaining signature bytes from the stream and compare them with + * the correct PNG signature. It is possible that this routine is called + * with bytes already read from the signature, either because they have been + * checked by the calling application, or because of multiple calls to this + * routine. + */ +void /* PRIVATE */ +png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) +{ + size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */ + size_t num_to_check = 8 - num_checked; + + if (png_ptr->buffer_size < num_to_check) + { + num_to_check = png_ptr->buffer_size; + } + + png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), + num_to_check); + png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) + png_error(png_ptr, "Not a PNG file"); + + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + else + { + if (png_ptr->sig_bytes >= 8) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + } +} + +void /* PRIVATE */ +png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) +{ + png_uint_32 chunk_name; +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int keep; /* unknown handling method */ +#endif + + /* First we make sure we have enough data for the 4-byte chunk name + * and the 4-byte chunk length before proceeding with decoding the + * chunk data. To fully decode each of these chunks, we also make + * sure we have enough data in the buffer for the 4-byte CRC at the + * end of every chunk (except IDAT, which is handled separately). + */ + if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) + { + PNG_PUSH_SAVE_BUFFER_IF_LT(8) + png_ptr->push_length = png_read_chunk_header(png_ptr); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + } + + chunk_name = png_ptr->chunk_name; + + if (chunk_name == png_IDAT) + { + if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + + /* If we reach an IDAT chunk, this means we have read all of the + * header chunks, and we can start reading the image (or if this + * is called after the image has been read - we have an error). + */ + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + (png_ptr->mode & PNG_HAVE_PLTE) == 0) + png_error(png_ptr, "Missing PLTE before IDAT"); + + png_ptr->process_mode = PNG_READ_IDAT_MODE; + + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) + if (png_ptr->push_length == 0) + return; + + png_ptr->mode |= PNG_HAVE_IDAT; + + if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) + png_benign_error(png_ptr, "Too many IDATs found"); + } + + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { + /* These flags must be set consistently for all non-IDAT chunks, + * including the unknown chunks. + */ + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT; + } + + if (chunk_name == png_IHDR) + { + if (png_ptr->push_length != 13) + png_error(png_ptr, "Invalid IHDR length"); + + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); + } + + else if (chunk_name == png_IEND) + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); + + png_ptr->process_mode = PNG_READ_DONE_MODE; + png_push_have_end(png_ptr, info_ptr); + } + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#endif + + else if (chunk_name == png_IDAT) + { + png_ptr->idat_size = png_ptr->push_length; + png_ptr->process_mode = PNG_READ_IDAT_MODE; + png_push_have_info(png_ptr, info_ptr); + png_ptr->zstream.avail_out = + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; + png_ptr->zstream.next_out = png_ptr->row_buf; + return; + } + + else + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); + } + + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; +} + +void PNGCBAPI +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length) +{ + png_bytep ptr; + + if (png_ptr == NULL) + return; + + ptr = buffer; + if (png_ptr->save_buffer_size != 0) + { + size_t save_size; + + if (length < png_ptr->save_buffer_size) + save_size = length; + + else + save_size = png_ptr->save_buffer_size; + + memcpy(ptr, png_ptr->save_buffer_ptr, save_size); + length -= save_size; + ptr += save_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + if (length != 0 && png_ptr->current_buffer_size != 0) + { + size_t save_size; + + if (length < png_ptr->current_buffer_size) + save_size = length; + + else + save_size = png_ptr->current_buffer_size; + + memcpy(ptr, png_ptr->current_buffer_ptr, save_size); + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } +} + +void /* PRIVATE */ +png_push_save_buffer(png_structrp png_ptr) +{ + if (png_ptr->save_buffer_size != 0) + { + if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) + { + size_t i, istop; + png_bytep sp; + png_bytep dp; + + istop = png_ptr->save_buffer_size; + for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; + i < istop; i++, sp++, dp++) + { + *dp = *sp; + } + } + } + if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > + png_ptr->save_buffer_max) + { + size_t new_max; + png_bytep old_buffer; + + if (png_ptr->save_buffer_size > PNG_SIZE_MAX - + (png_ptr->current_buffer_size + 256)) + { + png_error(png_ptr, "Potential overflow of save_buffer"); + } + + new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; + old_buffer = png_ptr->save_buffer; + png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, + (size_t)new_max); + + if (png_ptr->save_buffer == NULL) + { + png_free(png_ptr, old_buffer); + png_error(png_ptr, "Insufficient memory for save_buffer"); + } + + if (old_buffer) + memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); + else if (png_ptr->save_buffer_size) + png_error(png_ptr, "save_buffer error"); + png_free(png_ptr, old_buffer); + png_ptr->save_buffer_max = new_max; + } + if (png_ptr->current_buffer_size) + { + memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, + png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); + png_ptr->save_buffer_size += png_ptr->current_buffer_size; + png_ptr->current_buffer_size = 0; + } + png_ptr->save_buffer_ptr = png_ptr->save_buffer; + png_ptr->buffer_size = 0; +} + +void /* PRIVATE */ +png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, + size_t buffer_length) +{ + png_ptr->current_buffer = buffer; + png_ptr->current_buffer_size = buffer_length; + png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; + png_ptr->current_buffer_ptr = png_ptr->current_buffer; +} + +void /* PRIVATE */ +png_push_read_IDAT(png_structrp png_ptr) +{ + if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) + { + png_byte chunk_length[4]; + png_byte chunk_tag[4]; + + /* TODO: this code can be commoned up with the same code in push_read */ + PNG_PUSH_SAVE_BUFFER_IF_LT(8) + png_push_fill_buffer(png_ptr, chunk_length, 4); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); + png_reset_crc(png_ptr); + png_crc_read(png_ptr, chunk_tag, 4); + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; + + if (png_ptr->chunk_name != png_IDAT) + { + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + png_error(png_ptr, "Not enough compressed data"); + + return; + } + + png_ptr->idat_size = png_ptr->push_length; + } + + if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) + { + size_t save_size = png_ptr->save_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. Do not cast in the following test - it + * will break on either 16-bit or 64-bit platforms. + */ + if (idat_size < save_size) + save_size = (size_t)idat_size; + + else + idat_size = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_size; + png_ptr->buffer_size -= save_size; + png_ptr->save_buffer_size -= save_size; + png_ptr->save_buffer_ptr += save_size; + } + + if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) + { + size_t save_size = png_ptr->current_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. + */ + if (idat_size < save_size) + save_size = (size_t)idat_size; + + else + idat_size = (png_uint_32)save_size; + + png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_size; + png_ptr->buffer_size -= save_size; + png_ptr->current_buffer_size -= save_size; + png_ptr->current_buffer_ptr += save_size; + } + + if (png_ptr->idat_size == 0) + { + PNG_PUSH_SAVE_BUFFER_IF_LT(4) + png_crc_finish(png_ptr, 0); + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->zowner = 0; + } +} + +void /* PRIVATE */ +png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, + size_t buffer_length) +{ + /* The caller checks for a non-zero buffer length. */ + if (!(buffer_length > 0) || buffer == NULL) + png_error(png_ptr, "No IDAT data (internal error)"); + + /* This routine must process all the data it has been given + * before returning, calling the row callback as required to + * handle the uncompressed results. + */ + png_ptr->zstream.next_in = buffer; + /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ + png_ptr->zstream.avail_in = (uInt)buffer_length; + + /* Keep going until the decompressed data is all processed + * or the stream marked as finished. + */ + while (png_ptr->zstream.avail_in > 0 && + (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + { + int ret; + + /* We have data for zlib, but we must check that zlib + * has someplace to put the results. It doesn't matter + * if we don't expect any results -- it may be the input + * data is just the LZ end code. + */ + if (!(png_ptr->zstream.avail_out > 0)) + { + /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ + png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1); + + png_ptr->zstream.next_out = png_ptr->row_buf; + } + + /* Using Z_SYNC_FLUSH here means that an unterminated + * LZ stream (a stream with a missing end code) can still + * be handled, otherwise (Z_NO_FLUSH) a future zlib + * implementation might defer output and therefore + * change the current behavior (see comments in inflate.c + * for why this doesn't happen at present with zlib 1.2.5). + */ + ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); + + /* Check for any failure before proceeding. */ + if (ret != Z_OK && ret != Z_STREAM_END) + { + /* Terminate the decompression. */ + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + png_ptr->zowner = 0; + + /* This may be a truncated stream (missing or + * damaged end code). Treat that as a warning. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + png_warning(png_ptr, "Truncated compressed data in IDAT"); + + else + { + if (ret == Z_DATA_ERROR) + png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch"); + else + png_error(png_ptr, "Decompression error in IDAT"); + } + + /* Skip the check on unprocessed input */ + return; + } + + /* Did inflate output any data? */ + if (png_ptr->zstream.next_out != png_ptr->row_buf) + { + /* Is this unexpected data after the last row? + * If it is, artificially terminate the LZ output + * here. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + { + /* Extra data. */ + png_warning(png_ptr, "Extra compressed data in IDAT"); + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + png_ptr->zowner = 0; + + /* Do no more processing; skip the unprocessed + * input check below. + */ + return; + } + + /* Do we have a complete row? */ + if (png_ptr->zstream.avail_out == 0) + png_push_process_row(png_ptr); + } + + /* And check for the end of the stream. */ + if (ret == Z_STREAM_END) + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + } + + /* All the data should have been processed, if anything + * is left at this point we have bytes of IDAT data + * after the zlib end code. + */ + if (png_ptr->zstream.avail_in > 0) + png_warning(png_ptr, "Extra compression data in IDAT"); +} + +void /* PRIVATE */ +png_push_process_row(png_structrp png_ptr) +{ + /* 1.5.6: row_info moved out of png_struct to a local here. */ + png_row_info row_info; + + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } + + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced row count: + */ + memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations != 0) + png_do_read_transformations(png_ptr, &row_info); +#endif + + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "progressive row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal progressive row size calculation error"); + + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Expand interlaced rows to full size */ + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0) + { + if (png_ptr->pass < 6) + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); + + switch (png_ptr->pass) + { + case 0: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 0; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ + } + + if (png_ptr->pass == 2) /* Pass 1 might be empty */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + if (png_ptr->pass == 4 && png_ptr->height <= 4) + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + if (png_ptr->pass == 6 && png_ptr->height <= 4) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + case 1: + { + int i; + for (i = 0; i < 8 && png_ptr->pass == 1; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 2) /* Skip top 4 generated rows */ + { + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + break; + } + + case 2: + { + int i; + + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + for (i = 0; i < 4 && png_ptr->pass == 2; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 4) /* Pass 3 might be empty */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + break; + } + + case 3: + { + int i; + + for (i = 0; i < 4 && png_ptr->pass == 3; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 4) /* Skip top two generated rows */ + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + + break; + } + + case 4: + { + int i; + + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 6) /* Pass 5 might be empty */ + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + case 5: + { + int i; + + for (i = 0; i < 2 && png_ptr->pass == 5; i++) + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } + + if (png_ptr->pass == 6) /* Skip top generated row */ + { + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + + break; + } + + default: + case 6: + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + + if (png_ptr->pass != 6) + break; + + png_push_have_row(png_ptr, NULL); + png_read_push_finish_row(png_ptr); + } + } + } + else +#endif + { + png_push_have_row(png_ptr, png_ptr->row_buf + 1); + png_read_push_finish_row(png_ptr); + } +} + +void /* PRIVATE */ +png_read_push_finish_row(png_structrp png_ptr) +{ + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced != 0) + { + png_ptr->row_number = 0; + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + do + { + png_ptr->pass++; + if ((png_ptr->pass == 1 && png_ptr->width < 5) || + (png_ptr->pass == 3 && png_ptr->width < 3) || + (png_ptr->pass == 5 && png_ptr->width < 2)) + png_ptr->pass++; + + if (png_ptr->pass > 7) + png_ptr->pass--; + + if (png_ptr->pass >= 7) + break; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + if ((png_ptr->transformations & PNG_INTERLACE) != 0) + break; + + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + + } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); + } +#endif /* READ_INTERLACING */ +} + +void /* PRIVATE */ +png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) +{ + if (png_ptr->info_fn != NULL) + (*(png_ptr->info_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) +{ + if (png_ptr->end_fn != NULL) + (*(png_ptr->end_fn))(png_ptr, info_ptr); +} + +void /* PRIVATE */ +png_push_have_row(png_structrp png_ptr, png_bytep row) +{ + if (png_ptr->row_fn != NULL) + (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, + (int)png_ptr->pass); +} + +#ifdef PNG_READ_INTERLACING_SUPPORTED +void PNGAPI +png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, + png_const_bytep new_row) +{ + if (png_ptr == NULL) + return; + + /* new_row is a flag here - if it is NULL then the app callback was called + * from an empty row (see the calls to png_struct::row_fn below), otherwise + * it must be png_ptr->row_buf+1 + */ + if (new_row != NULL) + png_combine_row(png_ptr, old_row, 1/*blocky display*/); +} +#endif /* READ_INTERLACING */ + +void PNGAPI +png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->info_fn = info_fn; + png_ptr->row_fn = row_fn; + png_ptr->end_fn = end_fn; + + png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); +} + +png_voidp PNGAPI +png_get_progressive_ptr(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return png_ptr->io_ptr; +} +#endif /* PROGRESSIVE_READ */ diff --git a/thirdparty/libpng/upstream/pngpriv.h b/thirdparty/libpng/upstream/pngpriv.h index d93b16b2e..d7c4b3a91 100644 --- a/thirdparty/libpng/upstream/pngpriv.h +++ b/thirdparty/libpng/upstream/pngpriv.h @@ -1,2180 +1,2423 @@ - -/* pngpriv.h - private declarations for use inside libpng - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The symbols declared in this file (including the functions declared - * as extern) are PRIVATE. They are not part of the libpng public - * interface, and are not recommended for use by regular applications. - * Some of them may become public in the future; others may stay private, - * change in an incompatible way, or even disappear. - * Although the libpng users are not forbidden to include this header, - * they should be well aware of the issues that may arise from doing so. - */ - -#ifndef PNGPRIV_H -#define PNGPRIV_H - -/* Feature Test Macros. The following are defined here to ensure that correctly - * implemented libraries reveal the APIs libpng needs to build and hide those - * that are not needed and potentially damaging to the compilation. - * - * Feature Test Macros must be defined before any system header is included (see - * POSIX 1003.1 2.8.2 "POSIX Symbols." - * - * These macros only have an effect if the operating system supports either - * POSIX 1003.1 or C99, or both. On other operating systems (particularly - * Windows/Visual Studio) there is no effect; the OS specific tests below are - * still required (as of 2011-05-02.) - */ -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Standard library headers not required by png.h: */ -# include -# include -#endif - -#define PNGLIB_BUILD /*libpng is being built, not used*/ - -/* If HAVE_CONFIG_H is defined during the build then the build system must - * provide an appropriate "config.h" file on the include path. The header file - * must provide definitions as required below (search for "HAVE_CONFIG_H"); - * see configure.ac for more details of the requirements. The macro - * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on - * 'configure'; define this macro to prevent the configure build including the - * configure generated config.h. Libpng is expected to compile without *any* - * special build system support on a reasonably ANSI-C compliant system. - */ -#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) -# include - - /* Pick up the definition of 'restrict' from config.h if it was read: */ -# define PNG_RESTRICT restrict -#endif - -/* To support symbol prefixing it is necessary to know *before* including png.h - * whether the fixed point (and maybe other) APIs are exported, because if they - * are not internal definitions may be required. This is handled below just - * before png.h is included, but load the configuration now if it is available. - */ -#ifndef PNGLCONF_H -# include "pnglibconf.h" -#endif - -/* Local renames may change non-exported API functions from png.h */ -#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) -# include "pngprefix.h" -#endif - -#ifdef PNG_USER_CONFIG -# include "pngusr.h" - /* These should have been defined in pngusr.h */ -# ifndef PNG_USER_PRIVATEBUILD -# define PNG_USER_PRIVATEBUILD "Custom libpng build" -# endif -# ifndef PNG_USER_DLLFNAME_POSTFIX -# define PNG_USER_DLLFNAME_POSTFIX "Cb" -# endif -#endif - -/* Compile time options. - * ===================== - * In a multi-arch build the compiler may compile the code several times for the - * same object module, producing different binaries for different architectures. - * When this happens configure-time setting of the target host options cannot be - * done and this interferes with the handling of the ARM NEON optimizations, and - * possibly other similar optimizations. Put additional tests here; in general - * this is needed when the same option can be changed at both compile time and - * run time depending on the target OS (i.e. iOS vs Android.) - * - * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because - * this is not possible with certain compilers (Oracle SUN OS CC), as a result - * it is necessary to ensure that all extern functions that *might* be used - * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__ - * below is one example of this behavior because it is controlled by the - * presence or not of -mfpu=neon on the GCC command line, it is possible to do - * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely - * do this. - */ -#ifndef PNG_ARM_NEON_OPT - /* ARM NEON optimizations are being controlled by the compiler settings, - * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon - * with GCC) then the compiler will define __ARM_NEON__ and we can rely - * unconditionally on NEON instructions not crashing, otherwise we must - * disable use of NEON instructions. - * - * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they - * can only be turned on automatically if that is supported too. If - * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail - * to compile with an appropriate #error if ALIGNED_MEMORY has been turned - * off. - * - * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated - * __ARM_NEON__, so we check both variants. - * - * To disable ARM_NEON optimizations entirely, and skip compiling the - * associated assembler code, pass --enable-arm-neon=no to configure - * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS. - */ -# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \ - defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_ARM_NEON_OPT 2 -# else -# define PNG_ARM_NEON_OPT 0 -# endif -#endif - -#if PNG_ARM_NEON_OPT > 0 - /* NEON optimizations are to be at least considered by libpng, so enable the - * callbacks to do this. - */ -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon -# ifndef PNG_ARM_NEON_IMPLEMENTATION - /* Use the intrinsics code by default. */ -# define PNG_ARM_NEON_IMPLEMENTATION 1 -# endif -#else /* PNG_ARM_NEON_OPT == 0 */ -# define PNG_ARM_NEON_IMPLEMENTATION 0 -#endif /* PNG_ARM_NEON_OPT > 0 */ - -#ifndef PNG_MIPS_MSA_OPT -# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \ - defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_MIPS_MSA_OPT 2 -# else -# define PNG_MIPS_MSA_OPT 0 -# endif -#endif - -#ifndef PNG_MIPS_MMI_OPT -# ifdef PNG_MIPS_MMI -# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \ - defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_MIPS_MMI_OPT 1 -# else -# define PNG_MIPS_MMI_OPT 0 -# endif -# else -# define PNG_MIPS_MMI_OPT 0 -# endif -#endif - -#ifndef PNG_POWERPC_VSX_OPT -# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) -# define PNG_POWERPC_VSX_OPT 2 -# else -# define PNG_POWERPC_VSX_OPT 0 -# endif -#endif - -#ifndef PNG_LOONGARCH_LSX_OPT -# if defined(__loongarch_sx) -# define PNG_LOONGARCH_LSX_OPT 1 -# else -# define PNG_LOONGARCH_LSX_OPT 0 -# endif -#endif - -#ifndef PNG_INTEL_SSE_OPT -# ifdef PNG_INTEL_SSE - /* Only check for SSE if the build configuration has been modified to - * enable SSE optimizations. This means that these optimizations will - * be off by default. See contrib/intel for more details. - */ -# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ - defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ - (defined(_M_IX86_FP) && _M_IX86_FP >= 2) -# define PNG_INTEL_SSE_OPT 1 -# else -# define PNG_INTEL_SSE_OPT 0 -# endif -# else -# define PNG_INTEL_SSE_OPT 0 -# endif -#endif - -#if PNG_INTEL_SSE_OPT > 0 -# ifndef PNG_INTEL_SSE_IMPLEMENTATION -# if defined(__SSE4_1__) || defined(__AVX__) - /* We are not actually using AVX, but checking for AVX is the best - way we can detect SSE4.1 and SSSE3 on MSVC. - */ -# define PNG_INTEL_SSE_IMPLEMENTATION 3 -# elif defined(__SSSE3__) -# define PNG_INTEL_SSE_IMPLEMENTATION 2 -# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ - (defined(_M_IX86_FP) && _M_IX86_FP >= 2) -# define PNG_INTEL_SSE_IMPLEMENTATION 1 -# else -# define PNG_INTEL_SSE_IMPLEMENTATION 0 -# endif -# endif - -# if PNG_INTEL_SSE_IMPLEMENTATION > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2 -# endif -#else -# define PNG_INTEL_SSE_IMPLEMENTATION 0 -#endif - -#if PNG_MIPS_MSA_OPT > 0 -# ifndef PNG_MIPS_MSA_IMPLEMENTATION -# if defined(__mips_msa) -# if defined(__clang__) -# elif defined(__GNUC__) -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) -# define PNG_MIPS_MSA_IMPLEMENTATION 2 -# endif /* no GNUC support */ -# endif /* __GNUC__ */ -# else /* !defined __mips_msa */ -# define PNG_MIPS_MSA_IMPLEMENTATION 2 -# endif /* __mips_msa */ -# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */ - -# ifndef PNG_MIPS_MSA_IMPLEMENTATION -# define PNG_MIPS_MSA_IMPLEMENTATION 1 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips -# endif -#else -# define PNG_MIPS_MSA_IMPLEMENTATION 0 -#endif /* PNG_MIPS_MSA_OPT > 0 */ - -#if PNG_MIPS_MMI_OPT > 0 -# ifndef PNG_MIPS_MMI_IMPLEMENTATION -# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) -# define PNG_MIPS_MMI_IMPLEMENTATION 2 -# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */ -# define PNG_MIPS_MMI_IMPLEMENTATION 0 -# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */ -# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */ - -# if PNG_MIPS_MMI_IMPLEMENTATION > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips -# endif -#else -# define PNG_MIPS_MMI_IMPLEMENTATION 0 -#endif /* PNG_MIPS_MMI_OPT > 0 */ - -#if PNG_POWERPC_VSX_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx -# define PNG_POWERPC_VSX_IMPLEMENTATION 1 -#else -# define PNG_POWERPC_VSX_IMPLEMENTATION 0 -#endif - -#if PNG_LOONGARCH_LSX_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx -# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1 -#else -# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 -#endif - -/* Is this a build of a DLL where compilation of the object modules requires - * different preprocessor settings to those required for a simple library? If - * so PNG_BUILD_DLL must be set. - * - * If libpng is used inside a DLL but that DLL does not export the libpng APIs - * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a - * static library of libpng then link the DLL against that. - */ -#ifndef PNG_BUILD_DLL -# ifdef DLL_EXPORT - /* This is set by libtool when files are compiled for a DLL; libtool - * always compiles twice, even on systems where it isn't necessary. Set - * PNG_BUILD_DLL in case it is necessary: - */ -# define PNG_BUILD_DLL -# else -# ifdef _WINDLL - /* This is set by the Microsoft Visual Studio IDE in projects that - * build a DLL. It can't easily be removed from those projects (it - * isn't visible in the Visual Studio UI) so it is a fairly reliable - * indication that PNG_IMPEXP needs to be set to the DLL export - * attributes. - */ -# define PNG_BUILD_DLL -# else -# ifdef __DLL__ - /* This is set by the Borland C system when compiling for a DLL - * (as above.) - */ -# define PNG_BUILD_DLL -# else - /* Add additional compiler cases here. */ -# endif -# endif -# endif -#endif /* Setting PNG_BUILD_DLL if required */ - -/* See pngconf.h for more details: the builder of the library may set this on - * the command line to the right thing for the specific compilation system or it - * may be automagically set above (at present we know of no system where it does - * need to be set on the command line.) - * - * PNG_IMPEXP must be set here when building the library to prevent pngconf.h - * setting it to the "import" setting for a DLL build. - */ -#ifndef PNG_IMPEXP -# ifdef PNG_BUILD_DLL -# define PNG_IMPEXP PNG_DLL_EXPORT -# else - /* Not building a DLL, or the DLL doesn't require specific export - * definitions. - */ -# define PNG_IMPEXP -# endif -#endif - -/* No warnings for private or deprecated functions in the build: */ -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE -#endif - -/* Symbol preprocessing support. - * - * To enable listing global, but internal, symbols the following macros should - * always be used to declare an extern data or function object in this file. - */ -#ifndef PNG_INTERNAL_DATA -# define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array -#endif - -#ifndef PNG_INTERNAL_FUNCTION -# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ - PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) -#endif - -#ifndef PNG_INTERNAL_CALLBACK -# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ - PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\ - PNG_EMPTY attributes) -#endif - -/* If floating or fixed point APIs are disabled they may still be compiled - * internally. To handle this make sure they are declared as the appropriate - * internal extern function (otherwise the symbol prefixing stuff won't work and - * the functions will be used without definitions.) - * - * NOTE: although all the API functions are declared here they are not all - * actually built! Because the declarations are still made it is necessary to - * fake out types that they depend on. - */ -#ifndef PNG_FP_EXPORT -# ifndef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -# ifndef PNG_VERSION_INFO_ONLY - typedef struct png_incomplete png_double; - typedef png_double* png_doublep; - typedef const png_double* png_const_doublep; - typedef png_double** png_doublepp; -# endif -# endif -#endif -#ifndef PNG_FIXED_EXPORT -# ifndef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -# endif -#endif - -#include "png.h" - -/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ -#ifndef PNG_DLL_EXPORT -# define PNG_DLL_EXPORT -#endif - -/* This is a global switch to set the compilation for an installed system - * (a release build). It can be set for testing debug builds to ensure that - * they will compile when the build type is switched to RC or STABLE, the - * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS - * with either: - * - * -DPNG_RELEASE_BUILD Turns on the release compile path - * -DPNG_RELEASE_BUILD=0 Turns it off - * or in your pngusr.h with - * #define PNG_RELEASE_BUILD=1 Turns on the release compile path - * #define PNG_RELEASE_BUILD=0 Turns it off - */ -#ifndef PNG_RELEASE_BUILD -# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) -#endif - -/* SECURITY and SAFETY: - * - * libpng is built with support for internal limits on image dimensions and - * memory usage. These are documented in scripts/pnglibconf.dfa of the - * source and recorded in the machine generated header file pnglibconf.h. - */ - -/* If you are running on a machine where you cannot allocate more - * than 64K of memory at once, uncomment this. While libpng will not - * normally need that much memory in a chunk (unless you load up a very - * large file), zlib needs to know how big of a chunk it can use, and - * libpng thus makes sure to check any memory allocation to verify it - * will fit into memory. - * - * zlib provides 'MAXSEG_64K' which, if defined, indicates the - * same limit and pngconf.h (already included) sets the limit - * if certain operating systems are detected. - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) -# define PNG_MAX_MALLOC_64K -#endif - -#ifndef PNG_UNUSED -/* Unused formal parameter warnings are silenced using the following macro - * which is expected to have no bad effects on performance (optimizing - * compilers will probably remove it entirely). Note that if you replace - * it with something other than whitespace, you must include the terminating - * semicolon. - */ -# define PNG_UNUSED(param) (void)param; -#endif - -/* Just a little check that someone hasn't tried to define something - * contradictory. - */ -#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) -# undef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 65536L -#endif - -/* If warnings or errors are turned off the code is disabled or redirected here. - * From 1.5.4 functions have been added to allow very limited formatting of - * error and warning messages - this code will also be disabled here. - */ -#ifdef PNG_WARNINGS_SUPPORTED -# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; -#else -# define png_warning_parameter(p,number,string) ((void)0) -# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) -# define png_warning_parameter_signed(p,number,format,value) ((void)0) -# define png_formatted_warning(pp,p,message) ((void)(pp)) -# define PNG_WARNING_PARAMETERS(p) -#endif -#ifndef PNG_ERROR_TEXT_SUPPORTED -# define png_fixed_error(s1,s2) png_err(s1) -#endif - -/* Some fixed point APIs are still required even if not exported because - * they get used by the corresponding floating point APIs. This magic - * deals with this: - */ -#ifdef PNG_FIXED_POINT_SUPPORTED -# define PNGFAPI PNGAPI -#else -# define PNGFAPI /* PRIVATE */ -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Other defines specific to compilers can go here. Try to keep - * them inside an appropriate ifdef/endif pair for portability. - */ - -/* C allows up-casts from (void*) to any pointer and (const void*) to any - * pointer to a const object. C++ regards this as a type error and requires an - * explicit, static, cast and provides the static_cast<> rune to ensure that - * const is not cast away. - */ -#ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -# define png_constcast(type, value) const_cast(value) -# define png_aligncast(type, value) \ - static_cast(static_cast(value)) -# define png_aligncastconst(type, value) \ - static_cast(static_cast(value)) -#else -# define png_voidcast(type, value) (value) -# define png_constcast(type, value) ((type)(void*)(const void*)(value)) -# define png_aligncast(type, value) ((void*)(value)) -# define png_aligncastconst(type, value) ((const void*)(value)) -#endif /* __cplusplus */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - /* png.c requires the following ANSI-C constants if the conversion of - * floating point to ASCII is implemented therein: - * - * DBL_DIG Maximum number of decimal digits (can be set to any constant) - * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) - * DBL_MAX Maximum floating point number (can be set to an arbitrary value) - */ -# include - -# include - -# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) - /* Amiga SAS/C: We must include builtin FPU functions when compiling using - * MATH=68881 - */ -# include -# endif -#endif - -/* This provides the non-ANSI (far) memory allocation routines. */ -#if defined(__TURBOC__) && defined(__MSDOS__) -# include -# include -#endif - -#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) -# include -#endif -#endif /* PNG_VERSION_INFO_ONLY */ - -/* Moved here around 1.5.0beta36 from pngconf.h */ -/* Users may want to use these so they are not private. Any library - * functions that are passed far data must be model-independent. - */ - -/* Platform-independent functions */ -#ifndef PNG_ABORT -# define PNG_ABORT() abort() -#endif - -/* These macros may need to be architecture dependent. */ -#define PNG_ALIGN_NONE 0 /* do not use data alignment */ -#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ -#ifdef offsetof -# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ -#else -# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ -#endif -#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ - -#ifndef PNG_ALIGN_TYPE - /* Default to using aligned access optimizations and requiring alignment to a - * multiple of the data type size. Override in a compiler specific fashion - * if necessary by inserting tests here: - */ -# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE -#endif - -#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE - /* This is used because in some compiler implementations non-aligned - * structure members are supported, so the offsetof approach below fails. - * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access - * is good for performance. Do not do this unless you have tested the - * result and understand it. - */ -# define png_alignof(type) (sizeof(type)) -#else -# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET -# define png_alignof(type) offsetof(struct{char c; type t;}, t) -# else -# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS -# define png_alignof(type) 1 -# endif - /* Else leave png_alignof undefined to prevent use thereof */ -# endif -#endif - -/* This implicitly assumes alignment is always a multiple of 2. */ -#ifdef png_alignof -# define png_isaligned(ptr, type) \ - (((type)(size_t)((const void*)(ptr)) & (type)(png_alignof(type)-1)) == 0) -#else -# define png_isaligned(ptr, type) 0 -#endif - -/* End of memory model/platform independent support */ -/* End of 1.5.0beta36 move from pngconf.h */ - -/* CONSTANTS and UTILITY MACROS - * These are used internally by libpng and not exposed in the API - */ - -/* Various modes of operation. Note that after an init, mode is set to - * zero automatically when the structure is created. Three of these - * are defined in png.h because they need to be visible to applications - * that call png_set_unknown_chunk(). - */ -/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */ -/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */ -#define PNG_HAVE_IDAT 0x04U -/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */ -#define PNG_HAVE_IEND 0x10U - /* 0x20U (unused) */ - /* 0x40U (unused) */ - /* 0x80U (unused) */ -#define PNG_HAVE_CHUNK_HEADER 0x100U -#define PNG_WROTE_tIME 0x200U -#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U -#define PNG_BACKGROUND_IS_GRAY 0x800U -#define PNG_HAVE_PNG_SIGNATURE 0x1000U -#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */ -#define PNG_WROTE_eXIf 0x4000U -#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */ - -/* Flags for the transformations the PNG library does on the image data */ -#define PNG_BGR 0x0001U -#define PNG_INTERLACE 0x0002U -#define PNG_PACK 0x0004U -#define PNG_SHIFT 0x0008U -#define PNG_SWAP_BYTES 0x0010U -#define PNG_INVERT_MONO 0x0020U -#define PNG_QUANTIZE 0x0040U -#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */ -#define PNG_BACKGROUND_EXPAND 0x0100U -#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */ -#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */ -#define PNG_RGBA 0x0800U -#define PNG_EXPAND 0x1000U -#define PNG_GAMMA 0x2000U -#define PNG_GRAY_TO_RGB 0x4000U -#define PNG_FILLER 0x8000U -#define PNG_PACKSWAP 0x10000U -#define PNG_SWAP_ALPHA 0x20000U -#define PNG_STRIP_ALPHA 0x40000U -#define PNG_INVERT_ALPHA 0x80000U -#define PNG_USER_TRANSFORM 0x100000U -#define PNG_RGB_TO_GRAY_ERR 0x200000U -#define PNG_RGB_TO_GRAY_WARN 0x400000U -#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */ -#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */ -#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */ -#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */ -#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */ - /* 0x8000000U unused */ - /* 0x10000000U unused */ - /* 0x20000000U unused */ - /* 0x40000000U unused */ -/* Flags for png_create_struct */ -#define PNG_STRUCT_PNG 0x0001U -#define PNG_STRUCT_INFO 0x0002U - -/* Flags for the png_ptr->flags rather than declaring a byte for each one */ -#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U -#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */ - /* 0x0004U unused */ -#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */ - /* 0x0010U unused */ - /* 0x0020U unused */ -#define PNG_FLAG_ROW_INIT 0x0040U -#define PNG_FLAG_FILLER_AFTER 0x0080U -#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U -#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U -#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U -#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U -#define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */ -#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */ -#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */ -/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */ -/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */ -#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U -#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U -#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U -#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */ -#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */ -#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */ - /* 0x800000U unused */ - /* 0x1000000U unused */ - /* 0x2000000U unused */ - /* 0x4000000U unused */ - /* 0x8000000U unused */ - /* 0x10000000U unused */ - /* 0x20000000U unused */ - /* 0x40000000U unused */ - -#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ - PNG_FLAG_CRC_ANCILLARY_NOWARN) - -#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ - PNG_FLAG_CRC_CRITICAL_IGNORE) - -#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ - PNG_FLAG_CRC_CRITICAL_MASK) - -/* Save typing and make code easier to understand */ - -#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ - abs((int)((c1).green) - (int)((c2).green)) + \ - abs((int)((c1).blue) - (int)((c2).blue))) - -/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 - * by dividing by 257 *with rounding*. This macro is exact for the given range. - * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the - * macro were established by experiment (modifying the added value). The macro - * has a second variant that takes a value already scaled by 255 and divides by - * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it - * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. - */ -#define PNG_DIV65535(v24) (((v24) + 32895) >> 16) -#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255) - -/* Added to libpng-1.2.6 JB */ -#define PNG_ROWBYTES(pixel_bits, width) \ - ((pixel_bits) >= 8 ? \ - ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \ - (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) ) - -/* This returns the number of trailing bits in the last byte of a row, 0 if the - * last byte is completely full of pixels. It is, in principle, (pixel_bits x - * width) % 8, but that would overflow for large 'width'. The second macro is - * the same except that it returns the number of unused bits in the last byte; - * (8-TRAILBITS), but 0 when TRAILBITS is 0. - * - * NOTE: these macros are intended to be self-evidently correct and never - * overflow on the assumption that pixel_bits is in the range 0..255. The - * arguments are evaluated only once and they can be signed (e.g. as a result of - * the integral promotions). The result of the expression always has type - * (png_uint_32), however the compiler always knows it is in the range 0..7. - */ -#define PNG_TRAILBITS(pixel_bits, width) \ - (((pixel_bits) * ((width) % (png_uint_32)8)) % 8) - -#define PNG_PADBITS(pixel_bits, width) \ - ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8) - -/* PNG_OUT_OF_RANGE returns true if value is outside the range - * ideal-delta..ideal+delta. Each argument is evaluated twice. - * "ideal" and "delta" should be constants, normally simple - * integers, "value" a variable. Added to libpng-1.2.6 JB - */ -#define PNG_OUT_OF_RANGE(value, ideal, delta) \ - ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) - -/* Conversions between fixed and floating point, only defined if - * required (to make sure the code doesn't accidentally use float - * when it is supposedly disabled.) - */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* The floating point conversion can't overflow, though it can and - * does lose accuracy relative to the original fixed point value. - * In practice this doesn't matter because png_fixed_point only - * stores numbers with very low precision. The png_ptr and s - * arguments are unused by default but are there in case error - * checking becomes a requirement. - */ -#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) - -/* The fixed point conversion performs range checking and evaluates - * its argument multiple times, so must be used with care. The - * range checking uses the PNG specification values for a signed - * 32-bit fixed point value except that the values are deliberately - * rounded-to-zero to an integral value - 21474 (21474.83 is roughly - * (2^31-1) * 100000). 's' is a string that describes the value being - * converted. - * - * NOTE: this macro will raise a png_error if the range check fails, - * therefore it is normally only appropriate to use this on values - * that come from API calls or other sources where an out of range - * error indicates a programming error, not a data error! - * - * NOTE: by default this is off - the macro is not used - because the - * function call saves a lot of code. - */ -#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED -#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ - ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) -#endif -/* else the corresponding function is defined below, inside the scope of the - * cplusplus test. - */ -#endif - -/* Constants for known chunk types. If you need to add a chunk, define the name - * here. For historical reasons these constants have the form png_; i.e. - * the prefix is lower case. Please use decimal values as the parameters to - * match the ISO PNG specification and to avoid relying on the C locale - * interpretation of character values. - * - * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values - * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string - * to be generated if required. - * - * PNG_32b correctly produces a value shifted by up to 24 bits, even on - * architectures where (int) is only 16 bits. - */ -#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) -#define PNG_U32(b1,b2,b3,b4) \ - (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) - -/* Constants for known chunk types. - * - * MAINTAINERS: If you need to add a chunk, define the name here. - * For historical reasons these constants have the form png_; i.e. - * the prefix is lower case. Please use decimal values as the parameters to - * match the ISO PNG specification and to avoid relying on the C locale - * interpretation of character values. Please keep the list sorted. - * - * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk - * type. In fact the specification does not express chunk types this way, - * however using a 32-bit value means that the chunk type can be read from the - * stream using exactly the same code as used for a 32-bit unsigned value and - * can be examined far more efficiently (using one arithmetic compare). - * - * Prior to 1.5.6 the chunk type constants were expressed as C strings. The - * libpng API still uses strings for 'unknown' chunks and a macro, - * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice - * that for portable code numeric values must still be used; the string "IHDR" - * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). - * - * In 1.7.0 the definitions will be made public in png.h to avoid having to - * duplicate the same definitions in application code. - */ -#define png_IDAT PNG_U32( 73, 68, 65, 84) -#define png_IEND PNG_U32( 73, 69, 78, 68) -#define png_IHDR PNG_U32( 73, 72, 68, 82) -#define png_PLTE PNG_U32( 80, 76, 84, 69) -#define png_bKGD PNG_U32( 98, 75, 71, 68) -#define png_cHRM PNG_U32( 99, 72, 82, 77) -#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */ -#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ -#define png_gAMA PNG_U32(103, 65, 77, 65) -#define png_gIFg PNG_U32(103, 73, 70, 103) -#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ -#define png_gIFx PNG_U32(103, 73, 70, 120) -#define png_hIST PNG_U32(104, 73, 83, 84) -#define png_iCCP PNG_U32(105, 67, 67, 80) -#define png_iTXt PNG_U32(105, 84, 88, 116) -#define png_oFFs PNG_U32(111, 70, 70, 115) -#define png_pCAL PNG_U32(112, 67, 65, 76) -#define png_pHYs PNG_U32(112, 72, 89, 115) -#define png_sBIT PNG_U32(115, 66, 73, 84) -#define png_sCAL PNG_U32(115, 67, 65, 76) -#define png_sPLT PNG_U32(115, 80, 76, 84) -#define png_sRGB PNG_U32(115, 82, 71, 66) -#define png_sTER PNG_U32(115, 84, 69, 82) -#define png_tEXt PNG_U32(116, 69, 88, 116) -#define png_tIME PNG_U32(116, 73, 77, 69) -#define png_tRNS PNG_U32(116, 82, 78, 83) -#define png_zTXt PNG_U32(122, 84, 88, 116) - -/* The following will work on (signed char*) strings, whereas the get_uint_32 - * macro will fail on top-bit-set values because of the sign extension. - */ -#define PNG_CHUNK_FROM_STRING(s)\ - PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3]) - -/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is - * signed and the argument is a (char[]) This macro will fail miserably on - * systems where (char) is more than 8 bits. - */ -#define PNG_STRING_FROM_CHUNK(s,c)\ - (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \ - ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\ - ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \ - ((char*)(s))[3]=(char)((c & 0xff))) - -/* Do the same but terminate with a null character. */ -#define PNG_CSTRING_FROM_CHUNK(s,c)\ - (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) - -/* Test on flag values as defined in the spec (section 5.4): */ -#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) -#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) -#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) -#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) -#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) - -/* Gamma values (new at libpng-1.5.4): */ -#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ -#define PNG_GAMMA_MAC_INVERSE 65909 -#define PNG_GAMMA_sRGB_INVERSE 45455 - -/* Almost everything below is C specific; the #defines above can be used in - * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. - */ -#ifndef PNG_VERSION_INFO_ONLY - -#include "pngstruct.h" -#include "pnginfo.h" - -/* Validate the include paths - the include path used to generate pnglibconf.h - * must match that used in the build, or we must be using pnglibconf.h.prebuilt: - */ -#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM -# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ - "-I (include path) error: see the notes in pngpriv.h" - /* This means that when pnglibconf.h was built the copy of zlib.h that it - * used is not the same as the one being used here. Because the build of - * libpng makes decisions to use inflateInit2 and inflateReset2 based on the - * zlib version number and because this affects handling of certain broken - * PNG files the -I directives must match. - * - * The most likely explanation is that you passed a -I in CFLAGS. This will - * not work; all the preprocessor directives and in particular all the -I - * directives must be in CPPFLAGS. - */ -#endif - -/* This is used for 16-bit gamma tables -- only the top level pointers are - * const; this could be changed: - */ -typedef const png_uint_16p * png_const_uint_16pp; - -/* Added to libpng-1.5.7: sRGB conversion tables */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); - /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, - * 0..65535. This table gives the closest 16-bit answers (no errors). - */ -#endif - -PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); -PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); - -#define PNG_sRGB_FROM_LINEAR(linear) \ - ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \ - + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))) - /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB - * encoded value with maximum error 0.646365. Note that the input is not a - * 16-bit value; it has been multiplied by 255! */ -#endif /* SIMPLIFIED_READ/WRITE */ - - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Internal functions; these are not exported from a DLL however because they - * are used within several of the C source files they have to be C extern. - * - * All of these functions must be declared with PNG_INTERNAL_FUNCTION. - */ - -/* Zlib support */ -#define PNG_UNEXPECTED_ZLIB_RETURN (-7) -PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret), - PNG_EMPTY); - /* Used by the zlib handling functions to ensure that z_stream::msg is always - * set before they return. - */ - -#ifdef PNG_WRITE_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr, - png_compression_bufferp *list),PNG_EMPTY); - /* Free the buffer list used by the compressed write code. */ -#endif - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_sCAL_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) -PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr, - double fp, png_const_charp text),PNG_EMPTY); -#endif - -/* Check the user version string for compatibility, returns false if the version - * numbers aren't compatible. - */ -PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr, - png_const_charp user_png_ver),PNG_EMPTY); - -/* Internal base allocator - no messages, NULL on failure to allocate. This - * does, however, call the application provided allocator and that could call - * png_error (although that would be a bug in the application implementation.) - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr, - png_alloc_size_t size),PNG_ALLOCATED); - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ - defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -/* Internal array allocator, outputs no error or warning messages on failure, - * just returns NULL. - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr, - int nelements, size_t element_size),PNG_ALLOCATED); - -/* The same but an existing array is extended by add_elements. This function - * also memsets the new elements to 0 and copies the old elements. The old - * array is not freed or altered. - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr, - png_const_voidp array, int old_elements, int add_elements, - size_t element_size),PNG_ALLOCATED); -#endif /* text, sPLT or unknown chunks */ - -/* Magic to create a struct when there is no struct to call the user supplied - * memory allocators. Because error handling has not been set up the memory - * handlers can't safely call png_error, but this is an obscure and undocumented - * restriction so libpng has to assume that the 'free' handler, at least, might - * call png_error. - */ -PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, - png_free_ptr free_fn),PNG_ALLOCATED); - -/* Free memory from internal libpng struct */ -PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr), - PNG_EMPTY); - -/* Free an allocated jmp_buf (always succeeds) */ -PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY); - -/* Function to allocate memory for zlib. PNGAPI is disallowed. */ -PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size), - PNG_ALLOCATED); - -/* Function to free memory for zlib. PNGAPI is disallowed. */ -PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); - -/* Next four functions are used internally as callbacks. PNGCBAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to - * PNGCBAPI at 1.5.0 - */ - -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, - png_bytep data, size_t length),PNG_EMPTY); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, - png_bytep buffer, size_t length),PNG_EMPTY); -#endif - -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, - png_bytep data, size_t length),PNG_EMPTY); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr), - PNG_EMPTY); -# endif -#endif - -/* Reset the CRC variable */ -PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY); - -/* Write the "data" buffer to whatever output you are using */ -PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, - png_const_bytep data, size_t length),PNG_EMPTY); - -/* Read and check the PNG file signature */ -PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); - -/* Read the chunk header (length + type name) */ -PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr), - PNG_EMPTY); - -/* Read data from whatever input you are using into the "data" buffer */ -PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data, - size_t length),PNG_EMPTY); - -/* Read bytes into buf, and update png_ptr->crc */ -PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, - png_uint_32 length),PNG_EMPTY); - -/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ -PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, - png_uint_32 skip),PNG_EMPTY); - -/* Read the CRC from the file and compare it to the libpng calculated CRC */ -PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); - -/* Calculate the CRC over a section of data. Note that we are only - * passing a maximum of 64K on systems that have this as a memory limit, - * since this is the maximum buffer size we can specify. - */ -PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, - png_const_bytep ptr, size_t length),PNG_EMPTY); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY); -#endif - -/* Write various chunks */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. - */ -PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, - int compression_method, int filter_method, int interlace_method),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr, - png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr, - png_const_bytep row_data, png_alloc_size_t row_data_length, int flush), - PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY); - -#ifdef PNG_WRITE_gAMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr, - png_fixed_point file_gamma),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, - png_const_color_8p sbit, int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, - const png_xy *xy), PNG_EMPTY); - /* The xy value must have been previously validated */ -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, - int intent),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr, - png_bytep exif, int num_exif),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, - png_const_charp name, png_const_bytep profile), PNG_EMPTY); - /* The profile must have been previously validated for correctness, the - * length comes from the first four bytes. Only the base, deflate, - * compression is supported. - */ -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, - png_const_sPLT_tp palette),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr, - png_const_bytep trans, png_const_color_16p values, int number, - int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr, - png_const_color_16p values, int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, - png_const_uint_16p hist, int num_hist),PNG_EMPTY); -#endif - -/* Chunks that have keywords */ -#ifdef PNG_WRITE_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, - png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp - key, png_const_charp text, int compression),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr, - int compression, png_const_charp key, png_const_charp lang, - png_const_charp lang_key, png_const_charp text),PNG_EMPTY); -#endif - -#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ -PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr, - png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr, - png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, - png_const_charp units, png_charpp params),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr, - png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, - int unit_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr, - png_const_timep mod_time),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr, - int unit, png_const_charp width, png_const_charp height),PNG_EMPTY); -#endif - -/* Called when finished processing a row of data */ -PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr), - PNG_EMPTY); - -/* Internal use only. Called before first row of data */ -PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr), - PNG_EMPTY); - -/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an - * array of png_ptr->width pixels. If the image is not interlaced or this - * is the final pass this just does a memcpy, otherwise the "display" flag - * is used to determine whether to copy pixels that are not in the current pass. - * - * Because 'png_do_read_interlace' (below) replicates pixels this allows this - * function to achieve the documented 'blocky' appearance during interlaced read - * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' - * are not changed if they are not in the current pass, when display is 0. - * - * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. - * - * The API always reads from the png_struct row buffer and always assumes that - * it is full width (png_do_read_interlace has already been called.) - * - * This function is only ever used to write to row buffers provided by the - * caller of the relevant libpng API and the row must have already been - * transformed by the read transformations. - * - * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed - * bitmasks for use within the code, otherwise runtime generated masks are used. - * The default is compile time masks. - */ -#ifndef PNG_USE_COMPILE_TIME_MASKS -# define PNG_USE_COMPILE_TIME_MASKS 1 -#endif -PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr, - png_bytep row, int display),PNG_EMPTY); - -#ifdef PNG_READ_INTERLACING_SUPPORTED -/* Expand an interlaced row: the 'row_info' describes the pass data that has - * been read in and must correspond to the pixels in 'row', the pixels are - * expanded (moved apart) in 'row' to match the final layout, when doing this - * the pixels are *replicated* to the intervening space. This is essential for - * the correct operation of png_combine_row, above. - */ -PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info, - png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY); -#endif - -/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Grab pixels out of a row for an interlaced pass */ -PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info, - png_bytep row, int pass),PNG_EMPTY); -#endif - -/* Unfilter a row: check the filter value before calling this, there is no point - * calling it for PNG_FILTER_VALUE_NONE. - */ -PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop - row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY); - -#if PNG_ARM_NEON_OPT > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_MIPS_MSA_IMPLEMENTATION == 1 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_MIPS_MMI_IMPLEMENTATION > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_POWERPC_VSX_OPT > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_INTEL_SSE_IMPLEMENTATION > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -/* Choose the best filter to use and filter the row data */ -PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, - png_row_infop row_info),PNG_EMPTY); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr, - png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY); - /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer - * is NULL the function checks, instead, for the end of the stream. In this - * case a benign error will be issued if the stream end is not found or if - * extra data has to be consumed. - */ -PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr), - PNG_EMPTY); - /* This cleans up when the IDAT LZ stream does not end when the last image - * byte is read; there is still some pending input. - */ - -PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), - PNG_EMPTY); - /* Finish a row while reading, dealing with interlacing passes, etc. */ -#endif /* SEQUENTIAL_READ */ - -/* Initialize the row buffers, etc. */ -PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); - -#if ZLIB_VERNUM >= 0x1240 -PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush), - PNG_EMPTY); -# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush) -#else /* Zlib < 1.2.4 */ -# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush) -#endif /* Zlib < 1.2.4 */ - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -/* Optional call to update the users info structure */ -PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -#endif - -/* Shared transform functions, defined in pngtran.c */ -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info, - png_bytep row, int at_start),PNG_EMPTY); -#endif - -#ifdef PNG_16BIT_SUPPORTED -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif - -/* The following decodes the appropriate chunks, and does error correction, - * then calls the appropriate callback for the chunk if it is valid. - */ - -/* Decode the IHDR chunk */ -PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - -#ifdef PNG_READ_bKGD_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif /* READ_iCCP */ - -#ifdef PNG_READ_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif /* READ_sPLT */ - -#ifdef PNG_READ_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, - png_uint_32 chunk_name),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, - png_uint_32 chunk_length),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); - /* This is the function that gets called for unknown chunks. The 'keep' - * argument is either non-zero for a known chunk that has been set to be - * handled as unknown or zero for an unknown chunk. By default the function - * just skips the chunk or errors out if it is critical. - */ - -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling, - (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY); - /* Exactly as the API png_handle_as_unknown() except that the argument is a - * 32-bit chunk name, not a string. - */ -#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ - -/* Handle the transformations for reading and writing */ -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr, - png_row_infop row_info),PNG_EMPTY); -#endif -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr, - png_row_infop row_info),PNG_EMPTY); -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr), - PNG_EMPTY); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, - png_bytep buffer, size_t buffer_length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, - png_bytep buffer, size_t buffer_length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, - png_bytep row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), - PNG_EMPTY); -# ifdef PNG_READ_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif -# ifdef PNG_READ_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif -# ifdef PNG_READ_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif - -#endif /* PROGRESSIVE_READ */ - -/* Added at libpng version 1.6.0 */ -#ifdef PNG_GAMMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); - /* Set the colorspace gamma with a value provided by the application or by - * the gAMA chunk on read. The value will override anything set by an ICC - * profile. - */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Synchronize the info 'valid' flags with the colorspace */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Copy the png_struct colorspace to the info_struct and call the above to - * synchronize the flags. Checks for NULL info_ptr and does nothing. - */ -#endif - -/* Added at libpng version 1.4.0 */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* These internal functions are for maintaining the colorspace structure within - * a png_info or png_struct (or, indeed, both). - */ -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, - int preferred), PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, - int preferred), PNG_EMPTY); - -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, - png_colorspacerp colorspace, int intent), PNG_EMPTY); - /* This does set the colorspace gAMA and cHRM values too, but doesn't set the - * flags to write them, if it returns false there was a problem and an error - * message has already been output (but the colorspace may still need to be - * synced to record the invalid flag). - */ -#endif /* sRGB */ - -#ifdef PNG_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, png_const_bytep profile, int color_type), - PNG_EMPTY); - /* The 'name' is used for information only */ - -/* Routines for checking parts of an ICC profile. */ -#ifdef PNG_READ_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length), PNG_EMPTY); -#endif /* READ_iCCP */ -PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, - png_const_bytep profile /* first 132 bytes only */, int color_type), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( - png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_bytep profile, uLong adler), PNG_EMPTY); - /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may - * be zero to indicate that it is not available. It is used, if provided, - * as a fast check on the profile when checking to see if it is sRGB. - */ -#endif -#endif /* iCCP */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients, - (png_structrp png_ptr), PNG_EMPTY); - /* Set the rgb_to_gray coefficients from the colorspace Y values */ -#endif /* READ_RGB_TO_GRAY */ -#endif /* COLORSPACE */ - -/* Added at libpng version 1.4.0 */ -PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type),PNG_EMPTY); - -/* Added at libpng version 1.5.10 */ -#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ - defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes, - (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); -#endif - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr, - png_const_charp name),PNG_NORETURN); -#endif - -/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite - * the end. Always leaves the buffer nul terminated. Never errors out (and - * there is no error code.) - */ -PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize, - size_t pos, png_const_charp string),PNG_EMPTY); - -/* Various internal functions to handle formatted warning messages, currently - * only implemented for warnings. - */ -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. This utility only - * does unsigned values. - */ -PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start, - png_charp end, int format, png_alloc_size_t number),PNG_EMPTY); - -/* Convenience macro that takes an array: */ -#define PNG_FORMAT_NUMBER(buffer,format,number) \ - png_format_number(buffer, buffer + (sizeof buffer), format, number) - -/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ -#define PNG_NUMBER_BUFFER_SIZE 24 - -/* These are the integer formats currently supported, the name is formed from - * the standard printf(3) format string. - */ -#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ -#define PNG_NUMBER_FORMAT_02u 2 -#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ -#define PNG_NUMBER_FORMAT_02d 2 -#define PNG_NUMBER_FORMAT_x 3 -#define PNG_NUMBER_FORMAT_02x 4 -#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* New defines and members adding in libpng-1.5.4 */ -# define PNG_WARNING_PARAMETER_SIZE 32 -# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */ - -/* An l-value of this type has to be passed to the APIs below to cache the - * values of the parameters to a formatted warning message. - */ -typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ - PNG_WARNING_PARAMETER_SIZE]; - -PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p, - int number, png_const_charp string),PNG_EMPTY); - /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, - * including the trailing '\0'. - */ -PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned, - (png_warning_parameters p, int number, int format, png_alloc_size_t value), - PNG_EMPTY); - /* Use png_alloc_size_t because it is an unsigned type as big as any we - * need to output. Use the following for a signed value. - */ -PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed, - (png_warning_parameters p, int number, int format, png_int_32 value), - PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr, - png_warning_parameters p, png_const_charp message),PNG_EMPTY); - /* 'message' follows the X/Open approach of using @1, @2 to insert - * parameters previously supplied using the above functions. Errors in - * specifying the parameters will simply result in garbage substitutions. - */ -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Application errors (new in 1.6); use these functions (declared below) for - * errors in the parameters or order of API function calls on read. The - * 'warning' should be used for an error that can be handled completely; the - * 'error' for one which can be handled safely but which may lose application - * information or settings. - * - * By default these both result in a png_error call prior to release, while in a - * released version the 'warning' is just a warning. However if the application - * explicitly disables benign errors (explicitly permitting the code to lose - * information) they both turn into warnings. - * - * If benign errors aren't supported they end up as the corresponding base call - * (png_warning or png_error.) - */ -PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr, - png_const_charp message),PNG_EMPTY); - /* The application provided invalid parameters to an API function or called - * an API function at the wrong time, libpng can completely recover. - */ - -PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr, - png_const_charp message),PNG_EMPTY); - /* As above but libpng will ignore the call, or attempt some other partial - * recovery from the error. - */ -#else -# define png_app_warning(pp,s) png_warning(pp,s) -# define png_app_error(pp,s) png_error(pp,s) -#endif - -PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, - png_const_charp message, int error),PNG_EMPTY); - /* Report a recoverable issue in chunk data. On read this is used to report - * a problem found while reading a particular chunk and the - * png_chunk_benign_error or png_chunk_warning function is used as - * appropriate. On write this is used to report an error that comes from - * data set via an application call to a png_set_ API and png_app_error or - * png_app_warning is used as appropriate. - * - * The 'error' parameter must have one of the following values: - */ -#define PNG_CHUNK_WARNING 0 /* never an error */ -#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ -#define PNG_CHUNK_ERROR 2 /* always an error */ - -/* ASCII to FP interfaces, currently only implemented if sCAL - * support is required. - */ -#if defined(PNG_sCAL_SUPPORTED) -/* MAX_DIGITS is actually the maximum number of characters in an sCAL - * width or height, derived from the precision (number of significant - * digits - a build time settable option) and assumptions about the - * maximum ridiculous exponent. - */ -#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) - -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, - png_charp ascii, size_t size, double fp, unsigned int precision), - PNG_EMPTY); -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, - png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY); -#endif /* FIXED_POINT */ -#endif /* sCAL */ - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* An internal API to validate the format of a floating point number. - * The result is the index of the next character. If the number is - * not valid it will be the index of a character in the supposed number. - * - * The format of a number is defined in the PNG extensions specification - * and this API is strictly conformant to that spec, not anyone elses! - * - * The format as a regular expression is: - * - * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? - * - * or: - * - * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? - * - * The complexity is that either integer or fraction must be present and the - * fraction is permitted to have no digits only if the integer is present. - * - * NOTE: The dangling E problem. - * There is a PNG valid floating point number in the following: - * - * PNG floating point numbers are not greedy. - * - * Working this out requires *TWO* character lookahead (because of the - * sign), the parser does not do this - it will fail at the 'r' - this - * doesn't matter for PNG sCAL chunk values, but it requires more care - * if the value were ever to be embedded in something more complex. Use - * ANSI-C strtod if you need the lookahead. - */ -/* State table for the parser. */ -#define PNG_FP_INTEGER 0 /* before or in integer */ -#define PNG_FP_FRACTION 1 /* before or in fraction */ -#define PNG_FP_EXPONENT 2 /* before or in exponent */ -#define PNG_FP_STATE 3 /* mask for the above */ -#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ -#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ -#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ -#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ -#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ - -/* These three values don't affect the parser. They are set but not used. - */ -#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ -#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ -#define PNG_FP_NONZERO 256 /* A non-zero value */ -#define PNG_FP_STICKY 448 /* The above three flags */ - -/* This is available for the caller to store in 'state' if required. Do not - * call the parser after setting it (the parser sometimes clears it.) - */ -#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ - -/* Result codes for the parser (boolean - true means ok, false means - * not ok yet.) - */ -#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ -#define PNG_FP_OK 1 /* The number is valid */ - -/* Tests on the sticky non-zero and negative flags. To pass these checks - * the state must also indicate that the whole number is valid - this is - * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this - * is equivalent to PNG_FP_OK above.) - */ -#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) - /* NZ_MASK: the string is valid and a non-zero negative value */ -#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) - /* Z MASK: the string is valid and a non-zero value. */ - /* PNG_FP_SAW_DIGIT: the string is valid. */ -#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) -#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) -#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) - -/* The actual parser. This can be called repeatedly. It updates - * the index into the string and the state variable (which must - * be initialized to 0). It returns a result code, as above. There - * is no point calling the parser any more if it fails to advance to - * the end of the string - it is stuck on an invalid character (or - * terminated by '\0'). - * - * Note that the pointer will consume an E or even an E+ and then leave - * a 'maybe' state even though a preceding integer.fraction is valid. - * The PNG_FP_WAS_VALID flag indicates that a preceding substring was - * a valid number. It's possible to recover from this by calling - * the parser again (from the start, with state 0) but with a string - * that omits the last character (i.e. set the size to the index of - * the problem character.) This has not been tested within libpng. - */ -PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, - size_t size, int *statep, size_t *whereami),PNG_EMPTY); - -/* This is the same but it checks a complete string and returns true - * only if it just contains a floating point number. As of 1.5.4 this - * function also returns the state at the end of parsing the number if - * it was valid (otherwise it returns 0.) This can be used for testing - * for negative or zero values using the sticky flag. - */ -PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, - size_t size),PNG_EMPTY); -#endif /* pCAL || sCAL */ - -#if defined(PNG_GAMMA_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* Added at libpng version 1.5.0 */ -/* This is a utility to provide a*times/div (rounded) and indicate - * if there is an overflow. The result is a boolean - false (0) - * for overflow, true (1) if no overflow, in which case *res - * holds the result. - */ -PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, - png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* Same deal, but issue a warning on overflow and return 0. */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn, - (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by, - png_int_32 divided_by),PNG_EMPTY); -#endif - -#ifdef PNG_GAMMA_SUPPORTED -/* Calculate a reciprocal - used for gamma values. This returns - * 0 if the argument is 0 in order to maintain an undefined value; - * there are no warnings. - */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), - PNG_EMPTY); - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* The same but gives a reciprocal of the product of two fixed point - * values. Accuracy is suitable for gamma calculations but this is - * not exact - use png_muldiv for that. Only required at present on read. - */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a, - png_fixed_point b),PNG_EMPTY); -#endif - -/* Return true if the gamma value is significantly different from 1.0 */ -PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value), - PNG_EMPTY); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Internal fixed point gamma correction. These APIs are called as - * required to convert single values - they don't need to be fast, - * they are not used when processing image pixel values. - * - * While the input is an 'unsigned' value it must actually be the - * correct bit value - 0..255 or 0..65535 as required. - */ -PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr, - unsigned int value, png_fixed_point gamma_value),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value, - png_fixed_point gamma_value),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value, - png_fixed_point gamma_value),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr, - int bit_depth),PNG_EMPTY); -#endif - -/* SIMPLIFIED READ/WRITE SUPPORT */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* The internal structure that png_image::opaque points to. */ -typedef struct png_control -{ - png_structp png_ptr; - png_infop info_ptr; - png_voidp error_buf; /* Always a jmp_buf at present. */ - - png_const_bytep memory; /* Memory buffer. */ - size_t size; /* Size of the memory buffer. */ - - unsigned int for_write :1; /* Otherwise it is a read structure */ - unsigned int owned_file :1; /* We own the file in io_ptr */ -} png_control; - -/* Return the pointer to the jmp_buf from a png_control: necessary because C - * does not reveal the type of the elements of jmp_buf. - */ -#ifdef __cplusplus -# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) -#else -# define png_control_jmp_buf(pc) ((pc)->error_buf) -#endif - -/* Utility to safely execute a piece of libpng code catching and logging any - * errors that might occur. Returns true on success, false on failure (either - * of the function or as a result of a png_error.) - */ -PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr, - png_const_charp error_message),PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr, - png_const_charp warning_message),PNG_EMPTY); -#else -# define png_safe_warning 0/*dummy argument*/ -#endif - -PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image, - int (*function)(png_voidp), png_voidp arg),PNG_EMPTY); - -/* Utility to log an error; this also cleans up the png_image; the function - * always returns 0 (false). - */ -PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image, - png_const_charp error_message),PNG_EMPTY); - -#ifndef PNG_SIMPLIFIED_READ_SUPPORTED -/* png_image_free is used by the write code but not exported */ -PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY); -#endif /* !SIMPLIFIED_READ */ - -#endif /* SIMPLIFIED READ/WRITE */ - -/* These are initialization functions for hardware specific PNG filter - * optimizations; list these here then select the appropriate one at compile - * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined - * the generic code is used. - */ -#ifdef PNG_FILTER_OPTIMIZATIONS -PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr, - unsigned int bpp), PNG_EMPTY); - /* Just declare the optimization that will be used */ -#else - /* List *all* the possible optimizations here - this branch is required if - * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in - * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. - */ -# if PNG_ARM_NEON_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -#endif - -#if PNG_MIPS_MSA_IMPLEMENTATION == 1 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -#endif - -# if PNG_MIPS_MMI_IMPLEMENTATION > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -# endif - -# if PNG_INTEL_SSE_IMPLEMENTATION > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -# endif -#endif - -#if PNG_LOONGARCH_LSX_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -#endif - -PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, - png_const_charp key, png_bytep new_key), PNG_EMPTY); - -#if PNG_ARM_NEON_IMPLEMENTATION == 1 -PNG_INTERNAL_FUNCTION(void, - png_riffle_palette_neon, - (png_structrp), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int, - png_do_expand_palette_rgba8_neon, - (png_structrp, - png_row_infop, - png_const_bytep, - const png_bytepp, - const png_bytepp), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int, - png_do_expand_palette_rgb8_neon, - (png_structrp, - png_row_infop, - png_const_bytep, - const png_bytepp, - const png_bytepp), - PNG_EMPTY); -#endif - -/* Maintainer: Put new private prototypes here ^ */ - -#include "pngdebug.h" - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -#endif /* PNGPRIV_H */ +/* pngpriv.h - private declarations for use inside libpng + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* The symbols declared in this file (including the functions declared + * as extern) are PRIVATE. They are not part of the libpng public + * interface, and are not recommended for use by regular applications. + * Some of them may become public in the future; others may stay private, + * change in an incompatible way, or even disappear. + * Although the libpng users are not forbidden to include this header, + * they should be well aware of the issues that may arise from doing so. + */ + + +/* pngpriv.h must be included first in each translation unit inside libpng. + * On the other hand, it must not be included at all, directly or indirectly, + * by any application code that uses the libpng API. + */ +#ifndef PNGPRIV_H +# define PNGPRIV_H + +/* Feature Test Macros. The following are defined here to ensure that correctly + * implemented libraries reveal the APIs libpng needs to build and hide those + * that are not needed and potentially damaging to the compilation. + * + * Feature Test Macros must be defined before any system header is included (see + * POSIX 1003.1 2.8.2 "POSIX Symbols." + * + * These macros only have an effect if the operating system supports either + * POSIX 1003.1 or C99, or both. On other operating systems (particularly + * Windows/Visual Studio) there is no effect; the OS specific tests below are + * still required (as of 2011-05-02.) + */ +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ +#endif + +#ifndef PNG_VERSION_INFO_ONLY +/* Standard library headers not required by png.h: */ +# include +# include +#endif + +#define PNGLIB_BUILD /*libpng is being built, not used*/ + +/* If HAVE_CONFIG_H is defined during the build then the build system must + * provide an appropriate "config.h" file on the include path. The header file + * must provide definitions as required below (search for "HAVE_CONFIG_H"); + * see configure.ac for more details of the requirements. The macro + * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on + * 'configure'; define this macro to prevent the configure build including the + * configure generated config.h. Libpng is expected to compile without *any* + * special build system support on a reasonably ANSI-C compliant system. + */ +#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) +# include + /* Pick up the definition of 'restrict' from config.h if it was read: */ +# define PNG_RESTRICT restrict +#endif + +/* To support symbol prefixing it is necessary to know *before* including png.h + * whether the fixed point (and maybe other) APIs are exported, because if they + * are not internal definitions may be required. This is handled below just + * before png.h is included, but load the configuration now if it is available. + */ +#include "pnglibconf.h" + +/* Local renames may change non-exported API functions from png.h */ +#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) +# include "pngprefix.h" +#endif + +#ifdef PNG_USER_CONFIG +# include "pngusr.h" + /* These should have been defined in pngusr.h */ +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD "Custom libpng build" +# endif +# ifndef PNG_USER_DLLFNAME_POSTFIX +# define PNG_USER_DLLFNAME_POSTFIX "Cb" +# endif +#endif + +/* Compile time options. + * ===================== + * In a multi-arch build the compiler may compile the code several times for the + * same object module, producing different binaries for different architectures. + * When this happens configure-time setting of the target host options cannot be + * done and this interferes with the handling of the ARM NEON optimizations, and + * possibly other similar optimizations. Put additional tests here; in general + * this is needed when the same option can be changed at both compile time and + * run time depending on the target OS (i.e. iOS vs Android.) + * + * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because + * this is not possible with certain compilers (Oracle SUN OS CC), as a result + * it is necessary to ensure that all extern functions that *might* be used + * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__ + * below is one example of this behavior because it is controlled by the + * presence or not of -mfpu=neon on the GCC command line, it is possible to do + * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely + * do this. + */ +#ifndef PNG_ARM_NEON_OPT + /* ARM NEON optimizations are being controlled by the compiler settings, + * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon + * with GCC) then the compiler will define __ARM_NEON__ and we can rely + * unconditionally on NEON instructions not crashing, otherwise we must + * disable use of NEON instructions. + * + * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they + * can only be turned on automatically if that is supported too. If + * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail + * to compile with an appropriate #error if ALIGNED_MEMORY has been turned + * off. + * + * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated + * __ARM_NEON__, so we check both variants. + * + * To disable ARM_NEON optimizations entirely, and skip compiling the + * associated assembler code, pass --enable-arm-neon=no to configure + * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS. + */ +# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_ARM_NEON_OPT 2 +# else +# define PNG_ARM_NEON_OPT 0 +# endif +#endif + +#ifndef PNG_RISCV_RVV_OPT + /* RISCV_RVV optimizations are being controlled by the compiler settings, + * typically the target compiler will define __riscv but the rvv extension + * availability has to be explicitly stated. This is why if no + * PNG_RISCV_RVV_OPT was defined then a runtime check will be executed. + * + * To enable RISCV_RVV optimizations unconditionally, and compile the + * associated code, pass --enable-riscv-rvv=yes or --enable-riscv-rvv=on + * to configure or put -DPNG_RISCV_RVV_OPT=2 in CPPFLAGS. + */ + +# define PNG_RISCV_RVV_OPT 0 +#endif + +#if PNG_ARM_NEON_OPT > 0 + /* NEON optimizations are to be at least considered by libpng, so enable the + * callbacks to do this. + */ +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon +# ifndef PNG_ARM_NEON_IMPLEMENTATION + /* Use the intrinsics code by default. */ +# define PNG_ARM_NEON_IMPLEMENTATION 1 +# endif +#else /* PNG_ARM_NEON_OPT == 0 */ +# define PNG_ARM_NEON_IMPLEMENTATION 0 +#endif /* PNG_ARM_NEON_OPT > 0 */ + +#ifndef PNG_MIPS_MSA_OPT +# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_MIPS_MSA_OPT 2 +# else +# define PNG_MIPS_MSA_OPT 0 +# endif +#endif + +#ifndef PNG_MIPS_MMI_OPT +# ifdef PNG_MIPS_MMI +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_MIPS_MMI_OPT 1 +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +#endif + +#ifndef PNG_POWERPC_VSX_OPT +# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) +# define PNG_POWERPC_VSX_OPT 2 +# else +# define PNG_POWERPC_VSX_OPT 0 +# endif +#endif + +#ifndef PNG_LOONGARCH_LSX_OPT +# if defined(__loongarch_sx) +# define PNG_LOONGARCH_LSX_OPT 1 +# else +# define PNG_LOONGARCH_LSX_OPT 0 +# endif +#endif + +#ifndef PNG_INTEL_SSE_OPT +# ifdef PNG_INTEL_SSE + /* Only check for SSE if the build configuration has been modified to + * enable SSE optimizations. This means that these optimizations will + * be off by default. See contrib/intel for more details. + */ +# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ + defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP >= 2) +# define PNG_INTEL_SSE_OPT 1 +# else +# define PNG_INTEL_SSE_OPT 0 +# endif +# else +# define PNG_INTEL_SSE_OPT 0 +# endif +#endif + +#if PNG_INTEL_SSE_OPT > 0 +# ifndef PNG_INTEL_SSE_IMPLEMENTATION +# if defined(__SSE4_1__) || defined(__AVX__) + /* We are not actually using AVX, but checking for AVX is the best + way we can detect SSE4.1 and SSSE3 on MSVC. + */ +# define PNG_INTEL_SSE_IMPLEMENTATION 3 +# elif defined(__SSSE3__) +# define PNG_INTEL_SSE_IMPLEMENTATION 2 +# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP >= 2) +# define PNG_INTEL_SSE_IMPLEMENTATION 1 +# else +# define PNG_INTEL_SSE_IMPLEMENTATION 0 +# endif +# endif + +# if PNG_INTEL_SSE_IMPLEMENTATION > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2 +# endif +#else +# define PNG_INTEL_SSE_IMPLEMENTATION 0 +#endif + +#if PNG_MIPS_MSA_OPT > 0 +# ifndef PNG_MIPS_MSA_IMPLEMENTATION +# if defined(__mips_msa) +# if defined(__clang__) +# elif defined(__GNUC__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +# define PNG_MIPS_MSA_IMPLEMENTATION 2 +# endif /* no GNUC support */ +# endif /* __GNUC__ */ +# else /* !defined __mips_msa */ +# define PNG_MIPS_MSA_IMPLEMENTATION 2 +# endif /* __mips_msa */ +# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */ + +# ifndef PNG_MIPS_MSA_IMPLEMENTATION +# define PNG_MIPS_MSA_IMPLEMENTATION 1 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips +# endif +#else +# define PNG_MIPS_MSA_IMPLEMENTATION 0 +#endif /* PNG_MIPS_MSA_OPT > 0 */ + +#if PNG_MIPS_MMI_OPT > 0 +# ifndef PNG_MIPS_MMI_IMPLEMENTATION +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) +# define PNG_MIPS_MMI_IMPLEMENTATION 2 +# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */ +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */ +# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */ + +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips +# endif +#else +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +#endif /* PNG_MIPS_MMI_OPT > 0 */ + +#if PNG_POWERPC_VSX_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx +# define PNG_POWERPC_VSX_IMPLEMENTATION 1 +#else +# define PNG_POWERPC_VSX_IMPLEMENTATION 0 +#endif + +#if PNG_LOONGARCH_LSX_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1 +#else +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 +#endif + +#if PNG_RISCV_RVV_OPT > 0 && __riscv_v >= 1000000 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_rvv +# ifndef PNG_RISCV_RVV_IMPLEMENTATION + /* Use the intrinsics code by default. */ +# define PNG_RISCV_RVV_IMPLEMENTATION 1 +# endif +#else +# define PNG_RISCV_RVV_IMPLEMENTATION 0 +#endif /* PNG_RISCV_RVV_OPT > 0 && __riscv_v >= 1000000 */ + +/* Is this a build of a DLL where compilation of the object modules requires + * different preprocessor settings to those required for a simple library? If + * so PNG_BUILD_DLL must be set. + * + * If libpng is used inside a DLL but that DLL does not export the libpng APIs + * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a + * static library of libpng then link the DLL against that. + */ +#ifndef PNG_BUILD_DLL +# ifdef DLL_EXPORT + /* This is set by libtool when files are compiled for a DLL; libtool + * always compiles twice, even on systems where it isn't necessary. Set + * PNG_BUILD_DLL in case it is necessary: + */ +# define PNG_BUILD_DLL +# else +# ifdef _WINDLL + /* This is set by the Microsoft Visual Studio IDE in projects that + * build a DLL. It can't easily be removed from those projects (it + * isn't visible in the Visual Studio UI) so it is a fairly reliable + * indication that PNG_IMPEXP needs to be set to the DLL export + * attributes. + */ +# define PNG_BUILD_DLL +# else +# ifdef __DLL__ + /* This is set by the Borland C system when compiling for a DLL + * (as above.) + */ +# define PNG_BUILD_DLL +# else + /* Add additional compiler cases here. */ +# endif +# endif +# endif +#endif /* Setting PNG_BUILD_DLL if required */ + +/* See pngconf.h for more details: the builder of the library may set this on + * the command line to the right thing for the specific compilation system or it + * may be automagically set above (at present we know of no system where it does + * need to be set on the command line.) + * + * PNG_IMPEXP must be set here when building the library to prevent pngconf.h + * setting it to the "import" setting for a DLL build. + */ +#ifndef PNG_IMPEXP +# ifdef PNG_BUILD_DLL +# define PNG_IMPEXP PNG_DLL_EXPORT +# else + /* Not building a DLL, or the DLL doesn't require specific export + * definitions. + */ +# define PNG_IMPEXP +# endif +#endif + +/* No warnings for private or deprecated functions in the build: */ +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED +#endif +#ifndef PNG_PRIVATE +# define PNG_PRIVATE +#endif + +/* Symbol preprocessing support. + * + * To enable listing global, but internal, symbols the following macros should + * always be used to declare an extern data or function object in this file. + */ +#ifndef PNG_INTERNAL_DATA +# define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array +#endif + +#ifndef PNG_INTERNAL_FUNCTION +# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ + PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) +#endif + +#ifndef PNG_INTERNAL_CALLBACK +# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ + PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\ + PNG_EMPTY attributes) +#endif + +/* If floating or fixed point APIs are disabled they may still be compiled + * internally. To handle this make sure they are declared as the appropriate + * internal extern function (otherwise the symbol prefixing stuff won't work and + * the functions will be used without definitions.) + * + * NOTE: although all the API functions are declared here they are not all + * actually built! Because the declarations are still made it is necessary to + * fake out types that they depend on. + */ +#ifndef PNG_FP_EXPORT +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); +# ifndef PNG_VERSION_INFO_ONLY + typedef struct png_incomplete png_double; + typedef png_double* png_doublep; + typedef const png_double* png_const_doublep; + typedef png_double** png_doublepp; +# endif +# endif +#endif +#ifndef PNG_FIXED_EXPORT +# ifndef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); +# endif +#endif + +#include "png.h" + +/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ +#ifndef PNG_DLL_EXPORT +# define PNG_DLL_EXPORT +#endif + +/* This is a global switch to set the compilation for an installed system + * (a release build). It can be set for testing debug builds to ensure that + * they will compile when the build type is switched to RC or STABLE, the + * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS + * with either: + * + * -DPNG_RELEASE_BUILD Turns on the release compile path + * -DPNG_RELEASE_BUILD=0 Turns it off + * or in your pngusr.h with + * #define PNG_RELEASE_BUILD=1 Turns on the release compile path + * #define PNG_RELEASE_BUILD=0 Turns it off + */ +#ifndef PNG_RELEASE_BUILD +# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) +#endif + +/* SECURITY and SAFETY: + * + * libpng is built with support for internal limits on image dimensions and + * memory usage. These are documented in scripts/pnglibconf.dfa of the + * source and recorded in the machine generated header file pnglibconf.h. + */ + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. + * + * zlib provides 'MAXSEG_64K' which, if defined, indicates the + * same limit and pngconf.h (already included) sets the limit + * if certain operating systems are detected. + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +#ifndef PNG_UNUSED +/* Unused formal parameter warnings are silenced using the following macro + * which is expected to have no bad effects on performance (optimizing + * compilers will probably remove it entirely). Note that if you replace + * it with something other than whitespace, you must include the terminating + * semicolon. + */ +# define PNG_UNUSED(param) (void)param; +#endif + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +/* If warnings or errors are turned off the code is disabled or redirected here. + * From 1.5.4 functions have been added to allow very limited formatting of + * error and warning messages - this code will also be disabled here. + */ +#ifdef PNG_WARNINGS_SUPPORTED +# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; +#else +# define png_warning_parameter(p,number,string) ((void)0) +# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) +# define png_warning_parameter_signed(p,number,format,value) ((void)0) +# define png_formatted_warning(pp,p,message) ((void)(pp)) +# define PNG_WARNING_PARAMETERS(p) +#endif +#ifndef PNG_ERROR_TEXT_SUPPORTED +# define png_fixed_error(s1,s2) png_err(s1) +#endif + +/* Some fixed point APIs are still required even if not exported because + * they get used by the corresponding floating point APIs. This magic + * deals with this: + */ +#ifdef PNG_FIXED_POINT_SUPPORTED +# define PNGFAPI PNGAPI +#else +# define PNGFAPI /* PRIVATE */ +#endif + +#ifndef PNG_VERSION_INFO_ONLY +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +/* C allows up-casts from (void*) to any pointer and (const void*) to any + * pointer to a const object. C++ regards this as a type error and requires an + * explicit, static, cast and provides the static_cast<> rune to ensure that + * const is not cast away. + */ +#ifdef __cplusplus +# define png_voidcast(type, value) static_cast(value) +# define png_constcast(type, value) const_cast(value) +# define png_aligncast(type, value) \ + static_cast(static_cast(value)) +# define png_aligncastconst(type, value) \ + static_cast(static_cast(value)) +#else +# define png_voidcast(type, value) (value) +# define png_constcast(type, value) ((type)(void*)(const void*)(value)) +# define png_aligncast(type, value) ((void*)(value)) +# define png_aligncastconst(type, value) ((const void*)(value)) +#endif /* __cplusplus */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) + /* png.c requires the following ANSI-C constants if the conversion of + * floating point to ASCII is implemented therein: + * + * DBL_DIG Maximum number of decimal digits (can be set to any constant) + * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) + * DBL_MAX Maximum floating point number (can be set to an arbitrary value) + */ +# include + +# include + +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include +# endif +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include +# include +#endif + +#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +# include +#endif +#endif /* PNG_VERSION_INFO_ONLY */ + +/* Moved here around 1.5.0beta36 from pngconf.h */ +/* Users may want to use these so they are not private. Any library + * functions that are passed far data must be model-independent. + */ + +/* Platform-independent functions */ +#ifndef PNG_ABORT +# define PNG_ABORT() abort() +#endif + +/* These macros may need to be architecture dependent. */ +#define PNG_ALIGN_NONE 0 /* do not use data alignment */ +#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ +#ifdef offsetof +# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ +#else +# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ +#endif +#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ + +#ifndef PNG_ALIGN_TYPE + /* Default to using aligned access optimizations and requiring alignment to a + * multiple of the data type size. Override in a compiler specific fashion + * if necessary by inserting tests here: + */ +# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE +#endif + +#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE + /* This is used because in some compiler implementations non-aligned + * structure members are supported, so the offsetof approach below fails. + * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access + * is good for performance. Do not do this unless you have tested the + * result and understand it. + */ +# define png_alignof(type) (sizeof(type)) +#else +# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET +# define png_alignof(type) offsetof(struct{char c; type t;}, t) +# else +# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS +# define png_alignof(type) 1 +# endif + /* Else leave png_alignof undefined to prevent use thereof */ +# endif +#endif + +/* This implicitly assumes alignment is always a multiple of 2. */ +#ifdef png_alignof +# define png_isaligned(ptr, type) \ + (((type)(size_t)((const void*)(ptr)) & (type)(png_alignof(type)-1)) == 0) +#else +# define png_isaligned(ptr, type) 0 +#endif + +/* End of memory model/platform independent support */ +/* End of 1.5.0beta36 move from pngconf.h */ + +/* CONSTANTS and UTILITY MACROS + * These are used internally by libpng and not exposed in the API + */ + +/* Various modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. Three of these + * are defined in png.h because they need to be visible to applications + * that call png_set_unknown_chunk(). + */ +/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */ +/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */ +#define PNG_HAVE_IDAT 0x04U +/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */ +#define PNG_HAVE_IEND 0x10U + /* 0x20U (unused) */ + /* 0x40U (unused) */ + /* 0x80U (unused) */ +#define PNG_HAVE_CHUNK_HEADER 0x100U +#define PNG_WROTE_tIME 0x200U +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U +#define PNG_BACKGROUND_IS_GRAY 0x800U +#define PNG_HAVE_PNG_SIGNATURE 0x1000U +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */ +#define PNG_WROTE_eXIf 0x4000U +#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */ + +/* Flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001U +#define PNG_INTERLACE 0x0002U +#define PNG_PACK 0x0004U +#define PNG_SHIFT 0x0008U +#define PNG_SWAP_BYTES 0x0010U +#define PNG_INVERT_MONO 0x0020U +#define PNG_QUANTIZE 0x0040U +#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */ +#define PNG_BACKGROUND_EXPAND 0x0100U +#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */ +#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */ +#define PNG_RGBA 0x0800U +#define PNG_EXPAND 0x1000U +#define PNG_GAMMA 0x2000U +#define PNG_GRAY_TO_RGB 0x4000U +#define PNG_FILLER 0x8000U +#define PNG_PACKSWAP 0x10000U +#define PNG_SWAP_ALPHA 0x20000U +#define PNG_STRIP_ALPHA 0x40000U +#define PNG_INVERT_ALPHA 0x80000U +#define PNG_USER_TRANSFORM 0x100000U +#define PNG_RGB_TO_GRAY_ERR 0x200000U +#define PNG_RGB_TO_GRAY_WARN 0x400000U +#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */ +#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */ +#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */ +#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */ + /* 0x8000000U unused */ + /* 0x10000000U unused */ + /* 0x20000000U unused */ + /* 0x40000000U unused */ +/* Flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001U +#define PNG_STRUCT_INFO 0x0002U + +/* Flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U +#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */ + /* 0x0004U unused */ +#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */ + /* 0x0010U unused */ + /* 0x0020U unused */ +#define PNG_FLAG_ROW_INIT 0x0040U +#define PNG_FLAG_FILLER_AFTER 0x0080U +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U +/* PNG_FLAG_ASSUME_sRGB unused 0x1000U * Added to libpng-1.5.4 */ +#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */ +#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */ +/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */ +/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */ +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U + /* 0x40000U unused */ +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U +#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */ +#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */ +#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */ + /* 0x800000U unused */ + /* 0x1000000U unused */ + /* 0x2000000U unused */ + /* 0x4000000U unused */ + /* 0x8000000U unused */ + /* 0x10000000U unused */ + /* 0x20000000U unused */ + /* 0x40000000U unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* Save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 + * by dividing by 257 *with rounding*. This macro is exact for the given range. + * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the + * macro were established by experiment (modifying the added value). The macro + * has a second variant that takes a value already scaled by 255 and divides by + * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it + * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. + */ +#define PNG_DIV65535(v24) (((v24) + 32895) >> 16) +#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \ + (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) ) + +/* This returns the number of trailing bits in the last byte of a row, 0 if the + * last byte is completely full of pixels. It is, in principle, (pixel_bits x + * width) % 8, but that would overflow for large 'width'. The second macro is + * the same except that it returns the number of unused bits in the last byte; + * (8-TRAILBITS), but 0 when TRAILBITS is 0. + * + * NOTE: these macros are intended to be self-evidently correct and never + * overflow on the assumption that pixel_bits is in the range 0..255. The + * arguments are evaluated only once and they can be signed (e.g. as a result of + * the integral promotions). The result of the expression always has type + * (png_uint_32), however the compiler always knows it is in the range 0..7. + */ +#define PNG_TRAILBITS(pixel_bits, width) \ + (((pixel_bits) * ((width) % (png_uint_32)8)) % 8) + +#define PNG_PADBITS(pixel_bits, width) \ + ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + * ideal-delta..ideal+delta. Each argument is evaluated twice. + * "ideal" and "delta" should be constants, normally simple + * integers, "value" a variable. Added to libpng-1.2.6 JB + */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* Conversions between fixed and floating point, only defined if + * required (to make sure the code doesn't accidentally use float + * when it is supposedly disabled.) + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* The floating point conversion can't overflow, though it can and + * does lose accuracy relative to the original fixed point value. + * In practice this doesn't matter because png_fixed_point only + * stores numbers with very low precision. The png_ptr and s + * arguments are unused by default but are there in case error + * checking becomes a requirement. + */ +#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) + +/* The fixed point conversion performs range checking and evaluates + * its argument multiple times, so must be used with care. The + * range checking uses the PNG specification values for a signed + * 32-bit fixed point value except that the values are deliberately + * rounded-to-zero to an integral value - 21474 (21474.83 is roughly + * (2^31-1) * 100000). 's' is a string that describes the value being + * converted. + * + * NOTE: this macro will raise a png_error if the range check fails, + * therefore it is normally only appropriate to use this on values + * that come from API calls or other sources where an out of range + * error indicates a programming error, not a data error! + * + * NOTE: by default this is off - the macro is not used - because the + * function call saves a lot of code. + */ +#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED +#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ + ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) +#define png_fixed_ITU(png_ptr, fp, s) ((fp) <= 214748 && (fp) >= 0 ?\ + ((png_uint_32)(10000 * (fp))) : (png_fixed_error(png_ptr, s),0)) +#endif +/* else the corresponding function is defined below, inside the scope of the + * cplusplus test. + */ +#endif + +/* Constants for known chunk types. If you need to add a chunk, define the name + * here. For historical reasons these constants have the form png_; i.e. + * the prefix is lower case. Please use decimal values as the parameters to + * match the ISO PNG specification and to avoid relying on the C locale + * interpretation of character values. + * + * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values + * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string + * to be generated if required. + * + * PNG_32b correctly produces a value shifted by up to 24 bits, even on + * architectures where (int) is only 16 bits. + * + * 1.6.47: PNG_32b was made into a preprocessor evaluable macro by replacing the + * static_cast with a promoting binary operation using a guaranteed 32-bit + * (minimum) unsigned value. + */ +#define PNG_32b(b,s) (((0xFFFFFFFFU)&(b)) << (s)) +#define PNG_U32(b1,b2,b3,b4) \ + (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) + +/* Chunk name validation. When using these macros all the arguments should be + * constants, otherwise code bloat may well occur. The macros are provided + * primarily for use in #if checks. + * + * PNG_32to8 produces a byte value with the right shift; used to extract the + * byte value from a chunk name. + */ +#define PNG_32to8(cn,s) (((cn) >> (s)) & 0xffU) +#define PNG_CN_VALID_UPPER(b) ((b) >= 65 && (b) <= 90) /* upper-case ASCII */ +#define PNG_CN_VALID_ASCII(b) PNG_CN_VALID_UPPER((b) & ~32U) +#define PNG_CHUNK_NAME_VALID(cn) (\ + PNG_CN_VALID_ASCII(PNG_32to8(cn,24)) && /* critical, !ancillary */\ + PNG_CN_VALID_ASCII(PNG_32to8(cn,16)) && /* public, !privately defined */\ + PNG_CN_VALID_UPPER(PNG_32to8(cn, 8)) && /* VALID, !reserved */\ + PNG_CN_VALID_ASCII(PNG_32to8(cn, 0)) /* data-dependent, !copy ok */) + +/* Constants for known chunk types. + * + * MAINTAINERS: If you need to add a chunk, define the name here. + * For historical reasons these constants have the form png_; i.e. + * the prefix is lower case. Please use decimal values as the parameters to + * match the ISO PNG specification and to avoid relying on the C locale + * interpretation of character values. Please keep the list sorted. + * + * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk + * type. In fact the specification does not express chunk types this way, + * however using a 32-bit value means that the chunk type can be read from the + * stream using exactly the same code as used for a 32-bit unsigned value and + * can be examined far more efficiently (using one arithmetic compare). + * + * Prior to 1.5.6 the chunk type constants were expressed as C strings. The + * libpng API still uses strings for 'unknown' chunks and a macro, + * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice + * that for portable code numeric values must still be used; the string "IHDR" + * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). + * + * In 1.7.0 the definitions will be made public in png.h to avoid having to + * duplicate the same definitions in application code. + */ +#define png_IDAT PNG_U32( 73, 68, 65, 84) +#define png_IEND PNG_U32( 73, 69, 78, 68) +#define png_IHDR PNG_U32( 73, 72, 68, 82) +#define png_PLTE PNG_U32( 80, 76, 84, 69) +#define png_acTL PNG_U32( 97, 99, 84, 76) /* PNGv3: APNG */ +#define png_bKGD PNG_U32( 98, 75, 71, 68) +#define png_cHRM PNG_U32( 99, 72, 82, 77) +#define png_cICP PNG_U32( 99, 73, 67, 80) /* PNGv3 */ +#define png_cLLI PNG_U32( 99, 76, 76, 73) /* PNGv3 */ +#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */ +#define png_fcTL PNG_U32(102, 99, 84, 76) /* PNGv3: APNG */ +#define png_fdAT PNG_U32(102, 100, 65, 84) /* PNGv3: APNG */ +#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ +#define png_gAMA PNG_U32(103, 65, 77, 65) +#define png_gIFg PNG_U32(103, 73, 70, 103) +#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ +#define png_gIFx PNG_U32(103, 73, 70, 120) +#define png_hIST PNG_U32(104, 73, 83, 84) +#define png_iCCP PNG_U32(105, 67, 67, 80) +#define png_iTXt PNG_U32(105, 84, 88, 116) +#define png_mDCV PNG_U32(109, 68, 67, 86) /* PNGv3 */ +#define png_oFFs PNG_U32(111, 70, 70, 115) +#define png_pCAL PNG_U32(112, 67, 65, 76) +#define png_pHYs PNG_U32(112, 72, 89, 115) +#define png_sBIT PNG_U32(115, 66, 73, 84) +#define png_sCAL PNG_U32(115, 67, 65, 76) +#define png_sPLT PNG_U32(115, 80, 76, 84) +#define png_sRGB PNG_U32(115, 82, 71, 66) +#define png_sTER PNG_U32(115, 84, 69, 82) +#define png_tEXt PNG_U32(116, 69, 88, 116) +#define png_tIME PNG_U32(116, 73, 77, 69) +#define png_tRNS PNG_U32(116, 82, 78, 83) +#define png_zTXt PNG_U32(122, 84, 88, 116) + +/* The following will work on (signed char*) strings, whereas the get_uint_32 + * macro will fail on top-bit-set values because of the sign extension. + */ +#define PNG_CHUNK_FROM_STRING(s)\ + PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3]) + +/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is + * signed and the argument is a (char[]) This macro will fail miserably on + * systems where (char) is more than 8 bits. + */ +#define PNG_STRING_FROM_CHUNK(s,c)\ + (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \ + ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\ + ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \ + ((char*)(s))[3]=(char)((c & 0xff))) + +/* Do the same but terminate with a null character. */ +#define PNG_CSTRING_FROM_CHUNK(s,c)\ + (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) + +/* Test on flag values as defined in the spec (section 5.4): */ +#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) +#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) +#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) +#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) +#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) + +/* Known chunks. All supported chunks must be listed here. The macro PNG_CHUNK + * contains the four character ASCII name by which the chunk is identified. The + * macro is implemented as required to build tables or switch statements which + * require entries for every known chunk. The macro also contains an index + * value which should be in order (this is checked in png.c). + * + * Notice that "known" does not require "SUPPORTED"; tables should be built in + * such a way that chunks unsupported in a build require no more than the table + * entry (which should be small.) In particular function pointers for + * unsupported chunks should be NULL. + * + * At present these index values are not exported (not part of the public API) + * so can be changed at will. For convenience the names are in lexical sort + * order but with the critical chunks at the start in the order of occurrence in + * a PNG. + * + * PNG_INFO_ values do not exist for every one of these chunk handles; for + * example PNG_INFO_{IDAT,IEND,tEXt,iTXt,zTXt} and possibly other chunks in the + * future. + */ +#define PNG_KNOWN_CHUNKS\ + PNG_CHUNK(IHDR, 0)\ + PNG_CHUNK(PLTE, 1)\ + PNG_CHUNK(IDAT, 2)\ + PNG_CHUNK(IEND, 3)\ + PNG_CHUNK(acTL, 4)\ + PNG_CHUNK(bKGD, 5)\ + PNG_CHUNK(cHRM, 6)\ + PNG_CHUNK(cICP, 7)\ + PNG_CHUNK(cLLI, 8)\ + PNG_CHUNK(eXIf, 9)\ + PNG_CHUNK(fcTL, 10)\ + PNG_CHUNK(fdAT, 11)\ + PNG_CHUNK(gAMA, 12)\ + PNG_CHUNK(hIST, 13)\ + PNG_CHUNK(iCCP, 14)\ + PNG_CHUNK(iTXt, 15)\ + PNG_CHUNK(mDCV, 16)\ + PNG_CHUNK(oFFs, 17)\ + PNG_CHUNK(pCAL, 18)\ + PNG_CHUNK(pHYs, 19)\ + PNG_CHUNK(sBIT, 20)\ + PNG_CHUNK(sCAL, 21)\ + PNG_CHUNK(sPLT, 22)\ + PNG_CHUNK(sRGB, 23)\ + PNG_CHUNK(tEXt, 24)\ + PNG_CHUNK(tIME, 25)\ + PNG_CHUNK(tRNS, 26)\ + PNG_CHUNK(zTXt, 27) + +/* Gamma values (new at libpng-1.5.4): */ +#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ +#define PNG_GAMMA_MAC_INVERSE 65909 +#define PNG_GAMMA_sRGB_INVERSE 45455 + +/* gamma sanity check. libpng cannot implement gamma transforms outside a + * certain limit because of its use of 16-bit fixed point intermediate values. + * Gamma values that are too large or too small will zap the 16-bit values all + * to 0 or 65535 resulting in an obvious 'bad' image. + * + * In libpng 1.6.0 the limits were changed from 0.07..3 to 0.01..100 to + * accommodate the optimal 16-bit gamma of 36 and its reciprocal. + * + * These are png_fixed_point integral values: + */ +#define PNG_LIB_GAMMA_MIN 1000 +#define PNG_LIB_GAMMA_MAX 10000000 + +/* Almost everything below is C specific; the #defines above can be used in + * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. + */ +#ifndef PNG_VERSION_INFO_ONLY + +#include "pngstruct.h" +#include "pnginfo.h" + +/* Validate the include paths - the include path used to generate pnglibconf.h + * must match that used in the build, or we must be using pnglibconf.h.prebuilt: + */ +#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM +# error The include path of is incorrect + /* When pnglibconf.h was built, the copy of zlib.h that it used was not the + * same as the one being used here. Considering how libpng makes decisions + * to use the zlib API based on the zlib version number, the -I options must + * match. + * + * A possible cause of this mismatch is that you passed an -I option in + * CFLAGS, which is unlikely to work. All the preprocessor options, and all + * the -I options in particular, should be in CPPFLAGS. + */ +#endif + +/* This is used for 16-bit gamma tables -- only the top level pointers are + * const; this could be changed: + */ +typedef const png_uint_16p * png_const_uint_16pp; + +/* Added to libpng-1.5.7: sRGB conversion tables */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); + /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, + * 0..65535. This table gives the closest 16-bit answers (no errors). + */ +#endif + +PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); +PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); + +#define PNG_sRGB_FROM_LINEAR(linear) \ + ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \ + + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))) + /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB + * encoded value with maximum error 0.646365. Note that the input is not a + * 16-bit value; it has been multiplied by 255! */ +#endif /* SIMPLIFIED_READ/WRITE */ + + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Internal functions; these are not exported from a DLL however because they + * are used within several of the C source files they have to be C extern. + * + * All of these functions must be declared with PNG_INTERNAL_FUNCTION. + */ +/* Zlib support */ +#define PNG_UNEXPECTED_ZLIB_RETURN (-7) +PNG_INTERNAL_FUNCTION(void, png_zstream_error, + (png_structrp png_ptr, int ret), + PNG_EMPTY); + /* Used by the zlib handling functions to ensure that z_stream::msg is always + * set before they return. + */ + +#ifdef PNG_WRITE_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_free_buffer_list, + (png_structrp png_ptr, png_compression_bufferp *list), + PNG_EMPTY); + /* Free the buffer list used by the compressed write code. */ +#endif + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_mDCV_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ + (defined(PNG_sCAL_SUPPORTED) && \ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) +PNG_INTERNAL_FUNCTION(png_fixed_point, png_fixed, + (png_const_structrp png_ptr, double fp, png_const_charp text), + PNG_EMPTY); +#endif + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ + (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED)) +PNG_INTERNAL_FUNCTION(png_uint_32, png_fixed_ITU, + (png_const_structrp png_ptr, double fp, png_const_charp text), + PNG_EMPTY); +#endif + +/* Check the user version string for compatibility, returns false if the version + * numbers aren't compatible. + */ +PNG_INTERNAL_FUNCTION(int, png_user_version_check, + (png_structrp png_ptr, png_const_charp user_png_ver), + PNG_EMPTY); + +#ifdef PNG_READ_SUPPORTED /* should only be used on read */ +/* Security: read limits on the largest allocations while reading a PNG. This + * avoids very large allocations caused by PNG files with damaged or altered + * chunk 'length' fields. + */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED /* run-time limit */ +# define png_chunk_max(png_ptr) ((png_ptr)->user_chunk_malloc_max) + +#elif PNG_USER_CHUNK_MALLOC_MAX > 0 /* compile-time limit */ +# define png_chunk_max(png_ptr) ((void)png_ptr, PNG_USER_CHUNK_MALLOC_MAX) + +#elif (defined PNG_MAX_MALLOC_64K) /* legacy system limit */ +# define png_chunk_max(png_ptr) ((void)png_ptr, 65536U) + +#else /* modern system limit SIZE_MAX (C99) */ +# define png_chunk_max(png_ptr) ((void)png_ptr, PNG_SIZE_MAX) +#endif +#endif /* READ */ + +/* Internal base allocator - no messages, NULL on failure to allocate. This + * does, however, call the application provided allocator and that could call + * png_error (although that would be a bug in the application implementation.) + */ +PNG_INTERNAL_FUNCTION(png_voidp, png_malloc_base, + (png_const_structrp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ + defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) +/* Internal array allocator, outputs no error or warning messages on failure, + * just returns NULL. + */ +PNG_INTERNAL_FUNCTION(png_voidp, png_malloc_array, + (png_const_structrp png_ptr, int nelements, size_t element_size), + PNG_ALLOCATED); + +/* The same but an existing array is extended by add_elements. This function + * also memsets the new elements to 0 and copies the old elements. The old + * array is not freed or altered. + */ +PNG_INTERNAL_FUNCTION(png_voidp, png_realloc_array, + (png_const_structrp png_ptr, + png_const_voidp array, int old_elements, int add_elements, + size_t element_size), + PNG_ALLOCATED); +#endif /* text, sPLT or unknown chunks */ + +/* Magic to create a struct when there is no struct to call the user supplied + * memory allocators. Because error handling has not been set up the memory + * handlers can't safely call png_error, but this is an obscure and undocumented + * restriction so libpng has to assume that the 'free' handler, at least, might + * call png_error. + */ +PNG_INTERNAL_FUNCTION(png_structp, png_create_png_struct, + (png_const_charp user_png_ver, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); + +/* Free memory from internal libpng struct */ +PNG_INTERNAL_FUNCTION(void, png_destroy_png_struct, + (png_structrp png_ptr), + PNG_EMPTY); + +/* Free an allocated jmp_buf (always succeeds) */ +PNG_INTERNAL_FUNCTION(void, png_free_jmpbuf, + (png_structrp png_ptr), + PNG_EMPTY); + +/* Function to allocate memory for zlib. PNGAPI is disallowed. */ +PNG_INTERNAL_FUNCTION(voidpf, png_zalloc, + (voidpf png_ptr, uInt items, uInt size), + PNG_ALLOCATED); + +/* Function to free memory for zlib. PNGAPI is disallowed. */ +PNG_INTERNAL_FUNCTION(void, png_zfree, + (voidpf png_ptr, voidpf ptr), + PNG_EMPTY); + +/* Next four functions are used internally as callbacks. PNGCBAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to + * PNGCBAPI at 1.5.0 + */ + +PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_read_data, + (png_structp png_ptr, png_bytep data, size_t length), + PNG_EMPTY); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_push_fill_buffer, + (png_structp png_ptr, png_bytep buffer, size_t length), + PNG_EMPTY); +#endif + +PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_write_data, + (png_structp png_ptr, png_bytep data, size_t length), + PNG_EMPTY); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED +PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_flush, + (png_structp png_ptr), + PNG_EMPTY); +# endif +#endif + +/* Reset the CRC variable */ +PNG_INTERNAL_FUNCTION(void, png_reset_crc, + (png_structrp png_ptr), + PNG_EMPTY); + +/* Write the "data" buffer to whatever output you are using */ +PNG_INTERNAL_FUNCTION(void, png_write_data, + (png_structrp png_ptr, png_const_bytep data, size_t length), + PNG_EMPTY); + +/* Read and check the PNG file signature */ +PNG_INTERNAL_FUNCTION(void, png_read_sig, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); + +/* Read the chunk header (length + type name) */ +PNG_INTERNAL_FUNCTION(png_uint_32, png_read_chunk_header, + (png_structrp png_ptr), + PNG_EMPTY); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_INTERNAL_FUNCTION(void, png_read_data, + (png_structrp png_ptr, png_bytep data, size_t length), + PNG_EMPTY); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_INTERNAL_FUNCTION(void, png_crc_read, + (png_structrp png_ptr, png_bytep buf, png_uint_32 length), + PNG_EMPTY); + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_INTERNAL_FUNCTION(int, png_crc_finish, + (png_structrp png_ptr, png_uint_32 skip), + PNG_EMPTY); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_INTERNAL_FUNCTION(void, png_calculate_crc, + (png_structrp png_ptr, png_const_bytep ptr, size_t length), + PNG_EMPTY); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_flush, + (png_structrp png_ptr), + PNG_EMPTY); +#endif + +/* Write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_INTERNAL_FUNCTION(void, png_write_IHDR, + (png_structrp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, + int compression_method, int filter_method, int interlace_method), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void, png_write_PLTE, + (png_structrp png_ptr, + png_const_colorp palette, png_uint_32 num_pal), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void, png_compress_IDAT, + (png_structrp png_ptr, + png_const_bytep row_data, png_alloc_size_t row_data_length, int flush), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void, png_write_IEND, + (png_structrp png_ptr), + PNG_EMPTY); + +#ifdef PNG_WRITE_gAMA_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_gAMA_fixed, + (png_structrp png_ptr, png_fixed_point file_gamma), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_sBIT, + (png_structrp png_ptr, png_const_color_8p sbit, int color_type), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_cHRM_fixed, + (png_structrp png_ptr, const png_xy *xy), + PNG_EMPTY); + /* The xy value must have been previously validated */ +#endif + +#ifdef PNG_WRITE_cICP_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_cICP, + (png_structrp png_ptr, + png_byte colour_primaries, png_byte transfer_function, + png_byte matrix_coefficients, png_byte video_full_range_flag), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_cLLI_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_cLLI_fixed, + (png_structrp png_ptr, png_uint_32 maxCLL, png_uint_32 maxFALL), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_mDCV_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_mDCV_fixed, + (png_structrp png_ptr, + png_uint_16 red_x, png_uint_16 red_y, + png_uint_16 green_x, png_uint_16 green_y, + png_uint_16 blue_x, png_uint_16 blue_y, + png_uint_16 white_x, png_uint_16 white_y, + png_uint_32 maxDL, png_uint_32 minDL), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_sRGB, + (png_structrp png_ptr, int intent), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_eXIf_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_eXIf, + (png_structrp png_ptr, png_bytep exif, int num_exif), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_iCCP, + (png_structrp png_ptr, + png_const_charp name, png_const_bytep profile, png_uint_32 proflen), + PNG_EMPTY); + /* Writes a previously 'set' profile. The profile argument is **not** + * compressed. + */ +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_sPLT, + (png_structrp png_ptr, png_const_sPLT_tp palette), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_tRNS, + (png_structrp png_ptr, + png_const_bytep trans, png_const_color_16p values, int number, + int color_type), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_bKGD, + (png_structrp png_ptr, png_const_color_16p values, int color_type), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_hIST, + (png_structrp png_ptr, png_const_uint_16p hist, int num_hist), + PNG_EMPTY); +#endif + +/* Chunks that have keywords */ +#ifdef PNG_WRITE_tEXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_tEXt, + (png_structrp png_ptr, + png_const_charp key, png_const_charp text, size_t text_len), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_zTXt, + (png_structrp png_ptr, + png_const_charp key, png_const_charp text, int compression), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_iTXt, + (png_structrp png_ptr, + int compression, png_const_charp key, png_const_charp lang, + png_const_charp lang_key, png_const_charp text), + PNG_EMPTY); +#endif + +#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ +PNG_INTERNAL_FUNCTION(int, png_set_text_2, + (png_const_structrp png_ptr, + png_inforp info_ptr, png_const_textp text_ptr, int num_text), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_oFFs, + (png_structrp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_pCAL_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_pCAL, + (png_structrp png_ptr, + png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_const_charp units, png_charpp params), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_pHYs_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_pHYs, + (png_structrp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_tIME, + (png_structrp png_ptr, png_const_timep mod_time), + PNG_EMPTY); +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_write_sCAL_s, + (png_structrp png_ptr, + int unit, png_const_charp width, png_const_charp height), + PNG_EMPTY); +#endif + +/* Called when finished processing a row of data */ +PNG_INTERNAL_FUNCTION(void, png_write_finish_row, + (png_structrp png_ptr), + PNG_EMPTY); + +/* Internal use only. Called before first row of data */ +PNG_INTERNAL_FUNCTION(void, png_write_start_row, + (png_structrp png_ptr), + PNG_EMPTY); + +/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an + * array of png_ptr->width pixels. If the image is not interlaced or this + * is the final pass this just does a memcpy, otherwise the "display" flag + * is used to determine whether to copy pixels that are not in the current pass. + * + * Because 'png_do_read_interlace' (below) replicates pixels this allows this + * function to achieve the documented 'blocky' appearance during interlaced read + * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' + * are not changed if they are not in the current pass, when display is 0. + * + * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. + * + * The API always reads from the png_struct row buffer and always assumes that + * it is full width (png_do_read_interlace has already been called.) + * + * This function is only ever used to write to row buffers provided by the + * caller of the relevant libpng API and the row must have already been + * transformed by the read transformations. + * + * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed + * bitmasks for use within the code, otherwise runtime generated masks are used. + * The default is compile time masks. + */ +#ifndef PNG_USE_COMPILE_TIME_MASKS +# define PNG_USE_COMPILE_TIME_MASKS 1 +#endif +PNG_INTERNAL_FUNCTION(void, png_combine_row, + (png_const_structrp png_ptr, png_bytep row, int display), + PNG_EMPTY); + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Expand an interlaced row: the 'row_info' describes the pass data that has + * been read in and must correspond to the pixels in 'row', the pixels are + * expanded (moved apart) in 'row' to match the final layout, when doing this + * the pixels are *replicated* to the intervening space. This is essential for + * the correct operation of png_combine_row, above. + */ +PNG_INTERNAL_FUNCTION(void, png_do_read_interlace, + (png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations), + PNG_EMPTY); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED +/* Grab pixels out of a row for an interlaced pass */ +PNG_INTERNAL_FUNCTION(void, png_do_write_interlace, + (png_row_infop row_info, png_bytep row, int pass), + PNG_EMPTY); +#endif + +/* Unfilter a row: check the filter value before calling this, there is no point + * calling it for PNG_FILTER_VALUE_NONE. + */ +PNG_INTERNAL_FUNCTION(void, png_read_filter_row, + (png_structrp pp, png_row_infop row_info, + png_bytep row, png_const_bytep prev_row, int filter), + PNG_EMPTY); + +#if PNG_ARM_NEON_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_neon, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_msa, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +#if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_mmi, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +#if PNG_POWERPC_VSX_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_vsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +#if PNG_INTEL_SSE_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_sse2, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_sse2, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_sse2, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_sse2, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_sse2, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_sse2, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_lsx, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +#if PNG_RISCV_RVV_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_rvv, + (png_row_infop row_info, png_bytep row, png_const_bytep prev_row), + PNG_EMPTY); +#endif + +/* Choose the best filter to use and filter the row data */ +PNG_INTERNAL_FUNCTION(void, png_write_find_filter, + (png_structrp png_ptr, png_row_infop row_info), + PNG_EMPTY); + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_read_IDAT_data, + (png_structrp png_ptr, png_bytep output, png_alloc_size_t avail_out), + PNG_EMPTY); + /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer + * is NULL the function checks, instead, for the end of the stream. In this + * case a benign error will be issued if the stream end is not found or if + * extra data has to be consumed. + */ +PNG_INTERNAL_FUNCTION(void, png_read_finish_IDAT, + (png_structrp png_ptr), + PNG_EMPTY); + /* This cleans up when the IDAT LZ stream does not end when the last image + * byte is read; there is still some pending input. + */ + +PNG_INTERNAL_FUNCTION(void, png_read_finish_row, + (png_structrp png_ptr), + PNG_EMPTY); + /* Finish a row while reading, dealing with interlacing passes, etc. */ +#endif /* SEQUENTIAL_READ */ + +/* Initialize the row buffers, etc. */ +PNG_INTERNAL_FUNCTION(void, png_read_start_row, + (png_structrp png_ptr), + PNG_EMPTY); + +#if ZLIB_VERNUM >= 0x1240 +PNG_INTERNAL_FUNCTION(int, png_zlib_inflate, + (png_structrp png_ptr, int flush), + PNG_EMPTY); +# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush) +#else /* Zlib < 1.2.4 */ +# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush) +#endif /* Zlib < 1.2.4 */ + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +/* Optional call to update the users info structure */ +PNG_INTERNAL_FUNCTION(void, png_read_transform_info, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +#endif + +/* Shared transform functions, defined in pngtran.c */ +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_do_strip_channel, + (png_row_infop row_info, png_bytep row, int at_start), + PNG_EMPTY); +#endif + +#ifdef PNG_16BIT_SUPPORTED +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_do_swap, + (png_row_infop row_info, png_bytep row), + PNG_EMPTY); +#endif +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ + defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_do_packswap, + (png_row_infop row_info, png_bytep row), + PNG_EMPTY); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_do_invert, + (png_row_infop row_info, png_bytep row), + PNG_EMPTY); +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_do_bgr, + (png_row_infop row_info, png_bytep row), + PNG_EMPTY); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ +typedef enum +{ + /* Result of a call to png_handle_chunk made to handle the current chunk + * png_struct::chunk_name on read. Always informational, either the stream + * is read for the next chunk or the routine will call png_error. + * + * NOTE: order is important internally. handled_saved and above are regarded + * as handling the chunk. + */ + handled_error = 0, /* bad crc or known and bad format or too long */ + handled_discarded, /* not saved in the unknown chunk list */ + handled_saved, /* saved in the unknown chunk list */ + handled_ok /* known, supported and handled without error */ +} png_handle_result_code; + +PNG_INTERNAL_FUNCTION(png_handle_result_code, png_handle_unknown, + (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep), + PNG_EMPTY); + /* This is the function that gets called for unknown chunks. The 'keep' + * argument is either non-zero for a known chunk that has been set to be + * handled as unknown or zero for an unknown chunk. By default the function + * just skips the chunk or errors out if it is critical. + */ + +PNG_INTERNAL_FUNCTION(png_handle_result_code, png_handle_chunk, + (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length), + PNG_EMPTY); + /* This handles the current chunk png_ptr->chunk_name with unread + * data[length] and returns one of the above result codes. + */ + +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +PNG_INTERNAL_FUNCTION(int, png_chunk_unknown_handling, + (png_const_structrp png_ptr, png_uint_32 chunk_name), + PNG_EMPTY); + /* Exactly as the API png_handle_as_unknown() except that the argument is a + * 32-bit chunk name, not a string. + */ +#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ + +/* Handle the transformations for reading and writing */ +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_do_read_transformations, + (png_structrp png_ptr, png_row_infop row_info), + PNG_EMPTY); +#endif +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_do_write_transformations, + (png_structrp png_ptr, png_row_infop row_info), + PNG_EMPTY); +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_init_read_transformations, + (png_structrp png_ptr), + PNG_EMPTY); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_push_read_chunk, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_read_sig, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_check_crc, + (png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_save_buffer, + (png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_restore_buffer, + (png_structrp png_ptr, png_bytep buffer, size_t buffer_length), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_read_IDAT, + (png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_process_IDAT_data, + (png_structrp png_ptr, png_bytep buffer, size_t buffer_length), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_process_row, + (png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_have_info, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_have_end, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_have_row, + (png_structrp png_ptr, png_bytep row), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_push_read_end, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_process_some_data, + (png_structrp png_ptr, png_inforp info_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_read_push_finish_row, + (png_structrp png_ptr), + PNG_EMPTY); +#endif /* PROGRESSIVE_READ */ + +#ifdef PNG_iCCP_SUPPORTED +/* Routines for checking parts of an ICC profile. */ +#ifdef PNG_READ_iCCP_SUPPORTED +PNG_INTERNAL_FUNCTION(int, png_icc_check_length, + (png_const_structrp png_ptr, + png_const_charp name, png_uint_32 profile_length), + PNG_EMPTY); +#endif /* READ_iCCP */ +PNG_INTERNAL_FUNCTION(int, png_icc_check_header, + (png_const_structrp png_ptr, + png_const_charp name, png_uint_32 profile_length, + png_const_bytep profile /* first 132 bytes only */, int color_type), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int, png_icc_check_tag_table, + (png_const_structrp png_ptr, + png_const_charp name, png_uint_32 profile_length, + png_const_bytep profile /* header plus whole tag table */), + PNG_EMPTY); +#endif /* iCCP */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_set_rgb_coefficients, + (png_structrp png_ptr), + PNG_EMPTY); + /* Set the rgb_to_gray coefficients from the cHRM Y values (if unset) */ +#endif /* READ_RGB_TO_GRAY */ + +/* Added at libpng version 1.4.0 */ +PNG_INTERNAL_FUNCTION(void, png_check_IHDR, + (png_const_structrp png_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, + int interlace_type, int compression_type, int filter_type), + PNG_EMPTY); + +/* Added at libpng version 1.5.10 */ +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_do_check_palette_indexes, + (png_structrp png_ptr, png_row_infop row_info), + PNG_EMPTY); +#endif + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_INTERNAL_FUNCTION(void, png_fixed_error, + (png_const_structrp png_ptr, png_const_charp name), + PNG_NORETURN); +#endif + +/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite + * the end. Always leaves the buffer nul terminated. Never errors out (and + * there is no error code.) + */ +PNG_INTERNAL_FUNCTION(size_t, png_safecat, + (png_charp buffer, size_t bufsize, size_t pos, png_const_charp string), + PNG_EMPTY); + +/* Various internal functions to handle formatted warning messages, currently + * only implemented for warnings. + */ +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) +/* Utility to dump an unsigned value into a buffer, given a start pointer and + * and end pointer (which should point just *beyond* the end of the buffer!) + * Returns the pointer to the start of the formatted string. This utility only + * does unsigned values. + */ +PNG_INTERNAL_FUNCTION(png_charp, png_format_number, + (png_const_charp start, png_charp end, int format, png_alloc_size_t number), + PNG_EMPTY); + +/* Convenience macro that takes an array: */ +#define PNG_FORMAT_NUMBER(buffer,format,number) \ + png_format_number(buffer, buffer + (sizeof buffer), format, number) + +/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ +#define PNG_NUMBER_BUFFER_SIZE 24 + +/* These are the integer formats currently supported, the name is formed from + * the standard printf(3) format string. + */ +#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ +#define PNG_NUMBER_FORMAT_02u 2 +#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ +#define PNG_NUMBER_FORMAT_02d 2 +#define PNG_NUMBER_FORMAT_x 3 +#define PNG_NUMBER_FORMAT_02x 4 +#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ +#endif + +#ifdef PNG_WARNINGS_SUPPORTED +/* New defines and members adding in libpng-1.5.4 */ +# define PNG_WARNING_PARAMETER_SIZE 32 +# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */ + +/* An l-value of this type has to be passed to the APIs below to cache the + * values of the parameters to a formatted warning message. + */ +typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ + PNG_WARNING_PARAMETER_SIZE]; + +PNG_INTERNAL_FUNCTION(void, png_warning_parameter, + (png_warning_parameters p, int number, png_const_charp string), + PNG_EMPTY); + /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, + * including the trailing '\0'. + */ +PNG_INTERNAL_FUNCTION(void, png_warning_parameter_unsigned, + (png_warning_parameters p, int number, int format, png_alloc_size_t value), + PNG_EMPTY); + /* Use png_alloc_size_t because it is an unsigned type as big as any we + * need to output. Use the following for a signed value. + */ +PNG_INTERNAL_FUNCTION(void, png_warning_parameter_signed, + (png_warning_parameters p, int number, int format, png_int_32 value), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void, png_formatted_warning, + (png_const_structrp png_ptr, + png_warning_parameters p, png_const_charp message), + PNG_EMPTY); + /* 'message' follows the X/Open approach of using @1, @2 to insert + * parameters previously supplied using the above functions. Errors in + * specifying the parameters will simply result in garbage substitutions. + */ +#endif + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +/* Application errors (new in 1.6); use these functions (declared below) for + * errors in the parameters or order of API function calls on read. The + * 'warning' should be used for an error that can be handled completely; the + * 'error' for one which can be handled safely but which may lose application + * information or settings. + * + * By default these both result in a png_error call prior to release, while in a + * released version the 'warning' is just a warning. However if the application + * explicitly disables benign errors (explicitly permitting the code to lose + * information) they both turn into warnings. + * + * If benign errors aren't supported they end up as the corresponding base call + * (png_warning or png_error.) + */ +PNG_INTERNAL_FUNCTION(void, png_app_warning, + (png_const_structrp png_ptr, png_const_charp message), + PNG_EMPTY); + /* The application provided invalid parameters to an API function or called + * an API function at the wrong time, libpng can completely recover. + */ + +PNG_INTERNAL_FUNCTION(void, png_app_error, + (png_const_structrp png_ptr, png_const_charp message), + PNG_EMPTY); + /* As above but libpng will ignore the call, or attempt some other partial + * recovery from the error. + */ +#else +# define png_app_warning(pp,s) png_warning(pp,s) +# define png_app_error(pp,s) png_error(pp,s) +#endif + +PNG_INTERNAL_FUNCTION(void, png_chunk_report, + (png_const_structrp png_ptr, png_const_charp message, int error), + PNG_EMPTY); + /* Report a recoverable issue in chunk data. On read this is used to report + * a problem found while reading a particular chunk and the + * png_chunk_benign_error or png_chunk_warning function is used as + * appropriate. On write this is used to report an error that comes from + * data set via an application call to a png_set_ API and png_app_error or + * png_app_warning is used as appropriate. + * + * The 'error' parameter must have one of the following values: + */ +#define PNG_CHUNK_WARNING 0 /* never an error */ +#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ +#define PNG_CHUNK_ERROR 2 /* always an error */ + +/* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. + */ +#if defined(PNG_sCAL_SUPPORTED) +/* MAX_DIGITS is actually the maximum number of characters in an sCAL + * width or height, derived from the precision (number of significant + * digits - a build time settable option) and assumptions about the + * maximum ridiculous exponent. + */ +#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) + +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_ascii_from_fp, + (png_const_structrp png_ptr, + png_charp ascii, size_t size, double fp, unsigned int precision), + PNG_EMPTY); +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_INTERNAL_FUNCTION(void, png_ascii_from_fixed, + (png_const_structrp png_ptr, + png_charp ascii, size_t size, png_fixed_point fp), + PNG_EMPTY); +#endif /* FIXED_POINT */ +#endif /* sCAL */ + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* An internal API to validate the format of a floating point number. + * The result is the index of the next character. If the number is + * not valid it will be the index of a character in the supposed number. + * + * The format of a number is defined in the PNG extensions specification + * and this API is strictly conformant to that spec, not anyone else's! + * + * The format as a regular expression is: + * + * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? + * + * or: + * + * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? + * + * The complexity is that either integer or fraction must be present and the + * fraction is permitted to have no digits only if the integer is present. + * + * NOTE: The dangling E problem. + * There is a PNG valid floating point number in the following: + * + * PNG floating point numbers are not greedy. + * + * Working this out requires *TWO* character lookahead (because of the + * sign), the parser does not do this - it will fail at the 'r' - this + * doesn't matter for PNG sCAL chunk values, but it requires more care + * if the value were ever to be embedded in something more complex. Use + * ANSI-C strtod if you need the lookahead. + */ +/* State table for the parser. */ +#define PNG_FP_INTEGER 0 /* before or in integer */ +#define PNG_FP_FRACTION 1 /* before or in fraction */ +#define PNG_FP_EXPONENT 2 /* before or in exponent */ +#define PNG_FP_STATE 3 /* mask for the above */ +#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ +#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ +#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ +#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ +#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ + +/* These three values don't affect the parser. They are set but not used. + */ +#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ +#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ +#define PNG_FP_NONZERO 256 /* A non-zero value */ +#define PNG_FP_STICKY 448 /* The above three flags */ + +/* This is available for the caller to store in 'state' if required. Do not + * call the parser after setting it (the parser sometimes clears it.) + */ +#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ + +/* Result codes for the parser (boolean - true means ok, false means + * not ok yet.) + */ +#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ +#define PNG_FP_OK 1 /* The number is valid */ + +/* Tests on the sticky non-zero and negative flags. To pass these checks + * the state must also indicate that the whole number is valid - this is + * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this + * is equivalent to PNG_FP_OK above.) + */ +#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) + /* NZ_MASK: the string is valid and a non-zero negative value */ +#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) + /* Z MASK: the string is valid and a non-zero value. */ + /* PNG_FP_SAW_DIGIT: the string is valid. */ +#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) +#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) +#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) + +/* The actual parser. This can be called repeatedly. It updates + * the index into the string and the state variable (which must + * be initialized to 0). It returns a result code, as above. There + * is no point calling the parser any more if it fails to advance to + * the end of the string - it is stuck on an invalid character (or + * terminated by '\0'). + * + * Note that the pointer will consume an E or even an E+ and then leave + * a 'maybe' state even though a preceding integer.fraction is valid. + * The PNG_FP_WAS_VALID flag indicates that a preceding substring was + * a valid number. It's possible to recover from this by calling + * the parser again (from the start, with state 0) but with a string + * that omits the last character (i.e. set the size to the index of + * the problem character.) This has not been tested within libpng. + */ +PNG_INTERNAL_FUNCTION(int, png_check_fp_number, + (png_const_charp string, size_t size, int *statep, size_t *whereami), + PNG_EMPTY); + +/* This is the same but it checks a complete string and returns true + * only if it just contains a floating point number. As of 1.5.4 this + * function also returns the state at the end of parsing the number if + * it was valid (otherwise it returns 0.) This can be used for testing + * for negative or zero values using the sticky flag. + */ +PNG_INTERNAL_FUNCTION(int, png_check_fp_string, + (png_const_charp string, size_t size), + PNG_EMPTY); +#endif /* pCAL || sCAL */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ + defined(PNG_COLORSPACE_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) ||\ + defined(PNG_READ_pHYs_SUPPORTED) +/* Added at libpng version 1.5.0 */ +/* This is a utility to provide a*times/div (rounded) and indicate + * if there is an overflow. The result is a boolean - false (0) + * for overflow, true (1) if no overflow, in which case *res + * holds the result. + */ +PNG_INTERNAL_FUNCTION(int, png_muldiv, + (png_fixed_point_p res, png_fixed_point a, + png_int_32 multiplied_by, png_int_32 divided_by), + PNG_EMPTY); + +/* Calculate a reciprocal - used for gamma values. This returns + * 0 if the argument is 0 in order to maintain an undefined value; + * there are no warnings. + */ +PNG_INTERNAL_FUNCTION(png_fixed_point, png_reciprocal, + (png_fixed_point a), + PNG_EMPTY); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* The same but gives a reciprocal of the product of two fixed point + * values. Accuracy is suitable for gamma calculations but this is + * not exact - use png_muldiv for that. Only required at present on read. + */ +PNG_INTERNAL_FUNCTION(png_fixed_point, png_reciprocal2, + (png_fixed_point a, png_fixed_point b), + PNG_EMPTY); + +/* Return true if the gamma value is significantly different from 1.0 */ +PNG_INTERNAL_FUNCTION(int, png_gamma_significant, + (png_fixed_point gamma_value), + PNG_EMPTY); + +/* PNGv3: 'resolve' the file gamma according to the new PNGv3 rules for colour + * space information. + * + * NOTE: this uses precisely those chunks that libpng supports. For example it + * doesn't use iCCP and it can only use cICP for known and manageable + * transforms. For this reason a gamma specified by png_set_gamma always takes + * precedence. + */ +PNG_INTERNAL_FUNCTION(png_fixed_point, png_resolve_file_gamma, + (png_const_structrp png_ptr), + PNG_EMPTY); + +/* Internal fixed point gamma correction. These APIs are called as + * required to convert single values - they don't need to be fast, + * they are not used when processing image pixel values. + * + * While the input is an 'unsigned' value it must actually be the + * correct bit value - 0..255 or 0..65535 as required. + */ +PNG_INTERNAL_FUNCTION(png_uint_16, png_gamma_correct, + (png_structrp png_ptr, unsigned int value, png_fixed_point gamma_value), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(png_uint_16, png_gamma_16bit_correct, + (unsigned int value, png_fixed_point gamma_value), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(png_byte, png_gamma_8bit_correct, + (unsigned int value, png_fixed_point gamma_value), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_destroy_gamma_table, + (png_structrp png_ptr), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void, png_build_gamma_table, + (png_structrp png_ptr, int bit_depth), + PNG_EMPTY); +#endif /* READ_GAMMA */ + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Set the RGB coefficients if not already set by png_set_rgb_to_gray */ +PNG_INTERNAL_FUNCTION(void, png_set_rgb_coefficients, + (png_structrp png_ptr), + PNG_EMPTY); +#endif + +#if defined(PNG_cHRM_SUPPORTED) || defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_INTERNAL_FUNCTION(int, png_XYZ_from_xy, + (png_XYZ *XYZ, const png_xy *xy), + PNG_EMPTY); +#endif /* cHRM || READ_RGB_TO_GRAY */ + +#ifdef PNG_COLORSPACE_SUPPORTED +PNG_INTERNAL_FUNCTION(int, png_xy_from_XYZ, + (png_xy *xy, const png_XYZ *XYZ), + PNG_EMPTY); +#endif + +/* SIMPLIFIED READ/WRITE SUPPORT */ +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) +/* The internal structure that png_image::opaque points to. */ +typedef struct png_control +{ + png_structp png_ptr; + png_infop info_ptr; + png_voidp error_buf; /* Always a jmp_buf at present. */ + + png_const_bytep memory; /* Memory buffer. */ + size_t size; /* Size of the memory buffer. */ + + unsigned int for_write :1; /* Otherwise it is a read structure */ + unsigned int owned_file :1; /* We own the file in io_ptr */ +} png_control; + +/* Return the pointer to the jmp_buf from a png_control: necessary because C + * does not reveal the type of the elements of jmp_buf. + */ +#ifdef __cplusplus +# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) +#else +# define png_control_jmp_buf(pc) ((pc)->error_buf) +#endif + +/* Utility to safely execute a piece of libpng code catching and logging any + * errors that might occur. Returns true on success, false on failure (either + * of the function or as a result of a png_error.) + */ +PNG_INTERNAL_CALLBACK(void, png_safe_error, + (png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN); + +#ifdef PNG_WARNINGS_SUPPORTED +PNG_INTERNAL_CALLBACK(void, png_safe_warning, + (png_structp png_ptr, png_const_charp warning_message), + PNG_EMPTY); +#else +# define png_safe_warning 0/*dummy argument*/ +#endif + +PNG_INTERNAL_FUNCTION(int, png_safe_execute, + (png_imagep image, int (*function)(png_voidp), png_voidp arg), + PNG_EMPTY); + +/* Utility to log an error; this also cleans up the png_image; the function + * always returns 0 (false). + */ +PNG_INTERNAL_FUNCTION(int, png_image_error, + (png_imagep image, png_const_charp error_message), + PNG_EMPTY); + +#ifndef PNG_SIMPLIFIED_READ_SUPPORTED +/* png_image_free is used by the write code but not exported */ +PNG_INTERNAL_FUNCTION(void, png_image_free, + (png_imagep image), + PNG_EMPTY); +#endif /* !SIMPLIFIED_READ */ + +#endif /* SIMPLIFIED READ/WRITE */ + +/* These are initialization functions for hardware specific PNG filter + * optimizations; list these here then select the appropriate one at compile + * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined + * the generic code is used. + */ +#ifdef PNG_FILTER_OPTIMIZATIONS +PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); + /* Just declare the optimization that will be used */ +#else + /* List *all* the possible optimizations here - this branch is required if + * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in + * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. + */ +# if PNG_ARM_NEON_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); +#endif + +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); +#endif + +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); +# endif + +# if PNG_INTEL_SSE_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); +# endif +#endif + +#if PNG_LOONGARCH_LSX_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); +#endif + +# if PNG_RISCV_RVV_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_rvv, + (png_structp png_ptr, unsigned int bpp), + PNG_EMPTY); +#endif + +PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, + (png_structrp png_ptr, png_const_charp key, png_bytep new_key), + PNG_EMPTY); + +#if PNG_ARM_NEON_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, + png_riffle_palette_neon, + (png_structrp), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int, + png_do_expand_palette_rgba8_neon, + (png_structrp, + png_row_infop, + png_const_bytep, + const png_bytepp, + const png_bytepp), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int, + png_do_expand_palette_rgb8_neon, + (png_structrp, + png_row_infop, + png_const_bytep, + const png_bytepp, + const png_bytepp), + PNG_EMPTY); +#endif + +/* Maintainer: Put new private prototypes here ^ */ + +#include "pngdebug.h" + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ + +#endif /* PNGPRIV_H */ diff --git a/thirdparty/libpng/upstream/pngread.c b/thirdparty/libpng/upstream/pngread.c index b29863d9a..24199689a 100644 --- a/thirdparty/libpng/upstream/pngread.c +++ b/thirdparty/libpng/upstream/pngread.c @@ -1,4228 +1,4205 @@ - -/* pngread.c - read a PNG file - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that an application calls directly to - * read a PNG file or stream. - */ - -#include "pngpriv.h" -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -# include -#endif - -#ifdef PNG_READ_SUPPORTED - -/* Create a PNG structure for reading, and allocate any memory needed. */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifndef PNG_USER_MEM_SUPPORTED - png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); -#else - return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); -} - -/* Alternate create PNG structure for reading, and allocate any memory - * needed. - */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -#endif /* USER_MEM */ - - if (png_ptr != NULL) - { - png_ptr->mode = PNG_IS_READ_STRUCT; - - /* Added in libpng-1.6.0; this can be used to detect a read structure if - * required (it will be zero in a write structure.) - */ -# ifdef PNG_SEQUENTIAL_READ_SUPPORTED - png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; -# endif - -# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; - - /* In stable builds only warn if an application error can be completely - * handled. - */ -# if PNG_RELEASE_BUILD - png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; -# endif -# endif - - /* TODO: delay this, it can be done in png_init_io (if the app doesn't - * do it itself) avoiding setting the default function if it is not - * required. - */ - png_set_read_fn(png_ptr, NULL, NULL); - } - - return png_ptr; -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. This has been - * changed in v0.90 to allow reading a file that already has the magic - * bytes read from the stream. You can tell libpng how many bytes have - * been read from the beginning of the stream (up to the maximum of 8) - * via png_set_sig_bytes(), and we will only check the remaining bytes - * here. The application can then have access to the signature bytes we - * read if it is determined that this isn't a valid PNG file. - */ -void PNGAPI -png_read_info(png_structrp png_ptr, png_inforp info_ptr) -{ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int keep; -#endif - - png_debug(1, "in png_read_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Read and check the PNG file signature. */ - png_read_sig(png_ptr, info_ptr); - - for (;;) - { - png_uint_32 length = png_read_chunk_header(png_ptr); - png_uint_32 chunk_name = png_ptr->chunk_name; - - /* IDAT logic needs to happen here to simplify getting the two flags - * right. - */ - if (chunk_name == png_IDAT) - { - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - png_chunk_error(png_ptr, "Missing PLTE before IDAT"); - - else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_chunk_benign_error(png_ptr, "Too many IDATs found"); - - png_ptr->mode |= PNG_HAVE_IDAT; - } - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - png_ptr->mode |= PNG_AFTER_IDAT; - } - - /* This should be a binary subdivision search or a hash for - * matching the chunk name rather than a linear search. - */ - if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - - else if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { - png_handle_unknown(png_ptr, info_ptr, length, keep); - - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - - else if (chunk_name == png_IDAT) - { - png_ptr->idat_size = 0; /* It has been consumed */ - break; - } - } -#endif - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - - else if (chunk_name == png_IDAT) - { - png_ptr->idat_size = length; - break; - } - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED - else if (chunk_name == png_eXIf) - png_handle_eXIf(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - - else - png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); - } -} -#endif /* SEQUENTIAL_READ */ - -/* Optional call to update the users info_ptr structure */ -void PNGAPI -png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_update_info"); - - if (png_ptr != NULL) - { - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - png_read_start_row(png_ptr); - -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_read_transform_info(png_ptr, info_ptr); -# else - PNG_UNUSED(info_ptr) -# endif - } - - /* New in 1.6.0 this avoids the bug of doing the initializations twice */ - else - png_app_error(png_ptr, - "png_read_update_info/png_start_read_image: duplicate call"); - } -} - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Initialize palette, background, etc, after transformations - * are set, but before any reading takes place. This allows - * the user to obtain a gamma-corrected palette, for example. - * If the user doesn't call this, we will do it ourselves. - */ -void PNGAPI -png_start_read_image(png_structrp png_ptr) -{ - png_debug(1, "in png_start_read_image"); - - if (png_ptr != NULL) - { - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - png_read_start_row(png_ptr); - - /* New in 1.6.0 this avoids the bug of doing the initializations twice */ - else - png_app_error(png_ptr, - "png_start_read_image/png_read_update_info: duplicate call"); - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing, - * NOTE: this is apparently only supported in the 'sequential' reader. - */ -static void -png_do_read_intrapixel(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_read_intrapixel"); - - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); - *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); - } - } - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (s0 + s1 + 65536) & 0xffff; - png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } - } - } -} -#endif /* MNG_FEATURES */ - -void PNGAPI -png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) -{ - png_row_info row_info; - - if (png_ptr == NULL) - return; - - png_debug2(1, "in png_read_row (row %lu, pass %d)", - (unsigned long)png_ptr->row_number, png_ptr->pass); - - /* png_read_start_row sets the information (in particular iwidth) for this - * interlace pass. - */ - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - png_read_start_row(png_ptr); - - /* 1.5.6: row_info moved out of png_struct to a local here. */ - row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ - row_info.color_type = png_ptr->color_type; - row_info.bit_depth = png_ptr->bit_depth; - row_info.channels = png_ptr->channels; - row_info.pixel_depth = png_ptr->pixel_depth; - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - -#ifdef PNG_WARNINGS_SUPPORTED - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Check for transforms that have been set but were defined out */ -#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - !defined(PNG_READ_PACKSWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) - if ((png_ptr->transformations & PNG_PACK) != 0) - png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) - if ((png_ptr->transformations & PNG_BGR) != 0) - png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); -#endif - } -#endif /* WARNINGS */ - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* If interlaced and we do not need a new row, combine row and return. - * Notice that the pixels we have from previous rows have been transformed - * already; we can only combine like with like (transformed or - * untransformed) and, because of the libpng API for interlaced images, this - * means we must transform before de-interlacing. - */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - switch (png_ptr->pass) - { - case 0: - if (png_ptr->row_number & 0x07) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - png_read_finish_row(png_ptr); - return; - } - break; - - case 1: - if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 2: - if ((png_ptr->row_number & 0x07) != 4) - { - if (dsp_row != NULL && (png_ptr->row_number & 4)) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 3: - if ((png_ptr->row_number & 3) || png_ptr->width < 3) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 4: - if ((png_ptr->row_number & 3) != 2) - { - if (dsp_row != NULL && (png_ptr->row_number & 2)) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 5: - if ((png_ptr->row_number & 1) || png_ptr->width < 2) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - default: - case 6: - if ((png_ptr->row_number & 1) == 0) - { - png_read_finish_row(png_ptr); - return; - } - break; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_error(png_ptr, "Invalid attempt to read row data"); - - /* Fill the row with IDAT data: */ - png_ptr->row_buf[0]=255; /* to force error if no data was found */ - png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); - - if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { - if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) - png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); - else - png_error(png_ptr, "bad adaptive filter value"); - } - - /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before - * 1.5.6, while the buffer really is this big in current versions of libpng - * it may not be in the future, so this was changed just to copy the - * interlaced count: - */ - memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ - png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); - } -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations -# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - || png_ptr->num_palette_max >= 0 -# endif - ) - png_do_read_transformations(png_ptr, &row_info); -#endif - - /* The transformed pixel depth should match the depth now in row_info. */ - if (png_ptr->transformed_pixel_depth == 0) - { - png_ptr->transformed_pixel_depth = row_info.pixel_depth; - if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) - png_error(png_ptr, "sequential row overflow"); - } - - else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) - png_error(png_ptr, "internal sequential row size calculation error"); - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Expand interlaced rows to full size */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - if (png_ptr->pass < 6) - png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); - - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - if (row != NULL) - png_combine_row(png_ptr, row, 0/*row*/); - } - - else -#endif - { - if (row != NULL) - png_combine_row(png_ptr, row, -1/*ignored*/); - - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, -1/*ignored*/); - } - png_read_finish_row(png_ptr); - - if (png_ptr->read_row_fn != NULL) - (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); - -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. If the image is interlaced, - * and png_set_interlace_handling() has been called, the rows need to - * contain the contents of the rows from the previous pass. If the - * image has alpha or transparency, and png_handle_alpha()[*] has been - * called, the rows contents must be initialized to the contents of the - * screen. - * - * "row" holds the actual image, and pixels are placed in it - * as they arrive. If the image is displayed after each pass, it will - * appear to "sparkle" in. "display_row" can be used to display a - * "chunky" progressive image, with finer detail added as it becomes - * available. If you do not want this "chunky" display, you may pass - * NULL for display_row. If you do not want the sparkle display, and - * you have not called png_handle_alpha(), you may pass NULL for rows. - * If you have called png_handle_alpha(), and the image has either an - * alpha channel or a transparency chunk, you must provide a buffer for - * rows. In this case, you do not have to provide a display_row buffer - * also, but you may. If the image is not interlaced, or if you have - * not called png_set_interlace_handling(), the display_row buffer will - * be ignored, so pass NULL to it. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ - -void PNGAPI -png_read_rows(png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows) -{ - png_uint_32 i; - png_bytepp rp; - png_bytepp dp; - - png_debug(1, "in png_read_rows"); - - if (png_ptr == NULL) - return; - - rp = row; - dp = display_row; - if (rp != NULL && dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp++; - png_bytep dptr = *dp++; - - png_read_row(png_ptr, rptr, dptr); - } - - else if (rp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp; - png_read_row(png_ptr, rptr, NULL); - rp++; - } - - else if (dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep dptr = *dp; - png_read_row(png_ptr, NULL, dptr); - dp++; - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the entire image. If the image has an alpha channel or a tRNS - * chunk, and you have called png_handle_alpha()[*], you will need to - * initialize the image to the current image that PNG will be overlaying. - * We set the num_rows again here, in case it was incorrectly set in - * png_read_start_row() by a call to png_read_update_info() or - * png_start_read_image() if png_set_interlace_handling() wasn't called - * prior to either of these functions like it should have been. You can - * only call this function once. If you desire to have an image for - * each pass of a interlaced image, use png_read_rows() instead. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ -void PNGAPI -png_read_image(png_structrp png_ptr, png_bytepp image) -{ - png_uint_32 i, image_height; - int pass, j; - png_bytepp rp; - - png_debug(1, "in png_read_image"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - pass = png_set_interlace_handling(png_ptr); - /* And make sure transforms are initialized. */ - png_start_read_image(png_ptr); - } - else - { - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) == 0) - { - /* Caller called png_start_read_image or png_read_update_info without - * first turning on the PNG_INTERLACE transform. We can fix this here, - * but the caller should do it! - */ - png_warning(png_ptr, "Interlace handling should be turned on when " - "using png_read_image"); - /* Make sure this is set correctly */ - png_ptr->num_rows = png_ptr->height; - } - - /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in - * the above error case. - */ - pass = png_set_interlace_handling(png_ptr); - } -#else - if (png_ptr->interlaced) - png_error(png_ptr, - "Cannot read interlaced image -- interlace handler disabled"); - - pass = 1; -#endif - - image_height=png_ptr->height; - - for (j = 0; j < pass; j++) - { - rp = image; - for (i = 0; i < image_height; i++) - { - png_read_row(png_ptr, *rp, NULL); - rp++; - } - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. Will not read past the end of the - * file, will verify the end is accurate, and will read any comments - * or time information at the end of the file, if info is not NULL. - */ -void PNGAPI -png_read_end(png_structrp png_ptr, png_inforp info_ptr) -{ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int keep; -#endif - - png_debug(1, "in png_read_end"); - - if (png_ptr == NULL) - return; - - /* If png_read_end is called in the middle of reading the rows there may - * still be pending IDAT data and an owned zstream. Deal with this here. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) -#endif - png_read_finish_IDAT(png_ptr); - -#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Report invalid palette index; added at libng-1.5.10 */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= png_ptr->num_palette) - png_benign_error(png_ptr, "Read palette index exceeding num_palette"); -#endif - - do - { - png_uint_32 length = png_read_chunk_header(png_ptr); - png_uint_32 chunk_name = png_ptr->chunk_name; - - if (chunk_name != png_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - - if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - - else if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - - else if (info_ptr == NULL) - png_crc_finish(png_ptr, length); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { - if (chunk_name == png_IDAT) - { - if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) - || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, ".Too many IDATs found"); - } - png_handle_unknown(png_ptr, info_ptr, length, keep); - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - } -#endif - - else if (chunk_name == png_IDAT) - { - /* Zero length IDATs are legal after the last IDAT has been - * read, but not after other chunks have been read. 1.6 does not - * always read all the deflate data; specifically it cannot be relied - * upon to read the Adler32 at the end. If it doesn't ignore IDAT - * chunks which are longer than zero as well: - */ - if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) - || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "..Too many IDATs found"); - - png_crc_finish(png_ptr, length); - } - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED - else if (chunk_name == png_eXIf) - png_handle_eXIf(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - - else - png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); - } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); -} -#endif /* SEQUENTIAL_READ */ - -/* Free all memory used in the read struct */ -static void -png_read_destroy(png_structrp png_ptr) -{ - png_debug(1, "in png_read_destroy"); - -#ifdef PNG_READ_GAMMA_SUPPORTED - png_destroy_gamma_table(png_ptr); -#endif - - png_free(png_ptr, png_ptr->big_row_buf); - png_ptr->big_row_buf = NULL; - png_free(png_ptr, png_ptr->big_prev_row); - png_ptr->big_prev_row = NULL; - png_free(png_ptr, png_ptr->read_buffer); - png_ptr->read_buffer = NULL; - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_free(png_ptr, png_ptr->palette_lookup); - png_ptr->palette_lookup = NULL; - png_free(png_ptr, png_ptr->quantize_index); - png_ptr->quantize_index = NULL; -#endif - - if ((png_ptr->free_me & PNG_FREE_PLTE) != 0) - { - png_zfree(png_ptr, png_ptr->palette); - png_ptr->palette = NULL; - } - png_ptr->free_me &= ~PNG_FREE_PLTE; - -#if defined(PNG_tRNS_SUPPORTED) || \ - defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if ((png_ptr->free_me & PNG_FREE_TRNS) != 0) - { - png_free(png_ptr, png_ptr->trans_alpha); - png_ptr->trans_alpha = NULL; - } - png_ptr->free_me &= ~PNG_FREE_TRNS; -#endif - - inflateEnd(&png_ptr->zstream); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_free(png_ptr, png_ptr->save_buffer); - png_ptr->save_buffer = NULL; -#endif - -#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ - defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; -#endif - -#if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) - png_free(png_ptr, png_ptr->riffled_palette); - png_ptr->riffled_palette = NULL; -#endif - - /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error - * callbacks are still set at this point. They are required to complete the - * destruction of the png_struct itself. - */ -} - -/* Free all memory used by the read */ -void PNGAPI -png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, - png_infopp end_info_ptr_ptr) -{ - png_structrp png_ptr = NULL; - - png_debug(1, "in png_destroy_read_struct"); - - if (png_ptr_ptr != NULL) - png_ptr = *png_ptr_ptr; - - if (png_ptr == NULL) - return; - - /* libpng 1.6.0: use the API to destroy info structs to ensure consistent - * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. - * The extra was, apparently, unnecessary yet this hides memory leak bugs. - */ - png_destroy_info_struct(png_ptr, end_info_ptr_ptr); - png_destroy_info_struct(png_ptr, info_ptr_ptr); - - *png_ptr_ptr = NULL; - png_read_destroy(png_ptr); - png_destroy_png_struct(png_ptr); -} - -void PNGAPI -png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->read_row_fn = read_row_fn; -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_read_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, voidp params) -{ - png_debug(1, "in png_read_png"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). - */ - png_read_info(png_ptr, info_ptr); - if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) - png_error(png_ptr, "Image is too high to process with png_read_png()"); - - /* -------------- image transformations start here ------------------- */ - /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM - * is not implemented. This will only happen in de-configured (non-default) - * libpng builds. The results can be unexpected - png_read_png may return - * short or mal-formed rows because the transform is skipped. - */ - - /* Tell libpng to strip 16-bit/color files down to 8 bits per color. - */ - if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) - /* Added at libpng-1.5.4. "strip_16" produces the same result that it - * did in earlier versions, while "scale_16" is now more accurate. - */ -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_set_scale_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); -#endif - - /* If both SCALE and STRIP are required pngrtran will effectively cancel the - * latter by doing SCALE first. This is ok and allows apps not to check for - * which is supported to get the right answer. - */ - if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - png_set_strip_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); -#endif - - /* Strip alpha bytes from the input data without combining with - * the background (not recommended). - */ - if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - png_set_strip_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); -#endif - - /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). - */ - if ((transforms & PNG_TRANSFORM_PACKING) != 0) -#ifdef PNG_READ_PACK_SUPPORTED - png_set_packing(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); -#endif - - /* Change the order of packed pixels to least significant bit first - * (not useful if you are using png_set_packing). - */ - if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -#ifdef PNG_READ_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); -#endif - - /* Expand paletted colors into true RGB triplets - * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel - * Expand paletted or RGB images with transparency to full alpha - * channels so the data will be available as RGBA quartets. - */ - if ((transforms & PNG_TRANSFORM_EXPAND) != 0) -#ifdef PNG_READ_EXPAND_SUPPORTED - png_set_expand(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); -#endif - - /* We don't handle background color or gamma transformation or quantizing. - */ - - /* Invert monochrome files to have 0 as white and 1 as black - */ - if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -#ifdef PNG_READ_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); -#endif - - /* If you want to shift the pixel values from the range [0,255] or - * [0,65535] to the original [0,7] or [0,31], or whatever range the - * colors were originally in: - */ - if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); -#endif - - /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ - if ((transforms & PNG_TRANSFORM_BGR) != 0) -#ifdef PNG_READ_BGR_SUPPORTED - png_set_bgr(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); -#endif - - /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ - if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - png_set_swap_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); -#endif - - /* Swap bytes of 16-bit files to least significant byte first */ - if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -#ifdef PNG_READ_SWAP_SUPPORTED - png_set_swap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); -#endif - -/* Added at libpng-1.2.41 */ - /* Invert the alpha channel from opacity to transparency */ - if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - png_set_invert_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); -#endif - -/* Added at libpng-1.2.41 */ - /* Expand grayscale image to RGB */ - if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - png_set_gray_to_rgb(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); -#endif - -/* Added at libpng-1.5.4 */ - if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) -#ifdef PNG_READ_EXPAND_16_SUPPORTED - png_set_expand_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); -#endif - - /* We don't handle adding filler bytes */ - - /* We use png_read_image and rely on that for interlace handling, but we also - * call png_read_update_info therefore must turn on interlace handling now: - */ - (void)png_set_interlace_handling(png_ptr); - - /* Optional call to gamma correct and add the background to the palette - * and update info structure. REQUIRED if you are expecting libpng to - * update the palette for you (i.e., you selected such a transform above). - */ - png_read_update_info(png_ptr, info_ptr); - - /* -------------- image transformations end here ------------------- */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - if (info_ptr->row_pointers == NULL) - { - png_uint_32 iptr; - - info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, - info_ptr->height * (sizeof (png_bytep)))); - - for (iptr=0; iptrheight; iptr++) - info_ptr->row_pointers[iptr] = NULL; - - info_ptr->free_me |= PNG_FREE_ROWS; - - for (iptr = 0; iptr < info_ptr->height; iptr++) - info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, - png_malloc(png_ptr, info_ptr->rowbytes)); - } - - png_read_image(png_ptr, info_ptr->row_pointers); - info_ptr->valid |= PNG_INFO_IDAT; - - /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - - PNG_UNUSED(params) -} -#endif /* INFO_IMAGE */ -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* SIMPLIFIED READ - * - * This code currently relies on the sequential reader, though it could easily - * be made to work with the progressive one. - */ -/* Arguments to png_image_finish_read: */ - -/* Encoding of PNG data (used by the color-map code) */ -# define P_NOTSET 0 /* File encoding not yet known */ -# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ -# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ -# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ -# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ - -/* Color-map processing: after libpng has run on the PNG image further - * processing may be needed to convert the data to color-map indices. - */ -#define PNG_CMAP_NONE 0 -#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ -#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ -#define PNG_CMAP_RGB 3 /* Process RGB data */ -#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ - -/* The following document where the background is for each processing case. */ -#define PNG_CMAP_NONE_BACKGROUND 256 -#define PNG_CMAP_GA_BACKGROUND 231 -#define PNG_CMAP_TRANS_BACKGROUND 254 -#define PNG_CMAP_RGB_BACKGROUND 256 -#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 - -typedef struct -{ - /* Arguments: */ - png_imagep image; - png_voidp buffer; - png_int_32 row_stride; - png_voidp colormap; - png_const_colorp background; - /* Local variables: */ - png_voidp local_row; - png_voidp first_row; - ptrdiff_t row_bytes; /* step between rows */ - int file_encoding; /* E_ values above */ - png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ - int colormap_processing; /* PNG_CMAP_ values above */ -} png_image_read_control; - -/* Do all the *safe* initialization - 'safe' means that png_error won't be - * called, so setting up the jmp_buf is not required. This means that anything - * called from here must *not* call png_malloc - it has to call png_malloc_warn - * instead so that control is returned safely back to this routine. - */ -static int -png_image_read_init(png_imagep image) -{ - if (image->opaque == NULL) - { - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); - - /* And set the rest of the structure to NULL to ensure that the various - * fields are consistent. - */ - memset(image, 0, (sizeof *image)); - image->version = PNG_IMAGE_VERSION; - - if (png_ptr != NULL) - { - png_infop info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr != NULL) - { - png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); - - if (control != NULL) - { - memset(control, 0, (sizeof *control)); - - control->png_ptr = png_ptr; - control->info_ptr = info_ptr; - control->for_write = 0; - - image->opaque = control; - return 1; - } - - /* Error clean up */ - png_destroy_info_struct(png_ptr, &info_ptr); - } - - png_destroy_read_struct(&png_ptr, NULL, NULL); - } - - return png_image_error(image, "png_image_read: out of memory"); - } - - return png_image_error(image, "png_image_read: opaque pointer not NULL"); -} - -/* Utility to find the base format of a PNG file from a png_struct. */ -static png_uint_32 -png_image_format(png_structrp png_ptr) -{ - png_uint_32 format = 0; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - format |= PNG_FORMAT_FLAG_COLOR; - - if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - format |= PNG_FORMAT_FLAG_ALPHA; - - /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS - * sets the png_struct fields; that's all we are interested in here. The - * precise interaction with an app call to png_set_tRNS and PNG file reading - * is unclear. - */ - else if (png_ptr->num_trans > 0) - format |= PNG_FORMAT_FLAG_ALPHA; - - if (png_ptr->bit_depth == 16) - format |= PNG_FORMAT_FLAG_LINEAR; - - if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) - format |= PNG_FORMAT_FLAG_COLORMAP; - - return format; -} - -/* Is the given gamma significantly different from sRGB? The test is the same - * one used in pngrtran.c when deciding whether to do gamma correction. The - * arithmetic optimizes the division by using the fact that the inverse of the - * file sRGB gamma is 2.2 - */ -static int -png_gamma_not_sRGB(png_fixed_point g) -{ - if (g < PNG_FP_1) - { - /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ - if (g == 0) - return 0; - - return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); - } - - return 1; -} - -/* Do the main body of a 'png_image_begin_read' function; read the PNG file - * header and fill in all the information. This is executed in a safe context, - * unlike the init routine above. - */ -static int -png_image_read_header(png_voidp argument) -{ - png_imagep image = png_voidcast(png_imagep, argument); - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED - png_set_benign_errors(png_ptr, 1/*warn*/); -#endif - png_read_info(png_ptr, info_ptr); - - /* Do this the fast way; just read directly out of png_struct. */ - image->width = png_ptr->width; - image->height = png_ptr->height; - - { - png_uint_32 format = png_image_format(png_ptr); - - image->format = format; - -#ifdef PNG_COLORSPACE_SUPPORTED - /* Does the colorspace match sRGB? If there is no color endpoint - * (colorant) information assume yes, otherwise require the - * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the - * colorspace has been determined to be invalid ignore it. - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags - & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| - PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) - image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; -#endif - } - - /* We need the maximum number of entries regardless of the format the - * application sets here. - */ - { - png_uint_32 cmap_entries; - - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - cmap_entries = 1U << png_ptr->bit_depth; - break; - - case PNG_COLOR_TYPE_PALETTE: - cmap_entries = (png_uint_32)png_ptr->num_palette; - break; - - default: - cmap_entries = 256; - break; - } - - if (cmap_entries > 256) - cmap_entries = 256; - - image->colormap_entries = cmap_entries; - } - - return 1; -} - -#ifdef PNG_STDIO_SUPPORTED -int PNGAPI -png_image_begin_read_from_stdio(png_imagep image, FILE* file) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file != NULL) - { - if (png_image_read_init(image) != 0) - { - /* This is slightly evil, but png_init_io doesn't do anything other - * than this and we haven't changed the standard IO functions so - * this saves a 'safe' function. - */ - image->opaque->png_ptr->io_ptr = file; - return png_safe_execute(image, png_image_read_header, image); - } - } - - else - return png_image_error(image, - "png_image_begin_read_from_stdio: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); - - return 0; -} - -int PNGAPI -png_image_begin_read_from_file(png_imagep image, const char *file_name) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file_name != NULL) - { - FILE *fp = fopen(file_name, "rb"); - - if (fp != NULL) - { - if (png_image_read_init(image) != 0) - { - image->opaque->png_ptr->io_ptr = fp; - image->opaque->owned_file = 1; - return png_safe_execute(image, png_image_read_header, image); - } - - /* Clean up: just the opened file. */ - (void)fclose(fp); - } - - else - return png_image_error(image, strerror(errno)); - } - - else - return png_image_error(image, - "png_image_begin_read_from_file: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); - - return 0; -} -#endif /* STDIO */ - -static void PNGCBAPI -png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need) -{ - if (png_ptr != NULL) - { - png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); - if (image != NULL) - { - png_controlp cp = image->opaque; - if (cp != NULL) - { - png_const_bytep memory = cp->memory; - size_t size = cp->size; - - if (memory != NULL && size >= need) - { - memcpy(out, memory, need); - cp->memory = memory + need; - cp->size = size - need; - return; - } - - png_error(png_ptr, "read beyond end of data"); - } - } - - png_error(png_ptr, "invalid memory read"); - } -} - -int PNGAPI png_image_begin_read_from_memory(png_imagep image, - png_const_voidp memory, size_t size) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (memory != NULL && size > 0) - { - if (png_image_read_init(image) != 0) - { - /* Now set the IO functions to read from the memory buffer and - * store it into io_ptr. Again do this in-place to avoid calling a - * libpng function that requires error handling. - */ - image->opaque->memory = png_voidcast(png_const_bytep, memory); - image->opaque->size = size; - image->opaque->png_ptr->io_ptr = image; - image->opaque->png_ptr->read_data_fn = png_image_memory_read; - - return png_safe_execute(image, png_image_read_header, image); - } - } - - else - return png_image_error(image, - "png_image_begin_read_from_memory: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); - - return 0; -} - -/* Utility function to skip chunks that are not used by the simplified image - * read functions and an appropriate macro to call it. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -static void -png_image_skip_unused_chunks(png_structrp png_ptr) -{ - /* Prepare the reader to ignore all recognized chunks whose data will not - * be used, i.e., all chunks recognized by libpng except for those - * involved in basic image reading: - * - * IHDR, PLTE, IDAT, IEND - * - * Or image data handling: - * - * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. - * - * This provides a small performance improvement and eliminates any - * potential vulnerability to security problems in the unused chunks. - * - * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored - * too. This allows the simplified API to be compiled without iCCP support, - * however if the support is there the chunk is still checked to detect - * errors (which are unfortunately quite common.) - */ - { - static const png_byte chunks_to_process[] = { - 98, 75, 71, 68, '\0', /* bKGD */ - 99, 72, 82, 77, '\0', /* cHRM */ - 103, 65, 77, 65, '\0', /* gAMA */ -# ifdef PNG_READ_iCCP_SUPPORTED - 105, 67, 67, 80, '\0', /* iCCP */ -# endif - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 82, 71, 66, '\0', /* sRGB */ - }; - - /* Ignore unknown chunks and all other chunks except for the - * IHDR, PLTE, tRNS, IDAT, and IEND chunks. - */ - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, - NULL, -1); - - /* But do not ignore image data handling chunks */ - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, - chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); - } -} - -# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) -#else -# define PNG_SKIP_CHUNKS(p) ((void)0) -#endif /* HANDLE_AS_UNKNOWN */ - -/* The following macro gives the exact rounded answer for all values in the - * range 0..255 (it actually divides by 51.2, but the rounding still generates - * the correct numbers 0..5 - */ -#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) - -/* Utility functions to make particular color-maps */ -static void -set_file_encoding(png_image_read_control *display) -{ - png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; - if (png_gamma_significant(g) != 0) - { - if (png_gamma_not_sRGB(g) != 0) - { - display->file_encoding = P_FILE; - display->gamma_to_linear = png_reciprocal(g); - } - - else - display->file_encoding = P_sRGB; - } - - else - display->file_encoding = P_LINEAR8; -} - -static unsigned int -decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) -{ - if (encoding == P_FILE) /* double check */ - encoding = display->file_encoding; - - if (encoding == P_NOTSET) /* must be the file encoding */ - { - set_file_encoding(display); - encoding = display->file_encoding; - } - - switch (encoding) - { - case P_FILE: - value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); - break; - - case P_sRGB: - value = png_sRGB_table[value]; - break; - - case P_LINEAR: - break; - - case P_LINEAR8: - value *= 257; - break; - -#ifdef __GNUC__ - default: - png_error(display->image->opaque->png_ptr, - "unexpected encoding (internal error)"); -#endif - } - - return value; -} - -static png_uint_32 -png_colormap_compose(png_image_read_control *display, - png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, - png_uint_32 background, int encoding) -{ - /* The file value is composed on the background, the background has the given - * encoding and so does the result, the file is encoded with P_FILE and the - * file and alpha are 8-bit values. The (output) encoding will always be - * P_LINEAR or P_sRGB. - */ - png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); - png_uint_32 b = decode_gamma(display, background, encoding); - - /* The alpha is always an 8-bit value (it comes from the palette), the value - * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. - */ - f = f * alpha + b * (255-alpha); - - if (encoding == P_LINEAR) - { - /* Scale to 65535; divide by 255, approximately (in fact this is extremely - * accurate, it divides by 255.00000005937181414556, with no overflow.) - */ - f *= 257; /* Now scaled by 65535 */ - f += f >> 16; - f = (f+32768) >> 16; - } - - else /* P_sRGB */ - f = PNG_sRGB_FROM_LINEAR(f); - - return f; -} - -/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must - * be 8-bit. - */ -static void -png_create_colormap_entry(png_image_read_control *display, - png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, - png_uint_32 alpha, int encoding) -{ - png_imagep image = display->image; - int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; - int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && - (red != green || green != blue); - - if (ip > 255) - png_error(image->opaque->png_ptr, "color-map index out of range"); - - /* Update the cache with whether the file gamma is significantly different - * from sRGB. - */ - if (encoding == P_FILE) - { - if (display->file_encoding == P_NOTSET) - set_file_encoding(display); - - /* Note that the cached value may be P_FILE too, but if it is then the - * gamma_to_linear member has been set. - */ - encoding = display->file_encoding; - } - - if (encoding == P_FILE) - { - png_fixed_point g = display->gamma_to_linear; - - red = png_gamma_16bit_correct(red*257, g); - green = png_gamma_16bit_correct(green*257, g); - blue = png_gamma_16bit_correct(blue*257, g); - - if (convert_to_Y != 0 || output_encoding == P_LINEAR) - { - alpha *= 257; - encoding = P_LINEAR; - } - - else - { - red = PNG_sRGB_FROM_LINEAR(red * 255); - green = PNG_sRGB_FROM_LINEAR(green * 255); - blue = PNG_sRGB_FROM_LINEAR(blue * 255); - encoding = P_sRGB; - } - } - - else if (encoding == P_LINEAR8) - { - /* This encoding occurs quite frequently in test cases because PngSuite - * includes a gAMA 1.0 chunk with most images. - */ - red *= 257; - green *= 257; - blue *= 257; - alpha *= 257; - encoding = P_LINEAR; - } - - else if (encoding == P_sRGB && - (convert_to_Y != 0 || output_encoding == P_LINEAR)) - { - /* The values are 8-bit sRGB values, but must be converted to 16-bit - * linear. - */ - red = png_sRGB_table[red]; - green = png_sRGB_table[green]; - blue = png_sRGB_table[blue]; - alpha *= 257; - encoding = P_LINEAR; - } - - /* This is set if the color isn't gray but the output is. */ - if (encoding == P_LINEAR) - { - if (convert_to_Y != 0) - { - /* NOTE: these values are copied from png_do_rgb_to_gray */ - png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + - (png_uint_32)2366 * blue; - - if (output_encoding == P_LINEAR) - y = (y + 16384) >> 15; - - else - { - /* y is scaled by 32768, we need it scaled by 255: */ - y = (y + 128) >> 8; - y *= 255; - y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); - alpha = PNG_DIV257(alpha); - encoding = P_sRGB; - } - - blue = red = green = y; - } - - else if (output_encoding == P_sRGB) - { - red = PNG_sRGB_FROM_LINEAR(red * 255); - green = PNG_sRGB_FROM_LINEAR(green * 255); - blue = PNG_sRGB_FROM_LINEAR(blue * 255); - alpha = PNG_DIV257(alpha); - encoding = P_sRGB; - } - } - - if (encoding != output_encoding) - png_error(image->opaque->png_ptr, "bad encoding (internal error)"); - - /* Store the value. */ - { -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else -# define afirst 0 -# endif -# ifdef PNG_FORMAT_BGR_SUPPORTED - int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else -# define bgr 0 -# endif - - if (output_encoding == P_LINEAR) - { - png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); - - entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); - - /* The linear 16-bit values must be pre-multiplied by the alpha channel - * value, if less than 65535 (this is, effectively, composite on black - * if the alpha channel is removed.) - */ - switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) - { - case 4: - entry[afirst ? 0 : 3] = (png_uint_16)alpha; - /* FALLTHROUGH */ - - case 3: - if (alpha < 65535) - { - if (alpha > 0) - { - blue = (blue * alpha + 32767U)/65535U; - green = (green * alpha + 32767U)/65535U; - red = (red * alpha + 32767U)/65535U; - } - - else - red = green = blue = 0; - } - entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; - entry[afirst + 1] = (png_uint_16)green; - entry[afirst + bgr] = (png_uint_16)red; - break; - - case 2: - entry[1 ^ afirst] = (png_uint_16)alpha; - /* FALLTHROUGH */ - - case 1: - if (alpha < 65535) - { - if (alpha > 0) - green = (green * alpha + 32767U)/65535U; - - else - green = 0; - } - entry[afirst] = (png_uint_16)green; - break; - - default: - break; - } - } - - else /* output encoding is P_sRGB */ - { - png_bytep entry = png_voidcast(png_bytep, display->colormap); - - entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); - - switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) - { - case 4: - entry[afirst ? 0 : 3] = (png_byte)alpha; - /* FALLTHROUGH */ - case 3: - entry[afirst + (2 ^ bgr)] = (png_byte)blue; - entry[afirst + 1] = (png_byte)green; - entry[afirst + bgr] = (png_byte)red; - break; - - case 2: - entry[1 ^ afirst] = (png_byte)alpha; - /* FALLTHROUGH */ - case 1: - entry[afirst] = (png_byte)green; - break; - - default: - break; - } - } - -# ifdef afirst -# undef afirst -# endif -# ifdef bgr -# undef bgr -# endif - } -} - -static int -make_gray_file_colormap(png_image_read_control *display) -{ - unsigned int i; - - for (i=0; i<256; ++i) - png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); - - return (int)i; -} - -static int -make_gray_colormap(png_image_read_control *display) -{ - unsigned int i; - - for (i=0; i<256; ++i) - png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); - - return (int)i; -} -#define PNG_GRAY_COLORMAP_ENTRIES 256 - -static int -make_ga_colormap(png_image_read_control *display) -{ - unsigned int i, a; - - /* Alpha is retained, the output will be a color-map with entries - * selected by six levels of alpha. One transparent entry, 6 gray - * levels for all the intermediate alpha values, leaving 230 entries - * for the opaque grays. The color-map entries are the six values - * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the - * relevant entry. - * - * if (alpha > 229) // opaque - * { - * // The 231 entries are selected to make the math below work: - * base = 0; - * entry = (231 * gray + 128) >> 8; - * } - * else if (alpha < 26) // transparent - * { - * base = 231; - * entry = 0; - * } - * else // partially opaque - * { - * base = 226 + 6 * PNG_DIV51(alpha); - * entry = PNG_DIV51(gray); - * } - */ - i = 0; - while (i < 231) - { - unsigned int gray = (i * 256 + 115) / 231; - png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); - } - - /* 255 is used here for the component values for consistency with the code - * that undoes premultiplication in pngwrite.c. - */ - png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); - - for (a=1; a<5; ++a) - { - unsigned int g; - - for (g=0; g<6; ++g) - png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, - P_sRGB); - } - - return (int)i; -} - -#define PNG_GA_COLORMAP_ENTRIES 256 - -static int -make_rgb_colormap(png_image_read_control *display) -{ - unsigned int i, r; - - /* Build a 6x6x6 opaque RGB cube */ - for (i=r=0; r<6; ++r) - { - unsigned int g; - - for (g=0; g<6; ++g) - { - unsigned int b; - - for (b=0; b<6; ++b) - png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, - P_sRGB); - } - } - - return (int)i; -} - -#define PNG_RGB_COLORMAP_ENTRIES 216 - -/* Return a palette index to the above palette given three 8-bit sRGB values. */ -#define PNG_RGB_INDEX(r,g,b) \ - ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) - -static int -png_image_read_colormap(png_voidp argument) -{ - png_image_read_control *display = - png_voidcast(png_image_read_control*, argument); - png_imagep image = display->image; - - png_structrp png_ptr = image->opaque->png_ptr; - png_uint_32 output_format = image->format; - int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; - - unsigned int cmap_entries; - unsigned int output_processing; /* Output processing option */ - unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ - - /* Background information; the background color and the index of this color - * in the color-map if it exists (else 256). - */ - unsigned int background_index = 256; - png_uint_32 back_r, back_g, back_b; - - /* Flags to accumulate things that need to be done to the input. */ - int expand_tRNS = 0; - - /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is - * very difficult to do, the results look awful, and it is difficult to see - * what possible use it is because the application can't control the - * color-map. - */ - if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || - png_ptr->num_trans > 0) /* alpha in input */ && - ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) - { - if (output_encoding == P_LINEAR) /* compose on black */ - back_b = back_g = back_r = 0; - - else if (display->background == NULL /* no way to remove it */) - png_error(png_ptr, - "background color must be supplied to remove alpha/transparency"); - - /* Get a copy of the background color (this avoids repeating the checks - * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the - * output format. - */ - else - { - back_g = display->background->green; - if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) - { - back_r = display->background->red; - back_b = display->background->blue; - } - else - back_b = back_r = back_g; - } - } - - else if (output_encoding == P_LINEAR) - back_b = back_r = back_g = 65535; - - else - back_b = back_r = back_g = 255; - - /* Default the input file gamma if required - this is necessary because - * libpng assumes that if no gamma information is present the data is in the - * output format, but the simplified API deduces the gamma from the input - * format. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) - { - /* Do this directly, not using the png_colorspace functions, to ensure - * that it happens even if the colorspace is invalid (though probably if - * it is the setting will be ignored) Note that the same thing can be - * achieved at the application interface with png_set_gAMA. - */ - if (png_ptr->bit_depth == 16 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; - - else - png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; - - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* Decide what to do based on the PNG color type of the input data. The - * utility function png_create_colormap_entry deals with most aspects of the - * output transformations; this code works out how to produce bytes of - * color-map entries from the original format. - */ - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - if (png_ptr->bit_depth <= 8) - { - /* There at most 256 colors in the output, regardless of - * transparency. - */ - unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; - - cmap_entries = 1U << png_ptr->bit_depth; - if (cmap_entries > image->colormap_entries) - png_error(png_ptr, "gray[8] color-map: too few entries"); - - step = 255 / (cmap_entries - 1); - output_processing = PNG_CMAP_NONE; - - /* If there is a tRNS chunk then this either selects a transparent - * value or, if the output has no alpha, the background color. - */ - if (png_ptr->num_trans > 0) - { - trans = png_ptr->trans_color.gray; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) - back_alpha = output_encoding == P_LINEAR ? 65535 : 255; - } - - /* png_create_colormap_entry just takes an RGBA and writes the - * corresponding color-map entry using the format from 'image', - * including the required conversion to sRGB or linear as - * appropriate. The input values are always either sRGB (if the - * gamma correction flag is 0) or 0..255 scaled file encoded values - * (if the function must gamma correct them). - */ - for (i=val=0; ibit_depth < 8) - png_set_packing(png_ptr); - } - - else /* bit depth is 16 */ - { - /* The 16-bit input values can be converted directly to 8-bit gamma - * encoded values; however, if a tRNS chunk is present 257 color-map - * entries are required. This means that the extra entry requires - * special processing; add an alpha channel, sacrifice gray level - * 254 and convert transparent (alpha==0) entries to that. - * - * Use libpng to chop the data to 8 bits. Convert it to sRGB at the - * same time to minimize quality loss. If a tRNS chunk is present - * this means libpng must handle it too; otherwise it is impossible - * to do the exact match on the 16-bit value. - * - * If the output has no alpha channel *and* the background color is - * gray then it is possible to let libpng handle the substitution by - * ensuring that the corresponding gray level matches the background - * color exactly. - */ - data_encoding = P_sRGB; - - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray[16] color-map: too few entries"); - - cmap_entries = (unsigned int)make_gray_colormap(display); - - if (png_ptr->num_trans > 0) - { - unsigned int back_alpha; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - back_alpha = 0; - - else - { - if (back_r == back_g && back_g == back_b) - { - /* Background is gray; no special processing will be - * required. - */ - png_color_16 c; - png_uint_32 gray = back_g; - - if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(gray * 255); - - /* And make sure the corresponding palette entry - * matches. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); - } - - /* The background passed to libpng, however, must be the - * sRGB value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = (png_uint_16)gray; - - /* NOTE: does this work without expanding tRNS to alpha? - * It should be the color->gray case below apparently - * doesn't. - */ - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_NONE; - break; - } -#ifdef __COVERITY__ - /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) - * here. - */ - back_alpha = 255; -#else - back_alpha = output_encoding == P_LINEAR ? 65535 : 255; -#endif - } - - /* output_processing means that the libpng-processed row will be - * 8-bit GA and it has to be processing to single byte color-map - * values. Entry 254 is replaced by either a completely - * transparent entry or by the background color at full - * precision (and the background color is not a simple gray - * level in this case.) - */ - expand_tRNS = 1; - output_processing = PNG_CMAP_TRANS; - background_index = 254; - - /* And set (overwrite) color-map entry 254 to the actual - * background color at full precision. - */ - png_create_colormap_entry(display, 254, back_r, back_g, back_b, - back_alpha, output_encoding); - } - - else - output_processing = PNG_CMAP_NONE; - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum - * of 65536 combinations. If, however, the alpha channel is to be - * removed there are only 256 possibilities if the background is gray. - * (Otherwise there is a subset of the 65536 possibilities defined by - * the triangle between black, white and the background color.) - * - * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to - * worry about tRNS matching - tRNS is ignored if there is an alpha - * channel. - */ - data_encoding = P_sRGB; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray+alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_ga_colormap(display); - - background_index = PNG_CMAP_GA_BACKGROUND; - output_processing = PNG_CMAP_GA; - } - - else /* alpha is removed */ - { - /* Alpha must be removed as the PNG data is processed when the - * background is a color because the G and A channels are - * independent and the vector addition (non-parallel vectors) is a - * 2-D problem. - * - * This can be reduced to the same algorithm as above by making a - * colormap containing gray levels (for the opaque grays), a - * background entry (for a transparent pixel) and a set of four six - * level color values, one set for each intermediate alpha value. - * See the comments in make_ga_colormap for how this works in the - * per-pixel processing. - * - * If the background is gray, however, we only need a 256 entry gray - * level color map. It is sufficient to make the entry generated - * for the background color be exactly the color specified. - */ - if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || - (back_r == back_g && back_g == back_b)) - { - /* Background is gray; no special processing will be required. */ - png_color_16 c; - png_uint_32 gray = back_g; - - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray-alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_gray_colormap(display); - - if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(gray * 255); - - /* And make sure the corresponding palette entry matches. */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); - } - - /* The background passed to libpng, however, must be the sRGB - * value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = (png_uint_16)gray; - - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_NONE; - } - - else - { - png_uint_32 i, a; - - /* This is the same as png_make_ga_colormap, above, except that - * the entries are all opaque. - */ - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "ga-alpha color-map: too few entries"); - - i = 0; - while (i < 231) - { - png_uint_32 gray = (i * 256 + 115) / 231; - png_create_colormap_entry(display, i++, gray, gray, gray, - 255, P_sRGB); - } - - /* NOTE: this preserves the full precision of the application - * background color. - */ - background_index = i; - png_create_colormap_entry(display, i++, back_r, back_g, back_b, -#ifdef __COVERITY__ - /* Coverity claims that output_encoding - * cannot be 2 (P_LINEAR) here. - */ 255U, -#else - output_encoding == P_LINEAR ? 65535U : 255U, -#endif - output_encoding); - - /* For non-opaque input composite on the sRGB background - this - * requires inverting the encoding for each component. The input - * is still converted to the sRGB encoding because this is a - * reasonable approximate to the logarithmic curve of human - * visual sensitivity, at least over the narrow range which PNG - * represents. Consequently 'G' is always sRGB encoded, while - * 'A' is linear. We need the linear background colors. - */ - if (output_encoding == P_sRGB) /* else already linear */ - { - /* This may produce a value not exactly matching the - * background, but that's ok because these numbers are only - * used when alpha != 0 - */ - back_r = png_sRGB_table[back_r]; - back_g = png_sRGB_table[back_g]; - back_b = png_sRGB_table[back_b]; - } - - for (a=1; a<5; ++a) - { - unsigned int g; - - /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled - * by an 8-bit alpha value (0..255). - */ - png_uint_32 alpha = 51 * a; - png_uint_32 back_rx = (255-alpha) * back_r; - png_uint_32 back_gx = (255-alpha) * back_g; - png_uint_32 back_bx = (255-alpha) * back_b; - - for (g=0; g<6; ++g) - { - png_uint_32 gray = png_sRGB_table[g*51] * alpha; - - png_create_colormap_entry(display, i++, - PNG_sRGB_FROM_LINEAR(gray + back_rx), - PNG_sRGB_FROM_LINEAR(gray + back_gx), - PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); - } - } - - cmap_entries = i; - output_processing = PNG_CMAP_GA; - } - } - break; - - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - /* Exclude the case where the output is gray; we can always handle this - * with the cases above. - */ - if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) - { - /* The color-map will be grayscale, so we may as well convert the - * input RGB values to a simple grayscale and use the grayscale - * code above. - * - * NOTE: calling this apparently damages the recognition of the - * transparent color in background color handling; call - * png_set_tRNS_to_alpha before png_set_background_fixed. - */ - png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, - -1); - data_encoding = P_sRGB; - - /* The output will now be one or two 8-bit gray or gray+alpha - * channels. The more complex case arises when the input has alpha. - */ - if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) && - (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Both input and output have an alpha channel, so no background - * processing is required; just map the GA bytes to the right - * color-map entry. - */ - expand_tRNS = 1; - - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb[ga] color-map: too few entries"); - - cmap_entries = (unsigned int)make_ga_colormap(display); - background_index = PNG_CMAP_GA_BACKGROUND; - output_processing = PNG_CMAP_GA; - } - - else - { - /* Either the input or the output has no alpha channel, so there - * will be no non-opaque pixels in the color-map; it will just be - * grayscale. - */ - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb[gray] color-map: too few entries"); - - /* Ideally this code would use libpng to do the gamma correction, - * but if an input alpha channel is to be removed we will hit the - * libpng bug in gamma+compose+rgb-to-gray (the double gamma - * correction bug). Fix this by dropping the gamma correction in - * this case and doing it in the palette; this will result in - * duplicate palette entries, but that's better than the - * alternative of double gamma correction. - */ - if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) && - png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) - { - cmap_entries = (unsigned int)make_gray_file_colormap(display); - data_encoding = P_FILE; - } - - else - cmap_entries = (unsigned int)make_gray_colormap(display); - - /* But if the input has alpha or transparency it must be removed - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) - { - png_color_16 c; - png_uint_32 gray = back_g; - - /* We need to ensure that the application background exists in - * the colormap and that completely transparent pixels map to - * it. Achieve this simply by ensuring that the entry - * selected for the background really is the background color. - */ - if (data_encoding == P_FILE) /* from the fixup above */ - { - /* The app supplied a gray which is in output_encoding, we - * need to convert it to a value of the input (P_FILE) - * encoding then set this palette entry to the required - * output encoding. - */ - if (output_encoding == P_sRGB) - gray = png_sRGB_table[gray]; /* now P_LINEAR */ - - gray = PNG_DIV257(png_gamma_16bit_correct(gray, - png_ptr->colorspace.gamma)); /* now P_FILE */ - - /* And make sure the corresponding palette entry contains - * exactly the required sRGB value. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, output_encoding); - } - - else if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(gray * 255); - - /* And make sure the corresponding palette entry matches. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, P_LINEAR); - } - - /* The background passed to libpng, however, must be the - * output (normally sRGB) value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = (png_uint_16)gray; - - /* NOTE: the following is apparently a bug in libpng. Without - * it the transparent color recognition in - * png_set_background_fixed seems to go wrong. - */ - expand_tRNS = 1; - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - } - - output_processing = PNG_CMAP_NONE; - } - } - - else /* output is color */ - { - /* We could use png_quantize here so long as there is no transparent - * color or alpha; png_quantize ignores alpha. Easier overall just - * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. - * Consequently we always want libpng to produce sRGB data. - */ - data_encoding = P_sRGB; - - /* Is there any transparency or alpha? */ - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) - { - /* Is there alpha in the output too? If so all four channels are - * processed into a special RGB cube with alpha support. - */ - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - png_uint_32 r; - - if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) - png_error(png_ptr, "rgb+alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_rgb_colormap(display); - - /* Add a transparent entry. */ - png_create_colormap_entry(display, cmap_entries, 255, 255, - 255, 0, P_sRGB); - - /* This is stored as the background index for the processing - * algorithm. - */ - background_index = cmap_entries++; - - /* Add 27 r,g,b entries each with alpha 0.5. */ - for (r=0; r<256; r = (r << 1) | 0x7f) - { - png_uint_32 g; - - for (g=0; g<256; g = (g << 1) | 0x7f) - { - png_uint_32 b; - - /* This generates components with the values 0, 127 and - * 255 - */ - for (b=0; b<256; b = (b << 1) | 0x7f) - png_create_colormap_entry(display, cmap_entries++, - r, g, b, 128, P_sRGB); - } - } - - expand_tRNS = 1; - output_processing = PNG_CMAP_RGB_ALPHA; - } - - else - { - /* Alpha/transparency must be removed. The background must - * exist in the color map (achieved by setting adding it after - * the 666 color-map). If the standard processing code will - * pick up this entry automatically that's all that is - * required; libpng can be called to do the background - * processing. - */ - unsigned int sample_size = - PNG_IMAGE_SAMPLE_SIZE(output_format); - png_uint_32 r, g, b; /* sRGB background */ - - if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) - png_error(png_ptr, "rgb-alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_rgb_colormap(display); - - png_create_colormap_entry(display, cmap_entries, back_r, - back_g, back_b, 0/*unused*/, output_encoding); - - if (output_encoding == P_LINEAR) - { - r = PNG_sRGB_FROM_LINEAR(back_r * 255); - g = PNG_sRGB_FROM_LINEAR(back_g * 255); - b = PNG_sRGB_FROM_LINEAR(back_b * 255); - } - - else - { - r = back_r; - g = back_g; - b = back_g; - } - - /* Compare the newly-created color-map entry with the one the - * PNG_CMAP_RGB algorithm will use. If the two entries don't - * match, add the new one and set this as the background - * index. - */ - if (memcmp((png_const_bytep)display->colormap + - sample_size * cmap_entries, - (png_const_bytep)display->colormap + - sample_size * PNG_RGB_INDEX(r,g,b), - sample_size) != 0) - { - /* The background color must be added. */ - background_index = cmap_entries++; - - /* Add 27 r,g,b entries each with created by composing with - * the background at alpha 0.5. - */ - for (r=0; r<256; r = (r << 1) | 0x7f) - { - for (g=0; g<256; g = (g << 1) | 0x7f) - { - /* This generates components with the values 0, 127 - * and 255 - */ - for (b=0; b<256; b = (b << 1) | 0x7f) - png_create_colormap_entry(display, cmap_entries++, - png_colormap_compose(display, r, P_sRGB, 128, - back_r, output_encoding), - png_colormap_compose(display, g, P_sRGB, 128, - back_g, output_encoding), - png_colormap_compose(display, b, P_sRGB, 128, - back_b, output_encoding), - 0/*unused*/, output_encoding); - } - } - - expand_tRNS = 1; - output_processing = PNG_CMAP_RGB_ALPHA; - } - - else /* background color is in the standard color-map */ - { - png_color_16 c; - - c.index = 0; /*unused*/ - c.red = (png_uint_16)back_r; - c.gray = c.green = (png_uint_16)back_g; - c.blue = (png_uint_16)back_b; - - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_RGB; - } - } - } - - else /* no alpha or transparency in the input */ - { - /* Alpha in the output is irrelevant, simply map the opaque input - * pixels to the 6x6x6 color-map. - */ - if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb color-map: too few entries"); - - cmap_entries = (unsigned int)make_rgb_colormap(display); - output_processing = PNG_CMAP_RGB; - } - } - break; - - case PNG_COLOR_TYPE_PALETTE: - /* It's already got a color-map. It may be necessary to eliminate the - * tRNS entries though. - */ - { - unsigned int num_trans = png_ptr->num_trans; - png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; - png_const_colorp colormap = png_ptr->palette; - int do_background = trans != NULL && - (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; - unsigned int i; - - /* Just in case: */ - if (trans == NULL) - num_trans = 0; - - output_processing = PNG_CMAP_NONE; - data_encoding = P_FILE; /* Don't change from color-map indices */ - cmap_entries = (unsigned int)png_ptr->num_palette; - if (cmap_entries > 256) - cmap_entries = 256; - - if (cmap_entries > (unsigned int)image->colormap_entries) - png_error(png_ptr, "palette color-map: too few entries"); - - for (i=0; i < cmap_entries; ++i) - { - if (do_background != 0 && i < num_trans && trans[i] < 255) - { - if (trans[i] == 0) - png_create_colormap_entry(display, i, back_r, back_g, - back_b, 0, output_encoding); - - else - { - /* Must compose the PNG file color in the color-map entry - * on the sRGB color in 'back'. - */ - png_create_colormap_entry(display, i, - png_colormap_compose(display, colormap[i].red, - P_FILE, trans[i], back_r, output_encoding), - png_colormap_compose(display, colormap[i].green, - P_FILE, trans[i], back_g, output_encoding), - png_colormap_compose(display, colormap[i].blue, - P_FILE, trans[i], back_b, output_encoding), - output_encoding == P_LINEAR ? trans[i] * 257U : - trans[i], - output_encoding); - } - } - - else - png_create_colormap_entry(display, i, colormap[i].red, - colormap[i].green, colormap[i].blue, - i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); - } - - /* The PNG data may have indices packed in fewer than 8 bits, it - * must be expanded if so. - */ - if (png_ptr->bit_depth < 8) - png_set_packing(png_ptr); - } - break; - - default: - png_error(png_ptr, "invalid PNG color type"); - /*NOT REACHED*/ - } - - /* Now deal with the output processing */ - if (expand_tRNS != 0 && png_ptr->num_trans > 0 && - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) - png_set_tRNS_to_alpha(png_ptr); - - switch (data_encoding) - { - case P_sRGB: - /* Change to 8-bit sRGB */ - png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); - /* FALLTHROUGH */ - - case P_FILE: - if (png_ptr->bit_depth > 8) - png_set_scale_16(png_ptr); - break; - -#ifdef __GNUC__ - default: - png_error(png_ptr, "bad data option (internal error)"); -#endif - } - - if (cmap_entries > 256 || cmap_entries > image->colormap_entries) - png_error(png_ptr, "color map overflow (BAD internal error)"); - - image->colormap_entries = cmap_entries; - - /* Double check using the recorded background index */ - switch (output_processing) - { - case PNG_CMAP_NONE: - if (background_index != PNG_CMAP_NONE_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_GA: - if (background_index != PNG_CMAP_GA_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_TRANS: - if (background_index >= cmap_entries || - background_index != PNG_CMAP_TRANS_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_RGB: - if (background_index != PNG_CMAP_RGB_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_RGB_ALPHA: - if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) - goto bad_background; - break; - - default: - png_error(png_ptr, "bad processing option (internal error)"); - - bad_background: - png_error(png_ptr, "bad background index (internal error)"); - } - - display->colormap_processing = (int)output_processing; - - return 1/*ok*/; -} - -/* The final part of the color-map read called from png_image_finish_read. */ -static int -png_image_read_and_map(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - int passes; - - /* Called when the libpng data must be transformed into the color-mapped - * form. There is a local row buffer in display->local and this routine must - * do the interlace handling. - */ - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - { - png_uint_32 height = image->height; - png_uint_32 width = image->width; - int proc = display->colormap_processing; - png_bytep first_row = png_voidcast(png_bytep, display->first_row); - ptrdiff_t step_row = display->row_bytes; - int pass; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass); - stepx = PNG_PASS_COL_OFFSET(pass); - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = stepy = 1; - } - - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read read the libpng data into the temporary buffer. */ - png_read_row(png_ptr, inrow, NULL); - - /* Now process the row according to the processing option, note - * that the caller verifies that the format of the libpng output - * data is as required. - */ - outrow += startx; - switch (proc) - { - case PNG_CMAP_GA: - for (; outrow < end_row; outrow += stepx) - { - /* The data is always in the PNG order */ - unsigned int gray = *inrow++; - unsigned int alpha = *inrow++; - unsigned int entry; - - /* NOTE: this code is copied as a comment in - * make_ga_colormap above. Please update the - * comment if you change this code! - */ - if (alpha > 229) /* opaque */ - { - entry = (231 * gray + 128) >> 8; - } - else if (alpha < 26) /* transparent */ - { - entry = 231; - } - else /* partially opaque */ - { - entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); - } - - *outrow = (png_byte)entry; - } - break; - - case PNG_CMAP_TRANS: - for (; outrow < end_row; outrow += stepx) - { - png_byte gray = *inrow++; - png_byte alpha = *inrow++; - - if (alpha == 0) - *outrow = PNG_CMAP_TRANS_BACKGROUND; - - else if (gray != PNG_CMAP_TRANS_BACKGROUND) - *outrow = gray; - - else - *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); - } - break; - - case PNG_CMAP_RGB: - for (; outrow < end_row; outrow += stepx) - { - *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); - inrow += 3; - } - break; - - case PNG_CMAP_RGB_ALPHA: - for (; outrow < end_row; outrow += stepx) - { - unsigned int alpha = inrow[3]; - - /* Because the alpha entries only hold alpha==0.5 values - * split the processing at alpha==0.25 (64) and 0.75 - * (196). - */ - - if (alpha >= 196) - *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], - inrow[2]); - - else if (alpha < 64) - *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; - - else - { - /* Likewise there are three entries for each of r, g - * and b. We could select the entry by popcount on - * the top two bits on those architectures that - * support it, this is what the code below does, - * crudely. - */ - unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; - - /* Here are how the values map: - * - * 0x00 .. 0x3f -> 0 - * 0x40 .. 0xbf -> 1 - * 0xc0 .. 0xff -> 2 - * - * So, as above with the explicit alpha checks, the - * breakpoints are at 64 and 196. - */ - if (inrow[0] & 0x80) back_i += 9; /* red */ - if (inrow[0] & 0x40) back_i += 9; - if (inrow[0] & 0x80) back_i += 3; /* green */ - if (inrow[0] & 0x40) back_i += 3; - if (inrow[0] & 0x80) back_i += 1; /* blue */ - if (inrow[0] & 0x40) back_i += 1; - - *outrow = (png_byte)back_i; - } - - inrow += 4; - } - break; - - default: - break; - } - } - } - } - - return 1; -} - -static int -png_image_read_colormapped(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_controlp control = image->opaque; - png_structrp png_ptr = control->png_ptr; - png_inforp info_ptr = control->info_ptr; - - int passes = 0; /* As a flag */ - - PNG_SKIP_CHUNKS(png_ptr); - - /* Update the 'info' structure and make sure the result is as required; first - * make sure to turn on the interlace handling if it will be required - * (because it can't be turned on *after* the call to png_read_update_info!) - */ - if (display->colormap_processing == PNG_CMAP_NONE) - passes = png_set_interlace_handling(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - /* The expected output can be deduced from the colormap_processing option. */ - switch (display->colormap_processing) - { - case PNG_CMAP_NONE: - /* Output must be one channel and one byte per pixel, the output - * encoding can be anything. - */ - if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && - info_ptr->bit_depth == 8) - break; - - goto bad_output; - - case PNG_CMAP_TRANS: - case PNG_CMAP_GA: - /* Output must be two channels and the 'G' one must be sRGB, the latter - * can be checked with an exact number because it should have been set - * to this number above! - */ - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - info_ptr->bit_depth == 8 && - png_ptr->screen_gamma == PNG_GAMMA_sRGB && - image->colormap_entries == 256) - break; - - goto bad_output; - - case PNG_CMAP_RGB: - /* Output must be 8-bit sRGB encoded RGB */ - if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - info_ptr->bit_depth == 8 && - png_ptr->screen_gamma == PNG_GAMMA_sRGB && - image->colormap_entries == 216) - break; - - goto bad_output; - - case PNG_CMAP_RGB_ALPHA: - /* Output must be 8-bit sRGB encoded RGBA */ - if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && - info_ptr->bit_depth == 8 && - png_ptr->screen_gamma == PNG_GAMMA_sRGB && - image->colormap_entries == 244 /* 216 + 1 + 27 */) - break; - - goto bad_output; - - default: - bad_output: - png_error(png_ptr, "bad color-map processing (internal error)"); - } - - /* Now read the rows. Do this here if it is possible to read directly into - * the output buffer, otherwise allocate a local row buffer of the maximum - * size libpng requires and call the relevant processing routine safely. - */ - { - png_voidp first_row = display->buffer; - ptrdiff_t row_bytes = display->row_stride; - - /* The following expression is designed to work correctly whether it gives - * a signed or an unsigned result. - */ - if (row_bytes < 0) - { - char *ptr = png_voidcast(char*, first_row); - ptr += (image->height-1) * (-row_bytes); - first_row = png_voidcast(png_voidp, ptr); - } - - display->first_row = first_row; - display->row_bytes = row_bytes; - } - - if (passes == 0) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_and_map, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else - { - png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; - - while (--passes >= 0) - { - png_uint_32 y = image->height; - png_bytep row = png_voidcast(png_bytep, display->first_row); - - for (; y > 0; --y) - { - png_read_row(png_ptr, row, NULL); - row += row_bytes; - } - } - - return 1; - } -} - -/* Just the row reading part of png_image_read. */ -static int -png_image_read_composite(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - int passes; - - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - { - png_uint_32 height = image->height; - png_uint_32 width = image->width; - ptrdiff_t step_row = display->row_bytes; - unsigned int channels = - (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; - int pass; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass) * channels; - stepx = PNG_PASS_COL_OFFSET(pass) * channels; - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = channels; - stepy = 1; - } - - for (; ylocal_row); - png_bytep outrow; - png_const_bytep end_row; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - outrow = png_voidcast(png_bytep, display->first_row); - outrow += y * step_row; - end_row = outrow + width * channels; - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[channels]; - - if (alpha > 0) /* else no change to the output */ - { - unsigned int c; - - for (c=0; cimage; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - png_uint_32 height = image->height; - png_uint_32 width = image->width; - int pass, passes; - - /* Double check the convoluted logic below. We expect to get here with - * libpng doing rgb to gray and gamma correction but background processing - * left to the png_image_read_background function. The rows libpng produce - * might be 8 or 16-bit but should always have two channels; gray plus alpha. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) - png_error(png_ptr, "lost rgb to gray"); - - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_error(png_ptr, "unexpected compose"); - - if (png_get_channels(png_ptr, info_ptr) != 2) - png_error(png_ptr, "lost/gained channels"); - - /* Expect the 8-bit case to always remove the alpha channel */ - if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && - (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_error(png_ptr, "unexpected 8-bit transformation"); - - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - /* Use direct access to info_ptr here because otherwise the simplified API - * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is - * checking the value after libpng expansions, not the original value in the - * PNG. - */ - switch (info_ptr->bit_depth) - { - case 8: - /* 8-bit sRGB gray values with an alpha channel; the alpha channel is - * to be removed by composing on a background: either the row if - * display->background is NULL or display->background->green if not. - * Unlike the code above ALPHA_OPTIMIZED has *not* been done. - */ - { - png_bytep first_row = png_voidcast(png_bytep, display->first_row); - ptrdiff_t step_row = display->row_bytes; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass); - stepx = PNG_PASS_COL_OFFSET(pass); - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = stepy = 1; - } - - if (display->background == NULL) - { - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[1]; - - if (alpha > 0) /* else no change to the output */ - { - png_uint_32 component = inrow[0]; - - if (alpha < 255) /* else just use component */ - { - /* Since PNG_OPTIMIZED_ALPHA was not set it is - * necessary to invert the sRGB transfer - * function and multiply the alpha out. - */ - component = png_sRGB_table[component] * alpha; - component += png_sRGB_table[outrow[0]] * - (255-alpha); - component = PNG_sRGB_FROM_LINEAR(component); - } - - outrow[0] = (png_byte)component; - } - - inrow += 2; /* gray and alpha channel */ - } - } - } - - else /* constant background value */ - { - png_byte background8 = display->background->green; - png_uint_16 background = png_sRGB_table[background8]; - - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[1]; - - if (alpha > 0) /* else use background */ - { - png_uint_32 component = inrow[0]; - - if (alpha < 255) /* else just use component */ - { - component = png_sRGB_table[component] * alpha; - component += background * (255-alpha); - component = PNG_sRGB_FROM_LINEAR(component); - } - - outrow[0] = (png_byte)component; - } - - else - outrow[0] = background8; - - inrow += 2; /* gray and alpha channel */ - } - } - } - } - } - break; - - case 16: - /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must - * still be done and, maybe, the alpha channel removed. This code also - * handles the alpha-first option. - */ - { - png_uint_16p first_row = png_voidcast(png_uint_16p, - display->first_row); - /* The division by two is safe because the caller passed in a - * stride which was multiplied by 2 (below) to get row_bytes. - */ - ptrdiff_t step_row = display->row_bytes / 2; - unsigned int preserve_alpha = (image->format & - PNG_FORMAT_FLAG_ALPHA) != 0; - unsigned int outchannels = 1U+preserve_alpha; - int swap_alpha = 0; - -# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED - if (preserve_alpha != 0 && - (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - swap_alpha = 1; -# endif - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - /* The 'x' start and step are adjusted to output components here. - */ - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass) * outchannels; - stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = outchannels; - stepy = 1; - } - - for (; ylocal_row), NULL); - inrow = png_voidcast(png_const_uint_16p, display->local_row); - - /* Now do the pre-multiplication on each pixel in this row. - */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_uint_32 component = inrow[0]; - png_uint_16 alpha = inrow[1]; - - if (alpha > 0) /* else 0 */ - { - if (alpha < 65535) /* else just use component */ - { - component *= alpha; - component += 32767; - component /= 65535; - } - } - - else - component = 0; - - outrow[swap_alpha] = (png_uint_16)component; - if (preserve_alpha != 0) - outrow[1 ^ swap_alpha] = alpha; - - inrow += 2; /* components and alpha channel */ - } - } - } - } - break; - -#ifdef __GNUC__ - default: - png_error(png_ptr, "unexpected bit depth"); -#endif - } - - return 1; -} - -/* The guts of png_image_finish_read as a png_safe_execute callback. */ -static int -png_image_read_direct(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - - png_uint_32 format = image->format; - int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; - int do_local_compose = 0; - int do_local_background = 0; /* to avoid double gamma correction bug */ - int passes = 0; - - /* Add transforms to ensure the correct output format is produced then check - * that the required implementation support is there. Always expand; always - * need 8 bits minimum, no palette and expanded tRNS. - */ - png_set_expand(png_ptr); - - /* Now check the format to see if it was modified. */ - { - png_uint_32 base_format = png_image_format(png_ptr) & - ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; - png_uint_32 change = format ^ base_format; - png_fixed_point output_gamma; - int mode; /* alpha mode */ - - /* Do this first so that we have a record if rgb to gray is happening. */ - if ((change & PNG_FORMAT_FLAG_COLOR) != 0) - { - /* gray<->color transformation required. */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_gray_to_rgb(png_ptr); - - else - { - /* libpng can't do both rgb to gray and - * background/pre-multiplication if there is also significant gamma - * correction, because both operations require linear colors and - * the code only supports one transform doing the gamma correction. - * Handle this by doing the pre-multiplication or background - * operation in this code, if necessary. - * - * TODO: fix this by rewriting pngrtran.c (!) - * - * For the moment (given that fixing this in pngrtran.c is an - * enormous change) 'do_local_background' is used to indicate that - * the problem exists. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - do_local_background = 1/*maybe*/; - - png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, - PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); - } - - change &= ~PNG_FORMAT_FLAG_COLOR; - } - - /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. - */ - { - png_fixed_point input_gamma_default; - - if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - input_gamma_default = PNG_GAMMA_LINEAR; - else - input_gamma_default = PNG_DEFAULT_sRGB; - - /* Call png_set_alpha_mode to set the default for the input gamma; the - * output gamma is set by a second call below. - */ - png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); - } - - if (linear != 0) - { - /* If there *is* an alpha channel in the input it must be multiplied - * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - mode = PNG_ALPHA_STANDARD; /* associated alpha */ - - else - mode = PNG_ALPHA_PNG; - - output_gamma = PNG_GAMMA_LINEAR; - } - - else - { - mode = PNG_ALPHA_PNG; - output_gamma = PNG_DEFAULT_sRGB; - } - - if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) - { - mode = PNG_ALPHA_OPTIMIZED; - change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; - } - - /* If 'do_local_background' is set check for the presence of gamma - * correction; this is part of the work-round for the libpng bug - * described above. - * - * TODO: fix libpng and remove this. - */ - if (do_local_background != 0) - { - png_fixed_point gtest; - - /* This is 'png_gamma_threshold' from pngrtran.c; the test used for - * gamma correction, the screen gamma hasn't been set on png_struct - * yet; it's set below. png_struct::gamma, however, is set to the - * final value. - */ - if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, - PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) - do_local_background = 0; - - else if (mode == PNG_ALPHA_STANDARD) - { - do_local_background = 2/*required*/; - mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ - } - - /* else leave as 1 for the checks below */ - } - - /* If the bit-depth changes then handle that here. */ - if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) - { - if (linear != 0 /*16-bit output*/) - png_set_expand_16(png_ptr); - - else /* 8-bit output */ - png_set_scale_16(png_ptr); - - change &= ~PNG_FORMAT_FLAG_LINEAR; - } - - /* Now the background/alpha channel changes. */ - if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Removing an alpha channel requires composition for the 8-bit - * formats; for the 16-bit it is already done, above, by the - * pre-multiplication and the channel just needs to be stripped. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* If RGB->gray is happening the alpha channel must be left and the - * operation completed locally. - * - * TODO: fix libpng and remove this. - */ - if (do_local_background != 0) - do_local_background = 2/*required*/; - - /* 16-bit output: just remove the channel */ - else if (linear != 0) /* compose on black (well, pre-multiply) */ - png_set_strip_alpha(png_ptr); - - /* 8-bit output: do an appropriate compose */ - else if (display->background != NULL) - { - png_color_16 c; - - c.index = 0; /*unused*/ - c.red = display->background->red; - c.green = display->background->green; - c.blue = display->background->blue; - c.gray = display->background->green; - - /* This is always an 8-bit sRGB value, using the 'green' channel - * for gray is much better than calculating the luminance here; - * we can get off-by-one errors in that calculation relative to - * the app expectations and that will show up in transparent - * pixels. - */ - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - } - - else /* compose on row: implemented below. */ - { - do_local_compose = 1; - /* This leaves the alpha channel in the output, so it has to be - * removed by the code below. Set the encoding to the 'OPTIMIZE' - * one so the code only has to hack on the pixels that require - * composition. - */ - mode = PNG_ALPHA_OPTIMIZED; - } - } - - else /* output needs an alpha channel */ - { - /* This is tricky because it happens before the swap operation has - * been accomplished; however, the swap does *not* swap the added - * alpha channel (weird API), so it must be added in the correct - * place. - */ - png_uint_32 filler; /* opaque filler */ - int where; - - if (linear != 0) - filler = 65535; - - else - filler = 255; - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - where = PNG_FILLER_BEFORE; - change &= ~PNG_FORMAT_FLAG_AFIRST; - } - - else -#endif - where = PNG_FILLER_AFTER; - - png_set_add_alpha(png_ptr, filler, where); - } - - /* This stops the (irrelevant) call to swap_alpha below. */ - change &= ~PNG_FORMAT_FLAG_ALPHA; - } - - /* Now set the alpha mode correctly; this is always done, even if there is - * no alpha channel in either the input or the output because it correctly - * sets the output gamma. - */ - png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); - -# ifdef PNG_FORMAT_BGR_SUPPORTED - if ((change & PNG_FORMAT_FLAG_BGR) != 0) - { - /* Check only the output format; PNG is never BGR; don't do this if - * the output is gray, but fix up the 'format' value in that case. - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_bgr(png_ptr); - - else - format &= ~PNG_FORMAT_FLAG_BGR; - - change &= ~PNG_FORMAT_FLAG_BGR; - } -# endif - -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) - { - /* Only relevant if there is an alpha channel - it's particularly - * important to handle this correctly because do_local_compose may - * be set above and then libpng will keep the alpha channel for this - * code to remove. - */ - if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Disable this if doing a local background, - * TODO: remove this when local background is no longer required. - */ - if (do_local_background != 2) - png_set_swap_alpha(png_ptr); - } - - else - format &= ~PNG_FORMAT_FLAG_AFIRST; - - change &= ~PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* If the *output* is 16-bit then we need to check for a byte-swap on this - * architecture. - */ - if (linear != 0) - { - png_uint_16 le = 0x0001; - - if ((*(png_const_bytep) & le) != 0) - png_set_swap(png_ptr); - } - - /* If change is not now 0 some transformation is missing - error out. */ - if (change != 0) - png_error(png_ptr, "png_read_image: unsupported transformation"); - } - - PNG_SKIP_CHUNKS(png_ptr); - - /* Update the 'info' structure and make sure the result is as required; first - * make sure to turn on the interlace handling if it will be required - * (because it can't be turned on *after* the call to png_read_update_info!) - * - * TODO: remove the do_local_background fixup below. - */ - if (do_local_compose == 0 && do_local_background != 2) - passes = png_set_interlace_handling(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - { - png_uint_32 info_format = 0; - - if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_format |= PNG_FORMAT_FLAG_COLOR; - - if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - /* do_local_compose removes this channel below. */ - if (do_local_compose == 0) - { - /* do_local_background does the same if required. */ - if (do_local_background != 2 || - (format & PNG_FORMAT_FLAG_ALPHA) != 0) - info_format |= PNG_FORMAT_FLAG_ALPHA; - } - } - - else if (do_local_compose != 0) /* internal error */ - png_error(png_ptr, "png_image_read: alpha channel lost"); - - if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { - info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; - } - - if (info_ptr->bit_depth == 16) - info_format |= PNG_FORMAT_FLAG_LINEAR; - -#ifdef PNG_FORMAT_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - info_format |= PNG_FORMAT_FLAG_BGR; -#endif - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED - if (do_local_background == 2) - { - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - info_format |= PNG_FORMAT_FLAG_AFIRST; - } - - if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || - ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && - (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) - { - if (do_local_background == 2) - png_error(png_ptr, "unexpected alpha swap transformation"); - - info_format |= PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* This is actually an internal error. */ - if (info_format != format) - png_error(png_ptr, "png_read_image: invalid transformations"); - } - - /* Now read the rows. If do_local_compose is set then it is necessary to use - * a local row buffer. The output will be GA, RGBA or BGRA and must be - * converted to G, RGB or BGR as appropriate. The 'local_row' member of the - * display acts as a flag. - */ - { - png_voidp first_row = display->buffer; - ptrdiff_t row_bytes = display->row_stride; - - if (linear != 0) - row_bytes *= 2; - - /* The following expression is designed to work correctly whether it gives - * a signed or an unsigned result. - */ - if (row_bytes < 0) - { - char *ptr = png_voidcast(char*, first_row); - ptr += (image->height-1) * (-row_bytes); - first_row = png_voidcast(png_voidp, ptr); - } - - display->first_row = first_row; - display->row_bytes = row_bytes; - } - - if (do_local_compose != 0) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_composite, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else if (do_local_background == 2) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_background, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else - { - png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; - - while (--passes >= 0) - { - png_uint_32 y = image->height; - png_bytep row = png_voidcast(png_bytep, display->first_row); - - for (; y > 0; --y) - { - png_read_row(png_ptr, row, NULL); - row += row_bytes; - } - } - - return 1; - } -} - -int PNGAPI -png_image_finish_read(png_imagep image, png_const_colorp background, - void *buffer, png_int_32 row_stride, void *colormap) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - /* Check for row_stride overflow. This check is not performed on the - * original PNG format because it may not occur in the output PNG format - * and libpng deals with the issues of reading the original. - */ - unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - - /* The following checks just the 'row_stride' calculation to ensure it - * fits in a signed 32-bit value. Because channels/components can be - * either 1 or 2 bytes in size the length of a row can still overflow 32 - * bits; this is just to verify that the 'row_stride' argument can be - * represented. - */ - if (image->width <= 0x7fffffffU/channels) /* no overflow */ - { - png_uint_32 check; - png_uint_32 png_row_stride = image->width * channels; - - if (row_stride == 0) - row_stride = (png_int_32)/*SAFE*/png_row_stride; - - if (row_stride < 0) - check = (png_uint_32)(-row_stride); - - else - check = (png_uint_32)row_stride; - - /* This verifies 'check', the absolute value of the actual stride - * passed in and detects overflow in the application calculation (i.e. - * if the app did actually pass in a non-zero 'row_stride'. - */ - if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) - { - /* Now check for overflow of the image buffer calculation; this - * limits the whole image size to 32 bits for API compatibility with - * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. - * - * The PNG_IMAGE_BUFFER_SIZE macro is: - * - * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) - * - * And the component size is always 1 or 2, so make sure that the - * number of *bytes* that the application is saying are available - * does actually fit into a 32-bit number. - * - * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE - * will be changed to use png_alloc_size_t; bigger images can be - * accommodated on 64-bit systems. - */ - if (image->height <= - 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) - { - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || - (image->colormap_entries > 0 && colormap != NULL)) - { - int result; - png_image_read_control display; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.background = background; - display.local_row = NULL; - - /* Choose the correct 'end' routine; for the color-map case - * all the setup has already been done. - */ - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - result = - png_safe_execute(image, - png_image_read_colormap, &display) && - png_safe_execute(image, - png_image_read_colormapped, &display); - - else - result = - png_safe_execute(image, - png_image_read_direct, &display); - - png_image_free(image); - return result; - } - - else - return png_image_error(image, - "png_image_finish_read[color-map]: no color-map"); - } - - else - return png_image_error(image, - "png_image_finish_read: image too large"); - } - - else - return png_image_error(image, - "png_image_finish_read: invalid argument"); - } - - else - return png_image_error(image, - "png_image_finish_read: row_stride too large"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_finish_read: damaged PNG_IMAGE_VERSION"); - - return 0; -} - -#endif /* SIMPLIFIED_READ */ -#endif /* READ */ +/* pngread.c - read a PNG file + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that an application calls directly to + * read a PNG file or stream. + */ + +#include "pngpriv.h" +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) +# include +#endif + +#ifdef PNG_READ_SUPPORTED + +/* Create a PNG structure for reading, and allocate any memory needed. */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED) +{ +#ifndef PNG_USER_MEM_SUPPORTED + png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, NULL, NULL, NULL); +#else + return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL); +} + +/* Alternate create PNG structure for reading, and allocate any memory + * needed. + */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED) +{ + png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); +#endif /* USER_MEM */ + + if (png_ptr != NULL) + { + png_ptr->mode = PNG_IS_READ_STRUCT; + + /* Added in libpng-1.6.0; this can be used to detect a read structure if + * required (it will be zero in a write structure.) + */ +# ifdef PNG_SEQUENTIAL_READ_SUPPORTED + png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; +# endif + +# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + + /* In stable builds only warn if an application error can be completely + * handled. + */ +# if PNG_RELEASE_BUILD + png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; +# endif +# endif + + /* TODO: delay this, it can be done in png_init_io (if the app doesn't + * do it itself) avoiding setting the default function if it is not + * required. + */ + png_set_read_fn(png_ptr, NULL, NULL); + } + + return png_ptr; +} + + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the information before the actual image data. This has been + * changed in v0.90 to allow reading a file that already has the magic + * bytes read from the stream. You can tell libpng how many bytes have + * been read from the beginning of the stream (up to the maximum of 8) + * via png_set_sig_bytes(), and we will only check the remaining bytes + * here. The application can then have access to the signature bytes we + * read if it is determined that this isn't a valid PNG file. + */ +void PNGAPI +png_read_info(png_structrp png_ptr, png_inforp info_ptr) +{ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int keep; +#endif + + png_debug(1, "in png_read_info"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Read and check the PNG file signature. */ + png_read_sig(png_ptr, info_ptr); + + for (;;) + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + /* IDAT logic needs to happen here to simplify getting the two flags + * right. + */ + if (chunk_name == png_IDAT) + { + if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + (png_ptr->mode & PNG_HAVE_PLTE) == 0) + png_chunk_error(png_ptr, "Missing PLTE before IDAT"); + + else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) + png_chunk_benign_error(png_ptr, "Too many IDATs found"); + + png_ptr->mode |= PNG_HAVE_IDAT; + } + + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + png_ptr->mode |= PNG_AFTER_IDAT; + } + + if (chunk_name == png_IHDR) + png_handle_chunk(png_ptr, info_ptr, length); + + else if (chunk_name == png_IEND) + png_handle_chunk(png_ptr, info_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { + png_handle_unknown(png_ptr, info_ptr, length, keep); + + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + + else if (chunk_name == png_IDAT) + { + png_ptr->idat_size = 0; /* It has been consumed */ + break; + } + } +#endif + + else if (chunk_name == png_IDAT) + { + png_ptr->idat_size = length; + break; + } + + else + png_handle_chunk(png_ptr, info_ptr, length); + } +} +#endif /* SEQUENTIAL_READ */ + +/* Optional call to update the users info_ptr structure */ +void PNGAPI +png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) +{ + png_debug(1, "in png_read_update_info"); + + if (png_ptr != NULL) + { + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + png_read_start_row(png_ptr); + +# ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_read_transform_info(png_ptr, info_ptr); +# else + PNG_UNUSED(info_ptr) +# endif + } + + /* New in 1.6.0 this avoids the bug of doing the initializations twice */ + else + png_app_error(png_ptr, + "png_read_update_info/png_start_read_image: duplicate call"); + } +} + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Initialize palette, background, etc, after transformations + * are set, but before any reading takes place. This allows + * the user to obtain a gamma-corrected palette, for example. + * If the user doesn't call this, we will do it ourselves. + */ +void PNGAPI +png_start_read_image(png_structrp png_ptr) +{ + png_debug(1, "in png_start_read_image"); + + if (png_ptr != NULL) + { + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + png_read_start_row(png_ptr); + + /* New in 1.6.0 this avoids the bug of doing the initializations twice */ + else + png_app_error(png_ptr, + "png_start_read_image/png_read_update_info: duplicate call"); + } +} +#endif /* SEQUENTIAL_READ */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Undoes intrapixel differencing, + * NOTE: this is apparently only supported in the 'sequential' reader. + */ +static void +png_do_read_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_intrapixel"); + + if ( + (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); + *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); + } + } + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); + png_uint_32 red = (s0 + s1 + 65536) & 0xffff; + png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp + 1) = (png_byte)(red & 0xff); + *(rp + 4) = (png_byte)((blue >> 8) & 0xff); + *(rp + 5) = (png_byte)(blue & 0xff); + } + } + } +} +#endif /* MNG_FEATURES */ + +void PNGAPI +png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) +{ + png_row_info row_info; + + if (png_ptr == NULL) + return; + + png_debug2(1, "in png_read_row (row %lu, pass %d)", + (unsigned long)png_ptr->row_number, png_ptr->pass); + + /* png_read_start_row sets the information (in particular iwidth) for this + * interlace pass. + */ + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + png_read_start_row(png_ptr); + + /* 1.5.6: row_info moved out of png_struct to a local here. */ + row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ + row_info.color_type = png_ptr->color_type; + row_info.bit_depth = png_ptr->bit_depth; + row_info.channels = png_ptr->channels; + row_info.pixel_depth = png_ptr->pixel_depth; + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + +#ifdef PNG_WARNINGS_SUPPORTED + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* Check for transforms that have been set but were defined out */ +#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ + !defined(PNG_READ_PACKSWAP_SUPPORTED) + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) != 0) + png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) + if ((png_ptr->transformations & PNG_BGR) != 0) + png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); +#endif + +#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); +#endif + } +#endif /* WARNINGS */ + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* If interlaced and we do not need a new row, combine row and return. + * Notice that the pixels we have from previous rows have been transformed + * already; we can only combine like with like (transformed or + * untransformed) and, because of the libpng API for interlaced images, this + * means we must transform before de-interlacing. + */ + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0) + { + switch (png_ptr->pass) + { + case 0: + if (png_ptr->row_number & 0x07) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + png_read_finish_row(png_ptr); + return; + } + break; + + case 1: + if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + if (dsp_row != NULL && (png_ptr->row_number & 4)) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 3: + if ((png_ptr->row_number & 3) || png_ptr->width < 3) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 4: + if ((png_ptr->row_number & 3) != 2) + { + if (dsp_row != NULL && (png_ptr->row_number & 2)) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + case 5: + if ((png_ptr->row_number & 1) || png_ptr->width < 2) + { + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + png_read_finish_row(png_ptr); + return; + } + break; + + default: + case 6: + if ((png_ptr->row_number & 1) == 0) + { + png_read_finish_row(png_ptr); + return; + } + break; + } + } +#endif + + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) + png_error(png_ptr, "Invalid attempt to read row data"); + + /* Fill the row with IDAT data: */ + png_ptr->row_buf[0]=255; /* to force error if no data was found */ + png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); + + if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) + { + if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) + png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, + png_ptr->prev_row + 1, png_ptr->row_buf[0]); + else + png_error(png_ptr, "bad adaptive filter value"); + } + + /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before + * 1.5.6, while the buffer really is this big in current versions of libpng + * it may not be in the future, so this was changed just to copy the + * interlaced count: + */ + memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); + +#ifdef PNG_MNG_FEATURES_SUPPORTED + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); + } +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + if (png_ptr->transformations +# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + || png_ptr->num_palette_max >= 0 +# endif + ) + png_do_read_transformations(png_ptr, &row_info); +#endif + + /* The transformed pixel depth should match the depth now in row_info. */ + if (png_ptr->transformed_pixel_depth == 0) + { + png_ptr->transformed_pixel_depth = row_info.pixel_depth; + if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) + png_error(png_ptr, "sequential row overflow"); + } + + else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) + png_error(png_ptr, "internal sequential row size calculation error"); + +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Expand interlaced rows to full size */ + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0) + { + if (png_ptr->pass < 6) + png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, + png_ptr->transformations); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, 1/*display*/); + + if (row != NULL) + png_combine_row(png_ptr, row, 0/*row*/); + } + + else +#endif + { + if (row != NULL) + png_combine_row(png_ptr, row, -1/*ignored*/); + + if (dsp_row != NULL) + png_combine_row(png_ptr, dsp_row, -1/*ignored*/); + } + png_read_finish_row(png_ptr); + + if (png_ptr->read_row_fn != NULL) + (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} +#endif /* SEQUENTIAL_READ */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read one or more rows of image data. If the image is interlaced, + * and png_set_interlace_handling() has been called, the rows need to + * contain the contents of the rows from the previous pass. If the + * image has alpha or transparency, and png_handle_alpha()[*] has been + * called, the rows contents must be initialized to the contents of the + * screen. + * + * "row" holds the actual image, and pixels are placed in it + * as they arrive. If the image is displayed after each pass, it will + * appear to "sparkle" in. "display_row" can be used to display a + * "chunky" progressive image, with finer detail added as it becomes + * available. If you do not want this "chunky" display, you may pass + * NULL for display_row. If you do not want the sparkle display, and + * you have not called png_handle_alpha(), you may pass NULL for rows. + * If you have called png_handle_alpha(), and the image has either an + * alpha channel or a transparency chunk, you must provide a buffer for + * rows. In this case, you do not have to provide a display_row buffer + * also, but you may. If the image is not interlaced, or if you have + * not called png_set_interlace_handling(), the display_row buffer will + * be ignored, so pass NULL to it. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ + +void PNGAPI +png_read_rows(png_structrp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows) +{ + png_uint_32 i; + png_bytepp rp; + png_bytepp dp; + + png_debug(1, "in png_read_rows"); + + if (png_ptr == NULL) + return; + + rp = row; + dp = display_row; + if (rp != NULL && dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp++; + png_bytep dptr = *dp++; + + png_read_row(png_ptr, rptr, dptr); + } + + else if (rp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep rptr = *rp; + png_read_row(png_ptr, rptr, NULL); + rp++; + } + + else if (dp != NULL) + for (i = 0; i < num_rows; i++) + { + png_bytep dptr = *dp; + png_read_row(png_ptr, NULL, dptr); + dp++; + } +} +#endif /* SEQUENTIAL_READ */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the entire image. If the image has an alpha channel or a tRNS + * chunk, and you have called png_handle_alpha()[*], you will need to + * initialize the image to the current image that PNG will be overlaying. + * We set the num_rows again here, in case it was incorrectly set in + * png_read_start_row() by a call to png_read_update_info() or + * png_start_read_image() if png_set_interlace_handling() wasn't called + * prior to either of these functions like it should have been. You can + * only call this function once. If you desire to have an image for + * each pass of a interlaced image, use png_read_rows() instead. + * + * [*] png_handle_alpha() does not exist yet, as of this version of libpng + */ +void PNGAPI +png_read_image(png_structrp png_ptr, png_bytepp image) +{ + png_uint_32 i, image_height; + int pass, j; + png_bytepp rp; + + png_debug(1, "in png_read_image"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_READ_INTERLACING_SUPPORTED + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + pass = png_set_interlace_handling(png_ptr); + /* And make sure transforms are initialized. */ + png_start_read_image(png_ptr); + } + else + { + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) == 0) + { + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, + * but the caller should do it! + */ + png_warning(png_ptr, "Interlace handling should be turned on when " + "using png_read_image"); + /* Make sure this is set correctly */ + png_ptr->num_rows = png_ptr->height; + } + + /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in + * the above error case. + */ + pass = png_set_interlace_handling(png_ptr); + } +#else + if (png_ptr->interlaced) + png_error(png_ptr, + "Cannot read interlaced image -- interlace handler disabled"); + + pass = 1; +#endif + + image_height=png_ptr->height; + + for (j = 0; j < pass; j++) + { + rp = image; + for (i = 0; i < image_height; i++) + { + png_read_row(png_ptr, *rp, NULL); + rp++; + } + } +} +#endif /* SEQUENTIAL_READ */ + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +/* Read the end of the PNG file. Will not read past the end of the + * file, will verify the end is accurate, and will read any comments + * or time information at the end of the file, if info is not NULL. + */ +void PNGAPI +png_read_end(png_structrp png_ptr, png_inforp info_ptr) +{ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + int keep; +#endif + + png_debug(1, "in png_read_end"); + + if (png_ptr == NULL) + return; + + /* If png_read_end is called in the middle of reading the rows there may + * still be pending IDAT data and an owned zstream. Deal with this here. + */ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) +#endif + png_read_finish_IDAT(png_ptr); + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Report invalid palette index; added at libpng-1.5.10 */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= png_ptr->num_palette) + png_benign_error(png_ptr, "Read palette index exceeding num_palette"); +#endif + + do + { + png_uint_32 length = png_read_chunk_header(png_ptr); + png_uint_32 chunk_name = png_ptr->chunk_name; + + if (chunk_name != png_IDAT) + { + /* These flags must be set consistently for all non-IDAT chunks, + * including the unknown chunks. + */ + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT; + } + + if (chunk_name == png_IEND) + png_handle_chunk(png_ptr, info_ptr, length); + + else if (chunk_name == png_IHDR) + png_handle_chunk(png_ptr, info_ptr, length); + + else if (info_ptr == NULL) + png_crc_finish(png_ptr, length); + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED + else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) + { + if (chunk_name == png_IDAT) + { + if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) + png_benign_error(png_ptr, ".Too many IDATs found"); + } + png_handle_unknown(png_ptr, info_ptr, length, keep); + if (chunk_name == png_PLTE) + png_ptr->mode |= PNG_HAVE_PLTE; + } +#endif + + else if (chunk_name == png_IDAT) + { + /* Zero length IDATs are legal after the last IDAT has been + * read, but not after other chunks have been read. 1.6 does not + * always read all the deflate data; specifically it cannot be relied + * upon to read the Adler32 at the end. If it doesn't ignore IDAT + * chunks which are longer than zero as well: + */ + if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) + || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) + png_benign_error(png_ptr, "..Too many IDATs found"); + + png_crc_finish(png_ptr, length); + } + + else + png_handle_chunk(png_ptr, info_ptr, length); + } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); +} +#endif /* SEQUENTIAL_READ */ + +/* Free all memory used in the read struct */ +static void +png_read_destroy(png_structrp png_ptr) +{ + png_debug(1, "in png_read_destroy"); + +#ifdef PNG_READ_GAMMA_SUPPORTED + png_destroy_gamma_table(png_ptr); +#endif + + png_free(png_ptr, png_ptr->big_row_buf); + png_ptr->big_row_buf = NULL; + png_free(png_ptr, png_ptr->big_prev_row); + png_ptr->big_prev_row = NULL; + png_free(png_ptr, png_ptr->read_buffer); + png_ptr->read_buffer = NULL; + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_free(png_ptr, png_ptr->palette_lookup); + png_ptr->palette_lookup = NULL; + png_free(png_ptr, png_ptr->quantize_index); + png_ptr->quantize_index = NULL; +#endif + + /* png_ptr->palette is always independently allocated (not aliased + * with info_ptr->palette), so free it unconditionally. + */ + png_free(png_ptr, png_ptr->palette); + png_ptr->palette = NULL; + +#if defined(PNG_tRNS_SUPPORTED) || \ + defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_ptr->trans_alpha is always independently allocated (not aliased + * with info_ptr->trans_alpha), so free it unconditionally. + */ + png_free(png_ptr, png_ptr->trans_alpha); + png_ptr->trans_alpha = NULL; +#endif + + inflateEnd(&png_ptr->zstream); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_free(png_ptr, png_ptr->save_buffer); + png_ptr->save_buffer = NULL; +#endif + +#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; +#endif + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list = NULL; +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + (defined(PNG_ARM_NEON_IMPLEMENTATION) || \ + defined(PNG_RISCV_RVV_IMPLEMENTATION)) + png_free(png_ptr, png_ptr->riffled_palette); + png_ptr->riffled_palette = NULL; +#endif + + /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error + * callbacks are still set at this point. They are required to complete the + * destruction of the png_struct itself. + */ +} + +/* Free all memory used by the read */ +void PNGAPI +png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, + png_infopp end_info_ptr_ptr) +{ + png_structrp png_ptr = NULL; + + png_debug(1, "in png_destroy_read_struct"); + + if (png_ptr_ptr != NULL) + png_ptr = *png_ptr_ptr; + + if (png_ptr == NULL) + return; + + /* libpng 1.6.0: use the API to destroy info structs to ensure consistent + * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. + * The extra was, apparently, unnecessary yet this hides memory leak bugs. + */ + png_destroy_info_struct(png_ptr, end_info_ptr_ptr); + png_destroy_info_struct(png_ptr, info_ptr_ptr); + + *png_ptr_ptr = NULL; + png_read_destroy(png_ptr); + png_destroy_png_struct(png_ptr); +} + +void PNGAPI +png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->read_row_fn = read_row_fn; +} + + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +#ifdef PNG_INFO_IMAGE_SUPPORTED +void PNGAPI +png_read_png(png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params) +{ + png_debug(1, "in png_read_png"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* png_read_info() gives us all of the information from the + * PNG file before the first IDAT (image data chunk). + */ + png_read_info(png_ptr, info_ptr); + if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) + png_error(png_ptr, "Image is too high to process with png_read_png()"); + + /* -------------- image transformations start here ------------------- */ + /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM + * is not implemented. This will only happen in de-configured (non-default) + * libpng builds. The results can be unexpected - png_read_png may return + * short or mal-formed rows because the transform is skipped. + */ + + /* Tell libpng to strip 16-bit/color files down to 8 bits per color. + */ + if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) + /* Added at libpng-1.5.4. "strip_16" produces the same result that it + * did in earlier versions, while "scale_16" is now more accurate. + */ +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_set_scale_16(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); +#endif + + /* If both SCALE and STRIP are required pngrtran will effectively cancel the + * latter by doing SCALE first. This is ok and allows apps not to check for + * which is supported to get the right answer. + */ + if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + png_set_strip_16(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); +#endif + + /* Strip alpha bytes from the input data without combining with + * the background (not recommended). + */ + if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + png_set_strip_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); +#endif + + /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + if ((transforms & PNG_TRANSFORM_PACKING) != 0) +#ifdef PNG_READ_PACK_SUPPORTED + png_set_packing(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); +#endif + + /* Change the order of packed pixels to least significant bit first + * (not useful if you are using png_set_packing). + */ + if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) +#ifdef PNG_READ_PACKSWAP_SUPPORTED + png_set_packswap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); +#endif + + /* Expand paletted colors into true RGB triplets + * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel + * Expand paletted or RGB images with transparency to full alpha + * channels so the data will be available as RGBA quartets. + */ + if ((transforms & PNG_TRANSFORM_EXPAND) != 0) +#ifdef PNG_READ_EXPAND_SUPPORTED + png_set_expand(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); +#endif + + /* We don't handle background color or gamma transformation or quantizing. + */ + + /* Invert monochrome files to have 0 as white and 1 as black + */ + if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) +#ifdef PNG_READ_INVERT_SUPPORTED + png_set_invert_mono(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); +#endif + + /* If you want to shift the pixel values from the range [0,255] or + * [0,65535] to the original [0,7] or [0,31], or whatever range the + * colors were originally in: + */ + if ((transforms & PNG_TRANSFORM_SHIFT) != 0) +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sBIT) != 0) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); +#endif + + /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ + if ((transforms & PNG_TRANSFORM_BGR) != 0) +#ifdef PNG_READ_BGR_SUPPORTED + png_set_bgr(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); +#endif + + /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ + if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + png_set_swap_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); +#endif + + /* Swap bytes of 16-bit files to least significant byte first */ + if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) +#ifdef PNG_READ_SWAP_SUPPORTED + png_set_swap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); +#endif + +/* Added at libpng-1.2.41 */ + /* Invert the alpha channel from opacity to transparency */ + if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + png_set_invert_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); +#endif + +/* Added at libpng-1.2.41 */ + /* Expand grayscale image to RGB */ + if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + png_set_gray_to_rgb(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); +#endif + +/* Added at libpng-1.5.4 */ + if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) +#ifdef PNG_READ_EXPAND_16_SUPPORTED + png_set_expand_16(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); +#endif + + /* We don't handle adding filler bytes */ + + /* We use png_read_image and rely on that for interlace handling, but we also + * call png_read_update_info therefore must turn on interlace handling now: + */ + (void)png_set_interlace_handling(png_ptr); + + /* Optional call to gamma correct and add the background to the palette + * and update info structure. REQUIRED if you are expecting libpng to + * update the palette for you (i.e., you selected such a transform above). + */ + png_read_update_info(png_ptr, info_ptr); + + /* -------------- image transformations end here ------------------- */ + + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + if (info_ptr->row_pointers == NULL) + { + png_uint_32 iptr; + + info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, + info_ptr->height * (sizeof (png_bytep)))); + + for (iptr=0; iptrheight; iptr++) + info_ptr->row_pointers[iptr] = NULL; + + info_ptr->free_me |= PNG_FREE_ROWS; + + for (iptr = 0; iptr < info_ptr->height; iptr++) + info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, + png_malloc(png_ptr, info_ptr->rowbytes)); + } + + png_read_image(png_ptr, info_ptr->row_pointers); + info_ptr->valid |= PNG_INFO_IDAT; + + /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + + PNG_UNUSED(params) +} +#endif /* INFO_IMAGE */ +#endif /* SEQUENTIAL_READ */ + +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED +/* SIMPLIFIED READ + * + * This code currently relies on the sequential reader, though it could easily + * be made to work with the progressive one. + */ +/* Arguments to png_image_finish_read: */ + +/* Encoding of PNG data (used by the color-map code) */ +# define P_NOTSET 0 /* File encoding not yet known */ +# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ +# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ +# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ +# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ + +/* Color-map processing: after libpng has run on the PNG image further + * processing may be needed to convert the data to color-map indices. + */ +#define PNG_CMAP_NONE 0 +#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ +#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ +#define PNG_CMAP_RGB 3 /* Process RGB data */ +#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ + +/* The following document where the background is for each processing case. */ +#define PNG_CMAP_NONE_BACKGROUND 256 +#define PNG_CMAP_GA_BACKGROUND 231 +#define PNG_CMAP_TRANS_BACKGROUND 254 +#define PNG_CMAP_RGB_BACKGROUND 256 +#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 + +typedef struct +{ + /* Arguments */ + png_imagep image; + png_voidp buffer; + png_int_32 row_stride; + png_voidp colormap; + png_const_colorp background; + + /* Instance variables */ + png_voidp local_row; + png_voidp first_row; + ptrdiff_t row_step; /* step between rows */ + int file_encoding; /* E_ values above */ + png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ + int colormap_processing; /* PNG_CMAP_ values above */ +} png_image_read_control; + +/* Do all the *safe* initialization - 'safe' means that png_error won't be + * called, so setting up the jmp_buf is not required. This means that anything + * called from here must *not* call png_malloc - it has to call png_malloc_warn + * instead so that control is returned safely back to this routine. + */ +static int +png_image_read_init(png_imagep image) +{ + if (image->opaque == NULL) + { + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, + png_safe_error, png_safe_warning); + + /* And set the rest of the structure to NULL to ensure that the various + * fields are consistent. + */ + memset(image, 0, (sizeof *image)); + image->version = PNG_IMAGE_VERSION; + + if (png_ptr != NULL) + { + png_infop info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr != NULL) + { + png_controlp control = png_voidcast(png_controlp, + png_malloc_warn(png_ptr, (sizeof *control))); + + if (control != NULL) + { + memset(control, 0, (sizeof *control)); + + control->png_ptr = png_ptr; + control->info_ptr = info_ptr; + control->for_write = 0; + + image->opaque = control; + return 1; + } + + /* Error clean up */ + png_destroy_info_struct(png_ptr, &info_ptr); + } + + png_destroy_read_struct(&png_ptr, NULL, NULL); + } + + return png_image_error(image, "png_image_read: out of memory"); + } + + return png_image_error(image, "png_image_read: opaque pointer not NULL"); +} + +/* Utility to find the base format of a PNG file from a png_struct. */ +static png_uint_32 +png_image_format(png_structrp png_ptr) +{ + png_uint_32 format = 0; + + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + format |= PNG_FORMAT_FLAG_COLOR; + + if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) + format |= PNG_FORMAT_FLAG_ALPHA; + + /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS + * sets the png_struct fields; that's all we are interested in here. The + * precise interaction with an app call to png_set_tRNS and PNG file reading + * is unclear. + */ + else if (png_ptr->num_trans > 0) + format |= PNG_FORMAT_FLAG_ALPHA; + + if (png_ptr->bit_depth == 16) + format |= PNG_FORMAT_FLAG_LINEAR; + + if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) + format |= PNG_FORMAT_FLAG_COLORMAP; + + return format; +} + +static int +chromaticities_match_sRGB(const png_xy *xy) +{ +# define sRGB_TOLERANCE 1000 + static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ + { + /* color x y */ + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000, + /* white */ 31270, 32900 + }; + + if (PNG_OUT_OF_RANGE(xy->whitex, sRGB_xy.whitex,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->whitey, sRGB_xy.whitey,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->redx, sRGB_xy.redx, sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->redy, sRGB_xy.redy, sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->greenx, sRGB_xy.greenx,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->greeny, sRGB_xy.greeny,sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->bluex, sRGB_xy.bluex, sRGB_TOLERANCE) || + PNG_OUT_OF_RANGE(xy->bluey, sRGB_xy.bluey, sRGB_TOLERANCE)) + return 0; + return 1; +} + +/* Is the given gamma significantly different from sRGB? The test is the same + * one used in pngrtran.c when deciding whether to do gamma correction. The + * arithmetic optimizes the division by using the fact that the inverse of the + * file sRGB gamma is 2.2 + */ +static int +png_gamma_not_sRGB(png_fixed_point g) +{ + /* 1.6.47: use the same sanity checks as used in pngrtran.c */ + if (g < PNG_LIB_GAMMA_MIN || g > PNG_LIB_GAMMA_MAX) + return 0; /* Includes the uninitialized value 0 */ + + return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); +} + +/* Do the main body of a 'png_image_begin_read' function; read the PNG file + * header and fill in all the information. This is executed in a safe context, + * unlike the init routine above. + */ +static int +png_image_is_not_sRGB(png_const_structrp png_ptr) +{ + /* Does the colorspace **not** match sRGB? The flag is only set if the + * answer can be determined reliably. + * + * png_struct::chromaticities always exists since the simplified API + * requires rgb-to-gray. The mDCV, cICP and cHRM chunks may all set it to + * a non-sRGB value, so it needs to be checked but **only** if one of + * those chunks occurred in the file. + */ + /* Highest priority: check to be safe. */ + if (png_has_chunk(png_ptr, cICP) || png_has_chunk(png_ptr, mDCV)) + return !chromaticities_match_sRGB(&png_ptr->chromaticities); + + /* If the image is marked as sRGB then it is... */ + if (png_has_chunk(png_ptr, sRGB)) + return 0; + + /* Last stop: cHRM, must check: */ + if (png_has_chunk(png_ptr, cHRM)) + return !chromaticities_match_sRGB(&png_ptr->chromaticities); + + /* Else default to sRGB */ + return 0; +} + +static int +png_image_read_header(png_voidp argument) +{ + png_imagep image = png_voidcast(png_imagep, argument); + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED + png_set_benign_errors(png_ptr, 1/*warn*/); +#endif + png_read_info(png_ptr, info_ptr); + + /* Do this the fast way; just read directly out of png_struct. */ + image->width = png_ptr->width; + image->height = png_ptr->height; + + { + png_uint_32 format = png_image_format(png_ptr); + + image->format = format; + + /* Greyscale images don't (typically) have colour space information and + * using it is pretty much impossible, so use sRGB for grayscale (it + * doesn't matter r==g==b so the transform is irrelevant.) + */ + if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && + png_image_is_not_sRGB(png_ptr)) + image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; + } + + /* We need the maximum number of entries regardless of the format the + * application sets here. + */ + { + png_uint_32 cmap_entries; + + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_GRAY: + cmap_entries = 1U << png_ptr->bit_depth; + break; + + case PNG_COLOR_TYPE_PALETTE: + cmap_entries = (png_uint_32)png_ptr->num_palette; + break; + + default: + cmap_entries = 256; + break; + } + + if (cmap_entries > 256) + cmap_entries = 256; + + image->colormap_entries = cmap_entries; + } + + return 1; +} + +#ifdef PNG_STDIO_SUPPORTED +int PNGAPI +png_image_begin_read_from_stdio(png_imagep image, FILE *file) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file != NULL) + { + if (png_image_read_init(image) != 0) + { + /* This is slightly evil, but png_init_io doesn't do anything other + * than this and we haven't changed the standard IO functions so + * this saves a 'safe' function. + */ + image->opaque->png_ptr->io_ptr = file; + return png_safe_execute(image, png_image_read_header, image); + } + } + + else + return png_image_error(image, + "png_image_begin_read_from_stdio: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); + + return 0; +} + +int PNGAPI +png_image_begin_read_from_file(png_imagep image, const char *file_name) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file_name != NULL) + { + FILE *fp = fopen(file_name, "rb"); + + if (fp != NULL) + { + if (png_image_read_init(image) != 0) + { + image->opaque->png_ptr->io_ptr = fp; + image->opaque->owned_file = 1; + return png_safe_execute(image, png_image_read_header, image); + } + + /* Clean up: just the opened file. */ + (void)fclose(fp); + } + + else + return png_image_error(image, strerror(errno)); + } + + else + return png_image_error(image, + "png_image_begin_read_from_file: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); + + return 0; +} +#endif /* STDIO */ + +static void PNGCBAPI +png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need) +{ + if (png_ptr != NULL) + { + png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); + if (image != NULL) + { + png_controlp cp = image->opaque; + if (cp != NULL) + { + png_const_bytep memory = cp->memory; + size_t size = cp->size; + + if (memory != NULL && size >= need) + { + memcpy(out, memory, need); + cp->memory = memory + need; + cp->size = size - need; + return; + } + + png_error(png_ptr, "read beyond end of data"); + } + } + + png_error(png_ptr, "invalid memory read"); + } +} + +int PNGAPI png_image_begin_read_from_memory(png_imagep image, + png_const_voidp memory, size_t size) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (memory != NULL && size > 0) + { + if (png_image_read_init(image) != 0) + { + /* Now set the IO functions to read from the memory buffer and + * store it into io_ptr. Again do this in-place to avoid calling a + * libpng function that requires error handling. + */ + image->opaque->memory = png_voidcast(png_const_bytep, memory); + image->opaque->size = size; + image->opaque->png_ptr->io_ptr = image; + image->opaque->png_ptr->read_data_fn = png_image_memory_read; + + return png_safe_execute(image, png_image_read_header, image); + } + } + + else + return png_image_error(image, + "png_image_begin_read_from_memory: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); + + return 0; +} + +/* Utility function to skip chunks that are not used by the simplified image + * read functions and an appropriate macro to call it. + */ +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +static void +png_image_skip_unused_chunks(png_structrp png_ptr) +{ + /* Prepare the reader to ignore all recognized chunks whose data will not + * be used, i.e., all chunks recognized by libpng except for those + * involved in basic image reading: + * + * IHDR, PLTE, IDAT, IEND + * + * Or image data handling: + * + * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. + * + * This provides a small performance improvement and eliminates any + * potential vulnerability to security problems in the unused chunks. + * + * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored + * too. This allows the simplified API to be compiled without iCCP support. + */ + { + static const png_byte chunks_to_process[] = { + 98, 75, 71, 68, '\0', /* bKGD */ + 99, 72, 82, 77, '\0', /* cHRM */ + 99, 73, 67, 80, '\0', /* cICP */ + 103, 65, 77, 65, '\0', /* gAMA */ + 109, 68, 67, 86, '\0', /* mDCV */ + 115, 66, 73, 84, '\0', /* sBIT */ + 115, 82, 71, 66, '\0', /* sRGB */ + }; + + /* Ignore unknown chunks and all other chunks except for the + * IHDR, PLTE, tRNS, IDAT, and IEND chunks. + */ + png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, + NULL, -1); + + /* But do not ignore image data handling chunks */ + png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, + chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); + } +} + +# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) +#else +# define PNG_SKIP_CHUNKS(p) ((void)0) +#endif /* HANDLE_AS_UNKNOWN */ + +/* The following macro gives the exact rounded answer for all values in the + * range 0..255 (it actually divides by 51.2, but the rounding still generates + * the correct numbers 0..5 + */ +#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) + +/* Utility functions to make particular color-maps */ +static void +set_file_encoding(png_image_read_control *display) +{ + png_structrp png_ptr = display->image->opaque->png_ptr; + png_fixed_point g = png_resolve_file_gamma(png_ptr); + + /* PNGv3: the result may be 0 however the 'default_gamma' should have been + * set before this is called so zero is an error: + */ + if (g == 0) + png_error(png_ptr, "internal: default gamma not set"); + + if (png_gamma_significant(g) != 0) + { + if (png_gamma_not_sRGB(g) != 0) + { + display->file_encoding = P_FILE; + display->gamma_to_linear = png_reciprocal(g); + } + + else + display->file_encoding = P_sRGB; + } + + else + display->file_encoding = P_LINEAR8; +} + +static unsigned int +decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) +{ + if (encoding == P_FILE) /* double check */ + encoding = display->file_encoding; + + if (encoding == P_NOTSET) /* must be the file encoding */ + { + set_file_encoding(display); + encoding = display->file_encoding; + } + + switch (encoding) + { + case P_FILE: + value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); + break; + + case P_sRGB: + value = png_sRGB_table[value]; + break; + + case P_LINEAR: + break; + + case P_LINEAR8: + value *= 257; + break; + +#ifdef __GNUC__ + default: + png_error(display->image->opaque->png_ptr, + "unexpected encoding (internal error)"); +#endif + } + + return value; +} + +static png_uint_32 +png_colormap_compose(png_image_read_control *display, + png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, + png_uint_32 background, int encoding) +{ + /* The file value is composed on the background, the background has the given + * encoding and so does the result, the file is encoded with P_FILE and the + * file and alpha are 8-bit values. The (output) encoding will always be + * P_LINEAR or P_sRGB. + */ + png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); + png_uint_32 b = decode_gamma(display, background, encoding); + + /* The alpha is always an 8-bit value (it comes from the palette), the value + * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. + */ + f = f * alpha + b * (255-alpha); + + if (encoding == P_LINEAR) + { + /* Scale to 65535; divide by 255, approximately (in fact this is extremely + * accurate, it divides by 255.00000005937181414556, with no overflow.) + */ + f *= 257; /* Now scaled by 65535 */ + f += f >> 16; + f = (f+32768) >> 16; + } + + else /* P_sRGB */ + f = PNG_sRGB_FROM_LINEAR(f); + + return f; +} + +/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must + * be 8-bit. + */ +static void +png_create_colormap_entry(png_image_read_control *display, + png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, + png_uint_32 alpha, int encoding) +{ + png_imagep image = display->image; + int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? + P_LINEAR : P_sRGB; + int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && + (red != green || green != blue); + + if (ip > 255) + png_error(image->opaque->png_ptr, "color-map index out of range"); + + /* Update the cache with whether the file gamma is significantly different + * from sRGB. + */ + if (encoding == P_FILE) + { + if (display->file_encoding == P_NOTSET) + set_file_encoding(display); + + /* Note that the cached value may be P_FILE too, but if it is then the + * gamma_to_linear member has been set. + */ + encoding = display->file_encoding; + } + + if (encoding == P_FILE) + { + png_fixed_point g = display->gamma_to_linear; + + red = png_gamma_16bit_correct(red*257, g); + green = png_gamma_16bit_correct(green*257, g); + blue = png_gamma_16bit_correct(blue*257, g); + + if (convert_to_Y != 0 || output_encoding == P_LINEAR) + { + alpha *= 257; + encoding = P_LINEAR; + } + + else + { + red = PNG_sRGB_FROM_LINEAR(red * 255); + green = PNG_sRGB_FROM_LINEAR(green * 255); + blue = PNG_sRGB_FROM_LINEAR(blue * 255); + encoding = P_sRGB; + } + } + + else if (encoding == P_LINEAR8) + { + /* This encoding occurs quite frequently in test cases because PngSuite + * includes a gAMA 1.0 chunk with most images. + */ + red *= 257; + green *= 257; + blue *= 257; + alpha *= 257; + encoding = P_LINEAR; + } + + else if (encoding == P_sRGB && + (convert_to_Y != 0 || output_encoding == P_LINEAR)) + { + /* The values are 8-bit sRGB values, but must be converted to 16-bit + * linear. + */ + red = png_sRGB_table[red]; + green = png_sRGB_table[green]; + blue = png_sRGB_table[blue]; + alpha *= 257; + encoding = P_LINEAR; + } + + /* This is set if the color isn't gray but the output is. */ + if (encoding == P_LINEAR) + { + if (convert_to_Y != 0) + { + /* NOTE: these values are copied from png_do_rgb_to_gray */ + png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + + (png_uint_32)2366 * blue; + + if (output_encoding == P_LINEAR) + y = (y + 16384) >> 15; + + else + { + /* y is scaled by 32768, we need it scaled by 255: */ + y = (y + 128) >> 8; + y *= 255; + y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); + alpha = PNG_DIV257(alpha); + encoding = P_sRGB; + } + + blue = red = green = y; + } + + else if (output_encoding == P_sRGB) + { + red = PNG_sRGB_FROM_LINEAR(red * 255); + green = PNG_sRGB_FROM_LINEAR(green * 255); + blue = PNG_sRGB_FROM_LINEAR(blue * 255); + alpha = PNG_DIV257(alpha); + encoding = P_sRGB; + } + } + + if (encoding != output_encoding) + png_error(image->opaque->png_ptr, "bad encoding (internal error)"); + + /* Store the value. */ + { +# ifdef PNG_FORMAT_AFIRST_SUPPORTED + int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && + (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; +# else +# define afirst 0 +# endif +# ifdef PNG_FORMAT_BGR_SUPPORTED + int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; +# else +# define bgr 0 +# endif + + if (output_encoding == P_LINEAR) + { + png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); + + entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); + + /* The linear 16-bit values must be pre-multiplied by the alpha channel + * value, if less than 65535 (this is, effectively, composite on black + * if the alpha channel is removed.) + */ + switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) + { + case 4: + entry[afirst ? 0 : 3] = (png_uint_16)alpha; + /* FALLTHROUGH */ + + case 3: + if (alpha < 65535) + { + if (alpha > 0) + { + blue = (blue * alpha + 32767U)/65535U; + green = (green * alpha + 32767U)/65535U; + red = (red * alpha + 32767U)/65535U; + } + + else + red = green = blue = 0; + } + entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; + entry[afirst + 1] = (png_uint_16)green; + entry[afirst + bgr] = (png_uint_16)red; + break; + + case 2: + entry[1 ^ afirst] = (png_uint_16)alpha; + /* FALLTHROUGH */ + + case 1: + if (alpha < 65535) + { + if (alpha > 0) + green = (green * alpha + 32767U)/65535U; + + else + green = 0; + } + entry[afirst] = (png_uint_16)green; + break; + + default: + break; + } + } + + else /* output encoding is P_sRGB */ + { + png_bytep entry = png_voidcast(png_bytep, display->colormap); + + entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); + + switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) + { + case 4: + entry[afirst ? 0 : 3] = (png_byte)alpha; + /* FALLTHROUGH */ + case 3: + entry[afirst + (2 ^ bgr)] = (png_byte)blue; + entry[afirst + 1] = (png_byte)green; + entry[afirst + bgr] = (png_byte)red; + break; + + case 2: + entry[1 ^ afirst] = (png_byte)alpha; + /* FALLTHROUGH */ + case 1: + entry[afirst] = (png_byte)green; + break; + + default: + break; + } + } + +# ifdef afirst +# undef afirst +# endif +# ifdef bgr +# undef bgr +# endif + } +} + +static int +make_gray_file_colormap(png_image_read_control *display) +{ + unsigned int i; + + for (i=0; i<256; ++i) + png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); + + return (int)i; +} + +static int +make_gray_colormap(png_image_read_control *display) +{ + unsigned int i; + + for (i=0; i<256; ++i) + png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); + + return (int)i; +} +#define PNG_GRAY_COLORMAP_ENTRIES 256 + +static int +make_ga_colormap(png_image_read_control *display) +{ + unsigned int i, a; + + /* Alpha is retained, the output will be a color-map with entries + * selected by six levels of alpha. One transparent entry, 6 gray + * levels for all the intermediate alpha values, leaving 230 entries + * for the opaque grays. The color-map entries are the six values + * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the + * relevant entry. + * + * if (alpha > 229) // opaque + * { + * // The 231 entries are selected to make the math below work: + * base = 0; + * entry = (231 * gray + 128) >> 8; + * } + * else if (alpha < 26) // transparent + * { + * base = 231; + * entry = 0; + * } + * else // partially opaque + * { + * base = 226 + 6 * PNG_DIV51(alpha); + * entry = PNG_DIV51(gray); + * } + */ + i = 0; + while (i < 231) + { + unsigned int gray = (i * 256 + 115) / 231; + png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); + } + + /* 255 is used here for the component values for consistency with the code + * that undoes premultiplication in pngwrite.c. + */ + png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); + + for (a=1; a<5; ++a) + { + unsigned int g; + + for (g=0; g<6; ++g) + png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, + P_sRGB); + } + + return (int)i; +} + +#define PNG_GA_COLORMAP_ENTRIES 256 + +static int +make_rgb_colormap(png_image_read_control *display) +{ + unsigned int i, r; + + /* Build a 6x6x6 opaque RGB cube */ + for (i=r=0; r<6; ++r) + { + unsigned int g; + + for (g=0; g<6; ++g) + { + unsigned int b; + + for (b=0; b<6; ++b) + png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, + P_sRGB); + } + } + + return (int)i; +} + +#define PNG_RGB_COLORMAP_ENTRIES 216 + +/* Return a palette index to the above palette given three 8-bit sRGB values. */ +#define PNG_RGB_INDEX(r,g,b) \ + ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) + +static int +png_image_read_colormap(png_voidp argument) +{ + png_image_read_control *display = + png_voidcast(png_image_read_control*, argument); + png_imagep image = display->image; + + png_structrp png_ptr = image->opaque->png_ptr; + png_uint_32 output_format = image->format; + int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? + P_LINEAR : P_sRGB; + + unsigned int cmap_entries; + unsigned int output_processing; /* Output processing option */ + unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ + + /* Background information; the background color and the index of this color + * in the color-map if it exists (else 256). + */ + unsigned int background_index = 256; + png_uint_32 back_r, back_g, back_b; + + /* Flags to accumulate things that need to be done to the input. */ + int expand_tRNS = 0; + + /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is + * very difficult to do, the results look awful, and it is difficult to see + * what possible use it is because the application can't control the + * color-map. + */ + if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || + png_ptr->num_trans > 0) /* alpha in input */ && + ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) + { + if (output_encoding == P_LINEAR) /* compose on black */ + back_b = back_g = back_r = 0; + + else if (display->background == NULL /* no way to remove it */) + png_error(png_ptr, + "background color must be supplied to remove alpha/transparency"); + + /* Get a copy of the background color (this avoids repeating the checks + * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the + * output format. + */ + else + { + back_g = display->background->green; + if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) + { + back_r = display->background->red; + back_b = display->background->blue; + } + else + back_b = back_r = back_g; + } + } + + else if (output_encoding == P_LINEAR) + back_b = back_r = back_g = 65535; + + else + back_b = back_r = back_g = 255; + + /* Default the input file gamma if required - this is necessary because + * libpng assumes that if no gamma information is present the data is in the + * output format, but the simplified API deduces the gamma from the input + * format. The 'default' gamma value is also set by png_set_alpha_mode, but + * this is happening before any such call, so: + * + * TODO: should be an internal API and all this code should be copied into a + * single common gamma+colorspace file. + */ + if (png_ptr->bit_depth == 16 && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) + png_ptr->default_gamma = PNG_GAMMA_LINEAR; + + else + png_ptr->default_gamma = PNG_GAMMA_sRGB_INVERSE; + + /* Decide what to do based on the PNG color type of the input data. The + * utility function png_create_colormap_entry deals with most aspects of the + * output transformations; this code works out how to produce bytes of + * color-map entries from the original format. + */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_GRAY: + if (png_ptr->bit_depth <= 8) + { + /* There at most 256 colors in the output, regardless of + * transparency. + */ + unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; + + cmap_entries = 1U << png_ptr->bit_depth; + if (cmap_entries > image->colormap_entries) + png_error(png_ptr, "gray[8] color-map: too few entries"); + + step = 255 / (cmap_entries - 1); + output_processing = PNG_CMAP_NONE; + + /* If there is a tRNS chunk then this either selects a transparent + * value or, if the output has no alpha, the background color. + */ + if (png_ptr->num_trans > 0) + { + trans = png_ptr->trans_color.gray; + + if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) + back_alpha = output_encoding == P_LINEAR ? 65535 : 255; + } + + /* png_create_colormap_entry just takes an RGBA and writes the + * corresponding color-map entry using the format from 'image', + * including the required conversion to sRGB or linear as + * appropriate. The input values are always either sRGB (if the + * gamma correction flag is 0) or 0..255 scaled file encoded values + * (if the function must gamma correct them). + */ + for (i=val=0; ibit_depth < 8) + png_set_packing(png_ptr); + } + + else /* bit depth is 16 */ + { + /* The 16-bit input values can be converted directly to 8-bit gamma + * encoded values; however, if a tRNS chunk is present 257 color-map + * entries are required. This means that the extra entry requires + * special processing; add an alpha channel, sacrifice gray level + * 254 and convert transparent (alpha==0) entries to that. + * + * Use libpng to chop the data to 8 bits. Convert it to sRGB at the + * same time to minimize quality loss. If a tRNS chunk is present + * this means libpng must handle it too; otherwise it is impossible + * to do the exact match on the 16-bit value. + * + * If the output has no alpha channel *and* the background color is + * gray then it is possible to let libpng handle the substitution by + * ensuring that the corresponding gray level matches the background + * color exactly. + */ + data_encoding = P_sRGB; + + if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "gray[16] color-map: too few entries"); + + cmap_entries = (unsigned int)make_gray_colormap(display); + + if (png_ptr->num_trans > 0) + { + unsigned int back_alpha; + + if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) + back_alpha = 0; + + else + { + if (back_r == back_g && back_g == back_b) + { + /* Background is gray; no special processing will be + * required. + */ + png_color_16 c; + png_uint_32 gray = back_g; + + if (output_encoding == P_LINEAR) + { + gray = PNG_sRGB_FROM_LINEAR(gray * 255); + + /* And make sure the corresponding palette entry + * matches. + */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 65535, P_LINEAR); + } + + /* The background passed to libpng, however, must be the + * sRGB value. + */ + c.index = 0; /*unused*/ + c.gray = c.red = c.green = c.blue = (png_uint_16)gray; + + /* NOTE: does this work without expanding tRNS to alpha? + * It should be the color->gray case below apparently + * doesn't. + */ + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + + output_processing = PNG_CMAP_NONE; + break; + } +#ifdef __COVERITY__ + /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) + * here. + */ + back_alpha = 255; +#else + back_alpha = output_encoding == P_LINEAR ? 65535 : 255; +#endif + } + + /* output_processing means that the libpng-processed row will be + * 8-bit GA and it has to be processing to single byte color-map + * values. Entry 254 is replaced by either a completely + * transparent entry or by the background color at full + * precision (and the background color is not a simple gray + * level in this case.) + */ + expand_tRNS = 1; + output_processing = PNG_CMAP_TRANS; + background_index = 254; + + /* And set (overwrite) color-map entry 254 to the actual + * background color at full precision. + */ + png_create_colormap_entry(display, 254, back_r, back_g, back_b, + back_alpha, output_encoding); + } + + else + output_processing = PNG_CMAP_NONE; + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum + * of 65536 combinations. If, however, the alpha channel is to be + * removed there are only 256 possibilities if the background is gray. + * (Otherwise there is a subset of the 65536 possibilities defined by + * the triangle between black, white and the background color.) + * + * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to + * worry about tRNS matching - tRNS is ignored if there is an alpha + * channel. + */ + data_encoding = P_sRGB; + + if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "gray+alpha color-map: too few entries"); + + cmap_entries = (unsigned int)make_ga_colormap(display); + + background_index = PNG_CMAP_GA_BACKGROUND; + output_processing = PNG_CMAP_GA; + } + + else /* alpha is removed */ + { + /* Alpha must be removed as the PNG data is processed when the + * background is a color because the G and A channels are + * independent and the vector addition (non-parallel vectors) is a + * 2-D problem. + * + * This can be reduced to the same algorithm as above by making a + * colormap containing gray levels (for the opaque grays), a + * background entry (for a transparent pixel) and a set of four six + * level color values, one set for each intermediate alpha value. + * See the comments in make_ga_colormap for how this works in the + * per-pixel processing. + * + * If the background is gray, however, we only need a 256 entry gray + * level color map. It is sufficient to make the entry generated + * for the background color be exactly the color specified. + */ + if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || + (back_r == back_g && back_g == back_b)) + { + /* Background is gray; no special processing will be required. */ + png_color_16 c; + png_uint_32 gray = back_g; + + if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "gray-alpha color-map: too few entries"); + + cmap_entries = (unsigned int)make_gray_colormap(display); + + if (output_encoding == P_LINEAR) + { + gray = PNG_sRGB_FROM_LINEAR(gray * 255); + + /* And make sure the corresponding palette entry matches. */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 65535, P_LINEAR); + } + + /* The background passed to libpng, however, must be the sRGB + * value. + */ + c.index = 0; /*unused*/ + c.gray = c.red = c.green = c.blue = (png_uint_16)gray; + + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + + output_processing = PNG_CMAP_NONE; + } + + else + { + png_uint_32 i, a; + + /* This is the same as png_make_ga_colormap, above, except that + * the entries are all opaque. + */ + if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "ga-alpha color-map: too few entries"); + + i = 0; + while (i < 231) + { + png_uint_32 gray = (i * 256 + 115) / 231; + png_create_colormap_entry(display, i++, gray, gray, gray, + 255, P_sRGB); + } + + /* NOTE: this preserves the full precision of the application + * background color. + */ + background_index = i; + png_create_colormap_entry(display, i++, back_r, back_g, back_b, +#ifdef __COVERITY__ + /* Coverity claims that output_encoding + * cannot be 2 (P_LINEAR) here. + */ 255U, +#else + output_encoding == P_LINEAR ? 65535U : 255U, +#endif + output_encoding); + + /* For non-opaque input composite on the sRGB background - this + * requires inverting the encoding for each component. The input + * is still converted to the sRGB encoding because this is a + * reasonable approximate to the logarithmic curve of human + * visual sensitivity, at least over the narrow range which PNG + * represents. Consequently 'G' is always sRGB encoded, while + * 'A' is linear. We need the linear background colors. + */ + if (output_encoding == P_sRGB) /* else already linear */ + { + /* This may produce a value not exactly matching the + * background, but that's ok because these numbers are only + * used when alpha != 0 + */ + back_r = png_sRGB_table[back_r]; + back_g = png_sRGB_table[back_g]; + back_b = png_sRGB_table[back_b]; + } + + for (a=1; a<5; ++a) + { + unsigned int g; + + /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled + * by an 8-bit alpha value (0..255). + */ + png_uint_32 alpha = 51 * a; + png_uint_32 back_rx = (255-alpha) * back_r; + png_uint_32 back_gx = (255-alpha) * back_g; + png_uint_32 back_bx = (255-alpha) * back_b; + + for (g=0; g<6; ++g) + { + png_uint_32 gray = png_sRGB_table[g*51] * alpha; + + png_create_colormap_entry(display, i++, + PNG_sRGB_FROM_LINEAR(gray + back_rx), + PNG_sRGB_FROM_LINEAR(gray + back_gx), + PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); + } + } + + cmap_entries = i; + output_processing = PNG_CMAP_GA; + } + } + break; + + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + /* Exclude the case where the output is gray; we can always handle this + * with the cases above. + */ + if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) + { + /* The color-map will be grayscale, so we may as well convert the + * input RGB values to a simple grayscale and use the grayscale + * code above. + * + * NOTE: calling this apparently damages the recognition of the + * transparent color in background color handling; call + * png_set_tRNS_to_alpha before png_set_background_fixed. + */ + png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, + -1); + data_encoding = P_sRGB; + + /* The output will now be one or two 8-bit gray or gray+alpha + * channels. The more complex case arises when the input has alpha. + */ + if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) && + (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + /* Both input and output have an alpha channel, so no background + * processing is required; just map the GA bytes to the right + * color-map entry. + */ + expand_tRNS = 1; + + if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "rgb[ga] color-map: too few entries"); + + cmap_entries = (unsigned int)make_ga_colormap(display); + background_index = PNG_CMAP_GA_BACKGROUND; + output_processing = PNG_CMAP_GA; + } + + else + { + const png_fixed_point gamma = png_resolve_file_gamma(png_ptr); + + /* Either the input or the output has no alpha channel, so there + * will be no non-opaque pixels in the color-map; it will just be + * grayscale. + */ + if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "rgb[gray] color-map: too few entries"); + + /* Ideally this code would use libpng to do the gamma correction, + * but if an input alpha channel is to be removed we will hit the + * libpng bug in gamma+compose+rgb-to-gray (the double gamma + * correction bug). Fix this by dropping the gamma correction in + * this case and doing it in the palette; this will result in + * duplicate palette entries, but that's better than the + * alternative of double gamma correction. + * + * NOTE: PNGv3: check the resolved result of all the potentially + * different colour space chunks. + */ + if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) && + png_gamma_not_sRGB(gamma) != 0) + { + cmap_entries = (unsigned int)make_gray_file_colormap(display); + data_encoding = P_FILE; + } + + else + cmap_entries = (unsigned int)make_gray_colormap(display); + + /* But if the input has alpha or transparency it must be removed + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) + { + png_color_16 c; + png_uint_32 gray = back_g; + + /* We need to ensure that the application background exists in + * the colormap and that completely transparent pixels map to + * it. Achieve this simply by ensuring that the entry + * selected for the background really is the background color. + */ + if (data_encoding == P_FILE) /* from the fixup above */ + { + /* The app supplied a gray which is in output_encoding, we + * need to convert it to a value of the input (P_FILE) + * encoding then set this palette entry to the required + * output encoding. + */ + if (output_encoding == P_sRGB) + gray = png_sRGB_table[gray]; /* now P_LINEAR */ + + gray = PNG_DIV257(png_gamma_16bit_correct(gray, gamma)); + /* now P_FILE */ + + /* And make sure the corresponding palette entry contains + * exactly the required sRGB value. + */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 0/*unused*/, output_encoding); + } + + else if (output_encoding == P_LINEAR) + { + gray = PNG_sRGB_FROM_LINEAR(gray * 255); + + /* And make sure the corresponding palette entry matches. + */ + png_create_colormap_entry(display, gray, back_g, back_g, + back_g, 0/*unused*/, P_LINEAR); + } + + /* The background passed to libpng, however, must be the + * output (normally sRGB) value. + */ + c.index = 0; /*unused*/ + c.gray = c.red = c.green = c.blue = (png_uint_16)gray; + + /* NOTE: the following is apparently a bug in libpng. Without + * it the transparent color recognition in + * png_set_background_fixed seems to go wrong. + */ + expand_tRNS = 1; + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + } + + output_processing = PNG_CMAP_NONE; + } + } + + else /* output is color */ + { + /* We could use png_quantize here so long as there is no transparent + * color or alpha; png_quantize ignores alpha. Easier overall just + * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. + * Consequently we always want libpng to produce sRGB data. + */ + data_encoding = P_sRGB; + + /* Is there any transparency or alpha? */ + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + png_ptr->num_trans > 0) + { + /* Is there alpha in the output too? If so all four channels are + * processed into a special RGB cube with alpha support. + */ + if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + png_uint_32 r; + + if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) + png_error(png_ptr, "rgb+alpha color-map: too few entries"); + + cmap_entries = (unsigned int)make_rgb_colormap(display); + + /* Add a transparent entry. */ + png_create_colormap_entry(display, cmap_entries, 255, 255, + 255, 0, P_sRGB); + + /* This is stored as the background index for the processing + * algorithm. + */ + background_index = cmap_entries++; + + /* Add 27 r,g,b entries each with alpha 0.5. */ + for (r=0; r<256; r = (r << 1) | 0x7f) + { + png_uint_32 g; + + for (g=0; g<256; g = (g << 1) | 0x7f) + { + png_uint_32 b; + + /* This generates components with the values 0, 127 and + * 255 + */ + for (b=0; b<256; b = (b << 1) | 0x7f) + png_create_colormap_entry(display, cmap_entries++, + r, g, b, 128, P_sRGB); + } + } + + expand_tRNS = 1; + output_processing = PNG_CMAP_RGB_ALPHA; + } + + else + { + /* Alpha/transparency must be removed. The background must + * exist in the color map (achieved by setting adding it after + * the 666 color-map). If the standard processing code will + * pick up this entry automatically that's all that is + * required; libpng can be called to do the background + * processing. + */ + unsigned int sample_size = + PNG_IMAGE_SAMPLE_SIZE(output_format); + png_uint_32 r, g, b; /* sRGB background */ + + if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) + png_error(png_ptr, "rgb-alpha color-map: too few entries"); + + cmap_entries = (unsigned int)make_rgb_colormap(display); + + png_create_colormap_entry(display, cmap_entries, back_r, + back_g, back_b, 0/*unused*/, output_encoding); + + if (output_encoding == P_LINEAR) + { + r = PNG_sRGB_FROM_LINEAR(back_r * 255); + g = PNG_sRGB_FROM_LINEAR(back_g * 255); + b = PNG_sRGB_FROM_LINEAR(back_b * 255); + } + + else + { + r = back_r; + g = back_g; + b = back_b; + } + + /* Compare the newly-created color-map entry with the one the + * PNG_CMAP_RGB algorithm will use. If the two entries don't + * match, add the new one and set this as the background + * index. + */ + if (memcmp((png_const_bytep)display->colormap + + sample_size * cmap_entries, + (png_const_bytep)display->colormap + + sample_size * PNG_RGB_INDEX(r,g,b), + sample_size) != 0) + { + /* The background color must be added. */ + background_index = cmap_entries++; + + /* Add 27 r,g,b entries each with created by composing with + * the background at alpha 0.5. + */ + for (r=0; r<256; r = (r << 1) | 0x7f) + { + for (g=0; g<256; g = (g << 1) | 0x7f) + { + /* This generates components with the values 0, 127 + * and 255 + */ + for (b=0; b<256; b = (b << 1) | 0x7f) + png_create_colormap_entry(display, cmap_entries++, + png_colormap_compose(display, r, P_sRGB, 128, + back_r, output_encoding), + png_colormap_compose(display, g, P_sRGB, 128, + back_g, output_encoding), + png_colormap_compose(display, b, P_sRGB, 128, + back_b, output_encoding), + 0/*unused*/, output_encoding); + } + } + + expand_tRNS = 1; + output_processing = PNG_CMAP_RGB_ALPHA; + } + + else /* background color is in the standard color-map */ + { + png_color_16 c; + + c.index = 0; /*unused*/ + c.red = (png_uint_16)back_r; + c.gray = c.green = (png_uint_16)back_g; + c.blue = (png_uint_16)back_b; + + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + + output_processing = PNG_CMAP_RGB; + } + } + } + + else /* no alpha or transparency in the input */ + { + /* Alpha in the output is irrelevant, simply map the opaque input + * pixels to the 6x6x6 color-map. + */ + if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) + png_error(png_ptr, "rgb color-map: too few entries"); + + cmap_entries = (unsigned int)make_rgb_colormap(display); + output_processing = PNG_CMAP_RGB; + } + } + break; + + case PNG_COLOR_TYPE_PALETTE: + /* It's already got a color-map. It may be necessary to eliminate the + * tRNS entries though. + */ + { + unsigned int num_trans = png_ptr->num_trans; + png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; + png_const_colorp colormap = png_ptr->palette; + int do_background = trans != NULL && + (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; + unsigned int i; + + /* Just in case: */ + if (trans == NULL) + num_trans = 0; + + output_processing = PNG_CMAP_NONE; + data_encoding = P_FILE; /* Don't change from color-map indices */ + cmap_entries = (unsigned int)png_ptr->num_palette; + if (cmap_entries > 256) + cmap_entries = 256; + + if (cmap_entries > (unsigned int)image->colormap_entries) + png_error(png_ptr, "palette color-map: too few entries"); + + for (i=0; i < cmap_entries; ++i) + { + if (do_background != 0 && i < num_trans && trans[i] < 255) + { + if (trans[i] == 0) + png_create_colormap_entry(display, i, back_r, back_g, + back_b, 0, output_encoding); + + else + { + /* Must compose the PNG file color in the color-map entry + * on the sRGB color in 'back'. + */ + png_create_colormap_entry(display, i, + png_colormap_compose(display, colormap[i].red, + P_FILE, trans[i], back_r, output_encoding), + png_colormap_compose(display, colormap[i].green, + P_FILE, trans[i], back_g, output_encoding), + png_colormap_compose(display, colormap[i].blue, + P_FILE, trans[i], back_b, output_encoding), + output_encoding == P_LINEAR ? trans[i] * 257U : + trans[i], + output_encoding); + } + } + + else + png_create_colormap_entry(display, i, colormap[i].red, + colormap[i].green, colormap[i].blue, + i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); + } + + /* The PNG data may have indices packed in fewer than 8 bits, it + * must be expanded if so. + */ + if (png_ptr->bit_depth < 8) + png_set_packing(png_ptr); + } + break; + + default: + png_error(png_ptr, "invalid PNG color type"); + /*NOT REACHED*/ + } + + /* Now deal with the output processing */ + if (expand_tRNS != 0 && png_ptr->num_trans > 0 && + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) + png_set_tRNS_to_alpha(png_ptr); + + switch (data_encoding) + { + case P_sRGB: + /* Change to 8-bit sRGB */ + png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); + /* FALLTHROUGH */ + + case P_FILE: + if (png_ptr->bit_depth > 8) + png_set_scale_16(png_ptr); + break; + +#ifdef __GNUC__ + default: + png_error(png_ptr, "bad data option (internal error)"); +#endif + } + + if (cmap_entries > 256 || cmap_entries > image->colormap_entries) + png_error(png_ptr, "color map overflow (BAD internal error)"); + + image->colormap_entries = cmap_entries; + + /* Double check using the recorded background index */ + switch (output_processing) + { + case PNG_CMAP_NONE: + if (background_index != PNG_CMAP_NONE_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_GA: + if (background_index != PNG_CMAP_GA_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_TRANS: + if (background_index >= cmap_entries || + background_index != PNG_CMAP_TRANS_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_RGB: + if (background_index != PNG_CMAP_RGB_BACKGROUND) + goto bad_background; + break; + + case PNG_CMAP_RGB_ALPHA: + if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) + goto bad_background; + break; + + default: + png_error(png_ptr, "bad processing option (internal error)"); + + bad_background: + png_error(png_ptr, "bad background index (internal error)"); + } + + display->colormap_processing = (int)output_processing; + + return 1/*ok*/; +} + +/* The final part of the color-map read called from png_image_finish_read. */ +static int +png_image_read_and_map(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + int passes; + + /* Called when the libpng data must be transformed into the color-mapped + * form. There is a local row buffer in display->local and this routine must + * do the interlace handling. + */ + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + { + png_uint_32 height = image->height; + png_uint_32 width = image->width; + int proc = display->colormap_processing; + png_bytep first_row = png_voidcast(png_bytep, display->first_row); + ptrdiff_t row_step = display->row_step; + int pass; + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass); + stepx = PNG_PASS_COL_OFFSET(pass); + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = stepy = 1; + } + + for (; ylocal_row); + png_bytep outrow = first_row + y * row_step; + png_const_bytep row_end = outrow + width; + + /* Read the libpng data into the temporary buffer. */ + png_read_row(png_ptr, inrow, NULL); + + /* Now process the row according to the processing option, note + * that the caller verifies that the format of the libpng output + * data is as required. + */ + outrow += startx; + switch (proc) + { + case PNG_CMAP_GA: + for (; outrow < row_end; outrow += stepx) + { + /* The data is always in the PNG order */ + unsigned int gray = *inrow++; + unsigned int alpha = *inrow++; + unsigned int entry; + + /* NOTE: this code is copied as a comment in + * make_ga_colormap above. Please update the + * comment if you change this code! + */ + if (alpha > 229) /* opaque */ + { + entry = (231 * gray + 128) >> 8; + } + else if (alpha < 26) /* transparent */ + { + entry = 231; + } + else /* partially opaque */ + { + entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); + } + + *outrow = (png_byte)entry; + } + break; + + case PNG_CMAP_TRANS: + for (; outrow < row_end; outrow += stepx) + { + png_byte gray = *inrow++; + png_byte alpha = *inrow++; + + if (alpha == 0) + *outrow = PNG_CMAP_TRANS_BACKGROUND; + + else if (gray != PNG_CMAP_TRANS_BACKGROUND) + *outrow = gray; + + else + *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); + } + break; + + case PNG_CMAP_RGB: + for (; outrow < row_end; outrow += stepx) + { + *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); + inrow += 3; + } + break; + + case PNG_CMAP_RGB_ALPHA: + for (; outrow < row_end; outrow += stepx) + { + unsigned int alpha = inrow[3]; + + /* Because the alpha entries only hold alpha==0.5 values + * split the processing at alpha==0.25 (64) and 0.75 + * (196). + */ + + if (alpha >= 196) + *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], + inrow[2]); + + else if (alpha < 64) + *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; + + else + { + /* Likewise there are three entries for each of r, g + * and b. We could select the entry by popcount on + * the top two bits on those architectures that + * support it, this is what the code below does, + * crudely. + */ + unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; + + /* Here are how the values map: + * + * 0x00 .. 0x3f -> 0 + * 0x40 .. 0xbf -> 1 + * 0xc0 .. 0xff -> 2 + * + * So, as above with the explicit alpha checks, the + * breakpoints are at 64 and 196. + */ + if (inrow[0] & 0x80) back_i += 9; /* red */ + if (inrow[0] & 0x40) back_i += 9; + if (inrow[1] & 0x80) back_i += 3; /* green */ + if (inrow[1] & 0x40) back_i += 3; + if (inrow[2] & 0x80) back_i += 1; /* blue */ + if (inrow[2] & 0x40) back_i += 1; + + *outrow = (png_byte)back_i; + } + + inrow += 4; + } + break; + + default: + break; + } + } + } + } + + return 1; +} + +static int +png_image_read_colormapped(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_controlp control = image->opaque; + png_structrp png_ptr = control->png_ptr; + png_inforp info_ptr = control->info_ptr; + + int passes = 0; /* As a flag */ + + PNG_SKIP_CHUNKS(png_ptr); + + /* Update the 'info' structure and make sure the result is as required; first + * make sure to turn on the interlace handling if it will be required + * (because it can't be turned on *after* the call to png_read_update_info!) + */ + if (display->colormap_processing == PNG_CMAP_NONE) + passes = png_set_interlace_handling(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + + /* The expected output can be deduced from the colormap_processing option. */ + switch (display->colormap_processing) + { + case PNG_CMAP_NONE: + /* Output must be one channel and one byte per pixel, the output + * encoding can be anything. + */ + if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && + info_ptr->bit_depth == 8) + break; + + goto bad_output; + + case PNG_CMAP_TRANS: + case PNG_CMAP_GA: + /* Output must be two channels and the 'G' one must be sRGB, the latter + * can be checked with an exact number because it should have been set + * to this number above! + */ + if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + info_ptr->bit_depth == 8 && + png_ptr->screen_gamma == PNG_GAMMA_sRGB && + image->colormap_entries == 256) + break; + + goto bad_output; + + case PNG_CMAP_RGB: + /* Output must be 8-bit sRGB encoded RGB */ + if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + info_ptr->bit_depth == 8 && + png_ptr->screen_gamma == PNG_GAMMA_sRGB && + image->colormap_entries == 216) + break; + + goto bad_output; + + case PNG_CMAP_RGB_ALPHA: + /* Output must be 8-bit sRGB encoded RGBA */ + if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + info_ptr->bit_depth == 8 && + png_ptr->screen_gamma == PNG_GAMMA_sRGB && + image->colormap_entries == 244 /* 216 + 1 + 27 */) + break; + + goto bad_output; + + default: + bad_output: + png_error(png_ptr, "bad color-map processing (internal error)"); + } + + /* Now read the rows. Do this here if it is possible to read directly into + * the output buffer, otherwise allocate a local row buffer of the maximum + * size libpng requires and call the relevant processing routine safely. + */ + { + png_voidp first_row = display->buffer; + ptrdiff_t row_step = display->row_stride; + + /* The following adjustment is to ensure that calculations are correct, + * regardless whether row_step is positive or negative. + */ + if (row_step < 0) + { + char *ptr = png_voidcast(char*, first_row); + ptr += (image->height-1) * (-row_step); + first_row = png_voidcast(png_voidp, ptr); + } + + display->first_row = first_row; + display->row_step = row_step; + } + + if (passes == 0) + { + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_and_map, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else + { + ptrdiff_t row_step = display->row_step; + + while (--passes >= 0) + { + png_uint_32 y = image->height; + png_bytep row = png_voidcast(png_bytep, display->first_row); + + for (; y > 0; --y) + { + png_read_row(png_ptr, row, NULL); + row += row_step; + } + } + + return 1; + } +} + +/* Row reading for interlaced 16-to-8 bit depth conversion with local buffer. */ +static int +png_image_read_direct_scaled(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + png_bytep local_row = png_voidcast(png_bytep, display->local_row); + png_bytep first_row = png_voidcast(png_bytep, display->first_row); + ptrdiff_t row_step = display->row_step; + size_t row_bytes = png_get_rowbytes(png_ptr, info_ptr); + int passes; + + /* Handle interlacing. */ + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + /* Read each pass using local_row as intermediate buffer. */ + while (--passes >= 0) + { + png_uint_32 y = image->height; + png_bytep output_row = first_row; + + for (; y > 0; --y) + { + /* Read into local_row (gets transformed 8-bit data). */ + png_read_row(png_ptr, local_row, NULL); + + /* Copy from local_row to user buffer. + * Use row_bytes (i.e. the actual size in bytes of the row data) for + * copying into output_row. Use row_step for advancing output_row, + * to respect the caller's stride for padding or negative (bottom-up) + * layouts. + */ + memcpy(output_row, local_row, row_bytes); + output_row += row_step; + } + } + + return 1; +} + +/* Just the row reading part of png_image_read. */ +static int +png_image_read_composite(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + int passes; + + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + { + png_uint_32 height = image->height; + png_uint_32 width = image->width; + ptrdiff_t row_step = display->row_step; + unsigned int channels = + (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; + int optimize_alpha = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; + int pass; + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass) * channels; + stepx = PNG_PASS_COL_OFFSET(pass) * channels; + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = channels; + stepy = 1; + } + + for (; ylocal_row); + png_bytep outrow; + png_const_bytep row_end; + + /* Read the row, which is packed: */ + png_read_row(png_ptr, inrow, NULL); + + outrow = png_voidcast(png_bytep, display->first_row); + outrow += y * row_step; + row_end = outrow + width * channels; + + /* Now do the composition on each pixel in this row. */ + outrow += startx; + for (; outrow < row_end; outrow += stepx) + { + png_byte alpha = inrow[channels]; + + if (alpha > 0) /* else no change to the output */ + { + unsigned int c; + + for (c=0; c 255*65535) + component = 255*65535; + + /* So 'component' is scaled by 255*65535 and is + * therefore appropriate for the sRGB-to-linear + * conversion table. + */ + component = PNG_sRGB_FROM_LINEAR(component); + } + else + { + /* Compositing was already done on the palette + * entries. The data is sRGB premultiplied on black. + * Composite with the background in sRGB space. + * This is not gamma-correct, but matches what was + * done to the palette. + */ + png_uint_32 background = outrow[c]; + component += ((255-alpha) * background + 127) / 255; + if (component > 255) + component = 255; + } + } + + outrow[c] = (png_byte)component; + } + } + + inrow += channels+1; /* components and alpha channel */ + } + } + } + } + + return 1; +} + +/* The do_local_background case; called when all the following transforms are to + * be done: + * + * PNG_RGB_TO_GRAY + * PNG_COMPOSITE + * PNG_GAMMA + * + * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and + * PNG_COMPOSITE code performs gamma correction, so we get double gamma + * correction. The fix-up is to prevent the PNG_COMPOSITE operation from + * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha + * row and handles the removal or pre-multiplication of the alpha channel. + */ +static int +png_image_read_background(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + png_uint_32 height = image->height; + png_uint_32 width = image->width; + int pass, passes; + + /* Double check the convoluted logic below. We expect to get here with + * libpng doing rgb to gray and gamma correction but background processing + * left to the png_image_read_background function. The rows libpng produce + * might be 8 or 16-bit but should always have two channels; gray plus alpha. + */ + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) + png_error(png_ptr, "lost rgb to gray"); + + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_error(png_ptr, "unexpected compose"); + + if (png_get_channels(png_ptr, info_ptr) != 2) + png_error(png_ptr, "lost/gained channels"); + + /* Expect the 8-bit case to always remove the alpha channel */ + if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && + (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) + png_error(png_ptr, "unexpected 8-bit transformation"); + + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + /* Use direct access to info_ptr here because otherwise the simplified API + * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is + * checking the value after libpng expansions, not the original value in the + * PNG. + */ + switch (info_ptr->bit_depth) + { + case 8: + /* 8-bit sRGB gray values with an alpha channel; the alpha channel is + * to be removed by composing on a background: either the row if + * display->background is NULL or display->background->green if not. + * Unlike the code above ALPHA_OPTIMIZED has *not* been done. + */ + { + png_bytep first_row = png_voidcast(png_bytep, display->first_row); + ptrdiff_t row_step = display->row_step; + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass); + stepx = PNG_PASS_COL_OFFSET(pass); + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = stepy = 1; + } + + if (display->background == NULL) + { + for (; ylocal_row); + png_bytep outrow = first_row + y * row_step; + png_const_bytep row_end = outrow + width; + + /* Read the row, which is packed: */ + png_read_row(png_ptr, inrow, NULL); + + /* Now do the composition on each pixel in this row. */ + outrow += startx; + for (; outrow < row_end; outrow += stepx) + { + png_byte alpha = inrow[1]; + + if (alpha > 0) /* else no change to the output */ + { + png_uint_32 component = inrow[0]; + + if (alpha < 255) /* else just use component */ + { + /* Since PNG_OPTIMIZED_ALPHA was not set it is + * necessary to invert the sRGB transfer + * function and multiply the alpha out. + */ + component = png_sRGB_table[component] * alpha; + component += png_sRGB_table[outrow[0]] * + (255-alpha); + component = PNG_sRGB_FROM_LINEAR(component); + } + + outrow[0] = (png_byte)component; + } + + inrow += 2; /* gray and alpha channel */ + } + } + } + + else /* constant background value */ + { + png_byte background8 = display->background->green; + png_uint_16 background = png_sRGB_table[background8]; + + for (; ylocal_row); + png_bytep outrow = first_row + y * row_step; + png_const_bytep row_end = outrow + width; + + /* Read the row, which is packed: */ + png_read_row(png_ptr, inrow, NULL); + + /* Now do the composition on each pixel in this row. */ + outrow += startx; + for (; outrow < row_end; outrow += stepx) + { + png_byte alpha = inrow[1]; + + if (alpha > 0) /* else use background */ + { + png_uint_32 component = inrow[0]; + + if (alpha < 255) /* else just use component */ + { + component = png_sRGB_table[component] * alpha; + component += background * (255-alpha); + component = PNG_sRGB_FROM_LINEAR(component); + } + + outrow[0] = (png_byte)component; + } + + else + outrow[0] = background8; + + inrow += 2; /* gray and alpha channel */ + } + } + } + } + } + break; + + case 16: + /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must + * still be done and, maybe, the alpha channel removed. This code also + * handles the alpha-first option. + */ + { + png_uint_16p first_row = png_voidcast(png_uint_16p, + display->first_row); + /* The division by two is safe because the caller passed in a + * stride which was multiplied by 2 (below) to get row_step. + */ + ptrdiff_t row_step = display->row_step / 2; + unsigned int preserve_alpha = (image->format & + PNG_FORMAT_FLAG_ALPHA) != 0; + unsigned int outchannels = 1U+preserve_alpha; + int swap_alpha = 0; + +# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED + if (preserve_alpha != 0 && + (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + swap_alpha = 1; +# endif + + for (pass = 0; pass < passes; ++pass) + { + unsigned int startx, stepx, stepy; + png_uint_32 y; + + /* The 'x' start and step are adjusted to output components here. + */ + if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) + { + /* The row may be empty for a short image: */ + if (PNG_PASS_COLS(width, pass) == 0) + continue; + + startx = PNG_PASS_START_COL(pass) * outchannels; + stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; + y = PNG_PASS_START_ROW(pass); + stepy = PNG_PASS_ROW_OFFSET(pass); + } + + else + { + y = 0; + startx = 0; + stepx = outchannels; + stepy = 1; + } + + for (; ylocal_row), NULL); + inrow = png_voidcast(png_const_uint_16p, display->local_row); + + /* Now do the pre-multiplication on each pixel in this row. + */ + outrow += startx; + for (; outrow < row_end; outrow += stepx) + { + png_uint_32 component = inrow[0]; + png_uint_16 alpha = inrow[1]; + + if (alpha > 0) /* else 0 */ + { + if (alpha < 65535) /* else just use component */ + { + component *= alpha; + component += 32767; + component /= 65535; + } + } + + else + component = 0; + + outrow[swap_alpha] = (png_uint_16)component; + if (preserve_alpha != 0) + outrow[1 ^ swap_alpha] = alpha; + + inrow += 2; /* components and alpha channel */ + } + } + } + } + break; + +#ifdef __GNUC__ + default: + png_error(png_ptr, "unexpected bit depth"); +#endif + } + + return 1; +} + +/* The guts of png_image_finish_read as a png_safe_execute callback. */ +static int +png_image_read_direct(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + + png_uint_32 format = image->format; + int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; + int do_local_compose = 0; + int do_local_background = 0; /* to avoid double gamma correction bug */ + int do_local_scale = 0; /* for interlaced 16-to-8 bit conversion */ + int passes = 0; + + /* Add transforms to ensure the correct output format is produced then check + * that the required implementation support is there. Always expand; always + * need 8 bits minimum, no palette and expanded tRNS. + */ + png_set_expand(png_ptr); + + /* Now check the format to see if it was modified. */ + { + png_uint_32 base_format = png_image_format(png_ptr) & + ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; + png_uint_32 change = format ^ base_format; + png_fixed_point output_gamma; + int mode; /* alpha mode */ + + /* Do this first so that we have a record if rgb to gray is happening. */ + if ((change & PNG_FORMAT_FLAG_COLOR) != 0) + { + /* gray<->color transformation required. */ + if ((format & PNG_FORMAT_FLAG_COLOR) != 0) + png_set_gray_to_rgb(png_ptr); + + else + { + /* libpng can't do both rgb to gray and + * background/pre-multiplication if there is also significant gamma + * correction, because both operations require linear colors and + * the code only supports one transform doing the gamma correction. + * Handle this by doing the pre-multiplication or background + * operation in this code, if necessary. + * + * TODO: fix this by rewriting pngrtran.c (!) + * + * For the moment (given that fixing this in pngrtran.c is an + * enormous change) 'do_local_background' is used to indicate that + * the problem exists. + */ + if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) + do_local_background = 1/*maybe*/; + + png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, + PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); + } + + change &= ~PNG_FORMAT_FLAG_COLOR; + } + + /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. + */ + { + /* This is safe but should no longer be necessary as + * png_ptr->default_gamma should have been set after the + * info-before-IDAT was read in png_image_read_header. + * + * TODO: 1.8: remove this and see what happens. + */ + png_fixed_point input_gamma_default; + + if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && + (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) + input_gamma_default = PNG_GAMMA_LINEAR; + else + input_gamma_default = PNG_DEFAULT_sRGB; + + /* Call png_set_alpha_mode to set the default for the input gamma; the + * output gamma is set by a second call below. + */ + png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); + } + + if (linear != 0) + { + /* If there *is* an alpha channel in the input it must be multiplied + * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. + */ + if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) + mode = PNG_ALPHA_STANDARD; /* associated alpha */ + + else + mode = PNG_ALPHA_PNG; + + output_gamma = PNG_GAMMA_LINEAR; + } + + else + { + mode = PNG_ALPHA_PNG; + output_gamma = PNG_DEFAULT_sRGB; + } + + if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) + { + mode = PNG_ALPHA_OPTIMIZED; + change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + + /* If 'do_local_background' is set check for the presence of gamma + * correction; this is part of the work-round for the libpng bug + * described above. + * + * TODO: fix libpng and remove this. + */ + if (do_local_background != 0) + { + png_fixed_point gtest; + + /* This is 'png_gamma_threshold' from pngrtran.c; the test used for + * gamma correction, the screen gamma hasn't been set on png_struct + * yet; it's set below. png_struct::gamma, however, is set to the + * final value. + */ + if (png_muldiv(>est, output_gamma, + png_resolve_file_gamma(png_ptr), PNG_FP_1) != 0 && + png_gamma_significant(gtest) == 0) + do_local_background = 0; + + else if (mode == PNG_ALPHA_STANDARD) + { + do_local_background = 2/*required*/; + mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ + } + + /* else leave as 1 for the checks below */ + } + + /* If the bit-depth changes then handle that here. */ + if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) + { + if (linear != 0 /*16-bit output*/) + png_set_expand_16(png_ptr); + + else /* 8-bit output */ + { + png_set_scale_16(png_ptr); + + /* For interlaced images, use local_row buffer to avoid overflow + * in png_combine_row() which writes using IHDR bit-depth. + */ + if (png_ptr->interlaced != 0) + do_local_scale = 1; + } + + change &= ~PNG_FORMAT_FLAG_LINEAR; + } + + /* Now the background/alpha channel changes. */ + if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) + { + /* Removing an alpha channel requires composition for the 8-bit + * formats; for the 16-bit it is already done, above, by the + * pre-multiplication and the channel just needs to be stripped. + */ + if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + /* If RGB->gray is happening the alpha channel must be left and the + * operation completed locally. + * + * TODO: fix libpng and remove this. + */ + if (do_local_background != 0) + do_local_background = 2/*required*/; + + /* 16-bit output: just remove the channel */ + else if (linear != 0) /* compose on black (well, pre-multiply) */ + png_set_strip_alpha(png_ptr); + + /* 8-bit output: do an appropriate compose */ + else if (display->background != NULL) + { + png_color_16 c; + + c.index = 0; /*unused*/ + c.red = display->background->red; + c.green = display->background->green; + c.blue = display->background->blue; + c.gray = display->background->green; + + /* This is always an 8-bit sRGB value, using the 'green' channel + * for gray is much better than calculating the luminance here; + * we can get off-by-one errors in that calculation relative to + * the app expectations and that will show up in transparent + * pixels. + */ + png_set_background_fixed(png_ptr, &c, + PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, + 0/*gamma: not used*/); + } + + else /* compose on row: implemented below. */ + { + do_local_compose = 1; + /* This leaves the alpha channel in the output, so it has to be + * removed by the code below. Set the encoding to the 'OPTIMIZE' + * one so the code only has to hack on the pixels that require + * composition. + */ + mode = PNG_ALPHA_OPTIMIZED; + } + } + + else /* output needs an alpha channel */ + { + /* This is tricky because it happens before the swap operation has + * been accomplished; however, the swap does *not* swap the added + * alpha channel (weird API), so it must be added in the correct + * place. + */ + png_uint_32 filler; /* opaque filler */ + int where; + + if (linear != 0) + filler = 65535; + + else + filler = 255; + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED + if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + where = PNG_FILLER_BEFORE; + change &= ~PNG_FORMAT_FLAG_AFIRST; + } + + else +#endif + where = PNG_FILLER_AFTER; + + png_set_add_alpha(png_ptr, filler, where); + } + + /* This stops the (irrelevant) call to swap_alpha below. */ + change &= ~PNG_FORMAT_FLAG_ALPHA; + } + + /* Now set the alpha mode correctly; this is always done, even if there is + * no alpha channel in either the input or the output because it correctly + * sets the output gamma. + */ + png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); + +# ifdef PNG_FORMAT_BGR_SUPPORTED + if ((change & PNG_FORMAT_FLAG_BGR) != 0) + { + /* Check only the output format; PNG is never BGR; don't do this if + * the output is gray, but fix up the 'format' value in that case. + */ + if ((format & PNG_FORMAT_FLAG_COLOR) != 0) + png_set_bgr(png_ptr); + + else + format &= ~PNG_FORMAT_FLAG_BGR; + + change &= ~PNG_FORMAT_FLAG_BGR; + } +# endif + +# ifdef PNG_FORMAT_AFIRST_SUPPORTED + if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) + { + /* Only relevant if there is an alpha channel - it's particularly + * important to handle this correctly because do_local_compose may + * be set above and then libpng will keep the alpha channel for this + * code to remove. + */ + if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + /* Disable this if doing a local background, + * TODO: remove this when local background is no longer required. + */ + if (do_local_background != 2) + png_set_swap_alpha(png_ptr); + } + + else + format &= ~PNG_FORMAT_FLAG_AFIRST; + + change &= ~PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* If the *output* is 16-bit then we need to check for a byte-swap on this + * architecture. + */ + if (linear != 0) + { + png_uint_16 le = 0x0001; + + if ((*(png_const_bytep) & le) != 0) + png_set_swap(png_ptr); + } + + /* If change is not now 0 some transformation is missing - error out. */ + if (change != 0) + png_error(png_ptr, "png_read_image: unsupported transformation"); + } + + PNG_SKIP_CHUNKS(png_ptr); + + /* Update the 'info' structure and make sure the result is as required; first + * make sure to turn on the interlace handling if it will be required + * (because it can't be turned on *after* the call to png_read_update_info!) + * + * TODO: remove the do_local_background fixup below. + */ + if (do_local_compose == 0 && do_local_background != 2) + passes = png_set_interlace_handling(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + + { + png_uint_32 info_format = 0; + + if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + info_format |= PNG_FORMAT_FLAG_COLOR; + + if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + /* do_local_compose removes this channel below. */ + if (do_local_compose == 0) + { + /* do_local_background does the same if required. */ + if (do_local_background != 2 || + (format & PNG_FORMAT_FLAG_ALPHA) != 0) + info_format |= PNG_FORMAT_FLAG_ALPHA; + } + } + + else if (do_local_compose != 0) /* internal error */ + png_error(png_ptr, "png_image_read: alpha channel lost"); + + if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { + info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; + } + + if (info_ptr->bit_depth == 16) + info_format |= PNG_FORMAT_FLAG_LINEAR; + +#ifdef PNG_FORMAT_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + info_format |= PNG_FORMAT_FLAG_BGR; +#endif + +#ifdef PNG_FORMAT_AFIRST_SUPPORTED + if (do_local_background == 2) + { + if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) + info_format |= PNG_FORMAT_FLAG_AFIRST; + } + + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || + ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && + (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) + { + if (do_local_background == 2) + png_error(png_ptr, "unexpected alpha swap transformation"); + + info_format |= PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* This is actually an internal error. */ + if (info_format != format) + png_error(png_ptr, "png_read_image: invalid transformations"); + } + + /* Now read the rows. If do_local_compose is set then it is necessary to use + * a local row buffer. The output will be GA, RGBA or BGRA and must be + * converted to G, RGB or BGR as appropriate. The 'local_row' member of the + * display acts as a flag. + */ + { + png_voidp first_row = display->buffer; + ptrdiff_t row_step = display->row_stride; + + if (linear != 0) + row_step *= 2; + + /* The following adjustment is to ensure that calculations are correct, + * regardless whether row_step is positive or negative. + */ + if (row_step < 0) + { + char *ptr = png_voidcast(char*, first_row); + ptr += (image->height - 1) * (-row_step); + first_row = png_voidcast(png_voidp, ptr); + } + + display->first_row = first_row; + display->row_step = row_step; + } + + if (do_local_compose != 0) + { + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_composite, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else if (do_local_background == 2) + { + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_background, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else if (do_local_scale != 0) + { + /* For interlaced 16-to-8 conversion, use an intermediate row buffer + * to avoid buffer overflows in png_combine_row. The local_row is sized + * for the transformed (8-bit) output, preventing the overflow that would + * occur if png_combine_row wrote 16-bit data directly to the user buffer. + */ + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_direct_scaled, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + + else + { + ptrdiff_t row_step = display->row_step; + + while (--passes >= 0) + { + png_uint_32 y = image->height; + png_bytep row = png_voidcast(png_bytep, display->first_row); + + for (; y > 0; --y) + { + png_read_row(png_ptr, row, NULL); + row += row_step; + } + } + + return 1; + } +} + +int PNGAPI +png_image_finish_read(png_imagep image, png_const_colorp background, + void *buffer, png_int_32 row_stride, void *colormap) +{ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + /* Check for row_stride overflow. This check is not performed on the + * original PNG format because it may not occur in the output PNG format + * and libpng deals with the issues of reading the original. + */ + unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + + /* The following checks just the 'row_stride' calculation to ensure it + * fits in a signed 32-bit value. Because channels/components can be + * either 1 or 2 bytes in size the length of a row can still overflow 32 + * bits; this is just to verify that the 'row_stride' argument can be + * represented. + */ + if (image->width <= 0x7fffffffU/channels) /* no overflow */ + { + png_uint_32 check; + png_uint_32 png_row_stride = image->width * channels; + + if (row_stride == 0) + row_stride = (png_int_32)/*SAFE*/png_row_stride; + + if (row_stride < 0) + check = -(png_uint_32)row_stride; + + else + check = (png_uint_32)row_stride; + + /* This verifies 'check', the absolute value of the actual stride + * passed in and detects overflow in the application calculation (i.e. + * if the app did actually pass in a non-zero 'row_stride'. + */ + if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) + { + /* Now check for overflow of the image buffer calculation; this + * limits the whole image size to 32 bits for API compatibility with + * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. + * + * The PNG_IMAGE_BUFFER_SIZE macro is: + * + * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) + * + * And the component size is always 1 or 2, so make sure that the + * number of *bytes* that the application is saying are available + * does actually fit into a 32-bit number. + * + * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE + * will be changed to use png_alloc_size_t; bigger images can be + * accommodated on 64-bit systems. + */ + if (image->height <= + 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) + { + if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || + (image->colormap_entries > 0 && colormap != NULL)) + { + int result; + png_image_read_control display; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.background = background; + display.local_row = NULL; + + /* Choose the correct 'end' routine; for the color-map case + * all the setup has already been done. + */ + if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) + result = + png_safe_execute(image, + png_image_read_colormap, &display) && + png_safe_execute(image, + png_image_read_colormapped, &display); + + else + result = + png_safe_execute(image, + png_image_read_direct, &display); + + png_image_free(image); + return result; + } + + else + return png_image_error(image, + "png_image_finish_read[color-map]: no color-map"); + } + + else + return png_image_error(image, + "png_image_finish_read: image too large"); + } + + else + return png_image_error(image, + "png_image_finish_read: invalid argument"); + } + + else + return png_image_error(image, + "png_image_finish_read: row_stride too large"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_finish_read: damaged PNG_IMAGE_VERSION"); + + return 0; +} + +#endif /* SIMPLIFIED_READ */ +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/pngrio.c b/thirdparty/libpng/upstream/pngrio.c index 7d30c7a51..b4a216161 100644 --- a/thirdparty/libpng/upstream/pngrio.c +++ b/thirdparty/libpng/upstream/pngrio.c @@ -1,120 +1,119 @@ - -/* pngrio.c - functions for data input - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all input. Users who need - * special handling are expected to write a function that has the same - * arguments as this and performs a similar function, but that possibly - * has a different input method. Note that you shouldn't change this - * function, but rather write a replacement function and then make - * libpng use it at run time with png_set_read_fn(...). - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* Read the data from whatever input you are using. The default routine - * reads from a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered reads. This should never be asked - * to read more than 64K on a 16-bit machine. - */ -void /* PRIVATE */ -png_read_data(png_structrp png_ptr, png_bytep data, size_t length) -{ - png_debug1(4, "reading %d bytes", (int)length); - - if (png_ptr->read_data_fn != NULL) - (*(png_ptr->read_data_fn))(png_ptr, data, length); - - else - png_error(png_ptr, "Call to NULL read function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ -void PNGCBAPI -png_default_read_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check; - - if (png_ptr == NULL) - return; - - /* fread() returns 0 on error, so it is OK to store this in a size_t - * instead of an int, which is what fread() actually returns. - */ - check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Read Error"); -} -#endif - -/* This function allows the application to supply a new input function - * for libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * - * png_ptr - pointer to a png input data structure - * - * io_ptr - pointer to user supplied structure containing info about - * the input functions. May be NULL. - * - * read_data_fn - pointer to a new input function that takes as its - * arguments a pointer to a png_struct, a pointer to - * a location where input data can be stored, and a 32-bit - * unsigned int that is the number of bytes to be read. - * To exit and output any fatal error messages the new write - * function should call png_error(png_ptr, "Error msg"). - * May be NULL, in which case libpng's default function will - * be used. - */ -void PNGAPI -png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - -#ifdef PNG_STDIO_SUPPORTED - if (read_data_fn != NULL) - png_ptr->read_data_fn = read_data_fn; - - else - png_ptr->read_data_fn = png_default_read_data; -#else - png_ptr->read_data_fn = read_data_fn; -#endif - -#ifdef PNG_WRITE_SUPPORTED - /* It is an error to write to a read device */ - if (png_ptr->write_data_fn != NULL) - { - png_ptr->write_data_fn = NULL; - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->output_flush_fn = NULL; -#endif -} -#endif /* READ */ +/* pngrio.c - functions for data input + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all input. Users who need + * special handling are expected to write a function that has the same + * arguments as this and performs a similar function, but that possibly + * has a different input method. Note that you shouldn't change this + * function, but rather write a replacement function and then make + * libpng use it at run time with png_set_read_fn(...). + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* Read the data from whatever input you are using. The default routine + * reads from a file pointer. Note that this routine sometimes gets called + * with very small lengths, so you should implement some kind of simple + * buffering if you are using unbuffered reads. This should never be asked + * to read more than 64K on a 16-bit machine. + */ +void /* PRIVATE */ +png_read_data(png_structrp png_ptr, png_bytep data, size_t length) +{ + png_debug1(4, "reading %d bytes", (int)length); + + if (png_ptr->read_data_fn != NULL) + (*(png_ptr->read_data_fn))(png_ptr, data, length); + + else + png_error(png_ptr, "Call to NULL read function"); +} + +#ifdef PNG_STDIO_SUPPORTED +/* This is the function that does the actual reading of data. If you are + * not reading from a standard C stream, you should create a replacement + * read_data function and use it at run time with png_set_read_fn(), rather + * than changing the library. + */ +void PNGCBAPI +png_default_read_data(png_structp png_ptr, png_bytep data, size_t length) +{ + size_t check; + + if (png_ptr == NULL) + return; + + /* fread() returns 0 on error, so it is OK to store this in a size_t + * instead of an int, which is what fread() actually returns. + */ + check = fread(data, 1, length, png_voidcast(FILE *, png_ptr->io_ptr)); + + if (check != length) + png_error(png_ptr, "Read Error"); +} +#endif + +/* This function allows the application to supply a new input function + * for libpng if standard C streams aren't being used. + * + * This function takes as its arguments: + * + * png_ptr - pointer to a png input data structure + * + * io_ptr - pointer to user supplied structure containing info about + * the input functions. May be NULL. + * + * read_data_fn - pointer to a new input function that takes as its + * arguments a pointer to a png_struct, a pointer to + * a location where input data can be stored, and a 32-bit + * unsigned int that is the number of bytes to be read. + * To exit and output any fatal error messages the new write + * function should call png_error(png_ptr, "Error msg"). + * May be NULL, in which case libpng's default function will + * be used. + */ +void PNGAPI +png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = io_ptr; + +#ifdef PNG_STDIO_SUPPORTED + if (read_data_fn != NULL) + png_ptr->read_data_fn = read_data_fn; + + else + png_ptr->read_data_fn = png_default_read_data; +#else + png_ptr->read_data_fn = read_data_fn; +#endif + +#ifdef PNG_WRITE_SUPPORTED + /* It is an error to write to a read device */ + if (png_ptr->write_data_fn != NULL) + { + png_ptr->write_data_fn = NULL; + png_warning(png_ptr, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = NULL; +#endif +} +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/pngrtran.c b/thirdparty/libpng/upstream/pngrtran.c index 6e54dfe14..0ac8df749 100644 --- a/thirdparty/libpng/upstream/pngrtran.c +++ b/thirdparty/libpng/upstream/pngrtran.c @@ -1,5040 +1,5179 @@ - -/* pngrtran.c - transforms the data in a row for PNG readers - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains functions optionally called by an application - * in order to tell libpng how to handle data when reading a PNG. - * Transformations that are used in both reading and writing are - * in pngtrans.c. - */ - -#include "pngpriv.h" - -#ifdef PNG_ARM_NEON_IMPLEMENTATION -# if PNG_ARM_NEON_IMPLEMENTATION == 1 -# define PNG_ARM_NEON_INTRINSICS_AVAILABLE -# if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) -# include -# else -# include -# endif -# endif -#endif - -#ifdef PNG_READ_SUPPORTED - -/* Set the action on getting a CRC error for an ancillary or critical chunk. */ -void PNGAPI -png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) -{ - png_debug(1, "in png_set_crc_action"); - - if (png_ptr == NULL) - return; - - /* Tell libpng how we react to CRC errors in critical chunks */ - switch (crit_action) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | - PNG_FLAG_CRC_CRITICAL_IGNORE; - break; - - case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ - png_warning(png_ptr, - "Can't discard critical data on CRC error"); - /* FALLTHROUGH */ - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - - case PNG_CRC_DEFAULT: - default: - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - break; - } - - /* Tell libpng how we react to CRC errors in ancillary chunks */ - switch (ancil_action) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | - PNG_FLAG_CRC_ANCILLARY_NOWARN; - break; - - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; - break; - - case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ - - case PNG_CRC_DEFAULT: - default: - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - break; - } -} - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -/* Is it OK to set a transformation now? Only if png_start_read_image or - * png_read_update_info have not been called. It is not necessary for the IHDR - * to have been read in all cases; the need_IHDR parameter allows for this - * check too. - */ -static int -png_rtran_ok(png_structrp png_ptr, int need_IHDR) -{ - if (png_ptr != NULL) - { - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) - png_app_error(png_ptr, - "invalid after png_start_read_image or png_read_update_info"); - - else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_app_error(png_ptr, "invalid before the PNG header has been read"); - - else - { - /* Turn on failure to initialize correctly for all transforms. */ - png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; - - return 1; /* Ok */ - } - } - - return 0; /* no png_error possible! */ -} -#endif - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS via a background color */ -void PNGFAPI -png_set_background_fixed(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma) -{ - png_debug(1, "in png_set_background_fixed"); - - if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) - return; - - if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) - { - png_warning(png_ptr, "Application must supply a known background gamma"); - return; - } - - png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - png_ptr->background = *background_color; - png_ptr->background_gamma = background_gamma; - png_ptr->background_gamma_type = (png_byte)(background_gamma_code); - if (need_expand != 0) - png_ptr->transformations |= PNG_BACKGROUND_EXPAND; - else - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_background(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) -{ - png_set_background_fixed(png_ptr, background_color, background_gamma_code, - need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); -} -# endif /* FLOATING_POINT */ -#endif /* READ_BACKGROUND */ - -/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the - * one that pngrtran does first (scale) happens. This is necessary to allow the - * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. - */ -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -void PNGAPI -png_set_scale_16(png_structrp png_ptr) -{ - png_debug(1, "in png_set_scale_16"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_SCALE_16_TO_8; -} -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -/* Chop 16-bit depth files to 8-bit depth */ -void PNGAPI -png_set_strip_16(png_structrp png_ptr) -{ - png_debug(1, "in png_set_strip_16"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_16_TO_8; -} -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -void PNGAPI -png_set_strip_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_strip_alpha"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_STRIP_ALPHA; -} -#endif - -#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) -static png_fixed_point -translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, - int is_screen) -{ - /* Check for flag values. The main reason for having the old Mac value as a - * flag is that it is pretty near impossible to work out what the correct - * value is from Apple documentation - a working Mac system is needed to - * discover the value! - */ - if (output_gamma == PNG_DEFAULT_sRGB || - output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) - { - /* If there is no sRGB support this just sets the gamma to the standard - * sRGB value. (This is a side effect of using this function!) - */ -# ifdef PNG_READ_sRGB_SUPPORTED - png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; -# else - PNG_UNUSED(png_ptr) -# endif - if (is_screen != 0) - output_gamma = PNG_GAMMA_sRGB; - else - output_gamma = PNG_GAMMA_sRGB_INVERSE; - } - - else if (output_gamma == PNG_GAMMA_MAC_18 || - output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) - { - if (is_screen != 0) - output_gamma = PNG_GAMMA_MAC_OLD; - else - output_gamma = PNG_GAMMA_MAC_INVERSE; - } - - return output_gamma; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -static png_fixed_point -convert_gamma_value(png_structrp png_ptr, double output_gamma) -{ - /* The following silently ignores cases where fixed point (times 100,000) - * gamma values are passed to the floating point API. This is safe and it - * means the fixed point constants work just fine with the floating point - * API. The alternative would just lead to undetected errors and spurious - * bug reports. Negative values fail inside the _fixed API unless they - * correspond to the flag values. - */ - if (output_gamma > 0 && output_gamma < 128) - output_gamma *= PNG_FP_1; - - /* This preserves -1 and -2 exactly: */ - output_gamma = floor(output_gamma + .5); - - if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) - png_fixed_error(png_ptr, "gamma value"); - - return (png_fixed_point)output_gamma; -} -# endif -#endif /* READ_ALPHA_MODE || READ_GAMMA */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -void PNGFAPI -png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, - png_fixed_point output_gamma) -{ - int compose = 0; - png_fixed_point file_gamma; - - png_debug(1, "in png_set_alpha_mode_fixed"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - - /* Validate the value to ensure it is in a reasonable range. The value - * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out the API users - * who might use the inverse of the gamma value accidentally! - * - * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate - * the optimal 16-bit gamma of 36 and its reciprocal. - */ - if (output_gamma < 1000 || output_gamma > 10000000) - png_error(png_ptr, "output gamma out of expected range"); - - /* The default file gamma is the inverse of the output gamma; the output - * gamma may be changed below so get the file value first: - */ - file_gamma = png_reciprocal(output_gamma); - - /* There are really 8 possibilities here, composed of any combination - * of: - * - * premultiply the color channels - * do not encode non-opaque pixels - * encode the alpha as well as the color channels - * - * The differences disappear if the input/output ('screen') gamma is 1.0, - * because then the encoding is a no-op and there is only the choice of - * premultiplying the color channels or not. - * - * png_set_alpha_mode and png_set_background interact because both use - * png_compose to do the work. Calling both is only useful when - * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along - * with a default gamma value. Otherwise PNG_COMPOSE must not be set. - */ - switch (mode) - { - case PNG_ALPHA_PNG: /* default: png standard */ - /* No compose, but it may be set by png_set_background! */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - break; - - case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ - compose = 1; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - /* The output is linear: */ - output_gamma = PNG_FP_1; - break; - - case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ - compose = 1; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; - /* output_gamma records the encoding of opaque pixels! */ - break; - - case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ - compose = 1; - png_ptr->transformations |= PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - break; - - default: - png_error(png_ptr, "invalid alpha mode"); - } - - /* Only set the default gamma if the file gamma has not been set (this has - * the side effect that the gamma in a second call to png_set_alpha_mode will - * be ignored.) - */ - if (png_ptr->colorspace.gamma == 0) - { - png_ptr->colorspace.gamma = file_gamma; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* But always set the output gamma: */ - png_ptr->screen_gamma = output_gamma; - - /* Finally, if pre-multiplying, set the background fields to achieve the - * desired result. - */ - if (compose != 0) - { - /* And obtain alpha pre-multiplication by composing on black: */ - memset(&png_ptr->background, 0, (sizeof png_ptr->background)); - png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; - - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_error(png_ptr, - "conflicting calls to set alpha mode and background"); - - png_ptr->transformations |= PNG_COMPOSE; - } -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) -{ - png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, - output_gamma)); -} -# endif -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Dither file to 8-bit. Supply a palette, the current number - * of elements in the palette, the maximum number of elements - * allowed, and a histogram if possible. If the current number - * of colors is greater than the maximum number, the palette will be - * modified to fit in the maximum number. "full_quantize" indicates - * whether we need a quantizing cube set up for RGB images, or if we - * simply are reducing the number of colors in a paletted image. - */ - -typedef struct png_dsort_struct -{ - struct png_dsort_struct * next; - png_byte left; - png_byte right; -} png_dsort; -typedef png_dsort * png_dsortp; -typedef png_dsort * * png_dsortpp; - -void PNGAPI -png_set_quantize(png_structrp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_const_uint_16p histogram, - int full_quantize) -{ - png_debug(1, "in png_set_quantize"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_QUANTIZE; - - if (full_quantize == 0) - { - int i; - - png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)num_palette); - for (i = 0; i < num_palette; i++) - png_ptr->quantize_index[i] = (png_byte)i; - } - - if (num_palette > maximum_colors) - { - if (histogram != NULL) - { - /* This is easy enough, just throw out the least used colors. - * Perhaps not the best solution, but good enough. - */ - - int i; - - /* Initialize an array to sort colors */ - png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)num_palette); - - /* Initialize the quantize_sort array */ - for (i = 0; i < num_palette; i++) - png_ptr->quantize_sort[i] = (png_byte)i; - - /* Find the least used palette entries by starting a - * bubble sort, and running it until we have sorted - * out enough colors. Note that we don't care about - * sorting all the colors, just finding which are - * least used. - */ - - for (i = num_palette - 1; i >= maximum_colors; i--) - { - int done; /* To stop early if the list is pre-sorted */ - int j; - - done = 1; - for (j = 0; j < i; j++) - { - if (histogram[png_ptr->quantize_sort[j]] - < histogram[png_ptr->quantize_sort[j + 1]]) - { - png_byte t; - - t = png_ptr->quantize_sort[j]; - png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; - png_ptr->quantize_sort[j + 1] = t; - done = 0; - } - } - - if (done != 0) - break; - } - - /* Swap the palette around, and set up a table, if necessary */ - if (full_quantize != 0) - { - int j = num_palette; - - /* Put all the useful colors within the max, but don't - * move the others. - */ - for (i = 0; i < maximum_colors; i++) - { - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) - { - do - j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); - - palette[i] = palette[j]; - } - } - } - else - { - int j = num_palette; - - /* Move all the used colors inside the max limit, and - * develop a translation table. - */ - for (i = 0; i < maximum_colors; i++) - { - /* Only move the colors we need to */ - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) - { - png_color tmp_color; - - do - j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); - - tmp_color = palette[j]; - palette[j] = palette[i]; - palette[i] = tmp_color; - /* Indicate where the color went */ - png_ptr->quantize_index[j] = (png_byte)i; - png_ptr->quantize_index[i] = (png_byte)j; - } - } - - /* Find closest color for those colors we are not using */ - for (i = 0; i < num_palette; i++) - { - if ((int)png_ptr->quantize_index[i] >= maximum_colors) - { - int min_d, k, min_k, d_index; - - /* Find the closest color to one we threw out */ - d_index = png_ptr->quantize_index[i]; - min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); - for (k = 1, min_k = 0; k < maximum_colors; k++) - { - int d; - - d = PNG_COLOR_DIST(palette[d_index], palette[k]); - - if (d < min_d) - { - min_d = d; - min_k = k; - } - } - /* Point to closest color */ - png_ptr->quantize_index[i] = (png_byte)min_k; - } - } - } - png_free(png_ptr, png_ptr->quantize_sort); - png_ptr->quantize_sort = NULL; - } - else - { - /* This is much harder to do simply (and quickly). Perhaps - * we need to go through a median cut routine, but those - * don't always behave themselves with only a few colors - * as input. So we will just find the closest two colors, - * and throw out one of them (chosen somewhat randomly). - * [We don't understand this at all, so if someone wants to - * work on improving it, be our guest - AED, GRP] - */ - int i; - int max_d; - int num_new_palette; - png_dsortp t; - png_dsortpp hash; - - t = NULL; - - /* Initialize palette index arrays */ - png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)num_palette); - png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)num_palette); - - /* Initialize the sort array */ - for (i = 0; i < num_palette; i++) - { - png_ptr->index_to_palette[i] = (png_byte)i; - png_ptr->palette_to_index[i] = (png_byte)i; - } - - hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 * - (sizeof (png_dsortp)))); - - num_new_palette = num_palette; - - /* Initial wild guess at how far apart the farthest pixel - * pair we will be eliminating will be. Larger - * numbers mean more areas will be allocated, Smaller - * numbers run the risk of not saving enough data, and - * having to do this all over again. - * - * I have not done extensive checking on this number. - */ - max_d = 96; - - while (num_new_palette > maximum_colors) - { - for (i = 0; i < num_new_palette - 1; i++) - { - int j; - - for (j = i + 1; j < num_new_palette; j++) - { - int d; - - d = PNG_COLOR_DIST(palette[i], palette[j]); - - if (d <= max_d) - { - - t = (png_dsortp)png_malloc_warn(png_ptr, - (png_alloc_size_t)(sizeof (png_dsort))); - - if (t == NULL) - break; - - t->next = hash[d]; - t->left = (png_byte)i; - t->right = (png_byte)j; - hash[d] = t; - } - } - if (t == NULL) - break; - } - - if (t != NULL) - for (i = 0; i <= max_d; i++) - { - if (hash[i] != NULL) - { - png_dsortp p; - - for (p = hash[i]; p; p = p->next) - { - if ((int)png_ptr->index_to_palette[p->left] - < num_new_palette && - (int)png_ptr->index_to_palette[p->right] - < num_new_palette) - { - int j, next_j; - - if (num_new_palette & 0x01) - { - j = p->left; - next_j = p->right; - } - else - { - j = p->right; - next_j = p->left; - } - - num_new_palette--; - palette[png_ptr->index_to_palette[j]] - = palette[num_new_palette]; - if (full_quantize == 0) - { - int k; - - for (k = 0; k < num_palette; k++) - { - if (png_ptr->quantize_index[k] == - png_ptr->index_to_palette[j]) - png_ptr->quantize_index[k] = - png_ptr->index_to_palette[next_j]; - - if ((int)png_ptr->quantize_index[k] == - num_new_palette) - png_ptr->quantize_index[k] = - png_ptr->index_to_palette[j]; - } - } - - png_ptr->index_to_palette[png_ptr->palette_to_index - [num_new_palette]] = png_ptr->index_to_palette[j]; - - png_ptr->palette_to_index[png_ptr->index_to_palette[j]] - = png_ptr->palette_to_index[num_new_palette]; - - png_ptr->index_to_palette[j] = - (png_byte)num_new_palette; - - png_ptr->palette_to_index[num_new_palette] = - (png_byte)j; - } - if (num_new_palette <= maximum_colors) - break; - } - if (num_new_palette <= maximum_colors) - break; - } - } - - for (i = 0; i < 769; i++) - { - if (hash[i] != NULL) - { - png_dsortp p = hash[i]; - while (p) - { - t = p->next; - png_free(png_ptr, p); - p = t; - } - } - hash[i] = 0; - } - max_d += 96; - } - png_free(png_ptr, hash); - png_free(png_ptr, png_ptr->palette_to_index); - png_free(png_ptr, png_ptr->index_to_palette); - png_ptr->palette_to_index = NULL; - png_ptr->index_to_palette = NULL; - } - num_palette = maximum_colors; - } - if (png_ptr->palette == NULL) - { - png_ptr->palette = palette; - } - png_ptr->num_palette = (png_uint_16)num_palette; - - if (full_quantize != 0) - { - int i; - png_bytep distance; - int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + - PNG_QUANTIZE_BLUE_BITS; - int num_red = (1 << PNG_QUANTIZE_RED_BITS); - int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); - int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); - size_t num_entries = ((size_t)1 << total_bits); - - png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)(num_entries)); - - distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries); - - memset(distance, 0xff, num_entries); - - for (i = 0; i < num_palette; i++) - { - int ir, ig, ib; - int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); - int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); - int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); - - for (ir = 0; ir < num_red; ir++) - { - /* int dr = abs(ir - r); */ - int dr = ((ir > r) ? ir - r : r - ir); - int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + - PNG_QUANTIZE_GREEN_BITS)); - - for (ig = 0; ig < num_green; ig++) - { - /* int dg = abs(ig - g); */ - int dg = ((ig > g) ? ig - g : g - ig); - int dt = dr + dg; - int dm = ((dr > dg) ? dr : dg); - int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); - - for (ib = 0; ib < num_blue; ib++) - { - int d_index = index_g | ib; - /* int db = abs(ib - b); */ - int db = ((ib > b) ? ib - b : b - ib); - int dmax = ((dm > db) ? dm : db); - int d = dmax + dt + db; - - if (d < (int)distance[d_index]) - { - distance[d_index] = (png_byte)d; - png_ptr->palette_lookup[d_index] = (png_byte)i; - } - } - } - } - } - - png_free(png_ptr, distance); - } -} -#endif /* READ_QUANTIZE */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -void PNGFAPI -png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, - png_fixed_point file_gamma) -{ - png_debug(1, "in png_set_gamma_fixed"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - /* New in libpng-1.5.4 - reserve particular negative values as flags. */ - scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); - file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); - - /* Checking the gamma values for being >0 was added in 1.5.4 along with the - * premultiplied alpha support; this actually hides an undocumented feature - * of the previous implementation which allowed gamma processing to be - * disabled in background handling. There is no evidence (so far) that this - * was being used; however, png_set_background itself accepted and must still - * accept '0' for the gamma value it takes, because it isn't always used. - * - * Since this is an API change (albeit a very minor one that removes an - * undocumented API feature) the following checks were only enabled in - * libpng-1.6.0. - */ - if (file_gamma <= 0) - png_error(png_ptr, "invalid file gamma in png_set_gamma"); - - if (scrn_gamma <= 0) - png_error(png_ptr, "invalid screen gamma in png_set_gamma"); - - /* Set the gamma values unconditionally - this overrides the value in the PNG - * file if a gAMA chunk was present. png_set_alpha_mode provides a - * different, easier, way to default the file gamma. - */ - png_ptr->colorspace.gamma = file_gamma; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - png_ptr->screen_gamma = scrn_gamma; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) -{ - png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), - convert_gamma_value(png_ptr, file_gamma)); -} -# endif /* FLOATING_POINT */ -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand paletted images to RGB, expand grayscale images of - * less than 8-bit depth to 8-bit depth, and expand tRNS chunks - * to alpha channels. - */ -void PNGAPI -png_set_expand(png_structrp png_ptr) -{ - png_debug(1, "in png_set_expand"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -} - -/* GRR 19990627: the following three functions currently are identical - * to png_set_expand(). However, it is entirely reasonable that someone - * might wish to expand an indexed image to RGB but *not* expand a single, - * fully transparent palette entry to a full alpha channel--perhaps instead - * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace - * the transparent color with a particular RGB value, or drop tRNS entirely. - * IOW, a future version of the library may make the transformations flag - * a bit more fine-grained, with separate bits for each of these three - * functions. - * - * More to the point, these functions make it obvious what libpng will be - * doing, whereas "expand" can (and does) mean any number of things. - * - * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified - * to expand only the sample depth but not to expand the tRNS to alpha - * and its name was changed to png_set_expand_gray_1_2_4_to_8(). - */ - -/* Expand paletted images to RGB. */ -void PNGAPI -png_set_palette_to_rgb(png_structrp png_ptr) -{ - png_debug(1, "in png_set_palette_to_rgb"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -} - -/* Expand grayscale images of less than 8-bit depth to 8 bits. */ -void PNGAPI -png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) -{ - png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_EXPAND; -} - -/* Expand tRNS chunks to alpha channels. */ -void PNGAPI -png_set_tRNS_to_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_tRNS_to_alpha"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -} -#endif /* READ_EXPAND */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise - * it may not work correctly.) - */ -void PNGAPI -png_set_expand_16(png_structrp png_ptr) -{ - png_debug(1, "in png_set_expand_16"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); -} -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -void PNGAPI -png_set_gray_to_rgb(png_structrp png_ptr) -{ - png_debug(1, "in png_set_gray_to_rgb"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - /* Because rgb must be 8 bits or more: */ - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_ptr->transformations |= PNG_GRAY_TO_RGB; -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void PNGFAPI -png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, - png_fixed_point red, png_fixed_point green) -{ - png_debug(1, "in png_set_rgb_to_gray_fixed"); - - /* Need the IHDR here because of the check on color_type below. */ - /* TODO: fix this */ - if (png_rtran_ok(png_ptr, 1) == 0) - return; - - switch (error_action) - { - case PNG_ERROR_ACTION_NONE: - png_ptr->transformations |= PNG_RGB_TO_GRAY; - break; - - case PNG_ERROR_ACTION_WARN: - png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; - break; - - case PNG_ERROR_ACTION_ERROR: - png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; - break; - - default: - png_error(png_ptr, "invalid error action to rgb_to_gray"); - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#ifdef PNG_READ_EXPAND_SUPPORTED - png_ptr->transformations |= PNG_EXPAND; -#else - { - /* Make this an error in 1.6 because otherwise the application may assume - * that it just worked and get a memory overwrite. - */ - png_error(png_ptr, - "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); - - /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ - } -#endif - { - if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) - { - png_uint_16 red_int, green_int; - - /* NOTE: this calculation does not round, but this behavior is retained - * for consistency; the inaccuracy is very small. The code here always - * overwrites the coefficients, regardless of whether they have been - * defaulted or set already. - */ - red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); - green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); - - png_ptr->rgb_to_gray_red_coeff = red_int; - png_ptr->rgb_to_gray_green_coeff = green_int; - png_ptr->rgb_to_gray_coefficients_set = 1; - } - - else - { - if (red >= 0 && green >= 0) - png_app_warning(png_ptr, - "ignoring out of range rgb_to_gray coefficients"); - - /* Use the defaults, from the cHRM chunk if set, else the historical - * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See - * png_do_rgb_to_gray for more discussion of the values. In this case - * the coefficients are not marked as 'set' and are not overwritten if - * something has already provided a default. - */ - if (png_ptr->rgb_to_gray_red_coeff == 0 && - png_ptr->rgb_to_gray_green_coeff == 0) - { - png_ptr->rgb_to_gray_red_coeff = 6968; - png_ptr->rgb_to_gray_green_coeff = 23434; - /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ - } - } - } -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* Convert a RGB image to a grayscale of the same width. This allows us, - * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. - */ - -void PNGAPI -png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, - double green) -{ - png_set_rgb_to_gray_fixed(png_ptr, error_action, - png_fixed(png_ptr, red, "rgb to gray red coefficient"), - png_fixed(png_ptr, green, "rgb to gray green coefficient")); -} -#endif /* FLOATING POINT */ - -#endif /* RGB_TO_GRAY */ - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -void PNGAPI -png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - read_user_transform_fn) -{ - png_debug(1, "in png_set_read_user_transform_fn"); - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->read_user_transform_fn = read_user_transform_fn; -#endif -} -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED -/* In the case of gamma transformations only do transformations on images where - * the [file] gamma and screen_gamma are not close reciprocals, otherwise it - * slows things down slightly, and also needlessly introduces small errors. - */ -static int /* PRIVATE */ -png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) -{ - /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma - * correction as a difference of the overall transform from 1.0 - * - * We want to compare the threshold with s*f - 1, if we get - * overflow here it is because of wacky gamma values so we - * turn on processing anyway. - */ - png_fixed_point gtest; - return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || - png_gamma_significant(gtest); -} -#endif - -/* Initialize everything needed for the read. This includes modifying - * the palette. - */ - -/* For the moment 'png_init_palette_transformations' and - * 'png_init_rgb_transformations' only do some flag canceling optimizations. - * The intent is that these two routines should have palette or rgb operations - * extracted from 'png_init_read_transformations'. - */ -static void /* PRIVATE */ -png_init_palette_transformations(png_structrp png_ptr) -{ - /* Called to handle the (input) palette case. In png_do_read_transformations - * the first step is to expand the palette if requested, so this code must - * take care to only make changes that are invariant with respect to the - * palette expansion, or only do them if there is no expansion. - * - * STRIP_ALPHA has already been handled in the caller (by setting num_trans - * to 0.) - */ - int input_has_alpha = 0; - int input_has_transparency = 0; - - if (png_ptr->num_trans > 0) - { - int i; - - /* Ignore if all the entries are opaque (unlikely!) */ - for (i=0; inum_trans; ++i) - { - if (png_ptr->trans_alpha[i] == 255) - continue; - else if (png_ptr->trans_alpha[i] == 0) - input_has_transparency = 1; - else - { - input_has_transparency = 1; - input_has_alpha = 1; - break; - } - } - } - - /* If no alpha we can optimize. */ - if (input_has_alpha == 0) - { - /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - if (input_has_transparency == 0) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && - (png_ptr->transformations & PNG_EXPAND) != 0) - { - { - png_ptr->background.red = - png_ptr->palette[png_ptr->background.index].red; - png_ptr->background.green = - png_ptr->palette[png_ptr->background.index].green; - png_ptr->background.blue = - png_ptr->palette[png_ptr->background.index].blue; - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - { - if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) - { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later - */ - int i, istop = png_ptr->num_trans; - - for (i = 0; i < istop; i++) - png_ptr->trans_alpha[i] = - (png_byte)(255 - png_ptr->trans_alpha[i]); - } - } -#endif /* READ_INVERT_ALPHA */ - } - } /* background expand and (therefore) no alpha association. */ -#endif /* READ_EXPAND && READ_BACKGROUND */ -} - -static void /* PRIVATE */ -png_init_rgb_transformations(png_structrp png_ptr) -{ - /* Added to libpng-1.5.4: check the color type to determine whether there - * is any alpha or transparency in the image and simply cancel the - * background and alpha mode stuff if there isn't. - */ - int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; - int input_has_transparency = png_ptr->num_trans > 0; - - /* If no alpha we can optimize. */ - if (input_has_alpha == 0) - { - /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ -# ifdef PNG_READ_ALPHA_MODE_SUPPORTED - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; -# endif - - if (input_has_transparency == 0) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && - (png_ptr->transformations & PNG_EXPAND) != 0 && - (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - /* i.e., GRAY or GRAY_ALPHA */ - { - { - /* Expand background and tRNS chunks */ - int gray = png_ptr->background.gray; - int trans_gray = png_ptr->trans_color.gray; - - switch (png_ptr->bit_depth) - { - case 1: - gray *= 0xff; - trans_gray *= 0xff; - break; - - case 2: - gray *= 0x55; - trans_gray *= 0x55; - break; - - case 4: - gray *= 0x11; - trans_gray *= 0x11; - break; - - default: - - case 8: - /* FALLTHROUGH */ /* (Already 8 bits) */ - - case 16: - /* Already a full 16 bits */ - break; - } - - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = (png_uint_16)gray; - - if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) - { - png_ptr->trans_color.red = png_ptr->trans_color.green = - png_ptr->trans_color.blue = (png_uint_16)trans_gray; - } - } - } /* background expand and (therefore) no alpha association. */ -#endif /* READ_EXPAND && READ_BACKGROUND */ -} - -void /* PRIVATE */ -png_init_read_transformations(png_structrp png_ptr) -{ - png_debug(1, "in png_init_read_transformations"); - - /* This internal function is called from png_read_start_row in pngrutil.c - * and it is called before the 'rowbytes' calculation is done, so the code - * in here can change or update the transformations flags. - * - * First do updates that do not depend on the details of the PNG image data - * being processed. - */ - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds - * png_set_alpha_mode and this is another source for a default file gamma so - * the test needs to be performed later - here. In addition prior to 1.5.4 - * the tests were repeated for the PALETTE color type here - this is no - * longer necessary (and doesn't seem to have been necessary before.) - */ - { - /* The following temporary indicates if overall gamma correction is - * required. - */ - int gamma_correction = 0; - - if (png_ptr->colorspace.gamma != 0) /* has been set */ - { - if (png_ptr->screen_gamma != 0) /* screen set too */ - gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - - else - /* Assume the output matches the input; a long time default behavior - * of libpng, although the standard has nothing to say about this. - */ - png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); - } - - else if (png_ptr->screen_gamma != 0) - /* The converse - assume the file matches the screen, note that this - * perhaps undesirable default can (from 1.5.4) be changed by calling - * png_set_alpha_mode (even if the alpha handling mode isn't required - * or isn't changed from the default.) - */ - png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); - - else /* neither are set */ - /* Just in case the following prevents any processing - file and screen - * are both assumed to be linear and there is no way to introduce a - * third gamma value other than png_set_background with 'UNIQUE', and, - * prior to 1.5.4 - */ - png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; - - /* We have a gamma value now. */ - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Now turn the gamma transformation on or off as appropriate. Notice - * that PNG_GAMMA just refers to the file->screen correction. Alpha - * composition may independently cause gamma correction because it needs - * linear data (e.g. if the file has a gAMA chunk but the screen gamma - * hasn't been specified.) In any case this flag may get turned off in - * the code immediately below if the transform can be handled outside the - * row loop. - */ - if (gamma_correction != 0) - png_ptr->transformations |= PNG_GAMMA; - - else - png_ptr->transformations &= ~PNG_GAMMA; - } -#endif - - /* Certain transformations have the effect of preventing other - * transformations that happen afterward in png_do_read_transformations; - * resolve the interdependencies here. From the code of - * png_do_read_transformations the order is: - * - * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) - * 2) PNG_STRIP_ALPHA (if no compose) - * 3) PNG_RGB_TO_GRAY - * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY - * 5) PNG_COMPOSE - * 6) PNG_GAMMA - * 7) PNG_STRIP_ALPHA (if compose) - * 8) PNG_ENCODE_ALPHA - * 9) PNG_SCALE_16_TO_8 - * 10) PNG_16_TO_8 - * 11) PNG_QUANTIZE (converts to palette) - * 12) PNG_EXPAND_16 - * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY - * 14) PNG_INVERT_MONO - * 15) PNG_INVERT_ALPHA - * 16) PNG_SHIFT - * 17) PNG_PACK - * 18) PNG_BGR - * 19) PNG_PACKSWAP - * 20) PNG_FILLER (includes PNG_ADD_ALPHA) - * 21) PNG_SWAP_ALPHA - * 22) PNG_SWAP_BYTES - * 23) PNG_USER_TRANSFORM [must be last] - */ -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && - (png_ptr->transformations & PNG_COMPOSE) == 0) - { - /* Stripping the alpha channel happens immediately after the 'expand' - * transformations, before all other transformation, so it cancels out - * the alpha handling. It has the side effect negating the effect of - * PNG_EXPAND_tRNS too: - */ - png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | - PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen - * so transparency information would remain just so long as it wasn't - * expanded. This produces unexpected API changes if the set of things - * that do PNG_EXPAND_tRNS changes (perfectly possible given the - * documentation - which says ask for what you want, accept what you - * get.) This makes the behavior consistent from 1.5.4: - */ - png_ptr->num_trans = 0; - } -#endif /* STRIP_ALPHA supported, no COMPOSE */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA - * settings will have no effect. - */ - if (png_gamma_significant(png_ptr->screen_gamma) == 0) - { - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - } -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Make sure the coefficients for the rgb to gray conversion are set - * appropriately. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - png_colorspace_set_rgb_coefficients(png_ptr); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* Detect gray background and attempt to enable optimization for - * gray --> RGB case. - * - * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or - * RGB_ALPHA (in which case need_expand is superfluous anyway), the - * background color might actually be gray yet not be flagged as such. - * This is not a problem for the current code, which uses - * PNG_BACKGROUND_IS_GRAY only to decide when to do the - * png_do_gray_to_rgb() transformation. - * - * TODO: this code needs to be revised to avoid the complexity and - * interdependencies. The color type of the background should be recorded in - * png_set_background, along with the bit depth, then the code has a record - * of exactly what color space the background is currently in. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) - { - /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if - * the file was grayscale the background value is gray. - */ - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - } - - else if ((png_ptr->transformations & PNG_COMPOSE) != 0) - { - /* PNG_COMPOSE: png_set_background was called with need_expand false, - * so the color is in the color space of the output or png_set_alpha_mode - * was called and the color is black. Ignore RGB_TO_GRAY because that - * happens before GRAY_TO_RGB. - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - { - if (png_ptr->background.red == png_ptr->background.green && - png_ptr->background.red == png_ptr->background.blue) - { - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - png_ptr->background.gray = png_ptr->background.red; - } - } - } -#endif /* READ_EXPAND && READ_BACKGROUND */ -#endif /* READ_GRAY_TO_RGB */ - - /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations - * can be performed directly on the palette, and some (such as rgb to gray) - * can be optimized inside the palette. This is particularly true of the - * composite (background and alpha) stuff, which can be pretty much all done - * in the palette even if the result is expanded to RGB or gray afterward. - * - * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and - * earlier and the palette stuff is actually handled on the first row. This - * leads to the reported bug that the palette returned by png_get_PLTE is not - * updated. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_init_palette_transformations(png_ptr); - - else - png_init_rgb_transformations(png_ptr); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_EXPAND_16_SUPPORTED) - if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && - (png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && - png_ptr->bit_depth != 16) - { - /* TODO: fix this. Because the expand_16 operation is after the compose - * handling the background color must be 8, not 16, bits deep, but the - * application will supply a 16-bit value so reduce it here. - * - * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at - * present, so that case is ok (until do_expand_16 is moved.) - * - * NOTE: this discards the low 16 bits of the user supplied background - * color, but until expand_16 works properly there is no choice! - */ -# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) - CHOP(png_ptr->background.red); - CHOP(png_ptr->background.green); - CHOP(png_ptr->background.blue); - CHOP(png_ptr->background.gray); -# undef CHOP - } -#endif /* READ_BACKGROUND && READ_EXPAND_16 */ - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ - defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) - if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && - (png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && - png_ptr->bit_depth == 16) - { - /* On the other hand, if a 16-bit file is to be reduced to 8-bits per - * component this will also happen after PNG_COMPOSE and so the background - * color must be pre-expanded here. - * - * TODO: fix this too. - */ - png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); - png_ptr->background.green = - (png_uint_16)(png_ptr->background.green * 257); - png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); - png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); - } -#endif - - /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the - * background support (see the comments in scripts/pnglibconf.dfa), this - * allows pre-multiplication of the alpha channel to be implemented as - * compositing on black. This is probably sub-optimal and has been done in - * 1.5.4 betas simply to enable external critique and testing (i.e. to - * implement the new API quickly, without lots of internal changes.) - */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -# ifdef PNG_READ_BACKGROUND_SUPPORTED - /* Includes ALPHA_MODE */ - png_ptr->background_1 = png_ptr->background; -# endif - - /* This needs to change - in the palette image case a whole set of tables are - * built when it would be quicker to just calculate the correct value for - * each palette entry directly. Also, the test is too tricky - why check - * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that - * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the - * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction - * the gamma tables will not be built even if composition is required on a - * gamma encoded value. - * - * In 1.5.4 this is addressed below by an additional check on the individual - * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the - * tables. - */ - if ((png_ptr->transformations & PNG_GAMMA) != 0 || - ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && - (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || - png_gamma_significant(png_ptr->screen_gamma) != 0)) || - ((png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || - png_gamma_significant(png_ptr->screen_gamma) != 0 -# ifdef PNG_READ_BACKGROUND_SUPPORTED - || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && - png_gamma_significant(png_ptr->background_gamma) != 0) -# endif - )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && - png_gamma_significant(png_ptr->screen_gamma) != 0)) - { - png_build_gamma_table(png_ptr, png_ptr->bit_depth); - -#ifdef PNG_READ_BACKGROUND_SUPPORTED - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - { - /* Issue a warning about this combination: because RGB_TO_GRAY is - * optimized to do the gamma transform if present yet do_background has - * to do the same thing if both options are set a - * double-gamma-correction happens. This is true in all versions of - * libpng to date. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - png_warning(png_ptr, - "libpng does not support gamma+background+rgb_to_gray"); - - if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) - { - /* We don't get to here unless there is a tRNS chunk with non-opaque - * entries - see the checking code at the start of this function. - */ - png_color back, back_1; - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) - { - - back.red = png_ptr->gamma_table[png_ptr->background.red]; - back.green = png_ptr->gamma_table[png_ptr->background.green]; - back.blue = png_ptr->gamma_table[png_ptr->background.blue]; - - back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; - back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; - back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; - } - else - { - png_fixed_point g, gs; - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = (png_ptr->screen_gamma); - gs = PNG_FP_1; - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - default: - g = PNG_FP_1; /* back_1 */ - gs = PNG_FP_1; /* back */ - break; - } - - if (png_gamma_significant(gs) != 0) - { - back.red = png_gamma_8bit_correct(png_ptr->background.red, - gs); - back.green = png_gamma_8bit_correct(png_ptr->background.green, - gs); - back.blue = png_gamma_8bit_correct(png_ptr->background.blue, - gs); - } - - else - { - back.red = (png_byte)png_ptr->background.red; - back.green = (png_byte)png_ptr->background.green; - back.blue = (png_byte)png_ptr->background.blue; - } - - if (png_gamma_significant(g) != 0) - { - back_1.red = png_gamma_8bit_correct(png_ptr->background.red, - g); - back_1.green = png_gamma_8bit_correct( - png_ptr->background.green, g); - back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, - g); - } - - else - { - back_1.red = (png_byte)png_ptr->background.red; - back_1.green = (png_byte)png_ptr->background.green; - back_1.blue = (png_byte)png_ptr->background.blue; - } - } - - for (i = 0; i < num_palette; i++) - { - if (i < (int)png_ptr->num_trans && - png_ptr->trans_alpha[i] != 0xff) - { - if (png_ptr->trans_alpha[i] == 0) - { - palette[i] = back; - } - else /* if (png_ptr->trans_alpha[i] != 0xff) */ - { - png_byte v, w; - - v = png_ptr->gamma_to_1[palette[i].red]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); - palette[i].red = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].green]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); - palette[i].green = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].blue]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); - palette[i].blue = png_ptr->gamma_from_1[w]; - } - } - else - { - palette[i].red = png_ptr->gamma_table[palette[i].red]; - palette[i].green = png_ptr->gamma_table[palette[i].green]; - palette[i].blue = png_ptr->gamma_table[palette[i].blue]; - } - } - - /* Prevent the transformations being done again. - * - * NOTE: this is highly dubious; it removes the transformations in - * place. This seems inconsistent with the general treatment of the - * transformations elsewhere. - */ - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); - } /* color_type == PNG_COLOR_TYPE_PALETTE */ - - /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ - else /* color_type != PNG_COLOR_TYPE_PALETTE */ - { - int gs_sig, g_sig; - png_fixed_point g = PNG_FP_1; /* Correction to linear */ - png_fixed_point gs = PNG_FP_1; /* Correction to screen */ - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = png_ptr->screen_gamma; - /* gs = PNG_FP_1; */ - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - - default: - png_error(png_ptr, "invalid background gamma type"); - } - - g_sig = png_gamma_significant(g); - gs_sig = png_gamma_significant(gs); - - if (g_sig != 0) - png_ptr->background_1.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, g); - - if (gs_sig != 0) - png_ptr->background.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, gs); - - if ((png_ptr->background.red != png_ptr->background.green) || - (png_ptr->background.red != png_ptr->background.blue) || - (png_ptr->background.red != png_ptr->background.gray)) - { - /* RGB or RGBA with color background */ - if (g_sig != 0) - { - png_ptr->background_1.red = png_gamma_correct(png_ptr, - png_ptr->background.red, g); - - png_ptr->background_1.green = png_gamma_correct(png_ptr, - png_ptr->background.green, g); - - png_ptr->background_1.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, g); - } - - if (gs_sig != 0) - { - png_ptr->background.red = png_gamma_correct(png_ptr, - png_ptr->background.red, gs); - - png_ptr->background.green = png_gamma_correct(png_ptr, - png_ptr->background.green, gs); - - png_ptr->background.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, gs); - } - } - - else - { - /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ - png_ptr->background_1.red = png_ptr->background_1.green - = png_ptr->background_1.blue = png_ptr->background_1.gray; - - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - } - - /* The background is now in screen gamma: */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; - } /* color_type != PNG_COLOR_TYPE_PALETTE */ - }/* png_ptr->transformations & PNG_BACKGROUND */ - - else - /* Transformation does not include PNG_BACKGROUND */ -#endif /* READ_BACKGROUND */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ - && ((png_ptr->transformations & PNG_EXPAND) == 0 || - (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) -#endif - ) - { - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - - /* NOTE: there are other transformations that should probably be in - * here too. - */ - for (i = 0; i < num_palette; i++) - { - palette[i].red = png_ptr->gamma_table[palette[i].red]; - palette[i].green = png_ptr->gamma_table[palette[i].green]; - palette[i].blue = png_ptr->gamma_table[palette[i].blue]; - } - - /* Done the gamma correction. */ - png_ptr->transformations &= ~PNG_GAMMA; - } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ - } -#ifdef PNG_READ_BACKGROUND_SUPPORTED - else -#endif -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_BACKGROUND_SUPPORTED - /* No GAMMA transformation (see the hanging else 4 lines above) */ - if ((png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; - int istop = (int)png_ptr->num_trans; - png_color back; - png_colorp palette = png_ptr->palette; - - back.red = (png_byte)png_ptr->background.red; - back.green = (png_byte)png_ptr->background.green; - back.blue = (png_byte)png_ptr->background.blue; - - for (i = 0; i < istop; i++) - { - if (png_ptr->trans_alpha[i] == 0) - { - palette[i] = back; - } - - else if (png_ptr->trans_alpha[i] != 0xff) - { - /* The png_composite() macro is defined in png.h */ - png_composite(palette[i].red, palette[i].red, - png_ptr->trans_alpha[i], back.red); - - png_composite(palette[i].green, palette[i].green, - png_ptr->trans_alpha[i], back.green); - - png_composite(palette[i].blue, palette[i].blue, - png_ptr->trans_alpha[i], back.blue); - } - } - - png_ptr->transformations &= ~PNG_COMPOSE; - } -#endif /* READ_BACKGROUND */ - -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) != 0 && - (png_ptr->transformations & PNG_EXPAND) == 0 && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; - int istop = png_ptr->num_palette; - int shift = 8 - png_ptr->sig_bit.red; - - png_ptr->transformations &= ~PNG_SHIFT; - - /* significant bits can be in the range 1 to 7 for a meaningful result, if - * the number of significant bits is 0 then no shift is done (this is an - * error condition which is silently ignored.) - */ - if (shift > 0 && shift < 8) - for (i=0; ipalette[i].red; - - component >>= shift; - png_ptr->palette[i].red = (png_byte)component; - } - - shift = 8 - png_ptr->sig_bit.green; - if (shift > 0 && shift < 8) - for (i=0; ipalette[i].green; - - component >>= shift; - png_ptr->palette[i].green = (png_byte)component; - } - - shift = 8 - png_ptr->sig_bit.blue; - if (shift > 0 && shift < 8) - for (i=0; ipalette[i].blue; - - component >>= shift; - png_ptr->palette[i].blue = (png_byte)component; - } - } -#endif /* READ_SHIFT */ -} - -/* Modify the info structure to reflect the transformations. The - * info should be updated so a PNG file could be written with it, - * assuming the transformations result in valid PNG data. - */ -void /* PRIVATE */ -png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_transform_info"); - -#ifdef PNG_READ_EXPAND_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - /* This check must match what actually happens in - * png_do_expand_palette; if it ever checks the tRNS chunk to see if - * it is all opaque we must do the same (at present it does not.) - */ - if (png_ptr->num_trans > 0) - info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - - else - info_ptr->color_type = PNG_COLOR_TYPE_RGB; - - info_ptr->bit_depth = 8; - info_ptr->num_trans = 0; - - if (png_ptr->palette == NULL) - png_error (png_ptr, "Palette is NULL in indexed image"); - } - else - { - if (png_ptr->num_trans != 0) - { - if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } - if (info_ptr->bit_depth < 8) - info_ptr->bit_depth = 8; - - info_ptr->num_trans = 0; - } - } -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* The following is almost certainly wrong unless the background value is in - * the screen space! - */ - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - info_ptr->background = png_ptr->background; -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), - * however it seems that the code in png_init_read_transformations, which has - * been called before this from png_read_update_info->png_read_start_row - * sometimes does the gamma transform and cancels the flag. - * - * TODO: this looks wrong; the info_ptr should end up with a gamma equal to - * the screen_gamma value. The following probably results in weirdness if - * the info_ptr is used by the app after the rows have been read. - */ - info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; -#endif - - if (info_ptr->bit_depth == 16) - { -# ifdef PNG_READ_16BIT_SUPPORTED -# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) - info_ptr->bit_depth = 8; -# endif - -# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - if ((png_ptr->transformations & PNG_16_TO_8) != 0) - info_ptr->bit_depth = 8; -# endif - -# else - /* No 16-bit support: force chopping 16-bit input down to 8, in this case - * the app program can chose if both APIs are available by setting the - * correct scaling to use. - */ -# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* For compatibility with previous versions use the strip method by - * default. This code works because if PNG_SCALE_16_TO_8 is already - * set the code below will do that in preference to the chop. - */ - png_ptr->transformations |= PNG_16_TO_8; - info_ptr->bit_depth = 8; -# else - -# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_ptr->transformations |= PNG_SCALE_16_TO_8; - info_ptr->bit_depth = 8; -# else - - CONFIGURATION ERROR: you must enable at least one 16 to 8 method -# endif -# endif -#endif /* !READ_16BIT */ - } - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - info_ptr->color_type = (png_byte)(info_ptr->color_type | - PNG_COLOR_MASK_COLOR); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - info_ptr->color_type = (png_byte)(info_ptr->color_type & - ~PNG_COLOR_MASK_COLOR); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if ((png_ptr->transformations & PNG_QUANTIZE) != 0) - { - if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) - { - info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; - } - } -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && - info_ptr->bit_depth == 8 && - info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - info_ptr->bit_depth = 16; - } -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0 && - (info_ptr->bit_depth < 8)) - info_ptr->bit_depth = 8; -#endif - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - - else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) - { - info_ptr->color_type = (png_byte)(info_ptr->color_type & - ~PNG_COLOR_MASK_ALPHA); - info_ptr->num_trans = 0; - } -#endif - - if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - info_ptr->channels++; - -#ifdef PNG_READ_FILLER_SUPPORTED - /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ - if ((png_ptr->transformations & PNG_FILLER) != 0 && - (info_ptr->color_type == PNG_COLOR_TYPE_RGB || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) - { - info_ptr->channels++; - /* If adding a true alpha channel not just filler */ - if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } -#endif - -#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ -defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - if (png_ptr->user_transform_depth != 0) - info_ptr->bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels != 0) - info_ptr->channels = png_ptr->user_transform_channels; - } -#endif - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * - info_ptr->bit_depth); - - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); - - /* Adding in 1.5.4: cache the above value in png_struct so that we can later - * check in png_rowbytes that the user buffer won't get overwritten. Note - * that the field is not always set - if png_read_update_info isn't called - * the application has to either not do any transforms or get the calculation - * right itself. - */ - png_ptr->info_rowbytes = info_ptr->rowbytes; - -#ifndef PNG_READ_EXPAND_SUPPORTED - if (png_ptr != NULL) - return; -#endif -} - -#ifdef PNG_READ_PACK_SUPPORTED -/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, - * without changing the actual values. Thus, if you had a row with - * a bit depth of 1, you would end up with bytes that only contained - * the numbers 0 or 1. If you would rather they contain 0 and 255, use - * png_do_shift() after this. - */ -static void -png_do_unpack(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_unpack"); - - if (row_info->bit_depth < 8) - { - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - switch (row_info->bit_depth) - { - case 1: - { - png_bytep sp = row + (size_t)((row_width - 1) >> 3); - png_bytep dp = row + (size_t)row_width - 1; - png_uint_32 shift = 7U - ((row_width + 7U) & 0x07); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x01); - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - - png_bytep sp = row + (size_t)((row_width - 1) >> 2); - png_bytep dp = row + (size_t)row_width - 1; - png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x03); - - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - png_bytep sp = row + (size_t)((row_width - 1) >> 1); - png_bytep dp = row + (size_t)row_width - 1; - png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x0f); - - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED -/* Reverse the effects of png_do_shift. This routine merely shifts the - * pixels back to their significant bits values. Thus, if you have - * a row of bit depth 8, but only 5 are significant, this will shift - * the values back to 0 through 31. - */ -static void -png_do_unshift(png_row_infop row_info, png_bytep row, - png_const_color_8p sig_bits) -{ - int color_type; - - png_debug(1, "in png_do_unshift"); - - /* The palette case has already been handled in the _init routine. */ - color_type = row_info->color_type; - - if (color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift[4]; - int channels = 0; - int bit_depth = row_info->bit_depth; - - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - shift[channels++] = bit_depth - sig_bits->red; - shift[channels++] = bit_depth - sig_bits->green; - shift[channels++] = bit_depth - sig_bits->blue; - } - - else - { - shift[channels++] = bit_depth - sig_bits->gray; - } - - if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - shift[channels++] = bit_depth - sig_bits->alpha; - } - - { - int c, have_shift; - - for (c = have_shift = 0; c < channels; ++c) - { - /* A shift of more than the bit depth is an error condition but it - * gets ignored here. - */ - if (shift[c] <= 0 || shift[c] >= bit_depth) - shift[c] = 0; - - else - have_shift = 1; - } - - if (have_shift == 0) - return; - } - - switch (bit_depth) - { - default: - /* Must be 1bpp gray: should not be here! */ - /* NOTREACHED */ - break; - - case 2: - /* Must be 2bpp gray */ - /* assert(channels == 1 && shift[0] == 1) */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - - while (bp < bp_end) - { - int b = (*bp >> 1) & 0x55; - *bp++ = (png_byte)b; - } - break; - } - - case 4: - /* Must be 4bpp gray */ - /* assert(channels == 1) */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int gray_shift = shift[0]; - int mask = 0xf >> gray_shift; - - mask |= mask << 4; - - while (bp < bp_end) - { - int b = (*bp >> gray_shift) & mask; - *bp++ = (png_byte)b; - } - break; - } - - case 8: - /* Single byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int channel = 0; - - while (bp < bp_end) - { - int b = *bp >> shift[channel]; - if (++channel >= channels) - channel = 0; - *bp++ = (png_byte)b; - } - break; - } - -#ifdef PNG_READ_16BIT_SUPPORTED - case 16: - /* Double byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int channel = 0; - - while (bp < bp_end) - { - int value = (bp[0] << 8) + bp[1]; - - value >>= shift[channel]; - if (++channel >= channels) - channel = 0; - *bp++ = (png_byte)(value >> 8); - *bp++ = (png_byte)value; - } - break; - } -#endif - } - } -} -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale rows of bit depth 16 down to 8 accurately */ -static void -png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_scale_16_to_8"); - - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ - png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) - { - /* The input is an array of 16-bit components, these must be scaled to - * 8 bits each. For a 16-bit value V the required value (from the PNG - * specification) is: - * - * (V * 255) / 65535 - * - * This reduces to round(V / 257), or floor((V + 128.5)/257) - * - * Represent V as the two byte value vhi.vlo. Make a guess that the - * result is the top byte of V, vhi, then the correction to this value - * is: - * - * error = floor(((V-vhi.vhi) + 128.5) / 257) - * = floor(((vlo-vhi) + 128.5) / 257) - * - * This can be approximated using integer arithmetic (and a signed - * shift): - * - * error = (vlo-vhi+128) >> 8; - * - * The approximate differs from the exact answer only when (vlo-vhi) is - * 128; it then gives a correction of +1 when the exact correction is - * 0. This gives 128 errors. The exact answer (correct for all 16-bit - * input values) is: - * - * error = (vlo-vhi+128)*65535 >> 24; - * - * An alternative arithmetic calculation which also gives no errors is: - * - * (V * 255 + 32895) >> 16 - */ - - png_int_32 tmp = *sp++; /* must be signed! */ - tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; - *dp++ = (png_byte)tmp; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_info->width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -static void -/* Simply discard the low byte. This was the default behavior prior - * to libpng-1.5.4. - */ -png_do_chop(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_chop"); - - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ - png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) - { - *dp++ = *sp; - sp += 2; /* skip low byte */ - } - - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_info->width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -static void -png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) -{ - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_read_swap_alpha"); - - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - /* This converts from RGBA to ARGB */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from RRGGBBAA to AARRGGBB */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - /* This converts from GA to AG */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from GGAA to AAGG */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif - } -} -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -static void -png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) -{ - png_uint_32 row_width; - png_debug(1, "in png_do_read_invert_alpha"); - - row_width = row_info->width; - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in RGBA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=3; - dp=sp; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This inverts the alpha channel in RRGGBBAA */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=6; - dp=sp; - } - } -#endif - } - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in GA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = *(--sp); - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in GGAA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); -/* - *(--dp) = *(--sp); - *(--dp) = *(--sp); -*/ - sp-=2; - dp=sp; - } - } -#endif - } -} -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED -/* Add filler channel if we have RGB color */ -static void -png_do_read_filler(png_row_infop row_info, png_bytep row, - png_uint_32 filler, png_uint_32 flags) -{ - png_uint_32 i; - png_uint_32 row_width = row_info->width; - -#ifdef PNG_READ_16BIT_SUPPORTED - png_byte hi_filler = (png_byte)(filler>>8); -#endif - png_byte lo_filler = (png_byte)filler; - - png_debug(1, "in png_do_read_filler"); - - if ( - row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - if (row_info->bit_depth == 8) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from G to GX */ - png_bytep sp = row + (size_t)row_width; - png_bytep dp = sp + (size_t)row_width; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - row_info->channels = 2; - row_info->pixel_depth = 16; - row_info->rowbytes = row_width * 2; - } - - else - { - /* This changes the data from G to XG */ - png_bytep sp = row + (size_t)row_width; - png_bytep dp = sp + (size_t)row_width; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = lo_filler; - } - row_info->channels = 2; - row_info->pixel_depth = 16; - row_info->rowbytes = row_width * 2; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from GG to GGXX */ - png_bytep sp = row + (size_t)row_width * 2; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = hi_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - *(--dp) = hi_filler; - row_info->channels = 2; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - - else - { - /* This changes the data from GG to XXGG */ - png_bytep sp = row + (size_t)row_width * 2; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - *(--dp) = hi_filler; - } - row_info->channels = 2; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - } -#endif - } /* COLOR_TYPE == GRAY */ - else if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - if (row_info->bit_depth == 8) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from RGB to RGBX */ - png_bytep sp = row + (size_t)row_width * 3; - png_bytep dp = sp + (size_t)row_width; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - - else - { - /* This changes the data from RGB to XRGB */ - png_bytep sp = row + (size_t)row_width * 3; - png_bytep dp = sp + (size_t)row_width; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - } - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from RRGGBB to RRGGBBXX */ - png_bytep sp = row + (size_t)row_width * 6; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = hi_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - *(--dp) = hi_filler; - row_info->channels = 4; - row_info->pixel_depth = 64; - row_info->rowbytes = row_width * 8; - } - - else - { - /* This changes the data from RRGGBB to XXRRGGBB */ - png_bytep sp = row + (size_t)row_width * 6; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - *(--dp) = hi_filler; - } - - row_info->channels = 4; - row_info->pixel_depth = 64; - row_info->rowbytes = row_width * 8; - } - } -#endif - } /* COLOR_TYPE == RGB */ -} -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand grayscale files to RGB, with or without alpha */ -static void -png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) -{ - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_gray_to_rgb"); - - if (row_info->bit_depth >= 8 && - (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - if (row_info->bit_depth == 8) - { - /* This changes G to RGB */ - png_bytep sp = row + (size_t)row_width - 1; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(dp--) = *sp; - *(dp--) = *sp; - *(dp--) = *(sp--); - } - } - - else - { - /* This changes GG to RRGGBB */ - png_bytep sp = row + (size_t)row_width * 2 - 1; - png_bytep dp = sp + (size_t)row_width * 4; - for (i = 0; i < row_width; i++) - { - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *(sp--); - *(dp--) = *(sp--); - } - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This changes GA to RGBA */ - png_bytep sp = row + (size_t)row_width * 2 - 1; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(dp--) = *(sp--); - *(dp--) = *sp; - *(dp--) = *sp; - *(dp--) = *(sp--); - } - } - - else - { - /* This changes GGAA to RRGGBBAA */ - png_bytep sp = row + (size_t)row_width * 4 - 1; - png_bytep dp = sp + (size_t)row_width * 4; - for (i = 0; i < row_width; i++) - { - *(dp--) = *(sp--); - *(dp--) = *(sp--); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *(sp--); - *(dp--) = *(sp--); - } - } - } - row_info->channels = (png_byte)(row_info->channels + 2); - row_info->color_type |= PNG_COLOR_MASK_COLOR; - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB files to grayscale, with or without alpha - * using the equation given in Poynton's ColorFAQ of 1998-01-04 at - * (THIS LINK IS DEAD June 2008 but - * versions dated 1998 through November 2002 have been archived at - * https://web.archive.org/web/20000816232553/www.inforamp.net/ - * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) - * Charles Poynton poynton at poynton.com - * - * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B - * - * which can be expressed with integers as - * - * Y = (6969 * R + 23434 * G + 2365 * B)/32768 - * - * Poynton's current link (as of January 2003 through July 2011): - * - * has changed the numbers slightly: - * - * Y = 0.2126*R + 0.7152*G + 0.0722*B - * - * which can be expressed with integers as - * - * Y = (6966 * R + 23436 * G + 2366 * B)/32768 - * - * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 - * end point chromaticities and the D65 white point. Depending on the - * precision used for the D65 white point this produces a variety of different - * numbers, however if the four decimal place value used in ITU-R Rec 709 is - * used (0.3127,0.3290) the Y calculation would be: - * - * Y = (6968 * R + 23435 * G + 2366 * B)/32768 - * - * While this is correct the rounding results in an overflow for white, because - * the sum of the rounded coefficients is 32769, not 32768. Consequently - * libpng uses, instead, the closest non-overflowing approximation: - * - * Y = (6968 * R + 23434 * G + 2366 * B)/32768 - * - * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk - * (including an sRGB chunk) then the chromaticities are used to calculate the - * coefficients. See the chunk handling in pngrutil.c for more information. - * - * In all cases the calculation is to be done in a linear colorspace. If no - * gamma information is available to correct the encoding of the original RGB - * values this results in an implicit assumption that the original PNG RGB - * values were linear. - * - * Other integer coefficients can be used via png_set_rgb_to_gray(). Because - * the API takes just red and green coefficients the blue coefficient is - * calculated to make the sum 32768. This will result in different rounding - * to that used above. - */ -static int -png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) -{ - int rgb_error = 0; - - png_debug(1, "in png_do_rgb_to_gray"); - - if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && - (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; - png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; - png_uint_32 bc = 32768 - rc - gc; - png_uint_32 row_width = row_info->width; - int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; - - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - /* Notice that gamma to/from 1 are not necessarily inverses (if - * there is an overall gamma correction). Prior to 1.5.5 this code - * checked the linearized values for equality; this doesn't match - * the documentation, the original values must be checked. - */ - if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - - if (red != green || red != blue) - { - red = png_ptr->gamma_to_1[red]; - green = png_ptr->gamma_to_1[green]; - blue = png_ptr->gamma_to_1[blue]; - - rgb_error |= 1; - *(dp++) = png_ptr->gamma_from_1[ - (rc*red + gc*green + bc*blue + 16384)>>15]; - } - - else - { - /* If there is no overall correction the table will not be - * set. - */ - if (png_ptr->gamma_table != NULL) - red = png_ptr->gamma_table[red]; - - *(dp++) = red; - } - - if (have_alpha != 0) - *(dp++) = *(sp++); - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - - if (red != green || red != blue) - { - rgb_error |= 1; - /* NOTE: this is the historical approach which simply - * truncates the results. - */ - *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); - } - - else - *(dp++) = red; - - if (have_alpha != 0) - *(dp++) = *(sp++); - } - } - } - - else /* RGB bit_depth == 16 */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, w; - png_byte hi,lo; - - hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); - - if (red == green && red == blue) - { - if (png_ptr->gamma_16_table != NULL) - w = png_ptr->gamma_16_table[(red & 0xff) - >> png_ptr->gamma_shift][red >> 8]; - - else - w = red; - } - - else - { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff) - >> png_ptr->gamma_shift][red>>8]; - png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green & 0xff) >> - png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff) - >> png_ptr->gamma_shift][blue>>8]; - png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 - + bc*blue_1 + 16384)>>15); - w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >> - png_ptr->gamma_shift][gray16 >> 8]; - rgb_error |= 1; - } - - *(dp++) = (png_byte)((w>>8) & 0xff); - *(dp++) = (png_byte)(w & 0xff); - - if (have_alpha != 0) - { - *(dp++) = *(sp++); - *(dp++) = *(sp++); - } - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, gray16; - png_byte hi,lo; - - hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); - - if (red != green || red != blue) - rgb_error |= 1; - - /* From 1.5.5 in the 16-bit case do the accurate conversion even - * in the 'fast' case - this is because this is where the code - * ends up when handling linear 16-bit data. - */ - gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> - 15); - *(dp++) = (png_byte)((gray16 >> 8) & 0xff); - *(dp++) = (png_byte)(gray16 & 0xff); - - if (have_alpha != 0) - { - *(dp++) = *(sp++); - *(dp++) = *(sp++); - } - } - } - } - - row_info->channels = (png_byte)(row_info->channels - 2); - row_info->color_type = (png_byte)(row_info->color_type & - ~PNG_COLOR_MASK_COLOR); - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - return rgb_error; -} -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) -/* Replace any alpha or transparency with the supplied background color. - * "background" is already in the screen gamma, while "background_1" is - * at a gamma of 1.0. Paletted files have already been taken care of. - */ -static void -png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -{ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; - png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; - png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; - png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; - png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; - int gamma_shift = png_ptr->gamma_shift; - int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; -#endif - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - int shift; - - png_debug(1, "in png_do_compose"); - - switch (row_info->color_type) - { - case PNG_COLOR_TYPE_GRAY: - { - switch (row_info->bit_depth) - { - case 1: - { - sp = row; - shift = 7; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x01) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 7; - sp++; - } - - else - shift--; - } - break; - } - - case 2: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= - (unsigned int)png_ptr->background.gray << shift; - *sp = (png_byte)(tmp & 0xff); - } - - else - { - unsigned int p = (*sp >> shift) & 0x03; - unsigned int g = (gamma_table [p | (p << 2) | - (p << 4) | (p << 6)] >> 6) & 0x03; - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= (unsigned int)(g << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - - else -#endif - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= - (unsigned int)png_ptr->background.gray << shift; - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - break; - } - - case 4: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - else - { - unsigned int p = (*sp >> shift) & 0x0f; - unsigned int g = (gamma_table[p | (p << 4)] >> 4) & - 0x0f; - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= (unsigned int)(g << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - - else -#endif - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - break; - } - - case 8: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - - else - *sp = gamma_table[*sp]; - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - } - } - break; - } - - case 16: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray - & 0xff); - } - - else - { - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray - & 0xff); - } - } - } - break; - } - - default: - break; - } - break; - } - - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 3) - { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 3) - { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 a = *(sp + 1); - - if (a == 0xff) - *sp = gamma_table[*sp]; - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.gray; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.gray); - if (optimize == 0) - w = gamma_from_1[w]; - *sp = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_byte a = *(sp + 1); - - if (a == 0) - *sp = (png_byte)png_ptr->background.gray; - - else if (a < 0xff) - png_composite(*sp, *sp, a, png_ptr->background.gray); - } - } - } - else /* if (png_ptr->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else - { - png_uint_16 g, v, w; - - g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize != 0) - w = v; - else - w = gamma_16_from_1[(v & 0xff) >> - gamma_shift][v >> 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 g, v; - - g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_composite_16(v, g, a, png_ptr->background.gray); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0xff) - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.red); - if (optimize == 0) w = gamma_from_1[w]; - *sp = w; - - v = gamma_to_1[*(sp + 1)]; - png_composite(w, v, a, png_ptr->background_1.green); - if (optimize == 0) w = gamma_from_1[w]; - *(sp + 1) = w; - - v = gamma_to_1[*(sp + 2)]; - png_composite(w, v, a, png_ptr->background_1.blue); - if (optimize == 0) w = gamma_from_1[w]; - *(sp + 2) = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else if (a < 0xff) - { - png_composite(*sp, *sp, a, png_ptr->background.red); - - png_composite(*(sp + 1), *(sp + 1), a, - png_ptr->background.green); - - png_composite(*(sp + 2), *(sp + 2), a, - png_ptr->background.blue); - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v, w; - - v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(w, v, a, png_ptr->background_1.red); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; - png_composite_16(w, v, a, png_ptr->background_1.green); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - - *(sp + 2) = (png_byte)((w >> 8) & 0xff); - *(sp + 3) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; - png_composite_16(w, v, a, png_ptr->background_1.blue); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - - *(sp + 4) = (png_byte)((w >> 8) & 0xff); - *(sp + 5) = (png_byte)(w & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 v; - - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - png_composite_16(v, r, a, png_ptr->background.red); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - png_composite_16(v, g, a, png_ptr->background.green); - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - png_composite_16(v, b, a, png_ptr->background.blue); - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - default: - break; - } -} -#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Gamma correct the image, avoiding the alpha channel. Make sure - * you do this after you deal with the transparency issue on grayscale - * or RGB images. If your bit depth is 8, use gamma_table, if it - * is 16, use gamma_16_table and gamma_shift. Build these with - * build_gamma_table(). - */ -static void -png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -{ - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; - int gamma_shift = png_ptr->gamma_shift; - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_gamma"); - - if (((row_info->bit_depth <= 8 && gamma_table != NULL) || - (row_info->bit_depth == 16 && gamma_16_table != NULL))) - { - switch (row_info->color_type) - { - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - *sp = gamma_table[*sp]; - sp++; - *sp = gamma_table[*sp]; - sp++; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - } - } - break; - } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - - *sp = gamma_table[*sp]; - sp++; - - *sp = gamma_table[*sp]; - sp++; - - sp++; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 4; - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp += 2; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 4; - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY: - { - if (row_info->bit_depth == 2) - { - sp = row; - for (i = 0; i < row_width; i += 4) - { - int a = *sp & 0xc0; - int b = *sp & 0x30; - int c = *sp & 0x0c; - int d = *sp & 0x03; - - *sp = (png_byte)( - ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| - ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| - ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| - ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); - sp++; - } - } - - if (row_info->bit_depth == 4) - { - sp = row; - for (i = 0; i < row_width; i += 2) - { - int msb = *sp & 0xf0; - int lsb = *sp & 0x0f; - - *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) - | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); - sp++; - } - } - - else if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - } - } - - else if (row_info->bit_depth == 16) - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - } - } - break; - } - - default: - break; - } - } -} -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* Encode the alpha channel to the output gamma (the input channel is always - * linear.) Called only with color types that have an alpha channel. Needs the - * from_1 tables. - */ -static void -png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -{ - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_encode_alpha"); - - if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (row_info->bit_depth == 8) - { - png_bytep table = png_ptr->gamma_from_1; - - if (table != NULL) - { - int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; - - /* The alpha channel is the last component: */ - row += step - 1; - - for (; row_width > 0; --row_width, row += step) - *row = table[*row]; - - return; - } - } - - else if (row_info->bit_depth == 16) - { - png_uint_16pp table = png_ptr->gamma_16_from_1; - int gamma_shift = png_ptr->gamma_shift; - - if (table != NULL) - { - int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; - - /* The alpha channel is the last component: */ - row += step - 2; - - for (; row_width > 0; --row_width, row += step) - { - png_uint_16 v; - - v = table[*(row + 1) >> gamma_shift][*row]; - *row = (png_byte)((v >> 8) & 0xff); - *(row + 1) = (png_byte)(v & 0xff); - } - - return; - } - } - } - - /* Only get to here if called with a weird row_info; no harm has been done, - * so just issue a warning. - */ - png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); -} -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expands a palette row to an RGB or RGBA row depending - * upon whether you supply trans and num_trans. - */ -static void -png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, - png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, - int num_trans) -{ - int shift, value; - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_expand_palette"); - - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (row_info->bit_depth < 8) - { - switch (row_info->bit_depth) - { - case 1: - { - sp = row + (size_t)((row_width - 1) >> 3); - dp = row + (size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 1; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - sp = row + (size_t)((row_width - 1) >> 2); - dp = row + (size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)value; - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - sp = row + (size_t)((row_width - 1) >> 1); - dp = row + (size_t)row_width - 1; - shift = (int)((row_width & 0x01) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)value; - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift += 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (row_info->bit_depth == 8) - { - { - if (num_trans > 0) - { - sp = row + (size_t)row_width - 1; - dp = row + ((size_t)row_width << 2) - 1; - - i = 0; -#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - if (png_ptr->riffled_palette != NULL) - { - /* The RGBA optimization works with png_ptr->bit_depth == 8 - * but sometimes row_info->bit_depth has been changed to 8. - * In these cases, the palette hasn't been riffled. - */ - i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row, - &sp, &dp); - } -#else - PNG_UNUSED(png_ptr) -#endif - - for (; i < row_width; i++) - { - if ((int)(*sp) >= num_trans) - *dp-- = 0xff; - else - *dp-- = trans_alpha[*sp]; - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; - sp--; - } - row_info->bit_depth = 8; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - row_info->color_type = 6; - row_info->channels = 4; - } - - else - { - sp = row + (size_t)row_width - 1; - dp = row + (size_t)(row_width * 3) - 1; - i = 0; -#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row, - &sp, &dp); -#else - PNG_UNUSED(png_ptr) -#endif - - for (; i < row_width; i++) - { - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; - sp--; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 24; - row_info->rowbytes = row_width * 3; - row_info->color_type = 2; - row_info->channels = 3; - } - } - } - } -} - -/* If the bit depth < 8, it is expanded to 8. Also, if the already - * expanded transparency value is supplied, an alpha channel is built. - */ -static void -png_do_expand(png_row_infop row_info, png_bytep row, - png_const_color_16p trans_color) -{ - int shift, value; - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_expand"); - - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - unsigned int gray = trans_color != NULL ? trans_color->gray : 0; - - if (row_info->bit_depth < 8) - { - switch (row_info->bit_depth) - { - case 1: - { - gray = (gray & 0x01) * 0xff; - sp = row + (size_t)((row_width - 1) >> 3); - dp = row + (size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 0xff; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - gray = (gray & 0x03) * 0x55; - sp = row + (size_t)((row_width - 1) >> 2); - dp = row + (size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)(value | (value << 2) | (value << 4) | - (value << 6)); - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - gray = (gray & 0x0f) * 0x11; - sp = row + (size_t)((row_width - 1) >> 1); - dp = row + (size_t)row_width - 1; - shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)(value | (value << 4)); - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (trans_color != NULL) - { - if (row_info->bit_depth == 8) - { - gray = gray & 0xff; - sp = row + (size_t)row_width - 1; - dp = row + ((size_t)row_width << 1) - 1; - - for (i = 0; i < row_width; i++) - { - if ((*sp & 0xffU) == gray) - *dp-- = 0; - - else - *dp-- = 0xff; - - *dp-- = *sp--; - } - } - - else if (row_info->bit_depth == 16) - { - unsigned int gray_high = (gray >> 8) & 0xff; - unsigned int gray_low = gray & 0xff; - sp = row + row_info->rowbytes - 1; - dp = row + (row_info->rowbytes << 1) - 1; - for (i = 0; i < row_width; i++) - { - if ((*(sp - 1) & 0xffU) == gray_high && - (*(sp) & 0xffU) == gray_low) - { - *dp-- = 0; - *dp-- = 0; - } - - else - { - *dp-- = 0xff; - *dp-- = 0xff; - } - - *dp-- = *sp--; - *dp-- = *sp--; - } - } - - row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - row_info->channels = 2; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_width); - } - } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB && - trans_color != NULL) - { - if (row_info->bit_depth == 8) - { - png_byte red = (png_byte)(trans_color->red & 0xff); - png_byte green = (png_byte)(trans_color->green & 0xff); - png_byte blue = (png_byte)(trans_color->blue & 0xff); - sp = row + (size_t)row_info->rowbytes - 1; - dp = row + ((size_t)row_width << 2) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) - *dp-- = 0; - - else - *dp-- = 0xff; - - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - } - } - else if (row_info->bit_depth == 16) - { - png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); - png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); - png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); - png_byte red_low = (png_byte)(trans_color->red & 0xff); - png_byte green_low = (png_byte)(trans_color->green & 0xff); - png_byte blue_low = (png_byte)(trans_color->blue & 0xff); - sp = row + row_info->rowbytes - 1; - dp = row + ((size_t)row_width << 3) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 5) == red_high && - *(sp - 4) == red_low && - *(sp - 3) == green_high && - *(sp - 2) == green_low && - *(sp - 1) == blue_high && - *(sp ) == blue_low) - { - *dp-- = 0; - *dp-- = 0; - } - - else - { - *dp-- = 0xff; - *dp-- = 0xff; - } - - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - } - } - row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - row_info->channels = 4; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } -} -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* If the bit depth is 8 and the color type is not a palette type expand the - * whole row to 16 bits. Has no effect otherwise. - */ -static void -png_do_expand_16(png_row_infop row_info, png_bytep row) -{ - if (row_info->bit_depth == 8 && - row_info->color_type != PNG_COLOR_TYPE_PALETTE) - { - /* The row have a sequence of bytes containing [0..255] and we need - * to turn it into another row containing [0..65535], to do this we - * calculate: - * - * (input / 255) * 65535 - * - * Which happens to be exactly input * 257 and this can be achieved - * simply by byte replication in place (copying backwards). - */ - png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ - png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ - while (dp > sp) - { - dp[-2] = dp[-1] = *--sp; dp -= 2; - } - - row_info->rowbytes *= 2; - row_info->bit_depth = 16; - row_info->pixel_depth = (png_byte)(row_info->channels * 16); - } -} -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -static void -png_do_quantize(png_row_infop row_info, png_bytep row, - png_const_bytep palette_lookup, png_const_bytep quantize_lookup) -{ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_quantize"); - - if (row_info->bit_depth == 8) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) - { - int r, g, b, p; - sp = row; - dp = row; - for (i = 0; i < row_width; i++) - { - r = *sp++; - g = *sp++; - b = *sp++; - - /* This looks real messy, but the compiler will reduce - * it down to a reasonable formula. For example, with - * 5 bits per color, we get: - * p = (((r >> 3) & 0x1f) << 10) | - * (((g >> 3) & 0x1f) << 5) | - * ((b >> 3) & 0x1f); - */ - p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); - - *dp++ = palette_lookup[p]; - } - - row_info->color_type = PNG_COLOR_TYPE_PALETTE; - row_info->channels = 1; - row_info->pixel_depth = row_info->bit_depth; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && - palette_lookup != NULL) - { - int r, g, b, p; - sp = row; - dp = row; - for (i = 0; i < row_width; i++) - { - r = *sp++; - g = *sp++; - b = *sp++; - sp++; - - p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); - - *dp++ = palette_lookup[p]; - } - - row_info->color_type = PNG_COLOR_TYPE_PALETTE; - row_info->channels = 1; - row_info->pixel_depth = row_info->bit_depth; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - - else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - quantize_lookup) - { - sp = row; - - for (i = 0; i < row_width; i++, sp++) - { - *sp = quantize_lookup[*sp]; - } - } - } -} -#endif /* READ_QUANTIZE */ - -/* Transform the row. The order of transformations is significant, - * and is very touchy. If you add a transformation, take care to - * decide how it fits in with the other transformations here. - */ -void /* PRIVATE */ -png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_read_transformations"); - - if (png_ptr->row_buf == NULL) - { - /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this - * error is incredibly rare and incredibly easy to debug without this - * information. - */ - png_error(png_ptr, "NULL row buffer"); - } - - /* The following is debugging; prior to 1.5.4 the code was never compiled in; - * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro - * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for - * all transformations, however in practice the ROW_INIT always gets done on - * demand, if necessary. - */ - if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && - (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - /* Application has failed to call either png_read_start_image() or - * png_read_update_info() after setting transforms that expand pixels. - * This check added to libpng-1.2.19 (but not enabled until 1.5.4). - */ - png_error(png_ptr, "Uninitialized row"); - } - -#ifdef PNG_READ_EXPAND_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { -#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) - { - if (png_ptr->riffled_palette == NULL) - { - /* Initialize the accelerated palette expansion. */ - png_ptr->riffled_palette = - (png_bytep)png_malloc(png_ptr, 256 * 4); - png_riffle_palette_neon(png_ptr); - } - } -#endif - png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); - } - - else - { - if (png_ptr->num_trans != 0 && - (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) - png_do_expand(row_info, png_ptr->row_buf + 1, - &(png_ptr->trans_color)); - - else - png_do_expand(row_info, png_ptr->row_buf + 1, NULL); - } - } -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && - (png_ptr->transformations & PNG_COMPOSE) == 0 && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - { - int rgb_error = - png_do_rgb_to_gray(png_ptr, row_info, - png_ptr->row_buf + 1); - - if (rgb_error != 0) - { - png_ptr->rgb_to_gray_status=1; - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_WARN) - png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_ERR) - png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - } - } -#endif - -/* From Andreas Dilger e-mail to png-implement, 26 March 1998: - * - * In most cases, the "simple transparency" should be done prior to doing - * gray-to-RGB, or you will have to test 3x as many bytes to check if a - * pixel is transparent. You would also need to make sure that the - * transparency information is upgraded to RGB. - * - * To summarize, the current flow is: - * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite - * with background "in place" if transparent, - * convert to RGB if necessary - * - Gray + alpha -> composite with gray background and remove alpha bytes, - * convert to RGB if necessary - * - * To support RGB backgrounds for gray images we need: - * - Gray + simple transparency -> convert to RGB + simple transparency, - * compare 3 or 6 bytes and composite with - * background "in place" if transparent - * (3x compare/pixel compared to doing - * composite with gray bkgrnd) - * - Gray + alpha -> convert to RGB + alpha, composite with background and - * remove alpha bytes (3x float - * operations/pixel compared with composite - * on gray background) - * - * Greg's change will do this. The reason it wasn't done before is for - * performance, as this increases the per-pixel operations. If we would check - * in advance if the background was gray or RGB, and position the gray-to-RGB - * transform appropriately, then it would save a lot of work/time. - */ - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* If gray -> RGB, do so now only if background is non-gray; else do later - * for performance reasons - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - if ((png_ptr->transformations & PNG_GAMMA) != 0 && -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Because RGB_TO_GRAY does the gamma transform. */ - (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && -#endif -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* Because PNG_COMPOSE does the gamma transform if there is something to - * do (if there is an alpha channel or transparency.) - */ - !((png_ptr->transformations & PNG_COMPOSE) != 0 && - ((png_ptr->num_trans != 0) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && -#endif - /* Because png_init_read_transformations transforms the palette, unless - * RGB_TO_GRAY will do the transform. - */ - (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) - png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && - (png_ptr->transformations & PNG_COMPOSE) != 0 && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && - (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) - png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* There is no harm in doing both of these because only one has any effect, - * by putting the 'scale' option first if the app asks for scale (either by - * calling the API or in a TRANSFORM flag) this is what happens. - */ - if ((png_ptr->transformations & PNG_16_TO_8) != 0) - png_do_chop(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if ((png_ptr->transformations & PNG_QUANTIZE) != 0) - { - png_do_quantize(row_info, png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->quantize_index); - - if (row_info->rowbytes == 0) - png_error(png_ptr, "png_do_quantize returned rowbytes=0"); - } -#endif /* READ_QUANTIZE */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Do the expansion now, after all the arithmetic has been done. Notice - * that previous transformations can handle the PNG_EXPAND_16 flag if this - * is efficient (particularly true in the case of gamma correction, where - * better accuracy results faster!) - */ - if ((png_ptr->transformations & PNG_EXPAND_16) != 0) - png_do_expand_16(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* NOTE: moved here in 1.5.4 (from much later in this list.) */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_do_unshift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0) - png_do_unpack(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Added at libpng-1.5.10 */ - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= 0) - png_do_check_palette_indexes(png_ptr, row_info); -#endif - -#ifdef PNG_READ_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_do_read_filler(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->filler, png_ptr->flags); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) - png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_16BIT_SUPPORTED -#ifdef PNG_READ_SWAP_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_do_swap(row_info, png_ptr->row_buf + 1); -#endif -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - if (png_ptr->read_user_transform_fn != NULL) - (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - if (png_ptr->user_transform_depth != 0) - row_info->bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels != 0) - row_info->channels = png_ptr->user_transform_channels; -#endif - row_info->pixel_depth = (png_byte)(row_info->bit_depth * - row_info->channels); - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); - } -#endif -} - -#endif /* READ_TRANSFORMS */ -#endif /* READ */ +/* pngrtran.c - transforms the data in a row for PNG readers + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains functions optionally called by an application + * in order to tell libpng how to handle data when reading a PNG. + * Transformations that are used in both reading and writing are + * in pngtrans.c. + */ + +#include "pngpriv.h" + +#ifdef PNG_ARM_NEON_IMPLEMENTATION +# if PNG_ARM_NEON_IMPLEMENTATION == 1 +# define PNG_ARM_NEON_INTRINSICS_AVAILABLE +# if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) +# include +# else +# include +# endif +# endif +#endif + +#ifdef PNG_RISCV_RVV_IMPLEMENTATION +# if PNG_RISCV_RVV_IMPLEMENTATION == 1 +# define PNG_RISCV_RVV_INTRINSICS_AVAILABLE +# endif +#endif + +#ifdef PNG_READ_SUPPORTED + +/* Set the action on getting a CRC error for an ancillary or critical chunk. */ +void PNGAPI +png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) +{ + png_debug(1, "in png_set_crc_action"); + + if (png_ptr == NULL) + return; + + /* Tell libpng how we react to CRC errors in critical chunks */ + switch (crit_action) + { + case PNG_CRC_NO_CHANGE: /* Leave setting as is */ + break; + + case PNG_CRC_WARN_USE: /* Warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; + break; + + case PNG_CRC_QUIET_USE: /* Quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | + PNG_FLAG_CRC_CRITICAL_IGNORE; + break; + + case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ + png_warning(png_ptr, + "Can't discard critical data on CRC error"); + /* FALLTHROUGH */ + case PNG_CRC_ERROR_QUIT: /* Error/quit */ + + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; + break; + } + + /* Tell libpng how we react to CRC errors in ancillary chunks */ + switch (ancil_action) + { + case PNG_CRC_NO_CHANGE: /* Leave setting as is */ + break; + + case PNG_CRC_WARN_USE: /* Warn/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; + break; + + case PNG_CRC_QUIET_USE: /* Quiet/use data */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | + PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + + case PNG_CRC_ERROR_QUIT: /* Error/quit */ + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; + break; + + case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ + + case PNG_CRC_DEFAULT: + default: + png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; + break; + } +} + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +/* Is it OK to set a transformation now? Only if png_start_read_image or + * png_read_update_info have not been called. It is not necessary for the IHDR + * to have been read in all cases; the need_IHDR parameter allows for this + * check too. + */ +static int +png_rtran_ok(png_structrp png_ptr, int need_IHDR) +{ + if (png_ptr != NULL) + { + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) + png_app_error(png_ptr, + "invalid after png_start_read_image or png_read_update_info"); + + else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_app_error(png_ptr, "invalid before the PNG header has been read"); + + else + { + /* Turn on failure to initialize correctly for all transforms. */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; + + return 1; /* Ok */ + } + } + + return 0; /* no png_error possible! */ +} +#endif + +#ifdef PNG_READ_BACKGROUND_SUPPORTED +/* Handle alpha and tRNS via a background color */ +void PNGFAPI +png_set_background_fixed(png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma) +{ + png_debug(1, "in png_set_background_fixed"); + + if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) + return; + + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) + { + png_warning(png_ptr, "Application must supply a known background gamma"); + return; + } + + png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + png_ptr->background = *background_color; + png_ptr->background_gamma = background_gamma; + png_ptr->background_gamma_type = (png_byte)(background_gamma_code); + if (need_expand != 0) + png_ptr->transformations |= PNG_BACKGROUND_EXPAND; + else + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_background(png_structrp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_set_background_fixed(png_ptr, background_color, background_gamma_code, + need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); +} +# endif /* FLOATING_POINT */ +#endif /* READ_BACKGROUND */ + +/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the + * one that pngrtran does first (scale) happens. This is necessary to allow the + * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. + */ +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +void PNGAPI +png_set_scale_16(png_structrp png_ptr) +{ + png_debug(1, "in png_set_scale_16"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_SCALE_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +/* Chop 16-bit depth files to 8-bit depth */ +void PNGAPI +png_set_strip_16(png_structrp png_ptr) +{ + png_debug(1, "in png_set_strip_16"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_16_TO_8; +} +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED +void PNGAPI +png_set_strip_alpha(png_structrp png_ptr) +{ + png_debug(1, "in png_set_strip_alpha"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_STRIP_ALPHA; +} +#endif + +#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) +/* PNGv3 conformance: this private API exists to resolve the now mandatory error + * resolution when multiple conflicting sources of gamma or colour space + * information are available. + * + * Terminology (assuming power law, "gamma", encodings): + * "screen" gamma: a power law imposed by the output device when digital + * samples are converted to visible light output. The EOTF - voltage to + * luminance on output. + * + * "file" gamma: a power law used to encode luminance levels from the input + * data (the scene or the mastering display system) into digital voltages. + * The OETF - luminance to voltage on input. + * + * gamma "correction": a power law matching the **inverse** of the overall + * transfer function from input luminance levels to output levels. The + * **inverse** of the OOTF; the correction "corrects" for the OOTF by aiming + * to make the overall OOTF (including the correction) linear. + * + * It is important to understand this terminology because the defined terms are + * scattered throughout the libpng code and it is very easy to end up with the + * inverse of the power law required. + * + * Variable and struct::member names: + * file_gamma OETF how the PNG data was encoded + * + * screen_gamma EOTF how the screen will decode digital levels + * + * -- not used -- OOTF the net effect OETF x EOTF + * gamma_correction the inverse of OOTF to make the result linear + * + * All versions of libpng require a call to "png_set_gamma" to establish the + * "screen" gamma, the power law representing the EOTF. png_set_gamma may also + * set or default the "file" gamma; the OETF. gamma_correction is calculated + * internally. + * + * The earliest libpng versions required file_gamma to be supplied to set_gamma. + * Later versions started allowing png_set_gamma and, later, png_set_alpha_mode, + * to cause defaulting from the file data. + * + * PNGv3 mandated a particular form for this defaulting, one that is compatible + * with what libpng did except that if libpng detected inconsistencies it marked + * all the chunks as "invalid". PNGv3 effectively invalidates this prior code. + * + * Behaviour implemented below: + * translate_gamma_flags(gamma, is_screen) + * The libpng-1.6 API for the gamma parameters to libpng APIs + * (png_set_gamma and png_set_alpha_mode at present). This allows the + * 'gamma' value to be passed as a png_fixed_point number or as one of a + * set of integral values for specific "well known" examples of transfer + * functions. This is compatible with PNGv3. + */ +static png_fixed_point +translate_gamma_flags(png_fixed_point output_gamma, int is_screen) +{ + /* Check for flag values. The main reason for having the old Mac value as a + * flag is that it is pretty near impossible to work out what the correct + * value is from Apple documentation - a working Mac system is needed to + * discover the value! + */ + if (output_gamma == PNG_DEFAULT_sRGB || + output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) + { + if (is_screen != 0) + output_gamma = PNG_GAMMA_sRGB; + else + output_gamma = PNG_GAMMA_sRGB_INVERSE; + } + + else if (output_gamma == PNG_GAMMA_MAC_18 || + output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) + { + if (is_screen != 0) + output_gamma = PNG_GAMMA_MAC_OLD; + else + output_gamma = PNG_GAMMA_MAC_INVERSE; + } + + return output_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +static png_fixed_point +convert_gamma_value(png_structrp png_ptr, double output_gamma) +{ + /* The following silently ignores cases where fixed point (times 100,000) + * gamma values are passed to the floating point API. This is safe and it + * means the fixed point constants work just fine with the floating point + * API. The alternative would just lead to undetected errors and spurious + * bug reports. Negative values fail inside the _fixed API unless they + * correspond to the flag values. + */ + if (output_gamma > 0 && output_gamma < 128) + output_gamma *= PNG_FP_1; + + /* This preserves -1 and -2 exactly: */ + output_gamma = floor(output_gamma + .5); + + if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) + png_fixed_error(png_ptr, "gamma value"); + + return (png_fixed_point)output_gamma; +} +# endif + +static int +unsupported_gamma(png_structrp png_ptr, png_fixed_point gamma, int warn) +{ + /* Validate a gamma value to ensure it is in a reasonable range. The value + * is expected to be 1 or greater, but this range test allows for some + * viewing correction values. The intent is to weed out the API users + * who might use the inverse of the gamma value accidentally! + * + * 1.6.47: apply the test in png_set_gamma as well but only warn and return + * false if it fires. + * + * TODO: 1.8: make this an app_error in png_set_gamma as well. + */ + if (gamma < PNG_LIB_GAMMA_MIN || gamma > PNG_LIB_GAMMA_MAX) + { +# define msg "gamma out of supported range" + if (warn) + png_app_warning(png_ptr, msg); + else + png_app_error(png_ptr, msg); + return 1; +# undef msg + } + + return 0; +} +#endif /* READ_ALPHA_MODE || READ_GAMMA */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +void PNGFAPI +png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, + png_fixed_point output_gamma) +{ + png_fixed_point file_gamma; + int compose = 0; + + png_debug(1, "in png_set_alpha_mode_fixed"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + output_gamma = translate_gamma_flags(output_gamma, 1/*screen*/); + if (unsupported_gamma(png_ptr, output_gamma, 0/*error*/)) + return; + + /* The default file gamma is the inverse of the output gamma; the output + * gamma may be changed below so get the file value first. The default_gamma + * is set here and from the simplified API (which uses a different algorithm) + * so don't overwrite a set value: + */ + file_gamma = png_ptr->default_gamma; + if (file_gamma == 0) + { + file_gamma = png_reciprocal(output_gamma); + png_ptr->default_gamma = file_gamma; + } + + /* There are really 8 possibilities here, composed of any combination + * of: + * + * premultiply the color channels + * do not encode non-opaque pixels + * encode the alpha as well as the color channels + * + * The differences disappear if the input/output ('screen') gamma is 1.0, + * because then the encoding is a no-op and there is only the choice of + * premultiplying the color channels or not. + * + * png_set_alpha_mode and png_set_background interact because both use + * png_compose to do the work. Calling both is only useful when + * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along + * with a default gamma value. Otherwise PNG_COMPOSE must not be set. + */ + switch (mode) + { + case PNG_ALPHA_PNG: /* default: png standard */ + /* No compose, but it may be set by png_set_background! */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + break; + + case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ + compose = 1; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + /* The output is linear: */ + output_gamma = PNG_FP_1; + break; + + case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ + compose = 1; + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; + /* output_gamma records the encoding of opaque pixels! */ + break; + + case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ + compose = 1; + png_ptr->transformations |= PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + break; + + default: + png_error(png_ptr, "invalid alpha mode"); + } + + /* Set the screen gamma values: */ + png_ptr->screen_gamma = output_gamma; + + /* Finally, if pre-multiplying, set the background fields to achieve the + * desired result. + */ + if (compose != 0) + { + /* And obtain alpha pre-multiplication by composing on black: */ + memset(&png_ptr->background, 0, (sizeof png_ptr->background)); + png_ptr->background_gamma = file_gamma; /* just in case */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; + png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; + + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_error(png_ptr, + "conflicting calls to set alpha mode and background"); + + png_ptr->transformations |= PNG_COMPOSE; + } +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) +{ + png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, + output_gamma)); +} +# endif +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* Dither file to 8-bit. Supply a palette, the current number + * of elements in the palette, the maximum number of elements + * allowed, and a histogram if possible. If the current number + * of colors is greater than the maximum number, the palette will be + * modified to fit in the maximum number. "full_quantize" indicates + * whether we need a quantizing cube set up for RGB images, or if we + * simply are reducing the number of colors in a paletted image. + */ + +typedef struct png_dsort_struct +{ + struct png_dsort_struct * next; + png_byte left; + png_byte right; +} png_dsort; +typedef png_dsort * png_dsortp; +typedef png_dsort * * png_dsortpp; + +void PNGAPI +png_set_quantize(png_structrp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize) +{ + png_debug(1, "in png_set_quantize"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + if (palette == NULL) + return; + + png_ptr->transformations |= PNG_QUANTIZE; + + if (full_quantize == 0) + { + int i; + + /* Initialize the array to index colors. + * + * Ensure quantize_index can fit 256 elements (PNG_MAX_PALETTE_LENGTH) + * rather than num_palette elements. This is to prevent buffer overflows + * caused by malformed PNG files with out-of-range palette indices. + * + * Be careful to avoid leaking memory. Applications are allowed to call + * this function more than once per png_struct. + */ + png_free(png_ptr, png_ptr->quantize_index); + png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, + PNG_MAX_PALETTE_LENGTH); + for (i = 0; i < PNG_MAX_PALETTE_LENGTH; i++) + png_ptr->quantize_index[i] = (png_byte)i; + } + + if (num_palette > maximum_colors) + { + if (histogram != NULL) + { + /* This is easy enough, just throw out the least used colors. + * Perhaps not the best solution, but good enough. + */ + + png_bytep quantize_sort; + int i, j; + + /* Initialize the local array to sort colors. */ + quantize_sort = (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)num_palette); + for (i = 0; i < num_palette; i++) + quantize_sort[i] = (png_byte)i; + + /* Find the least used palette entries by starting a + * bubble sort, and running it until we have sorted + * out enough colors. Note that we don't care about + * sorting all the colors, just finding which are + * least used. + */ + + for (i = num_palette - 1; i >= maximum_colors; i--) + { + int done; /* To stop early if the list is pre-sorted */ + + done = 1; + for (j = 0; j < i; j++) + { + if (histogram[quantize_sort[j]] + < histogram[quantize_sort[j + 1]]) + { + png_byte t; + + t = quantize_sort[j]; + quantize_sort[j] = quantize_sort[j + 1]; + quantize_sort[j + 1] = t; + done = 0; + } + } + + if (done != 0) + break; + } + + /* Swap the palette around, and set up a table, if necessary */ + if (full_quantize != 0) + { + j = num_palette; + + /* Put all the useful colors within the max, but don't + * move the others. + */ + for (i = 0; i < maximum_colors; i++) + { + if ((int)quantize_sort[i] >= maximum_colors) + { + do + j--; + while ((int)quantize_sort[j] >= maximum_colors); + + palette[i] = palette[j]; + } + } + } + else + { + j = num_palette; + + /* Move all the used colors inside the max limit, and + * develop a translation table. + */ + for (i = 0; i < maximum_colors; i++) + { + /* Only move the colors we need to */ + if ((int)quantize_sort[i] >= maximum_colors) + { + png_color tmp_color; + + do + j--; + while ((int)quantize_sort[j] >= maximum_colors); + + tmp_color = palette[j]; + palette[j] = palette[i]; + palette[i] = tmp_color; + /* Indicate where the color went */ + png_ptr->quantize_index[j] = (png_byte)i; + png_ptr->quantize_index[i] = (png_byte)j; + } + } + + /* Find closest color for those colors we are not using */ + for (i = 0; i < num_palette; i++) + { + if ((int)png_ptr->quantize_index[i] >= maximum_colors) + { + int min_d, k, min_k, d_index; + + /* Find the closest color to one we threw out */ + d_index = png_ptr->quantize_index[i]; + min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); + for (k = 1, min_k = 0; k < maximum_colors; k++) + { + int d; + + d = PNG_COLOR_DIST(palette[d_index], palette[k]); + + if (d < min_d) + { + min_d = d; + min_k = k; + } + } + /* Point to closest color */ + png_ptr->quantize_index[i] = (png_byte)min_k; + } + } + } + png_free(png_ptr, quantize_sort); + } + else + { + /* This is much harder to do simply (and quickly). Perhaps + * we need to go through a median cut routine, but those + * don't always behave themselves with only a few colors + * as input. So we will just find the closest two colors, + * and throw out one of them (chosen somewhat randomly). + * [We don't understand this at all, so if someone wants to + * work on improving it, be our guest - AED, GRP] + */ + int i; + int max_d; + int num_new_palette; + png_dsortp t; + png_dsortpp hash; + + t = NULL; + + /* Initialize palette index arrays */ + png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)num_palette); + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)num_palette); + + /* Initialize the sort array */ + for (i = 0; i < num_palette; i++) + { + png_ptr->index_to_palette[i] = (png_byte)i; + png_ptr->palette_to_index[i] = (png_byte)i; + } + + hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 * + (sizeof (png_dsortp)))); + + num_new_palette = num_palette; + + /* Initial wild guess at how far apart the farthest pixel + * pair we will be eliminating will be. Larger + * numbers mean more areas will be allocated, Smaller + * numbers run the risk of not saving enough data, and + * having to do this all over again. + * + * I have not done extensive checking on this number. + */ + max_d = 96; + + while (num_new_palette > maximum_colors) + { + for (i = 0; i < num_new_palette - 1; i++) + { + int j; + + for (j = i + 1; j < num_new_palette; j++) + { + int d; + + d = PNG_COLOR_DIST(palette[i], palette[j]); + + if (d <= max_d) + { + + t = (png_dsortp)png_malloc_warn(png_ptr, + (png_alloc_size_t)(sizeof (png_dsort))); + + if (t == NULL) + break; + + t->next = hash[d]; + t->left = png_ptr->palette_to_index[i]; + t->right = png_ptr->palette_to_index[j]; + hash[d] = t; + } + } + if (t == NULL) + break; + } + + if (t != NULL) + for (i = 0; i <= max_d; i++) + { + if (hash[i] != NULL) + { + png_dsortp p; + + for (p = hash[i]; p; p = p->next) + { + if ((int)png_ptr->index_to_palette[p->left] + < num_new_palette && + (int)png_ptr->index_to_palette[p->right] + < num_new_palette) + { + int j, next_j; + + if (num_new_palette & 0x01) + { + j = p->left; + next_j = p->right; + } + else + { + j = p->right; + next_j = p->left; + } + + num_new_palette--; + palette[png_ptr->index_to_palette[j]] + = palette[num_new_palette]; + if (full_quantize == 0) + { + int k; + + for (k = 0; k < num_palette; k++) + { + if (png_ptr->quantize_index[k] == + png_ptr->index_to_palette[j]) + png_ptr->quantize_index[k] = + png_ptr->index_to_palette[next_j]; + + if ((int)png_ptr->quantize_index[k] == + num_new_palette) + png_ptr->quantize_index[k] = + png_ptr->index_to_palette[j]; + } + } + + png_ptr->index_to_palette[png_ptr->palette_to_index + [num_new_palette]] = png_ptr->index_to_palette[j]; + + png_ptr->palette_to_index[png_ptr->index_to_palette[j]] + = png_ptr->palette_to_index[num_new_palette]; + + png_ptr->index_to_palette[j] = + (png_byte)num_new_palette; + + png_ptr->palette_to_index[num_new_palette] = + (png_byte)j; + } + if (num_new_palette <= maximum_colors) + break; + } + if (num_new_palette <= maximum_colors) + break; + } + } + + for (i = 0; i < 769; i++) + { + if (hash[i] != NULL) + { + png_dsortp p = hash[i]; + while (p) + { + t = p->next; + png_free(png_ptr, p); + p = t; + } + } + hash[i] = 0; + } + max_d += 96; + } + png_free(png_ptr, hash); + png_free(png_ptr, png_ptr->palette_to_index); + png_free(png_ptr, png_ptr->index_to_palette); + png_ptr->palette_to_index = NULL; + png_ptr->index_to_palette = NULL; + } + num_palette = maximum_colors; + } + if (png_ptr->palette == NULL) + { + /* Allocate an owned copy rather than aliasing the caller's pointer, + * so that png_read_destroy can free png_ptr->palette unconditionally. + */ + png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); + memcpy(png_ptr->palette, palette, (unsigned int)num_palette * + (sizeof (png_color))); + } + png_ptr->num_palette = (png_uint_16)num_palette; + + if (full_quantize != 0) + { + int i; + png_bytep distance; + int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + + PNG_QUANTIZE_BLUE_BITS; + int num_red = (1 << PNG_QUANTIZE_RED_BITS); + int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); + int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); + size_t num_entries = ((size_t)1 << total_bits); + + png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, + (png_alloc_size_t)(num_entries)); + + distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries); + + memset(distance, 0xff, num_entries); + + for (i = 0; i < num_palette; i++) + { + int ir, ig, ib; + int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); + int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); + int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); + + for (ir = 0; ir < num_red; ir++) + { + /* int dr = abs(ir - r); */ + int dr = ((ir > r) ? ir - r : r - ir); + int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + + PNG_QUANTIZE_GREEN_BITS)); + + for (ig = 0; ig < num_green; ig++) + { + /* int dg = abs(ig - g); */ + int dg = ((ig > g) ? ig - g : g - ig); + int dt = dr + dg; + int dm = ((dr > dg) ? dr : dg); + int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); + + for (ib = 0; ib < num_blue; ib++) + { + int d_index = index_g | ib; + /* int db = abs(ib - b); */ + int db = ((ib > b) ? ib - b : b - ib); + int dmax = ((dm > db) ? dm : db); + int d = dmax + dt + db; + + if (d < (int)distance[d_index]) + { + distance[d_index] = (png_byte)d; + png_ptr->palette_lookup[d_index] = (png_byte)i; + } + } + } + } + } + + png_free(png_ptr, distance); + } +} +#endif /* READ_QUANTIZE */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +void PNGFAPI +png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) +{ + png_debug(1, "in png_set_gamma_fixed"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + /* New in libpng-1.5.4 - reserve particular negative values as flags. */ + scrn_gamma = translate_gamma_flags(scrn_gamma, 1/*screen*/); + file_gamma = translate_gamma_flags(file_gamma, 0/*file*/); + + /* Checking the gamma values for being >0 was added in 1.5.4 along with the + * premultiplied alpha support; this actually hides an undocumented feature + * of the previous implementation which allowed gamma processing to be + * disabled in background handling. There is no evidence (so far) that this + * was being used; however, png_set_background itself accepted and must still + * accept '0' for the gamma value it takes, because it isn't always used. + * + * Since this is an API change (albeit a very minor one that removes an + * undocumented API feature) the following checks were only enabled in + * libpng-1.6.0. + */ + if (file_gamma <= 0) + png_app_error(png_ptr, "invalid file gamma in png_set_gamma"); + if (scrn_gamma <= 0) + png_app_error(png_ptr, "invalid screen gamma in png_set_gamma"); + + if (unsupported_gamma(png_ptr, file_gamma, 1/*warn*/) || + unsupported_gamma(png_ptr, scrn_gamma, 1/*warn*/)) + return; + + /* 1.6.47: png_struct::file_gamma and png_struct::screen_gamma are now only + * written by this API. This removes dependencies on the order of API calls + * and allows the complex gamma checks to be delayed until needed. + */ + png_ptr->file_gamma = file_gamma; + png_ptr->screen_gamma = scrn_gamma; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) +{ + png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), + convert_gamma_value(png_ptr, file_gamma)); +} +# endif /* FLOATING_POINT */ +#endif /* READ_GAMMA */ + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expand paletted images to RGB, expand grayscale images of + * less than 8-bit depth to 8-bit depth, and expand tRNS chunks + * to alpha channels. + */ +void PNGAPI +png_set_expand(png_structrp png_ptr) +{ + png_debug(1, "in png_set_expand"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +/* GRR 19990627: the following three functions currently are identical + * to png_set_expand(). However, it is entirely reasonable that someone + * might wish to expand an indexed image to RGB but *not* expand a single, + * fully transparent palette entry to a full alpha channel--perhaps instead + * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace + * the transparent color with a particular RGB value, or drop tRNS entirely. + * IOW, a future version of the library may make the transformations flag + * a bit more fine-grained, with separate bits for each of these three + * functions. + * + * More to the point, these functions make it obvious what libpng will be + * doing, whereas "expand" can (and does) mean any number of things. + * + * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified + * to expand only the sample depth but not to expand the tRNS to alpha + * and its name was changed to png_set_expand_gray_1_2_4_to_8(). + */ + +/* Expand paletted images to RGB. */ +void PNGAPI +png_set_palette_to_rgb(png_structrp png_ptr) +{ + png_debug(1, "in png_set_palette_to_rgb"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} + +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +void PNGAPI +png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) +{ + png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= PNG_EXPAND; +} + +/* Expand tRNS chunks to alpha channels. */ +void PNGAPI +png_set_tRNS_to_alpha(png_structrp png_ptr) +{ + png_debug(1, "in png_set_tRNS_to_alpha"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif /* READ_EXPAND */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise + * it may not work correctly.) + */ +void PNGAPI +png_set_expand_16(png_structrp png_ptr) +{ + png_debug(1, "in png_set_expand_16"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); +} +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +void PNGAPI +png_set_gray_to_rgb(png_structrp png_ptr) +{ + png_debug(1, "in png_set_gray_to_rgb"); + + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + /* Because rgb must be 8 bits or more: */ + png_set_expand_gray_1_2_4_to_8(png_ptr); + png_ptr->transformations |= PNG_GRAY_TO_RGB; +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +void PNGFAPI +png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, + png_fixed_point red, png_fixed_point green) +{ + png_debug(1, "in png_set_rgb_to_gray_fixed"); + + /* Need the IHDR here because of the check on color_type below. */ + /* TODO: fix this */ + if (png_rtran_ok(png_ptr, 1) == 0) + return; + + switch (error_action) + { + case PNG_ERROR_ACTION_NONE: + png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; + + case PNG_ERROR_ACTION_WARN: + png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; + + case PNG_ERROR_ACTION_ERROR: + png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + break; + + default: + png_error(png_ptr, "invalid error action to rgb_to_gray"); + } + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) +#ifdef PNG_READ_EXPAND_SUPPORTED + png_ptr->transformations |= PNG_EXPAND; +#else + { + /* Make this an error in 1.6 because otherwise the application may assume + * that it just worked and get a memory overwrite. + */ + png_error(png_ptr, + "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); + + /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ + } +#endif + { + if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) + { + png_uint_16 red_int, green_int; + + /* NOTE: this calculation does not round, but this behavior is retained + * for consistency; the inaccuracy is very small. The code here always + * overwrites the coefficients, regardless of whether they have been + * defaulted or set already. + */ + red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); + green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); + + png_ptr->rgb_to_gray_red_coeff = red_int; + png_ptr->rgb_to_gray_green_coeff = green_int; + png_ptr->rgb_to_gray_coefficients_set = 1; + } + + else if (red >= 0 && green >= 0) + png_app_warning(png_ptr, + "ignoring out of range rgb_to_gray coefficients"); + } +} + +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* Convert a RGB image to a grayscale of the same width. This allows us, + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. + */ + +void PNGAPI +png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, + double green) +{ + png_set_rgb_to_gray_fixed(png_ptr, error_action, + png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, green, "rgb to gray green coefficient")); +} +#endif /* FLOATING POINT */ + +#endif /* RGB_TO_GRAY */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +void PNGAPI +png_set_read_user_transform_fn(png_structrp png_ptr, + png_user_transform_ptr read_user_transform_fn) +{ + png_debug(1, "in png_set_read_user_transform_fn"); + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->read_user_transform_fn = read_user_transform_fn; +#endif +} +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +#ifdef PNG_READ_GAMMA_SUPPORTED +/* In the case of gamma transformations only do transformations on images where + * the [file] gamma and screen_gamma are not close reciprocals, otherwise it + * slows things down slightly, and also needlessly introduces small errors. + */ +static int /* PRIVATE */ +png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) +{ + /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma + * correction as a difference of the overall transform from 1.0 + * + * We want to compare the threshold with s*f - 1, if we get + * overflow here it is because of wacky gamma values so we + * turn on processing anyway. + */ + png_fixed_point gtest; + return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || + png_gamma_significant(gtest); +} +#endif + +/* Initialize everything needed for the read. This includes modifying + * the palette. + */ + +/* For the moment 'png_init_palette_transformations' and + * 'png_init_rgb_transformations' only do some flag canceling optimizations. + * The intent is that these two routines should have palette or rgb operations + * extracted from 'png_init_read_transformations'. + */ +static void /* PRIVATE */ +png_init_palette_transformations(png_structrp png_ptr) +{ + /* Called to handle the (input) palette case. In png_do_read_transformations + * the first step is to expand the palette if requested, so this code must + * take care to only make changes that are invariant with respect to the + * palette expansion, or only do them if there is no expansion. + * + * STRIP_ALPHA has already been handled in the caller (by setting num_trans + * to 0.) + */ + int input_has_alpha = 0; + int input_has_transparency = 0; + + if (png_ptr->num_trans > 0) + { + int i; + + /* Ignore if all the entries are opaque (unlikely!) */ + for (i=0; inum_trans; ++i) + { + if (png_ptr->trans_alpha[i] == 255) + continue; + else if (png_ptr->trans_alpha[i] == 0) + input_has_transparency = 1; + else + { + input_has_transparency = 1; + input_has_alpha = 1; + break; + } + } + } + + /* If no alpha we can optimize. */ + if (input_has_alpha == 0) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + if (input_has_transparency == 0) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_set_background handling - deals with the complexity of whether the + * background color is in the file format or the screen format in the case + * where an 'expand' will happen. + */ + + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && + (png_ptr->transformations & PNG_EXPAND) != 0) + { + { + png_ptr->background.red = + png_ptr->palette[png_ptr->background.index].red; + png_ptr->background.green = + png_ptr->palette[png_ptr->background.index].green; + png_ptr->background.blue = + png_ptr->palette[png_ptr->background.index].blue; + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + { + if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) + { + /* Invert the alpha channel (in tRNS) unless the pixels are + * going to be expanded, in which case leave it for later + */ + int i, istop = png_ptr->num_trans; + + for (i = 0; i < istop; i++) + png_ptr->trans_alpha[i] = + (png_byte)(255 - png_ptr->trans_alpha[i]); + } + } +#endif /* READ_INVERT_ALPHA */ + } + } /* background expand and (therefore) no alpha association. */ +#endif /* READ_EXPAND && READ_BACKGROUND */ +} + +static void /* PRIVATE */ +png_init_rgb_transformations(png_structrp png_ptr) +{ + /* Added to libpng-1.5.4: check the color type to determine whether there + * is any alpha or transparency in the image and simply cancel the + * background and alpha mode stuff if there isn't. + */ + int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; + int input_has_transparency = png_ptr->num_trans > 0; + + /* If no alpha we can optimize. */ + if (input_has_alpha == 0) + { + /* Any alpha means background and associative alpha processing is + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA + * and ENCODE_ALPHA are irrelevant. + */ +# ifdef PNG_READ_ALPHA_MODE_SUPPORTED + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; +# endif + + if (input_has_transparency == 0) + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); + } + +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* png_set_background handling - deals with the complexity of whether the + * background color is in the file format or the screen format in the case + * where an 'expand' will happen. + */ + + /* The following code cannot be entered in the alpha pre-multiplication case + * because PNG_BACKGROUND_EXPAND is cancelled below. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && + (png_ptr->transformations & PNG_EXPAND) != 0 && + (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + /* i.e., GRAY or GRAY_ALPHA */ + { + { + /* Expand background and tRNS chunks */ + int gray = png_ptr->background.gray; + int trans_gray = png_ptr->trans_color.gray; + + switch (png_ptr->bit_depth) + { + case 1: + gray *= 0xff; + trans_gray *= 0xff; + break; + + case 2: + gray *= 0x55; + trans_gray *= 0x55; + break; + + case 4: + gray *= 0x11; + trans_gray *= 0x11; + break; + + default: + + case 8: + /* FALLTHROUGH */ /* (Already 8 bits) */ + + case 16: + /* Already a full 16 bits */ + break; + } + + png_ptr->background.red = png_ptr->background.green = + png_ptr->background.blue = (png_uint_16)gray; + + if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) + { + png_ptr->trans_color.red = png_ptr->trans_color.green = + png_ptr->trans_color.blue = (png_uint_16)trans_gray; + } + } + } /* background expand and (therefore) no alpha association. */ +#endif /* READ_EXPAND && READ_BACKGROUND */ +} + +#ifdef PNG_READ_GAMMA_SUPPORTED +png_fixed_point /* PRIVATE */ +png_resolve_file_gamma(png_const_structrp png_ptr) +{ + png_fixed_point file_gamma; + + /* The file gamma is determined by these precedence rules, in this order + * (i.e. use the first value found): + * + * png_set_gamma; png_struct::file_gammma if not zero, then: + * png_struct::chunk_gamma if not 0 (determined the PNGv3 rules), then: + * png_set_gamma; 1/png_struct::screen_gamma if not zero + * + * 0 (i.e. do no gamma handling) + */ + file_gamma = png_ptr->file_gamma; + if (file_gamma != 0) + return file_gamma; + + file_gamma = png_ptr->chunk_gamma; + if (file_gamma != 0) + return file_gamma; + + file_gamma = png_ptr->default_gamma; + if (file_gamma != 0) + return file_gamma; + + /* If png_reciprocal overflows, it returns 0, indicating to the caller that + * there is no usable file gamma. (The checks added to png_set_gamma and + * png_set_alpha_mode should prevent a screen_gamma which would overflow.) + */ + if (png_ptr->screen_gamma != 0) + file_gamma = png_reciprocal(png_ptr->screen_gamma); + + return file_gamma; +} + +static int +png_init_gamma_values(png_structrp png_ptr) +{ + /* The following temporary indicates if overall gamma correction is + * required. + */ + int gamma_correction = 0; + png_fixed_point file_gamma, screen_gamma; + + /* Resolve the file_gamma. See above: if png_ptr::screen_gamma is set + * file_gamma will always be set here: + */ + file_gamma = png_resolve_file_gamma(png_ptr); + screen_gamma = png_ptr->screen_gamma; + + if (file_gamma > 0) /* file has been set */ + { + if (screen_gamma > 0) /* screen set too */ + gamma_correction = png_gamma_threshold(file_gamma, screen_gamma); + + else + /* Assume the output matches the input; a long time default behavior + * of libpng, although the standard has nothing to say about this. + */ + screen_gamma = png_reciprocal(file_gamma); + } + + else /* both unset, prevent corrections: */ + file_gamma = screen_gamma = PNG_FP_1; + + png_ptr->file_gamma = file_gamma; + png_ptr->screen_gamma = screen_gamma; + return gamma_correction; + +} +#endif /* READ_GAMMA */ + +void /* PRIVATE */ +png_init_read_transformations(png_structrp png_ptr) +{ + png_debug(1, "in png_init_read_transformations"); + + /* This internal function is called from png_read_start_row in pngrutil.c + * and it is called before the 'rowbytes' calculation is done, so the code + * in here can change or update the transformations flags. + * + * First do updates that do not depend on the details of the PNG image data + * being processed. + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds + * png_set_alpha_mode and this is another source for a default file gamma so + * the test needs to be performed later - here. In addition prior to 1.5.4 + * the tests were repeated for the PALETTE color type here - this is no + * longer necessary (and doesn't seem to have been necessary before.) + * + * PNGv3: the new mandatory precedence/priority rules for colour space chunks + * are handled here (by calling the above function). + * + * Turn the gamma transformation on or off as appropriate. Notice that + * PNG_GAMMA just refers to the file->screen correction. Alpha composition + * may independently cause gamma correction because it needs linear data + * (e.g. if the file has a gAMA chunk but the screen gamma hasn't been + * specified.) In any case this flag may get turned off in the code + * immediately below if the transform can be handled outside the row loop. + */ + if (png_init_gamma_values(png_ptr) != 0) + png_ptr->transformations |= PNG_GAMMA; + + else + png_ptr->transformations &= ~PNG_GAMMA; +#endif + + /* Certain transformations have the effect of preventing other + * transformations that happen afterward in png_do_read_transformations; + * resolve the interdependencies here. From the code of + * png_do_read_transformations the order is: + * + * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) + * 2) PNG_STRIP_ALPHA (if no compose) + * 3) PNG_RGB_TO_GRAY + * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY + * 5) PNG_COMPOSE + * 6) PNG_GAMMA + * 7) PNG_STRIP_ALPHA (if compose) + * 8) PNG_ENCODE_ALPHA + * 9) PNG_SCALE_16_TO_8 + * 10) PNG_16_TO_8 + * 11) PNG_QUANTIZE (converts to palette) + * 12) PNG_EXPAND_16 + * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY + * 14) PNG_INVERT_MONO + * 15) PNG_INVERT_ALPHA + * 16) PNG_SHIFT + * 17) PNG_PACK + * 18) PNG_BGR + * 19) PNG_PACKSWAP + * 20) PNG_FILLER (includes PNG_ADD_ALPHA) + * 21) PNG_SWAP_ALPHA + * 22) PNG_SWAP_BYTES + * 23) PNG_USER_TRANSFORM [must be last] + */ +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) == 0) + { + /* Stripping the alpha channel happens immediately after the 'expand' + * transformations, before all other transformation, so it cancels out + * the alpha handling. It has the side effect negating the effect of + * PNG_EXPAND_tRNS too: + */ + png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | + PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + + /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen + * so transparency information would remain just so long as it wasn't + * expanded. This produces unexpected API changes if the set of things + * that do PNG_EXPAND_tRNS changes (perfectly possible given the + * documentation - which says ask for what you want, accept what you + * get.) This makes the behavior consistent from 1.5.4: + */ + png_ptr->num_trans = 0; + } +#endif /* STRIP_ALPHA supported, no COMPOSE */ + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA + * settings will have no effect. + */ + if (png_gamma_significant(png_ptr->screen_gamma) == 0) + { + png_ptr->transformations &= ~PNG_ENCODE_ALPHA; + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + } +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Make sure the coefficients for the rgb to gray conversion are set + * appropriately. + */ + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + png_set_rgb_coefficients(png_ptr); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + /* Detect gray background and attempt to enable optimization for + * gray --> RGB case. + * + * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or + * RGB_ALPHA (in which case need_expand is superfluous anyway), the + * background color might actually be gray yet not be flagged as such. + * This is not a problem for the current code, which uses + * PNG_BACKGROUND_IS_GRAY only to decide when to do the + * png_do_gray_to_rgb() transformation. + * + * TODO: this code needs to be revised to avoid the complexity and + * interdependencies. The color type of the background should be recorded in + * png_set_background, along with the bit depth, then the code has a record + * of exactly what color space the background is currently in. + */ + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) + { + /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if + * the file was grayscale the background value is gray. + */ + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + } + + else if ((png_ptr->transformations & PNG_COMPOSE) != 0) + { + /* PNG_COMPOSE: png_set_background was called with need_expand false, + * so the color is in the color space of the output or png_set_alpha_mode + * was called and the color is black. Ignore RGB_TO_GRAY because that + * happens before GRAY_TO_RGB. + */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) + { + if (png_ptr->background.red == png_ptr->background.green && + png_ptr->background.red == png_ptr->background.blue) + { + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + png_ptr->background.gray = png_ptr->background.red; + } + } + } +#endif /* READ_EXPAND && READ_BACKGROUND */ +#endif /* READ_GRAY_TO_RGB */ + + /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations + * can be performed directly on the palette, and some (such as rgb to gray) + * can be optimized inside the palette. This is particularly true of the + * composite (background and alpha) stuff, which can be pretty much all done + * in the palette even if the result is expanded to RGB or gray afterward. + * + * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and + * earlier and the palette stuff is actually handled on the first row. This + * leads to the reported bug that the palette returned by png_get_PLTE is not + * updated. + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_init_palette_transformations(png_ptr); + + else + png_init_rgb_transformations(png_ptr); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_EXPAND_16_SUPPORTED) + if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && + png_ptr->bit_depth != 16) + { + /* TODO: fix this. Because the expand_16 operation is after the compose + * handling the background color must be 8, not 16, bits deep, but the + * application will supply a 16-bit value so reduce it here. + * + * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at + * present, so that case is ok (until do_expand_16 is moved.) + * + * NOTE: this discards the low 16 bits of the user supplied background + * color, but until expand_16 works properly there is no choice! + */ +# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) + CHOP(png_ptr->background.red); + CHOP(png_ptr->background.green); + CHOP(png_ptr->background.blue); + CHOP(png_ptr->background.gray); +# undef CHOP + } +#endif /* READ_BACKGROUND && READ_EXPAND_16 */ + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ + defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) + if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && + png_ptr->bit_depth == 16) + { + /* On the other hand, if a 16-bit file is to be reduced to 8-bits per + * component this will also happen after PNG_COMPOSE and so the background + * color must be pre-expanded here. + * + * TODO: fix this too. + */ + png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); + png_ptr->background.green = + (png_uint_16)(png_ptr->background.green * 257); + png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); + png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); + } +#endif + + /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the + * background support (see the comments in scripts/pnglibconf.dfa), this + * allows pre-multiplication of the alpha channel to be implemented as + * compositing on black. This is probably sub-optimal and has been done in + * 1.5.4 betas simply to enable external critique and testing (i.e. to + * implement the new API quickly, without lots of internal changes.) + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +# ifdef PNG_READ_BACKGROUND_SUPPORTED + /* Includes ALPHA_MODE */ + png_ptr->background_1 = png_ptr->background; +# endif + + /* This needs to change - in the palette image case a whole set of tables are + * built when it would be quicker to just calculate the correct value for + * each palette entry directly. Also, the test is too tricky - why check + * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that + * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the + * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction + * the gamma tables will not be built even if composition is required on a + * gamma encoded value. + * + * In 1.5.4 this is addressed below by an additional check on the individual + * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the + * tables. + */ + if ((png_ptr->transformations & PNG_GAMMA) != 0 || + ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && + (png_gamma_significant(png_ptr->file_gamma) != 0 || + png_gamma_significant(png_ptr->screen_gamma) != 0)) || + ((png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_gamma_significant(png_ptr->file_gamma) != 0 || + png_gamma_significant(png_ptr->screen_gamma) != 0 +# ifdef PNG_READ_BACKGROUND_SUPPORTED + || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && + png_gamma_significant(png_ptr->background_gamma) != 0) +# endif + )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && + png_gamma_significant(png_ptr->screen_gamma) != 0)) + { + png_build_gamma_table(png_ptr, png_ptr->bit_depth); + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + { + /* Issue a warning about this combination: because RGB_TO_GRAY is + * optimized to do the gamma transform if present yet do_background has + * to do the same thing if both options are set a + * double-gamma-correction happens. This is true in all versions of + * libpng to date. + */ + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + png_warning(png_ptr, + "libpng does not support gamma+background+rgb_to_gray"); + + if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) + { + /* We don't get to here unless there is a tRNS chunk with non-opaque + * entries - see the checking code at the start of this function. + */ + png_color back, back_1; + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) + { + + back.red = png_ptr->gamma_table[png_ptr->background.red]; + back.green = png_ptr->gamma_table[png_ptr->background.green]; + back.blue = png_ptr->gamma_table[png_ptr->background.blue]; + + back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; + back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; + back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; + } + else + { + png_fixed_point g, gs; + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = (png_ptr->screen_gamma); + gs = PNG_FP_1; + break; + + case PNG_BACKGROUND_GAMMA_FILE: + g = png_reciprocal(png_ptr->file_gamma); + gs = png_reciprocal2(png_ptr->file_gamma, + png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + default: + g = PNG_FP_1; /* back_1 */ + gs = PNG_FP_1; /* back */ + break; + } + + if (png_gamma_significant(gs) != 0) + { + back.red = png_gamma_8bit_correct(png_ptr->background.red, + gs); + back.green = png_gamma_8bit_correct(png_ptr->background.green, + gs); + back.blue = png_gamma_8bit_correct(png_ptr->background.blue, + gs); + } + + else + { + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + } + + if (png_gamma_significant(g) != 0) + { + back_1.red = png_gamma_8bit_correct(png_ptr->background.red, + g); + back_1.green = png_gamma_8bit_correct( + png_ptr->background.green, g); + back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, + g); + } + + else + { + back_1.red = (png_byte)png_ptr->background.red; + back_1.green = (png_byte)png_ptr->background.green; + back_1.blue = (png_byte)png_ptr->background.blue; + } + } + + for (i = 0; i < num_palette; i++) + { + if (i < (int)png_ptr->num_trans && + png_ptr->trans_alpha[i] != 0xff) + { + if (png_ptr->trans_alpha[i] == 0) + { + palette[i] = back; + } + else /* if (png_ptr->trans_alpha[i] != 0xff) */ + { + if ((png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0) + { + /* Premultiply only: + * component = round((component * alpha) / 255) + */ + png_uint_32 component; + + component = png_ptr->gamma_to_1[palette[i].red]; + component = + (component * png_ptr->trans_alpha[i] + 128) / 255; + palette[i].red = png_ptr->gamma_from_1[component]; + + component = png_ptr->gamma_to_1[palette[i].green]; + component = + (component * png_ptr->trans_alpha[i] + 128) / 255; + palette[i].green = png_ptr->gamma_from_1[component]; + + component = png_ptr->gamma_to_1[palette[i].blue]; + component = + (component * png_ptr->trans_alpha[i] + 128) / 255; + palette[i].blue = png_ptr->gamma_from_1[component]; + } + else + { + /* Composite with background color: + * component = + * alpha * component + (1 - alpha) * background + */ + png_byte v, w; + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite(w, v, + png_ptr->trans_alpha[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].green]; + png_composite(w, v, + png_ptr->trans_alpha[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].blue]; + png_composite(w, v, + png_ptr->trans_alpha[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } + } + } + else + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + } + + /* Prevent the transformations being done again. + * + * NOTE: this is highly dubious; it removes the transformations in + * place. This seems inconsistent with the general treatment of the + * transformations elsewhere. + */ + png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; + } /* color_type == PNG_COLOR_TYPE_PALETTE */ + + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ + else /* color_type != PNG_COLOR_TYPE_PALETTE */ + { + int gs_sig, g_sig; + png_fixed_point g = PNG_FP_1; /* Correction to linear */ + png_fixed_point gs = PNG_FP_1; /* Correction to screen */ + + switch (png_ptr->background_gamma_type) + { + case PNG_BACKGROUND_GAMMA_SCREEN: + g = png_ptr->screen_gamma; + /* gs = PNG_FP_1; */ + break; + + case PNG_BACKGROUND_GAMMA_FILE: + g = png_reciprocal(png_ptr->file_gamma); + gs = png_reciprocal2(png_ptr->file_gamma, + png_ptr->screen_gamma); + break; + + case PNG_BACKGROUND_GAMMA_UNIQUE: + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); + break; + + default: + png_error(png_ptr, "invalid background gamma type"); + } + + g_sig = png_gamma_significant(g); + gs_sig = png_gamma_significant(gs); + + if (g_sig != 0) + png_ptr->background_1.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, g); + + if (gs_sig != 0) + png_ptr->background.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, gs); + + if ((png_ptr->background.red != png_ptr->background.green) || + (png_ptr->background.red != png_ptr->background.blue) || + (png_ptr->background.red != png_ptr->background.gray)) + { + /* RGB or RGBA with color background */ + if (g_sig != 0) + { + png_ptr->background_1.red = png_gamma_correct(png_ptr, + png_ptr->background.red, g); + + png_ptr->background_1.green = png_gamma_correct(png_ptr, + png_ptr->background.green, g); + + png_ptr->background_1.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, g); + } + + if (gs_sig != 0) + { + png_ptr->background.red = png_gamma_correct(png_ptr, + png_ptr->background.red, gs); + + png_ptr->background.green = png_gamma_correct(png_ptr, + png_ptr->background.green, gs); + + png_ptr->background.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, gs); + } + } + + else + { + /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ + png_ptr->background_1.red = png_ptr->background_1.green + = png_ptr->background_1.blue = png_ptr->background_1.gray; + + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; + } + + /* The background is now in screen gamma: */ + png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; + } /* color_type != PNG_COLOR_TYPE_PALETTE */ + }/* png_ptr->transformations & PNG_BACKGROUND */ + + else + /* Transformation does not include PNG_BACKGROUND */ +#endif /* READ_BACKGROUND */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ + && ((png_ptr->transformations & PNG_EXPAND) == 0 || + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) +#endif + ) + { + png_colorp palette = png_ptr->palette; + int num_palette = png_ptr->num_palette; + int i; + + /* NOTE: there are other transformations that should probably be in + * here too. + */ + for (i = 0; i < num_palette; i++) + { + palette[i].red = png_ptr->gamma_table[palette[i].red]; + palette[i].green = png_ptr->gamma_table[palette[i].green]; + palette[i].blue = png_ptr->gamma_table[palette[i].blue]; + } + + /* Done the gamma correction. */ + png_ptr->transformations &= ~PNG_GAMMA; + } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ + } +#ifdef PNG_READ_BACKGROUND_SUPPORTED + else +#endif +#endif /* READ_GAMMA */ + +#ifdef PNG_READ_BACKGROUND_SUPPORTED + /* No GAMMA transformation (see the hanging else 4 lines above) */ + if ((png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = (int)png_ptr->num_trans; + png_color back; + png_colorp palette = png_ptr->palette; + + back.red = (png_byte)png_ptr->background.red; + back.green = (png_byte)png_ptr->background.green; + back.blue = (png_byte)png_ptr->background.blue; + + for (i = 0; i < istop; i++) + { + if (png_ptr->trans_alpha[i] == 0) + { + palette[i] = back; + } + + else if (png_ptr->trans_alpha[i] != 0xff) + { + /* The png_composite() macro is defined in png.h */ + png_composite(palette[i].red, palette[i].red, + png_ptr->trans_alpha[i], back.red); + + png_composite(palette[i].green, palette[i].green, + png_ptr->trans_alpha[i], back.green); + + png_composite(palette[i].blue, palette[i].blue, + png_ptr->trans_alpha[i], back.blue); + } + } + + png_ptr->transformations &= ~PNG_COMPOSE; + } +#endif /* READ_BACKGROUND */ + +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) != 0 && + (png_ptr->transformations & PNG_EXPAND) == 0 && + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + { + int i; + int istop = png_ptr->num_palette; + int shift = 8 - png_ptr->sig_bit.red; + + png_ptr->transformations &= ~PNG_SHIFT; + + /* significant bits can be in the range 1 to 7 for a meaningful result, if + * the number of significant bits is 0 then no shift is done (this is an + * error condition which is silently ignored.) + */ + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].red; + + component >>= shift; + png_ptr->palette[i].red = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.green; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].green; + + component >>= shift; + png_ptr->palette[i].green = (png_byte)component; + } + + shift = 8 - png_ptr->sig_bit.blue; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].blue; + + component >>= shift; + png_ptr->palette[i].blue = (png_byte)component; + } + } +#endif /* READ_SHIFT */ +} + +/* Modify the info structure to reflect the transformations. The + * info should be updated so a PNG file could be written with it, + * assuming the transformations result in valid PNG data. + */ +void /* PRIVATE */ +png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) +{ + png_debug(1, "in png_read_transform_info"); + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + info_ptr->palette != NULL && png_ptr->palette != NULL) + { + /* Sync info_ptr->palette with png_ptr->palette, which may + * have been modified by png_init_read_transformations + * (e.g. for gamma correction or background compositing). + */ + memcpy(info_ptr->palette, png_ptr->palette, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))); + } + +#ifdef PNG_READ_EXPAND_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + /* This check must match what actually happens in + * png_do_expand_palette; if it ever checks the tRNS chunk to see if + * it is all opaque we must do the same (at present it does not.) + */ + if (png_ptr->num_trans > 0) + info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + + else + info_ptr->color_type = PNG_COLOR_TYPE_RGB; + + info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; + + if (png_ptr->palette == NULL) + png_error (png_ptr, "Palette is NULL in indexed image"); + } + else + { + if (png_ptr->num_trans != 0) + { + if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } + if (info_ptr->bit_depth < 8) + info_ptr->bit_depth = 8; + + info_ptr->num_trans = 0; + } + } +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* The following is almost certainly wrong unless the background value is in + * the screen space! + */ + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + info_ptr->background = png_ptr->background; +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), + * however it seems that the code in png_init_read_transformations, which has + * been called before this from png_read_update_info->png_read_start_row + * sometimes does the gamma transform and cancels the flag. + * + * TODO: this is confusing. It only changes the result of png_get_gAMA and, + * yes, it does return the value that the transformed data effectively has + * but does any app really understand this? + */ + info_ptr->gamma = png_ptr->file_gamma; +#endif + + if (info_ptr->bit_depth == 16) + { +# ifdef PNG_READ_16BIT_SUPPORTED +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) + info_ptr->bit_depth = 8; +# endif + +# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + if ((png_ptr->transformations & PNG_16_TO_8) != 0) + info_ptr->bit_depth = 8; +# endif + +# else + /* No 16-bit support: force chopping 16-bit input down to 8, in this case + * the app program can chose if both APIs are available by setting the + * correct scaling to use. + */ +# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* For compatibility with previous versions use the strip method by + * default. This code works because if PNG_SCALE_16_TO_8 is already + * set the code below will do that in preference to the chop. + */ + png_ptr->transformations |= PNG_16_TO_8; + info_ptr->bit_depth = 8; +# else + +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_ptr->transformations |= PNG_SCALE_16_TO_8; + info_ptr->bit_depth = 8; +# else + + CONFIGURATION ERROR: you must enable at least one 16 to 8 method +# endif +# endif +#endif /* !READ_16BIT */ + } + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) + info_ptr->color_type = (png_byte)(info_ptr->color_type | + PNG_COLOR_MASK_COLOR); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_COLOR); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if ((png_ptr->transformations & PNG_QUANTIZE) != 0) + { + if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && + png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) + { + info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; + } + } +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && + info_ptr->bit_depth == 8 && + info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + { + info_ptr->bit_depth = 16; + } +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0 && + (info_ptr->bit_depth < 8)) + info_ptr->bit_depth = 8; +#endif + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + + else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + info_ptr->channels = 3; + + else + info_ptr->channels = 1; + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) + { + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); + info_ptr->num_trans = 0; + } +#endif + + if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) + info_ptr->channels++; + +#ifdef PNG_READ_FILLER_SUPPORTED + /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ + if ((png_ptr->transformations & PNG_FILLER) != 0 && + (info_ptr->color_type == PNG_COLOR_TYPE_RGB || + info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) + { + info_ptr->channels++; + /* If adding a true alpha channel not just filler */ + if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } +#endif + +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ +defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { + if (png_ptr->user_transform_depth != 0) + info_ptr->bit_depth = png_ptr->user_transform_depth; + + if (png_ptr->user_transform_channels != 0) + info_ptr->channels = png_ptr->user_transform_channels; + } +#endif + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * + info_ptr->bit_depth); + + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); + + /* Adding in 1.5.4: cache the above value in png_struct so that we can later + * check in png_rowbytes that the user buffer won't get overwritten. Note + * that the field is not always set - if png_read_update_info isn't called + * the application has to either not do any transforms or get the calculation + * right itself. + */ + png_ptr->info_rowbytes = info_ptr->rowbytes; + +#ifndef PNG_READ_EXPAND_SUPPORTED + if (png_ptr != NULL) + return; +#endif +} + +#ifdef PNG_READ_PACK_SUPPORTED +/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, + * without changing the actual values. Thus, if you had a row with + * a bit depth of 1, you would end up with bytes that only contained + * the numbers 0 or 1. If you would rather they contain 0 and 255, use + * png_do_shift() after this. + */ +static void +png_do_unpack(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_unpack"); + + if (row_info->bit_depth < 8) + { + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + switch (row_info->bit_depth) + { + case 1: + { + png_bytep sp = row + (size_t)((row_width - 1) >> 3); + png_bytep dp = row + (size_t)row_width - 1; + png_uint_32 shift = 7U - ((row_width + 7U) & 0x07); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x01); + + if (shift == 7) + { + shift = 0; + sp--; + } + + else + shift++; + + dp--; + } + break; + } + + case 2: + { + + png_bytep sp = row + (size_t)((row_width - 1) >> 2); + png_bytep dp = row + (size_t)row_width - 1; + png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x03); + + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + png_bytep sp = row + (size_t)((row_width - 1) >> 1); + png_bytep dp = row + (size_t)row_width - 1; + png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x0f); + + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift = 4; + + dp--; + } + break; + } + + default: + break; + } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = (size_t)row_width * row_info->channels; + } +} +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED +/* Reverse the effects of png_do_shift. This routine merely shifts the + * pixels back to their significant bits values. Thus, if you have + * a row of bit depth 8, but only 5 are significant, this will shift + * the values back to 0 through 31. + */ +static void +png_do_unshift(png_row_infop row_info, png_bytep row, + png_const_color_8p sig_bits) +{ + int color_type; + + png_debug(1, "in png_do_unshift"); + + /* The palette case has already been handled in the _init routine. */ + color_type = row_info->color_type; + + if (color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift[4]; + int channels = 0; + int bit_depth = row_info->bit_depth; + + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + shift[channels++] = bit_depth - sig_bits->red; + shift[channels++] = bit_depth - sig_bits->green; + shift[channels++] = bit_depth - sig_bits->blue; + } + + else + { + shift[channels++] = bit_depth - sig_bits->gray; + } + + if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + shift[channels++] = bit_depth - sig_bits->alpha; + } + + { + int c, have_shift; + + for (c = have_shift = 0; c < channels; ++c) + { + /* A shift of more than the bit depth is an error condition but it + * gets ignored here. + */ + if (shift[c] <= 0 || shift[c] >= bit_depth) + shift[c] = 0; + + else + have_shift = 1; + } + + if (have_shift == 0) + return; + } + + switch (bit_depth) + { + default: + /* Must be 1bpp gray: should not be here! */ + /* NOTREACHED */ + break; + + case 2: + /* Must be 2bpp gray */ + /* assert(channels == 1 && shift[0] == 1) */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + + while (bp < bp_end) + { + int b = (*bp >> 1) & 0x55; + *bp++ = (png_byte)b; + } + break; + } + + case 4: + /* Must be 4bpp gray */ + /* assert(channels == 1) */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int gray_shift = shift[0]; + int mask = 0xf >> gray_shift; + + mask |= mask << 4; + + while (bp < bp_end) + { + int b = (*bp >> gray_shift) & mask; + *bp++ = (png_byte)b; + } + break; + } + + case 8: + /* Single byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; + + while (bp < bp_end) + { + int b = *bp >> shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)b; + } + break; + } + +#ifdef PNG_READ_16BIT_SUPPORTED + case 16: + /* Double byte components, G, GA, RGB, RGBA */ + { + png_bytep bp = row; + png_bytep bp_end = bp + row_info->rowbytes; + int channel = 0; + + while (bp < bp_end) + { + int value = (bp[0] << 8) + bp[1]; + + value >>= shift[channel]; + if (++channel >= channels) + channel = 0; + *bp++ = (png_byte)(value >> 8); + *bp++ = (png_byte)value; + } + break; + } +#endif + } + } +} +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED +/* Scale rows of bit depth 16 down to 8 accurately */ +static void +png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_scale_16_to_8"); + + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ + png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) + { + /* The input is an array of 16-bit components, these must be scaled to + * 8 bits each. For a 16-bit value V the required value (from the PNG + * specification) is: + * + * (V * 255) / 65535 + * + * This reduces to round(V / 257), or floor((V + 128.5)/257) + * + * Represent V as the two byte value vhi.vlo. Make a guess that the + * result is the top byte of V, vhi, then the correction to this value + * is: + * + * error = floor(((V-vhi.vhi) + 128.5) / 257) + * = floor(((vlo-vhi) + 128.5) / 257) + * + * This can be approximated using integer arithmetic (and a signed + * shift): + * + * error = (vlo-vhi+128) >> 8; + * + * The approximate differs from the exact answer only when (vlo-vhi) is + * 128; it then gives a correction of +1 when the exact correction is + * 0. This gives 128 errors. The exact answer (correct for all 16-bit + * input values) is: + * + * error = (vlo-vhi+128)*65535 >> 24; + * + * An alternative arithmetic calculation which also gives no errors is: + * + * (V * 255 + 32895) >> 16 + */ + + png_int_32 tmp = *sp++; /* must be signed! */ + tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; + *dp++ = (png_byte)tmp; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = (size_t)row_info->width * row_info->channels; + } +} +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED +static void +/* Simply discard the low byte. This was the default behavior prior + * to libpng-1.5.4. + */ +png_do_chop(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_chop"); + + if (row_info->bit_depth == 16) + { + png_bytep sp = row; /* source */ + png_bytep dp = row; /* destination */ + png_bytep ep = sp + row_info->rowbytes; /* end+1 */ + + while (sp < ep) + { + *dp++ = *sp; + sp += 2; /* skip low byte */ + } + + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = (size_t)row_info->width * row_info->channels; + } +} +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED +static void +png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_read_swap_alpha"); + + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This converts from RGBA to ARGB */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This converts from RRGGBBAA to AARRGGBB */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } +#endif + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from GA to AG */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This converts from GGAA to AAGG */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; + } + } +#endif + } +} +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED +static void +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_uint_32 row_width; + png_debug(1, "in png_do_read_invert_alpha"); + + row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in RGBA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=3; + dp=sp; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=6; + dp=sp; + } + } +#endif + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in GA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = *(--sp); + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); +/* + *(--dp) = *(--sp); + *(--dp) = *(--sp); +*/ + sp-=2; + dp=sp; + } + } +#endif + } +} +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED +/* Add filler channel if we have RGB color */ +static void +png_do_read_filler(png_row_infop row_info, png_bytep row, + png_uint_32 filler, png_uint_32 flags) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + +#ifdef PNG_READ_16BIT_SUPPORTED + png_byte hi_filler = (png_byte)(filler>>8); +#endif + png_byte lo_filler = (png_byte)filler; + + png_debug(1, "in png_do_read_filler"); + + if ( + row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from G to GX */ + png_bytep sp = row + (size_t)row_width; + png_bytep dp = sp + (size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = (size_t)row_width * 2; + } + + else + { + /* This changes the data from G to XG */ + png_bytep sp = row + (size_t)row_width; + png_bytep dp = sp + (size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 16; + row_info->rowbytes = (size_t)row_width * 2; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from GG to GGXX */ + png_bytep sp = row + (size_t)row_width * 2; + png_bytep dp = sp + (size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = hi_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + *(--dp) = hi_filler; + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = (size_t)row_width * 4; + } + + else + { + /* This changes the data from GG to XXGG */ + png_bytep sp = row + (size_t)row_width * 2; + png_bytep dp = sp + (size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = lo_filler; + *(--dp) = hi_filler; + } + row_info->channels = 2; + row_info->pixel_depth = 32; + row_info->rowbytes = (size_t)row_width * 4; + } + } +#endif + } /* COLOR_TYPE == GRAY */ + else if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + if (row_info->bit_depth == 8) + { + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from RGB to RGBX */ + png_bytep sp = row + (size_t)row_width * 3; + png_bytep dp = sp + (size_t)row_width; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = (size_t)row_width * 4; + } + + else + { + /* This changes the data from RGB to XRGB */ + png_bytep sp = row + (size_t)row_width * 3; + png_bytep dp = sp + (size_t)row_width; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = lo_filler; + } + row_info->channels = 4; + row_info->pixel_depth = 32; + row_info->rowbytes = (size_t)row_width * 4; + } + } + +#ifdef PNG_READ_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) + { + /* This changes the data from RRGGBB to RRGGBBXX */ + png_bytep sp = row + (size_t)row_width * 6; + png_bytep dp = sp + (size_t)row_width * 2; + for (i = 1; i < row_width; i++) + { + *(--dp) = lo_filler; + *(--dp) = hi_filler; + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + } + *(--dp) = lo_filler; + *(--dp) = hi_filler; + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = (size_t)row_width * 8; + } + + else + { + /* This changes the data from RRGGBB to XXRRGGBB */ + png_bytep sp = row + (size_t)row_width * 6; + png_bytep dp = sp + (size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = lo_filler; + *(--dp) = hi_filler; + } + + row_info->channels = 4; + row_info->pixel_depth = 64; + row_info->rowbytes = (size_t)row_width * 8; + } + } +#endif + } /* COLOR_TYPE == RGB */ +} +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +/* Expand grayscale files to RGB, with or without alpha */ +static void +png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) +{ + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_gray_to_rgb"); + + if (row_info->bit_depth >= 8 && + (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) + { + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + if (row_info->bit_depth == 8) + { + /* This changes G to RGB */ + png_bytep sp = row + (size_t)row_width - 1; + png_bytep dp = sp + (size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + + else + { + /* This changes GG to RRGGBB */ + png_bytep sp = row + (size_t)row_width * 2 - 1; + png_bytep dp = sp + (size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This changes GA to RGBA */ + png_bytep sp = row + (size_t)row_width * 2 - 1; + png_bytep dp = sp + (size_t)row_width * 2; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *sp; + *(dp--) = *(sp--); + } + } + + else + { + /* This changes GGAA to RRGGBBAA */ + png_bytep sp = row + (size_t)row_width * 4 - 1; + png_bytep dp = sp + (size_t)row_width * 4; + for (i = 0; i < row_width; i++) + { + *(dp--) = *(sp--); + *(dp--) = *(sp--); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *sp; + *(dp--) = *(sp - 1); + *(dp--) = *(sp--); + *(dp--) = *(sp--); + } + } + } + row_info->channels = (png_byte)(row_info->channels + 2); + row_info->color_type |= PNG_COLOR_MASK_COLOR; + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } +} +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED +/* Reduce RGB files to grayscale, with or without alpha + * using the equation given in Poynton's ColorFAQ of 1998-01-04 at + * (THIS LINK IS DEAD June 2008 but + * versions dated 1998 through November 2002 have been archived at + * https://web.archive.org/web/20000816232553/www.inforamp.net/ + * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) + * Charles Poynton poynton at poynton.com + * + * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B + * + * which can be expressed with integers as + * + * Y = (6969 * R + 23434 * G + 2365 * B)/32768 + * + * Poynton's current link (as of January 2003 through July 2011): + * + * has changed the numbers slightly: + * + * Y = 0.2126*R + 0.7152*G + 0.0722*B + * + * which can be expressed with integers as + * + * Y = (6966 * R + 23436 * G + 2366 * B)/32768 + * + * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 + * end point chromaticities and the D65 white point. Depending on the + * precision used for the D65 white point this produces a variety of different + * numbers, however if the four decimal place value used in ITU-R Rec 709 is + * used (0.3127,0.3290) the Y calculation would be: + * + * Y = (6968 * R + 23435 * G + 2366 * B)/32768 + * + * While this is correct the rounding results in an overflow for white, because + * the sum of the rounded coefficients is 32769, not 32768. Consequently + * libpng uses, instead, the closest non-overflowing approximation: + * + * Y = (6968 * R + 23434 * G + 2366 * B)/32768 + * + * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk + * (including an sRGB chunk) then the chromaticities are used to calculate the + * coefficients. See the chunk handling in pngrutil.c for more information. + * + * In all cases the calculation is to be done in a linear colorspace. If no + * gamma information is available to correct the encoding of the original RGB + * values this results in an implicit assumption that the original PNG RGB + * values were linear. + * + * Other integer coefficients can be used via png_set_rgb_to_gray(). Because + * the API takes just red and green coefficients the blue coefficient is + * calculated to make the sum 32768. This will result in different rounding + * to that used above. + */ +static int +png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) +{ + int rgb_error = 0; + + png_debug(1, "in png_do_rgb_to_gray"); + + if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && + (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + png_uint_32 bc = 32768 - rc - gc; + png_uint_32 row_width = row_info->width; + int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; + + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + /* Notice that gamma to/from 1 are not necessarily inverses (if + * there is an overall gamma correction). Prior to 1.5.5 this code + * checked the linearized values for equality; this doesn't match + * the documentation, the original values must be checked. + */ + if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + + if (red != green || red != blue) + { + red = png_ptr->gamma_to_1[red]; + green = png_ptr->gamma_to_1[green]; + blue = png_ptr->gamma_to_1[blue]; + + rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1[ + (rc*red + gc*green + bc*blue + 16384)>>15]; + } + + else + { + /* If there is no overall correction the table will not be + * set. + */ + if (png_ptr->gamma_table != NULL) + red = png_ptr->gamma_table[red]; + + *(dp++) = red; + } + + if (have_alpha != 0) + *(dp++) = *(sp++); + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_byte red = *(sp++); + png_byte green = *(sp++); + png_byte blue = *(sp++); + + if (red != green || red != blue) + { + rgb_error |= 1; + /* NOTE: this is the historical approach which simply + * truncates the results. + */ + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); + } + + else + *(dp++) = red; + + if (have_alpha != 0) + *(dp++) = *(sp++); + } + } + } + + else /* RGB bit_depth == 16 */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, w; + png_byte hi,lo; + + hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); + + if (red == green && red == blue) + { + if (png_ptr->gamma_16_table != NULL) + w = png_ptr->gamma_16_table[(red & 0xff) + >> png_ptr->gamma_shift][red >> 8]; + + else + w = red; + } + + else + { + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff) + >> png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = + png_ptr->gamma_16_to_1[(green & 0xff) >> + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff) + >> png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + + bc*blue_1 + 16384)>>15); + w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >> + png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; + } + + *(dp++) = (png_byte)((w>>8) & 0xff); + *(dp++) = (png_byte)(w & 0xff); + + if (have_alpha != 0) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + else +#endif + { + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + png_uint_16 red, green, blue, gray16; + png_byte hi,lo; + + hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); + + if (red != green || red != blue) + rgb_error |= 1; + + /* From 1.5.5 in the 16-bit case do the accurate conversion even + * in the 'fast' case - this is because this is where the code + * ends up when handling linear 16-bit data. + */ + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> + 15); + *(dp++) = (png_byte)((gray16 >> 8) & 0xff); + *(dp++) = (png_byte)(gray16 & 0xff); + + if (have_alpha != 0) + { + *(dp++) = *(sp++); + *(dp++) = *(sp++); + } + } + } + } + + row_info->channels = (png_byte)(row_info->channels - 2); + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_COLOR); + row_info->pixel_depth = (png_byte)(row_info->channels * + row_info->bit_depth); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + return rgb_error; +} +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) +/* Replace any alpha or transparency with the supplied background color. + * "background" is already in the screen gamma, while "background_1" is + * at a gamma of 1.0. Paletted files have already been taken care of. + */ +static void +png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) +{ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; + png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; + png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; + png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; + png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; + int gamma_shift = png_ptr->gamma_shift; + int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; +#endif + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + int shift; + + png_debug(1, "in png_do_compose"); + + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_GRAY: + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row; + shift = 7; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x01) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 7; + sp++; + } + + else + shift--; + } + break; + } + + case 2: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= + (unsigned int)png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); + } + + else + { + unsigned int p = (*sp >> shift) & 0x03; + unsigned int g = (gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03; + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= (unsigned int)(g << shift); + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + + else +#endif + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= + (unsigned int)png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + break; + } + + case 4: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); + *sp = (png_byte)(tmp & 0xff); + } + + else + { + unsigned int p = (*sp >> shift) & 0x0f; + unsigned int g = (gamma_table[p | (p << 4)] >> 4) & + 0x0f; + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= (unsigned int)(g << shift); + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + + else +#endif + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + break; + } + + case 8: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + + else + *sp = gamma_table[*sp]; + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + } + } + break; + } + + case 16: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + if (v == png_ptr->trans_color.gray) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray + & 0xff); + } + + else + { + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 v; + + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + if (v == png_ptr->trans_color.gray) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray + & 0xff); + } + } + } + break; + } + + default: + break; + } + break; + } + + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + if (r == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + if (r == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 a = *(sp + 1); + + if (a == 0xff) + *sp = gamma_table[*sp]; + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.gray; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.gray); + if (optimize == 0) + w = gamma_from_1[w]; + *sp = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_byte a = *(sp + 1); + + if (a == 0) + *sp = (png_byte)png_ptr->background.gray; + + else if (a < 0xff) + png_composite(*sp, *sp, a, png_ptr->background.gray); + } + } + } + else /* if (png_ptr->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else + { + png_uint_16 g, v, w; + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, png_ptr->background_1.gray); + if (optimize != 0) + w = v; + else + w = gamma_16_from_1[(v & 0xff) >> + gamma_shift][v >> 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_composite_16(v, g, a, png_ptr->background.gray); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.red); + if (optimize == 0) w = gamma_from_1[w]; + *sp = w; + + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, png_ptr->background_1.green); + if (optimize == 0) w = gamma_from_1[w]; + *(sp + 1) = w; + + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, png_ptr->background_1.blue); + if (optimize == 0) w = gamma_from_1[w]; + *(sp + 2) = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else if (a < 0xff) + { + png_composite(*sp, *sp, a, png_ptr->background.red); + + png_composite(*(sp + 1), *(sp + 1), a, + png_ptr->background.green); + + png_composite(*(sp + 2), *(sp + 2), a, + png_ptr->background.blue); + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v, w; + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, png_ptr->background_1.red); + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, png_ptr->background_1.green); + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; + + *(sp + 2) = (png_byte)((w >> 8) & 0xff); + *(sp + 3) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, png_ptr->background_1.blue); + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; + + *(sp + 4) = (png_byte)((w >> 8) & 0xff); + *(sp + 5) = (png_byte)(w & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 v; + + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + png_composite_16(v, r, a, png_ptr->background.red); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + png_composite_16(v, g, a, png_ptr->background.green); + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + png_composite_16(v, b, a, png_ptr->background.blue); + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + default: + break; + } +} +#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Gamma correct the image, avoiding the alpha channel. Make sure + * you do this after you deal with the transparency issue on grayscale + * or RGB images. If your bit depth is 8, use gamma_table, if it + * is 16, use gamma_16_table and gamma_shift. Build these with + * build_gamma_table(). + */ +static void +png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) +{ + png_const_bytep gamma_table = png_ptr->gamma_table; + png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; + int gamma_shift = png_ptr->gamma_shift; + + png_bytep sp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_gamma"); + + if (((row_info->bit_depth <= 8 && gamma_table != NULL) || + (row_info->bit_depth == 16 && gamma_16_table != NULL))) + { + switch (row_info->color_type) + { + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + *sp = gamma_table[*sp]; + sp++; + } + } + + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + + *sp = gamma_table[*sp]; + sp++; + + *sp = gamma_table[*sp]; + sp++; + + sp++; + } + } + + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp += 2; + } + } + + else /* if (row_info->bit_depth == 16) */ + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 4; + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY: + { + if (row_info->bit_depth == 2) + { + sp = row; + for (i = 0; i < row_width; i += 4) + { + int a = *sp & 0xc0; + int b = *sp & 0x30; + int c = *sp & 0x0c; + int d = *sp & 0x03; + + *sp = (png_byte)( + ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| + ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| + ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| + ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); + sp++; + } + } + + if (row_info->bit_depth == 4) + { + sp = row; + for (i = 0; i < row_width; i += 2) + { + int msb = *sp & 0xf0; + int lsb = *sp & 0x0f; + + *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) + | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); + sp++; + } + } + + else if (row_info->bit_depth == 8) + { + sp = row; + for (i = 0; i < row_width; i++) + { + *sp = gamma_table[*sp]; + sp++; + } + } + + else if (row_info->bit_depth == 16) + { + sp = row; + for (i = 0; i < row_width; i++) + { + png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + sp += 2; + } + } + break; + } + + default: + break; + } + } +} +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED +/* Encode the alpha channel to the output gamma (the input channel is always + * linear.) Called only with color types that have an alpha channel. Needs the + * from_1 tables. + */ +static void +png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) +{ + png_uint_32 row_width = row_info->width; + + png_debug(1, "in png_do_encode_alpha"); + + if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + if (row_info->bit_depth == 8) + { + png_bytep table = png_ptr->gamma_from_1; + + if (table != NULL) + { + int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; + + /* The alpha channel is the last component: */ + row += step - 1; + + for (; row_width > 0; --row_width, row += step) + *row = table[*row]; + + return; + } + } + + else if (row_info->bit_depth == 16) + { + png_uint_16pp table = png_ptr->gamma_16_from_1; + int gamma_shift = png_ptr->gamma_shift; + + if (table != NULL) + { + int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; + + /* The alpha channel is the last component: */ + row += step - 2; + + for (; row_width > 0; --row_width, row += step) + { + png_uint_16 v; + + v = table[*(row + 1) >> gamma_shift][*row]; + *row = (png_byte)((v >> 8) & 0xff); + *(row + 1) = (png_byte)(v & 0xff); + } + + return; + } + } + } + + /* Only get to here if called with a weird row_info; no harm has been done, + * so just issue a warning. + */ + png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); +} +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED +/* Expands a palette row to an RGB or RGBA row depending + * upon whether you supply trans and num_trans. + */ +static void +png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, + png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, + int num_trans) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand_palette"); + + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + sp = row + (size_t)((row_width - 1) >> 3); + dp = row + (size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 1; + + else + *dp = 0; + + if (shift == 7) + { + shift = 0; + sp--; + } + + else + shift++; + + dp--; + } + break; + } + + case 2: + { + sp = row + (size_t)((row_width - 1) >> 2); + dp = row + (size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)value; + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + sp = row + (size_t)((row_width - 1) >> 1); + dp = row + (size_t)row_width - 1; + shift = (int)((row_width & 0x01) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)value; + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift += 4; + + dp--; + } + break; + } + + default: + break; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (row_info->bit_depth == 8) + { + { + if (num_trans > 0) + { + sp = row + (size_t)row_width - 1; + dp = row + ((size_t)row_width << 2) - 1; + + i = 0; +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE + if (png_ptr->riffled_palette != NULL) + { + /* The RGBA optimization works with png_ptr->bit_depth == 8 + * but sometimes row_info->bit_depth has been changed to 8. + * In these cases, the palette hasn't been riffled. + */ + i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row, + &sp, &dp); + } +#else + PNG_UNUSED(png_ptr) +#endif + + for (; i < row_width; i++) + { + if ((int)(*sp) >= num_trans) + *dp-- = 0xff; + else + *dp-- = trans_alpha[*sp]; + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + row_info->bit_depth = 8; + row_info->pixel_depth = 32; + row_info->rowbytes = (size_t)row_width * 4; + row_info->color_type = 6; + row_info->channels = 4; + } + + else + { + sp = row + (size_t)row_width - 1; + dp = row + (size_t)row_width * 3 - 1; + i = 0; +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE + i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row, + &sp, &dp); +#else + PNG_UNUSED(png_ptr) +#endif + + for (; i < row_width; i++) + { + *dp-- = palette[*sp].blue; + *dp-- = palette[*sp].green; + *dp-- = palette[*sp].red; + sp--; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = 24; + row_info->rowbytes = (size_t)row_width * 3; + row_info->color_type = 2; + row_info->channels = 3; + } + } + } + } +} + +/* If the bit depth < 8, it is expanded to 8. Also, if the already + * expanded transparency value is supplied, an alpha channel is built. + */ +static void +png_do_expand(png_row_infop row_info, png_bytep row, + png_const_color_16p trans_color) +{ + int shift, value; + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_expand"); + + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + unsigned int gray = trans_color != NULL ? trans_color->gray : 0; + + if (row_info->bit_depth < 8) + { + switch (row_info->bit_depth) + { + case 1: + { + gray = (gray & 0x01) * 0xff; + sp = row + (size_t)((row_width - 1) >> 3); + dp = row + (size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + if ((*sp >> shift) & 0x01) + *dp = 0xff; + + else + *dp = 0; + + if (shift == 7) + { + shift = 0; + sp--; + } + + else + shift++; + + dp--; + } + break; + } + + case 2: + { + gray = (gray & 0x03) * 0x55; + sp = row + (size_t)((row_width - 1) >> 2); + dp = row + (size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)(value | (value << 2) | (value << 4) | + (value << 6)); + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + gray = (gray & 0x0f) * 0x11; + sp = row + (size_t)((row_width - 1) >> 1); + dp = row + (size_t)row_width - 1; + shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)(value | (value << 4)); + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift = 4; + + dp--; + } + break; + } + + default: + break; + } + + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; + } + + if (trans_color != NULL) + { + if (row_info->bit_depth == 8) + { + gray = gray & 0xff; + sp = row + (size_t)row_width - 1; + dp = row + ((size_t)row_width << 1) - 1; + + for (i = 0; i < row_width; i++) + { + if ((*sp & 0xffU) == gray) + *dp-- = 0; + + else + *dp-- = 0xff; + + *dp-- = *sp--; + } + } + + else if (row_info->bit_depth == 16) + { + unsigned int gray_high = (gray >> 8) & 0xff; + unsigned int gray_low = gray & 0xff; + sp = row + row_info->rowbytes - 1; + dp = row + (row_info->rowbytes << 1) - 1; + for (i = 0; i < row_width; i++) + { + if ((*(sp - 1) & 0xffU) == gray_high && + (*(sp) & 0xffU) == gray_low) + { + *dp-- = 0; + *dp-- = 0; + } + + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + + *dp-- = *sp--; + *dp-- = *sp--; + } + } + + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + row_info->channels = 2; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_width); + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && + trans_color != NULL) + { + if (row_info->bit_depth == 8) + { + png_byte red = (png_byte)(trans_color->red & 0xff); + png_byte green = (png_byte)(trans_color->green & 0xff); + png_byte blue = (png_byte)(trans_color->blue & 0xff); + sp = row + (size_t)row_info->rowbytes - 1; + dp = row + ((size_t)row_width << 2) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) + *dp-- = 0; + + else + *dp-- = 0xff; + + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); + png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); + png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); + png_byte red_low = (png_byte)(trans_color->red & 0xff); + png_byte green_low = (png_byte)(trans_color->green & 0xff); + png_byte blue_low = (png_byte)(trans_color->blue & 0xff); + sp = row + row_info->rowbytes - 1; + dp = row + ((size_t)row_width << 3) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 5) == red_high && + *(sp - 4) == red_low && + *(sp - 3) == green_high && + *(sp - 2) == green_low && + *(sp - 1) == blue_high && + *(sp ) == blue_low) + { + *dp-- = 0; + *dp-- = 0; + } + + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + row_info->channels = 4; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } +} +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED +/* If the bit depth is 8 and the color type is not a palette type expand the + * whole row to 16 bits. Has no effect otherwise. + */ +static void +png_do_expand_16(png_row_infop row_info, png_bytep row) +{ + if (row_info->bit_depth == 8 && + row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + /* The row have a sequence of bytes containing [0..255] and we need + * to turn it into another row containing [0..65535], to do this we + * calculate: + * + * (input / 255) * 65535 + * + * Which happens to be exactly input * 257 and this can be achieved + * simply by byte replication in place (copying backwards). + */ + png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ + png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ + while (dp > sp) + { + dp[-2] = dp[-1] = *--sp; dp -= 2; + } + + row_info->rowbytes *= 2; + row_info->bit_depth = 16; + row_info->pixel_depth = (png_byte)(row_info->channels * 16); + } +} +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +static void +png_do_quantize(png_row_infop row_info, png_bytep row, + png_const_bytep palette_lookup, png_const_bytep quantize_lookup) +{ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width=row_info->width; + + png_debug(1, "in png_do_quantize"); + + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + + /* This looks real messy, but the compiler will reduce + * it down to a reasonable formula. For example, with + * 5 bits per color, we get: + * p = (((r >> 3) & 0x1f) << 10) | + * (((g >> 3) & 0x1f) << 5) | + * ((b >> 3) & 0x1f); + */ + p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + palette_lookup != NULL) + { + int r, g, b, p; + sp = row; + dp = row; + for (i = 0; i < row_width; i++) + { + r = *sp++; + g = *sp++; + b = *sp++; + sp++; + + p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); + + *dp++ = palette_lookup[p]; + } + + row_info->color_type = PNG_COLOR_TYPE_PALETTE; + row_info->channels = 1; + row_info->pixel_depth = row_info->bit_depth; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } + + else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + quantize_lookup) + { + sp = row; + + for (i = 0; i < row_width; i++, sp++) + { + *sp = quantize_lookup[*sp]; + } + } + } +} +#endif /* READ_QUANTIZE */ + +/* Transform the row. The order of transformations is significant, + * and is very touchy. If you add a transformation, take care to + * decide how it fits in with the other transformations here. + */ +void /* PRIVATE */ +png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) +{ + png_debug(1, "in png_do_read_transformations"); + + if (png_ptr->row_buf == NULL) + { + /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this + * error is incredibly rare and incredibly easy to debug without this + * information. + */ + png_error(png_ptr, "NULL row buffer"); + } + + /* The following is debugging; prior to 1.5.4 the code was never compiled in; + * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro + * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for + * all transformations, however in practice the ROW_INIT always gets done on + * demand, if necessary. + */ + if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && + (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + /* Application has failed to call either png_read_start_image() or + * png_read_update_info() after setting transforms that expand pixels. + * This check added to libpng-1.2.19 (but not enabled until 1.5.4). + */ + png_error(png_ptr, "Uninitialized row"); + } + +#ifdef PNG_READ_EXPAND_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE + if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) + { + if (png_ptr->riffled_palette == NULL) + { + /* Initialize the accelerated palette expansion. */ + png_ptr->riffled_palette = + (png_bytep)png_malloc(png_ptr, 256 * 4); + png_riffle_palette_neon(png_ptr); + } + } +#endif + png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); + } + + else + { + if (png_ptr->num_trans != 0 && + (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) + png_do_expand(row_info, png_ptr->row_buf + 1, + &(png_ptr->trans_color)); + + else + png_do_expand(row_info, png_ptr->row_buf + 1, NULL); + } + } +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) == 0 && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + { + int rgb_error = + png_do_rgb_to_gray(png_ptr, row_info, + png_ptr->row_buf + 1); + + if (rgb_error != 0) + { + png_ptr->rgb_to_gray_status=1; + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_WARN) + png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_ERR) + png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + } + } +#endif + +/* From Andreas Dilger e-mail to png-implement, 26 March 1998: + * + * In most cases, the "simple transparency" should be done prior to doing + * gray-to-RGB, or you will have to test 3x as many bytes to check if a + * pixel is transparent. You would also need to make sure that the + * transparency information is upgraded to RGB. + * + * To summarize, the current flow is: + * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + * with background "in place" if transparent, + * convert to RGB if necessary + * - Gray + alpha -> composite with gray background and remove alpha bytes, + * convert to RGB if necessary + * + * To support RGB backgrounds for gray images we need: + * - Gray + simple transparency -> convert to RGB + simple transparency, + * compare 3 or 6 bytes and composite with + * background "in place" if transparent + * (3x compare/pixel compared to doing + * composite with gray bkgrnd) + * - Gray + alpha -> convert to RGB + alpha, composite with background and + * remove alpha bytes (3x float + * operations/pixel compared with composite + * on gray background) + * + * Greg's change will do this. The reason it wasn't done before is for + * performance, as this increases the per-pixel operations. If we would check + * in advance if the background was gray or RGB, and position the gray-to-RGB + * transform appropriately, then it would save a lot of work/time. + */ + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* If gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons + */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + if ((png_ptr->transformations & PNG_GAMMA) != 0 && +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Because RGB_TO_GRAY does the gamma transform. */ + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* Because PNG_COMPOSE does the gamma transform if there is something to + * do (if there is an alpha channel or transparency.) + */ + !((png_ptr->transformations & PNG_COMPOSE) != 0 && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && +#endif + /* Because png_init_read_transformations transforms the palette, unless + * RGB_TO_GRAY will do the transform. + */ + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && + (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) + png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* There is no harm in doing both of these because only one has any effect, + * by putting the 'scale' option first if the app asks for scale (either by + * calling the API or in a TRANSFORM flag) this is what happens. + */ + if ((png_ptr->transformations & PNG_16_TO_8) != 0) + png_do_chop(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if ((png_ptr->transformations & PNG_QUANTIZE) != 0) + png_do_quantize(row_info, png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->quantize_index); +#endif /* READ_QUANTIZE */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Do the expansion now, after all the arithmetic has been done. Notice + * that previous transformations can handle the PNG_EXPAND_16 flag if this + * is efficient (particularly true in the case of gamma correction, where + * better accuracy results faster!) + */ + if ((png_ptr->transformations & PNG_EXPAND_16) != 0) + png_do_expand_16(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* NOTE: moved here in 1.5.4 (from much later in this list.) */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_do_unshift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0) + png_do_unpack(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Added at libpng-1.5.10 */ + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, row_info); +#endif + +#ifdef PNG_READ_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_do_read_filler(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) + png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_16BIT_SUPPORTED +#ifdef PNG_READ_SWAP_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { + if (png_ptr->read_user_transform_fn != NULL) + (*(png_ptr->read_user_transform_fn)) /* User read transform function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + if (png_ptr->user_transform_depth != 0) + row_info->bit_depth = png_ptr->user_transform_depth; + + if (png_ptr->user_transform_channels != 0) + row_info->channels = png_ptr->user_transform_channels; +#endif + row_info->pixel_depth = (png_byte)(row_info->bit_depth * + row_info->channels); + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); + } +#endif +} + +#endif /* READ_TRANSFORMS */ +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/pngrutil.c b/thirdparty/libpng/upstream/pngrutil.c index 236e982f1..3a35fe9de 100644 --- a/thirdparty/libpng/upstream/pngrutil.c +++ b/thirdparty/libpng/upstream/pngrutil.c @@ -1,4680 +1,4683 @@ - -/* pngrutil.c - utilities to read a PNG file - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that are only called from within - * libpng itself during the course of reading an image. - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -png_uint_32 PNGAPI -png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range"); - - return uval; -} - -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) -/* The following is a variation on the above for use with the fixed - * point values used for gAMA and cHRM. Instead of png_error it - * issues a warning and returns (-1) - an invalid value because both - * gAMA and cHRM use *unsigned* integers for fixed point values. - */ -#define PNG_FIXED_ERROR (-1) - -static png_fixed_point /* PRIVATE */ -png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval <= PNG_UINT_31_MAX) - return (png_fixed_point)uval; /* known to be in range */ - - /* The caller can turn off the warning by passing NULL. */ - if (png_ptr != NULL) - png_warning(png_ptr, "PNG fixed point integer out of range"); - - return PNG_FIXED_ERROR; -} -#endif - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -/* NOTE: the read macros will obscure these definitions, so that if - * PNG_USE_READ_MACROS is set the library will not use them internally, - * but the APIs will still be available externally. - * - * The parentheses around "PNGAPI function_name" in the following three - * functions are necessary because they allow the macros to co-exist with - * these (unused but exported) functions. - */ - -/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ -png_uint_32 (PNGAPI -png_get_uint_32)(png_const_bytep buf) -{ - png_uint_32 uval = - ((png_uint_32)(*(buf )) << 24) + - ((png_uint_32)(*(buf + 1)) << 16) + - ((png_uint_32)(*(buf + 2)) << 8) + - ((png_uint_32)(*(buf + 3)) ) ; - - return uval; -} - -/* Grab a signed 32-bit integer from a buffer in big-endian format. The - * data is stored in the PNG file in two's complement format and there - * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore - * the following code does a two's complement to native conversion. - */ -png_int_32 (PNGAPI -png_get_int_32)(png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - if ((uval & 0x80000000) == 0) /* non-negative */ - return (png_int_32)uval; - - uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ - if ((uval & 0x80000000) == 0) /* no overflow */ - return -(png_int_32)uval; - /* The following has to be safe; this function only gets called on PNG data - * and if we get here that data is invalid. 0 is the most safe value and - * if not then an attacker would surely just generate a PNG with 0 instead. - */ - return 0; -} - -/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ -png_uint_16 (PNGAPI -png_get_uint_16)(png_const_bytep buf) -{ - /* ANSI-C requires an int value to accommodate at least 16 bits so this - * works and allows the compiler not to worry about possible narrowing - * on 32-bit systems. (Pre-ANSI systems did not make integers smaller - * than 16 bits either.) - */ - unsigned int val = - ((unsigned int)(*buf) << 8) + - ((unsigned int)(*(buf + 1))); - - return (png_uint_16)val; -} - -#endif /* READ_INT_FUNCTIONS */ - -/* Read and check the PNG file signature */ -void /* PRIVATE */ -png_read_sig(png_structrp png_ptr, png_inforp info_ptr) -{ - size_t num_checked, num_to_check; - - /* Exit if the user application does not expect a signature. */ - if (png_ptr->sig_bytes >= 8) - return; - - num_checked = png_ptr->sig_bytes; - num_to_check = 8 - num_checked; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; -#endif - - /* The signature must be serialized in a single I/O call. */ - png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); - png_ptr->sig_bytes = 8; - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) - png_error(png_ptr, "Not a PNG file"); - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - if (num_checked < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Read the chunk header (length + type name). - * Put the type name into png_ptr->chunk_name, and return the length. - */ -png_uint_32 /* PRIVATE */ -png_read_chunk_header(png_structrp png_ptr) -{ - png_byte buf[8]; - png_uint_32 length; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; -#endif - - /* Read the length and the chunk name. - * This must be performed in a single I/O call. - */ - png_read_data(png_ptr, buf, 8); - length = png_get_uint_31(png_ptr, buf); - - /* Put the chunk name into png_ptr->chunk_name. */ - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - - png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu", - (unsigned long)png_ptr->chunk_name, (unsigned long)length); - - /* Reset the crc and run it over the chunk name. */ - png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, buf + 4, 4); - - /* Check to see if chunk name is valid. */ - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - - /* Check for too-large chunk length */ - png_check_chunk_length(png_ptr, length); - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; -#endif - - return length; -} - -/* Read data, and (optionally) run it through the CRC. */ -void /* PRIVATE */ -png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) -{ - if (png_ptr == NULL) - return; - - png_read_data(png_ptr, buf, length); - png_calculate_crc(png_ptr, buf, length); -} - -/* Optionally skip data and then check the CRC. Depending on whether we - * are reading an ancillary or critical chunk, and how the program has set - * things up, we may calculate the CRC on the data and print a message. - * Returns '1' if there was a CRC error, '0' otherwise. - */ -int /* PRIVATE */ -png_crc_finish(png_structrp png_ptr, png_uint_32 skip) -{ - /* The size of the local buffer for inflate is a good guess as to a - * reasonable size to use for buffering reads from the application. - */ - while (skip > 0) - { - png_uint_32 len; - png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; - - len = (sizeof tmpbuf); - if (len > skip) - len = skip; - skip -= len; - - png_crc_read(png_ptr, tmpbuf, len); - } - - if (png_crc_error(png_ptr) != 0) - { - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? - (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : - (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) - { - png_chunk_warning(png_ptr, "CRC error"); - } - - else - png_chunk_error(png_ptr, "CRC error"); - - return 1; - } - - return 0; -} - -/* Compare the CRC stored in the PNG file with that calculated by libpng from - * the data it has read thus far. - */ -int /* PRIVATE */ -png_crc_error(png_structrp png_ptr) -{ - png_byte crc_bytes[4]; - png_uint_32 crc; - int need_crc = 1; - - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; -#endif - - /* The chunk CRC must be serialized in a single I/O call. */ - png_read_data(png_ptr, crc_bytes, 4); - - if (need_crc != 0) - { - crc = png_get_uint_32(crc_bytes); - return crc != png_ptr->crc; - } - - else - return 0; -} - -#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ - defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ - defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) -/* Manage the read buffer; this simply reallocates the buffer if it is not small - * enough (or if it is not allocated). The routine returns a pointer to the - * buffer; if an error occurs and 'warn' is set the routine returns NULL, else - * it will call png_error (via png_malloc) on failure. (warn == 2 means - * 'silent'). - */ -static png_bytep -png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) -{ - png_bytep buffer = png_ptr->read_buffer; - - if (buffer != NULL && new_size > png_ptr->read_buffer_size) - { - png_ptr->read_buffer = NULL; - png_ptr->read_buffer_size = 0; - png_free(png_ptr, buffer); - buffer = NULL; - } - - if (buffer == NULL) - { - buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); - - if (buffer != NULL) - { - memset(buffer, 0, new_size); /* just in case */ - png_ptr->read_buffer = buffer; - png_ptr->read_buffer_size = new_size; - } - - else if (warn < 2) /* else silent */ - { - if (warn != 0) - png_chunk_warning(png_ptr, "insufficient memory to read chunk"); - - else - png_chunk_error(png_ptr, "insufficient memory to read chunk"); - } - } - - return buffer; -} -#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ - -/* png_inflate_claim: claim the zstream for some nefarious purpose that involves - * decompression. Returns Z_OK on success, else a zlib error code. It checks - * the owner but, in final release builds, just issues a warning if some other - * chunk apparently owns the stream. Prior to release it does a png_error. - */ -static int -png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) -{ - if (png_ptr->zowner != 0) - { - char msg[64]; - - PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); - /* So the message that results is " using zstream"; this is an - * internal error, but is very useful for debugging. i18n requirements - * are minimal. - */ - (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); -#if PNG_RELEASE_BUILD - png_chunk_warning(png_ptr, msg); - png_ptr->zowner = 0; -#else - png_chunk_error(png_ptr, msg); -#endif - } - - /* Implementation note: unlike 'png_deflate_claim' this internal function - * does not take the size of the data as an argument. Some efficiency could - * be gained by using this when it is known *if* the zlib stream itself does - * not record the number; however, this is an illusion: the original writer - * of the PNG may have selected a lower window size, and we really must - * follow that because, for systems with with limited capabilities, we - * would otherwise reject the application's attempts to use a smaller window - * size (zlib doesn't have an interface to say "this or lower"!). - * - * inflateReset2 was added to zlib 1.2.4; before this the window could not be - * reset, therefore it is necessary to always allocate the maximum window - * size with earlier zlibs just in case later compressed chunks need it. - */ - { - int ret; /* zlib return code */ -#if ZLIB_VERNUM >= 0x1240 - int window_bits = 0; - -# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) - if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == - PNG_OPTION_ON) - { - window_bits = 15; - png_ptr->zstream_start = 0; /* fixed window size */ - } - - else - { - png_ptr->zstream_start = 1; - } -# endif - -#endif /* ZLIB_VERNUM >= 0x1240 */ - - /* Set this for safety, just in case the previous owner left pointers to - * memory allocations. - */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0; - - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - { -#if ZLIB_VERNUM >= 0x1240 - ret = inflateReset2(&png_ptr->zstream, window_bits); -#else - ret = inflateReset(&png_ptr->zstream); -#endif - } - - else - { -#if ZLIB_VERNUM >= 0x1240 - ret = inflateInit2(&png_ptr->zstream, window_bits); -#else - ret = inflateInit(&png_ptr->zstream); -#endif - - if (ret == Z_OK) - png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; - } - -#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED - if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) - /* Turn off validation of the ADLER32 checksum in IDAT chunks */ - ret = inflateValidate(&png_ptr->zstream, 0); -#endif - - if (ret == Z_OK) - png_ptr->zowner = owner; - - else - png_zstream_error(png_ptr, ret); - - return ret; - } - -#ifdef window_bits -# undef window_bits -#endif -} - -#if ZLIB_VERNUM >= 0x1240 -/* Handle the start of the inflate stream if we called inflateInit2(strm,0); - * in this case some zlib versions skip validation of the CINFO field and, in - * certain circumstances, libpng may end up displaying an invalid image, in - * contrast to implementations that call zlib in the normal way (e.g. libpng - * 1.5). - */ -int /* PRIVATE */ -png_zlib_inflate(png_structrp png_ptr, int flush) -{ - if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0) - { - if ((*png_ptr->zstream.next_in >> 4) > 7) - { - png_ptr->zstream.msg = "invalid window size (libpng)"; - return Z_DATA_ERROR; - } - - png_ptr->zstream_start = 0; - } - - return inflate(&png_ptr->zstream, flush); -} -#endif /* Zlib >= 1.2.4 */ - -#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED -#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED) -/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to - * allow the caller to do multiple calls if required. If the 'finish' flag is - * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must - * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and - * Z_OK or Z_STREAM_END will be returned on success. - * - * The input and output sizes are updated to the actual amounts of data consumed - * or written, not the amount available (as in a z_stream). The data pointers - * are not changed, so the next input is (data+input_size) and the next - * available output is (output+output_size). - */ -static int -png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, - /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, - /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) -{ - if (png_ptr->zowner == owner) /* Else not claimed */ - { - int ret; - png_alloc_size_t avail_out = *output_size_ptr; - png_uint_32 avail_in = *input_size_ptr; - - /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it - * can't even necessarily handle 65536 bytes) because the type uInt is - * "16 bits or more". Consequently it is necessary to chunk the input to - * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the - * maximum value that can be stored in a uInt.) It is possible to set - * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have - * a performance advantage, because it reduces the amount of data accessed - * at each step and that may give the OS more time to page it in. - */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); - /* avail_in and avail_out are set below from 'size' */ - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.avail_out = 0; - - /* Read directly into the output if it is available (this is set to - * a local buffer below if output is NULL). - */ - if (output != NULL) - png_ptr->zstream.next_out = output; - - do - { - uInt avail; - Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - - /* zlib INPUT BUFFER */ - /* The setting of 'avail_in' used to be outside the loop; by setting it - * inside it is possible to chunk the input to zlib and simply rely on - * zlib to advance the 'next_in' pointer. This allows arbitrary - * amounts of data to be passed through zlib at the unavoidable cost of - * requiring a window save (memcpy of up to 32768 output bytes) - * every ZLIB_IO_MAX input bytes. - */ - avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ - - avail = ZLIB_IO_MAX; - - if (avail_in < avail) - avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ - - avail_in -= avail; - png_ptr->zstream.avail_in = avail; - - /* zlib OUTPUT BUFFER */ - avail_out += png_ptr->zstream.avail_out; /* not written last time */ - - avail = ZLIB_IO_MAX; /* maximum zlib can process */ - - if (output == NULL) - { - /* Reset the output buffer each time round if output is NULL and - * make available the full buffer, up to 'remaining_space' - */ - png_ptr->zstream.next_out = local_buffer; - if ((sizeof local_buffer) < avail) - avail = (sizeof local_buffer); - } - - if (avail_out < avail) - avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ - - png_ptr->zstream.avail_out = avail; - avail_out -= avail; - - /* zlib inflate call */ - /* In fact 'avail_out' may be 0 at this point, that happens at the end - * of the read when the final LZ end code was not passed at the end of - * the previous chunk of input data. Tell zlib if we have reached the - * end of the output buffer. - */ - ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH : - (finish ? Z_FINISH : Z_SYNC_FLUSH)); - } while (ret == Z_OK); - - /* For safety kill the local buffer pointer now */ - if (output == NULL) - png_ptr->zstream.next_out = NULL; - - /* Claw back the 'size' and 'remaining_space' byte counts. */ - avail_in += png_ptr->zstream.avail_in; - avail_out += png_ptr->zstream.avail_out; - - /* Update the input and output sizes; the updated values are the amount - * consumed or written, effectively the inverse of what zlib uses. - */ - if (avail_out > 0) - *output_size_ptr -= avail_out; - - if (avail_in > 0) - *input_size_ptr -= avail_in; - - /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ - png_zstream_error(png_ptr, ret); - return ret; - } - - else - { - /* This is a bad internal error. The recovery assigns to the zstream msg - * pointer, which is not owned by the caller, but this is safe; it's only - * used on errors! - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); - return Z_STREAM_ERROR; - } -} - -/* - * Decompress trailing data in a chunk. The assumption is that read_buffer - * points at an allocated area holding the contents of a chunk with a - * trailing compressed part. What we get back is an allocated area - * holding the original prefix part and an uncompressed version of the - * trailing part (the malloc area passed in is freed). - */ -static int -png_decompress_chunk(png_structrp png_ptr, - png_uint_32 chunklength, png_uint_32 prefix_size, - png_alloc_size_t *newlength /* must be initialized to the maximum! */, - int terminate /*add a '\0' to the end of the uncompressed data*/) -{ - /* TODO: implement different limits for different types of chunk. - * - * The caller supplies *newlength set to the maximum length of the - * uncompressed data, but this routine allocates space for the prefix and - * maybe a '\0' terminator too. We have to assume that 'prefix_size' is - * limited only by the maximum chunk size. - */ - png_alloc_size_t limit = PNG_SIZE_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - - if (limit >= prefix_size + (terminate != 0)) - { - int ret; - - limit -= prefix_size + (terminate != 0); - - if (limit < *newlength) - *newlength = limit; - - /* Now try to claim the stream. */ - ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); - - if (ret == Z_OK) - { - png_uint_32 lzsize = chunklength - prefix_size; - - ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, - /* output: */ NULL, newlength); - - if (ret == Z_STREAM_END) - { - /* Use 'inflateReset' here, not 'inflateReset2' because this - * preserves the previously decided window size (otherwise it would - * be necessary to store the previous window size.) In practice - * this doesn't matter anyway, because png_inflate will call inflate - * with Z_FINISH in almost all cases, so the window will not be - * maintained. - */ - if (inflateReset(&png_ptr->zstream) == Z_OK) - { - /* Because of the limit checks above we know that the new, - * expanded, size will fit in a size_t (let alone an - * png_alloc_size_t). Use png_malloc_base here to avoid an - * extra OOM message. - */ - png_alloc_size_t new_size = *newlength; - png_alloc_size_t buffer_size = prefix_size + new_size + - (terminate != 0); - png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, - buffer_size)); - - if (text != NULL) - { - memset(text, 0, buffer_size); - - ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - png_ptr->read_buffer + prefix_size, &lzsize, - text + prefix_size, newlength); - - if (ret == Z_STREAM_END) - { - if (new_size == *newlength) - { - if (terminate != 0) - text[prefix_size + *newlength] = 0; - - if (prefix_size > 0) - memcpy(text, png_ptr->read_buffer, prefix_size); - - { - png_bytep old_ptr = png_ptr->read_buffer; - - png_ptr->read_buffer = text; - png_ptr->read_buffer_size = buffer_size; - text = old_ptr; /* freed below */ - } - } - - else - { - /* The size changed on the second read, there can be no - * guarantee that anything is correct at this point. - * The 'msg' pointer has been set to "unexpected end of - * LZ stream", which is fine, but return an error code - * that the caller won't accept. - */ - ret = PNG_UNEXPECTED_ZLIB_RETURN; - } - } - - else if (ret == Z_OK) - ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ - - /* Free the text pointer (this is the old read_buffer on - * success) - */ - png_free(png_ptr, text); - - /* This really is very benign, but it's still an error because - * the extra space may otherwise be used as a Trojan Horse. - */ - if (ret == Z_STREAM_END && - chunklength - prefix_size != lzsize) - png_chunk_benign_error(png_ptr, "extra compressed data"); - } - - else - { - /* Out of memory allocating the buffer */ - ret = Z_MEM_ERROR; - png_zstream_error(png_ptr, Z_MEM_ERROR); - } - } - - else - { - /* inflateReset failed, store the error message */ - png_zstream_error(png_ptr, ret); - ret = PNG_UNEXPECTED_ZLIB_RETURN; - } - } - - else if (ret == Z_OK) - ret = PNG_UNEXPECTED_ZLIB_RETURN; - - /* Release the claimed stream */ - png_ptr->zowner = 0; - } - - else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ - ret = PNG_UNEXPECTED_ZLIB_RETURN; - - return ret; - } - - else - { - /* Application/configuration limits exceeded */ - png_zstream_error(png_ptr, Z_MEM_ERROR); - return Z_MEM_ERROR; - } -} -#endif /* READ_zTXt || READ_iTXt */ -#endif /* READ_COMPRESSED_TEXT */ - -#ifdef PNG_READ_iCCP_SUPPORTED -/* Perform a partial read and decompress, producing 'avail_out' bytes and - * reading from the current chunk as required. - */ -static int -png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, - png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, - int finish) -{ - if (png_ptr->zowner == png_ptr->chunk_name) - { - int ret; - - /* next_in and avail_in must have been initialized by the caller. */ - png_ptr->zstream.next_out = next_out; - png_ptr->zstream.avail_out = 0; /* set in the loop */ - - do - { - if (png_ptr->zstream.avail_in == 0) - { - if (read_size > *chunk_bytes) - read_size = (uInt)*chunk_bytes; - *chunk_bytes -= read_size; - - if (read_size > 0) - png_crc_read(png_ptr, read_buffer, read_size); - - png_ptr->zstream.next_in = read_buffer; - png_ptr->zstream.avail_in = read_size; - } - - if (png_ptr->zstream.avail_out == 0) - { - uInt avail = ZLIB_IO_MAX; - if (avail > *out_size) - avail = (uInt)*out_size; - *out_size -= avail; - - png_ptr->zstream.avail_out = avail; - } - - /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all - * the available output is produced; this allows reading of truncated - * streams. - */ - ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ? - Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); - } - while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); - - *out_size += png_ptr->zstream.avail_out; - png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ - - /* Ensure the error message pointer is always set: */ - png_zstream_error(png_ptr, ret); - return ret; - } - - else - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); - return Z_STREAM_ERROR; - } -} -#endif /* READ_iCCP */ - -/* Read and check the IDHR chunk */ - -void /* PRIVATE */ -png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[13]; - png_uint_32 width, height; - int bit_depth, color_type, compression_type, filter_type; - int interlace_type; - - png_debug(1, "in png_handle_IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) - png_chunk_error(png_ptr, "out of place"); - - /* Check the length */ - if (length != 13) - png_chunk_error(png_ptr, "invalid"); - - png_ptr->mode |= PNG_HAVE_IHDR; - - png_crc_read(png_ptr, buf, 13); - png_crc_finish(png_ptr, 0); - - width = png_get_uint_31(png_ptr, buf); - height = png_get_uint_31(png_ptr, buf + 4); - bit_depth = buf[8]; - color_type = buf[9]; - compression_type = buf[10]; - filter_type = buf[11]; - interlace_type = buf[12]; - - /* Set internal variables */ - png_ptr->width = width; - png_ptr->height = height; - png_ptr->bit_depth = (png_byte)bit_depth; - png_ptr->interlaced = (png_byte)interlace_type; - png_ptr->color_type = (png_byte)color_type; -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_ptr->filter_type = (png_byte)filter_type; -#endif - png_ptr->compression_type = (png_byte)compression_type; - - /* Find number of channels */ - switch (png_ptr->color_type) - { - default: /* invalid, png_set_IHDR calls png_error */ - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_PALETTE: - png_ptr->channels = 1; - break; - - case PNG_COLOR_TYPE_RGB: - png_ptr->channels = 3; - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - png_ptr->channels = 2; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - png_ptr->channels = 4; - break; - } - - /* Set up other useful info */ - png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); - png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); - png_debug1(3, "channels = %d", png_ptr->channels); - png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); - png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); -} - -/* Read and check the palette */ -void /* PRIVATE */ -png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_color palette[PNG_MAX_PALETTE_LENGTH]; - int max_palette_length, num, i; -#ifdef PNG_POINTER_INDEXING_SUPPORTED - png_colorp pal_ptr; -#endif - - png_debug(1, "in png_handle_PLTE"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - /* Moved to before the 'after IDAT' check below because otherwise duplicate - * PLTE chunks are potentially ignored (the spec says there shall not be more - * than one PLTE, the error is not treated as benign, so this check trumps - * the requirement that PLTE appears before IDAT.) - */ - else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) - png_chunk_error(png_ptr, "duplicate"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - /* This is benign because the non-benign error happened before, when an - * IDAT was encountered in a color-mapped image with no PLTE. - */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - png_ptr->mode |= PNG_HAVE_PLTE; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); - return; - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - png_crc_finish(png_ptr, length); - return; - } -#endif - - if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) - { - png_crc_finish(png_ptr, length); - - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - png_chunk_benign_error(png_ptr, "invalid"); - - else - png_chunk_error(png_ptr, "invalid"); - - return; - } - - /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ - num = (int)length / 3; - - /* If the palette has 256 or fewer entries but is too large for the bit - * depth, we don't issue an error, to preserve the behavior of previous - * libpng versions. We silently truncate the unused extra palette entries - * here. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - max_palette_length = (1 << png_ptr->bit_depth); - else - max_palette_length = PNG_MAX_PALETTE_LENGTH; - - if (num > max_palette_length) - num = max_palette_length; - -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - pal_ptr->red = buf[0]; - pal_ptr->green = buf[1]; - pal_ptr->blue = buf[2]; - } -#else - for (i = 0; i < num; i++) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - /* Don't depend upon png_color being any order */ - palette[i].red = buf[0]; - palette[i].green = buf[1]; - palette[i].blue = buf[2]; - } -#endif - - /* If we actually need the PLTE chunk (ie for a paletted image), we do - * whatever the normal CRC configuration tells us. However, if we - * have an RGB image, the PLTE can be considered ancillary, so - * we will act as though it is. - */ -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#endif - { - png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3)); - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ - { - /* If we don't want to use the data from an ancillary chunk, - * we have two options: an error abort, or a warning and we - * ignore the data in this chunk (which should be OK, since - * it's considered ancillary for a RGB or RGBA image). - * - * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the - * chunk type to determine whether to check the ancillary or the critical - * flags. - */ - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) - return; - - else - png_chunk_error(png_ptr, "CRC error"); - } - - /* Otherwise, we (optionally) emit a warning and use the chunk. */ - else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) - png_chunk_warning(png_ptr, "CRC error"); - } -#endif - - /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its - * own copy of the palette. This has the side effect that when png_start_row - * is called (this happens after any call to png_read_update_info) the - * info_ptr palette gets changed. This is extremely unexpected and - * confusing. - * - * Fix this by not sharing the palette in this way. - */ - png_set_PLTE(png_ptr, info_ptr, palette, num); - - /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before - * IDAT. Prior to 1.6.0 this was not checked; instead the code merely - * checked the apparent validity of a tRNS chunk inserted before PLTE on a - * palette PNG. 1.6.0 attempts to rigorously follow the standard and - * therefore does a benign error if the erroneous condition is detected *and* - * cancels the tRNS if the benign error returns. The alternative is to - * amend the standard since it would be rather hypocritical of the standards - * maintainers to ignore it. - */ -#ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->num_trans > 0 || - (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) - { - /* Cancel this because otherwise it would be used if the transforms - * require it. Don't cancel the 'valid' flag because this would prevent - * detection of duplicate chunks. - */ - png_ptr->num_trans = 0; - - if (info_ptr != NULL) - info_ptr->num_trans = 0; - - png_chunk_benign_error(png_ptr, "tRNS must be after"); - } -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - png_chunk_benign_error(png_ptr, "hIST must be after"); -#endif - -#ifdef PNG_READ_bKGD_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) - png_chunk_benign_error(png_ptr, "bKGD must be after"); -#endif -} - -void /* PRIVATE */ -png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_debug(1, "in png_handle_IEND"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || - (png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_chunk_error(png_ptr, "out of place"); - - png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); - - png_crc_finish(png_ptr, length); - - if (length != 0) - png_chunk_benign_error(png_ptr, "invalid"); - - PNG_UNUSED(info_ptr) -} - -#ifdef PNG_READ_gAMA_SUPPORTED -void /* PRIVATE */ -png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_fixed_point igamma; - png_byte buf[4]; - - png_debug(1, "in png_handle_gAMA"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 4) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 4); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - igamma = png_get_fixed_point(NULL, buf); - - png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); - png_colorspace_sync(png_ptr, info_ptr); -} -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -void /* PRIVATE */ -png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int truelen, i; - png_byte sample_depth; - png_byte buf[4]; - - png_debug(1, "in png_handle_sBIT"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - truelen = 3; - sample_depth = 8; - } - - else - { - truelen = png_ptr->channels; - sample_depth = png_ptr->bit_depth; - } - - if (length != truelen || length > 4) - { - png_chunk_benign_error(png_ptr, "invalid"); - png_crc_finish(png_ptr, length); - return; - } - - buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - for (i=0; i sample_depth) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - } - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[1]; - png_ptr->sig_bit.blue = buf[2]; - png_ptr->sig_bit.alpha = buf[3]; - } - - else - { - png_ptr->sig_bit.gray = buf[0]; - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[0]; - png_ptr->sig_bit.blue = buf[0]; - png_ptr->sig_bit.alpha = buf[1]; - } - - png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); -} -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -void /* PRIVATE */ -png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[32]; - png_xy xy; - - png_debug(1, "in png_handle_cHRM"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 32) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 32); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - xy.whitex = png_get_fixed_point(NULL, buf); - xy.whitey = png_get_fixed_point(NULL, buf + 4); - xy.redx = png_get_fixed_point(NULL, buf + 8); - xy.redy = png_get_fixed_point(NULL, buf + 12); - xy.greenx = png_get_fixed_point(NULL, buf + 16); - xy.greeny = png_get_fixed_point(NULL, buf + 20); - xy.bluex = png_get_fixed_point(NULL, buf + 24); - xy.bluey = png_get_fixed_point(NULL, buf + 28); - - if (xy.whitex == PNG_FIXED_ERROR || - xy.whitey == PNG_FIXED_ERROR || - xy.redx == PNG_FIXED_ERROR || - xy.redy == PNG_FIXED_ERROR || - xy.greenx == PNG_FIXED_ERROR || - xy.greeny == PNG_FIXED_ERROR || - xy.bluex == PNG_FIXED_ERROR || - xy.bluey == PNG_FIXED_ERROR) - { - png_chunk_benign_error(png_ptr, "invalid values"); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - return; - - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, - 1/*prefer cHRM values*/); - png_colorspace_sync(png_ptr, info_ptr); -} -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED -void /* PRIVATE */ -png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte intent; - - png_debug(1, "in png_handle_sRGB"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, &intent, 1); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - return; - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "too many profiles"); - return; - } - - (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); - png_colorspace_sync(png_ptr, info_ptr); -} -#endif /* READ_sRGB */ - -#ifdef PNG_READ_iCCP_SUPPORTED -void /* PRIVATE */ -png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -/* Note: this does not properly handle profiles that are > 64K under DOS */ -{ - png_const_charp errmsg = NULL; /* error message output, or no error */ - int finished = 0; /* crc checked */ - - png_debug(1, "in png_handle_iCCP"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - /* Consistent with all the above colorspace handling an obviously *invalid* - * chunk is just ignored, so does not invalidate the color space. An - * alternative is to set the 'invalid' flags at the start of this routine - * and only clear them in they were not set before and all the tests pass. - */ - - /* The keyword must be at least one character and there is a - * terminator (0) byte and the compression method byte, and the - * 'zlib' datastream is at least 11 bytes. - */ - if (length < 14) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - png_crc_finish(png_ptr, length); - return; - } - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) - { - uInt read_length, keyword_length; - char keyword[81]; - - /* Find the keyword; the keyword plus separator and compression method - * bytes can be at most 81 characters long. - */ - read_length = 81; /* maximum */ - if (read_length > length) - read_length = (uInt)length; - - png_crc_read(png_ptr, (png_bytep)keyword, read_length); - length -= read_length; - - /* The minimum 'zlib' stream is assumed to be just the 2 byte header, - * 5 bytes minimum 'deflate' stream, and the 4 byte checksum. - */ - if (length < 11) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - keyword_length = 0; - while (keyword_length < 80 && keyword_length < read_length && - keyword[keyword_length] != 0) - ++keyword_length; - - /* TODO: make the keyword checking common */ - if (keyword_length >= 1 && keyword_length <= 79) - { - /* We only understand '0' compression - deflate - so if we get a - * different value we can't safely decode the chunk. - */ - if (keyword_length+1 < read_length && - keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) - { - read_length -= keyword_length+2; - - if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) - { - Byte profile_header[132]={0}; - Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - png_alloc_size_t size = (sizeof profile_header); - - png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); - png_ptr->zstream.avail_in = read_length; - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, profile_header, &size, - 0/*finish: don't, because the output is too small*/); - - if (size == 0) - { - /* We have the ICC profile header; do the basic header checks. - */ - png_uint_32 profile_length = png_get_uint_32(profile_header); - - if (png_icc_check_length(png_ptr, &png_ptr->colorspace, - keyword, profile_length) != 0) - { - /* The length is apparently ok, so we can check the 132 - * byte header. - */ - if (png_icc_check_header(png_ptr, &png_ptr->colorspace, - keyword, profile_length, profile_header, - png_ptr->color_type) != 0) - { - /* Now read the tag table; a variable size buffer is - * needed at this point, allocate one for the whole - * profile. The header check has already validated - * that none of this stuff will overflow. - */ - png_uint_32 tag_count = - png_get_uint_32(profile_header + 128); - png_bytep profile = png_read_buffer(png_ptr, - profile_length, 2/*silent*/); - - if (profile != NULL) - { - memcpy(profile, profile_header, - (sizeof profile_header)); - - size = 12 * tag_count; - - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header), &size, 0); - - /* Still expect a buffer error because we expect - * there to be some tag data! - */ - if (size == 0) - { - if (png_icc_check_tag_table(png_ptr, - &png_ptr->colorspace, keyword, profile_length, - profile) != 0) - { - /* The profile has been validated for basic - * security issues, so read the whole thing in. - */ - size = profile_length - (sizeof profile_header) - - 12 * tag_count; - - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header) + - 12 * tag_count, &size, 1/*finish*/); - - if (length > 0 && !(png_ptr->flags & - PNG_FLAG_BENIGN_ERRORS_WARN)) - errmsg = "extra compressed data"; - - /* But otherwise allow extra data: */ - else if (size == 0) - { - if (length > 0) - { - /* This can be handled completely, so - * keep going. - */ - png_chunk_warning(png_ptr, - "extra compressed data"); - } - - png_crc_finish(png_ptr, length); - finished = 1; - -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* Check for a match against sRGB */ - png_icc_set_sRGB(png_ptr, - &png_ptr->colorspace, profile, - png_ptr->zstream.adler); -# endif - - /* Steal the profile for info_ptr. */ - if (info_ptr != NULL) - { - png_free_data(png_ptr, info_ptr, - PNG_FREE_ICCP, 0); - - info_ptr->iccp_name = png_voidcast(char*, - png_malloc_base(png_ptr, - keyword_length+1)); - if (info_ptr->iccp_name != NULL) - { - memcpy(info_ptr->iccp_name, keyword, - keyword_length+1); - info_ptr->iccp_proflen = - profile_length; - info_ptr->iccp_profile = profile; - png_ptr->read_buffer = NULL; /*steal*/ - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; - } - - else - { - png_ptr->colorspace.flags |= - PNG_COLORSPACE_INVALID; - errmsg = "out of memory"; - } - } - - /* else the profile remains in the read - * buffer which gets reused for subsequent - * chunks. - */ - - if (info_ptr != NULL) - png_colorspace_sync(png_ptr, info_ptr); - - if (errmsg == NULL) - { - png_ptr->zowner = 0; - return; - } - } - if (errmsg == NULL) - errmsg = png_ptr->zstream.msg; - } - /* else png_icc_check_tag_table output an error */ - } - else /* profile truncated */ - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "out of memory"; - } - - /* else png_icc_check_header output an error */ - } - - /* else png_icc_check_length output an error */ - } - - else /* profile truncated */ - errmsg = png_ptr->zstream.msg; - - /* Release the stream */ - png_ptr->zowner = 0; - } - - else /* png_inflate_claim failed */ - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "bad compression method"; /* or missing */ - } - - else - errmsg = "bad keyword"; - } - - else - errmsg = "too many profiles"; - - /* Failure: the reason is in 'errmsg' */ - if (finished == 0) - png_crc_finish(png_ptr, length); - - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - if (errmsg != NULL) /* else already output */ - png_chunk_benign_error(png_ptr, errmsg); -} -#endif /* READ_iCCP */ - -#ifdef PNG_READ_sPLT_SUPPORTED -void /* PRIVATE */ -png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -/* Note: this does not properly handle chunks that are > 64K under DOS */ -{ - png_bytep entry_start, buffer; - png_sPLT_t new_palette; - png_sPLT_entryp pp; - png_uint_32 data_length; - int entry_size, i; - png_uint_32 skip = 0; - png_uint_32 dl; - size_t max_dl; - - png_debug(1, "in png_handle_sPLT"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for sPLT"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535U) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too large to fit in memory"); - return; - } -#endif - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - - /* WARNING: this may break if size_t is less than 32 bits; it is assumed - * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a - * potential breakage point if the types in pngconf.h aren't exactly right. - */ - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, skip) != 0) - return; - - buffer[length] = 0; - - for (entry_start = buffer; *entry_start; entry_start++) - /* Empty loop to find end of name */ ; - - ++entry_start; - - /* A sample depth should follow the separator, and we should be on it */ - if (length < 2U || entry_start > buffer + (length - 2U)) - { - png_warning(png_ptr, "malformed sPLT chunk"); - return; - } - - new_palette.depth = *entry_start++; - entry_size = (new_palette.depth == 8 ? 6 : 10); - /* This must fit in a png_uint_32 because it is derived from the original - * chunk data length. - */ - data_length = length - (png_uint_32)(entry_start - buffer); - - /* Integrity-check the data length */ - if ((data_length % (unsigned int)entry_size) != 0) - { - png_warning(png_ptr, "sPLT chunk has bad length"); - return; - } - - dl = (png_uint_32)(data_length / (unsigned int)entry_size); - max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); - - if (dl > max_dl) - { - png_warning(png_ptr, "sPLT chunk too long"); - return; - } - - new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size); - - new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, - (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry))); - - if (new_palette.entries == NULL) - { - png_warning(png_ptr, "sPLT chunk requires too much memory"); - return; - } - -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0; i < new_palette.nentries; i++) - { - pp = new_palette.entries + i; - - if (new_palette.depth == 8) - { - pp->red = *entry_start++; - pp->green = *entry_start++; - pp->blue = *entry_start++; - pp->alpha = *entry_start++; - } - - else - { - pp->red = png_get_uint_16(entry_start); entry_start += 2; - pp->green = png_get_uint_16(entry_start); entry_start += 2; - pp->blue = png_get_uint_16(entry_start); entry_start += 2; - pp->alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp->frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#else - pp = new_palette.entries; - - for (i = 0; i < new_palette.nentries; i++) - { - - if (new_palette.depth == 8) - { - pp[i].red = *entry_start++; - pp[i].green = *entry_start++; - pp[i].blue = *entry_start++; - pp[i].alpha = *entry_start++; - } - - else - { - pp[i].red = png_get_uint_16(entry_start); entry_start += 2; - pp[i].green = png_get_uint_16(entry_start); entry_start += 2; - pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; - pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#endif - - /* Discard all chunk data except the name and stash that */ - new_palette.name = (png_charp)buffer; - - png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - - png_free(png_ptr, new_palette.entries); -} -#endif /* READ_sPLT */ - -#ifdef PNG_READ_tRNS_SUPPORTED -void /* PRIVATE */ -png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_tRNS"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - png_byte buf[2]; - - if (length != 2) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 2); - png_ptr->num_trans = 1; - png_ptr->trans_color.gray = png_get_uint_16(buf); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - png_byte buf[6]; - - if (length != 6) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, length); - png_ptr->num_trans = 1; - png_ptr->trans_color.red = png_get_uint_16(buf); - png_ptr->trans_color.green = png_get_uint_16(buf + 2); - png_ptr->trans_color.blue = png_get_uint_16(buf + 4); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) - { - /* TODO: is this actually an error in the ISO spec? */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length > (unsigned int) png_ptr->num_palette || - length > (unsigned int) PNG_MAX_PALETTE_LENGTH || - length == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, readbuf, length); - png_ptr->num_trans = (png_uint_16)length; - } - - else - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid with alpha channel"); - return; - } - - if (png_crc_finish(png_ptr, 0) != 0) - { - png_ptr->num_trans = 0; - return; - } - - /* TODO: this is a horrible side effect in the palette case because the - * png_struct ends up with a pointer to the tRNS buffer owned by the - * png_info. Fix this. - */ - png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, - &(png_ptr->trans_color)); -} -#endif - -#ifdef PNG_READ_bKGD_SUPPORTED -void /* PRIVATE */ -png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int truelen; - png_byte buf[6]; - png_color_16 background; - - png_debug(1, "in png_handle_bKGD"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0)) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - truelen = 1; - - else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - truelen = 6; - - else - truelen = 2; - - if (length != truelen) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* We convert the index value into RGB components so that we can allow - * arbitrary RGB values for background when we have transparency, and - * so it is easy to determine the RGB values of the background color - * from the info_ptr struct. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - background.index = buf[0]; - - if (info_ptr != NULL && info_ptr->num_palette != 0) - { - if (buf[0] >= info_ptr->num_palette) - { - png_chunk_benign_error(png_ptr, "invalid index"); - return; - } - - background.red = (png_uint_16)png_ptr->palette[buf[0]].red; - background.green = (png_uint_16)png_ptr->palette[buf[0]].green; - background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; - } - - else - background.red = background.green = background.blue = 0; - - background.gray = 0; - } - - else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ - { - if (png_ptr->bit_depth <= 8) - { - if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth)) - { - png_chunk_benign_error(png_ptr, "invalid gray level"); - return; - } - } - - background.index = 0; - background.red = - background.green = - background.blue = - background.gray = png_get_uint_16(buf); - } - - else - { - if (png_ptr->bit_depth <= 8) - { - if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0) - { - png_chunk_benign_error(png_ptr, "invalid color"); - return; - } - } - - background.index = 0; - background.red = png_get_uint_16(buf); - background.green = png_get_uint_16(buf + 2); - background.blue = png_get_uint_16(buf + 4); - background.gray = 0; - } - - png_set_bKGD(png_ptr, info_ptr, &background); -} -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED -void /* PRIVATE */ -png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int i; - - png_debug(1, "in png_handle_eXIf"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if (length < 2) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - info_ptr->free_me |= PNG_FREE_EXIF; - - info_ptr->eXIf_buf = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->eXIf_buf == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - for (i = 0; i < length; i++) - { - png_byte buf[1]; - png_crc_read(png_ptr, buf, 1); - info_ptr->eXIf_buf[i] = buf[0]; - if (i == 1) - { - if ((buf[0] != 'M' && buf[0] != 'I') || - (info_ptr->eXIf_buf[0] != buf[0])) - { - png_crc_finish(png_ptr, length - 2); - png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - return; - } - } - } - - if (png_crc_finish(png_ptr, 0) == 0) - png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); - - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; -} -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -void /* PRIVATE */ -png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int num, i; - png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_hIST"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - num = length / 2 ; - - if (length != num * 2 || - num != (unsigned int)png_ptr->num_palette || - num > (unsigned int)PNG_MAX_PALETTE_LENGTH) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - for (i = 0; i < num; i++) - { - png_byte buf[2]; - - png_crc_read(png_ptr, buf, 2); - readbuf[i] = png_get_uint_16(buf); - } - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - png_set_hIST(png_ptr, info_ptr, readbuf); -} -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -void /* PRIVATE */ -png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[9]; - png_uint_32 res_x, res_y; - int unit_type; - - png_debug(1, "in png_handle_pHYs"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - res_x = png_get_uint_32(buf); - res_y = png_get_uint_32(buf + 4); - unit_type = buf[8]; - png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); -} -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -void /* PRIVATE */ -png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[9]; - png_int_32 offset_x, offset_y; - int unit_type; - - png_debug(1, "in png_handle_oFFs"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - offset_x = png_get_int_32(buf); - offset_y = png_get_int_32(buf + 4); - unit_type = buf[8]; - png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); -} -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -/* Read the pCAL chunk (described in the PNG Extensions document) */ -void /* PRIVATE */ -png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_int_32 X0, X1; - png_byte type, nparams; - png_bytep buffer, buf, units, endptr; - png_charpp params; - int i; - - png_debug(1, "in png_handle_pCAL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", - length + 1); - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - buffer[length] = 0; /* Null terminate the last string */ - - png_debug(3, "Finding end of pCAL purpose string"); - for (buf = buffer; *buf; buf++) - /* Empty loop */ ; - - endptr = buffer + length; - - /* We need to have at least 12 bytes after the purpose string - * in order to get the parameter information. - */ - if (endptr - buf <= 12) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); - X0 = png_get_int_32((png_bytep)buf+1); - X1 = png_get_int_32((png_bytep)buf+5); - type = buf[9]; - nparams = buf[10]; - units = buf + 11; - - png_debug(3, "Checking pCAL equation type and number of parameters"); - /* Check that we have the right number of parameters for known - * equation types. - */ - if ((type == PNG_EQUATION_LINEAR && nparams != 2) || - (type == PNG_EQUATION_BASE_E && nparams != 3) || - (type == PNG_EQUATION_ARBITRARY && nparams != 3) || - (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) - { - png_chunk_benign_error(png_ptr, "invalid parameter count"); - return; - } - - else if (type >= PNG_EQUATION_LAST) - { - png_chunk_benign_error(png_ptr, "unrecognized equation type"); - } - - for (buf = units; *buf; buf++) - /* Empty loop to move past the units string. */ ; - - png_debug(3, "Allocating pCAL parameters array"); - - params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - nparams * (sizeof (png_charp)))); - - if (params == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - /* Get pointers to the start of each parameter string. */ - for (i = 0; i < nparams; i++) - { - buf++; /* Skip the null string terminator from previous parameter. */ - - png_debug1(3, "Reading pCAL parameter %d", i); - - for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) - /* Empty loop to move past each parameter string */ ; - - /* Make sure we haven't run out of data yet */ - if (buf > endptr) - { - png_free(png_ptr, params); - png_chunk_benign_error(png_ptr, "invalid data"); - return; - } - } - - png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, - (png_charp)units, params); - - png_free(png_ptr, params); -} -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -/* Read the sCAL chunk */ -void /* PRIVATE */ -png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_bytep buffer; - size_t i; - int state; - - png_debug(1, "in png_handle_sCAL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - /* Need unit type, width, \0, height: minimum 4 bytes */ - else if (length < 4) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", - length + 1); - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - - if (buffer == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buffer, length); - buffer[length] = 0; /* Null terminate the last string */ - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* Validate the unit. */ - if (buffer[0] != 1 && buffer[0] != 2) - { - png_chunk_benign_error(png_ptr, "invalid unit"); - return; - } - - /* Validate the ASCII numbers, need two ASCII numbers separated by - * a '\0' and they need to fit exactly in the chunk data. - */ - i = 1; - state = 0; - - if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || - i >= length || buffer[i++] != 0) - png_chunk_benign_error(png_ptr, "bad width format"); - - else if (PNG_FP_IS_POSITIVE(state) == 0) - png_chunk_benign_error(png_ptr, "non-positive width"); - - else - { - size_t heighti = i; - - state = 0; - if (png_check_fp_number((png_const_charp)buffer, length, - &state, &i) == 0 || i != length) - png_chunk_benign_error(png_ptr, "bad height format"); - - else if (PNG_FP_IS_POSITIVE(state) == 0) - png_chunk_benign_error(png_ptr, "non-positive height"); - - else - /* This is the (only) success case. */ - png_set_sCAL_s(png_ptr, info_ptr, buffer[0], - (png_charp)buffer+1, (png_charp)buffer+heighti); - } -} -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -void /* PRIVATE */ -png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[7]; - png_time mod_time; - - png_debug(1, "in png_handle_tIME"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - if (length != 7) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 7); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - mod_time.second = buf[6]; - mod_time.minute = buf[5]; - mod_time.hour = buf[4]; - mod_time.day = buf[3]; - mod_time.month = buf[2]; - mod_time.year = png_get_uint_16(buf); - - png_set_tIME(png_ptr, info_ptr, &mod_time); -} -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -/* Note: this does not properly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_text text_info; - png_bytep buffer; - png_charp key; - png_charp text; - png_uint_32 skip = 0; - - png_debug(1, "in png_handle_tEXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535U) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too large to fit in memory"); - return; - } -#endif - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - - if (buffer == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, skip) != 0) - return; - - key = (png_charp)buffer; - key[length] = 0; - - for (text = key; *text; text++) - /* Empty loop to find end of key */ ; - - if (text != key + length) - text++; - - text_info.compression = PNG_TEXT_COMPRESSION_NONE; - text_info.key = key; - text_info.lang = NULL; - text_info.lang_key = NULL; - text_info.itxt_length = 0; - text_info.text = text; - text_info.text_length = strlen(text); - - if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) - png_warning(png_ptr, "Insufficient memory to process text chunk"); -} -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -/* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_const_charp errmsg = NULL; - png_bytep buffer; - png_uint_32 keyword_length; - - png_debug(1, "in png_handle_zTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - /* Note, "length" is sufficient here; we won't be adding - * a null terminator later. - */ - buffer = png_read_buffer(png_ptr, length, 2/*silent*/); - - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* TODO: also check that the keyword contents match the spec! */ - for (keyword_length = 0; - keyword_length < length && buffer[keyword_length] != 0; - ++keyword_length) - /* Empty loop to find end of name */ ; - - if (keyword_length > 79 || keyword_length < 1) - errmsg = "bad keyword"; - - /* zTXt must have some LZ data after the keyword, although it may expand to - * zero bytes; we need a '\0' at the end of the keyword, the compression type - * then the LZ data: - */ - else if (keyword_length + 3 > length) - errmsg = "truncated"; - - else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) - errmsg = "unknown compression type"; - - else - { - png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; - - /* TODO: at present png_decompress_chunk imposes a single application - * level memory limit, this should be split to different values for iCCP - * and text chunks. - */ - if (png_decompress_chunk(png_ptr, length, keyword_length+2, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) - { - png_text text; - - if (png_ptr->read_buffer == NULL) - errmsg="Read failure in png_handle_zTXt"; - else - { - /* It worked; png_ptr->read_buffer now looks like a tEXt chunk - * except for the extra compression type byte and the fact that - * it isn't necessarily '\0' terminated. - */ - buffer = png_ptr->read_buffer; - buffer[uncompressed_length+(keyword_length+2)] = 0; - - text.compression = PNG_TEXT_COMPRESSION_zTXt; - text.key = (png_charp)buffer; - text.text = (png_charp)(buffer + keyword_length+2); - text.text_length = uncompressed_length; - text.itxt_length = 0; - text.lang = NULL; - text.lang_key = NULL; - - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; - } - } - - else - errmsg = png_ptr->zstream.msg; - } - - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); -} -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED -/* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_const_charp errmsg = NULL; - png_bytep buffer; - png_uint_32 prefix_length; - - png_debug(1, "in png_handle_iTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* First the keyword. */ - for (prefix_length=0; - prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* Perform a basic check on the keyword length here. */ - if (prefix_length > 79 || prefix_length < 1) - errmsg = "bad keyword"; - - /* Expect keyword, compression flag, compression type, language, translated - * keyword (both may be empty but are 0 terminated) then the text, which may - * be empty. - */ - else if (prefix_length + 5 > length) - errmsg = "truncated"; - - else if (buffer[prefix_length+1] == 0 || - (buffer[prefix_length+1] == 1 && - buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) - { - int compressed = buffer[prefix_length+1] != 0; - png_uint_32 language_offset, translated_keyword_offset; - png_alloc_size_t uncompressed_length = 0; - - /* Now the language tag */ - prefix_length += 3; - language_offset = prefix_length; - - for (; prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* WARNING: the length may be invalid here, this is checked below. */ - translated_keyword_offset = ++prefix_length; - - for (; prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* prefix_length should now be at the trailing '\0' of the translated - * keyword, but it may already be over the end. None of this arithmetic - * can overflow because chunks are at most 2^31 bytes long, but on 16-bit - * systems the available allocation may overflow. - */ - ++prefix_length; - - if (compressed == 0 && prefix_length <= length) - uncompressed_length = length - prefix_length; - - else if (compressed != 0 && prefix_length < length) - { - uncompressed_length = PNG_SIZE_MAX; - - /* TODO: at present png_decompress_chunk imposes a single application - * level memory limit, this should be split to different values for - * iCCP and text chunks. - */ - if (png_decompress_chunk(png_ptr, length, prefix_length, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) - buffer = png_ptr->read_buffer; - - else - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "truncated"; - - if (errmsg == NULL) - { - png_text text; - - buffer[uncompressed_length+prefix_length] = 0; - - if (compressed == 0) - text.compression = PNG_ITXT_COMPRESSION_NONE; - - else - text.compression = PNG_ITXT_COMPRESSION_zTXt; - - text.key = (png_charp)buffer; - text.lang = (png_charp)buffer + language_offset; - text.lang_key = (png_charp)buffer + translated_keyword_offset; - text.text = (png_charp)buffer + prefix_length; - text.text_length = 0; - text.itxt_length = uncompressed_length; - - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; - } - } - - else - errmsg = "bad compression info"; - - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); -} -#endif - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ -static int -png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) -{ - png_alloc_size_t limit = PNG_SIZE_MAX; - - if (png_ptr->unknown_chunk.data != NULL) - { - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - } - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; - -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - - if (length <= limit) - { - PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); - /* The following is safe because of the PNG_SIZE_MAX init above */ - png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/; - /* 'mode' is a flag array, only the bottom four bits matter here */ - png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; - - if (length == 0) - png_ptr->unknown_chunk.data = NULL; - - else - { - /* Do a 'warn' here - it is handled below. */ - png_ptr->unknown_chunk.data = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, length)); - } - } - - if (png_ptr->unknown_chunk.data == NULL && length > 0) - { - /* This is benign because we clean up correctly */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); - return 0; - } - - else - { - if (length > 0) - png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); - png_crc_finish(png_ptr, 0); - return 1; - } -} -#endif /* READ_UNKNOWN_CHUNKS */ - -/* Handle an unknown, or known but disabled, chunk */ -void /* PRIVATE */ -png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, - png_uint_32 length, int keep) -{ - int handled = 0; /* the chunk was handled */ - - png_debug(1, "in png_handle_unknown"); - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing - * the bug which meant that setting a non-default behavior for a specific - * chunk would be ignored (the default was always used unless a user - * callback was installed). - * - * 'keep' is the value from the png_chunk_unknown_handling, the setting for - * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it - * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. - * This is just an optimization to avoid multiple calls to the lookup - * function. - */ -# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); -# endif -# endif - - /* One of the following methods will read the chunk or skip it (at least one - * of these is always defined because this is the only way to switch on - * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - */ -# ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* The user callback takes precedence over the chunk keep value, but the - * keep value is still required to validate a save of a critical chunk. - */ - if (png_ptr->read_user_chunk_fn != NULL) - { - if (png_cache_unknown_chunk(png_ptr, length) != 0) - { - /* Callback to user unknown chunk handler */ - int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, - &png_ptr->unknown_chunk); - - /* ret is: - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the chunk will be discarded - * unless png_set_keep_unknown_chunks has been used to set - * a 'keep' behavior for this particular chunk, in which - * case that will be used. A critical chunk will cause an - * error at this point unless it is to be saved. - * positive: The chunk was handled, libpng will ignore/discard it. - */ - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - - else if (ret == 0) - { - /* If the keep value is 'default' or 'never' override it, but - * still error out on critical chunks unless the keep value is - * 'always' While this is weird it is the behavior in 1.4.12. - * A possible improvement would be to obey the value set for the - * chunk, but this would be an API change that would probably - * damage some applications. - * - * The png_app_warning below catches the case that matters, where - * the application has not set specific save or ignore for this - * chunk or global save or ignore. - */ - if (keep < PNG_HANDLE_CHUNK_IF_SAFE) - { -# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) - { - png_chunk_warning(png_ptr, "Saving unknown chunk:"); - png_app_warning(png_ptr, - "forcing save of an unhandled chunk;" - " please call png_set_keep_unknown_chunks"); - /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ - } -# endif - keep = PNG_HANDLE_CHUNK_IF_SAFE; - } - } - - else /* chunk was handled */ - { - handled = 1; - /* Critical chunks can be safely discarded at this point. */ - keep = PNG_HANDLE_CHUNK_NEVER; - } - } - - else - keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ - } - - else - /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ -# endif /* READ_USER_CHUNKS */ - -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - { - /* keep is currently just the per-chunk setting, if there was no - * setting change it to the global default now (not that this may - * still be AS_DEFAULT) then obtain the cache of the chunk if required, - * if not simply skip the chunk. - */ - if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) - keep = png_ptr->unknown_default; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) - { - if (png_cache_unknown_chunk(png_ptr, length) == 0) - keep = PNG_HANDLE_CHUNK_NEVER; - } - - else - png_crc_finish(png_ptr, length); - } -# else -# ifndef PNG_READ_USER_CHUNKS_SUPPORTED -# error no method to support READ_UNKNOWN_CHUNKS -# endif - - { - /* If here there is no read callback pointer set and no support is - * compiled in to just save the unknown chunks, so simply skip this - * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then - * the app has erroneously asked for unknown chunk saving when there - * is no support. - */ - if (keep > PNG_HANDLE_CHUNK_NEVER) - png_app_error(png_ptr, "no unknown chunk support available"); - - png_crc_finish(png_ptr, length); - } -# endif - -# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Now store the chunk in the chunk list if appropriate, and if the limits - * permit it. - */ - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) - { -# ifdef PNG_USER_LIMITS_SUPPORTED - switch (png_ptr->user_chunk_cache_max) - { - case 2: - png_ptr->user_chunk_cache_max = 1; - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - /* FALLTHROUGH */ - case 1: - /* NOTE: prior to 1.6.0 this case resulted in an unknown critical - * chunk being skipped, now there will be a hard error below. - */ - break; - - default: /* not at limit */ - --(png_ptr->user_chunk_cache_max); - /* FALLTHROUGH */ - case 0: /* no limit */ -# endif /* USER_LIMITS */ - /* Here when the limit isn't reached or when limits are compiled - * out; store the chunk. - */ - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - handled = 1; -# ifdef PNG_USER_LIMITS_SUPPORTED - break; - } -# endif - } -# else /* no store support: the chunk must be handled by the user callback */ - PNG_UNUSED(info_ptr) -# endif - - /* Regardless of the error handling below the cached data (if any) can be - * freed now. Notice that the data is not freed if there is a png_error, but - * it will be freed by destroy_read_struct. - */ - if (png_ptr->unknown_chunk.data != NULL) - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - -#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ - /* There is no support to read an unknown chunk, so just skip it. */ - png_crc_finish(png_ptr, length); - PNG_UNUSED(info_ptr) - PNG_UNUSED(keep) -#endif /* !READ_UNKNOWN_CHUNKS */ - - /* Check for unhandled critical chunks */ - if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) - png_chunk_error(png_ptr, "unhandled critical chunk"); -} - -/* This function is called to verify that a chunk name is valid. - * This function can't have the "critical chunk check" incorporated - * into it, since in the future we will need to be able to call user - * functions to handle unknown critical chunks after we check that - * the chunk name itself is valid. - */ - -/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: - * - * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) - */ - -void /* PRIVATE */ -png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name) -{ - int i; - png_uint_32 cn=chunk_name; - - png_debug(1, "in png_check_chunk_name"); - - for (i=1; i<=4; ++i) - { - int c = cn & 0xff; - - if (c < 65 || c > 122 || (c > 90 && c < 97)) - png_chunk_error(png_ptr, "invalid chunk type"); - - cn >>= 8; - } -} - -void /* PRIVATE */ -png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) -{ - png_alloc_size_t limit = PNG_UINT_31_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - if (png_ptr->chunk_name == png_IDAT) - { - png_alloc_size_t idat_limit = PNG_UINT_31_MAX; - size_t row_factor = - (size_t)png_ptr->width - * (size_t)png_ptr->channels - * (png_ptr->bit_depth > 8? 2: 1) - + 1 - + (png_ptr->interlaced? 6: 0); - if (png_ptr->height > PNG_UINT_32_MAX/row_factor) - idat_limit = PNG_UINT_31_MAX; - else - idat_limit = png_ptr->height * row_factor; - row_factor = row_factor > 32566? 32566 : row_factor; - idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ - idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; - limit = limit < idat_limit? idat_limit : limit; - } - - if (length > limit) - { - png_debug2(0," length = %lu, limit = %lu", - (unsigned long)length,(unsigned long)limit); - png_benign_error(png_ptr, "chunk data is too large"); - } -} - -/* Combines the row recently read in with the existing pixels in the row. This - * routine takes care of alpha and transparency if requested. This routine also - * handles the two methods of progressive display of interlaced images, - * depending on the 'display' value; if 'display' is true then the whole row - * (dp) is filled from the start by replicating the available pixels. If - * 'display' is false only those pixels present in the pass are filled in. - */ -void /* PRIVATE */ -png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) -{ - unsigned int pixel_depth = png_ptr->transformed_pixel_depth; - png_const_bytep sp = png_ptr->row_buf + 1; - png_alloc_size_t row_width = png_ptr->width; - unsigned int pass = png_ptr->pass; - png_bytep end_ptr = 0; - png_byte end_byte = 0; - unsigned int end_mask; - - png_debug(1, "in png_combine_row"); - - /* Added in 1.5.6: it should not be possible to enter this routine until at - * least one row has been read from the PNG data and transformed. - */ - if (pixel_depth == 0) - png_error(png_ptr, "internal row logic error"); - - /* Added in 1.5.4: the pixel depth should match the information returned by - * any call to png_read_update_info at this point. Do not continue if we got - * this wrong. - */ - if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != - PNG_ROWBYTES(pixel_depth, row_width)) - png_error(png_ptr, "internal row size calculation error"); - - /* Don't expect this to ever happen: */ - if (row_width == 0) - png_error(png_ptr, "internal row width error"); - - /* Preserve the last byte in cases where only part of it will be overwritten, - * the multiply below may overflow, we don't care because ANSI-C guarantees - * we get the low bits. - */ - end_mask = (pixel_depth * row_width) & 7; - if (end_mask != 0) - { - /* end_ptr == NULL is a flag to say do nothing */ - end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; - end_byte = *end_ptr; -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - /* little-endian byte */ - end_mask = (unsigned int)(0xff << end_mask); - - else /* big-endian byte */ -# endif - end_mask = 0xff >> end_mask; - /* end_mask is now the bits to *keep* from the destination row */ - } - - /* For non-interlaced images this reduces to a memcpy(). A memcpy() - * will also happen if interlacing isn't supported or if the application - * does not call png_set_interlace_handling(). In the latter cases the - * caller just gets a sequence of the unexpanded rows from each interlace - * pass. - */ -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0 && - pass < 6 && (display == 0 || - /* The following copies everything for 'display' on passes 0, 2 and 4. */ - (display == 1 && (pass & 1) != 0))) - { - /* Narrow images may have no bits in a pass; the caller should handle - * this, but this test is cheap: - */ - if (row_width <= PNG_PASS_START_COL(pass)) - return; - - if (pixel_depth < 8) - { - /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit - * into 32 bits, then a single loop over the bytes using the four byte - * values in the 32-bit mask can be used. For the 'display' option the - * expanded mask may also not require any masking within a byte. To - * make this work the PACKSWAP option must be taken into account - it - * simply requires the pixels to be reversed in each byte. - * - * The 'regular' case requires a mask for each of the first 6 passes, - * the 'display' case does a copy for the even passes in the range - * 0..6. This has already been handled in the test above. - * - * The masks are arranged as four bytes with the first byte to use in - * the lowest bits (little-endian) regardless of the order (PACKSWAP or - * not) of the pixels in each byte. - * - * NOTE: the whole of this logic depends on the caller of this function - * only calling it on rows appropriate to the pass. This function only - * understands the 'x' logic; the 'y' logic is handled by the caller. - * - * The following defines allow generation of compile time constant bit - * masks for each pixel depth and each possibility of swapped or not - * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, - * is in the range 0..7; and the result is 1 if the pixel is to be - * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' - * for the block method. - * - * With some compilers a compile time expression of the general form: - * - * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) - * - * Produces warnings with values of 'shift' in the range 33 to 63 - * because the right hand side of the ?: expression is evaluated by - * the compiler even though it isn't used. Microsoft Visual C (various - * versions) and the Intel C compiler are known to do this. To avoid - * this the following macros are used in 1.5.6. This is a temporary - * solution to avoid destabilizing the code during the release process. - */ -# if PNG_USE_COMPILE_TIME_MASKS -# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) -# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) -# else -# define PNG_LSR(x,s) ((x)>>(s)) -# define PNG_LSL(x,s) ((x)<<(s)) -# endif -# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ - PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) -# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ - PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) - - /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is - * little endian - the first pixel is at bit 0 - however the extra - * parameter 's' can be set to cause the mask position to be swapped - * within each byte, to match the PNG format. This is done by XOR of - * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. - */ -# define PIXEL_MASK(p,x,d,s) \ - (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) - - /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. - */ -# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) -# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) - - /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp - * cases the result needs replicating, for the 4-bpp case the above - * generates a full 32 bits. - */ -# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) - -# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ - S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ - S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) - -# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ - B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ - B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) - -#if PNG_USE_COMPILE_TIME_MASKS - /* Utility macros to construct all the masks for a depth/swap - * combination. The 's' parameter says whether the format is PNG - * (big endian bytes) or not. Only the three odd-numbered passes are - * required for the display/block algorithm. - */ -# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ - S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } - -# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) } - -# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) - - /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and - * then pass: - */ - static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = - { - /* Little-endian byte masks for PACKSWAP */ - { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, - /* Normal (big-endian byte) masks - PNG format */ - { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } - }; - - /* display_mask has only three entries for the odd passes, so index by - * pass>>1. - */ - static const png_uint_32 display_mask[2][3][3] = - { - /* Little-endian byte masks for PACKSWAP */ - { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, - /* Normal (big-endian byte) masks - PNG format */ - { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } - }; - -# define MASK(pass,depth,display,png)\ - ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ - row_mask[png][DEPTH_INDEX(depth)][pass]) - -#else /* !PNG_USE_COMPILE_TIME_MASKS */ - /* This is the runtime alternative: it seems unlikely that this will - * ever be either smaller or faster than the compile time approach. - */ -# define MASK(pass,depth,display,png)\ - ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) -#endif /* !USE_COMPILE_TIME_MASKS */ - - /* Use the appropriate mask to copy the required bits. In some cases - * the byte mask will be 0 or 0xff; optimize these cases. row_width is - * the number of pixels, but the code copies bytes, so it is necessary - * to special case the end. - */ - png_uint_32 pixels_per_byte = 8 / pixel_depth; - png_uint_32 mask; - -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - mask = MASK(pass, pixel_depth, display, 0); - - else -# endif - mask = MASK(pass, pixel_depth, display, 1); - - for (;;) - { - png_uint_32 m; - - /* It doesn't matter in the following if png_uint_32 has more than - * 32 bits because the high bits always match those in m<<24; it is, - * however, essential to use OR here, not +, because of this. - */ - m = mask; - mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ - m &= 0xff; - - if (m != 0) /* something to copy */ - { - if (m != 0xff) - *dp = (png_byte)((*dp & ~m) | (*sp & m)); - else - *dp = *sp; - } - - /* NOTE: this may overwrite the last byte with garbage if the image - * is not an exact number of bytes wide; libpng has always done - * this. - */ - if (row_width <= pixels_per_byte) - break; /* May need to restore part of the last byte */ - - row_width -= pixels_per_byte; - ++dp; - ++sp; - } - } - - else /* pixel_depth >= 8 */ - { - unsigned int bytes_to_copy, bytes_to_jump; - - /* Validate the depth - it must be a multiple of 8 */ - if (pixel_depth & 7) - png_error(png_ptr, "invalid user transform pixel depth"); - - pixel_depth >>= 3; /* now in bytes */ - row_width *= pixel_depth; - - /* Regardless of pass number the Adam 7 interlace always results in a - * fixed number of pixels to copy then to skip. There may be a - * different number of pixels to skip at the start though. - */ - { - unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; - - row_width -= offset; - dp += offset; - sp += offset; - } - - /* Work out the bytes to copy. */ - if (display != 0) - { - /* When doing the 'block' algorithm the pixel in the pass gets - * replicated to adjacent pixels. This is why the even (0,2,4,6) - * passes are skipped above - the entire expanded row is copied. - */ - bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; - - /* But don't allow this number to exceed the actual row width. */ - if (bytes_to_copy > row_width) - bytes_to_copy = (unsigned int)/*SAFE*/row_width; - } - - else /* normal row; Adam7 only ever gives us one pixel to copy. */ - bytes_to_copy = pixel_depth; - - /* In Adam7 there is a constant offset between where the pixels go. */ - bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; - - /* And simply copy these bytes. Some optimization is possible here, - * depending on the value of 'bytes_to_copy'. Special case the low - * byte counts, which we know to be frequent. - * - * Notice that these cases all 'return' rather than 'break' - this - * avoids an unnecessary test on whether to restore the last byte - * below. - */ - switch (bytes_to_copy) - { - case 1: - for (;;) - { - *dp = *sp; - - if (row_width <= bytes_to_jump) - return; - - dp += bytes_to_jump; - sp += bytes_to_jump; - row_width -= bytes_to_jump; - } - - case 2: - /* There is a possibility of a partial copy at the end here; this - * slows the code down somewhat. - */ - do - { - dp[0] = sp[0]; dp[1] = sp[1]; - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - } - while (row_width > 1); - - /* And there can only be one byte left at this point: */ - *dp = *sp; - return; - - case 3: - /* This can only be the RGB case, so each copy is exactly one - * pixel and it is not necessary to check for a partial copy. - */ - for (;;) - { - dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2]; - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - } - - default: -#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE - /* Check for double byte alignment and, if possible, use a - * 16-bit copy. Don't attempt this for narrow images - ones that - * are less than an interlace panel wide. Don't attempt it for - * wide bytes_to_copy either - use the memcpy there. - */ - if (bytes_to_copy < 16 /*else use memcpy*/ && - png_isaligned(dp, png_uint_16) && - png_isaligned(sp, png_uint_16) && - bytes_to_copy % (sizeof (png_uint_16)) == 0 && - bytes_to_jump % (sizeof (png_uint_16)) == 0) - { - /* Everything is aligned for png_uint_16 copies, but try for - * png_uint_32 first. - */ - if (png_isaligned(dp, png_uint_32) && - png_isaligned(sp, png_uint_32) && - bytes_to_copy % (sizeof (png_uint_32)) == 0 && - bytes_to_jump % (sizeof (png_uint_32)) == 0) - { - png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); - png_const_uint_32p sp32 = png_aligncastconst( - png_const_uint_32p, sp); - size_t skip = (bytes_to_jump-bytes_to_copy) / - (sizeof (png_uint_32)); - - do - { - size_t c = bytes_to_copy; - do - { - *dp32++ = *sp32++; - c -= (sizeof (png_uint_32)); - } - while (c > 0); - - if (row_width <= bytes_to_jump) - return; - - dp32 += skip; - sp32 += skip; - row_width -= bytes_to_jump; - } - while (bytes_to_copy <= row_width); - - /* Get to here when the row_width truncates the final copy. - * There will be 1-3 bytes left to copy, so don't try the - * 16-bit loop below. - */ - dp = (png_bytep)dp32; - sp = (png_const_bytep)sp32; - do - *dp++ = *sp++; - while (--row_width > 0); - return; - } - - /* Else do it in 16-bit quantities, but only if the size is - * not too large. - */ - else - { - png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); - png_const_uint_16p sp16 = png_aligncastconst( - png_const_uint_16p, sp); - size_t skip = (bytes_to_jump-bytes_to_copy) / - (sizeof (png_uint_16)); - - do - { - size_t c = bytes_to_copy; - do - { - *dp16++ = *sp16++; - c -= (sizeof (png_uint_16)); - } - while (c > 0); - - if (row_width <= bytes_to_jump) - return; - - dp16 += skip; - sp16 += skip; - row_width -= bytes_to_jump; - } - while (bytes_to_copy <= row_width); - - /* End of row - 1 byte left, bytes_to_copy > row_width: */ - dp = (png_bytep)dp16; - sp = (png_const_bytep)sp16; - do - *dp++ = *sp++; - while (--row_width > 0); - return; - } - } -#endif /* ALIGN_TYPE code */ - - /* The true default - use a memcpy: */ - for (;;) - { - memcpy(dp, sp, bytes_to_copy); - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - if (bytes_to_copy > row_width) - bytes_to_copy = (unsigned int)/*SAFE*/row_width; - } - } - - /* NOT REACHED*/ - } /* pixel_depth >= 8 */ - - /* Here if pixel_depth < 8 to check 'end_ptr' below. */ - } - else -#endif /* READ_INTERLACING */ - - /* If here then the switch above wasn't used so just memcpy the whole row - * from the temporary row buffer (notice that this overwrites the end of the - * destination row if it is a partial byte.) - */ - memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); - - /* Restore the overwritten bits from the last byte if necessary. */ - if (end_ptr != NULL) - *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -void /* PRIVATE */ -png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, - png_uint_32 transformations /* Because these may affect the byte layout */) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* Offset to next interlace block */ - static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_read_interlace"); - if (row != NULL && row_info != NULL) - { - png_uint_32 final_width; - - final_width = row_info->width * png_pass_inc[pass]; - - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp = row + (size_t)((row_info->width - 1) >> 3); - png_bytep dp = row + (size_t)((final_width - 1) >> 3); - unsigned int sshift, dshift; - unsigned int s_start, s_end; - int s_inc; - int jstop = (int)png_pass_inc[pass]; - png_byte v; - png_uint_32 i; - int j; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = ((row_info->width + 7) & 0x07); - dshift = ((final_width + 7) & 0x07); - s_start = 7; - s_end = 0; - s_inc = -1; - } - - else -#endif - { - sshift = 7 - ((row_info->width + 7) & 0x07); - dshift = 7 - ((final_width + 7) & 0x07); - s_start = 0; - s_end = 7; - s_inc = 1; - } - - for (i = 0; i < row_info->width; i++) - { - v = (png_byte)((*sp >> sshift) & 0x01); - for (j = 0; j < jstop; j++) - { - unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); - tmp |= (unsigned int)(v << dshift); - *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift = (unsigned int)((int)dshift + s_inc); - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift = (unsigned int)((int)sshift + s_inc); - } - break; - } - - case 2: - { - png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); - png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); - unsigned int sshift, dshift; - unsigned int s_start, s_end; - int s_inc; - int jstop = (int)png_pass_inc[pass]; - png_uint_32 i; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (((row_info->width + 3) & 0x03) << 1); - dshift = (((final_width + 3) & 0x03) << 1); - s_start = 6; - s_end = 0; - s_inc = -2; - } - - else -#endif - { - sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1); - dshift = ((3 - ((final_width + 3) & 0x03)) << 1); - s_start = 0; - s_end = 6; - s_inc = 2; - } - - for (i = 0; i < row_info->width; i++) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0x03); - for (j = 0; j < jstop; j++) - { - unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); - tmp |= (unsigned int)(v << dshift); - *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift = (unsigned int)((int)dshift + s_inc); - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift = (unsigned int)((int)sshift + s_inc); - } - break; - } - - case 4: - { - png_bytep sp = row + (size_t)((row_info->width - 1) >> 1); - png_bytep dp = row + (size_t)((final_width - 1) >> 1); - unsigned int sshift, dshift; - unsigned int s_start, s_end; - int s_inc; - png_uint_32 i; - int jstop = (int)png_pass_inc[pass]; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (((row_info->width + 1) & 0x01) << 2); - dshift = (((final_width + 1) & 0x01) << 2); - s_start = 4; - s_end = 0; - s_inc = -4; - } - - else -#endif - { - sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2); - dshift = ((1 - ((final_width + 1) & 0x01)) << 2); - s_start = 0; - s_end = 4; - s_inc = 4; - } - - for (i = 0; i < row_info->width; i++) - { - png_byte v = (png_byte)((*sp >> sshift) & 0x0f); - int j; - - for (j = 0; j < jstop; j++) - { - unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); - tmp |= (unsigned int)(v << dshift); - *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift = (unsigned int)((int)dshift + s_inc); - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift = (unsigned int)((int)sshift + s_inc); - } - break; - } - - default: - { - size_t pixel_bytes = (row_info->pixel_depth >> 3); - - png_bytep sp = row + (size_t)(row_info->width - 1) - * pixel_bytes; - - png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes; - - int jstop = (int)png_pass_inc[pass]; - png_uint_32 i; - - for (i = 0; i < row_info->width; i++) - { - png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ - int j; - - memcpy(v, sp, pixel_bytes); - - for (j = 0; j < jstop; j++) - { - memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - - sp -= pixel_bytes; - } - break; - } - } - - row_info->width = final_width; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); - } -#ifndef PNG_READ_PACKSWAP_SUPPORTED - PNG_UNUSED(transformations) /* Silence compiler warning */ -#endif -} -#endif /* READ_INTERLACING */ - -static void -png_read_filter_row_sub(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - size_t i; - size_t istop = row_info->rowbytes; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp = row + bpp; - - PNG_UNUSED(prev_row) - - for (i = bpp; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); - rp++; - } -} - -static void -png_read_filter_row_up(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - size_t i; - size_t istop = row_info->rowbytes; - png_bytep rp = row; - png_const_bytep pp = prev_row; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } -} - -static void -png_read_filter_row_avg(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - size_t i; - png_bytep rp = row; - png_const_bytep pp = prev_row; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - size_t istop = row_info->rowbytes - bpp; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) / 2 )) & 0xff); - - rp++; - } - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + - (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); - - rp++; - } -} - -static void -png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp_end = row + row_info->rowbytes; - int a, c; - - /* First pixel/byte */ - c = *prev_row++; - a = *row + c; - *row++ = (png_byte)a; - - /* Remainder */ - while (row < rp_end) - { - int b, pa, pb, pc, p; - - a &= 0xff; /* From previous iteration or start */ - b = *prev_row++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - /* Find the best predictor, the least of pa, pb, pc favoring the earlier - * ones in the case of a tie. - */ - if (pb < pa) - { - pa = pb; a = b; - } - if (pc < pa) a = c; - - /* Calculate the current pixel in a, and move the previous row pixel to c - * for the next time round the loop - */ - c = b; - a += *row; - *row++ = (png_byte)a; - } -} - -static void -png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp_end = row + bpp; - - /* Process the first pixel in the row completely (this is the same as 'up' - * because there is only one candidate predictor for the first row). - */ - while (row < rp_end) - { - int a = *row + *prev_row++; - *row++ = (png_byte)a; - } - - /* Remainder */ - rp_end = rp_end + (row_info->rowbytes - bpp); - - while (row < rp_end) - { - int a, b, c, pa, pb, pc, p; - - c = *(prev_row - bpp); - a = *(row - bpp); - b = *prev_row++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - if (pb < pa) - { - pa = pb; a = b; - } - if (pc < pa) a = c; - - a += *row; - *row++ = (png_byte)a; - } -} - -static void -png_init_filter_functions(png_structrp pp) - /* This function is called once for every PNG image (except for PNG images - * that only use PNG_FILTER_VALUE_NONE for all rows) to set the - * implementations required to reverse the filtering of PNG rows. Reversing - * the filter is the first transformation performed on the row data. It is - * performed in place, therefore an implementation can be selected based on - * the image pixel format. If the implementation depends on image width then - * take care to ensure that it works correctly if the image is interlaced - - * interlacing causes the actual row width to vary. - */ -{ - unsigned int bpp = (pp->pixel_depth + 7) >> 3; - - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; - if (bpp == 1) - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_1byte_pixel; - else - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_multibyte_pixel; - -#ifdef PNG_FILTER_OPTIMIZATIONS - /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to - * call to install hardware optimizations for the above functions; simply - * replace whatever elements of the pp->read_filter[] array with a hardware - * specific (or, for that matter, generic) optimization. - * - * To see an example of this examine what configure.ac does when - * --enable-arm-neon is specified on the command line. - */ - PNG_FILTER_OPTIMIZATIONS(pp, bpp); -#endif -} - -void /* PRIVATE */ -png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, - png_const_bytep prev_row, int filter) -{ - /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define - * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic - * implementations. See png_init_filter_functions above. - */ - if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) - { - if (pp->read_filter[0] == NULL) - png_init_filter_functions(pp); - - pp->read_filter[filter-1](row_info, row, prev_row); - } -} - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -void /* PRIVATE */ -png_read_IDAT_data(png_structrp png_ptr, png_bytep output, - png_alloc_size_t avail_out) -{ - /* Loop reading IDATs and decompressing the result into output[avail_out] */ - png_ptr->zstream.next_out = output; - png_ptr->zstream.avail_out = 0; /* safety: set below */ - - if (output == NULL) - avail_out = 0; - - do - { - int ret; - png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; - - if (png_ptr->zstream.avail_in == 0) - { - uInt avail_in; - png_bytep buffer; - - while (png_ptr->idat_size == 0) - { - png_crc_finish(png_ptr, 0); - - png_ptr->idat_size = png_read_chunk_header(png_ptr); - /* This is an error even in the 'check' case because the code just - * consumed a non-IDAT header. - */ - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); - } - - avail_in = png_ptr->IDAT_read_size; - - if (avail_in > png_ptr->idat_size) - avail_in = (uInt)png_ptr->idat_size; - - /* A PNG with a gradually increasing IDAT size will defeat this attempt - * to minimize memory usage by causing lots of re-allocs, but - * realistically doing IDAT_read_size re-allocs is not likely to be a - * big problem. - */ - buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); - - png_crc_read(png_ptr, buffer, avail_in); - png_ptr->idat_size -= avail_in; - - png_ptr->zstream.next_in = buffer; - png_ptr->zstream.avail_in = avail_in; - } - - /* And set up the output side. */ - if (output != NULL) /* standard read */ - { - uInt out = ZLIB_IO_MAX; - - if (out > avail_out) - out = (uInt)avail_out; - - avail_out -= out; - png_ptr->zstream.avail_out = out; - } - - else /* after last row, checking for end */ - { - png_ptr->zstream.next_out = tmpbuf; - png_ptr->zstream.avail_out = (sizeof tmpbuf); - } - - /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the - * process. If the LZ stream is truncated the sequential reader will - * terminally damage the stream, above, by reading the chunk header of the - * following chunk (it then exits with png_error). - * - * TODO: deal more elegantly with truncated IDAT lists. - */ - ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH); - - /* Take the unconsumed output back. */ - if (output != NULL) - avail_out += png_ptr->zstream.avail_out; - - else /* avail_out counts the extra bytes */ - avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; - - png_ptr->zstream.avail_out = 0; - - if (ret == Z_STREAM_END) - { - /* Do this for safety; we won't read any more into this row. */ - png_ptr->zstream.next_out = NULL; - - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - - if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) - png_chunk_benign_error(png_ptr, "Extra compressed data"); - break; - } - - if (ret != Z_OK) - { - png_zstream_error(png_ptr, ret); - - if (output != NULL) - png_chunk_error(png_ptr, png_ptr->zstream.msg); - - else /* checking */ - { - png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); - return; - } - } - } while (avail_out > 0); - - if (avail_out > 0) - { - /* The stream ended before the image; this is the same as too few IDATs so - * should be handled the same way. - */ - if (output != NULL) - png_error(png_ptr, "Not enough image data"); - - else /* the deflate stream contained extra data */ - png_chunk_benign_error(png_ptr, "Too much image data"); - } -} - -void /* PRIVATE */ -png_read_finish_IDAT(png_structrp png_ptr) -{ - /* We don't need any more data and the stream should have ended, however the - * LZ end code may actually not have been processed. In this case we must - * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk - * may still remain to be consumed. - */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - { - /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in - * the compressed stream, but the stream may be damaged too, so even after - * this call we may need to terminate the zstream ownership. - */ - png_read_IDAT_data(png_ptr, NULL, 0); - png_ptr->zstream.next_out = NULL; /* safety */ - - /* Now clear everything out for safety; the following may not have been - * done. - */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - { - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - } - } - - /* If the zstream has not been released do it now *and* terminate the reading - * of the final IDAT chunk. - */ - if (png_ptr->zowner == png_IDAT) - { - /* Always do this; the pointers otherwise point into the read buffer. */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - - /* Now we no longer own the zstream. */ - png_ptr->zowner = 0; - - /* The slightly weird semantics of the sequential IDAT reading is that we - * are always in or at the end of an IDAT chunk, so we always need to do a - * crc_finish here. If idat_size is non-zero we also need to read the - * spurious bytes at the end of the chunk now. - */ - (void)png_crc_finish(png_ptr, png_ptr->idat_size); - } -} - -void /* PRIVATE */ -png_read_finish_row(png_structrp png_ptr) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - - png_debug(1, "in png_read_finish_row"); - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - - if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - - /* TO DO: don't do this if prev_row isn't needed (requires - * read-ahead of the next row's filter byte. - */ - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { - png_ptr->pass++; - - if (png_ptr->pass >= 7) - break; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - { - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - } - - else /* if (png_ptr->transformations & PNG_INTERLACE) */ - break; /* libpng deinterlacing sees every row */ - - } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); - - if (png_ptr->pass < 7) - return; - } - - /* Here after at the end of the last row of the last pass. */ - png_read_finish_IDAT(png_ptr); -} -#endif /* SEQUENTIAL_READ */ - -void /* PRIVATE */ -png_read_start_row(png_structrp png_ptr) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - - unsigned int max_pixel_depth; - size_t row_bytes; - - png_debug(1, "in png_read_start_row"); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_init_read_transformations(png_ptr); -#endif - if (png_ptr->interlaced != 0) - { - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - - else - png_ptr->num_rows = png_ptr->height; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - } - - else - { - png_ptr->num_rows = png_ptr->height; - png_ptr->iwidth = png_ptr->width; - } - - max_pixel_depth = (unsigned int)png_ptr->pixel_depth; - - /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of - * calculations to calculate the final pixel depth, then - * png_do_read_transforms actually does the transforms. This means that the - * code which effectively calculates this value is actually repeated in three - * separate places. They must all match. Innocent changes to the order of - * transformations can and will break libpng in a way that causes memory - * overwrites. - * - * TODO: fix this. - */ -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8) - max_pixel_depth = 8; -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (png_ptr->num_trans != 0) - max_pixel_depth = 32; - - else - max_pixel_depth = 24; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth < 8) - max_pixel_depth = 8; - - if (png_ptr->num_trans != 0) - max_pixel_depth *= 2; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - if (png_ptr->num_trans != 0) - { - max_pixel_depth *= 4; - max_pixel_depth /= 3; - } - } - } -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND_16) != 0) - { -# ifdef PNG_READ_EXPAND_SUPPORTED - /* In fact it is an error if it isn't supported, but checking is - * the safe way. - */ - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->bit_depth < 16) - max_pixel_depth *= 2; - } - else -# endif - png_ptr->transformations &= ~PNG_EXPAND_16; - } -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if ((png_ptr->transformations & (PNG_FILLER)) != 0) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth <= 8) - max_pixel_depth = 16; - - else - max_pixel_depth = 32; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (max_pixel_depth <= 32) - max_pixel_depth = 32; - - else - max_pixel_depth = 64; - } - } -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - { - if ( -#ifdef PNG_READ_EXPAND_SUPPORTED - (png_ptr->num_trans != 0 && - (png_ptr->transformations & PNG_EXPAND) != 0) || -#endif -#ifdef PNG_READ_FILLER_SUPPORTED - (png_ptr->transformations & (PNG_FILLER)) != 0 || -#endif - png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (max_pixel_depth <= 16) - max_pixel_depth = 32; - - else - max_pixel_depth = 64; - } - - else - { - if (max_pixel_depth <= 8) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - max_pixel_depth = 32; - - else - max_pixel_depth = 24; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - max_pixel_depth = 64; - - else - max_pixel_depth = 48; - } - } -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ -defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - unsigned int user_pixel_depth = png_ptr->user_transform_depth * - png_ptr->user_transform_channels; - - if (user_pixel_depth > max_pixel_depth) - max_pixel_depth = user_pixel_depth; - } -#endif - - /* This value is stored in png_struct and double checked in the row read - * code. - */ - png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; - png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ - - /* Align the width on the next larger 8 pixels. Mainly used - * for interlacing - */ - row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); - /* Calculate the maximum bytes needed, adding a byte and a pixel - * for safety's sake - */ - row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + - 1 + ((max_pixel_depth + 7) >> 3U); - -#ifdef PNG_MAX_MALLOC_64K - if (row_bytes > (png_uint_32)65536L) - png_error(png_ptr, "This image requires a row greater than 64KB"); -#endif - - if (row_bytes + 48 > png_ptr->old_big_row_buf_size) - { - png_free(png_ptr, png_ptr->big_row_buf); - png_free(png_ptr, png_ptr->big_prev_row); - - if (png_ptr->interlaced != 0) - png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, - row_bytes + 48); - - else - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - - png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - -#ifdef PNG_ALIGNED_MEMORY_SUPPORTED - /* Use 16-byte aligned memory for row_buf with at least 16 bytes - * of padding before and after row_buf; treat prev_row similarly. - * NOTE: the alignment is to the start of the pixels, one beyond the start - * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this - * was incorrect; the filter byte was aligned, which had the exact - * opposite effect of that intended. - */ - { - png_bytep temp = png_ptr->big_row_buf + 32; - size_t extra = (size_t)temp & 0x0f; - png_ptr->row_buf = temp - extra - 1/*filter byte*/; - - temp = png_ptr->big_prev_row + 32; - extra = (size_t)temp & 0x0f; - png_ptr->prev_row = temp - extra - 1/*filter byte*/; - } -#else - /* Use 31 bytes of padding before and 17 bytes after row_buf. */ - png_ptr->row_buf = png_ptr->big_row_buf + 31; - png_ptr->prev_row = png_ptr->big_prev_row + 31; -#endif - png_ptr->old_big_row_buf_size = row_bytes + 48; - } - -#ifdef PNG_MAX_MALLOC_64K - if (png_ptr->rowbytes > 65535) - png_error(png_ptr, "This image requires a row greater than 64KB"); - -#endif - if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) - png_error(png_ptr, "Row has too many bytes to allocate in memory"); - - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - png_debug1(3, "width = %u,", png_ptr->width); - png_debug1(3, "height = %u,", png_ptr->height); - png_debug1(3, "iwidth = %u,", png_ptr->iwidth); - png_debug1(3, "num_rows = %u,", png_ptr->num_rows); - png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); - png_debug1(3, "irowbytes = %lu", - (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); - - /* The sequential reader needs a buffer for IDAT, but the progressive reader - * does not, so free the read buffer now regardless; the sequential reader - * reallocates it on demand. - */ - if (png_ptr->read_buffer != NULL) - { - png_bytep buffer = png_ptr->read_buffer; - - png_ptr->read_buffer_size = 0; - png_ptr->read_buffer = NULL; - png_free(png_ptr, buffer); - } - - /* Finally claim the zstream for the inflate of the IDAT data, use the bits - * value from the stream (note that this will result in a fatal error if the - * IDAT stream has a bogus deflate header window_bits value, but this should - * not be happening any longer!) - */ - if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - png_ptr->flags |= PNG_FLAG_ROW_INIT; -} -#endif /* READ */ +/* pngrutil.c - utilities to read a PNG file + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that are only called from within + * libpng itself during the course of reading an image. + */ + +#include "pngpriv.h" + +#ifdef PNG_READ_SUPPORTED + +/* The minimum 'zlib' stream is assumed to be just the 2 byte header, 5 bytes + * minimum 'deflate' stream, and the 4 byte checksum. + */ +#define LZ77Min (2U+5U+4U) + +#ifdef PNG_READ_INTERLACING_SUPPORTED +/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */ + +/* Start of interlace block */ +static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; +/* Offset to next interlace block */ +static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +/* Start of interlace block in the y direction */ +static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; +/* Offset to next interlace block in the y direction */ +static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + +/* TODO: Move these arrays to a common utility module to avoid duplication. */ +#endif + +png_uint_32 PNGAPI +png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range"); + + return uval; +} + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +/* NOTE: the read macros will obscure these definitions, so that if + * PNG_USE_READ_MACROS is set the library will not use them internally, + * but the APIs will still be available externally. + * + * The parentheses around "PNGAPI function_name" in the following three + * functions are necessary because they allow the macros to co-exist with + * these (unused but exported) functions. + */ + +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ +png_uint_32 (PNGAPI +png_get_uint_32)(png_const_bytep buf) +{ + png_uint_32 uval = + ((png_uint_32)(*(buf )) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + ((png_uint_32)(*(buf + 3)) ) ; + + return uval; +} + +/* Grab a signed 32-bit integer from a buffer in big-endian format. The + * data is stored in the PNG file in two's complement format and there + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore + * the following code does a two's complement to native conversion. + */ +png_int_32 (PNGAPI +png_get_int_32)(png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + if ((uval & 0x80000000) == 0) /* non-negative */ + return (png_int_32)uval; + + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + if ((uval & 0x80000000) == 0) /* no overflow */ + return -(png_int_32)uval; + /* The following has to be safe; this function only gets called on PNG data + * and if we get here that data is invalid. 0 is the most safe value and + * if not then an attacker would surely just generate a PNG with 0 instead. + */ + return 0; +} + +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ +png_uint_16 (PNGAPI +png_get_uint_16)(png_const_bytep buf) +{ + /* ANSI-C requires an int value to accommodate at least 16 bits so this + * works and allows the compiler not to worry about possible narrowing + * on 32-bit systems. (Pre-ANSI systems did not make integers smaller + * than 16 bits either.) + */ + unsigned int val = + ((unsigned int)(*buf) << 8) + + ((unsigned int)(*(buf + 1))); + + return (png_uint_16)val; +} + +#endif /* READ_INT_FUNCTIONS */ + +/* Read and check the PNG file signature */ +void /* PRIVATE */ +png_read_sig(png_structrp png_ptr, png_inforp info_ptr) +{ + size_t num_checked, num_to_check; + + /* Exit if the user application does not expect a signature. */ + if (png_ptr->sig_bytes >= 8) + return; + + num_checked = png_ptr->sig_bytes; + num_to_check = 8 - num_checked; + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; +#endif + + /* The signature must be serialized in a single I/O call. */ + png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); + png_ptr->sig_bytes = 8; + + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) + { + if (num_checked < 4 && + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) + png_error(png_ptr, "Not a PNG file"); + else + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); + } + if (num_checked < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; +} + +/* This function is called to verify that a chunk name is valid. + * Do this using the bit-whacking approach from contrib/tools/pngfix.c + * + * Copied from libpng 1.7. + */ +static int +check_chunk_name(png_uint_32 name) +{ + png_uint_32 t; + + /* Remove bit 5 from all but the reserved byte; this means + * every 8-bit unit must be in the range 65-90 to be valid. + * So bit 5 must be zero, bit 6 must be set and bit 7 zero. + */ + name &= ~PNG_U32(32,32,0,32); + t = (name & ~0x1f1f1f1fU) ^ 0x40404040U; + + /* Subtract 65 for each 8-bit quantity, this must not + * overflow and each byte must then be in the range 0-25. + */ + name -= PNG_U32(65,65,65,65); + t |= name; + + /* Subtract 26, handling the overflow which should set the + * top three bits of each byte. + */ + name -= PNG_U32(25,25,25,26); + t |= ~name; + + return (t & 0xe0e0e0e0U) == 0U; +} + +/* Read the chunk header (length + type name). + * Put the type name into png_ptr->chunk_name, and return the length. + */ +png_uint_32 /* PRIVATE */ +png_read_chunk_header(png_structrp png_ptr) +{ + png_byte buf[8]; + png_uint_32 chunk_name, length; + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; +#endif + + /* Read the length and the chunk name. png_struct::chunk_name is immediately + * updated even if they are detectably wrong. This aids error message + * handling by allowing png_chunk_error to be used. + */ + png_read_data(png_ptr, buf, 8); + length = png_get_uint_31(png_ptr, buf); + png_ptr->chunk_name = chunk_name = PNG_CHUNK_FROM_STRING(buf+4); + + /* Reset the crc and run it over the chunk name. */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, buf + 4, 4); + + png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu", + (unsigned long)png_ptr->chunk_name, (unsigned long)length); + + /* Sanity check the length (first by <= 0x80) and the chunk name. An error + * here indicates a broken stream and libpng has no recovery from this. + */ + if (buf[0] >= 0x80U) + png_chunk_error(png_ptr, "bad header (invalid length)"); + + /* Check to see if chunk name is valid. */ + if (!check_chunk_name(chunk_name)) + png_chunk_error(png_ptr, "bad header (invalid type)"); + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; +#endif + + return length; +} + +/* Read data, and (optionally) run it through the CRC. */ +void /* PRIVATE */ +png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) +{ + if (png_ptr == NULL) + return; + + png_read_data(png_ptr, buf, length); + png_calculate_crc(png_ptr, buf, length); +} + +/* Compare the CRC stored in the PNG file with that calculated by libpng from + * the data it has read thus far. + */ +static int +png_crc_error(png_structrp png_ptr, int handle_as_ancillary) +{ + png_byte crc_bytes[4]; + png_uint_32 crc; + int need_crc = 1; + + /* There are four flags two for ancillary and two for critical chunks. The + * default setting of these flags is all zero. + * + * PNG_FLAG_CRC_ANCILLARY_USE + * PNG_FLAG_CRC_ANCILLARY_NOWARN + * USE+NOWARN: no CRC calculation (implemented here), else; + * NOWARN: png_chunk_error on error (implemented in png_crc_finish) + * else: png_chunk_warning on error (implemented in png_crc_finish) + * This is the default. + * + * I.e. NOWARN without USE produces png_chunk_error. The default setting + * where neither are set does the same thing. + * + * PNG_FLAG_CRC_CRITICAL_USE + * PNG_FLAG_CRC_CRITICAL_IGNORE + * IGNORE: no CRC calculation (implemented here), else; + * USE: png_chunk_warning on error (implemented in png_crc_finish) + * else: png_chunk_error on error (implemented in png_crc_finish) + * This is the default. + * + * This arose because of original mis-implementation and has persisted for + * compatibility reasons. + * + * TODO: the flag names are internal so maybe this can be changed to + * something comprehensible. + */ + if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) + { + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) + need_crc = 0; + } + + else /* critical */ + { + if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) + need_crc = 0; + } + +#ifdef PNG_IO_STATE_SUPPORTED + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; +#endif + + /* The chunk CRC must be serialized in a single I/O call. */ + png_read_data(png_ptr, crc_bytes, 4); + + if (need_crc != 0) + { + crc = png_get_uint_32(crc_bytes); + return crc != png_ptr->crc; + } + + else + return 0; +} + +/* Optionally skip data and then check the CRC. Depending on whether we + * are reading an ancillary or critical chunk, and how the program has set + * things up, we may calculate the CRC on the data and print a message. + * Returns '1' if there was a CRC error, '0' otherwise. + * + * There is one public version which is used in most places and another which + * takes the value for the 'critical' flag to check. This allows PLTE and IEND + * handling code to ignore the CRC error and removes some confusing code + * duplication. + */ +static int +png_crc_finish_critical(png_structrp png_ptr, png_uint_32 skip, + int handle_as_ancillary) +{ + /* The size of the local buffer for inflate is a good guess as to a + * reasonable size to use for buffering reads from the application. + */ + while (skip > 0) + { + png_uint_32 len; + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; + + len = (sizeof tmpbuf); + if (len > skip) + len = skip; + skip -= len; + + png_crc_read(png_ptr, tmpbuf, len); + } + + /* If 'handle_as_ancillary' has been requested and this is a critical chunk + * but PNG_FLAG_CRC_CRITICAL_IGNORE was set then png_read_crc did not, in + * fact, calculate the CRC so the ANCILLARY settings should not be used + * instead. + */ + if (handle_as_ancillary && + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) + handle_as_ancillary = 0; + + /* TODO: this might be more comprehensible if png_crc_error was inlined here. + */ + if (png_crc_error(png_ptr, handle_as_ancillary) != 0) + { + /* See above for the explanation of how the flags work. */ + if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? + (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) + png_chunk_warning(png_ptr, "CRC error"); + + else + png_chunk_error(png_ptr, "CRC error"); + + return 1; + } + + return 0; +} + +int /* PRIVATE */ +png_crc_finish(png_structrp png_ptr, png_uint_32 skip) +{ + return png_crc_finish_critical(png_ptr, skip, 0/*critical handling*/); +} + +#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ + defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ + defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ + defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_eXIf_SUPPORTED) ||\ + defined(PNG_SEQUENTIAL_READ_SUPPORTED) +/* Manage the read buffer; this simply reallocates the buffer if it is not small + * enough (or if it is not allocated). The routine returns a pointer to the + * buffer; if an error occurs and 'warn' is set the routine returns NULL, else + * it will call png_error on failure. + */ +static png_bytep +png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size) +{ + png_bytep buffer = png_ptr->read_buffer; + + if (new_size > png_chunk_max(png_ptr)) return NULL; + + if (buffer != NULL && new_size > png_ptr->read_buffer_size) + { + png_ptr->read_buffer = NULL; + png_ptr->read_buffer_size = 0; + png_free(png_ptr, buffer); + buffer = NULL; + } + + if (buffer == NULL) + { + buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); + + if (buffer != NULL) + { +# ifndef PNG_NO_MEMZERO /* for detecting UIM bugs **only** */ + memset(buffer, 0, new_size); /* just in case */ +# endif + png_ptr->read_buffer = buffer; + png_ptr->read_buffer_size = new_size; + } + } + + return buffer; +} +#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|eXIf|SEQUENTIAL_READ */ + +/* png_inflate_claim: claim the zstream for some nefarious purpose that involves + * decompression. Returns Z_OK on success, else a zlib error code. It checks + * the owner but, in final release builds, just issues a warning if some other + * chunk apparently owns the stream. Prior to release it does a png_error. + */ +static int +png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) +{ + if (png_ptr->zowner != 0) + { + char msg[64]; + + PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); + /* So the message that results is " using zstream"; this is an + * internal error, but is very useful for debugging. i18n requirements + * are minimal. + */ + (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); +#if PNG_RELEASE_BUILD + png_chunk_warning(png_ptr, msg); + png_ptr->zowner = 0; +#else + png_chunk_error(png_ptr, msg); +#endif + } + + /* Implementation note: unlike 'png_deflate_claim' this internal function + * does not take the size of the data as an argument. Some efficiency could + * be gained by using this when it is known *if* the zlib stream itself does + * not record the number; however, this is an illusion: the original writer + * of the PNG may have selected a lower window size, and we really must + * follow that because, for systems with limited capabilities, we + * would otherwise reject the application's attempts to use a smaller window + * size (zlib doesn't have an interface to say "this or lower"!). + * + * inflateReset2 was added to zlib 1.2.4; before this the window could not be + * reset, therefore it is necessary to always allocate the maximum window + * size with earlier zlibs just in case later compressed chunks need it. + */ + { + int ret; /* zlib return code */ +#if ZLIB_VERNUM >= 0x1240 + int window_bits = 0; + +# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) + if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == + PNG_OPTION_ON) + { + window_bits = 15; + png_ptr->zstream_start = 0; /* fixed window size */ + } + + else + { + png_ptr->zstream_start = 1; + } +# endif + +#endif /* ZLIB_VERNUM >= 0x1240 */ + + /* Set this for safety, just in case the previous owner left pointers to + * memory allocations. + */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->zstream.avail_out = 0; + + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) + { +#if ZLIB_VERNUM >= 0x1240 + ret = inflateReset2(&png_ptr->zstream, window_bits); +#else + ret = inflateReset(&png_ptr->zstream); +#endif + } + + else + { +#if ZLIB_VERNUM >= 0x1240 + ret = inflateInit2(&png_ptr->zstream, window_bits); +#else + ret = inflateInit(&png_ptr->zstream); +#endif + + if (ret == Z_OK) + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; + } + +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED + if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) + /* Turn off validation of the ADLER32 checksum in IDAT chunks */ + ret = inflateValidate(&png_ptr->zstream, 0); +#endif + + if (ret == Z_OK) + png_ptr->zowner = owner; + + else + png_zstream_error(png_ptr, ret); + + return ret; + } + +#ifdef window_bits +# undef window_bits +#endif +} + +#if ZLIB_VERNUM >= 0x1240 +/* Handle the start of the inflate stream if we called inflateInit2(strm,0); + * in this case some zlib versions skip validation of the CINFO field and, in + * certain circumstances, libpng may end up displaying an invalid image, in + * contrast to implementations that call zlib in the normal way (e.g. libpng + * 1.5). + */ +int /* PRIVATE */ +png_zlib_inflate(png_structrp png_ptr, int flush) +{ + if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0) + { + if ((*png_ptr->zstream.next_in >> 4) > 7) + { + png_ptr->zstream.msg = "invalid window size (libpng)"; + return Z_DATA_ERROR; + } + + png_ptr->zstream_start = 0; + } + + return inflate(&png_ptr->zstream, flush); +} +#endif /* Zlib >= 1.2.4 */ + +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED +#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED) +/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to + * allow the caller to do multiple calls if required. If the 'finish' flag is + * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must + * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and + * Z_OK or Z_STREAM_END will be returned on success. + * + * The input and output sizes are updated to the actual amounts of data consumed + * or written, not the amount available (as in a z_stream). The data pointers + * are not changed, so the next input is (data+input_size) and the next + * available output is (output+output_size). + */ +static int +png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, + /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, + /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) +{ + if (png_ptr->zowner == owner) /* Else not claimed */ + { + int ret; + png_alloc_size_t avail_out = *output_size_ptr; + png_uint_32 avail_in = *input_size_ptr; + + /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it + * can't even necessarily handle 65536 bytes) because the type uInt is + * "16 bits or more". Consequently it is necessary to chunk the input to + * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the + * maximum value that can be stored in a uInt.) It is possible to set + * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have + * a performance advantage, because it reduces the amount of data accessed + * at each step and that may give the OS more time to page it in. + */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); + /* avail_in and avail_out are set below from 'size' */ + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.avail_out = 0; + + /* Read directly into the output if it is available (this is set to + * a local buffer below if output is NULL). + */ + if (output != NULL) + png_ptr->zstream.next_out = output; + + do + { + uInt avail; + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; + + /* zlib INPUT BUFFER */ + /* The setting of 'avail_in' used to be outside the loop; by setting it + * inside it is possible to chunk the input to zlib and simply rely on + * zlib to advance the 'next_in' pointer. This allows arbitrary + * amounts of data to be passed through zlib at the unavoidable cost of + * requiring a window save (memcpy of up to 32768 output bytes) + * every ZLIB_IO_MAX input bytes. + */ + avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ + + avail = ZLIB_IO_MAX; + + if (avail_in < avail) + avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ + + avail_in -= avail; + png_ptr->zstream.avail_in = avail; + + /* zlib OUTPUT BUFFER */ + avail_out += png_ptr->zstream.avail_out; /* not written last time */ + + avail = ZLIB_IO_MAX; /* maximum zlib can process */ + + if (output == NULL) + { + /* Reset the output buffer each time round if output is NULL and + * make available the full buffer, up to 'remaining_space' + */ + png_ptr->zstream.next_out = local_buffer; + if ((sizeof local_buffer) < avail) + avail = (sizeof local_buffer); + } + + if (avail_out < avail) + avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ + + png_ptr->zstream.avail_out = avail; + avail_out -= avail; + + /* zlib inflate call */ + /* In fact 'avail_out' may be 0 at this point, that happens at the end + * of the read when the final LZ end code was not passed at the end of + * the previous chunk of input data. Tell zlib if we have reached the + * end of the output buffer. + */ + ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH : + (finish ? Z_FINISH : Z_SYNC_FLUSH)); + } while (ret == Z_OK); + + /* For safety kill the local buffer pointer now */ + if (output == NULL) + png_ptr->zstream.next_out = NULL; + + /* Claw back the 'size' and 'remaining_space' byte counts. */ + avail_in += png_ptr->zstream.avail_in; + avail_out += png_ptr->zstream.avail_out; + + /* Update the input and output sizes; the updated values are the amount + * consumed or written, effectively the inverse of what zlib uses. + */ + if (avail_out > 0) + *output_size_ptr -= avail_out; + + if (avail_in > 0) + *input_size_ptr -= avail_in; + + /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ + png_zstream_error(png_ptr, ret); + return ret; + } + + else + { + /* This is a bad internal error. The recovery assigns to the zstream msg + * pointer, which is not owned by the caller, but this is safe; it's only + * used on errors! + */ + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); + return Z_STREAM_ERROR; + } +} + +/* + * Decompress trailing data in a chunk. The assumption is that read_buffer + * points at an allocated area holding the contents of a chunk with a + * trailing compressed part. What we get back is an allocated area + * holding the original prefix part and an uncompressed version of the + * trailing part (the malloc area passed in is freed). + */ +static int +png_decompress_chunk(png_structrp png_ptr, + png_uint_32 chunklength, png_uint_32 prefix_size, + png_alloc_size_t *newlength /* must be initialized to the maximum! */, + int terminate /*add a '\0' to the end of the uncompressed data*/) +{ + /* TODO: implement different limits for different types of chunk. + * + * The caller supplies *newlength set to the maximum length of the + * uncompressed data, but this routine allocates space for the prefix and + * maybe a '\0' terminator too. We have to assume that 'prefix_size' is + * limited only by the maximum chunk size. + */ + png_alloc_size_t limit = png_chunk_max(png_ptr); + + if (limit >= prefix_size + (terminate != 0)) + { + int ret; + + limit -= prefix_size + (terminate != 0); + + if (limit < *newlength) + *newlength = limit; + + /* Now try to claim the stream. */ + ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); + + if (ret == Z_OK) + { + png_uint_32 lzsize = chunklength - prefix_size; + + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, + /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, + /* output: */ NULL, newlength); + + if (ret == Z_STREAM_END) + { + /* Use 'inflateReset' here, not 'inflateReset2' because this + * preserves the previously decided window size (otherwise it would + * be necessary to store the previous window size.) In practice + * this doesn't matter anyway, because png_inflate will call inflate + * with Z_FINISH in almost all cases, so the window will not be + * maintained. + */ + if (inflateReset(&png_ptr->zstream) == Z_OK) + { + /* Because of the limit checks above we know that the new, + * expanded, size will fit in a size_t (let alone an + * png_alloc_size_t). Use png_malloc_base here to avoid an + * extra OOM message. + */ + png_alloc_size_t new_size = *newlength; + png_alloc_size_t buffer_size = prefix_size + new_size + + (terminate != 0); + png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, + buffer_size)); + + if (text != NULL) + { + memset(text, 0, buffer_size); + + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, + png_ptr->read_buffer + prefix_size, &lzsize, + text + prefix_size, newlength); + + if (ret == Z_STREAM_END) + { + if (new_size == *newlength) + { + if (terminate != 0) + text[prefix_size + *newlength] = 0; + + if (prefix_size > 0) + memcpy(text, png_ptr->read_buffer, prefix_size); + + { + png_bytep old_ptr = png_ptr->read_buffer; + + png_ptr->read_buffer = text; + png_ptr->read_buffer_size = buffer_size; + text = old_ptr; /* freed below */ + } + } + + else + { + /* The size changed on the second read, there can be no + * guarantee that anything is correct at this point. + * The 'msg' pointer has been set to "unexpected end of + * LZ stream", which is fine, but return an error code + * that the caller won't accept. + */ + ret = PNG_UNEXPECTED_ZLIB_RETURN; + } + } + + else if (ret == Z_OK) + ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ + + /* Free the text pointer (this is the old read_buffer on + * success) + */ + png_free(png_ptr, text); + + /* This really is very benign, but it's still an error because + * the extra space may otherwise be used as a Trojan Horse. + */ + if (ret == Z_STREAM_END && + chunklength - prefix_size != lzsize) + png_chunk_benign_error(png_ptr, "extra compressed data"); + } + + else + { + /* Out of memory allocating the buffer */ + ret = Z_MEM_ERROR; + png_zstream_error(png_ptr, Z_MEM_ERROR); + } + } + + else + { + /* inflateReset failed, store the error message */ + png_zstream_error(png_ptr, ret); + ret = PNG_UNEXPECTED_ZLIB_RETURN; + } + } + + else if (ret == Z_OK) + ret = PNG_UNEXPECTED_ZLIB_RETURN; + + /* Release the claimed stream */ + png_ptr->zowner = 0; + } + + else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ + ret = PNG_UNEXPECTED_ZLIB_RETURN; + + return ret; + } + + else + { + /* Application/configuration limits exceeded */ + png_zstream_error(png_ptr, Z_MEM_ERROR); + return Z_MEM_ERROR; + } +} +#endif /* READ_zTXt || READ_iTXt */ +#endif /* READ_COMPRESSED_TEXT */ + +#ifdef PNG_READ_iCCP_SUPPORTED +/* Perform a partial read and decompress, producing 'avail_out' bytes and + * reading from the current chunk as required. + */ +static int +png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, + png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, + int finish) +{ + if (png_ptr->zowner == png_ptr->chunk_name) + { + int ret; + + /* next_in and avail_in must have been initialized by the caller. */ + png_ptr->zstream.next_out = next_out; + png_ptr->zstream.avail_out = 0; /* set in the loop */ + + do + { + if (png_ptr->zstream.avail_in == 0) + { + if (read_size > *chunk_bytes) + read_size = (uInt)*chunk_bytes; + *chunk_bytes -= read_size; + + if (read_size > 0) + png_crc_read(png_ptr, read_buffer, read_size); + + png_ptr->zstream.next_in = read_buffer; + png_ptr->zstream.avail_in = read_size; + } + + if (png_ptr->zstream.avail_out == 0) + { + uInt avail = ZLIB_IO_MAX; + if (avail > *out_size) + avail = (uInt)*out_size; + *out_size -= avail; + + png_ptr->zstream.avail_out = avail; + } + + /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all + * the available output is produced; this allows reading of truncated + * streams. + */ + ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ? + Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); + } + while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); + + *out_size += png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ + + /* Ensure the error message pointer is always set: */ + png_zstream_error(png_ptr, ret); + return ret; + } + + else + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); + return Z_STREAM_ERROR; + } +} +#endif /* READ_iCCP */ + +/* CHUNK HANDLING */ +/* Read and check the IDHR chunk */ +static png_handle_result_code +png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[13]; + png_uint_32 width, height; + int bit_depth, color_type, compression_type, filter_type; + int interlace_type; + + png_debug(1, "in png_handle_IHDR"); + + /* Length and position are checked by the caller. */ + + png_ptr->mode |= PNG_HAVE_IHDR; + + png_crc_read(png_ptr, buf, 13); + png_crc_finish(png_ptr, 0); + + width = png_get_uint_31(png_ptr, buf); + height = png_get_uint_31(png_ptr, buf + 4); + bit_depth = buf[8]; + color_type = buf[9]; + compression_type = buf[10]; + filter_type = buf[11]; + interlace_type = buf[12]; + + /* Set internal variables */ + png_ptr->width = width; + png_ptr->height = height; + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->interlaced = (png_byte)interlace_type; + png_ptr->color_type = (png_byte)color_type; +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + + /* Find number of channels */ + switch (png_ptr->color_type) + { + default: /* invalid, png_set_IHDR calls png_error */ + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_PALETTE: + png_ptr->channels = 1; + break; + + case PNG_COLOR_TYPE_RGB: + png_ptr->channels = 3; + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_ptr->channels = 2; + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: + png_ptr->channels = 4; + break; + } + + /* Set up other useful info */ + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); + png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); + png_debug1(3, "channels = %d", png_ptr->channels); + png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); + + /* Rely on png_set_IHDR to completely validate the data and call png_error if + * it's wrong. + */ + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, + color_type, interlace_type, compression_type, filter_type); + + return handled_ok; + PNG_UNUSED(length) +} + +/* Read and check the palette */ +/* TODO: there are several obvious errors in this code when handling + * out-of-place chunks and there is much over-complexity caused by trying to + * patch up the problems. + */ +static png_handle_result_code +png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_const_charp errmsg = NULL; + + png_debug(1, "in png_handle_PLTE"); + + /* 1.6.47: consistency. This used to be especially treated as a critical + * error even in an image which is not colour mapped, there isn't a good + * justification for treating some errors here one way and others another so + * everything uses the same logic. + */ + if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) + errmsg = "duplicate"; + + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + errmsg = "out of place"; + + else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + errmsg = "ignored in grayscale PNG"; + + else if (length > 3*PNG_MAX_PALETTE_LENGTH || (length % 3) != 0) + errmsg = "invalid"; + + /* This drops PLTE in favour of tRNS or bKGD because both of those chunks + * can have an effect on the rendering of the image whereas PLTE only matters + * in the case of an 8-bit display with a decoder which controls the palette. + * + * The alternative here is to ignore the error and store the palette anyway; + * destroying the tRNS will definitely cause problems. + * + * NOTE: the case of PNG_COLOR_TYPE_PALETTE need not be considered because + * the png_handle_ routines for the three 'after PLTE' chunks tRNS, bKGD and + * hIST all check for a preceding PLTE in these cases. + */ + else if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE && + (png_has_chunk(png_ptr, tRNS) || png_has_chunk(png_ptr, bKGD))) + errmsg = "out of place"; + + else + { + /* If the palette has 256 or fewer entries but is too large for the bit + * depth we don't issue an error to preserve the behavior of previous + * libpng versions. We silently truncate the unused extra palette entries + * here. + */ + const unsigned max_palette_length = + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + 1U << png_ptr->bit_depth : PNG_MAX_PALETTE_LENGTH; + + /* The cast is safe because 'length' is less than + * 3*PNG_MAX_PALETTE_LENGTH + */ + const unsigned num = (length > 3U*max_palette_length) ? + max_palette_length : (unsigned)length / 3U; + + unsigned i, j; + png_byte buf[3*PNG_MAX_PALETTE_LENGTH]; + png_color palette[PNG_MAX_PALETTE_LENGTH]; + + /* Read the chunk into the buffer then read to the end of the chunk. */ + png_crc_read(png_ptr, buf, num*3U); + png_crc_finish_critical(png_ptr, length - 3U*num, + /* Handle as ancillary if PLTE is optional: */ + png_ptr->color_type != PNG_COLOR_TYPE_PALETTE); + + for (i = 0U, j = 0U; i < num; i++) + { + palette[i].red = buf[j++]; + palette[i].green = buf[j++]; + palette[i].blue = buf[j++]; + } + + /* A valid PLTE chunk has been read */ + png_ptr->mode |= PNG_HAVE_PLTE; + + png_set_PLTE(png_ptr, info_ptr, palette, num); + return handled_ok; + } + + /* Here on error: errmsg is non NULL. */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_crc_finish(png_ptr, length); + png_chunk_error(png_ptr, errmsg); + } + + else /* not critical to this image */ + { + png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/); + png_chunk_benign_error(png_ptr, errmsg); + } + + /* Because PNG_UNUSED(errmsg) does not work if all the uses are compiled out + * (this does happen). + */ + return errmsg != NULL ? handled_error : handled_error; +} + +/* On read the IDAT chunk is always handled specially, even if marked for + * unknown handling (this is allowed), so: + */ +#define png_handle_IDAT NULL + +static png_handle_result_code +png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_debug(1, "in png_handle_IEND"); + + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); + + if (length != 0) + png_chunk_benign_error(png_ptr, "invalid"); + + png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/); + + return handled_ok; + PNG_UNUSED(info_ptr) +} + +#ifdef PNG_READ_gAMA_SUPPORTED +static png_handle_result_code +png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_uint_32 ugamma; + png_byte buf[4]; + + png_debug(1, "in png_handle_gAMA"); + + png_crc_read(png_ptr, buf, 4); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + ugamma = png_get_uint_32(buf); + + if (ugamma > PNG_UINT_31_MAX) + { + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_set_gAMA_fixed(png_ptr, info_ptr, (png_fixed_point)/*SAFE*/ugamma); + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. gAMA is + * at the end of the chain so simply check for an unset value. + */ + if (png_ptr->chunk_gamma == 0) + png_ptr->chunk_gamma = (png_fixed_point)/*SAFE*/ugamma; +#endif /*READ_GAMMA*/ + + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_gAMA NULL +#endif + +#ifdef PNG_READ_sBIT_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + unsigned int truelen, i; + png_byte sample_depth; + png_byte buf[4]; + + png_debug(1, "in png_handle_sBIT"); + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + truelen = 3; + sample_depth = 8; + } + + else + { + truelen = png_ptr->channels; + sample_depth = png_ptr->bit_depth; + } + + if (length != truelen) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "bad length"); + return handled_error; + } + + buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; + png_crc_read(png_ptr, buf, truelen); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + for (i=0; i sample_depth) + { + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + } + + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[1]; + png_ptr->sig_bit.blue = buf[2]; + png_ptr->sig_bit.alpha = buf[3]; + } + + else /* grayscale */ + { + png_ptr->sig_bit.gray = buf[0]; + png_ptr->sig_bit.red = buf[0]; + png_ptr->sig_bit.green = buf[0]; + png_ptr->sig_bit.blue = buf[0]; + png_ptr->sig_bit.alpha = buf[1]; + } + + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); + return handled_ok; +} +#else +# define png_handle_sBIT NULL +#endif + +#ifdef PNG_READ_cHRM_SUPPORTED +static png_int_32 +png_get_int_32_checked(png_const_bytep buf, int *error) +{ + png_uint_32 uval = png_get_uint_32(buf); + if ((uval & 0x80000000) == 0) /* non-negative */ + return (png_int_32)uval; + + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ + if ((uval & 0x80000000) == 0) /* no overflow */ + return -(png_int_32)uval; + + /* This version of png_get_int_32 has a way of returning the error to the + * caller, so: + */ + *error = 1; + return 0; /* Safe */ +} + +static png_handle_result_code /* PRIVATE */ +png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + int error = 0; + png_xy xy; + png_byte buf[32]; + + png_debug(1, "in png_handle_cHRM"); + + png_crc_read(png_ptr, buf, 32); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + xy.whitex = png_get_int_32_checked(buf + 0, &error); + xy.whitey = png_get_int_32_checked(buf + 4, &error); + xy.redx = png_get_int_32_checked(buf + 8, &error); + xy.redy = png_get_int_32_checked(buf + 12, &error); + xy.greenx = png_get_int_32_checked(buf + 16, &error); + xy.greeny = png_get_int_32_checked(buf + 20, &error); + xy.bluex = png_get_int_32_checked(buf + 24, &error); + xy.bluey = png_get_int_32_checked(buf + 28, &error); + + if (error) + { + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + /* png_set_cHRM may complain about some of the values but this doesn't matter + * because it was a cHRM and it did have vaguely (if, perhaps, ridiculous) + * values. Ridiculosity will be checked if the values are used later. + */ + png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy, + xy.greenx, xy.greeny, xy.bluex, xy.bluey); + + /* We only use 'chromaticities' for RGB to gray */ +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* There is no need to check sRGB here, cICP is NYI and iCCP is not + * supported so just check mDCV. + */ + if (!png_has_chunk(png_ptr, mDCV)) + { + png_ptr->chromaticities = xy; + } +# endif /* READ_RGB_TO_GRAY */ + + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_cHRM NULL +#endif + +#ifdef PNG_READ_sRGB_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte intent; + + png_debug(1, "in png_handle_sRGB"); + + png_crc_read(png_ptr, &intent, 1); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* This checks the range of the "rendering intent" because it is specified in + * the PNG spec itself; the "reserved" values will result in the chunk not + * being accepted, just as they do with the various "reserved" values in + * IHDR. + */ + if (intent > 3/*PNGv3 spec*/) + { + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_set_sRGB(png_ptr, info_ptr, intent); + /* NOTE: png_struct::chromaticities is not set here because the RGB to gray + * coefficients are known without a need for the chromaticities. + */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. iCCP is + * not supported by libpng so the only requirement is to check for cICP + * setting the gamma (this is NYI, but this check is safe.) + */ + if (!png_has_chunk(png_ptr, cICP) || png_ptr->chunk_gamma == 0) + png_ptr->chunk_gamma = PNG_GAMMA_sRGB_INVERSE; +#endif /*READ_GAMMA*/ + + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_sRGB NULL +#endif /* READ_sRGB */ + +#ifdef PNG_READ_iCCP_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +/* Note: this does not properly handle profiles that are > 64K under DOS */ +{ + png_const_charp errmsg = NULL; /* error message output, or no error */ + int finished = 0; /* crc checked */ + + png_debug(1, "in png_handle_iCCP"); + + /* PNGv3: allow PNG files with both sRGB and iCCP because the PNG spec only + * ever said that there "should" be only one, not "shall" and the PNGv3 + * colour chunk precedence rules give a handling for this case anyway. + */ + { + uInt read_length, keyword_length; + char keyword[81]; + + /* Find the keyword; the keyword plus separator and compression method + * bytes can be at most 81 characters long. + */ + read_length = 81; /* maximum */ + if (read_length > length) + read_length = (uInt)/*SAFE*/length; + + png_crc_read(png_ptr, (png_bytep)keyword, read_length); + length -= read_length; + + if (length < LZ77Min) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "too short"); + return handled_error; + } + + keyword_length = 0; + while (keyword_length < 80 && keyword_length < read_length && + keyword[keyword_length] != 0) + ++keyword_length; + + /* TODO: make the keyword checking common */ + if (keyword_length >= 1 && keyword_length <= 79) + { + /* We only understand '0' compression - deflate - so if we get a + * different value we can't safely decode the chunk. + */ + if (keyword_length+1 < read_length && + keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) + { + read_length -= keyword_length+2; + + if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) + { + Byte profile_header[132]={0}; + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; + png_alloc_size_t size = (sizeof profile_header); + + png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); + png_ptr->zstream.avail_in = read_length; + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, profile_header, &size, + 0/*finish: don't, because the output is too small*/); + + if (size == 0) + { + /* We have the ICC profile header; do the basic header checks. + */ + png_uint_32 profile_length = png_get_uint_32(profile_header); + + if (png_icc_check_length(png_ptr, keyword, profile_length) != + 0) + { + /* The length is apparently ok, so we can check the 132 + * byte header. + */ + if (png_icc_check_header(png_ptr, keyword, profile_length, + profile_header, png_ptr->color_type) != 0) + { + /* Now read the tag table; a variable size buffer is + * needed at this point, allocate one for the whole + * profile. The header check has already validated + * that none of this stuff will overflow. + */ + png_uint_32 tag_count = + png_get_uint_32(profile_header + 128); + png_bytep profile = png_read_buffer(png_ptr, + profile_length); + + if (profile != NULL) + { + memcpy(profile, profile_header, + (sizeof profile_header)); + + size = 12 * tag_count; + + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, + profile + (sizeof profile_header), &size, 0); + + /* Still expect a buffer error because we expect + * there to be some tag data! + */ + if (size == 0) + { + if (png_icc_check_tag_table(png_ptr, + keyword, profile_length, profile) != 0) + { + /* The profile has been validated for basic + * security issues, so read the whole thing in. + */ + size = profile_length - (sizeof profile_header) + - 12 * tag_count; + + (void)png_inflate_read(png_ptr, local_buffer, + (sizeof local_buffer), &length, + profile + (sizeof profile_header) + + 12 * tag_count, &size, 1/*finish*/); + + if (length > 0 && !(png_ptr->flags & + PNG_FLAG_BENIGN_ERRORS_WARN)) + errmsg = "extra compressed data"; + + /* But otherwise allow extra data: */ + else if (size == 0) + { + if (length > 0) + { + /* This can be handled completely, so + * keep going. + */ + png_chunk_warning(png_ptr, + "extra compressed data"); + } + + png_crc_finish(png_ptr, length); + finished = 1; + + /* Steal the profile for info_ptr. */ + if (info_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, + PNG_FREE_ICCP, 0); + + info_ptr->iccp_name = png_voidcast(char*, + png_malloc_base(png_ptr, + keyword_length+1)); + if (info_ptr->iccp_name != NULL) + { + memcpy(info_ptr->iccp_name, keyword, + keyword_length+1); + info_ptr->iccp_proflen = + profile_length; + info_ptr->iccp_profile = profile; + png_ptr->read_buffer = NULL; /*steal*/ + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; + } + + else + errmsg = "out of memory"; + } + + /* else the profile remains in the read + * buffer which gets reused for subsequent + * chunks. + */ + + if (errmsg == NULL) + { + png_ptr->zowner = 0; + return handled_ok; + } + } + if (errmsg == NULL) + errmsg = png_ptr->zstream.msg; + } + /* else png_icc_check_tag_table output an error */ + } + else /* profile truncated */ + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "out of memory"; + } + + /* else png_icc_check_header output an error */ + } + + /* else png_icc_check_length output an error */ + } + + else /* profile truncated */ + errmsg = png_ptr->zstream.msg; + + /* Release the stream */ + png_ptr->zowner = 0; + } + + else /* png_inflate_claim failed */ + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "bad compression method"; /* or missing */ + } + + else + errmsg = "bad keyword"; + } + + /* Failure: the reason is in 'errmsg' */ + if (finished == 0) + png_crc_finish(png_ptr, length); + + if (errmsg != NULL) /* else already output */ + png_chunk_benign_error(png_ptr, errmsg); + + return handled_error; +} +#else +# define png_handle_iCCP NULL +#endif /* READ_iCCP */ + +#ifdef PNG_READ_sPLT_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_bytep buffer; + png_bytep entry_start; + png_sPLT_t new_palette; + png_sPLT_entryp pp; + png_uint_32 data_length; + int entry_size, i; + png_uint_32 skip = 0; + png_uint_32 dl; + size_t max_dl; + + png_debug(1, "in png_handle_sPLT"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return handled_error; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for sPLT"); + png_crc_finish(png_ptr, length); + return handled_error; + } + } +#endif + + buffer = png_read_buffer(png_ptr, length+1); + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + + /* WARNING: this may break if size_t is less than 32 bits; it is assumed + * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a + * potential breakage point if the types in pngconf.h aren't exactly right. + */ + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, skip) != 0) + return handled_error; + + buffer[length] = 0; + + for (entry_start = buffer; *entry_start; entry_start++) + /* Empty loop to find end of name */ ; + + ++entry_start; + + /* A sample depth should follow the separator, and we should be on it */ + if (length < 2U || entry_start > buffer + (length - 2U)) + { + png_warning(png_ptr, "malformed sPLT chunk"); + return handled_error; + } + + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + /* This must fit in a png_uint_32 because it is derived from the original + * chunk data length. + */ + data_length = length - (png_uint_32)(entry_start - buffer); + + /* Integrity-check the data length */ + if ((data_length % (unsigned int)entry_size) != 0) + { + png_warning(png_ptr, "sPLT chunk has bad length"); + return handled_error; + } + + dl = (png_uint_32)(data_length / (unsigned int)entry_size); + max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); + + if (dl > max_dl) + { + png_warning(png_ptr, "sPLT chunk too long"); + return handled_error; + } + + new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size); + + new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, + (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry))); + + if (new_palette.entries == NULL) + { + png_warning(png_ptr, "sPLT chunk requires too much memory"); + return handled_error; + } + + for (i = 0; i < new_palette.nentries; i++) + { + pp = new_palette.entries + i; + + if (new_palette.depth == 8) + { + pp->red = *entry_start++; + pp->green = *entry_start++; + pp->blue = *entry_start++; + pp->alpha = *entry_start++; + } + + else + { + pp->red = png_get_uint_16(entry_start); entry_start += 2; + pp->green = png_get_uint_16(entry_start); entry_start += 2; + pp->blue = png_get_uint_16(entry_start); entry_start += 2; + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; + } + + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } + + /* Discard all chunk data except the name and stash that */ + new_palette.name = (png_charp)buffer; + + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, new_palette.entries); + return handled_ok; +} +#else +# define png_handle_sPLT NULL +#endif /* READ_sPLT */ + +#ifdef PNG_READ_tRNS_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_tRNS"); + + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + png_byte buf[2]; + + if (length != 2) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_crc_read(png_ptr, buf, 2); + png_ptr->num_trans = 1; + png_ptr->trans_color.gray = png_get_uint_16(buf); + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + png_byte buf[6]; + + if (length != 6) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_crc_read(png_ptr, buf, length); + png_ptr->num_trans = 1; + png_ptr->trans_color.red = png_get_uint_16(buf); + png_ptr->trans_color.green = png_get_uint_16(buf + 2); + png_ptr->trans_color.blue = png_get_uint_16(buf + 4); + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return handled_error; + } + + if (length > (unsigned int) png_ptr->num_palette || + length > (unsigned int) PNG_MAX_PALETTE_LENGTH || + length == 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_crc_read(png_ptr, readbuf, length); + png_ptr->num_trans = (png_uint_16)length; + } + + else + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid with alpha channel"); + return handled_error; + } + + if (png_crc_finish(png_ptr, 0) != 0) + { + png_ptr->num_trans = 0; + return handled_error; + } + + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, + &(png_ptr->trans_color)); + return handled_ok; +} +#else +# define png_handle_tRNS NULL +#endif + +#ifdef PNG_READ_bKGD_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + unsigned int truelen; + png_byte buf[6]; + png_color_16 background; + + png_debug(1, "in png_handle_bKGD"); + + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of place"); + return handled_error; + } + + truelen = 1; + } + + else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + truelen = 6; + + else + truelen = 2; + + if (length != truelen) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_crc_read(png_ptr, buf, truelen); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* We convert the index value into RGB components so that we can allow + * arbitrary RGB values for background when we have transparency, and + * so it is easy to determine the RGB values of the background color + * from the info_ptr struct. + */ + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + background.index = buf[0]; + + if (info_ptr != NULL && info_ptr->num_palette != 0) + { + if (buf[0] >= info_ptr->num_palette) + { + png_chunk_benign_error(png_ptr, "invalid index"); + return handled_error; + } + + background.red = (png_uint_16)png_ptr->palette[buf[0]].red; + background.green = (png_uint_16)png_ptr->palette[buf[0]].green; + background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; + } + + else + background.red = background.green = background.blue = 0; + + background.gray = 0; + } + + else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ + { + if (png_ptr->bit_depth <= 8) + { + if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth)) + { + png_chunk_benign_error(png_ptr, "invalid gray level"); + return handled_error; + } + } + + background.index = 0; + background.red = + background.green = + background.blue = + background.gray = png_get_uint_16(buf); + } + + else + { + if (png_ptr->bit_depth <= 8) + { + if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0) + { + png_chunk_benign_error(png_ptr, "invalid color"); + return handled_error; + } + } + + background.index = 0; + background.red = png_get_uint_16(buf); + background.green = png_get_uint_16(buf + 2); + background.blue = png_get_uint_16(buf + 4); + background.gray = 0; + } + + png_set_bKGD(png_ptr, info_ptr, &background); + return handled_ok; +} +#else +# define png_handle_bKGD NULL +#endif + +#ifdef PNG_READ_cICP_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[4]; + + png_debug(1, "in png_handle_cICP"); + + png_crc_read(png_ptr, buf, 4); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + png_set_cICP(png_ptr, info_ptr, buf[0], buf[1], buf[2], buf[3]); + + /* We only use 'chromaticities' for RGB to gray */ +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if (!png_has_chunk(png_ptr, mDCV)) + { + /* TODO: png_ptr->chromaticities = chromaticities; */ + } +# endif /* READ_RGB_TO_GRAY */ + +#ifdef PNG_READ_GAMMA_SUPPORTED + /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. cICP is + * at the head so simply set the gamma if it can be determined. If not + * chunk_gamma remains unchanged; sRGB and gAMA handling check it for + * being zero. + */ + /* TODO: set png_struct::chunk_gamma when possible */ +#endif /*READ_GAMMA*/ + + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_cICP NULL +#endif + +#ifdef PNG_READ_cLLI_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_cLLI(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[8]; + + png_debug(1, "in png_handle_cLLI"); + + png_crc_read(png_ptr, buf, 8); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* The error checking happens here, this puts it in just one place: */ + png_set_cLLI_fixed(png_ptr, info_ptr, png_get_uint_32(buf), + png_get_uint_32(buf+4)); + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_cLLI NULL +#endif + +#ifdef PNG_READ_mDCV_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_mDCV(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_xy chromaticities; + png_byte buf[24]; + + png_debug(1, "in png_handle_mDCV"); + + png_crc_read(png_ptr, buf, 24); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* The error checking happens here, this puts it in just one place. The + * odd /50000 scaling factor makes it more difficult but the (x.y) values are + * only two bytes so a <<1 is safe. + * + * WARNING: the PNG specification defines the cHRM chunk to **start** with + * the white point (x,y). The W3C PNG v3 specification puts the white point + * **after* R,G,B. The x,y values in mDCV are also scaled by 50,000 and + * stored in just two bytes, whereas those in cHRM are scaled by 100,000 and + * stored in four bytes. This is very, very confusing. These APIs remove + * the confusion by copying the existing, well established, API. + */ + chromaticities.redx = png_get_uint_16(buf+ 0U) << 1; /* red x */ + chromaticities.redy = png_get_uint_16(buf+ 2U) << 1; /* red y */ + chromaticities.greenx = png_get_uint_16(buf+ 4U) << 1; /* green x */ + chromaticities.greeny = png_get_uint_16(buf+ 6U) << 1; /* green y */ + chromaticities.bluex = png_get_uint_16(buf+ 8U) << 1; /* blue x */ + chromaticities.bluey = png_get_uint_16(buf+10U) << 1; /* blue y */ + chromaticities.whitex = png_get_uint_16(buf+12U) << 1; /* white x */ + chromaticities.whitey = png_get_uint_16(buf+14U) << 1; /* white y */ + + png_set_mDCV_fixed(png_ptr, info_ptr, + chromaticities.whitex, chromaticities.whitey, + chromaticities.redx, chromaticities.redy, + chromaticities.greenx, chromaticities.greeny, + chromaticities.bluex, chromaticities.bluey, + png_get_uint_32(buf+16U), /* peak luminance */ + png_get_uint_32(buf+20U));/* minimum perceivable luminance */ + + /* We only use 'chromaticities' for RGB to gray */ +# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_ptr->chromaticities = chromaticities; +# endif /* READ_RGB_TO_GRAY */ + + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_mDCV NULL +#endif + +#ifdef PNG_READ_eXIf_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_bytep buffer = NULL; + + png_debug(1, "in png_handle_eXIf"); + + buffer = png_read_buffer(png_ptr, length); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* PNGv3: the code used to check the byte order mark at the start for MM or + * II, however PNGv3 states that the first 4 bytes should be checked. + * The caller ensures that there are four bytes available. + */ + { + png_uint_32 header = png_get_uint_32(buffer); + + /* These numbers are copied from the PNGv3 spec: */ + if (header != 0x49492A00 && header != 0x4D4D002A) + { + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + } + + png_set_eXIf_1(png_ptr, info_ptr, length, buffer); + return handled_ok; +} +#else +# define png_handle_eXIf NULL +#endif + +#ifdef PNG_READ_hIST_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + unsigned int num, i; + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; + + png_debug(1, "in png_handle_hIST"); + + /* This cast is safe because the chunk definition limits the length to a + * maximum of 1024 bytes. + * + * TODO: maybe use png_uint_32 anyway, not unsigned int, to reduce the + * casts. + */ + num = (unsigned int)length / 2 ; + + if (length != num * 2 || + num != (unsigned int)png_ptr->num_palette || + num > (unsigned int)PNG_MAX_PALETTE_LENGTH) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + for (i = 0; i < num; i++) + { + png_byte buf[2]; + + png_crc_read(png_ptr, buf, 2); + readbuf[i] = png_get_uint_16(buf); + } + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + png_set_hIST(png_ptr, info_ptr, readbuf); + return handled_ok; +} +#else +# define png_handle_hIST NULL +#endif + +#ifdef PNG_READ_pHYs_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_uint_32 res_x, res_y; + int unit_type; + + png_debug(1, "in png_handle_pHYs"); + + png_crc_read(png_ptr, buf, 9); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + res_x = png_get_uint_32(buf); + res_y = png_get_uint_32(buf + 4); + unit_type = buf[8]; + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_pHYs NULL +#endif + +#ifdef PNG_READ_oFFs_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[9]; + png_int_32 offset_x, offset_y; + int unit_type; + + png_debug(1, "in png_handle_oFFs"); + + png_crc_read(png_ptr, buf, 9); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + offset_x = png_get_int_32(buf); + offset_y = png_get_int_32(buf + 4); + unit_type = buf[8]; + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_oFFs NULL +#endif + +#ifdef PNG_READ_pCAL_SUPPORTED +/* Read the pCAL chunk (described in the PNG Extensions document) */ +static png_handle_result_code /* PRIVATE */ +png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_bytep buffer; + png_bytep buf; + png_bytep endptr; + png_int_32 X0, X1; + png_byte type; + png_byte nparams; + png_byte *units; + png_charpp params; + int i; + + png_debug(1, "in png_handle_pCAL"); + png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", + length + 1); + + buffer = png_read_buffer(png_ptr, length+1); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + buffer[length] = 0; /* Null terminate the last string */ + + png_debug(3, "Finding end of pCAL purpose string"); + for (buf = buffer; *buf; buf++) + /* Empty loop */ ; + + endptr = buffer + length; + + /* We need to have at least 12 bytes after the purpose string + * in order to get the parameter information. + */ + if (endptr - buf <= 12) + { + png_chunk_benign_error(png_ptr, "invalid"); + return handled_error; + } + + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); + X0 = png_get_int_32((png_bytep)buf+1); + X1 = png_get_int_32((png_bytep)buf+5); + type = buf[9]; + nparams = buf[10]; + units = buf + 11; + + png_debug(3, "Checking pCAL equation type and number of parameters"); + /* Check that we have the right number of parameters for known + * equation types. + */ + if ((type == PNG_EQUATION_LINEAR && nparams != 2) || + (type == PNG_EQUATION_BASE_E && nparams != 3) || + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) + { + png_chunk_benign_error(png_ptr, "invalid parameter count"); + return handled_error; + } + + else if (type >= PNG_EQUATION_LAST) + { + png_chunk_benign_error(png_ptr, "unrecognized equation type"); + } + + for (buf = units; *buf; buf++) + /* Empty loop to move past the units string. */ ; + + png_debug(3, "Allocating pCAL parameters array"); + + params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, + nparams * (sizeof (png_charp)))); + + if (params == NULL) + { + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + /* Get pointers to the start of each parameter string. */ + for (i = 0; i < nparams; i++) + { + buf++; /* Skip the null string terminator from previous parameter. */ + + png_debug1(3, "Reading pCAL parameter %d", i); + + for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) + /* Empty loop to move past each parameter string */ ; + + /* Make sure we haven't run out of data yet */ + if (buf > endptr) + { + png_free(png_ptr, params); + png_chunk_benign_error(png_ptr, "invalid data"); + return handled_error; + } + } + + png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, + (png_charp)units, params); + + /* TODO: BUG: png_set_pCAL calls png_chunk_report which, in this case, calls + * png_benign_error and that can error out. + * + * png_read_buffer needs to be allocated with space for both nparams and the + * parameter strings. Not hard to do. + */ + png_free(png_ptr, params); + return handled_ok; +} +#else +# define png_handle_pCAL NULL +#endif + +#ifdef PNG_READ_sCAL_SUPPORTED +/* Read the sCAL chunk */ +static png_handle_result_code /* PRIVATE */ +png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_bytep buffer; + size_t i; + int state; + + png_debug(1, "in png_handle_sCAL"); + png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", + length + 1); + + buffer = png_read_buffer(png_ptr, length+1); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + png_crc_read(png_ptr, buffer, length); + buffer[length] = 0; /* Null terminate the last string */ + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* Validate the unit. */ + if (buffer[0] != 1 && buffer[0] != 2) + { + png_chunk_benign_error(png_ptr, "invalid unit"); + return handled_error; + } + + /* Validate the ASCII numbers, need two ASCII numbers separated by + * a '\0' and they need to fit exactly in the chunk data. + */ + i = 1; + state = 0; + + if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || + i >= length || buffer[i++] != 0) + png_chunk_benign_error(png_ptr, "bad width format"); + + else if (PNG_FP_IS_POSITIVE(state) == 0) + png_chunk_benign_error(png_ptr, "non-positive width"); + + else + { + size_t heighti = i; + + state = 0; + if (png_check_fp_number((png_const_charp)buffer, length, + &state, &i) == 0 || i != length) + png_chunk_benign_error(png_ptr, "bad height format"); + + else if (PNG_FP_IS_POSITIVE(state) == 0) + png_chunk_benign_error(png_ptr, "non-positive height"); + + else + { + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, buffer[0], + (png_charp)buffer+1, (png_charp)buffer+heighti); + return handled_ok; + } + } + + return handled_error; +} +#else +# define png_handle_sCAL NULL +#endif + +#ifdef PNG_READ_tIME_SUPPORTED +static png_handle_result_code /* PRIVATE */ +png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_byte buf[7]; + png_time mod_time; + + png_debug(1, "in png_handle_tIME"); + + /* TODO: what is this doing here? It should be happened in pngread.c and + * pngpread.c, although it could be moved to png_handle_chunk below and + * thereby avoid some code duplication. + */ + if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + png_ptr->mode |= PNG_AFTER_IDAT; + + png_crc_read(png_ptr, buf, 7); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + mod_time.second = buf[6]; + mod_time.minute = buf[5]; + mod_time.hour = buf[4]; + mod_time.day = buf[3]; + mod_time.month = buf[2]; + mod_time.year = png_get_uint_16(buf); + + png_set_tIME(png_ptr, info_ptr, &mod_time); + return handled_ok; + PNG_UNUSED(length) +} +#else +# define png_handle_tIME NULL +#endif + +#ifdef PNG_READ_tEXt_SUPPORTED +/* Note: this does not properly handle chunks that are > 64K under DOS */ +static png_handle_result_code /* PRIVATE */ +png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_text text_info; + png_bytep buffer; + png_charp key; + png_charp text; + png_uint_32 skip = 0; + + png_debug(1, "in png_handle_tEXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return handled_error; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "no space in chunk cache"); + return handled_error; + } + } +#endif + + buffer = png_read_buffer(png_ptr, length+1); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, skip) != 0) + return handled_error; + + key = (png_charp)buffer; + key[length] = 0; + + for (text = key; *text; text++) + /* Empty loop to find end of key */ ; + + if (text != key + length) + text++; + + text_info.compression = PNG_TEXT_COMPRESSION_NONE; + text_info.key = key; + text_info.lang = NULL; + text_info.lang_key = NULL; + text_info.itxt_length = 0; + text_info.text = text; + text_info.text_length = strlen(text); + + if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) == 0) + return handled_ok; + + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; +} +#else +# define png_handle_tEXt NULL +#endif + +#ifdef PNG_READ_zTXt_SUPPORTED +/* Note: this does not correctly handle chunks that are > 64K under DOS */ +static png_handle_result_code /* PRIVATE */ +png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_const_charp errmsg = NULL; + png_bytep buffer; + png_uint_32 keyword_length; + + png_debug(1, "in png_handle_zTXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return handled_error; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "no space in chunk cache"); + return handled_error; + } + } +#endif + + /* Note, "length" is sufficient here; we won't be adding + * a null terminator later. The limit check in png_handle_chunk should be + * sufficient. + */ + buffer = png_read_buffer(png_ptr, length); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* TODO: also check that the keyword contents match the spec! */ + for (keyword_length = 0; + keyword_length < length && buffer[keyword_length] != 0; + ++keyword_length) + /* Empty loop to find end of name */ ; + + if (keyword_length > 79 || keyword_length < 1) + errmsg = "bad keyword"; + + /* zTXt must have some LZ data after the keyword, although it may expand to + * zero bytes; we need a '\0' at the end of the keyword, the compression type + * then the LZ data: + */ + else if (keyword_length + 3 > length) + errmsg = "truncated"; + + else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) + errmsg = "unknown compression type"; + + else + { + png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; + + /* TODO: at present png_decompress_chunk imposes a single application + * level memory limit, this should be split to different values for iCCP + * and text chunks. + */ + if (png_decompress_chunk(png_ptr, length, keyword_length+2, + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + { + png_text text; + + if (png_ptr->read_buffer == NULL) + errmsg="Read failure in png_handle_zTXt"; + else + { + /* It worked; png_ptr->read_buffer now looks like a tEXt chunk + * except for the extra compression type byte and the fact that + * it isn't necessarily '\0' terminated. + */ + buffer = png_ptr->read_buffer; + buffer[uncompressed_length+(keyword_length+2)] = 0; + + text.compression = PNG_TEXT_COMPRESSION_zTXt; + text.key = (png_charp)buffer; + text.text = (png_charp)(buffer + keyword_length+2); + text.text_length = uncompressed_length; + text.itxt_length = 0; + text.lang = NULL; + text.lang_key = NULL; + + if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0) + return handled_ok; + + errmsg = "out of memory"; + } + } + + else + errmsg = png_ptr->zstream.msg; + } + + png_chunk_benign_error(png_ptr, errmsg); + return handled_error; +} +#else +# define png_handle_zTXt NULL +#endif + +#ifdef PNG_READ_iTXt_SUPPORTED +/* Note: this does not correctly handle chunks that are > 64K under DOS */ +static png_handle_result_code /* PRIVATE */ +png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + png_const_charp errmsg = NULL; + png_bytep buffer; + png_uint_32 prefix_length; + + png_debug(1, "in png_handle_iTXt"); + +#ifdef PNG_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return handled_error; + } + + if (--png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "no space in chunk cache"); + return handled_error; + } + } +#endif + + buffer = png_read_buffer(png_ptr, length+1); + + if (buffer == NULL) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "out of memory"); + return handled_error; + } + + png_crc_read(png_ptr, buffer, length); + + if (png_crc_finish(png_ptr, 0) != 0) + return handled_error; + + /* First the keyword. */ + for (prefix_length=0; + prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* Perform a basic check on the keyword length here. */ + if (prefix_length > 79 || prefix_length < 1) + errmsg = "bad keyword"; + + /* Expect keyword, compression flag, compression type, language, translated + * keyword (both may be empty but are 0 terminated) then the text, which may + * be empty. + */ + else if (prefix_length + 5 > length) + errmsg = "truncated"; + + else if (buffer[prefix_length+1] == 0 || + (buffer[prefix_length+1] == 1 && + buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) + { + int compressed = buffer[prefix_length+1] != 0; + png_uint_32 language_offset, translated_keyword_offset; + png_alloc_size_t uncompressed_length = 0; + + /* Now the language tag */ + prefix_length += 3; + language_offset = prefix_length; + + for (; prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* WARNING: the length may be invalid here, this is checked below. */ + translated_keyword_offset = ++prefix_length; + + for (; prefix_length < length && buffer[prefix_length] != 0; + ++prefix_length) + /* Empty loop */ ; + + /* prefix_length should now be at the trailing '\0' of the translated + * keyword, but it may already be over the end. None of this arithmetic + * can overflow because chunks are at most 2^31 bytes long, but on 16-bit + * systems the available allocation may overflow. + */ + ++prefix_length; + + if (compressed == 0 && prefix_length <= length) + uncompressed_length = length - prefix_length; + + else if (compressed != 0 && prefix_length < length) + { + uncompressed_length = PNG_SIZE_MAX; + + /* TODO: at present png_decompress_chunk imposes a single application + * level memory limit, this should be split to different values for + * iCCP and text chunks. + */ + if (png_decompress_chunk(png_ptr, length, prefix_length, + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) + buffer = png_ptr->read_buffer; + + else + errmsg = png_ptr->zstream.msg; + } + + else + errmsg = "truncated"; + + if (errmsg == NULL) + { + png_text text; + + buffer[uncompressed_length+prefix_length] = 0; + + if (compressed == 0) + text.compression = PNG_ITXT_COMPRESSION_NONE; + + else + text.compression = PNG_ITXT_COMPRESSION_zTXt; + + text.key = (png_charp)buffer; + text.lang = (png_charp)buffer + language_offset; + text.lang_key = (png_charp)buffer + translated_keyword_offset; + text.text = (png_charp)buffer + prefix_length; + text.text_length = 0; + text.itxt_length = uncompressed_length; + + if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0) + return handled_ok; + + errmsg = "out of memory"; + } + } + + else + errmsg = "bad compression info"; + + if (errmsg != NULL) + png_chunk_benign_error(png_ptr, errmsg); + return handled_error; +} +#else +# define png_handle_iTXt NULL +#endif + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ +static int +png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) +{ + const png_alloc_size_t limit = png_chunk_max(png_ptr); + + if (png_ptr->unknown_chunk.data != NULL) + { + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + + if (length <= limit) + { + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); + /* The following is safe because of the PNG_SIZE_MAX init above */ + png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/; + /* 'mode' is a flag array, only the bottom four bits matter here */ + png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; + + if (length == 0) + png_ptr->unknown_chunk.data = NULL; + + else + { + /* Do a 'warn' here - it is handled below. */ + png_ptr->unknown_chunk.data = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, length)); + } + } + + if (png_ptr->unknown_chunk.data == NULL && length > 0) + { + /* This is benign because we clean up correctly */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); + return 0; + } + + else + { + if (length > 0) + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); + png_crc_finish(png_ptr, 0); + return 1; + } +} +#endif /* READ_UNKNOWN_CHUNKS */ + +/* Handle an unknown, or known but disabled, chunk */ +png_handle_result_code /*PRIVATE*/ +png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, + png_uint_32 length, int keep) +{ + png_handle_result_code handled = handled_discarded; /* the default */ + + png_debug(1, "in png_handle_unknown"); + +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing + * the bug which meant that setting a non-default behavior for a specific + * chunk would be ignored (the default was always used unless a user + * callback was installed). + * + * 'keep' is the value from the png_chunk_unknown_handling, the setting for + * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it + * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. + * This is just an optimization to avoid multiple calls to the lookup + * function. + */ +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); +# endif +# endif + + /* One of the following methods will read the chunk or skip it (at least one + * of these is always defined because this is the only way to switch on + * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) + */ +# ifdef PNG_READ_USER_CHUNKS_SUPPORTED + /* The user callback takes precedence over the chunk keep value, but the + * keep value is still required to validate a save of a critical chunk. + */ + if (png_ptr->read_user_chunk_fn != NULL) + { + if (png_cache_unknown_chunk(png_ptr, length) != 0) + { + /* Callback to user unknown chunk handler */ + int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, + &png_ptr->unknown_chunk); + + /* ret is: + * negative: An error occurred; png_chunk_error will be called. + * zero: The chunk was not handled, the chunk will be discarded + * unless png_set_keep_unknown_chunks has been used to set + * a 'keep' behavior for this particular chunk, in which + * case that will be used. A critical chunk will cause an + * error at this point unless it is to be saved. + * positive: The chunk was handled, libpng will ignore/discard it. + */ + if (ret < 0) /* handled_error */ + png_chunk_error(png_ptr, "error in user chunk"); + + else if (ret == 0) + { + /* If the keep value is 'default' or 'never' override it, but + * still error out on critical chunks unless the keep value is + * 'always' While this is weird it is the behavior in 1.4.12. + * A possible improvement would be to obey the value set for the + * chunk, but this would be an API change that would probably + * damage some applications. + * + * The png_app_warning below catches the case that matters, where + * the application has not set specific save or ignore for this + * chunk or global save or ignore. + */ + if (keep < PNG_HANDLE_CHUNK_IF_SAFE) + { +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) + { + png_chunk_warning(png_ptr, "Saving unknown chunk:"); + png_app_warning(png_ptr, + "forcing save of an unhandled chunk;" + " please call png_set_keep_unknown_chunks"); + /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ + } +# endif + keep = PNG_HANDLE_CHUNK_IF_SAFE; + } + } + + else /* chunk was handled */ + { + handled = handled_ok; + /* Critical chunks can be safely discarded at this point. */ + keep = PNG_HANDLE_CHUNK_NEVER; + } + } + + else + keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ + } + + else + /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ +# endif /* READ_USER_CHUNKS */ + +# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED + { + /* keep is currently just the per-chunk setting, if there was no + * setting change it to the global default now (not that this may + * still be AS_DEFAULT) then obtain the cache of the chunk if required, + * if not simply skip the chunk. + */ + if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) + keep = png_ptr->unknown_default; + + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { + if (png_cache_unknown_chunk(png_ptr, length) == 0) + keep = PNG_HANDLE_CHUNK_NEVER; + } + + else + png_crc_finish(png_ptr, length); + } +# else +# ifndef PNG_READ_USER_CHUNKS_SUPPORTED +# error no method to support READ_UNKNOWN_CHUNKS +# endif + + { + /* If here there is no read callback pointer set and no support is + * compiled in to just save the unknown chunks, so simply skip this + * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then + * the app has erroneously asked for unknown chunk saving when there + * is no support. + */ + if (keep > PNG_HANDLE_CHUNK_NEVER) + png_app_error(png_ptr, "no unknown chunk support available"); + + png_crc_finish(png_ptr, length); + } +# endif + +# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED + /* Now store the chunk in the chunk list if appropriate, and if the limits + * permit it. + */ + if (keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_IF_SAFE && + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) + { +# ifdef PNG_USER_LIMITS_SUPPORTED + switch (png_ptr->user_chunk_cache_max) + { + case 2: + png_ptr->user_chunk_cache_max = 1; + png_chunk_benign_error(png_ptr, "no space in chunk cache"); + /* FALLTHROUGH */ + case 1: + /* NOTE: prior to 1.6.0 this case resulted in an unknown critical + * chunk being skipped, now there will be a hard error below. + */ + break; + + default: /* not at limit */ + --(png_ptr->user_chunk_cache_max); + /* FALLTHROUGH */ + case 0: /* no limit */ +# endif /* USER_LIMITS */ + /* Here when the limit isn't reached or when limits are compiled + * out; store the chunk. + */ + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + handled = handled_saved; +# ifdef PNG_USER_LIMITS_SUPPORTED + break; + } +# endif + } +# else /* no store support: the chunk must be handled by the user callback */ + PNG_UNUSED(info_ptr) +# endif + + /* Regardless of the error handling below the cached data (if any) can be + * freed now. Notice that the data is not freed if there is a png_error, but + * it will be freed by destroy_read_struct. + */ + if (png_ptr->unknown_chunk.data != NULL) + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + +#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ + /* There is no support to read an unknown chunk, so just skip it. */ + png_crc_finish(png_ptr, length); + PNG_UNUSED(info_ptr) + PNG_UNUSED(keep) +#endif /* !READ_UNKNOWN_CHUNKS */ + + /* Check for unhandled critical chunks */ + if (handled < handled_saved && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) + png_chunk_error(png_ptr, "unhandled critical chunk"); + + return handled; +} + +/* APNG handling: the minimal implementation of APNG handling in libpng 1.6 + * requires that those significant applications which already handle APNG not + * get hosed. To do this ensure the code here will have to ensure than APNG + * data by default (at least in 1.6) gets stored in the unknown chunk list. + * Maybe this can be relaxed in a few years but at present it's just the only + * safe way. + * + * ATM just cause unknown handling for all three chunks: + */ +#define png_handle_acTL NULL +#define png_handle_fcTL NULL +#define png_handle_fdAT NULL + +/* + * 1.6.47: This is the new table driven interface to all the chunk handling. + * + * The table describes the PNG standard rules for **reading** known chunks - + * every chunk which has an entry in PNG_KNOWN_CHUNKS. The table contains an + * entry for each PNG_INDEX_cHNK describing the rules. + * + * In this initial version the only information in the entry is the + * png_handle_cHNK function for the chunk in question. When chunk support is + * compiled out the entry will be NULL. + */ +static const struct +{ + png_handle_result_code (*handler)( + png_structrp, png_inforp, png_uint_32 length); + /* A chunk-specific 'handler', NULL if the chunk is not supported in this + * build. + */ + + /* Crushing these values helps on modern 32-bit architectures because the + * pointer and the following bit fields both end up requiring 32 bits. + * Typically this will halve the table size. On 64-bit architectures the + * table entries will typically be 8 bytes. + */ + png_uint_32 max_length :12; /* Length min, max in bytes */ + png_uint_32 min_length :8; + /* Length errors on critical chunks have special handling to preserve the + * existing behaviour in libpng 1.6. Ancillary chunks are checked below + * and produce a 'benign' error. + */ + png_uint_32 pos_before :4; /* PNG_HAVE_ values chunk must precede */ + png_uint_32 pos_after :4; /* PNG_HAVE_ values chunk must follow */ + /* NOTE: PLTE, tRNS and bKGD require special handling which depends on + * the colour type of the base image. + */ + png_uint_32 multiple :1; /* Multiple occurrences permitted */ + /* This is enabled for PLTE because PLTE may, in practice, be optional */ +} +read_chunks[PNG_INDEX_unknown] = +{ + /* Definitions as above but done indirectly by #define so that + * PNG_KNOWN_CHUNKS can be used safely to build the table in order. + * + * Each CDcHNK definition lists the values for the parameters **after** + * the first, 'handler', function. 'handler' is NULL when the chunk has no + * compiled in support. + */ +# define NoCheck 0x801U /* Do not check the maximum length */ +# define Limit 0x802U /* Limit to png_chunk_max bytes */ +# define LKMin 3U+LZ77Min /* Minimum length of keyword+LZ77 */ + +#define hIHDR PNG_HAVE_IHDR +#define hPLTE PNG_HAVE_PLTE +#define hIDAT PNG_HAVE_IDAT + /* For the two chunks, tRNS and bKGD which can occur in PNGs without a PLTE + * but must occur after the PLTE use this and put the check in the handler + * routine for colour mapped images were PLTE is required. Also put a check + * in PLTE for other image types to drop the PLTE if tRNS or bKGD have been + * seen. + */ +#define hCOL (PNG_HAVE_PLTE|PNG_HAVE_IDAT) + /* Used for the decoding chunks which must be before PLTE. */ +#define aIDAT PNG_AFTER_IDAT + + /* Chunks from W3C PNG v3: */ + /* cHNK max_len, min, before, after, multiple */ +# define CDIHDR 13U, 13U, hIHDR, 0, 0 +# define CDPLTE NoCheck, 0U, 0, hIHDR, 1 + /* PLTE errors are only critical for colour-map images, consequently the + * handler does all the checks. + */ +# define CDIDAT NoCheck, 0U, aIDAT, hIHDR, 1 +# define CDIEND NoCheck, 0U, 0, aIDAT, 0 + /* Historically data was allowed in IEND */ +# define CDtRNS 256U, 0U, hIDAT, hIHDR, 0 +# define CDcHRM 32U, 32U, hCOL, hIHDR, 0 +# define CDgAMA 4U, 4U, hCOL, hIHDR, 0 +# define CDiCCP NoCheck, LKMin, hCOL, hIHDR, 0 +# define CDsBIT 4U, 1U, hCOL, hIHDR, 0 +# define CDsRGB 1U, 1U, hCOL, hIHDR, 0 +# define CDcICP 4U, 4U, hCOL, hIHDR, 0 +# define CDmDCV 24U, 24U, hCOL, hIHDR, 0 +# define CDeXIf Limit, 4U, 0, hIHDR, 0 +# define CDcLLI 8U, 8U, hCOL, hIHDR, 0 +# define CDtEXt NoCheck, 2U, 0, hIHDR, 1 + /* Allocates 'length+1'; checked in the handler */ +# define CDzTXt Limit, LKMin, 0, hIHDR, 1 +# define CDiTXt NoCheck, 6U, 0, hIHDR, 1 + /* Allocates 'length+1'; checked in the handler */ +# define CDbKGD 6U, 1U, hIDAT, hIHDR, 0 +# define CDhIST 1024U, 0U, hPLTE, hIHDR, 0 +# define CDpHYs 9U, 9U, hIDAT, hIHDR, 0 +# define CDsPLT NoCheck, 3U, hIDAT, hIHDR, 1 + /* Allocates 'length+1'; checked in the handler */ +# define CDtIME 7U, 7U, 0, hIHDR, 0 +# define CDacTL 8U, 8U, hIDAT, hIHDR, 0 +# define CDfcTL 25U, 26U, 0, hIHDR, 1 +# define CDfdAT Limit, 4U, hIDAT, hIHDR, 1 + /* Supported chunks from PNG extensions 1.5.0, NYI so limit */ +# define CDoFFs 9U, 9U, hIDAT, hIHDR, 0 +# define CDpCAL NoCheck, 14U, hIDAT, hIHDR, 0 + /* Allocates 'length+1'; checked in the handler */ +# define CDsCAL Limit, 4U, hIDAT, hIHDR, 0 + /* Allocates 'length+1'; checked in the handler */ + +# define PNG_CHUNK(cHNK, index) { png_handle_ ## cHNK, CD ## cHNK }, + PNG_KNOWN_CHUNKS +# undef PNG_CHUNK +}; + + +static png_index +png_chunk_index_from_name(png_uint_32 chunk_name) +{ + /* For chunk png_cHNK return PNG_INDEX_cHNK. Return PNG_INDEX_unknown if + * chunk_name is not known. Notice that in a particular build "known" does + * not necessarily mean "supported", although the inverse applies. + */ + switch (chunk_name) + { +# define PNG_CHUNK(cHNK, index)\ + case png_ ## cHNK: return PNG_INDEX_ ## cHNK; /* == index */ + + PNG_KNOWN_CHUNKS + +# undef PNG_CHUNK + + default: return PNG_INDEX_unknown; + } +} + +png_handle_result_code /*PRIVATE*/ +png_handle_chunk(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) +{ + /* CSE: these things don't change, these autos are just to save typing and + * make the code more clear. + */ + const png_uint_32 chunk_name = png_ptr->chunk_name; + const png_index chunk_index = png_chunk_index_from_name(chunk_name); + + png_handle_result_code handled = handled_error; + png_const_charp errmsg = NULL; + + /* Is this a known chunk? If not there are no checks performed here; + * png_handle_unknown does the correct checks. This means that the values + * for known but unsupported chunks in the above table are not used here + * however the chunks_seen fields in png_struct are still set. + */ + if (chunk_index == PNG_INDEX_unknown || + read_chunks[chunk_index].handler == NULL) + { + handled = png_handle_unknown( + png_ptr, info_ptr, length, PNG_HANDLE_CHUNK_AS_DEFAULT); + } + + /* First check the position. The first check is historical; the stream must + * start with IHDR and anything else causes libpng to give up immediately. + */ + else if (chunk_index != PNG_INDEX_IHDR && + (png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_chunk_error(png_ptr, "missing IHDR"); /* NORETURN */ + + /* Before all the pos_before chunks, after all the pos_after chunks. */ + else if (((png_ptr->mode & read_chunks[chunk_index].pos_before) != 0) || + ((png_ptr->mode & read_chunks[chunk_index].pos_after) != + read_chunks[chunk_index].pos_after)) + { + errmsg = "out of place"; + } + + /* Now check for duplicates: duplicated critical chunks also produce a + * full error. + */ + else if (read_chunks[chunk_index].multiple == 0 && + png_file_has_chunk(png_ptr, chunk_index)) + { + errmsg = "duplicate"; + } + + else if (length < read_chunks[chunk_index].min_length) + errmsg = "too short"; + else + { + /* NOTE: apart from IHDR the critical chunks (PLTE, IDAT and IEND) are set + * up above not to do any length checks. + * + * The png_chunk_max check ensures that the variable length chunks are + * always checked at this point for being within the system allocation + * limits. + */ + unsigned max_length = read_chunks[chunk_index].max_length; + + switch (max_length) + { + case Limit: + /* png_read_chunk_header has already png_error'ed chunks with a + * length exceeding the 31-bit PNG limit, so just check the memory + * limit: + */ + if (length <= png_chunk_max(png_ptr)) + goto MeetsLimit; + + errmsg = "length exceeds libpng limit"; + break; + + default: + if (length <= max_length) + goto MeetsLimit; + + errmsg = "too long"; + break; + + case NoCheck: + MeetsLimit: + handled = read_chunks[chunk_index].handler( + png_ptr, info_ptr, length); + break; + } + } + + /* If there was an error or the chunk was simply skipped it is not counted as + * 'seen'. + */ + if (errmsg != NULL) + { + if (PNG_CHUNK_CRITICAL(chunk_name)) /* stop immediately */ + png_chunk_error(png_ptr, errmsg); + else /* ancillary chunk */ + { + /* The chunk data is skipped: */ + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, errmsg); + } + } + + else if (handled >= handled_saved) + { + if (chunk_index != PNG_INDEX_unknown) + png_file_add_chunk(png_ptr, chunk_index); + } + + return handled; +} + +/* Combines the row recently read in with the existing pixels in the row. This + * routine takes care of alpha and transparency if requested. This routine also + * handles the two methods of progressive display of interlaced images, + * depending on the 'display' value; if 'display' is true then the whole row + * (dp) is filled from the start by replicating the available pixels. If + * 'display' is false only those pixels present in the pass are filled in. + */ +void /* PRIVATE */ +png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) +{ + unsigned int pixel_depth = png_ptr->transformed_pixel_depth; + png_const_bytep sp = png_ptr->row_buf + 1; + png_alloc_size_t row_width = png_ptr->width; + unsigned int pass = png_ptr->pass; + png_bytep end_ptr = 0; + png_byte end_byte = 0; + unsigned int end_mask; + + png_debug(1, "in png_combine_row"); + + /* Added in 1.5.6: it should not be possible to enter this routine until at + * least one row has been read from the PNG data and transformed. + */ + if (pixel_depth == 0) + png_error(png_ptr, "internal row logic error"); + + /* Added in 1.5.4: the pixel depth should match the information returned by + * any call to png_read_update_info at this point. Do not continue if we got + * this wrong. + */ + if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != + PNG_ROWBYTES(pixel_depth, row_width)) + png_error(png_ptr, "internal row size calculation error"); + + /* Don't expect this to ever happen: */ + if (row_width == 0) + png_error(png_ptr, "internal row width error"); + + /* Preserve the last byte in cases where only part of it will be overwritten, + * the multiply below may overflow, we don't care because ANSI-C guarantees + * we get the low bits. + */ + end_mask = (pixel_depth * row_width) & 7; + if (end_mask != 0) + { + /* end_ptr == NULL is a flag to say do nothing */ + end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; + end_byte = *end_ptr; +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + /* little-endian byte */ + end_mask = (unsigned int)(0xff << end_mask); + + else /* big-endian byte */ +# endif + end_mask = 0xff >> end_mask; + /* end_mask is now the bits to *keep* from the destination row */ + } + + /* For non-interlaced images this reduces to a memcpy(). A memcpy() + * will also happen if interlacing isn't supported or if the application + * does not call png_set_interlace_handling(). In the latter cases the + * caller just gets a sequence of the unexpanded rows from each interlace + * pass. + */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0 && + pass < 6 && (display == 0 || + /* The following copies everything for 'display' on passes 0, 2 and 4. */ + (display == 1 && (pass & 1) != 0))) + { + /* Narrow images may have no bits in a pass; the caller should handle + * this, but this test is cheap: + */ + if (row_width <= PNG_PASS_START_COL(pass)) + return; + + if (pixel_depth < 8) + { + /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit + * into 32 bits, then a single loop over the bytes using the four byte + * values in the 32-bit mask can be used. For the 'display' option the + * expanded mask may also not require any masking within a byte. To + * make this work the PACKSWAP option must be taken into account - it + * simply requires the pixels to be reversed in each byte. + * + * The 'regular' case requires a mask for each of the first 6 passes, + * the 'display' case does a copy for the even passes in the range + * 0..6. This has already been handled in the test above. + * + * The masks are arranged as four bytes with the first byte to use in + * the lowest bits (little-endian) regardless of the order (PACKSWAP or + * not) of the pixels in each byte. + * + * NOTE: the whole of this logic depends on the caller of this function + * only calling it on rows appropriate to the pass. This function only + * understands the 'x' logic; the 'y' logic is handled by the caller. + * + * The following defines allow generation of compile time constant bit + * masks for each pixel depth and each possibility of swapped or not + * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, + * is in the range 0..7; and the result is 1 if the pixel is to be + * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' + * for the block method. + * + * With some compilers a compile time expression of the general form: + * + * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) + * + * Produces warnings with values of 'shift' in the range 33 to 63 + * because the right hand side of the ?: expression is evaluated by + * the compiler even though it isn't used. Microsoft Visual C (various + * versions) and the Intel C compiler are known to do this. To avoid + * this the following macros are used in 1.5.6. This is a temporary + * solution to avoid destabilizing the code during the release process. + */ +# if PNG_USE_COMPILE_TIME_MASKS +# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) +# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) +# else +# define PNG_LSR(x,s) ((x)>>(s)) +# define PNG_LSL(x,s) ((x)<<(s)) +# endif +# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) +# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ + PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) + + /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is + * little endian - the first pixel is at bit 0 - however the extra + * parameter 's' can be set to cause the mask position to be swapped + * within each byte, to match the PNG format. This is done by XOR of + * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. + */ +# define PIXEL_MASK(p,x,d,s) \ + (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) + + /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. + */ +# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) +# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) + + /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp + * cases the result needs replicating, for the 4-bpp case the above + * generates a full 32 bits. + */ +# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) + +# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ + S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ + S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) + +# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ + B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ + B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) + +#if PNG_USE_COMPILE_TIME_MASKS + /* Utility macros to construct all the masks for a depth/swap + * combination. The 's' parameter says whether the format is PNG + * (big endian bytes) or not. Only the three odd-numbered passes are + * required for the display/block algorithm. + */ +# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ + S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } + +# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) } + +# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) + + /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and + * then pass: + */ + static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + { + /* Little-endian byte masks for PACKSWAP */ + { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } + }; + + /* display_mask has only three entries for the odd passes, so index by + * pass>>1. + */ + static const png_uint_32 display_mask[2][3][3] = + { + /* Little-endian byte masks for PACKSWAP */ + { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, + /* Normal (big-endian byte) masks - PNG format */ + { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } + }; + +# define MASK(pass,depth,display,png)\ + ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ + row_mask[png][DEPTH_INDEX(depth)][pass]) + +#else /* !PNG_USE_COMPILE_TIME_MASKS */ + /* This is the runtime alternative: it seems unlikely that this will + * ever be either smaller or faster than the compile time approach. + */ +# define MASK(pass,depth,display,png)\ + ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) +#endif /* !USE_COMPILE_TIME_MASKS */ + + /* Use the appropriate mask to copy the required bits. In some cases + * the byte mask will be 0 or 0xff; optimize these cases. row_width is + * the number of pixels, but the code copies bytes, so it is necessary + * to special case the end. + */ + png_uint_32 pixels_per_byte = 8 / pixel_depth; + png_uint_32 mask; + +# ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + mask = MASK(pass, pixel_depth, display, 0); + + else +# endif + mask = MASK(pass, pixel_depth, display, 1); + + for (;;) + { + png_uint_32 m; + + /* It doesn't matter in the following if png_uint_32 has more than + * 32 bits because the high bits always match those in m<<24; it is, + * however, essential to use OR here, not +, because of this. + */ + m = mask; + mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ + m &= 0xff; + + if (m != 0) /* something to copy */ + { + if (m != 0xff) + *dp = (png_byte)((*dp & ~m) | (*sp & m)); + else + *dp = *sp; + } + + /* NOTE: this may overwrite the last byte with garbage if the image + * is not an exact number of bytes wide; libpng has always done + * this. + */ + if (row_width <= pixels_per_byte) + break; /* May need to restore part of the last byte */ + + row_width -= pixels_per_byte; + ++dp; + ++sp; + } + } + + else /* pixel_depth >= 8 */ + { + unsigned int bytes_to_copy, bytes_to_jump; + + /* Validate the depth - it must be a multiple of 8 */ + if (pixel_depth & 7) + png_error(png_ptr, "invalid user transform pixel depth"); + + pixel_depth >>= 3; /* now in bytes */ + row_width *= pixel_depth; + + /* Regardless of pass number the Adam 7 interlace always results in a + * fixed number of pixels to copy then to skip. There may be a + * different number of pixels to skip at the start though. + */ + { + unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; + + row_width -= offset; + dp += offset; + sp += offset; + } + + /* Work out the bytes to copy. */ + if (display != 0) + { + /* When doing the 'block' algorithm the pixel in the pass gets + * replicated to adjacent pixels. This is why the even (0,2,4,6) + * passes are skipped above - the entire expanded row is copied. + */ + bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; + + /* But don't allow this number to exceed the actual row width. */ + if (bytes_to_copy > row_width) + bytes_to_copy = (unsigned int)/*SAFE*/row_width; + } + + else /* normal row; Adam7 only ever gives us one pixel to copy. */ + bytes_to_copy = pixel_depth; + + /* In Adam7 there is a constant offset between where the pixels go. */ + bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; + + /* And simply copy these bytes. Some optimization is possible here, + * depending on the value of 'bytes_to_copy'. Special case the low + * byte counts, which we know to be frequent. + * + * Notice that these cases all 'return' rather than 'break' - this + * avoids an unnecessary test on whether to restore the last byte + * below. + */ + switch (bytes_to_copy) + { + case 1: + for (;;) + { + *dp = *sp; + + if (row_width <= bytes_to_jump) + return; + + dp += bytes_to_jump; + sp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + case 2: + /* There is a possibility of a partial copy at the end here; this + * slows the code down somewhat. + */ + do + { + dp[0] = sp[0]; dp[1] = sp[1]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + while (row_width > 1); + + /* And there can only be one byte left at this point: */ + *dp = *sp; + return; + + case 3: + /* This can only be the RGB case, so each copy is exactly one + * pixel and it is not necessary to check for a partial copy. + */ + for (;;) + { + dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2]; + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + } + + default: +#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE + /* Check for double byte alignment and, if possible, use a + * 16-bit copy. Don't attempt this for narrow images - ones that + * are less than an interlace panel wide. Don't attempt it for + * wide bytes_to_copy either - use the memcpy there. + */ + if (bytes_to_copy < 16 /*else use memcpy*/ && + png_isaligned(dp, png_uint_16) && + png_isaligned(sp, png_uint_16) && + bytes_to_copy % (sizeof (png_uint_16)) == 0 && + bytes_to_jump % (sizeof (png_uint_16)) == 0) + { + /* Everything is aligned for png_uint_16 copies, but try for + * png_uint_32 first. + */ + if (png_isaligned(dp, png_uint_32) && + png_isaligned(sp, png_uint_32) && + bytes_to_copy % (sizeof (png_uint_32)) == 0 && + bytes_to_jump % (sizeof (png_uint_32)) == 0) + { + png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); + png_const_uint_32p sp32 = png_aligncastconst( + png_const_uint_32p, sp); + size_t skip = (bytes_to_jump-bytes_to_copy) / + (sizeof (png_uint_32)); + + do + { + size_t c = bytes_to_copy; + do + { + *dp32++ = *sp32++; + c -= (sizeof (png_uint_32)); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp32 += skip; + sp32 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* Get to here when the row_width truncates the final copy. + * There will be 1-3 bytes left to copy, so don't try the + * 16-bit loop below. + */ + dp = (png_bytep)dp32; + sp = (png_const_bytep)sp32; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + + /* Else do it in 16-bit quantities, but only if the size is + * not too large. + */ + else + { + png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); + png_const_uint_16p sp16 = png_aligncastconst( + png_const_uint_16p, sp); + size_t skip = (bytes_to_jump-bytes_to_copy) / + (sizeof (png_uint_16)); + + do + { + size_t c = bytes_to_copy; + do + { + *dp16++ = *sp16++; + c -= (sizeof (png_uint_16)); + } + while (c > 0); + + if (row_width <= bytes_to_jump) + return; + + dp16 += skip; + sp16 += skip; + row_width -= bytes_to_jump; + } + while (bytes_to_copy <= row_width); + + /* End of row - 1 byte left, bytes_to_copy > row_width: */ + dp = (png_bytep)dp16; + sp = (png_const_bytep)sp16; + do + *dp++ = *sp++; + while (--row_width > 0); + return; + } + } +#endif /* ALIGN_TYPE code */ + + /* The true default - use a memcpy: */ + for (;;) + { + memcpy(dp, sp, bytes_to_copy); + + if (row_width <= bytes_to_jump) + return; + + sp += bytes_to_jump; + dp += bytes_to_jump; + row_width -= bytes_to_jump; + if (bytes_to_copy > row_width) + bytes_to_copy = (unsigned int)/*SAFE*/row_width; + } + } + + /* NOT REACHED*/ + } /* pixel_depth >= 8 */ + + /* Here if pixel_depth < 8 to check 'end_ptr' below. */ + } + else +#endif /* READ_INTERLACING */ + + /* If here then the switch above wasn't used so just memcpy the whole row + * from the temporary row buffer (notice that this overwrites the end of the + * destination row if it is a partial byte.) + */ + memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); + + /* Restore the overwritten bits from the last byte if necessary. */ + if (end_ptr != NULL) + *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); +} + +#ifdef PNG_READ_INTERLACING_SUPPORTED +void /* PRIVATE */ +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, + png_uint_32 transformations /* Because these may affect the byte layout */) +{ + png_debug(1, "in png_do_read_interlace"); + if (row != NULL && row_info != NULL) + { + png_uint_32 final_width; + + final_width = row_info->width * png_pass_inc[pass]; + + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp = row + (size_t)((row_info->width - 1) >> 3); + png_bytep dp = row + (size_t)((final_width - 1) >> 3); + unsigned int sshift, dshift; + unsigned int s_start, s_end; + int s_inc; + int jstop = (int)png_pass_inc[pass]; + png_byte v; + png_uint_32 i; + int j; + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((transformations & PNG_PACKSWAP) != 0) + { + sshift = ((row_info->width + 7) & 0x07); + dshift = ((final_width + 7) & 0x07); + s_start = 7; + s_end = 0; + s_inc = -1; + } + + else +#endif + { + sshift = 7 - ((row_info->width + 7) & 0x07); + dshift = 7 - ((final_width + 7) & 0x07); + s_start = 0; + s_end = 7; + s_inc = 1; + } + + for (i = 0; i < row_info->width; i++) + { + v = (png_byte)((*sp >> sshift) & 0x01); + for (j = 0; j < jstop; j++) + { + unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); + tmp |= (unsigned int)(v << dshift); + *dp = (png_byte)(tmp & 0xff); + + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + + else + dshift = (unsigned int)((int)dshift + s_inc); + } + + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + + else + sshift = (unsigned int)((int)sshift + s_inc); + } + break; + } + + case 2: + { + png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); + png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); + unsigned int sshift, dshift; + unsigned int s_start, s_end; + int s_inc; + int jstop = (int)png_pass_inc[pass]; + png_uint_32 i; + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((transformations & PNG_PACKSWAP) != 0) + { + sshift = (((row_info->width + 3) & 0x03) << 1); + dshift = (((final_width + 3) & 0x03) << 1); + s_start = 6; + s_end = 0; + s_inc = -2; + } + + else +#endif + { + sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1); + dshift = ((3 - ((final_width + 3) & 0x03)) << 1); + s_start = 0; + s_end = 6; + s_inc = 2; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v; + int j; + + v = (png_byte)((*sp >> sshift) & 0x03); + for (j = 0; j < jstop; j++) + { + unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); + tmp |= (unsigned int)(v << dshift); + *dp = (png_byte)(tmp & 0xff); + + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + + else + dshift = (unsigned int)((int)dshift + s_inc); + } + + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + + else + sshift = (unsigned int)((int)sshift + s_inc); + } + break; + } + + case 4: + { + png_bytep sp = row + (size_t)((row_info->width - 1) >> 1); + png_bytep dp = row + (size_t)((final_width - 1) >> 1); + unsigned int sshift, dshift; + unsigned int s_start, s_end; + int s_inc; + png_uint_32 i; + int jstop = (int)png_pass_inc[pass]; + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((transformations & PNG_PACKSWAP) != 0) + { + sshift = (((row_info->width + 1) & 0x01) << 2); + dshift = (((final_width + 1) & 0x01) << 2); + s_start = 4; + s_end = 0; + s_inc = -4; + } + + else +#endif + { + sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2); + dshift = ((1 - ((final_width + 1) & 0x01)) << 2); + s_start = 0; + s_end = 4; + s_inc = 4; + } + + for (i = 0; i < row_info->width; i++) + { + png_byte v = (png_byte)((*sp >> sshift) & 0x0f); + int j; + + for (j = 0; j < jstop; j++) + { + unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); + tmp |= (unsigned int)(v << dshift); + *dp = (png_byte)(tmp & 0xff); + + if (dshift == s_end) + { + dshift = s_start; + dp--; + } + + else + dshift = (unsigned int)((int)dshift + s_inc); + } + + if (sshift == s_end) + { + sshift = s_start; + sp--; + } + + else + sshift = (unsigned int)((int)sshift + s_inc); + } + break; + } + + default: + { + size_t pixel_bytes = (row_info->pixel_depth >> 3); + + png_bytep sp = row + (size_t)(row_info->width - 1) + * pixel_bytes; + + png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes; + + int jstop = (int)png_pass_inc[pass]; + png_uint_32 i; + + for (i = 0; i < row_info->width; i++) + { + png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ + int j; + + memcpy(v, sp, pixel_bytes); + + for (j = 0; j < jstop; j++) + { + memcpy(dp, v, pixel_bytes); + dp -= pixel_bytes; + } + + sp -= pixel_bytes; + } + break; + } + } + + row_info->width = final_width; + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); + } +#ifndef PNG_READ_PACKSWAP_SUPPORTED + PNG_UNUSED(transformations) /* Silence compiler warning */ +#endif +} +#endif /* READ_INTERLACING */ + +static void +png_read_filter_row_sub(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + size_t i; + size_t istop = row_info->rowbytes; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp = row + bpp; + + PNG_UNUSED(prev_row) + + for (i = bpp; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_up(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + size_t i; + size_t istop = row_info->rowbytes; + png_bytep rp = row; + png_const_bytep pp = prev_row; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); + rp++; + } +} + +static void +png_read_filter_row_avg(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + size_t i; + png_bytep rp = row; + png_const_bytep pp = prev_row; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + size_t istop = row_info->rowbytes - bpp; + + for (i = 0; i < bpp; i++) + { + *rp = (png_byte)(((int)(*rp) + + ((int)(*pp++) / 2 )) & 0xff); + + rp++; + } + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(((int)(*rp) + + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); + + rp++; + } +} + +static void +png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp_end = row + row_info->rowbytes; + int a, c; + + /* First pixel/byte */ + c = *prev_row++; + a = *row + c; + *row++ = (png_byte)a; + + /* Remainder */ + while (row < rp_end) + { + int b, pa, pb, pc, p; + + a &= 0xff; /* From previous iteration or start */ + b = *prev_row++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + /* Find the best predictor, the least of pa, pb, pc favoring the earlier + * ones in the case of a tie. + */ + if (pb < pa) + { + pa = pb; a = b; + } + if (pc < pa) a = c; + + /* Calculate the current pixel in a, and move the previous row pixel to c + * for the next time round the loop + */ + c = b; + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_bytep rp_end = row + bpp; + + /* Process the first pixel in the row completely (this is the same as 'up' + * because there is only one candidate predictor for the first row). + */ + while (row < rp_end) + { + int a = *row + *prev_row++; + *row++ = (png_byte)a; + } + + /* Remainder */ + rp_end = rp_end + (row_info->rowbytes - bpp); + + while (row < rp_end) + { + int a, b, c, pa, pb, pc, p; + + c = *(prev_row - bpp); + a = *(row - bpp); + b = *prev_row++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + if (pb < pa) + { + pa = pb; a = b; + } + if (pc < pa) a = c; + + a += *row; + *row++ = (png_byte)a; + } +} + +static void +png_init_filter_functions(png_structrp pp) + /* This function is called once for every PNG image (except for PNG images + * that only use PNG_FILTER_VALUE_NONE for all rows) to set the + * implementations required to reverse the filtering of PNG rows. Reversing + * the filter is the first transformation performed on the row data. It is + * performed in place, therefore an implementation can be selected based on + * the image pixel format. If the implementation depends on image width then + * take care to ensure that it works correctly if the image is interlaced - + * interlacing causes the actual row width to vary. + */ +{ + unsigned int bpp = (pp->pixel_depth + 7) >> 3; + + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; + if (bpp == 1) + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_1byte_pixel; + else + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth_multibyte_pixel; + +#ifdef PNG_FILTER_OPTIMIZATIONS + /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to + * call to install hardware optimizations for the above functions; simply + * replace whatever elements of the pp->read_filter[] array with a hardware + * specific (or, for that matter, generic) optimization. + * + * To see an example of this examine what configure.ac does when + * --enable-arm-neon is specified on the command line. + */ + PNG_FILTER_OPTIMIZATIONS(pp, bpp); +#endif +} + +void /* PRIVATE */ +png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, + png_const_bytep prev_row, int filter) +{ + /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define + * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic + * implementations. See png_init_filter_functions above. + */ + if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) + { + if (pp->read_filter[0] == NULL) + png_init_filter_functions(pp); + + pp->read_filter[filter-1](row_info, row, prev_row); + } +} + +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED +void /* PRIVATE */ +png_read_IDAT_data(png_structrp png_ptr, png_bytep output, + png_alloc_size_t avail_out) +{ + /* Loop reading IDATs and decompressing the result into output[avail_out] */ + png_ptr->zstream.next_out = output; + png_ptr->zstream.avail_out = 0; /* safety: set below */ + + if (output == NULL) + avail_out = 0; + + do + { + int ret; + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; + + if (png_ptr->zstream.avail_in == 0) + { + uInt avail_in; + png_bytep buffer; + + while (png_ptr->idat_size == 0) + { + png_crc_finish(png_ptr, 0); + + png_ptr->idat_size = png_read_chunk_header(png_ptr); + /* This is an error even in the 'check' case because the code just + * consumed a non-IDAT header. + */ + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); + } + + avail_in = png_ptr->IDAT_read_size; + + if (avail_in > png_chunk_max(png_ptr)) + avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr); + + if (avail_in > png_ptr->idat_size) + avail_in = (uInt)png_ptr->idat_size; + + /* A PNG with a gradually increasing IDAT size will defeat this attempt + * to minimize memory usage by causing lots of re-allocs, but + * realistically doing IDAT_read_size re-allocs is not likely to be a + * big problem. + * + * An error here corresponds to the system being out of memory. + */ + buffer = png_read_buffer(png_ptr, avail_in); + + if (buffer == NULL) + png_chunk_error(png_ptr, "out of memory"); + + png_crc_read(png_ptr, buffer, avail_in); + png_ptr->idat_size -= avail_in; + + png_ptr->zstream.next_in = buffer; + png_ptr->zstream.avail_in = avail_in; + } + + /* And set up the output side. */ + if (output != NULL) /* standard read */ + { + uInt out = ZLIB_IO_MAX; + + if (out > avail_out) + out = (uInt)avail_out; + + avail_out -= out; + png_ptr->zstream.avail_out = out; + } + + else /* after last row, checking for end */ + { + png_ptr->zstream.next_out = tmpbuf; + png_ptr->zstream.avail_out = (sizeof tmpbuf); + } + + /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the + * process. If the LZ stream is truncated the sequential reader will + * terminally damage the stream, above, by reading the chunk header of the + * following chunk (it then exits with png_error). + * + * TODO: deal more elegantly with truncated IDAT lists. + */ + ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH); + + /* Take the unconsumed output back. */ + if (output != NULL) + avail_out += png_ptr->zstream.avail_out; + + else /* avail_out counts the extra bytes */ + avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; + + png_ptr->zstream.avail_out = 0; + + if (ret == Z_STREAM_END) + { + /* Do this for safety; we won't read any more into this row. */ + png_ptr->zstream.next_out = NULL; + + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + + if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) + png_chunk_benign_error(png_ptr, "Extra compressed data"); + break; + } + + if (ret != Z_OK) + { + png_zstream_error(png_ptr, ret); + + if (output != NULL) + png_chunk_error(png_ptr, png_ptr->zstream.msg); + + else /* checking */ + { + png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); + return; + } + } + } while (avail_out > 0); + + if (avail_out > 0) + { + /* The stream ended before the image; this is the same as too few IDATs so + * should be handled the same way. + */ + if (output != NULL) + png_error(png_ptr, "Not enough image data"); + + else /* the deflate stream contained extra data */ + png_chunk_benign_error(png_ptr, "Too much image data"); + } +} + +void /* PRIVATE */ +png_read_finish_IDAT(png_structrp png_ptr) +{ + /* We don't need any more data and the stream should have ended, however the + * LZ end code may actually not have been processed. In this case we must + * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk + * may still remain to be consumed. + */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + { + /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in + * the compressed stream, but the stream may be damaged too, so even after + * this call we may need to terminate the zstream ownership. + */ + png_read_IDAT_data(png_ptr, NULL, 0); + png_ptr->zstream.next_out = NULL; /* safety */ + + /* Now clear everything out for safety; the following may not have been + * done. + */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) + { + png_ptr->mode |= PNG_AFTER_IDAT; + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; + } + } + + /* If the zstream has not been released do it now *and* terminate the reading + * of the final IDAT chunk. + */ + if (png_ptr->zowner == png_IDAT) + { + /* Always do this; the pointers otherwise point into the read buffer. */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + + /* Now we no longer own the zstream. */ + png_ptr->zowner = 0; + + /* The slightly weird semantics of the sequential IDAT reading is that we + * are always in or at the end of an IDAT chunk, so we always need to do a + * crc_finish here. If idat_size is non-zero we also need to read the + * spurious bytes at the end of the chunk now. + */ + (void)png_crc_finish(png_ptr, png_ptr->idat_size); + } +} + +void /* PRIVATE */ +png_read_finish_row(png_structrp png_ptr) +{ + png_debug(1, "in png_read_finish_row"); + png_ptr->row_number++; + if (png_ptr->row_number < png_ptr->num_rows) + return; + + if (png_ptr->interlaced != 0) + { + png_ptr->row_number = 0; + + /* TO DO: don't do this if prev_row isn't needed (requires + * read-ahead of the next row's filter byte. + */ + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + do + { + png_ptr->pass++; + + if (png_ptr->pass >= 7) + break; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + if ((png_ptr->transformations & PNG_INTERLACE) == 0) + { + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + } + + else /* if (png_ptr->transformations & PNG_INTERLACE) */ + break; /* libpng deinterlacing sees every row */ + + } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); + + if (png_ptr->pass < 7) + return; + } + + /* Here after at the end of the last row of the last pass. */ + png_read_finish_IDAT(png_ptr); +} +#endif /* SEQUENTIAL_READ */ + +void /* PRIVATE */ +png_read_start_row(png_structrp png_ptr) +{ + unsigned int max_pixel_depth; + size_t row_bytes; + + png_debug(1, "in png_read_start_row"); + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED + png_init_read_transformations(png_ptr); +#endif + if (png_ptr->interlaced != 0) + { + if ((png_ptr->transformations & PNG_INTERLACE) == 0) + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + + else + png_ptr->num_rows = png_ptr->height; + + png_ptr->iwidth = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + } + + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->iwidth = png_ptr->width; + } + + max_pixel_depth = (unsigned int)png_ptr->pixel_depth; + + /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of + * calculations to calculate the final pixel depth, then + * png_do_read_transforms actually does the transforms. This means that the + * code which effectively calculates this value is actually repeated in three + * separate places. They must all match. Innocent changes to the order of + * transformations can and will break libpng in a way that causes memory + * overwrites. + * + * TODO: fix this. + */ +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8) + max_pixel_depth = 8; +#endif + +#ifdef PNG_READ_EXPAND_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (png_ptr->num_trans != 0) + max_pixel_depth = 32; + + else + max_pixel_depth = 24; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth < 8) + max_pixel_depth = 8; + + if (png_ptr->num_trans != 0) + max_pixel_depth *= 2; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) + { + if (png_ptr->num_trans != 0) + { + max_pixel_depth *= 4; + max_pixel_depth /= 3; + } + } + } +#endif + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND_16) != 0) + { +# ifdef PNG_READ_EXPAND_SUPPORTED + /* In fact it is an error if it isn't supported, but checking is + * the safe way. + */ + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (png_ptr->bit_depth < 16) + max_pixel_depth *= 2; + } + else +# endif + png_ptr->transformations &= ~PNG_EXPAND_16; + } +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if ((png_ptr->transformations & (PNG_FILLER)) != 0) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) + { + if (max_pixel_depth <= 8) + max_pixel_depth = 16; + + else + max_pixel_depth = 32; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || + png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + if (max_pixel_depth <= 32) + max_pixel_depth = 32; + + else + max_pixel_depth = 64; + } + } +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) + { + if ( +#ifdef PNG_READ_EXPAND_SUPPORTED + (png_ptr->num_trans != 0 && + (png_ptr->transformations & PNG_EXPAND) != 0) || +#endif +#ifdef PNG_READ_FILLER_SUPPORTED + (png_ptr->transformations & (PNG_FILLER)) != 0 || +#endif + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (max_pixel_depth <= 16) + max_pixel_depth = 32; + + else + max_pixel_depth = 64; + } + + else + { + if (max_pixel_depth <= 8) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 32; + + else + max_pixel_depth = 24; + } + + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + max_pixel_depth = 64; + + else + max_pixel_depth = 48; + } + } +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { + unsigned int user_pixel_depth = png_ptr->user_transform_depth * + png_ptr->user_transform_channels; + + if (user_pixel_depth > max_pixel_depth) + max_pixel_depth = user_pixel_depth; + } +#endif + + /* This value is stored in png_struct and double checked in the row read + * code. + */ + png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; + png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ + + /* Align the width on the next larger 8 pixels. Mainly used + * for interlacing + */ + row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); + /* Calculate the maximum bytes needed, adding a byte and a pixel + * for safety's sake + */ + row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + + 1 + ((max_pixel_depth + 7) >> 3U); + +#ifdef PNG_MAX_MALLOC_64K + if (row_bytes > (png_uint_32)65536L) + png_error(png_ptr, "This image requires a row greater than 64KB"); +#endif + + if (row_bytes + 48 > png_ptr->old_big_row_buf_size) + { + png_free(png_ptr, png_ptr->big_row_buf); + png_free(png_ptr, png_ptr->big_prev_row); + + if (png_ptr->interlaced != 0) + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, + row_bytes + 48); + + else + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + + png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED + /* Use 16-byte aligned memory for row_buf with at least 16 bytes + * of padding before and after row_buf; treat prev_row similarly. + * NOTE: the alignment is to the start of the pixels, one beyond the start + * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this + * was incorrect; the filter byte was aligned, which had the exact + * opposite effect of that intended. + */ + { + png_bytep temp = png_ptr->big_row_buf + 32; + size_t extra = (size_t)temp & 0x0f; + png_ptr->row_buf = temp - extra - 1/*filter byte*/; + + temp = png_ptr->big_prev_row + 32; + extra = (size_t)temp & 0x0f; + png_ptr->prev_row = temp - extra - 1/*filter byte*/; + } +#else + /* Use 31 bytes of padding before and 17 bytes after row_buf. */ + png_ptr->row_buf = png_ptr->big_row_buf + 31; + png_ptr->prev_row = png_ptr->big_prev_row + 31; +#endif + png_ptr->old_big_row_buf_size = row_bytes + 48; + } + +#ifdef PNG_MAX_MALLOC_64K + if (png_ptr->rowbytes > 65535) + png_error(png_ptr, "This image requires a row greater than 64KB"); + +#endif + if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) + png_error(png_ptr, "Row has too many bytes to allocate in memory"); + + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + + png_debug1(3, "width = %u,", png_ptr->width); + png_debug1(3, "height = %u,", png_ptr->height); + png_debug1(3, "iwidth = %u,", png_ptr->iwidth); + png_debug1(3, "num_rows = %u,", png_ptr->num_rows); + png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); + png_debug1(3, "irowbytes = %lu", + (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); + + /* The sequential reader needs a buffer for IDAT, but the progressive reader + * does not, so free the read buffer now regardless; the sequential reader + * reallocates it on demand. + */ + if (png_ptr->read_buffer != NULL) + { + png_bytep buffer = png_ptr->read_buffer; + + png_ptr->read_buffer_size = 0; + png_ptr->read_buffer = NULL; + png_free(png_ptr, buffer); + } + + /* Finally claim the zstream for the inflate of the IDAT data, use the bits + * value from the stream (note that this will result in a fatal error if the + * IDAT stream has a bogus deflate header window_bits value, but this should + * not be happening any longer!) + */ + if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + png_ptr->flags |= PNG_FLAG_ROW_INIT; +} +#endif /* READ */ diff --git a/thirdparty/libpng/upstream/pngset.c b/thirdparty/libpng/upstream/pngset.c index 372b9f501..513c51eb4 100644 --- a/thirdparty/libpng/upstream/pngset.c +++ b/thirdparty/libpng/upstream/pngset.c @@ -1,1803 +1,2055 @@ - -/* pngset.c - storage of image information into info struct - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * The functions here are used during reads to store data from the file - * into the info struct, and during writes to store application data - * into the info struct for writing into the file. This abstracts the - * info struct and allows us to change the structure in the future. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#ifdef PNG_bKGD_SUPPORTED -void PNGAPI -png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_16p background) -{ - png_debug1(1, "in %s storage function", "bKGD"); - - if (png_ptr == NULL || info_ptr == NULL || background == NULL) - return; - - info_ptr->background = *background; - info_ptr->valid |= PNG_INFO_bKGD; -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -void PNGFAPI -png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) -{ - png_xy xy; - - png_debug1(1, "in %s storage function", "cHRM fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - xy.redx = red_x; - xy.redy = red_y; - xy.greenx = green_x; - xy.greeny = green_y; - xy.bluex = blue_x; - xy.bluey = blue_y; - xy.whitex = white_x; - xy.whitey = white_y; - - if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, - 2/* override with app values*/) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - - png_colorspace_sync_info(png_ptr, info_ptr); -} - -void PNGFAPI -png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z) -{ - png_XYZ XYZ; - - png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - XYZ.red_X = int_red_X; - XYZ.red_Y = int_red_Y; - XYZ.red_Z = int_red_Z; - XYZ.green_X = int_green_X; - XYZ.green_Y = int_green_Y; - XYZ.green_Z = int_green_Z; - XYZ.blue_X = int_blue_X; - XYZ.blue_Y = int_blue_Y; - XYZ.blue_Z = int_blue_Z; - - if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, - &XYZ, 2) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - - png_colorspace_sync_info(png_ptr, info_ptr); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, - double green_x, double green_y, double blue_x, double blue_y) -{ - png_set_cHRM_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, white_x, "cHRM White X"), - png_fixed(png_ptr, white_y, "cHRM White Y"), - png_fixed(png_ptr, red_x, "cHRM Red X"), - png_fixed(png_ptr, red_y, "cHRM Red Y"), - png_fixed(png_ptr, green_x, "cHRM Green X"), - png_fixed(png_ptr, green_y, "cHRM Green Y"), - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); -} - -void PNGAPI -png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, - double red_Y, double red_Z, double green_X, double green_Y, double green_Z, - double blue_X, double blue_Y, double blue_Z) -{ - png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, red_X, "cHRM Red X"), - png_fixed(png_ptr, red_Y, "cHRM Red Y"), - png_fixed(png_ptr, red_Z, "cHRM Red Z"), - png_fixed(png_ptr, green_X, "cHRM Green X"), - png_fixed(png_ptr, green_Y, "cHRM Green Y"), - png_fixed(png_ptr, green_Z, "cHRM Green Z"), - png_fixed(png_ptr, blue_X, "cHRM Blue X"), - png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), - png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); -} -# endif /* FLOATING_POINT */ - -#endif /* cHRM */ - -#ifdef PNG_eXIf_SUPPORTED -void PNGAPI -png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep exif) -{ - png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); - PNG_UNUSED(info_ptr) - PNG_UNUSED(exif) -} - -void PNGAPI -png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 num_exif, png_bytep exif) -{ - png_bytep new_exif; - - png_debug1(1, "in %s storage function", "eXIf"); - - if (png_ptr == NULL || info_ptr == NULL || - (png_ptr->mode & PNG_WROTE_eXIf) != 0) - return; - - new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif)); - - if (new_exif == NULL) - { - png_warning(png_ptr, "Insufficient memory for eXIf chunk data"); - return; - } - - memcpy(new_exif, exif, (size_t)num_exif); - - png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0); - - info_ptr->num_exif = num_exif; - info_ptr->exif = new_exif; - info_ptr->free_me |= PNG_FREE_EXIF; - info_ptr->valid |= PNG_INFO_eXIf; -} -#endif /* eXIf */ - -#ifdef PNG_gAMA_SUPPORTED -void PNGFAPI -png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point file_gamma) -{ - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); - png_colorspace_sync_info(png_ptr, info_ptr); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) -{ - png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, - "png_set_gAMA")); -} -# endif -#endif - -#ifdef PNG_hIST_SUPPORTED -void PNGAPI -png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_uint_16p hist) -{ - int i; - - png_debug1(1, "in %s storage function", "hIST"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->num_palette == 0 || info_ptr->num_palette - > PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, - "Invalid palette size, hIST allocation skipped"); - - return; - } - - png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); - - /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in - * version 1.2.1 - */ - info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, - PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); - - if (info_ptr->hist == NULL) - { - png_warning(png_ptr, "Insufficient memory for hIST chunk data"); - return; - } - - for (i = 0; i < info_ptr->num_palette; i++) - info_ptr->hist[i] = hist[i]; - - info_ptr->free_me |= PNG_FREE_HIST; - info_ptr->valid |= PNG_INFO_hIST; -} -#endif - -void PNGAPI -png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - png_debug1(1, "in %s storage function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->width = width; - info_ptr->height = height; - info_ptr->bit_depth = (png_byte)bit_depth; - info_ptr->color_type = (png_byte)color_type; - info_ptr->compression_type = (png_byte)compression_type; - info_ptr->filter_type = (png_byte)filter_type; - info_ptr->interlace_type = (png_byte)interlace_type; - - png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - - else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - - if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - info_ptr->channels++; - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); - - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); -} - -#ifdef PNG_oFFs_SUPPORTED -void PNGAPI -png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, - png_int_32 offset_x, png_int_32 offset_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "oFFs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_offset = offset_x; - info_ptr->y_offset = offset_y; - info_ptr->offset_unit_type = (png_byte)unit_type; - info_ptr->valid |= PNG_INFO_oFFs; -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -void PNGAPI -png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, - int nparams, png_const_charp units, png_charpp params) -{ - size_t length; - int i; - - png_debug1(1, "in %s storage function", "pCAL"); - - if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL - || (nparams > 0 && params == NULL)) - return; - - length = strlen(purpose) + 1; - png_debug1(3, "allocating purpose for info (%lu bytes)", - (unsigned long)length); - - /* TODO: validate format of calibration name and unit name */ - - /* Check that the type matches the specification. */ - if (type < 0 || type > 3) - { - png_chunk_report(png_ptr, "Invalid pCAL equation type", - PNG_CHUNK_WRITE_ERROR); - return; - } - - if (nparams < 0 || nparams > 255) - { - png_chunk_report(png_ptr, "Invalid pCAL parameter count", - PNG_CHUNK_WRITE_ERROR); - return; - } - - /* Validate params[nparams] */ - for (i=0; ipcal_purpose = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_purpose == NULL) - { - png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose", - PNG_CHUNK_WRITE_ERROR); - return; - } - - memcpy(info_ptr->pcal_purpose, purpose, length); - - info_ptr->free_me |= PNG_FREE_PCAL; - - png_debug(3, "storing X0, X1, type, and nparams in info"); - info_ptr->pcal_X0 = X0; - info_ptr->pcal_X1 = X1; - info_ptr->pcal_type = (png_byte)type; - info_ptr->pcal_nparams = (png_byte)nparams; - - length = strlen(units) + 1; - png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); - - info_ptr->pcal_units = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_units == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL units"); - return; - } - - memcpy(info_ptr->pcal_units, units, length); - - info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); - - if (info_ptr->pcal_params == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL params"); - return; - } - - memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) * - (sizeof (png_charp))); - - for (i = 0; i < nparams; i++) - { - length = strlen(params[i]) + 1; - png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, - (unsigned long)length); - - info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); - - if (info_ptr->pcal_params[i] == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL parameter"); - return; - } - - memcpy(info_ptr->pcal_params[i], params[i], length); - } - - info_ptr->valid |= PNG_INFO_pCAL; -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -void PNGAPI -png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, - int unit, png_const_charp swidth, png_const_charp sheight) -{ - size_t lengthw = 0, lengthh = 0; - - png_debug1(1, "in %s storage function", "sCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Double check the unit (should never get here with an invalid - * unit unless this is an API call.) - */ - if (unit != 1 && unit != 2) - png_error(png_ptr, "Invalid sCAL unit"); - - if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || - swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) - png_error(png_ptr, "Invalid sCAL width"); - - if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || - sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) - png_error(png_ptr, "Invalid sCAL height"); - - info_ptr->scal_unit = (png_byte)unit; - - ++lengthw; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); - - info_ptr->scal_s_width = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthw)); - - if (info_ptr->scal_s_width == NULL) - { - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - - return; - } - - memcpy(info_ptr->scal_s_width, swidth, lengthw); - - ++lengthh; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); - - info_ptr->scal_s_height = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthh)); - - if (info_ptr->scal_s_height == NULL) - { - png_free(png_ptr, info_ptr->scal_s_width); - info_ptr->scal_s_width = NULL; - - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - return; - } - - memcpy(info_ptr->scal_s_height, sheight, lengthh); - - info_ptr->free_me |= PNG_FREE_SCAL; - info_ptr->valid |= PNG_INFO_sCAL; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - double width, double height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, - PNG_sCAL_PRECISION); - png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, - PNG_sCAL_PRECISION); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - png_fixed_point width, png_fixed_point height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); - png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif -#endif - -#ifdef PNG_pHYs_SUPPORTED -void PNGAPI -png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "pHYs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_pixels_per_unit = res_x; - info_ptr->y_pixels_per_unit = res_y; - info_ptr->phys_unit_type = (png_byte)unit_type; - info_ptr->valid |= PNG_INFO_pHYs; -} -#endif - -void PNGAPI -png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, - png_const_colorp palette, int num_palette) -{ - - png_uint_32 max_palette_length; - - png_debug1(1, "in %s storage function", "PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? - (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; - - if (num_palette < 0 || num_palette > (int) max_palette_length) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Invalid palette length"); - - else - { - png_warning(png_ptr, "Invalid palette length"); - - return; - } - } - - if ((num_palette > 0 && palette == NULL) || - (num_palette == 0 -# ifdef PNG_MNG_FEATURES_SUPPORTED - && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 -# endif - )) - { - png_error(png_ptr, "Invalid palette"); - } - - /* It may not actually be necessary to set png_ptr->palette here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - * - * 1.6.0: the above statement appears to be incorrect; something has to set - * the palette inside png_struct on read. - */ - png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); - - /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead - * of num_palette entries, in case of an invalid PNG file or incorrect - * call to png_set_PLTE() with too-large sample values. - */ - png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, - PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); - - if (num_palette > 0) - memcpy(png_ptr->palette, palette, (unsigned int)num_palette * - (sizeof (png_color))); - - info_ptr->palette = png_ptr->palette; - info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; - info_ptr->free_me |= PNG_FREE_PLTE; - info_ptr->valid |= PNG_INFO_PLTE; -} - -#ifdef PNG_sBIT_SUPPORTED -void PNGAPI -png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_8p sig_bit) -{ - png_debug1(1, "in %s storage function", "sBIT"); - - if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) - return; - - info_ptr->sig_bit = *sig_bit; - info_ptr->valid |= PNG_INFO_sBIT; -} -#endif - -#ifdef PNG_sRGB_SUPPORTED -void PNGAPI -png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); - png_colorspace_sync_info(png_ptr, info_ptr); -} - -void PNGAPI -png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, - srgb_intent) != 0) - { - /* This causes the gAMA and cHRM to be written too */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif /* sRGB */ - - -#ifdef PNG_iCCP_SUPPORTED -void PNGAPI -png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen) -{ - png_charp new_iccp_name; - png_bytep new_iccp_profile; - size_t length; - - png_debug1(1, "in %s storage function", "iCCP"); - - if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) - return; - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - png_app_error(png_ptr, "Invalid iCCP compression method"); - - /* Set the colorspace first because this validates the profile; do not - * override previously set app cHRM or gAMA here (because likely as not the - * application knows better than libpng what the correct values are.) Pass - * the info_ptr color_type field to png_colorspace_set_ICC because in the - * write case it has not yet been stored in png_ptr. - */ - { - int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, - proflen, profile, info_ptr->color_type); - - png_colorspace_sync_info(png_ptr, info_ptr); - - /* Don't do any of the copying if the profile was bad, or inconsistent. */ - if (result == 0) - return; - - /* But do write the gAMA and cHRM chunks from the profile. */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - - length = strlen(name)+1; - new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); - - if (new_iccp_name == NULL) - { - png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); - - return; - } - - memcpy(new_iccp_name, name, length); - new_iccp_profile = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, proflen)); - - if (new_iccp_profile == NULL) - { - png_free(png_ptr, new_iccp_name); - png_benign_error(png_ptr, - "Insufficient memory to process iCCP profile"); - - return; - } - - memcpy(new_iccp_profile, profile, proflen); - - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); - - info_ptr->iccp_proflen = proflen; - info_ptr->iccp_name = new_iccp_name; - info_ptr->iccp_profile = new_iccp_profile; - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -void PNGAPI -png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) -{ - int ret; - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); - - if (ret != 0) - png_error(png_ptr, "Insufficient memory to store text"); -} - -int /* PRIVATE */ -png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) -{ - int i; - - png_debug1(1, "in text storage function, chunk typeid = 0x%lx", - png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name); - - if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return 0; - - /* Make sure we have enough space in the "text" array in info_struct - * to hold all of the incoming text_ptr objects. This compare can't overflow - * because max_text >= num_text (anyway, subtract of two positive integers - * can't overflow in any case.) - */ - if (num_text > info_ptr->max_text - info_ptr->num_text) - { - int old_num_text = info_ptr->num_text; - int max_text; - png_textp new_text = NULL; - - /* Calculate an appropriate max_text, checking for overflow. */ - max_text = old_num_text; - if (num_text <= INT_MAX - max_text) - { - max_text += num_text; - - /* Round up to a multiple of 8 */ - if (max_text < INT_MAX-8) - max_text = (max_text + 8) & ~0x7; - - else - max_text = INT_MAX; - - /* Now allocate a new array and copy the old members in; this does all - * the overflow checks. - */ - new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, - info_ptr->text, old_num_text, max_text-old_num_text, - sizeof *new_text)); - } - - if (new_text == NULL) - { - png_chunk_report(png_ptr, "too many text chunks", - PNG_CHUNK_WRITE_ERROR); - - return 1; - } - - png_free(png_ptr, info_ptr->text); - - info_ptr->text = new_text; - info_ptr->free_me |= PNG_FREE_TEXT; - info_ptr->max_text = max_text; - /* num_text is adjusted below as the entries are copied in */ - - png_debug1(3, "allocated %d entries for info_ptr->text", max_text); - } - - for (i = 0; i < num_text; i++) - { - size_t text_length, key_len; - size_t lang_len, lang_key_len; - png_textp textp = &(info_ptr->text[info_ptr->num_text]); - - if (text_ptr[i].key == NULL) - continue; - - if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || - text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) - { - png_chunk_report(png_ptr, "text compression mode is out of range", - PNG_CHUNK_WRITE_ERROR); - continue; - } - - key_len = strlen(text_ptr[i].key); - - if (text_ptr[i].compression <= 0) - { - lang_len = 0; - lang_key_len = 0; - } - - else -# ifdef PNG_iTXt_SUPPORTED - { - /* Set iTXt data */ - - if (text_ptr[i].lang != NULL) - lang_len = strlen(text_ptr[i].lang); - - else - lang_len = 0; - - if (text_ptr[i].lang_key != NULL) - lang_key_len = strlen(text_ptr[i].lang_key); - - else - lang_key_len = 0; - } -# else /* iTXt */ - { - png_chunk_report(png_ptr, "iTXt chunk not supported", - PNG_CHUNK_WRITE_ERROR); - continue; - } -# endif - - if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') - { - text_length = 0; -# ifdef PNG_iTXt_SUPPORTED - if (text_ptr[i].compression > 0) - textp->compression = PNG_ITXT_COMPRESSION_NONE; - - else -# endif - textp->compression = PNG_TEXT_COMPRESSION_NONE; - } - - else - { - text_length = strlen(text_ptr[i].text); - textp->compression = text_ptr[i].compression; - } - - textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, - key_len + text_length + lang_len + lang_key_len + 4)); - - if (textp->key == NULL) - { - png_chunk_report(png_ptr, "text chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); - - return 1; - } - - png_debug2(2, "Allocated %lu bytes at %p in png_set_text", - (unsigned long)(png_uint_32) - (key_len + lang_len + lang_key_len + text_length + 4), - textp->key); - - memcpy(textp->key, text_ptr[i].key, key_len); - *(textp->key + key_len) = '\0'; - - if (text_ptr[i].compression > 0) - { - textp->lang = textp->key + key_len + 1; - memcpy(textp->lang, text_ptr[i].lang, lang_len); - *(textp->lang + lang_len) = '\0'; - textp->lang_key = textp->lang + lang_len + 1; - memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); - *(textp->lang_key + lang_key_len) = '\0'; - textp->text = textp->lang_key + lang_key_len + 1; - } - - else - { - textp->lang=NULL; - textp->lang_key=NULL; - textp->text = textp->key + key_len + 1; - } - - if (text_length != 0) - memcpy(textp->text, text_ptr[i].text, text_length); - - *(textp->text + text_length) = '\0'; - -# ifdef PNG_iTXt_SUPPORTED - if (textp->compression > 0) - { - textp->text_length = 0; - textp->itxt_length = text_length; - } - - else -# endif - { - textp->text_length = text_length; - textp->itxt_length = 0; - } - - info_ptr->num_text++; - png_debug1(3, "transferred text chunk %d", info_ptr->num_text); - } - - return 0; -} -#endif - -#ifdef PNG_tIME_SUPPORTED -void PNGAPI -png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_timep mod_time) -{ - png_debug1(1, "in %s storage function", "tIME"); - - if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || - (png_ptr->mode & PNG_WROTE_tIME) != 0) - return; - - if (mod_time->month == 0 || mod_time->month > 12 || - mod_time->day == 0 || mod_time->day > 31 || - mod_time->hour > 23 || mod_time->minute > 59 || - mod_time->second > 60) - { - png_warning(png_ptr, "Ignoring invalid time value"); - - return; - } - - info_ptr->mod_time = *mod_time; - info_ptr->valid |= PNG_INFO_tIME; -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -void PNGAPI -png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, - png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) -{ - png_debug1(1, "in %s storage function", "tRNS"); - - if (png_ptr == NULL || info_ptr == NULL) - - return; - - if (trans_alpha != NULL) - { - /* It may not actually be necessary to set png_ptr->trans_alpha here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - * - * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively - * relies on png_set_tRNS storing the information in png_struct - * (otherwise it won't be there for the code in pngrtran.c). - */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) - { - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - info_ptr->trans_alpha = png_voidcast(png_bytep, - png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans); - - info_ptr->free_me |= PNG_FREE_TRNS; - info_ptr->valid |= PNG_INFO_tRNS; - } - png_ptr->trans_alpha = info_ptr->trans_alpha; - } - - if (trans_color != NULL) - { -#ifdef PNG_WARNINGS_SUPPORTED - if (info_ptr->bit_depth < 16) - { - int sample_max = (1 << info_ptr->bit_depth) - 1; - - if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && - trans_color->gray > sample_max) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - (trans_color->red > sample_max || - trans_color->green > sample_max || - trans_color->blue > sample_max))) - png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); - } -#endif - - info_ptr->trans_color = *trans_color; - - if (num_trans == 0) - num_trans = 1; - } - - info_ptr->num_trans = (png_uint_16)num_trans; - - if (num_trans != 0) - { - info_ptr->free_me |= PNG_FREE_TRNS; - info_ptr->valid |= PNG_INFO_tRNS; - } -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -void PNGAPI -png_set_sPLT(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) -/* - * entries - array of png_sPLT_t structures - * to be added to the list of palettes - * in the info structure. - * - * nentries - number of palette structures to be - * added. - */ -{ - png_sPLT_tp np; - - png_debug1(1, "in %s storage function", "sPLT"); - - if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) - return; - - /* Use the internal realloc function, which checks for all the possible - * overflows. Notice that the parameters are (int) and (size_t) - */ - np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, - info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, - sizeof *np)); - - if (np == NULL) - { - /* Out of memory or too many chunks */ - png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); - return; - } - - png_free(png_ptr, info_ptr->splt_palettes); - - info_ptr->splt_palettes = np; - info_ptr->free_me |= PNG_FREE_SPLT; - - np += info_ptr->splt_palettes_num; - - do - { - size_t length; - - /* Skip invalid input entries */ - if (entries->name == NULL || entries->entries == NULL) - { - /* png_handle_sPLT doesn't do this, so this is an app error */ - png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); - /* Just skip the invalid entry */ - continue; - } - - np->depth = entries->depth; - - /* In the event of out-of-memory just return - there's no point keeping - * on trying to add sPLT chunks. - */ - length = strlen(entries->name) + 1; - np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); - - if (np->name == NULL) - break; - - memcpy(np->name, entries->name, length); - - /* IMPORTANT: we have memory now that won't get freed if something else - * goes wrong; this code must free it. png_malloc_array produces no - * warnings; use a png_chunk_report (below) if there is an error. - */ - np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, - entries->nentries, sizeof (png_sPLT_entry))); - - if (np->entries == NULL) - { - png_free(png_ptr, np->name); - np->name = NULL; - break; - } - - np->nentries = entries->nentries; - /* This multiply can't overflow because png_malloc_array has already - * checked it when doing the allocation. - */ - memcpy(np->entries, entries->entries, - (unsigned int)entries->nentries * sizeof (png_sPLT_entry)); - - /* Note that 'continue' skips the advance of the out pointer and out - * count, so an invalid entry is not added. - */ - info_ptr->valid |= PNG_INFO_sPLT; - ++(info_ptr->splt_palettes_num); - ++np; - ++entries; - } - while (--nentries); - - if (nentries > 0) - png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); -} -#endif /* sPLT */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -static png_byte -check_location(png_const_structrp png_ptr, int location) -{ - location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); - - /* New in 1.6.0; copy the location and check it. This is an API - * change; previously the app had to use the - * png_set_unknown_chunk_location API below for each chunk. - */ - if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0) - { - /* Write struct, so unknown chunks come from the app */ - png_app_warning(png_ptr, - "png_set_unknown_chunks now expects a valid location"); - /* Use the old behavior */ - location = (png_byte)(png_ptr->mode & - (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); - } - - /* This need not be an internal error - if the app calls - * png_set_unknown_chunks on a read pointer it must get the location right. - */ - if (location == 0) - png_error(png_ptr, "invalid location in png_set_unknown_chunks"); - - /* Now reduce the location to the top-most set bit by removing each least - * significant bit in turn. - */ - while (location != (location & -location)) - location &= ~(location & -location); - - /* The cast is safe because 'location' is a bit mask and only the low four - * bits are significant. - */ - return (png_byte)location; -} - -void PNGAPI -png_set_unknown_chunks(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) -{ - png_unknown_chunkp np; - - if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || - unknowns == NULL) - return; - - /* Check for the failure cases where support has been disabled at compile - * time. This code is hardly ever compiled - it's here because - * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this - * code) but may be meaningless if the read or write handling of unknown - * chunks is not compiled in. - */ -# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ - defined(PNG_READ_SUPPORTED) - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { - png_app_error(png_ptr, "no unknown chunk support on read"); - - return; - } -# endif -# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ - defined(PNG_WRITE_SUPPORTED) - if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) - { - png_app_error(png_ptr, "no unknown chunk support on write"); - - return; - } -# endif - - /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that - * unknown critical chunks could be lost with just a warning resulting in - * undefined behavior. Now png_chunk_report is used to provide behavior - * appropriate to read or write. - */ - np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, - info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, - sizeof *np)); - - if (np == NULL) - { - png_chunk_report(png_ptr, "too many unknown chunks", - PNG_CHUNK_WRITE_ERROR); - return; - } - - png_free(png_ptr, info_ptr->unknown_chunks); - - info_ptr->unknown_chunks = np; /* safe because it is initialized */ - info_ptr->free_me |= PNG_FREE_UNKN; - - np += info_ptr->unknown_chunks_num; - - /* Increment unknown_chunks_num each time round the loop to protect the - * just-allocated chunk data. - */ - for (; num_unknowns > 0; --num_unknowns, ++unknowns) - { - memcpy(np->name, unknowns->name, (sizeof np->name)); - np->name[(sizeof np->name)-1] = '\0'; - np->location = check_location(png_ptr, unknowns->location); - - if (unknowns->size == 0) - { - np->data = NULL; - np->size = 0; - } - - else - { - np->data = png_voidcast(png_bytep, - png_malloc_base(png_ptr, unknowns->size)); - - if (np->data == NULL) - { - png_chunk_report(png_ptr, "unknown chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); - /* But just skip storing the unknown chunk */ - continue; - } - - memcpy(np->data, unknowns->data, unknowns->size); - np->size = unknowns->size; - } - - /* These increments are skipped on out-of-memory for the data - the - * unknown chunk entry gets overwritten if the png_chunk_report returns. - * This is correct in the read case (the chunk is just dropped.) - */ - ++np; - ++(info_ptr->unknown_chunks_num); - } -} - -void PNGAPI -png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, - int chunk, int location) -{ - /* This API is pretty pointless in 1.6.0 because the location can be set - * before the call to png_set_unknown_chunks. - * - * TODO: add a png_app_warning in 1.7 - */ - if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && - chunk < info_ptr->unknown_chunks_num) - { - if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) - { - png_app_error(png_ptr, "invalid unknown chunk location"); - /* Fake out the pre 1.6.0 behavior: */ - if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */ - location = PNG_AFTER_IDAT; - - else - location = PNG_HAVE_IHDR; /* also undocumented */ - } - - info_ptr->unknown_chunks[chunk].location = - check_location(png_ptr, location); - } -} -#endif /* STORE_UNKNOWN_CHUNKS */ - -#ifdef PNG_MNG_FEATURES_SUPPORTED -png_uint_32 PNGAPI -png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features) -{ - png_debug(1, "in png_permit_mng_features"); - - if (png_ptr == NULL) - return 0; - - png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; - - return png_ptr->mng_features_permitted; -} -#endif - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -static unsigned int -add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) -{ - unsigned int i; - - /* Utility function: update the 'keep' state of a chunk if it is already in - * the list, otherwise add it to the list. - */ - for (i=0; i= PNG_HANDLE_CHUNK_LAST) - { - png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); - - return; - } - - if (num_chunks_in <= 0) - { - png_ptr->unknown_default = keep; - - /* '0' means just set the flags, so stop here */ - if (num_chunks_in == 0) - return; - } - - if (num_chunks_in < 0) - { - /* Ignore all unknown chunks and all chunks recognized by - * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND - */ - static const png_byte chunks_to_ignore[] = { - 98, 75, 71, 68, '\0', /* bKGD */ - 99, 72, 82, 77, '\0', /* cHRM */ - 101, 88, 73, 102, '\0', /* eXIf */ - 103, 65, 77, 65, '\0', /* gAMA */ - 104, 73, 83, 84, '\0', /* hIST */ - 105, 67, 67, 80, '\0', /* iCCP */ - 105, 84, 88, 116, '\0', /* iTXt */ - 111, 70, 70, 115, '\0', /* oFFs */ - 112, 67, 65, 76, '\0', /* pCAL */ - 112, 72, 89, 115, '\0', /* pHYs */ - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 67, 65, 76, '\0', /* sCAL */ - 115, 80, 76, 84, '\0', /* sPLT */ - 115, 84, 69, 82, '\0', /* sTER */ - 115, 82, 71, 66, '\0', /* sRGB */ - 116, 69, 88, 116, '\0', /* tEXt */ - 116, 73, 77, 69, '\0', /* tIME */ - 122, 84, 88, 116, '\0' /* zTXt */ - }; - - chunk_list = chunks_to_ignore; - num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; - } - - else /* num_chunks_in > 0 */ - { - if (chunk_list == NULL) - { - /* Prior to 1.6.0 this was silently ignored, now it is an app_error - * which can be switched off. - */ - png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); - - return; - } - - num_chunks = (unsigned int)num_chunks_in; - } - - old_num_chunks = png_ptr->num_chunk_list; - if (png_ptr->chunk_list == NULL) - old_num_chunks = 0; - - /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. - */ - if (num_chunks + old_num_chunks > UINT_MAX/5) - { - png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); - - return; - } - - /* If these chunks are being reset to the default then no more memory is - * required because add_one_chunk above doesn't extend the list if the 'keep' - * parameter is the default. - */ - if (keep != 0) - { - new_list = png_voidcast(png_bytep, png_malloc(png_ptr, - 5 * (num_chunks + old_num_chunks))); - - if (old_num_chunks > 0) - memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); - } - - else if (old_num_chunks > 0) - new_list = png_ptr->chunk_list; - - else - new_list = NULL; - - /* Add the new chunks together with each one's handling code. If the chunk - * already exists the code is updated, otherwise the chunk is added to the - * end. (In libpng 1.6.0 order no longer matters because this code enforces - * the earlier convention that the last setting is the one that is used.) - */ - if (new_list != NULL) - { - png_const_bytep inlist; - png_bytep outlist; - unsigned int i; - - for (i=0; ichunk_list != new_list) - png_free(png_ptr, new_list); - - new_list = NULL; - } - } - - else - num_chunks = 0; - - png_ptr->num_chunk_list = num_chunks; - - if (png_ptr->chunk_list != new_list) - { - if (png_ptr->chunk_list != NULL) - png_free(png_ptr, png_ptr->chunk_list); - - png_ptr->chunk_list = new_list; - } -} -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -void PNGAPI -png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, - png_user_chunk_ptr read_user_chunk_fn) -{ - png_debug(1, "in png_set_read_user_chunk_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->read_user_chunk_fn = read_user_chunk_fn; - png_ptr->user_chunk_ptr = user_chunk_ptr; -} -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytepp row_pointers) -{ - png_debug(1, "in png_set_rows"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->row_pointers != NULL && - (info_ptr->row_pointers != row_pointers)) - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - - info_ptr->row_pointers = row_pointers; - - if (row_pointers != NULL) - info_ptr->valid |= PNG_INFO_IDAT; -} -#endif - -void PNGAPI -png_set_compression_buffer_size(png_structrp png_ptr, size_t size) -{ - png_debug(1, "in png_set_compression_buffer_size"); - - if (png_ptr == NULL) - return; - - if (size == 0 || size > PNG_UINT_31_MAX) - png_error(png_ptr, "invalid compression buffer size"); - -# ifdef PNG_SEQUENTIAL_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { - png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ - return; - } -# endif - -# ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) - { - if (png_ptr->zowner != 0) - { - png_warning(png_ptr, - "Compression buffer size cannot be changed because it is in use"); - - return; - } - -#ifndef __COVERITY__ - /* Some compilers complain that this is always false. However, it - * can be true when integer overflow happens. - */ - if (size > ZLIB_IO_MAX) - { - png_warning(png_ptr, - "Compression buffer size limited to system maximum"); - size = ZLIB_IO_MAX; /* must fit */ - } -#endif - - if (size < 6) - { - /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH - * if this is permitted. - */ - png_warning(png_ptr, - "Compression buffer size cannot be reduced below 6"); - - return; - } - - if (png_ptr->zbuffer_size != size) - { - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_ptr->zbuffer_size = (uInt)size; - } - } -# endif -} - -void PNGAPI -png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) -{ - if (png_ptr != NULL && info_ptr != NULL) - info_ptr->valid &= (unsigned int)(~mask); -} - - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* This function was added to libpng 1.2.6 */ -void PNGAPI -png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, - png_uint_32 user_height_max) -{ - png_debug(1, "in png_set_user_limits"); - - /* Images with dimensions larger than these limits will be - * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7fffffff. - */ - if (png_ptr == NULL) - return; - - png_ptr->user_width_max = user_width_max; - png_ptr->user_height_max = user_height_max; -} - -/* This function was added to libpng 1.4.0 */ -void PNGAPI -png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max) -{ - png_debug(1, "in png_set_chunk_cache_max"); - - if (png_ptr != NULL) - png_ptr->user_chunk_cache_max = user_chunk_cache_max; -} - -/* This function was added to libpng 1.4.1 */ -void PNGAPI -png_set_chunk_malloc_max(png_structrp png_ptr, - png_alloc_size_t user_chunk_malloc_max) -{ - png_debug(1, "in png_set_chunk_malloc_max"); - - if (png_ptr != NULL) - png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; -} -#endif /* ?SET_USER_LIMITS */ - - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_set_benign_errors(png_structrp png_ptr, int allowed) -{ - png_debug(1, "in png_set_benign_errors"); - - /* If allowed is 1, png_benign_error() is treated as a warning. - * - * If allowed is 0, png_benign_error() is treated as an error (which - * is the default behavior if png_set_benign_errors() is not called). - */ - - if (allowed != 0) - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | - PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; - - else - png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | - PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); -} -#endif /* BENIGN_ERRORS */ - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Whether to report invalid palette index; added at libng-1.5.10. - * It is possible for an indexed (color-type==3) PNG file to contain - * pixels with invalid (out-of-range) indexes if the PLTE chunk has - * fewer entries than the image's bit-depth would allow. We recover - * from this gracefully by filling any incomplete palette with zeros - * (opaque black). By default, when this occurs libpng will issue - * a benign error. This API can be used to override that behavior. - */ -void PNGAPI -png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) -{ - png_debug(1, "in png_set_check_for_invalid_index"); - - if (allowed > 0) - png_ptr->num_palette_max = 0; - - else - png_ptr->num_palette_max = -1; -} -#endif - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \ - defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) -/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, - * and if invalid, correct the keyword rather than discarding the entire - * chunk. The PNG 1.0 specification requires keywords 1-79 characters in - * length, forbids leading or trailing whitespace, multiple internal spaces, - * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. - * - * The 'new_key' buffer must be 80 characters in size (for the keyword plus a - * trailing '\0'). If this routine returns 0 then there was no keyword, or a - * valid one could not be generated, and the caller must png_error. - */ -png_uint_32 /* PRIVATE */ -png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) -{ -#ifdef PNG_WARNINGS_SUPPORTED - png_const_charp orig_key = key; -#endif - png_uint_32 key_len = 0; - int bad_character = 0; - int space = 1; - - png_debug(1, "in png_check_keyword"); - - if (key == NULL) - { - *new_key = 0; - return 0; - } - - while (*key && key_len < 79) - { - png_byte ch = (png_byte)*key++; - - if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) - { - *new_key++ = ch; ++key_len; space = 0; - } - - else if (space == 0) - { - /* A space or an invalid character when one wasn't seen immediately - * before; output just a space. - */ - *new_key++ = 32; ++key_len; space = 1; - - /* If the character was not a space then it is invalid. */ - if (ch != 32) - bad_character = ch; - } - - else if (bad_character == 0) - bad_character = ch; /* just skip it, record the first error */ - } - - if (key_len > 0 && space != 0) /* trailing space */ - { - --key_len; --new_key; - if (bad_character == 0) - bad_character = 32; - } - - /* Terminate the keyword */ - *new_key = 0; - - if (key_len == 0) - return 0; - -#ifdef PNG_WARNINGS_SUPPORTED - /* Try to only output one warning per keyword: */ - if (*key != 0) /* keyword too long */ - png_warning(png_ptr, "keyword truncated"); - - else if (bad_character != 0) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter(p, 1, orig_key); - png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); - - png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); - } -#else /* !WARNINGS */ - PNG_UNUSED(png_ptr) -#endif /* !WARNINGS */ - - return key_len; -} -#endif /* TEXT || pCAL || iCCP || sPLT */ -#endif /* READ || WRITE */ +/* pngset.c - storage of image information into info struct + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * The functions here are used during reads to store data from the file + * into the info struct, and during writes to store application data + * into the info struct for writing into the file. This abstracts the + * info struct and allows us to change the structure in the future. + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#ifdef PNG_bKGD_SUPPORTED +void PNGAPI +png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_16p background) +{ + png_debug1(1, "in %s storage function", "bKGD"); + + if (png_ptr == NULL || info_ptr == NULL || background == NULL) + return; + + info_ptr->background = *background; + info_ptr->valid |= PNG_INFO_bKGD; +} +#endif + +#ifdef PNG_cHRM_SUPPORTED +void PNGFAPI +png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) +{ + png_debug1(1, "in %s storage function", "cHRM fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->cHRM.redx = red_x; + info_ptr->cHRM.redy = red_y; + info_ptr->cHRM.greenx = green_x; + info_ptr->cHRM.greeny = green_y; + info_ptr->cHRM.bluex = blue_x; + info_ptr->cHRM.bluey = blue_y; + info_ptr->cHRM.whitex = white_x; + info_ptr->cHRM.whitey = white_y; + + info_ptr->valid |= PNG_INFO_cHRM; +} + +void PNGFAPI +png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point int_red_X, png_fixed_point int_red_Y, + png_fixed_point int_red_Z, png_fixed_point int_green_X, + png_fixed_point int_green_Y, png_fixed_point int_green_Z, + png_fixed_point int_blue_X, png_fixed_point int_blue_Y, + png_fixed_point int_blue_Z) +{ + png_XYZ XYZ; + png_xy xy; + + png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + XYZ.red_X = int_red_X; + XYZ.red_Y = int_red_Y; + XYZ.red_Z = int_red_Z; + XYZ.green_X = int_green_X; + XYZ.green_Y = int_green_Y; + XYZ.green_Z = int_green_Z; + XYZ.blue_X = int_blue_X; + XYZ.blue_Y = int_blue_Y; + XYZ.blue_Z = int_blue_Z; + + if (png_xy_from_XYZ(&xy, &XYZ) == 0) + { + info_ptr->cHRM = xy; + info_ptr->valid |= PNG_INFO_cHRM; + } + + else + png_app_error(png_ptr, "invalid cHRM XYZ"); +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, + double green_x, double green_y, double blue_x, double blue_y) +{ + png_set_cHRM_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); +} + +void PNGAPI +png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, + double red_Y, double red_Z, double green_X, double green_Y, double green_Z, + double blue_X, double blue_Y, double blue_Z) +{ + png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, red_X, "cHRM Red X"), + png_fixed(png_ptr, red_Y, "cHRM Red Y"), + png_fixed(png_ptr, red_Z, "cHRM Red Z"), + png_fixed(png_ptr, green_X, "cHRM Green X"), + png_fixed(png_ptr, green_Y, "cHRM Green Y"), + png_fixed(png_ptr, green_Z, "cHRM Green Z"), + png_fixed(png_ptr, blue_X, "cHRM Blue X"), + png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), + png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); +} +# endif /* FLOATING_POINT */ + +#endif /* cHRM */ + +#ifdef PNG_cICP_SUPPORTED +void PNGAPI +png_set_cICP(png_const_structrp png_ptr, png_inforp info_ptr, + png_byte colour_primaries, png_byte transfer_function, + png_byte matrix_coefficients, png_byte video_full_range_flag) +{ + png_debug1(1, "in %s storage function", "cICP"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->cicp_colour_primaries = colour_primaries; + info_ptr->cicp_transfer_function = transfer_function; + info_ptr->cicp_matrix_coefficients = matrix_coefficients; + info_ptr->cicp_video_full_range_flag = video_full_range_flag; + + if (info_ptr->cicp_matrix_coefficients != 0) + { + png_warning(png_ptr, "Invalid cICP matrix coefficients"); + return; + } + + info_ptr->valid |= PNG_INFO_cICP; +} +#endif /* cICP */ + +#ifdef PNG_cLLI_SUPPORTED +void PNGFAPI +png_set_cLLI_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + /* The values below are in cd/m2 (nits) and are scaled by 10,000; not + * 100,000 as in the case of png_fixed_point. + */ + png_uint_32 maxCLL, png_uint_32 maxFALL) +{ + png_debug1(1, "in %s storage function", "cLLI"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Check the light level range: */ + if (maxCLL > 0x7FFFFFFFU || maxFALL > 0x7FFFFFFFU) + { + /* The limit is 200kcd/m2; somewhat bright but not inconceivable because + * human vision is said to run up to 100Mcd/m2. The sun is about 2Gcd/m2. + * + * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is + * 2kcd/m2. + */ + png_chunk_report(png_ptr, "cLLI light level exceeds PNG limit", + PNG_CHUNK_WRITE_ERROR); + return; + } + + info_ptr->maxCLL = maxCLL; + info_ptr->maxFALL = maxFALL; + info_ptr->valid |= PNG_INFO_cLLI; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cLLI(png_const_structrp png_ptr, png_inforp info_ptr, + double maxCLL, double maxFALL) +{ + png_set_cLLI_fixed(png_ptr, info_ptr, + png_fixed_ITU(png_ptr, maxCLL, "png_set_cLLI(maxCLL)"), + png_fixed_ITU(png_ptr, maxFALL, "png_set_cLLI(maxFALL)")); +} +# endif /* FLOATING_POINT */ +#endif /* cLLI */ + +#ifdef PNG_mDCV_SUPPORTED +static png_uint_16 +png_ITU_fixed_16(int *error, png_fixed_point v) +{ + /* Return a safe uint16_t value scaled according to the ITU H273 rules for + * 16-bit display chromaticities. Functions like the corresponding + * png_fixed() internal function with regard to errors: it's an error on + * write, a chunk_benign_error on read: See the definition of + * png_chunk_report in pngpriv.h. + */ + v /= 2; /* rounds to 0 in C: avoids insignificant arithmetic errors */ + if (v > 65535 || v < 0) + { + *error = 1; + return 0; + } + + return (png_uint_16)/*SAFE*/v; +} + +void PNGAPI +png_set_mDCV_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point white_x, png_fixed_point white_y, + png_fixed_point red_x, png_fixed_point red_y, + png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y, + png_uint_32 maxDL, + png_uint_32 minDL) +{ + png_uint_16 rx, ry, gx, gy, bx, by, wx, wy; + int error; + + png_debug1(1, "in %s storage function", "mDCV"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Check the input values to ensure they are in the expected range: */ + error = 0; + rx = png_ITU_fixed_16(&error, red_x); + ry = png_ITU_fixed_16(&error, red_y); + gx = png_ITU_fixed_16(&error, green_x); + gy = png_ITU_fixed_16(&error, green_y); + bx = png_ITU_fixed_16(&error, blue_x); + by = png_ITU_fixed_16(&error, blue_y); + wx = png_ITU_fixed_16(&error, white_x); + wy = png_ITU_fixed_16(&error, white_y); + + if (error) + { + png_chunk_report(png_ptr, + "mDCV chromaticities outside representable range", + PNG_CHUNK_WRITE_ERROR); + return; + } + + /* Check the light level range: */ + if (maxDL > 0x7FFFFFFFU || minDL > 0x7FFFFFFFU) + { + /* The limit is 200kcd/m2; somewhat bright but not inconceivable because + * human vision is said to run up to 100Mcd/m2. The sun is about 2Gcd/m2. + * + * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is + * 2kcd/m2. + */ + png_chunk_report(png_ptr, "mDCV display light level exceeds PNG limit", + PNG_CHUNK_WRITE_ERROR); + return; + } + + /* All values are safe, the settings are accepted. + * + * IMPLEMENTATION NOTE: in practice the values can be checked and assigned + * but the result is confusing if a writing app calls png_set_mDCV more than + * once, the second time with an invalid value. This approach is more + * obviously correct at the cost of typing and a very slight machine + * overhead. + */ + info_ptr->mastering_red_x = rx; + info_ptr->mastering_red_y = ry; + info_ptr->mastering_green_x = gx; + info_ptr->mastering_green_y = gy; + info_ptr->mastering_blue_x = bx; + info_ptr->mastering_blue_y = by; + info_ptr->mastering_white_x = wx; + info_ptr->mastering_white_y = wy; + info_ptr->mastering_maxDL = maxDL; + info_ptr->mastering_minDL = minDL; + info_ptr->valid |= PNG_INFO_mDCV; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_mDCV(png_const_structrp png_ptr, png_inforp info_ptr, + double white_x, double white_y, double red_x, double red_y, double green_x, + double green_y, double blue_x, double blue_y, + double maxDL, double minDL) +{ + png_set_mDCV_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, white_x, "png_set_mDCV(white(x))"), + png_fixed(png_ptr, white_y, "png_set_mDCV(white(y))"), + png_fixed(png_ptr, red_x, "png_set_mDCV(red(x))"), + png_fixed(png_ptr, red_y, "png_set_mDCV(red(y))"), + png_fixed(png_ptr, green_x, "png_set_mDCV(green(x))"), + png_fixed(png_ptr, green_y, "png_set_mDCV(green(y))"), + png_fixed(png_ptr, blue_x, "png_set_mDCV(blue(x))"), + png_fixed(png_ptr, blue_y, "png_set_mDCV(blue(y))"), + png_fixed_ITU(png_ptr, maxDL, "png_set_mDCV(maxDL)"), + png_fixed_ITU(png_ptr, minDL, "png_set_mDCV(minDL)")); +} +# endif /* FLOATING_POINT */ +#endif /* mDCV */ + +#ifdef PNG_eXIf_SUPPORTED +void PNGAPI +png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytep exif) +{ + png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); + PNG_UNUSED(info_ptr) + PNG_UNUSED(exif) +} + +void PNGAPI +png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 num_exif, png_bytep exif) +{ + png_bytep new_exif; + + png_debug1(1, "in %s storage function", "eXIf"); + + if (png_ptr == NULL || info_ptr == NULL || + (png_ptr->mode & PNG_WROTE_eXIf) != 0 || + exif == NULL) + return; + + new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif)); + + if (new_exif == NULL) + { + png_warning(png_ptr, "Insufficient memory for eXIf chunk data"); + return; + } + + memcpy(new_exif, exif, (size_t)num_exif); + + png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0); + + info_ptr->num_exif = num_exif; + info_ptr->exif = new_exif; + info_ptr->free_me |= PNG_FREE_EXIF; + info_ptr->valid |= PNG_INFO_eXIf; +} +#endif /* eXIf */ + +#ifdef PNG_gAMA_SUPPORTED +void PNGFAPI +png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, + png_fixed_point file_gamma) +{ + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->gamma = file_gamma; + info_ptr->valid |= PNG_INFO_gAMA; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) +{ + png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, + "png_set_gAMA")); +} +# endif +#endif + +#ifdef PNG_hIST_SUPPORTED +void PNGAPI +png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_uint_16p hist) +{ + png_uint_16 safe_hist[PNG_MAX_PALETTE_LENGTH]; + int i; + + png_debug1(1, "in %s storage function", "hIST"); + + if (png_ptr == NULL || info_ptr == NULL || hist == NULL) + return; + + if (info_ptr->num_palette == 0 || info_ptr->num_palette + > PNG_MAX_PALETTE_LENGTH) + { + png_warning(png_ptr, + "Invalid palette size, hIST allocation skipped"); + + return; + } + + /* Snapshot the caller's hist before freeing, in case it points to + * info_ptr->hist (getter-to-setter aliasing). + */ + memcpy(safe_hist, hist, (unsigned int)info_ptr->num_palette * + (sizeof (png_uint_16))); + hist = safe_hist; + + png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); + + /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in + * version 1.2.1 + */ + info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); + + if (info_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data"); + return; + } + + for (i = 0; i < info_ptr->num_palette; i++) + info_ptr->hist[i] = hist[i]; + + info_ptr->free_me |= PNG_FREE_HIST; + info_ptr->valid |= PNG_INFO_hIST; +} +#endif + +void PNGAPI +png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) +{ + png_debug1(1, "in %s storage function", "IHDR"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->width = width; + info_ptr->height = height; + info_ptr->bit_depth = (png_byte)bit_depth; + info_ptr->color_type = (png_byte)color_type; + info_ptr->compression_type = (png_byte)compression_type; + info_ptr->filter_type = (png_byte)filter_type; + info_ptr->interlace_type = (png_byte)interlace_type; + + png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, + info_ptr->compression_type, info_ptr->filter_type); + + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->channels = 1; + + else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + info_ptr->channels = 3; + + else + info_ptr->channels = 1; + + if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) + info_ptr->channels++; + + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); + + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); +} + +#ifdef PNG_oFFs_SUPPORTED +void PNGAPI +png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type) +{ + png_debug1(1, "in %s storage function", "oFFs"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_offset = offset_x; + info_ptr->y_offset = offset_y; + info_ptr->offset_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_oFFs; +} +#endif + +#ifdef PNG_pCAL_SUPPORTED +void PNGAPI +png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params) +{ + size_t length; + int i; + + png_debug1(1, "in %s storage function", "pCAL"); + + if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL + || (nparams > 0 && params == NULL)) + return; + + length = strlen(purpose) + 1; + png_debug1(3, "allocating purpose for info (%lu bytes)", + (unsigned long)length); + + /* TODO: validate format of calibration name and unit name */ + + /* Check that the type matches the specification. */ + if (type < 0 || type > 3) + { + png_chunk_report(png_ptr, "Invalid pCAL equation type", + PNG_CHUNK_WRITE_ERROR); + return; + } + + if (nparams < 0 || nparams > 255) + { + png_chunk_report(png_ptr, "Invalid pCAL parameter count", + PNG_CHUNK_WRITE_ERROR); + return; + } + + /* Validate params[nparams] */ + for (i=0; ipcal_purpose = png_voidcast(png_charp, + png_malloc_warn(png_ptr, length)); + + if (info_ptr->pcal_purpose == NULL) + { + png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose", + PNG_CHUNK_WRITE_ERROR); + return; + } + + memcpy(info_ptr->pcal_purpose, purpose, length); + + info_ptr->free_me |= PNG_FREE_PCAL; + + png_debug(3, "storing X0, X1, type, and nparams in info"); + info_ptr->pcal_X0 = X0; + info_ptr->pcal_X1 = X1; + info_ptr->pcal_type = (png_byte)type; + info_ptr->pcal_nparams = (png_byte)nparams; + + length = strlen(units) + 1; + png_debug1(3, "allocating units for info (%lu bytes)", + (unsigned long)length); + + info_ptr->pcal_units = png_voidcast(png_charp, + png_malloc_warn(png_ptr, length)); + + if (info_ptr->pcal_units == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL units"); + return; + } + + memcpy(info_ptr->pcal_units, units, length); + + info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, + (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); + + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params"); + return; + } + + memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) * + (sizeof (png_charp))); + + for (i = 0; i < nparams; i++) + { + length = strlen(params[i]) + 1; + png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, + (unsigned long)length); + + info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); + + if (info_ptr->pcal_params[i] == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL parameter"); + return; + } + + memcpy(info_ptr->pcal_params[i], params[i], length); + } + + info_ptr->valid |= PNG_INFO_pCAL; +} +#endif + +#ifdef PNG_sCAL_SUPPORTED +void PNGAPI +png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight) +{ + size_t lengthw = 0, lengthh = 0; + + png_debug1(1, "in %s storage function", "sCAL"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Double check the unit (should never get here with an invalid + * unit unless this is an API call.) + */ + if (unit != 1 && unit != 2) + png_error(png_ptr, "Invalid sCAL unit"); + + if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || + swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + + if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || + sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) + png_error(png_ptr, "Invalid sCAL height"); + + info_ptr->scal_unit = (png_byte)unit; + + ++lengthw; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); + + info_ptr->scal_s_width = png_voidcast(png_charp, + png_malloc_warn(png_ptr, lengthw)); + + if (info_ptr->scal_s_width == NULL) + { + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); + + return; + } + + memcpy(info_ptr->scal_s_width, swidth, lengthw); + + ++lengthh; + + png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); + + info_ptr->scal_s_height = png_voidcast(png_charp, + png_malloc_warn(png_ptr, lengthh)); + + if (info_ptr->scal_s_height == NULL) + { + png_free(png_ptr, info_ptr->scal_s_width); + info_ptr->scal_s_width = NULL; + + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); + return; + } + + memcpy(info_ptr->scal_s_height, sheight, lengthh); + + info_ptr->free_me |= PNG_FREE_SCAL; + info_ptr->valid |= PNG_INFO_sCAL; +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, + double width, double height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, + PNG_sCAL_PRECISION); + png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, + PNG_sCAL_PRECISION); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, + png_fixed_point width, png_fixed_point height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); + png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif +#endif + +#ifdef PNG_pHYs_SUPPORTED +void PNGAPI +png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, + png_uint_32 res_x, png_uint_32 res_y, int unit_type) +{ + png_debug1(1, "in %s storage function", "pHYs"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->x_pixels_per_unit = res_x; + info_ptr->y_pixels_per_unit = res_y; + info_ptr->phys_unit_type = (png_byte)unit_type; + info_ptr->valid |= PNG_INFO_pHYs; +} +#endif + +void PNGAPI +png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, + png_const_colorp palette, int num_palette) +{ + png_color safe_palette[PNG_MAX_PALETTE_LENGTH]; + png_uint_32 max_palette_length; + + png_debug1(1, "in %s storage function", "PLTE"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; + + if (num_palette < 0 || num_palette > (int) max_palette_length) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Invalid palette length"); + + else + { + png_warning(png_ptr, "Invalid palette length"); + + return; + } + } + + if ((num_palette > 0 && palette == NULL) || + (num_palette == 0 +# ifdef PNG_MNG_FEATURES_SUPPORTED + && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 +# endif + )) + { + png_error(png_ptr, "Invalid palette"); + } + + /* Snapshot the caller's palette before freeing, in case it points to + * info_ptr->palette (getter-to-setter aliasing). + */ + if (num_palette > 0) + memcpy(safe_palette, palette, (unsigned int)num_palette * + (sizeof (png_color))); + + palette = safe_palette; + + png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); + + /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead + * of num_palette entries, in case of an invalid PNG file or incorrect + * call to png_set_PLTE() with too-large sample values. + * + * Allocate independent buffers for info_ptr and png_ptr so that the + * lifetime of png_ptr->palette is decoupled from the lifetime of + * info_ptr->palette. Previously, these two pointers were aliased, + * which caused a use-after-free vulnerability if png_free_data freed + * info_ptr->palette while png_ptr->palette was still in use by the + * row transform functions (e.g. png_do_expand_palette). + * + * Both buffers are allocated with png_calloc to zero-fill, because + * the ARM NEON palette riffle reads all 256 entries unconditionally, + * regardless of num_palette. + */ + png_free(png_ptr, png_ptr->palette); + png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); + info_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, + PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); + png_ptr->num_palette = info_ptr->num_palette = (png_uint_16)num_palette; + + if (num_palette > 0) + { + memcpy(info_ptr->palette, palette, (unsigned int)num_palette * + (sizeof (png_color))); + memcpy(png_ptr->palette, palette, (unsigned int)num_palette * + (sizeof (png_color))); + } + + info_ptr->free_me |= PNG_FREE_PLTE; + info_ptr->valid |= PNG_INFO_PLTE; +} + +#ifdef PNG_sBIT_SUPPORTED +void PNGAPI +png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_color_8p sig_bit) +{ + png_debug1(1, "in %s storage function", "sBIT"); + + if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) + return; + + info_ptr->sig_bit = *sig_bit; + info_ptr->valid |= PNG_INFO_sBIT; +} +#endif + +#ifdef PNG_sRGB_SUPPORTED +void PNGAPI +png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + info_ptr->rendering_intent = srgb_intent; + info_ptr->valid |= PNG_INFO_sRGB; +} + +void PNGAPI +png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, + int srgb_intent) +{ + png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_set_sRGB(png_ptr, info_ptr, srgb_intent); + +# ifdef PNG_gAMA_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); +# endif /* gAMA */ + +# ifdef PNG_cHRM_SUPPORTED + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000); +# endif /* cHRM */ +} +#endif /* sRGB */ + + +#ifdef PNG_iCCP_SUPPORTED +void PNGAPI +png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen) +{ + png_charp new_iccp_name; + png_bytep new_iccp_profile; + size_t length; + + png_debug1(1, "in %s storage function", "iCCP"); + + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + png_app_error(png_ptr, "Invalid iCCP compression method"); + + length = strlen(name)+1; + new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); + + if (new_iccp_name == NULL) + { + png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); + + return; + } + + memcpy(new_iccp_name, name, length); + new_iccp_profile = png_voidcast(png_bytep, + png_malloc_warn(png_ptr, proflen)); + + if (new_iccp_profile == NULL) + { + png_free(png_ptr, new_iccp_name); + png_benign_error(png_ptr, + "Insufficient memory to process iCCP profile"); + + return; + } + + memcpy(new_iccp_profile, profile, proflen); + + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); + + info_ptr->iccp_proflen = proflen; + info_ptr->iccp_name = new_iccp_name; + info_ptr->iccp_profile = new_iccp_profile; + info_ptr->free_me |= PNG_FREE_ICCP; + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#ifdef PNG_TEXT_SUPPORTED +void PNGAPI +png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_textp text_ptr, int num_text) +{ + int ret; + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + + if (ret != 0) + png_error(png_ptr, "Insufficient memory to store text"); +} + +int /* PRIVATE */ +png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_textp text_ptr, int num_text) +{ + int i; + png_textp old_text = NULL; + + png_debug1(1, "in text storage function, chunk typeid = 0x%lx", + png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name); + + if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) + return 0; + + /* Make sure we have enough space in the "text" array in info_struct + * to hold all of the incoming text_ptr objects. This compare can't overflow + * because max_text >= num_text (anyway, subtract of two positive integers + * can't overflow in any case.) + */ + if (num_text > info_ptr->max_text - info_ptr->num_text) + { + int old_num_text = info_ptr->num_text; + int max_text; + png_textp new_text = NULL; + + /* Calculate an appropriate max_text, checking for overflow. */ + max_text = old_num_text; + if (num_text <= INT_MAX - max_text) + { + max_text += num_text; + + /* Round up to a multiple of 8 */ + if (max_text < INT_MAX-8) + max_text = (max_text + 8) & ~0x7; + + else + max_text = INT_MAX; + + /* Now allocate a new array and copy the old members in; this does all + * the overflow checks. + */ + new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, + info_ptr->text, old_num_text, max_text-old_num_text, + sizeof *new_text)); + } + + if (new_text == NULL) + { + png_chunk_report(png_ptr, "too many text chunks", + PNG_CHUNK_WRITE_ERROR); + + return 1; + } + + /* Defer freeing the old array until after the copy loop below, + * in case text_ptr aliases info_ptr->text (getter-to-setter). + */ + old_text = info_ptr->text; + + info_ptr->text = new_text; + info_ptr->free_me |= PNG_FREE_TEXT; + info_ptr->max_text = max_text; + /* num_text is adjusted below as the entries are copied in */ + + png_debug1(3, "allocated %d entries for info_ptr->text", max_text); + } + + for (i = 0; i < num_text; i++) + { + size_t text_length, key_len; + size_t lang_len, lang_key_len; + png_textp textp = &(info_ptr->text[info_ptr->num_text]); + + if (text_ptr[i].key == NULL) + continue; + + if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || + text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) + { + png_chunk_report(png_ptr, "text compression mode is out of range", + PNG_CHUNK_WRITE_ERROR); + continue; + } + + key_len = strlen(text_ptr[i].key); + + if (text_ptr[i].compression <= 0) + { + lang_len = 0; + lang_key_len = 0; + } + + else +# ifdef PNG_iTXt_SUPPORTED + { + /* Set iTXt data */ + + if (text_ptr[i].lang != NULL) + lang_len = strlen(text_ptr[i].lang); + + else + lang_len = 0; + + if (text_ptr[i].lang_key != NULL) + lang_key_len = strlen(text_ptr[i].lang_key); + + else + lang_key_len = 0; + } +# else /* iTXt */ + { + png_chunk_report(png_ptr, "iTXt chunk not supported", + PNG_CHUNK_WRITE_ERROR); + continue; + } +# endif + + if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') + { + text_length = 0; +# ifdef PNG_iTXt_SUPPORTED + if (text_ptr[i].compression > 0) + textp->compression = PNG_ITXT_COMPRESSION_NONE; + + else +# endif + textp->compression = PNG_TEXT_COMPRESSION_NONE; + } + + else + { + text_length = strlen(text_ptr[i].text); + textp->compression = text_ptr[i].compression; + } + + textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, + key_len + text_length + lang_len + lang_key_len + 4)); + + if (textp->key == NULL) + { + png_chunk_report(png_ptr, "text chunk: out of memory", + PNG_CHUNK_WRITE_ERROR); + png_free(png_ptr, old_text); + + return 1; + } + + png_debug2(2, "Allocated %lu bytes at %p in png_set_text", + (unsigned long)(png_uint_32) + (key_len + lang_len + lang_key_len + text_length + 4), + textp->key); + + memcpy(textp->key, text_ptr[i].key, key_len); + *(textp->key + key_len) = '\0'; + + if (text_ptr[i].compression > 0) + { + textp->lang = textp->key + key_len + 1; + memcpy(textp->lang, text_ptr[i].lang, lang_len); + *(textp->lang + lang_len) = '\0'; + textp->lang_key = textp->lang + lang_len + 1; + memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); + *(textp->lang_key + lang_key_len) = '\0'; + textp->text = textp->lang_key + lang_key_len + 1; + } + + else + { + textp->lang=NULL; + textp->lang_key=NULL; + textp->text = textp->key + key_len + 1; + } + + if (text_length != 0) + memcpy(textp->text, text_ptr[i].text, text_length); + + *(textp->text + text_length) = '\0'; + +# ifdef PNG_iTXt_SUPPORTED + if (textp->compression > 0) + { + textp->text_length = 0; + textp->itxt_length = text_length; + } + + else +# endif + { + textp->text_length = text_length; + textp->itxt_length = 0; + } + + info_ptr->num_text++; + png_debug1(3, "transferred text chunk %d", info_ptr->num_text); + } + + png_free(png_ptr, old_text); + + return 0; +} +#endif + +#ifdef PNG_tIME_SUPPORTED +void PNGAPI +png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, + png_const_timep mod_time) +{ + png_debug1(1, "in %s storage function", "tIME"); + + if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || + (png_ptr->mode & PNG_WROTE_tIME) != 0) + return; + + if (mod_time->month == 0 || mod_time->month > 12 || + mod_time->day == 0 || mod_time->day > 31 || + mod_time->hour > 23 || mod_time->minute > 59 || + mod_time->second > 60) + { + png_warning(png_ptr, "Ignoring invalid time value"); + + return; + } + + info_ptr->mod_time = *mod_time; + info_ptr->valid |= PNG_INFO_tIME; +} +#endif + +#ifdef PNG_tRNS_SUPPORTED +void PNGAPI +png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, + png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) +{ + png_debug1(1, "in %s storage function", "tRNS"); + + if (png_ptr == NULL || info_ptr == NULL) + + return; + + if (trans_alpha != NULL) + { + /* Snapshot the caller's trans_alpha before freeing, in case it + * points to info_ptr->trans_alpha (getter-to-setter aliasing). + */ + png_byte safe_trans[PNG_MAX_PALETTE_LENGTH]; + + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + memcpy(safe_trans, trans_alpha, (size_t)num_trans); + + trans_alpha = safe_trans; + + png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); + + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + { + /* Allocate info_ptr's copy of the transparency data. + * Initialize all entries to fully opaque (0xff), then overwrite + * the first num_trans entries with the actual values. + */ + info_ptr->trans_alpha = png_voidcast(png_bytep, + png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); + memset(info_ptr->trans_alpha, 0xff, PNG_MAX_PALETTE_LENGTH); + memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans); + info_ptr->free_me |= PNG_FREE_TRNS; + info_ptr->valid |= PNG_INFO_tRNS; + + /* Allocate an independent copy for png_struct, so that the + * lifetime of png_ptr->trans_alpha is decoupled from the + * lifetime of info_ptr->trans_alpha. Previously these two + * pointers were aliased, which caused a use-after-free if + * png_free_data freed info_ptr->trans_alpha while + * png_ptr->trans_alpha was still in use by the row transform + * functions (e.g. png_do_expand_palette). + */ + png_free(png_ptr, png_ptr->trans_alpha); + png_ptr->trans_alpha = png_voidcast(png_bytep, + png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); + memset(png_ptr->trans_alpha, 0xff, PNG_MAX_PALETTE_LENGTH); + memcpy(png_ptr->trans_alpha, trans_alpha, (size_t)num_trans); + } + else + { + png_free(png_ptr, png_ptr->trans_alpha); + png_ptr->trans_alpha = NULL; + } + } + + if (trans_color != NULL) + { +#ifdef PNG_WARNINGS_SUPPORTED + if (info_ptr->bit_depth < 16) + { + int sample_max = (1 << info_ptr->bit_depth) - 1; + + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && + trans_color->gray > sample_max) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + (trans_color->red > sample_max || + trans_color->green > sample_max || + trans_color->blue > sample_max))) + png_warning(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth"); + } +#endif + + info_ptr->trans_color = *trans_color; + + if (num_trans == 0) + num_trans = 1; + } + + info_ptr->num_trans = (png_uint_16)num_trans; + + if (num_trans != 0) + { + info_ptr->free_me |= PNG_FREE_TRNS; + info_ptr->valid |= PNG_INFO_tRNS; + } +} +#endif + +#ifdef PNG_sPLT_SUPPORTED +void PNGAPI +png_set_sPLT(png_const_structrp png_ptr, + png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) +/* + * entries - array of png_sPLT_t structures + * to be added to the list of palettes + * in the info structure. + * + * nentries - number of palette structures to be + * added. + */ +{ + png_sPLT_tp np; + png_sPLT_tp old_spalettes; + + png_debug1(1, "in %s storage function", "sPLT"); + + if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) + return; + + /* Use the internal realloc function, which checks for all the possible + * overflows. Notice that the parameters are (int) and (size_t) + */ + np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, + info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, + sizeof *np)); + + if (np == NULL) + { + /* Out of memory or too many chunks */ + png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); + return; + } + + /* Defer freeing the old array until after the copy loop below, + * in case entries aliases info_ptr->splt_palettes (getter-to-setter). + */ + old_spalettes = info_ptr->splt_palettes; + + info_ptr->splt_palettes = np; + info_ptr->free_me |= PNG_FREE_SPLT; + + np += info_ptr->splt_palettes_num; + + do + { + size_t length; + + /* Skip invalid input entries */ + if (entries->name == NULL || entries->entries == NULL) + { + /* png_handle_sPLT doesn't do this, so this is an app error */ + png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); + /* Just skip the invalid entry */ + continue; + } + + np->depth = entries->depth; + + /* In the event of out-of-memory just return - there's no point keeping + * on trying to add sPLT chunks. + */ + length = strlen(entries->name) + 1; + np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); + + if (np->name == NULL) + break; + + memcpy(np->name, entries->name, length); + + /* IMPORTANT: we have memory now that won't get freed if something else + * goes wrong; this code must free it. png_malloc_array produces no + * warnings; use a png_chunk_report (below) if there is an error. + */ + np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, + entries->nentries, sizeof (png_sPLT_entry))); + + if (np->entries == NULL) + { + png_free(png_ptr, np->name); + np->name = NULL; + break; + } + + np->nentries = entries->nentries; + /* This multiply can't overflow because png_malloc_array has already + * checked it when doing the allocation. + */ + memcpy(np->entries, entries->entries, + (unsigned int)entries->nentries * sizeof (png_sPLT_entry)); + + /* Note that 'continue' skips the advance of the out pointer and out + * count, so an invalid entry is not added. + */ + info_ptr->valid |= PNG_INFO_sPLT; + ++(info_ptr->splt_palettes_num); + ++np; + ++entries; + } + while (--nentries); + + png_free(png_ptr, old_spalettes); + + if (nentries > 0) + png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); +} +#endif /* sPLT */ + +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED +static png_byte +check_location(png_const_structrp png_ptr, int location) +{ + location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); + + /* New in 1.6.0; copy the location and check it. This is an API + * change; previously the app had to use the + * png_set_unknown_chunk_location API below for each chunk. + */ + if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + /* Write struct, so unknown chunks come from the app */ + png_app_warning(png_ptr, + "png_set_unknown_chunks now expects a valid location"); + /* Use the old behavior */ + location = (png_byte)(png_ptr->mode & + (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); + } + + /* This need not be an internal error - if the app calls + * png_set_unknown_chunks on a read pointer it must get the location right. + */ + if (location == 0) + png_error(png_ptr, "invalid location in png_set_unknown_chunks"); + + /* Now reduce the location to the top-most set bit by removing each least + * significant bit in turn. + */ + while (location != (location & -location)) + location &= ~(location & -location); + + /* The cast is safe because 'location' is a bit mask and only the low four + * bits are significant. + */ + return (png_byte)location; +} + +void PNGAPI +png_set_unknown_chunks(png_const_structrp png_ptr, + png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) +{ + png_unknown_chunkp np; + png_unknown_chunkp old_unknowns; + + if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || + unknowns == NULL) + return; + + /* Check for the failure cases where support has been disabled at compile + * time. This code is hardly ever compiled - it's here because + * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this + * code) but may be meaningless if the read or write handling of unknown + * chunks is not compiled in. + */ +# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_READ_SUPPORTED) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { + png_app_error(png_ptr, "no unknown chunk support on read"); + + return; + } +# endif +# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ + defined(PNG_WRITE_SUPPORTED) + if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + png_app_error(png_ptr, "no unknown chunk support on write"); + + return; + } +# endif + + /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that + * unknown critical chunks could be lost with just a warning resulting in + * undefined behavior. Now png_chunk_report is used to provide behavior + * appropriate to read or write. + */ + np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, + info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, + sizeof *np)); + + if (np == NULL) + { + png_chunk_report(png_ptr, "too many unknown chunks", + PNG_CHUNK_WRITE_ERROR); + return; + } + + /* Defer freeing the old array until after the copy loop below, + * in case unknowns aliases info_ptr->unknown_chunks (getter-to-setter). + */ + old_unknowns = info_ptr->unknown_chunks; + + info_ptr->unknown_chunks = np; /* safe because it is initialized */ + info_ptr->free_me |= PNG_FREE_UNKN; + + np += info_ptr->unknown_chunks_num; + + /* Increment unknown_chunks_num each time round the loop to protect the + * just-allocated chunk data. + */ + for (; num_unknowns > 0; --num_unknowns, ++unknowns) + { + memcpy(np->name, unknowns->name, (sizeof np->name)); + np->name[(sizeof np->name)-1] = '\0'; + np->location = check_location(png_ptr, unknowns->location); + + if (unknowns->size == 0) + { + np->data = NULL; + np->size = 0; + } + + else + { + np->data = png_voidcast(png_bytep, + png_malloc_base(png_ptr, unknowns->size)); + + if (np->data == NULL) + { + png_chunk_report(png_ptr, "unknown chunk: out of memory", + PNG_CHUNK_WRITE_ERROR); + /* But just skip storing the unknown chunk */ + continue; + } + + memcpy(np->data, unknowns->data, unknowns->size); + np->size = unknowns->size; + } + + /* These increments are skipped on out-of-memory for the data - the + * unknown chunk entry gets overwritten if the png_chunk_report returns. + * This is correct in the read case (the chunk is just dropped.) + */ + ++np; + ++(info_ptr->unknown_chunks_num); + } + + png_free(png_ptr, old_unknowns); +} + +void PNGAPI +png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, + int chunk, int location) +{ + /* This API is pretty pointless in 1.6.0 because the location can be set + * before the call to png_set_unknown_chunks. + * + * TODO: add a png_app_warning in 1.7 + */ + if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && + chunk < info_ptr->unknown_chunks_num) + { + if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) + { + png_app_error(png_ptr, "invalid unknown chunk location"); + /* Fake out the pre 1.6.0 behavior: */ + if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */ + location = PNG_AFTER_IDAT; + + else + location = PNG_HAVE_IHDR; /* also undocumented */ + } + + info_ptr->unknown_chunks[chunk].location = + check_location(png_ptr, location); + } +} +#endif /* STORE_UNKNOWN_CHUNKS */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +png_uint_32 PNGAPI +png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features) +{ + png_debug(1, "in png_permit_mng_features"); + + if (png_ptr == NULL) + return 0; + + png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; + + return png_ptr->mng_features_permitted; +} +#endif + +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +static unsigned int +add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) +{ + unsigned int i; + + /* Utility function: update the 'keep' state of a chunk if it is already in + * the list, otherwise add it to the list. + */ + for (i=0; i= PNG_HANDLE_CHUNK_LAST) + { + png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); + + return; + } + + if (num_chunks_in <= 0) + { + png_ptr->unknown_default = keep; + + /* '0' means just set the flags, so stop here */ + if (num_chunks_in == 0) + return; + } + + if (num_chunks_in < 0) + { + /* Ignore all unknown chunks and all chunks recognized by + * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND + */ + static const png_byte chunks_to_ignore[] = { + 98, 75, 71, 68, '\0', /* bKGD */ + 99, 72, 82, 77, '\0', /* cHRM */ + 99, 73, 67, 80, '\0', /* cICP */ + 99, 76, 76, 73, '\0', /* cLLI */ + 101, 88, 73, 102, '\0', /* eXIf */ + 103, 65, 77, 65, '\0', /* gAMA */ + 104, 73, 83, 84, '\0', /* hIST */ + 105, 67, 67, 80, '\0', /* iCCP */ + 105, 84, 88, 116, '\0', /* iTXt */ + 109, 68, 67, 86, '\0', /* mDCV */ + 111, 70, 70, 115, '\0', /* oFFs */ + 112, 67, 65, 76, '\0', /* pCAL */ + 112, 72, 89, 115, '\0', /* pHYs */ + 115, 66, 73, 84, '\0', /* sBIT */ + 115, 67, 65, 76, '\0', /* sCAL */ + 115, 80, 76, 84, '\0', /* sPLT */ + 115, 84, 69, 82, '\0', /* sTER */ + 115, 82, 71, 66, '\0', /* sRGB */ + 116, 69, 88, 116, '\0', /* tEXt */ + 116, 73, 77, 69, '\0', /* tIME */ + 122, 84, 88, 116, '\0' /* zTXt */ + }; + + chunk_list = chunks_to_ignore; + num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; + } + + else /* num_chunks_in > 0 */ + { + if (chunk_list == NULL) + { + /* Prior to 1.6.0 this was silently ignored, now it is an app_error + * which can be switched off. + */ + png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); + + return; + } + + num_chunks = (unsigned int)num_chunks_in; + } + + old_num_chunks = png_ptr->num_chunk_list; + if (png_ptr->chunk_list == NULL) + old_num_chunks = 0; + + /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. + */ + if (num_chunks + old_num_chunks > UINT_MAX/5) + { + png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); + + return; + } + + /* If these chunks are being reset to the default then no more memory is + * required because add_one_chunk above doesn't extend the list if the 'keep' + * parameter is the default. + */ + if (keep != 0) + { + new_list = png_voidcast(png_bytep, png_malloc(png_ptr, + 5 * (num_chunks + old_num_chunks))); + + if (old_num_chunks > 0) + memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); + } + + else if (old_num_chunks > 0) + new_list = png_ptr->chunk_list; + + else + new_list = NULL; + + /* Add the new chunks together with each one's handling code. If the chunk + * already exists the code is updated, otherwise the chunk is added to the + * end. (In libpng 1.6.0 order no longer matters because this code enforces + * the earlier convention that the last setting is the one that is used.) + */ + if (new_list != NULL) + { + png_const_bytep inlist; + png_bytep outlist; + unsigned int i; + + for (i=0; ichunk_list != new_list) + png_free(png_ptr, new_list); + + new_list = NULL; + } + } + + else + num_chunks = 0; + + png_ptr->num_chunk_list = num_chunks; + + if (png_ptr->chunk_list != new_list) + { + if (png_ptr->chunk_list != NULL) + png_free(png_ptr, png_ptr->chunk_list); + + png_ptr->chunk_list = new_list; + } +} +#endif + +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED +void PNGAPI +png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, + png_user_chunk_ptr read_user_chunk_fn) +{ + png_debug(1, "in png_set_read_user_chunk_fn"); + + if (png_ptr == NULL) + return; + + png_ptr->read_user_chunk_fn = read_user_chunk_fn; + png_ptr->user_chunk_ptr = user_chunk_ptr; +} +#endif + +#ifdef PNG_INFO_IMAGE_SUPPORTED +void PNGAPI +png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, + png_bytepp row_pointers) +{ + png_debug(1, "in png_set_rows"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if (info_ptr->row_pointers != NULL && + (info_ptr->row_pointers != row_pointers)) + png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + + info_ptr->row_pointers = row_pointers; + + if (row_pointers != NULL) + info_ptr->valid |= PNG_INFO_IDAT; +} +#endif + +void PNGAPI +png_set_compression_buffer_size(png_structrp png_ptr, size_t size) +{ + png_debug(1, "in png_set_compression_buffer_size"); + + if (png_ptr == NULL) + return; + + if (size == 0 || size > PNG_UINT_31_MAX) + png_error(png_ptr, "invalid compression buffer size"); + +# ifdef PNG_SEQUENTIAL_READ_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { + png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ + return; + } +# endif + +# ifdef PNG_WRITE_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) + { + if (png_ptr->zowner != 0) + { + png_warning(png_ptr, + "Compression buffer size cannot be changed because it is in use"); + + return; + } + +#ifndef __COVERITY__ + /* Some compilers complain that this is always false. However, it + * can be true when integer overflow happens. + */ + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, + "Compression buffer size limited to system maximum"); + size = ZLIB_IO_MAX; /* must fit */ + } +#endif + + if (size < 6) + { + /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH + * if this is permitted. + */ + png_warning(png_ptr, + "Compression buffer size cannot be reduced below 6"); + + return; + } + + if (png_ptr->zbuffer_size != size) + { + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_ptr->zbuffer_size = (uInt)size; + } + } +# endif +} + +void PNGAPI +png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) +{ + if (png_ptr != NULL && info_ptr != NULL) + info_ptr->valid &= (unsigned int)(~mask); +} + + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +/* This function was added to libpng 1.2.6 */ +void PNGAPI +png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, + png_uint_32 user_height_max) +{ + png_debug(1, "in png_set_user_limits"); + + /* Images with dimensions larger than these limits will be + * rejected by png_set_IHDR(). To accept any PNG datastream + * regardless of dimensions, set both limits to 0x7fffffff. + */ + if (png_ptr == NULL) + return; + + png_ptr->user_width_max = user_width_max; + png_ptr->user_height_max = user_height_max; +} + +/* This function was added to libpng 1.4.0 */ +void PNGAPI +png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max) +{ + png_debug(1, "in png_set_chunk_cache_max"); + + if (png_ptr != NULL) + png_ptr->user_chunk_cache_max = user_chunk_cache_max; +} + +/* This function was added to libpng 1.4.1 */ +void PNGAPI +png_set_chunk_malloc_max(png_structrp png_ptr, + png_alloc_size_t user_chunk_malloc_max) +{ + png_debug(1, "in png_set_chunk_malloc_max"); + + /* pngstruct::user_chunk_malloc_max is initialized to a non-zero value in + * png.c. This API supports '0' for unlimited, make sure the correct + * (unlimited) value is set here to avoid a need to check for 0 everywhere + * the parameter is used. + */ + if (png_ptr != NULL) + { + if (user_chunk_malloc_max == 0U) /* unlimited */ + { +# ifdef PNG_MAX_MALLOC_64K + png_ptr->user_chunk_malloc_max = 65536U; +# else + png_ptr->user_chunk_malloc_max = PNG_SIZE_MAX; +# endif + } + else + png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; + } +} +#endif /* ?SET_USER_LIMITS */ + + +#ifdef PNG_BENIGN_ERRORS_SUPPORTED +void PNGAPI +png_set_benign_errors(png_structrp png_ptr, int allowed) +{ + png_debug(1, "in png_set_benign_errors"); + + /* If allowed is 1, png_benign_error() is treated as a warning. + * + * If allowed is 0, png_benign_error() is treated as an error (which + * is the default behavior if png_set_benign_errors() is not called). + */ + + if (allowed != 0) + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | + PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; + + else + png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | + PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); +} +#endif /* BENIGN_ERRORS */ + +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Whether to report invalid palette index; added at libpng-1.5.10. + * It is possible for an indexed (color-type==3) PNG file to contain + * pixels with invalid (out-of-range) indexes if the PLTE chunk has + * fewer entries than the image's bit-depth would allow. We recover + * from this gracefully by filling any incomplete palette with zeros + * (opaque black). By default, when this occurs libpng will issue + * a benign error. This API can be used to override that behavior. + */ +void PNGAPI +png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) +{ + png_debug(1, "in png_set_check_for_invalid_index"); + + if (allowed > 0) + png_ptr->num_palette_max = 0; + + else + png_ptr->num_palette_max = -1; +} +#endif + +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, + * and if invalid, correct the keyword rather than discarding the entire + * chunk. The PNG 1.0 specification requires keywords 1-79 characters in + * length, forbids leading or trailing whitespace, multiple internal spaces, + * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. + * + * The 'new_key' buffer must be 80 characters in size (for the keyword plus a + * trailing '\0'). If this routine returns 0 then there was no keyword, or a + * valid one could not be generated, and the caller must png_error. + */ +png_uint_32 /* PRIVATE */ +png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) +{ +#ifdef PNG_WARNINGS_SUPPORTED + png_const_charp orig_key = key; +#endif + png_uint_32 key_len = 0; + int bad_character = 0; + int space = 1; + + png_debug(1, "in png_check_keyword"); + + if (key == NULL) + { + *new_key = 0; + return 0; + } + + while (*key && key_len < 79) + { + png_byte ch = (png_byte)*key++; + + if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) + { + *new_key++ = ch; ++key_len; space = 0; + } + + else if (space == 0) + { + /* A space or an invalid character when one wasn't seen immediately + * before; output just a space. + */ + *new_key++ = 32; ++key_len; space = 1; + + /* If the character was not a space then it is invalid. */ + if (ch != 32) + bad_character = ch; + } + + else if (bad_character == 0) + bad_character = ch; /* just skip it, record the first error */ + } + + if (key_len > 0 && space != 0) /* trailing space */ + { + --key_len; --new_key; + if (bad_character == 0) + bad_character = 32; + } + + /* Terminate the keyword */ + *new_key = 0; + + if (key_len == 0) + return 0; + +#ifdef PNG_WARNINGS_SUPPORTED + /* Try to only output one warning per keyword: */ + if (*key != 0) /* keyword too long */ + png_warning(png_ptr, "keyword truncated"); + + else if (bad_character != 0) + { + PNG_WARNING_PARAMETERS(p) + + png_warning_parameter(p, 1, orig_key); + png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); + + png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); + } +#else /* !WARNINGS */ + PNG_UNUSED(png_ptr) +#endif /* !WARNINGS */ + + return key_len; +} +#endif /* TEXT || pCAL || iCCP || sPLT */ +#endif /* READ || WRITE */ diff --git a/thirdparty/libpng/upstream/pngstruct.h b/thirdparty/libpng/upstream/pngstruct.h index 11cae63f9..5cd7ddb45 100644 --- a/thirdparty/libpng/upstream/pngstruct.h +++ b/thirdparty/libpng/upstream/pngstruct.h @@ -1,479 +1,464 @@ - -/* pngstruct.h - header file for PNG reference library - * - * Copyright (c) 2018-2022 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The structure that holds the information to read and write PNG files. - * The only people who need to care about what is inside of this are the - * people who will be modifying the library for their own special needs. - * It should NOT be accessed directly by an application. - */ - -#ifndef PNGSTRUCT_H -#define PNGSTRUCT_H -/* zlib.h defines the structure z_stream, an instance of which is included - * in this structure and is required for decompressing the LZ compressed - * data in PNG files. - */ -#ifndef ZLIB_CONST - /* We must ensure that zlib uses 'const' in declarations. */ -# define ZLIB_CONST -#endif -#include -#ifdef const - /* zlib.h sometimes #defines const to nothing, undo this. */ -# undef const -#endif - -/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility - * with older builds. - */ -#if ZLIB_VERNUM < 0x1260 -# define PNGZ_MSG_CAST(s) png_constcast(char*,s) -# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) -#else -# define PNGZ_MSG_CAST(s) (s) -# define PNGZ_INPUT_CAST(b) (b) -#endif - -/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib - * can handle at once. This type need be no larger than 16 bits (so maximum of - * 65535), this define allows us to discover how big it is, but limited by the - * maximum for size_t. The value can be overridden in a library build - * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably - * lower value (e.g. 255 works). A lower value may help memory usage (slightly) - * and may even improve performance on some systems (and degrade it on others.) - */ -#ifndef ZLIB_IO_MAX -# define ZLIB_IO_MAX ((uInt)-1) -#endif - -#ifdef PNG_WRITE_SUPPORTED -/* The type of a compression buffer list used by the write code. */ -typedef struct png_compression_buffer -{ - struct png_compression_buffer *next; - png_byte output[1]; /* actually zbuf_size */ -} png_compression_buffer, *png_compression_bufferp; - -#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ - (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) -#endif - -/* Colorspace support; structures used in png_struct, png_info and in internal - * functions to hold and communicate information about the color space. - * - * PNG_COLORSPACE_SUPPORTED is only required if the application will perform - * colorspace corrections, otherwise all the colorspace information can be - * skipped and the size of libpng can be reduced (significantly) by compiling - * out the colorspace support. - */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* The chromaticities of the red, green and blue colorants and the chromaticity - * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). - */ -typedef struct png_xy -{ - png_fixed_point redx, redy; - png_fixed_point greenx, greeny; - png_fixed_point bluex, bluey; - png_fixed_point whitex, whitey; -} png_xy; - -/* The same data as above but encoded as CIE XYZ values. When this data comes - * from chromaticities the sum of the Y values is assumed to be 1.0 - */ -typedef struct png_XYZ -{ - png_fixed_point red_X, red_Y, red_Z; - png_fixed_point green_X, green_Y, green_Z; - png_fixed_point blue_X, blue_Y, blue_Z; -} png_XYZ; -#endif /* COLORSPACE */ - -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -/* A colorspace is all the above plus, potentially, profile information; - * however at present libpng does not use the profile internally so it is only - * stored in the png_info struct (if iCCP is supported.) The rendering intent - * is retained here and is checked. - * - * The file gamma encoding information is also stored here and gamma correction - * is done by libpng, whereas color correction must currently be done by the - * application. - */ -typedef struct png_colorspace -{ -#ifdef PNG_GAMMA_SUPPORTED - png_fixed_point gamma; /* File gamma */ -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED - png_xy end_points_xy; /* End points as chromaticities */ - png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ - png_uint_16 rendering_intent; /* Rendering intent of a profile */ -#endif - - /* Flags are always defined to simplify the code. */ - png_uint_16 flags; /* As defined below */ -} png_colorspace, * PNG_RESTRICT png_colorspacerp; - -typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; - -/* General flags for the 'flags' field */ -#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 -#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 -#define PNG_COLORSPACE_HAVE_INTENT 0x0004 -#define PNG_COLORSPACE_FROM_gAMA 0x0008 -#define PNG_COLORSPACE_FROM_cHRM 0x0010 -#define PNG_COLORSPACE_FROM_sRGB 0x0020 -#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 -#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ -#define PNG_COLORSPACE_INVALID 0x8000 -#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) -#endif /* COLORSPACE || GAMMA */ - -struct png_struct_def -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ - png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ - jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ - size_t jmp_buf_size; /* size of the above, if allocated */ -#endif - png_error_ptr error_fn; /* function for printing errors and aborting */ -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; /* function for printing warnings */ -#endif - png_voidp error_ptr; /* user supplied struct for error functions */ - png_rw_ptr write_data_fn; /* function for writing output data */ - png_rw_ptr read_data_fn; /* function for reading input data */ - png_voidp io_ptr; /* ptr to application struct for I/O functions */ - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr read_user_transform_fn; /* user read transform */ -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr write_user_transform_fn; /* user write transform */ -#endif - -/* These were added in libpng-1.0.2 */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - png_voidp user_transform_ptr; /* user supplied struct for user transform */ - png_byte user_transform_depth; /* bit depth of user transformed pixels */ - png_byte user_transform_channels; /* channels in user transformed pixels */ -#endif -#endif - - png_uint_32 mode; /* tells us where we are in the PNG file */ - png_uint_32 flags; /* flags indicating various things to libpng */ - png_uint_32 transformations; /* which transformations to perform */ - - png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ - z_stream zstream; /* decompression structure */ - -#ifdef PNG_WRITE_SUPPORTED - png_compression_bufferp zbuffer_list; /* Created on demand during write */ - uInt zbuffer_size; /* size of the actual buffer */ - - int zlib_level; /* holds zlib compression level */ - int zlib_method; /* holds zlib compression method */ - int zlib_window_bits; /* holds zlib compression window bits */ - int zlib_mem_level; /* holds zlib compression memory level */ - int zlib_strategy; /* holds zlib compression strategy */ -#endif -/* Added at libpng 1.5.4 */ -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - int zlib_text_level; /* holds zlib compression level */ - int zlib_text_method; /* holds zlib compression method */ - int zlib_text_window_bits; /* holds zlib compression window bits */ - int zlib_text_mem_level; /* holds zlib compression memory level */ - int zlib_text_strategy; /* holds zlib compression strategy */ -#endif -/* End of material added at libpng 1.5.4 */ -/* Added at libpng 1.6.0 */ -#ifdef PNG_WRITE_SUPPORTED - int zlib_set_level; /* Actual values set into the zstream on write */ - int zlib_set_method; - int zlib_set_window_bits; - int zlib_set_mem_level; - int zlib_set_strategy; -#endif - - png_uint_32 width; /* width of image in pixels */ - png_uint_32 height; /* height of image in pixels */ - png_uint_32 num_rows; /* number of rows in current pass */ - png_uint_32 usr_width; /* width of row at start of write */ - size_t rowbytes; /* size of row in bytes */ - png_uint_32 iwidth; /* width of current interlaced row in pixels */ - png_uint_32 row_number; /* current row in interlace pass */ - png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ - png_bytep prev_row; /* buffer to save previous (unfiltered) row. - * While reading this is a pointer into - * big_prev_row; while writing it is separately - * allocated if needed. - */ - png_bytep row_buf; /* buffer to save current (unfiltered) row. - * While reading, this is a pointer into - * big_row_buf; while writing it is separately - * allocated. - */ -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_bytep try_row; /* buffer to save trial row when filtering */ - png_bytep tst_row; /* buffer to save best trial row when filtering */ -#endif - size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ - - png_uint_32 idat_size; /* current IDAT size for read */ - png_uint_32 crc; /* current chunk CRC value */ - png_colorp palette; /* palette from the input file */ - png_uint_16 num_palette; /* number of color entries in palette */ - -/* Added at libpng-1.5.10 */ -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - int num_palette_max; /* maximum palette index found in IDAT */ -#endif - - png_uint_16 num_trans; /* number of transparency values */ - png_byte compression; /* file compression type (always 0) */ - png_byte filter; /* file filter type (always 0) */ - png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - png_byte pass; /* current interlace pass (0 - 6) */ - png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */ - png_byte color_type; /* color type of file */ - png_byte bit_depth; /* bit depth of file */ - png_byte usr_bit_depth; /* bit depth of users row: write only */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte channels; /* number of channels in file */ -#ifdef PNG_WRITE_SUPPORTED - png_byte usr_channels; /* channels at start of write: write only */ -#endif - png_byte sig_bytes; /* magic bytes read/written from start of file */ - png_byte maximum_pixel_depth; - /* pixel depth used for the row buffers */ - png_byte transformed_pixel_depth; - /* pixel depth after read/write transforms */ -#if ZLIB_VERNUM >= 0x1240 - png_byte zstream_start; /* at start of an input zlib stream */ -#endif /* Zlib >= 1.2.4 */ -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - png_uint_16 filler; /* filler bytes for pixel expansion */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - png_byte background_gamma_type; - png_fixed_point background_gamma; - png_color_16 background; /* background color in screen gamma space */ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_color_16 background_1; /* background normalized to gamma 1.0 */ -#endif -#endif /* bKGD */ - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn; /* Function for flushing output */ - png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ - png_uint_32 flush_rows; /* number of rows written since last flush */ -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ - png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ - - png_bytep gamma_table; /* gamma table for 8-bit depth files */ - png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_bytep gamma_from_1; /* converts from 1.0 to screen */ - png_bytep gamma_to_1; /* converts from file to 1.0 */ - png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ - png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) - png_color_8 sig_bit; /* significant bits in each available channel */ -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - png_color_8 shift; /* shift for significant bit transformation */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ - || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep trans_alpha; /* alpha values for paletted files */ - png_color_16 trans_color; /* transparent color for non-paletted files */ -#endif - - png_read_status_ptr read_row_fn; /* called after each row is decoded */ - png_write_status_ptr write_row_fn; /* called after each row is encoded */ -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_progressive_info_ptr info_fn; /* called after header data fully read */ - png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ - png_progressive_end_ptr end_fn; /* called after image is complete */ - png_bytep save_buffer_ptr; /* current location in save_buffer */ - png_bytep save_buffer; /* buffer for previously read data */ - png_bytep current_buffer_ptr; /* current location in current_buffer */ - png_bytep current_buffer; /* buffer for recently used data */ - png_uint_32 push_length; /* size of current input chunk */ - png_uint_32 skip_length; /* bytes to skip in input data */ - size_t save_buffer_size; /* amount of data now in save_buffer */ - size_t save_buffer_max; /* total size of save_buffer */ - size_t buffer_size; /* total amount of available input data */ - size_t current_buffer_size; /* amount of data now in current_buffer */ - int process_mode; /* what push library is currently doing */ - int cur_palette; /* current push library palette index */ -#endif /* PROGRESSIVE_READ */ - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_bytep palette_lookup; /* lookup table for quantizing */ - png_bytep quantize_index; /* index translation for palette files */ -#endif - -/* Options */ -#ifdef PNG_SET_OPTION_SUPPORTED - png_uint_32 options; /* On/off state (up to 16 options) */ -#endif - -#if PNG_LIBPNG_VER < 10700 -/* To do: remove this from libpng-1.7 */ -#ifdef PNG_TIME_RFC1123_SUPPORTED - char time_buffer[29]; /* String to hold RFC 1123 time text */ -#endif -#endif - -/* New members added in libpng-1.0.6 */ - - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#ifdef PNG_USER_CHUNKS_SUPPORTED - png_voidp user_chunk_ptr; -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ -#endif -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int unknown_default; /* As PNG_HANDLE_* */ - unsigned int num_chunk_list; /* Number of entries in the list */ - png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name - * followed by a PNG_HANDLE_* byte */ -#endif - -/* New members added in libpng-1.0.3 */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte rgb_to_gray_status; - /* Added in libpng 1.5.5 to record setting of coefficients: */ - png_byte rgb_to_gray_coefficients_set; - /* These were changed from png_byte in libpng-1.0.6 */ - png_uint_16 rgb_to_gray_red_coeff; - png_uint_16 rgb_to_gray_green_coeff; - /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ -#endif - -/* New member added in libpng-1.6.36 */ -#if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) - png_bytep riffled_palette; /* buffer for accelerated palette expansion */ -#endif - -/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ -#if defined(PNG_MNG_FEATURES_SUPPORTED) -/* Changed from png_byte to png_uint_32 at version 1.2.0 */ - png_uint_32 mng_features_permitted; -#endif - -/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_byte filter_type; -#endif - -/* New members added in libpng-1.2.0 */ - -/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ -#ifdef PNG_USER_MEM_SUPPORTED - png_voidp mem_ptr; /* user supplied struct for mem functions */ - png_malloc_ptr malloc_fn; /* function for allocating memory */ - png_free_ptr free_fn; /* function for freeing memory */ -#endif - -/* New member added in libpng-1.0.13 and 1.2.0 */ - png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep quantize_sort; /* working sort array */ - png_bytep index_to_palette; /* where the original index currently is - in the palette */ - png_bytep palette_to_index; /* which original index points to this - palette color */ -#endif - -/* New members added in libpng-1.0.16 and 1.2.6 */ - png_byte compression_type; - -#ifdef PNG_USER_LIMITS_SUPPORTED - png_uint_32 user_width_max; - png_uint_32 user_height_max; - - /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown - * chunks that can be stored (0 means unlimited). - */ - png_uint_32 user_chunk_cache_max; - - /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk - * can occupy when decompressed. 0 means unlimited. - */ - png_alloc_size_t user_chunk_malloc_max; -#endif - -/* New member added in libpng-1.0.25 and 1.2.17 */ -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* Temporary storage for unknown chunk that the library doesn't recognize, - * used while reading the chunk. - */ - png_unknown_chunk unknown_chunk; -#endif - -/* New member added in libpng-1.2.26 */ - size_t old_big_row_buf_size; - -#ifdef PNG_READ_SUPPORTED -/* New member added in libpng-1.2.30 */ - png_bytep read_buffer; /* buffer for reading chunk data */ - png_alloc_size_t read_buffer_size; /* current size of the buffer */ -#endif -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - uInt IDAT_read_size; /* limit on read buffer size for IDAT */ -#endif - -#ifdef PNG_IO_STATE_SUPPORTED -/* New member added in libpng-1.4.0 */ - png_uint_32 io_state; -#endif - -/* New member added in libpng-1.5.6 */ - png_bytep big_prev_row; - -/* New member added in libpng-1.5.7 */ - void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row); - -#ifdef PNG_READ_SUPPORTED -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - png_colorspace colorspace; -#endif -#endif -}; -#endif /* PNGSTRUCT_H */ +/* pngstruct.h - internal structures for libpng + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#ifndef PNGPRIV_H +# error This file must not be included by applications; please include +#endif + +#ifndef PNGSTRUCT_H +#define PNGSTRUCT_H +/* zlib.h defines the structure z_stream, an instance of which is included + * in this structure and is required for decompressing the LZ compressed + * data in PNG files. + */ +#ifndef ZLIB_CONST + /* We must ensure that zlib uses 'const' in declarations. */ +# define ZLIB_CONST +#endif +#include "zlib.h" +#ifdef const + /* zlib.h sometimes #defines const to nothing, undo this. */ +# undef const +#endif + +/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility + * with older builds. + */ +#if ZLIB_VERNUM < 0x1260 +# define PNGZ_MSG_CAST(s) png_constcast(char*,s) +# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) +#else +# define PNGZ_MSG_CAST(s) (s) +# define PNGZ_INPUT_CAST(b) (b) +#endif + +/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib + * can handle at once. This type need be no larger than 16 bits (so maximum of + * 65535), this define allows us to discover how big it is, but limited by the + * maximum for size_t. The value can be overridden in a library build + * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably + * lower value (e.g. 255 works). A lower value may help memory usage (slightly) + * and may even improve performance on some systems (and degrade it on others.) + */ +#ifndef ZLIB_IO_MAX +# define ZLIB_IO_MAX ((uInt)-1) +#endif + +#ifdef PNG_WRITE_SUPPORTED +/* The type of a compression buffer list used by the write code. */ +typedef struct png_compression_buffer +{ + struct png_compression_buffer *next; + png_byte output[1]; /* actually zbuf_size */ +} png_compression_buffer, *png_compression_bufferp; + +#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ + (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) +#endif + +/* Colorspace support; structures used in png_struct, png_info and in internal + * functions to hold and communicate information about the color space. + */ +/* The chromaticities of the red, green and blue colorants and the chromaticity + * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). + */ +typedef struct png_xy +{ + png_fixed_point redx, redy; + png_fixed_point greenx, greeny; + png_fixed_point bluex, bluey; + png_fixed_point whitex, whitey; +} png_xy; + +/* The same data as above but encoded as CIE XYZ values. When this data comes + * from chromaticities the sum of the Y values is assumed to be 1.0 + */ +typedef struct png_XYZ +{ + png_fixed_point red_X, red_Y, red_Z; + png_fixed_point green_X, green_Y, green_Z; + png_fixed_point blue_X, blue_Y, blue_Z; +} png_XYZ; + +/* Chunk index values as an enum, PNG_INDEX_unknown is also a count of the + * number of chunks. + */ +#define PNG_CHUNK(cHNK, i) PNG_INDEX_ ## cHNK = (i), +typedef enum +{ + PNG_KNOWN_CHUNKS + PNG_INDEX_unknown +} png_index; +#undef PNG_CHUNK + +/* Chunk flag values. These are (png_uint_32 values) with exactly one bit set + * and can be combined into a flag set with bitwise 'or'. + * + * TODO: C23: convert these macros to C23 inlines (which are static). + */ +#define png_chunk_flag_from_index(i) (0x80000000U >> (31 - (i))) + /* The flag corresponding to the given png_index enum value. This is defined + * for png_unknown as well (until it reaches the value 32) but this should + * not be relied on. + */ + +#define png_file_has_chunk(png_ptr, i)\ + (((png_ptr)->chunks & png_chunk_flag_from_index(i)) != 0) + /* The chunk has been recorded in png_struct */ + +#define png_file_add_chunk(png_ptr, i)\ + ((void)((png_ptr)->chunks |= png_chunk_flag_from_index(i))) + /* Record the chunk in the png_struct */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ + png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ + jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ + size_t jmp_buf_size; /* size of the above, if allocated */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ +#ifdef PNG_WARNINGS_SUPPORTED + png_error_ptr warning_fn; /* function for printing warnings */ +#endif + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ + z_stream zstream; /* decompression structure */ + +#ifdef PNG_WRITE_SUPPORTED + png_compression_bufferp zbuffer_list; /* Created on demand during write */ + uInt zbuffer_size; /* size of the actual buffer */ + + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ +#endif +/* Added at libpng 1.5.4 */ +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + int zlib_text_level; /* holds zlib compression level */ + int zlib_text_method; /* holds zlib compression method */ + int zlib_text_window_bits; /* holds zlib compression window bits */ + int zlib_text_mem_level; /* holds zlib compression memory level */ + int zlib_text_strategy; /* holds zlib compression strategy */ +#endif +/* End of material added at libpng 1.5.4 */ +/* Added at libpng 1.6.0 */ +#ifdef PNG_WRITE_SUPPORTED + int zlib_set_level; /* Actual values set into the zstream on write */ + int zlib_set_method; + int zlib_set_window_bits; + int zlib_set_mem_level; + int zlib_set_strategy; +#endif + + png_uint_32 chunks; /* PNG_CF_ for every chunk read or (NYI) written */ +# define png_has_chunk(png_ptr, cHNK)\ + png_file_has_chunk(png_ptr, PNG_INDEX_ ## cHNK) + /* Convenience accessor - use this to check for a known chunk by name */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + size_t rowbytes; /* size of row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row. + * While reading this is a pointer into + * big_prev_row; while writing it is separately + * allocated if needed. + */ + png_bytep row_buf; /* buffer to save current (unfiltered) row. + * While reading, this is a pointer into + * big_row_buf; while writing it is separately + * allocated. + */ +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_bytep try_row; /* buffer to save trial row when filtering */ + png_bytep tst_row; /* buffer to save best trial row when filtering */ +#endif + size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + +/* Added at libpng-1.5.10 */ +#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + int num_palette_max; /* maximum palette index found in IDAT */ +#endif + + png_uint_16 num_trans; /* number of transparency values */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row: write only */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ +#ifdef PNG_WRITE_SUPPORTED + png_byte usr_channels; /* channels at start of write: write only */ +#endif + png_byte sig_bytes; /* magic bytes read/written from start of file */ + png_byte maximum_pixel_depth; + /* pixel depth used for the row buffers */ + png_byte transformed_pixel_depth; + /* pixel depth after read/write transforms */ +#if ZLIB_VERNUM >= 0x1240 + png_byte zstream_start; /* at start of an input zlib stream */ +#endif /* Zlib >= 1.2.4 */ +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + png_byte background_gamma_type; + png_fixed_point background_gamma; + png_color_16 background; /* background color in screen gamma space */ +#ifdef PNG_READ_GAMMA_SUPPORTED + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* bKGD */ + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_flush_ptr output_flush_fn; /* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_xy chromaticities; /* From mDVC, cICP, [iCCP], sRGB or cHRM */ +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ + png_fixed_point screen_gamma; /* screen gamma value (display exponent) */ + png_fixed_point file_gamma; /* file gamma value (encoding exponent) */ + png_fixed_point chunk_gamma; /* from cICP, iCCP, sRGB or gAMA */ + png_fixed_point default_gamma;/* from png_set_alpha_mode */ + + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ +#endif /* READ_GAMMA */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit transformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans_alpha; /* alpha values for paletted files */ + png_color_16 trans_color; /* transparent color for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + size_t save_buffer_size; /* amount of data now in save_buffer */ + size_t save_buffer_max; /* total size of save_buffer */ + size_t buffer_size; /* total amount of available input data */ + size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ +#endif /* PROGRESSIVE_READ */ + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + png_bytep palette_lookup; /* lookup table for quantizing */ + png_bytep quantize_index; /* index translation for palette files */ +#endif + +/* Options */ +#ifdef PNG_SET_OPTION_SUPPORTED + png_uint_32 options; /* On/off state (up to 16 options) */ +#endif + +#if PNG_LIBPNG_VER < 10700 +/* To do: remove this from libpng-1.7 */ +#ifdef PNG_TIME_RFC1123_SUPPORTED + char time_buffer[29]; /* String to hold RFC 1123 time text */ +#endif /* TIME_RFC1123 */ +#endif /* LIBPNG_VER < 10700 */ + +/* New members added in libpng-1.0.6 */ + + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + +#ifdef PNG_USER_CHUNKS_SUPPORTED + png_voidp user_chunk_ptr; +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif /* READ_USER_CHUNKS */ +#endif /* USER_CHUNKS */ + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + int unknown_default; /* As PNG_HANDLE_* */ + unsigned int num_chunk_list; /* Number of entries in the list */ + png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name + * followed by a PNG_HANDLE_* byte */ +#endif + +/* New members added in libpng-1.0.3 */ +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + png_byte rgb_to_gray_status; + /* Added in libpng 1.5.5 to record setting of coefficients: */ + png_byte rgb_to_gray_coefficients_set; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ +#endif + +/* New member added in libpng-1.6.36 */ +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + (defined(PNG_ARM_NEON_IMPLEMENTATION) || \ + defined(PNG_RISCV_RVV_IMPLEMENTATION)) + png_bytep riffled_palette; /* buffer for accelerated palette expansion */ +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) +/* Changed from png_byte to png_uint_32 at version 1.2.0 */ + png_uint_32 mng_features_permitted; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_byte filter_type; +#endif + +/* New members added in libpng-1.2.0 */ + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#ifdef PNG_READ_QUANTIZE_SUPPORTED +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep index_to_palette; /* where the original index currently is + in the palette */ + png_bytep palette_to_index; /* which original index points to this + palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type; + +#ifdef PNG_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; + + /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown + * chunks that can be stored (0 means unlimited). + */ + png_uint_32 user_chunk_cache_max; + + /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk + * can occupy when decompressed. 0 means unlimited. + */ + png_alloc_size_t user_chunk_malloc_max; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED + /* Temporary storage for unknown chunk that the library doesn't recognize, + * used while reading the chunk. + */ + png_unknown_chunk unknown_chunk; +#endif + +/* New member added in libpng-1.2.26 */ + size_t old_big_row_buf_size; + +#ifdef PNG_READ_SUPPORTED +/* New member added in libpng-1.2.30 */ + png_bytep read_buffer; /* buffer for reading chunk data */ + png_alloc_size_t read_buffer_size; /* current size of the buffer */ +#endif +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED + uInt IDAT_read_size; /* limit on read buffer size for IDAT */ +#endif + +#ifdef PNG_IO_STATE_SUPPORTED +/* New member added in libpng-1.4.0 */ + png_uint_32 io_state; +#endif + +/* New member added in libpng-1.5.6 */ + png_bytep big_prev_row; + +/* New member added in libpng-1.5.7 */ + void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row); +}; +#endif /* PNGSTRUCT_H */ diff --git a/thirdparty/libpng/upstream/pngtest.c b/thirdparty/libpng/upstream/pngtest.c deleted file mode 100644 index 6624b8be3..000000000 --- a/thirdparty/libpng/upstream/pngtest.c +++ /dev/null @@ -1,2107 +0,0 @@ - -/* pngtest.c - a test program for libpng - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This program reads in a PNG image, writes it out again, and then - * compares the two files. If the files are identical, this shows that - * the basic chunk handling, filtering, and (de)compression code is working - * properly. It does not currently test all of the transforms, although - * it probably should. - * - * The program will report "FAIL" in certain legitimate cases: - * 1) when the compression level or filter selection method is changed. - * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. - * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks - * exist in the input file. - * 4) others not listed here... - * In these cases, it is best to check with another tool such as "pngcheck" - * to see what the differences between the two files are. - * - * If a filename is given on the command-line, then this file is used - * for the input, rather than the default "pngtest.png". This allows - * testing a wide variety of files easily. You can also test a number - * of files at once by typing "pngtest -m file1.png file2.png ..." - */ - -#define _POSIX_SOURCE 1 - -#include -#include -#include - -#ifdef PNG_ZLIB_HEADER -# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ -#else -# include -#endif - -#include "png.h" - -/* This hack was introduced for historical reasons, and we are - * still keeping it in libpng-1.6.x for compatibility reasons. - */ -#define STDERR stdout - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_44 Your_png_h_is_not_version_1_6_44; - -/* Ensure that all version numbers in png.h are consistent with one another. */ -#if (PNG_LIBPNG_VER != PNG_LIBPNG_VER_MAJOR * 10000 + \ - PNG_LIBPNG_VER_MINOR * 100 + \ - PNG_LIBPNG_VER_RELEASE) || \ - (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_MAJOR * 10 + \ - PNG_LIBPNG_VER_MINOR) || \ - (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_SONUM) || \ - (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_DLLNUM) -# error "Inconsistent version numbers in png.h" -#endif - -/* In version 1.6.1, we added support for the configure test harness, which - * uses 77 to indicate a skipped test. On the other hand, in cmake build tests, - * we still need to succeed on a skipped test, so: - */ -#if defined(HAVE_CONFIG_H) -# define SKIP 77 -#else -# define SKIP 0 -#endif - -/* Known chunks that exist in pngtest.png must be supported, or pngtest will - * fail simply as a result of re-ordering them. This may be fixed in the next - * generation of libpng. - * - * pngtest allocates a single row buffer for each row and overwrites it, - * therefore if the write side doesn't support the writing of interlaced images - * nothing can be done for an interlaced image (and the code below will fail - * horribly trying to write extra data after writing garbage). - */ -#if defined PNG_READ_SUPPORTED && /* else nothing can be done */ \ - defined PNG_READ_bKGD_SUPPORTED && \ - defined PNG_READ_cHRM_SUPPORTED && \ - defined PNG_READ_gAMA_SUPPORTED && \ - defined PNG_READ_oFFs_SUPPORTED && \ - defined PNG_READ_pCAL_SUPPORTED && \ - defined PNG_READ_pHYs_SUPPORTED && \ - defined PNG_READ_sBIT_SUPPORTED && \ - defined PNG_READ_sCAL_SUPPORTED && \ - defined PNG_READ_sRGB_SUPPORTED && \ - defined PNG_READ_sPLT_SUPPORTED && \ - defined PNG_READ_tEXt_SUPPORTED && \ - defined PNG_READ_tIME_SUPPORTED && \ - defined PNG_READ_zTXt_SUPPORTED && \ - (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700) - -/* Copied from pngpriv.h but only used in error messages below. */ -#ifndef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 8192 -#endif - -#ifndef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -#ifndef PNG_DEBUG -# define PNG_DEBUG 0 -#endif - -#if PNG_DEBUG > 1 -# define pngtest_debug(m) ((void)fprintf(stderr, m "\n")) -# define pngtest_debug1(m, p1) ((void)fprintf(stderr, m "\n", p1)) -# define pngtest_debug2(m, p1, p2) ((void)fprintf(stderr, m "\n", p1, p2)) -#elif PNG_DEBUG == 0 || PNG_DEBUG == 1 -# define pngtest_debug(m) ((void)0) -# define pngtest_debug1(m, p1) ((void)0) -# define pngtest_debug2(m, p1, p2) ((void)0) -#else /* PNG_DEBUG < 0 */ -# error "Bad PNG_DEBUG value" -#endif - -/* Turn on CPU timing -#define PNGTEST_TIMING -*/ - -#ifndef PNG_FLOATING_POINT_SUPPORTED -#undef PNGTEST_TIMING -#endif - -#ifdef PNGTEST_TIMING -static float t_start, t_stop, t_decode, t_encode, t_misc; -#include -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED -static int tIME_chunk_present = 0; -static char tIME_string[29] = "tIME chunk is not present"; -/* This use case is deprecated. - * See the declaration of png_convert_to_rfc1123_buffer for more details. - */ -#endif - -static int verbose = 0; -static int strict = 0; -static int relaxed = 0; -static int xfail = 0; -static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ -static int error_count = 0; /* count calls to png_error */ -static int warning_count = 0; /* count calls to png_warning */ - -/* Example of using row callbacks to make a simple progress meter */ -static int status_pass = 1; -static int status_dots_requested = 0; -static int status_dots = 1; - -static void PNGCBAPI -read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - /* The callback should always receive correct parameters. */ - if (png_ptr == NULL) - png_error(png_ptr, "read_row_callback: bad png_ptr"); - if (row_number > PNG_UINT_31_MAX) - png_error(png_ptr, "read_row_callback: bad row number"); - if (pass < 0 || pass > 7) - png_error(png_ptr, "read_row_callback: bad pass"); - - if (status_pass != pass) - { - fprintf(stdout, "\n Pass %d: ", pass); - status_pass = pass; - status_dots = 31; - } - - status_dots--; - - if (status_dots == 0) - { - fprintf(stdout, "\n "); - status_dots = 30; - } - - fprintf(stdout, "r"); -} - -#ifdef PNG_WRITE_SUPPORTED -static void PNGCBAPI -write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - /* The callback should always receive correct parameters. */ - if (png_ptr == NULL) - png_error(png_ptr, "write_row_callback: bad png_ptr"); - if (row_number > PNG_UINT_31_MAX) - png_error(png_ptr, "write_row_callback: bad row number"); - if (pass < 0 || pass > 7) - png_error(png_ptr, "write_row_callback: bad pass"); - - fprintf(stdout, "w"); -} -#endif - - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -/* Example of using a user transform callback (doesn't do anything at present). - */ -static void PNGCBAPI -read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - /* The callback should always receive correct parameters. */ - if (png_ptr == NULL) - png_error(png_ptr, "read_user_callback: bad png_ptr"); - if (row_info == NULL) - png_error(png_ptr, "read_user_callback: bad row info"); - if (data == NULL) - png_error(png_ptr, "read_user_callback: bad data"); -} -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -/* Example of using user transform callback (we don't transform anything, - * but merely count the zero samples) - */ - -static png_uint_32 zero_samples; - -static void PNGCBAPI -count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - png_bytep dp = data; - - /* The callback should always receive correct parameters. */ - if (png_ptr == NULL) - png_error(png_ptr, "count_zero_samples: bad png_ptr"); - if (row_info == NULL) - png_error(png_ptr, "count_zero_samples: bad row info"); - if (data == NULL) - png_error(png_ptr, "count_zero_samples: bad data"); - - /* Contents of row_info: - * png_uint_32 width width of row - * png_uint_32 rowbytes number of bytes in row - * png_byte color_type color type of pixels - * png_byte bit_depth bit depth of samples - * png_byte channels number of channels (1-4) - * png_byte pixel_depth bits per pixel (depth*channels) - */ - - /* Counts the number of zero samples (or zero pixels if color_type is 3 */ - - if (row_info->color_type == 0 || row_info->color_type == 3) - { - int pos = 0; - png_uint_32 n, nstop; - - for (n = 0, nstop = row_info->width; n < nstop; n++) - { - if (row_info->bit_depth == 1) - { - if (((*dp << pos++ ) & 0x80) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 2) - { - if (((*dp << (pos+=2)) & 0xc0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 4) - { - if (((*dp << (pos+=4)) & 0xf0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - dp += 2; - } - } - } - else /* Other color types */ - { - png_uint_32 n, nstop; - int channel; - int color_channels = row_info->channels; - if (row_info->color_type > 3) - color_channels--; - - for (n = 0, nstop = row_info->width; n < nstop; n++) - { - for (channel = 0; channel < color_channels; channel++) - { - if (row_info->bit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - - dp += 2; - } - } - if (row_info->color_type > 3) - { - dp++; - if (row_info->bit_depth == 16) - dp++; - } - } - } -} -#endif /* WRITE_USER_TRANSFORM */ - -#ifndef PNG_STDIO_SUPPORTED -/* START of code to validate stdio-free compilation */ -/* These copies of the default read/write functions come from pngrio.c and - * pngwio.c. They allow "don't include stdio" testing of the library. - * This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ - -#ifdef PNG_IO_STATE_SUPPORTED -void -pngtest_check_io_state(png_structp png_ptr, size_t data_length, - png_uint_32 io_op) -{ - png_uint_32 io_state = png_get_io_state(png_ptr); - int err = 0; - - /* Check if the current operation (reading / writing) is as expected. */ - if ((io_state & PNG_IO_MASK_OP) != io_op) - png_error(png_ptr, "Incorrect operation in I/O state"); - - /* Check if the buffer size specific to the current location - * (file signature / header / data / crc) is as expected. - */ - switch ((io_state & PNG_IO_MASK_LOC) != 0) - { - case PNG_IO_SIGNATURE: - if (data_length > 8) - err = 1; - break; - case PNG_IO_CHUNK_HDR: - if (data_length != 8) - err = 1; - break; - case PNG_IO_CHUNK_DATA: - break; /* no restrictions here */ - case PNG_IO_CHUNK_CRC: - if (data_length != 4) - err = 1; - break; - default: - err = 1; /* uninitialized */ - } - if (err != 0) - png_error(png_ptr, "Bad I/O state or buffer size"); -} -#endif - -static void PNGCBAPI -pngtest_read_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check = 0; - png_voidp io_ptr; - - if (png_ptr == NULL) - png_error(png_ptr, "pngtest_read_data: bad png_ptr"); - - /* fread() returns 0 on error, so it is OK to store this in a size_t - * instead of an int, which is what fread() actually returns. - */ - io_ptr = png_get_io_ptr(png_ptr); - if (io_ptr != NULL) - check = fread(data, 1, length, (png_FILE_p)io_ptr); - - if (check != length) - png_error(png_ptr, "Read Error"); - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_READING); -#endif -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -static void PNGCBAPI -pngtest_flush(png_structp png_ptr) -{ - if (png_ptr == NULL) - png_error(png_ptr, "pngtest_flush: bad png_ptr"); - - /* Do nothing; fflush() is said to be just a waste of energy. */ -} -#endif - -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -static void PNGCBAPI -pngtest_write_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check; - - if (png_ptr == NULL) - png_error(png_ptr, "pngtest_write_data: bad png_ptr"); - - check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr)); - - if (check != length) - png_error(png_ptr, "Write Error"); - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); -#endif -} -#endif /* !STDIO */ - -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -typedef struct -{ - const char *file_name; -} pngtest_error_parameters; - -static void PNGCBAPI -pngtest_warning(png_structp png_ptr, png_const_charp message) -{ - const char *name = "UNKNOWN (ERROR!)"; - pngtest_error_parameters *test = - (pngtest_error_parameters*)png_get_error_ptr(png_ptr); - - ++warning_count; - - if (test != NULL && test->file_name != NULL) - name = test->file_name; - - fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message); -} - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static void PNGCBAPI -pngtest_error(png_structp png_ptr, png_const_charp message) -{ - ++error_count; - - pngtest_warning(png_ptr, message); - /* We can return because png_error calls the default handler, which is - * actually OK in this case. - */ -} - -/* END of code to validate stdio-free compilation */ - -/* START of code to validate memory allocation and deallocation */ -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more than 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - * - * This piece of code can be compiled to validate max 64K allocations - * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. - */ -typedef struct memory_information -{ - png_alloc_size_t size; - png_voidp pointer; - struct memory_information *next; -} memory_information; -typedef memory_information *memory_infop; - -static memory_infop pinformation = NULL; -static int current_allocation = 0; -static int maximum_allocation = 0; -static int total_allocation = 0; -static int num_allocations = 0; - -png_voidp PNGCBAPI png_debug_malloc(png_structp png_ptr, - png_alloc_size_t size); -void PNGCBAPI png_debug_free(png_structp png_ptr, png_voidp ptr); - -png_voidp -PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) -{ - - /* png_malloc has already tested for NULL; png_create_struct calls - * png_debug_malloc directly, with png_ptr == NULL which is OK - */ - - if (size == 0) - return NULL; - - /* This calls the library allocator twice, once to get the requested - buffer and once to get a new free list entry. */ - { - /* Disable malloc_fn and free_fn */ - memory_infop pinfo; - png_set_mem_fn(png_ptr, NULL, NULL, NULL); - pinfo = (memory_infop)png_malloc(png_ptr, - (sizeof *pinfo)); - pinfo->size = size; - current_allocation += size; - total_allocation += size; - ++num_allocations; - - if (current_allocation > maximum_allocation) - maximum_allocation = current_allocation; - - pinfo->pointer = png_malloc(png_ptr, size); - /* Restore malloc_fn and free_fn */ - - png_set_mem_fn(png_ptr, - NULL, png_debug_malloc, png_debug_free); - - if (size != 0 && pinfo->pointer == NULL) - { - current_allocation -= size; - total_allocation -= size; - png_error(png_ptr, - "out of memory in pngtest->png_debug_malloc"); - } - - pinfo->next = pinformation; - pinformation = pinfo; - /* Make sure the caller isn't assuming zeroed memory. */ - memset(pinfo->pointer, 0xdd, pinfo->size); - - if (verbose != 0) - printf("png_malloc %lu bytes at %p\n", (unsigned long)size, - pinfo->pointer); - - return (png_voidp)pinfo->pointer; - } -} - -/* Free a pointer. It is removed from the list at the same time. */ -void PNGCBAPI -png_debug_free(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL) - fprintf(STDERR, "NULL pointer to png_debug_free.\n"); - - if (ptr == 0) - { -#if 0 /* This happens all the time. */ - fprintf(STDERR, "WARNING: freeing NULL pointer\n"); -#endif - return; - } - - /* Unlink the element from the list. */ - if (pinformation != NULL) - { - memory_infop *ppinfo = &pinformation; - - for (;;) - { - memory_infop pinfo = *ppinfo; - - if (pinfo->pointer == ptr) - { - *ppinfo = pinfo->next; - current_allocation -= pinfo->size; - if (current_allocation < 0) - fprintf(STDERR, "Duplicate free of memory\n"); - /* We must free the list element too, but first kill - the memory that is to be freed. */ - memset(ptr, 0x55, pinfo->size); - free(pinfo); - pinfo = NULL; - break; - } - - if (pinfo->next == NULL) - { - fprintf(STDERR, "Pointer %p not found\n", ptr); - break; - } - - ppinfo = &pinfo->next; - } - } - - /* Finally free the data. */ - if (verbose != 0) - printf("Freeing %p\n", ptr); - - if (ptr != NULL) - free(ptr); - ptr = NULL; -} -#endif /* USER_MEM && DEBUG */ -/* END of code to test memory allocation/deallocation */ - - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -/* Demonstration of user chunk support of the sTER and vpAg chunks */ - -/* (sTER is a public chunk not yet known by libpng. vpAg is a private -chunk used in ImageMagick to store "virtual page" size). */ - -typedef struct user_chunk_info_def -{ - png_const_infop info_ptr; - png_uint_32 vpAg_width, vpAg_height; - png_byte vpAg_units; - png_byte sTER_mode; - int location[2]; -} user_chunk_info; - -/* Used for location and order; zero means nothing. */ -#define have_sTER 0x01 -#define have_vpAg 0x02 -#define before_PLTE 0x10 -#define before_IDAT 0x20 -#define after_IDAT 0x40 - -static void -init_user_chunk_info(png_const_infop info_ptr, user_chunk_info *chunk_data) -{ - memset(chunk_data, 0, sizeof(*chunk_data)); - chunk_data->info_ptr = info_ptr; -} - -static int -set_chunk_location(png_structp png_ptr, user_chunk_info *chunk_data, int what) -{ - int location; - - if ((chunk_data->location[0] & what) != 0 || - (chunk_data->location[1] & what) != 0) - return 0; /* we already have one of these */ - - /* Find where we are (the code below zeroes info_ptr to indicate that the - * chunks before the first IDAT have been read.) - */ - if (chunk_data->info_ptr == NULL) /* after IDAT */ - location = what | after_IDAT; - - else if (png_get_valid(png_ptr, chunk_data->info_ptr, PNG_INFO_PLTE) != 0) - location = what | before_IDAT; - - else - location = what | before_PLTE; - - if (chunk_data->location[0] == 0) - chunk_data->location[0] = location; - - else - chunk_data->location[1] = location; - - return 1; /* handled */ -} - -static int PNGCBAPI -read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) -{ - user_chunk_info *my_user_chunk_data = - (user_chunk_info*)png_get_user_chunk_ptr(png_ptr); - - if (my_user_chunk_data == NULL) - png_error(png_ptr, "lost pointer to user chunk data"); - - /* Return one of the following: - * return -n; chunk had an error - * return 0; did not recognize - * return n; success - * - * The unknown chunk structure contains the chunk data: - * png_byte name[5]; - * png_byte *data; - * size_t size; - * - * Note that libpng has already taken care of the CRC handling. - */ - - if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ - chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ - { - /* Found sTER chunk */ - if (chunk->size != 1) - return -1; /* Error return */ - - if (chunk->data[0] != 0 && chunk->data[0] != 1) - return -1; /* Invalid mode */ - - if (set_chunk_location(png_ptr, my_user_chunk_data, have_sTER) != 0) - { - my_user_chunk_data->sTER_mode = chunk->data[0]; - return 1; - } - - else - return 0; /* duplicate sTER - give it to libpng */ - } - - if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ - chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ - return 0; /* Did not recognize */ - - /* Found ImageMagick vpAg chunk */ - - if (chunk->size != 9) - return -1; /* Error return */ - - if (set_chunk_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) - return 0; /* duplicate vpAg */ - - my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); - my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); - my_user_chunk_data->vpAg_units = chunk->data[8]; - - return 1; -} - -#ifdef PNG_WRITE_SUPPORTED -static void -write_sTER_chunk(png_structp write_ptr, user_chunk_info *data) -{ - png_byte sTER[5] = {115, 84, 69, 82, '\0'}; - - if (verbose != 0) - fprintf(STDERR, "\n stereo mode = %d\n", data->sTER_mode); - - png_write_chunk(write_ptr, sTER, &data->sTER_mode, 1); -} - -static void -write_vpAg_chunk(png_structp write_ptr, user_chunk_info *data) -{ - png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; - - png_byte vpag_chunk_data[9]; - - if (verbose != 0) - fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", - (unsigned long)data->vpAg_width, - (unsigned long)data->vpAg_height, - data->vpAg_units); - - png_save_uint_32(vpag_chunk_data, data->vpAg_width); - png_save_uint_32(vpag_chunk_data + 4, data->vpAg_height); - vpag_chunk_data[8] = data->vpAg_units; - png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); -} - -static void -write_chunks(png_structp write_ptr, user_chunk_info *data, int location) -{ - int i; - - /* Notice that this preserves the original chunk order, however chunks - * intercepted by the callback will be written *after* chunks passed to - * libpng. This will actually reverse a pair of sTER chunks or a pair of - * vpAg chunks, resulting in an error later. This is not worth worrying - * about - the chunks should not be duplicated! - */ - for (i = 0; i < 2; ++i) - { - if (data->location[i] == (location | have_sTER)) - write_sTER_chunk(write_ptr, data); - - else if (data->location[i] == (location | have_vpAg)) - write_vpAg_chunk(write_ptr, data); - } -} -#endif /* WRITE */ -#else /* !READ_USER_CHUNKS */ -# define write_chunks(pp,loc) ((void)0) -#endif -/* END of code to demonstrate user chunk support */ - -/* START of code to check that libpng has the required text support; this only - * checks for the write support because if read support is missing the chunk - * will simply not be reported back to pngtest. - */ -#ifdef PNG_TEXT_SUPPORTED -static void -pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr, - int num_text) -{ - while (num_text > 0) - { - switch (text_ptr[--num_text].compression) - { - case PNG_TEXT_COMPRESSION_NONE: - break; - - case PNG_TEXT_COMPRESSION_zTXt: -# ifndef PNG_WRITE_zTXt_SUPPORTED - ++unsupported_chunks; - /* In libpng 1.7 this now does an app-error, so stop it: */ - text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; -# endif - break; - - case PNG_ITXT_COMPRESSION_NONE: - case PNG_ITXT_COMPRESSION_zTXt: -# ifndef PNG_WRITE_iTXt_SUPPORTED - ++unsupported_chunks; - text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; -# endif - break; - - default: - /* This is an error */ - png_error(png_ptr, "invalid text chunk compression field"); - break; - } - } -} -#endif -/* END of code to check that libpng has the required text support */ - -/* Test one file */ -static int -test_one_file(const char *inname, const char *outname) -{ - static png_FILE_p fpin; - static png_FILE_p fpout; /* "static" prevents setjmp corruption */ - pngtest_error_parameters error_parameters; - png_structp read_ptr; - png_infop read_info_ptr, end_info_ptr; -#ifdef PNG_WRITE_SUPPORTED - png_structp write_ptr; - png_infop write_info_ptr; - png_infop write_end_info_ptr; -#ifdef PNG_WRITE_FILTER_SUPPORTED - int interlace_preserved = 1; -#endif /* WRITE_FILTER */ -#else /* !WRITE */ - png_structp write_ptr = NULL; - png_infop write_info_ptr = NULL; - png_infop write_end_info_ptr = NULL; -#endif /* !WRITE */ - png_bytep row_buf; - png_uint_32 y; - png_uint_32 width, height; - int bit_depth, color_type; - user_chunk_info my_user_chunk_data; - int pass, num_passes; - - row_buf = NULL; - error_parameters.file_name = inname; - - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find input file %s\n", inname); - return 1; - } - - if ((fpout = fopen(outname, "wb")) == NULL) - { - fprintf(STDERR, "Could not open output file %s\n", outname); - fclose(fpin); - return 1; - } - - pngtest_debug("Allocating read and write structures"); -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - read_ptr = - png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - read_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - png_set_error_fn(read_ptr, &error_parameters, pngtest_error, - pngtest_warning); - -#ifdef PNG_WRITE_SUPPORTED -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - write_ptr = - png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - write_ptr = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - png_set_error_fn(write_ptr, &error_parameters, pngtest_error, - pngtest_warning); -#endif - pngtest_debug("Allocating read_info, write_info and end_info structures"); - read_info_ptr = png_create_info_struct(read_ptr); - end_info_ptr = png_create_info_struct(read_ptr); -#ifdef PNG_WRITE_SUPPORTED - write_info_ptr = png_create_info_struct(write_ptr); - write_end_info_ptr = png_create_info_struct(write_ptr); -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - init_user_chunk_info(read_info_ptr, &my_user_chunk_data); - png_set_read_user_chunk_fn(read_ptr, &my_user_chunk_data, - read_user_chunk_callback); -#endif - -#ifdef PNG_SETJMP_SUPPORTED - pngtest_debug("Setting jmpbuf for read struct"); - if (setjmp(png_jmpbuf(read_ptr))) - { - fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); - png_free(read_ptr, row_buf); - row_buf = NULL; - if (verbose != 0) - fprintf(STDERR, " destroy read structs\n"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - if (verbose != 0) - fprintf(STDERR, " destroy write structs\n"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - fclose(fpin); - fclose(fpout); - return 1; - } - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Setting jmpbuf for write struct"); - - if (setjmp(png_jmpbuf(write_ptr))) - { - fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); - png_free(read_ptr, row_buf); - row_buf = NULL; - if (verbose != 0) - fprintf(STDERR, " destroying read structs\n"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); - if (verbose != 0) - fprintf(STDERR, " destroying write structs\n"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_destroy_write_struct(&write_ptr, &write_info_ptr); - fclose(fpin); - fclose(fpout); - return 1; - } -#endif -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED - if (strict != 0) - { - /* Treat png_benign_error() as errors on read */ - png_set_benign_errors(read_ptr, 0); - -# ifdef PNG_WRITE_SUPPORTED - /* Treat them as errors on write */ - png_set_benign_errors(write_ptr, 0); -# endif - - /* if strict is not set, then app warnings and errors are treated as - * warnings in release builds, but not in unstable builds; this can be - * changed with '--relaxed'. - */ - } - - else if (relaxed != 0) - { - /* Allow application (pngtest) errors and warnings to pass */ - png_set_benign_errors(read_ptr, 1); - - /* Turn off CRC checking while reading */ - png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - -#ifdef PNG_IGNORE_ADLER32 - /* Turn off ADLER32 checking while reading */ - png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON); -#endif - -# ifdef PNG_WRITE_SUPPORTED - png_set_benign_errors(write_ptr, 1); -# endif - - } -#endif /* BENIGN_ERRORS */ - - pngtest_debug("Initializing input and output streams"); -#ifdef PNG_STDIO_SUPPORTED - png_init_io(read_ptr, fpin); -# ifdef PNG_WRITE_SUPPORTED - png_init_io(write_ptr, fpout); -# endif -#else - png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); -# ifdef PNG_WRITE_SUPPORTED - png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, -# ifdef PNG_WRITE_FLUSH_SUPPORTED - pngtest_flush); -# else - NULL); -# endif -# endif -#endif - - if (status_dots_requested == 1) - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, write_row_callback); -#endif - png_set_read_status_fn(read_ptr, read_row_callback); - } - - else - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, NULL); -#endif - png_set_read_status_fn(read_ptr, NULL); - } - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_set_read_user_transform_fn(read_ptr, read_user_callback); -#endif -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - zero_samples = 0; - png_set_write_user_transform_fn(write_ptr, count_zero_samples); -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - /* Preserve all the unknown chunks, if possible. If this is disabled, then - * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use - * libpng to *save* the unknown chunks on read (because we can't switch the - * save option on!) - * - * Notice that if SET_UNKNOWN_CHUNKS is *not* supported, the reader will - * discard all unknown chunks, and the writer will write them all. - */ -#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#endif - - pngtest_debug("Reading info struct"); - png_read_info(read_ptr, read_info_ptr); - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* This is a bit of a hack; there is no obvious way in the callback function - * to determine that the chunks before the first IDAT have been read, so - * remove the info_ptr (which is only used to determine position relative to - * PLTE) here to indicate that we are after the IDAT. - */ - my_user_chunk_data.info_ptr = NULL; -#endif - - pngtest_debug("Transferring info struct"); - { - int interlace_type, compression_type, filter_type; - - if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, - &color_type, &interlace_type, &compression_type, &filter_type) != 0) - { - png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); - /* num_passes may not be available below if interlace support is not - * provided by libpng for both read and write. - */ - switch (interlace_type) - { - case PNG_INTERLACE_NONE: - num_passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - num_passes = 7; - break; - - default: - png_error(read_ptr, "invalid interlace type"); - /*NOT REACHED*/ - } - } - - else - png_error(read_ptr, "png_get_IHDR failed"); - } -#ifdef PNG_FIXED_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - png_fixed_point gamma; - - if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); - } -#endif -#else /* Use floating point versions */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - double gamma; - - if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA(write_ptr, write_info_ptr, gamma); - } -#endif -#endif /* Floating point */ -#endif /* Fixed point */ -#ifdef PNG_iCCP_SUPPORTED - { - png_charp name; - png_bytep profile; - png_uint_32 proflen; - int compression_type; - - if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen) != 0) - { - png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, - profile, proflen); - } - } -#endif -#ifdef PNG_sRGB_SUPPORTED - { - int intent; - - if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) - png_set_sRGB(write_ptr, write_info_ptr, intent); - } -#endif - { - png_colorp palette; - int num_palette; - - if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) - png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); - } -#ifdef PNG_bKGD_SUPPORTED - { - png_color_16p background; - - if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) - png_set_bKGD(write_ptr, write_info_ptr, background); - } -#endif -#ifdef PNG_READ_eXIf_SUPPORTED - { - png_bytep exif = NULL; - png_uint_32 exif_length; - - if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0) - { - if (exif_length > 1) - fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1], - (unsigned long)exif_length); -# ifdef PNG_WRITE_eXIf_SUPPORTED - png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif); -# endif - } - } -#endif -#ifdef PNG_hIST_SUPPORTED - { - png_uint_16p hist; - - if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) - png_set_hIST(write_ptr, write_info_ptr, hist); - } -#endif -#ifdef PNG_oFFs_SUPPORTED - { - png_int_32 offset_x, offset_y; - int unit_type; - - if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, - &unit_type) != 0) - png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); - } -#endif -#ifdef PNG_pCAL_SUPPORTED - { - png_charp purpose, units; - png_charpp params; - png_int_32 X0, X1; - int type, nparams; - - if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms) != 0) - png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, - nparams, units, params); - } -#endif -#ifdef PNG_pHYs_SUPPORTED - { - png_uint_32 res_x, res_y; - int unit_type; - - if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, - &unit_type) != 0) - png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); - } -#endif -#ifdef PNG_sBIT_SUPPORTED - { - png_color_8p sig_bit; - - if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) - png_set_sBIT(write_ptr, write_info_ptr, sig_bit); - } -#endif -#ifdef PNG_sCAL_SUPPORTED -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - { - int unit; - double scal_width, scal_height; - - if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) - png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - { - int unit; - png_charp scal_width, scal_height; - - if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) - { - png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, - scal_height); - } - } -#endif -#endif -#endif - -#ifdef PNG_sPLT_SUPPORTED - { - png_sPLT_tp entries; - - int num_entries = png_get_sPLT(read_ptr, read_info_ptr, &entries); - if (num_entries != 0) - png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries); - } -#endif - -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - pngtest_check_text_support(read_ptr, text_ptr, num_text); - - if (verbose != 0) - { - int i; - - fprintf(STDERR,"\n"); - for (i = 0; i < num_text; i++) - { - fprintf(STDERR," Text compression[%d]=%d\n", - i, text_ptr[i].compression); - } - } - - png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); - } - } -#endif -#ifdef PNG_tIME_SUPPORTED - { - png_timep mod_time; - - if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0) - { - png_set_tIME(write_ptr, write_info_ptr, mod_time); -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) - tIME_string[(sizeof tIME_string) - 1] = '\0'; - - else - { - strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string)); - tIME_string[(sizeof tIME_string) - 1] = '\0'; - } - - tIME_chunk_present++; -#endif /* TIME_RFC1123 */ - } - } -#endif -#ifdef PNG_tRNS_SUPPORTED - { - png_bytep trans_alpha; - int num_trans; - png_color_16p trans_color; - - if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, - &trans_color) != 0) - { - int sample_max = (1 << bit_depth); - /* libpng doesn't reject a tRNS chunk with out-of-range samples */ - if (!((color_type == PNG_COLOR_TYPE_GRAY && - (int)trans_color->gray > sample_max) || - (color_type == PNG_COLOR_TYPE_RGB && - ((int)trans_color->red > sample_max || - (int)trans_color->green > sample_max || - (int)trans_color->blue > sample_max)))) - png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, - trans_color); - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, - &unknowns); - - if (num_unknowns != 0) - png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, - num_unknowns); - } -#endif - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Writing info struct"); - - /* Write the info in two steps so that if we write the 'unknown' chunks here - * they go to the correct place. - */ - png_write_info_before_PLTE(write_ptr, write_info_ptr); - - write_chunks(write_ptr, &my_user_chunk_data, before_PLTE); /* before PLTE */ - - png_write_info(write_ptr, write_info_ptr); - - write_chunks(write_ptr, &my_user_chunk_data, before_IDAT); /* after PLTE */ - - png_write_info(write_ptr, write_end_info_ptr); - - write_chunks(write_ptr, &my_user_chunk_data, after_IDAT); /* after IDAT */ - -#ifdef PNG_COMPRESSION_COMPAT - /* Test the 'compatibility' setting here, if it is available. */ - png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT); -#endif -#endif - - pngtest_debug("Writing row data"); - -#if defined(PNG_READ_INTERLACING_SUPPORTED) &&\ - defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* Both must be defined for libpng to be able to handle the interlace, - * otherwise it gets handled below by simply reading and writing the passes - * directly. - */ - if (png_set_interlace_handling(read_ptr) != num_passes) - png_error(write_ptr, - "png_set_interlace_handling(read): wrong pass count "); - if (png_set_interlace_handling(write_ptr) != num_passes) - png_error(write_ptr, - "png_set_interlace_handling(write): wrong pass count "); -#else /* png_set_interlace_handling not called on either read or write */ -# define calc_pass_height -#endif /* not using libpng interlace handling */ - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; -#endif - for (pass = 0; pass < num_passes; pass++) - { -# ifdef calc_pass_height - png_uint_32 pass_height; - - if (num_passes == 7) /* interlaced */ - { - if (PNG_PASS_COLS(width, pass) > 0) - pass_height = PNG_PASS_ROWS(height, pass); - - else - pass_height = 0; - } - - else /* not interlaced */ - pass_height = height; -# else -# define pass_height height -# endif - - pngtest_debug1("Writing row data for pass %d", pass); - for (y = 0; y < pass_height; y++) - { - pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); - - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug2("\t%p (%lu bytes)", row_buf, - (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); - - png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_decode += (t_stop - t_start); - t_start = t_stop; -#endif - png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_encode += (t_stop - t_start); - t_start = t_stop; -#endif -#endif /* WRITE */ - - pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); - png_free(read_ptr, row_buf); - row_buf = NULL; - } - } - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); -# endif -# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); -# endif -#endif - - pngtest_debug("Reading and writing end_info data"); - - png_read_end(read_ptr, end_info_ptr); -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - pngtest_check_text_support(read_ptr, text_ptr, num_text); - - if (verbose != 0) - { - int i; - - fprintf(STDERR,"\n"); - for (i = 0; i < num_text; i++) - { - fprintf(STDERR," Text compression[%d]=%d\n", - i, text_ptr[i].compression); - } - } - - png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); - } - } -#endif -#ifdef PNG_READ_eXIf_SUPPORTED - { - png_bytep exif = NULL; - png_uint_32 exif_length; - - if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0) - { - if (exif_length > 1) - fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1], - (unsigned long)exif_length); -# ifdef PNG_WRITE_eXIf_SUPPORTED - png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif); -# endif - } - } -#endif -#ifdef PNG_tIME_SUPPORTED - { - png_timep mod_time; - - if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0) - { - png_set_tIME(write_ptr, write_end_info_ptr, mod_time); -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) - tIME_string[(sizeof tIME_string) - 1] = '\0'; - - else - { - strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string); - tIME_string[(sizeof tIME_string)-1] = '\0'; - } - - tIME_chunk_present++; -#endif /* TIME_RFC1123 */ - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, - &unknowns); - - if (num_unknowns != 0) - png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, - num_unknowns); - } -#endif - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - /* Normally one would use Z_DEFAULT_STRATEGY for text compression. - * This is here just to make pngtest replicate the results from libpng - * versions prior to 1.5.4, and to test this new API. - */ - png_set_text_compression_strategy(write_ptr, Z_FILTERED); -#endif - - /* When the unknown vpAg/sTER chunks are written by pngtest the only way to - * do it is to write them *before* calling png_write_end. When unknown - * chunks are written by libpng, however, they are written just before IEND. - * There seems to be no way round this, however vpAg/sTER are not expected - * after IDAT. - */ - write_chunks(write_ptr, &my_user_chunk_data, after_IDAT); - - png_write_end(write_ptr, write_end_info_ptr); -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED - if (verbose != 0) - { - png_uint_32 iwidth, iheight; - iwidth = png_get_image_width(write_ptr, write_info_ptr); - iheight = png_get_image_height(write_ptr, write_info_ptr); - fprintf(STDERR, "\n Image width = %lu, height = %lu\n", - (unsigned long)iwidth, (unsigned long)iheight); - } -#endif - - pngtest_debug("Destroying data structs"); - pngtest_debug("Destroying read_ptr, read_info_ptr, end_info_ptr"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Destroying write_end_info_ptr"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - pngtest_debug("Destroying write_ptr, write_info_ptr"); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - pngtest_debug("Destruction complete."); - - fclose(fpin); - fclose(fpout); - - /* Summarize any warnings or errors and in 'strict' mode fail the test. - * Unsupported chunks can result in warnings, in that case ignore the strict - * setting, otherwise fail the test on warnings as well as errors. - */ - if (error_count > 0) - { - /* We don't really expect to get here because of the setjmp handling - * above, but this is safe. - */ - fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", - inname, error_count, warning_count); - - if (strict != 0) - return 1; - } - -# ifdef PNG_WRITE_SUPPORTED - /* If there is no write support nothing was written! */ - else if (unsupported_chunks > 0) - { - fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", - inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); - } -# endif - - else if (warning_count > 0) - { - fprintf(STDERR, "\n %s: %d libpng warnings found", - inname, warning_count); - - if (strict != 0) - return 1; - } - - pngtest_debug("Opening files for comparison"); - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", inname); - return 1; - } - - if ((fpout = fopen(outname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", outname); - fclose(fpin); - return 1; - } - -#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\ - defined (PNG_WRITE_FILTER_SUPPORTED) - if (interlace_preserved != 0) /* else the files will be changed */ - { - for (;;) - { - static int wrote_question = 0; - size_t num_in, num_out; - char inbuf[256], outbuf[256]; - - num_in = fread(inbuf, 1, sizeof inbuf, fpin); - num_out = fread(outbuf, 1, sizeof outbuf, fpout); - - if (num_in != num_out) - { - fprintf(STDERR, "\nFiles %s and %s are of a different size\n", - inname, outname); - - if (wrote_question == 0 && unsupported_chunks == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum IDAT" - " chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - fclose(fpin); - fclose(fpout); - - if (strict != 0 && unsupported_chunks == 0) - return 1; - - else - return 0; - } - - if (num_in == 0) - break; - - if (memcmp(inbuf, outbuf, num_in)) - { - fprintf(STDERR, "\nFiles %s and %s are different\n", inname, - outname); - - if (wrote_question == 0 && unsupported_chunks == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum" - " IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - fclose(fpin); - fclose(fpout); - - /* NOTE: the unsupported_chunks escape is permitted here because - * unsupported text chunk compression will result in the compression - * mode being changed (to NONE) yet, in the test case, the result - * can be exactly the same size! - */ - if (strict != 0 && unsupported_chunks == 0) - return 1; - - else - return 0; - } - } - } -#endif /* WRITE && WRITE_FILTER */ - - fclose(fpin); - fclose(fpout); - - return 0; -} - -/* Input and output filenames */ -#ifdef RISCOS -static const char *inname = "pngtest/png"; -static const char *outname = "pngout/png"; -#else -static const char *inname = "pngtest.png"; -static const char *outname = "pngout.png"; -#endif - -int -main(int argc, char *argv[]) -{ - int multiple = 0; - int ierror = 0; - - png_structp dummy_ptr; - - fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); - fprintf(STDERR, "%s", png_get_copyright(NULL)); - /* Show the version of libpng used in building the library */ - fprintf(STDERR, " library (%lu):%s", - (unsigned long)png_access_version_number(), - png_get_header_version(NULL)); - - /* Show the version of libpng used in building the application */ - fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, - PNG_HEADER_VERSION_STRING); - - /* Do some consistency checking on the memory allocation settings, I'm - * not sure this matters, but it is nice to know, the first of these - * tests should be impossible because of the way the macros are set - * in pngconf.h - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); -#endif - /* I think the following can happen. */ -#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); -#endif - - if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING) != 0) - { - fprintf(STDERR, "Warning: mismatching versions of png.h and png.c\n"); - fprintf(STDERR, " png.h version string: %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " png.c version string: %s\n\n", png_libpng_ver); - ++ierror; - } - - if (argc > 1) - { - if (strcmp(argv[1], "-m") == 0) - { - multiple = 1; - status_dots_requested = 0; - } - - else if (strcmp(argv[1], "-mv") == 0 || - strcmp(argv[1], "-vm") == 0 ) - { - multiple = 1; - verbose = 1; - status_dots_requested = 1; - } - - else if (strcmp(argv[1], "-v") == 0) - { - verbose = 1; - status_dots_requested = 1; - inname = argv[2]; - } - - else if (strcmp(argv[1], "--strict") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict++; - relaxed = 0; - multiple = 1; - } - - else if (strcmp(argv[1], "--relaxed") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict = 0; - relaxed++; - multiple = 1; - } - else if (strcmp(argv[1], "--xfail") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict = 0; - xfail++; - relaxed++; - multiple = 1; - } - - else - { - inname = argv[1]; - status_dots_requested = 0; - } - } - - if (multiple == 0 && argc == 3 + verbose) - outname = argv[2 + verbose]; - - if ((multiple == 0 && argc > 3 + verbose) || - (multiple != 0 && argc < 2)) - { - fprintf(STDERR, - "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", - argv[0], argv[0]); - fprintf(STDERR, - " reads/writes one PNG file (without -m) or multiple files (-m)\n"); - fprintf(STDERR, - " with -m %s is used as a temporary file\n", outname); - exit(1); - } - - if (multiple != 0) - { - int i; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - for (i = 2; i < argc; ++i) - { - int kerror; - fprintf(STDERR, "\n Testing %s:", argv[i]); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - kerror = test_one_file(argv[i], outname); - if (kerror == 0) - { -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); - - tIME_chunk_present = 0; -#endif /* TIME_RFC1123 */ - } - - else - { - if (xfail) - fprintf(STDERR, " XFAIL\n"); - else - { - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, - pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - - else - { - int i; - for (i = 0; i < 3; ++i) - { - int kerror; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - if (i == 1) - status_dots_requested = 1; - - else if (verbose == 0) - status_dots_requested = 0; - - if (i == 0 || verbose == 1 || ierror != 0) - { - fprintf(STDERR, "\n Testing %s:", inname); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - } - - kerror = test_one_file(inname, outname); - - if (kerror == 0) - { - if (verbose == 1 || i == 2) - { -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); -#endif /* TIME_RFC1123 */ - } - } - - else - { - if (verbose == 0 && i != 2) - { - fprintf(STDERR, "\n Testing %s:", inname); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - } - - if (xfail) - fprintf(STDERR, " XFAIL\n"); - else - { - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; - fprintf(STDERR, " CPU time used = %.3f seconds", - (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " (decoding %.3f,\n", - t_decode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " encoding %.3f ,", - t_encode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " other %.3f seconds)\n\n", - t_misc/(float)CLOCKS_PER_SEC); -#endif - - if (ierror == 0) - fprintf(STDERR, " libpng passes test\n"); - - else - fprintf(STDERR, " libpng FAILS test\n"); - - dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - fprintf(STDERR, " Default limits:\n"); - fprintf(STDERR, " width_max = %lu\n", - (unsigned long) png_get_user_width_max(dummy_ptr)); - fprintf(STDERR, " height_max = %lu\n", - (unsigned long) png_get_user_height_max(dummy_ptr)); - if (png_get_chunk_cache_max(dummy_ptr) == 0) - fprintf(STDERR, " cache_max = unlimited\n"); - else - fprintf(STDERR, " cache_max = %lu\n", - (unsigned long) png_get_chunk_cache_max(dummy_ptr)); - if (png_get_chunk_malloc_max(dummy_ptr) == 0) - fprintf(STDERR, " malloc_max = unlimited\n"); - else - fprintf(STDERR, " malloc_max = %lu\n", - (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); - png_destroy_read_struct(&dummy_ptr, NULL, NULL); - - return (ierror != 0); -} -#else -int -main(void) -{ - fprintf(STDERR, - " test ignored because libpng was not built with read support\n"); - /* And skip this test */ - return SKIP; -} -#endif diff --git a/thirdparty/libpng/upstream/pngtrans.c b/thirdparty/libpng/upstream/pngtrans.c index 72642a75b..32a5fd3c0 100644 --- a/thirdparty/libpng/upstream/pngtrans.c +++ b/thirdparty/libpng/upstream/pngtrans.c @@ -1,868 +1,895 @@ - -/* pngtrans.c - transforms the data in a row (used by both readers and writers) - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Turn on BGR-to-RGB mapping */ -void PNGAPI -png_set_bgr(png_structrp png_ptr) -{ - png_debug(1, "in png_set_bgr"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_BGR; -} -#endif - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Turn on 16-bit byte swapping */ -void PNGAPI -png_set_swap(png_structrp png_ptr) -{ - png_debug(1, "in png_set_swap"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth == 16) - png_ptr->transformations |= PNG_SWAP_BYTES; -} -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Turn on pixel packing */ -void PNGAPI -png_set_packing(png_structrp png_ptr) -{ - png_debug(1, "in png_set_packing"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth < 8) - { - png_ptr->transformations |= PNG_PACK; -# ifdef PNG_WRITE_SUPPORTED - png_ptr->usr_bit_depth = 8; -# endif - } -} -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Turn on packed pixel swapping */ -void PNGAPI -png_set_packswap(png_structrp png_ptr) -{ - png_debug(1, "in png_set_packswap"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth < 8) - png_ptr->transformations |= PNG_PACKSWAP; -} -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -void PNGAPI -png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) -{ - png_debug(1, "in png_set_shift"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SHIFT; - png_ptr->shift = *true_bits; -} -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -int PNGAPI -png_set_interlace_handling(png_structrp png_ptr) -{ - png_debug(1, "in png_set_interlace handling"); - - if (png_ptr != 0 && png_ptr->interlaced != 0) - { - png_ptr->transformations |= PNG_INTERLACE; - return 7; - } - - return 1; -} -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte on read, or remove a filler or alpha byte on write. - * The filler type has changed in v0.95 to allow future 2-byte fillers - * for 48-bit input data, as well as to avoid problems with some compilers - * that don't like bytes as parameters. - */ -void PNGAPI -png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) -{ - png_debug(1, "in png_set_filler"); - - if (png_ptr == NULL) - return; - - /* In libpng 1.6 it is possible to determine whether this is a read or write - * operation and therefore to do more checking here for a valid call. - */ - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { -# ifdef PNG_READ_FILLER_SUPPORTED - /* On read png_set_filler is always valid, regardless of the base PNG - * format, because other transformations can give a format where the - * filler code can execute (basically an 8 or 16-bit component RGB or G - * format.) - * - * NOTE: usr_channels is not used by the read code! (This has led to - * confusion in the past.) The filler is only used in the read code. - */ - png_ptr->filler = (png_uint_16)filler; -# else - png_app_error(png_ptr, "png_set_filler not supported on read"); - PNG_UNUSED(filler) /* not used in the write case */ - return; -# endif - } - - else /* write */ - { -# ifdef PNG_WRITE_FILLER_SUPPORTED - /* On write the usr_channels parameter must be set correctly at the - * start to record the number of channels in the app-supplied data. - */ - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_RGB: - png_ptr->usr_channels = 4; - break; - - case PNG_COLOR_TYPE_GRAY: - if (png_ptr->bit_depth >= 8) - { - png_ptr->usr_channels = 2; - break; - } - - else - { - /* There simply isn't any code in libpng to strip out bits - * from bytes when the components are less than a byte in - * size! - */ - png_app_error(png_ptr, - "png_set_filler is invalid for" - " low bit depth gray output"); - return; - } - - default: - png_app_error(png_ptr, - "png_set_filler: inappropriate color type"); - return; - } -# else - png_app_error(png_ptr, "png_set_filler not supported on write"); - return; -# endif - } - - /* Here on success - libpng supports the operation, set the transformation - * and the flag to say where the filler channel is. - */ - png_ptr->transformations |= PNG_FILLER; - - if (filler_loc == PNG_FILLER_AFTER) - png_ptr->flags |= PNG_FLAG_FILLER_AFTER; - - else - png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; -} - -/* Added to libpng-1.2.7 */ -void PNGAPI -png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) -{ - png_debug(1, "in png_set_add_alpha"); - - if (png_ptr == NULL) - return; - - png_set_filler(png_ptr, filler, filler_loc); - /* The above may fail to do anything. */ - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_ptr->transformations |= PNG_ADD_ALPHA; -} - -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -void PNGAPI -png_set_swap_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_swap_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SWAP_ALPHA; -} -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -void PNGAPI -png_set_invert_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_invert_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_INVERT_ALPHA; -} -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -void PNGAPI -png_set_invert_mono(png_structrp png_ptr) -{ - png_debug(1, "in png_set_invert_mono"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_INVERT_MONO; -} - -/* Invert monochrome grayscale data */ -void /* PRIVATE */ -png_do_invert(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_invert"); - - /* This test removed from libpng version 1.0.13 and 1.2.0: - * if (row_info->bit_depth == 1 && - */ - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - png_bytep rp = row; - size_t i; - size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(~(*rp)); - rp++; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - row_info->bit_depth == 8) - { - png_bytep rp = row; - size_t i; - size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i += 2) - { - *rp = (png_byte)(~(*rp)); - rp += 2; - } - } - -#ifdef PNG_16BIT_SUPPORTED - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - row_info->bit_depth == 16) - { - png_bytep rp = row; - size_t i; - size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i += 4) - { - *rp = (png_byte)(~(*rp)); - *(rp + 1) = (png_byte)(~(*(rp + 1))); - rp += 4; - } - } -#endif -} -#endif - -#ifdef PNG_16BIT_SUPPORTED -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swaps byte order on 16-bit depth images */ -void /* PRIVATE */ -png_do_swap(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_swap"); - - if (row_info->bit_depth == 16) - { - png_bytep rp = row; - png_uint_32 i; - png_uint_32 istop= row_info->width * row_info->channels; - - for (i = 0; i < istop; i++, rp += 2) - { -#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED - /* Feature added to libpng-1.6.11 for testing purposes, not - * enabled by default. - */ - *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp); -#else - png_byte t = *rp; - *rp = *(rp + 1); - *(rp + 1) = t; -#endif - } - } -} -#endif -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -static const png_byte onebppswaptable[256] = { - 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, - 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, - 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, - 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, - 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, - 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, - 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, - 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, - 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, - 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, - 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, - 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, - 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, - 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, - 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, - 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, - 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, - 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, - 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, - 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, - 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, - 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, - 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, - 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, - 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, - 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, - 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, - 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, - 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, - 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, - 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF -}; - -static const png_byte twobppswaptable[256] = { - 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, - 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, - 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, - 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, - 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, - 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, - 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, - 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, - 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, - 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, - 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, - 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, - 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, - 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, - 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, - 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, - 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, - 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, - 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, - 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, - 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, - 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, - 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, - 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, - 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, - 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, - 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, - 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, - 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, - 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, - 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, - 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF -}; - -static const png_byte fourbppswaptable[256] = { - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, - 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, - 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, - 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, - 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, - 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, - 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, - 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, - 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, - 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, - 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, - 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, - 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, - 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, - 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, - 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, - 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, - 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, - 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, - 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, - 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, - 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, - 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, - 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, - 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, - 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, - 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, - 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, - 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, - 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, - 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, - 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF -}; - -/* Swaps pixel packing order within bytes */ -void /* PRIVATE */ -png_do_packswap(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_packswap"); - - if (row_info->bit_depth < 8) - { - png_bytep rp; - png_const_bytep end, table; - - end = row + row_info->rowbytes; - - if (row_info->bit_depth == 1) - table = onebppswaptable; - - else if (row_info->bit_depth == 2) - table = twobppswaptable; - - else if (row_info->bit_depth == 4) - table = fourbppswaptable; - - else - return; - - for (rp = row; rp < end; rp++) - *rp = table[*rp]; - } -} -#endif /* PACKSWAP || WRITE_PACKSWAP */ - -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -/* Remove a channel - this used to be 'png_do_strip_filler' but it used a - * somewhat weird combination of flags to determine what to do. All the calls - * to png_do_strip_filler are changed in 1.5.2 to call this instead with the - * correct arguments. - * - * The routine isn't general - the channel must be the channel at the start or - * end (not in the middle) of each pixel. - */ -void /* PRIVATE */ -png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) -{ - png_bytep sp = row; /* source pointer */ - png_bytep dp = row; /* destination pointer */ - png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ - - png_debug(1, "in png_do_strip_channel"); - - /* At the start sp will point to the first byte to copy and dp to where - * it is copied to. ep always points just beyond the end of the row, so - * the loop simply copies (channels-1) channels until sp reaches ep. - * - * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. - * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. - */ - - /* GA, GX, XG cases */ - if (row_info->channels == 2) - { - if (row_info->bit_depth == 8) - { - if (at_start != 0) /* Skip initial filler */ - ++sp; - else /* Skip initial channel and, for sp, the filler */ - { - sp += 2; ++dp; - } - - /* For a 1 pixel wide image there is nothing to do */ - while (sp < ep) - { - *dp++ = *sp; sp += 2; - } - - row_info->pixel_depth = 8; - } - - else if (row_info->bit_depth == 16) - { - if (at_start != 0) /* Skip initial filler */ - sp += 2; - else /* Skip initial channel and, for sp, the filler */ - { - sp += 4; dp += 2; - } - - while (sp < ep) - { - *dp++ = *sp++; *dp++ = *sp; sp += 3; - } - - row_info->pixel_depth = 16; - } - - else - return; /* bad bit depth */ - - row_info->channels = 1; - - /* Finally fix the color type if it records an alpha channel */ - if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - row_info->color_type = PNG_COLOR_TYPE_GRAY; - } - - /* RGBA, RGBX, XRGB cases */ - else if (row_info->channels == 4) - { - if (row_info->bit_depth == 8) - { - if (at_start != 0) /* Skip initial filler */ - ++sp; - else /* Skip initial channels and, for sp, the filler */ - { - sp += 4; dp += 3; - } - - /* Note that the loop adds 3 to dp and 4 to sp each time. */ - while (sp < ep) - { - *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2; - } - - row_info->pixel_depth = 24; - } - - else if (row_info->bit_depth == 16) - { - if (at_start != 0) /* Skip initial filler */ - sp += 2; - else /* Skip initial channels and, for sp, the filler */ - { - sp += 8; dp += 6; - } - - while (sp < ep) - { - /* Copy 6 bytes, skip 2 */ - *dp++ = *sp++; *dp++ = *sp++; - *dp++ = *sp++; *dp++ = *sp++; - *dp++ = *sp++; *dp++ = *sp; sp += 3; - } - - row_info->pixel_depth = 48; - } - - else - return; /* bad bit depth */ - - row_info->channels = 3; - - /* Finally fix the color type if it records an alpha channel */ - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - row_info->color_type = PNG_COLOR_TYPE_RGB; - } - - else - return; /* The filler channel has gone already */ - - /* Fix the rowbytes value. */ - row_info->rowbytes = (size_t)(dp-row); -} -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Swaps red and blue bytes within a pixel */ -void /* PRIVATE */ -png_do_bgr(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_bgr"); - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 3) - { - png_byte save = *rp; - *rp = *(rp + 2); - *(rp + 2) = save; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 4) - { - png_byte save = *rp; - *rp = *(rp + 2); - *(rp + 2) = save; - } - } - } - -#ifdef PNG_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 6) - { - png_byte save = *rp; - *rp = *(rp + 4); - *(rp + 4) = save; - save = *(rp + 1); - *(rp + 1) = *(rp + 5); - *(rp + 5) = save; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 8) - { - png_byte save = *rp; - *rp = *(rp + 4); - *(rp + 4) = save; - save = *(rp + 1); - *(rp + 1) = *(rp + 5); - *(rp + 5) = save; - } - } - } -#endif - } -} -#endif /* READ_BGR || WRITE_BGR */ - -#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ - defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) -/* Added at libpng-1.5.10 */ -void /* PRIVATE */ -png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_check_palette_indexes"); - - if (png_ptr->num_palette < (1 << row_info->bit_depth) && - png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ - { - /* Calculations moved outside switch in an attempt to stop different - * compiler warnings. 'padding' is in *bits* within the last byte, it is - * an 'int' because pixel_depth becomes an 'int' in the expression below, - * and this calculation is used because it avoids warnings that other - * forms produced on either GCC or MSVC. - */ - int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); - png_bytep rp = png_ptr->row_buf + row_info->rowbytes; - - switch (row_info->bit_depth) - { - case 1: - { - /* in this case, all bytes must be 0 so we don't need - * to unpack the pixels except for the rightmost one. - */ - for (; rp > png_ptr->row_buf; rp--) - { - if ((*rp >> padding) != 0) - png_ptr->num_palette_max = 1; - padding = 0; - } - - break; - } - - case 2: - { - for (; rp > png_ptr->row_buf; rp--) - { - int i = ((*rp >> padding) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 2) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 4) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 6) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - padding = 0; - } - - break; - } - - case 4: - { - for (; rp > png_ptr->row_buf; rp--) - { - int i = ((*rp >> padding) & 0x0f); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 4) & 0x0f); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - padding = 0; - } - - break; - } - - case 8: - { - for (; rp > png_ptr->row_buf; rp--) - { - if (*rp > png_ptr->num_palette_max) - png_ptr->num_palette_max = (int) *rp; - } - - break; - } - - default: - break; - } - } -} -#endif /* CHECK_FOR_INVALID_INDEX */ - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -void PNGAPI -png_set_user_transform_info(png_structrp png_ptr, png_voidp - user_transform_ptr, int user_transform_depth, int user_transform_channels) -{ - png_debug(1, "in png_set_user_transform_info"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) - { - png_app_error(png_ptr, - "info change after png_start_read_image or png_read_update_info"); - return; - } -#endif - - png_ptr->user_transform_ptr = user_transform_ptr; - png_ptr->user_transform_depth = (png_byte)user_transform_depth; - png_ptr->user_transform_channels = (png_byte)user_transform_channels; -} -#endif - -/* This function returns a pointer to the user_transform_ptr associated with - * the user transform functions. The application should free any memory - * associated with this pointer before png_write_destroy and png_read_destroy - * are called. - */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -png_voidp PNGAPI -png_get_user_transform_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return png_ptr->user_transform_ptr; -} -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -png_uint_32 PNGAPI -png_get_current_row_number(png_const_structrp png_ptr) -{ - /* See the comments in png.h - this is the sub-image row when reading an - * interlaced image. - */ - if (png_ptr != NULL) - return png_ptr->row_number; - - return PNG_UINT_32_MAX; /* help the app not to fail silently */ -} - -png_byte PNGAPI -png_get_current_pass_number(png_const_structrp png_ptr) -{ - if (png_ptr != NULL) - return png_ptr->pass; - return 8; /* invalid */ -} -#endif /* USER_TRANSFORM_INFO */ -#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ -#endif /* READ || WRITE */ +/* pngtrans.c - transforms the data in a row (used by both readers and writers) + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Turn on BGR-to-RGB mapping */ +void PNGAPI +png_set_bgr(png_structrp png_ptr) +{ + png_debug(1, "in png_set_bgr"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_BGR; +} +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Turn on 16-bit byte swapping */ +void PNGAPI +png_set_swap(png_structrp png_ptr) +{ + png_debug(1, "in png_set_swap"); + + if (png_ptr == NULL) + return; + + if (png_ptr->bit_depth == 16) + png_ptr->transformations |= PNG_SWAP_BYTES; +} +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Turn on pixel packing */ +void PNGAPI +png_set_packing(png_structrp png_ptr) +{ + png_debug(1, "in png_set_packing"); + + if (png_ptr == NULL) + return; + + if (png_ptr->bit_depth < 8) + { + png_ptr->transformations |= PNG_PACK; +# ifdef PNG_WRITE_SUPPORTED + png_ptr->usr_bit_depth = 8; +# endif + } +} +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Turn on packed pixel swapping */ +void PNGAPI +png_set_packswap(png_structrp png_ptr) +{ + png_debug(1, "in png_set_packswap"); + + if (png_ptr == NULL) + return; + + if (png_ptr->bit_depth < 8) + png_ptr->transformations |= PNG_PACKSWAP; +} +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +void PNGAPI +png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) +{ + png_debug(1, "in png_set_shift"); + + if (png_ptr == NULL || true_bits == NULL) + return; + + /* Check the shift values before passing them on to png_do_shift. */ + { + png_byte bit_depth = png_ptr->bit_depth; + int invalid = 0; + + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + if (true_bits->red == 0 || true_bits->red > bit_depth || + true_bits->green == 0 || true_bits->green > bit_depth || + true_bits->blue == 0 || true_bits->blue > bit_depth) + invalid = 1; + } + else + { + if (true_bits->gray == 0 || true_bits->gray > bit_depth) + invalid = 1; + } + + if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 && + (true_bits->alpha == 0 || true_bits->alpha > bit_depth)) + invalid = 1; + + if (invalid) + { + png_app_error(png_ptr, "png_set_shift: invalid shift values"); + return; + } + } + + png_ptr->transformations |= PNG_SHIFT; + png_ptr->shift = *true_bits; +} +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +int PNGAPI +png_set_interlace_handling(png_structrp png_ptr) +{ + png_debug(1, "in png_set_interlace handling"); + + if (png_ptr != 0 && png_ptr->interlaced != 0) + { + png_ptr->transformations |= PNG_INTERLACE; + return 7; + } + + return 1; +} +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte on read, or remove a filler or alpha byte on write. + * The filler type has changed in v0.95 to allow future 2-byte fillers + * for 48-bit input data, as well as to avoid problems with some compilers + * that don't like bytes as parameters. + */ +void PNGAPI +png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_filler"); + + if (png_ptr == NULL) + return; + + /* In libpng 1.6 it is possible to determine whether this is a read or write + * operation and therefore to do more checking here for a valid call. + */ + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) + { +# ifdef PNG_READ_FILLER_SUPPORTED + /* On read png_set_filler is always valid, regardless of the base PNG + * format, because other transformations can give a format where the + * filler code can execute (basically an 8 or 16-bit component RGB or G + * format.) + * + * NOTE: usr_channels is not used by the read code! (This has led to + * confusion in the past.) The filler is only used in the read code. + */ + png_ptr->filler = (png_uint_16)filler; +# else + png_app_error(png_ptr, "png_set_filler not supported on read"); + PNG_UNUSED(filler) /* not used in the write case */ + return; +# endif + } + + else /* write */ + { +# ifdef PNG_WRITE_FILLER_SUPPORTED + /* On write the usr_channels parameter must be set correctly at the + * start to record the number of channels in the app-supplied data. + */ + switch (png_ptr->color_type) + { + case PNG_COLOR_TYPE_RGB: + png_ptr->usr_channels = 4; + break; + + case PNG_COLOR_TYPE_GRAY: + if (png_ptr->bit_depth >= 8) + { + png_ptr->usr_channels = 2; + break; + } + + else + { + /* There simply isn't any code in libpng to strip out bits + * from bytes when the components are less than a byte in + * size! + */ + png_app_error(png_ptr, + "png_set_filler is invalid for" + " low bit depth gray output"); + return; + } + + default: + png_app_error(png_ptr, + "png_set_filler: inappropriate color type"); + return; + } +# else + png_app_error(png_ptr, "png_set_filler not supported on write"); + return; +# endif + } + + /* Here on success - libpng supports the operation, set the transformation + * and the flag to say where the filler channel is. + */ + png_ptr->transformations |= PNG_FILLER; + + if (filler_loc == PNG_FILLER_AFTER) + png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + + else + png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; +} + +/* Added to libpng-1.2.7 */ +void PNGAPI +png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) +{ + png_debug(1, "in png_set_add_alpha"); + + if (png_ptr == NULL) + return; + + png_set_filler(png_ptr, filler, filler_loc); + /* The above may fail to do anything. */ + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_ptr->transformations |= PNG_ADD_ALPHA; +} + +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +void PNGAPI +png_set_swap_alpha(png_structrp png_ptr) +{ + png_debug(1, "in png_set_swap_alpha"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_SWAP_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +void PNGAPI +png_set_invert_alpha(png_structrp png_ptr) +{ + png_debug(1, "in png_set_invert_alpha"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_INVERT_ALPHA; +} +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +void PNGAPI +png_set_invert_mono(png_structrp png_ptr) +{ + png_debug(1, "in png_set_invert_mono"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_INVERT_MONO; +} + +/* Invert monochrome grayscale data */ +void /* PRIVATE */ +png_do_invert(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_invert"); + + /* This test removed from libpng version 1.0.13 and 1.2.0: + * if (row_info->bit_depth == 1 && + */ + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + { + png_bytep rp = row; + size_t i; + size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i++) + { + *rp = (png_byte)(~(*rp)); + rp++; + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 8) + { + png_bytep rp = row; + size_t i; + size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i += 2) + { + *rp = (png_byte)(~(*rp)); + rp += 2; + } + } + +#ifdef PNG_16BIT_SUPPORTED + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 16) + { + png_bytep rp = row; + size_t i; + size_t istop = row_info->rowbytes; + + for (i = 0; i < istop; i += 4) + { + *rp = (png_byte)(~(*rp)); + *(rp + 1) = (png_byte)(~(*(rp + 1))); + rp += 4; + } + } +#endif +} +#endif + +#ifdef PNG_16BIT_SUPPORTED +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swaps byte order on 16-bit depth images */ +void /* PRIVATE */ +png_do_swap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_swap"); + + if (row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop= row_info->width * row_info->channels; + + for (i = 0; i < istop; i++, rp += 2) + { +#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED + /* Feature added to libpng-1.6.11 for testing purposes, not + * enabled by default. + */ + *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp); +#else + png_byte t = *rp; + *rp = *(rp + 1); + *(rp + 1) = t; +#endif + } + } +} +#endif +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) +static const png_byte onebppswaptable[256] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; + +static const png_byte twobppswaptable[256] = { + 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, + 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, + 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, + 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, + 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, + 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, + 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, + 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, + 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, + 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, + 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, + 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, + 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, + 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, + 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, + 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, + 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, + 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, + 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, + 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, + 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, + 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, + 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, + 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, + 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, + 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, + 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, + 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, + 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, + 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, + 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, + 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF +}; + +static const png_byte fourbppswaptable[256] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, + 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, + 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, + 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, + 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, + 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, + 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, + 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, + 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, + 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, + 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, + 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, + 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, + 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, + 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, + 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, + 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, + 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, + 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, + 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, + 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, + 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, + 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, + 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, + 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, + 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, + 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, + 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, + 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, + 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF +}; + +/* Swaps pixel packing order within bytes */ +void /* PRIVATE */ +png_do_packswap(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_packswap"); + + if (row_info->bit_depth < 8) + { + png_const_bytep table; + png_bytep rp; + png_bytep row_end = row + row_info->rowbytes; + + if (row_info->bit_depth == 1) + table = onebppswaptable; + + else if (row_info->bit_depth == 2) + table = twobppswaptable; + + else if (row_info->bit_depth == 4) + table = fourbppswaptable; + + else + return; + + for (rp = row; rp < row_end; rp++) + *rp = table[*rp]; + } +} +#endif /* PACKSWAP || WRITE_PACKSWAP */ + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +/* Remove a channel - this used to be 'png_do_strip_filler' but it used a + * somewhat weird combination of flags to determine what to do. All the calls + * to png_do_strip_filler are changed in 1.5.2 to call this instead with the + * correct arguments. + * + * The routine isn't general - the channel must be the channel at the start or + * end (not in the middle) of each pixel. + */ +void /* PRIVATE */ +png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) +{ + png_bytep sp = row; /* source pointer */ + png_bytep dp = row; /* destination pointer */ + png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ + + png_debug(1, "in png_do_strip_channel"); + + /* At the start sp will point to the first byte to copy and dp to where + * it is copied to. ep always points just beyond the end of the row, so + * the loop simply copies (channels-1) channels until sp reaches ep. + * + * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. + * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. + */ + + /* GA, GX, XG cases */ + if (row_info->channels == 2) + { + if (row_info->bit_depth == 8) + { + if (at_start != 0) /* Skip initial filler */ + ++sp; + else /* Skip initial channel and, for sp, the filler */ + { + sp += 2; ++dp; + } + + /* For a 1 pixel wide image there is nothing to do */ + while (sp < ep) + { + *dp++ = *sp; sp += 2; + } + + row_info->pixel_depth = 8; + } + + else if (row_info->bit_depth == 16) + { + if (at_start != 0) /* Skip initial filler */ + sp += 2; + else /* Skip initial channel and, for sp, the filler */ + { + sp += 4; dp += 2; + } + + while (sp < ep) + { + *dp++ = *sp++; *dp++ = *sp; sp += 3; + } + + row_info->pixel_depth = 16; + } + + else + return; /* bad bit depth */ + + row_info->channels = 1; + + /* Finally fix the color type if it records an alpha channel */ + if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + row_info->color_type = PNG_COLOR_TYPE_GRAY; + } + + /* RGBA, RGBX, XRGB cases */ + else if (row_info->channels == 4) + { + if (row_info->bit_depth == 8) + { + if (at_start != 0) /* Skip initial filler */ + ++sp; + else /* Skip initial channels and, for sp, the filler */ + { + sp += 4; dp += 3; + } + + /* Note that the loop adds 3 to dp and 4 to sp each time. */ + while (sp < ep) + { + *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2; + } + + row_info->pixel_depth = 24; + } + + else if (row_info->bit_depth == 16) + { + if (at_start != 0) /* Skip initial filler */ + sp += 2; + else /* Skip initial channels and, for sp, the filler */ + { + sp += 8; dp += 6; + } + + while (sp < ep) + { + /* Copy 6 bytes, skip 2 */ + *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp++; + *dp++ = *sp++; *dp++ = *sp; sp += 3; + } + + row_info->pixel_depth = 48; + } + + else + return; /* bad bit depth */ + + row_info->channels = 3; + + /* Finally fix the color type if it records an alpha channel */ + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + row_info->color_type = PNG_COLOR_TYPE_RGB; + } + + else + return; /* The filler channel has gone already */ + + /* Fix the rowbytes value. */ + row_info->rowbytes = (size_t)(dp-row); +} +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Swaps red and blue bytes within a pixel */ +void /* PRIVATE */ +png_do_bgr(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_bgr"); + + if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 3) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 4) + { + png_byte save = *rp; + *rp = *(rp + 2); + *(rp + 2) = save; + } + } + } + +#ifdef PNG_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 6) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + png_bytep rp; + png_uint_32 i; + + for (i = 0, rp = row; i < row_width; i++, rp += 8) + { + png_byte save = *rp; + *rp = *(rp + 4); + *(rp + 4) = save; + save = *(rp + 1); + *(rp + 1) = *(rp + 5); + *(rp + 5) = save; + } + } + } +#endif + } +} +#endif /* READ_BGR || WRITE_BGR */ + +#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ + defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) +/* Added at libpng-1.5.10 */ +void /* PRIVATE */ +png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) +{ + png_debug(1, "in png_do_check_palette_indexes"); + + if (png_ptr->num_palette < (1 << row_info->bit_depth) && + png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ + { + /* Calculations moved outside switch in an attempt to stop different + * compiler warnings. 'padding' is in *bits* within the last byte, it is + * an 'int' because pixel_depth becomes an 'int' in the expression below, + * and this calculation is used because it avoids warnings that other + * forms produced on either GCC or MSVC. + */ + int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; + + switch (row_info->bit_depth) + { + case 1: + { + /* in this case, all bytes must be 0 so we don't need + * to unpack the pixels except for the rightmost one. + */ + for (; rp > png_ptr->row_buf; rp--) + { + if ((*rp >> padding) != 0) + png_ptr->num_palette_max = 1; + padding = 0; + } + + break; + } + + case 2: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 2) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 6) & 0x03); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 4: + { + for (; rp > png_ptr->row_buf; rp--) + { + int i = ((*rp >> padding) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + i = (((*rp >> padding) >> 4) & 0x0f); + + if (i > png_ptr->num_palette_max) + png_ptr->num_palette_max = i; + + padding = 0; + } + + break; + } + + case 8: + { + for (; rp > png_ptr->row_buf; rp--) + { + if (*rp > png_ptr->num_palette_max) + png_ptr->num_palette_max = (int) *rp; + } + + break; + } + + default: + break; + } + } +} +#endif /* CHECK_FOR_INVALID_INDEX */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +void PNGAPI +png_set_user_transform_info(png_structrp png_ptr, png_voidp user_transform_ptr, + int user_transform_depth, int user_transform_channels) +{ + png_debug(1, "in png_set_user_transform_info"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && + (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) + { + png_app_error(png_ptr, + "info change after png_start_read_image or png_read_update_info"); + return; + } +#endif + + png_ptr->user_transform_ptr = user_transform_ptr; + png_ptr->user_transform_depth = (png_byte)user_transform_depth; + png_ptr->user_transform_channels = (png_byte)user_transform_channels; +} +#endif + +/* This function returns a pointer to the user_transform_ptr associated with + * the user transform functions. The application should free any memory + * associated with this pointer before png_write_destroy and png_read_destroy + * are called. + */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED +png_voidp PNGAPI +png_get_user_transform_ptr(png_const_structrp png_ptr) +{ + if (png_ptr == NULL) + return NULL; + + return png_ptr->user_transform_ptr; +} +#endif + +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED +png_uint_32 PNGAPI +png_get_current_row_number(png_const_structrp png_ptr) +{ + /* See the comments in png.h - this is the sub-image row when reading an + * interlaced image. + */ + if (png_ptr != NULL) + return png_ptr->row_number; + + return PNG_UINT_32_MAX; /* help the app not to fail silently */ +} + +png_byte PNGAPI +png_get_current_pass_number(png_const_structrp png_ptr) +{ + if (png_ptr != NULL) + return png_ptr->pass; + return 8; /* invalid */ +} +#endif /* USER_TRANSFORM_INFO */ +#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ +#endif /* READ || WRITE */ diff --git a/thirdparty/libpng/upstream/pngwio.c b/thirdparty/libpng/upstream/pngwio.c index b6adfd531..96a3187ff 100644 --- a/thirdparty/libpng/upstream/pngwio.c +++ b/thirdparty/libpng/upstream/pngwio.c @@ -1,168 +1,167 @@ - -/* pngwio.c - functions for data output - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all output. Users who need - * special handling are expected to write functions that have the same - * arguments as these and perform similar functions, but that possibly - * use different output methods. Note that you shouldn't change these - * functions, but rather write replacement functions and then change - * them at run time with png_set_write_fn(...). - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -/* Write the data to whatever output you are using. The default routine - * writes to a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered writes. This should never be asked - * to write more than 64K on a 16-bit machine. - */ - -void /* PRIVATE */ -png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length) -{ - /* NOTE: write_data_fn must not change the buffer! */ - if (png_ptr->write_data_fn != NULL ) - (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), - length); - - else - png_error(png_ptr, "Call to NULL write function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check; - - if (png_ptr == NULL) - return; - - check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Write Error"); -} -#endif - -/* This function is called to output any data pending writing (normally - * to disk). After png_flush is called, there should be no data pending - * writing in any buffers. - */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED -void /* PRIVATE */ -png_flush(png_structrp png_ptr) -{ - if (png_ptr->output_flush_fn != NULL) - (*(png_ptr->output_flush_fn))(png_ptr); -} - -# ifdef PNG_STDIO_SUPPORTED -void PNGCBAPI -png_default_flush(png_structp png_ptr) -{ - png_FILE_p io_ptr; - - if (png_ptr == NULL) - return; - - io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); - fflush(io_ptr); -} -# endif -#endif - -/* This function allows the application to supply new output functions for - * libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * png_ptr - pointer to a png output data structure - * io_ptr - pointer to user supplied structure containing info about - * the output functions. May be NULL. - * write_data_fn - pointer to a new output function that takes as its - * arguments a pointer to a png_struct, a pointer to - * data to be written, and a 32-bit unsigned int that is - * the number of bytes to be written. The new write - * function should call png_error(png_ptr, "Error msg") - * to exit and output any fatal error messages. May be - * NULL, in which case libpng's default function will - * be used. - * flush_data_fn - pointer to a new flush function that takes as its - * arguments a pointer to a png_struct. After a call to - * the flush function, there should be no data in any buffers - * or pending transmission. If the output method doesn't do - * any buffering of output, a function prototype must still be - * supplied although it doesn't have to do anything. If - * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile - * time, output_flush_fn will be ignored, although it must be - * supplied for compatibility. May be NULL, in which case - * libpng's default function will be used, if - * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not - * a good idea if io_ptr does not point to a standard - * *FILE structure. - */ -void PNGAPI -png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - -#ifdef PNG_STDIO_SUPPORTED - if (write_data_fn != NULL) - png_ptr->write_data_fn = write_data_fn; - - else - png_ptr->write_data_fn = png_default_write_data; -#else - png_ptr->write_data_fn = write_data_fn; -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED - - if (output_flush_fn != NULL) - png_ptr->output_flush_fn = output_flush_fn; - - else - png_ptr->output_flush_fn = png_default_flush; - -# else - png_ptr->output_flush_fn = output_flush_fn; -# endif -#else - PNG_UNUSED(output_flush_fn) -#endif /* WRITE_FLUSH */ - -#ifdef PNG_READ_SUPPORTED - /* It is an error to read while writing a png file */ - if (png_ptr->read_data_fn != NULL) - { - png_ptr->read_data_fn = NULL; - - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -#endif -} -#endif /* WRITE */ +/* pngwio.c - functions for data output + * + * Copyright (c) 2018-2025 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file provides a location for all output. Users who need + * special handling are expected to write functions that have the same + * arguments as these and perform similar functions, but that possibly + * use different output methods. Note that you shouldn't change these + * functions, but rather write replacement functions and then change + * them at run time with png_set_write_fn(...). + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +/* Write the data to whatever output you are using. The default routine + * writes to a file pointer. Note that this routine sometimes gets called + * with very small lengths, so you should implement some kind of simple + * buffering if you are using unbuffered writes. This should never be asked + * to write more than 64K on a 16-bit machine. + */ + +void /* PRIVATE */ +png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length) +{ + /* NOTE: write_data_fn must not change the buffer! */ + if (png_ptr->write_data_fn != NULL ) + (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), + length); + + else + png_error(png_ptr, "Call to NULL write function"); +} + +#ifdef PNG_STDIO_SUPPORTED +/* This is the function that does the actual writing of data. If you are + * not writing to a standard C stream, you should create a replacement + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ +void PNGCBAPI +png_default_write_data(png_structp png_ptr, png_bytep data, size_t length) +{ + size_t check; + + if (png_ptr == NULL) + return; + + check = fwrite(data, 1, length, (FILE *)png_ptr->io_ptr); + + if (check != length) + png_error(png_ptr, "Write Error"); +} +#endif + +/* This function is called to output any data pending writing (normally + * to disk). After png_flush is called, there should be no data pending + * writing in any buffers. + */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED +void /* PRIVATE */ +png_flush(png_structrp png_ptr) +{ + if (png_ptr->output_flush_fn != NULL) + (*(png_ptr->output_flush_fn))(png_ptr); +} + +# ifdef PNG_STDIO_SUPPORTED +void PNGCBAPI +png_default_flush(png_structp png_ptr) +{ + FILE *io_ptr; + + if (png_ptr == NULL) + return; + + io_ptr = png_voidcast(FILE *, png_ptr->io_ptr); + fflush(io_ptr); +} +# endif +#endif + +/* This function allows the application to supply new output functions for + * libpng if standard C streams aren't being used. + * + * This function takes as its arguments: + * png_ptr - pointer to a png output data structure + * io_ptr - pointer to user supplied structure containing info about + * the output functions. May be NULL. + * write_data_fn - pointer to a new output function that takes as its + * arguments a pointer to a png_struct, a pointer to + * data to be written, and a 32-bit unsigned int that is + * the number of bytes to be written. The new write + * function should call png_error(png_ptr, "Error msg") + * to exit and output any fatal error messages. May be + * NULL, in which case libpng's default function will + * be used. + * flush_data_fn - pointer to a new flush function that takes as its + * arguments a pointer to a png_struct. After a call to + * the flush function, there should be no data in any buffers + * or pending transmission. If the output method doesn't do + * any buffering of output, a function prototype must still be + * supplied although it doesn't have to do anything. If + * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile + * time, output_flush_fn will be ignored, although it must be + * supplied for compatibility. May be NULL, in which case + * libpng's default function will be used, if + * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not + * a good idea if io_ptr does not point to a standard + * *FILE structure. + */ +void PNGAPI +png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = io_ptr; + +#ifdef PNG_STDIO_SUPPORTED + if (write_data_fn != NULL) + png_ptr->write_data_fn = write_data_fn; + + else + png_ptr->write_data_fn = png_default_write_data; +#else + png_ptr->write_data_fn = write_data_fn; +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED + + if (output_flush_fn != NULL) + png_ptr->output_flush_fn = output_flush_fn; + + else + png_ptr->output_flush_fn = png_default_flush; + +# else + png_ptr->output_flush_fn = output_flush_fn; +# endif +#else + PNG_UNUSED(output_flush_fn) +#endif /* WRITE_FLUSH */ + +#ifdef PNG_READ_SUPPORTED + /* It is an error to read while writing a png file */ + if (png_ptr->read_data_fn != NULL) + { + png_ptr->read_data_fn = NULL; + + png_warning(png_ptr, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } +#endif +} +#endif /* WRITE */ diff --git a/thirdparty/libpng/upstream/pngwrite.c b/thirdparty/libpng/upstream/pngwrite.c index 780c7901d..2c95eb66c 100644 --- a/thirdparty/libpng/upstream/pngwrite.c +++ b/thirdparty/libpng/upstream/pngwrite.c @@ -1,2418 +1,2462 @@ - -/* pngwrite.c - general routines to write a PNG file - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -# include -#endif /* SIMPLIFIED_WRITE_STDIO */ - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -/* Write out all the unknown chunks for the current given location */ -static void -write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, - unsigned int where) -{ - if (info_ptr->unknown_chunks_num != 0) - { - png_const_unknown_chunkp up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - ++up) - if ((up->location & where) != 0) - { - /* If per-chunk unknown chunk handling is enabled use it, otherwise - * just write the chunks the application has set. - */ -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int keep = png_handle_as_unknown(png_ptr, up->name); - - /* NOTE: this code is radically different from the read side in the - * matter of handling an ancillary unknown chunk. In the read side - * the default behavior is to discard it, in the code below the default - * behavior is to write it. Critical chunks are, however, only - * written if explicitly listed or if the default is set to write all - * unknown chunks. - * - * The default handling is also slightly weird - it is not possible to - * stop the writing of all unsafe-to-copy chunks! - * - * TODO: REVIEW: this would seem to be a bug. - */ - if (keep != PNG_HANDLE_CHUNK_NEVER && - ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || - keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && - png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) -#endif - { - /* TODO: review, what is wrong with a zero length unknown chunk? */ - if (up->size == 0) - png_warning(png_ptr, "Writing zero-length unknown chunk"); - - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } -} -#endif /* WRITE_UNKNOWN_CHUNKS */ - -/* Writes all the PNG information. This is the suggested way to use the - * library. If you have a new chunk to add, make a function to write it, - * and put it in the correct location here. If you want the chunk written - * after the image data, put it in png_write_end(). I strongly encourage - * you to supply a PNG_INFO_ flag, and check info_ptr->valid before - * writing the chunk, as that will keep the code from breaking if you want - * to just write a plain PNG file. If you have long comments, I suggest - * writing them in png_write_end(), and compressing them. - */ -void PNGAPI -png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) -{ - png_debug(1, "in png_write_info_before_PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) - { - /* Write PNG signature */ - png_write_sig(png_ptr); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ - png_ptr->mng_features_permitted != 0) - { - png_warning(png_ptr, - "MNG features are not allowed in a PNG datastream"); - png_ptr->mng_features_permitted = 0; - } -#endif - - /* Write IHDR information. */ - png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, - info_ptr->filter_type, -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - info_ptr->interlace_type -#else - 0 -#endif - ); - - /* The rest of these check to see if the valid field has the appropriate - * flag set, and if it does, writes the chunk. - * - * 1.6.0: COLORSPACE support controls the writing of these chunks too, and - * the chunks will be written if the WRITE routine is there and - * information * is available in the COLORSPACE. (See - * png_colorspace_sync_info in png.c for where the valid flags get set.) - * - * Under certain circumstances the colorspace can be invalidated without - * syncing the info_struct 'valid' flags; this happens if libpng detects - * an error and calls png_error while the color space is being set, yet - * the application continues writing the PNG. So check the 'invalid' - * flag here too. - */ -#ifdef PNG_GAMMA_SUPPORTED -# ifdef PNG_WRITE_gAMA_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && - (info_ptr->valid & PNG_INFO_gAMA) != 0) - png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); -# endif -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED - /* Write only one of sRGB or an ICC profile. If a profile was supplied - * and it matches one of the known sRGB ones issue a warning. - */ -# ifdef PNG_WRITE_iCCP_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_iCCP) != 0) - { -# ifdef PNG_WRITE_sRGB_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sRGB) != 0) - png_app_warning(png_ptr, - "profile matches sRGB but writing iCCP instead"); -# endif - - png_write_iCCP(png_ptr, info_ptr->iccp_name, - info_ptr->iccp_profile); - } -# ifdef PNG_WRITE_sRGB_SUPPORTED - else -# endif -# endif - -# ifdef PNG_WRITE_sRGB_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_sRGB) != 0) - png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); -# endif /* WRITE_sRGB */ -#endif /* COLORSPACE */ - -#ifdef PNG_WRITE_sBIT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED -# ifdef PNG_WRITE_cHRM_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && - (info_ptr->valid & PNG_INFO_cHRM) != 0) - png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); -# endif -#endif - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); -#endif - - png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; - } -} - -void PNGAPI -png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) -{ -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) - int i; -#endif - - png_debug(1, "in png_write_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_write_info_before_PLTE(png_ptr, info_ptr); - - if ((info_ptr->valid & PNG_INFO_PLTE) != 0) - png_write_PLTE(png_ptr, info_ptr->palette, - (png_uint_32)info_ptr->num_palette); - - else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Valid palette required for paletted images"); - -#ifdef PNG_WRITE_tRNS_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tRNS) !=0) - { -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel (in tRNS) */ - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && - info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - int j, jend; - - jend = info_ptr->num_trans; - if (jend > PNG_MAX_PALETTE_LENGTH) - jend = PNG_MAX_PALETTE_LENGTH; - - for (j = 0; jtrans_alpha[j] = - (png_byte)(255 - info_ptr->trans_alpha[j]); - } -#endif - png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), - info_ptr->num_trans, info_ptr->color_type); - } -#endif -#ifdef PNG_WRITE_bKGD_SUPPORTED - if ((info_ptr->valid & PNG_INFO_bKGD) != 0) - png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED - if ((info_ptr->valid & PNG_INFO_eXIf) != 0) - { - png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); - png_ptr->mode |= PNG_WROTE_eXIf; - } -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED - if ((info_ptr->valid & PNG_INFO_hIST) != 0) - png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED - if ((info_ptr->valid & PNG_INFO_oFFs) != 0) - png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, - info_ptr->offset_unit_type); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED - if ((info_ptr->valid & PNG_INFO_pCAL) != 0) - png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, - info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, - info_ptr->pcal_units, info_ptr->pcal_params); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sCAL) != 0) - png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, - info_ptr->scal_s_width, info_ptr->scal_s_height); -#endif /* sCAL */ - -#ifdef PNG_WRITE_pHYs_SUPPORTED - if ((info_ptr->valid & PNG_INFO_pHYs) != 0) - png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, - info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); -#endif /* pHYs */ - -#ifdef PNG_WRITE_tIME_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tIME) != 0) - { - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - png_ptr->mode |= PNG_WROTE_tIME; - } -#endif /* tIME */ - -#ifdef PNG_WRITE_sPLT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sPLT) != 0) - for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) - png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); -#endif /* sPLT */ - -#ifdef PNG_WRITE_TEXT_SUPPORTED - /* Check to see if we need to write text chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing header text chunk %d, type %d", i, - info_ptr->text[i].compression); - /* An internationalized chunk? */ - if (info_ptr->text[i].compression > 0) - { -#ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); - /* Mark this chunk as written */ - if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - else - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write international text"); -#endif - } - - /* If we want a compressed text chunk */ - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) - { -#ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, info_ptr->text[i].compression); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write compressed text"); -#endif - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - { -#ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, - 0); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -#else - /* Can't get here */ - png_warning(png_ptr, "Unable to write uncompressed text"); -#endif - } - } -#endif /* tEXt */ - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); -#endif -} - -/* Writes the end of the PNG file. If you don't want to write comments or - * time information, you can pass NULL for info. If you already wrote these - * in png_write_info(), do not write them again here. If you have long - * comments, I suggest writing them here, and compressing them. - */ -void PNGAPI -png_write_end(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_write_end"); - - if (png_ptr == NULL) - return; - - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_error(png_ptr, "No IDATs written into file"); - -#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= png_ptr->num_palette) - png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); -#endif - - /* See if user wants us to write information chunks */ - if (info_ptr != NULL) - { -#ifdef PNG_WRITE_TEXT_SUPPORTED - int i; /* local index variable */ -#endif -#ifdef PNG_WRITE_tIME_SUPPORTED - /* Check to see if user has supplied a time chunk */ - if ((info_ptr->valid & PNG_INFO_tIME) != 0 && - (png_ptr->mode & PNG_WROTE_tIME) == 0) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - -#endif -#ifdef PNG_WRITE_TEXT_SUPPORTED - /* Loop through comment chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing trailer text chunk %d, type %d", i, - info_ptr->text[i].compression); - /* An internationalized chunk? */ - if (info_ptr->text[i].compression > 0) - { -#ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); - /* Mark this chunk as written */ - if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - else - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write international text"); -#endif - } - - else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) - { -#ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, info_ptr->text[i].compression); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write compressed text"); -#endif - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - { -#ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -#else - png_warning(png_ptr, "Unable to write uncompressed text"); -#endif - } - } -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED - if ((info_ptr->valid & PNG_INFO_eXIf) != 0 && - (png_ptr->mode & PNG_WROTE_eXIf) == 0) - png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); -#endif - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); -#endif - } - - png_ptr->mode |= PNG_AFTER_IDAT; - - /* Write end of PNG file */ - png_write_IEND(png_ptr); - - /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, - * and restored again in libpng-1.2.30, may cause some applications that - * do not set png_ptr->output_flush_fn to crash. If your application - * experiences a problem, please try building libpng with - * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to - * png-mng-implement at lists.sf.net . - */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED - png_flush(png_ptr); -# endif -#endif -} - -#ifdef PNG_CONVERT_tIME_SUPPORTED -void PNGAPI -png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime) -{ - png_debug(1, "in png_convert_from_struct_tm"); - - ptime->year = (png_uint_16)(1900 + ttime->tm_year); - ptime->month = (png_byte)(ttime->tm_mon + 1); - ptime->day = (png_byte)ttime->tm_mday; - ptime->hour = (png_byte)ttime->tm_hour; - ptime->minute = (png_byte)ttime->tm_min; - ptime->second = (png_byte)ttime->tm_sec; -} - -void PNGAPI -png_convert_from_time_t(png_timep ptime, time_t ttime) -{ - struct tm *tbuf; - - png_debug(1, "in png_convert_from_time_t"); - - tbuf = gmtime(&ttime); - if (tbuf == NULL) - { - /* TODO: add a safe function which takes a png_ptr argument and raises - * a png_error if the ttime argument is invalid and the call to gmtime - * fails as a consequence. - */ - memset(ptime, 0, sizeof(*ptime)); - return; - } - - png_convert_from_struct_tm(ptime, tbuf); -} -#endif - -/* Initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifndef PNG_USER_MEM_SUPPORTED - png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); -#else - return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); -} - -/* Alternate initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -#endif /* USER_MEM */ - if (png_ptr != NULL) - { - /* Set the zlib control values to defaults; they can be overridden by the - * application after the struct has been created. - */ - png_ptr->zbuffer_size = PNG_ZBUF_SIZE; - - /* The 'zlib_strategy' setting is irrelevant because png_default_claim in - * pngwutil.c defaults it according to whether or not filters will be - * used, and ignores this setting. - */ - png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; - png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; - png_ptr->zlib_mem_level = 8; - png_ptr->zlib_window_bits = 15; - png_ptr->zlib_method = 8; - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; - png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; - png_ptr->zlib_text_mem_level = 8; - png_ptr->zlib_text_window_bits = 15; - png_ptr->zlib_text_method = 8; -#endif /* WRITE_COMPRESSED_TEXT */ - - /* This is a highly dubious configuration option; by default it is off, - * but it may be appropriate for private builds that are testing - * extensions not conformant to the current specification, or of - * applications that must not fail to write at all costs! - */ -#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED - /* In stable builds only warn if an application error can be completely - * handled. - */ - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; -#endif - - /* App warnings are warnings in release (or release candidate) builds but - * are errors during development. - */ -#if PNG_RELEASE_BUILD - png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; -#endif - - /* TODO: delay this, it can be done in png_init_io() (if the app doesn't - * do it itself) avoiding setting the default function if it is not - * required. - */ - png_set_write_fn(png_ptr, NULL, NULL, NULL); - } - - return png_ptr; -} - - -/* Write a few rows of image data. If the image is interlaced, - * either you will have to write the 7 sub images, or, if you - * have called png_set_interlace_handling(), you will have to - * "write" the image seven times. - */ -void PNGAPI -png_write_rows(png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows) -{ - png_uint_32 i; /* row counter */ - png_bytepp rp; /* row pointer */ - - png_debug(1, "in png_write_rows"); - - if (png_ptr == NULL) - return; - - /* Loop through the rows */ - for (i = 0, rp = row; i < num_rows; i++, rp++) - { - png_write_row(png_ptr, *rp); - } -} - -/* Write the image. You only need to call this function once, even - * if you are writing an interlaced image. - */ -void PNGAPI -png_write_image(png_structrp png_ptr, png_bytepp image) -{ - png_uint_32 i; /* row index */ - int pass, num_pass; /* pass variables */ - png_bytepp rp; /* points to current row */ - - if (png_ptr == NULL) - return; - - png_debug(1, "in png_write_image"); - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Initialize interlace handling. If image is not interlaced, - * this will set pass to 1 - */ - num_pass = png_set_interlace_handling(png_ptr); -#else - num_pass = 1; -#endif - /* Loop through passes */ - for (pass = 0; pass < num_pass; pass++) - { - /* Loop through image */ - for (i = 0, rp = image; i < png_ptr->height; i++, rp++) - { - png_write_row(png_ptr, *rp); - } - } -} - -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Performs intrapixel differencing */ -static void -png_do_write_intrapixel(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_intrapixel"); - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)(*rp - *(rp + 1)); - *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); - png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); - *(rp ) = (png_byte)(red >> 8); - *(rp + 1) = (png_byte)red; - *(rp + 4) = (png_byte)(blue >> 8); - *(rp + 5) = (png_byte)blue; - } - } -#endif /* WRITE_16BIT */ - } -} -#endif /* MNG_FEATURES */ - -/* Called by user to write a row of image data */ -void PNGAPI -png_write_row(png_structrp png_ptr, png_const_bytep row) -{ - /* 1.5.6: moved from png_struct to be a local structure: */ - png_row_info row_info; - - png_debug2(1, "in png_write_row (row %u, pass %d)", - png_ptr->row_number, png_ptr->pass); - - if (png_ptr == NULL) - return; - - /* Initialize transformations and other stuff if first time */ - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Make sure we wrote the header info */ - if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) - png_error(png_ptr, - "png_write_info was never called before png_write_row"); - - /* Check for transforms that have been set but were defined out */ -#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); -#endif -#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - defined(PNG_READ_PACKSWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_warning(png_ptr, - "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) - if ((png_ptr->transformations & PNG_PACK) != 0) - png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) - if ((png_ptr->transformations & PNG_BGR) != 0) - png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); -#endif - - png_write_start_row(png_ptr); - } - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced and not interested in row, return */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - switch (png_ptr->pass) - { - case 0: - if ((png_ptr->row_number & 0x07) != 0) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 1: - if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 2: - if ((png_ptr->row_number & 0x07) != 4) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 3: - if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 4: - if ((png_ptr->row_number & 0x03) != 2) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 5: - if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 6: - if ((png_ptr->row_number & 0x01) == 0) - { - png_write_finish_row(png_ptr); - return; - } - break; - - default: /* error: ignore it */ - break; - } - } -#endif - - /* Set up row info for transformations */ - row_info.color_type = png_ptr->color_type; - row_info.width = png_ptr->usr_width; - row_info.channels = png_ptr->usr_channels; - row_info.bit_depth = png_ptr->usr_bit_depth; - row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - png_debug1(3, "row_info->color_type = %d", row_info.color_type); - png_debug1(3, "row_info->width = %u", row_info.width); - png_debug1(3, "row_info->channels = %d", row_info.channels); - png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); - png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); - - /* Copy user's row into buffer, leaving room for filter byte. */ - memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Handle interlacing */ - if (png_ptr->interlaced && png_ptr->pass < 6 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); - /* This should always get caught above, but still ... */ - if (row_info.width == 0) - { - png_write_finish_row(png_ptr); - return; - } - } -#endif - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* Handle other transformations */ - if (png_ptr->transformations != 0) - png_do_write_transformations(png_ptr, &row_info); -#endif - - /* At this point the row_info pixel depth must match the 'transformed' depth, - * which is also the output depth. - */ - if (row_info.pixel_depth != png_ptr->pixel_depth || - row_info.pixel_depth != png_ptr->transformed_pixel_depth) - png_error(png_ptr, "internal write transform logic error"); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ - png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); - } -#endif - -/* Added at libpng-1.5.10 */ -#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Check for out-of-range palette index */ - if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= 0) - png_do_check_palette_indexes(png_ptr, &row_info); -#endif - - /* Find a filter if necessary, filter the row and write it out. */ - png_write_find_filter(png_ptr, &row_info); - - if (png_ptr->write_row_fn != NULL) - (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Set the automatic flush interval or 0 to turn flushing off */ -void PNGAPI -png_set_flush(png_structrp png_ptr, int nrows) -{ - png_debug(1, "in png_set_flush"); - - if (png_ptr == NULL) - return; - - png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows); -} - -/* Flush the current output buffers now */ -void PNGAPI -png_write_flush(png_structrp png_ptr) -{ - png_debug(1, "in png_write_flush"); - - if (png_ptr == NULL) - return; - - /* We have already written out all of the data */ - if (png_ptr->row_number >= png_ptr->num_rows) - return; - - png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); - png_ptr->flush_rows = 0; - png_flush(png_ptr); -} -#endif /* WRITE_FLUSH */ - -/* Free any memory used in png_ptr struct without freeing the struct itself. */ -static void -png_write_destroy(png_structrp png_ptr) -{ - png_debug(1, "in png_write_destroy"); - - /* Free any memory zlib uses */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - deflateEnd(&png_ptr->zstream); - - /* Free our memory. png_free checks NULL for us. */ - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_free(png_ptr, png_ptr->row_buf); - png_ptr->row_buf = NULL; -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_free(png_ptr, png_ptr->prev_row); - png_free(png_ptr, png_ptr->try_row); - png_free(png_ptr, png_ptr->tst_row); - png_ptr->prev_row = NULL; - png_ptr->try_row = NULL; - png_ptr->tst_row = NULL; -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; -#endif - - /* The error handling and memory handling information is left intact at this - * point: the jmp_buf may still have to be freed. See png_destroy_png_struct - * for how this happens. - */ -} - -/* Free all memory used by the write. - * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for - * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free - * the passed in info_structs but it would quietly fail to free any of the data - * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it - * has no png_ptr.) - */ -void PNGAPI -png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) -{ - png_debug(1, "in png_destroy_write_struct"); - - if (png_ptr_ptr != NULL) - { - png_structrp png_ptr = *png_ptr_ptr; - - if (png_ptr != NULL) /* added in libpng 1.6.0 */ - { - png_destroy_info_struct(png_ptr, info_ptr_ptr); - - *png_ptr_ptr = NULL; - png_write_destroy(png_ptr); - png_destroy_png_struct(png_ptr); - } - } -} - -/* Allow the application to select one or more row filters to use. */ -void PNGAPI -png_set_filter(png_structrp png_ptr, int method, int filters) -{ - png_debug(1, "in png_set_filter"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (method == PNG_INTRAPIXEL_DIFFERENCING)) - method = PNG_FILTER_TYPE_BASE; - -#endif - if (method == PNG_FILTER_TYPE_BASE) - { - switch (filters & (PNG_ALL_FILTERS | 0x07)) - { -#ifdef PNG_WRITE_FILTER_SUPPORTED - case 5: - case 6: - case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); -#endif /* WRITE_FILTER */ - /* FALLTHROUGH */ - case PNG_FILTER_VALUE_NONE: - png_ptr->do_filter = PNG_FILTER_NONE; break; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - case PNG_FILTER_VALUE_SUB: - png_ptr->do_filter = PNG_FILTER_SUB; break; - - case PNG_FILTER_VALUE_UP: - png_ptr->do_filter = PNG_FILTER_UP; break; - - case PNG_FILTER_VALUE_AVG: - png_ptr->do_filter = PNG_FILTER_AVG; break; - - case PNG_FILTER_VALUE_PAETH: - png_ptr->do_filter = PNG_FILTER_PAETH; break; - - default: - png_ptr->do_filter = (png_byte)filters; break; -#else - default: - png_app_error(png_ptr, "Unknown row filter for method 0"); -#endif /* WRITE_FILTER */ - } - -#ifdef PNG_WRITE_FILTER_SUPPORTED - /* If we have allocated the row_buf, this means we have already started - * with the image and we should have allocated all of the filter buffers - * that have been selected. If prev_row isn't already allocated, then - * it is too late to start using the filters that need it, since we - * will be missing the data in the previous row. If an application - * wants to start and stop using particular filters during compression, - * it should start out with all of the filters, and then remove them - * or add them back after the start of compression. - * - * NOTE: this is a nasty constraint on the code, because it means that the - * prev_row buffer must be maintained even if there are currently no - * 'prev_row' requiring filters active. - */ - if (png_ptr->row_buf != NULL) - { - int num_filters; - png_alloc_size_t buf_size; - - /* Repeat the checks in png_write_start_row; 1 pixel high or wide - * images cannot benefit from certain filters. If this isn't done here - * the check below will fire on 1 pixel high images. - */ - if (png_ptr->height == 1) - filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if (png_ptr->width == 1) - filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0 - && png_ptr->prev_row == NULL) - { - /* This is the error case, however it is benign - the previous row - * is not available so the filter can't be used. Just warn here. - */ - png_app_warning(png_ptr, - "png_set_filter: UP/AVG/PAETH cannot be added after start"); - filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - } - - num_filters = 0; - - if (filters & PNG_FILTER_SUB) - num_filters++; - - if (filters & PNG_FILTER_UP) - num_filters++; - - if (filters & PNG_FILTER_AVG) - num_filters++; - - if (filters & PNG_FILTER_PAETH) - num_filters++; - - /* Allocate needed row buffers if they have not already been - * allocated. - */ - buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth, - png_ptr->width) + 1; - - if (png_ptr->try_row == NULL) - png_ptr->try_row = png_voidcast(png_bytep, - png_malloc(png_ptr, buf_size)); - - if (num_filters > 1) - { - if (png_ptr->tst_row == NULL) - png_ptr->tst_row = png_voidcast(png_bytep, - png_malloc(png_ptr, buf_size)); - } - } - png_ptr->do_filter = (png_byte)filters; -#endif - } - else - png_error(png_ptr, "Unknown custom filter method"); -} - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ -/* Provide floating and fixed point APIs */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, - int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs) -{ - PNG_UNUSED(png_ptr) - PNG_UNUSED(heuristic_method) - PNG_UNUSED(num_weights) - PNG_UNUSED(filter_weights) - PNG_UNUSED(filter_costs) -} -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, - int num_weights, png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs) -{ - PNG_UNUSED(png_ptr) - PNG_UNUSED(heuristic_method) - PNG_UNUSED(num_weights) - PNG_UNUSED(filter_weights) - PNG_UNUSED(filter_costs) -} -#endif /* FIXED_POINT */ -#endif /* WRITE_WEIGHTED_FILTER */ - -#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -void PNGAPI -png_set_compression_level(png_structrp png_ptr, int level) -{ - png_debug(1, "in png_set_compression_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_level = level; -} - -void PNGAPI -png_set_compression_mem_level(png_structrp png_ptr, int mem_level) -{ - png_debug(1, "in png_set_compression_mem_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_mem_level = mem_level; -} - -void PNGAPI -png_set_compression_strategy(png_structrp png_ptr, int strategy) -{ - png_debug(1, "in png_set_compression_strategy"); - - if (png_ptr == NULL) - return; - - /* The flag setting here prevents the libpng dynamic selection of strategy. - */ - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; - png_ptr->zlib_strategy = strategy; -} - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -void PNGAPI -png_set_compression_window_bits(png_structrp png_ptr, int window_bits) -{ - png_debug(1, "in png_set_compression_window_bits"); - - if (png_ptr == NULL) - return; - - /* Prior to 1.6.0 this would warn but then set the window_bits value. This - * meant that negative window bits values could be selected that would cause - * libpng to write a non-standard PNG file with raw deflate or gzip - * compressed IDAT or ancillary chunks. Such files can be read and there is - * no warning on read, so this seems like a very bad idea. - */ - if (window_bits > 15) - { - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); - window_bits = 15; - } - - else if (window_bits < 8) - { - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); - window_bits = 8; - } - - png_ptr->zlib_window_bits = window_bits; -} - -void PNGAPI -png_set_compression_method(png_structrp png_ptr, int method) -{ - png_debug(1, "in png_set_compression_method"); - - if (png_ptr == NULL) - return; - - /* This would produce an invalid PNG file if it worked, but it doesn't and - * deflate will fault it, so it is harmless to just warn here. - */ - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - - png_ptr->zlib_method = method; -} -#endif /* WRITE_CUSTOMIZE_COMPRESSION */ - -/* The following were added to libpng-1.5.4 */ -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -void PNGAPI -png_set_text_compression_level(png_structrp png_ptr, int level) -{ - png_debug(1, "in png_set_text_compression_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_text_level = level; -} - -void PNGAPI -png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) -{ - png_debug(1, "in png_set_text_compression_mem_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_text_mem_level = mem_level; -} - -void PNGAPI -png_set_text_compression_strategy(png_structrp png_ptr, int strategy) -{ - png_debug(1, "in png_set_text_compression_strategy"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_text_strategy = strategy; -} - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -void PNGAPI -png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) -{ - png_debug(1, "in png_set_text_compression_window_bits"); - - if (png_ptr == NULL) - return; - - if (window_bits > 15) - { - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); - window_bits = 15; - } - - else if (window_bits < 8) - { - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); - window_bits = 8; - } - - png_ptr->zlib_text_window_bits = window_bits; -} - -void PNGAPI -png_set_text_compression_method(png_structrp png_ptr, int method) -{ - png_debug(1, "in png_set_text_compression_method"); - - if (png_ptr == NULL) - return; - - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - - png_ptr->zlib_text_method = method; -} -#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ -/* end of API added to libpng-1.5.4 */ - -void PNGAPI -png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) -{ - png_debug(1, "in png_set_write_status_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->write_row_fn = write_row_fn; -} - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -void PNGAPI -png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - write_user_transform_fn) -{ - png_debug(1, "in png_set_write_user_transform_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->write_user_transform_fn = write_user_transform_fn; -} -#endif - - -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_write_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, voidp params) -{ - png_debug(1, "in png_write_png"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((info_ptr->valid & PNG_INFO_IDAT) == 0) - { - png_app_error(png_ptr, "no rows for png_write_image to write"); - return; - } - - /* Write the file header information. */ - png_write_info(png_ptr, info_ptr); - - /* ------ these transformations don't touch the info structure ------- */ - - /* Invert monochrome pixels */ - if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -#ifdef PNG_WRITE_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); -#endif - - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image. - */ - if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); -#endif - - /* Pack pixels into bytes */ - if ((transforms & PNG_TRANSFORM_PACKING) != 0) -#ifdef PNG_WRITE_PACK_SUPPORTED - png_set_packing(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); -#endif - - /* Swap location of alpha bytes from ARGB to RGBA */ - if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - png_set_swap_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); -#endif - - /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into - * RGB, note that the code expects the input color type to be G or RGB; no - * alpha channel. - */ - if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| - PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) - { -#ifdef PNG_WRITE_FILLER_SUPPORTED - if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) - { - if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) - png_app_error(png_ptr, - "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); - - /* Continue if ignored - this is the pre-1.6.10 behavior */ - png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); - } - - else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); -#endif - } - - /* Flip BGR pixels to RGB */ - if ((transforms & PNG_TRANSFORM_BGR) != 0) -#ifdef PNG_WRITE_BGR_SUPPORTED - png_set_bgr(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); -#endif - - /* Swap bytes of 16-bit files to most significant byte first */ - if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -#ifdef PNG_WRITE_SWAP_SUPPORTED - png_set_swap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); -#endif - - /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */ - if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); -#endif - - /* Invert the alpha channel from opacity to transparency */ - if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - png_set_invert_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); -#endif - - /* ----------------------- end of transformations ------------------- */ - - /* Write the bits */ - png_write_image(png_ptr, info_ptr->row_pointers); - - /* It is REQUIRED to call this to finish writing the rest of the file */ - png_write_end(png_ptr, info_ptr); - - PNG_UNUSED(params) -} -#endif - - -#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -/* Initialize the write structure - general purpose utility. */ -static int -png_image_write_init(png_imagep image) -{ - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); - - if (png_ptr != NULL) - { - png_infop info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr != NULL) - { - png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); - - if (control != NULL) - { - memset(control, 0, (sizeof *control)); - - control->png_ptr = png_ptr; - control->info_ptr = info_ptr; - control->for_write = 1; - - image->opaque = control; - return 1; - } - - /* Error clean up */ - png_destroy_info_struct(png_ptr, &info_ptr); - } - - png_destroy_write_struct(&png_ptr, NULL); - } - - return png_image_error(image, "png_image_write_: out of memory"); -} - -/* Arguments to png_image_write_main: */ -typedef struct -{ - /* Arguments: */ - png_imagep image; - png_const_voidp buffer; - png_int_32 row_stride; - png_const_voidp colormap; - int convert_to_8bit; - /* Local variables: */ - png_const_voidp first_row; - ptrdiff_t row_bytes; - png_voidp local_row; - /* Byte count for memory writing */ - png_bytep memory; - png_alloc_size_t memory_bytes; /* not used for STDIO */ - png_alloc_size_t output_bytes; /* running total */ -} png_image_write_control; - -/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to - * do any necessary byte swapping. The component order is defined by the - * png_image format value. - */ -static int -png_write_image_16bit(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - - png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); - png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); - png_uint_16p row_end; - unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? - 3 : 1; - int aindex = 0; - png_uint_32 y = image->height; - - if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - else - aindex = (int)channels; -# else - aindex = (int)channels; -# endif - } - - else - png_error(png_ptr, "png_write_image: internal call error"); - - /* Work out the output row end and count over this, note that the increment - * above to 'row' means that row_end can actually be beyond the end of the - * row; this is correct. - */ - row_end = output_row + image->width * (channels+1); - - for (; y > 0; --y) - { - png_const_uint_16p in_ptr = input_row; - png_uint_16p out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_16 alpha = in_ptr[aindex]; - png_uint_32 reciprocal = 0; - int c; - - out_ptr[aindex] = alpha; - - /* Calculate a reciprocal. The correct calculation is simply - * component/alpha*65535 << 15. (I.e. 15 bits of precision); this - * allows correct rounding by adding .5 before the shift. 'reciprocal' - * is only initialized when required. - */ - if (alpha > 0 && alpha < 65535) - reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; - - c = (int)channels; - do /* always at least one channel */ - { - png_uint_16 component = *in_ptr++; - - /* The following gives 65535 for an alpha of 0, which is fine, - * otherwise if 0/0 is represented as some other value there is more - * likely to be a discontinuity which will probably damage - * compression when moving from a fully transparent area to a - * nearly transparent one. (The assumption here is that opaque - * areas tend not to be 0 intensity.) - */ - if (component >= alpha) - component = 65535; - - /* component 0 && alpha < 65535) - { - png_uint_32 calc = component * reciprocal; - calc += 16384; /* round to nearest */ - component = (png_uint_16)(calc >> 15); - } - - *out_ptr++ = component; - } - while (--c > 0); - - /* Skip to next component (skip the intervening alpha channel) */ - ++in_ptr; - ++out_ptr; - } - - png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); - input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); - } - - return 1; -} - -/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel - * is present it must be removed from the components, the components are then - * written in sRGB encoding. No components are added or removed. - * - * Calculate an alpha reciprocal to reverse pre-multiplication. As above the - * calculation can be done to 15 bits of accuracy; however, the output needs to - * be scaled in the range 0..255*65535, so include that scaling here. - */ -# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+((alpha)>>1))/(alpha)) - -static png_byte -png_unpremultiply(png_uint_32 component, png_uint_32 alpha, - png_uint_32 reciprocal/*from the above macro*/) -{ - /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 - * is represented as some other value there is more likely to be a - * discontinuity which will probably damage compression when moving from a - * fully transparent area to a nearly transparent one. (The assumption here - * is that opaque areas tend not to be 0 intensity.) - * - * There is a rounding problem here; if alpha is less than 128 it will end up - * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the - * output change for this too. - */ - if (component >= alpha || alpha < 128) - return 255; - - /* component 0) - { - /* The test is that alpha/257 (rounded) is less than 255, the first value - * that becomes 255 is 65407. - * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, - * be exact!) [Could also test reciprocal != 0] - */ - if (alpha < 65407) - { - component *= reciprocal; - component += 64; /* round to nearest */ - component >>= 7; - } - - else - component *= 255; - - /* Convert the component to sRGB. */ - return (png_byte)PNG_sRGB_FROM_LINEAR(component); - } - - else - return 0; -} - -static int -png_write_image_8bit(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - - png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); - png_bytep output_row = png_voidcast(png_bytep, display->local_row); - png_uint_32 y = image->height; - unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? - 3 : 1; - - if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - png_bytep row_end; - int aindex; - -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - - else -# endif - aindex = (int)channels; - - /* Use row_end in place of a loop counter: */ - row_end = output_row + image->width * (channels+1); - - for (; y > 0; --y) - { - png_const_uint_16p in_ptr = input_row; - png_bytep out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_16 alpha = in_ptr[aindex]; - png_byte alphabyte = (png_byte)PNG_DIV257(alpha); - png_uint_32 reciprocal = 0; - int c; - - /* Scale and write the alpha channel. */ - out_ptr[aindex] = alphabyte; - - if (alphabyte > 0 && alphabyte < 255) - reciprocal = UNP_RECIPROCAL(alpha); - - c = (int)channels; - do /* always at least one channel */ - *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); - while (--c > 0); - - /* Skip to next component (skip the intervening alpha channel) */ - ++in_ptr; - ++out_ptr; - } /* while out_ptr < row_end */ - - png_write_row(png_ptr, png_voidcast(png_const_bytep, - display->local_row)); - input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); - } /* while y */ - } - - else - { - /* No alpha channel, so the row_end really is the end of the row and it - * is sufficient to loop over the components one by one. - */ - png_bytep row_end = output_row + image->width * channels; - - for (; y > 0; --y) - { - png_const_uint_16p in_ptr = input_row; - png_bytep out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_32 component = *in_ptr++; - - component *= 255; - *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); - } - - png_write_row(png_ptr, output_row); - input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); - } - } - - return 1; -} - -static void -png_image_set_PLTE(png_image_write_control *display) -{ - png_imagep image = display->image; - const void *cmap = display->colormap; - int entries = image->colormap_entries > 256 ? 256 : - (int)image->colormap_entries; - - /* NOTE: the caller must check for cmap != NULL and entries != 0 */ - png_uint_32 format = image->format; - unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); - -# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ - defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) - int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else -# define afirst 0 -# endif - -# ifdef PNG_FORMAT_BGR_SUPPORTED - int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else -# define bgr 0 -# endif - - int i, num_trans; - png_color palette[256]; - png_byte tRNS[256]; - - memset(tRNS, 255, (sizeof tRNS)); - memset(palette, 0, (sizeof palette)); - - for (i=num_trans=0; i= 3) /* RGB */ - { - palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[(2 ^ bgr)]); - palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[1]); - palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[bgr]); - } - - else /* Gray */ - palette[i].blue = palette[i].red = palette[i].green = - (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); - } - - else /* alpha */ - { - png_uint_16 alpha = entry[afirst ? 0 : channels-1]; - png_byte alphabyte = (png_byte)PNG_DIV257(alpha); - png_uint_32 reciprocal = 0; - - /* Calculate a reciprocal, as in the png_write_image_8bit code above - * this is designed to produce a value scaled to 255*65535 when - * divided by 128 (i.e. asr 7). - */ - if (alphabyte > 0 && alphabyte < 255) - reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; - - tRNS[i] = alphabyte; - if (alphabyte < 255) - num_trans = i+1; - - if (channels >= 3) /* RGB */ - { - palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], - alpha, reciprocal); - palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, - reciprocal); - palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, - reciprocal); - } - - else /* gray */ - palette[i].blue = palette[i].red = palette[i].green = - png_unpremultiply(entry[afirst], alpha, reciprocal); - } - } - - else /* Color-map has sRGB values */ - { - png_const_bytep entry = png_voidcast(png_const_bytep, cmap); - - entry += (unsigned int)i * channels; - - switch (channels) - { - case 4: - tRNS[i] = entry[afirst ? 0 : 3]; - if (tRNS[i] < 255) - num_trans = i+1; - /* FALLTHROUGH */ - case 3: - palette[i].blue = entry[afirst + (2 ^ bgr)]; - palette[i].green = entry[afirst + 1]; - palette[i].red = entry[afirst + bgr]; - break; - - case 2: - tRNS[i] = entry[1 ^ afirst]; - if (tRNS[i] < 255) - num_trans = i+1; - /* FALLTHROUGH */ - case 1: - palette[i].blue = palette[i].red = palette[i].green = - entry[afirst]; - break; - - default: - break; - } - } - } - -# ifdef afirst -# undef afirst -# endif -# ifdef bgr -# undef bgr -# endif - - png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, - entries); - - if (num_trans > 0) - png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, - num_trans, NULL); - - image->colormap_entries = (png_uint_32)entries; -} - -static int -png_image_write_main(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - png_uint_32 format = image->format; - - /* The following four ints are actually booleans */ - int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); - int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ - int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); - int write_16bit = linear && (display->convert_to_8bit == 0); - -# ifdef PNG_BENIGN_ERRORS_SUPPORTED - /* Make sure we error out on any bad situation */ - png_set_benign_errors(png_ptr, 0/*error*/); -# endif - - /* Default the 'row_stride' parameter if required, also check the row stride - * and total image size to ensure that they are within the system limits. - */ - { - unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - - if (image->width <= 0x7fffffffU/channels) /* no overflow */ - { - png_uint_32 check; - png_uint_32 png_row_stride = image->width * channels; - - if (display->row_stride == 0) - display->row_stride = (png_int_32)/*SAFE*/png_row_stride; - - if (display->row_stride < 0) - check = (png_uint_32)(-display->row_stride); - - else - check = (png_uint_32)display->row_stride; - - if (check >= png_row_stride) - { - /* Now check for overflow of the image buffer calculation; this - * limits the whole image size to 32 bits for API compatibility with - * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. - */ - if (image->height > 0xffffffffU/png_row_stride) - png_error(image->opaque->png_ptr, "memory image too large"); - } - - else - png_error(image->opaque->png_ptr, "supplied row stride too small"); - } - - else - png_error(image->opaque->png_ptr, "image row stride too large"); - } - - /* Set the required transforms then write the rows in the correct order. */ - if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) - { - if (display->colormap != NULL && image->colormap_entries > 0) - { - png_uint_32 entries = image->colormap_entries; - - png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), - PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - png_image_set_PLTE(display); - } - - else - png_error(image->opaque->png_ptr, - "no color-map for color-mapped image"); - } - - else - png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - write_16bit ? 16 : 8, - ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + - ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - /* Counter-intuitively the data transformations must be called *after* - * png_write_info, not before as in the read code, but the 'set' functions - * must still be called before. Just set the color space information, never - * write an interlaced image. - */ - - if (write_16bit != 0) - { - /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); - - if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) - png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270, 32900, - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000 - ); - } - - else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) - png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); - - /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit - * space must still be gamma encoded. - */ - else - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); - - /* Write the file header. */ - png_write_info(png_ptr, info_ptr); - - /* Now set up the data transformations (*after* the header is written), - * remove the handled transformations from the 'format' flags for checking. - * - * First check for a little endian system if writing 16-bit files. - */ - if (write_16bit != 0) - { - png_uint_16 le = 0x0001; - - if ((*(png_const_bytep) & le) != 0) - png_set_swap(png_ptr); - } - -# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED - if ((format & PNG_FORMAT_FLAG_BGR) != 0) - { - if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_bgr(png_ptr); - format &= ~PNG_FORMAT_FLAG_BGR; - } -# endif - -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_set_swap_alpha(png_ptr); - format &= ~PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* If there are 16 or fewer color-map entries we wrote a lower bit depth - * above, but the application data is still byte packed. - */ - if (colormap != 0 && image->colormap_entries <= 16) - png_set_packing(png_ptr); - - /* That should have handled all (both) the transforms. */ - if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | - PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) - png_error(png_ptr, "png_write_image: unsupported transformation"); - - { - png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); - ptrdiff_t row_bytes = display->row_stride; - - if (linear != 0) - row_bytes *= (sizeof (png_uint_16)); - - if (row_bytes < 0) - row += (image->height-1) * (-row_bytes); - - display->first_row = row; - display->row_bytes = row_bytes; - } - - /* Apply 'fast' options if the flag is set. */ - if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) - { - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); - /* NOTE: determined by experiment using pngstest, this reflects some - * balance between the time to write the image once and the time to read - * it about 50 times. The speed-up in pngstest was about 10-20% of the - * total (user) time on a heavily loaded system. - */ -# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED - png_set_compression_level(png_ptr, 3); -# endif - } - - /* Check for the cases that currently require a pre-transform on the row - * before it is written. This only applies when the input is 16-bit and - * either there is an alpha channel or it is converted to 8-bit. - */ - if ((linear != 0 && alpha != 0 ) || - (colormap == 0 && display->convert_to_8bit != 0)) - { - png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, - png_get_rowbytes(png_ptr, info_ptr))); - int result; - - display->local_row = row; - if (write_16bit != 0) - result = png_safe_execute(image, png_write_image_16bit, display); - else - result = png_safe_execute(image, png_write_image_8bit, display); - display->local_row = NULL; - - png_free(png_ptr, row); - - /* Skip the 'write_end' on error: */ - if (result == 0) - return 0; - } - - /* Otherwise this is the case where the input is in a format currently - * supported by the rest of the libpng write code; call it directly. - */ - else - { - png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); - ptrdiff_t row_bytes = display->row_bytes; - png_uint_32 y = image->height; - - for (; y > 0; --y) - { - png_write_row(png_ptr, row); - row += row_bytes; - } - } - - png_write_end(png_ptr, info_ptr); - return 1; -} - - -static void (PNGCBAPI -image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); - png_alloc_size_t ob = display->output_bytes; - - /* Check for overflow; this should never happen: */ - if (size <= ((png_alloc_size_t)-1) - ob) - { - /* I don't think libpng ever does this, but just in case: */ - if (size > 0) - { - if (display->memory_bytes >= ob+size) /* writing */ - memcpy(display->memory+ob, data, size); - - /* Always update the size: */ - display->output_bytes = ob+size; - } - } - - else - png_error(png_ptr, "png_image_write_to_memory: PNG too big"); -} - -static void (PNGCBAPI -image_memory_flush)(png_structp png_ptr) -{ - PNG_UNUSED(png_ptr) -} - -static int -png_image_write_memory(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - - /* The rest of the memory-specific init and write_main in an error protected - * environment. This case needs to use callbacks for the write operations - * since libpng has no built in support for writing to memory. - */ - png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/, - image_memory_write, image_memory_flush); - - return png_image_write_main(display); -} - -int PNGAPI -png_image_write_to_memory(png_imagep image, void *memory, - png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit, - const void *buffer, png_int_32 row_stride, const void *colormap) -{ - /* Write the image to the given buffer, or count the bytes if it is NULL */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (memory_bytes != NULL && buffer != NULL) - { - /* This is to give the caller an easier error detection in the NULL - * case and guard against uninitialized variable problems: - */ - if (memory == NULL) - *memory_bytes = 0; - - if (png_image_write_init(image) != 0) - { - png_image_write_control display; - int result; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.convert_to_8bit = convert_to_8bit; - display.memory = png_voidcast(png_bytep, memory); - display.memory_bytes = *memory_bytes; - display.output_bytes = 0; - - result = png_safe_execute(image, png_image_write_memory, &display); - png_image_free(image); - - /* write_memory returns true even if we ran out of buffer. */ - if (result) - { - /* On out-of-buffer this function returns '0' but still updates - * memory_bytes: - */ - if (memory != NULL && display.output_bytes > *memory_bytes) - result = 0; - - *memory_bytes = display.output_bytes; - } - - return result; - } - - else - return 0; - } - - else - return png_image_error(image, - "png_image_write_to_memory: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} - -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -int PNGAPI -png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, - const void *buffer, png_int_32 row_stride, const void *colormap) -{ - /* Write the image to the given (FILE*). */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file != NULL && buffer != NULL) - { - if (png_image_write_init(image) != 0) - { - png_image_write_control display; - int result; - - /* This is slightly evil, but png_init_io doesn't do anything other - * than this and we haven't changed the standard IO functions so - * this saves a 'safe' function. - */ - image->opaque->png_ptr->io_ptr = file; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.convert_to_8bit = convert_to_8bit; - - result = png_safe_execute(image, png_image_write_main, &display); - png_image_free(image); - return result; - } - - else - return 0; - } - - else - return png_image_error(image, - "png_image_write_to_stdio: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} - -int PNGAPI -png_image_write_to_file(png_imagep image, const char *file_name, - int convert_to_8bit, const void *buffer, png_int_32 row_stride, - const void *colormap) -{ - /* Write the image to the named file. */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file_name != NULL && buffer != NULL) - { - FILE *fp = fopen(file_name, "wb"); - - if (fp != NULL) - { - if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, - row_stride, colormap) != 0) - { - int error; /* from fflush/fclose */ - - /* Make sure the file is flushed correctly. */ - if (fflush(fp) == 0 && ferror(fp) == 0) - { - if (fclose(fp) == 0) - return 1; - - error = errno; /* from fclose */ - } - - else - { - error = errno; /* from fflush or ferror */ - (void)fclose(fp); - } - - (void)remove(file_name); - /* The image has already been cleaned up; this is just used to - * set the error (because the original write succeeded). - */ - return png_image_error(image, strerror(error)); - } - - else - { - /* Clean up: just the opened file. */ - (void)fclose(fp); - (void)remove(file_name); - return 0; - } - } - - else - return png_image_error(image, strerror(errno)); - } - - else - return png_image_error(image, - "png_image_write_to_file: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} -#endif /* SIMPLIFIED_WRITE_STDIO */ -#endif /* SIMPLIFIED_WRITE */ -#endif /* WRITE */ +/* pngwrite.c - general routines to write a PNG file + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED +# include +#endif /* SIMPLIFIED_WRITE_STDIO */ + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +/* Write out all the unknown chunks for the current given location */ +static void +write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, + unsigned int where) +{ + if (info_ptr->unknown_chunks_num != 0) + { + png_const_unknown_chunkp up; + + png_debug(5, "writing extra chunks"); + + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + ++up) + if ((up->location & where) != 0) + { + /* If per-chunk unknown chunk handling is enabled use it, otherwise + * just write the chunks the application has set. + */ +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + int keep = png_handle_as_unknown(png_ptr, up->name); + + /* NOTE: this code is radically different from the read side in the + * matter of handling an ancillary unknown chunk. In the read side + * the default behavior is to discard it, in the code below the default + * behavior is to write it. Critical chunks are, however, only + * written if explicitly listed or if the default is set to write all + * unknown chunks. + * + * The default handling is also slightly weird - it is not possible to + * stop the writing of all unsafe-to-copy chunks! + * + * TODO: REVIEW: this would seem to be a bug. + */ + if (keep != PNG_HANDLE_CHUNK_NEVER && + ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || + keep == PNG_HANDLE_CHUNK_ALWAYS || + (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && + png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) +#endif + { + /* TODO: review, what is wrong with a zero length unknown chunk? */ + if (up->size == 0) + png_warning(png_ptr, "Writing zero-length unknown chunk"); + + png_write_chunk(png_ptr, up->name, up->data, up->size); + } + } + } +} +#endif /* WRITE_UNKNOWN_CHUNKS */ + +/* Writes all the PNG information. This is the suggested way to use the + * library. If you have a new chunk to add, make a function to write it, + * and put it in the correct location here. If you want the chunk written + * after the image data, put it in png_write_end(). I strongly encourage + * you to supply a PNG_INFO_ flag, and check info_ptr->valid before + * writing the chunk, as that will keep the code from breaking if you want + * to just write a plain PNG file. If you have long comments, I suggest + * writing them in png_write_end(), and compressing them. + */ +void PNGAPI +png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) +{ + png_debug(1, "in png_write_info_before_PLTE"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) + { + /* Write PNG signature */ + png_write_sig(png_ptr); + +#ifdef PNG_MNG_FEATURES_SUPPORTED + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ + png_ptr->mng_features_permitted != 0) + { + png_warning(png_ptr, + "MNG features are not allowed in a PNG datastream"); + png_ptr->mng_features_permitted = 0; + } +#endif + + /* Write IHDR information. */ + png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + info_ptr->interlace_type +#else + 0 +#endif + ); + + /* The rest of these check to see if the valid field has the appropriate + * flag set, and if it does, writes the chunk. + * + * 1.6.0: COLORSPACE support controls the writing of these chunks too, and + * the chunks will be written if the WRITE routine is there and + * information * is available in the COLORSPACE. (See + * png_colorspace_sync_info in png.c for where the valid flags get set.) + * + * Under certain circumstances the colorspace can be invalidated without + * syncing the info_struct 'valid' flags; this happens if libpng detects + * an error and calls png_error while the color space is being set, yet + * the application continues writing the PNG. So check the 'invalid' + * flag here too. + */ +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + /* Write unknown chunks first; PNG v3 establishes a precedence order + * for colourspace chunks. It is certain therefore that new + * colourspace chunks will have a precedence and very likely it will be + * higher than all known so far. Writing the unknown chunks here is + * most likely to present the chunks in the most convenient order. + * + * FUTURE: maybe write chunks in the order the app calls png_set_chnk + * to give the app control. + */ + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED + /* PNG v3: a streaming app will need to see this before cICP because + * the information is helpful in handling HLG encoding (which is + * natively 10 bits but gets expanded to 16 in PNG.) + * + * The app shouldn't care about the order ideally, but it might have + * no choice. In PNG v3, apps are allowed to reject PNGs where the + * APNG chunks are out of order so it behooves libpng to be nice here. + */ + if ((info_ptr->valid & PNG_INFO_sBIT) != 0) + png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); +#endif + + /* PNG v3: the July 2004 version of the TR introduced the concept of colour + * space priority. As above it therefore behooves libpng to write the colour + * space chunks in the priority order so that a streaming app need not buffer + * them. + * + * PNG v3: Chunks mDCV and cLLI provide ancillary information for the + * interpretation of the colourspace chunks but do not require support for + * those chunks so are outside the "COLORSPACE" check but before the write of + * the colourspace chunks themselves. + */ +#ifdef PNG_WRITE_cLLI_SUPPORTED + if ((info_ptr->valid & PNG_INFO_cLLI) != 0) + { + png_write_cLLI_fixed(png_ptr, info_ptr->maxCLL, info_ptr->maxFALL); + } +#endif +#ifdef PNG_WRITE_mDCV_SUPPORTED + if ((info_ptr->valid & PNG_INFO_mDCV) != 0) + { + png_write_mDCV_fixed(png_ptr, + info_ptr->mastering_red_x, info_ptr->mastering_red_y, + info_ptr->mastering_green_x, info_ptr->mastering_green_y, + info_ptr->mastering_blue_x, info_ptr->mastering_blue_y, + info_ptr->mastering_white_x, info_ptr->mastering_white_y, + info_ptr->mastering_maxDL, info_ptr->mastering_minDL); + } +#endif + +# ifdef PNG_WRITE_cICP_SUPPORTED /* Priority 4 */ + if ((info_ptr->valid & PNG_INFO_cICP) != 0) + { + png_write_cICP(png_ptr, + info_ptr->cicp_colour_primaries, + info_ptr->cicp_transfer_function, + info_ptr->cicp_matrix_coefficients, + info_ptr->cicp_video_full_range_flag); + } +# endif + +# ifdef PNG_WRITE_iCCP_SUPPORTED /* Priority 3 */ + if ((info_ptr->valid & PNG_INFO_iCCP) != 0) + { + png_write_iCCP(png_ptr, info_ptr->iccp_name, + info_ptr->iccp_profile, info_ptr->iccp_proflen); + } +# endif + +# ifdef PNG_WRITE_sRGB_SUPPORTED /* Priority 2 */ + if ((info_ptr->valid & PNG_INFO_sRGB) != 0) + png_write_sRGB(png_ptr, info_ptr->rendering_intent); +# endif /* WRITE_sRGB */ + +# ifdef PNG_WRITE_gAMA_SUPPORTED /* Priority 1 */ + if ((info_ptr->valid & PNG_INFO_gAMA) != 0) + png_write_gAMA_fixed(png_ptr, info_ptr->gamma); +# endif + +# ifdef PNG_WRITE_cHRM_SUPPORTED /* Also priority 1 */ + if ((info_ptr->valid & PNG_INFO_cHRM) != 0) + png_write_cHRM_fixed(png_ptr, &info_ptr->cHRM); +# endif + + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } +} + +void PNGAPI +png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) +{ +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) + int i; +#endif + + png_debug(1, "in png_write_info"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + png_write_info_before_PLTE(png_ptr, info_ptr); + + if ((info_ptr->valid & PNG_INFO_PLTE) != 0) + png_write_PLTE(png_ptr, info_ptr->palette, + (png_uint_32)info_ptr->num_palette); + + else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Valid palette required for paletted images"); + +#ifdef PNG_WRITE_tRNS_SUPPORTED + if ((info_ptr->valid & PNG_INFO_tRNS) !=0) + { +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + /* Invert the alpha channel (in tRNS) */ + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + int j, jend; + + jend = info_ptr->num_trans; + if (jend > PNG_MAX_PALETTE_LENGTH) + jend = PNG_MAX_PALETTE_LENGTH; + + for (j = 0; jtrans_alpha[j] = + (png_byte)(255 - info_ptr->trans_alpha[j]); + } +#endif + png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), + info_ptr->num_trans, info_ptr->color_type); + } +#endif +#ifdef PNG_WRITE_bKGD_SUPPORTED + if ((info_ptr->valid & PNG_INFO_bKGD) != 0) + png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); +#endif + +#ifdef PNG_WRITE_eXIf_SUPPORTED + if ((info_ptr->valid & PNG_INFO_eXIf) != 0) + { + png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); + png_ptr->mode |= PNG_WROTE_eXIf; + } +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED + if ((info_ptr->valid & PNG_INFO_hIST) != 0) + png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED + if ((info_ptr->valid & PNG_INFO_oFFs) != 0) + png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, + info_ptr->offset_unit_type); +#endif + +#ifdef PNG_WRITE_pCAL_SUPPORTED + if ((info_ptr->valid & PNG_INFO_pCAL) != 0) + png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, + info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, + info_ptr->pcal_units, info_ptr->pcal_params); +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sCAL) != 0) + png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, + info_ptr->scal_s_width, info_ptr->scal_s_height); +#endif /* sCAL */ + +#ifdef PNG_WRITE_pHYs_SUPPORTED + if ((info_ptr->valid & PNG_INFO_pHYs) != 0) + png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, + info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); +#endif /* pHYs */ + +#ifdef PNG_WRITE_tIME_SUPPORTED + if ((info_ptr->valid & PNG_INFO_tIME) != 0) + { + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + png_ptr->mode |= PNG_WROTE_tIME; + } +#endif /* tIME */ + +#ifdef PNG_WRITE_sPLT_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sPLT) != 0) + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); +#endif /* sPLT */ + +#ifdef PNG_WRITE_TEXT_SUPPORTED + /* Check to see if we need to write text chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing header text chunk %d, type %d", i, + info_ptr->text[i].compression); + /* An internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#ifdef PNG_WRITE_iTXt_SUPPORTED + /* Write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); + /* Mark this chunk as written */ + if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + else + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + } + + /* If we want a compressed text chunk */ + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) + { +#ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, info_ptr->text[i].compression); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + } + + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#ifdef PNG_WRITE_tEXt_SUPPORTED + /* Write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, + 0); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; +#else + /* Can't get here */ + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + } + } +#endif /* tEXt */ + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); +#endif +} + +/* Writes the end of the PNG file. If you don't want to write comments or + * time information, you can pass NULL for info. If you already wrote these + * in png_write_info(), do not write them again here. If you have long + * comments, I suggest writing them here, and compressing them. + */ +void PNGAPI +png_write_end(png_structrp png_ptr, png_inforp info_ptr) +{ + png_debug(1, "in png_write_end"); + + if (png_ptr == NULL) + return; + + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) + png_error(png_ptr, "No IDATs written into file"); + +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= png_ptr->num_palette) + png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); +#endif + + /* See if user wants us to write information chunks */ + if (info_ptr != NULL) + { +#ifdef PNG_WRITE_TEXT_SUPPORTED + int i; /* local index variable */ +#endif +#ifdef PNG_WRITE_tIME_SUPPORTED + /* Check to see if user has supplied a time chunk */ + if ((info_ptr->valid & PNG_INFO_tIME) != 0 && + (png_ptr->mode & PNG_WROTE_tIME) == 0) + png_write_tIME(png_ptr, &(info_ptr->mod_time)); + +#endif +#ifdef PNG_WRITE_TEXT_SUPPORTED + /* Loop through comment chunks */ + for (i = 0; i < info_ptr->num_text; i++) + { + png_debug2(2, "Writing trailer text chunk %d, type %d", i, + info_ptr->text[i].compression); + /* An internationalized chunk? */ + if (info_ptr->text[i].compression > 0) + { +#ifdef PNG_WRITE_iTXt_SUPPORTED + /* Write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); + /* Mark this chunk as written */ + if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + else + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; +#else + png_warning(png_ptr, "Unable to write international text"); +#endif + } + + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) + { +#ifdef PNG_WRITE_zTXt_SUPPORTED + /* Write compressed chunk */ + png_write_zTXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, info_ptr->text[i].compression); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; +#else + png_warning(png_ptr, "Unable to write compressed text"); +#endif + } + + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) + { +#ifdef PNG_WRITE_tEXt_SUPPORTED + /* Write uncompressed chunk */ + png_write_tEXt(png_ptr, info_ptr->text[i].key, + info_ptr->text[i].text, 0); + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; +#else + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif + } + } +#endif + +#ifdef PNG_WRITE_eXIf_SUPPORTED + if ((info_ptr->valid & PNG_INFO_eXIf) != 0 && + (png_ptr->mode & PNG_WROTE_eXIf) == 0) + png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); +#endif + +#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED + write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); +#endif + } + + png_ptr->mode |= PNG_AFTER_IDAT; + + /* Write end of PNG file */ + png_write_IEND(png_ptr); + + /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, + * and restored again in libpng-1.2.30, may cause some applications that + * do not set png_ptr->output_flush_fn to crash. If your application + * experiences a problem, please try building libpng with + * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to + * png-mng-implement at lists.sf.net . + */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED +# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED + png_flush(png_ptr); +# endif +#endif +} + +#ifdef PNG_CONVERT_tIME_SUPPORTED +void PNGAPI +png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime) +{ + png_debug(1, "in png_convert_from_struct_tm"); + + ptime->year = (png_uint_16)(1900 + ttime->tm_year); + ptime->month = (png_byte)(ttime->tm_mon + 1); + ptime->day = (png_byte)ttime->tm_mday; + ptime->hour = (png_byte)ttime->tm_hour; + ptime->minute = (png_byte)ttime->tm_min; + ptime->second = (png_byte)ttime->tm_sec; +} + +void PNGAPI +png_convert_from_time_t(png_timep ptime, time_t ttime) +{ + struct tm *tbuf; + + png_debug(1, "in png_convert_from_time_t"); + + tbuf = gmtime(&ttime); + if (tbuf == NULL) + { + /* TODO: add a safe function which takes a png_ptr argument and raises + * a png_error if the ttime argument is invalid and the call to gmtime + * fails as a consequence. + */ + memset(ptime, 0, sizeof(*ptime)); + return; + } + + png_convert_from_struct_tm(ptime, tbuf); +} +#endif + +/* Initialize png_ptr structure, and allocate any memory needed */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED) +{ +#ifndef PNG_USER_MEM_SUPPORTED + png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, NULL, NULL, NULL); +#else + return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, + warn_fn, NULL, NULL, NULL); +} + +/* Alternate initialize png_ptr structure, and allocate any memory needed */ +PNG_FUNCTION(png_structp,PNGAPI +png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED) +{ + png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, + error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); +#endif /* USER_MEM */ + if (png_ptr != NULL) + { + /* Set the zlib control values to defaults; they can be overridden by the + * application after the struct has been created. + */ + png_ptr->zbuffer_size = PNG_ZBUF_SIZE; + + /* The 'zlib_strategy' setting is irrelevant because png_default_claim in + * pngwutil.c defaults it according to whether or not filters will be + * used, and ignores this setting. + */ + png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; + png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; + png_ptr->zlib_mem_level = 8; + png_ptr->zlib_window_bits = 15; + png_ptr->zlib_method = 8; + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED + png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; + png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; + png_ptr->zlib_text_mem_level = 8; + png_ptr->zlib_text_window_bits = 15; + png_ptr->zlib_text_method = 8; +#endif /* WRITE_COMPRESSED_TEXT */ + + /* This is a highly dubious configuration option; by default it is off, + * but it may be appropriate for private builds that are testing + * extensions not conformant to the current specification, or of + * applications that must not fail to write at all costs! + */ +#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED + /* In stable builds only warn if an application error can be completely + * handled. + */ + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; +#endif + + /* App warnings are warnings in release (or release candidate) builds but + * are errors during development. + */ +#if PNG_RELEASE_BUILD + png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; +#endif + + /* TODO: delay this, it can be done in png_init_io() (if the app doesn't + * do it itself) avoiding setting the default function if it is not + * required. + */ + png_set_write_fn(png_ptr, NULL, NULL, NULL); + } + + return png_ptr; +} + + +/* Write a few rows of image data. If the image is interlaced, + * either you will have to write the 7 sub images, or, if you + * have called png_set_interlace_handling(), you will have to + * "write" the image seven times. + */ +void PNGAPI +png_write_rows(png_structrp png_ptr, png_bytepp row, + png_uint_32 num_rows) +{ + png_uint_32 i; /* row counter */ + png_bytepp rp; /* row pointer */ + + png_debug(1, "in png_write_rows"); + + if (png_ptr == NULL) + return; + + /* Loop through the rows */ + for (i = 0, rp = row; i < num_rows; i++, rp++) + { + png_write_row(png_ptr, *rp); + } +} + +/* Write the image. You only need to call this function once, even + * if you are writing an interlaced image. + */ +void PNGAPI +png_write_image(png_structrp png_ptr, png_bytepp image) +{ + png_uint_32 i; /* row index */ + int pass, num_pass; /* pass variables */ + png_bytepp rp; /* points to current row */ + + if (png_ptr == NULL) + return; + + png_debug(1, "in png_write_image"); + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Initialize interlace handling. If image is not interlaced, + * this will set pass to 1 + */ + num_pass = png_set_interlace_handling(png_ptr); +#else + num_pass = 1; +#endif + /* Loop through passes */ + for (pass = 0; pass < num_pass; pass++) + { + /* Loop through image */ + for (i = 0, rp = image; i < png_ptr->height; i++, rp++) + { + png_write_row(png_ptr, *rp); + } + } +} + +#ifdef PNG_MNG_FEATURES_SUPPORTED +/* Performs intrapixel differencing */ +static void +png_do_write_intrapixel(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_intrapixel"); + + if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + int bytes_per_pixel; + png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 3; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 4; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + *(rp) = (png_byte)(*rp - *(rp + 1)); + *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else if (row_info->bit_depth == 16) + { + png_bytep rp; + png_uint_32 i; + + if (row_info->color_type == PNG_COLOR_TYPE_RGB) + bytes_per_pixel = 6; + + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bytes_per_pixel = 8; + + else + return; + + for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) + { + png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); + png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); + png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); + *(rp ) = (png_byte)(red >> 8); + *(rp + 1) = (png_byte)red; + *(rp + 4) = (png_byte)(blue >> 8); + *(rp + 5) = (png_byte)blue; + } + } +#endif /* WRITE_16BIT */ + } +} +#endif /* MNG_FEATURES */ + +/* Called by user to write a row of image data */ +void PNGAPI +png_write_row(png_structrp png_ptr, png_const_bytep row) +{ + /* 1.5.6: moved from png_struct to be a local structure: */ + png_row_info row_info; + + png_debug2(1, "in png_write_row (row %u, pass %d)", + png_ptr->row_number, png_ptr->pass); + + if (png_ptr == NULL) + return; + + /* Initialize transformations and other stuff if first time */ + if (png_ptr->row_number == 0 && png_ptr->pass == 0) + { + /* Make sure we wrote the header info */ + if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) + png_error(png_ptr, + "png_write_info was never called before png_write_row"); + + /* Check for transforms that have been set but were defined out */ +#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); +#endif +#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ + defined(PNG_READ_PACKSWAP_SUPPORTED) + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_warning(png_ptr, + "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) + if ((png_ptr->transformations & PNG_PACK) != 0) + png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) + if ((png_ptr->transformations & PNG_BGR) != 0) + png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); +#endif + +#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); +#endif + + png_write_start_row(png_ptr); + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced and not interested in row, return */ + if (png_ptr->interlaced != 0 && + (png_ptr->transformations & PNG_INTERLACE) != 0) + { + switch (png_ptr->pass) + { + case 0: + if ((png_ptr->row_number & 0x07) != 0) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 1: + if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 2: + if ((png_ptr->row_number & 0x07) != 4) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 3: + if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 4: + if ((png_ptr->row_number & 0x03) != 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 5: + if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2) + { + png_write_finish_row(png_ptr); + return; + } + break; + + case 6: + if ((png_ptr->row_number & 0x01) == 0) + { + png_write_finish_row(png_ptr); + return; + } + break; + + default: /* error: ignore it */ + break; + } + } +#endif + + /* Set up row info for transformations */ + row_info.color_type = png_ptr->color_type; + row_info.width = png_ptr->usr_width; + row_info.channels = png_ptr->usr_channels; + row_info.bit_depth = png_ptr->usr_bit_depth; + row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); + row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); + + png_debug1(3, "row_info->color_type = %d", row_info.color_type); + png_debug1(3, "row_info->width = %u", row_info.width); + png_debug1(3, "row_info->channels = %d", row_info.channels); + png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); + png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); + png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); + + /* Copy user's row into buffer, leaving room for filter byte. */ + memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* Handle interlacing */ + if (png_ptr->interlaced && png_ptr->pass < 6 && + (png_ptr->transformations & PNG_INTERLACE) != 0) + { + png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); + /* This should always get caught above, but still ... */ + if (row_info.width == 0) + { + png_write_finish_row(png_ptr); + return; + } + } +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED + /* Handle other transformations */ + if (png_ptr->transformations != 0) + png_do_write_transformations(png_ptr, &row_info); +#endif + + /* At this point the row_info pixel depth must match the 'transformed' depth, + * which is also the output depth. + */ + if (row_info.pixel_depth != png_ptr->pixel_depth || + row_info.pixel_depth != png_ptr->transformed_pixel_depth) + png_error(png_ptr, "internal write transform logic error"); + +#ifdef PNG_MNG_FEATURES_SUPPORTED + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + { + /* Intrapixel differencing */ + png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); + } +#endif + +/* Added at libpng-1.5.10 */ +#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Check for out-of-range palette index */ + if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, &row_info); +#endif + + /* Find a filter if necessary, filter the row and write it out. */ + png_write_find_filter(png_ptr, &row_info); + + if (png_ptr->write_row_fn != NULL) + (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); +} + +#ifdef PNG_WRITE_FLUSH_SUPPORTED +/* Set the automatic flush interval or 0 to turn flushing off */ +void PNGAPI +png_set_flush(png_structrp png_ptr, int nrows) +{ + png_debug(1, "in png_set_flush"); + + if (png_ptr == NULL) + return; + + png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows); +} + +/* Flush the current output buffers now */ +void PNGAPI +png_write_flush(png_structrp png_ptr) +{ + png_debug(1, "in png_write_flush"); + + if (png_ptr == NULL) + return; + + /* We have already written out all of the data */ + if (png_ptr->row_number >= png_ptr->num_rows) + return; + + png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); + png_ptr->flush_rows = 0; + png_flush(png_ptr); +} +#endif /* WRITE_FLUSH */ + +/* Free any memory used in png_ptr struct without freeing the struct itself. */ +static void +png_write_destroy(png_structrp png_ptr) +{ + png_debug(1, "in png_write_destroy"); + + /* Free any memory zlib uses */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) + deflateEnd(&png_ptr->zstream); + + /* Free our memory. png_free checks NULL for us. */ + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); + png_free(png_ptr, png_ptr->row_buf); + png_ptr->row_buf = NULL; +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_free(png_ptr, png_ptr->prev_row); + png_free(png_ptr, png_ptr->try_row); + png_free(png_ptr, png_ptr->tst_row); + png_ptr->prev_row = NULL; + png_ptr->try_row = NULL; + png_ptr->tst_row = NULL; +#endif + +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list = NULL; +#endif + +#if defined(PNG_tRNS_SUPPORTED) + /* Free the independent copy of trans_alpha owned by png_struct. */ + png_free(png_ptr, png_ptr->trans_alpha); + png_ptr->trans_alpha = NULL; +#endif + + /* Free the independent copy of the palette owned by png_struct. */ + png_free(png_ptr, png_ptr->palette); + png_ptr->palette = NULL; + + /* The error handling and memory handling information is left intact at this + * point: the jmp_buf may still have to be freed. See png_destroy_png_struct + * for how this happens. + */ +} + +/* Free all memory used by the write. + * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for + * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free + * the passed in info_structs but it would quietly fail to free any of the data + * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it + * has no png_ptr.) + */ +void PNGAPI +png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) +{ + png_debug(1, "in png_destroy_write_struct"); + + if (png_ptr_ptr != NULL) + { + png_structrp png_ptr = *png_ptr_ptr; + + if (png_ptr != NULL) /* added in libpng 1.6.0 */ + { + png_destroy_info_struct(png_ptr, info_ptr_ptr); + + *png_ptr_ptr = NULL; + png_write_destroy(png_ptr); + png_destroy_png_struct(png_ptr); + } + } +} + +/* Allow the application to select one or more row filters to use. */ +void PNGAPI +png_set_filter(png_structrp png_ptr, int method, int filters) +{ + png_debug(1, "in png_set_filter"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_MNG_FEATURES_SUPPORTED + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + (method == PNG_INTRAPIXEL_DIFFERENCING)) + method = PNG_FILTER_TYPE_BASE; + +#endif + if (method == PNG_FILTER_TYPE_BASE) + { + switch (filters & (PNG_ALL_FILTERS | 0x07)) + { +#ifdef PNG_WRITE_FILTER_SUPPORTED + case 5: + case 6: + case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); +#endif /* WRITE_FILTER */ + /* FALLTHROUGH */ + case PNG_FILTER_VALUE_NONE: + png_ptr->do_filter = PNG_FILTER_NONE; break; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + case PNG_FILTER_VALUE_SUB: + png_ptr->do_filter = PNG_FILTER_SUB; break; + + case PNG_FILTER_VALUE_UP: + png_ptr->do_filter = PNG_FILTER_UP; break; + + case PNG_FILTER_VALUE_AVG: + png_ptr->do_filter = PNG_FILTER_AVG; break; + + case PNG_FILTER_VALUE_PAETH: + png_ptr->do_filter = PNG_FILTER_PAETH; break; + + default: + png_ptr->do_filter = (png_byte)filters; break; +#else + default: + png_app_error(png_ptr, "Unknown row filter for method 0"); +#endif /* WRITE_FILTER */ + } + +#ifdef PNG_WRITE_FILTER_SUPPORTED + /* If we have allocated the row_buf, this means we have already started + * with the image and we should have allocated all of the filter buffers + * that have been selected. If prev_row isn't already allocated, then + * it is too late to start using the filters that need it, since we + * will be missing the data in the previous row. If an application + * wants to start and stop using particular filters during compression, + * it should start out with all of the filters, and then remove them + * or add them back after the start of compression. + * + * NOTE: this is a nasty constraint on the code, because it means that the + * prev_row buffer must be maintained even if there are currently no + * 'prev_row' requiring filters active. + */ + if (png_ptr->row_buf != NULL) + { + int num_filters; + png_alloc_size_t buf_size; + + /* Repeat the checks in png_write_start_row; 1 pixel high or wide + * images cannot benefit from certain filters. If this isn't done here + * the check below will fire on 1 pixel high images. + */ + if (png_ptr->height == 1) + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (png_ptr->width == 1) + filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0 + && png_ptr->prev_row == NULL) + { + /* This is the error case, however it is benign - the previous row + * is not available so the filter can't be used. Just warn here. + */ + png_app_warning(png_ptr, + "png_set_filter: UP/AVG/PAETH cannot be added after start"); + filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + } + + num_filters = 0; + + if (filters & PNG_FILTER_SUB) + num_filters++; + + if (filters & PNG_FILTER_UP) + num_filters++; + + if (filters & PNG_FILTER_AVG) + num_filters++; + + if (filters & PNG_FILTER_PAETH) + num_filters++; + + /* Allocate needed row buffers if they have not already been + * allocated. + */ + buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth, + png_ptr->width) + 1; + + if (png_ptr->try_row == NULL) + png_ptr->try_row = png_voidcast(png_bytep, + png_malloc(png_ptr, buf_size)); + + if (num_filters > 1) + { + if (png_ptr->tst_row == NULL) + png_ptr->tst_row = png_voidcast(png_bytep, + png_malloc(png_ptr, buf_size)); + } + } + png_ptr->do_filter = (png_byte)filters; +#endif + } + else + png_error(png_ptr, "Unknown custom filter method"); +} + +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ +/* Provide floating and fixed point APIs */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, + int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs) +{ + PNG_UNUSED(png_ptr) + PNG_UNUSED(heuristic_method) + PNG_UNUSED(num_weights) + PNG_UNUSED(filter_weights) + PNG_UNUSED(filter_costs) +} +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, + int num_weights, png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs) +{ + PNG_UNUSED(png_ptr) + PNG_UNUSED(heuristic_method) + PNG_UNUSED(num_weights) + PNG_UNUSED(filter_weights) + PNG_UNUSED(filter_costs) +} +#endif /* FIXED_POINT */ +#endif /* WRITE_WEIGHTED_FILTER */ + +#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED +void PNGAPI +png_set_compression_level(png_structrp png_ptr, int level) +{ + png_debug(1, "in png_set_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_level = level; +} + +void PNGAPI +png_set_compression_mem_level(png_structrp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_mem_level = mem_level; +} + +void PNGAPI +png_set_compression_strategy(png_structrp png_ptr, int strategy) +{ + png_debug(1, "in png_set_compression_strategy"); + + if (png_ptr == NULL) + return; + + /* The flag setting here prevents the libpng dynamic selection of strategy. + */ + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; + png_ptr->zlib_strategy = strategy; +} + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +void PNGAPI +png_set_compression_window_bits(png_structrp png_ptr, int window_bits) +{ + png_debug(1, "in png_set_compression_window_bits"); + + if (png_ptr == NULL) + return; + + /* Prior to 1.6.0 this would warn but then set the window_bits value. This + * meant that negative window bits values could be selected that would cause + * libpng to write a non-standard PNG file with raw deflate or gzip + * compressed IDAT or ancillary chunks. Such files can be read and there is + * no warning on read, so this seems like a very bad idea. + */ + if (window_bits > 15) + { + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + window_bits = 15; + } + + else if (window_bits < 8) + { + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + window_bits = 8; + } + + png_ptr->zlib_window_bits = window_bits; +} + +void PNGAPI +png_set_compression_method(png_structrp png_ptr, int method) +{ + png_debug(1, "in png_set_compression_method"); + + if (png_ptr == NULL) + return; + + /* This would produce an invalid PNG file if it worked, but it doesn't and + * deflate will fault it, so it is harmless to just warn here. + */ + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + + png_ptr->zlib_method = method; +} +#endif /* WRITE_CUSTOMIZE_COMPRESSION */ + +/* The following were added to libpng-1.5.4 */ +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED +void PNGAPI +png_set_text_compression_level(png_structrp png_ptr, int level) +{ + png_debug(1, "in png_set_text_compression_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_text_level = level; +} + +void PNGAPI +png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) +{ + png_debug(1, "in png_set_text_compression_mem_level"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_text_mem_level = mem_level; +} + +void PNGAPI +png_set_text_compression_strategy(png_structrp png_ptr, int strategy) +{ + png_debug(1, "in png_set_text_compression_strategy"); + + if (png_ptr == NULL) + return; + + png_ptr->zlib_text_strategy = strategy; +} + +/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a + * smaller value of window_bits if it can do so safely. + */ +void PNGAPI +png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) +{ + png_debug(1, "in png_set_text_compression_window_bits"); + + if (png_ptr == NULL) + return; + + if (window_bits > 15) + { + png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + window_bits = 15; + } + + else if (window_bits < 8) + { + png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + window_bits = 8; + } + + png_ptr->zlib_text_window_bits = window_bits; +} + +void PNGAPI +png_set_text_compression_method(png_structrp png_ptr, int method) +{ + png_debug(1, "in png_set_text_compression_method"); + + if (png_ptr == NULL) + return; + + if (method != 8) + png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + + png_ptr->zlib_text_method = method; +} +#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ +/* end of API added to libpng-1.5.4 */ + +void PNGAPI +png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) +{ + png_debug(1, "in png_set_write_status_fn"); + + if (png_ptr == NULL) + return; + + png_ptr->write_row_fn = write_row_fn; +} + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED +void PNGAPI +png_set_write_user_transform_fn(png_structrp png_ptr, + png_user_transform_ptr write_user_transform_fn) +{ + png_debug(1, "in png_set_write_user_transform_fn"); + + if (png_ptr == NULL) + return; + + png_ptr->transformations |= PNG_USER_TRANSFORM; + png_ptr->write_user_transform_fn = write_user_transform_fn; +} +#endif + + +#ifdef PNG_INFO_IMAGE_SUPPORTED +void PNGAPI +png_write_png(png_structrp png_ptr, png_inforp info_ptr, + int transforms, png_voidp params) +{ + png_debug(1, "in png_write_png"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + if ((info_ptr->valid & PNG_INFO_IDAT) == 0) + { + png_app_error(png_ptr, "no rows for png_write_image to write"); + return; + } + + /* Write the file header information. */ + png_write_info(png_ptr, info_ptr); + + /* ------ these transformations don't touch the info structure ------- */ + + /* Invert monochrome pixels */ + if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) +#ifdef PNG_WRITE_INVERT_SUPPORTED + png_set_invert_mono(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); +#endif + + /* Shift the pixels up to a legal bit depth and fill in + * as appropriate to correctly scale the image. + */ + if ((transforms & PNG_TRANSFORM_SHIFT) != 0) +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if ((info_ptr->valid & PNG_INFO_sBIT) != 0) + png_set_shift(png_ptr, &info_ptr->sig_bit); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); +#endif + + /* Pack pixels into bytes */ + if ((transforms & PNG_TRANSFORM_PACKING) != 0) +#ifdef PNG_WRITE_PACK_SUPPORTED + png_set_packing(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); +#endif + + /* Swap location of alpha bytes from ARGB to RGBA */ + if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + png_set_swap_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); +#endif + + /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into + * RGB, note that the code expects the input color type to be G or RGB; no + * alpha channel. + */ + if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| + PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) + { +#ifdef PNG_WRITE_FILLER_SUPPORTED + if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) + { + if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) + png_app_error(png_ptr, + "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); + + /* Continue if ignored - this is the pre-1.6.10 behavior */ + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + } + + else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) + png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); +#endif + } + + /* Flip BGR pixels to RGB */ + if ((transforms & PNG_TRANSFORM_BGR) != 0) +#ifdef PNG_WRITE_BGR_SUPPORTED + png_set_bgr(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); +#endif + + /* Swap bytes of 16-bit files to most significant byte first */ + if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) +#ifdef PNG_WRITE_SWAP_SUPPORTED + png_set_swap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); +#endif + + /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */ + if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + png_set_packswap(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); +#endif + + /* Invert the alpha channel from opacity to transparency */ + if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + png_set_invert_alpha(png_ptr); +#else + png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); +#endif + + /* ----------------------- end of transformations ------------------- */ + + /* Write the bits */ + png_write_image(png_ptr, info_ptr->row_pointers); + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + + PNG_UNUSED(params) +} +#endif + + +#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED +/* Initialize the write structure - general purpose utility. */ +static int +png_image_write_init(png_imagep image) +{ + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, + png_safe_error, png_safe_warning); + + if (png_ptr != NULL) + { + png_infop info_ptr = png_create_info_struct(png_ptr); + + if (info_ptr != NULL) + { + png_controlp control = png_voidcast(png_controlp, + png_malloc_warn(png_ptr, (sizeof *control))); + + if (control != NULL) + { + memset(control, 0, (sizeof *control)); + + control->png_ptr = png_ptr; + control->info_ptr = info_ptr; + control->for_write = 1; + + image->opaque = control; + return 1; + } + + /* Error clean up */ + png_destroy_info_struct(png_ptr, &info_ptr); + } + + png_destroy_write_struct(&png_ptr, NULL); + } + + return png_image_error(image, "png_image_write_: out of memory"); +} + +/* Arguments to png_image_write_main: */ +typedef struct +{ + /* Arguments */ + png_imagep image; + png_const_voidp buffer; + png_int_32 row_stride; + png_const_voidp colormap; + int convert_to_8bit; + + /* Instance variables */ + png_const_voidp first_row; + png_voidp local_row; + ptrdiff_t row_step; + + /* Byte count for memory writing */ + png_bytep memory; + png_alloc_size_t memory_bytes; /* not used for STDIO */ + png_alloc_size_t output_bytes; /* running total */ +} png_image_write_control; + +/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to + * do any necessary byte swapping. The component order is defined by the + * png_image format value. + */ +static int +png_write_image_16bit(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + + png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, + display->first_row); + png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); + png_uint_16p row_end; + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + 3 : 1; + int aindex = 0; + png_uint_32 y = image->height; + + if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) + { +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } + else + aindex = (int)channels; +# else + aindex = (int)channels; +# endif + } + + else + png_error(png_ptr, "png_write_image: internal call error"); + + /* Work out the output row end and count over this, note that the increment + * above to 'row' means that row_end can actually be beyond the end of the + * row; this is correct. + */ + row_end = output_row + image->width * (channels+1); + + for (; y > 0; --y) + { + png_const_uint_16p in_ptr = input_row; + png_uint_16p out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_16 alpha = in_ptr[aindex]; + png_uint_32 reciprocal = 0; + int c; + + out_ptr[aindex] = alpha; + + /* Calculate a reciprocal. The correct calculation is simply + * component/alpha*65535 << 15. (I.e. 15 bits of precision); this + * allows correct rounding by adding .5 before the shift. 'reciprocal' + * is only initialized when required. + */ + if (alpha > 0 && alpha < 65535) + reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; + + c = (int)channels; + do /* always at least one channel */ + { + png_uint_16 component = *in_ptr++; + + /* The following gives 65535 for an alpha of 0, which is fine, + * otherwise if 0/0 is represented as some other value there is more + * likely to be a discontinuity which will probably damage + * compression when moving from a fully transparent area to a + * nearly transparent one. (The assumption here is that opaque + * areas tend not to be 0 intensity.) + */ + if (component >= alpha) + component = 65535; + + /* component 0 && alpha < 65535) + { + png_uint_32 calc = component * reciprocal; + calc += 16384; /* round to nearest */ + component = (png_uint_16)(calc >> 15); + } + + *out_ptr++ = component; + } + while (--c > 0); + + /* Skip to next component (skip the intervening alpha channel) */ + ++in_ptr; + ++out_ptr; + } + + png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); + input_row += display->row_step / 2; + } + + return 1; +} + +/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel + * is present it must be removed from the components, the components are then + * written in sRGB encoding. No components are added or removed. + * + * Calculate an alpha reciprocal to reverse pre-multiplication. As above the + * calculation can be done to 15 bits of accuracy; however, the output needs to + * be scaled in the range 0..255*65535, so include that scaling here. + */ +# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+((alpha)>>1))/(alpha)) + +static png_byte +png_unpremultiply(png_uint_32 component, png_uint_32 alpha, + png_uint_32 reciprocal/*from the above macro*/) +{ + /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 + * is represented as some other value there is more likely to be a + * discontinuity which will probably damage compression when moving from a + * fully transparent area to a nearly transparent one. (The assumption here + * is that opaque areas tend not to be 0 intensity.) + * + * There is a rounding problem here; if alpha is less than 128 it will end up + * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the + * output change for this too. + */ + if (component >= alpha || alpha < 128) + return 255; + + /* component 0) + { + /* The test is that alpha/257 (rounded) is less than 255, the first value + * that becomes 255 is 65407. + * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, + * be exact!) [Could also test reciprocal != 0] + */ + if (alpha < 65407) + { + component *= reciprocal; + component += 64; /* round to nearest */ + component >>= 7; + } + + else + component *= 255; + + /* Convert the component to sRGB. */ + return (png_byte)PNG_sRGB_FROM_LINEAR(component); + } + + else + return 0; +} + +static int +png_write_image_8bit(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + + png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, + display->first_row); + png_bytep output_row = png_voidcast(png_bytep, display->local_row); + png_uint_32 y = image->height; + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + 3 : 1; + + if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) + { + png_bytep row_end; + int aindex; + +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + aindex = -1; + ++input_row; /* To point to the first component */ + ++output_row; + } + + else +# endif + aindex = (int)channels; + + /* Use row_end in place of a loop counter: */ + row_end = output_row + image->width * (channels+1); + + for (; y > 0; --y) + { + png_const_uint_16p in_ptr = input_row; + png_bytep out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_16 alpha = in_ptr[aindex]; + png_byte alphabyte = (png_byte)PNG_DIV257(alpha); + png_uint_32 reciprocal = 0; + int c; + + /* Scale and write the alpha channel. */ + out_ptr[aindex] = alphabyte; + + if (alphabyte > 0 && alphabyte < 255) + reciprocal = UNP_RECIPROCAL(alpha); + + c = (int)channels; + do /* always at least one channel */ + *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); + while (--c > 0); + + /* Skip to next component (skip the intervening alpha channel) */ + ++in_ptr; + ++out_ptr; + } /* while out_ptr < row_end */ + + png_write_row(png_ptr, png_voidcast(png_const_bytep, + display->local_row)); + input_row += display->row_step / 2; + } /* while y */ + } + + else + { + /* No alpha channel, so the row_end really is the end of the row and it + * is sufficient to loop over the components one by one. + */ + png_bytep row_end = output_row + image->width * channels; + + for (; y > 0; --y) + { + png_const_uint_16p in_ptr = input_row; + png_bytep out_ptr = output_row; + + while (out_ptr < row_end) + { + png_uint_32 component = *in_ptr++; + + component *= 255; + *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); + } + + png_write_row(png_ptr, output_row); + input_row += display->row_step / 2; + } + } + + return 1; +} + +static void +png_image_set_PLTE(png_image_write_control *display) +{ + png_imagep image = display->image; + const void *cmap = display->colormap; + int entries = image->colormap_entries > 256 ? 256 : + (int)image->colormap_entries; + + /* NOTE: the caller must check for cmap != NULL and entries != 0 */ + png_uint_32 format = image->format; + unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); + +# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ + defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) + int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && + (format & PNG_FORMAT_FLAG_ALPHA) != 0; +# else +# define afirst 0 +# endif + +# ifdef PNG_FORMAT_BGR_SUPPORTED + int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; +# else +# define bgr 0 +# endif + + int i, num_trans; + png_color palette[256]; + png_byte tRNS[256]; + + memset(tRNS, 255, (sizeof tRNS)); + memset(palette, 0, (sizeof palette)); + + for (i=num_trans=0; i= 3) /* RGB */ + { + palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[(2 ^ bgr)]); + palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[1]); + palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * + entry[bgr]); + } + + else /* Gray */ + palette[i].blue = palette[i].red = palette[i].green = + (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); + } + + else /* alpha */ + { + png_uint_16 alpha = entry[afirst ? 0 : channels-1]; + png_byte alphabyte = (png_byte)PNG_DIV257(alpha); + png_uint_32 reciprocal = 0; + + /* Calculate a reciprocal, as in the png_write_image_8bit code above + * this is designed to produce a value scaled to 255*65535 when + * divided by 128 (i.e. asr 7). + */ + if (alphabyte > 0 && alphabyte < 255) + reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; + + tRNS[i] = alphabyte; + if (alphabyte < 255) + num_trans = i+1; + + if (channels >= 3) /* RGB */ + { + palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], + alpha, reciprocal); + palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, + reciprocal); + palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, + reciprocal); + } + + else /* gray */ + palette[i].blue = palette[i].red = palette[i].green = + png_unpremultiply(entry[afirst], alpha, reciprocal); + } + } + + else /* Color-map has sRGB values */ + { + png_const_bytep entry = png_voidcast(png_const_bytep, cmap); + + entry += (unsigned int)i * channels; + + switch (channels) + { + case 4: + tRNS[i] = entry[afirst ? 0 : 3]; + if (tRNS[i] < 255) + num_trans = i+1; + /* FALLTHROUGH */ + case 3: + palette[i].blue = entry[afirst + (2 ^ bgr)]; + palette[i].green = entry[afirst + 1]; + palette[i].red = entry[afirst + bgr]; + break; + + case 2: + tRNS[i] = entry[1 ^ afirst]; + if (tRNS[i] < 255) + num_trans = i+1; + /* FALLTHROUGH */ + case 1: + palette[i].blue = palette[i].red = palette[i].green = + entry[afirst]; + break; + + default: + break; + } + } + } + +# ifdef afirst +# undef afirst +# endif +# ifdef bgr +# undef bgr +# endif + + png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, + entries); + + if (num_trans > 0) + png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, + num_trans, NULL); + + image->colormap_entries = (png_uint_32)entries; +} + +static int +png_image_write_main(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_inforp info_ptr = image->opaque->info_ptr; + png_uint_32 format = image->format; + + /* The following four ints are actually booleans */ + int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); + int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ + int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); + int write_16bit = linear && (display->convert_to_8bit == 0); + +# ifdef PNG_BENIGN_ERRORS_SUPPORTED + /* Make sure we error out on any bad situation */ + png_set_benign_errors(png_ptr, 0/*error*/); +# endif + + /* Default the 'row_stride' parameter if required, also check the row stride + * and total image size to ensure that they are within the system limits. + */ + { + unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + + if (image->width <= 0x7fffffffU/channels) /* no overflow */ + { + png_uint_32 check; + png_uint_32 png_row_stride = image->width * channels; + + if (display->row_stride == 0) + display->row_stride = (png_int_32)/*SAFE*/png_row_stride; + + if (display->row_stride < 0) + check = -(png_uint_32)display->row_stride; + + else + check = (png_uint_32)display->row_stride; + + if (check >= png_row_stride) + { + /* Now check for overflow of the image buffer calculation; this + * limits the whole image size to 32 bits for API compatibility with + * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. + */ + if (image->height > 0xffffffffU/png_row_stride) + png_error(image->opaque->png_ptr, "memory image too large"); + } + + else + png_error(image->opaque->png_ptr, "supplied row stride too small"); + } + + else + png_error(image->opaque->png_ptr, "image row stride too large"); + } + + /* Set the required transforms then write the rows in the correct order. */ + if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) + { + if (display->colormap != NULL && image->colormap_entries > 0) + { + png_uint_32 entries = image->colormap_entries; + + png_set_IHDR(png_ptr, info_ptr, image->width, image->height, + entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), + PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_image_set_PLTE(display); + } + + else + png_error(image->opaque->png_ptr, + "no color-map for color-mapped image"); + } + + else + png_set_IHDR(png_ptr, info_ptr, image->width, image->height, + write_16bit ? 16 : 8, + ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + + ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + /* Counter-intuitively the data transformations must be called *after* + * png_write_info, not before as in the read code, but the 'set' functions + * must still be called before. Just set the color space information, never + * write an interlaced image. + */ + + if (write_16bit != 0) + { + /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); + + if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) + png_set_cHRM_fixed(png_ptr, info_ptr, + /* color x y */ + /* white */ 31270, 32900, + /* red */ 64000, 33000, + /* green */ 30000, 60000, + /* blue */ 15000, 6000 + ); + } + + else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) + png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); + + /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit + * space must still be gamma encoded. + */ + else + png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); + + /* Write the file header. */ + png_write_info(png_ptr, info_ptr); + + /* Now set up the data transformations (*after* the header is written), + * remove the handled transformations from the 'format' flags for checking. + * + * First check for a little endian system if writing 16-bit files. + */ + if (write_16bit != 0) + { + png_uint_16 le = 0x0001; + + if ((*(png_const_bytep) & le) != 0) + png_set_swap(png_ptr); + } + +# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED + if ((format & PNG_FORMAT_FLAG_BGR) != 0) + { + if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) + png_set_bgr(png_ptr); + format &= ~PNG_FORMAT_FLAG_BGR; + } +# endif + +# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED + if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) + { + if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) + png_set_swap_alpha(png_ptr); + format &= ~PNG_FORMAT_FLAG_AFIRST; + } +# endif + + /* If there are 16 or fewer color-map entries we wrote a lower bit depth + * above, but the application data is still byte packed. + */ + if (colormap != 0 && image->colormap_entries <= 16) + png_set_packing(png_ptr); + + /* That should have handled all (both) the transforms. */ + if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | + PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) + png_error(png_ptr, "png_write_image: unsupported transformation"); + + { + png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); + ptrdiff_t row_step = display->row_stride; + + if (linear != 0) + row_step *= 2; + + if (row_step < 0) + row += (image->height-1) * (-row_step); + + display->first_row = row; + display->row_step = row_step; + } + + /* Apply 'fast' options if the flag is set. */ + if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) + { + png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); + /* NOTE: determined by experiment using pngstest, this reflects some + * balance between the time to write the image once and the time to read + * it about 50 times. The speed-up in pngstest was about 10-20% of the + * total (user) time on a heavily loaded system. + */ +# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED + png_set_compression_level(png_ptr, 3); +# endif + } + + /* Check for the cases that currently require a pre-transform on the row + * before it is written. This only applies when the input is 16-bit and + * either there is an alpha channel or it is converted to 8-bit. + */ + if (linear != 0 && (alpha != 0 || display->convert_to_8bit != 0)) + { + png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, + png_get_rowbytes(png_ptr, info_ptr))); + int result; + + display->local_row = row; + if (write_16bit != 0) + result = png_safe_execute(image, png_write_image_16bit, display); + else + result = png_safe_execute(image, png_write_image_8bit, display); + display->local_row = NULL; + + png_free(png_ptr, row); + + /* Skip the 'write_end' on error: */ + if (result == 0) + return 0; + } + + /* Otherwise this is the case where the input is in a format currently + * supported by the rest of the libpng write code; call it directly. + */ + else + { + png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); + ptrdiff_t row_step = display->row_step; + png_uint_32 y = image->height; + + for (; y > 0; --y) + { + png_write_row(png_ptr, row); + row += row_step; + } + } + + png_write_end(png_ptr, info_ptr); + return 1; +} + + +static void (PNGCBAPI +image_memory_write)(png_structp png_ptr, png_bytep data, size_t size) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); + png_alloc_size_t ob = display->output_bytes; + + /* Check for overflow; this should never happen: */ + if (size <= ((png_alloc_size_t)-1) - ob) + { + /* I don't think libpng ever does this, but just in case: */ + if (size > 0) + { + if (display->memory_bytes >= ob+size) /* writing */ + memcpy(display->memory+ob, data, size); + + /* Always update the size: */ + display->output_bytes = ob+size; + } + } + + else + png_error(png_ptr, "png_image_write_to_memory: PNG too big"); +} + +static void (PNGCBAPI +image_memory_flush)(png_structp png_ptr) +{ + PNG_UNUSED(png_ptr) +} + +static int +png_image_write_memory(png_voidp argument) +{ + png_image_write_control *display = png_voidcast(png_image_write_control*, + argument); + + /* The rest of the memory-specific init and write_main in an error protected + * environment. This case needs to use callbacks for the write operations + * since libpng has no built in support for writing to memory. + */ + png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/, + image_memory_write, image_memory_flush); + + return png_image_write_main(display); +} + +int PNGAPI +png_image_write_to_memory(png_imagep image, void *memory, + png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit, + const void *buffer, png_int_32 row_stride, const void *colormap) +{ + /* Write the image to the given buffer, or count the bytes if it is NULL */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (memory_bytes != NULL && buffer != NULL) + { + /* This is to give the caller an easier error detection in the NULL + * case and guard against uninitialized variable problems: + */ + if (memory == NULL) + *memory_bytes = 0; + + if (png_image_write_init(image) != 0) + { + png_image_write_control display; + int result; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.convert_to_8bit = convert_to_8bit; + display.memory = png_voidcast(png_bytep, memory); + display.memory_bytes = *memory_bytes; + display.output_bytes = 0; + + result = png_safe_execute(image, png_image_write_memory, &display); + png_image_free(image); + + /* write_memory returns true even if we ran out of buffer. */ + if (result) + { + /* On out-of-buffer this function returns '0' but still updates + * memory_bytes: + */ + if (memory != NULL && display.output_bytes > *memory_bytes) + result = 0; + + *memory_bytes = display.output_bytes; + } + + return result; + } + + else + return 0; + } + + else + return png_image_error(image, + "png_image_write_to_memory: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} + +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED +int PNGAPI +png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, + const void *buffer, png_int_32 row_stride, const void *colormap) +{ + /* Write the image to the given FILE object. */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file != NULL && buffer != NULL) + { + if (png_image_write_init(image) != 0) + { + png_image_write_control display; + int result; + + /* This is slightly evil, but png_init_io doesn't do anything other + * than this and we haven't changed the standard IO functions so + * this saves a 'safe' function. + */ + image->opaque->png_ptr->io_ptr = file; + + memset(&display, 0, (sizeof display)); + display.image = image; + display.buffer = buffer; + display.row_stride = row_stride; + display.colormap = colormap; + display.convert_to_8bit = convert_to_8bit; + + result = png_safe_execute(image, png_image_write_main, &display); + png_image_free(image); + return result; + } + + else + return 0; + } + + else + return png_image_error(image, + "png_image_write_to_stdio: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} + +int PNGAPI +png_image_write_to_file(png_imagep image, const char *file_name, + int convert_to_8bit, const void *buffer, png_int_32 row_stride, + const void *colormap) +{ + /* Write the image to the named file. */ + if (image != NULL && image->version == PNG_IMAGE_VERSION) + { + if (file_name != NULL && buffer != NULL) + { + FILE *fp = fopen(file_name, "wb"); + + if (fp != NULL) + { + if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, + row_stride, colormap) != 0) + { + int error; /* from fflush/fclose */ + + /* Make sure the file is flushed correctly. */ + if (fflush(fp) == 0 && ferror(fp) == 0) + { + if (fclose(fp) == 0) + return 1; + + error = errno; /* from fclose */ + } + + else + { + error = errno; /* from fflush or ferror */ + (void)fclose(fp); + } + + (void)remove(file_name); + /* The image has already been cleaned up; this is just used to + * set the error (because the original write succeeded). + */ + return png_image_error(image, strerror(error)); + } + + else + { + /* Clean up: just the opened file. */ + (void)fclose(fp); + (void)remove(file_name); + return 0; + } + } + + else + return png_image_error(image, strerror(errno)); + } + + else + return png_image_error(image, + "png_image_write_to_file: invalid argument"); + } + + else if (image != NULL) + return png_image_error(image, + "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); + + else + return 0; +} +#endif /* SIMPLIFIED_WRITE_STDIO */ +#endif /* SIMPLIFIED_WRITE */ +#endif /* WRITE */ diff --git a/thirdparty/libpng/upstream/pngwtran.c b/thirdparty/libpng/upstream/pngwtran.c index 473c3b872..a20847023 100644 --- a/thirdparty/libpng/upstream/pngwtran.c +++ b/thirdparty/libpng/upstream/pngwtran.c @@ -1,575 +1,574 @@ - -/* pngwtran.c - transforms the data in a row for PNG writers - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - -#ifdef PNG_WRITE_PACK_SUPPORTED -/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The - * row_info bit depth should be 8 (one pixel per byte). The channels - * should be 1 (this only happens on grayscale and paletted images). - */ -static void -png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) -{ - png_debug(1, "in png_do_pack"); - - if (row_info->bit_depth == 8 && - row_info->channels == 1) - { - switch ((int)bit_depth) - { - case 1: - { - png_bytep sp, dp; - int mask, v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - mask = 0x80; - v = 0; - - for (i = 0; i < row_width; i++) - { - if (*sp != 0) - v |= mask; - - sp++; - - if (mask > 1) - mask >>= 1; - - else - { - mask = 0x80; - *dp = (png_byte)v; - dp++; - v = 0; - } - } - - if (mask != 0x80) - *dp = (png_byte)v; - - break; - } - - case 2: - { - png_bytep sp, dp; - unsigned int shift; - int v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - shift = 6; - v = 0; - - for (i = 0; i < row_width; i++) - { - png_byte value; - - value = (png_byte)(*sp & 0x03); - v |= (value << shift); - - if (shift == 0) - { - shift = 6; - *dp = (png_byte)v; - dp++; - v = 0; - } - - else - shift -= 2; - - sp++; - } - - if (shift != 6) - *dp = (png_byte)v; - - break; - } - - case 4: - { - png_bytep sp, dp; - unsigned int shift; - int v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - shift = 4; - v = 0; - - for (i = 0; i < row_width; i++) - { - png_byte value; - - value = (png_byte)(*sp & 0x0f); - v |= (value << shift); - - if (shift == 0) - { - shift = 4; - *dp = (png_byte)v; - dp++; - v = 0; - } - - else - shift -= 4; - - sp++; - } - - if (shift != 4) - *dp = (png_byte)v; - - break; - } - - default: - break; - } - - row_info->bit_depth = (png_byte)bit_depth; - row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); - } -} -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED -/* Shift pixel values to take advantage of whole range. Pass the - * true number of bits in bit_depth. The row should be packed - * according to row_info->bit_depth. Thus, if you had a row of - * bit depth 4, but the pixels only had values from 0 to 7, you - * would pass 3 as bit_depth, and this routine would translate the - * data to 0 to 15. - */ -static void -png_do_shift(png_row_infop row_info, png_bytep row, - png_const_color_8p bit_depth) -{ - png_debug(1, "in png_do_shift"); - - if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift_start[4], shift_dec[4]; - unsigned int channels = 0; - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - shift_start[channels] = row_info->bit_depth - bit_depth->red; - shift_dec[channels] = bit_depth->red; - channels++; - - shift_start[channels] = row_info->bit_depth - bit_depth->green; - shift_dec[channels] = bit_depth->green; - channels++; - - shift_start[channels] = row_info->bit_depth - bit_depth->blue; - shift_dec[channels] = bit_depth->blue; - channels++; - } - - else - { - shift_start[channels] = row_info->bit_depth - bit_depth->gray; - shift_dec[channels] = bit_depth->gray; - channels++; - } - - if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - shift_start[channels] = row_info->bit_depth - bit_depth->alpha; - shift_dec[channels] = bit_depth->alpha; - channels++; - } - - /* With low row depths, could only be grayscale, so one channel */ - if (row_info->bit_depth < 8) - { - png_bytep bp = row; - size_t i; - unsigned int mask; - size_t row_bytes = row_info->rowbytes; - - if (bit_depth->gray == 1 && row_info->bit_depth == 2) - mask = 0x55; - - else if (row_info->bit_depth == 4 && bit_depth->gray == 3) - mask = 0x11; - - else - mask = 0xff; - - for (i = 0; i < row_bytes; i++, bp++) - { - int j; - unsigned int v, out; - - v = *bp; - out = 0; - - for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) - { - if (j > 0) - out |= v << j; - - else - out |= (v >> (-j)) & mask; - } - - *bp = (png_byte)(out & 0xff); - } - } - - else if (row_info->bit_depth == 8) - { - png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = channels * row_info->width; - - for (i = 0; i < istop; i++, bp++) - { - unsigned int c = i%channels; - int j; - unsigned int v, out; - - v = *bp; - out = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - out |= v << j; - - else - out |= v >> (-j); - } - - *bp = (png_byte)(out & 0xff); - } - } - - else - { - png_bytep bp; - png_uint_32 i; - png_uint_32 istop = channels * row_info->width; - - for (bp = row, i = 0; i < istop; i++) - { - unsigned int c = i%channels; - int j; - unsigned int value, v; - - v = png_get_uint_16(bp); - value = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - value |= v << j; - - else - value |= v >> (-j); - } - *bp++ = (png_byte)((value >> 8) & 0xff); - *bp++ = (png_byte)(value & 0xff); - } - } - } -} -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -static void -png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_swap_alpha"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This converts from ARGB to RGBA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save; - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This converts from AARRGGBB to RRGGBBAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save[2]; - save[0] = *(sp++); - save[1] = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save[0]; - *(dp++) = save[1]; - } - } -#endif /* WRITE_16BIT */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This converts from AG to GA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save; - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This converts from AAGG to GGAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save[2]; - save[0] = *(sp++); - save[1] = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save[0]; - *(dp++) = save[1]; - } - } -#endif /* WRITE_16BIT */ - } - } -} -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -static void -png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_invert_alpha"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in RGBA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=3; dp = sp; - *dp = (png_byte)(255 - *(sp++)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in RRGGBBAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=6; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - *dp = (png_byte)(255 - *(sp++)); - } - } -#endif /* WRITE_16BIT */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in GA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - *(dp++) = *(sp++); - *(dp++) = (png_byte)(255 - *(sp++)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in GGAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=2; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - *dp = (png_byte)(255 - *(sp++)); - } - } -#endif /* WRITE_16BIT */ - } - } -} -#endif - -/* Transform the data according to the user's wishes. The order of - * transformations is significant. - */ -void /* PRIVATE */ -png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_write_transformations"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - if (png_ptr->write_user_transform_fn != NULL) - (*(png_ptr->write_user_transform_fn)) /* User write transform - function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#endif - -#ifdef PNG_WRITE_FILLER_SUPPORTED - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); -#endif - -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0) - png_do_pack(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->bit_depth); -#endif - -#ifdef PNG_WRITE_SWAP_SUPPORTED -# ifdef PNG_16BIT_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_do_swap(row_info, png_ptr->row_buf + 1); -# endif -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_do_shift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) - png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif -} -#endif /* WRITE_TRANSFORMS */ -#endif /* WRITE */ +/* pngwtran.c - transforms the data in a row for PNG writers + * + * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED + +#ifdef PNG_WRITE_PACK_SUPPORTED +/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The + * row_info bit depth should be 8 (one pixel per byte). The channels + * should be 1 (this only happens on grayscale and paletted images). + */ +static void +png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) +{ + png_debug(1, "in png_do_pack"); + + if (row_info->bit_depth == 8 && + row_info->channels == 1) + { + switch ((int)bit_depth) + { + case 1: + { + png_bytep sp, dp; + int mask, v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + mask = 0x80; + v = 0; + + for (i = 0; i < row_width; i++) + { + if (*sp != 0) + v |= mask; + + sp++; + + if (mask > 1) + mask >>= 1; + + else + { + mask = 0x80; + *dp = (png_byte)v; + dp++; + v = 0; + } + } + + if (mask != 0x80) + *dp = (png_byte)v; + + break; + } + + case 2: + { + png_bytep sp, dp; + unsigned int shift; + int v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 6; + v = 0; + + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x03); + v |= (value << shift); + + if (shift == 0) + { + shift = 6; + *dp = (png_byte)v; + dp++; + v = 0; + } + + else + shift -= 2; + + sp++; + } + + if (shift != 6) + *dp = (png_byte)v; + + break; + } + + case 4: + { + png_bytep sp, dp; + unsigned int shift; + int v; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + sp = row; + dp = row; + shift = 4; + v = 0; + + for (i = 0; i < row_width; i++) + { + png_byte value; + + value = (png_byte)(*sp & 0x0f); + v |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp = (png_byte)v; + dp++; + v = 0; + } + + else + shift -= 4; + + sp++; + } + + if (shift != 4) + *dp = (png_byte)v; + + break; + } + + default: + break; + } + + row_info->bit_depth = (png_byte)bit_depth; + row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED +/* Shift pixel values to take advantage of whole range. Pass the + * true number of bits in bit_depth. The row should be packed + * according to row_info->bit_depth. Thus, if you had a row of + * bit depth 4, but the pixels only had values from 0 to 7, you + * would pass 3 as bit_depth, and this routine would translate the + * data to 0 to 15. + */ +static void +png_do_shift(png_row_infop row_info, png_bytep row, + png_const_color_8p bit_depth) +{ + png_debug(1, "in png_do_shift"); + + if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) + { + int shift_start[4], shift_dec[4]; + unsigned int channels = 0; + + if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) + { + shift_start[channels] = row_info->bit_depth - bit_depth->red; + shift_dec[channels] = bit_depth->red; + channels++; + + shift_start[channels] = row_info->bit_depth - bit_depth->green; + shift_dec[channels] = bit_depth->green; + channels++; + + shift_start[channels] = row_info->bit_depth - bit_depth->blue; + shift_dec[channels] = bit_depth->blue; + channels++; + } + + else + { + shift_start[channels] = row_info->bit_depth - bit_depth->gray; + shift_dec[channels] = bit_depth->gray; + channels++; + } + + if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + shift_start[channels] = row_info->bit_depth - bit_depth->alpha; + shift_dec[channels] = bit_depth->alpha; + channels++; + } + + /* With low row depths, could only be grayscale, so one channel */ + if (row_info->bit_depth < 8) + { + png_bytep bp = row; + size_t i; + unsigned int mask; + size_t row_bytes = row_info->rowbytes; + + if (bit_depth->gray == 1 && row_info->bit_depth == 2) + mask = 0x55; + + else if (row_info->bit_depth == 4 && bit_depth->gray == 3) + mask = 0x11; + + else + mask = 0xff; + + for (i = 0; i < row_bytes; i++, bp++) + { + int j; + unsigned int v, out; + + v = *bp; + out = 0; + + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) + { + if (j > 0) + out |= v << j; + + else + out |= (v >> (-j)) & mask; + } + + *bp = (png_byte)(out & 0xff); + } + } + + else if (row_info->bit_depth == 8) + { + png_bytep bp = row; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (i = 0; i < istop; i++, bp++) + { + unsigned int c = i%channels; + int j; + unsigned int v, out; + + v = *bp; + out = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + out |= v << j; + + else + out |= v >> (-j); + } + + *bp = (png_byte)(out & 0xff); + } + } + + else + { + png_bytep bp; + png_uint_32 i; + png_uint_32 istop = channels * row_info->width; + + for (bp = row, i = 0; i < istop; i++) + { + unsigned int c = i%channels; + int j; + unsigned int value, v; + + v = png_get_uint_16(bp); + value = 0; + + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) + { + if (j > 0) + value |= v << j; + + else + value |= v >> (-j); + } + *bp++ = (png_byte)((value >> 8) & 0xff); + *bp++ = (png_byte)(value & 0xff); + } + } + } +} +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED +static void +png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_swap_alpha"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This converts from ARGB to RGBA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This converts from AARRGGBB to RRGGBBAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } +#endif /* WRITE_16BIT */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This converts from AG to GA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save; + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This converts from AAGG to GGAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + png_byte save[2]; + save[0] = *(sp++); + save[1] = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = save[0]; + *(dp++) = save[1]; + } + } +#endif /* WRITE_16BIT */ + } + } +} +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED +static void +png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_write_invert_alpha"); + + { + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in RGBA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* Does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=3; dp = sp; + *dp = (png_byte)(255 - *(sp++)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in RRGGBBAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* Does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=6; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *dp = (png_byte)(255 - *(sp++)); + } + } +#endif /* WRITE_16BIT */ + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) + { + /* This inverts the alpha channel in GA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + *(dp++) = *(sp++); + *(dp++) = (png_byte)(255 - *(sp++)); + } + } + +#ifdef PNG_WRITE_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + png_bytep sp, dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + for (i = 0, sp = dp = row; i < row_width; i++) + { + /* Does nothing + *(dp++) = *(sp++); + *(dp++) = *(sp++); + */ + sp+=2; dp = sp; + *(dp++) = (png_byte)(255 - *(sp++)); + *dp = (png_byte)(255 - *(sp++)); + } + } +#endif /* WRITE_16BIT */ + } + } +} +#endif + +/* Transform the data according to the user's wishes. The order of + * transformations is significant. + */ +void /* PRIVATE */ +png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) +{ + png_debug(1, "in png_do_write_transformations"); + + if (png_ptr == NULL) + return; + +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + if (png_ptr->write_user_transform_fn != NULL) + (*(png_ptr->write_user_transform_fn)) /* User write transform + function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#endif + +#ifdef PNG_WRITE_FILLER_SUPPORTED + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); +#endif + +#ifdef PNG_WRITE_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0) + png_do_pack(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->bit_depth); +#endif + +#ifdef PNG_WRITE_SWAP_SUPPORTED +# ifdef PNG_16BIT_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_do_swap(row_info, png_ptr->row_buf + 1); +# endif +#endif + +#ifdef PNG_WRITE_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_do_shift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) + png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_WRITE_INVERT_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif +} +#endif /* WRITE_TRANSFORMS */ +#endif /* WRITE */ diff --git a/thirdparty/libpng/upstream/pngwutil.c b/thirdparty/libpng/upstream/pngwutil.c index ac36eabbd..e16c387c2 100644 --- a/thirdparty/libpng/upstream/pngwutil.c +++ b/thirdparty/libpng/upstream/pngwutil.c @@ -1,2781 +1,2780 @@ - -/* pngwutil.c - utilities to write a PNG file - * - * Copyright (c) 2018-2024 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -/* Place a 32-bit number into a buffer in PNG byte order. We work - * with unsigned numbers for convenience, although one supported - * ancillary chunk uses signed (two's complement) numbers. - */ -void PNGAPI -png_save_uint_32(png_bytep buf, png_uint_32 i) -{ - buf[0] = (png_byte)((i >> 24) & 0xffU); - buf[1] = (png_byte)((i >> 16) & 0xffU); - buf[2] = (png_byte)((i >> 8) & 0xffU); - buf[3] = (png_byte)( i & 0xffU); -} - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -void PNGAPI -png_save_uint_16(png_bytep buf, unsigned int i) -{ - buf[0] = (png_byte)((i >> 8) & 0xffU); - buf[1] = (png_byte)( i & 0xffU); -} -#endif - -/* Simple function to write the signature. If we have already written - * the magic bytes of the signature, or more likely, the PNG stream is - * being embedded into another stream and doesn't need its own signature, - * we should call png_set_sig_bytes() to tell libpng how many of the - * bytes have already been written. - */ -void PNGAPI -png_write_sig(png_structrp png_ptr) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the signature is being written */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; -#endif - - /* Write the rest of the 8 byte signature */ - png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], - (size_t)(8 - png_ptr->sig_bytes)); - - if (png_ptr->sig_bytes < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Write the start of a PNG chunk. The type is the chunk type. - * The total_length is the sum of the lengths of all the data you will be - * passing in png_write_chunk_data(). - */ -static void -png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, - png_uint_32 length) -{ - png_byte buf[8]; - -#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) - PNG_CSTRING_FROM_CHUNK(buf, chunk_name); - png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); -#endif - - if (png_ptr == NULL) - return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk header is being written. - * PNG_IO_CHUNK_HDR requires a single I/O call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; -#endif - - /* Write the length and the chunk name */ - png_save_uint_32(buf, length); - png_save_uint_32(buf + 4, chunk_name); - png_write_data(png_ptr, buf, 8); - - /* Put the chunk name into png_ptr->chunk_name */ - png_ptr->chunk_name = chunk_name; - - /* Reset the crc and run it over the chunk name */ - png_reset_crc(png_ptr); - - png_calculate_crc(png_ptr, buf + 4, 4); - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that chunk data will (possibly) be written. - * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; -#endif -} - -void PNGAPI -png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, - png_uint_32 length) -{ - png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); -} - -/* Write the data of a PNG chunk started with png_write_chunk_header(). - * Note that multiple calls to this function are allowed, and that the - * sum of the lengths from these calls *must* add up to the total_length - * given to png_write_chunk_header(). - */ -void PNGAPI -png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length) -{ - /* Write the data, and run the CRC over it */ - if (png_ptr == NULL) - return; - - if (data != NULL && length > 0) - { - png_write_data(png_ptr, data, length); - - /* Update the CRC after writing the data, - * in case the user I/O routine alters it. - */ - png_calculate_crc(png_ptr, data, length); - } -} - -/* Finish a chunk started with png_write_chunk_header(). */ -void PNGAPI -png_write_chunk_end(png_structrp png_ptr) -{ - png_byte buf[4]; - - if (png_ptr == NULL) return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk CRC is being written. - * PNG_IO_CHUNK_CRC requires a single I/O function call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; -#endif - - /* Write the crc in a single operation */ - png_save_uint_32(buf, png_ptr->crc); - - png_write_data(png_ptr, buf, 4); -} - -/* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the - * pre-defined chunk names here, and if you need a new one, define it - * where the others are defined. The length is the length of the data. - * All the data must be present. If that is not possible, use the - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ -static void -png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, - png_const_bytep data, size_t length) -{ - if (png_ptr == NULL) - return; - - /* On 64-bit architectures 'length' may not fit in a png_uint_32. */ - if (length > PNG_UINT_31_MAX) - png_error(png_ptr, "length exceeds PNG maximum"); - - png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); - png_write_chunk_data(png_ptr, data, length); - png_write_chunk_end(png_ptr); -} - -/* This is the API that calls the internal function above. */ -void PNGAPI -png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, - png_const_bytep data, size_t length) -{ - png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, - length); -} - -/* This is used below to find the size of an image to pass to png_deflate_claim, - * so it only needs to be accurate if the size is less than 16384 bytes (the - * point at which a lower LZ window size can be used.) - */ -static png_alloc_size_t -png_image_size(png_structrp png_ptr) -{ - /* Only return sizes up to the maximum of a png_uint_32; do this by limiting - * the width and height used to 15 bits. - */ - png_uint_32 h = png_ptr->height; - - if (png_ptr->rowbytes < 32768 && h < 32768) - { - if (png_ptr->interlaced != 0) - { - /* Interlacing makes the image larger because of the replication of - * both the filter byte and the padding to a byte boundary. - */ - png_uint_32 w = png_ptr->width; - unsigned int pd = png_ptr->pixel_depth; - png_alloc_size_t cb_base; - int pass; - - for (cb_base=0, pass=0; pass<=6; ++pass) - { - png_uint_32 pw = PNG_PASS_COLS(w, pass); - - if (pw > 0) - cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); - } - - return cb_base; - } - - else - return (png_ptr->rowbytes+1) * h; - } - - else - return 0xffffffffU; -} - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - /* This is the code to hack the first two bytes of the deflate stream (the - * deflate header) to correct the windowBits value to match the actual data - * size. Note that the second argument is the *uncompressed* size but the - * first argument is the *compressed* data (and it must be deflate - * compressed.) - */ -static void -optimize_cmf(png_bytep data, png_alloc_size_t data_size) -{ - /* Optimize the CMF field in the zlib stream. The resultant zlib stream is - * still compliant to the stream specification. - */ - if (data_size <= 16384) /* else windowBits must be 15 */ - { - unsigned int z_cmf = data[0]; /* zlib compression method and flags */ - - if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) - { - unsigned int z_cinfo; - unsigned int half_z_window_size; - - z_cinfo = z_cmf >> 4; - half_z_window_size = 1U << (z_cinfo + 7); - - if (data_size <= half_z_window_size) /* else no change */ - { - unsigned int tmp; - - do - { - half_z_window_size >>= 1; - --z_cinfo; - } - while (z_cinfo > 0 && data_size <= half_z_window_size); - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - data[0] = (png_byte)z_cmf; - tmp = data[1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - data[1] = (png_byte)tmp; - } - } - } -} -#endif /* WRITE_OPTIMIZE_CMF */ - -/* Initialize the compressor for the appropriate type of compression. */ -static int -png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, - png_alloc_size_t data_size) -{ - if (png_ptr->zowner != 0) - { -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) - char msg[64]; - - PNG_STRING_FROM_CHUNK(msg, owner); - msg[4] = ':'; - msg[5] = ' '; - PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); - /* So the message that results is " using zstream"; this is an - * internal error, but is very useful for debugging. i18n requirements - * are minimal. - */ - (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); -#endif -#if PNG_RELEASE_BUILD - png_warning(png_ptr, msg); - - /* Attempt sane error recovery */ - if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); - return Z_STREAM_ERROR; - } - - png_ptr->zowner = 0; -#else - png_error(png_ptr, msg); -#endif - } - - { - int level = png_ptr->zlib_level; - int method = png_ptr->zlib_method; - int windowBits = png_ptr->zlib_window_bits; - int memLevel = png_ptr->zlib_mem_level; - int strategy; /* set below */ - int ret; /* zlib return code */ - - if (owner == png_IDAT) - { - if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) - strategy = png_ptr->zlib_strategy; - - else if (png_ptr->do_filter != PNG_FILTER_NONE) - strategy = PNG_Z_DEFAULT_STRATEGY; - - else - strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; - } - - else - { -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - level = png_ptr->zlib_text_level; - method = png_ptr->zlib_text_method; - windowBits = png_ptr->zlib_text_window_bits; - memLevel = png_ptr->zlib_text_mem_level; - strategy = png_ptr->zlib_text_strategy; -#else - /* If customization is not supported the values all come from the - * IDAT values except for the strategy, which is fixed to the - * default. (This is the pre-1.6.0 behavior too, although it was - * implemented in a very different way.) - */ - strategy = Z_DEFAULT_STRATEGY; -#endif - } - - /* Adjust 'windowBits' down if larger than 'data_size'; to stop this - * happening just pass 32768 as the data_size parameter. Notice that zlib - * requires an extra 262 bytes in the window in addition to the data to be - * able to see the whole of the data, so if data_size+262 takes us to the - * next windowBits size we need to fix up the value later. (Because even - * though deflate needs the extra window, inflate does not!) - */ - if (data_size <= 16384) - { - /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to - * work round a Microsoft Visual C misbehavior which, contrary to C-90, - * widens the result of the following shift to 64-bits if (and, - * apparently, only if) it is used in a test. - */ - unsigned int half_window_size = 1U << (windowBits-1); - - while (data_size + 262 <= half_window_size) - { - half_window_size >>= 1; - --windowBits; - } - } - - /* Check against the previous initialized values, if any. */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && - (png_ptr->zlib_set_level != level || - png_ptr->zlib_set_method != method || - png_ptr->zlib_set_window_bits != windowBits || - png_ptr->zlib_set_mem_level != memLevel || - png_ptr->zlib_set_strategy != strategy)) - { - if (deflateEnd(&png_ptr->zstream) != Z_OK) - png_warning(png_ptr, "deflateEnd failed (ignored)"); - - png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; - } - - /* For safety clear out the input and output pointers (currently zlib - * doesn't use them on Init, but it might in the future). - */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0; - - /* Now initialize if required, setting the new parameters, otherwise just - * do a simple reset to the previous parameters. - */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - ret = deflateReset(&png_ptr->zstream); - - else - { - ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, - memLevel, strategy); - - if (ret == Z_OK) - png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; - } - - /* The return code is from either deflateReset or deflateInit2; they have - * pretty much the same set of error codes. - */ - if (ret == Z_OK) - png_ptr->zowner = owner; - - else - png_zstream_error(png_ptr, ret); - - return ret; - } -} - -/* Clean up (or trim) a linked list of compression buffers. */ -void /* PRIVATE */ -png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) -{ - png_compression_bufferp list = *listp; - - if (list != NULL) - { - *listp = NULL; - - do - { - png_compression_bufferp next = list->next; - - png_free(png_ptr, list); - list = next; - } - while (list != NULL); - } -} - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -/* This pair of functions encapsulates the operation of (a) compressing a - * text string, and (b) issuing it later as a series of chunk data writes. - * The compression_state structure is shared context for these functions - * set up by the caller to allow access to the relevant local variables. - * - * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size - * temporary buffers. From 1.6.0 it is retained in png_struct so that it will - * be correctly freed in the event of a write error (previous implementations - * just leaked memory.) - */ -typedef struct -{ - png_const_bytep input; /* The uncompressed input data */ - png_alloc_size_t input_len; /* Its length */ - png_uint_32 output_len; /* Final compressed length */ - png_byte output[1024]; /* First block of output */ -} compression_state; - -static void -png_text_compress_init(compression_state *comp, png_const_bytep input, - png_alloc_size_t input_len) -{ - comp->input = input; - comp->input_len = input_len; - comp->output_len = 0; -} - -/* Compress the data in the compression state input */ -static int -png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, - compression_state *comp, png_uint_32 prefix_len) -{ - int ret; - - /* To find the length of the output it is necessary to first compress the - * input. The result is buffered rather than using the two-pass algorithm - * that is used on the inflate side; deflate is assumed to be slower and a - * PNG writer is assumed to have more memory available than a PNG reader. - * - * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an - * upper limit on the output size, but it is always bigger than the input - * size so it is likely to be more efficient to use this linked-list - * approach. - */ - ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); - - if (ret != Z_OK) - return ret; - - /* Set up the compression buffers, we need a loop here to avoid overflowing a - * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited - * by the output buffer size, so there is no need to check that. Since this - * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits - * in size. - */ - { - png_compression_bufferp *end = &png_ptr->zbuffer_list; - png_alloc_size_t input_len = comp->input_len; /* may be zero! */ - png_uint_32 output_len; - - /* zlib updates these for us: */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); - png_ptr->zstream.avail_in = 0; /* Set below */ - png_ptr->zstream.next_out = comp->output; - png_ptr->zstream.avail_out = (sizeof comp->output); - - output_len = png_ptr->zstream.avail_out; - - do - { - uInt avail_in = ZLIB_IO_MAX; - - if (avail_in > input_len) - avail_in = (uInt)input_len; - - input_len -= avail_in; - - png_ptr->zstream.avail_in = avail_in; - - if (png_ptr->zstream.avail_out == 0) - { - png_compression_buffer *next; - - /* Chunk data is limited to 2^31 bytes in length, so the prefix - * length must be counted here. - */ - if (output_len + prefix_len > PNG_UINT_31_MAX) - { - ret = Z_MEM_ERROR; - break; - } - - /* Need a new (malloc'ed) buffer, but there may be one present - * already. - */ - next = *end; - if (next == NULL) - { - next = png_voidcast(png_compression_bufferp, png_malloc_base - (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); - - if (next == NULL) - { - ret = Z_MEM_ERROR; - break; - } - - /* Link in this buffer (so that it will be freed later) */ - next->next = NULL; - *end = next; - } - - png_ptr->zstream.next_out = next->output; - png_ptr->zstream.avail_out = png_ptr->zbuffer_size; - output_len += png_ptr->zstream.avail_out; - - /* Move 'end' to the next buffer pointer. */ - end = &next->next; - } - - /* Compress the data */ - ret = deflate(&png_ptr->zstream, - input_len > 0 ? Z_NO_FLUSH : Z_FINISH); - - /* Claw back input data that was not consumed (because avail_in is - * reset above every time round the loop). - */ - input_len += png_ptr->zstream.avail_in; - png_ptr->zstream.avail_in = 0; /* safety */ - } - while (ret == Z_OK); - - /* There may be some space left in the last output buffer. This needs to - * be subtracted from output_len. - */ - output_len -= png_ptr->zstream.avail_out; - png_ptr->zstream.avail_out = 0; /* safety */ - comp->output_len = output_len; - - /* Now double check the output length, put in a custom message if it is - * too long. Otherwise ensure the z_stream::msg pointer is set to - * something. - */ - if (output_len + prefix_len >= PNG_UINT_31_MAX) - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); - ret = Z_MEM_ERROR; - } - - else - png_zstream_error(png_ptr, ret); - - /* Reset zlib for another zTXt/iTXt or image data */ - png_ptr->zowner = 0; - - /* The only success case is Z_STREAM_END, input_len must be 0; if not this - * is an internal error. - */ - if (ret == Z_STREAM_END && input_len == 0) - { -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - /* Fix up the deflate header, if required */ - optimize_cmf(comp->output, comp->input_len); -#endif - /* But Z_OK is returned, not Z_STREAM_END; this allows the claim - * function above to return Z_STREAM_END on an error (though it never - * does in the current versions of zlib.) - */ - return Z_OK; - } - - else - return ret; - } -} - -/* Ship the compressed text out via chunk writes */ -static void -png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) -{ - png_uint_32 output_len = comp->output_len; - png_const_bytep output = comp->output; - png_uint_32 avail = (sizeof comp->output); - png_compression_buffer *next = png_ptr->zbuffer_list; - - for (;;) - { - if (avail > output_len) - avail = output_len; - - png_write_chunk_data(png_ptr, output, avail); - - output_len -= avail; - - if (output_len == 0 || next == NULL) - break; - - avail = png_ptr->zbuffer_size; - output = next->output; - next = next->next; - } - - /* This is an internal error; 'next' must have been NULL! */ - if (output_len > 0) - png_error(png_ptr, "error writing ancillary chunked compressed data"); -} -#endif /* WRITE_COMPRESSED_TEXT */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. Note that the rest of this code depends upon this - * information being correct. - */ -void /* PRIVATE */ -png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, - int bit_depth, int color_type, int compression_type, int filter_type, - int interlace_type) -{ - png_byte buf[13]; /* Buffer to store the IHDR info */ - int is_invalid_depth; - - png_debug(1, "in png_write_IHDR"); - - /* Check that we have valid input data from the application info */ - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: -#ifdef PNG_WRITE_16BIT_SUPPORTED - case 16: -#endif - png_ptr->channels = 1; break; - - default: - png_error(png_ptr, - "Invalid bit depth for grayscale image"); - } - break; - - case PNG_COLOR_TYPE_RGB: - is_invalid_depth = (bit_depth != 8); -#ifdef PNG_WRITE_16BIT_SUPPORTED - is_invalid_depth = (is_invalid_depth && bit_depth != 16); -#endif - if (is_invalid_depth) - png_error(png_ptr, "Invalid bit depth for RGB image"); - - png_ptr->channels = 3; - break; - - case PNG_COLOR_TYPE_PALETTE: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: - png_ptr->channels = 1; - break; - - default: - png_error(png_ptr, "Invalid bit depth for paletted image"); - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - is_invalid_depth = (bit_depth != 8); -#ifdef PNG_WRITE_16BIT_SUPPORTED - is_invalid_depth = (is_invalid_depth && bit_depth != 16); -#endif - if (is_invalid_depth) - png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); - - png_ptr->channels = 2; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - is_invalid_depth = (bit_depth != 8); -#ifdef PNG_WRITE_16BIT_SUPPORTED - is_invalid_depth = (is_invalid_depth && bit_depth != 16); -#endif - if (is_invalid_depth) - png_error(png_ptr, "Invalid bit depth for RGBA image"); - - png_ptr->channels = 4; - break; - - default: - png_error(png_ptr, "Invalid image color type specified"); - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Invalid compression type specified"); - compression_type = PNG_COMPRESSION_TYPE_BASE; - } - - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ( -#ifdef PNG_MNG_FEATURES_SUPPORTED - !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && -#endif - filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Invalid filter type specified"); - filter_type = PNG_FILTER_TYPE_BASE; - } - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - if (interlace_type != PNG_INTERLACE_NONE && - interlace_type != PNG_INTERLACE_ADAM7) - { - png_warning(png_ptr, "Invalid interlace type specified"); - interlace_type = PNG_INTERLACE_ADAM7; - } -#else - interlace_type=PNG_INTERLACE_NONE; -#endif - - /* Save the relevant information */ - png_ptr->bit_depth = (png_byte)bit_depth; - png_ptr->color_type = (png_byte)color_type; - png_ptr->interlaced = (png_byte)interlace_type; -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_ptr->filter_type = (png_byte)filter_type; -#endif - png_ptr->compression_type = (png_byte)compression_type; - png_ptr->width = width; - png_ptr->height = height; - - png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); - /* Set the usr info, so any transformations can modify it */ - png_ptr->usr_width = png_ptr->width; - png_ptr->usr_bit_depth = png_ptr->bit_depth; - png_ptr->usr_channels = png_ptr->channels; - - /* Pack the header information into the buffer */ - png_save_uint_32(buf, width); - png_save_uint_32(buf + 4, height); - buf[8] = (png_byte)bit_depth; - buf[9] = (png_byte)color_type; - buf[10] = (png_byte)compression_type; - buf[11] = (png_byte)filter_type; - buf[12] = (png_byte)interlace_type; - - /* Write the chunk */ - png_write_complete_chunk(png_ptr, png_IHDR, buf, 13); - - if ((png_ptr->do_filter) == PNG_NO_FILTERS) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - png_ptr->bit_depth < 8) - png_ptr->do_filter = PNG_FILTER_NONE; - - else - png_ptr->do_filter = PNG_ALL_FILTERS; - } - - png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ -} - -/* Write the palette. We are careful not to trust png_color to be in the - * correct order for PNG, so people can redefine it to any convenient - * structure. - */ -void /* PRIVATE */ -png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, - png_uint_32 num_pal) -{ - png_uint_32 max_palette_length, i; - png_const_colorp pal_ptr; - png_byte buf[3]; - - png_debug(1, "in png_write_PLTE"); - - max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? - (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; - - if (( -#ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && -#endif - num_pal == 0) || num_pal > max_palette_length) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_error(png_ptr, "Invalid number of colors in palette"); - } - - else - { - png_warning(png_ptr, "Invalid number of colors in palette"); - return; - } - } - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_warning(png_ptr, - "Ignoring request to write a PLTE chunk in grayscale PNG"); - - return; - } - - png_ptr->num_palette = (png_uint_16)num_pal; - png_debug1(3, "num_palette = %d", png_ptr->num_palette); - - png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); -#ifdef PNG_POINTER_INDEXING_SUPPORTED - - for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) - { - buf[0] = pal_ptr->red; - buf[1] = pal_ptr->green; - buf[2] = pal_ptr->blue; - png_write_chunk_data(png_ptr, buf, 3); - } - -#else - /* This is a little slower but some buggy compilers need to do this - * instead - */ - pal_ptr=palette; - - for (i = 0; i < num_pal; i++) - { - buf[0] = pal_ptr[i].red; - buf[1] = pal_ptr[i].green; - buf[2] = pal_ptr[i].blue; - png_write_chunk_data(png_ptr, buf, 3); - } - -#endif - png_write_chunk_end(png_ptr); - png_ptr->mode |= PNG_HAVE_PLTE; -} - -/* This is similar to png_text_compress, above, except that it does not require - * all of the data at once and, instead of buffering the compressed result, - * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out - * because it calls the write interface. As a result it does its own error - * reporting and does not return an error code. In the event of error it will - * just call png_error. The input data length may exceed 32-bits. The 'flush' - * parameter is exactly the same as that to deflate, with the following - * meanings: - * - * Z_NO_FLUSH: normal incremental output of compressed data - * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush - * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up - * - * The routine manages the acquire and release of the png_ptr->zstream by - * checking and (at the end) clearing png_ptr->zowner; it does some sanity - * checks on the 'mode' flags while doing this. - */ -void /* PRIVATE */ -png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, - png_alloc_size_t input_len, int flush) -{ - if (png_ptr->zowner != png_IDAT) - { - /* First time. Ensure we have a temporary buffer for compression and - * trim the buffer list if it has more than one entry to free memory. - * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been - * created at this point, but the check here is quick and safe. - */ - if (png_ptr->zbuffer_list == NULL) - { - png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, - png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); - png_ptr->zbuffer_list->next = NULL; - } - - else - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); - - /* It is a terminal error if we can't claim the zstream. */ - if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - /* The output state is maintained in png_ptr->zstream, so it must be - * initialized here after the claim. - */ - png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; - png_ptr->zstream.avail_out = png_ptr->zbuffer_size; - } - - /* Now loop reading and writing until all the input is consumed or an error - * terminates the operation. The _out values are maintained across calls to - * this function, but the input must be reset each time. - */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); - png_ptr->zstream.avail_in = 0; /* set below */ - for (;;) - { - int ret; - - /* INPUT: from the row data */ - uInt avail = ZLIB_IO_MAX; - - if (avail > input_len) - avail = (uInt)input_len; /* safe because of the check */ - - png_ptr->zstream.avail_in = avail; - input_len -= avail; - - ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); - - /* Include as-yet unconsumed input */ - input_len += png_ptr->zstream.avail_in; - png_ptr->zstream.avail_in = 0; - - /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note - * that these two zstream fields are preserved across the calls, therefore - * there is no need to set these up on entry to the loop. - */ - if (png_ptr->zstream.avail_out == 0) - { - png_bytep data = png_ptr->zbuffer_list->output; - uInt size = png_ptr->zbuffer_size; - - /* Write an IDAT containing the data then reset the buffer. The - * first IDAT may need deflate header optimization. - */ -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && - png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) - optimize_cmf(data, png_image_size(png_ptr)); -#endif - - if (size > 0) - png_write_complete_chunk(png_ptr, png_IDAT, data, size); - png_ptr->mode |= PNG_HAVE_IDAT; - - png_ptr->zstream.next_out = data; - png_ptr->zstream.avail_out = size; - - /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with - * the same flush parameter until it has finished output, for NO_FLUSH - * it doesn't matter. - */ - if (ret == Z_OK && flush != Z_NO_FLUSH) - continue; - } - - /* The order of these checks doesn't matter much; it just affects which - * possible error might be detected if multiple things go wrong at once. - */ - if (ret == Z_OK) /* most likely return code! */ - { - /* If all the input has been consumed then just return. If Z_FINISH - * was used as the flush parameter something has gone wrong if we get - * here. - */ - if (input_len == 0) - { - if (flush == Z_FINISH) - png_error(png_ptr, "Z_OK on Z_FINISH with output space"); - - return; - } - } - - else if (ret == Z_STREAM_END && flush == Z_FINISH) - { - /* This is the end of the IDAT data; any pending output must be - * flushed. For small PNG files we may still be at the beginning. - */ - png_bytep data = png_ptr->zbuffer_list->output; - uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && - png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) - optimize_cmf(data, png_image_size(png_ptr)); -#endif - - if (size > 0) - png_write_complete_chunk(png_ptr, png_IDAT, data, size); - png_ptr->zstream.avail_out = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; - - png_ptr->zowner = 0; /* Release the stream */ - return; - } - - else - { - /* This is an error condition. */ - png_zstream_error(png_ptr, ret); - png_error(png_ptr, png_ptr->zstream.msg); - } - } -} - -/* Write an IEND chunk */ -void /* PRIVATE */ -png_write_IEND(png_structrp png_ptr) -{ - png_debug(1, "in png_write_IEND"); - - png_write_complete_chunk(png_ptr, png_IEND, NULL, 0); - png_ptr->mode |= PNG_HAVE_IEND; -} - -#ifdef PNG_WRITE_gAMA_SUPPORTED -/* Write a gAMA chunk */ -void /* PRIVATE */ -png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) -{ - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_complete_chunk(png_ptr, png_gAMA, buf, 4); -} -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -/* Write a sRGB chunk */ -void /* PRIVATE */ -png_write_sRGB(png_structrp png_ptr, int srgb_intent) -{ - png_byte buf[1]; - - png_debug(1, "in png_write_sRGB"); - - if (srgb_intent >= PNG_sRGB_INTENT_LAST) - png_warning(png_ptr, - "Invalid sRGB rendering intent specified"); - - buf[0]=(png_byte)srgb_intent; - png_write_complete_chunk(png_ptr, png_sRGB, buf, 1); -} -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -/* Write an iCCP chunk */ -void /* PRIVATE */ -png_write_iCCP(png_structrp png_ptr, png_const_charp name, - png_const_bytep profile) -{ - png_uint_32 name_len; - png_uint_32 profile_len; - png_byte new_name[81]; /* 1 byte for the compression byte */ - compression_state comp; - png_uint_32 temp; - - png_debug(1, "in png_write_iCCP"); - - /* These are all internal problems: the profile should have been checked - * before when it was stored. - */ - if (profile == NULL) - png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ - - profile_len = png_get_uint_32(profile); - - if (profile_len < 132) - png_error(png_ptr, "ICC profile too short"); - - temp = (png_uint_32) (*(profile+8)); - if (temp > 3 && (profile_len & 0x03)) - png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); - - { - png_uint_32 embedded_profile_len = png_get_uint_32(profile); - - if (profile_len != embedded_profile_len) - png_error(png_ptr, "Profile length does not match profile"); - } - - name_len = png_check_keyword(png_ptr, name, new_name); - - if (name_len == 0) - png_error(png_ptr, "iCCP: invalid keyword"); - - new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; - - /* Make sure we include the NULL after the name and the compression type */ - ++name_len; - - png_text_compress_init(&comp, profile, profile_len); - - /* Allow for keyword terminator and compression byte */ - if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); - - png_write_chunk_data(png_ptr, new_name, name_len); - - png_write_compressed_data_out(png_ptr, &comp); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -/* Write a sPLT chunk */ -void /* PRIVATE */ -png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) -{ - png_uint_32 name_len; - png_byte new_name[80]; - png_byte entrybuf[10]; - size_t entry_size = (spalette->depth == 8 ? 6 : 10); - size_t palette_size = entry_size * (size_t)spalette->nentries; - png_sPLT_entryp ep; -#ifndef PNG_POINTER_INDEXING_SUPPORTED - int i; -#endif - - png_debug(1, "in png_write_sPLT"); - - name_len = png_check_keyword(png_ptr, spalette->name, new_name); - - if (name_len == 0) - png_error(png_ptr, "sPLT: invalid keyword"); - - /* Make sure we include the NULL after the name */ - png_write_chunk_header(png_ptr, png_sPLT, - (png_uint_32)(name_len + 2 + palette_size)); - - png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1)); - - png_write_chunk_data(png_ptr, &spalette->depth, 1); - - /* Loop through each palette entry, writing appropriately */ -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (ep = spalette->entries; epentries + spalette->nentries; ep++) - { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep->red; - entrybuf[1] = (png_byte)ep->green; - entrybuf[2] = (png_byte)ep->blue; - entrybuf[3] = (png_byte)ep->alpha; - png_save_uint_16(entrybuf + 4, ep->frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep->red); - png_save_uint_16(entrybuf + 2, ep->green); - png_save_uint_16(entrybuf + 4, ep->blue); - png_save_uint_16(entrybuf + 6, ep->alpha); - png_save_uint_16(entrybuf + 8, ep->frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, entry_size); - } -#else - ep=spalette->entries; - for (i = 0; i>spalette->nentries; i++) - { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep[i].red; - entrybuf[1] = (png_byte)ep[i].green; - entrybuf[2] = (png_byte)ep[i].blue; - entrybuf[3] = (png_byte)ep[i].alpha; - png_save_uint_16(entrybuf + 4, ep[i].frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep[i].red); - png_save_uint_16(entrybuf + 2, ep[i].green); - png_save_uint_16(entrybuf + 4, ep[i].blue); - png_save_uint_16(entrybuf + 6, ep[i].alpha); - png_save_uint_16(entrybuf + 8, ep[i].frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, entry_size); - } -#endif - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -/* Write the sBIT chunk */ -void /* PRIVATE */ -png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) -{ - png_byte buf[4]; - size_t size; - - png_debug(1, "in png_write_sBIT"); - - /* Make sure we don't depend upon the order of PNG_COLOR_8 */ - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_byte maxbits; - - maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : - png_ptr->usr_bit_depth); - - if (sbit->red == 0 || sbit->red > maxbits || - sbit->green == 0 || sbit->green > maxbits || - sbit->blue == 0 || sbit->blue > maxbits) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->red; - buf[1] = sbit->green; - buf[2] = sbit->blue; - size = 3; - } - - else - { - if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->gray; - size = 1; - } - - if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[size++] = sbit->alpha; - } - - png_write_complete_chunk(png_ptr, png_sBIT, buf, size); -} -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -/* Write the cHRM chunk */ -void /* PRIVATE */ -png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) -{ - png_byte buf[32]; - - png_debug(1, "in png_write_cHRM"); - - /* Each value is saved in 1/100,000ths */ - png_save_int_32(buf, xy->whitex); - png_save_int_32(buf + 4, xy->whitey); - - png_save_int_32(buf + 8, xy->redx); - png_save_int_32(buf + 12, xy->redy); - - png_save_int_32(buf + 16, xy->greenx); - png_save_int_32(buf + 20, xy->greeny); - - png_save_int_32(buf + 24, xy->bluex); - png_save_int_32(buf + 28, xy->bluey); - - png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); -} -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -/* Write the tRNS chunk */ -void /* PRIVATE */ -png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, - png_const_color_16p tran, int num_trans, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_tRNS"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) - { - png_app_warning(png_ptr, - "Invalid number of transparent colors specified"); - return; - } - - /* Write the chunk out as it is */ - png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, - (size_t)num_trans); - } - - else if (color_type == PNG_COLOR_TYPE_GRAY) - { - /* One 16-bit value */ - if (tran->gray >= (1 << png_ptr->bit_depth)) - { - png_app_warning(png_ptr, - "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, tran->gray); - png_write_complete_chunk(png_ptr, png_tRNS, buf, 2); - } - - else if (color_type == PNG_COLOR_TYPE_RGB) - { - /* Three 16-bit values */ - png_save_uint_16(buf, tran->red); - png_save_uint_16(buf + 2, tran->green); - png_save_uint_16(buf + 4, tran->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) -#else - if ((buf[0] | buf[2] | buf[4]) != 0) -#endif - { - png_app_warning(png_ptr, - "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); - return; - } - - png_write_complete_chunk(png_ptr, png_tRNS, buf, 6); - } - - else - { - png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); - } -} -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -/* Write the background chunk */ -void /* PRIVATE */ -png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_bKGD"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if ( -#ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->num_palette != 0 || - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && -#endif - back->index >= png_ptr->num_palette) - { - png_warning(png_ptr, "Invalid background palette index"); - return; - } - - buf[0] = back->index; - png_write_complete_chunk(png_ptr, png_bKGD, buf, 1); - } - - else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_save_uint_16(buf, back->red); - png_save_uint_16(buf + 2, back->green); - png_save_uint_16(buf + 4, back->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) -#else - if ((buf[0] | buf[2] | buf[4]) != 0) -#endif - { - png_warning(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk " - "when bit_depth is 8"); - - return; - } - - png_write_complete_chunk(png_ptr, png_bKGD, buf, 6); - } - - else - { - if (back->gray >= (1 << png_ptr->bit_depth)) - { - png_warning(png_ptr, - "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, back->gray); - png_write_complete_chunk(png_ptr, png_bKGD, buf, 2); - } -} -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED -/* Write the Exif data */ -void /* PRIVATE */ -png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif) -{ - int i; - png_byte buf[1]; - - png_debug(1, "in png_write_eXIf"); - - png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif)); - - for (i = 0; i < num_exif; i++) - { - buf[0] = exif[i]; - png_write_chunk_data(png_ptr, buf, 1); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -/* Write the histogram */ -void /* PRIVATE */ -png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) -{ - int i; - png_byte buf[3]; - - png_debug(1, "in png_write_hIST"); - - if (num_hist > (int)png_ptr->num_palette) - { - png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, - png_ptr->num_palette); - - png_warning(png_ptr, "Invalid number of histogram entries specified"); - return; - } - - png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); - - for (i = 0; i < num_hist; i++) - { - png_save_uint_16(buf, hist[i]); - png_write_chunk_data(png_ptr, buf, 2); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_tEXt_SUPPORTED -/* Write a tEXt chunk */ -void /* PRIVATE */ -png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - size_t text_len) -{ - png_uint_32 key_len; - png_byte new_key[80]; - - png_debug(1, "in png_write_tEXt"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - png_error(png_ptr, "tEXt: invalid keyword"); - - if (text == NULL || *text == '\0') - text_len = 0; - - else - text_len = strlen(text); - - if (text_len > PNG_UINT_31_MAX - (key_len+1)) - png_error(png_ptr, "tEXt: text too long"); - - /* Make sure we include the 0 after the key */ - png_write_chunk_header(png_ptr, png_tEXt, - (png_uint_32)/*checked above*/(key_len + text_len + 1)); - /* - * We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - */ - png_write_chunk_data(png_ptr, new_key, key_len + 1); - - if (text_len != 0) - png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -/* Write a compressed text chunk */ -void /* PRIVATE */ -png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - int compression) -{ - png_uint_32 key_len; - png_byte new_key[81]; - compression_state comp; - - png_debug(1, "in png_write_zTXt"); - - if (compression == PNG_TEXT_COMPRESSION_NONE) - { - png_write_tEXt(png_ptr, key, text, 0); - return; - } - - if (compression != PNG_TEXT_COMPRESSION_zTXt) - png_error(png_ptr, "zTXt: invalid compression type"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - png_error(png_ptr, "zTXt: invalid keyword"); - - /* Add the compression method and 1 for the keyword separator. */ - new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; - ++key_len; - - /* Compute the compressed data; do it now for the length */ - png_text_compress_init(&comp, (png_const_bytep)text, - text == NULL ? 0 : strlen(text)); - - if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - /* Write start of chunk */ - png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); - - /* Write key */ - png_write_chunk_data(png_ptr, new_key, key_len); - - /* Write the compressed data */ - png_write_compressed_data_out(png_ptr, &comp); - - /* Close the chunk */ - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -/* Write an iTXt chunk */ -void /* PRIVATE */ -png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, - png_const_charp lang, png_const_charp lang_key, png_const_charp text) -{ - png_uint_32 key_len, prefix_len; - size_t lang_len, lang_key_len; - png_byte new_key[82]; - compression_state comp; - - png_debug(1, "in png_write_iTXt"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - png_error(png_ptr, "iTXt: invalid keyword"); - - /* Set the compression flag */ - switch (compression) - { - case PNG_ITXT_COMPRESSION_NONE: - case PNG_TEXT_COMPRESSION_NONE: - compression = new_key[++key_len] = 0; /* no compression */ - break; - - case PNG_TEXT_COMPRESSION_zTXt: - case PNG_ITXT_COMPRESSION_zTXt: - compression = new_key[++key_len] = 1; /* compressed */ - break; - - default: - png_error(png_ptr, "iTXt: invalid compression"); - } - - new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; - ++key_len; /* for the keywod separator */ - - /* We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, - * specifies that the text is UTF-8 and this really doesn't require any - * checking. - * - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - * - * TODO: validate the language tag correctly (see the spec.) - */ - if (lang == NULL) lang = ""; /* empty language is valid */ - lang_len = strlen(lang)+1; - if (lang_key == NULL) lang_key = ""; /* may be empty */ - lang_key_len = strlen(lang_key)+1; - if (text == NULL) text = ""; /* may be empty */ - - prefix_len = key_len; - if (lang_len > PNG_UINT_31_MAX-prefix_len) - prefix_len = PNG_UINT_31_MAX; - else - prefix_len = (png_uint_32)(prefix_len + lang_len); - - if (lang_key_len > PNG_UINT_31_MAX-prefix_len) - prefix_len = PNG_UINT_31_MAX; - else - prefix_len = (png_uint_32)(prefix_len + lang_key_len); - - png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); - - if (compression != 0) - { - if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - } - - else - { - if (comp.input_len > PNG_UINT_31_MAX-prefix_len) - png_error(png_ptr, "iTXt: uncompressed text too long"); - - /* So the string will fit in a chunk: */ - comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; - } - - png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); - - png_write_chunk_data(png_ptr, new_key, key_len); - - png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); - - png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); - - if (compression != 0) - png_write_compressed_data_out(png_ptr, &comp); - - else - png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -/* Write the oFFs chunk */ -void /* PRIVATE */ -png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_oFFs"); - - if (unit_type >= PNG_OFFSET_LAST) - png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); - - png_save_int_32(buf, x_offset); - png_save_int_32(buf + 4, y_offset); - buf[8] = (png_byte)unit_type; - - png_write_complete_chunk(png_ptr, png_oFFs, buf, 9); -} -#endif -#ifdef PNG_WRITE_pCAL_SUPPORTED -/* Write the pCAL chunk (described in the PNG extensions document) */ -void /* PRIVATE */ -png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, - png_int_32 X1, int type, int nparams, png_const_charp units, - png_charpp params) -{ - png_uint_32 purpose_len; - size_t units_len, total_len; - size_t *params_len; - png_byte buf[10]; - png_byte new_purpose[80]; - int i; - - png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); - - if (type >= PNG_EQUATION_LAST) - png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); - - purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); - - if (purpose_len == 0) - png_error(png_ptr, "pCAL: invalid keyword"); - - ++purpose_len; /* terminator */ - - png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); - units_len = strlen(units) + (nparams == 0 ? 0 : 1); - png_debug1(3, "pCAL units length = %d", (int)units_len); - total_len = purpose_len + units_len + 10; - - params_len = (size_t *)png_malloc(png_ptr, - (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t)))); - - /* Find the length of each parameter, making sure we don't count the - * null terminator for the last parameter. - */ - for (i = 0; i < nparams; i++) - { - params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); - png_debug2(3, "pCAL parameter %d length = %lu", i, - (unsigned long)params_len[i]); - total_len += params_len[i]; - } - - png_debug1(3, "pCAL total length = %d", (int)total_len); - png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, new_purpose, purpose_len); - png_save_int_32(buf, X0); - png_save_int_32(buf + 4, X1); - buf[8] = (png_byte)type; - buf[9] = (png_byte)nparams; - png_write_chunk_data(png_ptr, buf, 10); - png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len); - - for (i = 0; i < nparams; i++) - { - png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); - } - - png_free(png_ptr, params_len); - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -/* Write the sCAL chunk */ -void /* PRIVATE */ -png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, - png_const_charp height) -{ - png_byte buf[64]; - size_t wlen, hlen, total_len; - - png_debug(1, "in png_write_sCAL_s"); - - wlen = strlen(width); - hlen = strlen(height); - total_len = wlen + hlen + 2; - - if (total_len > 64) - { - png_warning(png_ptr, "Can't write sCAL (buffer too small)"); - return; - } - - buf[0] = (png_byte)unit; - memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ - memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); -} -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -/* Write the pHYs chunk */ -void /* PRIVATE */ -png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_pHYs"); - - if (unit_type >= PNG_RESOLUTION_LAST) - png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); - - png_save_uint_32(buf, x_pixels_per_unit); - png_save_uint_32(buf + 4, y_pixels_per_unit); - buf[8] = (png_byte)unit_type; - - png_write_complete_chunk(png_ptr, png_pHYs, buf, 9); -} -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -/* Write the tIME chunk. Use either png_convert_from_struct_tm() - * or png_convert_from_time_t(), or fill in the structure yourself. - */ -void /* PRIVATE */ -png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) -{ - png_byte buf[7]; - - png_debug(1, "in png_write_tIME"); - - if (mod_time->month > 12 || mod_time->month < 1 || - mod_time->day > 31 || mod_time->day < 1 || - mod_time->hour > 23 || mod_time->second > 60) - { - png_warning(png_ptr, "Invalid time specified for tIME chunk"); - return; - } - - png_save_uint_16(buf, mod_time->year); - buf[2] = mod_time->month; - buf[3] = mod_time->day; - buf[4] = mod_time->hour; - buf[5] = mod_time->minute; - buf[6] = mod_time->second; - - png_write_complete_chunk(png_ptr, png_tIME, buf, 7); -} -#endif - -/* Initializes the row writing capability of libpng */ -void /* PRIVATE */ -png_write_start_row(png_structrp png_ptr) -{ -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - png_alloc_size_t buf_size; - int usr_pixel_depth; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_byte filters; -#endif - - png_debug(1, "in png_write_start_row"); - - usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; - buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; - - /* 1.5.6: added to allow checking in the row write code. */ - png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; - png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; - - /* Set up row buffer */ - png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); - - png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - filters = png_ptr->do_filter; - - if (png_ptr->height == 1) - filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if (png_ptr->width == 1) - filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if (filters == 0) - filters = PNG_FILTER_NONE; - - png_ptr->do_filter = filters; - - if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | - PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL) - { - int num_filters = 0; - - png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); - - if (filters & PNG_FILTER_SUB) - num_filters++; - - if (filters & PNG_FILTER_UP) - num_filters++; - - if (filters & PNG_FILTER_AVG) - num_filters++; - - if (filters & PNG_FILTER_PAETH) - num_filters++; - - if (num_filters > 1) - png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr, - buf_size)); - } - - /* We only need to keep the previous row if we are using one of the following - * filters. - */ - if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) - png_ptr->prev_row = png_voidcast(png_bytep, - png_calloc(png_ptr, buf_size)); -#endif /* WRITE_FILTER */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, we need to set up width and height of pass */ - if (png_ptr->interlaced != 0) - { - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - { - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - - png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - - png_pass_start[0]) / png_pass_inc[0]; - } - - else - { - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } - } - - else -#endif - { - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } -} - -/* Internal use only. Called when finished processing a row of data. */ -void /* PRIVATE */ -png_write_finish_row(png_structrp png_ptr) -{ -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - png_debug(1, "in png_write_finish_row"); - - /* Next row */ - png_ptr->row_number++; - - /* See if we are done */ - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, go to next pass */ - if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - if ((png_ptr->transformations & PNG_INTERLACE) != 0) - { - png_ptr->pass++; - } - - else - { - /* Loop until we find a non-zero width or height pass */ - do - { - png_ptr->pass++; - - if (png_ptr->pass >= 7) - break; - - png_ptr->usr_width = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - - if ((png_ptr->transformations & PNG_INTERLACE) != 0) - break; - - } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); - - } - - /* Reset the row above the image for the next pass */ - if (png_ptr->pass < 7) - { - if (png_ptr->prev_row != NULL) - memset(png_ptr->prev_row, 0, - PNG_ROWBYTES(png_ptr->usr_channels * - png_ptr->usr_bit_depth, png_ptr->width) + 1); - - return; - } - } -#endif - - /* If we get here, we've just written the last row, so we need - to flush the compressor */ - png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); -} - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Pick out the correct pixels for the interlace pass. - * The basic idea here is to go through the row with a source - * pointer and a destination pointer (sp and dp), and copy the - * correct pixels for the pass. As the row gets compacted, - * sp will always be >= dp, so we should never overwrite anything. - * See the default: case for the easiest code to understand. - */ -void /* PRIVATE */ -png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_write_interlace"); - - /* We don't have to do anything on the last pass (6) */ - if (pass < 6) - { - /* Each pixel depth is handled separately */ - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp; - png_bytep dp; - unsigned int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - d = 0; - shift = 7; - - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (size_t)(i >> 3); - value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; - d |= (value << shift); - - if (shift == 0) - { - shift = 7; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift--; - - } - if (shift != 7) - *dp = (png_byte)d; - - break; - } - - case 2: - { - png_bytep sp; - png_bytep dp; - unsigned int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - shift = 6; - d = 0; - - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (size_t)(i >> 2); - value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; - d |= (value << shift); - - if (shift == 0) - { - shift = 6; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift -= 2; - } - if (shift != 6) - *dp = (png_byte)d; - - break; - } - - case 4: - { - png_bytep sp; - png_bytep dp; - unsigned int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - shift = 4; - d = 0; - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (size_t)(i >> 1); - value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; - d |= (value << shift); - - if (shift == 0) - { - shift = 4; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift -= 4; - } - if (shift != 4) - *dp = (png_byte)d; - - break; - } - - default: - { - png_bytep sp; - png_bytep dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - size_t pixel_bytes; - - /* Start at the beginning */ - dp = row; - - /* Find out how many bytes each pixel takes up */ - pixel_bytes = (row_info->pixel_depth >> 3); - - /* Loop through the row, only looking at the pixels that matter */ - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - /* Find out where the original pixel is */ - sp = row + (size_t)i * pixel_bytes; - - /* Move the pixel */ - if (dp != sp) - memcpy(dp, sp, pixel_bytes); - - /* Next pixel */ - dp += pixel_bytes; - } - break; - } - } - /* Set new row width */ - row_info->width = (row_info->width + - png_pass_inc[pass] - 1 - - png_pass_start[pass]) / - png_pass_inc[pass]; - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); - } -} -#endif - - -/* This filters the row, chooses which filter to use, if it has not already - * been specified by the application, and then writes the row out with the - * chosen filter. - */ -static void /* PRIVATE */ -png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - size_t row_bytes); - -#ifdef PNG_WRITE_FILTER_SUPPORTED -static size_t /* PRIVATE */ -png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, lp; - size_t i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; - i++, rp++, dp++) - { - v = *dp = *rp; -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return sum; -} - -static void /* PRIVATE */ -png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes) -{ - png_bytep rp, dp, lp; - size_t i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; - i++, rp++, dp++) - { - *dp = *rp; - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); - } -} - -static size_t /* PRIVATE */ -png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, pp; - size_t i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) - { - v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return sum; -} -static void /* PRIVATE */ -png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) -{ - png_bytep rp, dp, pp; - size_t i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) - { - *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); - } -} - -static size_t /* PRIVATE */ -png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, pp, lp; - png_uint_32 i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) - & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return sum; -} -static void /* PRIVATE */ -png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes) -{ - png_bytep rp, dp, pp, lp; - png_uint_32 i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) - { - *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) - & 0xff); - } -} - -static size_t /* PRIVATE */ -png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, pp, cp, lp; - size_t i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - - for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; - i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return sum; -} -static void /* PRIVATE */ -png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes) -{ - png_bytep rp, dp, pp, cp, lp; - size_t i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - } - - for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; - i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - } -} -#endif /* WRITE_FILTER */ - -void /* PRIVATE */ -png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) -{ -#ifndef PNG_WRITE_FILTER_SUPPORTED - png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); -#else - unsigned int filter_to_do = png_ptr->do_filter; - png_bytep row_buf; - png_bytep best_row; - png_uint_32 bpp; - size_t mins; - size_t row_bytes = row_info->rowbytes; - - png_debug(1, "in png_write_find_filter"); - - /* Find out how many bytes offset each pixel is */ - bpp = (row_info->pixel_depth + 7) >> 3; - - row_buf = png_ptr->row_buf; - mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the - running sum */; - - /* The prediction method we use is to find which method provides the - * smallest value when summing the absolute values of the distances - * from zero, using anything >= 128 as negative numbers. This is known - * as the "minimum sum of absolute differences" heuristic. Other - * heuristics are the "weighted minimum sum of absolute differences" - * (experimental and can in theory improve compression), and the "zlib - * predictive" method (not implemented yet), which does test compressions - * of lines using different filter methods, and then chooses the - * (series of) filter(s) that give minimum compressed data size (VERY - * computationally expensive). - * - * GRR 980525: consider also - * - * (1) minimum sum of absolute differences from running average (i.e., - * keep running sum of non-absolute differences & count of bytes) - * [track dispersion, too? restart average if dispersion too large?] - * - * (1b) minimum sum of absolute differences from sliding average, probably - * with window size <= deflate window (usually 32K) - * - * (2) minimum sum of squared differences from zero or running average - * (i.e., ~ root-mean-square approach) - */ - - - /* We don't need to test the 'no filter' case if this is the only filter - * that has been chosen, as it doesn't actually do anything to the data. - */ - best_row = png_ptr->row_buf; - - if (PNG_SIZE_MAX/128 <= row_bytes) - { - /* Overflow can occur in the calculation, just select the lowest set - * filter. - */ - filter_to_do &= 0U-filter_to_do; - } - else if ((filter_to_do & PNG_FILTER_NONE) != 0 && - filter_to_do != PNG_FILTER_NONE) - { - /* Overflow not possible and multiple filters in the list, including the - * 'none' filter. - */ - png_bytep rp; - size_t sum = 0; - size_t i; - unsigned int v; - - { - for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) - { - v = *rp; -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - } - - mins = sum; - } - - /* Sub filter */ - if (filter_to_do == PNG_FILTER_SUB) - /* It's the only filter so no testing is needed */ - { - png_setup_sub_row_only(png_ptr, bpp, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_SUB) != 0) - { - size_t sum; - size_t lmins = mins; - - sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Up filter */ - if (filter_to_do == PNG_FILTER_UP) - { - png_setup_up_row_only(png_ptr, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_UP) != 0) - { - size_t sum; - size_t lmins = mins; - - sum = png_setup_up_row(png_ptr, row_bytes, lmins); - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Avg filter */ - if (filter_to_do == PNG_FILTER_AVG) - { - png_setup_avg_row_only(png_ptr, bpp, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_AVG) != 0) - { - size_t sum; - size_t lmins = mins; - - sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Paeth filter */ - if (filter_to_do == PNG_FILTER_PAETH) - { - png_setup_paeth_row_only(png_ptr, bpp, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_PAETH) != 0) - { - size_t sum; - size_t lmins = mins; - - sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); - - if (sum < mins) - { - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Do the actual writing of the filtered row data from the chosen filter. */ - png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); - -#endif /* WRITE_FILTER */ -} - - -/* Do the actual writing of a previously filtered row. */ -static void -png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - size_t full_row_length/*includes filter byte*/) -{ - png_debug(1, "in png_write_filtered_row"); - - png_debug1(2, "filter = %d", filtered_row[0]); - - png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); - -#ifdef PNG_WRITE_FILTER_SUPPORTED - /* Swap the current and previous rows */ - if (png_ptr->prev_row != NULL) - { - png_bytep tptr; - - tptr = png_ptr->prev_row; - png_ptr->prev_row = png_ptr->row_buf; - png_ptr->row_buf = tptr; - } -#endif /* WRITE_FILTER */ - - /* Finish row - updates counters and flushes zlib if last row */ - png_write_finish_row(png_ptr); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->flush_rows++; - - if (png_ptr->flush_dist > 0 && - png_ptr->flush_rows >= png_ptr->flush_dist) - { - png_write_flush(png_ptr); - } -#endif /* WRITE_FLUSH */ -} -#endif /* WRITE */ +/* pngwutil.c - utilities to write a PNG file + * + * Copyright (c) 2018-2026 Cosmin Truta + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * + * This file contains routines that are only called from within + * libpng itself during the course of writing an image. + */ + +#include "pngpriv.h" + +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED +/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */ + +/* Start of interlace block */ +static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; +/* Offset to next interlace block */ +static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +/* Start of interlace block in the y direction */ +static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; +/* Offset to next interlace block in the y direction */ +static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + +/* TODO: Move these arrays to a common utility module to avoid duplication. */ +#endif + +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +/* Place a 32-bit number into a buffer in PNG byte order. We work + * with unsigned numbers for convenience, although one supported + * ancillary chunk uses signed (two's complement) numbers. + */ +void PNGAPI +png_save_uint_32(png_bytep buf, png_uint_32 i) +{ + buf[0] = (png_byte)((i >> 24) & 0xffU); + buf[1] = (png_byte)((i >> 16) & 0xffU); + buf[2] = (png_byte)((i >> 8) & 0xffU); + buf[3] = (png_byte)( i & 0xffU); +} + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +void PNGAPI +png_save_uint_16(png_bytep buf, unsigned int i) +{ + buf[0] = (png_byte)((i >> 8) & 0xffU); + buf[1] = (png_byte)( i & 0xffU); +} +#endif + +/* Simple function to write the signature. If we have already written + * the magic bytes of the signature, or more likely, the PNG stream is + * being embedded into another stream and doesn't need its own signature, + * we should call png_set_sig_bytes() to tell libpng how many of the + * bytes have already been written. + */ +void PNGAPI +png_write_sig(png_structrp png_ptr) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the signature is being written */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; +#endif + + /* Write the rest of the 8 byte signature */ + png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], + (size_t)(8 - png_ptr->sig_bytes)); + + if (png_ptr->sig_bytes < 3) + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; +} + +/* Write the start of a PNG chunk. The type is the chunk type. + * The total_length is the sum of the lengths of all the data you will be + * passing in png_write_chunk_data(). + */ +static void +png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, + png_uint_32 length) +{ + png_byte buf[8]; + +#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) + PNG_CSTRING_FROM_CHUNK(buf, chunk_name); + png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); +#endif + + if (png_ptr == NULL) + return; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk header is being written. + * PNG_IO_CHUNK_HDR requires a single I/O call. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; +#endif + + /* Write the length and the chunk name */ + png_save_uint_32(buf, length); + png_save_uint_32(buf + 4, chunk_name); + png_write_data(png_ptr, buf, 8); + + /* Put the chunk name into png_ptr->chunk_name */ + png_ptr->chunk_name = chunk_name; + + /* Reset the crc and run it over the chunk name */ + png_reset_crc(png_ptr); + + png_calculate_crc(png_ptr, buf + 4, 4); + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that chunk data will (possibly) be written. + * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; +#endif +} + +void PNGAPI +png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, + png_uint_32 length) +{ + png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); +} + +/* Write the data of a PNG chunk started with png_write_chunk_header(). + * Note that multiple calls to this function are allowed, and that the + * sum of the lengths from these calls *must* add up to the total_length + * given to png_write_chunk_header(). + */ +void PNGAPI +png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length) +{ + /* Write the data, and run the CRC over it */ + if (png_ptr == NULL) + return; + + if (data != NULL && length > 0) + { + png_write_data(png_ptr, data, length); + + /* Update the CRC after writing the data, + * in case the user I/O routine alters it. + */ + png_calculate_crc(png_ptr, data, length); + } +} + +/* Finish a chunk started with png_write_chunk_header(). */ +void PNGAPI +png_write_chunk_end(png_structrp png_ptr) +{ + png_byte buf[4]; + + if (png_ptr == NULL) return; + +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk CRC is being written. + * PNG_IO_CHUNK_CRC requires a single I/O function call. + */ + png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; +#endif + + /* Write the crc in a single operation */ + png_save_uint_32(buf, png_ptr->crc); + + png_write_data(png_ptr, buf, 4); +} + +/* Write a PNG chunk all at once. The type is an array of ASCII characters + * representing the chunk name. The array must be at least 4 bytes in + * length, and does not need to be null terminated. To be safe, pass the + * pre-defined chunk names here, and if you need a new one, define it + * where the others are defined. The length is the length of the data. + * All the data must be present. If that is not possible, use the + * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() + * functions instead. + */ +static void +png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, + png_const_bytep data, size_t length) +{ + if (png_ptr == NULL) + return; + + /* On 64-bit architectures 'length' may not fit in a png_uint_32. */ + if (length > PNG_UINT_31_MAX) + png_error(png_ptr, "length exceeds PNG maximum"); + + png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); + png_write_chunk_data(png_ptr, data, length); + png_write_chunk_end(png_ptr); +} + +/* This is the API that calls the internal function above. */ +void PNGAPI +png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, + png_const_bytep data, size_t length) +{ + png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, + length); +} + +/* This is used below to find the size of an image to pass to png_deflate_claim, + * so it only needs to be accurate if the size is less than 16384 bytes (the + * point at which a lower LZ window size can be used.) + */ +static png_alloc_size_t +png_image_size(png_structrp png_ptr) +{ + /* Only return sizes up to the maximum of a png_uint_32; do this by limiting + * the width and height used to 15 bits. + */ + png_uint_32 h = png_ptr->height; + + if (png_ptr->rowbytes < 32768 && h < 32768) + { + if (png_ptr->interlaced != 0) + { + /* Interlacing makes the image larger because of the replication of + * both the filter byte and the padding to a byte boundary. + */ + png_uint_32 w = png_ptr->width; + unsigned int pd = png_ptr->pixel_depth; + png_alloc_size_t cb_base; + int pass; + + for (cb_base=0, pass=0; pass<=6; ++pass) + { + png_uint_32 pw = PNG_PASS_COLS(w, pass); + + if (pw > 0) + cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); + } + + return cb_base; + } + + else + return (png_ptr->rowbytes+1) * h; + } + + else + return 0xffffffffU; +} + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* This is the code to hack the first two bytes of the deflate stream (the + * deflate header) to correct the windowBits value to match the actual data + * size. Note that the second argument is the *uncompressed* size but the + * first argument is the *compressed* data (and it must be deflate + * compressed.) + */ +static void +optimize_cmf(png_bytep data, png_alloc_size_t data_size) +{ + /* Optimize the CMF field in the zlib stream. The resultant zlib stream is + * still compliant to the stream specification. + */ + if (data_size <= 16384) /* else windowBits must be 15 */ + { + unsigned int z_cmf = data[0]; /* zlib compression method and flags */ + + if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) + { + unsigned int z_cinfo; + unsigned int half_z_window_size; + + z_cinfo = z_cmf >> 4; + half_z_window_size = 1U << (z_cinfo + 7); + + if (data_size <= half_z_window_size) /* else no change */ + { + unsigned int tmp; + + do + { + half_z_window_size >>= 1; + --z_cinfo; + } + while (z_cinfo > 0 && data_size <= half_z_window_size); + + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); + + data[0] = (png_byte)z_cmf; + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; + } + } + } +} +#endif /* WRITE_OPTIMIZE_CMF */ + +/* Initialize the compressor for the appropriate type of compression. */ +static int +png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, + png_alloc_size_t data_size) +{ + if (png_ptr->zowner != 0) + { +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) + char msg[64]; + + PNG_STRING_FROM_CHUNK(msg, owner); + msg[4] = ':'; + msg[5] = ' '; + PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); + /* So the message that results is " using zstream"; this is an + * internal error, but is very useful for debugging. i18n requirements + * are minimal. + */ + (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); +#endif +#if PNG_RELEASE_BUILD + png_warning(png_ptr, msg); + + /* Attempt sane error recovery */ + if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); + return Z_STREAM_ERROR; + } + + png_ptr->zowner = 0; +#else + png_error(png_ptr, msg); +#endif + } + + { + int level = png_ptr->zlib_level; + int method = png_ptr->zlib_method; + int windowBits = png_ptr->zlib_window_bits; + int memLevel = png_ptr->zlib_mem_level; + int strategy; /* set below */ + int ret; /* zlib return code */ + + if (owner == png_IDAT) + { + if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) + strategy = png_ptr->zlib_strategy; + + else if (png_ptr->do_filter != PNG_FILTER_NONE) + strategy = PNG_Z_DEFAULT_STRATEGY; + + else + strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; + } + + else + { +#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED + level = png_ptr->zlib_text_level; + method = png_ptr->zlib_text_method; + windowBits = png_ptr->zlib_text_window_bits; + memLevel = png_ptr->zlib_text_mem_level; + strategy = png_ptr->zlib_text_strategy; +#else + /* If customization is not supported the values all come from the + * IDAT values except for the strategy, which is fixed to the + * default. (This is the pre-1.6.0 behavior too, although it was + * implemented in a very different way.) + */ + strategy = Z_DEFAULT_STRATEGY; +#endif + } + + /* Adjust 'windowBits' down if larger than 'data_size'; to stop this + * happening just pass 32768 as the data_size parameter. Notice that zlib + * requires an extra 262 bytes in the window in addition to the data to be + * able to see the whole of the data, so if data_size+262 takes us to the + * next windowBits size we need to fix up the value later. (Because even + * though deflate needs the extra window, inflate does not!) + */ + if (data_size <= 16384) + { + /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to + * work round a Microsoft Visual C misbehavior which, contrary to C-90, + * widens the result of the following shift to 64-bits if (and, + * apparently, only if) it is used in a test. + */ + unsigned int half_window_size = 1U << (windowBits-1); + + while (data_size + 262 <= half_window_size) + { + half_window_size >>= 1; + --windowBits; + } + } + + /* Check against the previous initialized values, if any. */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && + (png_ptr->zlib_set_level != level || + png_ptr->zlib_set_method != method || + png_ptr->zlib_set_window_bits != windowBits || + png_ptr->zlib_set_mem_level != memLevel || + png_ptr->zlib_set_strategy != strategy)) + { + if (deflateEnd(&png_ptr->zstream) != Z_OK) + png_warning(png_ptr, "deflateEnd failed (ignored)"); + + png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; + } + + /* For safety clear out the input and output pointers (currently zlib + * doesn't use them on Init, but it might in the future). + */ + png_ptr->zstream.next_in = NULL; + png_ptr->zstream.avail_in = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->zstream.avail_out = 0; + + /* Now initialize if required, setting the new parameters, otherwise just + * do a simple reset to the previous parameters. + */ + if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) + ret = deflateReset(&png_ptr->zstream); + + else + { + ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, + memLevel, strategy); + + if (ret == Z_OK) + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; + } + + /* The return code is from either deflateReset or deflateInit2; they have + * pretty much the same set of error codes. + */ + if (ret == Z_OK) + png_ptr->zowner = owner; + + else + png_zstream_error(png_ptr, ret); + + return ret; + } +} + +/* Clean up (or trim) a linked list of compression buffers. */ +void /* PRIVATE */ +png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) +{ + png_compression_bufferp list = *listp; + + if (list != NULL) + { + *listp = NULL; + + do + { + png_compression_bufferp next = list->next; + + png_free(png_ptr, list); + list = next; + } + while (list != NULL); + } +} + +#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED +/* This pair of functions encapsulates the operation of (a) compressing a + * text string, and (b) issuing it later as a series of chunk data writes. + * The compression_state structure is shared context for these functions + * set up by the caller to allow access to the relevant local variables. + * + * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size + * temporary buffers. From 1.6.0 it is retained in png_struct so that it will + * be correctly freed in the event of a write error (previous implementations + * just leaked memory.) + */ +typedef struct +{ + png_const_bytep input; /* The uncompressed input data */ + png_alloc_size_t input_len; /* Its length */ + png_uint_32 output_len; /* Final compressed length */ + png_byte output[1024]; /* First block of output */ +} compression_state; + +static void +png_text_compress_init(compression_state *comp, png_const_bytep input, + png_alloc_size_t input_len) +{ + comp->input = input; + comp->input_len = input_len; + comp->output_len = 0; +} + +/* Compress the data in the compression state input */ +static int +png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, + compression_state *comp, png_uint_32 prefix_len) +{ + int ret; + + /* To find the length of the output it is necessary to first compress the + * input. The result is buffered rather than using the two-pass algorithm + * that is used on the inflate side; deflate is assumed to be slower and a + * PNG writer is assumed to have more memory available than a PNG reader. + * + * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an + * upper limit on the output size, but it is always bigger than the input + * size so it is likely to be more efficient to use this linked-list + * approach. + */ + ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); + + if (ret != Z_OK) + return ret; + + /* Set up the compression buffers, we need a loop here to avoid overflowing a + * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited + * by the output buffer size, so there is no need to check that. Since this + * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits + * in size. + */ + { + png_compression_bufferp *end = &png_ptr->zbuffer_list; + png_alloc_size_t input_len = comp->input_len; /* may be zero! */ + png_uint_32 output_len; + + /* zlib updates these for us: */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); + png_ptr->zstream.avail_in = 0; /* Set below */ + png_ptr->zstream.next_out = comp->output; + png_ptr->zstream.avail_out = (sizeof comp->output); + + output_len = png_ptr->zstream.avail_out; + + do + { + uInt avail_in = ZLIB_IO_MAX; + + if (avail_in > input_len) + avail_in = (uInt)input_len; + + input_len -= avail_in; + + png_ptr->zstream.avail_in = avail_in; + + if (png_ptr->zstream.avail_out == 0) + { + png_compression_buffer *next; + + /* Chunk data is limited to 2^31 bytes in length, so the prefix + * length must be counted here. + */ + if (output_len + prefix_len > PNG_UINT_31_MAX) + { + ret = Z_MEM_ERROR; + break; + } + + /* Need a new (malloc'ed) buffer, but there may be one present + * already. + */ + next = *end; + if (next == NULL) + { + next = png_voidcast(png_compression_bufferp, png_malloc_base + (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); + + if (next == NULL) + { + ret = Z_MEM_ERROR; + break; + } + + /* Link in this buffer (so that it will be freed later) */ + next->next = NULL; + *end = next; + } + + png_ptr->zstream.next_out = next->output; + png_ptr->zstream.avail_out = png_ptr->zbuffer_size; + output_len += png_ptr->zstream.avail_out; + + /* Move 'end' to the next buffer pointer. */ + end = &next->next; + } + + /* Compress the data */ + ret = deflate(&png_ptr->zstream, + input_len > 0 ? Z_NO_FLUSH : Z_FINISH); + + /* Claw back input data that was not consumed (because avail_in is + * reset above every time round the loop). + */ + input_len += png_ptr->zstream.avail_in; + png_ptr->zstream.avail_in = 0; /* safety */ + } + while (ret == Z_OK); + + /* There may be some space left in the last output buffer. This needs to + * be subtracted from output_len. + */ + output_len -= png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out = 0; /* safety */ + comp->output_len = output_len; + + /* Now double check the output length, put in a custom message if it is + * too long. Otherwise ensure the z_stream::msg pointer is set to + * something. + */ + if (output_len + prefix_len >= PNG_UINT_31_MAX) + { + png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); + ret = Z_MEM_ERROR; + } + + else + png_zstream_error(png_ptr, ret); + + /* Reset zlib for another zTXt/iTXt or image data */ + png_ptr->zowner = 0; + + /* The only success case is Z_STREAM_END, input_len must be 0; if not this + * is an internal error. + */ + if (ret == Z_STREAM_END && input_len == 0) + { +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + /* Fix up the deflate header, if required */ + optimize_cmf(comp->output, comp->input_len); +#endif + /* But Z_OK is returned, not Z_STREAM_END; this allows the claim + * function above to return Z_STREAM_END on an error (though it never + * does in the current versions of zlib.) + */ + return Z_OK; + } + + else + return ret; + } +} + +/* Ship the compressed text out via chunk writes */ +static void +png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) +{ + png_uint_32 output_len = comp->output_len; + png_const_bytep output = comp->output; + png_uint_32 avail = (sizeof comp->output); + png_compression_buffer *next = png_ptr->zbuffer_list; + + for (;;) + { + if (avail > output_len) + avail = output_len; + + png_write_chunk_data(png_ptr, output, avail); + + output_len -= avail; + + if (output_len == 0 || next == NULL) + break; + + avail = png_ptr->zbuffer_size; + output = next->output; + next = next->next; + } + + /* This is an internal error; 'next' must have been NULL! */ + if (output_len > 0) + png_error(png_ptr, "error writing ancillary chunked compressed data"); +} +#endif /* WRITE_COMPRESSED_TEXT */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. Note that the rest of this code depends upon this + * information being correct. + */ +void /* PRIVATE */ +png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type) +{ + png_byte buf[13]; /* Buffer to store the IHDR info */ + int is_invalid_depth; + + png_debug(1, "in png_write_IHDR"); + + /* Check that we have valid input data from the application info */ + switch (color_type) + { + case PNG_COLOR_TYPE_GRAY: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: +#ifdef PNG_WRITE_16BIT_SUPPORTED + case 16: +#endif + png_ptr->channels = 1; break; + + default: + png_error(png_ptr, + "Invalid bit depth for grayscale image"); + } + break; + + case PNG_COLOR_TYPE_RGB: + is_invalid_depth = (bit_depth != 8); +#ifdef PNG_WRITE_16BIT_SUPPORTED + is_invalid_depth = (is_invalid_depth && bit_depth != 16); +#endif + if (is_invalid_depth) + png_error(png_ptr, "Invalid bit depth for RGB image"); + + png_ptr->channels = 3; + break; + + case PNG_COLOR_TYPE_PALETTE: + switch (bit_depth) + { + case 1: + case 2: + case 4: + case 8: + png_ptr->channels = 1; + break; + + default: + png_error(png_ptr, "Invalid bit depth for paletted image"); + } + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + is_invalid_depth = (bit_depth != 8); +#ifdef PNG_WRITE_16BIT_SUPPORTED + is_invalid_depth = (is_invalid_depth && bit_depth != 16); +#endif + if (is_invalid_depth) + png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); + + png_ptr->channels = 2; + break; + + case PNG_COLOR_TYPE_RGB_ALPHA: + is_invalid_depth = (bit_depth != 8); +#ifdef PNG_WRITE_16BIT_SUPPORTED + is_invalid_depth = (is_invalid_depth && bit_depth != 16); +#endif + if (is_invalid_depth) + png_error(png_ptr, "Invalid bit depth for RGBA image"); + + png_ptr->channels = 4; + break; + + default: + png_error(png_ptr, "Invalid image color type specified"); + } + + if (compression_type != PNG_COMPRESSION_TYPE_BASE) + { + png_warning(png_ptr, "Invalid compression type specified"); + compression_type = PNG_COMPRESSION_TYPE_BASE; + } + + /* Write filter_method 64 (intrapixel differencing) only if + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and + * 2. Libpng did not write a PNG signature (this filter_method is only + * used in PNG datastreams that are embedded in MNG datastreams) and + * 3. The application called png_permit_mng_features with a mask that + * included PNG_FLAG_MNG_FILTER_64 and + * 4. The filter_method is 64 and + * 5. The color_type is RGB or RGBA + */ + if ( +#ifdef PNG_MNG_FEATURES_SUPPORTED + !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && +#endif + filter_type != PNG_FILTER_TYPE_BASE) + { + png_warning(png_ptr, "Invalid filter type specified"); + filter_type = PNG_FILTER_TYPE_BASE; + } + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + if (interlace_type != PNG_INTERLACE_NONE && + interlace_type != PNG_INTERLACE_ADAM7) + { + png_warning(png_ptr, "Invalid interlace type specified"); + interlace_type = PNG_INTERLACE_ADAM7; + } +#else + interlace_type=PNG_INTERLACE_NONE; +#endif + + /* Save the relevant information */ + png_ptr->bit_depth = (png_byte)bit_depth; + png_ptr->color_type = (png_byte)color_type; + png_ptr->interlaced = (png_byte)interlace_type; +#ifdef PNG_MNG_FEATURES_SUPPORTED + png_ptr->filter_type = (png_byte)filter_type; +#endif + png_ptr->compression_type = (png_byte)compression_type; + png_ptr->width = width; + png_ptr->height = height; + + png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); + /* Set the usr info, so any transformations can modify it */ + png_ptr->usr_width = png_ptr->width; + png_ptr->usr_bit_depth = png_ptr->bit_depth; + png_ptr->usr_channels = png_ptr->channels; + + /* Pack the header information into the buffer */ + png_save_uint_32(buf, width); + png_save_uint_32(buf + 4, height); + buf[8] = (png_byte)bit_depth; + buf[9] = (png_byte)color_type; + buf[10] = (png_byte)compression_type; + buf[11] = (png_byte)filter_type; + buf[12] = (png_byte)interlace_type; + + /* Write the chunk */ + png_write_complete_chunk(png_ptr, png_IHDR, buf, 13); + + if ((png_ptr->do_filter) == PNG_NO_FILTERS) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || + png_ptr->bit_depth < 8) + png_ptr->do_filter = PNG_FILTER_NONE; + + else + png_ptr->do_filter = PNG_ALL_FILTERS; + } + + png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ +} + +/* Write the palette. We are careful not to trust png_color to be in the + * correct order for PNG, so people can redefine it to any convenient + * structure. + */ +void /* PRIVATE */ +png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, + png_uint_32 num_pal) +{ + png_uint_32 max_palette_length, i; + png_const_colorp pal_ptr; + png_byte buf[3]; + + png_debug(1, "in png_write_PLTE"); + + max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? + (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; + + if (( +#ifdef PNG_MNG_FEATURES_SUPPORTED + (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && +#endif + num_pal == 0) || num_pal > max_palette_length) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_error(png_ptr, "Invalid number of colors in palette"); + } + + else + { + png_warning(png_ptr, "Invalid number of colors in palette"); + return; + } + } + + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) + { + png_warning(png_ptr, + "Ignoring request to write a PLTE chunk in grayscale PNG"); + + return; + } + + png_ptr->num_palette = (png_uint_16)num_pal; + png_debug1(3, "num_palette = %d", png_ptr->num_palette); + + png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); + + for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) + { + buf[0] = pal_ptr->red; + buf[1] = pal_ptr->green; + buf[2] = pal_ptr->blue; + png_write_chunk_data(png_ptr, buf, 3); + } + + png_write_chunk_end(png_ptr); + png_ptr->mode |= PNG_HAVE_PLTE; +} + +/* This is similar to png_text_compress, above, except that it does not require + * all of the data at once and, instead of buffering the compressed result, + * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out + * because it calls the write interface. As a result it does its own error + * reporting and does not return an error code. In the event of error it will + * just call png_error. The input data length may exceed 32-bits. The 'flush' + * parameter is exactly the same as that to deflate, with the following + * meanings: + * + * Z_NO_FLUSH: normal incremental output of compressed data + * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush + * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up + * + * The routine manages the acquire and release of the png_ptr->zstream by + * checking and (at the end) clearing png_ptr->zowner; it does some sanity + * checks on the 'mode' flags while doing this. + */ +void /* PRIVATE */ +png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, + png_alloc_size_t input_len, int flush) +{ + if (png_ptr->zowner != png_IDAT) + { + /* First time. Ensure we have a temporary buffer for compression and + * trim the buffer list if it has more than one entry to free memory. + * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been + * created at this point, but the check here is quick and safe. + */ + if (png_ptr->zbuffer_list == NULL) + { + png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, + png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); + png_ptr->zbuffer_list->next = NULL; + } + + else + png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); + + /* It is a terminal error if we can't claim the zstream. */ + if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + /* The output state is maintained in png_ptr->zstream, so it must be + * initialized here after the claim. + */ + png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; + png_ptr->zstream.avail_out = png_ptr->zbuffer_size; + } + + /* Now loop reading and writing until all the input is consumed or an error + * terminates the operation. The _out values are maintained across calls to + * this function, but the input must be reset each time. + */ + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); + png_ptr->zstream.avail_in = 0; /* set below */ + for (;;) + { + int ret; + + /* INPUT: from the row data */ + uInt avail = ZLIB_IO_MAX; + + if (avail > input_len) + avail = (uInt)input_len; /* safe because of the check */ + + png_ptr->zstream.avail_in = avail; + input_len -= avail; + + ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); + + /* Include as-yet unconsumed input */ + input_len += png_ptr->zstream.avail_in; + png_ptr->zstream.avail_in = 0; + + /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note + * that these two zstream fields are preserved across the calls, therefore + * there is no need to set these up on entry to the loop. + */ + if (png_ptr->zstream.avail_out == 0) + { + png_bytep data = png_ptr->zbuffer_list->output; + uInt size = png_ptr->zbuffer_size; + + /* Write an IDAT containing the data then reset the buffer. The + * first IDAT may need deflate header optimization. + */ +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + optimize_cmf(data, png_image_size(png_ptr)); +#endif + + if (size > 0) + png_write_complete_chunk(png_ptr, png_IDAT, data, size); + png_ptr->mode |= PNG_HAVE_IDAT; + + png_ptr->zstream.next_out = data; + png_ptr->zstream.avail_out = size; + + /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with + * the same flush parameter until it has finished output, for NO_FLUSH + * it doesn't matter. + */ + if (ret == Z_OK && flush != Z_NO_FLUSH) + continue; + } + + /* The order of these checks doesn't matter much; it just affects which + * possible error might be detected if multiple things go wrong at once. + */ + if (ret == Z_OK) /* most likely return code! */ + { + /* If all the input has been consumed then just return. If Z_FINISH + * was used as the flush parameter something has gone wrong if we get + * here. + */ + if (input_len == 0) + { + if (flush == Z_FINISH) + png_error(png_ptr, "Z_OK on Z_FINISH with output space"); + + return; + } + } + + else if (ret == Z_STREAM_END && flush == Z_FINISH) + { + /* This is the end of the IDAT data; any pending output must be + * flushed. For small PNG files we may still be at the beginning. + */ + png_bytep data = png_ptr->zbuffer_list->output; + uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; + +#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED + if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && + png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) + optimize_cmf(data, png_image_size(png_ptr)); +#endif + + if (size > 0) + png_write_complete_chunk(png_ptr, png_IDAT, data, size); + png_ptr->zstream.avail_out = 0; + png_ptr->zstream.next_out = NULL; + png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; + + png_ptr->zowner = 0; /* Release the stream */ + return; + } + + else + { + /* This is an error condition. */ + png_zstream_error(png_ptr, ret); + png_error(png_ptr, png_ptr->zstream.msg); + } + } +} + +/* Write an IEND chunk */ +void /* PRIVATE */ +png_write_IEND(png_structrp png_ptr) +{ + png_debug(1, "in png_write_IEND"); + + png_write_complete_chunk(png_ptr, png_IEND, NULL, 0); + png_ptr->mode |= PNG_HAVE_IEND; +} + +#ifdef PNG_WRITE_gAMA_SUPPORTED +/* Write a gAMA chunk */ +void /* PRIVATE */ +png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) +{ + png_byte buf[4]; + + png_debug(1, "in png_write_gAMA"); + + /* file_gamma is saved in 1/100,000ths */ + png_save_uint_32(buf, (png_uint_32)file_gamma); + png_write_complete_chunk(png_ptr, png_gAMA, buf, 4); +} +#endif + +#ifdef PNG_WRITE_sRGB_SUPPORTED +/* Write a sRGB chunk */ +void /* PRIVATE */ +png_write_sRGB(png_structrp png_ptr, int srgb_intent) +{ + png_byte buf[1]; + + png_debug(1, "in png_write_sRGB"); + + if (srgb_intent >= PNG_sRGB_INTENT_LAST) + png_warning(png_ptr, + "Invalid sRGB rendering intent specified"); + + buf[0]=(png_byte)srgb_intent; + png_write_complete_chunk(png_ptr, png_sRGB, buf, 1); +} +#endif + +#ifdef PNG_WRITE_iCCP_SUPPORTED +/* Write an iCCP chunk */ +void /* PRIVATE */ +png_write_iCCP(png_structrp png_ptr, png_const_charp name, + png_const_bytep profile, png_uint_32 profile_len) +{ + png_uint_32 name_len; + png_byte new_name[81]; /* 1 byte for the compression byte */ + compression_state comp; + png_uint_32 temp; + + png_debug(1, "in png_write_iCCP"); + + /* These are all internal problems: the profile should have been checked + * before when it was stored. + */ + if (profile == NULL) + png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ + + if (profile_len < 132) + png_error(png_ptr, "ICC profile too short"); + + if (png_get_uint_32(profile) != profile_len) + png_error(png_ptr, "Incorrect data in iCCP"); + + temp = (png_uint_32) (*(profile+8)); + if (temp > 3 && (profile_len & 0x03)) + png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); + + { + png_uint_32 embedded_profile_len = png_get_uint_32(profile); + + if (profile_len != embedded_profile_len) + png_error(png_ptr, "Profile length does not match profile"); + } + + name_len = png_check_keyword(png_ptr, name, new_name); + + if (name_len == 0) + png_error(png_ptr, "iCCP: invalid keyword"); + + new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; + + /* Make sure we include the NULL after the name and the compression type */ + ++name_len; + + png_text_compress_init(&comp, profile, profile_len); + + /* Allow for keyword terminator and compression byte */ + if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); + + png_write_chunk_data(png_ptr, new_name, name_len); + + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sPLT_SUPPORTED +/* Write a sPLT chunk */ +void /* PRIVATE */ +png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) +{ + png_uint_32 name_len; + png_byte new_name[80]; + png_byte entrybuf[10]; + size_t entry_size = (spalette->depth == 8 ? 6 : 10); + size_t palette_size = entry_size * (size_t)spalette->nentries; + png_sPLT_entryp ep; + + png_debug(1, "in png_write_sPLT"); + + name_len = png_check_keyword(png_ptr, spalette->name, new_name); + + if (name_len == 0) + png_error(png_ptr, "sPLT: invalid keyword"); + + /* Make sure we include the NULL after the name */ + png_write_chunk_header(png_ptr, png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + + png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1)); + + png_write_chunk_data(png_ptr, &spalette->depth, 1); + + /* Loop through each palette entry, writing appropriately */ + for (ep = spalette->entries; epentries + spalette->nentries; ep++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep->red; + entrybuf[1] = (png_byte)ep->green; + entrybuf[2] = (png_byte)ep->blue; + entrybuf[3] = (png_byte)ep->alpha; + png_save_uint_16(entrybuf + 4, ep->frequency); + } + + else + { + png_save_uint_16(entrybuf + 0, ep->red); + png_save_uint_16(entrybuf + 2, ep->green); + png_save_uint_16(entrybuf + 4, ep->blue); + png_save_uint_16(entrybuf + 6, ep->alpha); + png_save_uint_16(entrybuf + 8, ep->frequency); + } + + png_write_chunk_data(png_ptr, entrybuf, entry_size); + } + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sBIT_SUPPORTED +/* Write the sBIT chunk */ +void /* PRIVATE */ +png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) +{ + png_byte buf[4]; + size_t size; + + png_debug(1, "in png_write_sBIT"); + + /* Make sure we don't depend upon the order of PNG_COLOR_8 */ + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_byte maxbits; + + maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : + png_ptr->usr_bit_depth); + + if (sbit->red == 0 || sbit->red > maxbits || + sbit->green == 0 || sbit->green > maxbits || + sbit->blue == 0 || sbit->blue > maxbits) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + + buf[0] = sbit->red; + buf[1] = sbit->green; + buf[2] = sbit->blue; + size = 3; + } + + else + { + if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + + buf[0] = sbit->gray; + size = 1; + } + + if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) + { + if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) + { + png_warning(png_ptr, "Invalid sBIT depth specified"); + return; + } + + buf[size++] = sbit->alpha; + } + + png_write_complete_chunk(png_ptr, png_sBIT, buf, size); +} +#endif + +#ifdef PNG_WRITE_cHRM_SUPPORTED +/* Write the cHRM chunk */ +void /* PRIVATE */ +png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) +{ + png_byte buf[32]; + + png_debug(1, "in png_write_cHRM"); + + /* Each value is saved in 1/100,000ths */ + png_save_int_32(buf, xy->whitex); + png_save_int_32(buf + 4, xy->whitey); + + png_save_int_32(buf + 8, xy->redx); + png_save_int_32(buf + 12, xy->redy); + + png_save_int_32(buf + 16, xy->greenx); + png_save_int_32(buf + 20, xy->greeny); + + png_save_int_32(buf + 24, xy->bluex); + png_save_int_32(buf + 28, xy->bluey); + + png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); +} +#endif + +#ifdef PNG_WRITE_tRNS_SUPPORTED +/* Write the tRNS chunk */ +void /* PRIVATE */ +png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, + png_const_color_16p tran, int num_trans, int color_type) +{ + png_byte buf[6]; + + png_debug(1, "in png_write_tRNS"); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) + { + png_app_warning(png_ptr, + "Invalid number of transparent colors specified"); + return; + } + + /* Write the chunk out as it is */ + png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, + (size_t)num_trans); + } + + else if (color_type == PNG_COLOR_TYPE_GRAY) + { + /* One 16-bit value */ + if (tran->gray >= (1 << png_ptr->bit_depth)) + { + png_app_warning(png_ptr, + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + + return; + } + + png_save_uint_16(buf, tran->gray); + png_write_complete_chunk(png_ptr, png_tRNS, buf, 2); + } + + else if (color_type == PNG_COLOR_TYPE_RGB) + { + /* Three 16-bit values */ + png_save_uint_16(buf, tran->red); + png_save_uint_16(buf + 2, tran->green); + png_save_uint_16(buf + 4, tran->blue); +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) +#else + if ((buf[0] | buf[2] | buf[4]) != 0) +#endif + { + png_app_warning(png_ptr, + "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); + return; + } + + png_write_complete_chunk(png_ptr, png_tRNS, buf, 6); + } + + else + { + png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); + } +} +#endif + +#ifdef PNG_WRITE_bKGD_SUPPORTED +/* Write the background chunk */ +void /* PRIVATE */ +png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) +{ + png_byte buf[6]; + + png_debug(1, "in png_write_bKGD"); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + { + if ( +#ifdef PNG_MNG_FEATURES_SUPPORTED + (png_ptr->num_palette != 0 || + (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && +#endif + back->index >= png_ptr->num_palette) + { + png_warning(png_ptr, "Invalid background palette index"); + return; + } + + buf[0] = back->index; + png_write_complete_chunk(png_ptr, png_bKGD, buf, 1); + } + + else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) + { + png_save_uint_16(buf, back->red); + png_save_uint_16(buf + 2, back->green); + png_save_uint_16(buf + 4, back->blue); +#ifdef PNG_WRITE_16BIT_SUPPORTED + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) +#else + if ((buf[0] | buf[2] | buf[4]) != 0) +#endif + { + png_warning(png_ptr, + "Ignoring attempt to write 16-bit bKGD chunk " + "when bit_depth is 8"); + + return; + } + + png_write_complete_chunk(png_ptr, png_bKGD, buf, 6); + } + + else + { + if (back->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + + return; + } + + png_save_uint_16(buf, back->gray); + png_write_complete_chunk(png_ptr, png_bKGD, buf, 2); + } +} +#endif + +#ifdef PNG_WRITE_cICP_SUPPORTED +/* Write the cICP data */ +void /* PRIVATE */ +png_write_cICP(png_structrp png_ptr, + png_byte colour_primaries, png_byte transfer_function, + png_byte matrix_coefficients, png_byte video_full_range_flag) +{ + png_byte buf[4]; + + png_debug(1, "in png_write_cICP"); + + png_write_chunk_header(png_ptr, png_cICP, 4); + + buf[0] = colour_primaries; + buf[1] = transfer_function; + buf[2] = matrix_coefficients; + buf[3] = video_full_range_flag; + png_write_chunk_data(png_ptr, buf, 4); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_cLLI_SUPPORTED +void /* PRIVATE */ +png_write_cLLI_fixed(png_structrp png_ptr, png_uint_32 maxCLL, + png_uint_32 maxFALL) +{ + png_byte buf[8]; + + png_debug(1, "in png_write_cLLI_fixed"); + + png_save_uint_32(buf, maxCLL); + png_save_uint_32(buf + 4, maxFALL); + + png_write_complete_chunk(png_ptr, png_cLLI, buf, 8); +} +#endif + +#ifdef PNG_WRITE_mDCV_SUPPORTED +void /* PRIVATE */ +png_write_mDCV_fixed(png_structrp png_ptr, + png_uint_16 red_x, png_uint_16 red_y, + png_uint_16 green_x, png_uint_16 green_y, + png_uint_16 blue_x, png_uint_16 blue_y, + png_uint_16 white_x, png_uint_16 white_y, + png_uint_32 maxDL, png_uint_32 minDL) +{ + png_byte buf[24]; + + png_debug(1, "in png_write_mDCV_fixed"); + + png_save_uint_16(buf + 0, red_x); + png_save_uint_16(buf + 2, red_y); + png_save_uint_16(buf + 4, green_x); + png_save_uint_16(buf + 6, green_y); + png_save_uint_16(buf + 8, blue_x); + png_save_uint_16(buf + 10, blue_y); + png_save_uint_16(buf + 12, white_x); + png_save_uint_16(buf + 14, white_y); + png_save_uint_32(buf + 16, maxDL); + png_save_uint_32(buf + 20, minDL); + + png_write_complete_chunk(png_ptr, png_mDCV, buf, 24); +} +#endif + +#ifdef PNG_WRITE_eXIf_SUPPORTED +/* Write the Exif data */ +void /* PRIVATE */ +png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif) +{ + int i; + png_byte buf[1]; + + png_debug(1, "in png_write_eXIf"); + + png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif)); + + for (i = 0; i < num_exif; i++) + { + buf[0] = exif[i]; + png_write_chunk_data(png_ptr, buf, 1); + } + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_hIST_SUPPORTED +/* Write the histogram */ +void /* PRIVATE */ +png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) +{ + int i; + png_byte buf[3]; + + png_debug(1, "in png_write_hIST"); + + if (num_hist > (int)png_ptr->num_palette) + { + png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, + png_ptr->num_palette); + + png_warning(png_ptr, "Invalid number of histogram entries specified"); + return; + } + + png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + + for (i = 0; i < num_hist; i++) + { + png_save_uint_16(buf, hist[i]); + png_write_chunk_data(png_ptr, buf, 2); + } + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_tEXt_SUPPORTED +/* Write a tEXt chunk */ +void /* PRIVATE */ +png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, + size_t text_len) +{ + png_uint_32 key_len; + png_byte new_key[80]; + + png_debug(1, "in png_write_tEXt"); + + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "tEXt: invalid keyword"); + + if (text == NULL || *text == '\0') + text_len = 0; + + else + text_len = strlen(text); + + if (text_len > PNG_UINT_31_MAX - (key_len+1)) + png_error(png_ptr, "tEXt: text too long"); + + /* Make sure we include the 0 after the key */ + png_write_chunk_header(png_ptr, png_tEXt, + (png_uint_32)/*checked above*/(key_len + text_len + 1)); + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, new_key, key_len + 1); + + if (text_len != 0) + png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_zTXt_SUPPORTED +/* Write a compressed text chunk */ +void /* PRIVATE */ +png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, + int compression) +{ + png_uint_32 key_len; + png_byte new_key[81]; + compression_state comp; + + png_debug(1, "in png_write_zTXt"); + + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + png_write_tEXt(png_ptr, key, text, 0); + return; + } + + if (compression != PNG_TEXT_COMPRESSION_zTXt) + png_error(png_ptr, "zTXt: invalid compression type"); + + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "zTXt: invalid keyword"); + + /* Add the compression method and 1 for the keyword separator. */ + new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; + ++key_len; + + /* Compute the compressed data; do it now for the length */ + png_text_compress_init(&comp, (png_const_bytep)text, + text == NULL ? 0 : strlen(text)); + + if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + + /* Write start of chunk */ + png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); + + /* Write key */ + png_write_chunk_data(png_ptr, new_key, key_len); + + /* Write the compressed data */ + png_write_compressed_data_out(png_ptr, &comp); + + /* Close the chunk */ + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_iTXt_SUPPORTED +/* Write an iTXt chunk */ +void /* PRIVATE */ +png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, + png_const_charp lang, png_const_charp lang_key, png_const_charp text) +{ + png_uint_32 key_len, prefix_len; + size_t lang_len, lang_key_len; + png_byte new_key[82]; + compression_state comp; + + png_debug(1, "in png_write_iTXt"); + + key_len = png_check_keyword(png_ptr, key, new_key); + + if (key_len == 0) + png_error(png_ptr, "iTXt: invalid keyword"); + + /* Set the compression flag */ + switch (compression) + { + case PNG_ITXT_COMPRESSION_NONE: + case PNG_TEXT_COMPRESSION_NONE: + compression = new_key[++key_len] = 0; /* no compression */ + break; + + case PNG_TEXT_COMPRESSION_zTXt: + case PNG_ITXT_COMPRESSION_zTXt: + compression = new_key[++key_len] = 1; /* compressed */ + break; + + default: + png_error(png_ptr, "iTXt: invalid compression"); + } + + new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; + ++key_len; /* for the keyword separator */ + + /* We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, + * specifies that the text is UTF-8 and this really doesn't require any + * checking. + * + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + * + * TODO: validate the language tag correctly (see the spec.) + */ + if (lang == NULL) lang = ""; /* empty language is valid */ + lang_len = strlen(lang)+1; + if (lang_key == NULL) lang_key = ""; /* may be empty */ + lang_key_len = strlen(lang_key)+1; + if (text == NULL) text = ""; /* may be empty */ + + prefix_len = key_len; + if (lang_len > PNG_UINT_31_MAX-prefix_len) + prefix_len = PNG_UINT_31_MAX; + else + prefix_len = (png_uint_32)(prefix_len + lang_len); + + if (lang_key_len > PNG_UINT_31_MAX-prefix_len) + prefix_len = PNG_UINT_31_MAX; + else + prefix_len = (png_uint_32)(prefix_len + lang_key_len); + + png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); + + if (compression != 0) + { + if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) + png_error(png_ptr, png_ptr->zstream.msg); + } + + else + { + if (comp.input_len > PNG_UINT_31_MAX-prefix_len) + png_error(png_ptr, "iTXt: uncompressed text too long"); + + /* So the string will fit in a chunk: */ + comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; + } + + png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); + + png_write_chunk_data(png_ptr, new_key, key_len); + + png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); + + png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); + + if (compression != 0) + png_write_compressed_data_out(png_ptr, &comp); + + else + png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len); + + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_oFFs_SUPPORTED +/* Write the oFFs chunk */ +void /* PRIVATE */ +png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, + int unit_type) +{ + png_byte buf[9]; + + png_debug(1, "in png_write_oFFs"); + + if (unit_type >= PNG_OFFSET_LAST) + png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); + + png_save_int_32(buf, x_offset); + png_save_int_32(buf + 4, y_offset); + buf[8] = (png_byte)unit_type; + + png_write_complete_chunk(png_ptr, png_oFFs, buf, 9); +} +#endif +#ifdef PNG_WRITE_pCAL_SUPPORTED +/* Write the pCAL chunk (described in the PNG extensions document) */ +void /* PRIVATE */ +png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, + png_int_32 X1, int type, int nparams, png_const_charp units, + png_charpp params) +{ + png_uint_32 purpose_len; + size_t units_len, total_len; + size_t *params_len; + png_byte buf[10]; + png_byte new_purpose[80]; + int i; + + png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); + + if (type >= PNG_EQUATION_LAST) + png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); + + purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); + + if (purpose_len == 0) + png_error(png_ptr, "pCAL: invalid keyword"); + + ++purpose_len; /* terminator */ + + png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); + units_len = strlen(units) + (nparams == 0 ? 0 : 1); + png_debug1(3, "pCAL units length = %d", (int)units_len); + total_len = purpose_len + units_len + 10; + + params_len = (size_t *)png_malloc(png_ptr, + (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t)))); + + /* Find the length of each parameter, making sure we don't count the + * null terminator for the last parameter. + */ + for (i = 0; i < nparams; i++) + { + params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); + png_debug2(3, "pCAL parameter %d length = %lu", i, + (unsigned long)params_len[i]); + total_len += params_len[i]; + } + + png_debug1(3, "pCAL total length = %d", (int)total_len); + png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, new_purpose, purpose_len); + png_save_int_32(buf, X0); + png_save_int_32(buf + 4, X1); + buf[8] = (png_byte)type; + buf[9] = (png_byte)nparams; + png_write_chunk_data(png_ptr, buf, 10); + png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len); + + for (i = 0; i < nparams; i++) + { + png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); + } + + png_free(png_ptr, params_len); + png_write_chunk_end(png_ptr); +} +#endif + +#ifdef PNG_WRITE_sCAL_SUPPORTED +/* Write the sCAL chunk */ +void /* PRIVATE */ +png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, + png_const_charp height) +{ + png_byte buf[64]; + size_t wlen, hlen, total_len; + + png_debug(1, "in png_write_sCAL_s"); + + wlen = strlen(width); + hlen = strlen(height); + total_len = wlen + hlen + 2; + + if (total_len > 64) + { + png_warning(png_ptr, "Can't write sCAL (buffer too small)"); + return; + } + + buf[0] = (png_byte)unit; + memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ + memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ + + png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); + png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); +} +#endif + +#ifdef PNG_WRITE_pHYs_SUPPORTED +/* Write the pHYs chunk */ +void /* PRIVATE */ +png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, + png_uint_32 y_pixels_per_unit, + int unit_type) +{ + png_byte buf[9]; + + png_debug(1, "in png_write_pHYs"); + + if (unit_type >= PNG_RESOLUTION_LAST) + png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); + + png_save_uint_32(buf, x_pixels_per_unit); + png_save_uint_32(buf + 4, y_pixels_per_unit); + buf[8] = (png_byte)unit_type; + + png_write_complete_chunk(png_ptr, png_pHYs, buf, 9); +} +#endif + +#ifdef PNG_WRITE_tIME_SUPPORTED +/* Write the tIME chunk. Use either png_convert_from_struct_tm() + * or png_convert_from_time_t(), or fill in the structure yourself. + */ +void /* PRIVATE */ +png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) +{ + png_byte buf[7]; + + png_debug(1, "in png_write_tIME"); + + if (mod_time->month > 12 || mod_time->month < 1 || + mod_time->day > 31 || mod_time->day < 1 || + mod_time->hour > 23 || mod_time->second > 60) + { + png_warning(png_ptr, "Invalid time specified for tIME chunk"); + return; + } + + png_save_uint_16(buf, mod_time->year); + buf[2] = mod_time->month; + buf[3] = mod_time->day; + buf[4] = mod_time->hour; + buf[5] = mod_time->minute; + buf[6] = mod_time->second; + + png_write_complete_chunk(png_ptr, png_tIME, buf, 7); +} +#endif + +/* Initializes the row writing capability of libpng */ +void /* PRIVATE */ +png_write_start_row(png_structrp png_ptr) +{ + png_alloc_size_t buf_size; + int usr_pixel_depth; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + png_byte filters; +#endif + + png_debug(1, "in png_write_start_row"); + + usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; + buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; + + /* 1.5.6: added to allow checking in the row write code. */ + png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; + png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; + + /* Set up row buffer */ + png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; + +#ifdef PNG_WRITE_FILTER_SUPPORTED + filters = png_ptr->do_filter; + + if (png_ptr->height == 1) + filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (png_ptr->width == 1) + filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); + + if (filters == 0) + filters = PNG_FILTER_NONE; + + png_ptr->do_filter = filters; + + if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | + PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL) + { + int num_filters = 0; + + png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); + + if (filters & PNG_FILTER_SUB) + num_filters++; + + if (filters & PNG_FILTER_UP) + num_filters++; + + if (filters & PNG_FILTER_AVG) + num_filters++; + + if (filters & PNG_FILTER_PAETH) + num_filters++; + + if (num_filters > 1) + png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr, + buf_size)); + } + + /* We only need to keep the previous row if we are using one of the following + * filters. + */ + if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) + png_ptr->prev_row = png_voidcast(png_bytep, + png_calloc(png_ptr, buf_size)); +#endif /* WRITE_FILTER */ + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced, we need to set up width and height of pass */ + if (png_ptr->interlaced != 0) + { + if ((png_ptr->transformations & PNG_INTERLACE) == 0) + { + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - + png_pass_ystart[0]) / png_pass_yinc[0]; + + png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - + png_pass_start[0]) / png_pass_inc[0]; + } + + else + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } + } + + else +#endif + { + png_ptr->num_rows = png_ptr->height; + png_ptr->usr_width = png_ptr->width; + } +} + +/* Internal use only. Called when finished processing a row of data. */ +void /* PRIVATE */ +png_write_finish_row(png_structrp png_ptr) +{ + png_debug(1, "in png_write_finish_row"); + + /* Next row */ + png_ptr->row_number++; + + /* See if we are done */ + if (png_ptr->row_number < png_ptr->num_rows) + return; + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + /* If interlaced, go to next pass */ + if (png_ptr->interlaced != 0) + { + png_ptr->row_number = 0; + if ((png_ptr->transformations & PNG_INTERLACE) != 0) + { + png_ptr->pass++; + } + + else + { + /* Loop until we find a non-zero width or height pass */ + do + { + png_ptr->pass++; + + if (png_ptr->pass >= 7) + break; + + png_ptr->usr_width = (png_ptr->width + + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + + png_ptr->num_rows = (png_ptr->height + + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + + if ((png_ptr->transformations & PNG_INTERLACE) != 0) + break; + + } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); + + } + + /* Reset the row above the image for the next pass */ + if (png_ptr->pass < 7) + { + if (png_ptr->prev_row != NULL) + memset(png_ptr->prev_row, 0, + PNG_ROWBYTES(png_ptr->usr_channels * + png_ptr->usr_bit_depth, png_ptr->width) + 1); + + return; + } + } +#endif + + /* If we get here, we've just written the last row, so we need + to flush the compressor */ + png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); +} + +#ifdef PNG_WRITE_INTERLACING_SUPPORTED +/* Pick out the correct pixels for the interlace pass. + * The basic idea here is to go through the row with a source + * pointer and a destination pointer (sp and dp), and copy the + * correct pixels for the pass. As the row gets compacted, + * sp will always be >= dp, so we should never overwrite anything. + * See the default: case for the easiest code to understand. + */ +void /* PRIVATE */ +png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) +{ + png_debug(1, "in png_do_write_interlace"); + + /* We don't have to do anything on the last pass (6) */ + if (pass < 6) + { + /* Each pixel depth is handled separately */ + switch (row_info->pixel_depth) + { + case 1: + { + png_bytep sp; + png_bytep dp; + unsigned int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + d = 0; + shift = 7; + + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (size_t)(i >> 3); + value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; + d |= (value << shift); + + if (shift == 0) + { + shift = 7; + *dp++ = (png_byte)d; + d = 0; + } + + else + shift--; + + } + if (shift != 7) + *dp = (png_byte)d; + + break; + } + + case 2: + { + png_bytep sp; + png_bytep dp; + unsigned int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 6; + d = 0; + + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (size_t)(i >> 2); + value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; + d |= (value << shift); + + if (shift == 0) + { + shift = 6; + *dp++ = (png_byte)d; + d = 0; + } + + else + shift -= 2; + } + if (shift != 6) + *dp = (png_byte)d; + + break; + } + + case 4: + { + png_bytep sp; + png_bytep dp; + unsigned int shift; + int d; + int value; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + + dp = row; + shift = 4; + d = 0; + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + sp = row + (size_t)(i >> 1); + value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; + d |= (value << shift); + + if (shift == 0) + { + shift = 4; + *dp++ = (png_byte)d; + d = 0; + } + + else + shift -= 4; + } + if (shift != 4) + *dp = (png_byte)d; + + break; + } + + default: + { + png_bytep sp; + png_bytep dp; + png_uint_32 i; + png_uint_32 row_width = row_info->width; + size_t pixel_bytes; + + /* Start at the beginning */ + dp = row; + + /* Find out how many bytes each pixel takes up */ + pixel_bytes = (row_info->pixel_depth >> 3); + + /* Loop through the row, only looking at the pixels that matter */ + for (i = png_pass_start[pass]; i < row_width; + i += png_pass_inc[pass]) + { + /* Find out where the original pixel is */ + sp = row + (size_t)i * pixel_bytes; + + /* Move the pixel */ + if (dp != sp) + memcpy(dp, sp, pixel_bytes); + + /* Next pixel */ + dp += pixel_bytes; + } + break; + } + } + /* Set new row width */ + row_info->width = (row_info->width + + png_pass_inc[pass] - 1 - + png_pass_start[pass]) / + png_pass_inc[pass]; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); + } +} +#endif + + +/* This filters the row, chooses which filter to use, if it has not already + * been specified by the application, and then writes the row out with the + * chosen filter. + */ +static void /* PRIVATE */ +png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, + size_t row_bytes); + +#ifdef PNG_WRITE_FILTER_SUPPORTED +static size_t /* PRIVATE */ +png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, + size_t row_bytes, size_t lmins) +{ + png_bytep rp, dp, lp; + size_t i; + size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; + i++, rp++, dp++) + { + v = *dp = *rp; +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return sum; +} + +static void /* PRIVATE */ +png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp, + size_t row_bytes) +{ + png_bytep rp, dp, lp; + size_t i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; + i++, rp++, dp++) + { + *dp = *rp; + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; + i++, rp++, lp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); + } +} + +static size_t /* PRIVATE */ +png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins) +{ + png_bytep rp, dp, pp; + size_t i; + size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return sum; +} +static void /* PRIVATE */ +png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) +{ + png_bytep rp, dp, pp; + size_t i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) + { + *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); + } +} + +static size_t /* PRIVATE */ +png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, + size_t row_bytes, size_t lmins) +{ + png_bytep rp, dp, pp, lp; + png_uint_32 i; + size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return sum; +} +static void /* PRIVATE */ +png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, + size_t row_bytes) +{ + png_bytep rp, dp, pp, lp; + png_uint_32 i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); + } + + for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) + & 0xff); + } +} + +static size_t /* PRIVATE */ +png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, + size_t row_bytes, size_t lmins) +{ + png_bytep rp, dp, pp, cp, lp; + size_t i; + size_t sum = 0; + unsigned int v; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + + for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; + i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + + if (sum > lmins) /* We are already worse, don't continue. */ + break; + } + + return sum; +} +static void /* PRIVATE */ +png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, + size_t row_bytes) +{ + png_bytep rp, dp, pp, cp, lp; + size_t i; + + png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; + + for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, + pp = png_ptr->prev_row + 1; i < bpp; i++) + { + *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); + } + + for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; + i++) + { + int a, b, c, pa, pb, pc, p; + + b = *pp++; + c = *cp++; + a = *lp++; + + p = b - c; + pc = a - c; + +#ifdef PNG_USE_ABS + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); +#else + pa = p < 0 ? -p : p; + pb = pc < 0 ? -pc : pc; + pc = (p + pc) < 0 ? -(p + pc) : p + pc; +#endif + + p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + + *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); + } +} +#endif /* WRITE_FILTER */ + +void /* PRIVATE */ +png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) +{ +#ifndef PNG_WRITE_FILTER_SUPPORTED + png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); +#else + unsigned int filter_to_do = png_ptr->do_filter; + png_bytep row_buf; + png_bytep best_row; + png_uint_32 bpp; + size_t mins; + size_t row_bytes = row_info->rowbytes; + + png_debug(1, "in png_write_find_filter"); + + /* Find out how many bytes offset each pixel is */ + bpp = (row_info->pixel_depth + 7) >> 3; + + row_buf = png_ptr->row_buf; + mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the + running sum */; + + /* The prediction method we use is to find which method provides the + * smallest value when summing the absolute values of the distances + * from zero, using anything >= 128 as negative numbers. This is known + * as the "minimum sum of absolute differences" heuristic. Other + * heuristics are the "weighted minimum sum of absolute differences" + * (experimental and can in theory improve compression), and the "zlib + * predictive" method (not implemented yet), which does test compressions + * of lines using different filter methods, and then chooses the + * (series of) filter(s) that give minimum compressed data size (VERY + * computationally expensive). + * + * GRR 980525: consider also + * + * (1) minimum sum of absolute differences from running average (i.e., + * keep running sum of non-absolute differences & count of bytes) + * [track dispersion, too? restart average if dispersion too large?] + * + * (1b) minimum sum of absolute differences from sliding average, probably + * with window size <= deflate window (usually 32K) + * + * (2) minimum sum of squared differences from zero or running average + * (i.e., ~ root-mean-square approach) + */ + + + /* We don't need to test the 'no filter' case if this is the only filter + * that has been chosen, as it doesn't actually do anything to the data. + */ + best_row = png_ptr->row_buf; + + if (PNG_SIZE_MAX/128 <= row_bytes) + { + /* Overflow can occur in the calculation, just select the lowest set + * filter. + */ + filter_to_do &= 0U-filter_to_do; + } + else if ((filter_to_do & PNG_FILTER_NONE) != 0 && + filter_to_do != PNG_FILTER_NONE) + { + /* Overflow not possible and multiple filters in the list, including the + * 'none' filter. + */ + png_bytep rp; + size_t sum = 0; + size_t i; + unsigned int v; + + { + for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) + { + v = *rp; +#ifdef PNG_USE_ABS + sum += 128 - abs((int)v - 128); +#else + sum += (v < 128) ? v : 256 - v; +#endif + } + } + + mins = sum; + } + + /* Sub filter */ + if (filter_to_do == PNG_FILTER_SUB) + /* It's the only filter so no testing is needed */ + { + png_setup_sub_row_only(png_ptr, bpp, row_bytes); + best_row = png_ptr->try_row; + } + + else if ((filter_to_do & PNG_FILTER_SUB) != 0) + { + size_t sum; + size_t lmins = mins; + + sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } + } + } + + /* Up filter */ + if (filter_to_do == PNG_FILTER_UP) + { + png_setup_up_row_only(png_ptr, row_bytes); + best_row = png_ptr->try_row; + } + + else if ((filter_to_do & PNG_FILTER_UP) != 0) + { + size_t sum; + size_t lmins = mins; + + sum = png_setup_up_row(png_ptr, row_bytes, lmins); + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } + } + } + + /* Avg filter */ + if (filter_to_do == PNG_FILTER_AVG) + { + png_setup_avg_row_only(png_ptr, bpp, row_bytes); + best_row = png_ptr->try_row; + } + + else if ((filter_to_do & PNG_FILTER_AVG) != 0) + { + size_t sum; + size_t lmins = mins; + + sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); + + if (sum < mins) + { + mins = sum; + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } + } + } + + /* Paeth filter */ + if (filter_to_do == PNG_FILTER_PAETH) + { + png_setup_paeth_row_only(png_ptr, bpp, row_bytes); + best_row = png_ptr->try_row; + } + + else if ((filter_to_do & PNG_FILTER_PAETH) != 0) + { + size_t sum; + size_t lmins = mins; + + sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); + + if (sum < mins) + { + best_row = png_ptr->try_row; + if (png_ptr->tst_row != NULL) + { + png_ptr->try_row = png_ptr->tst_row; + png_ptr->tst_row = best_row; + } + } + } + + /* Do the actual writing of the filtered row data from the chosen filter. */ + png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); + +#endif /* WRITE_FILTER */ +} + + +/* Do the actual writing of a previously filtered row. */ +static void +png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, + size_t full_row_length/*includes filter byte*/) +{ + png_debug(1, "in png_write_filtered_row"); + + png_debug1(2, "filter = %d", filtered_row[0]); + + png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); + +#ifdef PNG_WRITE_FILTER_SUPPORTED + /* Swap the current and previous rows */ + if (png_ptr->prev_row != NULL) + { + png_bytep tptr; + + tptr = png_ptr->prev_row; + png_ptr->prev_row = png_ptr->row_buf; + png_ptr->row_buf = tptr; + } +#endif /* WRITE_FILTER */ + + /* Finish row - updates counters and flushes zlib if last row */ + png_write_finish_row(png_ptr); + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->flush_rows++; + + if (png_ptr->flush_dist > 0 && + png_ptr->flush_rows >= png_ptr->flush_dist) + { + png_write_flush(png_ptr); + } +#endif /* WRITE_FLUSH */ +} +#endif /* WRITE */ diff --git a/thirdparty/libwebp/libwebp.c b/thirdparty/libwebp/libwebp.c index 5f47a7130..575a1bb31 100644 --- a/thirdparty/libwebp/libwebp.c +++ b/thirdparty/libwebp/libwebp.c @@ -375,5 +375,7 @@ #include "libwebp_undef.h" #include "src/utils/utils.c" #include "libwebp_undef.h" +#define clip_8b clip_8b_quant #include "src/utils/quant_levels_dec_utils.c" +#undef clip_8b #include "libwebp_undef.h" diff --git a/thirdparty/libwebp/upstream/src/dec/Makefile.am b/thirdparty/libwebp/upstream/src/dec/Makefile.am deleted file mode 100644 index f8c6398d9..000000000 --- a/thirdparty/libwebp/upstream/src/dec/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) -noinst_LTLIBRARIES = libwebpdecode.la - -libwebpdecode_la_SOURCES = -libwebpdecode_la_SOURCES += alpha_dec.c -libwebpdecode_la_SOURCES += alphai_dec.h -libwebpdecode_la_SOURCES += buffer_dec.c -libwebpdecode_la_SOURCES += common_dec.h -libwebpdecode_la_SOURCES += vp8_dec.h -libwebpdecode_la_SOURCES += frame_dec.c -libwebpdecode_la_SOURCES += idec_dec.c -libwebpdecode_la_SOURCES += io_dec.c -libwebpdecode_la_SOURCES += quant_dec.c -libwebpdecode_la_SOURCES += tree_dec.c -libwebpdecode_la_SOURCES += vp8_dec.c -libwebpdecode_la_SOURCES += vp8i_dec.h -libwebpdecode_la_SOURCES += vp8l_dec.c -libwebpdecode_la_SOURCES += vp8li_dec.h -libwebpdecode_la_SOURCES += webp_dec.c -libwebpdecode_la_SOURCES += webpi_dec.h - -libwebpdecodeinclude_HEADERS = -libwebpdecodeinclude_HEADERS += ../webp/decode.h -libwebpdecodeinclude_HEADERS += ../webp/types.h -noinst_HEADERS = -noinst_HEADERS += ../webp/format_constants.h - -libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS) -libwebpdecodeincludedir = $(includedir)/webp diff --git a/thirdparty/libwebp/upstream/src/dec/Makefile.in b/thirdparty/libwebp/upstream/src/dec/Makefile.in deleted file mode 100644 index 5ff28417c..000000000 --- a/thirdparty/libwebp/upstream/src/dec/Makefile.in +++ /dev/null @@ -1,797 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/dec -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(libwebpdecodeinclude_HEADERS) \ - $(noinst_HEADERS) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/webp/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libwebpdecode_la_LIBADD = -am_libwebpdecode_la_OBJECTS = libwebpdecode_la-alpha_dec.lo \ - libwebpdecode_la-buffer_dec.lo libwebpdecode_la-frame_dec.lo \ - libwebpdecode_la-idec_dec.lo libwebpdecode_la-io_dec.lo \ - libwebpdecode_la-quant_dec.lo libwebpdecode_la-tree_dec.lo \ - libwebpdecode_la-vp8_dec.lo libwebpdecode_la-vp8l_dec.lo \ - libwebpdecode_la-webp_dec.lo -libwebpdecode_la_OBJECTS = $(am_libwebpdecode_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/webp -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/libwebpdecode_la-alpha_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-buffer_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-frame_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-idec_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-io_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-quant_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-tree_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-vp8_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-vp8l_dec.Plo \ - ./$(DEPDIR)/libwebpdecode_la-webp_dec.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libwebpdecode_la_SOURCES) -DIST_SOURCES = $(libwebpdecode_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libwebpdecodeincludedir)" -HEADERS = $(libwebpdecodeinclude_HEADERS) $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_builddir) -I$(top_srcdir) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GIF_INCLUDES = @GIF_INCLUDES@ -GIF_LIBS = @GIF_LIBS@ -GL_INCLUDES = @GL_INCLUDES@ -GL_LIBS = @GL_LIBS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JPEG_INCLUDES = @JPEG_INCLUDES@ -JPEG_LIBS = @JPEG_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBPNG_CONFIG = @LIBPNG_CONFIG@ -LIBS = @LIBS@ -LIBSDL_CONFIG = @LIBSDL_CONFIG@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NEON_FLAGS = @NEON_FLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PNG_INCLUDES = @PNG_INCLUDES@ -PNG_LIBS = @PNG_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_INCLUDES = @SDL_INCLUDES@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE2_FLAGS = @SSE2_FLAGS@ -SSE41_FLAGS = @SSE41_FLAGS@ -STRIP = @STRIP@ -TIFF_INCLUDES = @TIFF_INCLUDES@ -TIFF_LIBS = @TIFF_LIBS@ -USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgconfigdir = @pkgconfigdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -webp_libname_prefix = @webp_libname_prefix@ -noinst_LTLIBRARIES = libwebpdecode.la -libwebpdecode_la_SOURCES = alpha_dec.c alphai_dec.h buffer_dec.c \ - common_dec.h vp8_dec.h frame_dec.c idec_dec.c io_dec.c \ - quant_dec.c tree_dec.c vp8_dec.c vp8i_dec.h vp8l_dec.c \ - vp8li_dec.h webp_dec.c webpi_dec.h -libwebpdecodeinclude_HEADERS = ../webp/decode.h ../webp/types.h -noinst_HEADERS = ../webp/format_constants.h -libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS) -libwebpdecodeincludedir = $(includedir)/webp -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/dec/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/dec/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libwebpdecode.la: $(libwebpdecode_la_OBJECTS) $(libwebpdecode_la_DEPENDENCIES) $(EXTRA_libwebpdecode_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libwebpdecode_la_OBJECTS) $(libwebpdecode_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-alpha_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-buffer_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-frame_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-idec_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-io_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-quant_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-tree_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-vp8_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-vp8l_dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdecode_la-webp_dec.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libwebpdecode_la-alpha_dec.lo: alpha_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-alpha_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-alpha_dec.Tpo -c -o libwebpdecode_la-alpha_dec.lo `test -f 'alpha_dec.c' || echo '$(srcdir)/'`alpha_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-alpha_dec.Tpo $(DEPDIR)/libwebpdecode_la-alpha_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_dec.c' object='libwebpdecode_la-alpha_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-alpha_dec.lo `test -f 'alpha_dec.c' || echo '$(srcdir)/'`alpha_dec.c - -libwebpdecode_la-buffer_dec.lo: buffer_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-buffer_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-buffer_dec.Tpo -c -o libwebpdecode_la-buffer_dec.lo `test -f 'buffer_dec.c' || echo '$(srcdir)/'`buffer_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-buffer_dec.Tpo $(DEPDIR)/libwebpdecode_la-buffer_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer_dec.c' object='libwebpdecode_la-buffer_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-buffer_dec.lo `test -f 'buffer_dec.c' || echo '$(srcdir)/'`buffer_dec.c - -libwebpdecode_la-frame_dec.lo: frame_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-frame_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-frame_dec.Tpo -c -o libwebpdecode_la-frame_dec.lo `test -f 'frame_dec.c' || echo '$(srcdir)/'`frame_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-frame_dec.Tpo $(DEPDIR)/libwebpdecode_la-frame_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame_dec.c' object='libwebpdecode_la-frame_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-frame_dec.lo `test -f 'frame_dec.c' || echo '$(srcdir)/'`frame_dec.c - -libwebpdecode_la-idec_dec.lo: idec_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-idec_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-idec_dec.Tpo -c -o libwebpdecode_la-idec_dec.lo `test -f 'idec_dec.c' || echo '$(srcdir)/'`idec_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-idec_dec.Tpo $(DEPDIR)/libwebpdecode_la-idec_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='idec_dec.c' object='libwebpdecode_la-idec_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-idec_dec.lo `test -f 'idec_dec.c' || echo '$(srcdir)/'`idec_dec.c - -libwebpdecode_la-io_dec.lo: io_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-io_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-io_dec.Tpo -c -o libwebpdecode_la-io_dec.lo `test -f 'io_dec.c' || echo '$(srcdir)/'`io_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-io_dec.Tpo $(DEPDIR)/libwebpdecode_la-io_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io_dec.c' object='libwebpdecode_la-io_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-io_dec.lo `test -f 'io_dec.c' || echo '$(srcdir)/'`io_dec.c - -libwebpdecode_la-quant_dec.lo: quant_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-quant_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-quant_dec.Tpo -c -o libwebpdecode_la-quant_dec.lo `test -f 'quant_dec.c' || echo '$(srcdir)/'`quant_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-quant_dec.Tpo $(DEPDIR)/libwebpdecode_la-quant_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quant_dec.c' object='libwebpdecode_la-quant_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-quant_dec.lo `test -f 'quant_dec.c' || echo '$(srcdir)/'`quant_dec.c - -libwebpdecode_la-tree_dec.lo: tree_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-tree_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-tree_dec.Tpo -c -o libwebpdecode_la-tree_dec.lo `test -f 'tree_dec.c' || echo '$(srcdir)/'`tree_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-tree_dec.Tpo $(DEPDIR)/libwebpdecode_la-tree_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tree_dec.c' object='libwebpdecode_la-tree_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-tree_dec.lo `test -f 'tree_dec.c' || echo '$(srcdir)/'`tree_dec.c - -libwebpdecode_la-vp8_dec.lo: vp8_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-vp8_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-vp8_dec.Tpo -c -o libwebpdecode_la-vp8_dec.lo `test -f 'vp8_dec.c' || echo '$(srcdir)/'`vp8_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-vp8_dec.Tpo $(DEPDIR)/libwebpdecode_la-vp8_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vp8_dec.c' object='libwebpdecode_la-vp8_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-vp8_dec.lo `test -f 'vp8_dec.c' || echo '$(srcdir)/'`vp8_dec.c - -libwebpdecode_la-vp8l_dec.lo: vp8l_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-vp8l_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-vp8l_dec.Tpo -c -o libwebpdecode_la-vp8l_dec.lo `test -f 'vp8l_dec.c' || echo '$(srcdir)/'`vp8l_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-vp8l_dec.Tpo $(DEPDIR)/libwebpdecode_la-vp8l_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vp8l_dec.c' object='libwebpdecode_la-vp8l_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-vp8l_dec.lo `test -f 'vp8l_dec.c' || echo '$(srcdir)/'`vp8l_dec.c - -libwebpdecode_la-webp_dec.lo: webp_dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdecode_la-webp_dec.lo -MD -MP -MF $(DEPDIR)/libwebpdecode_la-webp_dec.Tpo -c -o libwebpdecode_la-webp_dec.lo `test -f 'webp_dec.c' || echo '$(srcdir)/'`webp_dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdecode_la-webp_dec.Tpo $(DEPDIR)/libwebpdecode_la-webp_dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='webp_dec.c' object='libwebpdecode_la-webp_dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdecode_la-webp_dec.lo `test -f 'webp_dec.c' || echo '$(srcdir)/'`webp_dec.c - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-libwebpdecodeincludeHEADERS: $(libwebpdecodeinclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(libwebpdecodeinclude_HEADERS)'; test -n "$(libwebpdecodeincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libwebpdecodeincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libwebpdecodeincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpdecodeincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpdecodeincludedir)" || exit $$?; \ - done - -uninstall-libwebpdecodeincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libwebpdecodeinclude_HEADERS)'; test -n "$(libwebpdecodeincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libwebpdecodeincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libwebpdecodeincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/libwebpdecode_la-alpha_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-buffer_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-frame_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-idec_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-io_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-quant_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-tree_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-vp8_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-vp8l_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-webp_dec.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-libwebpdecodeincludeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libwebpdecode_la-alpha_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-buffer_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-frame_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-idec_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-io_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-quant_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-tree_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-vp8_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-vp8l_dec.Plo - -rm -f ./$(DEPDIR)/libwebpdecode_la-webp_dec.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-libwebpdecodeincludeHEADERS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstLTLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am \ - install-libwebpdecodeincludeHEADERS install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am \ - uninstall-libwebpdecodeincludeHEADERS - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libwebp/upstream/src/demux/Makefile.am b/thirdparty/libwebp/upstream/src/demux/Makefile.am deleted file mode 100644 index 9ecff1464..000000000 --- a/thirdparty/libwebp/upstream/src/demux/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) -lib_LTLIBRARIES = libwebpdemux.la - -libwebpdemux_la_SOURCES = -libwebpdemux_la_SOURCES += anim_decode.c demux.c - -libwebpdemuxinclude_HEADERS = -libwebpdemuxinclude_HEADERS += ../webp/decode.h -libwebpdemuxinclude_HEADERS += ../webp/demux.h -libwebpdemuxinclude_HEADERS += ../webp/mux_types.h -libwebpdemuxinclude_HEADERS += ../webp/types.h -noinst_HEADERS = -noinst_HEADERS += ../webp/format_constants.h - -libwebpdemux_la_LIBADD = ../libwebp.la -libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:15:0 -libwebpdemuxincludedir = $(includedir)/webp -pkgconfig_DATA = libwebpdemux.pc diff --git a/thirdparty/libwebp/upstream/src/demux/Makefile.in b/thirdparty/libwebp/upstream/src/demux/Makefile.in deleted file mode 100644 index 142df83ef..000000000 --- a/thirdparty/libwebp/upstream/src/demux/Makefile.in +++ /dev/null @@ -1,748 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/demux -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(libwebpdemuxinclude_HEADERS) \ - $(noinst_HEADERS) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/webp/config.h -CONFIG_CLEAN_FILES = libwebpdemux.pc -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(libwebpdemuxincludedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libwebpdemux_la_DEPENDENCIES = ../libwebp.la -am_libwebpdemux_la_OBJECTS = anim_decode.lo demux.lo -libwebpdemux_la_OBJECTS = $(am_libwebpdemux_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libwebpdemux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libwebpdemux_la_LDFLAGS) $(LDFLAGS) \ - -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/webp -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/anim_decode.Plo \ - ./$(DEPDIR)/demux.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libwebpdemux_la_SOURCES) -DIST_SOURCES = $(libwebpdemux_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -DATA = $(pkgconfig_DATA) -HEADERS = $(libwebpdemuxinclude_HEADERS) $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libwebpdemux.pc.in \ - $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_builddir) -I$(top_srcdir) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GIF_INCLUDES = @GIF_INCLUDES@ -GIF_LIBS = @GIF_LIBS@ -GL_INCLUDES = @GL_INCLUDES@ -GL_LIBS = @GL_LIBS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JPEG_INCLUDES = @JPEG_INCLUDES@ -JPEG_LIBS = @JPEG_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBPNG_CONFIG = @LIBPNG_CONFIG@ -LIBS = @LIBS@ -LIBSDL_CONFIG = @LIBSDL_CONFIG@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NEON_FLAGS = @NEON_FLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PNG_INCLUDES = @PNG_INCLUDES@ -PNG_LIBS = @PNG_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_INCLUDES = @SDL_INCLUDES@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE2_FLAGS = @SSE2_FLAGS@ -SSE41_FLAGS = @SSE41_FLAGS@ -STRIP = @STRIP@ -TIFF_INCLUDES = @TIFF_INCLUDES@ -TIFF_LIBS = @TIFF_LIBS@ -USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgconfigdir = @pkgconfigdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -webp_libname_prefix = @webp_libname_prefix@ -lib_LTLIBRARIES = libwebpdemux.la -libwebpdemux_la_SOURCES = anim_decode.c demux.c -libwebpdemuxinclude_HEADERS = ../webp/decode.h ../webp/demux.h \ - ../webp/mux_types.h ../webp/types.h -noinst_HEADERS = ../webp/format_constants.h -libwebpdemux_la_LIBADD = ../libwebp.la -libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:15:0 -libwebpdemuxincludedir = $(includedir)/webp -pkgconfig_DATA = libwebpdemux.pc -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/demux/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/demux/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -libwebpdemux.pc: $(top_builddir)/config.status $(srcdir)/libwebpdemux.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libwebpdemux.la: $(libwebpdemux_la_OBJECTS) $(libwebpdemux_la_DEPENDENCIES) $(EXTRA_libwebpdemux_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdemux_la_LINK) -rpath $(libdir) $(libwebpdemux_la_OBJECTS) $(libwebpdemux_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anim_decode.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demux.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-pkgconfigDATA: $(pkgconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ - done - -uninstall-pkgconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-libwebpdemuxincludeHEADERS: $(libwebpdemuxinclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(libwebpdemuxinclude_HEADERS)'; test -n "$(libwebpdemuxincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libwebpdemuxincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libwebpdemuxincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpdemuxincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpdemuxincludedir)" || exit $$?; \ - done - -uninstall-libwebpdemuxincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libwebpdemuxinclude_HEADERS)'; test -n "$(libwebpdemuxincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libwebpdemuxincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libwebpdemuxincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/anim_decode.Plo - -rm -f ./$(DEPDIR)/demux.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-libwebpdemuxincludeHEADERS \ - install-pkgconfigDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/anim_decode.Plo - -rm -f ./$(DEPDIR)/demux.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-libLTLIBRARIES \ - uninstall-libwebpdemuxincludeHEADERS uninstall-pkgconfigDATA - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES \ - install-libwebpdemuxincludeHEADERS install-man install-pdf \ - install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-libLTLIBRARIES uninstall-libwebpdemuxincludeHEADERS \ - uninstall-pkgconfigDATA - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libwebp/upstream/src/demux/libwebpdemux.pc.in b/thirdparty/libwebp/upstream/src/demux/libwebpdemux.pc.in deleted file mode 100644 index 4da2e40ad..000000000 --- a/thirdparty/libwebp/upstream/src/demux/libwebpdemux.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libwebpdemux -Description: Library for parsing the WebP graphics format container -Version: @PACKAGE_VERSION@ -Requires.private: libwebp >= 0.2.0 -Cflags: -I${includedir} -Libs: -L${libdir} -l@webp_libname_prefix@webpdemux diff --git a/thirdparty/libwebp/upstream/src/demux/libwebpdemux.rc b/thirdparty/libwebp/upstream/src/demux/libwebpdemux.rc deleted file mode 100644 index bc57c4089..000000000 --- a/thirdparty/libwebp/upstream/src/demux/libwebpdemux.rc +++ /dev/null @@ -1,41 +0,0 @@ -#define APSTUDIO_READONLY_SYMBOLS -#include "winres.h" -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,4,0 - PRODUCTVERSION 1,0,4,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Google, Inc." - VALUE "FileDescription", "libwebpdemux DLL" - VALUE "FileVersion", "1.4.0" - VALUE "InternalName", "libwebpdemux.dll" - VALUE "LegalCopyright", "Copyright (C) 2024" - VALUE "OriginalFilename", "libwebpdemux.dll" - VALUE "ProductName", "WebP Image Demuxer" - VALUE "ProductVersion", "1.4.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (United States) resources diff --git a/thirdparty/libwebp/upstream/src/dsp/Makefile.am b/thirdparty/libwebp/upstream/src/dsp/Makefile.am deleted file mode 100644 index 7db4ef0f0..000000000 --- a/thirdparty/libwebp/upstream/src/dsp/Makefile.am +++ /dev/null @@ -1,187 +0,0 @@ -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) -noinst_LTLIBRARIES = -noinst_LTLIBRARIES += libwebpdsp.la -noinst_LTLIBRARIES += libwebpdsp_sse2.la -noinst_LTLIBRARIES += libwebpdspdecode_sse2.la -noinst_LTLIBRARIES += libwebpdsp_sse41.la -noinst_LTLIBRARIES += libwebpdspdecode_sse41.la -noinst_LTLIBRARIES += libwebpdsp_neon.la -noinst_LTLIBRARIES += libwebpdspdecode_neon.la -noinst_LTLIBRARIES += libwebpdsp_msa.la -noinst_LTLIBRARIES += libwebpdspdecode_msa.la -noinst_LTLIBRARIES += libwebpdsp_mips32.la -noinst_LTLIBRARIES += libwebpdspdecode_mips32.la -noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la -noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la - -if BUILD_LIBWEBPDECODER - noinst_LTLIBRARIES += libwebpdspdecode.la -endif - -common_HEADERS = ../webp/types.h -commondir = $(includedir)/webp - -COMMON_SOURCES = -COMMON_SOURCES += alpha_processing.c -COMMON_SOURCES += cpu.c -COMMON_SOURCES += cpu.h -COMMON_SOURCES += dec.c -COMMON_SOURCES += dec_clip_tables.c -COMMON_SOURCES += dsp.h -COMMON_SOURCES += filters.c -COMMON_SOURCES += lossless.c -COMMON_SOURCES += lossless.h -COMMON_SOURCES += lossless_common.h -COMMON_SOURCES += rescaler.c -COMMON_SOURCES += upsampling.c -COMMON_SOURCES += yuv.c -COMMON_SOURCES += yuv.h - -ENC_SOURCES = -ENC_SOURCES += cost.c -ENC_SOURCES += enc.c -ENC_SOURCES += lossless_enc.c -ENC_SOURCES += quant.h -ENC_SOURCES += ssim.c - -libwebpdspdecode_sse41_la_SOURCES = -libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c -libwebpdspdecode_sse41_la_SOURCES += dec_sse41.c -libwebpdspdecode_sse41_la_SOURCES += lossless_sse41.c -libwebpdspdecode_sse41_la_SOURCES += upsampling_sse41.c -libwebpdspdecode_sse41_la_SOURCES += yuv_sse41.c -libwebpdspdecode_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdspdecode_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_FLAGS) - -libwebpdspdecode_sse2_la_SOURCES = -libwebpdspdecode_sse2_la_SOURCES += alpha_processing_sse2.c -libwebpdspdecode_sse2_la_SOURCES += common_sse2.h -libwebpdspdecode_sse2_la_SOURCES += dec_sse2.c -libwebpdspdecode_sse2_la_SOURCES += filters_sse2.c -libwebpdspdecode_sse2_la_SOURCES += lossless_sse2.c -libwebpdspdecode_sse2_la_SOURCES += rescaler_sse2.c -libwebpdspdecode_sse2_la_SOURCES += upsampling_sse2.c -libwebpdspdecode_sse2_la_SOURCES += yuv_sse2.c -libwebpdspdecode_sse2_la_CPPFLAGS = $(libwebpdsp_sse2_la_CPPFLAGS) -libwebpdspdecode_sse2_la_CFLAGS = $(libwebpdsp_sse2_la_CFLAGS) - -libwebpdspdecode_neon_la_SOURCES = -libwebpdspdecode_neon_la_SOURCES += alpha_processing_neon.c -libwebpdspdecode_neon_la_SOURCES += dec_neon.c -libwebpdspdecode_neon_la_SOURCES += filters_neon.c -libwebpdspdecode_neon_la_SOURCES += lossless_neon.c -libwebpdspdecode_neon_la_SOURCES += neon.h -libwebpdspdecode_neon_la_SOURCES += rescaler_neon.c -libwebpdspdecode_neon_la_SOURCES += upsampling_neon.c -libwebpdspdecode_neon_la_SOURCES += yuv_neon.c -libwebpdspdecode_neon_la_CPPFLAGS = $(libwebpdsp_neon_la_CPPFLAGS) -libwebpdspdecode_neon_la_CFLAGS = $(libwebpdsp_neon_la_CFLAGS) - -libwebpdspdecode_msa_la_SOURCES = -libwebpdspdecode_msa_la_SOURCES += dec_msa.c -libwebpdspdecode_msa_la_SOURCES += filters_msa.c -libwebpdspdecode_msa_la_SOURCES += lossless_msa.c -libwebpdspdecode_msa_la_SOURCES += msa_macro.h -libwebpdspdecode_msa_la_SOURCES += rescaler_msa.c -libwebpdspdecode_msa_la_SOURCES += upsampling_msa.c -libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS) -libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS) - -libwebpdspdecode_mips32_la_SOURCES = -libwebpdspdecode_mips32_la_SOURCES += dec_mips32.c -libwebpdspdecode_mips32_la_SOURCES += mips_macro.h -libwebpdspdecode_mips32_la_SOURCES += rescaler_mips32.c -libwebpdspdecode_mips32_la_SOURCES += yuv_mips32.c -libwebpdspdecode_mips32_la_CPPFLAGS = $(libwebpdsp_mips32_la_CPPFLAGS) -libwebpdspdecode_mips32_la_CFLAGS = $(libwebpdsp_mips32_la_CFLAGS) - -libwebpdspdecode_mips_dsp_r2_la_SOURCES = -libwebpdspdecode_mips_dsp_r2_la_SOURCES += alpha_processing_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_SOURCES += dec_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_SOURCES += filters_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_SOURCES += lossless_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_SOURCES += mips_macro.h -libwebpdspdecode_mips_dsp_r2_la_SOURCES += rescaler_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_SOURCES += upsampling_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_SOURCES += yuv_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) -libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS) - -libwebpdsp_sse2_la_SOURCES = -libwebpdsp_sse2_la_SOURCES += cost_sse2.c -libwebpdsp_sse2_la_SOURCES += enc_sse2.c -libwebpdsp_sse2_la_SOURCES += lossless_enc_sse2.c -libwebpdsp_sse2_la_SOURCES += ssim_sse2.c -libwebpdsp_sse2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS) -libwebpdsp_sse2_la_LIBADD = libwebpdspdecode_sse2.la - -libwebpdsp_sse41_la_SOURCES = -libwebpdsp_sse41_la_SOURCES += enc_sse41.c -libwebpdsp_sse41_la_SOURCES += lossless_enc_sse41.c -libwebpdsp_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_FLAGS) -libwebpdsp_sse41_la_LIBADD = libwebpdspdecode_sse41.la - -libwebpdsp_neon_la_SOURCES = -libwebpdsp_neon_la_SOURCES += cost_neon.c -libwebpdsp_neon_la_SOURCES += enc_neon.c -libwebpdsp_neon_la_SOURCES += lossless_enc_neon.c -libwebpdsp_neon_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS) -libwebpdsp_neon_la_LIBADD = libwebpdspdecode_neon.la - -libwebpdsp_msa_la_SOURCES = -libwebpdsp_msa_la_SOURCES += enc_msa.c -libwebpdsp_msa_la_SOURCES += lossless_enc_msa.c -libwebpdsp_msa_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_msa_la_CFLAGS = $(AM_CFLAGS) -libwebpdsp_msa_la_LIBADD = libwebpdspdecode_msa.la - -libwebpdsp_mips32_la_SOURCES = -libwebpdsp_mips32_la_SOURCES += cost_mips32.c -libwebpdsp_mips32_la_SOURCES += enc_mips32.c -libwebpdsp_mips32_la_SOURCES += lossless_enc_mips32.c -libwebpdsp_mips32_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_mips32_la_CFLAGS = $(AM_CFLAGS) -libwebpdsp_mips32_la_LIBADD = libwebpdspdecode_mips32.la - -libwebpdsp_mips_dsp_r2_la_SOURCES = -libwebpdsp_mips_dsp_r2_la_SOURCES += cost_mips_dsp_r2.c -libwebpdsp_mips_dsp_r2_la_SOURCES += enc_mips_dsp_r2.c -libwebpdsp_mips_dsp_r2_la_SOURCES += lossless_enc_mips_dsp_r2.c -libwebpdsp_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_mips_dsp_r2_la_CFLAGS = $(AM_CFLAGS) -libwebpdsp_mips_dsp_r2_la_LIBADD = libwebpdspdecode_mips_dsp_r2.la - -libwebpdsp_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) - -noinst_HEADERS = -noinst_HEADERS += ../dec/vp8_dec.h -noinst_HEADERS += ../webp/decode.h - -libwebpdsp_la_CPPFLAGS = -libwebpdsp_la_CPPFLAGS += $(AM_CPPFLAGS) -libwebpdsp_la_CPPFLAGS += $(USE_SWAP_16BIT_CSP) -libwebpdsp_la_LDFLAGS = -lm -libwebpdsp_la_LIBADD = -libwebpdsp_la_LIBADD += libwebpdsp_sse2.la -libwebpdsp_la_LIBADD += libwebpdsp_sse41.la -libwebpdsp_la_LIBADD += libwebpdsp_neon.la -libwebpdsp_la_LIBADD += libwebpdsp_msa.la -libwebpdsp_la_LIBADD += libwebpdsp_mips32.la -libwebpdsp_la_LIBADD += libwebpdsp_mips_dsp_r2.la - -if BUILD_LIBWEBPDECODER - libwebpdspdecode_la_SOURCES = $(COMMON_SOURCES) - - libwebpdspdecode_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) - libwebpdspdecode_la_LDFLAGS = $(libwebpdsp_la_LDFLAGS) - libwebpdspdecode_la_LIBADD = - libwebpdspdecode_la_LIBADD += libwebpdspdecode_sse2.la - libwebpdspdecode_la_LIBADD += libwebpdspdecode_sse41.la - libwebpdspdecode_la_LIBADD += libwebpdspdecode_neon.la - libwebpdspdecode_la_LIBADD += libwebpdspdecode_msa.la - libwebpdspdecode_la_LIBADD += libwebpdspdecode_mips32.la - libwebpdspdecode_la_LIBADD += libwebpdspdecode_mips_dsp_r2.la -endif diff --git a/thirdparty/libwebp/upstream/src/dsp/Makefile.in b/thirdparty/libwebp/upstream/src/dsp/Makefile.in deleted file mode 100644 index 9c8175c00..000000000 --- a/thirdparty/libwebp/upstream/src/dsp/Makefile.in +++ /dev/null @@ -1,1796 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@BUILD_LIBWEBPDECODER_TRUE@am__append_1 = libwebpdspdecode.la -subdir = src/dsp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(common_HEADERS) \ - $(noinst_HEADERS) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/webp/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libwebpdsp_la_DEPENDENCIES = libwebpdsp_sse2.la libwebpdsp_sse41.la \ - libwebpdsp_neon.la libwebpdsp_msa.la libwebpdsp_mips32.la \ - libwebpdsp_mips_dsp_r2.la -am__objects_1 = libwebpdsp_la-alpha_processing.lo libwebpdsp_la-cpu.lo \ - libwebpdsp_la-dec.lo libwebpdsp_la-dec_clip_tables.lo \ - libwebpdsp_la-filters.lo libwebpdsp_la-lossless.lo \ - libwebpdsp_la-rescaler.lo libwebpdsp_la-upsampling.lo \ - libwebpdsp_la-yuv.lo -am__objects_2 = libwebpdsp_la-cost.lo libwebpdsp_la-enc.lo \ - libwebpdsp_la-lossless_enc.lo libwebpdsp_la-ssim.lo -am_libwebpdsp_la_OBJECTS = $(am__objects_1) $(am__objects_2) -libwebpdsp_la_OBJECTS = $(am_libwebpdsp_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libwebpdsp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libwebpdsp_la_LDFLAGS) $(LDFLAGS) -o $@ -libwebpdsp_mips32_la_DEPENDENCIES = libwebpdspdecode_mips32.la -am_libwebpdsp_mips32_la_OBJECTS = libwebpdsp_mips32_la-cost_mips32.lo \ - libwebpdsp_mips32_la-enc_mips32.lo \ - libwebpdsp_mips32_la-lossless_enc_mips32.lo -libwebpdsp_mips32_la_OBJECTS = $(am_libwebpdsp_mips32_la_OBJECTS) -libwebpdsp_mips32_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdsp_mips_dsp_r2_la_DEPENDENCIES = \ - libwebpdspdecode_mips_dsp_r2.la -am_libwebpdsp_mips_dsp_r2_la_OBJECTS = \ - libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.lo \ - libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.lo \ - libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.lo -libwebpdsp_mips_dsp_r2_la_OBJECTS = \ - $(am_libwebpdsp_mips_dsp_r2_la_OBJECTS) -libwebpdsp_mips_dsp_r2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdsp_msa_la_DEPENDENCIES = libwebpdspdecode_msa.la -am_libwebpdsp_msa_la_OBJECTS = libwebpdsp_msa_la-enc_msa.lo \ - libwebpdsp_msa_la-lossless_enc_msa.lo -libwebpdsp_msa_la_OBJECTS = $(am_libwebpdsp_msa_la_OBJECTS) -libwebpdsp_msa_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdsp_msa_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ - -o $@ -libwebpdsp_neon_la_DEPENDENCIES = libwebpdspdecode_neon.la -am_libwebpdsp_neon_la_OBJECTS = libwebpdsp_neon_la-cost_neon.lo \ - libwebpdsp_neon_la-enc_neon.lo \ - libwebpdsp_neon_la-lossless_enc_neon.lo -libwebpdsp_neon_la_OBJECTS = $(am_libwebpdsp_neon_la_OBJECTS) -libwebpdsp_neon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdsp_sse2_la_DEPENDENCIES = libwebpdspdecode_sse2.la -am_libwebpdsp_sse2_la_OBJECTS = libwebpdsp_sse2_la-cost_sse2.lo \ - libwebpdsp_sse2_la-enc_sse2.lo \ - libwebpdsp_sse2_la-lossless_enc_sse2.lo \ - libwebpdsp_sse2_la-ssim_sse2.lo -libwebpdsp_sse2_la_OBJECTS = $(am_libwebpdsp_sse2_la_OBJECTS) -libwebpdsp_sse2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdsp_sse41_la_DEPENDENCIES = libwebpdspdecode_sse41.la -am_libwebpdsp_sse41_la_OBJECTS = libwebpdsp_sse41_la-enc_sse41.lo \ - libwebpdsp_sse41_la-lossless_enc_sse41.lo -libwebpdsp_sse41_la_OBJECTS = $(am_libwebpdsp_sse41_la_OBJECTS) -libwebpdsp_sse41_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdsp_sse41_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -@BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_DEPENDENCIES = \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_sse2.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_sse41.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_neon.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_msa.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_mips32.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_mips_dsp_r2.la -am__libwebpdspdecode_la_SOURCES_DIST = alpha_processing.c cpu.c cpu.h \ - dec.c dec_clip_tables.c dsp.h filters.c lossless.c lossless.h \ - lossless_common.h rescaler.c upsampling.c yuv.c yuv.h -am__objects_3 = libwebpdspdecode_la-alpha_processing.lo \ - libwebpdspdecode_la-cpu.lo libwebpdspdecode_la-dec.lo \ - libwebpdspdecode_la-dec_clip_tables.lo \ - libwebpdspdecode_la-filters.lo libwebpdspdecode_la-lossless.lo \ - libwebpdspdecode_la-rescaler.lo \ - libwebpdspdecode_la-upsampling.lo libwebpdspdecode_la-yuv.lo -@BUILD_LIBWEBPDECODER_TRUE@am_libwebpdspdecode_la_OBJECTS = \ -@BUILD_LIBWEBPDECODER_TRUE@ $(am__objects_3) -libwebpdspdecode_la_OBJECTS = $(am_libwebpdspdecode_la_OBJECTS) -libwebpdspdecode_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libwebpdspdecode_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -@BUILD_LIBWEBPDECODER_TRUE@am_libwebpdspdecode_la_rpath = -libwebpdspdecode_mips32_la_LIBADD = -am_libwebpdspdecode_mips32_la_OBJECTS = \ - libwebpdspdecode_mips32_la-dec_mips32.lo \ - libwebpdspdecode_mips32_la-rescaler_mips32.lo \ - libwebpdspdecode_mips32_la-yuv_mips32.lo -libwebpdspdecode_mips32_la_OBJECTS = \ - $(am_libwebpdspdecode_mips32_la_OBJECTS) -libwebpdspdecode_mips32_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdspdecode_mips_dsp_r2_la_LIBADD = -am_libwebpdspdecode_mips_dsp_r2_la_OBJECTS = libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.lo \ - libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.lo \ - libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.lo \ - libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.lo \ - libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.lo \ - libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.lo \ - libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.lo -libwebpdspdecode_mips_dsp_r2_la_OBJECTS = \ - $(am_libwebpdspdecode_mips_dsp_r2_la_OBJECTS) -libwebpdspdecode_mips_dsp_r2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -libwebpdspdecode_msa_la_LIBADD = -am_libwebpdspdecode_msa_la_OBJECTS = \ - libwebpdspdecode_msa_la-dec_msa.lo \ - libwebpdspdecode_msa_la-filters_msa.lo \ - libwebpdspdecode_msa_la-lossless_msa.lo \ - libwebpdspdecode_msa_la-rescaler_msa.lo \ - libwebpdspdecode_msa_la-upsampling_msa.lo -libwebpdspdecode_msa_la_OBJECTS = \ - $(am_libwebpdspdecode_msa_la_OBJECTS) -libwebpdspdecode_msa_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdspdecode_neon_la_LIBADD = -am_libwebpdspdecode_neon_la_OBJECTS = \ - libwebpdspdecode_neon_la-alpha_processing_neon.lo \ - libwebpdspdecode_neon_la-dec_neon.lo \ - libwebpdspdecode_neon_la-filters_neon.lo \ - libwebpdspdecode_neon_la-lossless_neon.lo \ - libwebpdspdecode_neon_la-rescaler_neon.lo \ - libwebpdspdecode_neon_la-upsampling_neon.lo \ - libwebpdspdecode_neon_la-yuv_neon.lo -libwebpdspdecode_neon_la_OBJECTS = \ - $(am_libwebpdspdecode_neon_la_OBJECTS) -libwebpdspdecode_neon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdspdecode_sse2_la_LIBADD = -am_libwebpdspdecode_sse2_la_OBJECTS = \ - libwebpdspdecode_sse2_la-alpha_processing_sse2.lo \ - libwebpdspdecode_sse2_la-dec_sse2.lo \ - libwebpdspdecode_sse2_la-filters_sse2.lo \ - libwebpdspdecode_sse2_la-lossless_sse2.lo \ - libwebpdspdecode_sse2_la-rescaler_sse2.lo \ - libwebpdspdecode_sse2_la-upsampling_sse2.lo \ - libwebpdspdecode_sse2_la-yuv_sse2.lo -libwebpdspdecode_sse2_la_OBJECTS = \ - $(am_libwebpdspdecode_sse2_la_OBJECTS) -libwebpdspdecode_sse2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -libwebpdspdecode_sse41_la_LIBADD = -am_libwebpdspdecode_sse41_la_OBJECTS = \ - libwebpdspdecode_sse41_la-alpha_processing_sse41.lo \ - libwebpdspdecode_sse41_la-dec_sse41.lo \ - libwebpdspdecode_sse41_la-lossless_sse41.lo \ - libwebpdspdecode_sse41_la-upsampling_sse41.lo \ - libwebpdspdecode_sse41_la-yuv_sse41.lo -libwebpdspdecode_sse41_la_OBJECTS = \ - $(am_libwebpdspdecode_sse41_la_OBJECTS) -libwebpdspdecode_sse41_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/webp -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/libwebpdsp_la-alpha_processing.Plo \ - ./$(DEPDIR)/libwebpdsp_la-cost.Plo \ - ./$(DEPDIR)/libwebpdsp_la-cpu.Plo \ - ./$(DEPDIR)/libwebpdsp_la-dec.Plo \ - ./$(DEPDIR)/libwebpdsp_la-dec_clip_tables.Plo \ - ./$(DEPDIR)/libwebpdsp_la-enc.Plo \ - ./$(DEPDIR)/libwebpdsp_la-filters.Plo \ - ./$(DEPDIR)/libwebpdsp_la-lossless.Plo \ - ./$(DEPDIR)/libwebpdsp_la-lossless_enc.Plo \ - ./$(DEPDIR)/libwebpdsp_la-rescaler.Plo \ - ./$(DEPDIR)/libwebpdsp_la-ssim.Plo \ - ./$(DEPDIR)/libwebpdsp_la-upsampling.Plo \ - ./$(DEPDIR)/libwebpdsp_la-yuv.Plo \ - ./$(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Plo \ - ./$(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Plo \ - ./$(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Plo \ - ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdsp_msa_la-enc_msa.Plo \ - ./$(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Plo \ - ./$(DEPDIR)/libwebpdsp_neon_la-cost_neon.Plo \ - ./$(DEPDIR)/libwebpdsp_neon_la-enc_neon.Plo \ - ./$(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Plo \ - ./$(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Plo \ - ./$(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Plo \ - ./$(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Plo \ - ./$(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Plo \ - ./$(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Plo \ - ./$(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-alpha_processing.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-cpu.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-dec.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-filters.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-lossless.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-rescaler.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-upsampling.Plo \ - ./$(DEPDIR)/libwebpdspdecode_la-yuv.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Plo \ - ./$(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Plo \ - ./$(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Plo \ - ./$(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Plo \ - ./$(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Plo \ - ./$(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libwebpdsp_la_SOURCES) $(libwebpdsp_mips32_la_SOURCES) \ - $(libwebpdsp_mips_dsp_r2_la_SOURCES) \ - $(libwebpdsp_msa_la_SOURCES) $(libwebpdsp_neon_la_SOURCES) \ - $(libwebpdsp_sse2_la_SOURCES) $(libwebpdsp_sse41_la_SOURCES) \ - $(libwebpdspdecode_la_SOURCES) \ - $(libwebpdspdecode_mips32_la_SOURCES) \ - $(libwebpdspdecode_mips_dsp_r2_la_SOURCES) \ - $(libwebpdspdecode_msa_la_SOURCES) \ - $(libwebpdspdecode_neon_la_SOURCES) \ - $(libwebpdspdecode_sse2_la_SOURCES) \ - $(libwebpdspdecode_sse41_la_SOURCES) -DIST_SOURCES = $(libwebpdsp_la_SOURCES) \ - $(libwebpdsp_mips32_la_SOURCES) \ - $(libwebpdsp_mips_dsp_r2_la_SOURCES) \ - $(libwebpdsp_msa_la_SOURCES) $(libwebpdsp_neon_la_SOURCES) \ - $(libwebpdsp_sse2_la_SOURCES) $(libwebpdsp_sse41_la_SOURCES) \ - $(am__libwebpdspdecode_la_SOURCES_DIST) \ - $(libwebpdspdecode_mips32_la_SOURCES) \ - $(libwebpdspdecode_mips_dsp_r2_la_SOURCES) \ - $(libwebpdspdecode_msa_la_SOURCES) \ - $(libwebpdspdecode_neon_la_SOURCES) \ - $(libwebpdspdecode_sse2_la_SOURCES) \ - $(libwebpdspdecode_sse41_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(commondir)" -HEADERS = $(common_HEADERS) $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_builddir) -I$(top_srcdir) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GIF_INCLUDES = @GIF_INCLUDES@ -GIF_LIBS = @GIF_LIBS@ -GL_INCLUDES = @GL_INCLUDES@ -GL_LIBS = @GL_LIBS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JPEG_INCLUDES = @JPEG_INCLUDES@ -JPEG_LIBS = @JPEG_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBPNG_CONFIG = @LIBPNG_CONFIG@ -LIBS = @LIBS@ -LIBSDL_CONFIG = @LIBSDL_CONFIG@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NEON_FLAGS = @NEON_FLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PNG_INCLUDES = @PNG_INCLUDES@ -PNG_LIBS = @PNG_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_INCLUDES = @SDL_INCLUDES@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE2_FLAGS = @SSE2_FLAGS@ -SSE41_FLAGS = @SSE41_FLAGS@ -STRIP = @STRIP@ -TIFF_INCLUDES = @TIFF_INCLUDES@ -TIFF_LIBS = @TIFF_LIBS@ -USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgconfigdir = @pkgconfigdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -webp_libname_prefix = @webp_libname_prefix@ -noinst_LTLIBRARIES = libwebpdsp.la libwebpdsp_sse2.la \ - libwebpdspdecode_sse2.la libwebpdsp_sse41.la \ - libwebpdspdecode_sse41.la libwebpdsp_neon.la \ - libwebpdspdecode_neon.la libwebpdsp_msa.la \ - libwebpdspdecode_msa.la libwebpdsp_mips32.la \ - libwebpdspdecode_mips32.la libwebpdsp_mips_dsp_r2.la \ - libwebpdspdecode_mips_dsp_r2.la $(am__append_1) -common_HEADERS = ../webp/types.h -commondir = $(includedir)/webp -COMMON_SOURCES = alpha_processing.c cpu.c cpu.h dec.c \ - dec_clip_tables.c dsp.h filters.c lossless.c lossless.h \ - lossless_common.h rescaler.c upsampling.c yuv.c yuv.h -ENC_SOURCES = cost.c enc.c lossless_enc.c quant.h ssim.c -libwebpdspdecode_sse41_la_SOURCES = alpha_processing_sse41.c \ - dec_sse41.c lossless_sse41.c upsampling_sse41.c yuv_sse41.c -libwebpdspdecode_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdspdecode_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_FLAGS) -libwebpdspdecode_sse2_la_SOURCES = alpha_processing_sse2.c \ - common_sse2.h dec_sse2.c filters_sse2.c lossless_sse2.c \ - rescaler_sse2.c upsampling_sse2.c yuv_sse2.c -libwebpdspdecode_sse2_la_CPPFLAGS = $(libwebpdsp_sse2_la_CPPFLAGS) -libwebpdspdecode_sse2_la_CFLAGS = $(libwebpdsp_sse2_la_CFLAGS) -libwebpdspdecode_neon_la_SOURCES = alpha_processing_neon.c dec_neon.c \ - filters_neon.c lossless_neon.c neon.h rescaler_neon.c \ - upsampling_neon.c yuv_neon.c -libwebpdspdecode_neon_la_CPPFLAGS = $(libwebpdsp_neon_la_CPPFLAGS) -libwebpdspdecode_neon_la_CFLAGS = $(libwebpdsp_neon_la_CFLAGS) -libwebpdspdecode_msa_la_SOURCES = dec_msa.c filters_msa.c \ - lossless_msa.c msa_macro.h rescaler_msa.c upsampling_msa.c -libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS) -libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS) -libwebpdspdecode_mips32_la_SOURCES = dec_mips32.c mips_macro.h \ - rescaler_mips32.c yuv_mips32.c -libwebpdspdecode_mips32_la_CPPFLAGS = $(libwebpdsp_mips32_la_CPPFLAGS) -libwebpdspdecode_mips32_la_CFLAGS = $(libwebpdsp_mips32_la_CFLAGS) -libwebpdspdecode_mips_dsp_r2_la_SOURCES = \ - alpha_processing_mips_dsp_r2.c dec_mips_dsp_r2.c \ - filters_mips_dsp_r2.c lossless_mips_dsp_r2.c mips_macro.h \ - rescaler_mips_dsp_r2.c upsampling_mips_dsp_r2.c \ - yuv_mips_dsp_r2.c -libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) -libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS) -libwebpdsp_sse2_la_SOURCES = cost_sse2.c enc_sse2.c \ - lossless_enc_sse2.c ssim_sse2.c -libwebpdsp_sse2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS) -libwebpdsp_sse2_la_LIBADD = libwebpdspdecode_sse2.la -libwebpdsp_sse41_la_SOURCES = enc_sse41.c lossless_enc_sse41.c -libwebpdsp_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_FLAGS) -libwebpdsp_sse41_la_LIBADD = libwebpdspdecode_sse41.la -libwebpdsp_neon_la_SOURCES = cost_neon.c enc_neon.c \ - lossless_enc_neon.c -libwebpdsp_neon_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS) -libwebpdsp_neon_la_LIBADD = libwebpdspdecode_neon.la -libwebpdsp_msa_la_SOURCES = enc_msa.c lossless_enc_msa.c -libwebpdsp_msa_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_msa_la_CFLAGS = $(AM_CFLAGS) -libwebpdsp_msa_la_LIBADD = libwebpdspdecode_msa.la -libwebpdsp_mips32_la_SOURCES = cost_mips32.c enc_mips32.c \ - lossless_enc_mips32.c -libwebpdsp_mips32_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_mips32_la_CFLAGS = $(AM_CFLAGS) -libwebpdsp_mips32_la_LIBADD = libwebpdspdecode_mips32.la -libwebpdsp_mips_dsp_r2_la_SOURCES = cost_mips_dsp_r2.c \ - enc_mips_dsp_r2.c lossless_enc_mips_dsp_r2.c -libwebpdsp_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -libwebpdsp_mips_dsp_r2_la_CFLAGS = $(AM_CFLAGS) -libwebpdsp_mips_dsp_r2_la_LIBADD = libwebpdspdecode_mips_dsp_r2.la -libwebpdsp_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) -noinst_HEADERS = ../dec/vp8_dec.h ../webp/decode.h -libwebpdsp_la_CPPFLAGS = $(AM_CPPFLAGS) $(USE_SWAP_16BIT_CSP) -libwebpdsp_la_LDFLAGS = -lm -libwebpdsp_la_LIBADD = libwebpdsp_sse2.la libwebpdsp_sse41.la \ - libwebpdsp_neon.la libwebpdsp_msa.la libwebpdsp_mips32.la \ - libwebpdsp_mips_dsp_r2.la -@BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_SOURCES = $(COMMON_SOURCES) -@BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) -@BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_LDFLAGS = $(libwebpdsp_la_LDFLAGS) -@BUILD_LIBWEBPDECODER_TRUE@libwebpdspdecode_la_LIBADD = \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_sse2.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_sse41.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_neon.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_msa.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_mips32.la \ -@BUILD_LIBWEBPDECODER_TRUE@ libwebpdspdecode_mips_dsp_r2.la -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/dsp/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/dsp/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libwebpdsp.la: $(libwebpdsp_la_OBJECTS) $(libwebpdsp_la_DEPENDENCIES) $(EXTRA_libwebpdsp_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_la_LINK) $(libwebpdsp_la_OBJECTS) $(libwebpdsp_la_LIBADD) $(LIBS) - -libwebpdsp_mips32.la: $(libwebpdsp_mips32_la_OBJECTS) $(libwebpdsp_mips32_la_DEPENDENCIES) $(EXTRA_libwebpdsp_mips32_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_mips32_la_LINK) $(libwebpdsp_mips32_la_OBJECTS) $(libwebpdsp_mips32_la_LIBADD) $(LIBS) - -libwebpdsp_mips_dsp_r2.la: $(libwebpdsp_mips_dsp_r2_la_OBJECTS) $(libwebpdsp_mips_dsp_r2_la_DEPENDENCIES) $(EXTRA_libwebpdsp_mips_dsp_r2_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_mips_dsp_r2_la_LINK) $(libwebpdsp_mips_dsp_r2_la_OBJECTS) $(libwebpdsp_mips_dsp_r2_la_LIBADD) $(LIBS) - -libwebpdsp_msa.la: $(libwebpdsp_msa_la_OBJECTS) $(libwebpdsp_msa_la_DEPENDENCIES) $(EXTRA_libwebpdsp_msa_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_msa_la_LINK) $(libwebpdsp_msa_la_OBJECTS) $(libwebpdsp_msa_la_LIBADD) $(LIBS) - -libwebpdsp_neon.la: $(libwebpdsp_neon_la_OBJECTS) $(libwebpdsp_neon_la_DEPENDENCIES) $(EXTRA_libwebpdsp_neon_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_neon_la_LINK) $(libwebpdsp_neon_la_OBJECTS) $(libwebpdsp_neon_la_LIBADD) $(LIBS) - -libwebpdsp_sse2.la: $(libwebpdsp_sse2_la_OBJECTS) $(libwebpdsp_sse2_la_DEPENDENCIES) $(EXTRA_libwebpdsp_sse2_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_sse2_la_LINK) $(libwebpdsp_sse2_la_OBJECTS) $(libwebpdsp_sse2_la_LIBADD) $(LIBS) - -libwebpdsp_sse41.la: $(libwebpdsp_sse41_la_OBJECTS) $(libwebpdsp_sse41_la_DEPENDENCIES) $(EXTRA_libwebpdsp_sse41_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdsp_sse41_la_LINK) $(libwebpdsp_sse41_la_OBJECTS) $(libwebpdsp_sse41_la_LIBADD) $(LIBS) - -libwebpdspdecode.la: $(libwebpdspdecode_la_OBJECTS) $(libwebpdspdecode_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_la_LINK) $(am_libwebpdspdecode_la_rpath) $(libwebpdspdecode_la_OBJECTS) $(libwebpdspdecode_la_LIBADD) $(LIBS) - -libwebpdspdecode_mips32.la: $(libwebpdspdecode_mips32_la_OBJECTS) $(libwebpdspdecode_mips32_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_mips32_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_mips32_la_LINK) $(libwebpdspdecode_mips32_la_OBJECTS) $(libwebpdspdecode_mips32_la_LIBADD) $(LIBS) - -libwebpdspdecode_mips_dsp_r2.la: $(libwebpdspdecode_mips_dsp_r2_la_OBJECTS) $(libwebpdspdecode_mips_dsp_r2_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_mips_dsp_r2_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_mips_dsp_r2_la_LINK) $(libwebpdspdecode_mips_dsp_r2_la_OBJECTS) $(libwebpdspdecode_mips_dsp_r2_la_LIBADD) $(LIBS) - -libwebpdspdecode_msa.la: $(libwebpdspdecode_msa_la_OBJECTS) $(libwebpdspdecode_msa_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_msa_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_msa_la_LINK) $(libwebpdspdecode_msa_la_OBJECTS) $(libwebpdspdecode_msa_la_LIBADD) $(LIBS) - -libwebpdspdecode_neon.la: $(libwebpdspdecode_neon_la_OBJECTS) $(libwebpdspdecode_neon_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_neon_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_neon_la_LINK) $(libwebpdspdecode_neon_la_OBJECTS) $(libwebpdspdecode_neon_la_LIBADD) $(LIBS) - -libwebpdspdecode_sse2.la: $(libwebpdspdecode_sse2_la_OBJECTS) $(libwebpdspdecode_sse2_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_sse2_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_sse2_la_LINK) $(libwebpdspdecode_sse2_la_OBJECTS) $(libwebpdspdecode_sse2_la_LIBADD) $(LIBS) - -libwebpdspdecode_sse41.la: $(libwebpdspdecode_sse41_la_OBJECTS) $(libwebpdspdecode_sse41_la_DEPENDENCIES) $(EXTRA_libwebpdspdecode_sse41_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpdspdecode_sse41_la_LINK) $(libwebpdspdecode_sse41_la_OBJECTS) $(libwebpdspdecode_sse41_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-alpha_processing.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-cost.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-cpu.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-dec_clip_tables.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-filters.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-lossless.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-lossless_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-rescaler.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-ssim.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-upsampling.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_la-yuv.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_msa_la-enc_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_neon_la-cost_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_neon_la-enc_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-alpha_processing.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-cpu.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-dec.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-filters.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-lossless.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-rescaler.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-upsampling.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_la-yuv.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libwebpdsp_la-alpha_processing.lo: alpha_processing.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-alpha_processing.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-alpha_processing.Tpo -c -o libwebpdsp_la-alpha_processing.lo `test -f 'alpha_processing.c' || echo '$(srcdir)/'`alpha_processing.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-alpha_processing.Tpo $(DEPDIR)/libwebpdsp_la-alpha_processing.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_processing.c' object='libwebpdsp_la-alpha_processing.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-alpha_processing.lo `test -f 'alpha_processing.c' || echo '$(srcdir)/'`alpha_processing.c - -libwebpdsp_la-cpu.lo: cpu.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-cpu.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-cpu.Tpo -c -o libwebpdsp_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-cpu.Tpo $(DEPDIR)/libwebpdsp_la-cpu.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpu.c' object='libwebpdsp_la-cpu.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c - -libwebpdsp_la-dec.lo: dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-dec.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-dec.Tpo -c -o libwebpdsp_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-dec.Tpo $(DEPDIR)/libwebpdsp_la-dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec.c' object='libwebpdsp_la-dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c - -libwebpdsp_la-dec_clip_tables.lo: dec_clip_tables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-dec_clip_tables.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-dec_clip_tables.Tpo -c -o libwebpdsp_la-dec_clip_tables.lo `test -f 'dec_clip_tables.c' || echo '$(srcdir)/'`dec_clip_tables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-dec_clip_tables.Tpo $(DEPDIR)/libwebpdsp_la-dec_clip_tables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_clip_tables.c' object='libwebpdsp_la-dec_clip_tables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-dec_clip_tables.lo `test -f 'dec_clip_tables.c' || echo '$(srcdir)/'`dec_clip_tables.c - -libwebpdsp_la-filters.lo: filters.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-filters.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-filters.Tpo -c -o libwebpdsp_la-filters.lo `test -f 'filters.c' || echo '$(srcdir)/'`filters.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-filters.Tpo $(DEPDIR)/libwebpdsp_la-filters.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters.c' object='libwebpdsp_la-filters.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-filters.lo `test -f 'filters.c' || echo '$(srcdir)/'`filters.c - -libwebpdsp_la-lossless.lo: lossless.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-lossless.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-lossless.Tpo -c -o libwebpdsp_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-lossless.Tpo $(DEPDIR)/libwebpdsp_la-lossless.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless.c' object='libwebpdsp_la-lossless.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c - -libwebpdsp_la-rescaler.lo: rescaler.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-rescaler.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-rescaler.Tpo -c -o libwebpdsp_la-rescaler.lo `test -f 'rescaler.c' || echo '$(srcdir)/'`rescaler.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-rescaler.Tpo $(DEPDIR)/libwebpdsp_la-rescaler.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler.c' object='libwebpdsp_la-rescaler.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-rescaler.lo `test -f 'rescaler.c' || echo '$(srcdir)/'`rescaler.c - -libwebpdsp_la-upsampling.lo: upsampling.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-upsampling.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-upsampling.Tpo -c -o libwebpdsp_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-upsampling.Tpo $(DEPDIR)/libwebpdsp_la-upsampling.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling.c' object='libwebpdsp_la-upsampling.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c - -libwebpdsp_la-yuv.lo: yuv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-yuv.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-yuv.Tpo -c -o libwebpdsp_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-yuv.Tpo $(DEPDIR)/libwebpdsp_la-yuv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv.c' object='libwebpdsp_la-yuv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c - -libwebpdsp_la-cost.lo: cost.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-cost.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-cost.Tpo -c -o libwebpdsp_la-cost.lo `test -f 'cost.c' || echo '$(srcdir)/'`cost.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-cost.Tpo $(DEPDIR)/libwebpdsp_la-cost.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost.c' object='libwebpdsp_la-cost.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-cost.lo `test -f 'cost.c' || echo '$(srcdir)/'`cost.c - -libwebpdsp_la-enc.lo: enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-enc.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-enc.Tpo -c -o libwebpdsp_la-enc.lo `test -f 'enc.c' || echo '$(srcdir)/'`enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-enc.Tpo $(DEPDIR)/libwebpdsp_la-enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc.c' object='libwebpdsp_la-enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-enc.lo `test -f 'enc.c' || echo '$(srcdir)/'`enc.c - -libwebpdsp_la-lossless_enc.lo: lossless_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-lossless_enc.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-lossless_enc.Tpo -c -o libwebpdsp_la-lossless_enc.lo `test -f 'lossless_enc.c' || echo '$(srcdir)/'`lossless_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-lossless_enc.Tpo $(DEPDIR)/libwebpdsp_la-lossless_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc.c' object='libwebpdsp_la-lossless_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-lossless_enc.lo `test -f 'lossless_enc.c' || echo '$(srcdir)/'`lossless_enc.c - -libwebpdsp_la-ssim.lo: ssim.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdsp_la-ssim.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_la-ssim.Tpo -c -o libwebpdsp_la-ssim.lo `test -f 'ssim.c' || echo '$(srcdir)/'`ssim.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_la-ssim.Tpo $(DEPDIR)/libwebpdsp_la-ssim.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssim.c' object='libwebpdsp_la-ssim.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdsp_la-ssim.lo `test -f 'ssim.c' || echo '$(srcdir)/'`ssim.c - -libwebpdsp_mips32_la-cost_mips32.lo: cost_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_mips32_la-cost_mips32.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Tpo -c -o libwebpdsp_mips32_la-cost_mips32.lo `test -f 'cost_mips32.c' || echo '$(srcdir)/'`cost_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Tpo $(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost_mips32.c' object='libwebpdsp_mips32_la-cost_mips32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_mips32_la-cost_mips32.lo `test -f 'cost_mips32.c' || echo '$(srcdir)/'`cost_mips32.c - -libwebpdsp_mips32_la-enc_mips32.lo: enc_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_mips32_la-enc_mips32.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Tpo -c -o libwebpdsp_mips32_la-enc_mips32.lo `test -f 'enc_mips32.c' || echo '$(srcdir)/'`enc_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Tpo $(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_mips32.c' object='libwebpdsp_mips32_la-enc_mips32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_mips32_la-enc_mips32.lo `test -f 'enc_mips32.c' || echo '$(srcdir)/'`enc_mips32.c - -libwebpdsp_mips32_la-lossless_enc_mips32.lo: lossless_enc_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_mips32_la-lossless_enc_mips32.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Tpo -c -o libwebpdsp_mips32_la-lossless_enc_mips32.lo `test -f 'lossless_enc_mips32.c' || echo '$(srcdir)/'`lossless_enc_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Tpo $(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc_mips32.c' object='libwebpdsp_mips32_la-lossless_enc_mips32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips32_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_mips32_la-lossless_enc_mips32.lo `test -f 'lossless_enc_mips32.c' || echo '$(srcdir)/'`lossless_enc_mips32.c - -libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.lo: cost_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Tpo -c -o libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.lo `test -f 'cost_mips_dsp_r2.c' || echo '$(srcdir)/'`cost_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost_mips_dsp_r2.c' object='libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.lo `test -f 'cost_mips_dsp_r2.c' || echo '$(srcdir)/'`cost_mips_dsp_r2.c - -libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.lo: enc_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Tpo -c -o libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.lo `test -f 'enc_mips_dsp_r2.c' || echo '$(srcdir)/'`enc_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_mips_dsp_r2.c' object='libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.lo `test -f 'enc_mips_dsp_r2.c' || echo '$(srcdir)/'`enc_mips_dsp_r2.c - -libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.lo: lossless_enc_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Tpo -c -o libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.lo `test -f 'lossless_enc_mips_dsp_r2.c' || echo '$(srcdir)/'`lossless_enc_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc_mips_dsp_r2.c' object='libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.lo `test -f 'lossless_enc_mips_dsp_r2.c' || echo '$(srcdir)/'`lossless_enc_mips_dsp_r2.c - -libwebpdsp_msa_la-enc_msa.lo: enc_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_msa_la-enc_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_msa_la-enc_msa.Tpo -c -o libwebpdsp_msa_la-enc_msa.lo `test -f 'enc_msa.c' || echo '$(srcdir)/'`enc_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_msa_la-enc_msa.Tpo $(DEPDIR)/libwebpdsp_msa_la-enc_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_msa.c' object='libwebpdsp_msa_la-enc_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_msa_la-enc_msa.lo `test -f 'enc_msa.c' || echo '$(srcdir)/'`enc_msa.c - -libwebpdsp_msa_la-lossless_enc_msa.lo: lossless_enc_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_msa_la-lossless_enc_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Tpo -c -o libwebpdsp_msa_la-lossless_enc_msa.lo `test -f 'lossless_enc_msa.c' || echo '$(srcdir)/'`lossless_enc_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Tpo $(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc_msa.c' object='libwebpdsp_msa_la-lossless_enc_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_msa_la-lossless_enc_msa.lo `test -f 'lossless_enc_msa.c' || echo '$(srcdir)/'`lossless_enc_msa.c - -libwebpdsp_neon_la-cost_neon.lo: cost_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_neon_la-cost_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_neon_la-cost_neon.Tpo -c -o libwebpdsp_neon_la-cost_neon.lo `test -f 'cost_neon.c' || echo '$(srcdir)/'`cost_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_neon_la-cost_neon.Tpo $(DEPDIR)/libwebpdsp_neon_la-cost_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost_neon.c' object='libwebpdsp_neon_la-cost_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_neon_la-cost_neon.lo `test -f 'cost_neon.c' || echo '$(srcdir)/'`cost_neon.c - -libwebpdsp_neon_la-enc_neon.lo: enc_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_neon_la-enc_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_neon_la-enc_neon.Tpo -c -o libwebpdsp_neon_la-enc_neon.lo `test -f 'enc_neon.c' || echo '$(srcdir)/'`enc_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_neon_la-enc_neon.Tpo $(DEPDIR)/libwebpdsp_neon_la-enc_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_neon.c' object='libwebpdsp_neon_la-enc_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_neon_la-enc_neon.lo `test -f 'enc_neon.c' || echo '$(srcdir)/'`enc_neon.c - -libwebpdsp_neon_la-lossless_enc_neon.lo: lossless_enc_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_neon_la-lossless_enc_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Tpo -c -o libwebpdsp_neon_la-lossless_enc_neon.lo `test -f 'lossless_enc_neon.c' || echo '$(srcdir)/'`lossless_enc_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Tpo $(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc_neon.c' object='libwebpdsp_neon_la-lossless_enc_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_neon_la-lossless_enc_neon.lo `test -f 'lossless_enc_neon.c' || echo '$(srcdir)/'`lossless_enc_neon.c - -libwebpdsp_sse2_la-cost_sse2.lo: cost_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_sse2_la-cost_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Tpo -c -o libwebpdsp_sse2_la-cost_sse2.lo `test -f 'cost_sse2.c' || echo '$(srcdir)/'`cost_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Tpo $(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost_sse2.c' object='libwebpdsp_sse2_la-cost_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_sse2_la-cost_sse2.lo `test -f 'cost_sse2.c' || echo '$(srcdir)/'`cost_sse2.c - -libwebpdsp_sse2_la-enc_sse2.lo: enc_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_sse2_la-enc_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Tpo -c -o libwebpdsp_sse2_la-enc_sse2.lo `test -f 'enc_sse2.c' || echo '$(srcdir)/'`enc_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Tpo $(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_sse2.c' object='libwebpdsp_sse2_la-enc_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_sse2_la-enc_sse2.lo `test -f 'enc_sse2.c' || echo '$(srcdir)/'`enc_sse2.c - -libwebpdsp_sse2_la-lossless_enc_sse2.lo: lossless_enc_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_sse2_la-lossless_enc_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Tpo -c -o libwebpdsp_sse2_la-lossless_enc_sse2.lo `test -f 'lossless_enc_sse2.c' || echo '$(srcdir)/'`lossless_enc_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Tpo $(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc_sse2.c' object='libwebpdsp_sse2_la-lossless_enc_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_sse2_la-lossless_enc_sse2.lo `test -f 'lossless_enc_sse2.c' || echo '$(srcdir)/'`lossless_enc_sse2.c - -libwebpdsp_sse2_la-ssim_sse2.lo: ssim_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_sse2_la-ssim_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Tpo -c -o libwebpdsp_sse2_la-ssim_sse2.lo `test -f 'ssim_sse2.c' || echo '$(srcdir)/'`ssim_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Tpo $(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssim_sse2.c' object='libwebpdsp_sse2_la-ssim_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_sse2_la-ssim_sse2.lo `test -f 'ssim_sse2.c' || echo '$(srcdir)/'`ssim_sse2.c - -libwebpdsp_sse41_la-enc_sse41.lo: enc_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_sse41_la-enc_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Tpo -c -o libwebpdsp_sse41_la-enc_sse41.lo `test -f 'enc_sse41.c' || echo '$(srcdir)/'`enc_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Tpo $(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='enc_sse41.c' object='libwebpdsp_sse41_la-enc_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_sse41_la-enc_sse41.lo `test -f 'enc_sse41.c' || echo '$(srcdir)/'`enc_sse41.c - -libwebpdsp_sse41_la-lossless_enc_sse41.lo: lossless_enc_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdsp_sse41_la-lossless_enc_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Tpo -c -o libwebpdsp_sse41_la-lossless_enc_sse41.lo `test -f 'lossless_enc_sse41.c' || echo '$(srcdir)/'`lossless_enc_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Tpo $(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_enc_sse41.c' object='libwebpdsp_sse41_la-lossless_enc_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdsp_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdsp_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdsp_sse41_la-lossless_enc_sse41.lo `test -f 'lossless_enc_sse41.c' || echo '$(srcdir)/'`lossless_enc_sse41.c - -libwebpdspdecode_la-alpha_processing.lo: alpha_processing.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-alpha_processing.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-alpha_processing.Tpo -c -o libwebpdspdecode_la-alpha_processing.lo `test -f 'alpha_processing.c' || echo '$(srcdir)/'`alpha_processing.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-alpha_processing.Tpo $(DEPDIR)/libwebpdspdecode_la-alpha_processing.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_processing.c' object='libwebpdspdecode_la-alpha_processing.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-alpha_processing.lo `test -f 'alpha_processing.c' || echo '$(srcdir)/'`alpha_processing.c - -libwebpdspdecode_la-cpu.lo: cpu.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-cpu.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-cpu.Tpo -c -o libwebpdspdecode_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-cpu.Tpo $(DEPDIR)/libwebpdspdecode_la-cpu.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpu.c' object='libwebpdspdecode_la-cpu.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-cpu.lo `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c - -libwebpdspdecode_la-dec.lo: dec.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-dec.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-dec.Tpo -c -o libwebpdspdecode_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-dec.Tpo $(DEPDIR)/libwebpdspdecode_la-dec.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec.c' object='libwebpdspdecode_la-dec.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-dec.lo `test -f 'dec.c' || echo '$(srcdir)/'`dec.c - -libwebpdspdecode_la-dec_clip_tables.lo: dec_clip_tables.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-dec_clip_tables.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Tpo -c -o libwebpdspdecode_la-dec_clip_tables.lo `test -f 'dec_clip_tables.c' || echo '$(srcdir)/'`dec_clip_tables.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Tpo $(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_clip_tables.c' object='libwebpdspdecode_la-dec_clip_tables.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-dec_clip_tables.lo `test -f 'dec_clip_tables.c' || echo '$(srcdir)/'`dec_clip_tables.c - -libwebpdspdecode_la-filters.lo: filters.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-filters.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-filters.Tpo -c -o libwebpdspdecode_la-filters.lo `test -f 'filters.c' || echo '$(srcdir)/'`filters.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-filters.Tpo $(DEPDIR)/libwebpdspdecode_la-filters.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters.c' object='libwebpdspdecode_la-filters.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-filters.lo `test -f 'filters.c' || echo '$(srcdir)/'`filters.c - -libwebpdspdecode_la-lossless.lo: lossless.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-lossless.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-lossless.Tpo -c -o libwebpdspdecode_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-lossless.Tpo $(DEPDIR)/libwebpdspdecode_la-lossless.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless.c' object='libwebpdspdecode_la-lossless.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-lossless.lo `test -f 'lossless.c' || echo '$(srcdir)/'`lossless.c - -libwebpdspdecode_la-rescaler.lo: rescaler.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-rescaler.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-rescaler.Tpo -c -o libwebpdspdecode_la-rescaler.lo `test -f 'rescaler.c' || echo '$(srcdir)/'`rescaler.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-rescaler.Tpo $(DEPDIR)/libwebpdspdecode_la-rescaler.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler.c' object='libwebpdspdecode_la-rescaler.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-rescaler.lo `test -f 'rescaler.c' || echo '$(srcdir)/'`rescaler.c - -libwebpdspdecode_la-upsampling.lo: upsampling.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-upsampling.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-upsampling.Tpo -c -o libwebpdspdecode_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-upsampling.Tpo $(DEPDIR)/libwebpdspdecode_la-upsampling.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling.c' object='libwebpdspdecode_la-upsampling.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-upsampling.lo `test -f 'upsampling.c' || echo '$(srcdir)/'`upsampling.c - -libwebpdspdecode_la-yuv.lo: yuv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_la-yuv.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_la-yuv.Tpo -c -o libwebpdspdecode_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_la-yuv.Tpo $(DEPDIR)/libwebpdspdecode_la-yuv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv.c' object='libwebpdspdecode_la-yuv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_la-yuv.lo `test -f 'yuv.c' || echo '$(srcdir)/'`yuv.c - -libwebpdspdecode_mips32_la-dec_mips32.lo: dec_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips32_la-dec_mips32.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Tpo -c -o libwebpdspdecode_mips32_la-dec_mips32.lo `test -f 'dec_mips32.c' || echo '$(srcdir)/'`dec_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Tpo $(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_mips32.c' object='libwebpdspdecode_mips32_la-dec_mips32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips32_la-dec_mips32.lo `test -f 'dec_mips32.c' || echo '$(srcdir)/'`dec_mips32.c - -libwebpdspdecode_mips32_la-rescaler_mips32.lo: rescaler_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips32_la-rescaler_mips32.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Tpo -c -o libwebpdspdecode_mips32_la-rescaler_mips32.lo `test -f 'rescaler_mips32.c' || echo '$(srcdir)/'`rescaler_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Tpo $(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler_mips32.c' object='libwebpdspdecode_mips32_la-rescaler_mips32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips32_la-rescaler_mips32.lo `test -f 'rescaler_mips32.c' || echo '$(srcdir)/'`rescaler_mips32.c - -libwebpdspdecode_mips32_la-yuv_mips32.lo: yuv_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips32_la-yuv_mips32.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Tpo -c -o libwebpdspdecode_mips32_la-yuv_mips32.lo `test -f 'yuv_mips32.c' || echo '$(srcdir)/'`yuv_mips32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Tpo $(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv_mips32.c' object='libwebpdspdecode_mips32_la-yuv_mips32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips32_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips32_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips32_la-yuv_mips32.lo `test -f 'yuv_mips32.c' || echo '$(srcdir)/'`yuv_mips32.c - -libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.lo: alpha_processing_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.lo `test -f 'alpha_processing_mips_dsp_r2.c' || echo '$(srcdir)/'`alpha_processing_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_processing_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.lo `test -f 'alpha_processing_mips_dsp_r2.c' || echo '$(srcdir)/'`alpha_processing_mips_dsp_r2.c - -libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.lo: dec_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.lo `test -f 'dec_mips_dsp_r2.c' || echo '$(srcdir)/'`dec_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.lo `test -f 'dec_mips_dsp_r2.c' || echo '$(srcdir)/'`dec_mips_dsp_r2.c - -libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.lo: filters_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.lo `test -f 'filters_mips_dsp_r2.c' || echo '$(srcdir)/'`filters_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.lo `test -f 'filters_mips_dsp_r2.c' || echo '$(srcdir)/'`filters_mips_dsp_r2.c - -libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.lo: lossless_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.lo `test -f 'lossless_mips_dsp_r2.c' || echo '$(srcdir)/'`lossless_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.lo `test -f 'lossless_mips_dsp_r2.c' || echo '$(srcdir)/'`lossless_mips_dsp_r2.c - -libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.lo: rescaler_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.lo `test -f 'rescaler_mips_dsp_r2.c' || echo '$(srcdir)/'`rescaler_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.lo `test -f 'rescaler_mips_dsp_r2.c' || echo '$(srcdir)/'`rescaler_mips_dsp_r2.c - -libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.lo: upsampling_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.lo `test -f 'upsampling_mips_dsp_r2.c' || echo '$(srcdir)/'`upsampling_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.lo `test -f 'upsampling_mips_dsp_r2.c' || echo '$(srcdir)/'`upsampling_mips_dsp_r2.c - -libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.lo: yuv_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Tpo -c -o libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.lo `test -f 'yuv_mips_dsp_r2.c' || echo '$(srcdir)/'`yuv_mips_dsp_r2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Tpo $(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv_mips_dsp_r2.c' object='libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_mips_dsp_r2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.lo `test -f 'yuv_mips_dsp_r2.c' || echo '$(srcdir)/'`yuv_mips_dsp_r2.c - -libwebpdspdecode_msa_la-dec_msa.lo: dec_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_msa_la-dec_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Tpo -c -o libwebpdspdecode_msa_la-dec_msa.lo `test -f 'dec_msa.c' || echo '$(srcdir)/'`dec_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Tpo $(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_msa.c' object='libwebpdspdecode_msa_la-dec_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_msa_la-dec_msa.lo `test -f 'dec_msa.c' || echo '$(srcdir)/'`dec_msa.c - -libwebpdspdecode_msa_la-filters_msa.lo: filters_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_msa_la-filters_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Tpo -c -o libwebpdspdecode_msa_la-filters_msa.lo `test -f 'filters_msa.c' || echo '$(srcdir)/'`filters_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Tpo $(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters_msa.c' object='libwebpdspdecode_msa_la-filters_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_msa_la-filters_msa.lo `test -f 'filters_msa.c' || echo '$(srcdir)/'`filters_msa.c - -libwebpdspdecode_msa_la-lossless_msa.lo: lossless_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_msa_la-lossless_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Tpo -c -o libwebpdspdecode_msa_la-lossless_msa.lo `test -f 'lossless_msa.c' || echo '$(srcdir)/'`lossless_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Tpo $(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_msa.c' object='libwebpdspdecode_msa_la-lossless_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_msa_la-lossless_msa.lo `test -f 'lossless_msa.c' || echo '$(srcdir)/'`lossless_msa.c - -libwebpdspdecode_msa_la-rescaler_msa.lo: rescaler_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_msa_la-rescaler_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Tpo -c -o libwebpdspdecode_msa_la-rescaler_msa.lo `test -f 'rescaler_msa.c' || echo '$(srcdir)/'`rescaler_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Tpo $(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler_msa.c' object='libwebpdspdecode_msa_la-rescaler_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_msa_la-rescaler_msa.lo `test -f 'rescaler_msa.c' || echo '$(srcdir)/'`rescaler_msa.c - -libwebpdspdecode_msa_la-upsampling_msa.lo: upsampling_msa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_msa_la-upsampling_msa.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Tpo -c -o libwebpdspdecode_msa_la-upsampling_msa.lo `test -f 'upsampling_msa.c' || echo '$(srcdir)/'`upsampling_msa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Tpo $(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_msa.c' object='libwebpdspdecode_msa_la-upsampling_msa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_msa_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_msa_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_msa_la-upsampling_msa.lo `test -f 'upsampling_msa.c' || echo '$(srcdir)/'`upsampling_msa.c - -libwebpdspdecode_neon_la-alpha_processing_neon.lo: alpha_processing_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-alpha_processing_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Tpo -c -o libwebpdspdecode_neon_la-alpha_processing_neon.lo `test -f 'alpha_processing_neon.c' || echo '$(srcdir)/'`alpha_processing_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_processing_neon.c' object='libwebpdspdecode_neon_la-alpha_processing_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-alpha_processing_neon.lo `test -f 'alpha_processing_neon.c' || echo '$(srcdir)/'`alpha_processing_neon.c - -libwebpdspdecode_neon_la-dec_neon.lo: dec_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-dec_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Tpo -c -o libwebpdspdecode_neon_la-dec_neon.lo `test -f 'dec_neon.c' || echo '$(srcdir)/'`dec_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_neon.c' object='libwebpdspdecode_neon_la-dec_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-dec_neon.lo `test -f 'dec_neon.c' || echo '$(srcdir)/'`dec_neon.c - -libwebpdspdecode_neon_la-filters_neon.lo: filters_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-filters_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Tpo -c -o libwebpdspdecode_neon_la-filters_neon.lo `test -f 'filters_neon.c' || echo '$(srcdir)/'`filters_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters_neon.c' object='libwebpdspdecode_neon_la-filters_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-filters_neon.lo `test -f 'filters_neon.c' || echo '$(srcdir)/'`filters_neon.c - -libwebpdspdecode_neon_la-lossless_neon.lo: lossless_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-lossless_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Tpo -c -o libwebpdspdecode_neon_la-lossless_neon.lo `test -f 'lossless_neon.c' || echo '$(srcdir)/'`lossless_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_neon.c' object='libwebpdspdecode_neon_la-lossless_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-lossless_neon.lo `test -f 'lossless_neon.c' || echo '$(srcdir)/'`lossless_neon.c - -libwebpdspdecode_neon_la-rescaler_neon.lo: rescaler_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-rescaler_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Tpo -c -o libwebpdspdecode_neon_la-rescaler_neon.lo `test -f 'rescaler_neon.c' || echo '$(srcdir)/'`rescaler_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler_neon.c' object='libwebpdspdecode_neon_la-rescaler_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-rescaler_neon.lo `test -f 'rescaler_neon.c' || echo '$(srcdir)/'`rescaler_neon.c - -libwebpdspdecode_neon_la-upsampling_neon.lo: upsampling_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-upsampling_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Tpo -c -o libwebpdspdecode_neon_la-upsampling_neon.lo `test -f 'upsampling_neon.c' || echo '$(srcdir)/'`upsampling_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_neon.c' object='libwebpdspdecode_neon_la-upsampling_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-upsampling_neon.lo `test -f 'upsampling_neon.c' || echo '$(srcdir)/'`upsampling_neon.c - -libwebpdspdecode_neon_la-yuv_neon.lo: yuv_neon.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_neon_la-yuv_neon.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Tpo -c -o libwebpdspdecode_neon_la-yuv_neon.lo `test -f 'yuv_neon.c' || echo '$(srcdir)/'`yuv_neon.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Tpo $(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv_neon.c' object='libwebpdspdecode_neon_la-yuv_neon.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_neon_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_neon_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_neon_la-yuv_neon.lo `test -f 'yuv_neon.c' || echo '$(srcdir)/'`yuv_neon.c - -libwebpdspdecode_sse2_la-alpha_processing_sse2.lo: alpha_processing_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-alpha_processing_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Tpo -c -o libwebpdspdecode_sse2_la-alpha_processing_sse2.lo `test -f 'alpha_processing_sse2.c' || echo '$(srcdir)/'`alpha_processing_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_processing_sse2.c' object='libwebpdspdecode_sse2_la-alpha_processing_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-alpha_processing_sse2.lo `test -f 'alpha_processing_sse2.c' || echo '$(srcdir)/'`alpha_processing_sse2.c - -libwebpdspdecode_sse2_la-dec_sse2.lo: dec_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-dec_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Tpo -c -o libwebpdspdecode_sse2_la-dec_sse2.lo `test -f 'dec_sse2.c' || echo '$(srcdir)/'`dec_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_sse2.c' object='libwebpdspdecode_sse2_la-dec_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-dec_sse2.lo `test -f 'dec_sse2.c' || echo '$(srcdir)/'`dec_sse2.c - -libwebpdspdecode_sse2_la-filters_sse2.lo: filters_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-filters_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Tpo -c -o libwebpdspdecode_sse2_la-filters_sse2.lo `test -f 'filters_sse2.c' || echo '$(srcdir)/'`filters_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filters_sse2.c' object='libwebpdspdecode_sse2_la-filters_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-filters_sse2.lo `test -f 'filters_sse2.c' || echo '$(srcdir)/'`filters_sse2.c - -libwebpdspdecode_sse2_la-lossless_sse2.lo: lossless_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-lossless_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Tpo -c -o libwebpdspdecode_sse2_la-lossless_sse2.lo `test -f 'lossless_sse2.c' || echo '$(srcdir)/'`lossless_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_sse2.c' object='libwebpdspdecode_sse2_la-lossless_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-lossless_sse2.lo `test -f 'lossless_sse2.c' || echo '$(srcdir)/'`lossless_sse2.c - -libwebpdspdecode_sse2_la-rescaler_sse2.lo: rescaler_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-rescaler_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Tpo -c -o libwebpdspdecode_sse2_la-rescaler_sse2.lo `test -f 'rescaler_sse2.c' || echo '$(srcdir)/'`rescaler_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rescaler_sse2.c' object='libwebpdspdecode_sse2_la-rescaler_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-rescaler_sse2.lo `test -f 'rescaler_sse2.c' || echo '$(srcdir)/'`rescaler_sse2.c - -libwebpdspdecode_sse2_la-upsampling_sse2.lo: upsampling_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-upsampling_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Tpo -c -o libwebpdspdecode_sse2_la-upsampling_sse2.lo `test -f 'upsampling_sse2.c' || echo '$(srcdir)/'`upsampling_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_sse2.c' object='libwebpdspdecode_sse2_la-upsampling_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-upsampling_sse2.lo `test -f 'upsampling_sse2.c' || echo '$(srcdir)/'`upsampling_sse2.c - -libwebpdspdecode_sse2_la-yuv_sse2.lo: yuv_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse2_la-yuv_sse2.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Tpo -c -o libwebpdspdecode_sse2_la-yuv_sse2.lo `test -f 'yuv_sse2.c' || echo '$(srcdir)/'`yuv_sse2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Tpo $(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv_sse2.c' object='libwebpdspdecode_sse2_la-yuv_sse2.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse2_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse2_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse2_la-yuv_sse2.lo `test -f 'yuv_sse2.c' || echo '$(srcdir)/'`yuv_sse2.c - -libwebpdspdecode_sse41_la-alpha_processing_sse41.lo: alpha_processing_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse41_la-alpha_processing_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Tpo -c -o libwebpdspdecode_sse41_la-alpha_processing_sse41.lo `test -f 'alpha_processing_sse41.c' || echo '$(srcdir)/'`alpha_processing_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Tpo $(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_processing_sse41.c' object='libwebpdspdecode_sse41_la-alpha_processing_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse41_la-alpha_processing_sse41.lo `test -f 'alpha_processing_sse41.c' || echo '$(srcdir)/'`alpha_processing_sse41.c - -libwebpdspdecode_sse41_la-dec_sse41.lo: dec_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse41_la-dec_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Tpo -c -o libwebpdspdecode_sse41_la-dec_sse41.lo `test -f 'dec_sse41.c' || echo '$(srcdir)/'`dec_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Tpo $(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dec_sse41.c' object='libwebpdspdecode_sse41_la-dec_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse41_la-dec_sse41.lo `test -f 'dec_sse41.c' || echo '$(srcdir)/'`dec_sse41.c - -libwebpdspdecode_sse41_la-lossless_sse41.lo: lossless_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse41_la-lossless_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Tpo -c -o libwebpdspdecode_sse41_la-lossless_sse41.lo `test -f 'lossless_sse41.c' || echo '$(srcdir)/'`lossless_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Tpo $(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lossless_sse41.c' object='libwebpdspdecode_sse41_la-lossless_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse41_la-lossless_sse41.lo `test -f 'lossless_sse41.c' || echo '$(srcdir)/'`lossless_sse41.c - -libwebpdspdecode_sse41_la-upsampling_sse41.lo: upsampling_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse41_la-upsampling_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Tpo -c -o libwebpdspdecode_sse41_la-upsampling_sse41.lo `test -f 'upsampling_sse41.c' || echo '$(srcdir)/'`upsampling_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Tpo $(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='upsampling_sse41.c' object='libwebpdspdecode_sse41_la-upsampling_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse41_la-upsampling_sse41.lo `test -f 'upsampling_sse41.c' || echo '$(srcdir)/'`upsampling_sse41.c - -libwebpdspdecode_sse41_la-yuv_sse41.lo: yuv_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -MT libwebpdspdecode_sse41_la-yuv_sse41.lo -MD -MP -MF $(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Tpo -c -o libwebpdspdecode_sse41_la-yuv_sse41.lo `test -f 'yuv_sse41.c' || echo '$(srcdir)/'`yuv_sse41.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Tpo $(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='yuv_sse41.c' object='libwebpdspdecode_sse41_la-yuv_sse41.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpdspdecode_sse41_la_CPPFLAGS) $(CPPFLAGS) $(libwebpdspdecode_sse41_la_CFLAGS) $(CFLAGS) -c -o libwebpdspdecode_sse41_la-yuv_sse41.lo `test -f 'yuv_sse41.c' || echo '$(srcdir)/'`yuv_sse41.c - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-commonHEADERS: $(common_HEADERS) - @$(NORMAL_INSTALL) - @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(commondir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(commondir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(commondir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(commondir)" || exit $$?; \ - done - -uninstall-commonHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(commondir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(commondir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/libwebpdsp_la-alpha_processing.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-cost.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-cpu.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-dec.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-dec_clip_tables.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-enc.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-filters.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-lossless.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-lossless_enc.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-rescaler.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-ssim.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-upsampling.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-yuv.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_msa_la-enc_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_neon_la-cost_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_neon_la-enc_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-alpha_processing.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-cpu.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-dec.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-filters.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-lossless.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-rescaler.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-upsampling.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-yuv.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-commonHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libwebpdsp_la-alpha_processing.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-cost.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-cpu.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-dec.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-dec_clip_tables.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-enc.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-filters.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-lossless.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-lossless_enc.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-rescaler.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-ssim.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-upsampling.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_la-yuv.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips32_la-cost_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips32_la-enc_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips32_la-lossless_enc_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-cost_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-enc_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_mips_dsp_r2_la-lossless_enc_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_msa_la-enc_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_msa_la-lossless_enc_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_neon_la-cost_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_neon_la-enc_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_neon_la-lossless_enc_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-cost_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-enc_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-lossless_enc_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse2_la-ssim_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse41_la-enc_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdsp_sse41_la-lossless_enc_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-alpha_processing.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-cpu.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-dec.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-dec_clip_tables.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-filters.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-lossless.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-rescaler.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-upsampling.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_la-yuv.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips32_la-dec_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips32_la-rescaler_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips32_la-yuv_mips32.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-alpha_processing_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-dec_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-filters_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-lossless_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-rescaler_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-upsampling_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_mips_dsp_r2_la-yuv_mips_dsp_r2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-dec_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-filters_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-lossless_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-rescaler_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_msa_la-upsampling_msa.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-alpha_processing_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-dec_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-filters_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-lossless_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-rescaler_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-upsampling_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_neon_la-yuv_neon.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-alpha_processing_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-dec_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-filters_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-lossless_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-rescaler_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-upsampling_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse2_la-yuv_sse2.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-alpha_processing_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-dec_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-lossless_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-upsampling_sse41.Plo - -rm -f ./$(DEPDIR)/libwebpdspdecode_sse41_la-yuv_sse41.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-commonHEADERS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstLTLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-commonHEADERS install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-commonHEADERS - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libwebp/upstream/src/enc/Makefile.am b/thirdparty/libwebp/upstream/src/enc/Makefile.am deleted file mode 100644 index 2fec804cb..000000000 --- a/thirdparty/libwebp/upstream/src/enc/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) -noinst_LTLIBRARIES = libwebpencode.la - -libwebpencode_la_SOURCES = -libwebpencode_la_SOURCES += alpha_enc.c -libwebpencode_la_SOURCES += analysis_enc.c -libwebpencode_la_SOURCES += backward_references_cost_enc.c -libwebpencode_la_SOURCES += backward_references_enc.c -libwebpencode_la_SOURCES += backward_references_enc.h -libwebpencode_la_SOURCES += config_enc.c -libwebpencode_la_SOURCES += cost_enc.c -libwebpencode_la_SOURCES += cost_enc.h -libwebpencode_la_SOURCES += filter_enc.c -libwebpencode_la_SOURCES += frame_enc.c -libwebpencode_la_SOURCES += histogram_enc.c -libwebpencode_la_SOURCES += histogram_enc.h -libwebpencode_la_SOURCES += iterator_enc.c -libwebpencode_la_SOURCES += near_lossless_enc.c -libwebpencode_la_SOURCES += picture_enc.c -libwebpencode_la_SOURCES += picture_csp_enc.c -libwebpencode_la_SOURCES += picture_psnr_enc.c -libwebpencode_la_SOURCES += picture_rescale_enc.c -libwebpencode_la_SOURCES += picture_tools_enc.c -libwebpencode_la_SOURCES += predictor_enc.c -libwebpencode_la_SOURCES += quant_enc.c -libwebpencode_la_SOURCES += syntax_enc.c -libwebpencode_la_SOURCES += token_enc.c -libwebpencode_la_SOURCES += tree_enc.c -libwebpencode_la_SOURCES += vp8i_enc.h -libwebpencode_la_SOURCES += vp8l_enc.c -libwebpencode_la_SOURCES += vp8li_enc.h -libwebpencode_la_SOURCES += webp_enc.c - -libwebpencodeinclude_HEADERS = -libwebpencodeinclude_HEADERS += ../webp/encode.h -libwebpencodeinclude_HEADERS += ../webp/types.h -noinst_HEADERS = -noinst_HEADERS += ../webp/format_constants.h - -libwebpencode_la_LIBADD = ../../sharpyuv/libsharpyuv.la -libwebpencode_la_LDFLAGS = -lm -libwebpencode_la_CPPFLAGS = $(AM_CPPFLAGS) -libwebpencodeincludedir = $(includedir)/webp diff --git a/thirdparty/libwebp/upstream/src/enc/Makefile.in b/thirdparty/libwebp/upstream/src/enc/Makefile.in deleted file mode 100644 index 5198a3ed8..000000000 --- a/thirdparty/libwebp/upstream/src/enc/Makefile.in +++ /dev/null @@ -1,963 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/enc -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(libwebpencodeinclude_HEADERS) \ - $(noinst_HEADERS) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/webp/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libwebpencode_la_DEPENDENCIES = ../../sharpyuv/libsharpyuv.la -am_libwebpencode_la_OBJECTS = libwebpencode_la-alpha_enc.lo \ - libwebpencode_la-analysis_enc.lo \ - libwebpencode_la-backward_references_cost_enc.lo \ - libwebpencode_la-backward_references_enc.lo \ - libwebpencode_la-config_enc.lo libwebpencode_la-cost_enc.lo \ - libwebpencode_la-filter_enc.lo libwebpencode_la-frame_enc.lo \ - libwebpencode_la-histogram_enc.lo \ - libwebpencode_la-iterator_enc.lo \ - libwebpencode_la-near_lossless_enc.lo \ - libwebpencode_la-picture_enc.lo \ - libwebpencode_la-picture_csp_enc.lo \ - libwebpencode_la-picture_psnr_enc.lo \ - libwebpencode_la-picture_rescale_enc.lo \ - libwebpencode_la-picture_tools_enc.lo \ - libwebpencode_la-predictor_enc.lo \ - libwebpencode_la-quant_enc.lo libwebpencode_la-syntax_enc.lo \ - libwebpencode_la-token_enc.lo libwebpencode_la-tree_enc.lo \ - libwebpencode_la-vp8l_enc.lo libwebpencode_la-webp_enc.lo -libwebpencode_la_OBJECTS = $(am_libwebpencode_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libwebpencode_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libwebpencode_la_LDFLAGS) $(LDFLAGS) \ - -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/webp -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/libwebpencode_la-alpha_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-analysis_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-backward_references_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-config_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-cost_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-filter_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-frame_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-histogram_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-iterator_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-near_lossless_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-picture_csp_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-picture_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-picture_psnr_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-picture_rescale_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-picture_tools_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-predictor_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-quant_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-syntax_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-token_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-tree_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-vp8l_enc.Plo \ - ./$(DEPDIR)/libwebpencode_la-webp_enc.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libwebpencode_la_SOURCES) -DIST_SOURCES = $(libwebpencode_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libwebpencodeincludedir)" -HEADERS = $(libwebpencodeinclude_HEADERS) $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_builddir) -I$(top_srcdir) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GIF_INCLUDES = @GIF_INCLUDES@ -GIF_LIBS = @GIF_LIBS@ -GL_INCLUDES = @GL_INCLUDES@ -GL_LIBS = @GL_LIBS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JPEG_INCLUDES = @JPEG_INCLUDES@ -JPEG_LIBS = @JPEG_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBPNG_CONFIG = @LIBPNG_CONFIG@ -LIBS = @LIBS@ -LIBSDL_CONFIG = @LIBSDL_CONFIG@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NEON_FLAGS = @NEON_FLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PNG_INCLUDES = @PNG_INCLUDES@ -PNG_LIBS = @PNG_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_INCLUDES = @SDL_INCLUDES@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE2_FLAGS = @SSE2_FLAGS@ -SSE41_FLAGS = @SSE41_FLAGS@ -STRIP = @STRIP@ -TIFF_INCLUDES = @TIFF_INCLUDES@ -TIFF_LIBS = @TIFF_LIBS@ -USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgconfigdir = @pkgconfigdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -webp_libname_prefix = @webp_libname_prefix@ -noinst_LTLIBRARIES = libwebpencode.la -libwebpencode_la_SOURCES = alpha_enc.c analysis_enc.c \ - backward_references_cost_enc.c backward_references_enc.c \ - backward_references_enc.h config_enc.c cost_enc.c cost_enc.h \ - filter_enc.c frame_enc.c histogram_enc.c histogram_enc.h \ - iterator_enc.c near_lossless_enc.c picture_enc.c \ - picture_csp_enc.c picture_psnr_enc.c picture_rescale_enc.c \ - picture_tools_enc.c predictor_enc.c quant_enc.c syntax_enc.c \ - token_enc.c tree_enc.c vp8i_enc.h vp8l_enc.c vp8li_enc.h \ - webp_enc.c -libwebpencodeinclude_HEADERS = ../webp/encode.h ../webp/types.h -noinst_HEADERS = ../webp/format_constants.h -libwebpencode_la_LIBADD = ../../sharpyuv/libsharpyuv.la -libwebpencode_la_LDFLAGS = -lm -libwebpencode_la_CPPFLAGS = $(AM_CPPFLAGS) -libwebpencodeincludedir = $(includedir)/webp -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/enc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/enc/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libwebpencode.la: $(libwebpencode_la_OBJECTS) $(libwebpencode_la_DEPENDENCIES) $(EXTRA_libwebpencode_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpencode_la_LINK) $(libwebpencode_la_OBJECTS) $(libwebpencode_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-alpha_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-analysis_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-backward_references_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-config_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-cost_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-filter_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-frame_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-histogram_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-iterator_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-near_lossless_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-picture_csp_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-picture_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-picture_psnr_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-picture_rescale_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-picture_tools_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-predictor_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-quant_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-syntax_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-token_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-tree_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-vp8l_enc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebpencode_la-webp_enc.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libwebpencode_la-alpha_enc.lo: alpha_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-alpha_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-alpha_enc.Tpo -c -o libwebpencode_la-alpha_enc.lo `test -f 'alpha_enc.c' || echo '$(srcdir)/'`alpha_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-alpha_enc.Tpo $(DEPDIR)/libwebpencode_la-alpha_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='alpha_enc.c' object='libwebpencode_la-alpha_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-alpha_enc.lo `test -f 'alpha_enc.c' || echo '$(srcdir)/'`alpha_enc.c - -libwebpencode_la-analysis_enc.lo: analysis_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-analysis_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-analysis_enc.Tpo -c -o libwebpencode_la-analysis_enc.lo `test -f 'analysis_enc.c' || echo '$(srcdir)/'`analysis_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-analysis_enc.Tpo $(DEPDIR)/libwebpencode_la-analysis_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='analysis_enc.c' object='libwebpencode_la-analysis_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-analysis_enc.lo `test -f 'analysis_enc.c' || echo '$(srcdir)/'`analysis_enc.c - -libwebpencode_la-backward_references_cost_enc.lo: backward_references_cost_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-backward_references_cost_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Tpo -c -o libwebpencode_la-backward_references_cost_enc.lo `test -f 'backward_references_cost_enc.c' || echo '$(srcdir)/'`backward_references_cost_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Tpo $(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backward_references_cost_enc.c' object='libwebpencode_la-backward_references_cost_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-backward_references_cost_enc.lo `test -f 'backward_references_cost_enc.c' || echo '$(srcdir)/'`backward_references_cost_enc.c - -libwebpencode_la-backward_references_enc.lo: backward_references_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-backward_references_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-backward_references_enc.Tpo -c -o libwebpencode_la-backward_references_enc.lo `test -f 'backward_references_enc.c' || echo '$(srcdir)/'`backward_references_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-backward_references_enc.Tpo $(DEPDIR)/libwebpencode_la-backward_references_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='backward_references_enc.c' object='libwebpencode_la-backward_references_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-backward_references_enc.lo `test -f 'backward_references_enc.c' || echo '$(srcdir)/'`backward_references_enc.c - -libwebpencode_la-config_enc.lo: config_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-config_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-config_enc.Tpo -c -o libwebpencode_la-config_enc.lo `test -f 'config_enc.c' || echo '$(srcdir)/'`config_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-config_enc.Tpo $(DEPDIR)/libwebpencode_la-config_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config_enc.c' object='libwebpencode_la-config_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-config_enc.lo `test -f 'config_enc.c' || echo '$(srcdir)/'`config_enc.c - -libwebpencode_la-cost_enc.lo: cost_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-cost_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-cost_enc.Tpo -c -o libwebpencode_la-cost_enc.lo `test -f 'cost_enc.c' || echo '$(srcdir)/'`cost_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-cost_enc.Tpo $(DEPDIR)/libwebpencode_la-cost_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cost_enc.c' object='libwebpencode_la-cost_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-cost_enc.lo `test -f 'cost_enc.c' || echo '$(srcdir)/'`cost_enc.c - -libwebpencode_la-filter_enc.lo: filter_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-filter_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-filter_enc.Tpo -c -o libwebpencode_la-filter_enc.lo `test -f 'filter_enc.c' || echo '$(srcdir)/'`filter_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-filter_enc.Tpo $(DEPDIR)/libwebpencode_la-filter_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='filter_enc.c' object='libwebpencode_la-filter_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-filter_enc.lo `test -f 'filter_enc.c' || echo '$(srcdir)/'`filter_enc.c - -libwebpencode_la-frame_enc.lo: frame_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-frame_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-frame_enc.Tpo -c -o libwebpencode_la-frame_enc.lo `test -f 'frame_enc.c' || echo '$(srcdir)/'`frame_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-frame_enc.Tpo $(DEPDIR)/libwebpencode_la-frame_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame_enc.c' object='libwebpencode_la-frame_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-frame_enc.lo `test -f 'frame_enc.c' || echo '$(srcdir)/'`frame_enc.c - -libwebpencode_la-histogram_enc.lo: histogram_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-histogram_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-histogram_enc.Tpo -c -o libwebpencode_la-histogram_enc.lo `test -f 'histogram_enc.c' || echo '$(srcdir)/'`histogram_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-histogram_enc.Tpo $(DEPDIR)/libwebpencode_la-histogram_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='histogram_enc.c' object='libwebpencode_la-histogram_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-histogram_enc.lo `test -f 'histogram_enc.c' || echo '$(srcdir)/'`histogram_enc.c - -libwebpencode_la-iterator_enc.lo: iterator_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-iterator_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-iterator_enc.Tpo -c -o libwebpencode_la-iterator_enc.lo `test -f 'iterator_enc.c' || echo '$(srcdir)/'`iterator_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-iterator_enc.Tpo $(DEPDIR)/libwebpencode_la-iterator_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iterator_enc.c' object='libwebpencode_la-iterator_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-iterator_enc.lo `test -f 'iterator_enc.c' || echo '$(srcdir)/'`iterator_enc.c - -libwebpencode_la-near_lossless_enc.lo: near_lossless_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-near_lossless_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-near_lossless_enc.Tpo -c -o libwebpencode_la-near_lossless_enc.lo `test -f 'near_lossless_enc.c' || echo '$(srcdir)/'`near_lossless_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-near_lossless_enc.Tpo $(DEPDIR)/libwebpencode_la-near_lossless_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='near_lossless_enc.c' object='libwebpencode_la-near_lossless_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-near_lossless_enc.lo `test -f 'near_lossless_enc.c' || echo '$(srcdir)/'`near_lossless_enc.c - -libwebpencode_la-picture_enc.lo: picture_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-picture_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-picture_enc.Tpo -c -o libwebpencode_la-picture_enc.lo `test -f 'picture_enc.c' || echo '$(srcdir)/'`picture_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-picture_enc.Tpo $(DEPDIR)/libwebpencode_la-picture_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='picture_enc.c' object='libwebpencode_la-picture_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-picture_enc.lo `test -f 'picture_enc.c' || echo '$(srcdir)/'`picture_enc.c - -libwebpencode_la-picture_csp_enc.lo: picture_csp_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-picture_csp_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-picture_csp_enc.Tpo -c -o libwebpencode_la-picture_csp_enc.lo `test -f 'picture_csp_enc.c' || echo '$(srcdir)/'`picture_csp_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-picture_csp_enc.Tpo $(DEPDIR)/libwebpencode_la-picture_csp_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='picture_csp_enc.c' object='libwebpencode_la-picture_csp_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-picture_csp_enc.lo `test -f 'picture_csp_enc.c' || echo '$(srcdir)/'`picture_csp_enc.c - -libwebpencode_la-picture_psnr_enc.lo: picture_psnr_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-picture_psnr_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-picture_psnr_enc.Tpo -c -o libwebpencode_la-picture_psnr_enc.lo `test -f 'picture_psnr_enc.c' || echo '$(srcdir)/'`picture_psnr_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-picture_psnr_enc.Tpo $(DEPDIR)/libwebpencode_la-picture_psnr_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='picture_psnr_enc.c' object='libwebpencode_la-picture_psnr_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-picture_psnr_enc.lo `test -f 'picture_psnr_enc.c' || echo '$(srcdir)/'`picture_psnr_enc.c - -libwebpencode_la-picture_rescale_enc.lo: picture_rescale_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-picture_rescale_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-picture_rescale_enc.Tpo -c -o libwebpencode_la-picture_rescale_enc.lo `test -f 'picture_rescale_enc.c' || echo '$(srcdir)/'`picture_rescale_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-picture_rescale_enc.Tpo $(DEPDIR)/libwebpencode_la-picture_rescale_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='picture_rescale_enc.c' object='libwebpencode_la-picture_rescale_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-picture_rescale_enc.lo `test -f 'picture_rescale_enc.c' || echo '$(srcdir)/'`picture_rescale_enc.c - -libwebpencode_la-picture_tools_enc.lo: picture_tools_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-picture_tools_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-picture_tools_enc.Tpo -c -o libwebpencode_la-picture_tools_enc.lo `test -f 'picture_tools_enc.c' || echo '$(srcdir)/'`picture_tools_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-picture_tools_enc.Tpo $(DEPDIR)/libwebpencode_la-picture_tools_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='picture_tools_enc.c' object='libwebpencode_la-picture_tools_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-picture_tools_enc.lo `test -f 'picture_tools_enc.c' || echo '$(srcdir)/'`picture_tools_enc.c - -libwebpencode_la-predictor_enc.lo: predictor_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-predictor_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-predictor_enc.Tpo -c -o libwebpencode_la-predictor_enc.lo `test -f 'predictor_enc.c' || echo '$(srcdir)/'`predictor_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-predictor_enc.Tpo $(DEPDIR)/libwebpencode_la-predictor_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='predictor_enc.c' object='libwebpencode_la-predictor_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-predictor_enc.lo `test -f 'predictor_enc.c' || echo '$(srcdir)/'`predictor_enc.c - -libwebpencode_la-quant_enc.lo: quant_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-quant_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-quant_enc.Tpo -c -o libwebpencode_la-quant_enc.lo `test -f 'quant_enc.c' || echo '$(srcdir)/'`quant_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-quant_enc.Tpo $(DEPDIR)/libwebpencode_la-quant_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='quant_enc.c' object='libwebpencode_la-quant_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-quant_enc.lo `test -f 'quant_enc.c' || echo '$(srcdir)/'`quant_enc.c - -libwebpencode_la-syntax_enc.lo: syntax_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-syntax_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-syntax_enc.Tpo -c -o libwebpencode_la-syntax_enc.lo `test -f 'syntax_enc.c' || echo '$(srcdir)/'`syntax_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-syntax_enc.Tpo $(DEPDIR)/libwebpencode_la-syntax_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syntax_enc.c' object='libwebpencode_la-syntax_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-syntax_enc.lo `test -f 'syntax_enc.c' || echo '$(srcdir)/'`syntax_enc.c - -libwebpencode_la-token_enc.lo: token_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-token_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-token_enc.Tpo -c -o libwebpencode_la-token_enc.lo `test -f 'token_enc.c' || echo '$(srcdir)/'`token_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-token_enc.Tpo $(DEPDIR)/libwebpencode_la-token_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='token_enc.c' object='libwebpencode_la-token_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-token_enc.lo `test -f 'token_enc.c' || echo '$(srcdir)/'`token_enc.c - -libwebpencode_la-tree_enc.lo: tree_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-tree_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-tree_enc.Tpo -c -o libwebpencode_la-tree_enc.lo `test -f 'tree_enc.c' || echo '$(srcdir)/'`tree_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-tree_enc.Tpo $(DEPDIR)/libwebpencode_la-tree_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tree_enc.c' object='libwebpencode_la-tree_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-tree_enc.lo `test -f 'tree_enc.c' || echo '$(srcdir)/'`tree_enc.c - -libwebpencode_la-vp8l_enc.lo: vp8l_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-vp8l_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-vp8l_enc.Tpo -c -o libwebpencode_la-vp8l_enc.lo `test -f 'vp8l_enc.c' || echo '$(srcdir)/'`vp8l_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-vp8l_enc.Tpo $(DEPDIR)/libwebpencode_la-vp8l_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vp8l_enc.c' object='libwebpencode_la-vp8l_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-vp8l_enc.lo `test -f 'vp8l_enc.c' || echo '$(srcdir)/'`vp8l_enc.c - -libwebpencode_la-webp_enc.lo: webp_enc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwebpencode_la-webp_enc.lo -MD -MP -MF $(DEPDIR)/libwebpencode_la-webp_enc.Tpo -c -o libwebpencode_la-webp_enc.lo `test -f 'webp_enc.c' || echo '$(srcdir)/'`webp_enc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwebpencode_la-webp_enc.Tpo $(DEPDIR)/libwebpencode_la-webp_enc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='webp_enc.c' object='libwebpencode_la-webp_enc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwebpencode_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwebpencode_la-webp_enc.lo `test -f 'webp_enc.c' || echo '$(srcdir)/'`webp_enc.c - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-libwebpencodeincludeHEADERS: $(libwebpencodeinclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(libwebpencodeinclude_HEADERS)'; test -n "$(libwebpencodeincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libwebpencodeincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libwebpencodeincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpencodeincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpencodeincludedir)" || exit $$?; \ - done - -uninstall-libwebpencodeincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libwebpencodeinclude_HEADERS)'; test -n "$(libwebpencodeincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libwebpencodeincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libwebpencodeincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/libwebpencode_la-alpha_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-analysis_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-backward_references_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-config_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-cost_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-filter_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-frame_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-histogram_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-iterator_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-near_lossless_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_csp_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_psnr_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_rescale_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_tools_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-predictor_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-quant_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-syntax_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-token_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-tree_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-vp8l_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-webp_enc.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-libwebpencodeincludeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libwebpencode_la-alpha_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-analysis_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-backward_references_cost_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-backward_references_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-config_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-cost_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-filter_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-frame_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-histogram_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-iterator_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-near_lossless_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_csp_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_psnr_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_rescale_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-picture_tools_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-predictor_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-quant_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-syntax_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-token_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-tree_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-vp8l_enc.Plo - -rm -f ./$(DEPDIR)/libwebpencode_la-webp_enc.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-libwebpencodeincludeHEADERS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstLTLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am \ - install-libwebpencodeincludeHEADERS install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am \ - uninstall-libwebpencodeincludeHEADERS - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libwebp/upstream/src/mux/Makefile.am b/thirdparty/libwebp/upstream/src/mux/Makefile.am deleted file mode 100644 index 18bc90e94..000000000 --- a/thirdparty/libwebp/upstream/src/mux/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) -lib_LTLIBRARIES = libwebpmux.la - -libwebpmux_la_SOURCES = -libwebpmux_la_SOURCES += anim_encode.c -libwebpmux_la_SOURCES += animi.h -libwebpmux_la_SOURCES += muxedit.c -libwebpmux_la_SOURCES += muxi.h -libwebpmux_la_SOURCES += muxinternal.c -libwebpmux_la_SOURCES += muxread.c - -libwebpmuxinclude_HEADERS = -libwebpmuxinclude_HEADERS += ../webp/mux.h -libwebpmuxinclude_HEADERS += ../webp/mux_types.h -libwebpmuxinclude_HEADERS += ../webp/types.h -noinst_HEADERS = -noinst_HEADERS += ../webp/format_constants.h - -libwebpmux_la_LIBADD = ../libwebp.la -libwebpmux_la_LDFLAGS = -no-undefined -version-info 4:0:1 -lm -libwebpmuxincludedir = $(includedir)/webp -pkgconfig_DATA = libwebpmux.pc diff --git a/thirdparty/libwebp/upstream/src/mux/Makefile.in b/thirdparty/libwebp/upstream/src/mux/Makefile.in deleted file mode 100644 index 98350e117..000000000 --- a/thirdparty/libwebp/upstream/src/mux/Makefile.in +++ /dev/null @@ -1,756 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/mux -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(libwebpmuxinclude_HEADERS) \ - $(noinst_HEADERS) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/webp/config.h -CONFIG_CLEAN_FILES = libwebpmux.pc -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(libwebpmuxincludedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libwebpmux_la_DEPENDENCIES = ../libwebp.la -am_libwebpmux_la_OBJECTS = anim_encode.lo muxedit.lo muxinternal.lo \ - muxread.lo -libwebpmux_la_OBJECTS = $(am_libwebpmux_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libwebpmux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libwebpmux_la_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/webp -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/anim_encode.Plo \ - ./$(DEPDIR)/muxedit.Plo ./$(DEPDIR)/muxinternal.Plo \ - ./$(DEPDIR)/muxread.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libwebpmux_la_SOURCES) -DIST_SOURCES = $(libwebpmux_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -DATA = $(pkgconfig_DATA) -HEADERS = $(libwebpmuxinclude_HEADERS) $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libwebpmux.pc.in \ - $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_builddir) -I$(top_srcdir) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GIF_INCLUDES = @GIF_INCLUDES@ -GIF_LIBS = @GIF_LIBS@ -GL_INCLUDES = @GL_INCLUDES@ -GL_LIBS = @GL_LIBS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JPEG_INCLUDES = @JPEG_INCLUDES@ -JPEG_LIBS = @JPEG_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBPNG_CONFIG = @LIBPNG_CONFIG@ -LIBS = @LIBS@ -LIBSDL_CONFIG = @LIBSDL_CONFIG@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NEON_FLAGS = @NEON_FLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PNG_INCLUDES = @PNG_INCLUDES@ -PNG_LIBS = @PNG_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_INCLUDES = @SDL_INCLUDES@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE2_FLAGS = @SSE2_FLAGS@ -SSE41_FLAGS = @SSE41_FLAGS@ -STRIP = @STRIP@ -TIFF_INCLUDES = @TIFF_INCLUDES@ -TIFF_LIBS = @TIFF_LIBS@ -USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgconfigdir = @pkgconfigdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -webp_libname_prefix = @webp_libname_prefix@ -lib_LTLIBRARIES = libwebpmux.la -libwebpmux_la_SOURCES = anim_encode.c animi.h muxedit.c muxi.h \ - muxinternal.c muxread.c -libwebpmuxinclude_HEADERS = ../webp/mux.h ../webp/mux_types.h \ - ../webp/types.h -noinst_HEADERS = ../webp/format_constants.h -libwebpmux_la_LIBADD = ../libwebp.la -libwebpmux_la_LDFLAGS = -no-undefined -version-info 4:0:1 -lm -libwebpmuxincludedir = $(includedir)/webp -pkgconfig_DATA = libwebpmux.pc -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/mux/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/mux/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -libwebpmux.pc: $(top_builddir)/config.status $(srcdir)/libwebpmux.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libwebpmux.la: $(libwebpmux_la_OBJECTS) $(libwebpmux_la_DEPENDENCIES) $(EXTRA_libwebpmux_la_DEPENDENCIES) - $(AM_V_CCLD)$(libwebpmux_la_LINK) -rpath $(libdir) $(libwebpmux_la_OBJECTS) $(libwebpmux_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anim_encode.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muxedit.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muxinternal.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/muxread.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-pkgconfigDATA: $(pkgconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ - done - -uninstall-pkgconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-libwebpmuxincludeHEADERS: $(libwebpmuxinclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(libwebpmuxinclude_HEADERS)'; test -n "$(libwebpmuxincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libwebpmuxincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libwebpmuxincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libwebpmuxincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libwebpmuxincludedir)" || exit $$?; \ - done - -uninstall-libwebpmuxincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libwebpmuxinclude_HEADERS)'; test -n "$(libwebpmuxincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libwebpmuxincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libwebpmuxincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/anim_encode.Plo - -rm -f ./$(DEPDIR)/muxedit.Plo - -rm -f ./$(DEPDIR)/muxinternal.Plo - -rm -f ./$(DEPDIR)/muxread.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-libwebpmuxincludeHEADERS \ - install-pkgconfigDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/anim_encode.Plo - -rm -f ./$(DEPDIR)/muxedit.Plo - -rm -f ./$(DEPDIR)/muxinternal.Plo - -rm -f ./$(DEPDIR)/muxread.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-libLTLIBRARIES \ - uninstall-libwebpmuxincludeHEADERS uninstall-pkgconfigDATA - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES \ - install-libwebpmuxincludeHEADERS install-man install-pdf \ - install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-libLTLIBRARIES uninstall-libwebpmuxincludeHEADERS \ - uninstall-pkgconfigDATA - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libwebp/upstream/src/mux/libwebpmux.pc.in b/thirdparty/libwebp/upstream/src/mux/libwebpmux.pc.in deleted file mode 100644 index c770daafc..000000000 --- a/thirdparty/libwebp/upstream/src/mux/libwebpmux.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libwebpmux -Description: Library for manipulating the WebP graphics format container -Version: @PACKAGE_VERSION@ -Requires.private: libwebp >= 0.2.0 -Cflags: -I${includedir} -Libs: -L${libdir} -l@webp_libname_prefix@webpmux -Libs.private: -lm diff --git a/thirdparty/libwebp/upstream/src/mux/libwebpmux.rc b/thirdparty/libwebp/upstream/src/mux/libwebpmux.rc deleted file mode 100644 index 1b20fac1a..000000000 --- a/thirdparty/libwebp/upstream/src/mux/libwebpmux.rc +++ /dev/null @@ -1,41 +0,0 @@ -#define APSTUDIO_READONLY_SYMBOLS -#include "winres.h" -#undef APSTUDIO_READONLY_SYMBOLS - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,4,0 - PRODUCTVERSION 1,0,4,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Google, Inc." - VALUE "FileDescription", "libwebpmux DLL" - VALUE "FileVersion", "1.4.0" - VALUE "InternalName", "libwebpmux.dll" - VALUE "LegalCopyright", "Copyright (C) 2024" - VALUE "OriginalFilename", "libwebpmux.dll" - VALUE "ProductName", "WebP Image Muxer" - VALUE "ProductVersion", "1.4.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // English (United States) resources diff --git a/thirdparty/libwebp/upstream/src/utils/Makefile.am b/thirdparty/libwebp/upstream/src/utils/Makefile.am deleted file mode 100644 index a0b7fe35e..000000000 --- a/thirdparty/libwebp/upstream/src/utils/Makefile.am +++ /dev/null @@ -1,54 +0,0 @@ -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) -noinst_LTLIBRARIES = libwebputils.la - -if BUILD_LIBWEBPDECODER - noinst_LTLIBRARIES += libwebputilsdecode.la -endif - -common_HEADERS = ../webp/types.h -commondir = $(includedir)/webp - -noinst_HEADERS = -noinst_HEADERS += ../dsp/cpu.h -noinst_HEADERS += ../dsp/dsp.h -noinst_HEADERS += ../webp/decode.h -noinst_HEADERS += ../webp/encode.h -noinst_HEADERS += ../webp/format_constants.h - -COMMON_SOURCES = -COMMON_SOURCES += bit_reader_utils.c -COMMON_SOURCES += bit_reader_utils.h -COMMON_SOURCES += bit_reader_inl_utils.h -COMMON_SOURCES += color_cache_utils.c -COMMON_SOURCES += color_cache_utils.h -COMMON_SOURCES += endian_inl_utils.h -COMMON_SOURCES += filters_utils.c -COMMON_SOURCES += filters_utils.h -COMMON_SOURCES += huffman_utils.c -COMMON_SOURCES += huffman_utils.h -COMMON_SOURCES += palette.c -COMMON_SOURCES += palette.h -COMMON_SOURCES += quant_levels_dec_utils.c -COMMON_SOURCES += quant_levels_dec_utils.h -COMMON_SOURCES += rescaler_utils.c -COMMON_SOURCES += rescaler_utils.h -COMMON_SOURCES += random_utils.c -COMMON_SOURCES += random_utils.h -COMMON_SOURCES += thread_utils.c -COMMON_SOURCES += thread_utils.h -COMMON_SOURCES += utils.c -COMMON_SOURCES += utils.h - -ENC_SOURCES = -ENC_SOURCES += bit_writer_utils.c -ENC_SOURCES += bit_writer_utils.h -ENC_SOURCES += huffman_encode_utils.c -ENC_SOURCES += huffman_encode_utils.h -ENC_SOURCES += quant_levels_utils.c -ENC_SOURCES += quant_levels_utils.h - -libwebputils_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) - -if BUILD_LIBWEBPDECODER - libwebputilsdecode_la_SOURCES = $(COMMON_SOURCES) -endif diff --git a/thirdparty/libwebp/upstream/src/utils/Makefile.in b/thirdparty/libwebp/upstream/src/utils/Makefile.in deleted file mode 100644 index 374fa7706..000000000 --- a/thirdparty/libwebp/upstream/src/utils/Makefile.in +++ /dev/null @@ -1,761 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@BUILD_LIBWEBPDECODER_TRUE@am__append_1 = libwebputilsdecode.la -subdir = src/utils -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(common_HEADERS) \ - $(noinst_HEADERS) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/webp/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libwebputils_la_LIBADD = -am__objects_1 = bit_reader_utils.lo color_cache_utils.lo \ - filters_utils.lo huffman_utils.lo palette.lo \ - quant_levels_dec_utils.lo rescaler_utils.lo random_utils.lo \ - thread_utils.lo utils.lo -am__objects_2 = bit_writer_utils.lo huffman_encode_utils.lo \ - quant_levels_utils.lo -am_libwebputils_la_OBJECTS = $(am__objects_1) $(am__objects_2) -libwebputils_la_OBJECTS = $(am_libwebputils_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libwebputilsdecode_la_LIBADD = -am__libwebputilsdecode_la_SOURCES_DIST = bit_reader_utils.c \ - bit_reader_utils.h bit_reader_inl_utils.h color_cache_utils.c \ - color_cache_utils.h endian_inl_utils.h filters_utils.c \ - filters_utils.h huffman_utils.c huffman_utils.h palette.c \ - palette.h quant_levels_dec_utils.c quant_levels_dec_utils.h \ - rescaler_utils.c rescaler_utils.h random_utils.c \ - random_utils.h thread_utils.c thread_utils.h utils.c utils.h -@BUILD_LIBWEBPDECODER_TRUE@am_libwebputilsdecode_la_OBJECTS = \ -@BUILD_LIBWEBPDECODER_TRUE@ $(am__objects_1) -libwebputilsdecode_la_OBJECTS = $(am_libwebputilsdecode_la_OBJECTS) -@BUILD_LIBWEBPDECODER_TRUE@am_libwebputilsdecode_la_rpath = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/webp -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/bit_reader_utils.Plo \ - ./$(DEPDIR)/bit_writer_utils.Plo \ - ./$(DEPDIR)/color_cache_utils.Plo \ - ./$(DEPDIR)/filters_utils.Plo \ - ./$(DEPDIR)/huffman_encode_utils.Plo \ - ./$(DEPDIR)/huffman_utils.Plo ./$(DEPDIR)/palette.Plo \ - ./$(DEPDIR)/quant_levels_dec_utils.Plo \ - ./$(DEPDIR)/quant_levels_utils.Plo \ - ./$(DEPDIR)/random_utils.Plo ./$(DEPDIR)/rescaler_utils.Plo \ - ./$(DEPDIR)/thread_utils.Plo ./$(DEPDIR)/utils.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libwebputils_la_SOURCES) $(libwebputilsdecode_la_SOURCES) -DIST_SOURCES = $(libwebputils_la_SOURCES) \ - $(am__libwebputilsdecode_la_SOURCES_DIST) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(commondir)" -HEADERS = $(common_HEADERS) $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_builddir) -I$(top_srcdir) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FILECMD = @FILECMD@ -GIF_INCLUDES = @GIF_INCLUDES@ -GIF_LIBS = @GIF_LIBS@ -GL_INCLUDES = @GL_INCLUDES@ -GL_LIBS = @GL_LIBS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -JPEG_INCLUDES = @JPEG_INCLUDES@ -JPEG_LIBS = @JPEG_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBPNG_CONFIG = @LIBPNG_CONFIG@ -LIBS = @LIBS@ -LIBSDL_CONFIG = @LIBSDL_CONFIG@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NEON_FLAGS = @NEON_FLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PNG_INCLUDES = @PNG_INCLUDES@ -PNG_LIBS = @PNG_LIBS@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -SDL_INCLUDES = @SDL_INCLUDES@ -SDL_LIBS = @SDL_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE2_FLAGS = @SSE2_FLAGS@ -SSE41_FLAGS = @SSE41_FLAGS@ -STRIP = @STRIP@ -TIFF_INCLUDES = @TIFF_INCLUDES@ -TIFF_LIBS = @TIFF_LIBS@ -USE_SWAP_16BIT_CSP = @USE_SWAP_16BIT_CSP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgconfigdir = @pkgconfigdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -webp_libname_prefix = @webp_libname_prefix@ -noinst_LTLIBRARIES = libwebputils.la $(am__append_1) -common_HEADERS = ../webp/types.h -commondir = $(includedir)/webp -noinst_HEADERS = ../dsp/cpu.h ../dsp/dsp.h ../webp/decode.h \ - ../webp/encode.h ../webp/format_constants.h -COMMON_SOURCES = bit_reader_utils.c bit_reader_utils.h \ - bit_reader_inl_utils.h color_cache_utils.c color_cache_utils.h \ - endian_inl_utils.h filters_utils.c filters_utils.h \ - huffman_utils.c huffman_utils.h palette.c palette.h \ - quant_levels_dec_utils.c quant_levels_dec_utils.h \ - rescaler_utils.c rescaler_utils.h random_utils.c \ - random_utils.h thread_utils.c thread_utils.h utils.c utils.h -ENC_SOURCES = bit_writer_utils.c bit_writer_utils.h \ - huffman_encode_utils.c huffman_encode_utils.h \ - quant_levels_utils.c quant_levels_utils.h -libwebputils_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) -@BUILD_LIBWEBPDECODER_TRUE@libwebputilsdecode_la_SOURCES = $(COMMON_SOURCES) -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/utils/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/utils/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libwebputils.la: $(libwebputils_la_OBJECTS) $(libwebputils_la_DEPENDENCIES) $(EXTRA_libwebputils_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libwebputils_la_OBJECTS) $(libwebputils_la_LIBADD) $(LIBS) - -libwebputilsdecode.la: $(libwebputilsdecode_la_OBJECTS) $(libwebputilsdecode_la_DEPENDENCIES) $(EXTRA_libwebputilsdecode_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libwebputilsdecode_la_rpath) $(libwebputilsdecode_la_OBJECTS) $(libwebputilsdecode_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit_reader_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit_writer_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color_cache_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filters_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman_encode_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/palette.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quant_levels_dec_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quant_levels_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rescaler_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_utils.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-commonHEADERS: $(common_HEADERS) - @$(NORMAL_INSTALL) - @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(commondir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(commondir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(commondir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(commondir)" || exit $$?; \ - done - -uninstall-commonHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(common_HEADERS)'; test -n "$(commondir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(commondir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) -installdirs: - for dir in "$(DESTDIR)$(commondir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/bit_reader_utils.Plo - -rm -f ./$(DEPDIR)/bit_writer_utils.Plo - -rm -f ./$(DEPDIR)/color_cache_utils.Plo - -rm -f ./$(DEPDIR)/filters_utils.Plo - -rm -f ./$(DEPDIR)/huffman_encode_utils.Plo - -rm -f ./$(DEPDIR)/huffman_utils.Plo - -rm -f ./$(DEPDIR)/palette.Plo - -rm -f ./$(DEPDIR)/quant_levels_dec_utils.Plo - -rm -f ./$(DEPDIR)/quant_levels_utils.Plo - -rm -f ./$(DEPDIR)/random_utils.Plo - -rm -f ./$(DEPDIR)/rescaler_utils.Plo - -rm -f ./$(DEPDIR)/thread_utils.Plo - -rm -f ./$(DEPDIR)/utils.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-commonHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/bit_reader_utils.Plo - -rm -f ./$(DEPDIR)/bit_writer_utils.Plo - -rm -f ./$(DEPDIR)/color_cache_utils.Plo - -rm -f ./$(DEPDIR)/filters_utils.Plo - -rm -f ./$(DEPDIR)/huffman_encode_utils.Plo - -rm -f ./$(DEPDIR)/huffman_utils.Plo - -rm -f ./$(DEPDIR)/palette.Plo - -rm -f ./$(DEPDIR)/quant_levels_dec_utils.Plo - -rm -f ./$(DEPDIR)/quant_levels_utils.Plo - -rm -f ./$(DEPDIR)/random_utils.Plo - -rm -f ./$(DEPDIR)/rescaler_utils.Plo - -rm -f ./$(DEPDIR)/thread_utils.Plo - -rm -f ./$(DEPDIR)/utils.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-commonHEADERS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstLTLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-commonHEADERS install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-commonHEADERS - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libwebp/upstream/src/utils/quant_levels_dec_utils.c b/thirdparty/libwebp/upstream/src/utils/quant_levels_dec_utils.c index 927e6d3b8..97e789370 100644 --- a/thirdparty/libwebp/upstream/src/utils/quant_levels_dec_utils.c +++ b/thirdparty/libwebp/upstream/src/utils/quant_levels_dec_utils.c @@ -71,13 +71,11 @@ typedef struct { //------------------------------------------------------------------------------ -#if 0 #define CLIP_8b_MASK (int)(~0U << (8 + DFIX)) static WEBP_INLINE uint8_t clip_8b(int v) { return (!(v & CLIP_8b_MASK)) ? (uint8_t)(v >> DFIX) : (v < 0) ? 0u : 255u; } #undef CLIP_8b_MASK -#endif // vertical accumulation static void VFilter(SmoothParams* const p) { diff --git a/thirdparty/libwebp/upstream/src/webp/config.h b/thirdparty/libwebp/upstream/src/webp/config.h index e69de29bb..25ea95442 100644 --- a/thirdparty/libwebp/upstream/src/webp/config.h +++ b/thirdparty/libwebp/upstream/src/webp/config.h @@ -0,0 +1,31 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#ifndef WEBP_CONFIG_H_ +#define WEBP_CONFIG_H_ + +/* + libwebp expects this generated header when HAVE_CONFIG_H is defined. The YUP + unity wrapper defines the actual feature macros before including upstream + sources, so this file only provides the include target expected by upstream. +*/ + +#endif /* WEBP_CONFIG_H_ */ diff --git a/thirdparty/libwebp/upstream/src/webp/config.h.in b/thirdparty/libwebp/upstream/src/webp/config.h.in deleted file mode 100644 index 007db075f..000000000 --- a/thirdparty/libwebp/upstream/src/webp/config.h.in +++ /dev/null @@ -1,151 +0,0 @@ -/* src/webp/config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Set to 1 if __builtin_bswap16 is available */ -#undef HAVE_BUILTIN_BSWAP16 - -/* Set to 1 if __builtin_bswap32 is available */ -#undef HAVE_BUILTIN_BSWAP32 - -/* Set to 1 if __builtin_bswap64 is available */ -#undef HAVE_BUILTIN_BSWAP64 - -/* Define to 1 if you have the header file. */ -#undef HAVE_CPU_FEATURES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_GLUT_GLUT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_GL_GLUT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENGL_GLUT_H - -/* Have PTHREAD_PRIO_INHERIT. */ -#undef HAVE_PTHREAD_PRIO_INHERIT - -/* Define to 1 if you have the header file. */ -#undef HAVE_SHLWAPI_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINCODEC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINDOWS_H - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* Define to 1 if all of the C90 standard headers exist (not just the ones - required in a freestanding environment). This macro is provided for - backward compatibility; new code need not use it. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Set to 1 if GIF library is installed */ -#undef WEBP_HAVE_GIF - -/* Set to 1 if OpenGL is supported */ -#undef WEBP_HAVE_GL - -/* Set to 1 if JPEG library is installed */ -#undef WEBP_HAVE_JPEG - -/* Set to 1 if NEON is supported */ -#undef WEBP_HAVE_NEON - -/* Set to 1 if runtime detection of NEON is enabled */ -#undef WEBP_HAVE_NEON_RTCD - -/* Set to 1 if PNG library is installed */ -#undef WEBP_HAVE_PNG - -/* Set to 1 if SDL library is installed */ -#undef WEBP_HAVE_SDL - -/* Set to 1 if SSE2 is supported */ -#undef WEBP_HAVE_SSE2 - -/* Set to 1 if SSE4.1 is supported */ -#undef WEBP_HAVE_SSE41 - -/* Set to 1 if TIFF library is installed */ -#undef WEBP_HAVE_TIFF - -/* Enable near lossless encoding */ -#undef WEBP_NEAR_LOSSLESS - -/* Undefine this to disable thread support. */ -#undef WEBP_USE_THREAD - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif diff --git a/thirdparty/luau/luau.cpp b/thirdparty/luau/luau.cpp new file mode 100644 index 000000000..44a664d37 --- /dev/null +++ b/thirdparty/luau/luau.cpp @@ -0,0 +1,59 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "luau.h" + +#include "upstream/VM/src/lapi.cpp" +#include "upstream/VM/src/laux.cpp" +#include "upstream/VM/src/lbaselib.cpp" +#include "upstream/VM/src/lbitlib.cpp" +#include "upstream/VM/src/lbuffer.cpp" +#include "upstream/VM/src/lbuflib.cpp" +#include "upstream/VM/src/lbuiltins.cpp" +#include "upstream/VM/src/lcorolib.cpp" +#include "upstream/VM/src/ldblib.cpp" +#include "upstream/VM/src/ldebug.cpp" +#include "upstream/VM/src/ldo.cpp" +#include "upstream/VM/src/lfunc.cpp" +#include "upstream/VM/src/lgc.cpp" +#include "upstream/VM/src/lgcdebug.cpp" +#include "upstream/VM/src/linit.cpp" +#include "upstream/VM/src/lmathlib.cpp" +#include "upstream/VM/src/lmem.cpp" +#include "upstream/VM/src/lnumprint.cpp" +#include "upstream/VM/src/lobject.cpp" +#include "upstream/VM/src/loslib.cpp" +#include "upstream/VM/src/lstate.cpp" +#include "upstream/VM/src/lstring.cpp" +#include "upstream/VM/src/lstrlib.cpp" +#include "upstream/VM/src/ltable.cpp" +#include "upstream/VM/src/ltablib.cpp" +#include "upstream/VM/src/ltm.cpp" +#include "upstream/VM/src/ludata.cpp" +#include "upstream/VM/src/lutf8lib.cpp" +#define createmetatable createmetatable_vec +#include "upstream/VM/src/lveclib.cpp" +#undef createmetatable +#include "upstream/VM/src/lvmexecute.cpp" +#include "upstream/VM/src/lvmload.cpp" +#include "upstream/VM/src/lvmutils.cpp" + +#include "upstream/VM/src/lperf.cpp" diff --git a/thirdparty/luau/luau.h b/thirdparty/luau/luau.h new file mode 100644 index 000000000..f4e63876b --- /dev/null +++ b/thirdparty/luau/luau.h @@ -0,0 +1,46 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +/* + ============================================================================== + + BEGIN_YUP_MODULE_DECLARATION + + ID: luau + vendor: luau + version: 0.35 + name: Luau Runtime + description: Luau is a fast, small, safe, gradually typed embeddable scripting language derived from Lua. + website: https://github.com/luau-lang/luau + license: MIT + + defines: LUA_USE_LONGJMP=1 RIVE_LUAU=1 + searchpaths: upstream/VM/include upstream/Common/include upstream/VM/src + + END_YUP_MODULE_DECLARATION + + ============================================================================== +*/ + +#pragma once + +#include "upstream/VM/include/lua.h" +#include "upstream/VM/include/lualib.h" diff --git a/thirdparty/luau/luau_split.cpp b/thirdparty/luau/luau_split.cpp new file mode 100644 index 000000000..d045fd4b8 --- /dev/null +++ b/thirdparty/luau/luau_split.cpp @@ -0,0 +1,27 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "luau.h" + +// BEGIN YUP GENERATED LUAU COMMON INCLUDES +#include "upstream/Common/src/StringUtils.cpp" +#include "upstream/Common/src/TimeTrace.cpp" +// END YUP GENERATED LUAU COMMON INCLUDES diff --git a/thirdparty/luau/upstream/Common/include/Luau/Bytecode.h b/thirdparty/luau/upstream/Common/include/Luau/Bytecode.h new file mode 100644 index 000000000..2b031dc87 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/Bytecode.h @@ -0,0 +1,683 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +// clang-format off + +// This header contains the bytecode definition for Luau interpreter +// Creating the bytecode is outside the scope of this file and is handled by bytecode builder (BytecodeBuilder.h) and bytecode compiler (Compiler.h) +// Note that ALL enums declared in this file are order-sensitive since the values are baked into bytecode that needs to be processed by legacy clients. + +// # Bytecode definitions +// Bytecode instructions are using "word code" - each instruction is one or many 32-bit words. +// The first word in the instruction is always the instruction header, and *must* contain the opcode (enum below) in the least significant byte. +// +// Instruction word can be encoded using one of the following encodings: +// ABC - least-significant byte for the opcode, followed by three bytes, A, B and C; each byte declares a register index, small index into some other table or an unsigned integral value +// AD - least-significant byte for the opcode, followed by A byte, followed by D half-word (16-bit integer). D is a signed integer that commonly specifies constant table index or jump offset +// E - least-significant byte for the opcode, followed by E (24-bit integer). E is a signed integer that commonly specifies a jump offset +// +// Instruction word is sometimes followed by one extra word, indicated as AUX - this is just a 32-bit word and is decoded according to the specification for each opcode. +// For each opcode the encoding is *static* - that is, based on the opcode you know apriori how large the instruction is, with the exception of NEWCLOSURE + +// # Bytecode indices +// Bytecode instructions commonly refer to integer values that define offsets or indices for various entities. For each type, there's a maximum encodable value. +// Note that in some cases, the compiler will set a lower limit than the maximum encodable value is to prevent fragile code into bumping against the limits whenever we change the compilation details. +// Additionally, in some specific instructions such as ANDK, the limit on the encoded value is smaller; this means that if a value is larger, a different instruction must be selected. +// +// Registers: 0-254. Registers refer to the values on the function's stack frame, including arguments. +// Upvalues: 0-199. Upvalues refer to the values stored in the closure object. +// Constants: 0-2^23-1. Constants are stored in a table allocated with each proto; to allow for future bytecode tweaks the encodable value is limited to 23 bits. +// Closures: 0-2^15-1. Closures are created from child protos via a child index; the limit is for the number of closures immediately referenced in each function. +// Jumps: -2^23..2^23. Jump offsets are specified in word increments, so jumping over an instruction may sometimes require an offset of 2 or more. Note that for jump instructions with AUX, the AUX word is included as part of the jump offset. + +// # Bytecode versions +// Bytecode serialized format embeds a version number, that dictates both the serialized form as well as the allowed instructions. As long as the bytecode version falls into supported +// range (indicated by LBC_BYTECODE_MIN / LBC_BYTECODE_MAX) and was produced by Luau compiler, it should load and execute correctly. +// +// Note that Luau runtime doesn't provide indefinite bytecode compatibility: support for older versions gets removed over time. As such, bytecode isn't a durable storage format and it's expected +// that Luau users can recompile bytecode from source on Luau version upgrades if necessary. + +// # Bytecode version history +// +// Note: due to limitations of the versioning scheme, some bytecode blobs that carry version 2 are using features from version 3. Starting from version 3, version should be sufficient to indicate bytecode compatibility. +// +// Version 1: Baseline version for the open-source release. Supported until 0.521. +// Version 2: Adds Proto::linedefined. Supported until 0.544. +// Version 3: Adds FORGPREP/JUMPXEQK* and enhances AUX encoding for FORGLOOP. Removes FORGLOOP_NEXT/INEXT and JUMPIFEQK/JUMPIFNOTEQK. Currently supported. +// Version 4: Adds Proto::flags, typeinfo, and floor division opcodes IDIV/IDIVK. Currently supported. +// Version 5: Adds SUBRK/DIVRK and vector constants. Currently supported. +// Version 6: Adds FASTCALL3. Currently supported. +// Version 7: Adds LBC_CONSTANT_TABLE_WITH_CONSTANTS for DUPTABLE with pre-filled constant values. Currently supported. + +// # Bytecode type information history +// Version 1: (from bytecode version 4) Type information for function signature. Currently supported. +// Version 2: (from bytecode version 4) Type information for arguments, upvalues, locals and some temporaries. Currently supported. +// Version 3: (from bytecode version 5) Type information for userdata type names and their index mapping. Currently supported. + +// Bytecode opcode, part of the instruction header +enum LuauOpcode +{ + // NOP: noop + LOP_NOP, + + // BREAK: debugger break + LOP_BREAK, + + // LOADNIL: sets register to nil + // A: target register + LOP_LOADNIL, + + // LOADB: sets register to boolean and jumps to a given short offset (used to compile comparison results into a boolean) + // A: target register + // B: value (0/1) + // C: jump offset + LOP_LOADB, + + // LOADN: sets register to a number literal + // A: target register + // D: value (-32768..32767) + LOP_LOADN, + + // LOADK: sets register to an entry from the constant table from the proto (number/vector/string) + // A: target register + // D: constant table index (0..32767) + LOP_LOADK, + + // MOVE: move (copy) value from one register to another + // A: target register + // B: source register + LOP_MOVE, + + // GETGLOBAL: load value from global table using constant string as a key + // A: target register + // C: predicted slot index (based on hash) + // AUX: constant table index + LOP_GETGLOBAL, + + // SETGLOBAL: set value in global table using constant string as a key + // A: source register + // C: predicted slot index (based on hash) + // AUX: constant table index + LOP_SETGLOBAL, + + // GETUPVAL: load upvalue from the upvalue table for the current function + // A: target register + // B: upvalue index + LOP_GETUPVAL, + + // SETUPVAL: store value into the upvalue table for the current function + // A: target register + // B: upvalue index + LOP_SETUPVAL, + + // CLOSEUPVALS: close (migrate to heap) all upvalues that were captured for registers >= target + // A: target register + LOP_CLOSEUPVALS, + + // GETIMPORT: load imported global table global from the constant table + // A: target register + // D: constant table index (0..32767); we assume that imports are loaded into the constant table + // AUX: 3 10-bit indices of constant strings that, combined, constitute an import path; length of the path is set by the top 2 bits (1,2,3) + LOP_GETIMPORT, + + // GETTABLE: load value from table into target register using key from register + // A: target register + // B: table register + // C: index register + LOP_GETTABLE, + + // SETTABLE: store source register into table using key from register + // A: source register + // B: table register + // C: index register + LOP_SETTABLE, + + // GETTABLEKS: load value from table into target register using constant string as a key + // A: target register + // B: table register + // C: predicted slot index (based on hash) + // AUX: constant table index + LOP_GETTABLEKS, + + // SETTABLEKS: store source register into table using constant string as a key + // A: source register + // B: table register + // C: predicted slot index (based on hash) + // AUX: constant table index + LOP_SETTABLEKS, + + // GETTABLEN: load value from table into target register using small integer index as a key + // A: target register + // B: table register + // C: index-1 (index is 1..256) + LOP_GETTABLEN, + + // SETTABLEN: store source register into table using small integer index as a key + // A: source register + // B: table register + // C: index-1 (index is 1..256) + LOP_SETTABLEN, + + // NEWCLOSURE: create closure from a child proto; followed by a CAPTURE instruction for each upvalue + // A: target register + // D: child proto index (0..32767) + LOP_NEWCLOSURE, + + // NAMECALL: prepare to call specified method by name by loading function from source register using constant index into target register and copying source register into target register + 1 + // A: target register + // B: source register + // C: predicted slot index (based on hash) + // AUX: constant table index + // Note that this instruction must be followed directly by CALL; it prepares the arguments + // This instruction is roughly equivalent to GETTABLEKS + MOVE pair, but we need a special instruction to support custom __namecall metamethod + LOP_NAMECALL, + + // CALL: call specified function + // A: register where the function object lives, followed by arguments; results are placed starting from the same register + // B: argument count + 1, or 0 to preserve all arguments up to top (MULTRET) + // C: result count + 1, or 0 to preserve all values and adjust top (MULTRET) + LOP_CALL, + + // RETURN: returns specified values from the function + // A: register where the returned values start + // B: number of returned values + 1, or 0 to return all values up to top (MULTRET) + LOP_RETURN, + + // JUMP: jumps to target offset + // D: jump offset (-32768..32767; 0 means "next instruction" aka "don't jump") + LOP_JUMP, + + // JUMPBACK: jumps to target offset; this is equivalent to JUMP but is used as a safepoint to be able to interrupt while/repeat loops + // D: jump offset (-32768..32767; 0 means "next instruction" aka "don't jump") + LOP_JUMPBACK, + + // JUMPIF: jumps to target offset if register is not nil/false + // A: source register + // D: jump offset (-32768..32767; 0 means "next instruction" aka "don't jump") + LOP_JUMPIF, + + // JUMPIFNOT: jumps to target offset if register is nil/false + // A: source register + // D: jump offset (-32768..32767; 0 means "next instruction" aka "don't jump") + LOP_JUMPIFNOT, + + // JUMPIFEQ, JUMPIFLE, JUMPIFLT, JUMPIFNOTEQ, JUMPIFNOTLE, JUMPIFNOTLT: jumps to target offset if the comparison is true (or false, for NOT variants) + // A: source register 1 + // D: jump offset (-32768..32767; 1 means "next instruction" aka "don't jump") + // AUX: source register 2 + LOP_JUMPIFEQ, + LOP_JUMPIFLE, + LOP_JUMPIFLT, + LOP_JUMPIFNOTEQ, + LOP_JUMPIFNOTLE, + LOP_JUMPIFNOTLT, + + // ADD, SUB, MUL, DIV, MOD, POW: compute arithmetic operation between two source registers and put the result into target register + // A: target register + // B: source register 1 + // C: source register 2 + LOP_ADD, + LOP_SUB, + LOP_MUL, + LOP_DIV, + LOP_MOD, + LOP_POW, + + // ADDK, SUBK, MULK, DIVK, MODK, POWK: compute arithmetic operation between the source register and a constant and put the result into target register + // A: target register + // B: source register + // C: constant table index (0..255); must refer to a number + LOP_ADDK, + LOP_SUBK, + LOP_MULK, + LOP_DIVK, + LOP_MODK, + LOP_POWK, + + // AND, OR: perform `and` or `or` operation (selecting first or second register based on whether the first one is truthy) and put the result into target register + // A: target register + // B: source register 1 + // C: source register 2 + LOP_AND, + LOP_OR, + + // ANDK, ORK: perform `and` or `or` operation (selecting source register or constant based on whether the source register is truthy) and put the result into target register + // A: target register + // B: source register + // C: constant table index (0..255) + LOP_ANDK, + LOP_ORK, + + // CONCAT: concatenate all strings between B and C (inclusive) and put the result into A + // A: target register + // B: source register start + // C: source register end + LOP_CONCAT, + + // NOT, MINUS, LENGTH: compute unary operation for source register and put the result into target register + // A: target register + // B: source register + LOP_NOT, + LOP_MINUS, + LOP_LENGTH, + + // NEWTABLE: create table in target register + // A: target register + // B: table size, stored as 0 for v=0 and ceil(log2(v))+1 for v!=0 + // AUX: array size + LOP_NEWTABLE, + + // DUPTABLE: duplicate table using the constant table template to target register + // A: target register + // D: constant table index (0..32767) + LOP_DUPTABLE, + + // SETLIST: set a list of values to table in target register + // A: target register + // B: source register start + // C: value count + 1, or 0 to use all values up to top (MULTRET) + // AUX: table index to start from + LOP_SETLIST, + + // FORNPREP: prepare a numeric for loop, jump over the loop if first iteration doesn't need to run + // A: target register; numeric for loops assume a register layout [limit, step, index, variable] + // D: jump offset (-32768..32767) + // limit/step are immutable, index isn't visible to user code since it's copied into variable + LOP_FORNPREP, + + // FORNLOOP: adjust loop variables for one iteration, jump back to the loop header if loop needs to continue + // A: target register; see FORNPREP for register layout + // D: jump offset (-32768..32767) + LOP_FORNLOOP, + + // FORGLOOP: adjust loop variables for one iteration of a generic for loop, jump back to the loop header if loop needs to continue + // A: target register; generic for loops assume a register layout [generator, state, index, variables...] + // D: jump offset (-32768..32767) + // AUX: variable count (1..255) in the low 8 bits, high bit indicates whether to use ipairs-style traversal in the fast path + // loop variables are adjusted by calling generator(state, index) and expecting it to return a tuple that's copied to the user variables + // the first variable is then copied into index; generator/state are immutable, index isn't visible to user code + LOP_FORGLOOP, + + // FORGPREP_INEXT: prepare FORGLOOP with 2 output variables (no AUX encoding), assuming generator is luaB_inext, and jump to FORGLOOP + // A: target register (see FORGLOOP for register layout) + // D: jump offset (-32768..32767) + LOP_FORGPREP_INEXT, + + // FASTCALL3: perform a fast call of a built-in function using 3 register arguments + // A: builtin function id (see LuauBuiltinFunction) + // B: source argument register + // C: jump offset to get to following CALL + // AUX: source register 2 in least-significant byte + // AUX: source register 3 in second least-significant byte + LOP_FASTCALL3, + + // FORGPREP_NEXT: prepare FORGLOOP with 2 output variables (no AUX encoding), assuming generator is luaB_next, and jump to FORGLOOP + // A: target register (see FORGLOOP for register layout) + // D: jump offset (-32768..32767) + LOP_FORGPREP_NEXT, + + // NATIVECALL: start executing new function in native code + // this is a pseudo-instruction that is never emitted by bytecode compiler, but can be constructed at runtime to accelerate native code dispatch + LOP_NATIVECALL, + + // GETVARARGS: copy variables into the target register from vararg storage for current function + // A: target register + // B: variable count + 1, or 0 to copy all variables and adjust top (MULTRET) + LOP_GETVARARGS, + + // DUPCLOSURE: create closure from a pre-created function object (reusing it unless environments diverge) + // A: target register + // D: constant table index (0..32767) + LOP_DUPCLOSURE, + + // PREPVARARGS: prepare stack for variadic functions so that GETVARARGS works correctly + // A: number of fixed arguments + LOP_PREPVARARGS, + + // LOADKX: sets register to an entry from the constant table from the proto (number/string) + // A: target register + // AUX: constant table index + LOP_LOADKX, + + // JUMPX: jumps to the target offset; like JUMPBACK, supports interruption + // E: jump offset (-2^23..2^23; 0 means "next instruction" aka "don't jump") + LOP_JUMPX, + + // FASTCALL: perform a fast call of a built-in function + // A: builtin function id (see LuauBuiltinFunction) + // C: jump offset to get to following CALL + // FASTCALL is followed by one of (GETIMPORT, MOVE, GETUPVAL) instructions and by CALL instruction + // This is necessary so that if FASTCALL can't perform the call inline, it can continue normal execution + // If FASTCALL *can* perform the call, it jumps over the instructions *and* over the next CALL + // Note that FASTCALL will read the actual call arguments, such as argument/result registers and counts, from the CALL instruction + LOP_FASTCALL, + + // COVERAGE: update coverage information stored in the instruction + // E: hit count for the instruction (0..2^23-1) + // The hit count is incremented by VM every time the instruction is executed, and saturates at 2^23-1 + LOP_COVERAGE, + + // CAPTURE: capture a local or an upvalue as an upvalue into a newly created closure; only valid after NEWCLOSURE + // A: capture type, see LuauCaptureType + // B: source register (for VAL/REF) or upvalue index (for UPVAL/UPREF) + LOP_CAPTURE, + + // SUBRK, DIVRK: compute arithmetic operation between the constant and a source register and put the result into target register + // A: target register + // B: constant table index (0..255); must refer to a number + // C: source register + LOP_SUBRK, + LOP_DIVRK, + + // FASTCALL1: perform a fast call of a built-in function using 1 register argument + // A: builtin function id (see LuauBuiltinFunction) + // B: source argument register + // C: jump offset to get to following CALL + LOP_FASTCALL1, + + // FASTCALL2: perform a fast call of a built-in function using 2 register arguments + // A: builtin function id (see LuauBuiltinFunction) + // B: source argument register + // C: jump offset to get to following CALL + // AUX: source register 2 in least-significant byte + LOP_FASTCALL2, + + // FASTCALL2K: perform a fast call of a built-in function using 1 register argument and 1 constant argument + // A: builtin function id (see LuauBuiltinFunction) + // B: source argument register + // C: jump offset to get to following CALL + // AUX: constant index + LOP_FASTCALL2K, + + // FORGPREP: prepare loop variables for a generic for loop, jump to the loop backedge unconditionally + // A: target register; generic for loops assume a register layout [generator, state, index, variables...] + // D: jump offset (-32768..32767) + LOP_FORGPREP, + + // JUMPXEQKNIL, JUMPXEQKB: jumps to target offset if the comparison with constant is true (or false, see AUX) + // A: source register 1 + // D: jump offset (-32768..32767; 1 means "next instruction" aka "don't jump") + // AUX: constant value (for boolean) in low bit, NOT flag (that flips comparison result) in high bit + LOP_JUMPXEQKNIL, + LOP_JUMPXEQKB, + + // JUMPXEQKN, JUMPXEQKS: jumps to target offset if the comparison with constant is true (or false, see AUX) + // A: source register 1 + // D: jump offset (-32768..32767; 1 means "next instruction" aka "don't jump") + // AUX: constant table index in low 24 bits, NOT flag (that flips comparison result) in high bit + LOP_JUMPXEQKN, + LOP_JUMPXEQKS, + + // IDIV: compute floor division between two source registers and put the result into target register + // A: target register + // B: source register 1 + // C: source register 2 + LOP_IDIV, + + // IDIVK compute floor division between the source register and a constant and put the result into target register + // A: target register + // B: source register + // C: constant table index (0..255) + LOP_IDIVK, + + // Enum entry for number of opcodes, not a valid opcode by itself! + LOP__COUNT +}; + +// Bytecode instruction header: it's always a 32-bit integer, with low byte (first byte in little endian) containing the opcode +// Some instruction types require more data and have more 32-bit integers following the header +#define LUAU_INSN_OP(insn) ((insn) & 0xff) + +// ABC encoding: three 8-bit values, containing registers or small numbers +#define LUAU_INSN_A(insn) (((insn) >> 8) & 0xff) +#define LUAU_INSN_B(insn) (((insn) >> 16) & 0xff) +#define LUAU_INSN_C(insn) (((insn) >> 24) & 0xff) + +// AD encoding: one 8-bit value, one signed 16-bit value +#define LUAU_INSN_D(insn) (int32_t(insn) >> 16) + +// E encoding: one signed 24-bit value +#define LUAU_INSN_E(insn) (int32_t(insn) >> 8) + +// Auxiliary AB: two 8-bit values, containing registers or small numbers +// Used in FASTCALL3 +#define LUAU_INSN_AUX_A(aux) ((aux) & 0xff) +#define LUAU_INSN_AUX_B(aux) (((aux) >> 8) & 0xff) + +// Auxiliary KV: unsigned 24-bit constant index +// Used in LOP_JUMPXEQK* instructions +#define LUAU_INSN_AUX_KV(aux) ((aux) & 0xffffff) + +// Auxiliary KB: 1-bit constant value +// Used in LOP_JUMPXEQKB instruction +#define LUAU_INSN_AUX_KB(aux) ((aux) & 0x1) + +// Auxiliary NOT: 1-bit negation flag +// Used in LOP_JUMPXEQK* instructions +#define LUAU_INSN_AUX_NOT(aux) ((aux) >> 31) + +// Bytecode tags, used internally for bytecode encoded as a string +enum LuauBytecodeTag +{ + // Bytecode version; runtime supports [MIN, MAX], compiler emits TARGET by default but may emit a higher version when flags are enabled + LBC_VERSION_MIN = 3, + LBC_VERSION_MAX = 7, + LBC_VERSION_TARGET = 6, + // Type encoding version + LBC_TYPE_VERSION_MIN = 1, + LBC_TYPE_VERSION_MAX = 3, + LBC_TYPE_VERSION_TARGET = 3, + // Types of constant table entries + LBC_CONSTANT_NIL = 0, + LBC_CONSTANT_BOOLEAN, + LBC_CONSTANT_NUMBER, + LBC_CONSTANT_STRING, + LBC_CONSTANT_IMPORT, + LBC_CONSTANT_TABLE, + LBC_CONSTANT_CLOSURE, + LBC_CONSTANT_VECTOR, + LBC_CONSTANT_TABLE_WITH_CONSTANTS, +}; + +// Type table tags +enum LuauBytecodeType +{ + LBC_TYPE_NIL = 0, + LBC_TYPE_BOOLEAN, + LBC_TYPE_NUMBER, + LBC_TYPE_STRING, + LBC_TYPE_TABLE, + LBC_TYPE_FUNCTION, + LBC_TYPE_THREAD, + LBC_TYPE_USERDATA, + LBC_TYPE_VECTOR, + LBC_TYPE_BUFFER, + + LBC_TYPE_ANY = 15, + + LBC_TYPE_TAGGED_USERDATA_BASE = 64, + LBC_TYPE_TAGGED_USERDATA_END = 64 + 32, + + LBC_TYPE_OPTIONAL_BIT = 1 << 7, + + LBC_TYPE_INVALID = 256, +}; + +// Builtin function ids, used in LOP_FASTCALL +enum LuauBuiltinFunction +{ + LBF_NONE = 0, + + // assert() + LBF_ASSERT, + + // math. + LBF_MATH_ABS, + LBF_MATH_ACOS, + LBF_MATH_ASIN, + LBF_MATH_ATAN2, + LBF_MATH_ATAN, + LBF_MATH_CEIL, + LBF_MATH_COSH, + LBF_MATH_COS, + LBF_MATH_DEG, + LBF_MATH_EXP, + LBF_MATH_FLOOR, + LBF_MATH_FMOD, + LBF_MATH_FREXP, + LBF_MATH_LDEXP, + LBF_MATH_LOG10, + LBF_MATH_LOG, + LBF_MATH_MAX, + LBF_MATH_MIN, + LBF_MATH_MODF, + LBF_MATH_POW, + LBF_MATH_RAD, + LBF_MATH_SINH, + LBF_MATH_SIN, + LBF_MATH_SQRT, + LBF_MATH_TANH, + LBF_MATH_TAN, + + // bit32. + LBF_BIT32_ARSHIFT, + LBF_BIT32_BAND, + LBF_BIT32_BNOT, + LBF_BIT32_BOR, + LBF_BIT32_BXOR, + LBF_BIT32_BTEST, + LBF_BIT32_EXTRACT, + LBF_BIT32_LROTATE, + LBF_BIT32_LSHIFT, + LBF_BIT32_REPLACE, + LBF_BIT32_RROTATE, + LBF_BIT32_RSHIFT, + + // type() + LBF_TYPE, + + // string. + LBF_STRING_BYTE, + LBF_STRING_CHAR, + LBF_STRING_LEN, + + // typeof() + LBF_TYPEOF, + + // string. + LBF_STRING_SUB, + + // math. + LBF_MATH_CLAMP, + LBF_MATH_SIGN, + LBF_MATH_ROUND, + + // raw* + LBF_RAWSET, + LBF_RAWGET, + LBF_RAWEQUAL, + + // table. + LBF_TABLE_INSERT, + LBF_TABLE_UNPACK, + + // vector ctor + LBF_VECTOR, + + // bit32.count + LBF_BIT32_COUNTLZ, + LBF_BIT32_COUNTRZ, + + // select(_, ...) + LBF_SELECT_VARARG, + + // rawlen + LBF_RAWLEN, + + // bit32.extract(_, k, k) + LBF_BIT32_EXTRACTK, + + // get/setmetatable + LBF_GETMETATABLE, + LBF_SETMETATABLE, + + // tonumber/tostring + LBF_TONUMBER, + LBF_TOSTRING, + + // bit32.byteswap(n) + LBF_BIT32_BYTESWAP, + + // buffer. + LBF_BUFFER_READI8, + LBF_BUFFER_READU8, + LBF_BUFFER_WRITEU8, + LBF_BUFFER_READI16, + LBF_BUFFER_READU16, + LBF_BUFFER_WRITEU16, + LBF_BUFFER_READI32, + LBF_BUFFER_READU32, + LBF_BUFFER_WRITEU32, + LBF_BUFFER_READF32, + LBF_BUFFER_WRITEF32, + LBF_BUFFER_READF64, + LBF_BUFFER_WRITEF64, + + // vector. + LBF_VECTOR_MAGNITUDE, + LBF_VECTOR_NORMALIZE, + LBF_VECTOR_CROSS, + LBF_VECTOR_DOT, + LBF_VECTOR_FLOOR, + LBF_VECTOR_CEIL, + LBF_VECTOR_ABS, + LBF_VECTOR_SIGN, + LBF_VECTOR_CLAMP, + LBF_VECTOR_MIN, + LBF_VECTOR_MAX, + + // math.lerp + LBF_MATH_LERP, + + // vector.lerp + LBF_VECTOR_LERP, + + // math. + LBF_MATH_ISNAN, + LBF_MATH_ISINF, + LBF_MATH_ISFINITE, + + // Rive Vector (2D-optimized). Pinned at the end of the 256-slot + // luauF_table to avoid collision with future upstream additions. + // New entries are added before the block (grow downward from 255). + LBF_RIVE_VECTOR_DISTANCE = 245, + LBF_RIVE_VECTOR_DISTANCE_SQUARED, + LBF_RIVE_VECTOR_ORIGIN, + LBF_RIVE_VECTOR_LENGTH_SQUARED, + LBF_RIVE_VECTOR2_DOT, + LBF_RIVE_VECTOR2_MAGNITUDE, + LBF_RIVE_VECTOR2_NORMALIZE, + LBF_RIVE_VECTOR2_LERP, + LBF_RIVE_VECTOR2_CROSS, + LBF_RIVE_VECTOR2_SCALE_AND_ADD, + LBF_RIVE_VECTOR2_SCALE_AND_SUB, +}; + +// Capture type, used in LOP_CAPTURE +enum LuauCaptureType +{ + LCT_VAL = 0, + LCT_REF, + LCT_UPVAL, +}; + +// Proto flag bitmask, stored in Proto::flags +enum LuauProtoFlag +{ + // used to tag main proto for modules with --!native + LPF_NATIVE_MODULE = 1 << 0, + // used to tag individual protos as not profitable to compile natively + LPF_NATIVE_COLD = 1 << 1, + // used to tag main proto for modules that have at least one function with native attribute + LPF_NATIVE_FUNCTION = 1 << 2, +}; diff --git a/thirdparty/luau/upstream/Common/include/Luau/BytecodeUtils.h b/thirdparty/luau/upstream/Common/include/Luau/BytecodeUtils.h new file mode 100644 index 000000000..6f1103118 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/BytecodeUtils.h @@ -0,0 +1,43 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/Bytecode.h" + +namespace Luau +{ + +inline int getOpLength(LuauOpcode op) +{ + switch (op) + { + case LOP_GETGLOBAL: + case LOP_SETGLOBAL: + case LOP_GETIMPORT: + case LOP_GETTABLEKS: + case LOP_SETTABLEKS: + case LOP_NAMECALL: + case LOP_JUMPIFEQ: + case LOP_JUMPIFLE: + case LOP_JUMPIFLT: + case LOP_JUMPIFNOTEQ: + case LOP_JUMPIFNOTLE: + case LOP_JUMPIFNOTLT: + case LOP_NEWTABLE: + case LOP_SETLIST: + case LOP_FORGLOOP: + case LOP_LOADKX: + case LOP_FASTCALL2: + case LOP_FASTCALL2K: + case LOP_FASTCALL3: + case LOP_JUMPXEQKNIL: + case LOP_JUMPXEQKB: + case LOP_JUMPXEQKN: + case LOP_JUMPXEQKS: + return 2; + + default: + return 1; + } +} + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/Common.h b/thirdparty/luau/upstream/Common/include/Luau/Common.h new file mode 100644 index 000000000..b4bbf0f73 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/Common.h @@ -0,0 +1,150 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +// Compiler codegen control macros +#ifdef _MSC_VER +#define LUAU_NORETURN __declspec(noreturn) +#define LUAU_NOINLINE __declspec(noinline) +#define LUAU_FORCEINLINE __forceinline +#define LUAU_LIKELY(x) x +#define LUAU_UNLIKELY(x) x +#define LUAU_UNREACHABLE() __assume(false) +#define LUAU_DEBUGBREAK() __debugbreak() +#else +#define LUAU_NORETURN __attribute__((__noreturn__)) +#define LUAU_NOINLINE __attribute__((noinline)) +#define LUAU_FORCEINLINE inline __attribute__((always_inline)) +#define LUAU_LIKELY(x) __builtin_expect(x, 1) +#define LUAU_UNLIKELY(x) __builtin_expect(x, 0) +#define LUAU_UNREACHABLE() __builtin_unreachable() +#define LUAU_DEBUGBREAK() __builtin_trap() +#endif + +// LUAU_FALLTHROUGH is a C++11-compatible alternative to [[fallthrough]] for use in the VM library +#if defined(__clang__) && defined(__has_warning) +#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#define LUAU_FALLTHROUGH [[clang::fallthrough]] +#else +#define LUAU_FALLTHROUGH +#endif +#elif defined(__GNUC__) && __GNUC__ >= 7 +#define LUAU_FALLTHROUGH [[gnu::fallthrough]] +#else +#define LUAU_FALLTHROUGH +#endif + +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define LUAU_BIG_ENDIAN +#endif + +namespace Luau +{ + +using AssertHandler = int (*)(const char* expression, const char* file, int line, const char* function); + +inline AssertHandler& assertHandler() +{ + static AssertHandler handler = nullptr; + return handler; +} + +// We want 'inline' to correctly link this function declared in the header +// But we also want to prevent compiler from inlining this function when optimization and assertions are enabled together +// Reason for that is that compilation times can increase significantly in such a configuration +LUAU_NOINLINE inline int assertCallHandler(const char* expression, const char* file, int line, const char* function) +{ + if (AssertHandler handler = assertHandler()) + return handler(expression, file, line, function); + + return 1; +} + +} // namespace Luau + +#if !defined(NDEBUG) || defined(LUAU_ENABLE_ASSERT) +#define LUAU_ASSERT(expr) ((void)(!!(expr) || (Luau::assertCallHandler(#expr, __FILE__, __LINE__, __FUNCTION__) && (LUAU_DEBUGBREAK(), 0)))) +#define LUAU_ASSERTENABLED +#else +#define LUAU_ASSERT(expr) (void)sizeof(!!(expr)) +#endif + +namespace Luau +{ + +template +struct FValue +{ + static FValue* list; + + T value; + bool dynamic; + const char* name; + FValue* next; + + FValue(const char* name, T def, bool dynamic) + : value(def) + , dynamic(dynamic) + , name(name) + , next(list) + { + list = this; + } + + LUAU_FORCEINLINE operator T() const + { + return value; + } +}; + +template +FValue* FValue::list = nullptr; + +} // namespace Luau + +#define LUAU_FASTFLAG(flag) \ + namespace FFlag \ + { \ + extern Luau::FValue flag; \ + } +#define LUAU_FASTFLAGVARIABLE(flag) \ + namespace FFlag \ + { \ + Luau::FValue flag(#flag, false, false); \ + } +#define LUAU_FASTINT(flag) \ + namespace FInt \ + { \ + extern Luau::FValue flag; \ + } +#define LUAU_FASTINTVARIABLE(flag, def) \ + namespace FInt \ + { \ + Luau::FValue flag(#flag, def, false); \ + } + +#define LUAU_DYNAMIC_FASTFLAG(flag) \ + namespace DFFlag \ + { \ + extern Luau::FValue flag; \ + } +#define LUAU_DYNAMIC_FASTFLAGVARIABLE(flag, def) \ + namespace DFFlag \ + { \ + Luau::FValue flag(#flag, def, true); \ + } +#define LUAU_DYNAMIC_FASTINT(flag) \ + namespace DFInt \ + { \ + extern Luau::FValue flag; \ + } +#define LUAU_DYNAMIC_FASTINTVARIABLE(flag, def) \ + namespace DFInt \ + { \ + Luau::FValue flag(#flag, def, true); \ + } + +#if defined(__GNUC__) +#define LUAU_PRINTF_ATTR(fmt, arg) __attribute__((format(printf, fmt, arg))) +#else +#define LUAU_PRINTF_ATTR(fmt, arg) +#endif diff --git a/thirdparty/luau/upstream/Common/include/Luau/DenseHash.h b/thirdparty/luau/upstream/Common/include/Luau/DenseHash.h new file mode 100644 index 000000000..1548152af --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/DenseHash.h @@ -0,0 +1,656 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/HashUtil.h" +#include "Luau/Common.h" + +#include +#include +#include +#include +#include + +namespace Luau +{ + +// Internal implementation of DenseHashSet and DenseHashMap +namespace detail +{ + +template +class DenseHashTable +{ +public: + class const_iterator; + class iterator; + + explicit DenseHashTable(const Key& empty_key, size_t buckets = 0) + : data(nullptr) + , capacity(0) + , count(0) + , empty_key(empty_key) + { + // validate that equality operator is at least somewhat functional + LUAU_ASSERT(eq(empty_key, empty_key)); + // buckets has to be power-of-two or zero + LUAU_ASSERT((buckets & (buckets - 1)) == 0); + + if (buckets) + { + data = static_cast(::operator new(sizeof(Item) * buckets)); + capacity = buckets; + + ItemInterface::fill(data, buckets, empty_key); + } + } + + ~DenseHashTable() + { + if (data) + destroy(); + } + + DenseHashTable(const DenseHashTable& other) + : data(nullptr) + , capacity(0) + , count(other.count) + , empty_key(other.empty_key) + { + if (other.capacity) + { + data = static_cast(::operator new(sizeof(Item) * other.capacity)); + + for (size_t i = 0; i < other.capacity; ++i) + { + new (&data[i]) Item(other.data[i]); + capacity = i + 1; // if Item copy throws, capacity will note the number of initialized objects for destroy() to clean up + } + } + } + + DenseHashTable(DenseHashTable&& other) + : data(other.data) + , capacity(other.capacity) + , count(other.count) + , empty_key(other.empty_key) + { + other.data = nullptr; + other.capacity = 0; + other.count = 0; + } + + DenseHashTable& operator=(DenseHashTable&& other) + { + if (this != &other) + { + if (data) + destroy(); + + data = other.data; + capacity = other.capacity; + count = other.count; + empty_key = other.empty_key; + + other.data = nullptr; + other.capacity = 0; + other.count = 0; + } + + return *this; + } + + DenseHashTable& operator=(const DenseHashTable& other) + { + if (this != &other) + { + DenseHashTable copy(other); + *this = std::move(copy); + } + + return *this; + } + + void clear(size_t thresholdToDestroy = 32) + { + if (count == 0) + return; + + if (capacity > thresholdToDestroy) + { + destroy(); + } + else + { + ItemInterface::destroy(data, capacity); + ItemInterface::fill(data, capacity, empty_key); + } + + count = 0; + } + + void destroy() + { + ItemInterface::destroy(data, capacity); + + ::operator delete(data); + data = nullptr; + + capacity = 0; + } + + Item* insert_unsafe(const Key& key) + { + // It is invalid to insert empty_key into the table since it acts as a "entry does not exist" marker + LUAU_ASSERT(!eq(key, empty_key)); + + size_t hashmod = capacity - 1; + size_t bucket = hasher(key) & hashmod; + + for (size_t probe = 0; probe <= hashmod; ++probe) + { + Item& probe_item = data[bucket]; + + // Element does not exist, insert here + if (eq(ItemInterface::getKey(probe_item), empty_key)) + { + ItemInterface::setKey(probe_item, key); + count++; + return &probe_item; + } + + // Element already exists + if (eq(ItemInterface::getKey(probe_item), key)) + { + return &probe_item; + } + + // Hash collision, quadratic probing + bucket = (bucket + probe + 1) & hashmod; + } + + // Hash table is full - this should not happen + LUAU_ASSERT(false); + return NULL; + } + + const Item* find(const Key& key) const + { + if (count == 0) + return 0; + if (eq(key, empty_key)) + return 0; + + size_t hashmod = capacity - 1; + size_t bucket = hasher(key) & hashmod; + + for (size_t probe = 0; probe <= hashmod; ++probe) + { + const Item& probe_item = data[bucket]; + + // Element exists + if (eq(ItemInterface::getKey(probe_item), key)) + return &probe_item; + + // Element does not exist + if (eq(ItemInterface::getKey(probe_item), empty_key)) + return NULL; + + // Hash collision, quadratic probing + bucket = (bucket + probe + 1) & hashmod; + } + + // Hash table is full - this should not happen + LUAU_ASSERT(false); + return NULL; + } + + void rehash() + { + size_t newsize = capacity == 0 ? 16 : capacity * 2; + + DenseHashTable newtable(empty_key, newsize); + + for (size_t i = 0; i < capacity; ++i) + { + const Key& key = ItemInterface::getKey(data[i]); + + if (!eq(key, empty_key)) + { + Item* item = newtable.insert_unsafe(key); + *item = std::move(data[i]); + } + } + + LUAU_ASSERT(count == newtable.count); + + std::swap(data, newtable.data); + std::swap(capacity, newtable.capacity); + } + + void rehash_if_full(const Key& key) + { + if (count >= capacity * 3 / 4 && !find(key)) + { + rehash(); + } + } + + const_iterator begin() const + { + size_t start = 0; + + while (start < capacity && eq(ItemInterface::getKey(data[start]), empty_key)) + start++; + + return const_iterator(this, start); + } + + const_iterator end() const + { + return const_iterator(this, capacity); + } + + iterator begin() + { + size_t start = 0; + + while (start < capacity && eq(ItemInterface::getKey(data[start]), empty_key)) + start++; + + return iterator(this, start); + } + + iterator end() + { + return iterator(this, capacity); + } + + size_t size() const + { + return count; + } + + class const_iterator + { + public: + using value_type = Item; + using reference = Item&; + using pointer = Item*; + using difference_type = ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + const_iterator() + : set(0) + , index(0) + { + } + + const_iterator(const DenseHashTable* set, size_t index) + : set(set) + , index(index) + { + } + + const Item& operator*() const + { + return set->data[index]; + } + + const Item* operator->() const + { + return &set->data[index]; + } + + bool operator==(const const_iterator& other) const + { + return set == other.set && index == other.index; + } + + bool operator!=(const const_iterator& other) const + { + return set != other.set || index != other.index; + } + + const_iterator& operator++() + { + size_t size = set->capacity; + + do + { + index++; + } while (index < size && set->eq(ItemInterface::getKey(set->data[index]), set->empty_key)); + + return *this; + } + + const_iterator operator++(int) + { + const_iterator res = *this; + ++*this; + return res; + } + + private: + const DenseHashTable* set; + size_t index; + }; + + class iterator + { + public: + using value_type = MutableItem; + using reference = MutableItem&; + using pointer = MutableItem*; + using difference_type = ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + iterator() + : set(0) + , index(0) + { + } + + iterator(DenseHashTable* set, size_t index) + : set(set) + , index(index) + { + } + + MutableItem& operator*() const + { + return *reinterpret_cast(&set->data[index]); + } + + MutableItem* operator->() const + { + return reinterpret_cast(&set->data[index]); + } + + bool operator==(const iterator& other) const + { + return set == other.set && index == other.index; + } + + bool operator!=(const iterator& other) const + { + return set != other.set || index != other.index; + } + + iterator& operator++() + { + size_t size = set->capacity; + + do + { + index++; + } while (index < size && set->eq(ItemInterface::getKey(set->data[index]), set->empty_key)); + + return *this; + } + + iterator operator++(int) + { + iterator res = *this; + ++*this; + return res; + } + + private: + DenseHashTable* set; + size_t index; + }; + +private: + Item* data; + size_t capacity; + size_t count; + Key empty_key; + Hash hasher; + Eq eq; +}; + +template +struct ItemInterfaceSet +{ + static const Key& getKey(const Key& item) + { + return item; + } + + static void setKey(Key& item, const Key& key) + { + item = key; + } + + static void fill(Key* data, size_t count, const Key& key) + { + for (size_t i = 0; i < count; ++i) + new (&data[i]) Key(key); + } + + static void destroy(Key* data, size_t count) + { + for (size_t i = 0; i < count; ++i) + data[i].~Key(); + } +}; + +template +struct ItemInterfaceMap +{ + static const Key& getKey(const std::pair& item) + { + return item.first; + } + + static void setKey(std::pair& item, const Key& key) + { + item.first = key; + } + + static void fill(std::pair* data, size_t count, const Key& key) + { + for (size_t i = 0; i < count; ++i) + { + new (&data[i].first) Key(key); + new (&data[i].second) Value(); + } + } + + static void destroy(std::pair* data, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + data[i].first.~Key(); + data[i].second.~Value(); + } + } +}; + +} // namespace detail + +// This is a faster alternative of unordered_set, but it does not implement the same interface (i.e. it does not support erasing) +template, typename Eq = std::equal_to> +class DenseHashSet +{ + typedef detail::DenseHashTable, Hash, Eq> Impl; + Impl impl; + +public: + typedef typename Impl::const_iterator const_iterator; + typedef typename Impl::iterator iterator; + + explicit DenseHashSet(const Key& empty_key, size_t buckets = 0) + : impl(empty_key, buckets) + { + } + + void clear() + { + impl.clear(); + } + + const Key& insert(const Key& key) + { + impl.rehash_if_full(key); + return *impl.insert_unsafe(key); + } + + const Key* find(const Key& key) const + { + return impl.find(key); + } + + bool contains(const Key& key) const + { + return impl.find(key) != 0; + } + + size_t size() const + { + return impl.size(); + } + + bool empty() const + { + return impl.size() == 0; + } + + const_iterator begin() const + { + return impl.begin(); + } + + const_iterator end() const + { + return impl.end(); + } + + iterator begin() + { + return impl.begin(); + } + + iterator end() + { + return impl.end(); + } + + bool operator==(const DenseHashSet& other) const + { + if (size() != other.size()) + return false; + + for (const Key& k : *this) + { + if (!other.contains(k)) + return false; + } + + return true; + } + + bool operator!=(const DenseHashSet& other) const + { + return !(*this == other); + } +}; + +// This is a faster alternative of unordered_map, but it does not implement the same interface (i.e. it does not support erasing and has +// contains() instead of find()) +template, typename Eq = std::equal_to> +class DenseHashMap +{ + typedef detail::DenseHashTable, std::pair, detail::ItemInterfaceMap, Hash, Eq> Impl; + Impl impl; + +public: + typedef typename Impl::const_iterator const_iterator; + typedef typename Impl::iterator iterator; + + explicit DenseHashMap(const Key& empty_key, size_t buckets = 0) + : impl(empty_key, buckets) + { + } + + void clear(size_t thresholdToDestroy = 32) + { + impl.clear(thresholdToDestroy); + } + + // Note: this reference is invalidated by any insert operation (i.e. operator[]) + Value& operator[](const Key& key) + { + impl.rehash_if_full(key); + return impl.insert_unsafe(key)->second; + } + + // Note: this pointer is invalidated by any insert operation (i.e. operator[]) + const Value* find(const Key& key) const + { + const std::pair* result = impl.find(key); + + return result ? &result->second : NULL; + } + + // Note: this pointer is invalidated by any insert operation (i.e. operator[]) + Value* find(const Key& key) + { + const std::pair* result = impl.find(key); + + return result ? const_cast(&result->second) : NULL; + } + + bool contains(const Key& key) const + { + return impl.find(key) != 0; + } + + std::pair try_insert(const Key& key, const Value& value) + { + impl.rehash_if_full(key); + + size_t before = impl.size(); + std::pair* slot = impl.insert_unsafe(key); + + // Value is fresh if container count has increased + bool fresh = impl.size() > before; + + if (fresh) + slot->second = value; + + return std::make_pair(std::ref(slot->second), fresh); + } + + size_t size() const + { + return impl.size(); + } + + bool empty() const + { + return impl.size() == 0; + } + + const_iterator begin() const + { + return impl.begin(); + } + + const_iterator end() const + { + return impl.end(); + } + + iterator begin() + { + return impl.begin(); + } + + iterator end() + { + return impl.end(); + } +}; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/ExperimentalFlags.h b/thirdparty/luau/upstream/Common/include/Luau/ExperimentalFlags.h new file mode 100644 index 000000000..e874a52d3 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/ExperimentalFlags.h @@ -0,0 +1,31 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include + +namespace Luau +{ + +inline bool isAnalysisFlagExperimental(const char* flag) +{ + // Flags in this list are disabled by default in various command-line tools. They may have behavior that is not fully final, + // or critical bugs that are found after the code has been submitted. This list is intended _only_ for flags that affect + // Luau's type checking. Flags that may change runtime behavior (e.g.: parser or VM flags) are not appropriate for this list. + static const char* const kList[] = { + "LuauInstantiateInSubtyping", // requires some fixes to lua-apps code + "LuauFixIndexerSubtypingOrdering", // requires some small fixes to lua-apps code since this fixes a false negative + "LuauSolverV2", + "UseNewLuauTypeSolverDefaultEnabled", // This can change the default solver used in cli applications, so it also needs to be disabled. Will + // require fixes in lua-apps code + // makes sure we always have at least one entry + nullptr, + }; + + for (const char* item : kList) + if (item && strcmp(item, flag) == 0) + return true; + + return false; +} + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/HashUtil.h b/thirdparty/luau/upstream/Common/include/Luau/HashUtil.h new file mode 100644 index 000000000..6184fa720 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/HashUtil.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Luau/Common.h" + +#include +#include + +#include +#include +#include + +namespace Luau +{ + +struct DenseHashPointer +{ + size_t operator()(const void* key) const + { + return (uintptr_t(key) >> 4) ^ (uintptr_t(key) >> 9); + } +}; + +namespace detail +{ + +template +using DenseHashDefault = std::conditional_t, DenseHashPointer, std::hash>; + +} // namespace detail + +inline void hashCombine(size_t& seed, size_t hash) +{ + // Golden Ratio constant used for better hash scattering + // See https://softwareengineering.stackexchange.com/a/402543 + seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + +template, typename H2 = detail::DenseHashDefault> +struct PairHash +{ + std::size_t operator()(const std::pair& p) const noexcept + { + std::size_t seed = 0; + hashCombine(seed, h1(p.first)); + hashCombine(seed, h2(p.second)); + return seed; + } + +private: + H1 h1; + H2 h2; +}; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/InsertionOrderedMap.h b/thirdparty/luau/upstream/Common/include/Luau/InsertionOrderedMap.h new file mode 100644 index 000000000..e99bad06b --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/InsertionOrderedMap.h @@ -0,0 +1,147 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/Common.h" + +#include +#include +#include +#include + +namespace Luau +{ + +template +struct InsertionOrderedMap +{ + static_assert(std::is_trivially_copyable_v, "key must be trivially copyable"); + +private: + using vec = std::vector>; + +public: + using iterator = typename vec::iterator; + using const_iterator = typename vec::const_iterator; + + void insert(K k, V v) + { + if (indices.count(k) != 0) + return; + + pairs.push_back(std::make_pair(k, std::move(v))); + indices[k] = pairs.size() - 1; + } + + void clear() + { + pairs.clear(); + indices.clear(); + } + + size_t size() const + { + LUAU_ASSERT(pairs.size() == indices.size()); + return pairs.size(); + } + + bool contains(const K& k) const + { + return indices.count(k) > 0; + } + + const V* get(const K& k) const + { + auto it = indices.find(k); + if (it == indices.end()) + return nullptr; + else + return &pairs.at(it->second).second; + } + + V* get(const K& k) + { + auto it = indices.find(k); + if (it == indices.end()) + return nullptr; + else + return &pairs.at(it->second).second; + } + + V& operator[](const K& k) + { + auto it = indices.find(k); + if (it == indices.end()) + { + pairs.push_back(std::make_pair(k, V())); + indices[k] = pairs.size() - 1; + return pairs.back().second; + } + else + return pairs.at(it->second).second; + } + + const_iterator begin() const + { + return pairs.begin(); + } + + const_iterator end() const + { + return pairs.end(); + } + + iterator begin() + { + return pairs.begin(); + } + + iterator end() + { + return pairs.end(); + } + + const_iterator find(K k) const + { + auto indicesIt = indices.find(k); + if (indicesIt == indices.end()) + return end(); + else + return begin() + indicesIt->second; + } + + iterator find(K k) + { + auto indicesIt = indices.find(k); + if (indicesIt == indices.end()) + return end(); + else + return begin() + indicesIt->second; + } + + void erase(iterator it) + { + if (it == pairs.end()) + return; + + K k = it->first; + auto indexIt = indices.find(k); + if (indexIt == indices.end()) + return; + + size_t removed = indexIt->second; + indices.erase(indexIt); + pairs.erase(it); + + for (auto& [_, index] : indices) + { + if (index > removed) + --index; + } + } + +private: + vec pairs; + std::unordered_map indices; +}; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/ScopedSeenSet.h b/thirdparty/luau/upstream/Common/include/Luau/ScopedSeenSet.h new file mode 100644 index 000000000..dcee6af71 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/ScopedSeenSet.h @@ -0,0 +1,29 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +namespace Luau +{ + +template +struct ScopedSeenSet +{ + SetType& seen; + Key key; + + ScopedSeenSet(SetType& seen, Key key) + : seen(seen) + , key(key) + { + seen.insert(key); + } + + ~ScopedSeenSet() + { + seen.erase(key); + } + + ScopedSeenSet(const ScopedSeenSet&) = delete; + ScopedSeenSet& operator=(const ScopedSeenSet&) = delete; +}; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/SmallVector.h b/thirdparty/luau/upstream/Common/include/Luau/SmallVector.h new file mode 100644 index 000000000..49fe3c211 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/SmallVector.h @@ -0,0 +1,322 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/Common.h" + +#include +#include +#include +#include +#include + +namespace Luau +{ + +template +class SmallVector +{ + static_assert(std::is_nothrow_move_constructible::value, "T must be nothrow move constructible"); + +public: + using iterator = T*; + using const_iterator = const T*; + using value_type = T; + using reference = T&; + using const_reference = const T&; + + SmallVector() + { + ptr = reinterpret_cast(storage); + } + + SmallVector(std::initializer_list init) + : SmallVector() + { + LUAU_ASSERT(unsigned(init.size()) == init.size()); + + reserve(unsigned(init.size())); + + std::uninitialized_copy(init.begin(), init.end(), ptr); + count = unsigned(init.size()); + } + + SmallVector(const SmallVector& other) + : SmallVector() + { + reserve(other.count); + + std::uninitialized_copy(other.begin(), other.end(), ptr); + count = other.count; + } + + SmallVector(SmallVector&& other) noexcept + : SmallVector() + { + if (!other.is_heap()) + { + std::uninitialized_move(other.begin(), other.end(), ptr); + count = other.count; + + other.clear(); + } + else + { + ptr = other.ptr; + max = other.max; + count = other.count; + + other.ptr = reinterpret_cast(other.storage); + other.max = N; + other.count = 0; + } + } + + ~SmallVector() + { + clear(); + + if (is_heap()) + ::operator delete(ptr); + } + + SmallVector& operator=(const SmallVector& other) + { + if (this == &other) + return *this; + + if (other.count <= count) + { + std::copy(other.begin(), other.end(), begin()); + + while (count > other.count) + ptr[--count].~T(); + } + else + { + std::copy(other.begin(), other.begin() + count, begin()); + + reserve(other.count); + + std::uninitialized_copy(other.begin() + count, other.end(), ptr + count); + count = other.count; + } + + return *this; + } + + SmallVector& operator=(SmallVector&& other) noexcept + { + if (this != &other) + { + clear(); + + if (!other.is_heap()) + { + std::uninitialized_move(other.begin(), other.end(), begin()); + count = other.count; + + other.clear(); + } + else + { + if (is_heap()) + ::operator delete(ptr); + + ptr = other.ptr; + max = other.max; + count = other.count; + + other.ptr = reinterpret_cast(other.storage); + other.max = N; + other.count = 0; + } + } + + return *this; + } + + template + reference emplace_back(Args&&... args) + { + if (count == max) + grow(count + 1); + + new (&ptr[count]) T(std::forward(args)...); + return ptr[count++]; + } + + void push_back(const T& val) + { + if (count == max) + grow(count + 1); + + new (&ptr[count]) T(val); + count++; + } + + void push_back(T&& val) + { + if (count == max) + grow(count + 1); + + new (&ptr[count]) T(std::move(val)); + count++; + } + + T& front() + { + LUAU_ASSERT(count > 0); + return ptr[0]; + } + + const T& front() const + { + LUAU_ASSERT(count > 0); + return ptr[0]; + } + + T& back() + { + LUAU_ASSERT(count > 0); + return ptr[count - 1]; + } + + const T& back() const + { + LUAU_ASSERT(count > 0); + return ptr[count - 1]; + } + + bool empty() const noexcept + { + return count == 0; + } + + unsigned size() const noexcept + { + return count; + } + + unsigned capacity() const noexcept + { + return max; + } + + void pop_back() + { + LUAU_ASSERT(count > 0); + ptr[--count].~T(); + } + + void clear() + { + while (count > 0) + ptr[--count].~T(); + } + + T* begin() + { + return ptr; + } + + const T* begin() const + { + return ptr; + } + + T* end() + { + return ptr + count; + } + + const T* end() const + { + return ptr + count; + } + + T* data() + { + return ptr; + } + const T* data() const + { + return ptr; + } + + T& operator[](size_t index) + { + LUAU_ASSERT(index < count); + + return ptr[index]; + } + + const T& operator[](size_t index) const + { + LUAU_ASSERT(index < count); + + return ptr[index]; + } + + void resize(unsigned newSize) + { + if (newSize > count) + { + if (newSize > max) + grow(newSize); + + for (unsigned i = count; i < newSize; ++i) + new (&ptr[i]) T(); + } + else + { + while (count > newSize) + ptr[--count].~T(); + } + + count = newSize; + } + + void reserve(unsigned reserveSize) + { + if (reserveSize > max) + grow(reserveSize); + } + +private: + bool is_heap() const + { + return ptr != reinterpret_cast(storage); + } + + void grow(unsigned newSize) + { + if (max + (max >> 1) > newSize) + newSize = max + (max >> 1); + else + newSize += 4; + + LUAU_ASSERT(newSize < 0x40000000); + + void* raw = ::operator new(newSize * sizeof(T)); + T* newData = static_cast(raw); + + std::uninitialized_move(ptr, ptr + count, newData); + + for (unsigned i = 0; i < count; ++i) + ptr[i].~T(); + + if (is_heap()) + ::operator delete(ptr); + + ptr = newData; + max = newSize; + } + + T* ptr = nullptr; + unsigned count = 0; + unsigned max = N; + + alignas(T) unsigned char storage[N * sizeof(T)]; +}; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/StringUtils.h b/thirdparty/luau/upstream/Common/include/Luau/StringUtils.h new file mode 100644 index 000000000..fb16daa72 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/StringUtils.h @@ -0,0 +1,39 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/Common.h" + +#include +#include + +#include + +namespace Luau +{ + +std::string format(const char* fmt, ...) LUAU_PRINTF_ATTR(1, 2); +std::string vformat(const char* fmt, va_list args); + +void formatAppend(std::string& str, const char* fmt, ...) LUAU_PRINTF_ATTR(2, 3); +void vformatAppend(std::string& ret, const char* fmt, va_list args); + +std::string join(const std::vector& segments, std::string_view delimiter); +std::string join(const std::vector& segments, std::string_view delimiter); + +std::vector split(std::string_view s, char delimiter); + +// Computes the Damerau-Levenshtein distance of A and B. +// https://en.wikipedia.org/wiki/Damerau-Levenshtein_distance#Distance_with_adjacent_transpositions +size_t editDistance(std::string_view a, std::string_view b); + +bool startsWith(std::string_view lhs, std::string_view rhs); +bool equalsLower(std::string_view lhs, std::string_view rhs); + +size_t hashRange(const char* data, size_t size); + +std::string escape(std::string_view s, bool escapeForInterpString = false); +bool isIdentifier(std::string_view s); + +std::string_view strip(std::string_view s); + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/TimeTrace.h b/thirdparty/luau/upstream/Common/include/Luau/TimeTrace.h new file mode 100644 index 000000000..2259f21ce --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/TimeTrace.h @@ -0,0 +1,240 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/Common.h" + +#include +#include + +#include +#include + +LUAU_FASTFLAG(DebugLuauTimeTracing) + +namespace Luau +{ +namespace TimeTrace +{ +double getClock(); +uint32_t getClockMicroseconds(); +} // namespace TimeTrace +} // namespace Luau + +#if defined(LUAU_ENABLE_TIME_TRACE) + +namespace Luau +{ +namespace TimeTrace +{ +struct Token +{ + const char* name; + const char* category; +}; + +enum class EventType : uint8_t +{ + Enter, + Leave, + + ArgName, + ArgValue, +}; + +struct Event +{ + EventType type; + uint16_t token; + + union + { + uint32_t microsec; // 1 hour trace limit + uint32_t dataPos; + } data; +}; + +struct GlobalContext; +struct ThreadContext; + +std::shared_ptr getGlobalContext(); + +uint16_t createToken(GlobalContext& context, const char* name, const char* category); +uint32_t createThread(GlobalContext& context, ThreadContext* threadContext); +void releaseThread(GlobalContext& context, ThreadContext* threadContext); +void flushEvents(GlobalContext& context, uint32_t threadId, const std::vector& events, const std::vector& data); + +struct ThreadContext +{ + ThreadContext() + : globalContext(getGlobalContext()) + { + threadId = createThread(*globalContext, this); + } + + ~ThreadContext() + { + if (!events.empty()) + flushEvents(); + + releaseThread(*globalContext, this); + } + + void flushEvents() + { + static uint16_t flushToken = createToken(*globalContext, "flushEvents", "TimeTrace"); + + events.push_back({EventType::Enter, flushToken, {getClockMicroseconds()}}); + + TimeTrace::flushEvents(*globalContext, threadId, events, data); + + events.clear(); + data.clear(); + + events.push_back({EventType::Leave, 0, {getClockMicroseconds()}}); + } + + void eventEnter(uint16_t token) + { + eventEnter(token, getClockMicroseconds()); + } + + void eventEnter(uint16_t token, uint32_t microsec) + { + events.push_back({EventType::Enter, token, {microsec}}); + } + + void eventLeave() + { + eventLeave(getClockMicroseconds()); + } + + void eventLeave(uint32_t microsec) + { + events.push_back({EventType::Leave, 0, {microsec}}); + + if (events.size() > kEventFlushLimit) + flushEvents(); + } + + void eventArgument(const char* name, const char* value) + { + uint32_t pos = uint32_t(data.size()); + data.insert(data.end(), name, name + strlen(name) + 1); + events.push_back({EventType::ArgName, 0, {pos}}); + + pos = uint32_t(data.size()); + data.insert(data.end(), value, value + strlen(value) + 1); + events.push_back({EventType::ArgValue, 0, {pos}}); + } + + std::shared_ptr globalContext; + uint32_t threadId; + std::vector events; + std::vector data; + + static constexpr size_t kEventFlushLimit = 8192; +}; + +using ThreadContextProvider = ThreadContext& (*)(); + +inline ThreadContextProvider& threadContextProvider() +{ + static ThreadContextProvider handler = nullptr; + return handler; +} + +ThreadContext& getThreadContext(); + +struct Scope +{ + explicit Scope(uint16_t token) + : context(getThreadContext()) + { + if (!FFlag::DebugLuauTimeTracing) + return; + + context.eventEnter(token); + } + + ~Scope() + { + if (!FFlag::DebugLuauTimeTracing) + return; + + context.eventLeave(); + } + + ThreadContext& context; +}; + +struct OptionalTailScope +{ + explicit OptionalTailScope(uint16_t token, uint32_t threshold) + : context(getThreadContext()) + , token(token) + , threshold(threshold) + { + if (!FFlag::DebugLuauTimeTracing) + return; + + pos = uint32_t(context.events.size()); + microsec = getClockMicroseconds(); + } + + ~OptionalTailScope() + { + if (!FFlag::DebugLuauTimeTracing) + return; + + if (pos == context.events.size()) + { + uint32_t curr = getClockMicroseconds(); + + if (curr - microsec > threshold) + { + context.eventEnter(token, microsec); + context.eventLeave(curr); + } + } + } + + ThreadContext& context; + uint16_t token; + uint32_t threshold; + uint32_t microsec; + uint32_t pos; +}; + +LUAU_NOINLINE uint16_t createScopeData(const char* name, const char* category); + +} // namespace TimeTrace +} // namespace Luau + +// Regular scope +#define LUAU_TIMETRACE_SCOPE(name, category) \ + static uint16_t lttScopeStatic = Luau::TimeTrace::createScopeData(name, category); \ + Luau::TimeTrace::Scope lttScope(lttScopeStatic) + +// A scope without nested scopes that may be skipped if the time it took is less than the threshold +#define LUAU_TIMETRACE_OPTIONAL_TAIL_SCOPE(name, category, microsec) \ + static uint16_t lttScopeStaticOptTail = Luau::TimeTrace::createScopeData(name, category); \ + Luau::TimeTrace::OptionalTailScope lttScope(lttScopeStaticOptTail, microsec) + +// Extra key/value data can be added to regular scopes +#define LUAU_TIMETRACE_ARGUMENT(name, value) \ + do \ + { \ + if (FFlag::DebugLuauTimeTracing) \ + lttScope.context.eventArgument(name, value); \ + } while (false) + +#else + +#define LUAU_TIMETRACE_SCOPE(name, category) +#define LUAU_TIMETRACE_OPTIONAL_TAIL_SCOPE(name, category, microsec) +#define LUAU_TIMETRACE_ARGUMENT(name, value) \ + do \ + { \ + } while (false) + +#endif diff --git a/thirdparty/luau/upstream/Common/include/Luau/Variant.h b/thirdparty/luau/upstream/Common/include/Luau/Variant.h new file mode 100644 index 000000000..67ca34f98 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/Variant.h @@ -0,0 +1,304 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include +#include +#include +#include + +#include + +namespace Luau +{ + +template +class Variant +{ + static_assert(sizeof...(Ts) > 0, "variant must have at least 1 type (empty variants are ill-formed)"); + static_assert(std::disjunction_v...> == false, "variant does not allow void as an alternative type"); + static_assert(std::disjunction_v...> == false, "variant does not allow references as an alternative type"); + static_assert(std::disjunction_v...> == false, "variant does not allow arrays as an alternative type"); + +public: + template + static constexpr int getTypeId() + { + using TT = std::decay_t; + + constexpr int N = sizeof...(Ts); + constexpr bool is[N] = {std::is_same_v...}; + + for (int i = 0; i < N; ++i) + if (is[i]) + return i; + + return -1; + } + +private: + template + struct First + { + using type = T; + }; + +public: + using first_alternative = typename First::type; + + template + static constexpr bool is_part_of_v = std::disjunction_v, T>...>; + + Variant() + { + static_assert(std::is_default_constructible_v, "first alternative type must be default constructible"); + typeId = 0; + new (&storage) first_alternative(); + } + + template + Variant(T&& value, std::enable_if_t() >= 0>* = 0) + { + using TT = std::decay_t; + + constexpr int tid = getTypeId(); + typeId = tid; + new (&storage) TT(std::forward(value)); + } + + Variant(const Variant& other) + { + static constexpr FnCopy table[sizeof...(Ts)] = {&fnCopy...}; + + typeId = other.typeId; + table[typeId](&storage, &other.storage); + } + + Variant(Variant&& other) noexcept + { + typeId = other.typeId; + tableMove[typeId](&storage, &other.storage); + } + + ~Variant() + { + tableDtor[typeId](&storage); + } + + Variant& operator=(const Variant& other) + { + Variant copy(other); + // static_cast is equivalent to std::move() but faster in Debug + return *this = static_cast(copy); + } + + Variant& operator=(Variant&& other) noexcept + { + if (this != &other) + { + tableDtor[typeId](&storage); + typeId = other.typeId; + tableMove[typeId](&storage, &other.storage); // nothrow + } + return *this; + } + + template + T& emplace(Args&&... args) + { + using TT = std::decay_t; + constexpr int tid = getTypeId(); + static_assert(tid >= 0, "unsupported T"); + + tableDtor[typeId](&storage); + typeId = tid; + new (&storage) TT{std::forward(args)...}; + + return *reinterpret_cast(&storage); + } + + template + const T* get_if() const + { + constexpr int tid = getTypeId(); + static_assert(tid >= 0, "unsupported T"); + + return tid == typeId ? reinterpret_cast(&storage) : nullptr; + } + + template + T* get_if() + { + constexpr int tid = getTypeId(); + static_assert(tid >= 0, "unsupported T"); + + return tid == typeId ? reinterpret_cast(&storage) : nullptr; + } + + bool valueless_by_exception() const + { + return false; + } + + int index() const + { + return typeId; + } + + bool operator==(const Variant& other) const + { + static constexpr FnPred table[sizeof...(Ts)] = {&fnPredEq...}; + + return typeId == other.typeId && table[typeId](&storage, &other.storage); + } + + bool operator!=(const Variant& other) const + { + return !(*this == other); + } + +private: + static constexpr size_t cmax(std::initializer_list l) + { + size_t res = 0; + for (size_t i : l) + res = (res < i) ? i : res; + return res; + } + + static constexpr size_t storageSize = cmax({sizeof(Ts)...}); + static constexpr size_t storageAlign = cmax({alignof(Ts)...}); + + using FnCopy = void (*)(void*, const void*); + using FnMove = void (*)(void*, void*) noexcept; + using FnDtor = void (*)(void*); + using FnPred = bool (*)(const void*, const void*); + + template + static void fnCopy(void* dst, const void* src) + { + new (dst) T(*static_cast(src)); + } + + template + static void fnMove(void* dst, void* src) noexcept + { + // static_cast is equivalent to std::move() but faster in Debug + new (dst) T(static_cast(*static_cast(src))); + } + + template + static void fnDtor(void* dst) + { + static_cast(dst)->~T(); + } + + template + static bool fnPredEq(const void* lhs, const void* rhs) + { + return *static_cast(lhs) == *static_cast(rhs); + } + + static constexpr FnMove tableMove[sizeof...(Ts)] = {&fnMove...}; + static constexpr FnDtor tableDtor[sizeof...(Ts)] = {&fnDtor...}; + + int typeId; + alignas(storageAlign) char storage[storageSize]; + + template + friend auto visit(Visitor&& vis, const Variant<_Ts...>& var); + template + friend auto visit(Visitor&& vis, Variant<_Ts...>& var); +}; + +template +const T* get_if(const Variant* var) +{ + return var ? var->template get_if() : nullptr; +} + +template +T* get_if(Variant* var) +{ + return var ? var->template get_if() : nullptr; +} + +template +static void fnVisitR(Visitor& vis, Result& dst, std::conditional_t, const void, void>* src) +{ + dst = vis(*static_cast(src)); +} + +template +static void fnVisitV(Visitor& vis, std::conditional_t, const void, void>* src) +{ + vis(*static_cast(src)); +} + +template +auto visit(Visitor&& vis, const Variant& var) +{ + static_assert(std::conjunction_v...>, "visitor must accept every alternative as an argument"); + + using Result = std::invoke_result_t::first_alternative>; + static_assert( + std::conjunction_v>...>, "visitor result type must be consistent between alternatives" + ); + + if constexpr (std::is_same_v) + { + using FnVisitV = void (*)(Visitor&, const void*); + static const FnVisitV tableVisit[sizeof...(Ts)] = {&fnVisitV...}; + + tableVisit[var.typeId](vis, &var.storage); + } + else + { + using FnVisitR = void (*)(Visitor&, Result&, const void*); + static const FnVisitR tableVisit[sizeof...(Ts)] = {&fnVisitR...}; + + Result res; + tableVisit[var.typeId](vis, res, &var.storage); + return res; + } +} + +template +auto visit(Visitor&& vis, Variant& var) +{ + static_assert(std::conjunction_v...>, "visitor must accept every alternative as an argument"); + + using Result = std::invoke_result_t::first_alternative&>; + static_assert( + std::conjunction_v>...>, "visitor result type must be consistent between alternatives" + ); + + if constexpr (std::is_same_v) + { + using FnVisitV = void (*)(Visitor&, void*); + static const FnVisitV tableVisit[sizeof...(Ts)] = {&fnVisitV...}; + + tableVisit[var.typeId](vis, &var.storage); + } + else + { + using FnVisitR = void (*)(Visitor&, Result&, void*); + static const FnVisitR tableVisit[sizeof...(Ts)] = {&fnVisitR...}; + + Result res; + tableVisit[var.typeId](vis, res, &var.storage); + return res; + } +} + +template +struct overloaded : Ts... +{ + using Ts::operator()...; +}; +template +overloaded(Ts...) -> overloaded; + +template +inline constexpr bool always_false_v = false; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/include/Luau/VecDeque.h b/thirdparty/luau/upstream/Common/include/Luau/VecDeque.h new file mode 100644 index 000000000..0b3d88e55 --- /dev/null +++ b/thirdparty/luau/upstream/Common/include/Luau/VecDeque.h @@ -0,0 +1,476 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "Luau/Common.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace Luau +{ +// `VecDeque` is a general double-ended implementation designed as a drop-in replacement for the +// standard library `std::deque`. It's backed by a growable ring buffer, rather than using the +// segmented queue design of `std::deque` which can degrade into a linked list in the worst case. +// The motivation for `VecDeque` as a replacement is to maintain the asymptotic complexity of +// `std::deque` while reducing overall allocations and promoting better usage of the cache. Its API +// is intended to be compatible with `std::deque` and `std::vector` as appropriate, and as such +// provides corresponding method definitions and supports the use of custom allocators. +// +// `VecDeque` offers pushing and popping from both ends with an amortized O(1) complexity. It also +// supports `std::vector`-style random-access in O(1). The implementation of buffer resizing uses +// a growth factor of 1.5x to enable better memory reuse after resizing, and reduce overall memory +// fragmentation when using the queue. +// +// Since `VecDeque` is a ring buffer, its elements are not necessarily contiguous in memory. To +// describe this, we refer to the two portions of the buffer as the `head` and the `tail`. The +// `head` is the initial portion of the queue that is on the range `[head, capacity)` and the tail +// is the (optionally) remaining portion on the range `[0, head + size - capacity)` whenever the +// `head + size` exceeds the capacity of the buffer. +// +// `VecDeque` does not currently support iteration since its primary focus is on providing +// double-ended queue functionality specifically, but it can be reasonably expanded to provide +// an iterator if we have a use-case for one in the future. +template> +class VecDeque : Allocator +{ +private: + static_assert(std::is_nothrow_move_constructible_v); + static_assert(std::is_nothrow_move_assignable_v); + + T* buffer = nullptr; // the existing allocation we have backing this queue + size_t buffer_capacity = 0; // the size of our allocation + + size_t head = 0; // the index of the head of the queue + size_t queue_size = 0; // the size of the queue + + void destroyElements() noexcept + { + size_t head_size = + std::min(queue_size, capacity() - head); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + // we have to destroy every element in the head portion + for (size_t index = head; index < head + head_size; index++) + buffer[index].~T(); + + // and any in the tail portion, if one exists + for (size_t index = 0; index < tail_size; index++) + buffer[index].~T(); + } + + bool is_full() + { + return queue_size == capacity(); + } + + void grow() + { + size_t old_capacity = capacity(); + + // we use a growth factor of 1.5x (plus a constant) here in order to enable the + // previous memory to be reused after a certain number of calls to grow. + // see: https://github.com/facebook/folly/blob/main/folly/docs/FBVector.md#memory-handling + size_t new_capacity = (old_capacity > 0) ? old_capacity * 3 / 2 + 1 : 4; + + // check that it's a legal allocation + if (new_capacity > max_size()) + throw std::bad_array_new_length(); + + // allocate a new backing buffer + T* new_buffer = this->allocate(new_capacity); + + // we should not be growing if the capacity is not the current size + LUAU_ASSERT(old_capacity == queue_size); + + size_t head_size = + std::min(queue_size, old_capacity - head); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + // move the head into the new buffer + if (head_size != 0) + std::uninitialized_move(buffer + head, buffer + head + head_size, new_buffer); + + // move the tail into the new buffer immediately after + if (tail_size != 0) + std::uninitialized_move(buffer, buffer + tail_size, new_buffer + head_size); + + // destroy the old elements + destroyElements(); + // deallocate the old buffer + this->deallocate(buffer, old_capacity); + + // set up the queue to be backed by the new buffer + buffer = new_buffer; + buffer_capacity = new_capacity; + head = 0; + } + + size_t logicalToPhysical(size_t pos) + { + return (head + pos) % capacity(); + } + +public: + VecDeque() = default; + + explicit VecDeque(const Allocator& alloc) noexcept + : Allocator{alloc} + { + } + + VecDeque(const VecDeque& other) + : buffer(this->allocate(other.buffer_capacity)) + , buffer_capacity(other.buffer_capacity) + , head(other.head) + , queue_size(other.queue_size) + { + // copy the initialized contents of the other buffer to this one + size_t head_size = std::min( + other.queue_size, + other.buffer_capacity - other.head + ); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = other.queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + if (head_size != 0) + std::uninitialized_copy(other.buffer + other.head, other.buffer + other.head + head_size, buffer + head); + + if (tail_size != 0) + std::uninitialized_copy(other.buffer, other.buffer + tail_size, buffer); + } + + VecDeque(const VecDeque& other, const Allocator& alloc) + : Allocator{alloc} + , buffer(this->allocate(other.buffer_capacity)) + , buffer_capacity(other.buffer_capacity) + , head(other.head) + , queue_size(other.queue_size) + { + // copy the initialized contents of the other buffer to this one + size_t head_size = std::min( + other.queue_size, + other.buffer_capacity - other.head + ); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = other.queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + if (head_size != 0) + std::uninitialized_copy(other.buffer + other.head, other.buffer + other.head + head_size, buffer + head); + + if (tail_size != 0) + std::uninitialized_copy(other.buffer, other.buffer + tail_size, buffer); + } + + VecDeque(VecDeque&& other) noexcept + : buffer(std::exchange(other.buffer, nullptr)) + , buffer_capacity(std::exchange(other.buffer_capacity, 0)) + , head(std::exchange(other.head, 0)) + , queue_size(std::exchange(other.queue_size, 0)) + { + } + + VecDeque(VecDeque&& other, const Allocator& alloc) noexcept + : Allocator{alloc} + , buffer(std::exchange(other.buffer, nullptr)) + , buffer_capacity(std::exchange(other.buffer_capacity, 0)) + , head(std::exchange(other.head, 0)) + , queue_size(std::exchange(other.queue_size, 0)) + { + } + + VecDeque(std::initializer_list init, const Allocator& alloc = Allocator()) + : Allocator{alloc} + { + buffer = this->allocate(init.size()); + buffer_capacity = init.size(); + queue_size = init.size(); + + std::uninitialized_copy(init.begin(), init.end(), buffer); + } + + ~VecDeque() noexcept + { + // destroy any elements that exist + destroyElements(); + // free the allocated buffer + this->deallocate(buffer, buffer_capacity); + } + + VecDeque& operator=(const VecDeque& other) + { + if (this == &other) + return *this; + + // destroy all of the existing elements + destroyElements(); + + if (buffer_capacity < other.size()) + { + // free the current buffer + this->deallocate(buffer, buffer_capacity); + + buffer = this->allocate(other.buffer_capacity); + buffer_capacity = other.buffer_capacity; + } + + size_t head_size = std::min( + other.queue_size, + other.buffer_capacity - other.head + ); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = other.queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + // Assignment doesn't try to match the capacity of 'other' and thus makes the buffer contiguous + head = 0; + queue_size = other.queue_size; + + if (head_size != 0) + std::uninitialized_copy(other.buffer + other.head, other.buffer + other.head + head_size, buffer); + + if (tail_size != 0) + std::uninitialized_copy(other.buffer, other.buffer + tail_size, buffer + head_size); + + return *this; + } + + VecDeque& operator=(VecDeque&& other) + { + if (this == &other) + return *this; + + // destroy all of the existing elements + destroyElements(); + // free the current buffer + this->deallocate(buffer, buffer_capacity); + + buffer = std::exchange(other.buffer, nullptr); + buffer_capacity = std::exchange(other.buffer_capacity, 0); + head = std::exchange(other.head, 0); + queue_size = std::exchange(other.queue_size, 0); + + return *this; + } + + Allocator get_allocator() const noexcept + { + return this; + } + + // element access + + T& at(size_t pos) + { + if (pos >= queue_size) + throw std::out_of_range("VecDeque"); + + return buffer[logicalToPhysical(pos)]; + } + + const T& at(size_t pos) const + { + if (pos >= queue_size) + throw std::out_of_range("VecDeque"); + + return buffer[logicalToPhysical(pos)]; + } + + [[nodiscard]] T& operator[](size_t pos) noexcept + { + LUAU_ASSERT(pos < queue_size); + + return buffer[logicalToPhysical(pos)]; + } + + [[nodiscard]] const T& operator[](size_t pos) const noexcept + { + LUAU_ASSERT(pos < queue_size); + + return buffer[logicalToPhysical(pos)]; + } + + T& front() + { + LUAU_ASSERT(!empty()); + + return buffer[head]; + } + + const T& front() const + { + LUAU_ASSERT(!empty()); + + return buffer[head]; + } + + T& back() + { + LUAU_ASSERT(!empty()); + + size_t back = logicalToPhysical(queue_size - 1); + return buffer[back]; + } + + const T& back() const + { + LUAU_ASSERT(!empty()); + + size_t back = logicalToPhysical(queue_size - 1); + return buffer[back]; + } + + // capacity + + bool empty() const noexcept + { + return queue_size == 0; + } + + size_t size() const noexcept + { + return queue_size; + } + + size_t max_size() const noexcept + { + return std::numeric_limits::max() / sizeof(T); + } + + void reserve(size_t new_capacity) + { + // error if this allocation would be illegal + if (new_capacity > max_size()) + throw std::length_error("too large"); + + size_t old_capacity = capacity(); + + // do nothing if we're requesting a capacity that would not cause growth + if (new_capacity <= old_capacity) + return; + + size_t head_size = + std::min(queue_size, old_capacity - head); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + // allocate a new backing buffer + T* new_buffer = this->allocate(new_capacity); + + // move the head into the new buffer + if (head_size != 0) + std::uninitialized_move(buffer + head, buffer + head + head_size, new_buffer); + + // move the tail into the new buffer immediately after + if (tail_size != 0) + std::uninitialized_move(buffer, buffer + tail_size, new_buffer + head_size); + + // destroy all the existing elements before freeing the old buffer + destroyElements(); + + // deallocate the old buffer + this->deallocate(buffer, old_capacity); + + // set up the queue to be backed by the new buffer + buffer = new_buffer; + buffer_capacity = new_capacity; + head = 0; + } + + size_t capacity() const noexcept + { + return buffer_capacity; + } + + void shrink_to_fit() + { + size_t old_capacity = capacity(); + size_t new_capacity = queue_size; + + if (old_capacity == new_capacity) + return; + + size_t head_size = + std::min(queue_size, old_capacity - head); // how many elements are in the head portion (i.e. from the head to the end of the buffer) + size_t tail_size = queue_size - head_size; // how many elements are in the tail portion (i.e. any portion that wrapped to the front) + + // allocate a new backing buffer + T* new_buffer = this->allocate(new_capacity); + + // move the head into the new buffer + if (head_size != 0) + std::uninitialized_move(buffer + head, buffer + head + head_size, new_buffer); + + // move the tail into the new buffer immediately after, if we have one + if (tail_size != 0) + std::uninitialized_move(buffer, buffer + tail_size, new_buffer + head_size); + + // destroy all the existing elements before freeing the old buffer + destroyElements(); + // deallocate the old buffer + this->deallocate(buffer, old_capacity); + + // set up the queue to be backed by the new buffer + buffer = new_buffer; + buffer_capacity = new_capacity; + head = 0; + } + + [[nodiscard]] bool is_contiguous() const noexcept + { + // this is an overflow-safe alternative to writing `head + size <= capacity`. + return head <= capacity() - queue_size; + } + + // modifiers + + void clear() noexcept + { + destroyElements(); + + head = 0; + queue_size = 0; + } + + void push_back(const T& value) + { + if (is_full()) + grow(); + + size_t next_back = logicalToPhysical(queue_size); + new (buffer + next_back) T(value); + queue_size++; + } + + void pop_back() + { + LUAU_ASSERT(!empty()); + + queue_size--; + size_t next_back = logicalToPhysical(queue_size); + buffer[next_back].~T(); + } + + void push_front(const T& value) + { + if (is_full()) + grow(); + + head = (head == 0) ? capacity() - 1 : head - 1; + new (buffer + head) T(value); + queue_size++; + } + + void pop_front() + { + LUAU_ASSERT(!empty()); + + buffer[head].~T(); + head++; + queue_size--; + + if (head == capacity()) + head = 0; + } +}; + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/src/StringUtils.cpp b/thirdparty/luau/upstream/Common/src/StringUtils.cpp new file mode 100644 index 000000000..3ca8bb346 --- /dev/null +++ b/thirdparty/luau/upstream/Common/src/StringUtils.cpp @@ -0,0 +1,315 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include "Luau/StringUtils.h" + +#include "Luau/Common.h" + +#include +#include +#include +#include +#include + +namespace Luau +{ + +void vformatAppend(std::string& ret, const char* fmt, va_list args) +{ + va_list argscopy; + va_copy(argscopy, args); +#ifdef _MSC_VER + int actualSize = _vscprintf(fmt, argscopy); +#else + int actualSize = vsnprintf(NULL, 0, fmt, argscopy); +#endif + va_end(argscopy); + + if (actualSize <= 0) + return; + + size_t sz = ret.size(); + ret.resize(sz + actualSize); + vsnprintf(&ret[0] + sz, actualSize + 1, fmt, args); +} + +std::string format(const char* fmt, ...) +{ + std::string result; + va_list args; + va_start(args, fmt); + vformatAppend(result, fmt, args); + va_end(args); + return result; +} + +void formatAppend(std::string& str, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + vformatAppend(str, fmt, args); + va_end(args); +} + +std::string vformat(const char* fmt, va_list args) +{ + std::string ret; + vformatAppend(ret, fmt, args); + return ret; +} + +template +static std::string joinImpl(const std::vector& segments, std::string_view delimiter) +{ + if (segments.empty()) + return ""; + + size_t len = (segments.size() - 1) * delimiter.size(); + for (const auto& sv : segments) + len += sv.size(); + + std::string result; + result.resize(len); + char* dest = const_cast(result.data()); // This const_cast is only necessary until C++17 + + auto it = segments.begin(); + memcpy(dest, it->data(), it->size()); + dest += it->size(); + ++it; + for (; it != segments.end(); ++it) + { + memcpy(dest, delimiter.data(), delimiter.size()); + dest += delimiter.size(); + memcpy(dest, it->data(), it->size()); + dest += it->size(); + } + + LUAU_ASSERT(dest == result.data() + len); + + return result; +} + +std::string join(const std::vector& segments, std::string_view delimiter) +{ + return joinImpl(segments, delimiter); +} + +std::string join(const std::vector& segments, std::string_view delimiter) +{ + return joinImpl(segments, delimiter); +} + +std::vector split(std::string_view s, char delimiter) +{ + std::vector result; + + while (!s.empty()) + { + auto index = s.find(delimiter); + if (index == std::string::npos) + { + result.push_back(s); + break; + } + result.push_back(s.substr(0, index)); + s.remove_prefix(index + 1); + } + + return result; +} + +size_t editDistance(std::string_view a, std::string_view b) +{ + // When there are matching prefix and suffix, they end up computing as zero cost, effectively making it no-op. We drop these characters. + while (!a.empty() && !b.empty() && a.front() == b.front()) + { + a.remove_prefix(1); + b.remove_prefix(1); + } + + while (!a.empty() && !b.empty() && a.back() == b.back()) + { + a.remove_suffix(1); + b.remove_suffix(1); + } + + // Since we know the edit distance is the difference of the length of A and B discounting the matching prefixes and suffixes, + // it is therefore pointless to run the rest of this function to find that out. We immediately infer this size and return it. + if (a.empty()) + return b.size(); + if (b.empty()) + return a.size(); + + size_t maxDistance = a.size() + b.size(); + + std::vector distances((a.size() + 2) * (b.size() + 2), 0); + auto getPos = [b](size_t x, size_t y) -> size_t + { + return (x * (b.size() + 2)) + y; + }; + + distances[0] = maxDistance; + + for (size_t x = 0; x <= a.size(); ++x) + { + distances[getPos(x + 1, 0)] = maxDistance; + distances[getPos(x + 1, 1)] = x; + } + + for (size_t y = 0; y <= b.size(); ++y) + { + distances[getPos(0, y + 1)] = maxDistance; + distances[getPos(1, y + 1)] = y; + } + + std::array seenCharToRow; + seenCharToRow.fill(0); + + for (size_t x = 1; x <= a.size(); ++x) + { + size_t lastMatchedY = 0; + + for (size_t y = 1; y <= b.size(); ++y) + { + // The value of b[N] can be negative with unicode characters + unsigned char bSeenCharIndex = static_cast(b[y - 1]); + size_t x1 = seenCharToRow[bSeenCharIndex]; + size_t y1 = lastMatchedY; + + size_t cost = 1; + if (a[x - 1] == b[y - 1]) + { + cost = 0; + lastMatchedY = y; + } + + size_t transposition = distances[getPos(x1, y1)] + (x - x1 - 1) + 1 + (y - y1 - 1); + size_t substitution = distances[getPos(x, y)] + cost; + size_t insertion = distances[getPos(x, y + 1)] + 1; + size_t deletion = distances[getPos(x + 1, y)] + 1; + + // It's more performant to use std::min(size_t, size_t) rather than the initializer_list overload. + // Until proven otherwise, please do not change this. + distances[getPos(x + 1, y + 1)] = std::min(std::min(insertion, deletion), std::min(substitution, transposition)); + } + + // The value of a[N] can be negative with unicode characters + unsigned char aSeenCharIndex = static_cast(a[x - 1]); + seenCharToRow[aSeenCharIndex] = x; + } + + return distances[getPos(a.size() + 1, b.size() + 1)]; +} + +bool startsWith(std::string_view haystack, std::string_view needle) +{ + // ::starts_with is C++20 + return haystack.size() >= needle.size() && haystack.substr(0, needle.size()) == needle; +} + +bool equalsLower(std::string_view lhs, std::string_view rhs) +{ + if (lhs.size() != rhs.size()) + return false; + + for (size_t i = 0; i < lhs.size(); ++i) + if (tolower(uint8_t(lhs[i])) != tolower(uint8_t(rhs[i]))) + return false; + + return true; +} + +size_t hashRange(const char* data, size_t size) +{ + // FNV-1a + uint32_t hash = 2166136261; + + for (size_t i = 0; i < size; ++i) + { + hash ^= uint8_t(data[i]); + hash *= 16777619; + } + + return hash; +} + +bool isIdentifier(std::string_view s) +{ + return (s.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_") == std::string::npos); +} + +std::string escape(std::string_view s, bool escapeForInterpString) +{ + std::string r; + r.reserve(s.size() + 50); // arbitrary number to guess how many characters we'll be inserting + + for (uint8_t c : s) + { + if (c >= ' ' && c != '\\' && c != '\'' && c != '\"' && c != '`' && c != '{') + r += c; + else + { + r += '\\'; + + if (escapeForInterpString && (c == '`' || c == '{')) + { + r += c; + continue; + } + + switch (c) + { + case '\a': + r += 'a'; + break; + case '\b': + r += 'b'; + break; + case '\f': + r += 'f'; + break; + case '\n': + r += 'n'; + break; + case '\r': + r += 'r'; + break; + case '\t': + r += 't'; + break; + case '\v': + r += 'v'; + break; + case '\'': + r += '\''; + break; + case '\"': + r += '\"'; + break; + case '\\': + r += '\\'; + break; + default: + Luau::formatAppend(r, "%03u", c); + } + } + } + + return r; +} + +static bool isWhitespace(char c) +{ + return c == ' ' || c == '\n' || c == '\r' || c == '\t'; +} + +std::string_view strip(std::string_view s) +{ + while (!s.empty() && isWhitespace(s.front())) + s.remove_prefix(1); + + while (!s.empty() && isWhitespace(s.back())) + s.remove_suffix(1); + + return s; +} + +} // namespace Luau diff --git a/thirdparty/luau/upstream/Common/src/TimeTrace.cpp b/thirdparty/luau/upstream/Common/src/TimeTrace.cpp new file mode 100644 index 000000000..24bc707f1 --- /dev/null +++ b/thirdparty/luau/upstream/Common/src/TimeTrace.cpp @@ -0,0 +1,278 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include "Luau/TimeTrace.h" + +#include "Luau/StringUtils.h" + +#include +#include +#include + +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#endif + +#ifdef __APPLE__ +#include +#include +#endif + +#include + +LUAU_FASTFLAGVARIABLE(DebugLuauTimeTracing) +namespace Luau +{ +namespace TimeTrace +{ +static double getClockPeriod() +{ +#if defined(_WIN32) + LARGE_INTEGER result = {}; + QueryPerformanceFrequency(&result); + return 1.0 / double(result.QuadPart); +#elif defined(__APPLE__) + mach_timebase_info_data_t result = {}; + mach_timebase_info(&result); + return double(result.numer) / double(result.denom) * 1e-9; +#elif defined(__linux__) || defined(__FreeBSD__) + return 1e-9; +#else + return 1.0 / double(CLOCKS_PER_SEC); +#endif +} + +static double getClockTimestamp() +{ +#if defined(_WIN32) + LARGE_INTEGER result = {}; + QueryPerformanceCounter(&result); + return double(result.QuadPart); +#elif defined(__APPLE__) + return double(mach_absolute_time()); +#elif defined(__linux__) || defined(__FreeBSD__) + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + return now.tv_sec * 1e9 + now.tv_nsec; +#else + return double(clock()); +#endif +} + +double getClock() +{ + static double period = getClockPeriod(); + static double start = getClockTimestamp(); + + return (getClockTimestamp() - start) * period; +} + +uint32_t getClockMicroseconds() +{ + static double period = getClockPeriod() * 1e6; + static double start = getClockTimestamp(); + + return uint32_t((getClockTimestamp() - start) * period); +} +} // namespace TimeTrace +} // namespace Luau + +#if defined(LUAU_ENABLE_TIME_TRACE) + +namespace Luau +{ +namespace TimeTrace +{ +struct GlobalContext +{ + ~GlobalContext() + { + if (traceFile) + fclose(traceFile); + } + + std::mutex mutex; + std::vector threads; + uint32_t nextThreadId = 0; + std::vector tokens; + FILE* traceFile = nullptr; + +private: + friend std::shared_ptr getGlobalContext(); + GlobalContext() = default; +}; + +std::shared_ptr getGlobalContext() +{ + static std::shared_ptr context = std::shared_ptr{new GlobalContext}; + return context; +} + +uint16_t createToken(GlobalContext& context, const char* name, const char* category) +{ + std::scoped_lock lock(context.mutex); + + LUAU_ASSERT(context.tokens.size() < 64 * 1024); + + context.tokens.push_back({name, category}); + return uint16_t(context.tokens.size() - 1); +} + +uint32_t createThread(GlobalContext& context, ThreadContext* threadContext) +{ + std::scoped_lock lock(context.mutex); + + context.threads.push_back(threadContext); + + return ++context.nextThreadId; +} + +void releaseThread(GlobalContext& context, ThreadContext* threadContext) +{ + std::scoped_lock lock(context.mutex); + + if (auto it = std::find(context.threads.begin(), context.threads.end(), threadContext); it != context.threads.end()) + context.threads.erase(it); +} + +void flushEvents(GlobalContext& context, uint32_t threadId, const std::vector& events, const std::vector& data) +{ + std::scoped_lock lock(context.mutex); + + if (!context.traceFile) + { + context.traceFile = fopen("trace.json", "w"); + + if (!context.traceFile) + return; + + fprintf(context.traceFile, "[\n"); + } + + std::string temp; + const unsigned tempReserve = 64 * 1024; + temp.reserve(tempReserve); + + const char* rawData = data.data(); + + // Formatting state + bool unfinishedEnter = false; + bool unfinishedArgs = false; + + for (const Event& ev : events) + { + switch (ev.type) + { + case EventType::Enter: + { + if (unfinishedArgs) + { + formatAppend(temp, "}"); + unfinishedArgs = false; + } + + if (unfinishedEnter) + { + formatAppend(temp, "},\n"); + unfinishedEnter = false; + } + + Token& token = context.tokens[ev.token]; + + formatAppend( + temp, + R"({"name": "%s", "cat": "%s", "ph": "B", "ts": %u, "pid": 0, "tid": %u)", + token.name, + token.category, + ev.data.microsec, + threadId + ); + unfinishedEnter = true; + } + break; + case EventType::Leave: + if (unfinishedArgs) + { + formatAppend(temp, "}"); + unfinishedArgs = false; + } + if (unfinishedEnter) + { + formatAppend(temp, "},\n"); + unfinishedEnter = false; + } + + formatAppend( + temp, + R"({"ph": "E", "ts": %u, "pid": 0, "tid": %u},)" + "\n", + ev.data.microsec, + threadId + ); + break; + case EventType::ArgName: + LUAU_ASSERT(unfinishedEnter); + + if (!unfinishedArgs) + { + formatAppend(temp, R"(, "args": { "%s": )", rawData + ev.data.dataPos); + unfinishedArgs = true; + } + else + { + formatAppend(temp, R"(, "%s": )", rawData + ev.data.dataPos); + } + break; + case EventType::ArgValue: + LUAU_ASSERT(unfinishedArgs); + formatAppend(temp, R"("%s")", rawData + ev.data.dataPos); + break; + } + + // Don't want to hit the string capacity and reallocate + if (temp.size() > tempReserve - 1024) + { + fwrite(temp.data(), 1, temp.size(), context.traceFile); + temp.clear(); + } + } + + if (unfinishedArgs) + { + formatAppend(temp, "}"); + unfinishedArgs = false; + } + if (unfinishedEnter) + { + formatAppend(temp, "},\n"); + unfinishedEnter = false; + } + + fwrite(temp.data(), 1, temp.size(), context.traceFile); + fflush(context.traceFile); +} + +ThreadContext& getThreadContext() +{ + // Check custom provider that which might implement a custom TLS + if (auto provider = threadContextProvider()) + return provider(); + + thread_local ThreadContext context; + return context; +} + +uint16_t createScopeData(const char* name, const char* category) +{ + return createToken(*Luau::TimeTrace::getGlobalContext(), name, category); +} +} // namespace TimeTrace +} // namespace Luau + +#endif diff --git a/thirdparty/luau/upstream/VM/include/lua.h b/thirdparty/luau/upstream/VM/include/lua.h new file mode 100644 index 000000000..b0e2cf3c5 --- /dev/null +++ b/thirdparty/luau/upstream/VM/include/lua.h @@ -0,0 +1,502 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include +#include +#include + +#include "luaconf.h" + + + +// option for multiple returns in `lua_pcall' and `lua_call' +#define LUA_MULTRET (-1) + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-LUAI_MAXCSTACK - 2000) +#define LUA_ENVIRONINDEX (-LUAI_MAXCSTACK - 2001) +#define LUA_GLOBALSINDEX (-LUAI_MAXCSTACK - 2002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX - (i)) +#define lua_ispseudo(i) ((i) <= LUA_REGISTRYINDEX) + +// thread status; 0 is OK +enum lua_Status +{ + LUA_OK = 0, + LUA_YIELD, + LUA_ERRRUN, + LUA_ERRSYNTAX, // legacy error code, preserved for compatibility + LUA_ERRMEM, + LUA_ERRERR, + LUA_BREAK, // yielded for a debug breakpoint +}; + +enum lua_CoStatus +{ + LUA_CORUN = 0, // running + LUA_COSUS, // suspended + LUA_CONOR, // 'normal' (it resumed another coroutine) + LUA_COFIN, // finished + LUA_COERR, // finished with error +}; + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction)(lua_State* L); +typedef int (*lua_Continuation)(lua_State* L, int status); + +/* +** prototype for memory-allocation functions +*/ + +typedef void* (*lua_Alloc)(void* ud, void* ptr, size_t osize, size_t nsize); + +// non-return type +#define l_noret void LUA_NORETURN + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +/* + * WARNING: if you change the order of this enumeration, + * grep "ORDER TYPE" + */ +// clang-format off +enum lua_Type +{ + LUA_TNIL = 0, // must be 0 due to lua_isnoneornil + LUA_TBOOLEAN = 1, // must be 1 due to l_isfalse + + LUA_TLIGHTUSERDATA, + LUA_TNUMBER, + LUA_TVECTOR, + + LUA_TSTRING, // all types above this must be value types, all types below this must be GC types - see iscollectable + + LUA_TTABLE, + LUA_TFUNCTION, + LUA_TUSERDATA, + LUA_TTHREAD, + LUA_TBUFFER, + + // values below this line are used in GCObject tags but may never show up in TValue type tags + LUA_TPROTO, + LUA_TUPVAL, + LUA_TDEADKEY, + + // the count of TValue type tags + LUA_T_COUNT = LUA_TPROTO +}; +// clang-format on + +// type of numbers in Luau +typedef double lua_Number; + +// type for integer functions +typedef int lua_Integer; + +// unsigned integer type +typedef unsigned lua_Unsigned; + +/* +** state manipulation +*/ +LUA_API lua_State* lua_newstate(lua_Alloc f, void* ud); +LUA_API void lua_close(lua_State* L); +LUA_API lua_State* lua_newthread(lua_State* L); +LUA_API lua_State* lua_mainthread(lua_State* L); +LUA_API void lua_resetthread(lua_State* L); +LUA_API int lua_isthreadreset(lua_State* L); + +/* +** basic stack manipulation +*/ +LUA_API int lua_absindex(lua_State* L, int idx); +LUA_API int lua_gettop(lua_State* L); +LUA_API void lua_settop(lua_State* L, int idx); +LUA_API void lua_pushvalue(lua_State* L, int idx); +LUA_API void lua_remove(lua_State* L, int idx); +LUA_API void lua_insert(lua_State* L, int idx); +LUA_API void lua_replace(lua_State* L, int idx); +LUA_API int lua_checkstack(lua_State* L, int sz); +LUA_API void lua_rawcheckstack(lua_State* L, int sz); // allows for unlimited stack frames + +LUA_API void lua_xmove(lua_State* from, lua_State* to, int n); +LUA_API void lua_xpush(lua_State* from, lua_State* to, int idx); + +/* +** access functions (stack -> C) +*/ + +LUA_API int lua_isnumber(lua_State* L, int idx); +LUA_API int lua_isstring(lua_State* L, int idx); +LUA_API int lua_iscfunction(lua_State* L, int idx); +LUA_API int lua_isLfunction(lua_State* L, int idx); +LUA_API int lua_isuserdata(lua_State* L, int idx); +LUA_API int lua_type(lua_State* L, int idx); +LUA_API const char* lua_typename(lua_State* L, int tp); + +LUA_API int lua_equal(lua_State* L, int idx1, int idx2); +LUA_API int lua_rawequal(lua_State* L, int idx1, int idx2); +LUA_API int lua_lessthan(lua_State* L, int idx1, int idx2); + +LUA_API double lua_tonumberx(lua_State* L, int idx, int* isnum); +LUA_API int lua_tointegerx(lua_State* L, int idx, int* isnum); +LUA_API unsigned lua_tounsignedx(lua_State* L, int idx, int* isnum); +LUA_API const float* lua_tovector(lua_State* L, int idx); +LUA_API int lua_toboolean(lua_State* L, int idx); +LUA_API const char* lua_tolstring(lua_State* L, int idx, size_t* len); +LUA_API const char* lua_tostringatom(lua_State* L, int idx, int* atom); +LUA_API const char* lua_tolstringatom(lua_State* L, int idx, size_t* len, int* atom); +LUA_API const char* lua_namecallatom(lua_State* L, int* atom); +LUA_API int lua_objlen(lua_State* L, int idx); +LUA_API lua_CFunction lua_tocfunction(lua_State* L, int idx); +LUA_API void* lua_tolightuserdata(lua_State* L, int idx); +LUA_API void* lua_tolightuserdatatagged(lua_State* L, int idx, int tag); +LUA_API void* lua_touserdata(lua_State* L, int idx); +LUA_API void* lua_touserdatatagged(lua_State* L, int idx, int tag); +LUA_API int lua_userdatatag(lua_State* L, int idx); +LUA_API int lua_lightuserdatatag(lua_State* L, int idx); +LUA_API lua_State* lua_tothread(lua_State* L, int idx); +LUA_API void* lua_tobuffer(lua_State* L, int idx, size_t* len); +LUA_API const void* lua_topointer(lua_State* L, int idx); + +/* +** push functions (C -> stack) +*/ +LUA_API void lua_pushnil(lua_State* L); +LUA_API void lua_pushnumber(lua_State* L, double n); +LUA_API void lua_pushinteger(lua_State* L, int n); +LUA_API void lua_pushunsigned(lua_State* L, unsigned n); +#if LUA_VECTOR_SIZE == 4 +LUA_API void lua_pushvector(lua_State* L, float x, float y, float z, float w); +#else +LUA_API void lua_pushvector(lua_State* L, float x, float y, float z); +#endif +LUA_API void lua_pushvector2(lua_State* L, float x, float y); +LUA_API void lua_pushlstring(lua_State* L, const char* s, size_t l); +LUA_API void lua_pushstring(lua_State* L, const char* s); +LUA_API const char* lua_pushvfstring(lua_State* L, const char* fmt, va_list argp); +LUA_API LUA_PRINTF_ATTR(2, 3) const char* lua_pushfstringL(lua_State* L, const char* fmt, ...); +LUA_API void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debugname, int nup, lua_Continuation cont); +LUA_API void lua_pushboolean(lua_State* L, int b); +LUA_API int lua_pushthread(lua_State* L); + +LUA_API void lua_pushlightuserdatatagged(lua_State* L, void* p, int tag); +LUA_API void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag); +LUA_API void* lua_newuserdatataggedwithmetatable(lua_State* L, size_t sz, int tag); // metatable fetched with lua_getuserdatametatable +LUA_API void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*)); + +LUA_API void* lua_newbuffer(lua_State* L, size_t sz); + +/* +** get functions (Lua -> stack) +*/ +LUA_API int lua_gettable(lua_State* L, int idx); +LUA_API int lua_getfield(lua_State* L, int idx, const char* k); +LUA_API int lua_rawgetfield(lua_State* L, int idx, const char* k); +LUA_API int lua_rawget(lua_State* L, int idx); +LUA_API int lua_rawgeti(lua_State* L, int idx, int n); +LUA_API int lua_rawgetptagged(lua_State* L, int idx, void* p, int tag); +LUA_API void lua_createtable(lua_State* L, int narr, int nrec); + +LUA_API void lua_setreadonly(lua_State* L, int idx, int enabled); +LUA_API int lua_getreadonly(lua_State* L, int idx); +LUA_API void lua_setsafeenv(lua_State* L, int idx, int enabled); + +LUA_API int lua_getmetatable(lua_State* L, int objindex); +LUA_API void lua_getfenv(lua_State* L, int idx); + +/* +** set functions (stack -> Lua) +*/ +LUA_API void lua_settable(lua_State* L, int idx); +LUA_API void lua_setfield(lua_State* L, int idx, const char* k); +LUA_API void lua_rawsetfield(lua_State* L, int idx, const char* k); +LUA_API void lua_rawset(lua_State* L, int idx); +LUA_API void lua_rawseti(lua_State* L, int idx, int n); +LUA_API void lua_rawsetptagged(lua_State* L, int idx, void* p, int tag); +LUA_API int lua_setmetatable(lua_State* L, int objindex); +LUA_API int lua_setfenv(lua_State* L, int idx); + +/* +** `load' and `call' functions (load and run Luau bytecode) +*/ +LUA_API int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env); +LUA_API void lua_call(lua_State* L, int nargs, int nresults); +LUA_API int lua_pcall(lua_State* L, int nargs, int nresults, int errfunc); +LUA_API int lua_cpcall(lua_State* L, lua_CFunction func, void* ud); + +/* +** coroutine functions +*/ +LUA_API int lua_yield(lua_State* L, int nresults); +LUA_API int lua_break(lua_State* L); +LUA_API int lua_resume(lua_State* L, lua_State* from, int narg); +LUA_API int lua_resumeerror(lua_State* L, lua_State* from); +LUA_API int lua_status(lua_State* L); +LUA_API int lua_isyieldable(lua_State* L); +LUA_API void* lua_getthreaddata(lua_State* L); +LUA_API void lua_setthreaddata(lua_State* L, void* data); +LUA_API int lua_costatus(lua_State* L, lua_State* co); + +/* +** garbage-collection function and options +*/ + +enum lua_GCOp +{ + // stop and resume incremental garbage collection + LUA_GCSTOP, + LUA_GCRESTART, + + // run a full GC cycle; not recommended for latency sensitive applications + LUA_GCCOLLECT, + + // return the heap size in KB and the remainder in bytes + LUA_GCCOUNT, + LUA_GCCOUNTB, + + // return 1 if GC is active (not stopped); note that GC may not be actively collecting even if it's running + LUA_GCISRUNNING, + + /* + ** perform an explicit GC step, with the step size specified in KB + ** + ** garbage collection is handled by 'assists' that perform some amount of GC work matching pace of allocation + ** explicit GC steps allow to perform some amount of work at custom points to offset the need for GC assists + ** note that GC might also be paused for some duration (until bytes allocated meet the threshold) + ** if an explicit step is performed during this pause, it will trigger the start of the next collection cycle + */ + LUA_GCSTEP, + + /* + ** tune GC parameters G (goal), S (step multiplier) and step size (usually best left ignored) + ** + ** garbage collection is incremental and tries to maintain the heap size to balance memory and performance overhead + ** this overhead is determined by G (goal) which is the ratio between total heap size and the amount of live data in it + ** G is specified in percentages; by default G=200% which means that the heap is allowed to grow to ~2x the size of live data. + ** + ** collector tries to collect S% of allocated bytes by interrupting the application after step size bytes were allocated. + ** when S is too small, collector may not be able to catch up and the effective goal that can be reached will be larger. + ** S is specified in percentages; by default S=200% which means that collector will run at ~2x the pace of allocations. + ** + ** it is recommended to set S in the interval [100 / (G - 100), 100 + 100 / (G - 100))] with a minimum value of 150%; for example: + ** - for G=200%, S should be in the interval [150%, 200%] + ** - for G=150%, S should be in the interval [200%, 300%] + ** - for G=125%, S should be in the interval [400%, 500%] + */ + LUA_GCSETGOAL, + LUA_GCSETSTEPMUL, + LUA_GCSETSTEPSIZE, +}; + +LUA_API int lua_gc(lua_State* L, int what, int data); + +/* +** memory statistics +** all allocated bytes are attributed to the memory category of the running thread (0..LUA_MEMORY_CATEGORIES-1) +*/ + +LUA_API void lua_setmemcat(lua_State* L, int category); +LUA_API size_t lua_totalbytes(lua_State* L, int category); + +/* +** miscellaneous functions +*/ + +LUA_API l_noret lua_error(lua_State* L); + +LUA_API int lua_next(lua_State* L, int idx); +LUA_API int lua_rawiter(lua_State* L, int idx, int iter); + +LUA_API void lua_concat(lua_State* L, int n); + +LUA_API uintptr_t lua_encodepointer(lua_State* L, uintptr_t p); + +LUA_API double lua_clock(); + +LUA_API void lua_setuserdatatag(lua_State* L, int idx, int tag); + +typedef void (*lua_Destructor)(lua_State* L, void* userdata); + +LUA_API void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor); +LUA_API lua_Destructor lua_getuserdatadtor(lua_State* L, int tag); + +// alternative access for metatables already registered with luaL_newmetatable +// used by lua_newuserdatataggedwithmetatable to create tagged userdata with the associated metatable assigned +LUA_API void lua_setuserdatametatable(lua_State* L, int tag); +LUA_API void lua_getuserdatametatable(lua_State* L, int tag); + +LUA_API void lua_setlightuserdataname(lua_State* L, int tag, const char* name); +LUA_API const char* lua_getlightuserdataname(lua_State* L, int tag); + +LUA_API void lua_clonefunction(lua_State* L, int idx); + +LUA_API void lua_cleartable(lua_State* L, int idx); +LUA_API void lua_clonetable(lua_State* L, int idx); + +LUA_API lua_Alloc lua_getallocf(lua_State* L, void** ud); + +/* +** reference system, can be used to pin objects +*/ +#define LUA_NOREF -1 +#define LUA_REFNIL 0 + +LUA_API int lua_ref(lua_State* L, int idx); +LUA_API void lua_unref(lua_State* L, int ref); + +#define lua_getref(L, ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ +#define lua_tonumber(L, i) lua_tonumberx(L, i, NULL) +#define lua_tointeger(L, i) lua_tointegerx(L, i, NULL) +#define lua_tounsigned(L, i) lua_tounsignedx(L, i, NULL) + +#define lua_pop(L, n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) +#define lua_newuserdata(L, s) lua_newuserdatatagged(L, s, 0) + +#define lua_strlen(L, i) lua_objlen(L, (i)) + +#define lua_isfunction(L, n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L, n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L, n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L, n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L, n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isvector(L, n) (lua_type(L, (n)) == LUA_TVECTOR) +#define lua_isthread(L, n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isbuffer(L, n) (lua_type(L, (n)) == LUA_TBUFFER) +#define lua_isnone(L, n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= LUA_TNIL) + +#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1) +#define lua_pushcfunction(L, fn, debugname) lua_pushcclosurek(L, fn, debugname, 0, NULL) +#define lua_pushcclosure(L, fn, debugname, nup) lua_pushcclosurek(L, fn, debugname, nup, NULL) +#define lua_pushlightuserdata(L, p) lua_pushlightuserdatatagged(L, p, 0) + +#define lua_rawgetp(L, idx, p) lua_rawgetptagged(L, idx, p, 0) +#define lua_rawsetp(L, idx, p) lua_rawsetptagged(L, idx, p, 0) + +#define lua_setglobal(L, s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L, s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L, i) lua_tolstring(L, (i), NULL) + +#define lua_pushfstring(L, fmt, ...) lua_pushfstringL(L, fmt, ##__VA_ARGS__) + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + +typedef struct lua_Debug lua_Debug; // activation record + +// Functions to be called by the debugger in specific events +typedef void (*lua_Hook)(lua_State* L, lua_Debug* ar); + +LUA_API int lua_stackdepth(lua_State* L); +LUA_API int lua_getinfo(lua_State* L, int level, const char* what, lua_Debug* ar); +LUA_API int lua_getargument(lua_State* L, int level, int n); +LUA_API const char* lua_getlocal(lua_State* L, int level, int n); +LUA_API const char* lua_setlocal(lua_State* L, int level, int n); +LUA_API const char* lua_getupvalue(lua_State* L, int funcindex, int n); +LUA_API const char* lua_setupvalue(lua_State* L, int funcindex, int n); + +LUA_API void lua_singlestep(lua_State* L, int enabled); +LUA_API int lua_breakpoint(lua_State* L, int funcindex, int line, int enabled); + +typedef void (*lua_Coverage)(void* context, const char* function, int linedefined, int depth, const int* hits, size_t size); + +LUA_API void lua_getcoverage(lua_State* L, int funcindex, void* context, lua_Coverage callback); + +typedef void (*lua_CounterFunction)(void* context, const char* function, int linedefined); +typedef void (*lua_CounterValue)(void* context, int kind, int line, uint64_t hits); + +// Unlike 'lua_getcoverage', counters are customizable in ways which prevent merging them together +// 'lua_getcounters' will visit the specified function and all nested functions +// 'functionvisit' is called first to establish a function, then multiple calls of 'countervisit' are made for each counter in that function +LUA_API void lua_getcounters(lua_State* L, int funcindex, void* context, lua_CounterFunction functionvisit, lua_CounterValue countervisit); + +// Warning: this function is not thread-safe since it stores the result in a shared global array! Only use for debugging. +LUA_API const char* lua_debugtrace(lua_State* L); + +struct lua_Debug +{ + const char* name; // (n) + const char* what; // (s) `Lua', `C', `main', `tail' + const char* source; // (s) + const char* short_src; // (s) + int linedefined; // (s) + int currentline; // (l) + unsigned char nupvals; // (u) number of upvalues + unsigned char nparams; // (a) number of parameters + char isvararg; // (a) + void* userdata; // only valid in luau_callhook + + char ssbuf[LUA_IDSIZE]; +}; + +// }====================================================================== + +/* Callbacks that can be used to reconfigure behavior of the VM dynamically. + * These are shared between all coroutines. + * + * Note: interrupt is safe to set from an arbitrary thread but all other callbacks + * can only be changed when the VM is not running any code */ +struct lua_Callbacks +{ + void* userdata; // arbitrary userdata pointer that is never overwritten by Luau + + void (*interrupt)(lua_State* L, int gc); // gets called at safepoints (loop back edges, call/ret, gc) if set + void (*panic)(lua_State* L, int errcode); // gets called when an unprotected error is raised (if longjmp is used) + + void (*userthread)(lua_State* LP, lua_State* L); // gets called when L is created (LP == parent) or destroyed (LP == NULL) + int16_t (*useratom)(lua_State* L, const char* s, size_t l); // gets called when a string is created to assign an atom id + + void (*debugbreak)(lua_State* L, lua_Debug* ar); // gets called when BREAK instruction is encountered + void (*debugstep)(lua_State* L, lua_Debug* ar); // gets called after each instruction in single step mode + void (*debuginterrupt)(lua_State* L, lua_Debug* ar); // gets called when thread execution is interrupted by break in another thread + void (*debugprotectederror)(lua_State* L); // gets called when protected call results in an error + + void (*onallocate)(lua_State* L, size_t osize, size_t nsize); // gets called when memory is allocated +}; +typedef struct lua_Callbacks lua_Callbacks; + +LUA_API lua_Callbacks* lua_callbacks(lua_State* L); + +/****************************************************************************** + * Copyright (c) 2019-2023 Roblox Corporation + * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ******************************************************************************/ diff --git a/thirdparty/luau/upstream/VM/include/luaconf.h b/thirdparty/luau/upstream/VM/include/luaconf.h new file mode 100644 index 000000000..ed7adba68 --- /dev/null +++ b/thirdparty/luau/upstream/VM/include/luaconf.h @@ -0,0 +1,140 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +// When debugging complex issues, consider enabling one of these: +// This will reallocate the stack very aggressively at every opportunity; use this with asan to catch stale stack pointers +// #define HARDSTACKTESTS 1 +// This will call GC validation very aggressively at every incremental GC step; use this with caution as it's SLOW +// #define HARDMEMTESTS 1 +// This will call GC validation very aggressively at every GC opportunity; use this with caution as it's VERY SLOW +// #define HARDMEMTESTS 2 + +// To force MSVC2017+ to generate SSE2 code for some stdlib functions we need to locally enable /fp:fast +// Note that /fp:fast changes the semantics of floating point comparisons so this is only safe to do for functions without ones +#if defined(_MSC_VER) && !defined(__clang__) +#define LUAU_FASTMATH_BEGIN __pragma(float_control(precise, off, push)) +#define LUAU_FASTMATH_END __pragma(float_control(pop)) +#else +#define LUAU_FASTMATH_BEGIN +#define LUAU_FASTMATH_END +#endif + +// Some functions like floor/ceil have SSE4.1 equivalents but we currently support systems without SSE4.1 +// Note that we only need to do this when SSE4.1 support is not guaranteed by compiler settings, as otherwise compiler will optimize these for us. +#if (defined(__x86_64__) || defined(_M_X64)) && !defined(__SSE4_1__) && !defined(__AVX__) +#if defined(_MSC_VER) && !defined(__clang__) +#define LUAU_TARGET_SSE41 +#elif defined(__GNUC__) && defined(__has_attribute) +#if __has_attribute(target) +#define LUAU_TARGET_SSE41 __attribute__((target("sse4.1"))) +#endif +#endif +#endif + +// Used on functions that have a printf-like interface to validate them statically +#if defined(__GNUC__) +#define LUA_PRINTF_ATTR(fmt, arg) __attribute__((format(printf, fmt, arg))) +#else +#define LUA_PRINTF_ATTR(fmt, arg) +#endif + +#ifdef _MSC_VER +#define LUA_NORETURN __declspec(noreturn) +#else +#define LUA_NORETURN __attribute__((__noreturn__)) +#endif + +// Can be used to reconfigure visibility/exports for public APIs +#ifndef LUA_API +#define LUA_API extern +#endif + +#define LUALIB_API LUA_API + +// Can be used to reconfigure visibility for internal APIs +#if defined(__GNUC__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + +// Can be used to reconfigure internal error handling to use longjmp instead of C++ EH +#ifndef LUA_USE_LONGJMP +#define LUA_USE_LONGJMP 0 +#endif + +// LUA_IDSIZE gives the maximum size for the description of the source +#ifndef LUA_IDSIZE +#define LUA_IDSIZE 256 +#endif + +// LUA_MINSTACK is the guaranteed number of Lua stack slots available to a C function +#ifndef LUA_MINSTACK +#define LUA_MINSTACK 20 +#endif + +// LUAI_MAXCSTACK limits the number of Lua stack slots that a C function can use +#ifndef LUAI_MAXCSTACK +#define LUAI_MAXCSTACK 8000 +#endif + +// LUAI_MAXCALLS limits the number of nested calls +#ifndef LUAI_MAXCALLS +#define LUAI_MAXCALLS 20000 +#endif + +// LUAI_MAXCCALLS is the maximum depth for nested C calls; this limit depends on native stack size +#ifndef LUAI_MAXCCALLS +#define LUAI_MAXCCALLS 200 +#endif + +// buffer size used for on-stack string operations; this limit depends on native stack size +#ifndef LUA_BUFFERSIZE +#define LUA_BUFFERSIZE 512 +#endif + +// number of valid Lua userdata tags +#ifndef LUA_UTAG_LIMIT +#define LUA_UTAG_LIMIT 128 +#endif + +// number of valid Lua lightuserdata tags +#ifndef LUA_LUTAG_LIMIT +#define LUA_LUTAG_LIMIT 128 +#endif + +// upper bound for number of size classes used by page allocator +#ifndef LUA_SIZECLASSES +#define LUA_SIZECLASSES 40 +#endif + +// available number of separate memory categories +#ifndef LUA_MEMORY_CATEGORIES +#define LUA_MEMORY_CATEGORIES 256 +#endif + +// extra storage for execution callbacks in global state +#ifndef LUA_EXECUTION_CALLBACK_STORAGE +#define LUA_EXECUTION_CALLBACK_STORAGE 512 +#endif + +// minimum size for the string table (must be power of 2) +#ifndef LUA_MINSTRTABSIZE +#define LUA_MINSTRTABSIZE 32 +#endif + +// maximum number of captures supported by pattern matching +#ifndef LUA_MAXCAPTURES +#define LUA_MAXCAPTURES 32 +#endif + +// }================================================================== + +#ifndef LUA_VECTOR_SIZE +#define LUA_VECTOR_SIZE 3 // must be 3 or 4 +#endif + +#define LUA_EXTRA_SIZE (LUA_VECTOR_SIZE - 2) diff --git a/thirdparty/luau/upstream/VM/include/lualib.h b/thirdparty/luau/upstream/VM/include/lualib.h new file mode 100644 index 000000000..d6b639d90 --- /dev/null +++ b/thirdparty/luau/upstream/VM/include/lualib.h @@ -0,0 +1,152 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lua.h" + +#define luaL_error(L, fmt, ...) luaL_errorL(L, fmt, ##__VA_ARGS__) +#define luaL_typeerror(L, narg, tname) luaL_typeerrorL(L, narg, tname) +#define luaL_argerror(L, narg, extramsg) luaL_argerrorL(L, narg, extramsg) + +struct luaL_Reg +{ + const char* name; + lua_CFunction func; +}; +typedef struct luaL_Reg luaL_Reg; + +LUALIB_API void luaL_register(lua_State* L, const char* libname, const luaL_Reg* l); +LUALIB_API int luaL_getmetafield(lua_State* L, int obj, const char* e); +LUALIB_API int luaL_callmeta(lua_State* L, int obj, const char* e); +LUALIB_API l_noret luaL_typeerrorL(lua_State* L, int narg, const char* tname); +LUALIB_API l_noret luaL_argerrorL(lua_State* L, int narg, const char* extramsg); +LUALIB_API const char* luaL_checklstring(lua_State* L, int numArg, size_t* l); +LUALIB_API const char* luaL_optlstring(lua_State* L, int numArg, const char* def, size_t* l); +LUALIB_API double luaL_checknumber(lua_State* L, int numArg); +LUALIB_API double luaL_optnumber(lua_State* L, int nArg, double def); + +LUALIB_API int luaL_checkboolean(lua_State* L, int narg); +LUALIB_API int luaL_optboolean(lua_State* L, int narg, int def); + +LUALIB_API int luaL_checkinteger(lua_State* L, int numArg); +LUALIB_API int luaL_optinteger(lua_State* L, int nArg, int def); +LUALIB_API unsigned luaL_checkunsigned(lua_State* L, int numArg); +LUALIB_API unsigned luaL_optunsigned(lua_State* L, int numArg, unsigned def); + +LUALIB_API const float* luaL_checkvector(lua_State* L, int narg); +LUALIB_API const float* luaL_optvector(lua_State* L, int narg, const float* def); + +LUALIB_API void luaL_checkstack(lua_State* L, int sz, const char* msg); +LUALIB_API void luaL_checktype(lua_State* L, int narg, int t); +LUALIB_API void luaL_checkany(lua_State* L, int narg); + +LUALIB_API int luaL_newmetatable(lua_State* L, const char* tname); +LUALIB_API void* luaL_checkudata(lua_State* L, int ud, const char* tname); + +LUALIB_API void* luaL_checkbuffer(lua_State* L, int narg, size_t* len); + +LUALIB_API void luaL_where(lua_State* L, int lvl); +LUALIB_API LUA_PRINTF_ATTR(2, 3) l_noret luaL_errorL(lua_State* L, const char* fmt, ...); + +LUALIB_API int luaL_checkoption(lua_State* L, int narg, const char* def, const char* const lst[]); + +LUALIB_API const char* luaL_tolstring(lua_State* L, int idx, size_t* len); + +LUALIB_API lua_State* luaL_newstate(void); + +LUALIB_API const char* luaL_findtable(lua_State* L, int idx, const char* fname, int szhint); + +LUALIB_API const char* luaL_typename(lua_State* L, int idx); + +// wrapper for making calls from yieldable C functions +LUALIB_API int luaL_callyieldable(lua_State* L, int nargs, int nresults); + +LUALIB_API void luaL_traceback(lua_State* L, lua_State* L1, const char* msg, int level); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond, arg, extramsg) ((void)((cond) ? (void)0 : luaL_argerror(L, arg, extramsg))) +#define luaL_argexpected(L, cond, arg, tname) ((void)((cond) ? (void)0 : luaL_typeerror(L, arg, tname))) + +#define luaL_checkstring(L, n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L, n, d) (luaL_optlstring(L, (n), (d), NULL)) + +#define luaL_getmetatable(L, n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L, f, n, d) (lua_isnoneornil(L, (n)) ? (d) : f(L, (n))) + +// generic buffer manipulation + +struct luaL_Strbuf +{ + char* p; // current position in buffer + char* end; // end of the current buffer + lua_State* L; + struct TString* storage; + char buffer[LUA_BUFFERSIZE]; +}; +typedef struct luaL_Strbuf luaL_Strbuf; + +// compatibility typedef: this type is called luaL_Buffer in Lua headers +// renamed to luaL_Strbuf to reduce confusion with internal VM buffer type +typedef struct luaL_Strbuf luaL_Buffer; + +// when internal buffer storage is exhausted, a mutable string value 'storage' will be placed on the stack +// in general, functions expect the mutable string buffer to be placed on top of the stack (top-1) +// with the exception of luaL_addvalue that expects the value at the top and string buffer further away (top-2) + +#define luaL_addchar(B, c) ((void)((B)->p < (B)->end || luaL_prepbuffsize(B, 1)), (*(B)->p++ = (char)(c))) +#define luaL_addstring(B, s) luaL_addlstring(B, s, strlen(s)) + +LUALIB_API void luaL_buffinit(lua_State* L, luaL_Strbuf* B); +LUALIB_API char* luaL_buffinitsize(lua_State* L, luaL_Strbuf* B, size_t size); +LUALIB_API char* luaL_prepbuffsize(luaL_Buffer* B, size_t size); +LUALIB_API void luaL_addlstring(luaL_Strbuf* B, const char* s, size_t l); +LUALIB_API void luaL_addvalue(luaL_Strbuf* B); +LUALIB_API void luaL_addvalueany(luaL_Strbuf* B, int idx); +LUALIB_API void luaL_pushresult(luaL_Strbuf* B); +LUALIB_API void luaL_pushresultsize(luaL_Strbuf* B, size_t size); + +// builtin libraries +LUALIB_API int luaopen_base(lua_State* L); + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int luaopen_coroutine(lua_State* L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int luaopen_table(lua_State* L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int luaopen_os(lua_State* L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int luaopen_string(lua_State* L); + +#define LUA_BITLIBNAME "bit32" +LUALIB_API int luaopen_bit32(lua_State* L); + +#define LUA_BUFFERLIBNAME "buffer" +LUALIB_API int luaopen_buffer(lua_State* L); + +#define LUA_UTF8LIBNAME "utf8" +LUALIB_API int luaopen_utf8(lua_State* L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int luaopen_math(lua_State* L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int luaopen_debug(lua_State* L); + +#define LUA_VECLIBNAME "vector" +LUALIB_API int luaopen_vector(lua_State* L); + +// open all builtin libraries +LUALIB_API void luaL_openlibs(lua_State* L); + +// sandbox libraries and globals +LUALIB_API void luaL_sandbox(lua_State* L); +LUALIB_API void luaL_sandboxthread(lua_State* L); diff --git a/thirdparty/luau/upstream/VM/src/lapi.cpp b/thirdparty/luau/upstream/VM/src/lapi.cpp new file mode 100644 index 000000000..207754c4f --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lapi.cpp @@ -0,0 +1,1670 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lapi.h" + +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lfunc.h" +#include "lgc.h" +#include "ldo.h" +#include "ludata.h" +#include "lvm.h" +#include "lnumutils.h" +#include "lbuffer.h" + +#include + +/* + * This file contains most implementations of core Lua APIs from lua.h. + * + * These implementations should use api_check macros to verify that stack and type contracts hold; it's the callers + * responsibility to, for example, pass a valid table index to lua_rawgetfield. Generally errors should only be raised + * for conditions caller can't predict such as an out-of-memory error. + * + * The caller is expected to handle stack reservation (by using less than LUA_MINSTACK slots or by calling lua_checkstack). + * To ensure this is handled correctly, use api_incr_top(L) when pushing values to the stack. + * + * Functions that push any collectable objects to the stack *should* call luaC_threadbarrier. Failure to do this can result + * in stack references that point to dead objects since black threads don't get rescanned. + * + * Functions that push newly created objects to the stack *should* call luaC_checkGC in addition to luaC_threadbarrier. + * Failure to do this can result in OOM since GC may never run. + * + * Note that luaC_checkGC may mark the thread and paint it black; functions that call both before pushing objects must + * therefore call luaC_checkGC before luaC_threadbarrier to guarantee the object is pushed to a gray thread. + */ + +const char* lua_ident = "$Lua: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio $\n" + "$Authors: R. Ierusalimschy, L. H. de Figueiredo & W. Celes $\n" + "$URL: www.lua.org $\n"; + +const char* luau_ident = "$Luau: Copyright (C) 2019-2024 Roblox Corporation $\n" + "$URL: luau.org $\n"; + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) + +#define api_incr_top(L) \ + { \ + api_check(L, L->top < L->ci->top); \ + L->top++; \ + } + +#define api_update_top(L, p) \ + { \ + api_check(L, p >= L->base && p <= L->ci->top); \ + L->top = p; \ + } + +#define updateatom(L, ts) \ + { \ + if (ts->atom == ATOM_UNDEF) \ + ts->atom = L->global->cb.useratom ? L->global->cb.useratom(L, ts->data, ts->len) : -1; \ + } + +static LuaTable* getcurrenv(lua_State* L) +{ + if (L->ci == L->base_ci) // no enclosing function? + return L->gt; // use global table as environment + else + return curr_func(L)->env; +} + +static LUAU_NOINLINE TValue* pseudo2addr(lua_State* L, int idx) +{ + api_check(L, lua_ispseudo(idx)); + switch (idx) + { // pseudo-indices + case LUA_REGISTRYINDEX: + return registry(L); + case LUA_ENVIRONINDEX: + { + sethvalue(L, &L->global->pseudotemp, getcurrenv(L)); + return &L->global->pseudotemp; + } + case LUA_GLOBALSINDEX: + { + sethvalue(L, &L->global->pseudotemp, L->gt); + return &L->global->pseudotemp; + } + default: + { + Closure* func = curr_func(L); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->nupvalues) ? &func->c.upvals[idx - 1] : cast_to(TValue*, luaO_nilobject); + } + } +} + +static LUAU_FORCEINLINE TValue* index2addr(lua_State* L, int idx) +{ + if (idx > 0) + { + TValue* o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) + return cast_to(TValue*, luaO_nilobject); + else + return o; + } + else if (idx > LUA_REGISTRYINDEX) + { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; + } + else + { + return pseudo2addr(L, idx); + } +} + +const TValue* luaA_toobject(lua_State* L, int idx) +{ + StkId p = index2addr(L, idx); + return (p == luaO_nilobject) ? NULL : p; +} + +void luaA_pushobject(lua_State* L, const TValue* o) +{ + setobj2s(L, L->top, o); + api_incr_top(L); +} + +int lua_checkstack(lua_State* L, int size) +{ + int res = 1; + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; // stack overflow + else if (size > 0) + { + if (stacklimitreached(L, size)) + { + struct CallContext + { + int size; + + static void run(lua_State* L, void* ud) + { + CallContext* ctx = (CallContext*)ud; + + luaD_growstack(L, ctx->size); + } + } ctx = {size}; + + // there could be no memory to extend the stack + if (luaD_rawrunprotected(L, &CallContext::run, &ctx) != LUA_OK) + return 0; + } + else + { + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK, 0)); + } + + expandstacklimit(L, L->top + size); + } + return res; +} + +void lua_rawcheckstack(lua_State* L, int size) +{ + luaD_checkstack(L, size); + expandstacklimit(L, L->top + size); +} + +void lua_xmove(lua_State* from, lua_State* to, int n) +{ + if (from == to) + return; + api_checknelems(from, n); + api_check(from, from->global == to->global); + api_check(from, to->ci->top - to->top >= n); + luaC_threadbarrier(to); + + StkId ttop = to->top; + StkId ftop = from->top - n; + for (int i = 0; i < n; i++) + setobj2s(to, ttop + i, ftop + i); + + from->top = ftop; + to->top = ttop + n; +} + +void lua_xpush(lua_State* from, lua_State* to, int idx) +{ + api_check(from, from->global == to->global); + luaC_threadbarrier(to); + setobj2s(to, to->top, index2addr(from, idx)); + api_incr_top(to); +} + +lua_State* lua_newthread(lua_State* L) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + lua_State* L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + global_State* g = L->global; + if (g->cb.userthread) + g->cb.userthread(L, L1); + return L1; +} + +lua_State* lua_mainthread(lua_State* L) +{ + return L->global->mainthread; +} + +/* +** basic stack manipulation +*/ + +int lua_absindex(lua_State* L, int idx) +{ + api_check(L, (idx > 0 && idx <= L->top - L->base) || (idx < 0 && -idx <= L->top - L->base) || lua_ispseudo(idx)); + return idx > 0 || lua_ispseudo(idx) ? idx : cast_int(L->top - L->base) + idx + 1; +} + +int lua_gettop(lua_State* L) +{ + return cast_int(L->top - L->base); +} + +void lua_settop(lua_State* L, int idx) +{ + if (idx >= 0) + { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else + { + api_check(L, -(idx + 1) <= (L->top - L->base)); + L->top += idx + 1; // `subtract' index (index is negative) + } +} + +void lua_remove(lua_State* L, int idx) +{ + StkId p = index2addr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) + setobj2s(L, p - 1, p); + L->top--; +} + +void lua_insert(lua_State* L, int idx) +{ + luaC_threadbarrier(L); + StkId p = index2addr(L, idx); + api_checkvalidindex(L, p); + for (StkId q = L->top; q > p; q--) + setobj2s(L, q, q - 1); + setobj2s(L, p, L->top); +} + +void lua_replace(lua_State* L, int idx) +{ + api_checknelems(L, 1); + luaC_threadbarrier(L); + StkId o = index2addr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) + { + api_check(L, L->ci != L->base_ci); + Closure* func = curr_func(L); + api_check(L, ttistable(L->top - 1)); + func->env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + else if (idx == LUA_GLOBALSINDEX) + { + api_check(L, ttistable(L->top - 1)); + L->gt = hvalue(L->top - 1); + } + else + { + setobj(L, o, L->top - 1); + if (idx < LUA_GLOBALSINDEX) // function upvalue? + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; +} + +void lua_pushvalue(lua_State* L, int idx) +{ + luaC_threadbarrier(L); + StkId o = index2addr(L, idx); + setobj2s(L, L->top, o); + api_incr_top(L); +} + +/* +** access functions (stack -> C) +*/ + +int lua_type(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +} + +const char* lua_typename(lua_State* L, int t) +{ + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + +int lua_iscfunction(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + return iscfunction(o); +} + +int lua_isLfunction(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + return isLfunction(o); +} + +int lua_isnumber(lua_State* L, int idx) +{ + TValue n; + const TValue* o = index2addr(L, idx); + return tonumber(o, &n); +} + +int lua_isstring(lua_State* L, int idx) +{ + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + +int lua_isuserdata(lua_State* L, int idx) +{ + const TValue* o = index2addr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + +int lua_rawequal(lua_State* L, int index1, int index2) +{ + StkId o1 = index2addr(L, index1); + StkId o2 = index2addr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : luaO_rawequalObj(o1, o2); +} + +int lua_equal(lua_State* L, int index1, int index2) +{ + StkId o1, o2; + int i; + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + return i; +} + +int lua_lessthan(lua_State* L, int index1, int index2) +{ + StkId o1, o2; + int i; + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : luaV_lessthan(L, o1, o2); + return i; +} + +double lua_tonumberx(lua_State* L, int idx, int* isnum) +{ + TValue n; + const TValue* o = index2addr(L, idx); + if (tonumber(o, &n)) + { + if (isnum) + *isnum = 1; + return nvalue(o); + } + else + { + if (isnum) + *isnum = 0; + return 0; + } +} + +int lua_tointegerx(lua_State* L, int idx, int* isnum) +{ + TValue n; + const TValue* o = index2addr(L, idx); + if (tonumber(o, &n)) + { + int res; + double num = nvalue(o); + luai_num2int(res, num); + if (isnum) + *isnum = 1; + return res; + } + else + { + if (isnum) + *isnum = 0; + return 0; + } +} + +unsigned lua_tounsignedx(lua_State* L, int idx, int* isnum) +{ + TValue n; + const TValue* o = index2addr(L, idx); + if (tonumber(o, &n)) + { + unsigned res; + double num = nvalue(o); + luai_num2unsigned(res, num); + if (isnum) + *isnum = 1; + return res; + } + else + { + if (isnum) + *isnum = 0; + return 0; + } +} + +int lua_toboolean(lua_State* L, int idx) +{ + const TValue* o = index2addr(L, idx); + return !l_isfalse(o); +} + +const char* lua_tolstring(lua_State* L, int idx, size_t* len) +{ + StkId o = index2addr(L, idx); + if (!ttisstring(o)) + { + luaC_threadbarrier(L); + if (!luaV_tostring(L, o)) + { // conversion failed? + if (len != NULL) + *len = 0; + return NULL; + } + luaC_checkGC(L); + o = index2addr(L, idx); // previous call may reallocate the stack + } + if (len != NULL) + *len = tsvalue(o)->len; + return svalue(o); +} + +const char* lua_tostringatom(lua_State* L, int idx, int* atom) +{ + StkId o = index2addr(L, idx); + if (!ttisstring(o)) + return NULL; + TString* s = tsvalue(o); + if (atom) + { + updateatom(L, s); + *atom = s->atom; + } + return getstr(s); +} + +const char* lua_tolstringatom(lua_State* L, int idx, size_t* len, int* atom) +{ + StkId o = index2addr(L, idx); + + if (!ttisstring(o)) + { + if (len) + *len = 0; + return NULL; + } + + TString* s = tsvalue(o); + if (len) + *len = s->len; + if (atom) + { + updateatom(L, s); + *atom = s->atom; + } + + return getstr(s); +} + +const char* lua_namecallatom(lua_State* L, int* atom) +{ + TString* s = L->namecall; + if (!s) + return NULL; + if (atom) + { + updateatom(L, s); + *atom = s->atom; + } + return getstr(s); +} + +const float* lua_tovector(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + if (!ttisvector(o)) + return NULL; + return vvalue(o); +} + +int lua_objlen(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + switch (ttype(o)) + { + case LUA_TSTRING: + return tsvalue(o)->len; + case LUA_TUSERDATA: + return uvalue(o)->len; + case LUA_TBUFFER: + return bufvalue(o)->len; + case LUA_TTABLE: + return luaH_getn(hvalue(o)); + default: + return 0; + } +} + +lua_CFunction lua_tocfunction(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + return (!iscfunction(o)) ? NULL : cast_to(lua_CFunction, clvalue(o)->c.f); +} + +void* lua_tolightuserdata(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + return (!ttislightuserdata(o)) ? NULL : pvalue(o); +} + +void* lua_tolightuserdatatagged(lua_State* L, int idx, int tag) +{ + StkId o = index2addr(L, idx); + return (!ttislightuserdata(o) || lightuserdatatag(o) != tag) ? NULL : pvalue(o); +} + +void* lua_touserdata(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + if (ttisuserdata(o)) + return uvalue(o)->data; + else if (ttislightuserdata(o)) + return pvalue(o); + else + return NULL; +} + +void* lua_touserdatatagged(lua_State* L, int idx, int tag) +{ + StkId o = index2addr(L, idx); + return (ttisuserdata(o) && uvalue(o)->tag == tag) ? uvalue(o)->data : NULL; +} + +int lua_userdatatag(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + if (ttisuserdata(o)) + return uvalue(o)->tag; + return -1; +} + +int lua_lightuserdatatag(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + if (ttislightuserdata(o)) + return lightuserdatatag(o); + return -1; +} + +lua_State* lua_tothread(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + +void* lua_tobuffer(lua_State* L, int idx, size_t* len) +{ + StkId o = index2addr(L, idx); + + if (!ttisbuffer(o)) + return NULL; + + Buffer* b = bufvalue(o); + + if (len) + *len = b->len; + + return b->data; +} + +const void* lua_topointer(lua_State* L, int idx) +{ + StkId o = index2addr(L, idx); + switch (ttype(o)) + { + case LUA_TUSERDATA: + return uvalue(o)->data; + case LUA_TLIGHTUSERDATA: + return pvalue(o); + default: + return iscollectable(o) ? gcvalue(o) : NULL; + } +} + +/* +** push functions (C -> stack) +*/ + +void lua_pushnil(lua_State* L) +{ + setnilvalue(L->top); + api_incr_top(L); +} + +void lua_pushnumber(lua_State* L, double n) +{ + setnvalue(L->top, n); + api_incr_top(L); +} + +void lua_pushinteger(lua_State* L, int n) +{ + setnvalue(L->top, cast_num(n)); + api_incr_top(L); +} + +void lua_pushunsigned(lua_State* L, unsigned u) +{ + setnvalue(L->top, cast_num(u)); + api_incr_top(L); +} + +#if LUA_VECTOR_SIZE == 4 +void lua_pushvector(lua_State* L, float x, float y, float z, float w) +{ + setvvalue(L->top, x, y, z, w); + api_incr_top(L); +} +#else +void lua_pushvector(lua_State* L, float x, float y, float z) +{ + setvvalue(L->top, x, y, z, 0.0f); + api_incr_top(L); +} +#endif +void lua_pushvector2(lua_State* L, float x, float y) +{ + TValue* i_o = L->top; + float* i_v = i_o->value.v; + i_v[0] = x; + i_v[1] = y; + i_o->tt = LUA_TVECTOR; + + api_incr_top(L); +} + +void lua_pushlstring(lua_State* L, const char* s, size_t len) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + setsvalue(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); +} + +void lua_pushstring(lua_State* L, const char* s) +{ + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + +const char* lua_pushvfstring(lua_State* L, const char* fmt, va_list argp) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + const char* ret = luaO_pushvfstring(L, fmt, argp); + return ret; +} + +const char* lua_pushfstringL(lua_State* L, const char* fmt, ...) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + va_list argp; + va_start(argp, fmt); + const char* ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return ret; +} + +void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debugname, int nup, lua_Continuation cont) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + api_checknelems(L, nup); + Closure* cl = luaF_newCclosure(L, nup, getcurrenv(L)); + cl->c.f = fn; + cl->c.cont = cont; + cl->c.debugname = debugname; + L->top -= nup; + while (nup--) + setobj2n(L, &cl->c.upvals[nup], L->top + nup); + setclvalue(L, L->top, cl); + LUAU_ASSERT(iswhite(obj2gco(cl))); + api_incr_top(L); +} + +void lua_pushboolean(lua_State* L, int b) +{ + setbvalue(L->top, (b != 0)); // ensure that true is 1 + api_incr_top(L); +} + +void lua_pushlightuserdatatagged(lua_State* L, void* p, int tag) +{ + api_check(L, unsigned(tag) < LUA_LUTAG_LIMIT); + setpvalue(L->top, p, tag); + api_incr_top(L); +} + +int lua_pushthread(lua_State* L) +{ + luaC_threadbarrier(L); + setthvalue(L, L->top, L); + api_incr_top(L); + return L->global->mainthread == L; +} + +/* +** get functions (Lua -> stack) +*/ + +int lua_gettable(lua_State* L, int idx) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + return ttype(L->top - 1); +} + +int lua_getfield(lua_State* L, int idx, const char* k) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_checkvalidindex(L, t); + TValue key; + setsvalue(L, &key, luaS_new(L, k)); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + return ttype(L->top - 1); +} + +int lua_rawgetfield(lua_State* L, int idx, const char* k) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + TValue key; + setsvalue(L, &key, luaS_new(L, k)); + setobj2s(L, L->top, luaH_getstr(hvalue(t), tsvalue(&key))); + api_incr_top(L); + return ttype(L->top - 1); +} + +int lua_rawget(lua_State* L, int idx) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + return ttype(L->top - 1); +} + +int lua_rawgeti(lua_State* L, int idx, int n) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top, luaH_getnum(hvalue(t), n)); + api_incr_top(L); + return ttype(L->top - 1); +} + +int lua_rawgetptagged(lua_State* L, int idx, void* p, int tag) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top, luaH_getp(hvalue(t), p, tag)); + api_incr_top(L); + return ttype(L->top - 1); +} + +void lua_createtable(lua_State* L, int narray, int nrec) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); +} + +void lua_setreadonly(lua_State* L, int objindex, int enabled) +{ + const TValue* o = index2addr(L, objindex); + api_check(L, ttistable(o)); + LuaTable* t = hvalue(o); + api_check(L, t != hvalue(registry(L))); + t->readonly = bool(enabled); +} + +int lua_getreadonly(lua_State* L, int objindex) +{ + const TValue* o = index2addr(L, objindex); + api_check(L, ttistable(o)); + LuaTable* t = hvalue(o); + int res = t->readonly; + return res; +} + +void lua_setsafeenv(lua_State* L, int objindex, int enabled) +{ + const TValue* o = index2addr(L, objindex); + api_check(L, ttistable(o)); + LuaTable* t = hvalue(o); + t->safeenv = bool(enabled); +} + +int lua_getmetatable(lua_State* L, int objindex) +{ + luaC_threadbarrier(L); + LuaTable* mt = NULL; + const TValue* obj = index2addr(L, objindex); + switch (ttype(obj)) + { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = L->global->mt[ttype(obj)]; + break; + } + if (mt) + { + sethvalue(L, L->top, mt); + api_incr_top(L); + } + return mt != NULL; +} + +void lua_getfenv(lua_State* L, int idx) +{ + luaC_threadbarrier(L); + StkId o = index2addr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) + { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->env); + break; + case LUA_TTHREAD: + sethvalue(L, L->top, thvalue(o)->gt); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); +} + +/* +** set functions (stack -> Lua) +*/ + +void lua_settable(lua_State* L, int idx) +{ + api_checknelems(L, 2); + StkId t = index2addr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; // pop index and value +} + +void lua_setfield(lua_State* L, int idx, const char* k) +{ + api_checknelems(L, 1); + StkId t = index2addr(L, idx); + api_checkvalidindex(L, t); + TValue key; + setsvalue(L, &key, luaS_new(L, k)); + luaV_settable(L, t, &key, L->top - 1); + L->top--; +} + +void lua_rawsetfield(lua_State* L, int idx, const char* k) +{ + api_checknelems(L, 1); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + if (hvalue(t)->readonly) + luaG_readonlyerror(L); + setobj2t(L, luaH_setstr(L, hvalue(t), luaS_new(L, k)), L->top - 1); + luaC_barriert(L, hvalue(t), L->top - 1); + L->top--; +} + +void lua_rawset(lua_State* L, int idx) +{ + api_checknelems(L, 2); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + if (hvalue(t)->readonly) + luaG_readonlyerror(L); + setobj2t(L, luaH_set(L, hvalue(t), L->top - 2), L->top - 1); + luaC_barriert(L, hvalue(t), L->top - 1); + L->top -= 2; +} + +void lua_rawseti(lua_State* L, int idx, int n) +{ + api_checknelems(L, 1); + StkId o = index2addr(L, idx); + api_check(L, ttistable(o)); + if (hvalue(o)->readonly) + luaG_readonlyerror(L); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top - 1); + luaC_barriert(L, hvalue(o), L->top - 1); + L->top--; +} + +void lua_rawsetptagged(lua_State* L, int idx, void* p, int tag) +{ + api_checknelems(L, 1); + StkId o = index2addr(L, idx); + api_check(L, ttistable(o)); + if (hvalue(o)->readonly) + luaG_readonlyerror(L); + setobj2t(L, luaH_setp(L, hvalue(o), p, tag), L->top - 1); + luaC_barriert(L, hvalue(o), L->top - 1); + L->top--; +} + +int lua_setmetatable(lua_State* L, int objindex) +{ + api_checknelems(L, 1); + TValue* obj = index2addr(L, objindex); + api_checkvalidindex(L, obj); + LuaTable* mt = NULL; + if (!ttisnil(L->top - 1)) + { + api_check(L, ttistable(L->top - 1)); + mt = hvalue(L->top - 1); + } + switch (ttype(obj)) + { + case LUA_TTABLE: + { + if (hvalue(obj)->readonly) + luaG_readonlyerror(L); + hvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: + { + uvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, uvalue(obj), mt); + break; + } + default: + { + L->global->mt[ttype(obj)] = mt; + break; + } + } + L->top--; + return 1; +} + +int lua_setfenv(lua_State* L, int idx) +{ + int res = 1; + api_checknelems(L, 1); + StkId o = index2addr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) + { + case LUA_TFUNCTION: + clvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + thvalue(o)->gt = hvalue(L->top - 1); + break; + default: + res = 0; + break; + } + if (res) + { + luaC_objbarrier(L, &gcvalue(o)->gch, hvalue(L->top - 1)); + } + L->top--; + return res; +} + +/* +** `load' and `call' functions (run Lua code) +*/ + +#define adjustresults(L, nres) \ + { \ + if (nres == LUA_MULTRET && L->top >= L->ci->top) \ + L->ci->top = L->top; \ + } + +#define checkresults(L, na, nr) api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + +void lua_call(lua_State* L, int nargs, int nresults) +{ + StkId func; + api_checknelems(L, nargs + 1); + api_check(L, L->status == 0); + checkresults(L, nargs, nresults); + func = L->top - (nargs + 1); + + luaD_call(L, func, nresults); + + adjustresults(L, nresults); +} + +/* +** Execute a protected call. +*/ +// data to `f_call' +struct CallS +{ + StkId func; + int nresults; +}; + +static void f_call(lua_State* L, void* ud) +{ + struct CallS* c = cast_to(struct CallS*, ud); + luaD_call(L, c->func, c->nresults); +} + +int lua_pcall(lua_State* L, int nargs, int nresults, int errfunc) +{ + api_checknelems(L, nargs + 1); + api_check(L, L->status == 0); + checkresults(L, nargs, nresults); + ptrdiff_t func = 0; + if (errfunc != 0) + { + StkId o = index2addr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + struct CallS c; + c.func = L->top - (nargs + 1); // function to be called + c.nresults = nresults; + + int status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + + adjustresults(L, nresults); + return status; +} + +/* +** Execute a protected C call. +*/ +// data to `f_Ccall' +struct CCallS +{ + lua_CFunction func; + void* ud; +}; + +static void f_Ccall(lua_State* L, void* ud) +{ + struct CCallS* c = cast_to(struct CCallS*, ud); + + if (!lua_checkstack(L, 2)) + luaG_runerror(L, "stack limit"); + + lua_pushcclosurek(L, c->func, nullptr, 0, nullptr); + lua_pushlightuserdata(L, c->ud); + luaD_call(L, L->top - 2, 0); +} + +int lua_cpcall(lua_State* L, lua_CFunction func, void* ud) +{ + api_check(L, L->status == 0); + + struct CCallS c; + c.func = func; + c.ud = ud; + + return luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); +} + +int lua_status(lua_State* L) +{ + return L->status; +} + +int lua_costatus(lua_State* L, lua_State* co) +{ + if (co == L) + return LUA_CORUN; + if (co->status == LUA_YIELD) + return LUA_COSUS; + if (co->status == LUA_BREAK) + return LUA_CONOR; + if (co->status != 0) // some error occurred + return LUA_COERR; + if (co->ci != co->base_ci) // does it have frames? + return LUA_CONOR; + if (co->top == co->base) + return LUA_COFIN; + return LUA_COSUS; // initial state +} + +void* lua_getthreaddata(lua_State* L) +{ + return L->userdata; +} + +void lua_setthreaddata(lua_State* L, void* data) +{ + L->userdata = data; +} + +/* +** Garbage-collection function +*/ + +int lua_gc(lua_State* L, int what, int data) +{ + int res = 0; + condhardmemtests(luaC_validate(L), 1); + global_State* g = L->global; + switch (what) + { + case LUA_GCSTOP: + { + g->GCthreshold = SIZE_MAX; + break; + } + case LUA_GCRESTART: + { + g->GCthreshold = g->totalbytes; + break; + } + case LUA_GCCOLLECT: + { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: + { + // GC values are expressed in Kbytes: #bytes/2^10 + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: + { + res = cast_int(g->totalbytes & 1023); + break; + } + case LUA_GCISRUNNING: + { + res = (g->GCthreshold != SIZE_MAX); + break; + } + case LUA_GCSTEP: + { + size_t amount = (cast_to(size_t, data) << 10); + ptrdiff_t oldcredit = g->gcstate == GCSpause ? 0 : g->GCthreshold - g->totalbytes; + + // temporarily adjust the threshold so that we can perform GC work + if (amount <= g->totalbytes) + g->GCthreshold = g->totalbytes - amount; + else + g->GCthreshold = 0; + +#ifdef LUAI_GCMETRICS + double startmarktime = g->gcmetrics.currcycle.marktime; + double startsweeptime = g->gcmetrics.currcycle.sweeptime; +#endif + + // track how much work the loop will actually perform + size_t actualwork = 0; + + while (g->GCthreshold <= g->totalbytes) + { + size_t stepsize = luaC_step(L, false); + + actualwork += stepsize; + + if (g->gcstate == GCSpause) + { // end of cycle? + res = 1; // signal it + break; + } + } + +#ifdef LUAI_GCMETRICS + // record explicit step statistics + GCCycleMetrics* cyclemetrics = g->gcstate == GCSpause ? &g->gcmetrics.lastcycle : &g->gcmetrics.currcycle; + + double totalmarktime = cyclemetrics->marktime - startmarktime; + double totalsweeptime = cyclemetrics->sweeptime - startsweeptime; + + if (totalmarktime > 0.0) + { + cyclemetrics->markexplicitsteps++; + + if (totalmarktime > cyclemetrics->markmaxexplicittime) + cyclemetrics->markmaxexplicittime = totalmarktime; + } + + if (totalsweeptime > 0.0) + { + cyclemetrics->sweepexplicitsteps++; + + if (totalsweeptime > cyclemetrics->sweepmaxexplicittime) + cyclemetrics->sweepmaxexplicittime = totalsweeptime; + } +#endif + + // if cycle hasn't finished, advance threshold forward for the amount of extra work performed + if (g->gcstate != GCSpause) + { + // if a new cycle was triggered by explicit step, old 'credit' of GC work is 0 + ptrdiff_t newthreshold = g->totalbytes + actualwork + oldcredit; + g->GCthreshold = newthreshold < 0 ? 0 : newthreshold; + } + break; + } + case LUA_GCSETGOAL: + { + res = g->gcgoal; + g->gcgoal = data; + break; + } + case LUA_GCSETSTEPMUL: + { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + case LUA_GCSETSTEPSIZE: + { + // GC values are expressed in Kbytes: #bytes/2^10 + res = g->gcstepsize >> 10; + g->gcstepsize = data << 10; + break; + } + default: + res = -1; // invalid option + } + return res; +} + +/* +** miscellaneous functions +*/ + +l_noret lua_error(lua_State* L) +{ + api_checknelems(L, 1); + + luaD_throw(L, LUA_ERRRUN); +} + +int lua_next(lua_State* L, int idx) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + int more = luaH_next(L, hvalue(t), L->top - 1); + if (more) + { + api_incr_top(L); + } + else // no more elements + L->top -= 1; // remove key + return more; +} + +int lua_rawiter(lua_State* L, int idx, int iter) +{ + luaC_threadbarrier(L); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + api_check(L, iter >= 0); + + LuaTable* h = hvalue(t); + int sizearray = h->sizearray; + + // first we advance iter through the array portion + for (; unsigned(iter) < unsigned(sizearray); ++iter) + { + TValue* e = &h->array[iter]; + + if (!ttisnil(e)) + { + StkId top = L->top; + setnvalue(top + 0, double(iter + 1)); + setobj2s(L, top + 1, e); + api_update_top(L, top + 2); + return iter + 1; + } + } + + int sizenode = 1 << h->lsizenode; + + // then we advance iter through the hash portion + for (; unsigned(iter - sizearray) < unsigned(sizenode); ++iter) + { + LuaNode* n = &h->node[iter - sizearray]; + + if (!ttisnil(gval(n))) + { + StkId top = L->top; + getnodekey(L, top + 0, n); + setobj2s(L, top + 1, gval(n)); + api_update_top(L, top + 2); + return iter + 1; + } + } + + // traversal finished + return -1; +} + +void lua_concat(lua_State* L, int n) +{ + api_checknelems(L, n); + if (n >= 2) + { + luaC_checkGC(L); + luaC_threadbarrier(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n - 1); + } + else if (n == 0) + { // push empty string + luaC_threadbarrier(L); + setsvalue(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + // else n == 1; nothing to do +} + +void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT || tag == UTAG_PROXY); + luaC_checkGC(L); + luaC_threadbarrier(L); + Udata* u = luaU_newudata(L, sz, tag); + setuvalue(L, L->top, u); + api_incr_top(L); + return u->data; +} + +void* lua_newuserdatataggedwithmetatable(lua_State* L, size_t sz, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + luaC_checkGC(L); + luaC_threadbarrier(L); + Udata* u = luaU_newudata(L, sz, tag); + + // currently, we always allocate unmarked objects, so forward barrier can be skipped + LUAU_ASSERT(!isblack(obj2gco(u))); + + LuaTable* h = L->global->udatamt[tag]; + api_check(L, h != nullptr); + + u->metatable = h; + + setuvalue(L, L->top, u); + api_incr_top(L); + return u->data; +} + +void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*)) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + // make sure sz + sizeof(dtor) doesn't overflow; luaU_newdata will reject SIZE_MAX correctly + size_t as = sz < SIZE_MAX - sizeof(dtor) ? sz + sizeof(dtor) : SIZE_MAX; + Udata* u = luaU_newudata(L, as, UTAG_IDTOR); + memcpy(&u->data + sz, &dtor, sizeof(dtor)); + setuvalue(L, L->top, u); + api_incr_top(L); + return u->data; +} + +void* lua_newbuffer(lua_State* L, size_t sz) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + Buffer* b = luaB_newbuffer(L, sz); + setbufvalue(L, L->top, b); + api_incr_top(L); + return b->data; +} + +static const char* aux_upvalue(StkId fi, int n, TValue** val) +{ + Closure* f; + if (!ttisfunction(fi)) + return NULL; + f = clvalue(fi); + if (f->isC) + { + if (!(1 <= n && n <= f->nupvalues)) + return NULL; + *val = &f->c.upvals[n - 1]; + return ""; + } + else + { + Proto* p = f->l.p; + if (!(1 <= n && n <= p->nups)) // not a valid upvalue + return NULL; + TValue* r = &f->l.uprefs[n - 1]; + *val = ttisupval(r) ? upvalue(r)->v : r; + if (!(1 <= n && n <= p->sizeupvalues)) // don't have a name for this upvalue + return ""; + return getstr(p->upvalues[n - 1]); + } +} + +const char* lua_getupvalue(lua_State* L, int funcindex, int n) +{ + luaC_threadbarrier(L); + TValue* val; + const char* name = aux_upvalue(index2addr(L, funcindex), n, &val); + if (name) + { + setobj2s(L, L->top, val); + api_incr_top(L); + } + return name; +} + +const char* lua_setupvalue(lua_State* L, int funcindex, int n) +{ + api_checknelems(L, 1); + StkId fi = index2addr(L, funcindex); + TValue* val; + const char* name = aux_upvalue(fi, n, &val); + if (name) + { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + return name; +} + +uintptr_t lua_encodepointer(lua_State* L, uintptr_t p) +{ + global_State* g = L->global; + return uintptr_t((g->ptrenckey[0] * p + g->ptrenckey[2]) ^ (g->ptrenckey[1] * p + g->ptrenckey[3])); +} + +int lua_ref(lua_State* L, int idx) +{ + api_check(L, idx != LUA_REGISTRYINDEX); // idx is a stack index for value + int ref = LUA_REFNIL; + global_State* g = L->global; + StkId p = index2addr(L, idx); + if (!ttisnil(p)) + { + LuaTable* reg = hvalue(registry(L)); + + if (g->registryfree != 0) + { // reuse existing slot + ref = g->registryfree; + } + else + { // no free elements + ref = luaH_getn(reg); + ref++; // create new reference + } + + TValue* slot = luaH_setnum(L, reg, ref); + if (g->registryfree != 0) + g->registryfree = int(nvalue(slot)); + setobj2t(L, slot, p); + luaC_barriert(L, reg, p); + } + return ref; +} + +void lua_unref(lua_State* L, int ref) +{ + if (ref <= LUA_REFNIL) + return; + + global_State* g = L->global; + LuaTable* reg = hvalue(registry(L)); + + const TValue* slot = luaH_getnum(reg, ref); + api_check(L, slot != luaO_nilobject); + + // similar to how 'luaH_setnum' makes non-nil slot value mutable + TValue* mutableSlot = (TValue*)slot; + + // NB: no barrier needed because value isn't collectable + setnvalue(mutableSlot, g->registryfree); + + g->registryfree = ref; +} + +void lua_setuserdatatag(lua_State* L, int idx, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + StkId o = index2addr(L, idx); + api_check(L, ttisuserdata(o)); + uvalue(o)->tag = uint8_t(tag); +} + +void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + L->global->udatagc[tag] = dtor; +} + +lua_Destructor lua_getuserdatadtor(lua_State* L, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + return L->global->udatagc[tag]; +} + +void lua_setuserdatametatable(lua_State* L, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + api_check(L, !L->global->udatamt[tag]); // reassignment not supported + api_check(L, ttistable(L->top - 1)); + L->global->udatamt[tag] = hvalue(L->top - 1); + L->top--; +} + +void lua_getuserdatametatable(lua_State* L, int tag) +{ + api_check(L, unsigned(tag) < LUA_UTAG_LIMIT); + luaC_threadbarrier(L); + + if (LuaTable* h = L->global->udatamt[tag]) + { + sethvalue(L, L->top, h); + } + else + { + setnilvalue(L->top); + } + + api_incr_top(L); +} + +void lua_setlightuserdataname(lua_State* L, int tag, const char* name) +{ + api_check(L, unsigned(tag) < LUA_LUTAG_LIMIT); + api_check(L, !L->global->lightuserdataname[tag]); // renaming not supported + if (!L->global->lightuserdataname[tag]) + { + L->global->lightuserdataname[tag] = luaS_new(L, name); + luaS_fix(L->global->lightuserdataname[tag]); // never collect these names + } +} + +const char* lua_getlightuserdataname(lua_State* L, int tag) +{ + api_check(L, unsigned(tag) < LUA_LUTAG_LIMIT); + const TString* name = L->global->lightuserdataname[tag]; + return name ? getstr(name) : nullptr; +} + +void lua_clonefunction(lua_State* L, int idx) +{ + luaC_checkGC(L); + luaC_threadbarrier(L); + StkId p = index2addr(L, idx); + api_check(L, isLfunction(p)); + Closure* cl = clvalue(p); + Closure* newcl = luaF_newLclosure(L, cl->nupvalues, L->gt, cl->l.p); + for (int i = 0; i < cl->nupvalues; ++i) + setobj2n(L, &newcl->l.uprefs[i], &cl->l.uprefs[i]); + setclvalue(L, L->top, newcl); + api_incr_top(L); +} + +void lua_cleartable(lua_State* L, int idx) +{ + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + LuaTable* tt = hvalue(t); + if (tt->readonly) + luaG_readonlyerror(L); + luaH_clear(tt); +} + +void lua_clonetable(lua_State* L, int idx) +{ + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + + LuaTable* tt = luaH_clone(L, hvalue(t)); + sethvalue(L, L->top, tt); + api_incr_top(L); +} + +lua_Callbacks* lua_callbacks(lua_State* L) +{ + return &L->global->cb; +} + +void lua_setmemcat(lua_State* L, int category) +{ + api_check(L, unsigned(category) < LUA_MEMORY_CATEGORIES); + L->activememcat = uint8_t(category); +} + +size_t lua_totalbytes(lua_State* L, int category) +{ + api_check(L, category < LUA_MEMORY_CATEGORIES); + return category < 0 ? L->global->totalbytes : L->global->memcatbytes[category]; +} + +lua_Alloc lua_getallocf(lua_State* L, void** ud) +{ + lua_Alloc f = L->global->frealloc; + if (ud) + *ud = L->global->ud; + return f; +} diff --git a/thirdparty/luau/upstream/VM/src/lapi.h b/thirdparty/luau/upstream/VM/src/lapi.h new file mode 100644 index 000000000..b72721862 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lapi.h @@ -0,0 +1,8 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" + +LUAI_FUNC const TValue* luaA_toobject(lua_State* L, int idx); +LUAI_FUNC void luaA_pushobject(lua_State* L, const TValue* o); diff --git a/thirdparty/luau/upstream/VM/src/laux.cpp b/thirdparty/luau/upstream/VM/src/laux.cpp new file mode 100644 index 000000000..8a4c06303 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/laux.cpp @@ -0,0 +1,681 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lapi.h" +#include "lgc.h" +#include "lnumutils.h" + +#include + +LUAU_FASTFLAG(LuauStacklessPcall) + +// convert a stack index to positive +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1) + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + +static const char* currfuncname(lua_State* L) +{ + Closure* cl = L->ci > L->base_ci ? curr_func(L) : NULL; + const char* debugname = cl && cl->isC ? cl->c.debugname + 0 : NULL; + + if (debugname && strcmp(debugname, "__namecall") == 0) + return L->namecall ? getstr(L->namecall) : NULL; + else + return debugname; +} + +l_noret luaL_argerrorL(lua_State* L, int narg, const char* extramsg) +{ + const char* fname = currfuncname(L); + + if (fname) + luaL_error(L, "invalid argument #%d to '%s' (%s)", narg, fname, extramsg); + else + luaL_error(L, "invalid argument #%d (%s)", narg, extramsg); +} + +l_noret luaL_typeerrorL(lua_State* L, int narg, const char* tname) +{ + const char* fname = currfuncname(L); + const TValue* obj = luaA_toobject(L, narg); + + if (obj) + { + if (fname) + luaL_error(L, "invalid argument #%d to '%s' (%s expected, got %s)", narg, fname, tname, luaT_objtypename(L, obj)); + else + luaL_error(L, "invalid argument #%d (%s expected, got %s)", narg, tname, luaT_objtypename(L, obj)); + } + else + { + if (fname) + luaL_error(L, "missing argument #%d to '%s' (%s expected)", narg, fname, tname); + else + luaL_error(L, "missing argument #%d (%s expected)", narg, tname); + } +} + +static l_noret tag_error(lua_State* L, int narg, int tag) +{ + luaL_typeerrorL(L, narg, lua_typename(L, tag)); +} + +#ifdef RIVE_LUAU +void luaL_where(lua_State* L, int level) +{ + lua_Debug ar; + if (lua_getinfo(L, level, "sl", &ar) && ar.currentline > 0) + { + lua_pushfstring(L, "%s:%d: ", ar.source, ar.currentline); + return; + } + if (lua_getinfo(L, 0, "sl", &ar) && ar.currentline > 0) + { + lua_pushfstring(L, "%s:%d: ", ar.source, ar.currentline); + return; + } + lua_rawcheckstack(L, 1); + lua_pushliteral(L, ":: "); // else, no information available... +} +#else +// Can be called without stack space reservation +void luaL_where(lua_State* L, int level) +{ + lua_Debug ar; + if (lua_getinfo(L, level, "sl", &ar) && ar.currentline > 0) + { + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + + lua_rawcheckstack(L, 1); + lua_pushliteral(L, ""); // else, no information available... +} +#endif + +// Can be called without stack space reservation +l_noret luaL_errorL(lua_State* L, const char* fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + lua_error(L); +} + +// }====================================================== + +int luaL_checkoption(lua_State* L, int narg, const char* def, const char* const lst[]) +{ + const char* name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); + int i; + for (i = 0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + const char* msg = lua_pushfstring(L, "invalid option '%s'", name); + luaL_argerrorL(L, narg, msg); +} + +int luaL_newmetatable(lua_State* L, const char* tname) +{ + lua_getfield(L, LUA_REGISTRYINDEX, tname); // get registry.name + if (!lua_isnil(L, -1)) // name already in use? + return 0; // leave previous value on top, but return 0 + lua_pop(L, 1); + lua_newtable(L); // create metatable + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); // registry.name = metatable + return 1; +} + +void* luaL_checkudata(lua_State* L, int ud, const char* tname) +{ + void* p = lua_touserdata(L, ud); + if (p != NULL) + { // value is a userdata? + if (lua_getmetatable(L, ud)) + { // does it have a metatable? + lua_getfield(L, LUA_REGISTRYINDEX, tname); // get correct metatable + if (lua_rawequal(L, -1, -2)) + { // does it have the correct mt? + lua_pop(L, 2); // remove both metatables + return p; + } + } + } + luaL_typeerrorL(L, ud, tname); // else error +} + +void* luaL_checkbuffer(lua_State* L, int narg, size_t* len) +{ + void* b = lua_tobuffer(L, narg, len); + if (!b) + tag_error(L, narg, LUA_TBUFFER); + return b; +} + +void luaL_checkstack(lua_State* L, int space, const char* mes) +{ + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + +void luaL_checktype(lua_State* L, int narg, int t) +{ + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + +void luaL_checkany(lua_State* L, int narg) +{ + if (lua_type(L, narg) == LUA_TNONE) + luaL_error(L, "missing argument #%d", narg); +} + +const char* luaL_checklstring(lua_State* L, int narg, size_t* len) +{ + const char* s = lua_tolstring(L, narg, len); + if (!s) + tag_error(L, narg, LUA_TSTRING); + return s; +} + +const char* luaL_optlstring(lua_State* L, int narg, const char* def, size_t* len) +{ + if (lua_isnoneornil(L, narg)) + { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else + return luaL_checklstring(L, narg, len); +} + +double luaL_checknumber(lua_State* L, int narg) +{ + int isnum; + double d = lua_tonumberx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + +double luaL_optnumber(lua_State* L, int narg, double def) +{ + return luaL_opt(L, luaL_checknumber, narg, def); +} + +int luaL_checkboolean(lua_State* L, int narg) +{ + // This checks specifically for boolean values, ignoring + // all other truthy/falsy values. If the desired result + // is true if value is present then lua_toboolean should + // directly be used instead. + if (!lua_isboolean(L, narg)) + tag_error(L, narg, LUA_TBOOLEAN); + return lua_toboolean(L, narg); +} + +int luaL_optboolean(lua_State* L, int narg, int def) +{ + return luaL_opt(L, luaL_checkboolean, narg, def); +} + +int luaL_checkinteger(lua_State* L, int narg) +{ + int isnum; + int d = lua_tointegerx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + +int luaL_optinteger(lua_State* L, int narg, int def) +{ + return luaL_opt(L, luaL_checkinteger, narg, def); +} + +unsigned luaL_checkunsigned(lua_State* L, int narg) +{ + int isnum; + unsigned d = lua_tounsignedx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + +unsigned luaL_optunsigned(lua_State* L, int narg, unsigned def) +{ + return luaL_opt(L, luaL_checkunsigned, narg, def); +} + +const float* luaL_checkvector(lua_State* L, int narg) +{ + const float* v = lua_tovector(L, narg); + if (!v) + tag_error(L, narg, LUA_TVECTOR); + return v; +} + +const float* luaL_optvector(lua_State* L, int narg, const float* def) +{ + return luaL_opt(L, luaL_checkvector, narg, def); +} + +int luaL_getmetafield(lua_State* L, int obj, const char* event) +{ + if (!lua_getmetatable(L, obj)) // no metatable? + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) + { + lua_pop(L, 2); // remove metatable and metafield + return 0; + } + else + { + lua_remove(L, -2); // remove only metatable + return 1; + } +} + +int luaL_callmeta(lua_State* L, int obj, const char* event) +{ + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) // no metafield? + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + +static int libsize(const luaL_Reg* l) +{ + int size = 0; + for (; l->name; l++) + size++; + return size; +} + +void luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) +{ + if (libname) + { + int size = libsize(l); + // check whether lib already exists + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); // get _LOADED[libname] + if (!lua_istable(L, -1)) + { // not found? + lua_pop(L, 1); // remove previous result + // try global variable (and create one if it does not exist) + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module '%s'", libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); // _LOADED[libname] = new table + } + lua_remove(L, -2); // remove _LOADED table + } + for (; l->name; l++) + { + lua_pushcfunction(L, l->func, l->name); + lua_setfield(L, -2, l->name); + } +} + +const char* luaL_findtable(lua_State* L, int idx, const char* fname, int szhint) +{ + const char* e; + lua_pushvalue(L, idx); + do + { + e = strchr(fname, '.'); + if (e == NULL) + e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) + { // no such field? + lua_pop(L, 1); // remove this nil + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); // new table for field + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); // set new table into field + } + else if (!lua_istable(L, -1)) + { // field has a non-table value? + lua_pop(L, 2); // remove table and value + return fname; // return problematic part of the name + } + lua_remove(L, -2); // remove previous table + fname = e + 1; + } while (*e == '.'); + return NULL; +} + +const char* luaL_typename(lua_State* L, int idx) +{ + const TValue* obj = luaA_toobject(L, idx); + return obj ? luaT_objtypename(L, obj) : "no value"; +} + +int luaL_callyieldable(lua_State* L, int nargs, int nresults) +{ + api_check(L, iscfunction(L->ci->func)); + Closure* cl = clvalue(L->ci->func); + api_check(L, cl->c.cont); + + lua_call(L, nargs, nresults); + + if (FFlag::LuauStacklessPcall) + { + // yielding means we need to propagate yield; resume will call continuation function later + if (isyielded(L)) + return C_CALL_YIELD; + } + else + { + if (L->status == LUA_YIELD || L->status == LUA_BREAK) + return -1; // -1 is a marker for yielding from C + } + + return cl->c.cont(L, LUA_OK); +} + +void luaL_traceback(lua_State* L, lua_State* L1, const char* msg, int level) +{ + api_check(L, level >= 0); + + luaL_Strbuf buf; + luaL_buffinit(L, &buf); + + if (msg) + { + luaL_addstring(&buf, msg); + luaL_addstring(&buf, "\n"); + } + + lua_Debug ar; + for (int i = level; lua_getinfo(L1, i, "sln", &ar); ++i) + { + if (strcmp(ar.what, "C") == 0) + continue; + + if (ar.source) + luaL_addstring(&buf, ar.short_src); + + if (ar.currentline > 0) + { + char line[32]; // manual conversion for performance + char* lineend = line + sizeof(line); + char* lineptr = lineend; + for (unsigned int r = ar.currentline; r > 0; r /= 10) + *--lineptr = '0' + (r % 10); + + luaL_addchar(&buf, ':'); + luaL_addlstring(&buf, lineptr, lineend - lineptr); + } + + if (ar.name) + { + luaL_addstring(&buf, " function "); + luaL_addstring(&buf, ar.name); + } + + luaL_addchar(&buf, '\n'); + } + + luaL_pushresult(&buf); +} + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +static size_t getnextbuffersize(lua_State* L, size_t currentsize, size_t desiredsize) +{ + size_t newsize = currentsize + currentsize / 2; + + // check for size overflow + if (SIZE_MAX - desiredsize < currentsize) + luaL_error(L, "buffer too large"); + + // growth factor might not be enough to satisfy the desired size + if (newsize < desiredsize) + newsize = desiredsize; + + return newsize; +} + +static char* extendstrbuf(luaL_Strbuf* B, size_t additionalsize, int boxloc) +{ + lua_State* L = B->L; + + if (B->storage) + LUAU_ASSERT(B->storage == tsvalue(L->top + boxloc)); + + char* base = B->storage ? B->storage->data : B->buffer; + + size_t capacity = B->end - base; + size_t nextsize = getnextbuffersize(B->L, capacity, capacity + additionalsize); + + TString* newStorage = luaS_bufstart(L, nextsize); + + memcpy(newStorage->data, base, B->p - base); + + // place the string storage at the expected position in the stack + if (base == B->buffer) + { + lua_pushnil(L); + lua_insert(L, boxloc); + } + + setsvalue(L, L->top + boxloc, newStorage); + B->p = newStorage->data + (B->p - base); + B->end = newStorage->data + nextsize; + B->storage = newStorage; + + return B->p; +} + +void luaL_buffinit(lua_State* L, luaL_Strbuf* B) +{ + // start with an internal buffer + B->p = B->buffer; + B->end = B->p + LUA_BUFFERSIZE; + + B->L = L; + B->storage = nullptr; +} + +char* luaL_buffinitsize(lua_State* L, luaL_Strbuf* B, size_t size) +{ + luaL_buffinit(L, B); + return luaL_prepbuffsize(B, size); +} + +char* luaL_prepbuffsize(luaL_Strbuf* B, size_t size) +{ + if (size_t(B->end - B->p) < size) + return extendstrbuf(B, size - (B->end - B->p), -1); + return B->p; +} + +void luaL_addlstring(luaL_Strbuf* B, const char* s, size_t len) +{ + if (size_t(B->end - B->p) < len) + extendstrbuf(B, len - (B->end - B->p), -1); + + memcpy(B->p, s, len); + B->p += len; +} + +void luaL_addvalue(luaL_Strbuf* B) +{ + lua_State* L = B->L; + + size_t vl; + if (const char* s = lua_tolstring(L, -1, &vl)) + { + if (size_t(B->end - B->p) < vl) + extendstrbuf(B, vl - (B->end - B->p), -2); + + memcpy(B->p, s, vl); + B->p += vl; + + lua_pop(L, 1); + } +} + +void luaL_addvalueany(luaL_Strbuf* B, int idx) +{ + lua_State* L = B->L; + + switch (lua_type(L, idx)) + { + case LUA_TNONE: + { + LUAU_ASSERT(!"expected value"); + break; + } + case LUA_TNIL: + luaL_addstring(B, "nil"); + break; + case LUA_TBOOLEAN: + if (lua_toboolean(L, idx)) + luaL_addstring(B, "true"); + else + luaL_addstring(B, "false"); + break; + case LUA_TNUMBER: + { + double n = lua_tonumber(L, idx); + char s[LUAI_MAXNUM2STR]; + char* e = luai_num2str(s, n); + luaL_addlstring(B, s, e - s); + break; + } + case LUA_TSTRING: + { + size_t len; + const char* s = lua_tolstring(L, idx, &len); + luaL_addlstring(B, s, len); + break; + } + default: + { + size_t len; + luaL_tolstring(L, idx, &len); + + // note: luaL_addlstring assumes box is stored at top of stack, so we can't call it here + // instead we use luaL_addvalue which will take the string from the top of the stack and add that + luaL_addvalue(B); + } + } +} + +void luaL_pushresult(luaL_Strbuf* B) +{ + lua_State* L = B->L; + + if (TString* storage = B->storage) + { + luaC_checkGC(L); + + // if we finished just at the end of the string buffer, we can convert it to a mutable stirng without a copy + if (B->p == B->end) + { + setsvalue(L, L->top - 1, luaS_buffinish(L, storage)); + } + else + { + setsvalue(L, L->top - 1, luaS_newlstr(L, storage->data, B->p - storage->data)); + } + } + else + { + lua_pushlstring(L, B->buffer, B->p - B->buffer); + } +} + +void luaL_pushresultsize(luaL_Strbuf* B, size_t size) +{ + B->p += size; + luaL_pushresult(B); +} + +// }====================================================== + +const char* luaL_tolstring(lua_State* L, int idx, size_t* len) +{ + if (luaL_callmeta(L, idx, "__tostring")) // is there a metafield? + { + const char* s = lua_tolstring(L, -1, len); + if (!s) + luaL_error(L, "'__tostring' must return a string"); + return s; + } + + switch (lua_type(L, idx)) + { + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNUMBER: + { + double n = lua_tonumber(L, idx); + char s[LUAI_MAXNUM2STR]; + char* e = luai_num2str(s, n); + lua_pushlstring(L, s, e - s); + break; + } + case LUA_TVECTOR: + { + const float* v = lua_tovector(L, idx); + + char s[LUAI_MAXNUM2STR * LUA_VECTOR_SIZE]; + char* e = s; + for (int i = 0; i < LUA_VECTOR_SIZE; ++i) + { + if (i != 0) + { + *e++ = ','; + *e++ = ' '; + } + e = luai_num2str(e, v[i]); + } + lua_pushlstring(L, s, e - s); + break; + } + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + default: + { + const void* ptr = lua_topointer(L, idx); + unsigned long long enc = lua_encodepointer(L, uintptr_t(ptr)); + lua_pushfstring(L, "%s: 0x%016llx", luaL_typename(L, idx), enc); + break; + } + } + return lua_tolstring(L, -1, len); +} diff --git a/thirdparty/luau/upstream/VM/src/lbaselib.cpp b/thirdparty/luau/upstream/VM/src/lbaselib.cpp new file mode 100644 index 000000000..2b54e5afb --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbaselib.cpp @@ -0,0 +1,519 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lstate.h" +#include "lapi.h" +#include "ldo.h" +#include "ludata.h" + +#include +#include +#include + +LUAU_FASTFLAG(LuauStacklessPcall) + +#ifndef RIVE_LUAU +static void writestring(const char* s, size_t l) +{ + fwrite(s, 1, l, stdout); +} + +static int luaB_print(lua_State* L) +{ + int n = lua_gettop(L); // number of arguments + for (int i = 1; i <= n; i++) + { + size_t l; + const char* s = luaL_tolstring(L, i, &l); // convert to string using __tostring et al + if (i > 1) + writestring("\t", 1); + writestring(s, l); + lua_pop(L, 1); // pop result + } + writestring("\n", 1); + return 0; +} +#endif +static int luaB_tonumber(lua_State* L) +{ + int base = luaL_optinteger(L, 2, 10); + if (base == 10) + { // standard conversion + int isnum = 0; + double n = lua_tonumberx(L, 1, &isnum); + if (isnum) + { + lua_pushnumber(L, n); + return 1; + } + luaL_checkany(L, 1); // error if we don't have any argument + } + else + { + const char* s1 = luaL_checkstring(L, 1); + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + char* s2; + unsigned long long n; + n = strtoull(s1, &s2, base); + if (s1 != s2) + { // at least one valid digit? + while (isspace((unsigned char)(*s2))) + s2++; // skip trailing spaces + if (*s2 == '\0') + { // no invalid trailing characters? + lua_pushnumber(L, (double)n); + return 1; + } + } + } + lua_pushnil(L); // else not a number + return 1; +} + +static int luaB_error(lua_State* L) +{ + int level = luaL_optinteger(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) + { // add extra information? + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + lua_error(L); +} + +static int luaB_getmetatable(lua_State* L) +{ + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) + { + lua_pushnil(L); + return 1; // no metatable + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; // returns either __metatable field (if present) or metatable +} + +static int luaB_setmetatable(lua_State* L) +{ + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + +static void getfunc(lua_State* L, int opt) +{ + if (lua_isfunction(L, 1)) + lua_pushvalue(L, 1); + else + { + lua_Debug ar; + int level = opt ? luaL_optinteger(L, 1, 1) : luaL_checkinteger(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getinfo(L, level, "f", &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", level); + } +} + +static int luaB_getfenv(lua_State* L) +{ + getfunc(L, 1); + if (lua_iscfunction(L, -1)) // is a C function? + lua_pushvalue(L, LUA_GLOBALSINDEX); // return the thread's global env. + else + lua_getfenv(L, -1); + lua_setsafeenv(L, -1, false); + return 1; +} + +static int luaB_setfenv(lua_State* L) +{ + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + lua_setsafeenv(L, -1, false); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) + { + // change environment of current thread + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, "'setfenv' cannot change environment of given object"); + return 1; +} + +static int luaB_rawequal(lua_State* L) +{ + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + +static int luaB_rawget(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + +static int luaB_rawlen(lua_State* L) +{ + int tt = lua_type(L, 1); + luaL_argcheck(L, tt == LUA_TTABLE || tt == LUA_TSTRING, 1, "table or string expected"); + int len = lua_objlen(L, 1); + lua_pushinteger(L, len); + return 1; +} + +static int luaB_gcinfo(lua_State* L) +{ + lua_pushinteger(L, lua_gc(L, LUA_GCCOUNT, 0)); + return 1; +} + +static int luaB_type(lua_State* L) +{ + luaL_checkany(L, 1); + // resulting name doesn't differentiate between userdata types + lua_pushstring(L, lua_typename(L, lua_type(L, 1))); + return 1; +} + +static int luaB_typeof(lua_State* L) +{ + luaL_checkany(L, 1); + // resulting name returns __type if specified unless the input is a newproxy-created userdata + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + +int luaB_next(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); // create a 2nd argument if there isn't one + if (lua_next(L, 1)) + return 2; + else + { + lua_pushnil(L); + return 1; + } +} + +static int luaB_pairs(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); // return generator, + lua_pushvalue(L, 1); // state, + lua_pushnil(L); // and initial value + return 3; +} + +int luaB_inext(lua_State* L) +{ + int i = luaL_checkinteger(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; // next value + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; +} + +static int luaB_ipairs(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); // return generator, + lua_pushvalue(L, 1); // state, + lua_pushinteger(L, 0); // and initial value + return 3; +} + +static int luaB_assert(lua_State* L) +{ + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + +static int luaB_select(lua_State* L) +{ + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') + { + lua_pushinteger(L, n - 1); + return 1; + } + else + { + int i = luaL_checkinteger(L, 1); + if (i < 0) + i = n + i; + else if (i > n) + i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + +static void luaB_pcallrun(lua_State* L, void* ud) +{ + StkId func = (StkId)ud; + + if (FFlag::LuauStacklessPcall) + { + // if we can yield, schedule a call setup with postponed reentry + luaD_callint(L, func, LUA_MULTRET, lua_isyieldable(L) != 0); + } + else + { + luaD_call(L, func, LUA_MULTRET); + } +} + +static int luaB_pcally(lua_State* L) +{ + luaL_checkany(L, 1); + + StkId func = L->base; + + // any errors from this point on are handled by continuation + L->ci->flags |= LUA_CALLINFO_HANDLE; + + int status = luaD_pcall(L, luaB_pcallrun, func, savestack(L, func), 0); + + // necessary to accommodate functions that return lots of values + expandstacklimit(L, L->top); + + if (FFlag::LuauStacklessPcall) + { + // yielding means we need to propagate yield; resume will call continuation function later + if (status == 0 && isyielded(L)) + return C_CALL_YIELD; + } + else + { + // yielding means we need to propagate yield; resume will call continuation function later + if (status == 0 && (L->status == LUA_YIELD || L->status == LUA_BREAK)) + return -1; // -1 is a marker for yielding from C + } + + // immediate return (error or success) + lua_rawcheckstack(L, 1); + lua_pushboolean(L, status == 0); + lua_insert(L, 1); + return lua_gettop(L); // return status + all results +} + +static int luaB_pcallcont(lua_State* L, int status) +{ + if (status == 0) + { + lua_rawcheckstack(L, 1); + lua_pushboolean(L, true); + lua_insert(L, 1); // insert status before all results + return lua_gettop(L); + } + else + { + lua_rawcheckstack(L, 1); + lua_pushboolean(L, false); + lua_insert(L, -2); // insert status before error object + return 2; + } +} + +static int luaB_xpcally(lua_State* L) +{ + luaL_checktype(L, 2, LUA_TFUNCTION); + + // swap function & error function + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); + lua_replace(L, 1); + lua_replace(L, 2); + // at this point the stack looks like err, f, args + + // any errors from this point on are handled by continuation + L->ci->flags |= LUA_CALLINFO_HANDLE; + + StkId errf = L->base; + StkId func = L->base + 1; + + int status = luaD_pcall(L, luaB_pcallrun, func, savestack(L, func), savestack(L, errf)); + + // necessary to accommodate functions that return lots of values + expandstacklimit(L, L->top); + + if (FFlag::LuauStacklessPcall) + { + // yielding means we need to propagate yield; resume will call continuation function later + if (status == 0 && isyielded(L)) + return C_CALL_YIELD; + } + else + { + // yielding means we need to propagate yield; resume will call continuation function later + if (status == 0 && (L->status == LUA_YIELD || L->status == LUA_BREAK)) + return -1; // -1 is a marker for yielding from C + } + + // immediate return (error or success) + lua_rawcheckstack(L, 1); + lua_pushboolean(L, status == 0); + lua_replace(L, 1); // replace error function with status + return lua_gettop(L); // return status + all results +} + +static void luaB_xpcallerr(lua_State* L, void* ud) +{ + StkId func = (StkId)ud; + + luaD_callny(L, func, 1); +} + +static int luaB_xpcallcont(lua_State* L, int status) +{ + if (status == 0) + { + lua_rawcheckstack(L, 1); + lua_pushboolean(L, true); + lua_replace(L, 1); // replace error function with status + return lua_gettop(L); // return status + all results + } + else + { + lua_rawcheckstack(L, 3); + lua_pushboolean(L, false); + lua_pushvalue(L, 1); // push error function on top of the stack + lua_pushvalue(L, -3); // push error object (that was on top of the stack before) + + StkId errf = L->top - 2; + ptrdiff_t oldtopoffset = savestack(L, errf); + + int err = luaD_pcall(L, luaB_xpcallerr, errf, oldtopoffset, 0); + + if (err != 0) + { + int errstatus = status; + + // in general we preserve the status, except for cases when the error handler fails + // out of memory is treated specially because it's common for it to be cascading, in which case we preserve the code + if (status == LUA_ERRMEM && err == LUA_ERRMEM) + errstatus = LUA_ERRMEM; + else + errstatus = LUA_ERRERR; + + StkId oldtop = restorestack(L, oldtopoffset); + luaD_seterrorobj(L, errstatus, oldtop); + } + + return 2; + } +} + +static int luaB_tostring(lua_State* L) +{ + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; +} +#ifndef RIVE_LUAU +static int luaB_newproxy(lua_State* L) +{ + int t = lua_type(L, 1); + luaL_argexpected(L, t == LUA_TNONE || t == LUA_TNIL || t == LUA_TBOOLEAN, 1, "nil or boolean"); + + bool needsmt = lua_toboolean(L, 1); + + lua_newuserdatatagged(L, 0, UTAG_PROXY); + + if (needsmt) + { + lua_newtable(L); + lua_setmetatable(L, -2); + } + + return 1; +} +#endif +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"error", luaB_error}, + {"gcinfo", luaB_gcinfo}, + {"getfenv", luaB_getfenv}, + {"getmetatable", luaB_getmetatable}, + {"next", luaB_next}, +#ifndef RIVE_LUAU + {"newproxy", luaB_newproxy}, + {"print", luaB_print}, +#endif + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"rawlen", luaB_rawlen}, + {"select", luaB_select}, + {"setfenv", luaB_setfenv}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"typeof", luaB_typeof}, + {NULL, NULL}, +}; + +static void auxopen(lua_State* L, const char* name, lua_CFunction f, lua_CFunction u) +{ + lua_pushcfunction(L, u, NULL); + lua_pushcclosure(L, f, name, 1); + lua_setfield(L, -2, name); +} + +int luaopen_base(lua_State* L) +{ + // set global _G + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + + // open lib into global table + luaL_register(L, "_G", base_funcs); + lua_pushliteral(L, "Luau"); + lua_setglobal(L, "_VERSION"); // set global _VERSION + + // `ipairs' and `pairs' need auxiliary functions as upvalues + auxopen(L, "ipairs", luaB_ipairs, luaB_inext); + auxopen(L, "pairs", luaB_pairs, luaB_next); + + lua_pushcclosurek(L, luaB_pcally, "pcall", 0, luaB_pcallcont); + lua_setfield(L, -2, "pcall"); + + lua_pushcclosurek(L, luaB_xpcally, "xpcall", 0, luaB_xpcallcont); + lua_setfield(L, -2, "xpcall"); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lbitlib.cpp b/thirdparty/luau/upstream/VM/src/lbitlib.cpp new file mode 100644 index 000000000..1d07c7a43 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbitlib.cpp @@ -0,0 +1,246 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lcommon.h" +#include "lnumutils.h" + +#define ALLONES ~0u +#define NBITS int(8 * sizeof(unsigned)) + +// macro to trim extra bits +#define trim(x) ((x) & ALLONES) + +// builds a number with 'n' ones (1 <= n <= NBITS) +#define mask(n) (~((ALLONES << 1) << ((n)-1))) + +typedef unsigned b_uint; + +static b_uint andaux(lua_State* L) +{ + int i, n = lua_gettop(L); + b_uint r = ~(b_uint)0; + for (i = 1; i <= n; i++) + r &= luaL_checkunsigned(L, i); + return trim(r); +} + +static int b_and(lua_State* L) +{ + b_uint r = andaux(L); + lua_pushunsigned(L, r); + return 1; +} + +static int b_test(lua_State* L) +{ + b_uint r = andaux(L); + lua_pushboolean(L, r != 0); + return 1; +} + +static int b_or(lua_State* L) +{ + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r |= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + +static int b_xor(lua_State* L) +{ + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r ^= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + +static int b_not(lua_State* L) +{ + b_uint r = ~luaL_checkunsigned(L, 1); + lua_pushunsigned(L, trim(r)); + return 1; +} + +static int b_shift(lua_State* L, b_uint r, int i) +{ + if (i < 0) + { // shift right? + i = -i; + r = trim(r); + if (i >= NBITS) + r = 0; + else + r >>= i; + } + else + { // shift left + if (i >= NBITS) + r = 0; + else + r <<= i; + r = trim(r); + } + lua_pushunsigned(L, r); + return 1; +} + +static int b_lshift(lua_State* L) +{ + return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2)); +} + +static int b_rshift(lua_State* L) +{ + return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2)); +} + +static int b_arshift(lua_State* L) +{ + b_uint r = luaL_checkunsigned(L, 1); + int i = luaL_checkinteger(L, 2); + if (i < 0 || !(r & ((b_uint)1 << (NBITS - 1)))) + return b_shift(L, r, -i); + else + { // arithmetic shift for 'negative' number + if (i >= NBITS) + r = ALLONES; + else + r = trim((r >> i) | ~(~(b_uint)0 >> i)); // add signal bit + lua_pushunsigned(L, r); + return 1; + } +} + +static int b_rot(lua_State* L, int i) +{ + b_uint r = luaL_checkunsigned(L, 1); + i &= (NBITS - 1); // i = i % NBITS + r = trim(r); + if (i != 0) // avoid undefined shift of NBITS when i == 0 + r = (r << i) | (r >> (NBITS - i)); + lua_pushunsigned(L, trim(r)); + return 1; +} + +static int b_lrot(lua_State* L) +{ + return b_rot(L, luaL_checkinteger(L, 2)); +} + +static int b_rrot(lua_State* L) +{ + return b_rot(L, -luaL_checkinteger(L, 2)); +} + +/* +** get field and width arguments for field-manipulation functions, +** checking whether they are valid. +** ('luaL_error' called without 'return' to avoid later warnings about +** 'width' being used uninitialized.) +*/ +static int fieldargs(lua_State* L, int farg, int* width) +{ + int f = luaL_checkinteger(L, farg); + int w = luaL_optinteger(L, farg + 1, 1); + luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); + luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + if (f + w > NBITS) + luaL_error(L, "trying to access non-existent bits"); + *width = w; + return f; +} + +static int b_extract(lua_State* L) +{ + int w; + b_uint r = luaL_checkunsigned(L, 1); + int f = fieldargs(L, 2, &w); + r = (r >> f) & mask(w); + lua_pushunsigned(L, r); + return 1; +} + +static int b_replace(lua_State* L) +{ + int w; + b_uint r = luaL_checkunsigned(L, 1); + b_uint v = luaL_checkunsigned(L, 2); + int f = fieldargs(L, 3, &w); + int m = mask(w); + v &= m; // erase bits outside given width + r = (r & ~(m << f)) | (v << f); + lua_pushunsigned(L, r); + return 1; +} + +static int b_countlz(lua_State* L) +{ + b_uint v = luaL_checkunsigned(L, 1); + + b_uint r = NBITS; + for (int i = 0; i < NBITS; ++i) + if (v & (1u << (NBITS - 1 - i))) + { + r = i; + break; + } + + lua_pushunsigned(L, r); + return 1; +} + +static int b_countrz(lua_State* L) +{ + b_uint v = luaL_checkunsigned(L, 1); + + b_uint r = NBITS; + for (int i = 0; i < NBITS; ++i) + if (v & (1u << i)) + { + r = i; + break; + } + + lua_pushunsigned(L, r); + return 1; +} + +static int b_swap(lua_State* L) +{ + b_uint n = luaL_checkunsigned(L, 1); + n = (n << 24) | ((n << 8) & 0xff0000) | ((n >> 8) & 0xff00) | (n >> 24); + + lua_pushunsigned(L, n); + return 1; +} + +static const luaL_Reg bitlib[] = { + {"arshift", b_arshift}, + {"band", b_and}, + {"bnot", b_not}, + {"bor", b_or}, + {"bxor", b_xor}, + {"btest", b_test}, + {"extract", b_extract}, + {"lrotate", b_lrot}, + {"lshift", b_lshift}, + {"replace", b_replace}, + {"rrotate", b_rrot}, + {"rshift", b_rshift}, + {"countlz", b_countlz}, + {"countrz", b_countrz}, + {"byteswap", b_swap}, + {NULL, NULL}, +}; + +int luaopen_bit32(lua_State* L) +{ + luaL_register(L, LUA_BITLIBNAME, bitlib); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lbuffer.cpp b/thirdparty/luau/upstream/VM/src/lbuffer.cpp new file mode 100644 index 000000000..04e5eecc2 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbuffer.cpp @@ -0,0 +1,24 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lbuffer.h" + +#include "lgc.h" +#include "lmem.h" + +#include + +Buffer* luaB_newbuffer(lua_State* L, size_t s) +{ + if (s > MAX_BUFFER_SIZE) + luaM_toobig(L); + + Buffer* b = luaM_newgco(L, Buffer, sizebuffer(s), L->activememcat); + luaC_init(L, b, LUA_TBUFFER); + b->len = unsigned(s); + memset(b->data, 0, b->len); + return b; +} + +void luaB_freebuffer(lua_State* L, Buffer* b, lua_Page* page) +{ + luaM_freegco(L, b, sizebuffer(b->len), b->memcat, page); +} diff --git a/thirdparty/luau/upstream/VM/src/lbuffer.h b/thirdparty/luau/upstream/VM/src/lbuffer.h new file mode 100644 index 000000000..728e89bac --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbuffer.h @@ -0,0 +1,13 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#pragma once + +#include "lobject.h" + +// buffer size limit +#define MAX_BUFFER_SIZE (1 << 30) + +// GCObject size has to be at least 16 bytes, so a minimum of 8 bytes is always reserved +#define sizebuffer(len) (offsetof(Buffer, data) + ((len) < 8 ? 8 : (len))) + +LUAI_FUNC Buffer* luaB_newbuffer(lua_State* L, size_t s); +LUAI_FUNC void luaB_freebuffer(lua_State* L, Buffer* u, struct lua_Page* page); diff --git a/thirdparty/luau/upstream/VM/src/lbuflib.cpp b/thirdparty/luau/upstream/VM/src/lbuflib.cpp new file mode 100644 index 000000000..ec14eb272 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbuflib.cpp @@ -0,0 +1,366 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lualib.h" + +#include "lcommon.h" +#include "lbuffer.h" + +#if defined(LUAU_BIG_ENDIAN) +#include +#endif + +#include + +// while C API returns 'size_t' for binary compatibility in case of future extensions, +// in the current implementation, length and offset are limited to 31 bits +// because offset is limited to an integer, a single 64bit comparison can be used and will not overflow +#define isoutofbounds(offset, len, accessize) (uint64_t(unsigned(offset)) + (accessize) > uint64_t(len)) + +static_assert(MAX_BUFFER_SIZE <= INT_MAX, "current implementation can't handle a larger limit"); + +#if defined(LUAU_BIG_ENDIAN) +template +inline T buffer_swapbe(T v) +{ + if (sizeof(T) == 8) + return htole64(v); + else if (sizeof(T) == 4) + return htole32(v); + else if (sizeof(T) == 2) + return htole16(v); + else + return v; +} +#endif + +static int buffer_create(lua_State* L) +{ + int size = luaL_checkinteger(L, 1); + + luaL_argcheck(L, size >= 0, 1, "size"); + + lua_newbuffer(L, size); + return 1; +} + +static int buffer_fromstring(lua_State* L) +{ + size_t len = 0; + const char* val = luaL_checklstring(L, 1, &len); + + void* data = lua_newbuffer(L, len); + memcpy(data, val, len); + return 1; +} + +static int buffer_tostring(lua_State* L) +{ + size_t len = 0; + void* data = luaL_checkbuffer(L, 1, &len); + + lua_pushlstring(L, (char*)data, len); + return 1; +} + +template +static int buffer_readinteger(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + + if (isoutofbounds(offset, len, sizeof(T))) + luaL_error(L, "buffer access out of bounds"); + + T val; + memcpy(&val, (char*)buf + offset, sizeof(T)); + +#if defined(LUAU_BIG_ENDIAN) + val = buffer_swapbe(val); +#endif + + lua_pushnumber(L, double(val)); + return 1; +} + +template +static int buffer_writeinteger(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + int value = luaL_checkunsigned(L, 3); + + if (isoutofbounds(offset, len, sizeof(T))) + luaL_error(L, "buffer access out of bounds"); + + T val = T(value); + +#if defined(LUAU_BIG_ENDIAN) + val = buffer_swapbe(val); +#endif + + memcpy((char*)buf + offset, &val, sizeof(T)); + return 0; +} + +template +static int buffer_readfp(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + + if (isoutofbounds(offset, len, sizeof(T))) + luaL_error(L, "buffer access out of bounds"); + + T val; + +#if defined(LUAU_BIG_ENDIAN) + static_assert(sizeof(T) == sizeof(StorageType), "type size must match to reinterpret data"); + StorageType tmp; + memcpy(&tmp, (char*)buf + offset, sizeof(tmp)); + tmp = buffer_swapbe(tmp); + + memcpy(&val, &tmp, sizeof(tmp)); +#else + memcpy(&val, (char*)buf + offset, sizeof(T)); +#endif + + lua_pushnumber(L, double(val)); + return 1; +} + +template +static int buffer_writefp(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + double value = luaL_checknumber(L, 3); + + if (isoutofbounds(offset, len, sizeof(T))) + luaL_error(L, "buffer access out of bounds"); + + T val = T(value); + +#if defined(LUAU_BIG_ENDIAN) + static_assert(sizeof(T) == sizeof(StorageType), "type size must match to reinterpret data"); + StorageType tmp; + memcpy(&tmp, &val, sizeof(tmp)); + tmp = buffer_swapbe(tmp); + + memcpy((char*)buf + offset, &tmp, sizeof(tmp)); +#else + memcpy((char*)buf + offset, &val, sizeof(T)); +#endif + + return 0; +} + +static int buffer_readstring(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + int size = luaL_checkinteger(L, 3); + + luaL_argcheck(L, size >= 0, 3, "size"); + + if (isoutofbounds(offset, len, unsigned(size))) + luaL_error(L, "buffer access out of bounds"); + + lua_pushlstring(L, (char*)buf + offset, size); + return 1; +} + +static int buffer_writestring(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + size_t size = 0; + const char* val = luaL_checklstring(L, 3, &size); + int count = luaL_optinteger(L, 4, int(size)); + + luaL_argcheck(L, count >= 0, 4, "count"); + + if (size_t(count) > size) + luaL_error(L, "string length overflow"); + + // string size can't exceed INT_MAX at this point + if (isoutofbounds(offset, len, unsigned(count))) + luaL_error(L, "buffer access out of bounds"); + + memcpy((char*)buf + offset, val, count); + return 0; +} + +static int buffer_len(lua_State* L) +{ + size_t len = 0; + luaL_checkbuffer(L, 1, &len); + + lua_pushnumber(L, double(unsigned(len))); + return 1; +} + +static int buffer_copy(lua_State* L) +{ + size_t tlen = 0; + void* tbuf = luaL_checkbuffer(L, 1, &tlen); + int toffset = luaL_checkinteger(L, 2); + + size_t slen = 0; + void* sbuf = luaL_checkbuffer(L, 3, &slen); + int soffset = luaL_optinteger(L, 4, 0); + + int size = luaL_optinteger(L, 5, int(slen) - soffset); + + if (size < 0) + luaL_error(L, "buffer access out of bounds"); + + if (isoutofbounds(soffset, slen, unsigned(size))) + luaL_error(L, "buffer access out of bounds"); + + if (isoutofbounds(toffset, tlen, unsigned(size))) + luaL_error(L, "buffer access out of bounds"); + + memmove((char*)tbuf + toffset, (char*)sbuf + soffset, size); + return 0; +} + +static int buffer_fill(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + unsigned value = luaL_checkunsigned(L, 3); + int size = luaL_optinteger(L, 4, int(len) - offset); + + if (size < 0) + luaL_error(L, "buffer access out of bounds"); + + if (isoutofbounds(offset, len, unsigned(size))) + luaL_error(L, "buffer access out of bounds"); + + memset((char*)buf + offset, value & 0xff, size); + return 0; +} + +static int buffer_readbits(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int64_t bitoffset = (int64_t)luaL_checknumber(L, 2); + int bitcount = luaL_checkinteger(L, 3); + + if (bitoffset < 0) + luaL_error(L, "buffer access out of bounds"); + + if (unsigned(bitcount) > 32) + luaL_error(L, "bit count is out of range of [0; 32]"); + + if (uint64_t(bitoffset + bitcount) > uint64_t(len) * 8) + luaL_error(L, "buffer access out of bounds"); + + unsigned startbyte = unsigned(bitoffset / 8); + unsigned endbyte = unsigned((bitoffset + bitcount + 7) / 8); + + uint64_t data = 0; + +#if defined(LUAU_BIG_ENDIAN) + for (int i = int(endbyte) - 1; i >= int(startbyte); i--) + data = (data << 8) + uint8_t(((char*)buf)[i]); +#else + memcpy(&data, (char*)buf + startbyte, endbyte - startbyte); +#endif + + uint64_t subbyteoffset = bitoffset & 0x7; + uint64_t mask = (1ull << bitcount) - 1; + + lua_pushunsigned(L, unsigned((data >> subbyteoffset) & mask)); + return 1; +} + +static int buffer_writebits(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int64_t bitoffset = (int64_t)luaL_checknumber(L, 2); + int bitcount = luaL_checkinteger(L, 3); + unsigned value = luaL_checkunsigned(L, 4); + + if (bitoffset < 0) + luaL_error(L, "buffer access out of bounds"); + + if (unsigned(bitcount) > 32) + luaL_error(L, "bit count is out of range of [0; 32]"); + + if (uint64_t(bitoffset + bitcount) > uint64_t(len) * 8) + luaL_error(L, "buffer access out of bounds"); + + unsigned startbyte = unsigned(bitoffset / 8); + unsigned endbyte = unsigned((bitoffset + bitcount + 7) / 8); + + uint64_t data = 0; + +#if defined(LUAU_BIG_ENDIAN) + for (int i = int(endbyte) - 1; i >= int(startbyte); i--) + data = data * 256 + uint8_t(((char*)buf)[i]); +#else + memcpy(&data, (char*)buf + startbyte, endbyte - startbyte); +#endif + + uint64_t subbyteoffset = bitoffset & 0x7; + uint64_t mask = ((1ull << bitcount) - 1) << subbyteoffset; + + data = (data & ~mask) | ((uint64_t(value) << subbyteoffset) & mask); + +#if defined(LUAU_BIG_ENDIAN) + for (int i = int(startbyte); i < int(endbyte); i++) + { + ((char*)buf)[i] = data & 0xff; + data >>= 8; + } +#else + memcpy((char*)buf + startbyte, &data, endbyte - startbyte); +#endif + return 0; +} + +static const luaL_Reg bufferlib[] = { + {"create", buffer_create}, + {"fromstring", buffer_fromstring}, + {"tostring", buffer_tostring}, + {"readi8", buffer_readinteger}, + {"readu8", buffer_readinteger}, + {"readi16", buffer_readinteger}, + {"readu16", buffer_readinteger}, + {"readi32", buffer_readinteger}, + {"readu32", buffer_readinteger}, + {"readf32", buffer_readfp}, + {"readf64", buffer_readfp}, + {"writei8", buffer_writeinteger}, + {"writeu8", buffer_writeinteger}, + {"writei16", buffer_writeinteger}, + {"writeu16", buffer_writeinteger}, + {"writei32", buffer_writeinteger}, + {"writeu32", buffer_writeinteger}, + {"writef32", buffer_writefp}, + {"writef64", buffer_writefp}, + {"readstring", buffer_readstring}, + {"writestring", buffer_writestring}, + {"len", buffer_len}, + {"copy", buffer_copy}, + {"fill", buffer_fill}, + {"readbits", buffer_readbits}, + {"writebits", buffer_writebits}, + {NULL, NULL}, +}; + +int luaopen_buffer(lua_State* L) +{ + luaL_register(L, LUA_BUFFERLIBNAME, bufferlib); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lbuiltins.cpp b/thirdparty/luau/upstream/VM/src/lbuiltins.cpp new file mode 100644 index 000000000..15b6cd2f8 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbuiltins.cpp @@ -0,0 +1,2160 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lbuiltins.h" + +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lgc.h" +#include "lnumutils.h" +#include "ldo.h" +#include "lbuffer.h" + +#include +#include + +#ifdef _MSC_VER +#include +#endif + +#ifdef LUAU_TARGET_SSE41 +#include + +#ifndef _MSC_VER +#include // on MSVC this comes from intrin.h +#endif +#endif + +// luauF functions implement FASTCALL instruction that performs a direct execution of some builtin functions from the VM +// The rule of thumb is that FASTCALL functions can not call user code, yield, fail, or reallocate stack. +// If types of the arguments mismatch, luauF_* needs to return -1 and the execution will fall back to the usual call path +// If luauF_* succeeds, it needs to return *all* requested arguments, filling results with nil as appropriate. +// On input, nparams refers to the actual number of arguments (0+), whereas nresults contains LUA_MULTRET for arbitrary returns or 0+ for a +// fixed-length return +// Because of this, and the fact that "extra" returned values will be ignored, implementations below typically check that nresults is <= expected +// number, which covers the LUA_MULTRET case. + +static int luauF_assert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults == 0 && !l_isfalse(arg0)) + { + return 0; + } + + return -1; +} + +static int luauF_abs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, fabs(a1)); + return 1; + } + + return -1; +} + +static int luauF_acos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, acos(a1)); + return 1; + } + + return -1; +} + +static int luauF_asin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, asin(a1)); + return 1; + } + + return -1; +} + +static int luauF_atan2(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + setnvalue(res, atan2(a1, a2)); + return 1; + } + + return -1; +} + +static int luauF_atan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, atan(a1)); + return 1; + } + + return -1; +} + +LUAU_FASTMATH_BEGIN +static int luauF_ceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, ceil(a1)); + return 1; + } + + return -1; +} +LUAU_FASTMATH_END + +static int luauF_cosh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, cosh(a1)); + return 1; + } + + return -1; +} + +static int luauF_cos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, cos(a1)); + return 1; + } + + return -1; +} + +static int luauF_deg(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + const double rpd = (3.14159265358979323846 / 180.0); + setnvalue(res, a1 / rpd); + return 1; + } + + return -1; +} + +static int luauF_exp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, exp(a1)); + return 1; + } + + return -1; +} + +LUAU_FASTMATH_BEGIN +static int luauF_floor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, floor(a1)); + return 1; + } + + return -1; +} +LUAU_FASTMATH_END + +static int luauF_fmod(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + setnvalue(res, fmod(a1, a2)); + return 1; + } + + return -1; +} + +static int luauF_frexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 2 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + int e; + double f = frexp(a1, &e); + setnvalue(res, f); + setnvalue(res + 1, double(e)); + return 2; + } + + return -1; +} + +static int luauF_ldexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + setnvalue(res, ldexp(a1, int(a2))); + return 1; + } + + return -1; +} + +static int luauF_log10(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, log10(a1)); + return 1; + } + + return -1; +} + +static int luauF_log(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + + if (nparams == 1) + { + setnvalue(res, log(a1)); + return 1; + } + else if (ttisnumber(args)) + { + double a2 = nvalue(args); + + if (a2 == 2.0) + { + setnvalue(res, log2(a1)); + return 1; + } + else if (a2 == 10.0) + { + setnvalue(res, log10(a1)); + return 1; + } + else + { + setnvalue(res, log(a1) / log(a2)); + return 1; + } + } + } + + return -1; +} + +static int luauF_max(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + double r = (a2 > a1) ? a2 : a1; + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + double a = nvalue(args + (i - 2)); + + r = (a > r) ? a : r; + } + + setnvalue(res, r); + return 1; + } + + return -1; +} + +static int luauF_min(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + double r = (a2 < a1) ? a2 : a1; + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + double a = nvalue(args + (i - 2)); + + r = (a < r) ? a : r; + } + + setnvalue(res, r); + return 1; + } + + return -1; +} + +static int luauF_modf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 2 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + double ip; + double fp = modf(a1, &ip); + setnvalue(res, ip); + setnvalue(res + 1, fp); + return 2; + } + + return -1; +} + +static int luauF_pow(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + setnvalue(res, pow(a1, a2)); + return 1; + } + + return -1; +} + +static int luauF_rad(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + const double rpd = (3.14159265358979323846 / 180.0); + setnvalue(res, a1 * rpd); + return 1; + } + + return -1; +} + +static int luauF_sinh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, sinh(a1)); + return 1; + } + + return -1; +} + +static int luauF_sin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, sin(a1)); + return 1; + } + + return -1; +} + +LUAU_FASTMATH_BEGIN +static int luauF_sqrt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, sqrt(a1)); + return 1; + } + + return -1; +} +LUAU_FASTMATH_END + +static int luauF_tanh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, tanh(a1)); + return 1; + } + + return -1; +} + +static int luauF_tan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, tan(a1)); + return 1; + } + + return -1; +} + +static int luauF_arshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u; + luai_num2unsigned(u, a1); + int s = int(a2); + + // note: we only specialize fast-path that doesn't require further conditionals (negative shifts and shifts greater or equal to bit width can + // be handled generically) + if (unsigned(s) < 32) + { + // note: technically right shift of negative values is UB, but this behavior is getting defined in C++20 and all compilers do the right + // (shift) thing. + uint32_t r = int32_t(u) >> s; + + setnvalue(res, double(r)); + return 1; + } + } + + return -1; +} + +static int luauF_band(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u1, u2; + luai_num2unsigned(u1, a1); + luai_num2unsigned(u2, a2); + + uint32_t r = u1 & u2; + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + double a = nvalue(args + (i - 2)); + unsigned u; + luai_num2unsigned(u, a); + + r &= u; + } + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_bnot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + unsigned u; + luai_num2unsigned(u, a1); + + uint32_t r = ~u; + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_bor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u1, u2; + luai_num2unsigned(u1, a1); + luai_num2unsigned(u2, a2); + + uint32_t r = u1 | u2; + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + double a = nvalue(args + (i - 2)); + unsigned u; + luai_num2unsigned(u, a); + + r |= u; + } + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_bxor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u1, u2; + luai_num2unsigned(u1, a1); + luai_num2unsigned(u2, a2); + + uint32_t r = u1 ^ u2; + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + double a = nvalue(args + (i - 2)); + unsigned u; + luai_num2unsigned(u, a); + + r ^= u; + } + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_btest(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u1, u2; + luai_num2unsigned(u1, a1); + luai_num2unsigned(u2, a2); + + uint32_t r = u1 & u2; + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + double a = nvalue(args + (i - 2)); + unsigned u; + luai_num2unsigned(u, a); + + r &= u; + } + + setbvalue(res, r != 0); + return 1; + } + + return -1; +} + +static int luauF_extract(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned n; + luai_num2unsigned(n, a1); + int f = int(a2); + + if (nparams == 2) + { + if (unsigned(f) < 32) + { + uint32_t m = 1; + uint32_t r = (n >> f) & m; + + setnvalue(res, double(r)); + return 1; + } + } + else if (ttisnumber(args + 1)) + { + double a3 = nvalue(args + 1); + int w = int(a3); + + if (f >= 0 && w > 0 && f + w <= 32) + { + uint32_t m = ~(0xfffffffeu << (w - 1)); + uint32_t r = (n >> f) & m; + + setnvalue(res, double(r)); + return 1; + } + } + } + + return -1; +} + +static int luauF_lrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u; + luai_num2unsigned(u, a1); + int s = int(a2); + + // MSVC doesn't recognize the rotate form that is UB-safe +#ifdef _MSC_VER + uint32_t r = _rotl(u, s); +#else + uint32_t r = (u << (s & 31)) | (u >> ((32 - s) & 31)); +#endif + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_lshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u; + luai_num2unsigned(u, a1); + int s = int(a2); + + // note: we only specialize fast-path that doesn't require further conditionals (negative shifts and shifts greater or equal to bit width can + // be handled generically) + if (unsigned(s) < 32) + { + uint32_t r = u << s; + + setnvalue(res, double(r)); + return 1; + } + } + + return -1; +} + +static int luauF_replace(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + double a3 = nvalue(args + 1); + + unsigned n, v; + luai_num2unsigned(n, a1); + luai_num2unsigned(v, a2); + int f = int(a3); + + if (nparams == 3) + { + if (unsigned(f) < 32) + { + uint32_t m = 1; + uint32_t r = (n & ~(m << f)) | ((v & m) << f); + + setnvalue(res, double(r)); + return 1; + } + } + else if (ttisnumber(args + 2)) + { + double a4 = nvalue(args + 2); + int w = int(a4); + + if (f >= 0 && w > 0 && f + w <= 32) + { + uint32_t m = ~(0xfffffffeu << (w - 1)); + uint32_t r = (n & ~(m << f)) | ((v & m) << f); + + setnvalue(res, double(r)); + return 1; + } + } + } + + return -1; +} + +static int luauF_rrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u; + luai_num2unsigned(u, a1); + int s = int(a2); + + // MSVC doesn't recognize the rotate form that is UB-safe +#ifdef _MSC_VER + uint32_t r = _rotr(u, s); +#else + uint32_t r = (u >> (s & 31)) | (u << ((32 - s) & 31)); +#endif + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_rshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned u; + luai_num2unsigned(u, a1); + int s = int(a2); + + // note: we only specialize fast-path that doesn't require further conditionals (negative shifts and shifts greater or equal to bit width can + // be handled generically) + if (unsigned(s) < 32) + { + uint32_t r = u >> s; + + setnvalue(res, double(r)); + return 1; + } + } + + return -1; +} + +static int luauF_type(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1) + { + int tt = ttype(arg0); + TString* ttname = L->global->ttname[tt]; + + setsvalue(L, res, ttname); + return 1; + } + + return -1; +} + +static int luauF_byte(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && ttisstring(arg0) && ttisnumber(args)) + { + TString* ts = tsvalue(arg0); + int i = int(nvalue(args)); + int j = (nparams >= 3) ? (ttisnumber(args + 1) ? int(nvalue(args + 1)) : 0) : i; + + if (i >= 1 && j >= i && j <= int(ts->len)) + { + int c = j - i + 1; + const char* s = getstr(ts); + + // for vararg returns, we only support a single result + // this is because this frees us from concerns about stack space + if (c == (nresults < 0 ? 1 : nresults)) + { + for (int k = 0; k < c; ++k) + { + setnvalue(res + k, uint8_t(s[i + k - 1])); + } + + return c; + } + } + } + + return -1; +} + +static int luauF_char(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + char buffer[8]; + + if (nparams < int(sizeof(buffer)) && nresults <= 1) + { + if (luaC_needsGC(L)) + return -1; // we can't call luaC_checkGC so fall back to C implementation + + if (nparams >= 1) + { + if (!ttisnumber(arg0)) + return -1; + + int ch = int(nvalue(arg0)); + + if ((unsigned char)(ch) != ch) + return -1; + + buffer[0] = ch; + } + + for (int i = 2; i <= nparams; ++i) + { + if (!ttisnumber(args + (i - 2))) + return -1; + + int ch = int(nvalue(args + (i - 2))); + + if ((unsigned char)(ch) != ch) + return -1; + + buffer[i - 1] = ch; + } + + buffer[nparams] = 0; + + setsvalue(L, res, luaS_newlstr(L, buffer, nparams)); + return 1; + } + + return -1; +} + +static int luauF_len(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisstring(arg0)) + { + TString* ts = tsvalue(arg0); + + setnvalue(res, int(ts->len)); + return 1; + } + + return -1; +} + +static int luauF_typeof(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1) + { + const TString* ttname = luaT_objtypenamestr(L, arg0); + + setsvalue(L, res, ttname); + return 1; + } + + return -1; +} + +static int luauF_sub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisstring(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + TString* ts = tsvalue(arg0); + int i = int(nvalue(args)); + int j = int(nvalue(args + 1)); + + if (luaC_needsGC(L)) + return -1; // we can't call luaC_checkGC so fall back to C implementation + + if (i >= 1 && j >= i && unsigned(j - 1) < unsigned(ts->len)) + { + setsvalue(L, res, luaS_newlstr(L, getstr(ts) + (i - 1), j - i + 1)); + return 1; + } + } + + return -1; +} + +static int luauF_clamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + double v = nvalue(arg0); + double min = nvalue(args); + double max = nvalue(args + 1); + + if (min <= max) + { + double r = v < min ? min : v; + r = r > max ? max : r; + + setnvalue(res, r); + return 1; + } + } + + return -1; +} + +static int luauF_sign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double v = nvalue(arg0); + setnvalue(res, v > 0.0 ? 1.0 : v < 0.0 ? -1.0 : 0.0); + return 1; + } + + return -1; +} + +LUAU_FASTMATH_BEGIN +static int luauF_round(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double v = nvalue(arg0); + setnvalue(res, round(v)); + return 1; + } + + return -1; +} +LUAU_FASTMATH_END + +static int luauF_rawequal(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1) + { + setbvalue(res, luaO_rawequalObj(arg0, args)); + return 1; + } + + return -1; +} + +static int luauF_rawget(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttistable(arg0)) + { + setobj2s(L, res, luaH_get(hvalue(arg0), args)); + return 1; + } + + return -1; +} + +static int luauF_rawset(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttistable(arg0)) + { + const TValue* key = args; + if (ttisnil(key)) + return -1; + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + return -1; + else if (ttisvector(key) && luai_vecisnan(vvalue(key))) + return -1; + + LuaTable* t = hvalue(arg0); + if (t->readonly) + return -1; + + setobj2s(L, res, arg0); + setobj2t(L, luaH_set(L, t, args), args + 1); + luaC_barriert(L, t, args + 1); + return 1; + } + + return -1; +} + +static int luauF_tinsert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams == 2 && nresults <= 0 && ttistable(arg0)) + { + LuaTable* t = hvalue(arg0); + if (t->readonly) + return -1; + + int pos = luaH_getn(t) + 1; + setobj2t(L, luaH_setnum(L, t, pos), args); + luaC_barriert(L, t, args); + return 0; + } + + return -1; +} + +static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults < 0 && ttistable(arg0)) + { + LuaTable* t = hvalue(arg0); + int n = -1; + + if (nparams == 1) + n = luaH_getn(t); + else if (nparams == 3 && ttisnumber(args) && ttisnumber(args + 1) && nvalue(args) == 1.0) + n = int(nvalue(args + 1)); + + if (n >= 0 && n <= t->sizearray && cast_int(L->stack_last - res) >= n && n + nparams <= LUAI_MAXCSTACK) + { + TValue* array = t->array; + for (int i = 0; i < n; ++i) + setobj2s(L, res + i, array + i); + expandstacklimit(L, res + n); + return n; + } + } + + return -1; +} + +static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args)) + { + float x = (float)nvalue(arg0); + float y = (float)nvalue(args); + float z = 0.0f; + + if (nparams >= 3) + { + if (!ttisnumber(args + 1)) + return -1; + z = (float)nvalue(args + 1); + } + +#if LUA_VECTOR_SIZE == 4 + float w = 0.0f; + if (nparams >= 4) + { + if (!ttisnumber(args + 2)) + return -1; + w = (float)nvalue(args + 2); + } + setvvalue(res, x, y, z, w); +#else + setvvalue(res, x, y, z, 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_countlz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + + unsigned n; + luai_num2unsigned(n, a1); + +#ifdef _MSC_VER + unsigned long rl; + int r = _BitScanReverse(&rl, n) ? 31 - int(rl) : 32; +#else + int r = n == 0 ? 32 : __builtin_clz(n); +#endif + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_countrz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + + unsigned n; + luai_num2unsigned(n, a1); + +#ifdef _MSC_VER + unsigned long rl; + int r = _BitScanForward(&rl, n) ? int(rl) : 32; +#else + int r = n == 0 ? 32 : __builtin_ctz(n); +#endif + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_select(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams == 1 && nresults == 1) + { + int n = cast_int(L->base - L->ci->func) - clvalue(L->ci->func)->l.p->numparams - 1; + + if (ttisnumber(arg0)) + { + int i = int(nvalue(arg0)); + + // i >= 1 && i <= n + if (unsigned(i - 1) < unsigned(n)) + { + setobj2s(L, res, L->base - n + (i - 1)); + return 1; + } + // note: for now we don't handle negative case (wrap around) and defer to fallback + } + else if (ttisstring(arg0) && *svalue(arg0) == '#') + { + setnvalue(res, double(n)); + return 1; + } + } + + return -1; +} + +static int luauF_rawlen(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1) + { + if (ttistable(arg0)) + { + LuaTable* h = hvalue(arg0); + setnvalue(res, double(luaH_getn(h))); + return 1; + } + else if (ttisstring(arg0)) + { + TString* ts = tsvalue(arg0); + setnvalue(res, double(ts->len)); + return 1; + } + } + + return -1; +} + +static int luauF_extractk(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + // args is known to contain a number constant with packed in-range f/w + if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + double a2 = nvalue(args); + + unsigned n; + luai_num2unsigned(n, a1); + int fw = int(a2); + + int f = fw & 31; + int w1 = fw >> 5; + + uint32_t m = ~(0xfffffffeu << w1); + uint32_t r = (n >> f) & m; + + setnvalue(res, double(r)); + return 1; + } + + return -1; +} + +static int luauF_getmetatable(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1) + { + LuaTable* mt = NULL; + if (ttistable(arg0)) + mt = hvalue(arg0)->metatable; + else if (ttisuserdata(arg0)) + mt = uvalue(arg0)->metatable; + else + mt = L->global->mt[ttype(arg0)]; + + const TValue* mtv = mt ? luaH_getstr(mt, L->global->tmname[TM_METATABLE]) : luaO_nilobject; + if (!ttisnil(mtv)) + { + setobj2s(L, res, mtv); + return 1; + } + + if (mt) + { + sethvalue(L, res, mt); + return 1; + } + else + { + setnilvalue(res); + return 1; + } + } + + return -1; +} + +static int luauF_setmetatable(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + // note: setmetatable(_, nil) is rare so we use fallback for it to optimize the fast path + if (nparams >= 2 && nresults <= 1 && ttistable(arg0) && ttistable(args)) + { + LuaTable* t = hvalue(arg0); + if (t->readonly || t->metatable != NULL) + return -1; // note: overwriting non-null metatable is very rare but it requires __metatable check + + LuaTable* mt = hvalue(args); + t->metatable = mt; + luaC_objbarrier(L, t, mt); + + sethvalue(L, res, t); + return 1; + } + + return -1; +} + +static int luauF_tonumber(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams == 1 && nresults <= 1) + { + double num; + + if (ttisnumber(arg0)) + { + setnvalue(res, nvalue(arg0)); + return 1; + } + else if (ttisstring(arg0) && luaO_str2d(svalue(arg0), &num)) + { + setnvalue(res, num); + return 1; + } + else + { + setnilvalue(res); + return 1; + } + } + + return -1; +} + +static int luauF_tostring(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1) + { + switch (ttype(arg0)) + { + case LUA_TNIL: + { + TString* s = L->global->ttname[LUA_TNIL]; + setsvalue(L, res, s); + return 1; + } + case LUA_TBOOLEAN: + { + TString* s = bvalue(arg0) ? luaS_newliteral(L, "true") : luaS_newliteral(L, "false"); + setsvalue(L, res, s); + return 1; + } + case LUA_TNUMBER: + { + if (luaC_needsGC(L)) + return -1; // we can't call luaC_checkGC so fall back to C implementation + + char s[LUAI_MAXNUM2STR]; + char* e = luai_num2str(s, nvalue(arg0)); + setsvalue(L, res, luaS_newlstr(L, s, e - s)); + return 1; + } + case LUA_TSTRING: + { + setsvalue(L, res, tsvalue(arg0)); + return 1; + } + } + + // fall back to generic C implementation + } + + return -1; +} + +static int luauF_byteswap(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + unsigned n; + luai_num2unsigned(n, a1); + + n = (n << 24) | ((n << 8) & 0xff0000) | ((n >> 8) & 0xff00) | (n >> 24); + + setnvalue(res, double(n)); + return 1; + } + + return -1; +} + +// because offset is limited to an integer, a single 64bit comparison can be used and will not overflow +#define checkoutofbounds(offset, len, accessize) (uint64_t(unsigned(offset)) + (accessize - 1) >= uint64_t(len)) + +template +static int luauF_readinteger(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ +#if !defined(LUAU_BIG_ENDIAN) + if (nparams >= 2 && nresults <= 1 && ttisbuffer(arg0) && ttisnumber(args)) + { + int offset; + luai_num2int(offset, nvalue(args)); + if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T))) + return -1; + + T val; + memcpy(&val, (char*)bufvalue(arg0)->data + unsigned(offset), sizeof(T)); + setnvalue(res, double(val)); + return 1; + } +#endif + + return -1; +} + +template +static int luauF_writeinteger(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ +#if !defined(LUAU_BIG_ENDIAN) + if (nparams >= 3 && nresults <= 0 && ttisbuffer(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + int offset; + luai_num2int(offset, nvalue(args)); + if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T))) + return -1; + + unsigned value; + double incoming = nvalue(args + 1); + luai_num2unsigned(value, incoming); + + T val = T(value); + memcpy((char*)bufvalue(arg0)->data + unsigned(offset), &val, sizeof(T)); + return 0; + } +#endif + + return -1; +} + +template +static int luauF_readfp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ +#if !defined(LUAU_BIG_ENDIAN) + if (nparams >= 2 && nresults <= 1 && ttisbuffer(arg0) && ttisnumber(args)) + { + int offset; + luai_num2int(offset, nvalue(args)); + if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T))) + return -1; + + T val; +#ifdef _MSC_VER + // avoid memcpy path on MSVC because it results in integer stack copy + floating-point ops on stack + val = *(T*)((char*)bufvalue(arg0)->data + unsigned(offset)); +#else + memcpy(&val, (char*)bufvalue(arg0)->data + unsigned(offset), sizeof(T)); +#endif + setnvalue(res, double(val)); + return 1; + } +#endif + + return -1; +} + +template +static int luauF_writefp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ +#if !defined(LUAU_BIG_ENDIAN) + if (nparams >= 3 && nresults <= 0 && ttisbuffer(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + int offset; + luai_num2int(offset, nvalue(args)); + if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T))) + return -1; + + T val = T(nvalue(args + 1)); +#ifdef _MSC_VER + // avoid memcpy path on MSVC because it results in integer stack copy + floating-point ops on stack + *(T*)((char*)bufvalue(arg0)->data + unsigned(offset)) = val; +#else + memcpy((char*)bufvalue(arg0)->data + unsigned(offset), &val, sizeof(T)); +#endif + return 0; + } +#endif + + return -1; +} + +static int luauF_vectormagnitude(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + +#if LUA_VECTOR_SIZE == 4 + setnvalue(res, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3])); +#else + setnvalue(res, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectornormalize(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + +#if LUA_VECTOR_SIZE == 4 + float invSqrt = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + + setvvalue(res, v[0] * invSqrt, v[1] * invSqrt, v[2] * invSqrt, v[3] * invSqrt); +#else + float invSqrt = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + + setvvalue(res, v[0] * invSqrt, v[1] * invSqrt, v[2] * invSqrt, 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectorcross(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + + // same for 3- and 4- wide vectors + setvvalue(res, a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], 0.0f); + return 1; + } + + return -1; +} + +static int luauF_vectordot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + +#if LUA_VECTOR_SIZE == 4 + setnvalue(res, a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]); +#else + setnvalue(res, a[0] * b[0] + a[1] * b[1] + a[2] * b[2]); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectorfloor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + +#if LUA_VECTOR_SIZE == 4 + setvvalue(res, floorf(v[0]), floorf(v[1]), floorf(v[2]), floorf(v[3])); +#else + setvvalue(res, floorf(v[0]), floorf(v[1]), floorf(v[2]), 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectorceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + +#if LUA_VECTOR_SIZE == 4 + setvvalue(res, ceilf(v[0]), ceilf(v[1]), ceilf(v[2]), ceilf(v[3])); +#else + setvvalue(res, ceilf(v[0]), ceilf(v[1]), ceilf(v[2]), 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectorabs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + +#if LUA_VECTOR_SIZE == 4 + setvvalue(res, fabsf(v[0]), fabsf(v[1]), fabsf(v[2]), fabsf(v[3])); +#else + setvvalue(res, fabsf(v[0]), fabsf(v[1]), fabsf(v[2]), 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectorsign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + +#if LUA_VECTOR_SIZE == 4 + setvvalue(res, luaui_signf(v[0]), luaui_signf(v[1]), luaui_signf(v[2]), luaui_signf(v[3])); +#else + setvvalue(res, luaui_signf(v[0]), luaui_signf(v[1]), luaui_signf(v[2]), 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_vectorclamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisvector(args + 1)) + { + const float* v = vvalue(arg0); + const float* min = vvalue(args); + const float* max = vvalue(args + 1); + + if (min[0] <= max[0] && min[1] <= max[1] && min[2] <= max[2]) + { +#if LUA_VECTOR_SIZE == 4 + setvvalue( + res, + luaui_clampf(v[0], min[0], max[0]), + luaui_clampf(v[1], min[1], max[1]), + luaui_clampf(v[2], min[2], max[2]), + luaui_clampf(v[3], min[3], max[3]) + ); +#else + setvvalue(res, luaui_clampf(v[0], min[0], max[0]), luaui_clampf(v[1], min[1], max[1]), luaui_clampf(v[2], min[2], max[2]), 0.0f); +#endif + + return 1; + } + } + + return -1; +} + +static int luauF_vectormin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + + float result[4]; + + result[0] = (b[0] < a[0]) ? b[0] : a[0]; + result[1] = (b[1] < a[1]) ? b[1] : a[1]; + result[2] = (b[2] < a[2]) ? b[2] : a[2]; + +#if LUA_VECTOR_SIZE == 4 + result[3] = (b[3] < a[3]) ? b[3] : a[3]; +#else + result[3] = 0.0f; +#endif + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisvector(args + (i - 2))) + return -1; + + const float* c = vvalue(args + (i - 2)); + + result[0] = (c[0] < result[0]) ? c[0] : result[0]; + result[1] = (c[1] < result[1]) ? c[1] : result[1]; + result[2] = (c[2] < result[2]) ? c[2] : result[2]; +#if LUA_VECTOR_SIZE == 4 + result[3] = (c[3] < result[3]) ? c[3] : result[3]; +#endif + } + + setvvalue(res, result[0], result[1], result[2], result[3]); + return 1; + } + + return -1; +} + +static int luauF_vectormax(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + + float result[4]; + + result[0] = (b[0] > a[0]) ? b[0] : a[0]; + result[1] = (b[1] > a[1]) ? b[1] : a[1]; + result[2] = (b[2] > a[2]) ? b[2] : a[2]; + +#if LUA_VECTOR_SIZE == 4 + result[3] = (b[3] > a[3]) ? b[3] : a[3]; +#else + result[3] = 0.0f; +#endif + + for (int i = 3; i <= nparams; ++i) + { + if (!ttisvector(args + (i - 2))) + return -1; + + const float* c = vvalue(args + (i - 2)); + + result[0] = (c[0] > result[0]) ? c[0] : result[0]; + result[1] = (c[1] > result[1]) ? c[1] : result[1]; + result[2] = (c[2] > result[2]) ? c[2] : result[2]; +#if LUA_VECTOR_SIZE == 4 + result[3] = (c[3] > result[3]) ? c[3] : result[3]; +#endif + } + + setvvalue(res, result[0], result[1], result[2], result[3]); + return 1; + } + + return -1; +} + +static int luauF_vectorlerp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisnumber(args + 1)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + const float t = static_cast(nvalue(args + 1)); + +#if LUA_VECTOR_SIZE == 4 + setvvalue(res, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), luai_lerpf(a[2], b[2], t), luai_lerpf(a[3], b[3], t)); +#else + setvvalue(res, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), luai_lerpf(a[2], b[2], t), 0.0f); +#endif + + return 1; + } + + return -1; +} + +static int luauF_lerp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1)) + { + double a = nvalue(arg0); + double b = nvalue(args); + double t = nvalue(args + 1); + + double r = (t == 1.0) ? b : a + (b - a) * t; + + setnvalue(res, r); + return 1; + } + + return -1; +} + +static int luauF_isnan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double x = nvalue(arg0); + + setbvalue(res, isnan(x)); + return 1; + } + + return -1; +} + +static int luauF_isinf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double x = nvalue(arg0); + + setbvalue(res, isinf(x)); + return 1; + } + + return -1; +} + +static int luauF_isfinite(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double x = nvalue(arg0); + + setbvalue(res, isfinite(x)); + return 1; + } + + return -1; +} + +// Rive 2D-optimized fast functions (skip z component since Rive vectors are 2D with z=0) + +static int luauF_vectordistance(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + float dx = a[0] - b[0]; + float dy = a[1] - b[1]; + setnvalue(res, sqrtf(dx * dx + dy * dy)); + return 1; + } + + return -1; +} + +static int luauF_vectordistancesquared(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + float dx = a[0] - b[0]; + float dy = a[1] - b[1]; + setnvalue(res, dx * dx + dy * dy); + return 1; + } + + return -1; +} + +static int luauF_vectororigin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nresults <= 1) + { + setvvalue(res, 0.0f, 0.0f, 0.0f, 0.0f); + return 1; + } + + return -1; +} + +static int luauF_vectorlengthsquared(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + setnvalue(res, v[0] * v[0] + v[1] * v[1]); + return 1; + } + + return -1; +} + +static int luauF_vector2dot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + setnvalue(res, a[0] * b[0] + a[1] * b[1]); + return 1; + } + + return -1; +} + +static int luauF_vector2magnitude(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + setnvalue(res, sqrtf(v[0] * v[0] + v[1] * v[1])); + return 1; + } + + return -1; +} + +static int luauF_vector2normalize(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisvector(arg0)) + { + const float* v = vvalue(arg0); + float lenSq = v[0] * v[0] + v[1] * v[1]; + float invLen = 1.0f / sqrtf(lenSq); + setvvalue(res, v[0] * invLen, v[1] * invLen, 0.0f, 0.0f); + return 1; + } + + return -1; +} + +static int luauF_vector2lerp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisnumber(args + 1)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + const float t = static_cast(nvalue(args + 1)); + setvvalue(res, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), 0.0f, 0.0f); + return 1; + } + + return -1; +} + +static int luauF_vector2cross(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + setnvalue(res, a[0] * b[1] - a[1] * b[0]); + return 1; + } + + return -1; +} + +static int luauF_vector2scaleandadd(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisnumber(args + 1)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + const float s = static_cast(nvalue(args + 1)); + setvvalue(res, a[0] + b[0] * s, a[1] + b[1] * s, 0.0f, 0.0f); + return 1; + } + + return -1; +} + +static int luauF_vector2scaleandsub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisnumber(args + 1)) + { + const float* a = vvalue(arg0); + const float* b = vvalue(args); + const float s = static_cast(nvalue(args + 1)); + setvvalue(res, a[0] - b[0] * s, a[1] - b[1] * s, 0.0f, 0.0f); + return 1; + } + + return -1; +} + +static int luauF_missing(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + return -1; +} + +#ifdef LUAU_TARGET_SSE41 +template +LUAU_TARGET_SSE41 inline double roundsd_sse41(double v) +{ + __m128d av = _mm_set_sd(v); + __m128d rv = _mm_round_sd(av, av, Rounding | _MM_FROUND_NO_EXC); + return _mm_cvtsd_f64(rv); +} + +LUAU_TARGET_SSE41 static int luauF_floor_sse41(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, roundsd_sse41<_MM_FROUND_TO_NEG_INF>(a1)); + return 1; + } + + return -1; +} + +LUAU_TARGET_SSE41 static int luauF_ceil_sse41(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + setnvalue(res, roundsd_sse41<_MM_FROUND_TO_POS_INF>(a1)); + return 1; + } + + return -1; +} + +LUAU_TARGET_SSE41 static int luauF_round_sse41(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams) +{ + if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0)) + { + double a1 = nvalue(arg0); + // roundsd only supports bankers rounding natively, so we need to emulate rounding by using truncation + // offset is prevfloat(0.5), which is important so that we round prevfloat(0.5) to 0. + const double offset = 0.49999999999999994; + setnvalue(res, roundsd_sse41<_MM_FROUND_TO_ZERO>(a1 + (a1 < 0 ? -offset : offset))); + return 1; + } + + return -1; +} + +static bool luau_hassse41() +{ + int cpuinfo[4] = {}; +#ifdef _MSC_VER + __cpuid(cpuinfo, 1); +#else + __cpuid(1, cpuinfo[0], cpuinfo[1], cpuinfo[2], cpuinfo[3]); +#endif + + // We require SSE4.1 support for ROUNDSD + // https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits + return (cpuinfo[2] & (1 << 19)) != 0; +} +#endif + +const luau_FastFunction luauF_table[256] = { + NULL, + luauF_assert, + + luauF_abs, + luauF_acos, + luauF_asin, + luauF_atan2, + luauF_atan, + +#ifdef LUAU_TARGET_SSE41 + luau_hassse41() ? luauF_ceil_sse41 : luauF_ceil, +#else + luauF_ceil, +#endif + + luauF_cosh, + luauF_cos, + luauF_deg, + luauF_exp, + +#ifdef LUAU_TARGET_SSE41 + luau_hassse41() ? luauF_floor_sse41 : luauF_floor, +#else + luauF_floor, +#endif + + luauF_fmod, + luauF_frexp, + luauF_ldexp, + luauF_log10, + luauF_log, + luauF_max, + luauF_min, + luauF_modf, + luauF_pow, + luauF_rad, + luauF_sinh, + luauF_sin, + luauF_sqrt, + luauF_tanh, + luauF_tan, + + luauF_arshift, + luauF_band, + luauF_bnot, + luauF_bor, + luauF_bxor, + luauF_btest, + luauF_extract, + luauF_lrotate, + luauF_lshift, + luauF_replace, + luauF_rrotate, + luauF_rshift, + + luauF_type, + + luauF_byte, + luauF_char, + luauF_len, + + luauF_typeof, + + luauF_sub, + + luauF_clamp, + luauF_sign, + +#ifdef LUAU_TARGET_SSE41 + luau_hassse41() ? luauF_round_sse41 : luauF_round, +#else + luauF_round, +#endif + + luauF_rawset, + luauF_rawget, + luauF_rawequal, + + luauF_tinsert, + luauF_tunpack, + + luauF_vector, + + luauF_countlz, + luauF_countrz, + + luauF_select, + + luauF_rawlen, + + luauF_extractk, + + luauF_getmetatable, + luauF_setmetatable, + + luauF_tonumber, + luauF_tostring, + + luauF_byteswap, + + luauF_readinteger, + luauF_readinteger, + luauF_writeinteger, + luauF_readinteger, + luauF_readinteger, + luauF_writeinteger, + luauF_readinteger, + luauF_readinteger, + luauF_writeinteger, + luauF_readfp, + luauF_writefp, + luauF_readfp, + luauF_writefp, + + luauF_vectormagnitude, + luauF_vectornormalize, + luauF_vectorcross, + luauF_vectordot, + luauF_vectorfloor, + luauF_vectorceil, + luauF_vectorabs, + luauF_vectorsign, + luauF_vectorclamp, + luauF_vectormin, + luauF_vectormax, + + luauF_lerp, + + luauF_vectorlerp, + + luauF_isnan, + luauF_isinf, + luauF_isfinite, + +// When adding builtins, add them above this line; what follows is padding to fill the 256-slot table. +// Rive fast functions are pinned at the end of the table (grow downward from 255). +#define MISSING8 luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing + + // Padding: indices 94-244 (151 entries = 18 MISSING8 + 7 individual) + luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, + MISSING8, MISSING8, MISSING8, MISSING8, + MISSING8, MISSING8, MISSING8, MISSING8, + MISSING8, MISSING8, MISSING8, MISSING8, + MISSING8, MISSING8, MISSING8, MISSING8, + MISSING8, MISSING8, + + // Rive Vector 2D fast functions: indices 245-255 + luauF_vectordistance, + luauF_vectordistancesquared, + luauF_vectororigin, + luauF_vectorlengthsquared, + luauF_vector2dot, + luauF_vector2magnitude, + luauF_vector2normalize, + luauF_vector2lerp, + luauF_vector2cross, + luauF_vector2scaleandadd, + luauF_vector2scaleandsub, + +#undef MISSING8 +}; + +static_assert(sizeof(luauF_table) / sizeof(luauF_table[0]) == 256, "luauF_table must have 256 entries"); diff --git a/thirdparty/luau/upstream/VM/src/lbuiltins.h b/thirdparty/luau/upstream/VM/src/lbuiltins.h new file mode 100644 index 000000000..44702c94d --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbuiltins.h @@ -0,0 +1,9 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" + +typedef int (*luau_FastFunction)(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams); + +extern const luau_FastFunction luauF_table[256]; diff --git a/thirdparty/luau/upstream/VM/src/lbytecode.h b/thirdparty/luau/upstream/VM/src/lbytecode.h new file mode 100644 index 000000000..da2a611c0 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lbytecode.h @@ -0,0 +1,6 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +// This is a forwarding header for Luau bytecode definition +#include "Luau/Bytecode.h" diff --git a/thirdparty/luau/upstream/VM/src/lcommon.h b/thirdparty/luau/upstream/VM/src/lcommon.h new file mode 100644 index 000000000..ed047a18b --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lcommon.h @@ -0,0 +1,46 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include +#include + +#include "luaconf.h" + +#include "Luau/Common.h" + +// internal assertions for in-house debugging +#define check_exp(c, e) (LUAU_ASSERT(c), (e)) +#define api_check(l, e) LUAU_ASSERT(e) + +#ifndef cast_to +#define cast_to(t, exp) ((t)(exp)) +#endif + +#define cast_byte(i) cast_to(uint8_t, (i)) +#define cast_num(i) cast_to(double, (i)) +#define cast_int(i) cast_to(int, (i)) + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef uint32_t Instruction; + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if defined(HARDSTACKTESTS) && HARDSTACKTESTS +#define condhardstacktests(x) (x) +#else +#define condhardstacktests(x) ((void)0) +#endif + +/* +** macro to control inclusion of some hard tests on garbage collection +*/ +#if defined(HARDMEMTESTS) && HARDMEMTESTS +#define condhardmemtests(x, l) (HARDMEMTESTS >= l ? (x) : (void)0) +#else +#define condhardmemtests(x, l) ((void)0) +#endif diff --git a/thirdparty/luau/upstream/VM/src/lcorolib.cpp b/thirdparty/luau/upstream/VM/src/lcorolib.cpp new file mode 100644 index 000000000..ddd9b7315 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lcorolib.cpp @@ -0,0 +1,269 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "ldebug.h" +#include "lstate.h" +#include "lvm.h" + +#define CO_STATUS_ERROR -1 +#define CO_STATUS_BREAK -2 + +static const char* const statnames[] = {"running", "suspended", "normal", "dead", "dead"}; // dead appears twice for LUA_COERR and LUA_COFIN + +static int costatus(lua_State* L) +{ + lua_State* co = lua_tothread(L, 1); + luaL_argexpected(L, co, 1, "thread"); + lua_pushstring(L, statnames[lua_costatus(L, co)]); + return 1; +} + +static int auxresume(lua_State* L, lua_State* co, int narg) +{ + // error handling for edge cases + if (co->status != LUA_YIELD) + { + int status = lua_costatus(L, co); + if (status != LUA_COSUS) + { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return CO_STATUS_ERROR; + } + } + + if (narg) + { + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + lua_xmove(L, co, narg); + } + else + { + // coroutine might be completely full already + if ((co->top - co->base) > LUAI_MAXCSTACK) + luaL_error(L, "too many arguments to resume"); + } + + co->singlestep = L->singlestep; + + int status = lua_resume(co, L, narg); + if (status == 0 || status == LUA_YIELD) + { + int nres = cast_int(co->top - co->base); + if (nres) + { + // +1 accounts for true/false status in resumefinish + if (nres + 1 > LUA_MINSTACK && !lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); // move yielded values + } + return nres; + } + else if (status == LUA_BREAK) + { + return CO_STATUS_BREAK; + } + else + { + lua_xmove(co, L, 1); // move error message + return CO_STATUS_ERROR; + } +} + +static int interruptThread(lua_State* L, lua_State* co) +{ + // notify the debugger that the thread was suspended + if (L->global->cb.debuginterrupt) + luau_callhook(L, L->global->cb.debuginterrupt, co); + + return lua_break(L); +} + +static int auxresumecont(lua_State* L, lua_State* co) +{ + if (co->status == 0 || co->status == LUA_YIELD) + { + int nres = cast_int(co->top - co->base); + if (!lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); // move yielded values + return nres; + } + else + { + lua_rawcheckstack(L, 2); + lua_xmove(co, L, 1); // move error message + return CO_STATUS_ERROR; + } +} + +static int coresumefinish(lua_State* L, int r) +{ + if (r < 0) + { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; // return false + error message + } + else + { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; // return true + `resume' returns + } +} + +static int coresumey(lua_State* L) +{ + lua_State* co = lua_tothread(L, 1); + luaL_argexpected(L, co, 1, "thread"); + int narg = cast_int(L->top - L->base) - 1; + int r = auxresume(L, co, narg); + + if (r == CO_STATUS_BREAK) + return interruptThread(L, co); + + return coresumefinish(L, r); +} + +static int coresumecont(lua_State* L, int status) +{ + lua_State* co = lua_tothread(L, 1); + luaL_argexpected(L, co, 1, "thread"); + + // if coroutine still hasn't yielded after the break, break current thread again + if (co->status == LUA_BREAK) + return interruptThread(L, co); + + int r = auxresumecont(L, co); + + return coresumefinish(L, r); +} + +static int auxwrapfinish(lua_State* L, int r) +{ + if (r < 0) + { + if (lua_isstring(L, -1)) + { // error object is a string? + luaL_where(L, 1); // add extra info + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); // propagate error + } + return r; +} + +static int auxwrapy(lua_State* L) +{ + lua_State* co = lua_tothread(L, lua_upvalueindex(1)); + int narg = cast_int(L->top - L->base); + int r = auxresume(L, co, narg); + + if (r == CO_STATUS_BREAK) + return interruptThread(L, co); + + return auxwrapfinish(L, r); +} + +static int auxwrapcont(lua_State* L, int status) +{ + lua_State* co = lua_tothread(L, lua_upvalueindex(1)); + + // if coroutine still hasn't yielded after the break, break current thread again + if (co->status == LUA_BREAK) + return interruptThread(L, co); + + int r = auxresumecont(L, co); + + return auxwrapfinish(L, r); +} + +static int cocreate(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_State* NL = lua_newthread(L); + lua_xpush(L, NL, 1); // push function on top of NL + return 1; +} + +static int cowrap(lua_State* L) +{ + cocreate(L); + + lua_pushcclosurek(L, auxwrapy, NULL, 1, auxwrapcont); + return 1; +} + +static int coyield(lua_State* L) +{ + int nres = cast_int(L->top - L->base); + return lua_yield(L, nres); +} + +static int corunning(lua_State* L) +{ + if (lua_pushthread(L)) + lua_pushnil(L); // main thread is not a coroutine + return 1; +} + +static int coyieldable(lua_State* L) +{ + lua_pushboolean(L, lua_isyieldable(L)); + return 1; +} + +static int coclose(lua_State* L) +{ + lua_State* co = lua_tothread(L, 1); + luaL_argexpected(L, co, 1, "thread"); + + int status = lua_costatus(L, co); + if (status != LUA_COFIN && status != LUA_COERR && status != LUA_COSUS) + luaL_error(L, "cannot close %s coroutine", statnames[status]); + + if (co->status == LUA_OK || co->status == LUA_YIELD) + { + lua_pushboolean(L, true); + lua_resetthread(co); + return 1; + } + else + { + lua_pushboolean(L, false); + + if (co->status == LUA_ERRMEM) + lua_pushstring(L, LUA_MEMERRMSG); + else if (co->status == LUA_ERRERR) + lua_pushstring(L, LUA_ERRERRMSG); + else if (lua_gettop(co)) + lua_xmove(co, L, 1); // move error message + + lua_resetthread(co); + return 2; + } +} + +static const luaL_Reg co_funcs[] = { + {"create", cocreate}, + {"running", corunning}, + {"status", costatus}, + {"wrap", cowrap}, + {"yield", coyield}, + {"isyieldable", coyieldable}, + {"close", coclose}, + {NULL, NULL}, +}; + +int luaopen_coroutine(lua_State* L) +{ + luaL_register(L, LUA_COLIBNAME, co_funcs); + + lua_pushcclosurek(L, coresumey, "resume", 0, coresumecont); + lua_setfield(L, -2, "resume"); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/ldblib.cpp b/thirdparty/luau/upstream/VM/src/ldblib.cpp new file mode 100644 index 000000000..a2166d2ea --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ldblib.cpp @@ -0,0 +1,192 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lvm.h" + +#include +#include +#include + +LUAU_FASTFLAGVARIABLE(UseNewTraceback) + +static lua_State* getthread(lua_State* L, int* arg) +{ + if (lua_isthread(L, 1)) + { + *arg = 1; + return lua_tothread(L, 1); + } + else + { + *arg = 0; + return L; + } +} + +static int db_info(lua_State* L) +{ + int arg; + lua_State* L1 = getthread(L, &arg); + int l1top = 0; + + // if L1 != L, L1 can be in any state, and therefore there are no guarantees about its stack space + if (L != L1) + { + // for 'f' option, we reserve one slot and we also record the stack top + lua_rawcheckstack(L1, 1); + + l1top = lua_gettop(L1); + } + + int level; + if (lua_isnumber(L, arg + 1)) + { + level = (int)lua_tointeger(L, arg + 1); + luaL_argcheck(L, level >= 0, arg + 1, "level can't be negative"); + } + else if (arg == 0 && lua_isfunction(L, 1)) + { + // convert absolute index to relative index + level = -lua_gettop(L); + } + else + luaL_argerror(L, arg + 1, "function or level expected"); + + const char* options = luaL_checkstring(L, arg + 2); + + lua_Debug ar; + if (!lua_getinfo(L1, level, options, &ar)) + return 0; + + int results = 0; + bool occurs[26] = {}; + + for (const char* it = options; *it; ++it) + { + if (unsigned(*it - 'a') < 26) + { + if (occurs[*it - 'a']) + { + // restore stack state of another thread as 'f' option might not have been visited yet + if (L != L1) + lua_settop(L1, l1top); + + luaL_argerror(L, arg + 2, "duplicate option"); + } + occurs[*it - 'a'] = true; + } + + switch (*it) + { + case 's': + lua_pushstring(L, ar.short_src); + results++; + break; + + case 'l': + lua_pushinteger(L, ar.currentline); + results++; + break; + + case 'n': + lua_pushstring(L, ar.name ? ar.name : ""); + results++; + break; + + case 'f': + if (L1 == L) + lua_pushvalue(L, -1 - results); // function is right before results + else + lua_xmove(L1, L, 1); // function is at top of L1 + results++; + break; + + case 'a': + lua_pushinteger(L, ar.nparams); + lua_pushboolean(L, ar.isvararg); + results += 2; + break; + + default: + // restore stack state of another thread as 'f' option might not have been visited yet + if (L != L1) + lua_settop(L1, l1top); + + luaL_argerror(L, arg + 2, "invalid option"); + } + } + + return results; +} + +static int db_traceback(lua_State* L) +{ + int arg; + lua_State* L1 = getthread(L, &arg); + const char* msg = luaL_optstring(L, arg + 1, NULL); + int level = luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); + luaL_argcheck(L, level >= 0, arg + 2, "level can't be negative"); + + if (FFlag::UseNewTraceback) + { + luaL_traceback(L, L1, msg, level); + } + else + { + luaL_Strbuf buf; + luaL_buffinit(L, &buf); + + if (msg) + { + luaL_addstring(&buf, msg); + luaL_addstring(&buf, "\n"); + } + + lua_Debug ar; + for (int i = level; lua_getinfo(L1, i, "sln", &ar); ++i) + { + if (strcmp(ar.what, "C") == 0) + continue; + + if (ar.source) + luaL_addstring(&buf, ar.short_src); + + if (ar.currentline > 0) + { + char line[32]; // manual conversion for performance + char* lineend = line + sizeof(line); + char* lineptr = lineend; + for (unsigned int r = ar.currentline; r > 0; r /= 10) + *--lineptr = '0' + (r % 10); + + luaL_addchar(&buf, ':'); + luaL_addlstring(&buf, lineptr, lineend - lineptr); + } + + if (ar.name) + { + luaL_addstring(&buf, " function "); + luaL_addstring(&buf, ar.name); + } + + luaL_addchar(&buf, '\n'); + } + + luaL_pushresult(&buf); + } + + return 1; +} + +static const luaL_Reg dblib[] = { + {"info", db_info}, + {"traceback", db_traceback}, + {NULL, NULL}, +}; + +int luaopen_debug(lua_State* L) +{ + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/ldebug.cpp b/thirdparty/luau/upstream/VM/src/ldebug.cpp new file mode 100644 index 000000000..e93209b57 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ldebug.cpp @@ -0,0 +1,675 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "ldebug.h" + +#include "lapi.h" +#include "lfunc.h" +#include "lmem.h" +#include "lgc.h" +#include "ldo.h" +#include "lbytecode.h" + +#include +#include + +static const char* getfuncname(Closure* f); + +static int currentpc(lua_State* L, CallInfo* ci) +{ + return pcRel(ci->savedpc, ci_func(ci)->l.p); +} + +static int currentline(lua_State* L, CallInfo* ci) +{ + return luaG_getline(ci_func(ci)->l.p, currentpc(L, ci)); +} + +static Proto* getluaproto(CallInfo* ci) +{ + return (isLua(ci) ? cast_to(Proto*, ci_func(ci)->l.p) : NULL); +} + +int lua_getargument(lua_State* L, int level, int n) +{ + if (unsigned(level) >= unsigned(L->ci - L->base_ci)) + return 0; + + CallInfo* ci = L->ci - level; + // changing tables in native functions externally may invalidate safety contracts wrt table state (metatable/size/readonly) + if (ci->flags & LUA_CALLINFO_NATIVE) + return 0; + + Proto* fp = getluaproto(ci); + int res = 0; + + if (fp && n > 0) + { + if (n <= fp->numparams) + { + luaC_threadbarrier(L); + luaA_pushobject(L, ci->base + (n - 1)); + res = 1; + } + else if (fp->is_vararg && n < ci->base - ci->func) + { + luaC_threadbarrier(L); + luaA_pushobject(L, ci->func + n); + res = 1; + } + } + + return res; +} + +const char* lua_getlocal(lua_State* L, int level, int n) +{ + if (unsigned(level) >= unsigned(L->ci - L->base_ci)) + return NULL; + + CallInfo* ci = L->ci - level; + // changing tables in native functions externally may invalidate safety contracts wrt table state (metatable/size/readonly) + if (ci->flags & LUA_CALLINFO_NATIVE) + return NULL; + + Proto* fp = getluaproto(ci); + const LocVar* var = fp ? luaF_getlocal(fp, n, currentpc(L, ci)) : NULL; + if (var) + { + luaC_threadbarrier(L); + luaA_pushobject(L, ci->base + var->reg); + } + const char* name = var ? getstr(var->varname) : NULL; + return name; +} + +const char* lua_setlocal(lua_State* L, int level, int n) +{ + if (unsigned(level) >= unsigned(L->ci - L->base_ci)) + return NULL; + + CallInfo* ci = L->ci - level; + // changing registers in native functions externally may invalidate safety contracts wrt register type tags + if (ci->flags & LUA_CALLINFO_NATIVE) + return NULL; + + Proto* fp = getluaproto(ci); + const LocVar* var = fp ? luaF_getlocal(fp, n, currentpc(L, ci)) : NULL; + if (var) + setobj2s(L, ci->base + var->reg, L->top - 1); + L->top--; // pop value + const char* name = var ? getstr(var->varname) : NULL; + return name; +} + +static Closure* auxgetinfo(lua_State* L, const char* what, lua_Debug* ar, Closure* f, CallInfo* ci) +{ + Closure* cl = NULL; + for (; *what; what++) + { + switch (*what) + { + case 's': + { + if (f->isC) + { + ar->source = "=[C]"; + ar->what = "C"; + ar->linedefined = -1; + ar->short_src = "[C]"; + } + else + { + TString* source = f->l.p->source; + ar->source = getstr(source); + ar->what = "Lua"; + ar->linedefined = f->l.p->linedefined; + ar->short_src = luaO_chunkid(ar->ssbuf, sizeof(ar->ssbuf), getstr(source), source->len); + } + break; + } + case 'l': + { + if (ci) + { + ar->currentline = isLua(ci) ? currentline(L, ci) : -1; + } + else + { + ar->currentline = f->isC ? -1 : f->l.p->linedefined; + } + + break; + } + case 'u': + { + ar->nupvals = f->nupvalues; + break; + } + case 'a': + { + if (f->isC) + { + ar->isvararg = 1; + ar->nparams = 0; + } + else + { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 'n': + { + ar->name = ci ? getfuncname(ci_func(ci)) : getfuncname(f); + break; + } + case 'f': + { + cl = f; + break; + } + default:; + } + } + return cl; +} + +int lua_stackdepth(lua_State* L) +{ + return int(L->ci - L->base_ci); +} + +int lua_getinfo(lua_State* L, int level, const char* what, lua_Debug* ar) +{ + Closure* f = NULL; + CallInfo* ci = NULL; + if (level < 0) + { + // element has to be within stack + if (-level > L->top - L->base) + return 0; + + StkId func = L->top + level; + + // and it has to be a function + if (!ttisfunction(func)) + return 0; + + f = clvalue(func); + } + else if (unsigned(level) < unsigned(L->ci - L->base_ci)) + { + ci = L->ci - level; + LUAU_ASSERT(ttisfunction(ci->func)); + f = clvalue(ci->func); + } + if (f) + { + // auxgetinfo fills ar and optionally requests to put closure on stack + if (Closure* fcl = auxgetinfo(L, what, ar, f, ci)) + { + luaC_threadbarrier(L); + setclvalue(L, L->top, fcl); + incr_top(L); + } + } + return f ? 1 : 0; +} + +static const char* getfuncname(Closure* cl) +{ + if (cl->isC) + { + if (cl->c.debugname) + { + return cl->c.debugname; + } + } + else + { + Proto* p = cl->l.p; + + if (p->debugname) + { + return getstr(p->debugname); + } + } + return nullptr; +} + +l_noret luaG_typeerrorL(lua_State* L, const TValue* o, const char* op) +{ + const char* t = luaT_objtypename(L, o); + + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + +l_noret luaG_forerrorL(lua_State* L, const TValue* o, const char* what) +{ + const char* t = luaT_objtypename(L, o); + + luaG_runerror(L, "invalid 'for' %s (number expected, got %s)", what, t); +} + +l_noret luaG_concaterror(lua_State* L, StkId p1, StkId p2) +{ + const char* t1 = luaT_objtypename(L, p1); + const char* t2 = luaT_objtypename(L, p2); + + luaG_runerror(L, "attempt to concatenate %s with %s", t1, t2); +} + +l_noret luaG_aritherror(lua_State* L, const TValue* p1, const TValue* p2, TMS op) +{ + const char* t1 = luaT_objtypename(L, p1); + const char* t2 = luaT_objtypename(L, p2); + const char* opname = luaT_eventname[op] + 2; // skip __ from metamethod name + + if (t1 == t2) + luaG_runerror(L, "attempt to perform arithmetic (%s) on %s", opname, t1); + else + luaG_runerror(L, "attempt to perform arithmetic (%s) on %s and %s", opname, t1, t2); +} + +l_noret luaG_ordererror(lua_State* L, const TValue* p1, const TValue* p2, TMS op) +{ + const char* t1 = luaT_objtypename(L, p1); + const char* t2 = luaT_objtypename(L, p2); + const char* opname = (op == TM_LT) ? "<" : (op == TM_LE) ? "<=" : "=="; + + luaG_runerror(L, "attempt to compare %s %s %s", t1, opname, t2); +} + +l_noret luaG_indexerror(lua_State* L, const TValue* p1, const TValue* p2) +{ + const char* t1 = luaT_objtypename(L, p1); + const char* t2 = luaT_objtypename(L, p2); + const TString* key = ttisstring(p2) ? tsvalue(p2) : 0; + + if (key && key->len <= 64) // limit length to make sure we don't generate very long error messages for very long keys + luaG_runerror(L, "attempt to index %s with '%s'", t1, getstr(key)); + else + luaG_runerror(L, "attempt to index %s with %s", t1, t2); +} + +l_noret luaG_methoderror(lua_State* L, const TValue* p1, const TString* p2) +{ + const char* t1 = luaT_objtypename(L, p1); + + luaG_runerror(L, "attempt to call missing method '%s' of %s", getstr(p2), t1); +} + +l_noret luaG_readonlyerror(lua_State* L) +{ + luaG_runerror(L, "attempt to modify a readonly table"); +} + +static void pusherror(lua_State* L, const char* msg) +{ + CallInfo* ci = L->ci; + if (isLua(ci)) + { + TString* source = getluaproto(ci)->source; + char chunkbuf[LUA_IDSIZE]; // add file:line information +#ifdef RIVE_LUAU + const char* chunkid = getstr(source); +#else + const char* chunkid = luaO_chunkid(chunkbuf, sizeof(chunkbuf), getstr(source), source->len); +#endif + int line = currentline(L, ci); + luaO_pushfstring(L, "%s:%d: %s", chunkid, line, msg); + } + else + { +#ifdef RIVE_LUAU + luaO_pushfstring(L, ":: %s", msg); +#else + lua_pushstring(L, msg); +#endif + } +} + +l_noret luaG_runerrorL(lua_State* L, const char* fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + char result[LUA_BUFFERSIZE]; + vsnprintf(result, sizeof(result), fmt, argp); + va_end(argp); + + lua_rawcheckstack(L, 1); + + pusherror(L, result); + luaD_throw(L, LUA_ERRRUN); +} + +void luaG_pusherror(lua_State* L, const char* error) +{ + lua_rawcheckstack(L, 1); + + pusherror(L, error); +} + +void luaG_breakpoint(lua_State* L, Proto* p, int line, bool enable) +{ + void (*ondisable)(lua_State*, Proto*) = L->global->ecb.disable; + + // since native code doesn't support breakpoints, we would need to update all call frames with LUAU_CALLINFO_NATIVE that refer to p + if (p->lineinfo && (ondisable || !p->execdata)) + { + for (int i = 0; i < p->sizecode; ++i) + { + // note: we keep prologue as is, instead opting to break at the first meaningful instruction + if (LUAU_INSN_OP(p->code[i]) == LOP_PREPVARARGS) + continue; + + if (luaG_getline(p, i) != line) + continue; + + // lazy copy of the original opcode array; done when the first breakpoint is set + if (!p->debuginsn) + { + p->debuginsn = luaM_newarray(L, p->sizecode, uint8_t, p->memcat); + for (int j = 0; j < p->sizecode; ++j) + p->debuginsn[j] = LUAU_INSN_OP(p->code[j]); + } + + uint8_t op = enable ? LOP_BREAK : LUAU_INSN_OP(p->debuginsn[i]); + + // patch just the opcode byte, leave arguments alone + p->code[i] &= ~0xff; + p->code[i] |= op; + LUAU_ASSERT(LUAU_INSN_OP(p->code[i]) == op); + + // currently we don't restore native code when breakpoint is disabled. + // this will be addressed in the future. + if (enable && p->execdata && ondisable) + ondisable(L, p); + + // note: this is important! + // we only patch the *first* instruction in each proto that's attributed to a given line + // this can be changed, but if requires making patching a bit more nuanced so that we don't patch AUX words + break; + } + } + + for (int i = 0; i < p->sizep; ++i) + { + luaG_breakpoint(L, p->p[i], line, enable); + } +} + +bool luaG_onbreak(lua_State* L) +{ + if (L->ci == L->base_ci) + return false; + + if (!isLua(L->ci)) + return false; + + return LUAU_INSN_OP(*L->ci->savedpc) == LOP_BREAK; +} + +int luaG_getline(Proto* p, int pc) +{ + LUAU_ASSERT(pc >= 0 && pc < p->sizecode); + + if (!p->lineinfo) + return 0; + + return p->abslineinfo[pc >> p->linegaplog2] + p->lineinfo[pc]; +} + +int luaG_isnative(lua_State* L, int level) +{ + if (unsigned(level) >= unsigned(L->ci - L->base_ci)) + return 0; + + CallInfo* ci = L->ci - level; + return (ci->flags & LUA_CALLINFO_NATIVE) != 0 ? 1 : 0; +} + +int luaG_hasnative(lua_State* L, int level) +{ + if (unsigned(level) >= unsigned(L->ci - L->base_ci)) + return 0; + + CallInfo* ci = L->ci - level; + + Proto* proto = getluaproto(ci); + if (proto == nullptr) + return 0; + + return (proto->execdata != nullptr); +} + +void lua_singlestep(lua_State* L, int enabled) +{ + L->singlestep = bool(enabled); +} + +static int getmaxline(Proto* p) +{ + int result = -1; + + for (int i = 0; i < p->sizecode; ++i) + { + int line = luaG_getline(p, i); + result = result < line ? line : result; + } + + for (int i = 0; i < p->sizep; ++i) + { + int psize = getmaxline(p->p[i]); + result = result < psize ? psize : result; + } + + return result; +} + +// Find the line number with instructions. If the provided line doesn't have any instruction, it should return the next valid line number. +static int getnextline(Proto* p, int line) +{ + int closest = -1; + + if (p->lineinfo) + { + for (int i = 0; i < p->sizecode; ++i) + { + // note: we keep prologue as is, instead opting to break at the first meaningful instruction + if (LUAU_INSN_OP(p->code[i]) == LOP_PREPVARARGS) + continue; + + int candidate = luaG_getline(p, i); + + if (candidate == line) + return line; + + if (candidate > line && (closest == -1 || candidate < closest)) + closest = candidate; + } + } + + for (int i = 0; i < p->sizep; ++i) + { + int candidate = getnextline(p->p[i], line); + + if (candidate == line) + return line; + + if (candidate > line && (closest == -1 || candidate < closest)) + closest = candidate; + } + + return closest; +} + +int lua_breakpoint(lua_State* L, int funcindex, int line, int enabled) +{ + const TValue* func = luaA_toobject(L, funcindex); + api_check(L, ttisfunction(func) && !clvalue(func)->isC); + + Proto* p = clvalue(func)->l.p; + + // set the breakpoint to the next closest line with valid instructions + int target = getnextline(p, line); + + if (target != -1) + luaG_breakpoint(L, p, target, bool(enabled)); + + return target; +} + +static void getcoverage(Proto* p, int depth, int* buffer, size_t size, void* context, lua_Coverage callback) +{ + memset(buffer, -1, size * sizeof(int)); + + for (int i = 0; i < p->sizecode; ++i) + { + Instruction insn = p->code[i]; + if (LUAU_INSN_OP(insn) != LOP_COVERAGE) + continue; + + int line = luaG_getline(p, i); + int hits = LUAU_INSN_E(insn); + + LUAU_ASSERT(size_t(line) < size); + buffer[line] = buffer[line] < hits ? hits : buffer[line]; + } + + const char* debugname = p->debugname ? getstr(p->debugname) : NULL; + int linedefined = p->linedefined; + + callback(context, debugname, linedefined, depth, buffer, size); + + for (int i = 0; i < p->sizep; ++i) + getcoverage(p->p[i], depth + 1, buffer, size, context, callback); +} + +void lua_getcoverage(lua_State* L, int funcindex, void* context, lua_Coverage callback) +{ + const TValue* func = luaA_toobject(L, funcindex); + api_check(L, ttisfunction(func) && !clvalue(func)->isC); + + Proto* p = clvalue(func)->l.p; + + size_t size = getmaxline(p) + 1; + if (size == 0) + return; + + int* buffer = luaM_newarray(L, size, int, 0); + + getcoverage(p, 0, buffer, size, context, callback); + + luaM_freearray(L, buffer, size, int, 0); +} + +static void getcounters(lua_State* L, Proto* p, void* context, lua_CounterFunction functionvisit, lua_CounterValue countervisit) +{ + if (p->execdata != nullptr && L->global->ecb.getcounterdata != nullptr) + { + size_t count = 0; + char* data = L->global->ecb.getcounterdata(L, p, &count); + + if (data != nullptr && count != 0) + { + const char* debugname = p->debugname ? getstr(p->debugname) : nullptr; + int linedefined = p->linedefined; + + functionvisit(context, debugname, linedefined); + + for (size_t i = 0; i < count; i++) + { + uint32_t kind = 0; + memcpy(&kind, data + 0, sizeof(kind)); + data += sizeof(kind); + + uint32_t pcpos = 0; + memcpy(&pcpos, data + 0, sizeof(pcpos)); + data += sizeof(pcpos); + + uint64_t hits = 0; + memcpy(&hits, data + 0, sizeof(hits)); + data += sizeof(hits); + + int line = pcpos == ~0u ? p->linedefined : luaG_getline(p, pcpos); + + countervisit(context, kind, line, hits); + } + } + } + + for (int i = 0; i < p->sizep; ++i) + getcounters(L, p->p[i], context, functionvisit, countervisit); +} + +void lua_getcounters(lua_State* L, int funcindex, void* context, lua_CounterFunction functionvisit, lua_CounterValue countervisit) +{ + const TValue* func = luaA_toobject(L, funcindex); + api_check(L, ttisfunction(func) && !clvalue(func)->isC); + + if (L->global->ecb.getcounterdata == nullptr) + return; + + Proto* p = clvalue(func)->l.p; + + getcounters(L, p, context, functionvisit, countervisit); +} + +static size_t append(char* buf, size_t bufsize, size_t offset, const char* data) +{ + size_t size = strlen(data); + size_t copy = offset + size >= bufsize ? bufsize - offset - 1 : size; + memcpy(buf + offset, data, copy); + return offset + copy; +} + +const char* lua_debugtrace(lua_State* L) +{ + static char buf[4096]; + + const int limit1 = 10; + const int limit2 = 10; + + int depth = int(L->ci - L->base_ci); + size_t offset = 0; + + lua_Debug ar; + for (int level = 0; lua_getinfo(L, level, "sln", &ar); ++level) + { + if (ar.source) + offset = append(buf, sizeof(buf), offset, ar.short_src); + + if (ar.currentline > 0) + { + char line[32]; + snprintf(line, sizeof(line), ":%d", ar.currentline); + + offset = append(buf, sizeof(buf), offset, line); + } + + if (ar.name) + { + offset = append(buf, sizeof(buf), offset, " function "); + offset = append(buf, sizeof(buf), offset, ar.name); + } + + offset = append(buf, sizeof(buf), offset, "\n"); + + if (depth > limit1 + limit2 && level == limit1 - 1) + { + char skip[32]; + snprintf(skip, sizeof(skip), "... (+%d frames)\n", int(depth - limit1 - limit2)); + + offset = append(buf, sizeof(buf), offset, skip); + + level = depth - limit2 - 1; + } + } + + LUAU_ASSERT(offset < sizeof(buf)); + buf[offset] = '\0'; + + return buf; +} diff --git a/thirdparty/luau/upstream/VM/src/ldebug.h b/thirdparty/luau/upstream/VM/src/ldebug.h new file mode 100644 index 000000000..3ff4d736c --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ldebug.h @@ -0,0 +1,34 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lstate.h" + +#define pcRel(pc, p) ((pc) && (pc) != (p)->code ? cast_to(int, (pc) - (p)->code) - 1 : 0) + +#define luaG_typeerror(L, o, opname) luaG_typeerrorL(L, o, opname) +#define luaG_forerror(L, o, what) luaG_forerrorL(L, o, what) +#define luaG_runerror(L, fmt, ...) luaG_runerrorL(L, fmt, ##__VA_ARGS__) + +#define LUA_MEMERRMSG "not enough memory" +#define LUA_ERRERRMSG "error in error handling" + +LUAI_FUNC l_noret luaG_typeerrorL(lua_State* L, const TValue* o, const char* opname); +LUAI_FUNC l_noret luaG_forerrorL(lua_State* L, const TValue* o, const char* what); +LUAI_FUNC l_noret luaG_concaterror(lua_State* L, StkId p1, StkId p2); +LUAI_FUNC l_noret luaG_aritherror(lua_State* L, const TValue* p1, const TValue* p2, TMS op); +LUAI_FUNC l_noret luaG_ordererror(lua_State* L, const TValue* p1, const TValue* p2, TMS op); +LUAI_FUNC l_noret luaG_indexerror(lua_State* L, const TValue* p1, const TValue* p2); +LUAI_FUNC l_noret luaG_methoderror(lua_State* L, const TValue* p1, const TString* p2); +LUAI_FUNC l_noret luaG_readonlyerror(lua_State* L); + +LUAI_FUNC LUA_PRINTF_ATTR(2, 3) l_noret luaG_runerrorL(lua_State* L, const char* fmt, ...); +LUAI_FUNC void luaG_pusherror(lua_State* L, const char* error); + +LUAI_FUNC void luaG_breakpoint(lua_State* L, Proto* p, int line, bool enable); +LUAI_FUNC bool luaG_onbreak(lua_State* L); + +LUAI_FUNC int luaG_getline(Proto* p, int pc); + +LUAI_FUNC int luaG_isnative(lua_State* L, int level); +LUAI_FUNC int luaG_hasnative(lua_State* L, int level); diff --git a/thirdparty/luau/upstream/VM/src/ldo.cpp b/thirdparty/luau/upstream/VM/src/ldo.cpp new file mode 100644 index 000000000..0773bf284 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ldo.cpp @@ -0,0 +1,794 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "ldo.h" + +#include "lstring.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lvm.h" + +#if LUA_USE_LONGJMP +#include +#include +#else +#include +#endif + +#include + +LUAU_FASTFLAGVARIABLE(LuauStacklessPcall) + +// keep max stack allocation request under 1GB +#define MAX_STACK_SIZE (int(1024 / sizeof(TValue)) * 1024 * 1024) + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + +#if LUA_USE_LONGJMP +struct lua_jmpbuf +{ + lua_jmpbuf* volatile prev; + volatile int status; + jmp_buf buf; +}; + +// use POSIX versions of setjmp/longjmp if possible: they don't save/restore signal mask and are therefore faster +#if defined(__linux__) || defined(__APPLE__) +#define LUAU_SETJMP(buf) _setjmp(buf) +#define LUAU_LONGJMP(buf, code) _longjmp(buf, code) +#else +#define LUAU_SETJMP(buf) setjmp(buf) +#define LUAU_LONGJMP(buf, code) longjmp(buf, code) +#endif + +int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud) +{ + lua_jmpbuf jb; + jb.prev = L->global->errorjmp; + jb.status = 0; + L->global->errorjmp = &jb; + + if (LUAU_SETJMP(jb.buf) == 0) + f(L, ud); + + L->global->errorjmp = jb.prev; + return jb.status; +} + +l_noret luaD_throw(lua_State* L, int errcode) +{ + if (lua_jmpbuf* jb = L->global->errorjmp) + { + jb->status = errcode; + LUAU_LONGJMP(jb->buf, 1); + } + + if (L->global->cb.panic) + L->global->cb.panic(L, errcode); + + abort(); +} +#else +class lua_exception : public std::exception +{ +public: + lua_exception(lua_State* L, int status) + : L(L) + , status(status) + { + } + + const char* what() const throw() override + { + // LUA_ERRRUN passes error object on the stack + if (status == LUA_ERRRUN) + if (const char* str = lua_tostring(L, -1)) + return str; + + switch (status) + { + case LUA_ERRRUN: + return "lua_exception: runtime error"; + case LUA_ERRSYNTAX: + return "lua_exception: syntax error"; + case LUA_ERRMEM: + return "lua_exception: " LUA_MEMERRMSG; + case LUA_ERRERR: + return "lua_exception: " LUA_ERRERRMSG; + default: + return "lua_exception: unexpected exception status"; + } + } + + int getStatus() const + { + return status; + } + + const lua_State* getThread() const + { + return L; + } + +private: + lua_State* L; + int status; +}; + +int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud) +{ + int status = 0; + + try + { + f(L, ud); + return 0; + } + catch (lua_exception& e) + { + // It is assumed/required that the exception caught here was thrown from the same Luau state. + // If this assert fires, it indicates a lua_exception was not properly caught and propagated + // to the exception handler for a different Luau state. Report this issue to the Luau team if + // you need more information or assistance resolving this assert. + LUAU_ASSERT(e.getThread() == L); + + status = e.getStatus(); + } + catch (std::exception& e) + { + // Luau will never throw this, but this can catch exceptions that escape from C++ implementations of external functions + try + { + // there's no exception object on stack; let's push the error on stack so that error handling below can proceed + luaG_pusherror(L, e.what()); + status = LUA_ERRRUN; + } + catch (std::exception&) + { + // out of memory while allocating error string + status = LUA_ERRMEM; + } + } + + return status; +} + +l_noret luaD_throw(lua_State* L, int errcode) +{ + throw lua_exception(L, errcode); +} +#endif + +// }====================================================== + +static void correctstack(lua_State* L, TValue* oldstack) +{ + L->top = (L->top - oldstack) + L->stack; + for (UpVal* up = L->openupval; up != NULL; up = up->u.open.threadnext) + up->v = (up->v - oldstack) + L->stack; + for (CallInfo* ci = L->base_ci; ci <= L->ci; ci++) + { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; +} + +void luaD_reallocstack(lua_State* L, int newsize, int fornewci) +{ + // throw 'out of memory' error because space for a custom error message cannot be guaranteed here + if (newsize > MAX_STACK_SIZE) + { + // reallocation was performed to setup a new CallInfo frame, which we have to remove + if (fornewci) + { + CallInfo* cip = L->ci - 1; + + L->ci = cip; + L->base = cip->base; + L->top = cip->top; + } + + luaD_throw(L, LUA_ERRMEM); + } + + TValue* oldstack = L->stack; + int realsize = newsize + EXTRA_STACK; + LUAU_ASSERT(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + luaM_reallocarray(L, L->stack, L->stacksize, realsize, TValue, L->memcat); + TValue* newstack = L->stack; + for (int i = L->stacksize; i < realsize; i++) + setnilvalue(newstack + i); // erase new segment + L->stacksize = realsize; + L->stack_last = newstack + newsize; + correctstack(L, oldstack); +} + +void luaD_reallocCI(lua_State* L, int newsize) +{ + CallInfo* oldci = L->base_ci; + luaM_reallocarray(L, L->base_ci, L->size_ci, newsize, CallInfo, L->memcat); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; +} + +void luaD_growstack(lua_State* L, int n) +{ + luaD_reallocstack(L, getgrownstacksize(L, n), 0); +} + +CallInfo* luaD_growCI(lua_State* L) +{ + // allow extra stack space to handle stack overflow in xpcall + const int hardlimit = LUAI_MAXCALLS + (LUAI_MAXCALLS >> 3); + + if (L->size_ci >= hardlimit) + luaD_throw(L, LUA_ERRERR); // error while handling stack error + + int request = L->size_ci * 2; + luaD_reallocCI(L, L->size_ci >= LUAI_MAXCALLS ? hardlimit : request < LUAI_MAXCALLS ? request : LUAI_MAXCALLS); + + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + + return ++L->ci; +} + +void luaD_checkCstack(lua_State* L) +{ + // allow extra stack space to handle stack overflow in xpcall + const int hardlimit = LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3); + + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= hardlimit) + luaD_throw(L, LUA_ERRERR); // error while handling stack error +} + +static void performcall(lua_State* L, StkId func, int nresults, bool preparereentry) +{ + if (luau_precall(L, func, nresults) == PCRLUA) + { // is a Lua function? + L->ci->flags |= LUA_CALLINFO_RETURN; // luau_execute will stop after returning from the stack frame + + bool oldactive = L->isactive; + L->isactive = true; + luaC_threadbarrier(L); + + if (FFlag::LuauStacklessPcall) + { + if (preparereentry) + L->status = SCHEDULED_REENTRY; + else + luau_execute(L); + } + else + { + luau_execute(L); // call it + } + + if (!oldactive) + L->isactive = false; + } +} + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_callint(lua_State* L, StkId func, int nresults, bool preparereentry) +{ + if (++L->nCcalls >= LUAI_MAXCCALLS) + luaD_checkCstack(L); + + // when called from a yieldable C function, maintain yieldable invariant (baseCcalls <= nCcalls) + bool fromyieldableccall = false; + + if (L->ci != L->base_ci) + { + Closure* ccl = clvalue(L->ci->func); + + if (ccl->isC && ccl->c.cont) + { + fromyieldableccall = true; + L->baseCcalls++; + } + } + + ptrdiff_t funcoffset = savestack(L, func); + ptrdiff_t cioffset = saveci(L, L->ci); + + performcall(L, func, nresults, preparereentry); + + bool yielded = FFlag::LuauStacklessPcall ? isyielded(L) : L->status == LUA_YIELD || L->status == LUA_BREAK; + + if (fromyieldableccall) + { + // restore original yieldable invariant + // in case of an error, this would either be restored by luaD_pcall or the thread would no longer be resumable + L->baseCcalls--; + + // on yield, we have to set the CallInfo top of the C function including slots for expected results, to restore later + if (yielded) + { + CallInfo* callerci = restoreci(L, cioffset); + callerci->top = restorestack(L, funcoffset) + (nresults != LUA_MULTRET ? nresults : 0); + } + } + + if (nresults != LUA_MULTRET && !yielded) + L->top = restorestack(L, funcoffset) + nresults; + + L->nCcalls--; + luaC_checkGC(L); +} + +void luaD_call(lua_State* L, StkId func, int nresults) +{ + luaD_callint(L, func, nresults, /* preparereentry */ false); +} + +// Non-yieldable version of luaD_call, used primarily to call an error handler which cannot yield +void luaD_callny(lua_State* L, StkId func, int nresults) +{ + if (++L->nCcalls >= LUAI_MAXCCALLS) + luaD_checkCstack(L); + + LUAU_ASSERT(L->nCcalls > L->baseCcalls); + + ptrdiff_t funcoffset = savestack(L, func); + + performcall(L, func, nresults, /* preparereentry */ false); + + if (FFlag::LuauStacklessPcall) + LUAU_ASSERT(!isyielded(L)); + else + LUAU_ASSERT(L->status != LUA_YIELD && L->status != LUA_BREAK); + + if (nresults != LUA_MULTRET) + L->top = restorestack(L, funcoffset) + nresults; + + L->nCcalls--; + luaC_checkGC(L); +} + +void luaD_seterrorobj(lua_State* L, int errcode, StkId oldtop) +{ + switch (errcode) + { + case LUA_ERRMEM: + { + setsvalue(L, oldtop, luaS_newliteral(L, LUA_MEMERRMSG)); // can not fail because string is pinned in luaopen + break; + } + case LUA_ERRERR: + { + setsvalue(L, oldtop, luaS_newliteral(L, LUA_ERRERRMSG)); // can not fail because string is pinned in luaopen + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: + { + setobj2s(L, oldtop, L->top - 1); // error message on current top + break; + } + } + L->top = oldtop + 1; +} + +static void resume_continue(lua_State* L) +{ + // unroll Luau/C combined stack, processing continuations + while ((FFlag::LuauStacklessPcall ? L->status == LUA_OK || L->status == SCHEDULED_REENTRY : L->status == LUA_OK) && L->ci > L->base_ci) + { + LUAU_ASSERT(L->baseCcalls == L->nCcalls); + + if (FFlag::LuauStacklessPcall) + L->status = LUA_OK; + + Closure* cl = curr_func(L); + + if (cl->isC) + { + LUAU_ASSERT(cl->c.cont); + + // C continuation; we expect this to be followed by Lua continuations + int n = cl->c.cont(L, 0); + + // continuation can break or yield again + if (L->status == LUA_BREAK || L->status == LUA_YIELD) + break; + + luau_poscall(L, L->top - n); + } + else + { + // Luau continuation; it terminates at the end of the stack or at another C continuation + luau_execute(L); + } + } +} + +static void resume(lua_State* L, void* ud) +{ + StkId firstArg = cast_to(StkId, ud); + + if (FFlag::LuauStacklessPcall) + { + if (L->status == LUA_OK) + { + // start coroutine + LUAU_ASSERT(L->ci == L->base_ci && firstArg >= L->base); + if (firstArg == L->base) + luaG_runerror(L, "cannot resume dead coroutine"); + + int precallresult = luau_precall(L, firstArg - 1, LUA_MULTRET); + + // on scheduled reentry, we will continue into the yield-continue block below + if (L->status == SCHEDULED_REENTRY) + { + firstArg = L->base; + } + else + { + // C function is either completed or yielded, exit + if (precallresult != PCRLUA) + return; + + // mark to not return past the current Luau function frame + L->ci->flags |= LUA_CALLINFO_RETURN; + } + } + + // restore from yield or reentry + if (L->status != LUA_OK) + { + // resume from previous yield or break + LUAU_ASSERT(firstArg >= L->base); + LUAU_ASSERT(isyielded(L)); + L->status = LUA_OK; + + Closure* cl = curr_func(L); + + if (cl->isC) + { + // if the top stack frame is a C call continuation, resume_continue will handle that case + if (!cl->c.cont) + { + // finish interrupted execution of `OP_CALL' + luau_poscall(L, firstArg); + } + else + { + // restore arguments we have protected for C continuation + L->base = L->ci->base; + } + } + else + { + // yielded inside a hook: just continue its execution + L->base = L->ci->base; + } + } + } + else + { + if (L->status == 0) + { + // start coroutine + LUAU_ASSERT(L->ci == L->base_ci && firstArg >= L->base); + if (firstArg == L->base) + luaG_runerror(L, "cannot resume dead coroutine"); + + if (luau_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + + L->ci->flags |= LUA_CALLINFO_RETURN; + } + else + { + // resume from previous yield or break + LUAU_ASSERT(firstArg >= L->base); + LUAU_ASSERT(L->status == LUA_YIELD || L->status == LUA_BREAK); + L->status = 0; + + Closure* cl = curr_func(L); + + if (cl->isC) + { + // if the top stack frame is a C call continuation, resume_continue will handle that case + if (!cl->c.cont) + { + // finish interrupted execution of `OP_CALL' + luau_poscall(L, firstArg); + } + else + { + // restore arguments we have protected for C continuation + L->base = L->ci->base; + } + } + else + { + // yielded inside a hook: just continue its execution + L->base = L->ci->base; + } + } + } + + // run continuations from the stack; typically resumes Luau code and pcalls + resume_continue(L); +} + +static CallInfo* resume_findhandler(lua_State* L) +{ + CallInfo* ci = L->ci; + + while (ci > L->base_ci) + { + if (ci->flags & LUA_CALLINFO_HANDLE) + return ci; + + ci--; + } + + return NULL; +} + +static void restore_stack_limit(lua_State* L) +{ + LUAU_ASSERT(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + if (L->size_ci > LUAI_MAXCALLS) + { // there was an overflow? + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) // can `undo' overflow? + luaD_reallocCI(L, LUAI_MAXCALLS); + } +} + +static void resume_handle(lua_State* L, void* ud) +{ + CallInfo* ci = (CallInfo*)ud; + Closure* cl = ci_func(ci); + + LUAU_ASSERT(ci->flags & LUA_CALLINFO_HANDLE); + LUAU_ASSERT(cl->isC && cl->c.cont); + LUAU_ASSERT(L->status != 0); + + // restore nCcalls back to base since this might not have happened during error handling + L->nCcalls = L->baseCcalls; + + // make sure we don't run the handler the second time + ci->flags &= ~LUA_CALLINFO_HANDLE; + + // restore thread status to LUA_OK since we're handling the error + int status = L->status; + + L->status = LUA_OK; + + // push error object to stack top if it's not already there + if (status != LUA_ERRRUN) + luaD_seterrorobj(L, status, L->top); + + // adjust the stack frame for ci to prepare for cont call + L->base = ci->base; + ci->top = L->top; + + // save ci pointer - it will be invalidated by cont call! + ptrdiff_t old_ci = saveci(L, ci); + + // handle the error in continuation; note that this executes on top of original stack! + int n = cl->c.cont(L, status); + + // restore the stack frame to the frame with continuation + L->ci = restoreci(L, old_ci); + + // close eventual pending closures; this means it's now safe to restore stack + luaF_close(L, L->ci->base); + + restore_stack_limit(L); + + // finish cont call and restore stack to previous ci top + luau_poscall(L, L->top - n); + + // run remaining continuations from the stack; typically resumes pcalls + resume_continue(L); +} + +static int resume_error(lua_State* L, const char* msg, int narg) +{ + L->top -= narg; + setsvalue(L, L->top, luaS_new(L, msg)); + incr_top(L); + return LUA_ERRRUN; +} + +static int resume_start(lua_State* L, lua_State* from, int nargs) +{ + api_check(L, L->top - L->base >= nargs); + + if (L->status != LUA_YIELD && L->status != LUA_BREAK && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine", nargs); + + L->nCcalls = from ? from->nCcalls : 0; + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow", nargs); + + L->baseCcalls = ++L->nCcalls; + L->isactive = true; + + luaC_threadbarrier(L); + + return LUA_OK; +} + +static int resume_finish(lua_State* L, int status) +{ + CallInfo* ch = NULL; + while (status != LUA_OK && (ch = resume_findhandler(L)) != NULL) + { + if (FFlag::LuauStacklessPcall && lua_isyieldable(L) != 0 && L->global->cb.debugprotectederror) + { + L->global->cb.debugprotectederror(L); + + // debug hook is only allowed to break + if (L->status == LUA_BREAK) + { + status = LUA_OK; + break; + } + } + + L->status = cast_byte(status); + status = luaD_rawrunprotected(L, resume_handle, ch); + } + + // C call count base was set to an incremented value of C call count in resume, so we decrement here + L->nCcalls = --L->baseCcalls; + + // make execution context non-yieldable as we are leaving the resume + L->baseCcalls = L->nCcalls; + + L->isactive = false; + + if (status != LUA_OK) + { + L->status = cast_byte(status); + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else if (L->status == LUA_OK) + { + expandstacklimit(L, L->top); + } + + return L->status; +} + +int lua_resume(lua_State* L, lua_State* from, int nargs) +{ + if (int starterror = resume_start(L, from, nargs)) + return starterror; + + int status = luaD_rawrunprotected(L, resume, L->top - nargs); + + return resume_finish(L, status); +} + +int lua_resumeerror(lua_State* L, lua_State* from) +{ + if (int starterror = resume_start(L, from, 1)) + return starterror; + + int status = LUA_ERRRUN; + + if (CallInfo* ci = resume_findhandler(L)) + { + L->status = cast_byte(status); + status = luaD_rawrunprotected(L, resume_handle, ci); + } + + return resume_finish(L, status); +} + +int lua_yield(lua_State* L, int nresults) +{ + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; // protect stack slots below + L->status = LUA_YIELD; + return -1; +} + +int lua_break(lua_State* L) +{ + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to break across metamethod/C-call boundary"); + L->status = LUA_BREAK; + return -1; +} + +int lua_isyieldable(lua_State* L) +{ + return (L->nCcalls <= L->baseCcalls); +} + +static void callerrfunc(lua_State* L, void* ud) +{ + StkId errfunc = cast_to(StkId, ud); + + setobj2s(L, L->top, L->top - 1); + setobj2s(L, L->top - 1, errfunc); + incr_top(L); + + luaD_callny(L, L->top - 2, 1); +} + +int luaD_pcall(lua_State* L, Pfunc func, void* u, ptrdiff_t old_top, ptrdiff_t ef) +{ + unsigned short oldnCcalls = L->nCcalls; + unsigned short oldbaseCcalls = L->baseCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + bool oldactive = L->isactive; + int status = luaD_rawrunprotected(L, func, u); + if (status != 0) + { + int errstatus = status; + + // call user-defined error function (used in xpcall) + if (ef) + { + // push error object to stack top if it's not already there + if (status != LUA_ERRRUN) + luaD_seterrorobj(L, status, L->top); + + // if errfunc fails, we fail with "error in error handling" or "not enough memory" + int err = luaD_rawrunprotected(L, callerrfunc, restorestack(L, ef)); + + // in general we preserve the status, except for cases when the error handler fails + // out of memory is treated specially because it's common for it to be cascading, in which case we preserve the code + if (err == 0) + errstatus = LUA_ERRRUN; + else if (status == LUA_ERRMEM && err == LUA_ERRMEM) + errstatus = LUA_ERRMEM; + else + errstatus = status = LUA_ERRERR; + } + + // since the call failed with an error, we might have to reset the 'active' thread state + if (!oldactive) + L->isactive = false; + + bool yieldable = L->nCcalls <= L->baseCcalls; // Inlined logic from 'lua_isyieldable' to avoid potential for an out of line call. + + // restore nCcalls and baseCcalls before calling the debugprotectederror callback which may rely on the proper value to have been restored. + L->nCcalls = oldnCcalls; + L->baseCcalls = oldbaseCcalls; + + // an error occurred, check if we have a protected error callback + if (yieldable && L->global->cb.debugprotectederror) + { + L->global->cb.debugprotectederror(L); + + // debug hook is only allowed to break + if (L->status == LUA_BREAK) + return 0; + } + + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); // close eventual pending closures + luaD_seterrorobj(L, errstatus, oldtop); + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + restore_stack_limit(L); + } + return status; +} diff --git a/thirdparty/luau/upstream/VM/src/ldo.h b/thirdparty/luau/upstream/VM/src/ldo.h new file mode 100644 index 000000000..23f25ce68 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ldo.h @@ -0,0 +1,79 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" +#include "lstate.h" +#include "luaconf.h" +#include "ldebug.h" + +// returns target stack for 'n' extra elements to reallocate +// if possible, stack size growth factor is 2x +#define getgrownstacksize(L, n) ((n) <= L->stacksize ? 2 * L->stacksize : L->stacksize + (n)) +#define stacklimitreached(L, n) ((char*)L->stack_last - (char*)L->top <= (n) * (int)sizeof(TValue)) + +#define luaD_checkstackfornewci(L, n) \ + if (stacklimitreached(L, (n))) \ + luaD_reallocstack(L, getgrownstacksize(L, (n)), 1); \ + else \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK, 1)); + +#define luaD_checkstack(L, n) \ + if (stacklimitreached(L, (n))) \ + luaD_growstack(L, n); \ + else \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK, 0)); + +#define incr_top(L) \ + { \ + luaD_checkstack(L, 1); \ + L->top++; \ + } + +#define savestack(L, p) ((char*)(p) - (char*)L->stack) +#define restorestack(L, n) ((TValue*)((char*)L->stack + (n))) + +#define expandstacklimit(L, p) \ + { \ + LUAU_ASSERT((p) <= (L)->stack_last); \ + if ((L)->ci->top < (p)) \ + (L)->ci->top = (p); \ + } + +#define incr_ci(L) ((L->ci == L->end_ci) ? luaD_growCI(L) : (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + +#define saveci(L, p) ((char*)(p) - (char*)L->base_ci) +#define restoreci(L, n) ((CallInfo*)((char*)L->base_ci + (n))) + +#define isyielded(L) ((L)->status == LUA_YIELD || (L)->status == LUA_BREAK || (L)->status == SCHEDULED_REENTRY) + +// results from luaD_precall +#define PCRLUA 0 // initiated a call to a Lua function +#define PCRC 1 // did a call to a C function +#define PCRYIELD 2 // C function yielded + +// return value for a yielded C call +#define C_CALL_YIELD -1 + +// luaD_call can 'yield' into an immediate reentry +// reentry will remove extra call frames from C call stack and continue execution +// this lua_State::status code is internal and should not be used by users +#define SCHEDULED_REENTRY 0x7f + +// type of protected functions, to be ran by `runprotected' +typedef void (*Pfunc)(lua_State* L, void* ud); + +LUAI_FUNC CallInfo* luaD_growCI(lua_State* L); + +LUAI_FUNC void luaD_callint(lua_State* L, StkId func, int nresults, bool forreentry); +LUAI_FUNC void luaD_call(lua_State* L, StkId func, int nresults); +LUAI_FUNC void luaD_callny(lua_State* L, StkId func, int nresults); +LUAI_FUNC int luaD_pcall(lua_State* L, Pfunc func, void* u, ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC void luaD_reallocCI(lua_State* L, int newsize); +LUAI_FUNC void luaD_reallocstack(lua_State* L, int newsize, int fornewci); +LUAI_FUNC void luaD_growstack(lua_State* L, int n); +LUAI_FUNC void luaD_checkCstack(lua_State* L); +LUAI_FUNC void luaD_seterrorobj(lua_State* L, int errcode, StkId oldtop); + +LUAI_FUNC l_noret luaD_throw(lua_State* L, int errcode); +LUAI_FUNC int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud); diff --git a/thirdparty/luau/upstream/VM/src/lfunc.cpp b/thirdparty/luau/upstream/VM/src/lfunc.cpp new file mode 100644 index 000000000..b172d0ad6 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lfunc.cpp @@ -0,0 +1,211 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lfunc.h" + +#include "lstate.h" +#include "lmem.h" +#include "lgc.h" + +Proto* luaF_newproto(lua_State* L) +{ + Proto* f = luaM_newgco(L, Proto, sizeof(Proto), L->activememcat); + + luaC_init(L, f, LUA_TPROTO); + + f->nups = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->flags = 0; + + f->k = NULL; + f->code = NULL; + f->p = NULL; + f->codeentry = NULL; + + f->execdata = NULL; + f->exectarget = 0; + + f->lineinfo = NULL; + f->abslineinfo = NULL; + f->locvars = NULL; + f->upvalues = NULL; + f->source = NULL; + + f->debugname = NULL; + f->debuginsn = NULL; + + f->typeinfo = NULL; + + f->userdata = NULL; + + f->gclist = NULL; + + f->sizecode = 0; + f->sizep = 0; + f->sizelocvars = 0; + f->sizeupvalues = 0; + f->sizek = 0; + f->sizelineinfo = 0; + f->linegaplog2 = 0; + f->linedefined = 0; + f->bytecodeid = 0; + f->sizetypeinfo = 0; + + return f; +} + +Closure* luaF_newLclosure(lua_State* L, int nelems, LuaTable* e, Proto* p) +{ + Closure* c = luaM_newgco(L, Closure, sizeLclosure(nelems), L->activememcat); + luaC_init(L, c, LUA_TFUNCTION); + c->isC = 0; + c->env = e; + c->nupvalues = cast_byte(nelems); + c->stacksize = p->maxstacksize; + c->preload = 0; + c->l.p = p; + for (int i = 0; i < nelems; ++i) + setnilvalue(&c->l.uprefs[i]); + return c; +} + +Closure* luaF_newCclosure(lua_State* L, int nelems, LuaTable* e) +{ + Closure* c = luaM_newgco(L, Closure, sizeCclosure(nelems), L->activememcat); + luaC_init(L, c, LUA_TFUNCTION); + c->isC = 1; + c->env = e; + c->nupvalues = cast_byte(nelems); + c->stacksize = LUA_MINSTACK; + c->preload = 0; + c->c.f = NULL; + c->c.cont = NULL; + c->c.debugname = NULL; + return c; +} + +UpVal* luaF_findupval(lua_State* L, StkId level) +{ + global_State* g = L->global; + UpVal** pp = &L->openupval; + UpVal* p; + while (*pp != NULL && (p = *pp)->v >= level) + { + LUAU_ASSERT(!isdead(g, obj2gco(p))); + LUAU_ASSERT(upisopen(p)); + if (p->v == level) + return p; + + pp = &p->u.open.threadnext; + } + + LUAU_ASSERT(L->isactive); + LUAU_ASSERT(!isblack(obj2gco(L))); // we don't use luaC_threadbarrier because active threads never turn black + + UpVal* uv = luaM_newgco(L, UpVal, sizeof(UpVal), L->activememcat); // not found: create a new one + luaC_init(L, uv, LUA_TUPVAL); + uv->markedopen = 0; + uv->v = level; // current value lives in the stack + + // chain the upvalue in the threads open upvalue list at the proper position + uv->u.open.threadnext = *pp; + *pp = uv; + + // double link the upvalue in the global open upvalue list + uv->u.open.prev = &g->uvhead; + uv->u.open.next = g->uvhead.u.open.next; + uv->u.open.next->u.open.prev = uv; + g->uvhead.u.open.next = uv; + LUAU_ASSERT(uv->u.open.next->u.open.prev == uv && uv->u.open.prev->u.open.next == uv); + + return uv; +} + +void luaF_freeupval(lua_State* L, UpVal* uv, lua_Page* page) +{ + luaM_freegco(L, uv, sizeof(UpVal), uv->memcat, page); // free upvalue +} + +void luaF_close(lua_State* L, StkId level) +{ + global_State* g = L->global; + UpVal* uv; + while (L->openupval != NULL && (uv = L->openupval)->v >= level) + { + GCObject* o = obj2gco(uv); + LUAU_ASSERT(!isblack(o) && upisopen(uv)); + LUAU_ASSERT(!isdead(g, o)); + + // unlink value *before* closing it since value storage overlaps + L->openupval = uv->u.open.threadnext; + + luaF_closeupval(L, uv, /* dead= */ false); + } +} + +void luaF_closeupval(lua_State* L, UpVal* uv, bool dead) +{ + // unlink value from all lists *before* closing it since value storage overlaps + LUAU_ASSERT(uv->u.open.next->u.open.prev == uv && uv->u.open.prev->u.open.next == uv); + uv->u.open.next->u.open.prev = uv->u.open.prev; + uv->u.open.prev->u.open.next = uv->u.open.next; + + if (dead) + return; + + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; + luaC_upvalclosed(L, uv); +} + +void luaF_freeproto(lua_State* L, Proto* f, lua_Page* page) +{ + luaM_freearray(L, f->code, f->sizecode, Instruction, f->memcat); + luaM_freearray(L, f->p, f->sizep, Proto*, f->memcat); + luaM_freearray(L, f->k, f->sizek, TValue, f->memcat); + if (f->lineinfo) + luaM_freearray(L, f->lineinfo, f->sizelineinfo, uint8_t, f->memcat); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar, f->memcat); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString*, f->memcat); + if (f->debuginsn) + luaM_freearray(L, f->debuginsn, f->sizecode, uint8_t, f->memcat); + + if (f->execdata) + L->global->ecb.destroy(L, f); + + if (f->typeinfo) + luaM_freearray(L, f->typeinfo, f->sizetypeinfo, uint8_t, f->memcat); + + luaM_freegco(L, f, sizeof(Proto), f->memcat, page); +} + +void luaF_freeclosure(lua_State* L, Closure* c, lua_Page* page) +{ + int size = c->isC ? sizeCclosure(c->nupvalues) : sizeLclosure(c->nupvalues); + luaM_freegco(L, c, size, c->memcat, page); +} + +const LocVar* luaF_getlocal(const Proto* f, int local_number, int pc) +{ + for (int i = 0; i < f->sizelocvars; i++) + { + if (pc >= f->locvars[i].startpc && pc < f->locvars[i].endpc) + { // is variable active? + local_number--; + if (local_number == 0) + return &f->locvars[i]; + } + } + + return NULL; // not found +} + +const LocVar* luaF_findlocal(const Proto* f, int local_reg, int pc) +{ + for (int i = 0; i < f->sizelocvars; i++) + if (local_reg == f->locvars[i].reg && pc >= f->locvars[i].startpc && pc < f->locvars[i].endpc) + return &f->locvars[i]; + + return NULL; // not found +} diff --git a/thirdparty/luau/upstream/VM/src/lfunc.h b/thirdparty/luau/upstream/VM/src/lfunc.h new file mode 100644 index 000000000..453cf581b --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lfunc.h @@ -0,0 +1,20 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" + +#define sizeCclosure(n) (offsetof(Closure, c.upvals) + sizeof(TValue) * (n)) +#define sizeLclosure(n) (offsetof(Closure, l.uprefs) + sizeof(TValue) * (n)) + +LUAI_FUNC Proto* luaF_newproto(lua_State* L); +LUAI_FUNC Closure* luaF_newLclosure(lua_State* L, int nelems, LuaTable* e, Proto* p); +LUAI_FUNC Closure* luaF_newCclosure(lua_State* L, int nelems, LuaTable* e); +LUAI_FUNC UpVal* luaF_findupval(lua_State* L, StkId level); +LUAI_FUNC void luaF_close(lua_State* L, StkId level); +LUAI_FUNC void luaF_closeupval(lua_State* L, UpVal* uv, bool dead); +LUAI_FUNC void luaF_freeproto(lua_State* L, Proto* f, struct lua_Page* page); +LUAI_FUNC void luaF_freeclosure(lua_State* L, Closure* c, struct lua_Page* page); +LUAI_FUNC void luaF_freeupval(lua_State* L, UpVal* uv, struct lua_Page* page); +LUAI_FUNC const LocVar* luaF_getlocal(const Proto* func, int local_number, int pc); +LUAI_FUNC const LocVar* luaF_findlocal(const Proto* func, int local_reg, int pc); diff --git a/thirdparty/luau/upstream/VM/src/lgc.cpp b/thirdparty/luau/upstream/VM/src/lgc.cpp new file mode 100644 index 000000000..873877c81 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lgc.cpp @@ -0,0 +1,1313 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lgc.h" + +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" +#include "lfunc.h" +#include "lstring.h" +#include "ldo.h" +#include "lmem.h" +#include "ludata.h" +#include "lbuffer.h" + +#include + +/* + * Luau uses an incremental non-generational non-moving mark&sweep garbage collector. + * + * The collector runs in three stages: mark, atomic and sweep. Mark and sweep are incremental and try to do a limited amount + * of work every GC step; atomic is ran once per the GC cycle and is indivisible. In either case, the work happens during GC + * steps that are "scheduled" by the GC pacing algorithm - the steps happen either from explicit calls to lua_gc, or after + * the mutator (aka application) allocates some amount of memory, which is known as "GC assist". In either case, GC steps + * can't happen concurrently with other access to VM state. + * + * Current GC stage is stored in global_State::gcstate, and has two additional stages for pause and second-phase mark, explained below. + * + * GC pacer is an algorithm that tries to ensure that GC can always catch up to the application allocating garbage, but do this + * with minimal amount of effort. To configure the pacer Luau provides control over three variables: GC goal, defined as the + * target heap size during atomic phase in relation to live heap size (e.g. 200% goal means the heap's worst case size is double + * the total size of alive objects), step size (how many kilobytes should the application allocate for GC step to trigger), and + * GC multiplier (how much should the GC try to mark relative to how much the application allocated). It's critical that step + * multiplier is significantly above 1, as this is what allows the GC to catch up to the application's allocation rate, and + * GC goal and GC multiplier are linked in subtle ways, described in lua.h comments for LUA_GCSETGOAL. + * + * During mark, GC tries to identify all reachable objects and mark them as reachable, while keeping unreachable objects unmarked. + * During sweep, GC tries to sweep all objects that were not reachable at the end of mark. The atomic phase is needed to ensure + * that all pending marking has completed and all objects that are still marked as unreachable are, in fact, unreachable. + * + * Notably, during mark GC doesn't free any objects, and so the heap size constantly grows; during sweep, GC doesn't do any marking + * work, so it can't immediately free objects that became unreachable after sweeping started. + * + * Every collectable object has one of three colors at any given point in time: white, gray or black. This coloring scheme + * is necessary to implement incremental marking: white objects have not been marked and may be unreachable, black objects + * have been marked and will not be marked again if they stay black, and gray objects have been marked but may contain unmarked + * references. + * + * Objects are allocated as white; however, during sweep, we need to differentiate between objects that remained white in the mark + * phase (these are not reachable and can be freed) and objects that were allocated after the mark phase ended. Because of this, the + * colors are encoded using three bits inside GCheader::marked: white0, white1 and black (so technically we use a four-color scheme: + * any object can be white0, white1, gray or black). All bits are exclusive, and gray objects have all three bits unset. This allows + * us to have the "current" white bit, which is flipped during atomic stage - during sweeping, objects that have the white color from + * the previous mark may be deleted, and all other objects may or may not be reachable, and will be changed to the current white color, + * so that the next mark can start coloring objects from scratch again. + * + * Crucially, the coloring scheme comes with what's known as a tri-color invariant: a black object may never point to a white object. + * + * At the end of atomic stage, the expectation is that there are no gray objects anymore, which means all objects are either black + * (reachable) or white (unreachable = dead). Tri-color invariant is maintained throughout mark and atomic phase. To uphold this + * invariant, every modification of an object needs to check if the object is black and the new referent is white; if so, we + * need to either mark the referent, making it non-white (known as a forward barrier), or mark the object as gray and queue it + * for additional marking (known as a backward barrier). + * + * Luau uses both types of barriers. Forward barriers advance GC progress, since they don't create new outstanding work for GC, + * but they may be expensive when an object is modified many times in succession. Backward barriers are cheaper, as they defer + * most of the work until "later", but they require queueing the object for a rescan which isn't always possible. Table writes usually + * use backward barriers (but switch to forward barriers during second-phase mark), whereas upvalue writes and setmetatable use forward + * barriers. + * + * Since marking is incremental, it needs a way to track progress, which is implemented as a gray set: at any point, objects that + * are gray need to mark their white references, objects that are black have no pending work, and objects that are white have not yet + * been reached. Once the gray set is empty, the work completes; as such, incremental marking is as simple as removing an object from + * the gray set, and turning it to black (which requires turning all its white references to gray). The gray set is implemented as + * an intrusive singly linked list, using `gclist` field in multiple objects (functions, tables, threads and protos). When an object + * doesn't have gclist field, the marking of that object needs to be "immediate", changing the colors of all references in one go. + * + * When a black object is modified, it needs to become gray again. Objects like this are placed on a separate `grayagain` list by a + * barrier - this is important because it allows us to have a mark stage that terminates when the gray set is empty even if the mutator + * is constantly changing existing objects to gray. After mark stage finishes traversing `gray` list, we copy `grayagain` list to `gray` + * once and incrementally mark it again. During this phase of marking, we may get more objects marked as `grayagain`, so after we finish + * emptying out the `gray` list the second time, we finish the mark stage and do final marking of `grayagain` during atomic phase. + * GC works correctly without this second-phase mark (called GCSpropagateagain), but it reduces the time spent during atomic phase. + * + * Sweeping is also incremental, but instead of working at a granularity of an object, it works at a granularity of a page: all GC + * objects are allocated in special pages (see lmem.cpp for details), and sweeper traverses all objects in one page in one incremental + * step, freeing objects that aren't reachable (old white), and recoloring all other objects with the new white to prepare them for next + * mark. During sweeping we don't need to maintain the GC invariant, because our goal is to paint all objects with current white - + * however, some barriers will still trigger (because some reachable objects are still black as sweeping didn't get to them yet), and + * some barriers will proactively mark black objects as white to avoid extra barriers from triggering excessively. + * + * Most references that GC deals with are strong, and as such they fit neatly into the incremental marking scheme. Some, however, are + * weak - notably, tables can be marked as having weak keys/values (using __mode metafield). During incremental marking, we don't know + * for certain if a given object is alive - if it's marked as black, it definitely was reachable during marking, but if it's marked as + * white, we don't know if it's actually unreachable. Because of this, we need to defer weak table handling to the atomic phase; after + * all objects are marked, we traverse all weak tables (that are linked into special weak table lists using `gclist` during marking), + * and remove all entries that have white keys or values. If keys or values are strong, they are marked normally. + * + * The simplified scheme described above isn't fully accurate because of threads, upvalues and strings. + * + * Strings are semantically black (they are initially white, and when the mark stage reaches a string, it changes its color and never + * touches the object again), but they are technically marked as gray - the black bit is never set on a string object. This behavior + * is inherited from Lua 5.1 GC, but doesn't have a clear rationale - effectively, strings are marked as gray but are never part of + * a gray list. + * + * Threads are hard to deal with because for them to fit into the white-gray-black scheme, writes to thread stacks need to have barriers + * that turn the thread from black (already scanned) to gray - but this is very expensive because stack writes are very common. To + * get around this problem, threads have an "active" state which means that a thread is actively executing code. When GC reaches an active + * thread, it keeps it as gray, and rescans it during atomic phase. When a thread is inactive, GC instead paints the thread black. All + * API calls that can write to thread stacks outside of execution (which implies active) uses a thread barrier that checks if the thread is + * black, and if it is it marks it as gray and puts it on a gray list to be rescanned during atomic phase. + * + * Upvalues are special objects that can be closed, in which case they contain the value (acting as a reference cell) and can be dealt + * with using the regular algorithm, or open, in which case they refer to a stack slot in some other thread. These are difficult to deal + * with because the stack writes are not monitored. Because of this open upvalues are treated in a somewhat special way: they are never marked + * as black (doing so would violate the GC invariant), and they are kept in a special global list (global_State::uvhead) which is traversed + * during atomic phase. This is needed because an open upvalue might point to a stack location in a dead thread that never marked the stack + * slot - upvalues like this are identified since they don't have `markedopen` bit set during thread traversal and closed in `clearupvals`. + */ + +#define GC_SWEEPPAGESTEPCOST 16 + +#define GC_INTERRUPT(state) \ + { \ + void (*interrupt)(lua_State*, int) = g->cb.interrupt; \ + if (LUAU_UNLIKELY(!!interrupt)) \ + interrupt(L, state); \ + } + +#define maskmarks cast_byte(~(bitmask(BLACKBIT) | WHITEBITS)) + +#define makewhite(g, x) ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) + +#define stringmark(s) reset2bits((s)->marked, WHITE0BIT, WHITE1BIT) + +#define markvalue(g, o) \ + { \ + checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) \ + reallymarkobject(g, gcvalue(o)); \ + } + +#define markobject(g, t) \ + { \ + if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); \ + } + +#ifdef LUAI_GCMETRICS +static void recordGcStateStep(global_State* g, int startgcstate, double seconds, bool assist, size_t work) +{ + switch (startgcstate) + { + case GCSpause: + // record root mark time if we have switched to next state + if (g->gcstate == GCSpropagate) + { + g->gcmetrics.currcycle.marktime += seconds; + + if (assist) + g->gcmetrics.currcycle.markassisttime += seconds; + } + break; + case GCSpropagate: + case GCSpropagateagain: + g->gcmetrics.currcycle.marktime += seconds; + g->gcmetrics.currcycle.markwork += work; + + if (assist) + g->gcmetrics.currcycle.markassisttime += seconds; + break; + case GCSatomic: + g->gcmetrics.currcycle.atomictime += seconds; + break; + case GCSsweep: + g->gcmetrics.currcycle.sweeptime += seconds; + g->gcmetrics.currcycle.sweepwork += work; + + if (assist) + g->gcmetrics.currcycle.sweepassisttime += seconds; + break; + default: + LUAU_ASSERT(!"Unexpected GC state"); + } + + if (assist) + { + g->gcmetrics.stepassisttimeacc += seconds; + g->gcmetrics.currcycle.assistwork += work; + } + else + { + g->gcmetrics.stepexplicittimeacc += seconds; + g->gcmetrics.currcycle.explicitwork += work; + } +} + +static double recordGcDeltaTime(double& timer) +{ + double now = lua_clock(); + double delta = now - timer; + timer = now; + return delta; +} + +static void startGcCycleMetrics(global_State* g) +{ + g->gcmetrics.currcycle.starttimestamp = lua_clock(); + g->gcmetrics.currcycle.pausetime = g->gcmetrics.currcycle.starttimestamp - g->gcmetrics.lastcycle.endtimestamp; +} + +static void finishGcCycleMetrics(global_State* g) +{ + g->gcmetrics.currcycle.endtimestamp = lua_clock(); + g->gcmetrics.currcycle.endtotalsizebytes = g->totalbytes; + + g->gcmetrics.completedcycles++; + g->gcmetrics.lastcycle = g->gcmetrics.currcycle; + g->gcmetrics.currcycle = GCCycleMetrics(); + + g->gcmetrics.currcycle.starttotalsizebytes = g->totalbytes; + g->gcmetrics.currcycle.heaptriggersizebytes = g->GCthreshold; +} +#endif + +static void removeentry(LuaNode* n) +{ + LUAU_ASSERT(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); // dead key; remove it +} + +static void reallymarkobject(global_State* g, GCObject* o) +{ + LUAU_ASSERT(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) + { + case LUA_TSTRING: + { + return; + } + case LUA_TUSERDATA: + { + LuaTable* mt = gco2u(o)->metatable; + gray2black(o); // udata are never gray + if (mt) + markobject(g, mt); + return; + } + case LUA_TUPVAL: + { + UpVal* uv = gco2uv(o); + markvalue(g, uv->v); + if (!upisopen(uv)) // closed? + gray2black(o); // open upvalues are never black + return; + } + case LUA_TFUNCTION: + { + gco2cl(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: + { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: + { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TBUFFER: + { + gray2black(o); // buffers are never gray + return; + } + case LUA_TPROTO: + { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: + LUAU_ASSERT(0); + } +} + +static const char* gettablemode(global_State* g, LuaTable* h) +{ + const TValue* mode = gfasttm(g, h->metatable, TM_MODE); + + if (mode && ttisstring(mode)) + return svalue(mode); + + return NULL; +} + +static int traversetable(global_State* g, LuaTable* h) +{ + int i; + int weakkey = 0; + int weakvalue = 0; + if (h->metatable) + markobject(g, cast_to(LuaTable*, h->metatable)); + + // is there a weak mode? + if (const char* modev = gettablemode(g, h)) + { + weakkey = (strchr(modev, 'k') != NULL); + weakvalue = (strchr(modev, 'v') != NULL); + if (weakkey || weakvalue) + { // is really weak? + h->gclist = g->weak; // must be cleared after GC, ... + g->weak = obj2gco(h); // ... so put in the appropriate list + } + } + + if (weakkey && weakvalue) + return 1; + if (!weakvalue) + { + i = h->sizearray; + while (i--) + markvalue(g, &h->array[i]); + } + i = sizenode(h); + while (i--) + { + LuaNode* n = gnode(h, i); + LUAU_ASSERT(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); // remove empty entries + else + { + LUAU_ASSERT(!ttisnil(gkey(n))); + if (!weakkey) + markvalue(g, gkey(n)); + if (!weakvalue) + markvalue(g, gval(n)); + } + } + return weakkey || weakvalue; +} + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void traverseproto(global_State* g, Proto* f) +{ + int i; + if (f->source) + stringmark(f->source); + if (f->debugname) + stringmark(f->debugname); + for (i = 0; i < f->sizek; i++) // mark literals + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) + { // mark upvalue names + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i = 0; i < f->sizep; i++) + { // mark nested protos + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i = 0; i < f->sizelocvars; i++) + { // mark local-variable names + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); + } +} + +static void traverseclosure(global_State* g, Closure* cl) +{ + markobject(g, cl->env); + if (cl->isC) + { + int i; + for (i = 0; i < cl->nupvalues; i++) // mark its upvalues + markvalue(g, &cl->c.upvals[i]); + } + else + { + int i; + LUAU_ASSERT(cl->nupvalues == cl->l.p->nups); + markobject(g, cast_to(Proto*, cl->l.p)); + for (i = 0; i < cl->nupvalues; i++) // mark its upvalues + markvalue(g, &cl->l.uprefs[i]); + } +} + +static void traversestack(global_State* g, lua_State* l) +{ + markobject(g, l->gt); + if (l->namecall) + stringmark(l->namecall); + for (StkId o = l->stack; o < l->top; o++) + markvalue(g, o); + for (UpVal* uv = l->openupval; uv; uv = uv->u.open.threadnext) + { + LUAU_ASSERT(upisopen(uv)); + uv->markedopen = 1; + markobject(g, uv); + } +} + +static void clearstack(lua_State* l) +{ + StkId stack_end = l->stack + l->stacksize; + for (StkId o = l->top; o < stack_end; o++) // clear not-marked stack slice + setnilvalue(o); +} + +static void shrinkstack(lua_State* L) +{ + // compute used stack - note that we can't use th->top if we're in the middle of vararg call + StkId lim = L->top; + for (CallInfo* ci = L->base_ci; ci <= L->ci; ci++) + { + LUAU_ASSERT(ci->top <= L->stack_last); + if (lim < ci->top) + lim = ci->top; + } + + // shrink stack and callinfo arrays if we aren't using most of the space + int ci_used = cast_int(L->ci - L->base_ci); // number of `ci' in use + int s_used = cast_int(lim - L->stack); // part of stack in use + if (L->size_ci > LUAI_MAXCALLS) // handling overflow? + return; // do not touch the stacks + + if (3 * size_t(ci_used) < size_t(L->size_ci) && 2 * BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci / 2); // still big enough... + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + + if (3 * size_t(s_used) < size_t(L->stacksize) && 2 * (BASIC_STACK_SIZE + EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize / 2, 0); // still big enough... + condhardstacktests(luaD_reallocstack(L, s_used, 0)); +} + +static void shrinkstackprotected(lua_State* L) +{ + struct CallContext + { + static void run(lua_State* L, void* ud) + { + shrinkstack(L); + } + } ctx = {}; + + // the resize call can fail on exception, in which case we will continue with original size + int status = luaD_rawrunprotected(L, &CallContext::run, &ctx); + LUAU_ASSERT(status == LUA_OK || status == LUA_ERRMEM); +} + +/* +** traverse one gray object, turning it to black. +** Returns `quantity' traversed. +*/ +static size_t propagatemark(global_State* g) +{ + GCObject* o = g->gray; + LUAU_ASSERT(isgray(o)); + gray2black(o); + switch (o->gch.tt) + { + case LUA_TTABLE: + { + LuaTable* h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) // table is weak? + black2gray(o); // keep it gray + return sizeof(LuaTable) + sizeof(TValue) * h->sizearray + sizeof(LuaNode) * sizenode(h); + } + case LUA_TFUNCTION: + { + Closure* cl = gco2cl(o); + g->gray = cl->gclist; + traverseclosure(g, cl); + return cl->isC ? sizeCclosure(cl->nupvalues) : sizeLclosure(cl->nupvalues); + } + case LUA_TTHREAD: + { + lua_State* th = gco2th(o); + g->gray = th->gclist; + + bool active = th->isactive || th == th->global->mainthread; + + traversestack(g, th); + + // active threads will need to be rescanned later to mark new stack writes so we mark them gray again + if (active) + { + th->gclist = g->grayagain; + g->grayagain = o; + + black2gray(o); + } + + // the stack needs to be cleared after the last modification of the thread state before sweep begins + // if the thread is inactive, we might not see the thread in this cycle so we must clear it now + if (!active || g->gcstate == GCSatomic) + clearstack(th); + + // we could shrink stack at any time but we opt to do it during initial mark to do that just once per cycle + if (g->gcstate == GCSpropagate) + shrinkstackprotected(th); + + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: + { + Proto* p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto*) * p->sizep + sizeof(TValue) * p->sizek + p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + sizeof(TString*) * p->sizeupvalues + p->sizetypeinfo; + } + default: + LUAU_ASSERT(0); + return 0; + } +} + +static size_t propagateall(global_State* g) +{ + size_t work = 0; + while (g->gray) + { + work += propagatemark(g); + } + return work; +} + +/* +** The next function tells whether a key or value can be cleared from +** a weak table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them. +*/ +static int isobjcleared(GCObject* o) +{ + if (o->gch.tt == LUA_TSTRING) + { + stringmark(&o->ts); // strings are `values', so are never weak + return 0; + } + + return iswhite(o); +} + +#define iscleared(o) (iscollectable(o) && isobjcleared(gcvalue(o))) + +static void tableresizeprotected(lua_State* L, LuaTable* t, int nhsize) +{ + struct CallContext + { + LuaTable* t; + int nhsize; + + static void run(lua_State* L, void* ud) + { + CallContext* ctx = (CallContext*)ud; + + luaH_resizehash(L, ctx->t, ctx->nhsize); + } + } ctx = {t, nhsize}; + + // the resize call can fail on exception, in which case we will continue with original size + int status = luaD_rawrunprotected(L, &CallContext::run, &ctx); + LUAU_ASSERT(status == LUA_OK || status == LUA_ERRMEM); +} + +/* +** clear collected entries from weaktables +*/ +static size_t cleartable(lua_State* L, GCObject* l) +{ + size_t work = 0; + while (l) + { + LuaTable* h = gco2h(l); + work += sizeof(LuaTable) + sizeof(TValue) * h->sizearray + sizeof(LuaNode) * sizenode(h); + + int i = h->sizearray; + while (i--) + { + TValue* o = &h->array[i]; + if (iscleared(o)) // value was collected? + setnilvalue(o); // remove value + } + i = sizenode(h); + int activevalues = 0; + while (i--) + { + LuaNode* n = gnode(h, i); + + // non-empty entry? + if (!ttisnil(gval(n))) + { + // can we clear key or value? + if (iscleared(gkey(n)) || iscleared(gval(n))) + { + setnilvalue(gval(n)); // remove value ... + removeentry(n); // remove entry from table + } + else + { + activevalues++; + } + } + } + + if (const char* modev = gettablemode(L->global, h)) + { + // are we allowed to shrink this weak table? + if (strchr(modev, 's')) + { + // shrink at 37.5% occupancy + if (activevalues < sizenode(h) * 3 / 8) + tableresizeprotected(L, h, activevalues); + } + } + + l = h->gclist; + } + return work; +} + +static void freeobj(lua_State* L, GCObject* o, lua_Page* page) +{ + switch (o->gch.tt) + { + case LUA_TPROTO: + luaF_freeproto(L, gco2p(o), page); + break; + case LUA_TFUNCTION: + luaF_freeclosure(L, gco2cl(o), page); + break; + case LUA_TUPVAL: + luaF_freeupval(L, gco2uv(o), page); + break; + case LUA_TTABLE: + luaH_free(L, gco2h(o), page); + break; + case LUA_TTHREAD: + LUAU_ASSERT(gco2th(o) != L && gco2th(o) != L->global->mainthread); + luaE_freethread(L, gco2th(o), page); + break; + case LUA_TSTRING: + luaS_free(L, gco2ts(o), page); + break; + case LUA_TUSERDATA: + luaU_freeudata(L, gco2u(o), page); + break; + case LUA_TBUFFER: + luaB_freebuffer(L, gco2buf(o), page); + break; + default: + LUAU_ASSERT(0); + } +} + +static void stringresizeprotected(lua_State* L, int newsize) +{ + struct CallContext + { + int newsize; + + static void run(lua_State* L, void* ud) + { + CallContext* ctx = (CallContext*)ud; + + luaS_resize(L, ctx->newsize); + } + } ctx = {newsize}; + + // the resize call can fail on exception, in which case we will continue with original size + int status = luaD_rawrunprotected(L, &CallContext::run, &ctx); + LUAU_ASSERT(status == LUA_OK || status == LUA_ERRMEM); +} + +static void shrinkbuffers(lua_State* L) +{ + global_State* g = L->global; + // check size of string hash + if (g->strt.nuse < cast_to(uint32_t, g->strt.size / 4) && g->strt.size > LUA_MINSTRTABSIZE * 2) + stringresizeprotected(L, g->strt.size / 2); // table is too big +} + +static void shrinkbuffersfull(lua_State* L) +{ + global_State* g = L->global; + // check size of string hash + int hashsize = g->strt.size; + while (g->strt.nuse < cast_to(uint32_t, hashsize / 4) && hashsize > LUA_MINSTRTABSIZE * 2) + hashsize /= 2; + if (hashsize != g->strt.size) + stringresizeprotected(L, hashsize); // table is too big +} + +static bool deletegco(void* context, lua_Page* page, GCObject* gco) +{ + lua_State* L = (lua_State*)context; + freeobj(L, gco, page); + return true; +} + +void luaC_freeall(lua_State* L) +{ + global_State* g = L->global; + + LUAU_ASSERT(L == g->mainthread); + + luaM_visitgco(L, L, deletegco); + + for (int i = 0; i < g->strt.size; i++) // free all string lists + LUAU_ASSERT(g->strt.hash[i] == NULL); + + LUAU_ASSERT(L->global->strt.nuse == 0); +} + +static void markmt(global_State* g) +{ + int i; + for (i = 0; i < LUA_T_COUNT; i++) + if (g->mt[i]) + markobject(g, g->mt[i]); +} + +// mark root set +static void markroot(lua_State* L) +{ + global_State* g = L->global; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + // make global table be traversed before main stack + markobject(g, g->mainthread->gt); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + +static size_t remarkupvals(global_State* g) +{ + size_t work = 0; + + for (UpVal* uv = g->uvhead.u.open.next; uv != &g->uvhead; uv = uv->u.open.next) + { + work += sizeof(UpVal); + + LUAU_ASSERT(upisopen(uv)); + LUAU_ASSERT(uv->u.open.next->u.open.prev == uv && uv->u.open.prev->u.open.next == uv); + LUAU_ASSERT(!isblack(obj2gco(uv))); // open upvalues are never black + + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } + + return work; +} + +static size_t clearupvals(lua_State* L) +{ + global_State* g = L->global; + + size_t work = 0; + + for (UpVal* uv = g->uvhead.u.open.next; uv != &g->uvhead;) + { + work += sizeof(UpVal); + + LUAU_ASSERT(upisopen(uv)); + LUAU_ASSERT(uv->u.open.next->u.open.prev == uv && uv->u.open.prev->u.open.next == uv); + LUAU_ASSERT(!isblack(obj2gco(uv))); // open upvalues are never black + LUAU_ASSERT(iswhite(obj2gco(uv)) || !iscollectable(uv->v) || !iswhite(gcvalue(uv->v))); + + if (uv->markedopen) + { + // upvalue is still open (belongs to alive thread) + LUAU_ASSERT(isgray(obj2gco(uv))); + uv->markedopen = 0; // for next cycle + uv = uv->u.open.next; + } + else + { + // upvalue is either dead, or alive but the thread is dead; unlink and close + UpVal* next = uv->u.open.next; + luaF_closeupval(L, uv, /* dead= */ iswhite(obj2gco(uv))); + uv = next; + } + } + + return work; +} + +static size_t atomic(lua_State* L) +{ + global_State* g = L->global; + LUAU_ASSERT(g->gcstate == GCSatomic); + + size_t work = 0; + +#ifdef LUAI_GCMETRICS + double currts = lua_clock(); +#endif + + // remark occasional upvalues of (maybe) dead threads + work += remarkupvals(g); + // traverse objects caught by write barrier and by 'remarkupvals' + work += propagateall(g); + +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.atomictimeupval += recordGcDeltaTime(currts); +#endif + + // remark weak tables + g->gray = g->weak; + g->weak = NULL; + LUAU_ASSERT(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); // mark running thread + markmt(g); // mark basic metatables (again) + work += propagateall(g); + +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.atomictimeweak += recordGcDeltaTime(currts); +#endif + + // remark gray again + g->gray = g->grayagain; + g->grayagain = NULL; + work += propagateall(g); + +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.atomictimegray += recordGcDeltaTime(currts); +#endif + + // remove collected objects from weak tables + work += cleartable(L, g->weak); + g->weak = NULL; + +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.atomictimeclear += recordGcDeltaTime(currts); +#endif + + // close orphaned live upvalues of dead threads and clear dead upvalues + work += clearupvals(L); + +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.atomictimeupval += recordGcDeltaTime(currts); +#endif + + // flip current white + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepgcopage = g->allgcopages; + g->gcstate = GCSsweep; + + return work; +} + +// a version of generic luaM_visitpage specialized for the main sweep stage +static int sweepgcopage(lua_State* L, lua_Page* page) +{ + char* start; + char* end; + int busyBlocks; + int blockSize; + luaM_getpagewalkinfo(page, &start, &end, &busyBlocks, &blockSize); + + LUAU_ASSERT(busyBlocks > 0); + + global_State* g = L->global; + + int deadmask = otherwhite(g); + LUAU_ASSERT(testbit(deadmask, FIXEDBIT)); // make sure we never sweep fixed objects + + int newwhite = luaC_white(g); + + for (char* pos = start; pos != end; pos += blockSize) + { + GCObject* gco = (GCObject*)pos; + + // skip memory blocks that are already freed + if (gco->gch.tt == LUA_TNIL) + continue; + + // is the object alive? + if ((gco->gch.marked ^ WHITEBITS) & deadmask) + { + LUAU_ASSERT(!isdead(g, gco)); + // make it white (for next cycle) + gco->gch.marked = cast_byte((gco->gch.marked & maskmarks) | newwhite); + } + else + { + LUAU_ASSERT(isdead(g, gco)); + freeobj(L, gco, page); + + // if the last block was removed, page would be removed as well + if (--busyBlocks == 0) + return int(pos - start) / blockSize + 1; + } + } + + return int(end - start) / blockSize; +} + +static size_t gcstep(lua_State* L, size_t limit) +{ + size_t cost = 0; + global_State* g = L->global; + switch (g->gcstate) + { + case GCSpause: + { + markroot(L); // start a new collection + LUAU_ASSERT(g->gcstate == GCSpropagate); + break; + } + case GCSpropagate: + { + while (g->gray && cost < limit) + { + cost += propagatemark(g); + } + + if (!g->gray) + { +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.propagatework = g->gcmetrics.currcycle.explicitwork + g->gcmetrics.currcycle.assistwork; +#endif + + // perform one iteration over 'gray again' list + g->gray = g->grayagain; + g->grayagain = NULL; + + g->gcstate = GCSpropagateagain; + } + break; + } + case GCSpropagateagain: + { + while (g->gray && cost < limit) + { + cost += propagatemark(g); + } + + if (!g->gray) // no more `gray' objects + { +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.propagateagainwork = + g->gcmetrics.currcycle.explicitwork + g->gcmetrics.currcycle.assistwork - g->gcmetrics.currcycle.propagatework; +#endif + + g->gcstate = GCSatomic; + } + break; + } + case GCSatomic: + { +#ifdef LUAI_GCMETRICS + g->gcmetrics.currcycle.atomicstarttimestamp = lua_clock(); + g->gcmetrics.currcycle.atomicstarttotalsizebytes = g->totalbytes; +#endif + + g->gcstats.atomicstarttimestamp = lua_clock(); + g->gcstats.atomicstarttotalsizebytes = g->totalbytes; + + cost = atomic(L); // finish mark phase + + LUAU_ASSERT(g->gcstate == GCSsweep); + break; + } + case GCSsweep: + { + while (g->sweepgcopage && cost < limit) + { + lua_Page* next = luaM_getnextpage(g->sweepgcopage); // page sweep might destroy the page + + int steps = sweepgcopage(L, g->sweepgcopage); + + g->sweepgcopage = next; + cost += steps * GC_SWEEPPAGESTEPCOST; + } + + // nothing more to sweep? + if (g->sweepgcopage == NULL) + { + // don't forget to visit main thread, it's the only object not allocated in GCO pages + LUAU_ASSERT(!isdead(g, obj2gco(g->mainthread))); + makewhite(g, obj2gco(g->mainthread)); // make it white (for next cycle) + + shrinkbuffers(L); + + g->gcstate = GCSpause; // end collection + } + break; + } + default: + LUAU_ASSERT(!"Unexpected GC state"); + } + return cost; +} + +static int64_t getheaptriggererroroffset(global_State* g) +{ + // adjust for error using Proportional-Integral controller + // https://en.wikipedia.org/wiki/PID_controller + int32_t errorKb = int32_t((g->gcstats.atomicstarttotalsizebytes - g->gcstats.heapgoalsizebytes) / 1024); + + // we use sliding window for the error integral to avoid error sum 'windup' when the desired target cannot be reached + const size_t triggertermcount = sizeof(g->gcstats.triggerterms) / sizeof(g->gcstats.triggerterms[0]); + + int32_t* slot = &g->gcstats.triggerterms[g->gcstats.triggertermpos % triggertermcount]; + int32_t prev = *slot; + *slot = errorKb; + g->gcstats.triggerintegral += errorKb - prev; + g->gcstats.triggertermpos++; + + // controller tuning + // https://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method + const double Ku = 0.9; // ultimate gain (measured) + const double Tu = 2.5; // oscillation period (measured) + + const double Kp = 0.45 * Ku; // proportional gain + const double Ti = 0.8 * Tu; + const double Ki = 0.54 * Ku / Ti; // integral gain + + double proportionalTerm = Kp * errorKb; + double integralTerm = Ki * g->gcstats.triggerintegral; + + double totalTerm = proportionalTerm + integralTerm; + + return int64_t(totalTerm * 1024); +} + +static size_t getheaptrigger(global_State* g, size_t heapgoal) +{ + // adjust threshold based on a guess of how many bytes will be allocated between the cycle start and sweep phase + // our goal is to begin the sweep when used memory has reached the heap goal + const double durationthreshold = 1e-3; + double allocationduration = g->gcstats.atomicstarttimestamp - g->gcstats.endtimestamp; + + // avoid measuring intervals smaller than 1ms + if (allocationduration < durationthreshold) + return heapgoal; + + double allocationrate = (g->gcstats.atomicstarttotalsizebytes - g->gcstats.endtotalsizebytes) / allocationduration; + double markduration = g->gcstats.atomicstarttimestamp - g->gcstats.starttimestamp; + + int64_t expectedgrowth = int64_t(markduration * allocationrate); + int64_t offset = getheaptriggererroroffset(g); + int64_t heaptrigger = heapgoal - (expectedgrowth + offset); + + // clamp the trigger between memory use at the end of the cycle and the heap goal + return heaptrigger < int64_t(g->totalbytes) ? g->totalbytes : (heaptrigger > int64_t(heapgoal) ? heapgoal : size_t(heaptrigger)); +} + +size_t luaC_step(lua_State* L, bool assist) +{ + global_State* g = L->global; + + int lim = g->gcstepsize * g->gcstepmul / 100; // how much to work + LUAU_ASSERT(g->totalbytes >= g->GCthreshold); + size_t debt = g->totalbytes - g->GCthreshold; + + GC_INTERRUPT(0); + + // at the start of the new cycle + if (g->gcstate == GCSpause) + g->gcstats.starttimestamp = lua_clock(); + +#ifdef LUAI_GCMETRICS + if (g->gcstate == GCSpause) + startGcCycleMetrics(g); + + double lasttimestamp = lua_clock(); +#endif + + int lastgcstate = g->gcstate; + + size_t work = gcstep(L, lim); + +#ifdef LUAI_GCMETRICS + recordGcStateStep(g, lastgcstate, lua_clock() - lasttimestamp, assist, work); +#endif + + size_t actualstepsize = work * 100 / g->gcstepmul; + + // at the end of the last cycle + if (g->gcstate == GCSpause) + { + // at the end of a collection cycle, set goal based on gcgoal setting + size_t heapgoal = (g->totalbytes / 100) * g->gcgoal; + size_t heaptrigger = getheaptrigger(g, heapgoal); + + g->GCthreshold = heaptrigger; + + g->gcstats.heapgoalsizebytes = heapgoal; + g->gcstats.endtimestamp = lua_clock(); + g->gcstats.endtotalsizebytes = g->totalbytes; + +#ifdef LUAI_GCMETRICS + finishGcCycleMetrics(g); +#endif + } + else + { + g->GCthreshold = g->totalbytes + actualstepsize; + + // compensate if GC is "behind schedule" (has some debt to pay) + if (g->GCthreshold >= debt) + g->GCthreshold -= debt; + } + + GC_INTERRUPT(lastgcstate); + + return actualstepsize; +} + +void luaC_fullgc(lua_State* L) +{ + global_State* g = L->global; + +#ifdef LUAI_GCMETRICS + if (g->gcstate == GCSpause) + startGcCycleMetrics(g); +#endif + + if (keepinvariant(g)) + { + // reset sweep marks to sweep all elements (returning them to white) + g->sweepgcopage = g->allgcopages; + // reset other collector lists + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweep; + } + LUAU_ASSERT(g->gcstate == GCSpause || g->gcstate == GCSsweep); + // finish any pending sweep phase + while (g->gcstate != GCSpause) + { + LUAU_ASSERT(g->gcstate == GCSsweep); + gcstep(L, SIZE_MAX); + } + + // clear markedopen bits for all open upvalues; these might be stuck from half-finished mark prior to full gc + for (UpVal* uv = g->uvhead.u.open.next; uv != &g->uvhead; uv = uv->u.open.next) + { + LUAU_ASSERT(upisopen(uv)); + uv->markedopen = 0; + } + +#ifdef LUAI_GCMETRICS + finishGcCycleMetrics(g); + startGcCycleMetrics(g); +#endif + + // run a full collection cycle + markroot(L); + while (g->gcstate != GCSpause) + { + gcstep(L, SIZE_MAX); + } + // reclaim as much buffer memory as possible (shrinkbuffers() called during sweep is incremental) + shrinkbuffersfull(L); + + size_t heapgoalsizebytes = (g->totalbytes / 100) * g->gcgoal; + + // trigger cannot be correctly adjusted after a forced full GC. + // we will try to place it so that we can reach the goal based on + // the rate at which we run the GC relative to allocation rate + // and on amount of bytes we need to traverse in propagation stage. + // goal and stepmul are defined in percents + g->GCthreshold = g->totalbytes * (g->gcgoal * g->gcstepmul / 100 - 100) / g->gcstepmul; + + // but it might be impossible to satisfy that directly + if (g->GCthreshold < g->totalbytes) + g->GCthreshold = g->totalbytes; + + g->gcstats.heapgoalsizebytes = heapgoalsizebytes; + +#ifdef LUAI_GCMETRICS + finishGcCycleMetrics(g); +#endif +} + +void luaC_barrierf(lua_State* L, GCObject* o, GCObject* v) +{ + global_State* g = L->global; + LUAU_ASSERT(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + LUAU_ASSERT(g->gcstate != GCSpause); + // must keep invariant? + if (keepinvariant(g)) + reallymarkobject(g, v); // restore invariant + else // don't mind + makewhite(g, o); // mark as white just to avoid other barriers +} + +void luaC_barriertable(lua_State* L, LuaTable* t, GCObject* v) +{ + global_State* g = L->global; + GCObject* o = obj2gco(t); + + // in the second propagation stage, table assignment barrier works as a forward barrier + if (g->gcstate == GCSpropagateagain) + { + LUAU_ASSERT(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + reallymarkobject(g, v); + return; + } + + LUAU_ASSERT(isblack(o) && !isdead(g, o)); + LUAU_ASSERT(g->gcstate != GCSpause); + black2gray(o); // make table gray (again) + t->gclist = g->grayagain; + g->grayagain = o; +} + +void luaC_barrierback(lua_State* L, GCObject* o, GCObject** gclist) +{ + global_State* g = L->global; + LUAU_ASSERT(isblack(o) && !isdead(g, o)); + LUAU_ASSERT(g->gcstate != GCSpause); + + black2gray(o); // make object gray (again) + *gclist = g->grayagain; + g->grayagain = o; +} + +void luaC_upvalclosed(lua_State* L, UpVal* uv) +{ + global_State* g = L->global; + GCObject* o = obj2gco(uv); + + LUAU_ASSERT(!upisopen(uv)); // upvalue was closed but needs GC state fixup + + if (isgray(o)) + { + if (keepinvariant(g)) + { + gray2black(o); // closed upvalues need barrier + luaC_barrier(L, uv, uv->v); + } + else + { // sweep phase: sweep it (turning it into white) + makewhite(g, o); + LUAU_ASSERT(g->gcstate != GCSpause); + } + } +} + +// measure the allocation rate in bytes/sec +// returns -1 if allocation rate cannot be measured +int64_t luaC_allocationrate(lua_State* L) +{ + global_State* g = L->global; + const double durationthreshold = 1e-3; // avoid measuring intervals smaller than 1ms + + if (g->gcstate <= GCSatomic) + { + double duration = lua_clock() - g->gcstats.endtimestamp; + + if (duration < durationthreshold) + return -1; + + return int64_t((g->totalbytes - g->gcstats.endtotalsizebytes) / duration); + } + + // totalbytes is unstable during the sweep, use the rate measured at the end of mark phase + double duration = g->gcstats.atomicstarttimestamp - g->gcstats.endtimestamp; + + if (duration < durationthreshold) + return -1; + + return int64_t((g->gcstats.atomicstarttotalsizebytes - g->gcstats.endtotalsizebytes) / duration); +} + +const char* luaC_statename(int state) +{ + switch (state) + { + case GCSpause: + return "pause"; + + case GCSpropagate: + return "mark"; + + case GCSpropagateagain: + return "remark"; + + case GCSatomic: + return "atomic"; + + case GCSsweep: + return "sweep"; + + default: + return NULL; + } +} diff --git a/thirdparty/luau/upstream/VM/src/lgc.h b/thirdparty/luau/upstream/VM/src/lgc.h new file mode 100644 index 000000000..2500bd38e --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lgc.h @@ -0,0 +1,145 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "ldo.h" +#include "lobject.h" +#include "lstate.h" + +/* +** Default settings for GC tunables (settable via lua_gc) +*/ +#define LUAI_GCGOAL 200 // 200% (allow heap to double compared to live heap size) +#define LUAI_GCSTEPMUL 200 // GC runs 'twice the speed' of memory allocation +#define LUAI_GCSTEPSIZE 1 // GC runs every KB of memory allocation + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSpropagateagain 2 +#define GCSatomic 3 +#define GCSsweep 4 + +/* +** The main invariant of the garbage collector, while marking objects, +** is that a black object can never point to a white one. This invariant +** is not being enforced during a sweep phase, and is restored when sweep +** ends. +*/ +#define keepinvariant(g) ((g)->gcstate == GCSpropagate || (g)->gcstate == GCSpropagateagain || (g)->gcstate == GCSatomic) + +/* +** some useful bit tricks +*/ +#define resetbits(x, m) ((x) &= cast_to(uint8_t, ~(m))) +#define setbits(x, m) ((x) |= (m)) +#define testbits(x, m) ((x) & (m)) +#define bitmask(b) (1 << (b)) +#define bit2mask(b1, b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x, b) setbits(x, bitmask(b)) +#define resetbit(x, b) resetbits(x, bitmask(b)) +#define testbit(x, b) testbits(x, bitmask(b)) +#define set2bits(x, b1, b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x, b1, b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x, b1, b2) testbits(x, (bit2mask(b1, b2))) + +/* +** Layout for bit use in `marked' field: +** bit 0 - object is white (type 0) +** bit 1 - object is white (type 1) +** bit 2 - object is black +** bit 3 - object is fixed (should not be collected) +*/ + +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FIXEDBIT 3 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) +#define isfixed(x) testbit((x)->gch.marked, FIXEDBIT) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g, v) (((v)->gch.marked & (WHITEBITS | bitmask(FIXEDBIT))) == (otherwhite(g) & WHITEBITS)) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define luaC_white(g) cast_to(uint8_t, ((g)->currentwhite) & WHITEBITS) + +#define luaC_needsGC(L) (L->global->totalbytes >= L->global->GCthreshold) + +#define luaC_checkGC(L) \ + { \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK, 0)); \ + if (luaC_needsGC(L)) \ + { \ + condhardmemtests(luaC_validate(L), 1); \ + luaC_step(L, true); \ + } \ + else \ + { \ + condhardmemtests(luaC_validate(L), 2); \ + } \ + } + +#define luaC_barrier(L, p, v) \ + { \ + if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \ + luaC_barrierf(L, obj2gco(p), gcvalue(v)); \ + } + +#define luaC_barriert(L, t, v) \ + { \ + if (iscollectable(v) && isblack(obj2gco(t)) && iswhite(gcvalue(v))) \ + luaC_barriertable(L, t, gcvalue(v)); \ + } + +#define luaC_barrierfast(L, t) \ + { \ + if (isblack(obj2gco(t))) \ + luaC_barrierback(L, obj2gco(t), &t->gclist); \ + } + +#define luaC_objbarrier(L, p, o) \ + { \ + if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \ + luaC_barrierf(L, obj2gco(p), obj2gco(o)); \ + } + +#define luaC_threadbarrier(L) \ + { \ + if (isblack(obj2gco(L))) \ + luaC_barrierback(L, obj2gco(L), &L->gclist); \ + } + +#define luaC_init(L, o, tt_) \ + { \ + o->marked = luaC_white(L->global); \ + o->tt = tt_; \ + o->memcat = L->activememcat; \ + } + +LUAI_FUNC void luaC_freeall(lua_State* L); +LUAI_FUNC size_t luaC_step(lua_State* L, bool assist); +LUAI_FUNC void luaC_fullgc(lua_State* L); +LUAI_FUNC void luaC_initobj(lua_State* L, GCObject* o, uint8_t tt); +LUAI_FUNC void luaC_upvalclosed(lua_State* L, UpVal* uv); +LUAI_FUNC void luaC_barrierf(lua_State* L, GCObject* o, GCObject* v); +LUAI_FUNC void luaC_barriertable(lua_State* L, LuaTable* t, GCObject* v); +LUAI_FUNC void luaC_barrierback(lua_State* L, GCObject* o, GCObject** gclist); +LUAI_FUNC void luaC_validate(lua_State* L); +LUAI_FUNC void luaC_dump(lua_State* L, void* file, const char* (*categoryName)(lua_State* L, uint8_t memcat)); +LUAI_FUNC void luaC_enumheap( + lua_State* L, + void* context, + void (*node)(void* context, void* ptr, uint8_t tt, uint8_t memcat, size_t size, const char* name), + void (*edge)(void* context, void* from, void* to, const char* name) +); +LUAI_FUNC int64_t luaC_allocationrate(lua_State* L); +LUAI_FUNC const char* luaC_statename(int state); diff --git a/thirdparty/luau/upstream/VM/src/lgcdebug.cpp b/thirdparty/luau/upstream/VM/src/lgcdebug.cpp new file mode 100644 index 000000000..f695188f5 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lgcdebug.cpp @@ -0,0 +1,917 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lgc.h" + +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ludata.h" +#include "lbuffer.h" + +#include +#include + +static void validateobjref(global_State* g, GCObject* f, GCObject* t) +{ + LUAU_ASSERT(!isdead(g, t)); + + if (keepinvariant(g)) + { + // basic incremental invariant: black can't point to white + LUAU_ASSERT(!(isblack(f) && iswhite(t))); + } +} + +static void validateref(global_State* g, GCObject* f, TValue* v) +{ + if (iscollectable(v)) + { + LUAU_ASSERT(ttype(v) == gcvalue(v)->gch.tt); + validateobjref(g, f, gcvalue(v)); + } +} + +static void validatetable(global_State* g, LuaTable* h) +{ + int sizenode = 1 << h->lsizenode; + + LUAU_ASSERT(h->lastfree <= sizenode); + + if (h->metatable) + validateobjref(g, obj2gco(h), obj2gco(h->metatable)); + + for (int i = 0; i < h->sizearray; ++i) + validateref(g, obj2gco(h), &h->array[i]); + + for (int i = 0; i < sizenode; ++i) + { + LuaNode* n = &h->node[i]; + + LUAU_ASSERT(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + LUAU_ASSERT(i + gnext(n) >= 0 && i + gnext(n) < sizenode); + + if (!ttisnil(gval(n))) + { + TValue k = {}; + k.tt = gkey(n)->tt; + k.value = gkey(n)->value; + + validateref(g, obj2gco(h), &k); + validateref(g, obj2gco(h), gval(n)); + } + } +} + +static void validateclosure(global_State* g, Closure* cl) +{ + validateobjref(g, obj2gco(cl), obj2gco(cl->env)); + + if (cl->isC) + { + for (int i = 0; i < cl->nupvalues; ++i) + validateref(g, obj2gco(cl), &cl->c.upvals[i]); + } + else + { + LUAU_ASSERT(cl->nupvalues == cl->l.p->nups); + + validateobjref(g, obj2gco(cl), obj2gco(cl->l.p)); + + for (int i = 0; i < cl->nupvalues; ++i) + validateref(g, obj2gco(cl), &cl->l.uprefs[i]); + } +} + +static void validatestack(global_State* g, lua_State* l) +{ + validateobjref(g, obj2gco(l), obj2gco(l->gt)); + + for (CallInfo* ci = l->base_ci; ci <= l->ci; ++ci) + { + LUAU_ASSERT(l->stack <= ci->base); + LUAU_ASSERT(ci->func <= ci->base && ci->base <= ci->top); + LUAU_ASSERT(ci->top <= l->stack_last); + } + + // note: stack refs can violate gc invariant so we only check for liveness + for (StkId o = l->stack; o < l->top; ++o) + checkliveness(g, o); + + if (l->namecall) + validateobjref(g, obj2gco(l), obj2gco(l->namecall)); + + for (UpVal* uv = l->openupval; uv; uv = uv->u.open.threadnext) + { + LUAU_ASSERT(uv->tt == LUA_TUPVAL); + LUAU_ASSERT(upisopen(uv)); + LUAU_ASSERT(uv->u.open.next->u.open.prev == uv && uv->u.open.prev->u.open.next == uv); + LUAU_ASSERT(!isblack(obj2gco(uv))); // open upvalues are never black + } +} + +static void validateproto(global_State* g, Proto* f) +{ + if (f->source) + validateobjref(g, obj2gco(f), obj2gco(f->source)); + + if (f->debugname) + validateobjref(g, obj2gco(f), obj2gco(f->debugname)); + + for (int i = 0; i < f->sizek; ++i) + validateref(g, obj2gco(f), &f->k[i]); + + for (int i = 0; i < f->sizeupvalues; ++i) + if (f->upvalues[i]) + validateobjref(g, obj2gco(f), obj2gco(f->upvalues[i])); + + for (int i = 0; i < f->sizep; ++i) + if (f->p[i]) + validateobjref(g, obj2gco(f), obj2gco(f->p[i])); + + for (int i = 0; i < f->sizelocvars; i++) + if (f->locvars[i].varname) + validateobjref(g, obj2gco(f), obj2gco(f->locvars[i].varname)); +} + +static void validateobj(global_State* g, GCObject* o) +{ + // dead objects can only occur during sweep + if (isdead(g, o)) + { + LUAU_ASSERT(g->gcstate == GCSsweep); + return; + } + + switch (o->gch.tt) + { + case LUA_TSTRING: + break; + + case LUA_TTABLE: + validatetable(g, gco2h(o)); + break; + + case LUA_TFUNCTION: + validateclosure(g, gco2cl(o)); + break; + + case LUA_TUSERDATA: + if (gco2u(o)->metatable) + validateobjref(g, o, obj2gco(gco2u(o)->metatable)); + break; + + case LUA_TTHREAD: + validatestack(g, gco2th(o)); + break; + + case LUA_TBUFFER: + break; + + case LUA_TPROTO: + validateproto(g, gco2p(o)); + break; + + case LUA_TUPVAL: + validateref(g, o, gco2uv(o)->v); + break; + + default: + LUAU_ASSERT(!"unexpected object type"); + } +} + +static void validategraylist(global_State* g, GCObject* o) +{ + if (!keepinvariant(g)) + return; + + while (o) + { + LUAU_ASSERT(isgray(o)); + + switch (o->gch.tt) + { + case LUA_TTABLE: + o = gco2h(o)->gclist; + break; + case LUA_TFUNCTION: + o = gco2cl(o)->gclist; + break; + case LUA_TTHREAD: + o = gco2th(o)->gclist; + break; + case LUA_TPROTO: + o = gco2p(o)->gclist; + break; + default: + LUAU_ASSERT(!"unknown object in gray list"); + return; + } + } +} + +static bool validategco(void* context, lua_Page* page, GCObject* gco) +{ + lua_State* L = (lua_State*)context; + global_State* g = L->global; + + validateobj(g, gco); + return false; +} + +void luaC_validate(lua_State* L) +{ + global_State* g = L->global; + + LUAU_ASSERT(!isdead(g, obj2gco(g->mainthread))); + checkliveness(g, &g->registry); + + for (int i = 0; i < LUA_T_COUNT; ++i) + if (g->mt[i]) + LUAU_ASSERT(!isdead(g, obj2gco(g->mt[i]))); + + validategraylist(g, g->weak); + validategraylist(g, g->gray); + validategraylist(g, g->grayagain); + + validategco(L, NULL, obj2gco(g->mainthread)); + + luaM_visitgco(L, L, validategco); + + for (UpVal* uv = g->uvhead.u.open.next; uv != &g->uvhead; uv = uv->u.open.next) + { + LUAU_ASSERT(uv->tt == LUA_TUPVAL); + LUAU_ASSERT(upisopen(uv)); + LUAU_ASSERT(uv->u.open.next->u.open.prev == uv && uv->u.open.prev->u.open.next == uv); + LUAU_ASSERT(!isblack(obj2gco(uv))); // open upvalues are never black + } +} + +inline bool safejson(char ch) +{ + return unsigned(ch) < 128 && ch >= 32 && ch != '\\' && ch != '\"'; +} + +static void dumpref(FILE* f, GCObject* o) +{ + fprintf(f, "\"%p\"", o); +} + +static void dumprefs(FILE* f, TValue* data, size_t size) +{ + bool first = true; + + for (size_t i = 0; i < size; ++i) + { + if (iscollectable(&data[i])) + { + if (!first) + fputc(',', f); + first = false; + + dumpref(f, gcvalue(&data[i])); + } + } +} + +static void dumpstringdata(FILE* f, const char* data, size_t len) +{ + for (size_t i = 0; i < len; ++i) + fputc(safejson(data[i]) ? data[i] : '?', f); +} + +static void dumpstring(FILE* f, TString* ts) +{ + fprintf(f, "{\"type\":\"string\",\"cat\":%d,\"size\":%d,\"data\":\"", ts->memcat, int(sizestring(ts->len))); + dumpstringdata(f, ts->data, ts->len); + fprintf(f, "\"}"); +} + +static void dumptable(FILE* f, LuaTable* h) +{ + size_t size = sizeof(LuaTable) + (h->node == &luaH_dummynode ? 0 : sizenode(h) * sizeof(LuaNode)) + h->sizearray * sizeof(TValue); + + fprintf(f, "{\"type\":\"table\",\"cat\":%d,\"size\":%d", h->memcat, int(size)); + + if (h->node != &luaH_dummynode) + { + fprintf(f, ",\"pairs\":["); + + bool first = true; + + for (int i = 0; i < sizenode(h); ++i) + { + const LuaNode& n = h->node[i]; + + if (!ttisnil(&n.val) && (iscollectable(&n.key) || iscollectable(&n.val))) + { + if (!first) + fputc(',', f); + first = false; + + if (iscollectable(&n.key)) + dumpref(f, gcvalue(&n.key)); + else + fprintf(f, "null"); + + fputc(',', f); + + if (iscollectable(&n.val)) + dumpref(f, gcvalue(&n.val)); + else + fprintf(f, "null"); + } + } + + fprintf(f, "]"); + } + if (h->sizearray) + { + fprintf(f, ",\"array\":["); + dumprefs(f, h->array, h->sizearray); + fprintf(f, "]"); + } + if (h->metatable) + { + fprintf(f, ",\"metatable\":"); + dumpref(f, obj2gco(h->metatable)); + } + fprintf(f, "}"); +} + +static void dumpclosure(FILE* f, Closure* cl) +{ + fprintf( + f, "{\"type\":\"function\",\"cat\":%d,\"size\":%d", cl->memcat, cl->isC ? int(sizeCclosure(cl->nupvalues)) : int(sizeLclosure(cl->nupvalues)) + ); + + fprintf(f, ",\"env\":"); + dumpref(f, obj2gco(cl->env)); + + if (cl->isC) + { + if (cl->c.debugname) + fprintf(f, ",\"name\":\"%s\"", cl->c.debugname + 0); + + if (cl->nupvalues) + { + fprintf(f, ",\"upvalues\":["); + dumprefs(f, cl->c.upvals, cl->nupvalues); + fprintf(f, "]"); + } + } + else + { + if (cl->l.p->debugname) + fprintf(f, ",\"name\":\"%s\"", getstr(cl->l.p->debugname)); + + fprintf(f, ",\"proto\":"); + dumpref(f, obj2gco(cl->l.p)); + if (cl->nupvalues) + { + fprintf(f, ",\"upvalues\":["); + dumprefs(f, cl->l.uprefs, cl->nupvalues); + fprintf(f, "]"); + } + } + fprintf(f, "}"); +} + +static void dumpudata(FILE* f, Udata* u) +{ + fprintf(f, "{\"type\":\"userdata\",\"cat\":%d,\"size\":%d,\"tag\":%d", u->memcat, int(sizeudata(u->len)), u->tag); + + if (u->metatable) + { + fprintf(f, ",\"metatable\":"); + dumpref(f, obj2gco(u->metatable)); + } + fprintf(f, "}"); +} + +static void dumpthread(FILE* f, lua_State* th) +{ + size_t size = sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci; + + fprintf(f, "{\"type\":\"thread\",\"cat\":%d,\"size\":%d", th->memcat, int(size)); + + fprintf(f, ",\"env\":"); + dumpref(f, obj2gco(th->gt)); + + Closure* tcl = 0; + for (CallInfo* ci = th->base_ci; ci <= th->ci; ++ci) + { + if (ttisfunction(ci->func)) + { + tcl = clvalue(ci->func); + break; + } + } + + if (tcl && !tcl->isC && tcl->l.p->source) + { + Proto* p = tcl->l.p; + + fprintf(f, ",\"source\":\""); + dumpstringdata(f, p->source->data, p->source->len); + fprintf(f, "\",\"line\":%d", p->linedefined); + } + + if (th->top > th->stack) + { + fprintf(f, ",\"stack\":["); + dumprefs(f, th->stack, th->top - th->stack); + fprintf(f, "]"); + + CallInfo* ci = th->base_ci; + bool first = true; + + fprintf(f, ",\"stacknames\":["); + for (StkId v = th->stack; v < th->top; ++v) + { + if (!iscollectable(v)) + continue; + + while (ci < th->ci && v >= (ci + 1)->func) + ci++; + + if (!first) + fputc(',', f); + first = false; + + if (v == ci->func) + { + Closure* cl = ci_func(ci); + + if (cl->isC) + { + fprintf(f, "\"frame:%s\"", cl->c.debugname ? cl->c.debugname : "[C]"); + } + else + { + Proto* p = cl->l.p; + fprintf(f, "\"frame:"); + if (p->source) + dumpstringdata(f, p->source->data, p->source->len); + fprintf(f, ":%d:%s\"", p->linedefined, p->debugname ? getstr(p->debugname) : ""); + } + } + else if (isLua(ci)) + { + Proto* p = ci_func(ci)->l.p; + int pc = pcRel(ci->savedpc, p); + const LocVar* var = luaF_findlocal(p, int(v - ci->base), pc); + + if (var && var->varname) + fprintf(f, "\"%s\"", getstr(var->varname)); + else + fprintf(f, "null"); + } + else + fprintf(f, "null"); + } + fprintf(f, "]"); + } + fprintf(f, "}"); +} + +static void dumpbuffer(FILE* f, Buffer* b) +{ + fprintf(f, "{\"type\":\"buffer\",\"cat\":%d,\"size\":%d}", b->memcat, int(sizebuffer(b->len))); +} + +static void dumpproto(FILE* f, Proto* p) +{ + size_t size = sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto*) * p->sizep + sizeof(TValue) * p->sizek + p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + sizeof(TString*) * p->sizeupvalues; + + fprintf(f, "{\"type\":\"proto\",\"cat\":%d,\"size\":%d", p->memcat, int(size)); + + if (p->source) + { + fprintf(f, ",\"source\":\""); + dumpstringdata(f, p->source->data, p->source->len); + fprintf(f, "\",\"line\":%d", p->abslineinfo ? p->abslineinfo[0] : 0); + } + + if (p->sizek) + { + fprintf(f, ",\"constants\":["); + dumprefs(f, p->k, p->sizek); + fprintf(f, "]"); + } + + if (p->sizep) + { + fprintf(f, ",\"protos\":["); + for (int i = 0; i < p->sizep; ++i) + { + if (i != 0) + fputc(',', f); + dumpref(f, obj2gco(p->p[i])); + } + fprintf(f, "]"); + } + + fprintf(f, "}"); +} + +static void dumpupval(FILE* f, UpVal* uv) +{ + fprintf(f, "{\"type\":\"upvalue\",\"cat\":%d,\"size\":%d,\"open\":%s", uv->memcat, int(sizeof(UpVal)), upisopen(uv) ? "true" : "false"); + + if (iscollectable(uv->v)) + { + fprintf(f, ",\"object\":"); + dumpref(f, gcvalue(uv->v)); + } + + fprintf(f, "}"); +} + +static void dumpobj(FILE* f, GCObject* o) +{ + switch (o->gch.tt) + { + case LUA_TSTRING: + return dumpstring(f, gco2ts(o)); + + case LUA_TTABLE: + return dumptable(f, gco2h(o)); + + case LUA_TFUNCTION: + return dumpclosure(f, gco2cl(o)); + + case LUA_TUSERDATA: + return dumpudata(f, gco2u(o)); + + case LUA_TTHREAD: + return dumpthread(f, gco2th(o)); + + case LUA_TBUFFER: + return dumpbuffer(f, gco2buf(o)); + + case LUA_TPROTO: + return dumpproto(f, gco2p(o)); + + case LUA_TUPVAL: + return dumpupval(f, gco2uv(o)); + + default: + LUAU_ASSERT(0); + } +} + +static bool dumpgco(void* context, lua_Page* page, GCObject* gco) +{ + FILE* f = (FILE*)context; + + dumpref(f, gco); + fputc(':', f); + dumpobj(f, gco); + fputc(',', f); + fputc('\n', f); + + return false; +} + +void luaC_dump(lua_State* L, void* file, const char* (*categoryName)(lua_State* L, uint8_t memcat)) +{ + global_State* g = L->global; + FILE* f = static_cast(file); + + fprintf(f, "{\"objects\":{\n"); + + dumpgco(f, NULL, obj2gco(g->mainthread)); + + luaM_visitgco(L, f, dumpgco); + + fprintf(f, "\"0\":{\"type\":\"userdata\",\"cat\":0,\"size\":0}\n"); // to avoid issues with trailing , + fprintf(f, "},\"roots\":{\n"); + fprintf(f, "\"mainthread\":"); + dumpref(f, obj2gco(g->mainthread)); + fprintf(f, ",\"registry\":"); + dumpref(f, gcvalue(&g->registry)); + + fprintf(f, "},\"stats\":{\n"); + + fprintf(f, "\"size\":%d,\n", int(g->totalbytes)); + + fprintf(f, "\"categories\":{\n"); + for (int i = 0; i < LUA_MEMORY_CATEGORIES; i++) + { + if (size_t bytes = g->memcatbytes[i]) + { + if (categoryName) + fprintf(f, "\"%d\":{\"name\":\"%s\", \"size\":%d},\n", i, categoryName(L, i), int(bytes)); + else + fprintf(f, "\"%d\":{\"size\":%d},\n", i, int(bytes)); + } + } + fprintf(f, "\"none\":{}\n"); // to avoid issues with trailing , + fprintf(f, "}\n"); + fprintf(f, "}}\n"); +} + +struct EnumContext +{ + lua_State* L; + void* context; + void (*node)(void* context, void* ptr, uint8_t tt, uint8_t memcat, size_t size, const char* name); + void (*edge)(void* context, void* from, void* to, const char* name); +}; + +static void* enumtopointer(GCObject* gco) +{ + // To match lua_topointer, userdata pointer is represented as a pointer to internal data + return gco->gch.tt == LUA_TUSERDATA ? (void*)gco2u(gco)->data : (void*)gco; +} + +static void enumnode(EnumContext* ctx, GCObject* gco, size_t size, const char* objname) +{ + ctx->node(ctx->context, enumtopointer(gco), gco->gch.tt, gco->gch.memcat, size, objname); +} + +static void enumedge(EnumContext* ctx, GCObject* from, GCObject* to, const char* edgename) +{ + ctx->edge(ctx->context, enumtopointer(from), enumtopointer(to), edgename); +} + +static void enumedges(EnumContext* ctx, GCObject* from, TValue* data, size_t size, const char* edgename) +{ + for (size_t i = 0; i < size; ++i) + { + if (iscollectable(&data[i])) + enumedge(ctx, from, gcvalue(&data[i]), edgename); + } +} + +static void enumstring(EnumContext* ctx, TString* ts) +{ + enumnode(ctx, obj2gco(ts), sizestring(ts->len), NULL); +} + +static void enumtable(EnumContext* ctx, LuaTable* h) +{ + size_t size = sizeof(LuaTable) + (h->node == &luaH_dummynode ? 0 : sizenode(h) * sizeof(LuaNode)) + h->sizearray * sizeof(TValue); + + // Provide a name for a special registry table + enumnode(ctx, obj2gco(h), size, h == hvalue(registry(ctx->L)) ? "registry" : NULL); + + if (h->node != &luaH_dummynode) + { + bool weakkey = false; + bool weakvalue = false; + + if (const TValue* mode = gfasttm(ctx->L->global, h->metatable, TM_MODE)) + { + if (ttisstring(mode)) + { + weakkey = strchr(svalue(mode), 'k') != NULL; + weakvalue = strchr(svalue(mode), 'v') != NULL; + } + } + + for (int i = 0; i < sizenode(h); ++i) + { + const LuaNode& n = h->node[i]; + + if (!ttisnil(&n.val) && (iscollectable(&n.key) || iscollectable(&n.val))) + { + if (!weakkey && iscollectable(&n.key)) + enumedge(ctx, obj2gco(h), gcvalue(&n.key), "[key]"); + + if (!weakvalue && iscollectable(&n.val)) + { + if (ttisstring(&n.key)) + { + enumedge(ctx, obj2gco(h), gcvalue(&n.val), svalue(&n.key)); + } + else if (ttisnumber(&n.key)) + { + char buf[32]; + snprintf(buf, sizeof(buf), "%.14g", nvalue(&n.key)); + enumedge(ctx, obj2gco(h), gcvalue(&n.val), buf); + } + else + { + char buf[32]; + snprintf(buf, sizeof(buf), "[%s]", getstr(ctx->L->global->ttname[n.key.tt])); + enumedge(ctx, obj2gco(h), gcvalue(&n.val), buf); + } + } + } + } + } + + if (h->sizearray) + enumedges(ctx, obj2gco(h), h->array, h->sizearray, "array"); + + if (h->metatable) + enumedge(ctx, obj2gco(h), obj2gco(h->metatable), "metatable"); +} + +static void enumclosure(EnumContext* ctx, Closure* cl) +{ + if (cl->isC) + { + enumnode(ctx, obj2gco(cl), sizeCclosure(cl->nupvalues), cl->c.debugname); + } + else + { + Proto* p = cl->l.p; + + char buf[LUA_IDSIZE]; + + if (p->source) + snprintf(buf, sizeof(buf), "%s:%d %s", p->debugname ? getstr(p->debugname) : "unnamed", p->linedefined, getstr(p->source)); + else + snprintf(buf, sizeof(buf), "%s:%d", p->debugname ? getstr(p->debugname) : "unnamed", p->linedefined); + + enumnode(ctx, obj2gco(cl), sizeLclosure(cl->nupvalues), buf); + } + + enumedge(ctx, obj2gco(cl), obj2gco(cl->env), "env"); + + if (cl->isC) + { + if (cl->nupvalues) + enumedges(ctx, obj2gco(cl), cl->c.upvals, cl->nupvalues, "upvalue"); + } + else + { + enumedge(ctx, obj2gco(cl), obj2gco(cl->l.p), "proto"); + + if (cl->nupvalues) + enumedges(ctx, obj2gco(cl), cl->l.uprefs, cl->nupvalues, "upvalue"); + } +} + +static void enumudata(EnumContext* ctx, Udata* u) +{ + const char* name = NULL; + + if (LuaTable* h = u->metatable) + { + if (h->node != &luaH_dummynode) + { + for (int i = 0; i < sizenode(h); ++i) + { + const LuaNode& n = h->node[i]; + + if (ttisstring(&n.key) && ttisstring(&n.val) && strcmp(svalue(&n.key), "__type") == 0) + { + name = svalue(&n.val); + break; + } + } + } + } + + enumnode(ctx, obj2gco(u), sizeudata(u->len), name); + + if (u->metatable) + enumedge(ctx, obj2gco(u), obj2gco(u->metatable), "metatable"); +} + +static void enumthread(EnumContext* ctx, lua_State* th) +{ + size_t size = sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci; + + Closure* tcl = NULL; + for (CallInfo* ci = th->base_ci; ci <= th->ci; ++ci) + { + if (ttisfunction(ci->func)) + { + tcl = clvalue(ci->func); + break; + } + } + + if (tcl && !tcl->isC && tcl->l.p->source) + { + Proto* p = tcl->l.p; + + char buf[LUA_IDSIZE]; + + if (p->source) + snprintf(buf, sizeof(buf), "thread at %s:%d %s", p->debugname ? getstr(p->debugname) : "unnamed", p->linedefined, getstr(p->source)); + else + snprintf(buf, sizeof(buf), "thread at %s:%d", p->debugname ? getstr(p->debugname) : "unnamed", p->linedefined); + + enumnode(ctx, obj2gco(th), size, buf); + } + else + { + enumnode(ctx, obj2gco(th), size, NULL); + } + + enumedge(ctx, obj2gco(th), obj2gco(th->gt), "globals"); + + if (th->top > th->stack) + enumedges(ctx, obj2gco(th), th->stack, th->top - th->stack, "stack"); +} + +static void enumbuffer(EnumContext* ctx, Buffer* b) +{ + enumnode(ctx, obj2gco(b), sizebuffer(b->len), NULL); +} + +static void enumproto(EnumContext* ctx, Proto* p) +{ + size_t size = sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto*) * p->sizep + sizeof(TValue) * p->sizek + p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + sizeof(TString*) * p->sizeupvalues; + + if (p->execdata && ctx->L->global->ecb.getmemorysize) + { + size_t nativesize = ctx->L->global->ecb.getmemorysize(ctx->L, p); + + ctx->node(ctx->context, p->execdata, uint8_t(LUA_TNONE), p->memcat, nativesize, NULL); + ctx->edge(ctx->context, enumtopointer(obj2gco(p)), p->execdata, "[native]"); + } + + char buf[LUA_IDSIZE]; + + if (p->source) + snprintf(buf, sizeof(buf), "proto %s:%d %s", p->debugname ? getstr(p->debugname) : "unnamed", p->linedefined, getstr(p->source)); + else + snprintf(buf, sizeof(buf), "proto %s:%d", p->debugname ? getstr(p->debugname) : "unnamed", p->linedefined); + + enumnode(ctx, obj2gco(p), size, buf); + + if (p->sizek) + enumedges(ctx, obj2gco(p), p->k, p->sizek, "constants"); + + for (int i = 0; i < p->sizep; ++i) + enumedge(ctx, obj2gco(p), obj2gco(p->p[i]), "protos"); +} + +static void enumupval(EnumContext* ctx, UpVal* uv) +{ + enumnode(ctx, obj2gco(uv), sizeof(UpVal), NULL); + + if (iscollectable(uv->v)) + enumedge(ctx, obj2gco(uv), gcvalue(uv->v), "value"); +} + +static void enumobj(EnumContext* ctx, GCObject* o) +{ + switch (o->gch.tt) + { + case LUA_TSTRING: + return enumstring(ctx, gco2ts(o)); + + case LUA_TTABLE: + return enumtable(ctx, gco2h(o)); + + case LUA_TFUNCTION: + return enumclosure(ctx, gco2cl(o)); + + case LUA_TUSERDATA: + return enumudata(ctx, gco2u(o)); + + case LUA_TTHREAD: + return enumthread(ctx, gco2th(o)); + + case LUA_TBUFFER: + return enumbuffer(ctx, gco2buf(o)); + + case LUA_TPROTO: + return enumproto(ctx, gco2p(o)); + + case LUA_TUPVAL: + return enumupval(ctx, gco2uv(o)); + + default: + LUAU_ASSERT(!"Unknown object tag"); + } +} + +static bool enumgco(void* context, lua_Page* page, GCObject* gco) +{ + enumobj((EnumContext*)context, gco); + return false; +} + +void luaC_enumheap( + lua_State* L, + void* context, + void (*node)(void* context, void* ptr, uint8_t tt, uint8_t memcat, size_t size, const char* name), + void (*edge)(void* context, void* from, void* to, const char* name) +) +{ + global_State* g = L->global; + + EnumContext ctx; + ctx.L = L; + ctx.context = context; + ctx.node = node; + ctx.edge = edge; + + enumgco(&ctx, NULL, obj2gco(g->mainthread)); + + luaM_visitgco(L, &ctx, enumgco); +} diff --git a/thirdparty/luau/upstream/VM/src/linit.cpp b/thirdparty/luau/upstream/VM/src/linit.cpp new file mode 100644 index 000000000..efcf19043 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/linit.cpp @@ -0,0 +1,95 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_BITLIBNAME, luaopen_bit32}, + {LUA_BUFFERLIBNAME, luaopen_buffer}, + {LUA_VECLIBNAME, luaopen_vector}, + {NULL, NULL}, +}; + +void luaL_openlibs(lua_State* L) +{ + const luaL_Reg* lib = lualibs; + for (; lib->func; lib++) + { + lua_pushcfunction(L, lib->func, NULL); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} + +void luaL_sandbox(lua_State* L) +{ + // set all libraries to read-only + lua_pushnil(L); + while (lua_next(L, LUA_GLOBALSINDEX) != 0) + { + if (lua_istable(L, -1)) + lua_setreadonly(L, -1, true); + + lua_pop(L, 1); + } + + // set all builtin metatables to read-only + lua_pushliteral(L, ""); + if (lua_getmetatable(L, -1)) + { + lua_setreadonly(L, -1, true); + lua_pop(L, 2); + } + else + { + lua_pop(L, 1); + } + + // set globals to readonly and activate safeenv since the env is immutable + lua_setreadonly(L, LUA_GLOBALSINDEX, true); + lua_setsafeenv(L, LUA_GLOBALSINDEX, true); +} + +void luaL_sandboxthread(lua_State* L) +{ + // create new global table that proxies reads to original table + lua_newtable(L); + + lua_newtable(L); + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + + lua_setmetatable(L, -2); + + // we can set safeenv now although it's important to set it to false if code is loaded twice into the thread + lua_replace(L, LUA_GLOBALSINDEX); + lua_setsafeenv(L, LUA_GLOBALSINDEX, true); +} + +static void* l_alloc(void* ud, void* ptr, size_t osize, size_t nsize) +{ + (void)ud; + (void)osize; + if (nsize == 0) + { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + +lua_State* luaL_newstate(void) +{ + return lua_newstate(l_alloc, NULL); +} diff --git a/thirdparty/luau/upstream/VM/src/lmathlib.cpp b/thirdparty/luau/upstream/VM/src/lmathlib.cpp new file mode 100644 index 000000000..9da17e78f --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lmathlib.cpp @@ -0,0 +1,537 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lstate.h" + +#include +#include +#include + +#define LUAU_PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (LUAU_PI / 180.0) + +#define LUAU_NAN (std::numeric_limits::quiet_NaN()) +#define LUAU_E (2.71828182845904523536) +#define LUAU_PHI (1.61803398874989484820) +#define LUAU_SQRT2 (1.41421356237309504880) +#define LUAU_TAU (6.28318530717958647692) + +#define PCG32_INC 105 + +LUAU_FASTFLAGVARIABLE(LuauMathSeedEncode) +LUAU_FASTFLAGVARIABLE(LuauNewMathConstantsRuntime) + +static uint32_t pcg32_random(uint64_t* state) +{ + uint64_t oldstate = *state; + *state = oldstate * 6364136223846793005ULL + (PCG32_INC | 1); + uint32_t xorshifted = uint32_t(((oldstate >> 18u) ^ oldstate) >> 27u); + uint32_t rot = uint32_t(oldstate >> 59u); + return (xorshifted >> rot) | (xorshifted << ((-int32_t(rot)) & 31)); +} + +static void pcg32_seed(uint64_t* state, uint64_t seed) +{ + *state = 0; + pcg32_random(state); + *state += seed; + pcg32_random(state); +} + +static int math_abs(lua_State* L) +{ + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin(lua_State* L) +{ + lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh(lua_State* L) +{ + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos(lua_State* L) +{ + lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh(lua_State* L) +{ + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan(lua_State* L) +{ + lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh(lua_State* L) +{ + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin(lua_State* L) +{ + lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos(lua_State* L) +{ + lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan(lua_State* L) +{ + lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2(lua_State* L) +{ + lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil(lua_State* L) +{ + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor(lua_State* L) +{ + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod(lua_State* L) +{ + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf(lua_State* L) +{ + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt(lua_State* L) +{ + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow(lua_State* L) +{ + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log(lua_State* L) +{ + double x = luaL_checknumber(L, 1); + double res; + if (lua_isnoneornil(L, 2)) + res = log(x); + else + { + double base = luaL_checknumber(L, 2); + if (base == 2.0) + res = log2(x); + else if (base == 10.0) + res = log10(x); + else + res = log(x) / log(base); + } + lua_pushnumber(L, res); + return 1; +} + +static int math_log10(lua_State* L) +{ + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp(lua_State* L) +{ + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg(lua_State* L) +{ + lua_pushnumber(L, luaL_checknumber(L, 1) / RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad(lua_State* L) +{ + lua_pushnumber(L, luaL_checknumber(L, 1) * RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp(lua_State* L) +{ + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp(lua_State* L) +{ + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkinteger(L, 2))); + return 1; +} + +static int math_min(lua_State* L) +{ + int n = lua_gettop(L); // number of arguments + double dmin = luaL_checknumber(L, 1); + int i; + for (i = 2; i <= n; i++) + { + double d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + +static int math_max(lua_State* L) +{ + int n = lua_gettop(L); // number of arguments + double dmax = luaL_checknumber(L, 1); + int i; + for (i = 2; i <= n; i++) + { + double d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + +static int math_random(lua_State* L) +{ + global_State* g = L->global; + switch (lua_gettop(L)) + { // check number of arguments + case 0: + { // no arguments + // Using ldexp instead of division for speed & clarity. + // See http://mumble.net/~campbell/tmp/random_real.c for details on generating doubles from integer ranges. + uint32_t rl = pcg32_random(&g->rngstate); + uint32_t rh = pcg32_random(&g->rngstate); + double rd = ldexp(double(rl | (uint64_t(rh) << 32)), -64); + lua_pushnumber(L, rd); // number between 0 and 1 + break; + } + case 1: + { // only upper limit + int u = luaL_checkinteger(L, 1); + luaL_argcheck(L, 1 <= u, 1, "interval is empty"); + + uint64_t x = uint64_t(u) * pcg32_random(&g->rngstate); + int r = int(1 + (x >> 32)); + lua_pushinteger(L, r); // int between 1 and `u' + break; + } + case 2: + { // lower and upper limits + int l = luaL_checkinteger(L, 1); + int u = luaL_checkinteger(L, 2); + luaL_argcheck(L, l <= u, 2, "interval is empty"); + + uint32_t ul = uint32_t(u) - uint32_t(l); + luaL_argcheck(L, ul < UINT_MAX, 2, "interval is too large"); // -INT_MIN..INT_MAX interval can result in integer overflow + uint64_t x = uint64_t(ul + 1) * pcg32_random(&g->rngstate); + int r = int(l + (x >> 32)); + lua_pushinteger(L, r); // int between `l' and `u' + break; + } + default: + luaL_error(L, "wrong number of arguments"); + } + return 1; +} + +static int math_randomseed(lua_State* L) +{ + int seed = luaL_checkinteger(L, 1); + + pcg32_seed(&L->global->rngstate, seed); + return 0; +} + +static const unsigned char kPerlinHash[257] = { + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, + 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, + 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, + 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, + 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, + 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, + 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, + 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, + 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, 151 +}; + +const float kPerlinGrad[16][3] = { + {1, 1, 0}, + {-1, 1, 0}, + {1, -1, 0}, + {-1, -1, 0}, + {1, 0, 1}, + {-1, 0, 1}, + {1, 0, -1}, + {-1, 0, -1}, + {0, 1, 1}, + {0, -1, 1}, + {0, 1, -1}, + {0, -1, -1}, + {1, 1, 0}, + {0, -1, 1}, + {-1, 1, 0}, + {0, -1, -1} +}; + +inline float perlin_fade(float t) +{ + return t * t * t * (t * (t * 6 - 15) + 10); +} + +inline float perlin_lerp(float t, float a, float b) +{ + return a + t * (b - a); +} + +inline float perlin_grad(int hash, float x, float y, float z) +{ + const float* g = kPerlinGrad[hash & 15]; + return g[0] * x + g[1] * y + g[2] * z; +} + +static float perlin(float x, float y, float z) +{ + float xflr = floorf(x); + float yflr = floorf(y); + float zflr = floorf(z); + + int xi = int(xflr) & 255; + int yi = int(yflr) & 255; + int zi = int(zflr) & 255; + + float xf = x - xflr; + float yf = y - yflr; + float zf = z - zflr; + + float u = perlin_fade(xf); + float v = perlin_fade(yf); + float w = perlin_fade(zf); + + const unsigned char* p = kPerlinHash; + + int a = (p[xi] + yi) & 255; + int aa = (p[a] + zi) & 255; + int ab = (p[a + 1] + zi) & 255; + + int b = (p[xi + 1] + yi) & 255; + int ba = (p[b] + zi) & 255; + int bb = (p[b + 1] + zi) & 255; + + float la = perlin_lerp(u, perlin_grad(p[aa], xf, yf, zf), perlin_grad(p[ba], xf - 1, yf, zf)); + float lb = perlin_lerp(u, perlin_grad(p[ab], xf, yf - 1, zf), perlin_grad(p[bb], xf - 1, yf - 1, zf)); + float la1 = perlin_lerp(u, perlin_grad(p[aa + 1], xf, yf, zf - 1), perlin_grad(p[ba + 1], xf - 1, yf, zf - 1)); + float lb1 = perlin_lerp(u, perlin_grad(p[ab + 1], xf, yf - 1, zf - 1), perlin_grad(p[bb + 1], xf - 1, yf - 1, zf - 1)); + + return perlin_lerp(w, perlin_lerp(v, la, lb), perlin_lerp(v, la1, lb1)); +} + +static int math_noise(lua_State* L) +{ + int nx, ny, nz; + double x = lua_tonumberx(L, 1, &nx); + double y = lua_tonumberx(L, 2, &ny); + double z = lua_tonumberx(L, 3, &nz); + + luaL_argexpected(L, nx, 1, "number"); + luaL_argexpected(L, ny || lua_isnoneornil(L, 2), 2, "number"); + luaL_argexpected(L, nz || lua_isnoneornil(L, 3), 3, "number"); + + double r = perlin((float)x, (float)y, (float)z); + + lua_pushnumber(L, r); + return 1; +} + +static int math_clamp(lua_State* L) +{ + double v = luaL_checknumber(L, 1); + double min = luaL_checknumber(L, 2); + double max = luaL_checknumber(L, 3); + + luaL_argcheck(L, min <= max, 3, "max must be greater than or equal to min"); + + double r = v < min ? min : v; + r = r > max ? max : r; + + lua_pushnumber(L, r); + return 1; +} + +static int math_sign(lua_State* L) +{ + double v = luaL_checknumber(L, 1); + lua_pushnumber(L, v > 0.0 ? 1.0 : v < 0.0 ? -1.0 : 0.0); + return 1; +} + +static int math_round(lua_State* L) +{ + lua_pushnumber(L, round(luaL_checknumber(L, 1))); + return 1; +} + +static int math_map(lua_State* L) +{ + double x = luaL_checknumber(L, 1); + double inmin = luaL_checknumber(L, 2); + double inmax = luaL_checknumber(L, 3); + double outmin = luaL_checknumber(L, 4); + double outmax = luaL_checknumber(L, 5); + + double result = outmin + (x - inmin) * (outmax - outmin) / (inmax - inmin); + lua_pushnumber(L, result); + return 1; +} + +static int math_lerp(lua_State* L) +{ + double a = luaL_checknumber(L, 1); + double b = luaL_checknumber(L, 2); + double t = luaL_checknumber(L, 3); + + double r = (t == 1.0) ? b : a + (b - a) * t; + lua_pushnumber(L, r); + return 1; +} + +static int math_isnan(lua_State* L) +{ + double x = luaL_checknumber(L, 1); + + lua_pushboolean(L, isnan(x)); + return 1; +} + +static int math_isinf(lua_State* L) +{ + double x = luaL_checknumber(L, 1); + + lua_pushboolean(L, isinf(x)); + return 1; +} + +static int math_isfinite(lua_State* L) +{ + double x = luaL_checknumber(L, 1); + + lua_pushboolean(L, isfinite(x)); + return 1; +} + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {"noise", math_noise}, + {"clamp", math_clamp}, + {"sign", math_sign}, + {"round", math_round}, + {"map", math_map}, + {"lerp", math_lerp}, + {"isnan", math_isnan}, + {"isinf", math_isinf}, + {"isfinite", math_isfinite}, + {NULL, NULL}, +}; + +/* +** Open math library +*/ +int luaopen_math(lua_State* L) +{ + uint64_t seed = FFlag::LuauMathSeedEncode ? lua_encodepointer(L, uintptr_t(L)) : uintptr_t(L); + seed ^= time(NULL); + seed ^= clock(); + + pcg32_seed(&L->global->rngstate, seed); + + luaL_register(L, LUA_MATHLIBNAME, mathlib); + + lua_pushnumber(L, LUAU_PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); + + if (FFlag::LuauNewMathConstantsRuntime) + { + lua_pushnumber(L, LUAU_NAN); + lua_setfield(L, -2, "nan"); + lua_pushnumber(L, LUAU_E); + lua_setfield(L, -2, "e"); + lua_pushnumber(L, LUAU_PHI); + lua_setfield(L, -2, "phi"); + lua_pushnumber(L, LUAU_SQRT2); + lua_setfield(L, -2, "sqrt2"); + lua_pushnumber(L, LUAU_TAU); + lua_setfield(L, -2, "tau"); + } + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lmem.cpp b/thirdparty/luau/upstream/VM/src/lmem.cpp new file mode 100644 index 000000000..c6e14951b --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lmem.cpp @@ -0,0 +1,710 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lmem.h" + +#include "lstate.h" +#include "ldo.h" +#include "ldebug.h" + +#include + +/* + * Luau heap uses a size-segregated page structure, with individual pages and large allocations + * allocated using system heap (via frealloc callback). + * + * frealloc callback serves as a general, if slow, allocation callback that can allocate, free or + * resize allocations: + * + * void* frealloc(void* ud, void* ptr, size_t oldsize, size_t newsize); + * + * frealloc(ud, NULL, 0, x) creates a new block of size x + * frealloc(ud, p, x, 0) frees the block p (must return NULL) + * frealloc(ud, NULL, 0, 0) does nothing, equivalent to free(NULL) + * + * frealloc returns NULL if it cannot create or reallocate the area + * (any reallocation to an equal or smaller size cannot fail!) + * + * On top of this, Luau implements heap storage which is split into two types of allocations: + * + * - GCO, short for "garbage collected objects" + * - other objects (for example, arrays stored inside table objects) + * + * The heap layout for these two allocation types is a bit different. + * + * All GCO are allocated in pages, which is a block of memory of ~16K in size that has a page header + * (lua_Page). Each page contains 1..N blocks of the same size, where N is selected to fill the page + * completely. This amortizes the allocation cost and increases locality. Each GCO block starts with + * the GC header (GCheader) which contains the object type, mark bits and other GC metadata. If the + * GCO block is free (not used), then it must have the type set to TNIL; in this case the block can + * be part of the per-page free list, the link for that list is stored after the header (freegcolink). + * + * Importantly, the GCO block doesn't have any back references to the page it's allocated in, so it's + * impossible to free it in isolation - GCO blocks are freed by sweeping the pages they belong to, + * using luaM_freegco which must specify the page; this is called by page sweeper that traverses the + * entire page's worth of objects. For this reason it's also important that freed GCO blocks keep the + * GC header intact and accessible (with type = NIL) so that the sweeper can access it. + * + * Some GCOs are too large to fit in a 16K page without excessive fragmentation (the size threshold is + * currently 512 bytes); in this case, we allocate a dedicated small page with just a single block's worth + * storage space, but that requires allocating an extra page header. In effect large GCOs are a little bit + * less memory efficient, but this allows us to uniformly sweep small and large GCOs using page lists. + * + * All GCO pages are linked in a large intrusive linked list (global_State::allgcopages). Additionally, + * for each block size there's a page free list that contains pages that have at least one free block + * (global_State::freegcopages). This free list is used to make sure object allocation is O(1). + * + * When LUAU_ASSERTENABLED is enabled, all non-GCO pages are also linked in a list (global_State::allpages). + * Because this list is not strictly required for runtime operations, it is only tracked for the purposes of + * debugging. While overhead of linking those pages together is very small, unnecessary operations are avoided. + * + * Compared to GCOs, regular allocations have two important differences: they can be freed in isolation, + * and they don't start with a GC header. Because of this, each allocation is prefixed with block metadata, + * which contains the pointer to the page for allocated blocks, and the pointer to the next free block + * inside the page for freed blocks. + * For regular allocations that are too large to fit in a page (using the same threshold of 512 bytes), + * we don't allocate a separate page, instead simply using frealloc to allocate a vanilla block of memory. + * + * Just like GCO pages, we store a page free list (global_State::freepages) that allows O(1) allocation; + * there is no global list for non-GCO pages since we never need to traverse them directly. + * + * In both cases, we pick the page by computing the size class from the block size which rounds the block + * size up to reduce the chance that we'll allocate pages that have very few allocated blocks. The size + * class strategy is determined by SizeClassConfig constructor. + * + * Note that when the last block in a page is freed, we immediately free the page with frealloc - the + * memory manager doesn't currently attempt to keep unused memory around. This can result in excessive + * allocation traffic and can be mitigated by adding a page cache in the future. + * + * For both GCO and non-GCO pages, the per-page block allocation combines bump pointer style allocation + * (lua_Page::freeNext) and per-page free list (lua_Page::freeList). We use the bump allocator to allocate + * the contents of the page, and the free list for further reuse; this allows shorter page setup times + * which results in less variance between allocation cost, as well as tighter sweep bounds for newly + * allocated pages. + */ + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if __has_feature(address_sanitizer) || defined(LUAU_ENABLE_ASAN) +#include +#define ASAN_POISON_MEMORY_REGION(addr, size) __asan_poison_memory_region((addr), (size)) +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) __asan_unpoison_memory_region((addr), (size)) +#else +#define ASAN_POISON_MEMORY_REGION(addr, size) (void)0 +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) (void)0 +#endif + +/* + * The sizes of most Luau objects aren't crucial for code correctness, but they are crucial for memory efficiency + * To prevent some of them accidentally growing and us losing memory without realizing it, we're going to lock + * the sizes of all critical structures down. + */ +#if defined(__APPLE__) +#define ABISWITCH(x64, ms32, gcc32) (sizeof(void*) == 8 ? x64 : gcc32) +#elif defined(__i386__) && defined(__MINGW32__) && !defined(__MINGW64__) +#define ABISWITCH(x64, ms32, gcc32) (ms32) +#elif defined(__i386__) && !defined(_MSC_VER) +#define ABISWITCH(x64, ms32, gcc32) (gcc32) +#else +// Android somehow uses a similar ABI to MSVC, *not* to iOS... +#define ABISWITCH(x64, ms32, gcc32) (sizeof(void*) == 8 ? x64 : ms32) +#endif + +#if LUA_VECTOR_SIZE == 4 +static_assert(sizeof(TValue) == ABISWITCH(24, 24, 24), "size mismatch for value"); +static_assert(sizeof(LuaNode) == ABISWITCH(48, 48, 48), "size mismatch for table entry"); +#else +static_assert(sizeof(TValue) == ABISWITCH(16, 16, 16), "size mismatch for value"); +static_assert(sizeof(LuaNode) == ABISWITCH(32, 32, 32), "size mismatch for table entry"); +#endif + +static_assert(offsetof(TString, data) == ABISWITCH(24, 20, 20), "size mismatch for string header"); +static_assert(sizeof(LuaTable) == ABISWITCH(48, 32, 32), "size mismatch for table header"); +static_assert(offsetof(Buffer, data) == ABISWITCH(8, 8, 8), "size mismatch for buffer header"); + +// The userdata is designed to provide 16 byte alignment for 16 byte and larger userdata sizes +static_assert(offsetof(Udata, data) == 16, "data must be at precise offset provide proper alignment"); + +const size_t kSizeClasses = LUA_SIZECLASSES; + +// Controls the number of entries in SizeClassConfig and define the maximum possible paged allocation size +// Modifications require updates the SizeClassConfig initialization +const size_t kMaxSmallSize = 1024; + +// Effective limit on object size to use paged allocation +// Can be modified without additional changes to code, provided it is smaller or equal to kMaxSmallSize +const size_t kMaxSmallSizeUsed = 1024; + +const size_t kLargePageThreshold = 512; // larger pages are used for objects larger than this size to fit more of them into a page + +// constant factor to reduce our page sizes by, to increase the chances that pages we allocate will +// allow external allocators to allocate them without wasting space due to rounding introduced by their heap meta data +const size_t kExternalAllocatorMetaDataReduction = 24; + +const size_t kSmallPageSize = 16 * 1024 - kExternalAllocatorMetaDataReduction; +const size_t kLargePageSize = 32 * 1024 - kExternalAllocatorMetaDataReduction; + +const size_t kBlockHeader = sizeof(double) > sizeof(void*) ? sizeof(double) : sizeof(void*); // suitable for aligning double & void* on all platforms +const size_t kGCOLinkOffset = (sizeof(GCheader) + sizeof(void*) - 1) & ~(sizeof(void*) - 1); // GCO pages contain freelist links after the GC header + +struct SizeClassConfig +{ + int sizeOfClass[kSizeClasses]; + int8_t classForSize[kMaxSmallSize + 1]; + int classCount = 0; + + SizeClassConfig() + { + memset(sizeOfClass, 0, sizeof(sizeOfClass)); + memset(classForSize, -1, sizeof(classForSize)); + + // we use a progressive size class scheme: + // - all size classes are aligned by 8b to satisfy pointer alignment requirements + // - we first allocate sizes classes in multiples of 8 + // - after the first cutoff we allocate size classes in multiples of 16 + // - after the second cutoff we allocate size classes in multiples of 32 + // - after the third cutoff we allocate size classes in multiples of 64 + // this balances internal fragmentation vs external fragmentation + for (int size = 8; size < 64; size += 8) + sizeOfClass[classCount++] = size; + + for (int size = 64; size < 256; size += 16) + sizeOfClass[classCount++] = size; + + for (int size = 256; size < 512; size += 32) + sizeOfClass[classCount++] = size; + + for (int size = 512; size <= 1024; size += 64) + sizeOfClass[classCount++] = size; + + LUAU_ASSERT(size_t(classCount) <= kSizeClasses); + + // fill the lookup table for all classes + for (int klass = 0; klass < classCount; ++klass) + classForSize[sizeOfClass[klass]] = int8_t(klass); + + // fill the gaps in lookup table + for (int size = kMaxSmallSize - 1; size >= 0; --size) + if (classForSize[size] < 0) + classForSize[size] = classForSize[size + 1]; + } +}; + +const SizeClassConfig kSizeClassConfig; + +// size class for a block of size sz; returns -1 for size=0 because empty allocations take no space +#define sizeclass(sz) (size_t((sz) - 1) < kMaxSmallSizeUsed ? kSizeClassConfig.classForSize[sz] : -1) + +// metadata for a block is stored in the first pointer of the block +#define metadata(block) (*(void**)(block)) +#define freegcolink(block) (*(void**)((char*)block + kGCOLinkOffset)) + +#if defined(LUAU_ASSERTENABLED) +#define debugpageset(x) (x) +#else +#define debugpageset(x) NULL +#endif + +struct lua_Page +{ + // list of pages with free blocks + lua_Page* prev; + lua_Page* next; + + // list of all pages + lua_Page* listprev; + lua_Page* listnext; + + int pageSize; // page size in bytes, including page header + int blockSize; // block size in bytes, including block header (for non-GCO) + + void* freeList; // next free block in this page; linked with metadata()/freegcolink() + int freeNext; // next free block offset in this page, in bytes; when negative, freeList is used instead + int busyBlocks; // number of blocks allocated out of this page + + // provide additional padding based on current object size to provide 16 byte alignment of data + // later static_assert checks that this requirement is held + char padding[sizeof(void*) == 8 ? 8 : 12]; + + char data[1]; +}; + +static_assert(offsetof(lua_Page, data) % 16 == 0, "data must be 16 byte aligned to provide properly aligned allocation of userdata objects"); + +l_noret luaM_toobig(lua_State* L) +{ + luaG_runerror(L, "memory allocation error: block too big"); +} + +static lua_Page* newpage(lua_State* L, lua_Page** pageset, int pageSize, int blockSize, int blockCount) +{ + global_State* g = L->global; + + LUAU_ASSERT(pageSize - int(offsetof(lua_Page, data)) >= blockSize * blockCount); + + lua_Page* page = (lua_Page*)(*g->frealloc)(g->ud, NULL, 0, pageSize); + if (!page) + luaD_throw(L, LUA_ERRMEM); + + ASAN_POISON_MEMORY_REGION(page->data, blockSize * blockCount); + + // setup page header + page->prev = NULL; + page->next = NULL; + + page->listprev = NULL; + page->listnext = NULL; + + page->pageSize = pageSize; + page->blockSize = blockSize; + + // note: we start with the last block in the page and move downward + // either order would work, but that way we don't need to store the block count in the page + // additionally, GC stores objects in singly linked lists, and this way the GC lists end up in increasing pointer order + page->freeList = NULL; + page->freeNext = (blockCount - 1) * blockSize; + page->busyBlocks = 0; + + if (pageset) + { + page->listnext = *pageset; + if (page->listnext) + page->listnext->listprev = page; + *pageset = page; + } + + return page; +} + +// this is part of a cold path in newblock and newgcoblock +// it is marked as noinline to prevent it from being inlined into those functions +// if it is inlined, then the compiler may determine those functions are "too big" to be profitably inlined, which results in reduced performance +LUAU_NOINLINE static lua_Page* newclasspage(lua_State* L, lua_Page** freepageset, lua_Page** pageset, uint8_t sizeClass, bool storeMetadata) +{ + int sizeOfClass = kSizeClassConfig.sizeOfClass[sizeClass]; + int pageSize = sizeOfClass > int(kLargePageThreshold) ? kLargePageSize : kSmallPageSize; + int blockSize = sizeOfClass + (storeMetadata ? kBlockHeader : 0); + int blockCount = (pageSize - offsetof(lua_Page, data)) / blockSize; + + lua_Page* page = newpage(L, pageset, pageSize, blockSize, blockCount); + + // prepend a page to page freelist (which is empty because we only ever allocate a new page when it is!) + LUAU_ASSERT(!freepageset[sizeClass]); + freepageset[sizeClass] = page; + + return page; +} + +static void freepage(lua_State* L, lua_Page** pageset, lua_Page* page) +{ + global_State* g = L->global; + + if (pageset) + { + // remove page from alllist + if (page->listnext) + page->listnext->listprev = page->listprev; + + if (page->listprev) + page->listprev->listnext = page->listnext; + else if (*pageset == page) + *pageset = page->listnext; + } + + // so long + (*g->frealloc)(g->ud, page, page->pageSize, 0); +} + +static void freeclasspage(lua_State* L, lua_Page** freepageset, lua_Page** pageset, lua_Page* page, uint8_t sizeClass) +{ + // remove page from freelist + if (page->next) + page->next->prev = page->prev; + + if (page->prev) + page->prev->next = page->next; + else if (freepageset[sizeClass] == page) + freepageset[sizeClass] = page->next; + + freepage(L, pageset, page); +} + +static void* newblock(lua_State* L, int sizeClass) +{ + global_State* g = L->global; + lua_Page* page = g->freepages[sizeClass]; + + // slow path: no page in the freelist, allocate a new one + if (!page) + page = newclasspage(L, g->freepages, debugpageset(&g->allpages), sizeClass, true); + + LUAU_ASSERT(!page->prev); + LUAU_ASSERT(page->freeList || page->freeNext >= 0); + LUAU_ASSERT(size_t(page->blockSize) == kSizeClassConfig.sizeOfClass[sizeClass] + kBlockHeader); + + void* block; + + if (page->freeNext >= 0) + { + block = &page->data + page->freeNext; + ASAN_UNPOISON_MEMORY_REGION(block, page->blockSize); + + page->freeNext -= page->blockSize; + page->busyBlocks++; + } + else + { + block = page->freeList; + ASAN_UNPOISON_MEMORY_REGION(block, page->blockSize); + + page->freeList = metadata(block); + page->busyBlocks++; + } + + // the first word in a block point back to the page + metadata(block) = page; + + // if we allocate the last block out of a page, we need to remove it from free list + if (!page->freeList && page->freeNext < 0) + { + g->freepages[sizeClass] = page->next; + if (page->next) + page->next->prev = NULL; + page->next = NULL; + } + + // the user data is right after the metadata + return (char*)block + kBlockHeader; +} + +static void* newgcoblock(lua_State* L, int sizeClass) +{ + global_State* g = L->global; + lua_Page* page = g->freegcopages[sizeClass]; + + // slow path: no page in the freelist, allocate a new one + if (!page) + page = newclasspage(L, g->freegcopages, &g->allgcopages, sizeClass, false); + + LUAU_ASSERT(!page->prev); + LUAU_ASSERT(page->freeList || page->freeNext >= 0); + LUAU_ASSERT(page->blockSize == kSizeClassConfig.sizeOfClass[sizeClass]); + + void* block; + + if (page->freeNext >= 0) + { + block = &page->data + page->freeNext; + ASAN_UNPOISON_MEMORY_REGION(block, page->blockSize); + + page->freeNext -= page->blockSize; + page->busyBlocks++; + } + else + { + block = page->freeList; + ASAN_UNPOISON_MEMORY_REGION((char*)block + sizeof(GCheader), page->blockSize - sizeof(GCheader)); + + // when separate block metadata is not used, free list link is stored inside the block data itself + page->freeList = freegcolink(block); + page->busyBlocks++; + } + + // if we allocate the last block out of a page, we need to remove it from free list + if (!page->freeList && page->freeNext < 0) + { + g->freegcopages[sizeClass] = page->next; + if (page->next) + page->next->prev = NULL; + page->next = NULL; + } + + return block; +} + +static void freeblock(lua_State* L, int sizeClass, void* block) +{ + global_State* g = L->global; + + // the user data is right after the metadata + LUAU_ASSERT(block); + block = (char*)block - kBlockHeader; + + lua_Page* page = (lua_Page*)metadata(block); + LUAU_ASSERT(page && page->busyBlocks > 0); + LUAU_ASSERT(size_t(page->blockSize) == kSizeClassConfig.sizeOfClass[sizeClass] + kBlockHeader); + LUAU_ASSERT(block >= page->data && block < (char*)page + page->pageSize); + + // if the page wasn't in the page free list, it should be now since it got a block! + if (!page->freeList && page->freeNext < 0) + { + LUAU_ASSERT(!page->prev); + LUAU_ASSERT(!page->next); + + page->next = g->freepages[sizeClass]; + if (page->next) + page->next->prev = page; + g->freepages[sizeClass] = page; + } + + // add the block to the free list inside the page + metadata(block) = page->freeList; + page->freeList = block; + + ASAN_POISON_MEMORY_REGION(block, page->blockSize); + + page->busyBlocks--; + + // if it's the last block in the page, we don't need the page + if (page->busyBlocks == 0) + freeclasspage(L, g->freepages, debugpageset(&g->allpages), page, sizeClass); +} + +static void freegcoblock(lua_State* L, int sizeClass, void* block, lua_Page* page) +{ + LUAU_ASSERT(page && page->busyBlocks > 0); + LUAU_ASSERT(page->blockSize == kSizeClassConfig.sizeOfClass[sizeClass]); + LUAU_ASSERT(block >= page->data && block < (char*)page + page->pageSize); + + global_State* g = L->global; + + // if the page wasn't in the page free list, it should be now since it got a block! + if (!page->freeList && page->freeNext < 0) + { + LUAU_ASSERT(!page->prev); + LUAU_ASSERT(!page->next); + + page->next = g->freegcopages[sizeClass]; + if (page->next) + page->next->prev = page; + g->freegcopages[sizeClass] = page; + } + + // when separate block metadata is not used, free list link is stored inside the block data itself + freegcolink(block) = page->freeList; + page->freeList = block; + + ASAN_POISON_MEMORY_REGION((char*)block + sizeof(GCheader), page->blockSize - sizeof(GCheader)); + + page->busyBlocks--; + + // if it's the last block in the page, we don't need the page + if (page->busyBlocks == 0) + freeclasspage(L, g->freegcopages, &g->allgcopages, page, sizeClass); +} + +void* luaM_new_(lua_State* L, size_t nsize, uint8_t memcat) +{ + global_State* g = L->global; + + int nclass = sizeclass(nsize); + + void* block = nclass >= 0 ? newblock(L, nclass) : (*g->frealloc)(g->ud, NULL, 0, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + + g->totalbytes += nsize; + g->memcatbytes[memcat] += nsize; + + if (LUAU_UNLIKELY(!!g->cb.onallocate)) + { + g->cb.onallocate(L, 0, nsize); + } + + return block; +} + +GCObject* luaM_newgco_(lua_State* L, size_t nsize, uint8_t memcat) +{ + // we need to accommodate space for link for free blocks (freegcolink) + LUAU_ASSERT(nsize >= kGCOLinkOffset + sizeof(void*)); + + global_State* g = L->global; + + int nclass = sizeclass(nsize); + + void* block = NULL; + + if (nclass >= 0) + { + block = newgcoblock(L, nclass); + } + else + { + lua_Page* page = newpage(L, &g->allgcopages, offsetof(lua_Page, data) + int(nsize), int(nsize), 1); + + block = &page->data; + ASAN_UNPOISON_MEMORY_REGION(block, page->blockSize); + + page->freeNext -= page->blockSize; + page->busyBlocks++; + } + + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + + g->totalbytes += nsize; + g->memcatbytes[memcat] += nsize; + + if (LUAU_UNLIKELY(!!g->cb.onallocate)) + { + g->cb.onallocate(L, 0, nsize); + } + + return (GCObject*)block; +} + +void luaM_free_(lua_State* L, void* block, size_t osize, uint8_t memcat) +{ + global_State* g = L->global; + LUAU_ASSERT((osize == 0) == (block == NULL)); + + int oclass = sizeclass(osize); + + if (oclass >= 0) + freeblock(L, oclass, block); + else + (*g->frealloc)(g->ud, block, osize, 0); + + g->totalbytes -= osize; + g->memcatbytes[memcat] -= osize; +} + +void luaM_freegco_(lua_State* L, GCObject* block, size_t osize, uint8_t memcat, lua_Page* page) +{ + global_State* g = L->global; + LUAU_ASSERT((osize == 0) == (block == NULL)); + + int oclass = sizeclass(osize); + + if (oclass >= 0) + { + block->gch.tt = LUA_TNIL; + + freegcoblock(L, oclass, block, page); + } + else + { + LUAU_ASSERT(page->busyBlocks == 1); + LUAU_ASSERT(size_t(page->blockSize) == osize); + LUAU_ASSERT((void*)block == page->data); + + freepage(L, &g->allgcopages, page); + } + + g->totalbytes -= osize; + g->memcatbytes[memcat] -= osize; +} + +void* luaM_realloc_(lua_State* L, void* block, size_t osize, size_t nsize, uint8_t memcat) +{ + global_State* g = L->global; + LUAU_ASSERT((osize == 0) == (block == NULL)); + + int nclass = sizeclass(nsize); + int oclass = sizeclass(osize); + void* result; + + // if either block needs to be allocated using a block allocator, we can't use realloc directly + if (nclass >= 0 || oclass >= 0) + { + result = nclass >= 0 ? newblock(L, nclass) : (*g->frealloc)(g->ud, NULL, 0, nsize); + if (result == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + + if (osize > 0 && nsize > 0) + memcpy(result, block, osize < nsize ? osize : nsize); + + if (oclass >= 0) + freeblock(L, oclass, block); + else + (*g->frealloc)(g->ud, block, osize, 0); + } + else + { + result = (*g->frealloc)(g->ud, block, osize, nsize); + if (result == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + } + + LUAU_ASSERT((nsize == 0) == (result == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + g->memcatbytes[memcat] += nsize - osize; + + if (LUAU_UNLIKELY(!!g->cb.onallocate)) + { + g->cb.onallocate(L, osize, nsize); + } + + return result; +} + +void luaM_getpagewalkinfo(lua_Page* page, char** start, char** end, int* busyBlocks, int* blockSize) +{ + int blockCount = (page->pageSize - offsetof(lua_Page, data)) / page->blockSize; + + LUAU_ASSERT(page->freeNext >= -page->blockSize && page->freeNext <= (blockCount - 1) * page->blockSize); + + char* data = page->data; // silences ubsan when indexing page->data + + *start = data + page->freeNext + page->blockSize; + *end = data + blockCount * page->blockSize; + *busyBlocks = page->busyBlocks; + *blockSize = page->blockSize; +} + +void luaM_getpageinfo(lua_Page* page, int* pageBlocks, int* busyBlocks, int* blockSize, int* pageSize) +{ + *pageBlocks = (page->pageSize - offsetof(lua_Page, data)) / page->blockSize; + *busyBlocks = page->busyBlocks; + *blockSize = page->blockSize; + *pageSize = page->pageSize; +} + +lua_Page* luaM_getnextpage(lua_Page* page) +{ + return page->listnext; +} + +void luaM_visitpage(lua_Page* page, void* context, bool (*visitor)(void* context, lua_Page* page, GCObject* gco)) +{ + char* start; + char* end; + int busyBlocks; + int blockSize; + luaM_getpagewalkinfo(page, &start, &end, &busyBlocks, &blockSize); + + for (char* pos = start; pos != end; pos += blockSize) + { + GCObject* gco = (GCObject*)pos; + + // skip memory blocks that are already freed + if (gco->gch.tt == LUA_TNIL) + continue; + + // when true is returned it means that the element was deleted + if (visitor(context, page, gco)) + { + LUAU_ASSERT(busyBlocks > 0); + + // if the last block was removed, page would be removed as well + if (--busyBlocks == 0) + break; + } + } +} + +void luaM_visitgco(lua_State* L, void* context, bool (*visitor)(void* context, lua_Page* page, GCObject* gco)) +{ + global_State* g = L->global; + + for (lua_Page* curr = g->allgcopages; curr;) + { + lua_Page* next = curr->listnext; // block visit might destroy the page + + luaM_visitpage(curr, context, visitor); + + curr = next; + } +} diff --git a/thirdparty/luau/upstream/VM/src/lmem.h b/thirdparty/luau/upstream/VM/src/lmem.h new file mode 100644 index 000000000..aff07548c --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lmem.h @@ -0,0 +1,33 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lua.h" + +struct lua_Page; +union GCObject; + +#define luaM_newgco(L, t, size, memcat) cast_to(t*, luaM_newgco_(L, size, memcat)) +#define luaM_freegco(L, p, size, memcat, page) luaM_freegco_(L, obj2gco(p), size, memcat, page) + +#define luaM_arraysize_(L, n, e) ((cast_to(size_t, (n)) <= SIZE_MAX / (e)) ? (n) * (e) : (luaM_toobig(L), SIZE_MAX)) + +#define luaM_newarray(L, n, t, memcat) cast_to(t*, luaM_new_(L, luaM_arraysize_(L, n, sizeof(t)), memcat)) +#define luaM_freearray(L, b, n, t, memcat) luaM_free_(L, (b), (n) * sizeof(t), memcat) +#define luaM_reallocarray(L, v, oldn, n, t, memcat) \ + ((v) = cast_to(t*, luaM_realloc_(L, v, (oldn) * sizeof(t), luaM_arraysize_(L, n, sizeof(t)), memcat))) + +LUAI_FUNC void* luaM_new_(lua_State* L, size_t nsize, uint8_t memcat); +LUAI_FUNC GCObject* luaM_newgco_(lua_State* L, size_t nsize, uint8_t memcat); +LUAI_FUNC void luaM_free_(lua_State* L, void* block, size_t osize, uint8_t memcat); +LUAI_FUNC void luaM_freegco_(lua_State* L, GCObject* block, size_t osize, uint8_t memcat, lua_Page* page); +LUAI_FUNC void* luaM_realloc_(lua_State* L, void* block, size_t osize, size_t nsize, uint8_t memcat); + +LUAI_FUNC l_noret luaM_toobig(lua_State* L); + +LUAI_FUNC void luaM_getpagewalkinfo(lua_Page* page, char** start, char** end, int* busyBlocks, int* blockSize); +LUAI_FUNC void luaM_getpageinfo(lua_Page* page, int* pageBlocks, int* busyBlocks, int* blockSize, int* pageSize); +LUAI_FUNC lua_Page* luaM_getnextpage(lua_Page* page); + +LUAI_FUNC void luaM_visitpage(lua_Page* page, void* context, bool (*visitor)(void* context, lua_Page* page, GCObject* gco)); +LUAI_FUNC void luaM_visitgco(lua_State* L, void* context, bool (*visitor)(void* context, lua_Page* page, GCObject* gco)); diff --git a/thirdparty/luau/upstream/VM/src/lnumprint.cpp b/thirdparty/luau/upstream/VM/src/lnumprint.cpp new file mode 100644 index 000000000..763675e00 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lnumprint.cpp @@ -0,0 +1,369 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "luaconf.h" +#include "lnumutils.h" + +#include "lcommon.h" + +#include + +#ifdef _MSC_VER +#include +#endif + +// This work is based on: +// Raffaello Giulietti. The Schubfach way to render doubles. 2021 +// https://drive.google.com/file/d/1IEeATSVnEE6TkrHlCYNY2GjaraBjOT4f/edit + +// The code uses the notation from the paper for local variables where appropriate, and refers to paper sections/figures/results. + +// 9.8.2. Precomputed table for 128-bit overestimates of powers of 10 (see figure 3 for table bounds) +// To avoid storing 616 128-bit numbers directly we use a technique inspired by Dragonbox implementation and store 16 consecutive +// powers using a 128-bit baseline and a bitvector with 1-bit scale and 3-bit offset for the delta between each entry and base*5^k +static const int kPow10TableMin = -292; +static const int kPow10TableMax = 324; + +// clang-format off +static const uint64_t kPow5Table[16] = { + 0x8000000000000000, 0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, 0xc350000000000000, + 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, + 0xe8d4a51000000000, 0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, +}; +static const uint64_t kPow10Table[(kPow10TableMax - kPow10TableMin + 1 + 15) / 16][3] = { + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b, 0x333443443333443b}, {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4, 0xbbb3ab3cb3ba3cbc}, + {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa, 0x4ba4bc4bb4bb4bcc}, {0xaecc49914078536d, 0x58fae9f773886e19, 0x3ba3bc33b43b43bb}, + {0xc21094364dfb5636, 0x985915fc12f542e5, 0x33b43b43a33b33cb}, {0xd77485cb25823ac7, 0x7d633293366b828c, 0x34b44c444343443c}, + {0xef340a98172aace4, 0x86fb897116c87c35, 0x333343333343334b}, {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074, 0xccaccbbcbcbb4bbc}, + {0x936b9fcebb25c995, 0xcab10dd900beec35, 0x3ab3ab3ab3bb3bbb}, {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb, 0x4cc3dc4db4db4dbb}, + {0xb5b5ada8aaff80b8, 0x0d819992132456bb, 0x33b33a34c33b34ab}, {0xc9bcff6034c13052, 0xfc89b393dd02f0b6, 0x33c33b44b43c34bc}, + {0xdff9772470297ebd, 0x59787e2b93bc56f8, 0x43b444444443434c}, {0xf8a95fcf88747d94, 0x75a44c6397ce912b, 0x443334343443343b}, + {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900, 0xbbabab3aa3ab4ccc}, {0x993fe2c6d07b7fab, 0xe546a8038efe402a, 0x4cb4bc4db4db4bcc}, + {0xaa242499697392d2, 0xdde50bd1d5d0b9ea, 0x3ba3ba3bb33b33bc}, {0xbce5086492111aea, 0x88f4bb1ca6bcf585, 0x44b44c44c44c43cb}, + {0xd1b71758e219652b, 0xd3c36113404ea4a9, 0x44c44c44c444443b}, {0xe8d4a51000000000, 0x0000000000000000, 0x444444444444444c}, + {0x813f3978f8940984, 0x4000000000000000, 0xcccccccccccccccc}, {0x8f7e32ce7bea5c6f, 0xe4820023a2000000, 0xbba3bc4cc4cc4ccc}, + {0x9f4f2726179a2245, 0x01d762422c946591, 0x4aa3bb3aa3ba3bab}, {0xb0de65388cc8ada8, 0x3b25a55f43294bcc, 0x3ca33b33b44b43bc}, + {0xc45d1df942711d9a, 0x3ba5d0bd324f8395, 0x44c44c34c44b44cb}, {0xda01ee641a708de9, 0xe80e6f4820cc9496, 0x33b33b343333333c}, + {0xf209787bb47d6b84, 0xc0678c5dbd23a49b, 0x443444444443443b}, {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3, 0xdbccbcccb4cb3bbb}, + {0x952ab45cfa97a0b2, 0xdd945a747bf26184, 0x3bc4bb4ab3ca3cbc}, {0xa59bc234db398c25, 0x43fab9837e699096, 0x3bb3ac3ab3bb33ac}, + {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30, 0x33b43b43b34c34dc}, {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5, 0x34c44c43c44b44cb}, + {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e, 0x333333333333333c}, {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2, 0x433344443333344c}, + {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f, 0xdcbdcc3cc4cc4bcb}, {0x9b10a4e5e9913128, 0xca7cf2b4191c8327, 0x3ab3cb3bc3bb4bbb}, + {0xac2820d9623bf429, 0x546345fa9fbdcd45, 0x3bb3cc43c43c43cb}, {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4, 0x44b34a43b44c44bc}, + {0xd433179d9c8cb841, 0x5fa60692a46151ec, 0x43a33a33a333333c}, +}; +// clang-format on + +static const char kDigitTable[] = "0001020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849" + "5051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"; + +// x*y => 128-bit product (lo+hi) +inline uint64_t mul128(uint64_t x, uint64_t y, uint64_t* hi) +{ +#if defined(_MSC_VER) && defined(_M_X64) + return _umul128(x, y, hi); +#elif defined(__SIZEOF_INT128__) + unsigned __int128 r = x; + r *= y; + *hi = uint64_t(r >> 64); + return uint64_t(r); +#else + uint32_t x0 = uint32_t(x), x1 = uint32_t(x >> 32); + uint32_t y0 = uint32_t(y), y1 = uint32_t(y >> 32); + uint64_t p11 = uint64_t(x1) * y1, p01 = uint64_t(x0) * y1; + uint64_t p10 = uint64_t(x1) * y0, p00 = uint64_t(x0) * y0; + uint64_t mid = p10 + (p00 >> 32) + uint32_t(p01); + uint64_t r0 = (mid << 32) | uint32_t(p00); + uint64_t r1 = p11 + (mid >> 32) + (p01 >> 32); + *hi = r1; + return r0; +#endif +} + +// (x*y)>>64 => 128-bit product (lo+hi) +inline uint64_t mul192hi(uint64_t xhi, uint64_t xlo, uint64_t y, uint64_t* hi) +{ + uint64_t z2; + uint64_t z1 = mul128(xhi, y, &z2); + + uint64_t z1c; + uint64_t z0 = mul128(xlo, y, &z1c); + (void)z0; + + z1 += z1c; + z2 += (z1 < z1c); + + *hi = z2; + return z1; +} + +// 9.3. Rounding to odd (+ figure 8 + result 23) +inline uint64_t roundodd(uint64_t ghi, uint64_t glo, uint64_t cp) +{ + uint64_t xhi; + uint64_t xlo = mul128(glo, cp, &xhi); + (void)xlo; + + uint64_t yhi; + uint64_t ylo = mul128(ghi, cp, &yhi); + + uint64_t z = ylo + xhi; + return (yhi + (z < xhi)) | (z > 1); +} + +struct Decimal +{ + uint64_t s; + int k; +}; + +static Decimal schubfach(int exponent, uint64_t fraction) +{ + // Extract c & q such that c*2^q == |v| + uint64_t c = fraction; + int q = exponent - 1023 - 51; + + if (exponent != 0) // normal numbers have implicit leading 1 + { + c |= (1ull << 52); + q--; + } + + // 8.3. Fast path for integers + if (unsigned(-q) < 53 && (c & ((1ull << (-q)) - 1)) == 0) + return {c >> (-q), 0}; + + // 5. Rounding interval + int irr = (c == (1ull << 52) && q != -1074); // Qmin + int out = int(c & 1); + + // 9.8.1. Boundaries for c + uint64_t cbl = 4 * c - 2 + irr; + uint64_t cb = 4 * c; + uint64_t cbr = 4 * c + 2; + + // 9.1. Computing k and h + const int Q = 20; + const int C = 315652; // floor(2^Q * log10(2)) + const int A = -131008; // floor(2^Q * log10(3/4)) + const int C2 = 3483294; // floor(2^Q * log2(10)) + int k = (q * C + (irr ? A : 0)) >> Q; + int h = q + ((-k * C2) >> Q) + 1; // see (9) in 9.9 + + // 9.8.2. Overestimates of powers of 10 + // Recover 10^-k fraction using compact tables generated by tools/numutils.py + // The 128-bit fraction is encoded as 128-bit baseline * power-of-5 * scale + offset + LUAU_ASSERT(-k >= kPow10TableMin && -k <= kPow10TableMax); + int gtoff = -k - kPow10TableMin; + const uint64_t* gt = kPow10Table[gtoff >> 4]; + + uint64_t ghi; + uint64_t glo = mul192hi(gt[0], gt[1], kPow5Table[gtoff & 15], &ghi); + + // Apply 1-bit scale + 3-bit offset; note, offset is intentionally applied without carry, numutils.py validates that this is sufficient + int gterr = (gt[2] >> ((gtoff & 15) * 4)) & 15; + int gtscale = gterr >> 3; + + ghi <<= gtscale; + ghi += (glo >> 63) & gtscale; + glo <<= gtscale; + glo -= (gterr & 7) - 4; + + // 9.9. Boundaries for v + uint64_t vbl = roundodd(ghi, glo, cbl << h); + uint64_t vb = roundodd(ghi, glo, cb << h); + uint64_t vbr = roundodd(ghi, glo, cbr << h); + + // Main algorithm; see figure 7 + figure 9 + uint64_t s = vb / 4; + + if (s >= 10) + { + uint64_t sp = s / 10; + + bool upin = vbl + out <= 40 * sp; + bool wpin = vbr >= 40 * sp + 40 + out; + + if (upin != wpin) + return {sp + wpin, k + 1}; + } + + // Figure 7 contains the algorithm to select between u (s) and w (s+1) + // rup computes the last 4 conditions in that algorithm + // rup is only used when uin == win, but since these branches predict poorly we use branchless selects + bool uin = vbl + out <= 4 * s; + bool win = 4 * s + 4 + out <= vbr; + bool rup = vb >= 4 * s + 2 + 1 - (s & 1); + + return {s + (uin != win ? win : rup), k}; +} + +static char* printspecial(char* buf, int sign, uint64_t fraction) +{ + if (fraction == 0) + { + memcpy(buf, ("-inf") + (1 - sign), 4); + return buf + 3 + sign; + } + else + { + memcpy(buf, "nan", 4); + return buf + 3; + } +} + +static char* printunsignedrev(char* end, uint64_t num) +{ + while (num >= 10000) + { + unsigned int tail = unsigned(num % 10000); + + memcpy(end - 4, &kDigitTable[int(tail / 100) * 2], 2); + memcpy(end - 2, &kDigitTable[int(tail % 100) * 2], 2); + num /= 10000; + end -= 4; + } + + unsigned int rest = unsigned(num); + + while (rest >= 10) + { + memcpy(end - 2, &kDigitTable[int(rest % 100) * 2], 2); + rest /= 100; + end -= 2; + } + + if (rest) + { + end[-1] = '0' + int(rest); + end -= 1; + } + + return end; +} + +static char* printexp(char* buf, int num) +{ + *buf++ = 'e'; + *buf++ = num < 0 ? '-' : '+'; + + int v = num < 0 ? -num : num; + + if (v >= 100) + { + *buf++ = '0' + (v / 100); + v %= 100; + } + + memcpy(buf, &kDigitTable[v * 2], 2); + return buf + 2; +} + +inline char* trimzero(char* end) +{ + while (end[-1] == '0') + end--; + + return end; +} + +// We use fixed-length memcpy/memset since they lower to fast SIMD+scalar writes; the target buffers should have padding space +#define fastmemcpy(dst, src, size, sizefast) check_exp((size) <= sizefast, memcpy(dst, src, sizefast)) +#define fastmemset(dst, val, size, sizefast) check_exp((size) <= sizefast, memset(dst, val, sizefast)) + +char* luai_num2str(char* buf, double n) +{ + // IEEE-754 + union + { + double v; + uint64_t bits; + } v = {n}; + int sign = int(v.bits >> 63); + int exponent = int(v.bits >> 52) & 2047; + uint64_t fraction = v.bits & ((1ull << 52) - 1); + + // specials + if (LUAU_UNLIKELY(exponent == 0x7ff)) + return printspecial(buf, sign, fraction); + + // sign bit + *buf = '-'; + buf += sign; + + // zero + if (exponent == 0 && fraction == 0) + { + buf[0] = '0'; + return buf + 1; + } + + // convert binary to decimal using Schubfach + Decimal d = schubfach(exponent, fraction); + LUAU_ASSERT(d.s < uint64_t(1e17)); + + // print the decimal to a temporary buffer; we'll need to insert the decimal point and figure out the format + char decbuf[40]; + char* decend = decbuf + 20; // significand needs at most 17 digits; the rest of the buffer may be copied using fixed length memcpy + char* dec = printunsignedrev(decend, d.s); + + int declen = int(decend - dec); + LUAU_ASSERT(declen <= 17); + + int dot = declen + d.k; + + // the limits are somewhat arbitrary but changing them may require changing fastmemset/fastmemcpy sizes below + if (dot >= -5 && dot <= 21) + { + // fixed point format + if (dot <= 0) + { + buf[0] = '0'; + buf[1] = '.'; + + fastmemset(buf + 2, '0', -dot, 5); + fastmemcpy(buf + 2 + (-dot), dec, declen, 17); + + return trimzero(buf + 2 + (-dot) + declen); + } + else if (dot == declen) + { + // no dot + fastmemcpy(buf, dec, dot, 17); + + return buf + dot; + } + else if (dot < declen) + { + // dot in the middle + fastmemcpy(buf, dec, dot, 16); + + buf[dot] = '.'; + + fastmemcpy(buf + dot + 1, dec + dot, declen - dot, 16); + + return trimzero(buf + declen + 1); + } + else + { + // no dot, zero padding + fastmemcpy(buf, dec, declen, 17); + fastmemset(buf + declen, '0', dot - declen, 8); + + return buf + dot; + } + } + else + { + // scientific format + buf[0] = dec[0]; + buf[1] = '.'; + fastmemcpy(buf + 2, dec + 1, declen - 1, 16); + + char* exp = trimzero(buf + declen + 1); + + if (exp[-1] == '.') + exp--; + + return printexp(exp, dot - 1); + } +} diff --git a/thirdparty/luau/upstream/VM/src/lnumutils.h b/thirdparty/luau/upstream/VM/src/lnumutils.h new file mode 100644 index 000000000..53c563e79 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lnumutils.h @@ -0,0 +1,85 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include + +#define luai_numadd(a, b) ((a) + (b)) +#define luai_numsub(a, b) ((a) - (b)) +#define luai_nummul(a, b) ((a) * (b)) +#define luai_numdiv(a, b) ((a) / (b)) +#define luai_numpow(a, b) (pow(a, b)) +#define luai_numunm(a) (-(a)) +#define luai_numisnan(a) ((a) != (a)) +#define luai_numeq(a, b) ((a) == (b)) +#define luai_numlt(a, b) ((a) < (b)) +#define luai_numle(a, b) ((a) <= (b)) + +inline bool luai_veceq(const float* a, const float* b) +{ +#if LUA_VECTOR_SIZE == 4 + return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]; +#else + return a[0] == b[0] && a[1] == b[1] && a[2] == b[2]; +#endif +} + +inline bool luai_vecisnan(const float* a) +{ +#if LUA_VECTOR_SIZE == 4 + return a[0] != a[0] || a[1] != a[1] || a[2] != a[2] || a[3] != a[3]; +#else + return a[0] != a[0] || a[1] != a[1] || a[2] != a[2]; +#endif +} + +inline float luaui_signf(float v) +{ + return v > 0.0f ? 1.0f : v < 0.0f ? -1.0f : 0.0f; +} + +inline float luaui_clampf(float v, float min, float max) +{ + float r = v < min ? min : v; + return r > max ? max : r; +} + +LUAU_FASTMATH_BEGIN +inline double luai_nummod(double a, double b) +{ + return a - floor(a / b) * b; +} +LUAU_FASTMATH_END + +LUAU_FASTMATH_BEGIN +inline double luai_numidiv(double a, double b) +{ + return floor(a / b); +} +LUAU_FASTMATH_END + +inline float luai_lerpf(float a, float b, float t) +{ + return (t == 1.0) ? b : a + (b - a) * t; +} + +#define luai_num2int(i, d) ((i) = (int)(d)) + +// On MSVC in 32-bit, double to unsigned cast compiles into a call to __dtoui3, so we invoke x87->int64 conversion path manually +#if defined(_MSC_VER) && defined(_M_IX86) +#define luai_num2unsigned(i, n) \ + { \ + __int64 l; \ + __asm { __asm fld n __asm fistp l} \ + ; \ + i = (unsigned int)l; \ + } +#else +#define luai_num2unsigned(i, n) ((i) = (unsigned)(long long)(n)) +#endif + +#define LUAI_MAXNUM2STR 48 + +LUAI_FUNC char* luai_num2str(char* buf, double n); + +#define luai_str2num(s, p) strtod((s), (p)) diff --git a/thirdparty/luau/upstream/VM/src/lobject.cpp b/thirdparty/luau/upstream/VM/src/lobject.cpp new file mode 100644 index 000000000..e4202d700 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lobject.cpp @@ -0,0 +1,162 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lobject.h" + +#include "lstate.h" +#include "lstring.h" +#include "lgc.h" +#include "ldo.h" +#include "lnumutils.h" + +#include +#include +#include +#include + +const TValue luaO_nilobject_ = {{NULL}, {0}, LUA_TNIL}; + +int luaO_log2(unsigned int x) +{ + static const uint8_t log_2[256] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 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, 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}; + int l = -1; + while (x >= 256) + { + l += 8; + x >>= 8; + } + return l + log_2[x]; +} + +int luaO_rawequalObj(const TValue* t1, const TValue* t2) +{ + if (ttype(t1) != ttype(t2)) + return 0; + else + switch (ttype(t1)) + { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TVECTOR: + return luai_veceq(vvalue(t1), vvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); // boolean true must be 1 !! + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2) && lightuserdatatag(t1) == lightuserdatatag(t2); + default: + LUAU_ASSERT(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + +int luaO_rawequalKey(const TKey* t1, const TValue* t2) +{ + if (ttype(t1) != ttype(t2)) + return 0; + else + switch (ttype(t1)) + { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TVECTOR: + return luai_veceq(vvalue(t1), vvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); // boolean true must be 1 !! + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2) && lightuserdatatag(t1) == lightuserdatatag(t2); + default: + LUAU_ASSERT(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + +int luaO_str2d(const char* s, double* result) +{ + char* endptr; + *result = luai_str2num(s, &endptr); + if (endptr == s) + return 0; // conversion failed + if (*endptr == 'x' || *endptr == 'X') // maybe an hexadecimal constant? + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') + return 1; // most common case + while (isspace(cast_to(unsigned char, *endptr))) + endptr++; + if (*endptr != '\0') + return 0; // invalid trailing characters? + return 1; +} + +const char* luaO_pushvfstring(lua_State* L, const char* fmt, va_list argp) +{ + char result[LUA_BUFFERSIZE]; + vsnprintf(result, sizeof(result), fmt, argp); + + setsvalue(L, L->top, luaS_new(L, result)); + incr_top(L); + return svalue(L->top - 1); +} + +const char* luaO_pushfstring(lua_State* L, const char* fmt, ...) +{ + const char* msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + +// Possible chunkname prefixes: +// +// '=' prefix: meant to represent custom chunknames. When truncation is needed, +// the beginning of the chunkname is kept. +// +// '@' prefix: meant to represent filepaths. When truncation is needed, the end +// of the filepath is kept, as this is more useful for identifying the file. +const char* luaO_chunkid(char* buf, size_t buflen, const char* source, size_t srclen) +{ + if (*source == '=') + { + if (srclen <= buflen) + return source + 1; + // truncate the part after = + memcpy(buf, source + 1, buflen - 1); + buf[buflen - 1] = '\0'; + } + else if (*source == '@') + { + if (srclen <= buflen) + return source + 1; + // truncate the part after @ + memcpy(buf, "...", 3); + memcpy(buf + 3, source + srclen - (buflen - 4), buflen - 4); + buf[buflen - 1] = '\0'; + } + else + { // buf = [string "string"] + size_t len = strcspn(source, "\n\r"); // stop at first newline + buflen -= sizeof("[string \"...\"]"); + if (len > buflen) + len = buflen; + strcpy(buf, "[string \""); + if (source[len] != '\0') + { // must truncate? + strncat(buf, source, len); + strcat(buf, "..."); + } + else + strcat(buf, source); + strcat(buf, "\"]"); + } + return buf; +} diff --git a/thirdparty/luau/upstream/VM/src/lobject.h b/thirdparty/luau/upstream/VM/src/lobject.h new file mode 100644 index 000000000..11db0bf2e --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lobject.h @@ -0,0 +1,491 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lua.h" +#include "lcommon.h" + +/* +** Union of all collectible objects +*/ +typedef union GCObject GCObject; + +/* +** Common Header for all collectible objects (in macro form, to be included in other objects) +*/ +// clang-format off +#define CommonHeader \ + uint8_t tt; uint8_t marked; uint8_t memcat +// clang-format on + +/* +** Common header in struct form +*/ +typedef struct GCheader +{ + CommonHeader; +} GCheader; + +/* +** Union of all Lua values +*/ +typedef union +{ + GCObject* gc; + void* p; + double n; + int b; + float v[2]; // v[0], v[1] live here; v[2] lives in TValue::extra +} Value; + +/* +** Tagged Values +*/ + +typedef struct lua_TValue +{ + Value value; + int extra[LUA_EXTRA_SIZE]; + int tt; +} TValue; + +// Macros to test type +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttisbuffer(o) (ttype(o) == LUA_TBUFFER) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) +#define ttisvector(o) (ttype(o) == LUA_TVECTOR) +#define ttisupval(o) (ttype(o) == LUA_TUPVAL) + +// Macros to access values +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define vvalue(o) check_exp(ttisvector(o), (o)->value.v) +#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) +#define bufvalue(o) check_exp(ttisbuffer(o), &(o)->value.gc->buf) +#define upvalue(o) check_exp(ttisupval(o), &(o)->value.gc->uv) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +#define lightuserdatatag(o) check_exp(ttislightuserdata(o), (o)->extra[0]) + +// Internal tags used by the VM +#define LU_TAG_ITERATOR LUA_UTAG_LIMIT + +/* +** for internal debug only +*/ +#define checkconsistency(obj) LUAU_ASSERT(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define checkliveness(g, obj) LUAU_ASSERT(!iscollectable(obj) || ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + +// Macros to set values +#define setnilvalue(obj) ((obj)->tt = LUA_TNIL) + +#define setnvalue(obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.n = (x); \ + i_o->tt = LUA_TNUMBER; \ + } + +#if LUA_VECTOR_SIZE == 4 +#define setvvalue(obj, x, y, z, w) \ + { \ + TValue* i_o = (obj); \ + float* i_v = i_o->value.v; \ + i_v[0] = (x); \ + i_v[1] = (y); \ + i_v[2] = (z); \ + i_v[3] = (w); \ + i_o->tt = LUA_TVECTOR; \ + } +#else +#define setvvalue(obj, x, y, z, w) \ + { \ + TValue* i_o = (obj); \ + float* i_v = i_o->value.v; \ + i_v[0] = (x); \ + i_v[1] = (y); \ + i_v[2] = (z); \ + i_o->tt = LUA_TVECTOR; \ + } +#endif + +#define setpvalue(obj, x, tag) \ + { \ + TValue* i_o = (obj); \ + i_o->value.p = (x); \ + i_o->extra[0] = (tag); \ + i_o->tt = LUA_TLIGHTUSERDATA; \ + } + +#define setbvalue(obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.b = (x); \ + i_o->tt = LUA_TBOOLEAN; \ + } + +#define setsvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TSTRING; \ + checkliveness(L->global, i_o); \ + } + +#define setuvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TUSERDATA; \ + checkliveness(L->global, i_o); \ + } + +#define setthvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TTHREAD; \ + checkliveness(L->global, i_o); \ + } + +#define setbufvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TBUFFER; \ + checkliveness(L->global, i_o); \ + } + +#define setclvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TFUNCTION; \ + checkliveness(L->global, i_o); \ + } + +#define sethvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TTABLE; \ + checkliveness(L->global, i_o); \ + } + +#define setptvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TPROTO; \ + checkliveness(L->global, i_o); \ + } + +#define setupvalue(L, obj, x) \ + { \ + TValue* i_o = (obj); \ + i_o->value.gc = cast_to(GCObject*, (x)); \ + i_o->tt = LUA_TUPVAL; \ + checkliveness(L->global, i_o); \ + } + +#define setobj(L, obj1, obj2) \ + { \ + const TValue* o2 = (obj2); \ + TValue* o1 = (obj1); \ + *o1 = *o2; \ + checkliveness(L->global, o1); \ + } + +/* +** different types of sets, according to destination +*/ + +// to stack +#define setobj2s setobj +// from table to same table (no barrier) +#define setobjt2t setobj +// to table (needs barrier) +#define setobj2t setobj +// to new object (no barrier) +#define setobj2n setobj + +#define setttype(obj, tt) (ttype(obj) = (tt)) + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + +typedef TValue* StkId; // index to stack elements + +/* +** String headers for string table +*/ +typedef struct TString +{ + CommonHeader; + // 1 byte padding + + int16_t atom; + + // 2 byte padding + + TString* next; // next string in the hash table bucket + + unsigned int hash; + unsigned int len; + + char data[1]; // string data is allocated right after the header +} TString; + + +#define getstr(ts) (ts)->data +#define svalue(o) getstr(tsvalue(o)) + +typedef struct Udata +{ + CommonHeader; + + uint8_t tag; + + int len; + + struct LuaTable* metatable; + + // userdata is allocated right after the header + // while the alignment is only 8 here, for sizes starting at 16 bytes, 16 byte alignment is provided + alignas(8) char data[1]; +} Udata; + +typedef struct LuauBuffer +{ + CommonHeader; + + unsigned int len; + + alignas(8) char data[1]; +} Buffer; + +/* +** Function Prototypes +*/ +// clang-format off +typedef struct Proto +{ + CommonHeader; + + uint8_t nups; // number of upvalues + uint8_t numparams; + uint8_t is_vararg; + uint8_t maxstacksize; + uint8_t flags; + + TValue* k; // constants used by the function + Instruction* code; // function bytecode + struct Proto** p; // functions defined inside the function + const Instruction* codeentry; + + void* execdata; + uintptr_t exectarget; + + uint8_t* lineinfo; // for each instruction, line number as a delta from baseline + int* abslineinfo; // baseline line info, one entry for each 1<v != &(up)->u.value) + +/* +** Closures +*/ + +typedef struct Closure +{ + CommonHeader; + + uint8_t isC; + uint8_t nupvalues; + uint8_t stacksize; + uint8_t preload; + + GCObject* gclist; + struct LuaTable* env; + + union + { + struct + { + lua_CFunction f; + lua_Continuation cont; + const char* debugname; + TValue upvals[1]; + } c; + + struct + { + struct Proto* p; + TValue uprefs[1]; + } l; + }; +} Closure; + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->isC) + +/* +** Tables +*/ + +typedef struct TKey +{ + ::Value value; + int extra[LUA_EXTRA_SIZE]; + unsigned tt : 4; + int next : 28; // for chaining +} TKey; + +typedef struct LuaNode +{ + TValue val; + TKey key; +} LuaNode; + +// copy a value into a key +#define setnodekey(L, node, obj) \ + { \ + LuaNode* n_ = (node); \ + const TValue* i_o = (obj); \ + n_->key.value = i_o->value; \ + memcpy(n_->key.extra, i_o->extra, sizeof(n_->key.extra)); \ + n_->key.tt = i_o->tt; \ + checkliveness(L->global, i_o); \ + } + +// copy a value from a key +#define getnodekey(L, obj, node) \ + { \ + TValue* i_o = (obj); \ + const LuaNode* n_ = (node); \ + i_o->value = n_->key.value; \ + memcpy(i_o->extra, n_->key.extra, sizeof(i_o->extra)); \ + i_o->tt = n_->key.tt; \ + checkliveness(L->global, i_o); \ + } + +// clang-format off +typedef struct LuaTable +{ + CommonHeader; + + uint8_t tmcache; // 1<

lsizenode)) + +#define luaO_nilobject (&luaO_nilobject_) + +LUAI_DATA const TValue luaO_nilobject_; + +#define ceillog2(x) (luaO_log2((x)-1) + 1) + +LUAI_FUNC int luaO_log2(unsigned int x); +LUAI_FUNC int luaO_rawequalObj(const TValue* t1, const TValue* t2); +LUAI_FUNC int luaO_rawequalKey(const TKey* t1, const TValue* t2); +LUAI_FUNC int luaO_str2d(const char* s, double* result); +LUAI_FUNC const char* luaO_pushvfstring(lua_State* L, const char* fmt, va_list argp); +LUAI_FUNC const char* luaO_pushfstring(lua_State* L, const char* fmt, ...); +LUAI_FUNC const char* luaO_chunkid(char* buf, size_t buflen, const char* source, size_t srclen); diff --git a/thirdparty/luau/upstream/VM/src/loslib.cpp b/thirdparty/luau/upstream/VM/src/loslib.cpp new file mode 100644 index 000000000..a3365558e --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/loslib.cpp @@ -0,0 +1,225 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lcommon.h" + +#include +#include + +#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYzZ%" + +#if defined(_WIN32) +static tm* gmtime_r(const time_t* timep, tm* result) +{ + return gmtime_s(result, timep) == 0 ? result : NULL; +} + +static tm* localtime_r(const time_t* timep, tm* result) +{ + return localtime_s(result, timep) == 0 ? result : NULL; +} +#endif + +static time_t os_timegm(struct tm* timep) +{ + // Julian day number calculation + int day = timep->tm_mday; + int month = timep->tm_mon + 1; + int year = timep->tm_year + 1900; + + // year adjustment, pretend that it starts in March + int a = timep->tm_mon % 12 < 2 ? 1 : 0; + + // also adjust for out-of-range month numbers in input + a -= timep->tm_mon / 12; + + int y = year + 4800 - a; + int m = month + (12 * a) - 3; + + int julianday = day + ((153 * m + 2) / 5) + (365 * y) + (y / 4) - (y / 100) + (y / 400) - 32045; + + const int utcstartasjulianday = 2440588; // Jan 1st 1970 offset in Julian calendar + const int64_t utcstartasjuliansecond = utcstartasjulianday * 86400ll; // same in seconds + + // fail the dates before UTC start + if (julianday < utcstartasjulianday) + return time_t(-1); + + int64_t daysecond = timep->tm_hour * 3600ll + timep->tm_min * 60ll + timep->tm_sec; + int64_t julianseconds = int64_t(julianday) * 86400ull + daysecond; + + if (julianseconds < utcstartasjuliansecond) + return time_t(-1); + + int64_t utc = julianseconds - utcstartasjuliansecond; + return time_t(utc); +} + +static int os_clock(lua_State* L) +{ + lua_pushnumber(L, lua_clock()); + return 1; +} + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield(lua_State* L, const char* key, int value) +{ + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield(lua_State* L, const char* key, int value) +{ + if (value < 0) // undefined? + return; // does not set field + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield(lua_State* L, const char* key) +{ + int res; + lua_rawgetfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + +static int getfield(lua_State* L, const char* key, int d) +{ + int res; + lua_rawgetfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else + { + if (d < 0) + luaL_error(L, "field '%s' missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + +static int os_date(lua_State* L) +{ + const char* s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + + struct tm tm; + struct tm* stm; + if (*s == '!') + { // UTC? + stm = gmtime_r(&t, &tm); + s++; // skip `!' + } + else + { + // on Windows, localtime() fails with dates before epoch start so we disallow that + stm = t < 0 ? NULL : localtime_r(&t, &tm); + } + + if (stm == NULL) // invalid date? + { + lua_pushnil(L); + } + else if (strcmp(s, "*t") == 0) + { + lua_createtable(L, 0, 9); // 9 = number of fields + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon + 1); + setfield(L, "year", stm->tm_year + 1900); + setfield(L, "wday", stm->tm_wday + 1); + setfield(L, "yday", stm->tm_yday + 1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else + { + char cc[3]; + cc[0] = '%'; + cc[2] = '\0'; + + luaL_Strbuf b; + luaL_buffinit(L, &b); + for (; *s; s++) + { + if (*s != '%' || *(s + 1) == '\0') // no conversion specifier? + { + luaL_addchar(&b, *s); + } + else if (strchr(LUA_STRFTIMEOPTIONS, *(s + 1)) == 0) + { + luaL_argerror(L, 1, "invalid conversion specifier"); + } + else + { + size_t reslen; + char buff[200]; // should be big enough for any conversion result + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + +static int os_time(lua_State* L) +{ + time_t t; + if (lua_isnoneornil(L, 1)) // called without args? + t = time(NULL); // get current time + else + { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); // make sure table is at the top + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + + // Note: upstream Lua uses mktime() here which assumes input is local time, but we prefer UTC for consistency + t = os_timegm(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (double)t); + return 1; +} + +static int os_difftime(lua_State* L) +{ + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"time", os_time}, + {NULL, NULL}, +}; + +int luaopen_os(lua_State* L) +{ + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lperf.cpp b/thirdparty/luau/upstream/VM/src/lperf.cpp new file mode 100644 index 000000000..f9585fb53 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lperf.cpp @@ -0,0 +1,69 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lua.h" + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#endif + +#ifdef __APPLE__ +#include +#include +#endif + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include + +static double clock_period() +{ +#if defined(_WIN32) + LARGE_INTEGER result = {}; + QueryPerformanceFrequency(&result); + return 1.0 / double(result.QuadPart); +#elif defined(__APPLE__) + mach_timebase_info_data_t result = {}; + mach_timebase_info(&result); + return double(result.numer) / double(result.denom) * 1e-9; +#elif defined(__linux__) || defined(__FreeBSD__) + return 1e-9; +#elif defined(__EMSCRIPTEN__) + return 1e-3; +#else + return 1.0 / double(CLOCKS_PER_SEC); +#endif +} + +static double clock_timestamp() +{ +#if defined(_WIN32) + LARGE_INTEGER result = {}; + QueryPerformanceCounter(&result); + return double(result.QuadPart); +#elif defined(__APPLE__) + return double(mach_absolute_time()); +#elif defined(__linux__) || defined(__FreeBSD__) + timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + return now.tv_sec * 1e9 + now.tv_nsec; +#elif defined(__EMSCRIPTEN__) + return emscripten_get_now(); +#else + return double(clock()); +#endif +} + +double lua_clock() +{ + static double period = clock_period(); + + return clock_timestamp() * period; +} diff --git a/thirdparty/luau/upstream/VM/src/lstate.cpp b/thirdparty/luau/upstream/VM/src/lstate.cpp new file mode 100644 index 000000000..5f5490aa4 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lstate.cpp @@ -0,0 +1,252 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lstate.h" + +#include "ltable.h" +#include "lstring.h" +#include "lfunc.h" +#include "lmem.h" +#include "lgc.h" +#include "ldo.h" +#include "ldebug.h" + +#include + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG +{ + lua_State l; + global_State g; +} LG; + +static void stack_init(lua_State* L1, lua_State* L) +{ + // initialize CallInfo array + L1->base_ci = luaM_newarray(L, BASIC_CI_SIZE, CallInfo, L1->memcat); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + // initialize stack array + L1->stack = luaM_newarray(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue, L1->memcat); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + TValue* stack = L1->stack; + for (int i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) + setnilvalue(stack + i); // erase new stack + L1->top = stack; + L1->stack_last = stack + (L1->stacksize - EXTRA_STACK); + // initialize first ci + L1->ci->func = L1->top; + setnilvalue(L1->top++); // `function' entry for this `ci' + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; +} + +static void freestack(lua_State* L, lua_State* L1) +{ + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo, L1->memcat); + luaM_freearray(L, L1->stack, L1->stacksize, TValue, L1->memcat); +} + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen(lua_State* L, void* ud) +{ + global_State* g = L->global; + stack_init(L, L); // init stack + L->gt = luaH_new(L, 0, 2); // table of globals + sethvalue(L, registry(L), luaH_new(L, 0, 2)); // registry + luaS_resize(L, LUA_MINSTRTABSIZE); // initial size of string table + luaT_init(L); + luaS_fix(luaS_newliteral(L, LUA_MEMERRMSG)); // pin to make sure we can always throw this error + luaS_fix(luaS_newliteral(L, LUA_ERRERRMSG)); // pin to make sure we can always throw this error + g->GCthreshold = 4 * g->totalbytes; +} + +static void preinit_state(lua_State* L, global_State* g) +{ + L->global = g; + L->stack = NULL; + L->stacksize = 0; + L->gt = NULL; + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->namecall = NULL; + L->cachedslot = 0; + L->singlestep = false; + L->isactive = false; + L->activememcat = 0; + L->userdata = NULL; +} + +static void close_state(lua_State* L) +{ + global_State* g = L->global; + luaF_close(L, L->stack); // close all upvalues for this thread + luaC_freeall(L); // collect all objects + LUAU_ASSERT(g->strt.nuse == 0); + luaM_freearray(L, L->global->strt.hash, L->global->strt.size, TString*, 0); + freestack(L, L); + for (int i = 0; i < LUA_SIZECLASSES; i++) + { + LUAU_ASSERT(g->freepages[i] == NULL); + LUAU_ASSERT(g->freegcopages[i] == NULL); + } + LUAU_ASSERT(g->allgcopages == NULL); + LUAU_ASSERT(g->totalbytes == sizeof(LG)); + LUAU_ASSERT(g->memcatbytes[0] == sizeof(LG)); + for (int i = 1; i < LUA_MEMORY_CATEGORIES; i++) + LUAU_ASSERT(g->memcatbytes[i] == 0); + + if (L->global->ecb.close) + L->global->ecb.close(L); + + (*g->frealloc)(g->ud, L, sizeof(LG), 0); +} + +lua_State* luaE_newthread(lua_State* L) +{ + lua_State* L1 = luaM_newgco(L, lua_State, sizeof(lua_State), L->activememcat); + luaC_init(L, L1, LUA_TTHREAD); + preinit_state(L1, L->global); + L1->activememcat = L->activememcat; // inherit the active memory category + stack_init(L1, L); // init stack + L1->gt = L->gt; // share table of globals + L1->singlestep = L->singlestep; + LUAU_ASSERT(iswhite(obj2gco(L1))); + return L1; +} + +void luaE_freethread(lua_State* L, lua_State* L1, lua_Page* page) +{ + global_State* g = L->global; + if (g->cb.userthread) + g->cb.userthread(NULL, L1); + freestack(L, L1); + luaM_freegco(L, L1, sizeof(lua_State), L1->memcat, page); +} + +void lua_resetthread(lua_State* L) +{ + // close upvalues before clearing anything + luaF_close(L, L->stack); + // clear call frames + CallInfo* ci = L->base_ci; + ci->func = L->stack; + ci->base = ci->func + 1; + ci->top = ci->base + LUA_MINSTACK; + setnilvalue(ci->func); + L->ci = ci; + if (L->size_ci != BASIC_CI_SIZE) + luaD_reallocCI(L, BASIC_CI_SIZE); + // clear thread state + L->status = LUA_OK; + L->base = L->ci->base; + L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + // clear thread stack + if (L->stacksize != BASIC_STACK_SIZE + EXTRA_STACK) + luaD_reallocstack(L, BASIC_STACK_SIZE, 0); + for (int i = 0; i < L->stacksize; i++) + setnilvalue(L->stack + i); +} + +int lua_isthreadreset(lua_State* L) +{ + return L->ci == L->base_ci && L->base == L->top && L->status == LUA_OK; +} + +lua_State* lua_newstate(lua_Alloc f, void* ud) +{ + int i; + lua_State* L; + global_State* g; + void* l = (*f)(ud, NULL, 0, sizeof(LG)); + if (l == NULL) + return NULL; + L = (lua_State*)l; + g = &((LG*)L)->g; + L->tt = LUA_TTHREAD; + L->marked = g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->memcat = 0; + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.open.prev = &g->uvhead; + g->uvhead.u.open.next = &g->uvhead; + g->GCthreshold = 0; // mark it as unfinished state + g->registryfree = 0; + g->errorjmp = NULL; + g->rngstate = 0; + g->ptrenckey[0] = 1; + g->ptrenckey[1] = 0; + g->ptrenckey[2] = 0; + g->ptrenckey[3] = 0; + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->pseudotemp); + setnilvalue(registry(L)); + g->gcstate = GCSpause; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->totalbytes = sizeof(LG); + g->gcgoal = LUAI_GCGOAL; + g->gcstepmul = LUAI_GCSTEPMUL; + g->gcstepsize = LUAI_GCSTEPSIZE << 10; + for (i = 0; i < LUA_SIZECLASSES; i++) + { + g->freepages[i] = NULL; + g->freegcopages[i] = NULL; + } + g->allpages = NULL; + g->allgcopages = NULL; + g->sweepgcopage = NULL; + for (i = 0; i < LUA_T_COUNT; i++) + g->mt[i] = NULL; + for (i = 0; i < LUA_UTAG_LIMIT; i++) + { + g->udatagc[i] = NULL; + g->udatamt[i] = NULL; + } + for (i = 0; i < LUA_LUTAG_LIMIT; i++) + g->lightuserdataname[i] = NULL; + for (i = 0; i < LUA_MEMORY_CATEGORIES; i++) + g->memcatbytes[i] = 0; + + g->memcatbytes[0] = sizeof(LG); + + g->cb = lua_Callbacks(); + + g->ecb = lua_ExecutionCallbacks(); + + memset(g->ecbdata, 0, LUA_EXECUTION_CALLBACK_STORAGE * sizeof(g->ecbdata[0])); + + g->gcstats = GCStats(); + +#ifdef LUAI_GCMETRICS + g->gcmetrics = GCMetrics(); +#endif + + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) + { + // memory allocation error: free partial state + close_state(L); + L = NULL; + } + return L; +} + +void lua_close(lua_State* L) +{ + L = L->global->mainthread; // only the main thread can be closed + luaF_close(L, L->stack); // close all upvalues for this thread + close_state(L); +} diff --git a/thirdparty/luau/upstream/VM/src/lstate.h b/thirdparty/luau/upstream/VM/src/lstate.h new file mode 100644 index 000000000..6a530fdcd --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lstate.h @@ -0,0 +1,305 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" +#include "ltm.h" + +// registry +#define registry(L) (&L->global->registry) + +// extra stack space to handle TM calls and some other extras +#define EXTRA_STACK 5 + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2 * LUA_MINSTACK) + +// clang-format off +typedef struct stringtable +{ + TString** hash; + uint32_t nuse; // number of elements + int size; +} stringtable; +// clang-format on + +/* +** informations about a call +** +** the general Lua stack frame structure is as follows: +** - each function gets a stack frame, with function "registers" being stack slots on the frame +** - function arguments are associated with registers 0+ +** - function locals and temporaries follow after; usually locals are a consecutive block per scope, and temporaries are allocated after this, but +*this is up to the compiler +** +** when function doesn't have varargs, the stack layout is as follows: +** ^ (func) ^^ [fixed args] [locals + temporaries] +** where ^ is the 'func' pointer in CallInfo struct, and ^^ is the 'base' pointer (which is what registers are relative to) +** +** when function *does* have varargs, the stack layout is more complex - the runtime has to copy the fixed arguments so that the 0+ addressing still +*works as follows: +** ^ (func) [fixed args] [varargs] ^^ [fixed args] [locals + temporaries] +** +** computing the sizes of these individual blocks works as follows: +** - the number of fixed args is always matching the `numparams` in a function's Proto object; runtime adds `nil` during the call execution as +*necessary +** - the number of variadic args can be computed by evaluating (ci->base - ci->func - 1 - numparams) +** +** the CallInfo structures are allocated as an array, with each subsequent call being *appended* to this array (so if f calls g, CallInfo for g +*immediately follows CallInfo for f) +** the `nresults` field in CallInfo is set by the caller to tell the function how many arguments the caller is expecting on the stack after the +*function returns +** the `flags` field in CallInfo contains internal execution flags that are important for pcall/etc, see LUA_CALLINFO_* +*/ +// clang-format off +typedef struct CallInfo +{ + StkId base; // base for this function + StkId func; // function index in the stack + StkId top; // top for this function + const Instruction* savedpc; + + int nresults; // expected number of results from this function + unsigned int flags; // call frame flags, see LUA_CALLINFO_* +} CallInfo; +// clang-format on + +#define LUA_CALLINFO_RETURN (1 << 0) // should the interpreter return after returning from this callinfo? first frame must have this set +#define LUA_CALLINFO_HANDLE (1 << 1) // should the error thrown during execution get handled by continuation from this callinfo? func must be C +#define LUA_CALLINFO_NATIVE (1 << 2) // should this function be executed using execution callback for native code + +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + +struct GCStats +{ + // data for proportional-integral controller of heap trigger value + int32_t triggerterms[32] = {0}; + uint32_t triggertermpos = 0; + int32_t triggerintegral = 0; + + size_t atomicstarttotalsizebytes = 0; + size_t endtotalsizebytes = 0; + size_t heapgoalsizebytes = 0; + + double starttimestamp = 0; + double atomicstarttimestamp = 0; + double endtimestamp = 0; +}; + +#ifdef LUAI_GCMETRICS +struct GCCycleMetrics +{ + size_t starttotalsizebytes = 0; + size_t heaptriggersizebytes = 0; + + double pausetime = 0.0; // time from end of the last cycle to the start of a new one + + double starttimestamp = 0.0; + double endtimestamp = 0.0; + + double marktime = 0.0; + double markassisttime = 0.0; + double markmaxexplicittime = 0.0; + size_t markexplicitsteps = 0; + size_t markwork = 0; + + double atomicstarttimestamp = 0.0; + size_t atomicstarttotalsizebytes = 0; + double atomictime = 0.0; + + // specific atomic stage parts + double atomictimeupval = 0.0; + double atomictimeweak = 0.0; + double atomictimegray = 0.0; + double atomictimeclear = 0.0; + + double sweeptime = 0.0; + double sweepassisttime = 0.0; + double sweepmaxexplicittime = 0.0; + size_t sweepexplicitsteps = 0; + size_t sweepwork = 0; + + size_t assistwork = 0; + size_t explicitwork = 0; + + size_t propagatework = 0; + size_t propagateagainwork = 0; + + size_t endtotalsizebytes = 0; +}; + +struct GCMetrics +{ + double stepexplicittimeacc = 0.0; + double stepassisttimeacc = 0.0; + + // when cycle is completed, last cycle values are updated + uint64_t completedcycles = 0; + + GCCycleMetrics lastcycle; + GCCycleMetrics currcycle; +}; +#endif + +// Callbacks that can be used to to redirect code execution from Luau bytecode VM to a custom implementation (AoT/JiT/sandboxing/...) +struct lua_ExecutionCallbacks +{ + void* context; + void (*close)(lua_State* L); // called when global VM state is closed + void (*destroy)(lua_State* L, Proto* proto); // called when function is destroyed + int (*enter)(lua_State* L, Proto* proto); // called when function is about to start/resume (when execdata is present), return 0 to exit VM + void (*disable)(lua_State* L, Proto* proto); // called when function has to be switched from native to bytecode in the debugger + size_t (*getmemorysize)(lua_State* L, Proto* proto); // called to request the size of memory associated with native part of the Proto + uint8_t (*gettypemapping)(lua_State* L, const char* str, size_t len); // called to get the userdata type index + char* (*getcounterdata)( + lua_State* L, + Proto* proto, + size_t* count + ); // called to get the execution counter data and count {uint32_t, uint32_t, uint64_t} +}; + +/* +** `global state', shared by all threads of this state +*/ +// clang-format off +typedef struct global_State +{ + stringtable strt; // hash table for strings + + lua_Alloc frealloc; // function to reallocate memory + void* ud; // auxiliary data to `frealloc' + + uint8_t currentwhite; + uint8_t gcstate; // state of garbage collector + + GCObject* gray; // list of gray objects + GCObject* grayagain; // list of objects to be traversed atomically + GCObject* weak; // list of weak tables (to be cleared) + + size_t GCthreshold; // when totalbytes >= GCthreshold, run GC step + size_t totalbytes; // number of bytes currently allocated + + int gcgoal; // see LUAI_GCGOAL + int gcstepmul; // see LUAI_GCSTEPMUL + int gcstepsize; // see LUAI_GCSTEPSIZE + + struct lua_Page* freepages[LUA_SIZECLASSES]; // free page linked list for each size class for non-collectable objects + struct lua_Page* freegcopages[LUA_SIZECLASSES]; // free page linked list for each size class for collectable objects + struct lua_Page* allpages; // page linked list with all pages for all non-collectable object classes (available with LUAU_ASSERTENABLED) + struct lua_Page* allgcopages; // page linked list with all pages for all collectable object classes + struct lua_Page* sweepgcopage; // position of the sweep in `allgcopages' + + struct lua_State* mainthread; + UpVal uvhead; // head of double-linked list of all open upvalues + struct LuaTable* mt[LUA_T_COUNT]; // metatables for basic types + TString* ttname[LUA_T_COUNT]; // names for basic types + TString* tmname[TM_N]; // array with tag-method names + + TValue pseudotemp; // storage for temporary values used in pseudo2addr + + TValue registry; // registry table, used by lua_ref and LUA_REGISTRYINDEX + int registryfree; // next free slot in registry + + struct lua_jmpbuf* errorjmp; // jump buffer data for longjmp-style error handling + + uint64_t rngstate; // PCG random number generator state + uint64_t ptrenckey[4]; // pointer encoding key for display + + lua_Callbacks cb; + + lua_ExecutionCallbacks ecb; + + alignas(16) uint8_t ecbdata[LUA_EXECUTION_CALLBACK_STORAGE]; + + size_t memcatbytes[LUA_MEMORY_CATEGORIES]; // total amount of memory used by each memory category + + void (*udatagc[LUA_UTAG_LIMIT])(lua_State*, void*); // for each userdata tag, a gc callback to be called immediately before freeing memory + LuaTable* udatamt[LUA_UTAG_LIMIT]; // metatables for tagged userdata + + TString* lightuserdataname[LUA_LUTAG_LIMIT]; // names for tagged lightuserdata + + GCStats gcstats; + +#ifdef LUAI_GCMETRICS + GCMetrics gcmetrics; +#endif +} global_State; +// clang-format on + +/* +** `per thread' state +*/ +// clang-format off +struct lua_State +{ + CommonHeader; + uint8_t status; + + uint8_t activememcat; // memory category that is used for new GC object allocations + + bool isactive; // thread is currently executing, stack may be mutated without barriers + bool singlestep; // call debugstep hook after each instruction + + StkId top; // first free slot in the stack + StkId base; // base of current function + global_State* global; + CallInfo* ci; // call info for current function + StkId stack_last; // last free slot in the stack + StkId stack; // stack base + + CallInfo* end_ci; // points after end of ci array + CallInfo* base_ci; // array of CallInfo's + + int stacksize; + int size_ci; // size of array `base_ci' + + unsigned short nCcalls; // number of nested C calls + unsigned short baseCcalls; // nested C calls when resuming coroutine + + int cachedslot; // when table operations or INDEX/NEWINDEX is invoked from Luau, what is the expected slot for lookup? + + LuaTable* gt; // table of globals + UpVal* openupval; // list of open upvalues in this stack + GCObject* gclist; + + TString* namecall; // when invoked from Luau using NAMECALL, what method do we need to invoke? + + void* userdata; +}; +// clang-format on + +/* +** Union of all collectible objects +*/ +union GCObject +{ + GCheader gch; + struct TString ts; + struct Udata u; + struct Closure cl; + struct LuaTable h; + struct Proto p; + struct UpVal uv; + struct lua_State th; // thread + struct LuauBuffer buf; +}; + +// macros to convert a GCObject into a specific value +#define gco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) +#define gco2buf(o) check_exp((o)->gch.tt == LUA_TBUFFER, &((o)->buf)) + +// macro to convert any Lua object into a GCObject +#define obj2gco(v) check_exp(iscollectable(v), cast_to(GCObject*, (v) + 0)) + +LUAI_FUNC lua_State* luaE_newthread(lua_State* L); +LUAI_FUNC void luaE_freethread(lua_State* L, lua_State* L1, struct lua_Page* page); diff --git a/thirdparty/luau/upstream/VM/src/lstring.cpp b/thirdparty/luau/upstream/VM/src/lstring.cpp new file mode 100644 index 000000000..e57f6c29e --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lstring.cpp @@ -0,0 +1,193 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lstring.h" + +#include "lgc.h" +#include "lmem.h" + +#include + +unsigned int luaS_hash(const char* str, size_t len) +{ + // Note that this hashing algorithm is replicated in BytecodeBuilder.cpp, BytecodeBuilder::getStringHash + unsigned int a = 0, b = 0; + unsigned int h = unsigned(len); + + // hash prefix in 12b chunks (using aligned reads) with ARX based hash (LuaJIT v2.1, lookup3) + // note that we stop at length<32 to maintain compatibility with Lua 5.1 + while (len >= 32) + { +#define rol(x, s) ((x >> s) | (x << (32 - s))) +#define mix(u, v, w) a ^= h, a -= rol(h, u), b ^= a, b -= rol(a, v), h ^= b, h -= rol(b, w) + + // should compile into fast unaligned reads + uint32_t block[3]; + memcpy(block, str, 12); + + a += block[0]; + b += block[1]; + h += block[2]; + mix(14, 11, 25); + str += 12; + len -= 12; + +#undef mix +#undef rol + } + + // original Lua 5.1 hash for compatibility (exact match when len<32) + for (size_t i = len; i > 0; --i) + h ^= (h << 5) + (h >> 2) + (uint8_t)str[i - 1]; + + return h; +} + +void luaS_resize(lua_State* L, int newsize) +{ + TString** newhash = luaM_newarray(L, newsize, TString*, 0); + stringtable* tb = &L->global->strt; + for (int i = 0; i < newsize; i++) + newhash[i] = NULL; + // rehash + for (int i = 0; i < tb->size; i++) + { + TString* p = tb->hash[i]; + while (p) + { // for each node in the list + TString* next = p->next; // save next + unsigned int h = p->hash; + int h1 = lmod(h, newsize); // new position + LUAU_ASSERT(cast_int(h % newsize) == lmod(h, newsize)); + p->next = newhash[h1]; // chain it + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString*, 0); + tb->size = newsize; + tb->hash = newhash; +} + +static TString* newlstr(lua_State* L, const char* str, size_t l, unsigned int h) +{ + if (l > MAXSSIZE) + luaM_toobig(L); + + TString* ts = luaM_newgco(L, TString, sizestring(l), L->activememcat); + luaC_init(L, ts, LUA_TSTRING); + ts->atom = ATOM_UNDEF; + ts->hash = h; + ts->len = unsigned(l); + + memcpy(ts->data, str, l); + ts->data[l] = '\0'; // ending 0 + + stringtable* tb = &L->global->strt; + h = lmod(h, tb->size); + ts->next = tb->hash[h]; // chain new entry + tb->hash[h] = ts; + + tb->nuse++; + if (tb->nuse > cast_to(uint32_t, tb->size) && tb->size <= INT_MAX / 2) + luaS_resize(L, tb->size * 2); // too crowded + + return ts; +} + +TString* luaS_bufstart(lua_State* L, size_t size) +{ + if (size > MAXSSIZE) + luaM_toobig(L); + + TString* ts = luaM_newgco(L, TString, sizestring(size), L->activememcat); + luaC_init(L, ts, LUA_TSTRING); + ts->atom = ATOM_UNDEF; + ts->hash = 0; // computed in luaS_buffinish + ts->len = unsigned(size); + + ts->next = NULL; + + return ts; +} + +TString* luaS_buffinish(lua_State* L, TString* ts) +{ + unsigned int h = luaS_hash(ts->data, ts->len); + stringtable* tb = &L->global->strt; + int bucket = lmod(h, tb->size); + + // search if we already have this string in the hash table + for (TString* el = tb->hash[bucket]; el != NULL; el = el->next) + { + if (el->len == ts->len && memcmp(el->data, ts->data, ts->len) == 0) + { + // string may be dead + if (isdead(L->global, obj2gco(el))) + changewhite(obj2gco(el)); + + return el; + } + } + + LUAU_ASSERT(ts->next == NULL); + + ts->hash = h; + ts->data[ts->len] = '\0'; // ending 0 + ts->atom = ATOM_UNDEF; + ts->next = tb->hash[bucket]; // chain new entry + tb->hash[bucket] = ts; + + tb->nuse++; + if (tb->nuse > cast_to(uint32_t, tb->size) && tb->size <= INT_MAX / 2) + luaS_resize(L, tb->size * 2); // too crowded + + return ts; +} + +TString* luaS_newlstr(lua_State* L, const char* str, size_t l) +{ + unsigned int h = luaS_hash(str, l); + for (TString* el = L->global->strt.hash[lmod(h, L->global->strt.size)]; el != NULL; el = el->next) + { + if (el->len == l && (memcmp(str, getstr(el), l) == 0)) + { + // string may be dead + if (isdead(L->global, obj2gco(el))) + changewhite(obj2gco(el)); + return el; + } + } + return newlstr(L, str, l, h); // not found +} + +static bool unlinkstr(lua_State* L, TString* ts) +{ + global_State* g = L->global; + + TString** p = &g->strt.hash[lmod(ts->hash, g->strt.size)]; + + while (TString* curr = *p) + { + if (curr == ts) + { + *p = curr->next; + return true; + } + else + { + p = &curr->next; + } + } + + return false; +} + +void luaS_free(lua_State* L, TString* ts, lua_Page* page) +{ + if (unlinkstr(L, ts)) + L->global->strt.nuse--; + else + LUAU_ASSERT(ts->next == NULL); // orphaned string buffer + + luaM_freegco(L, ts, sizestring(ts->len), ts->memcat, page); +} diff --git a/thirdparty/luau/upstream/VM/src/lstring.h b/thirdparty/luau/upstream/VM/src/lstring.h new file mode 100644 index 000000000..41f9df9a0 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lstring.h @@ -0,0 +1,29 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" +#include "lstate.h" + +// string size limit +#define MAXSSIZE (1 << 30) + +// string atoms are not defined by default; the storage is 16-bit integer +#define ATOM_UNDEF -32768 + +#define sizestring(len) (offsetof(TString, data) + len + 1) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, (sizeof(s) / sizeof(char)) - 1)) + +#define luaS_fix(s) l_setbit((s)->marked, FIXEDBIT) + +LUAI_FUNC unsigned int luaS_hash(const char* str, size_t len); + +LUAI_FUNC void luaS_resize(lua_State* L, int newsize); + +LUAI_FUNC TString* luaS_newlstr(lua_State* L, const char* str, size_t l); +LUAI_FUNC void luaS_free(lua_State* L, TString* ts, struct lua_Page* page); + +LUAI_FUNC TString* luaS_bufstart(lua_State* L, size_t size); +LUAI_FUNC TString* luaS_buffinish(lua_State* L, TString* ts); diff --git a/thirdparty/luau/upstream/VM/src/lstrlib.cpp b/thirdparty/luau/upstream/VM/src/lstrlib.cpp new file mode 100644 index 000000000..772bdf3af --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lstrlib.cpp @@ -0,0 +1,1679 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lstring.h" + +#include +#include +#include + +// macro to `unsign' a character +#define uchar(c) ((unsigned char)(c)) + +static int str_len(lua_State* L) +{ + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (int)l); + return 1; +} + +static int posrelat(int pos, size_t len) +{ + // relative string position: negative means back from end + if (pos < 0) + pos += (int)len + 1; + return (pos >= 0) ? pos : 0; +} + +static int str_sub(lua_State* L) +{ + size_t l; + const char* s = luaL_checklstring(L, 1, &l); + int start = posrelat(luaL_checkinteger(L, 2), l); + int end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) + start = 1; + if (end > (int)l) + end = (int)l; + if (start <= end) + lua_pushlstring(L, s + start - 1, end - start + 1); + else + lua_pushliteral(L, ""); + return 1; +} + +static int str_reverse(lua_State* L) +{ + size_t l; + const char* s = luaL_checklstring(L, 1, &l); + luaL_Strbuf b; + char* ptr = luaL_buffinitsize(L, &b, l); + while (l--) + *ptr++ = s[l]; + luaL_pushresultsize(&b, ptr - b.p); + return 1; +} + +static int str_lower(lua_State* L) +{ + size_t l; + const char* s = luaL_checklstring(L, 1, &l); + luaL_Strbuf b; + char* ptr = luaL_buffinitsize(L, &b, l); + for (size_t i = 0; i < l; i++) + *ptr++ = tolower(uchar(s[i])); + luaL_pushresultsize(&b, l); + return 1; +} + +static int str_upper(lua_State* L) +{ + size_t l; + const char* s = luaL_checklstring(L, 1, &l); + luaL_Strbuf b; + char* ptr = luaL_buffinitsize(L, &b, l); + for (size_t i = 0; i < l; i++) + *ptr++ = toupper(uchar(s[i])); + luaL_pushresultsize(&b, l); + return 1; +} + +static int str_rep(lua_State* L) +{ + size_t l; + const char* s = luaL_checklstring(L, 1, &l); + int n = luaL_checkinteger(L, 2); + + if (n <= 0) + { + lua_pushliteral(L, ""); + return 1; + } + + if (l > MAXSSIZE / (size_t)n) // may overflow? + luaL_error(L, "resulting string too large"); + + luaL_Strbuf b; + char* ptr = luaL_buffinitsize(L, &b, l * n); + + const char* start = ptr; + + size_t left = l * n; + size_t step = l; + + memcpy(ptr, s, l); + ptr += l; + left -= l; + + // use the increasing 'pattern' inside our target buffer to fill the next part + while (step < left) + { + memcpy(ptr, start, step); + ptr += step; + left -= step; + step <<= 1; + } + + // fill tail + memcpy(ptr, start, left); + ptr += left; + + luaL_pushresultsize(&b, l * n); + + return 1; +} + +static int str_byte(lua_State* L) +{ + size_t l; + const char* s = luaL_checklstring(L, 1, &l); + int posi = posrelat(luaL_optinteger(L, 2, 1), l); + int pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) + posi = 1; + if ((size_t)pose > l) + pose = (int)l; + if (posi > pose) + return 0; // empty interval; return no values + n = (int)(pose - posi + 1); + if (posi + n <= pose) // overflow? + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i = 0; i < n; i++) + lua_pushinteger(L, uchar(s[posi + i - 1])); + return n; +} + +static int str_char(lua_State* L) +{ + int n = lua_gettop(L); // number of arguments + + luaL_Strbuf b; + char* ptr = luaL_buffinitsize(L, &b, n); + + for (int i = 1; i <= n; i++) + { + int c = luaL_checkinteger(L, i); + luaL_argcheck(L, uchar(c) == c, i, "invalid value"); + + *ptr++ = uchar(c); + } + luaL_pushresultsize(&b, n); + return 1; +} + +/* +** {====================================================== +** PATTERN MATCHING +** ======================================================= +*/ + +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) + +typedef struct MatchState +{ + int matchdepth; // control for recursive depth (to avoid C stack overflow) + const char* src_init; // init of source string + const char* src_end; // end ('\0') of source string + const char* p_end; // end ('\0') of pattern + lua_State* L; + int level; // total number of captures (finished or unfinished) + struct + { + const char* init; + ptrdiff_t len; + } capture[LUA_MAXCAPTURES]; +} MatchState; + +// recursive function +static const char* match(MatchState* ms, const char* s, const char* p); + +#define L_ESC '%' +#define SPECIALS "^$*+?.([%-" + +static int check_capture(MatchState* ms, int l) +{ + l -= '1'; + if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) + luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; +} + +static int capture_to_close(MatchState* ms) +{ + int level = ms->level; + for (level--; level >= 0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) + return level; + luaL_error(ms->L, "invalid pattern capture"); +} + +static const char* classend(MatchState* ms, const char* p) +{ + switch (*p++) + { + case L_ESC: + { + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (ends with '%%')"); + return p + 1; + } + case '[': + { + if (*p == '^') + p++; + do + { // look for a `]' + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (missing ']')"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; // skip escapes (e.g. `%]') + } while (*p != ']'); + return p + 1; + } + default: + { + return p; + } + } +} + +static int match_class(int c, int cl) +{ + int res; + switch (tolower(cl)) + { + case 'a': + res = isalpha(c); + break; + case 'c': + res = iscntrl(c); + break; + case 'd': + res = isdigit(c); + break; + case 'g': + res = isgraph(c); + break; + case 'l': + res = islower(c); + break; + case 'p': + res = ispunct(c); + break; + case 's': + res = isspace(c); + break; + case 'u': + res = isupper(c); + break; + case 'w': + res = isalnum(c); + break; + case 'x': + res = isxdigit(c); + break; + case 'z': + res = (c == 0); + break; // deprecated option + default: + return (cl == c); + } + return (islower(cl) ? res : !res); +} + +static int matchbracketclass(int c, const char* p, const char* ec) +{ + int sig = 1; + if (*(p + 1) == '^') + { + sig = 0; + p++; // skip the `^' + } + while (++p < ec) + { + if (*p == L_ESC) + { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p + 1) == '-') && (p + 2 < ec)) + { + p += 2; + if (uchar(*(p - 2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) + return sig; + } + return !sig; +} + +static int singlematch(MatchState* ms, const char* s, const char* p, const char* ep) +{ + if (s >= ms->src_end) + return 0; + else + { + int c = uchar(*s); + switch (*p) + { + case '.': + return 1; // matches any char + case L_ESC: + return match_class(c, uchar(*(p + 1))); + case '[': + return matchbracketclass(c, p, ep - 1); + default: + return (uchar(*p) == c); + } + } +} + +static const char* matchbalance(MatchState* ms, const char* s, const char* p) +{ + if (p >= ms->p_end - 1) + luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); + if (*s != *p) + return NULL; + else + { + int b = *p; + int e = *(p + 1); + int cont = 1; + while (++s < ms->src_end) + { + if (*s == e) + { + if (--cont == 0) + return s + 1; + } + else if (*s == b) + cont++; + } + } + return NULL; // string ends out of balance +} + +static const char* max_expand(MatchState* ms, const char* s, const char* p, const char* ep) +{ + ptrdiff_t i = 0; // counts maximum expand for item + while (singlematch(ms, s + i, p, ep)) + i++; + // keeps trying to match with the maximum repetitions + while (i >= 0) + { + const char* res = match(ms, (s + i), ep + 1); + if (res) + return res; + i--; // else didn't match; reduce 1 repetition to try again + } + return NULL; +} + +static const char* min_expand(MatchState* ms, const char* s, const char* p, const char* ep) +{ + for (;;) + { + const char* res = match(ms, s, ep + 1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; // try with one more repetition + else + return NULL; + } +} + +static const char* start_capture(MatchState* ms, const char* s, const char* p, int what) +{ + const char* res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) + luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level + 1; + if ((res = match(ms, s, p)) == NULL) // match failed? + ms->level--; // undo capture + return res; +} + +static const char* end_capture(MatchState* ms, const char* s, const char* p) +{ + int l = capture_to_close(ms); + const char* res; + ms->capture[l].len = s - ms->capture[l].init; // close capture + if ((res = match(ms, s, p)) == NULL) // match failed? + ms->capture[l].len = CAP_UNFINISHED; // undo capture + return res; +} + +static const char* match_capture(MatchState* ms, const char* s, int l) +{ + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end - s) >= len && memcmp(ms->capture[l].init, s, len) == 0) + return s + len; + else + return NULL; +} + +static const char* match(MatchState* ms, const char* s, const char* p) +{ + if (ms->matchdepth-- == 0) + luaL_error(ms->L, "pattern too complex"); + + lua_State* L = ms->L; + void (*interrupt)(lua_State*, int) = L->global->cb.interrupt; + + if (LUAU_UNLIKELY(!!interrupt)) + { + // this interrupt is not yieldable + L->nCcalls++; + interrupt(L, -1); + L->nCcalls--; + } + +init: // using goto's to optimize tail recursion + if (p != ms->p_end) + { // end of pattern? + switch (*p) + { + case '(': + { // start capture + if (*(p + 1) == ')') // position capture? + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': + { // end capture + s = end_capture(ms, s, p + 1); + break; + } + case '$': + { + if ((p + 1) != ms->p_end) // is the `$' the last char in pattern? + goto dflt; // no; go to default + s = (s == ms->src_end) ? s : NULL; // check end of string + break; + } + case L_ESC: + { // escaped sequences not in the format class[*+?-]? + switch (*(p + 1)) + { + case 'b': + { // balanced string? + s = matchbalance(ms, s, p + 2); + if (s != NULL) + { + p += 4; + goto init; // return match(ms, s, p + 4); + } // else fail (s == NULL) + break; + } + case 'f': + { // frontier? + const char* ep; + char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing '[' after '%%f' in pattern"); + ep = classend(ms, p); // points to what is next + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && matchbracketclass(uchar(*s), p, ep - 1)) + { + p = ep; + goto init; // return match(ms, s, ep); + } + s = NULL; // match failed + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { // capture results (%0-%9)? + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) + { + p += 2; + goto init; // return match(ms, s, p + 2) + } + break; + } + default: + goto dflt; + } + break; + } + default: + dflt: + { // pattern class plus optional suffix + const char* ep = classend(ms, p); // points to optional suffix + // does not match at least once? + if (!singlematch(ms, s, p, ep)) + { + if (*ep == '*' || *ep == '?' || *ep == '-') + { // accept empty? + p = ep + 1; + goto init; // return match(ms, s, ep + 1); + } + else // '+' or no suffix + s = NULL; // fail + } + else + { // matched once + switch (*ep) + { // handle optional suffix + case '?': + { // optional + const char* res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else + { + p = ep + 1; + goto init; // else return match(ms, s, ep + 1); + } + break; + } + case '+': // 1 or more repetitions + s++; // 1 match already done + LUAU_FALLTHROUGH; // go through + case '*': // 0 or more repetitions + s = max_expand(ms, s, p, ep); + break; + case '-': // 0 or more repetitions (minimum) + s = min_expand(ms, s, p, ep); + break; + default: // no suffix + s++; + p = ep; + goto init; // return match(ms, s + 1, ep); + } + } + break; + } + } + } + ms->matchdepth++; + return s; +} + +static const char* lmemfind(const char* s1, size_t l1, const char* s2, size_t l2) +{ + if (l2 == 0) + return s1; // empty strings are everywhere + else if (l2 > l1) + return NULL; // avoids a negative `l1' + else + { + const char* init; // to search for a `*s2' inside `s1' + l2--; // 1st char will be checked by `memchr' + l1 = l1 - l2; // `s2' cannot be found after that + while (l1 > 0 && (init = (const char*)memchr(s1, *s2, l1)) != NULL) + { + init++; // 1st char is already checked + if (memcmp(init, s2 + 1, l2) == 0) + return init - 1; + else + { // correct `l1' and `s1' to try again + l1 -= init - s1; + s1 = init; + } + } + return NULL; // not found + } +} + +static void push_onecapture(MatchState* ms, int i, const char* s, const char* e) +{ + if (i >= ms->level) + { + if (i == 0) // ms->level == 0, too + lua_pushlstring(ms->L, s, e - s); // add whole match + else + luaL_error(ms->L, "invalid capture index"); + } + else + { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) + luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, (int)(ms->capture[i].init - ms->src_init) + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + +static int push_captures(MatchState* ms, const char* s, const char* e) +{ + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; // number of strings pushed +} + +// check whether pattern has no special characters +static int nospecials(const char* p, size_t l) +{ + size_t upto = 0; + do + { + if (strpbrk(p + upto, SPECIALS)) + return 0; // pattern has a special character + upto += strlen(p + upto) + 1; // may have more after \0 + } while (upto <= l); + return 1; // no special chars found +} + +static void prepstate(MatchState* ms, lua_State* L, const char* s, size_t ls, const char* p, size_t lp) +{ + ms->L = L; + ms->matchdepth = LUAI_MAXCCALLS; + ms->src_init = s; + ms->src_end = s + ls; + ms->p_end = p + lp; +} + +static void reprepstate(MatchState* ms) +{ + ms->level = 0; + LUAU_ASSERT(ms->matchdepth == LUAI_MAXCCALLS); +} + +static int str_find_aux(lua_State* L, int find) +{ + size_t ls, lp; + const char* s = luaL_checklstring(L, 1, &ls); + const char* p = luaL_checklstring(L, 2, &lp); + int init = posrelat(luaL_optinteger(L, 3, 1), ls); + if (init < 1) + init = 1; + else if (init > (int)ls + 1) + { // start after string's end? + lua_pushnil(L); // cannot find anything + return 1; + } + // explicit request or no special characters? + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) + { + // do a plain search + const char* s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); + if (s2) + { + lua_pushinteger(L, (int)(s2 - s + 1)); + lua_pushinteger(L, (int)(s2 - s + lp)); + return 2; + } + } + else + { + MatchState ms; + const char* s1 = s + init - 1; + int anchor = (*p == '^'); + if (anchor) + { + p++; + lp--; // skip anchor character + } + prepstate(&ms, L, s, ls, p, lp); + do + { + const char* res; + reprepstate(&ms); + if ((res = match(&ms, s1, p)) != NULL) + { + if (find) + { + lua_pushinteger(L, (int)(s1 - s + 1)); // start + lua_pushinteger(L, (int)(res - s)); // end + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); // not found + return 1; +} + +static int str_find(lua_State* L) +{ + return str_find_aux(L, 1); +} + +static int str_match(lua_State* L) +{ + return str_find_aux(L, 0); +} + +static int gmatch_aux(lua_State* L) +{ + MatchState ms; + size_t ls, lp; + const char* s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char* p = lua_tolstring(L, lua_upvalueindex(2), &lp); + const char* src; + prepstate(&ms, L, s, ls, p, lp); + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); src <= ms.src_end; src++) + { + const char* e; + reprepstate(&ms); + if ((e = match(&ms, src, p)) != NULL) + { + int newstart = (int)(e - s); + if (e == src) + newstart++; // empty match? go at least one position + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; // not found +} + +static int gmatch(lua_State* L) +{ + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, NULL, 3); + return 1; +} + +static void add_s(MatchState* ms, luaL_Strbuf* b, const char* s, const char* e) +{ + size_t l, i; + const char* news = lua_tolstring(ms->L, 3, &l); + + luaL_prepbuffsize(b, l); + + for (i = 0; i < l; i++) + { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else + { + i++; // skip ESC + if (!isdigit(uchar(news[i]))) + { + if (news[i] != L_ESC) + luaL_error(ms->L, "invalid use of '%c' in replacement string", L_ESC); + luaL_addchar(b, news[i]); + } + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else + { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); // add capture to accumulated result + } + } + } +} + +static void add_value(MatchState* ms, luaL_Strbuf* b, const char* s, const char* e, int tr) +{ + lua_State* L = ms->L; + switch (tr) + { + case LUA_TFUNCTION: + { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: + { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + default: + { // LUA_TNUMBER or LUA_TSTRING + add_s(ms, b, s, e); + return; + } + } + if (!lua_toboolean(L, -1)) + { // nil or false? + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); // keep original text + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); // add result to accumulator +} + +static int str_gsub(lua_State* L) +{ + size_t srcl, lp; + const char* src = luaL_checklstring(L, 1, &srcl); + const char* p = luaL_checklstring(L, 2, &lp); + int tr = lua_type(L, 3); + int max_s = luaL_optinteger(L, 4, (int)srcl + 1); + int anchor = (*p == '^'); + int n = 0; + MatchState ms; + luaL_Strbuf b; + luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table"); + luaL_buffinit(L, &b); + if (anchor) + { + p++; + lp--; // skip anchor character + } + prepstate(&ms, L, src, srcl, p, lp); + while (n < max_s) + { + const char* e; + reprepstate(&ms); + e = match(&ms, src, p); + if (e) + { + n++; + add_value(&ms, &b, src, e, tr); + } + if (e && e > src) // non empty match? + src = e; // skip it + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else + break; + if (anchor) + break; + } + luaL_addlstring(&b, src, ms.src_end - src); + luaL_pushresult(&b); + lua_pushinteger(L, n); // number of substitutions + return 2; +} + +// }====================================================== + +// valid flags in a format specification +#define FLAGS "-+ #0" +// maximum size of each formatted item (> len(format('%99.99f', -1e308))) +#define MAX_ITEM 512 +// maximum size of each format specification (such as '%-099.99d') +#define MAX_FORMAT 32 + +static void addquoted(lua_State* L, luaL_Strbuf* b, int arg) +{ + size_t l; + const char* s = luaL_checklstring(L, arg, &l); + + luaL_prepbuffsize(b, l + 2); + + luaL_addchar(b, '"'); + while (l--) + { + switch (*s) + { + case '"': + case '\\': + case '\n': + { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': + { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': + { + luaL_addlstring(b, "\\000", 4); + break; + } + default: + { + luaL_addchar(b, *s); + break; + } + } + s++; + } + luaL_addchar(b, '"'); +} + +static const char* scanformat(lua_State* L, const char* strfrmt, char* form, size_t* size) +{ + const char* p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) + p++; // skip flags + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) + p++; // skip width + if (isdigit(uchar(*p))) + p++; // (2 digits at most) + if (*p == '.') + { + p++; + if (isdigit(uchar(*p))) + p++; // skip precision + if (isdigit(uchar(*p))) + p++; // (2 digits at most) + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + *size = p - strfrmt + 1; + strncpy(form, strfrmt, *size); + form += *size; + *form = '\0'; + return p; +} + +static void addInt64Format(char form[MAX_FORMAT], char formatIndicator, size_t formatItemSize) +{ + LUAU_ASSERT((formatItemSize + 3) <= MAX_FORMAT); + LUAU_ASSERT(form[0] == '%'); + LUAU_ASSERT(form[formatItemSize] != 0); + LUAU_ASSERT(form[formatItemSize + 1] == 0); + form[formatItemSize + 0] = 'l'; + form[formatItemSize + 1] = 'l'; + form[formatItemSize + 2] = formatIndicator; + form[formatItemSize + 3] = 0; +} + +static int str_format(lua_State* L) +{ + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char* strfrmt = luaL_checklstring(L, arg, &sfl); + const char* strfrmt_end = strfrmt + sfl; + luaL_Strbuf b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) + { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); // %% + else if (*strfrmt == '*') + { + strfrmt++; + if (++arg > top) + luaL_error(L, "missing argument #%d", arg); + + luaL_addvalueany(&b, arg); + } + else + { // format item + char form[MAX_FORMAT]; // to store the format (`%...') + char buff[MAX_ITEM]; // to store the formatted item + if (++arg > top) + luaL_error(L, "missing argument #%d", arg); + size_t formatItemSize = 0; + strfrmt = scanformat(L, strfrmt, form, &formatItemSize); + char formatIndicator = *strfrmt++; + switch (formatIndicator) + { + case 'c': + { + int count = snprintf(buff, sizeof(buff), form, (int)luaL_checknumber(L, arg)); + luaL_addlstring(&b, buff, count); + continue; // skip the 'luaL_addlstring' at the end + } + case 'd': + case 'i': + { + addInt64Format(form, formatIndicator, formatItemSize); + snprintf(buff, sizeof(buff), form, (long long)luaL_checknumber(L, arg)); + break; + } + case 'o': + case 'u': + case 'x': + case 'X': + { + double argValue = luaL_checknumber(L, arg); + addInt64Format(form, formatIndicator, formatItemSize); + unsigned long long v = (argValue < 0) ? (unsigned long long)(long long)argValue : (unsigned long long)argValue; + snprintf(buff, sizeof(buff), form, v); + break; + } + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + { + snprintf(buff, sizeof(buff), form, (double)luaL_checknumber(L, arg)); + break; + } + case 'q': + { + addquoted(L, &b, arg); + continue; // skip the 'luaL_addlstring' at the end + } + case 's': + { + size_t l; + const char* s = luaL_checklstring(L, arg, &l); + // no precision and string is too long to be formatted, or no format necessary to begin with + if (form[2] == '\0' || (!strchr(form, '.') && l >= 100)) + { + luaL_addlstring(&b, s, l); + continue; // skip the `luaL_addlstring' at the end + } + else + { + snprintf(buff, sizeof(buff), form, s); + break; + } + } + case '*': + { + // %* is parsed above, so if we got here we must have %...* + luaL_error(L, "'%%*' does not take a form"); + } + default: + { // also treat cases `pnLlh' + luaL_error(L, "invalid option '%%%c' to 'format'", *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + +static int str_split(lua_State* L) +{ + size_t haystackLen; + const char* haystack = luaL_checklstring(L, 1, &haystackLen); + size_t needleLen; + const char* needle = luaL_optlstring(L, 2, ",", &needleLen); + + const char* begin = haystack; + const char* end = haystack + haystackLen; + const char* spanStart = begin; + int numMatches = 0; + + lua_createtable(L, 0, 0); + + if (needleLen == 0) + begin++; + + // Don't iterate the last needleLen - 1 bytes of the string - they are + // impossible to be splits and would let us memcmp past the end of the + // buffer. + for (const char* iter = begin; iter <= end - needleLen; iter++) + { + // Use of memcmp here instead of strncmp is so that we allow embedded + // nulls to be used in either of the haystack or the needle strings. + // Most Lua string APIs allow embedded nulls, and this should be no + // exception. + if (memcmp(iter, needle, needleLen) == 0) + { + lua_pushinteger(L, ++numMatches); + lua_pushlstring(L, spanStart, iter - spanStart); + lua_settable(L, -3); + + spanStart = iter + needleLen; + if (needleLen > 0) + iter += needleLen - 1; + } + } + + if (needleLen > 0) + { + lua_pushinteger(L, ++numMatches); + lua_pushlstring(L, spanStart, end - spanStart); + lua_settable(L, -3); + } + + return 1; +} + +/* +** {====================================================== +** PACK/UNPACK +** ======================================================= +*/ + +// value used for padding +#if !defined(LUAL_PACKPADBYTE) +#define LUAL_PACKPADBYTE 0x00 +#endif + +// maximum size for the binary representation of an integer +#define MAXINTSIZE 16 + +// number of bits in a character +#define NB CHAR_BIT + +// mask for one character (NB 1's) +#define MC ((1 << NB) - 1) + +// internal size of integers used for pack/unpack +#define SZINT (int)sizeof(long long) + +// dummy union to get native endianness +static const union +{ + int dummy; + char little; // true iff machine is little endian +} nativeendian = {1}; + +// assume we need to align for double & pointers +#define MAXALIGN 8 + +/* +** Union for serializing floats +*/ +typedef union Ftypes +{ + float f; + double d; + double n; + char buff[5 * sizeof(double)]; // enough for any float type +} Ftypes; + +/* +** information to pack/unpack stuff +*/ +typedef struct Header +{ + lua_State* L; + int islittle; + int maxalign; +} Header; + +/* +** options for pack/unpack +*/ +typedef enum KOption +{ + Kint, // signed integers + Kuint, // unsigned integers + Kfloat, // floating-point numbers + Kchar, // fixed-length strings + Kstring, // strings with prefixed length + Kzstr, // zero-terminated strings + Kpadding, // padding + Kpaddalign, // padding for alignment + Knop // no-op (configuration or spaces) +} KOption; + +/* +** Read an integer numeral from string 'fmt' or return 'df' if +** there is no numeral +*/ +static int digit(int c) +{ + return '0' <= c && c <= '9'; +} + +static int getnum(Header* h, const char** fmt, int df) +{ + if (!digit(**fmt)) // no number? + return df; // return default value + else + { + int a = 0; + do + { + a = a * 10 + (*((*fmt)++) - '0'); + } while (digit(**fmt) && a <= (INT_MAX - 9) / 10); + if (a > MAXSSIZE || digit(**fmt)) + luaL_error(h->L, "size specifier is too large"); + return a; + } +} + +/* +** Read an integer numeral and raises an error if it is larger +** than the maximum size for integers. +*/ +static int getnumlimit(Header* h, const char** fmt, int df) +{ + int sz = getnum(h, fmt, df); + if (sz > MAXINTSIZE || sz <= 0) + luaL_error(h->L, "integral size (%d) out of limits [1,%d]", sz, MAXINTSIZE); + return sz; +} + +/* +** Initialize Header +*/ +static void initheader(lua_State* L, Header* h) +{ + h->L = L; + h->islittle = nativeendian.little; + h->maxalign = 1; +} + +/* +** Read and classify next option. 'size' is filled with option's size. +*/ +static KOption getoption(Header* h, const char** fmt, int* size) +{ + int opt = *((*fmt)++); + *size = 0; // default + switch (opt) + { + case 'b': + *size = 1; + return Kint; + case 'B': + *size = 1; + return Kuint; + case 'h': + *size = 2; + return Kint; + case 'H': + *size = 2; + return Kuint; + case 'l': + *size = 8; + return Kint; + case 'L': + *size = 8; + return Kuint; + case 'j': + *size = 4; + return Kint; + case 'J': + *size = 4; + return Kuint; + case 'T': + *size = 4; + return Kuint; + case 'f': + *size = 4; + return Kfloat; + case 'd': + *size = 8; + return Kfloat; + case 'n': + *size = 8; + return Kfloat; + case 'i': + *size = getnumlimit(h, fmt, 4); + return Kint; + case 'I': + *size = getnumlimit(h, fmt, 4); + return Kuint; + case 's': + *size = getnumlimit(h, fmt, 4); + return Kstring; + case 'c': + *size = getnum(h, fmt, -1); + if (*size == -1) + luaL_error(h->L, "missing size for format option 'c'"); + return Kchar; + case 'z': + return Kzstr; + case 'x': + *size = 1; + return Kpadding; + case 'X': + return Kpaddalign; + case ' ': + break; + case '<': + h->islittle = 1; + break; + case '>': + h->islittle = 0; + break; + case '=': + h->islittle = nativeendian.little; + break; + case '!': + h->maxalign = getnumlimit(h, fmt, MAXALIGN); + break; + default: + luaL_error(h->L, "invalid format option '%c'", opt); + } + return Knop; +} + +/* +** Read, classify, and fill other details about the next option. +** 'psize' is filled with option's size, 'notoalign' with its +** alignment requirements. +** Local variable 'size' gets the size to be aligned. (Kpaddalign option +** always gets its full alignment, other options are limited by +** the maximum alignment ('maxalign'). Kchar option needs no alignment +** despite its size. +*/ +static KOption getdetails(Header* h, size_t totalsize, const char** fmt, int* psize, int* ntoalign) +{ + KOption opt = getoption(h, fmt, psize); + int align = *psize; // usually, alignment follows size + if (opt == Kpaddalign) + { // 'X' gets alignment from following option + if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) + luaL_argerror(h->L, 1, "invalid next option for option 'X'"); + } + if (align <= 1 || opt == Kchar) // need no alignment? + *ntoalign = 0; + else + { + if (align > h->maxalign) // enforce maximum alignment + align = h->maxalign; + if ((align & (align - 1)) != 0) // is 'align' not a power of 2? + luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); + } + return opt; +} + +/* +** Pack integer 'n' with 'size' bytes and 'islittle' endianness. +** The final 'if' handles the case when 'size' is larger than +** the size of a Lua integer, correcting the extra sign-extension +** bytes if necessary (by default they would be zeros). +*/ +static void packint(luaL_Strbuf* b, unsigned long long n, int islittle, int size, int neg) +{ + LUAU_ASSERT(size <= MAXINTSIZE); + char buff[MAXINTSIZE]; + int i; + buff[islittle ? 0 : size - 1] = (char)(n & MC); // first byte + for (i = 1; i < size; i++) + { + n >>= NB; + buff[islittle ? i : size - 1 - i] = (char)(n & MC); + } + if (neg && size > SZINT) + { // negative number need sign extension? + for (i = SZINT; i < size; i++) // correct extra bytes + buff[islittle ? i : size - 1 - i] = (char)MC; + } + luaL_addlstring(b, buff, size); // add result to buffer +} + +/* +** Copy 'size' bytes from 'src' to 'dest', correcting endianness if +** given 'islittle' is different from native endianness. +*/ +static void copywithendian(volatile char* dest, volatile const char* src, int size, int islittle) +{ + if (islittle == nativeendian.little) + { + while (size-- != 0) + *(dest++) = *(src++); + } + else + { + dest += size - 1; + while (size-- != 0) + *(dest--) = *(src++); + } +} + +static int str_pack(lua_State* L) +{ + luaL_Strbuf b; + Header h; + const char* fmt = luaL_checkstring(L, 1); // format string + int arg = 1; // current argument to pack + size_t totalsize = 0; // accumulate total size of result + initheader(L, &h); + lua_pushnil(L); // mark to separate arguments from string buffer + luaL_buffinit(L, &b); + while (*fmt != '\0') + { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + totalsize += ntoalign + size; + while (ntoalign-- > 0) + luaL_addchar(&b, LUAL_PACKPADBYTE); // fill alignment + arg++; + switch (opt) + { + case Kint: + { // signed integers + long long n = (long long)luaL_checknumber(L, arg); + if (size < SZINT) + { // need overflow check? + long long lim = (long long)1 << ((size * NB) - 1); + luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); + } + packint(&b, n, h.islittle, size, (n < 0)); + break; + } + case Kuint: + { // unsigned integers + long long n = (long long)luaL_checknumber(L, arg); + if (size < SZINT) // need overflow check? + luaL_argcheck(L, (unsigned long long)n < ((unsigned long long)1 << (size * NB)), arg, "unsigned overflow"); + packint(&b, (unsigned long long)n, h.islittle, size, 0); + break; + } + case Kfloat: + { // floating-point options + volatile Ftypes u; + char buff[MAXINTSIZE]; + double n = luaL_checknumber(L, arg); // get argument + if (size == sizeof(u.f)) + u.f = (float)n; // copy it into 'u' + else if (size == sizeof(u.d)) + u.d = (double)n; + else + u.n = n; + // move 'u' to final result, correcting endianness if needed + copywithendian(buff, u.buff, size, h.islittle); + luaL_addlstring(&b, buff, size); + break; + } + case Kchar: + { // fixed-size string + size_t len; + const char* s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, len <= (size_t)size, arg, "string longer than given size"); + luaL_addlstring(&b, s, len); // add string + while (len++ < (size_t)size) // pad extra space + luaL_addchar(&b, LUAL_PACKPADBYTE); + break; + } + case Kstring: + { // strings with length count + size_t len; + const char* s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, size >= (int)sizeof(size_t) || len < ((size_t)1 << (size * NB)), arg, "string length does not fit in given size"); + packint(&b, len, h.islittle, size, 0); // pack length + luaL_addlstring(&b, s, len); + totalsize += len; + break; + } + case Kzstr: + { // zero-terminated string + size_t len; + const char* s = luaL_checklstring(L, arg, &len); + luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); + luaL_addlstring(&b, s, len); + luaL_addchar(&b, '\0'); // add zero at the end + totalsize += len + 1; + break; + } + case Kpadding: + luaL_addchar(&b, LUAL_PACKPADBYTE); + LUAU_FALLTHROUGH; + case Kpaddalign: + case Knop: + arg--; // undo increment + break; + } + } + luaL_pushresult(&b); + return 1; +} + +static int str_packsize(lua_State* L) +{ + Header h; + const char* fmt = luaL_checkstring(L, 1); // format string + int totalsize = 0; // accumulate total size of result + initheader(L, &h); + while (*fmt != '\0') + { + int size, ntoalign; + KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); + luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, "variable-length format"); + size += ntoalign; // total space used by option + luaL_argcheck(L, totalsize <= MAXSSIZE - size, 1, "format result too large"); + totalsize += size; + } + lua_pushinteger(L, totalsize); + return 1; +} + +/* +** Unpack an integer with 'size' bytes and 'islittle' endianness. +** If size is smaller than the size of a Lua integer and integer +** is signed, must do sign extension (propagating the sign to the +** higher bits); if size is larger than the size of a Lua integer, +** it must check the unread bytes to see whether they do not cause an +** overflow. +*/ +static long long unpackint(lua_State* L, const char* str, int islittle, int size, int issigned) +{ + unsigned long long res = 0; + int i; + int limit = (size <= SZINT) ? size : SZINT; + for (i = limit - 1; i >= 0; i--) + { + res <<= NB; + res |= (unsigned char)str[islittle ? i : size - 1 - i]; + } + if (size < SZINT) + { // real size smaller than int? + if (issigned) + { // needs sign extension? + unsigned long long mask = (unsigned long long)1 << (size * NB - 1); + res = ((res ^ mask) - mask); // do sign extension + } + } + else if (size > SZINT) + { // must check unread bytes + int mask = (!issigned || (long long)res >= 0) ? 0 : MC; + for (i = limit; i < size; i++) + { + if ((unsigned char)str[islittle ? i : size - 1 - i] != mask) + luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); + } + } + return (long long)res; +} + +static int str_unpack(lua_State* L) +{ + Header h; + const char* fmt = luaL_checkstring(L, 1); + size_t ld; + const char* data = luaL_checklstring(L, 2, &ld); + int pos = posrelat(luaL_optinteger(L, 3, 1), ld) - 1; + if (pos < 0) + pos = 0; + int n = 0; // number of results + luaL_argcheck(L, size_t(pos) <= ld, 3, "initial position out of string"); + initheader(L, &h); + while (*fmt != '\0') + { + int size, ntoalign; + KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); + luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, "data string too short"); + pos += ntoalign; // skip alignment + // stack space for item + next position + luaL_checkstack(L, 2, "too many results"); + n++; + switch (opt) + { + case Kint: + { + long long res = unpackint(L, data + pos, h.islittle, size, true); + lua_pushnumber(L, (double)res); + break; + } + case Kuint: + { + unsigned long long res = unpackint(L, data + pos, h.islittle, size, false); + lua_pushnumber(L, (double)res); + break; + } + case Kfloat: + { + volatile Ftypes u; + double num; + copywithendian(u.buff, data + pos, size, h.islittle); + if (size == sizeof(u.f)) + num = (double)u.f; + else if (size == sizeof(u.d)) + num = (double)u.d; + else + num = u.n; + lua_pushnumber(L, num); + break; + } + case Kchar: + { + lua_pushlstring(L, data + pos, size); + break; + } + case Kstring: + { + size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); + luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); + lua_pushlstring(L, data + pos + size, len); + pos += (int)len; // skip string + break; + } + case Kzstr: + { + size_t len = strlen(data + pos); + luaL_argcheck(L, pos + len < ld, 2, "unfinished string for format 'z'"); + lua_pushlstring(L, data + pos, len); + pos += (int)len + 1; // skip string plus final '\0' + break; + } + case Kpaddalign: + case Kpadding: + case Knop: + n--; // undo increment + break; + } + pos += size; + } + lua_pushinteger(L, pos + 1); // next position + return n + 1; +} + +// }====================================================== + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {"split", str_split}, + {"pack", str_pack}, + {"packsize", str_packsize}, + {"unpack", str_unpack}, + {NULL, NULL}, +}; + +static void createmetatable(lua_State* L) +{ + lua_createtable(L, 0, 1); // create metatable for strings + lua_pushliteral(L, ""); // dummy string + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); // set string metatable + lua_pop(L, 1); // pop dummy string + lua_pushvalue(L, -2); // string library... + lua_setfield(L, -2, "__index"); // ...is the __index metamethod + lua_pop(L, 1); // pop metatable +} + +/* +** Open string library +*/ +int luaopen_string(lua_State* L) +{ + luaL_register(L, LUA_STRLIBNAME, strlib); + createmetatable(L); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/ltable.cpp b/thirdparty/luau/upstream/VM/src/ltable.cpp new file mode 100644 index 000000000..d1b125595 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ltable.cpp @@ -0,0 +1,890 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details + +/* + * Implementation of tables (aka arrays, objects, or hash tables). + * + * Tables keep the elements in two parts: an array part and a hash part. + * Integer keys >=1 are all candidates to be kept in the array part. The actual size of the array is the + * largest n such that at least half the slots between 0 and n are in use. + * Hash uses a mix of chained scatter table with Brent's variation. + * + * A main invariant of these tables is that, if an element is not in its main position (i.e. the original + * position that its hash gives to it), then the colliding element is in its own main position. + * Hence even when the load factor reaches 100%, performance remains good. + * + * Table keys can be arbitrary values unless they contain NaN. Keys are hashed and compared using raw equality, + * so even if the key is a userdata with an overridden __eq, it's not used during hash lookups. + * + * Each table has a "boundary", defined as the index k where t[k] ~= nil and t[k+1] == nil. The boundary can be + * computed using a binary search and can be adjusted when the table is modified; crucially, Luau enforces an + * invariant where the boundary must be in the array part - this enforces a consistent iteration order through the + * prefix of the table when using pairs(), and allows to implement algorithms that access elements in 1..#t range + * more efficiently. + */ + +#include "ltable.h" + +#include "lstate.h" +#include "ldebug.h" +#include "lgc.h" +#include "lmem.h" +#include "lnumutils.h" + +#include + +// max size of both array and hash part is 2^MAXBITS +#define MAXBITS 26 +#define MAXSIZE (1 << MAXBITS) + +static_assert(offsetof(LuaNode, val) == 0, "Unexpected Node memory layout, pointer cast in gval2slot is incorrect"); + +// TKey is bitpacked for memory efficiency so we need to validate bit counts for worst case +static_assert(TKey{{NULL}, {0}, LUA_TDEADKEY, 0}.tt == LUA_TDEADKEY, "not enough bits for tt"); +static_assert(TKey{{NULL}, {0}, LUA_TNIL, MAXSIZE - 1}.next == MAXSIZE - 1, "not enough bits for next"); +static_assert(TKey{{NULL}, {0}, LUA_TNIL, -(MAXSIZE - 1)}.next == -(MAXSIZE - 1), "not enough bits for next"); + +// empty hash data points to dummynode so that we can always dereference it +const LuaNode luaH_dummynode = { + {{NULL}, {0}, LUA_TNIL}, // value + {{NULL}, {0}, LUA_TNIL, 0} // key +}; + +#define dummynode (&luaH_dummynode) + +// hash is always reduced mod 2^k +#define hashpow2(t, n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t, str) hashpow2(t, (str)->hash) +#define hashboolean(t, p) hashpow2(t, p) + +static LuaNode* hashpointer(const LuaTable* t, const void* p) +{ + // we discard the high 32-bit portion of the pointer on 64-bit platforms as it doesn't carry much entropy anyway + unsigned int h = unsigned(uintptr_t(p)); + + // MurmurHash3 32-bit finalizer + h ^= h >> 16; + h *= 0x85ebca6bu; + h ^= h >> 13; + h *= 0xc2b2ae35u; + h ^= h >> 16; + + return hashpow2(t, h); +} + +static LuaNode* hashnum(const LuaTable* t, double n) +{ + static_assert(sizeof(double) == sizeof(unsigned int) * 2, "expected a 8-byte double"); + unsigned int i[2]; + memcpy(i, &n, sizeof(i)); + + // mask out sign bit to make sure -0 and 0 hash to the same value + uint32_t h1 = i[0]; + uint32_t h2 = i[1] & 0x7fffffff; + + // finalizer from MurmurHash64B + const uint32_t m = 0x5bd1e995; + + h1 ^= h2 >> 18; + h1 *= m; + h2 ^= h1 >> 22; + h2 *= m; + h1 ^= h2 >> 17; + h1 *= m; + h2 ^= h1 >> 19; + h2 *= m; + + // ... truncated to 32-bit output (normally hash is equal to (uint64_t(h1) << 32) | h2, but we only really need the lower 32-bit half) + return hashpow2(t, h2); +} + +static LuaNode* hashvec(const LuaTable* t, const float* v) +{ + unsigned int i[LUA_VECTOR_SIZE]; + memcpy(i, v, sizeof(i)); + + // convert -0 to 0 to make sure they hash to the same value + i[0] = (i[0] == 0x80000000) ? 0 : i[0]; + i[1] = (i[1] == 0x80000000) ? 0 : i[1]; + i[2] = (i[2] == 0x80000000) ? 0 : i[2]; + + // scramble bits to make sure that integer coordinates have entropy in lower bits + i[0] ^= i[0] >> 17; + i[1] ^= i[1] >> 17; + i[2] ^= i[2] >> 17; + + // Optimized Spatial Hashing for Collision Detection of Deformable Objects + unsigned int h = (i[0] * 73856093) ^ (i[1] * 19349663) ^ (i[2] * 83492791); + +#if LUA_VECTOR_SIZE == 4 + i[3] = (i[3] == 0x80000000) ? 0 : i[3]; + i[3] ^= i[3] >> 17; + h ^= i[3] * 39916801; +#endif + + return hashpow2(t, h); +} + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static LuaNode* mainposition(const LuaTable* t, const TValue* key) +{ + switch (ttype(key)) + { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TVECTOR: + return hashvec(t, vvalue(key)); + case LUA_TSTRING: + return hashstr(t, tsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex(double key) +{ + int i; + luai_num2int(i, key); + + return luai_numeq(cast_num(i), key) ? i : -1; +} + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signalled by -1. +*/ +static int findindex(lua_State* L, LuaTable* t, StkId key) +{ + int i; + if (ttisnil(key)) + return -1; // first iteration + i = ttisnumber(key) ? arrayindex(nvalue(key)) : -1; + if (0 < i && i <= t->sizearray) // is `key' inside array part? + return i - 1; // yes; that's the index (corrected to C) + else + { + LuaNode* n = mainposition(t, key); + for (;;) + { // check whether `key' is somewhere in the chain + // key may be dead already, but it is ok to use it in `next' + if (luaO_rawequalKey(gkey(n), key) || (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && gcvalue(gkey(n)) == gcvalue(key))) + { + i = cast_int(n - gnode(t, 0)); // key index in hash table + // hash elements are numbered after array ones + return i + t->sizearray; + } + if (gnext(n) == 0) + break; + n += gnext(n); + } + luaG_runerror(L, "invalid key to 'next'"); // key not found + } +} + +int luaH_next(lua_State* L, LuaTable* t, StkId key) +{ + int i = findindex(L, t, key); // find original element + for (i++; i < t->sizearray; i++) + { // try first array part + if (!ttisnil(&t->array[i])) + { // a non-nil value? + setnvalue(key, cast_num(i + 1)); + setobj2s(L, key + 1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) + { // then hash part + if (!ttisnil(gval(gnode(t, i)))) + { // a non-nil value? + getnodekey(L, key, gnode(t, i)); + setobj2s(L, key + 1, gval(gnode(t, i))); + return 1; + } + } + return 0; // no more elements +} + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + +#define maybesetaboundary(t, boundary) \ + { \ + if (t->aboundary <= 0) \ + t->aboundary = -int(boundary); \ + } + +#define getaboundary(t) (t->aboundary < 0 ? -t->aboundary : t->sizearray) + +static int computesizes(int nums[], int* narray) +{ + int i; + int twotoi; // 2^i + int a = 0; // number of elements smaller than 2^i + int na = 0; // number of elements to go to array part + int n = 0; // optimal size for array part + for (i = 0, twotoi = 1; twotoi / 2 < *narray; i++, twotoi *= 2) + { + if (nums[i] > 0) + { + a += nums[i]; + if (a > twotoi / 2) + { // more than half elements present? + n = twotoi; // optimal size (till now) + na = a; // all elements smaller than n will go to array part + } + } + if (a == *narray) + break; // all elements already counted + } + *narray = n; + LUAU_ASSERT(*narray / 2 <= na && na <= *narray); + return na; +} + +static int countint(double key, int* nums) +{ + int k = arrayindex(key); + if (0 < k && k <= MAXSIZE) + { // is `key' an appropriate array index? + nums[ceillog2(k)]++; // count as such + return 1; + } + else + return 0; +} + +static int numusearray(const LuaTable* t, int* nums) +{ + int lg; + int ttlg; // 2^lg + int ause = 0; // summation of `nums' + int i = 1; // count to traverse all array keys + for (lg = 0, ttlg = 1; lg <= MAXBITS; lg++, ttlg *= 2) + { // for each slice + int lc = 0; // counter + int lim = ttlg; + if (lim > t->sizearray) + { + lim = t->sizearray; // adjust upper limit + if (i > lim) + break; // no more elements to count + } + // count elements in range (2^(lg-1), 2^lg] + for (; i <= lim; i++) + { + if (!ttisnil(&t->array[i - 1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + +static int numusehash(const LuaTable* t, int* nums, int* pnasize) +{ + int totaluse = 0; // total number of elements + int ause = 0; // summation of `nums' + int i = sizenode(t); + while (i--) + { + LuaNode* n = &t->node[i]; + if (!ttisnil(gval(n))) + { + if (ttisnumber(gkey(n))) + ause += countint(nvalue(gkey(n)), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + +static void setarrayvector(lua_State* L, LuaTable* t, int size) +{ + if (size > MAXSIZE) + luaG_runerror(L, "table overflow"); + luaM_reallocarray(L, t->array, t->sizearray, size, TValue, t->memcat); + TValue* array = t->array; + for (int i = t->sizearray; i < size; i++) + setnilvalue(&array[i]); + t->sizearray = size; +} + +static void setnodevector(lua_State* L, LuaTable* t, int size) +{ + int lsize; + if (size == 0) + { // no elements to hash part? + t->node = cast_to(LuaNode*, dummynode); // use common `dummynode' + lsize = 0; + } + else + { + int i; + lsize = ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newarray(L, size, LuaNode, t->memcat); + for (i = 0; i < size; i++) + { + LuaNode* n = gnode(t, i); + gnext(n) = 0; + setnilvalue(gkey(n)); + setnilvalue(gval(n)); + } + } + t->lsizenode = cast_byte(lsize); + t->nodemask8 = cast_byte((1 << lsize) - 1); + t->lastfree = size; // all positions are free +} + +static TValue* newkey(lua_State* L, LuaTable* t, const TValue* key); + +static TValue* arrayornewkey(lua_State* L, LuaTable* t, const TValue* key) +{ + if (ttisnumber(key)) + { + int k; + double n = nvalue(key); + luai_num2int(k, n); + if (luai_numeq(cast_num(k), n) && unsigned(k) - 1 < unsigned(t->sizearray)) + return &t->array[k - 1]; + } + + return newkey(L, t, key); +} + +static void resize(lua_State* L, LuaTable* t, int nasize, int nhsize) +{ + if (nasize > MAXSIZE || nhsize > MAXSIZE) + luaG_runerror(L, "table overflow"); + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + LuaNode* nold = t->node; // save old hash ... + if (nasize > oldasize) // array part must grow? + setarrayvector(L, t, nasize); + // create new hash part with appropriate size + setnodevector(L, t, nhsize); + // used for the migration check at the end + LuaNode* nnew = t->node; + if (nasize < oldasize) + { // array part must shrink? + t->sizearray = nasize; + // re-insert elements from vanishing slice + for (int i = nasize; i < oldasize; i++) + { + if (!ttisnil(&t->array[i])) + { + TValue ok; + setnvalue(&ok, cast_num(i + 1)); + setobjt2t(L, newkey(L, t, &ok), &t->array[i]); + } + } + // shrink array + luaM_reallocarray(L, t->array, oldasize, nasize, TValue, t->memcat); + } + // used for the migration check at the end + TValue* anew = t->array; + // re-insert elements from hash part + for (int i = twoto(oldhsize) - 1; i >= 0; i--) + { + LuaNode* old = nold + i; + if (!ttisnil(gval(old))) + { + TValue ok; + getnodekey(L, &ok, old); + setobjt2t(L, arrayornewkey(L, t, &ok), gval(old)); + } + } + + // make sure we haven't recursively rehashed during element migration + LUAU_ASSERT(nnew == t->node); + LUAU_ASSERT(anew == t->array); + + if (nold != dummynode) + luaM_freearray(L, nold, twoto(oldhsize), LuaNode, t->memcat); // free old array +} + +static int adjustasize(LuaTable* t, int size, const TValue* ek) +{ + bool tbound = t->node != dummynode || size < t->sizearray; + int ekindex = ek && ttisnumber(ek) ? arrayindex(nvalue(ek)) : -1; + // move the array size up until the boundary is guaranteed to be inside the array part + while (size + 1 == ekindex || (tbound && !ttisnil(luaH_getnum(t, size + 1)))) + size++; + return size; +} + +void luaH_resizearray(lua_State* L, LuaTable* t, int nasize) +{ + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + int asize = adjustasize(t, nasize, NULL); + resize(L, t, asize, nsize); +} + +void luaH_resizehash(lua_State* L, LuaTable* t, int nhsize) +{ + resize(L, t, t->sizearray, nhsize); +} + +static void rehash(lua_State* L, LuaTable* t, const TValue* ek) +{ + int nums[MAXBITS + 1]; // nums[i] = number of keys between 2^(i-1) and 2^i + for (int i = 0; i <= MAXBITS; i++) + nums[i] = 0; // reset counts + int nasize = numusearray(t, nums); // count keys in array part + int totaluse = nasize; // all those keys are integer keys + totaluse += numusehash(t, nums, &nasize); // count keys in hash part + + // count extra key + if (ttisnumber(ek)) + nasize += countint(nvalue(ek), nums); + totaluse++; + + // compute new size for array part + int na = computesizes(nums, &nasize); + int nh = totaluse - na; + + // enforce the boundary invariant; for performance, only do hash lookups if we must + int nadjusted = adjustasize(t, nasize, ek); + + // count how many extra elements belong to array part instead of hash part + int aextra = nadjusted - nasize; + + if (aextra != 0) + { + // we no longer need to store those extra array elements in hash part + nh -= aextra; + + // because hash nodes are twice as large as array nodes, the memory we saved for hash parts can be used by array part + // this follows the general sparse array part optimization where array is allocated when 50% occupation is reached + nasize = nadjusted + aextra; + + // since the size was changed, it's again important to enforce the boundary invariant at the new size + nasize = adjustasize(t, nasize, ek); + } + + // resize the table to new computed sizes + resize(L, t, nasize, nh); +} + +/* +** }============================================================= +*/ + +LuaTable* luaH_new(lua_State* L, int narray, int nhash) +{ + LuaTable* t = luaM_newgco(L, LuaTable, sizeof(LuaTable), L->activememcat); + luaC_init(L, t, LUA_TTABLE); + t->metatable = NULL; + t->tmcache = cast_byte(~0); + t->array = NULL; + t->sizearray = 0; + t->lastfree = 0; + t->lsizenode = 0; + t->readonly = 0; + t->safeenv = 0; + t->nodemask8 = 0; + t->node = cast_to(LuaNode*, dummynode); + if (narray > 0) + setarrayvector(L, t, narray); + if (nhash > 0) + setnodevector(L, t, nhash); + return t; +} + +void luaH_free(lua_State* L, LuaTable* t, lua_Page* page) +{ + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), LuaNode, t->memcat); + if (t->array) + luaM_freearray(L, t->array, t->sizearray, TValue, t->memcat); + luaM_freegco(L, t, sizeof(LuaTable), t->memcat, page); +} + +static LuaNode* getfreepos(LuaTable* t) +{ + while (t->lastfree > 0) + { + t->lastfree--; + + LuaNode* n = gnode(t, t->lastfree); + if (ttisnil(gkey(n))) + return n; + } + return NULL; // could not find a free place +} + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TValue* newkey(lua_State* L, LuaTable* t, const TValue* key) +{ + // enforce boundary invariant + if (ttisnumber(key) && nvalue(key) == t->sizearray + 1) + { + rehash(L, t, key); // grow table + + // after rehash, numeric keys might be located in the new array part, but won't be found in the node part + return arrayornewkey(L, t, key); + } + + LuaNode* mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) + { + LuaNode* n = getfreepos(t); // get a free place + if (n == NULL) + { // cannot find a free place? + rehash(L, t, key); // grow table + + // after rehash, numeric keys might be located in the new array part, but won't be found in the node part + return arrayornewkey(L, t, key); + } + LUAU_ASSERT(n != dummynode); + TValue mk; + getnodekey(L, &mk, mp); + LuaNode* othern = mainposition(t, &mk); + if (othern != mp) + { // is colliding node out of its main position? + // yes; move colliding node into free position + while (othern + gnext(othern) != mp) + othern += gnext(othern); // find previous + gnext(othern) = cast_int(n - othern); // redo the chain with `n' in place of `mp' + *n = *mp; // copy colliding node into free pos. (mp->next also goes) + if (gnext(mp) != 0) + { + gnext(n) += cast_int(mp - n); // correct 'next' + gnext(mp) = 0; // now 'mp' is free + } + setnilvalue(gval(mp)); + } + else + { // colliding node is in its own main position + // new node will go into free position + if (gnext(mp) != 0) + gnext(n) = cast_int((mp + gnext(mp)) - n); // chain new position + else + LUAU_ASSERT(gnext(n) == 0); + gnext(mp) = cast_int(n - mp); + mp = n; + } + } + setnodekey(L, mp, key); + luaC_barriert(L, t, key); + LUAU_ASSERT(ttisnil(gval(mp))); + return gval(mp); +} + +/* +** search function for integers +*/ +const TValue* luaH_getnum(LuaTable* t, int key) +{ + // (1 <= key && key <= t->sizearray) + if (unsigned(key) - 1 < unsigned(t->sizearray)) + return &t->array[key - 1]; + else if (t->node != dummynode) + { + double nk = cast_num(key); + LuaNode* n = hashnum(t, nk); + for (;;) + { // check whether `key' is somewhere in the chain + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); // that's it + if (gnext(n) == 0) + break; + n += gnext(n); + } + return luaO_nilobject; + } + else + return luaO_nilobject; +} + +/* +** search function for strings +*/ +const TValue* luaH_getstr(LuaTable* t, TString* key) +{ + LuaNode* n = hashstr(t, key); + for (;;) + { // check whether `key' is somewhere in the chain + if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key) + return gval(n); // that's it + if (gnext(n) == 0) + break; + n += gnext(n); + } + return luaO_nilobject; +} + +/* +** search function for lightuserdata +*/ +const TValue* luaH_getp(LuaTable* t, void* key, int tag) +{ + LuaNode* n = hashpointer(t, key); + for (;;) + { // check whether `key' is somewhere in the chain + const TKey* nk = gkey(n); + if (ttislightuserdata(nk) && pvalue(nk) == key && lightuserdatatag(nk) == tag) + return gval(n); // that's it + if (gnext(n) == 0) + break; + n += gnext(n); + } + return luaO_nilobject; +} + +/* +** main search function +*/ +const TValue* luaH_get(LuaTable* t, const TValue* key) +{ + switch (ttype(key)) + { + case LUA_TNIL: + return luaO_nilobject; + case LUA_TSTRING: + return luaH_getstr(t, tsvalue(key)); + case LUA_TNUMBER: + { + int k; + double n = nvalue(key); + luai_num2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) // index is int? + return luaH_getnum(t, k); // use specialized version + LUAU_FALLTHROUGH; // else go through + } + default: + { + LuaNode* n = mainposition(t, key); + for (;;) + { // check whether `key' is somewhere in the chain + if (luaO_rawequalKey(gkey(n), key)) + return gval(n); // that's it + if (gnext(n) == 0) + break; + n += gnext(n); + } + return luaO_nilobject; + } + } +} + +TValue* luaH_set(lua_State* L, LuaTable* t, const TValue* key) +{ + const TValue* p = luaH_get(t, key); + invalidateTMcache(t); + if (p != luaO_nilobject) + return cast_to(TValue*, p); + else + return luaH_newkey(L, t, key); +} + +TValue* luaH_newkey(lua_State* L, LuaTable* t, const TValue* key) +{ + if (ttisnil(key)) + luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + else if (ttisvector(key) && luai_vecisnan(vvalue(key))) + luaG_runerror(L, "table index contains NaN"); + return newkey(L, t, key); +} + +TValue* luaH_setnum(lua_State* L, LuaTable* t, int key) +{ + // (1 <= key && key <= t->sizearray) + if (unsigned(key) - 1 < unsigned(t->sizearray)) + return &t->array[key - 1]; + // hash fallback + const TValue* p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast_to(TValue*, p); + else + { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); + } +} + +TValue* luaH_setstr(lua_State* L, LuaTable* t, TString* key) +{ + const TValue* p = luaH_getstr(t, key); + invalidateTMcache(t); + if (p != luaO_nilobject) + return cast_to(TValue*, p); + else + { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); + } +} + +TValue* luaH_setp(lua_State* L, LuaTable* t, void* key, int tag) +{ + const TValue* p = luaH_getp(t, key, tag); + if (p != luaO_nilobject) + return cast_to(TValue*, p); + else + { + TValue k; + setpvalue(&k, key, tag); + return newkey(L, t, &k); + } +} + +static int updateaboundary(LuaTable* t, int boundary) +{ + if (boundary < t->sizearray && ttisnil(&t->array[boundary - 1])) + { + if (boundary >= 2 && !ttisnil(&t->array[boundary - 2])) + { + maybesetaboundary(t, boundary - 1); + return boundary - 1; + } + } + else if (boundary + 1 < t->sizearray && !ttisnil(&t->array[boundary]) && ttisnil(&t->array[boundary + 1])) + { + maybesetaboundary(t, boundary + 1); + return boundary + 1; + } + + return 0; +} + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn(LuaTable* t) +{ + int boundary = getaboundary(t); + + if (boundary > 0) + { + if (!ttisnil(&t->array[t->sizearray - 1]) && t->node == dummynode) + return t->sizearray; // fast-path: the end of the array in `t' already refers to a boundary + if (boundary < t->sizearray && !ttisnil(&t->array[boundary - 1]) && ttisnil(&t->array[boundary])) + return boundary; // fast-path: boundary already refers to a boundary in `t' + + int foundboundary = updateaboundary(t, boundary); + if (foundboundary > 0) + return foundboundary; + } + + int j = t->sizearray; + + if (j > 0 && ttisnil(&t->array[j - 1])) + { + // "branchless" binary search from Array Layouts for Comparison-Based Searching, Paul Khuong, Pat Morin, 2017. + // note that clang is cmov-shy on cmovs around memory operands, so it will compile this to a branchy loop. + TValue* base = t->array; + int rest = j; + while (int half = rest >> 1) + { + base = ttisnil(&base[half]) ? base : base + half; + rest -= half; + } + int boundary = !ttisnil(base) + int(base - t->array); + maybesetaboundary(t, boundary); + return boundary; + } + else + { + // validate boundary invariant + LUAU_ASSERT(t->node == dummynode || ttisnil(luaH_getnum(t, j + 1))); + return j; + } +} + +LuaTable* luaH_clone(lua_State* L, LuaTable* tt) +{ + LuaTable* t = luaM_newgco(L, LuaTable, sizeof(LuaTable), L->activememcat); + luaC_init(L, t, LUA_TTABLE); + t->metatable = tt->metatable; + t->tmcache = tt->tmcache; + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->nodemask8 = 0; + t->readonly = 0; + t->safeenv = 0; + t->node = cast_to(LuaNode*, dummynode); + t->lastfree = 0; + + if (tt->sizearray) + { + t->array = luaM_newarray(L, tt->sizearray, TValue, t->memcat); + maybesetaboundary(t, getaboundary(tt)); + t->sizearray = tt->sizearray; + + memcpy(t->array, tt->array, t->sizearray * sizeof(TValue)); + } + + if (tt->node != dummynode) + { + int size = 1 << tt->lsizenode; + t->node = luaM_newarray(L, size, LuaNode, t->memcat); + t->lsizenode = tt->lsizenode; + t->nodemask8 = tt->nodemask8; + memcpy(t->node, tt->node, size * sizeof(LuaNode)); + t->lastfree = tt->lastfree; + } + + return t; +} + +void luaH_clear(LuaTable* tt) +{ + // clear array part + for (int i = 0; i < tt->sizearray; ++i) + { + setnilvalue(&tt->array[i]); + } + + maybesetaboundary(tt, 0); + + // clear hash part + if (tt->node != dummynode) + { + int size = sizenode(tt); + tt->lastfree = size; + for (int i = 0; i < size; ++i) + { + LuaNode* n = gnode(tt, i); + setnilvalue(gkey(n)); + setnilvalue(gval(n)); + gnext(n) = 0; + } + } + + // back to empty -> no tag methods present + tt->tmcache = cast_byte(~0); +} diff --git a/thirdparty/luau/upstream/VM/src/ltable.h b/thirdparty/luau/upstream/VM/src/ltable.h new file mode 100644 index 000000000..39c1fa915 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ltable.h @@ -0,0 +1,37 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" + +#define gnode(t, i) (&(t)->node[i]) +#define gkey(n) (&(n)->key) +#define gval(n) (&(n)->val) +#define gnext(n) ((n)->key.next) + +#define gval2slot(t, v) int(cast_to(LuaNode*, static_cast(v)) - t->node) + +// reset cache of absent metamethods, cache is updated in luaT_gettm +#define invalidateTMcache(t) t->tmcache = 0 + +LUAI_FUNC const TValue* luaH_getnum(LuaTable* t, int key); +LUAI_FUNC TValue* luaH_setnum(lua_State* L, LuaTable* t, int key); +LUAI_FUNC const TValue* luaH_getstr(LuaTable* t, TString* key); +LUAI_FUNC TValue* luaH_setstr(lua_State* L, LuaTable* t, TString* key); +LUAI_FUNC const TValue* luaH_getp(LuaTable* t, void* key, int tag); +LUAI_FUNC TValue* luaH_setp(lua_State* L, LuaTable* t, void* key, int tag); +LUAI_FUNC const TValue* luaH_get(LuaTable* t, const TValue* key); +LUAI_FUNC TValue* luaH_set(lua_State* L, LuaTable* t, const TValue* key); +LUAI_FUNC TValue* luaH_newkey(lua_State* L, LuaTable* t, const TValue* key); +LUAI_FUNC LuaTable* luaH_new(lua_State* L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray(lua_State* L, LuaTable* t, int nasize); +LUAI_FUNC void luaH_resizehash(lua_State* L, LuaTable* t, int nhsize); +LUAI_FUNC void luaH_free(lua_State* L, LuaTable* t, struct lua_Page* page); +LUAI_FUNC int luaH_next(lua_State* L, LuaTable* t, StkId key); +LUAI_FUNC int luaH_getn(LuaTable* t); +LUAI_FUNC LuaTable* luaH_clone(lua_State* L, LuaTable* tt); +LUAI_FUNC void luaH_clear(LuaTable* tt); + +#define luaH_setslot(L, t, slot, key) (invalidateTMcache(t), (slot == luaO_nilobject ? luaH_newkey(L, t, key) : cast_to(TValue*, slot))) + +extern const LuaNode luaH_dummynode; diff --git a/thirdparty/luau/upstream/VM/src/ltablib.cpp b/thirdparty/luau/upstream/VM/src/ltablib.cpp new file mode 100644 index 000000000..cdc4c9399 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ltablib.cpp @@ -0,0 +1,628 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lapi.h" +#include "lnumutils.h" +#include "lstate.h" +#include "ltable.h" +#include "lstring.h" +#include "lgc.h" +#include "ldebug.h" +#include "lvm.h" + +static int foreachi(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + int i; + int n = lua_objlen(L, 1); + for (i = 1; i <= n; i++) + { + lua_pushvalue(L, 2); // function + lua_pushinteger(L, i); // 1st argument + lua_rawgeti(L, 1, i); // 2nd argument + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); // remove nil result + } + return 0; +} + +static int foreach (lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); // first key + while (lua_next(L, 1)) + { + lua_pushvalue(L, 2); // function + lua_pushvalue(L, -3); // key + lua_pushvalue(L, -3); // value + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); // remove value and result + } + return 0; +} + +static int maxn(lua_State* L) +{ + double max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + + LuaTable* t = hvalue(L->base); + + for (int i = 0; i < t->sizearray; i++) + { + if (!ttisnil(&t->array[i])) + max = i + 1; + } + + for (int i = 0; i < sizenode(t); i++) + { + LuaNode* n = gnode(t, i); + + if (!ttisnil(gval(n)) && ttisnumber(gkey(n))) + { + double v = nvalue(gkey(n)); + + if (v > max) + max = v; + } + } + + lua_pushnumber(L, max); + return 1; +} + +static int getn(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushinteger(L, lua_objlen(L, 1)); + return 1; +} + +static void moveelements(lua_State* L, int srct, int dstt, int f, int e, int t) +{ + LuaTable* src = hvalue(L->base + (srct - 1)); + LuaTable* dst = hvalue(L->base + (dstt - 1)); + + if (dst->readonly) + luaG_readonlyerror(L); + + int n = e - f + 1; // number of elements to move + + if (unsigned(f) - 1 < unsigned(src->sizearray) && unsigned(t) - 1 < unsigned(dst->sizearray) && + unsigned(f) - 1 + unsigned(n) <= unsigned(src->sizearray) && unsigned(t) - 1 + unsigned(n) <= unsigned(dst->sizearray)) + { + TValue* srcarray = src->array; + TValue* dstarray = dst->array; + + if (t > e || t <= f || (dstt != srct && dst != src)) + { + for (int i = 0; i < n; ++i) + { + TValue* s = &srcarray[f + i - 1]; + TValue* d = &dstarray[t + i - 1]; + setobj2t(L, d, s); + } + } + else + { + for (int i = n - 1; i >= 0; i--) + { + TValue* s = &srcarray[(f + i) - 1]; + TValue* d = &dstarray[(t + i) - 1]; + setobj2t(L, d, s); + } + } + + luaC_barrierfast(L, dst); + } + else + { + if (t > e || t <= f || dst != src) + { + for (int i = 0; i < n; ++i) + { + lua_rawgeti(L, srct, f + i); + lua_rawseti(L, dstt, t + i); + } + } + else + { + for (int i = n - 1; i >= 0; i--) + { + lua_rawgeti(L, srct, f + i); + lua_rawseti(L, dstt, t + i); + } + } + } +} + +static int tinsert(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + int n = lua_objlen(L, 1); + int pos; // where to insert new element + switch (lua_gettop(L)) + { + case 2: + { // called with only 2 arguments + pos = n + 1; // insert new element at the end + break; + } + case 3: + { + pos = luaL_checkinteger(L, 2); // 2nd argument is the position + + // move up elements if necessary + if (1 <= pos && pos <= n) + moveelements(L, 1, 1, pos, n, pos + 1); + break; + } + default: + { + luaL_error(L, "wrong number of arguments to 'insert'"); + } + } + lua_rawseti(L, 1, pos); // t[pos] = v + return 0; +} + +static int tremove(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + int n = lua_objlen(L, 1); + int pos = luaL_optinteger(L, 2, n); + + if (!(1 <= pos && pos <= n)) // position is outside bounds? + return 0; // nothing to remove + lua_rawgeti(L, 1, pos); // result = t[pos] + + moveelements(L, 1, 1, pos + 1, n, pos); + + lua_pushnil(L); + lua_rawseti(L, 1, n); // t[n] = nil + return 1; +} + +/* +** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever +** possible, copy in increasing order, which is better for rehashing. +** "possible" means destination after original range, or smaller +** than origin, or copying to another table. +*/ +static int tmove(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + int f = luaL_checkinteger(L, 2); + int e = luaL_checkinteger(L, 3); + int t = luaL_checkinteger(L, 4); + int tt = !lua_isnoneornil(L, 5) ? 5 : 1; // destination table + luaL_checktype(L, tt, LUA_TTABLE); + + if (e >= f) + { // otherwise, nothing to move + luaL_argcheck(L, f > 0 || e < INT_MAX + f, 3, "too many elements to move"); + int n = e - f + 1; // number of elements to move + luaL_argcheck(L, t <= INT_MAX - n + 1, 4, "destination wrap around"); + + LuaTable* dst = hvalue(L->base + (tt - 1)); + + if (dst->readonly) // also checked in moveelements, but this blocks resizes of r/o tables + luaG_readonlyerror(L); + + if (t > 0 && (t - 1) <= dst->sizearray && (t - 1 + n) > dst->sizearray) + { // grow the destination table array + luaH_resizearray(L, dst, t - 1 + n); + } + + moveelements(L, 1, tt, f, e, t); + } + lua_pushvalue(L, tt); // return destination table + return 1; +} + +static void addfield(lua_State* L, luaL_Strbuf* b, int i, LuaTable* t) +{ + if (t && unsigned(i - 1) < unsigned(t->sizearray) && ttisstring(&t->array[i - 1])) + { + TString* ts = tsvalue(&t->array[i - 1]); + luaL_addlstring(b, getstr(ts), ts->len); + } + else + { + int tt = lua_rawgeti(L, 1, i); + if (tt != LUA_TSTRING && tt != LUA_TNUMBER) + luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", luaL_typename(L, -1), i); + luaL_addvalue(b); + } +} + +static int tconcat(lua_State* L) +{ + size_t lsep; + const char* sep = luaL_optlstring(L, 2, "", &lsep); + luaL_checktype(L, 1, LUA_TTABLE); + int i = luaL_optinteger(L, 3, 1); + int last = luaL_opt(L, luaL_checkinteger, 4, lua_objlen(L, 1)); + + LuaTable* t = hvalue(L->base); + + luaL_Strbuf b; + luaL_buffinit(L, &b); + for (; i < last; i++) + { + addfield(L, &b, i, t); + if (lsep != 0) + luaL_addlstring(&b, sep, lsep); + } + if (i == last) // add last value (if interval was not empty) + addfield(L, &b, i, t); + luaL_pushresult(&b); + return 1; +} + +static int tpack(lua_State* L) +{ + int n = lua_gettop(L); // number of elements to pack + lua_createtable(L, n, 1); // create result table + + LuaTable* t = hvalue(L->top - 1); + + for (int i = 0; i < n; ++i) + { + TValue* e = &t->array[i]; + setobj2t(L, e, L->base + i); + } + + // t.n = number of elements + TValue* nv = luaH_setstr(L, t, luaS_newliteral(L, "n")); + setnvalue(nv, n); + + return 1; // return table +} + +static int tunpack(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + LuaTable* t = hvalue(L->base); + + int i = luaL_optinteger(L, 2, 1); + int e = luaL_opt(L, luaL_checkinteger, 3, lua_objlen(L, 1)); + if (i > e) + return 0; // empty range + unsigned n = (unsigned)e - i; // number of elements minus 1 (avoid overflows) + if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) + luaL_error(L, "too many results to unpack"); + + // fast-path: direct array-to-stack copy + if (i == 1 && int(n) <= t->sizearray) + { + for (i = 0; i < int(n); i++) + setobj2s(L, L->top + i, &t->array[i]); + L->top += n; + } + else + { + // push arg[i..e - 1] (to avoid overflows) + for (; i < e; i++) + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 1, e); // push last element + } + return (int)n; +} + +typedef int (*SortPredicate)(lua_State* L, const TValue* l, const TValue* r); + +static int sort_func(lua_State* L, const TValue* l, const TValue* r) +{ + LUAU_ASSERT(L->top == L->base + 2); // table, function + + setobj2s(L, L->top, &L->base[1]); + setobj2s(L, L->top + 1, l); + setobj2s(L, L->top + 2, r); + L->top += 3; // safe because of LUA_MINSTACK guarantee + luaD_call(L, L->top - 3, 1); + L->top -= 1; // maintain stack depth + + return !l_isfalse(L->top); +} + +inline void sort_swap(lua_State* L, LuaTable* t, int i, int j) +{ + TValue* arr = t->array; + int n = t->sizearray; + LUAU_ASSERT(unsigned(i) < unsigned(n) && unsigned(j) < unsigned(n)); // contract maintained in sort_less after predicate call + + // no barrier required because both elements are in the array before and after the swap + TValue temp; + setobj2s(L, &temp, &arr[i]); + setobj2t(L, &arr[i], &arr[j]); + setobj2t(L, &arr[j], &temp); +} + +inline int sort_less(lua_State* L, LuaTable* t, int i, int j, SortPredicate pred) +{ + TValue* arr = t->array; + int n = t->sizearray; + LUAU_ASSERT(unsigned(i) < unsigned(n) && unsigned(j) < unsigned(n)); // contract maintained in sort_less after predicate call + + int res = pred(L, &arr[i], &arr[j]); + + // predicate call may resize the table, which is invalid + if (t->sizearray != n) + luaL_error(L, "table modified during sorting"); + + return res; +} + +static void sort_siftheap(lua_State* L, LuaTable* t, int l, int u, SortPredicate pred, int root) +{ + LUAU_ASSERT(l <= u); + int count = u - l + 1; + + // process all elements with two children + while (root * 2 + 2 < count) + { + int left = root * 2 + 1, right = root * 2 + 2; + int next = root; + next = sort_less(L, t, l + next, l + left, pred) ? left : next; + next = sort_less(L, t, l + next, l + right, pred) ? right : next; + + if (next == root) + break; + + sort_swap(L, t, l + root, l + next); + root = next; + } + + // process last element if it has just one child + int lastleft = root * 2 + 1; + if (lastleft == count - 1 && sort_less(L, t, l + root, l + lastleft, pred)) + sort_swap(L, t, l + root, l + lastleft); +} + +static void sort_heap(lua_State* L, LuaTable* t, int l, int u, SortPredicate pred) +{ + LUAU_ASSERT(l <= u); + int count = u - l + 1; + + for (int i = count / 2 - 1; i >= 0; --i) + sort_siftheap(L, t, l, u, pred, i); + + for (int i = count - 1; i > 0; --i) + { + sort_swap(L, t, l, l + i); + sort_siftheap(L, t, l, l + i - 1, pred, 0); + } +} + +static void sort_rec(lua_State* L, LuaTable* t, int l, int u, int limit, SortPredicate pred) +{ + // sort range [l..u] (inclusive, 0-based) + while (l < u) + { + // if the limit has been reached, quick sort is going over the permitted nlogn complexity, so we fall back to heap sort + if (limit == 0) + return sort_heap(L, t, l, u, pred); + + // sort elements a[l], a[(l+u)/2] and a[u] + // note: this simultaneously acts as a small sort and a median selector + if (sort_less(L, t, u, l, pred)) // a[u] < a[l]? + sort_swap(L, t, u, l); // swap a[l] - a[u] + if (u - l == 1) + break; // only 2 elements + int m = l + ((u - l) >> 1); // midpoint + if (sort_less(L, t, m, l, pred)) // a[m]= P + while (sort_less(L, t, ++i, p, pred)) + { + if (i >= u) + luaL_error(L, "invalid order function for sorting"); + } + // repeat --j until a[j] <= P + while (sort_less(L, t, p, --j, pred)) + { + if (j <= l) + luaL_error(L, "invalid order function for sorting"); + } + if (j < i) + break; + sort_swap(L, t, i, j); + } + + // swap pivot a[p] with a[i], which is the new midpoint + sort_swap(L, t, p, i); + + // adjust limit to allow 1.5 log2N recursive steps + limit = (limit >> 1) + (limit >> 2); + + // a[l..i-1] <= a[i] == P <= a[i+1..u] + // sort smaller half recursively; the larger half is sorted in the next loop iteration + if (i - l < u - i) + { + sort_rec(L, t, l, i - 1, limit, pred); + l = i + 1; + } + else + { + sort_rec(L, t, i + 1, u, limit, pred); + u = i - 1; + } + } +} + +static int tsort(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + LuaTable* t = hvalue(L->base); + int n = luaH_getn(t); + if (t->readonly) + luaG_readonlyerror(L); + + SortPredicate pred = luaV_lessthan; + if (!lua_isnoneornil(L, 2)) // is there a 2nd argument? + { + luaL_checktype(L, 2, LUA_TFUNCTION); + pred = sort_func; + } + lua_settop(L, 2); // make sure there are two arguments + + if (n > 0) + sort_rec(L, t, 0, n - 1, n, pred); + return 0; +} + +static int tcreate(lua_State* L) +{ + int size = luaL_checkinteger(L, 1); + if (size < 0) + luaL_argerror(L, 1, "size out of range"); + + if (!lua_isnoneornil(L, 2)) + { + lua_createtable(L, size, 0); + LuaTable* t = hvalue(L->top - 1); + + StkId v = L->base + 1; + + for (int i = 0; i < size; ++i) + { + TValue* e = &t->array[i]; + setobj2t(L, e, v); + } + } + else + { + lua_createtable(L, size, 0); + } + + return 1; +} + +static int tfind(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + int init = luaL_optinteger(L, 3, 1); + if (init < 1) + luaL_argerror(L, 3, "index out of range"); + + LuaTable* t = hvalue(L->base); + + for (int i = init;; ++i) + { + const TValue* e = luaH_getnum(t, i); + if (ttisnil(e)) + break; + + StkId v = L->base + 1; + + if (equalobj(L, v, e)) + { + lua_pushinteger(L, i); + return 1; + } + } + + lua_pushnil(L); + return 1; +} + +static int tclear(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + + LuaTable* tt = hvalue(L->base); + if (tt->readonly) + luaG_readonlyerror(L); + + luaH_clear(tt); + return 0; +} + +static int tfreeze(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, !lua_getreadonly(L, 1), 1, "table is already frozen"); + luaL_argcheck(L, !luaL_getmetafield(L, 1, "__metatable"), 1, "table has a protected metatable"); + + lua_setreadonly(L, 1, true); + + lua_pushvalue(L, 1); + return 1; +} + +static int tisfrozen(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + + lua_pushboolean(L, lua_getreadonly(L, 1)); + return 1; +} + +static int tclone(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, !luaL_getmetafield(L, 1, "__metatable"), 1, "table has a protected metatable"); + + LuaTable* tt = luaH_clone(L, hvalue(L->base)); + + TValue v; + sethvalue(L, &v, tt); + luaA_pushobject(L, &v); + + return 1; +} + +static const luaL_Reg tab_funcs[] = { + {"concat", tconcat}, + {"foreach", foreach}, + {"foreachi", foreachi}, + {"getn", getn}, + {"maxn", maxn}, + {"insert", tinsert}, + {"remove", tremove}, + {"sort", tsort}, + {"pack", tpack}, + {"unpack", tunpack}, + {"move", tmove}, + {"create", tcreate}, + {"find", tfind}, + {"clear", tclear}, + {"freeze", tfreeze}, + {"isfrozen", tisfrozen}, + {"clone", tclone}, + {NULL, NULL}, +}; + +int luaopen_table(lua_State* L) +{ + luaL_register(L, LUA_TABLIBNAME, tab_funcs); + + // Lua 5.1 compat + lua_pushcfunction(L, tunpack, "unpack"); + lua_setglobal(L, "unpack"); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/ltm.cpp b/thirdparty/luau/upstream/VM/src/ltm.cpp new file mode 100644 index 000000000..800c76bc2 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ltm.cpp @@ -0,0 +1,159 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "ltm.h" + +#include "lstate.h" +#include "lstring.h" +#include "ludata.h" +#include "ltable.h" +#include "lgc.h" + +#include + +// clang-format off +const char* const luaT_typenames[] = { + // ORDER TYPE + "nil", + "boolean", + + "userdata", + "number", + "vector", + + "string", + + "table", + "function", + "userdata", + "thread", + "buffer", +}; + +const char* const luaT_eventname[] = { + // ORDER TM + "__index", + "__newindex", + "__mode", + "__namecall", + "__call", + "__iter", + "__len", + + "__eq", + + "__add", + "__sub", + "__mul", + "__div", + "__idiv", + "__mod", + "__pow", + "__unm", + + "__lt", + "__le", + "__concat", + "__type", + "__metatable", +}; +// clang-format on + +static_assert(sizeof(luaT_typenames) / sizeof(luaT_typenames[0]) == LUA_T_COUNT, "luaT_typenames size mismatch"); +static_assert(sizeof(luaT_eventname) / sizeof(luaT_eventname[0]) == TM_N, "luaT_eventname size mismatch"); +static_assert(TM_EQ < 8, "fasttm optimization stores a bitfield with metamethods in a byte"); + +void luaT_init(lua_State* L) +{ + int i; + for (i = 0; i < LUA_T_COUNT; i++) + { + L->global->ttname[i] = luaS_new(L, luaT_typenames[i]); + luaS_fix(L->global->ttname[i]); // never collect these names + } + for (i = 0; i < TM_N; i++) + { + L->global->tmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(L->global->tmname[i]); // never collect these names + } +} + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods. +*/ +const TValue* luaT_gettm(LuaTable* events, TMS event, TString* ename) +{ + const TValue* tm = luaH_getstr(events, ename); + LUAU_ASSERT(event <= TM_EQ); + if (ttisnil(tm)) + { // no tag method? + events->tmcache |= cast_byte(1u << event); // cache this fact + return NULL; + } + else + return tm; +} + +const TValue* luaT_gettmbyobj(lua_State* L, const TValue* o, TMS event) +{ + /* + NB: Tag-methods were replaced by meta-methods in Lua 5.0, but the + old names are still around (this function, for example). + */ + LuaTable* mt; + switch (ttype(o)) + { + case LUA_TTABLE: + mt = hvalue(o)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = L->global->mt[ttype(o)]; + } + return (mt ? luaH_getstr(mt, L->global->tmname[event]) : luaO_nilobject); +} + +const TString* luaT_objtypenamestr(lua_State* L, const TValue* o) +{ + // Userdata created by the environment can have a custom type name set in the individual metatable + // If there is no custom name, 'userdata' is returned + if (ttisuserdata(o) && uvalue(o)->tag != UTAG_PROXY && uvalue(o)->metatable) + { + const TValue* type = luaH_getstr(uvalue(o)->metatable, L->global->tmname[TM_TYPE]); + + if (ttisstring(type)) + return tsvalue(type); + + return L->global->ttname[ttype(o)]; + } + + // Tagged lightuserdata can be named using lua_setlightuserdataname + if (ttislightuserdata(o)) + { + int tag = lightuserdatatag(o); + + if (unsigned(tag) < LUA_LUTAG_LIMIT) + { + if (const TString* name = L->global->lightuserdataname[tag]) + return name; + } + } + + // For all types except userdata and table, a global metatable can be set with a global name override + if (LuaTable* mt = L->global->mt[ttype(o)]) + { + const TValue* type = luaH_getstr(mt, L->global->tmname[TM_TYPE]); + + if (ttisstring(type)) + return tsvalue(type); + } + + return L->global->ttname[ttype(o)]; +} + +const char* luaT_objtypename(lua_State* L, const TValue* o) +{ + return getstr(luaT_objtypenamestr(L, o)); +} diff --git a/thirdparty/luau/upstream/VM/src/ltm.h b/thirdparty/luau/upstream/VM/src/ltm.h new file mode 100644 index 000000000..169a0b961 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ltm.h @@ -0,0 +1,57 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" + +/* + * WARNING: if you change the order of this enumeration, + * grep "ORDER TM" + */ +// clang-format off +typedef enum +{ + TM_INDEX, + TM_NEWINDEX, + TM_MODE, + TM_NAMECALL, + TM_CALL, + TM_ITER, + TM_LEN, + + TM_EQ, // last tag method with `fast' access + + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_IDIV, + TM_MOD, + TM_POW, + TM_UNM, + + TM_LT, + TM_LE, + TM_CONCAT, + TM_TYPE, + TM_METATABLE, + + TM_N // number of elements in the enum +} TMS; +// clang-format on + +#define gfasttm(g, et, e) ((et) == NULL ? NULL : ((et)->tmcache & (1u << (e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l, et, e) gfasttm(l->global, et, e) +#define fastnotm(et, e) ((et) == NULL || ((et)->tmcache & (1u << (e)))) + +LUAI_DATA const char* const luaT_typenames[]; +LUAI_DATA const char* const luaT_eventname[]; + +LUAI_FUNC const TValue* luaT_gettm(LuaTable* events, TMS event, TString* ename); +LUAI_FUNC const TValue* luaT_gettmbyobj(lua_State* L, const TValue* o, TMS event); + +LUAI_FUNC const TString* luaT_objtypenamestr(lua_State* L, const TValue* o); +LUAI_FUNC const char* luaT_objtypename(lua_State* L, const TValue* o); + +LUAI_FUNC void luaT_init(lua_State* L); diff --git a/thirdparty/luau/upstream/VM/src/ludata.cpp b/thirdparty/luau/upstream/VM/src/ludata.cpp new file mode 100644 index 000000000..13e870292 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ludata.cpp @@ -0,0 +1,43 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "ludata.h" + +#include "lgc.h" +#include "lmem.h" + +#include + +Udata* luaU_newudata(lua_State* L, size_t s, int tag) +{ + if (s > INT_MAX - sizeof(Udata)) + luaM_toobig(L); + Udata* u = luaM_newgco(L, Udata, sizeudata(s), L->activememcat); + luaC_init(L, u, LUA_TUSERDATA); + u->len = int(s); + u->metatable = NULL; + LUAU_ASSERT(tag >= 0 && tag <= 255); + u->tag = uint8_t(tag); + return u; +} + +void luaU_freeudata(lua_State* L, Udata* u, lua_Page* page) +{ + if (u->tag < LUA_UTAG_LIMIT) + { + lua_Destructor dtor = L->global->udatagc[u->tag]; + // TODO: access to L here is highly unsafe since this is called during internal GC traversal + // certain operations such as lua_getthreaddata are okay, but by and large this risks crashes on improper use + if (dtor) + dtor(L, u->data); + } + else if (u->tag == UTAG_IDTOR) + { + void (*dtor)(void*) = nullptr; + memcpy(&dtor, &u->data + u->len - sizeof(dtor), sizeof(dtor)); + if (dtor) + dtor(u->data); + } + + + luaM_freegco(L, u, sizeudata(u->len), u->memcat, page); +} diff --git a/thirdparty/luau/upstream/VM/src/ludata.h b/thirdparty/luau/upstream/VM/src/ludata.h new file mode 100644 index 000000000..eebe925c8 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/ludata.h @@ -0,0 +1,17 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" + +// special tag value is used for user data with inline dtors +#define UTAG_IDTOR LUA_UTAG_LIMIT + +// special tag value is used for newproxy-created user data (all other user data objects are host-exposed) +#define UTAG_PROXY (LUA_UTAG_LIMIT + 1) + +// userdata larger than 16 bytes will be extended to guarantee 16 byte alignment of subsequent blocks +#define sizeudata(len) (offsetof(Udata, data) + (len > 16 ? ((len + 15) & ~15) : len)) + +LUAI_FUNC Udata* luaU_newudata(lua_State* L, size_t s, int tag); +LUAI_FUNC void luaU_freeudata(lua_State* L, Udata* u, struct lua_Page* page); diff --git a/thirdparty/luau/upstream/VM/src/lutf8lib.cpp b/thirdparty/luau/upstream/VM/src/lutf8lib.cpp new file mode 100644 index 000000000..a45db259a --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lutf8lib.cpp @@ -0,0 +1,296 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lualib.h" + +#include "lcommon.h" + +#define MAXUNICODE 0x10FFFF + +#define iscont(p) ((*(p) & 0xC0) == 0x80) + +// from strlib +// translate a relative string position: negative means back from end +static int u_posrelat(int pos, size_t len) +{ + if (pos >= 0) + return pos; + else if (0u - (size_t)pos > len) + return 0; + else + return (int)len + pos + 1; +} + +/* +** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. +*/ +static const char* utf8_decode(const char* o, int* val) +{ + static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; + const unsigned char* s = (const unsigned char*)o; + unsigned int c = s[0]; + unsigned int res = 0; // final result + if (c < 0x80) // ascii? + res = c; + else + { + int count = 0; // to count number of continuation bytes + while (c & 0x40) + { // still have continuation bytes? + int cc = s[++count]; // read next byte + if ((cc & 0xC0) != 0x80) // not a continuation byte? + return NULL; // invalid byte sequence + res = (res << 6) | (cc & 0x3F); // add lower 6 bits from cont. byte + c <<= 1; // to test next bit + } + res |= ((c & 0x7F) << (count * 5)); // add first byte + if (count > 3 || res > MAXUNICODE || res <= limits[count]) + return NULL; // invalid byte sequence + if (unsigned(res - 0xD800) < 0x800) + return NULL; // surrogate + s += count; // skip continuation bytes read + } + if (val) + *val = res; + return (const char*)s + 1; // +1 to include first byte +} + +/* +** utf8len(s [, i [, j]]) --> number of characters that start in the +** range [i,j], or nil + current position if 's' is not well formed in +** that interval +*/ +static int utflen(lua_State* L) +{ + int n = 0; + size_t len; + const char* s = luaL_checklstring(L, 1, &len); + int posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + int posj = u_posrelat(luaL_optinteger(L, 3, -1), len); + luaL_argcheck(L, 1 <= posi && --posi <= (int)len, 2, "initial position out of string"); + luaL_argcheck(L, --posj < (int)len, 3, "final position out of string"); + while (posi <= posj) + { + const char* s1 = utf8_decode(s + posi, NULL); + if (s1 == NULL) + { // conversion error? + lua_pushnil(L); // return nil ... + lua_pushinteger(L, posi + 1); // ... and current position + return 2; + } + posi = (int)(s1 - s); + n++; + } + lua_pushinteger(L, n); + return 1; +} + +/* +** codepoint(s, [i, [j]]) -> returns codepoints for all characters +** that start in the range [i,j] +*/ +static int codepoint(lua_State* L) +{ + size_t len; + const char* s = luaL_checklstring(L, 1, &len); + int posi = u_posrelat(luaL_optinteger(L, 2, 1), len); + int pose = u_posrelat(luaL_optinteger(L, 3, posi), len); + int n; + const char* se; + luaL_argcheck(L, posi >= 1, 2, "out of range"); + luaL_argcheck(L, pose <= (int)len, 3, "out of range"); + if (posi > pose) + return 0; // empty interval; return no values + if (pose - posi >= INT_MAX) // (int -> int) overflow? + luaL_error(L, "string slice too long"); + n = (int)(pose - posi) + 1; + luaL_checkstack(L, n, "string slice too long"); + n = 0; + se = s + pose; + for (s += posi - 1; s < se;) + { + int code; + s = utf8_decode(s, &code); + if (s == NULL) + luaL_error(L, "invalid UTF-8 code"); + lua_pushinteger(L, code); + n++; + } + return n; +} + +// from Lua 5.3 lobject.h +#define UTF8BUFFSZ 8 + +// from Lua 5.3 lobject.c, copied verbatim + static +static int luaO_utf8esc(char* buff, unsigned long x) +{ + int n = 1; // number of bytes put in buffer (backwards) + LUAU_ASSERT(x <= 0x10FFFF); + if (x < 0x80) // ascii? + buff[UTF8BUFFSZ - 1] = cast_to(char, x); + else + { // need continuation bytes + unsigned int mfb = 0x3f; // maximum that fits in first byte + do + { // add continuation bytes + buff[UTF8BUFFSZ - (n++)] = cast_to(char, 0x80 | (x & 0x3f)); + x >>= 6; // remove added bits + mfb >>= 1; // now there is one less bit available in first byte + } while (x > mfb); // still needs continuation byte? + buff[UTF8BUFFSZ - n] = cast_to(char, (~mfb << 1) | x); // add first byte + } + return n; +} + +// lighter replacement for pushutfchar; doesn't push any string onto the stack +static int buffutfchar(lua_State* L, int arg, char* buff, const char** charstr) +{ + int code = luaL_checkinteger(L, arg); + luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); + int l = luaO_utf8esc(buff, cast_to(long, code)); + *charstr = buff + UTF8BUFFSZ - l; + return l; +} + +/* +** utfchar(n1, n2, ...) -> char(n1)..char(n2)... +** +** This version avoids the need to make more invasive upgrades elsewhere (like +** implementing the %U escape in lua_pushfstring) and avoids pushing string +** objects for each codepoint in the multi-argument case. -Jovanni +*/ +static int utfchar(lua_State* L) +{ + char buff[UTF8BUFFSZ]; + const char* charstr; + + int n = lua_gettop(L); // number of arguments + if (n == 1) + { // optimize common case of single char + int l = buffutfchar(L, 1, buff, &charstr); + lua_pushlstring(L, charstr, l); + } + else + { + luaL_Strbuf b; + luaL_buffinit(L, &b); + for (int i = 1; i <= n; i++) + { + int l = buffutfchar(L, i, buff, &charstr); + luaL_addlstring(&b, charstr, l); + } + luaL_pushresult(&b); + } + return 1; +} + +/* +** offset(s, n, [i]) -> index where n-th character counting from +** position 'i' starts; 0 means character at 'i'. +*/ +static int byteoffset(lua_State* L) +{ + size_t len; + const char* s = luaL_checklstring(L, 1, &len); + int n = luaL_checkinteger(L, 2); + int posi = (n >= 0) ? 1 : (int)len + 1; + posi = u_posrelat(luaL_optinteger(L, 3, posi), len); + luaL_argcheck(L, 1 <= posi && --posi <= (int)len, 3, "position out of range"); + if (n == 0) + { + // find beginning of current byte sequence + while (posi > 0 && iscont(s + posi)) + posi--; + } + else + { + if (iscont(s + posi)) + luaL_error(L, "initial position is a continuation byte"); + if (n < 0) + { + while (n < 0 && posi > 0) + { // move back + do + { // find beginning of previous character + posi--; + } while (posi > 0 && iscont(s + posi)); + n++; + } + } + else + { + n--; // do not move for 1st character + while (n > 0 && posi < (int)len) + { + do + { // find beginning of next character + posi++; + } while (iscont(s + posi)); // (cannot pass final '\0') + n--; + } + } + } + if (n == 0) // did it find given character? + lua_pushinteger(L, posi + 1); + else // no such character + lua_pushnil(L); + return 1; +} + +static int iter_aux(lua_State* L) +{ + size_t len; + const char* s = luaL_checklstring(L, 1, &len); + int n = lua_tointeger(L, 2) - 1; + if (n < 0) // first iteration? + n = 0; // start from here + else if (n < (int)len) + { + n++; // skip current byte + while (iscont(s + n)) + n++; // and its continuations + } + if (n >= (int)len) + return 0; // no more codepoints + else + { + int code; + const char* next = utf8_decode(s + n, &code); + if (next == NULL || iscont(next)) + luaL_error(L, "invalid UTF-8 code"); + lua_pushinteger(L, n + 1); + lua_pushinteger(L, code); + return 2; + } +} + +static int iter_codes(lua_State* L) +{ + luaL_checkstring(L, 1); + lua_pushcfunction(L, iter_aux, NULL); + lua_pushvalue(L, 1); + lua_pushinteger(L, 0); + return 3; +} + +// pattern to match a single UTF-8 character +#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" + +static const luaL_Reg funcs[] = { + {"offset", byteoffset}, + {"codepoint", codepoint}, + {"char", utfchar}, + {"len", utflen}, + {"codes", iter_codes}, + {NULL, NULL}, +}; + +int luaopen_utf8(lua_State* L) +{ + luaL_register(L, LUA_UTF8LIBNAME, funcs); + + lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT) / sizeof(char) - 1); + lua_setfield(L, -2, "charpattern"); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lveclib.cpp b/thirdparty/luau/upstream/VM/src/lveclib.cpp new file mode 100644 index 000000000..89a24379c --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lveclib.cpp @@ -0,0 +1,360 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +#include "lualib.h" + +#include "lcommon.h" +#include "lnumutils.h" + +#include + +static int vector_create(lua_State* L) +{ + // checking argument count to avoid accepting 'nil' as a valid value + int count = lua_gettop(L); + + double x = luaL_checknumber(L, 1); + double y = luaL_checknumber(L, 2); + double z = count >= 3 ? luaL_checknumber(L, 3) : 0.0; + +#if LUA_VECTOR_SIZE == 4 + double w = count >= 4 ? luaL_checknumber(L, 4) : 0.0; + + lua_pushvector(L, float(x), float(y), float(z), float(w)); +#else + lua_pushvector(L, float(x), float(y), float(z)); +#endif + + return 1; +} + +static int vector_magnitude(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + lua_pushnumber(L, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3])); +#else + lua_pushnumber(L, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])); +#endif + + return 1; +} + +static int vector_normalize(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + float invSqrt = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + + lua_pushvector(L, v[0] * invSqrt, v[1] * invSqrt, v[2] * invSqrt, v[3] * invSqrt); +#else + float invSqrt = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + + lua_pushvector(L, v[0] * invSqrt, v[1] * invSqrt, v[2] * invSqrt); +#endif + + return 1; +} + +static int vector_cross(lua_State* L) +{ + const float* a = luaL_checkvector(L, 1); + const float* b = luaL_checkvector(L, 2); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], 0.0f); +#else + lua_pushvector(L, a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]); +#endif + + return 1; +} + +static int vector_dot(lua_State* L) +{ + const float* a = luaL_checkvector(L, 1); + const float* b = luaL_checkvector(L, 2); + +#if LUA_VECTOR_SIZE == 4 + lua_pushnumber(L, a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]); +#else + lua_pushnumber(L, a[0] * b[0] + a[1] * b[1] + a[2] * b[2]); +#endif + + return 1; +} + +static int vector_angle(lua_State* L) +{ + const float* a = luaL_checkvector(L, 1); + const float* b = luaL_checkvector(L, 2); + const float* axis = luaL_optvector(L, 3, nullptr); + + // cross(a, b) + float cross[] = {a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]}; + + double sinA = sqrt(cross[0] * cross[0] + cross[1] * cross[1] + cross[2] * cross[2]); + double cosA = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + double angle = atan2(sinA, cosA); + + if (axis) + { + if (cross[0] * axis[0] + cross[1] * axis[1] + cross[2] * axis[2] < 0.0f) + angle = -angle; + } + + lua_pushnumber(L, angle); + return 1; +} + +static int vector_floor(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, floorf(v[0]), floorf(v[1]), floorf(v[2]), floorf(v[3])); +#else + lua_pushvector(L, floorf(v[0]), floorf(v[1]), floorf(v[2])); +#endif + + return 1; +} + +static int vector_ceil(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, ceilf(v[0]), ceilf(v[1]), ceilf(v[2]), ceilf(v[3])); +#else + lua_pushvector(L, ceilf(v[0]), ceilf(v[1]), ceilf(v[2])); +#endif + + return 1; +} + +static int vector_abs(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, fabsf(v[0]), fabsf(v[1]), fabsf(v[2]), fabsf(v[3])); +#else + lua_pushvector(L, fabsf(v[0]), fabsf(v[1]), fabsf(v[2])); +#endif + + return 1; +} + +static int vector_sign(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, luaui_signf(v[0]), luaui_signf(v[1]), luaui_signf(v[2]), luaui_signf(v[3])); +#else + lua_pushvector(L, luaui_signf(v[0]), luaui_signf(v[1]), luaui_signf(v[2])); +#endif + + return 1; +} + +static int vector_clamp(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + const float* min = luaL_checkvector(L, 2); + const float* max = luaL_checkvector(L, 3); + + luaL_argcheck(L, min[0] <= max[0], 3, "max.x must be greater than or equal to min.x"); + luaL_argcheck(L, min[1] <= max[1], 3, "max.y must be greater than or equal to min.y"); + luaL_argcheck(L, min[2] <= max[2], 3, "max.z must be greater than or equal to min.z"); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector( + L, + luaui_clampf(v[0], min[0], max[0]), + luaui_clampf(v[1], min[1], max[1]), + luaui_clampf(v[2], min[2], max[2]), + luaui_clampf(v[3], min[3], max[3]) + ); +#else + lua_pushvector(L, luaui_clampf(v[0], min[0], max[0]), luaui_clampf(v[1], min[1], max[1]), luaui_clampf(v[2], min[2], max[2])); +#endif + + return 1; +} + +static int vector_min(lua_State* L) +{ + int n = lua_gettop(L); + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + float result[] = {v[0], v[1], v[2], v[3]}; +#else + float result[] = {v[0], v[1], v[2]}; +#endif + + for (int i = 2; i <= n; i++) + { + const float* b = luaL_checkvector(L, i); + + if (b[0] < result[0]) + result[0] = b[0]; + if (b[1] < result[1]) + result[1] = b[1]; + if (b[2] < result[2]) + result[2] = b[2]; +#if LUA_VECTOR_SIZE == 4 + if (b[3] < result[3]) + result[3] = b[3]; +#endif + } + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, result[0], result[1], result[2], result[3]); +#else + lua_pushvector(L, result[0], result[1], result[2]); +#endif + + return 1; +} + +static int vector_max(lua_State* L) +{ + int n = lua_gettop(L); + const float* v = luaL_checkvector(L, 1); + +#if LUA_VECTOR_SIZE == 4 + float result[] = {v[0], v[1], v[2], v[3]}; +#else + float result[] = {v[0], v[1], v[2]}; +#endif + + for (int i = 2; i <= n; i++) + { + const float* b = luaL_checkvector(L, i); + + if (b[0] > result[0]) + result[0] = b[0]; + if (b[1] > result[1]) + result[1] = b[1]; + if (b[2] > result[2]) + result[2] = b[2]; +#if LUA_VECTOR_SIZE == 4 + if (b[3] > result[3]) + result[3] = b[3]; +#endif + } + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, result[0], result[1], result[2], result[3]); +#else + lua_pushvector(L, result[0], result[1], result[2]); +#endif + + return 1; +} + +static int vector_index(lua_State* L) +{ + const float* v = luaL_checkvector(L, 1); + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + + // field access implementation mirrors the fast-path we have in the VM + if (namelen == 1) + { + int ic = (name[0] | ' ') - 'x'; + +#if LUA_VECTOR_SIZE == 4 + // 'w' is before 'x' in ascii, so ic is -1 when indexing with 'w' + if (ic == -1) + ic = 3; +#endif + + if (unsigned(ic) < LUA_VECTOR_SIZE) + { + lua_pushnumber(L, v[ic]); + return 1; + } + } + + luaL_error(L, "attempt to index vector with '%s'", name); +} + +static int vector_lerp(lua_State* L) +{ + const float* a = luaL_checkvector(L, 1); + const float* b = luaL_checkvector(L, 2); + const float t = static_cast(luaL_checknumber(L, 3)); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), luai_lerpf(a[2], b[2], t), luai_lerpf(a[3], b[3], t)); +#else + lua_pushvector(L, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), luai_lerpf(a[2], b[2], t)); +#endif + + return 1; +} + +static const luaL_Reg vectorlib[] = { + {"create", vector_create}, + {"magnitude", vector_magnitude}, + {"normalize", vector_normalize}, + {"cross", vector_cross}, + {"dot", vector_dot}, + {"angle", vector_angle}, + {"floor", vector_floor}, + {"ceil", vector_ceil}, + {"abs", vector_abs}, + {"sign", vector_sign}, + {"clamp", vector_clamp}, + {"max", vector_max}, + {"min", vector_min}, + {"lerp", vector_lerp}, + {NULL, NULL}, +}; + +static void createmetatable(lua_State* L) +{ + lua_createtable(L, 0, 1); // create metatable for vectors + + // push dummy vector +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, 0.0f, 0.0f, 0.0f, 0.0f); +#else + lua_pushvector(L, 0.0f, 0.0f, 0.0f); +#endif + + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); // set vector metatable + lua_pop(L, 1); // pop dummy vector + + lua_pushcfunction(L, vector_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable +} + +int luaopen_vector(lua_State* L) +{ + luaL_register(L, LUA_VECLIBNAME, vectorlib); + +#if LUA_VECTOR_SIZE == 4 + lua_pushvector(L, 0.0f, 0.0f, 0.0f, 0.0f); + lua_setfield(L, -2, "zero"); + lua_pushvector(L, 1.0f, 1.0f, 1.0f, 1.0f); + lua_setfield(L, -2, "one"); +#else + lua_pushvector(L, 0.0f, 0.0f, 0.0f); + lua_setfield(L, -2, "zero"); + lua_pushvector(L, 1.0f, 1.0f, 1.0f); + lua_setfield(L, -2, "one"); +#endif + + createmetatable(L); + + return 1; +} diff --git a/thirdparty/luau/upstream/VM/src/lvm.h b/thirdparty/luau/upstream/VM/src/lvm.h new file mode 100644 index 000000000..6989bcee5 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lvm.h @@ -0,0 +1,37 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#pragma once + +#include "lobject.h" +#include "ltm.h" + +#define tostring(L, o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o, n) (ttype(o) == LUA_TNUMBER || (((o) = luaV_tonumber(o, n)) != NULL)) + +#define equalobj(L, o1, o2) (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + +LUAI_FUNC int luaV_strcmp(const TString* ls, const TString* rs); +LUAI_FUNC int luaV_lessthan(lua_State* L, const TValue* l, const TValue* r); +LUAI_FUNC int luaV_lessequal(lua_State* L, const TValue* l, const TValue* r); +LUAI_FUNC int luaV_equalval(lua_State* L, const TValue* t1, const TValue* t2); + +template +void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); + +LUAI_FUNC void luaV_dolen(lua_State* L, StkId ra, const TValue* rb); +LUAI_FUNC const TValue* luaV_tonumber(const TValue* obj, TValue* n); +LUAI_FUNC const float* luaV_tovector(const TValue* obj); +LUAI_FUNC int luaV_tostring(lua_State* L, StkId obj); +LUAI_FUNC void luaV_gettable(lua_State* L, const TValue* t, TValue* key, StkId val); +LUAI_FUNC void luaV_settable(lua_State* L, const TValue* t, TValue* key, StkId val); +LUAI_FUNC void luaV_concat(lua_State* L, int total, int last); +LUAI_FUNC void luaV_getimport(lua_State* L, LuaTable* env, TValue* k, StkId res, uint32_t id, bool propagatenil); +LUAI_FUNC void luaV_prepareFORN(lua_State* L, StkId plimit, StkId pstep, StkId pinit); +LUAI_FUNC void luaV_callTM(lua_State* L, int nparams, int res); +LUAI_FUNC void luaV_tryfuncTM(lua_State* L, StkId func); + +LUAI_FUNC void luau_execute(lua_State* L); +LUAI_FUNC int luau_precall(lua_State* L, struct lua_TValue* func, int nresults); +LUAI_FUNC void luau_poscall(lua_State* L, StkId first); +LUAI_FUNC void luau_callhook(lua_State* L, lua_Hook hook, void* userdata); diff --git a/thirdparty/luau/upstream/VM/src/lvmexecute.cpp b/thirdparty/luau/upstream/VM/src/lvmexecute.cpp new file mode 100644 index 000000000..4ad6dccff --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lvmexecute.cpp @@ -0,0 +1,3155 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lvm.h" + +#include "lstate.h" +#include "ltable.h" +#include "lfunc.h" +#include "lstring.h" +#include "lgc.h" +#include "lmem.h" +#include "ldebug.h" +#include "ldo.h" +#include "lbuiltins.h" +#include "lnumutils.h" +#include "lbytecode.h" + +#include + +// Disable c99-designator to avoid the warning in computed goto dispatch table +#ifdef __clang__ +#if __has_warning("-Wc99-designator") +#pragma clang diagnostic ignored "-Wc99-designator" +#endif +#endif + +// When working with VM code, pay attention to these rules for correctness: +// 1. Many external Lua functions can fail; for them to fail and be able to generate a proper stack, we need to copy pc to L->ci->savedpc before the +// call +// 2. Many external Lua functions can reallocate the stack. This invalidates stack pointers in VM C stack frame, most importantly base, but also +// ra/rb/rc! +// 3. VM_PROTECT macro saves savedpc and restores base for you; most external calls need to be wrapped into that. However, it does NOT restore +// ra/rb/rc! +// 4. When copying an object to any existing object as a field, generally speaking you need to call luaC_barrier! Be careful with all setobj calls +// 5. To make 4 easier to follow, please use setobj2s for copies to stack, setobj2t for writes to tables, and setobj for other copies. +// 6. You can define HARDSTACKTESTS in luaconf.h which will aggressively realloc stack; with address sanitizer this should be effective at finding +// stack corruption bugs +// 7. Many external Lua functions can call GC! GC will *not* traverse pointers to new objects that aren't reachable from Lua root. Be careful when +// creating new Lua objects, store them to stack soon. + +// When calling luau_callTM, we usually push the arguments to the top of the stack. +// This is safe to do for complicated reasons: +// - stack guarantees EXTRA_STACK room beyond stack_last (see luaD_reallocstack) +// - stack reallocation copies values past stack_last + +// All external function calls that can cause stack realloc or Lua calls have to be wrapped in VM_PROTECT +// This makes sure that we save the pc (in case the Lua call needs to generate a backtrace) before the call, +// and restores the stack pointer after in case stack gets reallocated +// Should only be used on the slow paths. +#define VM_PROTECT(x) \ + { \ + L->ci->savedpc = pc; \ + { \ + x; \ + }; \ + base = L->base; \ + } + +// Some external functions can cause an error, but never reallocate the stack; for these, VM_PROTECT_PC() is +// a cheaper version of VM_PROTECT that can be called before the external call. +#define VM_PROTECT_PC() L->ci->savedpc = pc + +#define VM_REG(i) (LUAU_ASSERT(unsigned(i) < unsigned(L->top - base)), &base[i]) +#define VM_KV(i) (LUAU_ASSERT(unsigned(i) < unsigned(cl->l.p->sizek)), &k[i]) +#define VM_UV(i) (LUAU_ASSERT(unsigned(i) < unsigned(cl->nupvalues)), &cl->l.uprefs[i]) + +#define VM_PATCH_C(pc, slot) *const_cast(pc) = ((uint8_t(slot) << 24) | (0x00ffffffu & *(pc))) +#define VM_PATCH_E(pc, slot) *const_cast(pc) = ((uint32_t(slot) << 8) | (0x000000ffu & *(pc))) + +#define VM_INTERRUPT() \ + { \ + void (*interrupt)(lua_State*, int) = L->global->cb.interrupt; \ + if (LUAU_UNLIKELY(!!interrupt)) \ + { /* the interrupt hook is called right before we advance pc */ \ + VM_PROTECT(L->ci->savedpc++; interrupt(L, -1)); \ + if (L->status != 0) \ + { \ + L->ci->savedpc--; \ + goto exit; \ + } \ + } \ + } + +#define VM_DISPATCH_OP(op) &&CASE_##op + +#define VM_DISPATCH_TABLE() \ + VM_DISPATCH_OP(LOP_NOP), VM_DISPATCH_OP(LOP_BREAK), VM_DISPATCH_OP(LOP_LOADNIL), VM_DISPATCH_OP(LOP_LOADB), VM_DISPATCH_OP(LOP_LOADN), \ + VM_DISPATCH_OP(LOP_LOADK), VM_DISPATCH_OP(LOP_MOVE), VM_DISPATCH_OP(LOP_GETGLOBAL), VM_DISPATCH_OP(LOP_SETGLOBAL), \ + VM_DISPATCH_OP(LOP_GETUPVAL), VM_DISPATCH_OP(LOP_SETUPVAL), VM_DISPATCH_OP(LOP_CLOSEUPVALS), VM_DISPATCH_OP(LOP_GETIMPORT), \ + VM_DISPATCH_OP(LOP_GETTABLE), VM_DISPATCH_OP(LOP_SETTABLE), VM_DISPATCH_OP(LOP_GETTABLEKS), VM_DISPATCH_OP(LOP_SETTABLEKS), \ + VM_DISPATCH_OP(LOP_GETTABLEN), VM_DISPATCH_OP(LOP_SETTABLEN), VM_DISPATCH_OP(LOP_NEWCLOSURE), VM_DISPATCH_OP(LOP_NAMECALL), \ + VM_DISPATCH_OP(LOP_CALL), VM_DISPATCH_OP(LOP_RETURN), VM_DISPATCH_OP(LOP_JUMP), VM_DISPATCH_OP(LOP_JUMPBACK), VM_DISPATCH_OP(LOP_JUMPIF), \ + VM_DISPATCH_OP(LOP_JUMPIFNOT), VM_DISPATCH_OP(LOP_JUMPIFEQ), VM_DISPATCH_OP(LOP_JUMPIFLE), VM_DISPATCH_OP(LOP_JUMPIFLT), \ + VM_DISPATCH_OP(LOP_JUMPIFNOTEQ), VM_DISPATCH_OP(LOP_JUMPIFNOTLE), VM_DISPATCH_OP(LOP_JUMPIFNOTLT), VM_DISPATCH_OP(LOP_ADD), \ + VM_DISPATCH_OP(LOP_SUB), VM_DISPATCH_OP(LOP_MUL), VM_DISPATCH_OP(LOP_DIV), VM_DISPATCH_OP(LOP_MOD), VM_DISPATCH_OP(LOP_POW), \ + VM_DISPATCH_OP(LOP_ADDK), VM_DISPATCH_OP(LOP_SUBK), VM_DISPATCH_OP(LOP_MULK), VM_DISPATCH_OP(LOP_DIVK), VM_DISPATCH_OP(LOP_MODK), \ + VM_DISPATCH_OP(LOP_POWK), VM_DISPATCH_OP(LOP_AND), VM_DISPATCH_OP(LOP_OR), VM_DISPATCH_OP(LOP_ANDK), VM_DISPATCH_OP(LOP_ORK), \ + VM_DISPATCH_OP(LOP_CONCAT), VM_DISPATCH_OP(LOP_NOT), VM_DISPATCH_OP(LOP_MINUS), VM_DISPATCH_OP(LOP_LENGTH), VM_DISPATCH_OP(LOP_NEWTABLE), \ + VM_DISPATCH_OP(LOP_DUPTABLE), VM_DISPATCH_OP(LOP_SETLIST), VM_DISPATCH_OP(LOP_FORNPREP), VM_DISPATCH_OP(LOP_FORNLOOP), \ + VM_DISPATCH_OP(LOP_FORGLOOP), VM_DISPATCH_OP(LOP_FORGPREP_INEXT), VM_DISPATCH_OP(LOP_FASTCALL3), VM_DISPATCH_OP(LOP_FORGPREP_NEXT), \ + VM_DISPATCH_OP(LOP_NATIVECALL), VM_DISPATCH_OP(LOP_GETVARARGS), VM_DISPATCH_OP(LOP_DUPCLOSURE), VM_DISPATCH_OP(LOP_PREPVARARGS), \ + VM_DISPATCH_OP(LOP_LOADKX), VM_DISPATCH_OP(LOP_JUMPX), VM_DISPATCH_OP(LOP_FASTCALL), VM_DISPATCH_OP(LOP_COVERAGE), \ + VM_DISPATCH_OP(LOP_CAPTURE), VM_DISPATCH_OP(LOP_SUBRK), VM_DISPATCH_OP(LOP_DIVRK), VM_DISPATCH_OP(LOP_FASTCALL1), \ + VM_DISPATCH_OP(LOP_FASTCALL2), VM_DISPATCH_OP(LOP_FASTCALL2K), VM_DISPATCH_OP(LOP_FORGPREP), VM_DISPATCH_OP(LOP_JUMPXEQKNIL), \ + VM_DISPATCH_OP(LOP_JUMPXEQKB), VM_DISPATCH_OP(LOP_JUMPXEQKN), VM_DISPATCH_OP(LOP_JUMPXEQKS), VM_DISPATCH_OP(LOP_IDIV), \ + VM_DISPATCH_OP(LOP_IDIVK), + +#if defined(__GNUC__) || defined(__clang__) +#define VM_USE_CGOTO 1 +#else +#define VM_USE_CGOTO 0 +#endif + +/** + * These macros help dispatching Luau opcodes using either case + * statements or computed goto. + * VM_CASE(op) Generates either a case statement or a label + * VM_NEXT() fetch a byte and dispatch or jump to the beginning of the switch statement + * VM_CONTINUE() Use an opcode override to dispatch with computed goto or + * switch statement to skip a LOP_BREAK instruction. + */ +#if VM_USE_CGOTO +#define VM_CASE(op) CASE_##op: +#define VM_NEXT() goto*(SingleStep ? &&dispatch : kDispatchTable[LUAU_INSN_OP(*pc)]) +#define VM_CONTINUE(op) goto* kDispatchTable[uint8_t(op)] +#else +#define VM_CASE(op) case op: +#define VM_NEXT() goto dispatch +#define VM_CONTINUE(op) \ + dispatchOp = uint8_t(op); \ + goto dispatchContinue +#endif + +// Does VM support native execution via ExecutionCallbacks? We mostly assume it does but keep the define to make it easy to quantify the cost. +#define VM_HAS_NATIVE 1 + +LUAU_NOINLINE void luau_callhook(lua_State* L, lua_Hook hook, void* userdata) +{ + ptrdiff_t base = savestack(L, L->base); + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + int status = L->status; + + // if the hook is called externally on a paused thread, we need to make sure the paused thread can emit Luau calls + if (status == LUA_YIELD || status == LUA_BREAK) + { + L->status = 0; + L->base = L->ci->base; + } + + Closure* cl = clvalue(L->ci->func); + + // note: the pc expectations of the hook are matching the general "pc points to next instruction" + // however, for the hook to be able to continue execution from the same point, this is called with savedpc at the *current* instruction + // this needs to be called before luaD_checkstack in case it fails to reallocate stack + const Instruction* oldsavedpc = L->ci->savedpc; + + if (L->ci->savedpc && L->ci->savedpc != cl->l.p->code + cl->l.p->sizecode) + L->ci->savedpc++; + + luaD_checkstack(L, LUA_MINSTACK); // ensure minimum stack size + L->ci->top = L->top + LUA_MINSTACK; + LUAU_ASSERT(L->ci->top <= L->stack_last); + + lua_Debug ar; + ar.currentline = cl->isC ? -1 : luaG_getline(cl->l.p, pcRel(L->ci->savedpc, cl->l.p)); + ar.userdata = userdata; + + hook(L, &ar); + + L->ci->savedpc = oldsavedpc; + + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + + // note that we only restore the paused state if the hook hasn't yielded by itself + if (status == LUA_YIELD && L->status != LUA_YIELD) + { + L->status = LUA_YIELD; + L->base = restorestack(L, base); + } + else if (status == LUA_BREAK) + { + LUAU_ASSERT(L->status != LUA_BREAK); // hook shouldn't break again + + L->status = LUA_BREAK; + L->base = restorestack(L, base); + } +} + +inline bool luau_skipstep(uint8_t op) +{ + return op == LOP_PREPVARARGS || op == LOP_BREAK; +} + +template +static void luau_execute(lua_State* L) +{ +#if VM_USE_CGOTO + static const void* kDispatchTable[256] = {VM_DISPATCH_TABLE()}; +#endif + + // the critical interpreter state, stored in locals for performance + // the hope is that these map to registers without spilling (which is not true for x86 :/) + Closure* cl; + StkId base; + TValue* k; + const Instruction* pc; + + LUAU_ASSERT(isLua(L->ci)); + LUAU_ASSERT(L->isactive); + LUAU_ASSERT(!isblack(obj2gco(L))); // we don't use luaC_threadbarrier because active threads never turn black + +#if VM_HAS_NATIVE + if ((L->ci->flags & LUA_CALLINFO_NATIVE) && !SingleStep) + { + Proto* p = clvalue(L->ci->func)->l.p; + LUAU_ASSERT(p->execdata); + + if (L->global->ecb.enter(L, p) == 0) + return; + } + +reentry: +#endif + + LUAU_ASSERT(isLua(L->ci)); + + pc = L->ci->savedpc; + cl = clvalue(L->ci->func); + base = L->base; + k = cl->l.p->k; + + VM_NEXT(); // starts the interpreter "loop" + + { + dispatch: + // Note: this code doesn't always execute! on some platforms we use computed goto which bypasses all of this unless we run in single-step mode + // Therefore only ever put assertions here. + LUAU_ASSERT(base == L->base && L->base == L->ci->base); + LUAU_ASSERT(base <= L->top && L->top <= L->stack + L->stacksize); + + // ... and singlestep logic :) + if (SingleStep) + { + if (L->global->cb.debugstep && !luau_skipstep(LUAU_INSN_OP(*pc))) + { + VM_PROTECT(luau_callhook(L, L->global->cb.debugstep, NULL)); + + // allow debugstep hook to put thread into error/yield state + if (L->status != 0) + goto exit; + } + +#if VM_USE_CGOTO + VM_CONTINUE(LUAU_INSN_OP(*pc)); +#endif + } + +#if !VM_USE_CGOTO + size_t dispatchOp = LUAU_INSN_OP(*pc); + + dispatchContinue: + switch (dispatchOp) +#endif + { + VM_CASE(LOP_NOP) + { + Instruction insn = *pc++; + LUAU_ASSERT(insn == 0); + VM_NEXT(); + } + + VM_CASE(LOP_LOADNIL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + setnilvalue(ra); + VM_NEXT(); + } + + VM_CASE(LOP_LOADB) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + setbvalue(ra, LUAU_INSN_B(insn)); + + pc += LUAU_INSN_C(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_LOADN) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + setnvalue(ra, LUAU_INSN_D(insn)); + VM_NEXT(); + } + + VM_CASE(LOP_LOADK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_D(insn)); + + setobj2s(L, ra, kv); + VM_NEXT(); + } + + VM_CASE(LOP_MOVE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + + setobj2s(L, ra, rb); + VM_NEXT(); + } + + VM_CASE(LOP_GETGLOBAL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + uint32_t aux = *pc++; + TValue* kv = VM_KV(aux); + LUAU_ASSERT(ttisstring(kv)); + + // fast-path: value is in expected slot + LuaTable* h = cl->env; + int slot = LUAU_INSN_C(insn) & h->nodemask8; + LuaNode* n = &h->node[slot]; + + if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv)) && !ttisnil(gval(n))) + { + setobj2s(L, ra, gval(n)); + VM_NEXT(); + } + else + { + // slow-path, may invoke Lua calls via __index metamethod + TValue g; + sethvalue(L, &g, h); + L->cachedslot = slot; + VM_PROTECT(luaV_gettable(L, &g, kv, ra)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + } + + VM_CASE(LOP_SETGLOBAL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + uint32_t aux = *pc++; + TValue* kv = VM_KV(aux); + LUAU_ASSERT(ttisstring(kv)); + + // fast-path: value is in expected slot + LuaTable* h = cl->env; + int slot = LUAU_INSN_C(insn) & h->nodemask8; + LuaNode* n = &h->node[slot]; + + if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)) && !h->readonly)) + { + setobj2t(L, gval(n), ra); + luaC_barriert(L, h, ra); + VM_NEXT(); + } + else + { + // slow-path, may invoke Lua calls via __newindex metamethod + TValue g; + sethvalue(L, &g, h); + L->cachedslot = slot; + VM_PROTECT(luaV_settable(L, &g, kv, ra)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + } + + VM_CASE(LOP_GETUPVAL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* ur = VM_UV(LUAU_INSN_B(insn)); + TValue* v = ttisupval(ur) ? upvalue(ur)->v : ur; + + setobj2s(L, ra, v); + VM_NEXT(); + } + + VM_CASE(LOP_SETUPVAL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* ur = VM_UV(LUAU_INSN_B(insn)); + UpVal* uv = upvalue(ur); + + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + VM_NEXT(); + } + + VM_CASE(LOP_CLOSEUPVALS) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + if (L->openupval && L->openupval->v >= ra) + luaF_close(L, ra); + VM_NEXT(); + } + + VM_CASE(LOP_GETIMPORT) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_D(insn)); + + // fast-path: import resolution was successful and closure environment is "safe" for import + if (!ttisnil(kv) && cl->env->safeenv) + { + setobj2s(L, ra, kv); + pc++; // skip over AUX + VM_NEXT(); + } + else + { + uint32_t aux = *pc++; + + VM_PROTECT(luaV_getimport(L, cl->env, k, ra, aux, /* propagatenil= */ false)); + VM_NEXT(); + } + } + + VM_CASE(LOP_GETTABLEKS) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + uint32_t aux = *pc++; + TValue* kv = VM_KV(aux); + LUAU_ASSERT(ttisstring(kv)); + + // fast-path: built-in table + if (LUAU_LIKELY(ttistable(rb))) + { + LuaTable* h = hvalue(rb); + + int slot = LUAU_INSN_C(insn) & h->nodemask8; + LuaNode* n = &h->node[slot]; + + // fast-path: value is in expected slot + if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)))) + { + setobj2s(L, ra, gval(n)); + VM_NEXT(); + } + else if (!h->metatable) + { + // fast-path: value is not in expected slot, but the table lookup doesn't involve metatable + const TValue* res = luaH_getstr(h, tsvalue(kv)); + + if (res != luaO_nilobject) + { + int cachedslot = gval2slot(h, res); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, cachedslot); + } + + setobj2s(L, ra, res); + VM_NEXT(); + } + else + { + // slow-path, may invoke Lua calls via __index metamethod + L->cachedslot = slot; + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + } + else + { + // fast-path: user data with C __index TM + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = fasttm(L, uvalue(rb)->metatable, TM_INDEX)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, kv); + L->top = top + 3; + + L->cachedslot = LUAU_INSN_C(insn); + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + else if (ttisvector(rb)) + { + // fast-path: quick case-insensitive comparison with "X"/"Y"/"Z" + const char* name = getstr(tsvalue(kv)); + int ic = (name[0] | ' ') - 'x'; + +#if LUA_VECTOR_SIZE == 4 + // 'w' is before 'x' in ascii, so ic is -1 when indexing with 'w' + if (ic == -1) + ic = 3; +#endif + + if (unsigned(ic) < LUA_VECTOR_SIZE && name[1] == '\0') + { + const float* v = vvalue(rb); // silences ubsan when indexing v[] + setnvalue(ra, v[ic]); + VM_NEXT(); + } + + fn = fasttm(L, L->global->mt[LUA_TVECTOR], TM_INDEX); + + if (fn && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, kv); + L->top = top + 3; + + L->cachedslot = LUAU_INSN_C(insn); + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + + // fall through to slow path + } + + // fall through to slow path + } + + // slow-path, may invoke Lua calls via __index metamethod + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + VM_NEXT(); + } + + VM_CASE(LOP_SETTABLEKS) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + uint32_t aux = *pc++; + TValue* kv = VM_KV(aux); + LUAU_ASSERT(ttisstring(kv)); + + // fast-path: built-in table + if (LUAU_LIKELY(ttistable(rb))) + { + LuaTable* h = hvalue(rb); + + int slot = LUAU_INSN_C(insn) & h->nodemask8; + LuaNode* n = &h->node[slot]; + + // fast-path: value is in expected slot + if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)) && !h->readonly)) + { + setobj2t(L, gval(n), ra); + luaC_barriert(L, h, ra); + VM_NEXT(); + } + else if (fastnotm(h->metatable, TM_NEWINDEX) && !h->readonly) + { + VM_PROTECT_PC(); // set may fail + + TValue* res = luaH_setstr(L, h, tsvalue(kv)); + int cachedslot = gval2slot(h, res); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, cachedslot); + setobj2t(L, res, ra); + luaC_barriert(L, h, ra); + VM_NEXT(); + } + else + { + // slow-path, may invoke Lua calls via __newindex metamethod + L->cachedslot = slot; + VM_PROTECT(luaV_settable(L, rb, kv, ra)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + } + else + { + // fast-path: user data with C __newindex TM + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = fasttm(L, uvalue(rb)->metatable, TM_NEWINDEX)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 4 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, kv); + setobj2s(L, top + 3, ra); + L->top = top + 4; + + L->cachedslot = LUAU_INSN_C(insn); + VM_PROTECT(luaV_callTM(L, 3, -1)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + VM_NEXT(); + } + else + { + // slow-path, may invoke Lua calls via __newindex metamethod + VM_PROTECT(luaV_settable(L, rb, kv, ra)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_GETTABLE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path: array lookup + if (ttistable(rb) && ttisnumber(rc)) + { + LuaTable* h = hvalue(rb); + + double indexd = nvalue(rc); + int index = int(indexd); + + // index has to be an exact integer and in-bounds for the array portion + if (LUAU_LIKELY(unsigned(index) - 1 < unsigned(h->sizearray) && !h->metatable && double(index) == indexd)) + { + setobj2s(L, ra, &h->array[unsigned(index - 1)]); + VM_NEXT(); + } + + // fall through to slow path + } + + // slow-path: handles out of bounds array lookups, non-integer numeric keys, non-array table lookup, __index MT calls + VM_PROTECT(luaV_gettable(L, rb, rc, ra)); + VM_NEXT(); + } + + VM_CASE(LOP_SETTABLE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path: array assign + if (ttistable(rb) && ttisnumber(rc)) + { + LuaTable* h = hvalue(rb); + + double indexd = nvalue(rc); + int index = int(indexd); + + // index has to be an exact integer and in-bounds for the array portion + if (LUAU_LIKELY(unsigned(index) - 1 < unsigned(h->sizearray) && !h->metatable && !h->readonly && double(index) == indexd)) + { + setobj2t(L, &h->array[unsigned(index - 1)], ra); + luaC_barriert(L, h, ra); + VM_NEXT(); + } + + // fall through to slow path + } + + // slow-path: handles out of bounds array assignments, non-integer numeric keys, non-array table access, __newindex MT calls + VM_PROTECT(luaV_settable(L, rb, rc, ra)); + VM_NEXT(); + } + + VM_CASE(LOP_GETTABLEN) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + int c = LUAU_INSN_C(insn); + + // fast-path: array lookup + if (ttistable(rb)) + { + LuaTable* h = hvalue(rb); + + if (LUAU_LIKELY(unsigned(c) < unsigned(h->sizearray) && !h->metatable)) + { + setobj2s(L, ra, &h->array[c]); + VM_NEXT(); + } + + // fall through to slow path + } + + // slow-path: handles out of bounds array lookups + TValue n; + setnvalue(&n, c + 1); + VM_PROTECT(luaV_gettable(L, rb, &n, ra)); + VM_NEXT(); + } + + VM_CASE(LOP_SETTABLEN) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + int c = LUAU_INSN_C(insn); + + // fast-path: array assign + if (ttistable(rb)) + { + LuaTable* h = hvalue(rb); + + if (LUAU_LIKELY(unsigned(c) < unsigned(h->sizearray) && !h->metatable && !h->readonly)) + { + setobj2t(L, &h->array[c], ra); + luaC_barriert(L, h, ra); + VM_NEXT(); + } + + // fall through to slow path + } + + // slow-path: handles out of bounds array lookups + TValue n; + setnvalue(&n, c + 1); + VM_PROTECT(luaV_settable(L, rb, &n, ra)); + VM_NEXT(); + } + + VM_CASE(LOP_NEWCLOSURE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + Proto* pv = cl->l.p->p[LUAU_INSN_D(insn)]; + LUAU_ASSERT(unsigned(LUAU_INSN_D(insn)) < unsigned(cl->l.p->sizep)); + + VM_PROTECT_PC(); // luaF_newLclosure may fail due to OOM + + // note: we save closure to stack early in case the code below wants to capture it by value + Closure* ncl = luaF_newLclosure(L, pv->nups, cl->env, pv); + setclvalue(L, ra, ncl); + + for (int ui = 0; ui < pv->nups; ++ui) + { + Instruction uinsn = *pc++; + LUAU_ASSERT(LUAU_INSN_OP(uinsn) == LOP_CAPTURE); + + switch (LUAU_INSN_A(uinsn)) + { + case LCT_VAL: + setobj(L, &ncl->l.uprefs[ui], VM_REG(LUAU_INSN_B(uinsn))); + break; + + case LCT_REF: + setupvalue(L, &ncl->l.uprefs[ui], luaF_findupval(L, VM_REG(LUAU_INSN_B(uinsn)))); + break; + + case LCT_UPVAL: + setobj(L, &ncl->l.uprefs[ui], VM_UV(LUAU_INSN_B(uinsn))); + break; + + default: + LUAU_ASSERT(!"Unknown upvalue capture type"); + LUAU_UNREACHABLE(); // improves switch() codegen by eliding opcode bounds checks + } + } + + VM_PROTECT(luaC_checkGC(L)); + VM_NEXT(); + } + + VM_CASE(LOP_NAMECALL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + uint32_t aux = *pc++; + TValue* kv = VM_KV(aux); + LUAU_ASSERT(ttisstring(kv)); + + if (LUAU_LIKELY(ttistable(rb))) + { + LuaTable* h = hvalue(rb); + // note: we can't use nodemask8 here because we need to query the main position of the table, and 8-bit nodemask8 only works + // for predictive lookups + LuaNode* n = &h->node[tsvalue(kv)->hash & (sizenode(h) - 1)]; + + const TValue* mt = 0; + const LuaNode* mtn = 0; + + // fast-path: key is in the table in expected slot + if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n))) + { + // note: order of copies allows rb to alias ra+1 or ra + setobj2s(L, ra + 1, rb); + setobj2s(L, ra, gval(n)); + } + // fast-path: key is absent from the base, table has an __index table, and it has the result in the expected slot + else if (gnext(n) == 0 && (mt = fasttm(L, hvalue(rb)->metatable, TM_INDEX)) && ttistable(mt) && + (mtn = &hvalue(mt)->node[LUAU_INSN_C(insn) & hvalue(mt)->nodemask8]) && ttisstring(gkey(mtn)) && + tsvalue(gkey(mtn)) == tsvalue(kv) && !ttisnil(gval(mtn))) + { + // note: order of copies allows rb to alias ra+1 or ra + setobj2s(L, ra + 1, rb); + setobj2s(L, ra, gval(mtn)); + } + else + { + // slow-path: handles full table lookup + setobj2s(L, ra + 1, rb); + L->cachedslot = LUAU_INSN_C(insn); + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + // recompute ra since stack might have been reallocated + ra = VM_REG(LUAU_INSN_A(insn)); + if (ttisnil(ra)) + luaG_methoderror(L, ra + 1, tsvalue(kv)); + } + } + else + { + LuaTable* mt = ttisuserdata(rb) ? uvalue(rb)->metatable : L->global->mt[ttype(rb)]; + const TValue* tmi = 0; + + // fast-path: metatable with __namecall + if (const TValue* fn = fasttm(L, mt, TM_NAMECALL)) + { + // note: order of copies allows rb to alias ra+1 or ra + setobj2s(L, ra + 1, rb); + setobj2s(L, ra, fn); + + L->namecall = tsvalue(kv); + } + else if ((tmi = fasttm(L, mt, TM_INDEX)) && ttistable(tmi)) + { + LuaTable* h = hvalue(tmi); + int slot = LUAU_INSN_C(insn) & h->nodemask8; + LuaNode* n = &h->node[slot]; + + // fast-path: metatable with __index that has method in expected slot + if (LUAU_LIKELY(ttisstring(gkey(n)) && tsvalue(gkey(n)) == tsvalue(kv) && !ttisnil(gval(n)))) + { + // note: order of copies allows rb to alias ra+1 or ra + setobj2s(L, ra + 1, rb); + setobj2s(L, ra, gval(n)); + } + else + { + // slow-path: handles slot mismatch + setobj2s(L, ra + 1, rb); + L->cachedslot = slot; + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + // save cachedslot to accelerate future lookups; patches currently executing instruction since pc-2 rolls back two pc++ + VM_PATCH_C(pc - 2, L->cachedslot); + // recompute ra since stack might have been reallocated + ra = VM_REG(LUAU_INSN_A(insn)); + if (ttisnil(ra)) + luaG_methoderror(L, ra + 1, tsvalue(kv)); + } + } + else + { + // slow-path: handles non-table __index + setobj2s(L, ra + 1, rb); + VM_PROTECT(luaV_gettable(L, rb, kv, ra)); + // recompute ra since stack might have been reallocated + ra = VM_REG(LUAU_INSN_A(insn)); + if (ttisnil(ra)) + luaG_methoderror(L, ra + 1, tsvalue(kv)); + } + } + + // intentional fallthrough to CALL + LUAU_ASSERT(LUAU_INSN_OP(*pc) == LOP_CALL); + } + + VM_CASE(LOP_CALL) + { + VM_INTERRUPT(); + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + int nparams = LUAU_INSN_B(insn) - 1; + int nresults = LUAU_INSN_C(insn) - 1; + + StkId argtop = L->top; + argtop = (nparams == LUA_MULTRET) ? argtop : ra + 1 + nparams; + + // slow-path: not a function call + if (LUAU_UNLIKELY(!ttisfunction(ra))) + { + VM_PROTECT_PC(); // luaV_tryfuncTM may fail + + luaV_tryfuncTM(L, ra); + argtop++; // __call adds an extra self + } + + Closure* ccl = clvalue(ra); + L->ci->savedpc = pc; + + CallInfo* ci = incr_ci(L); + ci->func = ra; + ci->base = ra + 1; + ci->top = argtop + ccl->stacksize; // note: technically UB since we haven't reallocated the stack yet + ci->savedpc = NULL; + ci->flags = 0; + ci->nresults = nresults; + + L->base = ci->base; + L->top = argtop; + + // note: this reallocs stack, but we don't need to VM_PROTECT this + // this is because we're going to modify base/savedpc manually anyhow + // crucially, we can't use ra/argtop after this line + luaD_checkstackfornewci(L, ccl->stacksize); + + LUAU_ASSERT(ci->top <= L->stack_last); + + if (!ccl->isC) + { + Proto* p = ccl->l.p; + + // fill unused parameters with nil + StkId argi = L->top; + StkId argend = L->base + p->numparams; + while (argi < argend) + setnilvalue(argi++); // complete missing arguments + L->top = p->is_vararg ? argi : ci->top; + + // reentry + // codeentry may point to NATIVECALL instruction when proto is compiled to native code + // this will result in execution continuing in native code, and is equivalent to if (p->execdata) but has no additional overhead + // note that p->codeentry may point *outside* of p->code..p->code+p->sizecode, but that pointer never gets saved to savedpc. + pc = SingleStep ? p->code : p->codeentry; + cl = ccl; + base = L->base; + k = p->k; + VM_NEXT(); + } + else + { + lua_CFunction func = ccl->c.f; + int n = func(L); + + // yield + if (n < 0) + goto exit; + + // ci is our callinfo, cip is our parent + CallInfo* ci = L->ci; + CallInfo* cip = ci - 1; + + // copy return values into parent stack (but only up to nresults!), fill the rest with nil + // note: in MULTRET context nresults starts as -1 so i != 0 condition never activates intentionally + StkId res = ci->func; + StkId vali = L->top - n; + StkId valend = L->top; + + int i; + for (i = nresults; i != 0 && vali < valend; i--) + setobj2s(L, res++, vali++); + while (i-- > 0) + setnilvalue(res++); + + // pop the stack frame + L->ci = cip; + L->base = cip->base; + L->top = (nresults == LUA_MULTRET) ? res : cip->top; + + base = L->base; // stack may have been reallocated, so we need to refresh base ptr + VM_NEXT(); + } + } + + VM_CASE(LOP_RETURN) + { + VM_INTERRUPT(); + Instruction insn = *pc++; + StkId ra = &base[LUAU_INSN_A(insn)]; // note: this can point to L->top if b == LUA_MULTRET making VM_REG unsafe to use + int b = LUAU_INSN_B(insn) - 1; + + // ci is our callinfo, cip is our parent + CallInfo* ci = L->ci; + CallInfo* cip = ci - 1; + + StkId res = ci->func; // note: we assume CALL always puts func+args and expects results to start at func + + StkId vali = ra; + StkId valend = + (b == LUA_MULTRET) ? L->top : ra + b; // copy as much as possible for MULTRET calls, and only as much as needed otherwise + + int nresults = ci->nresults; + + // copy return values into parent stack (but only up to nresults!), fill the rest with nil + // note: in MULTRET context nresults starts as -1 so i != 0 condition never activates intentionally + int i; + for (i = nresults; i != 0 && vali < valend; i--) + setobj2s(L, res++, vali++); + while (i-- > 0) + setnilvalue(res++); + + // pop the stack frame + L->ci = cip; + L->base = cip->base; + L->top = (nresults == LUA_MULTRET) ? res : cip->top; + + // we're done! + if (LUAU_UNLIKELY(ci->flags & LUA_CALLINFO_RETURN)) + { + goto exit; + } + + LUAU_ASSERT(isLua(L->ci)); + + Closure* nextcl = clvalue(cip->func); + Proto* nextproto = nextcl->l.p; + +#if VM_HAS_NATIVE + if (LUAU_UNLIKELY((cip->flags & LUA_CALLINFO_NATIVE) && !SingleStep)) + { + if (L->global->ecb.enter(L, nextproto) == 1) + goto reentry; + else + goto exit; + } +#endif + + // reentry + pc = cip->savedpc; + cl = nextcl; + base = L->base; + k = nextproto->k; + VM_NEXT(); + } + + VM_CASE(LOP_JUMP) + { + Instruction insn = *pc++; + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPIF) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + pc += l_isfalse(ra) ? 0 : LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPIFNOT) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + pc += l_isfalse(ra) ? LUAU_INSN_D(insn) : 0; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPIFEQ) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(aux); + + // Note that all jumps below jump by 1 in the "false" case to skip over aux + if (ttype(ra) == ttype(rb)) + { + switch (ttype(ra)) + { + case LUA_TNIL: + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TBOOLEAN: + pc += bvalue(ra) == bvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TLIGHTUSERDATA: + pc += (pvalue(ra) == pvalue(rb) && lightuserdatatag(ra) == lightuserdatatag(rb)) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TNUMBER: + pc += nvalue(ra) == nvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TVECTOR: + pc += luai_veceq(vvalue(ra), vvalue(rb)) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TSTRING: + case LUA_TFUNCTION: + case LUA_TTHREAD: + case LUA_TBUFFER: + pc += gcvalue(ra) == gcvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TTABLE: + // fast-path: same metatable, no EQ metamethod + if (hvalue(ra)->metatable == hvalue(rb)->metatable) + { + const TValue* fn = fasttm(L, hvalue(ra)->metatable, TM_EQ); + + if (!fn) + { + pc += hvalue(ra) == hvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + // slow path after switch() + break; + + case LUA_TUSERDATA: + // fast-path: same metatable, no EQ metamethod or C metamethod + if (uvalue(ra)->metatable == uvalue(rb)->metatable) + { + const TValue* fn = fasttm(L, uvalue(ra)->metatable, TM_EQ); + + if (!fn) + { + pc += uvalue(ra) == uvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else if (ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, ra); + setobj2s(L, top + 2, rb); + int res = int(top - base); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, res)); + pc += !l_isfalse(&base[res]) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + // slow path after switch() + break; + + default: + LUAU_ASSERT(!"Unknown value type"); + LUAU_UNREACHABLE(); // improves switch() codegen by eliding opcode bounds checks + } + + // slow-path: tables with metatables and userdata values + // note that we don't have a fast path for userdata values without metatables, since that's very rare + int res; + VM_PROTECT(res = luaV_equalval(L, ra, rb)); + + pc += (res == 1) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + pc += 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_JUMPIFNOTEQ) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(aux); + + // Note that all jumps below jump by 1 in the "true" case to skip over aux + if (ttype(ra) == ttype(rb)) + { + switch (ttype(ra)) + { + case LUA_TNIL: + pc += 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TBOOLEAN: + pc += bvalue(ra) != bvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TLIGHTUSERDATA: + pc += (pvalue(ra) != pvalue(rb) || lightuserdatatag(ra) != lightuserdatatag(rb)) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TNUMBER: + pc += nvalue(ra) != nvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TVECTOR: + pc += !luai_veceq(vvalue(ra), vvalue(rb)) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TSTRING: + case LUA_TFUNCTION: + case LUA_TTHREAD: + case LUA_TBUFFER: + pc += gcvalue(ra) != gcvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + + case LUA_TTABLE: + // fast-path: same metatable, no EQ metamethod + if (hvalue(ra)->metatable == hvalue(rb)->metatable) + { + const TValue* fn = fasttm(L, hvalue(ra)->metatable, TM_EQ); + + if (!fn) + { + pc += hvalue(ra) != hvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + // slow path after switch() + break; + + case LUA_TUSERDATA: + // fast-path: same metatable, no EQ metamethod or C metamethod + if (uvalue(ra)->metatable == uvalue(rb)->metatable) + { + const TValue* fn = fasttm(L, uvalue(ra)->metatable, TM_EQ); + + if (!fn) + { + pc += uvalue(ra) != uvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else if (ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, ra); + setobj2s(L, top + 2, rb); + int res = int(top - base); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, res)); + pc += l_isfalse(&base[res]) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + // slow path after switch() + break; + + default: + LUAU_ASSERT(!"Unknown value type"); + LUAU_UNREACHABLE(); // improves switch() codegen by eliding opcode bounds checks + } + + // slow-path: tables with metatables and userdata values + // note that we don't have a fast path for userdata values without metatables, since that's very rare + int res; + VM_PROTECT(res = luaV_equalval(L, ra, rb)); + + pc += (res == 0) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_JUMPIFLE) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(aux); + + // fast-path: number + // Note that all jumps below jump by 1 in the "false" case to skip over aux + if (LUAU_LIKELY(ttisnumber(ra) && ttisnumber(rb))) + { + pc += nvalue(ra) <= nvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + // fast-path: string + else if (ttisstring(ra) && ttisstring(rb)) + { + pc += luaV_strcmp(tsvalue(ra), tsvalue(rb)) <= 0 ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + int res; + VM_PROTECT(res = luaV_lessequal(L, ra, rb)); + + pc += (res == 1) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_JUMPIFNOTLE) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(aux); + + // fast-path: number + // Note that all jumps below jump by 1 in the "true" case to skip over aux + if (LUAU_LIKELY(ttisnumber(ra) && ttisnumber(rb))) + { + pc += !(nvalue(ra) <= nvalue(rb)) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + // fast-path: string + else if (ttisstring(ra) && ttisstring(rb)) + { + pc += !(luaV_strcmp(tsvalue(ra), tsvalue(rb)) <= 0) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + int res; + VM_PROTECT(res = luaV_lessequal(L, ra, rb)); + + pc += (res == 0) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_JUMPIFLT) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(aux); + + // fast-path: number + // Note that all jumps below jump by 1 in the "false" case to skip over aux + if (LUAU_LIKELY(ttisnumber(ra) && ttisnumber(rb))) + { + pc += nvalue(ra) < nvalue(rb) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + // fast-path: string + else if (ttisstring(ra) && ttisstring(rb)) + { + pc += luaV_strcmp(tsvalue(ra), tsvalue(rb)) < 0 ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + int res; + VM_PROTECT(res = luaV_lessthan(L, ra, rb)); + + pc += (res == 1) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_JUMPIFNOTLT) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(aux); + + // fast-path: number + // Note that all jumps below jump by 1 in the "true" case to skip over aux + if (LUAU_LIKELY(ttisnumber(ra) && ttisnumber(rb))) + { + pc += !(nvalue(ra) < nvalue(rb)) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + // fast-path: string + else if (ttisstring(ra) && ttisstring(rb)) + { + pc += !(luaV_strcmp(tsvalue(ra), tsvalue(rb)) < 0) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + int res; + VM_PROTECT(res = luaV_lessthan(L, ra, rb)); + + pc += (res == 0) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_ADD) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb) && ttisnumber(rc))) + { + setnvalue(ra, nvalue(rb) + nvalue(rc)); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisvector(rc)) + { + const float* vb = vvalue(rb); + const float* vc = vvalue(rc); + setvvalue(ra, vb[0] + vc[0], vb[1] + vc[1], vb[2] + vc[2], vb[3] + vc[3]); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_ADD)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, rc); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_SUB) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb) && ttisnumber(rc))) + { + setnvalue(ra, nvalue(rb) - nvalue(rc)); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisvector(rc)) + { + const float* vb = vvalue(rb); + const float* vc = vvalue(rc); + setvvalue(ra, vb[0] - vc[0], vb[1] - vc[1], vb[2] - vc[2], vb[3] - vc[3]); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_SUB)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, rc); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_MUL) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb) && ttisnumber(rc))) + { + setnvalue(ra, nvalue(rb) * nvalue(rc)); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisnumber(rc)) + { + const float* vb = vvalue(rb); + float vc = cast_to(float, nvalue(rc)); + setvvalue(ra, vb[0] * vc, vb[1] * vc, vb[2] * vc, vb[3] * vc); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisvector(rc)) + { + const float* vb = vvalue(rb); + const float* vc = vvalue(rc); + setvvalue(ra, vb[0] * vc[0], vb[1] * vc[1], vb[2] * vc[2], vb[3] * vc[3]); + VM_NEXT(); + } + else if (ttisnumber(rb) && ttisvector(rc)) + { + float vb = cast_to(float, nvalue(rb)); + const float* vc = vvalue(rc); + setvvalue(ra, vb * vc[0], vb * vc[1], vb * vc[2], vb * vc[3]); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + StkId rbc = ttisnumber(rb) ? rc : rb; + const TValue* fn = 0; + if (ttisuserdata(rbc) && (fn = luaT_gettmbyobj(L, rbc, TM_MUL)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, rc); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_DIV) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb) && ttisnumber(rc))) + { + setnvalue(ra, nvalue(rb) / nvalue(rc)); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisnumber(rc)) + { + const float* vb = vvalue(rb); + float vc = cast_to(float, nvalue(rc)); + setvvalue(ra, vb[0] / vc, vb[1] / vc, vb[2] / vc, vb[3] / vc); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisvector(rc)) + { + const float* vb = vvalue(rb); + const float* vc = vvalue(rc); + setvvalue(ra, vb[0] / vc[0], vb[1] / vc[1], vb[2] / vc[2], vb[3] / vc[3]); + VM_NEXT(); + } + else if (ttisnumber(rb) && ttisvector(rc)) + { + float vb = cast_to(float, nvalue(rb)); + const float* vc = vvalue(rc); + setvvalue(ra, vb / vc[0], vb / vc[1], vb / vc[2], vb / vc[3]); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + StkId rbc = ttisnumber(rb) ? rc : rb; + const TValue* fn = 0; + if (ttisuserdata(rbc) && (fn = luaT_gettmbyobj(L, rbc, TM_DIV)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, rc); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_IDIV) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb) && ttisnumber(rc))) + { + setnvalue(ra, luai_numidiv(nvalue(rb), nvalue(rc))); + VM_NEXT(); + } + else if (ttisvector(rb) && ttisnumber(rc)) + { + const float* vb = vvalue(rb); + float vc = cast_to(float, nvalue(rc)); + setvvalue( + ra, + float(luai_numidiv(vb[0], vc)), + float(luai_numidiv(vb[1], vc)), + float(luai_numidiv(vb[2], vc)), + float(luai_numidiv(vb[3], vc)) + ); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + StkId rbc = ttisnumber(rb) ? rc : rb; + const TValue* fn = 0; + if (ttisuserdata(rbc) && (fn = luaT_gettmbyobj(L, rbc, TM_IDIV)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, rc); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_MOD) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rb) && ttisnumber(rc)) + { + double nb = nvalue(rb); + double nc = nvalue(rc); + setnvalue(ra, luai_nummod(nb, nc)); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + + VM_CASE(LOP_POW) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rb) && ttisnumber(rc)) + { + setnvalue(ra, pow(nvalue(rb), nvalue(rc))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rc)); + VM_NEXT(); + } + } + + VM_CASE(LOP_ADDK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rb)) + { + setnvalue(ra, nvalue(rb) + nvalue(kv)); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + + VM_CASE(LOP_SUBK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rb)) + { + setnvalue(ra, nvalue(rb) - nvalue(kv)); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + + VM_CASE(LOP_MULK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb))) + { + setnvalue(ra, nvalue(rb) * nvalue(kv)); + VM_NEXT(); + } + else if (ttisvector(rb)) + { + const float* vb = vvalue(rb); + float vc = cast_to(float, nvalue(kv)); + setvvalue(ra, vb[0] * vc, vb[1] * vc, vb[2] * vc, vb[3] * vc); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_MUL)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, kv); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_DIVK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb))) + { + setnvalue(ra, nvalue(rb) / nvalue(kv)); + VM_NEXT(); + } + else if (ttisvector(rb)) + { + const float* vb = vvalue(rb); + float nc = cast_to(float, nvalue(kv)); + setvvalue(ra, vb[0] / nc, vb[1] / nc, vb[2] / nc, vb[3] / nc); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_DIV)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, kv); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_IDIVK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb))) + { + setnvalue(ra, luai_numidiv(nvalue(rb), nvalue(kv))); + VM_NEXT(); + } + else if (ttisvector(rb)) + { + const float* vb = vvalue(rb); + float vc = cast_to(float, nvalue(kv)); + setvvalue( + ra, + float(luai_numidiv(vb[0], vc)), + float(luai_numidiv(vb[1], vc)), + float(luai_numidiv(vb[2], vc)), + float(luai_numidiv(vb[3], vc)) + ); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_IDIV)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 3 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + setobj2s(L, top + 2, kv); + L->top = top + 3; + + VM_PROTECT(luaV_callTM(L, 2, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_MODK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rb)) + { + double nb = nvalue(rb); + double nk = nvalue(kv); + setnvalue(ra, luai_nummod(nb, nk)); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + + VM_CASE(LOP_POWK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rb)) + { + double nb = nvalue(rb); + double nk = nvalue(kv); + + // pow is very slow so we specialize this for ^2, ^0.5 and ^3 + double r = (nk == 2.0) ? nb * nb : (nk == 0.5) ? sqrt(nb) : (nk == 3.0) ? nb * nb * nb : pow(nb, nk); + + setnvalue(ra, r); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, kv)); + VM_NEXT(); + } + } + + VM_CASE(LOP_AND) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + setobj2s(L, ra, l_isfalse(rb) ? rb : rc); + VM_NEXT(); + } + + VM_CASE(LOP_OR) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + setobj2s(L, ra, l_isfalse(rb) ? rc : rb); + VM_NEXT(); + } + + VM_CASE(LOP_ANDK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + setobj2s(L, ra, l_isfalse(rb) ? rb : kv); + VM_NEXT(); + } + + VM_CASE(LOP_ORK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + TValue* kv = VM_KV(LUAU_INSN_C(insn)); + + setobj2s(L, ra, l_isfalse(rb) ? kv : rb); + VM_NEXT(); + } + + VM_CASE(LOP_CONCAT) + { + Instruction insn = *pc++; + int b = LUAU_INSN_B(insn); + int c = LUAU_INSN_C(insn); + + // This call may realloc the stack! So we need to query args further down + VM_PROTECT(luaV_concat(L, c - b + 1, c)); + + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + setobj2s(L, ra, base + b); + VM_PROTECT(luaC_checkGC(L)); + VM_NEXT(); + } + + VM_CASE(LOP_NOT) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + + int res = l_isfalse(rb); + setbvalue(ra, res); + VM_NEXT(); + } + + VM_CASE(LOP_MINUS) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rb))) + { + setnvalue(ra, -nvalue(rb)); + VM_NEXT(); + } + else if (ttisvector(rb)) + { + const float* vb = vvalue(rb); + setvvalue(ra, -vb[0], -vb[1], -vb[2], -vb[3]); + VM_NEXT(); + } + else + { + // fast-path for userdata with C functions + const TValue* fn = 0; + if (ttisuserdata(rb) && (fn = luaT_gettmbyobj(L, rb, TM_UNM)) && ttisfunction(fn) && clvalue(fn)->isC) + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 2 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top + 0, fn); + setobj2s(L, top + 1, rb); + L->top = top + 2; + + VM_PROTECT(luaV_callTM(L, 1, LUAU_INSN_A(insn))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, rb, rb)); + VM_NEXT(); + } + } + } + + VM_CASE(LOP_LENGTH) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = VM_REG(LUAU_INSN_B(insn)); + + // fast-path #1: tables + if (LUAU_LIKELY(ttistable(rb))) + { + LuaTable* h = hvalue(rb); + + if (fastnotm(h->metatable, TM_LEN)) + { + setnvalue(ra, cast_num(luaH_getn(h))); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_dolen(L, ra, rb)); + VM_NEXT(); + } + } + // fast-path #2: strings (not very important but easy to do) + else if (ttisstring(rb)) + { + TString* ts = tsvalue(rb); + setnvalue(ra, cast_num(ts->len)); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_dolen(L, ra, rb)); + VM_NEXT(); + } + } + + VM_CASE(LOP_NEWTABLE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + int b = LUAU_INSN_B(insn); + uint32_t aux = *pc++; + + VM_PROTECT_PC(); // luaH_new may fail due to OOM + + sethvalue(L, ra, luaH_new(L, aux, b == 0 ? 0 : (1 << (b - 1)))); + VM_PROTECT(luaC_checkGC(L)); + VM_NEXT(); + } + + VM_CASE(LOP_DUPTABLE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_D(insn)); + + VM_PROTECT_PC(); // luaH_clone may fail due to OOM + + sethvalue(L, ra, luaH_clone(L, hvalue(kv))); + VM_PROTECT(luaC_checkGC(L)); + VM_NEXT(); + } + + VM_CASE(LOP_SETLIST) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + StkId rb = &base[LUAU_INSN_B(insn)]; // note: this can point to L->top if c == LUA_MULTRET making VM_REG unsafe to use + int c = LUAU_INSN_C(insn) - 1; + uint32_t index = *pc++; + + if (c == LUA_MULTRET) + { + c = int(L->top - rb); + L->top = L->ci->top; + } + + LuaTable* h = hvalue(ra); + + // TODO: we really don't need this anymore + if (!ttistable(ra)) + return; // temporary workaround to weaken a rather powerful exploitation primitive in case of a MITM attack on bytecode + + int last = index + c - 1; + if (last > h->sizearray) + { + VM_PROTECT_PC(); // luaH_resizearray may fail due to OOM + + luaH_resizearray(L, h, last); + } + + TValue* array = h->array; + + for (int i = 0; i < c; ++i) + setobj2t(L, &array[index + i - 1], rb + i); + + luaC_barrierfast(L, h); + VM_NEXT(); + } + + VM_CASE(LOP_FORNPREP) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + if (!ttisnumber(ra + 0) || !ttisnumber(ra + 1) || !ttisnumber(ra + 2)) + { + // slow-path: can convert arguments to numbers and trigger Lua errors + // Note: this doesn't reallocate stack so we don't need to recompute ra/base + VM_PROTECT_PC(); + + luaV_prepareFORN(L, ra + 0, ra + 1, ra + 2); + } + + double limit = nvalue(ra + 0); + double step = nvalue(ra + 1); + double idx = nvalue(ra + 2); + + // Note: make sure the loop condition is exactly the same between this and LOP_FORNLOOP so that we handle NaN/etc. consistently + pc += (step > 0 ? idx <= limit : limit <= idx) ? 0 : LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_FORNLOOP) + { + VM_INTERRUPT(); + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + LUAU_ASSERT(ttisnumber(ra + 0) && ttisnumber(ra + 1) && ttisnumber(ra + 2)); + + double limit = nvalue(ra + 0); + double step = nvalue(ra + 1); + double idx = nvalue(ra + 2) + step; + + setnvalue(ra + 2, idx); + + // Note: make sure the loop condition is exactly the same between this and LOP_FORNPREP so that we handle NaN/etc. consistently + if (step > 0 ? idx <= limit : limit <= idx) + { + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + // fallthrough to exit + VM_NEXT(); + } + } + + VM_CASE(LOP_FORGPREP) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + if (ttisfunction(ra)) + { + // will be called during FORGLOOP + } + else + { + LuaTable* mt = ttistable(ra) ? hvalue(ra)->metatable : ttisuserdata(ra) ? uvalue(ra)->metatable : cast_to(LuaTable*, NULL); + + if (const TValue* fn = fasttm(L, mt, TM_ITER)) + { + setobj2s(L, ra + 1, ra); + setobj2s(L, ra, fn); + + L->top = ra + 2; // func + self arg + LUAU_ASSERT(L->top <= L->stack_last); + + VM_PROTECT(luaD_call(L, ra, 3)); + L->top = L->ci->top; + + // recompute ra since stack might have been reallocated + ra = VM_REG(LUAU_INSN_A(insn)); + + // protect against __iter returning nil, since nil is used as a marker for builtin iteration in FORGLOOP + if (ttisnil(ra)) + { + VM_PROTECT_PC(); // next call always errors + luaG_typeerror(L, ra, "call"); + } + } + else if (fasttm(L, mt, TM_CALL)) + { + // table or userdata with __call, will be called during FORGLOOP + // TODO: we might be able to stop supporting this depending on whether it's used in practice + } + else if (ttistable(ra)) + { + // set up registers for builtin iteration + setobj2s(L, ra + 1, ra); + setpvalue(ra + 2, reinterpret_cast(uintptr_t(0)), LU_TAG_ITERATOR); + setnilvalue(ra); + } + else + { + VM_PROTECT_PC(); // next call always errors + luaG_typeerror(L, ra, "iterate over"); + } + } + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_FORGLOOP) + { + VM_INTERRUPT(); + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + uint32_t aux = *pc; + + // fast-path: builtin table iteration + // note: ra=nil guarantees ra+1=table and ra+2=userdata because of the setup by FORGPREP* opcodes + // TODO: remove the table check per guarantee above + if (ttisnil(ra) && ttistable(ra + 1)) + { + LuaTable* h = hvalue(ra + 1); + int index = int(reinterpret_cast(pvalue(ra + 2))); + + int sizearray = h->sizearray; + + // clear extra variables since we might have more than two + // note: while aux encodes ipairs bit, when set we always use 2 variables, so it's safe to check this via a signed comparison + if (LUAU_UNLIKELY(int(aux) > 2)) + for (int i = 2; i < int(aux); ++i) + setnilvalue(ra + 3 + i); + + // terminate ipairs-style traversal early when encountering nil + if (int(aux) < 0 && (unsigned(index) >= unsigned(sizearray) || ttisnil(&h->array[index]))) + { + pc++; + VM_NEXT(); + } + + // first we advance index through the array portion + while (unsigned(index) < unsigned(sizearray)) + { + TValue* e = &h->array[index]; + + if (!ttisnil(e)) + { + setpvalue(ra + 2, reinterpret_cast(uintptr_t(index + 1)), LU_TAG_ITERATOR); + setnvalue(ra + 3, double(index + 1)); + setobj2s(L, ra + 4, e); + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + index++; + } + + int sizenode = 1 << h->lsizenode; + + // then we advance index through the hash portion + while (unsigned(index - sizearray) < unsigned(sizenode)) + { + LuaNode* n = &h->node[index - sizearray]; + + if (!ttisnil(gval(n))) + { + setpvalue(ra + 2, reinterpret_cast(uintptr_t(index + 1)), LU_TAG_ITERATOR); + getnodekey(L, ra + 3, n); + setobj2s(L, ra + 4, gval(n)); + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + index++; + } + + // fallthrough to exit + pc++; + VM_NEXT(); + } + else + { + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + setobj2s(L, ra + 3 + 2, ra + 2); + setobj2s(L, ra + 3 + 1, ra + 1); + setobj2s(L, ra + 3, ra); + + L->top = ra + 3 + 3; // func + 2 args (state and index) + LUAU_ASSERT(L->top <= L->stack_last); + + VM_PROTECT(luaD_call(L, ra + 3, uint8_t(aux))); + L->top = L->ci->top; + + // recompute ra since stack might have been reallocated + ra = VM_REG(LUAU_INSN_A(insn)); + + // copy first variable back into the iteration index + setobj2s(L, ra + 2, ra + 3); + + // note that we need to increment pc by 1 to exit the loop since we need to skip over aux + pc += ttisnil(ra + 3) ? 1 : LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + } + + VM_CASE(LOP_FORGPREP_INEXT) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + // fast-path: ipairs/inext + if (cl->env->safeenv && ttistable(ra + 1) && ttisnumber(ra + 2) && nvalue(ra + 2) == 0.0) + { + setnilvalue(ra); + // ra+1 is already the table + setpvalue(ra + 2, reinterpret_cast(uintptr_t(0)), LU_TAG_ITERATOR); + } + else if (!ttisfunction(ra)) + { + VM_PROTECT_PC(); // next call always errors + luaG_typeerror(L, ra, "iterate over"); + } + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_FORGPREP_NEXT) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + // fast-path: pairs/next + if (cl->env->safeenv && ttistable(ra + 1) && ttisnil(ra + 2)) + { + setnilvalue(ra); + // ra+1 is already the table + setpvalue(ra + 2, reinterpret_cast(uintptr_t(0)), LU_TAG_ITERATOR); + } + else if (!ttisfunction(ra)) + { + VM_PROTECT_PC(); // next call always errors + luaG_typeerror(L, ra, "iterate over"); + } + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_NATIVECALL) + { + Proto* p = cl->l.p; + LUAU_ASSERT(p->execdata); + + CallInfo* ci = L->ci; + ci->flags = LUA_CALLINFO_NATIVE; + ci->savedpc = p->code; + +#if VM_HAS_NATIVE + if (L->global->ecb.enter(L, p) == 1) + goto reentry; + else + goto exit; +#else + LUAU_ASSERT(!"Opcode is only valid when VM_HAS_NATIVE is defined"); + LUAU_UNREACHABLE(); +#endif + } + + VM_CASE(LOP_GETVARARGS) + { + Instruction insn = *pc++; + int b = LUAU_INSN_B(insn) - 1; + int n = cast_int(base - L->ci->func) - cl->l.p->numparams - 1; + + if (b == LUA_MULTRET) + { + VM_PROTECT(luaD_checkstack(L, n)); + StkId ra = VM_REG(LUAU_INSN_A(insn)); // previous call may change the stack + + for (int j = 0; j < n; j++) + setobj2s(L, ra + j, base - n + j); + + L->top = ra + n; + VM_NEXT(); + } + else + { + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + for (int j = 0; j < b && j < n; j++) + setobj2s(L, ra + j, base - n + j); + for (int j = n; j < b; j++) + setnilvalue(ra + j); + VM_NEXT(); + } + } + + VM_CASE(LOP_DUPCLOSURE) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_D(insn)); + + Closure* kcl = clvalue(kv); + + VM_PROTECT_PC(); // luaF_newLclosure may fail due to OOM + + // clone closure if the environment is not shared + // note: we save closure to stack early in case the code below wants to capture it by value + Closure* ncl = (kcl->env == cl->env) ? kcl : luaF_newLclosure(L, kcl->nupvalues, cl->env, kcl->l.p); + setclvalue(L, ra, ncl); + + // this loop does three things: + // - if the closure was created anew, it just fills it with upvalues + // - if the closure from the constant table is used, it fills it with upvalues so that it can be shared in the future + // - if the closure is reused, it checks if the reuse is safe via rawequal, and falls back to duplicating the closure + // normally this would use two separate loops, for reuse check and upvalue setup, but MSVC codegen goes crazy if you do that + for (int ui = 0; ui < kcl->nupvalues; ++ui) + { + Instruction uinsn = pc[ui]; + LUAU_ASSERT(LUAU_INSN_OP(uinsn) == LOP_CAPTURE); + LUAU_ASSERT(LUAU_INSN_A(uinsn) == LCT_VAL || LUAU_INSN_A(uinsn) == LCT_UPVAL); + + TValue* uv = (LUAU_INSN_A(uinsn) == LCT_VAL) ? VM_REG(LUAU_INSN_B(uinsn)) : VM_UV(LUAU_INSN_B(uinsn)); + + // check if the existing closure is safe to reuse + if (ncl == kcl && luaO_rawequalObj(&ncl->l.uprefs[ui], uv)) + continue; + + // lazily clone the closure and update the upvalues + if (ncl == kcl && kcl->preload == 0) + { + ncl = luaF_newLclosure(L, kcl->nupvalues, cl->env, kcl->l.p); + setclvalue(L, ra, ncl); + + ui = -1; // restart the loop to fill all upvalues + continue; + } + + // this updates a newly created closure, or an existing closure created during preload, in which case we need a barrier + setobj(L, &ncl->l.uprefs[ui], uv); + luaC_barrier(L, ncl, uv); + } + + // this is a noop if ncl is newly created or shared successfully, but it has to run after the closure is preloaded for the first time + ncl->preload = 0; + + if (kcl != ncl) + VM_PROTECT(luaC_checkGC(L)); + + pc += kcl->nupvalues; + VM_NEXT(); + } + + VM_CASE(LOP_PREPVARARGS) + { + Instruction insn = *pc++; + int numparams = LUAU_INSN_A(insn); + + // all fixed parameters are copied after the top so we need more stack space + VM_PROTECT(luaD_checkstack(L, cl->stacksize + numparams)); + + // the caller must have filled extra fixed arguments with nil + LUAU_ASSERT(cast_int(L->top - base) >= numparams); + + // move fixed parameters to final position + StkId fixed = base; // first fixed argument + base = L->top; // final position of first argument + + for (int i = 0; i < numparams; ++i) + { + setobj2s(L, base + i, fixed + i); + setnilvalue(fixed + i); + } + + // rewire our stack frame to point to the new base + L->ci->base = base; + L->ci->top = base + cl->stacksize; + + L->base = base; + L->top = L->ci->top; + VM_NEXT(); + } + + VM_CASE(LOP_JUMPBACK) + { + VM_INTERRUPT(); + Instruction insn = *pc++; + + pc += LUAU_INSN_D(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_LOADKX) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + uint32_t aux = *pc++; + TValue* kv = VM_KV(aux); + + setobj2s(L, ra, kv); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPX) + { + VM_INTERRUPT(); + Instruction insn = *pc++; + + pc += LUAU_INSN_E(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_FASTCALL) + { + Instruction insn = *pc++; + int bfid = LUAU_INSN_A(insn); + int skip = LUAU_INSN_C(insn); + LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + + Instruction call = pc[skip]; + LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + + StkId ra = VM_REG(LUAU_INSN_A(call)); + + int nparams = LUAU_INSN_B(call) - 1; + int nresults = LUAU_INSN_C(call) - 1; + + nparams = (nparams == LUA_MULTRET) ? int(L->top - ra - 1) : nparams; + + luau_FastFunction f = luauF_table[bfid]; + LUAU_ASSERT(f); + + if (cl->env->safeenv) + { + VM_PROTECT_PC(); // f may fail due to OOM + + int n = f(L, ra, ra + 1, nresults, ra + 2, nparams); + + if (n >= 0) + { + // when nresults != MULTRET, L->top might be pointing to the middle of stack frame if nparams is equal to MULTRET + // instead of restoring L->top to L->ci->top if nparams is MULTRET, we do it unconditionally to skip an extra check + L->top = (nresults == LUA_MULTRET) ? ra + n : L->ci->top; + + pc += skip + 1; // skip instructions that compute function as well as CALL + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + + VM_CASE(LOP_COVERAGE) + { + Instruction insn = *pc++; + int hits = LUAU_INSN_E(insn); + + // update hits with saturated add and patch the instruction in place + hits = (hits < (1 << 23) - 1) ? hits + 1 : hits; + VM_PATCH_E(pc - 1, hits); + + VM_NEXT(); + } + + VM_CASE(LOP_CAPTURE) + { + LUAU_ASSERT(!"CAPTURE is a pseudo-opcode and must be executed as part of NEWCLOSURE"); + LUAU_UNREACHABLE(); + } + + VM_CASE(LOP_SUBRK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (ttisnumber(rc)) + { + setnvalue(ra, nvalue(kv) - nvalue(rc)); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, kv, rc)); + VM_NEXT(); + } + } + + VM_CASE(LOP_DIVRK) + { + Instruction insn = *pc++; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_B(insn)); + StkId rc = VM_REG(LUAU_INSN_C(insn)); + + // fast-path + if (LUAU_LIKELY(ttisnumber(rc))) + { + setnvalue(ra, nvalue(kv) / nvalue(rc)); + VM_NEXT(); + } + else if (ttisvector(rc)) + { + float nb = cast_to(float, nvalue(kv)); + const float* vc = vvalue(rc); + setvvalue(ra, nb / vc[0], nb / vc[1], nb / vc[2], nb / vc[3]); + VM_NEXT(); + } + else + { + // slow-path, may invoke C/Lua via metamethods + VM_PROTECT(luaV_doarithimpl(L, ra, kv, rc)); + VM_NEXT(); + } + } + + VM_CASE(LOP_FASTCALL1) + { + Instruction insn = *pc++; + int bfid = LUAU_INSN_A(insn); + TValue* arg = VM_REG(LUAU_INSN_B(insn)); + int skip = LUAU_INSN_C(insn); + + LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + + Instruction call = pc[skip]; + LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + + StkId ra = VM_REG(LUAU_INSN_A(call)); + + int nparams = 1; + int nresults = LUAU_INSN_C(call) - 1; + + luau_FastFunction f = luauF_table[bfid]; + LUAU_ASSERT(f); + + if (cl->env->safeenv) + { + VM_PROTECT_PC(); // f may fail due to OOM + + int n = f(L, ra, arg, nresults, NULL, nparams); + + if (n >= 0) + { + if (nresults == LUA_MULTRET) + L->top = ra + n; + + pc += skip + 1; // skip instructions that compute function as well as CALL + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + + VM_CASE(LOP_FASTCALL2) + { + Instruction insn = *pc++; + int bfid = LUAU_INSN_A(insn); + int skip = LUAU_INSN_C(insn) - 1; + uint32_t aux = *pc++; + TValue* arg1 = VM_REG(LUAU_INSN_B(insn)); + TValue* arg2 = VM_REG(aux); + + LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + + Instruction call = pc[skip]; + LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + + StkId ra = VM_REG(LUAU_INSN_A(call)); + + int nparams = 2; + int nresults = LUAU_INSN_C(call) - 1; + + luau_FastFunction f = luauF_table[bfid]; + LUAU_ASSERT(f); + + if (cl->env->safeenv) + { + VM_PROTECT_PC(); // f may fail due to OOM + + int n = f(L, ra, arg1, nresults, arg2, nparams); + + if (n >= 0) + { + if (nresults == LUA_MULTRET) + L->top = ra + n; + + pc += skip + 1; // skip instructions that compute function as well as CALL + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + + VM_CASE(LOP_FASTCALL2K) + { + Instruction insn = *pc++; + int bfid = LUAU_INSN_A(insn); + int skip = LUAU_INSN_C(insn) - 1; + uint32_t aux = *pc++; + TValue* arg1 = VM_REG(LUAU_INSN_B(insn)); + TValue* arg2 = VM_KV(aux); + + LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + + Instruction call = pc[skip]; + LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + + StkId ra = VM_REG(LUAU_INSN_A(call)); + + int nparams = 2; + int nresults = LUAU_INSN_C(call) - 1; + + luau_FastFunction f = luauF_table[bfid]; + LUAU_ASSERT(f); + + if (cl->env->safeenv) + { + VM_PROTECT_PC(); // f may fail due to OOM + + int n = f(L, ra, arg1, nresults, arg2, nparams); + + if (n >= 0) + { + if (nresults == LUA_MULTRET) + L->top = ra + n; + + pc += skip + 1; // skip instructions that compute function as well as CALL + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + + VM_CASE(LOP_FASTCALL3) + { + Instruction insn = *pc++; + int bfid = LUAU_INSN_A(insn); + int skip = LUAU_INSN_C(insn) - 1; + uint32_t aux = *pc++; + TValue* arg1 = VM_REG(LUAU_INSN_B(insn)); + TValue* arg2 = VM_REG(LUAU_INSN_AUX_A(aux)); + TValue* arg3 = VM_REG(LUAU_INSN_AUX_B(aux)); + + LUAU_ASSERT(unsigned(pc - cl->l.p->code + skip) < unsigned(cl->l.p->sizecode)); + + Instruction call = pc[skip]; + LUAU_ASSERT(LUAU_INSN_OP(call) == LOP_CALL); + + StkId ra = VM_REG(LUAU_INSN_A(call)); + + int nparams = 3; + int nresults = LUAU_INSN_C(call) - 1; + + luau_FastFunction f = luauF_table[bfid]; + LUAU_ASSERT(f); + + if (cl->env->safeenv) + { + VM_PROTECT_PC(); // f may fail due to OOM + + // note: it's safe to push arguments past top for complicated reasons (see top of the file) + LUAU_ASSERT(L->top + 2 < L->stack + L->stacksize); + StkId top = L->top; + setobj2s(L, top, arg2); + setobj2s(L, top + 1, arg3); + + int n = f(L, ra, arg1, nresults, top, nparams); + + if (n >= 0) + { + if (nresults == LUA_MULTRET) + L->top = ra + n; + + pc += skip + 1; // skip instructions that compute function as well as CALL + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + else + { + // continue execution through the fallback code + VM_NEXT(); + } + } + + VM_CASE(LOP_BREAK) + { + LUAU_ASSERT(cl->l.p->debuginsn); + + uint8_t op = cl->l.p->debuginsn[unsigned(pc - cl->l.p->code)]; + LUAU_ASSERT(op != LOP_BREAK); + + if (L->global->cb.debugbreak) + { + VM_PROTECT(luau_callhook(L, L->global->cb.debugbreak, NULL)); + + // allow debugbreak hook to put thread into error/yield state + if (L->status != 0) + goto exit; + } + + VM_CONTINUE(op); + } + + VM_CASE(LOP_JUMPXEQKNIL) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + static_assert(LUA_TNIL == 0, "we expect type-1 to be negative iff type is nil"); + // condition is equivalent to: int(ttisnil(ra)) != LUAU_INSN_AUX_NOT(aux) + pc += int((ttype(ra) - 1) ^ aux) < 0 ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPXEQKB) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + + pc += int(ttisboolean(ra) && bvalue(ra) == int(LUAU_INSN_AUX_KB(aux))) != LUAU_INSN_AUX_NOT(aux) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPXEQKN) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_AUX_KV(aux)); + LUAU_ASSERT(ttisnumber(kv)); + +#if defined(__aarch64__) + // On several ARM chips (Apple M1/M2, Neoverse N1), comparing the result of a floating-point comparison is expensive, and a branch + // is much cheaper; on some 32-bit ARM chips (Cortex A53) the performance is about the same so we prefer less branchy variant there + if (LUAU_INSN_AUX_NOT(aux)) + pc += !(ttisnumber(ra) && nvalue(ra) == nvalue(kv)) ? LUAU_INSN_D(insn) : 1; + else + pc += (ttisnumber(ra) && nvalue(ra) == nvalue(kv)) ? LUAU_INSN_D(insn) : 1; +#else + pc += int(ttisnumber(ra) && nvalue(ra) == nvalue(kv)) != LUAU_INSN_AUX_NOT(aux) ? LUAU_INSN_D(insn) : 1; +#endif + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + + VM_CASE(LOP_JUMPXEQKS) + { + Instruction insn = *pc++; + uint32_t aux = *pc; + StkId ra = VM_REG(LUAU_INSN_A(insn)); + TValue* kv = VM_KV(LUAU_INSN_AUX_KV(aux)); + LUAU_ASSERT(ttisstring(kv)); + + pc += int(ttisstring(ra) && gcvalue(ra) == gcvalue(kv)) != LUAU_INSN_AUX_NOT(aux) ? LUAU_INSN_D(insn) : 1; + LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode)); + VM_NEXT(); + } + +#if !VM_USE_CGOTO + default: + LUAU_ASSERT(!"Unknown opcode"); + LUAU_UNREACHABLE(); // improves switch() codegen by eliding opcode bounds checks +#endif + } + } + +exit:; +} + +void luau_execute(lua_State* L) +{ + if (L->singlestep) + luau_execute(L); + else + luau_execute(L); +} + +int luau_precall(lua_State* L, StkId func, int nresults) +{ + if (!ttisfunction(func)) + { + luaV_tryfuncTM(L, func); + // L->top is incremented by tryfuncTM + } + + Closure* ccl = clvalue(func); + + CallInfo* ci = incr_ci(L); + ci->func = func; + ci->base = func + 1; + ci->top = L->top + ccl->stacksize; + ci->savedpc = NULL; + ci->flags = 0; + ci->nresults = nresults; + + L->base = ci->base; + // Note: L->top is assigned externally + + luaD_checkstackfornewci(L, ccl->stacksize); + LUAU_ASSERT(ci->top <= L->stack_last); + + if (!ccl->isC) + { + Proto* p = ccl->l.p; + + // fill unused parameters with nil + StkId argi = L->top; + StkId argend = L->base + p->numparams; + while (argi < argend) + setnilvalue(argi++); // complete missing arguments + L->top = p->is_vararg ? argi : ci->top; + + ci->savedpc = p->code; + +#if VM_HAS_NATIVE + if (p->exectarget != 0 && p->execdata) + ci->flags = LUA_CALLINFO_NATIVE; +#endif + + return PCRLUA; + } + else + { + lua_CFunction func = ccl->c.f; + int n = func(L); + + // yield + if (n < 0) + return PCRYIELD; + + // ci is our callinfo, cip is our parent + CallInfo* ci = L->ci; + CallInfo* cip = ci - 1; + + // copy return values into parent stack (but only up to nresults!), fill the rest with nil + // TODO: it might be worthwhile to handle the case when nresults==b explicitly? + StkId res = ci->func; + StkId vali = L->top - n; + StkId valend = L->top; + + int i; + for (i = nresults; i != 0 && vali < valend; i--) + setobj2s(L, res++, vali++); + while (i-- > 0) + setnilvalue(res++); + + // pop the stack frame + L->ci = cip; + L->base = cip->base; + L->top = res; + + return PCRC; + } +} + +void luau_poscall(lua_State* L, StkId first) +{ + // finish interrupted execution of `OP_CALL' + // ci is our callinfo, cip is our parent + CallInfo* ci = L->ci; + CallInfo* cip = ci - 1; + + // copy return values into parent stack (but only up to nresults!), fill the rest with nil + // TODO: it might be worthwhile to handle the case when nresults==b explicitly? + StkId res = ci->func; + StkId vali = first; + StkId valend = L->top; + + int i; + for (i = ci->nresults; i != 0 && vali < valend; i--) + setobj2s(L, res++, vali++); + while (i-- > 0) + setnilvalue(res++); + + // pop the stack frame + L->ci = cip; + L->base = cip->base; + L->top = (ci->nresults == LUA_MULTRET) ? res : cip->top; +} diff --git a/thirdparty/luau/upstream/VM/src/lvmload.cpp b/thirdparty/luau/upstream/VM/src/lvmload.cpp new file mode 100644 index 000000000..e632b3a9a --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lvmload.cpp @@ -0,0 +1,694 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lvm.h" + +#include "lstate.h" +#include "ltable.h" +#include "lfunc.h" +#include "lstring.h" +#include "lgc.h" +#include "lmem.h" +#include "lbytecode.h" +#include "lapi.h" + +#include + +template +struct TempBuffer +{ + lua_State* L; + T* data; + size_t count; + + TempBuffer() + : L(NULL) + , data(NULL) + , count(0) + { + } + + TempBuffer(const TempBuffer&) = delete; + TempBuffer(TempBuffer&&) = delete; + + TempBuffer& operator=(const TempBuffer&) = delete; + TempBuffer& operator=(TempBuffer&&) = delete; + + ~TempBuffer() noexcept + { + if (data) + luaM_freearray(L, data, count, T, 0); + } + + void allocate(lua_State* L, size_t count) + { + LUAU_ASSERT(this->L == nullptr); + this->L = L; + this->data = luaM_newarray(L, count, T, 0); + this->count = count; + } + + T& operator[](size_t index) + { + LUAU_ASSERT(index < count); + return data[index]; + } +}; + +struct ScopedSetGCThreshold +{ +public: + ScopedSetGCThreshold(global_State* global, size_t newThreshold) noexcept + : global{global} + { + originalThreshold = global->GCthreshold; + global->GCthreshold = newThreshold; + } + + ScopedSetGCThreshold(const ScopedSetGCThreshold&) = delete; + ScopedSetGCThreshold(ScopedSetGCThreshold&&) = delete; + + ScopedSetGCThreshold& operator=(const ScopedSetGCThreshold&) = delete; + ScopedSetGCThreshold& operator=(ScopedSetGCThreshold&&) = delete; + + ~ScopedSetGCThreshold() noexcept + { + global->GCthreshold = originalThreshold; + } + +private: + global_State* global = nullptr; + size_t originalThreshold = 0; +}; + +void luaV_getimport(lua_State* L, LuaTable* env, TValue* k, StkId res, uint32_t id, bool propagatenil) +{ + int count = id >> 30; + LUAU_ASSERT(count > 0); + + int id0 = int(id >> 20) & 1023; + int id1 = int(id >> 10) & 1023; + int id2 = int(id) & 1023; + + // after the first call to luaV_gettable, res may be invalid, and env may (sometimes) be garbage collected + // we take care to not use env again and to restore res before every consecutive use + ptrdiff_t resp = savestack(L, res); + + // global lookup for id0 + TValue g; + sethvalue(L, &g, env); + luaV_gettable(L, &g, &k[id0], res); + + // table lookup for id1 + if (count < 2) + return; + + res = restorestack(L, resp); + if (!propagatenil || !ttisnil(res)) + luaV_gettable(L, res, &k[id1], res); + + // table lookup for id2 + if (count < 3) + return; + + res = restorestack(L, resp); + if (!propagatenil || !ttisnil(res)) + luaV_gettable(L, res, &k[id2], res); +} + +template +static T read(const char* data, size_t size, size_t& offset) +{ + T result; + memcpy(&result, data + offset, sizeof(T)); + offset += sizeof(T); + + return result; +} + +static unsigned int readVarInt(const char* data, size_t size, size_t& offset) +{ + unsigned int result = 0; + unsigned int shift = 0; + + uint8_t byte; + + do + { + byte = read(data, size, offset); + result |= (byte & 127) << shift; + shift += 7; + } while (byte & 128); + + return result; +} + +static TString* readString(TempBuffer& strings, const char* data, size_t size, size_t& offset) +{ + unsigned int id = readVarInt(data, size, offset); + + return id == 0 ? NULL : strings[id - 1]; +} + +static void resolveImportSafe(lua_State* L, LuaTable* env, TValue* k, uint32_t id) +{ + struct ResolveImport + { + TValue* k; + uint32_t id; + + static void run(lua_State* L, void* ud) + { + ResolveImport* self = static_cast(ud); + + // note: we call getimport with nil propagation which means that accesses to table chains like A.B.C will resolve in nil + // this is technically not necessary but it reduces the number of exceptions when loading scripts that rely on getfenv/setfenv for global + // injection + // allocate a stack slot so that we can do table lookups + luaD_checkstack(L, 1); + setnilvalue(L->top); + L->top++; + + luaV_getimport(L, L->gt, self->k, L->top - 1, self->id, /* propagatenil= */ true); + } + }; + + ResolveImport ri = {k, id}; + if (L->gt->safeenv) + { + // luaD_pcall will make sure that if any C/Lua calls during import resolution fail, the thread state is restored back + int oldTop = lua_gettop(L); + int status = luaD_pcall(L, &ResolveImport::run, &ri, savestack(L, L->top), 0); + LUAU_ASSERT(oldTop + 1 == lua_gettop(L)); // if an error occurred, luaD_pcall saves it on stack + + if (status != 0) + { + // replace error object with nil + setnilvalue(L->top - 1); + } + } + else + { + setnilvalue(L->top); + L->top++; + } +} + +static void remapUserdataTypes(char* data, size_t size, uint8_t* userdataRemapping, uint32_t count) +{ + size_t offset = 0; + + uint32_t typeSize = readVarInt(data, size, offset); + uint32_t upvalCount = readVarInt(data, size, offset); + uint32_t localCount = readVarInt(data, size, offset); + + if (typeSize != 0) + { + uint8_t* types = (uint8_t*)data + offset; + + // Skip two bytes of function type introduction + for (uint32_t i = 2; i < typeSize; i++) + { + uint32_t index = uint32_t(types[i] - LBC_TYPE_TAGGED_USERDATA_BASE); + + if (index < count) + types[i] = userdataRemapping[index]; + } + + offset += typeSize; + } + + if (upvalCount != 0) + { + uint8_t* types = (uint8_t*)data + offset; + + for (uint32_t i = 0; i < upvalCount; i++) + { + uint32_t index = uint32_t(types[i] - LBC_TYPE_TAGGED_USERDATA_BASE); + + if (index < count) + types[i] = userdataRemapping[index]; + } + + offset += upvalCount; + } + + if (localCount != 0) + { + for (uint32_t i = 0; i < localCount; i++) + { + uint32_t index = uint32_t(data[offset] - LBC_TYPE_TAGGED_USERDATA_BASE); + + if (index < count) + data[offset] = userdataRemapping[index]; + + offset += 2; + readVarInt(data, size, offset); + readVarInt(data, size, offset); + } + } + + LUAU_ASSERT(offset == size); +} + +static int loadsafe( + lua_State* L, + TempBuffer& strings, + TempBuffer& protos, + const char* chunkname, + const char* data, + size_t size, + int env +) +{ + size_t offset = 0; + + uint8_t version = read(data, size, offset); + + + // 0 means the rest of the bytecode is the error message + if (version == 0) + { + char chunkbuf[LUA_IDSIZE]; + const char* chunkid = luaO_chunkid(chunkbuf, sizeof(chunkbuf), chunkname, strlen(chunkname)); + lua_pushfstring(L, "%s%.*s", chunkid, int(size - offset), data + offset); + return 1; + } + + if (version < LBC_VERSION_MIN || version > LBC_VERSION_MAX) + { + char chunkbuf[LUA_IDSIZE]; + const char* chunkid = luaO_chunkid(chunkbuf, sizeof(chunkbuf), chunkname, strlen(chunkname)); + lua_pushfstring(L, "%s: bytecode version mismatch (expected [%d..%d], got %d)", chunkid, LBC_VERSION_MIN, LBC_VERSION_MAX, version); + return 1; + } + + uint8_t typesversion = 0; + + if (version >= 4) + { + typesversion = read(data, size, offset); + + if (typesversion < LBC_TYPE_VERSION_MIN || typesversion > LBC_TYPE_VERSION_MAX) + { + char chunkbuf[LUA_IDSIZE]; + const char* chunkid = luaO_chunkid(chunkbuf, sizeof(chunkbuf), chunkname, strlen(chunkname)); + lua_pushfstring( + L, "%s: bytecode type version mismatch (expected [%d..%d], got %d)", chunkid, LBC_TYPE_VERSION_MIN, LBC_TYPE_VERSION_MAX, typesversion + ); + return 1; + } + } + + // env is 0 for current environment and a stack index otherwise + LuaTable* envt = (env == 0) ? L->gt : hvalue(luaA_toobject(L, env)); + + TString* source = luaS_new(L, chunkname); + + // string table + unsigned int stringCount = readVarInt(data, size, offset); + strings.allocate(L, stringCount); + + for (unsigned int i = 0; i < stringCount; ++i) + { + unsigned int length = readVarInt(data, size, offset); + + strings[i] = luaS_newlstr(L, data + offset, length); + offset += length; + } + + // userdata type remapping table + // for unknown userdata types, the entry will remap to common 'userdata' type + const uint32_t userdataTypeLimit = LBC_TYPE_TAGGED_USERDATA_END - LBC_TYPE_TAGGED_USERDATA_BASE; + uint8_t userdataRemapping[userdataTypeLimit]; + + if (typesversion == 3) + { + memset(userdataRemapping, LBC_TYPE_USERDATA, userdataTypeLimit); + + uint8_t index = read(data, size, offset); + + while (index != 0) + { + TString* name = readString(strings, data, size, offset); + + if (uint32_t(index - 1) < userdataTypeLimit) + { + if (auto cb = L->global->ecb.gettypemapping) + userdataRemapping[index - 1] = cb(L, getstr(name), name->len); + } + + index = read(data, size, offset); + } + } + + // proto table + unsigned int protoCount = readVarInt(data, size, offset); + protos.allocate(L, protoCount); + + for (unsigned int i = 0; i < protoCount; ++i) + { + Proto* p = luaF_newproto(L); + p->source = source; + p->bytecodeid = int(i); + + p->maxstacksize = read(data, size, offset); + p->numparams = read(data, size, offset); + p->nups = read(data, size, offset); + p->is_vararg = read(data, size, offset); + + if (version >= 4) + { + p->flags = read(data, size, offset); + + if (typesversion == 1) + { + uint32_t typesize = readVarInt(data, size, offset); + + if (typesize) + { + uint8_t* types = (uint8_t*)data + offset; + + LUAU_ASSERT(typesize == unsigned(2 + p->numparams)); + LUAU_ASSERT(types[0] == LBC_TYPE_FUNCTION); + LUAU_ASSERT(types[1] == p->numparams); + + // transform v1 into v2 format + int headersize = typesize > 127 ? 4 : 3; + + p->typeinfo = luaM_newarray(L, headersize + typesize, uint8_t, p->memcat); + p->sizetypeinfo = headersize + typesize; + + if (headersize == 4) + { + p->typeinfo[0] = (typesize & 127) | (1 << 7); + p->typeinfo[1] = typesize >> 7; + p->typeinfo[2] = 0; + p->typeinfo[3] = 0; + } + else + { + p->typeinfo[0] = uint8_t(typesize); + p->typeinfo[1] = 0; + p->typeinfo[2] = 0; + } + + memcpy(p->typeinfo + headersize, types, typesize); + } + + offset += typesize; + } + else if (typesversion == 2 || typesversion == 3) + { + uint32_t typesize = readVarInt(data, size, offset); + + if (typesize) + { + uint8_t* types = (uint8_t*)data + offset; + + p->typeinfo = luaM_newarray(L, typesize, uint8_t, p->memcat); + p->sizetypeinfo = typesize; + memcpy(p->typeinfo, types, typesize); + offset += typesize; + + if (typesversion == 3) + { + remapUserdataTypes((char*)(uint8_t*)p->typeinfo, p->sizetypeinfo, userdataRemapping, userdataTypeLimit); + } + } + } + } + + const int sizecode = readVarInt(data, size, offset); + p->code = luaM_newarray(L, sizecode, Instruction, p->memcat); + p->sizecode = sizecode; + + for (int j = 0; j < p->sizecode; ++j) + p->code[j] = read(data, size, offset); + + p->codeentry = p->code; + + const int sizek = readVarInt(data, size, offset); + p->k = luaM_newarray(L, sizek, TValue, p->memcat); + p->sizek = sizek; + + // Initialize the constants to nil to ensure they have a valid state + // in the event that some operation in the following loop fails with + // an exception. + for (int j = 0; j < p->sizek; ++j) + { + setnilvalue(&p->k[j]); + } + + for (int j = 0; j < p->sizek; ++j) + { + switch (read(data, size, offset)) + { + case LBC_CONSTANT_NIL: + // All constants have already been pre-initialized to nil + break; + + case LBC_CONSTANT_BOOLEAN: + { + uint8_t v = read(data, size, offset); + setbvalue(&p->k[j], v); + break; + } + + case LBC_CONSTANT_NUMBER: + { + double v = read(data, size, offset); + setnvalue(&p->k[j], v); + break; + } + + case LBC_CONSTANT_VECTOR: + { + float x = read(data, size, offset); + float y = read(data, size, offset); + float z = read(data, size, offset); + float w = read(data, size, offset); + (void)w; + setvvalue(&p->k[j], x, y, z, w); + break; + } + + case LBC_CONSTANT_STRING: + { + TString* v = readString(strings, data, size, offset); + setsvalue(L, &p->k[j], v); + break; + } + + case LBC_CONSTANT_IMPORT: + { + uint32_t iid = read(data, size, offset); + resolveImportSafe(L, envt, p->k, iid); + setobj(L, &p->k[j], L->top - 1); + L->top--; + break; + } + + case LBC_CONSTANT_TABLE: + { + int keys = readVarInt(data, size, offset); + LuaTable* h = luaH_new(L, 0, keys); + for (int i = 0; i < keys; ++i) + { + int key = readVarInt(data, size, offset); + TValue* val = luaH_set(L, h, &p->k[key]); + setnvalue(val, 0.0); + } + sethvalue(L, &p->k[j], h); + break; + } + + case LBC_CONSTANT_TABLE_WITH_CONSTANTS: + { + uint32_t keys = readVarInt(data, size, offset); + LuaTable* h = luaH_new(L, 0, keys); + + TempBuffer nilKeys; + nilKeys.allocate(L, keys); + size_t nilKeysSize = 0; + + for (uint32_t i = 0; i < keys; ++i) + { + int32_t key = readVarInt(data, size, offset); + TValue* val = luaH_set(L, h, &p->k[key]); + int32_t constantIdx = read(data, size, offset); + if (constantIdx >= 0) + { + TValue* constant = &p->k[constantIdx]; + if (ttisnil(constant)) + { + nilKeys[nilKeysSize++] = key; + } + else + { + setobj2t(L, val, constant); + luaC_barriert(L, h, constant); + continue; + } + } + setnvalue(val, 0.0); + } + + for (size_t idx = 0; idx < nilKeysSize; idx++) + { + int32_t key = nilKeys[idx]; + TValue* val = luaH_set(L, h, &p->k[key]); + setnilvalue(val); + } + + sethvalue(L, &p->k[j], h); + break; + } + + case LBC_CONSTANT_CLOSURE: + { + uint32_t fid = readVarInt(data, size, offset); + Closure* cl = luaF_newLclosure(L, protos[fid]->nups, envt, protos[fid]); + cl->preload = (cl->nupvalues > 0); + setclvalue(L, &p->k[j], cl); + break; + } + + default: + LUAU_ASSERT(!"Unexpected constant kind"); + } + } + + const int sizep = readVarInt(data, size, offset); + p->p = luaM_newarray(L, sizep, Proto*, p->memcat); + p->sizep = sizep; + + for (int j = 0; j < p->sizep; ++j) + { + uint32_t fid = readVarInt(data, size, offset); + p->p[j] = protos[fid]; + } + + p->linedefined = readVarInt(data, size, offset); + p->debugname = readString(strings, data, size, offset); + + uint8_t lineinfo = read(data, size, offset); + + if (lineinfo) + { + p->linegaplog2 = read(data, size, offset); + + int intervals = ((p->sizecode - 1) >> p->linegaplog2) + 1; + int absoffset = (p->sizecode + 3) & ~3; + + const int sizelineinfo = absoffset + intervals * sizeof(int); + p->lineinfo = luaM_newarray(L, sizelineinfo, uint8_t, p->memcat); + p->sizelineinfo = sizelineinfo; + + p->abslineinfo = (int*)(p->lineinfo + absoffset); + + uint8_t lastoffset = 0; + for (int j = 0; j < p->sizecode; ++j) + { + lastoffset += read(data, size, offset); + p->lineinfo[j] = lastoffset; + } + + int lastline = 0; + for (int j = 0; j < intervals; ++j) + { + lastline += read(data, size, offset); + p->abslineinfo[j] = lastline; + } + } + + uint8_t debuginfo = read(data, size, offset); + + if (debuginfo) + { + const int sizelocvars = readVarInt(data, size, offset); + p->locvars = luaM_newarray(L, sizelocvars, LocVar, p->memcat); + p->sizelocvars = sizelocvars; + + for (int j = 0; j < p->sizelocvars; ++j) + { + p->locvars[j].varname = readString(strings, data, size, offset); + p->locvars[j].startpc = readVarInt(data, size, offset); + p->locvars[j].endpc = readVarInt(data, size, offset); + p->locvars[j].reg = read(data, size, offset); + } + + const int sizeupvalues = readVarInt(data, size, offset); + LUAU_ASSERT(sizeupvalues == p->nups); + + p->upvalues = luaM_newarray(L, sizeupvalues, TString*, p->memcat); + p->sizeupvalues = sizeupvalues; + + for (int j = 0; j < p->sizeupvalues; ++j) + { + p->upvalues[j] = readString(strings, data, size, offset); + } + } + + protos[i] = p; + } + + // "main" proto is pushed to Lua stack + uint32_t mainid = readVarInt(data, size, offset); + Proto* main = protos[mainid]; + + luaC_threadbarrier(L); + + Closure* cl = luaF_newLclosure(L, 0, envt, main); + setclvalue(L, L->top, cl); + incr_top(L); + + return 0; +} + +int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env) +{ + // we will allocate a fair amount of memory so check GC before we do + luaC_checkGC(L); + + // pause GC for the duration of deserialization - some objects we're creating aren't rooted + const ScopedSetGCThreshold pauseGC{L->global, SIZE_MAX}; + + struct LoadContext + { + TempBuffer strings; + TempBuffer protos; + const char* chunkname; + const char* data; + size_t size; + int env; + + int result; + + static void run(lua_State* L, void* ud) + { + LoadContext* ctx = (LoadContext*)ud; + + ctx->result = loadsafe(L, ctx->strings, ctx->protos, ctx->chunkname, ctx->data, ctx->size, ctx->env); + } + } ctx = { + {}, + {}, + chunkname, + data, + size, + env, + }; + + int status = luaD_rawrunprotected(L, &LoadContext::run, &ctx); + + // load can either succeed or get an OOM error, any other errors should be handled internally + LUAU_ASSERT(status == LUA_OK || status == LUA_ERRMEM); + + if (status == LUA_ERRMEM) + { + lua_pushstring(L, LUA_MEMERRMSG); // out-of-memory error message doesn't require an allocation + return 1; + } + + return ctx.result; +} diff --git a/thirdparty/luau/upstream/VM/src/lvmutils.cpp b/thirdparty/luau/upstream/VM/src/lvmutils.cpp new file mode 100644 index 000000000..5c49139f6 --- /dev/null +++ b/thirdparty/luau/upstream/VM/src/lvmutils.cpp @@ -0,0 +1,638 @@ +// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details +// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details +#include "lvm.h" + +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lgc.h" +#include "ldo.h" +#include "lnumutils.h" + +#include + +// limit for table tag-method chains (to avoid loops) +#define MAXTAGLOOP 100 + +const TValue* luaV_tonumber(const TValue* obj, TValue* n) +{ + double num; + if (ttisnumber(obj)) + return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) + { + setnvalue(n, num); + return n; + } + else + return NULL; +} + +int luaV_tostring(lua_State* L, StkId obj) +{ + if (!ttisnumber(obj)) + return 0; + else + { + char s[LUAI_MAXNUM2STR]; + double n = nvalue(obj); + char* e = luai_num2str(s, n); + LUAU_ASSERT(e < s + sizeof(s)); + setsvalue(L, obj, luaS_newlstr(L, s, e - s)); + return 1; + } +} + +const float* luaV_tovector(const TValue* obj) +{ + if (ttisvector(obj)) + return vvalue(obj); + + return nullptr; +} + +static StkId callTMres(lua_State* L, StkId res, const TValue* f, const TValue* p1, const TValue* p2) +{ + ptrdiff_t result = savestack(L, res); + // using stack room beyond top is technically safe here, but for very complicated reasons: + // * The stack guarantees EXTRA_STACK room beyond stack_last (see luaD_reallocstack) will be allocated + // * we cannot move luaD_checkstack above because the arguments are *sometimes* pointers to the lua + // stack and checkstack may invalidate those pointers + // * we cannot use savestack/restorestack because the arguments are sometimes on the C++ stack + // * during stack reallocation all of the allocated stack is copied (even beyond stack_last) so these + // values will be preserved even if they go past stack_last + LUAU_ASSERT((L->top + 3) < (L->stack + L->stacksize)); + setobj2s(L, L->top, f); // push function + setobj2s(L, L->top + 1, p1); // 1st argument + setobj2s(L, L->top + 2, p2); // 2nd argument + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobj2s(L, res, L->top); + return res; +} + +static void callTM(lua_State* L, const TValue* f, const TValue* p1, const TValue* p2, const TValue* p3) +{ + // using stack room beyond top is technically safe here, but for very complicated reasons: + // * The stack guarantees EXTRA_STACK room beyond stack_last (see luaD_reallocstack) will be allocated + // * we cannot move luaD_checkstack above because the arguments are *sometimes* pointers to the lua + // stack and checkstack may invalidate those pointers + // * we cannot use savestack/restorestack because the arguments are sometimes on the C++ stack + // * during stack reallocation all of the allocated stack is copied (even beyond stack_last) so these + // values will be preserved even if they go past stack_last + LUAU_ASSERT((L->top + 4) < (L->stack + L->stacksize)); + setobj2s(L, L->top, f); // push function + setobj2s(L, L->top + 1, p1); // 1st argument + setobj2s(L, L->top + 2, p2); // 2nd argument + setobj2s(L, L->top + 3, p3); // 3th argument + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + +void luaV_gettable(lua_State* L, const TValue* t, TValue* key, StkId val) +{ + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) + { + const TValue* tm; + if (ttistable(t)) + { // `t' is a table? + LuaTable* h = hvalue(t); + + const TValue* res = luaH_get(h, key); // do a primitive get + + if (res != luaO_nilobject) + L->cachedslot = gval2slot(h, res); // remember slot to accelerate future lookups + + if (!ttisnil(res) // result is no nil? + || (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) + { // or no TM? + setobj2s(L, val, res); + return; + } + // t isn't a table, so see if it has an INDEX meta-method to look up the key with + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_indexerror(L, t, key); + if (ttisfunction(tm)) + { + callTMres(L, val, tm, t, key); + return; + } + t = tm; // else repeat with `tm' + } + luaG_runerror(L, "'__index' chain too long; possible loop"); +} + +void luaV_settable(lua_State* L, const TValue* t, TValue* key, StkId val) +{ + int loop; + TValue temp; + for (loop = 0; loop < MAXTAGLOOP; loop++) + { + const TValue* tm; + if (ttistable(t)) + { // `t' is a table? + LuaTable* h = hvalue(t); + + const TValue* oldval = luaH_get(h, key); + + // should we assign the key? (if key is valid or __newindex is not set) + if (!ttisnil(oldval) || (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) + { + if (h->readonly) + luaG_readonlyerror(L); + + // luaH_set would work but would repeat the lookup so we use luaH_setslot that can reuse oldval if it's safe + TValue* newval = luaH_setslot(L, h, oldval, key); + + L->cachedslot = gval2slot(h, newval); // remember slot to accelerate future lookups + + setobj2t(L, newval, val); + luaC_barriert(L, h, val); + return; + } + + // fallthrough to metamethod + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_indexerror(L, t, key); + + if (ttisfunction(tm)) + { + callTM(L, tm, t, key, val); + return; + } + // else repeat with `tm' + setobj(L, &temp, tm); // avoid pointing inside table (may rehash) + t = &temp; + } + luaG_runerror(L, "'__newindex' chain too long; possible loop"); +} + +static int call_binTM(lua_State* L, const TValue* p1, const TValue* p2, StkId res, TMS event) +{ + const TValue* tm = luaT_gettmbyobj(L, p1, event); // try first operand + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); // try second operand + if (ttisnil(tm)) + return 0; + callTMres(L, res, tm, p1, p2); + return 1; +} + +static const TValue* get_compTM(lua_State* L, LuaTable* mt1, LuaTable* mt2, TMS event) +{ + const TValue* tm1 = fasttm(L, mt1, event); + const TValue* tm2; + if (tm1 == NULL) + return NULL; // no metamethod + if (mt1 == mt2) + return tm1; // same metatables => same metamethods + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) + return NULL; // no metamethod + if (luaO_rawequalObj(tm1, tm2)) // same metamethods? + return tm1; + return NULL; +} + +static int call_orderTM(lua_State* L, const TValue* p1, const TValue* p2, TMS event, bool error = false) +{ + const TValue* tm1 = luaT_gettmbyobj(L, p1, event); + const TValue* tm2; + if (ttisnil(tm1)) + { + if (error) + luaG_ordererror(L, p1, p2, event); + return -1; // no metamethod? + } + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) // different metamethods? + { + if (error) + luaG_ordererror(L, p1, p2, event); + return -1; + } + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); +} + +int luaV_strcmp(const TString* ls, const TString* rs) +{ + if (ls == rs) + return 0; + + const char* l = getstr(ls); + const char* r = getstr(rs); + + // always safe to read one character because even empty strings are nul terminated + if (*l != *r) + return uint8_t(*l) - uint8_t(*r); + + size_t ll = ls->len; + size_t lr = rs->len; + size_t lmin = ll < lr ? ll : lr; + + int res = memcmp(l, r, lmin); + if (res != 0) + return res; + + return ll == lr ? 0 : ll < lr ? -1 : 1; +} + +int luaV_lessthan(lua_State* L, const TValue* l, const TValue* r) +{ + if (LUAU_UNLIKELY(ttype(l) != ttype(r))) + luaG_ordererror(L, l, r, TM_LT); + else if (LUAU_LIKELY(ttisnumber(l))) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; + else + return call_orderTM(L, l, r, TM_LT, /* error= */ true); +} + +int luaV_lessequal(lua_State* L, const TValue* l, const TValue* r) +{ + int res; + if (ttype(l) != ttype(r)) + luaG_ordererror(L, l, r, TM_LE); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) // first try `le' + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) == -1) // error if not `lt' + luaG_ordererror(L, l, r, TM_LE); + return !res; +} + +int luaV_equalval(lua_State* L, const TValue* t1, const TValue* t2) +{ + const TValue* tm; + LUAU_ASSERT(ttype(t1) == ttype(t2)); + switch (ttype(t1)) + { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TVECTOR: + return luai_veceq(vvalue(t1), vvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); // true must be 1 !! + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2) && lightuserdatatag(t1) == lightuserdatatag(t2); + case LUA_TUSERDATA: + { + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); + if (!tm) + return uvalue(t1) == uvalue(t2); + break; // will try TM + } + case LUA_TTABLE: + { + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + if (!tm) + return hvalue(t1) == hvalue(t2); + break; // will try TM + } + default: + return gcvalue(t1) == gcvalue(t2); + } + callTMres(L, L->top, tm, t1, t2); // call TM + return !l_isfalse(L->top); +} + +void luaV_concat(lua_State* L, int total, int last) +{ + do + { + StkId top = L->base + last + 1; + int n = 2; // number of elements handled in this pass (at least 2) + if (!(ttisstring(top - 2) || ttisnumber(top - 2)) || !tostring(L, top - 1)) + { + if (!call_binTM(L, top - 2, top - 1, top - 2, TM_CONCAT)) + luaG_concaterror(L, top - 2, top - 1); + } + else if (tsvalue(top - 1)->len == 0) // second op is empty? + (void)tostring(L, top - 2); // result is first op (as string) + else + { + // at least two string values; get as many as possible + size_t tl = tsvalue(top - 1)->len; + char* buffer; + int i; + // collect total length + for (n = 1; n < total && tostring(L, top - n - 1); n++) + { + size_t l = tsvalue(top - n - 1)->len; + if (l > MAXSSIZE - tl) + luaG_runerror(L, "string length overflow"); + tl += l; + } + + char buf[LUA_BUFFERSIZE]; + TString* ts = nullptr; + + if (tl < LUA_BUFFERSIZE) + { + buffer = buf; + } + else + { + ts = luaS_bufstart(L, tl); + buffer = ts->data; + } + + tl = 0; + for (i = n; i > 0; i--) + { // concat all strings + size_t l = tsvalue(top - i)->len; + memcpy(buffer + tl, svalue(top - i), l); + tl += l; + } + + if (tl < LUA_BUFFERSIZE) + { + setsvalue(L, top - n, luaS_newlstr(L, buffer, tl)); + } + else + { + setsvalue(L, top - n, luaS_buffinish(L, ts)); + } + } + total -= n - 1; // got `n' strings to create 1 new + last -= n - 1; + } while (total > 1); // repeat until only 1 result left +} + +template +void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc) +{ + TValue tempb, tempc; + const TValue *b, *c; + + // vector operations that we support: + // v+v v-v -v (add/sub/neg) + // v*v s*v v*s (mul) + // v/v s/v v/s (div) + // v//v s//v v//s (floor div) + const float* vb = ttisvector(rb) ? vvalue(rb) : nullptr; + const float* vc = ttisvector(rc) ? vvalue(rc) : nullptr; + + if (vb && vc) + { + switch (op) + { + case TM_ADD: + setvvalue(ra, vb[0] + vc[0], vb[1] + vc[1], vb[2] + vc[2], vb[3] + vc[3]); + return; + case TM_SUB: + setvvalue(ra, vb[0] - vc[0], vb[1] - vc[1], vb[2] - vc[2], vb[3] - vc[3]); + return; + case TM_MUL: + setvvalue(ra, vb[0] * vc[0], vb[1] * vc[1], vb[2] * vc[2], vb[3] * vc[3]); + return; + case TM_DIV: + setvvalue(ra, vb[0] / vc[0], vb[1] / vc[1], vb[2] / vc[2], vb[3] / vc[3]); + return; + case TM_IDIV: + setvvalue( + ra, + float(luai_numidiv(vb[0], vc[0])), + float(luai_numidiv(vb[1], vc[1])), + float(luai_numidiv(vb[2], vc[2])), + float(luai_numidiv(vb[3], vc[3])) + ); + return; + case TM_UNM: + setvvalue(ra, -vb[0], -vb[1], -vb[2], -vb[3]); + return; + default: + break; + } + } + else if (vb) + { + c = ttisnumber(rc) ? rc : luaV_tonumber(rc, &tempc); + + if (c) + { + float nc = cast_to(float, nvalue(c)); + + switch (op) + { + case TM_MUL: + setvvalue(ra, vb[0] * nc, vb[1] * nc, vb[2] * nc, vb[3] * nc); + return; + case TM_DIV: + setvvalue(ra, vb[0] / nc, vb[1] / nc, vb[2] / nc, vb[3] / nc); + return; + case TM_IDIV: + setvvalue( + ra, float(luai_numidiv(vb[0], nc)), float(luai_numidiv(vb[1], nc)), float(luai_numidiv(vb[2], nc)), float(luai_numidiv(vb[3], nc)) + ); + return; + default: + break; + } + } + } + else if (vc) + { + b = ttisnumber(rb) ? rb : luaV_tonumber(rb, &tempb); + + if (b) + { + float nb = cast_to(float, nvalue(b)); + + switch (op) + { + case TM_MUL: + setvvalue(ra, nb * vc[0], nb * vc[1], nb * vc[2], nb * vc[3]); + return; + case TM_DIV: + setvvalue(ra, nb / vc[0], nb / vc[1], nb / vc[2], nb / vc[3]); + return; + case TM_IDIV: + setvvalue( + ra, float(luai_numidiv(nb, vc[0])), float(luai_numidiv(nb, vc[1])), float(luai_numidiv(nb, vc[2])), float(luai_numidiv(nb, vc[3])) + ); + return; + default: + break; + } + } + } + + if ((b = luaV_tonumber(rb, &tempb)) != NULL && (c = luaV_tonumber(rc, &tempc)) != NULL) + { + double nb = nvalue(b), nc = nvalue(c); + + switch (op) + { + case TM_ADD: + setnvalue(ra, luai_numadd(nb, nc)); + break; + case TM_SUB: + setnvalue(ra, luai_numsub(nb, nc)); + break; + case TM_MUL: + setnvalue(ra, luai_nummul(nb, nc)); + break; + case TM_DIV: + setnvalue(ra, luai_numdiv(nb, nc)); + break; + case TM_IDIV: + setnvalue(ra, luai_numidiv(nb, nc)); + break; + case TM_MOD: + setnvalue(ra, luai_nummod(nb, nc)); + break; + case TM_POW: + setnvalue(ra, luai_numpow(nb, nc)); + break; + case TM_UNM: + setnvalue(ra, luai_numunm(nb)); + break; + default: + LUAU_ASSERT(0); + break; + } + } + else + { + if (!call_binTM(L, rb, rc, ra, op)) + { + luaG_aritherror(L, rb, rc, op); + } + } +} + +// instantiate private template implementation for external callers +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); +template void luaV_doarithimpl(lua_State* L, StkId ra, const TValue* rb, const TValue* rc); + +void luaV_dolen(lua_State* L, StkId ra, const TValue* rb) +{ + const TValue* tm = NULL; + switch (ttype(rb)) + { + case LUA_TTABLE: + { + LuaTable* h = hvalue(rb); + if ((tm = fasttm(L, h->metatable, TM_LEN)) == NULL) + { + setnvalue(ra, cast_num(luaH_getn(h))); + return; + } + break; + } + case LUA_TSTRING: + { + TString* ts = tsvalue(rb); + setnvalue(ra, cast_num(ts->len)); + return; + } + default: + tm = luaT_gettmbyobj(L, rb, TM_LEN); + } + + if (ttisnil(tm)) + luaG_typeerror(L, rb, "get length of"); + + StkId res = callTMres(L, ra, tm, rb, luaO_nilobject); + if (!ttisnumber(res)) + luaG_runerror(L, "'__len' must return a number"); // note, we can't access rb since stack may have been reallocated +} + +LUAU_NOINLINE void luaV_prepareFORN(lua_State* L, StkId plimit, StkId pstep, StkId pinit) +{ + if (!ttisnumber(pinit) && !luaV_tonumber(pinit, pinit)) + luaG_forerror(L, pinit, "initial value"); + if (!ttisnumber(plimit) && !luaV_tonumber(plimit, plimit)) + luaG_forerror(L, plimit, "limit"); + if (!ttisnumber(pstep) && !luaV_tonumber(pstep, pstep)) + luaG_forerror(L, pstep, "step"); +} + +// calls a C function f with no yielding support; optionally save one resulting value to the res register +// the function and arguments have to already be pushed to L->top +LUAU_NOINLINE void luaV_callTM(lua_State* L, int nparams, int res) +{ + ++L->nCcalls; + + if (L->nCcalls >= LUAI_MAXCCALLS) + luaD_checkCstack(L); + + luaD_checkstack(L, LUA_MINSTACK); + + StkId top = L->top; + StkId fun = top - nparams - 1; + + CallInfo* ci = incr_ci(L); + ci->func = fun; + ci->base = fun + 1; + ci->top = top + LUA_MINSTACK; + ci->savedpc = NULL; + ci->flags = 0; + ci->nresults = (res >= 0); + LUAU_ASSERT(ci->top <= L->stack_last); + + LUAU_ASSERT(ttisfunction(ci->func)); + LUAU_ASSERT(clvalue(ci->func)->isC); + + L->base = fun + 1; + LUAU_ASSERT(L->top == L->base + nparams); + + lua_CFunction func = clvalue(fun)->c.f; + int n = func(L); + LUAU_ASSERT(n >= 0); // yields should have been blocked by nCcalls + + // ci is our callinfo, cip is our parent + // note that we read L->ci again since it may have been reallocated by the call + CallInfo* cip = L->ci - 1; + + // copy return value into parent stack + if (res >= 0) + { + if (n > 0) + { + setobj2s(L, &cip->base[res], L->top - n); + } + else + { + setnilvalue(&cip->base[res]); + } + } + + L->ci = cip; + L->base = cip->base; + L->top = cip->top; + + --L->nCcalls; +} + +LUAU_NOINLINE void luaV_tryfuncTM(lua_State* L, StkId func) +{ + const TValue* tm = luaT_gettmbyobj(L, func, TM_CALL); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + for (StkId p = L->top; p > func; p--) // open space for metamethod + setobj2s(L, p, p - 1); + L->top++; // stack space pre-allocated by the caller + setobj2s(L, func, tm); // tag method is the new function to be called +} diff --git a/thirdparty/rive/include/rive/advance_flags.hpp b/thirdparty/rive/include/rive/advance_flags.hpp index 912f6b944..4ac608b95 100644 --- a/thirdparty/rive/include/rive/advance_flags.hpp +++ b/thirdparty/rive/include/rive/advance_flags.hpp @@ -1,7 +1,7 @@ #ifndef _RIVE_ADVANCE_FLAGS_HPP_ #define _RIVE_ADVANCE_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { @@ -21,6 +21,5 @@ enum class AdvanceFlags : unsigned short /// Whether we are advancing to a new frame NewFrame = 1 << 3, }; -RIVE_MAKE_ENUM_BITSET(AdvanceFlags) } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/advancing_component.hpp b/thirdparty/rive/include/rive/advancing_component.hpp index 7f9dd9f95..dc04653fd 100644 --- a/thirdparty/rive/include/rive/advancing_component.hpp +++ b/thirdparty/rive/include/rive/advancing_component.hpp @@ -13,7 +13,7 @@ class AdvancingComponent float elapsedSeconds, AdvanceFlags flags = AdvanceFlags::Animate | AdvanceFlags::NewFrame) = 0; - static AdvancingComponent* from(Component* component); + static AdvancingComponent* from(Core* component); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/blend_animation_direct.hpp b/thirdparty/rive/include/rive/animation/blend_animation_direct.hpp index 4c8433e77..82416e817 100644 --- a/thirdparty/rive/include/rive/animation/blend_animation_direct.hpp +++ b/thirdparty/rive/include/rive/animation/blend_animation_direct.hpp @@ -15,6 +15,7 @@ enum class DirectBlendSource : unsigned int class BlendAnimationDirect : public BlendAnimationDirectBase { public: + ~BlendAnimationDirect(); StatusCode onAddedDirty(CoreContext* context) override; StatusCode onAddedClean(CoreContext* context) override; StatusCode import(ImportStack& importStack) override; diff --git a/thirdparty/rive/include/rive/animation/data_converter_range_mapper_flags.hpp b/thirdparty/rive/include/rive/animation/data_converter_range_mapper_flags.hpp index a76da2df9..330c7e8e5 100644 --- a/thirdparty/rive/include/rive/animation/data_converter_range_mapper_flags.hpp +++ b/thirdparty/rive/include/rive/animation/data_converter_range_mapper_flags.hpp @@ -1,12 +1,13 @@ #ifndef _RIVE_DATA_CONVERTER_RANGE_MAPPER_FLAGS_HPP_ #define _RIVE_DATA_CONVERTER_RANGE_MAPPER_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { enum class DataConverterRangeMapperFlags : unsigned short { + None = 0, /// Whether the lower bound should be clamped ClampLower = 1 << 0, @@ -21,7 +22,5 @@ enum class DataConverterRangeMapperFlags : unsigned short Reverse = 1 << 3, }; - -RIVE_MAKE_ENUM_BITSET(DataConverterRangeMapperFlags) } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/data_converter_to_string_flags.hpp b/thirdparty/rive/include/rive/animation/data_converter_to_string_flags.hpp index b970f9ff7..d43cd70fd 100644 --- a/thirdparty/rive/include/rive/animation/data_converter_to_string_flags.hpp +++ b/thirdparty/rive/include/rive/animation/data_converter_to_string_flags.hpp @@ -1,12 +1,13 @@ #ifndef _RIVE_DATA_CONVERTER_TO_STRING_FLAGS_HPP_ #define _RIVE_DATA_CONVERTER_TO_STRING_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { enum class DataConverterToStringFlags : unsigned short { + None = 0, /// Whether to round to decimals Round = 1 << 0, @@ -14,8 +15,9 @@ enum class DataConverterToStringFlags : unsigned short /// Whether to remove trailing zeros TrailingZeros = 1 << 1, -}; + /// Whether to format the number with commans + FormatWithCommas = 1 << 2, -RIVE_MAKE_ENUM_BITSET(DataConverterToStringFlags) +}; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/focus_action.hpp b/thirdparty/rive/include/rive/animation/focus_action.hpp new file mode 100644 index 000000000..a3aac67b0 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/focus_action.hpp @@ -0,0 +1,15 @@ +/* + * Copyright 2024 Rive + */ + +#ifndef _RIVE_FOCUS_ACTION_HPP_ +#define _RIVE_FOCUS_ACTION_HPP_ +#include "rive/generated/animation/focus_action_base.hpp" + +namespace rive +{ +class FocusAction : public FocusActionBase +{}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/focus_action_target.hpp b/thirdparty/rive/include/rive/animation/focus_action_target.hpp new file mode 100644 index 000000000..1e4439d57 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/focus_action_target.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_FOCUS_ACTION_TARGET_HPP_ +#define _RIVE_FOCUS_ACTION_TARGET_HPP_ +#include "rive/generated/animation/focus_action_target_base.hpp" +namespace rive +{ +class FocusActionTarget : public FocusActionTargetBase +{ +public: + void perform(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/focus_action_traversal.hpp b/thirdparty/rive/include/rive/animation/focus_action_traversal.hpp new file mode 100644 index 000000000..6a01fcd06 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/focus_action_traversal.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_FOCUS_ACTION_TRAVERSAL_HPP_ +#define _RIVE_FOCUS_ACTION_TRAVERSAL_HPP_ +#include "rive/generated/animation/focus_action_traversal_base.hpp" +namespace rive +{ +class FocusActionTraversal : public FocusActionTraversalBase +{ +public: + void perform(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/focus_listener_group.hpp b/thirdparty/rive/include/rive/animation/focus_listener_group.hpp new file mode 100644 index 000000000..95fb77546 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/focus_listener_group.hpp @@ -0,0 +1,50 @@ +#ifndef _RIVE_FOCUS_LISTENER_GROUP_HPP_ +#define _RIVE_FOCUS_LISTENER_GROUP_HPP_ + +#include "rive/input/focus_listener.hpp" +#include "rive/listener_type.hpp" + +namespace rive +{ +class FocusData; +class StateMachineListener; +class StateMachineInstance; + +/// A FocusListenerGroup manages a focus or blur listener that's attached +/// to a FocusData. When the FocusData gains or loses focus, the listener's +/// actions are queued for deferred execution. +class FocusListenerGroup : public FocusListener +{ +public: + FocusListenerGroup(FocusData* focusData, + const StateMachineListener* listener, + StateMachineInstance* stateMachineInstance); + ~FocusListenerGroup() override; + + /// Get the listener this group is managing. + const StateMachineListener* listener() const { return m_listener; } + + /// Get the FocusData this group is attached to. + FocusData* focusData() const { return m_focusData; } + + /// Check if this is a focus listener (vs blur listener). + bool isFocusListener() const { return m_isFocusListener; } + + /// Check if this is a blur listener (vs focus listener). + bool isBlurListener() const { return m_isBlurListener; } + + // FocusListener interface + void onFocused() override; + void onBlurred() override; + +private: + FocusData* m_focusData; + const StateMachineListener* m_listener; + StateMachineInstance* m_stateMachineInstance; + bool m_isFocusListener; + bool m_isBlurListener; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/hittable.hpp b/thirdparty/rive/include/rive/animation/hittable.hpp deleted file mode 100644 index be4d888b6..000000000 --- a/thirdparty/rive/include/rive/animation/hittable.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _RIVE_HITTABLE_HPP_ -#define _RIVE_HITTABLE_HPP_ - -#include "rive/math/aabb.hpp" - -namespace rive -{ -class Component; - -// A Component that can be hit-tested via two passes: a faster AABB pass, and a -// more accurate HiFi pass. -class Hittable -{ -public: - static Hittable* from(Component* component); - virtual bool hitTestAABB(const Vec2D& position) = 0; - virtual bool hitTestHiFi(const Vec2D& position, float hitRadius) = 0; - virtual ~Hittable() {} -}; -} // namespace rive - -#endif diff --git a/thirdparty/rive/include/rive/animation/keyboard_listener_group.hpp b/thirdparty/rive/include/rive/animation/keyboard_listener_group.hpp new file mode 100644 index 000000000..fcfb6d81a --- /dev/null +++ b/thirdparty/rive/include/rive/animation/keyboard_listener_group.hpp @@ -0,0 +1,47 @@ +#ifndef _RIVE_KEYBOARD_LISTENER_GROUP_HPP_ +#define _RIVE_KEYBOARD_LISTENER_GROUP_HPP_ + +#include "rive/input/keyboard_listener.hpp" +#include "rive/listener_type.hpp" + +namespace rive +{ +class FocusData; +class StateMachineListener; +class StateMachineInstance; + +/// A KeyboardListenerGroup manages a keyboard listener that's attached +/// to a FocusData. When a key is pressed, the focus manager will call onKey +/// only on the focused one. +class KeyboardListenerGroup : public KeyboardListener +{ +public: + KeyboardListenerGroup(FocusData* focusData, + const StateMachineListener* listener, + StateMachineInstance* stateMachineInstance); + ~KeyboardListenerGroup(); + + /// Get the listener this group is managing. + const StateMachineListener* listener() const { return m_listener; } + + /// Get the FocusData this group is attached to. + FocusData* focusData() const { return m_focusData; } + + /// Called when the associated FocusData receives a key input. + bool keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) override; + + /// Called when the associated FocusData receives text input. + bool textInput(const std::string& text) override; + +private: + FocusData* m_focusData; + const StateMachineListener* m_listener; + StateMachineInstance* m_stateMachineInstance; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/keyframe_interpolator.hpp b/thirdparty/rive/include/rive/animation/keyframe_interpolator.hpp index af0a7caa2..10da9b378 100644 --- a/thirdparty/rive/include/rive/animation/keyframe_interpolator.hpp +++ b/thirdparty/rive/include/rive/animation/keyframe_interpolator.hpp @@ -26,7 +26,7 @@ class KeyFrameInterpolator : public KeyFrameInterpolatorBase StatusCode import(ImportStack& importStack) override; - virtual void initialize(){}; + virtual void initialize() {}; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/linear_animation.hpp b/thirdparty/rive/include/rive/animation/linear_animation.hpp index 5550547d9..6d4d1dc2a 100644 --- a/thirdparty/rive/include/rive/animation/linear_animation.hpp +++ b/thirdparty/rive/include/rive/animation/linear_animation.hpp @@ -43,6 +43,9 @@ class LinearAnimation : public LinearAnimationBase /// work area start/end, speed, looping). float globalToLocalSeconds(float seconds) const; + // Returns a list of only the KeyedObjects that were validated during + // onAddedDirty. This is not guaranteed to be the same as the list in the + // exported riv. const KeyedObject* getObject(size_t index) const { if (index < m_KeyedObjects.size()) diff --git a/thirdparty/rive/include/rive/animation/listener_action.hpp b/thirdparty/rive/include/rive/animation/listener_action.hpp index 691ab0fd0..9e9e392c0 100644 --- a/thirdparty/rive/include/rive/animation/listener_action.hpp +++ b/thirdparty/rive/include/rive/animation/listener_action.hpp @@ -1,7 +1,8 @@ #ifndef _RIVE_LISTENER_ACTION_HPP_ #define _RIVE_LISTENER_ACTION_HPP_ +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/state_machine_fire_action.hpp" #include "rive/generated/animation/listener_action_base.hpp" -#include "rive/math/vec2d.hpp" namespace rive { @@ -9,10 +10,31 @@ class StateMachineInstance; class ListenerAction : public ListenerActionBase { public: + enum class ParentKind : uint32_t + { + Listener = 0, + Transition = 1, + State = 2, + }; + StatusCode import(ImportStack& importStack) override; virtual void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const = 0; + const ListenerInvocation& invocation) const = 0; + + /// Layer-scheduled actions: bit 0 matches [StateMachineFireOccurance] + /// (0 = atStart, 1 = atEnd). Other bits are reserved. + bool matchesScheduledOccurrence(StateMachineFireOccurance occurs) const + { + return (flags() & 1u) == static_cast(occurs); + } + + ParentKind parentKind() const + { + auto raw = (flags() >> 1) & 0x3u; + return raw <= static_cast(ParentKind::State) + ? static_cast(raw) + : ParentKind::Listener; + } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/listener_align_target.hpp b/thirdparty/rive/include/rive/animation/listener_align_target.hpp index 2a150d6b2..265f42465 100644 --- a/thirdparty/rive/include/rive/animation/listener_align_target.hpp +++ b/thirdparty/rive/include/rive/animation/listener_align_target.hpp @@ -8,8 +8,7 @@ class ListenerAlignTarget : public ListenerAlignTargetBase { public: void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const override; + const ListenerInvocation& invocation) const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/listener_bool_change.hpp b/thirdparty/rive/include/rive/animation/listener_bool_change.hpp index a6f25c24b..c2f00121c 100644 --- a/thirdparty/rive/include/rive/animation/listener_bool_change.hpp +++ b/thirdparty/rive/include/rive/animation/listener_bool_change.hpp @@ -11,8 +11,7 @@ class ListenerBoolChange : public ListenerBoolChangeBase bool validateInputType(const StateMachineInput* input) const override; bool validateNestedInputType(const NestedInput* input) const override; void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const override; + const ListenerInvocation& invocation) const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/listener_fire_event.hpp b/thirdparty/rive/include/rive/animation/listener_fire_event.hpp index 4e4a7d23e..34c1199df 100644 --- a/thirdparty/rive/include/rive/animation/listener_fire_event.hpp +++ b/thirdparty/rive/include/rive/animation/listener_fire_event.hpp @@ -8,8 +8,7 @@ class ListenerFireEvent : public ListenerFireEventBase { public: void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const override; + const ListenerInvocation& invocation) const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/listener_invocation.hpp b/thirdparty/rive/include/rive/animation/listener_invocation.hpp new file mode 100644 index 000000000..560f93fc7 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_invocation.hpp @@ -0,0 +1,248 @@ +#ifndef _RIVE_LISTENER_INVOCATION_HPP_ +#define _RIVE_LISTENER_INVOCATION_HPP_ + +#include "rive/animation/semantic_listener_group.hpp" +#include "rive/input/focusable.hpp" +#include "rive/listener_type.hpp" +#include "rive/math/vec2d.hpp" + +#include +#include +#include + +namespace rive +{ + +class Event; +class FocusListenerGroup; +class ListenerViewModel; +/// Discriminator for what triggered a listener's actions. Not to be confused +/// with `rive::Event` (file/timeline event objects). +enum class ListenerInvocationKind : uint8_t +{ + pointer = 0, + keyboard = 1, + textInput = 2, + focus = 3, + reportedEvent = 4, + viewModelChange = 5, + none = 6, + gamepad = 7, + semantic = 8, +}; + +struct PointerInvocation +{ + Vec2D position{}; + Vec2D previousPosition{}; + int pointerId = 0; + ListenerType hitEvent = ListenerType::move; + float timeStamp = 0.f; +}; + +struct KeyboardInvocation +{ + Key key = Key::space; + KeyModifiers modifiers = KeyModifiers::none; + bool isPressed = false; + bool isRepeat = false; +}; + +/// IME / committed text. Owned so `ListenerInvocation` remains valid if +/// retained (e.g. scripted `Invocation` wrappers). +struct TextInputInvocation +{ + std::string text; +}; + +struct FocusInvocation +{ + FocusListenerGroup* group = nullptr; + bool isFocus = false; +}; + +/// A Rive file `Event` reported through the state machine (timeline, etc.). +struct ReportedEventInvocation +{ + Event* reportedEvent = nullptr; + float delaySeconds = 0.f; +}; + +struct ViewModelChangeInvocation +{ + ListenerViewModel* source = nullptr; +}; + +struct NoneInvocation +{}; + +struct GamepadInvocation +{ + int deviceId = 0; + uint64_t buttonMask = 0; + float axis0 = 0.f; +}; + +struct SemanticInvocation +{ + SemanticListenerGroup* group = nullptr; + SemanticActionType actionType{}; +}; + +using ListenerInvocationStorage = std::variant; + +/// Payload for a single run of listener actions (pointer, keyboard, reported +/// event, etc.). +class ListenerInvocation +{ +public: + static ListenerInvocation pointer(Vec2D position, + Vec2D previousPosition, + int pointerId, + ListenerType hitEvent, + float timeStamp); + static ListenerInvocation keyboard(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat); + static ListenerInvocation textInput(std::string text); + static ListenerInvocation focus(FocusListenerGroup* group, bool isFocus); + static ListenerInvocation reportedEvent(Event* reportedEvent, + float delaySeconds); + static ListenerInvocation viewModelChange(ListenerViewModel* source); + static ListenerInvocation none(); + static ListenerInvocation gamepad(int deviceId, + uint64_t buttonMask, + float axis0); + static ListenerInvocation semantic(SemanticListenerGroup* group, + SemanticActionType actionType); + + ListenerInvocationKind kind() const; + + const PointerInvocation* asPointer() const; + const KeyboardInvocation* asKeyboard() const; + const TextInputInvocation* asTextInput() const; + const FocusInvocation* asFocus() const; + const ReportedEventInvocation* asReportedEvent() const; + const ViewModelChangeInvocation* asViewModelChange() const; + const NoneInvocation* asNone() const; + const GamepadInvocation* asGamepad() const; + const SemanticInvocation* asSemantic() const; + + const ListenerInvocationStorage& storage() const { return m_storage; } + +private: + explicit ListenerInvocation(ListenerInvocationStorage&& storage) : + m_storage(std::move(storage)) + {} + + ListenerInvocationStorage m_storage; +}; + +inline ListenerInvocationKind ListenerInvocation::kind() const +{ + return std::visit( + [](const auto& alt) -> ListenerInvocationKind { + using T = std::decay_t; + if constexpr (std::is_same_v) + { + return ListenerInvocationKind::pointer; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::keyboard; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::textInput; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::focus; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::reportedEvent; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::viewModelChange; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::none; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::gamepad; + } + else if constexpr (std::is_same_v) + { + return ListenerInvocationKind::semantic; + } + else + { + return ListenerInvocationKind::none; + } + }, + m_storage); +} + +inline const PointerInvocation* ListenerInvocation::asPointer() const +{ + return std::get_if(&m_storage); +} + +inline const KeyboardInvocation* ListenerInvocation::asKeyboard() const +{ + return std::get_if(&m_storage); +} + +inline const TextInputInvocation* ListenerInvocation::asTextInput() const +{ + return std::get_if(&m_storage); +} + +inline const FocusInvocation* ListenerInvocation::asFocus() const +{ + return std::get_if(&m_storage); +} + +inline const ReportedEventInvocation* ListenerInvocation::asReportedEvent() + const +{ + return std::get_if(&m_storage); +} + +inline const ViewModelChangeInvocation* ListenerInvocation::asViewModelChange() + const +{ + return std::get_if(&m_storage); +} + +inline const NoneInvocation* ListenerInvocation::asNone() const +{ + return std::get_if(&m_storage); +} + +inline const GamepadInvocation* ListenerInvocation::asGamepad() const +{ + return std::get_if(&m_storage); +} + +inline const SemanticInvocation* ListenerInvocation::asSemantic() const +{ + return std::get_if(&m_storage); +} + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/listener_number_change.hpp b/thirdparty/rive/include/rive/animation/listener_number_change.hpp index 613d7d3c3..a10e74a94 100644 --- a/thirdparty/rive/include/rive/animation/listener_number_change.hpp +++ b/thirdparty/rive/include/rive/animation/listener_number_change.hpp @@ -11,8 +11,7 @@ class ListenerNumberChange : public ListenerNumberChangeBase bool validateInputType(const StateMachineInput* input) const override; bool validateNestedInputType(const NestedInput* input) const override; void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const override; + const ListenerInvocation& invocation) const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/listener_trigger_change.hpp b/thirdparty/rive/include/rive/animation/listener_trigger_change.hpp index 005f47275..a494fa78d 100644 --- a/thirdparty/rive/include/rive/animation/listener_trigger_change.hpp +++ b/thirdparty/rive/include/rive/animation/listener_trigger_change.hpp @@ -11,8 +11,7 @@ class ListenerTriggerChange : public ListenerTriggerChangeBase bool validateInputType(const StateMachineInput* input) const override; bool validateNestedInputType(const NestedInput* input) const override; void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const override; + const ListenerInvocation& invocation) const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/listener_types/listener_input_type.hpp b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type.hpp new file mode 100644 index 000000000..1d616f4ff --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_HPP_ +#include "rive/generated/animation/listener_types/listener_input_type_base.hpp" +#include +namespace rive +{ +class ListenerInputType : public ListenerInputTypeBase +{ +public: + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_event.hpp b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_event.hpp new file mode 100644 index 000000000..92c33617f --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_event.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_EVENT_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_EVENT_HPP_ +#include "rive/generated/animation/listener_types/listener_input_type_event_base.hpp" +#include +namespace rive +{ +class ListenerInputTypeEvent : public ListenerInputTypeEventBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_keyboard.hpp b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_keyboard.hpp new file mode 100644 index 000000000..88462fb38 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_keyboard.hpp @@ -0,0 +1,41 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_KEYBOARD_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_KEYBOARD_HPP_ + +#include "rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp" +#include "rive/input/focusable.hpp" + +#include + +namespace rive +{ +class KeyboardInput; +class StateMachineListener; + +class ListenerInputTypeKeyboard : public ListenerInputTypeKeyboardBase +{ +public: + size_t keyboardInputCount() const { return m_keyboardInputs.size(); } + const KeyboardInput* keyboardInput(size_t index) const; + void addKeyboardInput(KeyboardInput* input); + + static bool keyPhaseMatches(uint32_t keyPhase, + bool isPressed, + bool isRepeat); + static bool keyboardInputMatches(const KeyboardInput& input, + Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat); + static bool keyboardListenerConstraintsMet( + const StateMachineListener* listener, + Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat); + +private: + std::vector m_keyboardInputs; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_semantic.hpp b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_semantic.hpp new file mode 100644 index 000000000..edebb112f --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_semantic.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_SEMANTIC_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_SEMANTIC_HPP_ + +#include "rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp" + +#include + +namespace rive +{ +enum class SemanticActionType : uint8_t; + +class SemanticInput; +class StateMachineListener; + +class ListenerInputTypeSemantic : public ListenerInputTypeSemanticBase +{ +public: + size_t semanticInputCount() const { return m_semanticInputs.size(); } + const SemanticInput* semanticInput(size_t index) const; + void addSemanticInput(SemanticInput* input); + + /// True if [listener] should receive a semantic invocation for [action]. + /// Mirrors [ListenerInputTypeKeyboard::keyboardListenerConstraintsMet]: + /// a [ListenerInputTypeSemantic] with no [semanticInput] rows matches any + /// [action]. A base [ListenerInputType] whose value is + /// [ListenerType::semanticAction] (no typed subclass / no rows) also + /// matches any [action]. Otherwise at least one [SemanticInput] row must + /// match [action]. + static bool semanticListenerConstraintsMet( + const StateMachineListener* listener, + SemanticActionType action); + +private: + std::vector m_semanticInputs; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_text.hpp b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_text.hpp new file mode 100644 index 000000000..42ad8875a --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_text.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_TEXT_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_TEXT_HPP_ +#include "rive/generated/animation/listener_types/listener_input_type_text_base.hpp" +namespace rive +{ +class ListenerInputTypeText : public ListenerInputTypeTextBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_viewmodel.hpp b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_viewmodel.hpp new file mode 100644 index 000000000..045585183 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/listener_types/listener_input_type_viewmodel.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_VIEW_MODEL_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_VIEW_MODEL_HPP_ +#include "rive/generated/animation/listener_types/listener_input_type_viewmodel_base.hpp" +#include "rive/data_bind_path_referencer.hpp" +#include +namespace rive +{ +class ListenerInputTypeViewModel : public ListenerInputTypeViewModelBase, + public DataBindPathReferencer +{ +public: + void decodeViewModelPathIds(Span value) override; + void copyViewModelPathIds( + const ListenerInputTypeViewModelBase& object) override; + std::vector viewModelPathIdsBuffer() const; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/listener_viewmodel_change.hpp b/thirdparty/rive/include/rive/animation/listener_viewmodel_change.hpp index a58ef49bd..e823d1c85 100644 --- a/thirdparty/rive/include/rive/animation/listener_viewmodel_change.hpp +++ b/thirdparty/rive/include/rive/animation/listener_viewmodel_change.hpp @@ -10,8 +10,7 @@ class ListenerViewModelChange : public ListenerViewModelChangeBase public: ~ListenerViewModelChange(); void perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const override; + const ListenerInvocation& invocation) const override; StatusCode import(ImportStack& importStack) override; private: diff --git a/thirdparty/rive/include/rive/animation/nested_linear_animation.hpp b/thirdparty/rive/include/rive/animation/nested_linear_animation.hpp index 0864e2b48..5099b26f3 100644 --- a/thirdparty/rive/include/rive/animation/nested_linear_animation.hpp +++ b/thirdparty/rive/include/rive/animation/nested_linear_animation.hpp @@ -15,6 +15,7 @@ class NestedLinearAnimation : public NestedLinearAnimationBase ~NestedLinearAnimation() override; void initializeAnimation(ArtboardInstance*) override; + void releaseDependencies() override {} LinearAnimationInstance* animationInstance() { return m_AnimationInstance.get(); diff --git a/thirdparty/rive/include/rive/animation/nested_state_machine.hpp b/thirdparty/rive/include/rive/animation/nested_state_machine.hpp index 339fedef1..fcde3c1f2 100644 --- a/thirdparty/rive/include/rive/animation/nested_state_machine.hpp +++ b/thirdparty/rive/include/rive/animation/nested_state_machine.hpp @@ -24,10 +24,14 @@ class NestedStateMachine : public NestedStateMachineBase void initializeAnimation(ArtboardInstance*) override; StateMachineInstance* stateMachineInstance(); - HitResult pointerMove(Vec2D position); - HitResult pointerDown(Vec2D position); - HitResult pointerUp(Vec2D position); - HitResult pointerExit(Vec2D position); + HitResult pointerMove(Vec2D position, + float timeStamp = 0, + int pointerId = 0); + HitResult pointerDown(Vec2D position, int pointerId = 0); + HitResult pointerUp(Vec2D position, int pointerId = 0); + HitResult pointerExit(Vec2D position, int pointerId = 0); + HitResult dragStart(Vec2D position, float timeStamp = 0, int pointerId = 0); + HitResult dragEnd(Vec2D position, float timeStamp = 0, int pointerId = 0); bool tryChangeState(); bool hitTest(Vec2D position) const; @@ -36,7 +40,12 @@ class NestedStateMachine : public NestedStateMachineBase NestedInput* input(size_t index); NestedInput* input(std::string name); void bindViewModelInstance(rcp viewModelInstance); - void dataContext(DataContext* dataContext); + void dataContext(rcp dataContext); + void releaseDependencies() override + { + m_StateMachineInstance.reset(nullptr); + } + void clearDataContext(); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/scripted_listener_action.hpp b/thirdparty/rive/include/rive/animation/scripted_listener_action.hpp new file mode 100644 index 000000000..0a145aead --- /dev/null +++ b/thirdparty/rive/include/rive/animation/scripted_listener_action.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_SCRIPTED_LISTENER_ACTION_HPP_ +#define _RIVE_SCRIPTED_LISTENER_ACTION_HPP_ +#include "rive/generated/animation/scripted_listener_action_base.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptedListenerAction : public ScriptedListenerActionBase, + public ScriptedObject +{ +public: + ~ScriptedListenerAction(); + virtual void disposeScriptInputs() override; + void perform(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const override; + void performStateful(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const; + + uint32_t assetId() override { return scriptAssetId(); } + bool addScriptedDirt(ComponentDirt value, bool recurse = false) override + { + return false; + } + ScriptProtocol scriptProtocol() override + { + return ScriptProtocol::listenerAction; + } + Component* component() override { return nullptr; } + StatusCode import(ImportStack& importStack) override; + Core* clone() const override; + ScriptedObject* cloneScriptedObject(DataBindContainer*) const override; + void addProperty(CustomProperty* prop) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/scripted_transition_condition.hpp b/thirdparty/rive/include/rive/animation/scripted_transition_condition.hpp new file mode 100644 index 000000000..f955987a7 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/scripted_transition_condition.hpp @@ -0,0 +1,35 @@ +#ifndef _RIVE_SCRIPTED_TRANSITION_CONDITION_HPP_ +#define _RIVE_SCRIPTED_TRANSITION_CONDITION_HPP_ +#include "rive/generated/animation/scripted_transition_condition_base.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptedTransitionCondition : public ScriptedTransitionConditionBase, + public ScriptedObject +{ +public: + ~ScriptedTransitionCondition(); + virtual void disposeScriptInputs() override; + bool evaluate(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) const override; + bool evaluateStateful(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) const; + uint32_t assetId() override { return scriptAssetId(); } + bool addScriptedDirt(ComponentDirt value, bool recurse = false) override + { + return false; + } + ScriptProtocol scriptProtocol() override + { + return ScriptProtocol::transitionCondition; + } + Component* component() override { return nullptr; } + StatusCode import(ImportStack& importStack) override; + Core* clone() const override; + ScriptedObject* cloneScriptedObject(DataBindContainer*) const override; + void addProperty(CustomProperty* prop) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/semantic_listener_group.hpp b/thirdparty/rive/include/rive/animation/semantic_listener_group.hpp new file mode 100644 index 000000000..92a30671a --- /dev/null +++ b/thirdparty/rive/include/rive/animation/semantic_listener_group.hpp @@ -0,0 +1,50 @@ +#ifndef _RIVE_SEMANTIC_LISTENER_GROUP_HPP_ +#define _RIVE_SEMANTIC_LISTENER_GROUP_HPP_ + +#include "rive/semantic/semantic_listener.hpp" +#include "rive/listener_type.hpp" + +#include + +namespace rive +{ +class SemanticData; +class StateMachineListener; +class StateMachineInstance; + +enum class SemanticActionType : uint8_t +{ + tap = 0, + increase = 1, + decrease = 2, +}; + +/// A SemanticListenerGroup manages semantic action listeners attached +/// to a SemanticData. When semantic actions (tap, increase, decrease) are +/// fired, the listener's actions are queued for deferred execution. +class SemanticListenerGroup : public SemanticListener +{ +public: + SemanticListenerGroup(SemanticData* semanticData, + const StateMachineListener* listener, + StateMachineInstance* stateMachineInstance); + ~SemanticListenerGroup() override; + + const StateMachineListener* listener() const { return m_listener; } + SemanticData* semanticData() const { return m_semanticData; } + + void onSemanticTap() override; + void onSemanticIncrease() override; + void onSemanticDecrease() override; + +private: + void queueIfListening(SemanticActionType actionType); + + SemanticData* m_semanticData; + const StateMachineListener* m_listener; + StateMachineInstance* m_stateMachineInstance; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/state_machine.hpp b/thirdparty/rive/include/rive/animation/state_machine.hpp index 258fe6126..ff441caa7 100644 --- a/thirdparty/rive/include/rive/animation/state_machine.hpp +++ b/thirdparty/rive/include/rive/animation/state_machine.hpp @@ -10,6 +10,7 @@ class StateMachineLayer; class StateMachineInput; class StateMachineListener; class StateMachineImporter; +class ScriptedObject; class DataBind; class StateMachine : public StateMachineBase { @@ -20,6 +21,7 @@ class StateMachine : public StateMachineBase std::vector> m_Inputs; std::vector> m_Listeners; std::vector> m_dataBinds; + std::vector m_scriptedObjects; void addLayer(std::unique_ptr); void addInput(std::unique_ptr); @@ -36,6 +38,11 @@ class StateMachine : public StateMachineBase size_t inputCount() const { return m_Inputs.size(); } size_t listenerCount() const { return m_Listeners.size(); } size_t dataBindCount() const { return m_dataBinds.size(); } + void addScriptedObject(ScriptedObject* object); + std::vector scriptedObjects() const + { + return m_scriptedObjects; + } const StateMachineInput* input(std::string name) const; const StateMachineInput* input(size_t index) const; diff --git a/thirdparty/rive/include/rive/animation/state_machine_fire_action.hpp b/thirdparty/rive/include/rive/animation/state_machine_fire_action.hpp new file mode 100644 index 000000000..35fb47723 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/state_machine_fire_action.hpp @@ -0,0 +1,25 @@ +#ifndef _RIVE_STATE_MACHINE_FIRE_ACTION_HPP_ +#define _RIVE_STATE_MACHINE_FIRE_ACTION_HPP_ +#include "rive/generated/animation/state_machine_fire_action_base.hpp" +#include +namespace rive +{ +class StateMachineInstance; +enum class StateMachineFireOccurance : int +{ + atStart = 0, + atEnd = 1 +}; +class StateMachineFireAction : public StateMachineFireActionBase +{ +public: + StateMachineFireOccurance occurs() const + { + return (StateMachineFireOccurance)occursValue(); + } + StatusCode import(ImportStack& importStack) override; + virtual void perform(StateMachineInstance* stateMachineInstance) const = 0; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/state_machine_fire_event.hpp b/thirdparty/rive/include/rive/animation/state_machine_fire_event.hpp index 9927cfdb4..86173edf0 100644 --- a/thirdparty/rive/include/rive/animation/state_machine_fire_event.hpp +++ b/thirdparty/rive/include/rive/animation/state_machine_fire_event.hpp @@ -4,22 +4,11 @@ namespace rive { -class StateMachineInstance; -enum class StateMachineFireOccurance : int -{ - atStart = 0, - atEnd = 1 -}; class StateMachineFireEvent : public StateMachineFireEventBase { public: - StatusCode import(ImportStack& importStack) override; - StateMachineFireOccurance occurs() const - { - return (StateMachineFireOccurance)occursValue(); - } - void perform(StateMachineInstance* stateMachineInstance) const; + void perform(StateMachineInstance* stateMachineInstance) const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/state_machine_fire_trigger.hpp b/thirdparty/rive/include/rive/animation/state_machine_fire_trigger.hpp new file mode 100644 index 000000000..76f7e7f09 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/state_machine_fire_trigger.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_STATE_MACHINE_FIRE_TRIGGER_HPP_ +#define _RIVE_STATE_MACHINE_FIRE_TRIGGER_HPP_ +#include "rive/generated/animation/state_machine_fire_trigger_base.hpp" +#include "rive/data_bind_path_referencer.hpp" +#include +namespace rive +{ +class StateMachineFireTrigger : public StateMachineFireTriggerBase, + public DataBindPathReferencer +{ +public: + void perform(StateMachineInstance* stateMachineInstance) const override; + void decodeViewModelPathIds(Span value) override; + void copyViewModelPathIds( + const StateMachineFireTriggerBase& object) override; + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/state_machine_instance.hpp b/thirdparty/rive/include/rive/animation/state_machine_instance.hpp index 290674ba3..8e6b6fbea 100644 --- a/thirdparty/rive/include/rive/animation/state_machine_instance.hpp +++ b/thirdparty/rive/include/rive/animation/state_machine_instance.hpp @@ -5,6 +5,8 @@ #include #include #include +#include "rive/animation/keyboard_listener_group.hpp" +#include "rive/animation/semantic_listener_group.hpp" #include "rive/animation/linear_animation_instance.hpp" #include "rive/animation/state_instance.hpp" #include "rive/animation/state_transition.hpp" @@ -13,9 +15,16 @@ #include "rive/listener_type.hpp" #include "rive/nested_animation.hpp" #include "rive/scene.hpp" +#include "rive/data_bind/bindable_property_number.hpp" +#include "rive/data_bind/data_bind_container.hpp" +#include "rive/input/focusable.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/semantic/semantic_manager.hpp" namespace rive { +class FocusData; +class FocusListenerGroup; class StateMachine; class LayerState; class SMIInput; @@ -37,6 +46,9 @@ class EventReport; class DataBind; class BindableProperty; class HitDrawable; +class ListenerViewModel; +class ScriptedListenerAction; +typedef void (*DataBindChanged)(); #ifdef WITH_RIVE_TOOLS class StateMachineInstance; @@ -45,7 +57,8 @@ typedef void (*InputChanged)(StateMachineInstance*, uint64_t); class StateMachineInstance : public Scene, public NestedEventNotifier, - public NestedEventListener + public NestedEventListener, + public DataBindContainer { friend class SMIInput; friend class KeyedProperty; @@ -55,7 +68,10 @@ class StateMachineInstance : public Scene, private: /// Provide a hitListener if you want to process a down or an up for the /// pointer position too. - HitResult updateListeners(Vec2D position, ListenerType hitListener); + HitResult updateListeners(Vec2D position, + ListenerType hitListener, + int pointerId = 0, + float timeStamp = 0); template InstType* getNamedInput(const std::string& name) const; @@ -70,8 +86,7 @@ class StateMachineInstance : public Scene, StateInstance* stateFromInstance, StateMachineLayerInstance* layerInstance); - bool m_ownsDataContext = false; - DataContext* m_DataContext = nullptr; + rcp m_DataContext = nullptr; void addToHitLookup(Component* target, bool isLayoutComponent, std::unordered_map& hitLookup, @@ -94,6 +109,8 @@ class StateMachineInstance : public Scene, // Returns true when the StateMachineInstance has more data to process. bool needsAdvance() const; + void resetState(); + // Returns a pointer to the instance's stateMachine const StateMachine* stateMachine() const { return m_machine; } @@ -104,7 +121,10 @@ class StateMachineInstance : public Scene, SMITrigger* getTrigger(const std::string& name) const override; void bindViewModelInstance( rcp viewModelInstance) override; - void dataContext(DataContext* dataContext); + void bindDataContext(rcp dataContext); + void dataContext(rcp dataContext); + rcp dataContext() const { return m_DataContext; } + void rebind() override; size_t currentAnimationCount() const; const LinearAnimationInstance* currentAnimationByIndex(size_t index) const; @@ -120,11 +140,20 @@ class StateMachineInstance : public Scene, bool advanceAndApply(float secs) override; void advancedDataContext(); + void reset(); std::string name() const override; - HitResult pointerMove(Vec2D position) override; - HitResult pointerDown(Vec2D position) override; - HitResult pointerUp(Vec2D position) override; - HitResult pointerExit(Vec2D position) override; + HitResult pointerMove(Vec2D position, + float timeStamp = 0, + int pointerId = 0) override; + HitResult pointerDown(Vec2D position, int pointerId = 0) override; + HitResult pointerUp(Vec2D position, int pointerId = 0) override; + HitResult pointerExit(Vec2D position, int pointerId = 0) override; + HitResult dragStart(Vec2D position, + float timeStamp = 0, + bool disablePointer = true, + int pointerId = 0); + HitResult dragEnd(Vec2D position, float timeStamp = 0, int pointerId = 0); + bool tryChangeState(); bool hitTest(Vec2D position) const; @@ -152,11 +181,17 @@ class StateMachineInstance : public Scene, NestedArtboard* parentNestedArtboard() { return m_parentNestedArtboard; } void notify(const std::vector& events, NestedArtboard* context) override; + void notifyListenerViewModels( + const std::vector& events); /// Tracks an event that reported, will be cleared at the end of the next /// advance. void reportEvent(Event* event, float secondsDelay = 0.0f) override; + void applyEvents(); + + void reportListenerViewModel(ListenerViewModel*); + /// Gets the number of events that reported since the last advance. std::size_t reportedEventCount() const; @@ -169,7 +204,81 @@ class StateMachineInstance : public Scene, BindableProperty* bindableProperty) const; DataBind* bindableDataBindToTarget( BindableProperty* bindableProperty) const; + + /// Find the per-instance BindablePropertyNumber for the given shared + /// StateTransition and property key (e.g. durationPropertyKey). + /// Returns nullptr if no binding exists. + BindablePropertyNumber* findTransitionPropertyInstance( + const StateTransition* transition, + uint32_t propertyKey) const; bool hasListeners() { return m_hitComponents.size() > 0; } + void clearDataContext(); + void relinkDataContext() override; + void rebuildDataBind(DataBind*) override; + void internalDataContext(rcp dataContext); + ScriptedObject* scriptedObject(const ScriptedObject*) const; + + /// Queue a focus event for deferred execution during advance(). + void queueFocusEvent(FocusListenerGroup* group, bool isFocus); + + /// Queue a semantic event for deferred execution during advance(). + void queueSemanticEvent(SemanticListenerGroup* group, + SemanticActionType actionType); + + /// Fire a semantic action on the SemanticData with the given node ID. + void fireSemanticAction(uint32_t semanticNodeId, + SemanticActionType actionType); + + /// Get the focus manager for this state machine instance. + /// Returns the external focus manager if set, otherwise the internal one. + FocusManager* focusManager() + { + return m_externalFocusManager ? m_externalFocusManager + : &m_focusManager; + } + + /// Check if this state machine is using an external focus manager. + bool hasExternalFocusManager() const + { + return m_externalFocusManager != nullptr; + } + + /// Get the internal focus manager (always owned by this + /// StateMachineInstance). Useful when you need to operate only on the + /// internal manager regardless of whether an external one is set. + FocusManager* internalFocusManager() { return &m_focusManager; } + + /// Set an external focus manager to use instead of the internal one. + /// This is used when a nested artboard should share focus with its parent. + /// If the focus tree was already built with a different manager, it will + /// be rebuilt with the new manager. + void setExternalFocusManager(FocusManager* manager); + + /// Set focus to a specific FocusData's node. + void setFocus(FocusData* focusData); + + /// Get the semantic manager for this state machine instance. + /// Returns the external manager if set, otherwise the internal one. + /// Returns nullptr if semantics has not been enabled. + SemanticManager* semanticManager() const + { + return m_externalSemanticManager ? m_externalSemanticManager + : m_semanticManager.get(); + } + + /// Enable semantics for this state machine instance. Creates the + /// internal SemanticManager (if no external one was set) and builds + /// the semantic tree. This is a no-op if semantics is already enabled. + void enableSemantics(); + + /// Set an external semantic manager to use instead of the internal one. + /// Used when a nested artboard should share the parent's semantic tree. + /// Rebuilds the semantic tree with the new manager if already built. + /// @param parentNode If provided, the rebuilt tree is attached under it; + /// nullptr attaches at the manager root. + void setExternalSemanticManager(SemanticManager* manager, + rcp parentNode = nullptr); + #ifdef TESTING size_t hitComponentsCount() { return m_hitComponents.size(); }; HitComponent* hitComponent(size_t index) @@ -182,10 +291,13 @@ class StateMachineInstance : public Scene, } const LayerState* layerState(size_t index); #endif - void updateDataBinds(); + void enablePointerEvents(int pointerId = 0); + void disablePointerEvents(int pointerId = 0); + void dispose(); private: std::vector m_reportedEvents; + std::vector m_reportingEvents; const StateMachine* m_machine; bool m_needsAdvance = false; std::vector m_inputInstances; // we own each pointer @@ -196,15 +308,58 @@ class StateMachineInstance : public Scene, StateMachineInstance* m_parentStateMachineInstance = nullptr; NestedArtboard* m_parentNestedArtboard = nullptr; std::vector m_dataBinds; + std::vector m_listenerViewModels; + std::vector m_reportedListenerViewModels; + std::vector m_reportingListenerViewModels; std::unordered_map m_bindablePropertyInstances; + std::unordered_map + m_scriptedObjectsMap; std::unordered_map m_bindableDataBindsToTarget; std::unordered_map m_bindableDataBindsToSource; + /// Map from shared StateTransition* to per-instance BindablePropertyNumber + /// instances, keyed by original property key. Data binds write to these + /// instead of the shared StateTransition object. + std::unordered_map> + m_transitionPropertyInstances; uint8_t m_drawOrderChangeCounter = 0; - void internalDataContext(DataContext* dataContext); - void clearDataContext(); + void unbind(); + void removeEventListeners(); + void initScriptedObjects(); + + // Focus management + FocusManager m_focusManager; + FocusManager* m_externalFocusManager = nullptr; + std::vector> m_focusListenerGroups; + std::vector> + m_keyboardListenerGroups; + + // Semantic management + std::unique_ptr m_semanticManager; + SemanticManager* m_externalSemanticManager = nullptr; + + // Queued focus events for deferred processing + struct QueuedFocusEvent + { + FocusListenerGroup* group; + bool isFocus; + }; + std::vector m_queuedFocusEvents; + void processFocusEvents(); + + // Semantic listener groups and queued events + std::vector> + m_semanticListenerGroups; + struct QueuedSemanticEvent + { + SemanticListenerGroup* group; + SemanticActionType actionType; + }; + std::vector m_queuedSemanticEvents; + void processSemanticEvents(); #ifdef WITH_RIVE_TOOLS public: @@ -228,9 +383,15 @@ class HitComponent virtual ~HitComponent() {} virtual HitResult processEvent(Vec2D position, ListenerType hitType, - bool canHit) = 0; - virtual void prepareEvent(Vec2D position, ListenerType hitType) = 0; + bool canHit, + float timeStamp = 0, + int pointerId = 0) = 0; + virtual void prepareEvent(Vec2D position, + ListenerType hitType, + int pointerId) = 0; virtual bool hitTest(Vec2D position) const = 0; + virtual void enablePointerEvents(int pointerId = 0) {} + virtual void disablePointerEvents(int pointerId = 0) {} #ifdef TESTING int earlyOutCount = 0; #endif diff --git a/thirdparty/rive/include/rive/animation/state_machine_layer.hpp b/thirdparty/rive/include/rive/animation/state_machine_layer.hpp index 74ba7e34e..63d01754c 100644 --- a/thirdparty/rive/include/rive/animation/state_machine_layer.hpp +++ b/thirdparty/rive/include/rive/animation/state_machine_layer.hpp @@ -34,7 +34,6 @@ class StateMachineLayer : public StateMachineLayerBase const EntryState* entryState() const { return m_Entry; } const ExitState* exitState() const { return m_Exit; } -#ifdef TESTING size_t stateCount() const { return m_States.size(); } LayerState* state(size_t index) const { @@ -44,7 +43,6 @@ class StateMachineLayer : public StateMachineLayerBase } return nullptr; } -#endif }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/state_machine_layer_component.hpp b/thirdparty/rive/include/rive/animation/state_machine_layer_component.hpp index d94266df6..0b0d624a4 100644 --- a/thirdparty/rive/include/rive/animation/state_machine_layer_component.hpp +++ b/thirdparty/rive/include/rive/animation/state_machine_layer_component.hpp @@ -1,24 +1,31 @@ #ifndef _RIVE_STATE_MACHINE_LAYER_COMPONENT_HPP_ #define _RIVE_STATE_MACHINE_LAYER_COMPONENT_HPP_ +#include "rive/animation/listener_action.hpp" #include "rive/generated/animation/state_machine_layer_component_base.hpp" +#include #include namespace rive { -class StateMachineFireEvent; +class StateMachineFireAction; class StateMachineLayerComponent : public StateMachineLayerComponentBase { friend class StateMachineLayerComponentImporter; public: - const std::vector& events() const + const std::vector& events() const { return m_events; } + const std::vector>& listenerActions() const + { + return m_listenerActions; + } ~StateMachineLayerComponent() override; private: - std::vector m_events; + std::vector m_events; + std::vector> m_listenerActions; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/state_machine_listener.hpp b/thirdparty/rive/include/rive/animation/state_machine_listener.hpp index 051bc7a0d..44d41cbf5 100644 --- a/thirdparty/rive/include/rive/animation/state_machine_listener.hpp +++ b/thirdparty/rive/include/rive/animation/state_machine_listener.hpp @@ -1,8 +1,10 @@ #ifndef _RIVE_STATE_MACHINE_LISTENER_HPP_ #define _RIVE_STATE_MACHINE_LISTENER_HPP_ +#include "rive/animation/listener_invocation.hpp" #include "rive/generated/animation/state_machine_listener_base.hpp" #include "rive/listener_type.hpp" -#include "rive/math/vec2d.hpp" +#include "rive/span.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" namespace rive { @@ -18,22 +20,30 @@ class StateMachineListener : public StateMachineListenerBase StateMachineListener(); ~StateMachineListener() override; - ListenerType listenerType() const + // ListenerType listenerType() const + // { + // return (ListenerType)listenerTypeValue(); + // } + virtual bool hasListener(ListenerType) const; + bool hasListeners(Span listenerTypes) const; + size_t actionCount() const { return m_actions.size(); } + size_t listenerInputTypeCount() const { - return (ListenerType)listenerTypeValue(); + return m_listenerInputTypes.size(); } - size_t actionCount() const { return m_actions.size(); } const ListenerAction* action(size_t index) const; + const ListenerInputType* listenerInputType(size_t index) const; StatusCode import(ImportStack& importStack) override; void performChanges(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const; + const ListenerInvocation& invocation) const; private: void addAction(std::unique_ptr); + void addListenerInputType(std::unique_ptr); std::vector> m_actions; + std::vector> m_listenerInputTypes; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/state_machine_listener_single.hpp b/thirdparty/rive/include/rive/animation/state_machine_listener_single.hpp new file mode 100644 index 000000000..f972e0229 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/state_machine_listener_single.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_STATE_MACHINE_LISTENER_SINGLE_HPP_ +#define _RIVE_STATE_MACHINE_LISTENER_SINGLE_HPP_ +#include "rive/generated/animation/state_machine_listener_single_base.hpp" +#include "rive/data_bind_path_referencer.hpp" +namespace rive +{ +class StateMachineListenerSingle : public StateMachineListenerSingleBase, + public DataBindPathReferencer +{ +public: + StatusCode import(ImportStack& importStack) override; + bool hasListener(ListenerType listenerType) const override + { + return listenerTypeValue() == (int)listenerType; + } + void decodeViewModelPathIds(Span value) override; + void copyViewModelPathIds( + const StateMachineListenerSingleBase& object) override; + std::vector viewModelPathIdsBuffer() const; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/state_transition.hpp b/thirdparty/rive/include/rive/animation/state_transition.hpp index 79b9fff5b..1be85e0cb 100644 --- a/thirdparty/rive/include/rive/animation/state_transition.hpp +++ b/thirdparty/rive/include/rive/animation/state_transition.hpp @@ -96,6 +96,13 @@ class StateTransition : public StateTransitionBase StateTransitionFlags::EnableEarlyExit; } + bool durationIsPercentage() const + { + return (transitionFlags() & + StateTransitionFlags::DurationIsPercentage) == + StateTransitionFlags::DurationIsPercentage; + } + StatusCode import(ImportStack& importStack) override; size_t conditionCount() const { return m_Conditions.size(); } diff --git a/thirdparty/rive/include/rive/animation/text_input_listener_group.hpp b/thirdparty/rive/include/rive/animation/text_input_listener_group.hpp new file mode 100644 index 000000000..4a15c632c --- /dev/null +++ b/thirdparty/rive/include/rive/animation/text_input_listener_group.hpp @@ -0,0 +1,40 @@ +#ifndef _RIVE_TEXT_INPUT_LISTENER_GROUP_HPP_ +#define _RIVE_TEXT_INPUT_LISTENER_GROUP_HPP_ + +#include "rive/listener_group.hpp" + +namespace rive +{ +class TextInput; +class StateMachineInstance; + +/// A TextInputListenerGroup handles pointer events on TextInput components, +/// managing drag-to-select text behavior. +class TextInputListenerGroup : public ListenerGroup +{ +public: + TextInputListenerGroup(TextInput* textInput, + StateMachineInstance* stateMachineInstance); + ~TextInputListenerGroup() override = default; + + bool canEarlyOut(Component* drawable) override { return false; } + bool needsDownListener(Component* drawable) override { return true; } + bool needsUpListener(Component* drawable) override { return true; } + + ProcessEventResult processEvent( + Component* component, + Vec2D position, + int pointerId, + ListenerType hitEvent, + bool canHit, + float timeStamp, + StateMachineInstance* stateMachineInstance) override; + +private: + TextInput* m_textInput; + bool m_isDragging = false; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/animation/transition_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_comparator.hpp index b791373b6..ff9b7e181 100644 --- a/thirdparty/rive/include/rive/animation/transition_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_comparator.hpp @@ -13,27 +13,9 @@ class TransitionComparator : public TransitionComparatorBase { public: StatusCode import(ImportStack& importStack) override; - virtual bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance); virtual void useInLayer(const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) const - {} - -protected: - bool compareNumbers(float left, float right, TransitionConditionOp op); - bool compareBooleans(bool left, bool right, TransitionConditionOp op); - bool compareEnums(uint16_t left, uint16_t right, TransitionConditionOp op); - bool compareColors(int left, int right, TransitionConditionOp op); - bool compareStrings(std::string left, - std::string right, - TransitionConditionOp op); - bool compareTriggers(uint32_t left, - uint32_t right, - TransitionConditionOp op); + StateMachineLayerInstance* layerInstance) const {}; }; } // namespace rive - #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_property_artboard_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_property_artboard_comparator.hpp index 448f498d9..9efd06e65 100644 --- a/thirdparty/rive/include/rive/animation/transition_property_artboard_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_property_artboard_comparator.hpp @@ -7,16 +7,7 @@ namespace rive class Artboard; class TransitionPropertyArtboardComparator : public TransitionPropertyArtboardComparatorBase -{ -public: - bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) override; - -private: - float propertyValue(const StateMachineInstance* stateMachineInstance); -}; +{}; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_property_component_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_property_component_comparator.hpp new file mode 100644 index 000000000..b0b3c3907 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/transition_property_component_comparator.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_COMPONENT_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_PROPERTY_COMPONENT_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_property_component_comparator_base.hpp" +namespace rive +{ +class TransitionPropertyComponentComparator + : public TransitionPropertyComponentComparatorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_property_viewmodel_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_property_viewmodel_comparator.hpp index 87fe6d1cd..0043c50bb 100644 --- a/thirdparty/rive/include/rive/animation/transition_property_viewmodel_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_property_viewmodel_comparator.hpp @@ -12,10 +12,6 @@ class TransitionPropertyViewModelComparator public: ~TransitionPropertyViewModelComparator(); StatusCode import(ImportStack& importStack) override; - bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) override; template U value(const StateMachineInstance* stateMachineInstance) { @@ -31,13 +27,12 @@ class TransitionPropertyViewModelComparator } return T::defaultValue; }; - float valueToFloat(const StateMachineInstance* stateMachineInstance); void useInLayer(const StateMachineInstance* stateMachineInstance, StateMachineLayerInstance* layerInstance) const override; - DataType instanceDataType(const StateMachineInstance* stateMachineInstance); + BindableProperty* bindableProperty() { return m_bindableProperty; } protected: - BindableProperty* m_bindableProperty; + BindableProperty* m_bindableProperty = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/animation/transition_self_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_self_comparator.hpp new file mode 100644 index 000000000..860d76881 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/transition_self_comparator.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_TRANSITION_SELF_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_SELF_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_self_comparator_base.hpp" +#include +namespace rive +{ +class TransitionSelfComparator : public TransitionSelfComparatorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_artboard_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_artboard_comparator.hpp new file mode 100644 index 000000000..ea3e03add --- /dev/null +++ b/thirdparty/rive/include/rive/animation/transition_value_artboard_comparator.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_TRANSITION_VALUE_ARTBOARD_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_ARTBOARD_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_artboard_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueArtboardComparator + : public TransitionValueArtboardComparatorBase +{}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_asset_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_asset_comparator.hpp new file mode 100644 index 000000000..c9dd516e9 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/transition_value_asset_comparator.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_TRANSITION_VALUE_ASSET_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_ASSET_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_asset_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueAssetComparator : public TransitionValueAssetComparatorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_boolean_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_boolean_comparator.hpp index 9bc9f5dd7..1ccaf321a 100644 --- a/thirdparty/rive/include/rive/animation/transition_value_boolean_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_value_boolean_comparator.hpp @@ -6,13 +6,7 @@ namespace rive { class TransitionValueBooleanComparator : public TransitionValueBooleanComparatorBase -{ -public: - bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) override; -}; +{}; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_color_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_color_comparator.hpp index 389979f2b..3f4c46d1d 100644 --- a/thirdparty/rive/include/rive/animation/transition_value_color_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_value_color_comparator.hpp @@ -5,13 +5,7 @@ namespace rive { class TransitionValueColorComparator : public TransitionValueColorComparatorBase -{ -public: - bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) override; -}; +{}; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_id_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_id_comparator.hpp new file mode 100644 index 000000000..f4bd07fb5 --- /dev/null +++ b/thirdparty/rive/include/rive/animation/transition_value_id_comparator.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_TRANSITION_VALUE_ID_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_ID_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_id_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueIdComparator : public TransitionValueIdComparatorBase +{}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_number_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_number_comparator.hpp index 649768ff6..a752e3042 100644 --- a/thirdparty/rive/include/rive/animation/transition_value_number_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_value_number_comparator.hpp @@ -6,13 +6,7 @@ namespace rive { class TransitionValueNumberComparator : public TransitionValueNumberComparatorBase -{ -public: - bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) override; -}; +{}; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_value_string_comparator.hpp b/thirdparty/rive/include/rive/animation/transition_value_string_comparator.hpp index 4288c7e27..8b647e1b6 100644 --- a/thirdparty/rive/include/rive/animation/transition_value_string_comparator.hpp +++ b/thirdparty/rive/include/rive/animation/transition_value_string_comparator.hpp @@ -6,13 +6,7 @@ namespace rive { class TransitionValueStringComparator : public TransitionValueStringComparatorBase -{ -public: - bool compare(TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) override; -}; +{}; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/animation/transition_viewmodel_condition.hpp b/thirdparty/rive/include/rive/animation/transition_viewmodel_condition.hpp index 889140735..7d030fd3a 100644 --- a/thirdparty/rive/include/rive/animation/transition_viewmodel_condition.hpp +++ b/thirdparty/rive/include/rive/animation/transition_viewmodel_condition.hpp @@ -2,16 +2,725 @@ #define _RIVE_TRANSITION_VIEW_MODEL_CONDITION_HPP_ #include "rive/generated/animation/transition_viewmodel_condition_base.hpp" #include "rive/animation/transition_comparator.hpp" +#include "rive/animation/transition_property_artboard_comparator.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/animation/transition_condition_op.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_artboard.hpp" +#include "rive/data_bind/bindable_property_asset.hpp" +#include "rive/data_bind/bindable_property_boolean.hpp" +#include "rive/data_bind/bindable_property_color.hpp" +#include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_integer.hpp" +#include "rive/data_bind/bindable_property_number.hpp" +#include "rive/data_bind/bindable_property_string.hpp" +#include "rive/data_bind/bindable_property_trigger.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/animation/transition_self_comparator.hpp" +#include "rive/animation/transition_value_artboard_comparator.hpp" +#include "rive/animation/transition_value_asset_comparator.hpp" +#include "rive/animation/transition_value_number_comparator.hpp" +#include "rive/animation/transition_value_boolean_comparator.hpp" +#include "rive/animation/transition_value_string_comparator.hpp" +#include "rive/animation/transition_value_color_comparator.hpp" +#include "rive/animation/transition_value_enum_comparator.hpp" +#include "rive/animation/transition_value_trigger_comparator.hpp" +#include "rive/animation/artboard_property.hpp" +#include #include namespace rive { + +class TransitionPropertyComponentComparator; + +class ConditionOperation +{ +public: + virtual ~ConditionOperation() {} + virtual bool compareNumbers(float a, float b) { return false; }; + virtual bool compareBooleans(bool a, bool b) { return false; } + virtual bool compareStrings(const std::string& a, const std::string& b) + { + return false; + } + virtual bool compareInts(int a, int b) { return false; } + virtual bool compareUints32(uint32_t a, uint32_t b) { return false; } + +protected: + template bool equal(T left, T right) { return left == right; } + template bool notEqual(T left, T right) + { + return left != right; + } + template bool lessThanOrEqual(T left, T right) + { + return left <= right; + } + template bool lessThan(T left, T right) + { + return left < right; + } + template bool greaterThanOrEqual(T left, T right) + { + return left >= right; + } + template bool greaterThan(T left, T right) + { + return left > right; + } +}; +class ConditionOperationEqual : public ConditionOperation +{ +public: + bool compareNumbers(float a, float b) override + { + return equal(a, b); + } + bool compareBooleans(bool a, bool b) override { return equal(a, b); } + bool compareStrings(const std::string& a, const std::string& b) override + { + return equal(a, b); + } + bool compareInts(int a, int b) override { return equal(a, b); } + bool compareUints32(uint32_t a, uint32_t b) override + { + return equal(a, b); + } +}; +class ConditionOperationNotEqual : public ConditionOperation +{ +public: + bool compareNumbers(float a, float b) override + { + return notEqual(a, b); + } + bool compareBooleans(bool a, bool b) override + { + return notEqual(a, b); + } + bool compareStrings(const std::string& a, const std::string& b) override + { + return notEqual(a, b); + } + bool compareInts(int a, int b) override { return notEqual(a, b); } + bool compareUints32(uint32_t a, uint32_t b) override + { + return notEqual(a, b); + } +}; +class ConditionOperationLessThanOrEqual : public ConditionOperation +{ +public: + bool compareNumbers(float a, float b) override + { + return lessThanOrEqual(a, b); + } +}; +class ConditionOperationLessThan : public ConditionOperation +{ +public: + bool compareNumbers(float a, float b) override + { + return lessThan(a, b); + } +}; +class ConditionOperationGreaterThanOrEqual : public ConditionOperation +{ +public: + bool compareNumbers(float a, float b) override + { + return greaterThanOrEqual(a, b); + } +}; +class ConditionOperationGreaterThan : public ConditionOperation +{ +public: + bool compareNumbers(float a, float b) override + { + return greaterThan(a, b); + } +}; +class ConditionComparand +{}; + +class ConditionComparandNumber : public ConditionComparand +{ +public: + virtual ~ConditionComparandNumber() {} + virtual float value(const StateMachineInstance* stateMachineInstance) = 0; +}; +class ConditionComparandNumberBindable : public ConditionComparandNumber +{ +public: + ConditionComparandNumberBindable(BindablePropertyNumber* property) : + m_bindableProperty(property) + {} + float value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyNumber* m_bindableProperty; +}; +class ConditionComparandArtboardProperty : public ConditionComparandNumber +{ +public: + ConditionComparandArtboardProperty( + TransitionPropertyArtboardComparator* property) : + m_transitionPropertyArtboardComparator(property) + {} + float value(const StateMachineInstance* stateMachineInstance) override + { + + auto artboard = stateMachineInstance->artboard(); + if (artboard != nullptr) + { + auto property = static_cast( + m_transitionPropertyArtboardComparator->propertyType()); + switch (property) + { + case ArtboardProperty::width: + return artboard->layoutWidth(); + break; + case ArtboardProperty::height: + return artboard->layoutHeight(); + break; + case ArtboardProperty::ratio: + return artboard->layoutWidth() / artboard->layoutHeight(); + break; + + default: + break; + } + } + return 0; + } + +private: + TransitionPropertyArtboardComparator* + m_transitionPropertyArtboardComparator; +}; + +class ConditionComparandNumberBindableInteger : public ConditionComparandNumber +{ +public: + ConditionComparandNumberBindableInteger(BindablePropertyInteger* property) : + m_bindableProperty(property) + {} + float value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + + return (float)bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyInteger* m_bindableProperty; +}; +class ConditionComparandNumberValue : public ConditionComparandNumber +{ +public: + ConditionComparandNumberValue(TransitionValueNumberComparator* value) : + m_value(value) + {} + float value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueNumberComparator* m_value; +}; + +class ConditionComparandBoolean : public ConditionComparand +{ +public: + virtual ~ConditionComparandBoolean() {} + virtual bool value(const StateMachineInstance* stateMachineInstance) = 0; +}; +class ConditionComparandBooleanBindable : public ConditionComparandBoolean +{ +public: + ConditionComparandBooleanBindable(BindablePropertyBoolean* property) : + m_bindableProperty(property) + {} + bool value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return false; + } + +private: + BindablePropertyBoolean* m_bindableProperty; +}; +class ConditionComparandBooleanValue : public ConditionComparandBoolean +{ +public: + ConditionComparandBooleanValue(TransitionValueBooleanComparator* value) : + m_value(value) + {} + bool value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueBooleanComparator* m_value; +}; + +class ConditionComparandString : public ConditionComparand +{ +public: + virtual ~ConditionComparandString() {} + virtual std::string value( + const StateMachineInstance* stateMachineInstance) = 0; +}; +class ConditionComparandStringBindable : public ConditionComparandString +{ +public: + ConditionComparandStringBindable(BindablePropertyString* property) : + m_bindableProperty(property) + {} + std::string value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return std::string{}; + } + +private: + BindablePropertyString* m_bindableProperty; +}; +class ConditionComparandStringValue : public ConditionComparandString +{ +public: + ConditionComparandStringValue(TransitionValueStringComparator* value) : + m_value(value) + {} + std::string value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueStringComparator* m_value; +}; + +class ConditionComparandColor : public ConditionComparand +{ +public: + virtual ~ConditionComparandColor() {} + virtual int value(const StateMachineInstance* stateMachineInstance) = 0; +}; +class ConditionComparandColorBindable : public ConditionComparandColor +{ +public: + ConditionComparandColorBindable(BindablePropertyColor* property) : + m_bindableProperty(property) + {} + int value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyColor* m_bindableProperty; +}; +class ConditionComparandColorValue : public ConditionComparandColor +{ +public: + ConditionComparandColorValue(TransitionValueColorComparator* value) : + m_value(value) + {} + int value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueColorComparator* m_value; +}; + +class ConditionComparandUint32 : public ConditionComparand +{ +public: + virtual ~ConditionComparandUint32() {} + virtual uint32_t value( + const StateMachineInstance* stateMachineInstance) = 0; +}; +class ConditionComparandEnumBindable : public ConditionComparandUint32 +{ +public: + ConditionComparandEnumBindable(BindablePropertyEnum* property) : + m_bindableProperty(property) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyEnum* m_bindableProperty; +}; +class ConditionComparandEnumValue : public ConditionComparandUint32 +{ +public: + ConditionComparandEnumValue(TransitionValueEnumComparator* value) : + m_value(value) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueEnumComparator* m_value; +}; +class ConditionComparandTriggerBindable : public ConditionComparandUint32 +{ +public: + ConditionComparandTriggerBindable(BindablePropertyTrigger* property) : + m_bindableProperty(property) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyTrigger* m_bindableProperty; +}; +class ConditionComparandTriggerValue : public ConditionComparandUint32 +{ +public: + ConditionComparandTriggerValue(TransitionValueTriggerComparator* value) : + m_value(value) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueTriggerComparator* m_value; +}; +class ConditionComparandIntegerBindable : public ConditionComparandUint32 +{ +public: + ConditionComparandIntegerBindable(BindablePropertyInteger* property) : + m_bindableProperty(property) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyInteger* m_bindableProperty; +}; +class ConditionComparandAssetBindable : public ConditionComparandUint32 +{ +public: + ConditionComparandAssetBindable(BindablePropertyAsset* property) : + m_bindableProperty(property) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyAsset* m_bindableProperty; +}; +class ConditionComparandViewModel : public ConditionComparand +{ +public: + virtual ~ConditionComparandViewModel() {} + virtual ViewModelInstance* value( + const StateMachineInstance* stateMachineInstance) = 0; +}; +class ConditionComparandViewModelBindable : public ConditionComparandViewModel +{ +public: + ConditionComparandViewModelBindable(BindablePropertyViewModel* property) : + m_bindableProperty(property) + {} + + ViewModelInstance* value( + const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + auto dataBind = stateMachineInstance->bindableDataBindToTarget( + bindableInstance); + if (dataBind != nullptr) + { + if (dataBind->is()) + { + const auto& sourcePathIds = + dataBind->as()->sourcePathIds(); + // A root-only source path marks "My ViewModel" for + // transition comparands. Resolve it from the state machine + // data context. + if (sourcePathIds.size() == 1) + { + auto dataContext = stateMachineInstance->dataContext(); + if (dataContext != nullptr && + dataContext->viewModelInstance() != nullptr) + { + return dataContext->viewModelInstance().get(); + } + return nullptr; + } + } + auto source = dataBind->source(); + if (source != nullptr && + source->is()) + { + auto sourceViewModel = + source->as(); + auto referenced = + sourceViewModel->referenceViewModelInstance(); + if (referenced != nullptr) + { + return referenced.get(); + } + } + } + auto bindableViewModel = + bindableInstance->as(); + auto instanceValue = bindableViewModel->viewModelInstanceValue(); + if (instanceValue != nullptr) + { + return instanceValue; + } + return bindableViewModel->viewModelInstance(); + } + return nullptr; + } + +private: + BindablePropertyViewModel* m_bindableProperty; +}; +class ConditionComparandAssetValue : public ConditionComparandUint32 +{ +public: + ConditionComparandAssetValue(TransitionValueAssetComparator* value) : + m_value(value) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueAssetComparator* m_value; +}; +class ConditionComparandArtboardBindable : public ConditionComparandUint32 +{ +public: + ConditionComparandArtboardBindable(BindablePropertyArtboard* property) : + m_bindableProperty(property) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + if (bindableInstance) + { + return bindableInstance->as() + ->propertyValue(); + } + return 0; + } + +private: + BindablePropertyArtboard* m_bindableProperty; +}; +class ConditionComparandArtboardValue : public ConditionComparandUint32 +{ +public: + ConditionComparandArtboardValue(TransitionValueArtboardComparator* value) : + m_value(value) + {} + uint32_t value(const StateMachineInstance* stateMachineInstance) override + { + return m_value->value(); + } + +private: + TransitionValueArtboardComparator* m_value; +}; + +class ConditionComparandComponentCoreNumber : public ConditionComparandNumber +{ +public: + explicit ConditionComparandComponentCoreNumber( + TransitionPropertyComponentComparator* comparator); + float value(const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparandComponentCoreUintAsNumber + : public ConditionComparandNumber +{ +public: + explicit ConditionComparandComponentCoreUintAsNumber( + TransitionPropertyComponentComparator* comparator); + float value(const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparandComponentCoreBoolean : public ConditionComparandBoolean +{ +public: + explicit ConditionComparandComponentCoreBoolean( + TransitionPropertyComponentComparator* comparator); + bool value(const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparandComponentCoreString : public ConditionComparandString +{ +public: + explicit ConditionComparandComponentCoreString( + TransitionPropertyComponentComparator* comparator); + std::string value( + const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparandComponentCoreColor : public ConditionComparandColor +{ +public: + explicit ConditionComparandComponentCoreColor( + TransitionPropertyComponentComparator* comparator); + int value(const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparandComponentCoreUint : public ConditionComparandUint32 +{ +public: + explicit ConditionComparandComponentCoreUint( + TransitionPropertyComponentComparator* comparator); + uint32_t value(const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparandComponentViewModel : public ConditionComparandViewModel +{ +public: + explicit ConditionComparandComponentViewModel( + TransitionPropertyComponentComparator* comparator); + ViewModelInstance* value( + const StateMachineInstance* stateMachineInstance) override; + +private: + TransitionPropertyComponentComparator* m_comparator; +}; + +class ConditionComparison +{ +public: + ConditionComparison(ConditionOperation* op) : m_operation(op) {} + virtual ~ConditionComparison() { delete m_operation; } + virtual bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) = 0; + + bool compareNumbers(float left, float right); + bool compareBooleans(bool left, bool right); + bool compareStrings(const std::string& left, const std::string& right); + bool compareColors(int left, int right); + bool compareUints32(uint32_t left, uint32_t right); + bool comparePointers(const void* left, const void* right); + +protected: + ConditionOperation* m_operation; +}; class TransitionViewModelCondition : public TransitionViewModelConditionBase { protected: TransitionComparator* m_leftComparator; TransitionComparator* m_rightComparator; + ConditionComparison* m_comparison = nullptr; public: ~TransitionViewModelCondition(); @@ -36,6 +745,11 @@ class TransitionViewModelCondition : public TransitionViewModelConditionBase { return (TransitionConditionOp)opValue(); } + ConditionOperation* operation(TransitionConditionOp op); + void initialize(); + +private: + bool canEvaluate(const StateMachineInstance*) const; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/artboard.hpp b/thirdparty/rive/include/rive/artboard.hpp index 3e98109db..8a7e336cb 100644 --- a/thirdparty/rive/include/rive/artboard.hpp +++ b/thirdparty/rive/include/rive/artboard.hpp @@ -2,12 +2,12 @@ #define _RIVE_ARTBOARD_HPP_ #include "rive/advance_flags.hpp" +#include "rive/resetting_component.hpp" #include "rive/animation/linear_animation.hpp" #include "rive/animation/state_machine.hpp" #include "rive/core_context.hpp" -#include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_context.hpp" -#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind_container.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" #include "rive/generated/artboard_base.hpp" @@ -19,6 +19,10 @@ #include "rive/audio/audio_engine.hpp" #include "rive/math/raw_path.hpp" #include "rive/typed_children.hpp" +#include "rive/virtualizing_component.hpp" +#include "rive/input/focus_node.hpp" +#include "rive/semantic/semantic_node.hpp" +#include "rive/lua/scripting_vm.hpp" #include #include @@ -26,6 +30,7 @@ namespace rive { +class KeyFrameInterpolator; class ArtboardComponentList; class ArtboardHost; class File; @@ -46,12 +51,25 @@ class SMIBool; class SMIInput; class SMINumber; class SMITrigger; +class DataBind; +class DataBindContainer; +class ScriptedObject; +class FocusManager; +class SemanticManager; +class SemanticNode; #ifdef WITH_RIVE_TOOLS typedef void (*ArtboardCallback)(void*); +typedef uint8_t (*TestBoundsCallback)(void*, float, float, bool); +typedef uint8_t (*IsAncestorCallback)(void*, uint16_t); +typedef float (*RootTransformCallback)(void*, float, float, bool); #endif -class Artboard : public ArtboardBase, public CoreContext +class Artboard : public ArtboardBase, + public CoreContext, + public Virtualizable, + public ResettingComponent, + public DataBindContainer { friend class File; friend class ArtboardImporter; @@ -59,19 +77,24 @@ class Artboard : public ArtboardBase, public CoreContext private: std::vector m_Objects; + std::vector m_invalidObjects; std::vector m_Animations; std::vector m_StateMachines; std::vector m_DependencyOrder; std::vector m_Drawables; + std::vector m_clippingShapes; std::vector m_DrawTargets; std::vector m_NestedArtboards; std::vector m_ComponentLists; std::vector m_ArtboardHosts; std::vector m_Joysticks; - std::vector m_DataBinds; - std::vector m_AllDataBinds; - DataContext* m_DataContext = nullptr; - bool m_ownsDataContext = false; + std::vector m_Resettables; + std::vector m_ScriptedObjects; + std::vector m_advancingComponents; + rcp m_DataContext = nullptr; +#ifdef WITH_RIVE_SCRIPTING + ScriptingVM* m_scriptingVM = nullptr; +#endif bool m_JoysticksApplyBeforeUpdate = true; unsigned int m_DirtDepth = 0; @@ -81,20 +104,35 @@ class Artboard : public ArtboardBase, public CoreContext bool m_FrameOrigin = true; std::unordered_set m_dirtyLayout; bool m_isCleaningDirtyLayouts = false; + std::unique_ptr m_ownedInheritedInterpolator; float m_originalWidth = 0; float m_originalHeight = 0; bool m_updatesOwnLayout = true; + bool m_hostTransformMarkedDirty = false; + bool m_didChange = true; Artboard* parentArtboard() const; ArtboardHost* m_host = nullptr; + FocusManager* m_activeFocusManager = nullptr; + SemanticManager* m_activeSemanticManager = nullptr; + rcp m_semanticBoundaryNode; +#ifdef WITH_RIVE_TOOLS + rcp m_externalParentFocusNode; +#endif + static uint64_t sm_frameId; bool sharesLayoutWithHost() const; void cloneObjectDataBinds(const Core* object, Core* clone, Artboard* artboard) const; + void initScriptedObjects(); // Variable that tracks whenever the draw order changes. It is used by the // state machine controllers to sort their hittable components when they are // out of sync uint8_t m_drawOrderChangeCounter = 0; +#ifdef WITH_RIVE_TOOLS + uint16_t m_artboardId = 0; +#endif + const Artboard* m_artboardSource = nullptr; #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp m_audioEngine; @@ -102,19 +140,109 @@ class Artboard : public ArtboardBase, public CoreContext void sortDependencies(); void sortDrawOrder(); - void updateDataBinds(); + void clearRedundantOperations(); void updateRenderPath() override; void update(ComponentDirt value) override; public: + static uint64_t frameId() { return sm_frameId; } +#ifdef TESTING + static void incFrameId() { sm_frameId++; } +#elif WITH_RIVE_TOOLS + static void incFrameId() { sm_frameId++; } +#endif + void updateDataBinds(bool applyTargetToSource = true) override; void host(ArtboardHost* artboardHost); ArtboardHost* host() const; + void addedToHost() { m_justAddedToHost = true; } + + /// Set the active FocusManager for this artboard. The FocusManager is + /// typically owned by a StateMachineInstance. + void setActiveFocusManager(FocusManager* manager) + { + m_activeFocusManager = manager; + } + /// Get the active FocusManager for this artboard. + FocusManager* focusManager() const { return m_activeFocusManager; } + +#ifdef WITH_RIVE_TOOLS + /// Set an external parent FocusNode for this artboard's root-level focus + /// nodes. This is used when the artboard is nested inside another artboard + /// that has a FocusData in its hierarchy. The external parent allows focus + /// nodes in this artboard to be children of a FocusData in the host + /// artboard. + void setExternalParentFocusNode(rcp node); + /// Get the external parent FocusNode for this artboard. + rcp externalParentFocusNode() const; + // collapseSingle is only used by the editor. Its purpose is to set the + // collapse value to the immediate artboard but not to its children + void collapseSingle(bool); +#endif + + /// Build the focus tree for this artboard, registering all FocusData nodes + /// with the given FocusManager. + /// @param focusManager The FocusManager to register nodes with + /// @param parentFocusNode Optional parent node for root-level focus nodes + /// (used for nested artboards to connect to parent's focus tree) + void buildFocusTree(FocusManager* focusManager, + rcp parentFocusNode = nullptr); + + /// Build the focus tree for this artboard using the parent node's manager. + /// This is a convenience overload for nested artboards - the FocusManager + /// is derived from the parent node's manager() reference. + /// @param parentFocusNode The parent node to attach this artboard's focus + /// nodes under. Must have a valid manager() or this is a no-op. + void buildFocusTree(rcp parentFocusNode); + + /// Clean up the focus tree for this artboard, removing all FocusData nodes + /// from the FocusManager. This should be called before the artboard is + /// destroyed or recycled to prevent use-after-free when the FocusManager + /// still holds references to FocusNodes pointing to deleted FocusData. + void cleanupFocusTree(); + + /// Set the active SemanticManager for this artboard. The SemanticManager is + /// typically owned by a StateMachineInstance. + void setActiveSemanticManager(SemanticManager* manager) + { + m_activeSemanticManager = manager; + } + /// Get the active SemanticManager for this artboard. + SemanticManager* semanticManager() const { return m_activeSemanticManager; } + + /// Build the semantic tree for this artboard, registering all SemanticData + /// nodes with the given SemanticManager. + void buildSemanticTree(SemanticManager* semanticManager, + rcp parentSemanticNode = nullptr); + + /// Clean up the semantic tree for this artboard, removing all SemanticData + /// nodes from the SemanticManager. + void cleanupSemanticTree(); + + // Semantic-only collapse for this artboard's semantic nodes. + // When collapsing, walks the boundary's semantic subtree (O(K) semantic + // nodes). When uncollapsing, falls back to m_Objects because + // SemanticData::collapse(false) re-parents nodes outside the boundary. + void collapseSemanticBoundary(bool value); + + /// Mark bounds dirty for all semantic nodes under this artboard's + /// boundary node. Called when the host transform changes. + void markSemanticBoundaryTransformDirty(); + + /// Get the semantic boundary node for this artboard (null for root). + rcp semanticBoundaryNode() const + { + return m_semanticBoundaryNode; + } // Implemented for ShapePaintContainer. const Mat2D& shapeWorldTransform() const override { return worldTransform(); } + Component* virtualizableComponent() override { return this; } + bool updatesOwnLayout() { return m_updatesOwnLayout; } + StatusCode onAddedClean(CoreContext* context) override; + void addDirtyDataBind(DataBind*) override; private: #ifdef TESTING @@ -124,14 +252,30 @@ class Artboard : public ArtboardBase, public CoreContext void addObject(Core* object); void addAnimation(LinearAnimation* object); void addStateMachine(StateMachine* object); + void buildDataContext(rcp value); public: Artboard(); ~Artboard() override; bool validateObjects(); StatusCode initialize(); + bool didChange() { return m_didChange; } Core* resolve(uint32_t id) const override; +#ifdef WITH_RIVE_TOOLS + void artboardId(uint16_t id) { m_artboardId = id; } + uint16_t artboardId() const { return m_artboardId; } +#endif + + void artboardSource(const Artboard* artboard) + { + m_artboardSource = artboard; + } + const Artboard* artboardSource() const + { + return isInstance() ? m_artboardSource : this; + } + bool isAncestor(const Artboard* artboard); /// Find the id of a component in the artboard the object in the artboard. /// The artboard itself has id 0 so we use that as a flag for not found. @@ -143,6 +287,12 @@ class Artboard : public ArtboardBase, public CoreContext // DO NOT RELY ON THIS as it may change/disappear in the future. Core* hitTest(HitInfo*, const Mat2D&) override; + bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) override; + + Vec2D rootTransform(const Vec2D&); + void onComponentDirty(Component* component); /// Update components that depend on each other in DAG order. @@ -160,10 +310,17 @@ class Artboard : public ArtboardBase, public CoreContext void updateWorldTransform() override {} void markLayoutDirty(LayoutComponent* layoutComponent); + void markHostTransformDirty(); void cleanLayout(LayoutComponent* layoutComponent); LayoutData* takeLayoutData(); bool syncStyleChanges() override; + void syncStyleChangesWithUpdate(bool forceUpdate = false); + std::unique_ptr& ownedInheritedInterpolator() + { + return m_ownedInheritedInterpolator; + } + void calculateLayout(); bool canHaveOverrides() override { return true; } bool advance(float elapsedSeconds, @@ -174,19 +331,31 @@ class Artboard : public ArtboardBase, public CoreContext AdvanceFlags flags = AdvanceFlags::AdvanceNested | AdvanceFlags::Animate | AdvanceFlags::NewFrame); + void reset() override; uint8_t drawOrderChangeCounter() { return m_drawOrderChangeCounter; } Drawable* firstDrawable() { return m_FirstDrawable; }; + void addScriptedObject(ScriptedObject* object); - enum class DrawOption - { - kNormal, - kHideBG, - kHideFG, - }; - void draw(Renderer* renderer, DrawOption option); + void drawCanvases(); + void internalDrawCanvases(); + + /// Poll async work (image decodes, etc.) so promises resolve before + /// script callbacks run. Called at the top of advance(). + void pollAsyncWork(); + +#ifdef WITH_RIVE_SCRIPTING + /// Returns the lua_State* (as void*) for the first drawCanvas scripted + /// object in this artboard or any nested artboard, recursively. Returns + /// nullptr if no drawCanvas scripts exist. Used by the Dart FFI layer to + /// open a GPU frame before calling drawCanvases(). + void* findDrawCanvasLuauState() const; +#endif + void drawInternal(Renderer* renderer); void draw(Renderer* renderer) override; void addToRenderPath(RenderPath* path, const Mat2D& transform); + void addToRawPath(RawPath& path, const Mat2D* transform); + void changed(); #ifdef TESTING ShapePaintPath* clipPath() { return &m_worldPath; } ShapePaintPath* backgroundPath() { return &m_localPath; } @@ -207,9 +376,10 @@ class Artboard : public ArtboardBase, public CoreContext { return m_ComponentLists; } - const std::vector dataBinds() const { return m_DataBinds; } - const std::vector allDataBinds() const { return m_AllDataBinds; } - DataContext* dataContext() { return m_DataContext; } + rcp dataContext() { return m_DataContext; } +#ifdef WITH_RIVE_SCRIPTING + void scriptingVM(ScriptingVM* value) { m_scriptingVM = value; } +#endif NestedArtboard* nestedArtboard(const std::string& name) const; NestedArtboard* nestedArtboardAtPath(const std::string& path) const; @@ -220,25 +390,31 @@ class Artboard : public ArtboardBase, public CoreContext float layoutX() const; float layoutY() const; AABB bounds() const; + AABB worldBounds() const override; Vec2D origin() const; + void xChanged() override; + void yChanged() override; + + void resetSize() + { + width(m_originalWidth); + height(m_originalHeight); + } // Can we hide these from the public? (they use playable) bool isTranslucent() const; bool isTranslucent(const LinearAnimation*) const; bool isTranslucent(const LinearAnimationInstance*) const; - void dataContext(DataContext* dataContext); - void internalDataContext(DataContext* dataContext, bool isRoot); + void dataContext(rcp dataContext); + void internalDataContext(rcp dataContext); void clearDataContext(); + void unbind(); + void rebind() override; + void relinkDataContext() override; void bindViewModelInstance(rcp viewModelInstance, - DataContext* parent); - void bindViewModelInstance(rcp viewModelInstance, - DataContext* parent, - bool isRoot); + rcp parent); void bindViewModelInstance(rcp viewModelInstance); - void addDataBind(DataBind* dataBind); - void populateDataBinds(std::vector* dataBinds); - void sortDataBinds(); - void collectDataBinds(); + void rebuildDataBind(DataBind*) override; bool hasAudio() const; @@ -284,6 +460,20 @@ class Artboard : public ArtboardBase, public CoreContext return nullptr; } + int objectIndex(Core* component) const + { + int count = 0; + for (auto object : m_Objects) + { + if (object == component) + { + return count; + } + count++; + } + return -1; + } + template std::vector find() { std::vector results; @@ -300,6 +490,15 @@ class Artboard : public ArtboardBase, public CoreContext size_t animationCount() const { return m_Animations.size(); } std::string animationNameAt(size_t index) const; + /// Returns the count of FocusData objects that don't have a parent + /// FocusData within this artboard (i.e., "root" focus nodes from this + /// artboard's perspective). + size_t rootFocusDataCount() const; + + /// Returns the FocusData at the given index among root FocusData objects. + /// Returns nullptr if index is out of bounds. + class FocusData* rootFocusDataAt(size_t index) const; + size_t stateMachineCount() const { return m_StateMachines.size(); } std::string stateMachineNameAt(size_t index) const; @@ -328,6 +527,11 @@ class Artboard : public ArtboardBase, public CoreContext artboardClone->m_IsInstance = true; artboardClone->m_originalWidth = m_originalWidth; artboardClone->m_originalHeight = m_originalHeight; +#ifdef WITH_RIVE_TOOLS + artboardClone->m_artboardId = m_artboardId; +#endif + artboardClone->m_artboardSource = + isInstance() ? m_artboardSource : this; cloneObjectDataBinds(this, artboardClone.get(), artboardClone.get()); std::vector& cloneObjects = artboardClone->m_Objects; @@ -418,6 +622,10 @@ class Artboard : public ArtboardBase, public CoreContext #ifdef WITH_RIVE_TOOLS ArtboardCallback m_layoutChangedCallback = nullptr; ArtboardCallback m_layoutDirtyCallback = nullptr; + ArtboardCallback m_transformDirtyCallback = nullptr; + TestBoundsCallback m_testBoundsCallback = nullptr; + IsAncestorCallback m_isAncestorCallback = nullptr; + RootTransformCallback m_rootTransformCallback = nullptr; public: void* callbackUserData; @@ -430,6 +638,23 @@ class Artboard : public ArtboardBase, public CoreContext m_layoutDirtyCallback = callback; addDirt(ComponentDirt::Components); } + void onTransformDirty(ArtboardCallback callback) + { + m_transformDirtyCallback = callback; + addDirt(ComponentDirt::Components); + } + void onTestBounds(TestBoundsCallback callback) + { + m_testBoundsCallback = callback; + } + void onIsAncestor(IsAncestorCallback callback) + { + m_isAncestorCallback = callback; + } + void onRootTransform(RootTransformCallback callback) + { + m_rootTransformCallback = callback; + } #endif }; diff --git a/thirdparty/rive/include/rive/artboard_component_list.hpp b/thirdparty/rive/include/rive/artboard_component_list.hpp index d189a931d..e5eb424a1 100644 --- a/thirdparty/rive/include/rive/artboard_component_list.hpp +++ b/thirdparty/rive/include/rive/artboard_component_list.hpp @@ -1,27 +1,43 @@ #ifndef _RIVE_ARTBOARD_COMPONENT_LIST_HPP_ #define _RIVE_ARTBOARD_COMPONENT_LIST_HPP_ #include "rive/generated/artboard_component_list_base.hpp" +#include "rive/layout/artboard_component_list_override.hpp" #include "rive/advancing_component.hpp" +#include "rive/resetting_component.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/artboard.hpp" +#include "rive/constraints/constrainable_list.hpp" +#include "rive/property_recorder.hpp" +#include "rive/file.hpp" #include "rive/artboard_host.hpp" #include "rive/data_bind/data_bind_list_item_consumer.hpp" #include "rive/layout/layout_node_provider.hpp" #include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/viewmodel/symbol_type.hpp" +#include "rive/virtualizing_component.hpp" +#include #include #include +#include namespace rive { -class File; +class LayoutComponent; +class ScrollConstraint; +class ArtboardListMapRule; +class ArtboardListDrawIndexDependent; class ArtboardComponentList : public ArtboardComponentListBase, public ArtboardHost, public AdvancingComponent, + public ResettingComponent, public LayoutNodeProvider, - public DataBindListItemConsumer + public DataBindListItemConsumer, + public VirtualizingComponent, + public ConstrainableList { private: - std::vector m_listItems; + std::vector> m_listItems; + std::vector> m_oldItems; public: ArtboardComponentList(); @@ -30,34 +46,17 @@ class ArtboardComponentList : public ArtboardComponentListBase, void* layoutNode(int index) override; #endif size_t artboardCount() override { return m_listItems.size(); } - ViewModelInstanceListItem* listItem(int index) - { - if (index < m_listItems.size()) - { - return m_listItems[index]; - } - return nullptr; - } - ArtboardInstance* artboardInstance(int index = 0) override - { - if (index < m_listItems.size()) - { - return m_artboardInstancesMap[listItem(index)].get(); - } - return nullptr; - } - StateMachineInstance* stateMachineInstance(int index = 0) - { - if (index < m_listItems.size()) - { - return m_stateMachinesMap[listItem(index)].get(); - } - return nullptr; - } + rcp listItem(int index); + ArtboardInstance* artboardInstance(int index = 0) override; + /// Logical index of the given instance in the list, or -1 if not found. + int indexOfArtboardInstance(ArtboardInstance* instance) const; + StateMachineInstance* stateMachineInstance(int index = 0); bool worldToLocal(Vec2D world, Vec2D* local, int index); + bool collapse(bool value) override; bool advanceComponent(float elapsedSeconds, AdvanceFlags flags = AdvanceFlags::Animate | AdvanceFlags::NewFrame) override; + void reset() override; AABB layoutBounds() override; AABB layoutBoundsForNode(int index) override; void markHostingLayoutDirty(ArtboardInstance* artboardInstance) override; @@ -65,47 +64,169 @@ class ArtboardComponentList : public ArtboardComponentListBase, { return this->as(); } - void updateList(int propertyKey, - std::vector* list) override; + void updateWorldTransform() override; + void updateList(std::vector>* list) override; void draw(Renderer* renderer) override; + bool willDraw() override; Core* hitTest(HitInfo*, const Mat2D&) override; void update(ComponentDirt value) override; void updateConstraints() override; - void populateDataBinds(std::vector* dataBinds) override; - void internalDataContext(DataContext* dataContext) override; + void internalDataContext(rcp dataContext) override; void bindViewModelInstance(rcp viewModelInstance, - DataContext* parent) override; + rcp parent) override; void clearDataContext() override; + void unbind() override; + void updateDataBinds() override; Artboard* parentArtboard() override { return artboard(); } + bool hitTestHost(const Vec2D& position, + bool skipOnUnclipped, + ArtboardInstance* artboard) override; + Vec2D hostTransformPoint(const Vec2D& vec, ArtboardInstance*) override; + Mat2D worldTransformForArtboard(ArtboardInstance*) override; void markHostTransformDirty() override { markTransformDirty(); } + Component* hostComponent() override { return this; } bool syncStyleChanges() override; void updateLayoutBounds(bool animate = true) override; +#ifdef WITH_RIVE_LAYOUT + bool cascadeLayoutStyle(LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime, + LayoutDirection direction) override; +#endif void markLayoutNodeDirty( bool shouldForceUpdateLayoutBounds = false) override; bool isLayoutProvider() override { return true; } size_t numLayoutNodes() override { return m_listItems.size(); } - void reset(); - void file(File*); - File* file() const; + void clear(); + void file(File*) override; + File* file() const override; Core* clone() const override; + // API used by the virtualizer + Artboard* findArtboard( + const rcp& listItem) const; + void addVirtualizable(int index) override; + void removeVirtualizable(int index) override; + void setVisibleIndices(int start, int end) override + { + m_visibleStartIndex = start; + m_visibleEndIndex = end; + invalidateOrderedListIndicesCache(); + } + void shouldResetInstances(bool value) { m_shouldResetInstances = value; } + void setVirtualizablePosition(int index, Vec2D position) override; + void createArtboardAt(int index, bool forceLayoutSync = true); + void addArtboardAt(std::unique_ptr artboard, + int index, + bool forceLayoutSync = true); + void removeArtboardAt(int index); + void removeArtboard(rcp item); + bool virtualizationEnabled() override; + ScrollConstraint* scrollConstraint(); + int itemCount() override { return (int)m_listItems.size(); } + Virtualizable* item(int index) override { return artboardInstance(index); } + void setItemSize(Vec2D size, int index) override; + Vec2D size() override; + Vec2D itemSize(int index) override; + float gap(); + void syncLayoutChildren(); + bool mainAxisIsRow(); + LayoutComponent* layoutParent(); + const Mat2D& listTransform() override; + void listItemTransforms(std::vector& transforms) override; + void addMapRule(ArtboardListMapRule*); + int type() const override { return coreType(); } + + /// Rebuilds the ordered-list cache when invalid (list, visibility, or + /// drawIndex sort inputs changed). + void ensureOrderedListIndices(); + /// Paint / scroll order indices; uses drawIndex sorting when any list + /// item's view model defines SymbolType::drawIndex. Hit-test top-first by + /// iterating this vector in reverse. Do not retain references across + /// mutations that invalidate the cache. + const std::vector& orderedListIndices(); + void invalidateOrderedListIndicesCache(); + private: - void disposeListItem(ViewModelInstanceListItem* listItem); + void updateArtboardsWorldTransform(); + void disposeListItem(const rcp& listItem); std::unique_ptr createArtboard( Component* target, - ViewModelInstanceListItem* listItem) const; - Artboard* findArtboard(ViewModelInstanceListItem* listItem) const; + rcp listItem) const; + void bindArtboard(ArtboardInstance* artboard, + rcp listItem); std::unique_ptr createStateMachineInstance( Component* target, ArtboardInstance* artboard); + void linkStateMachineToArtboard(StateMachineInstance* stateMachineInstance, + ArtboardInstance* artboard); + void computeLayoutBounds(); + void createArtboardRecorders(const Artboard*); + void applyRecorders(Artboard* artboard, const Artboard* sourceArtboard); + void applyRecorders(StateMachineInstance* stateMachineInstance, + const Artboard* sourceArtboard); mutable std::unordered_map m_artboardsMap; - std::unordered_map, std::unique_ptr> m_artboardInstancesMap; - std::unordered_map, std::unique_ptr> m_stateMachinesMap; - File* m_file; + std::unordered_map>> + m_resourcePool; + std::unordered_map>> + m_stateMachinesPool; + std::unordered_map> + m_propertyRecordersMap; + std::unordered_map m_artboardTransforms; + Vec2D artboardPosition(ArtboardInstance* artboard); + + // Vectors used for access in non-virtualized mode + std::vector m_artboardInstancesByIndex; + std::vector m_stateMachinesByIndex; + + File* m_file = nullptr; + std::vector m_artboardSizes; + Vec2D m_layoutSize; + int m_visibleStartIndex = -1; + int m_visibleEndIndex = -1; + std::unordered_map + m_artboardOverridesMap; + std::unordered_map m_artboardMapRules; + + // Data binds that bridge properties between a stateful component's + // cloned ViewModelInstance and the original (user-provided) one. + // Keyed by list item so they can be cleaned up when the item is removed. + std::unordered_map, + std::vector>> + m_bridgeDataBinds; + void createBridgeBinds(rcp listItem, + ViewModelInstance* original, + ViewModelInstance* clone); + void removeBridgeBinds(const rcp& listItem); + void attachArtboardOverride(ArtboardInstance*, + rcp); + void clearArtboardOverride(ArtboardInstance*); + bool m_shouldResetInstances = false; + bool listsAreEqual(std::vector>* list, + std::vector>* compared); + + void recomputeListUsesDrawIndexSort(); + float listItemDrawIndex(int index) const; + void clearDrawIndexListeners(); + void syncDrawIndexListeners(); + void removeDrawIndexListenerForItem( + const rcp& listItem); + + bool m_listUsesDrawIndexSort = false; + bool m_orderedListIndicesCacheValid = false; + /// Always paint / scroll order (ascending drawIndex when enabled). + std::vector m_cachedOrderedListIndices; + std::unordered_map, + std::unique_ptr> + m_drawIndexDependents; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/artboard_host.hpp b/thirdparty/rive/include/rive/artboard_host.hpp index 88da3bf4b..8cbf3701b 100644 --- a/thirdparty/rive/include/rive/artboard_host.hpp +++ b/thirdparty/rive/include/rive/artboard_host.hpp @@ -1,6 +1,9 @@ #ifndef _RIVE_ARTBOARD_HOST_HPP_ #define _RIVE_ARTBOARD_HOST_HPP_ #include "rive/refcnt.hpp" +#include "rive/file.hpp" +#include "rive/data_bind_path_referencer.hpp" +#include "rive/math/mat2d.hpp" #include namespace rive { @@ -9,22 +12,38 @@ class DataBind; class DataContext; class ViewModelInstance; -class ArtboardHost +class ArtboardHost : public DataBindPathReferencer { public: virtual size_t artboardCount() = 0; virtual ArtboardInstance* artboardInstance(int index = 0) = 0; - virtual std::vector dataBindPathIds() { return {}; } - virtual void populateDataBinds(std::vector* dataBinds) = 0; - virtual void internalDataContext(DataContext* dataContext) = 0; + virtual void internalDataContext(rcp dataContext) = 0; virtual void bindViewModelInstance(rcp viewModelInstance, - DataContext* parent) = 0; + rcp parent) = 0; virtual void clearDataContext() = 0; + virtual void unbind() = 0; + virtual void updateDataBinds() = 0; virtual void markHostingLayoutDirty(ArtboardInstance* artboardInstance) {} // The artboard that contains this ArtboardHost virtual Artboard* parentArtboard() = 0; + virtual bool hitTestHost(const Vec2D& position, + bool skipOnUnclipped, + ArtboardInstance* artboard) = 0; + virtual Vec2D hostTransformPoint(const Vec2D&, ArtboardInstance*) = 0; + /// Returns the transform matrix from nested artboard space to parent + /// artboard space. Unlike hostTransformPoint, this does NOT include + /// rootTransform. + virtual Mat2D worldTransformForArtboard(ArtboardInstance*) = 0; virtual void markHostTransformDirty() = 0; virtual bool isLayoutProvider() { return false; } + virtual void file(File* value) = 0; + virtual File* file() const = 0; + + /// Return this host as a Component, if applicable (e.g., NestedArtboard). + /// Returns nullptr if the host is not a Component. + virtual class Component* hostComponent() { return nullptr; } + virtual void relinkDataContext(rcp viewModelInstance) {} + virtual int type() const = 0; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/artboard_list_map_rule.hpp b/thirdparty/rive/include/rive/artboard_list_map_rule.hpp new file mode 100644 index 000000000..695179652 --- /dev/null +++ b/thirdparty/rive/include/rive/artboard_list_map_rule.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_ARTBOARD_LIST_MAP_RULE_HPP_ +#define _RIVE_ARTBOARD_LIST_MAP_RULE_HPP_ +#include "rive/generated/artboard_list_map_rule_base.hpp" +#include +namespace rive +{ +class ArtboardListMapRule : public ArtboardListMapRuleBase +{ +public: + StatusCode onAddedDirty(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/artboard_referencer.hpp b/thirdparty/rive/include/rive/artboard_referencer.hpp new file mode 100644 index 000000000..11948eb4c --- /dev/null +++ b/thirdparty/rive/include/rive/artboard_referencer.hpp @@ -0,0 +1,33 @@ +#ifndef _RIVE_ARTBOARD_REFERENCER_HPP_ +#define _RIVE_ARTBOARD_REFERENCER_HPP_ +#include "rive/refcnt.hpp" +#include +namespace rive +{ +class Artboard; +class ViewModelInstanceArtboard; +class File; +class Core; + +class ArtboardReferencer +{ +protected: + Artboard* findArtboard(ViewModelInstanceArtboard* viewModelInstanceArtboard, + Artboard* parentArtboard, + File* file); + Artboard* m_referencedArtboard = nullptr; + +public: + virtual ~ArtboardReferencer() = default; + virtual void updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) = 0; + virtual int referencedArtboardId() = 0; + static ArtboardReferencer* from(Core*); + virtual void referencedArtboard(Artboard* artboard) + { + m_referencedArtboard = artboard; + } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/assets/blob_asset.hpp b/thirdparty/rive/include/rive/assets/blob_asset.hpp new file mode 100644 index 000000000..5f2d462a2 --- /dev/null +++ b/thirdparty/rive/include/rive/assets/blob_asset.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_BLOB_ASSET_HPP_ +#define _RIVE_BLOB_ASSET_HPP_ +#include "rive/generated/assets/blob_asset_base.hpp" +#include "rive/simple_array.hpp" + +namespace rive +{ +class BlobAsset : public BlobAssetBase +{ +public: + bool decode(SimpleArray&, Factory*) override; + std::string fileExtension() const override; + + Span bytes() const { return m_bytes; } + +private: + SimpleArray m_bytes; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/assets/file_asset.hpp b/thirdparty/rive/include/rive/assets/file_asset.hpp index 781d9fb25..680f484a6 100644 --- a/thirdparty/rive/include/rive/assets/file_asset.hpp +++ b/thirdparty/rive/include/rive/assets/file_asset.hpp @@ -1,20 +1,24 @@ #ifndef _RIVE_FILE_ASSET_HPP_ #define _RIVE_FILE_ASSET_HPP_ -#include "rive/assets/file_asset_referencer.hpp" #include "rive/generated/assets/file_asset_base.hpp" #include "rive/span.hpp" +#include "rive/refcnt.hpp" #include "rive/simple_array.hpp" #include namespace rive { class Factory; -class FileAsset : public FileAssetBase +class FileAssetReferencer; +class FileAsset : public FileAssetBase, public RefCnt { private: std::vector m_cdnUuid; std::vector m_fileAssetReferencers; +protected: + virtual bool addsToBackboard() { return true; } + public: Span cdnUuid() const; std::string cdnUuidStr() const; diff --git a/thirdparty/rive/include/rive/assets/file_asset_contents.hpp b/thirdparty/rive/include/rive/assets/file_asset_contents.hpp index 67457c02d..d4c4b2d75 100644 --- a/thirdparty/rive/include/rive/assets/file_asset_contents.hpp +++ b/thirdparty/rive/include/rive/assets/file_asset_contents.hpp @@ -10,12 +10,16 @@ class FileAssetContents : public FileAssetContentsBase { public: SimpleArray& bytes(); + SimpleArray& signature(); StatusCode import(ImportStack& importStack) override; void decodeBytes(Span value) override; void copyBytes(const FileAssetContentsBase& object) override; + void decodeSignature(Span value) override; + void copySignature(const FileAssetContentsBase& object) override; private: SimpleArray m_bytes; + SimpleArray m_signature; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/assets/file_asset_referencer.hpp b/thirdparty/rive/include/rive/assets/file_asset_referencer.hpp index 1b2be34e9..44f59883d 100644 --- a/thirdparty/rive/include/rive/assets/file_asset_referencer.hpp +++ b/thirdparty/rive/include/rive/assets/file_asset_referencer.hpp @@ -3,18 +3,19 @@ #include #include "rive/importers/import_stack.hpp" +#include "rive/assets/file_asset.hpp" namespace rive { -class FileAsset; class FileAssetReferencer { protected: - FileAsset* m_fileAsset = nullptr; + rcp m_fileAsset; public: virtual ~FileAssetReferencer() = 0; - virtual void setAsset(FileAsset* asset); + virtual void setAsset(rcp asset); + const rcp asset() { return m_fileAsset; } virtual uint32_t assetId() = 0; StatusCode registerReferencer(ImportStack& importStack); virtual void assetUpdated() {} diff --git a/thirdparty/rive/include/rive/assets/manifest_asset.hpp b/thirdparty/rive/include/rive/assets/manifest_asset.hpp new file mode 100644 index 000000000..2489dc2e0 --- /dev/null +++ b/thirdparty/rive/include/rive/assets/manifest_asset.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_MANIFEST_ASSET_HPP_ +#define _RIVE_MANIFEST_ASSET_HPP_ +#include "rive/generated/assets/manifest_asset_base.hpp" +#include "rive/data_resolver.hpp" +#include +#include +#include +namespace rive +{ +class ManifestAsset : public ManifestAssetBase, public DataResolver +{ +private: + std::unordered_map m_names; + std::unordered_map> m_paths; + static const std::string empty; + static const std::vector emptyIntVector; + bool decodeNames(BinaryReader& reader); + bool decodePaths(BinaryReader& reader); + +protected: + bool addsToBackboard() override { return false; } + +public: + bool decode(SimpleArray&, Factory*) override; + std::string fileExtension() const override; + const std::string& resolveName(int id) override; + const std::vector& resolvePath(int id) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/assets/script_asset.hpp b/thirdparty/rive/include/rive/assets/script_asset.hpp new file mode 100644 index 000000000..8b9d5d829 --- /dev/null +++ b/thirdparty/rive/include/rive/assets/script_asset.hpp @@ -0,0 +1,244 @@ +#ifndef _RIVE_SCRIPT_ASSET_HPP_ +#define _RIVE_SCRIPT_ASSET_HPP_ +#include "rive/file.hpp" +#include "rive/generated/assets/script_asset_base.hpp" +#include "rive/simple_array.hpp" +#include +#ifdef WITH_RIVE_SCRIPTING +#include +#endif + +#ifdef WITH_RIVE_SCRIPTING +struct lua_State; +#endif + +namespace rive +{ +class Artboard; +class Component; +class DataBind; +class ScriptedObject; +class ScriptingVM; + +enum ScriptProtocol +{ + utility, + node, + layout, + converter, + pathEffect, + listenerAction, + transitionCondition +}; + +#ifdef WITH_RIVE_SCRIPTING +class ScriptAssetImporter; +#endif + +class ScriptInput +{ +protected: + ScriptedObject* m_scriptedObject = nullptr; + DataBind* m_dataBind = nullptr; + bool m_ownsDataBind = false; + +public: + virtual ~ScriptInput(); + virtual void initScriptedValue(); + virtual bool validateForScriptInit() = 0; + /// Inputs that need a DataContext (VM paths, VM-resolved artboards) must + /// return true here without requiring binding; resolution runs in + /// hydrateScriptInput(). + virtual bool validateForColdScriptInit(); + /// Resolve bind-time inputs and push into Lua (called after data bind). + virtual bool hydrateScriptInput(); + /// Non-mutating checks that hydrateScriptInput can succeed for every input; + /// hydrateScriptInputs validates all before pushing any. + virtual bool validateHydrationPrerequisites(); + static ScriptInput* from(Core* component); + DataBind* dataBind() { return m_dataBind; } + void dataBind(DataBind* dataBind, bool ownsDataBind = false) + { + m_dataBind = dataBind; + m_ownsDataBind = ownsDataBind; + } + ScriptedObject* scriptedObject() { return m_scriptedObject; } + void scriptedObject(ScriptedObject* object) { m_scriptedObject = object; } +}; + +class OptionalScriptedMethods +{ +private: + static const int m_advancesBit = 1 << 0; + static const int m_updatesBit = 1 << 1; + static const int m_measuresBit = 1 << 2; + static const int m_wantsPointerDownBit = 1 << 3; + static const int m_wantsPointerMoveBit = 1 << 4; + static const int m_wantsPointerUpBit = 1 << 5; + static const int m_wantsPointerExitBit = 1 << 6; + static const int m_wantsPointerCancelBit = 1 << 7; + static const int m_drawsBit = 1 << 8; + static const int m_initsBit = 1 << 9; + static const int m_dataConvertsBit = 1 << 10; + static const int m_dataReverseConvertsBit = 1 << 11; + static const int m_resizesBit = 1 << 12; + static const int m_listenerPerforms = 1 << 13; + static const int m_listenerPerformsAction = 1 << 14; + static const int m_drawsCanvasBit = 1 << 15; + static const int m_wantsKeyboardInputBit = 1 << 16; + static const int m_wantsTextInputBit = 1 << 17; + + int m_implementedMethods = 0; + +protected: +#ifdef WITH_RIVE_SCRIPTING + bool verifyImplementation(ScriptedObject* object, lua_State* state); +#endif + +public: + int implementedMethods() { return m_implementedMethods; } + void implementedMethods(int implemented) + { + m_implementedMethods = implemented; + } + bool listensToPointerEvents() + { + return (m_implementedMethods & + (m_wantsPointerDownBit | m_wantsPointerMoveBit | + m_wantsPointerUpBit | m_wantsPointerExitBit | + m_wantsPointerCancelBit)) != 0; + } + bool advances() { return (m_implementedMethods & m_advancesBit) != 0; } + bool updates() { return (m_implementedMethods & m_updatesBit) != 0; } + bool measures() { return (m_implementedMethods & m_measuresBit) != 0; } + bool resizes() { return (m_implementedMethods & m_resizesBit) != 0; } + bool performs() const + { + return (m_implementedMethods & m_listenerPerforms) != 0; + } + bool performsAction() const + { + return (m_implementedMethods & m_listenerPerformsAction) != 0; + } + bool wantsPointerDown() + { + return (m_implementedMethods & m_wantsPointerDownBit) != 0; + } + bool wantsPointerMove() + { + return (m_implementedMethods & m_wantsPointerMoveBit) != 0; + } + bool wantsPointerUp() + { + return (m_implementedMethods & m_wantsPointerUpBit) != 0; + } + bool wantsPointerExit() + { + return (m_implementedMethods & m_wantsPointerExitBit) != 0; + } + bool wantsPointerCancel() + { + return (m_implementedMethods & m_wantsPointerCancelBit) != 0; + } + bool draws() { return (m_implementedMethods & m_drawsBit) != 0; } + bool inits() { return (m_implementedMethods & m_initsBit) != 0; } + bool dataConverts() + { + return (m_implementedMethods & m_dataConvertsBit) != 0; + } + bool dataReverseConverts() + { + return (m_implementedMethods & m_dataReverseConvertsBit) != 0; + } + bool drawsCanvas() + { + return (m_implementedMethods & m_drawsCanvasBit) != 0; + } + bool wantsKeyboardInput() + { + return (m_implementedMethods & m_wantsKeyboardInputBit) != 0; + } + bool wantsTextInput() + { + return (m_implementedMethods & m_wantsTextInputBit) != 0; + } +}; + +class ModuleDetails +{ +public: + virtual ~ModuleDetails() = default; + virtual std::string moduleName() = 0; + virtual void registrationComplete(int ref) {} + virtual Span moduleBytecode() { return Span(); } + virtual bool isProtocolScript() = 0; + virtual bool verified() const { return false; } + void addMissingDependency(std::string name) { m_dependencies.insert(name); } + void clearMissingDependency(std::string name) + { + auto it = m_dependencies.find(name); + if (it != m_dependencies.end()) + { + m_dependencies.erase(it); + } + } + std::unordered_set missingDependencies() + { + return m_dependencies; + } + +private: + std::unordered_set m_dependencies; +}; + +class ScriptAsset : public ScriptAssetBase, + public OptionalScriptedMethods, + public ModuleDetails +{ + +public: +#ifdef WITH_RIVE_SCRIPTING + bool verified() const override { return m_verified; } + Span moduleBytecode() override { return m_bytecode; } +#endif + + bool initScriptedObject(ScriptedObject* object); + + /// Sets the bytecode from data with header format: + /// [flags:1] [signature:64 if signed] [luau_bytecode:N] + /// Flags byte: bits 0-6 = version, bit 7 = isSigned + /// Returns true if bytecode was set (verification is separate from return). + bool bytecode(Span data); + + /// Bytecode provided via decode should only happen with in-band bytecode. + /// The signature will later be verified once file loading completes, so it + /// is immediately marked as unverified. + bool decode(SimpleArray& data, Factory* factory) override; + + std::string fileExtension() const override { return "lua"; } + void file(File* value) { m_file = value; } + File* file() const { return m_file; } +#ifdef WITH_RIVE_SCRIPTING + ScriptingVM* scriptingVM(); + lua_State* vm(); + void registrationComplete(int ref) override; +#endif + std::string moduleName() override + { + return folderPath() == "" ? name() : folderPath() + "/" + name(); + } + bool isProtocolScript() override { return !isModule(); } + +private: + File* m_file = nullptr; +#ifdef WITH_RIVE_SCRIPTING + bool m_scriptRegistered = false; + SimpleArray m_bytecode; + bool m_initted = false; +#endif + + bool initScriptedObjectWith(ScriptedObject* object); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/assets/shader_asset.hpp b/thirdparty/rive/include/rive/assets/shader_asset.hpp new file mode 100644 index 000000000..5744620bf --- /dev/null +++ b/thirdparty/rive/include/rive/assets/shader_asset.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_SHADER_ASSET_HPP_ +#define _RIVE_SHADER_ASSET_HPP_ +#include "rive/generated/assets/shader_asset_base.hpp" +#include "rive/simple_array.hpp" +#include "rive/span.hpp" +#include +#include + +namespace rive +{ +/// Asset holding one compiled shader in RSTB (Rive Shader Table Binary) v3. +/// Each ShaderAsset corresponds 1:1 to a WGSL source. The "table" is the +/// per-backend-target variant table (MSL, HLSL, GLSL, SPIR-V, WGSL passthrough) +/// plus the binding-map and GL-fixup sidecars. +/// +/// RSTB v3 layout: +/// Header (8 bytes): magic(u32LE=0x52535442) + version(u16LE=3) + +/// variant_count(u8) + section_count(u8) +/// Per variant: target(u8) + blob_offset(u32LE) + blob_size(u32LE) +/// Per section: tag(u8) + length(u16LE) + data[length] +/// Blob data section (blob_offset values are relative to this section) +/// +/// ShaderTarget enum (u8): +/// 0 = WGSL passthrough, 1 = GLSL ES3, 2 = MSL, 3 = HLSL SM5, 5 = SPIR-V +/// 10..13, 16 = binding-map sidecars (per source target) +/// 14, 15 = GL program-link fixup tables (VS, FS) +class ShaderAsset : public ShaderAssetBase +{ +public: + bool decode(SimpleArray& data, Factory* factory) override + { + return decode(Span(data.data(), data.size()), factory); + } + + bool decode(Span data, Factory* factory); + std::string fileExtension() const override { return "rstb"; } + + /// Returns the blob for the given target, or an empty span if not present. + /// The span is valid for the lifetime of this asset. + Span findShader(uint8_t target) const; + + /// Texture-sampler pair from shader reflection. + struct TextureSamplerPair + { + uint8_t texGroup; + uint8_t texBinding; + uint8_t sampGroup; + uint8_t sampBinding; + }; + + /// Texture-sampler pairs decoded from the RSTB tagged-section payload. + Span textureSamplerPairs() const + { + return Span(m_pairs.data(), m_pairs.size()); + } + +private: + SimpleArray m_bytes; + + struct ShaderVariant + { + uint32_t offset; // absolute byte offset into m_bytes + uint32_t size; + }; + // key = target + std::unordered_map m_index; + + std::vector m_pairs; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/assets/text_asset.hpp b/thirdparty/rive/include/rive/assets/text_asset.hpp new file mode 100644 index 000000000..f2cee1e61 --- /dev/null +++ b/thirdparty/rive/include/rive/assets/text_asset.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_TEXT_ASSET_HPP_ +#define _RIVE_TEXT_ASSET_HPP_ +#include "rive/generated/assets/text_asset_base.hpp" +#include + +namespace rive +{ +#ifdef WITH_RIVE_SCRIPTING +class TextAssetImporter; +#endif + +/// Abstract base for assets that carry editor-authored source text compiled +/// to a signed in-band payload. Concrete subclasses: ScriptAsset (Luau +/// bytecode), ShaderAsset (RSTB blob). The aggregate-signature machinery in +/// TextAssetImporter is shared across all TextAsset subclasses so a single +/// signature can cover mixed Luau + RSTB content in export order. +class TextAsset : public TextAssetBase +{ +#ifdef WITH_RIVE_SCRIPTING + friend class TextAssetImporter; +#endif + +public: +#ifdef WITH_RIVE_SCRIPTING + /// True once the aggregate in-band signature has verified against this + /// asset's content. Defaults to false until TextAssetImporter::resolve + /// runs. Production (non-tools) consumers should gate use of the content + /// behind this check. + bool verified() const { return m_verified; } + +protected: + bool m_verified = false; +#endif +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/async/work_pool.hpp b/thirdparty/rive/include/rive/async/work_pool.hpp new file mode 100644 index 000000000..fdb46b55b --- /dev/null +++ b/thirdparty/rive/include/rive/async/work_pool.hpp @@ -0,0 +1,89 @@ +/* + * Copyright 2026 Rive + */ + +#pragma once + +#include "rive/async/work_task.hpp" +#include "rive/refcnt.hpp" +#include +#include +#include + +#ifdef WITH_RIVE_THREADING +#include +#include +#include +#include +#include +#endif + +namespace rive +{ + +/// A pool that executes WorkTasks. +/// +/// WITH_RIVE_THREADING: spawns worker threads; submit() queues work; +/// pollCompletedWork() delivers callbacks on the main thread. +/// +/// Without threading: submit() just enqueues; pollCompletedWork() dequeues, +/// calls execute() synchronously, then delivers callbacks — all on the main +/// thread. +class WorkPool : public RefCnt +{ +public: + WorkPool(); + ~WorkPool(); + + /// Submit a task for execution. Returns a nonzero handle on success. + uint64_t submit(rcp task); + + /// Process up to maxCallbacks completed tasks on the main thread. + /// Returns the number of tasks processed. + uint32_t pollCompletedWork(uint32_t maxCallbacks = 16); + + /// Returns true if any tasks are queued, running, or + /// completed-but-unpolled. + bool hasPendingWork() const; + + /// Cancel all tasks belonging to the given owner. + void cancelAllForOwner(uint64_t ownerId); + + /// Generate a unique owner ID for task tracking. + static uint64_t nextOwnerId(); + +private: + std::deque> m_workQueue; + +#ifdef WITH_RIVE_THREADING + std::deque> m_completedQueue; + std::vector m_threads; + std::mutex m_queueMutex; + std::mutex m_completedMutex; + std::condition_variable m_haveWork; + // Maps ownerId → cancel generation. A task is owner-cancelled only if + // its submit generation is less than the owner's cancel generation. + std::unordered_map m_cancelledOwners; + std::atomic m_inFlightCount{0}; + uint64_t m_cancelGeneration = 0; + bool m_shutdown = false; + + void workerLoop(); +#endif + + uint64_t m_nextHandle = 1; + static std::atomic s_nextOwnerId; +}; + +/// Returns the process-global WorkPool singleton. Creates it on first call. +rcp& getGlobalWorkPool(); + +/// Returns the global WorkPool if it has been created, or an empty rcp if not. +rcp& getGlobalWorkPoolIfExists(); + +/// Poll the global WorkPool for completed async tasks (image decodes, etc.). +/// Called from Artboard::advance() so promises resolve before script callbacks. +/// Safe to call even if no WorkPool exists (no-op). +void rive_pollAsyncWork(); + +} // namespace rive diff --git a/thirdparty/rive/include/rive/async/work_task.hpp b/thirdparty/rive/include/rive/async/work_task.hpp new file mode 100644 index 000000000..cec098136 --- /dev/null +++ b/thirdparty/rive/include/rive/async/work_task.hpp @@ -0,0 +1,78 @@ +/* + * Copyright 2026 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include +#include + +namespace rive +{ + +/// Status of a WorkTask. +enum class WorkStatus : uint8_t +{ + Pending, + Running, + Completed, + Failed, + Cancelled +}; + +/// Base class for a unit of async work. +/// +/// With WITH_RIVE_THREADING, execute() runs on a worker thread and +/// onComplete()/onError() are called on the main thread during +/// pollCompletedWork(). +/// +/// Without threading, execute() runs synchronously on the main thread +/// inside pollCompletedWork(), followed immediately by onComplete()/onError(). +class WorkTask : public RefCnt +{ +public: + virtual ~WorkTask() = default; + + /// Perform the work. Called on worker thread (or main thread if no + /// threading). Return true on success, false on failure (set + /// m_errorMessage before returning false). + virtual bool execute() = 0; + + /// Called on the main thread after execute() returns true. + virtual void onComplete() {} + + /// Called on the main thread after execute() returns false. + virtual void onError(const std::string& error) {} + + /// Called when the task is cancelled (e.g. Lua state closing). + virtual void onCancel() {} + + WorkStatus status() const { return m_status; } + void setStatus(WorkStatus s) { m_status = s; } + + bool isCancelled() const + { + return m_cancelled.load(std::memory_order_acquire); + } + void cancel() { m_cancelled.store(true, std::memory_order_release); } + + const std::string& errorMessage() const { return m_errorMessage; } + + uint64_t ownerId() const { return m_ownerId; } + void setOwnerId(uint64_t id) { m_ownerId = id; } + + uint64_t submitGeneration() const { return m_submitGeneration; } + void setSubmitGeneration(uint64_t gen) { m_submitGeneration = gen; } + +protected: + std::string m_errorMessage; + +private: + WorkStatus m_status = WorkStatus::Pending; + std::atomic m_cancelled{false}; + uint64_t m_ownerId = 0; + uint64_t m_submitGeneration = 0; +}; + +} // namespace rive diff --git a/thirdparty/rive/include/rive/audio/audio_engine.hpp b/thirdparty/rive/include/rive/audio/audio_engine.hpp index 3d9ef8829..a790ff5e3 100644 --- a/thirdparty/rive/include/rive/audio/audio_engine.hpp +++ b/thirdparty/rive/include/rive/audio/audio_engine.hpp @@ -33,12 +33,16 @@ class AudioEngine : public RefCnt static rcp Make(uint32_t numChannels, uint32_t sampleRate); + static rcp MakeAndStore(uint32_t numChannels, + uint32_t sampleRate); + ma_device* device() { return m_device; } ma_engine* engine() { return m_engine; } uint32_t channels() const; uint32_t sampleRate() const; uint64_t timeInFrames(); + float timeInSeconds(); ~AudioEngine(); rcp play(rcp source, @@ -46,6 +50,11 @@ class AudioEngine : public RefCnt uint64_t endTime, uint64_t soundStartTime, Artboard* artboard = nullptr); + rcp playSeconds(rcp source, + float startTime, + uint64_t endTime, + uint64_t soundStartTime, + Artboard* artboard = nullptr); static rcp RuntimeEngine(bool makeWhenNecessary = true); @@ -68,6 +77,7 @@ class AudioEngine : public RefCnt #ifdef TESTING size_t playingSoundCount(); + rcp playingSoundsHead(); #endif private: AudioEngine(ma_engine* engine, ma_context* context); @@ -75,9 +85,15 @@ class AudioEngine : public RefCnt ma_engine* m_engine; ma_context* m_context; std::mutex m_mutex; + rcp internalPlaySound(rcp source, + uint64_t duration, + uint64_t endTime, + uint64_t soundStartTime, + Artboard* artboard = nullptr); void soundCompleted(rcp sound); void unlinkSound(rcp sound); + rcp initializeAudioSound(rcp); std::vector> m_completedSounds; rcp m_playingSoundsHead; diff --git a/thirdparty/rive/include/rive/audio/audio_sound.hpp b/thirdparty/rive/include/rive/audio/audio_sound.hpp index 754008ec4..a82709c34 100644 --- a/thirdparty/rive/include/rive/audio/audio_sound.hpp +++ b/thirdparty/rive/include/rive/audio/audio_sound.hpp @@ -109,8 +109,14 @@ class AudioSound : public RefCnt public: bool seek(uint64_t timeInFrames); + bool seekSeconds(float timeInSeconds); + uint64_t timeInFrames(); + float timeInSeconds(); ~AudioSound(); void stop(uint64_t fadeTimeInFrames = 0); + void play(); + void pause(); + void resume(); float volume(); void volume(float value); bool completed() const; diff --git a/thirdparty/rive/include/rive/audio/audio_source.hpp b/thirdparty/rive/include/rive/audio/audio_source.hpp index 9ddf49a93..eb42b39b7 100644 --- a/thirdparty/rive/include/rive/audio/audio_source.hpp +++ b/thirdparty/rive/include/rive/audio/audio_source.hpp @@ -14,6 +14,13 @@ class AudioSound; class AudioSource : public RefCnt { public: + // Validates the bytes before passing through to constructor. Returns + // nullptr if fails + static rcp MakeAudioSource(rive::Span fileBytes); + // Validates the bytes before passing through to constructor. Returns + // nullptr if fails + static rcp MakeAudioSource( + rive::SimpleArray fileBytes); // Makes an audio source that does not own it's backing bytes. AudioSource(rive::Span fileBytes); @@ -33,6 +40,11 @@ class AudioSource : public RefCnt uint32_t channels(); uint32_t sampleRate(); +#ifdef WITH_RIVE_AUDIO + float duration(); +#else + float duration() { return 0; } +#endif AudioFormat format() const; const rive::Span bytes() const { @@ -58,6 +70,7 @@ class AudioSource : public RefCnt bool m_isBuffered; uint32_t m_channels; uint32_t m_sampleRate; + float m_duration; rive::Span m_fileBytes; rive::SimpleArray m_ownedBytes; #endif diff --git a/thirdparty/rive/include/rive/audio_event.hpp b/thirdparty/rive/include/rive/audio_event.hpp index 2844e9c68..23ddf25cb 100644 --- a/thirdparty/rive/include/rive/audio_event.hpp +++ b/thirdparty/rive/include/rive/audio_event.hpp @@ -10,13 +10,13 @@ class AudioEvent : public AudioEventBase, public FileAssetReferencer { public: StatusCode import(ImportStack& importStack) override; - void setAsset(FileAsset* asset) override; + void setAsset(rcp asset) override; uint32_t assetId() override; void trigger(const CallbackData& value) override; void play(); #ifdef TESTING - AudioAsset* asset() const { return (AudioAsset*)m_fileAsset; } + AudioAsset* asset() const; #endif Core* clone() const override; }; diff --git a/thirdparty/rive/include/rive/bindable_artboard.hpp b/thirdparty/rive/include/rive/bindable_artboard.hpp new file mode 100644 index 000000000..fac7888fa --- /dev/null +++ b/thirdparty/rive/include/rive/bindable_artboard.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_BINDABLE_ARTBOARD_HPP_ +#define _RIVE_BINDABLE_ARTBOARD_HPP_ +#include "rive/refcnt.hpp" +#include "rive/file.hpp" +#include "rive/artboard.hpp" + +namespace rive +{ + +class BindableArtboard : public RefCnt +{ +public: + BindableArtboard(rcp file, + std::unique_ptr artboard); + ArtboardInstance* artboard() { return m_artboard.get(); } + +private: + rcp m_file; + std::unique_ptr m_artboard; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/command_queue.hpp b/thirdparty/rive/include/rive/command_queue.hpp index b69e4a30c..41d601467 100644 --- a/thirdparty/rive/include/rive/command_queue.hpp +++ b/thirdparty/rive/include/rive/command_queue.hpp @@ -7,6 +7,7 @@ #include "rive/object_stream.hpp" #include "rive/refcnt.hpp" #include "rive/math/vec2d.hpp" +#include "rive/viewmodel/runtime/viewmodel_runtime.hpp" #include #include @@ -39,15 +40,25 @@ class ArtboardInstance; class StateMachineInstance; class CommandServer; +RIVE_DEFINE_HANDLE(FontHandle); RIVE_DEFINE_HANDLE(FileHandle); RIVE_DEFINE_HANDLE(ArtboardHandle); +RIVE_DEFINE_HANDLE(AudioSourceHandle); +RIVE_DEFINE_HANDLE(RenderImageHandle); RIVE_DEFINE_HANDLE(StateMachineHandle); +RIVE_DEFINE_HANDLE(ViewModelInstanceHandle); RIVE_DEFINE_HANDLE(DrawKey); // Function poimter that gets called back from the server thread. using CommandServerCallback = std::function; using CommandServerDrawCallback = std::function; +struct ViewModelEnum +{ + std::string name; + std::vector enumerants; +}; + // Client-side recorder for commands that will be executed by a // CommandServer. class CommandQueue : public RefCnt @@ -92,21 +103,137 @@ class CommandQueue : public RefCnt : public CommandQueue::ListenerBase { public: + virtual void onFileError(const FileHandle, + uint64_t requestId, + std::string error) + {} + virtual void onFileDeleted(const FileHandle, uint64_t requestId) {} + virtual void onFileLoaded(const FileHandle, uint64_t requestId) {} + + virtual void onArtboardInstantiated(const FileHandle, + uint64_t requestId, + ArtboardHandle) + {} + + virtual void onViewModelInstanceInstantiated(const FileHandle, + uint64_t requestId, + ViewModelInstanceHandle) + {} + virtual void onArtboardsListed(const FileHandle, uint64_t requestId, std::vector artboardNames) {} + + virtual void onViewModelsListed(const FileHandle, + uint64_t requestId, + std::vector viewModelNames) + {} + + virtual void onViewModelInstanceNamesListed( + const FileHandle, + uint64_t requestId, + std::string viewModelName, + std::vector instanceNames) + {} + + struct ViewModelPropertyData + { + DataType type = DataType::none; + std::string name = ""; + std::string metaData = ""; + }; + + virtual void onViewModelPropertiesListed( + const FileHandle, + uint64_t requestId, + std::string viewModelName, + std::vector properties) + {} + + virtual void onViewModelEnumsListed(const FileHandle, + uint64_t requestId, + std::vector enums) + {} + }; + + class RenderImageListener + : public CommandQueue::ListenerBase + { + public: + virtual void onRenderImageDecoded(const RenderImageHandle, + uint64_t requestId) + {} + + virtual void onRenderImageError(const RenderImageHandle, + uint64_t requestId, + std::string error) + {} + + virtual void onRenderImageDeleted(const RenderImageHandle, + uint64_t requestId) + {} + }; + + class AudioSourceListener + : public CommandQueue::ListenerBase + { + public: + virtual void onAudioSourceDecoded(const AudioSourceHandle, + uint64_t requestId) + {} + + virtual void onAudioSourceError(const AudioSourceHandle, + uint64_t requestId, + std::string error) + {} + + virtual void onAudioSourceDeleted(const AudioSourceHandle, + uint64_t requestId) + {} + }; + + class FontListener + : public CommandQueue::ListenerBase + { + public: + virtual void onFontDecoded(const FontHandle, uint64_t requestId) {} + + virtual void onFontError(const FontHandle, + uint64_t requestId, + std::string error) + {} + + virtual void onFontDeleted(const FontHandle, uint64_t requestId) {} }; class ArtboardListener : public CommandQueue::ListenerBase { public: + virtual void onArtboardError(const ArtboardHandle, + uint64_t requestId, + std::string error) + {} + + virtual void onDefaultViewModelInfoReceived(const ArtboardHandle, + uint64_t requestId, + std::string viewModelName, + std::string instanceName) + {} + virtual void onArtboardDeleted(const ArtboardHandle, uint64_t requestId) {} + virtual void onStateMachineInstantiated(const ArtboardHandle, + uint64_t requestId, + StateMachineHandle) + {} + virtual void onStateMachinesListed( const ArtboardHandle, uint64_t requestId, @@ -114,11 +241,71 @@ class CommandQueue : public RefCnt {} }; + struct ViewModelInstanceData + { + // The path and type of this property + PropertyData metaData; + + // The specific value of this property, you must use the correct union + // member base on type in metaData, both enumType and string use + // stringValue + + // std::string is non trival, so it stays outside the union + std::string stringValue; + union + { + bool boolValue; + float numberValue; + ColorInt colorValue; + }; + }; + + class ViewModelInstanceListener + : public CommandQueue::ListenerBase + { + public: + virtual void onViewModelInstanceViewModelNameReceived( + const ViewModelInstanceHandle, + uint64_t requestId, + std::string viewModelName) + {} + virtual void onViewModelInstanceError(const ViewModelInstanceHandle, + uint64_t requestId, + std::string error) + {} + + virtual void onViewModelDeleted(const ViewModelInstanceHandle, + uint64_t requestId) + {} + + virtual void onViewModelDataReceived(const ViewModelInstanceHandle, + uint64_t requestId, + ViewModelInstanceData) + {} + + virtual void onViewModelListSizeReceived(const ViewModelInstanceHandle, + uint64_t requestId, + std::string path, + size_t size) + {} + + virtual void onViewModelListCleared(const ViewModelInstanceHandle, + uint64_t requestId, + std::string path) + {} + }; + class StateMachineListener : public CommandQueue::ListenerBase { public: + virtual void onStateMachineError(const StateMachineHandle, + uint64_t requestId, + std::string error) + {} + virtual void onStateMachineDeleted(const StateMachineHandle, uint64_t requestId) {} @@ -133,19 +320,25 @@ class CommandQueue : public RefCnt ~CommandQueue(); FileHandle loadFile(std::vector rivBytes, - rcp, FileListener* listener = nullptr, uint64_t requestId = 0); - FileHandle loadFile(std::vector rivBytes, - FileListener* listener = nullptr, - uint64_t requestId = 0) - { - return loadFile(std::move(rivBytes), nullptr, listener, requestId); - } - void deleteFile(FileHandle, uint64_t requestId = 0); + void addGlobalImageAsset(std::string name, + RenderImageHandle, + uint64_t requestId = 0); + void addGlobalFontAsset(std::string name, + FontHandle, + uint64_t requestId = 0); + void addGlobalAudioAsset(std::string name, + AudioSourceHandle, + uint64_t requestId = 0); + + void removeGlobalImageAsset(std::string name, uint64_t requestId = 0); + void removeGlobalFontAsset(std::string name, uint64_t requestId = 0); + void removeGlobalAudioAsset(std::string name, uint64_t requestId = 0); + ArtboardHandle instantiateArtboardNamed( FileHandle, std::string name, @@ -159,8 +352,173 @@ class CommandQueue : public RefCnt return instantiateArtboardNamed(fileHandle, "", listener, requestId); } + void setArtboardSize(ArtboardHandle, + float width, + float height, + float scale = 1, + uint64_t requestId = 0); + + void resetArtboardSize(ArtboardHandle, uint64_t requestId = 0); + void deleteArtboard(ArtboardHandle, uint64_t requestId = 0); + ViewModelInstanceHandle instantiateBlankViewModelInstance( + FileHandle fileHandle, + ArtboardHandle artboardHandle, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0); + + ViewModelInstanceHandle instantiateBlankViewModelInstance( + FileHandle fileHandle, + std::string viewModelName, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0); + + ViewModelInstanceHandle instantiateDefaultViewModelInstance( + FileHandle fileHandle, + ArtboardHandle artboardHandle, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0) + { + return instantiateViewModelInstanceNamed(fileHandle, + artboardHandle, + "", + listener, + requestId); + } + + ViewModelInstanceHandle instantiateDefaultViewModelInstance( + FileHandle fileHandle, + std::string viewModelName, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0) + { + return instantiateViewModelInstanceNamed(fileHandle, + viewModelName, + "", + listener, + requestId); + } + + ViewModelInstanceHandle instantiateViewModelInstanceNamed( + FileHandle, + ArtboardHandle, + std::string viewModelInstanceName, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0); + + ViewModelInstanceHandle instantiateViewModelInstanceNamed( + FileHandle, + std::string viewModelName, + std::string viewModelInstanceName, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0); + + ViewModelInstanceHandle referenceNestedViewModelInstance( + ViewModelInstanceHandle, + std::string path, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0); + + ViewModelInstanceHandle referenceListViewModelInstance( + ViewModelInstanceHandle, + std::string path, + int index, + ViewModelInstanceListener* listener = nullptr, + uint64_t requestId = 0); + + void fireViewModelTrigger(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void setViewModelInstanceBool(ViewModelInstanceHandle, + std::string path, + bool value, + uint64_t requestId = 0); + void setViewModelInstanceNumber(ViewModelInstanceHandle, + std::string path, + float value, + uint64_t requestId = 0); + void setViewModelInstanceColor(ViewModelInstanceHandle, + std::string path, + ColorInt value, + uint64_t requestId = 0); + void setViewModelInstanceEnum(ViewModelInstanceHandle, + std::string path, + std::string value, + uint64_t requestId = 0); + void setViewModelInstanceString(ViewModelInstanceHandle, + std::string path, + std::string value, + uint64_t requestId = 0); + void setViewModelInstanceImage(ViewModelInstanceHandle, + std::string path, + RenderImageHandle value, + uint64_t requestId = 0); + void setViewModelInstanceArtboard(ViewModelInstanceHandle, + std::string path, + ArtboardHandle value, + uint64_t requestId = 0); + void setViewModelInstanceNestedViewModel(ViewModelInstanceHandle, + std::string path, + ViewModelInstanceHandle value, + uint64_t requestId = 0); + void insertViewModelInstanceListViewModel(ViewModelInstanceHandle, + std::string path, + ViewModelInstanceHandle value, + int index, + uint64_t requestId = 0); + + void appendViewModelInstanceListViewModel(ViewModelInstanceHandle handle, + std::string path, + ViewModelInstanceHandle value, + uint64_t requestId = 0) + { + insertViewModelInstanceListViewModel(handle, + std::move(path), + value, + -1, + requestId); + } + + void removeViewModelInstanceListViewModel( + ViewModelInstanceHandle, + std::string path, + int index, + ViewModelInstanceHandle value = RIVE_NULL_HANDLE, + uint64_t requestId = 0); + + void removeViewModelInstanceListViewModel(ViewModelInstanceHandle handle, + std::string path, + ViewModelInstanceHandle value, + uint64_t requestId = 0) + { + removeViewModelInstanceListViewModel(handle, + std::move(path), + -1, + value, + requestId); + } + + void swapViewModelInstanceListValues(ViewModelInstanceHandle handle, + std::string path, + int indexa, + int indexb, + uint64_t requestId = 0); + + void subscribeToViewModelProperty(ViewModelInstanceHandle handle, + std::string path, + DataType type, + uint64_t requestId = 0); + + void unsubscribeToViewModelProperty(ViewModelInstanceHandle handle, + std::string path, + DataType type, + uint64_t requestId = 0); + + void deleteViewModelInstance(ViewModelInstanceHandle, + uint64_t requestId = 0); + StateMachineHandle instantiateStateMachineNamed( ArtboardHandle, std::string name, @@ -177,18 +535,66 @@ class CommandQueue : public RefCnt requestId); } + void bindViewModelInstance(StateMachineHandle, + ViewModelInstanceHandle, + uint64_t requestId = 0); + void advanceStateMachine(StateMachineHandle, float timeToAdvance, uint64_t requestId = 0); // Pointer events - void pointerMove(StateMachineHandle, Vec2D position); - void pointerDown(StateMachineHandle, Vec2D position); - void pointerUp(StateMachineHandle, Vec2D position); - void pointerExit(StateMachineHandle, Vec2D position); + struct PointerEvent + { + Fit fit = Fit::none; // the fit the artboard is drawn with + Alignment alignment; // the alignment the artboard is drawn with + Vec2D screenBounds; // the bounds of coordinate system of the cursor + Vec2D position; // the cursor position + float scaleFactor = 1.0f; // scale factor for things like retina display + int pointerId = 0; // stable pointer identifier for multitouch + }; + + // All pointer events will automatically convert between artboard and screen + // space for you based on the values passed in the PointerEvent struct. + + void pointerMove(StateMachineHandle, PointerEvent, uint64_t requestId = 0); + void pointerDown(StateMachineHandle, PointerEvent, uint64_t requestId = 0); + void pointerUp(StateMachineHandle, PointerEvent, uint64_t requestId = 0); + void pointerExit(StateMachineHandle, PointerEvent, uint64_t requestId = 0); void deleteStateMachine(StateMachineHandle, uint64_t requestId = 0); + RenderImageHandle decodeImage(std::vector imageEncodedBytes, + RenderImageListener* listener = nullptr, + uint64_t requestId = 0); + // This is needed for unreal rhi because all images come pre-decoded and + // uploaded to gpu. + RenderImageHandle addExternalImage(rcp externalImage, + RenderImageListener* listener = nullptr, + uint64_t requestId = 0); + + void deleteImage(RenderImageHandle, uint64_t requestId = 0); + + AudioSourceHandle decodeAudio(std::vector imageEncodedBytes, + AudioSourceListener* listener = nullptr, + uint64_t requestId = 0); + + AudioSourceHandle addExternalAudio(rcp externalAudio, + AudioSourceListener* listener = nullptr, + uint64_t requestId = 0); + + void deleteAudio(AudioSourceHandle, uint64_t requestId = 0); + + FontHandle decodeFont(std::vector imageEncodedBytes, + FontListener* listener = nullptr, + uint64_t requestId = 0); + + FontHandle addExternalFont(rcp externalFont, + FontListener* listener = nullptr, + uint64_t requestId = 0); + + void deleteFont(FontHandle, uint64_t requestId = 0); + // Create unique draw key for draw. DrawKey createDrawKey(); @@ -200,6 +606,10 @@ class CommandQueue : public RefCnt // will be run per pollCommands. void draw(DrawKey, CommandServerDrawCallback); + // Cancel a pending draw for the given key if it has already been admitted + // to the current coalesced draw batch. + void cancelDraw(DrawKey); + #ifdef TESTING // Sends a commandLoopBreak command to the server. This will cause the // processCommands to return even if there are more commands to consume. @@ -207,7 +617,6 @@ class CommandQueue : public RefCnt // return. To continue processing commands, another call to processCommands // is required. void testing_commandLoopBreak(); - FileListener* testing_getFileListener(FileHandle); ArtboardListener* testing_getArtboardListener(ArtboardHandle); StateMachineListener* testing_getStateMachineListener(StateMachineHandle); @@ -215,12 +624,84 @@ class CommandQueue : public RefCnt void disconnect(); + void requestViewModelNames(FileHandle, uint64_t requestId = 0); void requestArtboardNames(FileHandle, uint64_t requestId = 0); + void requestViewModelInstanceViewModelName(ViewModelInstanceHandle, + uint64_t requestId = 0); + void requestViewModelEnums(FileHandle, uint64_t requestId = 0); + void requestViewModelPropertyDefinitions(FileHandle, + std::string viewModelName, + uint64_t requestId = 0); + + void requestViewModelInstanceNames(FileHandle, + std::string viewModelName, + uint64_t requestId = 0); + + void requestViewModelInstanceBool(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void requestViewModelInstanceNumber(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void requestViewModelInstanceColor(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void requestViewModelInstanceEnum(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void requestViewModelInstanceString(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void requestViewModelInstanceListSize(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + + void requestViewModelInstanceListClear(ViewModelInstanceHandle, + std::string path, + uint64_t requestId = 0); + void requestStateMachineNames(ArtboardHandle, uint64_t requestId = 0); + void requestDefaultViewModelInfo(ArtboardHandle, + FileHandle, + uint64_t requestId = 0); // Consume all messages received from the server. void processMessages(); + void setGlobalFileListener(FileListener* listener) + { + m_globalFileListener = listener; + } + void setGlobalArtboardListener(ArtboardListener* listener) + { + m_globalArtboardListener = listener; + } + void setGlobalStateMachineListener(StateMachineListener* listener) + { + m_globalStateMachineListener = listener; + } + void setGlobalViewModelInstanceListener(ViewModelInstanceListener* listener) + { + m_globalViewModelListener = listener; + } + void setGlobalRenderImageListener(RenderImageListener* listener) + { + m_globalImageListener = listener; + } + void setGlobalAudioSourceListener(AudioSourceListener* listener) + { + m_globalAudioListener = listener; + } + void setGlobalFontListener(FontListener* listener) + { + m_globalFontListener = listener; + } + private: void registerListener(FileHandle handle, FileListener* listener) { @@ -229,6 +710,29 @@ class CommandQueue : public RefCnt m_fileListeners.insert({handle, listener}); } + void registerListener(RenderImageHandle handle, + RenderImageListener* listener) + { + assert(listener); + assert(m_imageListeners.find(handle) == m_imageListeners.end()); + m_imageListeners.insert({handle, listener}); + } + + void registerListener(AudioSourceHandle handle, + AudioSourceListener* listener) + { + assert(listener); + assert(m_audioListeners.find(handle) == m_audioListeners.end()); + m_audioListeners.insert({handle, listener}); + } + + void registerListener(FontHandle handle, FontListener* listener) + { + assert(listener); + assert(m_fontListeners.find(handle) == m_fontListeners.end()); + m_fontListeners.insert({handle, listener}); + } + void registerListener(ArtboardHandle handle, ArtboardListener* listener) { assert(listener); @@ -236,6 +740,14 @@ class CommandQueue : public RefCnt m_artboardListeners.insert({handle, listener}); } + void registerListener(ViewModelInstanceHandle handle, + ViewModelInstanceListener* listener) + { + assert(listener); + assert(m_viewModelListeners.find(handle) == m_viewModelListeners.end()); + m_viewModelListeners.insert({handle, listener}); + } + void registerListener(StateMachineHandle handle, StateMachineListener* listener) { @@ -254,11 +766,34 @@ class CommandQueue : public RefCnt m_fileListeners.erase(handle); } + void unregisterListener(RenderImageHandle handle, + RenderImageListener* listener) + { + m_imageListeners.erase(handle); + } + + void unregisterListener(AudioSourceHandle handle, + AudioSourceListener* listener) + { + m_audioListeners.erase(handle); + } + + void unregisterListener(FontHandle handle, FontListener* listener) + { + m_fontListeners.erase(handle); + } + void unregisterListener(ArtboardHandle handle, ArtboardListener* listener) { m_artboardListeners.erase(handle); } + void unregisterListener(ViewModelInstanceHandle handle, + ViewModelInstanceListener* listener) + { + m_viewModelListeners.erase(handle); + } + void unregisterListener(StateMachineHandle handle, StateMachineListener* listener) { @@ -269,13 +804,45 @@ class CommandQueue : public RefCnt { loadFile, deleteFile, + decodeImage, + externalImage, + decodeAudio, + externalAudio, + decodeFont, + externalFont, + deleteImage, + deleteAudio, + deleteFont, + addImageFileAsset, + addAudioFileAsset, + addFontFileAsset, + removeImageFileAsset, + removeAudioFileAsset, + removeFontFileAsset, instantiateArtboard, deleteArtboard, + setArtboardSize, + resetArtboardSize, + instantiateViewModel, + refNestedViewModel, + refListViewModel, + instantiateBlankViewModel, + instantiateViewModelForArtboard, + instantiateBlankViewModelForArtboard, + setViewModelInstanceValue, + addViewModelListValue, + removeViewModelListValue, + swapViewModelListValue, + subscribeViewModelProperty, + unsubscribeViewModelProperty, + deleteViewModel, instantiateStateMachine, deleteStateMachine, advanceStateMachine, + bindViewModelInstance, runOnce, draw, + cancelDraw, pointerMove, pointerDown, pointerUp, @@ -286,33 +853,78 @@ class CommandQueue : public RefCnt // how we achieve that. commandLoopBreak, // messages + listViewModelEnums, listArtboards, - listStateMachines + listStateMachines, + getDefaultViewModel, + listViewModels, + listViewModelInstanceNames, + listViewModelProperties, + listViewModelPropertyValue, + getViewModelInstanceViewModelName, + getViewModelListSize, + clearViewModelList }; enum class Message { // Same as commandLoopBreak for processMessages messageLoopBreak, + viewModelEnumsListed, artboardsListed, stateMachinesListed, + defaultViewModelReceived, + viewModelInstanceViewModelNameReceived, + viewModelsListend, + viewModelInstanceNamesListed, + viewModelPropertiesListed, + viewModelPropertyValueReceived, + viewModelListSizeReceived, + viewModelListCleared, + fileLoaded, fileDeleted, + artboardInstantiated, + stateMachineInstantiated, + viewModelInstanceInstantiated, + imageDecoded, + imageDeleted, + audioDecoded, + audioDeleted, + fontDecoded, + fontDeleted, artboardDeleted, + viewModelDeleted, stateMachineDeleted, - stateMachineSettled + stateMachineSettled, + fileError, + artboardError, + viewModelError, + imageError, + audioError, + fontError, + stateMachineError }; friend class CommandServer; uint64_t m_currentFileHandleIdx = 0; + uint64_t m_currentListHandleIdx = 0; + uint64_t m_currentFontHandleIdx = 0; uint64_t m_currentArtboardHandleIdx = 0; + uint64_t m_currentViewModelHandleIdx = 0; + uint64_t m_currentRenderImageHandleIdx = 0; + uint64_t m_currentAudioSourceHandleIdx = 0; uint64_t m_currentStateMachineHandleIdx = 0; uint64_t m_currentDrawKeyIdx = 0; std::mutex m_commandMutex; std::condition_variable m_commandConditionVariable; PODStream m_commandStream; + ObjectStream> m_externalImages; + ObjectStream> m_externalAudioSources; + ObjectStream> m_externalFonts; ObjectStream> m_byteVectors; + ObjectStream m_pointerEvents; ObjectStream m_names; ObjectStream m_callbacks; ObjectStream m_drawCallbacks; @@ -323,8 +935,23 @@ class CommandQueue : public RefCnt ObjectStream m_messageNames; // Listeners + FileListener* m_globalFileListener = nullptr; + RenderImageListener* m_globalImageListener = nullptr; + AudioSourceListener* m_globalAudioListener = nullptr; + FontListener* m_globalFontListener = nullptr; + ArtboardListener* m_globalArtboardListener = nullptr; + ViewModelInstanceListener* m_globalViewModelListener = nullptr; + StateMachineListener* m_globalStateMachineListener = nullptr; + std::unordered_map m_fileListeners; + std::unordered_map + m_imageListeners; + std::unordered_map + m_audioListeners; + std::unordered_map m_fontListeners; std::unordered_map m_artboardListeners; + std::unordered_map + m_viewModelListeners; std::unordered_map m_stateMachineListeners; }; diff --git a/thirdparty/rive/include/rive/command_server.hpp b/thirdparty/rive/include/rive/command_server.hpp index 9212e8c5d..5a3cc3694 100644 --- a/thirdparty/rive/include/rive/command_server.hpp +++ b/thirdparty/rive/include/rive/command_server.hpp @@ -5,25 +5,46 @@ #pragma once #include "rive/command_queue.hpp" +#include "rive/hit_result.hpp" +#include +#include #include #include +#include namespace rive { + // Server-side worker that executes commands from a CommandQueue. class CommandServer { public: - CommandServer(rcp, Factory*); + CommandServer(rcp, + Factory*, + rcp = nullptr); virtual ~CommandServer(); Factory* factory() const { return m_factory; } + rive::HitResult pointerDownSynchronized(StateMachineHandle, + const CommandQueue::PointerEvent&); + rive::HitResult pointerMoveSynchronized(StateMachineHandle, + const CommandQueue::PointerEvent&); + rive::HitResult pointerUpSynchronized(StateMachineHandle, + const CommandQueue::PointerEvent&); + File* getFile(FileHandle) const; bool getWasDisconnected() const { return m_wasDisconnectReceived; } - + RenderImage* getImage(RenderImageHandle) const; + AudioSource* getAudioSource(AudioSourceHandle) const; + Font* getFont(FontHandle) const; ArtboardInstance* getArtboardInstance(ArtboardHandle) const; + rcp getBindableArtboard(ArtboardHandle) const; StateMachineInstance* getStateMachineInstance(StateMachineHandle) const; + ViewModelInstanceRuntime* getViewModelInstance( + ViewModelInstanceHandle) const; + ViewModelInstanceHandle getHandleForInstance( + ViewModelInstanceRuntime*) const; // Wait for queue to not be empty, then returns pollMessages. bool waitCommands(); // Returns imidiatly after checking messages. If there are none just returns @@ -32,23 +53,201 @@ class CommandServer // Blocks and runs waitMessages until disconnect is received. void serveUntilDisconnect(); + struct Subscription + { + // The request Id for sbuscribing to this particular property. + uint64_t requestId; + // Information about the property we want to "subsribe" to. + PropertyData data; + // The root view model of from the perspective of the path in data.name. + ViewModelInstanceHandle rootViewModel; + }; + +#ifdef TESTING + // Expose cursorPosForPointerEvent for testing. + Vec2D testing_cursorPosForPointerEvent(StateMachineInstance* instance, + CommandQueue::PointerEvent event) + { + return cursorPosForPointerEvent(instance, event); + } + + const std::vector& testing_getSubsciptions() const + { + return m_propertySubscriptions; + } + + RenderImageHandle testing_globalImageNamed(std::string name); + AudioSourceHandle testing_globalAudioNamed(std::string name); + FontHandle testing_globalFontNamed(std::string name); + + bool testing_globalImageContains(std::string name); + bool testing_globalAudioContains(std::string name); + bool testing_globalFontContains(std::string name); + +#ifndef NDEBUG + // Used because "sync pointer events" test needs to be able to + // make the server on one thread but access it from another + void testing_overrideThreadID(std::thread::id threadID) + { + m_threadID = threadID; + } +#endif +#endif + private: friend class CommandQueue; + template class ErrorReporter + { + public: + ErrorReporter(CommandServer* server, + HandleType handle, + uint64_t requestId, + CommandQueue::Message message) : + m_server(server), m_lock(m_server->m_commandQueue->m_messageMutex) + { + assert(server); + assert(message >= CommandQueue::Message::fileError && + message <= CommandQueue::Message::stateMachineError); + + std::cerr << "ERROR : "; + m_server->m_commandQueue->m_messageStream << message; + m_server->m_commandQueue->m_messageStream << handle; + m_server->m_commandQueue->m_messageStream << requestId; + } + + ErrorReporter& operator<<(std::vector vector) + { + m_ostringstream << "{ "; + for (auto& s : vector) + m_ostringstream << s << ","; + m_ostringstream << "} "; + return *this; + } + + template ErrorReporter& operator<<(const T& t) + { + m_ostringstream << t; + return *this; + } + + ~ErrorReporter() + { + std::string str = m_ostringstream.str(); + assert(!str.empty()); + std::cerr << str << "\n"; + m_server->m_commandQueue->m_messageNames << std::move(str); + } + + CommandServer* m_server; + std::unique_lock m_lock; + std::ostringstream m_ostringstream; + }; + + void checkPropertySubscriptions(); + + Vec2D cursorPosForPointerEvent(StateMachineInstance*, + const CommandQueue::PointerEvent&); + + void cleanupArtboard(ArtboardHandle handle, uint64_t requestId) + { + auto itr = m_artboards.find(handle); + if (itr != m_artboards.end()) + { + auto dependencyItr = m_artboardDependencies.find(handle); + if (dependencyItr != m_artboardDependencies.end()) + { + auto& stateMachineVector = dependencyItr->second; + for (auto stateMachine : stateMachineVector) + { + if (m_stateMachines.erase(stateMachine) > 0) + { + std::unique_lock lock( + m_commandQueue->m_messageMutex); + m_commandQueue->m_messageStream + << CommandQueue::Message::stateMachineDeleted; + m_commandQueue->m_messageStream << stateMachine; + m_commandQueue->m_messageStream << requestId; + } + } + + m_artboardDependencies.erase(dependencyItr); + } + m_artboards.erase(itr); + std::unique_lock lock(m_commandQueue->m_messageMutex); + m_commandQueue->m_messageStream + << CommandQueue::Message::artboardDeleted; + m_commandQueue->m_messageStream << handle; + m_commandQueue->m_messageStream << requestId; + } + } + + struct SynchronizedStateMachine : RefCnt + { + // kept in seperate header to avoid including StateMachineInstance in + // the main CommandServer header + ~SynchronizedStateMachine(); + SynchronizedStateMachine& operator=(SynchronizedStateMachine&& other) + { + instance = std::move(other.instance); + return *this; + } + SynchronizedStateMachine() = default; + SynchronizedStateMachine( + std::unique_ptr instance) : + instance(std::move(instance)) + {} + std::unique_ptr instance; + // This mutex is used to ensure that a specific state machine instance + // is not being advanced at the same time a sync mouse event is being + // processed. + std::mutex m_mutex; + }; + + rcp getStateMachineWrapper( + StateMachineHandle handle); + bool m_wasDisconnectReceived = false; const rcp m_commandQueue; Factory* const m_factory; #ifndef NDEBUG +#ifdef TESTING + std::thread::id m_threadID; +#else const std::thread::id m_threadID; +#endif #endif - std::unordered_map> m_files; - std::unordered_map> - m_artboards; - std::unordered_map> + // Vector to iterate on for subscriptions. This is a vector instead of a map + // because we iterate through the entire vector every frame anyway. + std::vector m_propertySubscriptions; + + // Dependencies + // When a file gets deleted artboards and statemachine become invalid. Here + // we hold a reference to the artboard only because that artboard has a + // dependency to the State Machine. + std::unordered_map> + m_fileDependencies; + // When an artboard gets deleted the statemachine assosiated with it is also + // now invalid. + std::unordered_map> + m_artboardDependencies; + + // Handle Maps + std::unordered_map> m_files; + std::unordered_map> m_fonts; + std::unordered_map> m_images; + std::unordered_map> m_audioSources; + std::unordered_map> m_artboards; + std::unordered_map> + m_viewModels; + std::unordered_map> m_stateMachines; + std::mutex m_stateMachineAccessMutex; std::unordered_map m_uniqueDraws; + + class CommandFileAssetLoader; + rcp m_fileAssetLoader; }; }; // namespace rive diff --git a/thirdparty/rive/include/rive/component.hpp b/thirdparty/rive/include/rive/component.hpp index 9e1be4f45..78f5dd544 100644 --- a/thirdparty/rive/include/rive/component.hpp +++ b/thirdparty/rive/include/rive/component.hpp @@ -3,6 +3,7 @@ #include "rive/component_dirt.hpp" #include "rive/generated/component_base.hpp" #include "rive/dependency_helper.hpp" +#include "rive/math/vec2d.hpp" #include #include @@ -11,6 +12,7 @@ namespace rive { class ContainerComponent; class Artboard; +class DataBind; class Component : public ComponentBase { @@ -21,9 +23,11 @@ class Component : public ComponentBase unsigned int m_GraphOrder; Artboard* m_Artboard = nullptr; + std::vector m_collapsables; protected: ComponentDirt m_Dirt = ComponentDirt::Filthy; + void updateCollapsables(); public: DependencyHelper m_DependencyHelper; @@ -32,6 +36,7 @@ class Component : public ComponentBase bool validate(CoreContext* context) override; StatusCode onAddedDirty(CoreContext* context) override; inline ContainerComponent* parent() const { return m_Parent; } + void addCollapsable(DataBind* collapsable); const std::vector& dependents() const { return m_DependencyHelper.dependents(); @@ -64,6 +69,12 @@ class Component : public ComponentBase { return (m_Dirt & ComponentDirt::Collapsed) == ComponentDirt::Collapsed; } + virtual bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit); +#ifdef TESTING + ComponentDirt dirt() { return m_Dirt; } +#endif }; } // namespace rive diff --git a/thirdparty/rive/include/rive/component_dirt.hpp b/thirdparty/rive/include/rive/component_dirt.hpp index 68e5d6fd2..9fdd7389d 100644 --- a/thirdparty/rive/include/rive/component_dirt.hpp +++ b/thirdparty/rive/include/rive/component_dirt.hpp @@ -1,7 +1,7 @@ #ifndef _RIVE_DIRTY_FLAGS_HPP_ #define _RIVE_DIRTY_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { @@ -69,9 +69,15 @@ enum class ComponentDirt : unsigned short /// their render paths, mesh, points, etc. NSlicer = 1 << 13, + /// Set when a ScriptedObject needs to call update on the scripted + /// interface. + ScriptUpdate = 1 << 14, + + /// Clipping needs to be recalculated + Clipping = 1 << 15, + /// All dirty. Every flag (apart from Collapsed) is set. Filthy = 0xFFFE }; -RIVE_MAKE_ENUM_BITSET(ComponentDirt) } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/constraints/constrainable_list.hpp b/thirdparty/rive/include/rive/constraints/constrainable_list.hpp new file mode 100644 index 000000000..13fd3a273 --- /dev/null +++ b/thirdparty/rive/include/rive/constraints/constrainable_list.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_CONSTRAINABLE_LIST_HPP_ +#define _RIVE_CONSTRAINABLE_LIST_HPP_ +#include +#include +namespace rive +{ +class Component; +class ListConstraint; + +class ConstrainableList +{ +protected: + std::vector m_listConstraints; + +public: + static ConstrainableList* from(Component* component); + void addListConstraint(ListConstraint* constraint); + virtual const Mat2D& listTransform() = 0; + virtual void listItemTransforms(std::vector& transforms) = 0; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/constraints/constraint.hpp b/thirdparty/rive/include/rive/constraints/constraint.hpp index bb29fb216..40c3444ea 100644 --- a/thirdparty/rive/include/rive/constraints/constraint.hpp +++ b/thirdparty/rive/include/rive/constraints/constraint.hpp @@ -11,7 +11,7 @@ class Constraint : public ConstraintBase { public: void strengthChanged() override; - StatusCode onAddedClean(CoreContext* context) override; + StatusCode onAddedDirty(CoreContext* context) override; virtual void markConstraintDirty(); virtual void constrain(TransformComponent* component) = 0; void buildDependencies() override; diff --git a/thirdparty/rive/include/rive/constraints/draggable_constraint.hpp b/thirdparty/rive/include/rive/constraints/draggable_constraint.hpp index 778d99834..c748e791e 100644 --- a/thirdparty/rive/include/rive/constraints/draggable_constraint.hpp +++ b/thirdparty/rive/include/rive/constraints/draggable_constraint.hpp @@ -1,11 +1,16 @@ #ifndef _RIVE_DRAGGABLE_CONSTRAINT_HPP_ #define _RIVE_DRAGGABLE_CONSTRAINT_HPP_ #include "rive/generated/constraints/draggable_constraint_base.hpp" +#include "rive/animation/state_machine_listener.hpp" #include "rive/drawable.hpp" +#include "rive/listener_group.hpp" #include "rive/math/vec2d.hpp" +#include "rive/process_event_result.hpp" #include namespace rive { +class HitComponent; + enum class DraggableConstraintDirection : uint8_t { horizontal, @@ -21,13 +26,14 @@ class DraggableProxy public: virtual ~DraggableProxy() {} virtual bool isOpaque() { return false; } - virtual void startDrag(Vec2D mousePosition) = 0; - virtual void drag(Vec2D mousePosition) = 0; - virtual void endDrag(Vec2D mousePosition) = 0; + virtual bool startDrag(Vec2D mousePosition, float timeStamp = 0) = 0; + virtual bool drag(Vec2D mousePosition, float timeStamp = 0) = 0; + virtual bool endDrag(Vec2D mousePosition, float timeStamp = 0) = 0; Drawable* hittable() { return m_hittable; } }; -class DraggableConstraint : public DraggableConstraintBase +class DraggableConstraint : public DraggableConstraintBase, + public ListenerGroupProvider { public: DraggableConstraint() {} @@ -49,6 +55,52 @@ class DraggableConstraint : public DraggableConstraintBase return dir == DraggableConstraintDirection::vertical || dir == DraggableConstraintDirection::all; } + std::vector listenerGroups() override; + std::vector hitComponents(StateMachineInstance* sm) override + { + return {}; + } +}; + +class DraggableConstraintListenerGroup : public ListenerGroup +{ +public: + DraggableConstraintListenerGroup(const StateMachineListener* listener, + DraggableConstraint* constraint, + DraggableProxy* draggable) : + ListenerGroup(listener), + m_constraint(constraint), + m_draggable(draggable) + {} + ~DraggableConstraintListenerGroup() + { + delete listener(); + delete m_draggable; + } + + void enable(int pointerId = 0) override {} + void disable(int pointerId = 0) override {} + + DraggableConstraint* constraint() { return m_constraint; } + + bool canEarlyOut(Component* drawable) override { return false; } + + bool needsDownListener(Component* drawable) override { return true; } + + bool needsUpListener(Component* drawable) override { return true; } + ProcessEventResult processEvent( + Component* component, + Vec2D position, + int pointerId, + ListenerType hitEvent, + bool canHit, + float timeStamp, + StateMachineInstance* stateMachineInstance) override; + +private: + DraggableConstraint* m_constraint; + DraggableProxy* m_draggable; + bool m_hasScrolled = false; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/follow_path_constraint.hpp b/thirdparty/rive/include/rive/constraints/follow_path_constraint.hpp index 8c4344fdc..16c0e27a5 100644 --- a/thirdparty/rive/include/rive/constraints/follow_path_constraint.hpp +++ b/thirdparty/rive/include/rive/constraints/follow_path_constraint.hpp @@ -11,16 +11,19 @@ class FollowPathConstraint : public FollowPathConstraintBase void distanceChanged() override; void orientChanged() override; StatusCode onAddedClean(CoreContext* context) override; - const Mat2D targetTransform() const; + const Mat2D targetTransform(float distanceOffset = 1.0) const; void constrain(TransformComponent* component) override; void update(ComponentDirt value) override; void buildDependencies() override; +protected: + TransformComponents constrainHelper(const Mat2D& componentTransform, + Mat2D& transformB, + const Mat2D& componentParentWorld); + private: RawPath m_rawPath; PathMeasure m_pathMeasure; - TransformComponents m_ComponentsA; - TransformComponents m_ComponentsB; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/layout_constraint.hpp b/thirdparty/rive/include/rive/constraints/layout_constraint.hpp index 96b885b08..4cd0bc1f1 100644 --- a/thirdparty/rive/include/rive/constraints/layout_constraint.hpp +++ b/thirdparty/rive/include/rive/constraints/layout_constraint.hpp @@ -9,6 +9,8 @@ class LayoutConstraint { public: virtual void constrainChild(LayoutNodeProvider* child) {} + virtual void addLayoutChild(LayoutNodeProvider* child) {} + virtual Constraint* constraint() = 0; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/list_constraint.hpp b/thirdparty/rive/include/rive/constraints/list_constraint.hpp new file mode 100644 index 000000000..fe83d4e86 --- /dev/null +++ b/thirdparty/rive/include/rive/constraints/list_constraint.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_LIST_CONSTRAINT_HPP_ +#define _RIVE_LIST_CONSTRAINT_HPP_ +#include +namespace rive +{ +class ConstrainableList; + +class ListConstraint +{ +public: + static ListConstraint* from(Component* component); + virtual void constrainList(ConstrainableList* child) {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/constraints/list_follow_path_constraint.hpp b/thirdparty/rive/include/rive/constraints/list_follow_path_constraint.hpp new file mode 100644 index 000000000..71d647d1d --- /dev/null +++ b/thirdparty/rive/include/rive/constraints/list_follow_path_constraint.hpp @@ -0,0 +1,27 @@ +#ifndef _RIVE_LIST_FOLLOW_PATH_CONSTRAINT_HPP_ +#define _RIVE_LIST_FOLLOW_PATH_CONSTRAINT_HPP_ +#include "rive/constraints/list_constraint.hpp" +#include "rive/generated/constraints/list_follow_path_constraint_base.hpp" +#include +namespace rive +{ +class ConstrainableList; +class TransformComponents; + +class ListFollowPathConstraint : public ListFollowPathConstraintBase, + public ListConstraint +{ +public: + void distanceEndChanged() override; + void distanceOffsetChanged() override; + void constrainList(ConstrainableList* list) override; + void buildDependencies() override; + +private: + TransformComponents constrainAtOffset(const Mat2D& componentTransform, + const Mat2D& parentTransform, + float componentOffset); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/constraints/scrolling/clamped_scroll_physics.hpp b/thirdparty/rive/include/rive/constraints/scrolling/clamped_scroll_physics.hpp index f4ae3b80c..d961e4440 100644 --- a/thirdparty/rive/include/rive/constraints/scrolling/clamped_scroll_physics.hpp +++ b/thirdparty/rive/include/rive/constraints/scrolling/clamped_scroll_physics.hpp @@ -11,10 +11,13 @@ class ClampedScrollPhysics : public ClampedScrollPhysicsBase public: Vec2D advance(float elapsedSeconds) override; - void run(Vec2D range, + void run(Vec2D rangeMin, + Vec2D rangeMax, Vec2D value, - std::vector snappingPoints) override; - Vec2D clamp(Vec2D range, Vec2D value) override; + std::vector snappingPoints, + float contentSize, + float viewportSize) override; + Vec2D clamp(Vec2D rangeMin, Vec2D rangeMax, Vec2D value) override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/scrolling/elastic_scroll_physics.hpp b/thirdparty/rive/include/rive/constraints/scrolling/elastic_scroll_physics.hpp index f69da8591..39e1ebdcf 100644 --- a/thirdparty/rive/include/rive/constraints/scrolling/elastic_scroll_physics.hpp +++ b/thirdparty/rive/include/rive/constraints/scrolling/elastic_scroll_physics.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_ELASTIC_SCROLL_PHYSICS_HPP_ #define _RIVE_ELASTIC_SCROLL_PHYSICS_HPP_ #include "rive/generated/constraints/scrolling/elastic_scroll_physics_base.hpp" +#include #include namespace rive { @@ -14,7 +15,9 @@ class ElasticScrollPhysicsHelper float m_target = 0; float m_current = 0; float m_speed = 0; - float m_runRange = 0; + float m_snapTarget = NAN; + float m_runRangeMin = 0; + float m_runRangeMax = 0; bool m_isRunning = false; public: @@ -28,22 +31,29 @@ class ElasticScrollPhysicsHelper } bool isRunning() { return m_isRunning; } - float clamp(float range, float value); + float target() { return m_target; } + float clamp(float rangeMin, float rangeMax, float value); void run(float acceleration, - float range, + float rangeMin, + float rangeMax, float value, - std::vector snappingPoints); + std::vector snappingPoints, + float contentSize, + float viewportSize); float advance(float elapsedSeconds); + + /// Initiate a settling animation from current position to target. + /// This skips the velocity phase and goes directly to smooth settling. + void scrollTo(float current, float target, float rangeMin, float rangeMax); }; class ElasticScrollPhysics : public ElasticScrollPhysicsBase { private: - ElasticScrollPhysicsHelper* m_physicsX; - ElasticScrollPhysicsHelper* m_physicsY; + std::unique_ptr m_physicsX; + std::unique_ptr m_physicsY; public: - ~ElasticScrollPhysics(); bool enabled() override { return m_physicsX != nullptr || m_physicsY != nullptr; @@ -53,13 +63,34 @@ class ElasticScrollPhysics : public ElasticScrollPhysicsBase return (m_physicsX != nullptr && m_physicsX->isRunning()) || (m_physicsY != nullptr && m_physicsY->isRunning()); } + float targetX() override + { + return m_physicsX != nullptr ? m_physicsX->target() : 0.0f; + } + float targetY() override + { + return m_physicsY != nullptr ? m_physicsY->target() : 0.0f; + } + bool hasTargetX() override { return m_physicsX != nullptr; } + bool hasTargetY() override { return m_physicsY != nullptr; } Vec2D advance(float elapsedSeconds) override; - Vec2D clamp(Vec2D range, Vec2D value) override; - void run(Vec2D range, + Vec2D clamp(Vec2D rangeMin, Vec2D rangeMax, Vec2D value) override; + void run(Vec2D rangeMin, + Vec2D rangeMax, Vec2D value, - std::vector snappingPoints) override; + std::vector snappingPoints, + float contentSize, + float viewportSize) override; void prepare(DraggableConstraintDirection dir) override; void reset() override; + + /// Initiate animated scroll to target position. + void scrollToPosition(Vec2D current, + Vec2D target, + Vec2D rangeMin, + Vec2D rangeMax, + bool horizontal, + bool vertical) override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/scrolling/scroll_bar_constraint_proxy.hpp b/thirdparty/rive/include/rive/constraints/scrolling/scroll_bar_constraint_proxy.hpp index bffaa66fd..68ad70957 100644 --- a/thirdparty/rive/include/rive/constraints/scrolling/scroll_bar_constraint_proxy.hpp +++ b/thirdparty/rive/include/rive/constraints/scrolling/scroll_bar_constraint_proxy.hpp @@ -21,9 +21,12 @@ class ThumbDraggableProxy : public DraggableProxy } ~ThumbDraggableProxy() {} bool isOpaque() override { return true; } - void startDrag(Vec2D mousePosition) override; - void drag(Vec2D mousePosition) override; - void endDrag(Vec2D mousePosition) override {} + bool startDrag(Vec2D mousePosition, float timeStamp = 0) override; + bool drag(Vec2D mousePosition, float timeStamp = 0) override; + bool endDrag(Vec2D mousePosition, float timeStamp = 0) override + { + return true; + } }; class TrackDraggableProxy : public DraggableProxy @@ -38,10 +41,15 @@ class TrackDraggableProxy : public DraggableProxy m_hittable = hittable; } ~TrackDraggableProxy() {} - bool isOpaque() override { return true; } - void startDrag(Vec2D mousePosition) override; - void drag(Vec2D mousePosition) override {} - void endDrag(Vec2D mousePosition) override {} + bool startDrag(Vec2D mousePosition, float timeStamp = 0) override; + bool drag(Vec2D mousePosition, float timeStamp = 0) override + { + return true; + } + bool endDrag(Vec2D mousePosition, float timeStamp = 0) override + { + return true; + } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint.hpp b/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint.hpp index 403376864..2f24a3e92 100644 --- a/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint.hpp +++ b/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint.hpp @@ -12,6 +12,7 @@ namespace rive { class LayoutNodeProvider; +class ScrollVirtualizer; class ScrollConstraint : public ScrollConstraintBase, public AdvancingComponent, @@ -25,9 +26,16 @@ class ScrollConstraint : public ScrollConstraintBase, ScrollPhysics* m_physics; Mat2D m_scrollTransform; bool m_isDragging = false; + ScrollVirtualizer* m_virtualizer = nullptr; + std::vector m_layoutChildren; + int m_childConstraintAppliedCount = 0; Vec2D positionAtIndex(float index); float indexAtPosition(Vec2D pos); + float maxOffsetXForPercent(); + float maxOffsetYForPercent(); + bool isBoundsCollapsed(AABB bounds); + std::vector collectSnapPoints(); public: ~ScrollConstraint(); @@ -37,9 +45,12 @@ class ScrollConstraint : public ScrollConstraintBase, StatusCode import(ImportStack& importStack) override; StatusCode onAddedDirty(CoreContext* context) override; Core* clone() const override; - void dragView(Vec2D delta); + void dragView(Vec2D delta, float timeStamp); void runPhysics(); void constrainChild(LayoutNodeProvider* child) override; + void addLayoutChild(LayoutNodeProvider* child) override; + Constraint* constraint() override { return this; } + void constrainVirtualized(bool force = false); bool advanceComponent(float elapsedSeconds, AdvanceFlags flags = AdvanceFlags::Animate | AdvanceFlags::NewFrame) override; @@ -59,102 +70,23 @@ class ScrollConstraint : public ScrollConstraintBase, { return parent()->parent()->as(); } - float contentWidth() { return content()->layoutWidth(); } - float contentHeight() { return content()->layoutHeight(); } - float viewportWidth() - { - return direction() == DraggableConstraintDirection::vertical - ? viewport()->layoutWidth() - : std::max(0.0f, - viewport()->layoutWidth() - content()->layoutX()); - } - float viewportHeight() - { - return direction() == DraggableConstraintDirection::horizontal - ? viewport()->layoutHeight() - : std::max(0.0f, - viewport()->layoutHeight() - - content()->layoutY()); - } - float visibleWidthRatio() - { - if (contentWidth() == 0) - { - return 1; - } - return std::min(1.0f, viewportWidth() / contentWidth()); - } - float visibleHeightRatio() - { - if (contentHeight() == 0) - { - return 1; - } - return std::min(1.0f, viewportHeight() / contentHeight()); - } - float maxOffsetX() - { - return std::min(0.0f, - viewportWidth() - contentWidth() - - viewport()->paddingRight()); - } - float maxOffsetY() - { - return std::min(0.0f, - viewportHeight() - contentHeight() - - viewport()->paddingBottom()); - } - float clampedOffsetX() - { - if (maxOffsetX() > 0) - { - return 0; - } - if (m_physics != nullptr && m_physics->enabled()) - { - return m_physics - ->clamp(Vec2D(maxOffsetX(), maxOffsetY()), - Vec2D(m_offsetX, m_offsetY)) - .x; - } - return math::clamp(m_offsetX, maxOffsetX(), 0); - } - float clampedOffsetY() - { - if (maxOffsetY() > 0) - { - return 0; - } - if (m_physics != nullptr && m_physics->enabled()) - { - return m_physics - ->clamp(Vec2D(maxOffsetX(), maxOffsetY()), - Vec2D(m_offsetX, m_offsetY)) - .y; - } - return math::clamp(m_offsetY, maxOffsetY(), 0); - } + float contentWidth(); + float contentHeight(); + float viewportWidth(); + float viewportHeight(); + float visibleWidthRatio(); + float visibleHeightRatio(); + float minOffsetX(); + float minOffsetY(); + float maxOffsetX(); + float maxOffsetY(); + float clampedOffsetX(); + float clampedOffsetY(); float offsetX() { return m_offsetX; } float offsetY() { return m_offsetY; } - void offsetX(float value) - { - if (m_offsetX == value) - { - return; - } - m_offsetX = value; - content()->markWorldTransformDirty(); - } - void offsetY(float value) - { - if (m_offsetY == value) - { - return; - } - m_offsetY = value; - content()->markWorldTransformDirty(); - } + void offsetX(float value); + void offsetY(float value); void scrollOffsetXChanged() override { offsetX(scrollOffsetX()); } void scrollOffsetYChanged() override { offsetY(scrollOffsetY()); } @@ -165,8 +97,35 @@ class ScrollConstraint : public ScrollConstraintBase, void setScrollPercentX(float value) override; void setScrollPercentY(float value) override; void setScrollIndex(float value) override; + size_t scrollItemCount(); + std::vector& scrollChildren() + { + return m_layoutChildren; + } Vec2D gap(); + bool mainAxisIsColumn(); + + /// Animate scroll to the target position using the physics settling + /// animation. + void scrollToPosition(float targetX, float targetY); + + /// Given a target offset reached by scrolling from current, return the + /// nearest snap offset in the direction of travel, or target unchanged + /// if snap() is false, no snap points exist, or none lie in the scroll + /// direction. The returned snap is at least as far as target — so an + /// element brought into view by target stays in view. + Vec2D nearestSnapOffsetInDirection(Vec2D current, Vec2D target); + + /// Get the effective scroll offset X (target if animating, current + /// otherwise). Use this to check element visibility during rapid focus + /// changes. + float effectiveScrollOffsetX(); + + /// Get the effective scroll offset Y (target if animating, current + /// otherwise). Use this to check element visibility during rapid focus + /// changes. + float effectiveScrollOffsetY(); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint_proxy.hpp b/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint_proxy.hpp index 965724fac..5ec5ca826 100644 --- a/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint_proxy.hpp +++ b/thirdparty/rive/include/rive/constraints/scrolling/scroll_constraint_proxy.hpp @@ -12,6 +12,7 @@ class ViewportDraggableProxy : public DraggableProxy private: ScrollConstraint* m_constraint; Vec2D m_lastPosition; + bool m_isDragging = false; public: ViewportDraggableProxy(ScrollConstraint* constraint, Drawable* hittable) : @@ -21,9 +22,9 @@ class ViewportDraggableProxy : public DraggableProxy } ~ViewportDraggableProxy() {} bool isOpaque() override { return false; } - void startDrag(Vec2D mousePosition) override; - void drag(Vec2D mousePosition) override; - void endDrag(Vec2D mousePosition) override; + bool startDrag(Vec2D mousePosition, float timeStamp = 0) override; + bool drag(Vec2D mousePosition, float timeStamp = 0) override; + bool endDrag(Vec2D mousePosition, float timeStamp = 0) override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/scrolling/scroll_physics.hpp b/thirdparty/rive/include/rive/constraints/scrolling/scroll_physics.hpp index 62f535ccc..ad556dbc3 100644 --- a/thirdparty/rive/include/rive/constraints/scrolling/scroll_physics.hpp +++ b/thirdparty/rive/include/rive/constraints/scrolling/scroll_physics.hpp @@ -41,24 +41,45 @@ class ScrollPhysics : public ScrollPhysicsBase virtual bool isRunning() { return m_isRunning; } virtual void prepare(DraggableConstraintDirection dir) { + reset(); m_direction = dir; } - virtual Vec2D clamp(Vec2D range, Vec2D value) { return Vec2D(); }; + virtual Vec2D clamp(Vec2D rangeMin, Vec2D rangeMax, Vec2D value) + { + return Vec2D(); + }; virtual Vec2D advance(float elapsedSeconds) { return Vec2D(); }; - virtual void accumulate(Vec2D delta); - virtual void run(Vec2D range, + virtual void accumulate(Vec2D delta, float timeStamp); + virtual void run(Vec2D rangeMin, + Vec2D rangeMax, Vec2D value, - std::vector snappingPoints) + std::vector snappingPoints, + float contentSize, + float viewportSize) { m_isRunning = true; } virtual void stop() { m_isRunning = false; } - virtual void reset() - { - m_acceleration = Vec2D(); - stop(); - } + virtual void reset(); StatusCode import(ImportStack& importStack) override; + + /// Initiate animated scroll to target position. + virtual void scrollToPosition(Vec2D current, + Vec2D target, + Vec2D rangeMin, + Vec2D rangeMax, + bool horizontal, + bool vertical) + {} + + /// Get the target X position if animating. + virtual float targetX() { return 0.0f; } + /// Get the target Y position if animating. + virtual float targetY() { return 0.0f; } + /// Whether there's an active X target. + virtual bool hasTargetX() { return false; } + /// Whether there's an active Y target. + virtual bool hasTargetY() { return false; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/constraints/scrolling/scroll_virtualizer.hpp b/thirdparty/rive/include/rive/constraints/scrolling/scroll_virtualizer.hpp new file mode 100644 index 000000000..a0bf78e60 --- /dev/null +++ b/thirdparty/rive/include/rive/constraints/scrolling/scroll_virtualizer.hpp @@ -0,0 +1,41 @@ +#ifndef _RIVE_SCROLL_VIRTUALIZER_HPP_ +#define _RIVE_SCROLL_VIRTUALIZER_HPP_ +#include "rive/artboard.hpp" +#include "rive/math/vec2d.hpp" +#include "rive/world_transform_component.hpp" +#include "rive/virtualizing_component.hpp" +#include +#include +namespace rive +{ +class LayoutNodeProvider; +class ScrollConstraint; + +class ScrollVirtualizer +{ +private: + int m_visibleIndexStart = 0; + int m_visibleIndexEnd = 0; + float m_offset = 0; + bool m_infinite = false; + float m_viewportSize = 0; + VirtualizedDirection m_direction = VirtualizedDirection::horizontal; + + void recycleItems(std::vector indices, + std::vector& children, + int totalItemCount); + float getItemSize(LayoutNodeProvider* child, int index, bool isHorizontal); + +public: + ~ScrollVirtualizer(); + void reset(); + bool constrain(ScrollConstraint* scroll, + std::vector& children, + float offset, + VirtualizedDirection direction); + void virtualize(ScrollConstraint* scroll, + std::vector& children); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/container_component.hpp b/thirdparty/rive/include/rive/container_component.hpp index 1a91f3957..fc5db3567 100644 --- a/thirdparty/rive/include/rive/container_component.hpp +++ b/thirdparty/rive/include/rive/container_component.hpp @@ -17,6 +17,18 @@ class ContainerComponent : public ContainerComponentBase Span((Core**)m_children.data(), m_children.size())); } + template T* firstChild() + { + for (auto* child : m_children) + { + if (child->is()) + { + return child->as(); + } + } + return nullptr; + } + const std::vector& children() const { return m_children; } virtual void addChild(Component* component); bool collapse(bool value) override; diff --git a/thirdparty/rive/include/rive/core/binary_data_reader.hpp b/thirdparty/rive/include/rive/core/binary_data_reader.hpp index beae449af..1cf17a1b6 100644 --- a/thirdparty/rive/include/rive/core/binary_data_reader.hpp +++ b/thirdparty/rive/include/rive/core/binary_data_reader.hpp @@ -30,6 +30,7 @@ class BinaryDataReader float readFloat32(); uint8_t readByte(); uint32_t readUint32(); + std::string readString(); void complete(uint8_t* bytes, size_t length); void reset(uint8_t* bytes); }; diff --git a/thirdparty/rive/include/rive/core/binary_reader.hpp b/thirdparty/rive/include/rive/core/binary_reader.hpp index 0d77cb62c..0299a631d 100644 --- a/thirdparty/rive/include/rive/core/binary_reader.hpp +++ b/thirdparty/rive/include/rive/core/binary_reader.hpp @@ -31,8 +31,13 @@ class BinaryReader const uint8_t* position() const; std::string readString(); + std::string readString(size_t length); Span readBytes(); + Span readBytes(size_t length); float readFloat32(); +#ifdef WITH_RIVE_TOOLS + double readFloat64(); +#endif uint8_t readByte(); uint16_t readUint16(); uint32_t readUint32(); diff --git a/thirdparty/rive/include/rive/core/field_types/core_bool_type.hpp b/thirdparty/rive/include/rive/core/field_types/core_bool_type.hpp index c6b0fccfc..09cec319b 100644 --- a/thirdparty/rive/include/rive/core/field_types/core_bool_type.hpp +++ b/thirdparty/rive/include/rive/core/field_types/core_bool_type.hpp @@ -7,8 +7,11 @@ class BinaryReader; class CoreBoolType { public: - static const int id = 0; + static const int id = 4; static bool deserialize(BinaryReader& reader); +#ifdef WITH_RIVE_TOOLS + static bool deserializeRev(BinaryReader& reader); +#endif }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/field_types/core_bytes_type.hpp b/thirdparty/rive/include/rive/core/field_types/core_bytes_type.hpp index 90f1886f3..d49181384 100644 --- a/thirdparty/rive/include/rive/core/field_types/core_bytes_type.hpp +++ b/thirdparty/rive/include/rive/core/field_types/core_bytes_type.hpp @@ -12,6 +12,9 @@ class CoreBytesType public: static const int id = 1; static Span deserialize(BinaryReader& reader); +#ifdef WITH_RIVE_TOOLS + static Span deserializeRev(BinaryReader& reader); +#endif }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/field_types/core_color_type.hpp b/thirdparty/rive/include/rive/core/field_types/core_color_type.hpp index afacba900..16726d3b6 100644 --- a/thirdparty/rive/include/rive/core/field_types/core_color_type.hpp +++ b/thirdparty/rive/include/rive/core/field_types/core_color_type.hpp @@ -9,6 +9,9 @@ class CoreColorType public: static const int id = 3; static int deserialize(BinaryReader& reader); +#ifdef WITH_RIVE_TOOLS + static int deserializeRev(BinaryReader& reader); +#endif }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/field_types/core_double_type.hpp b/thirdparty/rive/include/rive/core/field_types/core_double_type.hpp index 63515728a..02d873bf8 100644 --- a/thirdparty/rive/include/rive/core/field_types/core_double_type.hpp +++ b/thirdparty/rive/include/rive/core/field_types/core_double_type.hpp @@ -9,6 +9,9 @@ class CoreDoubleType public: static const int id = 2; static float deserialize(BinaryReader& reader); +#ifdef WITH_RIVE_TOOLS + static float deserializeRev(BinaryReader& reader); +#endif }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/field_types/core_string_type.hpp b/thirdparty/rive/include/rive/core/field_types/core_string_type.hpp index 596254576..c5f669522 100644 --- a/thirdparty/rive/include/rive/core/field_types/core_string_type.hpp +++ b/thirdparty/rive/include/rive/core/field_types/core_string_type.hpp @@ -11,6 +11,9 @@ class CoreStringType public: static const int id = 1; static std::string deserialize(BinaryReader& reader); +#ifdef WITH_RIVE_TOOLS + static std::string deserializeRev(BinaryReader& reader); +#endif }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/field_types/core_uint_type.hpp b/thirdparty/rive/include/rive/core/field_types/core_uint_type.hpp index af9c39993..8726d4529 100644 --- a/thirdparty/rive/include/rive/core/field_types/core_uint_type.hpp +++ b/thirdparty/rive/include/rive/core/field_types/core_uint_type.hpp @@ -9,6 +9,9 @@ class CoreUintType public: static const int id = 0; static unsigned int deserialize(BinaryReader& reader); +#ifdef WITH_RIVE_TOOLS + static unsigned int deserializeRev(BinaryReader& reader); +#endif }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/reader.h b/thirdparty/rive/include/rive/core/reader.h index fa9196d6b..c40686252 100644 --- a/thirdparty/rive/include/rive/core/reader.h +++ b/thirdparty/rive/include/rive/core/reader.h @@ -1,5 +1,3 @@ -#pragma once - #include #include @@ -190,4 +188,4 @@ inline size_t decode_uint_32(const uint8_t* buf, memcpy(r, buf, sizeof(uint32_t)); } return sizeof(uint32_t); -} +} \ No newline at end of file diff --git a/thirdparty/rive/include/rive/core/type_conversions.hpp b/thirdparty/rive/include/rive/core/type_conversions.hpp index f8cc2b411..40e6851c3 100644 --- a/thirdparty/rive/include/rive/core/type_conversions.hpp +++ b/thirdparty/rive/include/rive/core/type_conversions.hpp @@ -7,6 +7,7 @@ #include "rive/rive_types.hpp" #include +#include namespace rive { @@ -24,6 +25,35 @@ template T castTo(intmax_t x) return static_cast(x); } +// Computes a * b for unsigned integral T. Returns true on success and writes +// the product to *out. Returns false if the multiplication overflows; *out is +// then the low bits of the wrapped product (matching __builtin_mul_overflow's +// contract) and must not be relied on by callers. +template bool checkedMul(T a, T b, T* out) +{ + static_assert(std::is_integral::value && std::is_unsigned::value, + "checkedMul requires unsigned integer types"); +#if __has_builtin(__builtin_mul_overflow) + return !__builtin_mul_overflow(a, b, out); +#else + // Widen narrow T to `unsigned` before multiplying so the operation is + // an unsigned multiplication rather than a signed-int multiplication + // after integer-promotion (which would be UB on overflow for + // uint8_t / uint16_t). + using MulT = typename std:: + conditional<(sizeof(T) < sizeof(unsigned)), unsigned, T>::type; + const bool overflow = (b != 0 && a > std::numeric_limits::max() / b); + *out = static_cast(static_cast(a) * static_cast(b)); + return !overflow; +#endif +} + +template bool mulOverflows(T a, T b) +{ + T tmp; + return !checkedMul(a, b, &tmp); +} + } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/core/vector_binary_stream.hpp b/thirdparty/rive/include/rive/core/vector_binary_stream.hpp new file mode 100644 index 000000000..98d9f7dca --- /dev/null +++ b/thirdparty/rive/include/rive/core/vector_binary_stream.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_CORE_VECTOR_BINARY_STREAM_HPP_ +#define _RIVE_CORE_VECTOR_BINARY_STREAM_HPP_ + +#include "rive/core/binary_stream.hpp" +#include "rive/span.hpp" +#include + +namespace rive +{ +// A BinaryStream implementation that writes to an in-memory +// std::vector. Useful for building binary data that will be read back +// later. +class VectorBinaryStream : public BinaryStream +{ +public: + void write(const uint8_t* bytes, std::size_t length) override + { + m_memory.insert(m_memory.end(), bytes, bytes + length); + } + + void flush() override {} + + void clear() override { m_memory.clear(); } + + Span memory() + { + return Span(m_memory.data(), m_memory.size()); + } + + const std::vector& data() const { return m_memory; } + +private: + std::vector m_memory; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/core/vector_binary_writer.hpp b/thirdparty/rive/include/rive/core/vector_binary_writer.hpp index 93663de73..6513d765c 100644 --- a/thirdparty/rive/include/rive/core/vector_binary_writer.hpp +++ b/thirdparty/rive/include/rive/core/vector_binary_writer.hpp @@ -4,6 +4,7 @@ #include "rive/core/binary_stream.hpp" #include "rive/core/binary_writer.hpp" #include +#include namespace rive { diff --git a/thirdparty/rive/include/rive/custom_property_color.hpp b/thirdparty/rive/include/rive/custom_property_color.hpp new file mode 100644 index 000000000..628d52e1d --- /dev/null +++ b/thirdparty/rive/include/rive/custom_property_color.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_COLOR_HPP_ +#define _RIVE_CUSTOM_PROPERTY_COLOR_HPP_ +#include "rive/generated/custom_property_color_base.hpp" +#include +namespace rive +{ +class CustomPropertyColor : public CustomPropertyColorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/custom_property_container.hpp b/thirdparty/rive/include/rive/custom_property_container.hpp new file mode 100644 index 000000000..160a70ab6 --- /dev/null +++ b/thirdparty/rive/include/rive/custom_property_container.hpp @@ -0,0 +1,27 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_CONTAINER_HPP_ +#define _RIVE_CUSTOM_PROPERTY_CONTAINER_HPP_ +#include +#include +namespace rive +{ +class Component; +class CustomProperty; + +class CustomPropertyContainer +{ +protected: + std::vector m_customProperties; + void syncCustomProperties(); + +public: + virtual void addProperty(CustomProperty* prop); + virtual void removeProperty(CustomProperty* prop); + virtual const std::vector& containerChildren() const + { + static const std::vector emptyVec; + return emptyVec; + } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/custom_property_enum.hpp b/thirdparty/rive/include/rive/custom_property_enum.hpp new file mode 100644 index 000000000..14919f701 --- /dev/null +++ b/thirdparty/rive/include/rive/custom_property_enum.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_ENUM_HPP_ +#define _RIVE_CUSTOM_PROPERTY_ENUM_HPP_ +#include "rive/generated/custom_property_enum_base.hpp" +#include +namespace rive +{ +class CustomPropertyEnum : public CustomPropertyEnumBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/custom_property_group.hpp b/thirdparty/rive/include/rive/custom_property_group.hpp index 80115e374..9a801a1f1 100644 --- a/thirdparty/rive/include/rive/custom_property_group.hpp +++ b/thirdparty/rive/include/rive/custom_property_group.hpp @@ -1,10 +1,12 @@ #ifndef _RIVE_CUSTOM_PROPERTY_GROUP_HPP_ #define _RIVE_CUSTOM_PROPERTY_GROUP_HPP_ +#include "rive/custom_property_container.hpp" #include "rive/generated/custom_property_group_base.hpp" #include namespace rive { -class CustomPropertyGroup : public CustomPropertyGroupBase +class CustomPropertyGroup : public CustomPropertyGroupBase, + public CustomPropertyContainer { public: }; diff --git a/thirdparty/rive/include/rive/custom_property_trigger.hpp b/thirdparty/rive/include/rive/custom_property_trigger.hpp new file mode 100644 index 000000000..a92baa92d --- /dev/null +++ b/thirdparty/rive/include/rive/custom_property_trigger.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_TRIGGER_HPP_ +#define _RIVE_CUSTOM_PROPERTY_TRIGGER_HPP_ +#include "rive/generated/custom_property_trigger_base.hpp" +#include "rive/resetting_component.hpp" +#include +namespace rive +{ +class CustomPropertyTrigger : public CustomPropertyTriggerBase, + public ResettingComponent +{ +public: + void fire(const CallbackData& value) override + { + propertyValue(propertyValue() + 1); + } + + void reset() override { propertyValue(0); } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/bindable_property_artboard.hpp b/thirdparty/rive/include/rive/data_bind/bindable_property_artboard.hpp new file mode 100644 index 000000000..45d2dde62 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/bindable_property_artboard.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_ARTBOARD_HPP_ +#define _RIVE_BINDABLE_PROPERTY_ARTBOARD_HPP_ +#include "rive/generated/data_bind/bindable_property_artboard_base.hpp" +#include +namespace rive +{ +class BindablePropertyArtboard : public BindablePropertyArtboardBase +{ +public: + constexpr static uint32_t defaultValue = -1; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/bindable_property_asset.hpp b/thirdparty/rive/include/rive/data_bind/bindable_property_asset.hpp index 58b89ff61..d75942586 100644 --- a/thirdparty/rive/include/rive/data_bind/bindable_property_asset.hpp +++ b/thirdparty/rive/include/rive/data_bind/bindable_property_asset.hpp @@ -1,13 +1,24 @@ #ifndef _RIVE_BINDABLE_PROPERTY_ASSET_HPP_ #define _RIVE_BINDABLE_PROPERTY_ASSET_HPP_ #include "rive/generated/data_bind/bindable_property_asset_base.hpp" +#include "rive/assets/image_asset.hpp" #include namespace rive { class BindablePropertyAsset : public BindablePropertyAssetBase { public: + BindablePropertyAsset() : m_fileAsset(rcp(new ImageAsset())) {} constexpr static uint32_t defaultValue = -1; + rcp fileAsset() { return m_fileAsset; } + void imageValue(RenderImage* image) + { + m_fileAsset->renderImage(ref_rcp(image)); + } + RenderImage* imageValue() { return m_fileAsset->renderImage(); } + +private: + rcp m_fileAsset = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/bindable_property_id.hpp b/thirdparty/rive/include/rive/data_bind/bindable_property_id.hpp new file mode 100644 index 000000000..5a541f413 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/bindable_property_id.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_ID_HPP_ +#define _RIVE_BINDABLE_PROPERTY_ID_HPP_ +#include "rive/generated/data_bind/bindable_property_id_base.hpp" +#include +namespace rive +{ +class BindablePropertyId : public BindablePropertyIdBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/bindable_property_list.hpp b/thirdparty/rive/include/rive/data_bind/bindable_property_list.hpp new file mode 100644 index 000000000..9f66601c0 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/bindable_property_list.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_LIST_HPP_ +#define _RIVE_BINDABLE_PROPERTY_LIST_HPP_ +#include "rive/generated/data_bind/bindable_property_list_base.hpp" +#include +namespace rive +{ +class BindablePropertyList : public BindablePropertyListBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/bindable_property_viewmodel.hpp b/thirdparty/rive/include/rive/data_bind/bindable_property_viewmodel.hpp new file mode 100644 index 000000000..c55c7c56f --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/bindable_property_viewmodel.hpp @@ -0,0 +1,39 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_VIEW_MODEL_HPP_ +#define _RIVE_BINDABLE_PROPERTY_VIEW_MODEL_HPP_ +#include "rive/generated/data_bind/bindable_property_viewmodel_base.hpp" +#include +namespace rive +{ +class ViewModelInstance; +class BindablePropertyViewModel : public BindablePropertyViewModelBase +{ +public: + constexpr static uint32_t defaultValue = -1; + + void viewModelInstanceValue(ViewModelInstance* value) + { + m_viewModelInstance = value; + } + + ViewModelInstance* viewModelInstanceValue() const + { + return m_viewModelInstance; + } + + // Backward-compatible aliases. + void viewModelInstance(ViewModelInstance* value) + { + viewModelInstanceValue(value); + } + + ViewModelInstance* viewModelInstance() const + { + return viewModelInstanceValue(); + } + +private: + ViewModelInstance* m_viewModelInstance = nullptr; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/context/context_target_value.hpp b/thirdparty/rive/include/rive/data_bind/context/context_target_value.hpp new file mode 100644 index 000000000..d73228810 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/context/context_target_value.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_TARGET_VALUE_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_TARGET_VALUE_HPP_ +#include +#include "rive/data_bind/data_values/data_value.hpp" +namespace rive +{ +class DataBind; +class DataBindContextTargetValue +{ +private: + DataValue* m_targetValue = nullptr; + DataBind* m_dataBind = nullptr; + template bool updateValue(U value) + { + if (m_targetValue->as()->value() != value) + { + m_targetValue->as()->value(value); + return true; + } + return false; + } + +public: + virtual ~DataBindContextTargetValue(); + void initialize(DataBind* dataBind); + bool syncTargetValue(); + DataValue* dataValue() { return m_targetValue; } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value.hpp index c4626d93c..25e8632f1 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value.hpp @@ -4,6 +4,7 @@ #include "rive/data_bind/converters/data_converter.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/context/context_target_value.hpp" #include namespace rive { @@ -12,8 +13,8 @@ class DataBindContextValue protected: DataBind* m_dataBind = nullptr; DataValue* m_dataValue = nullptr; + DataBindContextTargetValue m_targetValue; bool m_isValid = false; - virtual DataValue* targetValue() { return nullptr; }; public: DataBindContextValue(DataBind* dataBind); @@ -29,66 +30,72 @@ class DataBindContextValue bool isMainDirection); virtual void apply(Core* component, uint32_t propertyKey, - bool isMainDirection){}; + bool isMainDirection) {}; void invalidate() { m_isValid = false; }; virtual bool syncTargetValue(Core* target, uint32_t propertyKey) { return false; }; void syncSourceValue(); - template - U getDataValue(DataValue* input, DataBind* dataBind) + DataValue* calculateUntypedDataValue(DataValue* input, + bool isMainDirection, + DataBind* dataBind) { auto converter = dataBind->converter(); + auto dataValue = converter != nullptr + ? isMainDirection + ? converter->convert(input, dataBind) + : converter->reverseConvert(input, dataBind) + : input; + return dataValue; + } + template + DataValue* calculateDataValue(DataValue* input, + bool isMainDirection, + DataBind* dataBind) + { auto dataValue = - converter != nullptr ? converter->convert(input, dataBind) : input; + calculateUntypedDataValue(input, isMainDirection, dataBind); if (dataValue->is()) { - return dataValue->as()->value(); + return dataValue; } - return T::defaultValue; + return nullptr; }; + template - U getReverseDataValue(DataValue* input, DataBind* dataBind) + U calculateValue(DataValue* input, bool isMainDirection, DataBind* dataBind) { - auto converter = dataBind->converter(); - auto dataValue = converter != nullptr - ? converter->reverseConvert(input, dataBind) - : input; - if (dataValue->is()) + auto dataValue = + calculateDataValue(input, isMainDirection, dataBind); + if (dataValue && dataValue->template is()) { - return dataValue->as()->value(); + return dataValue->template as()->value(); } return T::defaultValue; }; - template - U calculateValue(DataValue* input, bool isMainDirection, DataBind* dataBind) - { - auto value = isMainDirection - ? getDataValue(input, dataBind) - : getReverseDataValue(input, dataBind); - return value; - }; template - void calculateValueAndApply(DataValue* input, - bool isMainDirection, - DataBind* dataBind, - Core* component, - uint32_t propertyKey) + void calculateValueAndApply(bool isMainDirection) { // Check if target value changed or binding has been invalidated - if (syncTargetValue(component, propertyKey) || !m_isValid) + if (m_targetValue.syncTargetValue() || !m_isValid) { // Calculate new value after converters are applied - auto value = calculateValue(input, isMainDirection, dataBind); - // Apply value to source - dataBind->suppressDirt(true); - auto source = dataBind->source(); - source->as()->propertyValue(value); - dataBind->suppressDirt(false); - m_isValid = true; + auto value = calculateDataValue(m_targetValue.dataValue(), + isMainDirection, + m_dataBind); + if (value) + { + + // Apply value to source + m_dataBind->suppressDirt(true); + auto source = m_dataBind->source(); + source->as()->applyValue(value->template as()); + m_dataBind->suppressDirt(false); + m_isValid = true; + } } }; }; diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_any.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_any.hpp new file mode 100644 index 000000000..d9afe0ad5 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_any.hpp @@ -0,0 +1,17 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_ANY_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_ANY_HPP_ +#include "rive/data_bind/context/context_value.hpp" +namespace rive +{ +class DataBindContextValueAny : public DataBindContextValue +{ + +public: + DataBindContextValueAny(DataBind* m_dataBind); + void apply(Core* component, + uint32_t propertyKey, + bool isMainDirection) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_artboard.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_artboard.hpp new file mode 100644 index 000000000..e194d4c39 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_artboard.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_ARTBOARD_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_ARTBOARD_HPP_ +#include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/data_values/data_value_artboard.hpp" +namespace rive +{ +class Artboard; +class DataBindContextValueArtboard : public DataBindContextValue +{ + +public: + DataBindContextValueArtboard(DataBind* m_dataBind); + void apply(Core* component, + uint32_t propertyKey, + bool isMainDirection) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_asset_image.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_asset_image.hpp index d3dac4683..416fd612f 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_asset_image.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_asset_image.hpp @@ -13,15 +13,7 @@ class DataBindContextValueAssetImage : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - ImageAsset* fileAsset(); - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } - -private: - uint32_t m_previousValue = -1; - DataValueAssetImage m_targetDataValue; + rcp fileAsset(); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_boolean.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_boolean.hpp index e8702c1fd..f052ea64c 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_boolean.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_boolean.hpp @@ -11,14 +11,6 @@ class DataBindContextValueBoolean : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - bool m_previousValue = false; - DataValueBoolean m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_color.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_color.hpp index 559064075..15ccfc3f5 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_color.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_color.hpp @@ -12,14 +12,6 @@ class DataBindContextValueColor : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - int m_previousValue = 0; - DataValueColor m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_enum.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_enum.hpp index 1ae2dd3f2..078f9fb6d 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_enum.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_enum.hpp @@ -12,14 +12,6 @@ class DataBindContextValueEnum : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - uint32_t m_previousValue = 0; - DataValueEnum m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_number.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_number.hpp index 2e158bd33..a69d0e5f8 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_number.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_number.hpp @@ -12,14 +12,6 @@ class DataBindContextValueNumber : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - float m_previousValue = 0; - DataValueNumber m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_string.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_string.hpp index ec81713d3..56e8800e8 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_string.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_string.hpp @@ -12,14 +12,6 @@ class DataBindContextValueString : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - std::string m_previousValue = ""; - DataValueString m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_symbol_list_index.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_symbol_list_index.hpp index a98f656a3..640ee8e84 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_symbol_list_index.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_symbol_list_index.hpp @@ -12,14 +12,6 @@ class DataBindContextValueSymbolListIndex : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - uint32_t m_previousValue = 0; - DataValueSymbolListIndex m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_trigger.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_trigger.hpp index b66e41f3b..35171b18e 100644 --- a/thirdparty/rive/include/rive/data_bind/context/context_value_trigger.hpp +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_trigger.hpp @@ -12,14 +12,6 @@ class DataBindContextValueTrigger : public DataBindContextValue void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; - bool syncTargetValue(Core* target, uint32_t propertyKey) override; - -private: - uint32_t m_previousValue = 0; - DataValueTrigger m_targetDataValue; - -protected: - DataValue* targetValue() override { return &m_targetDataValue; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/context/context_value_viewmodel.hpp b/thirdparty/rive/include/rive/data_bind/context/context_value_viewmodel.hpp new file mode 100644 index 000000000..381fc2741 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/context/context_value_viewmodel.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_VIEWMODEL_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_VIEWMODEL_HPP_ +#include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/data_values/data_value_viewmodel.hpp" + +namespace rive +{ +class DataBindContextValueViewModel : public DataBindContextValue +{ + +public: + DataBindContextValueViewModel(DataBind* m_dataBind); + void apply(Core* component, + uint32_t propertyKey, + bool isMainDirection) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter.hpp index 158aa1d99..86e3db82e 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/data_converter.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter.hpp @@ -3,11 +3,12 @@ #include "rive/generated/data_bind/converters/data_converter_base.hpp" #include "rive/data_bind/data_values/data_value.hpp" #include "rive/data_bind/data_context.hpp" +#include "rive/data_bind/data_bind_container.hpp" #include namespace rive { class DataBind; -class DataConverter : public DataConverterBase +class DataConverter : public DataConverterBase, public DataBindContainer { public: ~DataConverter(); @@ -23,15 +24,14 @@ class DataConverter : public DataConverterBase virtual void bindFromContext(DataContext* dataContext, DataBind* dataBind); virtual void unbind(); StatusCode import(ImportStack& importStack) override; - void addDataBind(DataBind* dataBind); - std::vector dataBinds() const { return m_dataBinds; } void markConverterDirty(); virtual void update(); void copy(const DataConverter& object); virtual bool advance(float elapsedTime); + void addDirtyDataBind(DataBind*) override; + virtual void reset() {}; -private: - std::vector m_dataBinds; +protected: DataBind* m_parentDataBind; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_formula.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_formula.hpp index feedf49a4..6e140353d 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/data_converter_formula.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_formula.hpp @@ -4,20 +4,25 @@ #include "rive/data_bind/converters/formula/formula_token.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_value_dependent.hpp" #include #include namespace rive { -class DataConverterFormula : public DataConverterFormulaBase +class DataConverterFormula : public DataConverterFormulaBase, + public ViewModelValueDependent { public: ~DataConverterFormula(); DataType outputType() override { return DataType::number; }; void addToken(FormulaToken*); void addOutputToken(FormulaToken*, int); - void initialize(); + void calculateFormula(); void isInstance(bool value) { m_isInstance = value; } + void addDirt(ComponentDirt value, bool recurse) override; + void relinkDataBind() override {} protected: DataValue* convert(DataValue* value, DataBind* dataBind) override; @@ -26,7 +31,6 @@ class DataConverterFormula : public DataConverterFormulaBase Core* clone() const override; void bindFromContext(DataContext* dataContext, DataBind* dataBind) override; void unbind() override; - void update() override; private: int getPrecedence(FormulaToken*); @@ -40,6 +44,7 @@ class DataConverterFormula : public DataConverterFormulaBase std::vector m_randoms; std::unordered_map m_argumentsCount; bool m_isInstance = false; + rcp m_source = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_group.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_group.hpp index 9b8e70f59..b6829a758 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/data_converter_group.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_group.hpp @@ -3,6 +3,7 @@ #include "rive/generated/data_bind/converters/data_converter_group_base.hpp" #include "rive/data_bind/converters/data_converter_group_item.hpp" #include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_values/data_type.hpp" #include namespace rive { @@ -17,7 +18,16 @@ class DataConverterGroup : public DataConverterGroupBase { if (m_items.size() > 0) { - return m_items.back()->converter()->outputType(); + int currentIndex = int(m_items.size() - 1); + while (currentIndex >= 0) + { + if (m_items[currentIndex]->converter()->outputType() != + DataType::input) + { + return m_items[currentIndex]->converter()->outputType(); + } + currentIndex--; + } }; return Super::outputType(); } @@ -27,6 +37,7 @@ class DataConverterGroup : public DataConverterGroupBase void unbind() override; void update() override; bool advance(float elapsedSeconds) override; + void reset() override; private: std::vector m_items; diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_interpolator.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_interpolator.hpp index ac7c06742..2ccb0086f 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/data_converter_interpolator.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_interpolator.hpp @@ -8,43 +8,144 @@ namespace rive { -struct InterpolatorAnimationData +class DataConverterInterpolator; + +class InterpolatorAnimationData { +public: float elapsedSeconds = 0.0f; - float from; - float to; - float interpolate(float f) const + DataValue* from = nullptr; + DataValue* to = nullptr; + void interpolate(float f, DataValue* store) const { - float fi = 1.0f - f; - return to * f + from * fi; + from->interpolate(to, store, f); } void copy(const InterpolatorAnimationData& source); + template void initialize() + { + from = new T(); + to = new T(); + } + void dispose() + { + elapsedSeconds = 0; + if (from != nullptr) + { + delete from; + from = nullptr; + delete to; + to = nullptr; + } + } +}; + +class InterpolatorAdvancer +{ +public: + template + void initialize(DataConverterInterpolator* converter) + { + m_initialized = true; + m_converter = converter; + + m_animationDataA.initialize(); + m_animationDataB.initialize(); + m_currentValue = new T(); + } + bool initialized() { return m_initialized; } + void dispose(); + void resetValues(DataValue* input) + { + auto animationData = currentAnimationData(); + input->copyValue(animationData->from); + input->copyValue(animationData->to); + input->copyValue(m_currentValue); + } + void resetToStart(DataValue* input) + { + resetValues(input); + m_isSmoothingAnimation = false; + m_animationDataA.elapsedSeconds = 0; + m_animationDataB.elapsedSeconds = 0; + } + void reset() + { + dispose(); + m_isSmoothingAnimation = false; + m_initialized = false; + } + void updateValues(DataValue* input) + { + auto animationData = currentAnimationData(); + if (!input->compare(animationData->to)) + { + if (animationData->elapsedSeconds != 0) + { + if (m_isSmoothingAnimation) + { + m_animationDataA.copy(m_animationDataB); + } + m_isSmoothingAnimation = true; + } + else + { + m_isSmoothingAnimation = false; + } + animationData = currentAnimationData(); + m_currentValue->copyValue(animationData->from); + input->copyValue(animationData->to); + animationData->elapsedSeconds = 0; + } + } + void copyCurrentValue(DataValue* output) + { + m_currentValue->copyValue(output); + } + void advanceAnimationData(float elapsedTime); + bool advance(float elapsedTime); + +private: + InterpolatorAnimationData m_animationDataA; + InterpolatorAnimationData m_animationDataB; + InterpolatorAnimationData* currentAnimationData(); + bool m_isSmoothingAnimation = false; + bool m_initialized = false; + DataValue* m_currentValue = nullptr; + DataConverterInterpolator* m_converter = nullptr; }; + class DataConverterInterpolator : public DataConverterInterpolatorBase { protected: KeyFrameInterpolator* m_interpolator = nullptr; public: + ~DataConverterInterpolator(); void interpolator(KeyFrameInterpolator* interpolator); KeyFrameInterpolator* interpolator() const { return m_interpolator; }; - DataType outputType() override { return DataType::number; }; + DataType outputType() override { return DataType::input; }; DataValue* convert(DataValue* value, DataBind* dataBind) override; DataValue* reverseConvert(DataValue* value, DataBind* dataBind) override; bool advance(float elapsedTime) override; + void reset() override; void copy(const DataConverterInterpolatorBase& object); void durationChanged() override; + template void startAdvancer() + { + if (m_output != nullptr) + { + delete m_output; + } + m_output = new T(); + m_advancer.initialize(this); + } private: - DataValueNumber m_output; - float m_currentValue; - bool m_isFirstRun = true; + DataValue* m_output = nullptr; + uint8_t m_advanceCount = 0; + bool isFirstRun() { return m_advanceCount < 2; } - InterpolatorAnimationData m_animationDataA; - InterpolatorAnimationData m_animationDataB; - bool m_isSmoothingAnimation = false; - InterpolatorAnimationData* currentAnimationData(); - void advanceAnimationData(float elapsedTime); + InterpolatorAdvancer m_advancer; public: }; diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_list_to_length.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_list_to_length.hpp new file mode 100644 index 000000000..4a04ff66e --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_list_to_length.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_DATA_CONVERTER_LIST_TO_LENGTH_HPP_ +#define _RIVE_DATA_CONVERTER_LIST_TO_LENGTH_HPP_ +#include "rive/generated/data_bind/converters/data_converter_list_to_length_base.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include +namespace rive +{ +class DataConverterListToLength : public DataConverterListToLengthBase +{ +public: + DataValue* convert(DataValue* value, DataBind* dataBind) override; + DataType outputType() override { return DataType::number; }; + +private: + DataValueNumber m_output; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_number_to_list.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_number_to_list.hpp index 25baba9ba..0f01946cf 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/data_converter_number_to_list.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_number_to_list.hpp @@ -6,21 +6,20 @@ #include "rive/refcnt.hpp" #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/file.hpp" #include namespace rive { -class File; class DataConverterNumberToList : public DataConverterNumberToListBase { private: File* m_file = nullptr; DataValueList m_output; - std::vector m_listItems; + std::vector> m_listItems; void clearItems(); public: - ~DataConverterNumberToList(); DataValue* convert(DataValue* value, DataBind* dataBind) override; DataType outputType() override { return DataType::list; }; void file(File*); diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_number.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_number.hpp new file mode 100644 index 000000000..af7d88adc --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_number.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_DATA_CONVERTER_TO_NUMBER_HPP_ +#define _RIVE_DATA_CONVERTER_TO_NUMBER_HPP_ +#include "rive/generated/data_bind/converters/data_converter_to_number_base.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" +#include "rive/data_bind/data_values/data_value_enum.hpp" +#include +namespace rive +{ +class DataConverterToNumber : public DataConverterToNumberBase +{ +public: + DataValue* convert(DataValue* value, DataBind* dataBind) override; + DataType outputType() override { return DataType::number; }; + +private: + DataValue* convertString(DataValueString* value); + DataValue* convertColor(DataValueColor* value); + DataValue* convertEnum(DataValueEnum* value); + DataValueNumber m_output; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_string.hpp b/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_string.hpp index 500dca902..b4cb3e0a9 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_string.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/data_converter_to_string.hpp @@ -139,6 +139,7 @@ class DataConverterToString : public DataConverterToStringBase private: DataValue* convertNumber(DataValueNumber* value); DataValue* convertColor(DataValueColor* value); + std::string formatWithCommas(std::string& num); DataValueString m_output; _ColorConverter m_converter; }; diff --git a/thirdparty/rive/include/rive/data_bind/converters/formula/formula_token.hpp b/thirdparty/rive/include/rive/data_bind/converters/formula/formula_token.hpp index b648eb882..8747c7c6b 100644 --- a/thirdparty/rive/include/rive/data_bind/converters/formula/formula_token.hpp +++ b/thirdparty/rive/include/rive/data_bind/converters/formula/formula_token.hpp @@ -7,23 +7,15 @@ #include namespace rive { +class DataConverterFormula; class FormulaToken : public FormulaTokenBase { public: - ~FormulaToken(); StatusCode import(ImportStack& importStack) override; - - virtual void bindFromContext(DataContext* dataContext, DataBind* dataBind); - virtual void unbind(); - virtual void update(); - void markDirty(); void addDataBind(DataBind* dataBind); - void copy(const FormulaTokenBase& object); - std::vector dataBinds() const { return m_dataBinds; } private: - std::vector m_dataBinds; - DataBind* m_parentDataBind; + DataConverterFormula* m_formula = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_bind.hpp b/thirdparty/rive/include/rive/data_bind/data_bind.hpp index f2049f844..2323f4c92 100644 --- a/thirdparty/rive/include/rive/data_bind/data_bind.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_bind.hpp @@ -6,17 +6,18 @@ #include "rive/data_bind/data_context.hpp" #include "rive/data_bind/converters/data_converter.hpp" #include "rive/data_bind/data_values/data_type.hpp" -#include "rive/dirtyable.hpp" +#include "rive/viewmodel/viewmodel_value_dependent.hpp" #include namespace rive { -class File; class DataBindContextValue; +class DataBindContainer; +class File; #ifdef WITH_RIVE_TOOLS class DataBind; typedef void (*DataBindChanged)(); #endif -class DataBind : public DataBindBase, public Dirtyable +class DataBind : public DataBindBase, public ViewModelValueDependent { public: ~DataBind(); @@ -24,6 +25,7 @@ class DataBind : public DataBindBase, public Dirtyable StatusCode import(ImportStack& importStack) override; virtual void updateSourceBinding(bool invalidate = false); virtual void update(ComponentDirt value); + void updateDependents(); Core* target() const { return m_target; }; void target(Core* value) { m_target = value; }; virtual void bind(); @@ -33,23 +35,36 @@ class DataBind : public DataBindBase, public Dirtyable void addDirt(ComponentDirt value, bool recurse) override; DataConverter* converter() const { return m_dataConverter; }; void converter(DataConverter* value) { m_dataConverter = value; }; - ViewModelInstanceValue* source() const { return m_Source; }; - void source(ViewModelInstanceValue* value); + ViewModelInstanceValue* source() const { return m_Source.get(); }; + void source(rcp value); void clearSource(); bool toSource(); bool toTarget(); + bool isNameBased(); + bool canSkip(); + bool isMainToSource(); + bool sourceToTargetRunsFirst(); bool advance(float elapsedTime); void suppressDirt(bool value) { m_suppressDirt = value; }; - void file(File* value) { m_file = value; }; - File* file() const { return m_file; }; + void file(File* value); + File* file() const; + DataType outputType(); + DataType sourceOutputType(); + void container(DataBindContainer*); + DataBindContainer* m_container = nullptr; + void collapse(bool collapsed); + void initialize(); + void relinkDataBind() override; + +private: + bool m_isCollapsed = false; protected: - ComponentDirt m_Dirt = ComponentDirt::Filthy; + ComponentDirt m_Dirt = ComponentDirt::None; Core* m_target = nullptr; - ViewModelInstanceValue* m_Source = nullptr; + rcp m_Source = nullptr; DataBindContextValue* m_ContextValue = nullptr; DataConverter* m_dataConverter = nullptr; - DataType outputType(); bool bindsOnce(); bool m_suppressDirt = false; File* m_file; diff --git a/thirdparty/rive/include/rive/data_bind/data_bind_container.hpp b/thirdparty/rive/include/rive/data_bind/data_bind_container.hpp new file mode 100644 index 000000000..cecdfe0be --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/data_bind_container.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_DATA_BIND_CONTAINER_HPP_ +#define _RIVE_DATA_BIND_CONTAINER_HPP_ +#include + +namespace rive +{ +class DataContext; +class DataBind; +class DataBindContainer +{ +public: + virtual void updateDataBinds(bool applyTargetToSource = true); + void addDataBind(DataBind* dataBind); + void removeDataBind(DataBind* dataBind); + const std::vector dataBinds() const { return m_dataBinds; } + virtual void addDirtyDataBind(DataBind* dataBind); + virtual void rebind() {}; + virtual void relinkDataContext() {}; + virtual void rebuildDataBind(DataBind*) {}; + +protected: + void deleteDataBinds(); + bool advanceDataBinds(float); + void bindDataBindsFromContext(DataContext*); + void unbindDataBinds(); + void sortDataBinds(); + +private: + void updateDataBind(DataBind* dataBind, bool applyTargetToSource); + std::vector m_dataBinds; + std::vector m_persistingDataBinds; + std::vector m_dirtyDataBinds; + std::vector m_pendingDirtyDataBinds; + bool m_isProcessing = false; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_bind_context.hpp b/thirdparty/rive/include/rive/data_bind/data_bind_context.hpp index 45b069e09..fccc49517 100644 --- a/thirdparty/rive/include/rive/data_bind/data_bind_context.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_bind_context.hpp @@ -17,6 +17,14 @@ class DataBindContext : public DataBindContextBase void decodeSourcePathIds(Span value) override; void copySourcePathIds(const DataBindContextBase& object) override; void bindFromContext(DataContext* dataContext); + const std::vector& sourcePathIds() const + { + return m_SourcePathIdsBuffer; + } + +private: + void resolvePath(); + bool m_isPathResolved = false; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_bind_list_item_consumer.hpp b/thirdparty/rive/include/rive/data_bind/data_bind_list_item_consumer.hpp index a1d576b0d..abf428402 100644 --- a/thirdparty/rive/include/rive/data_bind/data_bind_list_item_consumer.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_bind_list_item_consumer.hpp @@ -1,5 +1,7 @@ #ifndef _RIVE_DATA_BIND_LIST_ITEM_PROVIDER_HPP_ #define _RIVE_DATA_BIND_LIST_ITEM_PROVIDER_HPP_ +#include "rive/core.hpp" +#include "rive/refcnt.hpp" namespace rive { class ViewModelInstanceListItem; @@ -9,8 +11,8 @@ class DataBindListItemConsumer public: static DataBindListItemConsumer* from(Core* component); - virtual void updateList(int propertyKey, - std::vector* list) = 0; + virtual void updateList( + std::vector>* list) = 0; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_bind_path.hpp b/thirdparty/rive/include/rive/data_bind/data_bind_path.hpp new file mode 100644 index 000000000..589d29147 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/data_bind_path.hpp @@ -0,0 +1,29 @@ +#ifndef _RIVE_DATA_BIND_PATH_HPP_ +#define _RIVE_DATA_BIND_PATH_HPP_ +#include "rive/generated/data_bind/data_bind_path_base.hpp" +#include +namespace rive +{ +class File; +class DataBindPath : public DataBindPathBase +{ +public: + void decodePath(Span value) override; + void copyPath(const DataBindPathBase& object) override; + StatusCode import(ImportStack& importStack) override; + std::vector& path() { return m_pathBuffer; } + const std::vector& resolvedPath(); + void file(File* value); + File* file() { return m_file; }; + void resolved(bool value) { m_resolved = value; } + +protected: + std::vector m_pathBuffer; + +private: + File* m_file = nullptr; + bool m_resolved = false; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_bind_viewmodel_consumer.hpp b/thirdparty/rive/include/rive/data_bind/data_bind_viewmodel_consumer.hpp new file mode 100644 index 000000000..ffc8ced31 --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/data_bind_viewmodel_consumer.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_DATA_VIEWMODEL_CONSUMER_HPP_ +#define _RIVE_DATA_VIEWMODEL_CONSUMER_HPP_ +#include "rive/core.hpp" +namespace rive +{ +class ViewModelInstance; + +class DataBindViewModelConsumer +{ +public: + static DataBindViewModelConsumer* from(Core* component); + virtual void updateViewModel(ViewModelInstance* value) = 0; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_context.hpp b/thirdparty/rive/include/rive/data_bind/data_context.hpp index 9329bb70a..cb523b13c 100644 --- a/thirdparty/rive/include/rive/data_bind/data_context.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_context.hpp @@ -2,28 +2,46 @@ #define _RIVE_DATA_CONTEXT_HPP_ #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/data_resolver.hpp" #include "rive/refcnt.hpp" namespace rive { -class DataContext +class DataBindPath; +class DataContext : public RefCnt { private: - DataContext* m_Parent = nullptr; + rcp m_Parent = nullptr; rcp m_ViewModelInstance; public: DataContext(rcp viewModelInstance); - DataContext* parent() { return m_Parent; } - void parent(DataContext* value) { m_Parent = value; } + rcp parent() { return m_Parent; } + void parent(rcp value) { m_Parent = value; } ViewModelInstanceValue* getViewModelProperty( const std::vector path) const; + ViewModelInstanceValue* getRelativeViewModelProperty( + const std::vector path, + DataResolver* resolver) const; + ViewModelInstanceValue* getViewModelProperty(DataBindPath* dataBindPath); rcp getViewModelInstance( const std::vector path) const; + rcp getViewModelInstance(DataBindPath*) const; + rcp getRelativeViewModelInstance( + const std::vector path, + DataResolver* resolver) const; void viewModelInstance(rcp value); void advanced(); rcp viewModelInstance() { return m_ViewModelInstance; }; + rcp rootViewModelInstance() + { + if (m_Parent) + { + return m_Parent->rootViewModelInstance(); + } + return m_ViewModelInstance; + }; ViewModelInstanceValue* viewModelValue() { diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_type.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_type.hpp index d24b6a193..2e7debe31 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_type.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_type.hpp @@ -39,7 +39,15 @@ enum class DataType : unsigned int symbolListIndex = 10, /// Asset Image. - assetImage = 11 + assetImage = 11, + + /// Artboard. + artboard = 12, + + /// Special case, this type is used to indicate it uses the input type. + input = 99, + + any = 100 }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value.hpp index 202328646..a60ad3175 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_DATA_VALUE_HPP_ #define _RIVE_DATA_VALUE_HPP_ #include "rive/data_bind/data_values/data_type.hpp" +#include #include namespace rive @@ -8,7 +9,7 @@ namespace rive class DataValue { public: - virtual ~DataValue(){}; + virtual ~DataValue() {}; virtual bool isTypeOf(DataType dataType) const { return false; } template inline bool is() const { @@ -19,6 +20,9 @@ class DataValue assert(is()); return static_cast(this); } + virtual bool compare(DataValue* comparand) { return false; } + virtual void interpolate(DataValue* to, DataValue* data, float mix) {} + virtual void copyValue(DataValue* destination) {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_artboard.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_artboard.hpp new file mode 100644 index 000000000..d18662e2d --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_artboard.hpp @@ -0,0 +1,22 @@ +#ifndef _RIVE_DATA_VALUE_ARTBOARD_HPP_ +#define _RIVE_DATA_VALUE_ARTBOARD_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" + +#include +namespace rive +{ +class DataValueArtboard : public DataValueInteger +{ +public: + DataValueArtboard(uint32_t value) : DataValueInteger(value) {}; + DataValueArtboard() : DataValueInteger(-1) {}; + static const DataType typeKey = DataType::artboard; + bool isTypeOf(DataType typeKey) const override + { + return typeKey == DataType::artboard || typeKey == DataType::integer; + }; + constexpr static uint32_t defaultValue = -1; +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_asset_image.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_asset_image.hpp index 62b5090fb..2ee9da6cc 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_asset_image.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_asset_image.hpp @@ -1,26 +1,35 @@ #ifndef _RIVE_DATA_VALUE_ASSET_IMAGE_HPP_ #define _RIVE_DATA_VALUE_ASSET_IMAGE_HPP_ -#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" +#include "rive/assets/image_asset.hpp" +#include "rive/renderer.hpp" #include namespace rive { -class DataValueAssetImage : public DataValue +class DataValueAssetImage : public DataValueInteger { -private: - uint32_t m_value = -1; - public: - DataValueAssetImage(uint32_t value) : m_value(value){}; - DataValueAssetImage(){}; + DataValueAssetImage(uint32_t value) : + DataValueInteger(value), + m_fileAsset(rcp(new ImageAsset())) {}; + DataValueAssetImage() : + DataValueInteger(-1), m_fileAsset(rcp(new ImageAsset())) {}; static const DataType typeKey = DataType::assetImage; bool isTypeOf(DataType typeKey) const override { - return typeKey == DataType::assetImage; + return typeKey == DataType::assetImage || typeKey == DataType::integer; }; - uint32_t value() { return m_value; }; - void value(uint32_t value) { m_value = value; }; constexpr static uint32_t defaultValue = -1; + rcp fileAsset() { return m_fileAsset; } + void imageValue(RenderImage* image) + { + m_fileAsset->renderImage(ref_rcp(image)); + } + RenderImage* imageValue() { return m_fileAsset->renderImage(); } + +private: + rcp m_fileAsset = nullptr; }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_boolean.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_boolean.hpp index ba42e7909..e12ebb6aa 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_boolean.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_boolean.hpp @@ -11,8 +11,8 @@ class DataValueBoolean : public DataValue bool m_value = false; public: - DataValueBoolean(bool value) : m_value(value){}; - DataValueBoolean(){}; + DataValueBoolean(bool value) : m_value(value) {}; + DataValueBoolean() {}; static const DataType typeKey = DataType::boolean; bool isTypeOf(DataType typeKey) const override { diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_color.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_color.hpp index a8096755b..d204d9a25 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_color.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_color.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_DATA_VALUE_COLOR_HPP_ #define _RIVE_DATA_VALUE_COLOR_HPP_ #include "rive/data_bind/data_values/data_value.hpp" +#include "rive/shapes/paint/color.hpp" #include namespace rive @@ -11,8 +12,8 @@ class DataValueColor : public DataValue int m_value = 0; public: - DataValueColor(int value) : m_value(value){}; - DataValueColor(){}; + DataValueColor(int value) : m_value(value) {}; + DataValueColor() {}; static const DataType typeKey = DataType::color; bool isTypeOf(DataType typeKey) const override { @@ -20,6 +21,40 @@ class DataValueColor : public DataValue } int value() { return m_value; }; void value(int value) { m_value = value; }; + int alpha() { return (m_value >> 24) & 0xFF; } + int red() { return (m_value >> 16) & 0xFF; } + int green() { return (m_value >> 8) & 0xFF; } + int blue() { return m_value & 0xFF; } + void alpha(int value) { m_value = (m_value & 0x00FFFFFF) | (value << 24); } + void red(int value) { m_value = (m_value & 0xFF00FFFF) | (value << 16); } + void green(int value) { m_value = (m_value & 0xFFFF00FF) | (value << 8); } + void blue(int value) { m_value = (m_value & 0xFFFFFF00) | value; } + bool compare(DataValue* comparand) override + { + if (comparand->is()) + { + return comparand->as()->value() == m_value; + } + return false; + } + void interpolate(DataValue* to, DataValue* data, float f) override + { + if (to->is() && data->is()) + { + auto fromValue = static_cast(value()); + auto toValue = + static_cast(to->as()->value()); + auto mixedColor = colorLerp(fromValue, toValue, f); + data->as()->value(mixedColor); + } + } + void copyValue(DataValue* destination) override + { + if (destination->is()) + { + destination->as()->value(value()); + } + } static const int defaultValue = 0; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_enum.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_enum.hpp index d7b172edf..87b974136 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_enum.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_enum.hpp @@ -1,31 +1,28 @@ #ifndef _RIVE_DATA_VALUE_ENUM_HPP_ #define _RIVE_DATA_VALUE_ENUM_HPP_ #include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" #include "rive/viewmodel/data_enum.hpp" #include namespace rive { -class DataValueEnum : public DataValue +class DataValueEnum : public DataValueInteger { private: - uint32_t m_value = 0; DataEnum* m_dataEnum; public: DataValueEnum(uint32_t value, DataEnum* dataEnum) : - m_value(value), m_dataEnum(dataEnum){}; - DataValueEnum(){}; + DataValueInteger(value), m_dataEnum(dataEnum) {}; + DataValueEnum() {}; static const DataType typeKey = DataType::enumType; bool isTypeOf(DataType typeKey) const override { - return typeKey == DataType::enumType; + return typeKey == DataType::enumType || typeKey == DataType::integer; }; - uint32_t value() { return m_value; }; - void value(uint32_t value) { m_value = value; }; DataEnum* dataEnum() { return m_dataEnum; }; void dataEnum(DataEnum* value) { m_dataEnum = value; }; - static const uint32_t defaultValue = 0; }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_integer.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_integer.hpp index 4e71ddf5e..886bb2a10 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_integer.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_integer.hpp @@ -11,12 +11,12 @@ class DataValueInteger : public DataValue uint32_t m_value = 0; public: - DataValueInteger(uint32_t value) : m_value(value){}; - DataValueInteger(){}; - static const DataType typeKey = DataType::trigger; + DataValueInteger(uint32_t value) : m_value(value) {}; + DataValueInteger() {}; + static const DataType typeKey = DataType::integer; bool isTypeOf(DataType typeKey) const override { - return typeKey == DataType::trigger; + return typeKey == DataType::integer; } uint32_t value() { return m_value; }; void value(uint32_t value) { m_value = value; }; diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_list.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_list.hpp index b10068d40..75f90280e 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_list.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_list.hpp @@ -10,21 +10,24 @@ namespace rive class DataValueList : public DataValue { private: - std::vector m_value; + std::vector> m_value; public: - DataValueList(){}; + DataValueList() {}; static const DataType typeKey = DataType::list; bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::list; } - std::vector* value() { return &m_value; }; + std::vector>* value() { return &m_value; }; void clear() { m_value.clear(); }; - void addItem(ViewModelInstanceListItem* item) { m_value.push_back(item); }; + void addItem(rcp item) + { + m_value.push_back(item); + }; // void value(std::vector* value) { m_value = // value; }; - constexpr static std::vector* defaultValue = + constexpr static std::vector>* defaultValue = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_number.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_number.hpp index 85e8f7cc4..232195fe3 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_number.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_number.hpp @@ -11,8 +11,8 @@ class DataValueNumber : public DataValue float m_value = 0; public: - DataValueNumber(float value) : m_value(value){}; - DataValueNumber(){}; + DataValueNumber(float value) : m_value(value) {}; + DataValueNumber() {}; static const DataType typeKey = DataType::number; bool isTypeOf(DataType typeKey) const override { @@ -21,6 +21,33 @@ class DataValueNumber : public DataValue float value() { return m_value; }; void value(float value) { m_value = value; }; constexpr static const float defaultValue = 0; + bool compare(DataValue* comparand) override + { + if (comparand != nullptr && comparand->is()) + { + return comparand->as()->value() == m_value; + } + return false; + } + void interpolate(DataValue* to, DataValue* destination, float f) override + { + if (to != nullptr && to->is() && + destination != nullptr && destination->is()) + { + auto fromValue = value(); + auto toValue = to->as()->value(); + float fi = 1.0f - f; + auto result = toValue * f + fromValue * fi; + destination->as()->value(result); + } + } + void copyValue(DataValue* destination) override + { + if (destination != nullptr && destination->is()) + { + destination->as()->value(value()); + } + } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_string.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_string.hpp index e572511e4..0a6fd3b43 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_string.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_string.hpp @@ -11,14 +11,14 @@ class DataValueString : public DataValue std::string m_value = ""; public: - DataValueString(std::string value) : m_value(value){}; - DataValueString(){}; + DataValueString(std::string value) : m_value(value) {}; + DataValueString() {}; static const DataType typeKey = DataType::string; bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::string; }; - std::string value() { return m_value; }; + const std::string& value() { return m_value; }; void value(std::string value) { m_value = value; }; constexpr static const char* defaultValue = ""; }; diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_symbol_list_index.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_symbol_list_index.hpp index a08d24a78..332826ec3 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_symbol_list_index.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_symbol_list_index.hpp @@ -9,8 +9,8 @@ class DataValueSymbolListIndex : public DataValueInteger { public: - DataValueSymbolListIndex(uint32_t value) : DataValueInteger(value){}; - DataValueSymbolListIndex(){}; + DataValueSymbolListIndex(uint32_t value) : DataValueInteger(value) {}; + DataValueSymbolListIndex() {}; static const DataType typeKey = DataType::symbolListIndex; bool isTypeOf(DataType typeKey) const override { diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_trigger.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_trigger.hpp index f7424c0d6..0067edeaf 100644 --- a/thirdparty/rive/include/rive/data_bind/data_values/data_value_trigger.hpp +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_trigger.hpp @@ -9,12 +9,12 @@ class DataValueTrigger : public DataValueInteger { public: - DataValueTrigger(uint32_t value) : DataValueInteger(value){}; - DataValueTrigger(){}; + DataValueTrigger(uint32_t value) : DataValueInteger(value) {}; + DataValueTrigger() {}; static const DataType typeKey = DataType::trigger; bool isTypeOf(DataType typeKey) const override { - return typeKey == DataType::trigger; + return typeKey == DataType::trigger || typeKey == DataType::integer; } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/data_bind/data_values/data_value_viewmodel.hpp b/thirdparty/rive/include/rive/data_bind/data_values/data_value_viewmodel.hpp new file mode 100644 index 000000000..5d23b593c --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind/data_values/data_value_viewmodel.hpp @@ -0,0 +1,28 @@ +#ifndef _RIVE_DATA_VALUE_VIEWMODEL_HPP_ +#define _RIVE_DATA_VALUE_VIEWMODEL_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" + +#include +namespace rive +{ +class DataValueViewModel : public DataValue +{ +private: + ViewModelInstance* m_value = nullptr; + +public: + DataValueViewModel() {}; + static const DataType typeKey = DataType::viewModel; + bool isTypeOf(DataType typeKey) const override + { + return typeKey == DataType::viewModel; + } + ViewModelInstance* value() { return m_value; }; + void value(ViewModelInstance* value) { m_value = value; }; + + constexpr static ViewModelInstance* defaultValue = nullptr; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_bind_flags.hpp b/thirdparty/rive/include/rive/data_bind_flags.hpp index 2d8561fd5..8f54892a0 100644 --- a/thirdparty/rive/include/rive/data_bind_flags.hpp +++ b/thirdparty/rive/include/rive/data_bind_flags.hpp @@ -1,12 +1,14 @@ #ifndef _RIVE_DATA_BIND_FLAGS_HPP_ #define _RIVE_DATA_BIND_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { enum class DataBindFlags : unsigned short { + None = 0, + /// Whether the main binding direction is to source (0) or to target (1) Direction = 1 << 0, @@ -16,6 +18,12 @@ enum class DataBindFlags : unsigned short /// Whether the binding happens only once Once = 1 << 2, + /// Whether source to target runs before target to source + SourceToTargetRunsFirst = 1 << 3, + + /// Whether source to target runs before target to source + NameBased = 1 << 4, + /// Flag if set to target ToTarget = 0, @@ -23,7 +31,5 @@ enum class DataBindFlags : unsigned short ToSource = 1 << 0, }; - -RIVE_MAKE_ENUM_BITSET(DataBindFlags) } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/data_bind_path_referencer.hpp b/thirdparty/rive/include/rive/data_bind_path_referencer.hpp new file mode 100644 index 000000000..429a61f6a --- /dev/null +++ b/thirdparty/rive/include/rive/data_bind_path_referencer.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_DATA_BIND_PATH_REFERENCER_HPP_ +#define _RIVE_DATA_BIND_PATH_REFERENCER_HPP_ +#include +#include "rive/data_bind/data_bind_path.hpp" +namespace rive +{ +class File; +class DataBindPathReferencer +{ +public: + ~DataBindPathReferencer(); + DataBindPath* dataBindPath() const { return m_dataBindPath; } + + void copyDataBindPath(DataBindPath* dataBindPath); + void importDataBindPath(ImportStack& importStack); + void decodeDataBindPath(Span& value); + +protected: + DataBindPath* m_dataBindPath = nullptr; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/data_resolver.hpp b/thirdparty/rive/include/rive/data_resolver.hpp new file mode 100644 index 000000000..75d47643b --- /dev/null +++ b/thirdparty/rive/include/rive/data_resolver.hpp @@ -0,0 +1,15 @@ +#ifndef _RIVE_DATA_RESOLVER_HPP_ +#define _RIVE_DATA_RESOLVER_HPP_ +#include +#include +namespace rive +{ +class DataResolver +{ +public: + virtual const std::string& resolveName(int id) = 0; + virtual const std::vector& resolvePath(int id) = 0; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/dependency_helper.hpp b/thirdparty/rive/include/rive/dependency_helper.hpp index af1c9a0de..b99bdd33c 100644 --- a/thirdparty/rive/include/rive/dependency_helper.hpp +++ b/thirdparty/rive/include/rive/dependency_helper.hpp @@ -51,6 +51,8 @@ template class DependencyHelper } const std::vector& dependents() const { return m_Dependents; } + + std::vector& mutableDependents() { return m_Dependents; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/drawable.hpp b/thirdparty/rive/include/rive/drawable.hpp index 5c421ee6b..33cc56ab4 100644 --- a/thirdparty/rive/include/rive/drawable.hpp +++ b/thirdparty/rive/include/rive/drawable.hpp @@ -27,11 +27,16 @@ class Drawable : public DrawableBase Drawable* prev = nullptr; Drawable* next = nullptr; +protected: + bool m_needsSaveOperation = true; + public: BlendMode blendMode() const { return (BlendMode)blendModeValue(); } - ClipResult applyClip(Renderer* renderer) const; virtual void draw(Renderer* renderer) = 0; virtual Core* hitTest(HitInfo*, const Mat2D&) = 0; + bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) override; void addClippingShape(ClippingShape* shape); inline const std::vector& clippingShapes() const { @@ -45,19 +50,26 @@ class Drawable : public DrawableBase hasDirt(ComponentDirt::Collapsed); } - inline bool isTargetOpaque() const + virtual bool isTargetOpaque() { return (static_cast(drawableFlags()) & DrawableFlag::Opaque) == DrawableFlag::Opaque; } virtual bool isProxy() { return false; } + virtual bool isClipStart() { return false; } + virtual bool isClipEnd() { return false; } + virtual bool willClip() { return false; } + virtual bool willDraw(); + void needsSaveOperation(bool value) { m_needsSaveOperation = value; } bool isChildOfLayout(LayoutComponent* layout); StatusCode onAddedDirty(CoreContext* context) override; virtual Drawable* hittableComponent() { return this; } + + virtual int emptyClipCount() { return 0; } }; class ProxyDrawing @@ -84,7 +96,7 @@ class DrawableProxy : public Drawable Drawable* hittableComponent() override; - bool isTargetOpaque(); + bool isTargetOpaque() override; Core* hitTest(HitInfo*, const Mat2D&) override { return nullptr; } diff --git a/thirdparty/rive/include/rive/drawable_flag.hpp b/thirdparty/rive/include/rive/drawable_flag.hpp index fac31ad6f..5efe73749 100644 --- a/thirdparty/rive/include/rive/drawable_flag.hpp +++ b/thirdparty/rive/include/rive/drawable_flag.hpp @@ -1,7 +1,7 @@ #ifndef _RIVE_DRAWABLE_FLAGS_HPP_ #define _RIVE_DRAWABLE_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { @@ -26,6 +26,5 @@ enum class DrawableFlag : unsigned short /// Using Clean instead of dirty so it doesn't need to be initialized to 1 WorldBoundsClean = 1 << 4, }; -RIVE_MAKE_ENUM_BITSET(DrawableFlag) } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/enum_bitset.hpp b/thirdparty/rive/include/rive/enum_bitset.hpp deleted file mode 100644 index 0d78c381f..000000000 --- a/thirdparty/rive/include/rive/enum_bitset.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#ifndef _RIVE_ENUM_BITSET_HPP_ -#define _RIVE_ENUM_BITSET_HPP_ - -#include - -namespace rive -{ -// Wraps an enum containing a bitfield so that we can do implicit bool -// conversions. -template class EnumBitset -{ -public: - using UnderlyingType = typename std::underlying_type::type; - constexpr EnumBitset() = default; - constexpr EnumBitset(T value) : m_bits(static_cast(value)) - {} - constexpr UnderlyingType bits() const { return m_bits; } - constexpr T value() const { return static_cast(m_bits); } - constexpr operator T() const { return value(); } - constexpr operator bool() const { return m_bits != 0; } - -private: - UnderlyingType m_bits = 0; -}; -} // namespace rive - -#define RIVE_MAKE_ENUM_BITSET(ENUM) \ - constexpr inline ::rive::EnumBitset operator&( \ - ::rive::EnumBitset lhs, \ - ::rive::EnumBitset rhs) \ - { \ - return static_cast(lhs.bits() & rhs.bits()); \ - } \ - constexpr inline ::rive::EnumBitset operator&( \ - ENUM lhs, \ - ::rive::EnumBitset rhs) \ - { \ - return ::rive::EnumBitset(lhs) & rhs; \ - } \ - constexpr inline ::rive::EnumBitset operator&( \ - ::rive::EnumBitset lhs, \ - ENUM rhs) \ - { \ - return lhs & ::rive::EnumBitset(rhs); \ - } \ - constexpr inline ::rive::EnumBitset operator&(ENUM lhs, ENUM rhs) \ - { \ - return ::rive::EnumBitset(lhs) & ::rive::EnumBitset(rhs); \ - } \ - \ - constexpr inline ::rive::EnumBitset operator|( \ - ::rive::EnumBitset lhs, \ - ::rive::EnumBitset rhs) \ - { \ - return static_cast(lhs.bits() | rhs.bits()); \ - } \ - constexpr inline ::rive::EnumBitset operator|( \ - ENUM lhs, \ - ::rive::EnumBitset rhs) \ - { \ - return ::rive::EnumBitset(lhs) | rhs; \ - } \ - constexpr inline ::rive::EnumBitset operator|( \ - ::rive::EnumBitset lhs, \ - ENUM rhs) \ - { \ - return lhs | ::rive::EnumBitset(rhs); \ - } \ - constexpr inline ::rive::EnumBitset operator|(ENUM lhs, ENUM rhs) \ - { \ - return ::rive::EnumBitset(lhs) | ::rive::EnumBitset(rhs); \ - } \ - \ - constexpr inline ::rive::EnumBitset operator~( \ - ::rive::EnumBitset rhs) \ - { \ - return static_cast(~rhs.bits()); \ - } \ - constexpr inline ::rive::EnumBitset operator~(ENUM rhs) \ - { \ - return ~::rive::EnumBitset(rhs); \ - } \ - \ - inline ENUM& operator&=(ENUM& lhs, ::rive::EnumBitset rhs) \ - { \ - return lhs = lhs & rhs; \ - } \ - inline ENUM& operator&=(ENUM& lhs, ENUM rhs) { return lhs = lhs & rhs; } \ - \ - inline ENUM& operator|=(ENUM& lhs, ::rive::EnumBitset rhs) \ - { \ - return lhs = lhs | rhs; \ - } \ - inline ENUM& operator|=(ENUM& lhs, ENUM rhs) { return lhs = lhs | rhs; } - -#define RIVE_DECL_ENUM_BITSET_FRIENDS(ENUM) \ - friend constexpr ::rive::EnumBitset operator&( \ - ::rive::EnumBitset, \ - ::rive::EnumBitset); \ - friend constexpr ::rive::EnumBitset operator&( \ - ENUM, \ - ::rive::EnumBitset); \ - friend constexpr ::rive::EnumBitset operator&( \ - ::rive::EnumBitset, \ - ENUM); \ - friend constexpr ::rive::EnumBitset operator&(ENUM, ENUM); \ - friend constexpr ::rive::EnumBitset operator|( \ - ::rive::EnumBitset, \ - ::rive::EnumBitset); \ - friend constexpr ::rive::EnumBitset operator|( \ - ENUM, \ - ::rive::EnumBitset); \ - friend constexpr ::rive::EnumBitset operator|( \ - ::rive::EnumBitset, \ - ENUM); \ - friend constexpr ::rive::EnumBitset operator|(ENUM lhs, ENUM rhs); \ - friend constexpr ::rive::EnumBitset operator~( \ - ::rive::EnumBitset rhs); \ - friend constexpr ::rive::EnumBitset operator~(ENUM rhs); \ - friend ENUM& operator&=(ENUM& lhs, ::rive::EnumBitset rhs); \ - friend ENUM& operator&=(ENUM& lhs, ENUM rhs); \ - friend ENUM& operator|=(ENUM& lhs, ::rive::EnumBitset rhs); \ - friend ENUM& operator|=(ENUM& lhs, ENUM rhs); - -#endif diff --git a/thirdparty/rive/include/rive/enums.hpp b/thirdparty/rive/include/rive/enums.hpp new file mode 100644 index 000000000..9ae1a4e55 --- /dev/null +++ b/thirdparty/rive/include/rive/enums.hpp @@ -0,0 +1,178 @@ +/* + * Copyright 2023 Rive + */ + +#ifndef _RIVE_ENUM_BITSET_HPP_ +#define _RIVE_ENUM_BITSET_HPP_ + +#include +#include + +namespace rive::enums +{ + +namespace internal +{ +// Helper struct to test whether a type is a scoped enum ("enum class" or +// "enum struct") +template +struct IsScopedEnumImpl : std::is_enum +{}; + +// non-scoped enums are implicitly convertible to integers, which means the +// unary + operator works for them. If the unary + operation works, then the +// given type is actually a scoped enum. +template +struct IsScopedEnumImpl()))> + : std::false_type +{}; + +template +constexpr bool is_scoped_enum = IsScopedEnumImpl::value; + +// Helper struct to test whether a type is a "flag enum" (which would be a +// scoped enum that has either a "none", "None", or "NONE" element that equals +// 0. +template +struct IsFlagEnumImpl : std::false_type +{}; + +template +struct IsFlagEnumImpl + : std::integral_constant&& int(Enum::none) == 0> +{}; + +template +struct IsFlagEnumImpl + : std::integral_constant&& int(Enum::None) == 0> +{}; + +template +struct IsFlagEnumImpl + : std::integral_constant&& int(Enum::NONE) == 0> +{}; + +template +constexpr bool is_flag_enum = IsFlagEnumImpl::value; + +#define RIVE_ENABLE_IF_IS_SCOPED_ENUM(Enum) \ + template , int> = \ + 0> + +#define RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) \ + template , int> = 0> + +} // namespace internal + +RIVE_ENABLE_IF_IS_SCOPED_ENUM(Enum) +constexpr std::underlying_type_t underlying_value(Enum v) noexcept +{ + return std::underlying_type_t(v); +} + +RIVE_ENABLE_IF_IS_SCOPED_ENUM(Enum) +constexpr Enum incr(Enum v) noexcept { return Enum(underlying_value(v) + 1); } + +RIVE_ENABLE_IF_IS_SCOPED_ENUM(Enum) +constexpr Enum decr(Enum v) noexcept { return Enum(underlying_value(v) - 1); } + +} // namespace rive::enums + +// The operators need to live in the base `rive` namespace so they're +// discoverable from anywhere in the codebase +namespace rive +{ + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum operator&(Enum a, Enum b) noexcept +{ + return Enum(enums::underlying_value(a) & enums::underlying_value(b)); +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum operator^(Enum a, Enum b) noexcept +{ + return Enum(enums::underlying_value(a) ^ enums::underlying_value(b)); +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum operator|(Enum a, Enum b) noexcept +{ + return Enum(enums::underlying_value(a) | enums::underlying_value(b)); +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum operator~(Enum a) noexcept +{ + return Enum(~enums::underlying_value(a)); +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum& operator&=(Enum& a, Enum b) noexcept +{ + a = (a & b); + return a; +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum& operator^=(Enum& a, Enum b) noexcept +{ + a = (a ^ b); + return a; +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +inline constexpr Enum& operator|=(Enum& a, Enum b) noexcept +{ + a = (a | b); + return a; +} +} // namespace rive + +namespace rive::enums +{ +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool is_single_flag(Enum flags) noexcept +{ + auto u = underlying_value(flags); + return u != 0 && (u & (u - 1)) == 0; +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool is_flag_set(Enum flags, Enum testFlag) noexcept +{ + assert(is_single_flag(testFlag)); + return (flags & testFlag) != Enum(0); +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool any_flag_set(Enum flags) noexcept { return flags != Enum(0); } + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool any_flag_set(Enum flags, Enum mask) noexcept +{ + return any_flag_set(flags & mask); +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool all_flags_set(Enum flags, Enum mask) noexcept +{ + return (flags & mask) == mask; +} + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool no_flags_set(Enum flags) noexcept { return flags == Enum(0); } + +RIVE_ENABLE_IF_IS_FLAG_ENUM(Enum) +constexpr bool no_flags_set(Enum flags, Enum mask) noexcept +{ + return no_flags_set(flags & mask); +} +} // namespace rive::enums + +#endif + +#undef RIVE_ENABLE_IF_IS_FLAG_ENUM +#undef RIVE_ENABLE_IF_IS_SCOPED_ENUM \ No newline at end of file diff --git a/thirdparty/rive/include/rive/file.hpp b/thirdparty/rive/include/rive/file.hpp index a73f893c8..77149a7bf 100644 --- a/thirdparty/rive/include/rive/file.hpp +++ b/thirdparty/rive/include/rive/file.hpp @@ -5,6 +5,7 @@ #include "rive/backboard.hpp" #include "rive/factory.hpp" #include "rive/file_asset_loader.hpp" +#include "rive/assets/manifest_asset.hpp" #include "rive/viewmodel/data_enum.hpp" #include "rive/viewmodel/viewmodel_component.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" @@ -12,20 +13,33 @@ #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance_list_item.hpp" #include "rive/animation/keyframe_interpolator.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +#include "rive/refcnt.hpp" +#include "rive/data_resolver.hpp" #include #include #include +#ifdef WITH_RIVE_SCRIPTING +struct lua_State; +#endif + /// /// Default namespace for Rive Cpp runtime code. /// namespace rive { +#ifdef WITH_RIVE_TOOLS +class ViewModelInstance; +#endif class BinaryReader; +class DataBind; class RuntimeHeader; class Factory; class ScrollPhysics; class ViewModelRuntime; +class BindableArtboard; +class ScriptingVM; /// /// Tracks the success/failure result when importing a Rive file. @@ -40,22 +54,44 @@ enum class ImportResult malformed }; +#ifdef WITH_RIVE_TOOLS +/// +/// Callback interface for registering view model instances (used by the +/// editor). Implemented in rive_binding to store instances in a map keyed by +/// File. +/// +class ViewModelInstanceRegistrar +{ +public: + virtual ~ViewModelInstanceRegistrar() = default; + virtual void registerInstance(ViewModelInstance* ptr, + rcp ref) = 0; + virtual bool contains(ViewModelInstance* ptr) const = 0; + virtual void clear() = 0; +}; +#endif + /// /// A Rive file. /// -class File +class File : public RefCnt { public: /// Major version number supported by the runtime. static const int majorVersion = 7; /// Minor version number supported by the runtime. static const int minorVersion = 0; + /// deterministicMode sets a static seed for randomization and uses + /// timestamps for scrolling. + static bool deterministicMode; File(Factory*, rcp); public: ~File(); - +#if defined(DEBUG) + static size_t debugTotalFileCount; +#endif /// /// Imports a Rive file from a binary buffer. /// @param data the raw date of the file. @@ -63,18 +99,20 @@ class File /// @param assetLoader is an optional helper to load assets which /// cannot be found in-band. /// @returns a pointer to the file, or null on failure. - static std::unique_ptr import(Span data, - Factory* factory, - ImportResult* result = nullptr, - FileAssetLoader* assetLoader = nullptr) + static rcp import(Span data, + Factory* factory, + ImportResult* result = nullptr, + FileAssetLoader* assetLoader = nullptr, + ScriptingVM* vm = nullptr) { - return import(data, factory, result, ref_rcp(assetLoader)); + return import(data, factory, result, ref_rcp(assetLoader), vm); } - static std::unique_ptr import(Span data, - Factory*, - ImportResult* result, - rcp assetLoader); + static rcp import(Span data, + Factory*, + ImportResult* result, + rcp assetLoader, + ScriptingVM* vm = nullptr); /// @returns the file's backboard. All files have exactly one backboard. Backboard* backboard() const { return m_backboard; } @@ -83,12 +121,15 @@ class File size_t artboardCount() const { return m_artboards.size(); } std::string artboardNameAt(size_t index) const; - const std::vector& assets() const; + Span> assets() const; // Instances std::unique_ptr artboardDefault() const; std::unique_ptr artboardAt(size_t index) const; std::unique_ptr artboardNamed(std::string name) const; + rcp bindableArtboardNamed(std::string name) const; + rcp bindableArtboardDefault() const; + rcp internalBindableArtboardFromArtboard(Artboard*) const; Artboard* artboard() const; @@ -123,8 +164,8 @@ class File /// @returns a view model instance of the viewModel by name and instance /// name. rcp createViewModelInstance( - std::string name, - std::string instanceName) const; + const std::string& name, + const std::string& instanceName) const; /// @returns a view model instance of the viewModel by their indexes. rcp createViewModelInstance(size_t index, @@ -143,15 +184,49 @@ class File Artboard* artboard); void completeViewModelInstance( rcp viewModelInstance, - std::unordered_map> + std::unordered_map>& instancesMap) const; void completeViewModelInstance( rcp viewModelInstance) const; + void completeViewModelProperties(ViewModelInstance* viewModelInstance); const std::vector& enums() const; - FileAsset* asset(size_t index); + rcp asset(size_t index); std::vector artboards() { return m_artboards; }; + bool hasAudio() const { return m_hasAudio; }; + void addFileViewModelInstance(ViewModelInstance* viewModelInstance); + + // When the runtime is hosted in the editor, we get a pointer + // to the VM that we can use. If this is nullptr, we can assume + // we are running in the runtime and should instance our own VMs + // and pass them down to the root +#ifdef WITH_RIVE_SCRIPTING + /// Sets or replaces the ScriptingVM. Takes shared ownership via rcp. + void setScriptingVM(rcp vm); + + /// Returns the ScriptingVM, or nullptr if no VM is set. + ScriptingVM* scriptingVM() { return m_scriptingVM.get(); } + + /// Returns the lua_State from the current VM, or nullptr if no VM is set. + /// Do not hold a reference to this as the lifecycle is owned by the + /// ScriptingVM owning it. + lua_State* scriptingState(); +#ifdef WITH_RIVE_TOOLS + void clearScriptingVM() { cleanupScriptingVM(); } + bool hasVM() { return m_scriptingVM != nullptr; } +#endif +#endif + + DataResolver* dataResolver() + { + if (m_manifest) + { + return m_manifest.get()->as(); + } + return nullptr; + } + #ifdef WITH_RIVE_TOOLS /// Strips FileAssetContents for FileAssets of given typeKeys. /// @param data the raw data of the file. @@ -170,16 +245,24 @@ class File return m_assetLoader.get(); } #endif +#ifdef WITH_RIVE_TOOLS + void setViewModelInstanceRegistrar(ViewModelInstanceRegistrar* registrar); + void registerViewModelInstance(ViewModelInstance* ptr, + rcp ref) const; + bool containsViewModelInstance(ViewModelInstance* ptr) const; + void clearRuntimeViewModelInstances(); +#endif private: ImportResult read(BinaryReader&, const RuntimeHeader&); + std::unique_ptr instanceArtboard(Artboard* ab) const; /// The file's backboard. All Rive files have a single backboard /// where the artboards live. Backboard* m_backboard; /// We just keep these alive for the life of this File - std::vector m_fileAssets; + std::vector> m_fileAssets; std::vector m_DataConverters; @@ -197,9 +280,9 @@ class File /// List of view models instances in the file. We keep this list to keep /// them alive during the lifetime of this file. This list does not hold a /// reference to instances created by users. - std::vector m_ViewModelInstances; + std::vector> m_ViewModelInstances; - mutable std::vector m_viewModelRuntimes; + mutable std::vector> m_viewModelRuntimes; std::vector m_Enums; Factory* m_factory; @@ -208,14 +291,28 @@ class File /// with the file. rcp m_assetLoader; +#ifdef WITH_RIVE_SCRIPTING + rcp m_scriptingVM; + void makeScriptingVM(); + void cleanupScriptingVM(); + void registerScripts(); +#endif + rcp copyViewModelInstance( ViewModelInstance* viewModelInstance, - std::unordered_map> + std::unordered_map>& instancesMap) const; - ViewModelRuntime* createViewModelRuntime(ViewModel* viewModel) const; + rcp createViewModelRuntime(ViewModel* viewModel) const; uint32_t findViewModelId(ViewModel* search) const; +#ifdef WITH_RIVE_TOOLS + mutable ViewModelInstanceRegistrar* m_viewModelInstanceRegistrar = nullptr; +#endif + + rcp m_manifest = nullptr; + + bool m_hasAudio = false; }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/focus_data.hpp b/thirdparty/rive/include/rive/focus_data.hpp new file mode 100644 index 000000000..5adc928af --- /dev/null +++ b/thirdparty/rive/include/rive/focus_data.hpp @@ -0,0 +1,96 @@ +#ifndef _RIVE_FOCUS_DATA_HPP_ +#define _RIVE_FOCUS_DATA_HPP_ +#include "rive/component_dirt.hpp" +#include "rive/generated/focus_data_base.hpp" +#include "rive/input/focus_node.hpp" +#include "rive/input/keyboard_listener.hpp" +#include "rive/input/focusable.hpp" +#include "rive/math/aabb.hpp" +#include "rive/refcnt.hpp" +#include + +namespace rive +{ + +class FocusListener; + +class FocusData : public FocusDataBase, public Focusable +{ +public: + ~FocusData() override; + + rcp focusNode(); + + /// Register a listener to be notified of focus/blur events. + void addFocusListener(FocusListener* listener); + + /// Unregister a listener. + void removeFocusListener(FocusListener* listener); + + /// Register a listener to be notified of key input events. + void addKeyboardListener(KeyboardListener* listener); + + /// Unregister a keyboard listener. + void removeKeyboardListener(KeyboardListener* listener); + + /// Register a listener to be notified of text input events. + void addTextInputListener(KeyboardListener* listener); + + /// Unregister a text input listener. + void removeTextInputListener(KeyboardListener* listener); + + /// Programmatically focus this node. + void focus(); + + /// Find the parent FocusData by walking up the component hierarchy. + /// Returns nullptr if no parent FocusData exists. + FocusData* findParentFocusData() const; + + /// Find the closest FocusNode for a component by walking up the hierarchy. + /// Checks parent nodes for FocusData children, and crosses artboard + /// boundaries using externalParentFocusNode. + /// @param component The component to start searching from + /// @return The closest FocusNode, or nullptr if none found + static rcp findClosestFocusNode(Component* component); + + /// True if this focus target should participate in tab/spatial navigation + /// and pointer focus (not under a collapsed/hidden/opacity-zero branch, + /// including nested artboard hosts). Non-FocusData focusables are treated + /// as visible by FocusManager. + bool isEligibleForFocusTraversal() const override; + + // Focusable interface implementation + bool keyInput(Key value, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) override; + bool textInput(const std::string& text) override; + void focused() override; + void blurred() override; + bool worldPosition(Vec2D& outPosition) override; + Artboard* focusableArtboard() const override { return artboard(); } + + // Component overrides for update cycle + void buildDependencies() override; + void update(ComponentDirt value) override; + +protected: + void canFocusChanged() override; + void canTouchChanged() override; + void canTraverseChanged() override; + void edgeBehaviorValueChanged() override; + void nameChanged() override; + +private: + void updateWorldBounds(); + void scrollIntoView(); + void scrollConstraintToShowBounds(class ScrollConstraint* constraint, + const AABB& elementBounds); + rcp m_focusNode; + std::vector m_focusListeners; + std::vector m_keyboardListeners; + std::vector m_textInputListeners; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/generated/animation/focus_action_base.hpp b/thirdparty/rive/include/rive/generated/animation/focus_action_base.hpp new file mode 100644 index 000000000..bf517fddf --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/focus_action_base.hpp @@ -0,0 +1,34 @@ +#ifndef _RIVE_FOCUS_ACTION_BASE_HPP_ +#define _RIVE_FOCUS_ACTION_BASE_HPP_ +#include "rive/animation/listener_action.hpp" +namespace rive +{ +class FocusActionBase : public ListenerAction +{ +protected: + typedef ListenerAction Super; + +public: + static const uint16_t typeKey = 671; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case FocusActionBase::typeKey: + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/focus_action_target_base.hpp b/thirdparty/rive/include/rive/generated/animation/focus_action_target_base.hpp new file mode 100644 index 000000000..a028ba69d --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/focus_action_target_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_FOCUS_ACTION_TARGET_BASE_HPP_ +#define _RIVE_FOCUS_ACTION_TARGET_BASE_HPP_ +#include "rive/animation/focus_action.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class FocusActionTargetBase : public FocusAction +{ +protected: + typedef FocusAction Super; + +public: + static const uint16_t typeKey = 652; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case FocusActionTargetBase::typeKey: + case FocusActionBase::typeKey: + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t targetIdPropertyKey = 952; + +protected: + uint32_t m_TargetId = -1; + +public: + inline uint32_t targetId() const { return m_TargetId; } + void targetId(uint32_t value) + { + if (m_TargetId == value) + { + return; + } + m_TargetId = value; + targetIdChanged(); + } + + Core* clone() const override; + void copy(const FocusActionTargetBase& object) + { + m_TargetId = object.m_TargetId; + FocusAction::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case targetIdPropertyKey: + m_TargetId = CoreUintType::deserialize(reader); + return true; + } + return FocusAction::deserialize(propertyKey, reader); + } + +protected: + virtual void targetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/focus_action_traversal_base.hpp b/thirdparty/rive/include/rive/generated/animation/focus_action_traversal_base.hpp new file mode 100644 index 000000000..756ccd080 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/focus_action_traversal_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_FOCUS_ACTION_TRAVERSAL_BASE_HPP_ +#define _RIVE_FOCUS_ACTION_TRAVERSAL_BASE_HPP_ +#include "rive/animation/focus_action.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class FocusActionTraversalBase : public FocusAction +{ +protected: + typedef FocusAction Super; + +public: + static const uint16_t typeKey = 672; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case FocusActionTraversalBase::typeKey: + case FocusActionBase::typeKey: + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t traversalKindPropertyKey = 1011; + +protected: + uint32_t m_TraversalKind = 0; + +public: + inline uint32_t traversalKind() const { return m_TraversalKind; } + void traversalKind(uint32_t value) + { + if (m_TraversalKind == value) + { + return; + } + m_TraversalKind = value; + traversalKindChanged(); + } + + Core* clone() const override; + void copy(const FocusActionTraversalBase& object) + { + m_TraversalKind = object.m_TraversalKind; + FocusAction::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case traversalKindPropertyKey: + m_TraversalKind = CoreUintType::deserialize(reader); + return true; + } + return FocusAction::deserialize(propertyKey, reader); + } + +protected: + virtual void traversalKindChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/listener_action_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_action_base.hpp index 9437fa814..d195f14ca 100644 --- a/thirdparty/rive/include/rive/generated/animation/listener_action_base.hpp +++ b/thirdparty/rive/include/rive/generated/animation/listener_action_base.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_LISTENER_ACTION_BASE_HPP_ #define _RIVE_LISTENER_ACTION_BASE_HPP_ #include "rive/core.hpp" +#include "rive/core/field_types/core_uint_type.hpp" namespace rive { class ListenerActionBase : public Core @@ -26,14 +27,38 @@ class ListenerActionBase : public Core uint16_t coreType() const override { return typeKey; } - void copy(const ListenerActionBase& object) {} + static const uint16_t flagsPropertyKey = 980; + +protected: + uint32_t m_Flags = 0; + +public: + inline uint32_t flags() const { return m_Flags; } + void flags(uint32_t value) + { + if (m_Flags == value) + { + return; + } + m_Flags = value; + flagsChanged(); + } + + void copy(const ListenerActionBase& object) { m_Flags = object.m_Flags; } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { + switch (propertyKey) + { + case flagsPropertyKey: + m_Flags = CoreUintType::deserialize(reader); + return true; + } return false; } protected: + virtual void flagsChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_base.hpp new file mode 100644 index 000000000..c393a4cb3 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_base.hpp @@ -0,0 +1,69 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_BASE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_BASE_HPP_ +#include "rive/core.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ListenerInputTypeBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 658; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerInputTypeBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t listenerTypeValuePropertyKey = 965; + +protected: + uint32_t m_ListenerTypeValue = 0; + +public: + inline uint32_t listenerTypeValue() const { return m_ListenerTypeValue; } + void listenerTypeValue(uint32_t value) + { + if (m_ListenerTypeValue == value) + { + return; + } + m_ListenerTypeValue = value; + listenerTypeValueChanged(); + } + + Core* clone() const override; + void copy(const ListenerInputTypeBase& object) + { + m_ListenerTypeValue = object.m_ListenerTypeValue; + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case listenerTypeValuePropertyKey: + m_ListenerTypeValue = CoreUintType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void listenerTypeValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_event_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_event_base.hpp new file mode 100644 index 000000000..f0de47dd9 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_event_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_EVENT_BASE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_EVENT_BASE_HPP_ +#include "rive/animation/listener_types/listener_input_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ListenerInputTypeEventBase : public ListenerInputType +{ +protected: + typedef ListenerInputType Super; + +public: + static const uint16_t typeKey = 659; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerInputTypeEventBase::typeKey: + case ListenerInputTypeBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t eventIdPropertyKey = 962; + +protected: + uint32_t m_EventId = -1; + +public: + inline uint32_t eventId() const { return m_EventId; } + void eventId(uint32_t value) + { + if (m_EventId == value) + { + return; + } + m_EventId = value; + eventIdChanged(); + } + + Core* clone() const override; + void copy(const ListenerInputTypeEventBase& object) + { + m_EventId = object.m_EventId; + ListenerInputType::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case eventIdPropertyKey: + m_EventId = CoreUintType::deserialize(reader); + return true; + } + return ListenerInputType::deserialize(propertyKey, reader); + } + +protected: + virtual void eventIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp new file mode 100644 index 000000000..768d2970e --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_KEYBOARD_BASE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_KEYBOARD_BASE_HPP_ +#include "rive/animation/listener_types/listener_input_type.hpp" +namespace rive +{ +class ListenerInputTypeKeyboardBase : public ListenerInputType +{ +protected: + typedef ListenerInputType Super; + +public: + static const uint16_t typeKey = 665; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerInputTypeKeyboardBase::typeKey: + case ListenerInputTypeBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp new file mode 100644 index 000000000..6163b8f7b --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp @@ -0,0 +1,34 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_SEMANTIC_BASE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_SEMANTIC_BASE_HPP_ +#include "rive/animation/listener_types/listener_input_type.hpp" +namespace rive +{ +class ListenerInputTypeSemanticBase : public ListenerInputType +{ +protected: + typedef ListenerInputType Super; + +public: + static const uint16_t typeKey = 669; + + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerInputTypeSemanticBase::typeKey: + case ListenerInputTypeBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_text_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_text_base.hpp new file mode 100644 index 000000000..b102e5522 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_text_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_TEXT_BASE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_TEXT_BASE_HPP_ +#include "rive/animation/listener_types/listener_input_type.hpp" +namespace rive +{ +class ListenerInputTypeTextBase : public ListenerInputType +{ +protected: + typedef ListenerInputType Super; + +public: + static const uint16_t typeKey = 666; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerInputTypeTextBase::typeKey: + case ListenerInputTypeBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_viewmodel_base.hpp b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_viewmodel_base.hpp new file mode 100644 index 000000000..e657916a5 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/listener_types/listener_input_type_viewmodel_base.hpp @@ -0,0 +1,62 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_VIEW_MODEL_BASE_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_VIEW_MODEL_BASE_HPP_ +#include "rive/animation/listener_types/listener_input_type.hpp" +#include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/span.hpp" +namespace rive +{ +class ListenerInputTypeViewModelBase : public ListenerInputType +{ +protected: + typedef ListenerInputType Super; + +public: + static const uint16_t typeKey = 660; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerInputTypeViewModelBase::typeKey: + case ListenerInputTypeBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t viewModelPathIdsPropertyKey = 963; + +public: + virtual void decodeViewModelPathIds(Span value) = 0; + virtual void copyViewModelPathIds( + const ListenerInputTypeViewModelBase& object) = 0; + + Core* clone() const override; + void copy(const ListenerInputTypeViewModelBase& object) + { + copyViewModelPathIds(object); + ListenerInputType::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case viewModelPathIdsPropertyKey: + decodeViewModelPathIds(CoreBytesType::deserialize(reader)); + return true; + } + return ListenerInputType::deserialize(propertyKey, reader); + } + +protected: + virtual void viewModelPathIdsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/scripted_listener_action_base.hpp b/thirdparty/rive/include/rive/generated/animation/scripted_listener_action_base.hpp new file mode 100644 index 000000000..9a920330f --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/scripted_listener_action_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_SCRIPTED_LISTENER_ACTION_BASE_HPP_ +#define _RIVE_SCRIPTED_LISTENER_ACTION_BASE_HPP_ +#include "rive/animation/listener_action.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ScriptedListenerActionBase : public ListenerAction +{ +protected: + typedef ListenerAction Super; + +public: + static const uint16_t typeKey = 646; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptedListenerActionBase::typeKey: + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t scriptAssetIdPropertyKey = 930; + +protected: + uint32_t m_ScriptAssetId = -1; + +public: + inline uint32_t scriptAssetId() const { return m_ScriptAssetId; } + void scriptAssetId(uint32_t value) + { + if (m_ScriptAssetId == value) + { + return; + } + m_ScriptAssetId = value; + scriptAssetIdChanged(); + } + + Core* clone() const override; + void copy(const ScriptedListenerActionBase& object) + { + m_ScriptAssetId = object.m_ScriptAssetId; + ListenerAction::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case scriptAssetIdPropertyKey: + m_ScriptAssetId = CoreUintType::deserialize(reader); + return true; + } + return ListenerAction::deserialize(propertyKey, reader); + } + +protected: + virtual void scriptAssetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/scripted_transition_condition_base.hpp b/thirdparty/rive/include/rive/generated/animation/scripted_transition_condition_base.hpp new file mode 100644 index 000000000..01d08b59e --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/scripted_transition_condition_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_SCRIPTED_TRANSITION_CONDITION_BASE_HPP_ +#define _RIVE_SCRIPTED_TRANSITION_CONDITION_BASE_HPP_ +#include "rive/animation/transition_condition.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ScriptedTransitionConditionBase : public TransitionCondition +{ +protected: + typedef TransitionCondition Super; + +public: + static const uint16_t typeKey = 647; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptedTransitionConditionBase::typeKey: + case TransitionConditionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t scriptAssetIdPropertyKey = 931; + +protected: + uint32_t m_ScriptAssetId = -1; + +public: + inline uint32_t scriptAssetId() const { return m_ScriptAssetId; } + void scriptAssetId(uint32_t value) + { + if (m_ScriptAssetId == value) + { + return; + } + m_ScriptAssetId = value; + scriptAssetIdChanged(); + } + + Core* clone() const override; + void copy(const ScriptedTransitionConditionBase& object) + { + m_ScriptAssetId = object.m_ScriptAssetId; + TransitionCondition::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case scriptAssetIdPropertyKey: + m_ScriptAssetId = CoreUintType::deserialize(reader); + return true; + } + return TransitionCondition::deserialize(propertyKey, reader); + } + +protected: + virtual void scriptAssetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/state_machine_fire_action_base.hpp b/thirdparty/rive/include/rive/generated/animation/state_machine_fire_action_base.hpp new file mode 100644 index 000000000..a99107233 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/state_machine_fire_action_base.hpp @@ -0,0 +1,68 @@ +#ifndef _RIVE_STATE_MACHINE_FIRE_ACTION_BASE_HPP_ +#define _RIVE_STATE_MACHINE_FIRE_ACTION_BASE_HPP_ +#include "rive/core.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class StateMachineFireActionBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 615; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case StateMachineFireActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t occursValuePropertyKey = 393; + +protected: + uint32_t m_OccursValue = 0; + +public: + inline uint32_t occursValue() const { return m_OccursValue; } + void occursValue(uint32_t value) + { + if (m_OccursValue == value) + { + return; + } + m_OccursValue = value; + occursValueChanged(); + } + + void copy(const StateMachineFireActionBase& object) + { + m_OccursValue = object.m_OccursValue; + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case occursValuePropertyKey: + m_OccursValue = CoreUintType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void occursValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/state_machine_fire_event_base.hpp b/thirdparty/rive/include/rive/generated/animation/state_machine_fire_event_base.hpp index 34138da7e..6da429a9f 100644 --- a/thirdparty/rive/include/rive/generated/animation/state_machine_fire_event_base.hpp +++ b/thirdparty/rive/include/rive/generated/animation/state_machine_fire_event_base.hpp @@ -1,13 +1,13 @@ #ifndef _RIVE_STATE_MACHINE_FIRE_EVENT_BASE_HPP_ #define _RIVE_STATE_MACHINE_FIRE_EVENT_BASE_HPP_ -#include "rive/core.hpp" +#include "rive/animation/state_machine_fire_action.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { -class StateMachineFireEventBase : public Core +class StateMachineFireEventBase : public StateMachineFireAction { protected: - typedef Core Super; + typedef StateMachineFireAction Super; public: static const uint16_t typeKey = 169; @@ -19,6 +19,7 @@ class StateMachineFireEventBase : public Core switch (typeKey) { case StateMachineFireEventBase::typeKey: + case StateMachineFireActionBase::typeKey: return true; default: return false; @@ -28,11 +29,9 @@ class StateMachineFireEventBase : public Core uint16_t coreType() const override { return typeKey; } static const uint16_t eventIdPropertyKey = 392; - static const uint16_t occursValuePropertyKey = 393; protected: uint32_t m_EventId = -1; - uint32_t m_OccursValue = 0; public: inline uint32_t eventId() const { return m_EventId; } @@ -46,22 +45,11 @@ class StateMachineFireEventBase : public Core eventIdChanged(); } - inline uint32_t occursValue() const { return m_OccursValue; } - void occursValue(uint32_t value) - { - if (m_OccursValue == value) - { - return; - } - m_OccursValue = value; - occursValueChanged(); - } - Core* clone() const override; void copy(const StateMachineFireEventBase& object) { m_EventId = object.m_EventId; - m_OccursValue = object.m_OccursValue; + StateMachineFireAction::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override @@ -71,16 +59,12 @@ class StateMachineFireEventBase : public Core case eventIdPropertyKey: m_EventId = CoreUintType::deserialize(reader); return true; - case occursValuePropertyKey: - m_OccursValue = CoreUintType::deserialize(reader); - return true; } - return false; + return StateMachineFireAction::deserialize(propertyKey, reader); } protected: virtual void eventIdChanged() {} - virtual void occursValueChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/animation/state_machine_fire_trigger_base.hpp b/thirdparty/rive/include/rive/generated/animation/state_machine_fire_trigger_base.hpp new file mode 100644 index 000000000..311bee30c --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/state_machine_fire_trigger_base.hpp @@ -0,0 +1,62 @@ +#ifndef _RIVE_STATE_MACHINE_FIRE_TRIGGER_BASE_HPP_ +#define _RIVE_STATE_MACHINE_FIRE_TRIGGER_BASE_HPP_ +#include "rive/animation/state_machine_fire_action.hpp" +#include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/span.hpp" +namespace rive +{ +class StateMachineFireTriggerBase : public StateMachineFireAction +{ +protected: + typedef StateMachineFireAction Super; + +public: + static const uint16_t typeKey = 614; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case StateMachineFireTriggerBase::typeKey: + case StateMachineFireActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t viewModelPathIdsPropertyKey = 871; + +public: + virtual void decodeViewModelPathIds(Span value) = 0; + virtual void copyViewModelPathIds( + const StateMachineFireTriggerBase& object) = 0; + + Core* clone() const override; + void copy(const StateMachineFireTriggerBase& object) + { + copyViewModelPathIds(object); + StateMachineFireAction::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case viewModelPathIdsPropertyKey: + decodeViewModelPathIds(CoreBytesType::deserialize(reader)); + return true; + } + return StateMachineFireAction::deserialize(propertyKey, reader); + } + +protected: + virtual void viewModelPathIdsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/state_machine_listener_base.hpp b/thirdparty/rive/include/rive/generated/animation/state_machine_listener_base.hpp index f65a966b9..7684abbe8 100644 --- a/thirdparty/rive/include/rive/generated/animation/state_machine_listener_base.hpp +++ b/thirdparty/rive/include/rive/generated/animation/state_machine_listener_base.hpp @@ -10,7 +10,7 @@ class StateMachineListenerBase : public StateMachineComponent typedef StateMachineComponent Super; public: - static const uint16_t typeKey = 114; + static const uint16_t typeKey = 654; /// Helper to quickly determine if a core object extends another without /// RTTI at runtime. @@ -29,13 +29,9 @@ class StateMachineListenerBase : public StateMachineComponent uint16_t coreType() const override { return typeKey; } static const uint16_t targetIdPropertyKey = 224; - static const uint16_t listenerTypeValuePropertyKey = 225; - static const uint16_t eventIdPropertyKey = 399; protected: uint32_t m_TargetId = -1; - uint32_t m_ListenerTypeValue = 0; - uint32_t m_EventId = -1; public: inline uint32_t targetId() const { return m_TargetId; } @@ -49,34 +45,10 @@ class StateMachineListenerBase : public StateMachineComponent targetIdChanged(); } - inline uint32_t listenerTypeValue() const { return m_ListenerTypeValue; } - void listenerTypeValue(uint32_t value) - { - if (m_ListenerTypeValue == value) - { - return; - } - m_ListenerTypeValue = value; - listenerTypeValueChanged(); - } - - inline uint32_t eventId() const { return m_EventId; } - void eventId(uint32_t value) - { - if (m_EventId == value) - { - return; - } - m_EventId = value; - eventIdChanged(); - } - Core* clone() const override; void copy(const StateMachineListenerBase& object) { m_TargetId = object.m_TargetId; - m_ListenerTypeValue = object.m_ListenerTypeValue; - m_EventId = object.m_EventId; StateMachineComponent::copy(object); } @@ -87,20 +59,12 @@ class StateMachineListenerBase : public StateMachineComponent case targetIdPropertyKey: m_TargetId = CoreUintType::deserialize(reader); return true; - case listenerTypeValuePropertyKey: - m_ListenerTypeValue = CoreUintType::deserialize(reader); - return true; - case eventIdPropertyKey: - m_EventId = CoreUintType::deserialize(reader); - return true; } return StateMachineComponent::deserialize(propertyKey, reader); } protected: virtual void targetIdChanged() {} - virtual void listenerTypeValueChanged() {} - virtual void eventIdChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/animation/state_machine_listener_single_base.hpp b/thirdparty/rive/include/rive/generated/animation/state_machine_listener_single_base.hpp new file mode 100644 index 000000000..6deeb93b3 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/state_machine_listener_single_base.hpp @@ -0,0 +1,102 @@ +#ifndef _RIVE_STATE_MACHINE_LISTENER_SINGLE_BASE_HPP_ +#define _RIVE_STATE_MACHINE_LISTENER_SINGLE_BASE_HPP_ +#include "rive/animation/state_machine_listener.hpp" +#include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/span.hpp" +namespace rive +{ +class StateMachineListenerSingleBase : public StateMachineListener +{ +protected: + typedef StateMachineListener Super; + +public: + static const uint16_t typeKey = 114; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case StateMachineListenerSingleBase::typeKey: + case StateMachineListenerBase::typeKey: + case StateMachineComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t listenerTypeValuePropertyKey = 225; + static const uint16_t eventIdPropertyKey = 399; + static const uint16_t viewModelPathIdsPropertyKey = 868; + +protected: + uint32_t m_ListenerTypeValue = 0; + uint32_t m_EventId = -1; + +public: + inline uint32_t listenerTypeValue() const { return m_ListenerTypeValue; } + void listenerTypeValue(uint32_t value) + { + if (m_ListenerTypeValue == value) + { + return; + } + m_ListenerTypeValue = value; + listenerTypeValueChanged(); + } + + inline uint32_t eventId() const { return m_EventId; } + void eventId(uint32_t value) + { + if (m_EventId == value) + { + return; + } + m_EventId = value; + eventIdChanged(); + } + + virtual void decodeViewModelPathIds(Span value) = 0; + virtual void copyViewModelPathIds( + const StateMachineListenerSingleBase& object) = 0; + + Core* clone() const override; + void copy(const StateMachineListenerSingleBase& object) + { + m_ListenerTypeValue = object.m_ListenerTypeValue; + m_EventId = object.m_EventId; + copyViewModelPathIds(object); + StateMachineListener::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case listenerTypeValuePropertyKey: + m_ListenerTypeValue = CoreUintType::deserialize(reader); + return true; + case eventIdPropertyKey: + m_EventId = CoreUintType::deserialize(reader); + return true; + case viewModelPathIdsPropertyKey: + decodeViewModelPathIds(CoreBytesType::deserialize(reader)); + return true; + } + return StateMachineListener::deserialize(propertyKey, reader); + } + +protected: + virtual void listenerTypeValueChanged() {} + virtual void eventIdChanged() {} + virtual void viewModelPathIdsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/transition_property_component_comparator_base.hpp b/thirdparty/rive/include/rive/generated/animation/transition_property_component_comparator_base.hpp new file mode 100644 index 000000000..0b699a925 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/transition_property_component_comparator_base.hpp @@ -0,0 +1,91 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_COMPONENT_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_PROPERTY_COMPONENT_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_property_comparator.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TransitionPropertyComponentComparatorBase + : public TransitionPropertyComparator +{ +protected: + typedef TransitionPropertyComparator Super; + +public: + static const uint16_t typeKey = 667; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionPropertyComponentComparatorBase::typeKey: + case TransitionPropertyComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t objectIdPropertyKey = 977; + static const uint16_t propertyKeyPropertyKey = 978; + +protected: + uint32_t m_ObjectId = 0; + uint32_t m_PropertyKey = 0; + +public: + inline uint32_t objectId() const { return m_ObjectId; } + void objectId(uint32_t value) + { + if (m_ObjectId == value) + { + return; + } + m_ObjectId = value; + objectIdChanged(); + } + + inline uint32_t propertyKey() const { return m_PropertyKey; } + void propertyKey(uint32_t value) + { + if (m_PropertyKey == value) + { + return; + } + m_PropertyKey = value; + propertyKeyChanged(); + } + + Core* clone() const override; + void copy(const TransitionPropertyComponentComparatorBase& object) + { + m_ObjectId = object.m_ObjectId; + m_PropertyKey = object.m_PropertyKey; + TransitionPropertyComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case objectIdPropertyKey: + m_ObjectId = CoreUintType::deserialize(reader); + return true; + case propertyKeyPropertyKey: + m_PropertyKey = CoreUintType::deserialize(reader); + return true; + } + return TransitionPropertyComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void objectIdChanged() {} + virtual void propertyKeyChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/transition_self_comparator_base.hpp b/thirdparty/rive/include/rive/generated/animation/transition_self_comparator_base.hpp new file mode 100644 index 000000000..32c5f814a --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/transition_self_comparator_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_TRANSITION_SELF_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_SELF_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_comparator.hpp" +namespace rive +{ +class TransitionSelfComparatorBase : public TransitionComparator +{ +protected: + typedef TransitionComparator Super; + +public: + static const uint16_t typeKey = 593; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionSelfComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/transition_value_artboard_comparator_base.hpp b/thirdparty/rive/include/rive/generated/animation/transition_value_artboard_comparator_base.hpp new file mode 100644 index 000000000..cc9f8d9ff --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/transition_value_artboard_comparator_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_TRANSITION_VALUE_ARTBOARD_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_ARTBOARD_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_id_comparator.hpp" +namespace rive +{ +class TransitionValueArtboardComparatorBase : public TransitionValueIdComparator +{ +protected: + typedef TransitionValueIdComparator Super; + +public: + static const uint16_t typeKey = 630; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueArtboardComparatorBase::typeKey: + case TransitionValueIdComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/transition_value_asset_comparator_base.hpp b/thirdparty/rive/include/rive/generated/animation/transition_value_asset_comparator_base.hpp new file mode 100644 index 000000000..d84dd0a57 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/transition_value_asset_comparator_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_TRANSITION_VALUE_ASSET_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_ASSET_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_id_comparator.hpp" +namespace rive +{ +class TransitionValueAssetComparatorBase : public TransitionValueIdComparator +{ +protected: + typedef TransitionValueIdComparator Super; + +public: + static const uint16_t typeKey = 602; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueAssetComparatorBase::typeKey: + case TransitionValueIdComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/animation/transition_value_enum_comparator_base.hpp b/thirdparty/rive/include/rive/generated/animation/transition_value_enum_comparator_base.hpp index f2bbec604..737071b2c 100644 --- a/thirdparty/rive/include/rive/generated/animation/transition_value_enum_comparator_base.hpp +++ b/thirdparty/rive/include/rive/generated/animation/transition_value_enum_comparator_base.hpp @@ -1,13 +1,12 @@ #ifndef _RIVE_TRANSITION_VALUE_ENUM_COMPARATOR_BASE_HPP_ #define _RIVE_TRANSITION_VALUE_ENUM_COMPARATOR_BASE_HPP_ -#include "rive/animation/transition_value_comparator.hpp" -#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/animation/transition_value_id_comparator.hpp" namespace rive { -class TransitionValueEnumComparatorBase : public TransitionValueComparator +class TransitionValueEnumComparatorBase : public TransitionValueIdComparator { protected: - typedef TransitionValueComparator Super; + typedef TransitionValueIdComparator Super; public: static const uint16_t typeKey = 485; @@ -19,6 +18,7 @@ class TransitionValueEnumComparatorBase : public TransitionValueComparator switch (typeKey) { case TransitionValueEnumComparatorBase::typeKey: + case TransitionValueIdComparatorBase::typeKey: case TransitionValueComparatorBase::typeKey: case TransitionComparatorBase::typeKey: return true; @@ -29,43 +29,9 @@ class TransitionValueEnumComparatorBase : public TransitionValueComparator uint16_t coreType() const override { return typeKey; } - static const uint16_t valuePropertyKey = 653; - -protected: - uint32_t m_Value = -1; - -public: - inline uint32_t value() const { return m_Value; } - void value(uint32_t value) - { - if (m_Value == value) - { - return; - } - m_Value = value; - valueChanged(); - } - Core* clone() const override; - void copy(const TransitionValueEnumComparatorBase& object) - { - m_Value = object.m_Value; - TransitionValueComparator::copy(object); - } - - bool deserialize(uint16_t propertyKey, BinaryReader& reader) override - { - switch (propertyKey) - { - case valuePropertyKey: - m_Value = CoreUintType::deserialize(reader); - return true; - } - return TransitionValueComparator::deserialize(propertyKey, reader); - } protected: - virtual void valueChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/animation/transition_value_id_comparator_base.hpp b/thirdparty/rive/include/rive/generated/animation/transition_value_id_comparator_base.hpp new file mode 100644 index 000000000..696bf4bc4 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/animation/transition_value_id_comparator_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TRANSITION_VALUE_ID_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_ID_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_comparator.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TransitionValueIdComparatorBase : public TransitionValueComparator +{ +protected: + typedef TransitionValueComparator Super; + +public: + static const uint16_t typeKey = 601; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueIdComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 653; + +protected: + uint32_t m_Value = -1; + +public: + inline uint32_t value() const { return m_Value; } + void value(uint32_t value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const TransitionValueIdComparatorBase& object) + { + m_Value = object.m_Value; + TransitionValueComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreUintType::deserialize(reader); + return true; + } + return TransitionValueComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/artboard_base.hpp b/thirdparty/rive/include/rive/generated/artboard_base.hpp index 70cbaee0f..341853c6d 100644 --- a/thirdparty/rive/include/rive/generated/artboard_base.hpp +++ b/thirdparty/rive/include/rive/generated/artboard_base.hpp @@ -1,5 +1,6 @@ #ifndef _RIVE_ARTBOARD_BASE_HPP_ #define _RIVE_ARTBOARD_BASE_HPP_ +#include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" #include "rive/layout_component.hpp" @@ -39,12 +40,14 @@ class ArtboardBase : public LayoutComponent static const uint16_t originYPropertyKey = 12; static const uint16_t defaultStateMachineIdPropertyKey = 236; static const uint16_t viewModelIdPropertyKey = 583; + static const uint16_t isStatefulPropertyKey = 951; protected: float m_OriginX = 0.0f; float m_OriginY = 0.0f; uint32_t m_DefaultStateMachineId = -1; uint32_t m_ViewModelId = -1; + bool m_IsStateful = false; public: inline float originX() const { return m_OriginX; } @@ -94,6 +97,17 @@ class ArtboardBase : public LayoutComponent viewModelIdChanged(); } + inline bool isStateful() const { return m_IsStateful; } + void isStateful(bool value) + { + if (m_IsStateful == value) + { + return; + } + m_IsStateful = value; + isStatefulChanged(); + } + Core* clone() const override; void copy(const ArtboardBase& object) { @@ -101,6 +115,7 @@ class ArtboardBase : public LayoutComponent m_OriginY = object.m_OriginY; m_DefaultStateMachineId = object.m_DefaultStateMachineId; m_ViewModelId = object.m_ViewModelId; + m_IsStateful = object.m_IsStateful; LayoutComponent::copy(object); } @@ -120,6 +135,9 @@ class ArtboardBase : public LayoutComponent case viewModelIdPropertyKey: m_ViewModelId = CoreUintType::deserialize(reader); return true; + case isStatefulPropertyKey: + m_IsStateful = CoreBoolType::deserialize(reader); + return true; } return LayoutComponent::deserialize(propertyKey, reader); } @@ -129,6 +147,7 @@ class ArtboardBase : public LayoutComponent virtual void originYChanged() {} virtual void defaultStateMachineIdChanged() {} virtual void viewModelIdChanged() {} + virtual void isStatefulChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/artboard_list_map_rule_base.hpp b/thirdparty/rive/include/rive/generated/artboard_list_map_rule_base.hpp new file mode 100644 index 000000000..916f0ddd2 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/artboard_list_map_rule_base.hpp @@ -0,0 +1,89 @@ +#ifndef _RIVE_ARTBOARD_LIST_MAP_RULE_BASE_HPP_ +#define _RIVE_ARTBOARD_LIST_MAP_RULE_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ArtboardListMapRuleBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 648; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ArtboardListMapRuleBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t artboardIdPropertyKey = 934; + static const uint16_t viewModelIdPropertyKey = 935; + +protected: + uint32_t m_ArtboardId = -1; + uint32_t m_ViewModelId = -1; + +public: + inline uint32_t artboardId() const { return m_ArtboardId; } + void artboardId(uint32_t value) + { + if (m_ArtboardId == value) + { + return; + } + m_ArtboardId = value; + artboardIdChanged(); + } + + inline uint32_t viewModelId() const { return m_ViewModelId; } + void viewModelId(uint32_t value) + { + if (m_ViewModelId == value) + { + return; + } + m_ViewModelId = value; + viewModelIdChanged(); + } + + Core* clone() const override; + void copy(const ArtboardListMapRuleBase& object) + { + m_ArtboardId = object.m_ArtboardId; + m_ViewModelId = object.m_ViewModelId; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case artboardIdPropertyKey: + m_ArtboardId = CoreUintType::deserialize(reader); + return true; + case viewModelIdPropertyKey: + m_ViewModelId = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void artboardIdChanged() {} + virtual void viewModelIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/assets/blob_asset_base.hpp b/thirdparty/rive/include/rive/generated/assets/blob_asset_base.hpp new file mode 100644 index 000000000..768fce7df --- /dev/null +++ b/thirdparty/rive/include/rive/generated/assets/blob_asset_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_BLOB_ASSET_BASE_HPP_ +#define _RIVE_BLOB_ASSET_BASE_HPP_ +#include "rive/assets/file_asset.hpp" +namespace rive +{ +class BlobAssetBase : public FileAsset +{ +protected: + typedef FileAsset Super; + +public: + static const uint16_t typeKey = 649; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BlobAssetBase::typeKey: + case FileAssetBase::typeKey: + case AssetBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/assets/file_asset_contents_base.hpp b/thirdparty/rive/include/rive/generated/assets/file_asset_contents_base.hpp index aff6735fc..0c5402c7a 100644 --- a/thirdparty/rive/include/rive/generated/assets/file_asset_contents_base.hpp +++ b/thirdparty/rive/include/rive/generated/assets/file_asset_contents_base.hpp @@ -29,13 +29,21 @@ class FileAssetContentsBase : public Core uint16_t coreType() const override { return typeKey; } static const uint16_t bytesPropertyKey = 212; + static const uint16_t signaturePropertyKey = 911; public: virtual void decodeBytes(Span value) = 0; virtual void copyBytes(const FileAssetContentsBase& object) = 0; + virtual void decodeSignature(Span value) = 0; + virtual void copySignature(const FileAssetContentsBase& object) = 0; + Core* clone() const override; - void copy(const FileAssetContentsBase& object) { copyBytes(object); } + void copy(const FileAssetContentsBase& object) + { + copyBytes(object); + copySignature(object); + } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { @@ -44,12 +52,16 @@ class FileAssetContentsBase : public Core case bytesPropertyKey: decodeBytes(CoreBytesType::deserialize(reader)); return true; + case signaturePropertyKey: + decodeSignature(CoreBytesType::deserialize(reader)); + return true; } return false; } protected: virtual void bytesChanged() {} + virtual void signatureChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/assets/manifest_asset_base.hpp b/thirdparty/rive/include/rive/generated/assets/manifest_asset_base.hpp new file mode 100644 index 000000000..de7a7f908 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/assets/manifest_asset_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_MANIFEST_ASSET_BASE_HPP_ +#define _RIVE_MANIFEST_ASSET_BASE_HPP_ +#include "rive/assets/file_asset.hpp" +namespace rive +{ +class ManifestAssetBase : public FileAsset +{ +protected: + typedef FileAsset Super; + +public: + static const uint16_t typeKey = 642; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ManifestAssetBase::typeKey: + case FileAssetBase::typeKey: + case AssetBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/assets/script_asset_base.hpp b/thirdparty/rive/include/rive/generated/assets/script_asset_base.hpp new file mode 100644 index 000000000..31be61fa3 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/assets/script_asset_base.hpp @@ -0,0 +1,95 @@ +#ifndef _RIVE_SCRIPT_ASSET_BASE_HPP_ +#define _RIVE_SCRIPT_ASSET_BASE_HPP_ +#include "rive/assets/text_asset.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ScriptAssetBase : public TextAsset +{ +protected: + typedef TextAsset Super; + +public: + static const uint16_t typeKey = 529; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptAssetBase::typeKey: + case TextAssetBase::typeKey: + case FileAssetBase::typeKey: + case AssetBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t generatorFunctionRefPropertyKey = 893; + static const uint16_t isModulePropertyKey = 914; + +protected: + uint32_t m_GeneratorFunctionRef = 0; + bool m_IsModule = false; + +public: + inline uint32_t generatorFunctionRef() const + { + return m_GeneratorFunctionRef; + } + void generatorFunctionRef(uint32_t value) + { + if (m_GeneratorFunctionRef == value) + { + return; + } + m_GeneratorFunctionRef = value; + generatorFunctionRefChanged(); + } + + inline bool isModule() const { return m_IsModule; } + void isModule(bool value) + { + if (m_IsModule == value) + { + return; + } + m_IsModule = value; + isModuleChanged(); + } + + Core* clone() const override; + void copy(const ScriptAssetBase& object) + { + m_GeneratorFunctionRef = object.m_GeneratorFunctionRef; + m_IsModule = object.m_IsModule; + TextAsset::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case generatorFunctionRefPropertyKey: + m_GeneratorFunctionRef = CoreUintType::deserialize(reader); + return true; + case isModulePropertyKey: + m_IsModule = CoreBoolType::deserialize(reader); + return true; + } + return TextAsset::deserialize(propertyKey, reader); + } + +protected: + virtual void generatorFunctionRefChanged() {} + virtual void isModuleChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/assets/shader_asset_base.hpp b/thirdparty/rive/include/rive/generated/assets/shader_asset_base.hpp new file mode 100644 index 000000000..cefd1a57e --- /dev/null +++ b/thirdparty/rive/include/rive/generated/assets/shader_asset_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_SHADER_ASSET_BASE_HPP_ +#define _RIVE_SHADER_ASSET_BASE_HPP_ +#include "rive/assets/text_asset.hpp" +namespace rive +{ +class ShaderAssetBase : public TextAsset +{ +protected: + typedef TextAsset Super; + +public: + static const uint16_t typeKey = 970; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ShaderAssetBase::typeKey: + case TextAssetBase::typeKey: + case FileAssetBase::typeKey: + case AssetBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/assets/text_asset_base.hpp b/thirdparty/rive/include/rive/generated/assets/text_asset_base.hpp new file mode 100644 index 000000000..9d2b18634 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/assets/text_asset_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TEXT_ASSET_BASE_HPP_ +#define _RIVE_TEXT_ASSET_BASE_HPP_ +#include +#include "rive/assets/file_asset.hpp" +#include "rive/core/field_types/core_string_type.hpp" +namespace rive +{ +class TextAssetBase : public FileAsset +{ +protected: + typedef FileAsset Super; + +public: + static const uint16_t typeKey = 971; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TextAssetBase::typeKey: + case FileAssetBase::typeKey: + case AssetBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t folderPathPropertyKey = 926; + +protected: + std::string m_FolderPath = ""; + +public: + inline const std::string& folderPath() const { return m_FolderPath; } + void folderPath(std::string value) + { + if (m_FolderPath == value) + { + return; + } + m_FolderPath = value; + folderPathChanged(); + } + + void copy(const TextAssetBase& object) + { + m_FolderPath = object.m_FolderPath; + FileAsset::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case folderPathPropertyKey: + m_FolderPath = CoreStringType::deserialize(reader); + return true; + } + return FileAsset::deserialize(propertyKey, reader); + } + +protected: + virtual void folderPathChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/constraints/list_follow_path_constraint_base.hpp b/thirdparty/rive/include/rive/generated/constraints/list_follow_path_constraint_base.hpp new file mode 100644 index 000000000..3e812ff5d --- /dev/null +++ b/thirdparty/rive/include/rive/generated/constraints/list_follow_path_constraint_base.hpp @@ -0,0 +1,93 @@ +#ifndef _RIVE_LIST_FOLLOW_PATH_CONSTRAINT_BASE_HPP_ +#define _RIVE_LIST_FOLLOW_PATH_CONSTRAINT_BASE_HPP_ +#include "rive/constraints/follow_path_constraint.hpp" +#include "rive/core/field_types/core_double_type.hpp" +namespace rive +{ +class ListFollowPathConstraintBase : public FollowPathConstraint +{ +protected: + typedef FollowPathConstraint Super; + +public: + static const uint16_t typeKey = 625; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListFollowPathConstraintBase::typeKey: + case FollowPathConstraintBase::typeKey: + case TransformSpaceConstraintBase::typeKey: + case TargetedConstraintBase::typeKey: + case ConstraintBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t distanceEndPropertyKey = 888; + static const uint16_t distanceOffsetPropertyKey = 889; + +protected: + float m_DistanceEnd = 1.0f; + float m_DistanceOffset = 0.0f; + +public: + inline float distanceEnd() const { return m_DistanceEnd; } + void distanceEnd(float value) + { + if (m_DistanceEnd == value) + { + return; + } + m_DistanceEnd = value; + distanceEndChanged(); + } + + inline float distanceOffset() const { return m_DistanceOffset; } + void distanceOffset(float value) + { + if (m_DistanceOffset == value) + { + return; + } + m_DistanceOffset = value; + distanceOffsetChanged(); + } + + Core* clone() const override; + void copy(const ListFollowPathConstraintBase& object) + { + m_DistanceEnd = object.m_DistanceEnd; + m_DistanceOffset = object.m_DistanceOffset; + FollowPathConstraint::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case distanceEndPropertyKey: + m_DistanceEnd = CoreDoubleType::deserialize(reader); + return true; + case distanceOffsetPropertyKey: + m_DistanceOffset = CoreDoubleType::deserialize(reader); + return true; + } + return FollowPathConstraint::deserialize(propertyKey, reader); + } + +protected: + virtual void distanceEndChanged() {} + virtual void distanceOffsetChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/constraints/scrolling/scroll_constraint_base.hpp b/thirdparty/rive/include/rive/generated/constraints/scrolling/scroll_constraint_base.hpp index fe590971c..14f6f66c3 100644 --- a/thirdparty/rive/include/rive/generated/constraints/scrolling/scroll_constraint_base.hpp +++ b/thirdparty/rive/include/rive/generated/constraints/scrolling/scroll_constraint_base.hpp @@ -40,6 +40,10 @@ class ScrollConstraintBase : public DraggableConstraint static const uint16_t snapPropertyKey = 724; static const uint16_t physicsTypeValuePropertyKey = 727; static const uint16_t physicsIdPropertyKey = 726; + static const uint16_t virtualizePropertyKey = 850; + static const uint16_t infinitePropertyKey = 851; + static const uint16_t interactivePropertyKey = 891; + static const uint16_t thresholdPropertyKey = 894; protected: float m_ScrollOffsetX = 0.0f; @@ -47,6 +51,10 @@ class ScrollConstraintBase : public DraggableConstraint bool m_Snap = false; uint32_t m_PhysicsTypeValue = 0; uint32_t m_PhysicsId = -1; + bool m_Virtualize = false; + bool m_Infinite = false; + bool m_Interactive = true; + float m_Threshold = 0.0f; public: inline float scrollOffsetX() const { return m_ScrollOffsetX; } @@ -140,6 +148,50 @@ class ScrollConstraintBase : public DraggableConstraint physicsIdChanged(); } + inline bool virtualize() const { return m_Virtualize; } + void virtualize(bool value) + { + if (m_Virtualize == value) + { + return; + } + m_Virtualize = value; + virtualizeChanged(); + } + + inline bool infinite() const { return m_Infinite; } + void infinite(bool value) + { + if (m_Infinite == value) + { + return; + } + m_Infinite = value; + infiniteChanged(); + } + + inline bool interactive() const { return m_Interactive; } + void interactive(bool value) + { + if (m_Interactive == value) + { + return; + } + m_Interactive = value; + interactiveChanged(); + } + + inline float threshold() const { return m_Threshold; } + void threshold(float value) + { + if (m_Threshold == value) + { + return; + } + m_Threshold = value; + thresholdChanged(); + } + Core* clone() const override; void copy(const ScrollConstraintBase& object) { @@ -148,6 +200,10 @@ class ScrollConstraintBase : public DraggableConstraint m_Snap = object.m_Snap; m_PhysicsTypeValue = object.m_PhysicsTypeValue; m_PhysicsId = object.m_PhysicsId; + m_Virtualize = object.m_Virtualize; + m_Infinite = object.m_Infinite; + m_Interactive = object.m_Interactive; + m_Threshold = object.m_Threshold; DraggableConstraint::copy(object); } @@ -170,6 +226,18 @@ class ScrollConstraintBase : public DraggableConstraint case physicsIdPropertyKey: m_PhysicsId = CoreUintType::deserialize(reader); return true; + case virtualizePropertyKey: + m_Virtualize = CoreBoolType::deserialize(reader); + return true; + case infinitePropertyKey: + m_Infinite = CoreBoolType::deserialize(reader); + return true; + case interactivePropertyKey: + m_Interactive = CoreBoolType::deserialize(reader); + return true; + case thresholdPropertyKey: + m_Threshold = CoreDoubleType::deserialize(reader); + return true; } return DraggableConstraint::deserialize(propertyKey, reader); } @@ -183,6 +251,10 @@ class ScrollConstraintBase : public DraggableConstraint virtual void snapChanged() {} virtual void physicsTypeValueChanged() {} virtual void physicsIdChanged() {} + virtual void virtualizeChanged() {} + virtual void infiniteChanged() {} + virtual void interactiveChanged() {} + virtual void thresholdChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/core_registry.hpp b/thirdparty/rive/include/rive/generated/core_registry.hpp index 429b078fe..a621672b1 100644 --- a/thirdparty/rive/include/rive/generated/core_registry.hpp +++ b/thirdparty/rive/include/rive/generated/core_registry.hpp @@ -20,6 +20,9 @@ #include "rive/animation/elastic_interpolator.hpp" #include "rive/animation/entry_state.hpp" #include "rive/animation/exit_state.hpp" +#include "rive/animation/focus_action.hpp" +#include "rive/animation/focus_action_target.hpp" +#include "rive/animation/focus_action_traversal.hpp" #include "rive/animation/interpolating_keyframe.hpp" #include "rive/animation/keyed_object.hpp" #include "rive/animation/keyed_property.hpp" @@ -41,6 +44,12 @@ #include "rive/animation/listener_input_change.hpp" #include "rive/animation/listener_number_change.hpp" #include "rive/animation/listener_trigger_change.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" +#include "rive/animation/listener_types/listener_input_type_event.hpp" +#include "rive/animation/listener_types/listener_input_type_keyboard.hpp" +#include "rive/animation/listener_types/listener_input_type_semantic.hpp" +#include "rive/animation/listener_types/listener_input_type_text.hpp" +#include "rive/animation/listener_types/listener_input_type_viewmodel.hpp" #include "rive/animation/listener_viewmodel_change.hpp" #include "rive/animation/nested_bool.hpp" #include "rive/animation/nested_input.hpp" @@ -50,14 +59,19 @@ #include "rive/animation/nested_simple_animation.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/animation/nested_trigger.hpp" +#include "rive/animation/scripted_listener_action.hpp" +#include "rive/animation/scripted_transition_condition.hpp" #include "rive/animation/state_machine.hpp" #include "rive/animation/state_machine_bool.hpp" #include "rive/animation/state_machine_component.hpp" +#include "rive/animation/state_machine_fire_action.hpp" #include "rive/animation/state_machine_fire_event.hpp" +#include "rive/animation/state_machine_fire_trigger.hpp" #include "rive/animation/state_machine_input.hpp" #include "rive/animation/state_machine_layer.hpp" #include "rive/animation/state_machine_layer_component.hpp" #include "rive/animation/state_machine_listener.hpp" +#include "rive/animation/state_machine_listener_single.hpp" #include "rive/animation/state_machine_number.hpp" #include "rive/animation/state_machine_trigger.hpp" #include "rive/animation/state_transition.hpp" @@ -69,21 +83,28 @@ #include "rive/animation/transition_number_condition.hpp" #include "rive/animation/transition_property_artboard_comparator.hpp" #include "rive/animation/transition_property_comparator.hpp" +#include "rive/animation/transition_property_component_comparator.hpp" #include "rive/animation/transition_property_viewmodel_comparator.hpp" +#include "rive/animation/transition_self_comparator.hpp" #include "rive/animation/transition_trigger_condition.hpp" +#include "rive/animation/transition_value_artboard_comparator.hpp" +#include "rive/animation/transition_value_asset_comparator.hpp" #include "rive/animation/transition_value_boolean_comparator.hpp" #include "rive/animation/transition_value_color_comparator.hpp" #include "rive/animation/transition_value_comparator.hpp" #include "rive/animation/transition_value_condition.hpp" #include "rive/animation/transition_value_enum_comparator.hpp" +#include "rive/animation/transition_value_id_comparator.hpp" #include "rive/animation/transition_value_number_comparator.hpp" #include "rive/animation/transition_value_string_comparator.hpp" #include "rive/animation/transition_value_trigger_comparator.hpp" #include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/artboard.hpp" #include "rive/artboard_component_list.hpp" +#include "rive/artboard_list_map_rule.hpp" #include "rive/assets/asset.hpp" #include "rive/assets/audio_asset.hpp" +#include "rive/assets/blob_asset.hpp" #include "rive/assets/drawable_asset.hpp" #include "rive/assets/export_audio.hpp" #include "rive/assets/file_asset.hpp" @@ -91,6 +112,10 @@ #include "rive/assets/folder.hpp" #include "rive/assets/font_asset.hpp" #include "rive/assets/image_asset.hpp" +#include "rive/assets/manifest_asset.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/assets/shader_asset.hpp" +#include "rive/assets/text_asset.hpp" #include "rive/audio_event.hpp" #include "rive/backboard.hpp" #include "rive/bones/bone.hpp" @@ -106,6 +131,7 @@ #include "rive/constraints/draggable_constraint.hpp" #include "rive/constraints/follow_path_constraint.hpp" #include "rive/constraints/ik_constraint.hpp" +#include "rive/constraints/list_follow_path_constraint.hpp" #include "rive/constraints/rotation_constraint.hpp" #include "rive/constraints/scale_constraint.hpp" #include "rive/constraints/scrolling/clamped_scroll_physics.hpp" @@ -122,24 +148,32 @@ #include "rive/container_component.hpp" #include "rive/custom_property.hpp" #include "rive/custom_property_boolean.hpp" +#include "rive/custom_property_color.hpp" +#include "rive/custom_property_enum.hpp" #include "rive/custom_property_group.hpp" #include "rive/custom_property_number.hpp" #include "rive/custom_property_string.hpp" +#include "rive/custom_property_trigger.hpp" #include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_artboard.hpp" #include "rive/data_bind/bindable_property_asset.hpp" #include "rive/data_bind/bindable_property_boolean.hpp" #include "rive/data_bind/bindable_property_color.hpp" #include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_id.hpp" #include "rive/data_bind/bindable_property_integer.hpp" +#include "rive/data_bind/bindable_property_list.hpp" #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/bindable_property_trigger.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" #include "rive/data_bind/converters/data_converter.hpp" #include "rive/data_bind/converters/data_converter_boolean_negate.hpp" #include "rive/data_bind/converters/data_converter_formula.hpp" #include "rive/data_bind/converters/data_converter_group.hpp" #include "rive/data_bind/converters/data_converter_group_item.hpp" #include "rive/data_bind/converters/data_converter_interpolator.hpp" +#include "rive/data_bind/converters/data_converter_list_to_length.hpp" #include "rive/data_bind/converters/data_converter_number_to_list.hpp" #include "rive/data_bind/converters/data_converter_operation.hpp" #include "rive/data_bind/converters/data_converter_operation_value.hpp" @@ -151,6 +185,7 @@ #include "rive/data_bind/converters/data_converter_string_trim.hpp" #include "rive/data_bind/converters/data_converter_system_degs_to_rads.hpp" #include "rive/data_bind/converters/data_converter_system_normalizer.hpp" +#include "rive/data_bind/converters/data_converter_to_number.hpp" #include "rive/data_bind/converters/data_converter_to_string.hpp" #include "rive/data_bind/converters/data_converter_trigger.hpp" #include "rive/data_bind/converters/formula/formula_token.hpp" @@ -164,12 +199,18 @@ #include "rive/data_bind/converters/formula/formula_token_value.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind_path.hpp" #include "rive/draw_rules.hpp" #include "rive/draw_target.hpp" #include "rive/drawable.hpp" #include "rive/event.hpp" +#include "rive/focus_data.hpp" #include "rive/foreground_layout_drawable.hpp" +#include "rive/inputs/keyboard_input.hpp" +#include "rive/inputs/semantic_input.hpp" +#include "rive/inputs/user_input.hpp" #include "rive/joystick.hpp" +#include "rive/layout/artboard_component_list_override.hpp" #include "rive/layout/axis.hpp" #include "rive/layout/axis_x.hpp" #include "rive/layout/axis_y.hpp" @@ -184,6 +225,18 @@ #include "rive/nested_artboard_leaf.hpp" #include "rive/node.hpp" #include "rive/open_url_event.hpp" +#include "rive/script_input_artboard.hpp" +#include "rive/script_input_boolean.hpp" +#include "rive/script_input_color.hpp" +#include "rive/script_input_number.hpp" +#include "rive/script_input_string.hpp" +#include "rive/script_input_trigger.hpp" +#include "rive/script_input_viewmodel_property.hpp" +#include "rive/scripted/scripted_data_converter.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/scripted/scripted_layout.hpp" +#include "rive/scripted/scripted_path_effect.hpp" +#include "rive/semantic/semantic_data.hpp" #include "rive/shapes/clipping_shape.hpp" #include "rive/shapes/contour_mesh_vertex.hpp" #include "rive/shapes/cubic_asymmetric_vertex.hpp" @@ -192,6 +245,7 @@ #include "rive/shapes/cubic_vertex.hpp" #include "rive/shapes/ellipse.hpp" #include "rive/shapes/image.hpp" +#include "rive/shapes/list_path.hpp" #include "rive/shapes/mesh.hpp" #include "rive/shapes/mesh_vertex.hpp" #include "rive/shapes/paint/dash.hpp" @@ -199,15 +253,18 @@ #include "rive/shapes/paint/feather.hpp" #include "rive/shapes/paint/fill.hpp" #include "rive/shapes/paint/gradient_stop.hpp" +#include "rive/shapes/paint/group_effect.hpp" #include "rive/shapes/paint/linear_gradient.hpp" #include "rive/shapes/paint/radial_gradient.hpp" #include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/paint/solid_color.hpp" #include "rive/shapes/paint/stroke.hpp" +#include "rive/shapes/paint/target_effect.hpp" #include "rive/shapes/paint/trim_path.hpp" #include "rive/shapes/parametric_path.hpp" #include "rive/shapes/path.hpp" #include "rive/shapes/path_vertex.hpp" +#include "rive/shapes/points_common_path.hpp" #include "rive/shapes/points_path.hpp" #include "rive/shapes/polygon.hpp" #include "rive/shapes/rectangle.hpp" @@ -244,6 +301,7 @@ #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_component.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" #include "rive/viewmodel/viewmodel_instance_asset.hpp" #include "rive/viewmodel/viewmodel_instance_asset_image.hpp" #include "rive/viewmodel/viewmodel_instance_boolean.hpp" @@ -259,6 +317,7 @@ #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" #include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/viewmodel/viewmodel_property_artboard.hpp" #include "rive/viewmodel/viewmodel_property_asset.hpp" #include "rive/viewmodel/viewmodel_property_asset_image.hpp" #include "rive/viewmodel/viewmodel_property_boolean.hpp" @@ -285,12 +344,16 @@ class CoreRegistry { case ViewModelInstanceListItemBase::typeKey: return new ViewModelInstanceListItem(); - case ViewModelInstanceColorBase::typeKey: - return new ViewModelInstanceColor(); case ViewModelComponentBase::typeKey: return new ViewModelComponent(); case ViewModelPropertyBase::typeKey: return new ViewModelProperty(); + case ViewModelPropertyArtboardBase::typeKey: + return new ViewModelPropertyArtboard(); + case ViewModelInstanceValueBase::typeKey: + return new ViewModelInstanceValue(); + case ViewModelInstanceColorBase::typeKey: + return new ViewModelInstanceColor(); case ViewModelPropertyEnumBase::typeKey: return new ViewModelPropertyEnum(); case ViewModelPropertyEnumCustomBase::typeKey: @@ -305,6 +368,8 @@ class CoreRegistry return new ViewModelInstanceEnum(); case ViewModelPropertySymbolListIndexBase::typeKey: return new ViewModelPropertySymbolListIndex(); + case ViewModelInstanceArtboardBase::typeKey: + return new ViewModelInstanceArtboard(); case ViewModelInstanceStringBase::typeKey: return new ViewModelInstanceString(); case ViewModelPropertyListBase::typeKey: @@ -349,16 +414,24 @@ class CoreRegistry return new ViewModelInstanceAsset(); case ViewModelInstanceAssetImageBase::typeKey: return new ViewModelInstanceAssetImage(); + case CustomPropertyTriggerBase::typeKey: + return new CustomPropertyTrigger(); + case ScriptInputTriggerBase::typeKey: + return new ScriptInputTrigger(); case DrawTargetBase::typeKey: return new DrawTarget(); case CustomPropertyNumberBase::typeKey: return new CustomPropertyNumber(); + case ScriptInputViewModelPropertyBase::typeKey: + return new ScriptInputViewModelProperty(); case DistanceConstraintBase::typeKey: return new DistanceConstraint(); - case IKConstraintBase::typeKey: - return new IKConstraint(); case FollowPathConstraintBase::typeKey: return new FollowPathConstraint(); + case ListFollowPathConstraintBase::typeKey: + return new ListFollowPathConstraint(); + case IKConstraintBase::typeKey: + return new IKConstraint(); case TranslationConstraintBase::typeKey: return new TranslationConstraint(); case ClampedScrollPhysicsBase::typeKey: @@ -383,8 +456,20 @@ class CoreRegistry return new NestedArtboard(); case ArtboardComponentListBase::typeKey: return new ArtboardComponentList(); + case CustomPropertyColorBase::typeKey: + return new CustomPropertyColor(); case SoloBase::typeKey: return new Solo(); + case ScriptedDrawableBase::typeKey: + return new ScriptedDrawable(); + case ScriptedDataConverterBase::typeKey: + return new ScriptedDataConverter(); + case ScriptedLayoutBase::typeKey: + return new ScriptedLayout(); + case ScriptedPathEffectBase::typeKey: + return new ScriptedPathEffect(); + case ScriptInputNumberBase::typeKey: + return new ScriptInputNumber(); case NestedArtboardLayoutBase::typeKey: return new NestedArtboardLayout(); case NSlicerTileModeBase::typeKey: @@ -399,8 +484,14 @@ class CoreRegistry return new NSlicer(); case NSlicedNodeBase::typeKey: return new NSlicedNode(); + case ArtboardComponentListOverrideBase::typeKey: + return new ArtboardComponentListOverride(); case ListenerFireEventBase::typeKey: return new ListenerFireEvent(); + case TransitionSelfComparatorBase::typeKey: + return new TransitionSelfComparator(); + case StateMachineFireTriggerBase::typeKey: + return new StateMachineFireTrigger(); case TransitionValueTriggerComparatorBase::typeKey: return new TransitionValueTriggerComparator(); case KeyFrameUintBase::typeKey: @@ -411,6 +502,8 @@ class CoreRegistry return new AnimationState(); case NestedTriggerBase::typeKey: return new NestedTrigger(); + case ScriptedListenerActionBase::typeKey: + return new ScriptedListenerAction(); case KeyedObjectBase::typeKey: return new KeyedObject(); case AnimationBase::typeKey: @@ -419,14 +512,16 @@ class CoreRegistry return new BlendAnimationDirect(); case StateMachineNumberBase::typeKey: return new StateMachineNumber(); + case StateMachineListenerBase::typeKey: + return new StateMachineListener(); + case StateMachineListenerSingleBase::typeKey: + return new StateMachineListenerSingle(); case CubicValueInterpolatorBase::typeKey: return new CubicValueInterpolator(); case TransitionTriggerConditionBase::typeKey: return new TransitionTriggerCondition(); case KeyedPropertyBase::typeKey: return new KeyedProperty(); - case StateMachineListenerBase::typeKey: - return new StateMachineListener(); case TransitionPropertyArtboardComparatorBase::typeKey: return new TransitionPropertyArtboardComparator(); case TransitionPropertyViewModelComparatorBase::typeKey: @@ -439,6 +534,8 @@ class CoreRegistry return new ListenerBoolChange(); case ListenerAlignTargetBase::typeKey: return new ListenerAlignTarget(); + case ScriptedTransitionConditionBase::typeKey: + return new ScriptedTransitionCondition(); case TransitionNumberConditionBase::typeKey: return new TransitionNumberCondition(); case TransitionValueBooleanComparatorBase::typeKey: @@ -459,8 +556,12 @@ class CoreRegistry return new KeyFrameString(); case ListenerNumberChangeBase::typeKey: return new ListenerNumberChange(); + case FocusActionTargetBase::typeKey: + return new FocusActionTarget(); case CubicEaseInterpolatorBase::typeKey: return new CubicEaseInterpolator(); + case TransitionValueIdComparatorBase::typeKey: + return new TransitionValueIdComparator(); case StateTransitionBase::typeKey: return new StateTransition(); case NestedBoolBase::typeKey: @@ -469,6 +570,8 @@ class CoreRegistry return new KeyFrameDouble(); case KeyFrameColorBase::typeKey: return new KeyFrameColor(); + case FocusActionTraversalBase::typeKey: + return new FocusActionTraversal(); case StateMachineBase::typeKey: return new StateMachine(); case StateMachineFireEventBase::typeKey: @@ -489,10 +592,24 @@ class CoreRegistry return new ListenerViewModelChange(); case TransitionValueNumberComparatorBase::typeKey: return new TransitionValueNumberComparator(); + case TransitionPropertyComponentComparatorBase::typeKey: + return new TransitionPropertyComponentComparator(); case NestedStateMachineBase::typeKey: return new NestedStateMachine(); case ElasticInterpolatorBase::typeKey: return new ElasticInterpolator(); + case ListenerInputTypeBase::typeKey: + return new ListenerInputType(); + case ListenerInputTypeEventBase::typeKey: + return new ListenerInputTypeEvent(); + case ListenerInputTypeKeyboardBase::typeKey: + return new ListenerInputTypeKeyboard(); + case ListenerInputTypeTextBase::typeKey: + return new ListenerInputTypeText(); + case ListenerInputTypeSemanticBase::typeKey: + return new ListenerInputTypeSemantic(); + case ListenerInputTypeViewModelBase::typeKey: + return new ListenerInputTypeViewModel(); case ExitStateBase::typeKey: return new ExitState(); case NestedNumberBase::typeKey: @@ -501,10 +618,14 @@ class CoreRegistry return new TransitionValueEnumComparator(); case KeyFrameCallbackBase::typeKey: return new KeyFrameCallback(); + case TransitionValueArtboardComparatorBase::typeKey: + return new TransitionValueArtboardComparator(); case TransitionValueStringComparatorBase::typeKey: return new TransitionValueStringComparator(); case NestedRemapAnimationBase::typeKey: return new NestedRemapAnimation(); + case TransitionValueAssetComparatorBase::typeKey: + return new TransitionValueAssetComparator(); case TransitionBoolConditionBase::typeKey: return new TransitionBoolCondition(); case BlendState1DViewModelBase::typeKey: @@ -515,6 +636,10 @@ class CoreRegistry return new StateMachineBool(); case BlendAnimation1DBase::typeKey: return new BlendAnimation1D(); + case GroupEffectBase::typeKey: + return new GroupEffect(); + case TargetEffectBase::typeKey: + return new TargetEffect(); case DashPathBase::typeKey: return new DashPath(); case LinearGradientBase::typeKey: @@ -557,6 +682,8 @@ class CoreRegistry return new Triangle(); case EllipseBase::typeKey: return new Ellipse(); + case ListPathBase::typeKey: + return new ListPath(); case ClippingShapeBase::typeKey: return new ClippingShape(); case PolygonBase::typeKey: @@ -571,10 +698,16 @@ class CoreRegistry return new CustomPropertyGroup(); case EventBase::typeKey: return new Event(); - case DrawRulesBase::typeKey: - return new DrawRules(); + case FocusDataBase::typeKey: + return new FocusData(); case CustomPropertyBooleanBase::typeKey: return new CustomPropertyBoolean(); + case ScriptInputBooleanBase::typeKey: + return new ScriptInputBoolean(); + case ScriptInputColorBase::typeKey: + return new ScriptInputColor(); + case DrawRulesBase::typeKey: + return new DrawRules(); case LayoutComponentBase::typeKey: return new LayoutComponent(); case ArtboardBase::typeKey: @@ -585,6 +718,16 @@ class CoreRegistry return new Backboard(); case OpenUrlEventBase::typeKey: return new OpenUrlEvent(); + case SemanticDataBase::typeKey: + return new SemanticData(); + case CustomPropertyStringBase::typeKey: + return new CustomPropertyString(); + case ScriptInputStringBase::typeKey: + return new ScriptInputString(); + case BindablePropertyArtboardBase::typeKey: + return new BindablePropertyArtboard(); + case DataBindPathBase::typeKey: + return new DataBindPath(); case BindablePropertyIntegerBase::typeKey: return new BindablePropertyInteger(); case BindablePropertyTriggerBase::typeKey: @@ -599,6 +742,8 @@ class CoreRegistry return new DataConverterNumberToList(); case DataConverterFormulaBase::typeKey: return new DataConverterFormula(); + case DataConverterToNumberBase::typeKey: + return new DataConverterToNumber(); case DataConverterOperationBase::typeKey: return new DataConverterOperation(); case DataConverterOperationValueBase::typeKey: @@ -611,6 +756,8 @@ class CoreRegistry return new DataConverterInterpolator(); case DataConverterSystemNormalizerBase::typeKey: return new DataConverterSystemNormalizer(); + case DataConverterListToLengthBase::typeKey: + return new DataConverterListToLength(); case DataConverterGroupItemBase::typeKey: return new DataConverterGroupItem(); case DataConverterGroupBase::typeKey: @@ -651,6 +798,8 @@ class CoreRegistry return new DataConverterToString(); case DataBindContextBase::typeKey: return new DataBindContext(); + case BindablePropertyListBase::typeKey: + return new BindablePropertyList(); case BindablePropertyStringBase::typeKey: return new BindablePropertyString(); case BindablePropertyNumberBase::typeKey: @@ -659,6 +808,8 @@ class CoreRegistry return new BindablePropertyEnum(); case BindablePropertyColorBase::typeKey: return new BindablePropertyColor(); + case BindablePropertyViewModelBase::typeKey: + return new BindablePropertyViewModel(); case NestedArtboardLeafBase::typeKey: return new NestedArtboardLeaf(); case WeightBase::typeKey: @@ -703,12 +854,22 @@ class CoreRegistry return new Text(); case TextValueRunBase::typeKey: return new TextValueRun(); - case CustomPropertyStringBase::typeKey: - return new CustomPropertyString(); + case ArtboardListMapRuleBase::typeKey: + return new ArtboardListMapRule(); + case CustomPropertyEnumBase::typeKey: + return new CustomPropertyEnum(); + case BlobAssetBase::typeKey: + return new BlobAsset(); case FolderBase::typeKey: return new Folder(); + case ScriptAssetBase::typeKey: + return new ScriptAsset(); + case ManifestAssetBase::typeKey: + return new ManifestAsset(); case ImageAssetBase::typeKey: return new ImageAsset(); + case ShaderAssetBase::typeKey: + return new ShaderAsset(); case FontAssetBase::typeKey: return new FontAsset(); case AudioAssetBase::typeKey: @@ -717,6 +878,14 @@ class CoreRegistry return new FileAssetContents(); case AudioEventBase::typeKey: return new AudioEvent(); + case UserInputBase::typeKey: + return new UserInput(); + case KeyboardInputBase::typeKey: + return new KeyboardInput(); + case SemanticInputBase::typeKey: + return new SemanticInput(); + case ScriptInputArtboardBase::typeKey: + return new ScriptInputArtboard(); } return nullptr; } @@ -731,6 +900,15 @@ class CoreRegistry object->as() ->viewModelInstanceId(value); break; + case ViewModelPropertyBase::symbolTypeValuePropertyKey: + object->as()->symbolTypeValue(value); + break; + case ViewModelPropertyBase::componentPropsPropertyKey: + object->as()->componentProps(value); + break; + case ComponentBase::parentIdPropertyKey: + object->as()->parentId(value); + break; case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: object->as()->viewModelPropertyId( value); @@ -741,6 +919,10 @@ class CoreRegistry case ViewModelInstanceEnumBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; + case ViewModelInstanceArtboardBase::propertyValuePropertyKey: + object->as()->propertyValue( + value); + break; case ViewModelPropertyEnumSystemBase::enumTypePropertyKey: object->as()->enumType(value); break; @@ -752,12 +934,12 @@ class CoreRegistry object->as() ->viewModelReferenceId(value); break; - case ComponentBase::parentIdPropertyKey: - object->as()->parentId(value); - break; case ViewModelInstanceBase::viewModelIdPropertyKey: object->as()->viewModelId(value); break; + case ViewModelInstanceListBase::listSourcePropertyKey: + object->as()->listSource(value); + break; case ViewModelInstanceTriggerBase::propertyValuePropertyKey: object->as()->propertyValue( value); @@ -773,6 +955,9 @@ class CoreRegistry case ViewModelInstanceAssetBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; + case CustomPropertyTriggerBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case DrawTargetBase::drawableIdPropertyKey: object->as()->drawableId(value); break; @@ -834,6 +1019,15 @@ class CoreRegistry case SoloBase::activeComponentIdPropertyKey: object->as()->activeComponentId(value); break; + case ScriptedDrawableBase::scriptAssetIdPropertyKey: + object->as()->scriptAssetId(value); + break; + case ScriptedDataConverterBase::scriptAssetIdPropertyKey: + object->as()->scriptAssetId(value); + break; + case ScriptedPathEffectBase::scriptAssetIdPropertyKey: + object->as()->scriptAssetId(value); + break; case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: object->as()->instanceWidthUnitsValue( value); @@ -1011,12 +1205,42 @@ class CoreRegistry object->as()->maxHeightUnitsValue( value); break; + case ArtboardComponentListOverrideBase::artboardIdPropertyKey: + object->as()->artboardId( + value); + break; + case ArtboardComponentListOverrideBase:: + instanceWidthUnitsValuePropertyKey: + object->as() + ->instanceWidthUnitsValue(value); + break; + case ArtboardComponentListOverrideBase:: + instanceHeightUnitsValuePropertyKey: + object->as() + ->instanceHeightUnitsValue(value); + break; + case ArtboardComponentListOverrideBase:: + instanceWidthScaleTypePropertyKey: + object->as() + ->instanceWidthScaleType(value); + break; + case ArtboardComponentListOverrideBase:: + instanceHeightScaleTypePropertyKey: + object->as() + ->instanceHeightScaleType(value); + break; + case ListenerActionBase::flagsPropertyKey: + object->as()->flags(value); + break; case ListenerFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; case LayerStateBase::flagsPropertyKey: object->as()->flags(value); break; + case StateMachineFireActionBase::occursValuePropertyKey: + object->as()->occursValue(value); + break; case TransitionValueTriggerComparatorBase::valuePropertyKey: object->as()->value( value); @@ -1046,6 +1270,9 @@ class CoreRegistry case NestedInputBase::inputIdPropertyKey: object->as()->inputId(value); break; + case ScriptedListenerActionBase::scriptAssetIdPropertyKey: + object->as()->scriptAssetId(value); + break; case KeyedObjectBase::objectIdPropertyKey: object->as()->objectId(value); break; @@ -1058,21 +1285,21 @@ class CoreRegistry case BlendAnimationDirectBase::blendSourcePropertyKey: object->as()->blendSource(value); break; - case TransitionInputConditionBase::inputIdPropertyKey: - object->as()->inputId(value); - break; - case KeyedPropertyBase::propertyKeyPropertyKey: - object->as()->propertyKey(value); - break; case StateMachineListenerBase::targetIdPropertyKey: object->as()->targetId(value); break; - case StateMachineListenerBase::listenerTypeValuePropertyKey: - object->as()->listenerTypeValue( + case StateMachineListenerSingleBase::listenerTypeValuePropertyKey: + object->as()->listenerTypeValue( value); break; - case StateMachineListenerBase::eventIdPropertyKey: - object->as()->eventId(value); + case StateMachineListenerSingleBase::eventIdPropertyKey: + object->as()->eventId(value); + break; + case TransitionInputConditionBase::inputIdPropertyKey: + object->as()->inputId(value); + break; + case KeyedPropertyBase::propertyKeyPropertyKey: + object->as()->propertyKey(value); break; case TransitionPropertyArtboardComparatorBase:: propertyTypePropertyKey: @@ -1088,6 +1315,10 @@ class CoreRegistry case ListenerAlignTargetBase::targetIdPropertyKey: object->as()->targetId(value); break; + case ScriptedTransitionConditionBase::scriptAssetIdPropertyKey: + object->as()->scriptAssetId( + value); + break; case TransitionValueConditionBase::opValuePropertyKey: object->as()->opValue(value); break; @@ -1097,6 +1328,12 @@ class CoreRegistry case BlendState1DInputBase::inputIdPropertyKey: object->as()->inputId(value); break; + case FocusActionTargetBase::targetIdPropertyKey: + object->as()->targetId(value); + break; + case TransitionValueIdComparatorBase::valuePropertyKey: + object->as()->value(value); + break; case StateTransitionBase::stateToIdPropertyKey: object->as()->stateToId(value); break; @@ -1118,12 +1355,12 @@ class CoreRegistry case StateTransitionBase::randomWeightPropertyKey: object->as()->randomWeight(value); break; + case FocusActionTraversalBase::traversalKindPropertyKey: + object->as()->traversalKind(value); + break; case StateMachineFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; - case StateMachineFireEventBase::occursValuePropertyKey: - object->as()->occursValue(value); - break; case LinearAnimationBase::fpsPropertyKey: object->as()->fps(value); break; @@ -1139,11 +1376,23 @@ class CoreRegistry case LinearAnimationBase::workEndPropertyKey: object->as()->workEnd(value); break; + case TransitionPropertyComponentComparatorBase::objectIdPropertyKey: + object->as() + ->objectId(value); + break; + case TransitionPropertyComponentComparatorBase:: + propertyKeyPropertyKey: + object->as() + ->propertyKey(value); + break; case ElasticInterpolatorBase::easingValuePropertyKey: object->as()->easingValue(value); break; - case TransitionValueEnumComparatorBase::valuePropertyKey: - object->as()->value(value); + case ListenerInputTypeBase::listenerTypeValuePropertyKey: + object->as()->listenerTypeValue(value); + break; + case ListenerInputTypeEventBase::eventIdPropertyKey: + object->as()->eventId(value); break; case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: object->as()->exitBlendAnimationId( @@ -1152,6 +1401,9 @@ class CoreRegistry case ShapePaintBase::blendModeValuePropertyKey: object->as()->blendModeValue(value); break; + case TargetEffectBase::targetIdPropertyKey: + object->as()->targetId(value); + break; case StrokeBase::capPropertyKey: object->as()->cap(value); break; @@ -1170,6 +1422,9 @@ class CoreRegistry case PathBase::pathFlagsPropertyKey: object->as()->pathFlags(value); break; + case ListPathBase::listSourcePropertyKey: + object->as()->listSource(value); + break; case ClippingShapeBase::sourceIdPropertyKey: object->as()->sourceId(value); break; @@ -1182,6 +1437,12 @@ class CoreRegistry case ImageBase::assetIdPropertyKey: object->as()->assetId(value); break; + case ImageBase::fitPropertyKey: + object->as()->fit(value); + break; + case FocusDataBase::edgeBehaviorValuePropertyKey: + object->as()->edgeBehaviorValue(value); + break; case DrawRulesBase::drawTargetIdPropertyKey: object->as()->drawTargetId(value); break; @@ -1209,6 +1470,21 @@ class CoreRegistry case OpenUrlEventBase::targetValuePropertyKey: object->as()->targetValue(value); break; + case SemanticDataBase::rolePropertyKey: + object->as()->role(value); + break; + case SemanticDataBase::headingLevelPropertyKey: + object->as()->headingLevel(value); + break; + case SemanticDataBase::traitFlagsPropertyKey: + object->as()->traitFlags(value); + break; + case SemanticDataBase::stateFlagsPropertyKey: + object->as()->stateFlags(value); + break; + case BindablePropertyIdBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case BindablePropertyIntegerBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1221,12 +1497,12 @@ class CoreRegistry case DataBindBase::converterIdPropertyKey: object->as()->converterId(value); break; - case BindablePropertyAssetBase::propertyValuePropertyKey: - object->as()->propertyValue(value); - break; case DataConverterNumberToListBase::viewModelIdPropertyKey: object->as()->viewModelId(value); break; + case DataConverterFormulaBase::randomModeValuePropertyKey: + object->as()->randomModeValue(value); + break; case DataConverterOperationBase::operationTypePropertyKey: object->as()->operationType(value); break; @@ -1276,6 +1552,9 @@ class CoreRegistry case DataConverterToStringBase::decimalsPropertyKey: object->as()->decimals(value); break; + case BindablePropertyListBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case BindablePropertyEnumBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1354,38 +1633,47 @@ class CoreRegistry case TextBase::verticalAlignValuePropertyKey: object->as()->verticalAlignValue(value); break; + case TextBase::textRunListSourcePropertyKey: + object->as()->textRunListSource(value); + break; case TextValueRunBase::styleIdPropertyKey: object->as()->styleId(value); break; + case ArtboardListMapRuleBase::artboardIdPropertyKey: + object->as()->artboardId(value); + break; + case ArtboardListMapRuleBase::viewModelIdPropertyKey: + object->as()->viewModelId(value); + break; + case CustomPropertyEnumBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case CustomPropertyEnumBase::enumIdPropertyKey: + object->as()->enumId(value); + break; case FileAssetBase::assetIdPropertyKey: object->as()->assetId(value); break; + case ScriptAssetBase::generatorFunctionRefPropertyKey: + object->as()->generatorFunctionRef(value); + break; case AudioEventBase::assetIdPropertyKey: object->as()->assetId(value); break; - } - } - static void setColor(Core* object, int propertyKey, int value) - { - switch (propertyKey) - { - case ViewModelInstanceColorBase::propertyValuePropertyKey: - object->as()->propertyValue(value); + case KeyboardInputBase::keyTypePropertyKey: + object->as()->keyType(value); break; - case KeyFrameColorBase::valuePropertyKey: - object->as()->value(value); + case KeyboardInputBase::keyPhasePropertyKey: + object->as()->keyPhase(value); break; - case TransitionValueColorComparatorBase::valuePropertyKey: - object->as()->value(value); - break; - case SolidColorBase::colorValuePropertyKey: - object->as()->colorValue(value); + case KeyboardInputBase::modifiersPropertyKey: + object->as()->modifiers(value); break; - case GradientStopBase::colorValuePropertyKey: - object->as()->colorValue(value); + case SemanticInputBase::actionTypePropertyKey: + object->as()->actionType(value); break; - case BindablePropertyColorBase::propertyValuePropertyKey: - object->as()->propertyValue(value); + case ScriptInputArtboardBase::artboardIdPropertyKey: + object->as()->artboardId(value); break; } } @@ -1396,6 +1684,9 @@ class CoreRegistry case ViewModelComponentBase::namePropertyKey: object->as()->name(value); break; + case ComponentBase::namePropertyKey: + object->as()->name(value); + break; case DataEnumCustomBase::namePropertyKey: object->as()->name(value); break; @@ -1408,8 +1699,8 @@ class CoreRegistry case DataEnumValueBase::valuePropertyKey: object->as()->value(value); break; - case ComponentBase::namePropertyKey: - object->as()->name(value); + case DataConverterBase::namePropertyKey: + object->as()->name(value); break; case AnimationBase::namePropertyKey: object->as()->name(value); @@ -1426,8 +1717,17 @@ class CoreRegistry case OpenUrlEventBase::urlPropertyKey: object->as()->url(value); break; - case DataConverterBase::namePropertyKey: - object->as()->name(value); + case SemanticDataBase::labelPropertyKey: + object->as()->label(value); + break; + case SemanticDataBase::valuePropertyKey: + object->as()->value(value); + break; + case SemanticDataBase::hintPropertyKey: + object->as()->hint(value); + break; + case CustomPropertyStringBase::propertyValuePropertyKey: + object->as()->propertyValue(value); break; case DataConverterStringPadBase::textPropertyKey: object->as()->text(value); @@ -1444,15 +1744,42 @@ class CoreRegistry case TextValueRunBase::textPropertyKey: object->as()->text(value); break; - case CustomPropertyStringBase::propertyValuePropertyKey: - object->as()->propertyValue(value); - break; case AssetBase::namePropertyKey: object->as()->name(value); break; case FileAssetBase::cdnBaseUrlPropertyKey: object->as()->cdnBaseUrl(value); break; + case TextAssetBase::folderPathPropertyKey: + object->as()->folderPath(value); + break; + } + } + static void setColor(Core* object, int propertyKey, int value) + { + switch (propertyKey) + { + case ViewModelInstanceColorBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case CustomPropertyColorBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case KeyFrameColorBase::valuePropertyKey: + object->as()->value(value); + break; + case TransitionValueColorComparatorBase::valuePropertyKey: + object->as()->value(value); + break; + case SolidColorBase::colorValuePropertyKey: + object->as()->colorValue(value); + break; + case GradientStopBase::colorValuePropertyKey: + object->as()->colorValue(value); + break; + case BindablePropertyColorBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; } } static void setBool(Core* object, int propertyKey, bool value) @@ -1463,6 +1790,12 @@ class CoreRegistry object->as()->propertyValue( value); break; + case FollowPathConstraintBase::orientPropertyKey: + object->as()->orient(value); + break; + case FollowPathConstraintBase::offsetPropertyKey: + object->as()->offset(value); + break; case TransformComponentConstraintBase::offsetPropertyKey: object->as()->offset(value); break; @@ -1488,18 +1821,24 @@ class CoreRegistry case IKConstraintBase::invertDirectionPropertyKey: object->as()->invertDirection(value); break; - case FollowPathConstraintBase::orientPropertyKey: - object->as()->orient(value); - break; - case FollowPathConstraintBase::offsetPropertyKey: - object->as()->offset(value); - break; case ScrollConstraintBase::snapPropertyKey: object->as()->snap(value); break; + case ScrollConstraintBase::virtualizePropertyKey: + object->as()->virtualize(value); + break; + case ScrollConstraintBase::infinitePropertyKey: + object->as()->infinite(value); + break; + case ScrollConstraintBase::interactivePropertyKey: + object->as()->interactive(value); + break; case ScrollBarConstraintBase::autoSizePropertyKey: object->as()->autoSize(value); break; + case NestedArtboardBase::isPausedPropertyKey: + object->as()->isPaused(value); + break; case AxisBase::normalizedPropertyKey: object->as()->normalized(value); break; @@ -1553,8 +1892,8 @@ class CoreRegistry case PathBase::isHolePropertyKey: object->as()->isHole(value); break; - case PointsPathBase::isClosedPropertyKey: - object->as()->isClosed(value); + case PointsCommonPathBase::isClosedPropertyKey: + object->as()->isClosed(value); break; case RectangleBase::linkCornerRadiusPropertyKey: object->as()->linkCornerRadius(value); @@ -1562,12 +1901,384 @@ class CoreRegistry case ClippingShapeBase::isVisiblePropertyKey: object->as()->isVisible(value); break; + case FocusDataBase::canFocusPropertyKey: + object->as()->canFocus(value); + break; + case FocusDataBase::canTouchPropertyKey: + object->as()->canTouch(value); + break; + case FocusDataBase::canTraversePropertyKey: + object->as()->canTraverse(value); + break; case CustomPropertyBooleanBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; case LayoutComponentBase::clipPropertyKey: object->as()->clip(value); break; + case ArtboardBase::isStatefulPropertyKey: + object->as()->isStateful(value); + break; + case SemanticDataBase::isExpandablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 0); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isSelectablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 1); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isCheckablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 2); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isToggleablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 3); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isRequirablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 4); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isEnablablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 5); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isFocusablePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->traitFlags(); + const uint32_t _bm = static_cast(1u << 6); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->traitFlags(_next); + } + } + break; + } + case SemanticDataBase::isExpandedPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 0); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isSelectedPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 1); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isCheckedPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 2); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isMixedPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 3); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isToggledPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 4); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isRequiredPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 5); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isDisabledPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 6); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isFocusedPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 7); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isHiddenPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 8); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isLiveRegionPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 9); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isReadOnlyPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 10); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isModalPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 11); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isObscuredPropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 12); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case SemanticDataBase::isMultilinePropertyKey: + { + auto* _o = object->as(); + if (_o) + { + const uint32_t _cur = _o->stateFlags(); + const uint32_t _bm = static_cast(1u << 13); + const uint32_t _next = static_cast( + (_cur & ~_bm) | + (value ? _bm : static_cast(0))); + if (_cur != _next) + { + _o->stateFlags(_next); + } + } + break; + } + case DataBindPathBase::isRelativePropertyKey: + object->as()->isRelative(value); + break; case BindablePropertyBooleanBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1580,9 +2291,15 @@ class CoreRegistry case TextFollowPathModifierBase::orientPropertyKey: object->as()->orient(value); break; + case TextInputBase::multilinePropertyKey: + object->as()->multiline(value); + break; case TextBase::fitFromBaselinePropertyKey: object->as()->fitFromBaseline(value); break; + case ScriptAssetBase::isModulePropertyKey: + object->as()->isModule(value); + break; } } static void setDouble(Core* object, int propertyKey, float value) @@ -1601,6 +2318,16 @@ class CoreRegistry case DistanceConstraintBase::distancePropertyKey: object->as()->distance(value); break; + case FollowPathConstraintBase::distancePropertyKey: + object->as()->distance(value); + break; + case ListFollowPathConstraintBase::distanceEndPropertyKey: + object->as()->distanceEnd(value); + break; + case ListFollowPathConstraintBase::distanceOffsetPropertyKey: + object->as()->distanceOffset( + value); + break; case TransformComponentConstraintBase::copyFactorPropertyKey: object->as()->copyFactor( value); @@ -1623,9 +2350,6 @@ class CoreRegistry object->as()->maxValueY( value); break; - case FollowPathConstraintBase::distancePropertyKey: - object->as()->distance(value); - break; case ScrollConstraintBase::scrollOffsetXPropertyKey: object->as()->scrollOffsetX(value); break; @@ -1641,6 +2365,9 @@ class CoreRegistry case ScrollConstraintBase::scrollIndexPropertyKey: object->as()->scrollIndex(value); break; + case ScrollConstraintBase::thresholdPropertyKey: + object->as()->threshold(value); + break; case ElasticScrollPhysicsBase::frictionPropertyKey: object->as()->friction(value); break; @@ -1688,12 +2415,24 @@ class CoreRegistry case NodeBase::computedWorldYPropertyKey: object->as()->computedWorldY(value); break; + case NodeBase::computedRootXPropertyKey: + object->as()->computedRootX(value); + break; + case NodeBase::computedRootYPropertyKey: + object->as()->computedRootY(value); + break; case NodeBase::computedWidthPropertyKey: object->as()->computedWidth(value); break; case NodeBase::computedHeightPropertyKey: object->as()->computedHeight(value); break; + case NestedArtboardBase::speedPropertyKey: + object->as()->speed(value); + break; + case NestedArtboardBase::quantizePropertyKey: + object->as()->quantize(value); + break; case NestedArtboardLayoutBase::instanceWidthPropertyKey: object->as()->instanceWidth(value); break; @@ -1812,6 +2551,14 @@ class CoreRegistry case NSlicedNodeBase::heightPropertyKey: object->as()->height(value); break; + case ArtboardComponentListOverrideBase::instanceWidthPropertyKey: + object->as()->instanceWidth( + value); + break; + case ArtboardComponentListOverrideBase::instanceHeightPropertyKey: + object->as()->instanceHeight( + value); + break; case NestedLinearAnimationBase::mixPropertyKey: object->as()->mix(value); break; @@ -1995,6 +2742,12 @@ class CoreRegistry case ImageBase::originYPropertyKey: object->as()->originY(value); break; + case ImageBase::alignmentXPropertyKey: + object->as()->alignmentX(value); + break; + case ImageBase::alignmentYPropertyKey: + object->as()->alignmentY(value); + break; case CubicDetachedVertexBase::inRotationPropertyKey: object->as()->inRotation(value); break; @@ -2227,6 +2980,9 @@ class CoreRegistry { switch (propertyKey) { + case CustomPropertyTriggerBase::firePropertyKey: + object->as()->fire(value); + break; case NestedTriggerBase::firePropertyKey: object->as()->fire(value); break; @@ -2245,6 +3001,12 @@ class CoreRegistry case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: return object->as() ->viewModelInstanceId(); + case ViewModelPropertyBase::symbolTypeValuePropertyKey: + return object->as()->symbolTypeValue(); + case ViewModelPropertyBase::componentPropsPropertyKey: + return object->as()->componentProps(); + case ComponentBase::parentIdPropertyKey: + return object->as()->parentId(); case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: return object->as() ->viewModelPropertyId(); @@ -2252,6 +3014,9 @@ class CoreRegistry return object->as()->enumId(); case ViewModelInstanceEnumBase::propertyValuePropertyKey: return object->as()->propertyValue(); + case ViewModelInstanceArtboardBase::propertyValuePropertyKey: + return object->as() + ->propertyValue(); case ViewModelPropertyEnumSystemBase::enumTypePropertyKey: return object->as() ->enumType(); @@ -2261,10 +3026,10 @@ class CoreRegistry viewModelReferenceIdPropertyKey: return object->as() ->viewModelReferenceId(); - case ComponentBase::parentIdPropertyKey: - return object->as()->parentId(); case ViewModelInstanceBase::viewModelIdPropertyKey: return object->as()->viewModelId(); + case ViewModelInstanceListBase::listSourcePropertyKey: + return object->as()->listSource(); case ViewModelInstanceTriggerBase::propertyValuePropertyKey: return object->as() ->propertyValue(); @@ -2277,6 +3042,8 @@ class CoreRegistry case ViewModelInstanceAssetBase::propertyValuePropertyKey: return object->as() ->propertyValue(); + case CustomPropertyTriggerBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case DrawTargetBase::drawableIdPropertyKey: return object->as()->drawableId(); case DrawTargetBase::placementValuePropertyKey: @@ -2319,6 +3086,12 @@ class CoreRegistry return object->as()->animationId(); case SoloBase::activeComponentIdPropertyKey: return object->as()->activeComponentId(); + case ScriptedDrawableBase::scriptAssetIdPropertyKey: + return object->as()->scriptAssetId(); + case ScriptedDataConverterBase::scriptAssetIdPropertyKey: + return object->as()->scriptAssetId(); + case ScriptedPathEffectBase::scriptAssetIdPropertyKey: + return object->as()->scriptAssetId(); case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: return object->as() ->instanceWidthUnitsValue(); @@ -2452,10 +3225,33 @@ class CoreRegistry case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: return object->as() ->maxHeightUnitsValue(); + case ArtboardComponentListOverrideBase::artboardIdPropertyKey: + return object->as() + ->artboardId(); + case ArtboardComponentListOverrideBase:: + instanceWidthUnitsValuePropertyKey: + return object->as() + ->instanceWidthUnitsValue(); + case ArtboardComponentListOverrideBase:: + instanceHeightUnitsValuePropertyKey: + return object->as() + ->instanceHeightUnitsValue(); + case ArtboardComponentListOverrideBase:: + instanceWidthScaleTypePropertyKey: + return object->as() + ->instanceWidthScaleType(); + case ArtboardComponentListOverrideBase:: + instanceHeightScaleTypePropertyKey: + return object->as() + ->instanceHeightScaleType(); + case ListenerActionBase::flagsPropertyKey: + return object->as()->flags(); case ListenerFireEventBase::eventIdPropertyKey: return object->as()->eventId(); case LayerStateBase::flagsPropertyKey: return object->as()->flags(); + case StateMachineFireActionBase::occursValuePropertyKey: + return object->as()->occursValue(); case TransitionValueTriggerComparatorBase::valuePropertyKey: return object->as() ->value(); @@ -2477,6 +3273,9 @@ class CoreRegistry return object->as()->animationId(); case NestedInputBase::inputIdPropertyKey: return object->as()->inputId(); + case ScriptedListenerActionBase::scriptAssetIdPropertyKey: + return object->as() + ->scriptAssetId(); case KeyedObjectBase::objectIdPropertyKey: return object->as()->objectId(); case BlendAnimationBase::animationIdPropertyKey: @@ -2485,17 +3284,17 @@ class CoreRegistry return object->as()->inputId(); case BlendAnimationDirectBase::blendSourcePropertyKey: return object->as()->blendSource(); + case StateMachineListenerBase::targetIdPropertyKey: + return object->as()->targetId(); + case StateMachineListenerSingleBase::listenerTypeValuePropertyKey: + return object->as() + ->listenerTypeValue(); + case StateMachineListenerSingleBase::eventIdPropertyKey: + return object->as()->eventId(); case TransitionInputConditionBase::inputIdPropertyKey: return object->as()->inputId(); case KeyedPropertyBase::propertyKeyPropertyKey: return object->as()->propertyKey(); - case StateMachineListenerBase::targetIdPropertyKey: - return object->as()->targetId(); - case StateMachineListenerBase::listenerTypeValuePropertyKey: - return object->as() - ->listenerTypeValue(); - case StateMachineListenerBase::eventIdPropertyKey: - return object->as()->eventId(); case TransitionPropertyArtboardComparatorBase:: propertyTypePropertyKey: return object->as() @@ -2506,6 +3305,9 @@ class CoreRegistry return object->as()->value(); case ListenerAlignTargetBase::targetIdPropertyKey: return object->as()->targetId(); + case ScriptedTransitionConditionBase::scriptAssetIdPropertyKey: + return object->as() + ->scriptAssetId(); case TransitionValueConditionBase::opValuePropertyKey: return object->as()->opValue(); case TransitionViewModelConditionBase::opValuePropertyKey: @@ -2513,6 +3315,10 @@ class CoreRegistry ->opValue(); case BlendState1DInputBase::inputIdPropertyKey: return object->as()->inputId(); + case FocusActionTargetBase::targetIdPropertyKey: + return object->as()->targetId(); + case TransitionValueIdComparatorBase::valuePropertyKey: + return object->as()->value(); case StateTransitionBase::stateToIdPropertyKey: return object->as()->stateToId(); case StateTransitionBase::flagsPropertyKey: @@ -2527,10 +3333,10 @@ class CoreRegistry return object->as()->interpolatorId(); case StateTransitionBase::randomWeightPropertyKey: return object->as()->randomWeight(); + case FocusActionTraversalBase::traversalKindPropertyKey: + return object->as()->traversalKind(); case StateMachineFireEventBase::eventIdPropertyKey: return object->as()->eventId(); - case StateMachineFireEventBase::occursValuePropertyKey: - return object->as()->occursValue(); case LinearAnimationBase::fpsPropertyKey: return object->as()->fps(); case LinearAnimationBase::durationPropertyKey: @@ -2541,15 +3347,26 @@ class CoreRegistry return object->as()->workStart(); case LinearAnimationBase::workEndPropertyKey: return object->as()->workEnd(); + case TransitionPropertyComponentComparatorBase::objectIdPropertyKey: + return object->as() + ->objectId(); + case TransitionPropertyComponentComparatorBase:: + propertyKeyPropertyKey: + return object->as() + ->propertyKey(); case ElasticInterpolatorBase::easingValuePropertyKey: return object->as()->easingValue(); - case TransitionValueEnumComparatorBase::valuePropertyKey: - return object->as()->value(); + case ListenerInputTypeBase::listenerTypeValuePropertyKey: + return object->as()->listenerTypeValue(); + case ListenerInputTypeEventBase::eventIdPropertyKey: + return object->as()->eventId(); case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: return object->as() ->exitBlendAnimationId(); case ShapePaintBase::blendModeValuePropertyKey: return object->as()->blendModeValue(); + case TargetEffectBase::targetIdPropertyKey: + return object->as()->targetId(); case StrokeBase::capPropertyKey: return object->as()->cap(); case StrokeBase::joinPropertyKey: @@ -2562,6 +3379,8 @@ class CoreRegistry return object->as()->fillRule(); case PathBase::pathFlagsPropertyKey: return object->as()->pathFlags(); + case ListPathBase::listSourcePropertyKey: + return object->as()->listSource(); case ClippingShapeBase::sourceIdPropertyKey: return object->as()->sourceId(); case ClippingShapeBase::fillRulePropertyKey: @@ -2570,6 +3389,10 @@ class CoreRegistry return object->as()->points(); case ImageBase::assetIdPropertyKey: return object->as()->assetId(); + case ImageBase::fitPropertyKey: + return object->as()->fit(); + case FocusDataBase::edgeBehaviorValuePropertyKey: + return object->as()->edgeBehaviorValue(); case DrawRulesBase::drawTargetIdPropertyKey: return object->as()->drawTargetId(); case LayoutComponentBase::styleIdPropertyKey: @@ -2588,6 +3411,16 @@ class CoreRegistry return object->as()->handleSourceId(); case OpenUrlEventBase::targetValuePropertyKey: return object->as()->targetValue(); + case SemanticDataBase::rolePropertyKey: + return object->as()->role(); + case SemanticDataBase::headingLevelPropertyKey: + return object->as()->headingLevel(); + case SemanticDataBase::traitFlagsPropertyKey: + return object->as()->traitFlags(); + case SemanticDataBase::stateFlagsPropertyKey: + return object->as()->stateFlags(); + case BindablePropertyIdBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case BindablePropertyIntegerBase::propertyValuePropertyKey: return object->as() ->propertyValue(); @@ -2597,11 +3430,12 @@ class CoreRegistry return object->as()->flags(); case DataBindBase::converterIdPropertyKey: return object->as()->converterId(); - case BindablePropertyAssetBase::propertyValuePropertyKey: - return object->as()->propertyValue(); case DataConverterNumberToListBase::viewModelIdPropertyKey: return object->as() ->viewModelId(); + case DataConverterFormulaBase::randomModeValuePropertyKey: + return object->as() + ->randomModeValue(); case DataConverterOperationBase::operationTypePropertyKey: return object->as() ->operationType(); @@ -2637,6 +3471,8 @@ class CoreRegistry return object->as()->flags(); case DataConverterToStringBase::decimalsPropertyKey: return object->as()->decimals(); + case BindablePropertyListBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->as()->propertyValue(); case NestedArtboardLeafBase::fitPropertyKey: @@ -2689,33 +3525,34 @@ class CoreRegistry return object->as()->wrapValue(); case TextBase::verticalAlignValuePropertyKey: return object->as()->verticalAlignValue(); + case TextBase::textRunListSourcePropertyKey: + return object->as()->textRunListSource(); case TextValueRunBase::styleIdPropertyKey: return object->as()->styleId(); + case ArtboardListMapRuleBase::artboardIdPropertyKey: + return object->as()->artboardId(); + case ArtboardListMapRuleBase::viewModelIdPropertyKey: + return object->as()->viewModelId(); + case CustomPropertyEnumBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + case CustomPropertyEnumBase::enumIdPropertyKey: + return object->as()->enumId(); case FileAssetBase::assetIdPropertyKey: return object->as()->assetId(); + case ScriptAssetBase::generatorFunctionRefPropertyKey: + return object->as()->generatorFunctionRef(); case AudioEventBase::assetIdPropertyKey: return object->as()->assetId(); - } - return 0; - } - static int getColor(Core* object, int propertyKey) - { - switch (propertyKey) - { - case ViewModelInstanceColorBase::propertyValuePropertyKey: - return object->as() - ->propertyValue(); - case KeyFrameColorBase::valuePropertyKey: - return object->as()->value(); - case TransitionValueColorComparatorBase::valuePropertyKey: - return object->as() - ->value(); - case SolidColorBase::colorValuePropertyKey: - return object->as()->colorValue(); - case GradientStopBase::colorValuePropertyKey: - return object->as()->colorValue(); - case BindablePropertyColorBase::propertyValuePropertyKey: - return object->as()->propertyValue(); + case KeyboardInputBase::keyTypePropertyKey: + return object->as()->keyType(); + case KeyboardInputBase::keyPhasePropertyKey: + return object->as()->keyPhase(); + case KeyboardInputBase::modifiersPropertyKey: + return object->as()->modifiers(); + case SemanticInputBase::actionTypePropertyKey: + return object->as()->actionType(); + case ScriptInputArtboardBase::artboardIdPropertyKey: + return object->as()->artboardId(); } return 0; } @@ -2725,6 +3562,8 @@ class CoreRegistry { case ViewModelComponentBase::namePropertyKey: return object->as()->name(); + case ComponentBase::namePropertyKey: + return object->as()->name(); case DataEnumCustomBase::namePropertyKey: return object->as()->name(); case ViewModelInstanceStringBase::propertyValuePropertyKey: @@ -2734,8 +3573,8 @@ class CoreRegistry return object->as()->key(); case DataEnumValueBase::valuePropertyKey: return object->as()->value(); - case ComponentBase::namePropertyKey: - return object->as()->name(); + case DataConverterBase::namePropertyKey: + return object->as()->name(); case AnimationBase::namePropertyKey: return object->as()->name(); case StateMachineComponentBase::namePropertyKey: @@ -2747,8 +3586,14 @@ class CoreRegistry ->value(); case OpenUrlEventBase::urlPropertyKey: return object->as()->url(); - case DataConverterBase::namePropertyKey: - return object->as()->name(); + case SemanticDataBase::labelPropertyKey: + return object->as()->label(); + case SemanticDataBase::valuePropertyKey: + return object->as()->value(); + case SemanticDataBase::hintPropertyKey: + return object->as()->hint(); + case CustomPropertyStringBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case DataConverterStringPadBase::textPropertyKey: return object->as()->text(); case DataConverterToStringBase::colorFormatPropertyKey: @@ -2760,15 +3605,38 @@ class CoreRegistry return object->as()->text(); case TextValueRunBase::textPropertyKey: return object->as()->text(); - case CustomPropertyStringBase::propertyValuePropertyKey: - return object->as()->propertyValue(); case AssetBase::namePropertyKey: return object->as()->name(); case FileAssetBase::cdnBaseUrlPropertyKey: return object->as()->cdnBaseUrl(); + case TextAssetBase::folderPathPropertyKey: + return object->as()->folderPath(); } return ""; } + static int getColor(Core* object, int propertyKey) + { + switch (propertyKey) + { + case ViewModelInstanceColorBase::propertyValuePropertyKey: + return object->as() + ->propertyValue(); + case CustomPropertyColorBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + case KeyFrameColorBase::valuePropertyKey: + return object->as()->value(); + case TransitionValueColorComparatorBase::valuePropertyKey: + return object->as() + ->value(); + case SolidColorBase::colorValuePropertyKey: + return object->as()->colorValue(); + case GradientStopBase::colorValuePropertyKey: + return object->as()->colorValue(); + case BindablePropertyColorBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + } + return 0; + } static bool getBool(Core* object, int propertyKey) { switch (propertyKey) @@ -2776,6 +3644,10 @@ class CoreRegistry case ViewModelInstanceBooleanBase::propertyValuePropertyKey: return object->as() ->propertyValue(); + case FollowPathConstraintBase::orientPropertyKey: + return object->as()->orient(); + case FollowPathConstraintBase::offsetPropertyKey: + return object->as()->offset(); case TransformComponentConstraintBase::offsetPropertyKey: return object->as()->offset(); case TransformComponentConstraintBase::doesCopyPropertyKey: @@ -2794,14 +3666,18 @@ class CoreRegistry return object->as()->maxY(); case IKConstraintBase::invertDirectionPropertyKey: return object->as()->invertDirection(); - case FollowPathConstraintBase::orientPropertyKey: - return object->as()->orient(); - case FollowPathConstraintBase::offsetPropertyKey: - return object->as()->offset(); case ScrollConstraintBase::snapPropertyKey: return object->as()->snap(); + case ScrollConstraintBase::virtualizePropertyKey: + return object->as()->virtualize(); + case ScrollConstraintBase::infinitePropertyKey: + return object->as()->infinite(); + case ScrollConstraintBase::interactivePropertyKey: + return object->as()->interactive(); case ScrollBarConstraintBase::autoSizePropertyKey: return object->as()->autoSize(); + case NestedArtboardBase::isPausedPropertyKey: + return object->as()->isPaused(); case AxisBase::normalizedPropertyKey: return object->as()->normalized(); case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: @@ -2839,16 +3715,26 @@ class CoreRegistry return object->as()->inner(); case PathBase::isHolePropertyKey: return object->as()->isHole(); - case PointsPathBase::isClosedPropertyKey: - return object->as()->isClosed(); + case PointsCommonPathBase::isClosedPropertyKey: + return object->as()->isClosed(); case RectangleBase::linkCornerRadiusPropertyKey: return object->as()->linkCornerRadius(); case ClippingShapeBase::isVisiblePropertyKey: return object->as()->isVisible(); + case FocusDataBase::canFocusPropertyKey: + return object->as()->canFocus(); + case FocusDataBase::canTouchPropertyKey: + return object->as()->canTouch(); + case FocusDataBase::canTraversePropertyKey: + return object->as()->canTraverse(); case CustomPropertyBooleanBase::propertyValuePropertyKey: return object->as()->propertyValue(); case LayoutComponentBase::clipPropertyKey: return object->as()->clip(); + case ArtboardBase::isStatefulPropertyKey: + return object->as()->isStateful(); + case DataBindPathBase::isRelativePropertyKey: + return object->as()->isRelative(); case BindablePropertyBooleanBase::propertyValuePropertyKey: return object->as() ->propertyValue(); @@ -2858,8 +3744,12 @@ class CoreRegistry return object->as()->radial(); case TextFollowPathModifierBase::orientPropertyKey: return object->as()->orient(); + case TextInputBase::multilinePropertyKey: + return object->as()->multiline(); case TextBase::fitFromBaselinePropertyKey: return object->as()->fitFromBaseline(); + case ScriptAssetBase::isModulePropertyKey: + return object->as()->isModule(); } return false; } @@ -2876,6 +3766,14 @@ class CoreRegistry return object->as()->strength(); case DistanceConstraintBase::distancePropertyKey: return object->as()->distance(); + case FollowPathConstraintBase::distancePropertyKey: + return object->as()->distance(); + case ListFollowPathConstraintBase::distanceEndPropertyKey: + return object->as() + ->distanceEnd(); + case ListFollowPathConstraintBase::distanceOffsetPropertyKey: + return object->as() + ->distanceOffset(); case TransformComponentConstraintBase::copyFactorPropertyKey: return object->as() ->copyFactor(); @@ -2894,8 +3792,6 @@ class CoreRegistry case TransformComponentConstraintYBase::maxValueYPropertyKey: return object->as() ->maxValueY(); - case FollowPathConstraintBase::distancePropertyKey: - return object->as()->distance(); case ScrollConstraintBase::scrollOffsetXPropertyKey: return object->as()->scrollOffsetX(); case ScrollConstraintBase::scrollOffsetYPropertyKey: @@ -2906,6 +3802,8 @@ class CoreRegistry return object->as()->scrollPercentY(); case ScrollConstraintBase::scrollIndexPropertyKey: return object->as()->scrollIndex(); + case ScrollConstraintBase::thresholdPropertyKey: + return object->as()->threshold(); case ElasticScrollPhysicsBase::frictionPropertyKey: return object->as()->friction(); case ElasticScrollPhysicsBase::speedMultiplierPropertyKey: @@ -2939,10 +3837,18 @@ class CoreRegistry return object->as()->computedWorldX(); case NodeBase::computedWorldYPropertyKey: return object->as()->computedWorldY(); + case NodeBase::computedRootXPropertyKey: + return object->as()->computedRootX(); + case NodeBase::computedRootYPropertyKey: + return object->as()->computedRootY(); case NodeBase::computedWidthPropertyKey: return object->as()->computedWidth(); case NodeBase::computedHeightPropertyKey: return object->as()->computedHeight(); + case NestedArtboardBase::speedPropertyKey: + return object->as()->speed(); + case NestedArtboardBase::quantizePropertyKey: + return object->as()->quantize(); case NestedArtboardLayoutBase::instanceWidthPropertyKey: return object->as()->instanceWidth(); case NestedArtboardLayoutBase::instanceHeightPropertyKey: @@ -3022,6 +3928,12 @@ class CoreRegistry return object->as()->width(); case NSlicedNodeBase::heightPropertyKey: return object->as()->height(); + case ArtboardComponentListOverrideBase::instanceWidthPropertyKey: + return object->as() + ->instanceWidth(); + case ArtboardComponentListOverrideBase::instanceHeightPropertyKey: + return object->as() + ->instanceHeight(); case NestedLinearAnimationBase::mixPropertyKey: return object->as()->mix(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -3145,6 +4057,10 @@ class CoreRegistry return object->as()->originX(); case ImageBase::originYPropertyKey: return object->as()->originY(); + case ImageBase::alignmentXPropertyKey: + return object->as()->alignmentX(); + case ImageBase::alignmentYPropertyKey: + return object->as()->alignmentY(); case CubicDetachedVertexBase::inRotationPropertyKey: return object->as()->inRotation(); case CubicDetachedVertexBase::inDistancePropertyKey: @@ -3306,19 +4222,24 @@ class CoreRegistry { case ViewModelInstanceListItemBase::viewModelIdPropertyKey: case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: + case ViewModelPropertyBase::symbolTypeValuePropertyKey: + case ViewModelPropertyBase::componentPropsPropertyKey: + case ComponentBase::parentIdPropertyKey: case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: case ViewModelPropertyEnumCustomBase::enumIdPropertyKey: case ViewModelInstanceEnumBase::propertyValuePropertyKey: + case ViewModelInstanceArtboardBase::propertyValuePropertyKey: case ViewModelPropertyEnumSystemBase::enumTypePropertyKey: case DataEnumSystemBase::enumTypePropertyKey: case ViewModelPropertyViewModelBase:: viewModelReferenceIdPropertyKey: - case ComponentBase::parentIdPropertyKey: case ViewModelInstanceBase::viewModelIdPropertyKey: + case ViewModelInstanceListBase::listSourcePropertyKey: case ViewModelInstanceTriggerBase::propertyValuePropertyKey: case ViewModelInstanceSymbolListIndexBase::propertyValuePropertyKey: case ViewModelInstanceViewModelBase::propertyValuePropertyKey: case ViewModelInstanceAssetBase::propertyValuePropertyKey: + case CustomPropertyTriggerBase::propertyValuePropertyKey: case DrawTargetBase::drawableIdPropertyKey: case DrawTargetBase::placementValuePropertyKey: case TargetedConstraintBase::targetIdPropertyKey: @@ -3338,6 +4259,9 @@ class CoreRegistry case ArtboardComponentListBase::listSourcePropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: + case ScriptedDrawableBase::scriptAssetIdPropertyKey: + case ScriptedDataConverterBase::scriptAssetIdPropertyKey: + case ScriptedPathEffectBase::scriptAssetIdPropertyKey: case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: @@ -3385,8 +4309,19 @@ class CoreRegistry case LayoutComponentStyleBase::minHeightUnitsValuePropertyKey: case LayoutComponentStyleBase::maxWidthUnitsValuePropertyKey: case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: + case ArtboardComponentListOverrideBase::artboardIdPropertyKey: + case ArtboardComponentListOverrideBase:: + instanceWidthUnitsValuePropertyKey: + case ArtboardComponentListOverrideBase:: + instanceHeightUnitsValuePropertyKey: + case ArtboardComponentListOverrideBase:: + instanceWidthScaleTypePropertyKey: + case ArtboardComponentListOverrideBase:: + instanceHeightScaleTypePropertyKey: + case ListenerActionBase::flagsPropertyKey: case ListenerFireEventBase::eventIdPropertyKey: case LayerStateBase::flagsPropertyKey: + case StateMachineFireActionBase::occursValuePropertyKey: case TransitionValueTriggerComparatorBase::valuePropertyKey: case KeyFrameBase::framePropertyKey: case InterpolatingKeyFrameBase::interpolationTypePropertyKey: @@ -3396,23 +4331,27 @@ class CoreRegistry case ListenerInputChangeBase::nestedInputIdPropertyKey: case AnimationStateBase::animationIdPropertyKey: case NestedInputBase::inputIdPropertyKey: + case ScriptedListenerActionBase::scriptAssetIdPropertyKey: case KeyedObjectBase::objectIdPropertyKey: case BlendAnimationBase::animationIdPropertyKey: case BlendAnimationDirectBase::inputIdPropertyKey: case BlendAnimationDirectBase::blendSourcePropertyKey: + case StateMachineListenerBase::targetIdPropertyKey: + case StateMachineListenerSingleBase::listenerTypeValuePropertyKey: + case StateMachineListenerSingleBase::eventIdPropertyKey: case TransitionInputConditionBase::inputIdPropertyKey: case KeyedPropertyBase::propertyKeyPropertyKey: - case StateMachineListenerBase::targetIdPropertyKey: - case StateMachineListenerBase::listenerTypeValuePropertyKey: - case StateMachineListenerBase::eventIdPropertyKey: case TransitionPropertyArtboardComparatorBase:: propertyTypePropertyKey: case KeyFrameIdBase::valuePropertyKey: case ListenerBoolChangeBase::valuePropertyKey: case ListenerAlignTargetBase::targetIdPropertyKey: + case ScriptedTransitionConditionBase::scriptAssetIdPropertyKey: case TransitionValueConditionBase::opValuePropertyKey: case TransitionViewModelConditionBase::opValuePropertyKey: case BlendState1DInputBase::inputIdPropertyKey: + case FocusActionTargetBase::targetIdPropertyKey: + case TransitionValueIdComparatorBase::valuePropertyKey: case StateTransitionBase::stateToIdPropertyKey: case StateTransitionBase::flagsPropertyKey: case StateTransitionBase::durationPropertyKey: @@ -3420,27 +4359,35 @@ class CoreRegistry case StateTransitionBase::interpolationTypePropertyKey: case StateTransitionBase::interpolatorIdPropertyKey: case StateTransitionBase::randomWeightPropertyKey: + case FocusActionTraversalBase::traversalKindPropertyKey: case StateMachineFireEventBase::eventIdPropertyKey: - case StateMachineFireEventBase::occursValuePropertyKey: case LinearAnimationBase::fpsPropertyKey: case LinearAnimationBase::durationPropertyKey: case LinearAnimationBase::loopValuePropertyKey: case LinearAnimationBase::workStartPropertyKey: case LinearAnimationBase::workEndPropertyKey: + case TransitionPropertyComponentComparatorBase::objectIdPropertyKey: + case TransitionPropertyComponentComparatorBase:: + propertyKeyPropertyKey: case ElasticInterpolatorBase::easingValuePropertyKey: - case TransitionValueEnumComparatorBase::valuePropertyKey: + case ListenerInputTypeBase::listenerTypeValuePropertyKey: + case ListenerInputTypeEventBase::eventIdPropertyKey: case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: case ShapePaintBase::blendModeValuePropertyKey: + case TargetEffectBase::targetIdPropertyKey: case StrokeBase::capPropertyKey: case StrokeBase::joinPropertyKey: case FeatherBase::spaceValuePropertyKey: case TrimPathBase::modeValuePropertyKey: case FillBase::fillRulePropertyKey: case PathBase::pathFlagsPropertyKey: + case ListPathBase::listSourcePropertyKey: case ClippingShapeBase::sourceIdPropertyKey: case ClippingShapeBase::fillRulePropertyKey: case PolygonBase::pointsPropertyKey: case ImageBase::assetIdPropertyKey: + case ImageBase::fitPropertyKey: + case FocusDataBase::edgeBehaviorValuePropertyKey: case DrawRulesBase::drawTargetIdPropertyKey: case LayoutComponentBase::styleIdPropertyKey: case ArtboardBase::defaultStateMachineIdPropertyKey: @@ -3450,12 +4397,17 @@ class CoreRegistry case JoystickBase::joystickFlagsPropertyKey: case JoystickBase::handleSourceIdPropertyKey: case OpenUrlEventBase::targetValuePropertyKey: + case SemanticDataBase::rolePropertyKey: + case SemanticDataBase::headingLevelPropertyKey: + case SemanticDataBase::traitFlagsPropertyKey: + case SemanticDataBase::stateFlagsPropertyKey: + case BindablePropertyIdBase::propertyValuePropertyKey: case BindablePropertyIntegerBase::propertyValuePropertyKey: case DataBindBase::propertyKeyPropertyKey: case DataBindBase::flagsPropertyKey: case DataBindBase::converterIdPropertyKey: - case BindablePropertyAssetBase::propertyValuePropertyKey: case DataConverterNumberToListBase::viewModelIdPropertyKey: + case DataConverterFormulaBase::randomModeValuePropertyKey: case DataConverterOperationBase::operationTypePropertyKey: case DataConverterRangeMapperBase::interpolationTypePropertyKey: case DataConverterRangeMapperBase::interpolatorIdPropertyKey: @@ -3471,6 +4423,7 @@ class CoreRegistry case FormulaTokenFunctionBase::functionTypePropertyKey: case DataConverterToStringBase::flagsPropertyKey: case DataConverterToStringBase::decimalsPropertyKey: + case BindablePropertyListBase::propertyValuePropertyKey: case BindablePropertyEnumBase::propertyValuePropertyKey: case NestedArtboardLeafBase::fitPropertyKey: case WeightBase::valuesPropertyKey: @@ -3497,39 +4450,57 @@ class CoreRegistry case TextBase::originValuePropertyKey: case TextBase::wrapValuePropertyKey: case TextBase::verticalAlignValuePropertyKey: + case TextBase::textRunListSourcePropertyKey: case TextValueRunBase::styleIdPropertyKey: + case ArtboardListMapRuleBase::artboardIdPropertyKey: + case ArtboardListMapRuleBase::viewModelIdPropertyKey: + case CustomPropertyEnumBase::propertyValuePropertyKey: + case CustomPropertyEnumBase::enumIdPropertyKey: case FileAssetBase::assetIdPropertyKey: + case ScriptAssetBase::generatorFunctionRefPropertyKey: case AudioEventBase::assetIdPropertyKey: + case KeyboardInputBase::keyTypePropertyKey: + case KeyboardInputBase::keyPhasePropertyKey: + case KeyboardInputBase::modifiersPropertyKey: + case SemanticInputBase::actionTypePropertyKey: + case ScriptInputArtboardBase::artboardIdPropertyKey: return CoreUintType::id; - case ViewModelInstanceColorBase::propertyValuePropertyKey: - case KeyFrameColorBase::valuePropertyKey: - case TransitionValueColorComparatorBase::valuePropertyKey: - case SolidColorBase::colorValuePropertyKey: - case GradientStopBase::colorValuePropertyKey: - case BindablePropertyColorBase::propertyValuePropertyKey: - return CoreColorType::id; case ViewModelComponentBase::namePropertyKey: + case ComponentBase::namePropertyKey: case DataEnumCustomBase::namePropertyKey: case ViewModelInstanceStringBase::propertyValuePropertyKey: case DataEnumValueBase::keyPropertyKey: case DataEnumValueBase::valuePropertyKey: - case ComponentBase::namePropertyKey: + case DataConverterBase::namePropertyKey: case AnimationBase::namePropertyKey: case StateMachineComponentBase::namePropertyKey: case KeyFrameStringBase::valuePropertyKey: case TransitionValueStringComparatorBase::valuePropertyKey: case OpenUrlEventBase::urlPropertyKey: - case DataConverterBase::namePropertyKey: + case SemanticDataBase::labelPropertyKey: + case SemanticDataBase::valuePropertyKey: + case SemanticDataBase::hintPropertyKey: + case CustomPropertyStringBase::propertyValuePropertyKey: case DataConverterStringPadBase::textPropertyKey: case DataConverterToStringBase::colorFormatPropertyKey: case BindablePropertyStringBase::propertyValuePropertyKey: case TextInputBase::textPropertyKey: case TextValueRunBase::textPropertyKey: - case CustomPropertyStringBase::propertyValuePropertyKey: case AssetBase::namePropertyKey: case FileAssetBase::cdnBaseUrlPropertyKey: + case TextAssetBase::folderPathPropertyKey: return CoreStringType::id; + case ViewModelInstanceColorBase::propertyValuePropertyKey: + case CustomPropertyColorBase::propertyValuePropertyKey: + case KeyFrameColorBase::valuePropertyKey: + case TransitionValueColorComparatorBase::valuePropertyKey: + case SolidColorBase::colorValuePropertyKey: + case GradientStopBase::colorValuePropertyKey: + case BindablePropertyColorBase::propertyValuePropertyKey: + return CoreColorType::id; case ViewModelInstanceBooleanBase::propertyValuePropertyKey: + case FollowPathConstraintBase::orientPropertyKey: + case FollowPathConstraintBase::offsetPropertyKey: case TransformComponentConstraintBase::offsetPropertyKey: case TransformComponentConstraintBase::doesCopyPropertyKey: case TransformComponentConstraintBase::minPropertyKey: @@ -3538,10 +4509,12 @@ class CoreRegistry case TransformComponentConstraintYBase::minYPropertyKey: case TransformComponentConstraintYBase::maxYPropertyKey: case IKConstraintBase::invertDirectionPropertyKey: - case FollowPathConstraintBase::orientPropertyKey: - case FollowPathConstraintBase::offsetPropertyKey: case ScrollConstraintBase::snapPropertyKey: + case ScrollConstraintBase::virtualizePropertyKey: + case ScrollConstraintBase::infinitePropertyKey: + case ScrollConstraintBase::interactivePropertyKey: case ScrollBarConstraintBase::autoSizePropertyKey: + case NestedArtboardBase::isPausedPropertyKey: case AxisBase::normalizedPropertyKey: case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: @@ -3559,33 +4532,43 @@ class CoreRegistry case StrokeBase::transformAffectsStrokePropertyKey: case FeatherBase::innerPropertyKey: case PathBase::isHolePropertyKey: - case PointsPathBase::isClosedPropertyKey: + case PointsCommonPathBase::isClosedPropertyKey: case RectangleBase::linkCornerRadiusPropertyKey: case ClippingShapeBase::isVisiblePropertyKey: + case FocusDataBase::canFocusPropertyKey: + case FocusDataBase::canTouchPropertyKey: + case FocusDataBase::canTraversePropertyKey: case CustomPropertyBooleanBase::propertyValuePropertyKey: case LayoutComponentBase::clipPropertyKey: + case ArtboardBase::isStatefulPropertyKey: + case DataBindPathBase::isRelativePropertyKey: case BindablePropertyBooleanBase::propertyValuePropertyKey: case TextModifierRangeBase::clampPropertyKey: case TextFollowPathModifierBase::radialPropertyKey: case TextFollowPathModifierBase::orientPropertyKey: + case TextInputBase::multilinePropertyKey: case TextBase::fitFromBaselinePropertyKey: + case ScriptAssetBase::isModulePropertyKey: return CoreBoolType::id; case ViewModelInstanceNumberBase::propertyValuePropertyKey: case CustomPropertyNumberBase::propertyValuePropertyKey: case ConstraintBase::strengthPropertyKey: case DistanceConstraintBase::distancePropertyKey: + case FollowPathConstraintBase::distancePropertyKey: + case ListFollowPathConstraintBase::distanceEndPropertyKey: + case ListFollowPathConstraintBase::distanceOffsetPropertyKey: case TransformComponentConstraintBase::copyFactorPropertyKey: case TransformComponentConstraintBase::minValuePropertyKey: case TransformComponentConstraintBase::maxValuePropertyKey: case TransformComponentConstraintYBase::copyFactorYPropertyKey: case TransformComponentConstraintYBase::minValueYPropertyKey: case TransformComponentConstraintYBase::maxValueYPropertyKey: - case FollowPathConstraintBase::distancePropertyKey: case ScrollConstraintBase::scrollOffsetXPropertyKey: case ScrollConstraintBase::scrollOffsetYPropertyKey: case ScrollConstraintBase::scrollPercentXPropertyKey: case ScrollConstraintBase::scrollPercentYPropertyKey: case ScrollConstraintBase::scrollIndexPropertyKey: + case ScrollConstraintBase::thresholdPropertyKey: case ElasticScrollPhysicsBase::frictionPropertyKey: case ElasticScrollPhysicsBase::speedMultiplierPropertyKey: case ElasticScrollPhysicsBase::elasticFactorPropertyKey: @@ -3603,8 +4586,12 @@ class CoreRegistry case NodeBase::computedLocalYPropertyKey: case NodeBase::computedWorldXPropertyKey: case NodeBase::computedWorldYPropertyKey: + case NodeBase::computedRootXPropertyKey: + case NodeBase::computedRootYPropertyKey: case NodeBase::computedWidthPropertyKey: case NodeBase::computedHeightPropertyKey: + case NestedArtboardBase::speedPropertyKey: + case NestedArtboardBase::quantizePropertyKey: case NestedArtboardLayoutBase::instanceWidthPropertyKey: case NestedArtboardLayoutBase::instanceHeightPropertyKey: case AxisBase::offsetPropertyKey: @@ -3644,6 +4631,8 @@ class CoreRegistry case NSlicedNodeBase::initialHeightPropertyKey: case NSlicedNodeBase::widthPropertyKey: case NSlicedNodeBase::heightPropertyKey: + case ArtboardComponentListOverrideBase::instanceWidthPropertyKey: + case ArtboardComponentListOverrideBase::instanceHeightPropertyKey: case NestedLinearAnimationBase::mixPropertyKey: case NestedSimpleAnimationBase::speedPropertyKey: case AdvanceableStateBase::speedPropertyKey: @@ -3705,6 +4694,8 @@ class CoreRegistry case StarBase::innerRadiusPropertyKey: case ImageBase::originXPropertyKey: case ImageBase::originYPropertyKey: + case ImageBase::alignmentXPropertyKey: + case ImageBase::alignmentYPropertyKey: case CubicDetachedVertexBase::inRotationPropertyKey: case CubicDetachedVertexBase::inDistancePropertyKey: case CubicDetachedVertexBase::outRotationPropertyKey: @@ -3781,12 +4772,18 @@ class CoreRegistry case DrawableAssetBase::widthPropertyKey: case ExportAudioBase::volumePropertyKey: return CoreDoubleType::id; + case ScriptInputViewModelPropertyBase::dataBindPathIdsPropertyKey: case NestedArtboardBase::dataBindPathIdsPropertyKey: + case StateMachineFireTriggerBase::viewModelPathIdsPropertyKey: + case StateMachineListenerSingleBase::viewModelPathIdsPropertyKey: + case ListenerInputTypeViewModelBase::viewModelPathIdsPropertyKey: case MeshBase::triangleIndexBytesPropertyKey: + case DataBindPathBase::pathPropertyKey: case DataConverterOperationViewModelBase::sourcePathIdsPropertyKey: case DataBindContextBase::sourcePathIdsPropertyKey: case FileAssetBase::cdnUuidPropertyKey: case FileAssetContentsBase::bytesPropertyKey: + case FileAssetContentsBase::signaturePropertyKey: return CoreBytesType::id; default: return -1; @@ -3796,6 +4793,7 @@ class CoreRegistry { switch (propertyKey) { + case CustomPropertyTriggerBase::firePropertyKey: case NestedTriggerBase::firePropertyKey: case EventBase::triggerPropertyKey: return true; @@ -3811,12 +4809,20 @@ class CoreRegistry return object->is(); case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: return object->is(); + case ViewModelPropertyBase::symbolTypeValuePropertyKey: + return object->is(); + case ViewModelPropertyBase::componentPropsPropertyKey: + return object->is(); + case ComponentBase::parentIdPropertyKey: + return object->is(); case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: return object->is(); case ViewModelPropertyEnumCustomBase::enumIdPropertyKey: return object->is(); case ViewModelInstanceEnumBase::propertyValuePropertyKey: return object->is(); + case ViewModelInstanceArtboardBase::propertyValuePropertyKey: + return object->is(); case ViewModelPropertyEnumSystemBase::enumTypePropertyKey: return object->is(); case DataEnumSystemBase::enumTypePropertyKey: @@ -3824,10 +4830,10 @@ class CoreRegistry case ViewModelPropertyViewModelBase:: viewModelReferenceIdPropertyKey: return object->is(); - case ComponentBase::parentIdPropertyKey: - return object->is(); case ViewModelInstanceBase::viewModelIdPropertyKey: return object->is(); + case ViewModelInstanceListBase::listSourcePropertyKey: + return object->is(); case ViewModelInstanceTriggerBase::propertyValuePropertyKey: return object->is(); case ViewModelInstanceSymbolListIndexBase::propertyValuePropertyKey: @@ -3836,6 +4842,8 @@ class CoreRegistry return object->is(); case ViewModelInstanceAssetBase::propertyValuePropertyKey: return object->is(); + case CustomPropertyTriggerBase::propertyValuePropertyKey: + return object->is(); case DrawTargetBase::drawableIdPropertyKey: return object->is(); case DrawTargetBase::placementValuePropertyKey: @@ -3874,6 +4882,12 @@ class CoreRegistry return object->is(); case SoloBase::activeComponentIdPropertyKey: return object->is(); + case ScriptedDrawableBase::scriptAssetIdPropertyKey: + return object->is(); + case ScriptedDataConverterBase::scriptAssetIdPropertyKey: + return object->is(); + case ScriptedPathEffectBase::scriptAssetIdPropertyKey: + return object->is(); case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: return object->is(); case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: @@ -3968,10 +4982,28 @@ class CoreRegistry return object->is(); case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: return object->is(); + case ArtboardComponentListOverrideBase::artboardIdPropertyKey: + return object->is(); + case ArtboardComponentListOverrideBase:: + instanceWidthUnitsValuePropertyKey: + return object->is(); + case ArtboardComponentListOverrideBase:: + instanceHeightUnitsValuePropertyKey: + return object->is(); + case ArtboardComponentListOverrideBase:: + instanceWidthScaleTypePropertyKey: + return object->is(); + case ArtboardComponentListOverrideBase:: + instanceHeightScaleTypePropertyKey: + return object->is(); + case ListenerActionBase::flagsPropertyKey: + return object->is(); case ListenerFireEventBase::eventIdPropertyKey: return object->is(); case LayerStateBase::flagsPropertyKey: return object->is(); + case StateMachineFireActionBase::occursValuePropertyKey: + return object->is(); case TransitionValueTriggerComparatorBase::valuePropertyKey: return object->is(); case KeyFrameBase::framePropertyKey: @@ -3990,6 +5022,8 @@ class CoreRegistry return object->is(); case NestedInputBase::inputIdPropertyKey: return object->is(); + case ScriptedListenerActionBase::scriptAssetIdPropertyKey: + return object->is(); case KeyedObjectBase::objectIdPropertyKey: return object->is(); case BlendAnimationBase::animationIdPropertyKey: @@ -3998,16 +5032,16 @@ class CoreRegistry return object->is(); case BlendAnimationDirectBase::blendSourcePropertyKey: return object->is(); + case StateMachineListenerBase::targetIdPropertyKey: + return object->is(); + case StateMachineListenerSingleBase::listenerTypeValuePropertyKey: + return object->is(); + case StateMachineListenerSingleBase::eventIdPropertyKey: + return object->is(); case TransitionInputConditionBase::inputIdPropertyKey: return object->is(); case KeyedPropertyBase::propertyKeyPropertyKey: return object->is(); - case StateMachineListenerBase::targetIdPropertyKey: - return object->is(); - case StateMachineListenerBase::listenerTypeValuePropertyKey: - return object->is(); - case StateMachineListenerBase::eventIdPropertyKey: - return object->is(); case TransitionPropertyArtboardComparatorBase:: propertyTypePropertyKey: return object->is(); @@ -4017,12 +5051,18 @@ class CoreRegistry return object->is(); case ListenerAlignTargetBase::targetIdPropertyKey: return object->is(); + case ScriptedTransitionConditionBase::scriptAssetIdPropertyKey: + return object->is(); case TransitionValueConditionBase::opValuePropertyKey: return object->is(); case TransitionViewModelConditionBase::opValuePropertyKey: return object->is(); case BlendState1DInputBase::inputIdPropertyKey: return object->is(); + case FocusActionTargetBase::targetIdPropertyKey: + return object->is(); + case TransitionValueIdComparatorBase::valuePropertyKey: + return object->is(); case StateTransitionBase::stateToIdPropertyKey: return object->is(); case StateTransitionBase::flagsPropertyKey: @@ -4037,10 +5077,10 @@ class CoreRegistry return object->is(); case StateTransitionBase::randomWeightPropertyKey: return object->is(); + case FocusActionTraversalBase::traversalKindPropertyKey: + return object->is(); case StateMachineFireEventBase::eventIdPropertyKey: return object->is(); - case StateMachineFireEventBase::occursValuePropertyKey: - return object->is(); case LinearAnimationBase::fpsPropertyKey: return object->is(); case LinearAnimationBase::durationPropertyKey: @@ -4051,14 +5091,23 @@ class CoreRegistry return object->is(); case LinearAnimationBase::workEndPropertyKey: return object->is(); + case TransitionPropertyComponentComparatorBase::objectIdPropertyKey: + return object->is(); + case TransitionPropertyComponentComparatorBase:: + propertyKeyPropertyKey: + return object->is(); case ElasticInterpolatorBase::easingValuePropertyKey: return object->is(); - case TransitionValueEnumComparatorBase::valuePropertyKey: - return object->is(); + case ListenerInputTypeBase::listenerTypeValuePropertyKey: + return object->is(); + case ListenerInputTypeEventBase::eventIdPropertyKey: + return object->is(); case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: return object->is(); case ShapePaintBase::blendModeValuePropertyKey: return object->is(); + case TargetEffectBase::targetIdPropertyKey: + return object->is(); case StrokeBase::capPropertyKey: return object->is(); case StrokeBase::joinPropertyKey: @@ -4071,6 +5120,8 @@ class CoreRegistry return object->is(); case PathBase::pathFlagsPropertyKey: return object->is(); + case ListPathBase::listSourcePropertyKey: + return object->is(); case ClippingShapeBase::sourceIdPropertyKey: return object->is(); case ClippingShapeBase::fillRulePropertyKey: @@ -4079,6 +5130,10 @@ class CoreRegistry return object->is(); case ImageBase::assetIdPropertyKey: return object->is(); + case ImageBase::fitPropertyKey: + return object->is(); + case FocusDataBase::edgeBehaviorValuePropertyKey: + return object->is(); case DrawRulesBase::drawTargetIdPropertyKey: return object->is(); case LayoutComponentBase::styleIdPropertyKey: @@ -4097,6 +5152,16 @@ class CoreRegistry return object->is(); case OpenUrlEventBase::targetValuePropertyKey: return object->is(); + case SemanticDataBase::rolePropertyKey: + return object->is(); + case SemanticDataBase::headingLevelPropertyKey: + return object->is(); + case SemanticDataBase::traitFlagsPropertyKey: + return object->is(); + case SemanticDataBase::stateFlagsPropertyKey: + return object->is(); + case BindablePropertyIdBase::propertyValuePropertyKey: + return object->is(); case BindablePropertyIntegerBase::propertyValuePropertyKey: return object->is(); case DataBindBase::propertyKeyPropertyKey: @@ -4105,10 +5170,10 @@ class CoreRegistry return object->is(); case DataBindBase::converterIdPropertyKey: return object->is(); - case BindablePropertyAssetBase::propertyValuePropertyKey: - return object->is(); case DataConverterNumberToListBase::viewModelIdPropertyKey: return object->is(); + case DataConverterFormulaBase::randomModeValuePropertyKey: + return object->is(); case DataConverterOperationBase::operationTypePropertyKey: return object->is(); case DataConverterRangeMapperBase::interpolationTypePropertyKey: @@ -4139,6 +5204,8 @@ class CoreRegistry return object->is(); case DataConverterToStringBase::decimalsPropertyKey: return object->is(); + case BindablePropertyListBase::propertyValuePropertyKey: + return object->is(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->is(); case NestedArtboardLeafBase::fitPropertyKey: @@ -4191,26 +5258,38 @@ class CoreRegistry return object->is(); case TextBase::verticalAlignValuePropertyKey: return object->is(); + case TextBase::textRunListSourcePropertyKey: + return object->is(); case TextValueRunBase::styleIdPropertyKey: return object->is(); + case ArtboardListMapRuleBase::artboardIdPropertyKey: + return object->is(); + case ArtboardListMapRuleBase::viewModelIdPropertyKey: + return object->is(); + case CustomPropertyEnumBase::propertyValuePropertyKey: + return object->is(); + case CustomPropertyEnumBase::enumIdPropertyKey: + return object->is(); case FileAssetBase::assetIdPropertyKey: return object->is(); + case ScriptAssetBase::generatorFunctionRefPropertyKey: + return object->is(); case AudioEventBase::assetIdPropertyKey: return object->is(); - case ViewModelInstanceColorBase::propertyValuePropertyKey: - return object->is(); - case KeyFrameColorBase::valuePropertyKey: - return object->is(); - case TransitionValueColorComparatorBase::valuePropertyKey: - return object->is(); - case SolidColorBase::colorValuePropertyKey: - return object->is(); - case GradientStopBase::colorValuePropertyKey: - return object->is(); - case BindablePropertyColorBase::propertyValuePropertyKey: - return object->is(); + case KeyboardInputBase::keyTypePropertyKey: + return object->is(); + case KeyboardInputBase::keyPhasePropertyKey: + return object->is(); + case KeyboardInputBase::modifiersPropertyKey: + return object->is(); + case SemanticInputBase::actionTypePropertyKey: + return object->is(); + case ScriptInputArtboardBase::artboardIdPropertyKey: + return object->is(); case ViewModelComponentBase::namePropertyKey: return object->is(); + case ComponentBase::namePropertyKey: + return object->is(); case DataEnumCustomBase::namePropertyKey: return object->is(); case ViewModelInstanceStringBase::propertyValuePropertyKey: @@ -4219,8 +5298,8 @@ class CoreRegistry return object->is(); case DataEnumValueBase::valuePropertyKey: return object->is(); - case ComponentBase::namePropertyKey: - return object->is(); + case DataConverterBase::namePropertyKey: + return object->is(); case AnimationBase::namePropertyKey: return object->is(); case StateMachineComponentBase::namePropertyKey: @@ -4231,8 +5310,14 @@ class CoreRegistry return object->is(); case OpenUrlEventBase::urlPropertyKey: return object->is(); - case DataConverterBase::namePropertyKey: - return object->is(); + case SemanticDataBase::labelPropertyKey: + return object->is(); + case SemanticDataBase::valuePropertyKey: + return object->is(); + case SemanticDataBase::hintPropertyKey: + return object->is(); + case CustomPropertyStringBase::propertyValuePropertyKey: + return object->is(); case DataConverterStringPadBase::textPropertyKey: return object->is(); case DataConverterToStringBase::colorFormatPropertyKey: @@ -4243,14 +5328,32 @@ class CoreRegistry return object->is(); case TextValueRunBase::textPropertyKey: return object->is(); - case CustomPropertyStringBase::propertyValuePropertyKey: - return object->is(); case AssetBase::namePropertyKey: return object->is(); case FileAssetBase::cdnBaseUrlPropertyKey: return object->is(); + case TextAssetBase::folderPathPropertyKey: + return object->is(); + case ViewModelInstanceColorBase::propertyValuePropertyKey: + return object->is(); + case CustomPropertyColorBase::propertyValuePropertyKey: + return object->is(); + case KeyFrameColorBase::valuePropertyKey: + return object->is(); + case TransitionValueColorComparatorBase::valuePropertyKey: + return object->is(); + case SolidColorBase::colorValuePropertyKey: + return object->is(); + case GradientStopBase::colorValuePropertyKey: + return object->is(); + case BindablePropertyColorBase::propertyValuePropertyKey: + return object->is(); case ViewModelInstanceBooleanBase::propertyValuePropertyKey: return object->is(); + case FollowPathConstraintBase::orientPropertyKey: + return object->is(); + case FollowPathConstraintBase::offsetPropertyKey: + return object->is(); case TransformComponentConstraintBase::offsetPropertyKey: return object->is(); case TransformComponentConstraintBase::doesCopyPropertyKey: @@ -4267,14 +5370,18 @@ class CoreRegistry return object->is(); case IKConstraintBase::invertDirectionPropertyKey: return object->is(); - case FollowPathConstraintBase::orientPropertyKey: - return object->is(); - case FollowPathConstraintBase::offsetPropertyKey: - return object->is(); case ScrollConstraintBase::snapPropertyKey: return object->is(); + case ScrollConstraintBase::virtualizePropertyKey: + return object->is(); + case ScrollConstraintBase::infinitePropertyKey: + return object->is(); + case ScrollConstraintBase::interactivePropertyKey: + return object->is(); case ScrollBarConstraintBase::autoSizePropertyKey: return object->is(); + case NestedArtboardBase::isPausedPropertyKey: + return object->is(); case AxisBase::normalizedPropertyKey: return object->is(); case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: @@ -4309,16 +5416,68 @@ class CoreRegistry return object->is(); case PathBase::isHolePropertyKey: return object->is(); - case PointsPathBase::isClosedPropertyKey: - return object->is(); + case PointsCommonPathBase::isClosedPropertyKey: + return object->is(); case RectangleBase::linkCornerRadiusPropertyKey: return object->is(); case ClippingShapeBase::isVisiblePropertyKey: return object->is(); + case FocusDataBase::canFocusPropertyKey: + return object->is(); + case FocusDataBase::canTouchPropertyKey: + return object->is(); + case FocusDataBase::canTraversePropertyKey: + return object->is(); case CustomPropertyBooleanBase::propertyValuePropertyKey: return object->is(); case LayoutComponentBase::clipPropertyKey: return object->is(); + case ArtboardBase::isStatefulPropertyKey: + return object->is(); + case SemanticDataBase::isExpandablePropertyKey: + return object->is(); + case SemanticDataBase::isSelectablePropertyKey: + return object->is(); + case SemanticDataBase::isCheckablePropertyKey: + return object->is(); + case SemanticDataBase::isToggleablePropertyKey: + return object->is(); + case SemanticDataBase::isRequirablePropertyKey: + return object->is(); + case SemanticDataBase::isEnablablePropertyKey: + return object->is(); + case SemanticDataBase::isFocusablePropertyKey: + return object->is(); + case SemanticDataBase::isExpandedPropertyKey: + return object->is(); + case SemanticDataBase::isSelectedPropertyKey: + return object->is(); + case SemanticDataBase::isCheckedPropertyKey: + return object->is(); + case SemanticDataBase::isMixedPropertyKey: + return object->is(); + case SemanticDataBase::isToggledPropertyKey: + return object->is(); + case SemanticDataBase::isRequiredPropertyKey: + return object->is(); + case SemanticDataBase::isDisabledPropertyKey: + return object->is(); + case SemanticDataBase::isFocusedPropertyKey: + return object->is(); + case SemanticDataBase::isHiddenPropertyKey: + return object->is(); + case SemanticDataBase::isLiveRegionPropertyKey: + return object->is(); + case SemanticDataBase::isReadOnlyPropertyKey: + return object->is(); + case SemanticDataBase::isModalPropertyKey: + return object->is(); + case SemanticDataBase::isObscuredPropertyKey: + return object->is(); + case SemanticDataBase::isMultilinePropertyKey: + return object->is(); + case DataBindPathBase::isRelativePropertyKey: + return object->is(); case BindablePropertyBooleanBase::propertyValuePropertyKey: return object->is(); case TextModifierRangeBase::clampPropertyKey: @@ -4327,8 +5486,12 @@ class CoreRegistry return object->is(); case TextFollowPathModifierBase::orientPropertyKey: return object->is(); + case TextInputBase::multilinePropertyKey: + return object->is(); case TextBase::fitFromBaselinePropertyKey: return object->is(); + case ScriptAssetBase::isModulePropertyKey: + return object->is(); case ViewModelInstanceNumberBase::propertyValuePropertyKey: return object->is(); case CustomPropertyNumberBase::propertyValuePropertyKey: @@ -4337,6 +5500,12 @@ class CoreRegistry return object->is(); case DistanceConstraintBase::distancePropertyKey: return object->is(); + case FollowPathConstraintBase::distancePropertyKey: + return object->is(); + case ListFollowPathConstraintBase::distanceEndPropertyKey: + return object->is(); + case ListFollowPathConstraintBase::distanceOffsetPropertyKey: + return object->is(); case TransformComponentConstraintBase::copyFactorPropertyKey: return object->is(); case TransformComponentConstraintBase::minValuePropertyKey: @@ -4349,8 +5518,6 @@ class CoreRegistry return object->is(); case TransformComponentConstraintYBase::maxValueYPropertyKey: return object->is(); - case FollowPathConstraintBase::distancePropertyKey: - return object->is(); case ScrollConstraintBase::scrollOffsetXPropertyKey: return object->is(); case ScrollConstraintBase::scrollOffsetYPropertyKey: @@ -4361,6 +5528,8 @@ class CoreRegistry return object->is(); case ScrollConstraintBase::scrollIndexPropertyKey: return object->is(); + case ScrollConstraintBase::thresholdPropertyKey: + return object->is(); case ElasticScrollPhysicsBase::frictionPropertyKey: return object->is(); case ElasticScrollPhysicsBase::speedMultiplierPropertyKey: @@ -4393,10 +5562,18 @@ class CoreRegistry return object->is(); case NodeBase::computedWorldYPropertyKey: return object->is(); + case NodeBase::computedRootXPropertyKey: + return object->is(); + case NodeBase::computedRootYPropertyKey: + return object->is(); case NodeBase::computedWidthPropertyKey: return object->is(); case NodeBase::computedHeightPropertyKey: return object->is(); + case NestedArtboardBase::speedPropertyKey: + return object->is(); + case NestedArtboardBase::quantizePropertyKey: + return object->is(); case NestedArtboardLayoutBase::instanceWidthPropertyKey: return object->is(); case NestedArtboardLayoutBase::instanceHeightPropertyKey: @@ -4475,6 +5652,10 @@ class CoreRegistry return object->is(); case NSlicedNodeBase::heightPropertyKey: return object->is(); + case ArtboardComponentListOverrideBase::instanceWidthPropertyKey: + return object->is(); + case ArtboardComponentListOverrideBase::instanceHeightPropertyKey: + return object->is(); case NestedLinearAnimationBase::mixPropertyKey: return object->is(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -4597,6 +5778,10 @@ class CoreRegistry return object->is(); case ImageBase::originYPropertyKey: return object->is(); + case ImageBase::alignmentXPropertyKey: + return object->is(); + case ImageBase::alignmentYPropertyKey: + return object->is(); case CubicDetachedVertexBase::inRotationPropertyKey: return object->is(); case CubicDetachedVertexBase::inDistancePropertyKey: @@ -4747,6 +5932,8 @@ class CoreRegistry return object->is(); case ExportAudioBase::volumePropertyKey: return object->is(); + case CustomPropertyTriggerBase::firePropertyKey: + return object->is(); case NestedTriggerBase::firePropertyKey: return object->is(); case EventBase::triggerPropertyKey: diff --git a/thirdparty/rive/include/rive/generated/custom_property_color_base.hpp b/thirdparty/rive/include/rive/generated/custom_property_color_base.hpp new file mode 100644 index 000000000..c4858b686 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/custom_property_color_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_COLOR_BASE_HPP_ +#define _RIVE_CUSTOM_PROPERTY_COLOR_BASE_HPP_ +#include "rive/core/field_types/core_color_type.hpp" +#include "rive/custom_property.hpp" +namespace rive +{ +class CustomPropertyColorBase : public CustomProperty +{ +protected: + typedef CustomProperty Super; + +public: + static const uint16_t typeKey = 592; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case CustomPropertyColorBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 836; + +protected: + int m_PropertyValue = 0xFF1D1D1D; + +public: + inline int propertyValue() const { return m_PropertyValue; } + void propertyValue(int value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const CustomPropertyColorBase& object) + { + m_PropertyValue = object.m_PropertyValue; + CustomProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreColorType::deserialize(reader); + return true; + } + return CustomProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/custom_property_enum_base.hpp b/thirdparty/rive/include/rive/generated/custom_property_enum_base.hpp new file mode 100644 index 000000000..611471520 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/custom_property_enum_base.hpp @@ -0,0 +1,90 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_ENUM_BASE_HPP_ +#define _RIVE_CUSTOM_PROPERTY_ENUM_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/custom_property.hpp" +namespace rive +{ +class CustomPropertyEnumBase : public CustomProperty +{ +protected: + typedef CustomProperty Super; + +public: + static const uint16_t typeKey = 616; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case CustomPropertyEnumBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 872; + static const uint16_t enumIdPropertyKey = 873; + +protected: + uint32_t m_PropertyValue = -1; + uint32_t m_EnumId = -1; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + inline uint32_t enumId() const { return m_EnumId; } + void enumId(uint32_t value) + { + if (m_EnumId == value) + { + return; + } + m_EnumId = value; + enumIdChanged(); + } + + Core* clone() const override; + void copy(const CustomPropertyEnumBase& object) + { + m_PropertyValue = object.m_PropertyValue; + m_EnumId = object.m_EnumId; + CustomProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + case enumIdPropertyKey: + m_EnumId = CoreUintType::deserialize(reader); + return true; + } + return CustomProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} + virtual void enumIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/custom_property_trigger_base.hpp b/thirdparty/rive/include/rive/generated/custom_property_trigger_base.hpp new file mode 100644 index 000000000..21e588b6b --- /dev/null +++ b/thirdparty/rive/include/rive/generated/custom_property_trigger_base.hpp @@ -0,0 +1,76 @@ +#ifndef _RIVE_CUSTOM_PROPERTY_TRIGGER_BASE_HPP_ +#define _RIVE_CUSTOM_PROPERTY_TRIGGER_BASE_HPP_ +#include "rive/core/field_types/core_callback_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/custom_property.hpp" +namespace rive +{ +class CustomPropertyTriggerBase : public CustomProperty +{ +protected: + typedef CustomProperty Super; + +public: + static const uint16_t typeKey = 613; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case CustomPropertyTriggerBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t firePropertyKey = 869; + static const uint16_t propertyValuePropertyKey = 870; + +protected: + uint32_t m_PropertyValue = 0; + +public: + virtual void fire(const CallbackData& value) = 0; + + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const CustomPropertyTriggerBase& object) + { + m_PropertyValue = object.m_PropertyValue; + CustomProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return CustomProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/bindable_property_artboard_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_artboard_base.hpp new file mode 100644 index 000000000..2013e776e --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_artboard_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_ARTBOARD_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_ARTBOARD_BASE_HPP_ +#include "rive/data_bind/bindable_property_id.hpp" +namespace rive +{ +class BindablePropertyArtboardBase : public BindablePropertyId +{ +protected: + typedef BindablePropertyId Super; + +public: + static const uint16_t typeKey = 597; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyArtboardBase::typeKey: + case BindablePropertyIdBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/bindable_property_asset_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_asset_base.hpp index 8608b46c9..ee557a615 100644 --- a/thirdparty/rive/include/rive/generated/data_bind/bindable_property_asset_base.hpp +++ b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_asset_base.hpp @@ -1,13 +1,12 @@ #ifndef _RIVE_BINDABLE_PROPERTY_ASSET_BASE_HPP_ #define _RIVE_BINDABLE_PROPERTY_ASSET_BASE_HPP_ -#include "rive/core/field_types/core_uint_type.hpp" -#include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_id.hpp" namespace rive { -class BindablePropertyAssetBase : public BindableProperty +class BindablePropertyAssetBase : public BindablePropertyId { protected: - typedef BindableProperty Super; + typedef BindablePropertyId Super; public: static const uint16_t typeKey = 588; @@ -19,6 +18,7 @@ class BindablePropertyAssetBase : public BindableProperty switch (typeKey) { case BindablePropertyAssetBase::typeKey: + case BindablePropertyIdBase::typeKey: case BindablePropertyBase::typeKey: return true; default: @@ -28,43 +28,9 @@ class BindablePropertyAssetBase : public BindableProperty uint16_t coreType() const override { return typeKey; } - static const uint16_t propertyValuePropertyKey = 823; - -protected: - uint32_t m_PropertyValue = -1; - -public: - inline uint32_t propertyValue() const { return m_PropertyValue; } - void propertyValue(uint32_t value) - { - if (m_PropertyValue == value) - { - return; - } - m_PropertyValue = value; - propertyValueChanged(); - } - Core* clone() const override; - void copy(const BindablePropertyAssetBase& object) - { - m_PropertyValue = object.m_PropertyValue; - BindableProperty::copy(object); - } - - bool deserialize(uint16_t propertyKey, BinaryReader& reader) override - { - switch (propertyKey) - { - case propertyValuePropertyKey: - m_PropertyValue = CoreUintType::deserialize(reader); - return true; - } - return BindableProperty::deserialize(propertyKey, reader); - } protected: - virtual void propertyValueChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/data_bind/bindable_property_id_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_id_base.hpp new file mode 100644 index 000000000..d529b7ed1 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_id_base.hpp @@ -0,0 +1,70 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_ID_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_ID_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyIdBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 596; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyIdBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 823; + +protected: + uint32_t m_PropertyValue = -1; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + void copy(const BindablePropertyIdBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/bindable_property_list_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_list_base.hpp new file mode 100644 index 000000000..61dc332c2 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_list_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_LIST_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_LIST_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyListBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 590; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyListBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 835; + +protected: + uint32_t m_PropertyValue = -1; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const BindablePropertyListBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/bindable_property_viewmodel_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_viewmodel_base.hpp new file mode 100644 index 000000000..187934289 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/bindable_property_viewmodel_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_VIEW_MODEL_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_VIEW_MODEL_BASE_HPP_ +#include "rive/data_bind/bindable_property_id.hpp" +namespace rive +{ +class BindablePropertyViewModelBase : public BindablePropertyId +{ +protected: + typedef BindablePropertyId Super; + +public: + static const uint16_t typeKey = 662; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyViewModelBase::typeKey: + case BindablePropertyIdBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_formula_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_formula_base.hpp index b453420e4..dc7a1ddb1 100644 --- a/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_formula_base.hpp +++ b/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_formula_base.hpp @@ -1,5 +1,6 @@ #ifndef _RIVE_DATA_CONVERTER_FORMULA_BASE_HPP_ #define _RIVE_DATA_CONVERTER_FORMULA_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" #include "rive/data_bind/converters/data_converter.hpp" namespace rive { @@ -27,9 +28,43 @@ class DataConverterFormulaBase : public DataConverter uint16_t coreType() const override { return typeKey; } + static const uint16_t randomModeValuePropertyKey = 887; + +protected: + uint32_t m_RandomModeValue = 0; + +public: + inline uint32_t randomModeValue() const { return m_RandomModeValue; } + void randomModeValue(uint32_t value) + { + if (m_RandomModeValue == value) + { + return; + } + m_RandomModeValue = value; + randomModeValueChanged(); + } + Core* clone() const override; + void copy(const DataConverterFormulaBase& object) + { + m_RandomModeValue = object.m_RandomModeValue; + DataConverter::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case randomModeValuePropertyKey: + m_RandomModeValue = CoreUintType::deserialize(reader); + return true; + } + return DataConverter::deserialize(propertyKey, reader); + } protected: + virtual void randomModeValueChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_list_to_length_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_list_to_length_base.hpp new file mode 100644 index 000000000..d89770bb1 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_list_to_length_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_DATA_CONVERTER_LIST_TO_LENGTH_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_LIST_TO_LENGTH_BASE_HPP_ +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class DataConverterListToLengthBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 591; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterListToLengthBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_to_number_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_to_number_base.hpp new file mode 100644 index 000000000..5190098ae --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/converters/data_converter_to_number_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_DATA_CONVERTER_TO_NUMBER_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_TO_NUMBER_BASE_HPP_ +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class DataConverterToNumberBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 617; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterToNumberBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/data_bind/data_bind_path_base.hpp b/thirdparty/rive/include/rive/generated/data_bind/data_bind_path_base.hpp new file mode 100644 index 000000000..03627df3a --- /dev/null +++ b/thirdparty/rive/include/rive/generated/data_bind/data_bind_path_base.hpp @@ -0,0 +1,80 @@ +#ifndef _RIVE_DATA_BIND_PATH_BASE_HPP_ +#define _RIVE_DATA_BIND_PATH_BASE_HPP_ +#include "rive/core.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/span.hpp" +namespace rive +{ +class DataBindPathBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 643; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataBindPathBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t pathPropertyKey = 920; + static const uint16_t isRelativePropertyKey = 921; + +protected: + bool m_IsRelative = false; + +public: + virtual void decodePath(Span value) = 0; + virtual void copyPath(const DataBindPathBase& object) = 0; + + inline bool isRelative() const { return m_IsRelative; } + void isRelative(bool value) + { + if (m_IsRelative == value) + { + return; + } + m_IsRelative = value; + isRelativeChanged(); + } + + Core* clone() const override; + void copy(const DataBindPathBase& object) + { + copyPath(object); + m_IsRelative = object.m_IsRelative; + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case pathPropertyKey: + decodePath(CoreBytesType::deserialize(reader)); + return true; + case isRelativePropertyKey: + m_IsRelative = CoreBoolType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void pathChanged() {} + virtual void isRelativeChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/focus_data_base.hpp b/thirdparty/rive/include/rive/generated/focus_data_base.hpp new file mode 100644 index 000000000..710dd373f --- /dev/null +++ b/thirdparty/rive/include/rive/generated/focus_data_base.hpp @@ -0,0 +1,126 @@ +#ifndef _RIVE_FOCUS_DATA_BASE_HPP_ +#define _RIVE_FOCUS_DATA_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class FocusDataBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 653; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case FocusDataBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t canFocusPropertyKey = 953; + static const uint16_t canTouchPropertyKey = 954; + static const uint16_t canTraversePropertyKey = 955; + static const uint16_t edgeBehaviorValuePropertyKey = 956; + +protected: + bool m_CanFocus = true; + bool m_CanTouch = true; + bool m_CanTraverse = true; + uint32_t m_EdgeBehaviorValue = 0; + +public: + inline bool canFocus() const { return m_CanFocus; } + void canFocus(bool value) + { + if (m_CanFocus == value) + { + return; + } + m_CanFocus = value; + canFocusChanged(); + } + + inline bool canTouch() const { return m_CanTouch; } + void canTouch(bool value) + { + if (m_CanTouch == value) + { + return; + } + m_CanTouch = value; + canTouchChanged(); + } + + inline bool canTraverse() const { return m_CanTraverse; } + void canTraverse(bool value) + { + if (m_CanTraverse == value) + { + return; + } + m_CanTraverse = value; + canTraverseChanged(); + } + + inline uint32_t edgeBehaviorValue() const { return m_EdgeBehaviorValue; } + void edgeBehaviorValue(uint32_t value) + { + if (m_EdgeBehaviorValue == value) + { + return; + } + m_EdgeBehaviorValue = value; + edgeBehaviorValueChanged(); + } + + Core* clone() const override; + void copy(const FocusDataBase& object) + { + m_CanFocus = object.m_CanFocus; + m_CanTouch = object.m_CanTouch; + m_CanTraverse = object.m_CanTraverse; + m_EdgeBehaviorValue = object.m_EdgeBehaviorValue; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case canFocusPropertyKey: + m_CanFocus = CoreBoolType::deserialize(reader); + return true; + case canTouchPropertyKey: + m_CanTouch = CoreBoolType::deserialize(reader); + return true; + case canTraversePropertyKey: + m_CanTraverse = CoreBoolType::deserialize(reader); + return true; + case edgeBehaviorValuePropertyKey: + m_EdgeBehaviorValue = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void canFocusChanged() {} + virtual void canTouchChanged() {} + virtual void canTraverseChanged() {} + virtual void edgeBehaviorValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/inputs/keyboard_input_base.hpp b/thirdparty/rive/include/rive/generated/inputs/keyboard_input_base.hpp new file mode 100644 index 000000000..5163da316 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/inputs/keyboard_input_base.hpp @@ -0,0 +1,107 @@ +#ifndef _RIVE_KEYBOARD_INPUT_BASE_HPP_ +#define _RIVE_KEYBOARD_INPUT_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/inputs/user_input.hpp" +namespace rive +{ +class KeyboardInputBase : public UserInput +{ +protected: + typedef UserInput Super; + +public: + static const uint16_t typeKey = 664; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case KeyboardInputBase::typeKey: + case UserInputBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t keyTypePropertyKey = 971; + static const uint16_t keyPhasePropertyKey = 972; + static const uint16_t modifiersPropertyKey = 973; + +protected: + uint32_t m_KeyType = -1; + uint32_t m_KeyPhase = 0; + uint32_t m_Modifiers = 0; + +public: + inline uint32_t keyType() const { return m_KeyType; } + void keyType(uint32_t value) + { + if (m_KeyType == value) + { + return; + } + m_KeyType = value; + keyTypeChanged(); + } + + inline uint32_t keyPhase() const { return m_KeyPhase; } + void keyPhase(uint32_t value) + { + if (m_KeyPhase == value) + { + return; + } + m_KeyPhase = value; + keyPhaseChanged(); + } + + inline uint32_t modifiers() const { return m_Modifiers; } + void modifiers(uint32_t value) + { + if (m_Modifiers == value) + { + return; + } + m_Modifiers = value; + modifiersChanged(); + } + + Core* clone() const override; + void copy(const KeyboardInputBase& object) + { + m_KeyType = object.m_KeyType; + m_KeyPhase = object.m_KeyPhase; + m_Modifiers = object.m_Modifiers; + UserInput::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case keyTypePropertyKey: + m_KeyType = CoreUintType::deserialize(reader); + return true; + case keyPhasePropertyKey: + m_KeyPhase = CoreUintType::deserialize(reader); + return true; + case modifiersPropertyKey: + m_Modifiers = CoreUintType::deserialize(reader); + return true; + } + return UserInput::deserialize(propertyKey, reader); + } + +protected: + virtual void keyTypeChanged() {} + virtual void keyPhaseChanged() {} + virtual void modifiersChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/inputs/semantic_input_base.hpp b/thirdparty/rive/include/rive/generated/inputs/semantic_input_base.hpp new file mode 100644 index 000000000..74fac3801 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/inputs/semantic_input_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_SEMANTIC_INPUT_BASE_HPP_ +#define _RIVE_SEMANTIC_INPUT_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/inputs/user_input.hpp" + +#include +namespace rive +{ +class SemanticInputBase : public UserInput +{ +protected: + typedef UserInput Super; + +public: + static const uint16_t typeKey = 670; + + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case SemanticInputBase::typeKey: + case UserInputBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t actionTypePropertyKey = 1010; + +protected: + uint32_t m_ActionType = 0; + +public: + inline uint32_t actionType() const { return m_ActionType; } + void actionType(uint32_t value) + { + if (m_ActionType == value) + { + return; + } + m_ActionType = value; + actionTypeChanged(); + } + + Core* clone() const override; + void copy(const SemanticInputBase& object) + { + m_ActionType = object.m_ActionType; + UserInput::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case actionTypePropertyKey: + m_ActionType = CoreUintType::deserialize(reader); + return true; + } + return UserInput::deserialize(propertyKey, reader); + } + +protected: + virtual void actionTypeChanged() {} +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/generated/inputs/user_input_base.hpp b/thirdparty/rive/include/rive/generated/inputs/user_input_base.hpp new file mode 100644 index 000000000..fe57b33ae --- /dev/null +++ b/thirdparty/rive/include/rive/generated/inputs/user_input_base.hpp @@ -0,0 +1,41 @@ +#ifndef _RIVE_USER_INPUT_BASE_HPP_ +#define _RIVE_USER_INPUT_BASE_HPP_ +#include "rive/core.hpp" +namespace rive +{ +class UserInputBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 663; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case UserInputBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + void copy(const UserInputBase& object) {} + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + return false; + } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/layout/artboard_component_list_override_base.hpp b/thirdparty/rive/include/rive/generated/layout/artboard_component_list_override_base.hpp new file mode 100644 index 000000000..0a5260209 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/layout/artboard_component_list_override_base.hpp @@ -0,0 +1,192 @@ +#ifndef _RIVE_ARTBOARD_COMPONENT_LIST_OVERRIDE_BASE_HPP_ +#define _RIVE_ARTBOARD_COMPONENT_LIST_OVERRIDE_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ArtboardComponentListOverrideBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 606; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ArtboardComponentListOverrideBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t artboardIdPropertyKey = 858; + static const uint16_t instanceWidthPropertyKey = 859; + static const uint16_t instanceHeightPropertyKey = 860; + static const uint16_t instanceWidthUnitsValuePropertyKey = 856; + static const uint16_t instanceHeightUnitsValuePropertyKey = 861; + static const uint16_t instanceWidthScaleTypePropertyKey = 862; + static const uint16_t instanceHeightScaleTypePropertyKey = 863; + +protected: + uint32_t m_ArtboardId = -1; + float m_InstanceWidth = -1.0f; + float m_InstanceHeight = -1.0f; + uint32_t m_InstanceWidthUnitsValue = 1; + uint32_t m_InstanceHeightUnitsValue = 1; + uint32_t m_InstanceWidthScaleType = 0; + uint32_t m_InstanceHeightScaleType = 0; + +public: + inline uint32_t artboardId() const { return m_ArtboardId; } + void artboardId(uint32_t value) + { + if (m_ArtboardId == value) + { + return; + } + m_ArtboardId = value; + artboardIdChanged(); + } + + inline float instanceWidth() const { return m_InstanceWidth; } + void instanceWidth(float value) + { + if (m_InstanceWidth == value) + { + return; + } + m_InstanceWidth = value; + instanceWidthChanged(); + } + + inline float instanceHeight() const { return m_InstanceHeight; } + void instanceHeight(float value) + { + if (m_InstanceHeight == value) + { + return; + } + m_InstanceHeight = value; + instanceHeightChanged(); + } + + inline uint32_t instanceWidthUnitsValue() const + { + return m_InstanceWidthUnitsValue; + } + void instanceWidthUnitsValue(uint32_t value) + { + if (m_InstanceWidthUnitsValue == value) + { + return; + } + m_InstanceWidthUnitsValue = value; + instanceWidthUnitsValueChanged(); + } + + inline uint32_t instanceHeightUnitsValue() const + { + return m_InstanceHeightUnitsValue; + } + void instanceHeightUnitsValue(uint32_t value) + { + if (m_InstanceHeightUnitsValue == value) + { + return; + } + m_InstanceHeightUnitsValue = value; + instanceHeightUnitsValueChanged(); + } + + inline uint32_t instanceWidthScaleType() const + { + return m_InstanceWidthScaleType; + } + void instanceWidthScaleType(uint32_t value) + { + if (m_InstanceWidthScaleType == value) + { + return; + } + m_InstanceWidthScaleType = value; + instanceWidthScaleTypeChanged(); + } + + inline uint32_t instanceHeightScaleType() const + { + return m_InstanceHeightScaleType; + } + void instanceHeightScaleType(uint32_t value) + { + if (m_InstanceHeightScaleType == value) + { + return; + } + m_InstanceHeightScaleType = value; + instanceHeightScaleTypeChanged(); + } + + Core* clone() const override; + void copy(const ArtboardComponentListOverrideBase& object) + { + m_ArtboardId = object.m_ArtboardId; + m_InstanceWidth = object.m_InstanceWidth; + m_InstanceHeight = object.m_InstanceHeight; + m_InstanceWidthUnitsValue = object.m_InstanceWidthUnitsValue; + m_InstanceHeightUnitsValue = object.m_InstanceHeightUnitsValue; + m_InstanceWidthScaleType = object.m_InstanceWidthScaleType; + m_InstanceHeightScaleType = object.m_InstanceHeightScaleType; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case artboardIdPropertyKey: + m_ArtboardId = CoreUintType::deserialize(reader); + return true; + case instanceWidthPropertyKey: + m_InstanceWidth = CoreDoubleType::deserialize(reader); + return true; + case instanceHeightPropertyKey: + m_InstanceHeight = CoreDoubleType::deserialize(reader); + return true; + case instanceWidthUnitsValuePropertyKey: + m_InstanceWidthUnitsValue = CoreUintType::deserialize(reader); + return true; + case instanceHeightUnitsValuePropertyKey: + m_InstanceHeightUnitsValue = CoreUintType::deserialize(reader); + return true; + case instanceWidthScaleTypePropertyKey: + m_InstanceWidthScaleType = CoreUintType::deserialize(reader); + return true; + case instanceHeightScaleTypePropertyKey: + m_InstanceHeightScaleType = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void artboardIdChanged() {} + virtual void instanceWidthChanged() {} + virtual void instanceHeightChanged() {} + virtual void instanceWidthUnitsValueChanged() {} + virtual void instanceHeightUnitsValueChanged() {} + virtual void instanceWidthScaleTypeChanged() {} + virtual void instanceHeightScaleTypeChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/nested_artboard_base.hpp b/thirdparty/rive/include/rive/generated/nested_artboard_base.hpp index 4b37dd824..eb9fb8c66 100644 --- a/thirdparty/rive/include/rive/generated/nested_artboard_base.hpp +++ b/thirdparty/rive/include/rive/generated/nested_artboard_base.hpp @@ -1,6 +1,8 @@ #ifndef _RIVE_NESTED_ARTBOARD_BASE_HPP_ #define _RIVE_NESTED_ARTBOARD_BASE_HPP_ +#include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" #include "rive/drawable.hpp" #include "rive/span.hpp" @@ -37,9 +39,15 @@ class NestedArtboardBase : public Drawable static const uint16_t artboardIdPropertyKey = 197; static const uint16_t dataBindPathIdsPropertyKey = 582; + static const uint16_t isPausedPropertyKey = 895; + static const uint16_t speedPropertyKey = 907; + static const uint16_t quantizePropertyKey = 908; protected: uint32_t m_ArtboardId = -1; + bool m_IsPaused = false; + float m_Speed = 1.0f; + float m_Quantize = -1.0f; public: inline uint32_t artboardId() const { return m_ArtboardId; } @@ -56,11 +64,47 @@ class NestedArtboardBase : public Drawable virtual void decodeDataBindPathIds(Span value) = 0; virtual void copyDataBindPathIds(const NestedArtboardBase& object) = 0; + inline bool isPaused() const { return m_IsPaused; } + void isPaused(bool value) + { + if (m_IsPaused == value) + { + return; + } + m_IsPaused = value; + isPausedChanged(); + } + + inline float speed() const { return m_Speed; } + void speed(float value) + { + if (m_Speed == value) + { + return; + } + m_Speed = value; + speedChanged(); + } + + inline float quantize() const { return m_Quantize; } + void quantize(float value) + { + if (m_Quantize == value) + { + return; + } + m_Quantize = value; + quantizeChanged(); + } + Core* clone() const override; void copy(const NestedArtboardBase& object) { m_ArtboardId = object.m_ArtboardId; copyDataBindPathIds(object); + m_IsPaused = object.m_IsPaused; + m_Speed = object.m_Speed; + m_Quantize = object.m_Quantize; Drawable::copy(object); } @@ -74,6 +118,15 @@ class NestedArtboardBase : public Drawable case dataBindPathIdsPropertyKey: decodeDataBindPathIds(CoreBytesType::deserialize(reader)); return true; + case isPausedPropertyKey: + m_IsPaused = CoreBoolType::deserialize(reader); + return true; + case speedPropertyKey: + m_Speed = CoreDoubleType::deserialize(reader); + return true; + case quantizePropertyKey: + m_Quantize = CoreDoubleType::deserialize(reader); + return true; } return Drawable::deserialize(propertyKey, reader); } @@ -81,6 +134,9 @@ class NestedArtboardBase : public Drawable protected: virtual void artboardIdChanged() {} virtual void dataBindPathIdsChanged() {} + virtual void isPausedChanged() {} + virtual void speedChanged() {} + virtual void quantizeChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/node_base.hpp b/thirdparty/rive/include/rive/generated/node_base.hpp index 64db1cee9..df09e0c80 100644 --- a/thirdparty/rive/include/rive/generated/node_base.hpp +++ b/thirdparty/rive/include/rive/generated/node_base.hpp @@ -39,6 +39,8 @@ class NodeBase : public TransformComponent static const uint16_t computedLocalYPropertyKey = 807; static const uint16_t computedWorldXPropertyKey = 808; static const uint16_t computedWorldYPropertyKey = 809; + static const uint16_t computedRootXPropertyKey = 864; + static const uint16_t computedRootYPropertyKey = 865; static const uint16_t computedWidthPropertyKey = 810; static const uint16_t computedHeightPropertyKey = 811; @@ -117,6 +119,30 @@ class NodeBase : public TransformComponent computedWorldYChanged(); } + virtual void setComputedRootX(float value) = 0; + virtual float computedRootX() = 0; + void computedRootX(float value) + { + if (computedRootX() == value) + { + return; + } + setComputedRootX(value); + computedRootXChanged(); + } + + virtual void setComputedRootY(float value) = 0; + virtual float computedRootY() = 0; + void computedRootY(float value) + { + if (computedRootY() == value) + { + return; + } + setComputedRootY(value); + computedRootYChanged(); + } + virtual void setComputedWidth(float value) = 0; virtual float computedWidth() = 0; void computedWidth(float value) @@ -170,6 +196,8 @@ class NodeBase : public TransformComponent virtual void computedLocalYChanged() {} virtual void computedWorldXChanged() {} virtual void computedWorldYChanged() {} + virtual void computedRootXChanged() {} + virtual void computedRootYChanged() {} virtual void computedWidthChanged() {} virtual void computedHeightChanged() {} }; diff --git a/thirdparty/rive/include/rive/generated/script_input_artboard_base.hpp b/thirdparty/rive/include/rive/generated/script_input_artboard_base.hpp new file mode 100644 index 000000000..1482b563d --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_artboard_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_SCRIPT_INPUT_ARTBOARD_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_ARTBOARD_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/custom_property.hpp" +namespace rive +{ +class ScriptInputArtboardBase : public CustomProperty +{ +protected: + typedef CustomProperty Super; + +public: + static const uint16_t typeKey = 621; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputArtboardBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t artboardIdPropertyKey = 876; + +protected: + uint32_t m_ArtboardId = -1; + +public: + inline uint32_t artboardId() const { return m_ArtboardId; } + void artboardId(uint32_t value) + { + if (m_ArtboardId == value) + { + return; + } + m_ArtboardId = value; + artboardIdChanged(); + } + + Core* clone() const override; + void copy(const ScriptInputArtboardBase& object) + { + m_ArtboardId = object.m_ArtboardId; + CustomProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case artboardIdPropertyKey: + m_ArtboardId = CoreUintType::deserialize(reader); + return true; + } + return CustomProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void artboardIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/script_input_boolean_base.hpp b/thirdparty/rive/include/rive/generated/script_input_boolean_base.hpp new file mode 100644 index 000000000..e350391e7 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_boolean_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_SCRIPT_INPUT_BOOLEAN_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_BOOLEAN_BASE_HPP_ +#include "rive/custom_property_boolean.hpp" +namespace rive +{ +class ScriptInputBooleanBase : public CustomPropertyBoolean +{ +protected: + typedef CustomPropertyBoolean Super; + +public: + static const uint16_t typeKey = 631; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputBooleanBase::typeKey: + case CustomPropertyBooleanBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/script_input_color_base.hpp b/thirdparty/rive/include/rive/generated/script_input_color_base.hpp new file mode 100644 index 000000000..e776eec01 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_color_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_SCRIPT_INPUT_COLOR_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_COLOR_BASE_HPP_ +#include "rive/custom_property_color.hpp" +namespace rive +{ +class ScriptInputColorBase : public CustomPropertyColor +{ +protected: + typedef CustomPropertyColor Super; + +public: + static const uint16_t typeKey = 626; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputColorBase::typeKey: + case CustomPropertyColorBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/script_input_number_base.hpp b/thirdparty/rive/include/rive/generated/script_input_number_base.hpp new file mode 100644 index 000000000..72b0f684b --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_number_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_SCRIPT_INPUT_NUMBER_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_NUMBER_BASE_HPP_ +#include "rive/custom_property_number.hpp" +namespace rive +{ +class ScriptInputNumberBase : public CustomPropertyNumber +{ +protected: + typedef CustomPropertyNumber Super; + +public: + static const uint16_t typeKey = 611; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputNumberBase::typeKey: + case CustomPropertyNumberBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/script_input_string_base.hpp b/thirdparty/rive/include/rive/generated/script_input_string_base.hpp new file mode 100644 index 000000000..36492a238 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_string_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_SCRIPT_INPUT_STRING_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_STRING_BASE_HPP_ +#include "rive/custom_property_string.hpp" +namespace rive +{ +class ScriptInputStringBase : public CustomPropertyString +{ +protected: + typedef CustomPropertyString Super; + +public: + static const uint16_t typeKey = 627; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputStringBase::typeKey: + case CustomPropertyStringBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/script_input_trigger_base.hpp b/thirdparty/rive/include/rive/generated/script_input_trigger_base.hpp new file mode 100644 index 000000000..49f7de4a2 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_trigger_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_SCRIPT_INPUT_TRIGGER_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_TRIGGER_BASE_HPP_ +#include "rive/custom_property_trigger.hpp" +namespace rive +{ +class ScriptInputTriggerBase : public CustomPropertyTrigger +{ +protected: + typedef CustomPropertyTrigger Super; + +public: + static const uint16_t typeKey = 618; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputTriggerBase::typeKey: + case CustomPropertyTriggerBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/script_input_viewmodel_property_base.hpp b/thirdparty/rive/include/rive/generated/script_input_viewmodel_property_base.hpp new file mode 100644 index 000000000..e0f721492 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/script_input_viewmodel_property_base.hpp @@ -0,0 +1,63 @@ +#ifndef _RIVE_SCRIPT_INPUT_VIEW_MODEL_PROPERTY_BASE_HPP_ +#define _RIVE_SCRIPT_INPUT_VIEW_MODEL_PROPERTY_BASE_HPP_ +#include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/custom_property.hpp" +#include "rive/span.hpp" +namespace rive +{ +class ScriptInputViewModelPropertyBase : public CustomProperty +{ +protected: + typedef CustomProperty Super; + +public: + static const uint16_t typeKey = 612; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptInputViewModelPropertyBase::typeKey: + case CustomPropertyBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t dataBindPathIdsPropertyKey = 866; + +public: + virtual void decodeDataBindPathIds(Span value) = 0; + virtual void copyDataBindPathIds( + const ScriptInputViewModelPropertyBase& object) = 0; + + Core* clone() const override; + void copy(const ScriptInputViewModelPropertyBase& object) + { + copyDataBindPathIds(object); + CustomProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case dataBindPathIdsPropertyKey: + decodeDataBindPathIds(CoreBytesType::deserialize(reader)); + return true; + } + return CustomProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void dataBindPathIdsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/scripted/scripted_data_converter_base.hpp b/thirdparty/rive/include/rive/generated/scripted/scripted_data_converter_base.hpp new file mode 100644 index 000000000..2b81818d5 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/scripted/scripted_data_converter_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_SCRIPTED_DATA_CONVERTER_BASE_HPP_ +#define _RIVE_SCRIPTED_DATA_CONVERTER_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class ScriptedDataConverterBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 629; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptedDataConverterBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t scriptAssetIdPropertyKey = 892; + +protected: + uint32_t m_ScriptAssetId = -1; + +public: + inline uint32_t scriptAssetId() const { return m_ScriptAssetId; } + void scriptAssetId(uint32_t value) + { + if (m_ScriptAssetId == value) + { + return; + } + m_ScriptAssetId = value; + scriptAssetIdChanged(); + } + + Core* clone() const override; + void copy(const ScriptedDataConverterBase& object) + { + m_ScriptAssetId = object.m_ScriptAssetId; + DataConverter::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case scriptAssetIdPropertyKey: + m_ScriptAssetId = CoreUintType::deserialize(reader); + return true; + } + return DataConverter::deserialize(propertyKey, reader); + } + +protected: + virtual void scriptAssetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/scripted/scripted_drawable_base.hpp b/thirdparty/rive/include/rive/generated/scripted/scripted_drawable_base.hpp new file mode 100644 index 000000000..aca02638a --- /dev/null +++ b/thirdparty/rive/include/rive/generated/scripted/scripted_drawable_base.hpp @@ -0,0 +1,76 @@ +#ifndef _RIVE_SCRIPTED_DRAWABLE_BASE_HPP_ +#define _RIVE_SCRIPTED_DRAWABLE_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/drawable.hpp" +namespace rive +{ +class ScriptedDrawableBase : public Drawable +{ +protected: + typedef Drawable Super; + +public: + static const uint16_t typeKey = 603; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptedDrawableBase::typeKey: + case DrawableBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t scriptAssetIdPropertyKey = 848; + +protected: + uint32_t m_ScriptAssetId = -1; + +public: + inline uint32_t scriptAssetId() const { return m_ScriptAssetId; } + void scriptAssetId(uint32_t value) + { + if (m_ScriptAssetId == value) + { + return; + } + m_ScriptAssetId = value; + scriptAssetIdChanged(); + } + + Core* clone() const override; + void copy(const ScriptedDrawableBase& object) + { + m_ScriptAssetId = object.m_ScriptAssetId; + Drawable::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case scriptAssetIdPropertyKey: + m_ScriptAssetId = CoreUintType::deserialize(reader); + return true; + } + return Drawable::deserialize(propertyKey, reader); + } + +protected: + virtual void scriptAssetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/scripted/scripted_layout_base.hpp b/thirdparty/rive/include/rive/generated/scripted/scripted_layout_base.hpp new file mode 100644 index 000000000..f4a8a904b --- /dev/null +++ b/thirdparty/rive/include/rive/generated/scripted/scripted_layout_base.hpp @@ -0,0 +1,42 @@ +#ifndef _RIVE_SCRIPTED_LAYOUT_BASE_HPP_ +#define _RIVE_SCRIPTED_LAYOUT_BASE_HPP_ +#include "rive/scripted/scripted_drawable.hpp" +namespace rive +{ +class ScriptedLayoutBase : public ScriptedDrawable +{ +protected: + typedef ScriptedDrawable Super; + +public: + static const uint16_t typeKey = 637; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptedLayoutBase::typeKey: + case ScriptedDrawableBase::typeKey: + case DrawableBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/scripted/scripted_path_effect_base.hpp b/thirdparty/rive/include/rive/generated/scripted/scripted_path_effect_base.hpp new file mode 100644 index 000000000..1c7cbd064 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/scripted/scripted_path_effect_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_SCRIPTED_PATH_EFFECT_BASE_HPP_ +#define _RIVE_SCRIPTED_PATH_EFFECT_BASE_HPP_ +#include "rive/container_component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ScriptedPathEffectBase : public ContainerComponent +{ +protected: + typedef ContainerComponent Super; + +public: + static const uint16_t typeKey = 640; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ScriptedPathEffectBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t scriptAssetIdPropertyKey = 912; + +protected: + uint32_t m_ScriptAssetId = -1; + +public: + inline uint32_t scriptAssetId() const { return m_ScriptAssetId; } + void scriptAssetId(uint32_t value) + { + if (m_ScriptAssetId == value) + { + return; + } + m_ScriptAssetId = value; + scriptAssetIdChanged(); + } + + Core* clone() const override; + void copy(const ScriptedPathEffectBase& object) + { + m_ScriptAssetId = object.m_ScriptAssetId; + ContainerComponent::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case scriptAssetIdPropertyKey: + m_ScriptAssetId = CoreUintType::deserialize(reader); + return true; + } + return ContainerComponent::deserialize(propertyKey, reader); + } + +protected: + virtual void scriptAssetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/semantic/semantic_data_base.hpp b/thirdparty/rive/include/rive/generated/semantic/semantic_data_base.hpp new file mode 100644 index 000000000..0be9c7a27 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/semantic/semantic_data_base.hpp @@ -0,0 +1,224 @@ +#ifndef _RIVE_SEMANTIC_DATA_BASE_HPP_ +#define _RIVE_SEMANTIC_DATA_BASE_HPP_ +#include +#include "rive/component.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_string_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class SemanticDataBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 668; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case SemanticDataBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t rolePropertyKey = 982; + static const uint16_t labelPropertyKey = 983; + static const uint16_t valuePropertyKey = 984; + static const uint16_t hintPropertyKey = 985; + static const uint16_t headingLevelPropertyKey = 986; + static const uint16_t traitFlagsPropertyKey = 987; + static const uint16_t stateFlagsPropertyKey = 988; + static const uint16_t isExpandablePropertyKey = 989; + static const uint32_t isExpandableBitmask = 1u << 0; + static const uint16_t isSelectablePropertyKey = 990; + static const uint32_t isSelectableBitmask = 1u << 1; + static const uint16_t isCheckablePropertyKey = 991; + static const uint32_t isCheckableBitmask = 1u << 2; + static const uint16_t isToggleablePropertyKey = 992; + static const uint32_t isToggleableBitmask = 1u << 3; + static const uint16_t isRequirablePropertyKey = 993; + static const uint32_t isRequirableBitmask = 1u << 4; + static const uint16_t isEnablablePropertyKey = 994; + static const uint32_t isEnablableBitmask = 1u << 5; + static const uint16_t isFocusablePropertyKey = 995; + static const uint32_t isFocusableBitmask = 1u << 6; + static const uint16_t isExpandedPropertyKey = 996; + static const uint32_t isExpandedBitmask = 1u << 0; + static const uint16_t isSelectedPropertyKey = 997; + static const uint32_t isSelectedBitmask = 1u << 1; + static const uint16_t isCheckedPropertyKey = 998; + static const uint32_t isCheckedBitmask = 1u << 2; + static const uint16_t isMixedPropertyKey = 999; + static const uint32_t isMixedBitmask = 1u << 3; + static const uint16_t isToggledPropertyKey = 1000; + static const uint32_t isToggledBitmask = 1u << 4; + static const uint16_t isRequiredPropertyKey = 1001; + static const uint32_t isRequiredBitmask = 1u << 5; + static const uint16_t isDisabledPropertyKey = 1002; + static const uint32_t isDisabledBitmask = 1u << 6; + static const uint16_t isFocusedPropertyKey = 1003; + static const uint32_t isFocusedBitmask = 1u << 7; + static const uint16_t isHiddenPropertyKey = 1004; + static const uint32_t isHiddenBitmask = 1u << 8; + static const uint16_t isLiveRegionPropertyKey = 1005; + static const uint32_t isLiveRegionBitmask = 1u << 9; + static const uint16_t isReadOnlyPropertyKey = 1006; + static const uint32_t isReadOnlyBitmask = 1u << 10; + static const uint16_t isModalPropertyKey = 1007; + static const uint32_t isModalBitmask = 1u << 11; + static const uint16_t isObscuredPropertyKey = 1008; + static const uint32_t isObscuredBitmask = 1u << 12; + static const uint16_t isMultilinePropertyKey = 1009; + static const uint32_t isMultilineBitmask = 1u << 13; + +protected: + uint32_t m_Role = 0; + std::string m_Label = ""; + std::string m_Value = ""; + std::string m_Hint = ""; + uint32_t m_HeadingLevel = 0; + uint32_t m_TraitFlags = 0; + uint32_t m_StateFlags = 0; + +public: + inline uint32_t role() const { return m_Role; } + void role(uint32_t value) + { + if (m_Role == value) + { + return; + } + m_Role = value; + roleChanged(); + } + + inline const std::string& label() const { return m_Label; } + void label(std::string value) + { + if (m_Label == value) + { + return; + } + m_Label = value; + labelChanged(); + } + + inline const std::string& value() const { return m_Value; } + void value(std::string value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + inline const std::string& hint() const { return m_Hint; } + void hint(std::string value) + { + if (m_Hint == value) + { + return; + } + m_Hint = value; + hintChanged(); + } + + inline uint32_t headingLevel() const { return m_HeadingLevel; } + void headingLevel(uint32_t value) + { + if (m_HeadingLevel == value) + { + return; + } + m_HeadingLevel = value; + headingLevelChanged(); + } + + inline uint32_t traitFlags() const { return m_TraitFlags; } + void traitFlags(uint32_t value) + { + if (m_TraitFlags == value) + { + return; + } + m_TraitFlags = value; + traitFlagsChanged(); + } + + inline uint32_t stateFlags() const { return m_StateFlags; } + void stateFlags(uint32_t value) + { + if (m_StateFlags == value) + { + return; + } + m_StateFlags = value; + stateFlagsChanged(); + } + + Core* clone() const override; + void copy(const SemanticDataBase& object) + { + m_Role = object.m_Role; + m_Label = object.m_Label; + m_Value = object.m_Value; + m_Hint = object.m_Hint; + m_HeadingLevel = object.m_HeadingLevel; + m_TraitFlags = object.m_TraitFlags; + m_StateFlags = object.m_StateFlags; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case rolePropertyKey: + m_Role = CoreUintType::deserialize(reader); + return true; + case labelPropertyKey: + m_Label = CoreStringType::deserialize(reader); + return true; + case valuePropertyKey: + m_Value = CoreStringType::deserialize(reader); + return true; + case hintPropertyKey: + m_Hint = CoreStringType::deserialize(reader); + return true; + case headingLevelPropertyKey: + m_HeadingLevel = CoreUintType::deserialize(reader); + return true; + case traitFlagsPropertyKey: + m_TraitFlags = CoreUintType::deserialize(reader); + return true; + case stateFlagsPropertyKey: + m_StateFlags = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void roleChanged() {} + virtual void labelChanged() {} + virtual void valueChanged() {} + virtual void hintChanged() {} + virtual void headingLevelChanged() {} + virtual void traitFlagsChanged() {} + virtual void stateFlagsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/shapes/image_base.hpp b/thirdparty/rive/include/rive/generated/shapes/image_base.hpp index 05b85f9a0..6e296c6fe 100644 --- a/thirdparty/rive/include/rive/generated/shapes/image_base.hpp +++ b/thirdparty/rive/include/rive/generated/shapes/image_base.hpp @@ -37,11 +37,17 @@ class ImageBase : public Drawable static const uint16_t assetIdPropertyKey = 206; static const uint16_t originXPropertyKey = 380; static const uint16_t originYPropertyKey = 381; + static const uint16_t fitPropertyKey = 974; + static const uint16_t alignmentXPropertyKey = 975; + static const uint16_t alignmentYPropertyKey = 976; protected: uint32_t m_AssetId = -1; float m_OriginX = 0.5f; float m_OriginY = 0.5f; + uint32_t m_Fit = 0; + float m_AlignmentX = 0.0f; + float m_AlignmentY = 0.0f; public: inline uint32_t assetId() const { return m_AssetId; } @@ -77,12 +83,48 @@ class ImageBase : public Drawable originYChanged(); } + inline uint32_t fit() const { return m_Fit; } + void fit(uint32_t value) + { + if (m_Fit == value) + { + return; + } + m_Fit = value; + fitChanged(); + } + + inline float alignmentX() const { return m_AlignmentX; } + void alignmentX(float value) + { + if (m_AlignmentX == value) + { + return; + } + m_AlignmentX = value; + alignmentXChanged(); + } + + inline float alignmentY() const { return m_AlignmentY; } + void alignmentY(float value) + { + if (m_AlignmentY == value) + { + return; + } + m_AlignmentY = value; + alignmentYChanged(); + } + Core* clone() const override; void copy(const ImageBase& object) { m_AssetId = object.m_AssetId; m_OriginX = object.m_OriginX; m_OriginY = object.m_OriginY; + m_Fit = object.m_Fit; + m_AlignmentX = object.m_AlignmentX; + m_AlignmentY = object.m_AlignmentY; Drawable::copy(object); } @@ -99,6 +141,15 @@ class ImageBase : public Drawable case originYPropertyKey: m_OriginY = CoreDoubleType::deserialize(reader); return true; + case fitPropertyKey: + m_Fit = CoreUintType::deserialize(reader); + return true; + case alignmentXPropertyKey: + m_AlignmentX = CoreDoubleType::deserialize(reader); + return true; + case alignmentYPropertyKey: + m_AlignmentY = CoreDoubleType::deserialize(reader); + return true; } return Drawable::deserialize(propertyKey, reader); } @@ -107,6 +158,9 @@ class ImageBase : public Drawable virtual void assetIdChanged() {} virtual void originXChanged() {} virtual void originYChanged() {} + virtual void fitChanged() {} + virtual void alignmentXChanged() {} + virtual void alignmentYChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/shapes/list_path_base.hpp b/thirdparty/rive/include/rive/generated/shapes/list_path_base.hpp new file mode 100644 index 000000000..e9cc85b11 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/shapes/list_path_base.hpp @@ -0,0 +1,77 @@ +#ifndef _RIVE_LIST_PATH_BASE_HPP_ +#define _RIVE_LIST_PATH_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/shapes/points_common_path.hpp" +namespace rive +{ +class ListPathBase : public PointsCommonPath +{ +protected: + typedef PointsCommonPath Super; + +public: + static const uint16_t typeKey = 619; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListPathBase::typeKey: + case PointsCommonPathBase::typeKey: + case PathBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t listSourcePropertyKey = 874; + +protected: + uint32_t m_ListSource = -1; + +public: + inline uint32_t listSource() const { return m_ListSource; } + void listSource(uint32_t value) + { + if (m_ListSource == value) + { + return; + } + m_ListSource = value; + listSourceChanged(); + } + + Core* clone() const override; + void copy(const ListPathBase& object) + { + m_ListSource = object.m_ListSource; + PointsCommonPath::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case listSourcePropertyKey: + m_ListSource = CoreUintType::deserialize(reader); + return true; + } + return PointsCommonPath::deserialize(propertyKey, reader); + } + +protected: + virtual void listSourceChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/shapes/paint/group_effect_base.hpp b/thirdparty/rive/include/rive/generated/shapes/paint/group_effect_base.hpp new file mode 100644 index 000000000..8d711d5c4 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/shapes/paint/group_effect_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_GROUP_EFFECT_BASE_HPP_ +#define _RIVE_GROUP_EFFECT_BASE_HPP_ +#include "rive/container_component.hpp" +namespace rive +{ +class GroupEffectBase : public ContainerComponent +{ +protected: + typedef ContainerComponent Super; + +public: + static const uint16_t typeKey = 645; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case GroupEffectBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/shapes/paint/target_effect_base.hpp b/thirdparty/rive/include/rive/generated/shapes/paint/target_effect_base.hpp new file mode 100644 index 000000000..b8069c172 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/shapes/paint/target_effect_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_TARGET_EFFECT_BASE_HPP_ +#define _RIVE_TARGET_EFFECT_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TargetEffectBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 644; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TargetEffectBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t targetIdPropertyKey = 922; + +protected: + uint32_t m_TargetId = -1; + +public: + inline uint32_t targetId() const { return m_TargetId; } + void targetId(uint32_t value) + { + if (m_TargetId == value) + { + return; + } + m_TargetId = value; + targetIdChanged(); + } + + Core* clone() const override; + void copy(const TargetEffectBase& object) + { + m_TargetId = object.m_TargetId; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case targetIdPropertyKey: + m_TargetId = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void targetIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/shapes/points_common_path_base.hpp b/thirdparty/rive/include/rive/generated/shapes/points_common_path_base.hpp new file mode 100644 index 000000000..3d32fb498 --- /dev/null +++ b/thirdparty/rive/include/rive/generated/shapes/points_common_path_base.hpp @@ -0,0 +1,75 @@ +#ifndef _RIVE_POINTS_COMMON_PATH_BASE_HPP_ +#define _RIVE_POINTS_COMMON_PATH_BASE_HPP_ +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/shapes/path.hpp" +namespace rive +{ +class PointsCommonPathBase : public Path +{ +protected: + typedef Path Super; + +public: + static const uint16_t typeKey = 620; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case PointsCommonPathBase::typeKey: + case PathBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t isClosedPropertyKey = 32; + +protected: + bool m_IsClosed = false; + +public: + inline bool isClosed() const { return m_IsClosed; } + void isClosed(bool value) + { + if (m_IsClosed == value) + { + return; + } + m_IsClosed = value; + isClosedChanged(); + } + + void copy(const PointsCommonPathBase& object) + { + m_IsClosed = object.m_IsClosed; + Path::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case isClosedPropertyKey: + m_IsClosed = CoreBoolType::deserialize(reader); + return true; + } + return Path::deserialize(propertyKey, reader); + } + +protected: + virtual void isClosedChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/shapes/points_path_base.hpp b/thirdparty/rive/include/rive/generated/shapes/points_path_base.hpp index 29cee49fa..5d750143c 100644 --- a/thirdparty/rive/include/rive/generated/shapes/points_path_base.hpp +++ b/thirdparty/rive/include/rive/generated/shapes/points_path_base.hpp @@ -1,13 +1,12 @@ #ifndef _RIVE_POINTS_PATH_BASE_HPP_ #define _RIVE_POINTS_PATH_BASE_HPP_ -#include "rive/core/field_types/core_bool_type.hpp" -#include "rive/shapes/path.hpp" +#include "rive/shapes/points_common_path.hpp" namespace rive { -class PointsPathBase : public Path +class PointsPathBase : public PointsCommonPath { protected: - typedef Path Super; + typedef PointsCommonPath Super; public: static const uint16_t typeKey = 16; @@ -19,6 +18,7 @@ class PointsPathBase : public Path switch (typeKey) { case PointsPathBase::typeKey: + case PointsCommonPathBase::typeKey: case PathBase::typeKey: case NodeBase::typeKey: case TransformComponentBase::typeKey: @@ -33,43 +33,9 @@ class PointsPathBase : public Path uint16_t coreType() const override { return typeKey; } - static const uint16_t isClosedPropertyKey = 32; - -protected: - bool m_IsClosed = false; - -public: - inline bool isClosed() const { return m_IsClosed; } - void isClosed(bool value) - { - if (m_IsClosed == value) - { - return; - } - m_IsClosed = value; - isClosedChanged(); - } - Core* clone() const override; - void copy(const PointsPathBase& object) - { - m_IsClosed = object.m_IsClosed; - Path::copy(object); - } - - bool deserialize(uint16_t propertyKey, BinaryReader& reader) override - { - switch (propertyKey) - { - case isClosedPropertyKey: - m_IsClosed = CoreBoolType::deserialize(reader); - return true; - } - return Path::deserialize(propertyKey, reader); - } protected: - virtual void isClosedChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/text/text_base.hpp b/thirdparty/rive/include/rive/generated/text/text_base.hpp index f835ff210..ec8ea396c 100644 --- a/thirdparty/rive/include/rive/generated/text/text_base.hpp +++ b/thirdparty/rive/include/rive/generated/text/text_base.hpp @@ -47,6 +47,7 @@ class TextBase : public Drawable static const uint16_t wrapValuePropertyKey = 683; static const uint16_t verticalAlignValuePropertyKey = 685; static const uint16_t fitFromBaselinePropertyKey = 703; + static const uint16_t textRunListSourcePropertyKey = 932; protected: uint32_t m_AlignValue = 0; @@ -61,6 +62,7 @@ class TextBase : public Drawable uint32_t m_WrapValue = 0; uint32_t m_VerticalAlignValue = 0; bool m_FitFromBaseline = true; + uint32_t m_TextRunListSource = -1; public: inline uint32_t alignValue() const { return m_AlignValue; } @@ -195,6 +197,17 @@ class TextBase : public Drawable fitFromBaselineChanged(); } + inline uint32_t textRunListSource() const { return m_TextRunListSource; } + void textRunListSource(uint32_t value) + { + if (m_TextRunListSource == value) + { + return; + } + m_TextRunListSource = value; + textRunListSourceChanged(); + } + Core* clone() const override; void copy(const TextBase& object) { @@ -210,6 +223,7 @@ class TextBase : public Drawable m_WrapValue = object.m_WrapValue; m_VerticalAlignValue = object.m_VerticalAlignValue; m_FitFromBaseline = object.m_FitFromBaseline; + m_TextRunListSource = object.m_TextRunListSource; Drawable::copy(object); } @@ -253,6 +267,9 @@ class TextBase : public Drawable case fitFromBaselinePropertyKey: m_FitFromBaseline = CoreBoolType::deserialize(reader); return true; + case textRunListSourcePropertyKey: + m_TextRunListSource = CoreUintType::deserialize(reader); + return true; } return Drawable::deserialize(propertyKey, reader); } @@ -270,6 +287,7 @@ class TextBase : public Drawable virtual void wrapValueChanged() {} virtual void verticalAlignValueChanged() {} virtual void fitFromBaselineChanged() {} + virtual void textRunListSourceChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/text/text_input_base.hpp b/thirdparty/rive/include/rive/generated/text/text_input_base.hpp index 461045ed8..820b1c214 100644 --- a/thirdparty/rive/include/rive/generated/text/text_input_base.hpp +++ b/thirdparty/rive/include/rive/generated/text/text_input_base.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_TEXT_INPUT_BASE_HPP_ #define _RIVE_TEXT_INPUT_BASE_HPP_ #include +#include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_string_type.hpp" #include "rive/drawable.hpp" @@ -37,10 +38,12 @@ class TextInputBase : public Drawable static const uint16_t textPropertyKey = 817; static const uint16_t selectionRadiusPropertyKey = 818; + static const uint16_t multilinePropertyKey = 979; protected: std::string m_Text = ""; float m_SelectionRadius = 5.0f; + bool m_Multiline = true; public: inline const std::string& text() const { return m_Text; } @@ -65,11 +68,23 @@ class TextInputBase : public Drawable selectionRadiusChanged(); } + inline bool multiline() const { return m_Multiline; } + void multiline(bool value) + { + if (m_Multiline == value) + { + return; + } + m_Multiline = value; + multilineChanged(); + } + Core* clone() const override; void copy(const TextInputBase& object) { m_Text = object.m_Text; m_SelectionRadius = object.m_SelectionRadius; + m_Multiline = object.m_Multiline; Drawable::copy(object); } @@ -83,6 +98,9 @@ class TextInputBase : public Drawable case selectionRadiusPropertyKey: m_SelectionRadius = CoreDoubleType::deserialize(reader); return true; + case multilinePropertyKey: + m_Multiline = CoreBoolType::deserialize(reader); + return true; } return Drawable::deserialize(propertyKey, reader); } @@ -90,6 +108,7 @@ class TextInputBase : public Drawable protected: virtual void textChanged() {} virtual void selectionRadiusChanged() {} + virtual void multilineChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/text/text_style_paint_base.hpp b/thirdparty/rive/include/rive/generated/text/text_style_paint_base.hpp index 43deafbd8..abe240b1a 100644 --- a/thirdparty/rive/include/rive/generated/text/text_style_paint_base.hpp +++ b/thirdparty/rive/include/rive/generated/text/text_style_paint_base.hpp @@ -1,8 +1,6 @@ #ifndef _RIVE_TEXT_STYLE_PAINT_BASE_HPP_ #define _RIVE_TEXT_STYLE_PAINT_BASE_HPP_ - #include "rive/text/text_style.hpp" - namespace rive { class TextStylePaintBase : public TextStyle diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp new file mode 100644 index 000000000..85b5df88d --- /dev/null +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceArtboardBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 599; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceArtboardBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 846; + +protected: + uint32_t m_PropertyValue = -1; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceArtboardBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_base.hpp index e40a727a4..fabef228e 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceAssetBase : public ViewModelInstanceValue { case ViewModelInstanceAssetBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_image_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_image_base.hpp index 542e8b77a..c64b13e19 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_image_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_asset_image_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceAssetImageBase : public ViewModelInstanceAsset case ViewModelInstanceAssetImageBase::typeKey: case ViewModelInstanceAssetBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_base.hpp index 2f4010342..673b5df71 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_base.hpp @@ -1,13 +1,13 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_BASE_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_BASE_HPP_ -#include "rive/component.hpp" +#include "rive/container_component.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { -class ViewModelInstanceBase : public Component +class ViewModelInstanceBase : public ContainerComponent { protected: - typedef Component Super; + typedef ContainerComponent Super; public: static const uint16_t typeKey = 437; @@ -19,6 +19,7 @@ class ViewModelInstanceBase : public Component switch (typeKey) { case ViewModelInstanceBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: @@ -49,7 +50,7 @@ class ViewModelInstanceBase : public Component void copy(const ViewModelInstanceBase& object) { m_ViewModelId = object.m_ViewModelId; - Component::copy(object); + ContainerComponent::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override @@ -60,7 +61,7 @@ class ViewModelInstanceBase : public Component m_ViewModelId = CoreUintType::deserialize(reader); return true; } - return Component::deserialize(propertyKey, reader); + return ContainerComponent::deserialize(propertyKey, reader); } protected: diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp index 628fb0b74..edc2a724f 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceBooleanBase : public ViewModelInstanceValue { case ViewModelInstanceBooleanBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp index f74b073b8..8822f32ca 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceColorBase : public ViewModelInstanceValue { case ViewModelInstanceColorBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp index de624a5f6..79913d2ff 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceEnumBase : public ViewModelInstanceValue { case ViewModelInstanceEnumBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp index ec14bda91..c163ffe12 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp @@ -1,5 +1,6 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_LIST_BASE_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_LIST_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" namespace rive { @@ -19,6 +20,7 @@ class ViewModelInstanceListBase : public ViewModelInstanceValue { case ViewModelInstanceListBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; @@ -27,9 +29,43 @@ class ViewModelInstanceListBase : public ViewModelInstanceValue uint16_t coreType() const override { return typeKey; } + static const uint16_t listSourcePropertyKey = 966; + +protected: + uint32_t m_ListSource = -1; + +public: + inline uint32_t listSource() const { return m_ListSource; } + void listSource(uint32_t value) + { + if (m_ListSource == value) + { + return; + } + m_ListSource = value; + listSourceChanged(); + } + Core* clone() const override; + void copy(const ViewModelInstanceListBase& object) + { + m_ListSource = object.m_ListSource; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case listSourcePropertyKey: + m_ListSource = CoreUintType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } protected: + virtual void listSourceChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp index 57c235651..451254721 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceNumberBase : public ViewModelInstanceValue { case ViewModelInstanceNumberBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp index a757c2d57..382af677e 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp @@ -21,6 +21,7 @@ class ViewModelInstanceStringBase : public ViewModelInstanceValue { case ViewModelInstanceStringBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_base.hpp index 204cd1b4d..ddec5bbd4 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_base.hpp @@ -19,6 +19,7 @@ class ViewModelInstanceSymbolBase : public ViewModelInstanceValue { case ViewModelInstanceSymbolBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_list_index_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_list_index_base.hpp index 43454f5f2..6bc094a76 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_list_index_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_symbol_list_index_base.hpp @@ -21,6 +21,7 @@ class ViewModelInstanceSymbolListIndexBase : public ViewModelInstanceSymbol case ViewModelInstanceSymbolListIndexBase::typeKey: case ViewModelInstanceSymbolBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp index 0529b3164..b8d29cc0c 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceTriggerBase : public ViewModelInstanceValue { case ViewModelInstanceTriggerBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp index 3278f33ad..78816ccd4 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp @@ -1,13 +1,13 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_VALUE_BASE_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_VALUE_BASE_HPP_ -#include "rive/core.hpp" +#include "rive/component.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { -class ViewModelInstanceValueBase : public Core +class ViewModelInstanceValueBase : public Component { protected: - typedef Core Super; + typedef Component Super; public: static const uint16_t typeKey = 428; @@ -19,6 +19,7 @@ class ViewModelInstanceValueBase : public Core switch (typeKey) { case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; @@ -47,9 +48,11 @@ class ViewModelInstanceValueBase : public Core viewModelPropertyIdChanged(); } + Core* clone() const override; void copy(const ViewModelInstanceValueBase& object) { m_ViewModelPropertyId = object.m_ViewModelPropertyId; + Component::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override @@ -60,7 +63,7 @@ class ViewModelInstanceValueBase : public Core m_ViewModelPropertyId = CoreUintType::deserialize(reader); return true; } - return false; + return Component::deserialize(propertyKey, reader); } protected: diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp index ee303f091..78008311b 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp @@ -20,6 +20,7 @@ class ViewModelInstanceViewModelBase : public ViewModelInstanceValue { case ViewModelInstanceViewModelBase::typeKey: case ViewModelInstanceValueBase::typeKey: + case ComponentBase::typeKey: return true; default: return false; diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_artboard_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_artboard_base.hpp new file mode 100644 index 000000000..2880377ab --- /dev/null +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_artboard_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_ARTBOARD_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_ARTBOARD_BASE_HPP_ +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyArtboardBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 598; + + /// Helper to quickly determine if a core object extends another without + /// RTTI at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyArtboardBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_base.hpp b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_base.hpp index f016c1806..ca5dd2c40 100644 --- a/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_base.hpp +++ b/thirdparty/rive/include/rive/generated/viewmodel/viewmodel_property_base.hpp @@ -1,5 +1,6 @@ #ifndef _RIVE_VIEW_MODEL_PROPERTY_BASE_HPP_ #define _RIVE_VIEW_MODEL_PROPERTY_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" #include "rive/viewmodel/viewmodel_component.hpp" namespace rive { @@ -27,9 +28,61 @@ class ViewModelPropertyBase : public ViewModelComponent uint16_t coreType() const override { return typeKey; } + static const uint16_t symbolTypeValuePropertyKey = 875; + static const uint16_t componentPropsPropertyKey = 957; + +protected: + uint32_t m_SymbolTypeValue = 0; + uint32_t m_ComponentProps = 0; + +public: + inline uint32_t symbolTypeValue() const { return m_SymbolTypeValue; } + void symbolTypeValue(uint32_t value) + { + if (m_SymbolTypeValue == value) + { + return; + } + m_SymbolTypeValue = value; + symbolTypeValueChanged(); + } + + inline uint32_t componentProps() const { return m_ComponentProps; } + void componentProps(uint32_t value) + { + if (m_ComponentProps == value) + { + return; + } + m_ComponentProps = value; + componentPropsChanged(); + } + Core* clone() const override; + void copy(const ViewModelPropertyBase& object) + { + m_SymbolTypeValue = object.m_SymbolTypeValue; + m_ComponentProps = object.m_ComponentProps; + ViewModelComponent::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case symbolTypeValuePropertyKey: + m_SymbolTypeValue = CoreUintType::deserialize(reader); + return true; + case componentPropsPropertyKey: + m_ComponentProps = CoreUintType::deserialize(reader); + return true; + } + return ViewModelComponent::deserialize(propertyKey, reader); + } protected: + virtual void symbolTypeValueChanged() {} + virtual void componentPropsChanged() {} }; } // namespace rive diff --git a/thirdparty/rive/include/rive/gesture_click_phase.hpp b/thirdparty/rive/include/rive/gesture_click_phase.hpp index 2daf21ae7..04eda6e88 100644 --- a/thirdparty/rive/include/rive/gesture_click_phase.hpp +++ b/thirdparty/rive/include/rive/gesture_click_phase.hpp @@ -7,6 +7,7 @@ enum class GestureClickPhase : int out = 0, down = 1, clicked = 2, + disabled = 3, }; } #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/importers/backboard_importer.hpp b/thirdparty/rive/include/rive/importers/backboard_importer.hpp index 693cf9b2a..d8688858f 100644 --- a/thirdparty/rive/include/rive/importers/backboard_importer.hpp +++ b/thirdparty/rive/include/rive/importers/backboard_importer.hpp @@ -3,13 +3,14 @@ #include "rive/importers/import_stack.hpp" #include "rive/animation/keyframe_interpolator.hpp" +#include "rive/refcnt.hpp" +#include "rive/file.hpp" #include #include namespace rive { class Artboard; -class File; class NestedArtboard; class Backboard; class FileAsset; @@ -17,14 +18,16 @@ class FileAssetReferencer; class DataConverter; class DataBind; class DataConverterGroupItem; +class ScriptInputArtboard; class ScrollPhysics; +class ArtboardReferencer; class BackboardImporter : public ImportStackObject { private: Backboard* m_Backboard; std::unordered_map m_ArtboardLookup; - std::vector m_NestedArtboards; - std::vector m_FileAssets; + std::vector m_ArtboardsReferencers; + std::vector> m_FileAssets; std::vector m_FileAssetReferencers; std::vector m_DataConverters; std::vector m_DataConverterReferencers; @@ -38,8 +41,8 @@ class BackboardImporter : public ImportStackObject BackboardImporter(Backboard* backboard); void addArtboard(Artboard* artboard); void addMissingArtboard(); - void addNestedArtboard(NestedArtboard* artboard); - void addFileAsset(FileAsset* asset); + void addArtboardReferencer(ArtboardReferencer* artboard); + void addFileAsset(rcp asset); void addFileAssetReferencer(FileAssetReferencer* referencer); void addDataConverterReferencer(DataBind* referencer); void addDataConverter(DataConverter* converter); @@ -48,7 +51,7 @@ class BackboardImporter : public ImportStackObject void addInterpolator(KeyFrameInterpolator* interpolator); void addPhysics(ScrollPhysics* physics); std::vector physics() { return m_physics; } - std::vector* assets() { return &m_FileAssets; } + std::vector>* assets() { return &m_FileAssets; } void file(File* value); File* file() { return m_file; }; diff --git a/thirdparty/rive/include/rive/importers/data_bind_path_importer.hpp b/thirdparty/rive/include/rive/importers/data_bind_path_importer.hpp new file mode 100644 index 000000000..9902e20df --- /dev/null +++ b/thirdparty/rive/include/rive/importers/data_bind_path_importer.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_DATA_BIND_PATH_IMPORTER_HPP_ +#define _RIVE_DATA_BIND_PATH_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class Core; +class DataBindPath; +class DataBindPathImporter : public ImportStackObject +{ +private: + DataBindPath* m_dataBindPath; + +public: + DataBindPathImporter(DataBindPath* object); + DataBindPath* claim(); +}; +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/importers/file_asset_importer.hpp b/thirdparty/rive/include/rive/importers/file_asset_importer.hpp index 9e8246353..0594baca3 100644 --- a/thirdparty/rive/include/rive/importers/file_asset_importer.hpp +++ b/thirdparty/rive/include/rive/importers/file_asset_importer.hpp @@ -12,20 +12,20 @@ class FileAsset; class FileAssetContents; class FileAssetLoader; class Factory; - class FileAssetImporter : public ImportStackObject { -private: - FileAsset* m_FileAsset; - rcp m_FileAssetLoader; - Factory* m_Factory; - // we will delete this when we go out of scope - std::unique_ptr m_Content; - public: FileAssetImporter(FileAsset*, rcp, Factory*); - void onFileAssetContents(std::unique_ptr contents); + virtual void onFileAssetContents( + std::unique_ptr contents); StatusCode resolve() override; + +protected: + FileAsset* m_fileAsset; + rcp m_fileAssetLoader; + Factory* m_factory; + // we will delete this when we go out of scope + std::unique_ptr m_content; }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/importers/listener_input_type_keyboard_importer.hpp b/thirdparty/rive/include/rive/importers/listener_input_type_keyboard_importer.hpp new file mode 100644 index 000000000..9e6f7600c --- /dev/null +++ b/thirdparty/rive/include/rive/importers/listener_input_type_keyboard_importer.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_KEYBOARD_IMPORTER_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_KEYBOARD_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class ListenerInputTypeKeyboard; + +class ListenerInputTypeKeyboardImporter : public ImportStackObject +{ +private: + ListenerInputTypeKeyboard* m_listenerInputTypeKeyboard; + +public: + explicit ListenerInputTypeKeyboardImporter( + ListenerInputTypeKeyboard* listenerInputTypeKeyboard); + ListenerInputTypeKeyboard* listenerInputTypeKeyboard() const + { + return m_listenerInputTypeKeyboard; + } + StatusCode resolve() override; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/importers/listener_input_type_semantic_importer.hpp b/thirdparty/rive/include/rive/importers/listener_input_type_semantic_importer.hpp new file mode 100644 index 000000000..4f3cc7d02 --- /dev/null +++ b/thirdparty/rive/include/rive/importers/listener_input_type_semantic_importer.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_LISTENER_INPUT_TYPE_SEMANTIC_IMPORTER_HPP_ +#define _RIVE_LISTENER_INPUT_TYPE_SEMANTIC_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class ListenerInputTypeSemantic; + +class ListenerInputTypeSemanticImporter : public ImportStackObject +{ +private: + ListenerInputTypeSemantic* m_listenerInputTypeSemantic; + +public: + explicit ListenerInputTypeSemanticImporter( + ListenerInputTypeSemantic* listenerInputTypeSemantic); + ListenerInputTypeSemantic* listenerInputTypeSemantic() const + { + return m_listenerInputTypeSemantic; + } + StatusCode resolve() override; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/importers/scripted_object_importer.hpp b/thirdparty/rive/include/rive/importers/scripted_object_importer.hpp new file mode 100644 index 000000000..da5a40356 --- /dev/null +++ b/thirdparty/rive/include/rive/importers/scripted_object_importer.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_SCRIPTED_OBJECT_IMPORTER_HPP_ +#define _RIVE_SCRIPTED_OBJECT_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class Core; +class CustomProperty; +class ScriptedObject; + +class ScriptedObjectImporter : public ImportStackObject +{ +private: + ScriptedObject* m_scriptedObject; + +public: + ScriptedObjectImporter(ScriptedObject* object); + void addInput(CustomProperty* input); + StatusCode resolve() override; +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/importers/state_machine_importer.hpp b/thirdparty/rive/include/rive/importers/state_machine_importer.hpp index dc0823650..2d8c4029e 100644 --- a/thirdparty/rive/include/rive/importers/state_machine_importer.hpp +++ b/thirdparty/rive/include/rive/importers/state_machine_importer.hpp @@ -10,6 +10,7 @@ class StateMachineLayer; class StateMachineListener; class StateMachine; class DataBind; +class ScriptedObject; class StateMachineImporter : public ImportStackObject { private: @@ -23,6 +24,7 @@ class StateMachineImporter : public ImportStackObject void addInput(std::unique_ptr); void addListener(std::unique_ptr); void addDataBind(std::unique_ptr); + void addScriptedObject(ScriptedObject* object); StatusCode resolve() override; bool readNullObject() override; diff --git a/thirdparty/rive/include/rive/importers/state_machine_layer_component_importer.hpp b/thirdparty/rive/include/rive/importers/state_machine_layer_component_importer.hpp index b9132a225..3e1aaaf90 100644 --- a/thirdparty/rive/include/rive/importers/state_machine_layer_component_importer.hpp +++ b/thirdparty/rive/include/rive/importers/state_machine_layer_component_importer.hpp @@ -2,18 +2,21 @@ #define _RIVE_STATE_MACHINE_LAYER_COMPONENT_IMPORTER_HPP_ #include "rive/importers/import_stack.hpp" +#include namespace rive { class StateMachineLayerComponent; -class StateMachineFireEvent; +class StateMachineFireAction; +class ListenerAction; class StateMachineLayerComponentImporter : public ImportStackObject { public: StateMachineLayerComponentImporter(StateMachineLayerComponent* component); - void addFireEvent(StateMachineFireEvent* fireEvent); + void addFireEvent(StateMachineFireAction* fireEvent); + void addListenerAction(std::unique_ptr action); private: StateMachineLayerComponent* m_stateMachineLayerComponent; diff --git a/thirdparty/rive/include/rive/importers/state_machine_listener_importer.hpp b/thirdparty/rive/include/rive/importers/state_machine_listener_importer.hpp index 6dc640482..92c4b5bc6 100644 --- a/thirdparty/rive/include/rive/importers/state_machine_listener_importer.hpp +++ b/thirdparty/rive/include/rive/importers/state_machine_listener_importer.hpp @@ -20,6 +20,7 @@ class StateMachineListenerImporter : public ImportStackObject return m_StateMachineListener; } void addAction(std::unique_ptr); + void addListenerInputType(std::unique_ptr); StatusCode resolve() override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/importers/text_asset_importer.hpp b/thirdparty/rive/include/rive/importers/text_asset_importer.hpp new file mode 100644 index 000000000..8253f1b8a --- /dev/null +++ b/thirdparty/rive/include/rive/importers/text_asset_importer.hpp @@ -0,0 +1,56 @@ +#ifdef WITH_RIVE_SCRIPTING +#ifndef _RIVE_TEXT_ASSET_IMPORTER_HPP_ +#define _RIVE_TEXT_ASSET_IMPORTER_HPP_ + +#include "rive/importers/file_asset_importer.hpp" +#include "rive/simple_array.hpp" +#include + +namespace rive +{ +class TextAsset; +class TextAssetImporter; + +/// A single in-band payload (Luau bytecode or RSTB blob) captured during +/// import, held until the aggregate signature is verified in resolve(). +class InBandContent +{ + friend class TextAssetImporter; + +public: + InBandContent(TextAsset* asset, SimpleArray& bytes); + +private: + TextAsset* m_textAsset; + SimpleArray m_bytes; +}; + +/// Importer shared by all TextAsset subclasses (ScriptAsset, ShaderAsset). +/// Strips the SignedContentHeader envelope from in-band FileAssetContents and +/// contributes the raw content bytes to a shared verification set. The last +/// importer with a signature runs hydro_sign_verify against the concatenated +/// bytes and marks every participating asset as verified. +class TextAssetImporter : public FileAssetImporter +{ +public: + TextAssetImporter(TextAsset*, + rcp, + Factory*, + std::vector*); + StatusCode resolve() override; + void onFileAssetContents( + std::unique_ptr contents) override; + + TextAsset* textAsset(); + +private: + // The set of in-band contents which are signed together. + std::vector* m_verificationSet; +}; + +// Public key for in-band content signature verification (32 bytes) +// TODO: Replace with permanent production public key. +extern const uint8_t g_scriptVerificationPublicKey[32]; +} // namespace rive +#endif +#endif diff --git a/thirdparty/rive/include/rive/importers/transition_viewmodel_condition_importer.hpp b/thirdparty/rive/include/rive/importers/transition_viewmodel_condition_importer.hpp index 7cf92bdca..45dda8cd5 100644 --- a/thirdparty/rive/include/rive/importers/transition_viewmodel_condition_importer.hpp +++ b/thirdparty/rive/include/rive/importers/transition_viewmodel_condition_importer.hpp @@ -18,6 +18,7 @@ class TransitionViewModelConditionImporter : public ImportStackObject TransitionViewModelConditionImporter( TransitionViewModelCondition* transitionViewModelCondition); void setComparator(TransitionComparator* comparator); + StatusCode resolve() override; }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/importers/viewmodel_importer.hpp b/thirdparty/rive/include/rive/importers/viewmodel_importer.hpp index 8298c26ca..ad44cce53 100644 --- a/thirdparty/rive/include/rive/importers/viewmodel_importer.hpp +++ b/thirdparty/rive/include/rive/importers/viewmodel_importer.hpp @@ -8,14 +8,18 @@ namespace rive class ViewModel; class ViewModelProperty; class ViewModelInstance; +class File; class ViewModelImporter : public ImportStackObject { private: ViewModel* m_ViewModel; + File* m_File = nullptr; public: ViewModelImporter(ViewModel* viewModel); + void file(File* file) { m_File = file; } + File* file() const { return m_File; } void addProperty(ViewModelProperty* property); void addInstance(ViewModelInstance* value); StatusCode resolve() override; diff --git a/thirdparty/rive/include/rive/importers/viewmodel_instance_importer.hpp b/thirdparty/rive/include/rive/importers/viewmodel_instance_importer.hpp index d70c8583c..2c83c081e 100644 --- a/thirdparty/rive/include/rive/importers/viewmodel_instance_importer.hpp +++ b/thirdparty/rive/include/rive/importers/viewmodel_instance_importer.hpp @@ -11,12 +11,13 @@ class ViewModelInstanceValue; class ViewModelInstanceImporter : public ImportStackObject { private: - ViewModelInstance* m_ViewModelInstance; + ViewModelInstance* m_ViewModelInstance = nullptr; public: ViewModelInstanceImporter(ViewModelInstance* viewModelInstance); void addValue(ViewModelInstanceValue* value); StatusCode resolve() override; + ViewModelInstance* viewModelInstance() { return m_ViewModelInstance; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/importers/viewmodel_instance_list_importer.hpp b/thirdparty/rive/include/rive/importers/viewmodel_instance_list_importer.hpp index 3833b2ec1..b11b760f3 100644 --- a/thirdparty/rive/include/rive/importers/viewmodel_instance_list_importer.hpp +++ b/thirdparty/rive/include/rive/importers/viewmodel_instance_list_importer.hpp @@ -2,6 +2,7 @@ #define _RIVE_VIEWMODEL_INSTANCE_LIST_IMPORTER_HPP_ #include "rive/importers/import_stack.hpp" +#include "rive/refcnt.hpp" namespace rive { @@ -15,7 +16,7 @@ class ViewModelInstanceListImporter : public ImportStackObject public: ViewModelInstanceListImporter(ViewModelInstanceList* viewModelInstanceList); - void addItem(ViewModelInstanceListItem* listItem); + void addItem(rcp listItem); StatusCode resolve() override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/input/focus_listener.hpp b/thirdparty/rive/include/rive/input/focus_listener.hpp new file mode 100644 index 000000000..eaf363e47 --- /dev/null +++ b/thirdparty/rive/include/rive/input/focus_listener.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_FOCUS_LISTENER_HPP_ +#define _RIVE_FOCUS_LISTENER_HPP_ + +namespace rive +{ + +/// Interface for objects that want to be notified of focus changes on a +/// FocusData. +class FocusListener +{ +public: + virtual ~FocusListener() = default; + + /// Called when the associated FocusData gains focus. + virtual void onFocused() = 0; + + /// Called when the associated FocusData loses focus. + virtual void onBlurred() = 0; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/input/focus_manager.hpp b/thirdparty/rive/include/rive/input/focus_manager.hpp new file mode 100644 index 000000000..90cc861c2 --- /dev/null +++ b/thirdparty/rive/include/rive/input/focus_manager.hpp @@ -0,0 +1,149 @@ +/* + * Copyright 2024 Rive + */ + +#ifndef _RIVE_FOCUS_MANAGER_HPP_ +#define _RIVE_FOCUS_MANAGER_HPP_ + +#include "rive/input/focus_node.hpp" +#include "rive/refcnt.hpp" +#include + +namespace rive +{ + +class Artboard; + +/// Direction for directional focus navigation +enum class Direction : uint8_t +{ + left, + right, + up, + down +}; + +/// FocusManager tracks focus state and provides traversal. +/// Hierarchy is stored on FocusNode itself (parent/children). +class FocusManager +{ +public: + FocusManager() = default; + ~FocusManager(); + + // === Focus State === + + rcp primaryFocus() const { return m_primaryFocus; } + void setFocus(rcp node); + void clearFocus(); + + /// Clears primary focus if it targets FocusData that is no longer visible + /// in the hierarchy (collapsed, hidden, opacity 0, nested host hidden). + void dropFocusIfFocusTargetHidden(); + bool hasFocus(rcp node) const; // node or descendant has focus + bool hasPrimaryFocus( + rcp node) const; // node is the primary focus + + /// Get the world bounds of the primary focus node. + /// Returns true if bounds are valid, false if no focus or no bounds. + bool primaryFocusBounds(AABB& outBounds) const + { + if (m_primaryFocus == nullptr || !m_primaryFocus->hasWorldBounds()) + { + return false; + } + outBounds = m_primaryFocus->worldBounds(); + return true; + } + + /// Get the root artboard that contains the primary focus node. + /// This walks up the nested artboard chain to find the topmost artboard + /// (the one mounted by Dart/the host). + /// Returns nullptr if there is no focus or the focusable has no artboard. + Artboard* primaryFocusArtboard() const; + + /// Get the immediate artboard that contains the primary focus node. + /// Unlike primaryFocusArtboard(), this returns the direct parent artboard + /// without walking up nested artboard chains. + Artboard* primaryFocusImmediateArtboard() const + { + if (m_primaryFocus == nullptr || m_primaryFocus->focusable() == nullptr) + { + return nullptr; + } + return m_primaryFocus->focusable()->focusableArtboard(); + } + + // === Hierarchy === + + // Add child to parent (or to root nodes if parent is null) + void addChild(rcp parent, rcp child); + + // Remove child from its current parent (clears focus if needed) + void removeChild(rcp child); + + const std::vector>& rootNodes() const { return m_rootNodes; } + + // === Traversal === + + bool focusNext(); + bool focusPrevious(); + + // Directional navigation (gamepad/arrow keys) + bool focusLeft(); + bool focusRight(); + bool focusUp(); + bool focusDown(); + + // Get traversable children of a scope (or root nodes if scope is null) + // Sorted by tabIndex, filtered by canFocus && canTraverse + std::vector getTraversableNodes(FocusNode* scope) const; + + // === Input Routing === + + bool keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat); + bool textInput(const std::string& text); + +#ifdef WITH_RIVE_TOOLS + // === Callbacks (editor/tools only) === + using FocusChangedCallback = void (*)(); + void setFocusChangedCallback(FocusChangedCallback callback) + { + m_focusChangedCallback = callback; + } + + /// Callback for scroll-into-view requests from Dart-mounted artboards. + /// Called when focus changes to an element in an artboard whose root + /// has no host (i.e., is mounted by Dart). + /// Parameters: + /// - bounds: world bounds of the focused element to scroll into view + /// - artboard: the artboard directly hosted by the Dart root artboard + using ScrollIntoViewCallback = void (*)(const AABB& bounds, + Artboard* artboard); + void setScrollIntoViewCallback(ScrollIntoViewCallback callback) + { + m_scrollIntoViewCallback = callback; + } +#endif + +private: + rcp m_primaryFocus; + std::vector> m_rootNodes; + void removeManager(rcp); +#ifdef WITH_RIVE_TOOLS + FocusChangedCallback m_focusChangedCallback = nullptr; + ScrollIntoViewCallback m_scrollIntoViewCallback = nullptr; +#endif + + void notifyFocusChange(FocusNode* oldFocus, FocusNode* newFocus); + FocusNode* findNextFocusable(FocusNode* current, bool forward) const; + FocusNode* findNodeInDirection(FocusNode* current, + Direction direction) const; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/input/focus_node.hpp b/thirdparty/rive/include/rive/input/focus_node.hpp new file mode 100644 index 000000000..13f59cdde --- /dev/null +++ b/thirdparty/rive/include/rive/input/focus_node.hpp @@ -0,0 +1,192 @@ +/* + * Copyright 2024 Rive + */ + +#ifndef _RIVE_FOCUS_NODE_HPP_ +#define _RIVE_FOCUS_NODE_HPP_ + +#include "rive/input/focusable.hpp" +#include "rive/math/aabb.hpp" +#include "rive/refcnt.hpp" +#include +#include +#include + +namespace rive +{ + +class FocusManager; // Forward declaration + +enum class EdgeBehavior : uint8_t +{ + parentScope = 0, // Focus exits to parent scope's next focusable + closedLoop = 1, // Focus wraps from last to first within this scope + stop = 2, // Focus stays on boundary element +}; + +class FocusNode : public RefCnt +{ +public: + FocusNode(Focusable* focusable = nullptr) : m_focusable(focusable) {} + + // === Focusable === + + Focusable* focusable() const { return m_focusable; } + void setFocusable(Focusable* focusable) { m_focusable = focusable; } + void clearFocusable() { m_focusable = nullptr; } + + // === Properties (bitfield-backed) === + + // Master switch: if false, node cannot receive focus at all + bool canFocus() const { return m_flags & Flag::kCanFocus; } + void canFocus(bool value) { setFlag(Flag::kCanFocus, value); } + + // Can receive focus via pointer/touch click + bool canTouch() const { return m_flags & Flag::kCanTouch; } + void canTouch(bool value) { setFlag(Flag::kCanTouch, value); } + + // Included in tab traversal + bool canTraverse() const { return m_flags & Flag::kCanTraverse; } + void canTraverse(bool value) { setFlag(Flag::kCanTraverse, value); } + +#ifdef WITH_RIVE_TOOLS + // Only at edit time, we push down the collapse status of the nodes because + // we can't get the FocusData node from the FocusNode + bool isCollapsed() const { return m_isCollapsed; } + void isCollapsed(bool value) { m_isCollapsed = value; } +#endif + // True if this node or any descendant currently has focus + // (set by FocusManager during focus transitions) + bool hasFocus() const { return m_flags & Flag::kHasFocus; } + + // Note: A node with canFocus=true but canTouch=false and canTraverse=false + // can still be focused programmatically (via script) and receives text + // input. + + // Scope status is implicit: a node with children is a scope. + // EdgeBehavior only applies to scopes (nodes with children). + EdgeBehavior edgeBehavior() const + { + return static_cast((m_flags >> edgeBehaviorShift) & + edgeBehaviorMask); + } + void edgeBehavior(EdgeBehavior edge) + { + m_flags = (m_flags & ~(edgeBehaviorMask << edgeBehaviorShift)) | + (static_cast(edge) << edgeBehaviorShift); + } + + int tabIndex() const { return m_tabIndex; } + void tabIndex(int value) { m_tabIndex = static_cast(value); } + + // Debug name (not required to be unique) + const std::string& name() const { return m_name; } + void name(const std::string& value) { m_name = value; } + + // === World Bounds (for directional navigation) === + + // World bounds in root artboard space, used for spatial navigation. + // Set during update cycle by owner (TextInput, Dart, etc). + const AABB& worldBounds() const { return m_worldBounds; } + void worldBounds(const AABB& bounds) { m_worldBounds = bounds; } + + // Check if bounds are available (not empty/invalid) + bool hasWorldBounds() const { return !m_worldBounds.isEmptyOrNaN(); } + + // Clear bounds (mark as unavailable) + void clearWorldBounds() { m_worldBounds = AABB(); } + + // === Hierarchy === + + FocusNode* parent() const { return m_parent; } + const std::vector>& children() const { return m_children; } + FocusManager* manager() const { return m_manager; } + bool isScope() const { return !m_children.empty(); } + + void addChild(rcp child); + void removeChild(rcp child); + + // Remove this node from its current parent (used internally) + void removeFromParent(); + + // === Input Handling (delegates to Focusable) === + + bool keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) + { + return m_focusable + ? m_focusable->keyInput(key, modifiers, isPressed, isRepeat) + : false; + } + + bool textInput(const std::string& text) + { + return m_focusable ? m_focusable->textInput(text) : false; + } + + void focused() + { + if (m_focusable) + { + m_focusable->focused(); + } + } + + void blurred() + { + if (m_focusable) + { + m_focusable->blurred(); + } + } + +private: + friend class FocusManager; + + // Used by FocusManager to update focus state + void setHasFocus(bool value) { setFlag(Flag::kHasFocus, value); } + + enum Flag : uint8_t + { + kCanFocus = 1 << 0, // default: true + kCanTouch = 1 << 1, // default: true + kCanTraverse = 1 << 2, // default: true + // bits 3-4: EdgeBehavior (2 bits) + kHasFocus = 1 << 5, // true if this node or descendant has focus + }; + static constexpr uint8_t edgeBehaviorShift = 3; + static constexpr uint8_t edgeBehaviorMask = 0x3; + static constexpr uint8_t defaultFlags = + Flag::kCanFocus | Flag::kCanTouch | Flag::kCanTraverse; + + void setFlag(Flag flag, bool value) + { + if (value) + { + m_flags |= flag; + } + else + { + m_flags &= ~flag; + } + } + + Focusable* m_focusable = nullptr; + FocusNode* m_parent = nullptr; + FocusManager* m_manager = nullptr; + std::vector> m_children; + std::string m_name; + AABB m_worldBounds; // Default empty (invalid) - hasWorldBounds() returns + // false + uint8_t m_flags = defaultFlags; + int16_t m_tabIndex = 0; +#ifdef WITH_RIVE_TOOLS + bool m_isCollapsed = false; +#endif +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/input/focusable.hpp b/thirdparty/rive/include/rive/input/focusable.hpp new file mode 100644 index 000000000..b464426fa --- /dev/null +++ b/thirdparty/rive/include/rive/input/focusable.hpp @@ -0,0 +1,192 @@ +#ifndef _RIVE_FOCUSABLE_HPP_ +#define _RIVE_FOCUSABLE_HPP_ + +#include "rive/enums.hpp" +#include "rive/math/aabb.hpp" +#include "rive/math/vec2d.hpp" +#include + +namespace rive +{ +enum class KeyModifiers : uint8_t +{ + none = 0, + shift = 1 << 0, + ctrl = 1 << 1, + alt = 1 << 2, + meta = 1 << 3 + +}; + +inline KeyModifiers operator|(const KeyModifiers& a, const KeyModifiers& b) +{ + return (KeyModifiers)((uint8_t)a | (uint8_t)b); +} +inline KeyModifiers operator&(const KeyModifiers& a, const KeyModifiers& b) +{ + return (KeyModifiers)((uint8_t)a & (uint8_t)b); +} + +enum class Key : uint16_t +{ + space = 32, + apostrophe = 39, // ' + comma = 44, // , + minus = 45, // - + period = 46, // . + slash = 47, // / + key0 = 48, + key1 = 49, + key2 = 50, + key3 = 51, + key4 = 52, + key5 = 53, + key6 = 54, + key7 = 55, + key8 = 56, + key9 = 57, + semicolon = 59, // ; + equal = 61, // = + a = 65, + b = 66, + c = 67, + d = 68, + e = 69, + f = 70, + g = 71, + h = 72, + i = 73, + j = 74, + k = 75, + l = 76, + m = 77, + n = 78, + o = 79, + p = 80, + q = 81, + r = 82, + s = 83, + t = 84, + u = 85, + v = 86, + w = 87, + x = 88, + y = 89, + z = 90, + leftBracket = 91, // [ + backslash = 92, // "\" + rightBracket = 93, // ] + graveAccent = 96, // ` + world1 = 161, // non-US #1 + world2 = 162, // non-US #2 + escape = 256, + enter = 257, + tab = 258, + backspace = 259, + insert = 260, + deleteKey = 261, + right = 262, + left = 263, + down = 264, + up = 265, + pageUp = 266, + pageDown = 267, + home = 268, + end = 269, + capsLock = 280, + scrollLock = 281, + numLock = 282, + printScreen = 283, + pause = 284, + f1 = 290, + f2 = 291, + f3 = 292, + f4 = 293, + f5 = 294, + f6 = 295, + f7 = 296, + f8 = 297, + f9 = 298, + f10 = 299, + f11 = 300, + f12 = 301, + f13 = 302, + f14 = 303, + f15 = 304, + f16 = 305, + f17 = 306, + f18 = 307, + f19 = 308, + f20 = 309, + f21 = 310, + f22 = 311, + f23 = 312, + f24 = 313, + f25 = 314, + kp0 = 320, + kp1 = 321, + kp2 = 322, + kp3 = 323, + kp4 = 324, + kp5 = 325, + kp6 = 326, + kp7 = 327, + kp8 = 328, + kp9 = 329, + kpDecimal = 330, + kpDivide = 331, + kpMultiply = 332, + kpSubtract = 333, + kpAdd = 334, + kpEnter = 335, + kpEqual = 336, + leftShift = 340, + leftControl = 341, + leftAlt = 342, + leftSuper = 343, + rightShift = 344, + rightControl = 345, + rightAlt = 346, + rightSuper = 347, + menu = 348, +}; + +class Artboard; +class Core; + +class Focusable +{ +public: + virtual ~Focusable() = default; + + /// Try to get a Focusable from a Core object. + /// Returns nullptr if the object doesn't implement Focusable. + static Focusable* from(Core* object); + + /// Get the artboard this focusable belongs to. + /// Returns nullptr if not associated with an artboard. + virtual Artboard* focusableArtboard() const { return nullptr; } + + virtual bool keyInput(Key value, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) = 0; + virtual bool textInput(const std::string& text) = 0; + virtual void focused() = 0; + virtual void blurred() = 0; + + /// Get the world position of this focusable in root artboard space. + /// Used for directional focus navigation. + /// Returns false if position cannot be determined. + virtual bool worldPosition(Vec2D& outPosition) { return false; } + + /// Get the world bounds of this focusable in root artboard space. + /// Used for directional focus navigation with overlap/alignment. + /// Returns false if bounds cannot be determined (falls back to position). + virtual bool worldBounds(AABB& outBounds) { return false; } + + /// Returns whether the Focusable is currently eligible for focus traversal + virtual bool isEligibleForFocusTraversal() const { return true; } +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/input/keyboard_listener.hpp b/thirdparty/rive/include/rive/input/keyboard_listener.hpp new file mode 100644 index 000000000..4c0b5db56 --- /dev/null +++ b/thirdparty/rive/include/rive/input/keyboard_listener.hpp @@ -0,0 +1,27 @@ +#ifndef _RIVE_KEYBOARD_LISTENER_HPP_ +#define _RIVE_KEYBOARD_LISTENER_HPP_ +#include "rive/input/focusable.hpp" + +namespace rive +{ + +/// Interface for objects that want to be notified of key inputs on a +/// FocusData. +class KeyboardListener +{ +public: + virtual ~KeyboardListener() = default; + + /// Called when the associated FocusData receives key inputs. + virtual bool keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) = 0; + + /// Called when the associated FocusData receives text input. + virtual bool textInput(const std::string& text) = 0; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/inputs/keyboard_input.hpp b/thirdparty/rive/include/rive/inputs/keyboard_input.hpp new file mode 100644 index 000000000..8f13604f1 --- /dev/null +++ b/thirdparty/rive/include/rive/inputs/keyboard_input.hpp @@ -0,0 +1,15 @@ +#ifndef _RIVE_KEYBOARD_INPUT_HPP_ +#define _RIVE_KEYBOARD_INPUT_HPP_ +#include "rive/generated/inputs/keyboard_input_base.hpp" +#include "rive/inputs/keyboard_key_phase.hpp" +#include +namespace rive +{ +class KeyboardInput : public KeyboardInputBase +{ +public: + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/inputs/keyboard_key_phase.hpp b/thirdparty/rive/include/rive/inputs/keyboard_key_phase.hpp new file mode 100644 index 000000000..3d5d11b20 --- /dev/null +++ b/thirdparty/rive/include/rive/inputs/keyboard_key_phase.hpp @@ -0,0 +1,18 @@ +#ifndef _RIVE_KEYBOARD_KEY_PHASE_HPP_ +#define _RIVE_KEYBOARD_KEY_PHASE_HPP_ + +#include + +namespace rive +{ +/// Bitmask for \c KeyboardInputBase::keyPhase() (property key 972). +struct KeyboardKeyPhaseMask +{ + static constexpr uint32_t down = 1u << 0; + static constexpr uint32_t repeat = 1u << 1; + static constexpr uint32_t up = 1u << 2; + static constexpr uint32_t all = down | repeat | up; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/inputs/semantic_input.hpp b/thirdparty/rive/include/rive/inputs/semantic_input.hpp new file mode 100644 index 000000000..ad343eb2a --- /dev/null +++ b/thirdparty/rive/include/rive/inputs/semantic_input.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_SEMANTIC_INPUT_HPP_ +#define _RIVE_SEMANTIC_INPUT_HPP_ +#include "rive/generated/inputs/semantic_input_base.hpp" + +namespace rive +{ +class SemanticInput : public SemanticInputBase +{ +public: + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/inputs/user_input.hpp b/thirdparty/rive/include/rive/inputs/user_input.hpp new file mode 100644 index 000000000..d00a73704 --- /dev/null +++ b/thirdparty/rive/include/rive/inputs/user_input.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_USER_INPUT_HPP_ +#define _RIVE_USER_INPUT_HPP_ +#include "rive/generated/inputs/user_input_base.hpp" +#include +namespace rive +{ +class UserInput : public UserInputBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/joystick.hpp b/thirdparty/rive/include/rive/joystick.hpp index fb317e001..ce52d0e09 100644 --- a/thirdparty/rive/include/rive/joystick.hpp +++ b/thirdparty/rive/include/rive/joystick.hpp @@ -28,7 +28,7 @@ class Joystick : public JoystickBase, public IntrinsicallySizeable bool isJoystickFlagged(JoystickFlags flag) const { - return ((JoystickFlags)joystickFlags()) & flag; + return enums::any_flag_set(JoystickFlags(joystickFlags()), flag); } bool canApplyBeforeUpdate() const { return m_handleSource == nullptr; } diff --git a/thirdparty/rive/include/rive/joystick_flags.hpp b/thirdparty/rive/include/rive/joystick_flags.hpp index f4b253415..6b37b6593 100644 --- a/thirdparty/rive/include/rive/joystick_flags.hpp +++ b/thirdparty/rive/include/rive/joystick_flags.hpp @@ -1,12 +1,14 @@ #ifndef _RIVE_JOYSTICK_FLAGS_HPP_ #define _RIVE_JOYSTICK_FLAGS_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { enum class JoystickFlags : unsigned char { + none = 0, + /// Whether to invert the application of the x axis. invertX = 1 << 0, @@ -16,6 +18,5 @@ enum class JoystickFlags : unsigned char /// Whether this Joystick works in world space. worldSpace = 1 << 2 }; -RIVE_MAKE_ENUM_BITSET(JoystickFlags) } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/layout/artboard_component_list_override.hpp b/thirdparty/rive/include/rive/layout/artboard_component_list_override.hpp new file mode 100644 index 000000000..cc325750a --- /dev/null +++ b/thirdparty/rive/include/rive/layout/artboard_component_list_override.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_ARTBOARD_COMPONENT_LIST_OVERRIDE_HPP_ +#define _RIVE_ARTBOARD_COMPONENT_LIST_OVERRIDE_HPP_ +#include "rive/generated/layout/artboard_component_list_override_base.hpp" +#include "rive/layout/style_overrider.hpp" +#include +namespace rive +{ +class ArtboardInstance; +class ArtboardComponentListOverride : public ArtboardComponentListOverrideBase +{ +public: + void addArtboard(ArtboardInstance* artboard); + void removeArtboard(ArtboardInstance* artboard); + float actualInstanceWidth(ArtboardInstance* artboardInstance); + float actualInstanceHeight(ArtboardInstance* artboardInstance); + void markHostingLayoutDirty(ArtboardInstance* artboardInstance); + bool isRow(); + +protected: + void instanceWidthChanged() override; + void instanceHeightChanged() override; + void instanceWidthUnitsValueChanged() override; + void instanceHeightUnitsValueChanged() override; + void instanceWidthScaleTypeChanged() override; + void instanceHeightScaleTypeChanged() override; + +private: + std::vector m_artboards; + void updateWidthOverride(); + void updateHeightOverride(); + StyleOverrider m_styleOverrider = + StyleOverrider(this); +}; + +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/layout/layout_node_provider.hpp b/thirdparty/rive/include/rive/layout/layout_node_provider.hpp index 366511de5..4b3d0f1e7 100644 --- a/thirdparty/rive/include/rive/layout/layout_node_provider.hpp +++ b/thirdparty/rive/include/rive/layout/layout_node_provider.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_LAYOUT_NODE_PROVIDER_HPP_ #define _RIVE_LAYOUT_NODE_PROVIDER_HPP_ +#include "rive/layout/layout_enums.hpp" #include #include @@ -8,6 +9,7 @@ namespace rive { class AABB; class Component; +class KeyFrameInterpolator; class LayoutConstraint; class TransformComponent; @@ -26,10 +28,20 @@ class LayoutNodeProvider virtual AABB layoutBounds() = 0; virtual AABB layoutBoundsForNode(int index) { return layoutBounds(); } virtual bool syncStyleChanges() { return false; }; - virtual void updateLayoutBounds(bool animate = true){}; + virtual void updateLayoutBounds(bool animate = true) {}; virtual void markLayoutNodeDirty(bool shouldForceUpdateLayoutBounds = false) {} virtual size_t numLayoutNodes() = 0; +#ifdef WITH_RIVE_LAYOUT + virtual bool cascadeLayoutStyle( + LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime, + LayoutDirection direction) + { + return false; + } +#endif }; } // namespace rive diff --git a/thirdparty/rive/include/rive/layout/n_sliced_node.hpp b/thirdparty/rive/include/rive/layout/n_sliced_node.hpp index 7522aec10..834405dc0 100644 --- a/thirdparty/rive/include/rive/layout/n_sliced_node.hpp +++ b/thirdparty/rive/include/rive/layout/n_sliced_node.hpp @@ -32,6 +32,7 @@ class NSlicedNode : public NSlicedNodeBase, const Mat2D& inverseWorld) const override; Vec2D deformWorldPoint(Vec2D point) const override; Vec2D scaleForNSlicer() const; + AABB localBounds() const override; Vec2D measureLayout(float width, LayoutMeasureMode widthMode, diff --git a/thirdparty/rive/include/rive/layout/style_overrider.hpp b/thirdparty/rive/include/rive/layout/style_overrider.hpp new file mode 100644 index 000000000..13044bdc2 --- /dev/null +++ b/thirdparty/rive/include/rive/layout/style_overrider.hpp @@ -0,0 +1,103 @@ +#ifndef _RIVE_STYLE_OVERRIDER_HPP_ +#define _RIVE_STYLE_OVERRIDER_HPP_ +#include +#include "rive/artboard.hpp" +namespace rive +{ +// class ArtboardInstance; + +template class StyleOverrider +{ +public: + StyleOverrider(T* sp) : m_styleProvider(sp) {} + void updateHeightOverride(ArtboardInstance* artboardInstance) + { + + if (artboardInstance == nullptr) + { + return; + } + auto isRow = m_styleProvider->isRow(); + if (m_styleProvider->instanceHeightScaleType() == + 0) // LayoutScaleType::fixed + { + // If we're set to fixed, pass the unit value (points|percent) + artboardInstance->heightIntrinsicallySizeOverride(false); + artboardInstance->heightOverride( + actualInstanceHeight(artboardInstance), + m_styleProvider->instanceHeightUnitsValue(), + isRow); + } + else if (m_styleProvider->instanceHeightScaleType() == + 1) // LayoutScaleType::fill + { + // If we're set to fill, pass auto + artboardInstance->heightIntrinsicallySizeOverride(false); + artboardInstance->heightOverride( + actualInstanceHeight(artboardInstance), + 3, + isRow); + } + else if (m_styleProvider->instanceWidthScaleType() == 2) + { + artboardInstance->heightIntrinsicallySizeOverride(true); + } + m_styleProvider->markHostingLayoutDirty(artboardInstance); + } + void updateWidthOverride(ArtboardInstance* artboardInstance) + { + + if (artboardInstance == nullptr) + { + return; + } + auto isRow = m_styleProvider->isRow(); + if (m_styleProvider->instanceWidthScaleType() == + 0) // LayoutScaleType::fixed + { + // If we're set to fixed, pass the unit value (points|percent) + artboardInstance->widthIntrinsicallySizeOverride(false); + artboardInstance->widthOverride( + actualInstanceWidth(artboardInstance), + m_styleProvider->instanceWidthUnitsValue(), + isRow); + } + else if (m_styleProvider->instanceWidthScaleType() == + 1) // LayoutScaleType::fill + { + // If we're set to fill, pass auto + artboardInstance->widthIntrinsicallySizeOverride(false); + artboardInstance->widthOverride( + actualInstanceWidth(artboardInstance), + 3, + isRow); + } + else if (m_styleProvider->instanceWidthScaleType() == 2) + { + artboardInstance->widthIntrinsicallySizeOverride(true); + } + m_styleProvider->markHostingLayoutDirty(artboardInstance); + } + float actualInstanceWidth(ArtboardInstance* artboardInstance) + { + + return m_styleProvider->instanceWidth() == -1.0f + ? artboardInstance->originalWidth() + : m_styleProvider->instanceWidth(); + } + float actualInstanceHeight(ArtboardInstance* artboardInstance) + { + + return m_styleProvider->instanceHeight() == -1.0f + ? artboardInstance->originalHeight() + : m_styleProvider->instanceHeight(); + } + +private: +protected: + T* m_styleProvider = nullptr; +}; + +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/layout_component.hpp b/thirdparty/rive/include/rive/layout_component.hpp index bceb361a2..f599bd1d4 100644 --- a/thirdparty/rive/include/rive/layout_component.hpp +++ b/thirdparty/rive/include/rive/layout_component.hpp @@ -118,7 +118,7 @@ class LayoutComponent : public LayoutComponentBase, ShapePaintPath m_localPath; ShapePaintPath m_worldPath; DrawableProxy m_proxy; - bool m_displayHidden = false; + bool m_justAddedToHost = false; Artboard* getArtboard() override { return artboard(); } LayoutAnimationData* currentAnimationData(); @@ -136,13 +136,14 @@ class LayoutComponent : public LayoutComponentBase, } return nullptr; } - bool isDisplayHidden() const; + bool isCollapsed() const override; void propagateCollapse(bool collapse); bool collapse(bool value) override; float computedLocalX() override { return m_layout.left(); }; float computedLocalY() override { return m_layout.top(); }; float computedWidth() override { return m_layout.width(); }; float computedHeight() override { return m_layout.height(); }; + void calculateLayoutInternal(float availableWidth, float availableHeight); private: float m_widthOverride = NAN; @@ -155,13 +156,14 @@ class LayoutComponent : public LayoutComponentBase, float m_forcedWidth = NAN; float m_forcedHeight = NAN; bool m_forceUpdateLayoutBounds = false; + bool m_positionLeftChanged = true; + bool m_positionTopChanged = true; #ifdef WITH_RIVE_LAYOUT protected: void propagateSizeToChildren(ContainerComponent* component); bool applyInterpolation(float elapsedSeconds, bool animate = true); - void calculateLayout(); - bool styleDisplayHidden(); + bool styleDisplayHidden() const; #endif public: @@ -178,6 +180,9 @@ class LayoutComponent : public LayoutComponentBase, void drawProxy(Renderer* renderer) override; bool isProxyHidden() override { return isHidden(); } Core* hitTest(HitInfo*, const Mat2D&) override; + bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) override; DrawableProxy* proxy() { return &m_proxy; }; virtual void updateRenderPath(); void update(ComponentDirt value) override; @@ -190,11 +195,12 @@ class LayoutComponent : public LayoutComponentBase, m_layout.height()); } size_t numLayoutNodes() override { return 1; } + AABB constraintBounds() const override { return localBounds(); } AABB localBounds() const override { return AABB::fromLTWH(0.0f, 0.0f, m_layout.width(), m_layout.height()); } - AABB worldBounds() const + virtual AABB worldBounds() const { auto transform = worldTransform(); return AABB::fromLTWH(transform[4], @@ -276,7 +282,7 @@ class LayoutComponent : public LayoutComponentBase, bool cascadeLayoutStyle(LayoutStyleInterpolation inheritedInterpolation, KeyFrameInterpolator* inheritedInterpolator, float inheritedInterpolationTime, - LayoutDirection direction); + LayoutDirection direction) override; bool setInheritedInterpolation( LayoutStyleInterpolation inheritedInterpolation, KeyFrameInterpolator* inheritedInterpolator, @@ -291,6 +297,9 @@ class LayoutComponent : public LayoutComponentBase, void directionChanged(); LayoutDirection actualDirection(); #endif + + void markPositionLeftChanged() { m_positionLeftChanged = true; } + void markPositionTopChanged() { m_positionTopChanged = true; } void buildDependencies() override; void markLayoutNodeDirty( diff --git a/thirdparty/rive/include/rive/listener_group.hpp b/thirdparty/rive/include/rive/listener_group.hpp new file mode 100644 index 000000000..d860b7ca2 --- /dev/null +++ b/thirdparty/rive/include/rive/listener_group.hpp @@ -0,0 +1,108 @@ +#ifndef _RIVE_LISTENER_GROUP_HPP_ +#define _RIVE_LISTENER_GROUP_HPP_ + +#include +#include +#include "rive/animation/state_machine_instance.hpp" +#include "rive/core.hpp" +#include "rive/gesture_click_phase.hpp" +#include "rive/listener_type.hpp" +#include "rive/math/vec2d.hpp" +#include "rive/process_event_result.hpp" + +namespace rive +{ +class Component; +class HitComponent; +class StateMachineListener; + +class _PointerData +{ +public: + bool isHovered = false; + bool isPrevHovered = false; + GestureClickPhase phase = GestureClickPhase::out; + Vec2D* previousPosition() { return &m_previousPosition; } + +private: + // A vector storing the previous position for this pointer data + Vec2D m_previousPosition = Vec2D(0, 0); +}; + +class ListenerGroup +{ +public: + ListenerGroup(const StateMachineListener* listener) : m_listener(listener) + {} + virtual ~ListenerGroup(); + _PointerData* pointerData(int id); + void consume() { m_isConsumed = true; } + void hover(int id); + void reset(int pointerId); + void releaseEvent(int pointerId); + virtual void enable(int pointerId = 0); + virtual void disable(int pointerId = 0); + bool isConsumed() { return m_isConsumed; } + virtual bool canEarlyOut(Component* drawable); + virtual bool needsDownListener(Component* drawable); + virtual bool needsUpListener(Component* drawable); + + virtual ProcessEventResult processEvent( + Component* component, + Vec2D position, + int pointerId, + ListenerType hitEvent, + bool canHit, + float timeStamp, + StateMachineInstance* stateMachineInstance); + const StateMachineListener* listener() const { return m_listener; }; + +private: + // Consumed listeners aren't processed again in the current frame + bool m_isConsumed = false; + bool m_hasDragged = false; + const StateMachineListener* m_listener; + std::unordered_map m_pointers; + std::vector<_PointerData*> m_pointersPool; +}; + +class HitTarget +{ +private: + Component* m_component = nullptr; + bool m_isOpaque = false; + +public: + HitTarget(Component* component, bool isOpaque) : + m_component(component), m_isOpaque(isOpaque) + {} + Component* component() { return m_component; } + bool isOpaque() { return m_isOpaque; } +}; + +class ListenerGroupWithTargets +{ +private: + ListenerGroup* m_group = nullptr; + std::vector m_targets; + +public: + ListenerGroupWithTargets(ListenerGroup* group, + std::vector targets) : + m_group(group), m_targets(targets) + {} + ListenerGroup* group() { return m_group; } + std::vector targets() { return m_targets; } +}; + +class ListenerGroupProvider +{ +public: + static ListenerGroupProvider* from(Core* component); + virtual std::vector listenerGroups() = 0; + virtual std::vector hitComponents( + StateMachineInstance* sm) = 0; +}; + +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/listener_type.hpp b/thirdparty/rive/include/rive/listener_type.hpp index d31902e5c..38393e13b 100644 --- a/thirdparty/rive/include/rive/listener_type.hpp +++ b/thirdparty/rive/include/rive/listener_type.hpp @@ -11,7 +11,16 @@ enum class ListenerType : int move = 4, event = 5, click = 6, - draggableConstraint = 7, + componentProvided = 7, + textInput = 8, + dragStart = 9, + dragEnd = 10, + viewModel = 11, + drag = 12, + focus = 13, + blur = 14, + keyboard = 15, + semanticAction = 16, }; } #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/lua/lua_state.hpp b/thirdparty/rive/include/rive/lua/lua_state.hpp new file mode 100644 index 000000000..985cc3389 --- /dev/null +++ b/thirdparty/rive/include/rive/lua/lua_state.hpp @@ -0,0 +1,18 @@ +#ifndef _RIVE_LUA_STATE_HPP_ +#define _RIVE_LUA_STATE_HPP_ + +#ifdef WITH_RIVE_SCRIPTING +#include "lua.h" +#endif +#include + +namespace rive +{ +class ViewModel; + +#ifdef WITH_RIVE_SCRIPTING +void initializeLuaData(lua_State* state, std::vector& viewModels); +#endif + +} // namespace rive +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/lua/rive_lua_libs.hpp b/thirdparty/rive/include/rive/lua/rive_lua_libs.hpp new file mode 100644 index 000000000..da8d780b0 --- /dev/null +++ b/thirdparty/rive/include/rive/lua/rive_lua_libs.hpp @@ -0,0 +1,2093 @@ +#ifdef WITH_RIVE_SCRIPTING +#ifndef _RIVE_LUA_LIBS_HPP_ +#define _RIVE_LUA_LIBS_HPP_ +#include "lua.h" +#include "lualib.h" +#include "rive/animation/linear_animation_instance.hpp" +#include "rive/assets/file_asset.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/lua/lua_state.hpp" +#include "rive/math/raw_path.hpp" +#include "rive/renderer.hpp" +#include "rive/math/vec2d.hpp" +#include "rive/math/mat4.hpp" +#include "rive/math/contour_measure.hpp" +#include "rive/math/path_measure.hpp" +#include "rive/shapes/paint/image_sampler.hpp" +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/viewmodel_instance_asset_image.hpp" +#include "rive/viewmodel/viewmodel_instance_boolean.hpp" +#include "rive/viewmodel/viewmodel_instance_color.hpp" +#include "rive/viewmodel/viewmodel_instance_enum.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance_color.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" +#include "rive/viewmodel/viewmodel_instance_string.hpp" +#include "rive/viewmodel/viewmodel_instance_trigger.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" +#include "rive/data_bind/data_values/data_value_list.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/animation/listener_invocation.hpp" +#include "rive/hit_result.hpp" +#include "rive/lua/scripting_vm.hpp" +#include "rive/refcnt.hpp" +#ifdef WITH_RIVE_AUDIO +#include "rive/audio/audio_engine.hpp" +#include "rive/audio/audio_source.hpp" +#include "rive/audio/audio_sound.hpp" +#endif +#ifdef WITH_RIVE_TOOLS +#include "rive/core/binary_writer.hpp" +#include "rive/core/vector_binary_stream.hpp" +#endif + +#include +#include +#include +#include +#include +#include +#include + +static const int maxCStack = 8000; +static const int luaGlobalsIndex = -maxCStack - 2002; +static const int luaRegistryIndex = -maxCStack - 2000; + +namespace rive +{ +class Artboard; +class ArtboardInstance; +class Factory; +class File; +class ModuleDetails; +class ScriptedObject; +class StateMachineInstance; +class TransformComponent; +enum class LuaAtoms : int16_t +{ + // Vector + length, + lengthSquared, + normalized, + distance, + distanceSquared, + dot, + lerp, + + // Path + moveTo, + lineTo, + quadTo, + cubicTo, + close, + reset, + add, + contours, + measure, + + // Path Command + type, + points, + + // Mat2D + invert, + isIdentity, + + // Image + width, + height, + + // ImageSampler + clamp, + repeat, + mirror, + bilinear, + nearest, + + // Paint + style, + join, + cap, + thickness, + blendMode, + feather, + gradient, + color, + + stroke, + fill, + miter, + round, + bevel, + butt, + square, + srcOver, + screen, + overlay, + darken, + lighten, + colorDodge, + colorBurn, + hardLight, + softLight, + difference, + exclusion, + multiply, + hue, + saturation, + luminosity, + copy, + + // Renderer + drawPath, + drawImage, + drawImageMesh, + clipPath, + save, + restore, + transform, + + // Scripted Properties + value, + red, + green, + blue, + alpha, + getNumber, + getTrigger, + getString, + getBoolean, + getColor, + getList, + getViewModel, + getEnum, + getIndex, + getImage, + values, + addListener, + removeListener, + fire, + push, + insert, + shift, + pop, + swap, + clear, + + // Artboards + draw, + advance, + frameOrigin, + data, + instance, + animation, + newAtom, + bounds, + pointerDown, + pointerMove, + pointerUp, + pointerExit, + addToPath, + name, + + // Scripted DataValues + isNumber, + isString, + isBoolean, + isColor, + + // inputs + hit, + id, + position, + + // nodes + rotation, + scale, + worldTransform, + scaleX, + scaleY, + decompose, + children, + parent, + node, + paint, + asPaint, + asPath, + + // PathMeasure/ContourMeasure + positionAndTangent, + warp, + extract, + next, + isClosed, + + // Scripted Context + markNeedsUpdate, + viewModel, + rootViewModel, + image, + blob, + size, + dataContext, + audio, + play, + playAtTime, + playInTime, + playAtFrame, + playInFrame, + stop, + pause, + resume, + seek, + seekFrame, + volume, + completed, + time, + timeFrame, + sampleRate, + + // Animation + duration, + setTime, + setTimeFrames, + setTimePercentage, + + // PointerEvent (append to avoid shifting existing atom ids) + previousPosition, + timeStamp, + + // ScriptedInvocation / listener payloads (append only) + isPointerEvent, + isKeyboardEvent, + isTextInput, + isFocus, + isReportedEvent, + isViewModelChange, + isNone, + isGamepad, + asPointerEvent, + asKeyboardEvent, + asTextInput, + asFocus, + asReportedEvent, + asViewModelChange, + asGamepad, + asNone, + key, + alt, + control, + meta, + text, + phase, + delaySeconds, + deviceId, + buttonMask, + axis0, + remove, + removeAt, + removeAllOf, + + // GPU bindings + write, + upload, + view, + setPipeline, + setVertexBuffer, + setIndexBuffer, + setBindGroup, + setViewport, + setScissorRect, + setStencilReference, + setBlendColor, + drawIndexed, + finish, + beginRenderPass, + beginFrame, + endFrame, + colorView, + depthView, + resize, + canvas, + gpuCanvas, + drawCanvas, + features, + loadShader, + format, + preferredCanvasFormat, + + // Promise + andThen, + catch_, + finally_, + cancel, + onCancel, + getStatus, + + // Image decode + decodeImage, + + // Mat4 + transpose, + transformPoint, + transformVec4, + writeToBuffer, + invertAffine, +}; + +struct ScriptedMat2D +{ + static constexpr uint8_t luaTag = LUA_T_COUNT + 1; + static constexpr const char* luaName = "Mat2D"; + static constexpr bool hasMetatable = true; + + ScriptedMat2D(float x1, float y1, float x2, float y2, float tx, float ty) : + value(x1, y1, x2, y2, tx, ty) + {} + + ScriptedMat2D(const Mat2D& mat) : value(mat) {} + + ScriptedMat2D() {} + + rive::Mat2D value; +}; + +static_assert(std::is_trivially_destructible::value, + "ScriptedMat2D must be trivially destructible"); + +struct ScriptedMat4 +{ + static constexpr uint8_t luaTag = LUA_T_COUNT + 62; + static constexpr const char* luaName = "Mat4"; + static constexpr bool hasMetatable = true; + + ScriptedMat4() {} + ScriptedMat4(const Mat4& mat) : value(mat) {} + + rive::Mat4 value; +}; + +static_assert(std::is_trivially_destructible::value, + "ScriptedMat4 must be trivially destructible"); + +class ScriptedPathCommand +{ +public: + ScriptedPathCommand(std::string type, std::vector points = {}) : + m_type(type), m_points(points) + {} + static constexpr uint8_t luaTag = LUA_T_COUNT + 29; + static constexpr const char* luaName = "PathCommand"; + static constexpr bool hasMetatable = true; + std::string type() { return m_type; } + std::vector points() { return m_points; } + +private: + std::string m_type; + std::vector m_points; +}; + +class ScriptedPathData +{ +public: + ScriptedPathData() {} + ScriptedPathData(const RawPath* path); + int totalCommands(); + void markDirty() { m_isRenderPathDirty = true; } + RawPath rawPath; + static constexpr uint8_t luaTag = LUA_T_COUNT + 30; + static constexpr const char* luaName = "PathData"; + static constexpr bool hasMetatable = true; + RenderPath* renderPath(lua_State* L); + +protected: + rcp m_renderPath; + + bool m_isRenderPathDirty = true; + +private: + uint64_t m_renderFrameId = 0; +}; + +class ScriptedPath : public ScriptedPathData +{ +public: + ScriptedPath() {} + ScriptedPath(const RawPath* path) : ScriptedPathData(path) {} + static constexpr uint8_t luaTag = LUA_T_COUNT + 2; + static constexpr const char* luaName = "Path"; + static constexpr bool hasMetatable = true; +}; + +class ScriptedGradient +{ +public: + rcp shader; + static constexpr uint8_t luaTag = LUA_T_COUNT + 3; + static constexpr const char* luaName = "Gradient"; + static constexpr bool hasMetatable = false; +}; + +class ScriptedVertexBuffer +{ +public: + std::vector values; + rcp vertexBuffer; + static constexpr uint8_t luaTag = LUA_T_COUNT + 4; + static constexpr const char* luaName = "VertexBuffer"; + static constexpr bool hasMetatable = true; + + void update(Factory* factory); +}; + +class ScriptedTriangleBuffer +{ +public: + std::vector values; + rcp indexBuffer; + static constexpr uint8_t luaTag = LUA_T_COUNT + 5; + static constexpr const char* luaName = "TriangleBuffer"; + static constexpr bool hasMetatable = true; + + uint16_t max = 0; + void update(Factory* factory); +}; + +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) +namespace ore +{ +class TextureView; +} +#endif + +class ScriptedImage +{ +public: + rcp image; +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) + rcp cachedOreView; // Cached for Image:view() to avoid + // leaking D3D12 CPU descriptors. +#if defined(ORE_BACKEND_GL) + // GL only: when the source image is a Rive 2D RenderCanvas, the GL + // backend's getCanvasImportMirror returns a Y-flipped companion + // image. We hold a strong rcp here so the companion stays alive for + // the lifetime of this ScriptedImage. The view in cachedOreView wraps + // the companion's texture, not the source's. + rcp cachedMirrorImage; +#endif +#endif + // Out-of-line destructor — when ore is enabled, defined in lua_gpu.cpp + // where ore::TextureView is complete. Otherwise defined in lua_image.cpp. + ~ScriptedImage(); + // Out-of-line factory — avoids instantiating rcp::~rcp() in + // TUs that don't include the full ore headers (placement new requires a + // visible destructor for exception cleanup). + static ScriptedImage* luaNew(lua_State* L); + static constexpr uint8_t luaTag = LUA_T_COUNT + 6; + static constexpr const char* luaName = "Image"; + static constexpr bool hasMetatable = true; +}; + +class ScriptedBlob +{ +public: + rcp asset; // Holds ref to keep BlobAsset alive + + static constexpr uint8_t luaTag = LUA_T_COUNT + 35; + static constexpr const char* luaName = "Blob"; + static constexpr bool hasMetatable = true; +}; + +#ifdef WITH_RIVE_AUDIO + +class ScriptedAudio +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 40; + static constexpr const char* luaName = "Audio"; + static constexpr bool hasMetatable = true; +}; + +class ScriptedAudioSource +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 38; + static constexpr const char* luaName = "AudioSource"; + static constexpr bool hasMetatable = true; + void source(rcp); + rcp source() { return m_source; } + int play(lua_State*, AudioEngine*); + int play(lua_State*, AudioEngine*, double, bool); + int playFrame(lua_State*, AudioEngine*); + int playFrame(lua_State*, AudioEngine*, uint64_t, bool); + +private: + rcp m_source; + int initializeSound(lua_State*, rcp, Artboard*); +}; + +class ScriptedAudioSound +{ +public: + ScriptedAudioSound(Artboard* artboard) : m_artboard(artboard) {} + rcp sound; + static constexpr uint8_t luaTag = LUA_T_COUNT + 39; + static constexpr const char* luaName = "AudioSound"; + static constexpr bool hasMetatable = true; + Artboard* artboard() { return m_artboard; } + +private: + Artboard* m_artboard = nullptr; +}; +#endif + +#ifdef RIVE_CANVAS +namespace gpu +{ +class RenderCanvas; +class RenderContext; +} // namespace gpu + +// Forward-declare RiveRenderer so canvas handles can store a raw pointer to the +// active frame renderer without pulling in the full rive_renderer.hpp header. +class RiveRenderer; + +#ifdef RIVE_ORE +namespace ore +{ +class Buffer; +class Texture; +class TextureView; +class Sampler; +class BindGroup; +class BindGroupLayout; +class ShaderModule; +class Pipeline; +class RenderPass; +class Context; +} // namespace ore + +class ScriptedGPUBuffer +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 41; + static constexpr const char* luaName = "GPUBuffer"; + static constexpr bool hasMetatable = true; + rcp buffer; + // Set when constructed with `immutable=true`. The Lua wrapper rejects + // `:write` calls on immutable buffers — matching `BufferDesc::immutable`'s + // documented contract ("no update() calls allowed after creation"). + bool immutable = false; +}; + +class ScriptedGPUTexture +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 42; + static constexpr const char* luaName = "GPUTexture"; + static constexpr bool hasMetatable = true; + rcp texture; +}; + +class ScriptedGPUSampler +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 43; + static constexpr const char* luaName = "GPUSampler"; + static constexpr bool hasMetatable = false; + rcp sampler; +}; + +class ScriptedShader +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 44; + static constexpr const char* luaName = "Shader"; + static constexpr bool hasMetatable = false; + rcp module; // vertex module (or combined) + rcp fragmentModule; // fragment module (null if combined) + + // Returns the module to use for a given pipeline stage. + ore::ShaderModule* vertexMod() const { return module.get(); } + ore::ShaderModule* fragmentMod() const + { + return fragmentModule ? fragmentModule.get() : module.get(); + } +}; + +class ScriptedGPUPipeline +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 45; + static constexpr const char* luaName = "GPUPipeline"; + static constexpr bool hasMetatable = true; + rcp pipeline; + uint32_t sampleCount = 1; + + // Deep-copied vertex layout data so Pipeline's PipelineDesc pointers + // remain valid for the lifetime of this object. Stored as raw bytes to + // avoid pulling ore_types.hpp into this header. + std::vector ownedVertexLayoutData; + + // Auto-derived layouts (one per @group(N) in the shader) when the user + // omits `bindGroupLayouts`. Exposed via `pipeline:getBindGroupLayout(N)`. + // Empty when explicit layouts were supplied. + std::vector> autoBindGroupLayouts; +}; + +class ScriptedGPUBindGroup +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 52; + static constexpr const char* luaName = "GPUBindGroup"; + static constexpr bool hasMetatable = false; + ~ScriptedGPUBindGroup(); // Defers destruction via + // Context::deferBindGroupDestroy. + rcp bindGroup; +}; + +class ScriptedGPUBindGroupLayout +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 60; + static constexpr const char* luaName = "GPUBindGroupLayout"; + static constexpr bool hasMetatable = false; + rcp layout; +}; + +class ScriptedGPURenderPass +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 46; + static constexpr const char* luaName = "GPURenderPass"; + static constexpr bool hasMetatable = true; + ~ScriptedGPURenderPass(); + // `pass` is owned by `ScriptedGPUCanvas::m_activePass`. To prevent + // the canvas from being GC'd before this render pass — which would + // delete `m_activePass` and dangle this pointer — the constructor + // site stores a Lua ref to the owning canvas in `m_canvasRef`, + // released by `~ScriptedGPURenderPass`. + ore::RenderPass* pass = nullptr; + bool m_finished = false; + bool m_pipelineSet = false; + uint32_t sampleCount = 1; // for pipeline sampleCount validation + std::string label; + uint32_t drawCallCount = 0; + lua_State* m_L = nullptr; + int m_canvasRef = LUA_NOREF; +}; + +class ScriptedGPUTextureView +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 51; + static constexpr const char* luaName = "GPUTextureView"; + static constexpr bool hasMetatable = false; + rcp view; + // When created from Image:view(), retains the RenderImage so the + // underlying gpu::Texture stays alive even if the Image is GC'd. + rcp retainedImage; +}; + +class ScriptedGPUCanvas +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 47; + static constexpr const char* luaName = "GPUCanvas"; + static constexpr bool hasMetatable = true; + ~ScriptedGPUCanvas(); + rcp canvas; + // 1× resolve target (platform backing texture). + rcp oreColorView; + // MSAA color attachment — non-null when canvas was created with sampleCount + // > 1. + rcp oreMSAAColorTexture; + rcp oreMSAAColorView; + rcp oreDepthTexture; + rcp oreDepthView; + lua_State* m_L = nullptr; + int m_imageRef = LUA_NOREF; + ore::RenderPass* m_activePass = nullptr; // heap-allocated, owned by this + std::string m_activePassLabel; // label of m_activePass for diagnostics + gpu::RenderContext* renderCtx = nullptr; // needed for resize() +}; + +#endif // RIVE_ORE + +enum class CanvasState +{ + Idle, + Rendering +}; + +class ScriptedCanvas +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 50; + static constexpr const char* luaName = "Canvas"; + static constexpr bool hasMetatable = true; + ~ScriptedCanvas(); + rcp canvas; + lua_State* m_L = nullptr; + int m_imageRef = LUA_NOREF; + gpu::RenderContext* renderCtx = nullptr; + CanvasState m_state = CanvasState::Idle; + // Allocated on beginFrame(), deleted on endFrame(). Wraps renderCtx. + RiveRenderer* m_riveRenderer = nullptr; + // Lua registry ref to the ScriptedRenderer pushed by beginFrame(), + // kept alive until endFrame() so the Lua renderer stays valid. + int m_rendererRef = LUA_NOREF; +}; +#endif // RIVE_CANVAS + +// ── Promise ──────────────────────────────────────────────────────────────── + +enum class PromiseState : uint8_t +{ + Pending, + Fulfilled, + Rejected, + Cancelled +}; + +class ScriptedPromise +{ +public: + static constexpr uint8_t luaTag = LUA_T_COUNT + 53; + static constexpr const char* luaName = "Promise"; + static constexpr bool hasMetatable = true; + + ScriptedPromise(lua_State* mainThread) : m_state(mainThread) {} + ~ScriptedPromise(); + + void resolve(lua_State* L, int valueIdx); + // Overload with selfRef: a registry ref to this promise's userdata, + // needed for Promise/A+ adoption of pending inner promises. + void resolve(lua_State* L, int valueIdx, int selfRef); + void reject(lua_State* L, int errorIdx); + void cancel(lua_State* L); + + bool isFulfilled() const + { + return m_promiseState == PromiseState::Fulfilled; + } + bool isRejected() const { return m_promiseState == PromiseState::Rejected; } + bool isCancelled() const + { + return m_promiseState == PromiseState::Cancelled; + } + bool isPending() const { return m_promiseState == PromiseState::Pending; } + int resultRef() const { return m_resultRef; } + + lua_State* m_state; + PromiseState m_promiseState = PromiseState::Pending; + int m_resultRef = LUA_NOREF; + + struct ThenCallback + { + int successRef = LUA_NOREF; + int failureRef = LUA_NOREF; + int chainedPromiseRef = LUA_NOREF; // registry ref keeps it alive + int cancelRef = + LUA_NOREF; // cleanup callback fired on cancel (async/await) + }; + struct FinallyCallback + { + int callbackRef = LUA_NOREF; + int chainedPromiseRef = LUA_NOREF; // registry ref keeps it alive + }; + + std::vector m_thenCallbacks; + std::vector m_finallyCallbacks; + + // Parent promise (the promise this was chained FROM via + // andThen/catch/finally). + int m_parentRef = LUA_NOREF; + + // Consumer promises (chained FROM this one). Separate refs from + // ThenCallback.chainedPromiseRef for independent cancel propagation. + std::vector m_consumerRefs; + + // Cancellation hook: a Lua function called when cancel() fires. + // Used by decodeImage to cancel in-flight work, and by Promise.all + // to cancel chained promises. + int m_onCancelRef = LUA_NOREF; +}; + +int luaopen_rive_promise(lua_State* L); + +// ── ImageSampler ─────────────────────────────────────────────────────────── + +class ScriptedImageSampler +{ +public: + ImageSampler sampler; + + ScriptedImageSampler(ImageWrap wx, ImageWrap wy, ImageFilter f) + { + sampler.wrapX = wx; + sampler.wrapY = wy; + sampler.filter = f; + } + + static constexpr uint8_t luaTag = LUA_T_COUNT + 7; + static constexpr const char* luaName = "ImageSampler"; + static constexpr bool hasMetatable = false; +}; + +class ScriptedPaintData +{ +public: + ScriptedPaintData(); + ScriptedPaintData(const ShapePaint* shapePaint); + virtual ~ScriptedPaintData() = default; + + static constexpr uint8_t luaTag = LUA_T_COUNT + 33; + static constexpr const char* luaName = "PaintData"; + static constexpr bool hasMetatable = true; + + virtual void style(RenderPaintStyle style) { m_style = style; } + + virtual void color(ColorInt value) { m_color = value; } + virtual void thickness(float value) { m_thickness = value; } + + virtual void join(StrokeJoin value) { m_join = value; } + + virtual void cap(StrokeCap value) { m_cap = value; } + + virtual void feather(float value) { m_feather = value; } + + virtual void blendMode(BlendMode value) { m_blendMode = value; } + + virtual void gradient(rcp value) { m_gradient = value; } + + void pushStyle(lua_State* L); + void pushJoin(lua_State* L); + void pushCap(lua_State* L); + void pushThickness(lua_State* L); + void pushBlendMode(lua_State* L); + void pushFeather(lua_State* L); + void pushGradient(lua_State* L); + void pushColor(lua_State* L); + +protected: + RenderPaintStyle m_style = RenderPaintStyle::fill; + rcp m_gradient; + float m_thickness = 1; + StrokeJoin m_join = StrokeJoin::miter; + StrokeCap m_cap = StrokeCap::butt; + float m_feather = 0; + BlendMode m_blendMode = BlendMode::srcOver; + ColorInt m_color = 0xFF000000; +}; + +class ScriptedPaint : public ScriptedPaintData +{ +public: + ScriptedPaint(Factory* factory); + ScriptedPaint(Factory* factory, const ScriptedPaint& source); + virtual ~ScriptedPaint() = default; + rcp renderPaint; + + static constexpr uint8_t luaTag = LUA_T_COUNT + 8; + static constexpr const char* luaName = "Paint"; + static constexpr bool hasMetatable = true; + + void style(RenderPaintStyle style) override + { + ScriptedPaintData::style(style); + renderPaint->style(style); + } + + void color(ColorInt value) override + { + ScriptedPaintData::color(value); + renderPaint->color(value); + } + void thickness(float value) override + { + ScriptedPaintData::thickness(value); + renderPaint->thickness(value); + } + + void join(StrokeJoin value) override + { + ScriptedPaintData::join(value); + renderPaint->join(value); + } + + void cap(StrokeCap value) override + { + ScriptedPaintData::cap(value); + renderPaint->cap(value); + } + + void feather(float value) override + { + ScriptedPaintData::feather(value); + renderPaint->feather(value); + } + + void blendMode(BlendMode value) override + { + ScriptedPaintData::blendMode(value); + renderPaint->blendMode(value); + } + + void gradient(rcp value) override + { + ScriptedPaintData::gradient(value); + renderPaint->shader(value); + } +}; + +class ScriptedRenderer +{ +public: + ScriptedRenderer(Renderer* renderer) : m_renderer(renderer), m_saveCount(0) + {} + + // End usage of this ScriptedRenderer. + bool end(); + + void save(lua_State* L); + void restore(lua_State* L); + void transform(lua_State* L, const Mat2D& mat2d); + void clipPath(lua_State* L, ScriptedPathData* path); + Renderer* validate(lua_State* L); + + static constexpr uint8_t luaTag = LUA_T_COUNT + 9; + static constexpr const char* luaName = "Renderer"; + static constexpr bool hasMetatable = true; + +private: + // Not owned by the ScriptedRenderer, only valid when passed in. + Renderer* m_renderer = nullptr; + uint32_t m_saveCount = 0; +}; + +class ScriptReffedArtboard : public RefCnt +{ +public: + ScriptReffedArtboard(rcp file, + std::unique_ptr&& artboardInstance, + rcp viewModelInstance, + rcp parentDataContext); + + ~ScriptReffedArtboard(); + rive::rcp file(); + Artboard* artboard(); + StateMachineInstance* stateMachine(); + rcp viewModelInstance() { return m_viewModelInstance; } + +private: + rcp m_file; + std::unique_ptr m_artboard; + std::unique_ptr m_stateMachine; + rcp m_viewModelInstance; +}; + +class ScriptedArtboard +{ +public: + ScriptedArtboard(lua_State* L, + rcp file, + std::unique_ptr&& artboardInstance, + rcp viewModelInstance, + rcp dataContext); + ~ScriptedArtboard(); + + static constexpr uint8_t luaTag = LUA_T_COUNT + 10; + static constexpr const char* luaName = "Artboard"; + static constexpr bool hasMetatable = true; + + Artboard* artboard() { return m_scriptReffedArtboard->artboard(); } + StateMachineInstance* stateMachine() + { + return m_scriptReffedArtboard->stateMachine(); + } + rcp viewModelInstance() + { + return m_scriptReffedArtboard->viewModelInstance(); + } + + rcp scriptReffedArtboard() + { + return m_scriptReffedArtboard; + } + + int pushData(lua_State* L); + int instance(lua_State* L, rcp viewModelInstance); + int animation(lua_State* L, const char* animationName); + + bool advance(float seconds); + + void cleanupDataRef(lua_State* L); + +private: + lua_State* m_state = nullptr; + rcp m_scriptReffedArtboard = nullptr; + rcp m_dataContext = nullptr; + int m_dataRef = 0; +}; + +class ScriptedAnimation +{ +public: + ScriptedAnimation(lua_State* L, + std::unique_ptr animation); + + static constexpr uint8_t luaTag = LUA_T_COUNT + 32; + static constexpr const char* luaName = "Animation"; + static constexpr bool hasMetatable = true; + float duration(); + int advance(); + int setTime(std::string mode); + +private: + lua_State* m_state; + std::unique_ptr m_animation; +}; + +// Each listener keeps a registry ref to the property userdata (self) so Luau +// cannot collect ScriptedProperty while callbacks are registered. Released in +// clearListeners / removeListener alongside function and optional userdata +// refs. +struct ScriptedListener +{ + int function; + int userdata; + int propertySelfRef; +}; + +class ScriptedProperty : public ViewModelInstanceValueDelegate +{ +public: + ScriptedProperty(lua_State* L, rcp value); + virtual ~ScriptedProperty(); + int addListener(); + int removeListener(); + void clearListeners(); + virtual void dispose(); + + void valueChanged() override; + + const lua_State* state() const { return m_state; } + + ViewModelInstanceValue* instanceValue() { return m_instanceValue.get(); } + ScriptedObject* owner() const { return m_owner; } + +private: + std::vector m_listeners; + ScriptedObject* m_owner = nullptr; +#ifdef WITH_RIVE_TOOLS + ScriptingContext* m_orphanContext = nullptr; +#endif + bool m_disposed = false; + +protected: + lua_State* m_state; + rcp m_instanceValue; +}; + +class ScriptedViewModel +{ +public: + ScriptedViewModel(lua_State* L, + rcp viewModel, + rcp viewModelInstance); + ~ScriptedViewModel(); + static constexpr uint8_t luaTag = LUA_T_COUNT + 11; + static constexpr const char* luaName = "ViewModel"; + static constexpr bool hasMetatable = true; + int pushValue(const char* name, int coreType = 0); + int pushIndex(); + int instance(lua_State* L); + + const lua_State* state() const { return m_state; } + rcp viewModelInstance() const + { + return m_viewModelInstance; + } + rcp mutableViewModelInstance() + { + return m_viewModelInstance; + } + +private: + lua_State* m_state; + rcp m_viewModel; + rcp m_viewModelInstance; + std::unordered_map m_propertyRefs; +}; + +class ScriptedPropertyViewModel : public ScriptedProperty, + public ViewModelValueDependent +{ +public: + ScriptedPropertyViewModel(lua_State* L, + rcp viewModel, + rcp value); + ~ScriptedPropertyViewModel(); + static constexpr uint8_t luaTag = LUA_T_COUNT + 12; + static constexpr const char* luaName = "PropertyViewModel"; + static constexpr bool hasMetatable = true; + int pushValue(); + void setValue(ScriptedViewModel*); + void dispose() override; + void relinkDataBind() override; + void addDirt(ComponentDirt value, bool recurse) override {} + void clearRef(); + +private: + rcp m_viewModel; + int m_valueRef = 0; +}; + +class ScriptedPropertyNumber : public ScriptedProperty +{ +public: + ScriptedPropertyNumber(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 13; + static constexpr const char* luaName = "Property"; + static constexpr bool hasMetatable = true; + + int pushValue(); + void setValue(float value); +}; + +class ScriptedPropertyTrigger : public ScriptedProperty +{ +public: + ScriptedPropertyTrigger(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 14; + static constexpr const char* luaName = "PropertyTrigger"; + static constexpr bool hasMetatable = true; +}; + +class ScriptedPropertyList : public ScriptedProperty +{ +public: + ScriptedPropertyList(lua_State* L, rcp value); + ~ScriptedPropertyList(); + static constexpr uint8_t luaTag = LUA_T_COUNT + 15; + static constexpr const char* luaName = "PropertyList"; + static constexpr bool hasMetatable = true; + + int pushLength(); + int pushValue(int index); + void valueChanged() override; + void append(ViewModelInstance*); + +private: + bool m_changed = false; + std::unordered_map m_propertyRefs; +}; + +class ScriptedPropertyColor : public ScriptedProperty +{ +public: + ScriptedPropertyColor(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 16; + static constexpr const char* luaName = "PropertyColor"; + static constexpr bool hasMetatable = true; + + int pushValue(); + void setValue(unsigned value); +}; + +class ScriptedPropertyString : public ScriptedProperty +{ +public: + ScriptedPropertyString(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 17; + static constexpr const char* luaName = "PropertyString"; + static constexpr bool hasMetatable = true; + + int pushValue(); + void setValue(const std::string& value); +}; + +class ScriptedPropertyBoolean : public ScriptedProperty +{ +public: + ScriptedPropertyBoolean(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 18; + static constexpr const char* luaName = "Property"; + static constexpr bool hasMetatable = true; + + int pushValue(); + void setValue(bool value); +}; + +class ScriptedEnumValues +{ +public: + ScriptedEnumValues(lua_State* L, DataEnum* value) : + m_state(L), m_dataEnum(value) + {} + static constexpr uint8_t luaTag = LUA_T_COUNT + 34; + static constexpr const char* luaName = "EnumValues"; + static constexpr bool hasMetatable = true; + void dataEnum(DataEnum* value) { m_dataEnum = value; } + int pushValue(int index); + int pushLength(); + + const lua_State* state() const { return m_state; } + +private: + lua_State* m_state = nullptr; + DataEnum* m_dataEnum = nullptr; +}; + +class ScriptedPropertyEnum : public ScriptedProperty +{ +public: + ScriptedPropertyEnum(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 19; + static constexpr const char* luaName = "Property"; + static constexpr bool hasMetatable = true; + + int pushValue(); + void setValue(const std::string& value); +}; + +class ScriptedPropertyImage : public ScriptedProperty +{ +public: + ScriptedPropertyImage(lua_State* L, rcp value); + static constexpr uint8_t luaTag = LUA_T_COUNT + 49; + static constexpr const char* luaName = "Property"; + static constexpr bool hasMetatable = true; + + int pushValue(); + void setValue(ScriptedImage* scriptedImage); +}; + +// Make +// ScriptedPropertyViewModel +// - Nullable ViewModelInstanceValue (ViewModelInstanceViewModel) +// - Requires ViewModel to know which properties to expect +// ScriptedPropertyArtboard +// - Nullable ViewModelInstanceValue (ViewModelInstanceArtboard) + +// Make renderer: return lua_newrive(L, renderer); +template +static T* lua_newrive(lua_State* L, Args&&... args) +{ + if (T::hasMetatable) + { + return new (lua_newuserdatataggedwithmetatable(L, sizeof(T), T::luaTag)) + T(std::forward(args)...); + } + else + { + return new (lua_newuserdatatagged(L, sizeof(T), T::luaTag)) + T(std::forward(args)...); + } +} + +BlendMode lua_toblendmode(lua_State* L, int idx); + +template +static T* lua_torive(lua_State* L, int idx, bool allowNil = false) +{ + T* riveObject = (T*)lua_touserdatatagged(L, idx, T::luaTag); + if (!allowNil && riveObject == nullptr) + { + luaL_typeerror(L, idx, T::luaName); + return nullptr; + } + return riveObject; +} + +template static void lua_register_rive(lua_State* L) +{ + if (T::hasMetatable) + { + // create metatable for T + luaL_newmetatable(L, T::luaName); + // lua_createtable(L, 0, 1); + + // push it again as lua_setuserdatametatable pops it + lua_pushvalue(L, -1); + lua_setuserdatametatable(L, T::luaTag); + } + if (!std::is_trivially_destructible::value) + { + // We only need to call the C++ destructor if the object is not + // trivially destructible. + lua_setuserdatadtor(L, T::luaTag, [](lua_State* L, void* data) { + ((T*)data)->~T(); + }); + } +} + +inline const Vec2D* lua_checkvec2d(lua_State* L, int stack) +{ + return (const Vec2D*)luaL_checkvector(L, stack); +} + +inline const Vec2D* lua_tovec2d(lua_State* L, int stack) +{ + return (const Vec2D*)lua_tovector(L, stack); +} + +inline void lua_pushvec2d(lua_State* L, Vec2D vec) +{ + return lua_pushvector2(L, vec.x, vec.y); +} + +int luaopen_rive(lua_State* L); +int rive_luaErrorHandler(lua_State* L); +int rive_lua_pcall(lua_State* state, int nargs, int nresults); +int rive_lua_pcall_with_context(lua_State* state, + ScriptedObject* scriptedObject, + int nargs, + int nresults); +int rive_lua_pushRef(lua_State* state, int ref); +void rive_lua_pop(lua_State* state, int count); + +class ScriptingContext +{ +public: + ScriptingContext(Factory* factory) : m_factory(factory) {} + virtual ~ScriptingContext() { shutdownAsync(); } + Factory* factory() const { return m_factory; } + ScriptedObject* currentScriptedObject() const + { + return m_currentScriptedObject; + } + void currentScriptedObject(ScriptedObject* value) + { + m_currentScriptedObject = value; + } + + virtual void printError(lua_State* state) = 0; + virtual void printBeginLine(lua_State* state) = 0; + virtual void print(Span data) = 0; + virtual void printEndLine() = 0; + virtual int pCall(lua_State* state, int nargs, int nresults) = 0; + + // Add a module to be registered later via performRegistration() + void addModule(ModuleDetails* moduleDetails); + // Perform registration of all added modules, handling dependencies and + // retries + void performRegistration(lua_State* state); + // Called when a module is required but not found during registration + void recordMissingDependency(const std::string& requiringModule, + const std::string& missingModule); + + // Ore GPU context for this VM — set during VM adoption (response phase). + // Stored as void* to avoid coupling this header to ore headers; callers + // cast to ore::Context*. + void setOreContext(void* ctx) { m_oreContext = ctx; } + void* oreContext() const { return m_oreContext; } + + // GPU render context — set once at startup by the host app. + // Stored as void* to avoid coupling this header to gpu headers; callers + // cast to gpu::RenderContext*. + void setRenderContext(void* ctx) { m_renderContext = ctx; } + void* renderContext() const { return m_renderContext; } + + // WorkPool for async operations (image decode, etc.). + // Lazily created on first access. Shared across all contexts via a + // process-global singleton. + class WorkPool* workPool(); + uint64_t ownerId() const { return m_ownerId; } + + // Cancel all pending async tasks for this context. Must be called + // BEFORE lua_close() to prevent callbacks on a dead Lua state. + void shutdownAsync(); + + // Like shutdownAsync but also cancels WASM browser-native decodes + // that bypass WorkPool. Call from ~ScriptingVM with the main lua_State. + void shutdownAsyncForState(lua_State* mainThread); + + // WebGL/WASM only: whether an ore frame is currently open for this VM. + // riveLuaPCall uses this to auto-open a mini-frame when Lua callbacks + // fire outside the normal render boundary (e.g. Coop stream events). + void setOreFrameOpen(bool open) { m_oreFrameOpen = open; } + bool oreFrameOpen() const { return m_oreFrameOpen; } + + // True while Artboard::drawCanvases() is actively walking scripted + // objects to invoke their drawCanvas() Lua callbacks. + void setCanvasDrawingPhase(bool value) { m_canvasDrawingPhase = value; } + bool canvasDrawingPhase() const { return m_canvasDrawingPhase; } + + // WebGL/WASM only: GL context handle saved at riveGPUBeginFrame so + // riveGPUEndFrame can restore the caller's context afterwards. + void setPrevGLContext(intptr_t h) { m_prevGLContext = h; } + intptr_t prevGLContext() const { return m_prevGLContext; } + +#ifdef __EMSCRIPTEN__ + void setGLHandle(int h) { m_glHandle = h; } + int glHandle() const { return m_glHandle; } +#endif + +private: + bool tryRegisterModule(lua_State* state, ModuleDetails* moduleDetails); + void sortNextModule(ModuleDetails* module, + std::vector* pendingModules, + std::vector* sortedModules, + std::unordered_set* visitedModules); + // Called when a module successfully registers + void onModuleRegistered(ModuleDetails* moduleDetails); + +private: + void* m_oreContext = nullptr; + void* m_renderContext = nullptr; + uint64_t m_ownerId = 0; + bool m_oreFrameOpen = false; + bool m_canvasDrawingPhase = false; + intptr_t m_prevGLContext = 0; +#ifdef __EMSCRIPTEN__ + int m_glHandle = 0; +#endif + + Factory* m_factory; + ScriptedObject* m_currentScriptedObject = nullptr; + std::vector m_modulesToRegister; + std::unordered_map m_moduleLookup; + std::unordered_set m_pendingModules; + +#ifdef WITH_RIVE_TOOLS + // Editor-only: Map from asset ID to generator function ref. + // Allows direct ScriptedObject reinitialization without regenerating + // the runtime file. + std::unordered_map m_assetGeneratorRefs; + bool m_isPlaying = false; + std::vector m_orphanScriptedProperties; + + // Per-VM RSTB blobs for WGSL shaders compiled during requestVM. Populated + // by the scripting workspace response phase; looked up by loadShader(). + std::unordered_map> m_shaderRstbs; + +public: + void setGeneratorRef(uint32_t assetId, int ref); + int getGeneratorRef(uint32_t assetId) const; + void clearGeneratorRefs(); + bool hasGeneratorRef(uint32_t assetId) const; + void isPlaying(bool value) { m_isPlaying = value; } + bool isPlaying() const { return m_isPlaying; } + void trackOrphanScriptedProperty(ScriptedProperty* property); + void untrackOrphanScriptedProperty(ScriptedProperty* property); + void disposeOrphanScriptedProperties(); + void registerShaderRstb(std::string name, std::vector bytes); + const std::vector* findShaderRstb(const std::string& name) const; + // Transfers all RSTB blobs out of this context (used during VM adoption + // to preserve blobs across context replacement). + std::unordered_map> takeShaderRstbs() + { + return std::move(m_shaderRstbs); + } +#endif +}; + +class ScopedScriptedObjectContext +{ +public: + ScopedScriptedObjectContext(ScriptingContext* context, + ScriptedObject* scriptedObject) : + m_context(context), + m_previous(context == nullptr ? nullptr + : context->currentScriptedObject()) + { + if (m_context != nullptr) + { + m_context->currentScriptedObject(scriptedObject); + } + } + + ~ScopedScriptedObjectContext() + { + if (m_context != nullptr) + { + m_context->currentScriptedObject(m_previous); + } + } + +private: + ScriptingContext* m_context; + ScriptedObject* m_previous; +}; + +class ScopedCanvasDrawingPhase +{ +public: + ScopedCanvasDrawingPhase(ScriptingContext* context) : + m_context(context), + m_previous(context == nullptr ? false : context->canvasDrawingPhase()) + { + if (m_context != nullptr) + { + m_context->setCanvasDrawingPhase(true); + } + } + + ~ScopedCanvasDrawingPhase() + { + if (m_context != nullptr) + { + m_context->setCanvasDrawingPhase(m_previous); + } + } + +private: + ScriptingContext* m_context; + bool m_previous; +}; + +class ScriptedDataValue +{ +public: + ScriptedDataValue(lua_State* L) { m_state = L; } + virtual ~ScriptedDataValue(); + static constexpr const char* luaName = "DataValue"; + DataValue* dataValue() { return m_dataValue; } + virtual bool isNumber() { return false; } + virtual bool isString() { return false; } + virtual bool isBoolean() { return false; } + virtual bool isColor() { return false; } + + const lua_State* state() const { return m_state; } + +protected: + lua_State* m_state; + DataValue* m_dataValue = nullptr; +}; + +class ScriptedDataValueNumber : public ScriptedDataValue +{ +public: + ScriptedDataValueNumber(lua_State* L, float value) : ScriptedDataValue(L) + { + m_dataValue = new DataValueNumber(value); + } + static constexpr bool hasMetatable = true; + static constexpr uint8_t luaTag = LUA_T_COUNT + 20; + static constexpr const char* luaName = "DataValueNumber"; + bool isNumber() override { return true; } +}; + +class ScriptedDataValueString : public ScriptedDataValue +{ +public: + ScriptedDataValueString(lua_State* L, std::string value) : + ScriptedDataValue(L) + { + m_dataValue = new DataValueString(value); + } + static constexpr bool hasMetatable = true; + static constexpr uint8_t luaTag = LUA_T_COUNT + 21; + static constexpr const char* luaName = "DataValueString"; + bool isString() override { return true; } +}; + +class ScriptedDataValueBoolean : public ScriptedDataValue +{ +public: + ScriptedDataValueBoolean(lua_State* L, bool value) : ScriptedDataValue(L) + { + m_dataValue = new DataValueBoolean(value); + } + static constexpr bool hasMetatable = true; + static constexpr uint8_t luaTag = LUA_T_COUNT + 22; + static constexpr const char* luaName = "DataValueBoolean"; + bool isBoolean() override { return true; } +}; + +class ScriptedDataValueColor : public ScriptedDataValue +{ +public: + ScriptedDataValueColor(lua_State* L, int value) : ScriptedDataValue(L) + { + m_dataValue = new DataValueColor(value); + } + static constexpr bool hasMetatable = true; + static constexpr uint8_t luaTag = LUA_T_COUNT + 23; + static constexpr const char* luaName = "DataValueColor"; + bool isColor() override { return true; } +}; + +class ScriptedPointerEvent +{ +public: + ScriptedPointerEvent(uint8_t id, + Vec2D position, + Vec2D previousPosition = Vec2D(), + int hitListenerType = 0, + float timeStamp = 0.f) : + m_id(id), + m_position(position), + m_previousPosition(previousPosition), + m_hitListenerType(hitListenerType), + m_timeStamp(timeStamp) + {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 24; + static constexpr const char* luaName = "PointerEvent"; + static constexpr bool hasMetatable = true; + + uint8_t m_id = 0; + Vec2D m_position; + Vec2D m_previousPosition; + int m_hitListenerType = 0; + float m_timeStamp = 0.f; + HitResult m_hitResult = HitResult::none; +}; + +class ScriptedNode +{ +public: + ScriptedNode(rcp artboard, + TransformComponent* component); + + static constexpr uint8_t luaTag = LUA_T_COUNT + 25; + static constexpr const char* luaName = "NodeData"; + static constexpr bool hasMetatable = true; + + TransformComponent* component() { return m_component; } + rcp artboard() { return m_artboard; } + + const ShapePaint* shapePaint(); + void shapePaint(const ShapePaint* shapePaint) { m_shapePaint = shapePaint; } + +private: + rcp m_artboard; + TransformComponent* m_component = nullptr; + const ShapePaint* m_shapePaint = nullptr; +}; + +class ScriptedContourMeasure +{ +public: + ScriptedContourMeasure(rcp measure, + rcp iter) : + m_measure(measure), m_iter(iter) + {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 26; + static constexpr const char* luaName = "ContourMeasure"; + static constexpr bool hasMetatable = true; + + ContourMeasure* measure() { return m_measure.get(); } + rcp iter() { return m_iter; } + +private: + rcp m_measure; + rcp m_iter; +}; + +class ScriptedPathMeasure +{ +public: + ScriptedPathMeasure(PathMeasure measure) : m_measure(std::move(measure)) {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 27; + static constexpr const char* luaName = "PathMeasure"; + static constexpr bool hasMetatable = true; + + PathMeasure* measure() { return &m_measure; } + +private: + PathMeasure m_measure; +}; + +class ScriptedContext +{ +public: + ScriptedContext(ScriptedObject*); + ScriptedObject* scriptedObject() { return m_scriptedObject; } + void clearScriptedObject() { m_scriptedObject = nullptr; } + int pushViewModel(lua_State*); + int pushRootViewModel(lua_State*); + int pushDataContext(lua_State*); + static constexpr uint8_t luaTag = LUA_T_COUNT + 28; + static constexpr const char* luaName = "Context"; + static constexpr bool hasMetatable = true; + bool missingRequestedData() { return m_missingRequestedData; } + +private: + ScriptedObject* m_scriptedObject = nullptr; + bool m_missingRequestedData = false; +}; + +/// Wraps [`ListenerInvocation`] for `performAction` in scripted listener +/// actions. +class ScriptedInvocation +{ +public: + explicit ScriptedInvocation(ListenerInvocation inv) : + m_invocation(std::move(inv)) + {} + + ListenerInvocation& invocation() { return m_invocation; } + const ListenerInvocation& invocation() const { return m_invocation; } + + static constexpr uint8_t luaTag = LUA_T_COUNT + 54; + static constexpr const char* luaName = "Invocation"; + static constexpr bool hasMetatable = true; + +private: + ListenerInvocation m_invocation; +}; + +class ScriptedKeyboardInvocation +{ +public: + ScriptedKeyboardInvocation(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) : + m_key(key), + m_modifiers(modifiers), + m_isPressed(isPressed), + m_isRepeat(isRepeat) + {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 55; + static constexpr const char* luaName = "KeyboardInvocation"; + static constexpr bool hasMetatable = true; + + Key m_key; + KeyModifiers m_modifiers; + bool m_isPressed; + bool m_isRepeat; +}; + +class ScriptedTextInputInvocation +{ +public: + explicit ScriptedTextInputInvocation(std::string text) : + m_text(std::move(text)) + {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 56; + static constexpr const char* luaName = "TextInputInvocation"; + static constexpr bool hasMetatable = true; + + const std::string& text() const { return m_text; } + +private: + std::string m_text; +}; + +class ScriptedFocusInvocation +{ +public: + explicit ScriptedFocusInvocation(bool isFocus) : m_isFocus(isFocus) {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 57; + static constexpr const char* luaName = "FocusInvocation"; + static constexpr bool hasMetatable = true; + + bool m_isFocus; +}; + +class ScriptedReportedEventInvocation +{ +public: + ScriptedReportedEventInvocation(Event* event, float delaySeconds) : + m_event(event), m_delaySeconds(delaySeconds) + {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 58; + static constexpr const char* luaName = "ReportedEventInvocation"; + static constexpr bool hasMetatable = true; + + /// Valid only for the duration of the listener callback; do not retain. + Event* m_event; + float m_delaySeconds; +}; + +class ScriptedViewModelChangeInvocation +{ +public: + ScriptedViewModelChangeInvocation() = default; + + static constexpr uint8_t luaTag = LUA_T_COUNT + 59; + static constexpr const char* luaName = "ViewModelChangeInvocation"; + static constexpr bool hasMetatable = true; +}; + +class ScriptedGamepadInvocation +{ +public: + ScriptedGamepadInvocation(int deviceId, uint64_t buttonMask, float axis0) : + m_deviceId(deviceId), m_buttonMask(buttonMask), m_axis0(axis0) + {} + + static constexpr uint8_t luaTag = LUA_T_COUNT + 60; + static constexpr const char* luaName = "GamepadInvocation"; + static constexpr bool hasMetatable = true; + + int m_deviceId; + uint64_t m_buttonMask; + float m_axis0; +}; + +class ScriptedNoneInvocation +{ +public: + ScriptedNoneInvocation() = default; + + static constexpr uint8_t luaTag = LUA_T_COUNT + 61; + static constexpr const char* luaName = "NoneInvocation"; + static constexpr bool hasMetatable = true; +}; + +void rive_lua_register_listener_invocation_types(lua_State* L); +void rive_lua_push_pointer_arg_for_perform(lua_State* L, + const ListenerInvocation& inv); +void rive_lua_push_scripted_invocation(lua_State* L, + const ListenerInvocation& inv); + +static void interruptCPP(lua_State* L, int gc); + +#ifdef WITH_RIVE_TOOLS +// Callback type for notifying when console data is available. +// If null, console output goes to stdout. +using ConsoleCallback = void (*)(); +#endif + +class CPPRuntimeScriptingContext : public ScriptingContext +{ +public: +#ifdef WITH_RIVE_TOOLS + CPPRuntimeScriptingContext(Factory* factory, + int timeoutMs = 200, + ConsoleCallback consoleCallback = nullptr) : + ScriptingContext(factory), + m_timeoutMs(timeoutMs), + m_consoleCallback(consoleCallback) + {} +#else + CPPRuntimeScriptingContext(Factory* factory, int timeoutMs = 200) : + ScriptingContext(factory), m_timeoutMs(timeoutMs) + {} +#endif + virtual ~CPPRuntimeScriptingContext() = default; + + std::chrono::time_point executionTime; + + int timeoutMs() const { return m_timeoutMs; } + void setTimeoutMs(int ms) { m_timeoutMs = ms; } + + int pCall(lua_State* state, int nargs, int nresults) override; + + void printBeginLine(lua_State* state) override + { +#ifdef WITH_RIVE_TOOLS + BinaryWriter writer(&m_consoleBuffer); + lua_Debug ar; + bool hasInfo = lua_getinfo(state, 1, "sl", &ar) != 0; + writer.write((uint8_t)0); + writer.write(hasInfo && ar.source != nullptr ? ar.source : ""); + writer.writeVarUint((uint32_t)(hasInfo ? ar.currentline : 0)); +#endif + } + + void print(Span data) override + { +#ifdef WITH_RIVE_TOOLS + if (data.size() == 0) + { + return; + } + BinaryWriter writer(&m_consoleBuffer); + writer.writeVarUint((uint64_t)data.size()); + writer.write((const uint8_t*)data.data(), (size_t)data.size()); + + if (m_consoleCallback == nullptr) +#endif + { + auto message = std::string(data.data(), data.size()); + printf("%s", message.c_str()); + } + } + + void printEndLine() override + { +#ifdef WITH_RIVE_TOOLS + BinaryWriter writer(&m_consoleBuffer); + writer.writeVarUint((uint32_t)0); + + if (m_consoleCallback != nullptr) + { + if (!m_calledConsoleCallback) + { + m_calledConsoleCallback = true; + m_consoleCallback(); + } + } + else +#endif + { + printf("\n"); + } + } + + void printError(lua_State* state) override + { + const char* error = lua_tostring(state, -1); + fprintf(stderr, "%s\n", error); +#ifdef WITH_RIVE_TOOLS + if (error) + { + printBeginLine(state); + print(Span(error, strlen(error))); + printEndLine(); + } +#endif + } + + void startTimedExecution(lua_State* state) + { + if (m_timeoutMs == 0) + { + return; + } + lua_Callbacks* cb = lua_callbacks(state); + cb->interrupt = interruptCPP; + executionTime = std::chrono::steady_clock::now(); + } + + void endTimedExecution(lua_State* state) + { + if (m_timeoutMs == 0) + { + return; + } + lua_Callbacks* cb = lua_callbacks(state); + cb->interrupt = nullptr; + } + +#ifdef WITH_RIVE_TOOLS + // Console buffer access for editor + Span consoleMemory() { return m_consoleBuffer.memory(); } + + void clearConsole() + { + m_consoleBuffer.clear(); + m_calledConsoleCallback = false; + } + + bool hasConsoleCallback() const { return m_consoleCallback != nullptr; } +#endif + +private: + int m_timeoutMs = 200; +#ifdef WITH_RIVE_TOOLS + ConsoleCallback m_consoleCallback = nullptr; + VectorBinaryStream m_consoleBuffer; + bool m_calledConsoleCallback = false; +#endif +}; + +class ScriptedDataContext +{ +public: + ScriptedDataContext(lua_State* L, rcp dataContext); + static constexpr uint8_t luaTag = LUA_T_COUNT + 36; + static constexpr const char* luaName = "DataContext"; + static constexpr bool hasMetatable = true; + int pushViewModel(); + int pushParent(); + + const lua_State* state() const { return m_state; } + +private: + lua_State* m_state = nullptr; + rcp m_dataContext = nullptr; +}; + +static void interruptCPP(lua_State* L, int gc) +{ + if (gc >= 0 || !lua_isyieldable(L)) + { + return; + } + + CPPRuntimeScriptingContext* context = + static_cast(lua_getthreaddata(L)); + + const auto now = std::chrono::steady_clock::now(); + auto ms = std::chrono::duration_cast( + now - context->executionTime) + .count(); + if (ms > context->timeoutMs()) + { + lua_Callbacks* cb = lua_callbacks(L); + cb->interrupt = nullptr; + // reserve space for error string + lua_rawcheckstack(L, 1); + + // Format human-readable error message + char errorMsg[128]; + int timeoutMs = context->timeoutMs(); + if (timeoutMs >= 1000) + { + double seconds = timeoutMs / 1000.0; + snprintf(errorMsg, + sizeof(errorMsg), + "execution exceeded %.1f second%s timeout", + seconds, + seconds == 1.0 ? "" : "s"); + } + else + { + snprintf(errorMsg, + sizeof(errorMsg), + "execution exceeded %d millisecond%s timeout", + timeoutMs, + timeoutMs == 1 ? "" : "s"); + } + luaL_error(L, "%s", errorMsg); + } +} +} // namespace rive + +#ifdef RIVE_CANVAS +#ifdef RIVE_ORE +namespace rive +{ +class ShaderAsset; +} +// Load a shader by name into a ScriptedShader (populates both vertex and +// fragment modules for GLSL targets with split entry points). +// Checks ScriptingContext::m_shaderRstbs first (editor path, compiled +// during requestVM), then |fileAsset| if non-null (runtime .riv path). +// Returns false on failure. +bool lua_gpu_load_shader_by_name(rive::ScriptedShader* out, + rive::ScriptingContext* context, + const char* name, + rive::ShaderAsset* fileAsset); + +// Compile a shader by name and push the resulting ScriptedShader onto the +// Lua stack. Returns 1 on success, 0 on failure. Declared here (implemented +// in lua_gpu.cpp) so callers that only have a forward-declaration of +// ShaderModule do not need to touch rcp directly. +int lua_gpu_push_shader_by_name(lua_State* L, const char* name); +#endif // RIVE_ORE +#endif // RIVE_CANVAS + +// Push a GPU features table onto the Lua stack. Queries the ORE context when +// available, otherwise returns conservative defaults. Always returns 1. +// Implemented in lua_scripted_context.cpp. +int lua_push_gpu_features(lua_State* L); + +// Push the platform's preferred canvas color format (a string like +// "bgra8unorm" or "rgba8unorm") onto the Lua stack. Always returns 1. +// Implemented in lua_scripted_context.cpp. +int lua_push_preferred_canvas_format(lua_State* L); + +#endif +#endif diff --git a/thirdparty/rive/include/rive/lua/scripting_vm.hpp b/thirdparty/rive/include/rive/lua/scripting_vm.hpp new file mode 100644 index 000000000..c4e0f5cbc --- /dev/null +++ b/thirdparty/rive/include/rive/lua/scripting_vm.hpp @@ -0,0 +1,78 @@ +#ifdef WITH_RIVE_SCRIPTING +#ifndef _RIVE_SCRIPTING_VM_HPP_ +#define _RIVE_SCRIPTING_VM_HPP_ + +#include "rive/refcnt.hpp" +#include "rive/span.hpp" +#include + +struct lua_State; + +namespace rive +{ +class ModuleDetails; +class ScriptingContext; + +class ScriptingVM : public RefCnt +{ +public: + // Creates a ScriptingVM that owns both the lua_State and the context. + explicit ScriptingVM(std::unique_ptr context); + + ~ScriptingVM(); + + ScriptingContext* context() { return m_ownedContext.get(); } + lua_State* state() const { return m_state; } + + // Replaces the owned context with a new one. The old context is deleted + // and the new context is owned by this VM. Also updates lua thread data. + void replaceContext(std::unique_ptr newContext); + + static void init(lua_State* state, ScriptingContext* context); + + // Add a module to be registered later via performRegistration() + void addModule(ModuleDetails* moduleDetails); + + // Perform registration of all added modules, handling dependencies and + // retries + void performRegistration(); + + static bool registerModule(lua_State* state, + const char* name, + Span bytecode); + static void unregisterModule(lua_State* state, const char* name); + bool registerModule(const char* name, Span bytecode); + void unregisterModule(const char* name); + + static bool registerScript(lua_State* state, + const char* name, + Span bytecode); + + bool registerScript(const char* name, Span bytecode); + + // Loads bytecode into the VM, creating a sandboxed thread and + // deserializing the bytecode into an unexecuted closure. Pushes the + // module thread onto the stack. Returns true on success. + static bool loadModule(lua_State* state, + const char* name, + Span bytecode); + + // Executes a previously loaded module thread (on top of stack from + // loadModule). Runs lua_resume, validates the result, and for utility + // modules registers into the require cache. On success, the module + // result (table/function) replaces the thread on the stack. + // Returns true on success. + static bool executeModule(lua_State* state, + const char* name, + bool isUtility); + + static void dumpStack(lua_State* state); + +private: + lua_State* m_state; + std::unique_ptr m_ownedContext; +}; + +} // namespace rive +#endif +#endif diff --git a/thirdparty/rive/include/rive/manifest_sections.hpp b/thirdparty/rive/include/rive/manifest_sections.hpp new file mode 100644 index 000000000..3160681d2 --- /dev/null +++ b/thirdparty/rive/include/rive/manifest_sections.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_MANIFEST_FLAGS_HPP_ +#define _RIVE_MANIFEST_FLAGS_HPP_ + +namespace rive +{ +enum class ManifestSections : unsigned char +{ + names = 0, + paths = 1, +}; +} +#endif diff --git a/thirdparty/rive/include/rive/math/aabb.hpp b/thirdparty/rive/include/rive/math/aabb.hpp index 8d661a932..9bb04b45f 100644 --- a/thirdparty/rive/include/rive/math/aabb.hpp +++ b/thirdparty/rive/include/rive/math/aabb.hpp @@ -51,6 +51,8 @@ template struct TAABB return left <= rhs.left && top <= rhs.top && right >= rhs.right && bottom >= rhs.bottom; } + + static TAABB MakeWH(T width, T height) { return {0, 0, width, height}; } }; using IAABB = TAABB; diff --git a/thirdparty/rive/include/rive/math/bitwise.hpp b/thirdparty/rive/include/rive/math/bitwise.hpp new file mode 100644 index 000000000..4a3e5b4a6 --- /dev/null +++ b/thirdparty/rive/include/rive/math/bitwise.hpp @@ -0,0 +1,258 @@ +/* + * Copyright 2026 Rive + */ + +#ifndef _RIVE_BITWISE_HPP_ +#define _RIVE_BITWISE_HPP_ + +#include + +#include "rive/rive_types.hpp" +#include "rive/enums.hpp" +#include "rive/math/math_types.hpp" + +namespace rive::math +{ + +// Attempt to generate a "clz" assembly instruction. +RIVE_ALWAYS_INLINE static int clz32(uint32_t x) +{ + assert(x != 0); +#if __has_builtin(__builtin_clz) + return __builtin_clz(x); +#else + uint64_t doubleBits = bit_cast(static_cast(x)); + return 1054 - (doubleBits >> 52); +#endif +} + +RIVE_ALWAYS_INLINE static int clz64(uint64_t x) +{ + assert(x != 0); +#if __has_builtin(__builtin_clzll) + return __builtin_clzll(x); +#else + uint32_t hi32 = x >> 32; + return hi32 != 0 ? clz32(hi32) : 32 + clz32(x & 0xffffffff); +#endif +} + +// Returns the 1-based index of the most significat bit in x. +// +// 0 -> 0 +// 1 -> 1 +// 2..3 -> 2 +// 4..7 -> 3 +// ... +// +RIVE_ALWAYS_INLINE static uint32_t msb(uint32_t x) +{ + return x != 0 ? 32 - clz32(x) : 0; +} + +// Attempt to generate a "rotl" (rotate-left) assembly instruction. +RIVE_ALWAYS_INLINE static uint32_t rotateleft32(uint32_t x, int y) +{ +#if __has_builtin(__builtin_rotateleft32) + return __builtin_rotateleft32(x, y); +#else + return (x << y) | (x >> (32 - y)); +#endif +} + +namespace internal +{ +// For compilers where there isn't a built-in popcount function, here's the +// simplest efficient implementation. This is done here in a namespace so that +// it can be unit tested even on systems that have built-in popcount support. +template constexpr uint32_t count_set_bits_fallback(I i) noexcept +{ + uint32_t count = 0; + while (i != 0) + { + count++; + + // remove the lowest set bit from the given value + i &= i - 1; + } + return count; +} + +} // namespace internal + +template constexpr uint32_t count_set_bits(T i) noexcept +{ +#if __has_builtin(__builtin_popcount) + static_assert(std::is_integral_v); + if constexpr (sizeof(T) == sizeof(uint64_t)) + { + return uint32_t(__builtin_popcountll(uint64_t(i))); + } + else + { + return uint32_t(__builtin_popcount(uint32_t(i))); + } +#else + return internal::count_set_bits_fallback(i); +#endif +} + +// Give a value with bits set within a given mask, compact the bits down to the +// minimum number needed to represent the values that are set in the mask. +// For example: a mask of 11010001 has 4 set bits, and so a value of 10x0xxx1 +// (where x is any bit value not within the mask) would be compacted to 1001 +constexpr uint32_t compact_bitmask_value(uint32_t value, uint32_t mask) noexcept +{ + uint32_t compacted = 0; + for (int32_t inBitIndex = 31; inBitIndex >= 0; inBitIndex--) + { + auto bit = 1u << inBitIndex; + if ((mask & bit) != 0) + { + compacted <<= 1; + compacted |= ((value & bit) != 0) ? 1 : 0; + } + } + + return compacted; +} + +// Undo the operation that compactBitmaskValue does. +// For example: a mask of 11010001, with a given compacted vaue of 1001 would +// expand to 10000001 (where each 1 in "compacted" means setting the +// corresponding bit from mask) +constexpr uint32_t expand_compacted_bitmask_value(uint32_t compacted, + uint32_t mask) noexcept +{ + uint32_t expanded = 0; + for (int32_t maskBitIndex = 0; maskBitIndex < 32; maskBitIndex++) + { + auto maskBit = 1u << maskBitIndex; + if ((mask & maskBit) != 0) + { + if (compacted & 1) + { + expanded |= maskBit; + } + compacted >>= 1; + } + } + + return expanded; +} + +// Iteratable returned from iterateBitCombinationsInMask +template class BitCombinationIterable +{ +public: + explicit constexpr BitCombinationIterable(T mask) : m_mask(mask) {} + + class Iterator + { + public: + explicit constexpr Iterator(T mask) noexcept : + m_currentValue(mask), m_mask(mask) + {} + + constexpr static Iterator MakeEnd(T mask) noexcept + { + Iterator it{mask}; + it.m_wasAdvanced = true; + return it; + } + + constexpr Iterator& operator++() noexcept + { + m_wasAdvanced = true; + + // Do this operation as an unsigned integral version of the type. + // For enums this allows the subtraction below to work, and for + // signed integers this allows us to do wrapping subtraction + // (subtracting from 0) without it being undefined behavior. + // NOTE: The odd "enable_if" in there is a trick to delay evaluation + // of underlying_type until the conditional gets chosen, because + // otherwise this won't compile for non-enum types + using U = std::make_unsigned_t< + typename std::conditional_t, + std::underlying_type, + std::enable_if>::type>; + + // We actually iterate through these combinations from most bits to + // least bits because it's simpler. (Iterating forward can be + // accomplished by starting at 0, and xoring with the mask before + // and after this decrement, but it seemed unnecessary since it's + // unlikely that the ordering matters anywhere) + + // This subtraction and mask effectively removes the lowest set bit + // in the mask from the current value (and re-sets and mask bits + // below it), that is with a mask of 01001010 and a current value of + // 01001000, subtracting would give 01000111, then the mask leaves + // it as 01000010, which is the next-lowest valid combination of + // mask bits from where we were. + m_currentValue = T(U(m_currentValue) - 1) & m_mask; + + return *this; + } + + constexpr Iterator operator++(int) noexcept + { + auto prev = *this; + ++(*this); + return prev; + } + + constexpr T operator*() const noexcept { return m_currentValue; } + + constexpr bool operator==(const Iterator& other) const noexcept + { + assert(m_mask == other.m_mask); + return (m_currentValue == other.m_currentValue && + m_wasAdvanced == other.m_wasAdvanced); + } + + constexpr bool operator!=(const Iterator& other) const noexcept + { + return !(*this == other); + } + + private: + T m_currentValue{}; + T m_mask{}; + bool m_wasAdvanced = false; + }; + + constexpr Iterator begin() const noexcept { return Iterator{m_mask}; } + constexpr Iterator end() const noexcept + { + return Iterator::MakeEnd(m_mask); + } + +private: + T m_mask; +}; + +// Iterate through all combinations of set/unset bits for a given mask. +// That is, for a mask that is 101011, it would iterate through: +// 101011, 101010, 101001, 101000, 100011, ..., 000001, 000000 +template +BitCombinationIterable iterate_bit_combinations_in_mask(T mask) +{ + return BitCombinationIterable{mask}; +} + +// Shift bits into the bottom of a key value (ensuring that the key value does +// not overflow and the value fits within the specified bit count) +template +[[nodiscard]] Key add_bits_to_key(Key key, + Bits bits, + uint32_t bitCount) noexcept +{ + static_assert(sizeof(Bits) <= sizeof(Key)); + + assert((key << bitCount) >> bitCount == key); + assert((Key(bits) & ((1ull << bitCount) - 1)) == Key(bits)); + return (key << bitCount) | Key(bits); +} + +} // namespace rive::math +#endif diff --git a/thirdparty/rive/include/rive/math/contour_measure.hpp b/thirdparty/rive/include/rive/math/contour_measure.hpp index 04356927b..b82701c33 100644 --- a/thirdparty/rive/include/rive/math/contour_measure.hpp +++ b/thirdparty/rive/include/rive/math/contour_measure.hpp @@ -132,6 +132,14 @@ class ContourMeasureIter this->rewind(path, tol); } + // Constructor that copies the path, allowing ContourMeasure objects to + // outlive the original path. + ContourMeasureIter(const RawPath& path, float tol = kDefaultTolerance) + { + m_optionalCopy = path; + this->rewind(&m_optionalCopy, tol); + } + void rewind(const RawPath*, float = kDefaultTolerance); // Returns a measure object for each contour in the path @@ -154,6 +162,24 @@ class ContourMeasureIter std::vector m_segmentCounts; }; +// Ref-counted wrapper for ContourMeasureIter, used when the iterator needs +// to outlive stack scope (e.g., in script bindings). +class RefCntContourMeasureIter : public RefCnt +{ +public: + RefCntContourMeasureIter( + const RawPath& path, + float tol = ContourMeasureIter::kDefaultTolerance) : + m_iter(path, tol) + {} + + ContourMeasureIter* get() { return &m_iter; } + ContourMeasureIter* operator->() { return &m_iter; } + +private: + ContourMeasureIter m_iter; +}; + } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/math/mat2d.hpp b/thirdparty/rive/include/rive/math/mat2d.hpp index 48fe99313..c4c2e42d3 100644 --- a/thirdparty/rive/include/rive/math/mat2d.hpp +++ b/thirdparty/rive/include/rive/math/mat2d.hpp @@ -102,6 +102,8 @@ class Mat2D private: std::array m_buffer; }; +static_assert(std::is_trivially_destructible::value, + "Mat2D must be trivially destructible"); inline Vec2D operator*(const Mat2D& m, Vec2D v) { diff --git a/thirdparty/rive/include/rive/math/mat4.hpp b/thirdparty/rive/include/rive/math/mat4.hpp new file mode 100644 index 000000000..341ab2b6a --- /dev/null +++ b/thirdparty/rive/include/rive/math/mat4.hpp @@ -0,0 +1,402 @@ +#ifndef _RIVE_MAT4_HPP_ +#define _RIVE_MAT4_HPP_ + +#include "rive/math/simd.hpp" +#include "rive/math/vec2d.hpp" +#include +#include +#include + +namespace rive +{ +// Column-major 4x4 single-precision matrix. The 64-byte storage can be +// uploaded directly to a GPU uniform buffer. +// +// Column 0 = m[0..3], Column 1 = m[4..7], Column 2 = m[8..11], Column 3 = +// m[12..15]. +class Mat4 +{ +public: + constexpr Mat4() : + m_buffer{{1.f, + 0.f, + 0.f, + 0.f, + 0.f, + 1.f, + 0.f, + 0.f, + 0.f, + 0.f, + 1.f, + 0.f, + 0.f, + 0.f, + 0.f, + 1.f}} + {} + + constexpr Mat4(float c0x, + float c0y, + float c0z, + float c0w, + float c1x, + float c1y, + float c1z, + float c1w, + float c2x, + float c2y, + float c2z, + float c2w, + float c3x, + float c3y, + float c3z, + float c3w) : + m_buffer{{c0x, + c0y, + c0z, + c0w, + c1x, + c1y, + c1z, + c1w, + c2x, + c2y, + c2z, + c2w, + c3x, + c3y, + c3z, + c3w}} + {} + + const float* values() const { return m_buffer.data(); } + float* values() { return m_buffer.data(); } + + float& operator[](size_t i) { return m_buffer[i]; } + float operator[](size_t i) const { return m_buffer[i]; } + + static Mat4 identity() { return Mat4(); } + + static Mat4 fromTranslation(float x, float y, float z) + { + Mat4 m; + m.m_buffer[12] = x; + m.m_buffer[13] = y; + m.m_buffer[14] = z; + return m; + } + + static Mat4 fromScale(float sx, float sy, float sz) + { + Mat4 m; + m.m_buffer[0] = sx; + m.m_buffer[5] = sy; + m.m_buffer[10] = sz; + return m; + } + + static Mat4 fromRotationX(float rad) + { + float c = std::cos(rad), s = std::sin(rad); + Mat4 m; + m.m_buffer[5] = c; + m.m_buffer[6] = s; + m.m_buffer[9] = -s; + m.m_buffer[10] = c; + return m; + } + + static Mat4 fromRotationY(float rad) + { + float c = std::cos(rad), s = std::sin(rad); + Mat4 m; + m.m_buffer[0] = c; + m.m_buffer[2] = -s; + m.m_buffer[8] = s; + m.m_buffer[10] = c; + return m; + } + + static Mat4 fromRotationZ(float rad) + { + float c = std::cos(rad), s = std::sin(rad); + Mat4 m; + m.m_buffer[0] = c; + m.m_buffer[1] = s; + m.m_buffer[4] = -s; + m.m_buffer[5] = c; + return m; + } + + // Right-handed perspective. Maps view-space z=[-near, -far] to NDC z in + // either [0, 1] (default, depthZeroToOne=true) or [-1, 1]. + static Mat4 perspective(float fovYRadians, + float aspect, + float near_, + float far_, + bool depthZeroToOne = true) + { + float f = 1.f / std::tan(fovYRadians * 0.5f); + float nf = 1.f / (near_ - far_); + Mat4 m{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + m.m_buffer[0] = f / aspect; + m.m_buffer[5] = f; + if (depthZeroToOne) + { + m.m_buffer[10] = far_ * nf; + m.m_buffer[14] = far_ * near_ * nf; + } + else + { + m.m_buffer[10] = (far_ + near_) * nf; + m.m_buffer[14] = 2.f * far_ * near_ * nf; + } + m.m_buffer[11] = -1.f; + return m; + } + + // Right-handed perspective with reverse-Z (near -> 1, far -> 0) and an + // infinite far plane. Combined with a float depth buffer this gives a + // near-uniform 1/z depth distribution across the entire frustum — the + // best precision an arbitrary scene can hope for. See Upchurch & Desbrun, + // "Tightening the Precision of Perspective Rendering" (2012). + // + // Caller's depth buffer must be cleared to 0 (not 1) and the depth test + // flipped (GREATER, not LESS). + static Mat4 perspectiveReverseZ(float fovYRadians, + float aspect, + float near_) + { + float f = 1.f / std::tan(fovYRadians * 0.5f); + Mat4 m{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + m.m_buffer[0] = f / aspect; + m.m_buffer[5] = f; + m.m_buffer[10] = 0.f; + m.m_buffer[11] = -1.f; + m.m_buffer[14] = near_; + return m; + } + + // SIMD: out = lhs * rhs. Both column-major. + static Mat4 multiply(const Mat4& lhs, const Mat4& rhs) + { + // Each output column j is a linear combination of lhs's columns + // weighted by rhs's column j. + const float* L = lhs.m_buffer.data(); + const float* R = rhs.m_buffer.data(); + float4 c0 = simd::load4f(L); + float4 c1 = simd::load4f(L + 4); + float4 c2 = simd::load4f(L + 8); + float4 c3 = simd::load4f(L + 12); + + Mat4 out; + for (int j = 0; j < 4; ++j) + { + const float* rcol = R + j * 4; + float4 result = + c0 * rcol[0] + c1 * rcol[1] + c2 * rcol[2] + c3 * rcol[3]; + simd::store(out.m_buffer.data() + j * 4, result); + } + return out; + } + + Mat4 operator*(const Mat4& rhs) const { return multiply(*this, rhs); } + + // SIMD: out = lhs * rhs, assuming both are affine (bottom row + // [0, 0, 0, 1]). Skips the four FMAs that would multiply lhs's bottom- + // row zeros and the rhs[3]=0 entries of the first three columns. + // + // Result is always affine. Passing a non-affine input gives an + // incorrect result — callers must ensure the contract. + static Mat4 multiplyAffine(const Mat4& lhs, const Mat4& rhs) + { + const float* L = lhs.m_buffer.data(); + const float* R = rhs.m_buffer.data(); + float4 c0 = simd::load4f(L); // [_,_,_,0] + float4 c1 = simd::load4f(L + 4); // [_,_,_,0] + float4 c2 = simd::load4f(L + 8); // [_,_,_,0] + float4 c3 = simd::load4f(L + 12); // [_,_,_,1] + + Mat4 out; + // Cols 0..2: rhs[3] is 0, so the c3*rhs[3] term vanishes. + for (int j = 0; j < 3; ++j) + { + const float* rcol = R + j * 4; + float4 result = c0 * rcol[0] + c1 * rcol[1] + c2 * rcol[2]; + simd::store(out.m_buffer.data() + j * 4, result); + } + // Col 3: rhs[3] is 1, so c3 contributes directly. + { + const float* rcol = R + 12; + float4 result = c0 * rcol[0] + c1 * rcol[1] + c2 * rcol[2] + c3; + simd::store(out.m_buffer.data() + 12, result); + } + return out; + } + + // SIMD: out = M * (x, y, z, w). Returns a 4-component vector (xyzw). + void transformVec4(float out[4], float x, float y, float z, float w) const + { + float4 c0 = simd::load4f(m_buffer.data()); + float4 c1 = simd::load4f(m_buffer.data() + 4); + float4 c2 = simd::load4f(m_buffer.data() + 8); + float4 c3 = simd::load4f(m_buffer.data() + 12); + simd::store(out, c0 * x + c1 * y + c2 * z + c3 * w); + } + + Mat4 transposed() const + { + Mat4 t; + for (int r = 0; r < 4; ++r) + for (int c = 0; c < 4; ++c) + t.m_buffer[r * 4 + c] = m_buffer[c * 4 + r]; + return t; + } + + // Returns true and writes inverse if invertible. Otherwise returns false + // and `result` is unchanged. Cofactor method. + bool invert(Mat4* result) const + { + const float* m = m_buffer.data(); + float inv[16]; + + inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - + m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + + m[13] * m[6] * m[11] - m[13] * m[7] * m[10]; + inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - + m[12] * m[6] * m[11] + m[12] * m[7] * m[10]; + inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - + m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + + m[12] * m[5] * m[11] - m[12] * m[7] * m[9]; + inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - + m[12] * m[5] * m[10] + m[12] * m[6] * m[9]; + inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - + m[13] * m[2] * m[11] + m[13] * m[3] * m[10]; + inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - + m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + + m[12] * m[2] * m[11] - m[12] * m[3] * m[10]; + inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - + m[12] * m[1] * m[11] + m[12] * m[3] * m[9]; + inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - + m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + + m[12] * m[1] * m[10] - m[12] * m[2] * m[9]; + inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - + m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + + m[13] * m[2] * m[7] - m[13] * m[3] * m[6]; + inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - + m[12] * m[2] * m[7] + m[12] * m[3] * m[6]; + inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - + m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + + m[12] * m[1] * m[7] - m[12] * m[3] * m[5]; + inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - + m[12] * m[1] * m[6] + m[12] * m[2] * m[5]; + inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - + m[9] * m[2] * m[7] + m[9] * m[3] * m[6]; + inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - + m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + + m[8] * m[2] * m[7] - m[8] * m[3] * m[6]; + inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - + m[8] * m[1] * m[7] + m[8] * m[3] * m[5]; + inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - + m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + + m[8] * m[1] * m[6] - m[8] * m[2] * m[5]; + + float det = + m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; + if (det == 0.f) + return false; + float invDet = 1.f / det; + for (int i = 0; i < 16; ++i) + (*result)[i] = inv[i] * invDet; + return true; + } + + // Closed-form inverse for affine matrices (bottom row [0, 0, 0, 1]). + // Inverts the 3x3 linear part R via cofactors, then writes -R^-1 * t + // into the translation column. Much smaller and faster than the full + // 4x4 cofactor `invert`. + // + // Returns false (and leaves `result` unchanged) only if the linear part + // is singular. Caller must ensure the input is actually affine. + bool invertAffine(Mat4* result) const + { + const float* m = m_buffer.data(); + // The 3x3 linear part R has R[row][col] = m[col*4 + row]. + // Cofactors C[i][j] of column 0 of R, expanded for det along col 0. + float c00 = m[5] * m[10] - m[6] * m[9]; + float c10 = m[6] * m[8] - m[4] * m[10]; + float c20 = m[4] * m[9] - m[5] * m[8]; + float det = m[0] * c00 + m[1] * c10 + m[2] * c20; + if (det == 0.f) + return false; + float invDet = 1.f / det; + // Remaining 6 cofactors. + float c01 = m[2] * m[9] - m[1] * m[10]; + float c02 = m[1] * m[6] - m[2] * m[5]; + float c11 = m[0] * m[10] - m[2] * m[8]; + float c12 = m[2] * m[4] - m[0] * m[6]; + float c21 = m[1] * m[8] - m[0] * m[9]; + float c22 = m[0] * m[5] - m[1] * m[4]; + + // R^-1 = (cofactor matrix)^T / det, so Rinv[i][j] = C[j][i] / det. + // Naming below: ri_j = Rinv[i][j]. + float r0_0 = c00 * invDet, r0_1 = c10 * invDet, r0_2 = c20 * invDet; + float r1_0 = c01 * invDet, r1_1 = c11 * invDet, r1_2 = c21 * invDet; + float r2_0 = c02 * invDet, r2_1 = c12 * invDet, r2_2 = c22 * invDet; + + // Translation column: -R^-1 * t. + float tx = m[12], ty = m[13], tz = m[14]; + float ix = -(r0_0 * tx + r0_1 * ty + r0_2 * tz); + float iy = -(r1_0 * tx + r1_1 * ty + r1_2 * tz); + float iz = -(r2_0 * tx + r2_1 * ty + r2_2 * tz); + + // Store column-major: o[col*4 + row] = Rinv[row][col]. + float* o = result->m_buffer.data(); + o[0] = r0_0; + o[1] = r1_0; + o[2] = r2_0; + o[3] = 0.f; + o[4] = r0_1; + o[5] = r1_1; + o[6] = r2_1; + o[7] = 0.f; + o[8] = r0_2; + o[9] = r1_2; + o[10] = r2_2; + o[11] = 0.f; + o[12] = ix; + o[13] = iy; + o[14] = iz; + o[15] = 1.f; + return true; + } + +private: + std::array m_buffer; +}; + +static_assert(std::is_trivially_destructible::value, + "Mat4 must be trivially destructible"); +static_assert(sizeof(Mat4) == 16 * sizeof(float), + "Mat4 must be 64 bytes (no padding)"); + +inline bool operator==(const Mat4& a, const Mat4& b) +{ + for (size_t i = 0; i < 16; ++i) + if (a[i] != b[i]) + return false; + return true; +} +inline bool operator!=(const Mat4& a, const Mat4& b) { return !(a == b); } + +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/math/math_types.hpp b/thirdparty/rive/include/rive/math/math_types.hpp index 420126553..ab6a9dde3 100644 --- a/thirdparty/rive/include/rive/math/math_types.hpp +++ b/thirdparty/rive/include/rive/math/math_types.hpp @@ -73,52 +73,6 @@ template T lossless_numeric_cast(U u) return t; } -// Attempt to generate a "clz" assembly instruction. -RIVE_ALWAYS_INLINE static int clz32(uint32_t x) -{ - assert(x != 0); -#if __has_builtin(__builtin_clz) - return __builtin_clz(x); -#else - uint64_t doubleBits = bit_cast(static_cast(x)); - return 1054 - (doubleBits >> 52); -#endif -} - -RIVE_ALWAYS_INLINE static int clz64(uint64_t x) -{ - assert(x != 0); -#if __has_builtin(__builtin_clzll) - return __builtin_clzll(x); -#else - uint32_t hi32 = x >> 32; - return hi32 != 0 ? clz32(hi32) : 32 + clz32(x & 0xffffffff); -#endif -} - -// Returns the 1-based index of the most significat bit in x. -// -// 0 -> 0 -// 1 -> 1 -// 2..3 -> 2 -// 4..7 -> 3 -// ... -// -RIVE_ALWAYS_INLINE static uint32_t msb(uint32_t x) -{ - return x != 0 ? 32 - clz32(x) : 0; -} - -// Attempt to generate a "rotl" (rotate-left) assembly instruction. -RIVE_ALWAYS_INLINE static uint32_t rotateleft32(uint32_t x, int y) -{ -#if __has_builtin(__builtin_rotateleft32) - return __builtin_rotateleft32(x, y); -#else - return (x << y) | (x >> (32 - y)); -#endif -} - // Returns x rounded up to the next multiple of N. // If x is already a multiple of N, returns x. template @@ -159,11 +113,6 @@ RIVE_ALWAYS_INLINE static float positive_mod(float value, float range) inline float degrees_to_radians(float degrees) { return degrees * PI / 180.0f; } -RIVE_ALWAYS_INLINE static float degreesToRadians(float degrees) -{ - return degrees * (PI / 180.0f); -} - // Returns the smallest number that can be added to 'value', such that // 'value % alignment' == 0. template uint32_t padding_to_align_up(uintptr_t value) diff --git a/thirdparty/rive/include/rive/math/path_measure.hpp b/thirdparty/rive/include/rive/math/path_measure.hpp index 5e7990174..6a0300432 100644 --- a/thirdparty/rive/include/rive/math/path_measure.hpp +++ b/thirdparty/rive/include/rive/math/path_measure.hpp @@ -15,7 +15,13 @@ class PathMeasure ContourMeasure::PosTanDistance atDistance(float distance) const; ContourMeasure::PosTanDistance atPercentage(float percentageDistance) const; + void getSegment(float startDistance, + float endDistance, + RawPath* dst, + bool startWithMove = true) const; + float length() const { return m_length; } + bool isClosed() const; private: float m_length; diff --git a/thirdparty/rive/include/rive/math/random.hpp b/thirdparty/rive/include/rive/math/random.hpp new file mode 100644 index 000000000..ff86a305a --- /dev/null +++ b/thirdparty/rive/include/rive/math/random.hpp @@ -0,0 +1,53 @@ +/* + * Copyright 2022 Rive + */ +#ifndef _RIVE_RANDOM_HPP_ +#define _RIVE_RANDOM_HPP_ + +#include +#include + +namespace rive +{ + +class RandomProvider +{ +#ifdef TESTING +private: + static int m_randomCallsCount; + static std::vector m_randomResults; + +public: + static void addRandomValue(float value) + { + m_randomResults.push_back(value); + } + static void clearRandoms() + { + m_randomCallsCount = 0; + m_randomResults.clear(); + } + static float generateRandomFloat() + { + m_randomCallsCount++; + if (m_randomResults.size() > 0) + { + auto newRandom = m_randomResults[0]; + m_randomResults.erase(m_randomResults.begin()); + return newRandom; + } + return 0; + } + static int totalCalls() { return m_randomCallsCount; }; +#else +public: + static float generateRandomFloat() + { + return (float)rand() / float(RAND_MAX); + } +#endif +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/math/raw_path.hpp b/thirdparty/rive/include/rive/math/raw_path.hpp index ce26d1cca..d567f086a 100644 --- a/thirdparty/rive/include/rive/math/raw_path.hpp +++ b/thirdparty/rive/include/rive/math/raw_path.hpp @@ -33,9 +33,7 @@ class RawPath #ifdef DEBUG void printCode() const; #endif -#ifdef WITH_RIVE_TOOLS AABB preciseBounds() const; -#endif size_t countMoveTos() const; void move(Vec2D); @@ -280,7 +278,7 @@ class RawPath // True of the path is nonempty and the most recent verb is not "close". bool m_contourIsOpen = false; - void addPoints(std::vector::const_iterator& rev_iter, + void addPoints(std::vector::const_reverse_iterator& rev_iter, int count, const Mat2D* = nullptr); }; diff --git a/thirdparty/rive/include/rive/math/simd.hpp b/thirdparty/rive/include/rive/math/simd.hpp index d8d1e9131..7d13fb874 100644 --- a/thirdparty/rive/include/rive/math/simd.hpp +++ b/thirdparty/rive/include/rive/math/simd.hpp @@ -83,6 +83,22 @@ template struct boolean_mask_type #define SIMD_NATIVE_GVEC 1 +// NOTE: Due to the build compiling with march=native, on systems with AVX +// or AVX512 support, it will output those vectors from these functions, +// but clang will kick out the following warning: +// AVX vector return of type 'gvec' (vector of +// 32 'signed char' values) without 'avx' enabled changes the ABI +// In release builds, all of the places where these functions are being +// called should be getting inlined so there's not *technically* an ABI +// to be breaking, so disabling this should be fine. +#define DISABLE_CLANG_SIMD_ABI_WARNING() \ + _Pragma("clang diagnostic ignored \"-Wpsabi\"") + +#define PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() \ + _Pragma("clang diagnostic push") DISABLE_CLANG_SIMD_ABI_WARNING() + +#define POP_DISABLE_CLANG_SIMD_ABI_WARNING() _Pragma("clang diagnostic pop") + #else // gvec needs to be polyfilled with templates. @@ -94,6 +110,11 @@ template struct boolean_mask_type #define SIMD_NATIVE_GVEC 0 +// With non-native gvec these don't have to do anything +#define DISABLE_CLANG_SIMD_ABI_WARNING() +#define PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() +#define POP_DISABLE_CLANG_SIMD_ABI_WARNING() + #endif namespace rive @@ -585,6 +606,8 @@ SIMD_ALWAYS_INLINE std:: } #endif +PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() + template SIMD_ALWAYS_INLINE gvec join(gvec a, gvec b) { @@ -696,6 +719,8 @@ SIMD_ALWAYS_INLINE return ret; } +POP_DISABLE_CLANG_SIMD_ABI_WARNING() + ////// Basic linear algebra ////// template diff --git a/thirdparty/rive/include/rive/math/simd_gvec_polyfill.hpp b/thirdparty/rive/include/rive/math/simd_gvec_polyfill.hpp index 83f90c15f..5993f4b81 100644 --- a/thirdparty/rive/include/rive/math/simd_gvec_polyfill.hpp +++ b/thirdparty/rive/include/rive/math/simd_gvec_polyfill.hpp @@ -31,13 +31,22 @@ constexpr static Swizzle PackSwizzle2(uint32_t sourceVectorLength, { return (i1 << 5) | (i0 << 3) | sourceVectorLength; } + +constexpr static Swizzle PackSwizzle3(uint32_t sourceVectorLength, + uint32_t i0, + uint32_t i1, + uint32_t i2) +{ + return (i2 << 7) | PackSwizzle2(sourceVectorLength, i0, i1); +} + constexpr static Swizzle PackSwizzle4(uint32_t sourceVectorLength, uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) { - return (i3 << 9) | (i2 << 7) | PackSwizzle2(sourceVectorLength, i0, i1); + return (i3 << 9) | PackSwizzle3(sourceVectorLength, i0, i1, i2); } constexpr static uint32_t UnpackSwizzleSourceVectorLength(Swizzle swizzle) { @@ -59,6 +68,37 @@ template struct gvec ret[i] = (*this)[i]; return ret; } + + gvec& operator=(gvec b) + { + for (int i = 0; i < N; i++) + { + (*this)[i] = b[i]; + } + + return *this; + } + + T data[UnpackSwizzleSourceVectorLength(Z)]; +}; + +// To keep gvec as POD (or, more specifically, trivially copyable) some swizzles +// can be exposed as read-only (which effectively means they just have a +// conversion to gvec). This is useful for swizzles like "vec.www" which use a +// component multiple times. +template struct ReadOnlyGvecSwizzle +{ + T operator[](size_t i) const { return data[UnpackSwizzleIdx(Z, i)]; } + + operator gvec() const + { + gvec ret; + for (int i = 0; i < N; ++i) + ret[i] = (*this)[i]; + return ret; + } + +private: T data[UnpackSwizzleSourceVectorLength(Z)]; }; @@ -73,6 +113,7 @@ template struct gvec_data { T data[1]; T x; + T r; }; }; @@ -85,6 +126,10 @@ template struct gvec_data { T x, y; }; + struct + { + T r, g; + }; gvec yx; gvec xyxy; gvec yxyx; @@ -102,6 +147,11 @@ template struct gvec_data { T x, y, z; }; + struct + { + T r, g, b; + }; + gvec xyz; }; }; @@ -111,11 +161,16 @@ template struct gvec_data { T data[4]; gvec xyz; + gvec rgb; struct { gvec xy, zw; }; struct + { + T r, g, b, a; + }; + struct { T x; union @@ -137,6 +192,10 @@ template struct gvec_data gvec zyxw; gvec xwzy; gvec xzyw; + + // However, for swizzles that are used as a source only, they can be + // added as ReadOnlyGvecSwizzle entries. + ReadOnlyGvecSwizzle www; }; }; @@ -208,50 +267,74 @@ DECL_UNARY_OP(~) #undef DECL_UNARY_OP #define DECL_ARITHMETIC_OP(_OP_) \ - template \ + template typename A, \ + template typename B> \ typename std::enable_if::value, \ gvec>::type& \ - operator _OP_##=(gvec& a, gvec b) \ + operator _OP_##=(A& a, B b) \ { \ for (int i = 0; i < N; ++i) \ a[i] _OP_## = b[i]; \ return a; \ } \ - template \ + template typename A> \ typename std::enable_if::value, \ gvec>::type& \ - operator _OP_##=(gvec& a, U b) \ + operator _OP_##=(A& a, U b) \ { \ for (int i = 0; i < N; ++i) \ a[i] _OP_## = b; \ return a; \ } \ - template \ + template typename A, \ + template typename B> \ typename std::enable_if::value, \ gvec>::type \ - operator _OP_(gvec a, gvec b) \ + operator _OP_(A a, B b) \ { \ gvec ret; \ for (int i = 0; i < N; ++i) \ ret[i] = a[i] _OP_ b[i]; \ return ret; \ } \ - template \ + template typename A> \ typename std::enable_if::value, \ gvec>::type \ - operator _OP_(gvec a, U b) \ + operator _OP_(A a, U b) \ { \ gvec ret; \ for (int i = 0; i < N; ++i) \ ret[i] = a[i] _OP_ b; \ return ret; \ } \ - template \ + template typename B> \ typename std::enable_if::value, \ gvec>::type \ - operator _OP_(T a, gvec b) \ + operator _OP_(T a, B b) \ { \ - gvec ret; \ + gvec ret; \ for (int i = 0; i < N; ++i) \ ret[i] = a _OP_ b[i]; \ return ret; \ @@ -316,55 +399,96 @@ DECL_BOOLEAN_OP(||) #undef DECL_BOOLEAN_OP #define ENABLE_SWIZZLE1(F) \ - template gvec F(gvec x) \ + template typename X> \ + gvec F(X x) \ { \ return F((gvec)x); \ } #define ENABLE_SWIZZLE_REDUCE(F) \ - template T F(gvec x) \ + template typename X> \ + T F(X x) \ { \ return F((gvec)x); \ } #define ENABLE_SWIZZLE1F(F) \ - template gvec F(gvec x) \ + template typename X> \ + gvec F(X x) \ { \ return F((gvec)x); \ } #define ENABLE_SWIZZLE1B(F) \ - template bool F(gvec x) \ + template typename X> \ + bool F(X x) \ { \ return F((gvec)x); \ } #define ENABLE_SWIZZLEUT(F) \ - template gvec F(gvec x) \ + template typename X> \ + gvec F(X x) \ { \ return F((gvec)x); \ } #define ENABLE_SWIZZLE2(F) \ - template \ - gvec F(gvec a, gvec b) \ + template typename A, \ + template typename B> \ + gvec F(A a, B b) \ { \ return F((gvec)a, (gvec)b); \ } + #define ENABLE_SWIZZLE3(F) \ - template \ - gvec F(gvec a, gvec b, gvec c) \ + template typename A, \ + template typename B, \ + template typename C> \ + gvec F(A a, B b, C c) \ { \ return F((gvec)a, (gvec)b, (gvec)c); \ } #define ENABLE_SWIZZLE3F(F) \ - template \ - gvec F(gvec a, \ - gvec b, \ - gvec c) \ + template typename A, \ + template typename B, \ + template typename C> \ + gvec F(A a, B b, C c) \ { \ return F((gvec)a, (gvec)b, (gvec)c); \ } #define ENABLE_SWIZZLE3IT(F) \ - template \ - gvec F(gvec::type, N, Z0> a, \ - gvec b, \ - gvec c) \ + template typename A, \ + template typename B, \ + template typename C> \ + gvec F(A::type, N, Z0> a, \ + B b, \ + C c) \ { \ return F((gvec)a, (gvec)b, (gvec)c); \ } @@ -397,6 +521,11 @@ gvec cast(gvec x) return cast((gvec)x); } +static_assert(std::is_pod_v>); +static_assert(std::is_pod_v>); +static_assert(std::is_pod_v>); +static_assert(std::is_pod_v>); + #undef ENABLE_SWIZZLE1 #undef ENABLE_SWIZZLE_REDUCE #undef ENABLE_SWIZZLE1F diff --git a/thirdparty/rive/include/rive/math/vec2d.hpp b/thirdparty/rive/include/rive/math/vec2d.hpp index 1f6c44c6f..597d912a3 100644 --- a/thirdparty/rive/include/rive/math/vec2d.hpp +++ b/thirdparty/rive/include/rive/math/vec2d.hpp @@ -136,4 +136,4 @@ template <> struct hash }; } // namespace std -#endif +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/nested_animation.hpp b/thirdparty/rive/include/rive/nested_animation.hpp index 95f2200a6..2ef264c52 100644 --- a/thirdparty/rive/include/rive/nested_animation.hpp +++ b/thirdparty/rive/include/rive/nested_animation.hpp @@ -29,6 +29,13 @@ class NestedEventNotifier { m_nestedEventListeners.push_back(listener); } + void removeNestedEventListener(NestedEventListener* listener) + { + auto nested = std::remove(m_nestedEventListeners.begin(), + m_nestedEventListeners.end(), + listener); + m_nestedEventListeners.erase(nested, m_nestedEventListeners.end()); + } std::vector nestedEventListeners() { return m_nestedEventListeners; @@ -70,6 +77,9 @@ class NestedAnimation : public NestedAnimationBase // Initialize the animation (make instances as necessary) from the // source artboard. virtual void initializeAnimation(ArtboardInstance*) = 0; + + // Clear the nested animation dependencies + virtual void releaseDependencies() = 0; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/nested_artboard.hpp b/thirdparty/rive/include/rive/nested_artboard.hpp index 6dedf635c..7566673f9 100644 --- a/thirdparty/rive/include/rive/nested_artboard.hpp +++ b/thirdparty/rive/include/rive/nested_artboard.hpp @@ -3,11 +3,18 @@ #include "rive/generated/nested_artboard_base.hpp" #include "rive/artboard_host.hpp" +#include "rive/artboard_referencer.hpp" +#include "rive/data_bind_path_referencer.hpp" #include "rive/data_bind/data_context.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/hit_info.hpp" +#include "rive/input/focusable.hpp" #include "rive/span.hpp" #include "rive/advancing_component.hpp" +#include "rive/resetting_component.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" +#include "rive/refcnt.hpp" +#include "rive/file.hpp" #include namespace rive @@ -20,34 +27,56 @@ class NestedStateMachine; class StateMachineInstance; class NestedArtboard : public NestedArtboardBase, public AdvancingComponent, - public ArtboardHost + public ResettingComponent, + public ArtboardHost, + public ArtboardReferencer, + public Focusable { protected: - Artboard* m_Artboard = nullptr; // might point to m_Instance, and might not std::unique_ptr m_Instance; // may be null + std::unique_ptr + m_boundNestedStateMachine; // may be null std::vector m_NestedAnimations; + File* m_file = nullptr; + rcp m_viewModelInstance = nullptr; + rcp m_dataContext = nullptr; + // ViewModelInstance child for stateful artboards. + rcp m_statefulViewModelInstance = nullptr; protected: - std::vector m_DataBindPathIdsBuffer; +private: + void clearNestedAnimations(); + float m_cumulatedSeconds = 0; + bool m_hasPendingStatefulBinding = false; + void nest(Artboard* artboard); + bool tryScheduleBindStateful(); + void bindStateful(); + void bindArtboardInstance(rcp instance, + rcp parent); public: NestedArtboard(); ~NestedArtboard() override; StatusCode onAddedClean(CoreContext* context) override; void draw(Renderer* renderer) override; + bool willDraw() override; Core* hitTest(HitInfo*, const Mat2D&) override; void addNestedAnimation(NestedAnimation* nestedAnimation); - - void nest(Artboard* artboard); + void updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) override; + int referencedArtboardId() override; + void referencedArtboard(Artboard* artboard) override; size_t artboardCount() override { return 1; } + int type() const override { return coreType(); } ArtboardInstance* artboardInstance(int index = 0) override { return m_Instance.get(); } - Artboard* sourceArtboard() { return m_Artboard; } + Artboard* sourceArtboard() { return m_referencedArtboard; } StatusCode import(ImportStack& importStack) override; Core* clone() const override; + bool collapse(bool value) override; void update(ComponentDirt value) override; bool hasNestedStateMachines() const; @@ -73,21 +102,36 @@ class NestedArtboard : public NestedArtboardBase, bool worldToLocal(Vec2D world, Vec2D* local); void decodeDataBindPathIds(Span value) override; void copyDataBindPathIds(const NestedArtboardBase& object) override; - std::vector dataBindPathIds() override - { - return m_DataBindPathIdsBuffer; - }; - void populateDataBinds(std::vector* dataBinds) override; void bindViewModelInstance(rcp viewModelInstance, - DataContext* parent) override; - void internalDataContext(DataContext* dataContext) override; + rcp parent) override; + void internalDataContext(rcp dataContext) override; + void relinkDataContext(rcp viewModelInstance) override; void clearDataContext() override; + void unbind() override; + void updateDataBinds() override; + float calculateLocalElapsedSeconds(float elapsedSeconds); bool advanceComponent(float elapsedSeconds, AdvanceFlags flags = AdvanceFlags::Animate | AdvanceFlags::NewFrame) override; + void reset() override; Artboard* parentArtboard() override { return artboard(); } + Vec2D hostTransformPoint(const Vec2D&, ArtboardInstance*) override; + Mat2D worldTransformForArtboard(ArtboardInstance*) override; + bool hitTestHost(const Vec2D& position, + bool skipOnUnclipped, + ArtboardInstance* artboard) override; void markHostTransformDirty() override { markTransformDirty(); } + void file(File*) override; + File* file() const override; + Component* hostComponent() override { return this; } + + // Focusable interface - delegates to nested state machines + bool keyInput(Key, KeyModifiers, bool, bool) override { return false; }; + bool textInput(const std::string&) override { return false; }; + void focused() override {} + void blurred() override {} + Artboard* focusableArtboard() const override { return artboard(); } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/nested_artboard_layout.hpp b/thirdparty/rive/include/rive/nested_artboard_layout.hpp index 291cd2fb3..080b37996 100644 --- a/thirdparty/rive/include/rive/nested_artboard_layout.hpp +++ b/thirdparty/rive/include/rive/nested_artboard_layout.hpp @@ -3,6 +3,8 @@ #include "rive/generated/nested_artboard_layout_base.hpp" #include "rive/constraints/layout_constraint.hpp" #include "rive/layout/layout_node_provider.hpp" +#include "rive/layout/style_overrider.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" namespace rive { @@ -22,18 +24,25 @@ class NestedArtboardLayout : public NestedArtboardLayoutBase, void updateConstraints() override; StatusCode onAddedClean(CoreContext* context) override; - float actualInstanceWidth(); - float actualInstanceHeight(); bool syncStyleChanges() override; void updateLayoutBounds(bool animate = true) override; +#ifdef WITH_RIVE_LAYOUT + bool cascadeLayoutStyle(LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime, + LayoutDirection direction) override; +#endif AABB layoutBounds() override; size_t numLayoutNodes() override { return 1; } bool isLayoutProvider() override { return true; } + void updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) override; TransformComponent* transformComponent() override { return this->as(); } + bool isRow(); protected: void instanceWidthChanged() override; @@ -46,6 +55,8 @@ class NestedArtboardLayout : public NestedArtboardLayoutBase, private: void updateWidthOverride(); void updateHeightOverride(); + StyleOverrider m_styleOverrider = + StyleOverrider(this); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/node.hpp b/thirdparty/rive/include/rive/node.hpp index 79432e40d..ca801f33c 100644 --- a/thirdparty/rive/include/rive/node.hpp +++ b/thirdparty/rive/include/rive/node.hpp @@ -18,6 +18,8 @@ class Node : public NodeBase void setComputedLocalY(float value) override {} void setComputedWorldX(float value) override {} void setComputedWorldY(float value) override {} + void setComputedRootX(float value) override {} + void setComputedRootY(float value) override {} void setComputedWidth(float value) override {} void setComputedHeight(float value) override {} @@ -25,6 +27,8 @@ class Node : public NodeBase float computedLocalY() override { return localTransform()[5]; }; float computedWorldX() override { return worldTransform()[4]; }; float computedWorldY() override { return worldTransform()[5]; }; + float computedRootX() override; + float computedRootY() override; float computedWidth() override { return 0; }; float computedHeight() override { return 0; }; @@ -43,6 +47,8 @@ class Node : public NodeBase void computedLocalYChanged() override {} void computedWorldXChanged() override {} void computedWorldYChanged() override {} + void computedRootXChanged() override {} + void computedRootYChanged() override {} void computedWidthChanged() override {} void computedHeightChanged() override {} diff --git a/thirdparty/rive/include/rive/parent_traversal.hpp b/thirdparty/rive/include/rive/parent_traversal.hpp new file mode 100644 index 000000000..c72110644 --- /dev/null +++ b/thirdparty/rive/include/rive/parent_traversal.hpp @@ -0,0 +1,69 @@ +#ifndef _RIVE_PARENT_TRAVERSAL_HPP_ +#define _RIVE_PARENT_TRAVERSAL_HPP_ + +namespace rive +{ +class Artboard; +class ArtboardHost; +class ArtboardInstance; +class Component; +class ContainerComponent; + +/// Helper class for traversing up the parent hierarchy, automatically +/// crossing artboard boundaries when needed (e.g., from a nested artboard +/// to its parent artboard via ArtboardHost). +/// +/// Usage: +/// ParentTraversal traversal(startComponent); +/// while (auto* parent = traversal.next()) +/// { +/// // Process parent... +/// } +/// +/// For traversals that need to know when artboard boundaries are crossed +/// (e.g., to transform coordinates), check didCrossBoundary() after each +/// next() call. When true, crossingHost() and sourceArtboard() provide +/// the information needed to transform between artboard spaces. +class ParentTraversal +{ +public: + /// Start traversal from the given component. + /// The first call to next() will return the component's parent. + /// The component's artboard is used to detect when we need to + /// cross artboard boundaries. + ParentTraversal(Component* start); + + /// Move to the next parent in the hierarchy, crossing artboard + /// boundaries when needed. Returns the next parent, or nullptr + /// when the traversal is complete. + ContainerComponent* next(); + + /// Returns the artboard context for the current position in the traversal. + /// This changes when crossing artboard boundaries. + Artboard* currentArtboard() const { return m_currentArtboard; } + + /// Returns true if the last call to next() crossed an artboard boundary. + bool didCrossBoundary() const { return m_didCrossBoundary; } + + /// When didCrossBoundary() is true, returns the ArtboardHost that was + /// used to cross the boundary. Use this with sourceArtboard() to get + /// the world transform for coordinate conversions. + ArtboardHost* crossingHost() const { return m_crossingHost; } + + /// When didCrossBoundary() is true, returns the artboard we crossed FROM. + /// Cast to ArtboardInstance if needed for worldTransformForArtboard(). + Artboard* sourceArtboard() const { return m_sourceArtboard; } + +private: + ContainerComponent* m_current; + Artboard* m_currentArtboard; + + // Boundary crossing state (valid after next() that crosses a boundary) + bool m_didCrossBoundary = false; + ArtboardHost* m_crossingHost = nullptr; + Artboard* m_sourceArtboard = nullptr; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/pointer_event.hpp b/thirdparty/rive/include/rive/pointer_event.hpp index da1bb5591..6a4d69a5d 100644 --- a/thirdparty/rive/include/rive/pointer_event.hpp +++ b/thirdparty/rive/include/rive/pointer_event.hpp @@ -21,7 +21,6 @@ struct PointerEvent // add more fields as needed }; - } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/profiler/microprofile_emscripten.h b/thirdparty/rive/include/rive/profiler/microprofile_emscripten.h new file mode 100644 index 000000000..73eb3d02d --- /dev/null +++ b/thirdparty/rive/include/rive/profiler/microprofile_emscripten.h @@ -0,0 +1,32 @@ +#pragma once + +// Emscripten/WASM compatibility shim for microprofile. +// microprofile.h only defines MP_TICK, MP_BREAK, etc. for __APPLE__, _WIN32, +// and __linux__. Emscripten supports the same POSIX APIs as Linux so we +// replicate the Linux platform block here and include this header before +// microprofile.h. + +#if defined(__EMSCRIPTEN__) && !defined(MP_TICK) + +#include +#include +#include +#include + +inline int64_t MicroProfileTicksPerSecondCpu() { return 1000000000ll; } + +inline int64_t MicroProfileGetTick() +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return 1000000000ll * ts.tv_sec + ts.tv_nsec; +} + +#define MP_TICK() MicroProfileGetTick() +#define MP_BREAK() __builtin_trap() +#define MP_THREAD_LOCAL __thread +#define MP_STRCASECMP strcasecmp +#define MP_GETCURRENTTHREADID() (uint64_t)pthread_self() +typedef uint64_t MicroProfileThreadIdType; + +#endif // __EMSCRIPTEN__ && !MP_TICK diff --git a/thirdparty/rive/include/rive/profiler/profiler_macros.h b/thirdparty/rive/include/rive/profiler/profiler_macros.h new file mode 100644 index 000000000..ab6678417 --- /dev/null +++ b/thirdparty/rive/include/rive/profiler/profiler_macros.h @@ -0,0 +1,151 @@ +#pragma once + +// RIVE_PROF_FRAME() +// This function should be called at the start of the main loop +// +// RIVE_PROF_SCOPE() +// Add to a function or scope to profile, the function name is +// automatically filled in +// +// RIVE_PROF_SCOPENAME(name) +// Same as above but manually supplied name +// +// RIVE_PROF_THREAD(name) +// Add to new threads +// +// Level-gated variants: +// RIVE_PROF_SCOPE_L(level) +// RIVE_PROF_SCOPENAME_L(level, name) +// RIVE_PROF_GPUNAME_L(level, name) +// +// `level` MUST be a literal integer 0..4. Lower numbers mark higher-level +// functions (frame, scene, flush). Higher numbers mark hot inner-loop +// functions whose per-call overhead matters. The compile-time threshold +// `RIVE_PROF_LEVEL_MAX` drops every marker with `level > RIVE_PROF_LEVEL_MAX` +// to nothing — no token registration, no Enter/Leave call, no stack handler. +// Pass it via the build system, e.g. `-DRIVE_PROF_LEVEL_MAX=2`. +// +// The non-level macros (RIVE_PROF_SCOPE, RIVE_PROF_SCOPENAME, +// RIVE_PROF_GPUNAME) are equivalent to level 0 and are always on whenever the +// active profiler is compiled in. + +#ifndef RIVE_PROF_LEVEL_MAX +#define RIVE_PROF_LEVEL_MAX 2 +#endif + +// Per-level pass-through gates. Each either expands its argument (when the +// level is <= RIVE_PROF_LEVEL_MAX) or drops it. +#if RIVE_PROF_LEVEL_MAX >= 0 +#define _RIVE_PROF_LVL_0(body) body +#else +#define _RIVE_PROF_LVL_0(body) +#endif + +#if RIVE_PROF_LEVEL_MAX >= 1 +#define _RIVE_PROF_LVL_1(body) body +#else +#define _RIVE_PROF_LVL_1(body) +#endif + +#if RIVE_PROF_LEVEL_MAX >= 2 +#define _RIVE_PROF_LVL_2(body) body +#else +#define _RIVE_PROF_LVL_2(body) +#endif + +#if RIVE_PROF_LEVEL_MAX >= 3 +#define _RIVE_PROF_LVL_3(body) body +#else +#define _RIVE_PROF_LVL_3(body) +#endif + +#if RIVE_PROF_LEVEL_MAX >= 4 +#define _RIVE_PROF_LVL_4(body) body +#else +#define _RIVE_PROF_LVL_4(body) +#endif + +// Dispatch via token paste so `level` works as a literal integer. +#define _RIVE_PROF_LVL_DISPATCH(level, body) _RIVE_PROF_LVL_##level(body) +#define _RIVE_PROF_LVL(level, body) _RIVE_PROF_LVL_DISPATCH(level, body) + +#if defined(RIVE_OPTICK) // Optick integration + +#include "optick_core.h" +#include "optick.h" +#define RIVE_PROF_INIT() +#define RIVE_PROF_FRAME() OPTICK_FRAME("RiveFrame") +#define RIVE_PROF_SCOPE() OPTICK_EVENT() +#define RIVE_PROF_SCOPENAME(name) OPTICK_EVENT(name) +#define RIVE_PROF_GPUNAME(name) + +#define RIVE_PROF_SCOPE_L(level) _RIVE_PROF_LVL(level, OPTICK_EVENT();) +#define RIVE_PROF_SCOPENAME_L(level, name) \ + _RIVE_PROF_LVL(level, OPTICK_EVENT(name);) +#define RIVE_PROF_GPUNAME_L(level, name) _RIVE_PROF_LVL(level, /* unused */) + +#define RIVE_PROF_TAG(cat, tag) OPTICK_TAG(cat, tag) +#define RIVE_PROF_THREAD(name) OPTICK_THREAD(name) +#define RIVE_PROF_DRAW() +#define RIVE_PROF_TOGGLEDRAW() +#define RIVE_PROF_GPUSUBMIT(i) +#define RIVE_PROF_GPUFLIP() +#define RIVE_PROF_ENDFRAME() + +#elif defined(RIVE_MICROPROFILE) // Microprofile integration +#include "rive/profiler/microprofile_emscripten.h" +#include "microprofile.h" +#include "microprofiledraw.h" +#include "microprofileui.h" + +#define MICROPROFILE_GPU_TIMERS 1 + +#define RIVE_PROF_INIT() \ + MicroProfileSetEnableAllGroups(true); \ + MicroProfileSetForceEnable(true); \ + MicroProfileWebServerStart(); \ + MicroProfileOnThreadCreate("MainThread"); \ + MicroProfileInit(); + +#define RIVE_PROF_FRAME() +#define RIVE_PROF_SCOPE() \ + MICROPROFILE_SCOPEI(__FILE__, __FUNCTION__, 0xffffffff); +#define RIVE_PROF_SCOPENAME(name) \ + MICROPROFILE_SCOPEI("group", name, 0xffffffff); +#define RIVE_PROF_GPUNAME(name) MICROPROFILE_SCOPEGPUI(name, 0xffffffff); + +#define RIVE_PROF_SCOPE_L(level) \ + _RIVE_PROF_LVL(level, \ + MICROPROFILE_SCOPEI(__FILE__, __FUNCTION__, 0xffffffff);) +#define RIVE_PROF_SCOPENAME_L(level, name) \ + _RIVE_PROF_LVL(level, MICROPROFILE_SCOPEI("group", name, 0xffffffff);) +#define RIVE_PROF_GPUNAME_L(level, name) \ + _RIVE_PROF_LVL(level, MICROPROFILE_SCOPEGPUI(name, 0xffffffff);) + +#define RIVE_PROF_TAG(cat, tag) +#define RIVE_PROF_THREAD(name) +#define RIVE_PROF_DRAW() MicroProfileDraw(); +#define RIVE_PROF_TOGGLEDRAW() // MicroProfileToggleDisplayMode(); +#define RIVE_PROF_GPUSUBMIT(i) MicroProfileGpuSubmit(i); +#define RIVE_PROF_GPUFLIP() // MicroProfileGpuFlip(); +#define RIVE_PROF_ENDFRAME() MicroProfileFlip(); + +#else // No profiler selected - fallback to no-op + +#define RIVE_PROF_INIT() +#define RIVE_PROF_FRAME() +#define RIVE_PROF_SCOPE() +#define RIVE_PROF_SCOPENAME(name) +#define RIVE_PROF_GPUNAME(name) +#define RIVE_PROF_SCOPE_L(level) +#define RIVE_PROF_SCOPENAME_L(level, name) +#define RIVE_PROF_GPUNAME_L(level, name) +#define RIVE_PROF_TAG(cat, tag) +#define RIVE_PROF_THREAD(name) +#define RIVE_PROF_DRAW() +#define RIVE_PROF_TOGGLEDRAW() +#define RIVE_PROF_GPUSUBMIT(i) +#define RIVE_PROF_GPUFLIP() +#define RIVE_PROF_ENDFRAME() + +#endif diff --git a/thirdparty/rive/include/rive/profiler/rive_profile.hpp b/thirdparty/rive/include/rive/profiler/rive_profile.hpp new file mode 100644 index 000000000..54b4c98a0 --- /dev/null +++ b/thirdparty/rive/include/rive/profiler/rive_profile.hpp @@ -0,0 +1,165 @@ +#ifndef _RIVE_PROFILE_HPP_ +#define _RIVE_PROFILE_HPP_ + +#include +#include +#include +#include +#include + +namespace rive +{ + +/// Bitmask for which profile data to log. Combine flags to enable multiple. +enum ProfileLogFlags : uint32_t +{ + ProfileLogNone = 0, + ProfileLogTransitionRecords = 1u << 0, + ProfileLogListenerPerformChanges = 1u << 1, +}; + +/// Segment of the artboard path (root to state machine artboard). +/// type: 0 = NestedArtboard, 1 = ArtboardComponentList. index is used only when +/// type is ArtboardComponentList (logical index in list); otherwise -1. +struct ArtboardPathSegment +{ + uint8_t type = 0; + uint32_t nameId = 0; + int32_t index = -1; +}; + +/// Record for a single state machine transition (used when profiling). +/// String fields are stored as indices into the profiler string table; +/// see getStringTable() and resolveStringId(). path is root-to-leaf host chain. +struct TransitionRecord +{ + uint32_t artboardId = 0; + uint32_t smId = 0; + uint32_t layerId = 0; + uint32_t fromStateId = 0; + uint32_t toStateId = 0; + uint64_t tick = 0; + std::vector path; +}; + +/// Record for a single listener performChanges call (used when profiling). +/// artboardId, smId, listenerNameId index into the profiler string table. +/// listenerType and hitEvent are raw ListenerType enum values; consumer maps to +/// string. +struct ListenerPerformChangeRecord +{ + uint32_t artboardId = 0; + uint32_t smId = 0; + uint32_t listenerNameId = 0; + uint32_t listenerType = 0; + uint32_t hitEvent = 0; + uint32_t pointerId = 0; + uint64_t tick = 0; +}; + +/// Singleton that wraps all MicroProfile calls and collects transition records +/// as they occur during advance/apply (when RIVE_MICROPROFILE is defined). +class RiveProfile +{ +public: + using FlushCallback = + std::function&)>; + using ListenerPerformChangeFlushCallback = + std::function&)>; + + static RiveProfile& instance(); + + RiveProfile(const RiveProfile&) = delete; + RiveProfile& operator=(const RiveProfile&) = delete; + + // MicroProfile lifecycle (no-ops when RIVE_MICROPROFILE is not defined) + void init(); + void frame(); + void endFrame(); + + /// Profiling session (used by native binding for start/stop/dump). + void start(); + void stop(); + bool isActive() const; + + /// Append header (once) and new frame events to \a buffer. Call after + /// flushTransitionRecords() so the binding can merge transition data. + void flushFrameDataTo(std::vector& buffer); + + /// Record a state machine transition. Data is collected as it runs; no + /// second pass over instances is required. No-op when RIVE_MICROPROFILE is + /// undefined, the profiling session is inactive, no transition flush + /// callback is set, or ProfileLogTransitionRecords is not set. + /// If artboardForPath is non-null, the full artboard path is built and + /// stored on the record (only when recording). + void recordTransition(std::string artboardName, + std::string smName, + std::string layerName, + std::string fromStateName, + std::string toStateName, + class Artboard* artboardForPath = nullptr); + + /// Set the callback invoked when flushTransitionRecords() is called with + /// all collected records for the current frame. The binding uses this to + /// serialize records into the event buffer. + void setFlushCallback(FlushCallback callback); + + /// Invoke the flush callback with accumulated transition records and clear + /// the buffer. Call after advanceAndApply. No-op when callback is not set. + void flushTransitionRecords(); + + /// Record a listener performChanges call. No-op when RIVE_MICROPROFILE is + /// undefined, the profiling session is inactive, no listener flush callback + /// is set, or ProfileLogListenerPerformChanges is not set. listenerType and + /// hitEvent are stored as raw uint (ListenerType enum); consumer maps to + /// string. + void recordListenerPerformChange(std::string artboardName, + std::string smName, + std::string listenerName, + uint32_t listenerType, + uint32_t hitEvent, + uint32_t pointerId); + + /// Set the callback invoked when flushListenerPerformChangeRecords() is + /// called with all collected listener records for the current frame. + void setListenerPerformChangeFlushCallback( + ListenerPerformChangeFlushCallback callback); + + /// Invoke the listener flush callback with accumulated records and clear + /// the buffer. Call after flushTransitionRecords() when profiling. + void flushListenerPerformChangeRecords(); + + /// Set which profile data to log (bitmask of ProfileLogFlags). Combine + /// flags to enable multiple log types. + void setLogFlags(uint32_t flags) { m_logFlags = flags; } + uint32_t logFlags() const { return m_logFlags; } + + /// Resolve a string to a stable id in the profiler string table. Used by + /// transition records and any future record type that needs to log strings. + /// Returns existing id if the string was seen before, otherwise assigns new + /// id. + uint32_t resolveStringId(const std::string& str); + + /// Return the current profiler string table (id index -> string). The + /// binding uses this to emit 0x04 string table records; other record types + /// use ids that index into this table. + const std::vector& getStringTable() const; + +private: + RiveProfile() = default; + + FlushCallback m_flushCallback; + ListenerPerformChangeFlushCallback m_listenerPerformChangeFlushCallback; + std::vector m_transitionRecords; + std::vector m_listenerPerformChangeRecords; + std::unordered_map m_stringTable; + std::vector m_stringList; + bool m_profilingActive = false; + uint32_t m_logFlags = 3; + bool m_headerWritten = false; + uint64_t m_lastFlushedFrameIndex = 0; +}; + +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/property_recorder.hpp b/thirdparty/rive/include/rive/property_recorder.hpp new file mode 100644 index 000000000..a13632bed --- /dev/null +++ b/thirdparty/rive/include/rive/property_recorder.hpp @@ -0,0 +1,86 @@ +#ifndef _RIVE_PROPERTY_RECORDER_HPP_ +#define _RIVE_PROPERTY_RECORDER_HPP_ + +#include "rive/core/binary_writer.hpp" +#include "rive/core/vector_binary_writer.hpp" +#include "rive/core/binary_data_reader.hpp" +#include "rive/core/binary_data_reader.hpp" +#include +#include +#include +#include + +namespace rive +{ +class Artboard; +class StateMachine; +class StateMachineLayer; +class StateMachineInput; +class LayerState; +class LinearAnimation; +class KeyedObject; +class Core; +class StateMachineInstance; +class CoreObjectData +{ +private: + std::vector m_propertyKeys; + +public: + CoreObjectData(uint32_t id) { objectId = id; } + uint32_t objectId; + void addPropertyKey(uint16_t key) + { + auto it = std::find(m_propertyKeys.begin(), m_propertyKeys.end(), key); + if (it == m_propertyKeys.end()) + { + m_propertyKeys.push_back(key); + } + } + std::vector* propertyKeys() { return &m_propertyKeys; } +}; + +class PropertyRecorder +{ +private: + VectorBinaryWriter m_binaryWriter; + BinaryDataReader m_binaryReader; + std::vector m_WriteBuffer; + VectorBinaryWriter m_binaryWriterSM; + BinaryDataReader m_binaryReaderSM; + std::vector m_WriteBufferSM; + std::vector> m_coreObjectsData; + void recordDataBinds(const Artboard* artboard); + void recordStateMachine(const StateMachine* stateMachine); + void recordStateMachineInput(const StateMachineInput* stateMachineInput); + void recordStateMachineLayer(const StateMachineLayer* stateMachineLayer); + void recordStateMachineLayerState(const LayerState* layerState); + void recordLinearAnimation(const LinearAnimation* linearAnimation); + void recordKeyedObject(const KeyedObject* keyedObject); + CoreObjectData* getCoreObjectData(uint32_t id); + void writeProperties(const Artboard* artboard); + void addPropertyKey(CoreObjectData* coreObjectData, int propertyKey); + int getObjectId(const Artboard* artboard, Core* object); + void writeObjectId(uint32_t objectId, VectorBinaryWriter& writer); + void writeTotalProperties(uint32_t value, VectorBinaryWriter& writer); + void writePropertyKey(uint32_t value, VectorBinaryWriter& writer); + void writePropertyValue(float value, VectorBinaryWriter& writer); + void writePropertyValue(int value, VectorBinaryWriter& writer); + void writePropertyValue(uint32_t value, VectorBinaryWriter& writer); + void writePropertyValue(std::string value, VectorBinaryWriter& writer); + void writePropertyValue(bool value, VectorBinaryWriter& writer); + void writeSeparator(); + void complete(VectorBinaryWriter& writer, + BinaryDataReader& reader, + std::vector& buffer); + +public: + PropertyRecorder(); + void recordArtboard(const Artboard* artboard); + void recordStateMachineInputs(const StateMachine* stateMachine); + void apply(Artboard* artboard); + void apply(StateMachineInstance* stateMachineInstace); + void clear(); +}; +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/random_mode.hpp b/thirdparty/rive/include/rive/random_mode.hpp new file mode 100644 index 000000000..6e4a19140 --- /dev/null +++ b/thirdparty/rive/include/rive/random_mode.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_RANDOM_MODE_HPP_ +#define _RIVE_RANDOM_MODE_HPP_ +namespace rive +{ +enum class RandomMode : unsigned char +{ + once = 0, + always = 1, + sourceChange = 2, +}; +} +#endif diff --git a/thirdparty/rive/include/rive/refcnt.hpp b/thirdparty/rive/include/rive/refcnt.hpp index 7a1d69b55..ad38e70ae 100644 --- a/thirdparty/rive/include/rive/refcnt.hpp +++ b/thirdparty/rive/include/rive/refcnt.hpp @@ -232,4 +232,18 @@ inline bool operator!=(const rcp& a, const rcp& b) } // namespace rive +namespace std +{ +template struct hash> +{ + using result_type = std::size_t; + using argument_type = rive::rcp; + + std::size_t operator()(const rive::rcp& up) const + { + return hash()(up.get()); + } +}; + +} // namespace std #endif diff --git a/thirdparty/rive/include/rive/renderer.hpp b/thirdparty/rive/include/rive/renderer.hpp index 88cd39e3f..ff5cbedd0 100644 --- a/thirdparty/rive/include/rive/renderer.hpp +++ b/thirdparty/rive/include/rive/renderer.hpp @@ -5,7 +5,7 @@ #ifndef _RIVE_RENDERER_HPP_ #define _RIVE_RENDERER_HPP_ -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" #include "rive/shapes/paint/color.hpp" #include "rive/command_path.hpp" #include "rive/layout.hpp" @@ -46,7 +46,6 @@ enum class RenderBufferFlags 1 << 0, // The client will map the buffer exactly one time, before // rendering, and will never update it again. }; -RIVE_MAKE_ENUM_BITSET(RenderBufferFlags) class RenderBuffer : public RefCnt, public ENABLE_LITE_RTTI(RenderBuffer) @@ -187,8 +186,9 @@ class RenderPath : public CommandPath, public ENABLE_LITE_RTTI(RenderPath) addRenderPath(path->renderPath(), transform); } - virtual void addRenderPath(RenderPath* path, const Mat2D& transform) = 0; - virtual void addRenderPathBackwards(RenderPath* path, + virtual void addRenderPath(const RenderPath* path, + const Mat2D& transform) = 0; + virtual void addRenderPathBackwards(const RenderPath* path, const Mat2D& transform) { // No-op on non rive renderer. @@ -220,6 +220,12 @@ class Renderer BlendMode, float opacity) = 0; + // Modulate the opacity of subsequent draw calls. The opacity is stacked + // multiplicatively (e.g., modulateOpacity(0.5) followed by + // modulateOpacity(0.2) = 0.1 effective opacity). The modulated opacity is + // captured by save() and restored by restore(). + virtual void modulateOpacity(float opacity) = 0; + // helpers void translate(float x, float y); diff --git a/thirdparty/rive/include/rive/resetting_component.hpp b/thirdparty/rive/include/rive/resetting_component.hpp new file mode 100644 index 000000000..5e4c30bee --- /dev/null +++ b/thirdparty/rive/include/rive/resetting_component.hpp @@ -0,0 +1,15 @@ +#ifndef _RIVE_RESETTING_COMPONENT_HPP_ +#define _RIVE_RESETTING_COMPONENT_HPP_ + +namespace rive +{ +class Component; +class ResettingComponent +{ +public: + virtual void reset() = 0; + static ResettingComponent* from(Component* component); +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/rive_types.hpp b/thirdparty/rive/include/rive/rive_types.hpp index 00f7d8fe9..0ec8bf554 100644 --- a/thirdparty/rive/include/rive/rive_types.hpp +++ b/thirdparty/rive/include/rive/rive_types.hpp @@ -116,23 +116,9 @@ #endif #ifdef DEBUG -#define RIVE_DEBUG_CODE(CODE) CODE +#define RIVE_DEBUG_CODE(...) __VA_ARGS__ #else -#define RIVE_DEBUG_CODE(CODE) +#define RIVE_DEBUG_CODE(...) #endif -// Backports of later stl functions. -namespace rivestd -{ -template std::unique_ptr make_unique(Args&&... args) -{ - return std::unique_ptr(new T(std::forward(args)...)); -} - -template static std::unique_ptr adopt_unique(T* window) -{ - return std::unique_ptr(window); -} -} // namespace rivestd - #endif // rive_types diff --git a/thirdparty/rive/include/rive/scene.hpp b/thirdparty/rive/include/rive/scene.hpp index a6ff80c33..100da442d 100644 --- a/thirdparty/rive/include/rive/scene.hpp +++ b/thirdparty/rive/include/rive/scene.hpp @@ -52,10 +52,12 @@ class Scene : public KeyedCallbackReporter, public CallbackContext virtual void bindViewModelInstance( rcp viewModelInstance); - virtual HitResult pointerDown(Vec2D); - virtual HitResult pointerMove(Vec2D); - virtual HitResult pointerUp(Vec2D); - virtual HitResult pointerExit(Vec2D); + virtual HitResult pointerDown(Vec2D, int pointerId = 0); + virtual HitResult pointerMove(Vec2D position, + float timeStamp = 0, + int pointerId = 0); + virtual HitResult pointerUp(Vec2D, int pointerId = 0); + virtual HitResult pointerExit(Vec2D, int pointerId = 0); virtual size_t inputCount() const; virtual SMIInput* input(size_t index) const; diff --git a/thirdparty/rive/include/rive/script_input_artboard.hpp b/thirdparty/rive/include/rive/script_input_artboard.hpp new file mode 100644 index 000000000..01dfbde35 --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_artboard.hpp @@ -0,0 +1,42 @@ +#ifndef _RIVE_SCRIPT_INPUT_ARTBOARD_HPP_ +#define _RIVE_SCRIPT_INPUT_ARTBOARD_HPP_ +#include "rive/artboard_referencer.hpp" +#include "rive/generated/script_input_artboard_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" +#include +namespace rive +{ +class Artboard; + +class ScriptInputArtboard : public ScriptInputArtboardBase, + public ScriptInput, + public ArtboardReferencer +{ +private: + File* m_file = nullptr; + void syncReferencedArtboard(); + +public: + ~ScriptInputArtboard(); + void initScriptedValue() override; + bool validateForScriptInit() override + { + return m_referencedArtboard != nullptr; + } + bool validateForColdScriptInit() override; + bool hydrateScriptInput() override; + bool validateHydrationPrerequisites() override; + StatusCode import(ImportStack& importStack) override; + Core* clone() const override; + StatusCode onAddedClean(CoreContext* context) override; + void file(File* value) { m_file = value; }; + void artboardIdChanged() override; + void updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) override; + int referencedArtboardId() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/script_input_boolean.hpp b/thirdparty/rive/include/rive/script_input_boolean.hpp new file mode 100644 index 000000000..12190581b --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_boolean.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_SCRIPT_INPUT_BOOLEAN_HPP_ +#define _RIVE_SCRIPT_INPUT_BOOLEAN_HPP_ +#include "rive/generated/script_input_boolean_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptInputBoolean : public ScriptInputBooleanBase, public ScriptInput +{ +protected: + void propertyValueChanged() override; + +public: + ~ScriptInputBoolean(); + void initScriptedValue() override + { + ScriptInput::initScriptedValue(); + auto obj = scriptedObject(); + if (obj) + { + obj->setBooleanInput(name(), propertyValue()); + } + } + bool validateForScriptInit() override { return true; } + StatusCode import(ImportStack& importStack) override; + StatusCode onAddedClean(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/script_input_color.hpp b/thirdparty/rive/include/rive/script_input_color.hpp new file mode 100644 index 000000000..6e703af59 --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_color.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_SCRIPT_INPUT_COLOR_HPP_ +#define _RIVE_SCRIPT_INPUT_COLOR_HPP_ +#include "rive/generated/script_input_color_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptInputColor : public ScriptInputColorBase, public ScriptInput +{ +protected: + void propertyValueChanged() override; + +public: + ~ScriptInputColor(); + void initScriptedValue() override + { + ScriptInput::initScriptedValue(); + auto obj = scriptedObject(); + if (obj) + { + obj->setIntegerInput(name(), propertyValue()); + } + } + bool validateForScriptInit() override { return true; } + StatusCode import(ImportStack& importStack) override; + StatusCode onAddedClean(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/script_input_number.hpp b/thirdparty/rive/include/rive/script_input_number.hpp new file mode 100644 index 000000000..95db330d8 --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_number.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_SCRIPT_INPUT_NUMBER_HPP_ +#define _RIVE_SCRIPT_INPUT_NUMBER_HPP_ +#include "rive/generated/script_input_number_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptInputNumber : public ScriptInputNumberBase, public ScriptInput +{ +protected: + void propertyValueChanged() override; + +public: + ~ScriptInputNumber(); + void initScriptedValue() override + { + ScriptInput::initScriptedValue(); + auto obj = scriptedObject(); + if (obj) + { + obj->setNumberInput(name(), propertyValue()); + } + } + StatusCode onAddedClean(CoreContext* context) override; + bool validateForScriptInit() override { return true; } + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/script_input_string.hpp b/thirdparty/rive/include/rive/script_input_string.hpp new file mode 100644 index 000000000..2d7e227c1 --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_string.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_SCRIPT_INPUT_STRING_HPP_ +#define _RIVE_SCRIPT_INPUT_STRING_HPP_ +#include "rive/generated/script_input_string_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptInputString : public ScriptInputStringBase, public ScriptInput +{ +protected: + void propertyValueChanged() override; + +public: + ~ScriptInputString(); + void initScriptedValue() override + { + ScriptInput::initScriptedValue(); + auto obj = scriptedObject(); + if (obj) + { + obj->setStringInput(name(), propertyValue()); + } + } + bool validateForScriptInit() override { return true; } + StatusCode import(ImportStack& importStack) override; + StatusCode onAddedClean(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/script_input_trigger.hpp b/thirdparty/rive/include/rive/script_input_trigger.hpp new file mode 100644 index 000000000..1d8178724 --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_trigger.hpp @@ -0,0 +1,22 @@ +#ifndef _RIVE_SCRIPT_INPUT_TRIGGER_HPP_ +#define _RIVE_SCRIPT_INPUT_TRIGGER_HPP_ +#include "rive/generated/script_input_trigger_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class ScriptInputTrigger : public ScriptInputTriggerBase, public ScriptInput +{ +protected: + void propertyValueChanged() override; + +public: + ~ScriptInputTrigger(); + bool validateForScriptInit() override { return true; } + StatusCode import(ImportStack& importStack) override; + StatusCode onAddedClean(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/script_input_viewmodel_property.hpp b/thirdparty/rive/include/rive/script_input_viewmodel_property.hpp new file mode 100644 index 000000000..ec71db544 --- /dev/null +++ b/thirdparty/rive/include/rive/script_input_viewmodel_property.hpp @@ -0,0 +1,34 @@ +#ifndef _RIVE_SCRIPT_INPUT_VIEW_MODEL_PROPERTY_HPP_ +#define _RIVE_SCRIPT_INPUT_VIEW_MODEL_PROPERTY_HPP_ +#include "rive/generated/script_input_viewmodel_property_base.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/data_bind_path_referencer.hpp" +#include +namespace rive +{ +class ViewModelInstanceValue; + +class ScriptInputViewModelProperty : public ScriptInputViewModelPropertyBase, + public ScriptInput, + public DataBindPathReferencer +{ +private: + ViewModelInstanceValue* m_viewModelInstanceValue; + +public: + ~ScriptInputViewModelProperty(); + void decodeDataBindPathIds(Span value) override; + void copyDataBindPathIds( + const ScriptInputViewModelPropertyBase& object) override; + void initScriptedValue() override; + bool validateForScriptInit() override; + bool validateForColdScriptInit() override; + bool hydrateScriptInput() override; + bool validateHydrationPrerequisites() override; + StatusCode import(ImportStack& importStack) override; + StatusCode onAddedClean(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/scripted/scripted_data_converter.hpp b/thirdparty/rive/include/rive/scripted/scripted_data_converter.hpp new file mode 100644 index 000000000..995970315 --- /dev/null +++ b/thirdparty/rive/include/rive/scripted/scripted_data_converter.hpp @@ -0,0 +1,70 @@ +#ifndef _RIVE_SCRIPTED_DATA_CONVERTER_HPP_ +#define _RIVE_SCRIPTED_DATA_CONVERTER_HPP_ +#include "rive/generated/scripted/scripted_data_converter_base.hpp" +#include "rive/advancing_component.hpp" +#include "rive/scripted/scripted_object.hpp" +#include +namespace rive +{ +class DataBind; +class DataContext; +class DataValue; + +class ScriptedDataConverter : public ScriptedDataConverterBase, + public ScriptedObject, + public AdvancingComponent +{ +private: + rcp m_dataContext = nullptr; + DataValue* m_dataValue = nullptr; + template void storeData(DataValue* input) + { + if (m_dataValue && !m_dataValue->is()) + { + delete m_dataValue; + } + if (!m_dataValue) + { + m_dataValue = new T(); + } + m_dataValue->as()->value(input->as()->value()); + }; + virtual void disposeScriptInputs() override; +#ifdef WITH_RIVE_SCRIPTING + DataValue* applyConversion(DataValue* value, const std::string& method); + bool pushDataValue(DataValue*); +#endif + +public: + ~ScriptedDataConverter(); +#ifdef WITH_RIVE_SCRIPTING + void didHydrateScriptInputs() override; + DataValue* convert(DataValue* value, DataBind* dataBind) override; + DataValue* reverseConvert(DataValue* value, DataBind* dataBind) override; +#endif + void bindFromContext(DataContext* dataContext, DataBind* dataBind) override; + rcp dataContext() override { return m_dataContext; } + DataType outputType() override { return DataType::any; } + uint32_t assetId() override { return scriptAssetId(); } + bool advanceComponent(float elapsedSeconds, + AdvanceFlags flags = AdvanceFlags::Animate | + AdvanceFlags::NewFrame) override; + bool advance(float elapsedSeconds) override; + StatusCode import(ImportStack& importStack) override; + void addProperty(CustomProperty* prop) override; + Core* clone() const override; + bool addScriptedDirt(ComponentDirt value, bool recurse = false) override + { + markConverterDirty(); + return true; + } + ScriptProtocol scriptProtocol() override + { + return ScriptProtocol::converter; + } + Component* component() override { return nullptr; } + bool addDataBindFromScriptedObject(DataBind*) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/scripted/scripted_drawable.hpp b/thirdparty/rive/include/rive/scripted/scripted_drawable.hpp new file mode 100644 index 000000000..9493f7cf1 --- /dev/null +++ b/thirdparty/rive/include/rive/scripted/scripted_drawable.hpp @@ -0,0 +1,99 @@ +#ifndef _RIVE_SCRIPTED_DRAWABLE_HPP_ +#define _RIVE_SCRIPTED_DRAWABLE_HPP_ +#include "rive/generated/scripted/scripted_drawable_base.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/advancing_component.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/listener_group.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/custom_property_group.hpp" +#include +namespace rive +{ +class Component; +class HitComponent; +class HitScriptedDrawable; + +class ScriptedDrawable : public ScriptedDrawableBase, + public ScriptedObject, + public AdvancingComponent, + public ListenerGroupProvider +{ +public: +#ifdef WITH_RIVE_SCRIPTING + void didHydrateScriptInputs() override; +#endif + void draw(Renderer* renderer) override; + void update(ComponentDirt value) override; + Core* hitTest(HitInfo*, const Mat2D&) override; + uint32_t assetId() override { return scriptAssetId(); } + StatusCode onAddedDirty(CoreContext* context) override; + bool advanceComponent(float elapsedSeconds, + AdvanceFlags flags = AdvanceFlags::Animate | + AdvanceFlags::NewFrame) override; + StatusCode import(ImportStack& importStack) override; + Core* clone() const override; + const std::vector& containerChildren() const override + { + return children(); + } + void addProperty(CustomProperty* prop) override; + bool addScriptedDirt(ComponentDirt value, bool recurse = false) override; + rcp dataContext() override + { + if (artboard() != nullptr) + { + return artboard()->dataContext(); + } + return nullptr; + } + ScriptProtocol scriptProtocol() override { return ScriptProtocol::node; } + std::vector listenerGroups() override + { + return {}; + } + std::vector hitComponents(StateMachineInstance* sm) override; + bool worldToLocal(Vec2D world, Vec2D* local); + void markNeedsUpdate() override; + bool willDraw() override; + Component* component() override { return this; } + bool keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat); + bool textInput(const std::string& text); + +private: + bool m_isAdvanceActive = true; +}; + +class HitScriptedDrawable : public HitComponent +{ +private: + ScriptedDrawable* m_drawable; + bool handlesEvent(bool canHit, ListenerType hitEvent); + std::string methodName(bool canHit, ListenerType hitEvent); + +public: + HitScriptedDrawable(ScriptedDrawable* drawable, + StateMachineInstance* stateMachineInstance) : + HitComponent(drawable, stateMachineInstance) + { + this->m_drawable = drawable; + } + + bool hitTest(Vec2D position) const override { return true; } + void prepareEvent(Vec2D position, + ListenerType hitType, + int pointerId) override + {} + + HitResult processEvent(Vec2D position, + ListenerType hitType, + bool canHit, + float timeStamp, + int pointerId) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/scripted/scripted_layout.hpp b/thirdparty/rive/include/rive/scripted/scripted_layout.hpp new file mode 100644 index 000000000..57abc720e --- /dev/null +++ b/thirdparty/rive/include/rive/scripted/scripted_layout.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_SCRIPTED_LAYOUT_HPP_ +#define _RIVE_SCRIPTED_LAYOUT_HPP_ +#include "rive/layout/layout_enums.hpp" +#include "rive/layout/layout_measure_mode.hpp" +#include "rive/generated/scripted/scripted_layout_base.hpp" +#include +namespace rive +{ +class ScriptedLayout : public ScriptedLayoutBase +{ +private: + Vec2D m_size; +#ifdef WITH_RIVE_SCRIPTING + void callScriptedResize(Vec2D size); +#endif + +public: +#ifdef WITH_RIVE_SCRIPTING + void didHydrateScriptInputs() override; +#endif + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) override; + + void controlSize(Vec2D size, + LayoutScaleType widthScaleType, + LayoutScaleType heightScaleType, + LayoutDirection direction) override; + void addProperty(CustomProperty* prop) override; + Core* clone() const override; + ScriptProtocol scriptProtocol() override { return ScriptProtocol::layout; } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/scripted/scripted_object.hpp b/thirdparty/rive/include/rive/scripted/scripted_object.hpp new file mode 100644 index 000000000..601b0ff09 --- /dev/null +++ b/thirdparty/rive/include/rive/scripted/scripted_object.hpp @@ -0,0 +1,123 @@ +#ifndef _RIVE_SCRIPTED_OBJECT_HPP_ +#define _RIVE_SCRIPTED_OBJECT_HPP_ +#include "rive/assets/file_asset_referencer.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/custom_property.hpp" +#include "rive/custom_property_container.hpp" +#include "rive/refcnt.hpp" +#include "rive/generated/assets/script_asset_base.hpp" +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/scripting_vm.hpp" +#endif +#include +#include + +namespace rive +{ +class Artboard; +class Component; +class DataContext; +class ViewModelInstanceValue; +class DataBindContainer; +class ScriptedProperty; +class ScriptedContext; + +class ScriptedObject : public FileAssetReferencer, + public CustomPropertyContainer, + public OptionalScriptedMethods +{ +protected: + int m_self = 0; + int m_context = 0; + ScriptedContext* m_contextPtr = nullptr; + virtual void disposeScriptInputs(); +#ifdef WITH_RIVE_SCRIPTING +#ifdef WITH_RIVE_TOOLS + rcp m_vm = nullptr; // Ref-counted for editor +#else + ScriptingVM* m_vm = nullptr; // Non-owning for runtime +#endif +#endif +private: + rcp m_dataContext = nullptr; + std::vector m_trackedScriptedProperties; +#ifdef WITH_RIVE_SCRIPTING + bool m_userLuaInitDone = false; + bool tryLuaUserInit(lua_State* L); +#endif + void disposeScriptedContext(); + void disposeTrackedProperties(); + +public: + virtual ~ScriptedObject() { scriptDispose(); } + ScriptAsset* scriptAsset() const; + void setArtboardInput(std::string name, Artboard* artboard); + void setBooleanInput(std::string name, bool value); + void setIntegerInput(std::string name, int value); + void setNumberInput(std::string name, float value); + void setStringInput(std::string name, std::string value); + void setViewModelInput(std::string name, ViewModelInstanceValue* value); + void trigger(std::string name); + bool scriptAdvance(float elapsedSeconds); + void scriptDrawCanvas(); + void scriptUpdate(); + void reinit(); +#ifdef WITH_RIVE_SCRIPTING + bool userLuaInitDone() { return m_userLuaInitDone; } +#else + bool userLuaInitDone() { return true; } +#endif + virtual void markNeedsUpdate(); + virtual rcp dataContext() { return m_dataContext; } + void dataContext(rcp value) { m_dataContext = value; } +#ifdef WITH_RIVE_SCRIPTING + /// Load Lua factory result into m_self once per VM; does not push inputs or + /// call Lua init(); use hydrateScriptInputs() after data bind. + bool ensureScriptInitialized(ScriptingVM* vm); + /// Resolve inputs from DataContext and push into Lua; runs Lua init() once + /// after first successful hydration when implemented. + bool hydrateScriptInputs(); + lua_State* state() const { return m_vm ? m_vm->state() : nullptr; } +#else + bool hydrateScriptInputs() { return true; } +#endif + void scriptDispose(); + virtual bool addScriptedDirt(ComponentDirt value, bool recurse = false) = 0; + void setAsset(rcp asset) override; + static ScriptedObject* from(Core* object); + virtual ScriptProtocol scriptProtocol() = 0; + int self() { return m_self; } + virtual Component* component() = 0; + virtual ScriptedObject* cloneScriptedObject(DataBindContainer*) const + { + return nullptr; + } + void cloneProperties(CustomPropertyContainer*, DataBindContainer*) const; + void addTrackedScriptedProperty(ScriptedProperty* property) + { + if (property != nullptr) + { + m_trackedScriptedProperties.push_back(property); + } + } + void removeTrackedScriptedProperty(ScriptedProperty* property) + { + auto it = std::remove(m_trackedScriptedProperties.begin(), + m_trackedScriptedProperties.end(), + property); + m_trackedScriptedProperties.erase(it, + m_trackedScriptedProperties.end()); + } + const std::vector& trackedScriptedProperties() const + { + return m_trackedScriptedProperties; + } + virtual bool addDataBindFromScriptedObject(DataBind*) { return false; } +#ifdef WITH_RIVE_SCRIPTING + /// Called after hydrateScriptInputs() succeeds; + virtual void didHydrateScriptInputs() {} +#endif +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/scripted/scripted_path_effect.hpp b/thirdparty/rive/include/rive/scripted/scripted_path_effect.hpp new file mode 100644 index 000000000..128245e0e --- /dev/null +++ b/thirdparty/rive/include/rive/scripted/scripted_path_effect.hpp @@ -0,0 +1,69 @@ +#ifndef _RIVE_SCRIPTED_PATH_EFFECT_HPP_ +#define _RIVE_SCRIPTED_PATH_EFFECT_HPP_ +#include "rive/generated/scripted/scripted_path_effect_base.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/advancing_component.hpp" +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/stroke_effect.hpp" +#include +namespace rive +{ + +class ScriptedEffectPath : public EffectPath +{ +public: + void invalidateEffect() override; + ShapePaintPath* path() override { return &m_path; } + +private: + ShapePaintPath m_path; +}; +class ScriptedPathEffect : public ScriptedPathEffectBase, + public ScriptedObject, + public AdvancingComponent, + public StrokeEffect +{ +public: +#ifdef WITH_RIVE_SCRIPTING + void didHydrateScriptInputs() override; +#endif + void addProperty(CustomProperty* prop) override; + StatusCode onAddedClean(CoreContext* context) override; + StatusCode onAddedDirty(CoreContext* context) override; + uint32_t assetId() override { return scriptAssetId(); } + bool advanceComponent(float elapsedSeconds, + AdvanceFlags flags = AdvanceFlags::Animate | + AdvanceFlags::NewFrame) override; + bool addScriptedDirt(ComponentDirt value, bool recurse = false) override; + void buildDependencies() override; + void update(ComponentDirt value) override; + rcp dataContext() override + { + if (artboard() != nullptr) + { + return artboard()->dataContext(); + } + return nullptr; + } + ScriptProtocol scriptProtocol() override + { + return ScriptProtocol::pathEffect; + } + void updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) override; + StatusCode import(ImportStack& importStack) override; + Core* clone() const override; + void markNeedsUpdate() override; + Component* component() override { return this; } + EffectsContainer* parentPaint() override; + +protected: + virtual EffectPath* createEffectPath() override; + +private: + bool m_isAdvanceActive = true; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/semantic/semantic_data.hpp b/thirdparty/rive/include/rive/semantic/semantic_data.hpp new file mode 100644 index 000000000..0a2f55396 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_data.hpp @@ -0,0 +1,79 @@ +#ifndef _RIVE_SEMANTIC_DATA_HPP_ +#define _RIVE_SEMANTIC_DATA_HPP_ + +#include "rive/component_dirt.hpp" +#include "rive/generated/semantic/semantic_data_base.hpp" +#include "rive/semantic/semantic_node.hpp" +#include "rive/refcnt.hpp" + +#include + +namespace rive +{ +class SemanticListener; +class SemanticManager; + +class SemanticData : public SemanticDataBase +{ +public: + ~SemanticData() override; + + rcp semanticNode(); + bool hasSemanticNode() const { return m_semanticNode != nullptr; } + + /// Set or clear the Focused state flag on the underlying SemanticNode. + /// This is runtime-driven (not authored), so it modifies the node directly. + void setFocusedState(bool focused); + + /// Request focus on a sibling FocusData (if any) via the FocusManager. + /// Returns true if focus was successfully set. + bool requestFocus(); + + /// Register/unregister a SemanticListener for semantic action callbacks. + void addSemanticListener(SemanticListener* listener); + void removeSemanticListener(SemanticListener* listener); + + /// Fire semantic actions, notifying all registered listeners. + void fireSemanticTap(); + void fireSemanticIncrease(); + void fireSemanticDecrease(); + + /// Find the parent SemanticData by walking up the component hierarchy. + SemanticData* findParentSemanticData() const; + + /// Find the closest SemanticNode for a component by walking up the + /// hierarchy. Crosses artboard boundaries via externalParentSemanticNode. + static rcp findClosestSemanticNode(Component* component); + + // Component overrides for update cycle + bool collapse(bool value) override; + void buildDependencies() override; + void update(ComponentDirt value) override; + void syncSemanticTreeVisibility(); + +protected: + void roleChanged() override; + void labelChanged() override; + void stateFlagsChanged() override; + void traitFlagsChanged() override; + void valueChanged() override; + void hintChanged() override; + void headingLevelChanged() override; + + uint32_t semanticId() const; + +private: + bool shouldExcludeFromSemanticTree() const; + rcp resolveParentNode() const; + void updateWorldBounds(); + void markContentDirty(); + void applyInferredSemanticsIfNeeded(); + rcp m_semanticNode; + SemanticManager* m_semanticManager = nullptr; + std::vector m_semanticListeners; + bool m_boundsRetryPending = false; + bool m_excludedFromTree = false; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_dirt.hpp b/thirdparty/rive/include/rive/semantic/semantic_dirt.hpp new file mode 100644 index 000000000..891ba21ec --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_dirt.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_SEMANTIC_DIRT_HPP_ +#define _RIVE_SEMANTIC_DIRT_HPP_ + +#include "rive/enums.hpp" +#include + +namespace rive +{ + +enum class SemanticDirt : uint8_t +{ + None = 0, + Structure = 1 << 0, + Content = 1 << 1, + Bounds = 1 << 2, + All = (1 << 0) | (1 << 1) | (1 << 2), +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_listener.hpp b/thirdparty/rive/include/rive/semantic/semantic_listener.hpp new file mode 100644 index 000000000..72a075da3 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_listener.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_SEMANTIC_LISTENER_HPP_ +#define _RIVE_SEMANTIC_LISTENER_HPP_ + +namespace rive +{ + +/// Interface for objects that want to be notified of semantic actions on a +/// SemanticData. +class SemanticListener +{ +public: + virtual ~SemanticListener() = default; + + /// Called when a semantic tap/activate action is fired. + virtual void onSemanticTap() = 0; + + /// Called when a semantic increase action is fired (e.g. slider step up). + virtual void onSemanticIncrease() = 0; + + /// Called when a semantic decrease action is fired (e.g. slider step down). + virtual void onSemanticDecrease() = 0; +}; + +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_manager.hpp b/thirdparty/rive/include/rive/semantic/semantic_manager.hpp new file mode 100644 index 000000000..e2fbc0005 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_manager.hpp @@ -0,0 +1,100 @@ +#ifndef _RIVE_SEMANTIC_MANAGER_HPP_ +#define _RIVE_SEMANTIC_MANAGER_HPP_ + +#include "rive/refcnt.hpp" +#include "rive/semantic/semantic_dirt.hpp" +#include "rive/semantic/semantic_node.hpp" +#include "rive/semantic/semantic_snapshot.hpp" + +#include +#include +#include +#include + +namespace rive +{ +class Artboard; + +// Owns the semantic tree, tracks dirty state, and produces incremental +// SemanticsDiff payloads. Created by StateMachineInstance, populated by +// Artboard::buildSemanticTree(), consumed via SemanticManager::drainDiff(). +class SemanticManager +{ +public: + explicit SemanticManager() {} + + void addChild(rcp parentNode, rcp child); + void removeChild(rcp node); + + void markDirty(SemanticDirt dirt = SemanticDirt::All) + { + m_dirt = m_dirt | dirt; + } + void markNodeDirty(uint32_t id, SemanticDirt dirt = SemanticDirt::All); + + /// Mark a boundary node as having a dirty host transform. During the + /// next drainDiff(), bounds will be re-read for all semantic nodes under + /// this boundary instead of polling all nodes globally. + void markBoundaryDirty(uint32_t boundaryNodeId); + bool isDirty() const { return m_dirt != SemanticDirt::None; } + uint64_t version() const { return m_version; } + + // Look up a SemanticNode by its unique ID. Returns nullptr if not found. + SemanticNode* nodeById(uint32_t id) const + { + auto it = m_nodesById.find(id); + return it != m_nodesById.end() ? it->second.get() : nullptr; + } + + // Request focus on the FocusData sibling of the SemanticData that owns + // the given semantic node ID. Returns true if focus was set. + bool requestFocus(uint32_t semanticNodeId); + + // Rebuild the tree if dirty and return the diff since the last call. + // Returns an empty diff when nothing changed. Clears internal state so + // the next call starts fresh. + SemanticsDiff drainDiff(); + +private: + void refresh(); + SemanticsDiff consumeDiff(); + void patchBoundsNode(SemanticsDiffNode& entry, SemanticsDiff& diff); + void patchContentNode(SemanticsDiffNode& entry, SemanticsDiff& diff); + void reconcileBoundsForSubtree(SemanticNode* node); + + // Sorts children of every node in the given forest by visual position + // (top-to-bottom, left-to-right), recursively. Defined here (as a + // private static member rather than a free helper) so it can use + // SemanticNode::mutableChildren() through the friend relationship. + static void sortChildrenByVisualPosition( + std::vector>& nodes); + + // Assign a manager-local id to a freshly registered node (id == 0), + // or reconcile the watermark for an explicitly-provided id. Called from + // addChild() before the node is inserted in m_nodesById. + void ensureNodeId(SemanticNode& node); + + SemanticDirt m_dirt = SemanticDirt::All; + SemanticsDiff m_lastDiff; + std::vector m_lastFlatSnapshot; + uint64_t m_version = 0; + // Next id for auto-assignment; starts at 1 so 0 can remain an + // "unassigned" sentinel. Scoped per-manager so two unrelated managers + // in the same process can both start fresh without colliding. + uint32_t m_nextLocalId = 1; + std::unordered_map> m_nodesById; + std::vector> m_roots; + std::unordered_set m_dirtyContentNodes; + std::unordered_set m_dirtyBoundsNodes; + std::unordered_set m_dirtyBoundaryIds; + + // Label derivation state from the last full flatten. Interactive nodes + // that derived their label from children have entries in m_derivedLabels. + // Children that were absorbed (flattened) are tracked in m_excludedIds + // so the incremental path can detect when re-derivation is needed. + std::unordered_map m_derivedLabels; + std::unordered_set m_excludedIds; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_node.hpp b/thirdparty/rive/include/rive/semantic/semantic_node.hpp new file mode 100644 index 000000000..22c85ede2 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_node.hpp @@ -0,0 +1,137 @@ +#ifndef _RIVE_SEMANTIC_NODE_HPP_ +#define _RIVE_SEMANTIC_NODE_HPP_ + +#include "rive/math/aabb.hpp" +#include "rive/refcnt.hpp" + +#include +#include +#include + +namespace rive +{ +class Artboard; +class Core; +class SemanticManager; + +// Ref-counted tree node holding all data needed by platform accessibility. +// Created lazily by SemanticData::semanticNode() and registered with +// SemanticManager via addChild(). The manager flattens these into +// SemanticsDiffNode structs for platform consumption. +// +// Ids are scoped to the owning SemanticManager: a node is constructed +// with id == 0 (unassigned) and receives a manager-local id on first +// addChild(). This avoids collisions when multiple independent +// SemanticManagers (e.g. two unrelated artboards in the same process) +// outlive a single process-global counter. +// +// Callers that want a deterministic id (tests, serialization round-trips) +// may construct with an explicit id; SemanticManager will preserve it and +// bump its watermark to avoid future collisions. +// +// Access model: +// - Authored-value mutators (role, label, value, hint, headingLevel, +// stateFlags, traitFlags, bounds) are public: SemanticData writes +// them from its property-change handlers, Artboard sets them on +// boundary nodes, tests use them to hand-build trees. +// - Construction-time back-refs (coreOwner, semanticData, isBoundaryNode) +// are public: set once at node creation, never again. +// - Structural mutators (parent, mutable children, manager, +// id assignment) live behind `friend class SemanticManager`. The +// manager is the only code allowed to wire the tree or rebind a +// node to a different manager. +class SemanticNode : public RefCnt +{ +public: + explicit SemanticNode(uint32_t id = 0) : m_id(id) {} + + uint32_t id() const { return m_id; } + + SemanticNode* parent() const { return m_parent; } + + const std::vector>& children() const + { + return m_children; + } + + void role(uint32_t value) { m_role = value; } + uint32_t role() const { return m_role; } + + void stateFlags(uint32_t value) { m_stateFlags = value; } + uint32_t stateFlags() const { return m_stateFlags; } + + void label(const std::string& value) { m_label = value; } + const std::string& label() const { return m_label; } + + void value(const std::string& v) { m_value = v; } + const std::string& value() const { return m_value; } + + void hint(const std::string& v) { m_hint = v; } + const std::string& hint() const { return m_hint; } + + void headingLevel(uint32_t v) { m_headingLevel = v; } + uint32_t headingLevel() const { return m_headingLevel; } + + AABB bounds() const { return m_bounds; } + void bounds(const AABB& value) { m_bounds = value; } + + void traitFlags(uint32_t value) { m_traitFlags = value; } + uint32_t traitFlags() const { return m_traitFlags; } + + Core* coreOwner() const { return m_coreOwner; } + void coreOwner(Core* value) { m_coreOwner = value; } + + SemanticManager* manager() const { return m_manager; } + + /// Boundary nodes are structural-only nodes inserted at artboard + /// boundaries. They are skipped during flattening (children reparented + /// upward) but participate in tree management for O(1) subtree + /// collapse/uncollapse and targeted bounds dirtying. + bool isBoundaryNode() const { return m_isBoundaryNode; } + void isBoundaryNode(bool value) { m_isBoundaryNode = value; } + + /// For boundary nodes, the nested Artboard whose region this boundary + /// represents. The boundary's bounds are the artboard's rect mapped + /// through its rootTransform into root space. + Artboard* boundaryArtboard() const { return m_boundaryArtboard; } + void boundaryArtboard(Artboard* value) { m_boundaryArtboard = value; } + + /// Back-pointer to the SemanticData that owns this node. Null for + /// boundary nodes. Used for direct collapse without walking the + /// component hierarchy. + class SemanticData* semanticData() const { return m_semanticData; } + void semanticData(class SemanticData* value) { m_semanticData = value; } + +private: + // SemanticManager is the only class allowed to rewire the tree, + // assign/reassign ids, or rebind a node to a different manager. + friend class SemanticManager; + + void id(uint32_t value) { m_id = value; } + void parent(SemanticNode* value) { m_parent = value; } + std::vector>& mutableChildren() { return m_children; } + void manager(SemanticManager* m) { m_manager = m; } + + uint32_t m_id; + SemanticNode* m_parent = nullptr; + std::vector> m_children; + uint32_t m_role = 0; + uint32_t m_stateFlags = 0; + std::string m_label = ""; + std::string m_value = ""; + std::string m_hint = ""; + uint32_t m_headingLevel = 0; + // Default to "no bounds" rather than (0,0,0,0) which looks like a + // valid position at the origin. forExpansion() has minX > maxX so + // isEmptyOrNaN() returns true. + AABB m_bounds = AABB::forExpansion(); + uint32_t m_traitFlags = 0; + Core* m_coreOwner = nullptr; + SemanticManager* m_manager = nullptr; + bool m_isBoundaryNode = false; + class SemanticData* m_semanticData = nullptr; + Artboard* m_boundaryArtboard = nullptr; +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_provider.hpp b/thirdparty/rive/include/rive/semantic/semantic_provider.hpp new file mode 100644 index 000000000..313e066e0 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_provider.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_SEMANTIC_PROVIDER_HPP_ +#define _RIVE_SEMANTIC_PROVIDER_HPP_ + +#include "rive/math/aabb.hpp" +#include +#include + +namespace rive +{ +class Artboard; +class Component; + +struct ResolvedSemanticData +{ + bool hasSemantics = false; + uint32_t role = 0; + std::string label = ""; +}; + +class SemanticProvider +{ +public: + // Returns true if this component can have inferred semantics (e.g. Text). + static bool canInferSemantics(Component* component); + // Resolve semantic data from a SemanticData component child. + static ResolvedSemanticData resolveSemanticData(Component* component); + // Compute bounds in root artboard space. + static AABB semanticBounds(Component* component); + // Map an AABB in the given artboard's space through its rootTransform + // to the outermost artboard's space. All four corners are mapped and + // re-enclosed so rotation/shear in nested hosts is handled correctly. + static AABB rootTransformAABB(Artboard* ab, const AABB& bounds); +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_role.hpp b/thirdparty/rive/include/rive/semantic/semantic_role.hpp new file mode 100644 index 000000000..271e15f13 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_role.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_SEMANTIC_ROLE_HPP_ +#define _RIVE_SEMANTIC_ROLE_HPP_ + +#include + +namespace rive +{ +enum class SemanticRole : uint8_t +{ + none = 0, + + // Actions + button = 1, + link = 2, + + // Controls + checkbox = 3, + switchControl = 4, + slider = 5, + textField = 6, + + // Content + text = 7, + image = 8, + + // Structure + group = 9, + list = 10, + listItem = 11, + + // Navigation + tab = 12, + tabList = 13, + + // Phase 2 + dialog = 14, + alertDialog = 15, + radioGroup = 16, + radioButton = 17, +}; + +/// Returns true for roles that derive their accessible label from child +/// semantic nodes when no explicit label is authored. These roles also +/// flatten (absorb) the children that contributed to the derived label. +/// Note: textField is excluded — it requires an explicit label or external +/// association per accessibility guidelines. +inline bool isInteractiveRole(SemanticRole role) +{ + switch (role) + { + case SemanticRole::button: + case SemanticRole::link: + case SemanticRole::checkbox: + case SemanticRole::switchControl: + case SemanticRole::slider: + case SemanticRole::tab: + case SemanticRole::listItem: + case SemanticRole::radioButton: + return true; + default: + return false; + } +} + +inline bool isInteractiveRole(uint32_t roleValue) +{ + return isInteractiveRole(static_cast(roleValue)); +} +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_snapshot.hpp b/thirdparty/rive/include/rive/semantic/semantic_snapshot.hpp new file mode 100644 index 000000000..c90534eb2 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_snapshot.hpp @@ -0,0 +1,92 @@ +#ifndef _RIVE_SEMANTIC_SNAPSHOT_HPP_ +#define _RIVE_SEMANTIC_SNAPSHOT_HPP_ + +#include +#include +#include + +namespace rive +{ +// Flattened node payload used by incremental deltas. Produced by +// SemanticManager::refresh() and consumed by platform runtimes via +// SemanticManager::drainDiff(). +struct SemanticsDiffNode +{ + uint32_t id = 0; + uint32_t role = 0; + std::string label = ""; + std::string value = ""; + std::string hint = ""; + uint32_t stateFlags = 0; + uint32_t traitFlags = 0; + uint32_t headingLevel = 0; + float minX = 0.0f; + float minY = 0.0f; + float maxX = 0.0f; + float maxY = 0.0f; + // -1 means root. + int32_t parentId = -1; + // Sibling position under parent (or root index if parent is -1). + uint32_t siblingIndex = 0; +}; + +// Parent children list update for robust reorder/reparent sync. +// parentId == -1 updates root ordering. +struct SemanticsChildrenUpdate +{ + // -1 means roots list order. + int32_t parentId = -1; + // Full ordered child list for the parent. + std::vector childIds; +}; + +// Minimal bounds-only update for the hot path — avoids string allocations +// when only geometry changes frame-to-frame. +struct SemanticsBoundsUpdate +{ + uint32_t id = 0; + float minX = 0.0f; + float minY = 0.0f; + float maxX = 0.0f; + float maxY = 0.0f; +}; + +// Incremental delta payload emitted by SemanticManager::refresh(). +// Platform runtimes consume this to incrementally update their +// accessibility trees. +// +// Ordering contract (stable; platform adapters may rely on it): +// - added, moved, updatedSemantic, updatedGeometry are emitted in +// current-tree pre-order. A parent always precedes its children within +// the same array. +// - removed is emitted in previous-tree pre-order. +// - childrenUpdated lists parent ids in the order their subtrees are +// first entered during a pre-order walk of the current tree; parents +// that existed only in the previous tree are appended in previous-tree +// order. Each entry's childIds is the full authoritative child list. +// +// A minimal adapter may process the arrays in the order (removed, added, +// moved, childrenUpdated, updatedSemantic, updatedGeometry) and, within +// each array, iterate linearly without a deferred-attachment queue. +struct SemanticsDiff +{ + uint64_t frameNumber = 0; + uint64_t treeVersion = 0; + uint32_t rootId = 0; + std::vector removed; + std::vector added; + std::vector moved; + std::vector childrenUpdated; + std::vector updatedSemantic; + std::vector updatedGeometry; + + bool empty() const + { + return removed.empty() && added.empty() && moved.empty() && + childrenUpdated.empty() && updatedSemantic.empty() && + updatedGeometry.empty(); + } +}; +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_state.hpp b/thirdparty/rive/include/rive/semantic/semantic_state.hpp new file mode 100644 index 000000000..632d64362 --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_state.hpp @@ -0,0 +1,69 @@ +#ifndef _RIVE_SEMANTIC_STATE_HPP_ +#define _RIVE_SEMANTIC_STATE_HPP_ + +#include "rive/generated/semantic/semantic_data_base.hpp" +#include + +namespace rive +{ +/// Bitmask constants for semantic state flags. +/// These are stored in SemanticNode::stateFlags and transmitted in +/// SemanticsDiffNode::stateFlags. The platform accessibility layer +/// interprets them per-role. +/// +/// Bits 0-7 are trait-gated: they are only meaningful when the +/// corresponding SemanticTrait is set on the node. +/// Bits 8-13 are non-trait states (binary, role-implied). +/// +/// Values are pulled from SemanticDataBase's generated `*Bitmask` +/// constants, which are derived from the authoritative JSON definitions. +/// Editing the bit layout means editing dev/defs/semantic/semantic_data.json +/// and regenerating — the enum values will track automatically. +/// +/// Checked/Mixed precedence: Checked and Mixed occupy two independent bits +/// on stateFlags. When both bits are set, Mixed wins — the node is reported +/// as indeterminate, not checked. Platform adapters must +/// surface checked state as `!Mixed && Checked`. +enum class SemanticState : uint32_t +{ + None = 0, + + // Trait-gated states (only meaningful when trait is active) + Expanded = SemanticDataBase::isExpandedBitmask, // requires Expandable + Selected = SemanticDataBase::isSelectedBitmask, // requires Selectable + Checked = SemanticDataBase::isCheckedBitmask, // requires Checkable + Mixed = SemanticDataBase::isMixedBitmask, // requires Checkable; wins over + // Checked + Toggled = SemanticDataBase::isToggledBitmask, // requires Toggleable + Required = SemanticDataBase::isRequiredBitmask, // requires Requirable + Disabled = SemanticDataBase::isDisabledBitmask, // requires Enablable + Focused = SemanticDataBase::isFocusedBitmask, // requires Focusable + + // Non-trait states (binary, always applicable or role-implied) + Hidden = SemanticDataBase::isHiddenBitmask, + LiveRegion = SemanticDataBase::isLiveRegionBitmask, + ReadOnly = SemanticDataBase::isReadOnlyBitmask, + Modal = SemanticDataBase::isModalBitmask, + Obscured = SemanticDataBase::isObscuredBitmask, + Multiline = SemanticDataBase::isMultilineBitmask, +}; + +constexpr SemanticState operator|(SemanticState a, SemanticState b) +{ + return static_cast(static_cast(a) | + static_cast(b)); +} + +constexpr SemanticState operator&(SemanticState a, SemanticState b) +{ + return static_cast(static_cast(a) & + static_cast(b)); +} + +constexpr bool hasSemanticState(uint32_t flags, SemanticState flag) +{ + return (flags & static_cast(flag)) != 0; +} +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/semantic/semantic_trait.hpp b/thirdparty/rive/include/rive/semantic/semantic_trait.hpp new file mode 100644 index 000000000..ba6569bae --- /dev/null +++ b/thirdparty/rive/include/rive/semantic/semantic_trait.hpp @@ -0,0 +1,74 @@ +#ifndef _RIVE_SEMANTIC_TRAIT_HPP_ +#define _RIVE_SEMANTIC_TRAIT_HPP_ + +#include "rive/generated/semantic/semantic_data_base.hpp" +#include + +namespace rive +{ +/// Bitmask constants for semantic trait flags. +/// +/// Traits sit between Role and State: they declare what *capabilities* +/// a semantic node has. A state flag is only meaningful when its +/// corresponding trait is set. +/// +/// Example: a button with the Expandable trait can be Expanded or +/// collapsed. Without the trait the Expanded state bit is ignored. +/// +/// Stored in SemanticNode::traitFlags and transmitted in +/// SemanticsDiffNode::traitFlags. Platform accessibility layers use +/// traits to distinguish "property not applicable" from "property is +/// false" (the tristate problem). +/// +/// Values are pulled from SemanticDataBase's generated `*Bitmask` +/// constants, which are derived from the authoritative JSON definitions. +/// Editing the bit layout means editing dev/defs/semantic/semantic_data.json +/// and regenerating — the enum values will track automatically. +enum class SemanticTrait : uint32_t +{ + None = 0, + + /// Node can be expanded / collapsed (disclosure). + Expandable = SemanticDataBase::isExpandableBitmask, + + /// Node can be selected / unselected. + Selectable = SemanticDataBase::isSelectableBitmask, + + /// Node can be checked / unchecked (checkbox, radio). + Checkable = SemanticDataBase::isCheckableBitmask, + + /// Node can be toggled on / off (switch). + Toggleable = SemanticDataBase::isToggleableBitmask, + + /// Node can be marked as required / optional (form field). + Requirable = SemanticDataBase::isRequirableBitmask, + + /// Node has an enabled / disabled concept. + /// Without this trait, the Disabled state bit is ignored and the + /// platform sees the node as neither enabled nor disabled. + Enablable = SemanticDataBase::isEnablableBitmask, + + /// Node can receive focus. Auto-set by the runtime when a sibling + /// FocusData exists. + Focusable = SemanticDataBase::isFocusableBitmask, +}; + +constexpr SemanticTrait operator|(SemanticTrait a, SemanticTrait b) +{ + return static_cast(static_cast(a) | + static_cast(b)); +} + +constexpr SemanticTrait operator&(SemanticTrait a, SemanticTrait b) +{ + return static_cast(static_cast(a) & + static_cast(b)); +} + +constexpr bool hasSemanticTrait(uint32_t flags, SemanticTrait trait) +{ + return (flags & static_cast(trait)) != 0; +} +} // namespace rive + +#endif diff --git a/thirdparty/rive/include/rive/shape_paint_type.hpp b/thirdparty/rive/include/rive/shape_paint_type.hpp new file mode 100644 index 000000000..10e92c495 --- /dev/null +++ b/thirdparty/rive/include/rive/shape_paint_type.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_SHAPE_PAINT_TYPE_HPP_ +#define _RIVE_SHAPE_PAINT_TYPE_HPP_ +namespace rive +{ +enum class ShapePaintType : unsigned int +{ + stroke = 0, + fill = 1, +}; +} +#endif diff --git a/thirdparty/rive/include/rive/shapes/clipping_shape.hpp b/thirdparty/rive/include/rive/shapes/clipping_shape.hpp index a93a11e0e..cab469d5a 100644 --- a/thirdparty/rive/include/rive/shapes/clipping_shape.hpp +++ b/thirdparty/rive/include/rive/shapes/clipping_shape.hpp @@ -3,6 +3,7 @@ #include "rive/renderer.hpp" #include "rive/generated/shapes/clipping_shape_base.hpp" #include "rive/shapes/shape_paint_path.hpp" +#include "rive/drawable.hpp" #include namespace rive @@ -10,21 +11,124 @@ namespace rive class Shape; class Node; class RenderPath; +class ClippingShapeStart; +class ClippingShapeEnd; + +class ClippingShapeOperation +{ +public: + virtual ~ClippingShapeOperation() = default; + virtual void draw(Renderer* renderer, bool needsSaveOperation) = 0; + virtual int emptyClipCount() = 0; + void clippingShape(ClippingShape* shape) { m_clippingShape = shape; } + virtual bool isStart() { return false; } + virtual bool isVisible() { return true; } + +protected: + ClippingShape* m_clippingShape = nullptr; +}; + +class ClippingShapeStart : public ClippingShapeOperation +{ +public: + void draw(Renderer* renderer, bool needsSaveOperation) override; + int emptyClipCount() override; + bool isStart() override { return true; } + bool isVisible() override; +}; + +class ClippingShapeEnd : public ClippingShapeOperation +{ + void draw(Renderer* renderer, bool needsSaveOperation) override; + int emptyClipCount() override; +}; + +class ClippingShapeProxyDrawable : public Drawable +{ +public: + ClippingShapeProxyDrawable(ClippingShapeOperation* operation) : + m_clippingShapeOperation(operation) + {} + void draw(Renderer* renderer) override + { + m_clippingShapeOperation->draw(renderer, m_needsSaveOperation); + } + + int emptyClipCount() override + { + return m_clippingShapeOperation->emptyClipCount(); + } + + bool isHidden() const override { return false; } + + Drawable* hittableComponent() override { return nullptr; }; + + bool isTargetOpaque() override { return false; }; + + Core* hitTest(HitInfo*, const Mat2D&) override { return nullptr; } + + void operation(ClippingShapeOperation* value) + { + m_clippingShapeOperation = value; + } + + bool isProxy() override { return true; } + + bool isClipStart() override { return m_clippingShapeOperation->isStart(); } + bool isClipEnd() override { return !m_clippingShapeOperation->isStart(); } + bool willClip() override { return m_clippingShapeOperation->isVisible(); } + +private: + ClippingShapeOperation* m_clippingShapeOperation = nullptr; +}; + class ClippingShape : public ClippingShapeBase { private: std::vector m_Shapes; + std::vector m_proxyDrawables; + std::vector m_pooledProxyDrawables; Node* m_Source = nullptr; public: + ~ClippingShape(); Node* source() const { return m_Source; } const std::vector& shapes() const { return m_Shapes; } StatusCode onAddedClean(CoreContext* context) override; StatusCode onAddedDirty(CoreContext* context) override; void buildDependencies() override; void update(ComponentDirt value) override; + void isVisibleChanged() override; ShapePaintPath* path() { return m_clipPath; } + void resetDrawables() + { + m_pooledProxyDrawables.insert(m_pooledProxyDrawables.end(), + m_proxyDrawables.begin(), + m_proxyDrawables.end()); + m_proxyDrawables.clear(); + } + + ClippingShapeProxyDrawable* createProxyDrawable( + ClippingShapeOperation* operation) + { + ClippingShapeProxyDrawable* drawable; + if (m_pooledProxyDrawables.size() > 0) + { + drawable = m_pooledProxyDrawables.back(); + drawable->operation(operation); + drawable->needsSaveOperation(true); + m_pooledProxyDrawables.pop_back(); + } + else + { + drawable = new ClippingShapeProxyDrawable(operation); + } + m_proxyDrawables.push_back(drawable); + return drawable; + } + ClippingShapeStart clipStart; + ClippingShapeEnd clipEnd; private: ShapePaintPath m_path; diff --git a/thirdparty/rive/include/rive/shapes/image.hpp b/thirdparty/rive/include/rive/shapes/image.hpp index 2e7992144..f308e6d0a 100644 --- a/thirdparty/rive/include/rive/shapes/image.hpp +++ b/thirdparty/rive/include/rive/shapes/image.hpp @@ -20,15 +20,18 @@ class Image : public ImageBase, public FileAssetReferencer // and use the image width/height to compute the proper scale float m_layoutWidth = NAN; float m_layoutHeight = NAN; + float m_layoutOffsetX = 0.0f; + float m_layoutOffsetY = 0.0f; void updateImageScale(); public: void setMesh(MeshDrawable* mesh); - ImageAsset* imageAsset() const { return (ImageAsset*)m_fileAsset; } + ImageAsset* imageAsset() const; void draw(Renderer* renderer) override; + bool willDraw() override; Core* hitTest(HitInfo*, const Mat2D&) override; StatusCode import(ImportStack& importStack) override; - void setAsset(FileAsset*) override; + void setAsset(rcp) override; uint32_t assetId() override; Core* clone() const override; Vec2D measureLayout(float width, @@ -42,6 +45,8 @@ class Image : public ImageBase, public FileAssetReferencer float width() const; float height() const; void assetUpdated() override; + AABB localBounds() const override; + void updateTransform() override; #ifdef TESTING Mesh* mesh() const; diff --git a/thirdparty/rive/include/rive/shapes/list_path.hpp b/thirdparty/rive/include/rive/shapes/list_path.hpp new file mode 100644 index 000000000..241a84ac0 --- /dev/null +++ b/thirdparty/rive/include/rive/shapes/list_path.hpp @@ -0,0 +1,95 @@ +#ifndef _RIVE_LIST_PATH_HPP_ +#define _RIVE_LIST_PATH_HPP_ +#include "rive/generated/shapes/list_path_base.hpp" +#include "rive/data_bind/data_bind_list_item_consumer.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" +#include "rive/viewmodel/property_symbol_dependent.hpp" +#include "rive/shapes/vertex.hpp" +#include +namespace rive +{ + +class VertexListener; + +class VertexPropertyListenerSingle : public PropertySymbolDependentSingle +{ +public: + VertexPropertyListenerSingle(Core* vertex, + VertexListener* vertexListener, + ViewModelInstanceValue* instanceValue, + uint16_t propertyKey, + float multiplier); + void writeValue() override; + +protected: + float m_multiplier = 1; +}; + +class VertexPropertyListenerMulti : public PropertySymbolDependentMulti +{ +public: + VertexPropertyListenerMulti(Core* vertex, + VertexListener* vertexListener, + ViewModelInstanceValue* instanceValue, + std::vector propertyKeys, + float multiplier); + + void writeValue() override; + +private: + float m_multiplier = 1; +}; + +class VertexPropertyListenerPoint : public PropertySymbolDependent +{ +public: + ~VertexPropertyListenerPoint(); + VertexPropertyListenerPoint(Core* vertex, + VertexListener* vertexListener, + ViewModelInstanceValue* xValue, + ViewModelInstanceValue* yValue, + uint16_t distKey, + uint16_t rotKey); + void writeValue() override; + +private: + ViewModelInstanceValue* m_yValue; + uint16_t m_distKey; + uint16_t m_rotKey; +}; + +class VertexListener : public CoreObjectListener +{ +public: + VertexListener(Vertex* vertex, rcp instance, Path* path); + + Vertex* vertex() { return m_core->as(); } + void markDirty() override { m_path->markPathDirty(); } + +private: + Path* m_path = nullptr; + void createPropertyListener(SymbolType symbolType); + void createInPointPropertyListener(); + void createOutPointPropertyListener(); + PropertySymbolDependent* createSinglePropertyListener( + SymbolType symbolType); + PropertySymbolDependent* createDistancePropertyListener(); + PropertySymbolDependent* createRotationPropertyListener(); + +protected: + void createProperties() override; +}; + +class ListPath : public ListPathBase, public DataBindListItemConsumer +{ +public: + ~ListPath(); + void updateList(std::vector>* list) override; + +private: + std::vector m_vertexListeners; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/shapes/paint/blend_mode.hpp b/thirdparty/rive/include/rive/shapes/paint/blend_mode.hpp index 3b27246d4..e5c38a829 100644 --- a/thirdparty/rive/include/rive/shapes/paint/blend_mode.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/blend_mode.hpp @@ -21,5 +21,7 @@ enum class BlendMode : unsigned char color = 27, luminosity = 28 }; -} + +constexpr uint32_t BLEND_MODE_BIT_COUNT = 5; +} // namespace rive #endif diff --git a/thirdparty/rive/include/rive/shapes/paint/color.hpp b/thirdparty/rive/include/rive/shapes/paint/color.hpp index cf01a85d1..b898c809d 100644 --- a/thirdparty/rive/include/rive/shapes/paint/color.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/color.hpp @@ -7,6 +7,8 @@ namespace rive { using ColorInt = uint32_t; +uint8_t opacityToAlpha(float opacity); + ColorInt colorARGB(int a, int r, int g, int b); unsigned int colorRed(ColorInt value); diff --git a/thirdparty/rive/include/rive/shapes/paint/dash.hpp b/thirdparty/rive/include/rive/shapes/paint/dash.hpp index 444c75363..b3ba93780 100644 --- a/thirdparty/rive/include/rive/shapes/paint/dash.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/dash.hpp @@ -10,7 +10,7 @@ class Dash : public DashBase Dash(); Dash(float value, bool percentage); - float normalizedLength(float length) const; + float normalizedLength(float length, bool wraps) const; StatusCode onAddedClean(CoreContext* context) override; diff --git a/thirdparty/rive/include/rive/shapes/paint/dash_path.hpp b/thirdparty/rive/include/rive/shapes/paint/dash_path.hpp index 890daf74c..a9d1254c2 100644 --- a/thirdparty/rive/include/rive/shapes/paint/dash_path.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/dash_path.hpp @@ -2,49 +2,64 @@ #define _RIVE_DASH_PATH_HPP_ #include "rive/generated/shapes/paint/dash_path_base.hpp" +#include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/paint/stroke_effect.hpp" #include "rive/shapes/paint/stroke_effect.hpp" #include "rive/shapes/shape_paint_path.hpp" #include "rive/renderer.hpp" #include "rive/math/raw_path.hpp" -#include "rive/math/contour_measure.hpp" +#include "rive/math/path_measure.hpp" #include namespace rive { class Dash; + +class DashEffectPath : public EffectPath +{ +public: + void invalidateEffect() override; + PathMeasure& pathMeasure() { return m_pathMeasure; } + void createPathMeasure(const RawPath*); + ShapePaintPath* path() override { return &m_path; } + +private: + ShapePaintPath m_path; + PathMeasure m_pathMeasure; +}; class PathDasher { friend class Dash; protected: - void invalidateSourcePath(); virtual void invalidateDash(); - ShapePaintPath* dash(const RawPath* source, + ShapePaintPath* dash(ShapePaintPath* destination, + const RawPath* source, + PathMeasure* pathMeasure, Dash* offset, Span dashes); - ShapePaintPath* applyDash(const RawPath* source, + ShapePaintPath* applyDash(ShapePaintPath* destination, + const RawPath* source, + PathMeasure* pathMeasure, Dash* offset, Span dashes); -protected: - ShapePaintPath m_path; - std::vector> m_contours; - public: - float pathLength() const; + virtual ~PathDasher() {} }; class DashPath : public DashPathBase, public PathDasher, public StrokeEffect { public: StatusCode onAddedClean(CoreContext* context) override; - void invalidateEffect() override; void offsetChanged() override; void offsetIsPercentageChanged() override; - void updateEffect(const ShapePaintPath* source) override; - ShapePaintPath* effectPath() override; + void updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) override; void invalidateDash() override; + EffectsContainer* parentPaint() override; + virtual EffectPath* createEffectPath() override; private: std::vector m_dashes; diff --git a/thirdparty/rive/include/rive/shapes/paint/effects_container.hpp b/thirdparty/rive/include/rive/shapes/paint/effects_container.hpp new file mode 100644 index 000000000..07c29cb94 --- /dev/null +++ b/thirdparty/rive/include/rive/shapes/paint/effects_container.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_EFFECTS_CONTAINER_HPP_ +#define _RIVE_EFFECTS_CONTAINER_HPP_ +#include "rive/refcnt.hpp" +#include "rive/shapes/path_flags.hpp" +#include "rive/shapes/shape_paint_path.hpp" +#include "rive/math/mat2d.hpp" +#include + +namespace rive +{ +class StrokeEffect; +class PathProvider; + +class EffectsContainer +{ + +public: + static EffectsContainer* from(Component* component); + virtual void addStrokeEffect(StrokeEffect* effect); + virtual void invalidateEffects(StrokeEffect* invalidatingEffect); + virtual void invalidateEffects(); + ShapePaintPath* lastEffectPath(PathProvider*); +#ifdef TESTING + StrokeEffect* effect() + { + return m_effects.size() > 0 ? m_effects.back() : nullptr; + } +#endif + +protected: + std::vector* effects() { return &m_effects; } + +private: + std::vector m_effects; +}; +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/shapes/paint/feather.hpp b/thirdparty/rive/include/rive/shapes/paint/feather.hpp index 6f42ec58d..00c8cad93 100644 --- a/thirdparty/rive/include/rive/shapes/paint/feather.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/feather.hpp @@ -18,6 +18,12 @@ class Feather : public FeatherBase void buildDependencies() override; ShapePaintPath* innerPath() { return &m_innerPath; } + void rebuildInnerPath(const ShapePaintPath* path, + const Mat2D& shapeTransform, + bool offsetInArtboard); + + bool effectPathDirty() const { return m_effectPathDirty; } + void markEffectPathDirty() { m_effectPathDirty = true; } protected: void strengthChanged() override; @@ -26,6 +32,7 @@ class Feather : public FeatherBase private: ShapePaintPath m_innerPath; + bool m_effectPathDirty = true; #ifdef TESTING public: int renderCount = 0; diff --git a/thirdparty/rive/include/rive/shapes/paint/fill.hpp b/thirdparty/rive/include/rive/shapes/paint/fill.hpp index 37f9fe9ea..0fcd45a02 100644 --- a/thirdparty/rive/include/rive/shapes/paint/fill.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/fill.hpp @@ -11,6 +11,8 @@ class Fill : public FillBase PathFlags pathFlags() const override; void applyTo(RenderPaint* renderPaint, float opacityModifier) override; ShapePaintPath* pickPath(ShapePaintContainer* shape) const override; + ShapePaintType paintType() const override { return ShapePaintType::fill; } + void buildDependencies() override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/shapes/paint/group_effect.hpp b/thirdparty/rive/include/rive/shapes/paint/group_effect.hpp new file mode 100644 index 000000000..75724d621 --- /dev/null +++ b/thirdparty/rive/include/rive/shapes/paint/group_effect.hpp @@ -0,0 +1,33 @@ +#ifndef _RIVE_GROUP_EFFECT_HPP_ +#define _RIVE_GROUP_EFFECT_HPP_ +#include "rive/generated/shapes/paint/group_effect_base.hpp" +#include "rive/shapes/paint/effects_container.hpp" +#include "rive/shapes/paint/stroke_effect.hpp" +#include +namespace rive +{ +class TargetEffect; +class StrokeEffect; +class GroupEffect : public GroupEffectBase, + public EffectsContainer, + public StrokeEffect +{ +public: + void addTargetEffect(TargetEffect* effect); + void invalidateEffects(StrokeEffect* effect) override; + void invalidateEffects() override; + void updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) override; + EffectsContainer* parentPaint() override; + void addPathProvider(PathProvider* component) override; + void addStrokeEffect(StrokeEffect* effect) override; + void invalidateEffect(PathProvider* effect) override; + void buildDependencies() override; + +private: + std::vector m_targetEffects; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/shapes/paint/image_sampler.hpp b/thirdparty/rive/include/rive/shapes/paint/image_sampler.hpp index 8fe04c778..e929a4206 100644 --- a/thirdparty/rive/include/rive/shapes/paint/image_sampler.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/image_sampler.hpp @@ -7,11 +7,10 @@ namespace rive { enum class ImageFilter : uint8_t { - // High fidelity linear filter in all 3 directions: x, y, and between mip - // levels - trilinear = 0, + // High fidelity linear filter in all 2 directions: x, y + bilinear = 0, // Sample with low fidelity, good for things like pixel art. - nearest = 1 + nearest = 1, }; constexpr size_t NUM_IMAGE_FILTERS = 2; @@ -27,7 +26,7 @@ enum class ImageWrap : uint8_t mirror = 2, }; -constexpr size_t NUM_IMAGE_WRAP = 4; +constexpr size_t NUM_IMAGE_WRAP = 3; struct ImageSampler { @@ -38,7 +37,7 @@ struct ImageSampler ImageWrap wrapX = ImageWrap::clamp; ImageWrap wrapY = ImageWrap::clamp; // How to sample the texture, this will be for both MIN and MAG filtering. - ImageFilter filter = ImageFilter::trilinear; + ImageFilter filter = ImageFilter::bilinear; bool operator==(const ImageSampler other) const { @@ -54,14 +53,15 @@ struct ImageSampler // The maximum number of possible combinations of sampler options. Used for // array length in implementations. static constexpr size_t MAX_SAMPLER_PERMUTATIONS = - NUM_IMAGE_FILTERS * NUM_IMAGE_FILTERS * NUM_IMAGE_WRAP; + NUM_IMAGE_FILTERS * NUM_IMAGE_WRAP * NUM_IMAGE_WRAP; // Convert struct to a key that can be used to index an array to get a // unique sampler that represents these options. const uint8_t asKey() const { - return static_cast(wrapX) + (static_cast(wrapY) * 3) + - (static_cast(filter) * 9); + return static_cast(wrapX) + + (static_cast(wrapY) * NUM_IMAGE_WRAP) + + (static_cast(filter) * NUM_IMAGE_WRAP * NUM_IMAGE_WRAP); } static ImageSampler SamplerFromKey(uint8_t key) @@ -79,17 +79,18 @@ struct ImageSampler static ImageWrap GetWrapXOptionFromKey(uint8_t key) { - return static_cast(key % 3); + return static_cast(key % NUM_IMAGE_WRAP); } static ImageWrap GetWrapYOptionFromKey(uint8_t key) { - return static_cast((key % 9) / 3); + return static_cast((key / NUM_IMAGE_WRAP) % NUM_IMAGE_WRAP); } static ImageFilter GetFilterOptionFromKey(uint8_t key) { - return static_cast((key - (key % 9)) % 2); + return static_cast(key / + (NUM_IMAGE_WRAP * NUM_IMAGE_WRAP)); } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/shapes/paint/shape_paint.hpp b/thirdparty/rive/include/rive/shapes/paint/shape_paint.hpp index cb98ed15b..05921fb0a 100644 --- a/thirdparty/rive/include/rive/shapes/paint/shape_paint.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/shape_paint.hpp @@ -1,11 +1,13 @@ #ifndef _RIVE_SHAPE_PAINT_HPP_ #define _RIVE_SHAPE_PAINT_HPP_ #include "rive/generated/shapes/paint/shape_paint_base.hpp" +#include "rive/shapes/paint/effects_container.hpp" #include "rive/renderer.hpp" #include "rive/shapes/paint/blend_mode.hpp" #include "rive/shapes/paint/shape_paint_mutator.hpp" #include "rive/shapes/path_flags.hpp" #include "rive/shapes/shape_paint_path.hpp" +#include "rive/shapes/paint/stroke_effect.hpp" #include "rive/math/raw_path.hpp" namespace rive @@ -14,7 +16,10 @@ class RenderPaint; class ShapePaintMutator; class Feather; class ShapePaintContainer; -class ShapePaint : public ShapePaintBase +class TransformComponent; +class ShapePaint : public ShapePaintBase, + public EffectsContainer, + public PathProvider { protected: rcp m_RenderPaint; @@ -22,12 +27,17 @@ class ShapePaint : public ShapePaintBase public: StatusCode onAddedClean(CoreContext* context) override; + void invalidateEffects(StrokeEffect* effect) override; + void invalidateEffects() override; + virtual void invalidateRendering(); float renderOpacity() const { return m_PaintMutator->renderOpacity(); } void renderOpacity(float value) { m_PaintMutator->renderOpacity(value); } void blendMode(BlendMode value); + void addStrokeEffect(StrokeEffect* effect) override; + /// Creates a RenderPaint object for the provided ShapePaintMutator*. /// This should be called only once as the ShapePaint manages the /// lifecycle of the RenderPaint. @@ -43,7 +53,8 @@ class ShapePaint : public ShapePaintBase ShapePaintPath* shapePaintPath, const Mat2D& transform, bool usePathFillRule = false, - RenderPaint* overridePaint = nullptr); + RenderPaint* overridePaint = nullptr, + bool needsSaveOperation = true); RenderPaint* renderPaint() { return m_RenderPaint.get(); } @@ -70,6 +81,10 @@ class ShapePaint : public ShapePaintBase Feather* feather() const; virtual ShapePaintPath* pickPath(ShapePaintContainer* shape) const = 0; + void update(ComponentDirt value) override; + virtual ShapePaintType paintType() const = 0; + + TransformComponent* parentTransformComponent() const; private: Feather* m_feather = nullptr; diff --git a/thirdparty/rive/include/rive/shapes/paint/shape_paint_mutator.hpp b/thirdparty/rive/include/rive/shapes/paint/shape_paint_mutator.hpp index 8c5269064..52168ad9a 100644 --- a/thirdparty/rive/include/rive/shapes/paint/shape_paint_mutator.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/shape_paint_mutator.hpp @@ -2,7 +2,7 @@ #define _RIVE_SHAPE_PAINT_MUTATOR_HPP_ #include "rive/status_code.hpp" -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" namespace rive { @@ -52,6 +52,5 @@ class ShapePaintMutator /// The Component providing this ShapePaintMutator interface. Component* m_component = nullptr; }; -RIVE_MAKE_ENUM_BITSET(ShapePaintMutator::Flags); } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/shapes/paint/stroke.hpp b/thirdparty/rive/include/rive/shapes/paint/stroke.hpp index b67785887..010556a4b 100644 --- a/thirdparty/rive/include/rive/shapes/paint/stroke.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/stroke.hpp @@ -8,29 +8,17 @@ class StrokeEffect; class Stroke : public StrokeBase { private: - StrokeEffect* m_Effect = nullptr; - public: RenderPaint* initRenderPaint(ShapePaintMutator* mutator) override; PathFlags pathFlags() const override; - void addStrokeEffect(StrokeEffect* effect); - bool hasStrokeEffect() { return m_Effect != nullptr; } - void invalidateEffects(); bool isVisible() const override; - void invalidateRendering(); void applyTo(RenderPaint* renderPaint, float opacityModifier) override; ShapePaintPath* pickPath(ShapePaintContainer* shape) const override; - void draw(Renderer* renderer, - ShapePaintPath* shapePaintPath, - const Mat2D& transform, - bool usePathFillRule, - RenderPaint* overridePaint) override; void buildDependencies() override; void update(ComponentDirt value) override; -#ifdef TESTING - StrokeEffect* effect() { return m_Effect; } -#endif + void invalidateRendering() override; + ShapePaintType paintType() const override { return ShapePaintType::stroke; } protected: void thicknessChanged() override; diff --git a/thirdparty/rive/include/rive/shapes/paint/stroke_effect.hpp b/thirdparty/rive/include/rive/shapes/paint/stroke_effect.hpp index e73ba9ea4..ba4c674e0 100644 --- a/thirdparty/rive/include/rive/shapes/paint/stroke_effect.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/stroke_effect.hpp @@ -2,21 +2,58 @@ #define _RIVE_STROKE_EFFECT_HPP_ #include "rive/rive_types.hpp" +#include "rive/shape_paint_type.hpp" +#include namespace rive { class Factory; class RenderPath; class RawPath; +class ShapePaint; class ShapePaintPath; +class EffectsContainer; + +// A EffectPath is a reference that any StrokeEffect holds to identify each +// ShapePaint that is being affected by it. +class EffectPath +{ +public: + virtual ~EffectPath() = default; + virtual void invalidateEffect() {} + virtual ShapePaintPath* path() { return nullptr; } +}; + +// A PathProvider is any object that will be used to map a unique EffectPath. +// It allows to disambiguate path effect updates and invalidations without +// modifying any other instance that an effect is affecting. ShapePaints are +// PathProviders, but also TargetEffects. A TargetEffect needs to create a +// PathProvider proxy because the same ShapePaint can be targetting multiple +// times the same group effect and invalidating one doesn't need to invalidate +// the other one. +class PathProvider +{}; class StrokeEffect { public: - virtual ~StrokeEffect() {} - virtual void updateEffect(const ShapePaintPath* source) = 0; - virtual ShapePaintPath* effectPath() = 0; - virtual void invalidateEffect() = 0; + virtual ~StrokeEffect(); + virtual void updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) = 0; + virtual void invalidateEffect(PathProvider* pathProvider); + virtual EffectsContainer* parentPaint() = 0; + virtual void addPathProvider(PathProvider* component) + { + m_effectPaths[component] = createEffectPath(); + } + + virtual ShapePaintPath* effectPath(PathProvider* pathProvider); + virtual void invalidateEffectFromLocal(); + +protected: + virtual EffectPath* createEffectPath() { return new EffectPath(); } + std::unordered_map m_effectPaths; }; } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/shapes/paint/target_effect.hpp b/thirdparty/rive/include/rive/shapes/paint/target_effect.hpp new file mode 100644 index 000000000..30aeabd17 --- /dev/null +++ b/thirdparty/rive/include/rive/shapes/paint/target_effect.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_TARGET_EFFECT_HPP_ +#define _RIVE_TARGET_EFFECT_HPP_ +#include "rive/generated/shapes/paint/target_effect_base.hpp" +#include "rive/shapes/paint/stroke_effect.hpp" +#include +namespace rive +{ +class GroupEffect; +class TargetEffectPath : public EffectPath +{ +public: + PathProvider* pathProviderProxy() { return &m_pathProviderProxy; } + +private: + PathProvider m_pathProviderProxy; +}; +class TargetEffect : public TargetEffectBase, public StrokeEffect +{ +public: + StatusCode onAddedClean(CoreContext* context) override; + + void updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) override; + ShapePaintPath* effectPath(PathProvider* pathProvider) override; + EffectsContainer* parentPaint() override; + void addPathProvider(PathProvider* component) override; + void invalidateEffect(PathProvider* component) override; + +protected: + virtual EffectPath* createEffectPath() override; + +private: + GroupEffect* m_groupEffect = nullptr; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/shapes/paint/trim_path.hpp b/thirdparty/rive/include/rive/shapes/paint/trim_path.hpp index 2b026671c..cf21d3cf8 100644 --- a/thirdparty/rive/include/rive/shapes/paint/trim_path.hpp +++ b/thirdparty/rive/include/rive/shapes/paint/trim_path.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_TRIM_PATH_HPP_ #define _RIVE_TRIM_PATH_HPP_ #include "rive/generated/shapes/paint/trim_path_base.hpp" +#include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/shape_paint_path.hpp" #include "rive/shapes/paint/stroke_effect.hpp" #include "rive/renderer.hpp" @@ -16,14 +17,27 @@ enum class TrimPathMode : uint8_t }; +class TrimEffectPath : public EffectPath +{ +public: + void invalidateEffect() override; + std::vector>& contours() { return m_contours; } + ShapePaintPath* path() override { return &m_path; } + +private: + ShapePaintPath m_path; + std::vector> m_contours; +}; + class TrimPath : public TrimPathBase, public StrokeEffect { public: StatusCode onAddedClean(CoreContext* context) override; - void invalidateEffect() override; - void updateEffect(const ShapePaintPath* source) override; - ShapePaintPath* effectPath() override; + void updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) override; + EffectsContainer* parentPaint() override; void startChanged() override; void endChanged() override; @@ -34,13 +48,12 @@ class TrimPath : public TrimPathBase, public StrokeEffect StatusCode onAddedDirty(CoreContext* context) override; - const ShapePaintPath& path() const { return m_path; } - protected: - void invalidateTrim(); - void trimPath(const RawPath* source); - ShapePaintPath m_path; - std::vector> m_contours; + void trimPath(ShapePaintPath* destination, + std::vector>& contours, + const RawPath* source, + ShapePaintType shapePaintType); + virtual EffectPath* createEffectPath() override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/shapes/path.hpp b/thirdparty/rive/include/rive/shapes/path.hpp index 2d0d6e112..0e554a0dc 100644 --- a/thirdparty/rive/include/rive/shapes/path.hpp +++ b/thirdparty/rive/include/rive/shapes/path.hpp @@ -64,6 +64,7 @@ class Path : public PathBase bool canDeferPathUpdate(); void addVertex(PathVertex* vertex); + void popVertex(); virtual void markPathDirty(bool sendToLayout = true); virtual bool isPathClosed() const { return true; } @@ -78,6 +79,7 @@ class Path : public PathBase #endif void buildPath(RawPath&) const; + AABB localBounds() const override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/shapes/points_common_path.hpp b/thirdparty/rive/include/rive/shapes/points_common_path.hpp new file mode 100644 index 000000000..1eb44b0e2 --- /dev/null +++ b/thirdparty/rive/include/rive/shapes/points_common_path.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_POINTS_COMMON_PATH_HPP_ +#define _RIVE_POINTS_COMMON_PATH_HPP_ +#include "rive/generated/shapes/points_common_path_base.hpp" +#include +namespace rive +{ +class PointsCommonPath : public PointsCommonPathBase +{ +public: + bool isPathClosed() const override { return isClosed(); } + + bool isClockwise() const; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/shapes/points_path.hpp b/thirdparty/rive/include/rive/shapes/points_path.hpp index d57e0b2cc..66cff348a 100644 --- a/thirdparty/rive/include/rive/shapes/points_path.hpp +++ b/thirdparty/rive/include/rive/shapes/points_path.hpp @@ -7,14 +7,11 @@ namespace rive class PointsPath : public PointsPathBase, public Skinnable { public: - bool isPathClosed() const override { return isClosed(); } void buildDependencies() override; void update(ComponentDirt value) override; void markPathDirty(bool sendToLayout = true) override; void markSkinDirty() override; const Mat2D& pathTransform() const override; - - bool isClockwise() const; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/shapes/shape.hpp b/thirdparty/rive/include/rive/shapes/shape.hpp index d28db0e42..751600d95 100644 --- a/thirdparty/rive/include/rive/shapes/shape.hpp +++ b/thirdparty/rive/include/rive/shapes/shape.hpp @@ -3,7 +3,6 @@ #include "rive/hit_info.hpp" #include "rive/generated/shapes/shape_base.hpp" -#include "rive/animation/hittable.hpp" #include "rive/shapes/path_composer.hpp" #include "rive/shapes/shape_paint_container.hpp" #include "rive/drawable_flag.hpp" @@ -16,7 +15,7 @@ class PathComposer; class HitTester; class RenderPathDeformer; -class Shape : public ShapeBase, public ShapePaintContainer, public Hittable +class Shape : public ShapeBase, public ShapePaintContainer { private: PathComposer m_PathComposer; @@ -36,12 +35,14 @@ class Shape : public ShapeBase, public ShapePaintContainer, public Hittable bool canDeferPathUpdate(); void addPath(Path* path); void addToRenderPath(RenderPath* commandPath, const Mat2D& transform); + void addToRawPath(RawPath& rawPath, const Mat2D* transform); std::vector& paths() { return m_Paths; } bool wantDifferencePath() const { return m_WantDifferencePath; } void update(ComponentDirt value) override; void draw(Renderer* renderer) override; + bool willDraw() override; Core* hitTest(HitInfo*, const Mat2D&) override; const PathComposer* pathComposer() const { return &m_PathComposer; } @@ -60,6 +61,7 @@ class Shape : public ShapeBase, public ShapePaintContainer, public Hittable float length() override; void setLength(float value) override {} + AABB localBounds() const override { return computeLocalBounds(); } AABB worldBounds() { if ((static_cast(drawableFlags()) & @@ -86,8 +88,11 @@ class Shape : public ShapeBase, public ShapePaintContainer, public Hittable float height, LayoutMeasureMode heightMode) override; - bool hitTestAABB(const Vec2D& position) override; - bool hitTestHiFi(const Vec2D& position, float hitRadius) override; + bool hitTestAABB(const Vec2D& position); + bool hitTestHiFi(const Vec2D& position, float hitRadius); + bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) override; // Implemented for ShapePaintContainer. const Mat2D& shapeWorldTransform() const override { diff --git a/thirdparty/rive/include/rive/shapes/shape_path_flags.hpp b/thirdparty/rive/include/rive/shapes/shape_path_flags.hpp index ba527ff19..c370c0f26 100644 --- a/thirdparty/rive/include/rive/shapes/shape_path_flags.hpp +++ b/thirdparty/rive/include/rive/shapes/shape_path_flags.hpp @@ -11,8 +11,6 @@ enum class ShapePathFlags : uint8_t hidden = 1 << 0, // Unused at runtime isCounterClockwise = 1 << 1, }; - -RIVE_MAKE_ENUM_BITSET(ShapePathFlags) } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/signed_content_header.hpp b/thirdparty/rive/include/rive/signed_content_header.hpp new file mode 100644 index 000000000..2c8fb55cf --- /dev/null +++ b/thirdparty/rive/include/rive/signed_content_header.hpp @@ -0,0 +1,84 @@ +#ifndef _RIVE_SIGNED_CONTENT_HEADER_HPP_ +#define _RIVE_SIGNED_CONTENT_HEADER_HPP_ + +#include "rive/span.hpp" +#include +#include + +namespace rive +{ + +/// Size of the signature in bytes (hydro_sign_BYTES from libhydrogen). +static constexpr size_t kSignatureSize = 64; + +/// Lightweight view into signed content data with a header. +/// Does not copy the underlying data - just provides accessors. +/// +/// This envelope is shared by all text-backed assets (ScriptAsset for Luau +/// bytecode, ShaderAsset for RSTB blobs). The inner content type is +/// determined by the concrete asset class, not by this header. +/// +/// Header format: +/// [flags:1] [signature:64 if signed] [content:N] +/// +/// Flags byte layout: +/// Bits 0-6: Version number (0-127) +/// Bit 7: isSigned flag +class SignedContentHeader +{ +public: + /// Constructs a SignedContentHeader from raw data (header + content). + /// The data must outlive this object. + explicit SignedContentHeader(Span data) : m_data(data) + { + if (!data.empty()) + { + m_flags = data[0]; + } + } + + /// @returns true if the header indicates the content is signed + bool isSigned() const { return (m_flags & 0x80) != 0; } + + /// @returns the version number from the header (0-127) + uint8_t version() const { return m_flags & 0x7F; } + + /// @returns true if the data is valid (has at least the header byte and + /// enough bytes for signature if signed) + bool isValid() const { return m_data.size() >= contentOffset(); } + + /// @returns the offset where content starts (1 if unsigned, 65 if signed) + size_t contentOffset() const + { + return isSigned() ? (1 + kSignatureSize) : 1; + } + + /// @returns a span of the signature bytes, or empty span if not signed + Span signature() const + { + if (!isSigned() || m_data.size() < 1 + kSignatureSize) + { + return Span(); + } + return Span(m_data.data() + 1, kSignatureSize); + } + + /// @returns a span of the actual content (without header) + Span content() const + { + size_t offset = contentOffset(); + if (m_data.size() < offset) + { + return Span(); + } + return Span(m_data.data() + offset, + m_data.size() - offset); + } + +private: + Span m_data; + uint8_t m_flags = 0; +}; + +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/simple_array.hpp b/thirdparty/rive/include/rive/simple_array.hpp index 57a05068d..b9f31a1ae 100644 --- a/thirdparty/rive/include/rive/simple_array.hpp +++ b/thirdparty/rive/include/rive/simple_array.hpp @@ -6,6 +6,7 @@ #define _RIVE_SIMPLE_ARRAY_HPP_ #include "rive/rive_types.hpp" +#include "rive/core/type_conversions.hpp" #include #include @@ -77,18 +78,35 @@ template class SimpleArray { public: SimpleArray() : m_ptr(nullptr), m_size(0) {} - SimpleArray(size_t size) : - m_ptr(static_cast(malloc(size * sizeof(T)))), m_size(size) + SimpleArray(size_t size) : m_ptr(nullptr), m_size(0) { - SimpleArrayHelper::DefaultConstructArray(m_ptr, m_ptr + m_size); + size_t bytes; + if (size != 0 && checkedMul(size, sizeof(T), &bytes)) + { + m_ptr = static_cast(malloc(bytes)); + if (m_ptr != nullptr) + { + m_size = size; + SimpleArrayHelper::DefaultConstructArray(m_ptr, + m_ptr + m_size); #ifdef TESTING - SimpleArrayTesting::mallocCount++; + SimpleArrayTesting::mallocCount++; #endif + } + } } SimpleArray(const T* ptr, size_t size) : SimpleArray(size) { - assert(ptr <= ptr + size); - SimpleArrayHelper::CopyConstructArray(ptr, ptr + size, m_ptr); + // Early-return on the empty state: the delegated ctor clamps + // m_size to 0 on overflow / OOM, and we must avoid any pointer + // arithmetic or memcpy when ptr may be null with m_size == 0. + if (m_size == 0) + { + return; + } + assert(ptr != nullptr); + assert(ptr <= ptr + m_size); + SimpleArrayHelper::CopyConstructArray(ptr, ptr + m_size, m_ptr); } constexpr SimpleArray(const SimpleArray& other) : diff --git a/thirdparty/rive/include/rive/solo.hpp b/thirdparty/rive/include/rive/solo.hpp index 8458d769a..4e3cd8cfc 100644 --- a/thirdparty/rive/include/rive/solo.hpp +++ b/thirdparty/rive/include/rive/solo.hpp @@ -9,6 +9,10 @@ class Solo : public SoloBase void activeComponentIdChanged() override; StatusCode onAddedClean(CoreContext* context) override; bool collapse(bool value) override; + void updateByIndex(size_t index); + void updateByName(const std::string& name); + int getActiveChildIndex(); + std::string getActiveChildName(); private: void propagateCollapse(bool collapse); diff --git a/thirdparty/rive/include/rive/text/font_hb.hpp b/thirdparty/rive/include/rive/text/font_hb.hpp index a63d98b5f..cf8b31c83 100644 --- a/thirdparty/rive/include/rive/text/font_hb.hpp +++ b/thirdparty/rive/include/rive/text/font_hb.hpp @@ -5,10 +5,13 @@ #include "rive/text_engine.hpp" #include +#include struct hb_font_t; struct hb_draw_funcs_t; +struct hb_paint_funcs_t; struct hb_feature_t; +using hb_color_t = uint32_t; class HBFont : public rive::Font { @@ -25,6 +28,12 @@ class HBFont : public rive::Font bool isItalic() const override; rive::RawPath getPath(rive::GlyphID) const override; + bool hasColorGlyphs() const override; + bool isColorGlyph(rive::GlyphID) const override; + size_t getColorLayers( + rive::GlyphID, + std::vector& out, + rive::ColorInt foreground = 0xFF000000) const override; rive::SimpleArray onShapeText( rive::Span, rive::Span, @@ -65,12 +74,22 @@ class HBFont : public rive::Font private: hb_draw_funcs_t* m_drawFuncs; + hb_paint_funcs_t* m_paintFuncs; // Feature value lookup based on tag. std::unordered_map m_featureValues; // Axis value lookup based on for the feature. std::unordered_map m_axisValues; + + // Color glyph (emoji) support — COLRv0 (layers), COLRv1 (paint), + // and/or SBIX/CBDT (PNG bitmap). + bool m_hasColorLayers = false; // COLRv0 + bool m_hasColorPaint = false; // COLRv1 + bool m_hasPNG = false; // SBIX or CBDT + std::vector m_paletteColors; + mutable std::unordered_map> + m_colorLayerCache; }; #endif diff --git a/thirdparty/rive/include/rive/text/glyph_lookup.hpp b/thirdparty/rive/include/rive/text/glyph_lookup.hpp index 9286619dd..0683b7bbb 100644 --- a/thirdparty/rive/include/rive/text/glyph_lookup.hpp +++ b/thirdparty/rive/include/rive/text/glyph_lookup.hpp @@ -7,7 +7,7 @@ namespace rive { -/// Stores the glyphId/Index representing the unicode point at i. +/// Stores the glyphId/Index representing the codepoint at i. class GlyphLookup { public: @@ -18,6 +18,8 @@ class GlyphLookup public: uint32_t count(uint32_t index) const; + uint32_t glyphStart(uint32_t index) const; + bool isGlyphBoundary(uint32_t index) const; size_t size() const { return m_glyphIndices.size(); } // Returns the glyph index from the computed shape given the codePointIndex @@ -29,7 +31,7 @@ class GlyphLookup return m_glyphIndices[codePointIndex]; } - uint32_t lastCodeUnitIndex() const + uint32_t lastCodePointIndex() const { return m_glyphIndices.size() == 0 ? 0 diff --git a/thirdparty/rive/include/rive/text/raw_text.hpp b/thirdparty/rive/include/rive/text/raw_text.hpp index 36b687e77..270c77328 100644 --- a/thirdparty/rive/include/rive/text/raw_text.hpp +++ b/thirdparty/rive/include/rive/text/raw_text.hpp @@ -17,13 +17,15 @@ class RawText /// Returns true if the text object contains no text. bool empty() const; - /// Appends a run to the text object. + /// Appends a run to the text object. The foregroundColor is used for + /// color glyphs (emoji) that reference the text's foreground color. void append(const std::string& text, rcp paint, rcp font, float size = 16.0f, float lineHeight = -1.0f, - float letterSpacing = 0.0f); + float letterSpacing = 0.0f, + ColorInt foregroundColor = 0xFF000000); /// Resets the text object to empty state (no text). void clear(); @@ -68,6 +70,7 @@ class RawText rcp paint; bool isEmpty; ShapePaintPath path; + ColorInt foregroundColor = 0xFF000000; }; SimpleArray m_shape; SimpleArray> m_lines; @@ -90,6 +93,27 @@ class RawText GlyphRun m_ellipsisRun; AABB m_bounds; rcp m_clipRenderPath; + + // Color glyph draw commands for interleaving with style paths. + struct RawTextDrawCommand + { + enum Type + { + kStylePath, + kColorGlyph + }; + Type type; + RenderStyle* style = nullptr; + struct ColorGlyphInfo + { + rcp font; + GlyphID glyphId; + Mat2D transform; + ColorInt foregroundColor; + }; + ColorGlyphInfo colorGlyph; + }; + std::vector m_drawCommands; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/text/raw_text_input.hpp b/thirdparty/rive/include/rive/text/raw_text_input.hpp index cf177ebd7..e4c3c7fda 100644 --- a/thirdparty/rive/include/rive/text/raw_text_input.hpp +++ b/thirdparty/rive/include/rive/text/raw_text_input.hpp @@ -113,6 +113,7 @@ class RawTextInput std::string text() const; void text(std::string value); + void textPreserveCursor(std::string value); // Length of the input text. size_t length() const; @@ -157,6 +158,7 @@ class RawTextInput const OrderedLine* orderedLine(CursorPosition position) const; + void ensureShape(); void buildTextPaths(Factory* factory); void computeVisualPositionFromCursor(); void setTextPrivate(std::string value); @@ -228,7 +230,6 @@ inline RawTextInput::Delineator operator&(const RawTextInput::Delineator& a, { return (RawTextInput::Delineator)((uint8_t)a & (uint8_t)b); } -RIVE_MAKE_ENUM_BITSET(RawTextInput::Flags); } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/text/text.hpp b/thirdparty/rive/include/rive/text/text.hpp index 91b3a3895..801a1d50e 100644 --- a/thirdparty/rive/include/rive/text/text.hpp +++ b/thirdparty/rive/include/rive/text/text.hpp @@ -8,14 +8,46 @@ #include "rive/simple_array.hpp" #include "rive/text/glyph_lookup.hpp" #include "rive/text/text_interface.hpp" +#include "rive/data_bind/data_bind_list_item_consumer.hpp" +#include "rive/viewmodel/symbol_type.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/property_symbol_dependent.hpp" +#include "rive/dirtyable.hpp" +#include #include #include namespace rive { +class Factory; +class Renderer; class TextModifierGroup; +class TextStylePaint; + +// A draw command for interleaving monochrome style paths and color glyphs. +struct TextDrawCommand +{ + enum Type + { + kStylePath, + kColorGlyph + }; + Type type; + TextStylePaint* style = nullptr; // for kStylePath + + struct ColorGlyphInfo + { + rcp font; + GlyphID glyphId; + Mat2D transform; + ColorInt foregroundColor; + float opacity; + }; + ColorGlyphInfo colorGlyph; // for kColorGlyph +}; class StyledText { @@ -56,11 +88,82 @@ enum class LineIter : uint8_t yOutOfBounds }; -class TextStylePaint; -class Text : public TextBase, public TextInterface +class Text; + +#ifdef WITH_RIVE_TEXT +class TextValueRunListener; + +class TextValueRunProperty : public PropertySymbolDependentSingle +{ +public: + TextValueRunProperty(Core* textValueRun, + TextValueRunListener* textValueRunListener, + ViewModelInstanceValue* instanceValue, + uint16_t propertyKey, + SymbolType symbolType); + + void writeValue() override; + +private: + SymbolType m_symbolType = SymbolType::none; +}; + +class TextValueRunListener : public CoreObjectListener +{ +public: + TextValueRunListener(TextValueRun* textValueRun, + rcp instance, + Text* text); + + void markDirty() override; + Text* text() { return m_text; } + TextValueRun* textValueRun() + { + if (m_core) + { + return m_core->as(); + } + return nullptr; + } + +protected: + void createProperties() override; + +private: + Text* m_text = nullptr; + void createPropertyListener(SymbolType symbolType); + TextValueRunProperty* createSinglePropertyListener(SymbolType symbolType); +}; +#endif + +struct ColorGlyphCacheKey +{ + const Font* font; + GlyphID glyphId; + bool operator==(const ColorGlyphCacheKey& o) const + { + return font == o.font && glyphId == o.glyphId; + } +}; + +struct ColorGlyphCacheHash +{ + size_t operator()(const ColorGlyphCacheKey& k) const + { + size_t h = std::hash()(k.font); + h ^= + std::hash()(k.glyphId) + 0x9e3779b9 + (h << 6) + (h >> 2); + return h; + } +}; + +class Text : public TextBase, + public TextInterface, + public DataBindListItemConsumer { public: // Implements TextInterface + ~Text(); void markShapeDirty() override; void markPaintDirty() override; @@ -92,6 +195,7 @@ class Text : public TextBase, public TextInterface const TextStylePaint* styleFromShaperId(uint16_t id) const; bool modifierRangesNeedShape() const; AABB localBounds() const override; + AABB constraintBounds() const override { return localBounds(); } void originXChanged() override; void originYChanged() override; @@ -113,13 +217,18 @@ class Text : public TextBase, public TextInterface } float computedWidth() override { return localBounds().width(); }; float computedHeight() override { return localBounds().height(); }; + void updateList(std::vector>* list) override; #ifdef WITH_RIVE_TEXT - const std::vector& runs() const { return m_runs; } + const std::vector& runs() const { return m_allRuns; } static SimpleArray> BreakLines( const SimpleArray& paragraphs, float width, TextAlign align, TextWrap wrap); + const std::vector& textStylePaints() + { + return m_textStylePaints; + } #endif bool haveModifiers() const @@ -160,7 +269,9 @@ class Text : public TextBase, public TextInterface #ifdef WITH_RIVE_TEXT void updateOriginWorldTransform(); std::vector m_runs; + std::vector m_allRuns; std::vector m_renderStyles; + std::vector m_drawCommands; SimpleArray m_shape; SimpleArray m_modifierShape; SimpleArray> m_lines; @@ -176,10 +287,19 @@ class Text : public TextBase, public TextInterface StyledText m_styledText; StyledText m_modifierStyledText; GlyphLookup m_glyphLookup; + std::vector m_textStylePaints; void clearRenderStyles(); + void drawColorGlyph(Renderer* renderer, + const TextDrawCommand::ColorGlyphInfo& info, + const Mat2D& worldTransform); + std:: + unordered_map, ColorGlyphCacheHash> + m_emojiImageCache; TextBoundsInfo computeBoundsInfo(); LineIter shouldDrawLine(float y, float totalHeight, const GlyphLine& line); + void buildTextStylePaints(); + std::vector m_valueRunListeners; #endif float m_layoutWidth = NAN; diff --git a/thirdparty/rive/include/rive/text/text_input.hpp b/thirdparty/rive/include/rive/text/text_input.hpp index e550c5293..d9b22a9b0 100644 --- a/thirdparty/rive/include/rive/text/text_input.hpp +++ b/thirdparty/rive/include/rive/text/text_input.hpp @@ -2,17 +2,27 @@ #define _RIVE_TEXT_INPUT_HPP_ #include "rive/generated/text/text_input_base.hpp" +#include "rive/advancing_component.hpp" #include "rive/text/raw_text_input.hpp" #include "rive/text/text_interface.hpp" +#include "rive/input/focusable.hpp" +#include namespace rive { class TextStyle; -class TextInput : public TextInputBase, public TextInterface +class ScrollConstraint; +class TextInput : public TextInputBase, + public TextInterface, + public Focusable, + public AdvancingComponent { public: void draw(Renderer* renderer) override; Core* hitTest(HitInfo*, const Mat2D&) override; + bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) override; #ifdef WITH_RIVE_TEXT RawTextInput* rawTextInput() { return &m_rawTextInput; } @@ -34,13 +44,74 @@ class TextInput : public TextInputBase, public TextInterface LayoutScaleType heightScaleType, LayoutDirection direction) override; + bool keyInput(Key value, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) override; + bool textInput(const std::string& text) override; + void focused() override; + void blurred() override; + bool worldPosition(Vec2D& outPosition) override; + bool worldBounds(AABB& outBounds) override; + Artboard* focusableArtboard() const override { return artboard(); } + + /// Called when the user starts dragging on the text input. + /// Places the cursor at the given world position. + void startDrag(Vec2D worldPosition); + + /// Called when the user continues dragging on the text input. + /// Extends the selection to the given world position. + void drag(Vec2D worldPosition); + + /// Called when the user ends dragging on the text input. + void endDrag(Vec2D worldPosition); + + /// Advance edge scrolling during drag. Returns true if still scrolling. + bool advanceDrag(float elapsedSeconds); + bool advanceComponent(float elapsedSeconds, + AdvanceFlags flags = AdvanceFlags::Animate | + AdvanceFlags::NewFrame) override; + + /// Whether currently dragging (for hit test to avoid interference). + bool isDragging() const { return m_isDragging; } + protected: void textChanged() override; void selectionRadiusChanged() override; + void multilineChanged() override; private: + /// Convert a world position to local text input coordinates. + /// Handles viewport clamping and auto-scroll for scroll constraints. + bool worldToLocalWithViewport(Vec2D worldPosition, + Vec2D& outLocal, + bool enableAutoScroll); + + float edgeScrollSpeedForDistance(float distanceFromEdge) const; + float edgeActivationDistance(float position, float edgeStart) const; + + void updateMultiline(bool syncDisplayedText = false); + static std::string strippedLineBreaks(const std::string& text); + std::string displayedText() const; + void syncDisplayedTextFromSource(bool preserveCursor); + void syncSourceTextFromRaw(); + AABB m_worldBounds; + std::string m_sourceText; TextStyle* m_textStyle = nullptr; + ScrollConstraint* m_scrollConstraint = nullptr; + + /// Whether the user is currently dragging to select text. + bool m_isDragging = false; + Vec2D m_lastDragWorldPosition = Vec2D(NAN, NAN); + + /// Scroll velocity for edge scrolling during drag in X. + float m_scrollX = 0.0f; + + /// Scroll velocity for edge scrolling during drag. + float m_scrollY = 0.0f; + float m_layoutWidth = NAN; + #ifdef WITH_RIVE_TEXT RawTextInput m_rawTextInput; #endif diff --git a/thirdparty/rive/include/rive/text/text_input_drawable.hpp b/thirdparty/rive/include/rive/text/text_input_drawable.hpp index f0219fd8d..790bb5b9c 100644 --- a/thirdparty/rive/include/rive/text/text_input_drawable.hpp +++ b/thirdparty/rive/include/rive/text/text_input_drawable.hpp @@ -21,6 +21,7 @@ class TextInputDrawable : public TextInputDrawableBase, TextInput* textInput() const; Component* pathBuilder() override { return parent(); } void draw(Renderer* renderer) override; + bool willDraw() override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/text/text_input_selected_text.hpp b/thirdparty/rive/include/rive/text/text_input_selected_text.hpp index 05cfc2f3b..cfe0ae109 100644 --- a/thirdparty/rive/include/rive/text/text_input_selected_text.hpp +++ b/thirdparty/rive/include/rive/text/text_input_selected_text.hpp @@ -9,6 +9,7 @@ class TextInputSelectedText : public TextInputSelectedTextBase public: Core* hitTest(HitInfo*, const Mat2D&) override; ShapePaintPath* localClockwisePath() override; + StatusCode onAddedClean(CoreContext* context) override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/text/text_style.hpp b/thirdparty/rive/include/rive/text/text_style.hpp index 5a92e8acd..68e6b4670 100644 --- a/thirdparty/rive/include/rive/text/text_style.hpp +++ b/thirdparty/rive/include/rive/text/text_style.hpp @@ -5,6 +5,7 @@ #include "rive/assets/file_asset.hpp" #include "rive/assets/font_asset.hpp" #include "rive/text/text_interface.hpp" +#include "rive/text/text_variation_helper.hpp" namespace rive { @@ -26,16 +27,14 @@ class TextStyle : public TextStyleBase, public FileAssetReferencer TextStyle(); void buildDependencies() override; const rcp font() const; - void setAsset(FileAsset*) override; + void setAsset(rcp) override; uint32_t assetId() override; StatusCode import(ImportStack& importStack) override; - FontAsset* fontAsset() const { return (FontAsset*)m_fileAsset; } - Core* clone() const override; void addVariation(TextStyleAxis* axis); void addFeature(TextStyleFeature* feature); - void updateVariableFont(); + void updateVariableFont() const; StatusCode onAddedClean(CoreContext* context) override; void onDirty(ComponentDirt dirt) override; bool validate(CoreContext* context) override; @@ -44,16 +43,17 @@ class TextStyle : public TextStyleBase, public FileAssetReferencer void fontSizeChanged() override; void lineHeightChanged() override; void letterSpacingChanged() override; + FontAsset* fontAsset() const { return (FontAsset*)m_fileAsset.get(); } private: std::unique_ptr m_variationHelper; - rcp m_variableFont; + mutable rcp m_variableFont; - std::vector m_coords; + mutable std::vector m_coords; std::vector m_variations; std::vector m_styleFeatures; - std::vector m_features; - TextInterface* m_text; + mutable std::vector m_features; + TextInterface* m_text = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/text/text_style_paint.hpp b/thirdparty/rive/include/rive/text/text_style_paint.hpp index 2ec96e14e..9b33053c0 100644 --- a/thirdparty/rive/include/rive/text/text_style_paint.hpp +++ b/thirdparty/rive/include/rive/text/text_style_paint.hpp @@ -15,6 +15,10 @@ class TextStylePaint : public TextStylePaintBase, public ShapePaintContainer void rewindPath(); void draw(Renderer* renderer, const Mat2D& worldTransform); + /// Returns the foreground color from the first solid fill, or black if + /// none. + ColorInt foregroundColor() const; + // Implemented for ShapePaintContainer. const Mat2D& shapeWorldTransform() const override; Component* pathBuilder() override; @@ -31,4 +35,4 @@ class TextStylePaint : public TextStylePaintBase, public ShapePaintContainer }; } // namespace rive -#endif \ No newline at end of file +#endif diff --git a/thirdparty/rive/include/rive/text/text_value_run.hpp b/thirdparty/rive/include/rive/text/text_value_run.hpp index 94049910a..8cf05729c 100644 --- a/thirdparty/rive/include/rive/text/text_value_run.hpp +++ b/thirdparty/rive/include/rive/text/text_value_run.hpp @@ -1,7 +1,6 @@ #ifndef _RIVE_TEXT_VALUE_RUN_HPP_ #define _RIVE_TEXT_VALUE_RUN_HPP_ #include "rive/generated/text/text_value_run_base.hpp" -#include "rive/animation/hittable.hpp" #include "rive/text/utf.hpp" #include "rive/math/rectangles_to_contour.hpp" @@ -9,7 +8,7 @@ namespace rive { class TextStylePaint; class Text; -class TextValueRun : public TextValueRunBase, public Hittable +class TextValueRun : public TextValueRunBase { friend class HitTextRun; @@ -17,7 +16,9 @@ class TextValueRun : public TextValueRunBase, public Hittable StatusCode onAddedClean(CoreContext* context) override; StatusCode onAddedDirty(CoreContext* context) override; TextStylePaint* style() { return m_style; } + void style(TextStylePaint* value) { m_style = value; } Text* textComponent() const; + void textComponent(Text* value) { m_textComponent = value; }; uint32_t length() { if (m_length == -1) @@ -47,11 +48,14 @@ class TextValueRun : public TextValueRunBase, public Hittable // adding hit rects (via addHitRect) again. void computeHitContours(); - bool hitTestAABB(const Vec2D& position) override; - bool hitTestHiFi(const Vec2D& position, float hitRadius) override; + bool hitTestAABB(const Vec2D& position); + bool hitTestHiFi(const Vec2D& position, float hitRadius); bool isHitTarget() const { return m_isHitTarget; } void isHitTarget(bool value); + bool hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) override; protected: void textChanged() override; @@ -65,6 +69,7 @@ class TextValueRun : public TextValueRunBase, public Hittable TextStylePaint* m_style = nullptr; uint32_t m_length = -1; bool canHitTest() const; + Text* m_textComponent = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/text_engine.hpp b/thirdparty/rive/include/rive/text_engine.hpp index e9d5e85eb..14e21eb67 100644 --- a/thirdparty/rive/include/rive/text_engine.hpp +++ b/thirdparty/rive/include/rive/text_engine.hpp @@ -7,9 +7,12 @@ #include "rive/math/raw_path.hpp" #include "rive/refcnt.hpp" +#include "rive/shapes/paint/color.hpp" #include "rive/span.hpp" #include "rive/simple_array.hpp" +#include + namespace rive { @@ -224,6 +227,67 @@ class Font : public RefCnt // virtual RawPath getPath(GlyphID) const = 0; + // Color glyph (emoji) support via COLR/CPAL tables. + + // A single layer of a color glyph, with its own path and fill. + struct GradientStop + { + float offset; + ColorInt color; + }; + + enum class ColorGlyphPaintType : uint8_t + { + solid, + linearGradient, + radialGradient, + sweepGradient, + image, + }; + + struct ColorGlyphLayer + { + RawPath path; + ColorGlyphPaintType paintType = ColorGlyphPaintType::solid; + ColorInt color = 0xFF000000; // ARGB (for solid fills) + bool useForeground = false; // true if color should use text color + + // Gradient data (only valid when paintType != solid). + std::vector stops; + // Linear gradient: (x0,y0) start, (x1,y1) end. + // Radial gradient: (x0,y0,r0) inner circle, (x1,y1,r1) outer circle. + // Sweep gradient: (x0,y0) center, startAngle, endAngle. + float x0 = 0, y0 = 0, x1 = 0, y1 = 0; + float r0 = 0, r1 = 0; // radial + float startAngle = 0, endAngle = 0; // sweep + + // Image data (only valid when paintType == image). + // Raw encoded image bytes (e.g. PNG from SBIX/CBDT). + std::vector imageBytes; + unsigned int imageWidth = 0, imageHeight = 0; + // Glyph extents for positioning the image. + float imageBearingX = 0, imageBearingY = 0; + float imageExtentX = 0, imageExtentY = 0; + }; + + // Whether this font contains any COLR color glyphs. + virtual bool hasColorGlyphs() const { return false; } + + // Whether a specific glyph has color layers. + virtual bool isColorGlyph(GlyphID) const { return false; } + + // Decompose a color glyph into its colored layers. Returns the number + // of layers written to `out`. If the glyph is not a color glyph, + // returns 0. + virtual size_t getColorLayers(GlyphID, + std::vector& out, + ColorInt foreground = 0xFF000000) const + { + (void)out; + (void)foreground; + return 0; + } + SimpleArray shapeText(Span text, Span runs, int textDirectionFlag = -1) const; @@ -331,6 +395,11 @@ struct GlyphRun // Bidi level (even is LTR, odd is RTL) uint8_t level; + // List of indices where words are joined by a word-joiner character. + // During text breaking, these joins should be honored and not split at + // those points + SimpleArray joiners; + TextDirection dir() const { return level & 1 ? TextDirection::rtl : TextDirection::ltr; diff --git a/thirdparty/rive/include/rive/texture_archive.hpp b/thirdparty/rive/include/rive/texture_archive.hpp new file mode 100644 index 000000000..baf3981c3 --- /dev/null +++ b/thirdparty/rive/include/rive/texture_archive.hpp @@ -0,0 +1,91 @@ +#pragma once + +#include "rive/span.hpp" + +#include +#include +#include + +namespace rive +{ + +// On-disk header for a .rtex archive. Fields are little-endian; all Rive +// runtime targets (web/wasm, ARM iOS/Android, x86_64 desktop, Apple Silicon) +// are little-endian, so the struct is written and read by raw memcpy. +#pragma pack(push, 1) +struct TextureArchiveHeader +{ + static constexpr char kMagic[4] = {'R', 'T', 'E', 'X'}; + static constexpr uint16_t kCurrentVersion = 1; + + char magic[4]; + uint16_t version; + uint16_t textureCount; +}; +#pragma pack(pop) +static_assert(sizeof(TextureArchiveHeader) == 8, + "TextureArchiveHeader must be tightly packed (8 bytes)"); + +// Enum class to describe the format of a texture. +// Only formats which are directly read by a GPU are listed here +enum class GPUTextureFormat : uint8_t +{ + rgba32, + bc1, + bc2, + bc3, + bc7, + astc, + etc2 +}; + +// Block size of various GPUTextureFormats +enum class GPUTextureFormatBlockSize : uint8_t +{ + p_1x1, // Pixels are 1x1 for uncompressed + b_4x4, // B means Block here + b_6x6, + b_8x8, + b_12x12, +}; + +struct TextureMipLevel +{ + uint16_t blocksX; + uint16_t blocksY; + uint32_t bytesTotal; + const uint8_t* blocks; // or offset into a big buffer +}; + +struct TextureData +{ + uint16_t width; + uint16_t height; + uint16_t paddedWidth; + uint16_t paddedHeight; + + uint8_t blockSizeX; + uint8_t blockSizeY; + uint8_t bytesPerBlock; + uint8_t numMips; + + GPUTextureFormat format; + + std::vector mipLevels; + + // Combined pixel data size + uint32_t totalBytes; +}; + +class TextureDirectory +{ +public: + std::vector dir; + std::vector dataBlob; + + void addTexture(TextureData& header); + bool exportArchive(const std::string& path); + bool import(const std::string& path); + bool import(Span texBytes); +}; +} // namespace rive diff --git a/thirdparty/rive/include/rive/transform_component.hpp b/thirdparty/rive/include/rive/transform_component.hpp index e9bfa9987..13ff489aa 100644 --- a/thirdparty/rive/include/rive/transform_component.hpp +++ b/thirdparty/rive/include/rive/transform_component.hpp @@ -55,6 +55,7 @@ class TransformComponent : public TransformComponentBase, void scaleYChanged() override; void addConstraint(Constraint* constraint); + virtual AABB constraintBounds() const { return AABB(); } virtual AABB localBounds() const; void markDirtyIfConstrained(); }; diff --git a/thirdparty/rive/include/rive/typed_children.hpp b/thirdparty/rive/include/rive/typed_children.hpp index fbb2efbe3..f0b7ebef7 100644 --- a/thirdparty/rive/include/rive/typed_children.hpp +++ b/thirdparty/rive/include/rive/typed_children.hpp @@ -12,12 +12,21 @@ template class TypedChild public: TypedChild(Core** child, Core** end) : m_child(child), m_end(end) {} - T* operator*() const { return (*m_child)->template as(); } + T* operator*() const + { + auto child = *m_child; + if (child == nullptr) + { + return nullptr; + } + return child->template as(); + } + TypedChild& operator++() { m_child++; - while (m_child != m_end && (*m_child) != nullptr && - !(*m_child)->template is()) + while (m_child != m_end && + ((*m_child) == nullptr || !(*m_child)->template is())) { m_child++; } @@ -42,7 +51,8 @@ template class TypedChildren { size_t size = m_children.size(); size_t index = 0; - while (index < size && !m_children[index]->template is()) + while (index < size && (m_children[index] == nullptr || + !m_children[index]->template is())) { index++; } diff --git a/thirdparty/rive/include/rive/viewmodel/property_symbol_dependent.hpp b/thirdparty/rive/include/rive/viewmodel/property_symbol_dependent.hpp new file mode 100644 index 000000000..7b5debbc8 --- /dev/null +++ b/thirdparty/rive/include/rive/viewmodel/property_symbol_dependent.hpp @@ -0,0 +1,69 @@ +#ifndef _RIVE_PROPERTY_SYMBOl_DEPENDENT_HPP_ +#define _RIVE_PROPERTY_SYMBOl_DEPENDENT_HPP_ +#include "rive/core.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_value_dependent.hpp" +#include +namespace rive +{ +class CoreObjectListener; +class PropertySymbolDependent : public ViewModelValueDependent +{ +public: + PropertySymbolDependent(Core* coreObject, + CoreObjectListener* coreObjectListener, + ViewModelInstanceValue* instanceValue); + virtual ~PropertySymbolDependent(); + + void addDirt(ComponentDirt value, bool recurse) override; + virtual void writeValue() = 0; + void relinkDataBind() override {} + +protected: + Core* m_coreObject = nullptr; + CoreObjectListener* m_coreObjectListener = nullptr; + ViewModelInstanceValue* m_instanceValue = nullptr; +}; + +class PropertySymbolDependentSingle : public PropertySymbolDependent +{ +public: + PropertySymbolDependentSingle(Core* vertex, + CoreObjectListener* vertexListener, + ViewModelInstanceValue* instanceValue, + uint16_t propertyKey); + +protected: + uint16_t m_propertyKey = 0; +}; + +class PropertySymbolDependentMulti : public PropertySymbolDependent +{ +public: + PropertySymbolDependentMulti(Core* vertex, + CoreObjectListener* vertexListener, + ViewModelInstanceValue* instanceValue, + std::vector propertyKeys); + +protected: + std::vector m_propertyKeys; +}; + +class CoreObjectListener +{ +public: + CoreObjectListener(Core* core, rcp instance); + virtual ~CoreObjectListener(); + void remap(rcp instance); + virtual void markDirty() {} + +protected: + Core* m_core = nullptr; + rcp m_instance = nullptr; + virtual void createProperties(); + virtual void deleteProperties(); + std::vector m_properties; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_artboard_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_artboard_runtime.hpp new file mode 100644 index 000000000..57bb90103 --- /dev/null +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_artboard_runtime.hpp @@ -0,0 +1,30 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_RUNTIME_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_RUNTIME_HPP_ + +#include +#include +#include "rive/viewmodel/runtime/viewmodel_instance_value_runtime.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" +#include "rive/bindable_artboard.hpp" + +namespace rive +{ + +class ViewModelInstanceArtboardRuntime : public ViewModelInstanceValueRuntime +{ + +public: + ViewModelInstanceArtboardRuntime( + ViewModelInstanceArtboard* viewModelInstance) : + ViewModelInstanceValueRuntime(viewModelInstance) + {} + void value(rcp bindableArtboard); + void viewModelInstance(rcp viewModelInstance); + const DataType dataType() override { return DataType::artboard; } + +#ifdef TESTING + rcp testing_value(); +#endif +}; +} // namespace rive +#endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_asset_image_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_asset_image_runtime.hpp index 9db0a8c27..7c70727ba 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_asset_image_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_asset_image_runtime.hpp @@ -18,6 +18,11 @@ class ViewModelInstanceAssetImageRuntime : public ViewModelInstanceValueRuntime ViewModelInstanceValueRuntime(viewModelInstance) {} void value(RenderImage* renderImage); + const DataType dataType() override { return DataType::assetImage; } + +#ifdef TESTING + RenderImage* testing_value(); +#endif }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_boolean_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_boolean_runtime.hpp index 4673dc17d..95b6519a2 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_boolean_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_boolean_runtime.hpp @@ -19,6 +19,7 @@ class ViewModelInstanceBooleanRuntime : public ViewModelInstanceValueRuntime {} bool value() const; void value(bool); + const DataType dataType() override { return DataType::boolean; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_color_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_color_runtime.hpp index 22f9a159a..c1943440c 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_color_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_color_runtime.hpp @@ -21,6 +21,7 @@ class ViewModelInstanceColorRuntime : public ViewModelInstanceValueRuntime void rgb(int, int, int); void argb(int, int, int, int); void alpha(int); + const DataType dataType() override { return DataType::color; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_enum_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_enum_runtime.hpp index e520183d1..9e4ddb444 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_enum_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_enum_runtime.hpp @@ -23,6 +23,8 @@ class ViewModelInstanceEnumRuntime : public ViewModelInstanceValueRuntime uint32_t valueIndex() const; void valueIndex(uint32_t); std::vector values() const; + std::string enumType() const; + const DataType dataType() override { return DataType::enumType; } private: std::vector dataValues() const; diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_list_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_list_runtime.hpp index 4d41af115..8f9385984 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_list_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_list_runtime.hpp @@ -16,19 +16,22 @@ class ViewModelInstanceListRuntime : public ViewModelInstanceValueRuntime { public: - ~ViewModelInstanceListRuntime(); ViewModelInstanceListRuntime(ViewModelInstanceList* viewModelInstance) : ViewModelInstanceValueRuntime(viewModelInstance) {} - ViewModelInstanceRuntime* instanceAt(int index); + rcp instanceAt(int index); void addInstance(ViewModelInstanceRuntime*); + bool addInstanceAt(ViewModelInstanceRuntime*, int); void removeInstance(ViewModelInstanceRuntime*); void removeInstanceAt(int); void swap(uint32_t, uint32_t); + void removeAllInstances(); size_t size() const; + const DataType dataType() override { return DataType::list; } private: - std::unordered_map + std::unordered_map, + rcp> m_itemsMap; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_number_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_number_runtime.hpp index 06e864b2f..914333165 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_number_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_number_runtime.hpp @@ -18,6 +18,7 @@ class ViewModelInstanceNumberRuntime : public ViewModelInstanceValueRuntime {} float value() const; void value(float); + const DataType dataType() override { return DataType::number; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_runtime.hpp index c3cf87e23..209d78e58 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_runtime.hpp @@ -15,6 +15,7 @@ #include "rive/viewmodel/runtime/viewmodel_instance_trigger_runtime.hpp" #include "rive/viewmodel/runtime/viewmodel_instance_list_runtime.hpp" #include "rive/viewmodel/runtime/viewmodel_instance_asset_image_runtime.hpp" +#include "rive/viewmodel/runtime/viewmodel_instance_artboard_runtime.hpp" #include "rive/refcnt.hpp" namespace rive @@ -30,6 +31,7 @@ class ViewModelInstanceRuntime : public RefCnt ~ViewModelInstanceRuntime(); const std::string& name() const; + const std::string& viewModelName() const; size_t propertyCount() const; ViewModelInstanceNumberRuntime* propertyNumber( const std::string& path) const; @@ -42,9 +44,12 @@ class ViewModelInstanceRuntime : public RefCnt ViewModelInstanceTriggerRuntime* propertyTrigger( const std::string& path) const; ViewModelInstanceListRuntime* propertyList(const std::string& path) const; - ViewModelInstanceRuntime* propertyViewModel(const std::string& path) const; + rcp propertyViewModel( + const std::string& path) const; ViewModelInstanceAssetImageRuntime* propertyImage( const std::string& path) const; + ViewModelInstanceArtboardRuntime* propertyArtboard( + const std::string& path) const; bool replaceViewModel(const std::string& path, ViewModelInstanceRuntime* value) const; bool replaceViewModelByName(const std::string& name, @@ -55,7 +60,6 @@ class ViewModelInstanceRuntime : public RefCnt private: rcp m_viewModelInstance = nullptr; - std::string getPropertyNameFromPath(const std::string& path) const; const ViewModelInstanceRuntime* viewModelInstanceFromFullPath( const std::string& path) const; @@ -77,7 +81,12 @@ class ViewModelInstanceRuntime : public RefCnt auto itr = m_properties.find(name); if (itr != m_properties.end()) { - return static_cast(itr->second); + if (itr->second->viewModelInstanceValue() && + itr->second->viewModelInstanceValue()->is()) + { + return static_cast(itr->second); + } + return nullptr; } auto viewModelInstanceValue = m_viewModelInstance->propertyValue(name); if (viewModelInstanceValue != nullptr && diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_string_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_string_runtime.hpp index dc2e48161..b5a69fb9f 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_string_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_string_runtime.hpp @@ -18,6 +18,7 @@ class ViewModelInstanceStringRuntime : public ViewModelInstanceValueRuntime {} const std::string& value() const; void value(std::string); + const DataType dataType() override { return DataType::string; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_trigger_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_trigger_runtime.hpp index 73d346b7e..8ce7a2939 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_trigger_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_trigger_runtime.hpp @@ -18,6 +18,7 @@ class ViewModelInstanceTriggerRuntime : public ViewModelInstanceValueRuntime ViewModelInstanceValueRuntime(viewModelInstance) {} void trigger(); + const DataType dataType() override { return DataType::trigger; } }; } // namespace rive #endif diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_value_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_value_runtime.hpp index 306d826f1..3e494a27d 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_value_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_instance_value_runtime.hpp @@ -4,22 +4,29 @@ #include #include #include "rive/viewmodel/viewmodel_instance_value.hpp" -#include "rive/dirtyable.hpp" +#include "rive/viewmodel/viewmodel_value_dependent.hpp" +#include "rive/data_bind/data_values/data_type.hpp" namespace rive { -class ViewModelInstanceValueRuntime : public Dirtyable +class ViewModelInstanceValueRuntime : public ViewModelValueDependent { public: ViewModelInstanceValueRuntime(ViewModelInstanceValue* instanceValue); virtual ~ViewModelInstanceValueRuntime(); + virtual const DataType dataType() = 0; void addDirt(ComponentDirt dirt, bool recurse) override; void clearChanges(); bool hasChanged() const { return m_hasChanged; } bool flushChanges(); const std::string& name() const; + ViewModelInstanceValue* viewModelInstanceValue() + { + return m_viewModelInstanceValue; + } + void relinkDataBind() override; protected: ViewModelInstanceValue* m_viewModelInstanceValue = nullptr; diff --git a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_runtime.hpp b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_runtime.hpp index a249f25e7..77f6f0e21 100644 --- a/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_runtime.hpp +++ b/thirdparty/rive/include/rive/viewmodel/runtime/viewmodel_runtime.hpp @@ -18,7 +18,7 @@ struct PropertyData std::string name; }; -class ViewModelRuntime +class ViewModelRuntime : public RefCnt { public: @@ -27,11 +27,11 @@ class ViewModelRuntime const std::string& name() const; size_t instanceCount() const; size_t propertyCount() const; - ViewModelInstanceRuntime* createInstanceFromIndex(size_t index) const; - ViewModelInstanceRuntime* createInstanceFromName( + rcp createInstanceFromIndex(size_t index) const; + rcp createInstanceFromName( const std::string& name) const; - ViewModelInstanceRuntime* createDefaultInstance() const; - ViewModelInstanceRuntime* createInstance() const; + rcp createDefaultInstance() const; + rcp createInstance() const; std::vector properties(); static std::vector buildPropertiesData( std::vector& properties); @@ -40,9 +40,7 @@ class ViewModelRuntime private: ViewModel* m_viewModel; const File* m_file; - mutable std::vector> - m_viewModelInstanceRuntimes; - ViewModelInstanceRuntime* createRuntimeInstance( + rcp createRuntimeInstance( rcp instance) const; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/symbol_type.hpp b/thirdparty/rive/include/rive/viewmodel/symbol_type.hpp new file mode 100644 index 000000000..2a4902e62 --- /dev/null +++ b/thirdparty/rive/include/rive/viewmodel/symbol_type.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_SYMBOL_TYPE_HPP_ +#define _RIVE_SYMBOL_TYPE_HPP_ +namespace rive +{ +enum class SymbolType : unsigned char +{ + none = 0, + vertexX = 1, + vertexY = 2, + cubicVertexInPointX = 3, + cubicVertexInPointY = 4, + cubicVertexOutPointX = 5, + cubicVertexOutPointY = 6, + rotation = 7, + inRotation = 8, + outRotation = 9, + distance = 10, + inDistance = 11, + outDistance = 12, + textStyle = 13, + textContent = 14, + itemIndex = 15, + drawIndex = 16, +}; +} +#endif diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel.hpp index 1d1d3e866..cea2cc6dd 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel.hpp @@ -3,24 +3,34 @@ #include "rive/generated/viewmodel/viewmodel_base.hpp" #include "rive/viewmodel/viewmodel_property.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/symbol_type.hpp" #include "rive/refcnt.hpp" #include namespace rive { +class File; class ViewModel : public ViewModelBase, public RefCnt { private: std::vector m_Properties; std::vector m_Instances; + File* m_file = nullptr; public: ~ViewModel(); void addProperty(ViewModelProperty* property); ViewModelProperty* property(const std::string& name); + ViewModelProperty* property(SymbolType symbolType); ViewModelProperty* property(size_t index); void addInstance(ViewModelInstance* value); ViewModelInstance* instance(size_t index); ViewModelInstance* instance(const std::string& name); + rcp createInstance(); + rcp createFromInstance(const std::string& instanceName); + void file(File* value) { m_file = value; }; +#ifdef WITH_RIVE_TOOLS + File* file() { return m_file; }; +#endif ViewModelInstance* defaultInstance(); size_t instanceCount() const; std::vector properties() { return m_Properties; } diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance.hpp index 4abea31f9..cd8412c02 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance.hpp @@ -2,30 +2,55 @@ #define _RIVE_VIEW_MODEL_INSTANCE_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_base.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/symbol_type.hpp" +#include "rive/data_bind/data_bind_container.hpp" #include "rive/component.hpp" #include "rive/refcnt.hpp" +#include #include +#include +#include namespace rive { class ViewModel; +class ViewModelInstanceViewModel; class ViewModelInstance : public ViewModelInstanceBase, public RefCnt { private: - std::vector m_PropertyValues; + std::vector> m_PropertyValues; + std::vector m_parents; + std::vector m_dependents; + std::unordered_map m_propertySymbols; ViewModel* m_ViewModel; + void rebindDependents(); + void rebindProperties(); public: + static uint32_t pointerKey(const ViewModelInstance* instance) + { + if (instance == nullptr) + { + return -1; + } + auto ptr = reinterpret_cast(instance); + return static_cast(ptr ^ (ptr >> 32)); + } + ~ViewModelInstance(); void addValue(ViewModelInstanceValue* value); ViewModelInstanceValue* propertyValue(const uint32_t id); ViewModelInstanceValue* propertyValue(const std::string& name); + ViewModelInstanceValue* propertyValue(const SymbolType symbolType); + void propertyValue(const SymbolType symbolType, + ViewModelInstanceValue* value); bool replaceViewModelByName(const std::string& name, rcp value); - std::vector propertyValues(); + bool replaceViewModelByProperty(ViewModelInstanceViewModel*, + rcp value); + const std::vector>& propertyValues(); ViewModelInstanceValue* propertyFromPath(std::vector* path, size_t index); - ViewModelInstanceValue* symbol(int coreType); void viewModel(ViewModel* value); ViewModel* viewModel() const; void onComponentDirty(Component* component); @@ -34,6 +59,14 @@ class ViewModelInstance : public ViewModelInstanceBase, Core* clone() const override; StatusCode import(ImportStack& importStack) override; void advanced(); + void addParent(ViewModelInstance*); + void removeParent(ViewModelInstance*); + void addDependent(DataBindContainer*); + void removeDependent(DataBindContainer*); +#ifdef TESTING + std::vector dependents() { return m_dependents; } + std::vector parents() { return m_parents; } +#endif }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_artboard.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_artboard.hpp new file mode 100644 index 000000000..8229b1c4e --- /dev/null +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_artboard.hpp @@ -0,0 +1,44 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" +#include "rive/bindable_artboard.hpp" +#include +namespace rive +{ +#ifdef WITH_RIVE_TOOLS +class ViewModelInstanceArtboard; +typedef void (*ViewModelArtboardChanged)(ViewModelInstanceArtboard* vmi, + uint32_t value); +#endif +class ViewModelInstanceArtboard : public ViewModelInstanceArtboardBase +{ +protected: + void propertyValueChanged() override; + +public: + void asset(rcp value); + void boundViewModelInstance(rcp value); + rcp asset() { return m_bindableArtboard; } + void applyValue(DataValueInteger*); + rcp boundViewModelInstance() + { + return m_boundViewModelInstance; + } + void advanced() override; + +private: + rcp m_bindableArtboard = nullptr; + rcp m_boundViewModelInstance = nullptr; +#ifdef WITH_RIVE_TOOLS +public: + void onChanged(ViewModelArtboardChanged callback) + { + m_changedCallback = callback; + } + ViewModelArtboardChanged m_changedCallback = nullptr; +#endif +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset.hpp index 181f635bf..bfb86bc52 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset.hpp @@ -2,6 +2,7 @@ #define _RIVE_VIEW_MODEL_INSTANCE_ASSET_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_asset_base.hpp" #include "rive/assets/file_asset.hpp" +#include "rive/refcnt.hpp" #include namespace rive { @@ -14,13 +15,13 @@ class ViewModelInstanceAsset : public ViewModelInstanceAssetBase { public: StatusCode import(ImportStack& importStack) override; - void addAsset(FileAsset* asset) { m_assets.push_back(asset); } + void addAsset(rcp asset) { m_assets.push_back(asset); } protected: - const std::vector& assets() const { return m_assets; } + const std::vector>& assets() const { return m_assets; } private: - std::vector m_assets; + std::vector> m_assets; #ifdef WITH_RIVE_TOOLS public: void onChanged(ViewModelAssetChanged callback) diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset_image.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset_image.hpp index 9a523eefc..6c98f3a90 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset_image.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_asset_image.hpp @@ -2,6 +2,8 @@ #define _RIVE_VIEW_MODEL_INSTANCE_ASSET_IMAGE_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_asset_image_base.hpp" #include "rive/renderer.hpp" +#include "rive/refcnt.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" #include "rive/assets/image_asset.hpp" #include namespace rive @@ -12,12 +14,14 @@ class ViewModelInstanceAssetImage : public ViewModelInstanceAssetImageBase void propertyValueChanged() override; public: + ViewModelInstanceAssetImage(); void value(RenderImage* image); - ImageAsset* asset() { return &m_imageAsset; } + rcp asset() { return m_imageAsset; } Core* clone() const override; + void applyValue(DataValueInteger*); private: - ImageAsset m_imageAsset; + rcp m_imageAsset = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_boolean.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_boolean.hpp index 26ec4eebc..a8b2d0fd0 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_boolean.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_boolean.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_BOOLEAN_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_BOOLEAN_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" #include namespace rive { @@ -13,14 +14,16 @@ class ViewModelInstanceBoolean : public ViewModelInstanceBooleanBase { protected: void propertyValueChanged() override; -#ifdef WITH_RIVE_TOOLS + public: +#ifdef WITH_RIVE_TOOLS void onChanged(ViewModelBooleanChanged callback) { m_changedCallback = callback; } ViewModelBooleanChanged m_changedCallback = nullptr; #endif + void applyValue(DataValueBoolean*); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_color.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_color.hpp index 045dd6115..00b2eb719 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_color.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_color.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_COLOR_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_COLOR_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_color_base.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" #include namespace rive { @@ -13,13 +14,13 @@ class ViewModelInstanceColor : public ViewModelInstanceColorBase public: void propertyValueChanged() override; #ifdef WITH_RIVE_TOOLS -public: void onChanged(ViewModelColorChanged callback) { m_changedCallback = callback; } ViewModelColorChanged m_changedCallback = nullptr; #endif + void applyValue(DataValueColor*); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_enum.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_enum.hpp index 65db72787..f538297a5 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_enum.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_enum.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_ENUM_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_ENUM_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_enum_base.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" #include namespace rive { @@ -14,6 +15,7 @@ class ViewModelInstanceEnum : public ViewModelInstanceEnumBase public: bool value(std::string name); bool value(uint32_t index); + void applyValue(DataValueInteger*); protected: void propertyValueChanged() override; diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list.hpp index 63277adb2..52203cc99 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list.hpp @@ -1,27 +1,58 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_LIST_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_LIST_HPP_ +#include "rive/data_bind/data_bind_list_item_consumer.hpp" #include "rive/generated/viewmodel/viewmodel_instance_list_base.hpp" #include "rive/viewmodel/viewmodel_instance_list_item.hpp" #include namespace rive { -class ViewModelInstanceList : public ViewModelInstanceListBase +#ifdef WITH_RIVE_TOOLS +class ViewModelInstanceList; +typedef void (*ViewModelListChanged)(ViewModelInstanceList* vmi); +#endif +class ViewModelInstanceList : public ViewModelInstanceListBase, + public DataBindListItemConsumer { public: ~ViewModelInstanceList(); - void addItem(ViewModelInstanceListItem* listItem); - void internalAddItem(ViewModelInstanceListItem* listItem); - void insertItem(int index, ViewModelInstanceListItem* listItem); + void addItem(rcp listItem); + bool addItemAt(rcp listItem, int index); + void internalAddItem(rcp listItem); void removeItem(int index); - void removeItem(ViewModelInstanceListItem* listItem); - std::vector listItems() { return m_ListItems; }; - ViewModelInstanceListItem* item(uint32_t index); + void removeItem(rcp listItem); + Span> listItems() { return m_ListItems; } + rcp item(uint32_t index); void swap(uint32_t index1, uint32_t index2); + rcp pop(); + rcp shift(); + void removeAllItems(); + void removeAllItemsWithViewModelInstance( + ViewModelInstance* viewModelInstance); + void updateList(std::vector>* list) override; Core* clone() const override; + void advanced() override; + void parentViewModelInstance(ViewModelInstance* parent) + { + m_parentViewModelInstance = parent; + } + ViewModelInstance* parentViewModelInstance() + { + return m_parentViewModelInstance; + } +#ifdef WITH_RIVE_TOOLS + void onChanged(ViewModelListChanged callback) + { + m_changedCallback = callback; + } + ViewModelListChanged m_changedCallback = nullptr; +#endif protected: - std::vector m_ListItems; + std::vector> m_ListItems; void propertyValueChanged(); + +private: + ViewModelInstance* m_parentViewModelInstance = nullptr; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list_item.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list_item.hpp index 7a36877a4..635d2d179 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list_item.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_list_item.hpp @@ -18,7 +18,7 @@ class ViewModelInstanceListItem : public ViewModelInstanceListItemBase, { m_viewModelInstance = value; }; - rcp viewModelInstance() { return m_viewModelInstance; } + rcp& viewModelInstance() { return m_viewModelInstance; } void artboard(Artboard* value) { m_artboard = value; }; Artboard* artboard() { return m_artboard; } StatusCode import(ImportStack& importStack) override; diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_number.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_number.hpp index 7e85b5265..73f42a6cf 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_number.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_number.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_NUMBER_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_NUMBER_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_number_base.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" #include namespace rive { @@ -13,14 +14,16 @@ class ViewModelInstanceNumber : public ViewModelInstanceNumberBase { protected: void propertyValueChanged() override; -#ifdef WITH_RIVE_TOOLS + public: +#ifdef WITH_RIVE_TOOLS void onChanged(ViewModelNumberChanged callback) { m_changedCallback = callback; } ViewModelNumberChanged m_changedCallback = nullptr; #endif + void applyValue(DataValueNumber*); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_string.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_string.hpp index a579298a5..706588d98 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_string.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_string.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_STRING_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_STRING_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_string_base.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" #include namespace rive { @@ -14,13 +15,13 @@ class ViewModelInstanceString : public ViewModelInstanceStringBase public: void propertyValueChanged() override; #ifdef WITH_RIVE_TOOLS -public: void onChanged(ViewModelStringChanged callback) { m_changedCallback = callback; } ViewModelStringChanged m_changedCallback = nullptr; #endif + void applyValue(DataValueString*); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_symbol_list_index.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_symbol_list_index.hpp index 23d71519e..7175a637a 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_symbol_list_index.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_symbol_list_index.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_SYMBOL_LIST_INDEX_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_SYMBOL_LIST_INDEX_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_symbol_list_index_base.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" #include namespace rive { @@ -15,14 +16,16 @@ class ViewModelInstanceSymbolListIndex { protected: void propertyValueChanged() override; -#ifdef WITH_RIVE_TOOLS + public: +#ifdef WITH_RIVE_TOOLS void onChanged(ViewModelSymbolListIndexChanged callback) { m_changedCallback = callback; } ViewModelSymbolListIndexChanged m_changedCallback = nullptr; #endif + void applyValue(DataValueInteger*); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_trigger.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_trigger.hpp index 618a5b6b2..8016fc56a 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_trigger.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_trigger.hpp @@ -2,6 +2,7 @@ #define _RIVE_VIEW_MODEL_INSTANCE_TRIGGER_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp" #include "rive/animation/state_machine_input_instance.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" #include namespace rive { @@ -10,8 +11,7 @@ class ViewModelInstanceTrigger; typedef void (*ViewModelTriggerChanged)(ViewModelInstanceTrigger* vmi, uint32_t value); #endif -class ViewModelInstanceTrigger : public ViewModelInstanceTriggerBase, - public Triggerable +class ViewModelInstanceTrigger : public ViewModelInstanceTriggerBase { protected: void propertyValueChanged() override; @@ -27,6 +27,7 @@ class ViewModelInstanceTrigger : public ViewModelInstanceTriggerBase, #endif void trigger() { propertyValue(propertyValue() + 1); } + void applyValue(DataValueInteger*); }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_value.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_value.hpp index 292c7acff..3cb0dac9d 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_value.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_value.hpp @@ -1,37 +1,102 @@ #ifndef _RIVE_VIEW_MODEL_INSTANCE_VALUE_HPP_ #define _RIVE_VIEW_MODEL_INSTANCE_VALUE_HPP_ #include "rive/generated/viewmodel/viewmodel_instance_value_base.hpp" +#include "rive/animation/state_machine_input_instance.hpp" #include "rive/viewmodel/viewmodel_property.hpp" #include "rive/dependency_helper.hpp" -#include "rive/dirtyable.hpp" +#include "rive/viewmodel/viewmodel_value_dependent.hpp" #include "rive/component.hpp" #include "rive/component_dirt.hpp" #include "rive/refcnt.hpp" #include +#include + namespace rive { class ViewModelInstance; +class ViewModelInstanceValueDelegate +{ +public: + virtual void valueChanged() = 0; +}; + +enum class ValueFlags : uint8_t +{ + none = 0, + valueChanged = 1 << 1, + delegatesChanged = 1 << 2, + delegating = 1 << 3, +}; + +class SuppressDelegation; + class ViewModelInstanceValue : public ViewModelInstanceValueBase, - public RefCnt + public RefCnt, + public Triggerable { + friend class SuppressDelegation; + private: - ViewModelProperty* m_ViewModelProperty; + ViewModelProperty* m_ViewModelProperty = nullptr; static std::string defaultName; + ValueFlags m_changeFlags; + std::vector m_delegates; + std::vector m_delegatesCopy; + void registerSymbol(); + +public: + void addDelegate(ViewModelInstanceValueDelegate* delegate); + void removeDelegate(ViewModelInstanceValueDelegate* delegate); protected: - DependencyHelper, Dirtyable> m_DependencyHelper; + DependencyHelper, ViewModelValueDependent> + m_DependencyHelper; + ViewModelInstance* m_viewModelInstance = nullptr; void addDirt(ComponentDirt value); + // Suppress/restore calling delegates. + bool suppressDelegation(); + void restoreDelegation(); + public: + StatusCode onAddedDirty(CoreContext* context) override; StatusCode import(ImportStack& importStack) override; void viewModelProperty(ViewModelProperty* value); ViewModelProperty* viewModelProperty(); - void addDependent(Dirtyable* value); - void removeDependent(Dirtyable* value); + void viewModelInstance(ViewModelInstance* value); + void addDependent(ViewModelValueDependent* value); + void removeDependent(ViewModelValueDependent* value); virtual void setRoot(rcp value); - virtual void advanced(){}; + virtual void advanced(); + bool hasChanged(); + void onValueChanged(); const std::string& name() const; + std::vector& dependents() + { + return m_DependencyHelper.mutableDependents(); + } +}; + +class SuppressDelegation +{ +public: + SuppressDelegation(ViewModelInstanceValue* value) : + m_value(value), m_suppressed(value->suppressDelegation()) + {} + + ~SuppressDelegation() + { + if (m_suppressed) + { + m_value->restoreDelegation(); + } + } + +private: + ViewModelInstanceValue* m_value = nullptr; + bool m_suppressed; }; + } // namespace rive #endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp index e1407ca1f..1647cecfd 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp @@ -3,26 +3,65 @@ #include "rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" #include "rive/refcnt.hpp" +#include "rive/data_bind/data_bind_viewmodel_consumer.hpp" #include namespace rive { -class ViewModelInstanceViewModel : public ViewModelInstanceViewModelBase +class DataValueViewModel; +#ifdef WITH_RIVE_TOOLS +class ViewModelInstanceViewModel; +typedef void (*ViewModelViewModelChanged)(ViewModelInstanceViewModel* vmi); +#endif +class ViewModelInstanceViewModel : public ViewModelInstanceViewModelBase, + public DataBindViewModelConsumer { private: - rcp m_referenceViewModelInstance; + rcp m_referenceViewModelInstance = nullptr; + ViewModelInstance* m_parentViewModelInstance = nullptr; public: - ~ViewModelInstanceViewModel(); void referenceViewModelInstance(rcp value) { + if (m_referenceViewModelInstance && m_parentViewModelInstance) + { + m_referenceViewModelInstance->removeParent( + m_parentViewModelInstance); + } m_referenceViewModelInstance = value; + if (m_referenceViewModelInstance && m_parentViewModelInstance) + { + m_referenceViewModelInstance->addParent(m_parentViewModelInstance); + } + propertyValueChanged(); }; rcp referenceViewModelInstance() { return m_referenceViewModelInstance; } + void parentViewModelInstance(ViewModelInstance* parent) + { + m_parentViewModelInstance = parent; + } + ViewModelInstance* parentViewModelInstance() + { + return m_parentViewModelInstance; + } void setRoot(rcp value) override; void advanced() override; + void updateViewModel(ViewModelInstance*) override; + void applyValue(DataValueViewModel*); + StatusCode import(ImportStack& importStack) override; + Core* clone() const override; +#ifdef WITH_RIVE_TOOLS + void onChanged(ViewModelViewModelChanged callback) + { + m_changedCallback = callback; + } + ViewModelViewModelChanged m_changedCallback = nullptr; +#endif + +protected: + void propertyValueChanged() override; }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_property.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_property.hpp index 9c60f2b4c..4c5a1ca6e 100644 --- a/thirdparty/rive/include/rive/viewmodel/viewmodel_property.hpp +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_property.hpp @@ -7,8 +7,34 @@ namespace rive class ViewModelProperty : public ViewModelPropertyBase { public: + enum class Direction : uint8_t + { + none = 0, + input = 1, + output = 2, + both = 3, + }; + StatusCode import(ImportStack& importStack) override; inline const std::string& constName() const { return m_Name; } + + /// Direction is stored in bits 0–1 of componentProps. + Direction direction() const + { + return static_cast(componentProps() & 0x3); + } + + bool isInput() const + { + auto d = direction(); + return d == Direction::input || d == Direction::both; + } + + bool isOutput() const + { + auto d = direction(); + return d == Direction::output || d == Direction::both; + } }; } // namespace rive diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_property_artboard.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_property_artboard.hpp new file mode 100644 index 000000000..7be98c74d --- /dev/null +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_property_artboard.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_ARTBOARD_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_ARTBOARD_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_artboard_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyArtboard : public ViewModelPropertyArtboardBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/viewmodel/viewmodel_value_dependent.hpp b/thirdparty/rive/include/rive/viewmodel/viewmodel_value_dependent.hpp new file mode 100644 index 000000000..c65fb615f --- /dev/null +++ b/thirdparty/rive/include/rive/viewmodel/viewmodel_value_dependent.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_VIEWMODEL_VALUE_DEPENDENT_HPP_ +#define _RIVE_VIEWMODEL_VALUE_DEPENDENT_HPP_ +#include "rive/dirtyable.hpp" +#include +namespace rive +{ +class CoreObjectListener; +class ViewModelValueDependent : public Dirtyable +{ +public: + virtual void relinkDataBind() = 0; +}; + +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/rive/virtualizing_component.hpp b/thirdparty/rive/include/rive/virtualizing_component.hpp new file mode 100644 index 000000000..70b57cb3e --- /dev/null +++ b/thirdparty/rive/include/rive/virtualizing_component.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIRTUALIZING_COMPONENT_HPP_ +#define _RIVE_VIRTUALIZING_COMPONENT_HPP_ +#include "rive/math/vec2d.hpp" +#include +namespace rive +{ + +enum class VirtualizedDirection +{ + horizontal, + vertical +}; + +class Virtualizable +{ +public: + virtual Component* virtualizableComponent() = 0; +}; + +class VirtualizingComponent +{ +public: + static VirtualizingComponent* from(Component* component); + virtual bool virtualizationEnabled() = 0; + virtual int itemCount() = 0; + virtual Virtualizable* item(int index) = 0; + virtual Vec2D size() = 0; + virtual Vec2D itemSize(int index) = 0; + virtual void setItemSize(Vec2D size, int index) = 0; + virtual void addVirtualizable(int index) = 0; + virtual void removeVirtualizable(int index) = 0; + virtual void setVisibleIndices(int start, int end) = 0; + virtual void setVirtualizablePosition(int index, Vec2D position) = 0; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/thirdparty/rive/include/utils/compile_time_string_hash.hpp b/thirdparty/rive/include/utils/compile_time_string_hash.hpp index e0203a09a..2b43076f9 100644 --- a/thirdparty/rive/include/utils/compile_time_string_hash.hpp +++ b/thirdparty/rive/include/utils/compile_time_string_hash.hpp @@ -50,26 +50,26 @@ static constexpr unsigned int crc_table[256] = { 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; -template +template constexpr uint32_t combine_crc32(const char* str, uint32_t part) { return (part >> 8) ^ crc_table[(part ^ str[IDX]) & 0x000000FF]; } -template constexpr uint32_t crc32(const char* str) +template constexpr uint32_t crc32(const char* str) { return combine_crc32(str, crc32(str)); } // This is the stop-recursion function -template <> constexpr uint32_t crc32(const char* str) +template <> constexpr uint32_t crc32(const char* str) { return 0xFFFFFFFF; } } // namespace detail -template constexpr uint32_t ctcrc32(const char (&str)[LEN]) +template constexpr uint32_t ctcrc32(const char (&str)[LEN]) { // LEN-1 is to remove the null terminator at the end of the string const. return detail::crc32(str) ^ 0xFFFFFFFF; diff --git a/thirdparty/rive/include/utils/no_op_renderer.hpp b/thirdparty/rive/include/utils/no_op_renderer.hpp index 9c39b1fec..9dd535d47 100644 --- a/thirdparty/rive/include/utils/no_op_renderer.hpp +++ b/thirdparty/rive/include/utils/no_op_renderer.hpp @@ -30,6 +30,7 @@ class NoOpRenderer : public Renderer BlendMode, float) override {} + void modulateOpacity(float) override {} }; } // namespace rive diff --git a/thirdparty/rive/rive.cpp b/thirdparty/rive/rive.cpp index 3d95828ad..e7b27615f 100644 --- a/thirdparty/rive/rive.cpp +++ b/thirdparty/rive/rive.cpp @@ -37,6 +37,12 @@ #define _RIVE_INTERNAL_ 1 #endif +#if !defined(YG_DEPRECATED) + #define YUP_RIVE_DEFINED_YG_DEPRECATED 1 + #define YG_DEPRECATED(message) +#endif + +// BEGIN YUP GENERATED RIVE INCLUDES #include "source/generated/nested_artboard_layout_base.cpp" #include "source/generated/viewmodel/viewmodel_instance_list_base.cpp" #include "source/generated/viewmodel/viewmodel_instance_enum_base.cpp" @@ -293,16 +299,72 @@ #include "source/core/field_types/core_double_type.cpp" #include "source/core/field_types/core_string_type.cpp" #include "source/core/field_types/core_color_type.cpp" +#define is_big_endian yup_rive_binary_data_reader_is_big_endian +#define decode_uint_leb yup_rive_binary_data_reader_decode_uint_leb +#define decode_uint_leb32 yup_rive_binary_data_reader_decode_uint_leb32 +#define decode_string yup_rive_binary_data_reader_decode_string +#define decode_double yup_rive_binary_data_reader_decode_double +#define decode_float yup_rive_binary_data_reader_decode_float +#define decode_uint_8 yup_rive_binary_data_reader_decode_uint_8 +#define decode_uint_16 yup_rive_binary_data_reader_decode_uint_16 +#define decode_uint_32 yup_rive_binary_data_reader_decode_uint_32 #include "source/core/binary_data_reader.cpp" +#undef is_big_endian +#undef decode_uint_leb +#undef decode_uint_leb32 +#undef decode_string +#undef decode_double +#undef decode_float +#undef decode_uint_8 +#undef decode_uint_16 +#undef decode_uint_32 +#define is_big_endian yup_rive_binary_reader_is_big_endian +#define decode_uint_leb yup_rive_binary_reader_decode_uint_leb +#define decode_uint_leb32 yup_rive_binary_reader_decode_uint_leb32 +#define decode_string yup_rive_binary_reader_decode_string +#define decode_double yup_rive_binary_reader_decode_double +#define decode_float yup_rive_binary_reader_decode_float +#define decode_uint_8 yup_rive_binary_reader_decode_uint_8 +#define decode_uint_16 yup_rive_binary_reader_decode_uint_16 +#define decode_uint_32 yup_rive_binary_reader_decode_uint_32 #include "source/core/binary_reader.cpp" +#undef is_big_endian +#undef decode_uint_leb +#undef decode_uint_leb32 +#undef decode_string +#undef decode_double +#undef decode_float +#undef decode_uint_8 +#undef decode_uint_16 +#undef decode_uint_32 +#define is_big_endian yup_rive_binary_writer_is_big_endian +#define decode_uint_leb yup_rive_binary_writer_decode_uint_leb +#define decode_uint_leb32 yup_rive_binary_writer_decode_uint_leb32 +#define decode_string yup_rive_binary_writer_decode_string +#define decode_double yup_rive_binary_writer_decode_double +#define decode_float yup_rive_binary_writer_decode_float +#define decode_uint_8 yup_rive_binary_writer_decode_uint_8 +#define decode_uint_16 yup_rive_binary_writer_decode_uint_16 +#define decode_uint_32 yup_rive_binary_writer_decode_uint_32 #include "source/core/binary_writer.cpp" +#undef is_big_endian +#undef decode_uint_leb +#undef decode_uint_leb32 +#undef decode_string +#undef decode_double +#undef decode_float +#undef decode_uint_8 +#undef decode_uint_16 +#undef decode_uint_32 #include "source/scene.cpp" #include "source/simple_array.cpp" #include "source/nested_artboard.cpp" #include "source/constraints/transform_constraint.cpp" #include "source/constraints/distance_constraint.cpp" #include "source/constraints/follow_path_constraint.cpp" +#define identity yup_rive_constraint_identity #include "source/constraints/constraint.cpp" +#undef identity #include "source/constraints/rotation_constraint.cpp" #include "source/constraints/ik_constraint.cpp" #include "source/constraints/scale_constraint.cpp" @@ -354,9 +416,10 @@ #include "source/layout.cpp" #include "source/layout_component.cpp" #include "source/animation/blend_state_1d_input.cpp" -#include "source/animation/transition_value_string_comparator.cpp" #include "source/animation/cubic_interpolator_solver.cpp" +#define StateMachineInstance YUPRiveNestedTriggerStateMachineInstance #include "source/animation/nested_trigger.cpp" +#undef StateMachineInstance #include "source/animation/keyframe_color.cpp" #include "source/animation/blend_state_1d_viewmodel.cpp" #include "source/animation/keyframe_callback.cpp" @@ -365,7 +428,9 @@ #include "source/animation/state_machine_instance.cpp" #include "source/animation/keyframe_interpolator.cpp" #include "source/animation/transition_input_condition.cpp" +#define StateMachineInstance YUPRiveNestedBoolStateMachineInstance #include "source/animation/nested_bool.cpp" +#undef StateMachineInstance #include "source/animation/blend_state_direct.cpp" #include "source/animation/animation_state.cpp" #include "source/animation/nested_animation.cpp" @@ -393,13 +458,13 @@ #include "source/animation/linear_animation_instance.cpp" #include "source/animation/keyframe_double.cpp" #include "source/animation/listener_input_change.cpp" -#include "source/animation/hittable.cpp" #include "source/animation/blend_animation_direct.cpp" #include "source/animation/transition_property_comparator.cpp" #include "source/animation/cubic_ease_interpolator.cpp" #include "source/animation/blend_state_transition.cpp" +#define StateMachineInstance YUPRiveNestedNumberStateMachineInstance #include "source/animation/nested_number.cpp" -#include "source/animation/transition_property_artboard_comparator.cpp" +#undef StateMachineInstance #include "source/animation/transition_number_condition.cpp" #include "source/animation/listener_bool_change.cpp" #include "source/animation/keyframe.cpp" @@ -409,14 +474,11 @@ #include "source/animation/state_machine_layer.cpp" #include "source/animation/listener_align_target.cpp" #include "source/animation/blend_animation_1d.cpp" -#include "source/animation/transition_value_enum_comparator.cpp" #include "source/animation/blend_state_1d.cpp" #include "source/animation/cubic_value_interpolator.cpp" #include "source/animation/cubic_interpolator_component.cpp" #include "source/animation/state_instance.cpp" -#include "source/animation/transition_value_color_comparator.cpp" #include "source/animation/listener_trigger_change.cpp" -#include "source/animation/transition_value_boolean_comparator.cpp" #include "source/animation/cubic_interpolator.cpp" #include "source/animation/keyed_property.cpp" #include "source/animation/transition_bool_condition.cpp" @@ -424,7 +486,6 @@ #include "source/animation/animation_reset.cpp" #include "source/animation/nested_remap_animation.cpp" #include "source/animation/layer_state.cpp" -#include "source/animation/transition_value_number_comparator.cpp" #include "source/animation/system_state_instance.cpp" #include "source/animation/state_transition.cpp" #include "source/animation/listener_viewmodel_change.cpp" @@ -469,15 +530,25 @@ #include "source/shapes/cubic_mirrored_vertex.cpp" #include "source/shapes/vertex.cpp" #include "source/shapes/ellipse.cpp" +#define identity yup_rive_clipping_shape_identity #include "source/shapes/clipping_shape.cpp" +#undef identity #include "source/math/contour_measure.cpp" #include "source/math/raw_path.cpp" #include "source/math/bezier_utils.cpp" #include "source/math/bit_field_loc.cpp" +#include "rive/math/hit_test.hpp" +#include "rive/math/mat2d.hpp" +#define graphics_roundf yup_rive_hit_test_graphics_roundf +#define graphics_round yup_rive_hit_test_graphics_round +#define lerp yup_rive_hit_test_lerp +#include "source/math/hit_test.cpp" +#undef graphics_roundf +#undef graphics_round +#undef lerp #include "source/math/aabb.cpp" #include "source/math/mat2d_find_max_scale.cpp" #include "source/math/path_measure.cpp" -#include "source/math/hit_test.cpp" #include "source/math/raw_path_utils.cpp" #include "source/math/rectangles_to_contour.cpp" #include "source/math/vec2d.cpp" @@ -581,6 +652,187 @@ #include "source/renderer.cpp" #include "source/audio_event.cpp" #include "source/nested_artboard_leaf.cpp" +#include "source/animation/focus_action_target.cpp" +#include "source/animation/focus_action_traversal.cpp" +#include "source/animation/focus_listener_group.cpp" +#include "source/animation/keyboard_listener_group.cpp" +#include "source/animation/listener_invocation.cpp" +#include "source/animation/listener_types/listener_input_type.cpp" +#include "source/animation/listener_types/listener_input_type_keyboard.cpp" +#include "source/animation/listener_types/listener_input_type_semantic.cpp" +#include "source/animation/listener_types/listener_input_type_viewmodel.cpp" +#include "source/animation/property_recorder.cpp" +#include "source/animation/scripted_listener_action.cpp" +#include "source/animation/scripted_transition_condition.cpp" +#include "source/animation/semantic_listener_group.cpp" +#include "source/animation/state_machine_fire_action.cpp" +#include "source/animation/state_machine_fire_trigger.cpp" +#include "source/animation/state_machine_listener_single.cpp" +#include "source/animation/text_input_listener_group.cpp" +#include "source/artboard_list_map_rule.cpp" +#include "source/artboard_referencer.cpp" +#include "source/assets/blob_asset.cpp" +#include "source/assets/manifest_asset.cpp" +#include "source/assets/script_asset.cpp" +#include "source/assets/shader_asset.cpp" +#include "source/async/work_pool.cpp" +#include "source/bindable_artboard.cpp" +#include "source/constraints/constrainable_list.cpp" +#include "source/constraints/draggable_constraint.cpp" +#include "source/constraints/list_constraint.cpp" +#include "source/constraints/list_follow_path_constraint.cpp" +#include "source/constraints/scrolling/scroll_virtualizer.cpp" +#include "source/custom_property_container.cpp" +#include "source/data_bind/context/context_target_value.cpp" +#include "source/data_bind/context/context_value_any.cpp" +#include "source/data_bind/context/context_value_artboard.cpp" +#include "source/data_bind/context/context_value_viewmodel.cpp" +#include "source/data_bind/converters/data_converter_list_to_length.cpp" +#include "source/data_bind/converters/data_converter_to_number.cpp" +#include "source/data_bind/data_bind_container.cpp" +#include "source/data_bind/data_bind_path.cpp" +#include "source/data_bind/data_bind_viewmodel_consumer.cpp" +#include "source/data_bind_path_referencer.cpp" +#include "source/focus_data.cpp" +#include "source/generated/animation/focus_action_base.cpp" +#include "source/generated/animation/focus_action_target_base.cpp" +#include "source/generated/animation/focus_action_traversal_base.cpp" +#include "source/generated/animation/listener_types/listener_input_type_base.cpp" +#include "source/generated/animation/listener_types/listener_input_type_event_base.cpp" +#include "source/generated/animation/listener_types/listener_input_type_keyboard_base.cpp" +#include "source/generated/animation/listener_types/listener_input_type_semantic_base.cpp" +#include "source/generated/animation/listener_types/listener_input_type_text_base.cpp" +#include "source/generated/animation/listener_types/listener_input_type_viewmodel_base.cpp" +#include "source/generated/animation/scripted_listener_action_base.cpp" +#include "source/generated/animation/scripted_transition_condition_base.cpp" +#include "source/generated/animation/state_machine_fire_action_base.cpp" +#include "source/generated/animation/state_machine_fire_trigger_base.cpp" +#include "source/generated/animation/state_machine_listener_single_base.cpp" +#include "source/generated/animation/transition_property_component_comparator_base.cpp" +#include "source/generated/animation/transition_self_comparator_base.cpp" +#include "source/generated/animation/transition_value_artboard_comparator_base.cpp" +#include "source/generated/animation/transition_value_asset_comparator_base.cpp" +#include "source/generated/animation/transition_value_id_comparator_base.cpp" +#include "source/generated/artboard_list_map_rule_base.cpp" +#include "source/generated/assets/blob_asset_base.cpp" +#include "source/generated/assets/manifest_asset_base.cpp" +#include "source/generated/assets/script_asset_base.cpp" +#include "source/generated/assets/shader_asset_base.cpp" +#include "source/generated/constraints/list_follow_path_constraint_base.cpp" +#include "source/generated/custom_property_color_base.cpp" +#include "source/generated/custom_property_enum_base.cpp" +#include "source/generated/custom_property_trigger_base.cpp" +#include "source/generated/data_bind/bindable_property_artboard_base.cpp" +#include "source/generated/data_bind/bindable_property_list_base.cpp" +#include "source/generated/data_bind/bindable_property_viewmodel_base.cpp" +#include "source/generated/data_bind/converters/data_converter_list_to_length_base.cpp" +#include "source/generated/data_bind/converters/data_converter_to_number_base.cpp" +#include "source/generated/data_bind/data_bind_path_base.cpp" +#include "source/generated/focus_data_base.cpp" +#include "source/generated/inputs/keyboard_input_base.cpp" +#include "source/generated/inputs/semantic_input_base.cpp" +#include "source/generated/inputs/user_input_base.cpp" +#include "source/generated/layout/artboard_component_list_override_base.cpp" +#include "source/generated/script_input_artboard_base.cpp" +#include "source/generated/script_input_boolean_base.cpp" +#include "source/generated/script_input_color_base.cpp" +#include "source/generated/script_input_number_base.cpp" +#include "source/generated/script_input_string_base.cpp" +#include "source/generated/script_input_trigger_base.cpp" +#include "source/generated/script_input_viewmodel_property_base.cpp" +#include "source/generated/scripted/scripted_data_converter_base.cpp" +#include "source/generated/scripted/scripted_drawable_base.cpp" +#include "source/generated/scripted/scripted_layout_base.cpp" +#include "source/generated/scripted/scripted_path_effect_base.cpp" +#include "source/generated/semantic/semantic_data_base.cpp" +#include "source/generated/shapes/list_path_base.cpp" +#include "source/generated/shapes/paint/group_effect_base.cpp" +#include "source/generated/shapes/paint/target_effect_base.cpp" +#include "source/generated/viewmodel/viewmodel_instance_artboard_base.cpp" +#include "source/generated/viewmodel/viewmodel_instance_value_base.cpp" +#include "source/generated/viewmodel/viewmodel_property_artboard_base.cpp" +#include "source/importers/data_bind_path_importer.cpp" +#include "source/importers/listener_input_type_keyboard_importer.cpp" +#include "source/importers/listener_input_type_semantic_importer.cpp" +#include "source/importers/scripted_object_importer.cpp" +#include "source/importers/text_asset_importer.cpp" +#include "source/input/focus_manager.cpp" +#include "source/input/focus_node.cpp" +#include "source/input/focusable.cpp" +#include "source/inputs/keyboard_input.cpp" +#include "source/inputs/semantic_input.cpp" +#include "source/layout/artboard_component_list_override.cpp" +#include "source/listener_group.cpp" +#include "source/lua/lua_artboards.cpp" +#include "source/lua/lua_audio.cpp" +#include "source/lua/lua_buffer_ext.cpp" +#define data_value_namecall yup_rive_lua_data_context_namecall +#include "source/lua/lua_data_context.cpp" +#undef data_value_namecall +#define data_value_namecall yup_rive_lua_data_value_namecall +#include "source/lua/lua_data_value.cpp" +#undef data_value_namecall +#include "source/lua/lua_image_decode.cpp" +#include "source/lua/lua_listener_invocation.cpp" +#include "source/lua/lua_promise.cpp" +#include "source/lua/lua_properties.cpp" +#include "source/lua/lua_rive_base.cpp" +#include "source/lua/lua_scripted_context.cpp" +#include "source/lua/lua_state.cpp" +#include "source/lua/math/lua_color.cpp" +#include "source/lua/math/lua_input.cpp" +#include "source/lua/math/lua_mat2d.cpp" +#include "source/lua/math/lua_mat4.cpp" +#include "source/lua/math/lua_math.cpp" +#include "source/lua/math/lua_vec2d.cpp" +#include "source/lua/renderer/lua_blob.cpp" +#include "source/lua/renderer/lua_gpu.cpp" +#include "source/lua/renderer/lua_gradient.cpp" +#include "source/lua/renderer/lua_image.cpp" +#include "source/lua/renderer/lua_mesh.cpp" +#include "source/lua/renderer/lua_paint.cpp" +#include "source/lua/renderer/lua_path.cpp" +#include "source/lua/renderer/lua_renderer.cpp" +#include "source/lua/renderer/lua_renderer_library.cpp" +#include "source/lua/rive_lua_libs.cpp" +#include "source/math/random.cpp" +#include "source/parent_traversal.cpp" +#include "source/profiler/profiler.cpp" +#include "source/profiler/rive_profile.cpp" +#include "source/resetting_component.cpp" +#include "source/script_input_artboard.cpp" +#include "source/script_input_boolean.cpp" +#include "source/script_input_color.cpp" +#include "source/script_input_number.cpp" +#include "source/script_input_string.cpp" +#include "source/script_input_trigger.cpp" +#include "source/script_input_viewmodel_property.cpp" +#include "source/scripted/scripted_data_converter.cpp" +#include "source/scripted/scripted_drawable.cpp" +#include "source/scripted/scripted_layout.cpp" +#include "source/scripted/scripted_object.cpp" +#include "source/scripted/scripted_path_effect.cpp" +#include "source/semantic/semantic_data.cpp" +#include "source/semantic/semantic_inference_registry.cpp" +#include "source/semantic/semantic_manager.cpp" +#include "source/semantic/semantic_provider.cpp" +#include "source/shapes/list_path.cpp" +#include "source/shapes/paint/effects_container.cpp" +#include "source/shapes/paint/group_effect.cpp" +#include "source/shapes/paint/stroke_effect.cpp" +#include "source/shapes/paint/target_effect.cpp" +#include "source/shapes/points_common_path.cpp" +#include "source/texture_archive.cpp" +#include "source/viewmodel/property_symbol_dependent.cpp" +#include "source/viewmodel/runtime/viewmodel_instance_artboard_runtime.cpp" +#include "source/viewmodel/viewmodel_instance_artboard.cpp" +#include "source/virtualizing_component.cpp" +// END YUP GENERATED RIVE INCLUDES + +#if defined(YUP_RIVE_DEFINED_YG_DEPRECATED) + #undef YG_DEPRECATED + #undef YUP_RIVE_DEFINED_YG_DEPRECATED +#endif #if __clang__ #pragma clang diagnostic pop diff --git a/thirdparty/rive/rive.h b/thirdparty/rive/rive.h index d0d6d28c3..6d83befe7 100644 --- a/thirdparty/rive/rive.h +++ b/thirdparty/rive/rive.h @@ -26,14 +26,14 @@ ID: rive vendor: rive - version: 1.0 + version: 0.1.62 name: Rive C++ is a runtime library for Rive. description: Rive C++ is a runtime library for Rive, a real-time interactive design and animation tool. website: https://github.com/rive-app/rive-runtime license: MIT - dependencies: harfbuzz sheenbidi_library yoga_library - defines: WITH_RIVE_TEXT=1 WITH_RIVE_YOGA=1 WITH_RIVE_LAYOUT=1 + dependencies: harfbuzz sheenbidi_library yoga_library luau libhydrogen + defines: WITH_RIVE_TEXT=1 WITH_RIVE_YOGA=1 WITH_RIVE_LAYOUT=1 WITH_RIVE_SCRIPTING=1 appleFrameworks: CoreText searchpaths: include diff --git a/thirdparty/rive/source/advancing_component.cpp b/thirdparty/rive/source/advancing_component.cpp index c3640152b..317112142 100644 --- a/thirdparty/rive/source/advancing_component.cpp +++ b/thirdparty/rive/source/advancing_component.cpp @@ -6,10 +6,15 @@ #include "rive/nested_artboard.hpp" #include "rive/nested_artboard_layout.hpp" #include "rive/nested_artboard_leaf.hpp" +#include "rive/scripted/scripted_data_converter.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/scripted/scripted_layout.hpp" +#include "rive/scripted/scripted_path_effect.hpp" +#include "rive/text/text_input.hpp" using namespace rive; -AdvancingComponent* AdvancingComponent::from(Component* component) +AdvancingComponent* AdvancingComponent::from(Core* component) { switch (component->coreType()) { @@ -25,6 +30,16 @@ AdvancingComponent* AdvancingComponent::from(Component* component) return component->as(); case ScrollConstraint::typeKey: return component->as(); + case TextInputBase::typeKey: + return component->as(); + case ScriptedDataConverter::typeKey: + return component->as(); + case ScriptedDrawable::typeKey: + return component->as(); + case ScriptedLayout::typeKey: + return component->as(); + case ScriptedPathEffect::typeKey: + return component->as(); } return nullptr; } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/animation_reset.cpp b/thirdparty/rive/source/animation/animation_reset.cpp index 60f9c7513..fac6c455b 100644 --- a/thirdparty/rive/source/animation/animation_reset.cpp +++ b/thirdparty/rive/source/animation/animation_reset.cpp @@ -32,11 +32,18 @@ void AnimationReset::clear() { m_binaryWriter.clear(); } void AnimationReset::complete() { - m_binaryReader.complete(&m_WriteBuffer.front(), m_binaryWriter.size()); + if (!m_WriteBuffer.empty()) + { + m_binaryReader.complete(&m_WriteBuffer.front(), m_binaryWriter.size()); + } } void AnimationReset::apply(Artboard* artboard) { + if (m_WriteBuffer.empty()) + { + return; + } m_binaryReader.reset(&m_WriteBuffer.front()); while (!m_binaryReader.isEOF()) { diff --git a/thirdparty/rive/source/animation/animation_reset_factory.cpp b/thirdparty/rive/source/animation/animation_reset_factory.cpp index ace9919f9..b9aaf59a0 100644 --- a/thirdparty/rive/source/animation/animation_reset_factory.cpp +++ b/thirdparty/rive/source/animation/animation_reset_factory.cpp @@ -67,7 +67,7 @@ class AnimationsData } auto keyedObjectData = - rivestd::make_unique(keyedObject->objectId()); + std::make_unique(keyedObject->objectId()); auto ref = keyedObjectData.get(); keyedObjectsData.push_back(std::move(keyedObjectData)); return ref; @@ -181,7 +181,7 @@ std::unique_ptr AnimationResetFactory::getInstance() m_resources.pop_back(); return instance; } - auto instance = rivestd::make_unique(); + auto instance = std::make_unique(); return instance; } diff --git a/thirdparty/rive/source/animation/animation_state.cpp b/thirdparty/rive/source/animation/animation_state.cpp index c037ca0cf..7e5da82a1 100644 --- a/thirdparty/rive/source/animation/animation_state.cpp +++ b/thirdparty/rive/source/animation/animation_state.cpp @@ -9,7 +9,7 @@ using namespace rive; std::unique_ptr AnimationState::makeInstance( ArtboardInstance* instance) const { - return rivestd::make_unique(this, instance); + return std::make_unique(this, instance); } #ifdef TESTING diff --git a/thirdparty/rive/source/animation/blend_animation_direct.cpp b/thirdparty/rive/source/animation/blend_animation_direct.cpp index 334fed8dd..acdabb2ea 100644 --- a/thirdparty/rive/source/animation/blend_animation_direct.cpp +++ b/thirdparty/rive/source/animation/blend_animation_direct.cpp @@ -7,6 +7,15 @@ using namespace rive; +BlendAnimationDirect::~BlendAnimationDirect() +{ + if (m_bindableProperty != nullptr) + { + delete m_bindableProperty; + m_bindableProperty = nullptr; + } +} + StatusCode BlendAnimationDirect::onAddedDirty(CoreContext* context) { return StatusCode::Ok; diff --git a/thirdparty/rive/source/animation/blend_state_1d.cpp b/thirdparty/rive/source/animation/blend_state_1d.cpp index ddfab5db5..7365b26f6 100644 --- a/thirdparty/rive/source/animation/blend_state_1d.cpp +++ b/thirdparty/rive/source/animation/blend_state_1d.cpp @@ -6,5 +6,5 @@ using namespace rive; std::unique_ptr BlendState1D::makeInstance( ArtboardInstance* instance) const { - return rivestd::make_unique(this, instance); + return std::make_unique(this, instance); } diff --git a/thirdparty/rive/source/animation/blend_state_direct.cpp b/thirdparty/rive/source/animation/blend_state_direct.cpp index 82db10b77..a3a635c72 100644 --- a/thirdparty/rive/source/animation/blend_state_direct.cpp +++ b/thirdparty/rive/source/animation/blend_state_direct.cpp @@ -8,5 +8,5 @@ using namespace rive; std::unique_ptr BlendStateDirect::makeInstance( ArtboardInstance* instance) const { - return rivestd::make_unique(this, instance); + return std::make_unique(this, instance); } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/blend_state_direct_instance.cpp b/thirdparty/rive/source/animation/blend_state_direct_instance.cpp index c7dad6320..9146acbff 100644 --- a/thirdparty/rive/source/animation/blend_state_direct_instance.cpp +++ b/thirdparty/rive/source/animation/blend_state_direct_instance.cpp @@ -35,6 +35,10 @@ void BlendStateDirectInstance::advance( { auto bindableProperty = animation.blendAnimation()->bindableProperty(); + if (bindableProperty == nullptr) + { + continue; + } auto bindableInstance = stateMachineInstance->bindablePropertyInstance( bindableProperty); diff --git a/thirdparty/rive/source/animation/focus_action_target.cpp b/thirdparty/rive/source/animation/focus_action_target.cpp new file mode 100644 index 000000000..06095758d --- /dev/null +++ b/thirdparty/rive/source/animation/focus_action_target.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Rive + */ + +#include "rive/animation/focus_action_target.hpp" +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/artboard.hpp" +#include "rive/focus_data.hpp" +#include "rive/node.hpp" + +using namespace rive; + +void FocusActionTarget::perform(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const +{ + (void)invocation; + auto target = stateMachineInstance->artboard()->resolve(targetId()); + if (target == nullptr || !target->is()) + { + return; + } + + auto node = target->as(); + FocusData* focusData = nullptr; + + // Find FocusData child of the node + for (auto child : node->children()) + { + if (child->is()) + { + focusData = child->as(); + break; + } + } + + if (focusData != nullptr) + { + stateMachineInstance->setFocus(focusData); + } +} diff --git a/thirdparty/rive/source/animation/focus_action_traversal.cpp b/thirdparty/rive/source/animation/focus_action_traversal.cpp new file mode 100644 index 000000000..800eaa03b --- /dev/null +++ b/thirdparty/rive/source/animation/focus_action_traversal.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2024 Rive + */ + +#include "rive/animation/focus_action_traversal.hpp" +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/input/focus_manager.hpp" + +using namespace rive; + +void FocusActionTraversal::perform(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const +{ + (void)invocation; + if (stateMachineInstance == nullptr) + { + return; + } + + FocusManager* manager = stateMachineInstance->focusManager(); + // traversalKind: 0=next, 1=previous, 2=up, 3=down, 4=left, 5=right + switch (traversalKind()) + { + case 0: + manager->focusNext(); + break; + case 1: + manager->focusPrevious(); + break; + case 2: + manager->focusUp(); + break; + case 3: + manager->focusDown(); + break; + case 4: + manager->focusLeft(); + break; + case 5: + manager->focusRight(); + break; + default: + manager->focusNext(); + break; + } +} diff --git a/thirdparty/rive/source/animation/focus_listener_group.cpp b/thirdparty/rive/source/animation/focus_listener_group.cpp new file mode 100644 index 000000000..a6ecfabb8 --- /dev/null +++ b/thirdparty/rive/source/animation/focus_listener_group.cpp @@ -0,0 +1,43 @@ +#include "rive/animation/focus_listener_group.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/state_machine_listener.hpp" +#include "rive/focus_data.hpp" + +using namespace rive; + +FocusListenerGroup::FocusListenerGroup( + FocusData* focusData, + const StateMachineListener* listener, + StateMachineInstance* stateMachineInstance) : + m_focusData(focusData), + m_listener(listener), + m_stateMachineInstance(stateMachineInstance), + m_isFocusListener(listener->hasListener(ListenerType::focus)), + m_isBlurListener(listener->hasListener(ListenerType::blur)) +{ + // Register ourselves as a listener on the FocusData + m_focusData->addFocusListener(this); +} + +FocusListenerGroup::~FocusListenerGroup() +{ + m_focusData->removeFocusListener(this); +} + +void FocusListenerGroup::onFocused() +{ + // Only queue if this is a focus listener + if (m_isFocusListener) + { + m_stateMachineInstance->queueFocusEvent(this, true); + } +} + +void FocusListenerGroup::onBlurred() +{ + // Only queue if this is a blur listener + if (m_isBlurListener) + { + m_stateMachineInstance->queueFocusEvent(this, false); + } +} diff --git a/thirdparty/rive/source/animation/hittable.cpp b/thirdparty/rive/source/animation/hittable.cpp deleted file mode 100644 index 9566586b5..000000000 --- a/thirdparty/rive/source/animation/hittable.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "rive/animation/hittable.hpp" -#include "rive/component.hpp" -#include "rive/shapes/shape.hpp" -#include "rive/text/text_value_run.hpp" - -using namespace rive; - -Hittable* Hittable::from(Component* component) -{ - switch (component->coreType()) - { - case Shape::typeKey: - return component->as(); - case TextValueRun::typeKey: - return component->as(); - } - return nullptr; -} diff --git a/thirdparty/rive/source/animation/keyboard_listener_group.cpp b/thirdparty/rive/source/animation/keyboard_listener_group.cpp new file mode 100644 index 000000000..caf14638b --- /dev/null +++ b/thirdparty/rive/source/animation/keyboard_listener_group.cpp @@ -0,0 +1,177 @@ +#include "rive/animation/keyboard_listener_group.hpp" +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/listener_types/listener_input_type_keyboard.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/state_machine_listener.hpp" +#include "rive/text/text_input.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/focus_data.hpp" + +using namespace rive; + +KeyboardListenerGroup::KeyboardListenerGroup( + FocusData* focusData, + const StateMachineListener* listener, + StateMachineInstance* stateMachineInstance) : + m_focusData(focusData), + m_listener(listener), + m_stateMachineInstance(stateMachineInstance) +{ + // Register ourselves as a listener on the FocusData + if (m_listener) + { + if (m_listener->hasListener(ListenerType::keyboard)) + { + m_focusData->addKeyboardListener(this); + } + if (m_listener->hasListener(ListenerType::textInput)) + { + m_focusData->addTextInputListener(this); + } + } + else + { + if (m_focusData && m_focusData->parent()) + { + auto parent = m_focusData->parent(); + if (parent->is()) + { + auto scriptedObject = ScriptedObject::from(parent); + if (scriptedObject->wantsKeyboardInput()) + { + + m_focusData->addKeyboardListener(this); + } + if (scriptedObject->wantsTextInput()) + { + + m_focusData->addTextInputListener(this); + } + } + } + } +} + +KeyboardListenerGroup::~KeyboardListenerGroup() +{ + if (m_listener) + { + + if (m_listener->hasListener(ListenerType::keyboard)) + { + m_focusData->removeKeyboardListener(this); + } + if (m_listener->hasListener(ListenerType::textInput)) + { + m_focusData->removeTextInputListener(this); + } + } + else + { + if (m_focusData && m_focusData->parent()) + { + auto parent = m_focusData->parent(); + if (parent->is()) + { + auto scriptedObject = ScriptedObject::from(parent); + if (scriptedObject->wantsKeyboardInput()) + { + + m_focusData->removeKeyboardListener(this); + } + if (scriptedObject->wantsTextInput()) + { + + m_focusData->removeTextInputListener(this); + } + } + } + } +} + +bool KeyboardListenerGroup::keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + // Special case for text inputs. + // TODO: @hernan consider moving it into a special internal TextInput + // listener action. + if (m_focusData && m_focusData->parent()) + { + + auto parent = m_focusData->parent(); + if (parent->is()) + { + return parent->as()->keyInput(key, + modifiers, + isPressed, + isRepeat); + } +#ifdef WITH_RIVE_SCRIPTING + else if (parent->is() && !listener()) + { + auto scriptedObject = ScriptedObject::from(parent); + if (scriptedObject->wantsKeyboardInput()) + { + + return parent->as()->keyInput(key, + modifiers, + isPressed, + isRepeat); + } + } +#endif + } + if (listener()) + { + if (!ListenerInputTypeKeyboard::keyboardListenerConstraintsMet( + listener(), + key, + modifiers, + isPressed, + isRepeat)) + { + return false; + } + listener()->performChanges( + m_stateMachineInstance, + ListenerInvocation::keyboard(key, modifiers, isPressed, isRepeat)); + // Always return false for now. In the future we will let listeners + // decide whether they stop event propagation + } + return false; +} + +bool KeyboardListenerGroup::textInput(const std::string& text) +{ + + // Special case for text inputs. + // TODO: @hernan consider moving it into a special internal TextInput + // listener action. + if (m_focusData && m_focusData->parent()) + { + + auto parent = m_focusData->parent(); + if (parent->is()) + { + return parent->as()->textInput(text); + } +#ifdef WITH_RIVE_SCRIPTING + else if (parent->is() && !listener()) + { + auto scriptedObject = ScriptedObject::from(parent); + if (scriptedObject->wantsTextInput()) + { + return parent->as()->textInput(text); + } + } +#endif + } + if (listener()) + { + listener()->performChanges(m_stateMachineInstance, + ListenerInvocation::textInput(text)); + } + return false; +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/layer_state.cpp b/thirdparty/rive/source/animation/layer_state.cpp index 2d6d034b4..9b2aa36fe 100644 --- a/thirdparty/rive/source/animation/layer_state.cpp +++ b/thirdparty/rive/source/animation/layer_state.cpp @@ -62,5 +62,5 @@ void LayerState::addTransition(StateTransition* transition) std::unique_ptr LayerState::makeInstance( ArtboardInstance* instance) const { - return rivestd::make_unique(this, instance); + return std::make_unique(this, instance); } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/linear_animation.cpp b/thirdparty/rive/source/animation/linear_animation.cpp index 25dd73bea..2af357605 100644 --- a/thirdparty/rive/source/animation/linear_animation.cpp +++ b/thirdparty/rive/source/animation/linear_animation.cpp @@ -24,15 +24,30 @@ LinearAnimation::~LinearAnimation() StatusCode LinearAnimation::onAddedDirty(CoreContext* context) { - StatusCode code; - for (const auto& object : m_KeyedObjects) + StatusCode status = StatusCode::Ok; + std::vector failedKeyedObjects; + for (size_t i = 0; i < m_KeyedObjects.size(); ++i) { - if ((code = object->onAddedDirty(context)) != StatusCode::Ok) + StatusCode code = m_KeyedObjects[i]->onAddedDirty(context); + if (code != StatusCode::Ok) { - return code; + failedKeyedObjects.push_back(i); + if (status == StatusCode::Ok || status == StatusCode::MissingObject) + { + status = code; + } } } - return StatusCode::Ok; + + // Failed keyed objects should not be applied later in animation playback. + for (auto it = failedKeyedObjects.rbegin(); it != failedKeyedObjects.rend(); + ++it) + { + m_KeyedObjects.erase(m_KeyedObjects.begin() + *it); + } + + // Missing keyed objects are non-fatal at artboard init time. + return status == StatusCode::MissingObject ? StatusCode::Ok : status; } StatusCode LinearAnimation::onAddedClean(CoreContext* context) diff --git a/thirdparty/rive/source/animation/linear_animation_instance.cpp b/thirdparty/rive/source/animation/linear_animation_instance.cpp index f7887ba61..0bcb8f42d 100644 --- a/thirdparty/rive/source/animation/linear_animation_instance.cpp +++ b/thirdparty/rive/source/animation/linear_animation_instance.cpp @@ -2,6 +2,8 @@ #include "rive/animation/linear_animation.hpp" #include "rive/animation/loop.hpp" #include "rive/animation/keyed_callback_reporter.hpp" +#include "rive/profiler/profiler_macros.h" + #include #include @@ -40,6 +42,7 @@ LinearAnimationInstance::~LinearAnimationInstance() {} bool LinearAnimationInstance::advanceAndApply(float seconds) { + RIVE_PROF_SCOPE_L(1) bool more = this->advance(seconds, this); this->apply(); if (m_artboardInstance->advance(seconds)) diff --git a/thirdparty/rive/source/animation/listener_action.cpp b/thirdparty/rive/source/animation/listener_action.cpp index 0b1f34f15..50939dc09 100644 --- a/thirdparty/rive/source/animation/listener_action.cpp +++ b/thirdparty/rive/source/animation/listener_action.cpp @@ -1,23 +1,46 @@ +#include "rive/animation/listener_action.hpp" #include "rive/animation/state_machine_listener.hpp" #include "rive/importers/import_stack.hpp" +#include "rive/importers/state_machine_layer_component_importer.hpp" #include "rive/importers/state_machine_listener_importer.hpp" #include "rive/importers/state_machine_importer.hpp" #include "rive/animation/listener_input_change.hpp" #include "rive/animation/state_machine.hpp" +#include "rive/generated/animation/state_machine_layer_component_base.hpp" +#include "rive/generated/animation/state_machine_listener_base.hpp" using namespace rive; StatusCode ListenerAction::import(ImportStack& importStack) { - auto stateMachineListenerImporter = - importStack.latest( - StateMachineListenerBase::typeKey); - if (stateMachineListenerImporter == nullptr) + switch (parentKind()) { - return StatusCode::MissingObject; + case ParentKind::Listener: + { + auto listenerImporter = + importStack.latest( + StateMachineListenerBase::typeKey); + if (listenerImporter == nullptr) + { + return StatusCode::MissingObject; + } + listenerImporter->addAction(std::unique_ptr(this)); + return Super::import(importStack); + } + case ParentKind::Transition: + case ParentKind::State: + { + auto layerImporter = + importStack.latest( + StateMachineLayerComponentBase::typeKey); + if (layerImporter == nullptr) + { + return StatusCode::MissingObject; + } + layerImporter->addListenerAction( + std::unique_ptr(this)); + return Super::import(importStack); + } } - - stateMachineListenerImporter->addAction( - std::unique_ptr(this)); - return Super::import(importStack); + return StatusCode::MissingObject; } diff --git a/thirdparty/rive/source/animation/listener_align_target.cpp b/thirdparty/rive/source/animation/listener_align_target.cpp index 415321e61..a7a40d627 100644 --- a/thirdparty/rive/source/animation/listener_align_target.cpp +++ b/thirdparty/rive/source/animation/listener_align_target.cpp @@ -1,4 +1,5 @@ #include "rive/animation/listener_align_target.hpp" +#include "rive/animation/listener_invocation.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/node.hpp" #include "rive/constraints/constraint.hpp" @@ -6,9 +7,20 @@ using namespace rive; void ListenerAlignTarget::perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { + Vec2D position; + Vec2D previousPosition; + if (const PointerInvocation* p = invocation.asPointer()) + { + position = p->position; + previousPosition = p->previousPosition; + } + else + { + position = Vec2D(0, 0); + previousPosition = Vec2D(0, 0); + } auto coreTarget = stateMachineInstance->artboard()->resolve(targetId()); if (coreTarget == nullptr || !coreTarget->is()) { diff --git a/thirdparty/rive/source/animation/listener_bool_change.cpp b/thirdparty/rive/source/animation/listener_bool_change.cpp index 20bdf0eac..ebba34906 100644 --- a/thirdparty/rive/source/animation/listener_bool_change.cpp +++ b/thirdparty/rive/source/animation/listener_bool_change.cpp @@ -25,9 +25,9 @@ bool ListenerBoolChange::validateNestedInputType(const NestedInput* input) const } void ListenerBoolChange::perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { + (void)invocation; if (nestedInputId() != Core::emptyId) { auto nestedInputInstance = diff --git a/thirdparty/rive/source/animation/listener_fire_event.cpp b/thirdparty/rive/source/animation/listener_fire_event.cpp index bd6d07449..caa096a7a 100644 --- a/thirdparty/rive/source/animation/listener_fire_event.cpp +++ b/thirdparty/rive/source/animation/listener_fire_event.cpp @@ -1,13 +1,14 @@ #include "rive/animation/listener_fire_event.hpp" +#include "rive/animation/listener_invocation.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/event.hpp" using namespace rive; void ListenerFireEvent::perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { + (void)invocation; auto coreEvent = stateMachineInstance->artboard()->resolve(eventId()); if (coreEvent == nullptr || !coreEvent->is()) { diff --git a/thirdparty/rive/source/animation/listener_invocation.cpp b/thirdparty/rive/source/animation/listener_invocation.cpp new file mode 100644 index 000000000..c9012f5fd --- /dev/null +++ b/thirdparty/rive/source/animation/listener_invocation.cpp @@ -0,0 +1,92 @@ +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/semantic_listener_group.hpp" + +#include +#include + +using namespace rive; + +ListenerInvocation ListenerInvocation::pointer(Vec2D position, + Vec2D previousPosition, + int pointerId, + ListenerType hitEvent, + float timeStamp) +{ + PointerInvocation p; + p.position = position; + p.previousPosition = previousPosition; + p.pointerId = pointerId; + p.hitEvent = hitEvent; + p.timeStamp = timeStamp; + return ListenerInvocation(ListenerInvocationStorage(std::move(p))); +} + +ListenerInvocation ListenerInvocation::keyboard(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + KeyboardInvocation k; + k.key = key; + k.modifiers = modifiers; + k.isPressed = isPressed; + k.isRepeat = isRepeat; + return ListenerInvocation(ListenerInvocationStorage(std::move(k))); +} + +ListenerInvocation ListenerInvocation::textInput(std::string text) +{ + return ListenerInvocation( + ListenerInvocationStorage(TextInputInvocation{std::move(text)})); +} + +ListenerInvocation ListenerInvocation::focus(FocusListenerGroup* group, + bool isFocus) +{ + FocusInvocation f; + f.group = group; + f.isFocus = isFocus; + return ListenerInvocation(ListenerInvocationStorage(std::move(f))); +} + +ListenerInvocation ListenerInvocation::reportedEvent(Event* reportedEvent, + float delaySeconds) +{ + ReportedEventInvocation e; + e.reportedEvent = reportedEvent; + e.delaySeconds = delaySeconds; + return ListenerInvocation(ListenerInvocationStorage(std::move(e))); +} + +ListenerInvocation ListenerInvocation::viewModelChange( + ListenerViewModel* source) +{ + ViewModelChangeInvocation v; + v.source = source; + return ListenerInvocation(ListenerInvocationStorage(std::move(v))); +} + +ListenerInvocation ListenerInvocation::none() +{ + return ListenerInvocation(ListenerInvocationStorage(NoneInvocation{})); +} + +ListenerInvocation ListenerInvocation::gamepad(int deviceId, + uint64_t buttonMask, + float axis0) +{ + GamepadInvocation g; + g.deviceId = deviceId; + g.buttonMask = buttonMask; + g.axis0 = axis0; + return ListenerInvocation(ListenerInvocationStorage(std::move(g))); +} + +ListenerInvocation ListenerInvocation::semantic(SemanticListenerGroup* group, + SemanticActionType actionType) +{ + SemanticInvocation s; + s.group = group; + s.actionType = actionType; + return ListenerInvocation(ListenerInvocationStorage(std::move(s))); +} diff --git a/thirdparty/rive/source/animation/listener_number_change.cpp b/thirdparty/rive/source/animation/listener_number_change.cpp index a57d0dfa1..2724a9d17 100644 --- a/thirdparty/rive/source/animation/listener_number_change.cpp +++ b/thirdparty/rive/source/animation/listener_number_change.cpp @@ -28,9 +28,9 @@ bool ListenerNumberChange::validateNestedInputType( } void ListenerNumberChange::perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { + (void)invocation; if (nestedInputId() != Core::emptyId) { auto nestedInputInstance = diff --git a/thirdparty/rive/source/animation/listener_trigger_change.cpp b/thirdparty/rive/source/animation/listener_trigger_change.cpp index f8d85846f..c6c0e8bd9 100644 --- a/thirdparty/rive/source/animation/listener_trigger_change.cpp +++ b/thirdparty/rive/source/animation/listener_trigger_change.cpp @@ -29,9 +29,9 @@ bool ListenerTriggerChange::validateNestedInputType( } void ListenerTriggerChange::perform(StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { + (void)invocation; if (nestedInputId() != Core::emptyId) { auto nestedInputInstance = diff --git a/thirdparty/rive/source/animation/listener_types/listener_input_type.cpp b/thirdparty/rive/source/animation/listener_types/listener_input_type.cpp new file mode 100644 index 000000000..6513691e3 --- /dev/null +++ b/thirdparty/rive/source/animation/listener_types/listener_input_type.cpp @@ -0,0 +1,23 @@ +#include "rive/animation/state_machine_listener.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/state_machine_listener_importer.hpp" +#include "rive/importers/state_machine_importer.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" +#include "rive/animation/state_machine.hpp" + +using namespace rive; + +StatusCode ListenerInputType::import(ImportStack& importStack) +{ + auto stateMachineListenerImporter = + importStack.latest( + StateMachineListenerBase::typeKey); + if (stateMachineListenerImporter == nullptr) + { + return StatusCode::MissingObject; + } + + stateMachineListenerImporter->addListenerInputType( + std::unique_ptr(this)); + return Super::import(importStack); +} diff --git a/thirdparty/rive/source/animation/listener_types/listener_input_type_keyboard.cpp b/thirdparty/rive/source/animation/listener_types/listener_input_type_keyboard.cpp new file mode 100644 index 000000000..d9fe5ba73 --- /dev/null +++ b/thirdparty/rive/source/animation/listener_types/listener_input_type_keyboard.cpp @@ -0,0 +1,116 @@ +#include "rive/animation/listener_types/listener_input_type_keyboard.hpp" +#include "rive/animation/state_machine_listener.hpp" +#include "rive/inputs/keyboard_input.hpp" +#include "rive/rive_types.hpp" + +#include + +using namespace rive; + +const KeyboardInput* ListenerInputTypeKeyboard::keyboardInput( + size_t index) const +{ + if (index < m_keyboardInputs.size()) + { + return m_keyboardInputs[index]; + } + return nullptr; +} + +void ListenerInputTypeKeyboard::addKeyboardInput(KeyboardInput* input) +{ + if (input == nullptr) + { + return; + } + for (KeyboardInput* existing : m_keyboardInputs) + { + if (existing == input) + { + return; + } + } + m_keyboardInputs.push_back(input); +} + +bool ListenerInputTypeKeyboard::keyPhaseMatches(uint32_t keyPhase, + bool isPressed, + bool isRepeat) +{ + const uint32_t mask = keyPhase & KeyboardKeyPhaseMask::all; + if (mask == 0) + { + return false; + } + if (isPressed && isRepeat) + { + return (mask & KeyboardKeyPhaseMask::repeat) != 0; + } + if (isPressed) + { + return (mask & KeyboardKeyPhaseMask::down) != 0; + } + return (mask & KeyboardKeyPhaseMask::up) != 0; +} + +bool ListenerInputTypeKeyboard::keyboardInputMatches(const KeyboardInput& input, + Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + const uint32_t keyValue = static_cast(key); + if (input.keyType() != static_cast(-1) && + input.keyType() != keyValue) + { + return false; + } + if (input.modifiers() != static_cast(modifiers)) + { + return false; + } + return keyPhaseMatches(input.keyPhase(), isPressed, isRepeat); +} + +bool ListenerInputTypeKeyboard::keyboardListenerConstraintsMet( + const StateMachineListener* listener, + Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + if (listener == nullptr) + { + return false; + } + for (size_t i = 0; i < listener->listenerInputTypeCount(); ++i) + { + const ListenerInputType* lit = listener->listenerInputType(i); + if (lit == nullptr || !lit->is()) + { + continue; + } + const ListenerInputTypeKeyboard* litk = + lit->as(); + if (litk->keyboardInputCount() == 0) + { + return true; + } + bool anyMatches = false; + for (size_t j = 0; j < litk->keyboardInputCount(); ++j) + { + const KeyboardInput* ki = litk->keyboardInput(j); + if (ki != nullptr && + keyboardInputMatches(*ki, key, modifiers, isPressed, isRepeat)) + { + anyMatches = true; + break; + } + } + if (anyMatches) + { + return true; + } + } + return false; +} diff --git a/thirdparty/rive/source/animation/listener_types/listener_input_type_semantic.cpp b/thirdparty/rive/source/animation/listener_types/listener_input_type_semantic.cpp new file mode 100644 index 000000000..e61986afb --- /dev/null +++ b/thirdparty/rive/source/animation/listener_types/listener_input_type_semantic.cpp @@ -0,0 +1,71 @@ +#include "rive/animation/listener_types/listener_input_type_semantic.hpp" +#include "rive/animation/semantic_listener_group.hpp" +#include "rive/animation/state_machine_listener.hpp" +#include "rive/inputs/semantic_input.hpp" + +using namespace rive; + +const SemanticInput* ListenerInputTypeSemantic::semanticInput( + size_t index) const +{ + if (index < m_semanticInputs.size()) + { + return m_semanticInputs[index]; + } + return nullptr; +} + +void ListenerInputTypeSemantic::addSemanticInput(SemanticInput* input) +{ + if (input == nullptr) + { + return; + } + for (SemanticInput* existing : m_semanticInputs) + { + if (existing == input) + { + return; + } + } + m_semanticInputs.push_back(input); +} + +bool ListenerInputTypeSemantic::semanticListenerConstraintsMet( + const StateMachineListener* listener, + SemanticActionType action) +{ + if (listener == nullptr) + { + return false; + } + const uint32_t actionValue = static_cast(action); + for (size_t i = 0; i < listener->listenerInputTypeCount(); ++i) + { + const ListenerInputType* lit = listener->listenerInputType(i); + if (lit == nullptr) + { + continue; + } + if (lit->is()) + { + const ListenerInputTypeSemantic* sits = + lit->as(); + // No rows (or not yet deserialized): accept tap, increase, and + // decrease. + if (sits->semanticInputCount() == 0) + { + return true; + } + for (size_t j = 0; j < sits->semanticInputCount(); ++j) + { + const SemanticInput* si = sits->semanticInput(j); + if (si != nullptr && si->actionType() == actionValue) + { + return true; + } + } + } + } + return false; +} diff --git a/thirdparty/rive/source/animation/listener_types/listener_input_type_viewmodel.cpp b/thirdparty/rive/source/animation/listener_types/listener_input_type_viewmodel.cpp new file mode 100644 index 000000000..a08128178 --- /dev/null +++ b/thirdparty/rive/source/animation/listener_types/listener_input_type_viewmodel.cpp @@ -0,0 +1,20 @@ +#include "rive/animation/listener_types/listener_input_type_viewmodel.hpp" + +using namespace rive; + +void ListenerInputTypeViewModel::decodeViewModelPathIds( + Span value) +{ + decodeDataBindPath(value); +} + +void ListenerInputTypeViewModel::copyViewModelPathIds( + const ListenerInputTypeViewModelBase& object) +{ + copyDataBindPath(object.as()->dataBindPath()); +} + +std::vector ListenerInputTypeViewModel::viewModelPathIdsBuffer() const +{ + return dataBindPath()->path(); +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/listener_viewmodel_change.cpp b/thirdparty/rive/source/animation/listener_viewmodel_change.cpp index 2c63b00b5..703c4e210 100644 --- a/thirdparty/rive/source/animation/listener_viewmodel_change.cpp +++ b/thirdparty/rive/source/animation/listener_viewmodel_change.cpp @@ -1,7 +1,12 @@ #include "rive/animation/listener_viewmodel_change.hpp" +#include "rive/animation/listener_invocation.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/generated/core_registry.hpp" #include "rive/importers/bindable_property_importer.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" using namespace rive; @@ -36,9 +41,9 @@ StatusCode ListenerViewModelChange::import(ImportStack& importStack) // same bindable property with two data binding objects. void ListenerViewModelChange::perform( StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { + (void)invocation; // Get the bindable property instance from the state machine instance // context auto bindableInstance = @@ -47,7 +52,30 @@ void ListenerViewModelChange::perform( // bindable instance auto dataBind = stateMachineInstance->bindableDataBindToSource(bindableInstance); - // Apply the change that will assign the value of the bindable property to - // the view model property instance - dataBind->updateSourceBinding(true); + auto dataBindToTarget = + stateMachineInstance->bindableDataBindToTarget(bindableInstance); + if (dataBind != nullptr) + { + if (dataBind->target() != nullptr && + dataBind->target()->is()) + { + auto targetValue = + dataBind->target()->as(); + auto context = stateMachineInstance->dataContext(); + if (context != nullptr) + { + auto value = context->viewModelInstance().get(); + targetValue->viewModelInstanceValue(value); + CoreRegistry::setUint( + targetValue, + BindablePropertyIdBase::propertyValuePropertyKey, + ViewModelInstance::pointerKey(value)); + } + } + dataBind->updateSourceBinding(true); + } + if (dataBindToTarget) + { + dataBindToTarget->addDirt(ComponentDirt::Bindings, true); + } } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/nested_bool.cpp b/thirdparty/rive/source/animation/nested_bool.cpp index 3a5de15cf..e575022dc 100644 --- a/thirdparty/rive/source/animation/nested_bool.cpp +++ b/thirdparty/rive/source/animation/nested_bool.cpp @@ -4,6 +4,7 @@ #include "rive/container_component.hpp" using namespace rive; +class StateMachineInstance; // Use the NestedBoolBase m_NestedValue on initialization but then it won't // be used anymore and interface directly with the nested input value. @@ -45,4 +46,4 @@ bool NestedBool::nestedValue() const } } return false; -} +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/nested_linear_animation.cpp b/thirdparty/rive/source/animation/nested_linear_animation.cpp index 42d904db3..07ddb531a 100644 --- a/thirdparty/rive/source/animation/nested_linear_animation.cpp +++ b/thirdparty/rive/source/animation/nested_linear_animation.cpp @@ -8,7 +8,7 @@ NestedLinearAnimation::~NestedLinearAnimation() {} void NestedLinearAnimation::initializeAnimation(ArtboardInstance* artboard) { - m_AnimationInstance = rivestd::make_unique( + m_AnimationInstance = std::make_unique( artboard->animation(animationId()), artboard); } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/nested_number.cpp b/thirdparty/rive/source/animation/nested_number.cpp index 16a6a8d7b..a3d882934 100644 --- a/thirdparty/rive/source/animation/nested_number.cpp +++ b/thirdparty/rive/source/animation/nested_number.cpp @@ -4,6 +4,7 @@ #include "rive/container_component.hpp" using namespace rive; +class StateMachineInstance; // Use the NestedNumberBase m_NestedValue on initialization but then it won't // be used anymore and interface directly with the nested input value. @@ -45,4 +46,4 @@ float NestedNumber::nestedValue() const } } return 0.0; -} +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/nested_state_machine.cpp b/thirdparty/rive/source/animation/nested_state_machine.cpp index d6737a7ad..31e4d8ec2 100644 --- a/thirdparty/rive/source/animation/nested_state_machine.cpp +++ b/thirdparty/rive/source/animation/nested_state_machine.cpp @@ -3,7 +3,10 @@ #include "rive/animation/nested_number.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/focus_data.hpp" #include "rive/hit_result.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/nested_artboard.hpp" using namespace rive; @@ -23,6 +26,30 @@ bool NestedStateMachine::advance(float elapsedSeconds, bool newFrame) void NestedStateMachine::initializeAnimation(ArtboardInstance* artboard) { m_StateMachineInstance = artboard->stateMachineAt(animationId()); + if (m_StateMachineInstance != nullptr) + { + // Share parent's focus manager and build nested focus tree. + // The parent of NestedStateMachine is the NestedArtboard. + if (parent() != nullptr && parent()->is()) + { + auto* nestedArtboard = parent()->as(); + auto* parentArtboard = nestedArtboard->artboard(); + if (parentArtboard != nullptr && + parentArtboard->focusManager() != nullptr) + { + auto* parentFM = parentArtboard->focusManager(); + m_StateMachineInstance->setExternalFocusManager(parentFM); + + // Find closest focus node (handles artboard boundaries) + auto parentNode = + FocusData::findClosestFocusNode(nestedArtboard); + + // Build nested artboard's focus tree under parent + artboard->buildFocusTree(parentFM, parentNode); + } + } + } + auto count = m_nestedInputs.size(); for (size_t i = 0; i < count; i++) { @@ -48,38 +75,67 @@ bool NestedStateMachine::hitTest(Vec2D position) const return false; } -HitResult NestedStateMachine::pointerMove(Vec2D position) +HitResult NestedStateMachine::pointerMove(Vec2D position, + float timeStamp, + int pointerId) +{ + if (m_StateMachineInstance != nullptr) + { + return m_StateMachineInstance->pointerMove(position, + timeStamp, + pointerId); + } + return HitResult::none; +} + +HitResult NestedStateMachine::pointerDown(Vec2D position, int pointerId) { if (m_StateMachineInstance != nullptr) { - return m_StateMachineInstance->pointerMove(position); + return m_StateMachineInstance->pointerDown(position, pointerId); } return HitResult::none; } -HitResult NestedStateMachine::pointerDown(Vec2D position) +HitResult NestedStateMachine::pointerUp(Vec2D position, int pointerId) { if (m_StateMachineInstance != nullptr) { - return m_StateMachineInstance->pointerDown(position); + return m_StateMachineInstance->pointerUp(position, pointerId); } return HitResult::none; } -HitResult NestedStateMachine::pointerUp(Vec2D position) +HitResult NestedStateMachine::pointerExit(Vec2D position, int pointerId) { if (m_StateMachineInstance != nullptr) { - return m_StateMachineInstance->pointerUp(position); + return m_StateMachineInstance->pointerExit(position, pointerId); } return HitResult::none; } -HitResult NestedStateMachine::pointerExit(Vec2D position) +HitResult NestedStateMachine::dragStart(Vec2D position, + float timeStamp, + int pointerId) { if (m_StateMachineInstance != nullptr) { - return m_StateMachineInstance->pointerExit(position); + return m_StateMachineInstance->dragStart(position, + timeStamp, + true, + pointerId); + } + return HitResult::none; +} + +HitResult NestedStateMachine::dragEnd(Vec2D position, + float timeStamp, + int pointerId) +{ + if (m_StateMachineInstance != nullptr) + { + return m_StateMachineInstance->dragEnd(position, timeStamp, pointerId); } return HitResult::none; } @@ -119,7 +175,7 @@ void NestedStateMachine::bindViewModelInstance( } } -void NestedStateMachine::dataContext(DataContext* dataContext) +void NestedStateMachine::dataContext(rcp dataContext) { if (m_StateMachineInstance != nullptr) { @@ -127,6 +183,14 @@ void NestedStateMachine::dataContext(DataContext* dataContext) } } +void NestedStateMachine::clearDataContext() +{ + if (m_StateMachineInstance != nullptr) + { + m_StateMachineInstance->clearDataContext(); + } +} + bool NestedStateMachine::tryChangeState() { if (m_StateMachineInstance != nullptr) diff --git a/thirdparty/rive/source/animation/nested_trigger.cpp b/thirdparty/rive/source/animation/nested_trigger.cpp index be0700462..89fb586c3 100644 --- a/thirdparty/rive/source/animation/nested_trigger.cpp +++ b/thirdparty/rive/source/animation/nested_trigger.cpp @@ -4,6 +4,7 @@ #include "rive/container_component.hpp" using namespace rive; +class StateMachineInstance; void NestedTrigger::fire(const CallbackData& value) { this->applyValue(); } @@ -18,4 +19,4 @@ void NestedTrigger::applyValue() numInput->fire(); } } -} +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/property_recorder.cpp b/thirdparty/rive/source/animation/property_recorder.cpp new file mode 100644 index 000000000..cc84ba888 --- /dev/null +++ b/thirdparty/rive/source/animation/property_recorder.cpp @@ -0,0 +1,393 @@ +#include "rive/property_recorder.hpp" +#include "rive/core/vector_binary_writer.hpp" +#include "rive/generated/core_registry.hpp" +#include "rive/artboard.hpp" +#include "rive/animation/state_machine.hpp" +#include "rive/animation/state_machine_input.hpp" +#include "rive/animation/state_machine_number.hpp" +#include "rive/animation/state_machine_bool.hpp" +#include "rive/animation/state_machine_trigger.hpp" +#include "rive/animation/state_machine_layer.hpp" +#include "rive/animation/layer_state.hpp" +#include "rive/animation/blend_state.hpp" +#include "rive/animation/keyed_object.hpp" + +using namespace rive; + +PropertyRecorder::PropertyRecorder() : + m_binaryWriter(&m_WriteBuffer), + m_binaryReader(nullptr, 0), + m_binaryWriterSM(&m_WriteBufferSM), + m_binaryReaderSM(nullptr, 0) +{} + +void PropertyRecorder::writeObjectId(uint32_t objectId, + VectorBinaryWriter& writer) +{ + writer.writeVarUint(objectId); +} + +void PropertyRecorder::writeTotalProperties(uint32_t value, + VectorBinaryWriter& writer) +{ + writer.writeVarUint(value); +} + +void PropertyRecorder::writePropertyKey(uint32_t value, + VectorBinaryWriter& writer) +{ + writer.writeVarUint(value); +} + +void PropertyRecorder::writePropertyValue(float value, + VectorBinaryWriter& writer) +{ + writer.writeFloat(value); +} + +void PropertyRecorder::writePropertyValue(int value, VectorBinaryWriter& writer) +{ + writer.writeVarUint((uint32_t)value); +} + +void PropertyRecorder::writePropertyValue(uint32_t value, + VectorBinaryWriter& writer) +{ + writer.writeVarUint(value); +} + +void PropertyRecorder::writePropertyValue(std::string value, + VectorBinaryWriter& writer) +{ + writer.write(value); +} + +void PropertyRecorder::writePropertyValue(bool value, + VectorBinaryWriter& writer) +{ + writer.write((uint8_t)value); +} + +void PropertyRecorder::clear() { m_binaryWriter.clear(); } + +void PropertyRecorder::complete(VectorBinaryWriter& writer, + BinaryDataReader& reader, + std::vector& buffer) +{ + reader.complete(&buffer.front(), writer.size()); +} + +void PropertyRecorder::recordArtboard(const Artboard* artboard) +{ + auto sm = artboard->stateMachine(0); + recordStateMachineInputs(sm); + recordStateMachine(sm); + recordDataBinds(artboard); + writeProperties(artboard); + complete(m_binaryWriter, m_binaryReader, m_WriteBuffer); +} + +void PropertyRecorder::recordDataBinds(const Artboard* artboard) +{ + auto dataBinds = artboard->dataBinds(); + for (auto& dataBind : dataBinds) + { + auto target = dataBind->target(); + auto index = getObjectId(artboard, target); + auto propertyKey = dataBind->propertyKey(); + if (index >= 0) + { + auto coreObjectData = getCoreObjectData((uint32_t)index); + addPropertyKey(coreObjectData, propertyKey); + } + } +} + +void PropertyRecorder::addPropertyKey(CoreObjectData* coreObjectData, + int propertyKey) +{ + switch (CoreRegistry::propertyFieldId(propertyKey)) + { + case CoreDoubleType::id: + case CoreColorType::id: + case CoreUintType::id: + case CoreStringType::id: + case CoreBoolType::id: + coreObjectData->addPropertyKey(propertyKey); + break; + default: + break; + } +} +void PropertyRecorder::recordStateMachine(const StateMachine* stateMachine) +{ + if (stateMachine != nullptr) + { + auto totalLayers = stateMachine->layerCount(); + for (size_t i = 0; i < totalLayers; i++) + { + recordStateMachineLayer(stateMachine->layer(i)); + } + } +} +void PropertyRecorder::recordStateMachineInputs( + const StateMachine* stateMachine) +{ + if (stateMachine != nullptr) + { + auto totalInputs = stateMachine->inputCount(); + for (size_t i = 0; i < totalInputs; i++) + { + recordStateMachineInput(stateMachine->input(i)); + } + } + complete(m_binaryWriterSM, m_binaryReaderSM, m_WriteBufferSM); +} +void PropertyRecorder::recordStateMachineInput( + const StateMachineInput* stateMachineInput) +{ + if (stateMachineInput != nullptr) + { + if (stateMachineInput->is()) + { + writePropertyValue(0, m_binaryWriterSM); + writePropertyValue( + stateMachineInput->as()->value(), + m_binaryWriterSM); + } + else if (stateMachineInput->is()) + { + writePropertyValue(1, m_binaryWriterSM); + writePropertyValue( + stateMachineInput->as()->value(), + m_binaryWriterSM); + } + else if (stateMachineInput->is()) + { + // No need to write a value for triggers, but writing the type to + // keep the indexes coherent + writePropertyValue(2, m_binaryWriterSM); + } + } +} + +void PropertyRecorder::recordStateMachineLayer( + const StateMachineLayer* stateMachineLayer) +{ + + auto totalStates = stateMachineLayer->stateCount(); + for (size_t j = 0; j < totalStates; j++) + { + auto state = stateMachineLayer->state(j); + recordStateMachineLayerState(state); + } +} +void PropertyRecorder::recordStateMachineLayerState( + const LayerState* layerState) +{ + if (layerState->is()) + { + recordLinearAnimation(layerState->as()->animation()); + } + else if (layerState->is()) + { + auto blendState = layerState->as(); + for (auto& blendAnimation : blendState->animations()) + { + recordLinearAnimation(blendAnimation->animation()); + } + } +} +void PropertyRecorder::recordLinearAnimation( + const LinearAnimation* linearAnimation) +{ + if (linearAnimation != nullptr) + { + auto totalObjects = linearAnimation->numKeyedObjects(); + for (size_t i = 0; i < totalObjects; i += 1) + { + auto keyedObject = linearAnimation->getObject(i); + recordKeyedObject(keyedObject); + } + } +} +void PropertyRecorder::recordKeyedObject(const KeyedObject* keyedObject) +{ + if (keyedObject != nullptr) + { + auto coreObjectData = getCoreObjectData(keyedObject->objectId()); + + auto totalProperties = keyedObject->numKeyedProperties(); + for (size_t i = 0; i < totalProperties; i += 1) + { + auto property = keyedObject->getProperty(i); + addPropertyKey(coreObjectData, property->propertyKey()); + } + } +} + +CoreObjectData* PropertyRecorder::getCoreObjectData(uint32_t id) +{ + for (auto& coreObjectData : m_coreObjectsData) + { + if (coreObjectData->objectId == id) + { + return coreObjectData.get(); + } + } + + auto newCoreObjectData = std::make_unique(id); + auto ref = newCoreObjectData.get(); + m_coreObjectsData.push_back(std::move(newCoreObjectData)); + return ref; +} + +void PropertyRecorder::writeProperties(const Artboard* artboard) +{ + for (auto& coreObjectData : m_coreObjectsData) + { + auto propertyKeys = *coreObjectData->propertyKeys(); + if (propertyKeys.size() > 0) + { + auto object = artboard->resolve(coreObjectData->objectId); + writeObjectId(coreObjectData->objectId, m_binaryWriter); + writeTotalProperties((uint32_t)propertyKeys.size(), m_binaryWriter); + for (auto& propertyKey : propertyKeys) + { + switch (CoreRegistry::propertyFieldId(propertyKey)) + { + case CoreDoubleType::id: + { + writePropertyKey(propertyKey, m_binaryWriter); + auto value = + CoreRegistry::getDouble(object, propertyKey); + writePropertyValue(value, m_binaryWriter); + } + break; + case CoreColorType::id: + { + writePropertyKey(propertyKey, m_binaryWriter); + auto value = + CoreRegistry::getColor(object, propertyKey); + writePropertyValue(value, m_binaryWriter); + } + break; + case CoreUintType::id: + { + writePropertyKey(propertyKey, m_binaryWriter); + auto value = CoreRegistry::getUint(object, propertyKey); + writePropertyValue(value, m_binaryWriter); + } + break; + case CoreStringType::id: + { + writePropertyKey(propertyKey, m_binaryWriter); + auto value = + CoreRegistry::getString(object, propertyKey); + writePropertyValue(value, m_binaryWriter); + } + break; + case CoreBoolType::id: + { + writePropertyKey(propertyKey, m_binaryWriter); + auto value = CoreRegistry::getBool(object, propertyKey); + writePropertyValue(value, m_binaryWriter); + } + break; + default: + break; + } + } + } + } +} + +int PropertyRecorder::getObjectId(const Artboard* artboard, Core* object) +{ + return artboard->objectIndex(object); +} + +// void PropertyRecorder::applyInputs() {} + +void PropertyRecorder::apply(StateMachineInstance* stateMachineInstace) +{ + int index = 0; + m_binaryReaderSM.reset(&m_WriteBufferSM.front()); + while (!m_binaryReaderSM.isEOF() && index < 20) + { + auto inputType = m_binaryReaderSM.readVarUint32(); + auto smInput = stateMachineInstace->input(index); + if (inputType == 0) + { + auto value = m_binaryReaderSM.readFloat32(); + auto smInputNumber = + stateMachineInstace->getNumber(smInput->name()); + if (smInputNumber != nullptr) + { + smInputNumber->value(value); + } + } + else if (inputType == 1) + { + auto value = m_binaryReaderSM.readByte(); + auto smInputBool = stateMachineInstace->getBool(smInput->name()); + if (smInputBool != nullptr) + { + smInputBool->value(value); + } + } + index += 1; + } +} + +void PropertyRecorder::apply(Artboard* artboard) +{ + m_binaryReader.reset(&m_WriteBuffer.front()); + while (!m_binaryReader.isEOF()) + { + auto objectId = m_binaryReader.readVarUint32(); + auto object = artboard->resolve(objectId); + auto totalProperties = m_binaryReader.readVarUint32(); + uint32_t currentPropertyIndex = 0; + while (currentPropertyIndex < totalProperties) + { + auto propertyKey = m_binaryReader.readVarUint32(); + switch (CoreRegistry::propertyFieldId(propertyKey)) + { + case CoreDoubleType::id: + { + auto propertyValue = m_binaryReader.readFloat32(); + CoreRegistry::setDouble(object, propertyKey, propertyValue); + break; + } + case CoreColorType::id: + { + auto propertyValue = m_binaryReader.readVarUint32(); + CoreRegistry::setColor(object, propertyKey, propertyValue); + break; + } + case CoreUintType::id: + { + auto propertyValue = m_binaryReader.readVarUint32(); + CoreRegistry::setUint(object, propertyKey, propertyValue); + break; + } + case CoreStringType::id: + { + auto propertyValue = m_binaryReader.readString(); + CoreRegistry::setString(object, propertyKey, propertyValue); + break; + } + case CoreBoolType::id: + { + auto propertyValue = m_binaryReader.readByte(); + CoreRegistry::setBool(object, + propertyKey, + (bool)propertyValue); + break; + } + } + currentPropertyIndex++; + } + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/scripted_listener_action.cpp b/thirdparty/rive/source/animation/scripted_listener_action.cpp new file mode 100644 index 000000000..81e1b1c27 --- /dev/null +++ b/thirdparty/rive/source/animation/scripted_listener_action.cpp @@ -0,0 +1,157 @@ +#include "rive/animation/scripted_listener_action.hpp" +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/importers/state_machine_importer.hpp" +#include "rive/data_bind/data_bind.hpp" +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif + +using namespace rive; + +ScriptedListenerAction::~ScriptedListenerAction() { disposeScriptInputs(); } + +void ScriptedListenerAction::disposeScriptInputs() +{ + auto props = m_customProperties; + ScriptedObject::disposeScriptInputs(); + for (auto prop : props) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + // ScriptedDataConverters need to delete their own inputs + // because they are not components + delete scriptInput; + } + } +} + +// Note: performStateful is the actual instance of the ScriptedListenerAction +// that will run the script. perform itself will look for the map between the +// stateless and the stateful instances of this class. +// +// Dispatch: if `performAction` is defined, it is called with (self, +// ScriptedInvocation) and legacy `perform` is skipped. Otherwise `perform` +// is called with (self, PointerEvent) — real pointer data or a placeholder +// ScriptedPointerEvent for non-pointer invocations. +void ScriptedListenerAction::performStateful( + StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const +{ +#ifdef WITH_RIVE_SCRIPTING + (void)stateMachineInstance; + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + if (performsAction()) + { + // Stack: [self] + lua_getfield(L, -1, "performAction"); + // Stack: [self, performAction] + lua_pushvalue(L, -2); + rive_lua_push_scripted_invocation(L, invocation); + // Stack: [self, performAction, self, invocation] + if (static_cast(rive_lua_pcall_with_context( + L, + const_cast(this), + 2, + 0)) != LUA_OK) + { + // Stack: [self, status] + lua_pop(L, 1); + } + } + else if (performs()) + { + lua_getfield(L, -1, "perform"); + // Stack: [self, perform] + lua_pushvalue(L, -2); + // Stack: [self, perform, self] + rive_lua_push_pointer_arg_for_perform(L, invocation); + // Stack: [self, perform, self, pointerEvent] + if (static_cast(rive_lua_pcall_with_context( + L, + const_cast(this), + 2, + 0)) != LUA_OK) + { + // Stack: [self, status] + lua_pop(L, 1); + } + } + // Stack: [self] + lua_pop(L, 1); +#else + (void)stateMachineInstance; + (void)invocation; +#endif +} + +void ScriptedListenerAction::perform(StateMachineInstance* stateMachineInstance, + const ListenerInvocation& invocation) const +{ +#ifdef WITH_RIVE_SCRIPTING + auto scriptedObject = stateMachineInstance->scriptedObject(this); + if (scriptedObject != nullptr) + { + auto statefulListenerAction = + static_cast(scriptedObject); + statefulListenerAction->performStateful(stateMachineInstance, + invocation); + } +#else + (void)stateMachineInstance; + (void)invocation; +#endif +} + +StatusCode ScriptedListenerAction::import(ImportStack& importStack) +{ + auto result = registerReferencer(importStack); + if (result != StatusCode::Ok) + { + return result; + } + + auto stateMachineImporter = + importStack.latest(StateMachine::typeKey); + if (stateMachineImporter == nullptr) + { + return StatusCode::MissingObject; + } + stateMachineImporter->addScriptedObject(this); + return Super::import(importStack); +} + +Core* ScriptedListenerAction::clone() const +{ + ScriptedListenerAction* twin = + ScriptedListenerActionBase::clone()->as(); + if (m_fileAsset != nullptr) + { + twin->setAsset(m_fileAsset); + } + return twin; +} + +ScriptedObject* ScriptedListenerAction::cloneScriptedObject( + DataBindContainer* dataBindContainer) const +{ + auto clonedScriptedObject = clone()->as(); + cloneProperties(clonedScriptedObject, dataBindContainer); + clonedScriptedObject->reinit(); + return clonedScriptedObject; +} +void ScriptedListenerAction::addProperty(CustomProperty* prop) +{ + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(this); + } + CustomPropertyContainer::addProperty(prop); +} diff --git a/thirdparty/rive/source/animation/scripted_transition_condition.cpp b/thirdparty/rive/source/animation/scripted_transition_condition.cpp new file mode 100644 index 000000000..608381289 --- /dev/null +++ b/thirdparty/rive/source/animation/scripted_transition_condition.cpp @@ -0,0 +1,138 @@ +#include "rive/animation/scripted_transition_condition.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/importers/state_machine_importer.hpp" +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif + +using namespace rive; + +ScriptedTransitionCondition::~ScriptedTransitionCondition() +{ + disposeScriptInputs(); +} + +void ScriptedTransitionCondition::disposeScriptInputs() +{ + auto props = m_customProperties; + ScriptedObject::disposeScriptInputs(); + for (auto prop : props) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + // ScriptedDataConverters need to delete their own inputs + // because they are not components + delete scriptInput; + } + } +} + +// Note: evaluateStateful is the actual instance of the +// ScriptedTransitionCondition that will run the script. evaluate itself will +// look for the map between the stateless and the stateful instances of this +// class. +bool ScriptedTransitionCondition::evaluateStateful( + const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) const +{ + bool result = false; +#ifdef WITH_RIVE_SCRIPTING + if (m_vm != nullptr) + { + lua_State* L = state(); + // Stack: [] + rive_lua_pushRef(L, m_self); + // Stack: [self] + lua_getfield(L, -1, "evaluate"); + + // Stack: [self, field] + lua_insert(L, -2); // Swap self and field + + // Stack: [field, self] + if (static_cast(rive_lua_pcall_with_context( + L, + const_cast(this), + 1, + 1)) == LUA_OK) + { + if (lua_isboolean(L, -1)) + { + result = lua_toboolean(L, -1); + } + // Stack: [result] + rive_lua_pop(L, 1); + } + else + { + // Stack: [status] + rive_lua_pop(L, 1); + } + } +#endif + return result; +} + +bool ScriptedTransitionCondition::evaluate( + const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) const +{ +#ifdef WITH_RIVE_SCRIPTING + auto scriptedObject = stateMachineInstance->scriptedObject(this); + if (scriptedObject != nullptr) + { + auto statefulListenerAction = + static_cast(scriptedObject); + return statefulListenerAction->evaluateStateful(stateMachineInstance, + layerInstance); + } +#endif + return false; +} + +StatusCode ScriptedTransitionCondition::import(ImportStack& importStack) +{ + auto result = registerReferencer(importStack); + if (result != StatusCode::Ok) + { + return result; + } + auto stateMachineImporter = + importStack.latest(StateMachine::typeKey); + if (stateMachineImporter == nullptr) + { + return StatusCode::MissingObject; + } + stateMachineImporter->addScriptedObject(this); + return Super::import(importStack); +} + +Core* ScriptedTransitionCondition::clone() const +{ + ScriptedTransitionCondition* twin = ScriptedTransitionConditionBase::clone() + ->as(); + if (m_fileAsset != nullptr) + { + twin->setAsset(m_fileAsset); + } + return twin; +} + +ScriptedObject* ScriptedTransitionCondition::cloneScriptedObject( + DataBindContainer* dataBindContainer) const +{ + auto clonedScriptedObject = clone()->as(); + cloneProperties(clonedScriptedObject, dataBindContainer); + clonedScriptedObject->reinit(); + return clonedScriptedObject; +} + +void ScriptedTransitionCondition::addProperty(CustomProperty* prop) +{ + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(this); + } + CustomPropertyContainer::addProperty(prop); +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/semantic_listener_group.cpp b/thirdparty/rive/source/animation/semantic_listener_group.cpp new file mode 100644 index 000000000..ae310af71 --- /dev/null +++ b/thirdparty/rive/source/animation/semantic_listener_group.cpp @@ -0,0 +1,54 @@ +#include "rive/animation/semantic_listener_group.hpp" +#include "rive/animation/listener_types/listener_input_type_semantic.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/state_machine_listener.hpp" +#include "rive/semantic/semantic_data.hpp" + +using namespace rive; + +SemanticListenerGroup::SemanticListenerGroup( + SemanticData* semanticData, + const StateMachineListener* listener, + StateMachineInstance* stateMachineInstance) : + m_semanticData(semanticData), + m_listener(listener), + m_stateMachineInstance(stateMachineInstance) +{ + if (m_semanticData != nullptr) + { + m_semanticData->addSemanticListener(this); + } +} + +SemanticListenerGroup::~SemanticListenerGroup() +{ + if (m_semanticData != nullptr) + { + m_semanticData->removeSemanticListener(this); + } +} + +void SemanticListenerGroup::queueIfListening(SemanticActionType actionType) +{ + if (m_listener != nullptr && + ListenerInputTypeSemantic::semanticListenerConstraintsMet(m_listener, + actionType)) + { + m_stateMachineInstance->queueSemanticEvent(this, actionType); + } +} + +void SemanticListenerGroup::onSemanticTap() +{ + queueIfListening(SemanticActionType::tap); +} + +void SemanticListenerGroup::onSemanticIncrease() +{ + queueIfListening(SemanticActionType::increase); +} + +void SemanticListenerGroup::onSemanticDecrease() +{ + queueIfListening(SemanticActionType::decrease); +} diff --git a/thirdparty/rive/source/animation/state_machine.cpp b/thirdparty/rive/source/animation/state_machine.cpp index d2c822b59..be9cc5964 100644 --- a/thirdparty/rive/source/animation/state_machine.cpp +++ b/thirdparty/rive/source/animation/state_machine.cpp @@ -4,6 +4,8 @@ #include "rive/animation/state_machine_layer.hpp" #include "rive/animation/state_machine_input.hpp" #include "rive/animation/state_machine_listener.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/data_bind/data_bind.hpp" using namespace rive; @@ -155,4 +157,9 @@ const DataBind* StateMachine::dataBind(size_t index) const return m_dataBinds[index].get(); } return nullptr; +} + +void StateMachine::addScriptedObject(ScriptedObject* object) +{ + m_scriptedObjects.push_back(object); } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/state_machine_fire_action.cpp b/thirdparty/rive/source/animation/state_machine_fire_action.cpp new file mode 100644 index 000000000..f6b8089f3 --- /dev/null +++ b/thirdparty/rive/source/animation/state_machine_fire_action.cpp @@ -0,0 +1,20 @@ +#include "rive/generated/animation/state_machine_fire_action_base.hpp" +#include "rive/animation/state_machine_fire_event.hpp" +#include "rive/animation/state_machine_layer_component.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/event.hpp" +#include "rive/importers/state_machine_layer_component_importer.hpp" + +using namespace rive; + +StatusCode StateMachineFireAction::import(ImportStack& importStack) +{ + auto stateImporter = importStack.latest( + StateMachineLayerComponent::typeKey); + if (stateImporter == nullptr) + { + return StatusCode::MissingObject; + } + stateImporter->addFireEvent(this); + return Super::import(importStack); +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/state_machine_fire_trigger.cpp b/thirdparty/rive/source/animation/state_machine_fire_trigger.cpp new file mode 100644 index 000000000..28dc9f5e6 --- /dev/null +++ b/thirdparty/rive/source/animation/state_machine_fire_trigger.cpp @@ -0,0 +1,36 @@ +#include "rive/animation/state_machine_fire_trigger.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_trigger.hpp" + +using namespace rive; + +void StateMachineFireTrigger::perform( + StateMachineInstance* stateMachineInstance) const +{ + auto dataContext = stateMachineInstance->dataContext(); + if (dataContext != nullptr && m_dataBindPath) + { + auto vmProp = dataContext->getViewModelProperty(m_dataBindPath); + if (vmProp && vmProp->is()) + { + vmProp->as()->trigger(); + } + } +} + +StatusCode StateMachineFireTrigger::import(ImportStack& importStack) +{ + importDataBindPath(importStack); + return Super::import(importStack); +} + +void StateMachineFireTrigger::decodeViewModelPathIds(Span value) +{ + decodeDataBindPath(value); +} + +void StateMachineFireTrigger::copyViewModelPathIds( + const StateMachineFireTriggerBase& object) +{ + copyDataBindPath(object.as()->dataBindPath()); +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/state_machine_instance.cpp b/thirdparty/rive/source/animation/state_machine_instance.cpp index ce95b5a5b..f3206ded7 100644 --- a/thirdparty/rive/source/animation/state_machine_instance.cpp +++ b/thirdparty/rive/source/animation/state_machine_instance.cpp @@ -5,46 +5,120 @@ #include "rive/animation/any_state.hpp" #include "rive/animation/keyframe_interpolator.hpp" #include "rive/animation/entry_state.hpp" +#include "rive/animation/exit_state.hpp" #include "rive/animation/layer_state_flags.hpp" #include "rive/animation/nested_linear_animation.hpp" #include "rive/animation/nested_state_machine.hpp" +#include "rive/animation/scripted_transition_condition.hpp" #include "rive/animation/state_instance.hpp" #include "rive/animation/state_machine_bool.hpp" #include "rive/animation/state_machine_input_instance.hpp" #include "rive/animation/state_machine_input.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/animation/state_machine_layer.hpp" +#include "rive/animation/listener_invocation.hpp" #include "rive/animation/state_machine_listener.hpp" +#include "rive/animation/state_machine_listener_single.hpp" #include "rive/animation/state_machine_number.hpp" #include "rive/animation/state_machine_trigger.hpp" #include "rive/animation/state_machine.hpp" #include "rive/animation/state_transition.hpp" +#include "rive/animation/listener_action.hpp" +#include "rive/animation/listener_types/listener_input_type_viewmodel.hpp" +#include "rive/animation/scripted_listener_action.hpp" #include "rive/animation/transition_condition.hpp" #include "rive/animation/transition_comparator.hpp" #include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_machine_fire_event.hpp" +#include "rive/viewmodel/viewmodel_instance_trigger.hpp" #include "rive/artboard_component_list.hpp" #include "rive/constraints/draggable_constraint.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" #include "rive/data_bind_flags.hpp" #include "rive/event_report.hpp" -#include "rive/gesture_click_phase.hpp" #include "rive/hit_result.hpp" -#include "rive/process_event_result.hpp" +#include "rive/listener_group.hpp" #include "rive/math/aabb.hpp" +#include "rive/math/random.hpp" #include "rive/math/hit_test.hpp" #include "rive/nested_animation.hpp" #include "rive/nested_artboard.hpp" +#include "rive/process_event_result.hpp" +#include "rive/scripted/scripted_drawable.hpp" #include "rive/shapes/shape.hpp" #include "rive/text/text.hpp" #include "rive/math/math_types.hpp" #include "rive/audio_event.hpp" +#include "rive/dirtyable.hpp" +#include "rive/profiler/profiler_macros.h" +#include "rive/text/text_input.hpp" +#include "rive/refcnt.hpp" +#include "rive/animation/focus_listener_group.hpp" +#include "rive/animation/text_input_listener_group.hpp" +#include "rive/animation/listener_types/listener_input_type_event.hpp" +#include "rive/focus_data.hpp" +#include "rive/node.hpp" +#include "rive/semantic/semantic_data.hpp" +#include +#include #include +#include #include +#include using namespace rive; + +#ifdef RIVE_MICROPROFILE +#include "rive/profiler/rive_profile.hpp" +static std::string getStateName(const StateInstance* stateInstance) +{ + if (stateInstance == nullptr) + { + return "(null)"; + } + auto state = stateInstance->state(); + if (state->is()) + { + auto anim = state->as()->animation(); + return anim != nullptr ? anim->name() : "Animation"; + } + if (state->is()) + { + return "Entry"; + } + if (state->is()) + { + return "Exit"; + } + if (state->is()) + { + return "Any"; + } + return "Blend"; +} +#endif + namespace rive { +namespace +{ +constexpr std::array kPointerHitListenerTypes = { + ListenerType::enter, + ListenerType::exit, + ListenerType::down, + ListenerType::up, + ListenerType::move, + ListenerType::click, + ListenerType::dragStart, + ListenerType::dragEnd, + ListenerType::drag, +}; +} // namespace + class StateMachineLayerInstance { public: @@ -59,6 +133,19 @@ class StateMachineLayerInstance const StateMachineLayer* layer, ArtboardInstance* instance) { + + if (File::deterministicMode) + { + srand((unsigned int)1); + } + else + { + auto now = std::chrono::high_resolution_clock::now(); + auto nanos = std::chrono::duration_cast( + now.time_since_epoch()) + .count(); + srand((unsigned int)nanos); + } m_stateMachineInstance = stateMachineInstance; m_artboardInstance = instance; assert(m_layer == nullptr); @@ -66,34 +153,46 @@ class StateMachineLayerInstance layer->anyState()->makeInstance(instance).release(); m_layer = layer; changeState(m_layer->entryState()); + } -#ifdef TESTING - srand((unsigned int)1); -#else - auto now = std::chrono::high_resolution_clock::now(); - auto nanos = std::chrono::duration_cast( - now.time_since_epoch()) - .count(); - srand((unsigned int)nanos); -#endif + void resetState() + { + if (m_stateFrom != m_anyStateInstance && m_stateFrom != m_currentState) + { + delete m_stateFrom; + } + m_stateFrom = nullptr; + if (m_currentState != m_anyStateInstance) + { + delete m_currentState; + } + m_currentState = nullptr; + changeState(m_layer->entryState()); } void updateMix(float seconds) { if (m_transition != nullptr && m_stateFrom != nullptr && - m_transition->duration() != 0) + resolvedDuration() != 0) { - m_mix = std::min( - 1.0f, - std::max(0.0f, - (m_mix + seconds / m_transition->mixTime( - m_stateFrom->state())))); + auto mixTime = resolvedMixTime(); + if (mixTime == 0.0f) + { + m_mix = 1.0f; + } + else + { + m_mix = + std::min(1.0f, std::max(0.0f, (m_mix + seconds / mixTime))); + } if (m_mix == 1.0f && !m_transitionCompleted) { m_transitionCompleted = true; clearAnimationReset(); fireEvents(StateMachineFireOccurance::atEnd, m_transition->events()); + performListenerActions(StateMachineFireOccurance::atEnd, + m_transition->listenerActions()); } } else @@ -129,7 +228,12 @@ class StateMachineLayerInstance if (i == maxIterations) { - fprintf(stderr, "StateMachine exceeded max iterations.\n"); + fprintf(stderr, + "%s StateMachine exceeded max iterations in layer %s " + "on artboard %s\n", + m_stateMachineInstance->stateMachine()->name().c_str(), + m_layer->name().c_str(), + m_stateMachineInstance->artboard()->name().c_str()); return false; } } @@ -140,10 +244,48 @@ class StateMachineLayerInstance (m_currentState != nullptr && m_currentState->keepGoing()); } + /// Returns the per-instance transition duration, resolving any data + /// binding override. Falls back to the shared definition value when + /// no binding exists. + uint32_t resolvedDuration() const + { + if (m_transitionDurationProperty != nullptr) + { + float val = m_transitionDurationProperty->propertyValue(); + return val < 0 ? 0 : static_cast(std::round(val)); + } + return m_transition->duration(); + } + + /// Computes the mix time using the per-instance resolved duration. + float resolvedMixTime() const + { + auto dur = resolvedDuration(); + if (dur == 0) + { + return 0; + } + if (m_transition->durationIsPercentage()) + { + float animationDuration = 0.0f; + auto state = m_stateFrom->state(); + if (state->is()) + { + auto animation = state->as()->animation(); + if (animation != nullptr) + { + animationDuration = animation->durationSeconds(); + } + } + return (float)dur / 100.0f * animationDuration; + } + return (float)dur / 1000.0f; + } + bool isTransitioning() { return m_transition != nullptr && m_stateFrom != nullptr && - m_transition->duration() != 0 && m_mix < 1.0f; + resolvedDuration() != 0 && m_mix < 1.0f; } bool updateState() @@ -166,7 +308,7 @@ class StateMachineLayerInstance } void fireEvents(StateMachineFireOccurance occurs, - const std::vector& fireEvents) + const std::vector& fireEvents) { for (auto event : fireEvents) { @@ -177,6 +319,20 @@ class StateMachineLayerInstance } } + void performListenerActions( + StateMachineFireOccurance occurs, + const std::vector>& listenerActions) + { + for (const auto& action : listenerActions) + { + if (action->matchesScheduledOccurrence(occurs)) + { + action->perform(m_stateMachineInstance, + ListenerInvocation::none()); + } + } + } + bool canChangeState(const LayerState* stateTo) { return !( @@ -184,21 +340,14 @@ class StateMachineLayerInstance stateTo); } - double randomValue() - { -#ifdef TESTING - return 0; -#else - return ((double)rand() / (RAND_MAX)); -#endif - } + double randomValue() { return RandomProvider::generateRandomFloat(); } - bool changeState(const LayerState* stateTo) + void changeState(const LayerState* stateTo) { if ((m_currentState == nullptr ? nullptr : m_currentState->state()) == stateTo) { - return false; + return; } // Fire end events for the state we're changing from. @@ -206,6 +355,8 @@ class StateMachineLayerInstance { fireEvents(StateMachineFireOccurance::atEnd, m_currentState->state()->events()); + performListenerActions(StateMachineFireOccurance::atEnd, + m_currentState->state()->listenerActions()); } m_currentState = @@ -218,8 +369,10 @@ class StateMachineLayerInstance { fireEvents(StateMachineFireOccurance::atStart, m_currentState->state()->events()); + performListenerActions(StateMachineFireOccurance::atStart, + m_currentState->state()->listenerActions()); } - return true; + return; } StateTransition* findRandomTransition(StateInstance* stateFromInstance) @@ -351,15 +504,32 @@ class StateMachineLayerInstance clearAnimationReset(); changeState(transition->stateTo()); m_stateMachineChangedOnAdvance = true; +#ifdef RIVE_MICROPROFILE + RiveProfile::instance().recordTransition( + m_stateMachineInstance->artboard()->name(), + m_stateMachineInstance->name(), + m_layer->name(), + getStateName(outState), + getStateName(m_currentState), + m_stateMachineInstance->artboard()); +#endif // state actually has changed m_transition = transition; + m_transitionDurationProperty = + m_stateMachineInstance->findTransitionPropertyInstance( + transition, + StateTransitionBase::durationPropertyKey); fireEvents(StateMachineFireOccurance::atStart, transition->events()); - if (transition->duration() == 0) + performListenerActions(StateMachineFireOccurance::atStart, + transition->listenerActions()); + if (resolvedDuration() == 0) { m_transitionCompleted = true; fireEvents(StateMachineFireOccurance::atEnd, transition->events()); + performListenerActions(StateMachineFireOccurance::atEnd, + transition->listenerActions()); } else { @@ -399,16 +569,22 @@ class StateMachineLayerInstance { m_holdAnimationFrom = transition->pauseOnExit(); } - if (m_stateFrom != nullptr && - m_stateFrom->state()->is() && - m_currentState != nullptr) + if (m_currentState != nullptr) { - auto instance = - static_cast(m_stateFrom) - ->animationInstance(); + auto advanceTime = 0.0f; + if (m_stateFrom != nullptr) + { + if (m_stateFrom->state()->is()) + { - auto spilledTime = instance->spilledTime(); - m_currentState->advance(spilledTime, m_stateMachineInstance); + auto instance = + static_cast(m_stateFrom) + ->animationInstance(); + + advanceTime = instance->spilledTime(); + } + } + m_currentState->advance(advanceTime, m_stateMachineInstance); } m_mix = 0.0f; updateMix(0.0f); @@ -483,6 +659,7 @@ class StateMachineLayerInstance StateInstance* m_stateFrom = nullptr; const StateTransition* m_transition = nullptr; + BindablePropertyNumber* m_transitionDurationProperty = nullptr; std::unique_ptr m_animationReset = nullptr; bool m_transitionCompleted = false; @@ -498,229 +675,6 @@ class StateMachineLayerInstance float m_holdTime = 0.0f; }; -class ListenerGroup -{ -public: - ListenerGroup(const StateMachineListener* listener) : m_listener(listener) - {} - virtual ~ListenerGroup() {} - void consume() { m_isConsumed = true; } - // - void hover() { m_isHovered = true; } - void unhover() { m_isHovered = false; } - void reset() - { - m_isConsumed = false; - m_prevIsHovered = m_isHovered; - m_isHovered = false; - if (m_clickPhase == GestureClickPhase::clicked) - { - m_clickPhase = GestureClickPhase::out; - } - } - bool isConsumed() { return m_isConsumed; } - bool isHovered() { return m_isHovered; } - bool prevHovered() { return m_prevIsHovered; } - - virtual bool canEarlyOut(Component* drawable) - { - auto listenerType = m_listener->listenerType(); - return !(listenerType == ListenerType::enter || - listenerType == ListenerType::exit || - listenerType == ListenerType::move); - } - - virtual bool needsDownListener(Component* drawable) - { - auto listenerType = m_listener->listenerType(); - return listenerType == ListenerType::down || - listenerType == ListenerType::click; - } - - virtual bool needsUpListener(Component* drawable) - { - auto listenerType = m_listener->listenerType(); - return listenerType == ListenerType::up || - listenerType == ListenerType::click; - } - // Vec2D position, ListenerType hitType, bool canHit - virtual ProcessEventResult processEvent( - Component* component, - Vec2D position, - ListenerType hitEvent, - bool canHit, - StateMachineInstance* stateMachineInstance) - { - // Because each group is tested individually for its hover state, a - // group could be marked "incorrectly" as hovered at this point. But - // once we iterate each element in the drawing order, that group can be - // occluded by an opaque target on top of it. So although it is hovered - // in isolation, it shouldn't be considered as hovered in the full - // context. In this case, we unhover the group so it is not marked as - // previously hovered. - if (!canHit && isHovered()) - { - unhover(); - } - - bool isGroupHovered = canHit ? isHovered() : false; - bool hoverChange = prevHovered() != isGroupHovered; - // If hover has changes, it means that the element is hovered for the - // first time. Previous positions need to be reset to avoid jumps. - if (hoverChange && isGroupHovered) - { - previousPosition.x = position.x; - previousPosition.y = position.y; - } - - // Handle click gesture phases. A click gesture has two phases. - // First one attached to a pointer down actions, second one attached to - // a pointer up action. Both need to act on a shape of the listener - // group. - if (isGroupHovered) - { - if (hitEvent == ListenerType::down) - { - clickPhase(GestureClickPhase::down); - } - else if (hitEvent == ListenerType::up && - clickPhase() == GestureClickPhase::down) - { - clickPhase(GestureClickPhase::clicked); - } - } - else - { - if (hitEvent == ListenerType::down || hitEvent == ListenerType::up) - { - clickPhase(GestureClickPhase::out); - } - } - auto _listener = listener(); - // Always update hover states regardless of which specific listener type - // we're trying to trigger. - // If hover has changed and: - // - it's hovering and the listener is of type enter - // - it's not hovering and the listener is of type exit - if (hoverChange && ((isGroupHovered && _listener->listenerType() == - ListenerType::enter) || - (!isGroupHovered && - _listener->listenerType() == ListenerType::exit))) - { - _listener->performChanges(stateMachineInstance, - position, - previousPosition); - stateMachineInstance->markNeedsAdvance(); - consume(); - } - // Perform changes if: - // - the click gesture is complete and the listener is of type click - // - the event type matches the listener type and it is hovering the - // group - if ((clickPhase() == GestureClickPhase::clicked && - _listener->listenerType() == ListenerType::click) || - (isGroupHovered && hitEvent == _listener->listenerType())) - { - _listener->performChanges(stateMachineInstance, - position, - previousPosition); - stateMachineInstance->markNeedsAdvance(); - consume(); - } - previousPosition.x = position.x; - previousPosition.y = position.y; - return ProcessEventResult::pointer; - } - void clickPhase(GestureClickPhase value) { m_clickPhase = value; } - GestureClickPhase clickPhase() { return m_clickPhase; } - const StateMachineListener* listener() const { return m_listener; }; - // A vector storing the previous position for this specific listener gorup - Vec2D previousPosition; - -private: - // Consumed listeners aren't processed again in the current frame - bool m_isConsumed = false; - // This variable holds the hover status of the the listener itself so it can - // be shared between all shapes that target it - bool m_isHovered = false; - // Variable storing the previous hovered state to check for hover changes - bool m_prevIsHovered = false; - // A click gesture is composed of three phases and is shared between all - // shapes - GestureClickPhase m_clickPhase = GestureClickPhase::out; - const StateMachineListener* m_listener; -}; - -class DraggableConstraintListenerGroup : public ListenerGroup -{ -public: - DraggableConstraintListenerGroup(const StateMachineListener* listener, - DraggableConstraint* constraint, - DraggableProxy* draggable) : - ListenerGroup(listener), - m_constraint(constraint), - m_draggable(draggable) - {} - ~DraggableConstraintListenerGroup() - { - delete listener(); - delete m_draggable; - } - - DraggableConstraint* constraint() { return m_constraint; } - - bool canEarlyOut(Component* drawable) override { return false; } - - bool needsDownListener(Component* drawable) override { return true; } - - bool needsUpListener(Component* drawable) override { return true; } - // Vec2D position, ListenerType hitType, bool canHit - ProcessEventResult processEvent( - Component* component, - Vec2D position, - ListenerType hitEvent, - bool canHit, - StateMachineInstance* stateMachineInstance) override - { - auto prevPhase = clickPhase(); - ListenerGroup::processEvent(component, - position, - hitEvent, - canHit, - stateMachineInstance); - if (prevPhase == GestureClickPhase::down && - (clickPhase() == GestureClickPhase::clicked || - clickPhase() == GestureClickPhase::out)) - { - m_draggable->endDrag(position); - if (hasScrolled) - { - return ProcessEventResult::scroll; - hasScrolled = false; - } - } - else if (prevPhase != GestureClickPhase::down && - clickPhase() == GestureClickPhase::down) - { - m_draggable->startDrag(position); - hasScrolled = false; - } - else if (hitEvent == ListenerType::move && - clickPhase() == GestureClickPhase::down) - { - m_draggable->drag(position); - hasScrolled = true; - return ProcessEventResult::scroll; - } - return ProcessEventResult::none; - } - -private: - DraggableConstraint* m_constraint; - DraggableProxy* m_draggable; - bool hasScrolled = false; -}; - /// Representation of a Component from the Artboard Instance and all the /// listeners it triggers. Allows tracking hover and performing hit detection /// only once on components that trigger multiple listeners. @@ -749,70 +703,11 @@ class HitDrawable : public HitComponent Drawable* m_drawable; std::vector listeners; - virtual bool hitTestHelper(Vec2D position) const { return false; } - - bool hitTest(Vec2D position) const override - { - return hitTestHelper(position); - } - - virtual bool testBounds(Component* component, - Vec2D position, - bool skipOnUnclipped) const - { - if (component == nullptr) - { - return true; - } - - if (component->is()) - { - component = component->as()->hittableComponent(); - if (component == nullptr) - { - return true; - } - } - - if (component->is()) - { - Mat2D inverseWorld; - auto layout = component->as(); - - if (layout->worldTransform().invert(&inverseWorld)) - { - // If the layout is not clipped and skipOnUnclipped is true, we - // don't care about whether it contains the position - auto canSkip = skipOnUnclipped && !layout->clip(); - if (!canSkip) - { - auto localWorld = inverseWorld * position; - if (layout->is()) - { - auto artboard = layout->as(); - if (artboard->originX() != 0 || - artboard->originY() != 0) - { - localWorld += Vec2D( - artboard->originX() * artboard->layoutWidth(), - artboard->originY() * artboard->layoutHeight()); - } - } - if (!layout->localBounds().contains(localWorld)) - { - return false; - } - } - return testBounds(layout->parent(), position, true); - } - return false; - } - - // Keep going - return testBounds(component->parent(), position, skipOnUnclipped); - } + bool hitTest(Vec2D position) const override { return false; } - void prepareEvent(Vec2D position, ListenerType hitType) override + void prepareEvent(Vec2D position, + ListenerType hitType, + int pointerId) override { if (canEarlyOut && (hitType != ListenerType::down || !hasDownListener) && @@ -823,7 +718,7 @@ class HitDrawable : public HitComponent #endif return; } - isHovered = hitTest(position); + isHovered = hitType != ListenerType::exit && hitTest(position); // // iterate all listeners associated with this hit shape if (isHovered) @@ -831,14 +726,16 @@ class HitDrawable : public HitComponent for (auto listenerGroup : listeners) { - listenerGroup->hover(); + listenerGroup->hover(pointerId); } } } HitResult processEvent(Vec2D position, ListenerType hitType, - bool canHit) override + bool canHit, + float timeStamp, + int pointerId) override { // If the shape doesn't have any ListenerType::move / enter / exit and // the event being processed is not of the type it needs to handle. @@ -860,8 +757,10 @@ class HitDrawable : public HitComponent } if (listenerGroup->processEvent(m_component, position, + pointerId, hitType, canHit, + timeStamp, m_stateMachineInstance) == ProcessEventResult::scroll) { @@ -895,29 +794,28 @@ class HitDrawable : public HitComponent } listeners.push_back(listenerGroup); } -}; -/// Representation of a HitDrawable with a Hittable component -class HitExpandable : public HitDrawable -{ -public: - bool testBounds(Component* component, - Vec2D position, - bool skipOnUnclipped) const override + void enablePointerEvents(int pointerId) override { - Hittable* hittable = component ? Hittable::from(component) : nullptr; - if (hittable != nullptr) + for (auto listenerGroup : listeners) { - if (hittable->hitTestAABB(position) && - HitDrawable::testBounds(component->parent(), position, true)) - { - return hittable->hitTestHiFi(position, hitRadius); - } - return false; + listenerGroup->enable(pointerId); + } + } + + void disablePointerEvents(int pointerId) override + { + for (auto listenerGroup : listeners) + { + listenerGroup->disable(pointerId); } - return HitDrawable::testBounds(component, position, true); } +}; +/// Representation of a HitDrawable with a Hittable component +class HitExpandable : public HitDrawable +{ +public: HitExpandable(Drawable* drawable, Component* component, StateMachineInstance* stateMachineInstance, @@ -925,37 +823,24 @@ class HitExpandable : public HitDrawable HitDrawable(drawable, component, stateMachineInstance, isOpaque) {} - bool hitTestHelper(Vec2D position) const override + bool hitTest(Vec2D position) const override { - return testBounds(m_component, position, true); + return m_component->hitTestPoint(position, true, true); } }; -// Wrapper around HitExpandable to garbage collect text run contours. class HitTextRun : public HitExpandable { public: - TextValueRun* m_textValueRun; - HitTextRun(Drawable* drawable, TextValueRun* component, StateMachineInstance* stateMachineInstance, bool isOpaque = false) : HitExpandable(drawable, component, stateMachineInstance, isOpaque) { - m_textValueRun = component; - if (m_textValueRun) - { - m_textValueRun->isHitTarget(true); - } - } - - ~HitTextRun() - { - if (m_textValueRun != nullptr) + if (component) { - m_textValueRun->isHitTarget(false); - m_textValueRun->resetHitTest(); + component->isHitTarget(true); } } }; @@ -969,9 +854,9 @@ class HitLayout : public HitDrawable HitDrawable(layout, layout, stateMachineInstance, isOpaque) {} - bool hitTestHelper(Vec2D position) const override + bool hitTest(Vec2D position) const override { - return testBounds(m_component, position, false); + return m_component->hitTestPoint(position, false, true); } }; @@ -987,7 +872,7 @@ class HitNestedArtboard : public HitComponent bool hitTest(Vec2D position) const override { auto nestedArtboard = m_component->as(); - if (nestedArtboard->isCollapsed()) + if (nestedArtboard->isCollapsed() || nestedArtboard->isPaused()) { return false; } @@ -1014,11 +899,13 @@ class HitNestedArtboard : public HitComponent } HitResult processEvent(Vec2D position, ListenerType hitType, - bool canHit) override + bool canHit, + float timeStamp, + int pointerId) override { auto nestedArtboard = m_component->as(); HitResult hitResult = HitResult::none; - if (nestedArtboard->isCollapsed()) + if (nestedArtboard->isCollapsed() || nestedArtboard->isPaused()) { return hitResult; } @@ -1041,21 +928,46 @@ class HitNestedArtboard : public HitComponent { case ListenerType::down: hitResult = - nestedStateMachine->pointerDown(nestedPosition); + nestedStateMachine->pointerDown(nestedPosition, + pointerId); break; case ListenerType::up: hitResult = - nestedStateMachine->pointerUp(nestedPosition); + nestedStateMachine->pointerUp(nestedPosition, + pointerId); break; case ListenerType::move: hitResult = - nestedStateMachine->pointerMove(nestedPosition); + nestedStateMachine->pointerMove(nestedPosition, + timeStamp, + pointerId); + break; + case ListenerType::dragStart: + nestedStateMachine->dragStart(nestedPosition, + timeStamp, + pointerId); + break; + case ListenerType::dragEnd: + nestedStateMachine->dragEnd(nestedPosition, + timeStamp, + pointerId); break; - case ListenerType::enter: case ListenerType::exit: + hitResult = + nestedStateMachine->pointerExit(nestedPosition, + pointerId); + break; + case ListenerType::enter: case ListenerType::event: case ListenerType::click: - case ListenerType::draggableConstraint: + case ListenerType::componentProvided: + case ListenerType::textInput: + case ListenerType::viewModel: + case ListenerType::drag: + case ListenerType::focus: + case ListenerType::blur: + case ListenerType::keyboard: + case ListenerType::semanticAction: break; } } @@ -1066,13 +978,23 @@ class HitNestedArtboard : public HitComponent case ListenerType::down: case ListenerType::up: case ListenerType::move: - nestedStateMachine->pointerExit(nestedPosition); + case ListenerType::exit: + nestedStateMachine->pointerExit(nestedPosition, + pointerId); break; + case ListenerType::dragStart: + case ListenerType::dragEnd: case ListenerType::enter: - case ListenerType::exit: case ListenerType::event: case ListenerType::click: - case ListenerType::draggableConstraint: + case ListenerType::componentProvided: + case ListenerType::textInput: + case ListenerType::viewModel: + case ListenerType::drag: + case ListenerType::focus: + case ListenerType::blur: + case ListenerType::keyboard: + case ListenerType::semanticAction: break; } } @@ -1080,7 +1002,10 @@ class HitNestedArtboard : public HitComponent } return hitResult; } - void prepareEvent(Vec2D position, ListenerType hitType) override {} + void prepareEvent(Vec2D position, + ListenerType hitType, + int pointerId) override + {} }; class HitComponentList : public HitComponent @@ -1099,8 +1024,10 @@ class HitComponentList : public HitComponent { return false; } - for (int i = 0; i < componentList->artboardCount(); i++) + const auto& order = componentList->orderedListIndices(); + for (auto it = order.rbegin(); it != order.rend(); ++it) { + const int i = *it; Vec2D listPosition; if (!componentList->worldToLocal(position, &listPosition, i)) { @@ -1117,7 +1044,9 @@ class HitComponentList : public HitComponent } HitResult processEvent(Vec2D position, ListenerType hitType, - bool canHit) override + bool canHit, + float timeStamp, + int pointerId) override { auto componentList = m_component->as(); HitResult hitResult = HitResult::none; @@ -1126,8 +1055,10 @@ class HitComponentList : public HitComponent { return hitResult; } - for (int i = 0; i < componentList->artboardCount(); i++) + const auto& order = componentList->orderedListIndices(); + for (auto it = order.rbegin(); it != order.rend(); ++it) { + const int i = *it; Vec2D listPosition; bool hit = componentList->worldToLocal(position, &listPosition, i); if (!hit) @@ -1144,21 +1075,45 @@ class HitComponentList : public HitComponent { case ListenerType::down: itemHitResult = - stateMachine->pointerDown(listPosition); + stateMachine->pointerDown(listPosition, + pointerId); break; case ListenerType::up: itemHitResult = - stateMachine->pointerUp(listPosition); + stateMachine->pointerUp(listPosition, + pointerId); break; case ListenerType::move: itemHitResult = - stateMachine->pointerMove(listPosition); + stateMachine->pointerMove(listPosition, + timeStamp, + pointerId); break; - case ListenerType::enter: case ListenerType::exit: + itemHitResult = + stateMachine->pointerExit(listPosition, + pointerId); + break; + case ListenerType::dragStart: + stateMachine->dragStart(listPosition, + 0, + true, + pointerId); + break; + case ListenerType::dragEnd: + stateMachine->dragEnd(listPosition, 0, pointerId); + break; + case ListenerType::enter: case ListenerType::event: case ListenerType::click: - case ListenerType::draggableConstraint: + case ListenerType::componentProvided: + case ListenerType::textInput: + case ListenerType::viewModel: + case ListenerType::drag: + case ListenerType::focus: + case ListenerType::blur: + case ListenerType::keyboard: + case ListenerType::semanticAction: break; } } @@ -1169,13 +1124,22 @@ class HitComponentList : public HitComponent case ListenerType::down: case ListenerType::up: case ListenerType::move: - stateMachine->pointerExit(listPosition); + case ListenerType::exit: + stateMachine->pointerExit(listPosition, pointerId); break; + case ListenerType::dragStart: + case ListenerType::dragEnd: case ListenerType::enter: - case ListenerType::exit: case ListenerType::event: case ListenerType::click: - case ListenerType::draggableConstraint: + case ListenerType::componentProvided: + case ListenerType::textInput: + case ListenerType::viewModel: + case ListenerType::drag: + case ListenerType::focus: + case ListenerType::blur: + case ListenerType::keyboard: + case ListenerType::semanticAction: break; } } @@ -1195,39 +1159,261 @@ class HitComponentList : public HitComponent } return hitResult; } - void prepareEvent(Vec2D position, ListenerType hitType) override {} + void prepareEvent(Vec2D position, + ListenerType hitType, + int pointerId) override + {} }; -} // namespace rive +class ListenerViewModel; -HitResult StateMachineInstance::updateListeners(Vec2D position, - ListenerType hitType) +// Helper that holds one view model property reference, listens to its dirt, +// and reports the parent ListenerViewModel when the property changes. +class ListenerViewModelPropertyBinding : public ViewModelValueDependent { - if (m_artboardInstance->frameOrigin()) +public: + ListenerViewModelPropertyBinding(ListenerViewModel* parent, + ViewModelInstanceValue* vmProp); + virtual ~ListenerViewModelPropertyBinding(); + void addDirt(ComponentDirt value, bool recurse) override; + void relinkDataBind() override; + +protected: + ListenerViewModel* m_parent = nullptr; + rive::rcp m_viewModelInstanceValue = nullptr; + void clearDataContext(); +}; +class ListenerViewModelPropertyBindingListener + : public ListenerViewModelPropertyBinding +{ +public: + ListenerViewModelPropertyBindingListener( + ListenerViewModel* parent, + ViewModelInstanceValue* vmProp, + const StateMachineListenerSingle* listener); + void relinkDataBind() override; + +private: + const StateMachineListenerSingle* m_listener; +}; +class ListenerViewModelPropertyBindingInput + : public ListenerViewModelPropertyBinding +{ +public: + ListenerViewModelPropertyBindingInput( + ListenerViewModel* parent, + ViewModelInstanceValue* vmProp, + const ListenerInputTypeViewModel* listenerInput); + void relinkDataBind() override; + +private: + const ListenerInputTypeViewModel* m_listenerInput; +}; + +class ListenerViewModel +{ +public: + virtual ~ListenerViewModel(); + ListenerViewModel(StateMachineInstance* smInstance, + const StateMachineListener* listener) : + m_stateMachineInstance(smInstance), m_listener(listener) + {} + + void clearDataContext() { m_propertyBindings.clear(); } + void bindFromContext(rcp dataContext) { - position -= Vec2D( - m_artboardInstance->originX() * m_artboardInstance->layoutWidth(), - m_artboardInstance->originY() * m_artboardInstance->layoutHeight()); + m_dataContext = dataContext; + clearDataContext(); + if (m_listener->is()) + { + auto vmProp = dataContext->getViewModelProperty( + m_listener->as()->dataBindPath()); + if (vmProp != nullptr) + { + m_propertyBindings.push_back( + std::make_unique( + this, + vmProp, + m_listener->as())); + } + } + else + { + size_t index = 0; + while (index < m_listener->listenerInputTypeCount()) + { + auto listenerInputType = m_listener->listenerInputType(index); + if (listenerInputType->is()) + { + auto listenerInputTypeVM = + listenerInputType->as(); + auto vmProp = dataContext->getViewModelProperty( + listenerInputTypeVM->dataBindPath()); + if (vmProp != nullptr) + { + m_propertyBindings.push_back( + std::make_unique< + ListenerViewModelPropertyBindingInput>( + this, + vmProp, + listenerInputTypeVM)); + } + } + index++; + } + } + } + void reportToStateMachine(ViewModelInstanceValue* value) + { + if (!value->is() || + value->as()->propertyValue() != 0) + { + m_stateMachineInstance->reportListenerViewModel(this); + } + } + const StateMachineListener* listener() { return m_listener; } + DataContext* dataContext() + { + if (m_dataContext) + { + + return m_dataContext.get(); + } + return nullptr; + } + +private: + StateMachineInstance* m_stateMachineInstance = nullptr; + const StateMachineListener* m_listener = nullptr; + rcp m_dataContext = nullptr; + std::vector> + m_propertyBindings; +}; + +ListenerViewModelPropertyBinding::ListenerViewModelPropertyBinding( + ListenerViewModel* parent, + ViewModelInstanceValue* vmProp) : + m_parent(parent), m_viewModelInstanceValue(rive::ref_rcp(vmProp)) +{ + vmProp->addDependent(this); +} + +void ListenerViewModelPropertyBinding::relinkDataBind() {} + +ListenerViewModelPropertyBinding::~ListenerViewModelPropertyBinding() +{ + clearDataContext(); +} + +void ListenerViewModelPropertyBinding::clearDataContext() +{ + + if (m_viewModelInstanceValue != nullptr) + { + m_viewModelInstanceValue->removeDependent(this); + m_viewModelInstanceValue = nullptr; + } +} + +ListenerViewModelPropertyBindingListener:: + ListenerViewModelPropertyBindingListener( + ListenerViewModel* parent, + ViewModelInstanceValue* vmProp, + const StateMachineListenerSingle* listener) : + ListenerViewModelPropertyBinding(parent, vmProp), m_listener(listener) +{} + +void ListenerViewModelPropertyBindingListener::relinkDataBind() +{ + auto dataContext = m_parent->dataContext(); + if (dataContext) + { + + auto vmProp = + dataContext->getViewModelProperty(m_listener->dataBindPath()); + if (vmProp != m_viewModelInstanceValue.get()) + { + clearDataContext(); + if (vmProp != nullptr) + { + m_viewModelInstanceValue = ref_rcp(vmProp); + vmProp->addDependent(this); + } + } + } +} + +ListenerViewModelPropertyBindingInput::ListenerViewModelPropertyBindingInput( + ListenerViewModel* parent, + ViewModelInstanceValue* vmProp, + const ListenerInputTypeViewModel* listenerInput) : + ListenerViewModelPropertyBinding(parent, vmProp), + m_listenerInput(listenerInput) +{} + +void ListenerViewModelPropertyBindingInput::relinkDataBind() +{ + auto dataContext = m_parent->dataContext(); + if (dataContext) + { + auto vmProp = + dataContext->getViewModelProperty(m_listenerInput->dataBindPath()); + if (vmProp != m_viewModelInstanceValue.get()) + { + clearDataContext(); + if (vmProp != nullptr) + { + m_viewModelInstanceValue = ref_rcp(vmProp); + vmProp->addDependent(this); + } + } + } +} + +void ListenerViewModelPropertyBinding::addDirt(ComponentDirt value, + bool recurse) +{ + if (m_parent != nullptr && m_viewModelInstanceValue != nullptr) + { + m_parent->reportToStateMachine(m_viewModelInstanceValue.get()); + } +} + +ListenerViewModel::~ListenerViewModel() { clearDataContext(); } + +} // namespace rive + +HitResult StateMachineInstance::updateListeners(Vec2D position, + ListenerType hitType, + int pointerId, + float timeStamp) +{ + if (m_artboardInstance->frameOrigin()) + { + position -= Vec2D( + m_artboardInstance->originX() * m_artboardInstance->layoutWidth(), + m_artboardInstance->originY() * m_artboardInstance->layoutHeight()); } // First reset all listener groups before processing the events for (const auto& listenerGroup : m_listenerGroups) { - listenerGroup.get()->reset(); + listenerGroup.get()->reset(pointerId); } // Next prepare the event to set the common hover status for each group for (const auto& hitShape : m_hitComponents) { - hitShape->prepareEvent(position, hitType); + hitShape->prepareEvent(position, hitType, pointerId); } bool hitSomething = false; bool hitOpaque = false; - // Finally process the events + // Process the events for (const auto& hitShape : m_hitComponents) { - // TODO: quick reject. - - HitResult hitResult = - hitShape->processEvent(position, hitType, !hitOpaque); + HitResult hitResult = hitShape->processEvent(position, + hitType, + !hitOpaque, + timeStamp, + pointerId); if (hitResult != HitResult::none) { hitSomething = true; @@ -1237,6 +1423,15 @@ HitResult StateMachineInstance::updateListeners(Vec2D position, } } } + // Finally release events that are complete + if (hitType == ListenerType::exit) + { + for (const auto& listenerGroup : m_listenerGroups) + { + listenerGroup.get()->releaseEvent(pointerId); + } + } + return hitSomething ? hitOpaque ? HitResult::hitOpaque : HitResult::hit : HitResult::none; } @@ -1262,21 +1457,44 @@ bool StateMachineInstance::hitTest(Vec2D position) const return false; } -HitResult StateMachineInstance::pointerMove(Vec2D position) +HitResult StateMachineInstance::pointerMove(Vec2D position, + float timeStamp, + int id) { - return updateListeners(position, ListenerType::move); + return updateListeners(position, ListenerType::move, id, timeStamp); } -HitResult StateMachineInstance::pointerDown(Vec2D position) +HitResult StateMachineInstance::pointerDown(Vec2D position, int id) { - return updateListeners(position, ListenerType::down); + return updateListeners(position, ListenerType::down, id); } -HitResult StateMachineInstance::pointerUp(Vec2D position) +HitResult StateMachineInstance::pointerUp(Vec2D position, int id) { - return updateListeners(position, ListenerType::up); + return updateListeners(position, ListenerType::up, id); } -HitResult StateMachineInstance::pointerExit(Vec2D position) +HitResult StateMachineInstance::pointerExit(Vec2D position, int id) { - return updateListeners(position, ListenerType::exit); + return updateListeners(position, ListenerType::exit, id); +} +HitResult StateMachineInstance::dragStart(Vec2D position, + float timeStamp, + bool disablePointer, + int pointerId) +{ + if (disablePointer) + { + disablePointerEvents(pointerId); + } + auto hit = updateListeners(position, ListenerType::dragStart); + return hit; +} +HitResult StateMachineInstance::dragEnd(Vec2D position, + float timeStamp, + int pointerId) +{ + enablePointerEvents(pointerId); + auto hit = updateListeners(position, ListenerType::dragEnd); + pointerMove(position, timeStamp, pointerId); + return hit; } #ifdef TESTING @@ -1304,9 +1522,9 @@ void StateMachineInstance::addToHitLookup( auto itr = hitLookup.find(target); if (itr == hitLookup.end()) { - auto hs = rivestd::make_unique(target->as(), - this, - isOpaque); + auto hs = std::make_unique(target->as(), + this, + isOpaque); hitLookup[target] = hitLayout = hs.get(); m_hitComponents.push_back(std::move(hs)); } @@ -1331,7 +1549,7 @@ void StateMachineInstance::addToHitLookup( Shape* shape = target->as(); shape->addFlags(PathFlags::neverDeferUpdate); shape->addDirt(ComponentDirt::Path, true); - auto hs = rivestd::make_unique(shape, shape, this); + auto hs = std::make_unique(shape, shape, this); hitLookup[target] = hitShape = hs.get(); m_hitComponents.push_back(std::move(hs)); } @@ -1351,9 +1569,8 @@ void StateMachineInstance::addToHitLookup( { TextValueRun* run = target->as(); run->textComponent()->addDirt(ComponentDirt::Path, true); - auto hs = rivestd::make_unique(run->textComponent(), - run, - this); + auto hs = + std::make_unique(run->textComponent(), run, this); hitLookup[target] = hitTextRun = hs.get(); m_hitComponents.push_back(std::move(hs)); } @@ -1440,7 +1657,7 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, dataBindClone->converter( dataBind->converter()->clone()->as()); } - m_dataBinds.push_back(dataBindClone); + addDataBind(dataBindClone); if (dataBind->target()->is()) { auto bindableProperty = dataBind->target()->as(); @@ -1462,8 +1679,8 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, // We are only storing in this unordered map data binds that are // targetting the source. For now, this is only the case for // listener actions. - if (static_cast(dataBindClone->flags()) == - DataBindFlags::ToSource) + if ((static_cast(dataBindClone->flags()) & + DataBindFlags::ToSource) == DataBindFlags::ToSource) { m_bindableDataBindsToSource[bindablePropertyClone] = dataBindClone; @@ -1476,7 +1693,22 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, } else { - dataBindClone->target(dataBind->target()); + auto* originalTarget = dataBind->target(); + dataBindClone->target(originalTarget); + if (originalTarget->is()) + { + // Create a per-instance BindablePropertyNumber to + // receive the data-bound value instead of writing + // to the shared StateTransition. Swap the target + // and propertyKey so the normal apply() path writes + // to our instance-local property. + auto* prop = new BindablePropertyNumber(); + m_transitionPropertyInstances[originalTarget] + [dataBind->propertyKey()] = prop; + dataBindClone->target(prop); + dataBindClone->propertyKey( + BindablePropertyNumberBase::propertyValuePropertyKey); + } } } @@ -1487,77 +1719,175 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, for (std::size_t i = 0; i < machine->listenerCount(); i++) { auto listener = machine->listener(i); - if (listener->listenerType() == ListenerType::event) + if (listener->hasListener(ListenerType::event)) { continue; } - auto listenerGroup = rivestd::make_unique(listener); - auto target = m_artboardInstance->resolve(listener->targetId()); - if (target != nullptr && target->is()) + if (listener->hasListener(ListenerType::viewModel)) { - bool isLayoutComponent = false; - if (target->is()) + auto vmListener = new ListenerViewModel(this, listener); + m_listenerViewModels.push_back(vmListener); + continue; + } + // Handle focus/blur listeners - they're driven by FocusManager, + // not pointer events. + if (listener->hasListener(ListenerType::focus) || + listener->hasListener(ListenerType::blur)) + { + auto target = m_artboardInstance->resolve(listener->targetId()); + if (target != nullptr && target->is()) { - isLayoutComponent = true; - target = target->as()->proxy(); + auto node = target->as(); + // Find FocusData child of the node + FocusData* focusData = nullptr; + for (auto child : node->children()) + { + if (child->is()) + { + focusData = child->as(); + break; + } + } + if (focusData != nullptr) + { + auto focusGroup = + std::make_unique(focusData, + listener, + this); + m_focusListenerGroups.push_back(std::move(focusGroup)); + } + } + } + if (listener->hasListener(ListenerType::keyboard) || + listener->hasListener(ListenerType::textInput)) + { + auto target = m_artboardInstance->resolve(listener->targetId()); + if (target != nullptr && target->is()) + { + auto node = target->as(); + // Find FocusData child of the node + FocusData* focusData = nullptr; + for (auto child : node->children()) + { + if (child->is()) + { + focusData = child->as(); + break; + } + } + if (focusData != nullptr) + { + auto keyboardGroup = + std::make_unique(focusData, + listener, + this); + m_keyboardListenerGroups.push_back( + std::move(keyboardGroup)); + } + } + } + // Semantic listeners are driven by accessibility actions rather + // than pointer events. The editor enforces that the listener's + // target Node owns a SemanticData child directly; no ancestor + // walk is performed here. + if (listener->hasListener(ListenerType::semanticAction)) + { + auto target = m_artboardInstance->resolve(listener->targetId()); + if (target != nullptr && target->is()) + { + for (auto* child : target->as()->children()) + { + if (child->is()) + { + m_semanticListenerGroups.push_back( + std::make_unique( + child->as(), + listener, + this)); + break; + } + } } - addToHitLookup(target->as(), - isLayoutComponent, - hitLookup, - listenerGroup.get(), - false); } - m_listenerGroups.push_back(std::move(listenerGroup)); + + if (listener->hasListeners(kPointerHitListenerTypes)) + { + auto listenerGroup = std::make_unique(listener); + auto target = m_artboardInstance->resolve(listener->targetId()); + if (target != nullptr && target->is()) + { + bool isLayoutComponent = false; + if (target->is()) + { + isLayoutComponent = true; + target = target->as()->proxy(); + } + addToHitLookup(target->as(), + isLayoutComponent, + hitLookup, + listenerGroup.get(), + false); + } + m_listenerGroups.push_back(std::move(listenerGroup)); + } } - std::vector draggableConstraints; + std::vector componentProvidedListenerGroups; for (auto core : m_artboardInstance->objects()) { if (core == nullptr) { continue; } - if (core->is()) + auto provider = ListenerGroupProvider::from(core); + if (provider != nullptr) { - draggableConstraints.push_back(core->as()); + componentProvidedListenerGroups.push_back(provider); } } - for (auto constraint : draggableConstraints) + for (auto component : componentProvidedListenerGroups) { - auto draggables = constraint->draggables(); - for (auto dragProxy : draggables) + auto groupsWithTargets = component->listenerGroups(); + for (auto groupWithTargets : groupsWithTargets) { - auto listener = new StateMachineListener(); - listener->listenerTypeValue( - static_cast(ListenerType::draggableConstraint)); - auto listenerGroup = - rivestd::make_unique( - listener, - constraint, - dragProxy); - auto hittable = dragProxy->hittable(); - if (hittable != nullptr && hittable->is()) + auto group = groupWithTargets->group(); + auto targets = groupWithTargets->targets(); + for (auto target : targets) { - addToHitLookup(hittable->as(), - hittable->is() || - hittable->isProxy(), + auto component = target->component(); + bool isLayoutComponent = component->is() || + (component->is() && + component->as()->isProxy()); + addToHitLookup(target->component(), + isLayoutComponent, hitLookup, - listenerGroup.get(), - dragProxy->isOpaque()); + group, + target->isOpaque()); } - m_listenerGroups.push_back(std::move(listenerGroup)); + m_listenerGroups.push_back(std::unique_ptr(group)); + for (auto target : targets) + { + delete target; + } + delete groupWithTargets; + } + auto hitComponents = component->hitComponents(this); + for (auto* hitComponent : hitComponents) + { + m_hitComponents.push_back( + std::unique_ptr(hitComponent)); } } for (auto nestedArtboard : instance->nestedArtboards()) { - if (nestedArtboard->hasNestedStateMachines()) - { - auto hn = rivestd::make_unique( - nestedArtboard->as(), - this); - m_hitComponents.push_back(std::move(hn)); - } + // TODO: @hernan as an optimization only create a HitNestedArtboard if + // the nested artboard has state machines or if it is bound via data + // binding + auto hn = + std::make_unique(nestedArtboard->as(), + this); + m_hitComponents.push_back(std::move(hn)); for (auto animation : nestedArtboard->nestedAnimations()) { if (animation->is()) @@ -1582,17 +1912,103 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, } for (auto componentList : instance->artboardComponentLists()) { - auto hc = rivestd::make_unique( - componentList->as(), - this); + auto hc = + std::make_unique(componentList->as(), + this); m_hitComponents.push_back(std::move(hc)); } + +#ifdef WITH_RIVE_TEXT + // Register TextInputs as hit targets for drag-to-select functionality + for (auto textInput : instance->objects()) + { + auto textInputGroup = + std::make_unique(textInput, this); + auto hitExpandable = std::make_unique( + textInput->as(), + textInput->as(), + this, + true); // isOpaque - TextInput blocks hits behind it + hitExpandable->addListener(textInputGroup.get()); + m_hitComponents.push_back(std::move(hitExpandable)); + m_listenerGroups.push_back(std::move(textInputGroup)); + } +#endif + + // Initialize local instances of ScriptedObjects + for (auto& scriptedOb : machine->scriptedObjects()) + { + m_scriptedObjectsMap[scriptedOb] = + scriptedOb->cloneScriptedObject(this); + } + for (auto& scriptedPair : m_scriptedObjectsMap) + { + scriptedPair.second->dataContext(m_artboardInstance->dataContext()); + } + initScriptedObjects(); + // Register Scripted objects as keyboard and text targets when expected + for (auto object : instance->objects()) + { + auto scriptedObject = ScriptedObject::from(object); + if (scriptedObject && (scriptedObject->wantsKeyboardInput() || + scriptedObject->wantsTextInput())) + { + for (auto& child : object->as()->children()) + { + if (child->is()) + { + + auto keyboardGroup = + std::make_unique( + child->as(), + nullptr, + this); + m_keyboardListenerGroups.push_back( + std::move(keyboardGroup)); + break; + } + } + } + } sortHitComponents(); + + // Build the focus tree for this artboard. focusManager() returns the + // external manager if set (e.g., when Dart owns the manager at edit time), + // otherwise the internal one. For nested artboards that need a parent + // FocusNode, Dart should call buildFocusTreeWithParent() after init. + m_artboardInstance->buildFocusTree(focusManager(), nullptr); +} + +ScriptedObject* StateMachineInstance::scriptedObject( + const ScriptedObject* source) const +{ + auto itr = m_scriptedObjectsMap.find(source); + if (itr != m_scriptedObjectsMap.end()) + { + return itr->second; + } + return nullptr; } StateMachineInstance::~StateMachineInstance() { - clearDataContext(); + // Clean up focus tree BEFORE the internal FocusManager is destroyed. + // The artboard stores a raw pointer to our m_focusManager, so we must + // clear it before m_focusManager's implicit destruction at end of dtor. + if (m_externalFocusManager == nullptr && m_artboardInstance != nullptr) + { + m_artboardInstance->cleanupFocusTree(); + } + + // Clean up semantic tree BEFORE the internal SemanticManager is destroyed. + // Only needed when we own the manager; if external, the parent cleans up. + if (m_externalSemanticManager == nullptr && m_semanticManager != nullptr && + m_artboardInstance != nullptr) + { + m_artboardInstance->cleanupSemanticTree(); + } + + unbind(); for (auto inst : m_inputInstances) { delete inst; @@ -1601,21 +2017,76 @@ StateMachineInstance::~StateMachineInstance() { listenerGroup.reset(); } - for (auto databind : m_dataBinds) - { - delete databind; - } + deleteDataBinds(); delete[] m_layers; for (auto pair : m_bindablePropertyInstances) { delete pair.second; pair.second = nullptr; } - if (m_ownsDataContext) + for (auto& outer : m_transitionPropertyInstances) + { + for (auto& inner : outer.second) + { + delete inner.second; + } + } + m_transitionPropertyInstances.clear(); + for (auto& listenerViewModel : m_listenerViewModels) { - delete m_DataContext; + delete listenerViewModel; } m_bindablePropertyInstances.clear(); + for (auto& pair : m_scriptedObjectsMap) + { + delete pair.second; + pair.second = nullptr; + } + m_scriptedObjectsMap.clear(); +} + +// When a state machine instanced by a higher level runtime is destroyed, we +// need to clean up all its references from the nested artboard children. The +// reason is that the artboard might still be kept alive and it might have +// invalid pointers. This is not necessary for nested state machines because +// they are destroyed altogether. +void StateMachineInstance::dispose() { removeEventListeners(); } + +void StateMachineInstance::removeEventListeners() +{ + if (m_artboardInstance != nullptr) + { + for (auto nestedArtboard : m_artboardInstance->nestedArtboards()) + { + if (nestedArtboard == nullptr) + { + continue; + } + for (auto animation : nestedArtboard->nestedAnimations()) + { + if (animation == nullptr) + { + continue; + } + if (animation->is()) + { + if (auto notifier = animation->as() + ->stateMachineInstance()) + { + notifier->removeNestedEventListener(this); + } + } + else if (animation->is()) + { + if (auto notifier = animation->as() + ->animationInstance()) + { + notifier->removeNestedEventListener(this); + } + } + } + } + } } #ifdef WITH_RIVE_TOOLS @@ -1679,34 +2150,230 @@ void StateMachineInstance::sortHitComponents() } } -void StateMachineInstance::updateDataBinds() +bool StateMachineInstance::tryChangeState() +{ + updateDataBinds(false); + bool hasChangedState = false; + for (size_t i = 0; i < m_layerCount; i++) + { + if (m_layers[i].updateState()) + { + hasChangedState = true; + } + } + return hasChangedState; +} + +void StateMachineInstance::applyEvents() +{ + int maxIterations = 100; + int currentIteration = 0; + while ((m_reportedEvents.size() > 0 || + m_reportedListenerViewModels.size() > 0) && + currentIteration++ < maxIterations) + { + updateDataBinds(false); + m_reportingEvents = m_reportedEvents; + m_reportingListenerViewModels = m_reportedListenerViewModels; + m_reportedEvents.clear(); + m_reportedListenerViewModels.clear(); + this->notifyEventListeners(m_reportingEvents, nullptr); + this->notifyListenerViewModels(m_reportingListenerViewModels); + } + if (currentIteration >= maxIterations) + { + fprintf(stderr, + "%s StateMachine exceeded max event iterations" + "on artboard %s\n", + stateMachine()->name().c_str(), + artboard()->name().c_str()); + } +} + +void StateMachineInstance::setExternalFocusManager(FocusManager* manager) +{ + if (m_externalFocusManager == manager) + { + return; + } + + // Clean up old focus tree if one was built + if (m_artboardInstance != nullptr && + m_artboardInstance->focusManager() != nullptr) + { + m_artboardInstance->cleanupFocusTree(); + } + + m_externalFocusManager = manager; + + // Rebuild focus tree with new manager (focusManager() will return the new + // external manager if set, or internal if null) + if (m_artboardInstance != nullptr) + { + m_artboardInstance->buildFocusTree(focusManager(), nullptr); + } +} + +void StateMachineInstance::enableSemantics() { - for (auto dataBind : m_dataBinds) + if (semanticManager() != nullptr) { - auto d = dataBind->dirt(); - if (d != ComponentDirt::None) + return; + } + m_semanticManager = std::make_unique(); + if (m_artboardInstance != nullptr) + { + m_artboardInstance->buildSemanticTree(semanticManager(), nullptr); + } +} + +void StateMachineInstance::setExternalSemanticManager( + SemanticManager* manager, + rcp parentNode) +{ + if (m_externalSemanticManager == manager) + { + return; + } + + // Clean up the old semantic tree if one was built with a different manager. + if (m_artboardInstance != nullptr && + m_artboardInstance->semanticManager() != nullptr) + { + m_artboardInstance->cleanupSemanticTree(); + } + + m_externalSemanticManager = manager; + + // Rebuild with the new manager. semanticManager() now returns the external + // manager if set, or the internal one if null. + if (m_artboardInstance != nullptr) + { + m_artboardInstance->buildSemanticTree(semanticManager(), parentNode); + } +} + +void StateMachineInstance::queueFocusEvent(FocusListenerGroup* group, + bool isFocus) +{ + m_queuedFocusEvents.push_back({group, isFocus}); + m_needsAdvance = true; +} + +void StateMachineInstance::setFocus(FocusData* focusData) +{ + if (focusData != nullptr) + { + auto node = focusData->focusNode(); + auto* fm = focusManager(); + fm->setFocus(node); + } + else + { + focusManager()->clearFocus(); + } +} + +void StateMachineInstance::processFocusEvents() +{ + if (m_queuedFocusEvents.empty()) + { + return; + } + + auto events = std::move(m_queuedFocusEvents); + m_queuedFocusEvents.clear(); + + for (const auto& event : events) + { + auto listener = event.group->listener(); + bool isFocusEvent = event.isFocus; + + // Match listener type to event type + if ((isFocusEvent && listener->hasListener(ListenerType::focus)) || + (!isFocusEvent && listener->hasListener(ListenerType::blur))) { - dataBind->dirt(ComponentDirt::None); - dataBind->update(d); + listener->performChanges( + this, + ListenerInvocation::focus(event.group, event.isFocus)); } } } -bool StateMachineInstance::tryChangeState() +void StateMachineInstance::queueSemanticEvent(SemanticListenerGroup* group, + SemanticActionType actionType) { - bool hasChangedState = false; - for (size_t i = 0; i < m_layerCount; i++) + m_queuedSemanticEvents.push_back({group, actionType}); + m_needsAdvance = true; +} + +void StateMachineInstance::processSemanticEvents() +{ + if (m_queuedSemanticEvents.empty()) { - if (m_layers[i].updateState()) + return; + } + + auto events = std::move(m_queuedSemanticEvents); + m_queuedSemanticEvents.clear(); + + for (const auto& event : events) + { + if (event.group == nullptr) { - hasChangedState = true; + continue; + } + auto* listener = event.group->listener(); + if (listener == nullptr) + { + continue; } + listener->performChanges( + this, + ListenerInvocation::semantic(event.group, event.actionType)); + } +} + +void StateMachineInstance::fireSemanticAction(uint32_t semanticNodeId, + SemanticActionType actionType) +{ + // The unified SemanticManager indexes every SD in the tree — top-level, + // nested-artboard, and data-bound list items — so this lookup handles + // all dispatch targets uniformly. SemanticData::fire*() routes the + // event to listeners, which queue on their own owning state machine. + auto* mgr = semanticManager(); + if (mgr == nullptr) + { + return; + } + auto* node = mgr->nodeById(semanticNodeId); + if (node == nullptr) + { + return; + } + auto* sd = node->semanticData(); + if (sd == nullptr) + { + // Boundary nodes have no owning SemanticData. + return; + } + switch (actionType) + { + case SemanticActionType::tap: + sd->fireSemanticTap(); + break; + case SemanticActionType::increase: + sd->fireSemanticIncrease(); + break; + case SemanticActionType::decrease: + sd->fireSemanticDecrease(); + break; } - return hasChangedState; } bool StateMachineInstance::advance(float seconds, bool newFrame) { + RIVE_PROF_SCOPE() if (m_drawOrderChangeCounter != m_artboardInstance->drawOrderChangeCounter()) { @@ -1715,11 +2382,12 @@ bool StateMachineInstance::advance(float seconds, bool newFrame) } if (newFrame) { - this->notifyEventListeners(m_reportedEvents, nullptr); - m_reportedEvents.clear(); + processFocusEvents(); + processSemanticEvents(); + applyEvents(); m_needsAdvance = false; } - updateDataBinds(); + updateDataBinds(false); for (size_t i = 0; i < m_layerCount; i++) { if (m_layers[i].advance(seconds, newFrame)) @@ -1728,20 +2396,20 @@ bool StateMachineInstance::advance(float seconds, bool newFrame) } } - for (auto& dataBind : m_dataBinds) + if (advanceDataBinds(seconds)) { - if (dataBind->advance(seconds)) - { - m_needsAdvance = true; - } + m_needsAdvance = true; } - for (auto inst : m_inputInstances) + if (m_inputInstances.size() > 0) { - inst->advanced(); + for (auto inst : m_inputInstances) + { + inst->advanced(); + } } - - return m_needsAdvance || !m_reportedEvents.empty(); + return m_needsAdvance || !m_reportedEvents.empty() || + !m_reportedListenerViewModels.empty(); } void StateMachineInstance::advancedDataContext() @@ -1752,9 +2420,19 @@ void StateMachineInstance::advancedDataContext() } } +void StateMachineInstance::reset() +{ + advancedDataContext(); + m_artboardInstance->reset(); +} + bool StateMachineInstance::advanceAndApply(float seconds) { - bool keepGoing = this->advance(seconds, true); + RIVE_PROF_SCOPE_L(1) + // Advancing by 0 could return false, when it shouldn't. Force keepGoing + // to true. + bool keepGoing = this->advance(seconds, true) || seconds == 0.0f; + focusManager()->dropFocusIfFocusTargetHidden(); if (m_artboardInstance->advanceInternal( seconds, AdvanceFlags::IsRoot | AdvanceFlags::Animate | @@ -1784,19 +2462,28 @@ bool StateMachineInstance::advanceAndApply(float seconds) { keepGoing = true; } - advancedDataContext(); + reset(); if (!m_artboardInstance->hasDirt(ComponentDirt::Components)) { break; } } - return keepGoing || !m_reportedEvents.empty(); + return keepGoing || !m_reportedEvents.empty() || + !m_reportedListenerViewModels.empty(); } void StateMachineInstance::markNeedsAdvance() { m_needsAdvance = true; } bool StateMachineInstance::needsAdvance() const { return m_needsAdvance; } +void StateMachineInstance::resetState() +{ + for (size_t i = 0; i < m_layerCount; i++) + { + m_layers[i].resetState(); + } +} + std::string StateMachineInstance::name() const { return m_machine->name(); } SMIInput* StateMachineInstance::input(size_t index) const @@ -1839,43 +2526,101 @@ void StateMachineInstance::bindViewModelInstance( rcp viewModelInstance) { clearDataContext(); - m_ownsDataContext = true; - auto dataContext = new DataContext(viewModelInstance); + auto dataContext = make_rcp(viewModelInstance); + viewModelInstance->addDependent(this); m_artboardInstance->clearDataContext(); - m_artboardInstance->internalDataContext(dataContext, true); + m_artboardInstance->internalDataContext(dataContext); internalDataContext(dataContext); } -void StateMachineInstance::dataContext(DataContext* dataContext) +void StateMachineInstance::bindDataContext(rcp dataContext) { clearDataContext(); + if (dataContext->viewModelInstance()) + { + dataContext->viewModelInstance()->addDependent(this); + } + m_artboardInstance->clearDataContext(); + m_artboardInstance->internalDataContext(dataContext); internalDataContext(dataContext); } -void StateMachineInstance::internalDataContext(DataContext* dataContext) +void StateMachineInstance::dataContext(rcp dataContext) { - m_DataContext = dataContext; - for (auto dataBind : m_dataBinds) + clearDataContext(); + internalDataContext(dataContext); +} + +void StateMachineInstance::initScriptedObjects() +{ + for (auto obj : m_scriptedObjectsMap) { - if (dataBind->is()) + if (obj.second->scriptAsset() != nullptr) { - dataBind->as()->bindFromContext(dataContext); + if (!obj.second->userLuaInitDone()) + { + obj.second->scriptAsset()->initScriptedObject(obj.second); + } + obj.second->hydrateScriptInputs(); } } } +void StateMachineInstance::internalDataContext(rcp dataContext) +{ + m_DataContext = dataContext; + bindDataBindsFromContext(dataContext.get()); + for (auto listenerViewModel : m_listenerViewModels) + { + listenerViewModel->bindFromContext(dataContext); + } + for (auto& scriptedObjectItr : m_scriptedObjectsMap) + { + scriptedObjectItr.second->dataContext(dataContext); + } + initScriptedObjects(); +} + +void StateMachineInstance::rebind() +{ + m_artboardInstance->clearDataContext(); + m_artboardInstance->internalDataContext(m_DataContext); + internalDataContext(m_DataContext); +}; + void StateMachineInstance::clearDataContext() { - if (m_ownsDataContext && m_DataContext != nullptr) + if (m_DataContext) { - delete m_DataContext; + if (m_DataContext->viewModelInstance()) + { + m_DataContext->viewModelInstance()->removeDependent(this); + } m_DataContext = nullptr; } - for (auto dataBind : m_dataBinds) + for (auto& listenerViewModel : m_listenerViewModels) { - dataBind->unbind(); + listenerViewModel->clearDataContext(); } - m_ownsDataContext = false; +} + +void StateMachineInstance::relinkDataContext() +{ + m_artboardInstance->relinkDataContext(); +} + +void StateMachineInstance::rebuildDataBind(DataBind* dataBind) +{ + if (dataBind->is()) + { + dataBind->as()->bindFromContext(m_DataContext.get()); + } +}; + +void StateMachineInstance::unbind() +{ + clearDataContext(); + unbindDataBinds(); } size_t StateMachineInstance::stateChangedCount() const @@ -1944,6 +2689,12 @@ void StateMachineInstance::reportEvent(Event* event, float delaySeconds) m_reportedEvents.push_back(EventReport(event, delaySeconds)); } +void StateMachineInstance::reportListenerViewModel( + ListenerViewModel* listenerViewModel) +{ + m_reportedListenerViewModels.push_back(listenerViewModel); +} + std::size_t StateMachineInstance::reportedEventCount() const { return m_reportedEvents.size(); @@ -1962,7 +2713,21 @@ void StateMachineInstance::notify(const std::vector& events, NestedArtboard* context) { notifyEventListeners(events, context); - updateDataBinds(); + updateDataBinds(false); +} + +void StateMachineInstance::notifyListenerViewModels( + const std::vector& events) +{ + if (events.size() > 0) + { + for (auto& listenerViewModel : events) + { + listenerViewModel->listener()->performChanges( + this, + ListenerInvocation::viewModelChange(listenerViewModel)); + } + } } void StateMachineInstance::notifyEventListeners( @@ -1977,7 +2742,7 @@ void StateMachineInstance::notifyEventListeners( auto listener = m_machine->listener(i); auto target = artboard()->resolve(listener->targetId()); if (listener != nullptr && - listener->listenerType() == ListenerType::event && + listener->hasListener(ListenerType::event) && (source == nullptr || source == target)) { for (const auto event : events) @@ -1986,7 +2751,10 @@ void StateMachineInstance::notifyEventListeners( ? artboard() : source->artboardInstance(); - // listener->eventId() can point to an id from an + // NOTE: this issue can't happen anymore because a new + // fix in the editor prevents selecting other artboard + // as target. But the fix is kept here to fix older + // files. listener->eventId() can point to an id from an // event in the context of this artboard or the // context of a nested artboard. Because those ids // belong to different contexts, they can have the @@ -1999,18 +2767,58 @@ void StateMachineInstance::notifyEventListeners( // sure that a listener must be targetting the // current artboard to disambiguate between external // and internal events. - if (source == nullptr && - sourceArtboard->resolve(listener->targetId()) != - artboard()) + if (source == nullptr) { - continue; + auto target = + sourceArtboard->resolve(listener->targetId()); + if (target && target != artboard() && + !target->is()) + { + continue; + } } - auto listenerEvent = - sourceArtboard->resolve(listener->eventId()); - if (listenerEvent == event.event()) + if (listener->is()) { - listener->performChanges(this, Vec2D(), Vec2D()); - break; + auto listenerEvent = sourceArtboard->resolve( + listener->as() + ->eventId()); + if (listenerEvent == event.event()) + { + listener->performChanges( + this, + ListenerInvocation::reportedEvent( + event.event(), + event.secondsDelay())); + break; + } + } + else + { + size_t index = 0; + while (index < listener->listenerInputTypeCount()) + { + auto listenerInputType = + listener->listenerInputType(index); + if (listenerInputType->is()) + { + + auto listenerInputTypeEvent = + listenerInputType + ->as(); + auto listenerEvent = sourceArtboard->resolve( + listenerInputTypeEvent->eventId()); + if (listenerEvent == event.event()) + { + listener->performChanges( + this, + ListenerInvocation::reportedEvent( + event.event(), + event.secondsDelay())); + break; + } + } + index += 1; + } } } } @@ -2033,6 +2841,22 @@ void StateMachineInstance::notifyEventListeners( } } +void StateMachineInstance::enablePointerEvents(int pointerId) +{ + for (const auto& hitShape : m_hitComponents) + { + hitShape->enablePointerEvents(pointerId); + } +} + +void StateMachineInstance::disablePointerEvents(int pointerId) +{ + for (const auto& hitShape : m_hitComponents) + { + hitShape->disablePointerEvents(pointerId); + } +} + BindableProperty* StateMachineInstance::bindablePropertyInstance( BindableProperty* bindableProperty) const { @@ -2066,3 +2890,19 @@ DataBind* StateMachineInstance::bindableDataBindToTarget( } return dataBind->second; } + +BindablePropertyNumber* StateMachineInstance::findTransitionPropertyInstance( + const StateTransition* transition, + uint32_t propertyKey) const +{ + auto it = m_transitionPropertyInstances.find(transition); + if (it != m_transitionPropertyInstances.end()) + { + auto propIt = it->second.find(propertyKey); + if (propIt != it->second.end()) + { + return propIt->second; + } + } + return nullptr; +} diff --git a/thirdparty/rive/source/animation/state_machine_listener.cpp b/thirdparty/rive/source/animation/state_machine_listener.cpp index bc7cbaacc..78e99372b 100644 --- a/thirdparty/rive/source/animation/state_machine_listener.cpp +++ b/thirdparty/rive/source/animation/state_machine_listener.cpp @@ -6,17 +6,49 @@ #include "rive/shapes/shape.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/animation/listener_input_change.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" using namespace rive; StateMachineListener::StateMachineListener() {} StateMachineListener::~StateMachineListener() {} +bool StateMachineListener::hasListener(ListenerType listenerType) const +{ + for (auto& listenerInputType : m_listenerInputTypes) + { + if (listenerInputType->listenerTypeValue() == (int)listenerType) + { + return true; + } + } + return false; +} + +bool StateMachineListener::hasListeners( + Span listenerTypes) const +{ + for (auto listenerType : listenerTypes) + { + if (hasListener(listenerType)) + { + return true; + } + } + return false; +} + void StateMachineListener::addAction(std::unique_ptr action) { m_actions.push_back(std::move(action)); } +void StateMachineListener::addListenerInputType( + std::unique_ptr listenerInputType) +{ + m_listenerInputTypes.push_back(std::move(listenerInputType)); +} + StatusCode StateMachineListener::import(ImportStack& importStack) { auto stateMachineImporter = @@ -40,13 +72,22 @@ const ListenerAction* StateMachineListener::action(size_t index) const return nullptr; } +const ListenerInputType* StateMachineListener::listenerInputType( + size_t index) const +{ + if (index < m_listenerInputTypes.size()) + { + return m_listenerInputTypes[index].get(); + } + return nullptr; +} + void StateMachineListener::performChanges( StateMachineInstance* stateMachineInstance, - Vec2D position, - Vec2D previousPosition) const + const ListenerInvocation& invocation) const { for (auto& action : m_actions) { - action->perform(stateMachineInstance, position, previousPosition); + action->perform(stateMachineInstance, invocation); } } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/state_machine_listener_single.cpp b/thirdparty/rive/source/animation/state_machine_listener_single.cpp new file mode 100644 index 000000000..3fd4cf2a6 --- /dev/null +++ b/thirdparty/rive/source/animation/state_machine_listener_single.cpp @@ -0,0 +1,34 @@ +#include "rive/animation/state_machine_listener_single.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/state_machine_importer.hpp" +#include "rive/generated/animation/state_machine_base.hpp" +#include "rive/artboard.hpp" +#include "rive/shapes/shape.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/listener_input_change.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" + +using namespace rive; + +StatusCode StateMachineListenerSingle::import(ImportStack& importStack) +{ + importDataBindPath(importStack); + return Super::import(importStack); +} + +void StateMachineListenerSingle::decodeViewModelPathIds( + Span value) +{ + decodeDataBindPath(value); +} + +void StateMachineListenerSingle::copyViewModelPathIds( + const StateMachineListenerSingleBase& object) +{ + copyDataBindPath(object.as()->dataBindPath()); +} + +std::vector StateMachineListenerSingle::viewModelPathIdsBuffer() const +{ + return dataBindPath()->path(); +} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/text_input_listener_group.cpp b/thirdparty/rive/source/animation/text_input_listener_group.cpp new file mode 100644 index 000000000..d9daf513e --- /dev/null +++ b/thirdparty/rive/source/animation/text_input_listener_group.cpp @@ -0,0 +1,108 @@ +#include "rive/animation/text_input_listener_group.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/focus_data.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/input/focus_node.hpp" +#include "rive/text/text_input.hpp" + +using namespace rive; + +TextInputListenerGroup::TextInputListenerGroup( + TextInput* textInput, + StateMachineInstance* stateMachineInstance) : + // Pass nullptr for the listener - we won't use the base class's + // listener-based logic, just the click phase tracking + ListenerGroup(nullptr), m_textInput(textInput) +{} + +ProcessEventResult TextInputListenerGroup::processEvent( + Component* component, + Vec2D position, + int pointerId, + ListenerType hitEvent, + bool canHit, + float timeStamp, + StateMachineInstance* stateMachineInstance) +{ + // We implement our own click phase tracking instead of calling base class + // because base class processEvent accesses m_listener which is nullptr + auto* pData = pointerData(pointerId); + GestureClickPhase prevPhase = pData->phase; + + // Update hover state based on canHit + if (!canHit && pData->isHovered) + { + pData->isHovered = false; + } + + bool isGroupHovered = canHit ? pData->isHovered : false; + + // Update click phase + if (isGroupHovered) + { + if (hitEvent == ListenerType::down) + { + pData->phase = GestureClickPhase::down; + } + else if (hitEvent == ListenerType::up && + pData->phase == GestureClickPhase::down) + { + pData->phase = GestureClickPhase::clicked; + } + } + else + { + if (hitEvent == ListenerType::down || hitEvent == ListenerType::up) + { + pData->phase = GestureClickPhase::out; + } + } + + GestureClickPhase newPhase = pData->phase; + + // Handle drag start: pointer went down while hovering this text input + if (prevPhase != GestureClickPhase::down && + newPhase == GestureClickPhase::down) + { + m_textInput->startDrag(position); + m_isDragging = true; + + auto* manager = stateMachineInstance->focusManager(); + if (manager != nullptr) + { + for (auto* child : m_textInput->children()) + { + if (child->is()) + { + auto focusNode = child->as()->focusNode(); + if (focusNode != nullptr) + { + manager->setFocus(focusNode); + } + break; + } + } + } + return ProcessEventResult::scroll; + } + // Handle drag continue: pointer is moving while down + else if (hitEvent == ListenerType::move && + newPhase == GestureClickPhase::down && m_isDragging) + { + m_textInput->drag(position); + return ProcessEventResult::scroll; + } + // Handle drag end: pointer released or moved out while dragging + else if (prevPhase == GestureClickPhase::down && + (newPhase == GestureClickPhase::clicked || + newPhase == GestureClickPhase::out)) + { + if (m_isDragging) + { + m_textInput->endDrag(position); + m_isDragging = false; + } + } + + return ProcessEventResult::none; +} diff --git a/thirdparty/rive/source/animation/transition_comparator.cpp b/thirdparty/rive/source/animation/transition_comparator.cpp index b908a0a63..415eea888 100644 --- a/thirdparty/rive/source/animation/transition_comparator.cpp +++ b/thirdparty/rive/source/animation/transition_comparator.cpp @@ -16,119 +16,4 @@ StatusCode TransitionComparator::import(ImportStack& importStack) } transitionViewModelConditionImporter->setComparator(this); return Super::import(importStack); -} - -bool TransitionComparator::compareNumbers(float left, - float right, - TransitionConditionOp op) -{ - switch (op) - { - case TransitionConditionOp::equal: - return left == right; - case TransitionConditionOp::notEqual: - return left != right; - case TransitionConditionOp::lessThanOrEqual: - return left <= right; - case TransitionConditionOp::lessThan: - return left < right; - case TransitionConditionOp::greaterThanOrEqual: - return left >= right; - case TransitionConditionOp::greaterThan: - return left > right; - default: - return false; - } -} - -bool TransitionComparator::compareStrings(std::string left, - std::string right, - TransitionConditionOp op) -{ - switch (op) - { - case TransitionConditionOp::equal: - return left == right; - case TransitionConditionOp::notEqual: - return left != right; - default: - return false; - } -} - -bool TransitionComparator::compareBooleans(bool left, - bool right, - TransitionConditionOp op) -{ - switch (op) - { - case TransitionConditionOp::equal: - return left == right; - case TransitionConditionOp::notEqual: - return left != right; - default: - return false; - } -} - -bool TransitionComparator::compareEnums(uint16_t left, - uint16_t right, - TransitionConditionOp op) -{ - switch (op) - { - case TransitionConditionOp::equal: - return left == right; - case TransitionConditionOp::notEqual: - return left != right; - default: - return false; - } -} - -bool TransitionComparator::compareTriggers(uint32_t left, - uint32_t right, - TransitionConditionOp op) -{ - switch (op) - { - case TransitionConditionOp::equal: - return left == right; - case TransitionConditionOp::notEqual: - return left != right; - case TransitionConditionOp::lessThanOrEqual: - return left <= right; - case TransitionConditionOp::lessThan: - return left < right; - case TransitionConditionOp::greaterThanOrEqual: - return left >= right; - case TransitionConditionOp::greaterThan: - return left > right; - default: - return false; - } -} - -bool TransitionComparator::compareColors(int left, - int right, - TransitionConditionOp op) -{ - switch (op) - { - case TransitionConditionOp::equal: - return left == right; - case TransitionConditionOp::notEqual: - return left != right; - default: - return false; - } -} - -bool TransitionComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_property_artboard_comparator.cpp b/thirdparty/rive/source/animation/transition_property_artboard_comparator.cpp deleted file mode 100644 index 1b0d14c9c..000000000 --- a/thirdparty/rive/source/animation/transition_property_artboard_comparator.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "rive/animation/transition_property_artboard_comparator.hpp" -#include "rive/animation/transition_property_viewmodel_comparator.hpp" -#include "rive/animation/transition_value_number_comparator.hpp" -#include "rive/animation/artboard_property.hpp" -#include "rive/animation/state_machine_instance.hpp" -#include "rive/data_bind/bindable_property_number.hpp" - -using namespace rive; - -float TransitionPropertyArtboardComparator::propertyValue( - const StateMachineInstance* stateMachineInstance) -{ - auto artboard = stateMachineInstance->artboard(); - if (artboard != nullptr) - { - - auto property = static_cast(propertyType()); - switch (property) - { - case ArtboardProperty::width: - return artboard->layoutWidth(); - break; - case ArtboardProperty::height: - return artboard->layoutHeight(); - break; - case ArtboardProperty::ratio: - return artboard->layoutWidth() / artboard->layoutHeight(); - break; - - default: - break; - } - } - return 0; -} - -bool TransitionPropertyArtboardComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - auto value = propertyValue(stateMachineInstance); - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->value(stateMachineInstance); - return compareNumbers(value, rightValue, operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - return compareNumbers(value, rightValue, operation); - } - return false; -} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_property_viewmodel_comparator.cpp b/thirdparty/rive/source/animation/transition_property_viewmodel_comparator.cpp index 2e28f6573..3287059f0 100644 --- a/thirdparty/rive/source/animation/transition_property_viewmodel_comparator.cpp +++ b/thirdparty/rive/source/animation/transition_property_viewmodel_comparator.cpp @@ -1,12 +1,17 @@ #include "rive/animation/transition_property_viewmodel_comparator.hpp" +#include "rive/animation/transition_self_comparator.hpp" #include "rive/animation/transition_value_number_comparator.hpp" #include "rive/animation/transition_value_string_comparator.hpp" #include "rive/animation/transition_value_color_comparator.hpp" #include "rive/animation/transition_value_boolean_comparator.hpp" +#include "rive/animation/transition_value_asset_comparator.hpp" +#include "rive/animation/transition_value_artboard_comparator.hpp" #include "rive/animation/transition_value_enum_comparator.hpp" #include "rive/animation/transition_value_trigger_comparator.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/importers/bindable_property_importer.hpp" +#include "rive/data_bind/bindable_property_artboard.hpp" +#include "rive/data_bind/bindable_property_asset.hpp" #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/bindable_property_color.hpp" @@ -42,224 +47,6 @@ StatusCode TransitionPropertyViewModelComparator::import( return Super::import(importStack); } -float TransitionPropertyViewModelComparator::valueToFloat( - const StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = - stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - if (bindableInstance != nullptr) - { - if (bindableInstance->is()) - { - return (float)this->value( - stateMachineInstance); - } - else if (bindableInstance->is()) - { - return this->value( - stateMachineInstance); - } - } - return 0; -} - -bool TransitionPropertyViewModelComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - switch (m_bindableProperty->coreType()) - { - case BindablePropertyNumber::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->valueToFloat(stateMachineInstance); - return compareNumbers(valueToFloat(stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - return compareNumbers(valueToFloat(stateMachineInstance), - rightValue, - operation); - } - break; - case BindablePropertyString::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->value( - stateMachineInstance); - return compareStrings( - value( - stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - return compareStrings( - value( - stateMachineInstance), - rightValue, - operation); - } - break; - case BindablePropertyColor::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->value( - stateMachineInstance); - return compareColors( - value(stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - return compareColors( - value(stateMachineInstance), - rightValue, - operation); - } - break; - case BindablePropertyBoolean::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->value( - stateMachineInstance); - return compareBooleans( - value(stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - return compareBooleans( - value(stateMachineInstance), - rightValue, - operation); - } - break; - case BindablePropertyEnum::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->value( - stateMachineInstance); - return compareEnums( - value(stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - return compareEnums( - value(stateMachineInstance), - rightValue, - operation); - } - break; - case BindablePropertyTrigger::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->value( - stateMachineInstance); - return compareTriggers(value( - stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto bindableInstance = - stateMachineInstance->bindablePropertyInstance( - m_bindableProperty); - auto dataBind = stateMachineInstance->bindableDataBindToTarget( - bindableInstance); - if (dataBind != nullptr) - { - auto source = dataBind->source(); - if (source != nullptr && - source->is()) - { - if (source->as() - ->isUsedInLayer(layerInstance)) - { - - return false; - } - } - } - auto leftValue = value( - stateMachineInstance); - if (leftValue != 0) - { - return true; - } - } - break; - case BindablePropertyInteger::typeKey: - if (comparand->is()) - { - auto rightValue = - comparand->as() - ->valueToFloat(stateMachineInstance); - return compareNumbers(valueToFloat(stateMachineInstance), - rightValue, - operation); - } - else if (comparand->is()) - { - auto rightValue = - comparand->as()->value(); - switch (instanceDataType(stateMachineInstance)) - { - case DataType::number: - return compareNumbers( - valueToFloat(stateMachineInstance), - rightValue, - operation); - case DataType::integer: - { - - auto val = value( - stateMachineInstance); - return compareNumbers((float)val, - rightValue, - operation); - } - default: - break; - } - } - break; - } - return false; -} - void TransitionPropertyViewModelComparator::useInLayer( const StateMachineInstance* stateMachineInstance, StateMachineLayerInstance* layerInstance) const @@ -274,38 +61,8 @@ void TransitionPropertyViewModelComparator::useInLayer( auto dataBind = stateMachineInstance->bindableDataBindToTarget(bindableInstance); auto source = dataBind->source(); - if (source != nullptr && source->is()) - { - source->as()->useInLayer(layerInstance); - } -} - -DataType TransitionPropertyViewModelComparator::instanceDataType( - const StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = - stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - if (bindableInstance != nullptr) + if (source != nullptr) { - - switch (bindableInstance->coreType()) - { - case BindablePropertyNumberBase::typeKey: - - return DataType::number; - case BindablePropertyBooleanBase::typeKey: - return DataType::boolean; - case BindablePropertyColorBase::typeKey: - return DataType::color; - case BindablePropertyStringBase::typeKey: - return DataType::string; - case BindablePropertyEnumBase::typeKey: - return DataType::enumType; - case BindablePropertyTriggerBase::typeKey: - return DataType::trigger; - case BindablePropertyIntegerBase::typeKey: - return DataType::integer; - } + source->useInLayer(layerInstance); } - return DataType::none; } \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_value_boolean_comparator.cpp b/thirdparty/rive/source/animation/transition_value_boolean_comparator.cpp deleted file mode 100644 index 7d5488380..000000000 --- a/thirdparty/rive/source/animation/transition_value_boolean_comparator.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "rive/animation/transition_value_boolean_comparator.hpp" - -using namespace rive; - -bool TransitionValueBooleanComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - if (comparand->is()) - { - return compareBooleans( - value(), - comparand->as()->value(), - operation); - } - return false; -} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_value_color_comparator.cpp b/thirdparty/rive/source/animation/transition_value_color_comparator.cpp deleted file mode 100644 index 20ad28d3e..000000000 --- a/thirdparty/rive/source/animation/transition_value_color_comparator.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "rive/animation/transition_value_color_comparator.hpp" - -using namespace rive; - -bool TransitionValueColorComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - if (comparand->is()) - { - return compareColors( - value(), - comparand->as()->value(), - operation); - } - return false; -} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_value_enum_comparator.cpp b/thirdparty/rive/source/animation/transition_value_enum_comparator.cpp deleted file mode 100644 index 8742e37d6..000000000 --- a/thirdparty/rive/source/animation/transition_value_enum_comparator.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "rive/animation/transition_value_enum_comparator.hpp" -#include "rive/viewmodel/viewmodel_instance_enum.hpp" - -using namespace rive; \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_value_number_comparator.cpp b/thirdparty/rive/source/animation/transition_value_number_comparator.cpp deleted file mode 100644 index 5f4aa10e5..000000000 --- a/thirdparty/rive/source/animation/transition_value_number_comparator.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "rive/animation/transition_value_number_comparator.hpp" - -using namespace rive; - -bool TransitionValueNumberComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - if (comparand->is()) - { - return compareNumbers( - value(), - comparand->as()->value(), - operation); - } - return false; -} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_value_string_comparator.cpp b/thirdparty/rive/source/animation/transition_value_string_comparator.cpp deleted file mode 100644 index 5b6e85e1c..000000000 --- a/thirdparty/rive/source/animation/transition_value_string_comparator.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "rive/animation/transition_value_string_comparator.hpp" - -using namespace rive; - -bool TransitionValueStringComparator::compare( - TransitionComparator* comparand, - TransitionConditionOp operation, - const StateMachineInstance* stateMachineInstance, - StateMachineLayerInstance* layerInstance) -{ - if (comparand->is()) - { - return compareStrings( - value(), - comparand->as()->value(), - operation); - } - return false; -} \ No newline at end of file diff --git a/thirdparty/rive/source/animation/transition_viewmodel_condition.cpp b/thirdparty/rive/source/animation/transition_viewmodel_condition.cpp index ae564ffa0..2f00370ca 100644 --- a/thirdparty/rive/source/animation/transition_viewmodel_condition.cpp +++ b/thirdparty/rive/source/animation/transition_viewmodel_condition.cpp @@ -1,13 +1,994 @@ #include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_transition.hpp" +#include "rive/animation/transition_property_component_comparator.hpp" +#include "rive/artboard.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_color_type.hpp" +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_string_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/generated/core_registry.hpp" +#include "rive/generated/custom_property_enum_base.hpp" +#include "rive/generated/custom_property_trigger_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_asset_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_enum_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp" #include "rive/importers/state_transition_importer.hpp" #include "rive/importers/state_machine_importer.hpp" #include "rive/animation/state_machine.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/component_dirt.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" + +#include using namespace rive; +class ConditionComparisonNone : public ConditionComparison +{ +public: + ConditionComparisonNone() : ConditionComparison(nullptr) {} + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return false; + } +}; + +class ConditionComparisonSelf : public ConditionComparison +{ +public: + ConditionComparisonSelf(BindableProperty* property) : + ConditionComparison(nullptr), m_bindableProperty(property) + {} + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + auto dataBind = + stateMachineInstance->bindableDataBindToTarget(bindableInstance); + if (dataBind != nullptr) + { + auto source = dataBind->source(); + if (source != nullptr && source->hasChanged() && + !source->isUsedInLayer(layerInstance)) + { + return true; + } + } + return false; + } + +private: + BindableProperty* m_bindableProperty; +}; +class ConditionComparisonNumber : public ConditionComparison +{ +public: + ConditionComparisonNumber(ConditionComparandNumber* left, + ConditionComparandNumber* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonNumber() + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return compareNumbers(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandNumber* m_leftComparand = nullptr; + ConditionComparandNumber* m_rightComparand = nullptr; +}; +class ConditionComparisonBoolean : public ConditionComparison +{ +public: + ConditionComparisonBoolean(ConditionComparandBoolean* left, + ConditionComparandBoolean* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonBoolean() override + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return compareBooleans(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandBoolean* m_leftComparand = nullptr; + ConditionComparandBoolean* m_rightComparand = nullptr; +}; + +class ConditionComparisonString : public ConditionComparison +{ +public: + ConditionComparisonString(ConditionComparandString* left, + ConditionComparandString* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonString() + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return compareStrings(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandString* m_leftComparand = nullptr; + ConditionComparandString* m_rightComparand = nullptr; +}; + +class ConditionComparisonColor : public ConditionComparison +{ +public: + ConditionComparisonColor(ConditionComparandColor* left, + ConditionComparandColor* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonColor() + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return compareColors(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandColor* m_leftComparand = nullptr; + ConditionComparandColor* m_rightComparand = nullptr; +}; + +class ConditionComparisonEnum : public ConditionComparison +{ +public: + ConditionComparisonEnum(ConditionComparandUint32* left, + ConditionComparandUint32* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonEnum() + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return compareUints32(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandUint32* m_leftComparand = nullptr; + ConditionComparandUint32* m_rightComparand = nullptr; +}; + +class ConditionComparisonUint32 : public ConditionComparison +{ +public: + ConditionComparisonUint32(ConditionComparandUint32* left, + ConditionComparandUint32* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonUint32() + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return compareUints32(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandUint32* m_leftComparand = nullptr; + ConditionComparandUint32* m_rightComparand = nullptr; +}; + +class ConditionComparisonViewModel : public ConditionComparison +{ +public: + ConditionComparisonViewModel(ConditionComparandViewModel* left, + ConditionComparandViewModel* right, + ConditionOperation* operation) : + ConditionComparison(operation), + m_leftComparand(left), + m_rightComparand(right) + {} + ~ConditionComparisonViewModel() + { + delete m_leftComparand; + delete m_rightComparand; + } + bool compare(const StateMachineInstance* stateMachineInstance, + StateMachineLayerInstance* layerInstance) override + { + return comparePointers(m_leftComparand->value(stateMachineInstance), + m_rightComparand->value(stateMachineInstance)); + } + +private: + ConditionComparandViewModel* m_leftComparand = nullptr; + ConditionComparandViewModel* m_rightComparand = nullptr; +}; + +namespace +{ + +Core* resolveComponentTarget(const StateMachineInstance* smi, + const TransitionPropertyComponentComparator* comp) +{ + if (smi == nullptr || comp == nullptr) + { + return nullptr; + } + Artboard* artboard = smi->artboard(); + if (artboard == nullptr) + { + return nullptr; + } + Core* target = artboard->resolve(comp->objectId()); + if (target == nullptr || + !CoreRegistry::objectSupportsProperty(target, comp->propertyKey())) + { + return nullptr; + } + return target; +} + +enum class ComponentComparandKind +{ + NumberDouble, + NumberFromUint, + Boolean, + String, + Color, + Enum, + Trigger, + Asset, + Artboard, + ViewModel, +}; + +bool describeComponentSide(const TransitionPropertyComponentComparator* comp, + ComponentComparandKind* outKind) +{ + int fieldId = CoreRegistry::propertyFieldId((int)comp->propertyKey()); + if (fieldId < 0) + { + return false; + } + const uint32_t pk = comp->propertyKey(); + switch (fieldId) + { + case CoreDoubleType::id: + *outKind = ComponentComparandKind::NumberDouble; + return true; + case CoreBoolType::id: + *outKind = ComponentComparandKind::Boolean; + return true; + case CoreStringType::id: + *outKind = ComponentComparandKind::String; + return true; + case CoreColorType::id: + *outKind = ComponentComparandKind::Color; + return true; + case CoreUintType::id: + if (pk == CustomPropertyEnumBase::propertyValuePropertyKey || + pk == ViewModelInstanceEnumBase::propertyValuePropertyKey) + { + *outKind = ComponentComparandKind::Enum; + return true; + } + if (pk == CustomPropertyTriggerBase::propertyValuePropertyKey || + pk == ViewModelInstanceTriggerBase::propertyValuePropertyKey) + { + *outKind = ComponentComparandKind::Trigger; + return true; + } + if (pk == ViewModelInstanceAssetBase::propertyValuePropertyKey) + { + *outKind = ComponentComparandKind::Asset; + return true; + } + if (pk == ViewModelInstanceArtboardBase::propertyValuePropertyKey) + { + *outKind = ComponentComparandKind::Artboard; + return true; + } + if (pk == ViewModelInstanceViewModelBase::propertyValuePropertyKey) + { + *outKind = ComponentComparandKind::ViewModel; + return true; + } + *outKind = ComponentComparandKind::NumberFromUint; + return true; + default: + return false; + } +} + +bool componentKindsCompatible(ComponentComparandKind a, + ComponentComparandKind b) +{ + auto isNumberKind = [](ComponentComparandKind k) { + return k == ComponentComparandKind::NumberDouble || + k == ComponentComparandKind::NumberFromUint; + }; + if (isNumberKind(a) && isNumberKind(b)) + { + return true; + } + return a == b; +} + +ConditionComparandNumber* makeComponentNumberComparand( + TransitionPropertyComponentComparator* comp, + ComponentComparandKind kind) +{ + if (kind == ComponentComparandKind::NumberDouble) + { + return new ConditionComparandComponentCoreNumber(comp); + } + return new ConditionComparandComponentCoreUintAsNumber(comp); +} + +bool describeViewModelBindableKind(BindableProperty* bindable, + ComponentComparandKind* outKind) +{ + if (bindable == nullptr) + { + return false; + } + switch (bindable->coreType()) + { + case BindablePropertyNumber::typeKey: + *outKind = ComponentComparandKind::NumberDouble; + return true; + case BindablePropertyInteger::typeKey: + *outKind = ComponentComparandKind::NumberFromUint; + return true; + case BindablePropertyBoolean::typeKey: + *outKind = ComponentComparandKind::Boolean; + return true; + case BindablePropertyString::typeKey: + *outKind = ComponentComparandKind::String; + return true; + case BindablePropertyColor::typeKey: + *outKind = ComponentComparandKind::Color; + return true; + case BindablePropertyEnum::typeKey: + *outKind = ComponentComparandKind::Enum; + return true; + case BindablePropertyTrigger::typeKey: + *outKind = ComponentComparandKind::Trigger; + return true; + case BindablePropertyAsset::typeKey: + *outKind = ComponentComparandKind::Asset; + return true; + case BindablePropertyArtboard::typeKey: + *outKind = ComponentComparandKind::Artboard; + return true; + case BindablePropertyViewModel::typeKey: + *outKind = ComponentComparandKind::ViewModel; + return true; + default: + return false; + } +} + +enum class ComparatorSide +{ + Left, + Right, +}; + +// Artboard properties and literal values only participate on the left / right +// respectively (matches historical initialize() support). +void appendComparableKinds(TransitionComparator* comparator, + ComparatorSide side, + std::vector& out) +{ + if (comparator->is()) + { + if (side == ComparatorSide::Left) + { + out.push_back(ComponentComparandKind::NumberDouble); + } + return; + } + if (comparator->is()) + { + ComponentComparandKind k; + if (describeComponentSide( + comparator->as(), + &k)) + { + out.push_back(k); + } + return; + } + if (comparator->is()) + { + ComponentComparandKind k; + if (describeViewModelBindableKind( + comparator->as() + ->bindableProperty(), + &k)) + { + out.push_back(k); + } + return; + } + if (side != ComparatorSide::Right) + { + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::NumberDouble); + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::Boolean); + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::String); + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::Color); + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::Enum); + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::Asset); + return; + } + if (comparator->is()) + { + out.push_back(ComponentComparandKind::Artboard); + return; + } + // Uint32 comparison vs component triggers; VM trigger + value trigger uses + // ConditionComparisonSelf and is handled before kind intersection. + if (comparator->is()) + { + out.push_back(ComponentComparandKind::Trigger); + return; + } +} + +// Picks the first (lk, rk) pair such that componentKindsCompatible(lk, rk), +// scanning leftKinds in order then rightKinds (deterministic tie-break). +bool intersectCompatibleKinds( + const std::vector& leftKinds, + const std::vector& rightKinds, + ComponentComparandKind* outLeftKind, + ComponentComparandKind* outRightKind) +{ + for (ComponentComparandKind lk : leftKinds) + { + for (ComponentComparandKind rk : rightKinds) + { + if (componentKindsCompatible(lk, rk)) + { + *outLeftKind = lk; + *outRightKind = rk; + return true; + } + } + } + return false; +} + +enum class ComparisonShape +{ + Number, + Boolean, + String, + Color, + Enum, + Uint32, + ViewModel, +}; + +// Maps compatible kinds to ConditionComparison wrapper. Numeric: any +// NumberDouble in the pair uses float compare (Number); both NumberFromUint +// uses exact uint32 compare (Uint32), including component+component generic +// uint fields and VM integer pairs. +bool resolveComparisonShape(ComponentComparandKind lk, + ComponentComparandKind rk, + ComparisonShape* outShape) +{ + if (!componentKindsCompatible(lk, rk)) + { + return false; + } + auto isNumberKind = [](ComponentComparandKind k) { + return k == ComponentComparandKind::NumberDouble || + k == ComponentComparandKind::NumberFromUint; + }; + if (isNumberKind(lk) && isNumberKind(rk)) + { + if (lk == ComponentComparandKind::NumberFromUint && + rk == ComponentComparandKind::NumberFromUint) + { + *outShape = ComparisonShape::Uint32; + return true; + } + *outShape = ComparisonShape::Number; + return true; + } + if (lk != rk) + { + return false; + } + switch (lk) + { + case ComponentComparandKind::Boolean: + *outShape = ComparisonShape::Boolean; + return true; + case ComponentComparandKind::String: + *outShape = ComparisonShape::String; + return true; + case ComponentComparandKind::Color: + *outShape = ComparisonShape::Color; + return true; + case ComponentComparandKind::Enum: + *outShape = ComparisonShape::Enum; + return true; + case ComponentComparandKind::Trigger: + case ComponentComparandKind::Asset: + case ComponentComparandKind::Artboard: + *outShape = ComparisonShape::Uint32; + return true; + case ComponentComparandKind::ViewModel: + *outShape = ComparisonShape::ViewModel; + return true; + default: + return false; + } +} + +struct ComparandSlot +{ + ConditionComparandNumber* number = nullptr; + ConditionComparandBoolean* boolean = nullptr; + ConditionComparandString* string = nullptr; + ConditionComparandColor* color = nullptr; + ConditionComparandUint32* uint32 = nullptr; + ConditionComparandViewModel* viewModel = nullptr; +}; + +void clearComparandSlot(ComparandSlot& s) +{ + delete s.number; + delete s.boolean; + delete s.string; + delete s.color; + delete s.uint32; + delete s.viewModel; + s = ComparandSlot{}; +} + +// Builds one comparand for `c` and kind `k` given the resolved comparison. +bool makeComparand(TransitionComparator* c, + ComponentComparandKind k, + ComparisonShape shape, + ComparandSlot* slot) +{ + switch (shape) + { + case ComparisonShape::Number: + { + if (c->is()) + { + slot->number = new ConditionComparandArtboardProperty( + c->as()); + return true; + } + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr) + { + return false; + } + if (bp->is()) + { + slot->number = new ConditionComparandNumberBindable( + bp->as()); + return true; + } + if (bp->is()) + { + slot->number = new ConditionComparandNumberBindableInteger( + bp->as()); + return true; + } + return false; + } + if (c->is()) + { + slot->number = new ConditionComparandNumberValue( + c->as()); + return true; + } + if (c->is()) + { + auto* comp = c->as(); + if (k == ComponentComparandKind::NumberDouble) + { + slot->number = + new ConditionComparandComponentCoreNumber(comp); + return true; + } + if (k == ComponentComparandKind::NumberFromUint) + { + slot->number = makeComponentNumberComparand(comp, k); + return true; + } + return false; + } + return false; + } + case ComparisonShape::Boolean: + { + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr || !bp->is()) + { + return false; + } + slot->boolean = new ConditionComparandBooleanBindable( + bp->as()); + return true; + } + if (c->is()) + { + slot->boolean = new ConditionComparandBooleanValue( + c->as()); + return true; + } + if (c->is()) + { + slot->boolean = new ConditionComparandComponentCoreBoolean( + c->as()); + return true; + } + return false; + } + case ComparisonShape::String: + { + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr || !bp->is()) + { + return false; + } + slot->string = new ConditionComparandStringBindable( + bp->as()); + return true; + } + if (c->is()) + { + slot->string = new ConditionComparandStringValue( + c->as()); + return true; + } + if (c->is()) + { + slot->string = new ConditionComparandComponentCoreString( + c->as()); + return true; + } + return false; + } + case ComparisonShape::Color: + { + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr || !bp->is()) + { + return false; + } + slot->color = new ConditionComparandColorBindable( + bp->as()); + return true; + } + if (c->is()) + { + slot->color = new ConditionComparandColorValue( + c->as()); + return true; + } + if (c->is()) + { + slot->color = new ConditionComparandComponentCoreColor( + c->as()); + return true; + } + return false; + } + case ComparisonShape::Enum: + { + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr || !bp->is()) + { + return false; + } + slot->uint32 = new ConditionComparandEnumBindable( + bp->as()); + return true; + } + if (c->is()) + { + slot->uint32 = new ConditionComparandEnumValue( + c->as()); + return true; + } + if (c->is()) + { + slot->uint32 = new ConditionComparandComponentCoreUint( + c->as()); + return true; + } + return false; + } + case ComparisonShape::Uint32: + { + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr) + { + return false; + } + if (k == ComponentComparandKind::NumberFromUint && + bp->is()) + { + slot->uint32 = new ConditionComparandIntegerBindable( + bp->as()); + return true; + } + if (k == ComponentComparandKind::Trigger && + bp->is()) + { + slot->uint32 = new ConditionComparandTriggerBindable( + bp->as()); + return true; + } + if (k == ComponentComparandKind::Asset && + bp->is()) + { + slot->uint32 = new ConditionComparandAssetBindable( + bp->as()); + return true; + } + if (k == ComponentComparandKind::Artboard && + bp->is()) + { + slot->uint32 = new ConditionComparandArtboardBindable( + bp->as()); + return true; + } + return false; + } + if (c->is()) + { + slot->uint32 = new ConditionComparandTriggerValue( + c->as()); + return true; + } + if (c->is()) + { + slot->uint32 = new ConditionComparandAssetValue( + c->as()); + return true; + } + if (c->is()) + { + slot->uint32 = new ConditionComparandArtboardValue( + c->as()); + return true; + } + if (c->is()) + { + slot->uint32 = new ConditionComparandComponentCoreUint( + c->as()); + return true; + } + return false; + } + case ComparisonShape::ViewModel: + { + if (k != ComponentComparandKind::ViewModel) + { + return false; + } + if (c->is()) + { + auto* bp = c->as() + ->bindableProperty(); + if (bp == nullptr || !bp->is()) + { + return false; + } + slot->viewModel = new ConditionComparandViewModelBindable( + bp->as()); + return true; + } + return false; + } + default: + return false; + } +} + +ConditionComparison* wrapComparison(ComparisonShape shape, + ComparandSlot& leftSlot, + ComparandSlot& rightSlot, + ConditionOperation* op) +{ + switch (shape) + { + case ComparisonShape::Number: + if (leftSlot.number == nullptr || rightSlot.number == nullptr) + { + return nullptr; + } + return new ConditionComparisonNumber(leftSlot.number, + rightSlot.number, + op); + case ComparisonShape::Boolean: + if (leftSlot.boolean == nullptr || rightSlot.boolean == nullptr) + { + return nullptr; + } + return new ConditionComparisonBoolean(leftSlot.boolean, + rightSlot.boolean, + op); + case ComparisonShape::String: + if (leftSlot.string == nullptr || rightSlot.string == nullptr) + { + return nullptr; + } + return new ConditionComparisonString(leftSlot.string, + rightSlot.string, + op); + case ComparisonShape::Color: + if (leftSlot.color == nullptr || rightSlot.color == nullptr) + { + return nullptr; + } + return new ConditionComparisonColor(leftSlot.color, + rightSlot.color, + op); + case ComparisonShape::Enum: + if (leftSlot.uint32 == nullptr || rightSlot.uint32 == nullptr) + { + return nullptr; + } + return new ConditionComparisonEnum(leftSlot.uint32, + rightSlot.uint32, + op); + case ComparisonShape::Uint32: + if (leftSlot.uint32 == nullptr || rightSlot.uint32 == nullptr) + { + return nullptr; + } + return new ConditionComparisonUint32(leftSlot.uint32, + rightSlot.uint32, + op); + case ComparisonShape::ViewModel: + if (leftSlot.viewModel == nullptr || rightSlot.viewModel == nullptr) + { + return nullptr; + } + return new ConditionComparisonViewModel(leftSlot.viewModel, + rightSlot.viewModel, + op); + default: + return nullptr; + } +} + +bool buildComparandsFromIntersect(TransitionComparator* left, + TransitionComparator* right, + ComponentComparandKind lk, + ComponentComparandKind rk, + ConditionOperation* op, + ConditionComparison** outComparison) +{ + ComparisonShape shape; + if (!resolveComparisonShape(lk, rk, &shape)) + { + return false; + } + ComparandSlot leftSlot, rightSlot; + if (!makeComparand(left, lk, shape, &leftSlot) || + !makeComparand(right, rk, shape, &rightSlot)) + { + clearComparandSlot(leftSlot); + clearComparandSlot(rightSlot); + return false; + } + ConditionComparison* wrapped = + wrapComparison(shape, leftSlot, rightSlot, op); + if (wrapped == nullptr) + { + clearComparandSlot(leftSlot); + clearComparandSlot(rightSlot); + return false; + } + *outComparison = wrapped; + return true; +} + +} // namespace + TransitionViewModelCondition::~TransitionViewModelCondition() { if (m_leftComparator != nullptr) @@ -20,18 +1001,36 @@ TransitionViewModelCondition::~TransitionViewModelCondition() delete m_rightComparator; m_rightComparator = nullptr; } + if (m_comparison != nullptr) + { + delete m_comparison; + m_comparison = nullptr; + } +} + +bool TransitionViewModelCondition::canEvaluate( + const StateMachineInstance* stateMachineInstance) const +{ + if (!leftComparator() || !rightComparator()) + { + return false; + } + if (!stateMachineInstance->dataContext() && + (rightComparator()->is() || + leftComparator()->is())) + { + return false; + } + return true; } bool TransitionViewModelCondition::evaluate( const StateMachineInstance* stateMachineInstance, StateMachineLayerInstance* layerInstance) const { - if (leftComparator() != nullptr && rightComparator() != nullptr) + if (canEvaluate(stateMachineInstance) && m_comparison != nullptr) { - return leftComparator()->compare(rightComparator(), - op(), - stateMachineInstance, - layerInstance); + return m_comparison->compare(stateMachineInstance, layerInstance); } return false; } @@ -45,4 +1044,220 @@ void TransitionViewModelCondition::useInLayer( return leftComparator()->useInLayer(stateMachineInstance, layerInstance); } +} + +ConditionOperation* TransitionViewModelCondition::operation( + TransitionConditionOp op) +{ + switch (op) + { + case TransitionConditionOp::equal: + return new ConditionOperationEqual(); + case TransitionConditionOp::notEqual: + return new ConditionOperationNotEqual(); + case TransitionConditionOp::lessThanOrEqual: + return new ConditionOperationLessThanOrEqual(); + case TransitionConditionOp::lessThan: + return new ConditionOperationLessThan(); + case TransitionConditionOp::greaterThanOrEqual: + return new ConditionOperationGreaterThanOrEqual(); + case TransitionConditionOp::greaterThan: + return new ConditionOperationGreaterThan(); + } + return new ConditionOperation(); +} + +void TransitionViewModelCondition::initialize() +{ + TransitionComparator* left = leftComparator(); + TransitionComparator* right = rightComparator(); + if (left == nullptr || right == nullptr) + { + return; + } + + // Asymmetric: Self compares the left bindable against its data bind source, + // not a typed comparand intersection. + if (right->is()) + { + if (left->is()) + { + auto* leftBindable = + left->as() + ->bindableProperty(); + if (leftBindable != nullptr) + { + m_comparison = new ConditionComparisonSelf(leftBindable); + return; + } + } + m_comparison = new ConditionComparisonNone(); + return; + } + + // Asymmetric: value trigger on the right uses ConditionComparisonSelf with + // a VM trigger on the left (not uint32 vs a value comparand). + if (left->is() && + right->is()) + { + auto* lbp = left->as() + ->bindableProperty(); + if (lbp != nullptr && lbp->is()) + { + m_comparison = new ConditionComparisonSelf(lbp); + return; + } + } + + std::vector leftKinds; + std::vector rightKinds; + appendComparableKinds(left, ComparatorSide::Left, leftKinds); + appendComparableKinds(right, ComparatorSide::Right, rightKinds); + + ComponentComparandKind lk{}; + ComponentComparandKind rk{}; + if (!intersectCompatibleKinds(leftKinds, rightKinds, &lk, &rk)) + { + m_comparison = new ConditionComparisonNone(); + return; + } + + ConditionOperation* condOp = operation(op()); + ConditionComparison* cmp = nullptr; + if (buildComparandsFromIntersect(left, right, lk, rk, condOp, &cmp)) + { + m_comparison = cmp; + return; + } + delete condOp; + m_comparison = new ConditionComparisonNone(); +} + +ConditionComparandComponentCoreNumber::ConditionComparandComponentCoreNumber( + TransitionPropertyComponentComparator* comparator) : + m_comparator(comparator) +{} + +float ConditionComparandComponentCoreNumber::value( + const StateMachineInstance* stateMachineInstance) +{ + Core* target = resolveComponentTarget(stateMachineInstance, m_comparator); + if (target == nullptr) + { + return 0.0f; + } + return CoreRegistry::getDouble(target, (int)m_comparator->propertyKey()); +} + +ConditionComparandComponentCoreUintAsNumber:: + ConditionComparandComponentCoreUintAsNumber( + TransitionPropertyComponentComparator* comparator) : + m_comparator(comparator) +{} + +float ConditionComparandComponentCoreUintAsNumber::value( + const StateMachineInstance* stateMachineInstance) +{ + Core* target = resolveComponentTarget(stateMachineInstance, m_comparator); + if (target == nullptr) + { + return 0.0f; + } + return (float)CoreRegistry::getUint(target, + (int)m_comparator->propertyKey()); +} + +ConditionComparandComponentCoreBoolean::ConditionComparandComponentCoreBoolean( + TransitionPropertyComponentComparator* comparator) : + m_comparator(comparator) +{} + +bool ConditionComparandComponentCoreBoolean::value( + const StateMachineInstance* stateMachineInstance) +{ + Core* target = resolveComponentTarget(stateMachineInstance, m_comparator); + if (target == nullptr) + { + return false; + } + return CoreRegistry::getBool(target, (int)m_comparator->propertyKey()); +} + +ConditionComparandComponentCoreString::ConditionComparandComponentCoreString( + TransitionPropertyComponentComparator* comparator) : + m_comparator(comparator) +{} + +std::string ConditionComparandComponentCoreString::value( + const StateMachineInstance* stateMachineInstance) +{ + Core* target = resolveComponentTarget(stateMachineInstance, m_comparator); + if (target == nullptr) + { + return std::string{}; + } + return CoreRegistry::getString(target, (int)m_comparator->propertyKey()); +} + +ConditionComparandComponentCoreColor::ConditionComparandComponentCoreColor( + TransitionPropertyComponentComparator* comparator) : + m_comparator(comparator) +{} + +int ConditionComparandComponentCoreColor::value( + const StateMachineInstance* stateMachineInstance) +{ + Core* target = resolveComponentTarget(stateMachineInstance, m_comparator); + if (target == nullptr) + { + return 0; + } + return CoreRegistry::getColor(target, (int)m_comparator->propertyKey()); +} + +ConditionComparandComponentCoreUint::ConditionComparandComponentCoreUint( + TransitionPropertyComponentComparator* comparator) : + m_comparator(comparator) +{} + +uint32_t ConditionComparandComponentCoreUint::value( + const StateMachineInstance* stateMachineInstance) +{ + Core* target = resolveComponentTarget(stateMachineInstance, m_comparator); + if (target == nullptr) + { + return 0; + } + return CoreRegistry::getUint(target, (int)m_comparator->propertyKey()); +} + +bool ConditionComparison::compareNumbers(float left, float right) +{ + return m_operation->compareNumbers(left, right); +} + +bool ConditionComparison::compareStrings(const std::string& left, + const std::string& right) +{ + return m_operation->compareStrings(left, right); +} + +bool ConditionComparison::compareBooleans(bool left, bool right) +{ + return m_operation->compareBooleans(left, right); +} + +bool ConditionComparison::compareColors(int left, int right) +{ + return m_operation->compareInts(left, right); +} + +bool ConditionComparison::compareUints32(uint32_t left, uint32_t right) +{ + return m_operation->compareUints32(left, right); +} + +bool ConditionComparison::comparePointers(const void* left, const void* right) +{ + return m_operation->compareBooleans(left == right, true); } \ No newline at end of file diff --git a/thirdparty/rive/source/artboard.cpp b/thirdparty/rive/source/artboard.cpp index 1ec5a7bc5..fda2df9c4 100644 --- a/thirdparty/rive/source/artboard.cpp +++ b/thirdparty/rive/source/artboard.cpp @@ -1,7 +1,15 @@ #include "rive/artboard.hpp" +#include "rive/animation/keyframe_interpolator.hpp" #include "rive/artboard_component_list.hpp" #include "rive/backboard.hpp" +#include "rive/focus_data.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/semantic/semantic_data.hpp" +#include "rive/semantic/semantic_manager.hpp" +#include "rive/semantic/semantic_node.hpp" +#include "rive/input/focusable.hpp" #include "rive/animation/linear_animation_instance.hpp" +#include "rive/custom_property_trigger.hpp" #include "rive/dependency_sorter.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" @@ -21,23 +29,37 @@ #include "rive/nested_artboard.hpp" #include "rive/nested_artboard_leaf.hpp" #include "rive/nested_artboard_layout.hpp" +#include "rive/animation/nested_state_machine.hpp" #include "rive/joystick.hpp" +#include "rive/data_bind/data_bind.hpp" #include "rive/data_bind_flags.hpp" #include "rive/animation/nested_bool.hpp" #include "rive/animation/nested_number.hpp" #include "rive/animation/nested_trigger.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/animation/state_machine_input_instance.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/shapes/shape.hpp" +#include "rive/shapes/clipping_shape.hpp" #include "rive/text/text_value_run.hpp" #include "rive/event.hpp" #include "rive/assets/audio_asset.hpp" #include "rive/layout/layout_data.hpp" +#include "rive/profiler/profiler_macros.h" +#include "rive/scripted/scripted_object.hpp" +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/async/work_pool.hpp" +#include #include using namespace rive; +uint64_t Artboard::sm_frameId = 0; + Artboard::Artboard() { // Artboards need to override default clip value to true. @@ -49,6 +71,11 @@ Artboard::Artboard() Artboard::~Artboard() { + // NOTE: Do NOT call cleanupFocusTree() here! The FocusManager is owned by + // StateMachineInstance which may already be destroyed before the Artboard. + // Focus cleanup should be done explicitly via cleanupFocusTree() before + // the artboard is recycled/destroyed (e.g., in ArtboardComponentList). + #ifdef WITH_RIVE_AUDIO #ifdef EXTERNAL_RIVE_AUDIO_ENGINE auto audioEngine = m_audioEngine; @@ -60,22 +87,102 @@ Artboard::~Artboard() audioEngine->stop(this); } #endif - clearDataContext(); + unbind(); + + // ViewModelInstance and ViewModelInstanceValue inherit from RefCnt. + // + // ViewModelInstance (VMI) ownership rules: + // - VMIs in the component hierarchy (parent() != nullptr) are expected to + // be owned externally and must NOT be released here. + // - VMIs not in the component hierarchy are released by the artboard, but + // AFTER hierarchy components are destroyed to avoid use-after-free. This + // applies to both source and cloned artboards (e.g., artboard instances + // created by ArtboardComponentList). + // + // ViewModelInstanceValue (VMV) ownership: always owned by their parent + // ViewModelInstance via rcp<> in m_PropertyValues. When VMI is deleted, + // its destructor clears m_PropertyValues, which unrefs and deletes VMVs. + // + // Strategy: + // 1) Identify VMI/VMV objects by pointer (safe is<>() check BEFORE any + // deletions). + // 2) Delete everything else immediately, deferring VMI unref until after + // hierarchy components are gone. + std::set vmObjects; + std::set deferredVmiUnrefs; + + // First pass: identify ViewModelInstance and ViewModelInstanceValue + // objects while memory is valid (before any deletions). Precompute which + // VMIs should be released so we never dereference pointers after deletes. + auto gatherVmObjects = [&](Core* object) { + if (object == nullptr || object == this) + { + return; + } + if (object->is()) + { + vmObjects.insert(object); + auto vmi = object->as(); + if (vmi->parent() == nullptr) + { + deferredVmiUnrefs.insert(vmi); + } + return; + } + if (object->is()) + { + vmObjects.insert(object); + } + }; + for (auto object : m_Objects) + { + gatherVmObjects(object); + } + for (auto object : m_invalidObjects) + { + gatherVmObjects(object); + } + + auto isVmObject = [&](Core* object) -> bool { + return vmObjects.count(object) != 0; + }; + + // Second pass: delete non-VM objects. for (auto object : m_Objects) { - // First object is artboard - if (object == this) + if (object == nullptr || object == this) + { + continue; + } + if (isVmObject(object)) + { + continue; + } + delete object; + } + for (auto object : m_invalidObjects) + { + if (object == nullptr) + { + continue; + } + if (isVmObject(object)) { continue; } delete object; } - for (auto dataBind : m_DataBinds) + // Now release deferred ViewModelInstances (both source and clone artboards) + // after hierarchy components have been destroyed. Releasing via unref() + // keeps RefCnt ownership semantics intact. + for (auto* vmi : deferredVmiUnrefs) { - delete dataBind; + vmi->unref(); } + deleteDataBinds(); + // Instances reference back to the original artboard's animations and state // machines, so don't delete them here, they'll get cleaned up when the // source is deleted. @@ -92,11 +199,6 @@ Artboard::~Artboard() } } m_dirtyLayout.clear(); - if (m_ownsDataContext && m_DataContext != nullptr) - { - delete m_DataContext; - m_DataContext = nullptr; - } } static bool canContinue(StatusCode code) @@ -140,7 +242,13 @@ bool Artboard::validateObjects() { continue; } - delete m_Objects[i]; + // Instead of immediately deleting invalid objects, we keep them + // around in case other objects are referencing them. One + // example is the backboard_importer keeping a reference on its + // m_FileAssetReferencers. So the invalid objects are taken out + // of the objects list but only deleted when the artboard is + // destroyed. + m_invalidObjects.push_back(m_Objects[i]); m_Objects[i] = nullptr; } } @@ -202,6 +310,12 @@ StatusCode Artboard::initialize() return code; } } + if (m_Animations.size() == 0 && m_StateMachines.size() == 0) + { + auto sm = new StateMachine(); + sm->name("Auto Generated State Machine"); + m_StateMachines.push_back(sm); + } } // Store a map of the drawRules to make it easier to lookup the matching @@ -223,6 +337,14 @@ StatusCode Artboard::initialize() { return code; } + if (object->is()) + { + auto resettable = ResettingComponent::from(object->as()); + if (resettable) + { + m_Resettables.push_back(resettable); + } + } switch (object->coreType()) { case DrawRulesBase::typeKey: @@ -266,6 +388,11 @@ StatusCode Artboard::initialize() break; } } + auto advancingComponent = AdvancingComponent::from(object); + if (advancingComponent) + { + m_advancingComponents.push_back(advancingComponent); + } } if (!isInstance()) @@ -333,6 +460,10 @@ StatusCode Artboard::initialize() } } } + else if (object->is()) + { + m_clippingShapes.push_back(object->as()); + } } // Iterate over the drawables in order to inject proxies for layouts std::vector layouts; @@ -428,12 +559,16 @@ StatusCode Artboard::initialize() DependencySorter sorter; std::vector drawTargetOrder; sorter.sort(&root, drawTargetOrder); - auto itr = drawTargetOrder.begin(); - itr++; - while (itr != drawTargetOrder.end()) + if (drawTargetOrder.size() > 0) { - m_DrawTargets.push_back(static_cast(*itr++)); + auto itr = drawTargetOrder.begin(); + itr++; + while (itr != drawTargetOrder.end()) + { + m_DrawTargets.push_back(static_cast(*itr++)); + } } + initScriptedObjects(); return StatusCode::Ok; } @@ -529,6 +664,183 @@ void Artboard::sortDrawOrder() } m_FirstDrawable = lastDrawable; + + // Interleave clipping operations between drawables that share the same + // common clippings. Each clipping operation has a start and an end. + for (auto& clippingShape : m_clippingShapes) + { + clippingShape->resetDrawables(); + } + Drawable* currentDrawable = m_FirstDrawable; + Drawable* nextDrawable = nullptr; + std::vector _clippingStack; + while (currentDrawable) + { + currentDrawable->needsSaveOperation(true); + auto drawableClippingShapes = currentDrawable->clippingShapes(); + // Remove all clippings that are not part of the current drawable. Since + // they are applied as a stack, if one clipping is removed, all + // subsequent clippings from the stack need to be removed as well + size_t removingIndex = _clippingStack.size(); + for (size_t i = 0; i < _clippingStack.size(); ++i) + { + auto& cl = _clippingStack[i]; + // Check if this clipping should stay (is in both stack and + // drawable's clippings) + bool shouldStay = std::find(drawableClippingShapes.begin(), + drawableClippingShapes.end(), + cl) != drawableClippingShapes.end(); + if (!shouldStay) + { + removingIndex = i; + break; + } + } + + // Remove all clippings from stack in the reverse order they were added + if (_clippingStack.size() > 0 && removingIndex < _clippingStack.size()) + { + + size_t i = _clippingStack.size() - 1; + while (i >= removingIndex) + { + auto& clippingShape = _clippingStack[i]; + // Insert in the drawing list a clipEnd for each clipping that + // is removed + auto proxyDrawable = + clippingShape->createProxyDrawable(&clippingShape->clipEnd); + if (nextDrawable) + { + proxyDrawable->next = nextDrawable; + nextDrawable->prev = proxyDrawable; + } + else + { + fprintf(stderr, + "Error - adding clip end as first operation\n"); + } + proxyDrawable->prev = currentDrawable; + currentDrawable->next = proxyDrawable; + nextDrawable = proxyDrawable; + if (i == 0) + { + break; + } + i--; + } + _clippingStack.erase(_clippingStack.begin() + removingIndex, + _clippingStack.end()); + } + // Find clippings that are applied to the drawable but are not on the + // stack + for (auto& clippingShape : drawableClippingShapes) + { + auto itr = std::find(_clippingStack.begin(), + _clippingStack.end(), + clippingShape); + if (itr == _clippingStack.end()) + { + auto proxyDrawable = clippingShape->createProxyDrawable( + &clippingShape->clipStart); + if (nextDrawable) + { + proxyDrawable->next = nextDrawable; + nextDrawable->prev = proxyDrawable; + } + else + { + m_FirstDrawable = proxyDrawable; + } + proxyDrawable->prev = currentDrawable; + currentDrawable->next = proxyDrawable; + nextDrawable = proxyDrawable; + _clippingStack.push_back(clippingShape); + } + } + nextDrawable = currentDrawable; + currentDrawable = currentDrawable->prev; + } + // Add closing calls to remaining clippings in the stack + if (_clippingStack.size() > 0) + { + + for (int i = (int)(_clippingStack.size() - 1); i >= 0; i--) + { + auto& clippingShape = _clippingStack[i]; + auto proxyDrawable = + clippingShape->createProxyDrawable(&clippingShape->clipEnd); + if (nextDrawable) + { + nextDrawable->prev = proxyDrawable; + proxyDrawable->next = nextDrawable; + } + proxyDrawable->prev = nullptr; // End of list + nextDrawable = proxyDrawable; + } + } + clearRedundantOperations(); +} + +// Look for drawables that are preceeding and succeeding drawables that call +// save and restore. If found, the drawable does not need to call save and +// restore itself. +void Artboard::clearRedundantOperations() +{ + Drawable* currentDrawable = m_FirstDrawable; + bool prevAppliedSave = false; + // Keep a stack of clipStart operation results to apply the same operation + // to its clipEnd + std::vector appliedClippingSaveOperations; + while (currentDrawable) + { + currentDrawable->needsSaveOperation(true); + // If previous operation applied a save operation + if (prevAppliedSave) + { + // With consecutive clippings, we can skip the save and restore + // operation since the previous one has applied it + if (currentDrawable->isClipStart()) + { + appliedClippingSaveOperations.push_back(false); + currentDrawable->needsSaveOperation(false); + } + else if (currentDrawable->isClipEnd()) + { + // Apply or skip the clipEnd Restore operation matching its clip + // start counterpart + auto operationApplied = appliedClippingSaveOperations.back(); + appliedClippingSaveOperations.pop_back(); + currentDrawable->needsSaveOperation(operationApplied); + } + else + { + // Check if next is clip end, if it is, we can skip the drawable + // save/restore because it is tightly wrapped in a clipping + // operation + auto nextDrawable = currentDrawable->prev; + if (nextDrawable->isClipEnd()) + { + currentDrawable->needsSaveOperation(false); + } + } + } + else if (currentDrawable->isClipStart()) + { + appliedClippingSaveOperations.push_back(true); + } + else if (currentDrawable->isClipEnd()) + { + // Apply or skip the clipEnd Restore operation matching its clip + // start counterpart + auto operationApplied = appliedClippingSaveOperations.back(); + currentDrawable->needsSaveOperation(operationApplied); + appliedClippingSaveOperations.pop_back(); + } + prevAppliedSave = currentDrawable->isClipStart() && + (currentDrawable->willClip() || prevAppliedSave); + currentDrawable = currentDrawable->prev; + } + assert(appliedClippingSaveOperations.size() == 0); } void Artboard::sortDependencies() @@ -555,6 +867,97 @@ void Artboard::addStateMachine(StateMachine* object) m_StateMachines.push_back(object); } +void Artboard::addScriptedObject(ScriptedObject* object) +{ + m_ScriptedObjects.push_back(object); +} + +void Artboard::initScriptedObjects() +{ + if (isInstance()) + { + for (auto obj : m_ScriptedObjects) + { + if (obj->scriptAsset() != nullptr) + { + if (!obj->userLuaInitDone()) + { + obj->scriptAsset()->initScriptedObject(obj); + } + obj->hydrateScriptInputs(); + } + } + } +} + +void Artboard::pollAsyncWork() { rive_pollAsyncWork(); } + +void Artboard::drawCanvases() +{ +#ifdef WITH_RIVE_SCRIPTING + if (m_scriptingVM) + { + auto* L = m_scriptingVM->state(); + if (L != nullptr) + { + auto* context = + static_cast(lua_getthreaddata(L)); + ScopedCanvasDrawingPhase phase(context); + internalDrawCanvases(); + return; + } + } +#endif + internalDrawCanvases(); +} + +void Artboard::internalDrawCanvases() +{ + for (auto obj : m_ScriptedObjects) + { + obj->scriptDrawCanvas(); + } + for (auto artboardHost : m_ArtboardHosts) + { + for (int i = 0; i < artboardHost->artboardCount(); i++) + { + auto* nested = artboardHost->artboardInstance(i); + if (nested != nullptr) + { + nested->internalDrawCanvases(); + } + } + } +} + +#ifdef WITH_RIVE_SCRIPTING +void* Artboard::findDrawCanvasLuauState() const +{ + for (auto* obj : m_ScriptedObjects) + { + if (obj->drawsCanvas()) + { + return obj->state(); + } + } + for (auto* host : m_ArtboardHosts) + { + for (int i = 0; i < host->artboardCount(); i++) + { + auto* nested = host->artboardInstance(i); + if (nested != nullptr) + { + if (auto* state = nested->findDrawCanvasLuauState()) + { + return state; + } + } + } + } + return nullptr; +} +#endif + Core* Artboard::resolve(uint32_t id) const { if (id >= static_cast(m_Objects.size())) @@ -580,6 +983,7 @@ uint32_t Artboard::idOf(Core* object) const void Artboard::onComponentDirty(Component* component) { + m_didChange = true; m_Dirt |= ComponentDirt::Components; /// If the order of the component is less than the current dirt @@ -623,25 +1027,26 @@ void Artboard::cloneObjectDataBinds(const Core* object, Artboard* artboard) const { - for (auto dataBind : m_DataBinds) + for (auto dataBind : dataBinds()) { if (dataBind->target() == object) { auto dataBindClone = static_cast(dataBind->clone()); dataBindClone->target(clone); dataBindClone->file(dataBind->file()); + dataBindClone->initialize(); if (dataBind->converter() != nullptr) { - dataBindClone->converter( dataBind->converter()->clone()->as()); } - artboard->m_DataBinds.push_back(dataBindClone); + artboard->addDataBind(dataBindClone); } } } void Artboard::host(ArtboardHost* artboardHost) { + addedToHost(); m_host = artboardHost; #ifdef WITH_RIVE_LAYOUT if (!sharesLayoutWithHost()) @@ -659,6 +1064,18 @@ void Artboard::host(ArtboardHost* artboardHost) ArtboardHost* Artboard::host() const { return m_host; } +StatusCode Artboard::onAddedClean(CoreContext* context) +{ + auto code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + NodeBase::x(0); + NodeBase::y(0); + return StatusCode::Ok; +} + Artboard* Artboard::parentArtboard() const { if (m_host == nullptr) @@ -732,6 +1149,10 @@ void Artboard::update(ComponentDirt value) { sortDrawOrder(); } + if (hasDirt(value, ComponentDirt::Clipping)) + { + clearRedundantOperations(); + } #ifdef WITH_RIVE_LAYOUT if (hasDirt(value, ComponentDirt::LayoutStyle)) { @@ -745,30 +1166,25 @@ void Artboard::update(ComponentDirt value) // calling this twice. Although it is safe, because syncStyleChanges // checks for the list of dirty layouts that would be empty at this // point, it seems redundant. - if (syncStyleChanges() && (m_updatesOwnLayout || cascadeChanged)) - { - calculateLayout(); - updateLayoutBounds( - /*animation*/ true); // maybe use a static to allow - // the editor to set this. - } + syncStyleChangesWithUpdate(cascadeChanged); } #endif + m_hostTransformMarkedDirty = false; +} + +void Artboard::addDirtyDataBind(DataBind* dataBind) +{ + onComponentDirty(dataBind->target()->as()); + DataBindContainer::addDirtyDataBind(dataBind); } -void Artboard::updateDataBinds() +void Artboard::updateDataBinds(bool applyTargetToSource) { - for (auto dataBind : m_AllDataBinds) + for (auto artboardHost : m_ArtboardHosts) { - dataBind->updateSourceBinding(); - auto d = dataBind->dirt(); - if (d == ComponentDirt::None) - { - continue; - } - dataBind->dirt(ComponentDirt::None); - dataBind->update(d); + artboardHost->updateDataBinds(); } + DataBindContainer::updateDataBinds(applyTargetToSource); } bool Artboard::updateComponents() @@ -870,13 +1286,47 @@ void Artboard::markLayoutDirty(LayoutComponent* layoutComponent) } #endif m_dirtyLayout.insert(layoutComponent); - if (sharesLayoutWithHost() && isInstance()) + if (isInstance()) { - m_host->markHostingLayoutDirty(this->as()); + if (sharesLayoutWithHost()) + { + m_host->markHostingLayoutDirty(this->as()); + } + else + { + markHostTransformDirty(); + } } addDirt(ComponentDirt::Components); } +void Artboard::markHostTransformDirty() +{ +#ifdef WITH_RIVE_TOOLS + if (!m_hostTransformMarkedDirty && m_transformDirtyCallback != nullptr) + { + m_transformDirtyCallback(callbackUserData); + } +#endif + m_hostTransformMarkedDirty = true; + if (host()) + { + host()->markHostTransformDirty(); + } +} + +void Artboard::syncStyleChangesWithUpdate(bool forceUpdate) +{ +#ifdef WITH_RIVE_LAYOUT + if (syncStyleChanges() && (m_updatesOwnLayout || forceUpdate)) + { + calculateLayout(); + updateLayoutBounds(/*animation*/ true); // maybe use a static to allow + // the editor to set this. + } +#endif +} + bool Artboard::syncStyleChanges() { bool updated = false; @@ -902,7 +1352,10 @@ bool Artboard::syncStyleChanges() else { // This is a nested artboard, sync its changes too. - artboard->syncStyleChanges(); + if (!artboard->updatesOwnLayout()) + { + artboard->syncStyleChanges(); + } } break; } @@ -920,17 +1373,41 @@ bool Artboard::syncStyleChanges() return updated; } +void Artboard::calculateLayout() +{ + // Always pass NAN and let calculateLayoutInternal decide whether to use + // the intrinsic (hug) size or fall back to width()/height(). + // + // This covers all cases: + // - Runtime: + // - Top level artboards: intrinsically sized artboards get NAN so Yoga + // computes from children; fixed-size artboards fall back to + // width()/height() inside calculateLayoutInternal. + // - Nested node/leaf artboards (m_updatesOwnLayout == true): same as + // top-level, calculateLayoutInternal handles the distinction. + // - Nested layout-mode artboards (NestedArtboardLayout): their layout + // node is owned by the parent via takeLayoutData(), which sets + // m_updatesOwnLayout = false. syncStyleChangesWithUpdate() gates on + // that flag, so calculateLayout() is not reached for these. + // - Editor: + // - Top level artboards: are handled on the Dart side so don't take + // this code path + // - Nested node/leaf artboards (m_updatesOwnLayout == true): + // same as runtime, calculateLayoutInternal handles the distinction. + // - Nested layout-mode artboards (NestedArtboardLayout): same + // as runtime, their layout node is owned by the Dart parent + // which sets m_updatesOwnLayout = false + calculateLayoutInternal(NAN, NAN); +} + bool Artboard::updatePass(bool isRoot) { + RIVE_PROF_SCOPE() + updateDataBinds(); bool didUpdate = false; -#ifdef WITH_RIVE_LAYOUT - if (syncStyleChanges() && m_updatesOwnLayout) - { - calculateLayout(); - updateLayoutBounds(/*animation*/ true); // maybe use a static to allow - // the editor to set this. - } -#endif + syncStyleChangesWithUpdate(); + m_hostTransformMarkedDirty = false; + if (m_JoysticksApplyBeforeUpdate) { for (auto joystick : m_Joysticks) @@ -938,7 +1415,6 @@ bool Artboard::updatePass(bool isRoot) joystick->apply(this); } } - updateDataBinds(); if (updateComponents()) { didUpdate = true; @@ -963,34 +1439,51 @@ bool Artboard::updatePass(bool isRoot) didUpdate = true; } } + if (didUpdate) + { + updateDataBinds(); + } return didUpdate; } bool Artboard::advanceInternal(float elapsedSeconds, AdvanceFlags flags) { + RIVE_PROF_SCOPE() bool didUpdate = false; - for (auto dep : m_DependencyOrder) + for (auto adv : m_advancingComponents) { - auto adv = AdvancingComponent::from(dep); - if (adv != nullptr && adv->advanceComponent(elapsedSeconds, flags)) + if (adv->advanceComponent(elapsedSeconds, flags)) { didUpdate = true; } } - for (auto dataBind : m_AllDataBinds) + if (advanceDataBinds(elapsedSeconds)) { - if (dataBind->advance(elapsedSeconds)) - { - didUpdate = true; - } + didUpdate = true; } return didUpdate; } +void Artboard::reset() +{ + if (m_Resettables.size() == 0) + { + return; + } + for (auto obj : m_Resettables) + { + obj->reset(); + } +} + bool Artboard::advance(float elapsedSeconds, AdvanceFlags flags) { + // Poll async work (image decodes, etc.) so promises resolve before + // script advance() callbacks run. + pollAsyncWork(); + AdvanceFlags advancingFlags = flags; advancingFlags |= AdvanceFlags::IsRoot; bool didUpdate = advanceInternal(elapsedSeconds, advancingFlags); @@ -1041,60 +1534,149 @@ Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D& xform) return nullptr; } -void Artboard::draw(Renderer* renderer) { draw(renderer, DrawOption::kNormal); } - -void Artboard::draw(Renderer* renderer, DrawOption option) +Vec2D Artboard::rootTransform(const Vec2D& point) { - if (renderOpacity() == 0) - { - return; - } - bool save = clip() || m_FrameOrigin; - if (save) + if (host()) { - renderer->save(); + return host()->hostTransformPoint(point, this->as()); } - if (clip()) +#ifdef WITH_RIVE_TOOLS + // Editor artboards don't have a host, so we expose a function that calls + // the host in dart. + if (m_rootTransformCallback != nullptr) { - renderer->clipPath(m_worldPath.renderPath(this)); + auto x = + m_rootTransformCallback(callbackUserData, point.x, point.y, true); + auto y = + m_rootTransformCallback(callbackUserData, point.x, point.y, false); + return Vec2D(x, y); } +#endif + return point; +} - if (m_FrameOrigin) +bool Artboard::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + if (host() != nullptr && isInstance()) { - Mat2D artboardTransform; - artboardTransform[4] = layoutWidth() * originX(); - artboardTransform[5] = layoutHeight() * originY(); - renderer->transform(artboardTransform); - } - - if (option != DrawOption::kHideBG) - { - for (auto shapePaint : m_ShapePaints) + if (!host()->hitTestHost(position, + skipOnUnclipped, + this->as())) { - if (!shapePaint->shouldDraw()) - { - continue; - } - auto shapePaintPath = shapePaint->pickPath(this); - if (shapePaintPath == nullptr) - { - continue; - } - shapePaint->draw(renderer, shapePaintPath, worldTransform()); + return false; + } + } +#ifdef WITH_RIVE_TOOLS + // Editor artboards don't have a host, so we expose a function that calls + // the host in dart. + if (m_testBoundsCallback != nullptr) + { + // Dart can't return booleans to cpp, so we use a uint_8 instead + auto didHit = m_testBoundsCallback(callbackUserData, + position.x, + position.y, + skipOnUnclipped); + if (didHit == 0) + { + return false; } } +#endif + return LayoutComponent::hitTestPoint(position, + skipOnUnclipped, + isPrimaryHit); +} + +void Artboard::draw(Renderer* renderer) +{ + sm_frameId++; + drawCanvases(); + drawInternal(renderer); +} + +void Artboard::drawInternal(Renderer* renderer) +{ + RIVE_PROF_SCOPE_L(1) + m_didChange = false; + if (renderOpacity() == 0) + { + return; + } + bool save = clip() || m_FrameOrigin; + if (save) + { + renderer->save(); + } + if (clip()) + { + renderer->clipPath(m_worldPath.renderPath(this)); + } + + if (m_FrameOrigin) + { + Mat2D artboardTransform; + artboardTransform[4] = layoutWidth() * originX(); + artboardTransform[5] = layoutHeight() * originY(); + renderer->transform(artboardTransform); + } - if (option != DrawOption::kHideFG) + for (auto shapePaint : m_ShapePaints) { - for (auto drawable = m_FirstDrawable; drawable != nullptr; - drawable = drawable->prev) + if (!shapePaint->shouldDraw()) + { + continue; + } + auto shapePaintPath = shapePaint->pickPath(this); + if (shapePaintPath == nullptr) { - if (drawable->isHidden()) + continue; + } + shapePaint->draw(renderer, shapePaintPath, worldTransform()); + } + // Empty clips is a counter for clipping shapes that are empty, for + // example because they are hidden in a solo. If emptyClips > 0, the + // drawables should not be drawn. + int emptyClips = 0; + // We stack clip operations to avoid calling a save + clip + restore on + // clipping that don't have any drawables in between. this is a common + // case with drawables in solos where the drawables are not drawn. + std::vector pendingClipOperations; + for (auto drawable = m_FirstDrawable; drawable != nullptr; + drawable = drawable->prev) + { + auto prevClips = emptyClips; + emptyClips += drawable->emptyClipCount(); + if (!drawable->willDraw() || emptyClips != prevClips || emptyClips > 0) + { + continue; + } + if (drawable->isClipStart()) + { + pendingClipOperations.push_back(drawable); + continue; + } + else if (pendingClipOperations.size() > 0) + { + // If there are clip operations pending and the next drawable is + // a clip end, the clipping operation does not clip anything and + // both can be skipped. + if (drawable->isClipEnd()) { + pendingClipOperations.pop_back(); continue; } - drawable->draw(renderer); + else + { + for (auto& pendingClip : pendingClipOperations) + { + pendingClip->draw(renderer); + } + pendingClipOperations.clear(); + } } + drawable->draw(renderer); } if (save) { @@ -1116,6 +1698,20 @@ void Artboard::addToRenderPath(RenderPath* path, const Mat2D& transform) } } +void Artboard::addToRawPath(RawPath& path, const Mat2D* transform) +{ + for (auto drawable = m_FirstDrawable; drawable != nullptr; + drawable = drawable->prev) + { + if (drawable->isHidden() || !drawable->is()) + { + continue; + } + Shape* shape = drawable->as(); + shape->addToRawPath(path, transform); + } +} + Vec2D Artboard::origin() const { return m_FrameOrigin @@ -1123,6 +1719,18 @@ Vec2D Artboard::origin() const : Vec2D(-layoutWidth() * originX(), -layoutHeight() * originY()); } +void Artboard::xChanged() +{ + Super::xChanged(); + markHostTransformDirty(); +} + +void Artboard::yChanged() +{ + Super::yChanged(); + markHostTransformDirty(); +} + AABB Artboard::bounds() const { return m_FrameOrigin ? AABB(0.0f, 0.0f, layoutWidth(), layoutHeight()) @@ -1132,6 +1740,14 @@ AABB Artboard::bounds() const layoutHeight()); } +AABB Artboard::worldBounds() const +{ + return AABB::fromLTWH(NodeBase::x(), + NodeBase::y(), + m_layout.width(), + m_layout.height()); +} + bool Artboard::isTranslucent() const { for (const auto sp : m_ShapePaints) @@ -1199,6 +1815,522 @@ std::string Artboard::animationNameAt(size_t index) const return la ? la->name() : ""; } +// Helper: check if a FocusData has a parent FocusData within the artboard +// by walking up the component hierarchy +static bool hasParentFocusData(const FocusData* focusData) +{ + // FocusData's parent is a ContainerComponent (likely a Node) + // Walk up to find if any ancestor Node has a FocusData child + auto* current = focusData->parent(); + while (current != nullptr) + { + if (current->is()) + { + auto* node = current->as(); + for (auto child : node->children()) + { + if (child->is() && child != focusData) + { + return true; + } + } + } + current = current->parent(); + } + return false; +} + +size_t Artboard::rootFocusDataCount() const +{ + size_t count = 0; + for (auto* object : m_Objects) + { + if (object != nullptr && object->is()) + { + if (!hasParentFocusData(object->as())) + { + count++; + } + } + } + return count; +} + +FocusData* Artboard::rootFocusDataAt(size_t index) const +{ + size_t count = 0; + for (auto* object : m_Objects) + { + if (object != nullptr && object->is()) + { + if (!hasParentFocusData(object->as())) + { + if (count == index) + { + return object->as(); + } + count++; + } + } + } + return nullptr; +} + +void Artboard::buildFocusTree(FocusManager* focusManager, + rcp parentFocusNode) +{ + if (focusManager == nullptr) + { + return; + } + + // Store reference to the active focus manager + setActiveFocusManager(focusManager); + +#ifdef WITH_RIVE_TOOLS + // Store the parent focus node if provided (for later retrieval by tools) + if (parentFocusNode != nullptr) + { + m_externalParentFocusNode = parentFocusNode; + } + // Use explicit parent if provided, otherwise fall back to external parent + rcp effectiveParent = parentFocusNode != nullptr + ? parentFocusNode + : m_externalParentFocusNode; +#else + rcp effectiveParent = parentFocusNode; +#endif + + // Register all FocusData in this artboard + for (auto* obj : m_Objects) + { + if (obj != nullptr && obj->is()) + { + auto* fd = obj->as(); + auto* localParent = fd->findParentFocusData(); + + rcp parentNode = localParent != nullptr + ? localParent->focusNode() + : effectiveParent; + + focusManager->addChild(parentNode, fd->focusNode()); + } + } + // Propagate focus registration to nested artboards that might have been + // created before this artboard's focusManager was available. This handles + // ArtboardComponentList and NestedArtboard items that were initialized + // before the parent StateMachineInstance was created. + // + // We check if the nested artboard's focusManager is DIFFERENT from ours. + // If it is, that means it created its own internal focusManager when it + // should be sharing the parent's. We rebuild its focus tree with the + // correct shared focusManager. + + // Handle NestedArtboard instances + for (auto* nestedArtboardHost : m_NestedArtboards) + { + // Find closest focus node (handles artboard boundaries) + auto hostParentNode = + FocusData::findClosestFocusNode(nestedArtboardHost); + if (hostParentNode == nullptr) + { + hostParentNode = effectiveParent; + } + + auto* nestedArtboard = nestedArtboardHost->artboardInstance(0); + if (nestedArtboard != nullptr && + nestedArtboard->focusManager() != focusManager) + { + // Clean up old focus tree if it exists (with wrong focusManager) + nestedArtboard->cleanupFocusTree(); + nestedArtboard->buildFocusTree(focusManager, hostParentNode); + } + + // Also update the external focus manager on any nested state machines. + // This handles the case where initializeAnimation was called before + // the parent artboard had a focus manager. + for (auto* animation : nestedArtboardHost->nestedAnimations()) + { + if (animation->is()) + { + auto* nsm = animation->as(); + auto* smi = nsm->stateMachineInstance(); + if (smi != nullptr && smi->focusManager() != focusManager) + { + smi->setExternalFocusManager(focusManager); + } + } + } + } + + // Handle ArtboardComponentList instances + for (auto* componentList : m_ComponentLists) + { + // Find closest focus node (handles artboard boundaries) + auto hostParentNode = FocusData::findClosestFocusNode(componentList); + if (hostParentNode == nullptr) + { + hostParentNode = effectiveParent; + } + + for (size_t i = 0; i < componentList->artboardCount(); i++) + { + auto* nestedArtboard = + componentList->artboardInstance(static_cast(i)); + if (nestedArtboard != nullptr && + nestedArtboard->focusManager() != focusManager) + { + // Clean up old focus tree if it exists (with wrong + // focusManager) + nestedArtboard->cleanupFocusTree(); + nestedArtboard->buildFocusTree(focusManager, hostParentNode); + } + + // Also update the state machine's external focus manager. + // This handles the case where linkStateMachine was called before + // the parent artboard had a focus manager. + auto* smi = + componentList->stateMachineInstance(static_cast(i)); + if (smi != nullptr && smi->focusManager() != focusManager) + { + smi->setExternalFocusManager(focusManager); + } + } + } +} + +void Artboard::buildFocusTree(rcp parentFocusNode) +{ + if (parentFocusNode == nullptr) + { + return; + } + auto* manager = parentFocusNode->manager(); + if (manager == nullptr) + { + return; + } + buildFocusTree(manager, parentFocusNode); +} + +void Artboard::cleanupFocusTree() +{ + if (m_activeFocusManager == nullptr) + { + return; + } + + // Remove all FocusData's FocusNodes from the FocusManager + for (auto* obj : m_Objects) + { + if (obj != nullptr && obj->is()) + { + auto* fd = obj->as(); + // Only remove if the FocusNode was created (lazy initialization) + // and is still registered with THIS manager (defensive check for + // cases where auto-cleanup via FocusData destructor already ran) + auto node = fd->focusNode(); + if (node != nullptr && node->manager() == m_activeFocusManager) + { + m_activeFocusManager->removeChild(node); + } + } + } + + // Propagate cleanup to nested artboards that share our FocusManager + for (auto* nestedArtboardHost : m_NestedArtboards) + { + auto* nestedArtboard = nestedArtboardHost->artboardInstance(0); + if (nestedArtboard != nullptr && + nestedArtboard->focusManager() == m_activeFocusManager) + { + nestedArtboard->cleanupFocusTree(); + } + } + + // Propagate cleanup to ArtboardComponentList items + for (auto* componentList : m_ComponentLists) + { + for (size_t i = 0; i < componentList->artboardCount(); i++) + { + auto* nestedArtboard = + componentList->artboardInstance(static_cast(i)); + if (nestedArtboard != nullptr && + nestedArtboard->focusManager() == m_activeFocusManager) + { + nestedArtboard->cleanupFocusTree(); + } + } + } + + // Clear the active focus manager reference + m_activeFocusManager = nullptr; +} + +#ifdef WITH_RIVE_TOOLS +void Artboard::setExternalParentFocusNode(rcp node) +{ + m_externalParentFocusNode = std::move(node); +} + +rcp Artboard::externalParentFocusNode() const +{ + return m_externalParentFocusNode; +} + +void Artboard::collapseSingle(bool value) { Component::collapse(value); } +#endif + +// Builds the semantic tree for this artboard. Iterates all objects, +// registers each SemanticData's SemanticNode with the manager, then +// propagates to nested artboards using findClosestSemanticNode() for +// parent resolution across artboard boundaries. +// +// For nested artboards (those with a host), a boundary SemanticNode is +// created and inserted as the parent of all semantic nodes within this +// artboard. Boundary nodes are structural-only — skipped during +// flattening — but enable better subtree collapse/uncollapse and +// targeted bounds dirtying when the host transform changes. +void Artboard::buildSemanticTree(SemanticManager* semanticManager, + rcp parentSemanticNode) +{ + if (semanticManager == nullptr) + { + return; + } + + // Store reference to the active semantic manager + setActiveSemanticManager(semanticManager); + + // For nested artboards, create a boundary node that acts as the + // structural root of this artboard's semantic subtree. + rcp effectiveParent = parentSemanticNode; + if (host() != nullptr) + { + if (m_semanticBoundaryNode == nullptr) + { + // Id is assigned by the SemanticManager on addChild() below. + m_semanticBoundaryNode = rcp(new SemanticNode()); + m_semanticBoundaryNode->isBoundaryNode(true); + m_semanticBoundaryNode->boundaryArtboard(this); + } + semanticManager->addChild(parentSemanticNode, m_semanticBoundaryNode); + // Seed the boundary as dirty so the first drainDiff() resolves its + // bounds from the artboard rect even when semantics are enabled on + // an already-settled scene (no subsequent WorldTransform dirt to + // trigger this via the normal update cycle). + markSemanticBoundaryTransformDirty(); + effectiveParent = m_semanticBoundaryNode; + } + + // Register all SemanticData in this artboard + for (auto* obj : m_Objects) + { + if (obj != nullptr && obj->is()) + { + auto* sd = obj->as(); + auto* localParent = sd->findParentSemanticData(); + + rcp parentNode = localParent != nullptr + ? localParent->semanticNode() + : effectiveParent; + + semanticManager->addChild(parentNode, sd->semanticNode()); + sd->syncSemanticTreeVisibility(); + } + } + + // Propagate semantic registration to nested artboards that might have been + // created before this artboard's semanticManager was available. + // + // We check if the nested artboard's semanticManager is DIFFERENT from ours. + // If it is, that means it created its own internal semanticManager when it + // should be sharing the parent's. We rebuild its semantic tree with the + // correct shared semanticManager. + + // Handle NestedArtboard instances + for (auto* nestedArtboardHost : m_NestedArtboards) + { + // Find closest semantic node (handles artboard boundaries) + auto hostParentNode = + SemanticData::findClosestSemanticNode(nestedArtboardHost); + if (hostParentNode == nullptr) + { + hostParentNode = effectiveParent; + } + + auto* nestedArtboard = nestedArtboardHost->artboardInstance(0); + if (nestedArtboard != nullptr && + nestedArtboard->semanticManager() != semanticManager) + { + // Clean up old semantic tree if it exists (with wrong + // semanticManager) + nestedArtboard->cleanupSemanticTree(); + nestedArtboard->buildSemanticTree(semanticManager, hostParentNode); + } + } + + // Handle ArtboardComponentList instances + for (auto* componentList : m_ComponentLists) + { + // Find closest semantic node (handles artboard boundaries) + auto hostParentNode = + SemanticData::findClosestSemanticNode(componentList); + if (hostParentNode == nullptr) + { + hostParentNode = effectiveParent; + } + + for (size_t i = 0; i < componentList->artboardCount(); i++) + { + auto* nestedArtboard = + componentList->artboardInstance(static_cast(i)); + if (nestedArtboard != nullptr && + nestedArtboard->semanticManager() != semanticManager) + { + // Clean up old semantic tree if it exists (with wrong + // semanticManager) + nestedArtboard->cleanupSemanticTree(); + nestedArtboard->buildSemanticTree(semanticManager, + hostParentNode); + } + } + } +} + +void Artboard::cleanupSemanticTree() +{ + if (m_activeSemanticManager == nullptr) + { + return; + } + + // Propagate cleanup to nested artboards that share our SemanticManager. + // Done FIRST so their boundary nodes are removed before we remove ours. + for (auto* nestedArtboardHost : m_NestedArtboards) + { + auto* nestedArtboard = nestedArtboardHost->artboardInstance(0); + if (nestedArtboard != nullptr && + nestedArtboard->semanticManager() == m_activeSemanticManager) + { + nestedArtboard->cleanupSemanticTree(); + } + } + + // Propagate cleanup to ArtboardComponentList items + for (auto* componentList : m_ComponentLists) + { + for (size_t i = 0; i < componentList->artboardCount(); i++) + { + auto* nestedArtboard = + componentList->artboardInstance(static_cast(i)); + if (nestedArtboard != nullptr && + nestedArtboard->semanticManager() == m_activeSemanticManager) + { + nestedArtboard->cleanupSemanticTree(); + } + } + } + + // Remove all SemanticData's SemanticNodes from the SemanticManager. + // Use hasSemanticNode() to avoid lazy-creating a node during cleanup. + for (auto* obj : m_Objects) + { + if (obj != nullptr && obj->is()) + { + auto* sd = obj->as(); + if (!sd->hasSemanticNode()) + { + continue; + } + auto node = sd->semanticNode(); + if (node != nullptr && node->manager() == m_activeSemanticManager) + { + m_activeSemanticManager->removeChild(node); + } + } + } + + // Remove the boundary node for this artboard (if any). + if (m_semanticBoundaryNode != nullptr && + m_semanticBoundaryNode->manager() == m_activeSemanticManager) + { + m_activeSemanticManager->removeChild(m_semanticBoundaryNode); + } + m_semanticBoundaryNode = nullptr; + + // Clear the active semantic manager reference + m_activeSemanticManager = nullptr; +} + +// Walk the semantic subtree under a boundary node and collapse each +// SemanticData directly via the back-pointer. O(K) where K = semantic +// nodes under this boundary. +static void collapseBoundarySubtree(SemanticNode* node, bool value) +{ + // Copy children before iterating — collapse(true) calls + // removeChild which mutates the original vector. + std::vector> children(node->children()); + for (const auto& child : children) + { + auto* sd = child->semanticData(); + if (sd != nullptr && sd->isCollapsed() != value) + { + sd->collapse(value); + } + collapseBoundarySubtree(child.get(), value); + } +} + +// Semantic-only collapse for this artboard's semantic nodes. +// When collapsing, walks the boundary's semantic subtree (O(K) semantic +// nodes). When uncollapsing, falls back to m_Objects because +// SemanticData::collapse(false) re-parents nodes outside the boundary. +void Artboard::collapseSemanticBoundary(bool value) +{ + if (m_activeSemanticManager == nullptr) + { + return; + } + if (value && m_semanticBoundaryNode != nullptr) + { + // Fast path: walk the boundary tree. + collapseBoundarySubtree(m_semanticBoundaryNode.get(), true); + } + else + { + // Uncollapse or no boundary: scan artboard objects. + for (auto* obj : m_Objects) + { + if (obj != nullptr && obj->is()) + { + auto* sd = obj->as(); + if (sd->isCollapsed() != value) + { + sd->collapse(value); + } + } + } + } + + if (!value) + { + markSemanticBoundaryTransformDirty(); + } +} + +// Recursively mark all semantic nodes under the boundary as bounds-dirty. +// Called when the host transform changes so bounds are recalculated in +// root artboard space. +void Artboard::markSemanticBoundaryTransformDirty() +{ + if (m_semanticBoundaryNode == nullptr || m_activeSemanticManager == nullptr) + { + return; + } + m_activeSemanticManager->markBoundaryDirty(m_semanticBoundaryNode->id()); +} + std::string Artboard::stateMachineNameAt(size_t index) const { auto sm = this->stateMachine(index); @@ -1374,13 +2506,15 @@ StatusCode Artboard::import(ImportStack& importStack) return result; } -void Artboard::internalDataContext(DataContext* value, bool isRoot) +void Artboard::buildDataContext(rcp value) {} + +void Artboard::internalDataContext(rcp value) { m_DataContext = value; - for (auto artboardHost : m_NestedArtboards) + for (auto artboardHost : m_ArtboardHosts) { - auto value = m_DataContext->getViewModelInstance( - artboardHost->dataBindPathIds()); + auto value = + m_DataContext->getViewModelInstance(artboardHost->dataBindPath()); if (value != nullptr && value->is()) { artboardHost->bindViewModelInstance(value, m_DataContext); @@ -1390,52 +2524,66 @@ void Artboard::internalDataContext(DataContext* value, bool isRoot) artboardHost->internalDataContext(m_DataContext); } } - for (auto dataBind : m_DataBinds) - { - if (dataBind->is()) - { - dataBind->as()->bindFromContext(m_DataContext); - } - } - if (isRoot) + bindDataBindsFromContext(m_DataContext.get()); + sortDataBinds(); + for (auto* scriptedObject : m_ScriptedObjects) { - collectDataBinds(); + scriptedObject->dataContext(value); } + initScriptedObjects(); } -void Artboard::clearDataContext() +void Artboard::rebind() { internalDataContext(m_DataContext); } + +void Artboard::relinkDataContext() { - if (m_ownsDataContext && m_DataContext != nullptr) + if (m_DataContext == nullptr) { - delete m_DataContext; + return; } - m_DataContext = nullptr; - m_ownsDataContext = false; for (auto artboardHost : m_ArtboardHosts) { - artboardHost->clearDataContext(); + rcp value = + m_DataContext->getViewModelInstance(artboardHost->dataBindPath()); + if (value == nullptr) + { + value = m_DataContext->viewModelInstance(); + } + artboardHost->relinkDataContext(value); } - for (auto& dataBind : m_DataBinds) +} + +void Artboard::rebuildDataBind(DataBind* dataBind) +{ + if (dataBind->is()) { - dataBind->unbind(); + dataBind->as()->bindFromContext(m_DataContext.get()); + } +}; + +void Artboard::unbind() +{ + clearDataContext(); + unbindDataBinds(); + for (auto artboardHost : m_ArtboardHosts) + { + artboardHost->unbind(); } } -void Artboard::sortDataBinds() +void Artboard::clearDataContext() { - size_t currentToSourceIndex = 0; - for (size_t i = 0; i < m_AllDataBinds.size(); i++) + if (m_DataContext) { - if (m_AllDataBinds[i]->toSource()) + if (m_DataContext->viewModelInstance()) { - if (i != currentToSourceIndex) - { - - std::iter_swap(m_AllDataBinds.begin() + currentToSourceIndex, - m_AllDataBinds.begin() + i); - } - currentToSourceIndex += 1; + m_DataContext->viewModelInstance()->removeDependent(this); } + m_DataContext = nullptr; + } + for (auto artboardHost : m_ArtboardHosts) + { + artboardHost->clearDataContext(); } } @@ -1456,63 +2604,71 @@ void Artboard::volume(float value) } } -void Artboard::populateDataBinds(std::vector* dataBinds) -{ - for (auto dataBind : m_DataBinds) - { - dataBinds->push_back(dataBind); - } - for (auto artboardHost : m_ArtboardHosts) - { - artboardHost->populateDataBinds(dataBinds); - } -} - -void Artboard::collectDataBinds() -{ - m_AllDataBinds.clear(); - populateDataBinds(&m_AllDataBinds); - sortDataBinds(); -} - -void Artboard::addDataBind(DataBind* dataBind) -{ - m_DataBinds.push_back(dataBind); -} - -void Artboard::dataContext(DataContext* value) +void Artboard::dataContext(rcp value) { - internalDataContext(value, true); + internalDataContext(value); } void Artboard::bindViewModelInstance(rcp viewModelInstance) { - bindViewModelInstance(viewModelInstance, nullptr, true); -} - -void Artboard::bindViewModelInstance(rcp viewModelInstance, - DataContext* parent) -{ - bindViewModelInstance(viewModelInstance, parent, true); + bindViewModelInstance(viewModelInstance, nullptr); } void Artboard::bindViewModelInstance(rcp viewModelInstance, - DataContext* parent, - bool isRoot) + rcp parent) { - clearDataContext(); if (viewModelInstance == nullptr) { + unbind(); return; } - if (isRoot) + clearDataContext(); + auto dataContext = make_rcp(viewModelInstance); + if (dataContext->viewModelInstance()) { - viewModelInstance->setAsRoot(viewModelInstance); + dataContext->viewModelInstance()->addDependent(this); } - m_ownsDataContext = true; - auto dataContext = new DataContext(viewModelInstance); dataContext->parent(parent); - internalDataContext(dataContext, isRoot); + internalDataContext(dataContext); +} + +bool Artboard::isAncestor(const Artboard* artboard) +{ + if (artboard != nullptr && m_artboardSource == artboard->artboardSource()) + { + return true; + } + if (parentArtboard() != nullptr) + { + return parentArtboard()->isAncestor(artboard); + } +#ifdef WITH_RIVE_TOOLS + // Editor artboards don't have a host, so we expose a function that calls + // the host in dart. + if (m_isAncestorCallback != nullptr) + { + // Dart can't return booleans to cpp, so we use a uint_8 instead + auto isAncestor = + m_isAncestorCallback(callbackUserData, artboard->artboardId()); + if (isAncestor == 1) + { + return true; + } + } +#endif + return false; +} + +void Artboard::changed() +{ + if (!m_didChange) + { + m_didChange = true; + if (parentArtboard()) + { + parentArtboard()->changed(); + } + } } ////////// ArtboardInstance @@ -1528,30 +2684,28 @@ std::unique_ptr ArtboardInstance::animationAt( size_t index) { auto la = this->animation(index); - return la ? rivestd::make_unique(la, this) - : nullptr; + return la ? std::make_unique(la, this) : nullptr; } std::unique_ptr ArtboardInstance::animationNamed( const std::string& name) { auto la = this->animation(name); - return la ? rivestd::make_unique(la, this) - : nullptr; + return la ? std::make_unique(la, this) : nullptr; } std::unique_ptr ArtboardInstance::stateMachineAt( size_t index) { auto sm = this->stateMachine(index); - return sm ? rivestd::make_unique(sm, this) : nullptr; + return sm ? std::make_unique(sm, this) : nullptr; } std::unique_ptr ArtboardInstance::stateMachineNamed( const std::string& name) { auto sm = this->stateMachine(name); - return sm ? rivestd::make_unique(sm, this) : nullptr; + return sm ? std::make_unique(sm, this) : nullptr; } std::unique_ptr ArtboardInstance::defaultStateMachine() diff --git a/thirdparty/rive/source/artboard_component_list.cpp b/thirdparty/rive/source/artboard_component_list.cpp index affe67ccb..f22581724 100644 --- a/thirdparty/rive/source/artboard_component_list.cpp +++ b/thirdparty/rive/source/artboard_component_list.cpp @@ -1,34 +1,233 @@ #include "rive/component.hpp" #include "rive/file.hpp" +#include +#include +#include "rive/animation/keyframe_interpolator.hpp" #include "rive/artboard_component_list.hpp" +#include "rive/animation/state_machine_instance.hpp" #include "rive/constraints/layout_constraint.hpp" +#include "rive/constraints/list_constraint.hpp" +#include "rive/constraints/scrolling/scroll_constraint.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind_flags.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_number_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_string_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_color_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_enum_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_list_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_trigger_base.hpp" +#include "rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp" +#include "rive/focus_data.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/semantic/semantic_manager.hpp" #include "rive/layout_component.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" #include "rive/viewmodel/viewmodel_instance_symbol_list_index.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/viewmodel/symbol_type.hpp" +#include "rive/viewmodel/viewmodel_value_dependent.hpp" +#include "rive/world_transform_component.hpp" #include "rive/layout/layout_data.hpp" +#include "rive/artboard_list_map_rule.hpp" +#include "rive/semantic/semantic_data.hpp" using namespace rive; +namespace rive +{ +/// Marks the hosting list dirty when a list item's drawIndex VM value changes. +class ArtboardListDrawIndexDependent final : public ViewModelValueDependent +{ +public: + ArtboardListDrawIndexDependent(ArtboardComponentList* list, + ViewModelInstanceValue* value) : + m_list(list), m_value(ref_rcp(value)) + { + value->addDependent(this); + } + ~ArtboardListDrawIndexDependent() { clear(); } + + void addDirt(ComponentDirt value, bool recurse) override + { + if (m_list != nullptr) + { + m_list->invalidateOrderedListIndicesCache(); + m_list->addDirt(ComponentDirt::Components, false); + } + } + void relinkDataBind() override {} + + void clear() + { + if (m_value != nullptr) + { + m_value->removeDependent(this); + m_value = nullptr; + } + } + +private: + ArtboardComponentList* m_list; + rcp m_value; +}; +} // namespace rive + ArtboardComponentList::ArtboardComponentList() {} -ArtboardComponentList::~ArtboardComponentList() { reset(); } +ArtboardComponentList::~ArtboardComponentList() { clear(); } -void ArtboardComponentList::reset() +bool ArtboardComponentList::collapse(bool value) +{ + if (!Super::collapse(value)) + { + return false; + } + + // Semantic-only collapse via the artboard boundary node. Only touches + // SemanticData nodes — non-semantic components stay untouched. + for (size_t i = 0; i < artboardCount(); i++) + { + auto* nestedArtboard = artboardInstance(static_cast(i)); + if (nestedArtboard != nullptr) + { + nestedArtboard->collapseSemanticBoundary(value); + } + } + return true; +} + +void ArtboardComponentList::clear() { + // Clean up semantic trees before destroying artboards/state machines. for (auto& artboard : m_artboardInstancesMap) { - artboard.second.reset(); + if (artboard.second != nullptr) + { + artboard.second->cleanupSemanticTree(); + } } + + clearDrawIndexListeners(); + invalidateOrderedListIndicesCache(); + // Clean up focus trees FIRST to prevent use-after-free when the + // FocusManager still holds references to FocusNodes. + for (auto& artboard : m_artboardInstancesMap) + { + if (artboard.second != nullptr) + { + artboard.second->cleanupFocusTree(); + } + } + + // Clean up bridge binds FIRST since they reference VM instances + // that may be owned by the artboard instances below. + auto* parentAb = artboard(); + for (auto& [item, binds] : m_bridgeDataBinds) + { + for (auto& bind : binds) + { + bind->unbind(); + if (parentAb != nullptr) + { + parentAb->removeDataBind(bind.get()); + } + } + } + m_bridgeDataBinds.clear(); + + // Destroy state machines BEFORE artboards. + // StateMachineInstance owns FocusListenerGroup objects that hold raw + // pointers to FocusData (owned by artboards). Destroying artboards first + // would cause use-after-free when FocusListenerGroup destructor tries to + // unregister from the already-deleted FocusData. for (auto& sm : m_stateMachinesMap) { sm.second.reset(); } - for (auto& item : m_listItems) + for (auto& artboard : m_artboardInstancesMap) { - item->unref(); + artboard.second.reset(); } - m_artboardInstancesMap.clear(); m_stateMachinesMap.clear(); + m_artboardInstancesByIndex.clear(); + m_stateMachinesByIndex.clear(); + m_artboardInstancesMap.clear(); m_listItems.clear(); m_artboardsMap.clear(); + m_resourcePool.clear(); + m_stateMachinesPool.clear(); + m_artboardOverridesMap.clear(); +} + +rcp ArtboardComponentList::listItem(int index) +{ + if (index < m_listItems.size()) + { + return m_listItems[index]; + } + return nullptr; +} +ArtboardInstance* ArtboardComponentList::artboardInstance(int index) +{ + if (!virtualizationEnabled()) + { + if (index >= 0 && index < m_artboardInstancesByIndex.size()) + { + return m_artboardInstancesByIndex[index]; + } + return nullptr; + } + if (index >= 0 && index < m_listItems.size()) + { + auto item = listItem(index); + auto itr = m_artboardInstancesMap.find(item); + if (itr != m_artboardInstancesMap.end()) + { + return itr->second.get(); + } + } + return nullptr; +} +int ArtboardComponentList::indexOfArtboardInstance( + ArtboardInstance* instance) const +{ + if (instance == nullptr) + { + return -1; + } + for (size_t i = 0; i < m_listItems.size(); ++i) + { + auto itr = m_artboardInstancesMap.find(m_listItems[i]); + if (itr != m_artboardInstancesMap.end() && + itr->second.get() == instance) + { + return static_cast(i); + } + } + return -1; +} +StateMachineInstance* ArtboardComponentList::stateMachineInstance(int index) +{ + if (!virtualizationEnabled()) + { + if (index >= 0 && index < m_stateMachinesByIndex.size()) + { + return m_stateMachinesByIndex[index]; + } + return nullptr; + } + if (index >= 0 && index < m_listItems.size()) + { + auto item = listItem(index); + auto itr = m_stateMachinesMap.find(item); + if (itr != m_stateMachinesMap.end()) + { + return itr->second.get(); + } + } + return nullptr; } #ifdef WITH_RIVE_LAYOUT @@ -46,11 +245,7 @@ void* ArtboardComponentList::layoutNode(int index) void ArtboardComponentList::markLayoutNodeDirty( bool shouldForceUpdateLayoutBounds) { - bool parentIsRow = true; - if (parent()->is()) - { - parentIsRow = parent()->as()->mainAxisIsRow(); - } + bool parentIsRow = mainAxisIsRow(); for (int i = 0; i < artboardCount(); i++) { auto artboard = artboardInstance(i); @@ -70,10 +265,35 @@ void ArtboardComponentList::updateLayoutBounds(bool animate) if (artboard != nullptr) { artboard->updateLayoutBounds(animate); + auto bounds = artboard->layoutBounds(); + setItemSize(Vec2D(bounds.width(), bounds.height()), i); } } #endif + computeLayoutBounds(); +} + +#ifdef WITH_RIVE_LAYOUT +bool ArtboardComponentList::cascadeLayoutStyle( + LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime, + LayoutDirection direction) +{ + for (int i = 0; i < (int)artboardCount(); i++) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + artboard->cascadeLayoutStyle(inheritedInterpolation, + inheritedInterpolator, + inheritedInterpolationTime, + direction); + } + } + return false; } +#endif bool ArtboardComponentList::syncStyleChanges() { @@ -94,24 +314,41 @@ bool ArtboardComponentList::syncStyleChanges() } Artboard* ArtboardComponentList::findArtboard( - ViewModelInstanceListItem* listItem) const + const rcp& listItem) const { auto viewModelInstance = listItem->viewModelInstance(); if (viewModelInstance == nullptr) { return nullptr; } - auto artboard = m_artboardsMap.find(viewModelInstance->viewModelId()); + auto viewModelId = viewModelInstance->viewModelId(); + // Find artboard in the cached mappings + auto artboard = m_artboardsMap.find(viewModelId); if (artboard != m_artboardsMap.end()) { return artboard->second; } auto artboards = m_file->artboards(); + // Check if there is a special rule that maps the view model to a specific + // artboard + auto listRule = m_artboardMapRules.find(viewModelId); + if (listRule != m_artboardMapRules.end()) + { + auto artboardIndex = listRule->second; + if (artboardIndex < artboards.size()) + { + auto artboard = artboards[artboardIndex]; + m_artboardsMap[viewModelId] = artboard; + return artboard; + } + } + + // Search for the first artboard that is bound to this view model for (auto& artboard : artboards) { - if (artboard->viewModelId() == viewModelInstance->viewModelId()) + if (artboard->viewModelId() == viewModelId) { - m_artboardsMap[viewModelInstance->viewModelId()] = artboard; + m_artboardsMap[viewModelId] = artboard; return artboard; } } @@ -119,38 +356,21 @@ Artboard* ArtboardComponentList::findArtboard( return nullptr; } -void ArtboardComponentList::disposeListItem(ViewModelInstanceListItem* listItem) +void ArtboardComponentList::disposeListItem( + const rcp& listItem) { - auto artboard = m_artboardInstancesMap[listItem].get(); - if (artboard != nullptr) - { - m_artboardInstancesMap[listItem].reset(); - } - m_artboardInstancesMap.erase(listItem); - auto sm = m_stateMachinesMap[listItem].get(); - if (sm != nullptr) - { - m_stateMachinesMap[listItem].reset(); - } - m_stateMachinesMap.erase(listItem); - listItem->unref(); + removeArtboard(listItem); } std::unique_ptr ArtboardComponentList::createArtboard( Component* target, - ViewModelInstanceListItem* listItem) const + rcp listItem) const { auto artboard = findArtboard(listItem); if (artboard != nullptr) { - auto mainArtboard = target->artboard(); - auto dataContext = mainArtboard->dataContext(); - auto artboardCopy = artboard->instance(); - // artboardCopy->name(artboard->name()); - artboardCopy->bindViewModelInstance(listItem->viewModelInstance(), - dataContext, - true); - return artboardCopy; + auto inst = artboard->instance(); + return inst; } return nullptr; } @@ -160,23 +380,113 @@ std::unique_ptr ArtboardComponentList:: { if (artboard != nullptr) { - auto dataContext = artboard->dataContext(); auto stateMachineInstance = artboard->stateMachineAt(0); - stateMachineInstance->dataContext(dataContext); + linkStateMachineToArtboard(stateMachineInstance.get(), artboard); return stateMachineInstance; } return nullptr; } +void ArtboardComponentList::linkStateMachineToArtboard( + StateMachineInstance* stateMachineInstance, + ArtboardInstance* artboardInstance) +{ + if (artboardInstance != nullptr && stateMachineInstance != nullptr) + { + auto dataContext = artboardInstance->dataContext(); + stateMachineInstance->dataContext(dataContext); + // TODO: @hernan added this to make sure data binds are procesed in the + // current frame instead of waiting for the next run. But might not be + // necessary. Needs more testing. + stateMachineInstance->updateDataBinds(false); + + // Share parent artboard's focus manager and build focus tree for list + // item. + auto* parentArtboard = this->artboard(); + if (parentArtboard != nullptr && + parentArtboard->focusManager() != nullptr) + { + auto* parentFM = parentArtboard->focusManager(); + stateMachineInstance->setExternalFocusManager(parentFM); + + // Find closest focus node (handles artboard boundaries) + auto parentNode = FocusData::findClosestFocusNode(this); + + // Build list item's focus tree under parent + artboardInstance->buildFocusTree(parentFM, parentNode); + } + + // Share parent artboard's semantic manager and build semantic tree + // reparented under the enclosing SemanticData. + if (parentArtboard != nullptr && + parentArtboard->semanticManager() != nullptr) + { + auto* parentSM = parentArtboard->semanticManager(); + auto parentNode = SemanticData::findClosestSemanticNode(this); + stateMachineInstance->setExternalSemanticManager(parentSM, + parentNode); + } + } +} + +bool ArtboardComponentList::listsAreEqual( + std::vector>* list, + std::vector>* compared) +{ + if (!list || !compared) + { + return false; + } + if (list->size() != compared->size()) + { + return false; + } + size_t index = 0; + for (auto& item : *list) + { + if (item != (*compared)[index]) + { + return false; + } + ++index; + } + return true; +} + void ArtboardComponentList::updateList( - int propertyKey, - std::vector* list) + std::vector>* list) { - std::vector oldItems; - oldItems.assign(m_listItems.begin(), m_listItems.end()); + if (listsAreEqual(&m_listItems, list)) + { + return; + } + m_oldItems.clear(); + m_oldItems.assign(m_listItems.begin(), m_listItems.end()); m_listItems.clear(); m_listItems.assign(list->begin(), list->end()); - for (auto item : oldItems) + invalidateOrderedListIndicesCache(); + m_artboardSizes.clear(); + + // Clear the index vectors - they'll be rebuilt as artboards are created + m_artboardInstancesByIndex.clear(); + m_stateMachinesByIndex.clear(); + if (!virtualizationEnabled()) + { + m_artboardInstancesByIndex.resize(m_listItems.size(), nullptr); + m_stateMachinesByIndex.resize(m_listItems.size(), nullptr); + } + + auto p = layoutParent(); + if (p != nullptr) + { +#ifdef WITH_RIVE_LAYOUT + p->clearLayoutChildren(); +#endif + } + // We need to dispose old items after the layout children of the parent have + // updated to ensure no bad YGNodes are being hosted from the old data + // during clearLayoutChildren. + for (auto item : m_oldItems) { auto it = std::find(m_listItems.begin(), m_listItems.end(), item); if (it == m_listItems.end()) @@ -184,53 +494,64 @@ void ArtboardComponentList::updateList( disposeListItem(item); } } - if (parent()->is()) - { -#ifdef WITH_RIVE_LAYOUT - parent()->as()->clearLayoutChildren(); -#endif - } uint32_t index = 0; for (auto& item : m_listItems) { auto viewModelInstance = item->viewModelInstance(); if (viewModelInstance != nullptr) { - auto symbol = viewModelInstance->symbol( - ViewModelInstanceSymbolListIndexBase::typeKey); + auto symbol = + viewModelInstance->propertyValue(SymbolType::itemIndex); if (symbol != nullptr) { symbol->as()->propertyValue( index); } } - if (m_artboardInstancesMap[item] == nullptr) + auto artboard = findArtboard(item); + if (artboard != nullptr) + { + m_artboardSizes.push_back( + Vec2D(artboard->width(), artboard->height())); + } + auto itr = m_artboardInstancesMap.find(item); + if (!virtualizationEnabled()) { - auto artboardCopy = createArtboard(this, item); - if (artboardCopy != nullptr) + if (itr == m_artboardInstancesMap.end()) + { + createArtboardAt(index, false); + } + else { - auto artboardInstance = artboardCopy.get(); - auto stateMachineCopy = - createStateMachineInstance(this, artboardInstance); - m_artboardInstancesMap[item] = std::move(artboardCopy); - m_stateMachinesMap[item] = std::move(stateMachineCopy); - item->ref(); - if (artboardInstance != nullptr) + // Existing artboard - update index vectors + m_artboardInstancesByIndex[index] = itr->second.get(); + auto smItr = m_stateMachinesMap.find(item); + if (smItr != m_stateMachinesMap.end()) { - artboardInstance->host(this); + m_stateMachinesByIndex[index] = smItr->second.get(); } } } index++; } - if (parent()->is()) + computeLayoutBounds(); + syncLayoutChildren(); + markLayoutNodeDirty(); + markWorldTransformDirty(); + addDirt(ComponentDirt::Components); + recomputeListUsesDrawIndexSort(); + syncDrawIndexListeners(); +} + +void ArtboardComponentList::syncLayoutChildren() +{ + auto p = layoutParent(); + if (p != nullptr) { #ifdef WITH_RIVE_LAYOUT - parent()->as()->syncLayoutChildren(); + p->syncLayoutChildren(); #endif } - markLayoutNodeDirty(); - addDirt(ComponentDirt::Components); } bool ArtboardComponentList::advanceComponent(float elapsedSeconds, @@ -294,13 +615,75 @@ bool ArtboardComponentList::advanceComponent(float elapsedSeconds, return keepGoing; } -AABB ArtboardComponentList::layoutBounds() { return AABB(); } +void ArtboardComponentList::reset() +{ + for (auto& item : m_listItems) + { + auto itr = m_artboardInstancesMap.find(item); + if (m_shouldResetInstances) + { + auto viewModelInstance = item->viewModelInstance(); + if (viewModelInstance != nullptr) + { + viewModelInstance->advanced(); + } + if (itr != m_artboardInstancesMap.end() && itr->second != nullptr) + { + auto dataContext = itr->second->dataContext(); + if (dataContext != nullptr) + { + auto boundInstance = dataContext->viewModelInstance(); + if (boundInstance != nullptr && + boundInstance != viewModelInstance) + { + boundInstance->advanced(); + } + } + } + } + if (itr != m_artboardInstancesMap.end()) + { + itr->second->reset(); + } + } +} + +AABB ArtboardComponentList::layoutBounds() +{ + return AABB(0, 0, m_layoutSize.x, m_layoutSize.y); +} AABB ArtboardComponentList::layoutBoundsForNode(int index) { - if (index >= 0 && index < numLayoutNodes()) + if (virtualizationEnabled()) + { + auto realIndex = std::fmod(index, m_listItems.size()); + auto gap = this->gap(); + float runningSize = 0; + bool isHorizontal = mainAxisIsRow(); + for (int i = 0; i < realIndex; i++) + { + auto size = m_artboardSizes[i]; + if (isHorizontal) + { + runningSize += size.x + gap; + } + else + { + runningSize += size.y + gap; + } + } + auto itemSize = m_artboardSizes[realIndex]; + double left = isHorizontal ? runningSize : 0; + double top = isHorizontal ? 0 : runningSize; + return AABB(left, top, left + itemSize.x, top + itemSize.y); + } + else { - return artboardInstance(index)->layoutBounds(); + if (index >= 0 && index < numLayoutNodes()) + { + return artboardInstance(index)->layoutBounds(); + } } return AABB(); } @@ -318,108 +701,448 @@ void ArtboardComponentList::markHostingLayoutDirty( break; } } + markWorldTransformDirty(); } -void ArtboardComponentList::draw(Renderer* renderer) +bool ArtboardComponentList::willDraw() { - ClipResult clipResult = applyClip(renderer); - if (clipResult == ClipResult::noClip) - { - // We didn't clip, so make sure to save as we'll be doing some - // transformations. - renderer->save(); - } - if (clipResult != ClipResult::emptyClip) - { - renderer->transform(worldTransform()); - for (int i = 0; i < artboardCount(); i++) - { - auto artboard = artboardInstance(i); - if (artboard != nullptr) - { - renderer->save(); - auto bounds = artboard->layoutBounds(); - auto artboardTransform = - Mat2D::fromTranslate(bounds.left(), bounds.top()); - renderer->transform(artboardTransform); - artboard->draw(renderer); - renderer->restore(); - } - } - } - renderer->restore(); + return Super::willDraw() && m_listItems.size() > 0; } -Core* ArtboardComponentList::hitTest(HitInfo*, const Mat2D&) { return nullptr; } - -void ArtboardComponentList::update(ComponentDirt value) +void ArtboardComponentList::invalidateOrderedListIndicesCache() { - Super::update(value); - if (artboardCount() == 0) - { - return; - } + m_orderedListIndicesCacheValid = false; +} - if (hasDirt(value, ComponentDirt::RenderOpacity)) +void ArtboardComponentList::recomputeListUsesDrawIndexSort() +{ + const bool prevUsesDrawIndexSort = m_listUsesDrawIndexSort; + m_listUsesDrawIndexSort = false; + for (const auto& item : m_listItems) { - for (int i = 0; i < artboardCount(); i++) + auto vmi = item->viewModelInstance().get(); + if (vmi == nullptr) { - auto artboard = artboardInstance(i); - if (artboard != nullptr) - { - artboard->opacity(renderOpacity()); - } + continue; } - } - if (hasDirt(value, ComponentDirt::Components)) - { - for (int i = 0; i < artboardCount(); i++) + auto* vm = vmi->viewModel(); + if (vm != nullptr && vm->property(SymbolType::drawIndex) != nullptr) { - auto artboard = artboardInstance(i); - if (artboard != nullptr) + m_listUsesDrawIndexSort = true; + if (prevUsesDrawIndexSort != m_listUsesDrawIndexSort) { - artboard->updatePass(false); + invalidateOrderedListIndicesCache(); } + return; } } + if (prevUsesDrawIndexSort != m_listUsesDrawIndexSort) + { + invalidateOrderedListIndicesCache(); + } } -void ArtboardComponentList::updateConstraints() +float ArtboardComponentList::listItemDrawIndex(int index) const { - if (m_layoutConstraints.size() > 0) + if (index < 0 || static_cast(index) >= m_listItems.size()) { - for (auto parentConstraint : m_layoutConstraints) + return 0.0f; + } + auto* vmi = + m_listItems[static_cast(index)]->viewModelInstance().get(); + if (vmi == nullptr) + { + return 0.0f; + } + auto* vm = vmi->viewModel(); + if (vm == nullptr || vm->property(SymbolType::drawIndex) == nullptr) + { + return 0.0f; + } + auto* prop = vmi->propertyValue(SymbolType::drawIndex); + if (prop != nullptr && prop->is()) + { + float v = prop->as()->propertyValue(); + if (!std::isfinite(v)) { - parentConstraint->constrainChild(this); + return 0.0f; } + return v; } - Super::updateConstraints(); + return 0.0f; } -void ArtboardComponentList::internalDataContext(DataContext* value) +void ArtboardComponentList::clearDrawIndexListeners() { - // In the future, we may need to reconcile existing artboards with the - // new datacontext passed in here + m_drawIndexDependents.clear(); } -void ArtboardComponentList::populateDataBinds(std::vector* dataBinds) +void ArtboardComponentList::removeDrawIndexListenerForItem( + const rcp& listItem) { - // At the time this is called, artboards will not yet have been instanced - // so its essentially a no-op and the data binds will be populated at - // artboard creation time by calling artboard->bindViewModelInstance - // passing isRoot=true + m_drawIndexDependents.erase(listItem); +} + +void ArtboardComponentList::syncDrawIndexListeners() +{ + clearDrawIndexListeners(); + if (!m_listUsesDrawIndexSort) + { + return; + } + for (const auto& item : m_listItems) + { + auto vmi = item->viewModelInstance().get(); + if (vmi == nullptr) + { + continue; + } + auto* prop = vmi->propertyValue(SymbolType::drawIndex); + if (prop == nullptr) + { + continue; + } + m_drawIndexDependents[item] = + std::make_unique(this, prop); + } +} + +void ArtboardComponentList::ensureOrderedListIndices() +{ + const int count = static_cast(m_listItems.size()); + if (count == 0) + { + m_orderedListIndicesCacheValid = false; + m_cachedOrderedListIndices.clear(); + return; + } + + if (m_orderedListIndicesCacheValid) + { + return; + } + + std::vector& cache = m_cachedOrderedListIndices; + cache.clear(); + const bool useVirtualWindow = virtualizationEnabled() && + m_visibleStartIndex >= 0 && + m_visibleEndIndex >= 0; + + if (useVirtualWindow) + { + auto startIndex = m_visibleStartIndex % count; + auto endIndex = m_visibleEndIndex % count; + int i = startIndex; + while (true) + { + cache.push_back(i); + if (i == endIndex) + { + break; + } + i = (i + 1) % count; + } + } + else + { + cache.reserve(static_cast(count)); + for (int i = 0; i < count; i++) + { + cache.push_back(i); + } + } + + if (m_listUsesDrawIndexSort) + { + std::sort(cache.begin(), cache.end(), [this](int a, int b) { + const float da = listItemDrawIndex(a); + const float db = listItemDrawIndex(b); + if (da != db) + { + return da < db; + } + return a < b; + }); + } + + m_orderedListIndicesCacheValid = true; +} + +const std::vector& ArtboardComponentList::orderedListIndices() +{ + ensureOrderedListIndices(); + return m_cachedOrderedListIndices; +} + +void ArtboardComponentList::draw(Renderer* renderer) +{ + if (m_needsSaveOperation) + { + renderer->save(); + } + if (virtualizationEnabled()) + { + renderer->transform( + parent()->as()->worldTransform()); + if (m_visibleStartIndex != -1 && m_visibleEndIndex != -1) + { + // We need to render in the correct order so we get the correct + // z-index for items in cases where there is overlap + for (int i : orderedListIndices()) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + renderer->save(); + auto transform = m_artboardTransforms[artboard]; + renderer->transform(transform); + artboard->drawInternal(renderer); + renderer->restore(); + } + } + } + } + else + { + renderer->transform(worldTransform()); + for (int i : orderedListIndices()) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + renderer->save(); + auto transform = m_artboardTransforms[artboard]; + renderer->transform(transform); + artboard->drawInternal(renderer); + renderer->restore(); + } + } + } + if (m_needsSaveOperation) + { + renderer->restore(); + } +} + +Core* ArtboardComponentList::hitTest(HitInfo*, const Mat2D&) { return nullptr; } + +bool ArtboardComponentList::hitTestHost(const Vec2D& position, + bool skipOnUnclipped, + ArtboardInstance* artboard) +{ + if (artboard == nullptr) + { + return false; + } + auto bounds = artboardPosition(artboard); + Vec2D offset(bounds.x + position.x, bounds.y + position.y); + auto transform = virtualizationEnabled() + ? parent()->as()->worldTransform() + : worldTransform(); + return parent()->hitTestPoint(transform * offset, skipOnUnclipped, false); +} + +Vec2D ArtboardComponentList::hostTransformPoint( + const Vec2D& vec, + ArtboardInstance* artboardInstance) +{ + auto bounds = artboardPosition(artboardInstance); + Vec2D offset(bounds.x + vec.x, bounds.y + vec.y); + auto transform = virtualizationEnabled() + ? parent()->as()->worldTransform() + : worldTransform(); + auto localVec = transform * offset; + auto ab = artboard(); + return ab ? ab->rootTransform(localVec) : localVec; +} + +Mat2D ArtboardComponentList::worldTransformForArtboard( + ArtboardInstance* artboardInstance) +{ + auto offset = artboardPosition(artboardInstance); + // For scroll-into-view calculations, we need the position in content-local + // space (without scroll applied). Use the list's layout position combined + // with parent's world transform, rather than worldTransform() which may + // include scroll constraints. + auto* parentLayout = parent() != nullptr && parent()->is() + ? parent()->as() + : nullptr; + if (parentLayout != nullptr) + { + AABB listBounds = layoutBounds(); + Mat2D transform = + parentLayout->worldTransform() * + Mat2D::fromTranslate(listBounds.minX, listBounds.minY); + return transform * Mat2D::fromTranslate(offset.x, offset.y); + } + auto transform = virtualizationEnabled() + ? parent()->as()->worldTransform() + : worldTransform(); + return transform * Mat2D::fromTranslate(offset.x, offset.y); +} + +void ArtboardComponentList::update(ComponentDirt value) +{ + Super::update(value); + if (artboardCount() == 0) + { + return; + } + + if (hasDirt(value, ComponentDirt::WorldTransform)) + { + // Mark semantic bounds dirty for nodes inside each list item + // artboard. Their root-space bounds depend on the host's + // world transform. + for (int i = 0; i < artboardCount(); i++) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + artboard->markSemanticBoundaryTransformDirty(); + } + } + } + if (hasDirt(value, ComponentDirt::RenderOpacity)) + { + for (int i = 0; i < artboardCount(); i++) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + artboard->opacity(renderOpacity()); + } + } + } + if (hasDirt(value, ComponentDirt::Components)) + { + for (int i = 0; i < artboardCount(); i++) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + artboard->updatePass(false); + } + } + } +} + +void ArtboardComponentList::updateWorldTransform() +{ + updateArtboardsWorldTransform(); + Super::updateWorldTransform(); +} + +void ArtboardComponentList::updateArtboardsWorldTransform() +{ + auto count = m_listItems.size(); + if (count == 0) + { + return; + } + // We only update non layout transforms here + if (!virtualizationEnabled()) + { + auto useLayout = layoutParent() != nullptr; + for (int i = 0; i < count; i++) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + auto bounds = useLayout ? artboard->layoutBounds() + : artboard->worldBounds(); + auto origin = useLayout ? artboard->origin() : Vec2D(); + m_artboardTransforms[artboard] = + Mat2D::fromTranslate(bounds.left() - origin.x, + bounds.top() - origin.y); + } + } + } +} + +void ArtboardComponentList::updateConstraints() +{ + if (m_layoutConstraints.size() > 0) + { + for (auto parentConstraint : m_layoutConstraints) + { + parentConstraint->constrainChild(this); + } + } + if (m_listConstraints.size() > 0 && !virtualizationEnabled()) + { + for (auto listConstraint : m_listConstraints) + { + listConstraint->constrainList(this); + } + } + for (auto constraint : constraints()) + { + auto listConstraint = ListConstraint::from(constraint); + if (listConstraint != nullptr) + { + continue; + } + constraint->constrain(this); + } +} + +void ArtboardComponentList::internalDataContext(rcp value) +{ + // Reconcile the existing data contexts with the new parent + for (auto& artboard : m_artboardInstancesMap) + { + auto dataContext = artboard.second->dataContext(); + if (dataContext != nullptr) + { + dataContext->parent(value); + artboard.second->internalDataContext(dataContext); + } + } + for (auto& sm : m_stateMachinesMap) + { + auto dataContext = sm.second->dataContext(); + if (dataContext != nullptr) + { + dataContext->parent(value); + sm.second->internalDataContext(dataContext); + } + } } void ArtboardComponentList::bindViewModelInstance( rcp viewModelInstance, - DataContext* parent) + rcp parent) { // At the time this is called, artboards will not yet have been instanced // so its essentially a no-op and the call to bindViewModelInstance on // each artboard is made at the time of artboard instancing } -void ArtboardComponentList::clearDataContext() { reset(); } +void ArtboardComponentList::clearDataContext() {} +void ArtboardComponentList::unbind() { clear(); } +void ArtboardComponentList::updateDataBinds() +{ + for (int i = 0; i < artboardCount(); i++) + { + auto stateMachine = stateMachineInstance(i); + if (stateMachine != nullptr) + { + stateMachine->updateDataBinds(false); + } + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + artboard->updateDataBinds(); + } + } +} + +Vec2D ArtboardComponentList::artboardPosition(ArtboardInstance* artboard) +{ + auto mat = m_artboardTransforms[artboard]; + return Vec2D(mat[4], mat[5]); +} bool ArtboardComponentList::worldToLocal(Vec2D world, Vec2D* local, int index) { @@ -429,9 +1152,12 @@ bool ArtboardComponentList::worldToLocal(Vec2D world, Vec2D* local, int index) { return false; } - auto bounds = artboard->layoutBounds(); + Vec2D offset = artboardPosition(artboard); + auto transform = virtualizationEnabled() + ? parent()->as()->worldTransform() + : worldTransform(); auto artboardTransform = - worldTransform() * Mat2D::fromTranslate(bounds.left(), bounds.top()); + transform * Mat2D::fromTranslate(offset.x, offset.y); Mat2D toMountedArtboard; if (!artboardTransform.invert(&toMountedArtboard)) { @@ -452,4 +1178,637 @@ Core* ArtboardComponentList::clone() const static_cast(ArtboardComponentListBase::clone()); clone->file(file()); return clone; +} + +void ArtboardComponentList::createArtboardAt(int index, bool forceLayoutSync) +{ + auto item = listItem(index); + if (item != nullptr) + { + auto artboardCopy = createArtboard(this, item); + if (artboardCopy != nullptr) + { + attachArtboardOverride(artboardCopy.get(), item); + addArtboardAt(std::move(artboardCopy), index, forceLayoutSync); + } + } +} + +void ArtboardComponentList::addArtboardAt( + std::unique_ptr artboard, + int index, + bool forceLayoutSync) +{ + auto item = listItem(index); + if (item != nullptr) + { + auto artboardInstance = artboard.get(); + m_artboardInstancesMap[item] = std::move(artboard); + bindArtboard(artboardInstance, item); + if (artboardInstance != nullptr) + { + artboardInstance->host(this); + artboardInstance->frameOrigin(false); + artboardInstance->parentIsRow(mainAxisIsRow()); + } + if (forceLayoutSync) + { + syncLayoutChildren(); + } + + StateMachineInstance* stateMachineInstance = nullptr; + auto artboard = findArtboard(item); + if (artboard != nullptr) + { + + auto& smPool = m_stateMachinesPool[artboard]; + if (!smPool.empty()) + { + auto sm = smPool.back().get(); + + sm->resetState(); + applyRecorders(sm, artboard); + m_stateMachinesMap[item] = std::move(smPool.back()); + linkStateMachineToArtboard(sm, artboardInstance); + stateMachineInstance = sm; + smPool.pop_back(); + } + } + if (stateMachineInstance == nullptr) + { + auto stateMachineCopy = + createStateMachineInstance(this, artboardInstance); + stateMachineInstance = stateMachineCopy.get(); + m_stateMachinesMap[item] = std::move(stateMachineCopy); + } + + if (!virtualizationEnabled()) + { + if (index >= m_artboardInstancesByIndex.size()) + { + m_artboardInstancesByIndex.resize(index + 1, nullptr); + m_stateMachinesByIndex.resize(index + 1, nullptr); + } + m_artboardInstancesByIndex[index] = artboardInstance; + m_stateMachinesByIndex[index] = stateMachineInstance; + } + } +} + +void ArtboardComponentList::bindArtboard( + ArtboardInstance* artboardInstance, + rcp listItem) +{ + if (artboardInstance != nullptr) + { + auto mainArtboard = this->artboard(); + auto dataContext = mainArtboard->dataContext(); + rcp viewModelInstance = nullptr; + + // Check if the source artboard is stateful - if so, create a new + // instance for it (takes priority over any existing list item + // instance). Clone the list item's instance when available so we + // pick up its property values; otherwise fall back to the default. + if (m_file != nullptr) + { + auto source = artboardInstance->artboardSource(); + if (source != nullptr && source->isStateful()) + { + auto listItemInstance = listItem->viewModelInstance(); + if (listItemInstance != nullptr) + { + auto copy = rcp( + listItemInstance->clone()->as()); + m_file->completeViewModelProperties(copy.get()); +#ifdef WITH_RIVE_TOOLS + if (copy) + { + m_file->registerViewModelInstance(copy.get(), copy); + } +#endif + viewModelInstance = copy; + + // Create bridge data binds between the original and + // cloned VM instances for input/output properties. + createBridgeBinds(listItem, + listItemInstance.get(), + copy.get()); + } + else + { + auto viewModel = m_file->viewModel(source->viewModelId()); + if (viewModel != nullptr) + { + viewModelInstance = + m_file->createDefaultViewModelInstance(viewModel); + } + // Store the default instance on the list item so we + // don't recreate one every time. + if (viewModelInstance != nullptr) + { + listItem->viewModelInstance(viewModelInstance); + } + } + } + } + + // Fall back to the list item's VM instance if not stateful. + if (viewModelInstance == nullptr) + { + viewModelInstance = listItem->viewModelInstance(); + } + + // TODO: @hernan added this to make sure data binds are procesed in the + // current frame instead of waiting for the next run. But might not be + // necessary. Needs more testing. + artboardInstance->bindViewModelInstance(viewModelInstance, dataContext); + artboardInstance->updateDataBinds(); + + invalidateOrderedListIndicesCache(); + } +} + +void ArtboardComponentList::removeArtboardAt(int index) +{ + if (!virtualizationEnabled() && index >= 0 && + index < m_artboardInstancesByIndex.size()) + { + m_artboardInstancesByIndex[index] = nullptr; + m_stateMachinesByIndex[index] = nullptr; + } + auto item = listItem(index); + removeArtboard(item); +} + +void ArtboardComponentList::removeArtboard(rcp item) +{ + invalidateOrderedListIndicesCache(); + removeDrawIndexListenerForItem(item); + auto itr = m_artboardInstancesMap.find(item); + if (itr != m_artboardInstancesMap.end()) + { + // Clean up semantic tree before destroying the artboard. + if (itr->second != nullptr) + { + itr->second->cleanupSemanticTree(); + } + // Clean up focus tree before destroying the artboard to prevent + // use-after-free when the FocusManager still holds references + // to FocusNodes pointing to FocusData in this artboard. + if (itr->second != nullptr) + { + itr->second->cleanupFocusTree(); + } + clearArtboardOverride(itr->second.get()); + } + // Remove bridge data binds before destroying the artboard. + removeBridgeBinds(item); + // Destroy state machines BEFORE artboards to ensure FocusListenerGroup + // can unregister from FocusData before the artboard (and its FocusData) + // is destroyed. Otherwise we get use-after-free in ~FocusListenerGroup. + m_stateMachinesMap.erase(item); + m_artboardInstancesMap.erase(item); +} + +/// Returns the propertyValuePropertyKey for a ViewModelInstanceValue based +/// on its core type, or Core::invalidPropertyKey if unsupported. +static uint16_t propertyValueKeyForType(uint16_t coreType) +{ + switch (coreType) + { + case ViewModelInstanceNumberBase::typeKey: + return ViewModelInstanceNumberBase::propertyValuePropertyKey; + case ViewModelInstanceStringBase::typeKey: + return ViewModelInstanceStringBase::propertyValuePropertyKey; + case ViewModelInstanceColorBase::typeKey: + return ViewModelInstanceColorBase::propertyValuePropertyKey; + case ViewModelInstanceBooleanBase::typeKey: + return ViewModelInstanceBooleanBase::propertyValuePropertyKey; + case ViewModelInstanceEnumBase::typeKey: + return ViewModelInstanceEnumBase::propertyValuePropertyKey; + case ViewModelInstanceTriggerBase::typeKey: + return ViewModelInstanceTriggerBase::propertyValuePropertyKey; + case ViewModelInstanceViewModelBase::typeKey: + return ViewModelInstanceViewModelBase::propertyValuePropertyKey; + default: + return Core::invalidPropertyKey; + } +} + +void ArtboardComponentList::createBridgeBinds( + rcp listItem, + ViewModelInstance* original, + ViewModelInstance* clone) +{ + if (original == nullptr || clone == nullptr) + { + return; + } + auto* vm = clone->viewModel(); + if (vm == nullptr) + { + return; + } + auto* parentArtboard = artboard(); + if (parentArtboard == nullptr) + { + return; + } + + auto& binds = m_bridgeDataBinds[listItem]; + + for (auto& cloneValueRcp : clone->propertyValues()) + { + auto* cloneValue = cloneValueRcp.get(); + auto* prop = cloneValue->viewModelProperty(); + if (prop == nullptr || (!prop->isInput() && !prop->isOutput())) + { + continue; + } + + // Find the matching property on the original by ViewModelProperty + // pointer (both instances share the same ViewModel definition). + ViewModelInstanceValue* originalValue = nullptr; + for (auto& origRcp : original->propertyValues()) + { + if (origRcp->viewModelProperty() == prop) + { + originalValue = origRcp.get(); + break; + } + } + if (originalValue == nullptr) + { + continue; + } + + auto propKey = propertyValueKeyForType(cloneValue->coreType()); + if (propKey == Core::invalidPropertyKey) + { + continue; + } + + if (prop->isInput()) + { + // Input: original → clone (source to target) + auto bind = std::make_unique(); + bind->source(ref_rcp(originalValue)); + bind->target(cloneValue); + bind->propertyKey(propKey); + bind->flags(static_cast(DataBindFlags::ToTarget)); + bind->bind(); + parentArtboard->addDataBind(bind.get()); + binds.push_back(std::move(bind)); + } + + if (prop->isOutput()) + { + // Output: clone → original. Uses ToSource direction so the + // bind is in the persisting list and continuously syncs + // changes made by the component's state machine back to + // the user-provided VM instance. + // ToSource semantics: reads from target, writes to source. + auto bind = std::make_unique(); + bind->source(ref_rcp(originalValue)); + bind->target(cloneValue); + bind->propertyKey(propKey); + bind->flags(static_cast(DataBindFlags::ToSource)); + bind->bind(); + parentArtboard->addDataBind(bind.get()); + binds.push_back(std::move(bind)); + } + } +} + +void ArtboardComponentList::removeBridgeBinds( + const rcp& listItem) +{ + auto itr = m_bridgeDataBinds.find(listItem); + if (itr == m_bridgeDataBinds.end()) + { + return; + } + auto* parentArtboard = artboard(); + for (auto& bind : itr->second) + { + bind->unbind(); + if (parentArtboard != nullptr) + { + parentArtboard->removeDataBind(bind.get()); + } + } + m_bridgeDataBinds.erase(itr); +} + +void ArtboardComponentList::createArtboardRecorders(const Artboard* artboard) +{ + if (artboard == nullptr) + { + return; + } + auto recorderIt = m_propertyRecordersMap.find(artboard); + if (recorderIt == m_propertyRecordersMap.end()) + { + auto propertyRecorder = std::make_unique(); + propertyRecorder->recordArtboard(artboard); + m_propertyRecordersMap[artboard] = std::move(propertyRecorder); + for (auto& nestedArtboard : artboard->nestedArtboards()) + { + if (nestedArtboard == nullptr) + { + continue; + } + auto sourceArtboard = nestedArtboard->sourceArtboard(); + createArtboardRecorders(sourceArtboard); + } + } +} + +void ArtboardComponentList::applyRecorders(Artboard* artboard, + const Artboard* sourceArtboard) +{ + if (artboard == nullptr) + { + return; + } + auto sourcedArtboardIt = m_propertyRecordersMap.find(sourceArtboard); + if (sourcedArtboardIt != m_propertyRecordersMap.end()) + { + auto propertyRecorder = sourcedArtboardIt->second.get(); + if (propertyRecorder != nullptr) + { + propertyRecorder->apply(artboard); + } + } + for (auto& nestedArtboard : artboard->nestedArtboards()) + { + if (nestedArtboard == nullptr) + { + continue; + } + auto nestedInstance = nestedArtboard->sourceArtboard(); + if (nestedInstance == nullptr) + { + continue; + } + applyRecorders(nestedInstance, nestedInstance->artboardSource()); + } +} + +void ArtboardComponentList::applyRecorders( + StateMachineInstance* stateMachineInstance, + const Artboard* sourceArtboard) +{ + auto it = m_propertyRecordersMap.find(sourceArtboard); + if (it == m_propertyRecordersMap.end()) + { + return; + } + auto propertyRecorder = it->second.get(); + if (propertyRecorder != nullptr) + { + propertyRecorder->apply(stateMachineInstance); + } +} + +void ArtboardComponentList::addVirtualizable(int index) +{ + auto listItem = this->listItem(index); + if (listItem != nullptr) + { + auto artboard = findArtboard(listItem); + if (artboard != nullptr) + { + createArtboardRecorders(artboard); + auto& pool = m_resourcePool[artboard]; + if (pool.empty()) + { + createArtboardAt(index); + } + else + { + auto pooledArtboard = pool.back().get(); + applyRecorders(pooledArtboard, artboard); + addArtboardAt(std::move(pool.back()), index); + pool.pop_back(); + } + // Add components dirt so we process layout updates in the same + // frame that a mounted artboard is added + addDirt(ComponentDirt::Components); + auto p = layoutParent(); + if (p != nullptr) + { + p->markLayoutStyleDirty(); + } + } + } +} + +void ArtboardComponentList::removeVirtualizable(int index) +{ + auto listItem = this->listItem(index); + if (listItem != nullptr) + { + auto artboard = findArtboard(listItem); + auto artboardInstance = std::move(m_artboardInstancesMap[listItem]); + if (artboard != nullptr && artboardInstance != nullptr) + { + auto& pool = m_resourcePool[artboard]; + pool.push_back(std::move(artboardInstance)); + } + auto smInstanceIterator = m_stateMachinesMap.find(listItem); + if (smInstanceIterator != m_stateMachinesMap.end()) + { + auto& smPool = m_stateMachinesPool[artboard]; + smPool.push_back(std::move(smInstanceIterator->second)); + } + } + removeArtboardAt(index); +} + +void ArtboardComponentList::setVirtualizablePosition(int index, Vec2D position) +{ + auto artboard = this->artboardInstance(index); + if (artboard != nullptr) + { + auto useLayout = layoutParent() != nullptr; + auto origin = useLayout ? artboard->origin() : Vec2D(); + m_artboardTransforms[artboard] = + Mat2D::fromTranslate(position.x - origin.x, position.y - origin.y); + } +} + +bool ArtboardComponentList::virtualizationEnabled() +{ + auto virtualizer = scrollConstraint(); + return virtualizer != nullptr && virtualizer->virtualize(); +} + +ScrollConstraint* ArtboardComponentList::scrollConstraint() +{ + for (auto parentConstraint : m_layoutConstraints) + { + if (parentConstraint->constraint()->is()) + { + return parentConstraint->constraint()->as(); + } + } + return nullptr; +} + +void ArtboardComponentList::computeLayoutBounds() +{ + if (virtualizationEnabled()) + { + auto gap = this->gap(); + auto runningWidth = 0.0f; + auto runningHeight = 0.0f; + bool isHorz = mainAxisIsRow(); + for (int i = 0; i < m_artboardSizes.size(); i++) + { + auto size = m_artboardSizes[i]; + auto realGap = i == m_artboardSizes.size() - 1 ? 0 : gap; + if (isHorz) + { + runningWidth += size.x + realGap; + runningHeight = std::max(runningHeight, size.y); + } + else + { + runningWidth = std::max(runningWidth, size.x); + runningHeight += size.y + realGap; + } + } + m_layoutSize = Vec2D(runningWidth, runningHeight); + + auto scroll = scrollConstraint(); + if (scroll != nullptr) + { + scroll->constrainVirtualized(true); + } + } +} + +Vec2D ArtboardComponentList::size() { return m_layoutSize; } + +Vec2D ArtboardComponentList::itemSize(int index) +{ + return index < m_artboardSizes.size() ? m_artboardSizes[index] : Vec2D(); +} + +void ArtboardComponentList::setItemSize(Vec2D size, int index) +{ + if (index < m_artboardSizes.size()) + { + m_artboardSizes[index] = size; + } +} + +float ArtboardComponentList::gap() +{ + auto p = layoutParent(); + if (p != nullptr) + { + return mainAxisIsRow() ? p->gapHorizontal() : p->gapVertical(); + } + return 0.0f; +} + +void ArtboardComponentList::attachArtboardOverride( + ArtboardInstance* instance, + rcp listItem) +{ + + auto viewModelInstance = listItem->viewModelInstance(); + if (viewModelInstance == nullptr) + { + return; + } + auto artboards = m_file->artboards(); + int artboardIndex = -1; + for (auto& artboard : artboards) + { + artboardIndex++; + + if (artboard->viewModelId() == viewModelInstance->viewModelId()) + { + break; + } + } + if (artboardIndex < 0 && artboardIndex >= artboards.size()) + { + return; + } + ArtboardComponentListOverride* artboardOverride = nullptr; + for (auto& child : children()) + { + if (child->is()) + { + if (child->as()->artboardId() == -1) + { + artboardOverride = child->as(); + } + else if (child->as()->artboardId() == + artboardIndex) + { + artboardOverride = child->as(); + break; + } + } + } + if (artboardOverride != nullptr) + { + artboardOverride->addArtboard(instance); + } +} + +void ArtboardComponentList::clearArtboardOverride( + ArtboardInstance* artboardInstance) +{ + for (auto& child : children()) + { + if (child->is()) + { + // Passing the artboard to all overrides in case in the future we + // support stacking overrides on top of each other. + // Currently all except one will be a no-op. + child->as()->removeArtboard( + artboardInstance); + } + } +} + +bool ArtboardComponentList::mainAxisIsRow() +{ + auto p = layoutParent(); + return p != nullptr ? p->mainAxisIsRow() : true; +} + +LayoutComponent* ArtboardComponentList::layoutParent() +{ + if (parent() != nullptr && parent()->is()) + { + return parent()->as(); + } + return nullptr; +} + +const Mat2D& ArtboardComponentList::listTransform() { return worldTransform(); } + +void ArtboardComponentList::listItemTransforms(std::vector& transforms) +{ + auto count = m_listItems.size(); + for (int i = 0; i < count; i++) + { + auto artboard = artboardInstance(i); + if (artboard != nullptr) + { + transforms.push_back(&m_artboardTransforms[artboard]); + } + } +} + +void ArtboardComponentList::addMapRule(ArtboardListMapRule* rule) +{ + m_artboardMapRules[rule->viewModelId()] = rule->artboardId(); } \ No newline at end of file diff --git a/thirdparty/rive/source/artboard_list_map_rule.cpp b/thirdparty/rive/source/artboard_list_map_rule.cpp new file mode 100644 index 000000000..ccb721104 --- /dev/null +++ b/thirdparty/rive/source/artboard_list_map_rule.cpp @@ -0,0 +1,21 @@ +#include "rive/component.hpp" +#include "rive/file.hpp" +#include "rive/artboard_list_map_rule.hpp" +#include "rive/artboard_component_list.hpp" + +using namespace rive; + +StatusCode ArtboardListMapRule::onAddedDirty(CoreContext* context) +{ + StatusCode code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + if (!parent()->is()) + { + return StatusCode::MissingObject; + } + parent()->as()->addMapRule(this); + return StatusCode::Ok; +} \ No newline at end of file diff --git a/thirdparty/rive/source/artboard_referencer.cpp b/thirdparty/rive/source/artboard_referencer.cpp new file mode 100644 index 000000000..d307550f8 --- /dev/null +++ b/thirdparty/rive/source/artboard_referencer.cpp @@ -0,0 +1,58 @@ +#include "rive/artboard_referencer.hpp" +#include "rive/artboard.hpp" +#include "rive/nested_artboard.hpp" +#include "rive/nested_artboard_leaf.hpp" +#include "rive/nested_artboard_layout.hpp" +#include "rive/script_input_artboard.hpp" +#include "rive/file.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" + +using namespace rive; + +Artboard* ArtboardReferencer::findArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard, + Artboard* parentArtboard, + File* file) +{ + if (viewModelInstanceArtboard == nullptr) + { + return nullptr; + } + if (viewModelInstanceArtboard->asset() != nullptr) + { + if (!parentArtboard || + !parentArtboard->isAncestor( + viewModelInstanceArtboard->asset()->artboard())) + { + return viewModelInstanceArtboard->asset()->artboard(); + } + return nullptr; + } + else if (file != nullptr) + { + auto asset = file->artboard(viewModelInstanceArtboard->propertyValue()); + if (asset != nullptr) + { + auto artboardAsset = asset->as(); + if (!parentArtboard || !parentArtboard->isAncestor(artboardAsset)) + { + return artboardAsset; + } + } + } + return nullptr; +} + +ArtboardReferencer* ArtboardReferencer::from(Core* component) +{ + switch (component->coreType()) + { + case NestedArtboardBase::typeKey: + case NestedArtboardLeafBase::typeKey: + case NestedArtboardLayoutBase::typeKey: + return component->as(); + case ScriptInputArtboardBase::typeKey: + return component->as(); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive/source/assets/audio_asset.cpp b/thirdparty/rive/source/assets/audio_asset.cpp index de59faea7..194b1c61e 100644 --- a/thirdparty/rive/source/assets/audio_asset.cpp +++ b/thirdparty/rive/source/assets/audio_asset.cpp @@ -11,7 +11,7 @@ bool AudioAsset::decode(SimpleArray& bytes, Factory* factory) { #ifdef WITH_RIVE_AUDIO // Steal the bytes. - m_audioSource = rcp(new AudioSource(std::move(bytes))); + m_audioSource = AudioSource::MakeAudioSource((std::move(bytes))); #endif return true; } diff --git a/thirdparty/rive/source/assets/blob_asset.cpp b/thirdparty/rive/source/assets/blob_asset.cpp new file mode 100644 index 000000000..062dbb9a4 --- /dev/null +++ b/thirdparty/rive/source/assets/blob_asset.cpp @@ -0,0 +1,11 @@ +#include "rive/assets/blob_asset.hpp" + +using namespace rive; + +bool BlobAsset::decode(SimpleArray& data, Factory*) +{ + m_bytes = std::move(data); + return true; +} + +std::string BlobAsset::fileExtension() const { return "blob"; } diff --git a/thirdparty/rive/source/assets/file_asset.cpp b/thirdparty/rive/source/assets/file_asset.cpp index 8f99d2f1e..0a95f2d6a 100644 --- a/thirdparty/rive/source/assets/file_asset.cpp +++ b/thirdparty/rive/source/assets/file_asset.cpp @@ -10,13 +10,16 @@ using namespace rive; StatusCode FileAsset::import(ImportStack& importStack) { - auto backboardImporter = - importStack.latest(Backboard::typeKey); - if (backboardImporter == nullptr) + if (addsToBackboard()) { - return StatusCode::MissingObject; + auto backboardImporter = + importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + backboardImporter->addFileAsset(ref_rcp(this)); } - backboardImporter->addFileAsset(this); return Super::import(importStack); } diff --git a/thirdparty/rive/source/assets/file_asset_contents.cpp b/thirdparty/rive/source/assets/file_asset_contents.cpp index dbe9f1b34..da6ef4bad 100644 --- a/thirdparty/rive/source/assets/file_asset_contents.cpp +++ b/thirdparty/rive/source/assets/file_asset_contents.cpp @@ -31,3 +31,16 @@ void FileAssetContents::copyBytes(const FileAssetContentsBase& object) } SimpleArray& FileAssetContents::bytes() { return m_bytes; } + +void FileAssetContents::decodeSignature(Span value) +{ + m_signature = SimpleArray(value.data(), value.size()); +} + +void FileAssetContents::copySignature(const FileAssetContentsBase& object) +{ + // Should never be called. + assert(false); +} + +SimpleArray& FileAssetContents::signature() { return m_signature; } \ No newline at end of file diff --git a/thirdparty/rive/source/assets/file_asset_referencer.cpp b/thirdparty/rive/source/assets/file_asset_referencer.cpp index 5c703d9d4..7853a8ba6 100644 --- a/thirdparty/rive/source/assets/file_asset_referencer.cpp +++ b/thirdparty/rive/source/assets/file_asset_referencer.cpp @@ -26,7 +26,7 @@ StatusCode FileAssetReferencer::registerReferencer(ImportStack& importStack) return StatusCode::Ok; } -void FileAssetReferencer::setAsset(FileAsset* asset) +void FileAssetReferencer::setAsset(rcp asset) { if (m_fileAsset != nullptr) { diff --git a/thirdparty/rive/source/assets/image_asset.cpp b/thirdparty/rive/source/assets/image_asset.cpp index 0c82c317c..9c1827a77 100644 --- a/thirdparty/rive/source/assets/image_asset.cpp +++ b/thirdparty/rive/source/assets/image_asset.cpp @@ -1,6 +1,7 @@ #include "rive/assets/image_asset.hpp" #include "rive/artboard.hpp" #include "rive/factory.hpp" +#include "rive/assets/file_asset_referencer.hpp" using namespace rive; diff --git a/thirdparty/rive/source/assets/manifest_asset.cpp b/thirdparty/rive/source/assets/manifest_asset.cpp new file mode 100644 index 000000000..4df022009 --- /dev/null +++ b/thirdparty/rive/source/assets/manifest_asset.cpp @@ -0,0 +1,164 @@ +#include "rive/assets/manifest_asset.hpp" +#include "rive/factory.hpp" +#include "rive/core/binary_reader.hpp" +#include "rive/span.hpp" +#include "rive/manifest_sections.hpp" + +using namespace rive; + +const std::string ManifestAsset::empty; +const std::vector ManifestAsset::emptyIntVector; + +bool ManifestAsset::decodeNames(BinaryReader& reader) +{ + // Read count of names + uint64_t count = reader.readVarUint64(); + if (reader.hasError()) + { + return false; + } + + // Read all name entries + for (uint64_t i = 0; i < count; i++) + { + int id = static_cast(reader.readVarUint64()); + if (reader.hasError()) + { + return false; + } + + std::string value = reader.readString(); + if (reader.hasError()) + { + return false; + } + + m_names[id] = value; + } + return true; +} + +bool ManifestAsset::decodePaths(BinaryReader& reader) +{ + // Read count of paths + uint64_t count = reader.readVarUint64(); + if (reader.hasError()) + { + return false; + } + + // Read all path entries + for (uint64_t i = 0; i < count; i++) + { + int id = static_cast(reader.readVarUint64()); + if (reader.hasError()) + { + return false; + } + int pathLength = static_cast(reader.readVarUint64()); + if (reader.hasError()) + { + return false; + } + std::vector path; + for (uint64_t j = 0; j < pathLength; j++) + { + int pathId = static_cast(reader.readVarUint64()); + path.push_back(pathId); + } + m_paths[id] = path; + if (reader.hasError()) + { + return false; + } + } + return true; +} + +bool ManifestAsset::decode(SimpleArray& bytes, Factory* factory) +{ + if (bytes.empty()) + { + return true; + } + + BinaryReader reader(Span(bytes.data(), bytes.size())); + + while (!reader.reachedEnd()) + { + // Read section enum value + uint64_t sectionValue = reader.readVarUint64(); + if (reader.hasError()) + { + return false; + } + + // Read section size + uint64_t sectionSize = reader.readVarUint64(); + if (reader.hasError()) + { + return false; + } + + // Store the position before reading the section content + const uint8_t* sectionStart = reader.position(); + + if (static_cast(sectionValue) == + ManifestSections::names) + { + if (!decodeNames(reader)) + { + return false; + } + } + else if (static_cast(sectionValue) == + ManifestSections::paths) + { + if (!decodePaths(reader)) + { + return false; + } + } + else + { + // Unknown section - skip the specified number of bytes + reader.readBytes(static_cast(sectionSize)); + if (reader.hasError()) + { + return false; + } + continue; + } + + // Verify we read exactly the section size + size_t bytesRead = reader.position() - sectionStart; + if (bytesRead != sectionSize) + { + return false; + } + } + + return true; +} + +std::string ManifestAsset::fileExtension() const { return "man"; } + +const std::string& ManifestAsset::resolveName(int id) +{ + auto it = m_names.find(id); + if (it != m_names.end()) + { + return it->second; + } + return empty; +} + +const std::vector& ManifestAsset::resolvePath(int id) +{ + auto it = m_paths.find(id); + if (it != m_paths.end()) + { + return it->second; + } + return emptyIntVector; +} \ No newline at end of file diff --git a/thirdparty/rive/source/assets/script_asset.cpp b/thirdparty/rive/source/assets/script_asset.cpp new file mode 100644 index 000000000..900085a9c --- /dev/null +++ b/thirdparty/rive/source/assets/script_asset.cpp @@ -0,0 +1,417 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "libhydrogen.h" +#include "rive/importers/text_asset_importer.hpp" +#endif +#include "rive/assets/script_asset.hpp" +#include "rive/signed_content_header.hpp" +#include "rive/file.hpp" +#include "rive/script_input_artboard.hpp" +#include "rive/script_input_boolean.hpp" +#include "rive/script_input_color.hpp" +#include "rive/script_input_number.hpp" +#include "rive/script_input_string.hpp" +#include "rive/script_input_trigger.hpp" +#include "rive/script_input_viewmodel_property.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/scripted/scripted_layout.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/data_bind/data_bind.hpp" + +using namespace rive; + +ScriptInput::~ScriptInput() +{ + if (m_ownsDataBind && m_dataBind) + { + delete m_dataBind; + } +} + +ScriptInput* ScriptInput::from(Core* component) +{ + switch (component->coreType()) + { + case ScriptInputArtboard::typeKey: + return component->as(); + case ScriptInputBoolean::typeKey: + return component->as(); + case ScriptInputColor::typeKey: + return component->as(); + case ScriptInputNumber::typeKey: + return component->as(); + case ScriptInputString::typeKey: + return component->as(); + case ScriptInputTrigger::typeKey: + return component->as(); + case ScriptInputViewModelProperty::typeKey: + return component->as(); + } + return nullptr; +} + +void ScriptInput::initScriptedValue() {} + +bool ScriptInput::validateForColdScriptInit() +{ + return validateForScriptInit(); +} + +bool ScriptInput::hydrateScriptInput() +{ + initScriptedValue(); + return true; +} + +bool ScriptInput::validateHydrationPrerequisites() { return true; } + +#ifdef WITH_RIVE_SCRIPTING +bool OptionalScriptedMethods::verifyImplementation(ScriptedObject* object, + lua_State* state) +{ + // Log the stack-top type before pcall so we can see whether it's nil + // (meaning generator-ref resolved to nothing) vs a function that then + // errored internally. + int topType = static_cast(lua_type(state, -1)); + fprintf(stderr, + "[verifyImpl] entering verify for object protocol=%d, stack top " + "type=%d\n", + (int)object->scriptProtocol(), + topType); + + lua_pushvalue(state, -1); + if (static_cast(rive_lua_pcall(state, 0, 1)) != LUA_OK) + { + const char* err = lua_tostring(state, -1); + fprintf(stderr, + "Verifying implementation pcall failed (protocol=%d, " + "top-type-before=%d): %s\n", + (int)object->scriptProtocol(), + topType, + err ? err : "(no error message)"); + rive_lua_pop(state, 1); + return false; + } + if (static_cast(lua_type(state, -1)) != LUA_TTABLE) + { + fprintf(stderr, + "Verifying implementation not a table (protocol=%d)?\n", + (int)object->scriptProtocol()); + rive_lua_pop(state, 1); + return false; + } + m_implementedMethods = 0; + + auto scriptProtocol = object->scriptProtocol(); + if (scriptProtocol == ScriptProtocol::node || + scriptProtocol == ScriptProtocol::layout || + scriptProtocol == ScriptProtocol::converter || + scriptProtocol == ScriptProtocol::pathEffect || + scriptProtocol == ScriptProtocol::listenerAction || + scriptProtocol == ScriptProtocol::transitionCondition) + { + if (static_cast(lua_getfield(state, -1, "update")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_updatesBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "advance")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_advancesBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "pointerDown")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsPointerDownBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "pointerUp")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsPointerUpBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "pointerMove")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsPointerMoveBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "pointerCanceled")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsPointerCancelBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "pointerExit")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsPointerExitBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "init")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_initsBit; + } + rive_lua_pop(state, 1); + } + if (scriptProtocol == ScriptProtocol::layout) + { + if (static_cast(lua_getfield(state, -1, "measure")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_measuresBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "resize")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_resizesBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "draw")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_drawsBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "drawCanvas")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_drawsCanvasBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "keyboardEvent")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsKeyboardInputBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "textEvent")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsTextInputBit; + } + rive_lua_pop(state, 1); + } + else if (scriptProtocol == ScriptProtocol::node) + { + if (static_cast(lua_getfield(state, -1, "draw")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_drawsBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "drawCanvas")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_drawsCanvasBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "keyboardEvent")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsKeyboardInputBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "textEvent")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_wantsTextInputBit; + } + rive_lua_pop(state, 1); + } + else if (scriptProtocol == ScriptProtocol::converter) + { + if (static_cast(lua_getfield(state, -1, "convert")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_dataConvertsBit; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "reverseConvert")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_dataReverseConvertsBit; + } + rive_lua_pop(state, 1); + } + else if (scriptProtocol == ScriptProtocol::listenerAction) + { + if (static_cast(lua_getfield(state, -1, "perform")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_listenerPerforms; + } + rive_lua_pop(state, 1); + if (static_cast(lua_getfield(state, -1, "performAction")) == + LUA_TFUNCTION) + { + m_implementedMethods |= m_listenerPerformsAction; + } + rive_lua_pop(state, 1); + } + rive_lua_pop(state, 1); + return true; +} + +ScriptingVM* ScriptAsset::scriptingVM() +{ + if (m_file == nullptr) + { + return nullptr; + } + return m_file->scriptingVM(); +} + +lua_State* ScriptAsset::vm() +{ + auto scriptingVM = this->scriptingVM(); + return scriptingVM ? scriptingVM->state() : nullptr; +} +#endif + +bool ScriptAsset::initScriptedObject(ScriptedObject* object) +{ +#ifdef WITH_RIVE_SCRIPTING + if (scriptingVM() == nullptr) + { + return false; + } + return initScriptedObjectWith(object); +#else + return false; +#endif +} + +#if defined(WITH_RIVE_SCRIPTING) +void ScriptAsset::registrationComplete(int ref) +{ + if (isModule()) + { + m_scriptRegistered = true; + } + else + { + generatorFunctionRef(ref); + // Force re-verification on next init so that method detection (e.g. + // drawCanvas) reflects the newly compiled script. + m_initted = false; + } +} +#endif + +bool ScriptAsset::initScriptedObjectWith(ScriptedObject* object) +{ +#if defined(WITH_RIVE_SCRIPTING) + auto scriptVM = scriptingVM(); + if (scriptVM == nullptr) + { + return false; + } + lua_State* state = scriptVM->state(); + + int ref = 0; +#ifdef WITH_RIVE_TOOLS + ScriptingContext* context = + static_cast(lua_getthreaddata(state)); + if (context != nullptr && context->hasGeneratorRef(generatorFunctionRef())) + { + ref = context->getGeneratorRef(generatorFunctionRef()); + } + else +#endif + { + ref = generatorFunctionRef(); + } + + if (ref == 0) + { + fprintf(stderr, + "ScriptAsset doesn't have a generator function %s\n", + name().c_str()); + return false; + } + fprintf(stderr, + "[activate] script \"%s\" generatorFunctionRef=%u -> lua ref=%d\n", + name().c_str(), + generatorFunctionRef(), + ref); + rive_lua_pushRef(state, ref); + + if (!m_initted) + { + if (!verifyImplementation(object, state)) + { + rive_lua_pop(state, 1); + return false; + } + m_initted = true; + } + object->implementedMethods(implementedMethods()); + return object->ensureScriptInitialized(scriptVM); +#else + return false; +#endif +} + +bool ScriptAsset::decode(SimpleArray& data, Factory* factory) +{ +#ifdef WITH_RIVE_SCRIPTING + m_verified = false; + + // For in-band bytecode, isSigned should always be false (signature is + // stored separately for aggregate verification). + SignedContentHeader header(Span(data.data(), data.size())); + if (!header.isValid()) + { + return false; + } + + // Store just the bytecode (without header) for later verification and use. + auto bytecode = header.content(); + m_bytecode = SimpleArray(bytecode.data(), bytecode.size()); +#endif + return true; +} + +bool ScriptAsset::bytecode(Span data) +{ +#ifdef WITH_RIVE_SCRIPTING + SignedContentHeader header(Span(data.data(), data.size())); + if (!header.isValid()) + { + m_verified = false; + return false; + } + + auto bytecode = header.content(); + + if (!header.isSigned()) + { + // Unsigned bytecode - mark as unverified + m_verified = false; + m_bytecode = SimpleArray(bytecode.data(), bytecode.size()); + return true; + } + + auto signature = header.signature(); + if (hydro_sign_verify(signature.data(), + bytecode.data(), + bytecode.size(), + "RiveCode", + g_scriptVerificationPublicKey) != 0) + { + // Forged. + m_verified = false; + return false; + } + m_verified = true; + m_bytecode = SimpleArray(bytecode.data(), bytecode.size()); +#endif + return true; +} \ No newline at end of file diff --git a/thirdparty/rive/source/assets/shader_asset.cpp b/thirdparty/rive/source/assets/shader_asset.cpp new file mode 100644 index 000000000..f4f20fa08 --- /dev/null +++ b/thirdparty/rive/source/assets/shader_asset.cpp @@ -0,0 +1,125 @@ +#include "rive/assets/shader_asset.hpp" +#include "rive/signed_content_header.hpp" + +using namespace rive; + +bool rive::ShaderAsset::decode(Span data, Factory* factory) +{ + // `data` is always a SignedContentHeader envelope + // (`[flags:1][sig:64?][RSTB...]`) shared with ScriptAsset. Raw-RSTB + // callers (editor live-preview) must prepend a single 0x00 flag byte. + SignedContentHeader envelope(std::move(data)); + if (!envelope.isValid()) + { + return false; + } + auto inner = envelope.content(); + m_bytes = SimpleArray(inner.data(), inner.size()); + m_index.clear(); + m_pairs.clear(); + + const uint8_t* p = m_bytes.data(); + const uint8_t* end = p + m_bytes.size(); + + // Header: magic(u32LE) + version(u16LE) + variant_count(u8) + + // section_count(u8) + if (m_bytes.size() < 8) + { + return false; + } + uint32_t magic = (uint32_t)p[0] | ((uint32_t)p[1] << 8) | + ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); + if (magic != 0x52535442u) // "RSTB" + { + return false; + } + uint16_t version = (uint16_t)(p[4] | (p[5] << 8)); + if (version != 3) + { + return false; + } + uint8_t variantCount = p[6]; + uint8_t sectionCount = p[7]; + p += 8; + + // VariantDescriptor: target(u8) + blob_offset(u32) + blob_size(u32) = 9 + constexpr size_t kVariantDescriptorSize = 9; + if (p + (size_t)variantCount * kVariantDescriptorSize > end) + { + return false; + } + for (uint8_t v = 0; v < variantCount; v++) + { + uint8_t target = p[0]; + uint32_t blobOffset = (uint32_t)p[1] | ((uint32_t)p[2] << 8) | + ((uint32_t)p[3] << 16) | ((uint32_t)p[4] << 24); + uint32_t blobSize = (uint32_t)p[5] | ((uint32_t)p[6] << 8) | + ((uint32_t)p[7] << 16) | ((uint32_t)p[8] << 24); + p += kVariantDescriptorSize; + m_index[target] = {blobOffset, blobSize}; + } + + // Tagged metadata sections. + for (uint8_t sec = 0; sec < sectionCount; sec++) + { + if (p + 3 > end) + { + return false; + } + uint8_t tag = p[0]; + uint16_t length = (uint16_t)(p[1] | (p[2] << 8)); + p += 3; + if (p + length > end) + { + return false; + } + + if (tag == 1 && length >= 1) + { + // Tag 1: texture-sampler pairs. + uint8_t pairCount = p[0]; + if (length >= 1 + (size_t)pairCount * 4) + { + const uint8_t* pd = p + 1; + for (uint8_t i = 0; i < pairCount; i++) + { + m_pairs.push_back({pd[0], pd[1], pd[2], pd[3]}); + pd += 4; + } + } + } + // Unknown tags: skip. + p += length; + } + + // p now points to the start of the blob data section. + size_t blobDataStart = (size_t)(p - m_bytes.data()); + + // Fix up offsets to absolute and validate that each variant's range + // stays within m_bytes. Arithmetic widened to size_t so an adversarial + // (offset, size) pair can't overflow uint32_t past the bounds check. + for (auto& kv : m_index) + { + size_t absOffset = (size_t)kv.second.offset + blobDataStart; + if (absOffset > m_bytes.size() || + (size_t)kv.second.size > m_bytes.size() - absOffset) + { + m_index.clear(); + return false; + } + kv.second.offset = (uint32_t)absOffset; + } + + return true; +} + +Span ShaderAsset::findShader(uint8_t target) const +{ + auto it = m_index.find(target); + if (it == m_index.end()) + { + return {}; + } + const auto& v = it->second; + return Span(m_bytes.data() + v.offset, v.size); +} diff --git a/thirdparty/rive/source/async/work_pool.cpp b/thirdparty/rive/source/async/work_pool.cpp new file mode 100644 index 000000000..487a682eb --- /dev/null +++ b/thirdparty/rive/source/async/work_pool.cpp @@ -0,0 +1,346 @@ +/* + * Copyright 2026 Rive + */ + +#include "rive/async/work_pool.hpp" +#include +#include + +namespace rive +{ + +std::atomic WorkPool::s_nextOwnerId{1}; + +uint64_t WorkPool::nextOwnerId() +{ + return s_nextOwnerId.fetch_add(1, std::memory_order_relaxed); +} + +// ============================================================================ +// No-threading implementation +// ============================================================================ + +#ifndef WITH_RIVE_THREADING + +WorkPool::WorkPool() {} + +WorkPool::~WorkPool() +{ + // Deliver onCancel for tasks whose cancel flag was already set + // (e.g. by cancelAllForOwner) but never polled. Tasks that were + // never cancelled are silently dropped — calling virtual callbacks + // during destruction is unsafe if dependent state (e.g. Lua VM) + // has already been torn down. + for (auto& task : m_workQueue) + { + if (task->isCancelled()) + { + task->setStatus(WorkStatus::Cancelled); + task->onCancel(); + } + } + m_workQueue.clear(); +} + +uint64_t WorkPool::submit(rcp task) +{ + if (!task) + return 0; + task->setStatus(WorkStatus::Pending); + m_workQueue.push_back(std::move(task)); + return m_nextHandle++; +} + +uint32_t WorkPool::pollCompletedWork(uint32_t maxCallbacks) +{ + uint32_t processed = 0; + + while (processed < maxCallbacks && !m_workQueue.empty()) + { + auto task = std::move(m_workQueue.front()); + m_workQueue.pop_front(); + + if (task->isCancelled()) + { + task->setStatus(WorkStatus::Cancelled); + task->onCancel(); + processed++; + continue; + } + + task->setStatus(WorkStatus::Running); + bool success = task->execute(); + + if (task->isCancelled()) + { + task->setStatus(WorkStatus::Cancelled); + task->onCancel(); + } + else if (success) + { + task->setStatus(WorkStatus::Completed); + task->onComplete(); + } + else + { + task->setStatus(WorkStatus::Failed); + task->onError(task->errorMessage()); + } + processed++; + } + return processed; +} + +bool WorkPool::hasPendingWork() const { return !m_workQueue.empty(); } + +void WorkPool::cancelAllForOwner(uint64_t ownerId) +{ + // Only set the cancel flag here. onCancel() is delivered once from + // pollCompletedWork() when the task is dequeued, avoiding double-cancel. + for (auto& task : m_workQueue) + { + if (task->ownerId() == ownerId) + task->cancel(); + } +} + +// ============================================================================ +// Threaded implementation +// ============================================================================ + +#else // WITH_RIVE_THREADING + +WorkPool::WorkPool() +{ + unsigned int n = std::max(std::thread::hardware_concurrency(), 1u); + // Cap at a reasonable number for image decode. + n = std::min(n, 4u); + for (unsigned int i = 0; i < n; i++) + { + m_threads.emplace_back(&WorkPool::workerLoop, this); + } +} + +WorkPool::~WorkPool() +{ + { + std::lock_guard lock(m_queueMutex); + m_shutdown = true; + } + m_haveWork.notify_all(); + for (auto& t : m_threads) + { + if (t.joinable()) + t.join(); + } + // Deliver onCancel for tasks whose cancel flag was already set but + // never polled. Tasks that were never cancelled are silently dropped — + // calling virtual callbacks during destruction is unsafe if dependent + // state (e.g. Lua VM) has already been torn down. + for (auto& task : m_completedQueue) + { + if (task->isCancelled()) + { + task->setStatus(WorkStatus::Cancelled); + task->onCancel(); + } + } + m_completedQueue.clear(); + for (auto& task : m_workQueue) + { + if (task->isCancelled()) + { + task->setStatus(WorkStatus::Cancelled); + task->onCancel(); + } + } + m_workQueue.clear(); +} + +uint64_t WorkPool::submit(rcp task) +{ + if (!task) + return 0; + uint64_t handle; + { + std::lock_guard lock(m_queueMutex); + task->setStatus(WorkStatus::Pending); + task->setSubmitGeneration(m_cancelGeneration); + handle = m_nextHandle++; + m_workQueue.push_back(std::move(task)); + } + m_haveWork.notify_one(); + return handle; +} + +void WorkPool::workerLoop() +{ + while (true) + { + rcp task; + { + std::unique_lock lock(m_queueMutex); + m_haveWork.wait(lock, [this] { + return m_shutdown || !m_workQueue.empty(); + }); + if (m_shutdown && m_workQueue.empty()) + return; + task = std::move(m_workQueue.front()); + m_workQueue.pop_front(); + } + + m_inFlightCount.fetch_add(1, std::memory_order_relaxed); + + if (task->isCancelled()) + { + task->setStatus(WorkStatus::Cancelled); + std::lock_guard lock(m_completedMutex); + m_completedQueue.push_back(std::move(task)); + m_inFlightCount.fetch_sub(1, std::memory_order_relaxed); + continue; + } + + task->setStatus(WorkStatus::Running); + bool success = task->execute(); + + if (task->isCancelled()) + task->setStatus(WorkStatus::Cancelled); + else if (success) + task->setStatus(WorkStatus::Completed); + else + task->setStatus(WorkStatus::Failed); + + { + std::lock_guard lock(m_completedMutex); + m_completedQueue.push_back(std::move(task)); + } + m_inFlightCount.fetch_sub(1, std::memory_order_relaxed); + } +} + +uint32_t WorkPool::pollCompletedWork(uint32_t maxCallbacks) +{ + uint32_t processed = 0; + + while (processed < maxCallbacks) + { + rcp task; + { + std::lock_guard lock(m_completedMutex); + if (m_completedQueue.empty()) + break; + task = std::move(m_completedQueue.front()); + m_completedQueue.pop_front(); + } + + bool ownerCancelled = false; + { + std::lock_guard lock(m_queueMutex); + auto it = m_cancelledOwners.find(task->ownerId()); + if (it != m_cancelledOwners.end()) + { + // Task is owner-cancelled only if it was submitted + // before the cancel call (submit gen < cancel gen). + ownerCancelled = task->submitGeneration() < it->second; + } + } + + if (!task->isCancelled() && !ownerCancelled) + { + if (task->status() == WorkStatus::Completed) + task->onComplete(); + else if (task->status() == WorkStatus::Failed) + task->onError(task->errorMessage()); + } + else + { + task->setStatus(WorkStatus::Cancelled); + task->onCancel(); + } + processed++; + } + return processed; +} + +bool WorkPool::hasPendingWork() const +{ + if (m_inFlightCount.load(std::memory_order_relaxed) > 0) + return true; + { + std::lock_guard lock(const_cast(m_queueMutex)); + if (!m_workQueue.empty()) + return true; + } + { + std::lock_guard lock( + const_cast(m_completedMutex)); + if (!m_completedQueue.empty()) + return true; + } + return false; +} + +void WorkPool::cancelAllForOwner(uint64_t ownerId) +{ + // Only set the cancel flag under the lock. Do NOT call the virtual + // onCancel() here — that risks deadlocks (virtual code under mutex) + // and double-cancel (pollCompletedWork also delivers onCancel). + // The single onCancel() delivery happens from pollCompletedWork() + // on the main thread when the task is dequeued. + { + std::lock_guard lock(m_queueMutex); + // Bump the cancel generation so that tasks submitted after this + // call are not treated as cancelled. In-flight worker tasks + // submitted before this point have submitGeneration < cancelGen + // and will be caught by pollCompletedWork. + ++m_cancelGeneration; + m_cancelledOwners[ownerId] = m_cancelGeneration; + for (auto& task : m_workQueue) + { + if (task->ownerId() == ownerId) + task->cancel(); + } + } + { + std::lock_guard lock(m_completedMutex); + for (auto& task : m_completedQueue) + { + if (task->ownerId() == ownerId) + task->cancel(); + } + } +} + +#endif // WITH_RIVE_THREADING + +// ============================================================================ +// Global singleton + polling (shared by both threading modes) +// ============================================================================ + +static rcp& globalWorkPoolStorage() +{ + static rcp s_workPool; + return s_workPool; +} + +rcp& getGlobalWorkPool() +{ + // Thread-safe lazy initialization via std::call_once. + static std::once_flag s_initFlag; + auto& pool = globalWorkPoolStorage(); + std::call_once(s_initFlag, [&pool] { pool = make_rcp(); }); + return pool; +} + +rcp& getGlobalWorkPoolIfExists() { return globalWorkPoolStorage(); } + +void rive_pollAsyncWork() +{ + auto& pool = getGlobalWorkPoolIfExists(); + if (pool && pool->hasPendingWork()) + { + pool->pollCompletedWork(16); + } +} + +} // namespace rive diff --git a/thirdparty/rive/source/audio/audio_engine.cpp b/thirdparty/rive/source/audio/audio_engine.cpp index b18e6b450..72adeece4 100644 --- a/thirdparty/rive/source/audio/audio_engine.cpp +++ b/thirdparty/rive/source/audio/audio_engine.cpp @@ -238,18 +238,12 @@ AudioEngine::AudioEngine(ma_engine* engine, ma_context* context) : m_device(ma_engine_get_device(engine)), m_engine(engine), m_context(context) {} -rcp AudioEngine::play(rcp source, - uint64_t startTime, - uint64_t endTime, - uint64_t soundStartTime, - Artboard* artboard) +rcp AudioEngine::internalPlaySound(rcp source, + uint64_t duration, + uint64_t endTime, + uint64_t soundStartTime, + Artboard* artboard) { - if (endTime != 0 && startTime >= endTime) - { - // Requested to stop sound before start. - return nullptr; - } - std::unique_lock lock(m_mutex); // We have to dispose completed sounds out of the completed callback. So we // do it on next play or at destruct. @@ -267,8 +261,7 @@ rcp AudioEngine::play(rcp source, ma_uint64 sizeInFrames = samples.size() / source->channels(); if (endTime != 0) { - float durationSeconds = - (soundStartTime + endTime - startTime) / (float)sampleRate(); + float durationSeconds = duration / (float)sampleRate(); ma_uint64 clippedFrames = (ma_uint64)std::round(durationSeconds * source->sampleRate()); if (clippedFrames < sizeInFrames) @@ -319,8 +312,8 @@ rcp AudioEngine::play(rcp source, return nullptr; } clip->frameCursor = 0; - clip->endFrame = endTime == 0 ? std::numeric_limits::max() - : soundStartTime + endTime - startTime; + clip->endFrame = + endTime == 0 ? std::numeric_limits::max() : duration; ma_data_source_config baseConfig = ma_data_source_config_init(); baseConfig.vtable = &g_ma_end_clipped_decoder_vtable; if (ma_data_source_init(&baseConfig, &clip->base) != MA_SUCCESS) @@ -347,11 +340,11 @@ rcp AudioEngine::play(rcp source, ma_sound_set_end_callback(audioSound->sound(), SoundCompleted, audioSound.get()); + return audioSound; +} - if (startTime != 0) - { - ma_sound_set_start_time_in_pcm_frames(audioSound->sound(), startTime); - } +rcp AudioEngine::initializeAudioSound(rcp audioSound) +{ #ifdef WITH_RIVE_AUDIO_TOOLS if (m_levelMonitor != nullptr) { @@ -360,7 +353,6 @@ rcp AudioEngine::play(rcp source, #endif if (ma_sound_start(audioSound->sound()) != MA_SUCCESS) { - fprintf(stderr, "AudioSource::play - failed to start sound\n"); return nullptr; } @@ -370,10 +362,67 @@ rcp AudioEngine::play(rcp source, } audioSound->m_nextPlaying = m_playingSoundsHead; m_playingSoundsHead = audioSound; - return audioSound; } +rcp AudioEngine::playSeconds(rcp source, + float startTime, + uint64_t endTime, + uint64_t soundStartTime, + Artboard* artboard) +{ + + if (endTime != 0 && startTime >= (float)endTime) + { + // Requested to stop sound before start. + return nullptr; + } + auto audioSound = + internalPlaySound(source, + (int)(soundStartTime + endTime - startTime), + endTime, + soundStartTime, + artboard); + if (audioSound == nullptr) + { + return nullptr; + } + if (startTime != 0) + { + ma_sound_set_start_time_in_milliseconds(audioSound->sound(), + startTime * 1000.0f); + } + return initializeAudioSound(audioSound); +} + +rcp AudioEngine::play(rcp source, + uint64_t startTime, + uint64_t endTime, + uint64_t soundStartTime, + Artboard* artboard) +{ + if (endTime != 0 && startTime >= endTime) + { + // Requested to stop sound before start. + return nullptr; + } + auto audioSound = internalPlaySound(source, + soundStartTime + endTime - startTime, + endTime, + soundStartTime, + artboard); + + if (audioSound == nullptr) + { + return nullptr; + } + if (startTime != 0) + { + ma_sound_set_start_time_in_pcm_frames(audioSound->sound(), startTime); + } + return initializeAudioSound(audioSound); +} + #ifdef TESTING size_t AudioEngine::playingSoundCount() { @@ -388,6 +437,9 @@ size_t AudioEngine::playingSoundCount() return count; } + +rcp AudioEngine::playingSoundsHead() { return m_playingSoundsHead; } + #endif void AudioEngine::stop(Artboard* artboard) @@ -397,7 +449,7 @@ void AudioEngine::stop(Artboard* artboard) while (sound != nullptr) { auto next = sound->m_nextPlaying; - if (sound->m_artboard == artboard) + if (sound->m_artboard == artboard || artboard == nullptr) { sound->stop(); m_completedSounds.push_back(sound); @@ -455,7 +507,27 @@ uint64_t AudioEngine::timeInFrames() return (uint64_t)ma_engine_get_time_in_pcm_frames(m_engine); } +float AudioEngine::timeInSeconds() +{ + return ma_engine_get_time_in_milliseconds(m_engine) / 1000.0f; +} + static rcp m_runtimeAudioEngine; + +rcp AudioEngine::MakeAndStore(uint32_t numChannels, + uint32_t sampleRate) +{ + auto audioEngine = Make(numChannels, sampleRate); +#ifdef WITH_RIVE_TOOLS + if (m_runtimeAudioEngine) + { + m_runtimeAudioEngine->stop(nullptr); + } +#endif + m_runtimeAudioEngine = audioEngine; + return m_runtimeAudioEngine; +} + rcp AudioEngine::RuntimeEngine(bool makeWhenNecessary) { if (!makeWhenNecessary) diff --git a/thirdparty/rive/source/audio/audio_sound.cpp b/thirdparty/rive/source/audio/audio_sound.cpp index cfeb8fe07..7d400aeb1 100644 --- a/thirdparty/rive/source/audio/audio_sound.cpp +++ b/thirdparty/rive/source/audio/audio_sound.cpp @@ -60,6 +60,27 @@ void AudioSound::stop(uint64_t fadeTimeInFrames) } } +void AudioSound::play() +{ + if (m_isDisposed) + { + return; + } + ma_sound_seek_to_pcm_frame(&m_sound, 0); + ma_sound_start(&m_sound); +} + +void AudioSound::pause() { stop(0); } + +void AudioSound::resume() +{ + if (m_isDisposed) + { + return; + } + ma_sound_start(&m_sound); +} + bool AudioSound::seek(uint64_t timeInFrames) { if (m_isDisposed) @@ -70,4 +91,31 @@ bool AudioSound::seek(uint64_t timeInFrames) MA_SUCCESS; } +bool AudioSound::seekSeconds(float timeInSeconds) +{ + if (m_isDisposed) + { + return false; + } + return ma_sound_seek_to_second(&m_sound, timeInSeconds) == MA_SUCCESS; +} + +uint64_t AudioSound::timeInFrames() +{ + if (m_isDisposed) + { + return 0; + } + return ma_sound_get_time_in_pcm_frames(&m_sound); +} + +float AudioSound::timeInSeconds() +{ + if (m_isDisposed) + { + return 0.0f; + } + return ma_sound_get_time_in_milliseconds(&m_sound) / 1000.0f; +} + #endif \ No newline at end of file diff --git a/thirdparty/rive/source/audio/audio_source.cpp b/thirdparty/rive/source/audio/audio_source.cpp index a8ca91a47..faa205f9b 100644 --- a/thirdparty/rive/source/audio/audio_source.cpp +++ b/thirdparty/rive/source/audio/audio_source.cpp @@ -9,12 +9,51 @@ using namespace rive; #ifdef WITH_RIVE_AUDIO +// Both of these should be make_rcp but it is currently getting refed directy +// somewhere else so until we refactor that we have to not ref here. +rcp AudioSource::MakeAudioSource(rive::Span fileBytes) +{ + ma_decoder decoder; + ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 0, 0); + if (ma_decoder_init_memory(fileBytes.data(), + fileBytes.size(), + &config, + &decoder) != MA_SUCCESS) + { + return nullptr; + } + ma_decoder_uninit(&decoder); + return rcp(new AudioSource(std::move(fileBytes))); +} + +rcp AudioSource::MakeAudioSource( + rive::SimpleArray fileBytes) +{ + ma_decoder decoder; + ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 0, 0); + auto result = ma_decoder_init_memory(fileBytes.data(), + fileBytes.size(), + &config, + &decoder); + if (result != MA_SUCCESS) + { + fprintf(stderr, + "Failed to decode audio with error %s\n", + ma_result_description(result)); + return nullptr; + } + + ma_decoder_uninit(&decoder); + return rcp(new AudioSource(std::move(fileBytes))); +} + AudioSource::AudioSource(rive::Span samples, uint32_t numChannels, uint32_t sampleRate) : m_isBuffered(true), m_channels(numChannels), m_sampleRate(sampleRate), + m_duration(-1.0f), m_ownedBytes((uint8_t*)samples.data(), samples.size() * sizeof(float)) { assert(numChannels != 0); @@ -22,13 +61,18 @@ AudioSource::AudioSource(rive::Span samples, } AudioSource::AudioSource(rive::Span fileBytes) : - m_isBuffered(false), m_channels(0), m_sampleRate(0), m_fileBytes(fileBytes) + m_isBuffered(false), + m_channels(0), + m_sampleRate(0), + m_duration(-1.0f), + m_fileBytes(fileBytes) {} AudioSource::AudioSource(rive::SimpleArray fileBytes) : m_isBuffered(false), m_channels(0), m_sampleRate(0), + m_duration(-1.0f), m_fileBytes(fileBytes.data(), fileBytes.size()), m_ownedBytes(std::move(fileBytes)) {} @@ -62,6 +106,17 @@ class AudioSourceDecoder uint32_t sampleRate() { return (uint32_t)m_decoder.outputSampleRate; } + uint64_t lengthInFrames() + { + ma_uint64 length; + if (ma_data_source_get_length_in_pcm_frames(&m_decoder, &length) != + MA_SUCCESS) + { + return 0; + } + return (uint64_t)length; + } + private: ma_decoder m_decoder; }; @@ -86,6 +141,31 @@ uint32_t AudioSource::sampleRate() return m_sampleRate = audioDecoder.sampleRate(); } +float AudioSource::duration() +{ + if (m_duration >= 0.0f) + { + return m_duration; + } + if (m_isBuffered) + { + uint32_t ch = channels(); + uint32_t sr = sampleRate(); + if (ch == 0 || sr == 0) + { + return m_duration = 0.0f; + } + return m_duration = (float)bufferedSamples().size() / (float)(ch * sr); + } + AudioSourceDecoder audioDecoder(m_fileBytes); + uint32_t sr = audioDecoder.sampleRate(); + if (sr == 0) + { + return m_duration = 0.0f; + } + return m_duration = (float)audioDecoder.lengthInFrames() / (float)sr; +} + AudioFormat AudioSource::format() const { if (m_isBuffered) @@ -161,6 +241,16 @@ rcp AudioSource::makeReader(uint32_t numChannels, return reader; } #else +rcp AudioSource::MakeAudioSource(rive::Span fileBytes) +{ + return nullptr; +} + +rcp AudioSource::MakeAudioSource( + rive::SimpleArray fileBytes) +{ + return nullptr; +} AudioSource::AudioSource(rive::Span fileBytes) {} AudioSource::AudioSource(rive::SimpleArray fileBytes) {} AudioSource::AudioSource(rive::Span samples, diff --git a/thirdparty/rive/source/audio_event.cpp b/thirdparty/rive/source/audio_event.cpp index b2eef606d..b4043fb8d 100644 --- a/thirdparty/rive/source/audio_event.cpp +++ b/thirdparty/rive/source/audio_event.cpp @@ -9,7 +9,11 @@ using namespace rive; void AudioEvent::play() { #ifdef WITH_RIVE_AUDIO - auto audioAsset = (AudioAsset*)m_fileAsset; + if (m_fileAsset == nullptr) + { + return; + } + auto audioAsset = (AudioAsset*)m_fileAsset.get(); if (audioAsset == nullptr) { return; @@ -32,10 +36,15 @@ void AudioEvent::play() #endif AudioEngine::RuntimeEngine(); + if (engine == nullptr) + { + return; + } + auto sound = engine->play(audioSource, engine->timeInFrames(), 0, 0, artboard()); - if (volume != 1.0f) + if (sound != nullptr && volume != 1.0f) { sound->volume(volume); } @@ -62,9 +71,9 @@ StatusCode AudioEvent::import(ImportStack& importStack) return Super::import(importStack); } -void AudioEvent::setAsset(FileAsset* asset) +void AudioEvent::setAsset(rcp asset) { - if (asset->is()) + if (asset != nullptr && asset->is()) { FileAssetReferencer::setAsset(asset); } @@ -80,4 +89,8 @@ Core* AudioEvent::clone() const return twin; } -uint32_t AudioEvent::assetId() { return AudioEventBase::assetId(); } \ No newline at end of file +uint32_t AudioEvent::assetId() { return AudioEventBase::assetId(); } + +#ifdef TESTING +AudioAsset* AudioEvent::asset() const { return (AudioAsset*)m_fileAsset.get(); } +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/bindable_artboard.cpp b/thirdparty/rive/source/bindable_artboard.cpp new file mode 100644 index 000000000..d8b65d48e --- /dev/null +++ b/thirdparty/rive/source/bindable_artboard.cpp @@ -0,0 +1,8 @@ +#include "rive/bindable_artboard.hpp" + +using namespace rive; + +BindableArtboard::BindableArtboard(rcp file, + std::unique_ptr artboard) : + m_file(file), m_artboard(std::move(artboard)) +{} \ No newline at end of file diff --git a/thirdparty/rive/source/command_queue.cpp b/thirdparty/rive/source/command_queue.cpp index dccec8227..291917962 100644 --- a/thirdparty/rive/source/command_queue.cpp +++ b/thirdparty/rive/source/command_queue.cpp @@ -36,7 +36,6 @@ CommandQueue::CommandQueue() {} CommandQueue::~CommandQueue() {} FileHandle CommandQueue::loadFile(std::vector rivBytes, - rcp loader, FileListener* listener, uint64_t requestId) { @@ -44,6 +43,7 @@ FileHandle CommandQueue::loadFile(std::vector rivBytes, if (listener) { + assert(listener->m_handle == RIVE_NULL_HANDLE); listener->m_handle = handle; listener->m_owningQueue = ref_rcp(this); registerListener(handle, listener); @@ -53,7 +53,6 @@ FileHandle CommandQueue::loadFile(std::vector rivBytes, m_commandStream << Command::loadFile; m_commandStream << handle; m_commandStream << requestId; - m_commandStream << loader; m_byteVectors << std::move(rivBytes); return handle; @@ -67,6 +66,63 @@ void CommandQueue::deleteFile(FileHandle fileHandle, uint64_t requestId) m_commandStream << requestId; } +void CommandQueue::addGlobalImageAsset(std::string name, + RenderImageHandle handle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::addImageFileAsset; + m_commandStream << handle; + m_commandStream << requestId; + m_names << name; +} + +void CommandQueue::addGlobalFontAsset(std::string name, + FontHandle handle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::addFontFileAsset; + m_commandStream << handle; + m_commandStream << requestId; + m_names << name; +} + +void CommandQueue::addGlobalAudioAsset(std::string name, + AudioSourceHandle handle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::addAudioFileAsset; + m_commandStream << handle; + m_commandStream << requestId; + m_names << name; +} + +void CommandQueue::removeGlobalImageAsset(std::string name, uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::removeImageFileAsset; + m_commandStream << requestId; + m_names << name; +} + +void CommandQueue::removeGlobalFontAsset(std::string name, uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::removeFontFileAsset; + m_commandStream << requestId; + m_names << name; +} + +void CommandQueue::removeGlobalAudioAsset(std::string name, uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::removeAudioFileAsset; + m_commandStream << requestId; + m_names << name; +} + ArtboardHandle CommandQueue::instantiateArtboardNamed( FileHandle fileHandle, std::string name, @@ -78,6 +134,7 @@ ArtboardHandle CommandQueue::instantiateArtboardNamed( if (listener) { + assert(listener->m_handle == RIVE_NULL_HANDLE); listener->m_handle = handle; listener->m_owningQueue = ref_rcp(this); registerListener(handle, listener); @@ -93,6 +150,29 @@ ArtboardHandle CommandQueue::instantiateArtboardNamed( return handle; } +void CommandQueue::setArtboardSize(ArtboardHandle artboardHandle, + float width, + float height, + float scale, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::setArtboardSize; + m_commandStream << artboardHandle; + m_commandStream << width / scale; + m_commandStream << height / scale; + m_commandStream << requestId; +} + +void CommandQueue::resetArtboardSize(ArtboardHandle artboardHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::resetArtboardSize; + m_commandStream << artboardHandle; + m_commandStream << requestId; +} + void CommandQueue::deleteArtboard(ArtboardHandle artboardHandle, uint64_t requestId) { @@ -102,240 +182,1382 @@ void CommandQueue::deleteArtboard(ArtboardHandle artboardHandle, m_commandStream << requestId; } -StateMachineHandle CommandQueue::instantiateStateMachineNamed( +ViewModelInstanceHandle CommandQueue::instantiateBlankViewModelInstance( + FileHandle fileHandle, ArtboardHandle artboardHandle, - std::string name, - StateMachineListener* listener, + ViewModelInstanceListener* listener, uint64_t requestId) { - auto handle = - reinterpret_cast(++m_currentStateMachineHandleIdx); + auto viewHandle = reinterpret_cast( + ++m_currentViewModelHandleIdx); + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = viewHandle; + listener->m_owningQueue = ref_rcp(this); + registerListener(viewHandle, listener); + } + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::instantiateBlankViewModelForArtboard; + m_commandStream << fileHandle; + m_commandStream << artboardHandle; + m_commandStream << viewHandle; + m_commandStream << requestId; + + return viewHandle; +} +ViewModelInstanceHandle CommandQueue::instantiateBlankViewModelInstance( + FileHandle fileHandle, + std::string viewModelName, + ViewModelInstanceListener* listener, + uint64_t requestId) +{ + auto viewHandle = reinterpret_cast( + ++m_currentViewModelHandleIdx); if (listener) { - listener->m_handle = handle; + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = viewHandle; listener->m_owningQueue = ref_rcp(this); - registerListener(handle, listener); + registerListener(viewHandle, listener); } + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::instantiateBlankViewModel; + m_commandStream << fileHandle; + m_commandStream << viewHandle; + m_commandStream << requestId; + m_names << viewModelName; + return viewHandle; +} + +ViewModelInstanceHandle CommandQueue::instantiateViewModelInstanceNamed( + FileHandle fileHandle, + ArtboardHandle artboardHandle, + std::string viewModelInstanceName, + ViewModelInstanceListener* listener, + uint64_t requestId) +{ + auto viewHandle = reinterpret_cast( + ++m_currentViewModelHandleIdx); + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = viewHandle; + listener->m_owningQueue = ref_rcp(this); + registerListener(viewHandle, listener); + } AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::instantiateStateMachine; - m_commandStream << handle; + m_commandStream << Command::instantiateViewModelForArtboard; + m_commandStream << fileHandle; m_commandStream << artboardHandle; + m_commandStream << viewHandle; m_commandStream << requestId; - m_names << std::move(name); + m_names << viewModelInstanceName; - return handle; + return viewHandle; } -void CommandQueue::pointerMove(StateMachineHandle stateMachineHandle, - Vec2D position) +ViewModelInstanceHandle CommandQueue::instantiateViewModelInstanceNamed( + FileHandle fileHandle, + std::string viewModelName, + std::string viewModelInstanceName, + ViewModelInstanceListener* listener, + uint64_t requestId) { + auto viewHandle = reinterpret_cast( + ++m_currentViewModelHandleIdx); + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = viewHandle; + listener->m_owningQueue = ref_rcp(this); + registerListener(viewHandle, listener); + } AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::pointerMove; - m_commandStream << stateMachineHandle; - m_commandStream << position; + m_commandStream << Command::instantiateViewModel; + m_commandStream << fileHandle; + m_commandStream << viewHandle; + m_commandStream << requestId; + m_names << viewModelName; + m_names << viewModelInstanceName; + + return viewHandle; } -void CommandQueue::pointerDown(StateMachineHandle stateMachineHandle, - Vec2D position) +ViewModelInstanceHandle CommandQueue::referenceNestedViewModelInstance( + ViewModelInstanceHandle handle, + std::string path, + ViewModelInstanceListener* listener, + uint64_t requestId) { + auto viewHandle = reinterpret_cast( + ++m_currentViewModelHandleIdx); + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = viewHandle; + listener->m_owningQueue = ref_rcp(this); + registerListener(viewHandle, listener); + } AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::pointerDown; - m_commandStream << stateMachineHandle; - m_commandStream << position; + m_commandStream << Command::refNestedViewModel; + m_commandStream << handle; + m_commandStream << viewHandle; + m_commandStream << requestId; + m_names << path; + + return viewHandle; } -void CommandQueue::pointerUp(StateMachineHandle stateMachineHandle, - Vec2D position) +ViewModelInstanceHandle CommandQueue::referenceListViewModelInstance( + ViewModelInstanceHandle handle, + std::string path, + int index, + ViewModelInstanceListener* listener, + uint64_t requestId) { + auto viewHandle = reinterpret_cast( + ++m_currentViewModelHandleIdx); + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(viewHandle, listener); + } AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::pointerUp; - m_commandStream << stateMachineHandle; - m_commandStream << position; + m_commandStream << Command::refListViewModel; + m_commandStream << handle; + m_commandStream << index; + m_commandStream << viewHandle; + m_commandStream << requestId; + m_names << path; + + return viewHandle; } -void CommandQueue::pointerExit(StateMachineHandle stateMachineHandle, - Vec2D position) +void CommandQueue::fireViewModelTrigger(ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::pointerExit; - m_commandStream << stateMachineHandle; - m_commandStream << position; + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::trigger; + m_commandStream << requestId; + m_names << path; } -void CommandQueue::advanceStateMachine(StateMachineHandle stateMachineHandle, - float timeToAdvance, - uint64_t requestId) +void CommandQueue::setViewModelInstanceBool(ViewModelInstanceHandle handle, + std::string path, + bool value, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::advanceStateMachine; - m_commandStream << stateMachineHandle; + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::boolean; m_commandStream << requestId; - m_commandStream << timeToAdvance; + m_commandStream << value; + m_names << path; } -void CommandQueue::deleteStateMachine(StateMachineHandle stateMachineHandle, - uint64_t requestId) +void CommandQueue::setViewModelInstanceNumber(ViewModelInstanceHandle handle, + std::string path, + float value, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::deleteStateMachine; - m_commandStream << stateMachineHandle; + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::number; m_commandStream << requestId; + m_commandStream << value; + m_names << path; } -DrawKey CommandQueue::createDrawKey() +void CommandQueue::setViewModelInstanceColor(ViewModelInstanceHandle handle, + std::string path, + ColorInt value, + uint64_t requestId) { - // lock here so we can do this from several threads safely AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - auto key = reinterpret_cast(++m_currentDrawKeyIdx); - return key; + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::color; + m_commandStream << requestId; + m_commandStream << value; + m_names << path; } -void CommandQueue::draw(DrawKey drawKey, CommandServerDrawCallback callback) +void CommandQueue::setViewModelInstanceEnum(ViewModelInstanceHandle handle, + std::string path, + std::string value, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::draw; - m_commandStream << drawKey; - m_drawCallbacks << std::move(callback); + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::enumType; + m_commandStream << requestId; + m_names << path; + m_names << value; } -#ifdef TESTING -void CommandQueue::testing_commandLoopBreak() + +void CommandQueue::setViewModelInstanceString(ViewModelInstanceHandle handle, + std::string path, + std::string value, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::commandLoopBreak; + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::string; + m_commandStream << requestId; + m_names << path; + m_names << value; } -CommandQueue::FileListener* CommandQueue::testing_getFileListener( - FileHandle handle) +void CommandQueue::setViewModelInstanceImage(ViewModelInstanceHandle handle, + std::string path, + RenderImageHandle value, + uint64_t requestId) { - auto iter = m_fileListeners.find(handle); - if (iter != m_fileListeners.end()) - return iter->second; - return nullptr; + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::assetImage; + m_commandStream << requestId; + m_commandStream << value; + m_names << path; } -CommandQueue::ArtboardListener* CommandQueue::testing_getArtboardListener( - ArtboardHandle handle) +void CommandQueue::setViewModelInstanceArtboard(ViewModelInstanceHandle handle, + std::string path, + ArtboardHandle value, + uint64_t requestId) { - auto iter = m_artboardListeners.find(handle); - if (iter != m_artboardListeners.end()) - return iter->second; - return nullptr; + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::artboard; + m_commandStream << requestId; + m_commandStream << value; + m_names << path; } -CommandQueue::StateMachineListener* CommandQueue:: - testing_getStateMachineListener(StateMachineHandle handle) +void CommandQueue::setViewModelInstanceNestedViewModel( + ViewModelInstanceHandle handle, + std::string path, + ViewModelInstanceHandle value, + uint64_t requestId) { - auto iter = m_stateMachineListeners.find(handle); - if (iter != m_stateMachineListeners.end()) - return iter->second; - return nullptr; + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::setViewModelInstanceValue; + m_commandStream << handle; + m_commandStream << DataType::viewModel; + m_commandStream << requestId; + m_commandStream << value; + m_names << path; } -#endif -void CommandQueue::runOnce(CommandServerCallback callback) +void CommandQueue::insertViewModelInstanceListViewModel( + ViewModelInstanceHandle handle, + std::string path, + ViewModelInstanceHandle value, + int index, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::runOnce; - m_callbacks << std::move(callback); + m_commandStream << Command::addViewModelListValue; + m_commandStream << handle; + m_commandStream << value; + m_commandStream << index; + m_commandStream << requestId; + m_names << path; } -void CommandQueue::disconnect() +void CommandQueue::removeViewModelInstanceListViewModel( + ViewModelInstanceHandle handle, + std::string path, + int index, + ViewModelInstanceHandle value, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::disconnect; + m_commandStream << Command::removeViewModelListValue; + m_commandStream << handle; + m_commandStream << value; + m_commandStream << index; + m_commandStream << requestId; + m_names << path; } -void CommandQueue::requestArtboardNames(FileHandle fileHandle, - uint64_t requestId) +void CommandQueue::swapViewModelInstanceListValues( + ViewModelInstanceHandle handle, + std::string path, + int indexa, + int indexb, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::listArtboards; - m_commandStream << fileHandle; + m_commandStream << Command::swapViewModelListValue; + m_commandStream << handle; + m_commandStream << indexa; + m_commandStream << indexb; m_commandStream << requestId; + m_names << path; } -void CommandQueue::requestStateMachineNames(ArtboardHandle artboardHandle, - uint64_t requestId) +void CommandQueue::subscribeToViewModelProperty(ViewModelInstanceHandle handle, + std::string path, + DataType type, + uint64_t requestId) { AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); - m_commandStream << Command::listStateMachines; - m_commandStream << artboardHandle; + m_commandStream << Command::subscribeViewModelProperty; + m_commandStream << handle; + m_commandStream << type; m_commandStream << requestId; + m_names << path; } -void CommandQueue::processMessages() +void CommandQueue::unsubscribeToViewModelProperty( + ViewModelInstanceHandle handle, + std::string path, + DataType type, + uint64_t requestId) { - std::unique_lock lock(m_messageMutex); + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::unsubscribeViewModelProperty; + m_commandStream << handle; + m_commandStream << type; + m_commandStream << requestId; + m_names << path; +} - if (m_messageStream.empty()) - return; +void CommandQueue::deleteViewModelInstance(ViewModelInstanceHandle handle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::deleteViewModel; + m_commandStream << handle; + m_commandStream << requestId; +} - // Mark where we will end processing messages. This way if new messages come - // in while we're processing the existing ones, we won't loop forever. - m_messageStream << Message::messageLoopBreak; +StateMachineHandle CommandQueue::instantiateStateMachineNamed( + ArtboardHandle artboardHandle, + std::string name, + StateMachineListener* listener, + uint64_t requestId) +{ + auto handle = + reinterpret_cast(++m_currentStateMachineHandleIdx); - do + if (listener) { - Message message; - m_messageStream >> message; + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } - switch (message) - { - case Message::messageLoopBreak: - lock.unlock(); - return; - case Message::artboardsListed: - { - size_t numArtboards; - FileHandle handle; - uint64_t requestId; - m_messageStream >> handle; - m_messageStream >> requestId; + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::instantiateStateMachine; + m_commandStream << handle; + m_commandStream << artboardHandle; + m_commandStream << requestId; + m_names << std::move(name); + + return handle; +} + +void CommandQueue::pointerMove(StateMachineHandle stateMachineHandle, + PointerEvent pointerEvent, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::pointerMove; + m_commandStream << stateMachineHandle; + m_commandStream << requestId; + m_pointerEvents << std::move(pointerEvent); +} + +void CommandQueue::pointerDown(StateMachineHandle stateMachineHandle, + PointerEvent pointerEvent, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::pointerDown; + m_commandStream << stateMachineHandle; + m_commandStream << requestId; + m_pointerEvents << std::move(pointerEvent); +} + +void CommandQueue::pointerUp(StateMachineHandle stateMachineHandle, + PointerEvent pointerEvent, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::pointerUp; + m_commandStream << stateMachineHandle; + m_commandStream << requestId; + m_pointerEvents << std::move(pointerEvent); +} + +void CommandQueue::pointerExit(StateMachineHandle stateMachineHandle, + PointerEvent pointerEvent, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::pointerExit; + m_commandStream << stateMachineHandle; + m_commandStream << requestId; + m_pointerEvents << std::move(pointerEvent); +} + +void CommandQueue::bindViewModelInstance(StateMachineHandle handle, + ViewModelInstanceHandle viewModel, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::bindViewModelInstance; + m_commandStream << handle; + m_commandStream << viewModel; + m_commandStream << requestId; +} + +void CommandQueue::advanceStateMachine(StateMachineHandle stateMachineHandle, + float timeToAdvance, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::advanceStateMachine; + m_commandStream << stateMachineHandle; + m_commandStream << requestId; + m_commandStream << timeToAdvance; +} + +void CommandQueue::deleteStateMachine(StateMachineHandle stateMachineHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::deleteStateMachine; + m_commandStream << stateMachineHandle; + m_commandStream << requestId; +} + +RenderImageHandle CommandQueue::decodeImage( + std::vector imageEncodedBytes, + RenderImageListener* listener, + uint64_t requestId) +{ + auto handle = + reinterpret_cast(++m_currentRenderImageHandleIdx); + + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } + + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::decodeImage; + m_commandStream << handle; + m_commandStream << requestId; + m_byteVectors << std::move(imageEncodedBytes); + return handle; +} + +RenderImageHandle CommandQueue::addExternalImage(rcp externalImage, + RenderImageListener* listener, + uint64_t requestId) +{ + auto handle = + reinterpret_cast(++m_currentRenderImageHandleIdx); + + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } + + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::externalImage; + m_commandStream << handle; + m_commandStream << requestId; + m_externalImages << std::move(externalImage); + return handle; +} + +void CommandQueue::deleteImage(RenderImageHandle handle, uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::deleteImage; + m_commandStream << handle; + m_commandStream << requestId; +} + +AudioSourceHandle CommandQueue::decodeAudio( + std::vector imageEncodedBytes, + AudioSourceListener* listener, + uint64_t requestId) +{ + auto handle = + reinterpret_cast(++m_currentAudioSourceHandleIdx); + + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } + + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::decodeAudio; + m_commandStream << handle; + m_commandStream << requestId; + m_byteVectors << std::move(imageEncodedBytes); + return handle; +} + +AudioSourceHandle CommandQueue::addExternalAudio(rcp externalAudio, + AudioSourceListener* listener, + uint64_t requestId) +{ + auto handle = + reinterpret_cast(++m_currentAudioSourceHandleIdx); + + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } + + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::externalAudio; + m_commandStream << handle; + m_commandStream << requestId; + m_externalAudioSources << std::move(externalAudio); + return handle; +} + +void CommandQueue::deleteAudio(AudioSourceHandle handle, uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::deleteAudio; + m_commandStream << handle; + m_commandStream << requestId; +} + +FontHandle CommandQueue::decodeFont(std::vector imageEncodedBytes, + FontListener* listener, + uint64_t requestId) +{ + auto handle = reinterpret_cast(++m_currentFontHandleIdx); + + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } + + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::decodeFont; + m_commandStream << handle; + m_commandStream << requestId; + m_byteVectors << std::move(imageEncodedBytes); + return handle; +} + +FontHandle CommandQueue::addExternalFont(rcp externalFont, + FontListener* listener, + uint64_t requestId) +{ + auto handle = reinterpret_cast(++m_currentFontHandleIdx); + + if (listener) + { + assert(listener->m_handle == RIVE_NULL_HANDLE); + listener->m_handle = handle; + listener->m_owningQueue = ref_rcp(this); + registerListener(handle, listener); + } + + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::externalFont; + m_commandStream << handle; + m_commandStream << requestId; + m_externalFonts << std::move(externalFont); + return handle; +} + +void CommandQueue::deleteFont(FontHandle handle, uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::deleteFont; + m_commandStream << handle; + m_commandStream << requestId; +} + +DrawKey CommandQueue::createDrawKey() +{ + // lock here so we can do this from several threads safely + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + auto key = reinterpret_cast(++m_currentDrawKeyIdx); + return key; +} + +void CommandQueue::draw(DrawKey drawKey, CommandServerDrawCallback callback) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::draw; + m_commandStream << drawKey; + m_drawCallbacks << std::move(callback); +} + +void CommandQueue::cancelDraw(DrawKey drawKey) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::cancelDraw; + m_commandStream << drawKey; +} + +#ifdef TESTING +void CommandQueue::testing_commandLoopBreak() +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::commandLoopBreak; +} + +CommandQueue::FileListener* CommandQueue::testing_getFileListener( + FileHandle handle) +{ + auto iter = m_fileListeners.find(handle); + if (iter != m_fileListeners.end()) + return iter->second; + return nullptr; +} + +CommandQueue::ArtboardListener* CommandQueue::testing_getArtboardListener( + ArtboardHandle handle) +{ + auto iter = m_artboardListeners.find(handle); + if (iter != m_artboardListeners.end()) + return iter->second; + return nullptr; +} + +CommandQueue::StateMachineListener* CommandQueue:: + testing_getStateMachineListener(StateMachineHandle handle) +{ + auto iter = m_stateMachineListeners.find(handle); + if (iter != m_stateMachineListeners.end()) + return iter->second; + return nullptr; +} + +#endif +void CommandQueue::runOnce(CommandServerCallback callback) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::runOnce; + m_callbacks << std::move(callback); +} + +void CommandQueue::disconnect() +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::disconnect; +} + +void CommandQueue::requestViewModelNames(FileHandle fileHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModels; + m_commandStream << fileHandle; + m_commandStream << requestId; +} + +void CommandQueue::requestArtboardNames(FileHandle fileHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listArtboards; + m_commandStream << fileHandle; + m_commandStream << requestId; +} + +void CommandQueue::requestViewModelInstanceViewModelName( + ViewModelInstanceHandle viewModelInstanceHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::getViewModelInstanceViewModelName; + m_commandStream << viewModelInstanceHandle; + m_commandStream << requestId; +} +void CommandQueue::requestViewModelEnums(FileHandle fileHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelEnums; + m_commandStream << fileHandle; + m_commandStream << requestId; +} + +void CommandQueue::requestViewModelPropertyDefinitions( + FileHandle handle, + std::string viewModelName, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelProperties; + m_commandStream << handle; + m_commandStream << requestId; + m_names << viewModelName; +} + +void CommandQueue::requestViewModelInstanceNames(FileHandle handle, + std::string viewModelName, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelInstanceNames; + m_commandStream << handle; + m_commandStream << requestId; + m_names << viewModelName; +} + +void CommandQueue::requestViewModelInstanceBool(ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelPropertyValue; + m_commandStream << DataType::boolean; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestViewModelInstanceNumber( + ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelPropertyValue; + m_commandStream << DataType::number; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestViewModelInstanceColor(ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelPropertyValue; + m_commandStream << DataType::color; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestViewModelInstanceEnum(ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelPropertyValue; + m_commandStream << DataType::enumType; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestViewModelInstanceString( + ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listViewModelPropertyValue; + m_commandStream << DataType::string; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestViewModelInstanceListSize( + ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::getViewModelListSize; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestViewModelInstanceListClear( + ViewModelInstanceHandle handle, + std::string path, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::clearViewModelList; + m_commandStream << handle; + m_commandStream << requestId; + m_names << path; +} + +void CommandQueue::requestStateMachineNames(ArtboardHandle artboardHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::listStateMachines; + m_commandStream << artboardHandle; + m_commandStream << requestId; +} + +void CommandQueue::requestDefaultViewModelInfo(ArtboardHandle artboardHandle, + FileHandle fileHandle, + uint64_t requestId) +{ + AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable); + m_commandStream << Command::getDefaultViewModel; + m_commandStream << fileHandle; + m_commandStream << artboardHandle; + m_commandStream << requestId; +} + +void CommandQueue::processMessages() +{ + std::unique_lock lock(m_messageMutex); + + if (m_messageStream.empty()) + return; + + // Mark where we will end processing messages. This way if new messages come + // in while we're processing the existing ones, we won't loop forever. + m_messageStream << Message::messageLoopBreak; + + do + { + Message message; + m_messageStream >> message; + + switch (message) + { + case Message::messageLoopBreak: + lock.unlock(); + return; + case Message::viewModelEnumsListed: + { + size_t numEnums; + FileHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageStream >> numEnums; + std::vector enums(numEnums); + for (auto& enumData : enums) + { + size_t numEnumDataValue; + m_messageStream >> numEnumDataValue; + m_messageNames >> enumData.name; + enumData.enumerants.resize(numEnumDataValue); + for (auto& enumDataValue : enumData.enumerants) + { + m_messageNames >> enumDataValue; + } + } + lock.unlock(); + + if (m_globalFileListener) + { + m_globalFileListener->onViewModelEnumsListed( + handle, + requestId, + std::move(enums)); + } + + auto itr = m_fileListeners.find(handle); + if (itr != m_fileListeners.end()) + { + itr->second->onViewModelEnumsListed(itr->first, + requestId, + std::move(enums)); + } + break; + } + case Message::artboardsListed: + { + size_t numArtboards; + FileHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; m_messageStream >> numArtboards; std::vector artboardNames(numArtboards); for (auto& name : artboardNames) { - m_messageNames >> name; + m_messageNames >> name; + } + lock.unlock(); + + if (m_globalFileListener) + { + m_globalFileListener->onArtboardsListed(handle, + requestId, + artboardNames); + } + + auto itr = m_fileListeners.find(handle); + if (itr != m_fileListeners.end()) + { + itr->second->onArtboardsListed(itr->first, + requestId, + std::move(artboardNames)); + } + break; + } + case Message::stateMachinesListed: + { + size_t numStateMachines; + ArtboardHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageStream >> numStateMachines; + std::vector stateMachineNames(numStateMachines); + for (auto& name : stateMachineNames) + { + m_messageNames >> name; + } + lock.unlock(); + + if (m_globalArtboardListener) + { + m_globalArtboardListener->onStateMachinesListed( + handle, + requestId, + stateMachineNames); + } + + auto itr = m_artboardListeners.find(handle); + if (itr != m_artboardListeners.end()) + { + itr->second->onStateMachinesListed( + itr->first, + requestId, + std::move(stateMachineNames)); + } + + break; + } + case Message::defaultViewModelReceived: + { + ArtboardHandle handle; + uint64_t requestId; + std::string defaultViewModel; + std::string defaultViewModelInstance; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> defaultViewModel; + m_messageNames >> defaultViewModelInstance; + lock.unlock(); + + if (m_globalArtboardListener) + { + m_globalArtboardListener->onDefaultViewModelInfoReceived( + handle, + requestId, + defaultViewModel, + defaultViewModelInstance); + } + + auto itr = m_artboardListeners.find(handle); + if (itr != m_artboardListeners.end()) + { + itr->second->onDefaultViewModelInfoReceived( + itr->first, + requestId, + std::move(defaultViewModel), + std::move(defaultViewModelInstance)); + } + + break; + } + case Message::viewModelInstanceViewModelNameReceived: + { + ViewModelInstanceHandle handle; + uint64_t requestId; + std::string viewModelName; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> viewModelName; + + lock.unlock(); + if (m_globalViewModelListener) + { + m_globalViewModelListener + ->onViewModelInstanceViewModelNameReceived( + handle, + requestId, + viewModelName); + } + auto itr = m_viewModelListeners.find(handle); + if (itr != m_viewModelListeners.end()) + { + itr->second->onViewModelInstanceViewModelNameReceived( + handle, + requestId, + viewModelName); + } + break; + } + case Message::viewModelsListend: + { + size_t numViewModels; + FileHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageStream >> numViewModels; + std::vector viewModelNames(numViewModels); + for (auto& name : viewModelNames) + { + m_messageNames >> name; + } + lock.unlock(); + + if (m_globalFileListener) + { + m_globalFileListener->onViewModelsListed(handle, + requestId, + viewModelNames); + } + + auto itr = m_fileListeners.find(handle); + if (itr != m_fileListeners.end()) + { + itr->second->onViewModelsListed(itr->first, + requestId, + std::move(viewModelNames)); + } + + break; + } + + case Message::viewModelInstanceNamesListed: + { + size_t numViewModels; + FileHandle handle; + uint64_t requestId; + std::string viewModelName; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageStream >> numViewModels; + m_messageNames >> viewModelName; + std::vector viewModelInstanceNames(numViewModels); + for (auto& name : viewModelInstanceNames) + { + m_messageNames >> name; + } + lock.unlock(); + + if (m_globalFileListener) + { + m_globalFileListener->onViewModelInstanceNamesListed( + handle, + requestId, + viewModelName, + viewModelInstanceNames); + } + + auto itr = m_fileListeners.find(handle); + if (itr != m_fileListeners.end()) + { + itr->second->onViewModelInstanceNamesListed( + itr->first, + requestId, + std::move(viewModelName), + std::move(viewModelInstanceNames)); + } + break; + } + + case Message::viewModelPropertiesListed: + { + size_t numViewProperties; + FileHandle handle; + uint64_t requestId; + std::string viewModelName; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageStream >> numViewProperties; + m_messageNames >> viewModelName; + std::vector + viewModelProperties(numViewProperties); + + for (auto& property : viewModelProperties) + { + m_messageStream >> property.type; + m_messageNames >> property.name; + if (property.type == DataType::enumType || + property.type == DataType::viewModel) + { + m_messageNames >> property.metaData; + } + } + lock.unlock(); + + if (m_globalFileListener) + { + m_globalFileListener->onViewModelPropertiesListed( + handle, + requestId, + viewModelName, + viewModelProperties); + } + + auto itr = m_fileListeners.find(handle); + if (itr != m_fileListeners.end()) + { + itr->second->onViewModelPropertiesListed( + itr->first, + requestId, + std::move(viewModelName), + std::move(viewModelProperties)); + } + + break; + } + + case Message::viewModelPropertyValueReceived: + { + ViewModelInstanceHandle handle; + uint64_t requestId; + ViewModelInstanceData value; + + m_messageStream >> handle; + m_messageStream >> value.metaData.type; + m_messageStream >> requestId; + m_messageNames >> value.metaData.name; + + switch (value.metaData.type) + { + case DataType::assetImage: + case DataType::list: + case DataType::trigger: + break; + case DataType::boolean: + m_messageStream >> value.boolValue; + break; + case DataType::number: + m_messageStream >> value.numberValue; + break; + case DataType::color: + m_messageStream >> value.colorValue; + break; + case DataType::enumType: + case DataType::string: + m_messageNames >> value.stringValue; + break; + default: + RIVE_UNREACHABLE(); + } + + lock.unlock(); + + if (m_globalViewModelListener) + { + m_globalViewModelListener->onViewModelDataReceived( + handle, + requestId, + value); + } + + auto itr = m_viewModelListeners.find(handle); + if (itr != m_viewModelListeners.end()) + { + itr->second->onViewModelDataReceived(handle, + requestId, + value); + } + + break; + } + + case Message::viewModelListSizeReceived: + { + ViewModelInstanceHandle handle; + std::string path; + size_t size; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> size; + m_messageStream >> requestId; + m_messageNames >> path; + lock.unlock(); + if (m_globalViewModelListener) + { + m_globalViewModelListener->onViewModelListSizeReceived( + handle, + requestId, + path, + size); + } + auto itr = m_viewModelListeners.find(handle); + if (itr != m_viewModelListeners.end()) + { + itr->second->onViewModelListSizeReceived(handle, + requestId, + std::move(path), + size); } + break; + } + + case Message::viewModelListCleared: + { + ViewModelInstanceHandle handle; + std::string path; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> path; lock.unlock(); + if (m_globalViewModelListener) + { + m_globalViewModelListener->onViewModelListCleared(handle, + requestId, + path); + } + + auto itr = m_viewModelListeners.find(handle); + if (itr != m_viewModelListeners.end()) + { + itr->second->onViewModelListCleared(handle, + requestId, + std::move(path)); + } + } + break; + case Message::fileLoaded: + { + FileHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalFileListener) + { + m_globalFileListener->onFileLoaded(handle, requestId); + } auto itr = m_fileListeners.find(handle); if (itr != m_fileListeners.end()) { - itr->second->onArtboardsListed(itr->first, - requestId, - std::move(artboardNames)); + itr->second->onFileLoaded(handle, requestId); } break; } - case Message::stateMachinesListed: + + case Message::artboardInstantiated: { - size_t numStateMachines; + FileHandle fileHandle; ArtboardHandle handle; uint64_t requestId; + m_messageStream >> fileHandle; m_messageStream >> handle; m_messageStream >> requestId; - m_messageStream >> numStateMachines; - std::vector stateMachineNames(numStateMachines); - for (auto& name : stateMachineNames) + lock.unlock(); + if (m_globalFileListener) { - m_messageNames >> name; + m_globalFileListener->onArtboardInstantiated(fileHandle, + requestId, + handle); } - lock.unlock(); + auto itr = m_fileListeners.find(fileHandle); + if (itr != m_fileListeners.end()) + { + itr->second->onArtboardInstantiated(fileHandle, + requestId, + handle); + } + break; + } - auto itr = m_artboardListeners.find(handle); - if (itr != m_artboardListeners.end()) + case Message::stateMachineInstantiated: + { + ArtboardHandle artboardHandle; + StateMachineHandle handle; + uint64_t requestId; + m_messageStream >> artboardHandle; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalArtboardListener) { - itr->second->onStateMachinesListed( - itr->first, + m_globalArtboardListener->onStateMachineInstantiated( + artboardHandle, requestId, - std::move(stateMachineNames)); + handle); + } + auto itr = m_artboardListeners.find(artboardHandle); + if (itr != m_artboardListeners.end()) + { + itr->second->onStateMachineInstantiated(artboardHandle, + requestId, + handle); } + break; + } + case Message::viewModelInstanceInstantiated: + { + FileHandle fileHandle; + ViewModelInstanceHandle handle; + uint64_t requestId; + m_messageStream >> fileHandle; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalFileListener) + { + m_globalFileListener->onViewModelInstanceInstantiated( + fileHandle, + requestId, + handle); + } + auto itr = m_fileListeners.find(fileHandle); + if (itr != m_fileListeners.end()) + { + itr->second->onViewModelInstanceInstantiated(fileHandle, + requestId, + handle); + } break; } + case Message::fileDeleted: { FileHandle handle; @@ -343,6 +1565,10 @@ void CommandQueue::processMessages() m_messageStream >> handle; m_messageStream >> requestId; lock.unlock(); + if (m_globalFileListener) + { + m_globalFileListener->onFileDeleted(handle, requestId); + } auto itr = m_fileListeners.find(handle); if (itr != m_fileListeners.end()) { @@ -350,6 +1576,118 @@ void CommandQueue::processMessages() } break; } + case Message::imageDecoded: + { + RenderImageHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalImageListener) + { + m_globalImageListener->onRenderImageDecoded(handle, + requestId); + } + auto itr = m_imageListeners.find(handle); + if (itr != m_imageListeners.end()) + { + itr->second->onRenderImageDecoded(handle, requestId); + } + break; + } + case Message::imageDeleted: + { + RenderImageHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalImageListener) + { + m_globalImageListener->onRenderImageDeleted(handle, + requestId); + } + auto itr = m_imageListeners.find(handle); + if (itr != m_imageListeners.end()) + { + itr->second->onRenderImageDeleted(handle, requestId); + } + break; + } + case Message::audioDecoded: + { + AudioSourceHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalAudioListener) + { + m_globalAudioListener->onAudioSourceDecoded(handle, + requestId); + } + auto itr = m_audioListeners.find(handle); + if (itr != m_audioListeners.end()) + { + itr->second->onAudioSourceDecoded(handle, requestId); + } + break; + } + case Message::audioDeleted: + { + AudioSourceHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalAudioListener) + { + m_globalAudioListener->onAudioSourceDeleted(handle, + requestId); + } + auto itr = m_audioListeners.find(handle); + if (itr != m_audioListeners.end()) + { + itr->second->onAudioSourceDeleted(handle, requestId); + } + break; + } + case Message::fontDecoded: + { + FontHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalFontListener) + { + m_globalFontListener->onFontDecoded(handle, requestId); + } + auto itr = m_fontListeners.find(handle); + if (itr != m_fontListeners.end()) + { + itr->second->onFontDecoded(handle, requestId); + } + break; + } + case Message::fontDeleted: + { + FontHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalFontListener) + { + m_globalFontListener->onFontDeleted(handle, requestId); + } + auto itr = m_fontListeners.find(handle); + if (itr != m_fontListeners.end()) + { + itr->second->onFontDeleted(handle, requestId); + } + break; + } case Message::artboardDeleted: { ArtboardHandle handle; @@ -357,6 +1695,11 @@ void CommandQueue::processMessages() m_messageStream >> handle; m_messageStream >> requestId; lock.unlock(); + if (m_globalArtboardListener) + { + m_globalArtboardListener->onArtboardDeleted(handle, + requestId); + } auto itr = m_artboardListeners.find(handle); if (itr != m_artboardListeners.end()) { @@ -364,6 +1707,25 @@ void CommandQueue::processMessages() } break; } + case Message::viewModelDeleted: + { + ViewModelInstanceHandle handle; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + lock.unlock(); + if (m_globalViewModelListener) + { + m_globalViewModelListener->onViewModelDeleted(handle, + requestId); + } + auto itr = m_viewModelListeners.find(handle); + if (itr != m_viewModelListeners.end()) + { + itr->second->onViewModelDeleted(handle, requestId); + } + break; + } case Message::stateMachineSettled: { StateMachineHandle handle; @@ -371,6 +1733,12 @@ void CommandQueue::processMessages() m_messageStream >> handle; m_messageStream >> requestId; lock.unlock(); + if (m_globalStateMachineListener) + { + m_globalStateMachineListener->onStateMachineSettled( + handle, + requestId); + } auto itr = m_stateMachineListeners.find(handle); if (itr != m_stateMachineListeners.end()) { @@ -385,6 +1753,12 @@ void CommandQueue::processMessages() m_messageStream >> handle; m_messageStream >> requestId; lock.unlock(); + if (m_globalStateMachineListener) + { + m_globalStateMachineListener->onStateMachineDeleted( + handle, + requestId); + } auto itr = m_stateMachineListeners.find(handle); if (itr != m_stateMachineListeners.end()) { @@ -392,9 +1766,174 @@ void CommandQueue::processMessages() } break; } - default: + + case Message::fileError: + { + FileHandle handle; + std::string error; + uint64_t requestId; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalFileListener) + { + m_globalFileListener->onFileError(handle, requestId, error); + } + auto itr = m_fileListeners.find(handle); + if (itr != m_fileListeners.end()) + { + itr->second->onFileError(handle, + requestId, + std::move(error)); + } + + break; + } + case Message::viewModelError: + { + ViewModelInstanceHandle handle; + uint64_t requestId; + + std::string error; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalViewModelListener) + { + m_globalViewModelListener->onViewModelInstanceError( + handle, + requestId, + error); + } + auto itr = m_viewModelListeners.find(handle); + if (itr != m_viewModelListeners.end()) + { + itr->second->onViewModelInstanceError(handle, + requestId, + std::move(error)); + } + break; + } + case Message::imageError: + { + RenderImageHandle handle; + uint64_t requestId; + std::string error; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalImageListener) + { + m_globalImageListener->onRenderImageError(handle, + requestId, + error); + } + auto itr = m_imageListeners.find(handle); + if (itr != m_imageListeners.end()) + { + itr->second->onRenderImageError(handle, + requestId, + std::move(error)); + } + break; + } + + case Message::audioError: + { + AudioSourceHandle handle; + uint64_t requestId; + std::string error; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalAudioListener) + { + m_globalAudioListener->onAudioSourceError(handle, + requestId, + error); + } + auto itr = m_audioListeners.find(handle); + if (itr != m_audioListeners.end()) + { + itr->second->onAudioSourceError(handle, + requestId, + std::move(error)); + } + break; + } + case Message::fontError: + { + FontHandle handle; + uint64_t requestId; + std::string error; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalFontListener) + { + m_globalFontListener->onFontError(handle, requestId, error); + } + auto itr = m_fontListeners.find(handle); + if (itr != m_fontListeners.end()) + { + itr->second->onFontError(handle, + requestId, + std::move(error)); + } + break; + } + + case Message::stateMachineError: + { + StateMachineHandle handle; + uint64_t requestId; + std::string error; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalStateMachineListener) + { + m_globalStateMachineListener->onStateMachineError(handle, + requestId, + error); + } + auto itr = m_stateMachineListeners.find(handle); + if (itr != m_stateMachineListeners.end()) + { + itr->second->onStateMachineError(handle, + requestId, + std::move(error)); + } + break; + } + case Message::artboardError: { - RIVE_UNREACHABLE(); + ArtboardHandle handle; + uint64_t requestId; + std::string error; + m_messageStream >> handle; + m_messageStream >> requestId; + m_messageNames >> error; + lock.unlock(); + if (m_globalArtboardListener) + { + m_globalArtboardListener->onArtboardError(handle, + requestId, + error); + } + auto itr = m_artboardListeners.find(handle); + if (itr != m_artboardListeners.end()) + { + itr->second->onArtboardError(handle, + requestId, + std::move(error)); + } break; } } diff --git a/thirdparty/rive/source/command_server.cpp b/thirdparty/rive/source/command_server.cpp index 7a1d19742..96eb829bd 100644 --- a/thirdparty/rive/source/command_server.cpp +++ b/thirdparty/rive/source/command_server.cpp @@ -4,23 +4,349 @@ #include "rive/command_server.hpp" -#include "rive/file.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/assets/audio_asset.hpp" +#include "rive/assets/font_asset.hpp" +#include "rive/assets/image_asset.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/file.hpp" +#include "rive/viewmodel/runtime/viewmodel_runtime.hpp" namespace rive { + +class CommandServer::CommandFileAssetLoader : public FileAssetLoader +{ +public: + CommandFileAssetLoader(CommandServer* server, + rcp internalLoader) : + m_server(server), m_internalLoader(internalLoader) + {} + + virtual bool loadContents(FileAsset& asset, + Span inBandBytes, + Factory* factory) override + { + if (m_internalLoader) + { + if (m_internalLoader->loadContents(asset, inBandBytes, factory)) + return true; + } + if (asset.is()) + { + // No need for another if because as just asserts the above + // condition anyway + auto imageAsset = asset.as(); + auto itr = m_imageAssets.find(asset.uniqueName()); + if (itr != m_imageAssets.end()) + { + auto image = m_server->getImage(itr->second); + if (image) + { + imageAsset->renderImage(ref_rcp(image)); + return true; + } + return false; + } + } + + else if (asset.is()) + { + auto audioAsset = asset.as(); + auto itr = m_audioAssets.find(asset.uniqueName()); + if (itr != m_audioAssets.end()) + { + auto audioSource = m_server->getAudioSource(itr->second); + if (audioSource) + { + audioAsset->audioSource(ref_rcp(audioSource)); + return true; + } + return false; + } + } + else if (asset.is()) + { + auto fontAsset = asset.as(); + auto itr = m_fontAssets.find(asset.uniqueName()); + if (itr != m_fontAssets.end()) + { + auto font = m_server->getFont(itr->second); + if (font) + { + fontAsset->font(ref_rcp(font)); + return true; + } + return false; + } + } + else if (asset.is()) + { + // Script assets cannot currently be added externally. + // Let the file loader handle it. + return false; + } + else + { + fprintf(stderr, + "ERROR: CommandFileAssetLoader::loadContents - Unsupported" + " asset type for asset: '%s'\n", + asset.uniqueFilename().c_str()); + return false; + } + + return false; + } + + void addRenderImage(std::string name, RenderImageHandle handle) + { + m_imageAssets[name] = handle; + } + + void addAudioSource(std::string name, AudioSourceHandle handle) + { + m_audioAssets[name] = handle; + } + + void addFont(std::string name, FontHandle handle) + { + m_fontAssets[name] = handle; + } + + void removeRenderImage(RenderImageHandle handle) + { + using ItrType = std::pair; + auto itr = std::find_if( + m_imageAssets.begin(), + m_imageAssets.end(), + [handle](const ItrType& p) { return p.second == handle; }); + if (itr != m_imageAssets.end()) + m_imageAssets.erase(itr); + } + + void removeAudioSource(AudioSourceHandle handle) + { + using ItrType = std::pair; + auto itr = std::find_if( + m_audioAssets.begin(), + m_audioAssets.end(), + [handle](const ItrType& p) { return p.second == handle; }); + if (itr != m_audioAssets.end()) + m_audioAssets.erase(itr); + } + + void removeFont(FontHandle handle) + { + using ItrType = std::pair; + auto itr = std::find_if( + m_fontAssets.begin(), + m_fontAssets.end(), + [handle](const ItrType& p) { return p.second == handle; }); + if (itr != m_fontAssets.end()) + m_fontAssets.erase(itr); + } + + void removeRenderImage(std::string name) { m_imageAssets.erase(name); } + void removeAudioSource(std::string name) { m_audioAssets.erase(name); } + void removeFont(std::string name) { m_fontAssets.erase(name); } + +#ifdef TESTING + RenderImageHandle testing_imageNamed(std::string name) + { + auto itr = m_imageAssets.find(name); + if (itr != m_imageAssets.end()) + return itr->second; + return nullptr; + } + + AudioSourceHandle testing_audioNamed(std::string name) + { + auto itr = m_audioAssets.find(name); + if (itr != m_audioAssets.end()) + return itr->second; + return nullptr; + } + + FontHandle testing_fontNamed(std::string name) + { + auto itr = m_fontAssets.find(name); + if (itr != m_fontAssets.end()) + return itr->second; + return nullptr; + } +#endif + +private: + const CommandServer* m_server; + + std::unordered_map m_imageAssets; + std::unordered_map m_audioAssets; + std::unordered_map m_fontAssets; + rcp m_internalLoader; +}; + +std::ostream& operator<<(std::ostream& os, DataType t) +{ + switch (t) + { + case DataType::none: + os << "None"; + break; + case DataType::string: + os << "String"; + break; + case DataType::number: + os << "Number"; + break; + case DataType::boolean: + os << "Boolean"; + break; + case DataType::color: + os << "Color"; + break; + case DataType::list: + os << "List"; + break; + case DataType::enumType: + os << "Enum"; + break; + case DataType::trigger: + os << "Trigger"; + break; + case DataType::viewModel: + os << "View Model"; + break; + case DataType::integer: + os << "Integer"; + break; + case DataType::symbolListIndex: + os << "Symbol List Index"; + break; + case DataType::assetImage: + os << "Asset Image"; + break; + default: + os << "Unknown DataType"; + break; + } + return os; +} + +#ifdef TESTING + +RenderImageHandle CommandServer::testing_globalImageNamed(std::string name) +{ + return m_fileAssetLoader->testing_imageNamed(name); +} + +AudioSourceHandle CommandServer::testing_globalAudioNamed(std::string name) +{ + return m_fileAssetLoader->testing_audioNamed(name); +} + +FontHandle CommandServer::testing_globalFontNamed(std::string name) +{ + return m_fileAssetLoader->testing_fontNamed(name); +} + +bool CommandServer::testing_globalImageContains(std::string name) +{ + return m_fileAssetLoader->testing_imageNamed(name) != nullptr; +} + +bool CommandServer::testing_globalAudioContains(std::string name) +{ + return m_fileAssetLoader->testing_audioNamed(name) != nullptr; +} + +bool CommandServer::testing_globalFontContains(std::string name) +{ + return m_fileAssetLoader->testing_fontNamed(name) != nullptr; +} + +#endif + CommandServer::CommandServer(rcp commandBuffer, - Factory* factory) : + Factory* factory, + rcp internalLoader) : m_commandQueue(std::move(commandBuffer)), - m_factory(factory) + m_factory(factory), #ifndef NDEBUG - , - m_threadID(std::this_thread::get_id()) + m_threadID(std::this_thread::get_id()), #endif + m_fileAssetLoader( + make_rcp(this, std::move(internalLoader))) {} CommandServer::~CommandServer() {} +rive::HitResult CommandServer::pointerDownSynchronized( + StateMachineHandle handle, + const CommandQueue::PointerEvent& pointerEvent) +{ + std::unique_lock accesLock(m_stateMachineAccessMutex); + auto it = m_stateMachines.find(handle); + if (it != m_stateMachines.end()) + { + auto stateMachine = it->second; + accesLock.unlock(); + auto pos = cursorPosForPointerEvent(stateMachine->instance.get(), + pointerEvent); + { + std::unique_lock lock(stateMachine->m_mutex); + return stateMachine->instance->pointerDown(pos, + pointerEvent.pointerId); + } + } + + return rive::HitResult::none; +} + +rive::HitResult CommandServer::pointerMoveSynchronized( + StateMachineHandle handle, + const CommandQueue::PointerEvent& pointerEvent) +{ + std::unique_lock accesLock(m_stateMachineAccessMutex); + auto it = m_stateMachines.find(handle); + if (it != m_stateMachines.end()) + { + auto stateMachine = it->second; + accesLock.unlock(); + auto pos = cursorPosForPointerEvent(stateMachine->instance.get(), + pointerEvent); + { + std::unique_lock lock(stateMachine->m_mutex); + return stateMachine->instance->pointerMove(pos, + 0, + pointerEvent.pointerId); + } + } + + return rive::HitResult::none; +} + +rive::HitResult CommandServer::pointerUpSynchronized( + StateMachineHandle handle, + const CommandQueue::PointerEvent& pointerEvent) +{ + std::unique_lock accesLock(m_stateMachineAccessMutex); + auto it = m_stateMachines.find(handle); + if (it != m_stateMachines.end()) + { + auto stateMachine = it->second; + accesLock.unlock(); + auto pos = cursorPosForPointerEvent(stateMachine->instance.get(), + pointerEvent); + { + std::unique_lock lock(stateMachine->m_mutex); + return stateMachine->instance->pointerUp(pos, + pointerEvent.pointerId); + } + } + + return rive::HitResult::none; +} + File* CommandServer::getFile(FileHandle handle) const { assert(std::this_thread::get_id() == m_threadID); @@ -28,12 +354,49 @@ File* CommandServer::getFile(FileHandle handle) const return it != m_files.end() ? it->second.get() : nullptr; } +RenderImage* CommandServer::getImage(RenderImageHandle handle) const +{ + assert(std::this_thread::get_id() == m_threadID); + auto it = m_images.find(handle); + return it != m_images.end() ? it->second.get() : nullptr; +} + +AudioSource* CommandServer::getAudioSource(AudioSourceHandle handle) const +{ + assert(std::this_thread::get_id() == m_threadID); + auto it = m_audioSources.find(handle); + return it != m_audioSources.end() ? it->second.get() : nullptr; +} + +Font* CommandServer::getFont(FontHandle handle) const +{ + assert(std::this_thread::get_id() == m_threadID); + auto it = m_fonts.find(handle); + return it != m_fonts.end() ? it->second.get() : nullptr; +} + ArtboardInstance* CommandServer::getArtboardInstance( ArtboardHandle handle) const { assert(std::this_thread::get_id() == m_threadID); auto it = m_artboards.find(handle); - return it != m_artboards.end() ? it->second.get() : nullptr; + return it != m_artboards.end() ? it->second.get()->artboard() : nullptr; +} + +rcp CommandServer::getBindableArtboard( + ArtboardHandle handle) const +{ + assert(std::this_thread::get_id() == m_threadID); + auto it = m_artboards.find(handle); + return it != m_artboards.end() ? it->second : nullptr; +} + +rcp CommandServer:: + getStateMachineWrapper(StateMachineHandle handle) +{ + assert(std::this_thread::get_id() == m_threadID); + auto it = m_stateMachines.find(handle); + return it != m_stateMachines.end() ? it->second : nullptr; } StateMachineInstance* CommandServer::getStateMachineInstance( @@ -41,7 +404,166 @@ StateMachineInstance* CommandServer::getStateMachineInstance( { assert(std::this_thread::get_id() == m_threadID); auto it = m_stateMachines.find(handle); - return it != m_stateMachines.end() ? it->second.get() : nullptr; + return it != m_stateMachines.end() ? it->second->instance.get() : nullptr; +} + +ViewModelInstanceRuntime* CommandServer::getViewModelInstance( + ViewModelInstanceHandle handle) const +{ + assert(std::this_thread::get_id() == m_threadID); + auto it = m_viewModels.find(handle); + return it != m_viewModels.end() ? it->second.get() : nullptr; +} + +ViewModelInstanceHandle CommandServer::getHandleForInstance( + ViewModelInstanceRuntime* handle) const +{ + assert(std::this_thread::get_id() == m_threadID); + for (auto& itr : m_viewModels) + { + if (itr.second.get() == handle) + { + return itr.first; + } + } + return RIVE_NULL_HANDLE; +} + +Vec2D CommandServer::cursorPosForPointerEvent( + StateMachineInstance* instance, + const CommandQueue::PointerEvent& pointerEvent) +{ + AABB artboardBounds = instance->artboard()->bounds(); + AABB surfaceBounds = AABB(Vec2D{0.0f, 0.0f}, pointerEvent.screenBounds); + + if (surfaceBounds == artboardBounds || surfaceBounds.width() == 0.0f || + surfaceBounds.height() == 0.0f) + { + return pointerEvent.position; + } + + Mat2D forward = rive::computeAlignment(pointerEvent.fit, + pointerEvent.alignment, + surfaceBounds, + artboardBounds, + pointerEvent.scaleFactor); + + Mat2D inverse = forward.invertOrIdentity(); + + return inverse * pointerEvent.position; +} + +void CommandServer::checkPropertySubscriptions() +{ + for (auto& subscription : m_propertySubscriptions) + { + uint64_t requestId = subscription.requestId; + ViewModelInstanceHandle handle = subscription.rootViewModel; + CommandQueue::ViewModelInstanceData data; + data.metaData = subscription.data; + + if (auto viewModel = getViewModelInstance(handle)) + { + if (auto property = viewModel->property(data.metaData.name)) + { + if (property->hasChanged()) + { + property->clearChanges(); + switch (data.metaData.type) + { + // These don't have values but are still valid + // subscriptions. + case DataType::assetImage: + case DataType::trigger: + case DataType::list: + break; + case DataType::boolean: + if (auto value = static_cast< + ViewModelInstanceBooleanRuntime*>(property)) + { + data.boolValue = value->value(); + } + break; + + case DataType::color: + if (auto value = + static_cast( + property)) + { + data.colorValue = value->value(); + } + break; + + case DataType::number: + if (auto value = static_cast< + ViewModelInstanceNumberRuntime*>(property)) + { + data.numberValue = value->value(); + } + break; + + case DataType::enumType: + if (auto value = + static_cast( + property)) + { + data.stringValue = value->value(); + } + break; + + case DataType::string: + if (auto value = static_cast< + ViewModelInstanceStringRuntime*>(property)) + { + data.stringValue = value->value(); + } + break; + default: + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "ERROR : Invalid data type {" + << data.metaData.type << "} when checking" + << "subscriptions"; + continue; + } + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + m_commandQueue->m_messageStream << CommandQueue::Message:: + viewModelPropertyValueReceived; + m_commandQueue->m_messageStream << handle; + m_commandQueue->m_messageStream << data.metaData.type; + m_commandQueue->m_messageNames << data.metaData.name; + m_commandQueue->m_messageStream << requestId; + switch (data.metaData.type) + { + case DataType::assetImage: + case DataType::trigger: + case DataType::list: + break; + case DataType::boolean: + m_commandQueue->m_messageStream << data.boolValue; + break; + case DataType::number: + m_commandQueue->m_messageStream << data.numberValue; + break; + case DataType::color: + m_commandQueue->m_messageStream << data.colorValue; + break; + case DataType::enumType: + case DataType::string: + m_commandQueue->m_messageNames << data.stringValue; + break; + default: + RIVE_UNREACHABLE(); + } + } + } + } + } } void CommandServer::serveUntilDisconnect() @@ -58,7 +580,12 @@ bool CommandServer::waitCommands() { std::unique_lock lock(m_commandQueue->m_commandMutex); while (commandStream.empty()) + { + assert(m_commandQueue->m_callbacks.empty()); + assert(m_commandQueue->m_byteVectors.empty()); + assert(m_commandQueue->m_names.empty()); m_commandQueue->m_commandConditionVariable.wait(lock); + } } return processCommands(); @@ -70,6 +597,7 @@ bool CommandServer::processCommands() assert(std::this_thread::get_id() == m_threadID); PODStream& commandStream = m_commandQueue->m_commandStream; + PODStream& messageStream = m_commandQueue->m_messageStream; std::unique_lock lock(m_commandQueue->m_commandMutex); // Early out if we don't have anything to process. @@ -89,6 +617,7 @@ bool CommandServer::processCommands() { CommandQueue::Command command; commandStream >> command; + switch (command) { case CommandQueue::Command::loadFile: @@ -96,24 +625,32 @@ bool CommandServer::processCommands() FileHandle handle; uint64_t requestId; std::vector rivBytes; - rcp loader; commandStream >> handle; commandStream >> requestId; - commandStream >> loader; m_commandQueue->m_byteVectors >> rivBytes; lock.unlock(); - std::unique_ptr file = - rive::File::import(rivBytes, - m_factory, - nullptr, - std::move(loader)); + rcp file = rive::File::import(rivBytes, + m_factory, + nullptr, + m_fileAssetLoader); if (file != nullptr) { - m_files[handle] = std::move(file); + m_fileDependencies[handle] = {}; + m_files[handle] = file; + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::fileLoaded; + messageStream << handle; + messageStream << requestId; } else { - fprintf(stderr, "ERROR: failed to load Rive file.\n"); + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fileError) + << "failed to load Rive file."; } break; } @@ -125,221 +662,2186 @@ bool CommandServer::processCommands() commandStream >> handle; commandStream >> requestId; lock.unlock(); - m_files.erase(handle); - std::unique_lock messageLock( - m_commandQueue->m_messageMutex); - m_commandQueue->m_messageStream - << CommandQueue::Message::fileDeleted; - m_commandQueue->m_messageStream << handle; - m_commandQueue->m_messageStream << requestId; + m_files.erase(handle); + auto itr = m_fileDependencies.find(handle); + if (itr != m_fileDependencies.end()) + { + auto& artboardVector = itr->second; + for (auto artboardHandle : artboardVector) + { + cleanupArtboard(artboardHandle, requestId); + } + + m_fileDependencies.erase(itr); + } + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::fileDeleted; + messageStream << handle; + messageStream << requestId; + break; + } + + case CommandQueue::Command::decodeImage: + { + RenderImageHandle handle; + uint64_t requestId; + std::vector bytes; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_byteVectors >> bytes; + lock.unlock(); + + auto image = factory()->decodeImage(bytes); + if (image) + { + m_images[handle] = std::move(image); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::imageDecoded; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::imageError) + << "Command Server failed to decode image"; + } + + break; + } + + case CommandQueue::Command::externalImage: + { + RenderImageHandle handle; + uint64_t requestId; + rcp image; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_externalImages >> image; + lock.unlock(); + + if (image) + { + m_images[handle] = std::move(image); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::imageDecoded; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::imageError) + << "External image was empty"; + } + + break; + } + + case CommandQueue::Command::deleteImage: + { + RenderImageHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + m_images.erase(handle); + m_fileAssetLoader->removeRenderImage(handle); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::imageDeleted; + messageStream << handle; + messageStream << requestId; + break; + } + + case CommandQueue::Command::decodeAudio: + { + AudioSourceHandle handle; + uint64_t requestId; + std::vector bytes; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_byteVectors >> bytes; + lock.unlock(); + + auto audio = factory()->decodeAudio(bytes); + if (audio) + { + m_audioSources[handle] = std::move(audio); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::audioDecoded; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::audioError) + << "Command Server failed to decode audio"; + } + + break; + } + + case CommandQueue::Command::externalAudio: + { + AudioSourceHandle handle; + uint64_t requestId; + rcp audio; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_externalAudioSources >> audio; + lock.unlock(); + + if (audio) + { + m_audioSources[handle] = std::move(audio); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::audioDecoded; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::audioError) + << "External audio source was invalid"; + } + + break; + } + + case CommandQueue::Command::deleteAudio: + { + AudioSourceHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + m_audioSources.erase(handle); + m_fileAssetLoader->removeAudioSource(handle); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::audioDeleted; + messageStream << handle; + messageStream << requestId; + break; + } + + case CommandQueue::Command::decodeFont: + { + FontHandle handle; + uint64_t requestId; + std::vector bytes; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_byteVectors >> bytes; + lock.unlock(); + + auto font = factory()->decodeFont(bytes); + if (font) + { + m_fonts[handle] = std::move(font); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::fontDecoded; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fontError) + << "Command Server failed to decode font"; + } + + break; + } + + case CommandQueue::Command::externalFont: + { + FontHandle handle; + uint64_t requestId; + rcp font; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_externalFonts >> font; + lock.unlock(); + + if (font) + { + m_fonts[handle] = std::move(font); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::fontDecoded; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fontError) + << "Command Server failed to decode font"; + } + + break; + } + + case CommandQueue::Command::deleteFont: + { + FontHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + m_fonts.erase(handle); + m_fileAssetLoader->removeFont(handle); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::fontDeleted; + messageStream << handle; + messageStream << requestId; + break; + } + + case CommandQueue::Command::instantiateArtboard: + { + ArtboardHandle handle; + FileHandle fileHandle; + uint64_t requestId; + std::string name; + commandStream >> handle; + commandStream >> fileHandle; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + if (rive::File* file = getFile(fileHandle)) + { + if (auto artboard = name.empty() + ? file->bindableArtboardDefault() + : file->bindableArtboardNamed(name)) + { + m_artboardDependencies[handle] = {}; + m_artboards[handle] = std::move(artboard); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream + << CommandQueue::Message::artboardInstantiated; + messageStream << fileHandle; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "artboard \"" << name << "\" not found."; + } + } + else + { + ErrorReporter(this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "file " << fileHandle + << " not found when trying to create artboard"; + } + break; + } + + case CommandQueue::Command::setArtboardSize: + { + ArtboardHandle handle; + uint64_t requestId; + float width, height; + commandStream >> handle; + commandStream >> width; + commandStream >> height; + commandStream >> requestId; + lock.unlock(); + + if (auto artboardInstance = getArtboardInstance(handle)) + { + artboardInstance->width(width); + artboardInstance->height(height); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::artboardError) + << "artboard " << handle + << " not found when trying to set artboard size"; + } + } + break; + + case CommandQueue::Command::resetArtboardSize: + { + ArtboardHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + + if (auto artboardInstance = getArtboardInstance(handle)) + { + artboardInstance->resetSize(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::artboardError) + << "artboard " << handle + << " not found when trying to reset artboard size"; + } + } + break; + + case CommandQueue::Command::deleteArtboard: + { + ArtboardHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + cleanupArtboard(handle, requestId); + // We don't remove from the file dependencies here because + // calling erase on a non existent key is fine. + break; + } + + case CommandQueue::Command::instantiateViewModel: + case CommandQueue::Command::instantiateBlankViewModel: + case CommandQueue::Command::instantiateViewModelForArtboard: + case CommandQueue::Command::instantiateBlankViewModelForArtboard: + { + bool usesInstanceName = + command == CommandQueue::Command::instantiateViewModel || + command == + CommandQueue::Command::instantiateViewModelForArtboard; + bool usesArtboard = + command == CommandQueue::Command:: + instantiateBlankViewModelForArtboard || + command == + CommandQueue::Command::instantiateViewModelForArtboard; + + FileHandle fileHandle; + ArtboardHandle artboardHandle; + ViewModelInstanceHandle viewHandle; + uint64_t requestId; + std::string viewModelName; + std::string viewModelInstanceName; + commandStream >> fileHandle; + if (usesArtboard) + { + commandStream >> artboardHandle; + } + commandStream >> viewHandle; + commandStream >> requestId; + if (!usesArtboard) + { + m_commandQueue->m_names >> viewModelName; + } + if (usesInstanceName) + { + m_commandQueue->m_names >> viewModelInstanceName; + } + lock.unlock(); + if (auto file = getFile(fileHandle)) + { + ViewModelRuntime* viewModel = nullptr; + + if (usesArtboard) + { + if (auto artboardInstance = + getArtboardInstance(artboardHandle)) + { + viewModel = file->defaultArtboardViewModel( + artboardInstance); + if (viewModel == nullptr) + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "No view model found for artboard " + << artboardHandle; + } + } + else + { + if (usesInstanceName) + { + if (viewModelInstanceName.empty()) + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "ArtboardInstance " << artboardHandle + << " Not found when trying to create" + << " default view model with default " + "view " + << "model instance"; + } + else + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "ArtboardInstance " << artboardHandle + << " Not found when trying to create " + << "default view model with " + << "view model instance name " + << viewModelInstanceName; + } + } + else + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "ArtboardInstance " << artboardHandle + << " Not found when trying to create " + << "default view model with blank view " + << "model instance"; + } + } + } + else + { + viewModel = file->viewModelByName(viewModelName); + if (viewModel == nullptr) + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "View model " << viewModelName + << " not found"; + } + } + + if (viewModel) + { + rcp instance; + + if (usesInstanceName) + { + if (viewModelInstanceName.empty()) + { + instance = viewModel->createDefaultInstance(); + if (instance == nullptr) + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "Could not create " + << "default view model instance " + << "from view model " << viewModelName; + } + } + else + { + instance = viewModel->createInstanceFromName( + viewModelInstanceName); + if (instance == nullptr) + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "Could not create " + "view model instance named " + << viewModelInstanceName + << "from view model " << viewModelName; + } + } + } + else + { + instance = viewModel->createInstance(); + if (instance == nullptr) + { + ErrorReporter( + this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "Could not create " + << "blank view model instance " + << "from view model " << viewModelName; + } + } + + if (instance) + { + m_viewModels[viewHandle] = std::move(instance); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message:: + viewModelInstanceInstantiated; + messageStream << fileHandle; + messageStream << viewHandle; + messageStream << requestId; + } + } + } + else + { + ErrorReporter(this, + fileHandle, + requestId, + CommandQueue::Message::fileError) + << "File " << fileHandle + << " not found when creating view model instance "; + } + break; + } + + case CommandQueue::Command::addViewModelListValue: + { + ViewModelInstanceHandle rootHandle; + ViewModelInstanceHandle viewHandle; + uint64_t requestId; + std::string path; + int index; + commandStream >> rootHandle; + commandStream >> viewHandle; + commandStream >> index; + commandStream >> requestId; + m_commandQueue->m_names >> path; + lock.unlock(); + + if (auto root = getViewModelInstance(rootHandle)) + { + if (auto viewModel = getViewModelInstance(viewHandle)) + { + if (auto property = root->propertyList(path)) + { + if (index >= 0) + property->addInstanceAt(viewModel, index); + else + property->addInstance(viewModel); + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find list at path " << path + << " when trying to add to a list"; + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find value view model " << viewHandle + << "isntance for add list"; + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find root view model isntance " + << rootHandle << "for add list"; + } + + break; + } + + case CommandQueue::Command::removeViewModelListValue: + { + ViewModelInstanceHandle rootHandle; + ViewModelInstanceHandle viewHandle; + uint64_t requestId; + std::string path; + int index; + commandStream >> rootHandle; + commandStream >> viewHandle; + commandStream >> index; + commandStream >> requestId; + m_commandQueue->m_names >> path; + lock.unlock(); + + if (auto root = getViewModelInstance(rootHandle)) + { + if (auto property = root->propertyList(path)) + { + if (index >= 0) + { + property->removeInstanceAt(index); + } + else if (auto viewModel = + getViewModelInstance(viewHandle)) + { + property->removeInstance(viewModel); + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find list on view model " + "isntance for " + "remove at path " + << path; + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find view model instance " << rootHandle + << " for remove list"; + } + + break; + } + + case CommandQueue::Command::swapViewModelListValue: + { + ViewModelInstanceHandle rootHandle; + uint64_t requestId; + std::string path; + int indexa, indexb; + commandStream >> rootHandle; + commandStream >> indexa; + commandStream >> indexb; + commandStream >> requestId; + m_commandQueue->m_names >> path; + lock.unlock(); + if (auto viewModel = getViewModelInstance(rootHandle)) + { + if (auto list = viewModel->propertyList(path)) + { + list->swap(indexa, indexb); + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find list on view model " + "isntance for " + "swap at path " + << path; + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to find view model instance " << rootHandle + << " for swap"; + } + break; + } + + case CommandQueue::Command::subscribeViewModelProperty: + case CommandQueue::Command::unsubscribeViewModelProperty: + { + ViewModelInstanceHandle rootHandle; + PropertyData data; + uint64_t requestId; + commandStream >> rootHandle; + commandStream >> data.type; + commandStream >> requestId; + m_commandQueue->m_names >> data.name; + lock.unlock(); + + if (command == + CommandQueue::Command::subscribeViewModelProperty) + { + // Validate that this is a valid thing to subscribe to. + + if (auto view = getViewModelInstance(rootHandle)) + { + if (data.type != DataType::viewModel && + data.type != DataType::integer && + data.type != DataType::none && + data.type != DataType::symbolListIndex) + { + if (view->property(data.name) != nullptr) + { + m_propertySubscriptions.push_back( + {requestId, data, rootHandle}); + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "Property " << data.name + << " not found when subscribing"; + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "Property type " << data.type + << " is not valid when subscribing"; + } + } + else + { + ErrorReporter( + this, + rootHandle, + requestId, + CommandQueue::Message::viewModelError) + << "Root view model " << rootHandle + << " not found when subscribing " + "to property " + << data.name; + } + } + else + { + auto itr = std::remove_if( + m_propertySubscriptions.begin(), + m_propertySubscriptions.end(), + [data, rootHandle](const Subscription& val) { + return val.data.name == data.name && + val.data.type == data.type && + val.rootViewModel == rootHandle; + }); + + m_propertySubscriptions.erase( + itr, + m_propertySubscriptions.end()); + } + + break; + } + + case CommandQueue::Command::refNestedViewModel: + { + ViewModelInstanceHandle rootViewHandle; + ViewModelInstanceHandle nestedViewHandle; + uint64_t requestId; + std::string path; + commandStream >> rootViewHandle; + commandStream >> nestedViewHandle; + commandStream >> requestId; + m_commandQueue->m_names >> path; + lock.unlock(); + + if (auto rootViewInstance = + getViewModelInstance(rootViewHandle)) + { + if (auto nestedViewModel = + rootViewInstance->propertyViewModel(path)) + { + m_viewModels[nestedViewHandle] = nestedViewModel; + } + else + { + ErrorReporter( + this, + nestedViewHandle, + requestId, + CommandQueue::Message::viewModelError) + << "Nested view not found at path" << path + << " when refing nested " + "view model"; + } + } + else + { + ErrorReporter( + this, + nestedViewHandle, + requestId, + CommandQueue::Message::viewModelError) + << "Root view model " << rootViewHandle + << " not found when refing nested " + "view model at path " + << path; + } + break; + } + + case CommandQueue::Command::refListViewModel: + { + ViewModelInstanceHandle rootViewHandle; + ViewModelInstanceHandle listViewHandle; + int index; + uint64_t requestId; + std::string path; + commandStream >> rootViewHandle; + commandStream >> index; + commandStream >> listViewHandle; + commandStream >> requestId; + m_commandQueue->m_names >> path; + lock.unlock(); + + if (auto rootViewInstance = + getViewModelInstance(rootViewHandle)) + { + if (auto list = rootViewInstance->propertyList(path)) + { + auto viewModelInstance = list->instanceAt(index); + if (viewModelInstance) + { + m_viewModels[listViewHandle] = viewModelInstance; + } + else + { + ErrorReporter( + this, + rootViewHandle, + requestId, + CommandQueue::Message::viewModelError) + << "View model not found on list " << path + << " at index " << index; + } + } + else + { + ErrorReporter( + this, + rootViewHandle, + requestId, + CommandQueue::Message::viewModelError) + << "List not found at path " << path + << " when refing view model at index " << index; + } + } + else + { + ErrorReporter( + this, + rootViewHandle, + requestId, + CommandQueue::Message::viewModelError) + << "Root view model" << rootViewHandle + << " not found when refing nested " + "view model at path " + << path; + } + break; + } + + case CommandQueue::Command::deleteViewModel: + { + ViewModelInstanceHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + m_viewModels.erase(handle); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::viewModelDeleted; + messageStream << handle; + messageStream << requestId; + break; + } + case CommandQueue::Command::instantiateStateMachine: + { + StateMachineHandle handle; + ArtboardHandle artboardHandle; + uint64_t requestId; + std::string name; + commandStream >> handle; + commandStream >> artboardHandle; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + if (rive::ArtboardInstance* artboard = + getArtboardInstance(artboardHandle)) + { + if (auto stateMachine = + name.empty() ? artboard->defaultStateMachine() + : artboard->stateMachineNamed(name)) + { + std::unique_lock accesLock( + m_stateMachineAccessMutex); + m_stateMachines[handle] = + make_rcp( + std::move(stateMachine)); + accesLock.unlock(); + assert(m_artboardDependencies.find(artboardHandle) != + m_artboardDependencies.end()); + m_artboardDependencies[artboardHandle].push_back( + handle); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream + << CommandQueue::Message::stateMachineInstantiated; + messageStream << artboardHandle; + messageStream << handle; + messageStream << requestId; + } + else + { + ErrorReporter( + this, + artboardHandle, + requestId, + CommandQueue::Message::artboardError) + << "Could not create state " + "machine with name \"" + << name << "\" because it was not found."; + } + } + else + { + ErrorReporter( + this, + artboardHandle, + requestId, + CommandQueue::Message::artboardError) + << "Could not create state " + "machine with name \"" + << name << "\" because the owning artboard " + << artboardHandle << " was not found."; + } + break; + } + + case CommandQueue::Command::bindViewModelInstance: + { + StateMachineHandle handle; + ViewModelInstanceHandle viewModel; + uint64_t requestId; + commandStream >> handle; + commandStream >> viewModel; + commandStream >> requestId; + lock.unlock(); + + if (auto stateMachineWrapper = getStateMachineWrapper(handle)) + { + if (auto viewModelInstance = + getViewModelInstance(viewModel)) + { + std::unique_lock accesLock( + stateMachineWrapper->m_mutex); + stateMachineWrapper->instance->bindViewModelInstance( + viewModelInstance->instance()); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "View model instance " << viewModel + << " not found for when trying to bind " + "to a state machine"; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "State machine " << handle + << " not found for binding view model."; + } + break; + } + + case CommandQueue::Command::advanceStateMachine: + { + StateMachineHandle handle; + uint64_t requestId; + float timeToAdvance; + commandStream >> handle; + commandStream >> requestId; + commandStream >> timeToAdvance; + lock.unlock(); + + if (auto wrapper = getStateMachineWrapper(handle)) + { + std::unique_lock advanceLock(wrapper->m_mutex); + if (!wrapper->instance->advanceAndApply(timeToAdvance)) + { + advanceLock.unlock(); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream + << CommandQueue::Message::stateMachineSettled; + messageStream << handle; + messageStream << requestId; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "State machine " << handle + << " not found for " + "advance."; + } + + break; + } + + case CommandQueue::Command::deleteStateMachine: + { + StateMachineHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + auto it = m_stateMachines.find(handle); + if (it != m_stateMachines.end()) + { + std::unique_lock accesLock( + m_stateMachineAccessMutex); + m_stateMachines.erase(it); + accesLock.unlock(); + } + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::stateMachineDeleted; + messageStream << handle; + messageStream << requestId; + // We don't remove from the artboard dependencies here because + // calling erase on a non existent key is fine. + break; + } + + case CommandQueue::Command::runOnce: + { + CommandServerCallback callback; + m_commandQueue->m_callbacks >> callback; + lock.unlock(); + callback(this); + break; + } + + case CommandQueue::Command::draw: + { + DrawKey drawKey; + CommandServerDrawCallback drawCallback; + commandStream >> drawKey; + m_commandQueue->m_drawCallbacks >> drawCallback; + lock.unlock(); + m_uniqueDraws[drawKey] = std::move(drawCallback); + break; + } + + case CommandQueue::Command::cancelDraw: + { + DrawKey drawKey; + commandStream >> drawKey; + lock.unlock(); + m_uniqueDraws.erase(drawKey); + break; + } + + case CommandQueue::Command::commandLoopBreak: + { + lock.unlock(); + shouldProcessCommands = false; + break; + } + + case CommandQueue::Command::listArtboards: + { + FileHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + auto file = getFile(handle); + if (file) + { + auto artboards = file->artboards(); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::artboardsListed; + messageStream << handle; + messageStream << requestId; + messageStream << artboards.size(); + for (auto artboard : artboards) + { + m_commandQueue->m_messageNames << artboard->name(); + } + } + else + { + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fileError) + << "Invalid file handle " << handle + << " when getting list of artboards"; + } + + break; + } + + case CommandQueue::Command::getViewModelInstanceViewModelName: + { + ViewModelInstanceHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + auto viewModelInstance = getViewModelInstance(handle); + if (viewModelInstance) + { + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message:: + viewModelInstanceViewModelNameReceived; + messageStream << handle; + messageStream << requestId; + m_commandQueue->m_messageNames + << viewModelInstance->viewModelName(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Invalid view model instance handle " << handle; + } + break; + } + + case CommandQueue::Command::listViewModelEnums: + { + FileHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + auto file = getFile(handle); + if (file) + { + auto enums = file->enums(); + std::vector enumDatas; + + for (auto tenum : enums) + { + ViewModelEnum data; + data.name = tenum->enumName(); + auto values = tenum->values(); + for (auto value : values) + { + data.enumerants.push_back(value->key()); + } + + enumDatas.push_back(data); + } + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream + << CommandQueue::Message::viewModelEnumsListed; + messageStream << handle; + messageStream << requestId; + messageStream << enumDatas.size(); + for (auto& enumData : enumDatas) + { + m_commandQueue->m_messageNames << enumData.name; + messageStream << enumData.enumerants.size(); + for (auto& enumValueName : enumData.enumerants) + m_commandQueue->m_messageNames << enumValueName; + } + } + else + { + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fileError) + << "Invalid file handle " << handle + << " when getting list of enums"; + } + break; + } + + case CommandQueue::Command::listStateMachines: + { + ArtboardHandle handle; + uint64_t requestId; + commandStream >> handle; + commandStream >> requestId; + lock.unlock(); + auto artboard = getArtboardInstance(handle); + if (artboard) + { + auto numStateMachines = artboard->stateMachineCount(); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::stateMachinesListed; + messageStream << handle; + messageStream << requestId; + messageStream << numStateMachines; + for (int i = 0; i < numStateMachines; ++i) + { + m_commandQueue->m_messageNames + << artboard->stateMachineNameAt(i); + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::artboardError) + << "Invalid artboard handle " << handle + << " when getting list of state machines"; + } break; } - case CommandQueue::Command::instantiateArtboard: + case CommandQueue::Command::getDefaultViewModel: { - ArtboardHandle handle; FileHandle fileHandle; + ArtboardHandle artboardHandle; uint64_t requestId; - std::string name; - commandStream >> handle; commandStream >> fileHandle; + commandStream >> artboardHandle; commandStream >> requestId; - m_commandQueue->m_names >> name; lock.unlock(); - if (rive::File* file = getFile(fileHandle)) + auto artboard = getArtboardInstance(artboardHandle); + if (artboard) { - if (auto artboard = name.empty() - ? file->artboardDefault() - : file->artboardNamed(name)) + auto file = getFile(fileHandle); + if (file) { - m_artboards[handle] = std::move(artboard); + auto defaultViewModel = + file->defaultArtboardViewModel(artboard); + + if (defaultViewModel) + { + auto defaultInstance = + defaultViewModel->createDefaultInstance(); + if (defaultInstance) + { + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message:: + defaultViewModelReceived; + messageStream << artboardHandle; + messageStream << requestId; + m_commandQueue->m_messageNames + << defaultViewModel->name(); + m_commandQueue->m_messageNames + << defaultInstance->name(); + } + else + { + ErrorReporter( + this, + artboardHandle, + requestId, + CommandQueue::Message::artboardError) + << "Could not find default view model " + "instance for " + "artboard" + << " when getting default view model info"; + } + } + else + { + ErrorReporter( + this, + artboardHandle, + requestId, + CommandQueue::Message::artboardError) + << "Could not find default view model for " + "artboard" + << " when getting default view model info"; + } } else { - fprintf(stderr, - "ERROR: artboard \"%s\" not found.\n", - name.c_str()); + ErrorReporter( + this, + artboardHandle, + requestId, + CommandQueue::Message::artboardError) + << "Invalid file handle " << fileHandle + << " when getting default view model info"; } } + else + { + ErrorReporter( + this, + artboardHandle, + requestId, + CommandQueue::Message::artboardError) + << "Invalid artboard handle " << artboardHandle + << " when getting default view model info"; + } break; } - case CommandQueue::Command::deleteArtboard: + case CommandQueue::Command::listViewModels: { - ArtboardHandle handle; + FileHandle handle; uint64_t requestId; commandStream >> handle; commandStream >> requestId; lock.unlock(); - m_artboards.erase(handle); - std::unique_lock messageLock( - m_commandQueue->m_messageMutex); - m_commandQueue->m_messageStream - << CommandQueue::Message::artboardDeleted; - m_commandQueue->m_messageStream << handle; - m_commandQueue->m_messageStream << requestId; + auto file = getFile(handle); + if (file) + { + auto numViewModels = file->viewModelCount(); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message::viewModelsListend; + messageStream << handle; + messageStream << requestId; + messageStream << numViewModels; + for (int i = 0; i < numViewModels; ++i) + { + m_commandQueue->m_messageNames + << file->viewModelByIndex(i)->name(); + } + } + else + { + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fileError) + << "Invalid file handle " << handle + << " when getting list of view models"; + } break; } - case CommandQueue::Command::instantiateStateMachine: + case CommandQueue::Command::listViewModelInstanceNames: { - StateMachineHandle handle; - ArtboardHandle artboardHandle; + FileHandle handle; uint64_t requestId; - std::string name; + std::string viewModelName; commandStream >> handle; - commandStream >> artboardHandle; commandStream >> requestId; - m_commandQueue->m_names >> name; + m_commandQueue->m_names >> viewModelName; lock.unlock(); - if (rive::ArtboardInstance* artboard = - getArtboardInstance(artboardHandle)) + auto file = getFile(handle); + if (file) { - if (auto stateMachine = - name.empty() ? artboard->defaultStateMachine() - : artboard->stateMachineNamed(name)) + auto model = file->viewModelByName(viewModelName); + if (model) { - m_stateMachines[handle] = std::move(stateMachine); + auto names = model->instanceNames(); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message:: + viewModelInstanceNamesListed; + messageStream << handle; + messageStream << requestId; + messageStream << names.size(); + m_commandQueue->m_messageNames << viewModelName; + for (auto& name : names) + { + m_commandQueue->m_messageNames << name; + } } else { - fprintf(stderr, - "ERROR: Could not create state machine with " - "name \"%s\" because it was not found.\n", - name.c_str()); + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Invalid view model name " << viewModelName + << " when getting list of view model instance " + "names"; } } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Invalid file handle " << handle + << " when getting list of view model instance names"; + } break; } - case CommandQueue::Command::advanceStateMachine: + case CommandQueue::Command::listViewModelProperties: { - StateMachineHandle handle; + FileHandle handle; uint64_t requestId; - float timeToAdvance; + std::string viewModelName; commandStream >> handle; commandStream >> requestId; - commandStream >> timeToAdvance; + m_commandQueue->m_names >> viewModelName; lock.unlock(); - - if (auto stateMachine = getStateMachineInstance(handle)) + auto file = getFile(handle); + if (file) { - if (!stateMachine->advanceAndApply(timeToAdvance)) + auto model = file->viewModelByName(viewModelName); + if (model) { + // Used to get meta data about enums. + auto modelInstance = model->createDefaultInstance(); + auto properties = model->properties(); + std::unique_lock messageLock( m_commandQueue->m_messageMutex); - m_commandQueue->m_messageStream - << CommandQueue::Message::stateMachineSettled; - m_commandQueue->m_messageStream << handle; - m_commandQueue->m_messageStream << requestId; + messageStream + << CommandQueue::Message::viewModelPropertiesListed; + messageStream << handle; + messageStream << requestId; + messageStream << properties.size(); + m_commandQueue->m_messageNames << viewModelName; + for (auto& property : properties) + { + messageStream << property.type; + m_commandQueue->m_messageNames << property.name; + if (property.type == DataType::enumType) + { + auto enumProperty = + modelInstance->propertyEnum(property.name); + m_commandQueue->m_messageNames + << enumProperty->enumType(); + } + if (property.type == DataType::viewModel) + { + // Get the type of the view model property + auto viewModelTmp = + modelInstance->propertyViewModel( + property.name); + if (viewModelTmp) + { + m_commandQueue->m_messageNames + << viewModelTmp->instance() + ->viewModel() + ->name(); + } + else + { + // If we can't determine the name we still + // need to send something because the + // command queue is expecting a name. + m_commandQueue->m_messageNames << "Unkown"; + } + } + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::fileError) + << "Invalid view model name " << viewModelName + << " when getting list of view model properties"; } } else { - fprintf(stderr, - "ERROR: State machine \"%llu\" not found for " - "advance.\n", - reinterpret_cast(handle)); + ErrorReporter(this, + handle, + requestId, + CommandQueue::Message::fileError) + << "Invalid file handle " << handle + << " when getting list of view model properties"; } - break; } - case CommandQueue::Command::deleteStateMachine: + case CommandQueue::Command::setViewModelInstanceValue: { - StateMachineHandle handle; + ViewModelInstanceHandle handle = RIVE_NULL_HANDLE; + ViewModelInstanceHandle nestedHandle = RIVE_NULL_HANDLE; + RenderImageHandle imageHandle = RIVE_NULL_HANDLE; + ArtboardHandle artboadHandle = RIVE_NULL_HANDLE; uint64_t requestId; + CommandQueue::ViewModelInstanceData value; + commandStream >> handle; + commandStream >> value.metaData.type; commandStream >> requestId; - lock.unlock(); - m_stateMachines.erase(handle); - std::unique_lock messageLock( - m_commandQueue->m_messageMutex); - m_commandQueue->m_messageStream - << CommandQueue::Message::stateMachineDeleted; - m_commandQueue->m_messageStream << handle; - m_commandQueue->m_messageStream << requestId; - break; - } + m_commandQueue->m_names >> value.metaData.name; - case CommandQueue::Command::runOnce: - { - CommandServerCallback callback; - m_commandQueue->m_callbacks >> callback; + switch (value.metaData.type) + { + // Triggers are valid but have no data. + case DataType::trigger: + break; + case DataType::boolean: + commandStream >> value.boolValue; + break; + case DataType::number: + commandStream >> value.numberValue; + break; + case DataType::color: + commandStream >> value.colorValue; + break; + case DataType::string: + case DataType::enumType: + m_commandQueue->m_names >> value.stringValue; + break; + case DataType::viewModel: + commandStream >> nestedHandle; + break; + case DataType::assetImage: + commandStream >> imageHandle; + break; + case DataType::artboard: + commandStream >> artboadHandle; + break; + default: + RIVE_UNREACHABLE(); + } lock.unlock(); - callback(this); - break; - } - case CommandQueue::Command::draw: - { - DrawKey drawKey; - CommandServerDrawCallback drawCallback; - commandStream >> drawKey; - m_commandQueue->m_drawCallbacks >> drawCallback; - lock.unlock(); - m_uniqueDraws[drawKey] = std::move(drawCallback); + if (auto viewModelInstance = getViewModelInstance(handle)) + { + switch (value.metaData.type) + { + case DataType::trigger: + { + if (auto property = + viewModelInstance->propertyTrigger( + value.metaData.name)) + { + property->trigger(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::boolean: + { + if (auto property = + viewModelInstance->propertyBoolean( + value.metaData.name)) + { + property->value(value.boolValue); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::number: + { + if (auto property = + viewModelInstance->propertyNumber( + value.metaData.name)) + { + property->value(value.numberValue); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::color: + { + if (auto property = + viewModelInstance->propertyColor( + value.metaData.name)) + { + property->value(value.colorValue); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::string: + { + if (auto property = + viewModelInstance->propertyString( + value.metaData.name)) + { + property->value(value.stringValue); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::enumType: + { + if (auto property = viewModelInstance->propertyEnum( + value.metaData.name)) + { + // As far as I can tell, there is no built in + // way to do this from the core runtime. So we + // just verify manually ourselves. + auto values = property->values(); + if (std::find(values.begin(), + values.end(), + value.stringValue) != + values.end()) + { + property->value(value.stringValue); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Invalid enum value for " + "property " + << value.metaData.name + << " when trying to set enum to " + << value.stringValue + << " possible values " << values; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::viewModel: + { + if (auto nestedViewModel = + getViewModelInstance(nestedHandle)) + { + if (!viewModelInstance->replaceViewModel( + value.metaData.name, + nestedViewModel)) + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not replace " + "view model at path " + << value.metaData.name; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find nested view " + "model " + "with handle " + << nestedHandle + << " to set for view model instance when " + "setting property with path " + << value.metaData.name; + } + break; + } + case DataType::assetImage: + { + if (auto image = getImage(imageHandle)) + { + if (auto imageProperty = + viewModelInstance->propertyImage( + value.metaData.name)) + { + imageProperty->value(image); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find " + "image property at path " + << value.metaData.name; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find image " << imageHandle + << " to set for view model instance when " + "setting property with path " + << value.metaData.name; + } + break; + } + case DataType::artboard: + { + if (auto bindableArtboard = + getBindableArtboard(artboadHandle)) + { + if (auto artboardProperty = + viewModelInstance->propertyArtboard( + value.metaData.name)) + { + artboardProperty->value(bindableArtboard); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find " + "artboard property at path " + << value.metaData.name; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find artboard " + << artboadHandle + << " to set for view model instance when " + "setting property with path " + << value.metaData.name; + } + break; + } + default: + RIVE_UNREACHABLE(); + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model instance when " + "setting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } break; } - case CommandQueue::Command::commandLoopBreak: + case CommandQueue::Command::listViewModelPropertyValue: { + ViewModelInstanceHandle handle; + uint64_t requestId; + CommandQueue::ViewModelInstanceData value; + commandStream >> value.metaData.type; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_names >> value.metaData.name; lock.unlock(); - shouldProcessCommands = false; + + if (auto viewModelInstance = getViewModelInstance(handle)) + { + switch (value.metaData.type) + { + case DataType::boolean: + { + if (auto property = + viewModelInstance->propertyBoolean( + value.metaData.name)) + { + value.boolValue = property->value(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when getting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::number: + { + if (auto property = + viewModelInstance->propertyNumber( + value.metaData.name)) + { + value.numberValue = property->value(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when getting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::color: + { + if (auto property = + viewModelInstance->propertyColor( + value.metaData.name)) + { + value.colorValue = property->value(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when getting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::string: + { + if (auto property = + viewModelInstance->propertyString( + value.metaData.name)) + { + value.stringValue = property->value(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when getting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + case DataType::enumType: + { + if (auto property = viewModelInstance->propertyEnum( + value.metaData.name)) + { + value.stringValue = property->value(); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model " + "property " + "instance when getting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } + break; + } + default: + RIVE_UNREACHABLE(); + } + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream << CommandQueue::Message:: + viewModelPropertyValueReceived; + messageStream << handle; + messageStream << value.metaData.type; + m_commandQueue->m_messageNames << value.metaData.name; + messageStream << requestId; + switch (value.metaData.type) + { + case DataType::boolean: + messageStream << value.boolValue; + break; + case DataType::number: + messageStream << value.numberValue; + break; + case DataType::color: + messageStream << value.colorValue; + break; + case DataType::enumType: + case DataType::string: + m_commandQueue->m_messageNames << value.stringValue; + break; + default: + RIVE_UNREACHABLE(); + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "Could not find view model instance when " + "getting property type " + << value.metaData.type << " with path " + << value.metaData.name; + } break; } - case CommandQueue::Command::listArtboards: + case CommandQueue::Command::getViewModelListSize: { - FileHandle handle; + ViewModelInstanceHandle handle; uint64_t requestId; + std::string path; commandStream >> handle; commandStream >> requestId; + m_commandQueue->m_names >> path; lock.unlock(); - auto file = getFile(handle); - if (file) - { - auto artboards = file->artboards(); - std::unique_lock messageLock( - m_commandQueue->m_messageMutex); - m_commandQueue->m_messageStream - << CommandQueue::Message::artboardsListed; - m_commandQueue->m_messageStream << handle; - m_commandQueue->m_messageStream << requestId; - m_commandQueue->m_messageStream << artboards.size(); - for (auto artboard : artboards) + if (auto viewModel = getViewModelInstance(handle)) + { + if (auto property = viewModel->propertyList(path)) { - m_commandQueue->m_messageNames << artboard->name(); + auto size = property->size(); + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream + << CommandQueue::Message::viewModelListSizeReceived; + messageStream << handle; + messageStream << size; + messageStream << requestId; + m_commandQueue->m_messageNames << path; + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to get list at path " << path + << " when getting list size"; } } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to get view model " << handle + << " when getting list size"; + } break; } - case CommandQueue::Command::listStateMachines: + case CommandQueue::Command::clearViewModelList: { - ArtboardHandle handle; + ViewModelInstanceHandle handle; uint64_t requestId; + std::string path; commandStream >> handle; commandStream >> requestId; + m_commandQueue->m_names >> path; lock.unlock(); - auto artboard = getArtboardInstance(handle); - if (artboard) + + if (auto viewModel = getViewModelInstance(handle)) { - auto numStateMachines = artboard->stateMachineCount(); - std::unique_lock messageLock( - m_commandQueue->m_messageMutex); - m_commandQueue->m_messageStream - << CommandQueue::Message::stateMachinesListed; - m_commandQueue->m_messageStream << handle; - m_commandQueue->m_messageStream << requestId; - m_commandQueue->m_messageStream << numStateMachines; - for (int i = 0; i < numStateMachines; ++i) + if (auto property = viewModel->propertyList(path)) { - m_commandQueue->m_messageNames - << artboard->stateMachineNameAt(i); + property->removeAllInstances(); + + std::unique_lock messageLock( + m_commandQueue->m_messageMutex); + messageStream + << CommandQueue::Message::viewModelListCleared; + messageStream << handle; + messageStream << requestId; + m_commandQueue->m_messageNames << path; + messageLock.unlock(); } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to get list at path " << path + << " when clearing list"; + } + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::viewModelError) + << "failed to get view model " << handle + << " when clearing list"; } break; } @@ -347,20 +2849,33 @@ bool CommandServer::processCommands() case CommandQueue::Command::pointerMove: { StateMachineHandle handle; - Vec2D position; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; commandStream >> handle; - commandStream >> position; + commandStream >> requestId; + m_commandQueue->m_pointerEvents >> pointerEvent; lock.unlock(); - if (auto stateMachine = getStateMachineInstance(handle)) + if (auto stateMachineWrapper = getStateMachineWrapper(handle)) { - stateMachine->pointerMove(position); + Vec2D position = cursorPosForPointerEvent( + stateMachineWrapper->instance.get(), + pointerEvent); + std::unique_lock stateMachineLock( + stateMachineWrapper->m_mutex); + stateMachineWrapper->instance->pointerMove( + position, + 0.0f, + pointerEvent.pointerId); } else { - fprintf(stderr, - "ERROR: State machine \"%llu\" not found for " - "pointerMove.\n", - reinterpret_cast(handle)); + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "State machine \"" << handle + << "\" not found for pointerMove."; } break; } @@ -368,19 +2883,32 @@ bool CommandServer::processCommands() case CommandQueue::Command::pointerDown: { StateMachineHandle handle; - Vec2D position; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; commandStream >> handle; - commandStream >> position; + commandStream >> requestId; + m_commandQueue->m_pointerEvents >> pointerEvent; lock.unlock(); - if (auto stateMachine = getStateMachineInstance(handle)) + if (auto stateMachineWrapper = getStateMachineWrapper(handle)) { - stateMachine->pointerDown(position); + Vec2D position = cursorPosForPointerEvent( + stateMachineWrapper->instance.get(), + pointerEvent); + std::unique_lock stateMachineLock( + stateMachineWrapper->m_mutex); + stateMachineWrapper->instance->pointerDown( + position, + pointerEvent.pointerId); } + else { - fprintf(stderr, - "ERROR: State machine \"%llu\" not found for " - "pointerDown.\n", - reinterpret_cast(handle)); + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "State machine \"" << handle + << "\" not found for pointerDown."; } break; } @@ -388,19 +2916,32 @@ bool CommandServer::processCommands() case CommandQueue::Command::pointerUp: { StateMachineHandle handle; - Vec2D position; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; commandStream >> handle; - commandStream >> position; + commandStream >> requestId; + m_commandQueue->m_pointerEvents >> pointerEvent; lock.unlock(); - if (auto stateMachine = getStateMachineInstance(handle)) + if (auto stateMachineWrapper = getStateMachineWrapper(handle)) { - stateMachine->pointerUp(position); + Vec2D position = cursorPosForPointerEvent( + stateMachineWrapper->instance.get(), + pointerEvent); + std::unique_lock stateMachineLock( + stateMachineWrapper->m_mutex); + stateMachineWrapper->instance->pointerUp( + position, + pointerEvent.pointerId); } + else { - fprintf(stderr, - "ERROR: State machine \"%llu\" not found for " - "pointerUp.\n", - reinterpret_cast(handle)); + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "State machine \"" << handle + << "\" not found for pointerUp."; } break; } @@ -408,23 +2949,123 @@ bool CommandServer::processCommands() case CommandQueue::Command::pointerExit: { StateMachineHandle handle; - Vec2D position; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_pointerEvents >> pointerEvent; + lock.unlock(); + if (auto stateMachineWrapper = getStateMachineWrapper(handle)) + { + Vec2D position = cursorPosForPointerEvent( + stateMachineWrapper->instance.get(), + pointerEvent); + std::unique_lock stateMachineLock( + stateMachineWrapper->m_mutex); + stateMachineWrapper->instance->pointerExit( + position, + pointerEvent.pointerId); + } + else + { + ErrorReporter( + this, + handle, + requestId, + CommandQueue::Message::stateMachineError) + << "State machine \"" << handle + << "\" not found for pointerExit."; + } + break; + } + + case CommandQueue::Command::addImageFileAsset: + { + RenderImageHandle handle; + std::string name; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + if (handle && getImage(handle) != nullptr) + { + m_fileAssetLoader->addRenderImage(std::move(name), handle); + } + break; + } + + case CommandQueue::Command::removeImageFileAsset: + { + std::string name; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + m_fileAssetLoader->removeRenderImage(std::move(name)); + break; + } + + case CommandQueue::Command::addAudioFileAsset: + { + AudioSourceHandle handle; + std::string name; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; commandStream >> handle; - commandStream >> position; + commandStream >> requestId; + m_commandQueue->m_names >> name; lock.unlock(); - if (auto stateMachine = getStateMachineInstance(handle)) + if (handle && getAudioSource(handle) != nullptr) { - stateMachine->pointerExit(position); + m_fileAssetLoader->addAudioSource(std::move(name), handle); } + break; + } + + case CommandQueue::Command::removeAudioFileAsset: + { + std::string name; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + m_fileAssetLoader->removeAudioSource(std::move(name)); + break; + } + + case CommandQueue::Command::addFontFileAsset: + { + FontHandle handle; + std::string name; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; + commandStream >> handle; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + if (handle && getFont(handle) != nullptr) { - fprintf(stderr, - "ERROR: State machine \"%llu\" not found for " - "pointerExit.\n", - reinterpret_cast(handle)); + m_fileAssetLoader->addFont(std::move(name), handle); } break; } + case CommandQueue::Command::removeFontFileAsset: + { + std::string name; + uint64_t requestId; + CommandQueue::PointerEvent pointerEvent; + commandStream >> requestId; + m_commandQueue->m_names >> name; + lock.unlock(); + m_fileAssetLoader->removeFont(std::move(name)); + break; + } + case CommandQueue::Command::disconnect: { lock.unlock(); @@ -438,6 +3079,10 @@ bool CommandServer::processCommands() lock.lock(); } while (!commandStream.empty() && shouldProcessCommands); + // Since we always retake the lock at the end of the do while we need to + // unlock here. + lock.unlock(); + for (const auto& drawPair : m_uniqueDraws) { drawPair.second(drawPair.first, this); @@ -445,6 +3090,13 @@ bool CommandServer::processCommands() m_uniqueDraws.clear(); + checkPropertySubscriptions(); + return !m_wasDisconnectReceived; } +CommandServer::SynchronizedStateMachine::~SynchronizedStateMachine() +{ + std::unique_lock lock(m_mutex); + instance->dispose(); +} }; // namespace rive diff --git a/thirdparty/rive/source/component.cpp b/thirdparty/rive/source/component.cpp index e7dd01e6d..bc3c2a75d 100644 --- a/thirdparty/rive/source/component.cpp +++ b/thirdparty/rive/source/component.cpp @@ -5,6 +5,7 @@ #include "rive/importers/artboard_importer.hpp" #include "rive/importers/import_stack.hpp" #include "rive/layout_component.hpp" +#include "rive/data_bind/data_bind.hpp" #include using namespace rive; @@ -80,7 +81,8 @@ StatusCode Component::import(ImportStack& importStack) bool Component::collapse(bool value) { - if (isCollapsed() == value) + if (((m_Dirt & ComponentDirt::Collapsed) == ComponentDirt::Collapsed) == + value) { return false; } @@ -94,5 +96,37 @@ bool Component::collapse(bool value) } onDirty(m_Dirt); m_DependencyHelper.onComponentDirty(this); + updateCollapsables(); return true; +} + +bool Component::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + if (parent()) + { + return parent()->hitTestPoint(position, skipOnUnclipped, false); + } + return true; +} + +void Component::addCollapsable(DataBind* collapsable) +{ + auto itr = + std::find(m_collapsables.begin(), m_collapsables.end(), collapsable); + if (itr == m_collapsables.end()) + { + m_collapsables.push_back(collapsable); + collapsable->collapse(isCollapsed()); + } +} + +void Component::updateCollapsables() +{ + auto collapsed = isCollapsed(); + for (auto& collapsable : m_collapsables) + { + collapsable->collapse(collapsed); + } } \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/constrainable_list.cpp b/thirdparty/rive/source/constraints/constrainable_list.cpp new file mode 100644 index 000000000..04d46bea5 --- /dev/null +++ b/thirdparty/rive/source/constraints/constrainable_list.cpp @@ -0,0 +1,24 @@ +#include "rive/artboard_component_list.hpp" +#include "rive/component.hpp" +#include "rive/constraints/list_constraint.hpp" +#include "rive/constraints/constrainable_list.hpp" + +using namespace rive; + +ConstrainableList* ConstrainableList::from(Component* component) +{ + switch (component->coreType()) + { + case ArtboardComponentListBase::typeKey: + return component->as(); + } + return nullptr; +} + +void ConstrainableList::addListConstraint(ListConstraint* constraint) +{ + assert(std::find(m_listConstraints.begin(), + m_listConstraints.end(), + constraint) == m_listConstraints.end()); + m_listConstraints.push_back(constraint); +} \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/constraint.cpp b/thirdparty/rive/source/constraints/constraint.cpp index 7da213cc0..b3b9f9ed1 100644 --- a/thirdparty/rive/source/constraints/constraint.cpp +++ b/thirdparty/rive/source/constraints/constraint.cpp @@ -6,8 +6,9 @@ using namespace rive; -StatusCode Constraint::onAddedClean(CoreContext* context) +StatusCode Constraint::onAddedDirty(CoreContext* context) { + StatusCode result = Super::onAddedDirty(context); if (!parent()->is()) { return StatusCode::InvalidObject; @@ -15,7 +16,7 @@ StatusCode Constraint::onAddedClean(CoreContext* context) parent()->as()->addConstraint(this); - return StatusCode::Ok; + return result; } void Constraint::markConstraintDirty() diff --git a/thirdparty/rive/source/constraints/draggable_constraint.cpp b/thirdparty/rive/source/constraints/draggable_constraint.cpp new file mode 100644 index 000000000..cc4a1f27b --- /dev/null +++ b/thirdparty/rive/source/constraints/draggable_constraint.cpp @@ -0,0 +1,86 @@ +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/state_machine_listener_single.hpp" +#include "rive/component.hpp" +#include "rive/constraints/draggable_constraint.hpp" + +using namespace rive; + +std::vector DraggableConstraint::listenerGroups() +{ + std::vector result; + for (auto dragProxy : draggables()) + { + auto listener = new StateMachineListenerSingle(); + listener->listenerTypeValue( + static_cast(ListenerType::componentProvided)); + auto* listenerGroup = + new DraggableConstraintListenerGroup(listener, this, dragProxy); + auto hittable = dragProxy->hittable(); + if (hittable != nullptr && hittable->is()) + { + auto* target = + new HitTarget(hittable->as(), dragProxy->isOpaque()); + auto* groupWithTargets = + new ListenerGroupWithTargets(listenerGroup, + std::vector{target}); + result.push_back(groupWithTargets); + } + } + return result; +} + +ProcessEventResult DraggableConstraintListenerGroup::processEvent( + Component* component, + Vec2D position, + int pointerId, + ListenerType hitEvent, + bool canHit, + float timeStamp, + StateMachineInstance* stateMachineInstance) +{ + auto pointer = pointerData(pointerId); + auto prevPhase = pointer->phase; + ListenerGroup::processEvent(component, + position, + pointerId, + hitEvent, + canHit, + timeStamp, + stateMachineInstance); + if (prevPhase == GestureClickPhase::down && + (pointer->phase == GestureClickPhase::clicked || + pointer->phase == GestureClickPhase::out)) + { + m_draggable->endDrag(position, timeStamp); + if (m_hasScrolled) + { + stateMachineInstance->dragEnd(position, timeStamp, pointerId); + m_hasScrolled = false; + return ProcessEventResult::scroll; + } + } + else if (prevPhase != GestureClickPhase::down && + pointer->phase == GestureClickPhase::down) + { + m_draggable->startDrag(position, timeStamp); + m_hasScrolled = false; + } + else if (hitEvent == ListenerType::move && + pointer->phase == GestureClickPhase::down) + { + auto hasDragged = m_draggable->drag(position, timeStamp); + if (hasDragged) + { + if (!m_hasScrolled) + { + stateMachineInstance->dragStart(position, + timeStamp, + false, + pointerId); + } + m_hasScrolled = true; + return ProcessEventResult::scroll; + } + } + return ProcessEventResult::none; +} \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/follow_path_constraint.cpp b/thirdparty/rive/source/constraints/follow_path_constraint.cpp index ac6334d95..38ef49849 100644 --- a/thirdparty/rive/source/constraints/follow_path_constraint.cpp +++ b/thirdparty/rive/source/constraints/follow_path_constraint.cpp @@ -1,5 +1,6 @@ #include "rive/artboard.hpp" #include "rive/command_path.hpp" +#include "rive/constraints/constrainable_list.hpp" #include "rive/constraints/follow_path_constraint.hpp" #include "rive/factory.hpp" #include "rive/math/contour_measure.hpp" @@ -17,18 +18,29 @@ using namespace rive; void FollowPathConstraint::distanceChanged() { markConstraintDirty(); } void FollowPathConstraint::orientChanged() { markConstraintDirty(); } -const Mat2D FollowPathConstraint::targetTransform() const +const Mat2D FollowPathConstraint::targetTransform(float distanceOffset) const { if (m_Target->is() || m_Target->is()) { - auto result = m_pathMeasure.atPercentage(distance()); + auto result = m_pathMeasure.atPercentage(distanceOffset); Vec2D position = result.pos; Mat2D transformB = Mat2D(m_Target->worldTransform()); if (orient()) { - transformB = - Mat2D::fromRotation(std::atan2(result.tan.y, result.tan.x)); + auto componentsB = transformB.decompose(); + auto tangentRotation = std::atan2(result.tan.y, result.tan.x); + float angleB = std::fmod(componentsB.rotation(), math::PI * 2); + float diff = tangentRotation - angleB; + if (diff > math::PI) + { + diff -= math::PI * 2; + } + else if (diff < -math::PI) + { + diff += math::PI * 2; + } + transformB = Mat2D::fromRotation(angleB + diff * strength()); } Vec2D offsetPosition = Vec2D(); if (offset()) @@ -57,8 +69,20 @@ void FollowPathConstraint::constrain(TransformComponent* component) { return; } - const Mat2D& transformA = component->worldTransform(); - Mat2D transformB(targetTransform()); + Mat2D transformB(targetTransform(distance())); + const Mat2D& targetParentWorld = getParentWorld(*component); + auto transformComponents = constrainHelper(component->worldTransform(), + transformB, + targetParentWorld); + component->mutableWorldTransform() = Mat2D::compose(transformComponents); +} + +TransformComponents FollowPathConstraint::constrainHelper( + const Mat2D& componentTransform, + Mat2D& transformB, + const Mat2D& componentParentWorld) +{ + const Mat2D& transformA = componentTransform; if (sourceSpace() == TransformSpace::local) { const Mat2D& targetParentWorld = getParentWorld(*m_Target); @@ -66,34 +90,33 @@ void FollowPathConstraint::constrain(TransformComponent* component) Mat2D inverse; if (!targetParentWorld.invert(&inverse)) { - return; + TransformComponents result; + return result; } transformB = inverse * transformB; } if (destSpace() == TransformSpace::local) { - const Mat2D& targetParentWorld = getParentWorld(*component); - transformB = targetParentWorld * transformB; + transformB = componentParentWorld * transformB; } - m_ComponentsA = transformA.decompose(); - m_ComponentsB = transformB.decompose(); + auto componentsA = transformA.decompose(); + auto componentsB = transformB.decompose(); float t = strength(); float ti = 1.0f - t; if (!orient()) { - float angleA = std::fmod(m_ComponentsA.rotation(), math::PI * 2); - m_ComponentsB.rotation(angleA); + float angleA = std::fmod(componentsA.rotation(), math::PI * 2); + componentsB.rotation(angleA); } - m_ComponentsB.x(m_ComponentsA.x() * ti + m_ComponentsB.x() * t); - m_ComponentsB.y(m_ComponentsA.y() * ti + m_ComponentsB.y() * t); - m_ComponentsB.scaleX(m_ComponentsA.scaleX()); - m_ComponentsB.scaleY(m_ComponentsA.scaleY()); - m_ComponentsB.skew(m_ComponentsA.skew()); - - component->mutableWorldTransform() = Mat2D::compose(m_ComponentsB); + componentsB.x(componentsA.x() * ti + componentsB.x() * t); + componentsB.y(componentsA.y() * ti + componentsB.y() * t); + componentsB.scaleX(componentsA.scaleX()); + componentsB.scaleY(componentsA.scaleY()); + componentsB.skew(componentsA.skew()); + return componentsB; } void FollowPathConstraint::update(ComponentDirt value) @@ -143,23 +166,25 @@ StatusCode FollowPathConstraint::onAddedClean(CoreContext* context) void FollowPathConstraint::buildDependencies() { - - if (m_Target != nullptr && - m_Target->is()) // which should never happen + if (m_Target != nullptr && m_Target->is()) { - // Follow path should update after the target's path composer + // Follow path should update after the target's path composer. Shape* shape = static_cast(m_Target); shape->pathComposer()->addDependent(this); } - // ok this appears to be enough to get the inital layout & animations to be - // working. - else if (m_Target != nullptr && - m_Target->is()) // which should never happen + else if (m_Target != nullptr && m_Target->is()) { - // or do we need to be dependent on the shape still??? Path* path = static_cast(m_Target); - path->addDependent(this); + Shape* shape = path->shape(); + if (shape != nullptr) + { + shape->pathComposer()->addDependent(this); + } + else + { + path->addDependent(this); + } } - // The constrained component should update after follow path + // The constrained component should update after follow path. addDependent(parent()); } diff --git a/thirdparty/rive/source/constraints/ik_constraint.cpp b/thirdparty/rive/source/constraints/ik_constraint.cpp index 1727066dc..666f1c16e 100644 --- a/thirdparty/rive/source/constraints/ik_constraint.cpp +++ b/thirdparty/rive/source/constraints/ik_constraint.cpp @@ -1,6 +1,5 @@ #include "rive/constraints/ik_constraint.hpp" #include "rive/bones/bone.hpp" -#include "rive/artboard.hpp" #include "rive/math/math_types.hpp" #include @@ -52,32 +51,23 @@ StatusCode IKConstraint::onAddedClean(CoreContext* context) link.angle = 0.0f; } - // Make sure all of the first level children of each bone depend on the - // tip (constrainedComponent). + // Make sure all of the first level children of each bone (other than the + // chain bones themselves) depend on the tip (constrainedComponent). The + // chain is built by walking up parents, so the only chain bone that can + // appear among an ancestor's direct children is the next bone down the + // chain — bones[i - 1]. auto tip = parent()->as(); - - auto artboard = static_cast(context); - - // Find all children of this bone (we don't directly build up - // hierarchy at runtime, so we have to traverse everything and check - // parents). - for (auto core : artboard->objects()) + for (int i = 1; i < numBones; i++) { - if (core == nullptr || !core->is()) - { - continue; - } - auto transformComponent = core->as(); - - for (int i = 1; i < numBones; i++) + Bone* ancestor = bones[i]; + Bone* chainChild = bones[i - 1]; + for (Component* child : ancestor->children()) { - auto childBone = bones[i]; - if (transformComponent->parent() == childBone && - std::find(bones.begin(), bones.end(), transformComponent) == - bones.end()) + if (!child->is() || child == chainChild) { - tip->addDependent(transformComponent); + continue; } + tip->addDependent(child->as()); } } return Super::onAddedClean(context); diff --git a/thirdparty/rive/source/constraints/list_constraint.cpp b/thirdparty/rive/source/constraints/list_constraint.cpp new file mode 100644 index 000000000..0f16ec5e7 --- /dev/null +++ b/thirdparty/rive/source/constraints/list_constraint.cpp @@ -0,0 +1,15 @@ +#include "rive/component.hpp" +#include "rive/constraints/list_follow_path_constraint.hpp" +#include "rive/constraints/list_constraint.hpp" + +using namespace rive; + +ListConstraint* ListConstraint::from(Component* component) +{ + switch (component->coreType()) + { + case ListFollowPathConstraintBase::typeKey: + return component->as(); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/list_follow_path_constraint.cpp b/thirdparty/rive/source/constraints/list_follow_path_constraint.cpp new file mode 100644 index 000000000..6d8929e05 --- /dev/null +++ b/thirdparty/rive/source/constraints/list_follow_path_constraint.cpp @@ -0,0 +1,64 @@ +#include "rive/artboard.hpp" +#include "rive/constraints/constrainable_list.hpp" +#include "rive/constraints/list_follow_path_constraint.hpp" +#include "rive/math/transform_components.hpp" + +using namespace rive; + +void ListFollowPathConstraint::distanceEndChanged() { markConstraintDirty(); } +void ListFollowPathConstraint::distanceOffsetChanged() +{ + markConstraintDirty(); +} + +void ListFollowPathConstraint::constrainList(ConstrainableList* list) +{ + auto listTransform = list->listTransform(); + std::vector transforms; + list->listItemTransforms(transforms); + auto count = transforms.size(); + float startOffset = distanceOffset() + distance(); + float startToEndDistance = distanceEnd() - distance(); + float offsetDistance = + count <= 1 ? 0 : startToEndDistance / ((float)count - 1); + for (int i = 0; i < count; i++) + { + auto transform = transforms[i]; + auto transformComponents = + constrainAtOffset(*transform, + listTransform, + startOffset + i * offsetDistance); + auto transformB = Mat2D::compose(transformComponents); + transform->xx(transformB.xx()); + transform->xy(transformB.xy()); + transform->yx(transformB.yx()); + transform->yy(transformB.yy()); + transform->tx(transformB.tx()); + transform->ty(transformB.ty()); + } +} + +TransformComponents ListFollowPathConstraint::constrainAtOffset( + const Mat2D& componentTransform, + const Mat2D& parentTransform, + float componentOffset) +{ + if (m_Target == nullptr || m_Target->isCollapsed()) + { + return TransformComponents(); + } + Mat2D transformB(targetTransform(componentOffset)); + auto transformComponents = + constrainHelper(componentTransform, transformB, parentTransform); + return transformComponents; +} + +void ListFollowPathConstraint::buildDependencies() +{ + Super::buildDependencies(); + auto constrainableList = ConstrainableList::from(parent()); + if (constrainableList != nullptr) + { + constrainableList->addListConstraint(this); + } +} diff --git a/thirdparty/rive/source/constraints/scrolling/clamped_scroll_physics.cpp b/thirdparty/rive/source/constraints/scrolling/clamped_scroll_physics.cpp index 318a20e51..2f80dac43 100644 --- a/thirdparty/rive/source/constraints/scrolling/clamped_scroll_physics.cpp +++ b/thirdparty/rive/source/constraints/scrolling/clamped_scroll_physics.cpp @@ -9,16 +9,24 @@ Vec2D ClampedScrollPhysics::advance(float elapsedSeconds) return m_value; } -void ClampedScrollPhysics::run(Vec2D range, +void ClampedScrollPhysics::run(Vec2D rangeMin, + Vec2D rangeMax, Vec2D value, - std::vector snappingPoints) + std::vector snappingPoints, + float contentSize, + float viewportSize) { - ScrollPhysics::run(range, value, snappingPoints); - m_value = clamp(range, value); + ScrollPhysics::run(rangeMin, + rangeMax, + value, + snappingPoints, + contentSize, + viewportSize); + m_value = clamp(rangeMin, rangeMax, value); } -Vec2D ClampedScrollPhysics::clamp(Vec2D range, Vec2D value) +Vec2D ClampedScrollPhysics::clamp(Vec2D rangeMin, Vec2D rangeMax, Vec2D value) { - return Vec2D(math::clamp(value.x, range.x, 0), - math::clamp(value.y, range.y, 0)); + return Vec2D(math::clamp(value.x, rangeMin.x, rangeMax.x), + math::clamp(value.y, rangeMin.y, rangeMax.y)); } \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/scrolling/elastic_scroll_physics.cpp b/thirdparty/rive/source/constraints/scrolling/elastic_scroll_physics.cpp index 2f153f53d..68eb65948 100644 --- a/thirdparty/rive/source/constraints/scrolling/elastic_scroll_physics.cpp +++ b/thirdparty/rive/source/constraints/scrolling/elastic_scroll_physics.cpp @@ -3,12 +3,6 @@ using namespace rive; -ElasticScrollPhysics::~ElasticScrollPhysics() -{ - delete m_physicsX; - delete m_physicsY; -} - Vec2D ElasticScrollPhysics::advance(float elapsedSeconds) { float advanceX = @@ -24,20 +18,30 @@ Vec2D ElasticScrollPhysics::advance(float elapsedSeconds) return Vec2D(advanceX, advanceY); } -Vec2D ElasticScrollPhysics::clamp(Vec2D range, Vec2D value) +Vec2D ElasticScrollPhysics::clamp(Vec2D rangeMin, Vec2D rangeMax, Vec2D value) { - float clampX = - m_physicsX != nullptr ? m_physicsX->clamp(range.x, value.x) : 0.0f; - float clampY = - m_physicsY != nullptr ? m_physicsY->clamp(range.y, value.y) : 0.0f; + float clampX = m_physicsX != nullptr + ? m_physicsX->clamp(rangeMin.x, rangeMax.x, value.x) + : 0.0f; + float clampY = m_physicsY != nullptr + ? m_physicsY->clamp(rangeMin.y, rangeMax.y, value.y) + : 0.0f; return Vec2D(clampX, clampY); } -void ElasticScrollPhysics::run(Vec2D range, +void ElasticScrollPhysics::run(Vec2D rangeMin, + Vec2D rangeMax, Vec2D value, - std::vector snappingPoints) + std::vector snappingPoints, + float contentSize, + float viewportSize) { - Super::run(range, value, snappingPoints); + Super::run(rangeMin, + rangeMax, + value, + snappingPoints, + contentSize, + viewportSize); std::vector xPoints; std::vector yPoints; for (auto pt : snappingPoints) @@ -47,11 +51,23 @@ void ElasticScrollPhysics::run(Vec2D range, } if (m_physicsX != nullptr) { - m_physicsX->run(m_acceleration.x, range.x, value.x, xPoints); + m_physicsX->run(m_acceleration.x, + rangeMin.x, + rangeMax.x, + value.x, + xPoints, + contentSize, + viewportSize); } if (m_physicsY != nullptr) { - m_physicsY->run(m_acceleration.y, range.y, value.y, yPoints); + m_physicsY->run(m_acceleration.y, + rangeMin.y, + rangeMax.y, + value.y, + yPoints, + contentSize, + viewportSize); } } @@ -61,24 +77,26 @@ void ElasticScrollPhysics::prepare(DraggableConstraintDirection dir) if (dir == DraggableConstraintDirection::horizontal || dir == DraggableConstraintDirection::all) { - m_physicsX = new ElasticScrollPhysicsHelper(friction(), - speedMultiplier(), - elasticFactor()); + m_physicsX = + std::make_unique(friction(), + speedMultiplier(), + elasticFactor()); } if (dir == DraggableConstraintDirection::vertical || dir == DraggableConstraintDirection::all) { - m_physicsY = new ElasticScrollPhysicsHelper(friction(), - speedMultiplier(), - elasticFactor()); + m_physicsY = + std::make_unique(friction(), + speedMultiplier(), + elasticFactor()); } } void ElasticScrollPhysics::reset() { Super::reset(); - m_physicsX = nullptr; - m_physicsY = nullptr; + m_physicsX.reset(); + m_physicsY.reset(); } float ElasticScrollPhysicsHelper::advance(float elapsedSeconds) @@ -87,28 +105,27 @@ float ElasticScrollPhysicsHelper::advance(float elapsedSeconds) { m_current += m_speed * elapsedSeconds; - auto friction = m_friction; - if (m_current < m_runRange) + if (m_current < m_runRangeMin) { - friction *= 4; + m_friction *= 4; } - else if (m_current > 0) + else if (m_current > m_runRangeMax) { - friction *= 4; + m_friction *= 4; } - m_speed += -m_speed * std::min(1.0f, elapsedSeconds * friction); + m_speed += -m_speed * std::min(1.0f, elapsedSeconds * m_friction); if (abs(m_speed) < 5) { m_speed = 0; - if (m_current < m_runRange) + if (m_current < m_runRangeMin) { - m_target = m_runRange; + m_target = m_runRangeMin; } - else if (m_current > 0) + else if (m_current > m_runRangeMax) { - m_target = 0; + m_target = m_runRangeMax; } else { @@ -120,7 +137,7 @@ float ElasticScrollPhysicsHelper::advance(float elapsedSeconds) auto diff = m_target - m_current; if (abs(diff) < 0.1) { - m_current = m_target; + m_current = std::isnan(m_snapTarget) ? m_target : m_snapTarget; m_isRunning = false; } else @@ -130,26 +147,32 @@ float ElasticScrollPhysicsHelper::advance(float elapsedSeconds) return m_current; } -float ElasticScrollPhysicsHelper::clamp(float range, float value) +float ElasticScrollPhysicsHelper::clamp(float rangeMin, + float rangeMax, + float value) { - if (value < range) + if (value < rangeMin) { - return range - pow(-(value - range), m_elasticFactor); + return rangeMin - pow(-(value - rangeMin), m_elasticFactor); } - else if (value > 0) + else if (value > rangeMax) { - return pow(value, m_elasticFactor); + return rangeMax + pow(value + rangeMax, m_elasticFactor); } return value; } void ElasticScrollPhysicsHelper::run(float acceleration, - float range, + float rangeMin, + float rangeMax, float value, - std::vector snappingPoints) + std::vector snappingPoints, + float contentSize, + float viewportSize) { m_isRunning = true; - m_runRange = range; + m_runRangeMin = rangeMin; + m_runRangeMax = rangeMax; if (abs(acceleration) > 100) { m_speed = acceleration * 0.16f * 0.16f * 0.1f * m_speedMultiplier; @@ -158,13 +181,13 @@ void ElasticScrollPhysicsHelper::run(float acceleration, { m_speed = 0; } - if (value < range) + if (value < rangeMin) { - m_target = range; + m_target = rangeMin; } - else if (value > 0) + else if (value > rangeMax) { - m_target = 0; + m_target = rangeMax; } else { @@ -175,17 +198,82 @@ void ElasticScrollPhysicsHelper::run(float acceleration, if (!snappingPoints.empty()) { float endTarget = -(m_current + m_speed / m_friction); + float sectionSize = contentSize != 0 ? contentSize : 1; + float viewportSectionSize = viewportSize != 0 ? viewportSize : 1; + int multiple = rangeMax == std::numeric_limits::infinity() + ? std::floor(endTarget / sectionSize) + : 0; + float modEndTarget = rangeMax == std::numeric_limits::infinity() + ? std::fmod(endTarget, sectionSize) + : endTarget; + float maxTarget = rangeMax == std::numeric_limits::infinity() + ? std::numeric_limits::infinity() + : sectionSize - viewportSectionSize; float closest = std::numeric_limits::max(); float snapTarget = 0; for (auto snap : snappingPoints) { - float diff = std::abs(snap - endTarget); + float diff = std::abs(snap - modEndTarget); if (diff < closest) { closest = diff; - snapTarget = snap; + snapTarget = snap + (multiple * sectionSize); } } + snapTarget = std::min(snapTarget, maxTarget); m_speed = -(snapTarget + m_current) * m_friction; + m_snapTarget = -snapTarget; + } + else + { + m_snapTarget = NAN; + } +} + +void ElasticScrollPhysicsHelper::scrollTo(float current, + float target, + float rangeMin, + float rangeMax) +{ + m_isRunning = true; + m_runRangeMin = rangeMin; + m_runRangeMax = rangeMax; + m_current = current; + m_target = target; + m_speed = 0; // Skip velocity phase, go directly to settling + m_snapTarget = NAN; +} + +void ElasticScrollPhysics::scrollToPosition(Vec2D current, + Vec2D target, + Vec2D rangeMin, + Vec2D rangeMax, + bool horizontal, + bool vertical) +{ + // Create physics helpers if needed + if (horizontal && m_physicsX == nullptr) + { + m_physicsX = + std::make_unique(friction(), + speedMultiplier(), + elasticFactor()); + } + if (vertical && m_physicsY == nullptr) + { + m_physicsY = + std::make_unique(friction(), + speedMultiplier(), + elasticFactor()); + } + + // Initiate settling animation + if (m_physicsX != nullptr && horizontal) + { + m_physicsX->scrollTo(current.x, target.x, rangeMin.x, rangeMax.x); + } + if (m_physicsY != nullptr && vertical) + { + m_physicsY->scrollTo(current.y, target.y, rangeMin.y, rangeMax.y); } } \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/scrolling/scroll_bar_constraint_proxy.cpp b/thirdparty/rive/source/constraints/scrolling/scroll_bar_constraint_proxy.cpp index b8e79748b..37430364e 100644 --- a/thirdparty/rive/source/constraints/scrolling/scroll_bar_constraint_proxy.cpp +++ b/thirdparty/rive/source/constraints/scrolling/scroll_bar_constraint_proxy.cpp @@ -4,18 +4,21 @@ using namespace rive; -void ThumbDraggableProxy::drag(Vec2D mousePosition) +bool ThumbDraggableProxy::drag(Vec2D mousePosition, float timeStamp) { m_constraint->dragThumb(mousePosition - m_lastPosition); m_lastPosition = mousePosition; + return true; } -void ThumbDraggableProxy::startDrag(Vec2D mousePosition) +bool ThumbDraggableProxy::startDrag(Vec2D mousePosition, float timeStamp) { m_lastPosition = mousePosition; + return true; } -void TrackDraggableProxy::startDrag(Vec2D mousePosition) +bool TrackDraggableProxy::startDrag(Vec2D mousePosition, float timeStamp) { m_constraint->hitTrack(mousePosition); + return true; } \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/scrolling/scroll_constraint.cpp b/thirdparty/rive/source/constraints/scrolling/scroll_constraint.cpp index c990692cb..16e38ed72 100644 --- a/thirdparty/rive/source/constraints/scrolling/scroll_constraint.cpp +++ b/thirdparty/rive/source/constraints/scrolling/scroll_constraint.cpp @@ -1,20 +1,201 @@ #include "rive/constraints/scrolling/scroll_constraint.hpp" #include "rive/constraints/scrolling/scroll_constraint_proxy.hpp" +#include "rive/constraints/scrolling/scroll_virtualizer.hpp" #include "rive/constraints/transform_constraint.hpp" #include "rive/core_context.hpp" #include "rive/layout/layout_node_provider.hpp" #include "rive/transform_component.hpp" +#include "rive/virtualizing_component.hpp" #include "rive/math/mat2d.hpp" using namespace rive; -ScrollConstraint::~ScrollConstraint() { delete m_physics; } +ScrollConstraint::~ScrollConstraint() +{ + if (m_virtualizer != nullptr) + { + delete m_virtualizer; + m_virtualizer = nullptr; + } + m_layoutChildren.clear(); + delete m_physics; +} + +float ScrollConstraint::contentWidth() +{ + if (virtualize() && !mainAxisIsColumn()) + { + auto contentSize = 0.0f; + for (auto child : scrollChildren()) + { + if (child == nullptr) + { + continue; + } + contentSize += child->layoutBounds().width(); + } + auto lenOffset = infinite() ? 0 : 1; + return contentSize + gap().x * (scrollChildren().size() - lenOffset); + } + return content()->layoutWidth(); +} + +float ScrollConstraint::contentHeight() +{ + if (virtualize() && mainAxisIsColumn()) + { + auto contentSize = 0.0f; + for (auto child : scrollChildren()) + { + if (child == nullptr) + { + continue; + } + contentSize += child->layoutBounds().height(); + } + auto lenOffset = infinite() ? 0 : 1; + return contentSize + gap().y * (scrollChildren().size() - lenOffset); + } + return content()->layoutHeight(); +} + +float ScrollConstraint::viewportWidth() +{ + return direction() == DraggableConstraintDirection::vertical + ? viewport()->layoutWidth() + : std::max(0.0f, + viewport()->layoutWidth() - content()->layoutX()); +} +float ScrollConstraint::viewportHeight() +{ + return direction() == DraggableConstraintDirection::horizontal + ? viewport()->layoutHeight() + : std::max(0.0f, + viewport()->layoutHeight() - content()->layoutY()); +} +float ScrollConstraint::visibleWidthRatio() +{ + if (contentWidth() == 0) + { + return 1; + } + return std::min(1.0f, viewportWidth() / contentWidth()); +} +float ScrollConstraint::visibleHeightRatio() +{ + if (contentHeight() == 0) + { + return 1; + } + return std::min(1.0f, viewportHeight() / contentHeight()); +} +float ScrollConstraint::minOffsetX() +{ + if (infinite() && !mainAxisIsColumn()) + { + return std::numeric_limits::infinity(); + } + return 0; +} +float ScrollConstraint::minOffsetY() +{ + if (infinite() && mainAxisIsColumn()) + { + return std::numeric_limits::infinity(); + } + return 0; +} +float ScrollConstraint::maxOffsetX() +{ + if (infinite() && !mainAxisIsColumn()) + { + return -std::numeric_limits::infinity(); + } + return std::min(0.0f, + viewportWidth() - contentWidth() - + viewport()->paddingRight()); +} +float ScrollConstraint::maxOffsetY() +{ + if (infinite() && mainAxisIsColumn()) + { + return -std::numeric_limits::infinity(); + } + return std::min(0.0f, + viewportHeight() - contentHeight() - + viewport()->paddingBottom()); +} +float ScrollConstraint::clampedOffsetX() +{ + if (infinite()) + { + return offsetX(); + } + if (maxOffsetX() > 0) + { + return 0; + } + if (m_physics != nullptr && m_physics->enabled()) + { + return m_physics + ->clamp(Vec2D(maxOffsetX(), maxOffsetY()), + Vec2D(minOffsetX(), minOffsetY()), + Vec2D(m_offsetX, m_offsetY)) + .x; + } + return math::clamp(m_offsetX, maxOffsetX(), 0); +} +float ScrollConstraint::clampedOffsetY() +{ + if (infinite()) + { + return offsetY(); + } + if (maxOffsetY() > 0) + { + return 0; + } + if (m_physics != nullptr && m_physics->enabled()) + { + return m_physics + ->clamp(Vec2D(maxOffsetX(), maxOffsetY()), + Vec2D(minOffsetX(), minOffsetY()), + Vec2D(m_offsetX, m_offsetY)) + .y; + } + return math::clamp(m_offsetY, maxOffsetY(), 0); +} + +void ScrollConstraint::offsetX(float value) +{ + if (m_offsetX == value) + { + return; + } + m_offsetX = value; + content()->markWorldTransformDirty(); +} +void ScrollConstraint::offsetY(float value) +{ + if (m_offsetY == value) + { + return; + } + m_offsetY = value; + content()->markWorldTransformDirty(); +} + +bool ScrollConstraint::mainAxisIsColumn() +{ + return content() != nullptr && content()->mainAxisIsColumn(); +} void ScrollConstraint::constrain(TransformComponent* component) { m_scrollTransform = Mat2D::fromTranslate(constrainsHorizontal() ? clampedOffsetX() : 0, constrainsVertical() ? clampedOffsetY() : 0); + m_childConstraintAppliedCount = 0; } void ScrollConstraint::constrainChild(LayoutNodeProvider* child) @@ -32,44 +213,82 @@ void ScrollConstraint::constrainChild(LayoutNodeProvider* child) targetTransform, m_componentsB, strength()); + m_childConstraintAppliedCount += 1; + constrainVirtualized(); +} + +void ScrollConstraint::constrainVirtualized(bool force) +{ + if (virtualize() && m_virtualizer != nullptr) + { + auto children = scrollChildren(); + if (m_childConstraintAppliedCount < children.size() && !force) + { + return; + } + auto isColumn = mainAxisIsColumn(); + auto direction = isColumn ? VirtualizedDirection::vertical + : VirtualizedDirection::horizontal; + auto offset = isColumn ? clampedOffsetY() : clampedOffsetX(); + m_virtualizer->constrain(this, children, offset, direction); + } +} + +void ScrollConstraint::addLayoutChild(LayoutNodeProvider* child) +{ + m_layoutChildren.push_back(child); } -void ScrollConstraint::dragView(Vec2D delta) +void ScrollConstraint::dragView(Vec2D delta, float timeStamp) { if (m_physics != nullptr) { - m_physics->accumulate(delta); + m_physics->accumulate(delta, timeStamp); } scrollOffsetX(offsetX() + delta.x); scrollOffsetY(offsetY() + delta.y); } -void ScrollConstraint::runPhysics() +std::vector ScrollConstraint::collectSnapPoints() { - m_isDragging = false; std::vector snappingPoints; - if (snap()) + if (content() == nullptr) + { + return snappingPoints; + } + for (auto child : content()->children()) { - for (auto child : content()->children()) + auto c = LayoutNodeProvider::from(child); + if (c != nullptr) { - auto c = LayoutNodeProvider::from(child); - if (c != nullptr) + size_t count = c->numLayoutNodes(); + for (int j = 0; j < count; j++) { - size_t count = c->numLayoutNodes(); - for (int j = 0; j < count; j++) + auto bounds = c->layoutBoundsForNode(j); + if (isBoundsCollapsed(bounds)) { - auto bounds = c->layoutBoundsForNode(j); - snappingPoints.push_back( - Vec2D(bounds.left(), bounds.top())); + continue; } + snappingPoints.push_back(Vec2D(bounds.left(), bounds.top())); } } } + return snappingPoints; +} + +void ScrollConstraint::runPhysics() +{ + m_isDragging = false; + std::vector snappingPoints = + snap() ? collectSnapPoints() : std::vector(); if (m_physics != nullptr) { m_physics->run(Vec2D(maxOffsetX(), maxOffsetY()), + Vec2D(minOffsetX(), minOffsetY()), Vec2D(offsetX(), offsetY()), - snap() ? snappingPoints : std::vector()); + snappingPoints, + mainAxisIsColumn() ? contentHeight() : contentWidth(), + mainAxisIsColumn() ? viewportHeight() : viewportWidth()); } } @@ -156,6 +375,10 @@ StatusCode ScrollConstraint::import(ImportStack& importStack) StatusCode ScrollConstraint::onAddedDirty(CoreContext* context) { StatusCode result = Super::onAddedDirty(context); + if (virtualize()) + { + m_virtualizer = new ScrollVirtualizer(); + } offsetX(scrollOffsetX()); offsetY(scrollOffsetY()); return result; @@ -178,14 +401,24 @@ void ScrollConstraint::stopPhysics() } } +float ScrollConstraint::maxOffsetXForPercent() +{ + return infinite() ? contentWidth() : maxOffsetX(); +} + +float ScrollConstraint::maxOffsetYForPercent() +{ + return infinite() ? contentHeight() : maxOffsetY(); +} + float ScrollConstraint::scrollPercentX() { - return maxOffsetX() != 0 ? scrollOffsetX() / maxOffsetX() : 0; + return maxOffsetX() != 0 ? scrollOffsetX() / maxOffsetXForPercent() : 0; } float ScrollConstraint::scrollPercentY() { - return maxOffsetY() != 0 ? scrollOffsetY() / maxOffsetY() : 0; + return maxOffsetY() != 0 ? scrollOffsetY() / maxOffsetYForPercent() : 0; } float ScrollConstraint::scrollIndex() @@ -200,7 +433,7 @@ void ScrollConstraint::setScrollPercentX(float value) return; } stopPhysics(); - float to = value * maxOffsetX(); + float to = value * maxOffsetXForPercent(); scrollOffsetX(to); } @@ -211,7 +444,7 @@ void ScrollConstraint::setScrollPercentY(float value) return; } stopPhysics(); - float to = value * maxOffsetY(); + float to = value * maxOffsetYForPercent(); scrollOffsetY(to); } @@ -235,32 +468,39 @@ void ScrollConstraint::setScrollIndex(float value) Vec2D ScrollConstraint::positionAtIndex(float index) { - if (content() == nullptr || content()->children().size() == 0) + auto count = scrollItemCount(); + if (content() == nullptr || count == 0) { return Vec2D(); } uint32_t i = 0; Vec2D contentGap = gap(); - float floorIndex = std::floor(index); - LayoutNodeProvider* lastChild; - for (auto child : content()->children()) + float normalizedIndex = infinite() ? std::fmod(index, (float)count) : index; + float floorIndex = std::floor(normalizedIndex); + LayoutNodeProvider* lastChild = nullptr; + for (auto child : scrollChildren()) { - auto c = LayoutNodeProvider::from(child); - if (c != nullptr) + if (child == nullptr) { - size_t count = c->numLayoutNodes(); - if ((uint32_t)floorIndex < i + count) - { - float mod = index - floorIndex; - auto bounds = c->layoutBoundsForNode(floorIndex - i); - return Vec2D( - -bounds.left() - (bounds.width() + contentGap.x) * mod, - -bounds.top() - (bounds.height() + contentGap.y) * mod); - } - lastChild = c; - i += count; + continue; + } + size_t count = child->numLayoutNodes(); + if ((uint32_t)floorIndex < i + count) + { + float mod = normalizedIndex - floorIndex; + auto bounds = child->layoutBoundsForNode(floorIndex - i); + return Vec2D(-bounds.left() - (bounds.width() + contentGap.x) * mod, + -bounds.top() - + (bounds.height() + contentGap.y) * mod); } + lastChild = child; + i += count; + } + if (lastChild == nullptr) + { + return Vec2D(); } + auto bounds = lastChild->layoutBoundsForNode((int)lastChild->numLayoutNodes() - 1); return Vec2D(-bounds.left(), -bounds.top()); @@ -276,63 +516,67 @@ float ScrollConstraint::indexAtPosition(Vec2D pos) Vec2D contentGap = gap(); if (constrainsHorizontal()) { - for (auto child : content()->children()) + for (auto child : scrollChildren()) { - auto c = LayoutNodeProvider::from(child); - if (c != nullptr) + if (child == nullptr) + { + continue; + } + size_t count = child->numLayoutNodes(); + for (int j = 0; j < count; j++) { - size_t count = c->numLayoutNodes(); - for (int j = 0; j < count; j++) + auto bounds = child->layoutBoundsForNode(j); + if (pos.x > -bounds.left() - (bounds.width() + contentGap.x)) { - auto bounds = c->layoutBoundsForNode(j); - if (pos.x > - -bounds.left() - (bounds.width() + contentGap.x)) - { - return (i + j) + (-pos.x - bounds.left()) / - (bounds.width() + contentGap.x); - } + return (i + j) + (-pos.x - bounds.left()) / + (bounds.width() + contentGap.x); } - i += count; } + i += count; } return i; } else if (constrainsVertical()) { - for (auto child : content()->children()) + for (auto child : scrollChildren()) { - auto c = LayoutNodeProvider::from(child); - if (c != nullptr) + if (child == nullptr) + { + continue; + } + size_t count = child->numLayoutNodes(); + for (int j = 0; j < count; j++) { - size_t count = c->numLayoutNodes(); - for (int j = 0; j < count; j++) + auto bounds = child->layoutBoundsForNode(j); + if (pos.y > -bounds.top() - (bounds.height() + contentGap.y)) { - auto bounds = c->layoutBoundsForNode(j); - if (pos.y > - -bounds.top() - (bounds.height() + contentGap.y)) - { - return (i + j) + (-pos.y - bounds.top()) / - (bounds.height() + contentGap.y); - } + return (i + j) + (-pos.y - bounds.top()) / + (bounds.height() + contentGap.y); } - i += count; } + i += count; } return i; } return 0; } +bool ScrollConstraint::isBoundsCollapsed(AABB bounds) +{ + return (constrainsHorizontal() && bounds.width() <= 0) || + (constrainsVertical() && bounds.height() <= 0); +} + size_t ScrollConstraint::scrollItemCount() { size_t count = 0; - for (auto child : content()->children()) + for (auto child : scrollChildren()) { - auto c = LayoutNodeProvider::from(child); - if (c != nullptr) + if (child == nullptr) { - count += c->numLayoutNodes(); + continue; } + count += child->numLayoutNodes(); } return count; } @@ -344,4 +588,101 @@ Vec2D ScrollConstraint::gap() return Vec2D(); } return Vec2D(content()->gapHorizontal(), content()->gapVertical()); +} + +void ScrollConstraint::scrollToPosition(float targetX, float targetY) +{ + if (m_physics == nullptr) + { + // No physics, just set offset directly + scrollOffsetX(targetX); + scrollOffsetY(targetY); + return; + } + + Vec2D current(m_offsetX, m_offsetY); + Vec2D target(targetX, targetY); + Vec2D rangeMin(maxOffsetX(), maxOffsetY()); + Vec2D rangeMax(0.0f, 0.0f); + + m_physics->scrollToPosition(current, + target, + rangeMin, + rangeMax, + constrainsHorizontal(), + constrainsVertical()); +} + +static float nearestSnapInDirection(float current, + float target, + const std::vector& snapPoints, + bool useX) +{ + if (current == target) + { + return target; + } + bool scrollingNegative = target < current; + float best = target; + bool found = false; + float bestDist = 0.0f; + for (const auto& p : snapPoints) + { + float c = useX ? -p.x : -p.y; + if (scrollingNegative ? c > target : c < target) + { + continue; + } + float d = scrollingNegative ? target - c : c - target; + if (!found || d < bestDist) + { + bestDist = d; + best = c; + found = true; + } + } + return found ? best : target; +} + +Vec2D ScrollConstraint::nearestSnapOffsetInDirection(Vec2D current, + Vec2D target) +{ + if (!snap()) + { + return target; + } + auto snapPoints = collectSnapPoints(); + if (snapPoints.empty()) + { + return target; + } + float snappedX = + constrainsHorizontal() + ? nearestSnapInDirection(current.x, target.x, snapPoints, true) + : target.x; + float snappedY = + constrainsVertical() + ? nearestSnapInDirection(current.y, target.y, snapPoints, false) + : target.y; + return Vec2D(snappedX, snappedY); +} + +float ScrollConstraint::effectiveScrollOffsetX() +{ + if (m_physics != nullptr && m_physics->isRunning() && + m_physics->hasTargetX()) + { + return m_physics->targetX(); + } + return scrollOffsetX(); +} + +float ScrollConstraint::effectiveScrollOffsetY() +{ + if (m_physics != nullptr && m_physics->isRunning() && + m_physics->hasTargetY()) + { + return m_physics->targetY(); + } + return scrollOffsetY(); } \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/scrolling/scroll_constraint_proxy.cpp b/thirdparty/rive/source/constraints/scrolling/scroll_constraint_proxy.cpp index 36fee886e..9a0fadd08 100644 --- a/thirdparty/rive/source/constraints/scrolling/scroll_constraint_proxy.cpp +++ b/thirdparty/rive/source/constraints/scrolling/scroll_constraint_proxy.cpp @@ -5,19 +5,78 @@ using namespace rive; -void ViewportDraggableProxy::drag(Vec2D mousePosition) +bool ViewportDraggableProxy::drag(Vec2D mousePosition, float timeStamp) { - m_constraint->dragView(mousePosition - m_lastPosition); + if (!m_constraint->interactive()) + { + return false; + } + auto deltaPosition = mousePosition - m_lastPosition; + if (!m_isDragging) + { + switch (m_constraint->direction()) + { + case DraggableConstraintDirection::vertical: + { + if (std::abs(deltaPosition.y) > m_constraint->threshold()) + { + m_isDragging = true; + } + else + { + return false; + } + } + break; + case DraggableConstraintDirection::horizontal: + { + if (std::abs(deltaPosition.x) > m_constraint->threshold()) + { + m_isDragging = true; + } + else + { + return false; + } + } + break; + case DraggableConstraintDirection::all: + { + if (deltaPosition.length() > m_constraint->threshold()) + { + m_isDragging = true; + } + else + { + return false; + } + } + break; + } + } + m_constraint->dragView(deltaPosition, timeStamp); m_lastPosition = mousePosition; + return true; } -void ViewportDraggableProxy::startDrag(Vec2D mousePosition) +bool ViewportDraggableProxy::startDrag(Vec2D mousePosition, float timeStamp) { + if (!m_constraint->interactive()) + { + return false; + } + m_isDragging = false; m_constraint->initPhysics(); m_lastPosition = mousePosition; + return true; } -void ViewportDraggableProxy::endDrag(Vec2D mousePosition) +bool ViewportDraggableProxy::endDrag(Vec2D mousePosition, float timeStamp) { + if (!m_constraint->interactive()) + { + return false; + } m_constraint->runPhysics(); + return true; } \ No newline at end of file diff --git a/thirdparty/rive/source/constraints/scrolling/scroll_physics.cpp b/thirdparty/rive/source/constraints/scrolling/scroll_physics.cpp index 74740e02a..fec46c394 100644 --- a/thirdparty/rive/source/constraints/scrolling/scroll_physics.cpp +++ b/thirdparty/rive/source/constraints/scrolling/scroll_physics.cpp @@ -5,13 +5,24 @@ using namespace rive; -void ScrollPhysics::accumulate(Vec2D delta) +void ScrollPhysics::accumulate(Vec2D delta, float timeStamp) { - auto now = std::chrono::high_resolution_clock::now(); - auto ms = std::chrono::duration_cast( - now.time_since_epoch()) - .count(); - float elapsedSeconds = (float)(ms - m_lastTime) / 1000000.0f; + float elapsedSeconds = 0; + if (File::deterministicMode) + { + auto now = timeStamp; + elapsedSeconds = now - m_lastTime; + m_lastTime = now; + } + else + { + auto now = std::chrono::high_resolution_clock::now(); + auto ms = std::chrono::duration_cast( + now.time_since_epoch()) + .count(); + elapsedSeconds = (float)(ms - m_lastTime) / 1000000.0f; + m_lastTime = ms; + } if (elapsedSeconds > 0) { auto lastSpeed = m_speed; @@ -19,7 +30,23 @@ void ScrollPhysics::accumulate(Vec2D delta) m_acceleration = Vec2D((lastSpeed.x + m_speed.x) / elapsedSeconds, (lastSpeed.y + m_speed.y) / elapsedSeconds); } - m_lastTime = ms; +} + +void ScrollPhysics::reset() +{ + if (File::deterministicMode) + { + m_lastTime = 0; + } + else + { + m_lastTime = + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + } + m_acceleration = Vec2D(); + stop(); } StatusCode ScrollPhysics::import(ImportStack& importStack) diff --git a/thirdparty/rive/source/constraints/scrolling/scroll_virtualizer.cpp b/thirdparty/rive/source/constraints/scrolling/scroll_virtualizer.cpp new file mode 100644 index 000000000..3ffd2a3cb --- /dev/null +++ b/thirdparty/rive/source/constraints/scrolling/scroll_virtualizer.cpp @@ -0,0 +1,381 @@ +#include "rive/constraints/scrolling/scroll_constraint.hpp" +#include "rive/layout/layout_node_provider.hpp" +#include "rive/constraints/scrolling/scroll_virtualizer.hpp" + +using namespace rive; + +ScrollVirtualizer::~ScrollVirtualizer() { reset(); } + +void ScrollVirtualizer::reset() { m_visibleIndexStart = m_visibleIndexEnd = 0; } + +bool ScrollVirtualizer::constrain(ScrollConstraint* scroll, + std::vector& children, + float offset, + VirtualizedDirection direction) +{ + bool isHorz = direction == VirtualizedDirection::horizontal; + double contentSize = + isHorz ? scroll->contentWidth() : scroll->contentHeight(); + if (contentSize > 0.0f) + { + float normalizedOffset = -offset; + m_direction = direction; + m_viewportSize = + isHorz ? scroll->viewportWidth() : scroll->viewportHeight(); + m_infinite = scroll->infinite(); + if (offset > 0.0f) + { + if (m_infinite) + { + int offsetMultiplier = + static_cast(std::floor(offset / contentSize)) + 1; + m_offset = -1.0f * (offset - (offsetMultiplier * contentSize)); + } + else + { + m_offset = -offset; + } + } + else + { + int offsetMultiplier = + static_cast(std::floor(normalizedOffset / contentSize)); + m_offset = offsetMultiplier > 0 + ? std::fmod(normalizedOffset, + offsetMultiplier * contentSize) + : normalizedOffset; + } + virtualize(scroll, children); + } + return true; +} + +void ScrollVirtualizer::virtualize(ScrollConstraint* scroll, + std::vector& children) +{ + int totalItemCount = 0; + for (auto child : children) + { + totalItemCount += child->numLayoutNodes(); + } + + // All changes in this function are intended to compare the + // ranges of the previous render to the ranges of the upcoming list. This is + // removing the carousel overflow. + // normalizing the two values to the actual indexes of available children + int lastVisibleIndexStart = m_infinite && totalItemCount > 0 + ? m_visibleIndexStart % totalItemCount + : m_visibleIndexStart; + int lastVisibleIndexEnd = m_infinite && totalItemCount > 0 + ? m_visibleIndexEnd % totalItemCount + : m_visibleIndexEnd; + + m_visibleIndexStart = 0; + m_visibleIndexEnd = totalItemCount - 1; + float runningSize = 0.0f; + float runningOffset = 0.0f; + int runningIndex = 0; + int childIndex = 0; + int currentChildIndex = 0; + bool isHorz = m_direction == VirtualizedDirection::horizontal; + float gap = isHorz ? scroll->gap().x : scroll->gap().y; + + for (int i = 0; i < children.size(); i++) + { + auto child = children[i]; + auto component = child->transformComponent(); + if (component != nullptr) + { + auto virt = VirtualizingComponent::from(component); + if (virt != nullptr) + { + virt->setVisibleIndices(-1, -1); + } + } + } + + for (int i = 0; i < children.size(); i++) + { + auto child = children[i]; + for (int j = 0; j < child->numLayoutNodes(); j++) + { + auto size = getItemSize(child, j, isHorz); + if (runningSize + size > m_offset) + { + runningOffset = runningSize - m_offset; + m_visibleIndexStart = runningIndex; + if (currentChildIndex == children.size() - 1) + { + childIndex++; + currentChildIndex = 0; + } + else + { + currentChildIndex++; + } + goto findVisibleEnd; + } + runningSize += size; + currentChildIndex = j; + runningIndex++; + if (runningSize + gap > m_offset) + { + if (runningIndex == totalItemCount) + { + runningIndex = 0; + } + if (currentChildIndex == children.size() - 1) + { + childIndex++; + currentChildIndex = 0; + } + else + { + currentChildIndex++; + } + runningSize += gap; + runningOffset = runningSize - m_offset; + m_visibleIndexStart = runningIndex; + goto findVisibleEnd; + } + runningSize += gap; + } + childIndex++; + } + +findVisibleEnd: + childIndex = childIndex % children.size(); + int i = m_visibleIndexStart; + bool wrapped = false; + int cycleCount = 0; + while (i < totalItemCount && cycleCount < 2) + { + auto child = children[childIndex]; + for (int j = currentChildIndex; j < child->numLayoutNodes(); j++) + { + auto size = getItemSize(child, j, isHorz); + if (runningSize + size + gap >= m_offset + m_viewportSize) + { + m_visibleIndexEnd = + m_infinite ? (wrapped ? i + totalItemCount : i) : i; + goto recycle; + } + runningSize += size + gap; + runningIndex++; + if (m_infinite && i == totalItemCount - 1) + { + wrapped = true; + i = -1; // will become 0 after increment + cycleCount++; + } + i++; + } + currentChildIndex = 0; + } + +recycle: + std::vector indicesToRecycle; + int actualStart = m_infinite && totalItemCount > 0 + ? m_visibleIndexStart % totalItemCount + : m_visibleIndexStart; + int actualEnd = m_infinite && totalItemCount > 0 + ? m_visibleIndexEnd % totalItemCount + : m_visibleIndexEnd; + std::unordered_map usedIndexes = {}; + // If start < end it means that the range is not going over + // the end of the list, so we know we can add the full range to the used + // items. + if (actualStart <= actualEnd) + { + for (int i = actualStart; i <= actualEnd; i++) + { + usedIndexes[i] = true; + } + } + // If end > start, we know that the range wraps, so we + // actually need to add two ranges, from [start to totalIItems] and from [0 + // to end] + else + { + for (int i = actualStart; i < totalItemCount; i++) + { + usedIndexes[i] = true; + } + for (int i = 0; i <= actualEnd; i++) + { + usedIndexes[i] = true; + } + } + // Similarly, we check the previous ranges and check which + // ones overlap with the new range and which ones can be recycled. + if (lastVisibleIndexStart <= lastVisibleIndexEnd) + { + + for (int i = lastVisibleIndexStart; i <= lastVisibleIndexEnd; i++) + { + if (usedIndexes.find(i) == usedIndexes.end()) + { + indicesToRecycle.push_back(i); + } + } + } + else + { + + for (int i = lastVisibleIndexStart; i < totalItemCount; i++) + { + if (usedIndexes.find(i) == usedIndexes.end()) + { + indicesToRecycle.push_back(i); + } + } + for (int i = 0; i <= lastVisibleIndexEnd; i++) + { + if (usedIndexes.find(i) == usedIndexes.end()) + { + indicesToRecycle.push_back(i); + } + } + } + recycleItems(indicesToRecycle, children, totalItemCount); + + std::vector visibleIndices(children.size(), Vec2D(-1, -1)); + + for (int i = m_visibleIndexStart; i <= m_visibleIndexEnd; ++i) + { + int actualIndex = m_infinite ? i % totalItemCount : i; + int runningTotal = 0; + for (int i = 0; i < children.size(); i++) + { + auto child = children[i]; + int start = runningTotal; + int end = start + (int)child->numLayoutNodes(); + auto component = child->transformComponent(); + if (component != nullptr) + { + auto virt = VirtualizingComponent::from(component); + if (virt != nullptr && start < end) + { + if (actualIndex < end && actualIndex >= start) + { + int childIndex = actualIndex - start; + auto& visibleInd = visibleIndices[i]; + if (visibleInd.x == -1) + { + visibleInd.x = childIndex; + } + visibleInd.y = childIndex; + auto item = virt->item(childIndex); + if (item == nullptr) + { + virt->addVirtualizable(childIndex); + } + + auto size = getItemSize(child, childIndex, isHorz); + auto virtualizable = virt->item(childIndex); + if (virtualizable != nullptr) + { + auto virtualizableComponent = + virtualizable->virtualizableComponent(); + if (virtualizableComponent != nullptr && + virtualizableComponent->is()) + { + auto artboardInstance = + virtualizableComponent + ->as(); + auto parentWorld = component->worldTransform(); + Mat2D inverse; + if (!parentWorld.invert(&inverse)) + { + continue; + } + auto location = + isHorz ? Vec2D(runningOffset, + artboardInstance->layoutY()) + : Vec2D(artboardInstance->layoutX(), + runningOffset); + virt->setVirtualizablePosition(childIndex, + location); + } + } + + runningOffset += size + gap; + break; + } + } + } + runningTotal = end; + } + } + + for (int i = 0; i < children.size(); i++) + { + auto child = children[i]; + auto visible = visibleIndices[i]; + auto component = child->transformComponent(); + if (component != nullptr) + { + auto virt = VirtualizingComponent::from(component); + if (virt != nullptr) + { + virt->setVisibleIndices(visible.x, visible.y); + } + } + } +} + +void ScrollVirtualizer::recycleItems(std::vector indices, + std::vector& children, + int totalItemCount) +{ + if (totalItemCount == 0) + { + return; + } + std::sort(indices.begin(), indices.end()); + for (auto globalIndex : indices) + { + auto actualIndex = + m_infinite ? globalIndex % totalItemCount : globalIndex; + int runningTotal = 0; + for (int i = 0; i < children.size(); i++) + { + auto child = children[i]; + int start = runningTotal; + int end = start + (int)child->numLayoutNodes(); + auto component = child->transformComponent(); + if (component != nullptr) + { + auto virt = VirtualizingComponent::from(component); + if (virt != nullptr && start < end) + { + if (actualIndex < end && actualIndex >= start) + { + int childIndex = actualIndex - start; + virt->removeVirtualizable(childIndex); + break; + } + } + } + runningTotal = end; + } + } +} + +float ScrollVirtualizer::getItemSize(LayoutNodeProvider* child, + int index, + bool isHorizontal) +{ + auto component = child->transformComponent(); + if (component != nullptr) + { + auto virt = VirtualizingComponent::from(component); + if (virt != nullptr) + { + auto size = virt->itemSize(index); + return isHorizontal ? size.x : size.y; + } + } + auto bounds = child->layoutBounds(); + return isHorizontal ? bounds.width() : bounds.height(); +} diff --git a/thirdparty/rive/source/constraints/transform_constraint.cpp b/thirdparty/rive/source/constraints/transform_constraint.cpp index f74dd6e45..d127d8692 100644 --- a/thirdparty/rive/source/constraints/transform_constraint.cpp +++ b/thirdparty/rive/source/constraints/transform_constraint.cpp @@ -8,7 +8,7 @@ using namespace rive; const Mat2D TransformConstraint::targetTransform() const { - AABB bounds = m_Target->localBounds(); + AABB bounds = m_Target->constraintBounds(); Mat2D local = Mat2D::fromTranslate(bounds.left() + bounds.width() * originX(), bounds.top() + bounds.height() * originY()); diff --git a/thirdparty/rive/source/core/binary_data_reader.cpp b/thirdparty/rive/source/core/binary_data_reader.cpp index 41ab9a7f6..55c3382b1 100644 --- a/thirdparty/rive/source/core/binary_data_reader.cpp +++ b/thirdparty/rive/source/core/binary_data_reader.cpp @@ -95,6 +95,26 @@ uint32_t BinaryDataReader::readUint32() return value; } +std::string BinaryDataReader::readString() +{ + uint64_t length = readVarUint(); + if (didOverflow()) + { + return std::string(); + } + + std::string rawValue; + rawValue.resize(length); + auto readBytes = decode_string(length, m_Position, m_End, &rawValue[0]); + if (readBytes != length) + { + overflow(); + return std::string(); + } + m_Position += readBytes; + return std::string(rawValue); +} + void BinaryDataReader::complete(uint8_t* bytes, size_t length) { m_Position = bytes; diff --git a/thirdparty/rive/source/core/binary_reader.cpp b/thirdparty/rive/source/core/binary_reader.cpp index 0cf9e7a88..fcb78724a 100644 --- a/thirdparty/rive/source/core/binary_reader.cpp +++ b/thirdparty/rive/source/core/binary_reader.cpp @@ -49,14 +49,8 @@ uint64_t BinaryReader::readVarUint64() return value; } -std::string BinaryReader::readString() +std::string BinaryReader::readString(size_t length) { - uint64_t length = readVarUint64(); - if (didOverflow()) - { - return std::string(); - } - std::vector rawValue((size_t)length + 1); auto readBytes = decode_string(length, m_Position, m_Bytes.end(), &rawValue[0]); @@ -69,6 +63,16 @@ std::string BinaryReader::readString() return std::string(rawValue.data(), (size_t)length); } +std::string BinaryReader::readString() +{ + uint64_t length = readVarUint64(); + if (didOverflow()) + { + return std::string(); + } + return readString(length); +} + Span BinaryReader::readBytes() { uint64_t length = readVarUint64(); @@ -77,6 +81,11 @@ Span BinaryReader::readBytes() return Span(m_Position, 0); } + return readBytes((size_t)length); +} + +Span BinaryReader::readBytes(size_t length) +{ const uint8_t* start = m_Position; m_Position += length; return {start, (size_t)length}; @@ -95,6 +104,21 @@ float BinaryReader::readFloat32() return value; } +#ifdef WITH_RIVE_TOOLS +double BinaryReader::readFloat64() +{ + double value; + auto readBytes = decode_double(m_Position, m_Bytes.end(), &value); + if (readBytes == 0) + { + overflow(); + return 0.0f; + } + m_Position += readBytes; + return value; +} +#endif + uint8_t BinaryReader::readByte() { if (m_Bytes.end() - m_Position < 1) diff --git a/thirdparty/rive/source/core/field_types/core_bool_type.cpp b/thirdparty/rive/source/core/field_types/core_bool_type.cpp index d738b7400..ad20b180b 100644 --- a/thirdparty/rive/source/core/field_types/core_bool_type.cpp +++ b/thirdparty/rive/source/core/field_types/core_bool_type.cpp @@ -6,4 +6,11 @@ using namespace rive; bool CoreBoolType::deserialize(BinaryReader& reader) { return reader.readByte() == 1; -} \ No newline at end of file +} + +#ifdef WITH_RIVE_TOOLS +bool CoreBoolType::deserializeRev(BinaryReader& reader) +{ + return deserialize(reader); +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/core/field_types/core_bytes_type.cpp b/thirdparty/rive/source/core/field_types/core_bytes_type.cpp index b2a1e5d90..7a1a582c5 100644 --- a/thirdparty/rive/source/core/field_types/core_bytes_type.cpp +++ b/thirdparty/rive/source/core/field_types/core_bytes_type.cpp @@ -6,4 +6,11 @@ using namespace rive; Span CoreBytesType::deserialize(BinaryReader& reader) { return reader.readBytes(); -} \ No newline at end of file +} + +#ifdef WITH_RIVE_TOOLS +Span CoreBytesType::deserializeRev(BinaryReader& reader) +{ + return reader.readBytes(reader.lengthInBytes()); +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/core/field_types/core_color_type.cpp b/thirdparty/rive/source/core/field_types/core_color_type.cpp index 2809d4fd7..4b1bc9c20 100644 --- a/thirdparty/rive/source/core/field_types/core_color_type.cpp +++ b/thirdparty/rive/source/core/field_types/core_color_type.cpp @@ -6,4 +6,11 @@ using namespace rive; int CoreColorType::deserialize(BinaryReader& reader) { return reader.readUint32(); -} \ No newline at end of file +} + +#ifdef WITH_RIVE_TOOLS +int CoreColorType::deserializeRev(BinaryReader& reader) +{ + return (int)reader.readVarUint64(); +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/core/field_types/core_double_type.cpp b/thirdparty/rive/source/core/field_types/core_double_type.cpp index 0c72e9761..24aca1094 100644 --- a/thirdparty/rive/source/core/field_types/core_double_type.cpp +++ b/thirdparty/rive/source/core/field_types/core_double_type.cpp @@ -6,4 +6,20 @@ using namespace rive; float CoreDoubleType::deserialize(BinaryReader& reader) { return reader.readFloat32(); -} \ No newline at end of file +} + +#ifdef WITH_RIVE_TOOLS +float CoreDoubleType::deserializeRev(BinaryReader& reader) +{ + size_t length = reader.lengthInBytes(); + if (length == 4) + { + return reader.readFloat32(); + } + else if (length == 8) + { + return (float)reader.readFloat64(); + } + return 0.0f; +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/core/field_types/core_string_type.cpp b/thirdparty/rive/source/core/field_types/core_string_type.cpp index c9d7ed01a..bb2e4c075 100644 --- a/thirdparty/rive/source/core/field_types/core_string_type.cpp +++ b/thirdparty/rive/source/core/field_types/core_string_type.cpp @@ -6,4 +6,12 @@ using namespace rive; std::string CoreStringType::deserialize(BinaryReader& reader) { return reader.readString(); -} \ No newline at end of file +} + +#ifdef WITH_RIVE_TOOLS +std::string CoreStringType::deserializeRev(BinaryReader& reader) +{ + size_t length = reader.lengthInBytes(); + return reader.readString(length); +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/core/field_types/core_uint_type.cpp b/thirdparty/rive/source/core/field_types/core_uint_type.cpp index 4009f5051..9602f20c7 100644 --- a/thirdparty/rive/source/core/field_types/core_uint_type.cpp +++ b/thirdparty/rive/source/core/field_types/core_uint_type.cpp @@ -7,3 +7,10 @@ unsigned int CoreUintType::deserialize(BinaryReader& reader) { return reader.readVarUintAs(); } + +#ifdef WITH_RIVE_TOOLS +unsigned int CoreUintType::deserializeRev(BinaryReader& reader) +{ + return deserialize(reader); +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/custom_property_container.cpp b/thirdparty/rive/source/custom_property_container.cpp new file mode 100644 index 000000000..2d4fe4fe3 --- /dev/null +++ b/thirdparty/rive/source/custom_property_container.cpp @@ -0,0 +1,37 @@ +#include "rive/component.hpp" +#include "rive/custom_property.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +void CustomPropertyContainer::syncCustomProperties() +{ + m_customProperties.clear(); + for (auto child : containerChildren()) + { + if (child->is()) + { + m_customProperties.push_back(child->as()); + } + } +} + +void CustomPropertyContainer::addProperty(CustomProperty* prop) +{ + auto it = + std::find(m_customProperties.begin(), m_customProperties.end(), prop); + if (it == m_customProperties.end()) + { + m_customProperties.push_back(prop); + } +} + +void CustomPropertyContainer::removeProperty(CustomProperty* prop) +{ + auto it = + std::find(m_customProperties.begin(), m_customProperties.end(), prop); + if (it != m_customProperties.end()) + { + m_customProperties.erase(it); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_target_value.cpp b/thirdparty/rive/source/data_bind/context/context_target_value.cpp new file mode 100644 index 000000000..d05b1efaa --- /dev/null +++ b/thirdparty/rive/source/data_bind/context/context_target_value.cpp @@ -0,0 +1,248 @@ +#include "rive/data_bind/context/context_target_value.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_asset_image.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" +#include "rive/data_bind/data_values/data_value_viewmodel.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_color_type.hpp" +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_string_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextTargetValue::~DataBindContextTargetValue() +{ + if (m_targetValue != nullptr) + { + delete m_targetValue; + } +}; + +void DataBindContextTargetValue::initialize(DataBind* dataBind) +{ + m_dataBind = dataBind; + switch (CoreRegistry::propertyFieldId(dataBind->propertyKey())) + { + case CoreUintType::id: + { + // Solos are a special case where the output type is relevant to + // apply the reverse conversion. In the furute we might need to + // traverse the full conversion chain to make sure we create the + // right type. + if (dataBind->propertyKey() == + SoloBase::activeComponentIdPropertyKey) + { + if (dataBind->sourceOutputType() == DataType::string) + { + m_targetValue = new DataValueString(); + } + else if (dataBind->sourceOutputType() == DataType::number) + { + m_targetValue = new DataValueNumber(); + } + else if (dataBind->sourceOutputType() == DataType::enumType) + { + m_targetValue = new DataValueInteger(); + } + } + else if (dataBind->source() != nullptr && + dataBind->source()->coreType() == + ViewModelInstanceAssetImageBase::typeKey) + { + m_targetValue = new DataValueAssetImage(); + } + else if (dataBind->source() != nullptr && + dataBind->source()->coreType() == + ViewModelInstanceViewModelBase::typeKey) + { + m_targetValue = new DataValueViewModel(); + } + else + { + m_targetValue = new DataValueInteger(); + } + } + break; + case CoreColorType::id: + { + m_targetValue = new DataValueColor(); + } + break; + case CoreDoubleType::id: + { + m_targetValue = new DataValueNumber(); + } + break; + case CoreStringType::id: + { + m_targetValue = new DataValueString(); + } + break; + case CoreBoolType::id: + { + m_targetValue = new DataValueBoolean(); + } + break; + default: + break; + } +} + +bool DataBindContextTargetValue::syncTargetValue() +{ + switch (CoreRegistry::propertyFieldId(m_dataBind->propertyKey())) + { + case CoreUintType::id: + { + if (m_dataBind->propertyKey() == + SoloBase::activeComponentIdPropertyKey && + m_dataBind->target() && m_dataBind->target()->is()) + { + auto target = m_dataBind->target()->as(); + if (m_dataBind->sourceOutputType() == DataType::string) + { + auto value = target->getActiveChildName(); + return updateValue(value); + } + else if (m_dataBind->sourceOutputType() == DataType::number) + { + auto value = (float)target->getActiveChildIndex(); + return updateValue(value); + } + else if (m_dataBind->sourceOutputType() == DataType::integer) + { + auto value = target->getActiveChildIndex(); + return updateValue(value); + } + else if (m_dataBind->sourceOutputType() == DataType::enumType) + { + auto activeChildName = target->getActiveChildName(); + if (m_dataBind->source() && + m_dataBind->source()->is()) + { + auto viewModelInstanceEnum = + m_dataBind->source()->as(); + if (viewModelInstanceEnum->viewModelProperty()) + { + auto enumProperty = + viewModelInstanceEnum->viewModelProperty() + ->as(); + if (enumProperty && enumProperty->dataEnum()) + { + auto dataEnum = enumProperty->dataEnum(); + auto index = + dataEnum->valueIndex(activeChildName); + return updateValue( + index); + } + } + } + } + } + else if (m_dataBind->target()->coreType() == + BindablePropertyAssetBase::typeKey) + { + auto value = CoreRegistry::getUint(m_dataBind->target(), + m_dataBind->propertyKey()); + auto fileAsset = m_dataBind->target() + ->as() + ->fileAsset(); + bool didChange = false; + if (updateValue(value)) + { + didChange = true; + } + if (fileAsset->renderImage() != + m_targetValue->as()->imageValue()) + { + m_targetValue->as()->imageValue( + fileAsset->renderImage()); + didChange = true; + } + return didChange; + } + else if (m_dataBind->target()->coreType() == + BindablePropertyViewModelBase::typeKey) + { + bool didChange = false; + auto viewModelInstance = m_dataBind->target() + ->as() + ->viewModelInstanceValue(); + if (m_targetValue->is() && + m_targetValue->as()->value() != + viewModelInstance) + { + m_targetValue->as()->value( + viewModelInstance); + didChange = true; + } + return didChange; + } + else if (m_dataBind->target()->coreType() == + ViewModelInstanceViewModelBase::typeKey) + { + bool didChange = false; + auto viewModelInstanceViewModel = + m_dataBind->target()->as(); + if (viewModelInstanceViewModel->referenceViewModelInstance() + .get() != + m_targetValue->as()->value()) + { + m_targetValue->as()->value( + viewModelInstanceViewModel->referenceViewModelInstance() + .get()); + didChange = true; + } + return didChange; + } + else + { + auto value = CoreRegistry::getUint(m_dataBind->target(), + m_dataBind->propertyKey()); + return updateValue(value); + } + } + break; + case CoreColorType::id: + { + auto value = CoreRegistry::getColor(m_dataBind->target(), + m_dataBind->propertyKey()); + return updateValue(value); + } + break; + case CoreDoubleType::id: + { + auto value = CoreRegistry::getDouble(m_dataBind->target(), + m_dataBind->propertyKey()); + return updateValue(value); + } + break; + case CoreStringType::id: + { + auto value = CoreRegistry::getString(m_dataBind->target(), + m_dataBind->propertyKey()); + return updateValue(value); + } + break; + case CoreBoolType::id: + { + auto value = CoreRegistry::getBool(m_dataBind->target(), + m_dataBind->propertyKey()); + return updateValue(value); + } + break; + default: + break; + } + return false; +} diff --git a/thirdparty/rive/source/data_bind/context/context_value.cpp b/thirdparty/rive/source/data_bind/context/context_value.cpp index 8bdfafed0..6c7a8d6cc 100644 --- a/thirdparty/rive/source/data_bind/context/context_value.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value.cpp @@ -11,13 +11,17 @@ #include "rive/data_bind/data_values/data_value_list.hpp" #include "rive/data_bind/data_values/data_value_symbol_list_index.hpp" #include "rive/data_bind/data_values/data_value_asset_image.hpp" +#include "rive/data_bind/data_values/data_value_artboard.hpp" +#include "rive/data_bind/data_values/data_value_viewmodel.hpp" #include "rive/generated/core_registry.hpp" +#include "rive/refcnt.hpp" using namespace rive; DataBindContextValue::DataBindContextValue(DataBind* dataBind) : m_dataBind(dataBind) { + m_targetValue.initialize(dataBind); auto source = dataBind->source(); if (source != nullptr) { @@ -43,12 +47,18 @@ DataBindContextValue::DataBindContextValue(DataBind* dataBind) : { auto viewmodelInstanceEnum = source->as(); + auto viewModelProperty = + viewmodelInstanceEnum->viewModelProperty(); auto viewModelPropertyEnum = - viewmodelInstanceEnum->viewModelProperty() - ->as(); + viewModelProperty != nullptr && + viewModelProperty->is() + ? viewModelProperty->as() + : nullptr; m_dataValue = new DataValueEnum(viewmodelInstanceEnum->propertyValue(), - viewModelPropertyEnum->dataEnum()); + viewModelPropertyEnum != nullptr + ? viewModelPropertyEnum->dataEnum() + : nullptr); } break; case ViewModelInstanceTriggerBase::typeKey: @@ -65,6 +75,13 @@ DataBindContextValue::DataBindContextValue(DataBind* dataBind) : m_dataValue = new DataValueAssetImage( source->as()->propertyValue()); break; + case ViewModelInstanceArtboardBase::typeKey: + m_dataValue = new DataValueArtboard( + source->as()->propertyValue()); + break; + case ViewModelInstanceViewModelBase::typeKey: + m_dataValue = new DataValueViewModel(); + break; default: m_dataValue = new DataValue(); } @@ -122,6 +139,16 @@ void DataBindContextValue::syncSourceValue() m_dataValue->as()->value( source->as()->propertyValue()); break; + case ViewModelInstanceArtboardBase::typeKey: + m_dataValue->as()->value( + source->as()->propertyValue()); + break; + case ViewModelInstanceViewModelBase::typeKey: + m_dataValue->as()->value( + source->as() + ->referenceViewModelInstance() + .get()); + break; } } } @@ -138,88 +165,71 @@ void DataBindContextValue::applyToSource(Core* component, calculateValueAndApply(targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + ViewModelInstanceNumber>(isMainDirection); } break; case ViewModelInstanceStringBase::typeKey: { calculateValueAndApply(targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + ViewModelInstanceString>(isMainDirection); } break; case ViewModelInstanceColorBase::typeKey: { calculateValueAndApply( - targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + isMainDirection); } break; case ViewModelInstanceBooleanBase::typeKey: { calculateValueAndApply(targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + ViewModelInstanceBoolean>(isMainDirection); } break; case ViewModelInstanceEnumBase::typeKey: { - calculateValueAndApply(targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + ViewModelInstanceEnum>(isMainDirection); } break; case ViewModelInstanceTriggerBase::typeKey: { - calculateValueAndApply(targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + ViewModelInstanceTrigger>(isMainDirection); } break; case ViewModelInstanceSymbolListIndexBase::typeKey: { - calculateValueAndApply( - targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + isMainDirection); } break; case ViewModelInstanceAssetImageBase::typeKey: { - calculateValueAndApply(targetValue(), - isMainDirection, - m_dataBind, - component, - propertyKey); + ViewModelInstanceAssetImage>( + isMainDirection); + } + break; + case ViewModelInstanceArtboardBase::typeKey: + { + calculateValueAndApply(isMainDirection); + } + break; + case ViewModelInstanceViewModelBase::typeKey: + { + calculateValueAndApply(isMainDirection); } break; } diff --git a/thirdparty/rive/source/data_bind/context/context_value_any.cpp b/thirdparty/rive/source/data_bind/context/context_value_any.cpp new file mode 100644 index 000000000..818231f3d --- /dev/null +++ b/thirdparty/rive/source/data_bind/context/context_value_any.cpp @@ -0,0 +1,81 @@ +#include "rive/data_bind/context/context_value_any.hpp" +#include "rive/generated/core_registry.hpp" +#include + +using namespace rive; + +DataBindContextValueAny::DataBindContextValueAny(DataBind* dataBind) : + DataBindContextValue(dataBind) +{} + +void DataBindContextValueAny::apply(Core* target, + uint32_t propertyKey, + bool isMainDirection) +{ + syncSourceValue(); + auto dataValue = + calculateUntypedDataValue(m_dataValue, isMainDirection, m_dataBind); + switch (CoreRegistry::propertyFieldId(propertyKey)) + { + case CoreDoubleType::id: + if (dataValue->is()) + { + CoreRegistry::setDouble( + target, + propertyKey, + dataValue->as()->value()); + } + break; + case CoreUintType::id: + if (dataValue->is()) + { + auto value = dataValue->as()->value(); + if (target && target->is()) + { + target->as()->updateByIndex( + (size_t)std::round(value)); + } + else + { + int rounded = value < 0 ? 0 : std::round(value); + CoreRegistry::setUint(target, propertyKey, rounded); + } + } + else if (dataValue->is()) + { + if (target && target->is()) + { + target->as()->updateByName( + dataValue->as()->value()); + } + } + break; + case CoreStringType::id: + if (dataValue->is()) + { + CoreRegistry::setString( + target, + propertyKey, + dataValue->as()->value()); + } + break; + case CoreBoolType::id: + if (dataValue->is()) + { + CoreRegistry::setBool( + target, + propertyKey, + dataValue->as()->value()); + } + break; + case CoreColorType::id: + if (dataValue->is()) + { + CoreRegistry::setColor( + target, + propertyKey, + dataValue->as()->value()); + } + break; + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_artboard.cpp b/thirdparty/rive/source/data_bind/context/context_value_artboard.cpp new file mode 100644 index 000000000..86fd666b7 --- /dev/null +++ b/thirdparty/rive/source/data_bind/context/context_value_artboard.cpp @@ -0,0 +1,38 @@ +#include "rive/data_bind/context/context_value_artboard.hpp" +#include "rive/data_bind/data_values/data_value_artboard.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" +#include "rive/generated/core_registry.hpp" +#include "rive/file.hpp" +#include "rive/artboard_referencer.hpp" + +using namespace rive; + +DataBindContextValueArtboard::DataBindContextValueArtboard(DataBind* dataBind) : + DataBindContextValue(dataBind) +{} + +void DataBindContextValueArtboard::apply(Core* target, + uint32_t propertyKey, + bool isMainDirection) +{ + syncSourceValue(); + auto source = m_dataBind->source(); + if (source != nullptr && source->is()) + { + auto artboardReferencer = ArtboardReferencer::from(target); + if (artboardReferencer) + { + + artboardReferencer->updateArtboard( + source->as()); + } + else + { + auto value = + calculateValue(m_dataValue, + isMainDirection, + m_dataBind); + CoreRegistry::setUint(target, propertyKey, value); + } + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_asset_image.cpp b/thirdparty/rive/source/data_bind/context/context_value_asset_image.cpp index 6fceef286..7dd0c3434 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_asset_image.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_asset_image.cpp @@ -10,7 +10,7 @@ DataBindContextValueAssetImage::DataBindContextValueAssetImage( DataBindContextValue(dataBind) {} -ImageAsset* DataBindContextValueAssetImage::fileAsset() +rcp DataBindContextValueAssetImage::fileAsset() { auto file = m_dataBind->file(); auto source = m_dataBind->source(); @@ -20,9 +20,9 @@ ImageAsset* DataBindContextValueAssetImage::fileAsset() auto asset = file->asset( source->as()->propertyValue()); - if (asset != nullptr) + if (asset != nullptr && asset->is()) { - return asset->as(); + return static_rcp_cast(asset); } } return nullptr; @@ -46,26 +46,22 @@ void DataBindContextValueAssetImage::apply(Core* target, source->as()->asset()); } } - else + else if (target->is()) { auto source = m_dataBind->source(); + target->as()->imageValue( + source->as()->asset()->renderImage()); CoreRegistry::setUint( target, propertyKey, source->as()->propertyValue()); } -} - -bool DataBindContextValueAssetImage::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getUint(target, propertyKey); - - if (m_previousValue != value) + else { - m_previousValue = value; - m_targetDataValue.value(value); - return true; + auto source = m_dataBind->source(); + CoreRegistry::setUint( + target, + propertyKey, + source->as()->propertyValue()); } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_boolean.cpp b/thirdparty/rive/source/data_bind/context/context_value_boolean.cpp index d4b209b88..3b5f4832f 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_boolean.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_boolean.cpp @@ -17,18 +17,4 @@ void DataBindContextValueBoolean::apply(Core* target, isMainDirection, m_dataBind); CoreRegistry::setBool(target, propertyKey, value); -} - -bool DataBindContextValueBoolean::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getBool(target, propertyKey); - - if (m_previousValue != value) - { - m_previousValue = value; - m_targetDataValue.value(value); - return true; - } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_color.cpp b/thirdparty/rive/source/data_bind/context/context_value_color.cpp index 40d95ebc1..764f3dfd6 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_color.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_color.cpp @@ -17,18 +17,4 @@ void DataBindContextValueColor::apply(Core* target, isMainDirection, m_dataBind); CoreRegistry::setColor(target, propertyKey, value); -} - -bool DataBindContextValueColor::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getColor(target, propertyKey); - - if (m_previousValue != value) - { - m_previousValue = value; - m_targetDataValue.value(value); - return true; - } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_enum.cpp b/thirdparty/rive/source/data_bind/context/context_value_enum.cpp index 3b81b0213..e9610d82e 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_enum.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_enum.cpp @@ -6,13 +6,7 @@ using namespace rive; DataBindContextValueEnum::DataBindContextValueEnum(DataBind* dataBind) : DataBindContextValue(dataBind) -{ - auto source = m_dataBind->source(); - auto viewmodelInstanceEnum = source->as(); - auto viewModelPropertyEnum = - viewmodelInstanceEnum->viewModelProperty()->as(); - m_targetDataValue.dataEnum(viewModelPropertyEnum->dataEnum()); -} +{} void DataBindContextValueEnum::apply(Core* target, uint32_t propertyKey, @@ -23,19 +17,31 @@ void DataBindContextValueEnum::apply(Core* target, auto value = calculateValue(m_dataValue, isMainDirection, m_dataBind); - CoreRegistry::setUint(target, propertyKey, value); -} - -bool DataBindContextValueEnum::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getUint(target, propertyKey); - - if (m_previousValue != value) + switch (CoreRegistry::propertyFieldId(propertyKey)) { - m_previousValue = value; - m_targetDataValue.value(value); - return true; + case CoreUintType::id: + { + if (target && target->is()) + { + if (m_dataValue->is()) + { + auto dataValueEnum = m_dataValue->as(); + auto dataEnum = dataValueEnum->dataEnum(); + if (dataEnum) + { + auto valueString = dataEnum->value(value); + target->as()->updateByName(valueString); + } + } + } + else + { + CoreRegistry::setUint(target, propertyKey, value); + } + break; + } + default: + CoreRegistry::setUint(target, propertyKey, value); + break; } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_list.cpp b/thirdparty/rive/source/data_bind/context/context_value_list.cpp index 2242e5efb..1dff72f19 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_list.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_list.cpp @@ -14,17 +14,17 @@ void DataBindContextValueList::apply(Core* target, bool isMainDirection) { syncSourceValue(); - auto value = - calculateValue*>( - m_dataValue, - isMainDirection, - m_dataBind); + auto value = calculateValue>*>( + m_dataValue, + isMainDirection, + m_dataBind); if (target != nullptr) { auto consumer = DataBindListItemConsumer::from(target); if (consumer != nullptr) { - consumer->updateList(m_dataBind->propertyKey(), value); + consumer->updateList(value); } } } diff --git a/thirdparty/rive/source/data_bind/context/context_value_number.cpp b/thirdparty/rive/source/data_bind/context/context_value_number.cpp index 5a4fd7ede..2250f8394 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_number.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_number.cpp @@ -22,35 +22,16 @@ void DataBindContextValueNumber::apply(Core* target, CoreRegistry::setDouble(target, propertyKey, value); break; case CoreUintType::id: - int rounded = value < 0 ? 0 : std::round(value); - CoreRegistry::setUint(target, propertyKey, rounded); - break; - } -} -bool DataBindContextValueNumber::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - float value = 0; - switch (CoreRegistry::propertyFieldId(propertyKey)) - { - case CoreDoubleType::id: - { - value = CoreRegistry::getDouble(target, propertyKey); - } - break; - case CoreUintType::id: - { - value = (float)CoreRegistry::getUint(target, propertyKey); + if (target && target->is()) + { + target->as()->updateByIndex((size_t)std::round(value)); + } + else + { + int rounded = value < 0 ? 0 : std::round(value); + CoreRegistry::setUint(target, propertyKey, rounded); + } break; - } - } - if (m_previousValue != value) - { - m_previousValue = value; - - m_targetDataValue.value(value); - return true; } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_string.cpp b/thirdparty/rive/source/data_bind/context/context_value_string.cpp index e4b8c6c42..2f9e55ec6 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_string.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_string.cpp @@ -16,19 +16,18 @@ void DataBindContextValueString::apply(Core* target, auto value = calculateValue(m_dataValue, isMainDirection, m_dataBind); - CoreRegistry::setString(target, propertyKey, value); -} - -bool DataBindContextValueString::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getString(target, propertyKey); - - if (m_previousValue != value) + switch (CoreRegistry::propertyFieldId(propertyKey)) { - m_previousValue = value; - m_targetDataValue.value(value); - return true; + case CoreUintType::id: + { + if (target && target->is()) + { + target->as()->updateByName(value); + } + break; + } + default: + CoreRegistry::setString(target, propertyKey, value); + break; } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_symbol_list_index.cpp b/thirdparty/rive/source/data_bind/context/context_value_symbol_list_index.cpp index 1e34cc490..6320c8756 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_symbol_list_index.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_symbol_list_index.cpp @@ -27,18 +27,4 @@ void DataBindContextValueSymbolListIndex::apply(Core* target, CoreRegistry::setUint(target, propertyKey, value); break; } -} - -bool DataBindContextValueSymbolListIndex::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getUint(target, propertyKey); - - if (m_previousValue != value) - { - m_previousValue = value; - m_targetDataValue.value(value); - return true; - } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_trigger.cpp b/thirdparty/rive/source/data_bind/context/context_value_trigger.cpp index e4a937612..f9d5a84ec 100644 --- a/thirdparty/rive/source/data_bind/context/context_value_trigger.cpp +++ b/thirdparty/rive/source/data_bind/context/context_value_trigger.cpp @@ -17,18 +17,4 @@ void DataBindContextValueTrigger::apply(Core* target, isMainDirection, m_dataBind); CoreRegistry::setUint(target, propertyKey, value); -} - -bool DataBindContextValueTrigger::syncTargetValue(Core* target, - uint32_t propertyKey) -{ - auto value = CoreRegistry::getUint(target, propertyKey); - - if (m_previousValue != value) - { - m_previousValue = value; - m_targetDataValue.value(value); - return true; - } - return false; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/context/context_value_viewmodel.cpp b/thirdparty/rive/source/data_bind/context/context_value_viewmodel.cpp new file mode 100644 index 000000000..e4591ce17 --- /dev/null +++ b/thirdparty/rive/source/data_bind/context/context_value_viewmodel.cpp @@ -0,0 +1,43 @@ +#include "rive/data_bind/context/context_value_viewmodel.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" +#include "rive/generated/data_bind/bindable_property_id_base.hpp" +#include "rive/data_bind/data_bind_viewmodel_consumer.hpp" +#include "rive/generated/core_registry.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" + +using namespace rive; + +DataBindContextValueViewModel::DataBindContextValueViewModel( + DataBind* dataBind) : + DataBindContextValue(dataBind) +{} + +void DataBindContextValueViewModel::apply(Core* target, + uint32_t propertyKey, + bool isMainDirection) +{ + syncSourceValue(); + auto value = + calculateValue(m_dataValue, + isMainDirection, + m_dataBind); + if (target != nullptr) + { + auto consumer = DataBindViewModelConsumer::from(target); + if (consumer != nullptr) + { + consumer->updateViewModel(value); + } + else if (target->is()) + { + auto bindable = target->as(); + bindable->viewModelInstanceValue(value); + CoreRegistry::setUint( + target, + BindablePropertyIdBase::propertyValuePropertyKey, + value != nullptr ? ViewModelInstance::pointerKey(value) + : BindablePropertyViewModel::defaultValue); + } + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/converters/data_converter.cpp b/thirdparty/rive/source/data_bind/converters/data_converter.cpp index 1dea5b62f..ed9d9f3e0 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter.cpp @@ -7,13 +7,7 @@ using namespace rive; -DataConverter::~DataConverter() -{ - for (auto dataBind : m_dataBinds) - { - delete dataBind; - } -} +DataConverter::~DataConverter() { deleteDataBinds(); } StatusCode DataConverter::import(ImportStack& importStack) { @@ -28,53 +22,32 @@ StatusCode DataConverter::import(ImportStack& importStack) return Super::import(importStack); } -void DataConverter::addDataBind(DataBind* dataBind) -{ - m_dataBinds.push_back(dataBind); -} - void DataConverter::bindFromContext(DataContext* dataContext, DataBind* dataBind) { m_parentDataBind = dataBind; - for (auto dataBind : m_dataBinds) - { - if (dataBind->is()) - { - - dataBind->as()->bindFromContext(dataContext); - } - } + bindDataBindsFromContext(dataContext); } -void DataConverter::unbind() +void DataConverter::unbind() { unbindDataBinds(); } + +void DataConverter::markConverterDirty() { - for (auto dataBind : m_dataBinds) + if (m_parentDataBind != nullptr) { - dataBind->unbind(); + m_parentDataBind->addDirt(ComponentDirt::Dependents | + ComponentDirt::Bindings, + false); } } -void DataConverter::markConverterDirty() +void DataConverter::addDirtyDataBind(DataBind* dataBind) { - m_parentDataBind->addDirt(ComponentDirt::Dependents | - ComponentDirt::Bindings, - false); + markConverterDirty(); + DataBindContainer::addDirtyDataBind(dataBind); } -void DataConverter::update() -{ - for (auto dataBind : m_dataBinds) - { - auto d = dataBind->dirt(); - if (d == ComponentDirt::None) - { - continue; - } - dataBind->dirt(ComponentDirt::None); - dataBind->update(d); - } -} +void DataConverter::update() { updateDataBinds(false); } void DataConverter::copy(const DataConverter& object) { diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_formula.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_formula.cpp index 5a1392b5b..326b15ba9 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_formula.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_formula.cpp @@ -10,14 +10,17 @@ #include "rive/data_bind/converters/formula/formula_token_parenthesis_open.hpp" #include "rive/data_bind/converters/formula/formula_token_parenthesis_close.hpp" #include "rive/animation/arithmetic_operation.hpp" +#include "rive/random_mode.hpp" #include "rive/function_type.hpp" #include "rive/math/math_types.hpp" +#include "rive/math/random.hpp" #include using namespace rive; DataConverterFormula::~DataConverterFormula() { + unbind(); if (m_isInstance) { @@ -34,6 +37,8 @@ DataConverterFormula::~DataConverterFormula() delete token; } } + m_outputQueue.clear(); + m_tokens.clear(); } int DataConverterFormula::getPrecedence(FormulaToken* token) @@ -71,7 +76,7 @@ int DataConverterFormula::getPrecedence(FormulaToken* token) return 0; } -void DataConverterFormula::initialize() +void DataConverterFormula::calculateFormula() { // convert the formula to Reverse Polish Notation using a version of // the Shunting yard algorithm @@ -218,16 +223,14 @@ float DataConverterFormula::applyOperation(float left, float DataConverterFormula::getRandom(int randomIndex) { -#ifdef TESTING - int testInt = 0; -#endif + if (randomModeValue() == static_cast(RandomMode::always)) + { + return RandomProvider::generateRandomFloat(); + } + while (m_randoms.size() <= randomIndex) { -#ifdef TESTING - m_randoms.push_back(testInt++); -#else - m_randoms.push_back((float)rand() / float(RAND_MAX)); -#endif + m_randoms.push_back(RandomProvider::generateRandomFloat()); } return m_randoms[randomIndex]; } @@ -495,7 +498,7 @@ void DataConverterFormula::addOutputToken(FormulaToken* token, Core* DataConverterFormula::clone() const { auto cloned = DataConverterFormulaBase::clone()->as(); - // Instead of cloning all tookens, we can clone the processed tokens that + // Instead of cloning all tokens, we can clone the processed tokens that // will be used during conversion for (auto& token : m_outputQueue) { @@ -506,6 +509,15 @@ Core* DataConverterFormula::clone() const : tokenArgumentsCountSearch->second; auto clonedToken = token->clone()->as(); cloned->addOutputToken(clonedToken, argumentsCount); + int index = 0; + for (auto& dataBind : dataBinds()) + { + if (dataBind->target() == token) + { + cloned->dataBinds()[index]->target(clonedToken); + } + index++; + } } cloned->isInstance(true); return cloned; @@ -514,24 +526,27 @@ Core* DataConverterFormula::clone() const void DataConverterFormula::bindFromContext(DataContext* dataContext, DataBind* dataBind) { - for (auto& token : m_outputQueue) + DataConverter::bindFromContext(dataContext, dataBind); + if (dataBind && dataBind->source()) { - token->bindFromContext(dataContext, dataBind); + m_source = ref_rcp(dataBind->source()); + m_source->addDependent(this); } } -void DataConverterFormula::unbind() +void DataConverterFormula::addDirt(ComponentDirt value, bool recurse) { - for (auto& token : m_outputQueue) + if (randomModeValue() == static_cast(RandomMode::sourceChange)) { - token->unbind(); + m_randoms.clear(); } } -void DataConverterFormula::update() +void DataConverterFormula::unbind() { - for (auto& token : m_outputQueue) + if (m_source) { - token->update(); + m_source->removeDependent(this); + m_source = nullptr; } -} \ No newline at end of file +} diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_group.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_group.cpp index 94ddb0c5d..904093b21 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_group.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_group.cpp @@ -63,6 +63,7 @@ Core* DataConverterGroup::clone() const void DataConverterGroup::bindFromContext(DataContext* dataContext, DataBind* dataBind) { + DataConverter::bindFromContext(dataContext, dataBind); for (auto& item : m_items) { auto converter = item->converter(); @@ -97,6 +98,18 @@ void DataConverterGroup::update() } } +void DataConverterGroup::reset() +{ + for (auto& item : m_items) + { + auto converter = item->converter(); + if (converter != nullptr) + { + converter->reset(); + } + } +} + bool DataConverterGroup::advance(float elapsedSeconds) { bool didUpdate = false; diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_interpolator.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_interpolator.cpp index 096fa3052..21fa6e1bb 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_interpolator.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_interpolator.cpp @@ -1,40 +1,48 @@ #include "rive/math/math_types.hpp" #include "rive/data_bind/converters/data_converter_interpolator.hpp" #include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" using namespace rive; -void DataConverterInterpolator::copy( - const DataConverterInterpolatorBase& object) +void InterpolatorAnimationData::copy(const InterpolatorAnimationData& source) { - interpolator(object.as()->interpolator()); - DataConverterInterpolatorBase::copy(object); + source.from->copyValue(from); + source.to->copyValue(to); + elapsedSeconds = source.elapsedSeconds; } -InterpolatorAnimationData* DataConverterInterpolator::currentAnimationData() +void InterpolatorAdvancer::dispose() { - return m_isSmoothingAnimation ? &m_animationDataB : &m_animationDataA; + m_animationDataA.dispose(); + m_animationDataB.dispose(); + if (m_currentValue != nullptr) + { + delete m_currentValue; + m_currentValue = nullptr; + } } -void DataConverterInterpolator::interpolator(KeyFrameInterpolator* interpolator) +InterpolatorAnimationData* InterpolatorAdvancer::currentAnimationData() { - m_interpolator = interpolator; + return m_isSmoothingAnimation ? &m_animationDataB : &m_animationDataA; } -void DataConverterInterpolator::advanceAnimationData(float elapsedTime) +void InterpolatorAdvancer::advanceAnimationData(float elapsedTime) { auto animationData = currentAnimationData(); if (m_isSmoothingAnimation) { float f = std::fmin(1.0f, - duration() > 0 - ? m_animationDataA.elapsedSeconds / duration() + m_converter->duration() > 0 + ? m_animationDataA.elapsedSeconds / + m_converter->duration() : 1.0f); - if (m_interpolator != nullptr) + if (m_converter->interpolator() != nullptr) { - f = m_interpolator->transform(f); + f = m_converter->interpolator()->transform(f); } - m_animationDataB.from = m_animationDataA.interpolate(f); + m_animationDataA.interpolate(f, m_animationDataB.from); if (f == 1) { m_animationDataA.copy(m_animationDataB); @@ -45,9 +53,9 @@ void DataConverterInterpolator::advanceAnimationData(float elapsedTime) m_animationDataA.elapsedSeconds += elapsedTime; } } - if (animationData->elapsedSeconds >= duration()) + if (animationData->elapsedSeconds >= m_converter->duration()) { - m_currentValue = animationData->to; + animationData->to->copyValue(m_currentValue); if (m_isSmoothingAnimation) { @@ -62,77 +70,121 @@ void DataConverterInterpolator::advanceAnimationData(float elapsedTime) } return; } - float f = std::fmin( - 1.0f, - duration() > 0 ? animationData->elapsedSeconds / duration() : 1.0f); - if (m_interpolator != nullptr) - { - f = m_interpolator->transform(f); - } - auto current = animationData->interpolate(f); - if (m_currentValue != current) + animationData->elapsedSeconds += elapsedTime; + float f = + std::fmin(1.0f, + m_converter->duration() > 0 + ? animationData->elapsedSeconds / m_converter->duration() + : 1.0f); + if (m_converter->interpolator() != nullptr) { - m_currentValue = current; + f = m_converter->interpolator()->transform(f); } - - animationData->elapsedSeconds += elapsedTime; + animationData->interpolate(f, m_currentValue); } -bool DataConverterInterpolator::advance(float elapsedTime) +bool InterpolatorAdvancer::advance(float elapsedTime) { auto animationData = currentAnimationData(); - if (animationData->to == m_currentValue) + if (animationData->to->compare(m_currentValue) || elapsedTime == 0) { return false; } + auto prevTime = animationData->elapsedSeconds; advanceAnimationData(elapsedTime); - if (animationData->elapsedSeconds < duration()) + + if (prevTime < m_converter->duration()) + { + m_converter->markConverterDirty(); + } + if (animationData->elapsedSeconds < m_converter->duration()) { - markConverterDirty(); return true; } return false; } +DataConverterInterpolator::~DataConverterInterpolator() +{ + if (m_output != nullptr) + { + delete m_output; + } + m_advancer.dispose(); +} + +void DataConverterInterpolator::copy( + const DataConverterInterpolatorBase& object) +{ + interpolator(object.as()->interpolator()); + DataConverterInterpolatorBase::copy(object); +} + +void DataConverterInterpolator::interpolator(KeyFrameInterpolator* interpolator) +{ + m_interpolator = interpolator; +} + +bool DataConverterInterpolator::advance(float elapsedTime) +{ + // Advance can be called multiple times in a single frame. + // We want to make sure that two advances with time > 0 have elapsed before + // considering the state as second frame. + if (m_advanceCount < 2 && elapsedTime > 0) + { + m_advanceCount++; + } + if (!m_advancer.initialized()) + { + return true; + } + return m_advancer.advance(elapsedTime); +} + DataValue* DataConverterInterpolator::convert(DataValue* input, DataBind* dataBind) { - if (input->is()) + if (duration() == 0 && m_advancer.initialized()) + { + m_advancer.resetToStart(input); + return input; + } + if (!m_advancer.initialized()) { - auto animationData = currentAnimationData(); - auto numberInput = input->as(); - if (m_isFirstRun) + if (input->is()) { - animationData->from = numberInput->value(); - animationData->to = numberInput->value(); - m_currentValue = numberInput->value(); - m_isFirstRun = false; + startAdvancer(); + } + else if (input->is()) + { + startAdvancer(); + } + else + { + return input; + } + } + if (m_output != nullptr && + (input->is() || input->is())) + { + if (isFirstRun()) + { + m_advancer.resetValues(input); } else { - if (animationData->to != numberInput->value()) - { - if (animationData->elapsedSeconds != 0) - { - if (m_isSmoothingAnimation) - { - m_animationDataA.copy(m_animationDataB); - } - m_isSmoothingAnimation = true; - } - else - { - m_isSmoothingAnimation = false; - } - animationData = currentAnimationData(); - animationData->from = m_currentValue; - animationData->to = numberInput->value(); - animationData->elapsedSeconds = 0; - } + m_advancer.updateValues(input); } - m_output.value(m_currentValue); + m_advancer.copyCurrentValue(m_output); + return m_output; } - return &m_output; + return input; +} + +void DataConverterInterpolator::reset() +{ + m_advanceCount = 0; + m_advancer.reset(); } DataValue* DataConverterInterpolator::reverseConvert(DataValue* input, @@ -142,10 +194,3 @@ DataValue* DataConverterInterpolator::reverseConvert(DataValue* input, } void DataConverterInterpolator::durationChanged() { markConverterDirty(); } - -void InterpolatorAnimationData::copy(const InterpolatorAnimationData& source) -{ - from = source.from; - to = source.to; - elapsedSeconds = source.elapsedSeconds; -} diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_list_to_length.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_list_to_length.cpp new file mode 100644 index 000000000..49dacf321 --- /dev/null +++ b/thirdparty/rive/source/data_bind/converters/data_converter_list_to_length.cpp @@ -0,0 +1,21 @@ +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_list_to_length.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_list.hpp" + +using namespace rive; + +DataValue* DataConverterListToLength::convert(DataValue* input, + DataBind* dataBind) +{ + if (input->is()) + { + size_t length = input->as()->value()->size(); + m_output.value((float)length); + } + else + { + m_output.value(DataValueNumber::defaultValue); + } + return &m_output; +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_number_to_list.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_number_to_list.cpp index e1e7df280..2d286c26e 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_number_to_list.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_number_to_list.cpp @@ -7,14 +7,6 @@ using namespace rive; -DataConverterNumberToList::~DataConverterNumberToList() -{ - for (auto& item : m_listItems) - { - item->unref(); - } -} - DataValue* DataConverterNumberToList::convert(DataValue* input, DataBind* dataBind) { @@ -32,12 +24,11 @@ DataValue* DataConverterNumberToList::convert(DataValue* input, auto viewModel = m_file->viewModel(viewModelId()); if (count > m_listItems.size()) { - auto defaultInstance = viewModel->defaultInstance(); while (m_listItems.size() < count) { - auto item = new ViewModelInstanceListItem(); - auto copy = rcp( - defaultInstance->clone()->as()); + auto item = make_rcp(); + auto copy = + m_file->createDefaultViewModelInstance(viewModel); item->viewModelInstance(copy); m_listItems.push_back(item); } @@ -46,9 +37,7 @@ DataValue* DataConverterNumberToList::convert(DataValue* input, { while (m_listItems.size() > count) { - auto item = m_listItems.back(); m_listItems.pop_back(); - item->unref(); } } } diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_operation_viewmodel.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_operation_viewmodel.cpp index a13257878..ceef60726 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_operation_viewmodel.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_operation_viewmodel.cpp @@ -48,6 +48,7 @@ void DataConverterOperationViewModel::copySourcePathIds( void DataConverterOperationViewModel::bindFromContext(DataContext* dataContext, DataBind* dataBind) { + DataConverter::bindFromContext(dataContext, dataBind); auto propertyValue = dataContext->getViewModelProperty(m_SourcePathIdsBuffer); if (propertyValue != nullptr && diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_string_pad.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_string_pad.cpp index 8ff34af70..31aefeb2e 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_string_pad.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_string_pad.cpp @@ -10,7 +10,7 @@ DataValue* DataConverterStringPad::convert(DataValue* input, DataBind* dataBind) { auto inputValue = input->as()->value(); auto inputLength = inputValue.size(); - if (inputLength < length()) + if (inputLength < length() && text() != "") { auto padPattern = text(); auto padLength = padPattern.size(); diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_to_number.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_to_number.cpp new file mode 100644 index 000000000..186abc312 --- /dev/null +++ b/thirdparty/rive/source/data_bind/converters/data_converter_to_number.cpp @@ -0,0 +1,77 @@ +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_to_number.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_enum.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" +#include "rive/data_bind/data_values/data_value_trigger.hpp" +#include "rive/data_bind/data_values/data_value_symbol_list_index.hpp" +#include "rive/animation/data_converter_to_string_flags.hpp" +#include "rive/data_bind/converters/data_converter_string_remove_zeros.hpp" + +using namespace rive; + +// Not supported for now. We need to find a way to match the output of dart +// with the output of cpp +DataValue* DataConverterToNumber::convertString(DataValueString* input) +{ + auto value = input->value(); + errno = 0; // Clear errno before the call + float v = std::atof(value.c_str()); + if (errno == 0) + { + m_output.value(v); + } + return &m_output; +} + +DataValue* DataConverterToNumber::convertColor(DataValueColor* input) +{ + auto colorValue = input->value(); + m_output.value(static_cast(colorValue)); + return &m_output; +} + +DataValue* DataConverterToNumber::convertEnum(DataValueEnum* input) +{ + auto index = input->as()->value(); + m_output.value(float(index)); + return &m_output; +} + +DataValue* DataConverterToNumber::convert(DataValue* input, DataBind* dataBind) +{ + if (input->is()) + { + return convertString(input->as()); + } + else if (input->is()) + { + return convertEnum(input->as()); + } + else if (input->is()) + { + m_output.value(input->as()->value()); + } + else if (input->is()) + { + return convertColor(input->as()); + } + else if (input->is()) + { + + auto value = input->as()->value(); + m_output.value(value ? 1.0f : 0.0f); + } + else if (input->is()) + { + auto value = input->as()->value(); + m_output.value(float(value)); + } + else + { + m_output.value(DataValueNumber::defaultValue); + } + return &m_output; +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_to_string.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_to_string.cpp index 9c190514f..88ff4b38e 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_to_string.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_to_string.cpp @@ -14,6 +14,32 @@ using namespace rive; +std::string DataConverterToString::formatWithCommas(std::string& num) +{ + // Split integer and fractional parts + std::string intPart, fracPart; + size_t dotPos = num.find('.'); + if (dotPos != std::string::npos) + { + intPart = num.substr(0, dotPos); + fracPart = num.substr(dotPos); // keep the '.' too + } + else + { + intPart = num; + } + + // Insert commas into the integer part + int insertPosition = (int)intPart.length() - 3; + while (insertPosition > 0 && isdigit(intPart[insertPosition - 1])) + { + intPart.insert(insertPosition, ","); + insertPosition -= 3; + } + + return intPart + fracPart; +} + DataValue* DataConverterToString::convertNumber(DataValueNumber* input) { auto flagsValue = static_cast(flags()); @@ -35,6 +61,11 @@ DataValue* DataConverterToString::convertNumber(DataValueNumber* input) { outputValue = DataConverterStringRemoveZeros::removeZeros(outputValue); } + if ((flagsValue & DataConverterToStringFlags::FormatWithCommas) == + DataConverterToStringFlags::FormatWithCommas) + { + outputValue = formatWithCommas(outputValue); + } m_output.value(outputValue); return &m_output; } @@ -154,9 +185,12 @@ DataValue* DataConverterToString::convert(DataValue* input, DataBind* dataBind) else if (input->is()) { auto dataEnum = input->as()->dataEnum(); - auto index = input->as()->value(); - auto enumValue = dataEnum->value(index); - m_output.value(enumValue); + if (dataEnum) + { + auto index = input->as()->value(); + auto enumValue = dataEnum->value(index); + m_output.value(enumValue); + } } else if (input->is()) { diff --git a/thirdparty/rive/source/data_bind/converters/data_converter_trigger.cpp b/thirdparty/rive/source/data_bind/converters/data_converter_trigger.cpp index 5b12b8ff1..0d45a9400 100644 --- a/thirdparty/rive/source/data_bind/converters/data_converter_trigger.cpp +++ b/thirdparty/rive/source/data_bind/converters/data_converter_trigger.cpp @@ -1,14 +1,15 @@ #include "rive/math/math_types.hpp" #include "rive/data_bind/converters/data_converter_trigger.hpp" #include "rive/data_bind/data_values/data_value_trigger.hpp" +#include "rive/data_bind/data_values/data_value_integer.hpp" using namespace rive; DataValue* DataConverterTrigger::convert(DataValue* input, DataBind* dataBind) { - if (input->is()) + if (input->is()) { - uint32_t inputValue = input->as()->value(); + uint32_t inputValue = input->as()->value(); m_output.value(inputValue + 1); } else diff --git a/thirdparty/rive/source/data_bind/converters/formula/formula_token.cpp b/thirdparty/rive/source/data_bind/converters/formula/formula_token.cpp index d6972b70f..8902807b6 100644 --- a/thirdparty/rive/source/data_bind/converters/formula/formula_token.cpp +++ b/thirdparty/rive/source/data_bind/converters/formula/formula_token.cpp @@ -6,82 +6,24 @@ using namespace rive; -FormulaToken::~FormulaToken() -{ - for (auto dataBind : m_dataBinds) - { - delete dataBind; - } -} - StatusCode FormulaToken::import(ImportStack& importStack) { - auto dataConveterFormulaImporter = + auto dataConverterFormulaImporter = importStack.latest( DataConverterFormulaBase::typeKey); - if (dataConveterFormulaImporter == nullptr) + if (dataConverterFormulaImporter == nullptr) { return StatusCode::MissingObject; } - dataConveterFormulaImporter->formula()->addToken(this); + dataConverterFormulaImporter->formula()->addToken(this); + m_formula = dataConverterFormulaImporter->formula(); return Super::import(importStack); } void FormulaToken::addDataBind(DataBind* dataBind) { - m_dataBinds.push_back(dataBind); -} - -void FormulaToken::markDirty() -{ - m_parentDataBind->addDirt(ComponentDirt::Dependents | - ComponentDirt::Bindings, - false); -} - -void FormulaToken::bindFromContext(DataContext* dataContext, DataBind* dataBind) -{ - m_parentDataBind = dataBind; - for (auto dataBind : m_dataBinds) - { - if (dataBind->is()) - { - - dataBind->as()->bindFromContext(dataContext); - } - } -} - -void FormulaToken::unbind() -{ - for (auto dataBind : m_dataBinds) - { - dataBind->unbind(); - } -} - -void FormulaToken::update() -{ - for (auto dataBind : m_dataBinds) - { - auto d = dataBind->dirt(); - if (d == ComponentDirt::None) - { - continue; - } - dataBind->dirt(ComponentDirt::None); - dataBind->update(d); - } -} - -void FormulaToken::copy(const FormulaTokenBase& object) -{ - auto dataBinds = object.as()->dataBinds(); - for (auto dataBind : dataBinds) + if (m_formula) { - auto dataBindClone = dataBind->clone()->as(); - dataBindClone->target(this); - addDataBind(dataBindClone); + m_formula->addDataBind(dataBind); } - FormulaTokenBase::copy(object); } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/data_bind.cpp b/thirdparty/rive/source/data_bind/data_bind.cpp index 822a76d4e..7e942df82 100644 --- a/thirdparty/rive/source/data_bind/data_bind.cpp +++ b/thirdparty/rive/source/data_bind/data_bind.cpp @@ -2,16 +2,22 @@ #include "rive/artboard.hpp" #include "rive/data_bind_flags.hpp" #include "rive/generated/core_registry.hpp" +#include "rive/data_bind/bindable_property_artboard.hpp" #include "rive/data_bind/bindable_property_asset.hpp" #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/bindable_property_color.hpp" #include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_list.hpp" #include "rive/data_bind/bindable_property_boolean.hpp" #include "rive/data_bind/bindable_property_trigger.hpp" #include "rive/data_bind/bindable_property_integer.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" +#include "rive/data_bind/data_bind_container.hpp" #include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/context/context_value_any.hpp" #include "rive/data_bind/context/context_value_asset_image.hpp" +#include "rive/data_bind/context/context_value_artboard.hpp" #include "rive/data_bind/context/context_value_boolean.hpp" #include "rive/data_bind/context/context_value_number.hpp" #include "rive/data_bind/context/context_value_string.hpp" @@ -20,14 +26,17 @@ #include "rive/data_bind/context/context_value_color.hpp" #include "rive/data_bind/context/context_value_trigger.hpp" #include "rive/data_bind/context/context_value_symbol_list_index.hpp" +#include "rive/data_bind/context/context_value_viewmodel.hpp" #include "rive/data_bind/data_values/data_type.hpp" #include "rive/data_bind/converters/data_converter.hpp" #include "rive/data_bind/converters/formula/formula_token.hpp" #include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_machine.hpp" +#include "rive/artboard_component_list.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/state_machine_importer.hpp" #include "rive/importers/backboard_importer.hpp" +#include "rive/component.hpp" using namespace rive; @@ -54,7 +63,32 @@ StatusCode DataBind::import(ImportStack& importStack) backboardImporter->addDataConverterReferencer(this); if (target()) { - if (target()->is()) + initialize(); + auto input = ScriptInput::from(target()); + if (input != nullptr) + { + bool ownsDataBind = true; + if (input->scriptedObject() != nullptr) + { + if (input->scriptedObject()->component() != nullptr) + { + auto importer = importStack.latest( + ArtboardBase::typeKey); + if (importer != nullptr) + { + ownsDataBind = false; + importer->addDataBind(this); + } + } + else if (input->scriptedObject()->addDataBindFromScriptedObject( + this)) + { + ownsDataBind = false; + } + } + input->dataBind(this, ownsDataBind); + } + else if (target()->is()) { target()->as()->addDataBind(this); } @@ -70,10 +104,13 @@ StatusCode DataBind::import(ImportStack& importStack) case BindablePropertyStringBase::typeKey: case BindablePropertyBooleanBase::typeKey: case BindablePropertyEnumBase::typeKey: + case BindablePropertyArtboardBase::typeKey: case BindablePropertyColorBase::typeKey: case BindablePropertyTriggerBase::typeKey: case BindablePropertyIntegerBase::typeKey: case BindablePropertyAssetBase::typeKey: + case BindablePropertyViewModelBase::typeKey: + case BindablePropertyListBase::typeKey: case TransitionPropertyViewModelComparatorBase::typeKey: case StateTransitionBase::typeKey: { @@ -90,6 +127,21 @@ StatusCode DataBind::import(ImportStack& importStack) } default: { + // Prefer the artboard that actually owns the target object. + // Relying on latest can attach binds to + // the wrong source artboard when multiple artboards are + // loaded. + if (target()->is()) + { + auto comp = target()->as(); + auto parentArtboard = comp->artboard(); + if (parentArtboard != nullptr) + { + parentArtboard->addDataBind(this); + return Super::import(importStack); + } + } + auto artboardImporter = importStack.latest( ArtboardBase::typeKey); @@ -109,42 +161,64 @@ StatusCode DataBind::import(ImportStack& importStack) DataType DataBind::outputType() { - if (converter()) + if (converter() && converter()->outputType() != DataType::input && + converter() && converter()->outputType() != DataType::none) { return converter()->outputType(); } - switch (m_Source->coreType()) + return sourceOutputType(); +} + +DataType DataBind::sourceOutputType() +{ + if (m_Source != nullptr) { - case ViewModelInstanceNumberBase::typeKey: - return DataType::number; - case ViewModelInstanceStringBase::typeKey: - return DataType::string; - case ViewModelInstanceEnumBase::typeKey: - return DataType::enumType; - case ViewModelInstanceColorBase::typeKey: - return DataType::color; - case ViewModelInstanceBooleanBase::typeKey: - return DataType::boolean; - case ViewModelInstanceListBase::typeKey: - return DataType::list; - case ViewModelInstanceTriggerBase::typeKey: - return DataType::trigger; - case ViewModelInstanceSymbolListIndexBase::typeKey: - return DataType::symbolListIndex; - case ViewModelInstanceAssetImageBase::typeKey: - return DataType::assetImage; + switch (m_Source->coreType()) + { + case ViewModelInstanceNumberBase::typeKey: + return DataType::number; + case ViewModelInstanceStringBase::typeKey: + return DataType::string; + case ViewModelInstanceEnumBase::typeKey: + return DataType::enumType; + case ViewModelInstanceColorBase::typeKey: + return DataType::color; + case ViewModelInstanceBooleanBase::typeKey: + return DataType::boolean; + case ViewModelInstanceListBase::typeKey: + return DataType::list; + case ViewModelInstanceTriggerBase::typeKey: + return DataType::trigger; + case ViewModelInstanceSymbolListIndexBase::typeKey: + return DataType::symbolListIndex; + case ViewModelInstanceAssetImageBase::typeKey: + return DataType::assetImage; + case ViewModelInstanceArtboardBase::typeKey: + return DataType::artboard; + case ViewModelInstanceViewModelBase::typeKey: + return DataType::viewModel; + } } return DataType::none; } -void DataBind::source(ViewModelInstanceValue* value) +void DataBind::source(rcp value) { if (!bindsOnce()) { value->addDependent(this); - value->ref(); } m_Source = value; + + // We treat this as a special case. If an ArtboardComponentList's list + // property is bound to a number instance, we know that the component + // will be provided with dettached view model instances that need to be + // advanced explicitly + if (m_Source && target() && target()->is()) + { + target()->as()->shouldResetInstances( + m_Source->coreType() == ViewModelInstanceNumberBase::typeKey); + } } void DataBind::clearSource() @@ -155,11 +229,6 @@ void DataBind::clearSource() if (!bindsOnce()) { m_Source->removeDependent(this); - m_Source->unref(); - } - if (m_dataConverter != nullptr) - { - m_dataConverter->unbind(); } m_Source = nullptr; } @@ -167,7 +236,7 @@ void DataBind::clearSource() DataBind::~DataBind() { - clearSource(); + unbind(); delete m_ContextValue; m_ContextValue = nullptr; delete m_dataConverter; @@ -207,15 +276,32 @@ void DataBind::bind() case DataType::assetImage: m_ContextValue = new DataBindContextValueAssetImage(this); break; + case DataType::artboard: + m_ContextValue = new DataBindContextValueArtboard(this); + break; + case DataType::viewModel: + m_ContextValue = new DataBindContextValueViewModel(this); + break; + case DataType::any: + m_ContextValue = new DataBindContextValueAny(this); + break; default: break; } + if (m_dataConverter) + { + m_dataConverter->reset(); + } addDirt(ComponentDirt::Bindings, true); } void DataBind::unbind() { clearSource(); + if (m_dataConverter != nullptr) + { + m_dataConverter->unbind(); + } if (m_ContextValue != nullptr) { delete m_ContextValue; @@ -223,13 +309,15 @@ void DataBind::unbind() } } +bool DataBind::canSkip() +{ + return m_target && m_target->is() && + m_target->as()->isCollapsed() && + propertyKey() != LayoutComponentStyleBase::displayValuePropertyKey; +} + void DataBind::update(ComponentDirt value) { - if ((value & ComponentDirt::Dependents) == ComponentDirt::Dependents && - m_dataConverter != nullptr) - { - m_dataConverter->update(); - } if (m_Source != nullptr && m_ContextValue != nullptr) { if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings) @@ -249,15 +337,16 @@ void DataBind::update(ComponentDirt value) } } -void DataBind::updateSourceBinding(bool invalidate) +void DataBind::updateDependents() { - if ((m_Dirt & ComponentDirt::Dependents) == ComponentDirt::Dependents && - m_dataConverter != nullptr) + if (m_dataConverter) { - m_Dirt &= ~ComponentDirt::Dependents; m_dataConverter->update(); } - auto flagsValue = static_cast(flags()); +} + +void DataBind::updateSourceBinding(bool invalidate) +{ if (toSource()) { if (m_ContextValue != nullptr) @@ -266,15 +355,26 @@ void DataBind::updateSourceBinding(bool invalidate) { m_ContextValue->invalidate(); } - m_ContextValue->applyToSource( - m_target, - propertyKey(), - (flagsValue & DataBindFlags::Direction) == - DataBindFlags::ToSource); + m_ContextValue->applyToSource(m_target, + propertyKey(), + isMainToSource()); } } } +bool DataBind::isMainToSource() +{ + auto flagsValue = static_cast(flags()); + return (flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource; +} + +bool DataBind::sourceToTargetRunsFirst() +{ + auto flagsValue = static_cast(flags()); + return (flagsValue & DataBindFlags::SourceToTargetRunsFirst) == + DataBindFlags::SourceToTargetRunsFirst; +} + void DataBind::addDirt(ComponentDirt value, bool recurse) { if (m_suppressDirt || (m_Dirt & value) == value) @@ -290,58 +390,82 @@ void DataBind::addDirt(ComponentDirt value, bool recurse) m_changedCallback(); } #endif - if (target() != nullptr) + if (enums::is_flag_set(m_Dirt, ComponentDirt::Dependents) && + m_ContextValue != nullptr) { - if (target()->is()) - { - - target()->as()->markConverterDirty(); - } - else if (target()->is()) - { - - target()->as()->markDirty(); - } - else if (target()->is()) - { - auto artboard = target()->as()->artboard(); - if (artboard != nullptr) - { - artboard->onComponentDirty(target()->as()); - } - } + m_ContextValue->invalidate(); } - if ((m_Dirt & ComponentDirt::Dependents) != 0 && m_ContextValue != nullptr) + if (m_container && !m_isCollapsed) { - m_ContextValue->invalidate(); + m_container->addDirtyDataBind(this); } } +void DataBind::container(DataBindContainer* container) +{ + m_container = container; +} + +void DataBind::relinkDataBind() { m_container->rebuildDataBind(this); } + bool DataBind::bindsOnce() { auto flagsValue = static_cast(flags()); - return (flagsValue & DataBindFlags::Once) == DataBindFlags::Once; + return enums::is_flag_set(flagsValue, DataBindFlags::Once); } bool DataBind::toSource() { auto flagsValue = static_cast(flags()); - return (flagsValue & (DataBindFlags::TwoWay | DataBindFlags::ToSource)) != - 0; + return enums::any_flag_set(flagsValue, + DataBindFlags::TwoWay | DataBindFlags::ToSource); } bool DataBind::toTarget() { auto flagsValue = static_cast(flags()); - return (flagsValue & DataBindFlags::TwoWay) != 0 || - (flagsValue & DataBindFlags::ToSource) == 0; + return enums::is_flag_set(flagsValue, DataBindFlags::TwoWay) || + !enums::is_flag_set(flagsValue, DataBindFlags::ToSource); +} + +bool DataBind::isNameBased() +{ + auto flagsValue = static_cast(flags()); + return enums::is_flag_set(flagsValue, DataBindFlags::NameBased); } bool DataBind::advance(float elapsedTime) { - if (converter()) + if (converter() && m_Source && !m_isCollapsed) { return converter()->advance(elapsedTime); } return false; +} + +void DataBind::file(File* value) { m_file = value; }; + +File* DataBind::file() const { return m_file; }; + +void DataBind::collapse(bool isCollapsed) +{ + if (m_isCollapsed == isCollapsed || + propertyKey() == LayoutComponentStyleBase::displayValuePropertyKey || + toSource()) + { + return; + } + m_isCollapsed = isCollapsed; + if (!m_isCollapsed && m_Dirt != ComponentDirt::None && m_container) + { + m_container->addDirtyDataBind(this); + } +} + +void DataBind::initialize() +{ + if (target() && target()->is()) + { + target()->as()->addCollapsable(this); + } } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/data_bind_container.cpp b/thirdparty/rive/source/data_bind/data_bind_container.cpp new file mode 100644 index 000000000..221c252f8 --- /dev/null +++ b/thirdparty/rive/source/data_bind/data_bind_container.cpp @@ -0,0 +1,178 @@ +#include "rive/data_bind/data_bind_container.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_context.hpp" + +using namespace rive; + +void DataBindContainer::deleteDataBinds() +{ + for (auto& dataBind : m_dataBinds) + { + delete dataBind; + } +} + +void DataBindContainer::unbindDataBinds() +{ + for (auto& dataBind : m_dataBinds) + { + dataBind->unbind(); + } +} + +void DataBindContainer::bindDataBindsFromContext(DataContext* dataContext) +{ + + for (auto& dataBind : m_dataBinds) + { + if (dataBind->is()) + { + dataBind->as()->bindFromContext(dataContext); + } + } +} + +bool DataBindContainer::advanceDataBinds(float elapsedSeconds) +{ + if (m_dataBinds.size() == 0) + { + return false; + } + bool didUpdate = false; + for (auto& dataBind : m_dataBinds) + { + if (dataBind->advance(elapsedSeconds)) + { + didUpdate = true; + } + } + return didUpdate; +} + +void DataBindContainer::removeDataBind(DataBind* dataBind) +{ + m_dataBinds.erase( + std::remove(m_dataBinds.begin(), m_dataBinds.end(), dataBind), + m_dataBinds.end()); + m_persistingDataBinds.erase(std::remove(m_persistingDataBinds.begin(), + m_persistingDataBinds.end(), + dataBind), + m_persistingDataBinds.end()); + m_dirtyDataBinds.erase( + std::remove(m_dirtyDataBinds.begin(), m_dirtyDataBinds.end(), dataBind), + m_dirtyDataBinds.end()); + m_pendingDirtyDataBinds.erase(std::remove(m_pendingDirtyDataBinds.begin(), + m_pendingDirtyDataBinds.end(), + dataBind), + m_pendingDirtyDataBinds.end()); +} + +void DataBindContainer::addDataBind(DataBind* dataBind) +{ + m_dataBinds.push_back(dataBind); + // Any data bind that is applied to source needs to be updated regardless of + // it having dirt or not. The reason is that they depend on changes of the + // value of the target, which is not propagated as dirt to the data binding + // object. That's why there is a separate list for these that is constantly + // updated. + if (dataBind->toSource()) + { + m_persistingDataBinds.push_back(dataBind); + } + dataBind->container(this); +} + +void DataBindContainer::updateDataBind(DataBind* dataBind, + bool applyTargetToSource) +{ + auto d = dataBind->dirt(); + + // Update dependents before applying both target to source and source to + // target + if ((d & ComponentDirt::Dependents) == ComponentDirt::Dependents) + { + dataBind->updateDependents(); + } + + if (applyTargetToSource && !dataBind->sourceToTargetRunsFirst()) + { + + dataBind->updateSourceBinding(); + } + if (d != ComponentDirt::None) + { + dataBind->dirt(ComponentDirt::None); + dataBind->update(d); + } + if (applyTargetToSource && dataBind->sourceToTargetRunsFirst()) + { + + dataBind->updateSourceBinding(); + } +} + +void DataBindContainer::updateDataBinds(bool applyTargetToSource) +{ + if (m_persistingDataBinds.size() == 0 && m_dirtyDataBinds.size() == 0) + { + return; + } + m_isProcessing = true; + for (auto& dataBind : m_persistingDataBinds) + { + if (!dataBind->canSkip()) + { + updateDataBind(dataBind, applyTargetToSource); + } + } + for (auto& dataBind : m_dirtyDataBinds) + { + // data binds on this list don't need to apply target to source because + // any data bind that applies to source is collected on the + // m_persistingDataBinds list + updateDataBind(dataBind, false); + } + m_dirtyDataBinds.clear(); + if (m_pendingDirtyDataBinds.size() > 0) + { + + m_dirtyDataBinds.assign(m_pendingDirtyDataBinds.begin(), + m_pendingDirtyDataBinds.end()); + m_pendingDirtyDataBinds.clear(); + } + m_isProcessing = false; +} + +void DataBindContainer::sortDataBinds() +{ + size_t currentToSourceIndex = 0; + for (size_t i = 0; i < m_dataBinds.size(); i++) + { + if (m_dataBinds[i]->toSource()) + { + if (i != currentToSourceIndex) + { + + std::iter_swap(m_dataBinds.begin() + currentToSourceIndex, + m_dataBinds.begin() + i); + } + currentToSourceIndex += 1; + } + } +} + +void DataBindContainer::addDirtyDataBind(DataBind* dataBind) +{ + if (dataBind->toSource()) + { + return; + } + auto& insertingList = + m_isProcessing ? m_pendingDirtyDataBinds : m_dirtyDataBinds; + auto itr = std::find(insertingList.begin(), insertingList.end(), dataBind); + if (itr == insertingList.end()) + { + insertingList.push_back(dataBind); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/data_bind_context.cpp b/thirdparty/rive/source/data_bind/data_bind_context.cpp index edf3f01c2..174521fe5 100644 --- a/thirdparty/rive/source/data_bind/data_bind_context.cpp +++ b/thirdparty/rive/source/data_bind/data_bind_context.cpp @@ -25,18 +25,61 @@ void DataBindContext::decodeSourcePathIds(Span value) void DataBindContext::copySourcePathIds(const DataBindContextBase& object) { m_SourcePathIdsBuffer = object.as()->m_SourcePathIdsBuffer; + m_isPathResolved = object.as()->m_isPathResolved; +} + +void DataBindContext::resolvePath() +{ + if (!isNameBased() || m_isPathResolved) + { + return; + } + m_isPathResolved = true; + if (m_SourcePathIdsBuffer.size() > 0) + { + auto pathId = m_SourcePathIdsBuffer[0]; + if (m_file) + { + auto dataResolver = m_file->dataResolver(); + if (dataResolver) + { + auto resolvedPath = dataResolver->resolvePath(pathId); + if (!resolvedPath.empty()) + { + m_SourcePathIdsBuffer = resolvedPath; + } + } + } + } } void DataBindContext::bindFromContext(DataContext* dataContext) { if (dataContext != nullptr) { + resolvePath(); auto vmSource = - dataContext->getViewModelProperty(m_SourcePathIdsBuffer); - if (vmSource != nullptr) + isNameBased() && file() + ? dataContext->getRelativeViewModelProperty( + m_SourcePathIdsBuffer, + file()->dataResolver()) + : dataContext->getViewModelProperty(m_SourcePathIdsBuffer); + if (m_Source == nullptr || vmSource != m_Source.get()) + { + if (vmSource != nullptr) + { + clearSource(); + source(ref_rcp(vmSource)); + bind(); + } + else + { + unbind(); + } + } + else { - source(vmSource); - bind(); + addDirt(ComponentDirt::Bindings, true); } if (m_dataConverter != nullptr) { diff --git a/thirdparty/rive/source/data_bind/data_bind_list_item_consumer.cpp b/thirdparty/rive/source/data_bind/data_bind_list_item_consumer.cpp index 4f8e55a23..309fa9902 100644 --- a/thirdparty/rive/source/data_bind/data_bind_list_item_consumer.cpp +++ b/thirdparty/rive/source/data_bind/data_bind_list_item_consumer.cpp @@ -1,7 +1,9 @@ #include "rive/artboard_component_list.hpp" +#include "rive/shapes/list_path.hpp" #include "rive/component.hpp" #include "rive/data_bind/data_bind_list_item_consumer.hpp" #include "rive/generated/core_registry.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" using namespace rive; @@ -11,6 +13,12 @@ DataBindListItemConsumer* DataBindListItemConsumer::from(Core* component) { case ArtboardComponentList::typeKey: return component->as(); + case ListPath::typeKey: + return component->as(); + case Text::typeKey: + return component->as(); + case ViewModelInstanceList::typeKey: + return component->as(); } return nullptr; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/data_bind_path.cpp b/thirdparty/rive/source/data_bind/data_bind_path.cpp new file mode 100644 index 000000000..1b4ddf441 --- /dev/null +++ b/thirdparty/rive/source/data_bind/data_bind_path.cpp @@ -0,0 +1,55 @@ +#include "rive/data_bind/data_bind_path.hpp" +#include "rive/importers/backboard_importer.hpp" + +using namespace rive; + +void DataBindPath::decodePath(Span value) +{ + BinaryReader reader(value); + while (!reader.reachedEnd()) + { + auto val = reader.readVarUintAs(); + m_pathBuffer.push_back(val); + } +} + +void DataBindPath::copyPath(const DataBindPathBase& object) +{ + m_pathBuffer = object.as()->m_pathBuffer; + m_resolved = object.as()->m_resolved; +} + +StatusCode DataBindPath::import(ImportStack& importStack) +{ + auto backboardImporter = + importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + auto file = backboardImporter->file(); + m_file = file; + + return Super::import(importStack); +} + +const std::vector& DataBindPath::resolvedPath() +{ + if (!m_resolved) + { + if (!m_file) + { + return m_pathBuffer; + } + auto dataResolver = m_file->dataResolver(); + if (dataResolver && m_pathBuffer.size() == 1) + { + auto pathId = m_pathBuffer[0]; + m_pathBuffer = dataResolver->resolvePath(pathId); + } + m_resolved = true; + } + return m_pathBuffer; +} + +void DataBindPath::file(File* file) { m_file = file; } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/data_bind_viewmodel_consumer.cpp b/thirdparty/rive/source/data_bind/data_bind_viewmodel_consumer.cpp new file mode 100644 index 000000000..862bd290e --- /dev/null +++ b/thirdparty/rive/source/data_bind/data_bind_viewmodel_consumer.cpp @@ -0,0 +1,17 @@ +#include "rive/artboard_component_list.hpp" +#include "rive/shapes/list_path.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/data_bind/data_bind_viewmodel_consumer.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindViewModelConsumer* DataBindViewModelConsumer::from(Core* component) +{ + switch (component->coreType()) + { + case ViewModelInstanceViewModel::typeKey: + return component->as(); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind/data_context.cpp b/thirdparty/rive/source/data_bind/data_context.cpp index c96bde152..e570dcaca 100644 --- a/thirdparty/rive/source/data_bind/data_context.cpp +++ b/thirdparty/rive/source/data_bind/data_context.cpp @@ -1,4 +1,8 @@ #include "rive/data_bind/data_context.hpp" +#include "rive/data_bind/data_bind_path.hpp" +#include "rive/file.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" using namespace rive; @@ -25,6 +29,10 @@ ViewModelInstanceValue* DataContext::getViewModelProperty( if (m_ViewModelInstance != nullptr && m_ViewModelInstance->viewModelId() == path[0]) { + if (path.size() == 1) + { + return nullptr; + } rcp instance = m_ViewModelInstance; for (it = path.begin() + 1; it != path.end() - 1; it++) { @@ -52,14 +60,86 @@ ViewModelInstanceValue* DataContext::getViewModelProperty( return nullptr; } +ViewModelInstanceValue* DataContext::getRelativeViewModelProperty( + const std::vector path, + DataResolver* resolver) const +{ + std::vector::const_iterator it; + if (path.size() == 0 || !resolver) + { + return nullptr; + } + { + rcp instance = m_ViewModelInstance; + if (path.size() == 1) + { + ViewModelInstanceValue* propertyValue = + instance->propertyValue(resolver->resolveName(path[0])); + if (propertyValue) + { + return propertyValue; + } + goto skip_relative_path; + } + for (it = path.begin(); it != path.end() - 1; it++) + { + auto viewModelInstanceValue = + instance->propertyValue(resolver->resolveName(*it)); + if (viewModelInstanceValue != nullptr && + viewModelInstanceValue->is()) + { + instance = + viewModelInstanceValue->as() + ->referenceViewModelInstance(); + } + else + { + goto skip_relative_path; + } + } + ViewModelInstanceValue* propertyValue = + instance->propertyValue(resolver->resolveName(*it++)); + if (propertyValue) + { + return propertyValue; + } + } +skip_relative_path: + if (m_Parent != nullptr) + { + return m_Parent->getRelativeViewModelProperty(path, resolver); + } + return nullptr; +} + +ViewModelInstanceValue* DataContext::getViewModelProperty( + DataBindPath* dataBindPath) +{ + if (dataBindPath->isRelative()) + { + auto file = dataBindPath->file(); + if (file) + { + auto resolver = file->dataResolver(); + if (resolver) + { + return getRelativeViewModelProperty( + dataBindPath->resolvedPath(), + resolver); + } + } + } + return getViewModelProperty(dataBindPath->path()); +} + rcp DataContext::getViewModelInstance( const std::vector path) const { - std::vector::const_iterator it; if (path.size() == 0) { return nullptr; } + std::vector::const_iterator it; if (m_ViewModelInstance != nullptr && m_ViewModelInstance->viewModelId() == path[0]) { @@ -91,4 +171,74 @@ rcp DataContext::getViewModelInstance( return m_Parent->getViewModelInstance(path); } return nullptr; +} + +rcp DataContext::getRelativeViewModelInstance( + const std::vector path, + DataResolver* resolver) const +{ + if (path.size() == 0 || !resolver) + { + return nullptr; + } + std::vector::const_iterator it; + if (m_ViewModelInstance != nullptr) + { + rcp instance = m_ViewModelInstance; + for (it = path.begin(); it != path.end(); it++) + { + auto viewModelInstanceValue = + instance->propertyValue(resolver->resolveName(*it)); + if (viewModelInstanceValue != nullptr && + viewModelInstanceValue->is()) + { + instance = + viewModelInstanceValue->as() + ->referenceViewModelInstance(); + } + else + { + instance = nullptr; + } + if (instance == nullptr) + { + goto skip_path_relative; + } + } + return instance; + } +skip_path_relative: + if (m_Parent != nullptr) + { + return m_Parent->getRelativeViewModelInstance(path, resolver); + } + return nullptr; +} + +rcp DataContext::getViewModelInstance( + DataBindPath* dataBindPath) const +{ + if (!dataBindPath) + { + return nullptr; + } + if (dataBindPath->isRelative()) + { + auto file = dataBindPath->file(); + if (file) + { + auto resolver = file->dataResolver(); + if (resolver) + { + return getRelativeViewModelInstance( + dataBindPath->resolvedPath(), + resolver); + } + } + return nullptr; + } + else + { + return getViewModelInstance(dataBindPath->resolvedPath()); + } } \ No newline at end of file diff --git a/thirdparty/rive/source/data_bind_path_referencer.cpp b/thirdparty/rive/source/data_bind_path_referencer.cpp new file mode 100644 index 000000000..718ff1d15 --- /dev/null +++ b/thirdparty/rive/source/data_bind_path_referencer.cpp @@ -0,0 +1,46 @@ +#include "rive/data_bind_path_referencer.hpp" +#include "rive/importers/data_bind_path_importer.hpp" +#include "rive/file.hpp" + +using namespace rive; + +DataBindPathReferencer::~DataBindPathReferencer() +{ + if (m_dataBindPath) + { + delete m_dataBindPath; + } +} + +void DataBindPathReferencer::copyDataBindPath(DataBindPath* dataBindPath) +{ + if (dataBindPath) + { + m_dataBindPath = dataBindPath->clone()->as(); + m_dataBindPath->file(dataBindPath->file()); + } +} + +void DataBindPathReferencer::importDataBindPath(ImportStack& importStack) +{ + auto dataBindPathImporter = + importStack.latest(DataBindPathBase::typeKey); + if (dataBindPathImporter) + { + auto dataBindPath = dataBindPathImporter->claim(); + if (dataBindPath != nullptr) + { + // If a DataBindPath is claimed, the core object shouldn't have a + // path already created + assert(m_dataBindPath == nullptr); + m_dataBindPath = dataBindPath; + } + } +} + +void DataBindPathReferencer::decodeDataBindPath(Span& value) +{ + m_dataBindPath = new DataBindPath(); + m_dataBindPath->decodePath(value); + m_dataBindPath->resolved(true); +} \ No newline at end of file diff --git a/thirdparty/rive/source/drawable.cpp b/thirdparty/rive/source/drawable.cpp index 25103a893..fea7a832f 100644 --- a/thirdparty/rive/source/drawable.cpp +++ b/thirdparty/rive/source/drawable.cpp @@ -43,37 +43,7 @@ void Drawable::addClippingShape(ClippingShape* shape) m_ClippingShapes.push_back(shape); } -ClipResult Drawable::applyClip(Renderer* renderer) const -{ - if (m_ClippingShapes.size() == 0) - { - return ClipResult::noClip; - } - - renderer->save(); - - for (auto clippingShape : m_ClippingShapes) - { - if (!clippingShape->isVisible()) - { - continue; - } - - ShapePaintPath* path = clippingShape->path(); - if (path == nullptr) - { - return ClipResult::emptyClip; - } - RenderPath* renderPath = path->renderPath(this); - if (renderPath == nullptr) - { - return ClipResult::emptyClip; - } - - renderer->clipPath(renderPath); - } - return ClipResult::clip; -} +bool Drawable::willDraw() { return !isHidden(); } bool Drawable::isChildOfLayout(LayoutComponent* layout) { @@ -89,6 +59,24 @@ bool Drawable::isChildOfLayout(LayoutComponent* layout) return false; } +bool Drawable::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + if (isHidden()) + { + return false; + } + auto hComponent = hittableComponent(); + if (hComponent != this && hComponent != nullptr) + { + return hComponent->hitTestPoint(position, + skipOnUnclipped, + isPrimaryHit); + } + return Component::hitTestPoint(position, skipOnUnclipped, isPrimaryHit); +} + Drawable* DrawableProxy::hittableComponent() { return static_cast(proxyDrawing()); @@ -97,4 +85,4 @@ Drawable* DrawableProxy::hittableComponent() bool DrawableProxy::isTargetOpaque() { return hittableComponent()->isTargetOpaque(); -} +} \ No newline at end of file diff --git a/thirdparty/rive/source/factory.cpp b/thirdparty/rive/source/factory.cpp index edb0180d0..77b0a0100 100644 --- a/thirdparty/rive/source/factory.cpp +++ b/thirdparty/rive/source/factory.cpp @@ -31,8 +31,8 @@ rcp Factory::decodeFont(Span span) rcp Factory::decodeAudio(Span span) { #ifdef WITH_RIVE_AUDIO - return rcp( - new AudioSource(SimpleArray(span.data(), span.size()))); + return AudioSource::MakeAudioSource( + SimpleArray(span.data(), span.size())); #else return nullptr; #endif diff --git a/thirdparty/rive/source/file.cpp b/thirdparty/rive/source/file.cpp index cab80af21..b6e72f101 100644 --- a/thirdparty/rive/source/file.cpp +++ b/thirdparty/rive/source/file.cpp @@ -1,4 +1,5 @@ #include "rive/file.hpp" +#include "rive/bindable_artboard.hpp" #include "rive/runtime_header.hpp" #include "rive/animation/animation.hpp" #include "rive/artboard_component_list.hpp" @@ -6,7 +7,9 @@ #include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_string_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" +#include "rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp" #include "rive/generated/core_registry.hpp" +#include "rive/animation/listener_types/listener_input_type_semantic.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/backboard_importer.hpp" #include "rive/importers/bindable_property_importer.hpp" @@ -14,10 +17,16 @@ #include "rive/importers/data_converter_formula_importer.hpp" #include "rive/importers/enum_importer.hpp" #include "rive/importers/file_asset_importer.hpp" +#include "rive/importers/text_asset_importer.hpp" #include "rive/importers/import_stack.hpp" +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/lua/lua_state.hpp" +#endif #include "rive/importers/keyed_object_importer.hpp" #include "rive/importers/keyed_property_importer.hpp" #include "rive/importers/linear_animation_importer.hpp" +#include "rive/importers/scripted_object_importer.hpp" #include "rive/importers/state_machine_importer.hpp" #include "rive/importers/state_machine_listener_importer.hpp" #include "rive/importers/state_machine_layer_importer.hpp" @@ -25,9 +34,12 @@ #include "rive/importers/state_transition_importer.hpp" #include "rive/importers/state_machine_layer_component_importer.hpp" #include "rive/importers/transition_viewmodel_condition_importer.hpp" +#include "rive/importers/listener_input_type_keyboard_importer.hpp" +#include "rive/importers/listener_input_type_semantic_importer.hpp" #include "rive/importers/viewmodel_importer.hpp" #include "rive/importers/viewmodel_instance_importer.hpp" #include "rive/importers/viewmodel_instance_list_importer.hpp" +#include "rive/importers/data_bind_path_importer.hpp" #include "rive/animation/blend_state_transition.hpp" #include "rive/animation/any_state.hpp" #include "rive/animation/entry_state.hpp" @@ -38,8 +50,12 @@ #include "rive/animation/blend_state_direct.hpp" #include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/constraints/scrolling/scroll_physics.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_bind_path.hpp" #include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_artboard.hpp" #include "rive/data_bind/bindable_property_asset.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/bindable_property_color.hpp" @@ -52,7 +68,14 @@ #include "rive/data_bind/converters/data_converter_number_to_list.hpp" #include "rive/assets/file_asset.hpp" #include "rive/assets/audio_asset.hpp" +#include "rive/assets/blob_asset.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/assets/shader_asset.hpp" #include "rive/assets/file_asset_contents.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/scripted/scripted_layout.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/scripted/scripted_path_effect.hpp" #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/data_enum.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" @@ -74,6 +97,10 @@ // Default namespace for Rive Cpp code using namespace rive; +#if defined(DEBUG) +size_t File::debugTotalFileCount = 0; +#endif + #if !defined(RIVE_FMT_U64) #if defined(__ANDROID__) #if INTPTR_MAX == INT64_MAX @@ -163,31 +190,33 @@ static Core* readRuntimeObject(BinaryReader& reader, return object; } +bool File::deterministicMode = false; + File::File(Factory* factory, rcp assetLoader) : m_factory(factory), m_assetLoader(std::move(assetLoader)) { +#if defined(DEBUG) + debugTotalFileCount++; +#endif assert(factory); } File::~File() { +#if defined(DEBUG) + debugTotalFileCount--; +#endif for (auto artboard : m_artboards) { delete artboard; } - // Assets delete after artboards as they reference them. - for (auto asset : m_fileAssets) - { - delete asset; - } for (auto& viewModel : m_ViewModels) { viewModel->unref(); } - for (auto& viewModelInstance : m_ViewModelInstances) - { - viewModelInstance->unref(); - } +#ifdef WITH_RIVE_TOOLS + m_viewModelInstanceRegistrar = nullptr; +#endif for (auto& enumData : m_Enums) { enumData->unref(); @@ -196,10 +225,6 @@ File::~File() { delete dataConverter; } - for (auto& viewModelRuntime : m_viewModelRuntimes) - { - delete viewModelRuntime; - } for (auto& keyframeInterpolator : m_keyframeInterpolators) { delete keyframeInterpolator; @@ -209,12 +234,16 @@ File::~File() delete physics; } delete m_backboard; +#ifdef WITH_RIVE_SCRIPTING + cleanupScriptingVM(); +#endif } -std::unique_ptr File::import(Span bytes, - Factory* factory, - ImportResult* result, - rcp assetLoader) +rcp File::import(Span bytes, + Factory* factory, + ImportResult* result, + rcp assetLoader, + ScriptingVM* vm) { BinaryReader reader(bytes); RuntimeHeader header; @@ -241,7 +270,13 @@ std::unique_ptr File::import(Span bytes, } return nullptr; } - auto file = rivestd::make_unique(factory, std::move(assetLoader)); + auto file = make_rcp(factory, std::move(assetLoader)); +#ifdef WITH_RIVE_SCRIPTING + if (vm != nullptr) + { + file->setScriptingVM(ref_rcp(vm)); + } +#endif auto readResult = file->read(reader, header); if (result) @@ -258,10 +293,13 @@ std::unique_ptr File::import(Span bytes, ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) { ImportStack importStack; +#ifdef WITH_RIVE_SCRIPTING + std::vector inBandContent; +#endif // TODO: @hernan consider moving this to a special importer. It's not that // simple because Core doesn't have a typeKey, so it should be treated as // a special case. In any case, it's not that bad having it here for now. - Core* lastBindableObject; + Core* lastBindableObject = nullptr; while (!reader.reachedEnd()) { auto object = readRuntimeObject(reader, header); @@ -295,9 +333,16 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) case ImageAsset::typeKey: case FontAsset::typeKey: case AudioAsset::typeKey: + case BlobAsset::typeKey: + case ScriptAsset::typeKey: + case ShaderAsset::typeKey: { auto fa = object->as(); - m_fileAssets.push_back(fa); + m_fileAssets.push_back(rcp(fa)); + if (object->coreType() == AudioAsset::typeKey) + { + m_hasAudio = true; + } } break; case ViewModel::typeKey: @@ -306,12 +351,6 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) m_ViewModels.push_back(vmc); break; } - case ViewModelInstance::typeKey: - { - auto vmi = object->as(); - m_ViewModelInstances.push_back(vmi); - break; - } case DataEnum::typeKey: case DataEnumCustom::typeKey: { @@ -332,6 +371,10 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) } else { + if (lastBindableObject == object) + { + lastBindableObject = nullptr; + } fprintf(stderr, "Failed to import object of type %d\n", object->coreType()); @@ -344,24 +387,24 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) switch (stackType) { case Backboard::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); static_cast(stackObject.get())->file(this); break; case Artboard::typeKey: - stackObject = rivestd::make_unique( - object->as()); + stackObject = + std::make_unique(object->as()); break; case DataEnumCustom::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); break; case LinearAnimation::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); break; case KeyedObject::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); break; case KeyedProperty::typeKey: @@ -372,13 +415,13 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) { return ImportResult::malformed; } - stackObject = rivestd::make_unique( + stackObject = std::make_unique( importer->animation(), object->as()); break; } case StateMachine::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); break; case StateMachineLayer::typeKey: @@ -390,7 +433,7 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) return ImportResult::malformed; } - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as(), artboardImporter->artboard()); @@ -403,50 +446,100 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) case BlendState1DViewModel::typeKey: case BlendState1DInput::typeKey: case BlendStateDirect::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); stackType = LayerState::typeKey; break; case StateTransition::typeKey: case BlendStateTransition::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); stackType = StateTransition::typeKey; break; case StateMachineListener::typeKey: - stackObject = - rivestd::make_unique( - object->as()); + case StateMachineListenerSingle::typeKey: + stackObject = std::make_unique( + object->as()); + stackType = StateMachineListener::typeKey; break; case ImageAsset::typeKey: case FontAsset::typeKey: case AudioAsset::typeKey: - stackObject = rivestd::make_unique( - object->as(), - m_assetLoader, - m_factory); + case BlobAsset::typeKey: + stackObject = + std::make_unique(object->as(), + m_assetLoader, + m_factory); + stackType = FileAsset::typeKey; + break; + case ListenerInputTypeKeyboardBase::typeKey: + stackObject = + std::make_unique( + object->as()); + stackType = ListenerInputTypeKeyboardBase::typeKey; + break; + case ListenerInputTypeSemanticBase::typeKey: + stackObject = + std::make_unique( + object->as()); + stackType = ListenerInputTypeSemanticBase::typeKey; + break; +#ifdef WITH_RIVE_SCRIPTING + case ScriptAsset::typeKey: + { + auto scriptAsset = object->as(); + stackObject = + std::make_unique(scriptAsset, + m_assetLoader, + m_factory, + &inBandContent); stackType = FileAsset::typeKey; + scriptAsset->file(this); + break; + } + case ShaderAsset::typeKey: + { + auto shaderAsset = object->as(); + stackObject = + std::make_unique(shaderAsset, + m_assetLoader, + m_factory, + &inBandContent); + stackType = FileAsset::typeKey; + break; + } +#endif + case ManifestAsset::typeKey: + stackObject = + std::make_unique(object->as(), + m_assetLoader, + m_factory); + stackType = FileAsset::typeKey; + m_manifest = rcp(object->as()); break; case ViewModel::typeKey: - stackObject = rivestd::make_unique( + { + stackObject = std::make_unique( object->as()); + static_cast(stackObject.get())->file(this); stackType = ViewModel::typeKey; + object->as()->file(this); break; + } case ViewModelInstance::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); stackType = ViewModelInstance::typeKey; break; case ViewModelInstanceList::typeKey: - stackObject = - rivestd::make_unique( - object->as()); + stackObject = std::make_unique( + object->as()); stackType = ViewModelInstanceList::typeKey; break; case TransitionViewModelCondition::typeKey: case TransitionArtboardCondition::typeKey: stackObject = - rivestd::make_unique( + std::make_unique( object->as()); stackType = TransitionViewModelCondition::typeKey; break; @@ -456,21 +549,23 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) case BindablePropertyEnum::typeKey: case BindablePropertyBoolean::typeKey: case BindablePropertyAsset::typeKey: + case BindablePropertyViewModel::typeKey: + case BindablePropertyArtboard::typeKey: case BindablePropertyTrigger::typeKey: case BindablePropertyInteger::typeKey: - stackObject = rivestd::make_unique( + case BindablePropertyList::typeKey: + stackObject = std::make_unique( object->as()); stackType = BindablePropertyBase::typeKey; break; case DataConverterGroupBase::typeKey: - stackObject = rivestd::make_unique( + stackObject = std::make_unique( object->as()); stackType = DataConverterGroupBase::typeKey; break; case DataConverterFormulaBase::typeKey: - stackObject = - rivestd::make_unique( - object->as()); + stackObject = std::make_unique( + object->as()); stackType = DataConverterFormulaBase::typeKey; break; case DataConverterNumberToList::typeKey: @@ -479,6 +574,35 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) case ArtboardComponentList::typeKey: object->as()->file(this); break; + case NestedArtboard::typeKey: + case NestedArtboardLayout::typeKey: + case NestedArtboardLeaf::typeKey: + object->as()->file(this); + break; + case ScriptedDataConverter::typeKey: + case ScriptedDrawable::typeKey: + case ScriptedLayout::typeKey: + case ScriptedPathEffect::typeKey: + case ScriptedListenerAction::typeKey: + case ScriptedTransitionCondition::typeKey: + { + auto scriptedObject = ScriptedObject::from(object); + if (scriptedObject != nullptr) + { + stackObject = std::make_unique( + scriptedObject); + stackType = ScriptedDrawable::typeKey; + } + break; + } + case DataBindPathBase::typeKey: + stackObject = std::make_unique( + object->as()); + stackType = DataBindPathBase::typeKey; + break; + case ScriptInputArtboard::typeKey: + object->as()->file(this); + break; } if (importStack.makeLatest(stackType, std::move(stackObject)) != StatusCode::Ok) @@ -489,7 +613,7 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) if (object->is() && importStack.makeLatest( StateMachineLayerComponent::typeKey, - rivestd::make_unique( + std::make_unique( object->as())) != StatusCode::Ok) { @@ -517,11 +641,110 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) } } - return !reader.hasError() && importStack.resolve() == StatusCode::Ok + auto resolved = importStack.resolve(); +#ifdef WITH_RIVE_SCRIPTING + registerScripts(); +#endif + return !reader.hasError() && resolved == StatusCode::Ok ? ImportResult::success : ImportResult::malformed; } +void File::addFileViewModelInstance(ViewModelInstance* viewModelInstance) +{ + m_ViewModelInstances.push_back(rcp(viewModelInstance)); +} + +#ifdef WITH_RIVE_SCRIPTING +void File::registerScripts() +{ + // Check if we have any script assets in the file + std::vector scripts; + for (auto asset : m_fileAssets) + { + if (asset->is()) + { + scripts.push_back(asset->as()); + } + } + // Only make the ScriptingVM if we have any script assets + if (!scripts.empty()) + { + // If no VM was provided (e.g., from editor), create our own. + if (m_scriptingVM == nullptr) + { + makeScriptingVM(); + } + + ScriptingVM* vm = m_scriptingVM.get(); + if (vm != nullptr) + { + for (auto scriptAsset : scripts) + { + // At runtime, if the script is verified, add it to be + // registered with the VM. At edit time, the script will + // have already been registered, so this won't run. + // WITH_RIVE_TOOLS allows unverified scripts for testing. +#ifdef WITH_RIVE_TOOLS + vm->addModule(scriptAsset); +#else + if (scriptAsset->verified()) + { + vm->addModule(scriptAsset); + } +#endif + } + // Perform registration - ScriptingContext will handle dependencies + // and retries + vm->performRegistration(); + } + } +} + +void File::makeScriptingVM() +{ + cleanupScriptingVM(); + auto context = std::make_unique(m_factory); + m_scriptingVM = make_rcp(std::move(context)); + initializeLuaData(m_scriptingVM->state(), m_ViewModels); +} + +lua_State* File::scriptingState() +{ + return m_scriptingVM ? m_scriptingVM->state() : nullptr; +} + +void File::setScriptingVM(rcp vm) +{ +#ifdef WITH_RIVE_TOOLS + if (m_scriptingVM != nullptr) + { + ScriptingContext* context = m_scriptingVM->context(); + if (context != nullptr) + { + context->disposeOrphanScriptedProperties(); + } + } +#endif + m_scriptingVM = std::move(vm); +} + +void File::cleanupScriptingVM() +{ +#ifdef WITH_RIVE_TOOLS + if (m_scriptingVM != nullptr) + { + ScriptingContext* context = m_scriptingVM->context(); + if (context != nullptr) + { + context->disposeOrphanScriptedProperties(); + } + } +#endif + m_scriptingVM = nullptr; +} +#endif + Artboard* File::artboard(std::string name) const { for (const auto& artboard : m_artboards) @@ -558,22 +781,56 @@ std::string File::artboardNameAt(size_t index) const return ab ? ab->name() : ""; } +std::unique_ptr File::instanceArtboard(Artboard* ab) const +{ + if (ab) + { + auto artboardInstance = ab->instance(); +#ifdef WITH_RIVE_SCRIPTING + artboardInstance->scriptingVM(m_scriptingVM.get()); +#endif + return artboardInstance; + } + return nullptr; +} + std::unique_ptr File::artboardDefault() const { auto ab = this->artboard(); - return ab ? ab->instance() : nullptr; + return instanceArtboard(ab); } std::unique_ptr File::artboardAt(size_t index) const { auto ab = this->artboard(index); - return ab ? ab->instance() : nullptr; + return instanceArtboard(ab); } std::unique_ptr File::artboardNamed(std::string name) const { auto ab = this->artboard(name); - return ab ? ab->instance() : nullptr; + return instanceArtboard(ab); +} + +rcp File::bindableArtboardNamed(std::string name) const +{ + auto ab = this->artboardNamed(name); + return ab ? make_rcp(ref_rcp(this), std::move(ab)) + : nullptr; +} + +rcp File::bindableArtboardDefault() const +{ + auto ab = this->artboardDefault(); + return ab ? make_rcp(ref_rcp(this), std::move(ab)) + : nullptr; +} + +rcp File::internalBindableArtboardFromArtboard( + Artboard* artboard) const +{ + auto ab = artboard ? artboard->instance() : nullptr; + return ab ? make_rcp(nullptr, std::move(ab)) : nullptr; } void File::completeViewModelInstance( @@ -585,8 +842,8 @@ void File::completeViewModelInstance( void File::completeViewModelInstance( rcp viewModelInstance, - std::unordered_map> instancesMap) - const + std::unordered_map>& + instancesMap) const { auto viewModel = m_ViewModels[viewModelInstance->viewModelId()]; auto propertyValues = viewModelInstance->propertyValues(); @@ -602,20 +859,23 @@ void File::completeViewModelInstance( property->as(); auto viewModelReference = m_ViewModels[propertViewModel->viewModelReferenceId()]; - auto viewModelInstance = viewModelReference->instance( + auto viewModelReferenceInstance = viewModelReference->instance( valueViewModel->propertyValue()); - if (viewModelInstance != nullptr) + valueViewModel->parentViewModelInstance( + viewModelInstance.get()); + if (viewModelReferenceInstance != nullptr) { - auto itr = instancesMap.find(viewModelInstance); + auto itr = instancesMap.find(viewModelReferenceInstance); if (itr == instancesMap.end()) { - auto viewModelInstanceCopy = - copyViewModelInstance(viewModelInstance, + auto viewModelReferenceInstanceCopy = + copyViewModelInstance(viewModelReferenceInstance, instancesMap); - instancesMap[viewModelInstance] = viewModelInstanceCopy; + instancesMap[viewModelReferenceInstance] = + viewModelReferenceInstanceCopy; valueViewModel->referenceViewModelInstance( - viewModelInstanceCopy); + viewModelReferenceInstanceCopy); } else { @@ -627,23 +887,26 @@ void File::completeViewModelInstance( else if (value->is()) { auto viewModelList = value->as(); + viewModelList->parentViewModelInstance(viewModelInstance.get()); for (auto& listItem : viewModelList->listItems()) { auto viewModel = m_ViewModels[listItem->viewModelId()]; - auto viewModelInstance = + auto viewModelListItemInstance = viewModel->instance(listItem->viewModelInstanceId()); - if (viewModelInstance != nullptr) + if (viewModelListItemInstance != nullptr) { - auto itr = instancesMap.find(viewModelInstance); + auto itr = instancesMap.find(viewModelListItemInstance); if (itr == instancesMap.end()) { - auto viewModelInstanceCopy = - copyViewModelInstance(viewModelInstance, + auto viewModelInstanceListItemCopy = + copyViewModelInstance(viewModelListItemInstance, instancesMap); - instancesMap[viewModelInstance] = viewModelInstanceCopy; - listItem->viewModelInstance(viewModelInstanceCopy); + instancesMap[viewModelListItemInstance] = + viewModelInstanceListItemCopy; + listItem->viewModelInstance( + viewModelInstanceListItemCopy); } else { @@ -657,14 +920,63 @@ void File::completeViewModelInstance( } } +void File::completeViewModelProperties(ViewModelInstance* viewModelInstance) +{ + auto viewModel = m_ViewModels[viewModelInstance->viewModelId()]; + auto propertyValues = viewModelInstance->propertyValues(); + for (auto& value : propertyValues) + { + if (value->is()) + { + auto property = viewModel->property(value->viewModelPropertyId()); + if (property->is()) + { + auto valueViewModel = value->as(); + auto propertViewModel = + property->as(); + auto viewModelReference = + m_ViewModels[propertViewModel->viewModelReferenceId()]; + auto viewModelReferenceInstance = viewModelReference->instance( + valueViewModel->propertyValue()); + if (viewModelReferenceInstance != nullptr) + { + completeViewModelProperties(viewModelReferenceInstance); + } + } + } + else if (value->is()) + { + auto viewModelList = value->as(); + for (auto& listItem : viewModelList->listItems()) + { + auto viewModel = m_ViewModels[listItem->viewModelId()]; + auto viewModelListItemInstance = + viewModel->instance(listItem->viewModelInstanceId()); + if (viewModelListItemInstance != nullptr) + { + completeViewModelProperties(viewModelListItemInstance); + } + } + } + value->viewModelProperty( + viewModel->property(value->viewModelPropertyId())); + } +} + rcp File::copyViewModelInstance( ViewModelInstance* viewModelInstance, - std::unordered_map> instancesMap) - const + std::unordered_map>& + instancesMap) const { auto copy = rcp( viewModelInstance->clone()->as()); completeViewModelInstance(copy, instancesMap); +#ifdef WITH_RIVE_TOOLS + if (copy) + { + registerViewModelInstance(copy.get(), copy); + } +#endif return copy; } @@ -684,8 +996,8 @@ rcp File::createViewModelInstance(std::string name) const } rcp File::createViewModelInstance( - std::string name, - std::string instanceName) const + const std::string& name, + const std::string& instanceName) const { for (auto& viewModel : m_ViewModels) { @@ -734,6 +1046,36 @@ uint32_t File::findViewModelId(ViewModel* search) const return viewModelId; } +#ifdef WITH_RIVE_TOOLS +void File::setViewModelInstanceRegistrar(ViewModelInstanceRegistrar* registrar) +{ + m_viewModelInstanceRegistrar = registrar; +} + +void File::registerViewModelInstance(ViewModelInstance* ptr, + rcp ref) const +{ + if (ptr != nullptr && m_viewModelInstanceRegistrar != nullptr) + { + m_viewModelInstanceRegistrar->registerInstance(ptr, std::move(ref)); + } +} + +bool File::containsViewModelInstance(ViewModelInstance* ptr) const +{ + return m_viewModelInstanceRegistrar != nullptr && + m_viewModelInstanceRegistrar->contains(ptr); +} + +void File::clearRuntimeViewModelInstances() +{ + if (m_viewModelInstanceRegistrar != nullptr) + { + m_viewModelInstanceRegistrar->clear(); + } +} +#endif + rcp File::createViewModelInstance(ViewModel* viewModel) const { if (viewModel != nullptr) @@ -764,6 +1106,8 @@ rcp File::createViewModelInstance(ViewModel* viewModel) const break; case ViewModelPropertyListBase::typeKey: viewModelInstanceValue = new ViewModelInstanceList(); + viewModelInstanceValue->as() + ->parentViewModelInstance(viewModelInstance); break; case ViewModelPropertyEnumSystemBase::typeKey: case ViewModelPropertyEnumCustomBase::typeKey: @@ -783,8 +1127,15 @@ rcp File::createViewModelInstance(ViewModel* viewModel) const auto viewModelInstanceViewModel = viewModelInstanceValue ->as(); - viewModelInstanceViewModel->referenceViewModelInstance( - createViewModelInstance(viewModelReference)); + auto referenceViewModelInstance = + createViewModelInstance(viewModelReference); + if (referenceViewModelInstance) + { + viewModelInstanceViewModel->parentViewModelInstance( + viewModelInstance); + viewModelInstanceViewModel->referenceViewModelInstance( + referenceViewModelInstance); + } } break; case ViewModelPropertyAssetImageBase::typeKey: @@ -794,7 +1145,11 @@ rcp File::createViewModelInstance(ViewModel* viewModel) const viewModelInstanceValue = new ViewModelInstanceSymbolListIndex(); break; + case ViewModelPropertyArtboardBase::typeKey: + viewModelInstanceValue = new ViewModelInstanceArtboard(); + break; default: + fprintf(stderr, "Missing view model property type\n"); break; } if (viewModelInstanceValue != nullptr) @@ -805,6 +1160,14 @@ rcp File::createViewModelInstance(ViewModel* viewModel) const viewModelInstance->addValue(viewModelInstanceValue); propertyId++; } +#ifdef WITH_RIVE_TOOLS + if (viewModelInstance) + { + auto result = rcp(viewModelInstance); + registerViewModelInstance(viewModelInstance, result); + return result; + } +#endif return rcp(viewModelInstance); } return nullptr; @@ -846,6 +1209,12 @@ rcp File::createDefaultViewModelInstance( auto copy = rcp( viewModelInstance->clone()->as()); completeViewModelInstance(copy); +#ifdef WITH_RIVE_TOOLS + if (copy) + { + registerViewModelInstance(copy.get(), copy); + } +#endif return copy; } return createViewModelInstance(viewModel); @@ -903,7 +1272,7 @@ ViewModelRuntime* File::viewModelByIndex(size_t index) const { if (index < m_ViewModels.size()) { - return createViewModelRuntime(m_ViewModels[index]); + return createViewModelRuntime(m_ViewModels[index]).get(); } fprintf(stderr, "Could not find View Model. Index %zu is out of range.\n", @@ -917,7 +1286,7 @@ ViewModelRuntime* File::viewModelByName(std::string name) const { if (viewModel->name() == name) { - return createViewModelRuntime(viewModel); + return createViewModelRuntime(viewModel).get(); } } fprintf(stderr, "Could not find View Model named %s.\n", name.c_str()); @@ -934,7 +1303,7 @@ ViewModelRuntime* File::defaultArtboardViewModel(Artboard* artboard) const if ((size_t)artboard->viewModelId() < m_ViewModels.size()) { auto viewModel = m_ViewModels[artboard->viewModelId()]; - return createViewModelRuntime(viewModel); + return createViewModelRuntime(viewModel).get(); } fprintf(stderr, "Could not find a View Model linked to Artboard %s.\n", @@ -942,15 +1311,14 @@ ViewModelRuntime* File::defaultArtboardViewModel(Artboard* artboard) const return nullptr; } -ViewModelRuntime* File::createViewModelRuntime(ViewModel* viewModel) const +rcp File::createViewModelRuntime(ViewModel* viewModel) const { - - auto viewModelRuntime = new ViewModelRuntime(viewModel, this); + auto viewModelRuntime = make_rcp(viewModel, this); m_viewModelRuntimes.push_back(viewModelRuntime); return viewModelRuntime; } -const std::vector& File::assets() const { return m_fileAssets; } +Span> File::assets() const { return m_fileAssets; } const std::vector& File::enums() const { return m_Enums; } @@ -1019,7 +1387,7 @@ const std::vector File::stripAssets(Span bytes, #endif -FileAsset* File::asset(size_t index) +rcp File::asset(size_t index) { if (index >= 0 && index < m_fileAssets.size()) { diff --git a/thirdparty/rive/source/focus_data.cpp b/thirdparty/rive/source/focus_data.cpp new file mode 100644 index 000000000..6a79977a3 --- /dev/null +++ b/thirdparty/rive/source/focus_data.cpp @@ -0,0 +1,612 @@ +#include "rive/focus_data.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_component_list.hpp" +#include "rive/artboard_host.hpp" +#include "rive/component.hpp" +#include "rive/constraints/scrolling/scroll_constraint.hpp" +#include "rive/drawable.hpp" +#include "rive/input/focusable.hpp" +#include "rive/input/focus_listener.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/layout_component.hpp" +#include "rive/math/mat2d.hpp" +#include "rive/nested_artboard.hpp" +#include "rive/node.hpp" +#include "rive/parent_traversal.hpp" +#include "rive/semantic/semantic_data.hpp" +#include "rive/semantic/semantic_state.hpp" +#include "rive/text/text_input.hpp" +#include "rive/transform_component.hpp" +#include "rive/world_transform_component.hpp" +#include + +using namespace rive; + +namespace +{ +SemanticData* findSiblingSemanticData(Component* self) +{ + auto* parentNode = self->parent(); + if (parentNode == nullptr || !parentNode->is()) + { + return nullptr; + } + return parentNode->as()->firstChild(); +} +} // namespace + +FocusData::~FocusData() +{ + if (m_focusNode != nullptr) + { + // Clear the focusable pointer first to prevent callbacks during removal + m_focusNode->clearFocusable(); + + // Remove from manager if registered + auto* manager = m_focusNode->manager(); + if (manager != nullptr) + { + manager->removeChild(m_focusNode); + } + // m_focusNode (rcp) is released automatically when this destructor ends + } +} + +rcp FocusData::focusNode() +{ + if (m_focusNode == nullptr) + { + m_focusNode = rcp(new FocusNode(this)); + m_focusNode->canFocus(m_CanFocus); + m_focusNode->canTouch(m_CanTouch); + m_focusNode->canTraverse(m_CanTraverse); + m_focusNode->edgeBehavior( + static_cast(m_EdgeBehaviorValue)); + m_focusNode->name(name()); + // Set initial world bounds if available + updateWorldBounds(); + } + return m_focusNode; +} + +void FocusData::addFocusListener(FocusListener* listener) +{ + m_focusListeners.push_back(listener); +} + +void FocusData::removeFocusListener(FocusListener* listener) +{ + auto it = + std::find(m_focusListeners.begin(), m_focusListeners.end(), listener); + if (it != m_focusListeners.end()) + { + m_focusListeners.erase(it); + } +} + +void FocusData::addKeyboardListener(KeyboardListener* listener) +{ + m_keyboardListeners.push_back(listener); +} + +void FocusData::removeKeyboardListener(KeyboardListener* listener) +{ + auto it = std::find(m_keyboardListeners.begin(), + m_keyboardListeners.end(), + listener); + if (it != m_keyboardListeners.end()) + { + m_keyboardListeners.erase(it); + } +} + +void FocusData::addTextInputListener(KeyboardListener* listener) +{ + m_textInputListeners.push_back(listener); +} + +void FocusData::removeTextInputListener(KeyboardListener* listener) +{ + auto it = std::find(m_textInputListeners.begin(), + m_textInputListeners.end(), + listener); + if (it != m_textInputListeners.end()) + { + m_textInputListeners.erase(it); + } +} + +void FocusData::focus() +{ + // Note: In C++ runtime, focus() needs a FocusManager to set focus. + // The StateMachineInstance will handle this through its own FocusManager. + // This method is provided for API completeness but the actual focus + // setting happens through StateMachineInstance::setFocus(FocusData*). +} + +bool FocusData::keyInput(Key value, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + // Notify listeners + for (auto* listener : m_keyboardListeners) + { + if (listener->keyInput(value, modifiers, isPressed, isRepeat)) + { + return true; + } + } + return false; +} + +bool FocusData::textInput(const std::string& text) +{ + + for (auto* listener : m_textInputListeners) + { + if (listener->textInput(text)) + { + return true; + } + } + return false; +} + +void FocusData::scrollIntoView() +{ + // Find closest LayoutComponent ancestor + Component* layoutComponent = parent(); + while (layoutComponent != nullptr && + !layoutComponent->is()) + { + layoutComponent = layoutComponent->parent(); + } + if (layoutComponent == nullptr) + { + return; + } + + // Get element bounds in its artboard's world space. + // We'll transform these bounds as we cross artboard boundaries. + AABB elementBounds = layoutComponent->as()->worldBounds(); + + // Walk up the hierarchy finding all ScrollConstraints. + // This traversal crosses artboard boundaries via the host chain. + ParentTraversal traversal(this); + while (auto* p = traversal.next()) + { + // When crossing an artboard boundary, transform element bounds from + // nested artboard space to parent artboard space. + if (traversal.didCrossBoundary()) + { + auto* host = traversal.crossingHost(); + auto* sourceArtboard = traversal.sourceArtboard(); + auto* artboardInstance = + sourceArtboard->is() + ? sourceArtboard->as() + : nullptr; + Mat2D hostTransform = + host->worldTransformForArtboard(artboardInstance); + Vec2D min = + hostTransform * Vec2D(elementBounds.minX, elementBounds.minY); + Vec2D max = + hostTransform * Vec2D(elementBounds.maxX, elementBounds.maxY); + elementBounds = AABB(min.x, min.y, max.x, max.y); + } + + // ScrollConstraint is a Constraint that targets Content, so we check + // TransformComponent::constraints() to find ScrollConstraints. + if (p->is()) + { + auto* tc = p->as(); + + for (auto* constraint : tc->constraints()) + { + if (!constraint->is()) + { + continue; + } + + scrollConstraintToShowBounds(constraint->as(), + elementBounds); + } + } + } +} + +void FocusData::scrollConstraintToShowBounds(ScrollConstraint* constraint, + const AABB& elementBounds) +{ + auto* content = constraint->content(); + auto* viewport = constraint->viewport(); + if (content == nullptr || viewport == nullptr) + { + return; + } + + // Get viewport position in world space. + const Mat2D& viewportTransform = viewport->worldTransform(); + float viewportWorldX = viewportTransform[4]; + float viewportWorldY = viewportTransform[5]; + + float viewportWidth = constraint->viewportWidth(); + float viewportHeight = constraint->viewportHeight(); + + // Element position relative to viewport in world space. + // This directly tells us where the element appears in the viewport. + float viewportLeft = elementBounds.minX - viewportWorldX; + float viewportTop = elementBounds.minY - viewportWorldY; + float viewportRight = elementBounds.maxX - viewportWorldX; + float viewportBottom = elementBounds.maxY - viewportWorldY; + + // Use effective scroll offset (target if animating) to handle rapid focus + // changes. + float effectiveScrollX = constraint->effectiveScrollOffsetX(); + float effectiveScrollY = constraint->effectiveScrollOffsetY(); + + float deltaX = 0.0f; + float deltaY = 0.0f; + + // Calculate horizontal scroll adjustment. + if (constraint->constrainsHorizontal()) + { + float elementWidth = viewportRight - viewportLeft; + if (elementWidth > viewportWidth) + { + // Oversized element: keep the left edge visible. + deltaX = -viewportLeft; + } + else if (viewportLeft < 0) + { + // Element is to the left of viewport, scroll right (increase + // offset) + deltaX = -viewportLeft; + } + else if (viewportRight > viewportWidth) + { + // Element is to the right of viewport, scroll left (decrease + // offset) + deltaX = -(viewportRight - viewportWidth); + } + } + + // Calculate vertical scroll adjustment + if (constraint->constrainsVertical()) + { + float elementHeight = viewportBottom - viewportTop; + if (elementHeight > viewportHeight) + { + // Oversized element: keep the top edge visible. + deltaY = -viewportTop; + } + else if (viewportTop < 0) + { + // Element is above viewport, scroll up (increase offset) + deltaY = -viewportTop; + } + else if (viewportBottom > viewportHeight) + { + // Element is below viewport, scroll down (decrease offset) + deltaY = -(viewportBottom - viewportHeight); + } + } + + // Apply scroll if needed (using animated scroll) + if (deltaX != 0 || deltaY != 0) + { + // Add delta to effective scroll offset to get target position. + Vec2D current(effectiveScrollX, effectiveScrollY); + Vec2D target(effectiveScrollX + deltaX, effectiveScrollY + deltaY); + Vec2D snapped = + constraint->nearestSnapOffsetInDirection(current, target); + constraint->scrollToPosition(snapped.x, snapped.y); + } +} + +void FocusData::focused() +{ + // Scroll this element into view, crossing artboard boundaries as needed + scrollIntoView(); + + // Notify listeners + for (auto* listener : m_focusListeners) + { + listener->onFocused(); + } + + // Sync focus state to sibling SemanticData (if any) + auto* sibling = findSiblingSemanticData(this); + if (sibling != nullptr) + { + sibling->setFocusedState(true); + } +} + +void FocusData::blurred() +{ + for (auto* listener : m_focusListeners) + { + listener->onBlurred(); + } + + // Sync focus state to sibling SemanticData (if any) + auto* sibling = findSiblingSemanticData(this); + if (sibling != nullptr) + { + sibling->setFocusedState(false); + } +} + +void FocusData::canFocusChanged() +{ + if (m_focusNode != nullptr) + { + m_focusNode->canFocus(m_CanFocus); + } +} + +void FocusData::canTouchChanged() +{ + if (m_focusNode != nullptr) + { + m_focusNode->canTouch(m_CanTouch); + } +} + +void FocusData::canTraverseChanged() +{ + if (m_focusNode != nullptr) + { + m_focusNode->canTraverse(m_CanTraverse); + } +} + +void FocusData::edgeBehaviorValueChanged() +{ + if (m_focusNode != nullptr) + { + m_focusNode->edgeBehavior( + static_cast(m_EdgeBehaviorValue)); + } +} + +FocusData* FocusData::findParentFocusData() const +{ + // FocusData's parent is typically a Node. Walk up from the parent + // to find any ancestor Node that has a FocusData child. + auto* current = parent(); + while (current != nullptr) + { + if (current->is()) + { + auto* node = current->as(); + for (auto* child : node->children()) + { + if (child->is() && child != this) + { + return child->as(); + } + } + } + current = current->parent(); + } + return nullptr; +} + +rcp FocusData::findClosestFocusNode(Component* component) +{ + if (component == nullptr) + { + return nullptr; + } + + auto* current = component->parent(); + while (current != nullptr) + { + // Check if we've hit an artboard boundary + if (current->is()) + { + auto* artboard = current->as(); + // Try to cross the artboard boundary via the host component + auto* host = artboard->host(); + if (host != nullptr) + { + auto* hostComponent = host->hostComponent(); + if (hostComponent != nullptr && + hostComponent->is()) + { + // Continue searching from the host component (e.g., + // NestedArtboard) + current = hostComponent->as(); + continue; + } + } +#ifdef WITH_RIVE_TOOLS + // Fall back to externally-set parent focus node (editor scenario) + auto externalNode = artboard->externalParentFocusNode(); + if (externalNode != nullptr) + { + return externalNode; + } +#endif + // No way to traverse up, stop searching + return nullptr; + } + + // Check if this node has a FocusData child + if (current->is()) + { + for (auto* child : current->as()->children()) + { + if (child->is()) + { + return child->as()->focusNode(); + } + } + } + + current = current->parent(); + } + return nullptr; +} + +namespace +{ + +bool componentAllowsFocusTraversal(const Component* c) +{ + if (c == nullptr || c->isCollapsed()) + { + return false; + } + if (c->is()) + { + if (c->as()->isHidden()) + { + return false; + } + } + if (c->is()) + { + if (c->as()->renderOpacity() <= 0.0f) + { + return false; + } + } + return true; +} + +} // namespace + +bool FocusData::isEligibleForFocusTraversal() const +{ + if (isCollapsed()) + { + return false; + } + Component* start = parent(); + if (start == nullptr) + { + return true; + } + if (!componentAllowsFocusTraversal(start)) + { + return false; + } + ParentTraversal traversal(start); + while (true) + { + ContainerComponent* p = traversal.next(); + if (p == nullptr) + { + break; + } + if (!componentAllowsFocusTraversal(p)) + { + return false; + } + if (traversal.didCrossBoundary()) + { + ArtboardHost* host = traversal.crossingHost(); + if (host != nullptr) + { + Component* hc = host->hostComponent(); + if (hc != nullptr) + { + if (!componentAllowsFocusTraversal(hc)) + { + return false; + } + if (hc->is() && + hc->as()->isPaused()) + { + return false; + } + } + } + } + } + return true; +} + +bool FocusData::worldPosition(Vec2D& outPosition) +{ + // Get local position from parent transform component + auto* parentComponent = parent(); + if (!parentComponent || !parentComponent->is()) + { + return false; + } + Vec2D localPos = + parentComponent->as()->worldTranslation(); + + // Transform to root artboard space (handles nested artboards) + auto* ab = artboard(); + if (ab) + { + outPosition = ab->rootTransform(localPos); + } + else + { + outPosition = localPos; + } + return true; +} + +void FocusData::nameChanged() +{ + if (m_focusNode != nullptr) + { + m_focusNode->name(name()); + } +} + +void FocusData::buildDependencies() +{ + Super::buildDependencies(); + // Depend on parent's world transform so we update when it moves + auto* parentComponent = parent(); + if (parentComponent != nullptr) + { + parentComponent->addDependent(this); + } +} + +void FocusData::update(ComponentDirt value) +{ + if ((value & ComponentDirt::WorldTransform) == + ComponentDirt::WorldTransform) + { + updateWorldBounds(); + } +} + +void FocusData::updateWorldBounds() +{ + if (m_focusNode == nullptr) + { + return; + } + + auto* parentComponent = parent(); + if (parentComponent != nullptr && parentComponent->is()) + { + // LayoutComponent has worldBounds based on its layout dimensions + AABB bounds = parentComponent->as()->worldBounds(); + // Transform to root artboard space (handles nested artboards) + auto* ab = artboard(); + if (ab != nullptr) + { + Vec2D min = ab->rootTransform(Vec2D(bounds.minX, bounds.minY)); + Vec2D max = ab->rootTransform(Vec2D(bounds.maxX, bounds.maxY)); + bounds = AABB(min.x, min.y, max.x, max.y); + } + m_focusNode->worldBounds(bounds); + } + else + { + // For non-layout parents, clear bounds (will fall back to position) + m_focusNode->clearWorldBounds(); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/foreground_layout_drawable.cpp b/thirdparty/rive/source/foreground_layout_drawable.cpp index a54bb3fbb..a7fd62ada 100644 --- a/thirdparty/rive/source/foreground_layout_drawable.cpp +++ b/thirdparty/rive/source/foreground_layout_drawable.cpp @@ -32,6 +32,10 @@ void ForegroundLayoutDrawable::update(ComponentDirt value) { propagateOpacity(parentLayout->childOpacity()); } + if (hasDirt(value, ComponentDirt::Path | ComponentDirt::WorldTransform)) + { + invalidateStrokeEffects(); + } } } @@ -76,4 +80,4 @@ ShapePaintPath* ForegroundLayoutDrawable::localPath() ShapePaintPath* ForegroundLayoutDrawable::localClockwisePath() { return parent()->as()->localClockwisePath(); -} +} \ No newline at end of file diff --git a/thirdparty/rive/source/generated/animation/focus_action_base.cpp b/thirdparty/rive/source/generated/animation/focus_action_base.cpp new file mode 100644 index 000000000..e012c98ee --- /dev/null +++ b/thirdparty/rive/source/generated/animation/focus_action_base.cpp @@ -0,0 +1,4 @@ +#include "rive/generated/animation/focus_action_base.hpp" +#include "rive/animation/focus_action.hpp" + +using namespace rive; diff --git a/thirdparty/rive/source/generated/animation/focus_action_target_base.cpp b/thirdparty/rive/source/generated/animation/focus_action_target_base.cpp new file mode 100644 index 000000000..b86b6fe96 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/focus_action_target_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/focus_action_target_base.hpp" +#include "rive/animation/focus_action_target.hpp" + +using namespace rive; + +Core* FocusActionTargetBase::clone() const +{ + auto cloned = new FocusActionTarget(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/focus_action_traversal_base.cpp b/thirdparty/rive/source/generated/animation/focus_action_traversal_base.cpp new file mode 100644 index 000000000..2ab758f56 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/focus_action_traversal_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/focus_action_traversal_base.hpp" +#include "rive/animation/focus_action_traversal.hpp" + +using namespace rive; + +Core* FocusActionTraversalBase::clone() const +{ + auto cloned = new FocusActionTraversal(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_base.cpp b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_base.cpp new file mode 100644 index 000000000..dd617a1f7 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_types/listener_input_type_base.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" + +using namespace rive; + +Core* ListenerInputTypeBase::clone() const +{ + auto cloned = new ListenerInputType(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_event_base.cpp b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_event_base.cpp new file mode 100644 index 000000000..befa4e510 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_event_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_types/listener_input_type_event_base.hpp" +#include "rive/animation/listener_types/listener_input_type_event.hpp" + +using namespace rive; + +Core* ListenerInputTypeEventBase::clone() const +{ + auto cloned = new ListenerInputTypeEvent(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_keyboard_base.cpp b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_keyboard_base.cpp new file mode 100644 index 000000000..663f41518 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_keyboard_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp" +#include "rive/animation/listener_types/listener_input_type_keyboard.hpp" + +using namespace rive; + +Core* ListenerInputTypeKeyboardBase::clone() const +{ + auto cloned = new ListenerInputTypeKeyboard(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_semantic_base.cpp b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_semantic_base.cpp new file mode 100644 index 000000000..3f774b4f5 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_semantic_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp" +#include "rive/animation/listener_types/listener_input_type_semantic.hpp" + +using namespace rive; + +Core* ListenerInputTypeSemanticBase::clone() const +{ + auto cloned = new ListenerInputTypeSemantic(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_text_base.cpp b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_text_base.cpp new file mode 100644 index 000000000..8678ee4c5 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_text_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_types/listener_input_type_text_base.hpp" +#include "rive/animation/listener_types/listener_input_type_text.hpp" + +using namespace rive; + +Core* ListenerInputTypeTextBase::clone() const +{ + auto cloned = new ListenerInputTypeText(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_viewmodel_base.cpp b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_viewmodel_base.cpp new file mode 100644 index 000000000..0dc9637d7 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/listener_types/listener_input_type_viewmodel_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_types/listener_input_type_viewmodel_base.hpp" +#include "rive/animation/listener_types/listener_input_type_viewmodel.hpp" + +using namespace rive; + +Core* ListenerInputTypeViewModelBase::clone() const +{ + auto cloned = new ListenerInputTypeViewModel(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/scripted_listener_action_base.cpp b/thirdparty/rive/source/generated/animation/scripted_listener_action_base.cpp new file mode 100644 index 000000000..6ac036e4e --- /dev/null +++ b/thirdparty/rive/source/generated/animation/scripted_listener_action_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/scripted_listener_action_base.hpp" +#include "rive/animation/scripted_listener_action.hpp" + +using namespace rive; + +Core* ScriptedListenerActionBase::clone() const +{ + auto cloned = new ScriptedListenerAction(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/scripted_transition_condition_base.cpp b/thirdparty/rive/source/generated/animation/scripted_transition_condition_base.cpp new file mode 100644 index 000000000..d4bd6d1dc --- /dev/null +++ b/thirdparty/rive/source/generated/animation/scripted_transition_condition_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/scripted_transition_condition_base.hpp" +#include "rive/animation/scripted_transition_condition.hpp" + +using namespace rive; + +Core* ScriptedTransitionConditionBase::clone() const +{ + auto cloned = new ScriptedTransitionCondition(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/state_machine_fire_action_base.cpp b/thirdparty/rive/source/generated/animation/state_machine_fire_action_base.cpp new file mode 100644 index 000000000..cd8eec4a1 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/state_machine_fire_action_base.cpp @@ -0,0 +1,4 @@ +#include "rive/generated/animation/state_machine_fire_action_base.hpp" +#include "rive/animation/state_machine_fire_action.hpp" + +using namespace rive; diff --git a/thirdparty/rive/source/generated/animation/state_machine_fire_event.cpp b/thirdparty/rive/source/generated/animation/state_machine_fire_event.cpp index 568d11bc7..5b2a2c2fd 100644 --- a/thirdparty/rive/source/generated/animation/state_machine_fire_event.cpp +++ b/thirdparty/rive/source/generated/animation/state_machine_fire_event.cpp @@ -7,18 +7,6 @@ using namespace rive; -StatusCode StateMachineFireEvent::import(ImportStack& importStack) -{ - auto stateImporter = importStack.latest( - StateMachineLayerComponent::typeKey); - if (stateImporter == nullptr) - { - return StatusCode::MissingObject; - } - stateImporter->addFireEvent(this); - return Super::import(importStack); -} - void StateMachineFireEvent::perform( StateMachineInstance* stateMachineInstance) const { diff --git a/thirdparty/rive/source/generated/animation/state_machine_fire_trigger_base.cpp b/thirdparty/rive/source/generated/animation/state_machine_fire_trigger_base.cpp new file mode 100644 index 000000000..734398d4d --- /dev/null +++ b/thirdparty/rive/source/generated/animation/state_machine_fire_trigger_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/state_machine_fire_trigger_base.hpp" +#include "rive/animation/state_machine_fire_trigger.hpp" + +using namespace rive; + +Core* StateMachineFireTriggerBase::clone() const +{ + auto cloned = new StateMachineFireTrigger(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/state_machine_listener_single_base.cpp b/thirdparty/rive/source/generated/animation/state_machine_listener_single_base.cpp new file mode 100644 index 000000000..7fe37ed44 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/state_machine_listener_single_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/state_machine_listener_single_base.hpp" +#include "rive/animation/state_machine_listener_single.hpp" + +using namespace rive; + +Core* StateMachineListenerSingleBase::clone() const +{ + auto cloned = new StateMachineListenerSingle(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/transition_property_component_comparator_base.cpp b/thirdparty/rive/source/generated/animation/transition_property_component_comparator_base.cpp new file mode 100644 index 000000000..3524c905f --- /dev/null +++ b/thirdparty/rive/source/generated/animation/transition_property_component_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_property_component_comparator_base.hpp" +#include "rive/animation/transition_property_component_comparator.hpp" + +using namespace rive; + +Core* TransitionPropertyComponentComparatorBase::clone() const +{ + auto cloned = new TransitionPropertyComponentComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/transition_self_comparator_base.cpp b/thirdparty/rive/source/generated/animation/transition_self_comparator_base.cpp new file mode 100644 index 000000000..e82b711a4 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/transition_self_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_self_comparator_base.hpp" +#include "rive/animation/transition_self_comparator.hpp" + +using namespace rive; + +Core* TransitionSelfComparatorBase::clone() const +{ + auto cloned = new TransitionSelfComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/transition_value_artboard_comparator_base.cpp b/thirdparty/rive/source/generated/animation/transition_value_artboard_comparator_base.cpp new file mode 100644 index 000000000..e7ac4618e --- /dev/null +++ b/thirdparty/rive/source/generated/animation/transition_value_artboard_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_artboard_comparator_base.hpp" +#include "rive/animation/transition_value_artboard_comparator.hpp" + +using namespace rive; + +Core* TransitionValueArtboardComparatorBase::clone() const +{ + auto cloned = new TransitionValueArtboardComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/transition_value_asset_comparator_base.cpp b/thirdparty/rive/source/generated/animation/transition_value_asset_comparator_base.cpp new file mode 100644 index 000000000..6cddb1e71 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/transition_value_asset_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_asset_comparator_base.hpp" +#include "rive/animation/transition_value_asset_comparator.hpp" + +using namespace rive; + +Core* TransitionValueAssetComparatorBase::clone() const +{ + auto cloned = new TransitionValueAssetComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/animation/transition_value_id_comparator_base.cpp b/thirdparty/rive/source/generated/animation/transition_value_id_comparator_base.cpp new file mode 100644 index 000000000..e68034821 --- /dev/null +++ b/thirdparty/rive/source/generated/animation/transition_value_id_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_id_comparator_base.hpp" +#include "rive/animation/transition_value_id_comparator.hpp" + +using namespace rive; + +Core* TransitionValueIdComparatorBase::clone() const +{ + auto cloned = new TransitionValueIdComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/artboard_list_map_rule_base.cpp b/thirdparty/rive/source/generated/artboard_list_map_rule_base.cpp new file mode 100644 index 000000000..2e6730776 --- /dev/null +++ b/thirdparty/rive/source/generated/artboard_list_map_rule_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/artboard_list_map_rule_base.hpp" +#include "rive/artboard_list_map_rule.hpp" + +using namespace rive; + +Core* ArtboardListMapRuleBase::clone() const +{ + auto cloned = new ArtboardListMapRule(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/assets/blob_asset_base.cpp b/thirdparty/rive/source/generated/assets/blob_asset_base.cpp new file mode 100644 index 000000000..da8be57c5 --- /dev/null +++ b/thirdparty/rive/source/generated/assets/blob_asset_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/assets/blob_asset_base.hpp" +#include "rive/assets/blob_asset.hpp" + +using namespace rive; + +Core* BlobAssetBase::clone() const +{ + auto cloned = new BlobAsset(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/assets/manifest_asset_base.cpp b/thirdparty/rive/source/generated/assets/manifest_asset_base.cpp new file mode 100644 index 000000000..4c7da9313 --- /dev/null +++ b/thirdparty/rive/source/generated/assets/manifest_asset_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/assets/manifest_asset_base.hpp" +#include "rive/assets/manifest_asset.hpp" + +using namespace rive; + +Core* ManifestAssetBase::clone() const +{ + auto cloned = new ManifestAsset(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/assets/script_asset_base.cpp b/thirdparty/rive/source/generated/assets/script_asset_base.cpp new file mode 100644 index 000000000..f6ab59345 --- /dev/null +++ b/thirdparty/rive/source/generated/assets/script_asset_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/assets/script_asset_base.hpp" +#include "rive/assets/script_asset.hpp" + +using namespace rive; + +Core* ScriptAssetBase::clone() const +{ + auto cloned = new ScriptAsset(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/assets/shader_asset_base.cpp b/thirdparty/rive/source/generated/assets/shader_asset_base.cpp new file mode 100644 index 000000000..69e52e7e8 --- /dev/null +++ b/thirdparty/rive/source/generated/assets/shader_asset_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/assets/shader_asset_base.hpp" +#include "rive/assets/shader_asset.hpp" + +using namespace rive; + +Core* ShaderAssetBase::clone() const +{ + auto cloned = new ShaderAsset(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/constraints/list_follow_path_constraint_base.cpp b/thirdparty/rive/source/generated/constraints/list_follow_path_constraint_base.cpp new file mode 100644 index 000000000..340dfc00f --- /dev/null +++ b/thirdparty/rive/source/generated/constraints/list_follow_path_constraint_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/constraints/list_follow_path_constraint_base.hpp" +#include "rive/constraints/list_follow_path_constraint.hpp" + +using namespace rive; + +Core* ListFollowPathConstraintBase::clone() const +{ + auto cloned = new ListFollowPathConstraint(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/custom_property_color_base.cpp b/thirdparty/rive/source/generated/custom_property_color_base.cpp new file mode 100644 index 000000000..76c92d965 --- /dev/null +++ b/thirdparty/rive/source/generated/custom_property_color_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/custom_property_color_base.hpp" +#include "rive/custom_property_color.hpp" + +using namespace rive; + +Core* CustomPropertyColorBase::clone() const +{ + auto cloned = new CustomPropertyColor(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/custom_property_enum_base.cpp b/thirdparty/rive/source/generated/custom_property_enum_base.cpp new file mode 100644 index 000000000..be813d6fb --- /dev/null +++ b/thirdparty/rive/source/generated/custom_property_enum_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/custom_property_enum_base.hpp" +#include "rive/custom_property_enum.hpp" + +using namespace rive; + +Core* CustomPropertyEnumBase::clone() const +{ + auto cloned = new CustomPropertyEnum(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/custom_property_trigger_base.cpp b/thirdparty/rive/source/generated/custom_property_trigger_base.cpp new file mode 100644 index 000000000..ed6a5ab9f --- /dev/null +++ b/thirdparty/rive/source/generated/custom_property_trigger_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/custom_property_trigger_base.hpp" +#include "rive/custom_property_trigger.hpp" + +using namespace rive; + +Core* CustomPropertyTriggerBase::clone() const +{ + auto cloned = new CustomPropertyTrigger(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/data_bind/bindable_property_artboard_base.cpp b/thirdparty/rive/source/generated/data_bind/bindable_property_artboard_base.cpp new file mode 100644 index 000000000..9fb5e52bc --- /dev/null +++ b/thirdparty/rive/source/generated/data_bind/bindable_property_artboard_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_artboard_base.hpp" +#include "rive/data_bind/bindable_property_artboard.hpp" + +using namespace rive; + +Core* BindablePropertyArtboardBase::clone() const +{ + auto cloned = new BindablePropertyArtboard(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/data_bind/bindable_property_list_base.cpp b/thirdparty/rive/source/generated/data_bind/bindable_property_list_base.cpp new file mode 100644 index 000000000..017e2b1de --- /dev/null +++ b/thirdparty/rive/source/generated/data_bind/bindable_property_list_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_list_base.hpp" +#include "rive/data_bind/bindable_property_list.hpp" + +using namespace rive; + +Core* BindablePropertyListBase::clone() const +{ + auto cloned = new BindablePropertyList(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/data_bind/bindable_property_viewmodel_base.cpp b/thirdparty/rive/source/generated/data_bind/bindable_property_viewmodel_base.cpp new file mode 100644 index 000000000..b7c39afe6 --- /dev/null +++ b/thirdparty/rive/source/generated/data_bind/bindable_property_viewmodel_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_viewmodel_base.hpp" +#include "rive/data_bind/bindable_property_viewmodel.hpp" + +using namespace rive; + +Core* BindablePropertyViewModelBase::clone() const +{ + auto cloned = new BindablePropertyViewModel(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/data_bind/converters/data_converter_list_to_length_base.cpp b/thirdparty/rive/source/generated/data_bind/converters/data_converter_list_to_length_base.cpp new file mode 100644 index 000000000..aa1c4a594 --- /dev/null +++ b/thirdparty/rive/source/generated/data_bind/converters/data_converter_list_to_length_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_list_to_length_base.hpp" +#include "rive/data_bind/converters/data_converter_list_to_length.hpp" + +using namespace rive; + +Core* DataConverterListToLengthBase::clone() const +{ + auto cloned = new DataConverterListToLength(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/data_bind/converters/data_converter_to_number_base.cpp b/thirdparty/rive/source/generated/data_bind/converters/data_converter_to_number_base.cpp new file mode 100644 index 000000000..1ff9a87b3 --- /dev/null +++ b/thirdparty/rive/source/generated/data_bind/converters/data_converter_to_number_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_to_number_base.hpp" +#include "rive/data_bind/converters/data_converter_to_number.hpp" + +using namespace rive; + +Core* DataConverterToNumberBase::clone() const +{ + auto cloned = new DataConverterToNumber(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/data_bind/data_bind_path_base.cpp b/thirdparty/rive/source/generated/data_bind/data_bind_path_base.cpp new file mode 100644 index 000000000..4dcb38321 --- /dev/null +++ b/thirdparty/rive/source/generated/data_bind/data_bind_path_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/data_bind_path_base.hpp" +#include "rive/data_bind/data_bind_path.hpp" + +using namespace rive; + +Core* DataBindPathBase::clone() const +{ + auto cloned = new DataBindPath(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/focus_data_base.cpp b/thirdparty/rive/source/generated/focus_data_base.cpp new file mode 100644 index 000000000..0cdf2cc32 --- /dev/null +++ b/thirdparty/rive/source/generated/focus_data_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/focus_data_base.hpp" +#include "rive/focus_data.hpp" + +using namespace rive; + +Core* FocusDataBase::clone() const +{ + auto cloned = new FocusData(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/inputs/keyboard_input_base.cpp b/thirdparty/rive/source/generated/inputs/keyboard_input_base.cpp new file mode 100644 index 000000000..8846aca2f --- /dev/null +++ b/thirdparty/rive/source/generated/inputs/keyboard_input_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/inputs/keyboard_input_base.hpp" +#include "rive/inputs/keyboard_input.hpp" + +using namespace rive; + +Core* KeyboardInputBase::clone() const +{ + auto cloned = new KeyboardInput(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/inputs/semantic_input_base.cpp b/thirdparty/rive/source/generated/inputs/semantic_input_base.cpp new file mode 100644 index 000000000..ac6d2b817 --- /dev/null +++ b/thirdparty/rive/source/generated/inputs/semantic_input_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/inputs/semantic_input_base.hpp" +#include "rive/inputs/semantic_input.hpp" + +using namespace rive; + +Core* SemanticInputBase::clone() const +{ + auto cloned = new SemanticInput(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/inputs/user_input_base.cpp b/thirdparty/rive/source/generated/inputs/user_input_base.cpp new file mode 100644 index 000000000..a8a0447ad --- /dev/null +++ b/thirdparty/rive/source/generated/inputs/user_input_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/inputs/user_input_base.hpp" +#include "rive/inputs/user_input.hpp" + +using namespace rive; + +Core* UserInputBase::clone() const +{ + auto cloned = new UserInput(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/layout/artboard_component_list_override_base.cpp b/thirdparty/rive/source/generated/layout/artboard_component_list_override_base.cpp new file mode 100644 index 000000000..83cc2000e --- /dev/null +++ b/thirdparty/rive/source/generated/layout/artboard_component_list_override_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout/artboard_component_list_override_base.hpp" +#include "rive/layout/artboard_component_list_override.hpp" + +using namespace rive; + +Core* ArtboardComponentListOverrideBase::clone() const +{ + auto cloned = new ArtboardComponentListOverride(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_artboard_base.cpp b/thirdparty/rive/source/generated/script_input_artboard_base.cpp new file mode 100644 index 000000000..4d85c9525 --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_artboard_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_artboard_base.hpp" +#include "rive/script_input_artboard.hpp" + +using namespace rive; + +Core* ScriptInputArtboardBase::clone() const +{ + auto cloned = new ScriptInputArtboard(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_boolean_base.cpp b/thirdparty/rive/source/generated/script_input_boolean_base.cpp new file mode 100644 index 000000000..32c459885 --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_boolean_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_boolean_base.hpp" +#include "rive/script_input_boolean.hpp" + +using namespace rive; + +Core* ScriptInputBooleanBase::clone() const +{ + auto cloned = new ScriptInputBoolean(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_color_base.cpp b/thirdparty/rive/source/generated/script_input_color_base.cpp new file mode 100644 index 000000000..90ac80051 --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_color_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_color_base.hpp" +#include "rive/script_input_color.hpp" + +using namespace rive; + +Core* ScriptInputColorBase::clone() const +{ + auto cloned = new ScriptInputColor(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_number_base.cpp b/thirdparty/rive/source/generated/script_input_number_base.cpp new file mode 100644 index 000000000..dd9b042cf --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_number_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_number_base.hpp" +#include "rive/script_input_number.hpp" + +using namespace rive; + +Core* ScriptInputNumberBase::clone() const +{ + auto cloned = new ScriptInputNumber(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_string_base.cpp b/thirdparty/rive/source/generated/script_input_string_base.cpp new file mode 100644 index 000000000..44e26bdd7 --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_string_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_string_base.hpp" +#include "rive/script_input_string.hpp" + +using namespace rive; + +Core* ScriptInputStringBase::clone() const +{ + auto cloned = new ScriptInputString(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_trigger_base.cpp b/thirdparty/rive/source/generated/script_input_trigger_base.cpp new file mode 100644 index 000000000..d8da2540e --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_trigger_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_trigger_base.hpp" +#include "rive/script_input_trigger.hpp" + +using namespace rive; + +Core* ScriptInputTriggerBase::clone() const +{ + auto cloned = new ScriptInputTrigger(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/script_input_viewmodel_property_base.cpp b/thirdparty/rive/source/generated/script_input_viewmodel_property_base.cpp new file mode 100644 index 000000000..a5617030b --- /dev/null +++ b/thirdparty/rive/source/generated/script_input_viewmodel_property_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/script_input_viewmodel_property_base.hpp" +#include "rive/script_input_viewmodel_property.hpp" + +using namespace rive; + +Core* ScriptInputViewModelPropertyBase::clone() const +{ + auto cloned = new ScriptInputViewModelProperty(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/scripted/scripted_data_converter_base.cpp b/thirdparty/rive/source/generated/scripted/scripted_data_converter_base.cpp new file mode 100644 index 000000000..015b73045 --- /dev/null +++ b/thirdparty/rive/source/generated/scripted/scripted_data_converter_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/scripted/scripted_data_converter_base.hpp" +#include "rive/scripted/scripted_data_converter.hpp" + +using namespace rive; + +Core* ScriptedDataConverterBase::clone() const +{ + auto cloned = new ScriptedDataConverter(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/scripted/scripted_drawable_base.cpp b/thirdparty/rive/source/generated/scripted/scripted_drawable_base.cpp new file mode 100644 index 000000000..58dfbed36 --- /dev/null +++ b/thirdparty/rive/source/generated/scripted/scripted_drawable_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/scripted/scripted_drawable_base.hpp" +#include "rive/scripted/scripted_drawable.hpp" + +using namespace rive; + +Core* ScriptedDrawableBase::clone() const +{ + auto cloned = new ScriptedDrawable(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/scripted/scripted_layout_base.cpp b/thirdparty/rive/source/generated/scripted/scripted_layout_base.cpp new file mode 100644 index 000000000..a54bb6bb8 --- /dev/null +++ b/thirdparty/rive/source/generated/scripted/scripted_layout_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/scripted/scripted_layout_base.hpp" +#include "rive/scripted/scripted_layout.hpp" + +using namespace rive; + +Core* ScriptedLayoutBase::clone() const +{ + auto cloned = new ScriptedLayout(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/scripted/scripted_path_effect_base.cpp b/thirdparty/rive/source/generated/scripted/scripted_path_effect_base.cpp new file mode 100644 index 000000000..b8a32f182 --- /dev/null +++ b/thirdparty/rive/source/generated/scripted/scripted_path_effect_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/scripted/scripted_path_effect_base.hpp" +#include "rive/scripted/scripted_path_effect.hpp" + +using namespace rive; + +Core* ScriptedPathEffectBase::clone() const +{ + auto cloned = new ScriptedPathEffect(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/semantic/semantic_data_base.cpp b/thirdparty/rive/source/generated/semantic/semantic_data_base.cpp new file mode 100644 index 000000000..cc916a854 --- /dev/null +++ b/thirdparty/rive/source/generated/semantic/semantic_data_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/semantic/semantic_data_base.hpp" +#include "rive/semantic/semantic_data.hpp" + +using namespace rive; + +Core* SemanticDataBase::clone() const +{ + auto cloned = new SemanticData(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/shapes/list_path_base.cpp b/thirdparty/rive/source/generated/shapes/list_path_base.cpp new file mode 100644 index 000000000..7e7a3629d --- /dev/null +++ b/thirdparty/rive/source/generated/shapes/list_path_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/shapes/list_path_base.hpp" +#include "rive/shapes/list_path.hpp" + +using namespace rive; + +Core* ListPathBase::clone() const +{ + auto cloned = new ListPath(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/shapes/paint/group_effect_base.cpp b/thirdparty/rive/source/generated/shapes/paint/group_effect_base.cpp new file mode 100644 index 000000000..4f626d39f --- /dev/null +++ b/thirdparty/rive/source/generated/shapes/paint/group_effect_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/shapes/paint/group_effect_base.hpp" +#include "rive/shapes/paint/group_effect.hpp" + +using namespace rive; + +Core* GroupEffectBase::clone() const +{ + auto cloned = new GroupEffect(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/shapes/paint/target_effect_base.cpp b/thirdparty/rive/source/generated/shapes/paint/target_effect_base.cpp new file mode 100644 index 000000000..3205576b5 --- /dev/null +++ b/thirdparty/rive/source/generated/shapes/paint/target_effect_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/shapes/paint/target_effect_base.hpp" +#include "rive/shapes/paint/target_effect.hpp" + +using namespace rive; + +Core* TargetEffectBase::clone() const +{ + auto cloned = new TargetEffect(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/text/text_style_paint_base.cpp b/thirdparty/rive/source/generated/text/text_style_paint_base.cpp index 77a3a5aae..9465e7f14 100644 --- a/thirdparty/rive/source/generated/text/text_style_paint_base.cpp +++ b/thirdparty/rive/source/generated/text/text_style_paint_base.cpp @@ -1,6 +1,5 @@ #include "rive/generated/text/text_style_paint_base.hpp" #include "rive/text/text_style_paint.hpp" -#include "rive/text/text_variation_helper.hpp" using namespace rive; diff --git a/thirdparty/rive/source/generated/viewmodel/viewmodel_instance_artboard_base.cpp b/thirdparty/rive/source/generated/viewmodel/viewmodel_instance_artboard_base.cpp new file mode 100644 index 000000000..7c6499d5b --- /dev/null +++ b/thirdparty/rive/source/generated/viewmodel/viewmodel_instance_artboard_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp" +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" + +using namespace rive; + +Core* ViewModelInstanceArtboardBase::clone() const +{ + auto cloned = new ViewModelInstanceArtboard(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/viewmodel/viewmodel_instance_value_base.cpp b/thirdparty/rive/source/generated/viewmodel/viewmodel_instance_value_base.cpp new file mode 100644 index 000000000..9bfe8cf82 --- /dev/null +++ b/thirdparty/rive/source/generated/viewmodel/viewmodel_instance_value_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_value_base.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" + +using namespace rive; + +Core* ViewModelInstanceValueBase::clone() const +{ + auto cloned = new ViewModelInstanceValue(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/generated/viewmodel/viewmodel_property_artboard_base.cpp b/thirdparty/rive/source/generated/viewmodel/viewmodel_property_artboard_base.cpp new file mode 100644 index 000000000..0c88b7afc --- /dev/null +++ b/thirdparty/rive/source/generated/viewmodel/viewmodel_property_artboard_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_artboard_base.hpp" +#include "rive/viewmodel/viewmodel_property_artboard.hpp" + +using namespace rive; + +Core* ViewModelPropertyArtboardBase::clone() const +{ + auto cloned = new ViewModelPropertyArtboard(); + cloned->copy(*this); + return cloned; +} diff --git a/thirdparty/rive/source/importers/backboard_importer.cpp b/thirdparty/rive/source/importers/backboard_importer.cpp index 6329fdfd2..f9662a70f 100644 --- a/thirdparty/rive/source/importers/backboard_importer.cpp +++ b/thirdparty/rive/source/importers/backboard_importer.cpp @@ -9,11 +9,13 @@ #include "rive/constraints/scrolling/scroll_physics.hpp" #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/file.hpp" #include "rive/data_bind/converters/data_converter.hpp" #include "rive/data_bind/converters/data_converter_group_item.hpp" #include "rive/data_bind/converters/data_converter_range_mapper.hpp" #include "rive/data_bind/converters/data_converter_interpolator.hpp" #include "rive/data_bind/data_bind.hpp" +#include "rive/script_input_artboard.hpp" #include using namespace rive; @@ -21,12 +23,12 @@ using namespace rive; BackboardImporter::BackboardImporter(Backboard* backboard) : m_Backboard(backboard), m_NextArtboardId(0) {} -void BackboardImporter::addNestedArtboard(NestedArtboard* artboard) +void BackboardImporter::addArtboardReferencer(ArtboardReferencer* artboard) { - m_NestedArtboards.push_back(artboard); + m_ArtboardsReferencers.push_back(artboard); } -void BackboardImporter::addFileAsset(FileAsset* asset) +void BackboardImporter::addFileAsset(rcp asset) { m_FileAssets.push_back(asset); { @@ -63,6 +65,9 @@ void BackboardImporter::addFileAssetReferencer(FileAssetReferencer* referencer) void BackboardImporter::addArtboard(Artboard* artboard) { +#ifdef WITH_RIVE_TOOLS + artboard->artboardId((uint16_t)m_NextArtboardId); +#endif m_ArtboardLookup[m_NextArtboardId++] = artboard; } @@ -70,15 +75,16 @@ void BackboardImporter::addMissingArtboard() { m_NextArtboardId++; } StatusCode BackboardImporter::resolve() { - for (auto nestedArtboard : m_NestedArtboards) + for (auto nestedArtboard : m_ArtboardsReferencers) { - auto itr = m_ArtboardLookup.find(nestedArtboard->artboardId()); + auto itr = + m_ArtboardLookup.find(nestedArtboard->referencedArtboardId()); if (itr != m_ArtboardLookup.end()) { auto artboard = itr->second; if (artboard != nullptr) { - nestedArtboard->nest(artboard); + nestedArtboard->referencedArtboard(artboard); } } } diff --git a/thirdparty/rive/source/importers/data_bind_path_importer.cpp b/thirdparty/rive/source/importers/data_bind_path_importer.cpp new file mode 100644 index 000000000..9808ea806 --- /dev/null +++ b/thirdparty/rive/source/importers/data_bind_path_importer.cpp @@ -0,0 +1,15 @@ +#include "rive/data_bind/data_bind_path.hpp" +#include "rive/importers/data_bind_path_importer.hpp" + +using namespace rive; + +DataBindPathImporter::DataBindPathImporter(DataBindPath* obj) : + m_dataBindPath(obj) +{} + +DataBindPath* DataBindPathImporter::claim() +{ + auto path = m_dataBindPath; + m_dataBindPath = nullptr; + return path; +} \ No newline at end of file diff --git a/thirdparty/rive/source/importers/data_converter_formula_importer.cpp b/thirdparty/rive/source/importers/data_converter_formula_importer.cpp index 7657a48cf..4c7f5422a 100644 --- a/thirdparty/rive/source/importers/data_converter_formula_importer.cpp +++ b/thirdparty/rive/source/importers/data_converter_formula_importer.cpp @@ -11,6 +11,6 @@ DataConverterFormulaImporter::DataConverterFormulaImporter( StatusCode DataConverterFormulaImporter::resolve() { - m_dataConverterFormula->initialize(); + m_dataConverterFormula->calculateFormula(); return StatusCode::Ok; } \ No newline at end of file diff --git a/thirdparty/rive/source/importers/file_asset_importer.cpp b/thirdparty/rive/source/importers/file_asset_importer.cpp index 0d5d8f062..6a8eb7eeb 100644 --- a/thirdparty/rive/source/importers/file_asset_importer.cpp +++ b/thirdparty/rive/source/importers/file_asset_importer.cpp @@ -10,9 +10,9 @@ using namespace rive; FileAssetImporter::FileAssetImporter(FileAsset* fileAsset, rcp assetLoader, Factory* factory) : - m_FileAsset(fileAsset), - m_FileAssetLoader(std::move(assetLoader)), - m_Factory(factory) + m_fileAsset(fileAsset), + m_fileAssetLoader(std::move(assetLoader)), + m_factory(factory) {} // if file asset contents are found when importing a rive file, store those for @@ -21,29 +21,29 @@ void FileAssetImporter::onFileAssetContents( std::unique_ptr contents) { // we should only ever be called once - assert(!m_Content); - m_Content = std::move(contents); + assert(!m_content); + m_content = std::move(contents); } StatusCode FileAssetImporter::resolve() { Span bytes; - if (m_Content != nullptr) + if (m_content != nullptr) { - bytes = m_Content->bytes(); + bytes = m_content->bytes(); } // If we have a file asset loader, lets give it the opportunity to claim // responsibility for loading the asset - if (m_FileAssetLoader != nullptr && - m_FileAssetLoader->loadContents(*m_FileAsset, bytes, m_Factory)) + if (m_fileAssetLoader != nullptr && + m_fileAssetLoader->loadContents(*m_fileAsset, bytes, m_factory)) { return StatusCode::Ok; } // If we do not, but we have found in band contents, load those else if (bytes.size() > 0) { - m_FileAsset->decode(m_Content->bytes(), m_Factory); + m_fileAsset->decode(m_content->bytes(), m_factory); } // Note that it's ok for an asset to not resolve (or to resolve async). diff --git a/thirdparty/rive/source/importers/listener_input_type_keyboard_importer.cpp b/thirdparty/rive/source/importers/listener_input_type_keyboard_importer.cpp new file mode 100644 index 000000000..dd091bb37 --- /dev/null +++ b/thirdparty/rive/source/importers/listener_input_type_keyboard_importer.cpp @@ -0,0 +1,13 @@ +#include "rive/importers/listener_input_type_keyboard_importer.hpp" + +using namespace rive; + +ListenerInputTypeKeyboardImporter::ListenerInputTypeKeyboardImporter( + ListenerInputTypeKeyboard* listenerInputTypeKeyboard) : + m_listenerInputTypeKeyboard(listenerInputTypeKeyboard) +{} + +StatusCode ListenerInputTypeKeyboardImporter::resolve() +{ + return StatusCode::Ok; +} diff --git a/thirdparty/rive/source/importers/listener_input_type_semantic_importer.cpp b/thirdparty/rive/source/importers/listener_input_type_semantic_importer.cpp new file mode 100644 index 000000000..23e13cd19 --- /dev/null +++ b/thirdparty/rive/source/importers/listener_input_type_semantic_importer.cpp @@ -0,0 +1,13 @@ +#include "rive/importers/listener_input_type_semantic_importer.hpp" + +using namespace rive; + +ListenerInputTypeSemanticImporter::ListenerInputTypeSemanticImporter( + ListenerInputTypeSemantic* listenerInputTypeSemantic) : + m_listenerInputTypeSemantic(listenerInputTypeSemantic) +{} + +StatusCode ListenerInputTypeSemanticImporter::resolve() +{ + return StatusCode::Ok; +} diff --git a/thirdparty/rive/source/importers/scripted_object_importer.cpp b/thirdparty/rive/source/importers/scripted_object_importer.cpp new file mode 100644 index 000000000..8b13910ba --- /dev/null +++ b/thirdparty/rive/source/importers/scripted_object_importer.cpp @@ -0,0 +1,22 @@ +#include "rive/artboard.hpp" +#include "rive/custom_property.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/importers/scripted_object_importer.hpp" + +using namespace rive; + +ScriptedObjectImporter::ScriptedObjectImporter(ScriptedObject* obj) : + m_scriptedObject(obj) +{} + +void ScriptedObjectImporter::addInput(CustomProperty* value) +{ + auto input = ScriptInput::from(value); + if (input != nullptr) + { + m_scriptedObject->addProperty(value); + } +} + +StatusCode ScriptedObjectImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/thirdparty/rive/source/importers/state_machine_importer.cpp b/thirdparty/rive/source/importers/state_machine_importer.cpp index de29f246c..67eac5817 100644 --- a/thirdparty/rive/source/importers/state_machine_importer.cpp +++ b/thirdparty/rive/source/importers/state_machine_importer.cpp @@ -39,4 +39,9 @@ bool StateMachineImporter::readNullObject() return true; } +void StateMachineImporter::addScriptedObject(ScriptedObject* object) +{ + m_StateMachine->addScriptedObject(object); +} + StatusCode StateMachineImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/thirdparty/rive/source/importers/state_machine_layer_component_importer.cpp b/thirdparty/rive/source/importers/state_machine_layer_component_importer.cpp index 4ea47caf0..4cbee5365 100644 --- a/thirdparty/rive/source/importers/state_machine_layer_component_importer.cpp +++ b/thirdparty/rive/source/importers/state_machine_layer_component_importer.cpp @@ -1,6 +1,7 @@ #include "rive/importers/state_machine_layer_component_importer.hpp" +#include "rive/animation/listener_action.hpp" #include "rive/animation/state_machine_layer_component.hpp" -#include "rive/animation/state_machine_fire_event.hpp" +#include "rive/animation/state_machine_fire_action.hpp" using namespace rive; @@ -18,7 +19,14 @@ StateMachineLayerComponentImporter::StateMachineLayerComponentImporter( {} void StateMachineLayerComponentImporter::addFireEvent( - StateMachineFireEvent* fireEvent) + StateMachineFireAction* fireEvent) { m_stateMachineLayerComponent->m_events.push_back(fireEvent); +} + +void StateMachineLayerComponentImporter::addListenerAction( + std::unique_ptr action) +{ + m_stateMachineLayerComponent->m_listenerActions.push_back( + std::move(action)); } \ No newline at end of file diff --git a/thirdparty/rive/source/importers/state_machine_listener_importer.cpp b/thirdparty/rive/source/importers/state_machine_listener_importer.cpp index 19257bed2..82d0dfde3 100644 --- a/thirdparty/rive/source/importers/state_machine_listener_importer.cpp +++ b/thirdparty/rive/source/importers/state_machine_listener_importer.cpp @@ -1,4 +1,5 @@ #include "rive/animation/listener_action.hpp" +#include "rive/animation/listener_types/listener_input_type.hpp" #include "rive/importers/state_machine_listener_importer.hpp" #include "rive/animation/state_machine_listener.hpp" @@ -15,4 +16,10 @@ void StateMachineListenerImporter::addAction( m_StateMachineListener->addAction(std::move(action)); } +void StateMachineListenerImporter::addListenerInputType( + std::unique_ptr listenerInputType) +{ + m_StateMachineListener->addListenerInputType(std::move(listenerInputType)); +} + StatusCode StateMachineListenerImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/thirdparty/rive/source/importers/text_asset_importer.cpp b/thirdparty/rive/source/importers/text_asset_importer.cpp new file mode 100644 index 000000000..221109da9 --- /dev/null +++ b/thirdparty/rive/source/importers/text_asset_importer.cpp @@ -0,0 +1,114 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/importers/text_asset_importer.hpp" +#include "rive/importers/file_asset_importer.hpp" +#include "rive/assets/file_asset_contents.hpp" +#include "rive/assets/text_asset.hpp" +#include "rive/signed_content_header.hpp" +#include "rive/file_asset_loader.hpp" +#include "rive/span.hpp" +#include +#include "libhydrogen.h" + +using namespace rive; + +namespace rive +{ +#ifdef WITH_RIVE_TEST_SIGNATURE +// Test-only public key matching the sample private key in +// `packages/rive_core/lib/runtime/signing_context.dart::_samplePrivateKey` +// (the last 32 bytes of that 64-byte libhydrogen keypair). Lets a runtime +// build verify .riv files signed locally via `SampleSigningContext`, which +// is useful for end-to-end testing the export+load pipeline without the +// production signing backend. NEVER enable this flag on a shipping build — +// it accepts .rivs any attacker could produce. +const uint8_t g_scriptVerificationPublicKey[32] = { + 180, 113, 86, 235, 225, 24, 110, 236, 105, 86, 201, 6, 73, 5, 203, 102, + 81, 179, 12, 240, 226, 55, 103, 134, 227, 94, 82, 187, 51, 178, 96, 46}; +#else +// Public key for in-band content signature verification (32 bytes) +const uint8_t g_scriptVerificationPublicKey[32] = { + 159, 202, 90, 135, 12, 153, 157, 21, 112, 103, 62, + 130, 59, 196, 187, 236, 103, 210, 239, 227, 175, 97, + 222, 254, 70, 53, 212, 18, 191, 143, 101, 108}; +#endif +} // namespace rive + +TextAssetImporter::TextAssetImporter( + TextAsset* fileAsset, + rcp assetLoader, + Factory* factory, + std::vector* verificationSet) : + FileAssetImporter(fileAsset, assetLoader, factory), + m_verificationSet(verificationSet) +{} + +TextAsset* TextAssetImporter::textAsset() +{ + return m_fileAsset->as(); +} + +void TextAssetImporter::onFileAssetContents( + std::unique_ptr contents) +{ + // When contents are found in-band, this asset's raw bytes become part of + // the aggregate verification set. Strip the SignedContentHeader first. + auto& bytes = contents->bytes(); + SignedContentHeader header(Span(bytes.data(), bytes.size())); + if (header.isValid()) + { + auto content = header.content(); + SimpleArray rawContent(content.data(), content.size()); + m_verificationSet->emplace_back(InBandContent(textAsset(), rawContent)); + } + FileAssetImporter::onFileAssetContents(std::move(contents)); +} + +InBandContent::InBandContent(TextAsset* asset, SimpleArray& content) : + m_textAsset(asset), m_bytes(SimpleArray(content)) +{} + +StatusCode TextAssetImporter::resolve() +{ + auto status = FileAssetImporter::resolve(); + if (status != StatusCode::Ok) + { + return status; + } + + if (m_content && !m_content->signature().empty()) + { + std::vector combinedBytecode; + // Concatenate every in-band payload captured so far. + for (auto& inband : *m_verificationSet) + { + SimpleArray& bytecode = inband.m_bytes; + combinedBytecode.insert(combinedBytecode.end(), + bytecode.begin(), + bytecode.end()); + } + + Span signature = m_content->signature(); + if (signature.size() != hydro_sign_BYTES) + { + return StatusCode::Ok; + } + int isVerified = hydro_sign_verify(signature.data(), + combinedBytecode.data(), + combinedBytecode.size(), + "RiveCode", + g_scriptVerificationPublicKey); + + // Propagate the aggregate verification result to every participating + // TextAsset (Luau modules and RSTB blobs alike). + for (auto& inband : *m_verificationSet) + { + inband.m_textAsset->m_verified = isVerified == 0; + } + m_verificationSet->clear(); + } + + // Note that it's ok for an asset to not resolve (or to resolve async). + return StatusCode::Ok; +} + +#endif diff --git a/thirdparty/rive/source/importers/transition_viewmodel_condition_importer.cpp b/thirdparty/rive/source/importers/transition_viewmodel_condition_importer.cpp index 13108f11a..5c71f7ee0 100644 --- a/thirdparty/rive/source/importers/transition_viewmodel_condition_importer.cpp +++ b/thirdparty/rive/source/importers/transition_viewmodel_condition_importer.cpp @@ -14,4 +14,10 @@ void TransitionViewModelConditionImporter::setComparator( TransitionComparator* comparator) { m_TransitionViewModelCondition->comparator(comparator); +} + +StatusCode TransitionViewModelConditionImporter::resolve() +{ + m_TransitionViewModelCondition->initialize(); + return StatusCode::Ok; } \ No newline at end of file diff --git a/thirdparty/rive/source/importers/viewmodel_instance_list_importer.cpp b/thirdparty/rive/source/importers/viewmodel_instance_list_importer.cpp index c66b5d018..8d01cc863 100644 --- a/thirdparty/rive/source/importers/viewmodel_instance_list_importer.cpp +++ b/thirdparty/rive/source/importers/viewmodel_instance_list_importer.cpp @@ -8,7 +8,8 @@ ViewModelInstanceListImporter::ViewModelInstanceListImporter( ViewModelInstanceList* viewModelInstanceList) : m_ViewModelInstanceList(viewModelInstanceList) {} -void ViewModelInstanceListImporter::addItem(ViewModelInstanceListItem* listItem) +void ViewModelInstanceListImporter::addItem( + rcp listItem) { m_ViewModelInstanceList->internalAddItem(listItem); } diff --git a/thirdparty/rive/source/input/focus_manager.cpp b/thirdparty/rive/source/input/focus_manager.cpp new file mode 100644 index 000000000..3738613f2 --- /dev/null +++ b/thirdparty/rive/source/input/focus_manager.cpp @@ -0,0 +1,968 @@ +/* + * Copyright 2024 Rive + */ + +#include "rive/input/focus_manager.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_host.hpp" +#include "rive/focus_data.hpp" +#include "rive/math/aabb.hpp" +#include +#include +#include +#include + +namespace rive +{ + +static bool focusNodeEligibleForFocus(FocusNode* node) +{ + if (node == nullptr || !node->canFocus()) + { + return false; + } +#ifdef WITH_RIVE_TOOLS + if (node->isCollapsed()) + { + return false; + } +#endif + Focusable* f = node->focusable(); + if (f == nullptr) + { + return true; + } + return f->isEligibleForFocusTraversal(); +} + +static bool focusNodeEligibleForTraversal(FocusNode* node) +{ + if (node == nullptr || !node->canTraverse()) + { + return false; + } + return focusNodeEligibleForFocus(node); +} + +void FocusManager::dropFocusIfFocusTargetHidden() +{ + if (m_primaryFocus == nullptr) + { + return; + } + if (!focusNodeEligibleForTraversal(m_primaryFocus.get())) + { + clearFocus(); + } +} + +Artboard* FocusManager::primaryFocusArtboard() const +{ + if (m_primaryFocus == nullptr || m_primaryFocus->focusable() == nullptr) + { + return nullptr; + } + + // Get the immediate artboard containing the focused element + Artboard* artboard = m_primaryFocus->focusable()->focusableArtboard(); + if (artboard == nullptr) + { + return nullptr; + } + + // Walk up the nested artboard chain to find the root (one with no host) + // The root artboard is the one mounted by Dart, which has no host. + while (artboard->host() != nullptr && + artboard->host()->parentArtboard() != nullptr) + { + artboard = artboard->host()->parentArtboard(); + } + + return artboard; +} + +FocusManager::~FocusManager() +{ + // Don't call clearFocus() here - it would invoke callbacks on FocusNodes, + // but during destruction (especially Dart finalizers) callbacks may be + // invalid. Just clear the reference directly. + for (auto node : m_rootNodes) + { + removeManager(node); + } + m_primaryFocus = nullptr; +} + +void FocusManager::removeManager(rcp node) +{ + for (const auto& child : node->children()) + { + removeManager(child); + } + node->m_manager = nullptr; +} + +void FocusManager::setFocus(rcp node) +{ + if (node == m_primaryFocus) + { + return; + } + + if (node && !node->canFocus()) + { + return; + } + + if (node != nullptr && !focusNodeEligibleForFocus(node.get())) + { + return; + } + FocusNode* oldFocus = m_primaryFocus.get(); + m_primaryFocus = std::move(node); + notifyFocusChange(oldFocus, m_primaryFocus.get()); +} + +void FocusManager::clearFocus() +{ + if (m_primaryFocus) + { + // Move to local variable to keep node alive during notification. + // Setting m_primaryFocus to nullptr first ensures hasFocus() returns + // false during the blurred() callback, but the node stays alive until + // notification completes. + auto oldFocus = std::move(m_primaryFocus); + notifyFocusChange(oldFocus.get(), nullptr); + // oldFocus is released here after notification is complete + } +} + +bool FocusManager::hasFocus(rcp node) const +{ + // The hasFocus flag on the node is maintained by notifyFocusChange + return node && node->hasFocus(); +} + +bool FocusManager::hasPrimaryFocus(rcp node) const +{ + return m_primaryFocus == node; +} + +void FocusManager::addChild(rcp parent, rcp child) +{ + if (!child) + { + return; + } + + // Remove from old location first + if (child->parent()) + { + child->removeFromParent(); + } + else + { + // Remove from root nodes if it was a root + auto it = std::find(m_rootNodes.begin(), m_rootNodes.end(), child); + if (it != m_rootNodes.end()) + { + m_rootNodes.erase(it); + } + } + + // Set the manager reference on the child + child->m_manager = this; + + if (parent) + { + parent->addChild(std::move(child)); + } + else + { + // Add to root nodes + m_rootNodes.push_back(std::move(child)); + } +} + +void FocusManager::removeChild(rcp child) +{ + if (!child) + { + return; + } + + // Clear focus if this node or descendant has focus + if (hasFocus(child)) + { + clearFocus(); + } + + // Clear the manager reference + child->m_manager = nullptr; + + if (child->parent()) + { + child->removeFromParent(); + } + else + { + // Remove from root nodes + auto it = std::find(m_rootNodes.begin(), m_rootNodes.end(), child); + if (it != m_rootNodes.end()) + { + m_rootNodes.erase(it); + } + } +} + +bool FocusManager::focusNext() +{ + dropFocusIfFocusTargetHidden(); + return findNextFocusable(m_primaryFocus.get(), true) != nullptr; +} + +bool FocusManager::focusPrevious() +{ + dropFocusIfFocusTargetHidden(); + return findNextFocusable(m_primaryFocus.get(), false) != nullptr; +} + +// Helper to get root-space world position from FocusNode +// Computes center from bounds if available, falls back to Focusable +static bool getRootPosition(FocusNode* node, Vec2D& outPosition) +{ + if (!node) + { + return false; + } + // First try bounds stored directly on FocusNode (set during update cycle) + if (node->hasWorldBounds()) + { + outPosition = node->worldBounds().center(); + return true; + } + // Fall back to Focusable for legacy implementations + if (node->focusable()) + { + return node->focusable()->worldPosition(outPosition); + } + return false; +} + +// Helper to get root-space world bounds from FocusNode +// First checks bounds stored on FocusNode, falls back to Focusable +static bool getRootBounds(FocusNode* node, AABB& outBounds) +{ + if (!node) + { + return false; + } + // First try bounds stored directly on FocusNode (set during update cycle) + if (node->hasWorldBounds()) + { + outBounds = node->worldBounds(); + return true; + } + // Fall back to Focusable for legacy implementations + if (node->focusable()) + { + return node->focusable()->worldBounds(outBounds); + } + return false; +} + +// Helper to check if a node is a leaf (no traversable children) +static bool isLeaf(FocusNode* node) +{ + for (const auto& child : node->children()) + { + if (child->canFocus() && child->canTraverse()) + { + return false; + } + } + return true; +} + +// Helper to collect all traversable leaf focus nodes recursively +// Only collects leaves (nodes with no traversable children) to match +// next/prev behavior +static void collectAllTraversableNodes(const std::vector>& nodes, + std::vector& result) +{ + for (const auto& node : nodes) + { + if (node->canFocus() && node->canTraverse() && isLeaf(node.get()) && + focusNodeEligibleForTraversal(node.get())) + { + result.push_back(node.get()); + } + // Recurse into children + collectAllTraversableNodes(node->children(), result); + } +} + +// Calculate overlap on the orthogonal axis (perpendicular to navigation) +// Returns the length of overlap, or 0 if no overlap +static float calculateOverlap(float aMin, float aMax, float bMin, float bMax) +{ + float overlapMin = std::max(aMin, bMin); + float overlapMax = std::min(aMax, bMax); + return std::max(0.0f, overlapMax - overlapMin); +} + +// CSS Spatial Navigation-inspired scoring for bounds-aware navigation +// Formula: distance = displacement + orthogonalWeight * orthogonalDistance - +// sqrt(overlap) +struct ScoreBreakdown +{ + float displacement; + float orthogonalDistance; + float overlap; + float orthogonalWeight; + float total; + bool rejected; +}; + +static ScoreBreakdown scoreCandidateBoundsDetailed(const AABB& current, + const AABB& candidate, + Direction direction) +{ + // CSS Spatial Navigation weights + const float horizontalWeight = 30.0f; + const float verticalWeight = 2.0f; + + ScoreBreakdown result = {}; + + switch (direction) + { + case Direction::left: + // Displacement: distance from current's left edge to candidate's + // right edge + result.displacement = current.left() - candidate.right(); + if (result.displacement < 0) + { + result.rejected = true; + result.total = std::numeric_limits::max(); + return result; + } + // Orthogonal: vertical distance between closest edges + result.orthogonalDistance = + std::max(0.0f, + std::max(candidate.top() - current.bottom(), + current.top() - candidate.bottom())); + result.overlap = calculateOverlap(current.top(), + current.bottom(), + candidate.top(), + candidate.bottom()); + result.orthogonalWeight = horizontalWeight; + break; + + case Direction::right: + result.displacement = candidate.left() - current.right(); + if (result.displacement < 0) + { + result.rejected = true; + result.total = std::numeric_limits::max(); + return result; + } + result.orthogonalDistance = + std::max(0.0f, + std::max(candidate.top() - current.bottom(), + current.top() - candidate.bottom())); + result.overlap = calculateOverlap(current.top(), + current.bottom(), + candidate.top(), + candidate.bottom()); + result.orthogonalWeight = horizontalWeight; + break; + + case Direction::up: + result.displacement = current.top() - candidate.bottom(); + if (result.displacement < 0) + { + result.rejected = true; + result.total = std::numeric_limits::max(); + return result; + } + result.orthogonalDistance = + std::max(0.0f, + std::max(candidate.left() - current.right(), + current.left() - candidate.right())); + result.overlap = calculateOverlap(current.left(), + current.right(), + candidate.left(), + candidate.right()); + result.orthogonalWeight = verticalWeight; + break; + + case Direction::down: + result.displacement = candidate.top() - current.bottom(); + if (result.displacement < 0) + { + result.rejected = true; + result.total = std::numeric_limits::max(); + return result; + } + result.orthogonalDistance = + std::max(0.0f, + std::max(candidate.left() - current.right(), + current.left() - candidate.right())); + result.overlap = calculateOverlap(current.left(), + current.right(), + candidate.left(), + candidate.right()); + result.orthogonalWeight = verticalWeight; + break; + } + + // CSS-inspired formula: displacement + weighted orthogonal - sqrt(overlap) + // The sqrt(overlap) bonus favors candidates that are "in line" with current + result.total = result.displacement + + result.orthogonalWeight * result.orthogonalDistance - + std::sqrt(result.overlap); + return result; +} + +static float scoreCandidateBounds(const AABB& current, + const AABB& candidate, + Direction direction) +{ + return scoreCandidateBoundsDetailed(current, candidate, direction).total; +} + +// Point-based scoring fallback for nodes without bounds +static float scoreCandidatePoint(const Vec2D& currentPos, + const Vec2D& candidatePos, + Direction direction) +{ + const float horizontalWeight = 30.0f; + const float verticalWeight = 2.0f; + + Vec2D delta = candidatePos - currentPos; + float primary, orthogonal, orthogonalWeight; + + switch (direction) + { + case Direction::left: + primary = -delta.x; + orthogonal = std::abs(delta.y); + orthogonalWeight = horizontalWeight; + break; + case Direction::right: + primary = delta.x; + orthogonal = std::abs(delta.y); + orthogonalWeight = horizontalWeight; + break; + case Direction::up: + primary = -delta.y; + orthogonal = std::abs(delta.x); + orthogonalWeight = verticalWeight; + break; + case Direction::down: + primary = delta.y; + orthogonal = std::abs(delta.x); + orthogonalWeight = verticalWeight; + break; + } + + if (primary <= 0) + { + return std::numeric_limits::max(); + } + + return primary + orthogonalWeight * orthogonal; +} + +FocusNode* FocusManager::findNodeInDirection(FocusNode* current, + Direction direction) const +{ + if (!current) + { + return nullptr; + } + + std::vector candidates; + collectAllTraversableNodes(m_rootNodes, candidates); + + FocusNode* best = nullptr; + float bestScore = std::numeric_limits::max(); + + // Try to get bounds for current node + AABB currentBounds; + bool currentHasBounds = getRootBounds(current, currentBounds); + + // Fallback to position if no bounds + Vec2D currentPos; + if (!currentHasBounds && !getRootPosition(current, currentPos)) + { + return nullptr; + } + + for (FocusNode* candidate : candidates) + { + if (candidate == current) + { + continue; + } + + float score; + + // Try bounds-based scoring first + AABB candidateBounds; + if (currentHasBounds && getRootBounds(candidate, candidateBounds)) + { + score = + scoreCandidateBounds(currentBounds, candidateBounds, direction); + } + else + { + // Fall back to point-based scoring + Vec2D candidatePos; + if (!getRootPosition(candidate, candidatePos)) + { + continue; + } + + if (currentHasBounds) + { + // Use center of current bounds + score = scoreCandidatePoint(currentBounds.center(), + candidatePos, + direction); + } + else + { + score = + scoreCandidatePoint(currentPos, candidatePos, direction); + } + } + + if (score < bestScore) + { + bestScore = score; + best = candidate; + } + } + + return best; +} + +bool FocusManager::focusLeft() +{ + dropFocusIfFocusTargetHidden(); + FocusNode* next = + findNodeInDirection(m_primaryFocus.get(), Direction::left); + if (next) + { + setFocus(ref_rcp(next)); + return true; + } + return false; +} + +bool FocusManager::focusRight() +{ + dropFocusIfFocusTargetHidden(); + FocusNode* next = + findNodeInDirection(m_primaryFocus.get(), Direction::right); + if (next) + { + setFocus(ref_rcp(next)); + return true; + } + return false; +} + +bool FocusManager::focusUp() +{ + dropFocusIfFocusTargetHidden(); + FocusNode* next = findNodeInDirection(m_primaryFocus.get(), Direction::up); + if (next) + { + setFocus(ref_rcp(next)); + return true; + } + return false; +} + +bool FocusManager::focusDown() +{ + dropFocusIfFocusTargetHidden(); + FocusNode* next = + findNodeInDirection(m_primaryFocus.get(), Direction::down); + if (next) + { + setFocus(ref_rcp(next)); + return true; + } + return false; +} + +bool FocusManager::keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + dropFocusIfFocusTargetHidden(); + // Bubble up through focus tree until someone handles the input + FocusNode* node = m_primaryFocus.get(); + while (node != nullptr) + { + if (node->keyInput(key, modifiers, isPressed, isRepeat)) + { + return true; + } + node = node->parent(); + } + return false; +} + +bool FocusManager::textInput(const std::string& text) +{ + dropFocusIfFocusTargetHidden(); + // Bubble up through focus tree until someone handles the input + FocusNode* node = m_primaryFocus.get(); + while (node != nullptr) + { + if (node->textInput(text)) + { + return true; + } + node = node->parent(); + } + return false; +} + +void FocusManager::notifyFocusChange(FocusNode* oldFocus, FocusNode* newFocus) +{ + // Find the common ancestor to avoid unnecessary blur/focus notifications + // on shared ancestors + FocusNode* commonAncestor = nullptr; + if (oldFocus != nullptr && newFocus != nullptr) + { + // Build a set of ancestors from oldFocus + std::unordered_set oldAncestors; + for (FocusNode* node = oldFocus; node != nullptr; node = node->parent()) + { + oldAncestors.insert(node); + } + // Find the first ancestor of newFocus that's also an ancestor of + // oldFocus + for (FocusNode* node = newFocus; node != nullptr; node = node->parent()) + { + if (oldAncestors.count(node) > 0) + { + commonAncestor = node; + break; + } + } + } + + // Walk up from oldFocus, clear hasFocus flag and notify blurred + // Stop at common ancestor (don't blur it or its ancestors) + FocusNode* current = oldFocus; + while (current != nullptr && current != commonAncestor && + current->hasFocus()) + { + current->setHasFocus(false); + current->blurred(); + current = current->parent(); + } + + // Walk up from newFocus, set hasFocus flag and notify focused + // Stop at common ancestor (don't re-focus it or its ancestors) + current = newFocus; + while (current != nullptr && current != commonAncestor && + !current->hasFocus()) + { + current->setHasFocus(true); + current->focused(); + current = current->parent(); + } + +#ifdef WITH_RIVE_TOOLS + if (m_focusChangedCallback) + { + m_focusChangedCallback(); + } + + // Check if we should fire scroll-into-view callback for Dart-mounted + // artboards. This happens when the focused element is in an artboard + // whose root has no host (mounted by Dart). + if (m_scrollIntoViewCallback && newFocus != nullptr) + { + AABB bounds; + if (getRootBounds(newFocus, bounds)) + { + // Get the immediate artboard containing the focused element + Artboard* artboard = + newFocus->focusable() != nullptr + ? newFocus->focusable()->focusableArtboard() + : nullptr; + if (artboard != nullptr) + { + // Walk up to find the highest artboard (host == nullptr). + // This is the artboard that Dart is hosting. + while (artboard->host() != nullptr && + artboard->host()->parentArtboard() != nullptr) + { + artboard = artboard->host()->parentArtboard(); + } + + // If this artboard has no host, it's Dart-mounted + // Pass it to the callback so Dart can find and scroll it + if (artboard->host() == nullptr) + { + m_scrollIntoViewCallback(bounds, artboard); + } + } + } + } +#endif +} + +std::vector FocusManager::getTraversableNodes( + FocusNode* scope) const +{ + std::vector result; + + // Get children from scope or root nodes + const std::vector>* childList = + scope ? &scope->children() : &m_rootNodes; + + for (const auto& child : *childList) + { + if (focusNodeEligibleForTraversal(child.get())) + { + result.push_back(child.get()); + } + } + + // Sort by tabIndex, then by tree order (which is insertion order) + std::stable_sort(result.begin(), + result.end(), + [](FocusNode* a, FocusNode* b) { + return a->tabIndex() < b->tabIndex(); + }); + + return result; +} + +static bool hasEligibleTraversableChildInFocusTree(FocusNode* node) +{ + for (const auto& ch : node->children()) + { + if (focusNodeEligibleForTraversal(ch.get())) + { + return true; + } + } + return false; +} + +// First eligible leaf under node (deepest first); nullptr if none +static FocusNode* getFirstLeaf(FocusNode* node, const FocusManager* manager) +{ + if (node == nullptr) + { + return nullptr; + } + auto children = manager->getTraversableNodes(node); + for (FocusNode* ch : children) + { + FocusNode* leaf = getFirstLeaf(ch, manager); + if (leaf != nullptr) + { + return leaf; + } + } + if (focusNodeEligibleForTraversal(node) && + !hasEligibleTraversableChildInFocusTree(node)) + { + return node; + } + return nullptr; +} + +static FocusNode* getLastLeaf(FocusNode* node, const FocusManager* manager) +{ + if (node == nullptr) + { + return nullptr; + } + auto children = manager->getTraversableNodes(node); + for (auto it = children.rbegin(); it != children.rend(); ++it) + { + FocusNode* leaf = getLastLeaf(*it, manager); + if (leaf != nullptr) + { + return leaf; + } + } + if (focusNodeEligibleForTraversal(node) && + !hasEligibleTraversableChildInFocusTree(node)) + { + return node; + } + return nullptr; +} + +static FocusNode* firstEligibleLeafFrom( + const std::vector& traversable, + bool forward, + const FocusManager* manager) +{ + if (forward) + { + for (FocusNode* t : traversable) + { + FocusNode* leaf = getFirstLeaf(t, manager); + if (leaf != nullptr) + { + return leaf; + } + } + } + else + { + for (auto it = traversable.rbegin(); it != traversable.rend(); ++it) + { + FocusNode* leaf = getLastLeaf(*it, manager); + if (leaf != nullptr) + { + return leaf; + } + } + } + return nullptr; +} + +FocusNode* FocusManager::findNextFocusable(FocusNode* current, + bool forward) const +{ + FocusNode* scope = current ? current->parent() : nullptr; + auto traversable = getTraversableNodes(scope); + + if (traversable.empty()) + { + if (scope) + { + return findNextFocusable(scope, forward); + } + return nullptr; + } + + auto it = std::find(traversable.begin(), traversable.end(), current); + FocusNode* next = nullptr; + + if (it == traversable.end()) + { + next = firstEligibleLeafFrom(traversable, forward, this); + } + else + { + size_t idx = static_cast(it - traversable.begin()); + if (forward) + { + for (size_t i = idx + 1; i < traversable.size(); i++) + { + next = getFirstLeaf(traversable[i], this); + if (next != nullptr) + { + break; + } + } + if (next == nullptr) + { + EdgeBehavior edge = + scope ? scope->edgeBehavior() : EdgeBehavior::parentScope; + switch (edge) + { + case EdgeBehavior::closedLoop: + for (size_t i = 0; i < idx; i++) + { + next = getFirstLeaf(traversable[i], this); + if (next != nullptr) + { + break; + } + } + if (next == nullptr) + { + next = + firstEligibleLeafFrom(traversable, true, this); + } + break; + case EdgeBehavior::stop: + next = current; + break; + case EdgeBehavior::parentScope: + if (scope) + { + return findNextFocusable(scope, forward); + } + next = firstEligibleLeafFrom(traversable, true, this); + break; + } + } + } + else + { + for (int i = static_cast(idx) - 1; i >= 0; i--) + { + next = getLastLeaf(traversable[static_cast(i)], this); + if (next != nullptr) + { + break; + } + } + if (next == nullptr) + { + EdgeBehavior edge = + scope ? scope->edgeBehavior() : EdgeBehavior::parentScope; + switch (edge) + { + case EdgeBehavior::closedLoop: + for (int i = static_cast(traversable.size()) - 1; + i > static_cast(idx); + i--) + { + next = + getLastLeaf(traversable[static_cast(i)], + this); + if (next != nullptr) + { + break; + } + } + if (next == nullptr) + { + next = + firstEligibleLeafFrom(traversable, false, this); + } + break; + case EdgeBehavior::stop: + next = current; + break; + case EdgeBehavior::parentScope: + if (scope) + { + return findNextFocusable(scope, forward); + } + next = firstEligibleLeafFrom(traversable, false, this); + break; + } + } + } + } + + if (next != nullptr && next != current) + { + const_cast(this)->setFocus(ref_rcp(next)); + return next; + } + return nullptr; +} + +} // namespace rive diff --git a/thirdparty/rive/source/input/focus_node.cpp b/thirdparty/rive/source/input/focus_node.cpp new file mode 100644 index 000000000..8e30df657 --- /dev/null +++ b/thirdparty/rive/source/input/focus_node.cpp @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Rive + */ + +#include "rive/input/focus_node.hpp" +#include + +namespace rive +{ + +void FocusNode::addChild(rcp child) +{ + if (!child) + { + return; + } + + // Remove from old parent if exists + child->removeFromParent(); + + child->m_parent = this; + m_children.push_back(std::move(child)); +} + +void FocusNode::removeChild(rcp child) +{ + if (!child || child->m_parent != this) + { + return; + } + + child->m_parent = nullptr; + auto it = std::find(m_children.begin(), m_children.end(), child); + if (it != m_children.end()) + { + m_children.erase(it); + } +} + +void FocusNode::removeFromParent() +{ + if (m_parent) + { + m_parent->removeChild(ref_rcp(this)); + } +} + +} // namespace rive diff --git a/thirdparty/rive/source/input/focusable.cpp b/thirdparty/rive/source/input/focusable.cpp new file mode 100644 index 000000000..43ce68ea7 --- /dev/null +++ b/thirdparty/rive/source/input/focusable.cpp @@ -0,0 +1,23 @@ +#include "rive/input/focusable.hpp" +#include "rive/nested_artboard.hpp" +#include "rive/text/text_input.hpp" + +using namespace rive; + +Focusable* Focusable::from(Core* object) +{ + if (object == nullptr) + { + return nullptr; + } + + if (object->is()) + { + return object->as(); + } + if (object->is()) + { + return object->as(); + } + return nullptr; +} diff --git a/thirdparty/rive/source/inputs/keyboard_input.cpp b/thirdparty/rive/source/inputs/keyboard_input.cpp new file mode 100644 index 000000000..22ab2d536 --- /dev/null +++ b/thirdparty/rive/source/inputs/keyboard_input.cpp @@ -0,0 +1,28 @@ +#include "rive/inputs/keyboard_input.hpp" +#include "rive/animation/listener_types/listener_input_type_keyboard.hpp" +#include "rive/generated/animation/listener_types/listener_input_type_keyboard_base.hpp" +#include "rive/generated/artboard_base.hpp" +#include "rive/importers/artboard_importer.hpp" +#include "rive/importers/listener_input_type_keyboard_importer.hpp" + +using namespace rive; + +StatusCode KeyboardInput::import(ImportStack& importStack) +{ + auto* litImporter = importStack.latest( + ListenerInputTypeKeyboardBase::typeKey); + if (litImporter == nullptr) + { + return StatusCode::MissingObject; + } + litImporter->listenerInputTypeKeyboard()->addKeyboardInput(this); + + auto artboardImporter = + importStack.latest(ArtboardBase::typeKey); + if (artboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + artboardImporter->addComponent(this); + return Super::import(importStack); +} diff --git a/thirdparty/rive/source/inputs/semantic_input.cpp b/thirdparty/rive/source/inputs/semantic_input.cpp new file mode 100644 index 000000000..bbf7c0c77 --- /dev/null +++ b/thirdparty/rive/source/inputs/semantic_input.cpp @@ -0,0 +1,28 @@ +#include "rive/inputs/semantic_input.hpp" +#include "rive/animation/listener_types/listener_input_type_semantic.hpp" +#include "rive/generated/animation/listener_types/listener_input_type_semantic_base.hpp" +#include "rive/generated/artboard_base.hpp" +#include "rive/importers/artboard_importer.hpp" +#include "rive/importers/listener_input_type_semantic_importer.hpp" + +using namespace rive; + +StatusCode SemanticInput::import(ImportStack& importStack) +{ + auto* litImporter = importStack.latest( + ListenerInputTypeSemanticBase::typeKey); + if (litImporter == nullptr) + { + return StatusCode::MissingObject; + } + litImporter->listenerInputTypeSemantic()->addSemanticInput(this); + + auto artboardImporter = + importStack.latest(ArtboardBase::typeKey); + if (artboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + artboardImporter->addComponent(this); + return Super::import(importStack); +} diff --git a/thirdparty/rive/source/layout/artboard_component_list_override.cpp b/thirdparty/rive/source/layout/artboard_component_list_override.cpp new file mode 100644 index 000000000..72676f8ae --- /dev/null +++ b/thirdparty/rive/source/layout/artboard_component_list_override.cpp @@ -0,0 +1,78 @@ +#include "rive/container_component.hpp" +#include "rive/layout/artboard_component_list_override.hpp" +#include "rive/artboard_component_list.hpp" +#include "rive/artboard.hpp" + +using namespace rive; + +void ArtboardComponentListOverride::addArtboard(ArtboardInstance* artboard) +{ + m_artboards.push_back(artboard); + m_styleOverrider.updateWidthOverride(artboard); + m_styleOverrider.updateHeightOverride(artboard); +} + +void ArtboardComponentListOverride::removeArtboard(ArtboardInstance* artboard) +{ + m_artboards.erase( + std::remove(m_artboards.begin(), m_artboards.end(), artboard), + m_artboards.end()); +} + +bool ArtboardComponentListOverride::isRow() +{ + return parent()->is() + ? parent()->as()->mainAxisIsRow() + : true; +} + +void ArtboardComponentListOverride::updateWidthOverride() +{ + for (auto& artboardInstance : m_artboards) + { + m_styleOverrider.updateWidthOverride(artboardInstance); + } +} + +void ArtboardComponentListOverride::updateHeightOverride() +{ + for (auto& artboardInstance : m_artboards) + { + m_styleOverrider.updateHeightOverride(artboardInstance); + } +} + +void ArtboardComponentListOverride::instanceWidthChanged() +{ + updateWidthOverride(); +} +void ArtboardComponentListOverride::instanceHeightChanged() +{ + updateHeightOverride(); +} +void ArtboardComponentListOverride::instanceWidthUnitsValueChanged() +{ + updateWidthOverride(); +} +void ArtboardComponentListOverride::instanceHeightUnitsValueChanged() +{ + updateHeightOverride(); +} +void ArtboardComponentListOverride::instanceWidthScaleTypeChanged() +{ + updateWidthOverride(); +} +void ArtboardComponentListOverride::instanceHeightScaleTypeChanged() +{ + updateHeightOverride(); +} + +void ArtboardComponentListOverride::markHostingLayoutDirty( + ArtboardInstance* artboardInstance) +{ + if (artboard() != nullptr) + { + artboard()->markLayoutDirty(artboardInstance); + artboard()->markLayoutStyleDirty(); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/layout/axis.cpp b/thirdparty/rive/source/layout/axis.cpp index 0161d78ad..bc3bce099 100644 --- a/thirdparty/rive/source/layout/axis.cpp +++ b/thirdparty/rive/source/layout/axis.cpp @@ -20,4 +20,11 @@ StatusCode Axis::onAddedDirty(CoreContext* context) return StatusCode::Ok; } -void Axis::offsetChanged() { NSlicerDetails::from(parent())->axisChanged(); } +void Axis::offsetChanged() +{ + auto details = NSlicerDetails::from(parent()); + if (details != nullptr) + { + details->axisChanged(); + } +} diff --git a/thirdparty/rive/source/layout/layout_component_style.cpp b/thirdparty/rive/source/layout/layout_component_style.cpp index 3258f67ef..7f1c89038 100644 --- a/thirdparty/rive/source/layout/layout_component_style.cpp +++ b/thirdparty/rive/source/layout/layout_component_style.cpp @@ -337,9 +337,23 @@ void LayoutComponentStyle::paddingLeftChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::paddingRightChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::paddingTopChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::paddingBottomChanged() { markLayoutNodeDirty(); } -void LayoutComponentStyle::positionLeftChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionLeftChanged() +{ + if (parent()->is()) + { + parent()->as()->markPositionLeftChanged(); + } + markLayoutNodeDirty(); +} void LayoutComponentStyle::positionRightChanged() { markLayoutNodeDirty(); } -void LayoutComponentStyle::positionTopChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionTopChanged() +{ + if (parent()->is()) + { + parent()->as()->markPositionTopChanged(); + } + markLayoutNodeDirty(); +} void LayoutComponentStyle::positionBottomChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::widthUnitsValueChanged() { markLayoutNodeDirty(); } diff --git a/thirdparty/rive/source/layout/layout_node_provider.cpp b/thirdparty/rive/source/layout/layout_node_provider.cpp index 8957bdf6a..a4142163f 100644 --- a/thirdparty/rive/source/layout/layout_node_provider.cpp +++ b/thirdparty/rive/source/layout/layout_node_provider.cpp @@ -27,4 +27,5 @@ void LayoutNodeProvider::addLayoutConstraint(LayoutConstraint* constraint) m_layoutConstraints.end(), constraint) == m_layoutConstraints.end()); m_layoutConstraints.push_back(constraint); + constraint->addLayoutChild(this); } \ No newline at end of file diff --git a/thirdparty/rive/source/layout/n_sliced_node.cpp b/thirdparty/rive/source/layout/n_sliced_node.cpp index e6533f5f3..77432aef5 100644 --- a/thirdparty/rive/source/layout/n_sliced_node.cpp +++ b/thirdparty/rive/source/layout/n_sliced_node.cpp @@ -30,6 +30,11 @@ void NSlicedNode::axisChanged() { markPathDirtyRecursive(); } void NSlicedNode::widthChanged() { markPathDirtyRecursive(); } void NSlicedNode::heightChanged() { markPathDirtyRecursive(); } +AABB NSlicedNode::localBounds() const +{ + return AABB(0, 0, initialWidth(), initialHeight()); +} + void NSlicedNode::update(ComponentDirt value) { Super::update(value); diff --git a/thirdparty/rive/source/layout/n_slicer.cpp b/thirdparty/rive/source/layout/n_slicer.cpp index 2fcaafe50..2b7d89a0b 100644 --- a/thirdparty/rive/source/layout/n_slicer.cpp +++ b/thirdparty/rive/source/layout/n_slicer.cpp @@ -6,7 +6,7 @@ using namespace rive; -NSlicer::NSlicer() { m_sliceMesh = rivestd::make_unique(this); } +NSlicer::NSlicer() { m_sliceMesh = std::make_unique(this); } Image* NSlicer::image() { diff --git a/thirdparty/rive/source/layout_component.cpp b/thirdparty/rive/source/layout_component.cpp index 42759fd33..c3f4cc9bd 100644 --- a/thirdparty/rive/source/layout_component.cpp +++ b/thirdparty/rive/source/layout_component.cpp @@ -13,7 +13,6 @@ #include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/paint/stroke.hpp" #include "rive/shapes/rectangle.hpp" -#include "rive/nested_artboard_layout.hpp" #include "rive/layout/layout_data.hpp" #include "rive/layout/layout_component_style.hpp" #ifdef WITH_RIVE_LAYOUT @@ -47,6 +46,39 @@ void LayoutComponent::buildDependencies() Core* LayoutComponent::hitTest(HitInfo*, const Mat2D&) { return nullptr; } +bool LayoutComponent::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + Mat2D inverseWorld; + if (worldTransform().invert(&inverseWorld)) + { + // If the layout is not clipped and skipOnUnclipped is true, we + // don't care about whether it contains the position + auto canSkip = skipOnUnclipped && !this->clip(); + if (!canSkip) + { + auto localWorld = inverseWorld * position; + if (this->is()) + { + auto artboard = this->as(); + if (artboard->originX() != 0 || artboard->originY() != 0) + { + localWorld += + Vec2D(artboard->originX() * artboard->layoutWidth(), + artboard->originY() * artboard->layoutHeight()); + } + } + if (!localBounds().contains(localWorld)) + { + return false; + } + } + return Drawable::hitTestPoint(position, true, isPrimaryHit); + } + return false; +} + void LayoutComponent::update(ComponentDirt value) { Super::update(value); @@ -84,6 +116,9 @@ void LayoutComponent::update(ComponentDirt value) { updateRenderPath(); } + + m_positionLeftChanged = false; + m_positionTopChanged = false; } void LayoutComponent::widthOverride(float width, int unitValue, bool isRow) @@ -180,29 +215,29 @@ bool LayoutComponent::overridesKeyedInterpolation(int propertyKey) bool LayoutComponent::isHidden() const { - return Super::isHidden() || isDisplayHidden(); + return Super::isHidden() || isCollapsed(); } -bool LayoutComponent::isDisplayHidden() const +bool LayoutComponent::isCollapsed() const { -#ifdef WITH_RIVE_LAYOUT - if (m_displayHidden || parent() == nullptr || - !parent()->is()) + if (Super::isCollapsed()) { - return m_displayHidden; + return true; } - return parent()->as()->isDisplayHidden(); +#ifdef WITH_RIVE_LAYOUT + return styleDisplayHidden(); #endif return false; } void LayoutComponent::propagateCollapse(bool collapse) { - bool displayHidden = isDisplayHidden(); + auto collapsed = collapse || isCollapsed(); for (Component* child : children()) { - child->collapse(collapse || displayHidden); + child->collapse(collapsed); } + updateCollapsables(); } bool LayoutComponent::collapse(bool value) @@ -211,10 +246,7 @@ bool LayoutComponent::collapse(bool value) { return false; } - for (Component* child : children()) - { - child->collapse(value || m_displayHidden); - } + propagateCollapse(value); return true; } @@ -315,7 +347,7 @@ void LayoutComponent::draw(Renderer* renderer) void LayoutComponent::updateRenderPath() { - if (isDisplayHidden()) + if (isHidden()) { return; } @@ -353,9 +385,9 @@ void LayoutComponent::updateRenderPath() { continue; } - if (shapePaint->is()) + if (shapePaint->is()) { - shapePaint->as()->invalidateEffects(); + shapePaint->as()->invalidateEffects(); } } } @@ -461,12 +493,45 @@ void LayoutComponent::syncStyle() ygNode.setMeasureFunc(nullptr); } + // Derive the unit the layout engine needs from the persisted unit + scale + // type. + // - fill/hug always map to YGUnitAuto (regardless of position type) — + // these scale modes don't have a meaningful unit; the layout engine + // decides the size. + // - fixed uses the stored unit. Absolute layouts trust whatever's + // stored (e.g. the editor freezes a point value at the moment + // positionType becomes absolute, since absolute children sit outside + // flex flow). + bool isAbsolute = m_style->positionType() == YGPositionTypeAbsolute; + bool isLegacyHugEncoding = + m_style->widthScaleType() == LayoutScaleType::fixed && + m_style->heightScaleType() == LayoutScaleType::fixed && + m_style->intrinsicallySized() && isLeaf(); + auto effectiveUnits = [isAbsolute, + isLegacyHugEncoding](LayoutScaleType scaleType, + YGUnit storedUnits) { + if (isAbsolute && scaleType != LayoutScaleType::hug) + { + return storedUnits; + } + if (scaleType != LayoutScaleType::fixed) + { + return YGUnitAuto; + } + if (storedUnits == YGUnitPoint || storedUnits == YGUnitPercent) + { + return storedUnits; + } + return isLegacyHugEncoding ? YGUnitAuto : YGUnitPoint; + }; auto realWidth = width(); - auto realWidthUnits = m_style->widthUnits(); auto realWidthScaleType = m_style->widthScaleType(); + auto realWidthUnits = + effectiveUnits(realWidthScaleType, m_style->widthUnits()); auto realHeight = height(); - auto realHeightUnits = m_style->heightUnits(); auto realHeightScaleType = m_style->heightScaleType(); + auto realHeightUnits = + effectiveUnits(realHeightScaleType, m_style->heightUnits()); auto parentIsRow = layoutParent() != nullptr ? layoutParent()->mainAxisIsRow() : true; @@ -767,14 +832,21 @@ void LayoutComponent::syncStyle() YGValue{m_style->borderTop(), m_style->borderTopUnits()}; ygStyle.border()[YGEdgeBottom] = YGValue{m_style->borderBottom(), m_style->borderBottomUnits()}; + + bool hasLayoutParent = layoutParent() != nullptr; ygStyle.margin()[startEdge] = - YGValue{m_style->marginLeft(), m_style->marginLeftUnits()}; + YGValue{m_style->marginLeft(), + hasLayoutParent ? m_style->marginLeftUnits() : YGUnitPoint}; ygStyle.margin()[endEdge] = - YGValue{m_style->marginRight(), m_style->marginRightUnits()}; + YGValue{m_style->marginRight(), + hasLayoutParent ? m_style->marginRightUnits() : YGUnitPoint}; ygStyle.margin()[YGEdgeTop] = - YGValue{m_style->marginTop(), m_style->marginTopUnits()}; + YGValue{m_style->marginTop(), + hasLayoutParent ? m_style->marginTopUnits() : YGUnitPoint}; ygStyle.margin()[YGEdgeBottom] = - YGValue{m_style->marginBottom(), m_style->marginBottomUnits()}; + YGValue{m_style->marginBottom(), + hasLayoutParent ? m_style->marginBottomUnits() : YGUnitPoint}; + ygStyle.padding()[startEdge] = YGValue{m_style->paddingLeft(), m_style->paddingLeftUnits()}; ygStyle.padding()[endEdge] = @@ -798,6 +870,8 @@ void LayoutComponent::syncStyle() ygStyle.flexDirection() = m_style->flexDirection(); ygStyle.flexWrap() = m_style->flexWrap(); ygStyle.direction() = m_style->direction(); + ygStyle.aspectRatio() = YGFloatOptional( + m_style->aspectRatio() > 0 ? m_style->aspectRatio() : NAN); ygNode.setStyle(ygStyle); } @@ -894,15 +968,24 @@ void LayoutComponent::propagateSizeToChildren(ContainerComponent* component) } } -void LayoutComponent::calculateLayout() +void LayoutComponent::calculateLayoutInternal(float availableWidth, + float availableHeight) { + auto actualAvailWidth = + std::isnan(availableWidth) && m_style && m_style->intrinsicallySized() + ? availableWidth + : width(); + auto actualAvailHeight = + std::isnan(availableHeight) && m_style && m_style->intrinsicallySized() + ? availableHeight + : height(); YGNodeCalculateLayout(&m_layoutData->node, - width(), - height(), + actualAvailWidth, + actualAvailHeight, YGDirection::YGDirectionInherit); } -bool LayoutComponent::styleDisplayHidden() +bool LayoutComponent::styleDisplayHidden() const { if (m_style == nullptr) { @@ -965,12 +1048,6 @@ void LayoutComponent::updateLayoutBounds(bool animate) } node.setHasNewLayout(false); - if (m_style != nullptr && styleDisplayHidden() != m_displayHidden) - { - m_displayHidden = styleDisplayHidden(); - propagateCollapse(isCollapsed()); - } - for (auto child : children()) { auto layout = LayoutNodeProvider::from(child); @@ -984,6 +1061,30 @@ void LayoutComponent::updateLayoutBounds(bool animate) Layout newLayout = layoutFromYoga(yogaLayout); m_layoutPadding = layoutPaddingFromYoga(yogaLayout); + if (m_justAddedToHost) + { + m_justAddedToHost = false; + // In cases were we have a host (ie, Component List, etc), we + // don't want to animate the x/y/width/height because the initial + // x/y/width/height will have been 0,0,0,0 within the parent host. + // + // Instead, we want to the position/size to start at whatever this + // layout's computed position is within its host. + // + // We'll keep this as an entirely seperate code path because + // this may be useful in adding support for animate in/out of + // items in an ArtboardHost. + m_layout = newLayout; + auto animationData = currentAnimationData(); + animationData->from = newLayout; + animationData->to = newLayout; + animationData->elapsedSeconds = 0.0f; + propagateSize(); + markWorldTransformDirty(); + m_forceUpdateLayoutBounds = false; + return; + } + if (animate && animates()) { auto animationData = currentAnimationData(); @@ -1028,6 +1129,11 @@ void LayoutComponent::updateLayoutBounds(bool animate) bool LayoutComponent::advanceComponent(float elapsedSeconds, AdvanceFlags flags) { + if ((flags & AdvanceFlags::NewFrame) != AdvanceFlags::NewFrame) + { + return false; + } + return applyInterpolation(elapsedSeconds, (flags & AdvanceFlags::Animate) == AdvanceFlags::Animate || @@ -1152,6 +1258,13 @@ bool LayoutComponent::cascadeLayoutStyle( interpolationTime(), actualDirection()); } + else if (auto provider = LayoutNodeProvider::from(child)) + { + provider->cascadeLayoutStyle(interpolation(), + interpolator(), + interpolationTime(), + actualDirection()); + } } return updated; } @@ -1323,8 +1436,17 @@ void LayoutComponent::positionTypeChanged() } if (m_style->positionType() == YGPositionTypeAbsolute) { - m_style->positionLeft(layoutBounds().left()); - m_style->positionTop(layoutBounds().top()); + // Preserve computed position only if left/top were not explicitly keyed + // this frame. If keyed, honor those values and only set units + // appropriately. + if (!m_positionLeftChanged) + { + m_style->positionLeft(layoutBounds().left()); + } + if (!m_positionTopChanged) + { + m_style->positionTop(layoutBounds().top()); + } m_style->positionRight(0); m_style->positionBottom(0); m_style->positionLeftUnitsValue(YGUnitPoint); @@ -1352,12 +1474,6 @@ void LayoutComponent::scaleTypeChanged() { return; } - m_style->widthUnitsValue(m_style->widthScaleType() == LayoutScaleType::fixed - ? YGUnitPoint - : YGUnitAuto); - m_style->heightUnitsValue( - m_style->heightScaleType() == LayoutScaleType::fixed ? YGUnitPoint - : YGUnitAuto); m_style->intrinsicallySizedValue( m_style->widthScaleType() == LayoutScaleType::hug || m_style->heightScaleType() == LayoutScaleType::hug); @@ -1370,6 +1486,7 @@ void LayoutComponent::displayChanged() { return; } + propagateCollapse(isCollapsed()); markLayoutNodeDirty(); } @@ -1424,6 +1541,9 @@ void LayoutComponent::onDirty(ComponentDirt value) {} bool LayoutComponent::mainAxisIsRow() { return true; } bool LayoutComponent::mainAxisIsColumn() { return false; } +void LayoutComponent::calculateLayoutInternal(float availableWidth, + float availableHeight) +{} #endif LayoutComponent::~LayoutComponent() diff --git a/thirdparty/rive/source/listener_group.cpp b/thirdparty/rive/source/listener_group.cpp new file mode 100644 index 000000000..672324aea --- /dev/null +++ b/thirdparty/rive/source/listener_group.cpp @@ -0,0 +1,281 @@ +#include "rive/animation/listener_invocation.hpp" +#include "rive/animation/state_machine_listener.hpp" +#include "rive/constraints/scrolling/scroll_bar_constraint.hpp" +#include "rive/constraints/scrolling/scroll_constraint.hpp" +#include "rive/listener_group.hpp" +#include "rive/profiler/rive_profile.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/scripted/scripted_layout.hpp" + +using namespace rive; + +ListenerGroup::~ListenerGroup() +{ + for (auto& pointerData : m_pointers) + { + delete pointerData.second; + } + for (auto& pointerData : m_pointersPool) + { + delete pointerData; + } +} + +_PointerData* ListenerGroup::pointerData(int id) +{ + if (m_pointers.find(id) == m_pointers.end()) + { + if (m_pointersPool.size() > 0) + { + m_pointers[id] = m_pointersPool.back(); + m_pointersPool.pop_back(); + } + else + { + m_pointers[id] = new _PointerData(); + } + } + return m_pointers[id]; +} + +void ListenerGroup::hover(int id) +{ + auto pointer = pointerData(id); + pointer->isHovered = true; +} + +void ListenerGroup::reset(int pointerId) +{ + auto pointer = pointerData(pointerId); + if (pointer->phase != GestureClickPhase::disabled) + { + m_isConsumed = false; + pointer->isPrevHovered = pointer->isHovered; + pointer->isHovered = false; + } + if (pointer->phase == GestureClickPhase::clicked) + { + pointer->phase = GestureClickPhase::out; + } +} + +void ListenerGroup::releaseEvent(int pointerId) +{ + if (m_pointers.find(pointerId) != m_pointers.end()) + { + // Reset pointer data before caching it + auto pointerData = m_pointers[pointerId]; + pointerData->isHovered = false; + pointerData->isPrevHovered = false; + pointerData->phase = GestureClickPhase::out; + auto previousPosition = pointerData->previousPosition(); + previousPosition->x = 0; + previousPosition->y = 0; + + m_pointersPool.push_back(m_pointers[pointerId]); + m_pointers.erase(pointerId); + } +} + +void ListenerGroup::enable(int pointerId) +{ + auto pointer = pointerData(pointerId); + pointer->phase = GestureClickPhase::out; +} + +void ListenerGroup::disable(int pointerId) +{ + auto pointer = pointerData(pointerId); + pointer->phase = GestureClickPhase::disabled; + consume(); +} + +bool ListenerGroup::canEarlyOut(Component* drawable) +{ + return !(m_listener->hasListener(ListenerType::enter) || + m_listener->hasListener(ListenerType::exit) || + m_listener->hasListener(ListenerType::move) || + m_listener->hasListener(ListenerType::drag)); +} + +bool ListenerGroup::needsDownListener(Component* drawable) +{ + return m_listener->hasListener(ListenerType::down) || + m_listener->hasListener(ListenerType::click) || + m_listener->hasListener(ListenerType::drag); +} + +bool ListenerGroup::needsUpListener(Component* drawable) +{ + return m_listener->hasListener(ListenerType::up) || + m_listener->hasListener(ListenerType::click) || + m_listener->hasListener(ListenerType::drag); +} + +ProcessEventResult ListenerGroup::processEvent( + Component* component, + Vec2D position, + int pointerId, + ListenerType hitEvent, + bool canHit, + float timeStamp, + StateMachineInstance* stateMachineInstance) +{ + // Because each group is tested individually for its hover state, a + // group could be marked "incorrectly" as hovered at this point. But + // once we iterate each element in the drawing order, that group can be + // occluded by an opaque target on top of it. So although it is hovered + // in isolation, it shouldn't be considered as hovered in the full + // context. In this case, we unhover the group so it is not marked as + // previously hovered. + auto pointer = pointerData(pointerId); + auto prevPhase = pointer->phase; + if (!canHit && pointer->isHovered) + { + pointer->isHovered = false; + } + + bool isGroupHovered = canHit ? pointer->isHovered : false; + bool hoverChange = pointer->isPrevHovered != isGroupHovered; + // If hover has changes, it means that the element is hovered for the + // first time. Previous positions need to be reset to avoid jumps. + auto previousPosition = pointer->previousPosition(); + if (hoverChange && isGroupHovered) + { + previousPosition->x = position.x; + previousPosition->y = position.y; + } + + // Handle click gesture phases. A click gesture has two phases. + // First one attached to a pointer down actions, second one attached to + // a pointer up action. Both need to act on a shape of the listener + // group. + if (isGroupHovered) + { + if (hitEvent == ListenerType::down) + { + pointer->phase = GestureClickPhase::down; + } + else if (hitEvent == ListenerType::up && + pointer->phase == GestureClickPhase::down) + { + pointer->phase = GestureClickPhase::clicked; + } + } + else + { + if (hitEvent == ListenerType::down || hitEvent == ListenerType::up) + { + pointer->phase = GestureClickPhase::out; + } + } + if (prevPhase == GestureClickPhase::down && + (pointer->phase == GestureClickPhase::clicked || + pointer->phase == GestureClickPhase::out) && + m_hasDragged) + { + stateMachineInstance->dragEnd(position, timeStamp, pointerId); + m_hasDragged = false; + } + auto _listener = listener(); + bool shouldPerformChanges = false; + auto listenerTypeMatched = hitEvent; + // Always update hover states regardless of which specific listener type + // we're trying to trigger. + // If hover has changed and: + // - it's hovering and the listener is of type enter + // - it's not hovering and the listener is of type exit + if (hoverChange) + { + if (isGroupHovered && _listener->hasListener(ListenerType::enter)) + { + shouldPerformChanges = true; + listenerTypeMatched = ListenerType::enter; + } + else if ((!isGroupHovered && + _listener->hasListener(ListenerType::exit))) + { + shouldPerformChanges = true; + listenerTypeMatched = ListenerType::exit; + } + } + // Perform changes if: + // - the click gesture is complete and the listener is of type click + // - the event type matches the listener type and it is hovering the + // group + if (pointer->phase == GestureClickPhase::clicked && + _listener->hasListener(ListenerType::click)) + { + shouldPerformChanges = true; + listenerTypeMatched = ListenerType::click; + } + else if (isGroupHovered && _listener->hasListener(hitEvent)) + { + shouldPerformChanges = true; + } + // Perform changes if: + // - the listener type is drag + // - the clickPhase is down + // - the pointer type is move + if (pointer->phase == GestureClickPhase::down && + _listener->hasListener(ListenerType::drag) && + hitEvent == ListenerType::move) + { + shouldPerformChanges = true; + listenerTypeMatched = ListenerType::drag; + if (!m_hasDragged) + { + stateMachineInstance->dragStart(position, + timeStamp, + false, + pointerId); + m_hasDragged = true; + } + } + if (shouldPerformChanges) + { + _listener->performChanges( + stateMachineInstance, + ListenerInvocation::pointer( + position, + Vec2D(previousPosition->x, previousPosition->y), + pointerId, + listenerTypeMatched, + timeStamp)); + stateMachineInstance->markNeedsAdvance(); + consume(); + +#ifdef RIVE_MICROPROFILE + if (RiveProfile::instance().logFlags() & + ProfileLogListenerPerformChanges) + { + RiveProfile::instance().recordListenerPerformChange( + stateMachineInstance->artboard()->name(), + stateMachineInstance->name(), + _listener->name(), + static_cast(listenerTypeMatched), + static_cast(hitEvent), + pointerId); + } +#endif + } + previousPosition->x = position.x; + previousPosition->y = position.y; + return ProcessEventResult::pointer; +} + +ListenerGroupProvider* ListenerGroupProvider::from(Core* component) +{ + switch (component->coreType()) + { + case ScrollConstraint::typeKey: + return component->as(); + case ScrollBarConstraint::typeKey: + return component->as(); + case ScriptedLayout::typeKey: + return component->as(); + case ScriptedDrawable::typeKey: + return component->as(); + } + return nullptr; +} diff --git a/thirdparty/rive/source/lua/lua_artboards.cpp b/thirdparty/rive/source/lua/lua_artboards.cpp new file mode 100644 index 000000000..7c5011aad --- /dev/null +++ b/thirdparty/rive/source/lua/lua_artboards.cpp @@ -0,0 +1,840 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/file.hpp" +#include "rive/artboard.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/viewmodel/viewmodel_property_number.hpp" +#include "rive/viewmodel/viewmodel_property_trigger.hpp" +#include "rive/node.hpp" +#include "rive/bones/root_bone.hpp" +#include "rive/constraints/constraint.hpp" +#include "rive/math/transform_components.hpp" + +#include +#include + +using namespace rive; + +ScriptReffedArtboard::ScriptReffedArtboard( + rcp file, + std::unique_ptr&& artboardInstance, + rcp viewModelInstance, + rcp parentDataContext) : + m_file(file), + m_artboard(std::move(artboardInstance)), + m_stateMachine(m_artboard->defaultStateMachine()) +{ + if (viewModelInstance) + { + m_viewModelInstance = viewModelInstance; + } + else + { + m_viewModelInstance = m_file->createViewModelInstance(m_artboard.get()); + } + if (m_stateMachine && m_viewModelInstance) + { + if (parentDataContext) + { + auto dataContext = make_rcp(m_viewModelInstance); + dataContext->parent(parentDataContext); + m_stateMachine->bindDataContext(dataContext); + } + else + { + m_stateMachine->bindViewModelInstance(m_viewModelInstance); + } + } +} + +ScriptReffedArtboard::~ScriptReffedArtboard() +{ + // Make sure state machine is deleted before artboard since + // StateMachineInstance destructor accesses the artboard. + m_stateMachine = nullptr; + // Make sure artboard is deleted before file. + m_artboard = nullptr; + m_file = nullptr; +} + +rive::rcp ScriptReffedArtboard::file() { return m_file; } + +Artboard* ScriptReffedArtboard::artboard() { return m_artboard.get(); } + +StateMachineInstance* ScriptReffedArtboard::stateMachine() +{ + return m_stateMachine.get(); +} + +static int artboard_draw(lua_State* L) +{ + auto scriptedArtboard = lua_torive(L, 1); + auto scriptedRenderer = lua_torive(L, 2); + + auto renderer = scriptedRenderer->validate(L); + scriptedArtboard->artboard()->drawInternal(renderer); + + return 0; +} + +static int artboard_draw_canvas(lua_State* L) +{ + auto scriptedArtboard = lua_torive(L, 1); + scriptedArtboard->artboard()->internalDrawCanvases(); + + return 0; +} + +bool ScriptedArtboard::advance(float seconds) +{ + auto machine = stateMachine(); + if (machine) + { + return machine->advanceAndApply(seconds); + } + else + { + return artboard()->advance(seconds); + } +} + +static int apply_pointer_event(lua_State* L, int atom) +{ + auto scriptedArtboard = lua_torive(L, 1); + auto pointerEvent = lua_torive(L, 2); + auto result = 0; + if (scriptedArtboard->stateMachine()) + { + switch (atom) + { + case (int)LuaAtoms::pointerDown: + result = (int)scriptedArtboard->stateMachine()->pointerDown( + pointerEvent->m_position, + pointerEvent->m_id); + break; + case (int)LuaAtoms::pointerMove: + result = (int)scriptedArtboard->stateMachine()->pointerMove( + pointerEvent->m_position, + 0, + pointerEvent->m_id); + break; + case (int)LuaAtoms::pointerUp: + result = (int)scriptedArtboard->stateMachine()->pointerUp( + pointerEvent->m_position, + pointerEvent->m_id); + break; + case (int)LuaAtoms::pointerExit: + result = (int)scriptedArtboard->stateMachine()->pointerExit( + pointerEvent->m_position, + pointerEvent->m_id); + break; + } + } + lua_pushinteger(L, result); + return 1; +} + +static int artboard_advance(lua_State* L) +{ + auto scriptedArtboard = lua_torive(L, 1); + auto seconds = float(luaL_checknumber(L, 2)); + + bool advanced = scriptedArtboard->advance(seconds); + lua_pushboolean(L, advanced ? 1 : 0); + + return 1; +} + +static int artboard_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::draw: + return artboard_draw(L); + case (int)LuaAtoms::drawCanvas: + return artboard_draw_canvas(L); + case (int)LuaAtoms::advance: + return artboard_advance(L); + case (int)LuaAtoms::instance: + { + int nargs = lua_gettop(L); + auto scriptedArtboard = lua_torive(L, 1); + if (nargs == 2) + { + + auto scriptedViewModel = + lua_torive(L, 2); + return scriptedArtboard->instance( + L, + scriptedViewModel->viewModelInstance()); + } + return scriptedArtboard->instance(L, nullptr); + } + case (int)LuaAtoms::animation: + { + auto scriptedArtboard = lua_torive(L, 1); + const char* animationName = luaL_checkstring(L, 2); + return scriptedArtboard->animation(L, animationName); + } + case (int)LuaAtoms::addToPath: + { + int nargs = lua_gettop(L); + auto scriptedArtboard = lua_torive(L, 1); + auto scriptedPath = lua_torive(L, 2); + Mat2D* transform = nullptr; + if (nargs == 3) + { + auto matrix = lua_torive(L, 3); + transform = &matrix->value; + } + + scriptedArtboard->scriptReffedArtboard() + ->artboard() + ->addToRawPath(scriptedPath->rawPath, transform); + scriptedPath->markDirty(); + + return 0; + } + case (int)LuaAtoms::bounds: + { + auto scriptedArtboard = lua_torive(L, 1); + const auto& bounds = scriptedArtboard->artboard()->bounds(); + lua_pushvec2d(L, bounds.min()); + lua_pushvec2d(L, bounds.max()); + return 2; + } + case (int)LuaAtoms::node: + { + auto scriptedArtboard = lua_torive(L, 1); + const char* name = luaL_checkstring(L, 2); + auto component = + scriptedArtboard->artboard()->find( + name); + if (component == nullptr) + { + lua_pushnil(L); + return 1; + } + lua_newrive( + L, + scriptedArtboard->scriptReffedArtboard(), + component); + return 1; + } + case (int)LuaAtoms::pointerDown: + case (int)LuaAtoms::pointerUp: + case (int)LuaAtoms::pointerMove: + case (int)LuaAtoms::pointerExit: + { + return apply_pointer_event(L, atom); + } + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedArtboard::luaName); + return 0; +} + +int ScriptedArtboard::pushData(lua_State* L) +{ + if (m_dataRef != 0) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, m_dataRef); + return 1; + } + auto vm = viewModelInstance(); + if (!vm) + { + lua_pushnil(L); + } + else + { + lua_newrive(L, L, ref_rcp(vm->viewModel()), vm); + } + m_dataRef = lua_ref(L, -1); + + return 1; +} + +int ScriptedArtboard::instance(lua_State* L, + rcp viewModelInstance) +{ + auto artboardInstance = artboard()->instance(); + artboardInstance->frameOrigin(false); + lua_newrive(L, + L, + m_scriptReffedArtboard->file(), + std::move(artboardInstance), + viewModelInstance, + m_dataContext); + return 1; +} + +int ScriptedArtboard::animation(lua_State* L, const char* animationName) +{ + if (artboard()->isInstance()) + { + + auto animation = static_cast(artboard()) + ->animationNamed(animationName); + if (animation) + { + lua_newrive(L, L, std::move(animation)); + return 1; + } + } + return 0; +} + +ScriptedNode::ScriptedNode(rcp artboard, + TransformComponent* component) : + m_artboard(artboard), m_component(component) +{} + +const ShapePaint* ScriptedNode::shapePaint() +{ + if (m_shapePaint) + { + return m_shapePaint; + } + if (m_component != nullptr && m_component->is()) + { + return m_component->as(); + } + return nullptr; +} + +static int artboard_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedArtboard = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::frameOrigin: + lua_pushboolean(L, + scriptedArtboard->artboard()->frameOrigin() ? 1 + : 0); + return 1; + + case (int)LuaAtoms::width: + lua_pushnumber(L, scriptedArtboard->artboard()->width()); + return 1; + case (int)LuaAtoms::height: + lua_pushnumber(L, scriptedArtboard->artboard()->height()); + return 1; + case (int)LuaAtoms::data: + return scriptedArtboard->pushData(L); + + default: + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedArtboard::luaName); + return 0; +} + +static int artboard_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedArtboard = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::frameOrigin: + scriptedArtboard->artboard()->frameOrigin(luaL_checkboolean(L, 3) != + 0); + return 0; + case (int)LuaAtoms::width: + scriptedArtboard->artboard()->width(luaL_checknumber(L, 3)); + return 0; + case (int)LuaAtoms::height: + scriptedArtboard->artboard()->height(luaL_checknumber(L, 3)); + return 0; + default: + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedArtboard::luaName); + + return 0; +} + +ScriptedArtboard::ScriptedArtboard( + lua_State* L, + rcp file, + std::unique_ptr&& artboardInstance, + rcp viewModelInstance, + rcp dataContext) : + m_state(L), + m_scriptReffedArtboard( + make_rcp(file, + std::move(artboardInstance), + viewModelInstance, + dataContext)), + m_dataContext(dataContext) +{} + +ScriptedArtboard::~ScriptedArtboard() +{ + lua_unref(m_state, m_dataRef); + m_scriptReffedArtboard = nullptr; +} + +ScriptedAnimation::ScriptedAnimation( + lua_State* L, + std::unique_ptr animation) : + m_state(L), m_animation(std::move(animation)) +{} + +float ScriptedAnimation::duration() +{ + auto durationFrames = (float)m_animation->duration(); + auto fps = (float)m_animation->fps(); + return durationFrames / fps; +} + +int ScriptedAnimation::advance() +{ + auto seconds = float(luaL_checknumber(m_state, 2)); + + bool advanced = m_animation->advance(seconds); + m_animation->apply(); + lua_pushboolean(m_state, advanced ? 1 : 0); + return 1; +} + +int ScriptedAnimation::setTime(std::string mode) +{ + float seconds = 0; + if (mode == "seconds") + { + seconds = float(luaL_checknumber(m_state, 2)); + } + else if (mode == "frames") + { + auto frames = float(luaL_checknumber(m_state, 2)); + + seconds = frames / m_animation->fps(); + } + else if (mode == "percentage") + { + auto percentage = float(luaL_checknumber(m_state, 2)); + seconds = percentage * duration(); + } + + m_animation->time(m_animation->animation()->globalToLocalSeconds(seconds)); + m_animation->apply(); + return 0; +} + +static int node_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedNode = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::position: + lua_pushvector2(L, + scriptedNode->component()->x(), + scriptedNode->component()->y()); + return 1; + + case (int)LuaAtoms::rotation: + lua_pushnumber(L, scriptedNode->component()->rotation()); + return 1; + + case (int)LuaAtoms::scale: + lua_pushvector2(L, + scriptedNode->component()->scaleX(), + scriptedNode->component()->scaleY()); + return 1; + + case (int)LuaAtoms::scaleX: + lua_pushnumber(L, scriptedNode->component()->scaleX()); + return 1; + + case (int)LuaAtoms::scaleY: + lua_pushnumber(L, scriptedNode->component()->scaleY()); + return 1; + + case (int)LuaAtoms::worldTransform: + lua_newrive( + L, + scriptedNode->component()->worldTransform()); + return 1; + + case (int)LuaAtoms::children: + { + auto component = scriptedNode->component(); + if (component->is()) + { + auto container = component->as(); + // speculative pre-alloc the table + auto& children = container->children(); + lua_createtable(L, (int)children.size(), 0); + + int index = 1; + for (auto child : children) + { + if (child->is()) + { + lua_newrive( + L, + scriptedNode->artboard(), + child->as()); + // Set table[i] = value, pops the value + lua_rawseti(L, -2, index++); + } + } + } + return 1; + } + + case (int)LuaAtoms::parent: + { + auto parent = scriptedNode->component()->parent(); + if (parent != nullptr && parent->is()) + { + lua_newrive(L, + scriptedNode->artboard(), + parent->as()); + } + else + { + lua_pushnil(L); + } + return 1; + } + case (int)LuaAtoms::paint: + { + auto shapePaint = scriptedNode->shapePaint(); + if (shapePaint) + { + lua_newrive(L, shapePaint); + } + else + { + lua_pushnil(L); + } + return 1; + } + + default: + switch (key[0]) + { + case 'x': + lua_pushnumber(L, scriptedNode->component()->x()); + return 1; + case 'y': + lua_pushnumber(L, scriptedNode->component()->y()); + return 1; + } + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedNode::luaName); + return 0; +} + +static int node_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedNode = lua_torive(L, 1); + auto component = scriptedNode->component(); + switch (atom) + { + case (int)LuaAtoms::position: + { + const float* vec = luaL_checkvector(L, 3); + + if (component->is()) + { + Node* node = component->as(); + node->x(vec[0]); + node->y(vec[1]); + } + else if (component->is()) + { + RootBone* bone = component->as(); + bone->x(vec[0]); + bone->y(vec[1]); + } + return 0; + } + case (int)LuaAtoms::rotation: + component->rotation(float(luaL_checknumber(L, 3))); + return 0; + + case (int)LuaAtoms::scale: + { + const float* vec = luaL_checkvector(L, 3); + component->scaleX(vec[0]); + component->scaleY(vec[1]); + return 0; + } + + case (int)LuaAtoms::scaleX: + component->scaleX(float(luaL_checknumber(L, 3))); + return 0; + + case (int)LuaAtoms::scaleY: + component->scaleY(float(luaL_checknumber(L, 3))); + return 0; + + case (int)LuaAtoms::worldTransform: + { + Mat2D& transform = component->mutableWorldTransform(); + transform = *(Mat2D*)lua_torive(L, 3); + return 0; + } + + default: + switch (key[0]) + { + case 'x': + if (component->is()) + { + Node* node = component->as(); + node->x(float(luaL_checknumber(L, 3))); + } + else if (component->is()) + { + RootBone* bone = component->as(); + bone->x(float(luaL_checknumber(L, 3))); + } + return 0; + case 'y': + if (component->is()) + { + Node* node = component->as(); + node->y(float(luaL_checknumber(L, 3))); + } + else if (component->is()) + { + RootBone* bone = component->as(); + bone->y(float(luaL_checknumber(L, 3))); + } + return 0; + } + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedNode::luaName); + return 0; +} + +static int node_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::decompose: + { + auto scriptedNode = lua_torive(L, 1); + auto component = scriptedNode->component(); + Mat2D world = getParentWorld(*component).invertOrIdentity() * + (*(Mat2D*)lua_torive(L, 2)); + TransformComponents components = world.decompose(); + if (component->is()) + { + Node* node = component->as(); + node->x(components.x()); + node->y(components.y()); + } + else if (component->is()) + { + RootBone* bone = component->as(); + bone->x(components.x()); + bone->y(components.y()); + } + component->scaleX(components.scaleX()); + component->scaleY(components.scaleY()); + component->rotation(components.rotation()); + return 0; + } + + case (int)LuaAtoms::asPath: + { + + auto scriptedNode = lua_torive(L, 1); + auto component = scriptedNode->component(); + if (component->is()) + { + lua_newrive( + L, + &component->as()->rawPath()); + } + else + { + lua_pushnil(L); + } + return 1; + } + + case (int)LuaAtoms::asPaint: + { + auto scriptedNode = lua_torive(L, 1); + auto shapePaint = scriptedNode->shapePaint(); + if (shapePaint) + { + lua_newrive(L, shapePaint); + } + else + { + lua_pushnil(L); + } + return 1; + } + } + } + + luaL_error(L, "%s is not a valid method of %s", str, ScriptedNode::luaName); + return 0; +} + +static int animation_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedAnimation = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::duration: + lua_pushnumber(L, scriptedAnimation->duration()); + return 1; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedNode::luaName); + return 0; +} + +static int animation_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto scriptedAnimation = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::advance: + { + return scriptedAnimation->advance(); + } + case (int)LuaAtoms::setTime: + { + return scriptedAnimation->setTime("seconds"); + } + case (int)LuaAtoms::setTimeFrames: + { + return scriptedAnimation->setTime("frames"); + } + case (int)LuaAtoms::setTimePercentage: + { + return scriptedAnimation->setTime("percentage"); + } + } + } + + luaL_error(L, "%s is not a valid method of %s", str, ScriptedNode::luaName); + return 0; +} + +int luaopen_rive_artboards(lua_State* L) +{ + lua_register_rive(L); + + lua_pushcfunction(L, artboard_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, artboard_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, artboard_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + lua_register_rive(L); + + lua_pushcfunction(L, node_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, node_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, node_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + lua_register_rive(L); + lua_pushcfunction(L, animation_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, animation_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_pop(L, 1); // pop the metatable + + return 0; +} +#endif diff --git a/thirdparty/rive/source/lua/lua_audio.cpp b/thirdparty/rive/source/lua/lua_audio.cpp new file mode 100644 index 000000000..c15b5bf35 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_audio.cpp @@ -0,0 +1,477 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/file.hpp" +#ifdef WITH_RIVE_AUDIO +#include "rive/audio/audio_engine.hpp" +#include "rive/audio/audio_source.hpp" +#include "rive/audio/audio_sound.hpp" +#include "rive/assets/audio_asset.hpp" +#include "rive/component.hpp" +#include "rive/artboard.hpp" +#endif + +#include +#include +#include + +using namespace rive; + +#ifdef WITH_RIVE_AUDIO +void ScriptedAudioSource::source(rcp value) { m_source = value; } + +int ScriptedAudioSource::initializeSound(lua_State* L, + rcp sound, + Artboard* artboard) +{ + if (sound != nullptr) + { + if (artboard) + { + sound->volume(artboard->volume()); + } + auto* scriptedAudioSound = lua_newrive(L, artboard); + scriptedAudioSound->sound = std::move(sound); + return 1; + } + return 0; +} + +int ScriptedAudioSource::play(lua_State* L, + AudioEngine* engine, + double time, + bool isRelative) +{ + if (source() == nullptr) + { + return 0; + } +#ifdef WITH_RIVE_TOOLS + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + if (context && !context->isPlaying()) + { + return 0; + } +#endif + float startTime = time; + if (isRelative) + { + startTime += engine->timeInSeconds(); + } + rcp audioSound = + engine->playSeconds(source(), startTime, 0, 0, nullptr); + return initializeSound(L, audioSound, nullptr); +} + +int ScriptedAudioSource::play(lua_State* L, AudioEngine* engine) +{ + return play(L, engine, 0, true); +} +int ScriptedAudioSource::playFrame(lua_State* L, + AudioEngine* engine, + uint64_t startTime, + bool isRelative) +{ + if (source() == nullptr) + { + return 0; + } + +#ifdef WITH_RIVE_TOOLS + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + if (context && !context->isPlaying()) + { + return 0; + } +#endif + if (isRelative) + { + startTime += engine->timeInFrames(); + } + rcp audioSound = + engine->play(source(), startTime, 0, 0, nullptr); + return initializeSound(L, audioSound, nullptr); +} +int ScriptedAudioSource::playFrame(lua_State* L, AudioEngine* engine) +{ + return playFrame(L, engine, 0, true); +} + +static int audio_source_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto* scriptedAudioSource = lua_torive(L, 1); + if (scriptedAudioSource == nullptr || + scriptedAudioSource->source() == nullptr) + { + return 0; + } + switch (atom) + { + case (int)LuaAtoms::duration: + lua_pushnumber( + L, + (lua_Number)scriptedAudioSource->source()->duration()); + return 1; + default: + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedAudioSource::luaName); + return 0; +} + +static int audio_sound_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto* scriptedAudioSound = lua_torive(L, 1); + if (scriptedAudioSound == nullptr || + scriptedAudioSound->sound == nullptr) + { + return 0; + } + auto sound = scriptedAudioSound->sound; + switch (atom) + { + case (int)LuaAtoms::play: + { + sound->play(); + return 0; + } + case (int)LuaAtoms::pause: + { + sound->pause(); + return 0; + } + case (int)LuaAtoms::resume: + { + sound->resume(); + return 0; + } + case (int)LuaAtoms::stop: + { + uint64_t fadeTimeInFrames = 0; + if (lua_gettop(L) >= 2 && lua_isnumber(L, 2)) + { + fadeTimeInFrames = (uint64_t)lua_tonumber(L, 2); + } + sound->stop(fadeTimeInFrames); + return 0; + } + case (int)LuaAtoms::seek: + { + float timeInSeconds = (float)luaL_checknumber(L, 2); + lua_pushboolean(L, sound->seekSeconds(timeInSeconds)); + return 1; + } + case (int)LuaAtoms::seekFrame: + { + uint64_t timeInFrames = (uint64_t)luaL_checknumber(L, 2); + lua_pushboolean(L, sound->seek(timeInFrames)); + return 1; + } + case (int)LuaAtoms::completed: + { + lua_pushboolean(L, sound->completed()); + return 1; + } + case (int)LuaAtoms::time: + { + lua_pushnumber(L, sound->timeInSeconds()); + return 1; + } + case (int)LuaAtoms::timeFrame: + { + lua_pushnumber(L, sound->timeInFrames()); + return 1; + } + default: + break; + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedAudioSound::luaName); + return 0; +} + +static int audio_sound_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedAudioSound = lua_torive(L, 1); + auto sound = scriptedAudioSound->sound; + auto artboard = scriptedAudioSound->artboard(); + switch (atom) + { + case (int)LuaAtoms::volume: + { + float value = (float)luaL_checknumber(L, 3); + if (artboard) + { + value *= artboard->volume(); + } + sound->volume(value); + return 0; + } + default: + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedAudioSound::luaName); + + return 0; +} + +static int audio_sound_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedAudioSound = lua_torive(L, 1); + auto sound = scriptedAudioSound->sound; + switch (atom) + { + case (int)LuaAtoms::volume: + lua_pushnumber(L, (lua_Number)sound->volume()); + return 1; + + default: + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + key, + ScriptedAudioSound::luaName); + return 0; +} + +static int audio_play(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + if (engine == nullptr) + { + lua_pushnil(L); + return 1; + } + auto* scriptedAudioSource = lua_torive(L, 1); + if (scriptedAudioSource == nullptr) + { + lua_pushnil(L); + return 1; + } + return scriptedAudioSource->play(L, engine.get()); +#else + lua_pushnil(L); + return 1; +#endif +} + +static int audio_play_at_time(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + if (engine == nullptr) + { + lua_pushnil(L); + return 1; + } + auto* scriptedAudioSource = lua_torive(L, 1); + if (scriptedAudioSource == nullptr) + { + lua_pushnil(L); + return 1; + } + auto startTime = lua_tonumber(L, 2); + + return scriptedAudioSource->play(L, engine.get(), startTime, false); +#else + lua_pushnil(L); + return 1; +#endif +} + +static int audio_play_in_time(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + if (engine == nullptr) + { + lua_pushnil(L); + return 1; + } + auto* scriptedAudioSource = lua_torive(L, 1); + if (scriptedAudioSource == nullptr) + { + lua_pushnil(L); + return 1; + } + auto startTime = lua_tonumber(L, 2); + + return scriptedAudioSource->play(L, engine.get(), startTime, true); +#else + lua_pushnil(L); + return 1; +#endif +} + +static int audio_play_at_frame(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + if (engine == nullptr) + { + lua_pushnil(L); + return 1; + } + auto* scriptedAudioSource = lua_torive(L, 1); + if (scriptedAudioSource == nullptr) + { + lua_pushnil(L); + return 1; + } + auto startTime = lua_tonumber(L, 2); + + return scriptedAudioSource->playFrame(L, engine.get(), startTime, false); +#else + lua_pushnil(L); + return 1; +#endif +} + +static int audio_play_in_frame(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + if (engine == nullptr) + { + lua_pushnil(L); + return 1; + } + auto* scriptedAudioSource = lua_torive(L, 1); + if (scriptedAudioSource == nullptr) + { + lua_pushnil(L); + return 1; + } + auto startTime = lua_tonumber(L, 2); + + return scriptedAudioSource->playFrame(L, engine.get(), startTime, true); +#else + lua_pushnil(L); + return 1; +#endif +} + +static int audio_time(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + lua_pushnumber(L, (lua_Number)(engine ? engine->timeInSeconds() : 0)); +#else + lua_pushnumber(L, 0); +#endif + return 1; +} + +static int audio_time_frame(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + lua_pushinteger(L, (engine ? (int)engine->timeInFrames() : 0)); +#else + lua_pushinteger(L, 0); +#endif + return 1; +} + +static int audio_sample_rate(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + auto engine = AudioEngine::RuntimeEngine(true); + lua_pushinteger(L, (engine ? (int)engine->sampleRate() : 0)); +#else + lua_pushinteger(L, 0); +#endif + return 1; +} + +static const luaL_Reg audioStaticMethods[] = { + {"time", audio_time}, + {"timeFrame", audio_time_frame}, + {"sampleRate", audio_sample_rate}, + {"play", audio_play}, + {"playAtTime", audio_play_at_time}, + {"playInTime", audio_play_in_time}, + {"playAtFrame", audio_play_at_frame}, + {"playInFrame", audio_play_in_frame}, + {nullptr, nullptr}}; +#endif + +int luaopen_rive_audio(lua_State* L) +{ +#ifdef WITH_RIVE_AUDIO + { + lua_register_rive(L); + + lua_pushcfunction(L, audio_source_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + { + lua_register_rive(L); + + lua_pushcfunction(L, audio_sound_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_pushcfunction(L, audio_sound_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, audio_sound_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + luaL_register(L, ScriptedAudio::luaName, audioStaticMethods); +#endif + + return 0; +} + +#endif diff --git a/thirdparty/rive/source/lua/lua_buffer_ext.cpp b/thirdparty/rive/source/lua/lua_buffer_ext.cpp new file mode 100644 index 000000000..962f8733b --- /dev/null +++ b/thirdparty/rive/source/lua/lua_buffer_ext.cpp @@ -0,0 +1,538 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lualib.h" + +#include +#include + +#if defined(__aarch64__) || defined(__ARM_NEON__) || defined(__ARM_NEON) +#include +#if defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) +#define RIVE_BUF_NEON_F16 1 +#endif +#endif + +#if defined(__F16C__) +#include +#define RIVE_BUF_F16C 1 +#elif defined(__SSE2__) +#include +#endif + +#define isoutofbounds(offset, len, accessize) \ + (uint64_t(unsigned(offset)) + (accessize) > uint64_t(len)) + +// -------------------------------------------------------------------------- +// Half-float (IEEE 754 half-precision) — scalar fallback +// -------------------------------------------------------------------------- + +static float halfToFloat(uint16_t h) +{ + uint32_t sign = (uint32_t)(h >> 15) << 31; + uint32_t exp = (h >> 10) & 0x1F; + uint32_t mant = h & 0x3FF; + + if (exp == 0) + { + if (mant == 0) + { + uint32_t bits = sign; + float f; + memcpy(&f, &bits, 4); + return f; + } + exp = 1; + while ((mant & 0x400) == 0) + { + mant <<= 1; + exp--; + } + mant &= 0x3FF; + uint32_t bits = sign | ((exp + 127 - 15) << 23) | (mant << 13); + float f; + memcpy(&f, &bits, 4); + return f; + } + if (exp == 31) + { + uint32_t bits = sign | 0x7F800000 | (mant << 13); + float f; + memcpy(&f, &bits, 4); + return f; + } + uint32_t bits = sign | ((exp + 127 - 15) << 23) | (mant << 13); + float f; + memcpy(&f, &bits, 4); + return f; +} + +static uint16_t floatToHalf(float value) +{ + uint32_t bits; + memcpy(&bits, &value, 4); + + uint32_t sign = (bits >> 16) & 0x8000; + int32_t exp = ((bits >> 23) & 0xFF) - 127 + 15; + uint32_t mant = bits & 0x7FFFFF; + + if (exp <= 0) + { + if (exp < -10) + return (uint16_t)sign; + mant |= 0x800000; + uint32_t shift = (uint32_t)(1 - exp); + uint32_t round = mant & ((1u << (shift + 13)) - 1); + mant >>= (shift + 13); + if (round > (1u << (shift + 12)) || + (round == (1u << (shift + 12)) && (mant & 1))) + mant++; + return (uint16_t)(sign | mant); + } + if (exp == 0xFF - 127 + 15) + { + if (mant == 0) + return (uint16_t)(sign | 0x7C00); + return (uint16_t)(sign | 0x7C00 | (mant >> 13)); + } + uint32_t round = mant & 0x1FFF; + mant >>= 13; + if (round > 0x1000 || (round == 0x1000 && (mant & 1))) + { + mant++; + if (mant >= 0x400) + { + mant = 0; + exp++; + } + } + if (exp >= 31) + return (uint16_t)(sign | 0x7C00); + return (uint16_t)(sign | ((uint32_t)exp << 10) | mant); +} + +// -------------------------------------------------------------------------- +// SIMD bulk f32↔f16 conversion +// -------------------------------------------------------------------------- + +static void convertF32ToF16Bulk(const float* src, uint16_t* dst, int count) +{ + int i = 0; +#if RIVE_BUF_NEON_F16 + for (; i + 3 < count; i += 4) + { + float32x4_t v = vld1q_f32(src + i); + float16x4_t h = vcvt_f16_f32(v); + vst1_u16(dst + i, vreinterpret_u16_f16(h)); + } +#elif RIVE_BUF_F16C + for (; i + 3 < count; i += 4) + { + __m128 v = _mm_loadu_ps(src + i); + __m128i h = _mm_cvtps_ph(v, _MM_FROUND_TO_NEAREST_INT); + _mm_storel_epi64((__m128i*)(dst + i), h); + } +#endif + for (; i < count; i++) + dst[i] = floatToHalf(src[i]); +} + +static void convertF16ToF32Bulk(const uint16_t* src, float* dst, int count) +{ + int i = 0; +#if RIVE_BUF_NEON_F16 + for (; i + 3 < count; i += 4) + { + uint16x4_t h = vld1_u16(src + i); + float32x4_t v = vcvt_f32_f16(vreinterpret_f16_u16(h)); + vst1q_f32(dst + i, v); + } +#elif RIVE_BUF_F16C + for (; i + 3 < count; i += 4) + { + __m128i h = _mm_loadl_epi64((const __m128i*)(src + i)); + __m128 v = _mm_cvtph_ps(h); + _mm_storeu_ps(dst + i, v); + } +#endif + for (; i < count; i++) + dst[i] = halfToFloat(src[i]); +} + +// -------------------------------------------------------------------------- +// buffer.readf16 / buffer.writef16 +// -------------------------------------------------------------------------- + +static int buffer_readf16(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + + if (isoutofbounds(offset, len, 2)) + luaL_error(L, "buffer access out of bounds"); + + uint16_t half; + memcpy(&half, (char*)buf + offset, 2); + lua_pushnumber(L, (double)halfToFloat(half)); + return 1; +} + +static int buffer_writef16(lua_State* L) +{ + size_t len = 0; + void* buf = luaL_checkbuffer(L, 1, &len); + int offset = luaL_checkinteger(L, 2); + double value = luaL_checknumber(L, 3); + + if (isoutofbounds(offset, len, 2)) + luaL_error(L, "buffer access out of bounds"); + + uint16_t half = floatToHalf((float)value); + memcpy((char*)buf + offset, &half, 2); + return 0; +} + +// -------------------------------------------------------------------------- +// buffer.stridedcopy +// -------------------------------------------------------------------------- + +static int buffer_stridedcopy(lua_State* L) +{ + size_t dstLen = 0, srcLen = 0; + void* dst = luaL_checkbuffer(L, 1, &dstLen); + int dstOffset = luaL_checkinteger(L, 2); + int dstStride = luaL_checkinteger(L, 3); + void* src = luaL_checkbuffer(L, 4, &srcLen); + int srcOffset = luaL_checkinteger(L, 5); + int srcStride = luaL_checkinteger(L, 6); + int elementSize = luaL_checkinteger(L, 7); + int count = luaL_checkinteger(L, 8); + + if (elementSize < 0) + luaL_error(L, "elementSize must be non-negative"); + if (count < 0) + luaL_error(L, "count must be non-negative"); + if (count == 0) + return 0; + if (srcStride < elementSize || dstStride < elementSize) + luaL_error(L, "stride must be >= elementSize"); + + int64_t srcEnd = + (int64_t)srcOffset + (int64_t)(count - 1) * srcStride + elementSize; + if (srcOffset < 0 || srcEnd > (int64_t)srcLen) + luaL_error(L, "buffer access out of bounds"); + + int64_t dstEnd = + (int64_t)dstOffset + (int64_t)(count - 1) * dstStride + elementSize; + if (dstOffset < 0 || dstEnd > (int64_t)dstLen) + luaL_error(L, "buffer access out of bounds"); + + char* d = (char*)dst + dstOffset; + const char* s = (const char*)src + srcOffset; + + for (int i = 0; i < count; i++) + { + memcpy(d + (int64_t)i * dstStride, + s + (int64_t)i * srcStride, + (size_t)elementSize); + } + + return 0; +} + +// -------------------------------------------------------------------------- +// buffer.convert — bulk format conversion with optional stride + SIMD +// -------------------------------------------------------------------------- + +enum BufFormat +{ + BufFormat_f16, + BufFormat_f32, + BufFormat_u8, + BufFormat_u8norm, + BufFormat_i8norm, + BufFormat_u16, + BufFormat_u16norm, + BufFormat_i16norm, + BufFormat_u32, +}; + +static BufFormat parseFormat(lua_State* L, int arg) +{ + const char* s = luaL_checkstring(L, arg); + if (strcmp(s, "f16") == 0) + return BufFormat_f16; + if (strcmp(s, "f32") == 0) + return BufFormat_f32; + if (strcmp(s, "u8") == 0) + return BufFormat_u8; + if (strcmp(s, "u8norm") == 0) + return BufFormat_u8norm; + if (strcmp(s, "i8norm") == 0) + return BufFormat_i8norm; + if (strcmp(s, "u16") == 0) + return BufFormat_u16; + if (strcmp(s, "u16norm") == 0) + return BufFormat_u16norm; + if (strcmp(s, "i16norm") == 0) + return BufFormat_i16norm; + if (strcmp(s, "u32") == 0) + return BufFormat_u32; + luaL_error(L, "unknown buffer format '%s'", s); + return BufFormat_f32; +} + +static int formatByteSize(BufFormat fmt) +{ + switch (fmt) + { + case BufFormat_f16: + case BufFormat_u16: + case BufFormat_u16norm: + case BufFormat_i16norm: + return 2; + case BufFormat_f32: + case BufFormat_u32: + return 4; + case BufFormat_u8: + case BufFormat_u8norm: + case BufFormat_i8norm: + return 1; + } + return 0; +} + +static double readElement(const char* ptr, BufFormat fmt) +{ + switch (fmt) + { + case BufFormat_f16: + { + uint16_t h; + memcpy(&h, ptr, 2); + return (double)halfToFloat(h); + } + case BufFormat_f32: + { + float f; + memcpy(&f, ptr, 4); + return (double)f; + } + case BufFormat_u8: + return (double)(uint8_t)*ptr; + case BufFormat_u8norm: + return (double)(uint8_t)*ptr / 255.0; + case BufFormat_i8norm: + { + int8_t v; + memcpy(&v, ptr, 1); + double d = (double)v / 127.0; + return d < -1.0 ? -1.0 : d; + } + case BufFormat_u16: + { + uint16_t v; + memcpy(&v, ptr, 2); + return (double)v; + } + case BufFormat_u16norm: + { + uint16_t v; + memcpy(&v, ptr, 2); + return (double)v / 65535.0; + } + case BufFormat_i16norm: + { + int16_t v; + memcpy(&v, ptr, 2); + double d = (double)v / 32767.0; + return d < -1.0 ? -1.0 : d; + } + case BufFormat_u32: + { + uint32_t v; + memcpy(&v, ptr, 4); + return (double)v; + } + } + return 0.0; +} + +static void writeElement(char* ptr, BufFormat fmt, double value) +{ + switch (fmt) + { + case BufFormat_f16: + { + uint16_t h = floatToHalf((float)value); + memcpy(ptr, &h, 2); + break; + } + case BufFormat_f32: + { + float f = (float)value; + memcpy(ptr, &f, 4); + break; + } + case BufFormat_u8: + { + *ptr = (char)(uint8_t)(unsigned int)value; + break; + } + case BufFormat_u8norm: + { + double c = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value); + *ptr = (char)(uint8_t)(c * 255.0 + 0.5); + break; + } + case BufFormat_i8norm: + { + double c = value < -1.0 ? -1.0 : (value > 1.0 ? 1.0 : value); + int8_t v = (int8_t)(c * 127.0 + (c >= 0 ? 0.5 : -0.5)); + memcpy(ptr, &v, 1); + break; + } + case BufFormat_u16: + { + uint16_t v = (uint16_t)(unsigned int)value; + memcpy(ptr, &v, 2); + break; + } + case BufFormat_u16norm: + { + double c = value < 0.0 ? 0.0 : (value > 1.0 ? 1.0 : value); + uint16_t v = (uint16_t)(c * 65535.0 + 0.5); + memcpy(ptr, &v, 2); + break; + } + case BufFormat_i16norm: + { + double c = value < -1.0 ? -1.0 : (value > 1.0 ? 1.0 : value); + int16_t v = (int16_t)(c * 32767.0 + (c >= 0 ? 0.5 : -0.5)); + memcpy(ptr, &v, 2); + break; + } + case BufFormat_u32: + { + uint32_t v = (uint32_t)value; + memcpy(ptr, &v, 4); + break; + } + } +} + +// buffer.convert(dst, dstOff, dstFmt, src, srcOff, srcFmt, count, +// components?, dstStride?, srcStride?) +static int buffer_convert(lua_State* L) +{ + size_t dstLen = 0, srcLen = 0; + void* dst = luaL_checkbuffer(L, 1, &dstLen); + int dstOffset = luaL_checkinteger(L, 2); + BufFormat dstFmt = parseFormat(L, 3); + void* src = luaL_checkbuffer(L, 4, &srcLen); + int srcOffset = luaL_checkinteger(L, 5); + BufFormat srcFmt = parseFormat(L, 6); + int count = luaL_checkinteger(L, 7); + int components = luaL_optinteger(L, 8, 1); + + int srcElemSize = formatByteSize(srcFmt); + int dstElemSize = formatByteSize(dstFmt); + + int dstStride = luaL_optinteger(L, 9, components * dstElemSize); + int srcStride = luaL_optinteger(L, 10, components * srcElemSize); + + if (count < 0) + luaL_error(L, "count must be non-negative"); + if (components < 1) + luaL_error(L, "components must be at least 1"); + if (count == 0) + return 0; + if (srcStride < 0 || dstStride < 0) + luaL_error(L, "stride must be non-negative"); + + int64_t srcSpan = (int64_t)components * srcElemSize; + int64_t dstSpan = (int64_t)components * dstElemSize; + + if (srcStride > 0 && srcStride < srcSpan) + luaL_error(L, "srcStride must be >= components * element size"); + if (dstStride > 0 && dstStride < dstSpan) + luaL_error(L, "dstStride must be >= components * element size"); + + // Bounds check: last element at offset + (count-1)*stride + span + { + int64_t srcEnd = + (int64_t)srcOffset + (int64_t)(count - 1) * srcStride + srcSpan; + if (srcOffset < 0 || srcEnd > (int64_t)srcLen) + luaL_error(L, "buffer access out of bounds"); + + int64_t dstEnd = + (int64_t)dstOffset + (int64_t)(count - 1) * dstStride + dstSpan; + if (dstOffset < 0 || dstEnd > (int64_t)dstLen) + luaL_error(L, "buffer access out of bounds"); + } + + const char* s = (const char*)src + srcOffset; + char* d = (char*)dst + dstOffset; + + bool packed = (srcStride == (int)srcSpan && dstStride == (int)dstSpan); + int totalScalars = count * components; + + // Fast path: same format, packed → memcpy + if (srcFmt == dstFmt && packed) + { + memcpy(d, s, (size_t)totalScalars * srcElemSize); + return 0; + } + + // SIMD fast path: packed f32 → f16 + if (srcFmt == BufFormat_f32 && dstFmt == BufFormat_f16 && packed) + { + convertF32ToF16Bulk((const float*)s, (uint16_t*)d, totalScalars); + return 0; + } + + // SIMD fast path: packed f16 → f32 + if (srcFmt == BufFormat_f16 && dstFmt == BufFormat_f32 && packed) + { + convertF16ToF32Bulk((const uint16_t*)s, (float*)d, totalScalars); + return 0; + } + + // General path: per-element with stride support + for (int i = 0; i < count; i++) + { + const char* sp = s + (int64_t)i * srcStride; + char* dp = d + (int64_t)i * dstStride; + for (int c = 0; c < components; c++) + { + double val = readElement(sp + c * srcElemSize, srcFmt); + writeElement(dp + c * dstElemSize, dstFmt, val); + } + } + return 0; +} + +// -------------------------------------------------------------------------- +// Registration +// -------------------------------------------------------------------------- + +extern "C" int luaopen_rive_buffer_ext(lua_State* L) +{ + lua_getglobal(L, "buffer"); + + lua_pushcfunction(L, buffer_readf16, "buffer.readf16"); + lua_setfield(L, -2, "readf16"); + + lua_pushcfunction(L, buffer_writef16, "buffer.writef16"); + lua_setfield(L, -2, "writef16"); + + lua_pushcfunction(L, buffer_stridedcopy, "buffer.stridedcopy"); + lua_setfield(L, -2, "stridedcopy"); + + lua_pushcfunction(L, buffer_convert, "buffer.convert"); + lua_setfield(L, -2, "convert"); + + lua_pop(L, 1); + return 0; +} + +#endif // WITH_RIVE_SCRIPTING diff --git a/thirdparty/rive/source/lua/lua_data_context.cpp b/thirdparty/rive/source/lua/lua_data_context.cpp new file mode 100644 index 000000000..a5298dcb6 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_data_context.cpp @@ -0,0 +1,92 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" + +#include +#include + +using namespace rive; + +ScriptedDataContext::ScriptedDataContext(lua_State* L, + rcp dataContext) : + m_state(L), m_dataContext(dataContext) +{} + +int ScriptedDataContext::pushParent() +{ + if (m_dataContext->parent()) + { + + lua_newrive(m_state, + m_state, + m_dataContext->parent()); + } + else + { + lua_pushnil(m_state); + } + return 1; +} + +int ScriptedDataContext::pushViewModel() +{ + auto vmi = m_dataContext->viewModelInstance(); + if (vmi) + { + lua_newrive(m_state, + m_state, + ref_rcp(vmi->viewModel()), + vmi); + } + else + { + lua_pushnil(m_state); + } + return 1; +} + +static int data_value_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto dataContext = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::parent: + { + assert(dataContext->state() == L); + return dataContext->pushParent(); + } + case (int)LuaAtoms::viewModel: + { + assert(dataContext->state() == L); + return dataContext->pushViewModel(); + } + default: + break; + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedDataContext::luaName); + return 0; +} + +int luaopen_rive_data_context(lua_State* L) +{ + { + lua_register_rive(L); + + lua_pushcfunction(L, data_value_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + return 1; +} +#endif diff --git a/thirdparty/rive/source/lua/lua_data_value.cpp b/thirdparty/rive/source/lua/lua_data_value.cpp new file mode 100644 index 000000000..94955654d --- /dev/null +++ b/thirdparty/rive/source/lua/lua_data_value.cpp @@ -0,0 +1,412 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" + +#include +#include + +using namespace rive; + +ScriptedDataValue::~ScriptedDataValue() +{ + if (m_dataValue) + { + delete m_dataValue; + } +} + +static int property_namecall_atom(lua_State* L, + ScriptedDataValue* scriptedDataValue, + uint8_t tag, + int atom, + bool& error) +{ + switch (atom) + { + case (int)LuaAtoms::value: + { + assert(scriptedDataValue->state() == L); + switch (tag) + { + case ScriptedDataValueNumber::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushnumber(L, dataValue->value()); + return 1; + } + case ScriptedDataValueString::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushstring(L, dataValue->value().c_str()); + return 1; + } + case ScriptedDataValueBoolean::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushboolean(L, dataValue->value() ? 1 : 0); + return 1; + } + case ScriptedDataValueColor::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushinteger(L, dataValue->value()); + return 1; + } + } + } + case (int)LuaAtoms::red: + { + assert(scriptedDataValue->state() == L); + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushinteger(L, dataValue->red()); + return 1; + } + } + } + case (int)LuaAtoms::green: + { + assert(scriptedDataValue->state() == L); + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushinteger(L, dataValue->green()); + return 1; + } + } + } + case (int)LuaAtoms::blue: + { + assert(scriptedDataValue->state() == L); + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushinteger(L, dataValue->blue()); + return 1; + } + } + } + case (int)LuaAtoms::alpha: + { + assert(scriptedDataValue->state() == L); + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto dataValue = + scriptedDataValue->dataValue()->as(); + lua_pushinteger(L, dataValue->alpha()); + return 1; + } + } + } + } + error = true; + return 0; +} + +static int data_value_index(lua_State* L) +{ + int atom; + lua_tostringatom(L, 2, &atom); + + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + + auto tag = lua_userdatatag(L, 1); + auto scriptedDataValue = (ScriptedDataValue*)lua_touserdata(L, 1); + + bool error = false; + int stackChange = + property_namecall_atom(L, scriptedDataValue, tag, atom, error); + if (!error) + { + return stackChange; + } + + luaL_error(L, "'%s' is not a valid index of DataValue", name); + return 0; +} + +static int data_value_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto tag = lua_userdatatag(L, 1); + auto scriptedDataValue = (ScriptedDataValue*)lua_touserdata(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + { + switch (tag) + { + case ScriptedDataValueNumber::luaTag: + { + auto val = float(luaL_checknumber(L, 3)); + scriptedDataValue->dataValue() + ->as() + ->value(val); + return 1; + } + case ScriptedDataValueString::luaTag: + { + auto val = luaL_checkstring(L, 3); + scriptedDataValue->dataValue() + ->as() + ->value(val); + return 1; + } + case ScriptedDataValueBoolean::luaTag: + { + auto val = luaL_checkboolean(L, 3); + scriptedDataValue->dataValue() + ->as() + ->value(val != 0); + return 1; + } + case ScriptedDataValueColor::luaTag: + { + auto val = luaL_checkinteger(L, 3); + scriptedDataValue->dataValue()->as()->value( + val); + return 1; + } + } + } + case (int)LuaAtoms::red: + { + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto val = luaL_checkinteger(L, 3); + scriptedDataValue->dataValue()->as()->red( + val); + return 1; + } + default: + return 1; + } + } + case (int)LuaAtoms::green: + { + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto val = luaL_checkinteger(L, 3); + scriptedDataValue->dataValue()->as()->green( + val); + return 1; + } + default: + return 1; + } + } + case (int)LuaAtoms::blue: + { + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto val = luaL_checkinteger(L, 3); + scriptedDataValue->dataValue()->as()->blue( + val); + return 1; + } + default: + return 1; + } + } + case (int)LuaAtoms::alpha: + { + switch (tag) + { + case ScriptedDataValueColor::luaTag: + { + auto val = luaL_checkinteger(L, 3); + scriptedDataValue->dataValue()->as()->alpha( + val); + return 1; + } + default: + return 1; + } + } + default: + return 0; + } + + return 0; +} + +static int dataValue_number(lua_State* L) +{ + lua_newrive(L, L, 0); + + return 1; +} + +static int dataValue_string(lua_State* L) +{ + lua_newrive(L, L, ""); + + return 1; +} + +static int dataValue_boolean(lua_State* L) +{ + lua_newrive(L, L, false); + + return 1; +} + +static int dataValue_color(lua_State* L) +{ + lua_newrive(L, L, 0); + + return 1; +} + +static int data_value_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto dataValue = (ScriptedDataValue*)lua_touserdata(L, 1); + switch (atom) + { + case (int)LuaAtoms::isNumber: + { + assert(dataValue->state() == L); + lua_pushboolean(L, dataValue->isNumber() ? 1 : 0); + return 1; + } + case (int)LuaAtoms::isString: + { + assert(dataValue->state() == L); + lua_pushboolean(L, dataValue->isString() ? 1 : 0); + return 1; + } + case (int)LuaAtoms::isBoolean: + { + assert(dataValue->state() == L); + lua_pushboolean(L, dataValue->isBoolean() ? 1 : 0); + return 1; + } + case (int)LuaAtoms::isColor: + { + assert(dataValue->state() == L); + lua_pushboolean(L, dataValue->isColor() ? 1 : 0); + return 1; + } + default: + break; + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedPropertyViewModel::luaName); + return 0; +} + +static const luaL_Reg dataValueStaticMethods[] = { + {"number", dataValue_number}, + {"string", dataValue_string}, + {"boolean", dataValue_boolean}, + {"color", dataValue_color}, + {nullptr, nullptr}}; + +int luaopen_rive_data_values(lua_State* L) +{ + { + + luaL_register(L, ScriptedDataValue::luaName, dataValueStaticMethods); + } + { + lua_register_rive(L); + + lua_pushcfunction(L, data_value_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, data_value_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, data_value_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + { + lua_register_rive(L); + + lua_pushcfunction(L, data_value_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, data_value_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, data_value_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + { + lua_register_rive(L); + + lua_pushcfunction(L, data_value_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, data_value_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, data_value_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + { + lua_register_rive(L); + + lua_pushcfunction(L, data_value_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, data_value_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, data_value_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + return 1; +} +#endif diff --git a/thirdparty/rive/source/lua/lua_image_decode.cpp b/thirdparty/rive/source/lua/lua_image_decode.cpp new file mode 100644 index 000000000..c7bf19496 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_image_decode.cpp @@ -0,0 +1,467 @@ +#ifdef WITH_RIVE_SCRIPTING + +#include "rive/lua/rive_lua_libs.hpp" +#include "lua.h" +#include "lualib.h" + +#include +#include +#include +#include + +// ============================================================================ +// Native path — uses Bitmap::decode via WorkPool +// ============================================================================ + +#ifndef __EMSCRIPTEN__ + +#include "rive/async/work_pool.hpp" +#ifdef RIVE_DECODERS +#include "rive/decoders/bitmap_decoder.hpp" +#endif + +namespace rive +{ + +#ifdef RIVE_DECODERS +class ImageDecodeTask : public WorkTask +{ +public: + std::vector m_encodedData; + uint32_t m_width = 0; + uint32_t m_height = 0; + lua_State* m_state = nullptr; + int m_promiseRef = LUA_NOREF; + std::unique_ptr m_bitmap; + + bool execute() override + { + m_bitmap = Bitmap::decode(m_encodedData.data(), m_encodedData.size()); + if (!m_bitmap) + { + m_errorMessage = "failed to decode image data"; + return false; + } + if (m_bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul) + { + m_bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul); + } + m_width = m_bitmap->width(); + m_height = m_bitmap->height(); + return true; + } + + void onComplete() override + { + if (!m_state || m_promiseRef == LUA_NOREF) + return; + lua_State* L = m_state; + lua_rawgeti(L, LUA_REGISTRYINDEX, m_promiseRef); + auto* promise = lua_torive(L, -1, true); + lua_pop(L, 1); + if (promise && promise->isPending()) + { + if (m_bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul) + { + lua_pushstring(L, + "internal error: decoded image is not " + "RGBAPremul"); + promise->reject(L, lua_gettop(L)); + lua_pop(L, 1); + m_bitmap.reset(); + lua_unref(L, m_promiseRef); + m_promiseRef = LUA_NOREF; + return; + } + lua_newtable(L); + size_t pixelSize = (size_t)m_width * m_height * 4; + void* buf = lua_newbuffer(L, pixelSize); + memcpy(buf, m_bitmap->bytes(), pixelSize); + lua_setfield(L, -2, "data"); + lua_pushnumber(L, m_width); + lua_setfield(L, -2, "width"); + lua_pushnumber(L, m_height); + lua_setfield(L, -2, "height"); + promise->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + } + // Release decoded bitmap immediately — the pixels have been + // copied to the Lua buffer. The TaskRef userdata in the onCancel + // closure may keep this task alive until GC, so eagerly free the + // large allocation. + m_bitmap.reset(); + m_encodedData.clear(); + m_encodedData.shrink_to_fit(); + lua_unref(L, m_promiseRef); + m_promiseRef = LUA_NOREF; + } + + void onError(const std::string& error) override + { + if (!m_state || m_promiseRef == LUA_NOREF) + return; + lua_State* L = m_state; + lua_rawgeti(L, LUA_REGISTRYINDEX, m_promiseRef); + auto* promise = lua_torive(L, -1, true); + lua_pop(L, 1); + if (promise && promise->isPending()) + { + lua_pushstring(L, error.c_str()); + promise->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + lua_unref(L, m_promiseRef); + m_promiseRef = LUA_NOREF; + } + + void onCancel() override + { + m_promiseRef = LUA_NOREF; + m_state = nullptr; + } +}; +#endif // RIVE_DECODERS + +} // namespace rive + +int context_decodeImage_impl(lua_State* L) +{ + using namespace rive; + + size_t len = 0; + const void* data = nullptr; + if (lua_isbuffer(L, 2)) + data = lua_tobuffer(L, 2, &len); + else + { + luaL_typeerror(L, 2, "buffer"); + return 0; + } + if (!data || len == 0) + { + luaL_error(L, "decodeImage: empty buffer"); + return 0; + } + +#ifndef RIVE_DECODERS + luaL_error(L, "decodeImage: not supported on this platform"); + return 0; +#else + auto* ctx = static_cast(lua_getthreaddata(L)); + WorkPool* wp = ctx->workPool(); + + lua_State* mainThread = lua_mainthread(L); + lua_newrive(L, mainThread); + int promiseIdx = lua_gettop(L); + lua_pushvalue(L, promiseIdx); + int promiseRef = lua_ref(L, -1); + lua_pop(L, 1); + + auto task = make_rcp(); + task->m_encodedData.assign(static_cast(data), + static_cast(data) + len); + task->m_state = mainThread; + task->m_promiseRef = promiseRef; + task->setOwnerId(ctx->ownerId()); + + // Wrap the rcp in a Lua userdata with a destructor so the + // task stays alive as long as the onCancel closure exists. This + // prevents a use-after-free if the WorkPool is destroyed (dropping + // its rcp) before the promise is cancelled. + struct TaskRef + { + rcp ref; + }; + auto* taskUD = static_cast( + lua_newuserdatadtor(L, sizeof(TaskRef), [](void* p) { + static_cast(p)->~TaskRef(); + })); + new (taskUD) TaskRef{task}; // copy rcp before submit moves it + int taskUDIdx = lua_gettop(L); + + wp->submit(std::move(task)); + + // Register onCancel hook: cancel the WorkPool task so the decode + // thread skips execution (or the result is discarded), and release + // the promise registry reference so the Promise can be collected. + auto* promise = lua_torive(L, promiseIdx); + lua_pushvalue(L, taskUDIdx); + lua_remove(L, taskUDIdx); // remove original, closure upvalue has it + lua_pushinteger(L, promiseRef); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + auto* tr = + static_cast(lua_touserdata(L, lua_upvalueindex(1))); + if (tr && tr->ref) + tr->ref->cancel(); + int pRef = (int)lua_tointeger(L, lua_upvalueindex(2)); + lua_unref(L, pRef); + return 0; + }, + nullptr, + 2, + nullptr); + promise->m_onCancelRef = lua_ref(L, -1); + lua_pop(L, 1); + + lua_pushvalue(L, promiseIdx); + return 1; +#endif // RIVE_DECODERS +} + +// ============================================================================ +// WASM path — uses browser's createImageBitmap, no WorkPool +// ============================================================================ + +#else // __EMSCRIPTEN__ + +#include + +namespace +{ + +// Track in-flight decodes so the JS callback can find the Lua state + promise. +struct PendingDecode +{ + lua_State* state; + int promiseRef; +}; +std::unordered_map s_pendingDecodes; +uint32_t s_nextDecodeId = 1; + +// Generate a unique decode ID, skipping any that are still in-flight. +uint32_t nextDecodeId() +{ + uint32_t id = s_nextDecodeId++; + // On wraparound, skip IDs that collide with in-flight decodes. + while (id == 0 || s_pendingDecodes.count(id)) + id = s_nextDecodeId++; + return id; +} + +} // namespace + +// Start a browser-native image decode. createImageBitmap is async; the JS +// callback fires between frames and calls back into C++ to resolve the promise. +EM_JS(void, + wasm_start_image_decode, + (uint32_t requestId, const uint8_t* data, int dataLen), + { + // Copy from WASM heap (SharedArrayBuffer can't be used for Blob). + var sourceView = Module["HEAP8"].subarray(data, data + dataLen); + var buffer = new Uint8Array(dataLen); + buffer.set(sourceView); + + var blob = new Blob([buffer]); + createImageBitmap(blob) + .then(function(bmp) { + // Draw to OffscreenCanvas to extract raw RGBA pixels. + var canvas = new OffscreenCanvas(bmp.width, bmp.height); + var ctx2d = canvas.getContext("2d"); + ctx2d.drawImage(bmp, 0, 0); + var imageData = + ctx2d.getImageData(0, 0, bmp.width, bmp.height); + + // Allocate WASM memory and copy pixels. + var numBytes = imageData.data.length; + var ptr = Module._malloc(numBytes); + Module.HEAPU8.set(imageData.data, ptr); + + Module._wasm_image_decode_complete(requestId, + bmp.width, + bmp.height, + ptr, + numBytes); + }) + .catch(function(err) { + var msg = err.message || "decode failed"; + var msgLen = Module.lengthBytesUTF8(msg) + 1; + var msgPtr = Module._malloc(msgLen); + Module.stringToUTF8(msg, msgPtr, msgLen); + Module._wasm_image_decode_error(requestId, msgPtr); + Module._free(msgPtr); + }); + }); + +// C callbacks invoked by JS when createImageBitmap resolves/rejects. +extern "C" +{ + using namespace rive; + + EMSCRIPTEN_KEEPALIVE + void wasm_image_decode_complete(uint32_t requestId, + int width, + int height, + uint8_t* pixels, + int numBytes) + { + auto it = s_pendingDecodes.find(requestId); + if (it == s_pendingDecodes.end()) + { + free(pixels); + return; + } + + auto [state, promiseRef] = it->second; + s_pendingDecodes.erase(it); + + if (!state) + { + free(pixels); + return; + } + + lua_State* L = state; + lua_rawgeti(L, LUA_REGISTRYINDEX, promiseRef); + auto* promise = lua_torive(L, -1, true); + lua_pop(L, 1); + + if (promise && promise->isPending()) + { + // getImageData() returns straight RGBA; premultiply in-place so + // the scripting API always delivers premultiplied RGBA8. + for (int i = 0; i < numBytes; i += 4) + { + uint8_t a = pixels[i + 3]; + if (a < 255) + { + pixels[i + 0] = (uint16_t(pixels[i + 0]) * a + 127) / 255; + pixels[i + 1] = (uint16_t(pixels[i + 1]) * a + 127) / 255; + pixels[i + 2] = (uint16_t(pixels[i + 2]) * a + 127) / 255; + } + } + + lua_newtable(L); + + void* buf = lua_newbuffer(L, numBytes); + memcpy(buf, pixels, numBytes); + lua_setfield(L, -2, "data"); + + lua_pushnumber(L, width); + lua_setfield(L, -2, "width"); + + lua_pushnumber(L, height); + lua_setfield(L, -2, "height"); + + promise->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + } + + lua_unref(L, promiseRef); + free(pixels); + } + + EMSCRIPTEN_KEEPALIVE + void wasm_image_decode_error(uint32_t requestId, const char* msg) + { + auto it = s_pendingDecodes.find(requestId); + if (it == s_pendingDecodes.end()) + return; + + auto [state, promiseRef] = it->second; + s_pendingDecodes.erase(it); + + if (state) + { + lua_State* L = state; + lua_rawgeti(L, LUA_REGISTRYINDEX, promiseRef); + auto* promise = lua_torive(L, -1, true); + lua_pop(L, 1); + + if (promise && promise->isPending()) + { + lua_pushstring(L, msg); + promise->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + lua_unref(L, promiseRef); + } + } + +} // extern "C" + +// Cancel all pending decodes for a Lua state (called on shutdown). +// Must be called while mainThread is still valid so we can unref promises. +namespace rive +{ +void wasm_cancelPendingDecodes(lua_State* mainThread) +{ + for (auto it = s_pendingDecodes.begin(); it != s_pendingDecodes.end();) + { + if (it->second.state == mainThread) + { + lua_unref(mainThread, it->second.promiseRef); + it = s_pendingDecodes.erase(it); + } + else + { + ++it; + } + } +} +} // namespace rive + +int context_decodeImage_impl(lua_State* L) +{ + using namespace rive; + + size_t len = 0; + const void* data = nullptr; + if (lua_isbuffer(L, 2)) + data = lua_tobuffer(L, 2, &len); + else + { + luaL_typeerror(L, 2, "buffer"); + return 0; + } + if (!data || len == 0) + { + luaL_error(L, "decodeImage: empty buffer"); + return 0; + } + + lua_State* mainThread = lua_mainthread(L); + lua_newrive(L, mainThread); + int promiseIdx = lua_gettop(L); + lua_pushvalue(L, promiseIdx); + int promiseRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Register the pending decode so the JS callback can find the promise. + uint32_t id = nextDecodeId(); + s_pendingDecodes[id] = {mainThread, promiseRef}; + + // Start the browser-native decode. This returns immediately. + wasm_start_image_decode(id, + static_cast(data), + static_cast(len)); + + // Register onCancel hook: erase from pending decodes so the JS + // callback becomes a no-op (the browser will still finish decoding, + // but the result is discarded). + auto* promise = lua_torive(L, promiseIdx); + lua_pushinteger(L, id); + lua_pushinteger(L, promiseRef); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + uint32_t decodeId = (uint32_t)lua_tointeger(L, lua_upvalueindex(1)); + int pRef = (int)lua_tointeger(L, lua_upvalueindex(2)); + s_pendingDecodes.erase(decodeId); + lua_unref(L, pRef); + return 0; + }, + nullptr, + 2, + nullptr); + promise->m_onCancelRef = lua_ref(L, -1); + lua_pop(L, 1); + + lua_pushvalue(L, promiseIdx); + return 1; +} + +#endif // __EMSCRIPTEN__ + +#endif // WITH_RIVE_SCRIPTING diff --git a/thirdparty/rive/source/lua/lua_listener_invocation.cpp b/thirdparty/rive/source/lua/lua_listener_invocation.cpp new file mode 100644 index 000000000..52d460ac1 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_listener_invocation.cpp @@ -0,0 +1,380 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "lualib.h" + +namespace rive +{ + +void rive_lua_push_pointer_arg_for_perform(lua_State* L, + const ListenerInvocation& inv) +{ + if (const PointerInvocation* p = inv.asPointer()) + { + lua_newrive(L, + (uint8_t)p->pointerId, + p->position, + p->previousPosition, + static_cast(p->hitEvent), + p->timeStamp); + } + else + { + lua_newrive(L, + (uint8_t)0, + Vec2D(0, 0), + Vec2D(0, 0), + -1, + 0.f); + } +} + +void rive_lua_push_scripted_invocation(lua_State* L, + const ListenerInvocation& inv) +{ + lua_newrive(L, inv); +} + +static int scripted_invocation_namecall(lua_State* L) +{ + auto* self = lua_torive(L, 1); + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str == nullptr) + { + luaL_error(L, "invalid call"); + return 0; + } + + const ListenerInvocation& inv = self->invocation(); + + auto pushBool = [&](bool v) { + lua_pushboolean(L, v ? 1 : 0); + return 1; + }; + + switch (atom) + { + case (int)LuaAtoms::isPointerEvent: + return pushBool(inv.kind() == ListenerInvocationKind::pointer); + case (int)LuaAtoms::isKeyboardEvent: + return pushBool(inv.kind() == ListenerInvocationKind::keyboard); + case (int)LuaAtoms::isTextInput: + return pushBool(inv.kind() == ListenerInvocationKind::textInput); + case (int)LuaAtoms::isFocus: + return pushBool(inv.kind() == ListenerInvocationKind::focus); + case (int)LuaAtoms::isReportedEvent: + return pushBool(inv.kind() == + ListenerInvocationKind::reportedEvent); + case (int)LuaAtoms::isViewModelChange: + return pushBool(inv.kind() == + ListenerInvocationKind::viewModelChange); + case (int)LuaAtoms::isNone: + return pushBool(inv.kind() == ListenerInvocationKind::none); + case (int)LuaAtoms::isGamepad: + return pushBool(inv.kind() == ListenerInvocationKind::gamepad); + + case (int)LuaAtoms::asPointerEvent: + if (const PointerInvocation* p = inv.asPointer()) + { + lua_newrive(L, + (uint8_t)p->pointerId, + p->position, + p->previousPosition, + static_cast(p->hitEvent), + p->timeStamp); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asKeyboardEvent: + if (const KeyboardInvocation* k = inv.asKeyboard()) + { + lua_newrive(L, + k->key, + k->modifiers, + k->isPressed, + k->isRepeat); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asTextInput: + if (const TextInputInvocation* t = inv.asTextInput()) + { + lua_newrive(L, t->text); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asFocus: + if (const FocusInvocation* f = inv.asFocus()) + { + lua_newrive(L, f->isFocus); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asReportedEvent: + if (const ReportedEventInvocation* e = inv.asReportedEvent()) + { + lua_newrive(L, + e->reportedEvent, + e->delaySeconds); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asViewModelChange: + if (inv.asViewModelChange() != nullptr) + { + lua_newrive(L); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asGamepad: + if (const GamepadInvocation* g = inv.asGamepad()) + { + lua_newrive(L, + g->deviceId, + g->buttonMask, + g->axis0); + return 1; + } + lua_pushnil(L); + return 1; + + case (int)LuaAtoms::asNone: + if (inv.asNone() != nullptr) + { + lua_newrive(L); + return 1; + } + lua_pushnil(L); + return 1; + } + + luaL_error(L, + "%s is not a valid method of %s", + luaL_checkstring(L, 1), + ScriptedInvocation::luaName); + return 0; +} + +static int keyboard_invocation_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + auto* k = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::key: + lua_pushinteger(L, static_cast(k->m_key)); + return 1; + case (int)LuaAtoms::shift: + lua_pushboolean(L, + (k->m_modifiers & KeyModifiers::shift) == + KeyModifiers::shift); + return 1; + case (int)LuaAtoms::control: + lua_pushboolean(L, + (k->m_modifiers & KeyModifiers::ctrl) == + KeyModifiers::ctrl); + return 1; + case (int)LuaAtoms::alt: + lua_pushboolean(L, + (k->m_modifiers & KeyModifiers::alt) == + KeyModifiers::alt); + return 1; + case (int)LuaAtoms::meta: + lua_pushboolean(L, + (k->m_modifiers & KeyModifiers::meta) == + KeyModifiers::meta); + return 1; + case (int)LuaAtoms::phase: + { + if (k->m_isPressed) + { + if (k->m_isRepeat) + { + lua_pushstring(L, "repeat"); + } + else + { + lua_pushstring(L, "down"); + } + } + else + { + lua_pushstring(L, "up"); + } + } + + return 1; + } + luaL_error(L, + "%s is not a valid field of %s", + luaL_checkstring(L, 1), + ScriptedKeyboardInvocation::luaName); + return 0; +} + +static int text_input_invocation_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + auto* t = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::text: + lua_pushstring(L, t->text().c_str()); + return 1; + } + luaL_error(L, + "%s is not a valid field of %s", + luaL_checkstring(L, 1), + ScriptedTextInputInvocation::luaName); + return 0; +} + +static int focus_invocation_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + auto* f = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::isFocus: + lua_pushboolean(L, f->m_isFocus ? 1 : 0); + return 1; + } + luaL_error(L, + "%s is not a valid field of %s", + luaL_checkstring(L, 1), + ScriptedFocusInvocation::luaName); + return 0; +} + +static int reported_event_invocation_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + auto* e = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::delaySeconds: + lua_pushnumber(L, e->m_delaySeconds); + return 1; + } + luaL_error(L, + "%s is not a valid field of %s", + luaL_checkstring(L, 1), + ScriptedReportedEventInvocation::luaName); + return 0; +} + +static int gamepad_invocation_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + auto* g = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::deviceId: + lua_pushinteger(L, g->m_deviceId); + return 1; + case (int)LuaAtoms::buttonMask: + lua_pushnumber(L, static_cast(g->m_buttonMask)); + return 1; + case (int)LuaAtoms::axis0: + lua_pushnumber(L, g->m_axis0); + return 1; + } + luaL_error(L, + "%s is not a valid field of %s", + luaL_checkstring(L, 1), + ScriptedGamepadInvocation::luaName); + return 0; +} + +void rive_lua_register_listener_invocation_types(lua_State* L) +{ + lua_register_rive(L); + lua_pushcfunction(L, scripted_invocation_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_pushcfunction(L, keyboard_invocation_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_pushcfunction(L, text_input_invocation_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_pushcfunction(L, focus_invocation_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_pushcfunction(L, reported_event_invocation_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_pushcfunction(L, gamepad_invocation_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_register_rive(L); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); +} + +} // namespace rive + +#endif diff --git a/thirdparty/rive/source/lua/lua_promise.cpp b/thirdparty/rive/source/lua/lua_promise.cpp new file mode 100644 index 000000000..feb3c95e1 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_promise.cpp @@ -0,0 +1,1323 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" + +#include "lua.h" +#include "lualib.h" + +#include + +namespace rive +{ + +// --------------------------------------------------------------------------- +// ScriptedPromise – a lightweight Promise/A+ for Luau with cancellation +// --------------------------------------------------------------------------- +// +// States: Pending → Fulfilled | Rejected | Cancelled (one-way, immutable) +// +// Cancellation follows the Roblox model: +// - cancel() propagates DOWN to consumers (chained promises) +// - cancel() propagates UP to parent when ALL consumers are cancelled +// - An onCancel hook fires to clean up in-flight work (e.g. image decode) +// +// Parent/consumer refs form a tree. To break the cycle (parent ↔ consumer), +// all refs are released eagerly on any terminal transition via +// promise_cleanupLinks(). + +// ── helpers ──────────────────────────────────────────────────────────────── + +static void promise_notifyCallbacks(lua_State* L, ScriptedPromise* p); +static void handleCoroutineCompletion(lua_State* L, + lua_State* co, + int status, + int coIdx, + int asyncPromiseIdx); + +// Release parent/consumer/onCancel refs after a terminal transition. +static void promise_cleanupLinks(lua_State* L, ScriptedPromise* p) +{ + if (p->m_parentRef != LUA_NOREF) + { + lua_unref(L, p->m_parentRef); + p->m_parentRef = LUA_NOREF; + } + for (int ref : p->m_consumerRefs) + { + if (ref != LUA_NOREF) + lua_unref(L, ref); + } + p->m_consumerRefs.clear(); + if (p->m_onCancelRef != LUA_NOREF) + { + lua_unref(L, p->m_onCancelRef); + p->m_onCancelRef = LUA_NOREF; + } +} + +// ── resolve / reject / cancel ───────────────────────────────────────────── + +void ScriptedPromise::resolve(lua_State* L, int valueIdx) +{ + if (m_promiseState != PromiseState::Pending) + return; + + // Promise/A+ flattening: if the resolved value is itself a Promise, + // adopt its state instead of resolving with the Promise object. + auto* inner = lua_torive(L, valueIdx, true); + if (inner && inner != this) + { + if (inner->isFulfilled()) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, inner->resultRef()); + resolve(L, lua_gettop(L)); + lua_pop(L, 1); + return; + } + if (inner->isRejected()) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, inner->resultRef()); + reject(L, lua_gettop(L)); + lua_pop(L, 1); + return; + } + if (inner->isCancelled()) + { + cancel(L); + return; + } + // Still pending — adopt by chaining. Handled by the overload + // that has a selfRef. Direct resolve() callers that don't have + // a ref to self can't adopt pending promises; assert that this + // path is unreachable in practice. + assert(false && "resolve() with pending inner promise requires " + "selfRef — use the overload"); + return; + } + + m_promiseState = PromiseState::Fulfilled; + lua_pushvalue(L, valueIdx); + m_resultRef = lua_ref(L, -1); + lua_pop(L, 1); + promise_notifyCallbacks(L, this); + promise_cleanupLinks(L, this); +} + +void ScriptedPromise::resolve(lua_State* L, int valueIdx, int selfRef) +{ + if (m_promiseState != PromiseState::Pending) + return; + + // Promise/A+ flattening with self registry ref for pending adoption. + auto* inner = lua_torive(L, valueIdx, true); + if (inner && inner != this) + { + if (inner->isFulfilled()) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, inner->resultRef()); + resolve(L, lua_gettop(L)); + lua_pop(L, 1); + return; + } + if (inner->isRejected()) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, inner->resultRef()); + reject(L, lua_gettop(L)); + lua_pop(L, 1); + return; + } + if (inner->isCancelled()) + { + cancel(L); + return; + } + // Still pending — wire this as a consumer of inner so that when + // inner settles, it forwards the result to this promise via the + // no-handler ThenCallback propagation path. + // Release any existing parent ref (this promise may already be + // chained from another promise via andThen). + if (m_parentRef != LUA_NOREF) + lua_unref(L, m_parentRef); + lua_pushvalue(L, valueIdx); // push inner for ref + m_parentRef = lua_ref(L, -1); + lua_pop(L, 1); + + // selfRef is a registry ref to this promise's userdata — duplicate + // it for the consumer list and the chained callback. + lua_rawgeti(L, LUA_REGISTRYINDEX, selfRef); + int consumerRef = lua_ref(L, -1); // for m_consumerRefs + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, selfRef); + int chainedRef = lua_ref(L, -1); // for ThenCallback + lua_pop(L, 1); + + inner->m_consumerRefs.push_back(consumerRef); + { + ScriptedPromise::ThenCallback cb; + cb.chainedPromiseRef = chainedRef; + inner->m_thenCallbacks.push_back(cb); + } + return; + } + + m_promiseState = PromiseState::Fulfilled; + lua_pushvalue(L, valueIdx); + m_resultRef = lua_ref(L, -1); + lua_pop(L, 1); + promise_notifyCallbacks(L, this); + promise_cleanupLinks(L, this); +} + +void ScriptedPromise::reject(lua_State* L, int errorIdx) +{ + if (m_promiseState != PromiseState::Pending) + return; + m_promiseState = PromiseState::Rejected; + lua_pushvalue(L, errorIdx); + m_resultRef = lua_ref(L, -1); + lua_pop(L, 1); + promise_notifyCallbacks(L, this); + promise_cleanupLinks(L, this); +} + +void ScriptedPromise::cancel(lua_State* L) +{ + if (m_promiseState != PromiseState::Pending) + return; + + m_promiseState = PromiseState::Cancelled; + + // 1. Fire the onCancel hook (if registered). + if (m_onCancelRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, m_onCancelRef); + if (lua_pcall(L, 0, 0, 0) != LUA_OK) + { + lua_pop(L, 1); // pop error object + } + } + + // 2. Propagate cancel DOWN to all consumers. + for (int ref : m_consumerRefs) + { + if (ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ref); + auto* consumer = lua_torive(L, -1, true); + lua_pop(L, 1); + if (consumer && consumer->isPending()) + consumer->cancel(L); + } + } + + // 3. Notify parent: cancel parent if ALL its consumers are now cancelled. + if (m_parentRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, m_parentRef); + auto* parent = lua_torive(L, -1, true); + lua_pop(L, 1); + if (parent && parent->isPending()) + { + bool allCancelled = true; + for (int cRef : parent->m_consumerRefs) + { + if (cRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cRef); + auto* c = lua_torive(L, -1, true); + lua_pop(L, 1); + if (c && !c->isCancelled()) + { + allCancelled = false; + break; + } + } + } + if (allCancelled) + parent->cancel(L); + } + } + + // 4. Clean up callback refs (they will never fire). + for (auto& cb : m_thenCallbacks) + { + // Fire cancelRef if present (async/await cleanup). + if (cb.cancelRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cb.cancelRef); + if (lua_pcall(L, 0, 0, 0) != LUA_OK) + { + lua_pop(L, 1); + } + lua_unref(L, cb.cancelRef); + } + if (cb.successRef != LUA_NOREF) + lua_unref(L, cb.successRef); + if (cb.failureRef != LUA_NOREF) + lua_unref(L, cb.failureRef); + if (cb.chainedPromiseRef != LUA_NOREF) + lua_unref(L, cb.chainedPromiseRef); + } + m_thenCallbacks.clear(); + for (auto& cb : m_finallyCallbacks) + { + if (cb.callbackRef != LUA_NOREF) + lua_unref(L, cb.callbackRef); + if (cb.chainedPromiseRef != LUA_NOREF) + lua_unref(L, cb.chainedPromiseRef); + } + m_finallyCallbacks.clear(); + + // 5. Clean up parent/consumer/onCancel refs. + promise_cleanupLinks(L, this); +} + +ScriptedPromise::~ScriptedPromise() +{ + // Release any held Lua refs. m_state may be the main thread of a + // still-alive VM, so only unref if we actually have refs. + if (m_resultRef != LUA_NOREF && m_state) + lua_unref(m_state, m_resultRef); + for (auto& cb : m_thenCallbacks) + { + if (cb.successRef != LUA_NOREF && m_state) + lua_unref(m_state, cb.successRef); + if (cb.failureRef != LUA_NOREF && m_state) + lua_unref(m_state, cb.failureRef); + if (cb.chainedPromiseRef != LUA_NOREF && m_state) + lua_unref(m_state, cb.chainedPromiseRef); + if (cb.cancelRef != LUA_NOREF && m_state) + lua_unref(m_state, cb.cancelRef); + } + for (auto& cb : m_finallyCallbacks) + { + if (cb.callbackRef != LUA_NOREF && m_state) + lua_unref(m_state, cb.callbackRef); + if (cb.chainedPromiseRef != LUA_NOREF && m_state) + lua_unref(m_state, cb.chainedPromiseRef); + } + if (m_parentRef != LUA_NOREF && m_state) + lua_unref(m_state, m_parentRef); + for (int ref : m_consumerRefs) + { + if (ref != LUA_NOREF && m_state) + lua_unref(m_state, ref); + } + if (m_onCancelRef != LUA_NOREF && m_state) + lua_unref(m_state, m_onCancelRef); +} + +// ── callback dispatch ────────────────────────────────────────────────────── + +static void promise_notifyCallbacks(lua_State* L, ScriptedPromise* p) +{ + // Cancelled promises don't fire andThen/catch/finally handlers. + if (p->isCancelled()) + return; + + bool fulfilled = p->isFulfilled(); + + // Push the result/error value once. + lua_rawgeti(L, LUA_REGISTRYINDEX, p->resultRef()); + + int resultIdx = lua_gettop(L); + + // ── andThen / catch callbacks ── + for (auto& cb : p->m_thenCallbacks) + { + // Resolve the chained promise ref to a pointer. + ScriptedPromise* chained = nullptr; + if (cb.chainedPromiseRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cb.chainedPromiseRef); + chained = lua_torive(L, -1, true); + lua_pop(L, 1); + // Skip cancelled consumers. + if (chained && chained->isCancelled()) + chained = nullptr; + } + + int handlerRef = fulfilled ? cb.successRef : cb.failureRef; + if (handlerRef != LUA_NOREF) + { + // Call the handler with the result. + lua_rawgeti(L, LUA_REGISTRYINDEX, handlerRef); + lua_pushvalue(L, resultIdx); + int status = lua_pcall(L, 1, 1, 0); + if (status == LUA_OK) + { + // Handler returned a value — resolve chained promise with it. + // Use the selfRef overload for Promise/A+ flattening. + if (chained) + chained->resolve(L, lua_gettop(L), cb.chainedPromiseRef); + lua_pop(L, 1); + } + else + { + // Handler errored — reject chained promise. + if (chained) + chained->reject(L, lua_gettop(L)); + lua_pop(L, 1); // pop error + } + } + else + { + // No handler for this branch — propagate to chained promise. + // No flattening needed here — the value is already unwrapped + // from the parent, not a handler return value. + if (chained) + { + if (fulfilled) + chained->resolve(L, resultIdx, cb.chainedPromiseRef); + else + chained->reject(L, resultIdx); + } + } + + // Unref handlers. + if (cb.successRef != LUA_NOREF) + lua_unref(L, cb.successRef); + if (cb.failureRef != LUA_NOREF) + lua_unref(L, cb.failureRef); + if (cb.chainedPromiseRef != LUA_NOREF) + lua_unref(L, cb.chainedPromiseRef); + if (cb.cancelRef != LUA_NOREF) + lua_unref(L, cb.cancelRef); + } + + // ── finally callbacks ── + for (auto& cb : p->m_finallyCallbacks) + { + ScriptedPromise* chained = nullptr; + if (cb.chainedPromiseRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cb.chainedPromiseRef); + chained = lua_torive(L, -1, true); + lua_pop(L, 1); + if (chained && chained->isCancelled()) + chained = nullptr; + } + + if (cb.callbackRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cb.callbackRef); + int status = lua_pcall(L, 0, 0, 0); + if (status != LUA_OK) + { + // finally threw — reject the chained promise with the error + // instead of propagating the original result. + if (chained) + chained->reject(L, lua_gettop(L)); + lua_pop(L, 1); // pop error from stack + lua_unref(L, cb.callbackRef); + if (cb.chainedPromiseRef != LUA_NOREF) + lua_unref(L, cb.chainedPromiseRef); + continue; + } + lua_unref(L, cb.callbackRef); + } + // Propagate original result to chained promise. + if (chained) + { + if (fulfilled) + chained->resolve(L, resultIdx); + else + chained->reject(L, resultIdx); + } + if (cb.chainedPromiseRef != LUA_NOREF) + lua_unref(L, cb.chainedPromiseRef); + } + + lua_pop(L, 1); // pop result value + + p->m_thenCallbacks.clear(); + p->m_finallyCallbacks.clear(); +} + +// ── helper: wire parent/consumer links for a chained promise ──────────── + +// Call after creating a chained promise. `source` is at stack index +// `sourceIdx`, chained promise is at the top of the stack. +static void promise_wireLinks(lua_State* L, + ScriptedPromise* source, + int sourceIdx, + ScriptedPromise* chained) +{ + // Consumer ref: source → chained (for downward cancel propagation). + lua_pushvalue(L, -1); // push chained + int consumerRef = lua_ref(L, -1); + lua_pop(L, 1); + source->m_consumerRefs.push_back(consumerRef); + + // Parent ref: chained → source (for upward cancel propagation). + lua_pushvalue(L, sourceIdx); + chained->m_parentRef = lua_ref(L, -1); + lua_pop(L, 1); +} + +// ── namecall: p:andThen(), p:catch(), p:finally(), p:cancel(), etc. ───── + +static int promise_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + auto* p = lua_torive(L, 1); + + if (atom == (int)LuaAtoms::andThen) + { + // andThen(onFulfilled [, onRejected]) -> Promise + int successRef = LUA_NOREF; + int failureRef = LUA_NOREF; + if (lua_isfunction(L, 2)) + { + lua_pushvalue(L, 2); + successRef = lua_ref(L, -1); + lua_pop(L, 1); + } + if (lua_isfunction(L, 3)) + { + lua_pushvalue(L, 3); + failureRef = lua_ref(L, -1); + lua_pop(L, 1); + } + + auto* chained = lua_newrive(L, lua_mainthread(L)); + // The chained promise is now at the top of the stack. + // Create a registry ref to prevent GC while the parent is pending. + lua_pushvalue(L, -1); + int chainedRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Wire parent/consumer links. + promise_wireLinks(L, p, 1, chained); + + { + ScriptedPromise::ThenCallback cb; + cb.successRef = successRef; + cb.failureRef = failureRef; + cb.chainedPromiseRef = chainedRef; + p->m_thenCallbacks.push_back(cb); + } + + if (!p->isPending()) + promise_notifyCallbacks(L, p); + + return 1; // return chained promise (still on stack) + } + else if (atom == (int)LuaAtoms::catch_) + { + // catch(onRejected) -> Promise (sugar for andThen(nil, onRejected)) + int failureRef = LUA_NOREF; + if (lua_isfunction(L, 2)) + { + lua_pushvalue(L, 2); + failureRef = lua_ref(L, -1); + lua_pop(L, 1); + } + + auto* chained = lua_newrive(L, lua_mainthread(L)); + lua_pushvalue(L, -1); + int chainedRef = lua_ref(L, -1); + lua_pop(L, 1); + + promise_wireLinks(L, p, 1, chained); + + { + ScriptedPromise::ThenCallback cb; + cb.failureRef = failureRef; + cb.chainedPromiseRef = chainedRef; + p->m_thenCallbacks.push_back(cb); + } + + if (!p->isPending()) + promise_notifyCallbacks(L, p); + + return 1; + } + else if (atom == (int)LuaAtoms::finally_) + { + int cbRef = LUA_NOREF; + if (lua_isfunction(L, 2)) + { + lua_pushvalue(L, 2); + cbRef = lua_ref(L, -1); + lua_pop(L, 1); + } + + auto* chained = lua_newrive(L, lua_mainthread(L)); + lua_pushvalue(L, -1); + int chainedRef = lua_ref(L, -1); + lua_pop(L, 1); + + promise_wireLinks(L, p, 1, chained); + + { + ScriptedPromise::FinallyCallback cb; + cb.callbackRef = cbRef; + cb.chainedPromiseRef = chainedRef; + p->m_finallyCallbacks.push_back(cb); + } + + if (!p->isPending()) + promise_notifyCallbacks(L, p); + + return 1; + } + else if (atom == (int)LuaAtoms::cancel) + { + p->cancel(L); + lua_pushvalue(L, 1); // return self for chaining + return 1; + } + else if (atom == (int)LuaAtoms::onCancel) + { + // onCancel(fn) — register a cancellation hook. + if (lua_isfunction(L, 2)) + { + if (p->m_onCancelRef != LUA_NOREF) + lua_unref(L, p->m_onCancelRef); + lua_pushvalue(L, 2); + p->m_onCancelRef = lua_ref(L, -1); + lua_pop(L, 1); + } + lua_pushvalue(L, 1); // return self + return 1; + } + else if (atom == (int)LuaAtoms::getStatus) + { + switch (p->m_promiseState) + { + case PromiseState::Pending: + lua_pushstring(L, "Pending"); + break; + case PromiseState::Fulfilled: + lua_pushstring(L, "Fulfilled"); + break; + case PromiseState::Rejected: + lua_pushstring(L, "Rejected"); + break; + case PromiseState::Cancelled: + lua_pushstring(L, "Cancelled"); + break; + } + return 1; + } + + luaL_error(L, "'%s' is not a valid method of Promise", str); + return 0; +} + +// ── static methods: Promise.resolve(), Promise.reject(), Promise.all() ─── + +static int promise_static_resolve(lua_State* L) +{ + auto* p = lua_newrive(L, lua_mainthread(L)); + int pIdx = lua_gettop(L); // p is on top of stack + if (pIdx >= 2) + { + // Promise.resolve(value) — use selfRef overload for A+ flattening. + lua_pushvalue(L, pIdx); + int selfRef = lua_ref(L, -1); + lua_pop(L, 1); + p->resolve(L, 1, selfRef); // arg 1 is the value (before we pushed p) + lua_unref(L, selfRef); + } + else + { + // Promise.resolve() with no value → resolve with nil + lua_pushnil(L); + p->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + } + return 1; +} + +static int promise_static_reject(lua_State* L) +{ + auto* p = lua_newrive(L, lua_mainthread(L)); + if (lua_gettop(L) >= 2) + { + p->reject(L, 1); + } + else + { + lua_pushstring(L, "rejected"); + p->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + return 1; +} + +// ── Promise.new(executor) ─────────────────────────────────────────────── + +static int promise_static_new(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + + auto* p = lua_newrive(L, lua_mainthread(L)); + int promiseIdx = lua_gettop(L); + + // Create resolve callback — captures promise as direct upvalue (no + // registry ref needed; GC keeps it alive via the closure). + lua_pushvalue(L, promiseIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + auto* promise = + lua_torive(L, lua_upvalueindex(1), true); + if (promise && promise->isPending()) + { + if (lua_gettop(L) >= 1) + { + // Use selfRef overload for A+ flattening. + lua_pushvalue(L, lua_upvalueindex(1)); + int selfRef = lua_ref(L, -1); + lua_pop(L, 1); + promise->resolve(L, 1, selfRef); + lua_unref(L, selfRef); + } + else + { + lua_pushnil(L); + promise->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + } + } + return 0; + }, + nullptr, + 1, + nullptr); + int resolveIdx = lua_gettop(L); + + // Create reject callback. + lua_pushvalue(L, promiseIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + auto* promise = + lua_torive(L, lua_upvalueindex(1), true); + if (promise && promise->isPending()) + { + if (lua_gettop(L) >= 1) + promise->reject(L, 1); + else + { + lua_pushstring(L, "rejected"); + promise->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + } + return 0; + }, + nullptr, + 1, + nullptr); + int rejectIdx = lua_gettop(L); + + // Create onCancel callback. + lua_pushvalue(L, promiseIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + auto* promise = + lua_torive(L, lua_upvalueindex(1), true); + if (promise && lua_isfunction(L, 1)) + { + if (promise->m_onCancelRef != LUA_NOREF) + lua_unref(L, promise->m_onCancelRef); + lua_pushvalue(L, 1); + promise->m_onCancelRef = lua_ref(L, -1); + lua_pop(L, 1); + } + return 0; + }, + nullptr, + 1, + nullptr); + int onCancelIdx = lua_gettop(L); + + // Call executor(resolve, reject, onCancel). + lua_pushvalue(L, 1); // push executor + lua_pushvalue(L, resolveIdx); + lua_pushvalue(L, rejectIdx); + lua_pushvalue(L, onCancelIdx); + int status = lua_pcall(L, 3, 0, 0); + if (status != LUA_OK) + { + // Executor threw — reject the promise with the error. + if (p->isPending()) + p->reject(L, lua_gettop(L)); + lua_pop(L, 1); // pop error + } + + // Clean up intermediates and return the promise. + lua_pushvalue(L, promiseIdx); + return 1; +} + +// ── Promise.all ───────────────────────────────────────────────────────── + +static int promise_static_all(lua_State* L) +{ + // Promise.all({p1, p2, ...}) -> Promise<{v1, v2, ...}> + luaL_checktype(L, 1, LUA_TTABLE); + int n = lua_objlen(L, 1); + + auto* result = lua_newrive(L, lua_mainthread(L)); + int resultIdx = lua_gettop(L); + + if (n == 0) + { + // Empty array → resolve immediately with empty table. + lua_newtable(L); + result->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + lua_pushvalue(L, resultIdx); + return 1; + } + + // Shared state table — stays on L's stack, captured as direct upvalue + // by all success/failure closures. No registry ref needed. + // Fields: { remaining=n, results={}, done=false } + lua_newtable(L); + int stateIdx = lua_gettop(L); + lua_pushinteger(L, n); + lua_setfield(L, stateIdx, "remaining"); + lua_newtable(L); + lua_setfield(L, stateIdx, "results"); + lua_pushboolean(L, false); + lua_setfield(L, stateIdx, "done"); + + // Chained refs table — stays on stack, captured as direct upvalue. + // Populated during the loop below with registry refs to chained + // promises for cancellation cleanup. + lua_newtable(L); + int chainedRefsTableIdx = lua_gettop(L); + + for (int i = 1; i <= n; i++) + { + lua_rawgeti(L, 1, i); // push promises[i] + auto* pi = lua_torive(L, -1, true); + int piIdx = lua_gettop(L); + if (!pi) + { + lua_pop(L, 1); + luaL_error(L, "Promise.all: element %d is not a Promise", i); + return 0; + } + + // Create chained promise for this input. + auto* chained = lua_newrive(L, lua_mainthread(L)); + int chainedIdx = lua_gettop(L); + + // Wire parent/consumer links: pi → chained. + promise_wireLinks(L, pi, piIdx, chained); + + // Registry ref for ThenCallback dispatch. + lua_pushvalue(L, chainedIdx); + int chainedRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Store a separate ref in the chainedRefs table for cancellation. + lua_pushvalue(L, chainedIdx); + int cancelCollectionRef = lua_ref(L, -1); + lua_pop(L, 1); + lua_pushinteger(L, cancelCollectionRef); + lua_rawseti(L, chainedRefsTableIdx, i); + + // Success closure: upvalues = (index, state, resultPromise, + // chainedRefs) + lua_pushinteger(L, i); + lua_pushvalue(L, stateIdx); + lua_pushvalue(L, resultIdx); + lua_pushvalue(L, chainedRefsTableIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + int idx = (int)lua_tointeger(L, lua_upvalueindex(1)); + // upvalue 2 = state table, 3 = result promise, 4 = chainedRefs + + lua_pushvalue(L, lua_upvalueindex(2)); // state + int st = lua_gettop(L); + + lua_getfield(L, st, "done"); + if (lua_toboolean(L, -1)) + { + lua_pop(L, 2); + return 0; + } + lua_pop(L, 1); + + // Store result at index. + lua_getfield(L, st, "results"); + lua_pushvalue(L, 1); + lua_rawseti(L, -2, idx); + lua_pop(L, 1); + + // Decrement remaining. + lua_getfield(L, st, "remaining"); + int rem = (int)lua_tointeger(L, -1) - 1; + lua_pop(L, 1); + lua_pushinteger(L, rem); + lua_setfield(L, st, "remaining"); + + if (rem == 0) + { + lua_pushboolean(L, true); + lua_setfield(L, st, "done"); + + auto* rp = lua_torive(L, + lua_upvalueindex(3), + true); + if (rp && rp->isPending()) + { + lua_getfield(L, st, "results"); + rp->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + } + + // Clean up cancelCollectionRefs in chainedRefs table. + lua_pushvalue(L, lua_upvalueindex(4)); + int tbl = lua_gettop(L); + int count = (int)lua_objlen(L, tbl); + for (int j = 1; j <= count; j++) + { + lua_rawgeti(L, tbl, j); + int cRef = (int)lua_tointeger(L, -1); + lua_pop(L, 1); + if (cRef != LUA_NOREF) + lua_unref(L, cRef); + } + lua_pop(L, 1); // pop table + } + + lua_pop(L, 1); // pop state table + return 0; + }, + nullptr, + 4, + nullptr); + int successRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Failure closure: upvalues = (state, resultPromise, chainedRefs) + lua_pushvalue(L, stateIdx); + lua_pushvalue(L, resultIdx); + lua_pushvalue(L, chainedRefsTableIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + // upvalue 1 = state, 2 = result promise, 3 = chainedRefs + lua_pushvalue(L, lua_upvalueindex(1)); // state + int st = lua_gettop(L); + + lua_getfield(L, st, "done"); + if (lua_toboolean(L, -1)) + { + lua_pop(L, 2); + return 0; + } + lua_pop(L, 1); + + lua_pushboolean(L, true); + lua_setfield(L, st, "done"); + + auto* rp = + lua_torive(L, lua_upvalueindex(2), true); + if (rp && rp->isPending()) + { + rp->reject(L, 1); // arg 1 is the error + } + + // Cancel all chained promises from chainedRefs table. + lua_pushvalue(L, lua_upvalueindex(3)); + int tbl = lua_gettop(L); + int count = (int)lua_objlen(L, tbl); + for (int j = 1; j <= count; j++) + { + lua_rawgeti(L, tbl, j); + int cRef = (int)lua_tointeger(L, -1); + lua_pop(L, 1); + if (cRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cRef); + auto* cp = lua_torive(L, -1, true); + lua_pop(L, 1); + if (cp && cp->isPending()) + cp->cancel(L); + lua_unref(L, cRef); + } + } + lua_pop(L, 1); // pop table + + lua_pop(L, 1); // pop state table + return 0; + }, + nullptr, + 3, + nullptr); + int failureRef = lua_ref(L, -1); + lua_pop(L, 1); + + { + ScriptedPromise::ThenCallback cb; + cb.successRef = successRef; + cb.failureRef = failureRef; + cb.chainedPromiseRef = chainedRef; + pi->m_thenCallbacks.push_back(cb); + } + + if (!pi->isPending()) + promise_notifyCallbacks(L, pi); + + lua_pop(L, 2); // pop chained promise and pi + } + + // Register onCancel hook: captures chainedRefs table as direct upvalue. + lua_pushvalue(L, chainedRefsTableIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + // upvalue 1 = chainedRefs table + lua_pushvalue(L, lua_upvalueindex(1)); + int tbl = lua_gettop(L); + int count = (int)lua_objlen(L, tbl); + + for (int j = 1; j <= count; j++) + { + lua_rawgeti(L, tbl, j); + int cRef = (int)lua_tointeger(L, -1); + lua_pop(L, 1); + if (cRef != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, cRef); + auto* cp = lua_torive(L, -1, true); + lua_pop(L, 1); + if (cp && cp->isPending()) + cp->cancel(L); + lua_unref(L, cRef); + } + } + lua_pop(L, 1); // pop table + return 0; + }, + nullptr, + 1, + nullptr); + result->m_onCancelRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Pop the chainedRefs table and state table from the stack. + lua_pop(L, 2); + + lua_pushvalue(L, resultIdx); + return 1; +} + +// ── Promise table __index (static method dispatch) ───────────────────── + +static int promise_table_index(lua_State* L) +{ + const char* key = luaL_checkstring(L, 2); + if (strcmp(key, "resolve") == 0) + { + lua_pushcfunction(L, promise_static_resolve, "Promise.resolve"); + return 1; + } + if (strcmp(key, "reject") == 0) + { + lua_pushcfunction(L, promise_static_reject, "Promise.reject"); + return 1; + } + if (strcmp(key, "all") == 0) + { + lua_pushcfunction(L, promise_static_all, "Promise.all"); + return 1; + } + if (strcmp(key, "new") == 0) + { + lua_pushcfunction(L, promise_static_new, "Promise.new"); + return 1; + } + luaL_error(L, "'%s' is not a valid member of Promise", key); + return 0; +} + +// ── async / await ────────────────────────────────────────────────────────── + +// await(promise) -> (ok: boolean, value: any) +// Non-throwing: returns (true, resolvedValue) or (false, rejectionReason). +// Matches Roblox Promise:await() semantics. Use expect() for throwing variant. +static int lua_await(lua_State* L) +{ + auto* p = lua_torive(L, 1); + + if (!lua_isyieldable(L)) + { + luaL_error(L, "await() must be called inside async()"); + return 0; + } + + if (p->isFulfilled()) + { + lua_pushboolean(L, true); + lua_rawgeti(L, LUA_REGISTRYINDEX, p->resultRef()); + return 2; + } + if (p->isRejected()) + { + lua_pushboolean(L, false); + lua_rawgeti(L, LUA_REGISTRYINDEX, p->resultRef()); + return 2; + } + if (p->isCancelled()) + { + lua_pushboolean(L, false); + lua_pushstring(L, "Promise was cancelled"); + return 2; + } + + // Pending — yield with the promise on the stack so the caller + // (async's resume callback) can attach andThen to it. + lua_pushvalue(L, 1); + int nresults = lua_yield(L, 1); + // After resume: success callback pushes (true, value), + // failure callback pushes (false, error). + // Return them directly — no throwing. + return nresults; +} + +static int lua_async(lua_State* L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + + // Create the result promise. + lua_newrive(L, lua_mainthread(L)); + int promiseIdx = lua_gettop(L); + + // Create a coroutine. Both stay on L's stack — closures capture + // them as direct upvalues, GC keeps them alive. + lua_State* co = lua_newthread(L); + int coIdx = lua_gettop(L); + + // Copy function to coroutine stack. + lua_pushvalue(L, 1); + lua_xmove(L, co, 1); + + // Resume the coroutine (0 args). + int status = lua_resume(co, L, 0); + + handleCoroutineCompletion(L, co, status, coIdx, promiseIdx); + + // Clean up thread from main stack. + lua_remove(L, coIdx); + + // Return the promise. + lua_pushvalue(L, promiseIdx); + return 1; +} + +// handleCoroutineCompletion takes the coroutine and async promise as +// stack values (coIdx, asyncPromiseIdx on L). Closures capture them +// as direct upvalues — no registry refs needed; GC owns lifetime. +static void handleCoroutineCompletion(lua_State* L, + lua_State* co, + int status, + int coIdx, + int asyncPromiseIdx) +{ + auto* asyncPromise = lua_torive(L, asyncPromiseIdx, true); + + if (status == LUA_OK) + { + // Coroutine finished — resolve with the return value (if any). + // Use selfRef overload for A+ flattening (user may return a Promise). + if (lua_gettop(co) > 0) + { + lua_xmove(co, L, 1); + lua_pushvalue(L, asyncPromiseIdx); + int selfRef = lua_ref(L, -1); + lua_pop(L, 1); + asyncPromise->resolve(L, lua_gettop(L), selfRef); + lua_unref(L, selfRef); + lua_pop(L, 1); + } + else + { + lua_pushnil(L); + asyncPromise->resolve(L, lua_gettop(L)); + lua_pop(L, 1); + } + // No refs to clean up — GC handles the upvalues. + } + else if (status == LUA_YIELD) + { + // Coroutine yielded at await(promise). + if (lua_gettop(co) < 1) + { + luaL_error(L, "async: coroutine yielded without a promise"); + return; + } + + auto* awaited = lua_torive(co, -1, true); + if (!awaited) + { + luaL_error(L, "async: await() argument is not a Promise"); + return; + } + lua_pop(co, 1); // pop the promise from co stack + + // Success callback: captures coroutine + asyncPromise as upvalues. + // asyncPromise is captured to prevent GC, not used directly. + lua_pushvalue(L, coIdx); + lua_pushvalue(L, asyncPromiseIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + lua_State* co = lua_tothread(L, lua_upvalueindex(1)); + + // Push (true, resolvedValue) onto coroutine stack. + lua_pushboolean(co, true); + lua_pushvalue(L, 1); + lua_xmove(L, co, 1); + + int status = lua_resume(co, L, 2); + + // Push co + asyncPromise onto stack for recursive call. + lua_pushvalue(L, lua_upvalueindex(1)); + int coIdx = lua_gettop(L); + lua_pushvalue(L, lua_upvalueindex(2)); + int apIdx = lua_gettop(L); + handleCoroutineCompletion(L, co, status, coIdx, apIdx); + lua_pop(L, 2); + return 0; + }, + nullptr, + 2, + nullptr); + int successRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Failure callback: resume coroutine with (false, error). + // asyncPromise is captured to prevent GC, not used directly. + lua_pushvalue(L, coIdx); + lua_pushvalue(L, asyncPromiseIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + lua_State* co = lua_tothread(L, lua_upvalueindex(1)); + + lua_pushboolean(co, false); + lua_pushvalue(L, 1); + lua_xmove(L, co, 1); + + int status = lua_resume(co, L, 2); + + lua_pushvalue(L, lua_upvalueindex(1)); + int coIdx = lua_gettop(L); + lua_pushvalue(L, lua_upvalueindex(2)); + int apIdx = lua_gettop(L); + handleCoroutineCompletion(L, co, status, coIdx, apIdx); + lua_pop(L, 2); + return 0; + }, + nullptr, + 2, + nullptr); + int failureRef = lua_ref(L, -1); + lua_pop(L, 1); + + // Cancel callback: close the coroutine and reject async promise. + lua_pushvalue(L, coIdx); + lua_pushvalue(L, asyncPromiseIdx); + lua_pushcclosurek( + L, + [](lua_State* L) -> int { + lua_State* co = lua_tothread(L, lua_upvalueindex(1)); + auto* ap = + lua_torive(L, lua_upvalueindex(2), true); + + // Close the coroutine to release its stack/locals + // immediately rather than waiting for GC. + if (co) + lua_resetthread(co); + + if (ap && ap->isPending()) + { + lua_pushstring(L, "Promise was cancelled"); + ap->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + return 0; + }, + nullptr, + 2, + nullptr); + int cancelRef = lua_ref(L, -1); + lua_pop(L, 1); + + { + ScriptedPromise::ThenCallback cb; + cb.successRef = successRef; + cb.failureRef = failureRef; + cb.cancelRef = cancelRef; + awaited->m_thenCallbacks.push_back(cb); + } + + if (!awaited->isPending()) + promise_notifyCallbacks(L, awaited); + } + else + { + // Coroutine errored. + if (lua_gettop(co) > 0) + { + lua_xmove(co, L, 1); + asyncPromise->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + else + { + lua_pushstring(L, "async function errored"); + asyncPromise->reject(L, lua_gettop(L)); + lua_pop(L, 1); + } + } +} + +// ── registration ─────────────────────────────────────────────────────────── + +int luaopen_rive_promise(lua_State* L) +{ + // Register ScriptedPromise type. + lua_register_rive(L); + lua_pushcfunction(L, promise_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop metatable + + // Create global Promise table. + lua_newtable(L); + + // Metatable for static method dispatch. + lua_newtable(L); + lua_pushcfunction(L, promise_table_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + + lua_setglobal(L, "Promise"); + + // Register global await / async functions. + lua_pushcfunction(L, lua_await, "await"); + lua_setglobal(L, "await"); + + lua_pushcfunction(L, lua_async, "async"); + lua_setglobal(L, "async"); + + return 0; +} + +} // namespace rive + +#endif // WITH_RIVE_SCRIPTING diff --git a/thirdparty/rive/source/lua/lua_properties.cpp b/thirdparty/rive/source/lua/lua_properties.cpp new file mode 100644 index 000000000..9f75caea1 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_properties.cpp @@ -0,0 +1,1750 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/viewmodel/viewmodel_property_asset_image.hpp" +#include "rive/viewmodel/viewmodel_property_boolean.hpp" +#include "rive/viewmodel/viewmodel_property_color.hpp" +#include "rive/viewmodel/viewmodel_property_enum.hpp" +#include "rive/viewmodel/viewmodel_property_number.hpp" +#include "rive/viewmodel/viewmodel_property_string.hpp" +#include "rive/viewmodel/viewmodel_property_trigger.hpp" +#include "rive/viewmodel/viewmodel_property_list.hpp" +#include "rive/viewmodel/viewmodel_property_symbol_list_index.hpp" +#include "rive/viewmodel/viewmodel_property_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance_asset_image.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/viewmodel/viewmodel_instance_enum.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/viewmodel/viewmodel_instance_symbol_list_index.hpp" +#include "rive/scripted/scripted_object.hpp" + +#include + +using namespace rive; + +static ScriptingContext* scriptingContext(lua_State* L) +{ + return static_cast(lua_getthreaddata(L)); +} + +static void pushViewModelInstanceValue(lua_State* L, + rcp viewModel, + ViewModelInstanceValue* propValue) +{ + switch (propValue->coreType()) + { + case ViewModelInstanceNumberBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceTriggerBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceListBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceColorBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceStringBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceBooleanBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceEnumBase::typeKey: + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceViewModelBase::typeKey: + lua_newrive( + L, + L, + viewModel, + ref_rcp(propValue->as())); + break; + case ViewModelInstanceSymbolListIndexBase::typeKey: + { + + auto listIndexProp = + propValue->as(); + lua_pushinteger(L, listIndexProp->propertyValue()); + break; + } + case ViewModelInstanceAssetImageBase::typeKey: + { + lua_newrive( + L, + L, + ref_rcp(propValue->as())); + break; + } + default: + lua_pushnil(L); + break; + } +} + +// int ScriptedPropertyViewModel::pushValueOfType(const char* name, int +// coreType) +// { +// auto vmi = m_instanceValue->referenceViewModelInstance(); +// if (!vmi) +// { +// lua_pushnil(m_state); +// } +// else +// { +// auto propValue = vmi->propertyValue(name); +// if (propValue->coreType() != coreType) +// { +// lua_pushnil(m_state); +// } +// else +// { +// pushViewModelInstanceValue(m_state, propValue); +// } +// } +// return 1; +// } + +ScriptedProperty::~ScriptedProperty() { dispose(); } + +ScriptedPropertyViewModel::~ScriptedPropertyViewModel() { dispose(); } + +void ScriptedProperty::clearListeners() +{ + for (auto itr = m_listeners.begin(); itr != m_listeners.end(); ++itr) + { + const ScriptedListener& listener = *itr; + lua_unref(m_state, listener.function); + if (listener.userdata) + { + lua_unref(m_state, listener.userdata); + } + lua_unref(m_state, listener.propertySelfRef); + } + m_listeners.clear(); +} + +ScriptedProperty::ScriptedProperty(lua_State* L, + rcp value) : + m_state(L), m_instanceValue(std::move(value)) +{ + if (m_instanceValue != nullptr) + { + m_instanceValue->addDelegate(this); + } + + auto context = scriptingContext(L); + if (context != nullptr) + { + m_owner = context->currentScriptedObject(); + if (m_owner != nullptr) + { + m_owner->addTrackedScriptedProperty(this); + } +#ifdef WITH_RIVE_TOOLS + else + { + context->trackOrphanScriptedProperty(this); + m_orphanContext = context; + } +#endif + } +} + +void ScriptedProperty::dispose() +{ + if (m_disposed) + { + return; + } + m_disposed = true; + + if (m_owner != nullptr) + { + m_owner->removeTrackedScriptedProperty(this); + m_owner = nullptr; + } +#ifdef WITH_RIVE_TOOLS + if (m_orphanContext != nullptr) + { + m_orphanContext->untrackOrphanScriptedProperty(this); + m_orphanContext = nullptr; + } +#endif + + if (m_instanceValue != nullptr) + { + m_instanceValue->removeDelegate(this); + m_instanceValue = nullptr; + } + + clearListeners(); +} + +void ScriptedProperty::valueChanged() +{ + // This works because we don't actually call as we go (or we could + // invalidate listeners if a callback registers a new or removes a + // listener). Instead, we build up the call stack and then call for each + // callback on the stack. + for (auto itr = m_listeners.rbegin(); itr != m_listeners.rend(); itr++) + { + const ScriptedListener& listener = *itr; + lua_rawgeti(m_state, LUA_REGISTRYINDEX, listener.function); + if (listener.userdata) + { + lua_rawgeti(m_state, LUA_REGISTRYINDEX, listener.userdata); + } + else + { + // push nil so we have a constant number of args per call + lua_pushnil(m_state); + } + } + size_t calls = m_listeners.size(); + for (size_t i = 0; i < calls; i++) + { + lua_pcall(m_state, 1, 0, 0); + } +} + +int ScriptedProperty::addListener() +{ + if (lua_isfunction(m_state, 2)) + { + lua_pushvalue(m_state, 1); + int propertySelfRef = lua_ref(m_state, -1); + lua_pop(m_state, 1); + int callbackRef = lua_ref(m_state, 2); + m_listeners.push_back({callbackRef, 0, propertySelfRef}); + return 0; + } + else if (lua_isfunction(m_state, 3)) + { + lua_pushvalue(m_state, 1); + int propertySelfRef = lua_ref(m_state, -1); + lua_pop(m_state, 1); + int userdataRef = lua_ref(m_state, 2); + int callbackRef = lua_ref(m_state, 3); + m_listeners.push_back({callbackRef, userdataRef, propertySelfRef}); + return 0; + } + + luaL_typeerrorL(m_state, 2, lua_typename(m_state, LUA_TFUNCTION)); + return 0; +} + +int ScriptedProperty::removeListener() +{ + int checkIndex; + if (lua_isfunction(m_state, 2)) + { + checkIndex = 2; + } + else if (lua_isfunction(m_state, 3)) + { + checkIndex = 3; + } + else + { + luaL_typeerrorL(m_state, 2, lua_typename(m_state, LUA_TFUNCTION)); + } + + for (auto itr = m_listeners.begin(); itr != m_listeners.end();) + { + const ScriptedListener& listener = *itr; + lua_rawgeti(m_state, LUA_REGISTRYINDEX, listener.function); + if (lua_rawequal(m_state, -1, checkIndex)) + { + lua_unref(m_state, listener.function); + if (listener.userdata) + { + lua_unref(m_state, listener.userdata); + } + lua_unref(m_state, listener.propertySelfRef); + itr = m_listeners.erase(itr); + } + else + { + ++itr; + } + lua_pop(m_state, 1); + } + return 0; +} + +ScriptedPropertyViewModel::ScriptedPropertyViewModel( + lua_State* L, + rcp viewModel, + rcp value) : + ScriptedProperty(L, std::move(value)), m_viewModel(std::move(viewModel)) +{} + +void ScriptedPropertyViewModel::setValue(ScriptedViewModel* scriptedViewModel) +{ + if (m_instanceValue != nullptr && + m_instanceValue->is()) + { + auto instanceValue = m_instanceValue->as(); + auto parentViewModelInstance = instanceValue->parentViewModelInstance(); + auto viewModelInstance = scriptedViewModel->mutableViewModelInstance(); + parentViewModelInstance->replaceViewModelByProperty( + instanceValue, + rcp(viewModelInstance)); + // Invalidate cached Lua-side value so the next push reflects the new + // instance. + clearRef(); + } +} + +void ScriptedPropertyViewModel::dispose() +{ + if (m_instanceValue) + { + m_instanceValue->removeDependent(this); + } + clearRef(); + ScriptedProperty::dispose(); +} + +void ScriptedPropertyViewModel::clearRef() +{ + + if (m_valueRef != 0) + { + lua_unref(m_state, m_valueRef); + m_valueRef = 0; + } +} + +ScriptedViewModel::ScriptedViewModel(lua_State* L, + rcp viewModel, + rcp viewModelInstance) : + m_state(L), m_viewModel(viewModel), m_viewModelInstance(viewModelInstance) +{} + +ScriptedViewModel::~ScriptedViewModel() +{ + for (auto itr : m_propertyRefs) + { + lua_unref(m_state, itr.second); + } +} + +int ScriptedViewModel::instance(lua_State* L) +{ + if (m_viewModel) + { + + int nargs = lua_gettop(L); + if (nargs == 2) + { + if (lua_isnoneornil(L, -1) || !lua_isstring(L, -1)) + { + auto instance = m_viewModel->createInstance(); + lua_newrive(L, L, m_viewModel, instance); + } + else + { + const char* instanceName = lua_tostring(L, -1); + auto instance = m_viewModel->createFromInstance(instanceName); + if (!instance) + { + instance = m_viewModel->createInstance(); + } + lua_newrive(L, L, m_viewModel, instance); + } + } + else + { + auto instance = m_viewModel->createInstance(); + lua_newrive(L, L, m_viewModel, instance); + } + } + else + { + lua_pushnil(L); + } + return 1; +} + +int ScriptedViewModel::pushValue(const char* name, int coreType) +{ + auto itr = m_propertyRefs.find(name); + if (itr != m_propertyRefs.end()) + { + lua_rawgeti(m_state, LUA_REGISTRYINDEX, itr->second); + return 1; + } + // To be fully typesafe at runtime we should check the property in the + // viewmodel and make sure the one in the value matches the same type or + // return a default based on the type of the viewmodel, but this incurs + // extra performance and since our type system at edit-time lets the user be + // intentional, for now we runtime error if the type is un-expected and we + // optimize for the best case. + + auto vmi = m_viewModelInstance; + if (!vmi) + { + // Get type from viewmodel if we have one and user didn't request a type + // dynamically. + if (coreType != 0 || !m_viewModel) + { + lua_pushnil(m_state); + } + else + { + auto prop = m_viewModel->property(name); + switch (prop->coreType()) + { + case ViewModelPropertyNumberBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyTriggerBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyListBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyColorBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyStringBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyBooleanBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyEnumBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertyViewModelBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr, + nullptr); + break; + case ViewModelPropertyAssetImageBase::typeKey: + lua_newrive(m_state, + m_state, + nullptr); + break; + case ViewModelPropertySymbolListIndexBase::typeKey: + lua_pushinteger(m_state, 1); + break; + } + } + } + else + { + auto propValue = vmi->propertyValue(name); + if (propValue == nullptr || + (coreType != 0 && propValue->coreType() != coreType)) + { + lua_pushnil(m_state); + } + else + { + pushViewModelInstanceValue(m_state, m_viewModel, propValue); + } + } + m_propertyRefs[name] = lua_ref(m_state, -1); + return 1; +} + +int ScriptedViewModel::pushIndex() +{ + auto prop = m_viewModelInstance->propertyValue(SymbolType::itemIndex); + if (prop && prop->is()) + { + lua_pushinteger( + m_state, + prop->as()->propertyValue()); + } + else + { + lua_pushinteger(m_state, -1); + } + return 1; +} + +int ScriptedPropertyViewModel::pushValue() +{ + if (m_valueRef != 0) + { + lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_valueRef); + return 1; + } + if (m_instanceValue) + { + m_instanceValue->addDependent(this); + lua_newrive( + m_state, + m_state, + m_viewModel, + m_instanceValue->as() + ->referenceViewModelInstance()); + } + else + { + // Push nil or push an empty model ref? For now empty/with def values. + lua_newrive(m_state, m_state, m_viewModel, nullptr); + } + m_valueRef = lua_ref(m_state, -1); + return 1; +} + +void ScriptedPropertyViewModel::relinkDataBind() { clearRef(); } + +static int property_vm_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto vmProp = lua_torive(L, 1); + assert(vmProp->state() == L); + switch (atom) + { + case (int)LuaAtoms::value: + return vmProp->pushValue(); + default: + return 0; + } +} + +static int property_vm_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedPropertyViewModel = + lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + { + auto vm = lua_torive(L, 3); + scriptedPropertyViewModel->setValue(vm); + break; + } + default: + return 0; + } + + return 0; +} + +static int vm_index(lua_State* L) +{ + auto vm = lua_torive(L, 1); + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name); +} + +static int property_namecall_atom(lua_State* L, + ScriptedProperty* property, + int atom, + bool& error) +{ + switch (atom) + { + case (int)LuaAtoms::addListener: + { + assert(property->state() == L); + return property->addListener(); + } + case (int)LuaAtoms::removeListener: + { + assert(property->state() == L); + return property->removeListener(); + } + case (int)LuaAtoms::fire: + { + auto value = property->instanceValue(); + if (value != nullptr && value->is()) + { + value->as()->trigger(); + return 0; + } + } + case (int)LuaAtoms::push: + { + auto scriptedViewModel = lua_torive(L, 2); + auto vmi = scriptedViewModel->viewModelInstance(); + auto copy = ref_rcp(vmi.get()); + auto list = property->instanceValue()->as(); + auto listItem = make_rcp(); + + listItem->viewModelInstance(copy); + list->addItem(listItem); + return 0; + } + case (int)LuaAtoms::pop: + { + auto list = property->instanceValue()->as(); + auto listItem = list->pop(); + if (listItem) + { + auto vmi = listItem->viewModelInstance(); + if (vmi) + { + lua_newrive(L, + L, + ref_rcp(vmi->viewModel()), + vmi); + return 1; + } + } + return 0; + } + case (int)LuaAtoms::swap: + { + auto list = property->instanceValue()->as(); + auto index1 = lua_tounsigned(L, 2); + auto index2 = lua_tounsigned(L, 3); + list->swap(index1 - 1, index2 - 1); + return 0; + } + case (int)LuaAtoms::shift: + { + auto list = property->instanceValue()->as(); + auto listItem = list->shift(); + if (listItem) + { + auto vmi = listItem->viewModelInstance(); + if (vmi) + { + lua_newrive(L, + L, + ref_rcp(vmi->viewModel()), + vmi); + return 1; + } + } + return 0; + } + case (int)LuaAtoms::clear: + { + auto list = property->instanceValue()->as(); + list->removeAllItems(); + return 0; + } + + case (int)LuaAtoms::insert: + { + auto scriptedViewModel = lua_torive(L, 2); + auto index = lua_tounsigned(L, 3); + auto vmi = scriptedViewModel->viewModelInstance(); + auto copy = ref_rcp(vmi.get()); + auto list = property->instanceValue()->as(); + auto listItem = make_rcp(); + + listItem->viewModelInstance(copy); + list->addItemAt(listItem, index - 1); + return 0; + } + + case (int)LuaAtoms::remove: + { + auto list = property->instanceValue()->as(); + auto* vmUser = static_cast( + lua_touserdatatagged(L, 2, ScriptedViewModel::luaTag)); + if (vmUser != nullptr) + { + auto vmi = vmUser->viewModelInstance(); + if (vmi) + { + for (const auto& item : list->listItems()) + { + if (item->viewModelInstance() == vmi) + { + list->removeItem(item); + break; + } + } + } + } + return 0; + } + + case (int)LuaAtoms::removeAt: + { + auto list = property->instanceValue()->as(); + const lua_Integer luaIndex = luaL_checkinteger(L, 2); + const size_t count = list->listItems().size(); + if (luaIndex < 1 || + static_cast(luaIndex) > static_cast(count)) + { + luaL_error(L, "removeAt index out of range"); + } + list->removeItem(static_cast(luaIndex - 1)); + return 0; + } + + case (int)LuaAtoms::removeAllOf: + { + auto list = property->instanceValue()->as(); + auto* vmUser = static_cast( + lua_touserdatatagged(L, 2, ScriptedViewModel::luaTag)); + if (vmUser != nullptr) + { + auto vmi = vmUser->viewModelInstance(); + if (vmi) + { + list->removeAllItemsWithViewModelInstance(vmi.get()); + } + } + return 0; + } + + case (int)LuaAtoms::values: + { + auto viewModelInstanceEnum = + property->instanceValue()->as(); + DataEnum* dataEnum = nullptr; + auto viewModelPropertyEnum = + viewModelInstanceEnum->viewModelProperty() + ->as(); + if (viewModelPropertyEnum) + { + dataEnum = viewModelPropertyEnum->dataEnum(); + } + lua_newrive(L, L, dataEnum); + + return 1; + } + } + error = true; + return 0; +} + +static int vm_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto vm = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::getNumber: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, + ViewModelInstanceNumberBase::typeKey); + } + case (int)LuaAtoms::getTrigger: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, + ViewModelInstanceTriggerBase::typeKey); + } + case (int)LuaAtoms::getString: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, + ViewModelInstanceStringBase::typeKey); + } + case (int)LuaAtoms::getBoolean: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, + ViewModelInstanceBooleanBase::typeKey); + } + case (int)LuaAtoms::getColor: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, ViewModelInstanceColorBase::typeKey); + } + case (int)LuaAtoms::getList: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, ViewModelInstanceListBase::typeKey); + } + case (int)LuaAtoms::getViewModel: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, + ViewModelInstanceViewModelBase::typeKey); + } + case (int)LuaAtoms::getEnum: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, ViewModelInstanceEnumBase::typeKey); + } + case (int)LuaAtoms::getIndex: + { + assert(vm->state() == L); + return vm->pushIndex(); + } + case (int)LuaAtoms::getImage: + { + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + assert(vm->state() == L); + return vm->pushValue(name, + ViewModelInstanceAssetImageBase::typeKey); + } + case (int)LuaAtoms::instance: + case (int)LuaAtoms::newAtom: + { + assert(vm->state() == L); + return vm->instance(L); + } + default: + break; + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedPropertyViewModel::luaName); + return 0; +} + +static int property_vm_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto vm = lua_torive(L, 1); + + bool error = false; + int stackChange = property_namecall_atom(L, vm, atom, error); + if (!error) + { + return stackChange; + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedPropertyViewModel::luaName); + return 0; +} + +static int property_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + const char* name = "Property"; + if (str != nullptr) + { + auto tag = lua_userdatatag(L, 1); + switch (tag) + { + case ScriptedPropertyNumber::luaTag: + name = ScriptedPropertyNumber::luaName; + break; + case ScriptedPropertyTrigger::luaTag: + name = ScriptedPropertyTrigger::luaName; + break; + case ScriptedPropertyColor::luaTag: + name = ScriptedPropertyColor::luaName; + break; + case ScriptedPropertyString::luaTag: + name = ScriptedPropertyString::luaName; + break; + case ScriptedPropertyBoolean::luaTag: + name = ScriptedPropertyBoolean::luaName; + break; + case ScriptedPropertyEnum::luaTag: + name = ScriptedPropertyEnum::luaName; + break; + case ScriptedPropertyList::luaTag: + name = ScriptedPropertyList::luaName; + break; + case ScriptedPropertyImage::luaTag: + name = ScriptedPropertyImage::luaName; + break; + default: + luaL_typeerror(L, 1, name); + break; + } + auto vm = (ScriptedProperty*)lua_touserdata(L, 1); + bool error = false; + int stackChange = property_namecall_atom(L, vm, atom, error); + if (!error) + { + return stackChange; + } + } + luaL_error(L, "%s is not a valid method of %s", str, name); + return 0; +} + +ScriptedPropertyNumber::ScriptedPropertyNumber( + lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +ScriptedPropertyTrigger::ScriptedPropertyTrigger( + lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +void ScriptedPropertyNumber::setValue(float value) +{ + if (m_instanceValue) + { + m_instanceValue->as()->propertyValue(value); + } +} + +int ScriptedPropertyNumber::pushValue() +{ + if (m_instanceValue) + { + lua_pushnumber( + m_state, + m_instanceValue->as()->propertyValue()); + } + else + { + lua_pushnumber(m_state, 0); + } + return 1; +} + +ScriptedPropertyColor::ScriptedPropertyColor( + lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +void ScriptedPropertyColor::setValue(unsigned value) +{ + if (m_instanceValue) + { + m_instanceValue->as()->propertyValue( + (int)value); + } +} + +int ScriptedPropertyColor::pushValue() +{ + if (m_instanceValue) + { + lua_pushunsigned(m_state, + (unsigned)m_instanceValue->as() + ->propertyValue()); + } + else + { + lua_pushunsigned(m_state, 0); + } + return 1; +} + +ScriptedPropertyString::ScriptedPropertyString( + lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +void ScriptedPropertyString::setValue(const std::string& value) +{ + if (m_instanceValue) + { + m_instanceValue->as()->propertyValue(value); + } +} + +int ScriptedPropertyString::pushValue() +{ + if (m_instanceValue) + { + lua_pushstring(m_state, + m_instanceValue->as() + ->propertyValue() + .c_str()); + } + else + { + lua_pushstring(m_state, ""); + } + return 1; +} + +ScriptedPropertyBoolean::ScriptedPropertyBoolean( + lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +void ScriptedPropertyBoolean::setValue(bool value) +{ + if (m_instanceValue) + { + m_instanceValue->as()->propertyValue(value); + } +} + +int ScriptedPropertyBoolean::pushValue() +{ + if (m_instanceValue) + { + lua_pushboolean( + m_state, + m_instanceValue->as()->propertyValue()); + } + else + { + lua_pushboolean(m_state, 0); + } + return 1; +} + +ScriptedPropertyEnum::ScriptedPropertyEnum(lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +void ScriptedPropertyEnum::setValue(const std::string& value) +{ + if (m_instanceValue) + { + m_instanceValue->as()->value(value); + } +} + +int ScriptedPropertyEnum::pushValue() +{ + if (m_instanceValue) + { + auto vmi = m_instanceValue->as(); + auto vmProp = vmi->viewModelProperty()->as(); + if (vmProp != nullptr && vmProp->dataEnum() != nullptr) + { + auto values = vmProp->dataEnum()->values(); + uint32_t index = vmi->propertyValue(); + if (index < values.size()) + { + lua_pushstring(m_state, values[index]->key().c_str()); + return 1; + } + } + } + lua_pushstring(m_state, ""); + return 1; +} + +ScriptedPropertyList::ScriptedPropertyList(lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +ScriptedPropertyList::~ScriptedPropertyList() +{ + for (const auto& pair : m_propertyRefs) + { + lua_unref(m_state, pair.second); + } +} + +void ScriptedPropertyList::valueChanged() +{ + m_changed = true; + ScriptedProperty::valueChanged(); +} + +int ScriptedPropertyList::pushLength() +{ + if (m_instanceValue) + { + lua_pushinteger(m_state, + (int)m_instanceValue->as() + ->listItems() + .size()); + } + else + { + lua_pushinteger(m_state, 0); + } + return 1; +} + +int ScriptedPropertyList::pushValue(int index) +{ + if (m_instanceValue) + { + auto items = m_instanceValue->as()->listItems(); + + if (m_changed) + { + std::unordered_map refs; + + // re-validate references. + for (auto& item : items) + { + auto vmi = item->viewModelInstance().get(); + auto itr = m_propertyRefs.find(vmi); + if (itr != m_propertyRefs.end()) + { + refs[vmi] = itr->second; + m_propertyRefs.erase(itr); + } + } + + for (const auto& pair : m_propertyRefs) + { + lua_unref(m_state, pair.second); + } + m_propertyRefs = refs; + + m_changed = false; + } + + if (index >= items.size()) + { + lua_pushnil(m_state); + } + else + { + + auto listItem = items[index]; + auto vmi = listItem->viewModelInstance(); + auto itr = m_propertyRefs.find(vmi.get()); + if (itr != m_propertyRefs.end()) + { + lua_rawgeti(m_state, LUA_REGISTRYINDEX, itr->second); + } + else + { + lua_newrive(m_state, + m_state, + ref_rcp(vmi->viewModel()), + vmi); + m_propertyRefs[vmi.get()] = lua_ref(m_state, -1); + } + } + } + else + { + lua_pushnil(m_state); + } + return 1; +} + +ScriptedPropertyImage::ScriptedPropertyImage( + lua_State* L, + rcp value) : + ScriptedProperty(L, std::move(value)) +{} + +void ScriptedPropertyImage::setValue(ScriptedImage* scriptedImage) +{ + if (!m_instanceValue) + { + return; + } + m_instanceValue->as()->value( + scriptedImage != nullptr ? scriptedImage->image.get() : nullptr); +} + +int ScriptedPropertyImage::pushValue() +{ + if (m_instanceValue) + { + auto vmi = m_instanceValue->as(); + auto asset = vmi->asset(); + if (asset != nullptr && asset->renderImage() != nullptr) + { + // Use the out-of-line `ScriptedImage::luaNew` factory rather + // than `lua_newrive` directly: when ore is + // enabled, ScriptedImage holds an `rcp` and + // its destructor needs the full TextureView definition (this + // TU only sees the forward decl in `rive_lua_libs.hpp`). The + // factory lives in `lua_gpu.cpp` / `lua_image.cpp` where the + // ore headers are visible. + auto scriptedImage = ScriptedImage::luaNew(m_state); + scriptedImage->image = ref_rcp(asset->renderImage()); + return 1; + } + } + lua_pushnil(m_state); + return 1; +} + +int ScriptedEnumValues::pushValue(int index) +{ + if (m_dataEnum && m_state) + { + auto values = m_dataEnum->values(); + if (index >= 0 && index < values.size()) + { + auto value = values[index]; + lua_pushstring(m_state, value->key().c_str()); + return 1; + } + } + lua_pushnil(m_state); + return 1; +} + +int ScriptedEnumValues::pushLength() +{ + + if (m_dataEnum) + { + lua_pushinteger(m_state, (int)m_dataEnum->values().size()); + } + else + { + lua_pushinteger(m_state, 0); + } + return 1; +} + +static int property_list_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + auto propertyList = lua_torive(L, 1); + // if it's not an atom it should be an index into the array + if (!key) + { + int index = luaL_checkinteger(L, 2); + return propertyList->pushValue(index - 1); + } + + switch (atom) + { + case (int)LuaAtoms::length: + assert(propertyList->state() == L); + return propertyList->pushLength(); + default: + return 0; + } +} + +static int enum_value_length(lua_State* L) +{ + auto enumValues = lua_torive(L, 1); + assert(enumValues->state() == L); + return enumValues->pushLength(); +} + +static int enum_value_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + auto enumValues = lua_torive(L, 1); + // if it's not an atom it should be an index into the array + if (!key) + { + int index = luaL_checkinteger(L, 2); + return enumValues->pushValue(index - 1); + } + return 0; +} + +static int property_number_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyNumber = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + assert(propertyNumber->state() == L); + return propertyNumber->pushValue(); + default: + return 0; + } +} + +static int property_color_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyColor = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + assert(propertyColor->state() == L); + return propertyColor->pushValue(); + default: + return 0; + } +} + +static int property_number_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyNumber = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + propertyNumber->setValue(float(luaL_checknumber(L, 3))); + default: + return 0; + } + + return 0; +} + +static int property_color_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyColor = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + propertyColor->setValue(luaL_checkunsigned(L, 3)); + default: + return 0; + } + + return 0; +} + +static int property_string_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyString = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + assert(propertyString->state() == L); + return propertyString->pushValue(); + default: + return 0; + } +} + +static int property_string_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyString = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + propertyString->setValue(luaL_checkstring(L, 3)); + default: + return 0; + } + + return 0; +} + +static int property_boolean_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyBoolean = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + assert(propertyBoolean->state() == L); + return propertyBoolean->pushValue(); + default: + return 0; + } +} + +static int property_boolean_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyBoolean = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + propertyBoolean->setValue(luaL_checkboolean(L, 3)); + default: + return 0; + } + + return 0; +} + +static int property_enum_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyEnum = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + assert(propertyEnum->state() == L); + return propertyEnum->pushValue(); + default: + return 0; + } +} + +static int property_enum_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyEnum = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + { + propertyEnum->setValue(luaL_checkstring(L, 3)); + } + default: + return 0; + } + + return 0; +} + +static int property_image_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyImage = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + assert(propertyImage->state() == L); + return propertyImage->pushValue(); + default: + return 0; + } +} + +static int property_image_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto propertyImage = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::value: + { + auto image = lua_torive(L, 3); + propertyImage->setValue(image); + break; + } + default: + return 0; + } + + return 0; +} + +static int vm_eq(lua_State* L) +{ + auto lhs = lua_torive(L, 1); + auto rhs = lua_torive(L, 2); + lua_pushboolean(L, lhs->viewModelInstance() == rhs->viewModelInstance()); + return 1; +} + +int luaopen_rive_properties(lua_State* L) +{ + { + lua_register_rive(L); + + lua_pushcfunction(L, vm_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, vm_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_pushcfunction(L, vm_eq, nullptr); + lua_setfield(L, -2, "__eq"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_vm_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_vm_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, property_vm_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_number_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_number_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_color_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_color_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_string_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_string_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_boolean_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_boolean_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_enum_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_enum_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_pushcfunction(L, property_list_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, property_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_pushcfunction(L, property_image_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, property_image_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + { + lua_register_rive(L); + + lua_pushcfunction(L, enum_value_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, enum_value_length, nullptr); + lua_setfield(L, -2, "__len"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + return 0; +} +#endif diff --git a/thirdparty/rive/source/lua/lua_rive_base.cpp b/thirdparty/rive/source/lua/lua_rive_base.cpp new file mode 100644 index 000000000..fc6fabedf --- /dev/null +++ b/thirdparty/rive/source/lua/lua_rive_base.cpp @@ -0,0 +1,45 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/span.hpp" + +using namespace rive; +static int luaB_print(lua_State* L) +{ + int n = lua_gettop(L); // number of arguments + if (n == 0) + { + return 0; + } + + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + + context->printBeginLine(L); + for (int i = 1; i <= n; i++) + { + size_t l; + const char* s = + luaL_tolstring(L, + i, + &l); // convert to string using __tostring et al + context->print(Span(s, l)); + lua_pop(L, 1); // pop result + } + context->printEndLine(); + return 0; +} + +static const luaL_Reg base_funcs[] = { + {"print", luaB_print}, + {NULL, NULL}, +}; + +int luaopen_rive_base(lua_State* L) +{ + // open lib into global table + luaL_register(L, "_G", base_funcs); + + return 1; +} + +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/lua/lua_scripted_context.cpp b/thirdparty/rive/source/lua/lua_scripted_context.cpp new file mode 100644 index 000000000..40b55ff5b --- /dev/null +++ b/thirdparty/rive/source/lua/lua_scripted_context.cpp @@ -0,0 +1,639 @@ +#ifdef WITH_RIVE_SCRIPTING +#include +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/assets/image_asset.hpp" +#include "rive/assets/blob_asset.hpp" +#include "rive/file.hpp" +#ifdef WITH_RIVE_AUDIO +#include "rive/audio/audio_engine.hpp" +#include "rive/assets/audio_asset.hpp" +#endif +#ifdef RIVE_CANVAS +#include "rive/renderer/render_context.hpp" +#include "rive/renderer/render_canvas.hpp" +#ifdef RIVE_ORE +#include "rive/renderer/ore/ore_context.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/assets/shader_asset.hpp" +#endif +#endif + +#include +#include +#include + +using namespace rive; + +// Pushes a GPU features table onto the Lua stack. Queries the ORE context +// when available, otherwise returns conservative defaults. Always returns 1. +int lua_push_gpu_features(lua_State* L) +{ +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) + auto* oreCtx = static_cast( + static_cast(lua_getthreaddata(L))->oreContext()); + if (oreCtx != nullptr) + { + const auto& f = oreCtx->features(); + lua_createtable(L, 0, 18); + lua_pushboolean(L, f.bc); + lua_setfield(L, -2, "bc"); + lua_pushboolean(L, f.etc2); + lua_setfield(L, -2, "etc2"); + lua_pushboolean(L, f.astc); + lua_setfield(L, -2, "astc"); + lua_pushnumber(L, f.maxTextureSize2D); + lua_setfield(L, -2, "maxTextureSize2D"); + lua_pushnumber(L, f.maxTextureSizeCube); + lua_setfield(L, -2, "maxTextureSizeCube"); + lua_pushnumber(L, f.maxTextureSize3D); + lua_setfield(L, -2, "maxTextureSize3D"); + lua_pushboolean(L, f.anisotropicFiltering); + lua_setfield(L, -2, "anisotropicFiltering"); + lua_pushboolean(L, f.texture3D); + lua_setfield(L, -2, "texture3D"); + lua_pushboolean(L, f.textureArrays); + lua_setfield(L, -2, "textureArrays"); + lua_pushboolean(L, f.colorBufferFloat); + lua_setfield(L, -2, "colorBufferFloat"); + lua_pushboolean(L, f.perTargetBlend); + lua_setfield(L, -2, "perTargetBlend"); + lua_pushboolean(L, f.perTargetWriteMask); + lua_setfield(L, -2, "perTargetWriteMask"); + lua_pushboolean(L, f.drawBaseInstance); + lua_setfield(L, -2, "drawBaseInstance"); + lua_pushboolean(L, f.depthBiasClamp); + lua_setfield(L, -2, "depthBiasClamp"); + lua_pushnumber(L, f.maxColorAttachments); + lua_setfield(L, -2, "maxColorAttachments"); + lua_pushnumber(L, f.maxUniformBufferSize); + lua_setfield(L, -2, "maxUniformBufferSize"); + lua_pushnumber(L, f.maxSamplers); + lua_setfield(L, -2, "maxSamplers"); + lua_pushnumber(L, f.maxSamples); + lua_setfield(L, -2, "maxSamples"); + lua_setreadonly(L, -1, true); + return 1; + } +#endif + // Fallback when no ore context is available + lua_createtable(L, 0, 18); + lua_pushboolean(L, false); + lua_setfield(L, -2, "bc"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "etc2"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "astc"); + lua_pushnumber(L, 4096); + lua_setfield(L, -2, "maxTextureSize2D"); + lua_pushnumber(L, 4096); + lua_setfield(L, -2, "maxTextureSizeCube"); + lua_pushnumber(L, 256); + lua_setfield(L, -2, "maxTextureSize3D"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "anisotropicFiltering"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "texture3D"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "textureArrays"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "colorBufferFloat"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "perTargetBlend"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "perTargetWriteMask"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "drawBaseInstance"); + lua_pushboolean(L, false); + lua_setfield(L, -2, "depthBiasClamp"); + lua_pushnumber(L, 4); + lua_setfield(L, -2, "maxColorAttachments"); + lua_pushnumber(L, 16384); + lua_setfield(L, -2, "maxUniformBufferSize"); + lua_pushnumber(L, 16); + lua_setfield(L, -2, "maxSamplers"); + lua_pushnumber(L, 4); + lua_setfield(L, -2, "maxSamples"); + lua_setreadonly(L, -1, true); + return 1; +} + +// Push the platform's preferred canvas color format onto the Lua stack as a +// string. makeRenderCanvas() hardcodes RGBA8 on Metal so that Rive's internal +// PLS shaders (which work in RGBA space) can render into the canvas without +// format-dependent swizzling. +// Metal (macOS/iOS) → rgba8unorm (off-screen canvas, not a CAMetalLayer +// surface) +// D3D11/D3D12 → bgra8unorm +// Vulkan/GL/WebGPU → rgba8unorm (safe default; actual format may vary — +// query canvas.format for the authoritative value once +// a canvas has been created) +int lua_push_preferred_canvas_format(lua_State* L) +{ +#if defined(_WIN32) + lua_pushstring(L, "bgra8unorm"); +#else + lua_pushstring(L, "rgba8unorm"); +#endif + return 1; +} + +ScriptedContext::ScriptedContext(ScriptedObject* scriptedObject) : + m_scriptedObject(scriptedObject) +{} + +int ScriptedContext::pushViewModel(lua_State* state) +{ + if (m_scriptedObject) + { + auto dataContext = m_scriptedObject->dataContext(); + if (dataContext && dataContext->viewModelInstance()) + { + auto viewModelInstance = dataContext->viewModelInstance(); + lua_newrive( + state, + state, + ref_rcp(viewModelInstance->viewModel()), + viewModelInstance); + return 1; + } + } + m_missingRequestedData = true; + return 0; +} + +int ScriptedContext::pushRootViewModel(lua_State* state) +{ + if (m_scriptedObject) + { + auto dataContext = m_scriptedObject->dataContext(); + if (dataContext) + { + auto viewModelInstance = dataContext->rootViewModelInstance(); + if (viewModelInstance) + { + lua_newrive( + state, + state, + ref_rcp(viewModelInstance->viewModel()), + viewModelInstance); + return 1; + } + } + } + m_missingRequestedData = true; + return 0; +} + +int ScriptedContext::pushDataContext(lua_State* state) +{ + + if (m_scriptedObject) + { + auto dataContext = m_scriptedObject->dataContext(); + if (dataContext) + { + lua_newrive(state, state, dataContext); + return 1; + } + } + m_missingRequestedData = true; + return 0; +} + +static int context_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + auto scriptedContext = lua_torive(L, 1); + if (scriptedContext->scriptedObject() == nullptr) + { + luaL_error(L, + "context:%s() called on a disposed context — the " + "context passed to init() must not be used after " + "init() returns", + str); + return 0; + } + switch (atom) + { + case (int)LuaAtoms::markNeedsUpdate: + { + auto scriptedObject = scriptedContext->scriptedObject(); + scriptedObject->markNeedsUpdate(); + return 0; + } + case (int)LuaAtoms::viewModel: + { + return scriptedContext->pushViewModel(L); + } + case (int)LuaAtoms::rootViewModel: + { + return scriptedContext->pushRootViewModel(L); + } + case (int)LuaAtoms::image: + { + const char* imageName = luaL_checkstring(L, 2); + + // First, try to find the image from the file's assets (runtime) + auto scriptedObject = scriptedContext->scriptedObject(); + auto scriptAsset = scriptedObject->scriptAsset(); + if (scriptAsset != nullptr) + { + File* file = scriptAsset->file(); + if (file != nullptr) + { + // Find ImageAsset by name + auto assets = file->assets(); + for (const auto& asset : assets) + { + if (asset->is()) + { + ImageAsset* imageAsset = + asset->as(); + if (imageAsset->name() == imageName) + { + RenderImage* renderImage = + imageAsset->renderImage(); + if (renderImage != nullptr) + { + auto scriptedImage = + lua_newrive(L); + // ref_rcp properly refs the RenderImage + // for the rcp<>. When ScriptedImage is + // GC'd, rcp<> destructor will deref() + scriptedImage->image = + ref_rcp(renderImage); + return 1; + } + } + } + } + } + } + + return 0; // return nil if not found + } + case (int)LuaAtoms::blob: + { + const char* blobName = luaL_checkstring(L, 2); + + auto scriptedObject = scriptedContext->scriptedObject(); + auto scriptAsset = scriptedObject->scriptAsset(); + if (scriptAsset != nullptr) + { + File* file = scriptAsset->file(); + if (file != nullptr) + { + auto assets = file->assets(); + for (const auto& asset : assets) + { + if (asset->is()) + { + BlobAsset* blobAsset = asset->as(); + if (blobAsset->name() == blobName) + { + auto bytes = blobAsset->bytes(); + if (!bytes.empty()) + { + auto scriptedBlob = + lua_newrive(L); + scriptedBlob->asset = ref_rcp( + static_cast(blobAsset)); + return 1; + } + } + } + } + } + } + + return 0; // return nil if not found + } + case (int)LuaAtoms::dataContext: + { + return scriptedContext->pushDataContext(L); + } +#ifdef WITH_RIVE_AUDIO + case (int)LuaAtoms::audio: + { + const char* audioName = luaL_checkstring(L, 2); + + auto scriptedObject = scriptedContext->scriptedObject(); + auto scriptAsset = scriptedObject->scriptAsset(); + if (scriptAsset != nullptr) + { + File* file = scriptAsset->file(); + if (file != nullptr) + { + auto assets = file->assets(); + for (const auto& asset : assets) + { + if (asset->is()) + { + AudioAsset* audioAsset = + asset->as(); + if (audioAsset->name() == audioName) + { + auto audioSource = + audioAsset->audioSource(); + if (audioSource != nullptr) + { + auto scriptedAudioSource = + lua_newrive(L); + scriptedAudioSource->source( + audioSource); + return 1; + } + } + } + } + } + } + + return 0; // return nil if not found + } +#endif + + case (int)LuaAtoms::canvas: + { + // context:canvas({ width = w, height = h, clearColor = c }) + luaL_checktype(L, 2, LUA_TTABLE); + lua_getfield(L, 2, "width"); + uint32_t cw = (uint32_t)luaL_checknumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, 2, "height"); + uint32_t ch = (uint32_t)luaL_checknumber(L, -1); + lua_pop(L, 1); +#ifndef RIVE_CANVAS + (void)cw; + (void)ch; + luaL_error(L, "context:canvas() requires a RIVE_CANVAS build"); + return 0; +#else + auto* scriptingCtx = + static_cast(lua_getthreaddata(L)); + auto* renderCtx = static_cast( + scriptingCtx->renderContext()); + if (renderCtx == nullptr) + { + luaL_error( + L, + "context:canvas() requires a RenderContext — call " + "setRenderContext() first"); + return 0; + } + auto canvas = renderCtx->makeRenderCanvas(cw, ch); + if (!canvas) + { + luaL_error( + L, + "context:canvas() failed to create RenderCanvas"); + return 0; + } + auto* handle = lua_newrive(L); + handle->m_L = L; + handle->canvas = std::move(canvas); + handle->renderCtx = renderCtx; + // Create a ScriptedImage backed by canvas->renderImage() so + // the script can composite it with renderer:drawImage() + auto* img = lua_newrive(L); + img->image = ref_rcp( + static_cast(handle->canvas->renderImage())); + handle->m_imageRef = lua_ref(L, -1); + lua_pop(L, 1); // pop image, handle remains on top + return 1; +#endif + } + case (int)LuaAtoms::gpuCanvas: + { + // context:gpuCanvas({ width = w, height = h }) + luaL_checktype(L, 2, LUA_TTABLE); + lua_getfield(L, 2, "width"); + uint32_t gw = (uint32_t)luaL_checknumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, 2, "height"); + uint32_t gh = (uint32_t)luaL_checknumber(L, -1); + lua_pop(L, 1); +#if !defined(RIVE_CANVAS) || !defined(RIVE_ORE) + (void)gw; + (void)gh; + luaL_error(L, + "context:gpuCanvas() requires a RIVE_CANVAS + " + "RIVE_ORE build"); + return 0; +#else + auto* gpuScriptingCtx = + static_cast(lua_getthreaddata(L)); + auto* gpuRenderCtx = static_cast( + gpuScriptingCtx->renderContext()); + if (gpuRenderCtx == nullptr) + { + luaL_error( + L, + "context:gpuCanvas() requires a RenderContext — call " + "setRenderContext() first"); + return 0; + } + auto* oreCtx = + static_cast(gpuScriptingCtx->oreContext()); + if (oreCtx == nullptr) + { + luaL_error( + L, + "context:gpuCanvas() requires a GPU context — call " + "scriptingWorkspaceSetOreContext() before requestVM()"); + return 0; + } + auto canvas = gpuRenderCtx->makeRenderCanvas(gw, gh); + if (!canvas) + { + luaL_error( + L, + "context:gpuCanvas() failed to create RenderCanvas"); + return 0; + } + auto colorView = oreCtx->wrapCanvasTexture(canvas.get()); + if (!colorView) + { + luaL_error( + L, + "context:gpuCanvas() failed to wrap canvas texture"); + return 0; + } + auto* handle = lua_newrive(L); + handle->m_L = L; + handle->canvas = std::move(canvas); + handle->oreColorView = std::move(colorView); + handle->renderCtx = gpuRenderCtx; + + // Optional MSAA: context:gpuCanvas({ ..., sampleCount = 4 }) + lua_getfield(L, 2, "sampleCount"); + uint32_t gpuCanvasSamples = + lua_isnumber(L, -1) + ? static_cast(lua_tonumber(L, -1)) + : 1; + lua_pop(L, 1); + if (gpuCanvasSamples > 1) + { + if ((gpuCanvasSamples & (gpuCanvasSamples - 1)) != 0) + luaL_error(L, + "gpuCanvas sampleCount must be a power of " + "two (got %u)", + gpuCanvasSamples); + uint32_t maxSamples = oreCtx->features().maxSamples; + if (gpuCanvasSamples > maxSamples) + luaL_error(L, + "gpuCanvas sampleCount %u exceeds device " + "maximum of %u — query " + "context:features().maxSamples first", + gpuCanvasSamples, + maxSamples); + } + if (gpuCanvasSamples > 1) + { + ore::TextureDesc msaaDesc; + msaaDesc.width = gw; + msaaDesc.height = gh; + msaaDesc.format = handle->oreColorView->texture()->format(); + msaaDesc.renderTarget = true; + msaaDesc.sampleCount = gpuCanvasSamples; + msaaDesc.label = "GPUCanvasMSAAColor"; + handle->oreMSAAColorTexture = oreCtx->makeTexture(msaaDesc); + if (!handle->oreMSAAColorTexture) + { + luaL_error( + L, + "context:gpuCanvas() failed to create MSAA color " + "texture (sampleCount=%u)", + gpuCanvasSamples); + return 0; + } + ore::TextureViewDesc msaaViewDesc; + msaaViewDesc.texture = handle->oreMSAAColorTexture.get(); + handle->oreMSAAColorView = + oreCtx->makeTextureView(msaaViewDesc); + + // Depth buffer — sampleCount must match the MSAA color + // attachment or Metal/Vulkan will reject the render pass. + ore::TextureDesc depthDesc; + depthDesc.width = gw; + depthDesc.height = gh; + depthDesc.format = ore::TextureFormat::depth32float; + depthDesc.renderTarget = true; + depthDesc.sampleCount = gpuCanvasSamples; + depthDesc.label = "GPUCanvasMSAADepth"; + handle->oreDepthTexture = oreCtx->makeTexture(depthDesc); + if (!handle->oreDepthTexture) + { + luaL_error( + L, + "context:gpuCanvas() failed to create MSAA depth " + "texture (sampleCount=%u)", + gpuCanvasSamples); + return 0; + } + ore::TextureViewDesc depthViewDesc; + depthViewDesc.texture = handle->oreDepthTexture.get(); + handle->oreDepthView = + oreCtx->makeTextureView(depthViewDesc); + } + // Create a ScriptedImage backed by canvas->renderImage() so + // the script can composite it with renderer:drawImage() + auto* img = lua_newrive(L); + img->image = ref_rcp( + static_cast(handle->canvas->renderImage())); + handle->m_imageRef = lua_ref(L, -1); + lua_pop(L, 1); // pop image, handle remains on top + return 1; +#endif + } + case (int)LuaAtoms::features: + return lua_push_gpu_features(L); + + case (int)LuaAtoms::preferredCanvasFormat: + return lua_push_preferred_canvas_format(L); + + case (int)LuaAtoms::loadShader: + { +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) + const char* shaderName = luaL_checkstring(L, 2); + + // Runtime path: search file->assets() for a ShaderAsset + // with the matching name. + ShaderAsset* fileAsset = nullptr; + auto scriptedObject = scriptedContext->scriptedObject(); + auto scriptAsset = scriptedObject->scriptAsset(); + if (scriptAsset != nullptr) + { + File* file = scriptAsset->file(); + if (file != nullptr) + { + for (const auto& asset : file->assets()) + { + if (asset->is()) + { + auto* sa = asset->as(); + if (sa->name() == shaderName) + { + fileAsset = sa; + break; + } + } + } + } + } + + auto* scriptingCtx = + static_cast(lua_getthreaddata(L)); + auto* scripted = lua_newrive(L); + if (lua_gpu_load_shader_by_name(scripted, + scriptingCtx, + shaderName, + fileAsset)) + { + return 1; + } + lua_pop(L, 1); + return 0; // return nil, shader not found or compile failed +#else + return 0; +#endif + } + + case (int)LuaAtoms::decodeImage: + { + // Defined in lua_image_decode.cpp. + extern int context_decodeImage_impl(lua_State * L); + return context_decodeImage_impl(L); + } + + default: + break; + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedContext::luaName); + return 0; +} + +int luaopen_rive_contex(lua_State* L) +{ + { + lua_register_rive(L); + + lua_pushcfunction(L, context_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + return 0; +} + +#endif diff --git a/thirdparty/rive/source/lua/lua_scripted_context_apple.mm b/thirdparty/rive/source/lua/lua_scripted_context_apple.mm new file mode 100644 index 000000000..817e0bac0 --- /dev/null +++ b/thirdparty/rive/source/lua/lua_scripted_context_apple.mm @@ -0,0 +1,4 @@ +// On Apple platforms, ore_context.hpp imports (via the +// globally-defined ORE_BACKEND_METAL), which is only valid in ObjC++ files. +// This wrapper compiles lua_scripted_context.cpp as ObjC++ on macOS/iOS. +#include "lua_scripted_context.cpp" diff --git a/thirdparty/rive/source/lua/lua_state.cpp b/thirdparty/rive/source/lua/lua_state.cpp new file mode 100644 index 000000000..69725511d --- /dev/null +++ b/thirdparty/rive/source/lua/lua_state.cpp @@ -0,0 +1,105 @@ + +#include "rive/lua/lua_state.hpp" +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/viewmodel/viewmodel.hpp" +#include +using namespace rive; + +#ifdef WITH_RIVE_SCRIPTING +static int viewmodel_new(lua_State* L) +{ + // Get the viewModel pointer from the upvalue + ViewModel* viewModel = (ViewModel*)lua_touserdata(L, lua_upvalueindex(1)); + if (viewModel) + { + int nargs = lua_gettop(L); + if (nargs == 1) + { + // If the argument is nil, treat it as "no template instance" + if (lua_isnil(L, -1)) + { + auto instance = viewModel->createInstance(); + lua_newrive(L, + L, + ref_rcp(viewModel), + instance); + } + // If the argument is a string, use it as the template instance name + else if (lua_isstring(L, -1)) + { + const char* instanceName = lua_tostring(L, -1); + auto instance = viewModel->createFromInstance(instanceName); + if (instance) + { + lua_newrive(L, + L, + ref_rcp(viewModel), + instance); + } + else + { + auto instance = viewModel->createInstance(); + lua_newrive(L, + L, + ref_rcp(viewModel), + instance); + } + } + else + { + lua_pushnil(L); + } + } + else + { + auto instance = viewModel->createInstance(); + lua_newrive(L, L, ref_rcp(viewModel), instance); + } + return 1; + } + lua_pushnil(L); + return 1; +} + +void rive::initializeLuaData(lua_State* state, + std::vector& viewModels) +{ + if (state) + { + // create metatable for global Data + luaL_newmetatable(state, "Data"); + + lua_pop(state, 1); + lua_getfield(state, luaRegistryIndex, "Data"); + lua_setglobal(state, "Data"); + + // Get the Data metatable back on the stack + lua_getfield(state, luaRegistryIndex, "Data"); + + for (auto& viewModel : viewModels) + { + // Create a new table for this viewModel + lua_createtable(state, 0, 1); + + // Push the viewModel pointer as a light userdata (upvalue) + lua_pushlightuserdata(state, viewModel); + + // Create a closure with the viewModel as an upvalue + lua_pushcclosurek(state, viewmodel_new, "new", 1, nullptr); + + // Set the function as "new" in the table + lua_setfield(state, -2, "new"); + + // Set the table as a field in Data metatable using the viewModel + // name + lua_setfield(state, -2, viewModel->name().c_str()); + } + + // Pop the Data metatable from the stack + lua_pop(state, 1); + } +} + +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/lua/math/lua_color.cpp b/thirdparty/rive/source/lua/math/lua_color.cpp new file mode 100644 index 000000000..dd30dd0b5 --- /dev/null +++ b/thirdparty/rive/source/lua/math/lua_color.cpp @@ -0,0 +1,173 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lua.h" +#include "rive/lua/rive_lua_libs.hpp" +#include "lualib.h" +#include "rive/shapes/paint/color.hpp" + +using namespace rive; + +static int color_rgb(lua_State* L) +{ + uint32_t r = luaL_checkunsigned(L, 1); + uint32_t g = luaL_checkunsigned(L, 2); + uint32_t b = luaL_checkunsigned(L, 3); + uint32_t a = 255; + lua_pushunsigned(L, colorARGB(a, r, g, b)); + + return 1; +} + +static int color_rgba(lua_State* L) +{ + uint32_t r = luaL_checkunsigned(L, 1); + uint32_t g = luaL_checkunsigned(L, 2); + uint32_t b = luaL_checkunsigned(L, 3); + uint32_t a = luaL_checkunsigned(L, 4); + lua_pushunsigned(L, colorARGB(a, r, g, b)); + + return 1; +} + +static int color_red(lua_State* L) +{ + uint32_t color = luaL_checkunsigned(L, 1); + int isnum; + uint32_t red = lua_tounsignedx(L, 2, &isnum); + if (isnum == 1) + { + lua_pushunsigned(L, + colorARGB(colorAlpha(color), + red, + colorGreen(color), + colorBlue(color))); + } + else + { + lua_pushunsigned(L, colorRed(color)); + } + return 1; +} + +static int color_green(lua_State* L) +{ + uint32_t color = luaL_checkunsigned(L, 1); + int isnum; + uint32_t green = lua_tounsignedx(L, 2, &isnum); + if (isnum == 1) + { + lua_pushunsigned(L, + colorARGB(colorAlpha(color), + colorRed(color), + green, + colorBlue(color))); + } + else + { + lua_pushunsigned(L, colorGreen(color)); + } + return 1; +} + +static int color_blue(lua_State* L) +{ + uint32_t color = luaL_checkunsigned(L, 1); + int isnum; + uint32_t blue = lua_tounsignedx(L, 2, &isnum); + if (isnum == 1) + { + lua_pushunsigned(L, + colorARGB(colorAlpha(color), + colorRed(color), + colorGreen(color), + blue)); + } + else + { + lua_pushunsigned(L, colorBlue(color)); + } + return 1; +} + +static int color_alpha(lua_State* L) +{ + uint32_t color = luaL_checkunsigned(L, 1); + int isnum; + uint32_t alpha = lua_tounsignedx(L, 2, &isnum); + if (isnum == 1) + { + lua_pushunsigned(L, + colorARGB(alpha, + colorRed(color), + colorGreen(color), + colorBlue(color))); + } + else + { + lua_pushunsigned(L, colorAlpha(color)); + } + return 1; +} + +static int color_opacity(lua_State* L) +{ + uint32_t color = luaL_checkunsigned(L, 1); + int isnum; + float opacity = float(lua_tonumberx(L, 2, &isnum)); + if (isnum == 1) + { + lua_pushunsigned(L, + colorARGB(opacityToAlpha(opacity), + colorRed(color), + colorGreen(color), + colorBlue(color))); + } + else + { + lua_pushnumber(L, colorOpacity(color)); + } + return 1; +} + +static int color_lerp(lua_State* L) +{ + uint32_t from = luaL_checkunsigned(L, 1); + uint32_t to = luaL_checkunsigned(L, 2); + float f = float(luaL_checknumber(L, 3)); + lua_pushnumber(L, colorLerp(from, to, f)); + return 1; +} + +static int color_toFloat(lua_State* L) +{ + uint32_t color = luaL_checkunsigned(L, 1); + lua_createtable(L, 4, 0); + lua_pushnumber(L, colorRed(color) / 255.0); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, colorGreen(color) / 255.0); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, colorBlue(color) / 255.0); + lua_rawseti(L, -2, 3); + lua_pushnumber(L, colorAlpha(color) / 255.0); + lua_rawseti(L, -2, 4); + return 1; +} + +static const luaL_Reg colorStaticMethods[] = {{"red", color_red}, + {"green", color_green}, + {"blue", color_blue}, + {"alpha", color_alpha}, + {"opacity", color_opacity}, + {"lerp", color_lerp}, + {"rgb", color_rgb}, + {"rgba", color_rgba}, + {"toFloat", color_toFloat}, + {nullptr, nullptr}}; + +int luaopen_rive_color(lua_State* L) +{ + luaL_register(L, "Color", colorStaticMethods); + + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/math/lua_input.cpp b/thirdparty/rive/source/lua/math/lua_input.cpp new file mode 100644 index 000000000..8fb661310 --- /dev/null +++ b/thirdparty/rive/source/lua/math/lua_input.cpp @@ -0,0 +1,146 @@ + +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "lualib.h" + +using namespace rive; + +static const char* hit_listener_type_string(int raw) +{ + switch (static_cast(raw)) + { + case ListenerType::enter: + return "pointerEnter"; + case ListenerType::exit: + return "pointerExit"; + case ListenerType::down: + return "pointerDown"; + case ListenerType::up: + return "pointerUp"; + case ListenerType::move: + return "pointerMove"; + case ListenerType::click: + return "click"; + case ListenerType::drag: + return "pointerDrag"; + default: + return "unknown"; + } + return "unknown"; +} + +static int pointer_event_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto pointerEvent = lua_torive(L, 1); + switch (atom) + { + case (int)LuaAtoms::id: + lua_pushunsigned(L, (unsigned)pointerEvent->m_id); + return 1; + case (int)LuaAtoms::position: + lua_pushvector2(L, + pointerEvent->m_position.x, + pointerEvent->m_position.y); + return 1; + case (int)LuaAtoms::previousPosition: + lua_pushvector2(L, + pointerEvent->m_previousPosition.x, + pointerEvent->m_previousPosition.y); + return 1; + case (int)LuaAtoms::type: + lua_pushstring( + L, + hit_listener_type_string(pointerEvent->m_hitListenerType)); + return 1; + case (int)LuaAtoms::timeStamp: + lua_pushnumber(L, pointerEvent->m_timeStamp); + return 1; + } + + luaL_error(L, + "%s is not a valid field of %s", + luaL_checkstring(L, 1), + ScriptedPointerEvent::luaName); + return 0; +} + +static int pointer_event_hit(lua_State* L) +{ + auto pointerEvent = lua_torive(L, 1); + if (lua_isboolean(L, 2)) + { + pointerEvent->m_hitResult = + lua_toboolean(L, 2) ? HitResult::hit : HitResult::hitOpaque; + } + else + { + pointerEvent->m_hitResult = HitResult::hitOpaque; + } + return 0; +} + +static int pointer_event_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::hit: + return pointer_event_hit(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + luaL_checkstring(L, 1), + ScriptedPointerEvent::luaName); + return 0; +} + +static int pointer_event_new(lua_State* L) +{ + + int id = luaL_checkinteger(L, 1); + auto vec = lua_checkvec2d(L, 2); + lua_newrive(L, id, Vec2D(vec->x, vec->y)); + return 1; +} + +static const luaL_Reg pointerEventsStaticMethods[] = { + {"new", pointer_event_new}, + {nullptr, nullptr}}; + +int luaopen_rive_input(lua_State* L) +{ + { + luaL_register(L, + ScriptedPointerEvent::luaName, + pointerEventsStaticMethods); + } + { + lua_register_rive(L); + lua_pushcfunction(L, pointer_event_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, pointer_event_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + rive_lua_register_listener_invocation_types(L); + + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/math/lua_mat2d.cpp b/thirdparty/rive/source/lua/math/lua_mat2d.cpp new file mode 100644 index 000000000..2fe4d62fc --- /dev/null +++ b/thirdparty/rive/source/lua/math/lua_mat2d.cpp @@ -0,0 +1,390 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/math/mat2d.hpp" +#include "rive/lua/rive_lua_libs.hpp" + +using namespace rive; + +static ScriptedMat2D* lua_pushmat2d(lua_State* L, + float x1, + float y1, + float x2, + float y2, + float tx, + float ty) +{ + return lua_newrive(L, x1, y1, x2, y2, tx, ty); +} + +static ScriptedMat2D* lua_pushmat2d(lua_State* L, const Mat2D& mat) +{ + return lua_newrive(L, mat); +} + +static int mat2d_values(lua_State* L) +{ + float m[6] = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}; + for (int i = 0; i < 6; i++) + { + m[i] = float(luaL_checknumber(L, 1 + i)); + } + + lua_pushmat2d(L, m[0], m[1], m[2], m[3], m[4], m[5]); + return 1; +} + +static int mat2d_identity(lua_State* L) +{ + lua_pushmat2d(L, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); + return 1; +} + +static int mat2d_withTranslation(lua_State* L) +{ + auto vec = lua_tovec2d(L, 1); + if (vec != nullptr) + { + lua_pushmat2d(L, Mat2D::fromTranslation(*vec)); + return 1; + } + + float x = float(luaL_checknumber(L, 1)); + float y = float(luaL_checknumber(L, 2)); + + lua_pushmat2d(L, Mat2D::fromTranslation(Vec2D(x, y))); + + return 1; +} + +static int mat2d_withRotation(lua_State* L) +{ + float radians = float(luaL_checknumber(L, 1)); + + lua_pushmat2d(L, Mat2D::fromRotation(radians)); + + return 1; +} + +static int mat2d_withScale(lua_State* L) +{ + auto scale = lua_tovec2d(L, 1); + if (scale != nullptr) + { + lua_pushmat2d(L, Mat2D::fromScale(scale->x, scale->y)); + return 1; + } + float scaleX = float(luaL_checknumber(L, 1)); + float scaleY = lua_isnumber(L, 2) ? float(luaL_checknumber(L, 2)) : scaleX; + + lua_pushmat2d(L, Mat2D::fromScale(scaleX, scaleY)); + + return 1; +} + +static int mat2d_withScaleAndTranslation(lua_State* L) +{ + auto scale = lua_tovec2d(L, 1); + if (scale != nullptr) + { + auto translation = lua_checkvec2d(L, 2); + lua_pushmat2d(L, + Mat2D::fromScaleAndTranslation(scale->x, + scale->y, + translation->x, + translation->y)); + return 1; + } + float scaleX = float(luaL_checknumber(L, 1)); + float scaleY = float(luaL_checknumber(L, 2)); + float translationX = float(luaL_checknumber(L, 3)); + float translationY = float(luaL_checknumber(L, 4)); + + lua_pushmat2d(L, + Mat2D::fromScaleAndTranslation(scaleX, + scaleY, + translationX, + translationY)); + + return 1; +} + +static int mat2d_newindex(lua_State* L) +{ + auto mat = lua_torive(L, 1); + + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + switch (namelen) + { + case 2: + switch (name[0]) + { + case 'x': + switch (name[1]) + { + case 'x': + mat->value.xx(luaL_checknumber(L, 3)); + return 0; + case 'y': + mat->value.xy(luaL_checknumber(L, 3)); + return 0; + } + break; + case 'y': + switch (name[1]) + { + case 'x': + mat->value.yx(luaL_checknumber(L, 3)); + return 0; + case 'y': + mat->value.yy(luaL_checknumber(L, 3)); + return 0; + } + break; + case 't': + switch (name[1]) + { + case 'x': + mat->value.tx(luaL_checknumber(L, 3)); + return 0; + case 'y': + mat->value.ty(luaL_checknumber(L, 3)); + return 0; + } + return 1; + default: + break; + } + break; + case 1: + switch (name[0]) + { + case '1': + mat->value.xx(luaL_checknumber(L, 3)); + return 0; + case '2': + mat->value.xy(luaL_checknumber(L, 3)); + return 0; + case '3': + mat->value.yx(luaL_checknumber(L, 3)); + return 0; + case '4': + mat->value.yy(luaL_checknumber(L, 3)); + return 0; + case '5': + mat->value.tx(luaL_checknumber(L, 3)); + return 0; + case '6': + mat->value.ty(luaL_checknumber(L, 3)); + return 0; + default: + break; + } + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + name, + ScriptedMat2D::luaName); + return 0; +} + +static int mat2d_index(lua_State* L) +{ + auto mat = lua_torive(L, 1); + + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + switch (namelen) + { + case 2: + switch (name[0]) + { + case 'x': + switch (name[1]) + { + case 'x': + lua_pushnumber(L, mat->value.xx()); + return 1; + case 'y': + lua_pushnumber(L, mat->value.xy()); + return 1; + } + break; + case 'y': + switch (name[1]) + { + case 'x': + lua_pushnumber(L, mat->value.yx()); + return 1; + case 'y': + lua_pushnumber(L, mat->value.yy()); + return 1; + } + break; + case 't': + switch (name[1]) + { + case 'x': + lua_pushnumber(L, mat->value.tx()); + return 1; + case 'y': + lua_pushnumber(L, mat->value.ty()); + return 1; + } + return 1; + default: + break; + } + break; + case 1: + switch (name[0]) + { + case '1': + lua_pushnumber(L, mat->value.xx()); + return 1; + case '2': + lua_pushnumber(L, mat->value.xy()); + return 1; + case '3': + lua_pushnumber(L, mat->value.yx()); + return 1; + case '4': + lua_pushnumber(L, mat->value.yy()); + return 1; + case '5': + lua_pushnumber(L, mat->value.tx()); + return 1; + case '6': + lua_pushnumber(L, mat->value.ty()); + return 1; + default: + break; + } + break; + } + + luaL_error(L, + "'%s' is not a valid index of %s", + name, + ScriptedMat2D::luaName); + return 0; +} + +static int mat2d_mul(lua_State* L) +{ + auto mat2d = lua_torive(L, 1); + auto vec = lua_tovec2d(L, 2); + if (vec != nullptr) + { + lua_pushvec2d(L, mat2d->value * (*vec)); + return 1; + } + auto rhs = lua_torive(L, 2); + + lua_pushmat2d(L, mat2d->value * rhs->value); + return 1; +} + +static int mat2d_invert(lua_State* L) +{ + auto mat2d = lua_torive(L, 1); + Mat2D result; + if (mat2d->value.invert(&result)) + { + lua_pushmat2d(L, result); + return 1; + } + lua_pushnil(L); + return 1; +} + +static int mat2d_isIdentity(lua_State* L) +{ + auto mat2d = lua_torive(L, 1); + lua_pushboolean(L, mat2d->value == Mat2D()); + return 1; +} + +static int mat2d_eq(lua_State* L) +{ + auto lhs = lua_torive(L, 1); + auto rhs = lua_torive(L, 2); + lua_pushboolean(L, lhs->value == rhs->value); + return 1; +} + +static int mat2d_namecall(lua_State* L) +{ + int atom; + if (lua_namecallatom(L, &atom)) + { + switch (atom) + { + case (int)LuaAtoms::invert: + return mat2d_invert(L); + case (int)LuaAtoms::isIdentity: + return mat2d_isIdentity(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + luaL_checkstring(L, 1), + ScriptedMat2D::luaName); + return 0; +} + +static int mat2d_static_invert(lua_State* L) +{ + auto out = lua_torive(L, 1); + auto in = lua_torive(L, 2); + + if (in->value.invert(&out->value)) + { + lua_pushboolean(L, 1); + } + else + { + lua_pushboolean(L, 0); + } + + return 1; +} + +static const luaL_Reg mat2dStaticMethods[] = { + {"withTranslation", mat2d_withTranslation}, + {"withRotation", mat2d_withRotation}, + {"withScale", mat2d_withScale}, + {"withScaleAndTranslation", mat2d_withScaleAndTranslation}, + {"identity", mat2d_identity}, + {"values", mat2d_values}, + {"invert", mat2d_static_invert}, + {nullptr, nullptr}}; + +int luaopen_rive_mat2d(lua_State* L) +{ + luaL_register(L, ScriptedMat2D::luaName, mat2dStaticMethods); + lua_register_rive(L); + + lua_pushcfunction(L, mat2d_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, mat2d_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, mat2d_mul, nullptr); + lua_setfield(L, -2, "__mul"); + + lua_pushcfunction(L, mat2d_eq, nullptr); + lua_setfield(L, -2, "__eq"); + + lua_pushcfunction(L, mat2d_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/math/lua_mat4.cpp b/thirdparty/rive/source/lua/math/lua_mat4.cpp new file mode 100644 index 000000000..1cb334496 --- /dev/null +++ b/thirdparty/rive/source/lua/math/lua_mat4.cpp @@ -0,0 +1,402 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/math/mat4.hpp" +#include "rive/lua/rive_lua_libs.hpp" +#include +#include + +using namespace rive; + +static ScriptedMat4* lua_pushmat4(lua_State* L, const Mat4& mat) +{ + return lua_newrive(L, mat); +} + +static ScriptedMat4* lua_pushmat4(lua_State* L) +{ + return lua_newrive(L); +} + +// Mat4.values(c0x, c0y, c0z, c0w, c1x, ..., c3w) — column-major. +static int mat4_values(lua_State* L) +{ + auto out = lua_pushmat4(L); + float* m = out->value.values(); + for (int i = 0; i < 16; ++i) + { + m[i] = float(luaL_checknumber(L, 1 + i)); + } + return 1; +} + +static int mat4_identity(lua_State* L) +{ + lua_pushmat4(L, Mat4::identity()); + return 1; +} + +static int mat4_fromTranslation(lua_State* L) +{ + float x = float(luaL_checknumber(L, 1)); + float y = float(luaL_checknumber(L, 2)); + float z = float(luaL_checknumber(L, 3)); + lua_pushmat4(L, Mat4::fromTranslation(x, y, z)); + return 1; +} + +static int mat4_fromScale(lua_State* L) +{ + float sx = float(luaL_checknumber(L, 1)); + float sy = lua_isnumber(L, 2) ? float(luaL_checknumber(L, 2)) : sx; + float sz = lua_isnumber(L, 3) ? float(luaL_checknumber(L, 3)) : sx; + lua_pushmat4(L, Mat4::fromScale(sx, sy, sz)); + return 1; +} + +static int mat4_fromRotationX(lua_State* L) +{ + lua_pushmat4(L, Mat4::fromRotationX(float(luaL_checknumber(L, 1)))); + return 1; +} + +static int mat4_fromRotationY(lua_State* L) +{ + lua_pushmat4(L, Mat4::fromRotationY(float(luaL_checknumber(L, 1)))); + return 1; +} + +static int mat4_fromRotationZ(lua_State* L) +{ + lua_pushmat4(L, Mat4::fromRotationZ(float(luaL_checknumber(L, 1)))); + return 1; +} + +static int mat4_perspective(lua_State* L) +{ + float fov = float(luaL_checknumber(L, 1)); + float aspect = float(luaL_checknumber(L, 2)); + float n = float(luaL_checknumber(L, 3)); + float f = float(luaL_checknumber(L, 4)); + lua_pushmat4(L, Mat4::perspective(fov, aspect, n, f, /*zeroToOne=*/true)); + return 1; +} + +// Reverse-Z infinite-far perspective. See Mat4::perspectiveReverseZ. +static int mat4_perspectiveReverseZ(lua_State* L) +{ + float fov = float(luaL_checknumber(L, 1)); + float aspect = float(luaL_checknumber(L, 2)); + float n = float(luaL_checknumber(L, 3)); + lua_pushmat4(L, Mat4::perspectiveReverseZ(fov, aspect, n)); + return 1; +} + +// In-place: Mat4.multiply(out, a, b) -> out = a * b. Returns out. +// Avoids per-call userdata allocation in tight loops. +static int mat4_static_multiply(lua_State* L) +{ + auto out = lua_torive(L, 1); + auto a = lua_torive(L, 2); + auto b = lua_torive(L, 3); + out->value = Mat4::multiply(a->value, b->value); + lua_pushvalue(L, 1); + return 1; +} + +// In-place: Mat4.multiplyAffine(out, a, b) -> out = a * b, assuming both +// inputs are affine (bottom row [0,0,0,1]). Faster than `multiply` (skips +// the bottom-row work). +static int mat4_static_multiplyAffine(lua_State* L) +{ + auto out = lua_torive(L, 1); + auto a = lua_torive(L, 2); + auto b = lua_torive(L, 3); + out->value = Mat4::multiplyAffine(a->value, b->value); + lua_pushvalue(L, 1); + return 1; +} + +static int mat4_static_invert(lua_State* L) +{ + auto out = lua_torive(L, 1); + auto in = lua_torive(L, 2); + lua_pushboolean(L, in->value.invert(&out->value)); + return 1; +} + +// In-place: Mat4.invertAffine(out, in) — closed-form affine inverse. +// Returns true if invertible. Caller must ensure the input is affine. +static int mat4_static_invertAffine(lua_State* L) +{ + auto out = lua_torive(L, 1); + auto in = lua_torive(L, 2); + lua_pushboolean(L, in->value.invertAffine(&out->value)); + return 1; +} + +// Field index lookup. Supports m11..m44 (row,col 1-indexed) and 1..16 +// (column-major linear index, 1-indexed). +static int mat4_index_field(lua_State* L, + ScriptedMat4* mat, + const char* name, + size_t namelen) +{ + if (namelen == 3 && name[0] == 'm') + { + int row = name[1] - '0'; + int col = name[2] - '0'; + if (row >= 1 && row <= 4 && col >= 1 && col <= 4) + { + // m[row][col] 1-indexed; column-major storage means + // index = (col-1)*4 + (row-1). + lua_pushnumber(L, mat->value[(col - 1) * 4 + (row - 1)]); + return 1; + } + } + if (namelen >= 1 && namelen <= 2) + { + char* end = nullptr; + long n = std::strtol(name, &end, 10); + if (end && *end == '\0' && n >= 1 && n <= 16) + { + lua_pushnumber(L, mat->value[n - 1]); + return 1; + } + } + return 0; +} + +static int mat4_newindex_field(lua_State* L, + ScriptedMat4* mat, + const char* name, + size_t namelen, + float value) +{ + if (namelen == 3 && name[0] == 'm') + { + int row = name[1] - '0'; + int col = name[2] - '0'; + if (row >= 1 && row <= 4 && col >= 1 && col <= 4) + { + mat->value[(col - 1) * 4 + (row - 1)] = value; + return 0; + } + } + if (namelen >= 1 && namelen <= 2) + { + char* end = nullptr; + long n = std::strtol(name, &end, 10); + if (end && *end == '\0' && n >= 1 && n <= 16) + { + mat->value[n - 1] = value; + return 0; + } + } + return -1; +} + +static int mat4_index(lua_State* L) +{ + auto mat = lua_torive(L, 1); + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + if (mat4_index_field(L, mat, name, namelen) == 1) + return 1; + luaL_error(L, + "'%s' is not a valid index of %s", + name, + ScriptedMat4::luaName); + return 0; +} + +static int mat4_newindex(lua_State* L) +{ + auto mat = lua_torive(L, 1); + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + float value = float(luaL_checknumber(L, 3)); + if (mat4_newindex_field(L, mat, name, namelen, value) == 0) + return 0; + luaL_error(L, + "'%s' is not a valid index of %s", + name, + ScriptedMat4::luaName); + return 0; +} + +static int mat4_mul(lua_State* L) +{ + auto a = lua_torive(L, 1); + auto b = lua_torive(L, 2); + lua_pushmat4(L, Mat4::multiply(a->value, b->value)); + return 1; +} + +static int mat4_eq(lua_State* L) +{ + auto a = lua_torive(L, 1); + auto b = lua_torive(L, 2); + lua_pushboolean(L, a->value == b->value); + return 1; +} + +static int mat4_invert(lua_State* L) +{ + auto mat = lua_torive(L, 1); + Mat4 result; + if (mat->value.invert(&result)) + { + lua_pushmat4(L, result); + return 1; + } + lua_pushnil(L); + return 1; +} + +static int mat4_invertAffine(lua_State* L) +{ + auto mat = lua_torive(L, 1); + Mat4 result; + if (mat->value.invertAffine(&result)) + { + lua_pushmat4(L, result); + return 1; + } + lua_pushnil(L); + return 1; +} + +static int mat4_transpose(lua_State* L) +{ + auto mat = lua_torive(L, 1); + lua_pushmat4(L, mat->value.transposed()); + return 1; +} + +// mat:transformPoint(x, y, z) -> vector(x', y', z') (w=1, perspective +// divide) +static int mat4_transformPoint(lua_State* L) +{ + auto mat = lua_torive(L, 1); + float x = float(luaL_checknumber(L, 2)); + float y = float(luaL_checknumber(L, 3)); + float z = float(luaL_checknumber(L, 4)); + float out[4]; + mat->value.transformVec4(out, x, y, z, 1.f); + if (out[3] != 0.f && out[3] != 1.f) + { + float inv = 1.f / out[3]; + lua_pushvector(L, out[0] * inv, out[1] * inv, out[2] * inv); + } + else + { + lua_pushvector(L, out[0], out[1], out[2]); + } + return 1; +} + +// mat:transformVec4(x, y, z, w) -> x', y', z', w' (no perspective divide) +// Useful for clip-space transforms where the caller wants the homogeneous w +// preserved. +static int mat4_transformVec4(lua_State* L) +{ + auto mat = lua_torive(L, 1); + float x = float(luaL_checknumber(L, 2)); + float y = float(luaL_checknumber(L, 3)); + float z = float(luaL_checknumber(L, 4)); + float w = float(luaL_checknumber(L, 5)); + float out[4]; + mat->value.transformVec4(out, x, y, z, w); + lua_pushnumber(L, out[0]); + lua_pushnumber(L, out[1]); + lua_pushnumber(L, out[2]); + lua_pushnumber(L, out[3]); + return 4; +} + +// mat:writeToBuffer(buf, byteOffset) — direct 64-byte memcpy of the +// column-major matrix into a Luau buffer (uniform-buffer-friendly). +static int mat4_writeToBuffer(lua_State* L) +{ + auto mat = lua_torive(L, 1); + size_t bufLen = 0; + void* buf = luaL_checkbuffer(L, 2, &bufLen); + int off = int(luaL_checkinteger(L, 3)); + if (off < 0 || size_t(off) + 64 > bufLen) + { + luaL_error(L, "Mat4:writeToBuffer offset out of range"); + return 0; + } + std::memcpy(static_cast(buf) + off, mat->value.values(), 64); + return 0; +} + +static int mat4_namecall(lua_State* L) +{ + int atom; + if (lua_namecallatom(L, &atom)) + { + switch (atom) + { + case (int)LuaAtoms::invert: + return mat4_invert(L); + case (int)LuaAtoms::invertAffine: + return mat4_invertAffine(L); + case (int)LuaAtoms::transpose: + return mat4_transpose(L); + case (int)LuaAtoms::transformPoint: + return mat4_transformPoint(L); + case (int)LuaAtoms::transformVec4: + return mat4_transformVec4(L); + case (int)LuaAtoms::writeToBuffer: + return mat4_writeToBuffer(L); + } + } + luaL_error(L, + "%s is not a valid method of %s", + luaL_checkstring(L, 1), + ScriptedMat4::luaName); + return 0; +} + +static const luaL_Reg mat4StaticMethods[] = { + {"identity", mat4_identity}, + {"values", mat4_values}, + {"fromTranslation", mat4_fromTranslation}, + {"fromScale", mat4_fromScale}, + {"fromRotationX", mat4_fromRotationX}, + {"fromRotationY", mat4_fromRotationY}, + {"fromRotationZ", mat4_fromRotationZ}, + {"perspective", mat4_perspective}, + {"perspectiveReverseZ", mat4_perspectiveReverseZ}, + {"multiply", mat4_static_multiply}, + {"multiplyAffine", mat4_static_multiplyAffine}, + {"invert", mat4_static_invert}, + {"invertAffine", mat4_static_invertAffine}, + {nullptr, nullptr}}; + +int luaopen_rive_mat4(lua_State* L) +{ + luaL_register(L, ScriptedMat4::luaName, mat4StaticMethods); + lua_register_rive(L); + + lua_pushcfunction(L, mat4_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, mat4_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, mat4_mul, nullptr); + lua_setfield(L, -2, "__mul"); + + lua_pushcfunction(L, mat4_eq, nullptr); + lua_setfield(L, -2, "__eq"); + + lua_pushcfunction(L, mat4_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop metatable + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/math/lua_math.cpp b/thirdparty/rive/source/lua/math/lua_math.cpp new file mode 100644 index 000000000..f7987c8a5 --- /dev/null +++ b/thirdparty/rive/source/lua/math/lua_math.cpp @@ -0,0 +1,24 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" + +int luaopen_rive_vector(lua_State* L); +int luaopen_rive_mat2d(lua_State* L); +int luaopen_rive_mat4(lua_State* L); +int luaopen_rive_color(lua_State* L); + +static const lua_CFunction mathTypes[] = {luaopen_rive_vector, + luaopen_rive_mat2d, + luaopen_rive_mat4, + luaopen_rive_color}; + +int luaopen_rive_math(lua_State* L) +{ + int added = 0; + for (auto type : mathTypes) + { + added += type(L); + } + return added; +} + +#endif diff --git a/thirdparty/rive/source/lua/math/lua_vec2d.cpp b/thirdparty/rive/source/lua/math/lua_vec2d.cpp new file mode 100644 index 000000000..d9cdd01e2 --- /dev/null +++ b/thirdparty/rive/source/lua/math/lua_vec2d.cpp @@ -0,0 +1,213 @@ + +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "lualib.h" + +using namespace rive; + +static int vector_index(lua_State* L) +{ + const float* vec = luaL_checkvector(L, 1); + + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + + if (namelen == 1) + { + switch (name[0]) + { + case 'x': + case '1': + lua_pushnumber(L, vec[0]); + return 1; + case 'y': + case '2': + lua_pushnumber(L, vec[1]); + return 1; + case 'z': + case '3': + // Luau's vector type stores 3 components; .z is reachable + // intrinsically through the VM's named-axis fastpath, but + // numeric `[3]` indexing routes through this metamethod. + lua_pushnumber(L, vec[2]); + return 1; + default: + break; + } + } + + luaL_error(L, "'%s' is not a valid index of Vector", name); + return 0; +} + +static int vector_length(lua_State* L) +{ + auto vec = lua_checkvec2d(L, 1); + lua_pushnumber(L, vec->length()); + return 1; +} + +static int vector_normalized(lua_State* L) +{ + auto vec = lua_checkvec2d(L, 1); + lua_pushvec2d(L, vec->normalized()); + return 1; +} + +static int vector_lengthSquared(lua_State* L) +{ + auto vec = lua_checkvec2d(L, 1); + lua_pushnumber(L, vec->lengthSquared()); + return 1; +} + +static int vector_distance(lua_State* L) +{ + auto lhs = lua_checkvec2d(L, 1); + auto rhs = lua_checkvec2d(L, 2); + lua_pushnumber(L, Vec2D::distance(*lhs, *rhs)); + return 1; +} + +static int vector_distanceSquared(lua_State* L) +{ + auto lhs = lua_checkvec2d(L, 1); + auto rhs = lua_checkvec2d(L, 2); + lua_pushnumber(L, Vec2D::distanceSquared(*lhs, *rhs)); + return 1; +} + +static int vector_dot(lua_State* L) +{ + auto lhs = lua_checkvec2d(L, 1); + auto rhs = lua_checkvec2d(L, 2); + + lua_pushnumber(L, Vec2D::dot(*lhs, *rhs)); + return 1; +} + +static int vector_cross(lua_State* L) +{ + auto lhs = lua_checkvec2d(L, 1); + auto rhs = lua_checkvec2d(L, 2); + lua_pushnumber(L, Vec2D::cross(*lhs, *rhs)); + return 1; +} + +static int vector_scaleAndAdd(lua_State* L) +{ + auto a = lua_checkvec2d(L, 1); + auto b = lua_checkvec2d(L, 2); + float scale = float(luaL_checknumber(L, 3)); + lua_pushvec2d(L, Vec2D::scaleAndAdd(*a, *b, scale)); + return 1; +} + +static int vector_scaleAndSub(lua_State* L) +{ + auto a = lua_checkvec2d(L, 1); + auto b = lua_checkvec2d(L, 2); + float scale = float(luaL_checknumber(L, 3)); + lua_pushvec2d(L, *a - *b * scale); + return 1; +} + +static int vector_lerp(lua_State* L) +{ + auto lhs = lua_checkvec2d(L, 1); + auto rhs = lua_checkvec2d(L, 2); + float factor = float(luaL_checknumber(L, 3)); + lua_pushvec2d(L, Vec2D::lerp(*lhs, *rhs, factor)); + return 1; +} + +static int vector_xy(lua_State* L) +{ + float x = (float)lua_tonumber(L, 1); + float y = (float)lua_tonumber(L, 2); + + lua_pushvector2(L, x, y); + return 1; +} + +static int vector_origin(lua_State* L) +{ + lua_pushvector2(L, 0.0f, 0.0f); + return 1; +} + +static int vector_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::length: + return vector_length(L); + case (int)LuaAtoms::lengthSquared: + return vector_lengthSquared(L); + case (int)LuaAtoms::normalized: + return vector_normalized(L); + case (int)LuaAtoms::distance: + return vector_distance(L); + case (int)LuaAtoms::distanceSquared: + return vector_distanceSquared(L); + case (int)LuaAtoms::dot: + return vector_dot(L); + case (int)LuaAtoms::lerp: + return vector_lerp(L); + } + } + + luaL_error(L, "%s is not a valid method of Vector", luaL_checkstring(L, 1)); + return 0; +} + +static const luaL_Reg vectorStaticMethods[] = { + {"distance", vector_distance}, + {"distanceSquared", vector_distanceSquared}, + {"dot", vector_dot}, + {"cross", vector_cross}, + {"scaleAndAdd", vector_scaleAndAdd}, + {"scaleAndSub", vector_scaleAndSub}, + {"lerp", vector_lerp}, + {"xy", vector_xy}, + {"origin", vector_origin}, + {"length", vector_length}, + {"lengthSquared", vector_lengthSquared}, + {"normalized", vector_normalized}, + {nullptr, nullptr}}; + +int luaopen_rive_vector(lua_State* L) +{ + luaL_register(L, "Vector", vectorStaticMethods); + // create metatable for T + lua_createtable(L, 0, 1); + + // Dupe the metatable on the stack + lua_pushvalue(L, -1); + // Add a vector + lua_pushvector(L, 0.0f, 0.0f, 0.0f); + // Move it before the metatable + lua_insert(L, -2); + // Set metatable on the vector (globally sets the metatable for all + // vectors). + lua_setmetatable(L, -2); + // pop vector + lua_pop(L, 1); + + lua_pushcfunction(L, vector_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, vector_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_blob.cpp b/thirdparty/rive/source/lua/renderer/lua_blob.cpp new file mode 100644 index 000000000..bec87df1f --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_blob.cpp @@ -0,0 +1,70 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lua.h" +#include "lualib.h" +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/assets/blob_asset.hpp" + +#include + +using namespace rive; + +static int blob_index(lua_State* L) +{ + auto blob = lua_torive(L, 1); + + int atom; + const char* name = lua_tostringatom(L, 2, &atom); + if (!name) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + } + + BlobAsset* blobAsset = blob->asset ? blob->asset->as() : nullptr; + if (blobAsset == nullptr) + { + lua_pushnil(L); + return 1; + } + + switch (atom) + { + case (int)LuaAtoms::size: + lua_pushnumber(L, static_cast(blobAsset->bytes().size())); + return 1; + case (int)LuaAtoms::name: + lua_pushstring(L, blobAsset->name().c_str()); + return 1; + case (int)LuaAtoms::data: + { + auto bytes = blobAsset->bytes(); + if (bytes.size() > 0) + { + void* bufferData = lua_newbuffer(L, bytes.size()); + memcpy(bufferData, bytes.data(), bytes.size()); + return 1; + } + lua_pushnil(L); + return 1; + } + } + + luaL_error(L, + "'%s' is not a valid index of %s", + name, + ScriptedBlob::luaName); + return 0; +} + +int luaopen_rive_blob(lua_State* L) +{ + lua_register_rive(L); + + lua_pushcfunction(L, blob_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + return 0; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_gpu.cpp b/thirdparty/rive/source/lua/renderer/lua_gpu.cpp new file mode 100644 index 000000000..d219c0a1e --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_gpu.cpp @@ -0,0 +1,3577 @@ +#ifdef WITH_RIVE_SCRIPTING +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) +#include "lualib.h" +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/renderer/ore/ore_binding_map.hpp" +#include "rive/renderer/ore/ore_context.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/renderer/render_context.hpp" +#include "rive/renderer/render_context_impl.hpp" +#include "rive/renderer/rive_renderer.hpp" +#include "rive/assets/shader_asset.hpp" +#include "rive/shapes/paint/color.hpp" + +#include +#include +#include +#include +#include +#include + +using namespace rive; +using namespace rive::ore; + +// ============================================================================ +// String-to-enum helpers +// ============================================================================ + +static BufferUsage lua_tobufferusage(lua_State* L, int idx) +{ + const char* s = luaL_checkstring(L, idx); + if (strcmp(s, "vertex") == 0) + return BufferUsage::vertex; + if (strcmp(s, "index") == 0) + return BufferUsage::index; + if (strcmp(s, "uniform") == 0) + return BufferUsage::uniform; + luaL_error(L, "invalid BufferUsage: %s", s); + return BufferUsage::vertex; +} + +static TextureFormat lua_totextureformat(lua_State* L, const char* s) +{ + if (strcmp(s, "r8unorm") == 0) + return TextureFormat::r8unorm; + if (strcmp(s, "rg8unorm") == 0) + return TextureFormat::rg8unorm; + if (strcmp(s, "rgba8unorm") == 0) + return TextureFormat::rgba8unorm; + if (strcmp(s, "bgra8unorm") == 0) + return TextureFormat::bgra8unorm; + if (strcmp(s, "rgba16float") == 0) + return TextureFormat::rgba16float; + if (strcmp(s, "rg16float") == 0) + return TextureFormat::rg16float; + if (strcmp(s, "r16float") == 0) + return TextureFormat::r16float; + if (strcmp(s, "rgba32float") == 0) + return TextureFormat::rgba32float; + if (strcmp(s, "rgb10a2unorm") == 0) + return TextureFormat::rgb10a2unorm; + if (strcmp(s, "rg11b10ufloat") == 0) + return TextureFormat::r11g11b10float; + if (strcmp(s, "depth16unorm") == 0) + return TextureFormat::depth16unorm; + if (strcmp(s, "depth24plus-stencil8") == 0) + return TextureFormat::depth24plusStencil8; + if (strcmp(s, "depth32float") == 0) + return TextureFormat::depth32float; + if (strcmp(s, "depth32float-stencil8") == 0) + return TextureFormat::depth32floatStencil8; + if (strcmp(s, "bc1-rgba-unorm") == 0) + return TextureFormat::bc1unorm; + if (strcmp(s, "bc3-rgba-unorm") == 0) + return TextureFormat::bc3unorm; + if (strcmp(s, "bc7-rgba-unorm") == 0) + return TextureFormat::bc7unorm; + if (strcmp(s, "etc2-rgb8unorm") == 0) + return TextureFormat::etc2rgb8; + if (strcmp(s, "etc2-rgba8unorm") == 0) + return TextureFormat::etc2rgba8; + if (strcmp(s, "astc-4x4-unorm") == 0) + return TextureFormat::astc4x4; + if (strcmp(s, "astc-6x6-unorm") == 0) + return TextureFormat::astc6x6; + if (strcmp(s, "astc-8x8-unorm") == 0) + return TextureFormat::astc8x8; + luaL_error(L, "invalid TextureFormat: %s", s); + return TextureFormat::rgba8unorm; +} + +static const char* lua_totextureformatstring(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return "r8unorm"; + case TextureFormat::rg8unorm: + return "rg8unorm"; + case TextureFormat::rgba8unorm: + return "rgba8unorm"; + case TextureFormat::bgra8unorm: + return "bgra8unorm"; + case TextureFormat::rgba16float: + return "rgba16float"; + case TextureFormat::rg16float: + return "rg16float"; + case TextureFormat::r16float: + return "r16float"; + case TextureFormat::rgba32float: + return "rgba32float"; + case TextureFormat::rgb10a2unorm: + return "rgb10a2unorm"; + case TextureFormat::r11g11b10float: + return "rg11b10ufloat"; + case TextureFormat::depth16unorm: + return "depth16unorm"; + case TextureFormat::depth24plusStencil8: + return "depth24plus-stencil8"; + case TextureFormat::depth32float: + return "depth32float"; + case TextureFormat::depth32floatStencil8: + return "depth32float-stencil8"; + default: + return "rgba8unorm"; + } +} + +static TextureType lua_totexturetype(lua_State* L, const char* s) +{ + if (strcmp(s, "2d") == 0) + return TextureType::texture2D; + if (strcmp(s, "cube") == 0) + return TextureType::cube; + if (strcmp(s, "3d") == 0) + return TextureType::texture3D; + if (strcmp(s, "2d-array") == 0) + return TextureType::array2D; + luaL_error(L, "invalid TextureType: %s", s); + return TextureType::texture2D; +} + +static CompareFunction lua_tocompare(lua_State* L, const char* s) +{ + if (strcmp(s, "never") == 0) + return CompareFunction::never; + if (strcmp(s, "less") == 0) + return CompareFunction::less; + if (strcmp(s, "equal") == 0) + return CompareFunction::equal; + if (strcmp(s, "less-equal") == 0) + return CompareFunction::lessEqual; + if (strcmp(s, "greater") == 0) + return CompareFunction::greater; + if (strcmp(s, "not-equal") == 0) + return CompareFunction::notEqual; + if (strcmp(s, "greater-equal") == 0) + return CompareFunction::greaterEqual; + if (strcmp(s, "always") == 0) + return CompareFunction::always; + luaL_error(L, "invalid CompareFunction: %s", s); + return CompareFunction::none; +} + +static Filter lua_tofilter(lua_State* L, const char* s) +{ + if (strcmp(s, "nearest") == 0) + return Filter::nearest; + if (strcmp(s, "linear") == 0) + return Filter::linear; + luaL_error(L, "invalid Filter: %s", s); + return Filter::nearest; +} + +static WrapMode lua_towrapmode(lua_State* L, const char* s) +{ + if (strcmp(s, "repeat") == 0) + return WrapMode::repeat; + if (strcmp(s, "mirror-repeat") == 0) + return WrapMode::mirrorRepeat; + if (strcmp(s, "clamp-to-edge") == 0) + return WrapMode::clampToEdge; + luaL_error(L, "invalid WrapMode: %s", s); + return WrapMode::clampToEdge; +} + +static VertexFormat lua_tovertexformat(lua_State* L, const char* s) +{ + if (strcmp(s, "float32") == 0) + return VertexFormat::float1; + if (strcmp(s, "float32x2") == 0) + return VertexFormat::float2; + if (strcmp(s, "float32x3") == 0) + return VertexFormat::float3; + if (strcmp(s, "float32x4") == 0) + return VertexFormat::float4; + if (strcmp(s, "uint8x4") == 0) + return VertexFormat::uint8x4; + if (strcmp(s, "unorm8x4") == 0) + return VertexFormat::unorm8x4; + if (strcmp(s, "snorm8x4") == 0) + return VertexFormat::snorm8x4; + if (strcmp(s, "float16x2") == 0) + return VertexFormat::float16x2; + if (strcmp(s, "float16x4") == 0) + return VertexFormat::float16x4; + luaL_error(L, "invalid VertexFormat: %s", s); + return VertexFormat::float4; +} + +static CullMode lua_tocullmode(lua_State* L, const char* s) +{ + if (strcmp(s, "none") == 0) + return CullMode::none; + if (strcmp(s, "front") == 0) + return CullMode::front; + if (strcmp(s, "back") == 0) + return CullMode::back; + luaL_error(L, "invalid CullMode: %s", s); + return CullMode::none; +} + +static PrimitiveTopology lua_totopology(lua_State* L, const char* s) +{ + if (strcmp(s, "triangle-list") == 0) + return PrimitiveTopology::triangleList; + if (strcmp(s, "triangle-strip") == 0) + return PrimitiveTopology::triangleStrip; + if (strcmp(s, "line-list") == 0) + return PrimitiveTopology::lineList; + if (strcmp(s, "line-strip") == 0) + return PrimitiveTopology::lineStrip; + if (strcmp(s, "point-list") == 0) + return PrimitiveTopology::pointList; + luaL_error(L, "invalid PrimitiveTopology: %s", s); + return PrimitiveTopology::triangleList; +} + +static BlendFactor lua_toblendfactor(lua_State* L, const char* s) +{ + if (strcmp(s, "zero") == 0) + return BlendFactor::zero; + if (strcmp(s, "one") == 0) + return BlendFactor::one; + if (strcmp(s, "src") == 0) + return BlendFactor::srcColor; + if (strcmp(s, "one-minus-src") == 0) + return BlendFactor::oneMinusSrcColor; + if (strcmp(s, "src-alpha") == 0) + return BlendFactor::srcAlpha; + if (strcmp(s, "one-minus-src-alpha") == 0) + return BlendFactor::oneMinusSrcAlpha; + if (strcmp(s, "dst") == 0) + return BlendFactor::dstColor; + if (strcmp(s, "one-minus-dst") == 0) + return BlendFactor::oneMinusDstColor; + if (strcmp(s, "dst-alpha") == 0) + return BlendFactor::dstAlpha; + if (strcmp(s, "one-minus-dst-alpha") == 0) + return BlendFactor::oneMinusDstAlpha; + if (strcmp(s, "src-alpha-saturated") == 0) + return BlendFactor::srcAlphaSaturated; + if (strcmp(s, "constant") == 0) + return BlendFactor::blendColor; + if (strcmp(s, "one-minus-constant") == 0) + return BlendFactor::oneMinusBlendColor; + luaL_error(L, "invalid BlendFactor: %s", s); + return BlendFactor::one; +} + +static BlendOp lua_toblendop(lua_State* L, const char* s) +{ + if (strcmp(s, "add") == 0) + return BlendOp::add; + if (strcmp(s, "subtract") == 0) + return BlendOp::subtract; + if (strcmp(s, "reverse-subtract") == 0) + return BlendOp::reverseSubtract; + if (strcmp(s, "min") == 0) + return BlendOp::min; + if (strcmp(s, "max") == 0) + return BlendOp::max; + luaL_error(L, "invalid BlendOp: %s", s); + return BlendOp::add; +} + +static FaceWinding lua_towinding(lua_State* L, const char* s) +{ + if (strcmp(s, "cw") == 0) + return FaceWinding::clockwise; + if (strcmp(s, "ccw") == 0) + return FaceWinding::counterClockwise; + luaL_error(L, "invalid FaceWinding: %s", s); + return FaceWinding::counterClockwise; +} + +static StencilOp lua_tostencilop(lua_State* L, const char* s) +{ + if (strcmp(s, "keep") == 0) + return StencilOp::keep; + if (strcmp(s, "zero") == 0) + return StencilOp::zero; + if (strcmp(s, "replace") == 0) + return StencilOp::replace; + if (strcmp(s, "increment-clamp") == 0) + return StencilOp::incrementClamp; + if (strcmp(s, "decrement-clamp") == 0) + return StencilOp::decrementClamp; + if (strcmp(s, "invert") == 0) + return StencilOp::invert; + if (strcmp(s, "increment-wrap") == 0) + return StencilOp::incrementWrap; + if (strcmp(s, "decrement-wrap") == 0) + return StencilOp::decrementWrap; + luaL_error(L, "invalid StencilOp: %s", s); + return StencilOp::keep; +} + +// Parse a color writemask string. Each of "r"/"g"/"b"/"a" present in the +// string enables that channel. Recognized special values: "" or "none" +// disables all; "all" / "rgba" enables all (also the default if the +// field is absent). Order doesn't matter. +static ColorWriteMask lua_towritemask(lua_State* L, const char* s) +{ + if (s == nullptr || strcmp(s, "all") == 0 || strcmp(s, "rgba") == 0) + return ColorWriteMask::all; + if (s[0] == '\0' || strcmp(s, "none") == 0) + return ColorWriteMask::none; + ColorWriteMask out = ColorWriteMask::none; + for (const char* p = s; *p; ++p) + { + switch (*p) + { + case 'r': + case 'R': + out = out | ColorWriteMask::red; + break; + case 'g': + case 'G': + out = out | ColorWriteMask::green; + break; + case 'b': + case 'B': + out = out | ColorWriteMask::blue; + break; + case 'a': + case 'A': + out = out | ColorWriteMask::alpha; + break; + default: + luaL_error(L, + "invalid ColorWriteMask: '%s' " + "(expected r/g/b/a chars or 'all'/'none')", + s); + } + } + return out; +} + +// Helper to get a string field from a table at idx, returns nullptr if +// the field doesn't exist. +static const char* lua_getoptionalstringfield(lua_State* L, + int idx, + const char* field) +{ + lua_getfield(L, idx, field); + const char* s = lua_isstring(L, -1) ? lua_tostring(L, -1) : nullptr; + lua_pop(L, 1); + return s; +} + +// Parse a stencil-face state table: +// { compare="...", failOp="...", depthFailOp="...", passOp="..." } +// Defined after `lua_getoptionalstringfield` because it uses that helper — +// Android NDK clang's `-Werror` rejects forward use of a `static` function +// that hasn't been declared yet. +static void lua_tostencilface(lua_State* L, int idx, StencilFaceState* face) +{ + if (!lua_istable(L, idx)) + return; + const char* s = lua_getoptionalstringfield(L, idx, "compare"); + if (s) + face->compare = lua_tocompare(L, s); + s = lua_getoptionalstringfield(L, idx, "failOp"); + if (s) + face->failOp = lua_tostencilop(L, s); + s = lua_getoptionalstringfield(L, idx, "depthFailOp"); + if (s) + face->depthFailOp = lua_tostencilop(L, s); + s = lua_getoptionalstringfield(L, idx, "passOp"); + if (s) + face->passOp = lua_tostencilop(L, s); +} + +static double lua_getoptionalnumberfield(lua_State* L, + int idx, + const char* field, + double def) +{ + lua_getfield(L, idx, field); + double v = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : def; + lua_pop(L, 1); + return v; +} + +static bool lua_getoptionalboolfield(lua_State* L, + int idx, + const char* field, + bool def) +{ + lua_getfield(L, idx, field); + bool v = lua_isboolean(L, -1) ? lua_toboolean(L, -1) : def; + lua_pop(L, 1); + return v; +} + +// ============================================================================ +// Debug tracing +// ============================================================================ + +// ============================================================================ +// Shader (ore::ShaderModule) +// ============================================================================ + +// Retrieves the ore GPU context for the current VM from its ScriptingContext. +static Context* getOreContext(lua_State* L) +{ + return static_cast( + static_cast(lua_getthreaddata(L))->oreContext()); +} + +/// Returns the RSTB `ShaderTarget` byte that matches the ore backend +/// compiled into this build. Dispatches on `ORE_BACKEND_*` rather than +/// host-OS macros (`__APPLE__` / `_WIN32`) so hosts whose backend doesn't +/// match the host's "default" runtime API — e.g. the Linux GPU recorder +/// (Vulkan, not GL) or Mac MoltenVK — pick the correct pre-compiled +/// variant out of the RSTB table. +/// +/// Target enum (must match `ShaderAsset` RSTB format): +/// 0 = WGSL passthrough, 1 = GLSL ES3, 2 = MSL, 3 = HLSL SM5, +/// 5 = SPIR-V +static uint8_t currentShaderTarget() +{ +#if defined(ORE_BACKEND_METAL) + return 2; // MSL +#elif defined(ORE_BACKEND_VK) + return 5; // SPIR-V +#elif defined(ORE_BACKEND_D3D11) || defined(ORE_BACKEND_D3D12) + return 3; // HLSL SM5, compiled to DXBC at runtime via D3DCompile +#elif defined(ORE_BACKEND_WGPU) + return 0; // WGSL passthrough (Dawn + wagyu) +#elif defined(ORE_BACKEND_GL) + return 1; // GLSL ES3 +#else + return 1; +#endif +} + +/// Try to create ShaderModules from a raw RSTB blob. +/// For GLSL targets, the blob may contain two sources separated by a null +/// byte (vertex then fragment). Populates both module and fragmentModule on +/// the ScriptedShader. Returns true on success. +/// Copy texture-sampler pairs from a ShaderAsset into both +/// vertex and fragment ShaderModules of a ScriptedShader. +static void propagatePairs(const ShaderAsset& asset, ScriptedShader* out) +{ + auto pairs = asset.textureSamplerPairs(); + if (pairs.empty()) + return; + std::vector vec; + vec.reserve(pairs.size()); + for (size_t i = 0; i < pairs.size(); i++) + { + vec.push_back({pairs[i].texGroup, + pairs[i].texBinding, + pairs[i].sampGroup, + pairs[i].sampBinding}); + } + if (out->module) + out->module->m_textureSamplerPairs = vec; + if (out->fragmentModule) + out->fragmentModule->m_textureSamplerPairs = vec; +} + +static bool makeShaderFromRstb(Context* oreCtx, + const uint8_t* data, + uint32_t len, + ScriptedShader* out) +{ + if (oreCtx == nullptr || data == nullptr || len == 0 || out == nullptr) + return false; + + // ShaderAsset::decode expects a SignedContentHeader envelope + // (shared with ScriptAsset: `[flags:1][sig:64?][inner]`). The workspace + // hands us raw RSTB bytes, so prepend an unsigned envelope (flags=0, + // no signature) to produce the canonical input format. + ShaderAsset asset; + SimpleArray bytes(static_cast(len) + 1); + bytes[0] = 0x00; // flags: unsigned, version 0 + memcpy(bytes.data() + 1, data, len); + if (!asset.decode(bytes, nullptr)) + return false; + + uint8_t target = currentShaderTarget(); + auto blob = asset.findShader(target); + if (blob.empty()) + return false; + + const char* blobData = reinterpret_cast(blob.data()); + uint32_t blobSize = static_cast(blob.size()); + + // Binding-map sidecar (mandatory) + GL fixup sidecars (only present + // for the GLSL source target). Every shipped shader carries a sidecar + // paired with its source variant. + auto bindingMapTargetFor = [](uint8_t t) -> uint8_t { + switch (t) + { + case 0: + return 16; + case 1: + return 11; + case 2: + return 10; + case 3: + return 12; + case 5: + return 13; + default: + return 255; + } + }; + uint8_t bmTarget = bindingMapTargetFor(target); + auto bindingMapBlob = + (bmTarget == 255) ? Span{} : asset.findShader(bmTarget); + const uint8_t* bindingMapBytes = + bindingMapBlob.empty() ? nullptr : bindingMapBlob.data(); + uint32_t bindingMapSize = static_cast(bindingMapBlob.size()); + auto vsGLFixupBlob = + (target == 1) ? asset.findShader(14) : Span{}; + auto fsGLFixupBlob = + (target == 1) ? asset.findShader(15) : Span{}; + const uint8_t* vsGLFixupBytes = + vsGLFixupBlob.empty() ? nullptr : vsGLFixupBlob.data(); + uint32_t vsGLFixupSize = static_cast(vsGLFixupBlob.size()); + const uint8_t* fsGLFixupBytes = + fsGLFixupBlob.empty() ? nullptr : fsGLFixupBlob.data(); + uint32_t fsGLFixupSize = static_cast(fsGLFixupBlob.size()); + + // HLSL SM5 via SPIRV-Cross (D3D11/D3D12 on Windows). + // Blob format: "vsEntry\0fsEntry\0vsHLSL\0fsHLSL" + // Compiled to DXBC at runtime via D3DCompile in ensureD3DShaders(). + if (target == 3) + { + // Parse: vsEntry\0 + const char* vsEntry = blobData; + const char* vsEnd = + static_cast(memchr(vsEntry, '\0', blobSize)); + if (!vsEnd) + return false; + // Parse: fsEntry\0 + const char* fsEntry = vsEnd + 1; + uint32_t remaining = + blobSize - static_cast(fsEntry - blobData); + const char* fsEnd = + static_cast(memchr(fsEntry, '\0', remaining)); + if (!fsEnd) + return false; + // Parse: vsHLSL\0 + const char* vsHLSL = fsEnd + 1; + remaining = blobSize - static_cast(vsHLSL - blobData); + const char* vsHLSLEnd = + static_cast(memchr(vsHLSL, '\0', remaining)); + if (!vsHLSLEnd) + return false; + // Parse: fsHLSL (rest of blob) + const char* fsHLSL = vsHLSLEnd + 1; + uint32_t fsHLSLSize = + blobSize - static_cast(fsHLSL - blobData); + + // Create vertex module with HLSL source for runtime D3DCompile. + { + ShaderModuleDesc vtxDesc; + vtxDesc.stage = ShaderStage::vertex; + vtxDesc.hlslSource = vsHLSL; + vtxDesc.hlslSourceSize = static_cast(vsHLSLEnd - vsHLSL); + vtxDesc.hlslEntryPoint = vsEntry; + vtxDesc.bindingMapBytes = bindingMapBytes; + vtxDesc.bindingMapSize = bindingMapSize; + out->module = oreCtx->makeShaderModule(vtxDesc); + } + // Create fragment module with HLSL source for runtime D3DCompile. + { + ShaderModuleDesc fragDesc; + fragDesc.stage = ShaderStage::fragment; + fragDesc.hlslSource = fsHLSL; + fragDesc.hlslSourceSize = fsHLSLSize; + fragDesc.hlslEntryPoint = fsEntry; + fragDesc.bindingMapBytes = bindingMapBytes; + fragDesc.bindingMapSize = bindingMapSize; + out->fragmentModule = oreCtx->makeShaderModule(fragDesc); + } + if (out->module) + propagatePairs(asset, out); + return out->module != nullptr; + } + + // Check for a null separator inside the blob — indicates split + // vertex/fragment GLSL (one GLSL source per entry point). + const char* sep = + static_cast(memchr(blobData, '\0', blobSize - 1)); + + if (sep != nullptr) + { + // Split blob: vertex before separator, fragment after. + uint32_t vtxSize = static_cast(sep - blobData); + const char* fragData = sep + 1; + uint32_t fragSize = blobSize - vtxSize - 1; + + ShaderModuleDesc vtxDesc; + vtxDesc.code = blobData; + vtxDesc.codeSize = vtxSize; + vtxDesc.stage = ShaderStage::vertex; + vtxDesc.bindingMapBytes = bindingMapBytes; + vtxDesc.bindingMapSize = bindingMapSize; + vtxDesc.glFixupBytes = vsGLFixupBytes; + vtxDesc.glFixupSize = vsGLFixupSize; + out->module = oreCtx->makeShaderModule(vtxDesc); + + ShaderModuleDesc fragDesc; + fragDesc.code = fragData; + fragDesc.codeSize = fragSize; + fragDesc.stage = ShaderStage::fragment; + fragDesc.bindingMapBytes = bindingMapBytes; + fragDesc.bindingMapSize = bindingMapSize; + fragDesc.glFixupBytes = fsGLFixupBytes; + fragDesc.glFixupSize = fsGLFixupSize; + out->fragmentModule = oreCtx->makeShaderModule(fragDesc); + + if (out->module && out->fragmentModule) + propagatePairs(asset, out); + return out->module != nullptr && out->fragmentModule != nullptr; + } + + // Single combined blob (Metal, WGSL, etc.) + ShaderModuleDesc desc; + desc.code = blobData; + desc.codeSize = blobSize; + desc.bindingMapBytes = bindingMapBytes; + desc.bindingMapSize = bindingMapSize; + out->module = oreCtx->makeShaderModule(desc); + if (out->module) + propagatePairs(asset, out); + return out->module != nullptr; +} + +/// Look up a shader by name: first check the per-VM RSTB blobs on the +/// ScriptingContext (editor path, compiled during requestVM), then try the +/// ShaderAsset from file->assets() (runtime .riv path). +/// Populates both vertex and fragment modules on the ScriptedShader. +/// Returns true on success. +bool lua_gpu_load_shader_by_name(ScriptedShader* out, + ScriptingContext* context, + const char* name, + ShaderAsset* fileAsset) +{ + Context* oreCtx = static_cast( + context != nullptr ? context->oreContext() : nullptr); + +#ifdef WITH_RIVE_TOOLS + // Editor path: RSTB blobs compiled from WGSL during requestVM, stored + // per-VM on the ScriptingContext. + if (context != nullptr) + { + const auto* rstb = context->findShaderRstb(name); + if (rstb != nullptr) + { + return makeShaderFromRstb(oreCtx, + rstb->data(), + static_cast(rstb->size()), + out); + } + } +#endif + // Runtime path: ShaderAsset from the .riv file's asset list. + // Use the same RSTB decoding as the editor path so that GLSL + // vertex/fragment splitting and texture-sampler pair propagation + // are handled correctly on all backends. + if (fileAsset != nullptr && oreCtx != nullptr) + { + uint8_t target = currentShaderTarget(); + auto blob = fileAsset->findShader(target); + if (!blob.empty()) + { + const char* blobData = reinterpret_cast(blob.data()); + uint32_t blobSize = static_cast(blob.size()); + const uint32_t assetId = fileAsset->assetId(); + + // Sidecar lookup (mirrors makeShaderFromRstb above). The + // sidecar is mandatory; absence here would assert in + // `makeShaderModule::applyBindingMapFromDesc`. + auto bmTarget = [](uint8_t t) -> uint8_t { + switch (t) + { + case 0: + return 16; + case 1: + return 11; + case 2: + return 10; + case 3: + return 12; + case 5: + return 13; + default: + return 255; + } + }(target); + auto bmBlob = (bmTarget == 255) ? Span{} + : fileAsset->findShader(bmTarget); + const uint8_t* bindingMapBytes = + bmBlob.empty() ? nullptr : bmBlob.data(); + uint32_t bindingMapSize = static_cast(bmBlob.size()); + auto vsFixupBlob = (target == 1) ? fileAsset->findShader(14) + : Span{}; + auto fsFixupBlob = (target == 1) ? fileAsset->findShader(15) + : Span{}; + const uint8_t* vsFixupBytes = + vsFixupBlob.empty() ? nullptr : vsFixupBlob.data(); + uint32_t vsFixupSize = static_cast(vsFixupBlob.size()); + const uint8_t* fsFixupBytes = + fsFixupBlob.empty() ? nullptr : fsFixupBlob.data(); + uint32_t fsFixupSize = static_cast(fsFixupBlob.size()); + + // HLSL SM5 (target 3): split vsEntry/fsEntry/vsHLSL/fsHLSL. + if (target == 3) + { + const char* vsEntry = blobData; + const char* vsEnd = + static_cast(memchr(vsEntry, '\0', blobSize)); + if (!vsEnd) + return false; + const char* fsEntry = vsEnd + 1; + uint32_t remaining = + blobSize - static_cast(fsEntry - blobData); + const char* fsEnd = + static_cast(memchr(fsEntry, '\0', remaining)); + if (!fsEnd) + return false; + const char* vsHLSL = fsEnd + 1; + remaining = blobSize - static_cast(vsHLSL - blobData); + const char* vsHLSLEnd = + static_cast(memchr(vsHLSL, '\0', remaining)); + if (!vsHLSLEnd) + return false; + const char* fsHLSL = vsHLSLEnd + 1; + uint32_t fsHLSLSize = + blobSize - static_cast(fsHLSL - blobData); + + ShaderModuleDesc vtxDesc; + vtxDesc.stage = ShaderStage::vertex; + vtxDesc.hlslSource = vsHLSL; + vtxDesc.hlslSourceSize = + static_cast(vsHLSLEnd - vsHLSL); + vtxDesc.hlslEntryPoint = vsEntry; + vtxDesc.bindingMapBytes = bindingMapBytes; + vtxDesc.bindingMapSize = bindingMapSize; + vtxDesc.shaderAssetId = assetId; + out->module = oreCtx->makeShaderModule(vtxDesc); + + ShaderModuleDesc fragDesc; + fragDesc.stage = ShaderStage::fragment; + fragDesc.hlslSource = fsHLSL; + fragDesc.hlslSourceSize = fsHLSLSize; + fragDesc.hlslEntryPoint = fsEntry; + fragDesc.bindingMapBytes = bindingMapBytes; + fragDesc.bindingMapSize = bindingMapSize; + fragDesc.shaderAssetId = assetId; + out->fragmentModule = oreCtx->makeShaderModule(fragDesc); + } + // GLSL ES3 (target 1): split vertex\0fragment. + else if (target == 1 && blobSize > 1) + { + const char* sep = static_cast( + memchr(blobData, '\0', blobSize - 1)); + if (sep) + { + uint32_t vtxSize = static_cast(sep - blobData); + const char* fragData = sep + 1; + uint32_t fragSize = blobSize - vtxSize - 1; + + ShaderModuleDesc vtxDesc; + vtxDesc.code = blobData; + vtxDesc.codeSize = vtxSize; + vtxDesc.stage = ShaderStage::vertex; + vtxDesc.bindingMapBytes = bindingMapBytes; + vtxDesc.bindingMapSize = bindingMapSize; + vtxDesc.glFixupBytes = vsFixupBytes; + vtxDesc.glFixupSize = vsFixupSize; + vtxDesc.shaderAssetId = assetId; + out->module = oreCtx->makeShaderModule(vtxDesc); + + ShaderModuleDesc fragDesc; + fragDesc.code = fragData; + fragDesc.codeSize = fragSize; + fragDesc.stage = ShaderStage::fragment; + fragDesc.bindingMapBytes = bindingMapBytes; + fragDesc.bindingMapSize = bindingMapSize; + fragDesc.glFixupBytes = fsFixupBytes; + fragDesc.glFixupSize = fsFixupSize; + fragDesc.shaderAssetId = assetId; + out->fragmentModule = oreCtx->makeShaderModule(fragDesc); + } + else + { + // No separator — single module (unusual). + ShaderModuleDesc desc; + desc.code = blobData; + desc.codeSize = blobSize; + desc.bindingMapBytes = bindingMapBytes; + desc.bindingMapSize = bindingMapSize; + desc.shaderAssetId = assetId; + out->module = oreCtx->makeShaderModule(desc); + } + } + // Single combined blob (MSL, WGSL, SPIR-V). + else + { + ShaderModuleDesc desc; + desc.code = blobData; + desc.codeSize = blobSize; + desc.bindingMapBytes = bindingMapBytes; + desc.bindingMapSize = bindingMapSize; + desc.shaderAssetId = assetId; + out->module = oreCtx->makeShaderModule(desc); + } + + // Propagate texture-sampler pairs from the RSTB. + if (out->module) + { + auto pairs = fileAsset->textureSamplerPairs(); + if (!pairs.empty()) + { + std::vector vec; + vec.reserve(pairs.size()); + for (size_t i = 0; i < pairs.size(); i++) + { + vec.push_back({pairs[i].texGroup, + pairs[i].texBinding, + pairs[i].sampGroup, + pairs[i].sampBinding}); + } + out->module->m_textureSamplerPairs = vec; + if (out->fragmentModule) + out->fragmentModule->m_textureSamplerPairs = vec; + } + } + + return out->module != nullptr; + } + } + + return false; +} + +int lua_gpu_push_shader_by_name(lua_State* L, const char* name) +{ + auto* context = static_cast(lua_getthreaddata(L)); + auto* scripted = lua_newrive(L); + if (!lua_gpu_load_shader_by_name(scripted, context, name, nullptr)) + { + lua_pop(L, 1); + return 0; + } + return 1; +} + +// Optional WGSL→native compiler, set by the host via +// luaopen_rive_gpu_set_wgsl_compiler(). When set, shader_construct() routes +// WGSL source through this function before passing to makeShaderModule(). +// Returns true and fills |outSource| on success; returns false and fills +// |outError| on failure. Not set in Flutter runtime builds (shaders arrive +// as pre-compiled backend source from ShaderAsset). +#ifdef WITH_RIVE_TOOLS +static bool (*g_wgslCompilerFn)(const char* wgsl, + uint32_t len, + std::string* outSource, + std::string* outError) = nullptr; + +void luaopen_rive_gpu_set_wgsl_compiler( + bool (*fn)(const char*, uint32_t, std::string*, std::string*)) +{ + g_wgslCompilerFn = fn; +} +#endif + +static int shader_construct(lua_State* L) +{ + // Argument 1 is the name of a pre-compiled WGSL shader asset that was + // bundled with the Rive file (set via the "wgslAssetName" field in the + // editor). Raw WGSL source strings are NOT accepted at runtime; shaders + // must be pre-compiled and embedded as assets. + const char* name = luaL_checkstring(L, 1); + if (lua_gpu_push_shader_by_name(L, name) == 0) + { + luaL_error(L, "Shader.new: no shader asset named '%s' found", name); + } + return 1; +} + +// ============================================================================ +// GPUBuffer +// ============================================================================ + +// `GPUBuffer.new(size, usage [, options])` where `options` is an optional +// table of: +// - `data` : Lua buffer with initial contents. Required when +// `immutable=true`. Length must match `size` exactly so +// backends can populate the GPU resource at create time. +// - `immutable` : when true, the buffer is GPU-only (no `:write` after +// creation). Required for `BufferDesc::immutable`, which +// backends with a USAGE_IMMUTABLE concept (D3D11) honor +// for static vertex/index buffers. +static int gpubuffer_construct(lua_State* L) +{ + if (getOreContext(L) == nullptr) + { + luaL_error(L, "GPU context not initialized"); + } + + uint32_t size = static_cast(luaL_checkunsigned(L, 1)); + BufferUsage usage = lua_tobufferusage(L, 2); + + BufferDesc desc; + desc.size = size; + desc.usage = usage; + + // Optional `options` table with initial data + immutable flag. + if (lua_istable(L, 3)) + { + int optsIdx = 3; + desc.immutable = + lua_getoptionalboolfield(L, optsIdx, "immutable", false); + + lua_getfield(L, optsIdx, "data"); + if (!lua_isnil(L, -1)) + { + size_t dataLen = 0; + const void* dataPtr = lua_tobuffer(L, -1, &dataLen); + if (dataPtr == nullptr) + { + luaL_error(L, + "GPUBuffer.new: 'data' option must be a Luau " + "buffer"); + } + if (dataLen != size) + { + luaL_error(L, + "GPUBuffer.new: data length (%zu) must equal " + "size (%u)", + dataLen, + size); + } + desc.data = dataPtr; + } + lua_pop(L, 1); + + if (desc.immutable && desc.data == nullptr) + { + luaL_error(L, + "GPUBuffer.new: immutable=true requires 'data' " + "option (the GPU buffer is GPU-only after creation)"); + } + } + + auto* ctx = getOreContext(L); + ctx->clearLastError(); + auto buffer = ctx->makeBuffer(desc); + if (!buffer) + { + if (!ctx->lastError().empty()) + luaL_error(L, "GPUBuffer.new: %s", ctx->lastError().c_str()); + luaL_error(L, "GPUBuffer.new: failed to create buffer"); + } + + auto* scripted = lua_newrive(L); + scripted->buffer = std::move(buffer); + scripted->immutable = desc.immutable; + return 1; +} + +static int gpubuffer_write(lua_State* L) +{ + auto* self = lua_torive(L, 1); + if (self->immutable) + { + luaL_error(L, + "GPUBuffer:write: buffer was created with " + "immutable=true; its contents are fixed at construction"); + } + // Luau buffer type + size_t len; + const void* data = lua_tobuffer(L, 2, &len); + if (data == nullptr) + { + luaL_typeerror(L, 2, "buffer"); + } + uint32_t offset = + lua_isnumber(L, 3) ? static_cast(lua_tonumber(L, 3)) : 0; + + if (offset + len > self->buffer->size()) + { + luaL_error(L, + "GPUBuffer:write: offset(%u) + size(%u) = %u exceeds " + "buffer size(%u)", + offset, + (uint32_t)len, + (uint32_t)(offset + len), + self->buffer->size()); + } + + self->buffer->update(data, static_cast(len), offset); + return 0; +} + +static int gpubuffer_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::write: + return gpubuffer_write(L); + } + } + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedGPUBuffer::luaName); + return 0; +} + +static int gpubuffer_index(lua_State* L) +{ + auto* self = lua_torive(L, 1); + const char* key = luaL_checkstring(L, 2); + if (strcmp(key, "size") == 0) + { + lua_pushnumber(L, self->buffer->size()); + return 1; + } + luaL_error(L, "%s is not a valid property of GPUBuffer", key); + return 0; +} + +// ============================================================================ +// GPUTexture +// ============================================================================ + +// Validate a user-supplied sampleCount against the device's actual limit. +// Errors with a clear message rather than letting Metal/Vulkan assert-fail. +static void lua_checksamplecount(lua_State* L, uint32_t sampleCount) +{ + if (sampleCount <= 1) + return; + // Must be a power of two. + if ((sampleCount & (sampleCount - 1)) != 0) + luaL_error(L, + "sampleCount must be a power of two (got %u)", + sampleCount); + auto* ctx = getOreContext(L); + if (ctx) + { + uint32_t maxSamples = ctx->features().maxSamples; + if (sampleCount > maxSamples) + luaL_error(L, + "sampleCount %u exceeds device maximum of %u — " + "query context:features().maxSamples before creating " + "MSAA textures", + sampleCount, + maxSamples); + } +} + +static int gputexture_construct(lua_State* L) +{ + if (getOreContext(L) == nullptr) + { + luaL_error(L, "GPU context not initialized"); + } + + luaL_checktype(L, 1, LUA_TTABLE); + int descIdx = 1; + + TextureDesc desc; + desc.width = static_cast( + lua_getoptionalnumberfield(L, descIdx, "width", 0)); + desc.height = static_cast( + lua_getoptionalnumberfield(L, descIdx, "height", 0)); + if (desc.width == 0 || desc.height == 0) + { + luaL_error(L, "GPUTexture requires width and height"); + } + + const char* fmt = lua_getoptionalstringfield(L, descIdx, "format"); + if (fmt) + desc.format = lua_totextureformat(L, fmt); + + const char* typ = lua_getoptionalstringfield(L, descIdx, "type"); + if (typ) + desc.type = lua_totexturetype(L, typ); + + desc.renderTarget = + lua_getoptionalboolfield(L, descIdx, "renderTarget", false); + desc.sampleCount = static_cast( + lua_getoptionalnumberfield(L, descIdx, "sampleCount", 1)); + lua_checksamplecount(L, desc.sampleCount); + desc.numMipmaps = static_cast( + lua_getoptionalnumberfield(L, descIdx, "mipmaps", 1)); + desc.depthOrArrayLayers = static_cast( + lua_getoptionalnumberfield(L, descIdx, "layers", 1)); + + auto* ctx = getOreContext(L); + ctx->clearLastError(); + auto texture = ctx->makeTexture(desc); + if (!texture) + { + if (!ctx->lastError().empty()) + luaL_error(L, "GPUTexture.new: %s", ctx->lastError().c_str()); + luaL_error(L, "GPUTexture.new: failed to create texture"); + } + + auto* scripted = lua_newrive(L); + scripted->texture = std::move(texture); + return 1; +} + +static int gputexture_view(lua_State* L) +{ + auto* self = lua_torive(L, 1); + + TextureViewDesc viewDesc; + viewDesc.texture = self->texture.get(); + viewDesc.mipCount = self->texture->numMipmaps(); + viewDesc.layerCount = self->texture->depthOrArrayLayers(); + + // Map TextureType -> TextureViewDimension + switch (self->texture->type()) + { + case TextureType::texture2D: + viewDesc.dimension = TextureViewDimension::texture2D; + break; + case TextureType::cube: + viewDesc.dimension = TextureViewDimension::cube; + break; + case TextureType::texture3D: + viewDesc.dimension = TextureViewDimension::texture3D; + break; + case TextureType::array2D: + viewDesc.dimension = TextureViewDimension::array2D; + break; + } + + if (lua_istable(L, 2)) + { + const char* dim = lua_getoptionalstringfield(L, 2, "dimension"); + if (dim) + { + if (strcmp(dim, "2d") == 0) + viewDesc.dimension = TextureViewDimension::texture2D; + else if (strcmp(dim, "cube") == 0) + viewDesc.dimension = TextureViewDimension::cube; + else if (strcmp(dim, "3d") == 0) + viewDesc.dimension = TextureViewDimension::texture3D; + else if (strcmp(dim, "2d-array") == 0) + viewDesc.dimension = TextureViewDimension::array2D; + } + viewDesc.baseMipLevel = static_cast( + lua_getoptionalnumberfield(L, 2, "baseMipLevel", 0)); + viewDesc.mipCount = static_cast( + lua_getoptionalnumberfield(L, 2, "mipCount", viewDesc.mipCount)); + viewDesc.baseLayer = static_cast( + lua_getoptionalnumberfield(L, 2, "baseLayer", 0)); + viewDesc.layerCount = static_cast( + lua_getoptionalnumberfield(L, + 2, + "layerCount", + viewDesc.layerCount)); + } + + auto* ctx = getOreContext(L); + ctx->clearLastError(); + auto tv = ctx->makeTextureView(viewDesc); + if (!tv) + { + if (!ctx->lastError().empty()) + luaL_error(L, "GPUTexture:view: %s", ctx->lastError().c_str()); + luaL_error(L, "GPUTexture:view: failed to create texture view"); + } + + auto* scripted = lua_newrive(L); + scripted->view = std::move(tv); + return 1; +} + +static int gputexture_upload(lua_State* L) +{ + auto* self = lua_torive(L, 1); + luaL_checktype(L, 2, LUA_TTABLE); + int descIdx = 2; + + lua_getfield(L, descIdx, "data"); + size_t len; + const void* data = lua_tobuffer(L, -1, &len); + if (!data) + { + luaL_error(L, "upload requires 'data' field of type buffer"); + } + lua_pop(L, 1); + + TextureDataDesc uploadDesc; + uploadDesc.data = data; + uploadDesc.width = static_cast( + lua_getoptionalnumberfield(L, + descIdx, + "width", + self->texture->width())); + uploadDesc.height = static_cast( + lua_getoptionalnumberfield(L, + descIdx, + "height", + self->texture->height())); + uploadDesc.depth = static_cast( + lua_getoptionalnumberfield(L, descIdx, "depth", 1)); + uploadDesc.x = + static_cast(lua_getoptionalnumberfield(L, descIdx, "x", 0)); + uploadDesc.y = + static_cast(lua_getoptionalnumberfield(L, descIdx, "y", 0)); + uploadDesc.z = + static_cast(lua_getoptionalnumberfield(L, descIdx, "z", 0)); + uploadDesc.mipLevel = static_cast( + lua_getoptionalnumberfield(L, descIdx, "mipLevel", 0)); + uploadDesc.layer = static_cast( + lua_getoptionalnumberfield(L, descIdx, "layer", 0)); + uploadDesc.bytesPerRow = static_cast( + lua_getoptionalnumberfield(L, descIdx, "bytesPerRow", 0)); + uploadDesc.rowsPerImage = static_cast( + lua_getoptionalnumberfield(L, descIdx, "rowsPerImage", 0)); + + // Validate region/level/layer against the texture's actual dimensions — + // out-of-range values trip backend asserts (Metal API Validation, D3D12 + // GPU hangs, Vulkan validation). Per the + // `feedback_lua_gpu_misuse_validation` rule, surface as luaL_error. + if (uploadDesc.mipLevel >= self->texture->numMipmaps()) + { + luaL_error(L, + "upload: mipLevel %u out of range [0, %u)", + uploadDesc.mipLevel, + self->texture->numMipmaps()); + } + if (uploadDesc.layer >= self->texture->depthOrArrayLayers()) + { + luaL_error(L, + "upload: layer %u out of range [0, %u)", + uploadDesc.layer, + self->texture->depthOrArrayLayers()); + } + // Mip-level dimensions: floor-div-by-2 per level, min 1. + uint32_t mipW = std::max(1u, self->texture->width() >> uploadDesc.mipLevel); + uint32_t mipH = + std::max(1u, self->texture->height() >> uploadDesc.mipLevel); + if (uploadDesc.x > mipW || uploadDesc.width > mipW - uploadDesc.x) + { + luaL_error(L, + "upload: x+width (%u+%u) exceeds mip %u width %u", + uploadDesc.x, + uploadDesc.width, + uploadDesc.mipLevel, + mipW); + } + if (uploadDesc.y > mipH || uploadDesc.height > mipH - uploadDesc.y) + { + luaL_error(L, + "upload: y+height (%u+%u) exceeds mip %u height %u", + uploadDesc.y, + uploadDesc.height, + uploadDesc.mipLevel, + mipH); + } + + // Compute a tightly-packed bytesPerRow when the caller omits it. + if (uploadDesc.bytesPerRow == 0) + { + uint32_t bpt = textureFormatBytesPerTexel(self->texture->format()); + if (bpt == 0) + { + luaL_error(L, + "upload: bytesPerRow must be provided for " + "block-compressed formats"); + } + uploadDesc.bytesPerRow = uploadDesc.width * bpt; + } + + // Default rowsPerImage to height so Metal's bytesPerImage is correct. + if (uploadDesc.rowsPerImage == 0) + { + uploadDesc.rowsPerImage = uploadDesc.height; + } + + // Validate the data buffer is large enough to cover the region. + // GPUs read past the supplied bytes if we don't catch it here; on + // Metal the validation layer aborts, on others it's a silent OOB. + const uint64_t requiredBytes = + static_cast(uploadDesc.bytesPerRow) * + uploadDesc.rowsPerImage * std::max(1u, uploadDesc.depth); + if (len < requiredBytes) + { + luaL_error(L, + "upload: data buffer is %zu bytes but region requires " + "%llu (bytesPerRow=%u * rowsPerImage=%u * depth=%u)", + len, + static_cast(requiredBytes), + uploadDesc.bytesPerRow, + uploadDesc.rowsPerImage, + std::max(1u, uploadDesc.depth)); + } + + self->texture->upload(uploadDesc); + return 0; +} + +static int gputexture_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::view: + return gputexture_view(L); + case (int)LuaAtoms::upload: + return gputexture_upload(L); + } + } + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedGPUTexture::luaName); + return 0; +} + +static int gputexture_index(lua_State* L) +{ + auto* self = lua_torive(L, 1); + const char* key = luaL_checkstring(L, 2); + if (strcmp(key, "width") == 0) + { + lua_pushnumber(L, self->texture->width()); + return 1; + } + if (strcmp(key, "height") == 0) + { + lua_pushnumber(L, self->texture->height()); + return 1; + } + if (strcmp(key, "format") == 0) + { + lua_pushstring(L, lua_totextureformatstring(self->texture->format())); + return 1; + } + luaL_error(L, "%s is not a valid property of GPUTexture", key); + return 0; +} + +static int gputextureview_index(lua_State* L) +{ + auto* self = lua_torive(L, 1); + const char* key = luaL_checkstring(L, 2); + if (strcmp(key, "format") == 0) + { + if (self->view && self->view->texture()) + lua_pushstring( + L, + lua_totextureformatstring(self->view->texture()->format())); + else + lua_pushnil(L); + return 1; + } + luaL_error(L, "%s is not a valid property of GPUTextureView", key); + return 0; +} + +// ============================================================================ +// GPUSampler +// ============================================================================ + +static int gpusampler_construct(lua_State* L) +{ + if (getOreContext(L) == nullptr) + { + luaL_error(L, "GPU context not initialized"); + } + + SamplerDesc desc; + + if (lua_istable(L, 1)) + { + int descIdx = 1; + const char* s; + + s = lua_getoptionalstringfield(L, descIdx, "min"); + if (s) + desc.minFilter = lua_tofilter(L, s); + s = lua_getoptionalstringfield(L, descIdx, "mag"); + if (s) + desc.magFilter = lua_tofilter(L, s); + s = lua_getoptionalstringfield(L, descIdx, "mipmap"); + if (s) + desc.mipmapFilter = lua_tofilter(L, s); + s = lua_getoptionalstringfield(L, descIdx, "wrapU"); + if (s) + desc.wrapU = lua_towrapmode(L, s); + s = lua_getoptionalstringfield(L, descIdx, "wrapV"); + if (s) + desc.wrapV = lua_towrapmode(L, s); + s = lua_getoptionalstringfield(L, descIdx, "wrapW"); + if (s) + desc.wrapW = lua_towrapmode(L, s); + s = lua_getoptionalstringfield(L, descIdx, "compare"); + if (s) + desc.compare = lua_tocompare(L, s); + desc.minLod = static_cast( + lua_getoptionalnumberfield(L, descIdx, "minLod", 0.0)); + desc.maxLod = static_cast( + lua_getoptionalnumberfield(L, descIdx, "maxLod", 32.0)); + if (desc.minLod > desc.maxLod) + { + luaL_error(L, + "GPUSampler.new: minLod (%g) > maxLod (%g)", + desc.minLod, + desc.maxLod); + } + desc.maxAnisotropy = static_cast( + lua_getoptionalnumberfield(L, descIdx, "maxAnisotropy", 1)); + // WebGPU + every backend caps anisotropy at 16x and accepts only + // power-of-two values. Reject out-of-range early so a bad sampler + // doesn't cause a backend-specific create failure later. + const uint32_t a = desc.maxAnisotropy; + if (a < 1 || a > 16 || (a & (a - 1)) != 0) + { + luaL_error(L, + "GPUSampler.new: maxAnisotropy must be a power of " + "two in [1, 16] (got %u)", + a); + } + if (a > 1 && !getOreContext(L)->features().anisotropicFiltering) + { + luaL_error(L, + "GPUSampler.new: maxAnisotropy=%u requires " + "anisotropicFiltering feature, which the active " + "backend does not support", + a); + } + } + + auto* ctx = getOreContext(L); + ctx->clearLastError(); + auto sampler = ctx->makeSampler(desc); + if (!sampler) + { + if (!ctx->lastError().empty()) + luaL_error(L, "GPUSampler.new: %s", ctx->lastError().c_str()); + luaL_error(L, "GPUSampler.new: failed to create sampler"); + } + + auto* scripted = lua_newrive(L); + scripted->sampler = std::move(sampler); + return 1; +} + +// ============================================================================ +// GPUBindGroup +// ============================================================================ + +ScriptedGPUBindGroup::~ScriptedGPUBindGroup() +{ + // If the BindGroup has a context, defer its destruction until after + // endFrame() so the GPU is done with any command buffers referencing it. + // The rcp<> is moved into the context's deferred queue, keeping the + // BindGroup alive. When endFrame() clears the queue, refcount drops + // to zero and onRefCntReachedZero() does a simple delete. + if (bindGroup && bindGroup->context()) + { + bindGroup->context()->deferBindGroupDestroy(std::move(bindGroup)); + return; + } + // No context (or null) — drop immediately; rcp destructor handles it. +} + +// ============================================================================ +// GPUBindGroupLayout.new — explicit BindGroupLayout (Phase E). +// ============================================================================ + +// Map binding-map types to layout-entry types. These mirror the GM helper +// `makeLayoutFromShader` so Lua-built layouts validate the same way as +// C++-built ones. +static BindingKind bindingKindFromResource(ResourceKind k) +{ + switch (k) + { + case ResourceKind::UniformBuffer: + return BindingKind::uniformBuffer; + case ResourceKind::StorageBufferRO: + return BindingKind::storageBufferRO; + case ResourceKind::StorageBufferRW: + return BindingKind::storageBufferRW; + case ResourceKind::SampledTexture: + return BindingKind::sampledTexture; + case ResourceKind::StorageTexture: + return BindingKind::storageTexture; + case ResourceKind::Sampler: + return BindingKind::sampler; + case ResourceKind::ComparisonSampler: + return BindingKind::comparisonSampler; + } + return BindingKind::uniformBuffer; +} + +static TextureViewDimension viewDimFromBindingMap(TextureViewDim d) +{ + switch (d) + { + case TextureViewDim::Cube: + return TextureViewDimension::cube; + case TextureViewDim::CubeArray: + return TextureViewDimension::cubeArray; + case TextureViewDim::D3: + return TextureViewDimension::texture3D; + case TextureViewDim::D2Array: + return TextureViewDimension::array2D; + case TextureViewDim::D1: + case TextureViewDim::D2: + case TextureViewDim::Undefined: + return TextureViewDimension::texture2D; + } + return TextureViewDimension::texture2D; +} + +static BindGroupLayoutEntry::SampleType sampleTypeFromBindingMap( + TextureSampleType s) +{ + switch (s) + { + case TextureSampleType::UnfilterableFloat: + return BindGroupLayoutEntry::SampleType::floatUnfilterable; + case TextureSampleType::Depth: + return BindGroupLayoutEntry::SampleType::depth; + case TextureSampleType::Sint: + return BindGroupLayoutEntry::SampleType::sint; + case TextureSampleType::Uint: + return BindGroupLayoutEntry::SampleType::uint; + case TextureSampleType::Float: + case TextureSampleType::Undefined: + return BindGroupLayoutEntry::SampleType::floatFilterable; + } + return BindGroupLayoutEntry::SampleType::floatFilterable; +} + +// Walk a shader's BindingMap for the given group, populating layout entries +// with kind / visibility / texture metadata / native slots — the same path the +// GM helper takes. Returns the entry count actually filled. +static uint32_t populateEntriesFromShader(BindGroupLayoutEntry* entries, + uint32_t maxEntries, + const ore::ShaderModule* shader, + uint32_t group, + const uint32_t* dynamicUBOBindings, + uint32_t dynamicUBOCount) +{ + if (shader == nullptr) + return 0; + auto isDynamic = [&](uint32_t binding) -> bool { + for (uint32_t i = 0; i < dynamicUBOCount; ++i) + if (dynamicUBOBindings[i] == binding) + return true; + return false; + }; + const BindingMap& bm = shader->m_bindingMap; + uint32_t n = 0; + for (size_t i = 0; i < bm.size() && n < maxEntries; ++i) + { + const BindingMap::Entry& e = bm.at(i); + if (e.group != group) + continue; + BindGroupLayoutEntry& out = entries[n++]; + out.binding = e.binding; + out.kind = bindingKindFromResource(e.kind); + uint8_t vis = 0; + if (e.stageMask & BindingMap::kStageVertex) + vis |= StageVisibility::kVertex; + if (e.stageMask & BindingMap::kStageFragment) + vis |= StageVisibility::kFragment; + if (e.stageMask & BindingMap::kStageCompute) + vis |= StageVisibility::kCompute; + out.visibility.mask = vis; + out.hasDynamicOffset = + (out.kind == BindingKind::uniformBuffer && isDynamic(e.binding)); + out.textureViewDim = viewDimFromBindingMap(e.textureViewDim); + out.textureSampleType = sampleTypeFromBindingMap(e.textureSampleType); + out.textureMultisampled = e.textureMultisampled; + const uint16_t vs = + e.backendSlot[static_cast(BindingMap::Stage::VS)]; + const uint16_t fs = + e.backendSlot[static_cast(BindingMap::Stage::FS)]; + out.nativeSlotVS = (vs == BindingMap::kAbsent) + ? BindGroupLayoutEntry::kNativeSlotAbsent + : static_cast(vs); + out.nativeSlotFS = (fs == BindingMap::kAbsent) + ? BindGroupLayoutEntry::kNativeSlotAbsent + : static_cast(fs); + } + return n; +} + +static int gpubindgrouplayout_construct(lua_State* L) +{ + Context* oreCtx = getOreContext(L); + if (oreCtx == nullptr) + luaL_error(L, "GPU context not initialized"); + + luaL_checktype(L, 1, LUA_TTABLE); + int descIdx = 1; + + BindGroupLayoutDesc desc; + desc.groupIndex = static_cast( + lua_getoptionalnumberfield(L, descIdx, "groupIndex", 0)); + if (desc.groupIndex >= ore::kMaxBindGroups) + luaL_error(L, + "GPUBindGroupLayout.new: groupIndex must be in [0, %u)", + ore::kMaxBindGroups); + + // Resolve the source shader. Layouts must always derive from a shader + // module — Lua callers cannot meaningfully fill in `nativeSlotVS/FS` + // without the binding map, and getting kind/visibility wrong would + // fail validation anyway. + lua_getfield(L, descIdx, "shader"); + auto* scripted = lua_torive(L, -1); + lua_pop(L, 1); + if (scripted == nullptr || !scripted->module) + luaL_error(L, + "GPUBindGroupLayout.new: 'shader' must be a Shader with " + "a loaded module"); + + static constexpr int kMaxEntries = 16; + BindGroupLayoutEntry entries[kMaxEntries]{}; + + // Optional `dynamicUBOs`: array of WGSL @binding values whose UBO + // entries should set hasDynamicOffset. + uint32_t dynUBOs[kMaxEntries] = {}; + uint32_t dynUBOCount = 0; + lua_getfield(L, descIdx, "dynamicUBOs"); + if (lua_istable(L, -1)) + { + int dynTbl = lua_gettop(L); + int dynN = (int)lua_objlen(L, dynTbl); + for (int i = 0; i < dynN && dynUBOCount < kMaxEntries; ++i) + { + lua_rawgeti(L, dynTbl, i + 1); + if (lua_isnumber(L, -1)) + dynUBOs[dynUBOCount++] = + static_cast(lua_tonumber(L, -1)); + lua_pop(L, 1); + } + } + lua_pop(L, 1); // dynamicUBOs + + // Vertex module carries the merged binding map for both stages — + // the same module the GM helper walks. + uint32_t entryCount = populateEntriesFromShader(entries, + kMaxEntries, + scripted->vertexMod(), + desc.groupIndex, + dynUBOs, + dynUBOCount); + + desc.entries = entries; + desc.entryCount = entryCount; + + rcp layout = oreCtx->makeBindGroupLayout(desc); + if (!layout) + { + const std::string& err = oreCtx->lastError(); + oreCtx->clearLastError(); + luaL_error(L, + "GPUBindGroupLayout.new: %s", + err.empty() ? "failed" : err.c_str()); + } + + auto* w = lua_newrive(L); + w->layout = std::move(layout); + return 1; +} + +static int gpubindgroup_construct(lua_State* L) +{ + Context* oreCtx = getOreContext(L); + if (oreCtx == nullptr) + { + luaL_error(L, "GPU context not initialized"); + } + + luaL_checktype(L, 1, LUA_TTABLE); + int descIdx = 1; + + BindGroupDesc desc; + + // layout (required) — replaces the legacy `pipeline` field. The + // BindGroup is built against a BindGroupLayout (Phase E); the + // layout's groupIndex determines which @group(N) the BindGroup + // binds to. + lua_getfield(L, descIdx, "layout"); + auto* layoutScripted = lua_torive(L, -1); + if (layoutScripted == nullptr) + { + luaL_error(L, + "GPUBindGroup.new: 'layout' field is required and must be " + "a GPUBindGroupLayout"); + } + desc.layout = layoutScripted->layout.get(); + lua_pop(L, 1); + + // Parse UBO entries + static constexpr int MAX_ENTRIES = 8; + BindGroupDesc::UBOEntry uboEntries[MAX_ENTRIES]; + uint32_t uboCount = 0; + + lua_getfield(L, descIdx, "ubos"); + if (lua_istable(L, -1)) + { + int tbl = lua_gettop(L); + int n = (int)lua_objlen(L, tbl); + for (int i = 0; i < n && i < MAX_ENTRIES; i++) + { + lua_rawgeti(L, tbl, i + 1); + int entry = lua_gettop(L); + + uboEntries[uboCount].slot = static_cast( + lua_getoptionalnumberfield(L, entry, "slot", 0)); + if (uboEntries[uboCount].slot > 7) + { + luaL_error(L, + "GPUBindGroup.new: UBO slot must be 0-7 (got %u)", + uboEntries[uboCount].slot); + } + + lua_getfield(L, entry, "buffer"); + auto* bufScripted = lua_torive(L, -1); + uboEntries[uboCount].buffer = bufScripted->buffer.get(); + lua_pop(L, 1); + + uboEntries[uboCount].offset = static_cast( + lua_getoptionalnumberfield(L, entry, "offset", 0)); + uboEntries[uboCount].size = static_cast( + lua_getoptionalnumberfield(L, entry, "size", 0)); + + lua_pop(L, 1); // entry table + uboCount++; + } + } + lua_pop(L, 1); + desc.ubos = uboEntries; + desc.uboCount = uboCount; + + // Parse texture entries + BindGroupDesc::TexEntry texEntries[MAX_ENTRIES]; + uint32_t texCount = 0; + + lua_getfield(L, descIdx, "textures"); + if (lua_istable(L, -1)) + { + int tbl = lua_gettop(L); + int n = (int)lua_objlen(L, tbl); + for (int i = 0; i < n && i < MAX_ENTRIES; i++) + { + lua_rawgeti(L, tbl, i + 1); + int entry = lua_gettop(L); + + texEntries[texCount].slot = static_cast( + lua_getoptionalnumberfield(L, entry, "slot", 0)); + if (texEntries[texCount].slot > 7) + { + luaL_error( + L, + "GPUBindGroup.new: texture slot must be 0-7 (got %u)", + texEntries[texCount].slot); + } + + lua_getfield(L, entry, "view"); + auto* tv = lua_torive(L, -1); + texEntries[texCount].view = tv->view.get(); + lua_pop(L, 1); + + lua_pop(L, 1); // entry table + texCount++; + } + } + lua_pop(L, 1); + desc.textures = texEntries; + desc.textureCount = texCount; + + // Parse sampler entries + BindGroupDesc::SampEntry sampEntries[MAX_ENTRIES]; + uint32_t sampCount = 0; + + lua_getfield(L, descIdx, "samplers"); + if (lua_istable(L, -1)) + { + int tbl = lua_gettop(L); + int n = (int)lua_objlen(L, tbl); + for (int i = 0; i < n && i < MAX_ENTRIES; i++) + { + lua_rawgeti(L, tbl, i + 1); + int entry = lua_gettop(L); + + sampEntries[sampCount].slot = static_cast( + lua_getoptionalnumberfield(L, entry, "slot", 0)); + if (sampEntries[sampCount].slot > 7) + { + luaL_error( + L, + "GPUBindGroup.new: sampler slot must be 0-7 (got %u)", + sampEntries[sampCount].slot); + } + + lua_getfield(L, entry, "sampler"); + auto* ss = lua_torive(L, -1); + sampEntries[sampCount].sampler = ss->sampler.get(); + lua_pop(L, 1); + + lua_pop(L, 1); // entry table + sampCount++; + } + } + lua_pop(L, 1); + desc.samplers = sampEntries; + desc.samplerCount = sampCount; + + oreCtx->clearLastError(); + auto bindGroup = oreCtx->makeBindGroup(desc); + if (!bindGroup) + { + if (!oreCtx->lastError().empty()) + luaL_error(L, "GPUBindGroup.new: %s", oreCtx->lastError().c_str()); + luaL_error(L, "GPUBindGroup.new: failed to create bind group"); + } + + auto* scripted = lua_newrive(L); + scripted->bindGroup = std::move(bindGroup); + return 1; +} + +// ============================================================================ +// GPUPipeline +// ============================================================================ + +static int gpupipeline_construct(lua_State* L) +{ + if (getOreContext(L) == nullptr) + { + luaL_error(L, "GPU context not initialized"); + } + + luaL_checktype(L, 1, LUA_TTABLE); + int descIdx = 1; + + PipelineDesc desc; + + // vertex shader (required) + lua_getfield(L, descIdx, "vertex"); + auto* vs = lua_torive(L, -1); + desc.vertexModule = vs->vertexMod(); + lua_pop(L, 1); + + // fragment shader. Three cases: + // * explicit `fragment` Shader → use its fragment module. + // * absent + at least one colorTarget → fall back to vs's fragment + // module (combined-shader file with both vs_main and fs_main). + // * absent + no colorTargets → depth-only pipeline, no fragment. + // Case 3 resolution is deferred until after colorTargets is parsed. + bool explicitFragment = false; + lua_getfield(L, descIdx, "fragment"); + if (!lua_isnil(L, -1)) + { + auto* fs = lua_torive(L, -1); + desc.fragmentModule = fs->fragmentMod(); + explicitFragment = true; + } + lua_pop(L, 1); + + // vertexLayout (required) + lua_getfield(L, descIdx, "vertexLayout"); + luaL_checktype(L, -1, LUA_TTABLE); + int layoutTableIdx = lua_gettop(L); + int vbCount = (int)lua_objlen(L, layoutTableIdx); + + // Stack-allocate vertex buffer layouts and attributes + static constexpr int MAX_VB = 8; + static constexpr int MAX_ATTRS = 32; + VertexBufferLayout vbLayouts[MAX_VB]; + VertexAttribute attrs[MAX_ATTRS]; + int totalAttrs = 0; + + for (int vb = 0; vb < vbCount && vb < MAX_VB; vb++) + { + lua_rawgeti(L, layoutTableIdx, vb + 1); + int vbIdx = lua_gettop(L); + + vbLayouts[vb].stride = static_cast( + lua_getoptionalnumberfield(L, vbIdx, "stride", 0)); + + const char* stepMode = lua_getoptionalstringfield(L, vbIdx, "stepMode"); + if (stepMode && strcmp(stepMode, "instance") == 0) + vbLayouts[vb].stepMode = VertexStepMode::instance; + else + vbLayouts[vb].stepMode = VertexStepMode::vertex; + + lua_getfield(L, vbIdx, "attributes"); + int attrTableIdx = lua_gettop(L); + int attrCount = (int)lua_objlen(L, attrTableIdx); + + vbLayouts[vb].attributes = &attrs[totalAttrs]; + vbLayouts[vb].attributeCount = attrCount; + + for (int a = 0; a < attrCount && totalAttrs < MAX_ATTRS; a++) + { + lua_rawgeti(L, attrTableIdx, a + 1); + int attrIdx = lua_gettop(L); + + const char* fmt = lua_getoptionalstringfield(L, attrIdx, "format"); + if (fmt) + attrs[totalAttrs].format = lua_tovertexformat(L, fmt); + + attrs[totalAttrs].shaderSlot = static_cast( + lua_getoptionalnumberfield(L, attrIdx, "slot", 0)); + attrs[totalAttrs].offset = static_cast( + lua_getoptionalnumberfield(L, attrIdx, "offset", 0)); + + totalAttrs++; + lua_pop(L, 1); // pop attr entry + } + lua_pop(L, 1); // pop attributes table + lua_pop(L, 1); // pop vb entry + } + lua_pop(L, 1); // pop vertexLayout table + + // colorTargets (optional). WebGPU-shaped: omitting it means "no color + // outputs" (depth-only pipeline, e.g. shadow map). We override the C++ + // PipelineDesc default of colorCount=1 so that scripts don't get a + // phantom color target that mismatches a depth-only render pass. + desc.colorCount = 0; + lua_getfield(L, descIdx, "colorTargets"); + if (lua_istable(L, -1)) + { + int ctTableIdx = lua_gettop(L); + int ctCount = (int)lua_objlen(L, ctTableIdx); + constexpr int kMaxColorTargets = + sizeof(desc.colorTargets) / sizeof(desc.colorTargets[0]); + if (ctCount > kMaxColorTargets) + { + luaL_error(L, + "GPUPipeline.new: colorTargets count %d exceeds " + "maximum of %d", + ctCount, + kMaxColorTargets); + } + desc.colorCount = ctCount; + + for (int ct = 0; ct < ctCount; ct++) + { + lua_rawgeti(L, ctTableIdx, ct + 1); + int ctIdx = lua_gettop(L); + + const char* fmt = lua_getoptionalstringfield(L, ctIdx, "format"); + if (fmt) + desc.colorTargets[ct].format = lua_totextureformat(L, fmt); + + // writeMask: optional. String like "rgba" / "rg" / "" / "all". + // Default (when absent) is `ColorWriteMask::all` from PipelineDesc. + const char* wm = lua_getoptionalstringfield(L, ctIdx, "writeMask"); + if (wm) + desc.colorTargets[ct].writeMask = lua_towritemask(L, wm); + + lua_getfield(L, ctIdx, "blend"); + if (lua_istable(L, -1)) + { + int blendIdx = lua_gettop(L); + desc.colorTargets[ct].blendEnabled = true; + const char* s; + + s = lua_getoptionalstringfield(L, blendIdx, "srcColor"); + if (s) + desc.colorTargets[ct].blend.srcColor = + lua_toblendfactor(L, s); + s = lua_getoptionalstringfield(L, blendIdx, "dstColor"); + if (s) + desc.colorTargets[ct].blend.dstColor = + lua_toblendfactor(L, s); + s = lua_getoptionalstringfield(L, blendIdx, "colorOp"); + if (s) + desc.colorTargets[ct].blend.colorOp = lua_toblendop(L, s); + s = lua_getoptionalstringfield(L, blendIdx, "srcAlpha"); + if (s) + desc.colorTargets[ct].blend.srcAlpha = + lua_toblendfactor(L, s); + s = lua_getoptionalstringfield(L, blendIdx, "dstAlpha"); + if (s) + desc.colorTargets[ct].blend.dstAlpha = + lua_toblendfactor(L, s); + s = lua_getoptionalstringfield(L, blendIdx, "alphaOp"); + if (s) + desc.colorTargets[ct].blend.alphaOp = lua_toblendop(L, s); + } + lua_pop(L, 1); // pop blend + lua_pop(L, 1); // pop color target entry + } + } + lua_pop(L, 1); // pop colorTargets + + // Resolve the deferred fragment-module decision (see "fragment shader" + // block above). With color outputs but no explicit fragment shader, + // fall back to the vertex shader's fragment module (combined file). + if (!explicitFragment && desc.colorCount > 0) + desc.fragmentModule = vs->fragmentMod(); + + // depthStencil (optional) + lua_getfield(L, descIdx, "depthStencil"); + if (lua_istable(L, -1)) + { + int dsIdx = lua_gettop(L); + const char* fmt = lua_getoptionalstringfield(L, dsIdx, "format"); + if (fmt) + desc.depthStencil.format = lua_totextureformat(L, fmt); + const char* cmp = lua_getoptionalstringfield(L, dsIdx, "compare"); + if (cmp) + desc.depthStencil.depthCompare = lua_tocompare(L, cmp); + desc.depthStencil.depthWriteEnabled = + lua_getoptionalboolfield(L, dsIdx, "write", false); + desc.depthStencil.depthBias = static_cast( + lua_getoptionalnumberfield(L, dsIdx, "depthBias", 0)); + desc.depthStencil.depthBiasSlopeScale = static_cast( + lua_getoptionalnumberfield(L, dsIdx, "depthBiasSlopeScale", 0)); + desc.depthStencil.depthBiasClamp = static_cast( + lua_getoptionalnumberfield(L, dsIdx, "depthBiasClamp", 0)); + } + lua_pop(L, 1); + + // stencilFront / stencilBack (optional, both default to "always pass, + // keep on every op"). Each is a table of compare + failOp + depthFailOp + // + passOp strings. + lua_getfield(L, descIdx, "stencilFront"); + lua_tostencilface(L, lua_gettop(L), &desc.stencilFront); + lua_pop(L, 1); + lua_getfield(L, descIdx, "stencilBack"); + lua_tostencilface(L, lua_gettop(L), &desc.stencilBack); + lua_pop(L, 1); + + // stencilReadMask / stencilWriteMask (optional, default 0xFF). + desc.stencilReadMask = static_cast( + lua_getoptionalnumberfield(L, descIdx, "stencilReadMask", 0xFF)); + desc.stencilWriteMask = static_cast( + lua_getoptionalnumberfield(L, descIdx, "stencilWriteMask", 0xFF)); + + // bindGroupLayouts (optional). When absent, derive layouts per + // @group(N) from the shader's binding map (WebGPU's `layout: 'auto'`). + // Supply explicitly to share one layout across multiple pipelines. + BindGroupLayout* layoutPtrs[ore::kMaxBindGroups] = {}; + uint32_t layoutCount = 0; + std::vector> autoLayouts; + lua_getfield(L, descIdx, "bindGroupLayouts"); + bool explicitLayouts = lua_istable(L, -1); + if (explicitLayouts) + { + int blglIdx = lua_gettop(L); + int n = (int)lua_objlen(L, blglIdx); + if (n > static_cast(ore::kMaxBindGroups)) + { + luaL_error(L, + "GPUPipeline.new: bindGroupLayouts count %d exceeds " + "maximum of %u", + n, + ore::kMaxBindGroups); + } + for (int i = 0; i < n; ++i) + { + lua_rawgeti(L, blglIdx, i + 1); + auto* l = lua_torive(L, -1); + layoutPtrs[i] = l ? l->layout.get() : nullptr; + lua_pop(L, 1); + } + layoutCount = static_cast(n); + } + lua_pop(L, 1); + if (!explicitLayouts) + { + // Auto path: scan the binding map for unique groups, build a + // layout per group. Sparse-group shaders are supported (e.g. + // group 0 + group 2 → autoLayouts[1] is null/empty). + const BindingMap& bm = vs->vertexMod()->m_bindingMap; + uint32_t maxGroup = 0; + bool seen[ore::kMaxBindGroups] = {}; + for (size_t i = 0; i < bm.size(); ++i) + { + uint32_t g = bm.at(i).group; + if (g >= ore::kMaxBindGroups) + continue; + seen[g] = true; + if (g + 1 > maxGroup) + maxGroup = g + 1; + } + autoLayouts.resize(maxGroup); + static constexpr int kMaxEntries = 16; + for (uint32_t g = 0; g < maxGroup; ++g) + { + if (!seen[g]) + continue; + BindGroupLayoutEntry entries[kMaxEntries]{}; + uint32_t n = populateEntriesFromShader(entries, + kMaxEntries, + vs->vertexMod(), + g, + nullptr, + 0); + BindGroupLayoutDesc lDesc; + lDesc.groupIndex = g; + lDesc.entries = entries; + lDesc.entryCount = n; + autoLayouts[g] = getOreContext(L)->makeBindGroupLayout(lDesc); + layoutPtrs[g] = autoLayouts[g].get(); + } + layoutCount = maxGroup; + } + desc.bindGroupLayouts = layoutPtrs; + desc.bindGroupLayoutCount = layoutCount; + + // cullMode (optional) + const char* cull = lua_getoptionalstringfield(L, descIdx, "cullMode"); + if (cull) + desc.cullMode = lua_tocullmode(L, cull); + + // winding (optional, default counterClockwise) + const char* wind = lua_getoptionalstringfield(L, descIdx, "winding"); + if (wind) + desc.winding = lua_towinding(L, wind); + + // topology (optional) + const char* topo = lua_getoptionalstringfield(L, descIdx, "topology"); + if (topo) + desc.topology = lua_totopology(L, topo); + + // sampleCount (optional, default 1) + uint32_t pipelineSampleCount = static_cast( + lua_getoptionalnumberfield(L, descIdx, "sampleCount", 1)); + desc.sampleCount = pipelineSampleCount; + + // Allocate the ScriptedGPUPipeline first so we can deep-copy the vertex + // layout data into it. Pipeline shallow-copies PipelineDesc, so the + // vertex buffer layout pointers must outlive the Pipeline. + auto* scripted = lua_newrive(L); + + // Deep-copy layouts and attributes into a single byte buffer: + // [ VertexBufferLayout[vbCount] ][ VertexAttribute[totalAttrs] ] + size_t layoutBytes = sizeof(VertexBufferLayout) * vbCount; + size_t attrBytes = sizeof(VertexAttribute) * totalAttrs; + scripted->ownedVertexLayoutData.resize(layoutBytes + attrBytes); + + auto* ownedLayouts = reinterpret_cast( + scripted->ownedVertexLayoutData.data()); + auto* ownedAttrs = reinterpret_cast( + scripted->ownedVertexLayoutData.data() + layoutBytes); + + memcpy(ownedLayouts, vbLayouts, layoutBytes); + memcpy(ownedAttrs, attrs, attrBytes); + + // Patch each layout's attributes pointer to point into the owned copy. + int attrOffset = 0; + for (int vb = 0; vb < vbCount; vb++) + { + ownedLayouts[vb].attributes = ownedAttrs + attrOffset; + attrOffset += ownedLayouts[vb].attributeCount; + } + + desc.vertexBuffers = ownedLayouts; + desc.vertexBufferCount = vbCount; + + std::string pipelineError; + auto pipeline = getOreContext(L)->makePipeline(desc, &pipelineError); + if (!pipeline) + { + if (pipelineError.empty()) + luaL_error(L, "GPUPipeline.new: failed to create pipeline"); + else + luaL_error(L, "GPUPipeline.new: %s", pipelineError.c_str()); + } + + scripted->pipeline = std::move(pipeline); + scripted->sampleCount = pipelineSampleCount; + scripted->autoBindGroupLayouts = std::move(autoLayouts); + return 1; +} + +// pipeline:getBindGroupLayout(groupIndex) — returns an auto-derived layout +// (WebGPU's pipeline.getBindGroupLayout). Errors when explicit layouts were +// supplied — share the explicit one directly instead. +static int gpupipeline_getbindgrouplayout(lua_State* L) +{ + auto* self = lua_torive(L, 1); + uint32_t group = static_cast(luaL_checkunsigned(L, 2)); + if (self->autoBindGroupLayouts.empty()) + luaL_error(L, + "getBindGroupLayout: pipeline was built with explicit " + "bindGroupLayouts; reuse the layout you supplied"); + if (group >= self->autoBindGroupLayouts.size() || + !self->autoBindGroupLayouts[group]) + luaL_error(L, + "getBindGroupLayout: group %u not present in shader", + group); + auto* w = lua_newrive(L); + w->layout = self->autoBindGroupLayouts[group]; + return 1; +} + +static int gpupipeline_namecall(lua_State* L) +{ + int atom; + const char* method = lua_namecallatom(L, &atom); + if (method == nullptr) + luaL_error(L, "GPUPipeline: no method specified"); + if (strcmp(method, "getBindGroupLayout") == 0) + return gpupipeline_getbindgrouplayout(L); + luaL_error(L, "GPUPipeline: unknown method '%s'", method); + return 0; +} + +// ============================================================================ +// GPURenderPass +// ============================================================================ + +static void validate_render_pass(lua_State* L, ScriptedGPURenderPass* self) +{ + if (self->m_finished || self->pass == nullptr) + { + luaL_error(L, "render pass expired — call finish() only once"); + } +} + +static void validate_pipeline_set(lua_State* L, ScriptedGPURenderPass* self) +{ + if (!self->m_pipelineSet) + { + luaL_error(L, + "setPipeline must be called before draw/setVertexBuffer/" + "setBindGroup"); + } +} + +static int gpurenderpass_setpipeline(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + auto* pipeline = lua_torive(L, 2); + if (pipeline->sampleCount != self->sampleCount) + { + luaL_error(L, + "pipeline sampleCount (%u) does not match render pass " + "sampleCount (%u) — recreate the pipeline with matching " + "sampleCount", + pipeline->sampleCount, + self->sampleCount); + } + // Capture any attachment-compat failure from ore::RenderPass::setPipeline. + // Without this, checkPipelineCompat failures silently no-op the Metal + // encoder state and subsequent draws crash inside the driver. + Context* oreCtx = getOreContext(L); + if (oreCtx) + oreCtx->clearLastError(); + self->pass->setPipeline(pipeline->pipeline.get()); + if (oreCtx && !oreCtx->lastError().empty()) + { + luaL_error(L, "setPipeline: %s", oreCtx->lastError().c_str()); + } + self->m_pipelineSet = true; + return 0; +} + +static int gpurenderpass_setvertexbuffer(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + // Note: WebGPU / Metal / Vulkan / D3D11 all permit `setVertexBuffer` + // before `setPipeline` — vertex-buffer state is layered onto whatever + // pipeline is current at draw time. Don't gate on `m_pipelineSet`. + uint32_t slot = static_cast(luaL_checkunsigned(L, 2)); + if (slot > 7) + { + luaL_error(L, "setVertexBuffer: slot must be 0-7 (got %u)", slot); + } + auto* buffer = lua_torive(L, 3); + self->pass->setVertexBuffer(slot, buffer->buffer.get()); + return 0; +} + +static int gpurenderpass_setindexbuffer(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + auto* buffer = lua_torive(L, 2); + IndexFormat fmt = IndexFormat::uint16; + if (lua_isstring(L, 3)) + { + const char* s = lua_tostring(L, 3); + if (strcmp(s, "uint32") == 0) + fmt = IndexFormat::uint32; + } + self->pass->setIndexBuffer(buffer->buffer.get(), fmt); + return 0; +} + +static int gpurenderpass_setbindgroup(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + uint32_t groupIndex = static_cast(luaL_checkunsigned(L, 2)); + if (groupIndex >= ore::kMaxBindGroups) + { + luaL_error(L, + "setBindGroup: groupIndex must be in [0, %u) (got %u)", + ore::kMaxBindGroups, + groupIndex); + } + auto* bg = lua_torive(L, 3); + + // Parse optional dynamic offsets array. + // + // WebGPU contract: `dynamicOffsets[i]` corresponds to the i-th dynamic + // entry in the BindGroupLayout, ordered by ascending `@binding`. + // The count must equal the BindGroup's dynamic-offset count exactly, + // and each value must be aligned to `minUniformBufferOffsetAlignment` + // (256 bytes — D3D11.1's `firstConstant` requirement, D3D12's CBV + // alignment, Vulkan's adapter-default minimum). Validate here so a + // misuse error surfaces on the Lua call site instead of a backend + // assert / silent misbind. + constexpr uint32_t kDynamicOffsetAlign = 256; + uint32_t dynamicOffsets[8] = {}; + uint32_t dynamicOffsetCount = 0; + if (lua_istable(L, 4)) + { + int tbl = 4; + int n = (int)lua_objlen(L, tbl); + if (n > 8) + { + luaL_error(L, + "setBindGroup: dynamicOffsets count %d exceeds " + "maximum of 8", + n); + } + for (int i = 0; i < n; i++) + { + lua_rawgeti(L, tbl, i + 1); + uint32_t off = static_cast(lua_tonumber(L, -1)); + lua_pop(L, 1); + if ((off % kDynamicOffsetAlign) != 0) + { + luaL_error(L, + "setBindGroup: dynamicOffsets[%d] = %u is not a " + "multiple of %u (alignment requirement)", + i, + off, + kDynamicOffsetAlign); + } + dynamicOffsets[dynamicOffsetCount++] = off; + } + } + + if (bg->bindGroup && + dynamicOffsetCount != bg->bindGroup->dynamicOffsetCount()) + { + luaL_error(L, + "setBindGroup: dynamicOffsets count %u does not match the " + "BindGroup's declared dynamic UBO count %u", + dynamicOffsetCount, + bg->bindGroup->dynamicOffsetCount()); + } + + self->pass->setBindGroup(groupIndex, + bg->bindGroup.get(), + dynamicOffsetCount > 0 ? dynamicOffsets : nullptr, + dynamicOffsetCount); + return 0; +} + +static int gpurenderpass_setviewport(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + float x = static_cast(luaL_checknumber(L, 2)); + float y = static_cast(luaL_checknumber(L, 3)); + float w = static_cast(luaL_checknumber(L, 4)); + float h = static_cast(luaL_checknumber(L, 5)); + self->pass->setViewport(x, y, w, h); + return 0; +} + +static int gpurenderpass_setscissorrect(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + uint32_t x = static_cast(luaL_checkunsigned(L, 2)); + uint32_t y = static_cast(luaL_checkunsigned(L, 3)); + uint32_t w = static_cast(luaL_checkunsigned(L, 4)); + uint32_t h = static_cast(luaL_checkunsigned(L, 5)); + self->pass->setScissorRect(x, y, w, h); + return 0; +} + +static int gpurenderpass_setstencilreference(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + uint32_t ref = static_cast(luaL_checkunsigned(L, 2)); + self->pass->setStencilReference(ref); + return 0; +} + +static int gpurenderpass_setblendcolor(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + float r = static_cast(luaL_checknumber(L, 2)); + float g = static_cast(luaL_checknumber(L, 3)); + float b = static_cast(luaL_checknumber(L, 4)); + float a = static_cast(luaL_checknumber(L, 5)); + self->pass->setBlendColor(r, g, b, a); + return 0; +} + +// `pass:draw(vertexCount [, instanceCount [, firstVertex +// [, firstInstance]]])` +static int gpurenderpass_draw(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + validate_pipeline_set(L, self); + uint32_t vertexCount = static_cast(luaL_checkunsigned(L, 2)); + uint32_t instanceCount = + lua_isnumber(L, 3) ? static_cast(lua_tonumber(L, 3)) : 1; + uint32_t firstVertex = + lua_isnumber(L, 4) ? static_cast(lua_tonumber(L, 4)) : 0; + uint32_t firstInstance = + lua_isnumber(L, 5) ? static_cast(lua_tonumber(L, 5)) : 0; + if (firstInstance > 0 && !getOreContext(L)->features().drawBaseInstance) + { + luaL_error(L, + "draw: firstInstance=%u requires the drawBaseInstance " + "feature, which the active backend does not support", + firstInstance); + } + self->pass->draw(vertexCount, instanceCount, firstVertex, firstInstance); + self->drawCallCount++; + return 0; +} + +// `pass:drawIndexed(indexCount [, instanceCount [, firstIndex +// [, baseVertex [, firstInstance]]]])` +static int gpurenderpass_drawindexed(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + validate_pipeline_set(L, self); + uint32_t indexCount = static_cast(luaL_checkunsigned(L, 2)); + uint32_t instanceCount = + lua_isnumber(L, 3) ? static_cast(lua_tonumber(L, 3)) : 1; + uint32_t firstIndex = + lua_isnumber(L, 4) ? static_cast(lua_tonumber(L, 4)) : 0; + int32_t baseVertex = + lua_isnumber(L, 5) ? static_cast(lua_tointeger(L, 5)) : 0; + uint32_t firstInstance = + lua_isnumber(L, 6) ? static_cast(lua_tonumber(L, 6)) : 0; + if (firstInstance > 0 && !getOreContext(L)->features().drawBaseInstance) + { + luaL_error(L, + "drawIndexed: firstInstance=%u requires the " + "drawBaseInstance feature, which the active backend " + "does not support", + firstInstance); + } + self->pass->drawIndexed(indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); + self->drawCallCount++; + return 0; +} + +static int gpurenderpass_finish(lua_State* L) +{ + auto* self = lua_torive(L, 1); + validate_render_pass(L, self); + self->pass->finish(); + self->m_finished = true; + // Clear the context's active pass pointer so the next beginRenderPass + // doesn't see a stale (already-finished) pass. + Context* oreCtx = getOreContext(L); + if (oreCtx && oreCtx->activeRenderPass() == self->pass) + oreCtx->setActiveRenderPass(nullptr); + return 0; +} + +static int gpurenderpass_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::setPipeline: + return gpurenderpass_setpipeline(L); + case (int)LuaAtoms::setVertexBuffer: + return gpurenderpass_setvertexbuffer(L); + case (int)LuaAtoms::setIndexBuffer: + return gpurenderpass_setindexbuffer(L); + case (int)LuaAtoms::setBindGroup: + return gpurenderpass_setbindgroup(L); + case (int)LuaAtoms::setViewport: + return gpurenderpass_setviewport(L); + case (int)LuaAtoms::setScissorRect: + return gpurenderpass_setscissorrect(L); + case (int)LuaAtoms::setStencilReference: + return gpurenderpass_setstencilreference(L); + case (int)LuaAtoms::setBlendColor: + return gpurenderpass_setblendcolor(L); + case (int)LuaAtoms::draw: + return gpurenderpass_draw(L); + case (int)LuaAtoms::drawIndexed: + return gpurenderpass_drawindexed(L); + case (int)LuaAtoms::finish: + return gpurenderpass_finish(L); + } + } + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedGPURenderPass::luaName); + return 0; +} + +// ============================================================================ +// ScriptedGPUCanvas / ScriptedCanvas — destructors +// ============================================================================ + +ScriptedGPUCanvas::~ScriptedGPUCanvas() +{ + delete m_activePass; + m_activePass = nullptr; + if (m_L != nullptr && m_imageRef != LUA_NOREF) + { + lua_unref(m_L, m_imageRef); + } +} + +ScriptedGPURenderPass::~ScriptedGPURenderPass() +{ + if (m_L != nullptr && m_canvasRef != LUA_NOREF) + { + lua_unref(m_L, m_canvasRef); + } +} + +ScriptedCanvas::~ScriptedCanvas() +{ + // Clean up any active frame renderer that was never ended + delete m_riveRenderer; + m_riveRenderer = nullptr; + if (m_L != nullptr) + { + if (m_rendererRef != LUA_NOREF) + lua_unref(m_L, m_rendererRef); + if (m_imageRef != LUA_NOREF) + lua_unref(m_L, m_imageRef); + } +} + +// ============================================================================ +// GPUCanvas +// ============================================================================ + +static LoadOp lua_toloadop_str(const char* s) +{ + if (strcmp(s, "load") == 0) + return LoadOp::load; + return LoadOp::clear; +} + +static StoreOp lua_tostoreop_str(const char* s) +{ + if (strcmp(s, "discard") == 0) + return StoreOp::discard; + return StoreOp::store; +} + +static int gpucanvashandle_beginrenderpass(lua_State* L) +{ + auto* self = lua_torive(L, 1); + if (!self->oreColorView) + { + luaL_error(L, "GPUCanvas has no color view"); + } + if (getOreContext(L) == nullptr) + { + luaL_error(L, "GPU context not initialized"); + } + + auto* scriptingContext = + static_cast(lua_getthreaddata(L)); + if (scriptingContext == nullptr || !scriptingContext->canvasDrawingPhase()) + { + luaL_error(L, + "GPUCanvas:beginRenderPass() called outside drawing phase"); + } + + RenderPassDesc passDesc{}; + passDesc.colorCount = 1; + // Default: if the canvas has an MSAA color texture, render into it and + // resolve to the 1× platform backing; otherwise render directly to it. + if (self->oreMSAAColorView) + { + passDesc.colorAttachments[0].view = self->oreMSAAColorView.get(); + passDesc.colorAttachments[0].resolveTarget = self->oreColorView.get(); + passDesc.colorAttachments[0].storeOp = StoreOp::discard; + } + else + { + passDesc.colorAttachments[0].view = self->oreColorView.get(); + } + passDesc.colorAttachments[0].loadOp = LoadOp::clear; + + uint32_t passSampleCount = + self->oreMSAAColorView ? self->oreMSAAColorTexture->sampleCount() : 1; + + // Parse optional descriptor table + if (lua_gettop(L) >= 2 && lua_istable(L, 2)) + { + lua_getfield(L, 2, "color"); + if (lua_isnil(L, -1)) + { + // Descriptor provided but no 'color' key — caller wants a + // depth-only pass (e.g. shadow map). Drop the default canvas + // color attachment so the render pass matches pipelines that + // have no color outputs. + passDesc.colorCount = 0; + // Fall through to the lua_pop(L, 1) below (don't pop here). + } + else if (lua_istable(L, -1)) + { + // color is an array of attachment descriptor tables. Each entry + // Each entry is an attachment descriptor table. Supported fields: + // view: GPUTextureView? — overrides the default canvas view + // resolveTarget: GPUTextureView? — 1× resolve (for MSAA) + // loadOp: LoadOp? + // storeOp: StoreOp? — use 'discard' on MSAA color + // clearColor: {r, g, b, a}? + passDesc.colorCount = 0; + for (int ci = 1; ci <= 4; ++ci) + { + lua_rawgeti(L, -1, ci); + if (!lua_istable(L, -1)) + { + lua_pop(L, 1); + break; + } + int slot = passDesc.colorCount++; + + // Optional explicit TextureView override + lua_getfield(L, -1, "view"); + if (!lua_isnil(L, -1)) + { + auto* tv = lua_torive(L, -1); + if (tv && tv->view) + { + passDesc.colorAttachments[slot].view = tv->view.get(); + if (slot == 0) + passSampleCount = + tv->view->texture()->sampleCount(); + } + } + lua_pop(L, 1); // view + + // Default view for slot 0 is the canvas itself; other slots + // require an explicit view from the descriptor. This + // mirrors the depthStencil-attachment shape below — both + // depth and color slot 1+ surface a clear error when no + // view is supplied, so a malformed `colorAttachments` + // table can't silently truncate the pass to fewer + // attachments than declared. + if (passDesc.colorAttachments[slot].view == nullptr) + { + if (slot == 0) + { + passDesc.colorAttachments[0].view = + self->oreColorView.get(); + } + else + { + luaL_error(L, + "beginRenderPass: colorAttachments[%d] " + "has no `view` field — slot %d requires " + "an explicit GPUTextureView (only slot 0 " + "defaults to the canvas color view)", + slot + 1, + slot); + } + } + + // resolveTarget (optional — for MSAA) + lua_getfield(L, -1, "resolveTarget"); + if (!lua_isnil(L, -1)) + { + auto* tv = lua_torive(L, -1); + if (tv && tv->view) + { + // Validate: resolveTarget format must match the MSAA + // attachment format. Metal/Vulkan/D3D all require this; + // mismatches produce silent corruption (channel swaps, + // broken alpha). bgra8 canvas vs rgba8 MSAA is the + // classic footgun — catch it here. + auto* msaaTex = passDesc.colorAttachments[slot].view + ? passDesc.colorAttachments[slot] + .view->texture() + : nullptr; + if (msaaTex && + tv->view->texture()->format() != msaaTex->format()) + { + luaL_error( + L, + "beginRenderPass: resolveTarget format '%s' " + "does not match MSAA attachment format '%s' — " + "resolve requires identical formats. Use " + "canvas.format to " + "match your pipeline and textures.", + lua_totextureformatstring( + tv->view->texture()->format()), + lua_totextureformatstring(msaaTex->format())); + } + passDesc.colorAttachments[slot].resolveTarget = + tv->view.get(); + } + } + lua_pop(L, 1); // resolveTarget + + lua_getfield(L, -1, "loadOp"); + if (!lua_isnil(L, -1)) + { + passDesc.colorAttachments[slot].loadOp = + lua_toloadop_str(luaL_checkstring(L, -1)); + } + lua_pop(L, 1); // loadOp + + lua_getfield(L, -1, "storeOp"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + luaL_error(L, + "beginRenderPass: color[%d].storeOp is required " + "— use 'discard' for MSAA color (after resolve) " + "or 'store' to keep the rendered output", + slot + 1); + } + passDesc.colorAttachments[slot].storeOp = + lua_tostoreop_str(luaL_checkstring(L, -1)); + lua_pop(L, 1); // storeOp + + lua_getfield(L, -1, "clearColor"); + if (lua_istable(L, -1)) + { + lua_rawgeti(L, -1, 1); + passDesc.colorAttachments[slot].clearColor.r = + (float)lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 2); + passDesc.colorAttachments[slot].clearColor.g = + (float)lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 3); + passDesc.colorAttachments[slot].clearColor.b = + (float)lua_tonumber(L, -1); + lua_pop(L, 1); + lua_rawgeti(L, -1, 4); + passDesc.colorAttachments[slot].clearColor.a = + (float)lua_tonumber(L, -1); + lua_pop(L, 1); + } + lua_pop(L, 1); // clearColor + lua_pop(L, 1); // entry table + } + // If no explicit entries were found, fall back to the canvas view + if (passDesc.colorCount == 0) + { + passDesc.colorCount = 1; + passDesc.colorAttachments[0].view = self->oreColorView.get(); + } + } + lua_pop(L, 1); // color + + lua_getfield(L, 2, "depthStencil"); + if (lua_istable(L, -1)) + { + // Prefer an explicit view from the descriptor; fall back to the + // canvas's own depth view if available. + lua_getfield(L, -1, "view"); + if (!lua_isnil(L, -1)) + { + auto* tv = lua_torive(L, -1); + if (tv && tv->view) + passDesc.depthStencil.view = tv->view.get(); + } + else if (self->oreDepthView) + { + passDesc.depthStencil.view = self->oreDepthView.get(); + } + lua_pop(L, 1); // view + + // Require an explicit view, matching WebGPU validation. Without + // one, GL silently drops depth testing while Metal/TBDR implicitly + // allocates tile memory — making the same script behave differently + // across backends. + if (!passDesc.depthStencil.view) + { + luaL_error(L, + "beginRenderPass: depthStencil.view is required — " + "pass GPUTexture:view()"); + } + + if (passDesc.depthStencil.view) + { + passDesc.depthStencil.depthLoadOp = LoadOp::clear; + lua_getfield(L, -1, "depthLoadOp"); + if (!lua_isnil(L, -1)) + { + passDesc.depthStencil.depthLoadOp = + lua_toloadop_str(luaL_checkstring(L, -1)); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "depthStoreOp"); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + luaL_error(L, + "beginRenderPass: depthStencil.depthStoreOp is " + "required — use 'discard' for transient/MSAA " + "depth or 'store' if you need to read it later"); + } + passDesc.depthStencil.depthStoreOp = + lua_tostoreop_str(luaL_checkstring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, -1, "depthClearValue"); + if (!lua_isnil(L, -1)) + { + passDesc.depthStencil.depthClearValue = + static_cast(lua_tonumber(L, -1)); + } + lua_pop(L, 1); + } + } + lua_pop(L, 1); // depthStencil + } + + // Delete any previous active pass (ore::RenderPass destructor handles + // cleanup) + // Metal (and other backends) only allow one active encoder per command + // buffer. If another canvas handle (or another VM sharing the same + // oreCtx) left a pass open, finish it before opening a new encoder. + Context* oreCtx = getOreContext(L); + if (oreCtx->activeRenderPass() && !oreCtx->activeRenderPass()->isFinished()) + { + oreCtx->activeRenderPass()->finish(); + } + + delete self->m_activePass; + self->m_activePass = nullptr; + + ore::RenderPass raw = oreCtx->beginRenderPass(passDesc); + self->m_activePass = new ore::RenderPass(std::move(raw)); + self->m_activePassLabel = passDesc.label ? passDesc.label : ""; + oreCtx->setActiveRenderPass(self->m_activePass); + + auto* rp = lua_newrive(L); + rp->pass = self->m_activePass; + rp->m_finished = false; + rp->sampleCount = passSampleCount; + rp->label = self->m_activePassLabel; + rp->drawCallCount = 0; + // Hold a Lua ref to the owning canvas so it can't be GC'd while the + // pass userdata is reachable. Without this, `~ScriptedGPUCanvas` + // deletes `m_activePass` (which `rp->pass` aliases) and any + // subsequent method on the pass dereferences a freed pointer. + rp->m_L = L; + lua_pushvalue(L, 1); // canvas userdata is the `self` argument. + rp->m_canvasRef = lua_ref(L, -1); + lua_pop(L, 1); + return 1; +} + +// Recreate the underlying RenderCanvas at a new size, then re-wrap its backing +// texture for use in ORE render passes. The handle's `.image` ref continues to +// point to the updated canvas image. +static int gpucanvashandle_resize(lua_State* L) +{ + auto* self = lua_torive(L, 1); + uint32_t w = static_cast(luaL_checkunsigned(L, 2)); + uint32_t h = static_cast(luaL_checkunsigned(L, 3)); + + if (self->renderCtx == nullptr) + { + luaL_error(L, "GPUCanvas: renderCtx not initialized"); + } + auto* oreCtx = getOreContext(L); + if (oreCtx == nullptr) + { + luaL_error(L, "GPUCanvas: GPU context not initialized"); + } + + auto newCanvas = self->renderCtx->makeRenderCanvas(w, h); + if (!newCanvas) + { + luaL_error(L, "GPUCanvas:resize() failed to create RenderCanvas"); + } + auto newColorView = oreCtx->wrapCanvasTexture(newCanvas.get()); + if (!newColorView) + { + luaL_error(L, "GPUCanvas:resize() failed to wrap canvas texture"); + } + + // Update the image ref to point to the new canvas + if (self->m_L != nullptr && self->m_imageRef != LUA_NOREF) + { + lua_unref(self->m_L, self->m_imageRef); + self->m_imageRef = LUA_NOREF; + } + self->canvas = std::move(newCanvas); + self->oreColorView = std::move(newColorView); + + // Rebuild MSAA color texture if canvas was created with sampleCount > 1. + if (self->oreMSAAColorTexture) + { + uint32_t sc = self->oreMSAAColorTexture->sampleCount(); + ore::TextureDesc msaaDesc; + msaaDesc.width = w; + msaaDesc.height = h; + msaaDesc.format = self->oreColorView->texture()->format(); + msaaDesc.renderTarget = true; + msaaDesc.sampleCount = sc; + msaaDesc.label = "GPUCanvasMSAAColor"; + self->oreMSAAColorTexture = oreCtx->makeTexture(msaaDesc); + ore::TextureViewDesc msaaViewDesc; + msaaViewDesc.texture = self->oreMSAAColorTexture.get(); + self->oreMSAAColorView = oreCtx->makeTextureView(msaaViewDesc); + + ore::TextureDesc depthDesc; + depthDesc.width = w; + depthDesc.height = h; + depthDesc.format = ore::TextureFormat::depth32float; + depthDesc.renderTarget = true; + depthDesc.sampleCount = sc; + depthDesc.label = "GPUCanvasMSAADepth"; + self->oreDepthTexture = oreCtx->makeTexture(depthDesc); + ore::TextureViewDesc depthViewDesc; + depthViewDesc.texture = self->oreDepthTexture.get(); + self->oreDepthView = oreCtx->makeTextureView(depthViewDesc); + } + else + { + self->oreMSAAColorTexture = nullptr; + self->oreMSAAColorView = nullptr; + self->oreDepthTexture = nullptr; + self->oreDepthView = nullptr; + } + + auto* img = lua_newrive(L); + img->image = + ref_rcp(static_cast(self->canvas->renderImage())); + self->m_imageRef = lua_ref(L, -1); + lua_pop(L, 1); // pop image + + return 0; +} + +static int gpucanvashandle_colorview(lua_State* L) +{ + auto* self = lua_torive(L, 1); + if (!self->oreColorView) + { + lua_pushnil(L); + return 1; + } + auto* tv = lua_newrive(L); + tv->view = self->oreColorView; + return 1; +} + +static int gpucanvashandle_index(lua_State* L) +{ + auto* self = lua_torive(L, 1); + const char* key = luaL_checkstring(L, 2); + if (strcmp(key, "image") == 0) + { + if (self->m_imageRef != LUA_NOREF) + { + rive_lua_pushRef(L, self->m_imageRef); + return 1; + } + lua_pushnil(L); + return 1; + } + if (strcmp(key, "width") == 0 && self->canvas) + { + lua_pushnumber(L, self->canvas->width()); + return 1; + } + if (strcmp(key, "height") == 0 && self->canvas) + { + lua_pushnumber(L, self->canvas->height()); + return 1; + } + if (strcmp(key, "sampleCount") == 0) + { + uint32_t sc = self->oreMSAAColorTexture + ? self->oreMSAAColorTexture->sampleCount() + : 1; + lua_pushnumber(L, sc); + return 1; + } + if (strcmp(key, "hasDepth") == 0) + { + lua_pushboolean(L, self->oreDepthView != nullptr); + return 1; + } + if (strcmp(key, "format") == 0) + { + if (self->oreColorView && self->oreColorView->texture()) + lua_pushstring(L, + lua_totextureformatstring( + self->oreColorView->texture()->format())); + else + lua_pushnil(L); + return 1; + } + luaL_error(L, "%s is not a valid property of GPUCanvas", key); + return 0; +} + +static int gpucanvashandle_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::beginRenderPass: + return gpucanvashandle_beginrenderpass(L); + case (int)LuaAtoms::colorView: + return gpucanvashandle_colorview(L); + case (int)LuaAtoms::resize: + return gpucanvashandle_resize(L); + default: + break; + } + } + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedGPUCanvas::luaName); + return 0; +} + +// ============================================================================ +// Canvas (2D Rive renderer canvas) +// ============================================================================ + +// Recreate the underlying RenderCanvas at a new size. Must not be called +// between beginFrame() and endFrame(). +static int canvashandle_resize(lua_State* L) +{ + auto* self = lua_torive(L, 1); + uint32_t w = static_cast(luaL_checkunsigned(L, 2)); + uint32_t h = static_cast(luaL_checkunsigned(L, 3)); + + if (self->renderCtx == nullptr) + { + luaL_error(L, "Canvas: renderCtx not initialized"); + } + if (self->m_state != CanvasState::Idle) + { + luaL_error(L, "Canvas:resize() called during an active frame"); + } + + auto newCanvas = self->renderCtx->makeRenderCanvas(w, h); + if (!newCanvas) + { + luaL_error(L, "Canvas:resize() failed to create RenderCanvas"); + } + + if (self->m_L != nullptr && self->m_imageRef != LUA_NOREF) + { + lua_unref(self->m_L, self->m_imageRef); + self->m_imageRef = LUA_NOREF; + } + self->canvas = std::move(newCanvas); + + auto* img = lua_newrive(L); + img->image = + ref_rcp(static_cast(self->canvas->renderImage())); + self->m_imageRef = lua_ref(L, -1); + lua_pop(L, 1); + + return 0; +} + +// Begin a Rive rendering frame on this canvas. Returns a Renderer that the +// caller can use to issue Rive draw calls. Must be paired with endFrame(). +// +// Optional `desc` table fields: +// clearColor: Color? ARGB integer (e.g. 0xFF000000 for opaque black). +// Defaults to transparent black (0). +static int canvashandle_beginframe(lua_State* L) +{ + auto* self = lua_torive(L, 1); + if (self->renderCtx == nullptr) + { + luaL_error(L, "Canvas: renderCtx not initialized"); + } + auto* scriptingContext = + static_cast(lua_getthreaddata(L)); + if (scriptingContext == nullptr || !scriptingContext->canvasDrawingPhase()) + { + luaL_error(L, "Canvas:beginFrame() called outside drawing phase"); + } + if (self->m_state != CanvasState::Idle) + { + luaL_error(L, "Canvas:beginFrame() called during an active frame"); + } + if (!self->canvas) + { + luaL_error(L, "Canvas:beginFrame() — canvas is null"); + } + + gpu::RenderContext::FrameDescriptor desc{}; + desc.renderTargetWidth = self->canvas->width(); + desc.renderTargetHeight = self->canvas->height(); + desc.loadAction = gpu::LoadAction::clear; + desc.clearColor = 0; // transparent black + + if (lua_gettop(L) >= 2 && lua_istable(L, 2)) + { + lua_getfield(L, 2, "clearColor"); + if (!lua_isnil(L, -1)) + { + // clearColor is a ColorInt (ARGB uint32) + desc.clearColor = static_cast(lua_tounsigned(L, -1)); + } + lua_pop(L, 1); + } + + self->renderCtx->beginFrame(desc); + + // Allocate a RiveRenderer that issues into this render context. + // Deleted in endFrame() (or in the destructor if endFrame is never called). + self->m_riveRenderer = new RiveRenderer(self->renderCtx); + self->m_state = CanvasState::Rendering; + + // Push a non-owning ScriptedRenderer wrapping our RiveRenderer and keep a + // registry ref so the Lua object stays alive until endFrame(). + lua_newrive(L, self->m_riveRenderer); + lua_pushvalue(L, -1); + self->m_rendererRef = lua_ref(L, -1); + lua_pop(L, 1); // pop the extra copy used for ref; original stays on stack + + return 1; // returns the ScriptedRenderer +} + +// Flush all pending Rive draw calls for this frame to the canvas render target, +// then release the renderer. Must be called after beginFrame(). +static int canvashandle_endframe(lua_State* L) +{ + auto* self = lua_torive(L, 1); + if (self->m_state != CanvasState::Rendering) + { + luaL_error(L, "Canvas:endFrame() called without beginFrame()"); + } + + // Null out the ScriptedRenderer's pointer so it can no longer issue draws. + if (self->m_L != nullptr && self->m_rendererRef != LUA_NOREF) + { + rive_lua_pushRef(L, self->m_rendererRef); + if (!lua_isnil(L, -1)) + { + auto* sr = lua_torive(L, -1); + if (sr != nullptr) + sr->end(); + } + lua_pop(L, 1); + lua_unref(self->m_L, self->m_rendererRef); + self->m_rendererRef = LUA_NOREF; + } + + // Create a command buffer, flush the render context into the canvas + // render target, then commit. Without a proper command buffer the + // buffer ring mutex would never be unlocked (the completion handler + // that unlocks it is registered on the command buffer). + void* commandBuffer = self->renderCtx->impl()->makeCommandBuffer(); + + gpu::RenderContext::FlushResources flush{}; + flush.renderTarget = self->canvas->renderTarget(); + flush.externalCommandBuffer = commandBuffer; + self->renderCtx->flush(flush); + + self->renderCtx->impl()->commitCommandBuffer(commandBuffer); + + // Destroy the RiveRenderer — it is no longer valid after flush(). + delete self->m_riveRenderer; + self->m_riveRenderer = nullptr; + self->m_state = CanvasState::Idle; + + return 0; +} + +static int canvashandle_index(lua_State* L) +{ + auto* self = lua_torive(L, 1); + const char* key = luaL_checkstring(L, 2); + if (strcmp(key, "image") == 0) + { + if (self->m_imageRef != LUA_NOREF) + { + rive_lua_pushRef(L, self->m_imageRef); + return 1; + } + lua_pushnil(L); + return 1; + } + if (strcmp(key, "width") == 0 && self->canvas) + { + lua_pushnumber(L, self->canvas->width()); + return 1; + } + if (strcmp(key, "height") == 0 && self->canvas) + { + lua_pushnumber(L, self->canvas->height()); + return 1; + } + luaL_error(L, "%s is not a valid property of Canvas", key); + return 0; +} + +static int canvashandle_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::beginFrame: + return canvashandle_beginframe(L); + case (int)LuaAtoms::endFrame: + return canvashandle_endframe(L); + case (int)LuaAtoms::resize: + return canvashandle_resize(L); + default: + break; + } + } + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedCanvas::luaName); + return 0; +} + +// ============================================================================ +// Registration +// ============================================================================ + +static const luaL_Reg empty[] = { + {NULL, NULL}, +}; + +template +static void register_type_with_constructor(lua_State* L, + lua_CFunction constructor, + lua_CFunction namecall = nullptr, + lua_CFunction indexfn = nullptr) +{ + luaL_register(L, T::luaName, empty); + lua_register_rive(L); + + if (namecall) + { + lua_pushcfunction(L, namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + } + if (indexfn) + { + lua_pushcfunction(L, indexfn, nullptr); + lua_setfield(L, -2, "__index"); + } + + // Create metatable for the metatable (so we can call T.new()) + lua_createtable(L, 0, 1); + lua_pushcfunction(L, constructor, nullptr); + lua_setfield(L, -2, "__index"); + + // Also set __call so T.new(...) works + // Actually the pattern is T.new(), so set new on the __index table + // Let's do it properly: make __index return the new function + lua_pop(L, 1); // pop the meta-meta + + // Simpler: just put "new" on the library table directly + lua_pushcfunction(L, constructor, nullptr); + lua_setfield(L, -2, "new"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable +} + +int luaopen_rive_gpu(lua_State* L) +{ + static const luaL_Reg shaderStatics[] = {{"new", shader_construct}, + {nullptr, nullptr}}; + static const luaL_Reg gpuBufferStatics[] = {{"new", gpubuffer_construct}, + {nullptr, nullptr}}; + static const luaL_Reg gpuTextureStatics[] = {{"new", gputexture_construct}, + {nullptr, nullptr}}; + static const luaL_Reg gpuSamplerStatics[] = {{"new", gpusampler_construct}, + {nullptr, nullptr}}; + static const luaL_Reg gpuPipelineStatics[] = { + {"new", gpupipeline_construct}, + {nullptr, nullptr}}; + static const luaL_Reg gpuBindGroupStatics[] = { + {"new", gpubindgroup_construct}, + {nullptr, nullptr}}; + static const luaL_Reg gpuBindGroupLayoutStatics[] = { + {"new", gpubindgrouplayout_construct}, + {nullptr, nullptr}}; + // Shader + { + luaL_register(L, ScriptedShader::luaName, shaderStatics); + lua_register_rive(L); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUBuffer + { + luaL_register(L, ScriptedGPUBuffer::luaName, gpuBufferStatics); + lua_register_rive(L); + lua_pushcfunction(L, gpubuffer_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_pushcfunction(L, gpubuffer_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUTexture + { + luaL_register(L, ScriptedGPUTexture::luaName, gpuTextureStatics); + lua_register_rive(L); + lua_pushcfunction(L, gputexture_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_pushcfunction(L, gputexture_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUSampler + { + luaL_register(L, ScriptedGPUSampler::luaName, gpuSamplerStatics); + lua_register_rive(L); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUPipeline + { + luaL_register(L, ScriptedGPUPipeline::luaName, gpuPipelineStatics); + lua_register_rive(L); + lua_pushcfunction(L, gpupipeline_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUBindGroup + { + luaL_register(L, ScriptedGPUBindGroup::luaName, gpuBindGroupStatics); + lua_register_rive(L); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUBindGroupLayout + { + luaL_register(L, + ScriptedGPUBindGroupLayout::luaName, + gpuBindGroupLayoutStatics); + lua_register_rive(L); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPURenderPass + { + luaL_register(L, ScriptedGPURenderPass::luaName, empty); + lua_register_rive(L); + lua_pushcfunction(L, gpurenderpass_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUTextureView (no constructor — created via GPUTexture:view()) + { + luaL_register(L, ScriptedGPUTextureView::luaName, empty); + lua_register_rive(L); + lua_pushcfunction(L, gputextureview_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // GPUCanvas (no public constructor — created via context:gpuCanvas()) + { + luaL_register(L, ScriptedGPUCanvas::luaName, empty); + lua_register_rive(L); + lua_pushcfunction(L, gpucanvashandle_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_pushcfunction(L, gpucanvashandle_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + // Canvas (no public constructor — created via context:canvas()) + { + luaL_register(L, ScriptedCanvas::luaName, empty); + lua_register_rive(L); + lua_pushcfunction(L, canvashandle_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_pushcfunction(L, canvashandle_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + } + + return 0; +} + +// ============================================================================ +// Image:view() implementation — called from lua_image.cpp +// Lives here because ore headers require ObjC++ on Apple. +// ============================================================================ + +#include "rive/renderer/rive_render_image.hpp" + +// ore::TextureView is complete here — define the destructor and factory. +ScriptedImage::~ScriptedImage() = default; +ScriptedImage* ScriptedImage::luaNew(lua_State* L) +{ + return lua_newrive(L); +} + +int riveImageViewImpl(lua_State* L) +{ + auto* self = lua_torive(L, 1); + if (!self->image) + { + luaL_error(L, "Image has no backing texture"); + return 0; + } + + // Safe cast — returns nullptr if the image isn't GPU-backed. + auto* riveImage = lite_rtti_cast(self->image.get()); + if (!riveImage) + { + luaL_error(L, "Image is not a GPU-backed RiveRenderImage"); + return 0; + } + gpu::Texture* sourceGpuTex = riveImage->getTexture(); + if (!sourceGpuTex) + { + luaL_error(L, "Image GPU texture not available"); + return 0; + } + + // Get ore::Context from scripting context. + auto* ctx = static_cast(lua_getthreaddata(L)); + auto* oreCtx = static_cast(ctx->oreContext()); + if (!oreCtx) + { + luaL_error(L, "GPU context not available for Image:view()"); + return 0; + } + + if (!self->cachedOreView) + { + // GL canvas-import boundary: on GL/WebGL, sampling a Rive 2D + // RenderCanvas as a WGSL texture requires a Y-flipped companion + // because PLS renders the canvas bottom-up while WGSL expects + // V=0 at the visual top of the image. The render context's + // getCanvasImportMirror returns nullptr on every backend except + // GL — on GL it lazily allocates a companion texture, registers + // a per-flush blit hook, and returns the companion image. We + // cache the companion's RiveRenderImage so the companion stays + // alive as long as this ScriptedImage does. + // + // See dev/ore_canvas_import_invariant.md. + gpu::Texture* texToWrap = sourceGpuTex; +#if defined(ORE_BACKEND_GL) + { + auto* renderCtx = + static_cast(ctx->renderContext()); + self->cachedMirrorImage = + getCanvasImportMirrorGL(renderCtx, + sourceGpuTex, + self->image->width(), + self->image->height()); + if (self->cachedMirrorImage != nullptr) + { + auto* mirrorRive = lite_rtti_cast( + self->cachedMirrorImage.get()); + if (mirrorRive != nullptr && + mirrorRive->getTexture() != nullptr) + { + texToWrap = mirrorRive->getTexture(); + } + } + } +#endif // ORE_BACKEND_GL + + self->cachedOreView = oreCtx->wrapRiveTexture(texToWrap, + self->image->width(), + self->image->height()); + if (!self->cachedOreView) + { + luaL_error(L, "Image:view() not supported on this backend"); + return 0; + } + } + + // Create the GPUTextureView and have it retain the RenderImage so the + // underlying gpu::Texture stays alive even if the Image is GC'd. + auto* tv = lua_newrive(L); + tv->view = self->cachedOreView; + tv->retainedImage = self->image; + + return 1; +} + +#endif // RIVE_CANVAS && RIVE_ORE +#endif // WITH_RIVE_SCRIPTING diff --git a/thirdparty/rive/source/lua/renderer/lua_gpu_apple.mm b/thirdparty/rive/source/lua/renderer/lua_gpu_apple.mm new file mode 100644 index 000000000..06e8375fa --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_gpu_apple.mm @@ -0,0 +1,4 @@ +// On Apple platforms, ore_context.hpp imports (via the +// globally-defined ORE_BACKEND_METAL), which is only valid in ObjC++ files. +// This wrapper compiles lua_gpu.cpp as ObjC++ on macOS/iOS. +#include "lua_gpu.cpp" diff --git a/thirdparty/rive/source/lua/renderer/lua_gradient.cpp b/thirdparty/rive/source/lua/renderer/lua_gradient.cpp new file mode 100644 index 000000000..61a045d5d --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_gradient.cpp @@ -0,0 +1,89 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lua.h" +#include "lualib.h" +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/factory.hpp" + +using namespace rive; + +static void fill_stops(lua_State* L, + std::vector& stops, + std::vector& colors) +{ + luaL_checktype(L, 3, LUA_TTABLE); + int index = 1; + while (true) + { + if (lua_rawgeti(L, 3, index++) != LUA_TTABLE) + { + lua_pop(L, 1); + break; + } + lua_rawgetfield(L, -1, "position"); + float position = float(luaL_checknumber(L, -1)); + lua_pop(L, 1); + lua_rawgetfield(L, -1, "color"); + uint32_t color = luaL_checkunsigned(L, -1); + + stops.push_back(position); + colors.push_back(color); + lua_pop(L, 1); + } +} +static int gradient_linear(lua_State* L) +{ + auto from = lua_checkvec2d(L, 1); + auto to = lua_checkvec2d(L, 2); + + std::vector stops; + std::vector colors; + fill_stops(L, stops, colors); + + ScriptedGradient* gradient = lua_newrive(L); + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + + gradient->shader = context->factory()->makeLinearGradient(from->x, + from->y, + to->x, + to->y, + colors.data(), + stops.data(), + stops.size()); + return 1; +} + +static int gradient_radial(lua_State* L) +{ + auto from = lua_checkvec2d(L, 1); + auto radius = luaL_checknumber(L, 2); + std::vector stops; + std::vector colors; + fill_stops(L, stops, colors); + + ScriptedGradient* gradient = lua_newrive(L); + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + + gradient->shader = context->factory()->makeRadialGradient(from->x, + from->y, + radius, + colors.data(), + stops.data(), + stops.size()); + return 1; +} + +static const luaL_Reg gradientStaticMethods[] = {{"linear", gradient_linear}, + {"radial", gradient_radial}, + {nullptr, nullptr}}; + +int luaopen_rive_gradient(lua_State* L) +{ + luaL_register(L, ScriptedGradient::luaName, gradientStaticMethods); + lua_register_rive(L); + + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_image.cpp b/thirdparty/rive/source/lua/renderer/lua_image.cpp new file mode 100644 index 000000000..0b98a7244 --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_image.cpp @@ -0,0 +1,140 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lua.h" +#include "lualib.h" +#include "rive/lua/rive_lua_libs.hpp" + +using namespace rive; + +// Defined in lua_gpu.cpp (compiled as ObjC++ on Apple, has ore includes). +#ifdef RIVE_ORE +extern int riveImageViewImpl(lua_State* L); +#endif + +// Out-of-line destructor. The rcp member (when +// RIVE_CANVAS && RIVE_ORE) prevents implicit ~ScriptedImage() in TUs +// that don't include the full ore headers. When ore is not enabled the +// default-generated body is fine. +#if !(defined(RIVE_CANVAS) && defined(RIVE_ORE)) +ScriptedImage::~ScriptedImage() = default; +ScriptedImage* ScriptedImage::luaNew(lua_State* L) +{ + return lua_newrive(L); +} +#endif + +static int image_index(lua_State* L) +{ + auto image = lua_torive(L, 1); + + int atom; + const char* name = lua_tostringatom(L, 2, &atom); + if (!name) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + } + switch (atom) + { + case (int)LuaAtoms::width: + lua_pushnumber(L, image->image ? image->image->width() : 0); + return 1; + case (int)LuaAtoms::height: + lua_pushnumber(L, image->image ? image->image->height() : 0); + return 1; +#ifdef RIVE_ORE + case (int)LuaAtoms::view: + lua_pushcfunction(L, riveImageViewImpl, "Image.view"); + return 1; +#endif + } + luaL_error(L, + "'%s' is not a valid index of %s", + name, + ScriptedImage::luaName); + return 0; +} + +static int imagesampler_construct(lua_State* L) +{ + int wrapXAtom; + const char* wrapXName = lua_tostringatom(L, 1, &wrapXAtom); + if (!wrapXName) + { + luaL_typeerrorL(L, 1, lua_typename(L, LUA_TSTRING)); + } + int wrapYAtom; + const char* wrapYName = lua_tostringatom(L, 2, &wrapYAtom); + if (!wrapYName) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + } + int imageFilterAtom; + const char* imageFilterName = lua_tostringatom(L, 3, &imageFilterAtom); + if (!imageFilterName) + { + luaL_typeerrorL(L, 3, lua_typename(L, LUA_TSTRING)); + } + ImageWrap wrapX = ImageWrap::clamp; + ImageWrap wrapY = ImageWrap::clamp; + ImageFilter filter = ImageFilter::bilinear; + switch (wrapXAtom) + { + case (int)LuaAtoms::clamp: + break; + case (int)LuaAtoms::repeat: + wrapX = ImageWrap::repeat; + break; + case (int)LuaAtoms::mirror: + wrapX = ImageWrap::mirror; + break; + default: + luaL_error(L, "'%s' is not a valid ImageWrap", wrapXName); + break; + } + switch (wrapYAtom) + { + case (int)LuaAtoms::clamp: + break; + case (int)LuaAtoms::repeat: + wrapY = ImageWrap::repeat; + break; + case (int)LuaAtoms::mirror: + wrapY = ImageWrap::mirror; + break; + default: + luaL_error(L, "'%s' is not a valid ImageWrap", wrapYName); + break; + } + + switch (imageFilterAtom) + { + case (int)LuaAtoms::bilinear: + break; + case (int)LuaAtoms::nearest: + filter = ImageFilter::nearest; + break; + default: + luaL_error(L, "'%s' is not a valid ImageFilter", imageFilterName); + break; + } + + lua_newrive(L, wrapX, wrapY, filter); + return 1; +} + +int luaopen_rive_image(lua_State* L) +{ + lua_register_rive(L); + + lua_pushcfunction(L, image_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); + + lua_pushcfunction(L, imagesampler_construct, ScriptedImageSampler::luaName); + lua_setfield(L, LUA_GLOBALSINDEX, ScriptedImageSampler::luaName); + lua_register_rive(L); + + return 0; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_mesh.cpp b/thirdparty/rive/source/lua/renderer/lua_mesh.cpp new file mode 100644 index 000000000..7b621ebfa --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_mesh.cpp @@ -0,0 +1,216 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lualib.h" +#include "rive/math/vec2d.hpp" +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/factory.hpp" + +#include +#include + +using namespace rive; + +static int vertex_buffer_construct(lua_State* L) +{ + lua_newrive(L); + return 1; +} + +static int vertex_buffer_reset(lua_State* L) +{ + auto vertexBuffer = lua_torive(L, 1); + vertexBuffer->values.clear(); + vertexBuffer->vertexBuffer = nullptr; + return 0; +} + +static int vertex_buffer_add(lua_State* L) +{ + auto vertexBuffer = lua_torive(L, 1); + int nargs = lua_gettop(L) - 1; + for (int i = 0; i < nargs; i++) + { + auto vec = lua_checkvec2d(L, 2 + i); + vertexBuffer->values.push_back(*vec); + } + vertexBuffer->vertexBuffer = nullptr; + return 0; +} + +static int vertex_buffer_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::reset: + return vertex_buffer_reset(L); + case (int)LuaAtoms::add: + return vertex_buffer_add(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedVertexBuffer::luaName); + return 0; +} + +static int index_buffer_construct(lua_State* L) +{ + lua_newrive(L); + return 1; +} + +static int index_buffer_reset(lua_State* L) +{ + auto indexBuffer = lua_torive(L, 1); + indexBuffer->values.clear(); + indexBuffer->max = 0; + indexBuffer->indexBuffer = nullptr; + return 0; +} + +static int index_buffer_add(lua_State* L) +{ + auto indexBuffer = lua_torive(L, 1); + for (int i = 0; i < 3; i++) + { + auto index = luaL_checkunsigned(L, 2 + i); + if (index > std::numeric_limits::max()) + { + luaL_error(L, + "index %i exceeds %i", + index, + std::numeric_limits::max()); + } + if (index > indexBuffer->max) + { + indexBuffer->max = index; + } + indexBuffer->values.push_back((uint16_t)index); + } + indexBuffer->indexBuffer = nullptr; + + return 0; +} + +static int index_buffer_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::reset: + return index_buffer_reset(L); + case (int)LuaAtoms::add: + return index_buffer_add(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedTriangleBuffer::luaName); + return 0; +} + +static const luaL_Reg empty[] = { + {NULL, NULL}, +}; + +static void register_vertex_buffer(lua_State* L) +{ + luaL_register(L, ScriptedVertexBuffer::luaName, empty); + lua_register_rive(L); + + lua_pushcfunction(L, vertex_buffer_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + // Create metatable for the metatable (so we can call it). + lua_createtable(L, 0, 1); + lua_pushcfunction(L, vertex_buffer_construct, nullptr); + lua_setfield(L, -2, "__call"); + // -3 as it's the library (Path) that we're setting this metatable on. + lua_setmetatable(L, -3); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable +} + +static void register_index_buffer(lua_State* L) +{ + luaL_register(L, ScriptedTriangleBuffer::luaName, empty); + lua_register_rive(L); + + lua_pushcfunction(L, index_buffer_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + // Create metatable for the metatable (so we can call it). + lua_createtable(L, 0, 1); + lua_pushcfunction(L, index_buffer_construct, nullptr); + lua_setfield(L, -2, "__call"); + // -3 as it's the library (Path) that we're setting this metatable on. + lua_setmetatable(L, -3); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable +} + +void ScriptedVertexBuffer::update(Factory* factory) +{ + // still valid? + if (vertexBuffer) + { + return; + } + auto buffer = + factory->makeRenderBuffer(RenderBufferType::vertex, + RenderBufferFlags::mappedOnceAtInitialization, + values.size() * sizeof(Vec2D)); + if (buffer != nullptr) + { + float* pos = static_cast(buffer->map()); + if (pos != nullptr) + { + memcpy(pos, values.data(), buffer->sizeInBytes()); + buffer->unmap(); + } + } + vertexBuffer = buffer; +} + +void ScriptedTriangleBuffer::update(Factory* factory) +{ + // still valid? + if (indexBuffer) + { + return; + } + auto buffer = + factory->makeRenderBuffer(RenderBufferType::index, + RenderBufferFlags::mappedOnceAtInitialization, + values.size() * sizeof(uint16_t)); + if (buffer != nullptr) + { + void* indexData = buffer->map(); + if (indexData != nullptr) + { + memcpy(indexData, values.data(), buffer->sizeInBytes()); + buffer->unmap(); + } + } + indexBuffer = buffer; +} + +int luaopen_rive_mesh(lua_State* L) +{ + register_vertex_buffer(L); + register_index_buffer(L); + + return 2; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_paint.cpp b/thirdparty/rive/source/lua/renderer/lua_paint.cpp new file mode 100644 index 000000000..97eb51355 --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_paint.cpp @@ -0,0 +1,569 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "lua.h" +#include "rive/renderer.hpp" +#include "rive/rive_types.hpp" +#include "rive/shapes/paint/blend_mode.hpp" +#include "rive/shapes/paint/fill.hpp" +#include "rive/shapes/paint/stroke.hpp" +#include "rive/shapes/paint/solid_color.hpp" +#include "rive/shapes/paint/feather.hpp" +#include "lualib.h" +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/factory.hpp" + +using namespace rive; + +static void readStyle(lua_State* L, ScriptedPaint* paint, int index) +{ + int atom; + const char* styleName = lua_tostringatom(L, index, &atom); + if (!styleName) + { + luaL_typeerrorL(L, index, lua_typename(L, LUA_TSTRING)); + } + switch (atom) + { + case (int)LuaAtoms::stroke: + paint->style(RenderPaintStyle::stroke); + break; + case (int)LuaAtoms::fill: + paint->style(RenderPaintStyle::fill); + break; + default: + luaL_error(L, "'%s' is not a valid PaintStyle", styleName); + break; + } +} + +static void readJoin(lua_State* L, ScriptedPaint* paint, int index) +{ + int atom; + const char* joinName = lua_tostringatom(L, index, &atom); + if (!joinName) + { + luaL_typeerrorL(L, index, lua_typename(L, LUA_TSTRING)); + } + switch (atom) + { + case (int)LuaAtoms::miter: + paint->join(StrokeJoin::miter); + break; + case (int)LuaAtoms::round: + paint->join(StrokeJoin::round); + break; + case (int)LuaAtoms::bevel: + paint->join(StrokeJoin::bevel); + break; + default: + luaL_error(L, "'%s' is not a valid StrokeJoin", joinName); + break; + } +} + +static void readCap(lua_State* L, ScriptedPaint* paint, int index) +{ + int atom; + const char* capName = lua_tostringatom(L, index, &atom); + if (!capName) + { + luaL_typeerrorL(L, index, lua_typename(L, LUA_TSTRING)); + } + switch (atom) + { + case (int)LuaAtoms::butt: + paint->cap(StrokeCap::butt); + break; + case (int)LuaAtoms::round: + paint->cap(StrokeCap::round); + break; + case (int)LuaAtoms::square: + paint->cap(StrokeCap::square); + break; + default: + luaL_error(L, "'%s' is not a valid StrokeCap", capName); + break; + } +} + +BlendMode rive::lua_toblendmode(lua_State* L, int idx) +{ + int atom; + const char* blendName = lua_tostringatom(L, idx, &atom); + if (!blendName) + { + luaL_typeerrorL(L, idx, lua_typename(L, LUA_TSTRING)); + } + switch (atom) + { + case (int)LuaAtoms::srcOver: + return BlendMode::srcOver; + + case (int)LuaAtoms::screen: + return BlendMode::screen; + + case (int)LuaAtoms::overlay: + return BlendMode::overlay; + + case (int)LuaAtoms::darken: + return BlendMode::darken; + + case (int)LuaAtoms::lighten: + return BlendMode::lighten; + + case (int)LuaAtoms::colorDodge: + return BlendMode::colorDodge; + + case (int)LuaAtoms::colorBurn: + return BlendMode::colorBurn; + + case (int)LuaAtoms::hardLight: + return BlendMode::hardLight; + + case (int)LuaAtoms::softLight: + return BlendMode::softLight; + + case (int)LuaAtoms::difference: + return BlendMode::difference; + + case (int)LuaAtoms::exclusion: + return BlendMode::exclusion; + + case (int)LuaAtoms::multiply: + return BlendMode::multiply; + + case (int)LuaAtoms::hue: + return BlendMode::hue; + + case (int)LuaAtoms::saturation: + return BlendMode::saturation; + + case (int)LuaAtoms::color: + return BlendMode::color; + + case (int)LuaAtoms::luminosity: + return BlendMode::luminosity; + + default: + luaL_error(L, "'%s' is not a valid BlendMode", blendName); + return BlendMode::srcOver; + } +} + +static void readBlendMode(lua_State* L, ScriptedPaint* paint, int index) +{ + auto blendMode = lua_toblendmode(L, index); + paint->blendMode(blendMode); +} + +ScriptedPaintData::ScriptedPaintData() {} + +ScriptedPaintData::ScriptedPaintData(const ShapePaint* shapePaint) +{ + if (shapePaint->is()) + { + style(RenderPaintStyle::fill); + } + else if (shapePaint->is()) + { + auto stroke = shapePaint->as(); + style(RenderPaintStyle::stroke); + thickness(stroke->thickness()); + cap((StrokeCap)stroke->cap()); + join((StrokeJoin)stroke->join()); + } + for (auto& child : shapePaint->children()) + { + if (child->is()) + { + color(child->as()->colorValue()); + break; + } + } + if (shapePaint->feather()) + { + feather(shapePaint->feather()->strength()); + } + blendMode((BlendMode)shapePaint->blendModeValue()); +} + +ScriptedPaint::ScriptedPaint(Factory* factory) : + renderPaint(factory->makeRenderPaint()) +{} + +ScriptedPaint::ScriptedPaint(Factory* factory, const ScriptedPaint& source) : + ScriptedPaint(factory) +{ + style(source.m_style); + color(source.m_color); + thickness(source.m_thickness); + join(source.m_join); + cap(source.m_cap); + feather(source.m_feather); + blendMode(source.m_blendMode); + gradient(source.m_gradient); +} + +static bool paint_set_value(lua_State* L, + ScriptedPaint* renderPaint, + int keyAtom, + int valueIndex) +{ + switch (keyAtom) + { + case (int)LuaAtoms::style: + readStyle(L, renderPaint, valueIndex); + return true; + case (int)LuaAtoms::join: + readJoin(L, renderPaint, valueIndex); + return true; + case (int)LuaAtoms::cap: + readCap(L, renderPaint, valueIndex); + return true; + case (int)LuaAtoms::thickness: + renderPaint->thickness(float(luaL_checknumber(L, valueIndex))); + return true; + case (int)LuaAtoms::blendMode: + readBlendMode(L, renderPaint, valueIndex); + return true; + case (int)LuaAtoms::feather: + renderPaint->feather(float(luaL_checknumber(L, valueIndex))); + return true; + case (int)LuaAtoms::gradient: + { + ScriptedGradient* gradient = + lua_torive(L, valueIndex, true); + if (gradient != nullptr) + { + renderPaint->gradient(gradient->shader); + } + else + { + renderPaint->gradient(nullptr); + } + return true; + } + case (int)LuaAtoms::color: + renderPaint->color(luaL_checkunsigned(L, valueIndex)); + return true; + default: + return false; + } +} + +static void setPropertiesFromDefinitionTable(lua_State* L, + ScriptedPaint* scriptedPaint, + int tableIndex) +{ + luaL_checktype(L, tableIndex, LUA_TTABLE); + + // iterate table + // Push another reference to the table on top of the stack (so we know + // where it is, and this function can work for negative, positive and + // pseudo indices + lua_pushvalue(L, tableIndex); + // stack now contains: -1 => table + lua_pushnil(L); + // stack now contains: -1 => nil; -2 => table + while (lua_next(L, -2)) + { + // stack now contains: -1 => value; -2 => key; -3 => table + // copy the key so that lua_tostring does not modify the original + // lua_pushvalue(L, -2); + // stack now contains: -1 => key; -2 => value; -3 => key; -4 => + // table + int atom; + const char* key = lua_tostringatom(L, -2, &atom); + if (key) + { + paint_set_value(L, scriptedPaint, atom, -1); + } + lua_pop(L, 1); + // stack now contains: -1 => key; -2 => table + } + // stack now contains: -1 => table (when lua_next returns 0 it pops the + // key but does not push anything.) Pop table + lua_pop(L, 1); +} + +static int paint_new(lua_State* L) +{ + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + lua_newrive(L, context->factory()); + + return 1; +} + +static int paint_with(lua_State* L) +{ + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + auto scriptedPaint = lua_newrive(L, context->factory()); + setPropertiesFromDefinitionTable(L, scriptedPaint, 1); + return 1; +} + +static int paint_newindex(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedPaint = lua_torive(L, 1); + paint_set_value(L, scriptedPaint, atom, 3); + + return 0; +} + +void ScriptedPaintData::pushStyle(lua_State* L) +{ + switch (m_style) + { + case RenderPaintStyle::fill: + lua_pushstring(L, "fill"); + break; + case RenderPaintStyle::stroke: + lua_pushstring(L, "stroke"); + break; + default: + RIVE_UNREACHABLE(); + } +} + +void ScriptedPaintData::pushJoin(lua_State* L) +{ + switch (m_join) + { + case StrokeJoin::miter: + lua_pushstring(L, "miter"); + break; + case StrokeJoin::bevel: + lua_pushstring(L, "bevel"); + break; + case StrokeJoin::round: + lua_pushstring(L, "round"); + break; + default: + RIVE_UNREACHABLE(); + } +} + +void ScriptedPaintData::pushCap(lua_State* L) +{ + switch (m_cap) + { + case StrokeCap::butt: + lua_pushstring(L, "butt"); + break; + case StrokeCap::square: + lua_pushstring(L, "square"); + break; + case StrokeCap::round: + lua_pushstring(L, "round"); + break; + default: + RIVE_UNREACHABLE(); + } +} + +void ScriptedPaintData::pushThickness(lua_State* L) +{ + lua_pushnumber(L, m_thickness); +} + +void ScriptedPaintData::pushBlendMode(lua_State* L) +{ + switch (m_blendMode) + { + case BlendMode::srcOver: + lua_pushstring(L, "srcOver"); + break; + case BlendMode::screen: + lua_pushstring(L, "screen"); + break; + case BlendMode::overlay: + lua_pushstring(L, "overlay"); + break; + case BlendMode::darken: + lua_pushstring(L, "darken"); + break; + case BlendMode::lighten: + lua_pushstring(L, "lighten"); + break; + case BlendMode::colorDodge: + lua_pushstring(L, "colorDodge"); + break; + case BlendMode::colorBurn: + lua_pushstring(L, "colorBurn"); + break; + case BlendMode::hardLight: + lua_pushstring(L, "hardLight"); + break; + case BlendMode::softLight: + lua_pushstring(L, "softLight"); + break; + case BlendMode::difference: + lua_pushstring(L, "difference"); + break; + case BlendMode::exclusion: + lua_pushstring(L, "exclusion"); + break; + case BlendMode::multiply: + lua_pushstring(L, "multiply"); + break; + case BlendMode::hue: + lua_pushstring(L, "hue"); + break; + case BlendMode::saturation: + lua_pushstring(L, "saturation"); + break; + case BlendMode::color: + lua_pushstring(L, "color"); + break; + case BlendMode::luminosity: + lua_pushstring(L, "luminosity"); + break; + default: + RIVE_UNREACHABLE(); + } +} + +void ScriptedPaintData::pushFeather(lua_State* L) +{ + lua_pushnumber(L, m_feather); +} +void ScriptedPaintData::pushGradient(lua_State* L) +{ + if (m_gradient) + { + ScriptedGradient* gradient = lua_newrive(L); + gradient->shader = m_gradient; + } + else + { + lua_pushnil(L); + } +} +void ScriptedPaintData::pushColor(lua_State* L) +{ + lua_pushunsigned(L, m_color); +} + +static int paint_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + auto scriptedPaint = (ScriptedPaintData*)lua_touserdata(L, 1); + switch (atom) + { + case (int)LuaAtoms::style: + scriptedPaint->pushStyle(L); + return 1; + case (int)LuaAtoms::join: + scriptedPaint->pushJoin(L); + return 1; + case (int)LuaAtoms::cap: + scriptedPaint->pushCap(L); + return 1; + case (int)LuaAtoms::thickness: + scriptedPaint->pushThickness(L); + return 1; + case (int)LuaAtoms::blendMode: + scriptedPaint->pushBlendMode(L); + return 1; + case (int)LuaAtoms::feather: + scriptedPaint->pushFeather(L); + return 1; + case (int)LuaAtoms::gradient: + scriptedPaint->pushGradient(L); + return 1; + case (int)LuaAtoms::color: + scriptedPaint->pushColor(L); + return 1; + default: + return 0; + } +} + +static int paint_copy(lua_State* L) +{ + int argCount = lua_gettop(L); + + auto scriptedPaint = lua_torive(L, 1); + + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + auto scriptedPaintCopy = + lua_newrive(L, context->factory(), *scriptedPaint); + + if (argCount == 2) + { + setPropertiesFromDefinitionTable(L, scriptedPaintCopy, 2); + } + return 1; +} + +static int paint_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::copy: + return paint_copy(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedMat2D::luaName); + return 0; +} + +static const luaL_Reg paintStaticMethods[] = { + {"new", paint_new}, + {"with", paint_with}, + {NULL, NULL}, +}; + +int luaopen_rive_paint(lua_State* L) +{ + lua_register_rive(L); + + lua_pushcfunction(L, paint_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + luaL_register(L, ScriptedPaint::luaName, paintStaticMethods); + lua_register_rive(L); + + lua_pushcfunction(L, paint_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, paint_newindex, nullptr); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, paint_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_path.cpp b/thirdparty/rive/source/lua/renderer/lua_path.cpp new file mode 100644 index 000000000..86bfd23dc --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_path.cpp @@ -0,0 +1,655 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/math/vec2d.hpp" +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/math/raw_path.hpp" +#include "rive/math/contour_measure.hpp" +#include "rive/math/path_measure.hpp" +#include "rive/factory.hpp" + +#include +#include + +using namespace rive; + +RenderPath* ScriptedPathData::renderPath(lua_State* L) +{ + if (m_isRenderPathDirty) + { + m_isRenderPathDirty = false; + const bool sameFrameRebuild = + m_renderPath && m_renderFrameId == Artboard::frameId(); + m_renderFrameId = Artboard::frameId(); + + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + if (!m_renderPath || sameFrameRebuild) + { + m_renderPath = context->factory()->makeEmptyRenderPath(); + m_renderPath->fillRule(FillRule::clockwise); + } + else + { + m_renderPath->rewind(); + } + m_renderPath->addRawPath(rawPath); + } + + return m_renderPath.get(); +} + +ScriptedPathData::ScriptedPathData(const RawPath* path) +{ + rawPath.addPath(*path); +} + +int ScriptedPathData::totalCommands() { return (int)rawPath.verbs().size(); } + +static ScriptedPath* lua_pushpath(lua_State* L) +{ + return lua_newrive(L); +} + +static int path_new(lua_State* L) +{ + lua_pushpath(L); + return 1; +} + +static int path_moveTo(lua_State* L) +{ + auto scriptedPath = lua_torive(L, 1); + auto vec = lua_checkvec2d(L, 2); + scriptedPath->rawPath.move(*vec); + scriptedPath->markDirty(); + return 0; +} + +static int path_lineTo(lua_State* L) +{ + auto scriptedPath = lua_torive(L, 1); + auto vec = lua_checkvec2d(L, 2); + scriptedPath->rawPath.line(*vec); + scriptedPath->markDirty(); + return 0; +} + +static int path_quadTo(lua_State* L) +{ + auto scriptedPath = lua_torive(L, 1); + auto p1 = lua_checkvec2d(L, 2); + auto p2 = lua_checkvec2d(L, 3); + scriptedPath->rawPath.quad(*p1, *p2); + scriptedPath->markDirty(); + return 0; +} + +static int path_cubicTo(lua_State* L) +{ + auto scriptedPath = lua_torive(L, 1); + auto p1 = lua_checkvec2d(L, 2); + auto p2 = lua_checkvec2d(L, 3); + auto p3 = lua_checkvec2d(L, 4); + scriptedPath->rawPath.cubic(*p1, *p2, *p3); + scriptedPath->markDirty(); + return 0; +} + +static int path_close(lua_State* L) +{ + auto scriptedPath = lua_torive(L, 1); + scriptedPath->rawPath.close(); + scriptedPath->markDirty(); + return 0; +} + +static int path_reset(lua_State* L) +{ + auto scriptedPath = lua_torive(L, 1); + scriptedPath->rawPath.reset(); + scriptedPath->markDirty(); + return 0; +} + +static int path_add(lua_State* L) +{ + auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1); + auto scriptedPathToAdd = (ScriptedPathData*)lua_touserdata(L, 2); + const Mat2D* transform = nullptr; + int nargs = lua_gettop(L); + if (nargs == 3) + { + auto matrix = lua_torive(L, 3); + transform = &matrix->value; + } + scriptedPath->rawPath.addPath(scriptedPathToAdd->rawPath, transform); + scriptedPath->markDirty(); + return 0; +} + +static int path_command(lua_State* L) +{ + auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1); + auto rawPath = scriptedPath->rawPath; + auto verbs = rawPath.verbs(); + auto points = rawPath.points(); + auto verbIndex = int(luaL_checknumber(L, 2)); + auto verbName = "none"; + std::vector verbPoints; + + if (verbIndex >= 0 && verbIndex < (int)verbs.size()) + { + auto verb = verbs[verbIndex]; + + // Calculate the point index for this verb by summing point counts of + // previous verbs + int pointIndex = 0; + for (int i = 0; i < verbIndex; i++) + { + pointIndex += path_verb_to_point_count(verbs[i]); + } + + switch (verb) + { + case PathVerb::move: + verbName = "moveTo"; + if (pointIndex < (int)points.size()) + { + verbPoints.push_back(points[pointIndex]); + } + break; + case PathVerb::line: + verbName = "lineTo"; + if (pointIndex < (int)points.size()) + { + verbPoints.push_back(points[pointIndex]); + } + break; + case PathVerb::quad: + verbName = "quadTo"; + if (pointIndex + 1 < (int)points.size()) + { + verbPoints.push_back(points[pointIndex]); + verbPoints.push_back(points[pointIndex + 1]); + } + break; + case PathVerb::cubic: + verbName = "cubicTo"; + if (pointIndex + 2 < (int)points.size()) + { + verbPoints.push_back(points[pointIndex]); + verbPoints.push_back(points[pointIndex + 1]); + verbPoints.push_back(points[pointIndex + 2]); + } + break; + case PathVerb::close: + verbName = "close"; + // close has no points + break; + } + } + lua_newrive(L, verbName, verbPoints); + return 1; +} + +static int path_contours(lua_State* L) +{ + auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1); + // Use the copy constructor to ensure ContourMeasure outlives the path + auto iter = make_rcp(scriptedPath->rawPath); + auto firstContour = iter->get()->next(); + if (firstContour) + { + lua_newrive(L, firstContour, iter); + return 1; + } + lua_pushnil(L); + return 1; +} + +static int path_measure(lua_State* L) +{ + auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1); + PathMeasure pathMeasure(&scriptedPath->rawPath); + lua_newrive(L, std::move(pathMeasure)); + return 1; +} + +static int path_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::moveTo: + return path_moveTo(L); + case (int)LuaAtoms::lineTo: + return path_lineTo(L); + case (int)LuaAtoms::quadTo: + return path_quadTo(L); + case (int)LuaAtoms::cubicTo: + return path_cubicTo(L); + case (int)LuaAtoms::close: + return path_close(L); + case (int)LuaAtoms::reset: + return path_reset(L); + case (int)LuaAtoms::add: + return path_add(L); + case (int)LuaAtoms::contours: + return path_contours(L); + case (int)LuaAtoms::measure: + return path_measure(L); + } + } + + luaL_error(L, "%s is not a valid method of %s", str, ScriptedPath::luaName); + return 0; +} + +// ContourMeasure methods +static int contour_measure_length(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + lua_pushnumber(L, scripted->measure()->length()); + return 1; +} + +static int contour_measure_isClosed(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + lua_pushboolean(L, scripted->measure()->isClosed()); + return 1; +} + +static int contour_measure_positionAndTangent(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + float distance = (float)luaL_checknumber(L, 2); + auto posTan = scripted->measure()->getPosTan(distance); + lua_pushvec2d(L, posTan.pos); + lua_pushvec2d(L, posTan.tan); + return 2; +} + +static int contour_measure_warp(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + auto src = lua_checkvec2d(L, 2); + Vec2D result = scripted->measure()->warp(*src); + lua_pushvec2d(L, result); + return 1; +} + +static int contour_measure_extract(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + float startDistance = (float)luaL_checknumber(L, 2); + float endDistance = (float)luaL_checknumber(L, 3); + auto destPath = lua_torive(L, 4); + bool startWithMove = lua_isboolean(L, 5) ? lua_toboolean(L, 5) : true; + scripted->measure()->getSegment(startDistance, + endDistance, + &destPath->rawPath, + startWithMove); + destPath->markDirty(); + return 0; +} + +static int contour_measure_next(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + auto iter = scripted->iter(); + if (iter) + { + auto nextContour = iter->get()->next(); + if (nextContour) + { + // Create new ScriptedContourMeasure with the same rcp iter + // The iter is already advanced, so we can reuse it + lua_newrive(L, nextContour, iter); + return 1; + } + } + lua_pushnil(L); + return 1; +} + +static int path_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + + // If it's not a string/atom, treat it as a numeric index + if (!key) + { + int index = luaL_checkinteger(L, 2); + // Convert from 1-based Lua index to 0-based C++ index + // Replace the index at position 2 with the 0-based version + lua_pushinteger(L, index - 1); // Push 0-based index + lua_replace(L, 2); // Replace the value at position 2 + // Now stack has: 1=path, 2=0-based index, which is what path_command + // expects + return path_command(L); + } + + // String indices are handled by __namecall for methods + return 0; +} + +static int path_length(lua_State* L) +{ + auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1); + + auto totalCommands = scriptedPath->totalCommands(); + lua_pushnumber(L, totalCommands); + return 1; +} + +static int contour_measure_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + switch (atom) + { + case (int)LuaAtoms::length: + return contour_measure_length(L); + case (int)LuaAtoms::isClosed: + return contour_measure_isClosed(L); + case (int)LuaAtoms::next: + return contour_measure_next(L); + default: + return 0; + } +} + +static int contour_measure_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::positionAndTangent: + return contour_measure_positionAndTangent(L); + case (int)LuaAtoms::warp: + return contour_measure_warp(L); + case (int)LuaAtoms::extract: + return contour_measure_extract(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedContourMeasure::luaName); + return 0; +} + +// PathMeasure methods +static int path_measure_length(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + lua_pushnumber(L, scripted->measure()->length()); + return 1; +} + +static int path_measure_isClosed(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + lua_pushboolean(L, scripted->measure()->isClosed()); + return 1; +} + +static int path_measure_positionAndTangent(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + float distance = (float)luaL_checknumber(L, 2); + auto posTanDist = scripted->measure()->atDistance(distance); + lua_pushvec2d(L, posTanDist.pos); + lua_pushvec2d(L, posTanDist.tan); + return 2; +} + +static int path_measure_warp(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + auto src = lua_checkvec2d(L, 2); + // Use atDistance to get position and tangent, then apply warp formula + auto posTanDist = scripted->measure()->atDistance(src->x); + Vec2D result = { + posTanDist.pos.x - posTanDist.tan.y * src->y, + posTanDist.pos.y + posTanDist.tan.x * src->y, + }; + lua_pushvec2d(L, result); + return 1; +} + +static int path_measure_extract(lua_State* L) +{ + auto scripted = lua_torive(L, 1); + float startDistance = (float)luaL_checknumber(L, 2); + float endDistance = (float)luaL_checknumber(L, 3); + auto destPath = lua_torive(L, 4); + bool startWithMove = lua_isboolean(L, 5) ? lua_toboolean(L, 5) : true; + scripted->measure()->getSegment(startDistance, + endDistance, + &destPath->rawPath, + startWithMove); + destPath->markDirty(); + return 0; +} + +static int path_measure_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + if (!key) + { + luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING)); + return 0; + } + + switch (atom) + { + case (int)LuaAtoms::length: + return path_measure_length(L); + case (int)LuaAtoms::isClosed: + return path_measure_isClosed(L); + default: + return 0; + } +} + +static int path_measure_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::positionAndTangent: + return path_measure_positionAndTangent(L); + case (int)LuaAtoms::warp: + return path_measure_warp(L); + case (int)LuaAtoms::extract: + return path_measure_extract(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedPathMeasure::luaName); + return 0; +} + +static int property_namecall_atom(lua_State* L, + ScriptedPathCommand* pathCommand, + uint8_t tag, + int atom, + bool& error) +{ + switch (atom) + { + case (int)LuaAtoms::type: + { + lua_pushstring(L, pathCommand->type().c_str()); + return 1; + } + } + error = true; + return 0; +} + +static int pathCommand_index(lua_State* L) +{ + int atom; + const char* key = lua_tostringatom(L, 2, &atom); + + // If it's not a string/atom, treat it as a numeric index + if (!key) + { + int luaIndex = luaL_checkinteger(L, 2); + int index = luaIndex - 1; + + auto pathCommand = (ScriptedPathCommand*)lua_touserdata(L, 1); + auto points = pathCommand->points(); + auto size = (int)points.size(); + if (index >= 0 && index < size) + { + auto point = points[index]; + lua_pushvec2d(L, point); + return 1; + } + } + else + { + int atom; + lua_tostringatom(L, 2, &atom); + + size_t namelen = 0; + const char* name = luaL_checklstring(L, 2, &namelen); + + auto tag = lua_userdatatag(L, 1); + auto pathCommand = (ScriptedPathCommand*)lua_touserdata(L, 1); + + bool error = false; + int stackChange = + property_namecall_atom(L, pathCommand, tag, atom, error); + if (!error) + { + return stackChange; + } + + luaL_error(L, "'%s' is not a valid index of PathCommand", name); + return 0; + } + return 0; +} + +static int pathCommand_length(lua_State* L) +{ + auto pathCommand = (ScriptedPathCommand*)lua_touserdata(L, 1); + + auto points = pathCommand->points(); + lua_pushnumber(L, (int)points.size()); + return 1; +} + +static int pathCommand_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedPathCommand::luaName); + return 0; +} + +static const luaL_Reg pathStaticMethods[] = { + {"new", path_new}, + {NULL, NULL}, +}; + +int luaopen_rive_path(lua_State* L) +{ + { + lua_register_rive(L); + + lua_pushcfunction(L, path_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, path_length, nullptr); + lua_setfield(L, -2, "__len"); + + lua_pushcfunction(L, path_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + { + luaL_register(L, ScriptedPath::luaName, pathStaticMethods); + lua_register_rive(L); + + lua_pushcfunction(L, path_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, path_length, nullptr); + lua_setfield(L, -2, "__len"); + + lua_pushcfunction(L, path_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + { + lua_register_rive(L); + + lua_pushcfunction(L, pathCommand_index, nullptr); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, pathCommand_length, nullptr); + lua_setfield(L, -2, "__len"); + + lua_pushcfunction(L, pathCommand_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + } + + // Register ContourMeasure + lua_register_rive(L); + lua_pushcfunction(L, contour_measure_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, contour_measure_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + // Register PathMeasure + lua_register_rive(L); + lua_pushcfunction(L, path_measure_index, nullptr); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, path_measure_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + + return 1; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_renderer.cpp b/thirdparty/rive/source/lua/renderer/lua_renderer.cpp new file mode 100644 index 000000000..d3f33752a --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_renderer.cpp @@ -0,0 +1,214 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" + +#include +#include + +using namespace rive; + +bool ScriptedRenderer::end() +{ + assert(m_renderer != nullptr); + auto count = m_saveCount; + + while (count) + { + m_renderer->restore(); + count--; + } + // if (m_saveCount != 0) + // { + // luaL_error(L, + // "%s save/restore stack was unbalanced with %i remaining " + // "saves to restore.", + // ScriptedRenderer::luaName, + // m_saveCount); + // } + m_renderer = nullptr; + bool success = m_saveCount == 0; + m_saveCount = 0; + return success; +} + +void ScriptedRenderer::save(lua_State* L) +{ + validate(L); + m_renderer->save(); + m_saveCount++; +} + +void ScriptedRenderer::restore(lua_State* L) +{ + validate(L); + if (m_saveCount == 0) + { + luaL_error(L, + "%s save/restore stack was unbalanced by trying to restore " + "more times than saved.", + ScriptedRenderer::luaName); + } + m_renderer->restore(); + m_saveCount--; +} + +void ScriptedRenderer::transform(lua_State* L, const Mat2D& mat2d) +{ + validate(L); + m_renderer->transform(mat2d); +} + +void ScriptedRenderer::clipPath(lua_State* L, ScriptedPathData* path) +{ + validate(L); + m_renderer->clipPath(path->renderPath(L)); +} + +static int renderer_drawImage(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + auto scriptedImage = lua_torive(L, 2); + auto scriptedSampler = lua_torive(L, 3); + auto blendMode = lua_toblendmode(L, 4); + auto opacity = float(luaL_checknumber(L, 5)); + + auto renderer = scriptedRenderer->validate(L); + renderer->drawImage(scriptedImage->image.get(), + scriptedSampler->sampler, + blendMode, + opacity); + + return 0; +} + +static int renderer_drawImageMesh(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + auto scriptedImage = lua_torive(L, 2); + auto scriptedSampler = lua_torive(L, 3); + auto scriptedVertexBuffer = lua_torive(L, 4); + auto scriptedUVBuffer = lua_torive(L, 5); + auto scriptedTriangleBuffer = lua_torive(L, 6); + auto blendMode = lua_toblendmode(L, 7); + auto opacity = float(luaL_checknumber(L, 8)); + + // Ensure the buffers are created before drawing + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + Factory* factory = context->factory(); + scriptedVertexBuffer->update(factory); + scriptedUVBuffer->update(factory); + scriptedTriangleBuffer->update(factory); + + auto renderer = scriptedRenderer->validate(L); + renderer->drawImageMesh(scriptedImage->image.get(), + scriptedSampler->sampler, + scriptedVertexBuffer->vertexBuffer, + scriptedUVBuffer->vertexBuffer, + scriptedTriangleBuffer->indexBuffer, + (uint32_t)scriptedVertexBuffer->values.size(), + (uint32_t)scriptedTriangleBuffer->values.size(), + blendMode, + opacity); + + return 0; +} + +Renderer* ScriptedRenderer::validate(lua_State* L) +{ + if (m_renderer == nullptr) + { + luaL_error(L, "%s is no longer valid.", ScriptedRenderer::luaName); + } + return m_renderer; +} + +static int renderer_drawPath(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + auto scriptedPath = lua_torive(L, 2); + auto scriptedPaint = lua_torive(L, 3); + + auto renderer = scriptedRenderer->validate(L); + renderer->drawPath(scriptedPath->renderPath(L), + scriptedPaint->renderPaint.get()); + + return 0; +} + +static int renderer_save(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + scriptedRenderer->save(L); + + return 0; +} + +static int renderer_restore(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + scriptedRenderer->restore(L); + + return 0; +} + +static int renderer_clip_path(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + auto path = lua_torive(L, 2); + scriptedRenderer->clipPath(L, path); + return 0; +} + +static int renderer_transform(lua_State* L) +{ + auto scriptedRenderer = lua_torive(L, 1); + auto mat2d = lua_torive(L, 2); + scriptedRenderer->transform(L, mat2d->value); + return 0; +} + +static int renderer_namecall(lua_State* L) +{ + int atom; + const char* str = lua_namecallatom(L, &atom); + if (str != nullptr) + { + switch (atom) + { + case (int)LuaAtoms::drawPath: + return renderer_drawPath(L); + case (int)LuaAtoms::save: + return renderer_save(L); + case (int)LuaAtoms::restore: + return renderer_restore(L); + case (int)LuaAtoms::clipPath: + return renderer_clip_path(L); + case (int)LuaAtoms::transform: + return renderer_transform(L); + case (int)LuaAtoms::drawImage: + return renderer_drawImage(L); + case (int)LuaAtoms::drawImageMesh: + return renderer_drawImageMesh(L); + } + } + + luaL_error(L, + "%s is not a valid method of %s", + str, + ScriptedRenderer::luaName); + return 0; +} + +int luaopen_rive_renderer(lua_State* L) +{ + lua_register_rive(L); + + lua_pushcfunction(L, renderer_namecall, nullptr); + lua_setfield(L, -2, "__namecall"); + + lua_setreadonly(L, -1, true); + lua_pop(L, 1); // pop the metatable + return 0; +} + +#endif diff --git a/thirdparty/rive/source/lua/renderer/lua_renderer_library.cpp b/thirdparty/rive/source/lua/renderer/lua_renderer_library.cpp new file mode 100644 index 000000000..1fd4d5cff --- /dev/null +++ b/thirdparty/rive/source/lua/renderer/lua_renderer_library.cpp @@ -0,0 +1,38 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" + +int luaopen_rive_path(lua_State* L); +int luaopen_rive_gradient(lua_State* L); +int luaopen_rive_mesh(lua_State* L); +int luaopen_rive_image(lua_State* L); +int luaopen_rive_blob(lua_State* L); +int luaopen_rive_paint(lua_State* L); +int luaopen_rive_renderer(lua_State* L); +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) +int luaopen_rive_gpu(lua_State* L); +#endif + +static const lua_CFunction rendererTypes[] = { + luaopen_rive_path, + luaopen_rive_gradient, + luaopen_rive_mesh, + luaopen_rive_image, + luaopen_rive_blob, + luaopen_rive_paint, + luaopen_rive_renderer, +#if defined(RIVE_CANVAS) && defined(RIVE_ORE) + luaopen_rive_gpu, +#endif +}; + +int luaopen_rive_renderer_library(lua_State* L) +{ + int added = 0; + for (auto type : rendererTypes) + { + added += type(L); + } + return added; +} + +#endif diff --git a/thirdparty/rive/source/lua/rive_lua_libs.cpp b/thirdparty/rive/source/lua/rive_lua_libs.cpp new file mode 100644 index 000000000..7c9ac12a9 --- /dev/null +++ b/thirdparty/rive/source/lua/rive_lua_libs.cpp @@ -0,0 +1,1018 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/async/work_pool.hpp" +#include "lualib.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace rive; + +int luaopen_rive_base(lua_State* L); +int luaopen_rive_math(lua_State* L); +int luaopen_rive_renderer_library(lua_State* L); +int luaopen_rive_properties(lua_State* L); +int luaopen_rive_artboards(lua_State* L); +int luaopen_rive_data_values(lua_State* L); +int luaopen_rive_data_context(lua_State* L); +int luaopen_rive_input(lua_State* L); +int luaopen_rive_contex(lua_State* L); +int luaopen_rive_audio(lua_State* L); +extern "C" int luaopen_rive_buffer_ext(lua_State* L); + +std::unordered_map atoms = { + {"length", (int16_t)LuaAtoms::length}, + {"lengthSquared", (int16_t)LuaAtoms::lengthSquared}, + {"normalized", (int16_t)LuaAtoms::normalized}, + {"distance", (int16_t)LuaAtoms::distance}, + {"distanceSquared", (int16_t)LuaAtoms::distanceSquared}, + {"dot", (int16_t)LuaAtoms::dot}, + {"lerp", (int16_t)LuaAtoms::lerp}, + {"moveTo", (int16_t)LuaAtoms::moveTo}, + {"lineTo", (int16_t)LuaAtoms::lineTo}, + {"quadTo", (int16_t)LuaAtoms::quadTo}, + {"cubicTo", (int16_t)LuaAtoms::cubicTo}, + {"close", (int16_t)LuaAtoms::close}, + {"type", (int16_t)LuaAtoms::type}, + {"reset", (int16_t)LuaAtoms::reset}, + {"add", (int16_t)LuaAtoms::add}, + {"contours", (int16_t)LuaAtoms::contours}, + {"measure", (int16_t)LuaAtoms::measure}, + {"invert", (int16_t)LuaAtoms::invert}, + {"isIdentity", (int16_t)LuaAtoms::isIdentity}, + {"width", (int16_t)LuaAtoms::width}, + {"height", (int16_t)LuaAtoms::height}, + {"clamp", (int16_t)LuaAtoms::clamp}, + {"repeat", (int16_t)LuaAtoms::repeat}, + {"mirror", (int16_t)LuaAtoms::mirror}, + {"bilinear", (int16_t)LuaAtoms::bilinear}, + {"nearest", (int16_t)LuaAtoms::nearest}, + {"style", (int16_t)LuaAtoms::style}, + {"join", (int16_t)LuaAtoms::join}, + {"cap", (int16_t)LuaAtoms::cap}, + {"thickness", (int16_t)LuaAtoms::thickness}, + {"blendMode", (int16_t)LuaAtoms::blendMode}, + {"feather", (int16_t)LuaAtoms::feather}, + {"gradient", (int16_t)LuaAtoms::gradient}, + {"color", (int16_t)LuaAtoms::color}, + {"stroke", (int16_t)LuaAtoms::stroke}, + {"fill", (int16_t)LuaAtoms::fill}, + {"miter", (int16_t)LuaAtoms::miter}, + {"round", (int16_t)LuaAtoms::round}, + {"bevel", (int16_t)LuaAtoms::bevel}, + {"butt", (int16_t)LuaAtoms::butt}, + {"square", (int16_t)LuaAtoms::square}, + {"srcOver", (int16_t)LuaAtoms::srcOver}, + {"screen", (int16_t)LuaAtoms::screen}, + {"overlay", (int16_t)LuaAtoms::overlay}, + {"darken", (int16_t)LuaAtoms::darken}, + {"lighten", (int16_t)LuaAtoms::lighten}, + {"colorDodge", (int16_t)LuaAtoms::colorDodge}, + {"colorBurn", (int16_t)LuaAtoms::colorBurn}, + {"hardLight", (int16_t)LuaAtoms::hardLight}, + {"softLight", (int16_t)LuaAtoms::softLight}, + {"difference", (int16_t)LuaAtoms::difference}, + {"exclusion", (int16_t)LuaAtoms::exclusion}, + {"multiply", (int16_t)LuaAtoms::multiply}, + {"hue", (int16_t)LuaAtoms::hue}, + {"saturation", (int16_t)LuaAtoms::saturation}, + {"luminosity", (int16_t)LuaAtoms::luminosity}, + {"copy", (int16_t)LuaAtoms::copy}, + {"drawPath", (int16_t)LuaAtoms::drawPath}, + {"drawImage", (int16_t)LuaAtoms::drawImage}, + {"drawImageMesh", (int16_t)LuaAtoms::drawImageMesh}, + {"clipPath", (int16_t)LuaAtoms::clipPath}, + {"save", (int16_t)LuaAtoms::save}, + {"restore", (int16_t)LuaAtoms::restore}, + {"transform", (int16_t)LuaAtoms::transform}, + {"value", (int16_t)LuaAtoms::value}, + {"red", (int16_t)LuaAtoms::red}, + {"green", (int16_t)LuaAtoms::green}, + {"blue", (int16_t)LuaAtoms::blue}, + {"alpha", (int16_t)LuaAtoms::alpha}, + {"getNumber", (int16_t)LuaAtoms::getNumber}, + {"getTrigger", (int16_t)LuaAtoms::getTrigger}, + {"getString", (int16_t)LuaAtoms::getString}, + {"getBoolean", (int16_t)LuaAtoms::getBoolean}, + {"getColor", (int16_t)LuaAtoms::getColor}, + {"getList", (int16_t)LuaAtoms::getList}, + {"getViewModel", (int16_t)LuaAtoms::getViewModel}, + {"getEnum", (int16_t)LuaAtoms::getEnum}, + {"getIndex", (int16_t)LuaAtoms::getIndex}, + {"getImage", (int16_t)LuaAtoms::getImage}, + {"values", (int16_t)LuaAtoms::values}, + {"addListener", (int16_t)LuaAtoms::addListener}, + {"removeListener", (int16_t)LuaAtoms::removeListener}, + {"fire", (int16_t)LuaAtoms::fire}, + {"push", (int16_t)LuaAtoms::push}, + {"insert", (int16_t)LuaAtoms::insert}, + {"pop", (int16_t)LuaAtoms::pop}, + {"swap", (int16_t)LuaAtoms::swap}, + {"shift", (int16_t)LuaAtoms::shift}, + {"clear", (int16_t)LuaAtoms::clear}, + {"draw", (int16_t)LuaAtoms::draw}, + {"advance", (int16_t)LuaAtoms::advance}, + {"frameOrigin", (int16_t)LuaAtoms::frameOrigin}, + {"data", (int16_t)LuaAtoms::data}, + {"instance", (int16_t)LuaAtoms::instance}, + {"animation", (int16_t)LuaAtoms::animation}, + {"new", (int16_t)LuaAtoms::newAtom}, + {"bounds", (int16_t)LuaAtoms::bounds}, + {"pointerDown", (int16_t)LuaAtoms::pointerDown}, + {"pointerUp", (int16_t)LuaAtoms::pointerUp}, + {"pointerMove", (int16_t)LuaAtoms::pointerMove}, + {"pointerExit", (int16_t)LuaAtoms::pointerExit}, + {"isNumber", (int16_t)LuaAtoms::isNumber}, + {"isString", (int16_t)LuaAtoms::isString}, + {"isBoolean", (int16_t)LuaAtoms::isBoolean}, + {"isColor", (int16_t)LuaAtoms::isColor}, + {"hit", (int16_t)LuaAtoms::hit}, + {"id", (int16_t)LuaAtoms::id}, + {"position", (int16_t)LuaAtoms::position}, + {"rotation", (int16_t)LuaAtoms::rotation}, + {"scale", (int16_t)LuaAtoms::scale}, + {"worldTransform", (int16_t)LuaAtoms::worldTransform}, + {"scaleX", (int16_t)LuaAtoms::scaleX}, + {"scaleY", (int16_t)LuaAtoms::scaleY}, + {"decompose", (int16_t)LuaAtoms::decompose}, + {"children", (int16_t)LuaAtoms::children}, + {"parent", (int16_t)LuaAtoms::parent}, + {"node", (int16_t)LuaAtoms::node}, + {"paint", (int16_t)LuaAtoms::paint}, + {"asPath", (int16_t)LuaAtoms::asPath}, + {"asPaint", (int16_t)LuaAtoms::asPaint}, + {"addToPath", (int16_t)LuaAtoms::addToPath}, + {"positionAndTangent", (int16_t)LuaAtoms::positionAndTangent}, + {"warp", (int16_t)LuaAtoms::warp}, + {"extract", (int16_t)LuaAtoms::extract}, + {"next", (int16_t)LuaAtoms::next}, + {"isClosed", (int16_t)LuaAtoms::isClosed}, + {"markNeedsUpdate", (int16_t)LuaAtoms::markNeedsUpdate}, + {"viewModel", (int16_t)LuaAtoms::viewModel}, + {"rootViewModel", (int16_t)LuaAtoms::rootViewModel}, + {"dataContext", (int16_t)LuaAtoms::dataContext}, + {"image", (int16_t)LuaAtoms::image}, + {"blob", (int16_t)LuaAtoms::blob}, + {"size", (int16_t)LuaAtoms::size}, + {"duration", (int16_t)LuaAtoms::duration}, + {"setTime", (int16_t)LuaAtoms::setTime}, + {"setTimeFrames", (int16_t)LuaAtoms::setTimeFrames}, + {"setTimePercentage", (int16_t)LuaAtoms::setTimePercentage}, + {"isPointerEvent", (int16_t)LuaAtoms::isPointerEvent}, + {"isKeyboardEvent", (int16_t)LuaAtoms::isKeyboardEvent}, + {"isTextInput", (int16_t)LuaAtoms::isTextInput}, + {"previousPosition", (int16_t)LuaAtoms::previousPosition}, + {"timeStamp", (int16_t)LuaAtoms::timeStamp}, + {"isFocus", (int16_t)LuaAtoms::isFocus}, + {"isReportedEvent", (int16_t)LuaAtoms::isReportedEvent}, + {"isViewModelChange", (int16_t)LuaAtoms::isViewModelChange}, + {"isNone", (int16_t)LuaAtoms::isNone}, + {"isGamepad", (int16_t)LuaAtoms::isGamepad}, + {"asPointerEvent", (int16_t)LuaAtoms::asPointerEvent}, + {"asKeyboardEvent", (int16_t)LuaAtoms::asKeyboardEvent}, + {"asTextInput", (int16_t)LuaAtoms::asTextInput}, + {"asFocus", (int16_t)LuaAtoms::asFocus}, + {"asReportedEvent", (int16_t)LuaAtoms::asReportedEvent}, + {"asViewModelChange", (int16_t)LuaAtoms::asViewModelChange}, + {"asGamepad", (int16_t)LuaAtoms::asGamepad}, + {"asNone", (int16_t)LuaAtoms::asNone}, + {"key", (int16_t)LuaAtoms::key}, + {"shift", (int16_t)LuaAtoms::shift}, + {"alt", (int16_t)LuaAtoms::alt}, + {"control", (int16_t)LuaAtoms::control}, + {"meta", (int16_t)LuaAtoms::meta}, + {"text", (int16_t)LuaAtoms::text}, + {"phase", (int16_t)LuaAtoms::phase}, + {"delaySeconds", (int16_t)LuaAtoms::delaySeconds}, + {"deviceId", (int16_t)LuaAtoms::deviceId}, + {"buttonMask", (int16_t)LuaAtoms::buttonMask}, + {"axis0", (int16_t)LuaAtoms::axis0}, + {"remove", (int16_t)LuaAtoms::remove}, + {"removeAt", (int16_t)LuaAtoms::removeAt}, + {"removeAllOf", (int16_t)LuaAtoms::removeAllOf}, + {"audio", (int16_t)LuaAtoms::audio}, + {"play", (int16_t)LuaAtoms::play}, + {"playAtTime", (int16_t)LuaAtoms::playAtTime}, + {"playInTime", (int16_t)LuaAtoms::playInTime}, + {"playAtFrame", (int16_t)LuaAtoms::playAtFrame}, + {"playInFrame", (int16_t)LuaAtoms::playInFrame}, + {"stop", (int16_t)LuaAtoms::stop}, + {"pause", (int16_t)LuaAtoms::pause}, + {"resume", (int16_t)LuaAtoms::resume}, + {"seek", (int16_t)LuaAtoms::seek}, + {"seekFrame", (int16_t)LuaAtoms::seekFrame}, + {"volume", (int16_t)LuaAtoms::volume}, + {"completed", (int16_t)LuaAtoms::completed}, + {"time", (int16_t)LuaAtoms::time}, + {"timeFrame", (int16_t)LuaAtoms::timeFrame}, + {"sampleRate", (int16_t)LuaAtoms::sampleRate}, + // GPU + {"write", (int16_t)LuaAtoms::write}, + {"upload", (int16_t)LuaAtoms::upload}, + {"view", (int16_t)LuaAtoms::view}, + {"setPipeline", (int16_t)LuaAtoms::setPipeline}, + {"setVertexBuffer", (int16_t)LuaAtoms::setVertexBuffer}, + {"setIndexBuffer", (int16_t)LuaAtoms::setIndexBuffer}, + {"setBindGroup", (int16_t)LuaAtoms::setBindGroup}, + {"setViewport", (int16_t)LuaAtoms::setViewport}, + {"setScissorRect", (int16_t)LuaAtoms::setScissorRect}, + {"setStencilReference", (int16_t)LuaAtoms::setStencilReference}, + {"drawIndexed", (int16_t)LuaAtoms::drawIndexed}, + {"finish", (int16_t)LuaAtoms::finish}, + {"beginRenderPass", (int16_t)LuaAtoms::beginRenderPass}, + {"beginFrame", (int16_t)LuaAtoms::beginFrame}, + {"endFrame", (int16_t)LuaAtoms::endFrame}, + {"colorView", (int16_t)LuaAtoms::colorView}, + {"depthView", (int16_t)LuaAtoms::depthView}, + {"setBlendColor", (int16_t)LuaAtoms::setBlendColor}, + {"resize", (int16_t)LuaAtoms::resize}, + {"canvas", (int16_t)LuaAtoms::canvas}, + {"gpuCanvas", (int16_t)LuaAtoms::gpuCanvas}, + {"features", (int16_t)LuaAtoms::features}, + {"drawCanvas", (int16_t)LuaAtoms::drawCanvas}, + {"loadShader", (int16_t)LuaAtoms::loadShader}, + {"format", (int16_t)LuaAtoms::format}, + {"preferredCanvasFormat", (int16_t)LuaAtoms::preferredCanvasFormat}, + {"andThen", (int16_t)LuaAtoms::andThen}, + {"catch", (int16_t)LuaAtoms::catch_}, + {"finally", (int16_t)LuaAtoms::finally_}, + {"cancel", (int16_t)LuaAtoms::cancel}, + {"onCancel", (int16_t)LuaAtoms::onCancel}, + {"getStatus", (int16_t)LuaAtoms::getStatus}, + {"decodeImage", (int16_t)LuaAtoms::decodeImage}, + // Mat4 + {"transpose", (int16_t)LuaAtoms::transpose}, + {"transformPoint", (int16_t)LuaAtoms::transformPoint}, + {"transformVec4", (int16_t)LuaAtoms::transformVec4}, + {"writeToBuffer", (int16_t)LuaAtoms::writeToBuffer}, + {"invertAffine", (int16_t)LuaAtoms::invertAffine}, +}; + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_MATHLIBNAME, luaopen_math}, + {"rive", luaopen_rive_base}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_UTF8LIBNAME, luaopen_utf8}, + {LUA_BUFFERLIBNAME, luaopen_buffer}, + {LUA_BITLIBNAME, luaopen_bit32}, + {"math", luaopen_rive_math}, + {"renderer", luaopen_rive_renderer_library}, + {"properties", luaopen_rive_properties}, + {"artboard", luaopen_rive_artboards}, + {"dataValue", luaopen_rive_data_values}, + {"input", luaopen_rive_input}, + {"context", luaopen_rive_contex}, + {"dataContext", luaopen_rive_data_context}, + {"audio", luaopen_rive_audio}, + {"promise", luaopen_rive_promise}, + {NULL, NULL}, +}; + +namespace rive +{ +int luaopen_rive(lua_State* L) +{ + lua_callbacks(L)->useratom = + [](lua_State*, const char* s, size_t l) -> int16_t { + auto itr = atoms.find(s); + if (itr != atoms.end()) + { + return itr->second; + } + + return -1; + }; + + const luaL_Reg* lib = lualibs; + for (; lib->func; lib++) + { + lua_pushcfunction(L, lib->func, NULL); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } + + // Extend the buffer library with SIMD-accelerated functions + // (readf16, writef16, stridedcopy, convert). + luaopen_rive_buffer_ext(L); + + return 0; +} + +int rive_luaErrorHandler(lua_State* L) +{ + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + context->printError(L); + + // Optionally, you can push a new value onto the stack to be returned by + // lua_pcall For example, push a specific error code or a more detailed + // message + const char* error = lua_tostring(L, -1); + lua_pushstring(L, error); + return 1; // Number of return values + // return 0; +} + +int rive_lua_pcall(lua_State* state, int nargs, int nresults) +{ + ScriptingContext* context = + static_cast(lua_getthreaddata(state)); + + return context->pCall(state, nargs, nresults); +} + +int rive_lua_pcall_with_context(lua_State* state, + ScriptedObject* scriptedObject, + int nargs, + int nresults) +{ + ScriptingContext* context = + static_cast(lua_getthreaddata(state)); + ScopedScriptedObjectContext scope(context, scriptedObject); + return context->pCall(state, nargs, nresults); +} + +int rive_lua_pushRef(lua_State* state, int ref) +{ + lua_checkstack(state, 1); + return lua_rawgeti(state, luaRegistryIndex, ref); +} + +void rive_lua_pop(lua_State* state, int count) +{ + lua_settop(state, -count - 1); +} + +static void* l_alloc(void* ud, void* ptr, size_t osize, size_t nsize) +{ + (void)ud; + (void)osize; + if (nsize == 0) + { + free(ptr); + // delete[] (uint8_t*)ptr; + return NULL; + } + else + { + // auto nptr = new uint8_t[nsize]; + // memcpy(nptr, ptr, std::min(nsize, osize)); + // delete[] (uint8_t*)ptr; + // return nptr; + return realloc(ptr, nsize); + } +} + +static const char* registeredCacheTableKey = "_MODULES"; + +static int checkRegisteredModules(lua_State* L, const char* path) +{ + luaL_findtable(L, LUA_REGISTRYINDEX, registeredCacheTableKey, 1); + lua_getfield(L, -1, path); + if (lua_isnil(L, -1)) + { + lua_pop(L, 2); + return 0; + } + + lua_remove(L, -2); + return 1; +} + +static int lua_requireinternal(lua_State* L, const char* requirerChunkname) +{ + // Discard extra arguments, we only use path + lua_settop(L, 1); + const char* path = luaL_checkstring(L, 1); + + if (checkRegisteredModules(L, path) == 1) + { + return 1; + } + + // Record missing dependency if we're registering a module + if (requirerChunkname) + { + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + if (context) + { + context->recordMissingDependency(requirerChunkname, path); + } + } + + luaL_error(L, "require could not find a script named %s", path); + return 0; +} + +static int lua_require(lua_State* L) +{ + lua_Debug ar; + int level = 1; + + do + { + if (!lua_getinfo(L, level++, "s", &ar)) + { + luaL_error(L, "require is not supported in this context"); + } + } while (ar.what[0] == 'C'); + + return lua_requireinternal(L, ar.source); +} + +static int luaR_error(lua_State* L) +{ + int level = luaL_optinteger(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) + { + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + lua_error(L); +} + +static int lua_late(lua_State* L) +{ + lua_pushnil(L); + return 1; +} + +void ScriptingVM::init(lua_State* state, ScriptingContext* context) +{ + luaopen_rive(state); + lua_setthreaddata(state, context); + + lua_pushcclosurek(state, lua_require, "require", 0, nullptr); + lua_setglobal(state, "require"); + + lua_pushcclosurek(state, luaR_error, "error", 0, nullptr); + lua_setglobal(state, "error"); + + lua_pushcclosurek(state, lua_late, "late", 0, nullptr); + lua_setglobal(state, "late"); + + luaL_sandbox(state); + luaL_sandboxthread(state); +} + +ScriptingVM::ScriptingVM(std::unique_ptr context) : + m_ownedContext(std::move(context)) +{ + m_state = lua_newstate(l_alloc, nullptr); + init(m_state, m_ownedContext.get()); +} + +ScriptingVM::~ScriptingVM() +{ + // Cancel async tasks before closing Lua state to prevent callbacks + // from accessing dead state. + if (m_ownedContext) + m_ownedContext->shutdownAsyncForState(m_state); + lua_close(m_state); +} + +void ScriptingVM::replaceContext(std::unique_ptr newContext) +{ +#ifdef WITH_RIVE_TOOLS + if (m_ownedContext != nullptr) + { + m_ownedContext->disposeOrphanScriptedProperties(); + } +#endif + m_ownedContext = std::move(newContext); + lua_setthreaddata(m_state, m_ownedContext.get()); +} + +void ScriptingVM::addModule(ModuleDetails* moduleDetails) +{ + context()->addModule(moduleDetails); +} + +void ScriptingVM::performRegistration() +{ + context()->performRegistration(m_state); +} + +// Loads bytecode into a sandboxed thread without executing it. +// On success, pushes the module thread (with loaded closure) onto L's stack. +// Returns true on success. +bool ScriptingVM::loadModule(lua_State* L, + const char* name, + Span bytecode) +{ + if (bytecode.empty()) + { + return false; + } + // module needs to run in a new thread, isolated from the rest + // note: we create ML on main thread so that it doesn't inherit environment + // of L + lua_State* GL = lua_mainthread(L); + lua_State* ML = lua_newthread(GL); + lua_xmove(GL, L, 1); + // new thread needs to have the globals sandboxed + luaL_sandboxthread(ML); + lua_setthreaddata(ML, lua_getthreaddata(L)); + + int status = + luau_load(ML, name, (const char*)bytecode.data(), bytecode.size(), 0); + + if (status != 0) + { + // luau_load failed — error string is on ML stack + lua_xmove(ML, L, 1); + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + context->printError(L); + lua_pop(L, 2); // pop error + thread + return false; + } + + // Thread with loaded closure is on top of L's stack. + return true; +} + +// Executes a previously loaded module thread (on top of L's stack from +// loadModule). On success, replaces the thread with the module result. +// If isUtility, also registers the result in the require cache. +// Returns true on success. +bool ScriptingVM::executeModule(lua_State* L, const char* name, bool isUtility) +{ + // The module thread should be on top of the stack. + lua_State* ML = lua_tothread(L, -1); + if (ML == nullptr) + { + return false; + } + + int status = lua_resume(ML, L, 0); + if (status == 0) + { + if (lua_gettop(ML) == 0) + { + lua_pushfstring(ML, "%s:1: module must return a value", name); + } + else if (!lua_istable(ML, -1) && !lua_isfunction(ML, -1)) + { + lua_pushfstring(ML, + "%s:1: module must return a table or function", + name); + } + } + else if (status == LUA_YIELD) + { + lua_pushfstring(ML, "%s:1: module can not yield", name); + } + else if (!lua_isstring(ML, -1)) + { + lua_pushfstring(ML, "%s:1: unknown error while running module", name); + } + + // add ML result to L stack + lua_xmove(ML, L, 1); + // An error occurred if the top of the stack is a string. + if (lua_isstring(L, -1)) + { + ScriptingContext* context = + static_cast(lua_getthreaddata(L)); + context->printError(L); + lua_pop(L, 2); // pop error + thread + return false; + } + // remove ML thread from L stack + lua_remove(L, -2); + // added one value to L stack: module result + + if (isUtility) + { + // Register into the require cache directly. + luaL_findtable(L, LUA_REGISTRYINDEX, registeredCacheTableKey, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -3); // copy module result (below cache table + name) + lua_settable(L, -3); // cache[name] = result + lua_pop(L, 1); // pop cache table + } + + return true; +} + +static void dump_stack(lua_State* state) +{ + int i; + int top = lua_gettop(state); + for (i = 1; i <= top; i++) + { /* repeat for each level */ + int t = lua_type(state, i); + switch (t) + { + + case LUA_TSTRING: /* strings */ + fprintf(stderr, + " (%i)[STRING] %s\n", + i, + lua_tostring(state, i)); + break; + + case LUA_TBOOLEAN: /* booleans */ + fprintf(stderr, + " (%i)[BOOLEAN] %s\n", + i, + lua_toboolean(state, i) ? "true" : "false"); + break; + + case LUA_TNUMBER: /* numbers */ + fprintf(stderr, + " (%i)[NUMBER] %g\n", + i, + lua_tonumber(state, i)); + break; + + default: /* other values */ + fprintf(stderr, " (%i)[%s]\n", i, lua_typename(state, t)); + break; + } + } + fprintf(stderr, "\n"); /* end the listing */ +} + +void ScriptingVM::dumpStack(lua_State* state) { dump_stack(state); } + +void ScriptingContext::addModule(ModuleDetails* moduleDetails) +{ + m_modulesToRegister.push_back(moduleDetails); + m_moduleLookup[moduleDetails->moduleName()] = moduleDetails; +} + +bool ScriptingContext::tryRegisterModule(lua_State* state, + ModuleDetails* moduleDetails) +{ +#ifndef WITH_RIVE_TOOLS + // In production builds, only allow verified (signed) scripts + if (!moduleDetails->verified()) + { + return false; + } +#endif + const std::string& name = moduleDetails->moduleName(); + bool registerSuccess = false; + int functionRef = 0; + if (moduleDetails->isProtocolScript()) + { + if (ScriptingVM::registerScript(state, + name.c_str(), + moduleDetails->moduleBytecode())) + { + // registerScript leaves the function on the stack + if (static_cast(lua_type(state, -1)) == LUA_TFUNCTION) + { + functionRef = lua_ref(state, -1); + } + lua_pop(state, 1); + registerSuccess = true; + } + } + else + { + if (ScriptingVM::registerModule(state, + name.c_str(), + moduleDetails->moduleBytecode())) + { + registerSuccess = true; + } + } + if (registerSuccess) + { + moduleDetails->registrationComplete(functionRef); + onModuleRegistered(moduleDetails); + return true; + } + + return false; +} + +void ScriptingContext::performRegistration(lua_State* state) +{ + // Loop over all of the modules once. We need do a tryRegister + // pass on each module in order to determine if it has any + // required dependencies + for (ModuleDetails* moduleDetails : m_modulesToRegister) + { + if (moduleDetails == nullptr) + { + continue; + } + std::string moduleName = moduleDetails->moduleName(); + + // Skip if already registered + if (checkRegisteredModules(state, moduleName.c_str()) == 1) + { + lua_pop(state, 1); + continue; + } + tryRegisterModule(state, moduleDetails); + } + + // If any modules had dependencies, resolve their registration order + // and try registering again + if (!m_pendingModules.empty()) + { + std::vector pendingModules; + for (auto module : m_pendingModules) + { + pendingModules.push_back(module); + } + std::vector sortedModules; + std::unordered_set visitedModules; + + ModuleDetails* module = pendingModules.back(); + pendingModules.pop_back(); + sortNextModule(module, + &pendingModules, + &sortedModules, + &visitedModules); + + // Register modules in sorted order + for (ModuleDetails* moduleDetails : sortedModules) + { + tryRegisterModule(state, moduleDetails); + } + } + + m_modulesToRegister.clear(); + m_pendingModules.clear(); +} + +void ScriptingContext::sortNextModule( + ModuleDetails* module, + std::vector* pendingModules, + std::vector* sortedModules, + std::unordered_set* visitedModules) +{ + // If already visited, skip + if (visitedModules->find(module) != visitedModules->end()) + { + return; + } + + auto dependencies = module->missingDependencies(); + for (const auto& dependencyName : dependencies) + { + auto lookupIt = m_moduleLookup.find(dependencyName); + if (lookupIt != m_moduleLookup.end()) + { + ModuleDetails* dependencyModule = lookupIt->second; + // Recursively process the dependency + sortNextModule(dependencyModule, + pendingModules, + sortedModules, + visitedModules); + } + } + + if (std::find(sortedModules->begin(), sortedModules->end(), module) == + sortedModules->end()) + { + sortedModules->push_back(module); + } + visitedModules->insert(module); + if (!pendingModules->empty()) + { + ModuleDetails* nextModule = pendingModules->back(); + pendingModules->pop_back(); + sortNextModule(nextModule, + pendingModules, + sortedModules, + visitedModules); + } +} + +void ScriptingContext::recordMissingDependency( + const std::string& requiringModule, + const std::string& missingModule) +{ + if (!requiringModule.empty()) + { + ModuleDetails* moduleDetails = m_moduleLookup[requiringModule]; + if (moduleDetails != nullptr) + { + moduleDetails->addMissingDependency(missingModule); + m_pendingModules.insert(moduleDetails); + } + } +} + +void ScriptingContext::onModuleRegistered(ModuleDetails* moduleDetails) +{ + for (ModuleDetails* module : m_modulesToRegister) + { + if (!module->missingDependencies().empty()) + { + moduleDetails->clearMissingDependency(moduleDetails->moduleName()); + } + } + auto it = m_pendingModules.find(moduleDetails); + if (it != m_pendingModules.end()) + { + m_pendingModules.erase(it); + } +} + +#ifdef WITH_RIVE_TOOLS +void ScriptingContext::registerShaderRstb(std::string name, + std::vector bytes) +{ + m_shaderRstbs[std::move(name)] = std::move(bytes); +} + +const std::vector* ScriptingContext::findShaderRstb( + const std::string& name) const +{ + auto it = m_shaderRstbs.find(name); + return it != m_shaderRstbs.end() ? &it->second : nullptr; +} + +void ScriptingContext::setGeneratorRef(uint32_t assetId, int ref) +{ + m_assetGeneratorRefs[assetId] = ref; +} + +int ScriptingContext::getGeneratorRef(uint32_t assetId) const +{ + auto it = m_assetGeneratorRefs.find(assetId); + return it != m_assetGeneratorRefs.end() ? it->second : 0; +} + +void ScriptingContext::clearGeneratorRefs() { m_assetGeneratorRefs.clear(); } + +bool ScriptingContext::hasGeneratorRef(uint32_t assetId) const +{ + return m_assetGeneratorRefs.find(assetId) != m_assetGeneratorRefs.end(); +} + +void ScriptingContext::trackOrphanScriptedProperty(ScriptedProperty* property) +{ + if (property != nullptr) + { + m_orphanScriptedProperties.push_back(property); + } +} + +void ScriptingContext::untrackOrphanScriptedProperty(ScriptedProperty* property) +{ + auto it = std::remove(m_orphanScriptedProperties.begin(), + m_orphanScriptedProperties.end(), + property); + m_orphanScriptedProperties.erase(it, m_orphanScriptedProperties.end()); +} + +void ScriptingContext::disposeOrphanScriptedProperties() +{ + auto orphans = m_orphanScriptedProperties; + for (ScriptedProperty* property : orphans) + { + if (property != nullptr) + { + property->dispose(); + } + } + m_orphanScriptedProperties.clear(); +} +#endif + +// ── WorkPool integration ─────────────────────────────────────────────────── +// getGlobalWorkPool() is defined in work_pool.cpp (shared singleton). + +WorkPool* ScriptingContext::workPool() +{ + if (m_ownerId == 0) + m_ownerId = WorkPool::nextOwnerId(); + return getGlobalWorkPool().get(); +} + +// Forward-declared in lua_image_decode.cpp (WASM only). +#ifdef __EMSCRIPTEN__ +extern void wasm_cancelPendingDecodes(lua_State* mainThread); +#endif + +void ScriptingContext::shutdownAsync() +{ + if (m_ownerId != 0) + { + auto& pool = getGlobalWorkPoolIfExists(); + if (pool) + pool->cancelAllForOwner(m_ownerId); + m_ownerId = 0; + } +} + +// Called from ~ScriptingVM before lua_close. On WASM, also cancel +// browser-native image decodes that bypass WorkPool. +void ScriptingContext::shutdownAsyncForState(lua_State* mainThread) +{ + shutdownAsync(); +#ifdef __EMSCRIPTEN__ + wasm_cancelPendingDecodes(mainThread); +#endif +} + +bool ScriptingVM::registerScript(lua_State* state, + const char* name, + Span bytecode) +{ + // Check if already registered - leave module on stack for caller to use + if (checkRegisteredModules(state, name) == 1) + { + return true; + } + + if (!loadModule(state, name, bytecode)) + { + return false; + } + + if (!executeModule(state, name, false)) + { + return false; + } + + return true; +} + +bool ScriptingVM::registerModule(lua_State* state, + const char* name, + Span bytecode) +{ + // Check if already registered + if (checkRegisteredModules(state, name) == 1) + { + lua_pop(state, 1); + return true; + } + + if (!loadModule(state, name, bytecode)) + { + return false; + } + + if (!executeModule(state, name, true)) + { + return false; + } + + // executeModule with isUtility=true registers into the require cache + // and leaves the module result on the stack. Pop it. + lua_pop(state, 1); + return true; +} + +void ScriptingVM::unregisterModule(lua_State* state, const char* name) +{ + luaL_findtable(state, LUA_REGISTRYINDEX, registeredCacheTableKey, 1); + lua_pushstring(state, name); + lua_pushnil(state); + lua_settable(state, -3); + lua_pop(state, 1); +} + +void ScriptingVM::unregisterModule(const char* name) +{ + return unregisterModule(m_state, name); +} + +bool ScriptingVM::registerModule(const char* name, Span bytecode) +{ + return registerModule(m_state, name, bytecode); +} + +bool ScriptingVM::registerScript(const char* name, Span bytecode) +{ + return registerScript(m_state, name, bytecode); +} + +int CPPRuntimeScriptingContext::pCall(lua_State* state, int nargs, int nresults) +{ + // calculate stack position for message handler + int hpos = lua_gettop(state) - nargs; + lua_pushcfunction(state, rive_luaErrorHandler, "riveErrorHandler"); + lua_insert(state, hpos); + + startTimedExecution(state); + int ret = lua_pcall(state, nargs, nresults, hpos); + endTimedExecution(state); + lua_remove(state, hpos); + return ret; +} + +} // namespace rive +#endif diff --git a/thirdparty/rive/source/math/contour_measure.cpp b/thirdparty/rive/source/math/contour_measure.cpp index 5fd28179f..410d2e7b2 100644 --- a/thirdparty/rive/source/math/contour_measure.cpp +++ b/thirdparty/rive/source/math/contour_measure.cpp @@ -7,6 +7,7 @@ #include "rive/math/contour_measure.hpp" #include "rive/math/math_types.hpp" #include "rive/math/wangs_formula.hpp" +#include "rive/profiler/profiler_macros.h" #include #include @@ -272,6 +273,8 @@ void ContourMeasure::getSegment(float startDist, RawPath* dst, bool startWithMove) const { + RIVE_PROF_SCOPE_L(3) + // sanitize the inputs startDist = std::max(0.f, startDist); endDist = std::min(m_length, endDist); @@ -279,16 +282,26 @@ void ContourMeasure::getSegment(float startDist, { return; } - - const auto startIndex = this->findSegment(startDist); + auto startIndex = this->findSegment(startDist); const auto endIndex = this->findSegment(endDist); - const auto start = m_segments[startIndex]; + auto start = m_segments[startIndex]; const auto end = m_segments[endIndex]; - const auto startT = compute_t(m_segments, startIndex, startDist); + auto startT = compute_t(m_segments, startIndex, startDist); const auto endT = compute_t(m_segments, endIndex, endDist); + // If we have a startT very close to 1.0 this will end up creating a cubic + // with near identical points. If we have an edncap then there is not enough + // precision left to determine the orientation of endcaps if they have one. + // Solution is to skip this bezier and move to the next + if ((1.0f - startT < math::EPSILON) && (startIndex < endIndex)) + { + startIndex++; + start = m_segments[startIndex]; + startT = 0.0f; + } + if (start.m_ptIndex == end.m_ptIndex) { start.extract(dst, startT, endT, m_points.data(), startWithMove); diff --git a/thirdparty/rive/source/math/hit_test.cpp b/thirdparty/rive/source/math/hit_test.cpp index a6ca01c66..70984559d 100644 --- a/thirdparty/rive/source/math/hit_test.cpp +++ b/thirdparty/rive/source/math/hit_test.cpp @@ -14,9 +14,9 @@ using namespace rive; -//static inline float graphics_roundf(float x) { return std::floor(x + 0.5f); } +static inline float graphics_roundf(float x) { return std::floor(x + 0.5f); } -//static inline int graphics_round(float x) { return (int)graphics_roundf(x); } +static inline int graphics_round(float x) { return (int)graphics_roundf(x); } struct Point { @@ -44,7 +44,7 @@ struct Point friend Point operator*(float s, Point v) { return {v.x * s, v.y * s}; } }; -//template T lerp(T a, T b, float t) { return a + (b - a) * t; } +template T lerp(T a, T b, float t) { return a + (b - a) * t; } template T ave(T a, T b) { return lerp(a, b, 0.5f); } diff --git a/thirdparty/rive/source/math/path_measure.cpp b/thirdparty/rive/source/math/path_measure.cpp index 4583d9a73..ea521ec18 100644 --- a/thirdparty/rive/source/math/path_measure.cpp +++ b/thirdparty/rive/source/math/path_measure.cpp @@ -1,4 +1,5 @@ #include "rive/math/path_measure.hpp" +#include using namespace rive; @@ -50,3 +51,63 @@ ContourMeasure::PosTanDistance PathMeasure::atPercentage( return atDistance(m_length * inRangePercentage); } + +void PathMeasure::getSegment(float startDistance, + float endDistance, + RawPath* dst, + bool startWithMove) const +{ + if (dst == nullptr || m_contours.empty()) + { + return; + } + + // Clamp distances to valid range + startDistance = std::max(0.0f, std::min(startDistance, m_length)); + endDistance = std::max(0.0f, std::min(endDistance, m_length)); + + if (startDistance >= endDistance) + { + return; + } + + float currentDistance = 0.0f; + bool isFirstSegment = true; + + for (auto contour : m_contours) + { + float contourLength = contour->length(); + float contourStart = currentDistance; + float contourEnd = currentDistance + contourLength; + + // Check if this contour intersects with the requested range + if (contourEnd > startDistance && contourStart < endDistance) + { + // Calculate the local distances within this contour + float localStart = std::max(0.0f, startDistance - contourStart); + float localEnd = + std::min(contourLength, endDistance - contourStart); + + // Extract from this contour + contour->getSegment(localStart, + localEnd, + dst, + !isFirstSegment || startWithMove); + isFirstSegment = false; + } + + currentDistance += contourLength; + + // If we've passed the end distance, we're done + if (currentDistance >= endDistance) + { + break; + } + } +} + +bool PathMeasure::isClosed() const +{ + // Return true only if there is exactly one contour and it is closed + return m_contours.size() == 1 && m_contours[0]->isClosed(); +} diff --git a/thirdparty/rive/source/math/random.cpp b/thirdparty/rive/source/math/random.cpp new file mode 100644 index 000000000..bc868a91a --- /dev/null +++ b/thirdparty/rive/source/math/random.cpp @@ -0,0 +1,15 @@ +/* + * Copyright 2022 Rive + */ + +#include "rive/math/random.hpp" + +namespace rive +{ + +#ifdef TESTING +int RandomProvider::m_randomCallsCount = 0; +std::vector RandomProvider::m_randomResults; +#endif + +} // namespace rive diff --git a/thirdparty/rive/source/math/raw_path.cpp b/thirdparty/rive/source/math/raw_path.cpp index 3c7c46d42..66b433dec 100644 --- a/thirdparty/rive/source/math/raw_path.cpp +++ b/thirdparty/rive/source/math/raw_path.cpp @@ -231,7 +231,7 @@ void RawPath::addPoly(Span span, bool isClosed) } } -void RawPath::addPoints(std::vector::const_iterator& ptIter, +void RawPath::addPoints(std::vector::const_reverse_iterator& ptIter, int count, const Mat2D* mat) { @@ -247,7 +247,7 @@ void RawPath::addPoints(std::vector::const_iterator& ptIter, { m_Points.emplace_back(point); } - ptIter--; + ptIter++; count--; } } @@ -280,76 +280,72 @@ RawPath::Iter RawPath::addPath(const RawPath& src, const Mat2D* mat) RawPath::Iter RawPath::addPathBackwards(const RawPath& src, const Mat2D* mat) { - size_t initialVerbCount = m_Verbs.size(); - size_t initialPointCount = m_Points.size(); - if (!src.m_Verbs.empty()) + if (src.empty()) { - bool isClosed = src.m_Verbs.back() == PathVerb::close; + return end(); + } - auto reversePointIterator = src.m_Points.end() - 1; - // Move to first point - m_Verbs.emplace_back(PathVerb::move); - addPoints(reversePointIterator, 1, mat); + // To reverse a path's points, we just add them in reverse order. + size_t initialPointCount = m_Points.size(); + m_Points.reserve(initialPointCount + src.m_Points.size()); + for (auto it = src.m_Points.rbegin(); it != src.m_Points.rend(); ++it) + { + m_Points.push_back(*it); + } - auto reverseVerbIterator = src.m_Verbs.end() - 1; - if (isClosed) + // To reverse a path's verbs, we have to swap sides of the moveTo and close + // (if any) verbs. + size_t initialVerbCount = m_Verbs.size(); + m_Verbs.reserve(initialVerbCount + src.m_Verbs.size()); + assert(!src.m_Verbs.empty()); + assert(src.m_Verbs[0] == PathVerb::move); + m_Verbs.push_back(PathVerb::move); // Swap moves from one side of the + // contour to the other. + bool closed = false; + for (auto it = src.m_Verbs.rbegin();; ++it) + { + PathVerb verb = *it; + if (verb == PathVerb::close) { - reverseVerbIterator--; + // RawPath guarantees that a single contour will never have more + // than one close (by injecting implicit moveTos when needed). + assert(!closed); + closed = true; // Move the close to the other side of the contour. + assert(it + 1 != src.m_Verbs.rend()); + continue; } - - bool hasPendingMoveCommand = false; - - for (; reverseVerbIterator != src.m_Verbs.begin(); - reverseVerbIterator--) + if (verb == PathVerb::move && closed) { - PathVerb verb = *reverseVerbIterator; - // For paths that have multiple segments (like in certain font - // glyphs), we need to flip the intermediate move verbs with the - // previous close path. So we hold on to it and add it after the - // next close call. - if (verb == PathVerb::move) - { - hasPendingMoveCommand = true; - } - else - { - if (hasPendingMoveCommand && verb != PathVerb::close) - { - m_Verbs.emplace_back(PathVerb::move); - hasPendingMoveCommand = false; - } - m_Verbs.emplace_back(verb); - if (hasPendingMoveCommand && verb == PathVerb::close) - { - m_Verbs.emplace_back(PathVerb::move); - hasPendingMoveCommand = false; - } - } - switch (verb) - { - case PathVerb::cubic: - addPoints(reversePointIterator, 3, mat); - break; - case PathVerb::quad: - addPoints(reversePointIterator, 2, mat); - break; - case PathVerb::line: - case PathVerb::move: - addPoints(reversePointIterator, 1, mat); - break; - default: - break; - } + // Time to apply the deferred close verb. + m_Verbs.push_back(PathVerb::close); + closed = false; } - // This should never be the case, but if for some reason a path ends - // with a move command, we add it to the list of verbs to ensure the - // path matches with the number of points - if (hasPendingMoveCommand) + if (it + 1 != src.m_Verbs.rend()) { - m_Verbs.emplace_back(PathVerb::move); + m_Verbs.push_back(verb); } - m_Verbs.emplace_back(PathVerb::close); + else + { + // Skip the intitial move; it got replaced by an initial move on + // the other side of the path. + assert(verb == PathVerb::move); + break; + } + } + assert(!closed); // Make sure we didn't miss a close verb. + assert(m_Verbs.size() == initialVerbCount + src.m_Verbs.size()); + assert(m_Points.size() == initialPointCount + src.m_Points.size()); + + if (mat != nullptr) + { + // Don't share newlyAddedPoints with the below return since + // pruneEmptySegments may invalidate it. + Vec2D* newlyAddedPoints = m_Points.data() + initialPointCount; + mat->mapPoints(newlyAddedPoints, newlyAddedPoints, src.m_Points.size()); + pruneEmptySegments( + {m_Verbs.data() + initialVerbCount, newlyAddedPoints}); } + return Iter{m_Verbs.data() + initialVerbCount, m_Points.data() + initialPointCount}; } @@ -539,7 +535,7 @@ void RawPath::printCode() const fprintf(stderr, "\n"); } #endif -#ifdef WITH_RIVE_TOOLS + static void expandAxisBounds(AABB& bounds, int axis, float value) { switch (axis) @@ -713,7 +709,6 @@ AABB RawPath::preciseBounds() const } return bounds; } -#endif float RawPath::computeCoarseArea() const { diff --git a/thirdparty/rive/source/math/rectangles_to_contour.cpp b/thirdparty/rive/source/math/rectangles_to_contour.cpp index 9642e6344..fdba0a8af 100644 --- a/thirdparty/rive/source/math/rectangles_to_contour.cpp +++ b/thirdparty/rive/source/math/rectangles_to_contour.cpp @@ -158,13 +158,16 @@ void RectanglesToContour::addRect(const AABB& rect) { if (!m_rects.empty()) { - auto& last = m_rects.back(); + AABB& last = m_rects.back(); if (last.minY == rect.minY && last.maxY == rect.maxY && last.maxX == rect.minX) { + float minX = last.minX; + float minY = last.minY; + float maxY = last.maxY; + m_rects.pop_back(); - m_rects.emplace_back( - AABB(last.minX, last.minY, rect.maxX, last.maxY)); + m_rects.emplace_back(AABB(minX, minY, rect.maxX, maxY)); return; } } diff --git a/thirdparty/rive/source/nested_artboard.cpp b/thirdparty/rive/source/nested_artboard.cpp index 54b874e39..42a0f94e3 100644 --- a/thirdparty/rive/source/nested_artboard.cpp +++ b/thirdparty/rive/source/nested_artboard.cpp @@ -1,47 +1,72 @@ #include "rive/nested_artboard.hpp" #include "rive/artboard.hpp" #include "rive/backboard.hpp" +#include "rive/file.hpp" #include "rive/importers/import_stack.hpp" #include "rive/importers/backboard_importer.hpp" +#include "rive/input/focusable.hpp" #include "rive/nested_animation.hpp" #include "rive/animation/nested_state_machine.hpp" +#include "rive/data_bind/data_bind_path.hpp" #include "rive/clip_result.hpp" +#include "rive/text/text_input.hpp" #include #include using namespace rive; NestedArtboard::NestedArtboard() {} -NestedArtboard::~NestedArtboard() {} +NestedArtboard::~NestedArtboard() +{ + // Release dependencies of nested animations BEFORE m_Instance is destroyed. + // The nested animations (like NestedStateMachine) hold + // StateMachineInstances that reference m_Instance. If we don't release them + // here, their destructors (called later when the parent artboard destroys + // them from m_Objects) will try to access the already-freed m_Instance. + for (auto& animation : m_NestedAnimations) + { + animation->releaseDependencies(); + } + // Also release the bound state machine's dependencies if it exists + if (m_boundNestedStateMachine) + { + m_boundNestedStateMachine->releaseDependencies(); + } + + // Clear ViewModelInstance references to break potential ref cycles. + // The ViewModelInstance and its property values are also in the artboard's + // m_Objects list and will be cleaned up there. + m_viewModelInstance = nullptr; + m_statefulViewModelInstance = nullptr; +} Core* NestedArtboard::clone() const { NestedArtboard* nestedArtboard = static_cast(NestedArtboardBase::clone()); - if (m_Artboard == nullptr) + nestedArtboard->file(file()); + if (m_referencedArtboard == nullptr) { return nestedArtboard; } - auto ni = m_Artboard->instance(); - nestedArtboard->nest(ni.release()); + auto ni = m_referencedArtboard->instance(); + nestedArtboard->referencedArtboard(ni.release()); return nestedArtboard; } void NestedArtboard::nest(Artboard* artboard) { - assert(artboard != nullptr); - - m_Artboard = artboard; - if (!m_Artboard->isInstance()) + m_referencedArtboard = artboard; + if (!m_referencedArtboard->isInstance()) { // We're just marking the source artboard so we can later instance from // it. No need to advance it or change any of its properties. // E.g. at import time, we return here. return; } - m_Artboard->frameOrigin(false); - m_Artboard->opacity(renderOpacity()); - m_Artboard->volume(artboard->volume()); + m_referencedArtboard->frameOrigin(false); + m_referencedArtboard->opacity(renderOpacity()); + m_referencedArtboard->volume(artboard->volume()); m_Instance = nullptr; if (artboard->isInstance()) { @@ -50,7 +75,139 @@ void NestedArtboard::nest(Artboard* artboard) } // This allows for swapping after initial load (after onAddedClean has // already been called). - m_Artboard->host(this); + m_referencedArtboard->host(this); +} + +bool NestedArtboard::tryScheduleBindStateful() +{ + + if (m_statefulViewModelInstance != nullptr && artboardInstance()) + { + m_hasPendingStatefulBinding = true; + return true; + } + return false; +} + +void NestedArtboard::bindStateful() +{ + m_hasPendingStatefulBinding = false; + bindArtboardInstance(m_statefulViewModelInstance, m_dataContext); +} + +void NestedArtboard::bindArtboardInstance(rcp instance, + rcp parent) +{ + artboardInstance()->bindViewModelInstance(instance, parent); + for (auto& animation : m_NestedAnimations) + { + if (animation->is()) + { + animation->as()->dataContext( + artboardInstance()->dataContext()); + } + } +} + +void NestedArtboard::clearNestedAnimations() +{ + for (auto& animation : m_NestedAnimations) + { + // Release the nested animation dependencies. The file will take care of + // destroying the nested animation itself. + animation->releaseDependencies(); + } + m_NestedAnimations.clear(); +} + +void NestedArtboard::updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) +{ + clearDataContext(); + clearNestedAnimations(); + m_boundNestedStateMachine = nullptr; + // If asset == nullptr and propertyValue == -1, it means that the user + // explicitly set the asset to null, so only in that case we clear the + // artboard + if (viewModelInstanceArtboard != nullptr && + viewModelInstanceArtboard->asset() == nullptr && + viewModelInstanceArtboard->propertyValue() == -1) + { + if (m_referencedArtboard) + { + m_referencedArtboard->host(nullptr); + m_referencedArtboard = nullptr; + } + m_Instance = nullptr; + m_statefulViewModelInstance = nullptr; + return; + } + + Artboard* artboard = + findArtboard(viewModelInstanceArtboard, parentArtboard(), m_file); + if (artboard != nullptr) + { + auto artboardInstance = artboard->instance(); + if (artboard->stateMachineCount() > 0) + { + + auto nestedStateMachine = new NestedStateMachine(); + nestedStateMachine->animationId(0); + nestedStateMachine->initializeAnimation(artboardInstance.get()); + addNestedAnimation(nestedStateMachine); + + m_boundNestedStateMachine.reset(static_cast( + nestedStateMachine)); // take ownership + } + referencedArtboard(artboardInstance.release()); + + if (artboard->isStateful()) + { + const bool cacheStale = + m_statefulViewModelInstance == nullptr || + m_statefulViewModelInstance->viewModelId() != + artboard->viewModelId(); + if (cacheStale) + { + auto vm = m_file != nullptr + ? m_file->viewModel(artboard->viewModelId()) + : nullptr; + m_statefulViewModelInstance = + vm != nullptr ? m_file->createDefaultViewModelInstance(vm) + : nullptr; + if (m_statefulViewModelInstance != nullptr) + { + m_file->completeViewModelProperties( + m_statefulViewModelInstance.get()); + } + } + } + else + { + m_statefulViewModelInstance = nullptr; + } + + if (viewModelInstanceArtboard->boundViewModelInstance()) + { + bindViewModelInstance( + viewModelInstanceArtboard->boundViewModelInstance(), + m_dataContext); + } + else if (tryScheduleBindStateful()) + { + bindStateful(); + } + else if (m_dataContext != nullptr && m_viewModelInstance == nullptr) + { + internalDataContext(m_dataContext); + } + else if (m_viewModelInstance != nullptr) + { + bindViewModelInstance(m_viewModelInstance, m_dataContext); + } + // TODO: @hernan review what dirt to add + addDirt(ComponentDirt::Filthy); + } } static Mat2D makeTranslate(const Artboard* artboard) @@ -61,34 +218,32 @@ static Mat2D makeTranslate(const Artboard* artboard) void NestedArtboard::draw(Renderer* renderer) { - if (m_Artboard == nullptr) - { - return; - } - ClipResult clipResult = applyClip(renderer); - if (clipResult == ClipResult::noClip) + if (m_needsSaveOperation) { - // We didn't clip, so make sure to save as we'll be doing some - // transformations. renderer->save(); } - if (clipResult != ClipResult::emptyClip) + renderer->transform(worldTransform()); + m_referencedArtboard->drawInternal(renderer); + if (m_needsSaveOperation) { - renderer->transform(worldTransform()); - m_Artboard->draw(renderer); + renderer->restore(); } - renderer->restore(); +} + +bool NestedArtboard::willDraw() +{ + return Super::willDraw() && m_referencedArtboard != nullptr; } Core* NestedArtboard::hitTest(HitInfo* hinfo, const Mat2D& xform) { - if (m_Artboard == nullptr) + if (m_referencedArtboard == nullptr) { return nullptr; } hinfo->mounts.push_back(this); - auto mx = xform * worldTransform() * makeTranslate(m_Artboard); - if (auto c = m_Artboard->hitTest(hinfo, mx)) + auto mx = xform * worldTransform() * makeTranslate(m_referencedArtboard); + if (auto c = m_referencedArtboard->hitTest(hinfo, mx)) { return c; } @@ -96,15 +251,38 @@ Core* NestedArtboard::hitTest(HitInfo* hinfo, const Mat2D& xform) return nullptr; } +bool NestedArtboard::hitTestHost(const Vec2D& position, + bool skipOnUnclipped, + ArtboardInstance* artboard) +{ + return parent()->hitTestPoint(worldTransform() * position, + skipOnUnclipped, + false); +} + +Vec2D NestedArtboard::hostTransformPoint(const Vec2D& vec, + ArtboardInstance* artboardInstance) +{ + auto localVec = Vec2D::transformMat2D(vec, worldTransform()); + auto ab = artboard(); + return ab ? ab->rootTransform(localVec) : localVec; +} + +Mat2D NestedArtboard::worldTransformForArtboard(ArtboardInstance*) +{ + return worldTransform(); +} + StatusCode NestedArtboard::import(ImportStack& importStack) { + importDataBindPath(importStack); auto backboardImporter = importStack.latest(Backboard::typeKey); if (backboardImporter == nullptr) { return StatusCode::MissingObject; } - backboardImporter->addNestedArtboard(this); + backboardImporter->addArtboardReferencer(this); return Super::import(importStack); } @@ -122,7 +300,8 @@ StatusCode NestedArtboard::onAddedClean(CoreContext* context) // does require that we always use an artboard instance (not just the source // artboard) when working with nested artboards, but in general this is good // practice for any loaded Rive file. - assert(m_Artboard == nullptr || m_Artboard == m_Instance.get()); + assert(m_referencedArtboard == nullptr || + m_referencedArtboard == m_Instance.get()); if (m_Instance) { @@ -130,31 +309,77 @@ StatusCode NestedArtboard::onAddedClean(CoreContext* context) { animation->initializeAnimation(m_Instance.get()); } - m_Artboard->host(this); + m_referencedArtboard->host(this); + } + + // ViewModelInstance children are only added to NestedArtboards + // that wrap a stateful component Artboard. + for (auto child : children()) + { + if (child->is()) + { + auto vmi = child->as(); + // Take ownership of the VMI's initial ref count. The VMI starts + // with ref count 1 from construction. The rcp constructor takes + // this ref without adding another. NestedArtboard now owns the VMI. + m_statefulViewModelInstance = rcp(vmi); + m_file->completeViewModelProperties( + m_statefulViewModelInstance.get()); + break; + } } + tryScheduleBindStateful(); + return Super::onAddedClean(context); } void NestedArtboard::update(ComponentDirt value) { Super::update(value); - if (m_Artboard == nullptr) + if (m_referencedArtboard == nullptr) { return; } + if (hasDirt(value, ComponentDirt::WorldTransform)) + { + // Mark semantic bounds dirty for nodes inside the nested artboard. + // Their root-space bounds depend on the host's world transform. + if (m_Instance != nullptr) + { + m_Instance->markSemanticBoundaryTransformDirty(); + } + } if (hasDirt(value, ComponentDirt::RenderOpacity)) { - m_Artboard->opacity(renderOpacity()); + m_referencedArtboard->opacity(renderOpacity()); } if (hasDirt(value, ComponentDirt::Components)) { // We intentionally discard whether or not this updated because by the // end of the pass all the dirt is removed and only another advance of // animations/statemachines can re-add it. - m_Artboard->updatePass(false); + m_referencedArtboard->updatePass(false); } } +bool NestedArtboard::collapse(bool value) +{ + if (!Super::collapse(value)) + { + return false; + } + + auto* nestedInstance = artboardInstance(); + if (nestedInstance == nullptr) + { + return true; + } + // Semantic-only collapse via the artboard boundary node. Only touches + // SemanticData nodes — non-semantic components stay untouched. + nestedInstance->collapseSemanticBoundary(value); + return true; +} + bool NestedArtboard::hasNestedStateMachines() const { for (auto animation : m_NestedAnimations) @@ -229,7 +454,7 @@ NestedInput* NestedArtboard::input(std::string name, bool NestedArtboard::worldToLocal(Vec2D world, Vec2D* local) { assert(local != nullptr); - if (m_Artboard == nullptr) + if (m_referencedArtboard == nullptr) { return false; } @@ -267,25 +492,30 @@ void NestedArtboard::controlSize(Vec2D size, void NestedArtboard::decodeDataBindPathIds(Span value) { - BinaryReader reader(value); - while (!reader.reachedEnd()) - { - auto val = reader.readVarUintAs(); - m_DataBindPathIdsBuffer.push_back(val); - } + decodeDataBindPath(value); } void NestedArtboard::copyDataBindPathIds(const NestedArtboardBase& object) { - m_DataBindPathIdsBuffer = - object.as()->m_DataBindPathIdsBuffer; + copyDataBindPath(object.as()->dataBindPath()); } -void NestedArtboard::internalDataContext(DataContext* value) +void NestedArtboard::internalDataContext(rcp value) { + m_dataContext = value; + m_viewModelInstance = nullptr; + if (artboardInstance() != nullptr) { - artboardInstance()->internalDataContext(value, false); + // If we have a stateful ViewModelInstance, bind it to the artboard + // instance. + if (tryScheduleBindStateful()) + { + return; + } + + // Non-stateful path: just propagate the data context. + artboardInstance()->internalDataContext(value); for (auto& animation : m_NestedAnimations) { if (animation->is()) @@ -296,55 +526,117 @@ void NestedArtboard::internalDataContext(DataContext* value) } } +void NestedArtboard::relinkDataContext(rcp viewModelInstance) +{ + m_viewModelInstance = viewModelInstance; + auto instance = artboardInstance(0); + if (instance && !instance->isStateful()) + { + auto dataContext = instance->dataContext(); + if (dataContext != nullptr) + { + if (dataContext->viewModelInstance() != viewModelInstance) + { + dataContext->viewModelInstance(viewModelInstance); + } + } + instance->relinkDataContext(); + } +} + void NestedArtboard::clearDataContext() { if (artboardInstance() != nullptr) { artboardInstance()->clearDataContext(); + for (auto& animation : m_NestedAnimations) + { + if (animation->is()) + { + animation->as()->clearDataContext(); + } + } } } -void NestedArtboard::populateDataBinds(std::vector* dataBinds) +void NestedArtboard::unbind() { if (artboardInstance() != nullptr) { - artboardInstance()->populateDataBinds(dataBinds); + artboardInstance()->unbind(); + } +} + +void NestedArtboard::updateDataBinds() +{ + if (artboardInstance() != nullptr && !isPaused()) + { + artboardInstance()->updateDataBinds(); } } void NestedArtboard::bindViewModelInstance( rcp viewModelInstance, - DataContext* parent) + rcp parent) { + m_dataContext = parent; + m_viewModelInstance = viewModelInstance; if (artboardInstance() != nullptr) { - artboardInstance()->bindViewModelInstance(viewModelInstance, - parent, - false); - for (auto& animation : m_NestedAnimations) + // Stateful nested artboards must keep their own instance as the local + // root context, while the incoming instance remains the parent context. + auto instanceToBind = m_statefulViewModelInstance != nullptr + ? m_statefulViewModelInstance + : viewModelInstance; + bindArtboardInstance(instanceToBind, parent); + } +} + +float NestedArtboard::calculateLocalElapsedSeconds(float elapsedSeconds) +{ + auto localElapsedSeconds = elapsedSeconds * (speed() >= 0 ? speed() : 1); + if (quantize() >= 0) + { + m_cumulatedSeconds += localElapsedSeconds; + auto quantizedSeconds = 1 / quantize(); + if (m_cumulatedSeconds > quantizedSeconds) { - if (animation->is()) - { - animation->as()->dataContext( - artboardInstance()->dataContext()); - } + localElapsedSeconds = + std::floor(m_cumulatedSeconds / quantizedSeconds) * + quantizedSeconds; + m_cumulatedSeconds -= localElapsedSeconds; + } + else + { + localElapsedSeconds = 0; } } + return localElapsedSeconds; } bool NestedArtboard::advanceComponent(float elapsedSeconds, AdvanceFlags flags) { - if (m_Artboard == nullptr || isCollapsed()) + if (m_referencedArtboard == nullptr || isCollapsed() || isPaused()) { return false; } + if (m_hasPendingStatefulBinding) + { + bindStateful(); + } bool keepGoing = false; bool advanceNested = (flags & AdvanceFlags::AdvanceNested) == AdvanceFlags::AdvanceNested; + auto localElapsedSeconds = calculateLocalElapsedSeconds(elapsedSeconds); + bool newFrame = (flags & AdvanceFlags::NewFrame) == AdvanceFlags::NewFrame; + // If the elapsed time is 0 because of quantization, we still want to + // continue advancing until the cumulated time is flushed + if (localElapsedSeconds == 0 && quantize() >= 0 && newFrame) + { + return true; + } if (advanceNested) { - bool newFrame = - (flags & AdvanceFlags::NewFrame) == AdvanceFlags::NewFrame; for (auto animation : m_NestedAnimations) { // If it is not a new frame, we only advance state machines. And we @@ -358,7 +650,7 @@ bool NestedArtboard::advanceComponent(float elapsedSeconds, AdvanceFlags flags) { if (animation->as()->tryChangeState()) { - if (animation->advance(elapsedSeconds, newFrame)) + if (animation->advance(localElapsedSeconds, newFrame)) { keepGoing = true; } @@ -368,7 +660,7 @@ bool NestedArtboard::advanceComponent(float elapsedSeconds, AdvanceFlags flags) else { - if (animation->advance(elapsedSeconds, newFrame)) + if (animation->advance(localElapsedSeconds, newFrame)) { keepGoing = true; } @@ -377,11 +669,12 @@ bool NestedArtboard::advanceComponent(float elapsedSeconds, AdvanceFlags flags) } auto advancingFlags = flags & ~AdvanceFlags::IsRoot; - if (m_Artboard->advanceInternal(elapsedSeconds, advancingFlags)) + if (m_referencedArtboard->advanceInternal(localElapsedSeconds, + advancingFlags)) { keepGoing = true; } - if (m_Artboard->hasDirt(ComponentDirt::Components)) + if (m_referencedArtboard->hasDirt(ComponentDirt::Components)) { // The animation(s) caused the artboard to need an update. addDirt(ComponentDirt::Components); @@ -389,3 +682,29 @@ bool NestedArtboard::advanceComponent(float elapsedSeconds, AdvanceFlags flags) return keepGoing; } + +void NestedArtboard::reset() +{ + if (m_referencedArtboard) + { + m_referencedArtboard->reset(); + } + if (m_statefulViewModelInstance != nullptr) + { + m_statefulViewModelInstance->advanced(); + } +} + +void NestedArtboard::file(File* value) { m_file = value; } + +File* NestedArtboard::file() const { return m_file; } + +int NestedArtboard::referencedArtboardId() { return artboardId(); } + +void NestedArtboard::referencedArtboard(Artboard* artboard) +{ + assert(artboard != nullptr); + ArtboardReferencer::referencedArtboard(artboard); + nest(artboard); + tryScheduleBindStateful(); +} \ No newline at end of file diff --git a/thirdparty/rive/source/nested_artboard_layout.cpp b/thirdparty/rive/source/nested_artboard_layout.cpp index e9ea83277..0fac14dde 100644 --- a/thirdparty/rive/source/nested_artboard_layout.cpp +++ b/thirdparty/rive/source/nested_artboard_layout.cpp @@ -1,7 +1,8 @@ #include "rive/nested_artboard_layout.hpp" #include "rive/artboard.hpp" -#include "rive/math/aabb.hpp" +#include "rive/animation/keyframe_interpolator.hpp" #include "rive/layout/layout_data.hpp" +#include "rive/math/aabb.hpp" using namespace rive; @@ -9,27 +10,16 @@ Core* NestedArtboardLayout::clone() const { NestedArtboardLayout* nestedArtboard = static_cast(NestedArtboardLayoutBase::clone()); - if (m_Artboard == nullptr) + nestedArtboard->file(file()); + if (m_referencedArtboard == nullptr) { return nestedArtboard; } - auto ni = m_Artboard->instance(); - nestedArtboard->nest(ni.release()); + auto ni = m_referencedArtboard->instance(); + nestedArtboard->referencedArtboard(ni.release()); return nestedArtboard; } -float NestedArtboardLayout::actualInstanceWidth() -{ - return instanceWidth() == -1.0f ? artboardInstance()->originalWidth() - : instanceWidth(); -} - -float NestedArtboardLayout::actualInstanceHeight() -{ - return instanceHeight() == -1.0f ? artboardInstance()->originalHeight() - : instanceHeight(); -} - AABB NestedArtboardLayout::layoutBounds() { #ifdef WITH_RIVE_LAYOUT @@ -58,6 +48,7 @@ void NestedArtboardLayout::markHostingLayoutDirty( if (artboard() != nullptr) { artboard()->markLayoutDirty(this->artboardInstance()); + artboard()->markLayoutStyleDirty(); } } @@ -130,34 +121,31 @@ void NestedArtboardLayout::updateLayoutBounds(bool animate) #endif } +#ifdef WITH_RIVE_LAYOUT +bool NestedArtboardLayout::cascadeLayoutStyle( + LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime, + LayoutDirection direction) +{ + if (artboardInstance() != nullptr) + { + artboardInstance()->cascadeLayoutStyle(inheritedInterpolation, + inheritedInterpolator, + inheritedInterpolationTime, + direction); + } + return false; +} +#endif + void NestedArtboardLayout::updateWidthOverride() { if (artboardInstance() == nullptr) { return; } - auto isRow = parent()->is() - ? parent()->as()->mainAxisIsRow() - : true; - if (instanceWidthScaleType() == 0) // LayoutScaleType::fixed - { - // If we're set to fixed, pass the unit value (points|percent) - artboardInstance()->widthIntrinsicallySizeOverride(false); - artboardInstance()->widthOverride(actualInstanceWidth(), - instanceWidthUnitsValue(), - isRow); - } - else if (instanceWidthScaleType() == 1) // LayoutScaleType::fill - { - // If we're set to fill, pass auto - artboardInstance()->widthIntrinsicallySizeOverride(false); - artboardInstance()->widthOverride(actualInstanceWidth(), 3, isRow); - } - else if (instanceWidthScaleType() == 2) - { - artboardInstance()->widthIntrinsicallySizeOverride(true); - } - markHostingLayoutDirty(artboardInstance()); + m_styleOverrider.updateWidthOverride(artboardInstance()); } void NestedArtboardLayout::updateHeightOverride() @@ -166,28 +154,14 @@ void NestedArtboardLayout::updateHeightOverride() { return; } - auto isRow = parent()->is() - ? parent()->as()->mainAxisIsRow() - : true; - if (instanceHeightScaleType() == 0) // LayoutScaleType::fixed - { - // If we're set to fixed, pass the unit value (points|percent) - artboardInstance()->heightIntrinsicallySizeOverride(false); - artboardInstance()->heightOverride(actualInstanceHeight(), - instanceHeightUnitsValue(), - isRow); - } - else if (instanceHeightScaleType() == 1) // LayoutScaleType::fill - { - // If we're set to fill, pass auto - artboardInstance()->heightIntrinsicallySizeOverride(false); - artboardInstance()->heightOverride(actualInstanceHeight(), 3, isRow); - } - else if (instanceWidthScaleType() == 2) - { - artboardInstance()->heightIntrinsicallySizeOverride(true); - } - markHostingLayoutDirty(artboardInstance()); + m_styleOverrider.updateHeightOverride(artboardInstance()); +} + +bool NestedArtboardLayout::isRow() +{ + return parent()->is() + ? parent()->as()->mainAxisIsRow() + : true; } void NestedArtboardLayout::instanceWidthChanged() { updateWidthOverride(); } @@ -216,9 +190,29 @@ void NestedArtboardLayout::instanceHeightScaleTypeChanged() bool NestedArtboardLayout::syncStyleChanges() { - if (m_Artboard == nullptr) + if (m_referencedArtboard == nullptr) { return false; } - return m_Artboard->syncStyleChanges(); + return m_referencedArtboard->syncStyleChanges(); +} + +void NestedArtboardLayout::updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) +{ +#ifdef WITH_RIVE_LAYOUT + if (parent()->is()) + { + parent()->as()->clearLayoutChildren(); + } +#endif + NestedArtboard::updateArtboard(viewModelInstanceArtboard); + updateWidthOverride(); + updateHeightOverride(); +#ifdef WITH_RIVE_LAYOUT + if (parent()->is()) + { + parent()->as()->syncLayoutChildren(); + } +#endif } \ No newline at end of file diff --git a/thirdparty/rive/source/nested_artboard_leaf.cpp b/thirdparty/rive/source/nested_artboard_leaf.cpp index 02c1b0e1f..ed71b33d0 100644 --- a/thirdparty/rive/source/nested_artboard_leaf.cpp +++ b/thirdparty/rive/source/nested_artboard_leaf.cpp @@ -9,12 +9,13 @@ Core* NestedArtboardLeaf::clone() const { NestedArtboardLeaf* nestedArtboard = static_cast(NestedArtboardLeafBase::clone()); - if (m_Artboard == nullptr) + nestedArtboard->file(file()); + if (m_referencedArtboard == nullptr) { return nestedArtboard; } - auto ni = m_Artboard->instance(); - nestedArtboard->nest(ni.release()); + auto ni = m_referencedArtboard->instance(); + nestedArtboard->referencedArtboard(ni.release()); return nestedArtboard; } diff --git a/thirdparty/rive/source/node.cpp b/thirdparty/rive/source/node.cpp index 8f5f635f6..4e4ebd112 100644 --- a/thirdparty/rive/source/node.cpp +++ b/thirdparty/rive/source/node.cpp @@ -1,12 +1,28 @@ #include "rive/node.hpp" #include "rive/world_transform_component.hpp" #include "rive/layout_component.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_host.hpp" using namespace rive; void Node::xChanged() { markTransformDirty(); } void Node::yChanged() { markTransformDirty(); } +float Node::computedRootX() +{ + auto wt = worldTransform(); + auto rootPos = artboard()->rootTransform(Vec2D(wt[4], wt[5])); + return rootPos.x; +}; + +float Node::computedRootY() +{ + auto wt = worldTransform(); + auto rootPos = artboard()->rootTransform(Vec2D(wt[4], wt[5])); + return rootPos.y; +}; + Mat2D Node::localTransform() { if (m_LocalTransformNeedsRecompute) diff --git a/thirdparty/rive/source/parent_traversal.cpp b/thirdparty/rive/source/parent_traversal.cpp new file mode 100644 index 000000000..031b9f367 --- /dev/null +++ b/thirdparty/rive/source/parent_traversal.cpp @@ -0,0 +1,61 @@ +#include "rive/parent_traversal.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_host.hpp" +#include "rive/component.hpp" +#include "rive/container_component.hpp" + +using namespace rive; + +ParentTraversal::ParentTraversal(Component* start) : + m_current(start != nullptr ? start->parent() : nullptr), + m_currentArtboard(start != nullptr ? start->artboard() : nullptr) +{} + +ContainerComponent* ParentTraversal::next() +{ + // Reset boundary crossing state + m_didCrossBoundary = false; + m_crossingHost = nullptr; + m_sourceArtboard = nullptr; + + if (m_current == nullptr) + { + return nullptr; + } + + ContainerComponent* result = m_current; + + // Advance to next parent + if (m_current->parent() != nullptr) + { + m_current = m_current->parent(); + } + else if (m_currentArtboard != nullptr && + m_currentArtboard->host() != nullptr) + { + // No direct parent - try crossing artboard boundary + auto* host = m_currentArtboard->host(); + auto* hostComponent = host->hostComponent(); + + if (hostComponent != nullptr && hostComponent->parent() != nullptr) + { + // Record boundary crossing info before updating state + m_didCrossBoundary = true; + m_crossingHost = host; + m_sourceArtboard = m_currentArtboard; + + m_current = hostComponent->parent(); + m_currentArtboard = host->parentArtboard(); + } + else + { + m_current = nullptr; + } + } + else + { + m_current = nullptr; + } + + return result; +} diff --git a/thirdparty/rive/source/profiler/profiler.cpp b/thirdparty/rive/source/profiler/profiler.cpp new file mode 100644 index 000000000..ba2c96ad3 --- /dev/null +++ b/thirdparty/rive/source/profiler/profiler.cpp @@ -0,0 +1,16 @@ +#ifdef RIVE_MICROPROFILE +#define MICROPROFILE_IMPL +#if defined(RIVE_WINDOWS) +#define MICROPROFILE_GPU_TIMERS_D3D11 1 +#define MICROPROFILE_GPU_TIMERS_D3D12 1 +#endif +#include "rive/profiler/microprofile_emscripten.h" +#ifdef __EMSCRIPTEN__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat" +#endif +#include "microprofile.h" +#ifdef __EMSCRIPTEN__ +#pragma clang diagnostic pop +#endif +#endif diff --git a/thirdparty/rive/source/profiler/rive_profile.cpp b/thirdparty/rive/source/profiler/rive_profile.cpp new file mode 100644 index 000000000..45700498a --- /dev/null +++ b/thirdparty/rive/source/profiler/rive_profile.cpp @@ -0,0 +1,374 @@ +#include "rive/profiler/rive_profile.hpp" +#include "rive/core/vector_binary_writer.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_host.hpp" +#include "rive/artboard_component_list.hpp" +#include "rive/nested_artboard.hpp" +#include + +#ifdef RIVE_MICROPROFILE +#include "rive/profiler/microprofile_emscripten.h" +#include "microprofile.h" + +namespace +{ +void writeInt64(rive::VectorBinaryWriter& writer, int64_t value) +{ + writer.write(reinterpret_cast(&value), sizeof(value)); +} +void writeUint64(rive::VectorBinaryWriter& writer, uint64_t value) +{ + writer.write(reinterpret_cast(&value), sizeof(value)); +} + +void writeProfileHeader(rive::VectorBinaryWriter& writer) +{ + MicroProfile* pState = MicroProfileGet(); + writer.write((uint32_t)0x52505246); // "RPRF" magic + writer.write((uint32_t)2); // version 2 + writeInt64(writer, MicroProfileTicksPerSecondCpu()); + writer.writeVarUint(pState->nTotalTimers); + for (uint32_t i = 0; i < pState->nTotalTimers; i++) + { + const auto& info = pState->TimerInfo[i]; + writer.write(std::string(info.pName)); + writer.write((uint32_t)info.nGroupIndex); + writer.write((uint32_t)info.nColor); + } + writer.writeVarUint(pState->nGroupCount); + for (uint32_t i = 0; i < pState->nGroupCount; i++) + { + writer.write(std::string(pState->GroupInfo[i].pName)); + } +} + +void writeFrameEvents(rive::VectorBinaryWriter& writer, + MicroProfile* pState, + uint32_t frameIndex, + uint32_t nextFrameIndex) +{ + const MicroProfileFrameState& frame = pState->Frames[frameIndex]; + const MicroProfileFrameState& nextFrame = pState->Frames[nextFrameIndex]; + + std::vector payload; + rive::VectorBinaryWriter pw(&payload); + writeInt64(pw, frame.nFrameStartCpu); + writeInt64(pw, nextFrame.nFrameStartCpu); + uint32_t totalEvents = 0; + for (uint32_t threadIdx = 0; threadIdx < MICROPROFILE_MAX_THREADS; + threadIdx++) + { + MicroProfileThreadLog* pLog = pState->Pool[threadIdx]; + if (!pLog) + continue; + uint32_t logStart = frame.nLogStart[threadIdx]; + uint32_t logEnd = nextFrame.nLogStart[threadIdx]; + if (logEnd >= logStart) + totalEvents += (logEnd - logStart); + else + totalEvents += (MICROPROFILE_BUFFER_SIZE - logStart) + logEnd; + } + pw.writeVarUint(totalEvents); + for (uint32_t threadIdx = 0; threadIdx < MICROPROFILE_MAX_THREADS; + threadIdx++) + { + MicroProfileThreadLog* pLog = pState->Pool[threadIdx]; + if (!pLog) + continue; + uint32_t logStart = frame.nLogStart[threadIdx]; + uint32_t logEnd = nextFrame.nLogStart[threadIdx]; + for (uint32_t k = logStart; k != logEnd; + k = (k + 1) % MICROPROFILE_BUFFER_SIZE) + { + MicroProfileLogEntry entry = pLog->Log[k]; + uint64_t nType = MicroProfileLogType(entry); + uint64_t nTimerIndex = MicroProfileLogTimerIndex(entry); + int64_t nTick = + MicroProfileLogTickDifference(frame.nFrameStartCpu, entry); + uint8_t eventType = (nType == MP_LOG_ENTER) ? 0 + : (nType == MP_LOG_LEAVE) ? 1 + : 2; + pw.write(eventType); + pw.writeVarUint((uint32_t)nTimerIndex); + writeInt64(pw, nTick); + } + } + + writer.write((uint8_t)0x01); + writer.writeVarUint(static_cast(payload.size())); + writer.write(payload.data(), payload.size()); +} +} // namespace +#endif + +namespace rive +{ + +RiveProfile& RiveProfile::instance() +{ + static RiveProfile s_instance; + return s_instance; +} + +void RiveProfile::init() +{ +#ifdef RIVE_MICROPROFILE + MicroProfileSetEnableAllGroups(true); + MicroProfileSetForceEnable(true); + MicroProfileOnThreadCreate("MainThread"); + MicroProfileInit(); +#endif +} + +void RiveProfile::frame() +{ +#ifdef RIVE_MICROPROFILE + // Frame is typically a no-op at start of loop; MicroProfile tracks + // internally +#endif +} + +void RiveProfile::endFrame() +{ +#ifdef RIVE_MICROPROFILE + if (m_profilingActive) + { + MicroProfileFlip(); + } +#endif +} + +void RiveProfile::start() +{ +#ifdef RIVE_MICROPROFILE + m_profilingActive = true; + m_headerWritten = false; + m_lastFlushedFrameIndex = 0; + m_stringTable.clear(); + m_stringList.clear(); + MicroProfileSetEnableAllGroups(true); + MicroProfileSetForceEnable(true); + MicroProfile* pState = MicroProfileGet(); + if (pState != nullptr) + { + m_lastFlushedFrameIndex = pState->nFramePutIndex; + } +#endif +} + +void RiveProfile::stop() +{ +#ifdef RIVE_MICROPROFILE + m_profilingActive = false; + MicroProfileSetForceEnable(false); +#endif +} + +bool RiveProfile::isActive() const +{ +#ifdef RIVE_MICROPROFILE + return m_profilingActive; +#else + return false; +#endif +} + +void RiveProfile::flushFrameDataTo(std::vector& buffer) +{ +#ifdef RIVE_MICROPROFILE + MicroProfile* pState = MicroProfileGet(); + if (pState == nullptr) + return; + VectorBinaryWriter writer(&buffer); + if (!m_headerWritten) + { + writeProfileHeader(writer); + m_headerWritten = true; + } + uint64_t currentFrameIndex = pState->nFramePutIndex; + const uint32_t GPU_DELAY = MICROPROFILE_GPU_FRAME_DELAY + 1; + if (currentFrameIndex <= m_lastFlushedFrameIndex + GPU_DELAY) + return; + uint64_t endFrameIndex = currentFrameIndex - GPU_DELAY; + uint64_t maxHistory = MICROPROFILE_MAX_FRAME_HISTORY - GPU_DELAY - 2; + if (endFrameIndex - m_lastFlushedFrameIndex > maxHistory) + { + m_lastFlushedFrameIndex = endFrameIndex - maxHistory; + } + for (uint64_t frameIdx = m_lastFlushedFrameIndex; frameIdx < endFrameIndex; + frameIdx++) + { + uint32_t ringIdx = + static_cast(frameIdx % MICROPROFILE_MAX_FRAME_HISTORY); + uint32_t nextRingIdx = static_cast( + (frameIdx + 1) % MICROPROFILE_MAX_FRAME_HISTORY); + writeFrameEvents(writer, pState, ringIdx, nextRingIdx); + } + m_lastFlushedFrameIndex = endFrameIndex; +#endif +} + +#ifdef RIVE_MICROPROFILE +namespace +{ +std::vector buildArtboardPath(Artboard* artboard, + RiveProfile* profile) +{ + std::vector pathSegments; + if (artboard == nullptr || profile == nullptr) + { + return pathSegments; + } + Artboard* current = artboard; + while (ArtboardHost* host = current->host()) + { + ArtboardPathSegment segment; + if (host->type() == NestedArtboardBase::typeKey) + { + auto na = static_cast(host); + segment.type = 0; + segment.nameId = profile->resolveStringId(na->name()); + segment.index = -1; + } + else if (host->type() == ArtboardComponentListBase::typeKey) + { + auto acl = static_cast(host); + segment.type = 1; + segment.nameId = profile->resolveStringId(acl->name()); + segment.index = current->isInstance() + ? acl->indexOfArtboardInstance( + static_cast(current)) + : -1; + } + else + { + break; + } + pathSegments.push_back(segment); + ArtboardPathSegment abSegment; + abSegment.type = 0; + abSegment.nameId = profile->resolveStringId(current->name()); + abSegment.index = -1; + pathSegments.push_back(abSegment); + current = host->parentArtboard(); + if (current == nullptr) + { + break; + } + } + std::reverse(pathSegments.begin(), pathSegments.end()); + return pathSegments; +} +} // namespace +#endif + +void RiveProfile::recordTransition(std::string artboardName, + std::string smName, + std::string layerName, + std::string fromStateName, + std::string toStateName, + Artboard* artboardForPath) +{ +#ifdef RIVE_MICROPROFILE + if ((m_logFlags & ProfileLogTransitionRecords) == 0) + return; + if (!isActive() || !m_flushCallback) + return; + TransitionRecord rec; + rec.artboardId = resolveStringId(artboardName); + rec.smId = resolveStringId(smName); + rec.layerId = resolveStringId(layerName); + rec.fromStateId = resolveStringId(fromStateName); + rec.toStateId = resolveStringId(toStateName); + rec.tick = MP_TICK(); + if (artboardForPath != nullptr) + rec.path = buildArtboardPath(artboardForPath, this); + m_transitionRecords.push_back(std::move(rec)); +#endif +} + +uint32_t RiveProfile::resolveStringId(const std::string& str) +{ +#ifdef RIVE_MICROPROFILE + auto it = m_stringTable.find(str); + if (it != m_stringTable.end()) + { + return it->second; + } + const uint32_t id = static_cast(m_stringList.size()); + m_stringTable[str] = id; + m_stringList.push_back(str); + return id; +#else + (void)str; + return 0; +#endif +} + +const std::vector& RiveProfile::getStringTable() const +{ + return m_stringList; +} + +void RiveProfile::setFlushCallback(FlushCallback callback) +{ + m_flushCallback = std::move(callback); +} + +void RiveProfile::flushTransitionRecords() +{ + if (m_flushCallback && !m_transitionRecords.empty()) + { + m_flushCallback(m_transitionRecords); + } + m_transitionRecords.clear(); +} + +void RiveProfile::recordListenerPerformChange(std::string artboardName, + std::string smName, + std::string listenerName, + uint32_t listenerType, + uint32_t hitEvent, + uint32_t pointerId) +{ +#ifdef RIVE_MICROPROFILE + if ((m_logFlags & ProfileLogListenerPerformChanges) == 0) + return; + if (!isActive() || !m_listenerPerformChangeFlushCallback) + return; + ListenerPerformChangeRecord rec; + rec.artboardId = resolveStringId(artboardName); + rec.smId = resolveStringId(smName); + rec.listenerNameId = resolveStringId(listenerName); + rec.listenerType = listenerType; + rec.hitEvent = hitEvent; + rec.pointerId = pointerId; + rec.tick = MP_TICK(); + m_listenerPerformChangeRecords.push_back(std::move(rec)); +#else + (void)artboardName; + (void)smName; + (void)listenerName; + (void)listenerType; + (void)hitEvent; + (void)pointerId; +#endif +} + +void RiveProfile::setListenerPerformChangeFlushCallback( + ListenerPerformChangeFlushCallback callback) +{ + m_listenerPerformChangeFlushCallback = std::move(callback); +} + +void RiveProfile::flushListenerPerformChangeRecords() +{ + if (m_listenerPerformChangeFlushCallback && + !m_listenerPerformChangeRecords.empty()) + { + m_listenerPerformChangeFlushCallback(m_listenerPerformChangeRecords); + } + m_listenerPerformChangeRecords.clear(); +} + +} // namespace rive diff --git a/thirdparty/rive/source/renderer.cpp b/thirdparty/rive/source/renderer.cpp index 3cab3c24a..6aa50a56c 100644 --- a/thirdparty/rive/source/renderer.cpp +++ b/thirdparty/rive/source/renderer.cpp @@ -55,7 +55,8 @@ Mat2D rive::computeAlignment(Fit fit, } case Fit::layout: { - return Mat2D::fromScale(scaleFactor, scaleFactor); + scaleX = scaleY = scaleFactor; + break; } case Fit::none: { @@ -109,7 +110,8 @@ RenderBuffer::~RenderBuffer() {} void* RenderBuffer::map() { assert(m_mapCount == 0 || - !(m_flags & RenderBufferFlags::mappedOnceAtInitialization)); + !enums::is_flag_set(m_flags, + RenderBufferFlags::mappedOnceAtInitialization)); assert(m_mapCount == m_unmapCount); RIVE_DEBUG_CODE(++m_mapCount;) m_dirty = true; @@ -137,7 +139,12 @@ RenderImage::~RenderImage() {} RenderPath::RenderPath() {} RenderPath::~RenderPath() {} -bool rive::isWhiteSpace(Unichar c) { return c <= ' ' || c == 0x2028; } +bool rive::isWhiteSpace(Unichar c) +{ + // 0x2028 is a Line separator. + // 0x200B is a Zero width space. + return c <= ' ' || c == 0x2028 || c == 0x200B; +} SimpleArray Font::shapeText(Span text, Span runs, @@ -159,6 +166,7 @@ SimpleArray Font::shapeText(Span text, GlyphRun* lastRun = nullptr; size_t reserveSize = text.size() / 4; SimpleArrayBuilder breakBuilder(reserveSize); + SimpleArrayBuilder joinerBuilder(reserveSize); for (const Paragraph& para : paragraphs) { for (GlyphRun& gr : para.runs) @@ -166,8 +174,10 @@ SimpleArray Font::shapeText(Span text, if (lastRun != nullptr) { lastRun->breaks = std::move(breakBuilder); + lastRun->joiners = std::move(joinerBuilder); // Reset the builder. breakBuilder = SimpleArrayBuilder(reserveSize); + joinerBuilder = SimpleArrayBuilder(reserveSize); } uint32_t glyphIndex = 0; for (uint32_t offset : gr.textIndices) @@ -178,6 +188,10 @@ SimpleArray Font::shapeText(Span text, breakBuilder.add(glyphIndex); breakBuilder.add(glyphIndex); } + if (unicode == 0x2060) + { + joinerBuilder.add(offset); + } if (wantWhiteSpace == isWhiteSpace(unicode)) { breakBuilder.add(glyphIndex); @@ -202,6 +216,7 @@ SimpleArray Font::shapeText(Span text, breakBuilder.add((uint32_t)lastRun->glyphs.size()); } lastRun->breaks = std::move(breakBuilder); + lastRun->joiners = std::move(joinerBuilder); } #ifdef DEBUG diff --git a/thirdparty/rive/source/resetting_component.cpp b/thirdparty/rive/source/resetting_component.cpp new file mode 100644 index 000000000..72f8945eb --- /dev/null +++ b/thirdparty/rive/source/resetting_component.cpp @@ -0,0 +1,26 @@ +#include "rive/component.hpp" +#include "rive/resetting_component.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_component_list.hpp" +#include "rive/custom_property_trigger.hpp" +#include "rive/nested_artboard.hpp" +#include "rive/nested_artboard_layout.hpp" +#include "rive/nested_artboard_leaf.hpp" + +using namespace rive; + +ResettingComponent* ResettingComponent::from(Component* component) +{ + switch (component->coreType()) + { + case NestedArtboardLeaf::typeKey: + case NestedArtboardLayout::typeKey: + case NestedArtboard::typeKey: + return component->as(); + case ArtboardComponentListBase::typeKey: + return component->as(); + case CustomPropertyTriggerBase::typeKey: + return component->as(); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive/source/scene.cpp b/thirdparty/rive/source/scene.cpp index 7efc88744..4f43749a9 100644 --- a/thirdparty/rive/source/scene.cpp +++ b/thirdparty/rive/source/scene.cpp @@ -15,10 +15,13 @@ float Scene::height() const { return m_artboardInstance->height(); } void Scene::draw(Renderer* renderer) { m_artboardInstance->draw(renderer); } -HitResult Scene::pointerDown(Vec2D) { return HitResult::none; } -HitResult Scene::pointerMove(Vec2D) { return HitResult::none; } -HitResult Scene::pointerUp(Vec2D) { return HitResult::none; } -HitResult Scene::pointerExit(Vec2D) { return HitResult::none; } +HitResult Scene::pointerDown(Vec2D, int) { return HitResult::none; } +HitResult Scene::pointerMove(Vec2D, float timeStamp, int) +{ + return HitResult::none; +} +HitResult Scene::pointerUp(Vec2D, int) { return HitResult::none; } +HitResult Scene::pointerExit(Vec2D, int) { return HitResult::none; } size_t Scene::inputCount() const { return 0; } SMIInput* Scene::input(size_t index) const { return nullptr; } diff --git a/thirdparty/rive/source/script_input_artboard.cpp b/thirdparty/rive/source/script_input_artboard.cpp new file mode 100644 index 000000000..efdf12055 --- /dev/null +++ b/thirdparty/rive/source/script_input_artboard.cpp @@ -0,0 +1,135 @@ +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_artboard.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputArtboard::~ScriptInputArtboard() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } + m_referencedArtboard = nullptr; +} + +StatusCode ScriptInputArtboard::import(ImportStack& importStack) +{ + auto backboardImporter = + importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + backboardImporter->addArtboardReferencer(this); + + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +void ScriptInputArtboard::initScriptedValue() +{ + ScriptInput::initScriptedValue(); + syncReferencedArtboard(); +} + +bool ScriptInputArtboard::validateForColdScriptInit() { return true; } + +bool ScriptInputArtboard::validateHydrationPrerequisites() +{ + return m_referencedArtboard != nullptr; +} + +bool ScriptInputArtboard::hydrateScriptInput() +{ + initScriptedValue(); + return m_referencedArtboard != nullptr; +} + +void ScriptInputArtboard::syncReferencedArtboard() +{ + + if (m_referencedArtboard == nullptr) + { + return; + } + auto obj = scriptedObject(); + if (obj) + { + obj->setArtboardInput(name(), m_referencedArtboard); + } +} + +StatusCode ScriptInputArtboard::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} + +Core* ScriptInputArtboard::clone() const +{ + ScriptInputArtboard* twin = + ScriptInputArtboardBase::clone()->as(); + if (m_referencedArtboard != nullptr) + { + twin->referencedArtboard(m_referencedArtboard); + twin->file(m_file); + } + return twin; +} + +void ScriptInputArtboard::artboardIdChanged() +{ + if (m_file) + { + m_referencedArtboard = m_file->artboard(artboardId()); + syncReferencedArtboard(); + } +} + +void ScriptInputArtboard::updateArtboard( + ViewModelInstanceArtboard* viewModelInstanceArtboard) +{ + auto referencedArtboard = + findArtboard(viewModelInstanceArtboard, artboard(), m_file); + if (referencedArtboard) + { + m_referencedArtboard = referencedArtboard; + syncReferencedArtboard(); + } +} + +int ScriptInputArtboard::referencedArtboardId() { return artboardId(); } \ No newline at end of file diff --git a/thirdparty/rive/source/script_input_boolean.cpp b/thirdparty/rive/source/script_input_boolean.cpp new file mode 100644 index 000000000..1f2712003 --- /dev/null +++ b/thirdparty/rive/source/script_input_boolean.cpp @@ -0,0 +1,67 @@ +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_boolean.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputBoolean::~ScriptInputBoolean() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } +} + +StatusCode ScriptInputBoolean::import(ImportStack& importStack) +{ + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +StatusCode ScriptInputBoolean::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} + +void ScriptInputBoolean::propertyValueChanged() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->setBooleanInput(name(), propertyValue()); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/script_input_color.cpp b/thirdparty/rive/source/script_input_color.cpp new file mode 100644 index 000000000..01f0d451b --- /dev/null +++ b/thirdparty/rive/source/script_input_color.cpp @@ -0,0 +1,67 @@ +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_color.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputColor::~ScriptInputColor() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } +} + +StatusCode ScriptInputColor::import(ImportStack& importStack) +{ + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +StatusCode ScriptInputColor::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} + +void ScriptInputColor::propertyValueChanged() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->setIntegerInput(name(), propertyValue()); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/script_input_number.cpp b/thirdparty/rive/source/script_input_number.cpp new file mode 100644 index 000000000..2ea5c9cde --- /dev/null +++ b/thirdparty/rive/source/script_input_number.cpp @@ -0,0 +1,67 @@ +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_number.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputNumber::~ScriptInputNumber() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } +} + +StatusCode ScriptInputNumber::import(ImportStack& importStack) +{ + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +StatusCode ScriptInputNumber::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} + +void ScriptInputNumber::propertyValueChanged() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->setNumberInput(name(), propertyValue()); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/script_input_string.cpp b/thirdparty/rive/source/script_input_string.cpp new file mode 100644 index 000000000..07e1442ed --- /dev/null +++ b/thirdparty/rive/source/script_input_string.cpp @@ -0,0 +1,67 @@ +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_string.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputString::~ScriptInputString() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } +} + +StatusCode ScriptInputString::import(ImportStack& importStack) +{ + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +StatusCode ScriptInputString::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} + +void ScriptInputString::propertyValueChanged() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->setStringInput(name(), propertyValue()); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/script_input_trigger.cpp b/thirdparty/rive/source/script_input_trigger.cpp new file mode 100644 index 000000000..7c3dc5058 --- /dev/null +++ b/thirdparty/rive/source/script_input_trigger.cpp @@ -0,0 +1,66 @@ +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_trigger.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputTrigger::~ScriptInputTrigger() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } +} + +StatusCode ScriptInputTrigger::import(ImportStack& importStack) +{ + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +StatusCode ScriptInputTrigger::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} + +void ScriptInputTrigger::propertyValueChanged() +{ + if (propertyValue() != 0) + { + scriptedObject()->trigger(name()); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/script_input_viewmodel_property.cpp b/thirdparty/rive/source/script_input_viewmodel_property.cpp new file mode 100644 index 000000000..6fb2bb232 --- /dev/null +++ b/thirdparty/rive/source/script_input_viewmodel_property.cpp @@ -0,0 +1,156 @@ +#include "rive/importers/scripted_object_importer.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/script_input_viewmodel_property.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_property_enum_custom.hpp" +#include "rive/viewmodel/viewmodel_property_viewmodel.hpp" +#include "rive/custom_property_container.hpp" + +using namespace rive; + +ScriptInputViewModelProperty::~ScriptInputViewModelProperty() +{ + auto obj = scriptedObject(); + if (obj != nullptr) + { + obj->removeProperty(this); + } +} + +void ScriptInputViewModelProperty::decodeDataBindPathIds( + Span value) +{ + decodeDataBindPath(value); +} + +void ScriptInputViewModelProperty::copyDataBindPathIds( + const ScriptInputViewModelPropertyBase& object) +{ + copyDataBindPath(object.as()->dataBindPath()); +} + +void ScriptInputViewModelProperty::initScriptedValue() +{ + ScriptInput::initScriptedValue(); + if (m_viewModelInstanceValue == nullptr) + { + return; + } + auto obj = scriptedObject(); + if (obj) + { + obj->setViewModelInput(name(), m_viewModelInstanceValue); + } +} + +bool ScriptInputViewModelProperty::validateForScriptInit() +{ + // Binding validation happens in hydrateScriptInput(); cold init does not + // require a resolved view-model property. + m_viewModelInstanceValue = nullptr; + return true; +} + +bool ScriptInputViewModelProperty::validateForColdScriptInit() +{ + m_viewModelInstanceValue = nullptr; + return true; +} + +bool ScriptInputViewModelProperty::validateHydrationPrerequisites() +{ + auto scriptedObj = scriptedObject(); + if (scriptedObj == nullptr) + { + return false; + } + auto dataContext = scriptedObj->dataContext(); + if (dataContext == nullptr) + { + return false; + } + if (m_dataBindPath == nullptr) + { + return false; + } + auto instanceValue = dataContext->getViewModelProperty(m_dataBindPath); + if (instanceValue == nullptr) + { + return false; + } + return instanceValue->viewModelProperty() != nullptr; +} + +bool ScriptInputViewModelProperty::hydrateScriptInput() +{ + m_viewModelInstanceValue = nullptr; + auto scriptedObj = scriptedObject(); + if (scriptedObj == nullptr) + { + return false; + } + auto dataContext = scriptedObj->dataContext(); + if (dataContext == nullptr) + { + return false; + } + if (m_dataBindPath == nullptr) + { + return false; + } + auto instanceValue = dataContext->getViewModelProperty(m_dataBindPath); + if (instanceValue == nullptr) + { + return false; + } + auto viewModelProperty = instanceValue->viewModelProperty(); + if (viewModelProperty == nullptr) + { + return false; + } + m_viewModelInstanceValue = instanceValue; + initScriptedValue(); + return true; +} + +StatusCode ScriptInputViewModelProperty::import(ImportStack& importStack) +{ + importDataBindPath(importStack); + auto importer = + importStack.latest(ScriptedDrawable::typeKey); + if (importer == nullptr) + { + return StatusCode::MissingObject; + } + importer->addInput(this); + + auto obj = scriptedObject(); + if (obj && obj->component() != nullptr) + { + // If the ScriptedObject is a Component, we need the ArtboardImporter + // to add it as a Component, otherwise, return Ok + return Super::import(importStack); + } + return StatusCode::Ok; +} + +StatusCode ScriptInputViewModelProperty::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto p = parent(); + if (p != nullptr) + { + auto scriptedObj = ScriptedObject::from(p); + if (scriptedObj != nullptr) + { + scriptedObj->addProperty(this); + } + } + + return StatusCode::Ok; +} \ No newline at end of file diff --git a/thirdparty/rive/source/scripted/scripted_data_converter.cpp b/thirdparty/rive/source/scripted/scripted_data_converter.cpp new file mode 100644 index 000000000..3cc0e90ed --- /dev/null +++ b/thirdparty/rive/source/scripted/scripted_data_converter.cpp @@ -0,0 +1,274 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/assets/script_asset.hpp" +#include "rive/component_dirt.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_values/data_type.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" +#include "rive/scripted/scripted_data_converter.hpp" + +using namespace rive; + +ScriptedDataConverter::~ScriptedDataConverter() +{ + disposeScriptInputs(); + if (m_dataValue) + { + delete m_dataValue; + } +} + +void ScriptedDataConverter::disposeScriptInputs() +{ + auto props = m_customProperties; + ScriptedObject::disposeScriptInputs(); + for (auto prop : props) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + // ScriptedDataConverters need to delete their own inputs + // because they are not components + delete scriptInput; + } + } +} + +#ifdef WITH_RIVE_SCRIPTING + +void ScriptedDataConverter::didHydrateScriptInputs() +{ + addScriptedDirt(ComponentDirt::Bindings); +} + +bool ScriptedDataConverter::pushDataValue(DataValue* value) +{ + lua_State* L = state(); + // Stack: [self, field, self] + if (value->is()) + { + lua_newrive( + L, + L, + value->as()->value()); + } + else if (value->is()) + { + lua_newrive( + L, + L, + value->as()->value()); + } + else if (value->is()) + { + lua_newrive( + L, + L, + value->as()->value()); + } + else if (value->is()) + { + lua_newrive( + L, + L, + value->as()->value()); + } + else + { + return false; + } + return true; +} + +DataValue* ScriptedDataConverter::applyConversion(DataValue* value, + const std::string& method) +{ + lua_State* L = state(); + if (L == nullptr) + { + return value; + } + // Stack: [] + rive_lua_pushRef(L, m_self); + // Stack: [self] + lua_getfield(L, -1, method.c_str()); + + // Stack: [self, field] + lua_pushvalue(L, -2); + // Stack: [self, field, self] + if (pushDataValue(value)) + { + // Stack: [self, field, self, ScriptedData] + if (static_cast( + rive_lua_pcall_with_context(L, this, 2, 1)) == LUA_OK) + { + auto result = (ScriptedDataValue*)lua_touserdata(L, -1); + if (result->isNumber()) + { + storeData(result->dataValue()); + } + else if (result->isString()) + { + storeData(result->dataValue()); + } + else if (result->isBoolean()) + { + storeData(result->dataValue()); + } + else if (result->isColor()) + { + storeData(result->dataValue()); + } + } + // Stack: [self, status] or [self, result] + rive_lua_pop(L, 2); + } + else + { + // Stack: [self, field, self] + rive_lua_pop(L, 3); + } + if (!m_dataValue) + { + m_dataValue = new DataValue(); + } + return m_dataValue; +} + +DataValue* ScriptedDataConverter::convert(DataValue* value, DataBind* dataBind) +{ + if (dataConverts()) + { + return applyConversion(value, "convert"); + } + return value; +} + +DataValue* ScriptedDataConverter::reverseConvert(DataValue* value, + DataBind* dataBind) +{ + if (dataReverseConverts()) + { + return applyConversion(value, "reverseConvert"); + } + return value; +} +#endif + +void ScriptedDataConverter::bindFromContext(DataContext* dataContext, + DataBind* dataBind) +{ + m_dataContext = rcp(safe_ref(dataContext)); + Super::bindFromContext(dataContext, dataBind); + reinit(); + for (auto prop : m_customProperties) + { + auto input = ScriptInput::from(prop); + if (input != nullptr) + { + if (input->dataBind() != nullptr) + { + input->dataBind()->as()->bindFromContext( + dataContext); + } + } + } +} + +bool ScriptedDataConverter::advanceComponent(float elapsedSeconds, + AdvanceFlags flags) +{ + if (!enums::is_flag_set(flags, AdvanceFlags::AdvanceNested)) + { + elapsedSeconds = 0; + } + return advance(elapsedSeconds); +} + +bool ScriptedDataConverter::advance(float elapsedSeconds) +{ + + if (elapsedSeconds == 0) + { + return false; + } + auto needsAdvance = scriptAdvance(elapsedSeconds); + if (needsAdvance) + { + markConverterDirty(); + } + return needsAdvance; +} + +void ScriptedDataConverter::addProperty(CustomProperty* prop) +{ + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(this); + } + CustomPropertyContainer::addProperty(prop); +} + +StatusCode ScriptedDataConverter::import(ImportStack& importStack) +{ + auto result = registerReferencer(importStack); + if (result != StatusCode::Ok) + { + return result; + } + return Super::import(importStack); +} + +Core* ScriptedDataConverter::clone() const +{ + ScriptedDataConverter* twin = + ScriptedDataConverterBase::clone()->as(); + if (m_fileAsset != nullptr) + { + twin->setAsset(m_fileAsset); + } + for (auto prop : m_customProperties) + { + auto clonedValue = prop->clone()->as(); + twin->addProperty(clonedValue); + auto scriptedInputClone = ScriptInput::from(clonedValue); + auto scriptedInputSource = ScriptInput::from(prop); + auto thisDataBinds = dataBinds(); + auto twinDataBinds = twin->dataBinds(); + if (scriptedInputClone && scriptedInputSource) + { + if (scriptedInputSource->dataBind()) + { + int index = 0; + // Data binds are cloned in the data converters, and assigned to + // the right target here + for (auto& dataBind : thisDataBinds) + { + if (dataBind->target() == prop) + { + if (index < twinDataBinds.size()) + { + twinDataBinds[index]->target(clonedValue); + scriptedInputClone->dataBind(twinDataBinds[index]); + } + } + index++; + } + } + } + } + return twin; +} + +bool ScriptedDataConverter::addDataBindFromScriptedObject(DataBind* dataBind) +{ + addDataBind(dataBind); + return true; +} \ No newline at end of file diff --git a/thirdparty/rive/source/scripted/scripted_drawable.cpp b/thirdparty/rive/source/scripted/scripted_drawable.cpp new file mode 100644 index 000000000..f5f819145 --- /dev/null +++ b/thirdparty/rive/source/scripted/scripted_drawable.cpp @@ -0,0 +1,383 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/component_dirt.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_drawable.hpp" + +using namespace rive; + +#ifdef WITH_RIVE_SCRIPTING + +void ScriptedDrawable::didHydrateScriptInputs() +{ + m_isAdvanceActive = true; + addDirt(ComponentDirt::Paint); +} + +void ScriptedDrawable::draw(Renderer* renderer) +{ + if (!draws() || m_vm == nullptr) + { + return; + } + + lua_State* L = state(); + float opacity = renderOpacity(); + bool needsOpacitySave = (opacity != 1.0f); + if (m_needsSaveOperation || needsOpacitySave) + { + renderer->save(); + } + + if (needsOpacitySave) + { + renderer->modulateOpacity(opacity); + } + + renderer->transform(worldTransform()); + // Stack: [] + auto scriptedRenderer = lua_newrive(L, renderer); + // Stack: [scriptedRenderer] + rive_lua_pushRef(L, m_self); + // Stack: [scriptedRenderer, self] + lua_getfield(L, -1, "draw"); + // Stack: [scriptedRenderer, self, "draw"] + lua_pushvalue(L, -2); + // Stack: [scriptedRenderer, self, "draw", self] + lua_pushvalue(L, -4); + // Stack: [scriptedRenderer, self, "draw", self, scriptedRenderer] + if (static_cast(rive_lua_pcall_with_context(L, this, 2, 0)) != + LUA_OK) + { + // Stack: [scriptedRenderer, self, status] + rive_lua_pop(L, 1); + } + scriptedRenderer->end(); + // Stack: [scriptedRenderer, self] + rive_lua_pop(L, 2); + + if (m_needsSaveOperation || needsOpacitySave) + { + renderer->restore(); + } +} + +std::vector ScriptedDrawable::hitComponents( + StateMachineInstance* sm) +{ + if (!listensToPointerEvents()) + { + return {}; + } + auto* hitComponent = new HitScriptedDrawable(this, sm); + return std::vector{hitComponent}; +} + +HitResult HitScriptedDrawable::processEvent(Vec2D position, + ListenerType hitType, + bool canHit, + float timeStamp, + int pointerId) +{ + HitResult hitResult = HitResult::none; + auto scriptAsset = m_drawable->scriptAsset(); + auto state = m_drawable->state(); + if (state == nullptr || scriptAsset == nullptr || + !handlesEvent(canHit, hitType)) + { + return HitResult::none; + } + Vec2D localPos; + auto hasLocalPos = m_drawable->worldToLocal(position, &localPos); + if (!hasLocalPos) + { + return hitResult; + } + rive_lua_pushRef(state, m_drawable->self()); + auto mName = methodName(canHit, hitType); + if (static_cast(lua_getfield(state, -1, mName.c_str())) != + LUA_TFUNCTION) + { + fprintf(stderr, "expected %s to be a function\n", mName.c_str()); + rive_lua_pop(state, 1); + } + else + { + lua_pushvalue(state, -2); + auto pointerEvent = + lua_newrive(state, pointerId, localPos); + if (static_cast( + rive_lua_pcall_with_context(state, m_drawable, 2, 0)) != LUA_OK) + { + fprintf(stderr, "%s failed\n", mName.c_str()); + rive_lua_pop(state, 1); + } + hitResult = pointerEvent->m_hitResult; + } + rive_lua_pop(state, 1); + return hitResult; +} + +bool ScriptedDrawable::keyInput(Key key, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ + if (!wantsKeyboardInput()) + { + return false; + } + bool shouldStopPropagation = false; + auto L = state(); + if (L == nullptr) + { + return shouldStopPropagation; + } + // Stack: [] + rive_lua_pushRef(L, self()); + // Stack: [self] + lua_getfield(L, -1, "keyboardEvent"); + // Stack: [self, field] + lua_pushvalue(L, -2); + // Stack: [self, field, self] + lua_newrive(L, + key, + modifiers, + isPressed, + isRepeat); + + // Stack: [self, field, self, keyEvent] + if (static_cast(rive_lua_pcall_with_context(L, this, 2, 1)) != + LUA_OK) + { + fprintf(stderr, "%s failed\n", "keyboardEvent"); + // Stack: [self, status] + rive_lua_pop(L, 1); + } + else + { + if (lua_isboolean(L, -1)) + { + shouldStopPropagation = lua_toboolean(L, -1); + } + // Stack: [self, result] + rive_lua_pop(L, 1); + } + // Stack: [self] + rive_lua_pop(L, 1); + return shouldStopPropagation; +} + +bool ScriptedDrawable::textInput(const std::string& text) +{ + if (!wantsTextInput()) + { + return false; + } + bool shouldStopPropagation = false; + auto L = state(); + if (L == nullptr) + { + return shouldStopPropagation; + } + // Stack: [] + rive_lua_pushRef(L, self()); + // Stack: [self] + lua_getfield(L, -1, "textEvent"); + // Stack: [self, field] + lua_pushvalue(L, -2); + // Stack: [self, field, self] + lua_newrive(L, text); + + // Stack: [self, field, self, textInvocation] + if (static_cast(rive_lua_pcall_with_context(L, this, 2, 1)) != + LUA_OK) + { + fprintf(stderr, "%s failed\n", "textEvent"); + // Stack: [self, status] + rive_lua_pop(L, 1); + } + else + { + if (lua_isboolean(L, -1)) + { + shouldStopPropagation = lua_toboolean(L, -1); + } + // Stack: [self, result] + rive_lua_pop(L, 1); + } + // Stack: [self] + rive_lua_pop(L, 1); + return shouldStopPropagation; +} + +bool ScriptedDrawable::willDraw() +{ + return Super::willDraw() && m_vm != nullptr && draws(); +} + +#else +void ScriptedDrawable::draw(Renderer* renderer) {} + +std::vector ScriptedDrawable::hitComponents( + StateMachineInstance* sm) +{ + return {}; +} + +HitResult HitScriptedDrawable::processEvent(Vec2D position, + ListenerType hitType, + bool canHit, + float timeStamp, + int pointerId) +{ + return HitResult::none; +} + +bool ScriptedDrawable::willDraw() { return Super::willDraw() && draws(); } + +#endif + +void ScriptedDrawable::update(ComponentDirt value) +{ + Super::update(value); + if ((value & ComponentDirt::ScriptUpdate) == ComponentDirt::ScriptUpdate) + { + scriptUpdate(); + m_isAdvanceActive = true; + } +} + +Core* ScriptedDrawable::hitTest(HitInfo*, const Mat2D&) { return nullptr; } + +StatusCode ScriptedDrawable::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + artboard()->addScriptedObject(this); + return StatusCode::Ok; +} + +bool ScriptedDrawable::advanceComponent(float elapsedSeconds, + AdvanceFlags flags) +{ + if (elapsedSeconds == 0) + { + return false; + } + if (!m_isAdvanceActive) + { + return false; + } + m_isAdvanceActive = false; + if (!enums::is_flag_set(flags, AdvanceFlags::AdvanceNested)) + { + elapsedSeconds = 0; + } + auto advanced = scriptAdvance(elapsedSeconds); + if (advanced) + { + m_isAdvanceActive = true; + addScriptedDirt(ComponentDirt::Paint); + } + return advanced; +} + +bool ScriptedDrawable::addScriptedDirt(ComponentDirt value, bool recurse) +{ + return Drawable::addDirt(value, recurse); +} + +void ScriptedDrawable::addProperty(CustomProperty* prop) +{ + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(this); + } + CustomPropertyContainer::addProperty(prop); +} + +StatusCode ScriptedDrawable::import(ImportStack& importStack) +{ + auto result = registerReferencer(importStack); + if (result != StatusCode::Ok) + { + return result; + } + return Super::import(importStack); +} + +Core* ScriptedDrawable::clone() const +{ + ScriptedDrawable* twin = + ScriptedDrawableBase::clone()->as(); + if (m_fileAsset != nullptr) + { + twin->setAsset(m_fileAsset); + } + return twin; +} + +void ScriptedDrawable::markNeedsUpdate() +{ + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +bool ScriptedDrawable::worldToLocal(Vec2D world, Vec2D* local) +{ + Mat2D toMountedArtboard; + if (!worldTransform().invert(&toMountedArtboard)) + { + return false; + } + + *local = toMountedArtboard * world; + + return true; +} + +bool HitScriptedDrawable::handlesEvent(bool canHit, ListenerType hitEvent) +{ + if (canHit) + { + switch (hitEvent) + { + case ListenerType::down: + return m_drawable->wantsPointerDown(); + case ListenerType::up: + return m_drawable->wantsPointerUp(); + case ListenerType::dragStart: + return false; + case ListenerType::dragEnd: + return false; + default: + return m_drawable->wantsPointerMove(); + } + } + return m_drawable->wantsPointerExit(); +} + +std::string HitScriptedDrawable::methodName(bool canHit, ListenerType hitEvent) +{ + if (canHit) + { + switch (hitEvent) + { + case ListenerType::down: + return "pointerDown"; + case ListenerType::up: + return "pointerUp"; + case ListenerType::dragStart: + case ListenerType::dragEnd: + return ""; + default: + return "pointerMove"; + } + } + return "pointerExit"; +} \ No newline at end of file diff --git a/thirdparty/rive/source/scripted/scripted_layout.cpp b/thirdparty/rive/source/scripted/scripted_layout.cpp new file mode 100644 index 000000000..05e8ef0eb --- /dev/null +++ b/thirdparty/rive/source/scripted/scripted_layout.cpp @@ -0,0 +1,148 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/component_dirt.hpp" +#include "rive/layout_component.hpp" +#include "rive/scripted/scripted_layout.hpp" + +using namespace rive; + +#ifdef WITH_RIVE_SCRIPTING + +void ScriptedLayout::didHydrateScriptInputs() +{ + ScriptedDrawable::didHydrateScriptInputs(); + if (parent() != nullptr && parent()->is()) + { + parent()->as()->markLayoutNodeDirty(true); + } +} + +void ScriptedLayout::callScriptedResize(Vec2D size) +{ + if (!resizes() || m_vm == nullptr) + { + return; + } + lua_State* L = state(); + // Stack: [] + rive_lua_pushRef(L, m_self); + // Stack: [self] + lua_getfield(L, -1, "resize"); + // Stack: [self, function] + lua_pushvalue(L, -2); + // Stack: [self, function, self] + lua_pushvec2d(L, size); + // Stack: [self, function, self, size] + if (static_cast(rive_lua_pcall_with_context(L, this, 2, 0)) != + LUA_OK) + { + // Stack: [self, status] + fprintf(stderr, "resize failed\n"); + rive_lua_pop(L, 1); + } + // Stack: [self] + rive_lua_pop(L, 1); +} + +Vec2D ScriptedLayout::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + if (!measures() || m_vm == nullptr) + { + return Vec2D(0, 0); + } + lua_State* L = state(); + auto measuredWidth = std::numeric_limits::max(); + auto measuredHeight = std::numeric_limits::max(); + // Stack: [] + rive_lua_pushRef(L, m_self); + // Stack: [self] + lua_getfield(L, -1, "measure"); + // Stack: [self, field] + lua_pushvalue(L, -2); + // Stack: [self, field, self] + if (static_cast(rive_lua_pcall_with_context(L, this, 1, 1)) != + LUA_OK) + { + + fprintf(stderr, "measure failed\n"); + } + else + { + if (static_cast(lua_type(L, -1)) != LUA_TVECTOR) + { + fprintf(stderr, "expected measure to return a Vec2D\n"); + } + else + { + auto size = lua_tovec2d(L, -1); + measuredWidth = size->x; + measuredHeight = size->y; + } + } + // Stack: [self, status] or Stack: [self, result] + rive_lua_pop(L, 2); + + return Vec2D(std::min((widthMode == LayoutMeasureMode::undefined + ? std::numeric_limits::max() + : width), + measuredWidth), + std::min((heightMode == LayoutMeasureMode::undefined + ? std::numeric_limits::max() + : height), + measuredHeight)); +} + +void ScriptedLayout::controlSize(Vec2D size, + LayoutScaleType widthScaleType, + LayoutScaleType heightScaleType, + LayoutDirection direction) +{ + m_size = size; + callScriptedResize(size); +} +#else +Vec2D ScriptedLayout::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + return Vec2D((widthMode == LayoutMeasureMode::undefined + ? std::numeric_limits::max() + : width), + (heightMode == LayoutMeasureMode::undefined + ? std::numeric_limits::max() + : height)); +} + +void ScriptedLayout::controlSize(Vec2D size, + LayoutScaleType widthScaleType, + LayoutScaleType heightScaleType, + LayoutDirection direction) +{ + m_size = size; +} +#endif + +void ScriptedLayout::addProperty(CustomProperty* prop) +{ + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(this); + } + CustomPropertyContainer::addProperty(prop); +} + +Core* ScriptedLayout::clone() const +{ + ScriptedLayout* twin = ScriptedLayoutBase::clone()->as(); + if (m_fileAsset != nullptr) + { + twin->setAsset(m_fileAsset); + } + return twin; +} \ No newline at end of file diff --git a/thirdparty/rive/source/scripted/scripted_object.cpp b/thirdparty/rive/source/scripted/scripted_object.cpp new file mode 100644 index 000000000..5d56e4933 --- /dev/null +++ b/thirdparty/rive/source/scripted/scripted_object.cpp @@ -0,0 +1,525 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/assets/script_asset.hpp" +#include "rive/artboard.hpp" +#include "rive/file.hpp" +#include "rive/script_input_artboard.hpp" +#include "rive/animation/scripted_listener_action.hpp" +#include "rive/animation/scripted_transition_condition.hpp" +#include "rive/scripted/scripted_data_converter.hpp" +#include "rive/scripted/scripted_drawable.hpp" +#include "rive/scripted/scripted_layout.hpp" +#include "rive/scripted/scripted_path_effect.hpp" +#include "rive/scripted/scripted_object.hpp" +#include "rive/data_bind/data_bind.hpp" + +using namespace rive; + +ScriptedObject* ScriptedObject::from(Core* object) +{ + switch (object->coreType()) + { + case ScriptedDataConverter::typeKey: + return object->as(); + case ScriptedDrawable::typeKey: + return object->as(); + case ScriptedLayout::typeKey: + return object->as(); + case ScriptedPathEffect::typeKey: + return object->as(); + case ScriptedListenerAction::typeKey: + return object->as(); + case ScriptedTransitionCondition::typeKey: + return object->as(); + } + return nullptr; +} + +#ifdef WITH_RIVE_SCRIPTING +void ScriptedObject::setArtboardInput(std::string name, Artboard* artboard) +{ + lua_State* L = state(); + if (L == nullptr || scriptAsset() == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + auto artboardInstance = artboard->instance(); + artboardInstance->frameOrigin(false); + lua_newrive(L, + L, + ref_rcp(scriptAsset()->file()), + std::move(artboardInstance), + nullptr, + dataContext()); + lua_setfield(L, -2, name.c_str()); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +void ScriptedObject::setBooleanInput(std::string name, bool value) +{ + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + lua_pushboolean(L, value); + lua_setfield(L, -2, name.c_str()); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +void ScriptedObject::setNumberInput(std::string name, float value) +{ + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + lua_pushnumber(L, value); + lua_setfield(L, -2, name.c_str()); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +void ScriptedObject::setIntegerInput(std::string name, int value) +{ + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + lua_pushunsigned(L, value); + lua_setfield(L, -2, name.c_str()); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +void ScriptedObject::setStringInput(std::string name, std::string value) +{ + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + lua_pushstring(L, value.c_str()); + lua_setfield(L, -2, name.c_str()); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +void ScriptedObject::setViewModelInput(std::string name, + ViewModelInstanceValue* value) +{ + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + switch (value->coreType()) + { + case ViewModelInstanceViewModelBase::typeKey: + { + auto viewModel = value->as(); + auto vmi = viewModel->referenceViewModelInstance(); + if (vmi == nullptr) + { + fprintf(stderr, + "riveLuaPushViewModelInstanceValue - passed in a " + "ViewModelInstanceViewModel with no associated " + "ViewModelInstance.\n"); + return; + } + + lua_newrive(L, + L, + ref_rcp(vmi->viewModel()), + vmi); + break; + } + default: + break; + } + lua_setfield(L, -2, name.c_str()); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +void ScriptedObject::trigger(std::string name) +{ + lua_State* L = state(); + if (L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + if (static_cast(lua_getfield(L, -1, name.c_str())) != + LUA_TFUNCTION) + { + rive_lua_pop(L, 2); + return; + } + lua_pushvalue(L, -2); + rive_lua_pcall_with_context(L, this, 1, 0); + rive_lua_pop(L, 1); + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +bool ScriptedObject::scriptAdvance(float elapsedSeconds) +{ + lua_State* L = state(); + if (!advances() || L == nullptr) + { + return false; + } + rive_lua_pushRef(L, m_self); + lua_getfield(L, -1, "advance"); + lua_pushvalue(L, -2); + lua_pushnumber(L, elapsedSeconds); + if (static_cast(rive_lua_pcall_with_context(L, this, 2, 1)) != + LUA_OK) + { + rive_lua_pop(L, 2); + return false; + } + bool result = lua_toboolean(L, -1); + rive_lua_pop(L, 2); + return result; +} + +void ScriptedObject::scriptDrawCanvas() +{ + lua_State* L = state(); + if (!drawsCanvas() || L == nullptr) + { + return; + } + rive_lua_pushRef(L, m_self); + lua_getfield(L, -1, "drawCanvas"); + lua_pushvalue(L, -2); + if (static_cast(rive_lua_pcall(L, 1, 0)) != LUA_OK) + { + rive_lua_pop(L, 1); + return; + } + rive_lua_pop(L, 1); +} + +void ScriptedObject::scriptUpdate() +{ + lua_State* L = state(); + if (!updates() || L == nullptr) + { + return; + } + // Stack: [] + rive_lua_pushRef(L, m_self); + // Stack: [self] + lua_getfield(L, -1, "update"); + // Stack: [self, field] Swap self and field + lua_insert(L, -2); + // Stack: [field, self] + if (static_cast(rive_lua_pcall_with_context(L, this, 1, 0)) != + LUA_OK) + { + rive_lua_pop(L, 1); + } +} + +bool ScriptedObject::tryLuaUserInit(lua_State* L) +{ + rive_lua_pushRef(L, m_self); + // Stack: [self] + m_contextPtr = lua_newrive(L, this); + // Stack: [self, ScriptedContext] + m_context = lua_ref(L, -1); + rive_lua_pop(L, 1); + // Stack: [self] + lua_getfield(L, -1, "init"); + // Stack: [self, field] + lua_pushvalue(L, -2); + // Stack: [self, field, self] + rive_lua_pushRef(L, m_context); + // Stack: [self, field, self, ScriptedContext] + auto pCallResult = rive_lua_pcall_with_context(L, this, 2, 1); + if (static_cast(pCallResult) != LUA_OK) + { + lua_unref(L, m_self); + disposeScriptedContext(); + // Stack: [self, status] + rive_lua_pop(L, 2); + m_vm = nullptr; + m_self = 0; + return false; + } + if (!lua_toboolean(L, -1) || m_contextPtr->missingRequestedData()) + { + lua_unref(L, m_self); + disposeScriptedContext(); + rive_lua_pop(L, 2); + m_vm = nullptr; + m_self = 0; + return false; + } + // Stack: [self, result] + rive_lua_pop(L, 1); + assert(static_cast(lua_type(L, -1)) == LUA_TTABLE); + // Stack: [self] + rive_lua_pop(L, 1); + return true; +} + +bool ScriptedObject::ensureScriptInitialized(ScriptingVM* vm) +{ + lua_State* L = vm ? vm->state() : nullptr; + if (L == nullptr) + { + return false; + } +#if defined(WITH_RIVE_TOOLS) + if (m_self != 0 && m_vm.get() == vm) +#else + if (m_self != 0 && m_vm == vm) +#endif + { + rive_lua_pop(L, 1); + return true; + } + if (m_vm != nullptr) + { + lua_State* oldState = state(); + if (m_self != 0) + { + lua_unref(oldState, m_self); + m_self = 0; + } + + disposeTrackedProperties(); + disposeScriptedContext(); + } + m_userLuaInitDone = false; + + for (auto prop : m_customProperties) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput && !scriptInput->validateForColdScriptInit()) + { + rive_lua_pop(L, 1); + return false; + } + } + if (static_cast(rive_lua_pcall_with_context(L, this, 0, 1)) != + LUA_OK) + { + rive_lua_pop(L, 1); + return false; + } + if (static_cast(lua_type(L, -1)) != LUA_TTABLE) + { + rive_lua_pop(L, 1); + return false; + } + m_self = lua_ref(L, -1); +#ifdef WITH_RIVE_TOOLS + m_vm = ref_rcp(vm); +#else + m_vm = vm; +#endif + rive_lua_pop(L, 1); + return true; +} + +bool ScriptedObject::hydrateScriptInputs() +{ + lua_State* L = state(); + if (L == nullptr || m_self == 0) + { + return false; + } + // First validate that all properties are hydratable. + // This ensures we don't partially hydrate props and early out on the next + // step + for (auto prop : m_customProperties) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr && + !scriptInput->validateHydrationPrerequisites()) + { + return false; + } + } + // Next hydrate all properties + for (auto prop : m_customProperties) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr && !scriptInput->hydrateScriptInput()) + { + return false; + } + } + // Finally initialize the script if it hasn't been initialized before. + if (inits() && !m_userLuaInitDone) + { + if (!tryLuaUserInit(L)) + { + return false; + } + m_userLuaInitDone = true; + } + didHydrateScriptInputs(); + return true; +} + +void ScriptedObject::disposeScriptInputs() +{ + for (auto prop : m_customProperties) + { + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(nullptr); + } + } + m_customProperties.clear(); +} + +void ScriptedObject::disposeTrackedProperties() +{ + + auto trackedProperties = m_trackedScriptedProperties; + for (auto* property : trackedProperties) + { + if (property != nullptr) + { + property->dispose(); + } + } +} + +void ScriptedObject::disposeScriptedContext() +{ + if (m_contextPtr != nullptr) + { + m_contextPtr->clearScriptedObject(); + m_contextPtr = nullptr; + } + if (m_context != 0) + { + lua_State* L = state(); + if (L != nullptr) + { + lua_unref(L, m_context); + } + m_context = 0; + } +} + +void ScriptedObject::scriptDispose() +{ + disposeScriptInputs(); + disposeTrackedProperties(); + m_trackedScriptedProperties.clear(); + + lua_State* L = state(); + if (L != nullptr) + { + lua_unref(L, m_self); + disposeScriptedContext(); +#ifdef TESTING + // Force GC to collect any ScriptedArtboard instances created via + // instance() + lua_gc(L, LUA_GCCOLLECT, 0); +#endif + } + m_vm = nullptr; + m_self = 0; + m_userLuaInitDone = false; +} +#else +void ScriptedObject::setArtboardInput(std::string name, Artboard* artboard) {} + +void ScriptedObject::setBooleanInput(std::string name, bool value) {} + +void ScriptedObject::setIntegerInput(std::string name, int value) {} + +void ScriptedObject::setNumberInput(std::string name, float value) {} + +void ScriptedObject::setStringInput(std::string name, std::string value) {} + +void ScriptedObject::setViewModelInput(std::string name, + ViewModelInstanceValue* value) +{} + +void ScriptedObject::trigger(std::string name) {} + +bool ScriptedObject::scriptAdvance(float elapsedSeconds) { return false; } + +void ScriptedObject::scriptDrawCanvas() {} + +void ScriptedObject::scriptUpdate() {} + +void ScriptedObject::scriptDispose() {} + +void ScriptedObject::disposeScriptInputs() {} +#endif + +void ScriptedObject::reinit() +{ + if (scriptAsset() != nullptr) + { + scriptAsset()->initScriptedObject(this); +#ifdef WITH_RIVE_SCRIPTING + hydrateScriptInputs(); +#endif + } +} + +ScriptAsset* ScriptedObject::scriptAsset() const +{ + return (ScriptAsset*)m_fileAsset.get(); +} + +void ScriptedObject::setAsset(rcp asset) +{ + if (asset != nullptr && asset->is()) + { + FileAssetReferencer::setAsset(asset); + } +} + +void ScriptedObject::markNeedsUpdate() {} + +void ScriptedObject::cloneProperties(CustomPropertyContainer* twin, + DataBindContainer* dataBindContainer) const +{ + + for (auto prop : m_customProperties) + { + auto clonedValue = prop->clone()->as(); + twin->addProperty(clonedValue); + auto input = ScriptInput::from(prop); + if (input != nullptr) + { + auto dataBind = input->dataBind(); + if (dataBind) + { + auto dataBindClone = static_cast(dataBind->clone()); + dataBindClone->file(dataBind->file()); + if (dataBind->converter() != nullptr) + { + dataBindClone->converter( + dataBind->converter()->clone()->as()); + } + dataBindClone->target(clonedValue); + dataBindContainer->addDataBind(dataBindClone); + } + } + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/scripted/scripted_path_effect.cpp b/thirdparty/rive/source/scripted/scripted_path_effect.cpp new file mode 100644 index 000000000..8f880b4ed --- /dev/null +++ b/thirdparty/rive/source/scripted/scripted_path_effect.cpp @@ -0,0 +1,202 @@ +#ifdef WITH_RIVE_SCRIPTING +#include "rive/lua/rive_lua_libs.hpp" +#endif +#include "rive/component_dirt.hpp" +#include "rive/assets/script_asset.hpp" +#include "rive/scripted/scripted_path_effect.hpp" +#include "rive/shapes/paint/stroke.hpp" + +using namespace rive; + +void ScriptedEffectPath::invalidateEffect() { m_path.rewind(); } + +#ifdef WITH_RIVE_SCRIPTING + +void ScriptedPathEffect::didHydrateScriptInputs() +{ + m_isAdvanceActive = true; + addScriptedDirt(ComponentDirt::Paint, true); +} + +void ScriptedPathEffect::updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) +{ + if (!updates()) + { + return; + } + + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) + { + auto trimEffectPath = + static_cast(effectPathIt->second); + auto path = trimEffectPath->path(); + if (path->hasRenderPath()) + { + // Previous result hasn't been invalidated, it's still good. + return; + } + + path->rewind(source->isLocal(), source->fillRule()); + lua_State* L = state(); + if (L == nullptr) + { + return; + } + // Stack: [] + rive_lua_pushRef(L, m_self); + // Stack: [self] + lua_getfield(L, -1, "update"); + // Stack: [self, "update"] + lua_pushvalue(L, -2); + // Stack: [self, "update", self] + lua_newrive(L, source->rawPath()); + // Stack: [self, "update", self, pathData] + lua_newrive(L, + nullptr, + shapePaint->parentTransformComponent()); + auto scriptedNode = lua_torive(L, -1); + scriptedNode->shapePaint(shapePaint); + // Stack: [self, "update", self, pathData, node] + if (static_cast( + rive_lua_pcall_with_context(L, this, 3, 1)) != LUA_OK) + { + fprintf(stderr, "update function failed\n"); + } + else + { + // Stack: [self, outputPathData] + auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, -1); + auto rawPath = path->mutableRawPath(); + rawPath->addPath(scriptedPath->rawPath); + } + // Stack: [self, status] or [self, outputPathData] + rive_lua_pop(L, 2); + } +} +#else +void ScriptedPathEffect::updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) +{} +#endif + +StatusCode ScriptedPathEffect::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + artboard()->addScriptedObject(this); + return StatusCode::Ok; +} + +StatusCode ScriptedPathEffect::onAddedClean(CoreContext* context) +{ + auto effectsContainer = EffectsContainer::from(parent()); + if (!effectsContainer) + { + return StatusCode::InvalidObject; + } + effectsContainer->addStrokeEffect(this); + + return StatusCode::Ok; +} + +bool ScriptedPathEffect::advanceComponent(float elapsedSeconds, + AdvanceFlags flags) +{ + if (elapsedSeconds == 0) + { + return false; + } + if (!m_isAdvanceActive) + { + return false; + } + m_isAdvanceActive = false; + if (!enums::is_flag_set(flags, AdvanceFlags::AdvanceNested)) + { + elapsedSeconds = 0; + } + auto advanced = scriptAdvance(elapsedSeconds); + if (advanced) + { + m_isAdvanceActive = true; + } + return advanced; +} + +bool ScriptedPathEffect::addScriptedDirt(ComponentDirt value, bool recurse) +{ + return Component::addDirt(value, recurse); +} + +void ScriptedPathEffect::addProperty(CustomProperty* prop) +{ + auto scriptInput = ScriptInput::from(prop); + if (scriptInput != nullptr) + { + scriptInput->scriptedObject(this); + } + CustomPropertyContainer::addProperty(prop); +} + +StatusCode ScriptedPathEffect::import(ImportStack& importStack) +{ + auto result = registerReferencer(importStack); + if (result != StatusCode::Ok) + { + return result; + } + return Super::import(importStack); +} + +Core* ScriptedPathEffect::clone() const +{ + ScriptedPathEffect* twin = + ScriptedPathEffectBase::clone()->as(); + if (m_fileAsset != nullptr) + { + twin->setAsset(m_fileAsset); + } + return twin; +} + +void ScriptedPathEffect::markNeedsUpdate() +{ + addScriptedDirt(ComponentDirt::ScriptUpdate); +} + +EffectsContainer* ScriptedPathEffect::parentPaint() +{ + return EffectsContainer::from(parent()); +} + +EffectPath* ScriptedPathEffect::createEffectPath() +{ + return new ScriptedEffectPath(); +} + +void ScriptedPathEffect::buildDependencies() +{ + Super::buildDependencies(); + if (parent()) + { + parent()->addDependent(this); + } +} + +void ScriptedPathEffect::update(ComponentDirt value) +{ + Super::update(value); + + if (hasDirt(value, ComponentDirt::ScriptUpdate)) + { + invalidateEffectFromLocal(); + m_isAdvanceActive = true; + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/semantic/semantic_data.cpp b/thirdparty/rive/source/semantic/semantic_data.cpp new file mode 100644 index 000000000..cc2ea11aa --- /dev/null +++ b/thirdparty/rive/source/semantic/semantic_data.cpp @@ -0,0 +1,572 @@ +#include "rive/semantic/semantic_data.hpp" +#include "rive/artboard.hpp" +#include "rive/artboard_host.hpp" +#include "rive/component_dirt.hpp" +#include "rive/container_component.hpp" +#include "rive/drawable.hpp" +#include "rive/focus_data.hpp" +#include "rive/input/focus_manager.hpp" +#include "rive/node.hpp" +#include "rive/semantic/semantic_listener.hpp" +#include "rive/semantic/semantic_manager.hpp" +#include "rive/semantic/semantic_node.hpp" +#include "rive/semantic/semantic_provider.hpp" +#include "rive/semantic/semantic_state.hpp" +#include "rive/semantic/semantic_trait.hpp" + +#include "semantic_inference_registry.hpp" + +using namespace rive; + +SemanticData::~SemanticData() +{ + if (m_semanticNode != nullptr) + { + auto* manager = m_semanticNode->manager(); + if (manager != nullptr) + { + manager->removeChild(m_semanticNode); + } + } +} + +// Lazily creates the SemanticNode with a globally unique ID, copies +// authored properties, applies text inference, and computes initial bounds. +rcp SemanticData::semanticNode() +{ + if (m_semanticNode == nullptr) + { + // Id is assigned by SemanticManager on first addChild(); until + // then the node has id 0 and can't be looked up. All dirty-marking + // call sites in this file guard against a null manager, so id 0 + // is safe to carry around pre-registration. + m_semanticNode = rcp(new SemanticNode()); + m_semanticNode->coreOwner(parent()); + m_semanticNode->semanticData(this); + m_semanticNode->role(m_Role); + m_semanticNode->label(m_Label); + m_semanticNode->value(m_Value); + m_semanticNode->hint(m_Hint); + m_semanticNode->headingLevel(m_HeadingLevel); + m_semanticNode->stateFlags(m_StateFlags); + // Check if a sibling FocusData exists — if so, set the Focusable + // trait so the platform knows this node can receive focus. + uint32_t initialTraits = m_TraitFlags; + auto* parentNode = parent(); + if (parentNode != nullptr && parentNode->is()) + { + for (auto* child : parentNode->as()->children()) + { + if (child->is()) + { + initialTraits |= + static_cast(SemanticTrait::Focusable); + break; + } + } + } + m_semanticNode->traitFlags(initialTraits); + applyInferredSemanticsIfNeeded(); + // Set initial world bounds if available. Sibling shapes may not + // have built their paths yet (deferred due to renderOpacity == 0 + // during nested artboard init). Flag a retry so updateWorldBounds + // re-dirts once if the initial bounds are degenerate. + m_boundsRetryPending = true; + updateWorldBounds(); + } + return m_semanticNode; +} + +// Finds parent SemanticData by walking up the component hierarchy. +SemanticData* SemanticData::findParentSemanticData() const +{ + auto* current = parent(); + while (current != nullptr) + { + if (current->is()) + { + auto* node = current->as(); + for (auto* child : node->children()) + { + if (child->is() && child != this) + { + return child->as(); + } + } + } + current = current->parent(); + } + return nullptr; +} + +// Finds the closest SemanticNode for a component, crossing artboard +// boundaries via ArtboardHost. Walks up the component hierarchy; when +// it hits an Artboard, jumps to the host component in the parent artboard. +// Starts from the component itself so that SemanticData attached directly +// to the component (e.g. a NestedArtboard with role=button) is found. +rcp SemanticData::findClosestSemanticNode(Component* component) +{ + if (component == nullptr) + { + return nullptr; + } + + auto* current = component; + while (current != nullptr) + { + if (current->is()) + { + auto* artboard = current->as(); + // Try to cross the artboard boundary via the host component + auto* host = artboard->host(); + if (host != nullptr) + { + auto* hostComponent = host->hostComponent(); + if (hostComponent != nullptr && + hostComponent->is()) + { + // Continue searching from the host component (e.g., + // NestedArtboard) + current = hostComponent->as(); + continue; + } + } + // No way to traverse up, stop searching + return nullptr; + } + + if (current->is()) + { + if (auto* data = current->as()->firstChild()) + { + return data->semanticNode(); + } + } + + current = current->parent(); + } + return nullptr; +} + +uint32_t SemanticData::semanticId() const +{ + if (m_semanticNode == nullptr) + { + return 0; + } + return m_semanticNode->id(); +} + +void SemanticData::setFocusedState(bool focused) +{ + if (m_semanticNode == nullptr) + { + return; + } + uint32_t flags = m_semanticNode->stateFlags(); + if (focused) + { + flags |= static_cast(SemanticState::Focused); + } + else + { + flags &= ~static_cast(SemanticState::Focused); + } + m_semanticNode->stateFlags(flags); + markContentDirty(); +} + +bool SemanticData::requestFocus() +{ + auto* parentNode = parent(); + if (parentNode == nullptr || !parentNode->is()) + { + return false; + } + auto* focusData = parentNode->as()->firstChild(); + if (focusData == nullptr) + { + return false; + } + auto* ab = artboard(); + if (ab == nullptr) + { + return false; + } + auto* focusManager = ab->focusManager(); + if (focusManager == nullptr) + { + return false; + } + focusManager->setFocus(focusData->focusNode()); + return true; +} + +// Collapse/uncollapse: removes or re-adds SemanticNode to the tree. +// Collapse caches the manager before removal. Uncollapse re-adds with +// correct parent, recomputes bounds, and forces a WorldTransform dirt. +bool SemanticData::collapse(bool value) +{ + if (!Super::collapse(value)) + { + return false; + } + + if (m_semanticNode == nullptr) + { + return true; + } + + if (value) + { + // Capture the manager before removeChild clears it. + auto* manager = m_semanticNode->manager(); + if (manager != nullptr) + { + m_semanticManager = manager; + manager->removeChild(m_semanticNode); + } + } + else + { + // Re-add to semantic tree using the cached manager. + auto* manager = m_semanticManager; + if (manager == nullptr) + { + manager = m_semanticNode->manager(); + } + if (manager != nullptr) + { + m_semanticManager = manager; + manager->addChild(resolveParentNode(), m_semanticNode); + + // Re-apply current bounds and content so the node is up to date. + m_boundsRetryPending = true; + updateWorldBounds(); + + // Force a WorldTransform update so bounds are recomputed + // in the next update cycle after layout has been recalculated. + addDirt(ComponentDirt::WorldTransform, false); + + applyInferredSemanticsIfNeeded(); + } + } + + return true; +} + +// Register dependency on parent's world transform so update() fires +// when the parent node moves. +void SemanticData::buildDependencies() +{ + Super::buildDependencies(); + auto* parentComponent = parent(); + if (parentComponent != nullptr) + { + parentComponent->addDependent(this); + } +} + +// Update cycle handler. Called when the parent node's world transform +// changes or when a sibling Shape's geometry is rebuilt. Re-evaluates +// inferred semantics and recomputes world-space bounds. +void SemanticData::update(ComponentDirt value) +{ + // Paint dirt (opacity/color) does not affect tree membership — see + // shouldExcludeFromSemanticTree(). Only Collapsed + Hidden-state matter. + if (hasDirt(value, ComponentDirt::Collapsed)) + { + syncSemanticTreeVisibility(); + } + + if ((value & ComponentDirt::WorldTransform) == + ComponentDirt::WorldTransform) + { + applyInferredSemanticsIfNeeded(); + updateWorldBounds(); + } + + if ((value & ComponentDirt::Path) == ComponentDirt::Path) + { + updateWorldBounds(); + } +} + +// Applies inferred semantics if no explicit role/label was authored. +// Currently supports Text → role=label with concatenated run text. +void SemanticData::applyInferredSemanticsIfNeeded() +{ + if (m_Role != 0 || !m_Label.empty() || m_semanticNode == nullptr) + { + return; + } + ResolvedSemanticData inferred; + if (!resolveInferredSemantics(parent(), inferred)) + { + return; + } + if (m_semanticNode->role() == inferred.role && + m_semanticNode->label() == inferred.label) + { + return; + } + m_semanticNode->role(inferred.role); + m_semanticNode->label(inferred.label); + markContentDirty(); +} + +// Marks semantic content as dirty so manager emits updated diffs. +void SemanticData::markContentDirty() +{ + if (m_semanticNode == nullptr) + { + return; + } + auto* manager = m_semanticNode->manager(); + if (manager != nullptr && parent() != nullptr) + { + manager->markNodeDirty(semanticId(), SemanticDirt::Content); + } +} + +// Property change handlers. Called when role/label/stateFlags change from +// deserialization, animation, or data binding. Pushes the new value to the +// SemanticNode and marks content-dirty for the next diff. +void SemanticData::roleChanged() +{ + if (m_semanticNode == nullptr || m_semanticNode->role() == m_Role) + { + return; + } + m_semanticNode->role(m_Role); + markContentDirty(); +} + +void SemanticData::labelChanged() +{ + if (m_semanticNode == nullptr || m_semanticNode->label() == m_Label) + { + return; + } + m_semanticNode->label(m_Label); + markContentDirty(); +} + +void SemanticData::stateFlagsChanged() +{ + if (m_semanticNode == nullptr) + { + return; + } + if (m_semanticNode->stateFlags() == m_StateFlags) + { + return; + } + m_semanticNode->stateFlags(m_StateFlags); + markContentDirty(); + // Hidden bit changes affect tree membership, not just content. + syncSemanticTreeVisibility(); +} + +void SemanticData::traitFlagsChanged() +{ + if (m_semanticNode == nullptr || + m_semanticNode->traitFlags() == m_TraitFlags) + { + return; + } + m_semanticNode->traitFlags(m_TraitFlags); + markContentDirty(); +} + +void SemanticData::valueChanged() +{ + if (m_semanticNode == nullptr || m_semanticNode->value() == m_Value) + { + return; + } + m_semanticNode->value(m_Value); + markContentDirty(); +} + +void SemanticData::hintChanged() +{ + if (m_semanticNode == nullptr || m_semanticNode->hint() == m_Hint) + { + return; + } + m_semanticNode->hint(m_Hint); + markContentDirty(); +} + +void SemanticData::headingLevelChanged() +{ + if (m_semanticNode == nullptr || + m_semanticNode->headingLevel() == m_HeadingLevel) + { + return; + } + m_semanticNode->headingLevel(m_HeadingLevel); + markContentDirty(); +} + +rcp SemanticData::resolveParentNode() const +{ + auto* localParent = findParentSemanticData(); + rcp parentNode = + localParent != nullptr ? localParent->semanticNode() : nullptr; + if (parentNode == nullptr) + { + auto* ab = artboard(); + if (ab != nullptr) + { + parentNode = ab->semanticBoundaryNode(); + } + } + return parentNode; +} + +bool SemanticData::shouldExcludeFromSemanticTree() const +{ + if (hasSemanticState(m_StateFlags, SemanticState::Hidden)) + { + return true; + } + + auto* current = parent(); + if (current == nullptr) + { + return true; + } + if (current->isCollapsed()) + { + return true; + } + if (current->is() && current->as()->isHidden()) + { + return true; + } + // Note: opacity 0 does NOT exclude from the semantic tree. A + // visually hidden component may still be interactive and should + // remain accessible to screen readers. Use the Hidden semantic + // state flag for intentional exclusion. + return false; +} + +void SemanticData::syncSemanticTreeVisibility() +{ + if (m_semanticNode == nullptr) + { + return; + } + + const bool shouldExclude = shouldExcludeFromSemanticTree(); + if (shouldExclude == m_excludedFromTree) + { + return; + } + m_excludedFromTree = shouldExclude; + + auto* manager = m_semanticNode->manager(); + if (shouldExclude) + { + if (manager != nullptr) + { + m_semanticManager = manager; + manager->removeChild(m_semanticNode); + } + return; + } + + // Already tracked in the semantic tree. + if (manager != nullptr) + { + return; + } + + manager = m_semanticManager; + + if (manager == nullptr) + { + return; + } + + manager->addChild(resolveParentNode(), m_semanticNode); + + m_boundsRetryPending = true; + updateWorldBounds(); + applyInferredSemanticsIfNeeded(); +} + +void SemanticData::updateWorldBounds() +{ + if (m_semanticNode == nullptr) + { + return; + } + auto* parentComponent = parent(); + if (parentComponent == nullptr) + { + return; + } + auto bounds = SemanticProvider::semanticBounds(parentComponent); + if (bounds.isEmptyOrNaN() && m_boundsRetryPending) + { + // Bounds not ready (e.g. sibling Shape paths still deferred). + // Re-dirty so updateComponents() runs another iteration after + // sibling paths have been rebuilt in this same pass. + addDirt(ComponentDirt::WorldTransform, false); + return; + } + m_boundsRetryPending = false; + if (bounds == m_semanticNode->bounds()) + { + return; + } + m_semanticNode->bounds(bounds); + auto* manager = m_semanticNode->manager(); + if (manager != nullptr) + { + manager->markNodeDirty(semanticId(), SemanticDirt::Bounds); + } +} + +void SemanticData::addSemanticListener(SemanticListener* listener) +{ + m_semanticListeners.push_back(listener); +} + +void SemanticData::removeSemanticListener(SemanticListener* listener) +{ + auto it = std::find(m_semanticListeners.begin(), + m_semanticListeners.end(), + listener); + if (it != m_semanticListeners.end()) + { + m_semanticListeners.erase(it); + } +} + +void SemanticData::fireSemanticTap() +{ + for (auto* listener : m_semanticListeners) + { + listener->onSemanticTap(); + } +} + +void SemanticData::fireSemanticIncrease() +{ + for (auto* listener : m_semanticListeners) + { + listener->onSemanticIncrease(); + } +} + +void SemanticData::fireSemanticDecrease() +{ + for (auto* listener : m_semanticListeners) + { + listener->onSemanticDecrease(); + } +} diff --git a/thirdparty/rive/source/semantic/semantic_inference_registry.cpp b/thirdparty/rive/source/semantic/semantic_inference_registry.cpp new file mode 100644 index 000000000..442bf2005 --- /dev/null +++ b/thirdparty/rive/source/semantic/semantic_inference_registry.cpp @@ -0,0 +1,97 @@ +#include "semantic_inference_registry.hpp" + +#include "rive/component.hpp" +#include "rive/generated/text/text_base.hpp" +#include "rive/semantic/semantic_role.hpp" +#include "rive/text/text.hpp" + +namespace rive +{ +#ifdef WITH_RIVE_TEXT +namespace +{ + +using InferSemanticFn = bool (*)(Component*, ResolvedSemanticData&); + +struct InferenceRule +{ + uint16_t typeKey; + InferSemanticFn infer; +}; + +static std::string inferredTextLabel(Text* text) +{ + std::string label; + for (auto run : text->runs()) + { + if (run != nullptr) + { + label += run->text(); + } + } + return label; +} + +static bool inferTextSemantics(Component* component, ResolvedSemanticData& out) +{ + const auto label = inferredTextLabel(component->as()); + if (label.empty()) + { + return false; + } + + out.hasSemantics = true; + out.role = static_cast(SemanticRole::text); + out.label = label; + return true; +} + +static constexpr InferenceRule kInferenceRules[] = { + {TextBase::typeKey, inferTextSemantics}, +}; + +} // namespace + +bool supportsInferredSemantics(Component* component) +{ + if (component == nullptr) + { + return false; + } + for (const auto& rule : kInferenceRules) + { + if (component->isTypeOf(rule.typeKey)) + { + return true; + } + } + return false; +} + +bool resolveInferredSemantics(Component* component, ResolvedSemanticData& out) +{ + if (component == nullptr) + { + return false; + } + for (const auto& rule : kInferenceRules) + { + if (component->isTypeOf(rule.typeKey) && rule.infer(component, out)) + { + return true; + } + } + return false; +} +#else +// No inference rules are active when the text engine is compiled out — +// Text is the only current rule and it needs Text::runs(). +bool supportsInferredSemantics(Component*) { return false; } + +bool resolveInferredSemantics(Component*, ResolvedSemanticData&) +{ + return false; +} +#endif + +} // namespace rive diff --git a/thirdparty/rive/source/semantic/semantic_inference_registry.hpp b/thirdparty/rive/source/semantic/semantic_inference_registry.hpp new file mode 100644 index 000000000..7fc4baf07 --- /dev/null +++ b/thirdparty/rive/source/semantic/semantic_inference_registry.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_SEMANTIC_INFERENCE_REGISTRY_HPP_ +#define _RIVE_SEMANTIC_INFERENCE_REGISTRY_HPP_ + +#include "rive/semantic/semantic_provider.hpp" + +namespace rive +{ +class Component; + +bool supportsInferredSemantics(Component* component); +bool resolveInferredSemantics(Component* component, ResolvedSemanticData& out); +} // namespace rive + +#endif diff --git a/thirdparty/rive/source/semantic/semantic_manager.cpp b/thirdparty/rive/source/semantic/semantic_manager.cpp new file mode 100644 index 000000000..d4da9a1b8 --- /dev/null +++ b/thirdparty/rive/source/semantic/semantic_manager.cpp @@ -0,0 +1,1109 @@ +#include "rive/semantic/semantic_manager.hpp" + +#include "rive/artboard.hpp" +#include "rive/component.hpp" +#include "rive/semantic/semantic_data.hpp" +#include "rive/semantic/semantic_node.hpp" +#include "rive/semantic/semantic_provider.hpp" +#include "rive/semantic/semantic_role.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace rive; + +namespace +{ +// --------------------------------------------------------------------------- +// Label derivation helpers. +// +// Interactive elements (button, toggle, etc.) with no explicit label derive +// their accessible label from child semantic nodes. Children that contribute +// to the derived label are "absorbed" — excluded from the flat accessibility +// output so screen readers don't announce them twice. +// --------------------------------------------------------------------------- + +// Trim leading/trailing whitespace and collapse internal runs of whitespace +// to a single space. Preserves logical reading order. +static std::string normalizeLabel(const std::string& input) +{ + std::string result; + result.reserve(input.size()); + bool lastWasSpace = true; // treats start as whitespace → trims leading + for (char c : input) + { + if (static_cast(c) <= ' ') + { + if (!lastWasSpace && !result.empty()) + { + result += ' '; + lastWasSpace = true; + } + } + else + { + result += c; + lastWasSpace = false; + } + } + // Trim trailing space. + if (!result.empty() && result.back() == ' ') + { + result.pop_back(); + } + return result; +} + +// Walks the subtree rooted at `node` in tree order, collecting text and +// image labels. All visited (non-interactive) nodes are added to +// `absorbedIds`. Nested interactive elements are left untouched — they +// are not absorbed and their subtrees are not descended into. +static void collectLabelsFromSubtree(const rcp& node, + std::string& textOut, + std::string& imageTextOut, + std::unordered_set& absorbedIds) +{ + auto role = static_cast(node->role()); + + // Nested interactive element: don't absorb, don't descend. + if (isInteractiveRole(role)) + { + return; + } + + absorbedIds.insert(node->id()); + + if (role == SemanticRole::text && !node->label().empty()) + { + if (!textOut.empty()) + { + textOut += ' '; + } + textOut += node->label(); + } + else if (role == SemanticRole::image && !node->label().empty()) + { + // Only keep the first image label as fallback. + if (imageTextOut.empty()) + { + imageTextOut = node->label(); + } + } + + for (const auto& child : node->children()) + { + collectLabelsFromSubtree(child, textOut, imageTextOut, absorbedIds); + } +} + +// Reusable scratch state for a single deriveLabelForInteractiveNodes pass. +// Allocation buffers are owned here and clear()-ed between interactive +// nodes so capacity is kept across the walk. +struct LabelDerivationScratch +{ + std::string textLabel; + std::string imageLabel; + std::unordered_set absorbed; +}; + +static void deriveLabelVisit( + const rcp& node, + std::unordered_map& derivedLabels, + std::unordered_set& excludedIds, + LabelDerivationScratch& scratch) +{ + if (isInteractiveRole(node->role()) && node->label().empty()) + { + scratch.textLabel.clear(); + scratch.imageLabel.clear(); + scratch.absorbed.clear(); + + for (const auto& child : node->children()) + { + collectLabelsFromSubtree(child, + scratch.textLabel, + scratch.imageLabel, + scratch.absorbed); + } + + // Text takes priority; images are fallback only (spec §3.3). + std::string derived = normalizeLabel(scratch.textLabel); + if (derived.empty()) + { + derived = normalizeLabel(scratch.imageLabel); + } + + if (!derived.empty()) + { + derivedLabels[node->id()] = std::move(derived); + excludedIds.insert(scratch.absorbed.begin(), + scratch.absorbed.end()); + } + } + + for (const auto& child : node->children()) + { + if (excludedIds.count(child->id()) == 0) + { + deriveLabelVisit(child, derivedLabels, excludedIds, scratch); + } + } +} + +// Pre-pass that computes derived labels for interactive nodes and builds +// the set of absorbed (excluded) node IDs. +// +// Rules (from spec): +// 1. Explicit label wins — skip derivation. +// 2. Text children contribute in tree order; images only if no text. +// 3. Hidden / non-semantic nodes were already pruned before this point. +// 4. textField never auto-derives (not in isInteractiveRole). +// 5. Nested interactive children are not absorbed. +static void deriveLabelForInteractiveNodes( + const std::vector>& roots, + std::unordered_map& derivedLabels, + std::unordered_set& excludedIds) +{ + LabelDerivationScratch scratch; + for (const auto& root : roots) + { + deriveLabelVisit(root, derivedLabels, excludedIds, scratch); + } +} + +// --------------------------------------------------------------------------- +// Tree flattening. +// --------------------------------------------------------------------------- + +// Depth-first pre-order flattening of the SemanticNode tree into a flat +// array of SemanticsDiffNode structs. Nodes in `excludedIds` are skipped +// but their non-excluded children are reparented to the excluded node's +// parent (handles the nested-interactive-inside-absorbed-group case). +// Interactive nodes with entries in `derivedLabels` use the derived label +// instead of their (empty) canonical label. +static void flattenSemanticNode( + const rcp& node, + int32_t parentId, + uint32_t& siblingCounter, + std::vector& out, + const std::unordered_set& excludedIds, + const std::unordered_map& derivedLabels) +{ + if (excludedIds.count(node->id()) || node->isBoundaryNode()) + { + // Node is absorbed or is a structural boundary node — skip it + // but reparent any non-excluded children to the absorbing parent. + for (const auto& child : node->children()) + { + flattenSemanticNode(child, + parentId, + siblingCounter, + out, + excludedIds, + derivedLabels); + } + return; + } + + SemanticsDiffNode flat; + flat.id = node->id(); + flat.role = node->role(); + + auto derivedIt = derivedLabels.find(node->id()); + flat.label = + (derivedIt != derivedLabels.end()) ? derivedIt->second : node->label(); + + flat.value = node->value(); + flat.hint = node->hint(); + flat.stateFlags = node->stateFlags(); + flat.traitFlags = node->traitFlags(); + flat.headingLevel = node->headingLevel(); + const auto bounds = node->bounds(); + flat.minX = bounds.minX; + flat.minY = bounds.minY; + flat.maxX = bounds.maxX; + flat.maxY = bounds.maxY; + flat.parentId = parentId; + flat.siblingIndex = siblingCounter++; + out.push_back(flat); + + uint32_t childSiblingCounter = 0; + for (const auto& child : node->children()) + { + flattenSemanticNode(child, + static_cast(flat.id), + childSiblingCounter, + out, + excludedIds, + derivedLabels); + } +} + +// Entry point for full-tree flattening. Iterates all root nodes (nodes with +// no semantic parent, i.e. top-level accessible elements). Root nodes have +// parentId = -1. The reserveHint pre-allocates to avoid repeated +// vector reallocation during the walk. +static std::vector flattenFromSemanticNodes( + const std::vector>& roots, + size_t reserveHint, + const std::unordered_set& excludedIds, + const std::unordered_map& derivedLabels) +{ + std::vector out; + if (reserveHint != 0) + { + out.reserve(reserveHint); + } + uint32_t rootSiblingCounter = 0; + for (const auto& root : roots) + { + flattenSemanticNode(root, + -1, + rootSiblingCounter, + out, + excludedIds, + derivedLabels); + } + return out; +} + +// Maps parentId → ordered list of child ids. +// Used by buildDiffFromFlats to detect reordering and reparenting. +using ChildrenByParent = std::unordered_map>; + +// Builds the ChildrenByParent map from a flat snapshot. Groups nodes by +// parentId, then sorts each group by siblingIndex to produce the +// canonical child ordering. This ordering is compared frame-to-frame to +// detect reorder/reparent changes, which are emitted as +// SemanticsChildrenUpdate entries in the diff. +static ChildrenByParent buildChildrenByParent( + const std::vector& nodes) +{ + // First pass: group (siblingIndex, id) pairs by parent. + std::unordered_map>> + grouped; + grouped.reserve(nodes.size()); + for (const auto& node : nodes) + { + grouped[node.parentId].emplace_back(node.siblingIndex, node.id); + } + + // Second pass: sort each group by siblingIndex and extract ids + // in order. The result is a map from parentId to an ordered child list + // that can be directly compared via == for change detection. + ChildrenByParent out; + out.reserve(grouped.size()); + for (auto& entry : grouped) + { + auto& nodeList = entry.second; + std::sort(nodeList.begin(), + nodeList.end(), + [](const std::pair& a, + const std::pair& b) { + return a.first < b.first; + }); + auto& children = out[entry.first]; + children.reserve(nodeList.size()); + for (const auto& n : nodeList) + { + children.push_back(n.second); + } + } + return out; +} + +// --------------------------------------------------------------------------- +// Visual position ordering. +// +// Screen-reader traversal order is determined by the order of children in +// each SemanticNode's children vector. These helpers sort children by their +// visual position (top-to-bottom, left-to-right) and detect when bounds +// changes have caused siblings to move past each other. +// --------------------------------------------------------------------------- + +// Returns true if the children with valid bounds are already in visual +// order (top-to-bottom, left-to-right). Nodes with empty/NaN bounds are +// skipped — they have no visual position to compare. +static bool childrenInVisualOrder( + const std::vector>& children) +{ + AABB prevBounds; + bool hasPrev = false; + for (const auto& child : children) + { + const auto b = child->bounds(); + if (b.isEmptyOrNaN()) + { + continue; + } + if (hasPrev) + { + if (b.minY < prevBounds.minY || + (b.minY == prevBounds.minY && b.minX < prevBounds.minX)) + { + return false; + } + } + prevBounds = b; + hasPrev = true; + } + return true; +} + +// Compares two flat snapshots (current vs. previous) and produces a +// SemanticsDiff with added, removed, moved, updatedSemantic, +// updatedGeometry, and childrenUpdated arrays. +static SemanticsDiff buildDiffFromFlats( + const std::vector& currentFlat, + const std::vector& previousFlat, + uint64_t treeVersion) +{ + SemanticsDiff diff; + diff.frameNumber = Artboard::frameId(); + diff.treeVersion = treeVersion; + + uint32_t rootCount = 0; + uint32_t rootId = 0; + for (const auto& node : currentFlat) + { + if (node.parentId != -1) + { + continue; + } + rootCount++; + rootId = node.id; + } + if (rootCount == 1) + { + diff.rootId = rootId; + } + + // First-frame fast path: no previous snapshot to diff against, so + // everything is an addition. Also emit the full children ordering map + // so the platform can set up its tree structure in one pass. + // + // Emit childrenUpdated entries in the order parents first appear as + // parentId in currentFlat (tree pre-order). Consumers applying the diff + // sequentially see parents attached before their children's orderings. + if (previousFlat.empty()) + { + const auto currentChildrenByParent = buildChildrenByParent(currentFlat); + std::unordered_set seenParents; + seenParents.reserve(currentChildrenByParent.size()); + for (const auto& node : currentFlat) + { + if (!seenParents.insert(node.parentId).second) + { + continue; + } + auto it = currentChildrenByParent.find(node.parentId); + if (it == currentChildrenByParent.end()) + { + continue; + } + SemanticsChildrenUpdate update; + update.parentId = it->first; + update.childIds = it->second; + diff.childrenUpdated.push_back(std::move(update)); + } + + diff.added.reserve(currentFlat.size()); + for (const auto& node : currentFlat) + { + diff.added.push_back(node); + } + return diff; + } + + // Build O(1) lookup maps for both snapshots. These allow per-node + // comparisons without scanning the full arrays. + std::unordered_map currentById; + currentById.reserve(currentFlat.size()); + for (const auto& node : currentFlat) + { + currentById[node.id] = &node; + } + + std::unordered_map previousById; + previousById.reserve(previousFlat.size()); + for (const auto& node : previousFlat) + { + previousById[node.id] = &node; + } + + // Build children-by-parent maps for both snapshots. Used later + // to detect reordering and reparenting of child lists. + const auto currentChildrenByParent = buildChildrenByParent(currentFlat); + const auto previousChildrenByParent = buildChildrenByParent(previousFlat); + + // Removal detection: any node in the previous snapshot that is absent + // from the current snapshot has been removed. The platform layer uses + // this to tear down the corresponding accessibility node. Iterate + // previousFlat (tree pre-order) so removed ids are emitted + // deterministically. + for (const auto& previousNode : previousFlat) + { + if (currentById.find(previousNode.id) == currentById.end()) + { + diff.removed.push_back(previousNode.id); + } + } + + // Added / moved / content / geometry detection for nodes in current. + // For each current node: + // - If absent from previous → added (new node appeared). + // - If present in previous → compare fields: + // - parentId or siblingIndex changed → moved (reparent or + // reorder within same parent). + // - role, label, or stateFlags changed → updatedSemantic. The + // platform layer re-reads these to update screen reader properties. + // - bounds changed → updatedGeometry. The platform layer updates + // the hit-test region and visual position. + // A single node can appear in multiple diff arrays (e.g. both moved + // and updatedSemantic) if multiple aspects changed simultaneously. + // + // Iterate currentFlat (tree pre-order) so parents land in the added/ + // moved arrays before their children, and iteration is deterministic + // frame-to-frame. currentById/previousById are used for O(1) lookup. + for (const auto& currentNode : currentFlat) + { + auto previousIt = previousById.find(currentNode.id); + if (previousIt == previousById.end()) + { + diff.added.push_back(currentNode); + continue; + } + + const auto& previousNode = *previousIt->second; + + // Moved detection: parent changed (reparent) or sibling position + // changed (reorder within the same parent). + const bool moved = + previousNode.parentId != currentNode.parentId || + previousNode.siblingIndex != currentNode.siblingIndex; + if (moved) + { + diff.moved.push_back(currentNode); + } + + // Semantic content detection: any of role, label, stateFlags, or + // traitFlags changed. These affect how a screen reader + // announces the node (e.g. "button, selected" vs "button"). + if (previousNode.role != currentNode.role || + previousNode.label != currentNode.label || + previousNode.stateFlags != currentNode.stateFlags || + previousNode.traitFlags != currentNode.traitFlags) + { + diff.updatedSemantic.push_back(currentNode); + } + + // Geometry detection: bounds changed. Affects hit-test region and + // visual overlay positioning. + if (previousNode.minX != currentNode.minX || + previousNode.minY != currentNode.minY || + previousNode.maxX != currentNode.maxX || + previousNode.maxY != currentNode.maxY) + { + diff.updatedGeometry.push_back({currentNode.id, + currentNode.minX, + currentNode.minY, + currentNode.maxX, + currentNode.maxY}); + } + } + + // Children ordering updates. Parent ids are collected in currentFlat + // tree order, then appended with any parents that only exist in + // previousFlat. This gives a deterministic emission order matching how + // a consumer would walk the new tree. + std::vector orderedParents; + std::unordered_set seenParents; + orderedParents.reserve(currentChildrenByParent.size() + + previousChildrenByParent.size()); + seenParents.reserve(orderedParents.capacity()); + for (const auto& node : currentFlat) + { + if (seenParents.insert(node.parentId).second) + { + orderedParents.push_back(node.parentId); + } + } + for (const auto& node : previousFlat) + { + if (seenParents.insert(node.parentId).second) + { + orderedParents.push_back(node.parentId); + } + } + + for (const auto parentId : orderedParents) + { + auto currentIt = currentChildrenByParent.find(parentId); + auto previousIt = previousChildrenByParent.find(parentId); + std::vector empty; + const auto* currentChildren = currentIt == currentChildrenByParent.end() + ? &empty + : ¤tIt->second; + const auto* previousChildren = + previousIt == previousChildrenByParent.end() ? &empty + : &previousIt->second; + if (*currentChildren != *previousChildren) + { + SemanticsChildrenUpdate update; + update.parentId = parentId; + update.childIds = *currentChildren; + diff.childrenUpdated.push_back(std::move(update)); + } + } + + return diff; +} + +} // namespace + +// Recursively sorts each node's children by visual position so that the +// flatten traversal produces siblingIndex values matching screen-reader +// order (top-to-bottom, left-to-right). Nodes with empty/NaN bounds are +// sorted to the end, preserving their relative insertion order via +// stable_sort. +void SemanticManager::sortChildrenByVisualPosition( + std::vector>& nodes) +{ + if (nodes.size() > 1) + { + std::stable_sort( + nodes.begin(), + nodes.end(), + [](const rcp& a, const rcp& b) { + const auto ab = a->bounds(); + const auto bb = b->bounds(); + const bool aEmpty = ab.isEmptyOrNaN(); + const bool bEmpty = bb.isEmptyOrNaN(); + // Empty-bounds nodes sort after all valid-bounds nodes. + if (aEmpty != bEmpty) + { + return bEmpty; // a < b when b is empty and a is not + } + if (aEmpty) + { + return false; // both empty — preserve order + } + if (ab.minY != bb.minY) + { + return ab.minY < bb.minY; + } + return ab.minX < bb.minX; + }); + } + + for (auto& node : nodes) + { + sortChildrenByVisualPosition(node->mutableChildren()); + } +} + +// Marks a specific node dirty. The global m_dirt flag triggers refresh(); +// the per-node sets enable O(K) incremental patching. id == 0 is the +// uninitialized sentinel — we set global dirt but skip per-node. +void SemanticManager::markNodeDirty(uint32_t id, SemanticDirt dirt) +{ + markDirty(dirt); + if (id == 0) + { + return; + } + + if (enums::is_flag_set(dirt, SemanticDirt::Content)) + { + m_dirtyContentNodes.insert(id); + } + if (enums::is_flag_set(dirt, SemanticDirt::Bounds)) + { + m_dirtyBoundsNodes.insert(id); + } +} + +void SemanticManager::markBoundaryDirty(uint32_t boundaryNodeId) +{ + m_dirtyBoundaryIds.insert(boundaryNodeId); + markDirty(SemanticDirt::Bounds); +} + +// Re-read bounds for every node in the subtree rooted at `node`: +// boundary nodes get their artboard rect mapped through rootTransform, +// non-boundary nodes get their component's semanticBounds(). Each node +// whose bounds actually changed is inserted into m_dirtyBoundsNodes. +void SemanticManager::reconcileBoundsForSubtree(SemanticNode* node) +{ + if (node == nullptr) + { + return; + } + + if (node->isBoundaryNode()) + { + if (auto* ab = node->boundaryArtboard()) + { + const AABB newBounds = SemanticProvider::rootTransformAABB( + ab, + AABB::fromLTWH(0.0f, 0.0f, ab->width(), ab->height())); + if (newBounds != node->bounds()) + { + node->bounds(newBounds); + m_dirtyBoundsNodes.insert(node->id()); + } + } + } + else + { + auto* coreOwner = node->coreOwner(); + if (coreOwner != nullptr && coreOwner->is()) + { + auto* owner = coreOwner->as(); + const AABB liveBounds = SemanticProvider::semanticBounds(owner); + if (liveBounds != node->bounds()) + { + node->bounds(liveBounds); + m_dirtyBoundsNodes.insert(node->id()); + } + } + } + + for (const auto& child : node->children()) + { + reconcileBoundsForSubtree(child.get()); + } +} + +// Assign a manager-local id to this node, or reconcile the watermark +// for an explicitly-provided id so subsequent auto-assignments don't +// collide. Called from addChild() before the lookup map is updated. +void SemanticManager::ensureNodeId(SemanticNode& node) +{ + if (node.id() == 0) + { + // Fresh node: pick the next local id. Skip any id already in + // the map (can happen when an explicit id was preserved earlier + // with a value greater than our watermark). + while (m_nodesById.count(m_nextLocalId) != 0) + { + ++m_nextLocalId; + } + node.id(m_nextLocalId++); + return; + } + + // Explicit id: bump the watermark so future auto-assignments skip it. + if (node.id() >= m_nextLocalId) + { + m_nextLocalId = node.id() + 1; + } +} + +// Registers a SemanticNode in the tree. Appends the child to the +// parent's children (or roots). Assigns a manager-local id if the node +// was constructed without one. If the node's id collides with a +// *different* node already tracked by this manager (nodes migrating from +// another manager's id space), reassign it. +void SemanticManager::addChild(rcp parentNode, + rcp child) +{ + if (child == nullptr) + { + return; + } + + // Collision with a different node already tracked under this id — + // reassign the new node to a fresh manager-local id. + auto existing = m_nodesById.find(child->id()); + if (child->id() != 0 && existing != m_nodesById.end() && + existing->second != child) + { + child->id(0); + } + + ensureNodeId(*child); + + if (m_nodesById.find(child->id()) == m_nodesById.end()) + { + m_nodesById[child->id()] = child; + } + + child->manager(this); + + // Append to the end — refresh() sorts children by visual position + // (bounds) before every flatten. + if (parentNode != nullptr) + { + // Parent may have been created by a different artboard's + // buildSemanticTree and never inserted here directly. + if (m_nodesById.find(parentNode->id()) == m_nodesById.end()) + { + m_nodesById[parentNode->id()] = parentNode; + } + child->parent(parentNode.get()); + parentNode->mutableChildren().push_back(child); + } + else + { + child->parent(nullptr); + m_roots.push_back(child); + } + + markDirty(SemanticDirt::Structure); +} + +// Removes a SemanticNode from the tree. Unlinks from parent (or roots), +// clears the manager back-reference, removes from lookup map, and marks +// Structure dirty so the next refresh() emits a removal diff entry. +void SemanticManager::removeChild(rcp node) +{ + if (node == nullptr) + { + return; + } + + auto* parentNode = node->parent(); + if (parentNode != nullptr) + { + auto& siblings = parentNode->mutableChildren(); + siblings.erase(std::remove_if(siblings.begin(), + siblings.end(), + [&node](const rcp& child) { + return child.get() == node.get(); + }), + siblings.end()); + node->parent(nullptr); + } + else + { + m_roots.erase(std::remove_if(m_roots.begin(), + m_roots.end(), + [&node](const rcp& root) { + return root.get() == node.get(); + }), + m_roots.end()); + } + + node->manager(nullptr); + m_nodesById.erase(node->id()); + markDirty(SemanticDirt::Structure); +} + +// Incremental bounds patch for a single dirty node. Compares live bounds +// to the snapshot; if different, updates in-place and emits updatedGeometry. +void SemanticManager::patchBoundsNode(SemanticsDiffNode& entry, + SemanticsDiff& diff) +{ + auto nodeIt = m_nodesById.find(entry.id); + if (nodeIt == m_nodesById.end()) + { + return; + } + const auto b = nodeIt->second->bounds(); + + // Only emit an update if bounds actually changed. This avoids no-op + // diffs when a node is marked dirty but its bounds haven't moved + // (e.g. a text content change that doesn't affect layout). + if (entry.minX != b.minX || entry.minY != b.minY || entry.maxX != b.maxX || + entry.maxY != b.maxY) + { + entry.minX = b.minX; + entry.minY = b.minY; + entry.maxX = b.maxX; + entry.maxY = b.maxY; + diff.updatedGeometry.push_back( + {entry.id, entry.minX, entry.minY, entry.maxX, entry.maxY}); + } +} + +// Incremental content patch for a single dirty node. Compares role, label, +// stateFlags, and traitFlags to the snapshot; if different, updates in-place +// and emits updatedSemantic. This is how animation/data-binding changes to +// stateFlags (e.g. "Selected" toggling) propagate to the platform layer. +void SemanticManager::patchContentNode(SemanticsDiffNode& entry, + SemanticsDiff& diff) +{ + auto nodeIt = m_nodesById.find(entry.id); + if (nodeIt == m_nodesById.end()) + { + return; + } + const auto& node = nodeIt->second; + + // Use derived label if this node has one, otherwise the canonical label. + auto derivedIt = m_derivedLabels.find(entry.id); + const std::string& effectiveLabel = (derivedIt != m_derivedLabels.end()) + ? derivedIt->second + : node->label(); + + // Compare all semantic content fields. Even if only one changed, + // we update all fields to keep the snapshot consistent. + if (entry.role != node->role() || entry.label != effectiveLabel || + entry.value != node->value() || entry.hint != node->hint() || + entry.stateFlags != node->stateFlags() || + entry.traitFlags != node->traitFlags() || + entry.headingLevel != node->headingLevel()) + { + entry.role = node->role(); + entry.label = effectiveLabel; + entry.value = node->value(); + entry.hint = node->hint(); + entry.stateFlags = node->stateFlags(); + entry.traitFlags = node->traitFlags(); + entry.headingLevel = node->headingLevel(); + diff.updatedSemantic.push_back(entry); + } +} + +// Core refresh algorithm. Two paths: +// 1. FULL RE-FLATTEN (Structure dirty or first frame): O(N) in tree size. +// 2. INCREMENTAL PATCH (only Bounds/Content dirty): O(K) dirty nodes. +// Before diffing, reconciles live bounds and computes container bounds. +void SemanticManager::refresh() +{ + // Read the current dirt flags. + const bool structureDirty = + enums::is_flag_set(m_dirt, SemanticDirt::Structure); + bool boundsDirty = enums::is_flag_set(m_dirt, SemanticDirt::Bounds); + const bool contentDirty = enums::is_flag_set(m_dirt, SemanticDirt::Content); + + // ------------------------------------------------------------------------- + // Targeted bounds reconciliation via dirty boundary nodes. + // + // When a host artboard's transform changes, its boundary node is marked + // dirty via markBoundaryDirty(). We re-read bounds only for nodes under + // dirty boundaries — O(K_subtree) instead of O(N_all_nodes). + // ------------------------------------------------------------------------- + if (!m_dirtyBoundaryIds.empty()) + { + for (uint32_t boundaryId : m_dirtyBoundaryIds) + { + auto it = m_nodesById.find(boundaryId); + if (it != m_nodesById.end()) + { + reconcileBoundsForSubtree(it->second.get()); + } + } + m_dirtyBoundaryIds.clear(); + if (!m_dirtyBoundsNodes.empty()) + { + boundsDirty = true; + } + } + + // Early exit if nothing is dirty after reconciliation. + if (!structureDirty && !boundsDirty && !contentDirty) + { + return; + } + + // ------------------------------------------------------------------------- + // Visual-order check. + // + // Screen-reader traversal order is visual (top-to-bottom, left-to-right). + // If a node's bounds changed, its parent's children may have moved past + // each other and need re-sorting via the full re-flatten path. + // + // Only relevant on the incremental path: the full re-flatten always + // re-sorts children from scratch. Only checks at parents whose direct + // children actually had a bounds change — parents with no dirty child + // can't have reordered. + // ------------------------------------------------------------------------- + bool needsReorder = false; + if (boundsDirty && !structureDirty && !m_lastFlatSnapshot.empty()) + { + std::unordered_set parentsToCheck; + bool anyRootMoved = false; + + for (uint32_t id : m_dirtyBoundsNodes) + { + auto it = m_nodesById.find(id); + if (it == m_nodesById.end()) + { + continue; + } + SemanticNode* parent = it->second->parent(); + if (parent != nullptr) + { + parentsToCheck.insert(parent); + } + else + { + anyRootMoved = true; + } + } + + for (auto* parent : parentsToCheck) + { + if (parent->children().size() > 1 && + !childrenInVisualOrder(parent->children())) + { + needsReorder = true; + break; + } + } + if (!needsReorder && anyRootMoved && m_roots.size() > 1 && + !childrenInVisualOrder(m_roots)) + { + needsReorder = true; + } + } + + // ------------------------------------------------------------------------- + // Diff production — two paths depending on what kind of dirt is present. + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + // Check if any content-dirty node is an absorbed child from the last + // derivation pass. If so, the parent interactive node's derived label + // may be stale — escalate to a full re-flatten so derivation re-runs. + // ------------------------------------------------------------------------- + bool needsRederivation = false; + if (contentDirty && !m_excludedIds.empty()) + { + for (const auto& id : m_dirtyContentNodes) + { + if (m_excludedIds.count(id)) + { + needsRederivation = true; + break; + } + } + } + + if (structureDirty || needsRederivation || needsReorder || + m_lastFlatSnapshot.empty()) + { + // FULL RE-FLATTEN PATH. + // The tree topology changed (add/remove/reparent), an absorbed + // child's content changed (needs re-derivation), children moved + // past each other (needs re-sort), or this is the first frame. + // Walk the entire SemanticNode tree to produce a new flat snapshot, + // then diff it against the previous snapshot. + // + // Step 1: Sort children by visual position (bounds) — only needed + // when topology or ordering changed, not for rederivation. + // Step 2: Derive labels for interactive nodes and build exclude set. + // Step 3: Flatten with derivation applied. + // Step 4: Diff against previous snapshot. + if (structureDirty || needsReorder || m_lastFlatSnapshot.empty()) + { + sortChildrenByVisualPosition(m_roots); + } + + m_derivedLabels.clear(); + m_excludedIds.clear(); + deriveLabelForInteractiveNodes(m_roots, m_derivedLabels, m_excludedIds); + + auto currentFlat = flattenFromSemanticNodes(m_roots, + m_nodesById.size(), + m_excludedIds, + m_derivedLabels); + auto nextDiff = + buildDiffFromFlats(currentFlat, m_lastFlatSnapshot, m_version + 1); + if (!nextDiff.empty()) + { + m_version++; + m_lastDiff = std::move(nextDiff); + m_lastFlatSnapshot = std::move(currentFlat); + } + } + else + { + // INCREMENTAL PATCH PATH. + // Only bounds and/or content changed — no structural changes. + // Iterate m_lastFlatSnapshot, which is already in tree pre-order; + // for each entry whose id is in the bounds- or content-dirty set, + // patch the entry in place and emit a diff record. Iterating the + // dirty sets directly would emit in hash-bucket order, which does + // not track tree structure; consumers expect diff records in tree + // pre-order, so the snapshot drives iteration and the sets are + // used only for O(1) membership checks. + // + // This path skips the structural tree walk, child re-sort, label + // re-derivation, and flat-vs-flat comparison that the full + // re-flatten path performs. + SemanticsDiff nextDiff; + nextDiff.frameNumber = Artboard::frameId(); + + if (boundsDirty || contentDirty) + { + if (boundsDirty) + { + nextDiff.updatedGeometry.reserve(m_dirtyBoundsNodes.size()); + } + if (contentDirty) + { + nextDiff.updatedSemantic.reserve(m_dirtyContentNodes.size()); + } + + for (auto& entry : m_lastFlatSnapshot) + { + if (boundsDirty && m_dirtyBoundsNodes.count(entry.id)) + { + patchBoundsNode(entry, nextDiff); + } + if (contentDirty && m_dirtyContentNodes.count(entry.id)) + { + patchContentNode(entry, nextDiff); + } + } + } + + // Single-root optimization for the incremental path. + if (m_roots.size() == 1) + { + nextDiff.rootId = m_roots[0]->id(); + } + + // Only bump version and store the diff if something actually changed. + // The patchBounds/patchContent methods guard against no-op updates, + // so nextDiff can be empty even when dirty flags were set. + if (!nextDiff.empty()) + { + m_version++; + nextDiff.treeVersion = m_version; + m_lastDiff = std::move(nextDiff); + } + } + + // Clear all dirt flags and per-node dirty sets for the next frame. + m_dirt = SemanticDirt::None; + m_dirtyContentNodes.clear(); + m_dirtyBoundsNodes.clear(); +} + +SemanticsDiff SemanticManager::drainDiff() +{ + refresh(); + return consumeDiff(); +} + +// Returns the diff produced by the most recent refresh() and clears it. +// Subsequent calls return an empty diff until the next dirty refresh. +// +// The move + replace pattern ensures the caller gets ownership of the diff +// data and the manager's internal storage is reset to empty. +SemanticsDiff SemanticManager::consumeDiff() +{ + SemanticsDiff result = std::move(m_lastDiff); + m_lastDiff = SemanticsDiff(); + return result; +} + +bool SemanticManager::requestFocus(uint32_t semanticNodeId) +{ + auto* semanticNode = nodeById(semanticNodeId); + if (semanticNode == nullptr) + { + return false; + } + auto* data = semanticNode->semanticData(); + return data != nullptr && data->requestFocus(); +} diff --git a/thirdparty/rive/source/semantic/semantic_provider.cpp b/thirdparty/rive/source/semantic/semantic_provider.cpp new file mode 100644 index 000000000..6bee14755 --- /dev/null +++ b/thirdparty/rive/source/semantic/semantic_provider.cpp @@ -0,0 +1,148 @@ +#include "rive/semantic/semantic_provider.hpp" + +#include "rive/artboard.hpp" +#include "rive/component.hpp" +#include "rive/container_component.hpp" +#include "rive/math/mat2d.hpp" +#include "rive/node.hpp" +#include "rive/semantic/semantic_data.hpp" +#include "semantic_inference_registry.hpp" + +using namespace rive; + +static bool tryNodeWorldBounds(Node* node, AABB& outBounds) +{ + if (node == nullptr) + { + return false; + } + + const auto localBounds = node->localBounds(); + if (localBounds.isEmptyOrNaN()) + { + return false; + } + const auto worldTransform = node->worldTransform(); + const auto worldBounds = worldTransform.mapBoundingBox(localBounds); + if (worldBounds.isEmptyOrNaN()) + { + return false; + } + outBounds = worldBounds; + return true; +} + +AABB SemanticProvider::rootTransformAABB(Artboard* ab, const AABB& bounds) +{ + AABB out = AABB::forExpansion(); + AABB::expandTo(out, ab->rootTransform({bounds.minX, bounds.minY})); + AABB::expandTo(out, ab->rootTransform({bounds.maxX, bounds.minY})); + AABB::expandTo(out, ab->rootTransform({bounds.maxX, bounds.maxY})); + AABB::expandTo(out, ab->rootTransform({bounds.minX, bounds.maxY})); + return out; +} + +bool SemanticProvider::canInferSemantics(Component* component) +{ + return supportsInferredSemantics(component); +} + +ResolvedSemanticData SemanticProvider::resolveSemanticData(Component* component) +{ + ResolvedSemanticData out; + if (component == nullptr || !component->is()) + { + return out; + } + + if (auto* sd = component->as()->firstChild()) + { + out.hasSemantics = true; + out.role = sd->role(); + out.label = sd->label(); + return out; + } + + // Inference fallback (Text -> label) + resolveInferredSemantics(component, out); + + return out; +} + +// Computes world-space bounds for a component. Three strategies: +// 1. Drawable nodes: localBounds() → worldTransform → rootTransform +// 2. Container nodes: merge bounds of all direct Node children +// 3. Fallback: world transform translation (degenerate point bounds) +AABB SemanticProvider::semanticBounds(Component* component) +{ + if (component == nullptr || !component->is()) + { + return AABB(); + } + + auto* node = component->as(); + + AABB worldBounds; + if (tryNodeWorldBounds(node, worldBounds)) + { + auto* ab = node->artboard(); + if (ab != nullptr) + { + return rootTransformAABB(ab, worldBounds); + } + return worldBounds; + } + + // If this semantic node is a non-drawable container/group, derive bounds + // from visual descendant nodes. ContainerComponent::forEachChild walks + // the whole subtree (not just direct children): the predicate runs for + // each descendant, and returning `true` tells forEachChild to keep + // descending into that descendant's children. We always return true so + // every Node descendant contributes bounds; non-Node descendants and + // Nodes without valid bounds are skipped but their subtrees are still + // walked. + if (component->is()) + { + AABB merged = AABB::forExpansion(); + bool hasDescendantBounds = false; + component->as()->forEachChild( + [&](Component* child) -> bool { + if (child == nullptr || !child->is()) + { + return true; + } + + AABB childBounds; + if (!tryNodeWorldBounds(child->as(), childBounds)) + { + return true; + } + + merged.expand(childBounds); + hasDescendantBounds = true; + return true; + }); + + if (hasDescendantBounds) + { + auto* ab = node->artboard(); + if (ab != nullptr) + { + return rootTransformAABB(ab, merged); + } + return merged; + } + } + + // Fallback for nodes/components without local bounds. + const auto worldTransform = node->worldTransform(); + const float x = worldTransform[4]; + const float y = worldTransform[5]; + auto* ab = node->artboard(); + if (ab != nullptr) + { + Vec2D pos = ab->rootTransform(Vec2D(x, y)); + return AABB(pos.x, pos.y, pos.x, pos.y); + } + return AABB(x, y, x, y); +} diff --git a/thirdparty/rive/source/shapes/clipping_shape.cpp b/thirdparty/rive/source/shapes/clipping_shape.cpp index 4d029d87a..413cb7cd7 100644 --- a/thirdparty/rive/source/shapes/clipping_shape.cpp +++ b/thirdparty/rive/source/shapes/clipping_shape.cpp @@ -9,51 +9,111 @@ using namespace rive; -StatusCode ClippingShape::onAddedClean(CoreContext* context) +void ClippingShapeStart::draw(Renderer* renderer, bool needsSaveOperation) { - auto clippingHolder = parent(); + if (!m_clippingShape->isVisible()) + { + return; + } + if (needsSaveOperation) + { - auto artboard = static_cast(context); - for (auto core : artboard->objects()) + renderer->save(); + } + if (m_clippingShape) { - if (core == nullptr) + ShapePaintPath* path = m_clippingShape->path(); + if (!path) { - continue; + return; } - // Iterate artboard to find drawables that are parented to this clipping - // shape, they need to know they'll be clipped by this shape. - if (core->is()) + RenderPath* renderPath = path->renderPath(m_clippingShape); + renderer->clipPath(renderPath); + } +} + +int ClippingShapeStart::emptyClipCount() +{ + if (m_clippingShape && m_clippingShape->isVisible()) + { + ShapePaintPath* path = m_clippingShape->path(); + if (!path) { - auto drawable = core->as(); - for (ContainerComponent* component = drawable; component != nullptr; - component = component->parent()) - { - if (component == clippingHolder) - { - drawable->addClippingShape(this); - break; - } - } + return 1; } + } + return 0; +} - // Iterate artboard to find shapes that are parented to the source, - // their paths will need to be RenderPaths in order to be used for - // clipping operations. - if (core->is()) +bool ClippingShapeStart::isVisible() +{ + if (m_clippingShape) + { + return m_clippingShape->isVisible(); + } + return false; +} + +int ClippingShapeEnd::emptyClipCount() +{ + if (m_clippingShape && m_clippingShape->isVisible()) + { + ShapePaintPath* path = m_clippingShape->path(); + if (!path) { - auto component = core->as(); - while (component != nullptr) + return -1; + } + } + return 0; +} + +void ClippingShapeEnd::draw(Renderer* renderer, bool needsSaveOperation) +{ + if (!m_clippingShape->isVisible() || !needsSaveOperation) + { + return; + } + renderer->restore(); +} + +ClippingShape::~ClippingShape() +{ + for (auto& proxy : m_proxyDrawables) + { + delete proxy; + } + for (auto& proxy : m_pooledProxyDrawables) + { + delete proxy; + } +} + +StatusCode ClippingShape::onAddedClean(CoreContext* context) +{ + // Find drawables parented (directly or transitively) to this clipping + // shape's parent; they need to know they'll be clipped by this shape. + parent()->forAll([this](Component* component) -> bool { + if (component->is()) + { + component->as()->addClippingShape(this); + } + return true; + }); + + // Find shapes parented (directly or transitively) to the source node; + // their paths will need to be RenderPaths in order to be used for + // clipping operations. + if (m_Source) + { + m_Source->forAll([this](Component* component) -> bool { + if (component->is()) { - if (component == m_Source) - { - auto shape = core->as(); - shape->addFlags(PathFlags::world | PathFlags::clipping); - m_Shapes.push_back(shape); - break; - } - component = component->parent(); + auto shape = component->as(); + shape->addFlags(PathFlags::world | PathFlags::clipping); + m_Shapes.push_back(shape); } - } + return true; + }); } return StatusCode::Ok; @@ -83,12 +143,13 @@ void ClippingShape::buildDependencies() { shape->pathComposer()->addDependent(this); } + clipStart.clippingShape(this); + clipEnd.clippingShape(this); } +static Mat2D identity; void ClippingShape::update(ComponentDirt value) { - static Mat2D identity; - if (hasDirt(value, ComponentDirt::Path | ComponentDirt::WorldTransform | ComponentDirt::NSlicer)) @@ -110,3 +171,8 @@ void ClippingShape::update(ComponentDirt value) } } } + +void ClippingShape::isVisibleChanged() +{ + artboard()->addDirt(ComponentDirt::Clipping); +} \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/image.cpp b/thirdparty/rive/source/shapes/image.cpp index f2836a747..6e53c7839 100644 --- a/thirdparty/rive/source/shapes/image.cpp +++ b/thirdparty/rive/source/shapes/image.cpp @@ -4,6 +4,7 @@ #include "rive/importers/backboard_importer.hpp" #include "rive/assets/file_asset.hpp" #include "rive/assets/image_asset.hpp" +#include "rive/layout.hpp" #include "rive/layout/n_slicer.hpp" #include "rive/shapes/mesh_drawable.hpp" #include "rive/artboard.hpp" @@ -13,54 +14,52 @@ using namespace rive; void Image::draw(Renderer* renderer) { + rive::ImageAsset* asset = this->imageAsset(); - if (asset == nullptr || renderOpacity() == 0.0f) - { - return; - } rive::RenderImage* renderImage = asset->renderImage(); if (renderImage == nullptr) { return; } - - ClipResult clipResult = applyClip(renderer); - - if (clipResult == ClipResult::noClip) + if (m_needsSaveOperation) { - // We didn't clip, so make sure to save as we'll be doing some - // transformations. + renderer->save(); } - if (clipResult != ClipResult::emptyClip) - { - float width = (float)renderImage->width(); - float height = (float)renderImage->height(); + float width = (float)renderImage->width(); + float height = (float)renderImage->height(); - // until image loading and saving is done, use default sampling for - // image assets - if (m_Mesh != nullptr) - { - m_Mesh->draw(renderer, - renderImage, - rive::ImageSampler::LinearClamp(), - blendMode(), - renderOpacity()); - } - else - { - renderer->transform(worldTransform()); - renderer->translate(-width * originX(), -height * originY()); - renderer->drawImage(renderImage, - rive::ImageSampler::LinearClamp(), - blendMode(), - renderOpacity()); - } + // until image loading and saving is done, use default sampling for + // image assets + if (m_Mesh != nullptr) + { + m_Mesh->draw(renderer, + renderImage, + rive::ImageSampler::LinearClamp(), + blendMode(), + renderOpacity()); + } + else + { + renderer->transform(worldTransform()); + renderer->translate(-width * originX(), -height * originY()); + renderer->drawImage(renderImage, + rive::ImageSampler::LinearClamp(), + blendMode(), + renderOpacity()); + } + if (m_needsSaveOperation) + { + renderer->restore(); } +} - renderer->restore(); +bool Image::willDraw() +{ + return Super::willDraw() && renderOpacity() != 0.0f && + this->imageAsset() != nullptr; } Core* Image::hitTest(HitInfo* hinfo, const Mat2D& xform) @@ -105,9 +104,9 @@ StatusCode Image::import(ImportStack& importStack) // getAssetId...) uint32_t Image::assetId() { return ImageBase::assetId(); } -void Image::setAsset(FileAsset* asset) +void Image::setAsset(rcp asset) { - if (asset->is()) + if (asset != nullptr && asset->is()) { FileAssetReferencer::setAsset(asset); @@ -137,7 +136,15 @@ Core* Image::clone() const return twin; } -void Image::setMesh(MeshDrawable* mesh) { m_Mesh = mesh; } +void Image::setMesh(MeshDrawable* mesh) +{ + if (m_Mesh == mesh) + { + return; + } + m_Mesh = mesh; + updateImageScale(); +} float Image::width() const { @@ -150,7 +157,7 @@ float Image::width() const rive::RenderImage* renderImage = asset->renderImage(); if (renderImage == nullptr) { - return 0.0f; + return asset->width(); } return (float)renderImage->width(); } @@ -166,7 +173,7 @@ float Image::height() const rive::RenderImage* renderImage = asset->renderImage(); if (renderImage == nullptr) { - return 0.0f; + return asset->height(); } return (float)renderImage->height(); } @@ -220,29 +227,135 @@ void Image::controlSize(Vec2D size, } } +void Image::updateTransform() +{ + Super::updateTransform(); + m_Transform[4] += m_layoutOffsetX; + m_Transform[5] += m_layoutOffsetY; +} + void Image::updateImageScale() { - // User-created meshes are not affected by scale - if ((m_Mesh != nullptr && m_Mesh->type() == MeshType::vertex) || - imageAsset() == nullptr) + if (imageAsset() == nullptr) { + if (m_layoutOffsetX != 0.0f || m_layoutOffsetY != 0.0f) + { + m_layoutOffsetX = 0.0f; + m_layoutOffsetY = 0.0f; + markTransformDirty(); + } return; } + + float newOffsetX = 0.0f; + float newOffsetY = 0.0f; auto renderImage = imageAsset()->renderImage(); if (renderImage != nullptr && !std::isnan(m_layoutWidth) && !std::isnan(m_layoutHeight)) { - float newScaleX = m_layoutWidth / (float)renderImage->width(); - float newScaleY = m_layoutHeight / (float)renderImage->height(); + float imgW = (float)renderImage->width(); + float imgH = (float)renderImage->height(); + float newScaleX, newScaleY; + auto imageFit = static_cast(fit()); + switch (imageFit) + { + case Fit::fill: + newScaleX = m_layoutWidth / imgW; + newScaleY = m_layoutHeight / imgH; + break; + case Fit::contain: + { + float s = + std::fmin(m_layoutWidth / imgW, m_layoutHeight / imgH); + newScaleX = newScaleY = s; + break; + } + case Fit::cover: + { + float s = + std::fmax(m_layoutWidth / imgW, m_layoutHeight / imgH); + newScaleX = newScaleY = s; + break; + } + case Fit::fitWidth: + newScaleX = newScaleY = m_layoutWidth / imgW; + break; + case Fit::fitHeight: + newScaleX = newScaleY = m_layoutHeight / imgH; + break; + case Fit::none: + newScaleX = newScaleY = 1.0f; + break; + case Fit::scaleDown: + { + float s = + std::fmin(m_layoutWidth / imgW, m_layoutHeight / imgH); + s = s < 1.0f ? s : 1.0f; + newScaleX = newScaleY = s; + break; + } + case Fit::layout: + default: + newScaleX = m_layoutWidth / imgW; + newScaleY = m_layoutHeight / imgH; + break; + } + + // Compatibility: legacy files assume fill does not apply fit/alignment + // translation offsets, only scale. + if (imageFit != Fit::fill) + { + float boundsW = imgW; + float boundsH = imgH; + float boundsLeft = -imgW * originX(); + float boundsTop = -imgH * originY(); + if (m_Mesh != nullptr && m_Mesh->type() == MeshType::vertex) + { + // Keep fit behavior stable while editing vertex meshes. + boundsLeft = -imgW * 0.5f; + boundsTop = -imgH * 0.5f; + } + Alignment alignment(alignmentX(), alignmentY()); + float xAlign = (alignment.x() + 1.0f) * 0.5f; + float yAlign = (alignment.y() + 1.0f) * 0.5f; + float scaledLeft = boundsLeft * newScaleX; + float scaledTop = boundsTop * newScaleY; + float widthRemainder = m_layoutWidth - (boundsW * newScaleX); + float heightRemainder = m_layoutHeight - (boundsH * newScaleY); + newOffsetX = -scaledLeft + widthRemainder * xAlign; + newOffsetY = -scaledTop + heightRemainder * yAlign; + } + if (newScaleX != scaleX() || newScaleY != scaleY()) { scaleX(newScaleX); scaleY(newScaleY); - addDirt(ComponentDirt::WorldTransform, false); } } + if (newOffsetX != m_layoutOffsetX || newOffsetY != m_layoutOffsetY) + { + m_layoutOffsetX = newOffsetX; + m_layoutOffsetY = newOffsetY; + // Offset is applied in updateTransform(), so changing it must mark the + // local transform dirty (not just world transform). + markTransformDirty(); + } } +AABB Image::localBounds() const +{ + if (imageAsset() == nullptr) + { + return AABB(); + } + return AABB::fromLTWH(-width() * originX(), + -height() * originY(), + width(), + height()); +} + +ImageAsset* Image::imageAsset() const { return (ImageAsset*)m_fileAsset.get(); } + #ifdef TESTING #include "rive/shapes/mesh.hpp" Mesh* Image::mesh() const { return static_cast(m_Mesh); }; diff --git a/thirdparty/rive/source/shapes/list_path.cpp b/thirdparty/rive/source/shapes/list_path.cpp new file mode 100644 index 000000000..3186d29d9 --- /dev/null +++ b/thirdparty/rive/source/shapes/list_path.cpp @@ -0,0 +1,324 @@ +#include "rive/shapes/list_path.hpp" +#include "rive/math/math_types.hpp" +#include "rive/artboard.hpp" +#include "rive/shapes/cubic_detached_vertex.hpp" +#include "rive/shapes/straight_vertex.hpp" +#include "rive/shapes/vertex.hpp" +#include "rive/shapes/path_vertex.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/symbol_type.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +VertexListener::VertexListener(Vertex* vertex, + rcp instance, + Path* path) : + CoreObjectListener(vertex, instance), m_path(path) +{ + createProperties(); +} + +void VertexListener::createProperties() +{ + CoreObjectListener::createProperties(); + createPropertyListener(SymbolType::vertexX); + createPropertyListener(SymbolType::vertexY); + createPropertyListener(SymbolType::rotation); + createPropertyListener(SymbolType::inRotation); + createPropertyListener(SymbolType::outRotation); + createPropertyListener(SymbolType::distance); + createPropertyListener(SymbolType::inDistance); + createPropertyListener(SymbolType::outDistance); + createInPointPropertyListener(); + createOutPointPropertyListener(); +} + +PropertySymbolDependent* VertexListener::createSinglePropertyListener( + SymbolType symbolType) +{ + uint16_t propertyKey = 0; + float multiplier = 1.0f; + switch (symbolType) + { + case SymbolType::vertexX: + propertyKey = VertexBase::xPropertyKey; + break; + case SymbolType::vertexY: + propertyKey = VertexBase::yPropertyKey; + break; + case SymbolType::inRotation: + propertyKey = CubicDetachedVertexBase::inRotationPropertyKey; + multiplier = math::PI / 180.0f; + break; + case SymbolType::outRotation: + propertyKey = CubicDetachedVertexBase::outRotationPropertyKey; + multiplier = math::PI / 180.0f; + break; + case SymbolType::inDistance: + propertyKey = CubicDetachedVertexBase::inDistancePropertyKey; + break; + case SymbolType::outDistance: + propertyKey = CubicDetachedVertexBase::outDistancePropertyKey; + break; + default: + break; + } + + auto prop = m_instance->propertyValue(symbolType); + if (prop != nullptr && prop->is()) + { + auto vpl = new VertexPropertyListenerSingle(m_core, + this, + prop, + propertyKey, + multiplier); + return vpl; + } + return nullptr; +} + +PropertySymbolDependent* VertexListener::createDistancePropertyListener() +{ + + auto prop = m_instance->propertyValue(SymbolType::distance); + if (prop != nullptr && prop->is()) + { + std::vector keys = {}; + auto inPropKey = CubicDetachedVertexBase::inDistancePropertyKey; + keys.push_back(inPropKey); + auto outPropKey = CubicDetachedVertexBase::outDistancePropertyKey; + keys.push_back(outPropKey); + auto vpl = + new VertexPropertyListenerMulti(m_core, this, prop, keys, 1.0f); + return vpl; + } + return nullptr; +} + +PropertySymbolDependent* VertexListener::createRotationPropertyListener() +{ + + auto prop = m_instance->propertyValue(SymbolType::rotation); + if (prop != nullptr && prop->is()) + { + std::vector keys = {}; + auto inPropKey = CubicDetachedVertexBase::inRotationPropertyKey; + keys.push_back(inPropKey); + auto outPropKey = CubicDetachedVertexBase::outRotationPropertyKey; + keys.push_back(outPropKey); + auto vpl = new VertexPropertyListenerMulti(m_core, + this, + prop, + keys, + math::PI / 180.0f); + return vpl; + } + return nullptr; +} + +void VertexListener::createInPointPropertyListener() +{ + auto xProp = m_instance->propertyValue(SymbolType::cubicVertexInPointX); + auto yProp = m_instance->propertyValue(SymbolType::cubicVertexInPointY); + if ((xProp != nullptr && xProp->is()) || + (yProp != nullptr && yProp->is())) + { + auto vpl = new VertexPropertyListenerPoint( + m_core, + this, + xProp, + yProp, + CubicDetachedVertexBase::inDistancePropertyKey, + CubicDetachedVertexBase::inRotationPropertyKey); + + vpl->writeValue(); + m_properties.push_back(vpl); + } +} + +void VertexListener::createOutPointPropertyListener() +{ + auto xProp = m_instance->propertyValue(SymbolType::cubicVertexOutPointX); + auto yProp = m_instance->propertyValue(SymbolType::cubicVertexOutPointY); + if ((xProp != nullptr && xProp->is()) || + (yProp != nullptr && yProp->is())) + { + auto vpl = new VertexPropertyListenerPoint( + m_core, + this, + xProp, + yProp, + CubicDetachedVertexBase::outDistancePropertyKey, + CubicDetachedVertexBase::outRotationPropertyKey); + + vpl->writeValue(); + m_properties.push_back(vpl); + } +} + +void VertexListener::createPropertyListener(SymbolType symbolType) +{ + PropertySymbolDependent* listener = nullptr; + switch (symbolType) + { + case SymbolType::vertexX: + case SymbolType::vertexY: + case SymbolType::inRotation: + case SymbolType::outRotation: + case SymbolType::inDistance: + case SymbolType::outDistance: + listener = createSinglePropertyListener(symbolType); + break; + case SymbolType::distance: + listener = createDistancePropertyListener(); + break; + case SymbolType::rotation: + listener = createRotationPropertyListener(); + break; + default: + break; + } + if (listener != nullptr) + { + listener->writeValue(); + m_properties.push_back(listener); + } +} + +VertexPropertyListenerSingle::VertexPropertyListenerSingle( + Core* vertex, + VertexListener* vertexListener, + ViewModelInstanceValue* instanceValue, + uint16_t propertyKey, + float multiplier) : + PropertySymbolDependentSingle(vertex, + vertexListener, + instanceValue, + propertyKey), + m_multiplier(multiplier) +{} + +void VertexPropertyListenerSingle::writeValue() +{ + CoreRegistry::setDouble( + m_coreObject, + m_propertyKey, + m_instanceValue->as()->propertyValue() * + m_multiplier); +} + +VertexPropertyListenerMulti::VertexPropertyListenerMulti( + Core* vertex, + VertexListener* vertexListener, + ViewModelInstanceValue* instanceValue, + std::vector propertyKeys, + float multiplier) : + PropertySymbolDependentMulti(vertex, + vertexListener, + instanceValue, + propertyKeys), + m_multiplier(multiplier) +{} + +void VertexPropertyListenerMulti::writeValue() +{ + for (auto& key : m_propertyKeys) + { + CoreRegistry::setDouble( + m_coreObject, + key, + m_instanceValue->as()->propertyValue() * + m_multiplier); + } +} + +VertexPropertyListenerPoint::VertexPropertyListenerPoint( + Core* vertex, + VertexListener* vertexListener, + ViewModelInstanceValue* xValue, + ViewModelInstanceValue* yValue, + uint16_t distKey, + uint16_t rotKey) : + PropertySymbolDependent(vertex, vertexListener, xValue), + m_yValue(yValue), + m_distKey(distKey), + m_rotKey(rotKey) +{ + if (m_yValue) + { + m_yValue->addDependent(this); + } +} + +VertexPropertyListenerPoint::~VertexPropertyListenerPoint() +{ + if (m_yValue) + { + m_yValue->removeDependent(this); + } +} + +void VertexPropertyListenerPoint::writeValue() +{ + auto x = + m_instanceValue + ? m_instanceValue->as()->propertyValue() + : 0; + auto y = + m_yValue ? m_yValue->as()->propertyValue() : 0; + auto vec = Vec2D(x, y); + auto length = vec.length(); + auto rotation = std::atan2(vec.y, vec.x); + CoreRegistry::setDouble(m_coreObject, m_distKey, length); + CoreRegistry::setDouble(m_coreObject, m_rotKey, rotation); +} + +ListPath::~ListPath() +{ + for (auto& vertex : m_vertexListeners) + { + delete vertex; + } +} + +void ListPath::updateList(std::vector>* list) +{ + auto currentVertexSize = m_vertexListeners.size(); + size_t index = 0; + for (auto& listItem : *list) + { + auto instance = listItem->viewModelInstance(); + if (instance != nullptr) + { + if (index >= currentVertexSize) + { + // We treat all vertices as CubicDetached vertices because all + // others can be expressed by this one. There doesn't seem to be + // significant performance implications of doing so. But in the + // future it might be valuable to be smarter and build the + // corresponding one. + auto vertex = new CubicDetachedVertex(); + auto vertexListener = + new VertexListener(vertex, instance, this); + m_vertexListeners.push_back(vertexListener); + addVertex(vertex); + } + else + { + auto vertexListener = m_vertexListeners[index]; + vertexListener->remap(instance); + } + index++; + } + } + while (m_vertexListeners.size() > index) + { + auto vertex = m_vertexListeners.back(); + m_vertexListeners.pop_back(); + popVertex(); + delete vertex; + } + markPathDirty(); +} \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/mesh.cpp b/thirdparty/rive/source/shapes/mesh.cpp index bade4916c..633704bd2 100644 --- a/thirdparty/rive/source/shapes/mesh.cpp +++ b/thirdparty/rive/source/shapes/mesh.cpp @@ -114,16 +114,19 @@ void Mesh::onAssetLoaded(RenderImage* renderImage) factory->makeRenderBuffer(RenderBufferType::vertex, RenderBufferFlags::mappedOnceAtInitialization, m_Vertices.size() * sizeof(Vec2D)); - if (m_UVRenderBuffer) + if (m_UVRenderBuffer != nullptr) { float* uv = static_cast(m_UVRenderBuffer->map()); - for (auto vertex : m_Vertices) + if (uv != nullptr) { - Vec2D xformedUV = uvTransform * Vec2D(vertex->u(), vertex->v()); - *uv++ = xformedUV.x; - *uv++ = xformedUV.y; + for (auto vertex : m_Vertices) + { + Vec2D xformedUV = uvTransform * Vec2D(vertex->u(), vertex->v()); + *uv++ = xformedUV.x; + *uv++ = xformedUV.y; + } + m_UVRenderBuffer->unmap(); } - m_UVRenderBuffer->unmap(); } if (m_IndexBuffer != nullptr) @@ -135,10 +138,13 @@ void Mesh::onAssetLoaded(RenderImage* renderImage) if (m_IndexRenderBuffer) { void* indexData = m_IndexRenderBuffer->map(); - memcpy(indexData, - m_IndexBuffer->data(), - m_IndexRenderBuffer->sizeInBytes()); - m_IndexRenderBuffer->unmap(); + if (indexData != nullptr) + { + memcpy(indexData, + m_IndexBuffer->data(), + m_IndexRenderBuffer->sizeInBytes()); + m_IndexRenderBuffer->unmap(); + } } } } @@ -176,11 +182,15 @@ void Mesh::draw(Renderer* renderer, { Vec2D* mappedVertices = reinterpret_cast(m_VertexRenderBuffer->map()); - for (auto vertex : m_Vertices) + if (mappedVertices != nullptr) { - *mappedVertices++ = vertex->renderTranslation(); + for (auto vertex : m_Vertices) + { + *mappedVertices++ = vertex->renderTranslation(); + } + m_VertexRenderBuffer->unmap(); } - m_VertexRenderBuffer->unmap(); + m_VertexRenderBufferDirty = false; } diff --git a/thirdparty/rive/source/shapes/paint/color.cpp b/thirdparty/rive/source/shapes/paint/color.cpp index 7712f4ec8..15113dd0b 100644 --- a/thirdparty/rive/source/shapes/paint/color.cpp +++ b/thirdparty/rive/source/shapes/paint/color.cpp @@ -45,7 +45,7 @@ void UnpackColorToRGBA32FPremul(ColorInt color, float out[4]) float colorOpacity(ColorInt value) { return (float)colorAlpha(value) / 0xFF; } -static uint8_t opacityToAlpha(float opacity) +uint8_t opacityToAlpha(float opacity) { return (uint8_t)std::lround(255.f * std::max(0.0f, std::min(1.0f, opacity))); diff --git a/thirdparty/rive/source/shapes/paint/dash.cpp b/thirdparty/rive/source/shapes/paint/dash.cpp index de06f39eb..79515eec4 100644 --- a/thirdparty/rive/source/shapes/paint/dash.cpp +++ b/thirdparty/rive/source/shapes/paint/dash.cpp @@ -11,13 +11,17 @@ Dash::Dash(float value, bool percentage) lengthIsPercentage(percentage); } -float Dash::normalizedLength(float contourLength) const +float Dash::normalizedLength(float contourLength, bool wraps) const { - float right = lengthIsPercentage() ? 1.0f : contourLength; - float p = fmodf(length(), right); - if (p < 0.0f) + float p = length(); + if (wraps) { - p += right; + float right = lengthIsPercentage() ? 1.0f : contourLength; + p = fmodf(length(), right); + if (p < 0.0f) + { + p += right; + } } return lengthIsPercentage() ? p * contourLength : p; } diff --git a/thirdparty/rive/source/shapes/paint/dash_path.cpp b/thirdparty/rive/source/shapes/paint/dash_path.cpp index ffe744464..b0f2d650f 100644 --- a/thirdparty/rive/source/shapes/paint/dash_path.cpp +++ b/thirdparty/rive/source/shapes/paint/dash_path.cpp @@ -1,136 +1,113 @@ #include "rive/shapes/paint/dash_path.hpp" #include "rive/shapes/paint/dash.hpp" #include "rive/shapes/paint/stroke.hpp" +#include "rive/math/path_measure.hpp" #include "rive/factory.hpp" using namespace rive; -void PathDasher::invalidateSourcePath() +void DashEffectPath::invalidateEffect() { m_path.rewind(); } + +void DashEffectPath::createPathMeasure(const RawPath* source) { - m_contours.clear(); - invalidateDash(); + m_pathMeasure = PathMeasure(source); } -void PathDasher::invalidateDash() { m_path.rewind(); } +void PathDasher::invalidateDash() {} -ShapePaintPath* PathDasher::dash(const RawPath* source, +ShapePaintPath* PathDasher::dash(ShapePaintPath* destination, + const RawPath* source, + PathMeasure* pathMeasure, Dash* offset, Span dashes) { - if (m_path.hasRenderPath()) + if (destination->hasRenderPath()) { // Previous result hasn't been invalidated, it's still good. - return &m_path; + return destination; } - m_path.rewind(); - return applyDash(source, offset, dashes); + destination->rewind(); + return applyDash(destination, source, pathMeasure, offset, dashes); } -ShapePaintPath* PathDasher::applyDash(const RawPath* source, +ShapePaintPath* PathDasher::applyDash(ShapePaintPath* destination, + const RawPath* source, + PathMeasure* pathMeasure, Dash* offset, Span dashes) { - if (m_contours.empty()) - { - // 0.5f / 8.0f is a value that seems to look good on dashes with small - // gaps and scaled - ContourMeasureIter iter(source, 0.0625f); - while (auto meas = iter.next()) - { - m_contours.push_back(meas); - } - } - // Make sure dashes have some length. bool hasValidDash = false; - for (const rcp& contour : m_contours) + for (auto dash : dashes) { - for (auto dash : dashes) - { - if (dash->normalizedLength(contour->length()) > 0.0f) - { - hasValidDash = true; - break; - } - } - if (hasValidDash) + if (dash->normalizedLength(pathMeasure->length(), false) > 0.0f) { + hasValidDash = true; break; } } if (hasValidDash) { int dashIndex = 0; - auto rawPath = m_path.mutableRawPath(); - for (const rcp& contour : m_contours) + auto rawPath = destination->mutableRawPath(); + float dashed = 0.0f; + float distance = offset->normalizedLength(pathMeasure->length(), true); + bool draw = true; + while (dashed < pathMeasure->length()) { - float dashed = 0.0f; - float distance = offset->normalizedLength(contour->length()); - bool draw = true; - while (dashed < contour->length()) + const Dash* dash = dashes[dashIndex++ % dashes.size()]; + float dashLength = + dash->normalizedLength(pathMeasure->length(), false); + if (dashLength > pathMeasure->length()) { - const Dash* dash = dashes[dashIndex++ % dashes.size()]; - float dashLength = dash->normalizedLength(contour->length()); - if (dashLength > contour->length()) - { - dashLength = contour->length(); - } - float endLength = distance + dashLength; - if (endLength > contour->length()) + dashLength = pathMeasure->length(); + } + float endLength = distance + dashLength; + if (endLength > pathMeasure->length()) + { + endLength -= pathMeasure->length(); + if (draw) { - endLength -= contour->length(); - if (draw) + if (distance < pathMeasure->length()) { - if (distance < contour->length()) - { - contour->getSegment(distance, - contour->length(), + pathMeasure->getSegment(distance, + pathMeasure->length(), rawPath, true); - contour->getSegment(0.0f, + pathMeasure->getSegment(0.0f, endLength, rawPath, - !contour->isClosed()); - } - else - { - contour->getSegment(0.0f, endLength, rawPath, true); - } + !pathMeasure->isClosed()); + } + else + { + pathMeasure->getSegment(0.0f, endLength, rawPath, true); } - - // Setup next step. - distance = endLength - dashLength; - } - else if (draw) - { - contour->getSegment(distance, endLength, rawPath, true); } - distance += dashLength; - dashed += dashLength; - draw = !draw; + + // Setup next step. + distance = endLength - dashLength; } + else if (draw) + { + pathMeasure->getSegment(distance, endLength, rawPath, true); + } + distance += dashLength; + dashed += dashLength; + draw = !draw; } } - return &m_path; -} - -float PathDasher::pathLength() const -{ - float totalLength = 0.0f; - for (auto contour : m_contours) - { - totalLength += contour->length(); - } - return totalLength; + return destination; } StatusCode DashPath::onAddedClean(CoreContext* context) { - if (!parent()->is()) + auto effectsContainer = EffectsContainer::from(parent()); + if (!effectsContainer) { return StatusCode::InvalidObject; } - parent()->as()->addStrokeEffect(this); + effectsContainer->addStrokeEffect(this); m_dashes.clear(); for (auto child : children()) @@ -143,33 +120,47 @@ StatusCode DashPath::onAddedClean(CoreContext* context) return StatusCode::Ok; } -void DashPath::invalidateEffect() { invalidateSourcePath(); } - -void DashPath::offsetChanged() { invalidateDash(); } -void DashPath::offsetIsPercentageChanged() { invalidateDash(); } +void DashPath::offsetChanged() { invalidateEffectFromLocal(); } +void DashPath::offsetIsPercentageChanged() { invalidateEffectFromLocal(); } -void DashPath::updateEffect(const ShapePaintPath* source) +void DashPath::updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) { - - if (m_path.hasRenderPath()) + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) { - return; + auto dashEffectPath = + static_cast(effectPathIt->second); + auto path = dashEffectPath->path(); + if (path->hasRenderPath()) + { + return; + } + path->rewind(source->isLocal()); + // Dash is not supported on fills so it will use the source as output + if (shapePaint->paintType() == ShapePaintType::fill) + { + path->addPath(source); + } + else + { + Dash dashOffset(offset(), offsetIsPercentage()); + dashEffectPath->createPathMeasure(source->rawPath()); + applyDash(path, + source->rawPath(), + &dashEffectPath->pathMeasure(), + &dashOffset, + m_dashes); + } } - m_path.rewind(source->isLocal()); - - Dash dashOffset(offset(), offsetIsPercentage()); - applyDash(source->rawPath(), &dashOffset, m_dashes); } -ShapePaintPath* DashPath::effectPath() { return &m_path; } +void DashPath::invalidateDash() { invalidateEffectFromLocal(); } -void DashPath::invalidateDash() +EffectsContainer* DashPath::parentPaint() { - PathDasher::invalidateDash(); - if (parent() != nullptr) - { - auto stroke = parent()->as(); - stroke->parent()->addDirt(ComponentDirt::Paint); - stroke->invalidateRendering(); - } -} \ No newline at end of file + return EffectsContainer::from(parent()); +} + +EffectPath* DashPath::createEffectPath() { return new DashEffectPath(); } \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/effects_container.cpp b/thirdparty/rive/source/shapes/paint/effects_container.cpp new file mode 100644 index 000000000..4a578aeaa --- /dev/null +++ b/thirdparty/rive/source/shapes/paint/effects_container.cpp @@ -0,0 +1,70 @@ +#include "rive/shapes/paint/effects_container.hpp" +#include "rive/shapes/paint/stroke_effect.hpp" +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/fill.hpp" +#include "rive/shapes/paint/stroke.hpp" +#include "rive/shapes/paint/group_effect.hpp" + +using namespace rive; + +void EffectsContainer::addStrokeEffect(StrokeEffect* effect) +{ + m_effects.push_back(effect); +} + +EffectsContainer* EffectsContainer::from(Component* component) +{ + if (component) + { + switch (component->coreType()) + { + case ShapePaintBase::typeKey: + case FillBase::typeKey: + case StrokeBase::typeKey: + return component->as(); + case GroupEffectBase::typeKey: + return component->as(); + } + } + return nullptr; +} + +void EffectsContainer::invalidateEffects(StrokeEffect* invalidatingEffect) +{ + auto found = invalidatingEffect == nullptr; + for (auto& effect : m_effects) + { + if (found) + { + effect->invalidateEffect(nullptr); + } + if (invalidatingEffect && invalidatingEffect == effect) + { + found = true; + } + } +} + +ShapePaintPath* EffectsContainer::lastEffectPath(PathProvider* pathProvider) +{ + if (m_effects.size() > 0) + { + size_t effectIndex = m_effects.size() - 1; + while (effectIndex >= 0) + { + auto effect = m_effects[effectIndex]->effectPath(pathProvider); + if (effect) + { + return effect; + } + if (effectIndex == 0) + { + break; + } + effectIndex -= 1; + } + } + return nullptr; +} + +void EffectsContainer::invalidateEffects() { invalidateEffects(nullptr); } \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/feather.cpp b/thirdparty/rive/source/shapes/paint/feather.cpp index a3aa78803..b6473628f 100644 --- a/thirdparty/rive/source/shapes/paint/feather.cpp +++ b/thirdparty/rive/source/shapes/paint/feather.cpp @@ -52,20 +52,10 @@ void Feather::update(ComponentDirt value) { return; } - auto bounds = path->rawPath()->bounds().pad(strength() * 1.5f); - Vec2D innerOffset(offsetX(), offsetY()); - if (offsetInArtboard) - { - Mat2D inverseTransform = transform.invertOrIdentity(); - innerOffset = - Vec2D::transformDir(innerOffset, inverseTransform); - } - m_innerPath.rewind(); - m_innerPath.addRect(bounds); - Mat2D innerOffsetTransform = - Mat2D::fromTranslation(innerOffset); - m_innerPath.addPathBackwards(*path->rawPath(), - &innerOffsetTransform); + rebuildInnerPath(path, transform, offsetInArtboard); + // Mark dirty so draw() re-applies the effect path override if + // one is active (update() only has the original shape path). + m_effectPathDirty = true; } #ifdef TESTING renderCount++; @@ -75,6 +65,24 @@ void Feather::update(ComponentDirt value) } } +void Feather::rebuildInnerPath(const ShapePaintPath* path, + const Mat2D& shapeTransform, + bool offsetInArtboard) +{ + m_effectPathDirty = false; + auto bounds = path->rawPath()->bounds().pad(strength() * 1.5f); + Vec2D innerOffset(offsetX(), offsetY()); + if (offsetInArtboard) + { + Mat2D inverseTransform = shapeTransform.invertOrIdentity(); + innerOffset = Vec2D::transformDir(innerOffset, inverseTransform); + } + m_innerPath.rewind(); + m_innerPath.addRect(bounds); + Mat2D innerOffsetTransform = Mat2D::fromTranslation(innerOffset); + m_innerPath.addPathBackwards(*path->rawPath(), &innerOffsetTransform); +} + void Feather::buildDependencies() { auto shape = parent()->as()->parent(); diff --git a/thirdparty/rive/source/shapes/paint/fill.cpp b/thirdparty/rive/source/shapes/paint/fill.cpp index 2bacb464c..81d9a863f 100644 --- a/thirdparty/rive/source/shapes/paint/fill.cpp +++ b/thirdparty/rive/source/shapes/paint/fill.cpp @@ -31,4 +31,16 @@ ShapePaintPath* Fill::pickPath(ShapePaintContainer* shape) const return shape->localClockwisePath(); } return shape->localPath(); +} + +void Fill::buildDependencies() +{ + if (effects()->size() > 0) + { + auto container = ShapePaintContainer::from(parent()); + if (container != nullptr) + { + container->pathBuilder()->addDependent(this); + } + } } \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/group_effect.cpp b/thirdparty/rive/source/shapes/paint/group_effect.cpp new file mode 100644 index 000000000..dd3e94411 --- /dev/null +++ b/thirdparty/rive/source/shapes/paint/group_effect.cpp @@ -0,0 +1,73 @@ +#include "rive/shapes/paint/group_effect.hpp" +#include "rive/shapes/paint/target_effect.hpp" + +using namespace rive; + +void GroupEffect::updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) +{ + auto path = source; + for (auto& effect : *effects()) + { + effect->updateEffect(pathProvider, path, shapePaint); + auto newPath = effect->effectPath(pathProvider); + if (newPath) + { + path = newPath; + } + } +} + +void GroupEffect::invalidateEffects(StrokeEffect* invalidatingEffect) +{ + for (auto& targetEffect : m_targetEffects) + { + targetEffect->invalidateEffectFromLocal(); + } + EffectsContainer::invalidateEffects(invalidatingEffect); +} + +void GroupEffect::invalidateEffects() { invalidateEffects(nullptr); } + +void GroupEffect::addTargetEffect(TargetEffect* targetEffect) +{ + m_targetEffects.push_back(targetEffect); +} + +EffectsContainer* GroupEffect::parentPaint() { return nullptr; } + +void GroupEffect::addPathProvider(PathProvider* component) +{ + StrokeEffect::addPathProvider(component); + for (auto& effect : *effects()) + { + effect->addPathProvider(component); + } +} + +void GroupEffect::addStrokeEffect(StrokeEffect* effect) +{ + EffectsContainer::addStrokeEffect(effect); + for (auto& effectPath : m_effectPaths) + { + effect->addPathProvider(effectPath.first); + } +} +void GroupEffect::invalidateEffect(PathProvider* component) +{ + StrokeEffect::invalidateEffect(component); + for (auto& effect : *effects()) + { + effect->invalidateEffect(component); + } +} + +void GroupEffect::buildDependencies() +{ + Super::buildDependencies(); + if (parent()) + { + parent()->addDependent(this); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/linear_gradient.cpp b/thirdparty/rive/source/shapes/paint/linear_gradient.cpp index 5f75b4d42..e11ffc1b3 100644 --- a/thirdparty/rive/source/shapes/paint/linear_gradient.cpp +++ b/thirdparty/rive/source/shapes/paint/linear_gradient.cpp @@ -132,6 +132,7 @@ void LinearGradient::applyTo(RenderPaint* renderPaint, float opacityModifier) parent()->as()->isFlagged(PathFlags::world); Vec2D start(startX(), startY()); Vec2D end(endX(), endY()); + // Check if we need to update the world space gradient (if there's no // shape container, presumably it's the artboard and we're already in // world). @@ -150,7 +151,7 @@ void LinearGradient::applyTo(RenderPaint* renderPaint, float opacityModifier) } else { - if (m_deformer) + if (m_deformer && m_shapePaintContainer != nullptr) { const Mat2D& world = m_shapePaintContainer->worldTransform(); Mat2D inverseWorld; diff --git a/thirdparty/rive/source/shapes/paint/shape_paint.cpp b/thirdparty/rive/source/shapes/paint/shape_paint.cpp index d4a6c3073..e9f464dac 100644 --- a/thirdparty/rive/source/shapes/paint/shape_paint.cpp +++ b/thirdparty/rive/source/shapes/paint/shape_paint.cpp @@ -2,8 +2,10 @@ #include "rive/shapes/shape_paint_container.hpp" #include "rive/shapes/paint/feather.hpp" #include "rive/artboard.hpp" +#include "rive/transform_component.hpp" #include "rive/factory.hpp" #include "rive/shapes/paint/fill.hpp" +#include "rive/profiler/profiler_macros.h" using namespace rive; @@ -25,6 +27,26 @@ StatusCode ShapePaint::onAddedClean(CoreContext* context) return StatusCode::Ok; } +void ShapePaint::update(ComponentDirt value) +{ + Super::update(value); + auto shapeEffects = effects(); + if (hasDirt(value, ComponentDirt::Path) && shapeEffects->size() > 0) + { + auto container = ShapePaintContainer::from(parent()); + auto path = pickPath(container); + for (auto& effect : *shapeEffects) + { + effect->updateEffect(this, path, this); + auto newPath = effect->effectPath(this); + if (newPath) + { + path = newPath; + } + } + } +} + RenderPaint* ShapePaint::initRenderPaint(ShapePaintMutator* mutator) { assert(m_RenderPaint == nullptr); @@ -57,10 +79,13 @@ void ShapePaint::draw(Renderer* renderer, ShapePaintPath* shapePaintPath, const Mat2D& transform, bool usePathFillRule, - RenderPaint* overridePaint) + RenderPaint* overridePaint, + bool needsSaveOperation) { + RIVE_PROF_SCOPE_L(2) + ShapePaintPath* pathToDraw = shapePaintPath; - bool saved = false; + bool saved = !needsSaveOperation; if (m_feather != nullptr) { bool offsetInArtboard = m_feather->space() == TransformSpace::world; @@ -87,6 +112,12 @@ void ShapePaint::draw(Renderer* renderer, renderer->transform(transform); } + auto pathEffect = lastEffectPath(this); + if (pathEffect) + { + pathToDraw = pathEffect; + } + if (m_feather != nullptr) { if (m_feather->inner()) @@ -95,13 +126,30 @@ void ShapePaint::draw(Renderer* renderer, { return; } + // When a path effect is active, the inner path and clip must be + // based on the effect-modified path, not the original shape path. + // Only rebuild when the effect path has actually changed. + if (pathEffect != nullptr && m_feather->effectPathDirty()) + { + auto container = ShapePaintContainer::from(parent()); + if (container != nullptr) + { + bool offsetInArtboard = + m_feather->space() == TransformSpace::world; + m_feather->rebuildInnerPath( + pathEffect, + container->shapeWorldTransform(), + offsetInArtboard); + } + } pathToDraw = m_feather->innerPath(); if (!saved) { saved = true; renderer->save(); } - auto renderPath = shapePaintPath->renderPath(this); + auto clipPath = pathEffect ? pathEffect : shapePaintPath; + auto renderPath = clipPath->renderPath(this); if (renderPath != nullptr) { renderer->clipPath(renderPath); @@ -136,8 +184,42 @@ void ShapePaint::draw(Renderer* renderer, : renderPaint()); } - if (saved) + if (saved && needsSaveOperation) { renderer->restore(); } +} + +void ShapePaint::invalidateEffects(StrokeEffect* invalidatingEffect) +{ + EffectsContainer::invalidateEffects(invalidatingEffect); + if (m_feather != nullptr) + { + m_feather->markEffectPathDirty(); + } + invalidateRendering(); +} + +void ShapePaint::invalidateEffects() { invalidateEffects(nullptr); } + +void ShapePaint::invalidateRendering() { addDirt(ComponentDirt::Path); } + +void ShapePaint::addStrokeEffect(StrokeEffect* effect) +{ + effect->addPathProvider(this); + EffectsContainer::addStrokeEffect(effect); +} + +TransformComponent* ShapePaint::parentTransformComponent() const +{ + auto _parent = parent(); + while (_parent) + { + if (_parent->is()) + { + return _parent->as(); + } + _parent = _parent->parent(); + } + return nullptr; } \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/shape_paint_path.cpp b/thirdparty/rive/source/shapes/paint/shape_paint_path.cpp index c23a71cfa..e74f93565 100644 --- a/thirdparty/rive/source/shapes/paint/shape_paint_path.cpp +++ b/thirdparty/rive/source/shapes/paint/shape_paint_path.cpp @@ -57,6 +57,7 @@ RenderPath* ShapePaintPath::renderPath(const Component* component) RenderPath* ShapePaintPath::renderPath(Factory* factory) { + assert(factory != nullptr); if (!m_renderPath) { m_renderPath = factory->makeEmptyRenderPath(); diff --git a/thirdparty/rive/source/shapes/paint/solid_color.cpp b/thirdparty/rive/source/shapes/paint/solid_color.cpp index da062f4a0..f1ceb6cd5 100644 --- a/thirdparty/rive/source/shapes/paint/solid_color.cpp +++ b/thirdparty/rive/source/shapes/paint/solid_color.cpp @@ -2,6 +2,7 @@ #include "rive/container_component.hpp" #include "rive/renderer.hpp" #include "rive/shapes/paint/color.hpp" +#include "rive/artboard.hpp" using namespace rive; @@ -38,6 +39,10 @@ void SolidColor::renderOpacityChanged() { m_flags |= ShapePaintMutator::Flags::translucent; } + if (artboard()) + { + artboard()->changed(); + } } void SolidColor::applyTo(RenderPaint* renderPaint, float opacityModifier) diff --git a/thirdparty/rive/source/shapes/paint/stroke.cpp b/thirdparty/rive/source/shapes/paint/stroke.cpp index c50200546..f550ac9d7 100644 --- a/thirdparty/rive/source/shapes/paint/stroke.cpp +++ b/thirdparty/rive/source/shapes/paint/stroke.cpp @@ -1,7 +1,6 @@ #include "rive/artboard.hpp" #include "rive/shapes/paint/stroke.hpp" #include "rive/shapes/paint/stroke_cap.hpp" -#include "rive/shapes/paint/stroke_effect.hpp" #include "rive/shapes/paint/stroke_join.hpp" using namespace rive; @@ -20,17 +19,6 @@ RenderPaint* Stroke::initRenderPaint(ShapePaintMutator* mutator) return renderPaint; } -void Stroke::update(ComponentDirt value) -{ - Super::update(value); - if (hasDirt(value, ComponentDirt::Path) && m_Effect != nullptr) - { - auto container = ShapePaintContainer::from(parent()); - auto path = pickPath(container); - m_Effect->updateEffect(path); - } -} - void Stroke::applyTo(RenderPaint* renderPaint, float opacityModifier) { renderPaint->style(RenderPaintStyle::stroke); @@ -46,40 +34,29 @@ bool Stroke::isVisible() const return Super::isVisible() && thickness() > 0.0f; } -void Stroke::thicknessChanged() -{ - assert(m_RenderPaint != nullptr); - m_RenderPaint->thickness(thickness()); -} +void Stroke::thicknessChanged() { addDirt(ComponentDirt::Paint); } -void Stroke::capChanged() -{ - assert(m_RenderPaint != nullptr); - m_RenderPaint->cap((StrokeCap)cap()); -} +void Stroke::capChanged() { addDirt(ComponentDirt::Paint); } -void Stroke::joinChanged() -{ - assert(m_RenderPaint != nullptr); - m_RenderPaint->join((StrokeJoin)join()); -} +void Stroke::joinChanged() { addDirt(ComponentDirt::Paint); } -void Stroke::addStrokeEffect(StrokeEffect* effect) { m_Effect = effect; } - -void Stroke::invalidateEffects() +void Stroke::update(ComponentDirt value) { - if (m_Effect != nullptr) + Super::update(value); + if (hasDirt(value, ComponentDirt::Paint)) { - m_Effect->invalidateEffect(); + assert(m_RenderPaint != nullptr); + m_RenderPaint->thickness(thickness()); + m_RenderPaint->cap((StrokeCap)cap()); + m_RenderPaint->join((StrokeJoin)join()); } - invalidateRendering(); } void Stroke::invalidateRendering() { assert(m_RenderPaint != nullptr); m_RenderPaint->invalidateStroke(); - addDirt(ComponentDirt::Path); + Super::invalidateRendering(); } ShapePaintPath* Stroke::pickPath(ShapePaintContainer* shape) const @@ -91,24 +68,6 @@ ShapePaintPath* Stroke::pickPath(ShapePaintContainer* shape) const return shape->worldPath(); } -void Stroke::draw(Renderer* renderer, - ShapePaintPath* shapePaintPath, - const Mat2D& transform, - bool usePathFillRule, - RenderPaint* overridePaint) -{ - if (m_Effect != nullptr) - { - shapePaintPath = m_Effect->effectPath(); - } - - Super::draw(renderer, - shapePaintPath, - transform, - usePathFillRule, - overridePaint); -} - void Stroke::buildDependencies() { auto container = ShapePaintContainer::from(parent()); diff --git a/thirdparty/rive/source/shapes/paint/stroke_effect.cpp b/thirdparty/rive/source/shapes/paint/stroke_effect.cpp new file mode 100644 index 000000000..cfb779db6 --- /dev/null +++ b/thirdparty/rive/source/shapes/paint/stroke_effect.cpp @@ -0,0 +1,66 @@ +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/stroke_effect.hpp" + +using namespace rive; + +// This is only called from within a StrokeEffect. +// Whenever a StrokeEffect needs to invalidate ITSELF +// this method should be used (not invalidateEffect). +// It calls invalidateEffects on its parent ShapePaint +// which can result in invalidating other StrokeEffects. +// It also calls invalidateEffect() to do the invalidation +// work on itself +void StrokeEffect::invalidateEffectFromLocal() +{ + for (auto& effectPath : m_effectPaths) + { + effectPath.second->invalidateEffect(); + } + auto parentShapePaint = parentPaint(); + if (parentShapePaint != nullptr) + { + parentShapePaint->invalidateEffects(this); + } +} + +// This is called from outside StrokeEffect. +// This does the actual invalidation work. +// This should NOT be called from inside StrokeEffect +// directly (it is called indirectly via invalidateEffectFromLocal) +void StrokeEffect::invalidateEffect(PathProvider* pathProvider) +{ + + if (pathProvider) + { + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) + { + effectPathIt->second->invalidateEffect(); + } + } + else + { + for (auto& effectPath : m_effectPaths) + { + effectPath.second->invalidateEffect(); + } + } +} + +StrokeEffect::~StrokeEffect() +{ + for (auto& effectPath : m_effectPaths) + { + delete effectPath.second; + } +} + +ShapePaintPath* StrokeEffect::effectPath(PathProvider* pathProvider) +{ + auto it = m_effectPaths.find(pathProvider); + if (it != m_effectPaths.end()) + { + return it->second->path(); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/target_effect.cpp b/thirdparty/rive/source/shapes/paint/target_effect.cpp new file mode 100644 index 000000000..5bdfe1f07 --- /dev/null +++ b/thirdparty/rive/source/shapes/paint/target_effect.cpp @@ -0,0 +1,121 @@ +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/target_effect.hpp" +#include "rive/artboard.hpp" +#include "rive/shapes/paint/group_effect.hpp" + +using namespace rive; + +StatusCode TargetEffect::onAddedClean(CoreContext* context) +{ + auto effectsContainer = EffectsContainer::from(parent()); + if (!effectsContainer) + { + return StatusCode::InvalidObject; + } + effectsContainer->addStrokeEffect(this); + + auto groupTarget = context->resolve(targetId()); + if (groupTarget == nullptr || !groupTarget->is()) + { + return StatusCode::MissingObject; + } + m_groupEffect = groupTarget->as(); + m_groupEffect->addTargetEffect(this); + for (auto& effectPath : m_effectPaths) + { + auto targetEffectPath = + static_cast(effectPath.second); + m_groupEffect->addPathProvider(targetEffectPath->pathProviderProxy()); + } + + return StatusCode::Ok; +} + +void TargetEffect::updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) +{ + if (!m_groupEffect) + { + return; + } + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) + { + auto targetEffectPath = + static_cast(effectPathIt->second); + m_groupEffect->updateEffect(targetEffectPath->pathProviderProxy(), + source, + shapePaint); + } +} + +ShapePaintPath* TargetEffect::effectPath(PathProvider* pathProvider) +{ + if (!m_groupEffect) + { + return nullptr; + } + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) + { + auto targetEffectPath = + static_cast(effectPathIt->second); + return m_groupEffect->lastEffectPath( + targetEffectPath->pathProviderProxy()); + } + return nullptr; +} + +void TargetEffect::addPathProvider(PathProvider* component) +{ + StrokeEffect::addPathProvider(component); + + auto effectPathIt = m_effectPaths.find(component); + if (effectPathIt != m_effectPaths.end()) + { + auto targetEffectPath = + static_cast(effectPathIt->second); + if (m_groupEffect) + { + m_groupEffect->addPathProvider( + targetEffectPath->pathProviderProxy()); + } + } +} + +EffectsContainer* TargetEffect::parentPaint() +{ + return EffectsContainer::from(parent()); +} + +EffectPath* TargetEffect::createEffectPath() { return new TargetEffectPath(); } + +void TargetEffect::invalidateEffect(PathProvider* pathProvider) +{ + if (!m_groupEffect) + { + return; + } + if (pathProvider) + { + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) + { + auto targetEffectPath = + static_cast(effectPathIt->second); + m_groupEffect->invalidateEffect( + targetEffectPath->pathProviderProxy()); + } + } + else + { + for (auto& effectPath : m_effectPaths) + { + auto targetEffectPath = + static_cast(effectPath.second); + m_groupEffect->invalidateEffect( + targetEffectPath->pathProviderProxy()); + } + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/paint/trim_path.cpp b/thirdparty/rive/source/shapes/paint/trim_path.cpp index 303203964..35dba6713 100644 --- a/thirdparty/rive/source/shapes/paint/trim_path.cpp +++ b/thirdparty/rive/source/shapes/paint/trim_path.cpp @@ -1,31 +1,43 @@ #include "rive/shapes/paint/trim_path.hpp" -#include "rive/shapes/paint/stroke.hpp" +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/profiler/profiler_macros.h" using namespace rive; +void TrimEffectPath::invalidateEffect() +{ + m_path.rewind(); + m_contours.clear(); +} + StatusCode TrimPath::onAddedClean(CoreContext* context) { - if (!parent()->is()) + auto effectsContainer = EffectsContainer::from(parent()); + if (!effectsContainer) { return StatusCode::InvalidObject; } - - parent()->as()->addStrokeEffect(this); + effectsContainer->addStrokeEffect(this); return StatusCode::Ok; } -void TrimPath::trimPath(const RawPath* source) +void TrimPath::trimPath(ShapePaintPath* destination, + std::vector>& contours, + const RawPath* source, + ShapePaintType shapePaintType) { - auto rawPath = m_path.mutableRawPath(); + RIVE_PROF_SCOPE_L(3) + auto rawPath = destination->mutableRawPath(); auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f); + auto closeShape = shapePaintType == ShapePaintType::fill; // Build up contours if they're empty. - if (m_contours.empty()) + if (contours.empty()) { ContourMeasureIter iter(source); while (auto meas = iter.next()) { - m_contours.push_back(meas); + contours.push_back(meas); } } switch (mode()) @@ -33,7 +45,7 @@ void TrimPath::trimPath(const RawPath* source) case TrimPathMode::sequential: { float totalLength = 0.0f; - for (auto contour : m_contours) + for (auto contour : contours) { totalLength += contour->length(); } @@ -53,13 +65,13 @@ void TrimPath::trimPath(const RawPath* source) endLength -= totalLength; } - int i = 0, subPathCount = (int)m_contours.size(); + int i = 0, subPathCount = (int)contours.size(); std::vector indices; std::vector lengths; while (endLength > 0) { auto currentContourIndex = i % subPathCount; - auto contour = m_contours[currentContourIndex]; + auto contour = contours[currentContourIndex]; auto contourLength = contour->length(); if (startLength < contourLength) @@ -96,7 +108,7 @@ void TrimPath::trimPath(const RawPath* source) : startingIndex) % indices.size(); auto contourIndex = indices[index]; - auto contour = m_contours[contourIndex]; + auto contour = contours[contourIndex]; auto contourLength = contour->length(); auto lengthIndex = index * 2; auto startLength = lengths[lengthIndex]; @@ -110,9 +122,10 @@ void TrimPath::trimPath(const RawPath* source) !contour->isClosed()); // Close contours that are fully used as // segments - if (startLength == 0.0f && - endLength - startLength >= contourLength && - contour->isClosed()) + if ((startLength == 0.0f && + endLength - startLength >= contourLength && + contour->isClosed()) || + closeShape) { rawPath->close(); } @@ -125,7 +138,7 @@ void TrimPath::trimPath(const RawPath* source) case TrimPathMode::synchronized: { - for (auto contour : m_contours) + for (auto contour : contours) { auto contourLength = contour->length(); auto startLength = contourLength * (start() + renderOffset); @@ -153,7 +166,8 @@ void TrimPath::trimPath(const RawPath* source) !contour->isClosed()); } - if (start() == 0.0f && end() == 1.0f && contour->isClosed()) + if ((start() == 0.0f && end() == 1.0f && contour->isClosed()) || + closeShape) { rawPath->close(); } @@ -165,29 +179,10 @@ void TrimPath::trimPath(const RawPath* source) } } -void TrimPath::invalidateEffect() -{ - invalidateTrim(); - // This is usually sent when the path is changed so we need to also - // invalidate the contours, not just the trim effect. - m_contours.clear(); -} - -void TrimPath::invalidateTrim() -{ - m_path.rewind(); - if (parent() != nullptr) - { - auto stroke = parent()->as(); - stroke->parent()->addDirt(ComponentDirt::Paint); - stroke->invalidateRendering(); - } -} - -void TrimPath::startChanged() { invalidateTrim(); } -void TrimPath::endChanged() { invalidateTrim(); } -void TrimPath::offsetChanged() { invalidateTrim(); } -void TrimPath::modeValueChanged() { invalidateTrim(); } +void TrimPath::startChanged() { invalidateEffectFromLocal(); } +void TrimPath::endChanged() { invalidateEffectFromLocal(); } +void TrimPath::offsetChanged() { invalidateEffectFromLocal(); } +void TrimPath::modeValueChanged() { invalidateEffectFromLocal(); } StatusCode TrimPath::onAddedDirty(CoreContext* context) { @@ -200,20 +195,38 @@ StatusCode TrimPath::onAddedDirty(CoreContext* context) { case TrimPathMode::sequential: case TrimPathMode::synchronized: + return StatusCode::Ok; } return StatusCode::InvalidObject; } -void TrimPath::updateEffect(const ShapePaintPath* source) +void TrimPath::updateEffect(PathProvider* pathProvider, + const ShapePaintPath* source, + const ShapePaint* shapePaint) { - if (m_path.hasRenderPath()) + auto effectPathIt = m_effectPaths.find(pathProvider); + if (effectPathIt != m_effectPaths.end()) { - // Previous result hasn't been invalidated, it's still good. - return; + auto trimEffectPath = + static_cast(effectPathIt->second); + auto path = trimEffectPath->path(); + if (path->hasRenderPath()) + { + // Previous result hasn't been invalidated, it's still good. + return; + } + path->rewind(source->isLocal(), source->fillRule()); + trimPath(path, + trimEffectPath->contours(), + source->rawPath(), + shapePaint->paintType()); } - m_path.rewind(source->isLocal(), source->fillRule()); - trimPath(source->rawPath()); } -ShapePaintPath* TrimPath::effectPath() { return &m_path; } \ No newline at end of file +EffectsContainer* TrimPath::parentPaint() +{ + return EffectsContainer::from(parent()); +} + +EffectPath* TrimPath::createEffectPath() { return new TrimEffectPath(); } \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/path.cpp b/thirdparty/rive/source/shapes/path.cpp index 437491793..419dcd223 100644 --- a/thirdparty/rive/source/shapes/path.cpp +++ b/thirdparty/rive/source/shapes/path.cpp @@ -100,6 +100,8 @@ void Path::buildDependencies() { Super::buildDependencies(); } void Path::addVertex(PathVertex* vertex) { m_Vertices.push_back(vertex); } +void Path::popVertex() { m_Vertices.pop_back(); } + void Path::addFlags(PathFlags flags) { m_pathFlags |= flags; } bool Path::isFlagged(PathFlags flags) const { @@ -125,6 +127,8 @@ bool Path::canDeferPathUpdate() const Mat2D& Path::pathTransform() const { return worldTransform(); } +AABB Path::localBounds() const { return m_rawPath.preciseBounds(); } + void Path::buildPath(RawPath& rawPath) const { const bool isClosed = isPathClosed(); diff --git a/thirdparty/rive/source/shapes/points_common_path.cpp b/thirdparty/rive/source/shapes/points_common_path.cpp new file mode 100644 index 000000000..03f948125 --- /dev/null +++ b/thirdparty/rive/source/shapes/points_common_path.cpp @@ -0,0 +1,15 @@ +#include "rive/artboard.hpp" +#include "rive/shapes/points_common_path.hpp" +#include "rive/shapes/vertex.hpp" +#include "rive/shapes/path_vertex.hpp" +#include "rive/shapes/shape.hpp" +#include "rive/bones/skin.hpp" +#include "rive/span.hpp" +#include "rive/shapes/shape_path_flags.hpp" + +using namespace rive; + +bool PointsCommonPath::isClockwise() const +{ + return (pathFlags() & (int)ShapePathFlags::isCounterClockwise) == 0; +} diff --git a/thirdparty/rive/source/shapes/points_path.cpp b/thirdparty/rive/source/shapes/points_path.cpp index 7227b2ebf..344b2421e 100644 --- a/thirdparty/rive/source/shapes/points_path.cpp +++ b/thirdparty/rive/source/shapes/points_path.cpp @@ -50,8 +50,3 @@ void PointsPath::markPathDirty(bool sendToLayout) } void PointsPath::markSkinDirty() { markPathDirty(); } - -bool PointsPath::isClockwise() const -{ - return (pathFlags() & (int)ShapePathFlags::isCounterClockwise) == 0; -} diff --git a/thirdparty/rive/source/shapes/rectangle.cpp b/thirdparty/rive/source/shapes/rectangle.cpp index 272718bd1..e70cb0ed4 100644 --- a/thirdparty/rive/source/shapes/rectangle.cpp +++ b/thirdparty/rive/source/shapes/rectangle.cpp @@ -1,5 +1,3 @@ -#pragma once - #include "rive/shapes/rectangle.hpp" using namespace rive; @@ -45,4 +43,4 @@ void Rectangle::update(ComponentDirt value) } Super::update(value); -} +} \ No newline at end of file diff --git a/thirdparty/rive/source/shapes/shape.cpp b/thirdparty/rive/source/shapes/shape.cpp index e42aeb94b..4fe3bf338 100644 --- a/thirdparty/rive/source/shapes/shape.cpp +++ b/thirdparty/rive/source/shapes/shape.cpp @@ -8,9 +8,11 @@ #include "rive/shapes/paint/blend_mode.hpp" #include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/path_composer.hpp" +#include "rive/artboard.hpp" #include "rive/clip_result.hpp" #include "rive/math/contour_measure.hpp" #include "rive/math/raw_path.hpp" +#include "rive/profiler/profiler_macros.h" #include using namespace rive; @@ -76,7 +78,13 @@ float Shape::length() float l = 0; for (auto path : m_Paths) { - RawPath source = path->rawPath().transform(path->pathTransform()); + const bool pathDirty = path->hasDirt(ComponentDirt::Path | + ComponentDirt::WorldTransform | + ComponentDirt::NSlicer); + RawPath temp; + const RawPath& base = + pathDirty ? (path->buildPath(temp), temp) : path->rawPath(); + RawPath source = base.transform(path->pathTransform()); ContourMeasureIter iter(&source); while (auto contour = iter.next()) { @@ -91,6 +99,7 @@ float Shape::length() void Shape::pathChanged() { m_PathComposer.addDirt(ComponentDirt::Path, true); + m_WorldLength = -1; for (auto constraint : constraints()) { constraint->addDirt(ComponentDirt::Path); @@ -111,34 +120,41 @@ void Shape::addToRenderPath(RenderPath* path, const Mat2D& transform) } } -void Shape::draw(Renderer* renderer) +void Shape::addToRawPath(RawPath& path, const Mat2D* transform) { - if (renderOpacity() == 0.0f) + if (isFlagged(PathFlags::local)) { - return; + Mat2D xform = transform == nullptr ? worldTransform() + : (*transform) * worldTransform(); + path.addPath(*m_PathComposer.localPath()->rawPath(), &xform); } - ClipResult clipResult = applyClip(renderer); - - if (clipResult != ClipResult::emptyClip) + else { - for (auto shapePaint : m_ShapePaints) - { - if (!shapePaint->isVisible()) - { - continue; - } - auto shapePaintPath = shapePaint->pickPath(this); - if (shapePaintPath == nullptr) - { - continue; - } - shapePaint->draw(renderer, shapePaintPath, worldTransform()); - } + path.addPath(*m_PathComposer.worldPath()->rawPath(), transform); } +} - if (clipResult != ClipResult::noClip) +void Shape::draw(Renderer* renderer) +{ + RIVE_PROF_SCOPE_L(2) + auto needsSaveOperation = m_needsSaveOperation || m_ShapePaints.size() > 1; + for (auto shapePaint : m_ShapePaints) { - renderer->restore(); + if (!shapePaint->isVisible()) + { + continue; + } + auto shapePaintPath = shapePaint->pickPath(this); + if (shapePaintPath == nullptr) + { + continue; + } + shapePaint->draw(renderer, + shapePaintPath, + worldTransform(), + false, + nullptr, + needsSaveOperation); } } @@ -222,6 +238,27 @@ Core* Shape::hitTest(HitInfo* hinfo, const Mat2D& xform) return nullptr; } +bool Shape::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + // If we're NOT the primary hit test, don't perform the AABB hit test + // just keep walking up the tree + if (!isPrimaryHit) + { + return Component::hitTestPoint(position, skipOnUnclipped, isPrimaryHit); + } + // Only perform the AABB hit test if we're the primary hit test + // This prevents walking up the tree and having another shape return a + // false hit test because we're not hitting their AABB + if (hitTestAABB(position) && + Component::hitTestPoint(position, skipOnUnclipped, isPrimaryHit)) + { + return hitTestHiFi(position, 2); + } + return false; +} + void Shape::buildDependencies() { // Make sure to propagate the call to PathComposer as it's no longer part of @@ -286,6 +323,8 @@ bool Shape::isEmpty() return true; } +bool Shape::willDraw() { return Super::willDraw() && renderOpacity() != 0.0f; } + // Do constraints need to be marked as dirty too? From tests it doesn't seem // they do. void Shape::pathCollapseChanged() { m_PathComposer.pathCollapseChanged(); } diff --git a/thirdparty/rive/source/shapes/shape_paint_container.cpp b/thirdparty/rive/source/shapes/shape_paint_container.cpp index 2d8f090ab..e1ee3cea2 100644 --- a/thirdparty/rive/source/shapes/shape_paint_container.cpp +++ b/thirdparty/rive/source/shapes/shape_paint_container.cpp @@ -4,7 +4,7 @@ #include "rive/component.hpp" #include "rive/layout_component.hpp" #include "rive/foreground_layout_drawable.hpp" -#include "rive/shapes/paint/stroke.hpp" +#include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/shape.hpp" #include "rive/text/text_style_paint.hpp" #include "rive/text/text_input_selected_text.hpp" @@ -59,9 +59,9 @@ void ShapePaintContainer::invalidateStrokeEffects() { for (auto paint : m_ShapePaints) { - if (paint->is()) + if (paint->is()) { - paint->as()->invalidateEffects(); + paint->as()->invalidateEffects(); } } } diff --git a/thirdparty/rive/source/shapes/slice_mesh.cpp b/thirdparty/rive/source/shapes/slice_mesh.cpp index 22e96b2e1..39de547ef 100644 --- a/thirdparty/rive/source/shapes/slice_mesh.cpp +++ b/thirdparty/rive/source/shapes/slice_mesh.cpp @@ -73,15 +73,18 @@ void SliceMesh::updateBuffers() vertexSizeInBytes); } - if (m_VertexRenderBuffer) + if (m_VertexRenderBuffer != nullptr) { Vec2D* mappedVertices = reinterpret_cast(m_VertexRenderBuffer->map()); - for (auto v : m_vertices) + if (mappedVertices != nullptr) { - *mappedVertices++ = v; + for (auto v : m_vertices) + { + *mappedVertices++ = v; + } + m_VertexRenderBuffer->unmap(); } - m_VertexRenderBuffer->unmap(); } // 2. uv render buffer @@ -106,12 +109,15 @@ void SliceMesh::updateBuffers() renderImage != nullptr ? renderImage->uvTransform() : Mat2D(); Vec2D* mappedUVs = reinterpret_cast(m_UVRenderBuffer->map()); - for (auto uv : m_uvs) + if (mappedUVs != nullptr) { - Vec2D xformedUV = uvTransform * uv; - *mappedUVs++ = xformedUV; + for (auto uv : m_uvs) + { + Vec2D xformedUV = uvTransform * uv; + *mappedUVs++ = xformedUV; + } + m_UVRenderBuffer->unmap(); } - m_UVRenderBuffer->unmap(); } // 3. index render buffer @@ -132,8 +138,11 @@ void SliceMesh::updateBuffers() if (m_IndexRenderBuffer) { void* mappedIndex = m_IndexRenderBuffer->map(); - memcpy(mappedIndex, m_indices.data(), indexSizeInBytes); - m_IndexRenderBuffer->unmap(); + if (mappedIndex != nullptr) + { + memcpy(mappedIndex, m_indices.data(), indexSizeInBytes); + m_IndexRenderBuffer->unmap(); + } } } diff --git a/thirdparty/rive/source/solo.cpp b/thirdparty/rive/source/solo.cpp index 4eb085981..02054b73a 100644 --- a/thirdparty/rive/source/solo.cpp +++ b/thirdparty/rive/source/solo.cpp @@ -51,4 +51,56 @@ StatusCode Solo::onAddedClean(CoreContext* context) propagateCollapse(isCollapsed()); return StatusCode::Ok; -} \ No newline at end of file +} + +void Solo::updateByIndex(size_t index) +{ + if (index >= 0 && index < children().size() && artboard()) + { + auto child = children()[index]; + int globalIndex = artboard()->idOf(child); + activeComponentId(globalIndex); + } +} + +void Solo::updateByName(const std::string& name) +{ + for (auto& child : children()) + { + if (child->name() == name) + { + + int globalIndex = artboard()->idOf(child); + activeComponentId(globalIndex); + break; + } + } +} + +int Solo::getActiveChildIndex() +{ + Core* active = artboard()->resolve(activeComponentId()); + if (active) + { + int index = 0; + for (auto& child : children()) + { + if (child == active) + { + return index; + } + index++; + } + } + return -1; +} + +std::string Solo::getActiveChildName() +{ + Core* active = artboard()->resolve(activeComponentId()); + if (active && active->is()) + { + return active->as()->name(); + } + return ""; +} diff --git a/thirdparty/rive/source/static_scene.cpp b/thirdparty/rive/source/static_scene.cpp index 9f8ecb5ea..c98b5dbe5 100644 --- a/thirdparty/rive/source/static_scene.cpp +++ b/thirdparty/rive/source/static_scene.cpp @@ -1,5 +1,6 @@ #include "rive/static_scene.hpp" #include "rive/artboard.hpp" +#include "rive/profiler/profiler_macros.h" using namespace rive; @@ -20,6 +21,7 @@ float StaticScene::durationSeconds() const { return 0; } bool StaticScene::advanceAndApply(float seconds) { + RIVE_PROF_SCOPE_L(1) // We ignore the 'seconds' argument because it's not an animated scene m_artboardInstance->advance(0); return true; diff --git a/thirdparty/rive/source/text/cursor.cpp b/thirdparty/rive/source/text/cursor.cpp index 3ebe4f7e0..529c2851b 100644 --- a/thirdparty/rive/source/text/cursor.cpp +++ b/thirdparty/rive/source/text/cursor.cpp @@ -207,21 +207,21 @@ CursorPosition CursorPosition::clamped(const FullyShapedText& shape) const std::min(m_lineIndex, subtractUint32((uint32_t)shape.orderedLines().size(), 1)), std::min(m_codePointIndex, - subtractUint32(shape.glyphLookup().lastCodeUnitIndex(), 1))); + subtractUint32(shape.glyphLookup().lastCodePointIndex(), 1))); } CursorPosition CursorPosition::atIndex(uint32_t codePointIndex, const FullyShapedText& shape) { - // Don't go to actual last code unit index as we always insert a zero width + // Don't go to actual last codepoint index as we always insert a zero width // space. // https://en.wikipedia.org/wiki/Zero-width_space if (codePointIndex >= - subtractUint32(shape.glyphLookup().lastCodeUnitIndex(), 1)) + subtractUint32(shape.glyphLookup().lastCodePointIndex(), 1)) { return CursorPosition( subtractUint32((uint32_t)shape.orderedLines().size(), 1), - subtractUint32(shape.glyphLookup().lastCodeUnitIndex(), 1)); + subtractUint32(shape.glyphLookup().lastCodePointIndex(), 1)); } const SimpleArray& paragraphs = shape.paragraphs(); diff --git a/thirdparty/rive/source/text/font_hb.cpp b/thirdparty/rive/source/text/font_hb.cpp index 3db80fac8..aa9b5822d 100644 --- a/thirdparty/rive/source/text/font_hb.cpp +++ b/thirdparty/rive/source/text/font_hb.cpp @@ -9,6 +9,7 @@ #include "rive/factory.hpp" #include "rive/renderer_utils.hpp" +#include "rive/shapes/paint/color.hpp" #include "hb.h" #include "hb-ot.h" @@ -33,7 +34,7 @@ rive::rcp HBFont::Decode(rive::Span span) nullptr); if (blob) { - auto face = hb_face_create(blob, 0); + auto face = hb_face_create_or_fail(blob, 0); hb_blob_destroy(blob); if (face) { @@ -130,6 +131,342 @@ extern "C" } } +// Convert HarfBuzz color (BGRA byte order) to Rive ColorInt (ARGB). +static rive::ColorInt hbColorToColorInt(hb_color_t c) +{ + uint8_t b = hb_color_get_blue(c); + uint8_t g = hb_color_get_green(c); + uint8_t r = hb_color_get_red(c); + uint8_t a = hb_color_get_alpha(c); + return rive::colorARGB(a, r, g, b); +} + +// ── COLRv1 paint callbacks ────────────────────────────────────────────── +// We flatten the COLRv1 paint tree into a list of (path, fill) layers. + +struct PaintState +{ + hb_font_t* font; + hb_draw_funcs_t* drawFuncs; + std::vector* layers; + rive::GlyphID clipGlyph = 0; + bool hasClip = false; + rive::ColorInt foreground = 0xFF000000; + + // Transform stack for gradient coordinates. + // HarfBuzz gives gradient coords in the local space of the paint; + // transforms map them to glyph space. + std::vector transformStack; + + void pushTransform(float xx, + float yx, + float xy, + float yy, + float dx, + float dy) + { + rive::Mat2D m; + m[0] = xx; + m[1] = yx; + m[2] = xy; + m[3] = yy; + m[4] = dx * gInvScale; + m[5] = -dy * gInvScale; + if (transformStack.empty()) + { + transformStack.push_back(m); + } + else + { + transformStack.push_back(transformStack.back() * m); + } + } + + void popTransform() + { + if (!transformStack.empty()) + { + transformStack.pop_back(); + } + } + + rive::Vec2D mapPoint(float x, float y) const + { + // Scale from HB font units to Rive glyph units, and flip Y. + float rx = x * gInvScale; + float ry = -y * gInvScale; + if (!transformStack.empty()) + { + // The transform stack already incorporates gInvScale + Y flip + // in pushTransform, so just apply raw coords. + const auto& m = transformStack.back(); + return rive::Vec2D(m[0] * x + m[2] * y + m[4], + m[1] * x + m[3] * y + m[5]); + } + return rive::Vec2D(rx, ry); + } + + float mapRadius(float r) const + { + float scaled = r * gInvScale; + if (!transformStack.empty()) + { + // Use the geometric mean of the scale factors. + const auto& m = transformStack.back(); + float sx = std::sqrt(m[0] * m[0] + m[1] * m[1]); + return r * sx; // Don't double-apply gInvScale; it's in the matrix. + } + return scaled; + } + + // Helper: extract color stops from hb_color_line_t. + static std::vector extractStops( + hb_color_line_t* colorLine, + rive::ColorInt foreground) + { + unsigned int count = 0; + hb_color_line_get_color_stops(colorLine, 0, &count, nullptr); + std::vector hbStops(count); + hb_color_line_get_color_stops(colorLine, 0, &count, hbStops.data()); + std::vector stops; + stops.reserve(count); + for (auto& s : hbStops) + { + rive::ColorInt c = + s.is_foreground ? foreground : hbColorToColorInt(s.color); + stops.push_back({s.offset, c}); + } + return stops; + } + + // Helper: emit a layer with the current clip glyph path. + rive::Font::ColorGlyphLayer makeClipLayer() const + { + rive::Font::ColorGlyphLayer layer; + hb_font_draw_glyph(font, clipGlyph, drawFuncs, &layer.path); + return layer; + } +}; + +static void paint_push_transform(hb_paint_funcs_t*, + void* paint_data, + float xx, + float yx, + float xy, + float yy, + float dx, + float dy, + void*) +{ + ((PaintState*)paint_data)->pushTransform(xx, yx, xy, yy, dx, dy); +} + +static void paint_pop_transform(hb_paint_funcs_t*, void* paint_data, void*) +{ + ((PaintState*)paint_data)->popTransform(); +} + +static void paint_push_clip_glyph(hb_paint_funcs_t*, + void* paint_data, + hb_codepoint_t glyph, + hb_font_t*, + void*) +{ + auto* state = (PaintState*)paint_data; + state->clipGlyph = (rive::GlyphID)glyph; + state->hasClip = true; +} + +static void paint_push_clip_rectangle(hb_paint_funcs_t*, + void*, + float, + float, + float, + float, + void*) +{} + +static void paint_pop_clip(hb_paint_funcs_t*, void* paint_data, void*) +{ + ((PaintState*)paint_data)->hasClip = false; +} + +static void paint_solid(hb_paint_funcs_t*, + void* paint_data, + hb_bool_t is_foreground, + hb_color_t color, + void*) +{ + auto* state = (PaintState*)paint_data; + if (!state->hasClip) + return; + + auto layer = state->makeClipLayer(); + layer.paintType = rive::Font::ColorGlyphPaintType::solid; + if (is_foreground) + { + layer.useForeground = true; + layer.color = state->foreground; + } + else + { + layer.color = hbColorToColorInt(color); + } + state->layers->push_back(std::move(layer)); +} + +static void paint_linear_gradient(hb_paint_funcs_t*, + void* paint_data, + hb_color_line_t* colorLine, + float x0, + float y0, + float x1, + float y1, + float x2, + float y2, + void*) +{ + auto* state = (PaintState*)paint_data; + if (!state->hasClip) + return; + + auto layer = state->makeClipLayer(); + layer.paintType = rive::Font::ColorGlyphPaintType::linearGradient; + layer.stops = PaintState::extractStops(colorLine, state->foreground); + + // OpenType linear gradient uses 3 points: p0 (start), p1 (end), p2 + // (rotation). The gradient line goes from p0 toward p1, and p2 is used + // to rotate the direction. For Rive we need a 2-point definition. + // The actual gradient direction is: start = p0, end = p1 projected + // along the p0->p2 direction. For simplicity, just use p0 and p1. + auto sp0 = state->mapPoint(x0, y0); + auto sp1 = state->mapPoint(x1, y1); + layer.x0 = sp0.x; + layer.y0 = sp0.y; + layer.x1 = sp1.x; + layer.y1 = sp1.y; + + state->layers->push_back(std::move(layer)); +} + +static void paint_radial_gradient(hb_paint_funcs_t*, + void* paint_data, + hb_color_line_t* colorLine, + float x0, + float y0, + float radius0, + float x1, + float y1, + float radius1, + void*) +{ + auto* state = (PaintState*)paint_data; + if (!state->hasClip) + return; + + auto layer = state->makeClipLayer(); + layer.paintType = rive::Font::ColorGlyphPaintType::radialGradient; + layer.stops = PaintState::extractStops(colorLine, state->foreground); + + auto sp0 = state->mapPoint(x0, y0); + auto sp1 = state->mapPoint(x1, y1); + layer.x0 = sp0.x; + layer.y0 = sp0.y; + layer.x1 = sp1.x; + layer.y1 = sp1.y; + layer.r0 = state->mapRadius(radius0); + layer.r1 = state->mapRadius(radius1); + + state->layers->push_back(std::move(layer)); +} + +static void paint_sweep_gradient(hb_paint_funcs_t*, + void* paint_data, + hb_color_line_t* colorLine, + float cx, + float cy, + float startAngle, + float endAngle, + void*) +{ + auto* state = (PaintState*)paint_data; + if (!state->hasClip) + return; + + auto layer = state->makeClipLayer(); + layer.paintType = rive::Font::ColorGlyphPaintType::sweepGradient; + layer.stops = PaintState::extractStops(colorLine, state->foreground); + + auto sc = state->mapPoint(cx, cy); + layer.x0 = sc.x; + layer.y0 = sc.y; + layer.startAngle = startAngle; + layer.endAngle = endAngle; + + state->layers->push_back(std::move(layer)); +} + +static void paint_push_group(hb_paint_funcs_t*, void*, void*) {} +static void paint_pop_group(hb_paint_funcs_t*, + void*, + hb_paint_composite_mode_t, + void*) +{} + +static hb_bool_t paint_color_glyph(hb_paint_funcs_t*, + void*, + hb_codepoint_t, + hb_font_t*, + void*) +{ + return false; +} + +static hb_bool_t paint_image(hb_paint_funcs_t*, + void* paint_data, + hb_blob_t* blob, + unsigned int width, + unsigned int height, + hb_tag_t format, + float slant, + hb_glyph_extents_t* extents, + void*) +{ + // We only support PNG images (SBIX / CBDT). + if (format != HB_TAG('p', 'n', 'g', ' ')) + { + return false; + } + + unsigned int length; + const char* data = hb_blob_get_data(blob, &length); + if (data == nullptr || length == 0) + { + return false; + } + + auto* state = (PaintState*)paint_data; + + rive::Font::ColorGlyphLayer layer; + layer.paintType = rive::Font::ColorGlyphPaintType::image; + layer.imageBytes.assign(reinterpret_cast(data), + reinterpret_cast(data) + length); + layer.imageWidth = width; + layer.imageHeight = height; + if (extents != nullptr) + { + layer.imageBearingX = extents->x_bearing * gInvScale; + layer.imageBearingY = -extents->y_bearing * gInvScale; + layer.imageExtentX = extents->width * gInvScale; + layer.imageExtentY = -extents->height * gInvScale; + } + + state->layers->push_back(std::move(layer)); + return true; +} + +// ──────────────────────────────────────────────────────────────────────── + static rive::Font::LineMetrics make_lmx(hb_font_t* font) { // premable on font... @@ -175,11 +512,82 @@ HBFont::HBFont(hb_font_t* font, nullptr, nullptr); hb_draw_funcs_make_immutable(m_drawFuncs); + + // Initialize COLRv1 paint funcs. + m_paintFuncs = hb_paint_funcs_create(); + hb_paint_funcs_set_push_transform_func(m_paintFuncs, + paint_push_transform, + nullptr, + nullptr); + hb_paint_funcs_set_pop_transform_func(m_paintFuncs, + paint_pop_transform, + nullptr, + nullptr); + hb_paint_funcs_set_push_clip_glyph_func(m_paintFuncs, + paint_push_clip_glyph, + nullptr, + nullptr); + hb_paint_funcs_set_push_clip_rectangle_func(m_paintFuncs, + paint_push_clip_rectangle, + nullptr, + nullptr); + hb_paint_funcs_set_pop_clip_func(m_paintFuncs, + paint_pop_clip, + nullptr, + nullptr); + hb_paint_funcs_set_color_func(m_paintFuncs, paint_solid, nullptr, nullptr); + hb_paint_funcs_set_push_group_func(m_paintFuncs, + paint_push_group, + nullptr, + nullptr); + hb_paint_funcs_set_pop_group_func(m_paintFuncs, + paint_pop_group, + nullptr, + nullptr); + hb_paint_funcs_set_color_glyph_func(m_paintFuncs, + paint_color_glyph, + nullptr, + nullptr); + hb_paint_funcs_set_linear_gradient_func(m_paintFuncs, + paint_linear_gradient, + nullptr, + nullptr); + hb_paint_funcs_set_radial_gradient_func(m_paintFuncs, + paint_radial_gradient, + nullptr, + nullptr); + hb_paint_funcs_set_sweep_gradient_func(m_paintFuncs, + paint_sweep_gradient, + nullptr, + nullptr); + hb_paint_funcs_set_image_func(m_paintFuncs, paint_image, nullptr, nullptr); + hb_paint_funcs_make_immutable(m_paintFuncs); + + // Initialize color glyph (COLR/CPAL/SBIX/CBDT) support. + hb_face_t* face = hb_font_get_face(font); + m_hasColorLayers = hb_ot_color_has_layers(face); + m_hasColorPaint = hb_ot_color_has_paint(face); + m_hasPNG = hb_ot_color_has_png(face); + if (m_hasColorLayers || m_hasColorPaint) + { + unsigned int colorCount = 0; + hb_ot_color_palette_get_colors(face, 0, 0, &colorCount, nullptr); + if (colorCount > 0) + { + m_paletteColors.resize(colorCount); + hb_ot_color_palette_get_colors(face, + 0, + 0, + &colorCount, + m_paletteColors.data()); + } + } } HBFont::~HBFont() { hb_draw_funcs_destroy(m_drawFuncs); + hb_paint_funcs_destroy(m_paintFuncs); hb_font_destroy(m_font); } @@ -384,6 +792,178 @@ rive::RawPath HBFont::getPath(rive::GlyphID glyph) const return rpath; } +bool HBFont::hasColorGlyphs() const +{ + return m_hasColorLayers || m_hasColorPaint || m_hasPNG; +} + +bool HBFont::isColorGlyph(rive::GlyphID glyph) const +{ + if (!m_hasColorLayers && !m_hasColorPaint && !m_hasPNG) + { + return false; + } + hb_face_t* face = hb_font_get_face(m_font); + // Check COLRv0 layers first. + if (m_hasColorLayers) + { + unsigned int total = + hb_ot_color_glyph_get_layers(face, glyph, 0, nullptr, nullptr); + if (total > 0) + { + return true; + } + } + // Check COLRv1 paint. + if (m_hasColorPaint) + { + if (hb_ot_color_glyph_has_paint(face, glyph)) + { + return true; + } + } + // Check SBIX/CBDT PNG. + if (m_hasPNG) + { + hb_blob_t* blob = hb_ot_color_glyph_reference_png(m_font, glyph); + if (blob != nullptr) + { + bool has = hb_blob_get_length(blob) > 0; + hb_blob_destroy(blob); + return has; + } + } + return false; +} + +size_t HBFont::getColorLayers(rive::GlyphID glyph, + std::vector& out, + rive::ColorInt foreground) const +{ + if (!m_hasColorLayers && !m_hasColorPaint && !m_hasPNG) + { + return 0; + } + + // Check cache first. + auto cacheIt = m_colorLayerCache.find(glyph); + if (cacheIt != m_colorLayerCache.end()) + { + // Copy from cache, but update foreground colors. + for (const auto& cached : cacheIt->second) + { + ColorGlyphLayer layer; + layer.paintType = cached.paintType; + layer.path = cached.path; + layer.useForeground = cached.useForeground; + layer.color = cached.useForeground ? foreground : cached.color; + // Copy gradient data if present. + layer.stops = cached.stops; + layer.x0 = cached.x0; + layer.y0 = cached.y0; + layer.x1 = cached.x1; + layer.y1 = cached.y1; + layer.r0 = cached.r0; + layer.r1 = cached.r1; + layer.startAngle = cached.startAngle; + layer.endAngle = cached.endAngle; + // Copy image data if present. + layer.imageBytes = cached.imageBytes; + layer.imageWidth = cached.imageWidth; + layer.imageHeight = cached.imageHeight; + layer.imageBearingX = cached.imageBearingX; + layer.imageBearingY = cached.imageBearingY; + layer.imageExtentX = cached.imageExtentX; + layer.imageExtentY = cached.imageExtentY; + out.push_back(std::move(layer)); + } + return cacheIt->second.size(); + } + + std::vector layers; + hb_face_t* face = hb_font_get_face(m_font); + + // Try COLRv0 first. + if (m_hasColorLayers) + { + unsigned int layerCount = + hb_ot_color_glyph_get_layers(face, glyph, 0, nullptr, nullptr); + if (layerCount > 0) + { + std::vector hbLayers(layerCount); + hb_ot_color_glyph_get_layers(face, + glyph, + 0, + &layerCount, + hbLayers.data()); + + layers.reserve(layerCount); + for (unsigned int i = 0; i < layerCount; i++) + { + ColorGlyphLayer layer; + hb_font_draw_glyph(m_font, + hbLayers[i].glyph, + m_drawFuncs, + &layer.path); + if (hbLayers[i].color_index == 0xFFFF) + { + layer.useForeground = true; + layer.color = foreground; + } + else + { + layer.useForeground = false; + if (hbLayers[i].color_index < m_paletteColors.size()) + { + layer.color = hbColorToColorInt( + m_paletteColors[hbLayers[i].color_index]); + } + else + { + layer.color = 0xFF000000; + } + } + layers.push_back(std::move(layer)); + } + } + } + + // Fall back to COLRv1 paint if no COLRv0 layers found. + if (layers.empty() && (m_hasColorPaint || m_hasPNG)) + { + // hb_font_paint_glyph handles both COLRv1 and SBIX/CBDT. + // For COLRv1 it calls paint_solid/gradient callbacks; + // for SBIX/CBDT it calls paint_image. + PaintState state; + state.font = m_font; + state.drawFuncs = m_drawFuncs; + state.layers = &layers; + state.foreground = foreground; + + hb_font_paint_glyph(m_font, + glyph, + m_paintFuncs, + &state, + 0, // palette_index + HB_COLOR(0, 0, 0, 255)); // foreground + } + + if (layers.empty()) + { + return 0; + } + + size_t count = layers.size(); + // Cache the result. + m_colorLayerCache[glyph] = layers; + // Move into output. + for (auto& layer : layers) + { + out.push_back(std::move(layer)); + } + return count; +} + /////////////////////////////////////////////////////////// static rive::GlyphRun shape_run(const rive::Unichar text[], @@ -476,8 +1056,14 @@ static void perform_fallback(rive::rcp fallbackFont, { ++endI; } + auto textStart = orig.textIndices[startI]; - auto textCount = orig.textIndices[endI - 1] - textStart + 1; + auto textCount = + endI == count + ? origTextRun.unicharCount - + (orig.textIndices[startI] - orig.textIndices[0]) + : orig.textIndices[endI] - textStart; + auto tr = rive::TextRun{ fallbackFont, orig.size, @@ -539,7 +1125,7 @@ void HBFont::shapeFallbackRun(rive::SimpleArrayBuilder& gruns, gruns, text, gr, - originalTextRun, + textRun, fallbackIndex + 1); } else if (gr.glyphs.size() > 0) @@ -697,6 +1283,34 @@ rive::SimpleArray HBFont::onShapeText( auto gr = shape_run(&text[unicharIndex], tr, unicharIndex); unicharIndex += tr.unicharCount; + // Handle dual-presentation characters (e.g. ☠ U+2620) that have a + // text-form glyph in the current font but are followed by U+FE0F + // (VARIATION SELECTOR-16), which requests emoji presentation. + // The standard fallback only fires for glyph ID 0, so we explicitly + // force such glyphs to 0 here — but only when a color emoji + // fallback font is actually available for that codepoint, to avoid + // regressing the rendering when no emoji font is loaded. + if (gFallbackProc && gFallbackProcEnabled && !hasColorGlyphs()) + { + for (size_t gi = 0; gi < gr.glyphs.size(); ++gi) + { + if (gr.glyphs[gi] != 0) + { + auto textPos = gr.textIndices[gi]; + if (textPos + 1 < text.size() && + text[textPos + 1] == 0xFE0F) + { + auto emojiFont = + gFallbackProc(text[textPos], 0, this); + if (emojiFont && emojiFont->hasColorGlyphs()) + { + gr.glyphs[gi] = 0; + } + } + } + } + } + auto end = gr.glyphs.end(); auto iter = std::find(gr.glyphs.begin(), end, 0); if (!gFallbackProc || iter == end || !gFallbackProcEnabled) diff --git a/thirdparty/rive/source/text/font_hb_apple.mm b/thirdparty/rive/source/text/font_hb_apple.mm index b741ffb3b..de0b15cd4 100644 --- a/thirdparty/rive/source/text/font_hb_apple.mm +++ b/thirdparty/rive/source/text/font_hb_apple.mm @@ -8,6 +8,7 @@ #include // #endif +#include "rive/math/math_types.hpp" #include "rive/text_engine.hpp" #include "rive/text/font_hb.hpp" #include "rive/text/utf.hpp" @@ -21,15 +22,16 @@ class CoreTextHBFont : public HBFont { private: + CTFontRef m_ctFont; bool m_useSystemShaper; - uint16_t m_weight; - uint8_t m_width; public: CoreTextHBFont(hb_font_t* font, + CTFontRef ctFont, bool useSystemShaper, uint16_t weight, uint8_t width); + ~CoreTextHBFont() override; void shapeFallbackRun(rive::SimpleArrayBuilder& gruns, const rive::Unichar text[], @@ -41,24 +43,115 @@ void shapeFallbackRun(rive::SimpleArrayBuilder& gruns, rive::RawPath getPath(rive::GlyphID glyph) const override; }; +struct HBCTFaceData +{ + CTFontRef ctFont; +}; + +static void hb_ct_face_data_destroy(void* userData) +{ + auto data = static_cast(userData); + if (data != nullptr) + { + if (data->ctFont != nullptr) + { + CFRelease(data->ctFont); + } + delete data; + } +} + +static hb_blob_t* hb_ct_reference_table(hb_face_t*, + hb_tag_t tag, + void* userData) +{ + auto data = static_cast(userData); + if (data == nullptr || data->ctFont == nullptr) + { + return hb_blob_get_empty(); + } + + CFDataRef table = CTFontCopyTable(data->ctFont, + static_cast(tag), + kCTFontTableOptionNoOptions); + if (table == nullptr) + { + return hb_blob_get_empty(); + } + + const char* bytes = reinterpret_cast(CFDataGetBytePtr(table)); + const auto length = static_cast(CFDataGetLength(table)); + + return hb_blob_create(bytes, + length, + HB_MEMORY_MODE_READONLY, + (void*)table, + [](void* blobUserData) { + CFRelease(static_cast(blobUserData)); + }); +} + +static hb_font_t* hb_font_create_from_ct_tables(CTFontRef ctFont) +{ + if (ctFont == nullptr) + { + return nullptr; + } + + auto* faceData = new HBCTFaceData{(CTFontRef)CFRetain(ctFont)}; + hb_face_t* face = hb_face_create_for_tables( + hb_ct_reference_table, faceData, hb_ct_face_data_destroy); + if (face == nullptr) + { + hb_ct_face_data_destroy(faceData); + return nullptr; + } + + const unsigned int upem = (unsigned int)CTFontGetUnitsPerEm(ctFont); + if (upem > 0) + { + hb_face_set_upem(face, upem); + } + + hb_font_t* font = hb_font_create(face); + hb_face_destroy(face); + return font; +} + rive::rcp HBFont::FromSystem(void* systemFont, bool useSystemShaper, uint16_t weight, uint8_t width) { - auto ctFont = (CTFontRef)systemFont; + CTFontRef ctFont = (CTFontRef)systemFont; + bool isCopy = false; if (CTFontGetSize(ctFont) != kStdScale) { // Need the font sized at our magic scale so we can extract normalized // path data. ctFont = CTFontCreateCopyWithAttributes(ctFont, kStdScale, nullptr, nullptr); + isCopy = true; + } + + hb_font_t* font = hb_font_create_from_ct_tables(ctFont); + if (font == nullptr) + { + font = hb_coretext_font_create(ctFont); } - auto font = hb_coretext_font_create(ctFont); if (font) { - return rive::rcp( - new CoreTextHBFont(font, useSystemShaper, weight, width)); + auto riveFont = rive::rcp( + new CoreTextHBFont(font, ctFont, useSystemShaper, weight, width)); + if (isCopy) + { + CFRelease(ctFont); + } + return riveFont; + } + if (isCopy) + { + CFRelease(ctFont); } return nullptr; } @@ -220,13 +313,30 @@ static void apply_element(void* ctx, const CGPathElement* element) } } +static bool ct_extract_glyph_path(CTFontRef ctFont, + rive::GlyphID glyph, + rive::RawPath* outPath) +{ + if (ctFont == nullptr) + { + return false; + } + AutoCF cgPath = CTFontCreatePathForGlyph(ctFont, glyph, nullptr); + if (!cgPath) + { + return false; + } + CGPathApply(cgPath.get(), outPath, apply_element); + return true; +} + CoreTextHBFont::CoreTextHBFont(hb_font_t* font, + CTFontRef ctFont, bool useSystemShaper, uint16_t weight, uint8_t width) : + m_ctFont(ctFont ? (CTFontRef)CFRetain(ctFont) : nullptr), m_useSystemShaper(useSystemShaper), - m_weight(weight), - m_width(width), HBFont(font) { hb_variation_t variation_data[2]; @@ -237,6 +347,14 @@ static void apply_element(void* ctx, const CGPathElement* element) hb_font_set_variations(font, variation_data, 2); } +CoreTextHBFont::~CoreTextHBFont() +{ + if (m_ctFont) + { + CFRelease(m_ctFont); + } +} + void CoreTextHBFont::shapeFallbackRun( rive::SimpleArrayBuilder& gruns, const rive::Unichar text[], @@ -252,14 +370,16 @@ static void apply_element(void* ctx, const CGPathElement* element) return; } - CTFontRef ctFont = hb_coretext_font_get_ct_font(m_font); + CTFontRef ctFont = m_ctFont; AutoUTF16 utf16(&text[textStart], textRun.unicharCount); + CFIndex utf16Length = + rive::math::lossless_numeric_cast(utf16.array.size()); - assert(utf16.array.size() == textRun.unicharCount); + assert(utf16.array.size() >= textRun.unicharCount); AutoCF string = CFStringCreateWithCharactersNoCopy( - nullptr, utf16.array.data(), utf16.array.size(), kCFAllocatorNull); + nullptr, utf16.array.data(), utf16Length, kCFAllocatorNull); AutoCF attr = CFDictionaryCreateMutable(kCFAllocatorDefault, @@ -269,10 +389,11 @@ static void apply_element(void* ctx, const CGPathElement* element) CFDictionaryAddValue(attr.get(), kCTFontAttributeName, ctFont); AutoCF attrString = - CFAttributedStringCreateMutable(kCFAllocatorDefault, - textRun.unicharCount); + CFAttributedStringCreateMutable(kCFAllocatorDefault, utf16Length); CFAttributedStringReplaceString( attrString.get(), CFRangeMake(0, 0), string.get()); + CFAttributedStringSetAttributes( + attrString.get(), CFRangeMake(0, utf16Length), attr.get(), false); AutoCF level_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &textRun.level); @@ -297,25 +418,11 @@ static void apply_element(void* ctx, const CGPathElement* element) { CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(run_array, runIndex); - if (auto count = CTRunGetGlyphCount(run)) + if (CFIndex count = CTRunGetGlyphCount(run)) { rive::GlyphRun gr(count); - - // Because CoreText will automatically do its own font fallbacks - // we need to detect that it's trying to use a different font. - CFDictionaryRef attributes = CTRunGetAttributes(run); - CTFontRef runCtFont = static_cast( - CFDictionaryGetValue(attributes, kCTFontAttributeName)); - const float scale = textRun.size / (float)CTFontGetSize(runCtFont); - if (!CFEqual(runCtFont, ctFont)) - { - gr.font = HBFont::FromSystem( - (void*)runCtFont, true, m_weight, m_width); - } - else - { - gr.font = textRun.font; - } + const float scale = textRun.size / (float)CTFontGetSize(ctFont); + gr.font = textRun.font; gr.size = textRun.size; gr.lineHeight = textRun.lineHeight; gr.letterSpacing = textRun.letterSpacing; @@ -334,15 +441,17 @@ static void apply_element(void* ctx, const CGPathElement* element) CTRunGetAdvances(run, {0, count}, advances.data()); CTRunGetStringIndices(run, {0, count}, indices.data()); - int reverseIndex = count - 1; + CFIndex reverseIndex = count - 1; for (CFIndex i = 0; i < count; ++i) { - int glyphIndex = isEvenLevel ? i : reverseIndex; + CFIndex glyphIndex = isEvenLevel ? i : reverseIndex; float advance = (float)(advances[i].width * scale) + textRun.letterSpacing; gr.xpos[glyphIndex] = gr.advances[glyphIndex] = advance; gr.textIndices[glyphIndex] = - textStart + indices[i]; // utf16 offsets, will fix-up later + rive::math::lossless_numeric_cast( + textStart + + indices[i]); // utf16 offsets, will fix-up later gr.offsets[glyphIndex] = rive::Vec2D(0.0f, 0.0f); reverseIndex--; @@ -360,18 +469,10 @@ static void apply_element(void* ctx, const CGPathElement* element) // too. if (m_useSystemShaper) { - CTFontRef ctFont = hb_coretext_font_get_ct_font(m_font); - if (ctFont) + rive::RawPath ctPath; + if (ct_extract_glyph_path(m_ctFont, glyph, &ctPath)) { - AutoCF cgPath = - CTFontCreatePathForGlyph(ctFont, glyph, nullptr); - - if (cgPath) - { - rive::RawPath rpath; - CGPathApply(cgPath.get(), &rpath, apply_element); - return rpath; - } + return ctPath; } } @@ -381,18 +482,10 @@ static void apply_element(void* ctx, const CGPathElement* element) // glyphs. Try getting them from the system. if (rpath.empty() && !m_useSystemShaper) { - CTFontRef ctFont = hb_coretext_font_get_ct_font(m_font); - if (ctFont) + rive::RawPath ctPath; + if (ct_extract_glyph_path(m_ctFont, glyph, &ctPath)) { - AutoCF cgPath = - CTFontCreatePathForGlyph(ctFont, glyph, nullptr); - - if (cgPath) - { - rive::RawPath rpath; - CGPathApply(cgPath.get(), &rpath, apply_element); - return rpath; - } + return ctPath; } } return rpath; diff --git a/thirdparty/rive/source/text/fully_shaped_text.cpp b/thirdparty/rive/source/text/fully_shaped_text.cpp index c532dbf54..d9b9f3229 100644 --- a/thirdparty/rive/source/text/fully_shaped_text.cpp +++ b/thirdparty/rive/source/text/fully_shaped_text.cpp @@ -87,7 +87,6 @@ void FullyShapedText::shape(Span text, isEllipsisLineLast = lastLineIndex == ellipsisLine; int32_t lineIndex = 0; - paragraphIndex = 0; m_bounds = AABB(0.0f, minY, measuredWidth, std::max(minY, y - paragraphSpacing)); diff --git a/thirdparty/rive/source/text/glyph_lookup.cpp b/thirdparty/rive/source/text/glyph_lookup.cpp index a30f20dd0..acb46697f 100644 --- a/thirdparty/rive/source/text/glyph_lookup.cpp +++ b/thirdparty/rive/source/text/glyph_lookup.cpp @@ -6,9 +6,9 @@ using namespace rive; void GlyphLookup::compute(Span text, const SimpleArray& shape) { - size_t codeUnitCount = text.size(); - m_glyphIndices.resize(codeUnitCount + 1); - // Build a mapping of codePoints to glyphs indices. + size_t codePointCount = text.size(); + m_glyphIndices.resize(codePointCount + 1); + // Build a mapping of codepoints to glyph indices. uint32_t glyphIndex = 0; uint32_t lastTextIndex = 0; for (const Paragraph& paragraph : shape) @@ -28,15 +28,15 @@ void GlyphLookup::compute(Span text, } } } - for (size_t i = lastTextIndex; i < codeUnitCount; i++) + for (size_t i = lastTextIndex; i < codePointCount; i++) { m_glyphIndices[i] = glyphIndex - 1; } // Store a fake unreachable glyph at the end to allow selecting the last // one. - m_glyphIndices[codeUnitCount] = - codeUnitCount == 0 ? 0 : m_glyphIndices[codeUnitCount - 1] + 1; + m_glyphIndices[codePointCount] = + codePointCount == 0 ? 0 : m_glyphIndices[codePointCount - 1] + 1; } uint32_t GlyphLookup::count(uint32_t index) const @@ -53,6 +53,29 @@ uint32_t GlyphLookup::count(uint32_t index) const return count; } +uint32_t GlyphLookup::glyphStart(uint32_t index) const +{ + if (index == 0 || index >= (uint32_t)m_glyphIndices.size()) + { + return index; + } + uint32_t value = m_glyphIndices[index]; + while (index > 0 && m_glyphIndices[index - 1] == value) + { + index--; + } + return index; +} + +bool GlyphLookup::isGlyphBoundary(uint32_t index) const +{ + if (index == 0 || index >= (uint32_t)m_glyphIndices.size()) + { + return true; + } + return m_glyphIndices[index] != m_glyphIndices[index - 1]; +} + float GlyphLookup::advanceFactor(int32_t codePointIndex, bool inv) const { if (codePointIndex < 0 || codePointIndex >= (int32_t)m_glyphIndices.size()) diff --git a/thirdparty/rive/source/text/line_breaker.cpp b/thirdparty/rive/source/text/line_breaker.cpp index 2577ccc68..e7501ffb5 100644 --- a/thirdparty/rive/source/text/line_breaker.cpp +++ b/thirdparty/rive/source/text/line_breaker.cpp @@ -164,6 +164,71 @@ class RunIterator { m_index--; } + // If there are any word-joiners, do not break on them and find the + // closest index that does not wrap a WJ + if (m_run->joiners.size() > 0 && m_run->textIndices[m_index] > 0) + { + auto joiners = m_run->joiners; + auto wordJoinerIndex = m_run->textIndices[m_index] - 1; + size_t mid = 0; + size_t start = 0; + size_t end = joiners.size(); + // If this condition is not met, skip to avoid binary search + if (wordJoinerIndex >= joiners[start] && + wordJoinerIndex < joiners[end - 1]) + { + while (start < end) + { + mid = (start + end) >> 1; + auto joinerCandidate = joiners[mid]; + if (joinerCandidate == wordJoinerIndex) + { + // we found that the previous text index is a joiner + // now let's clean all indexes that are pointing to word + // joiners + bool isJoiner = true; + auto currentJoinerIndex = mid; + while (isJoiner) + { + if (m_index == 0) + { + return back(); + } + // If the text index of the previous glyph is a + // joiner, we need to skip it + if (m_run->textIndices[m_index - 1] == + joiners[currentJoinerIndex]) + { + m_index--; + if (currentJoinerIndex > 0) + { + // we keep moving up the joiners list in + // case there are consecutive word joiners + currentJoinerIndex--; + } + else + { + isJoiner = false; + } + } + else + { + isJoiner = false; + } + } + return back(); + } + if (joinerCandidate < wordJoinerIndex) + { + start = mid + 1; + } + else + { + end = mid; + } + } + } + } return true; } @@ -186,6 +251,71 @@ class RunIterator { m_index++; } + if (m_run->joiners.size() > 0 && m_index < m_run->textIndices.size()) + { + auto joiners = m_run->joiners; + auto wordJoinerIndex = m_run->textIndices[m_index]; + size_t mid = 0; + size_t start = 0; + size_t end = joiners.size(); + // If this condition is not met, skip to avoid binary search + if (wordJoinerIndex >= joiners[start] && + wordJoinerIndex < joiners[end - 1]) + { + + while (start < end) + { + mid = (start + end) >> 1; + auto joinerCandidate = joiners[mid]; + if (joinerCandidate == wordJoinerIndex) + { + // we found that the next text index is a joiner + // now let's clean all indexes that are pointing to word + // joiners + bool isJoiner = true; + auto currentJoinerIndex = mid; + while (isJoiner) + { + if (m_index == m_run->glyphs.size()) + { + return forward(); + } + // If the text index of the current glyph is a + // joiner, we need to skip it + if (currentJoinerIndex < joiners.size() && + m_run->textIndices[m_index] == + joiners[currentJoinerIndex]) + { + m_index++; + if (currentJoinerIndex < joiners.size()) + { + // we keep moving down the joiners list in + // case there are consecutive word joiners + currentJoinerIndex++; + } + else + { + isJoiner = false; + } + } + else + { + isJoiner = false; + } + } + return forward(); + } + if (joinerCandidate < wordJoinerIndex) + { + start = mid + 1; + } + else + { + end = mid; + } + } + } + } return true; } @@ -217,15 +347,15 @@ SimpleArray GlyphLine::BreakLines(Span runs, bool advanceWord = false; - // We iterate the breaks list with a WordMarker helper which is basically an - // iterator. The breaks lists contains tightly packed start/end indices per - // run. So the first valid word is at break index 0,1 (per run). Because a - // run can be created with no valid breaks, we start the word iterator at a - // negative index and attempt to move it to the first valid index (which - // could be in the Nth run in the paragraph). If that fails, we know we have - // no words to break in the entire paragraph and can early out. See how - // WordMarker::next works and notice how we also use it below in this same - // method. + // We iterate the breaks list with a WordMarker helper which is + // basically an iterator. The breaks lists contains tightly packed + // start/end indices per run. So the first valid word is at break index + // 0,1 (per run). Because a run can be created with no valid breaks, we + // start the word iterator at a negative index and attempt to move it to + // the first valid index (which could be in the Nth run in the + // paragraph). If that fails, we know we have no words to break in the + // entire paragraph and can early out. See how WordMarker::next works + // and notice how we also use it below in this same method. WordMarker start = {runs.begin(), (uint32_t)-2}; WordMarker end = {runs.begin(), (uint32_t)-1}; if (!start.next(runs) || !end.next(runs)) @@ -273,8 +403,8 @@ SimpleArray GlyphLine::BreakLines(Span runs, { uint32_t startRunIndex = (uint32_t)(start.run - runs.begin()); - // A whole word overflowed, break until we can no longer break (or - // it fits). + // A whole word overflowed, break until we can no longer break + // (or it fits). if (line.startRunIndex == startRunIndex && line.startGlyphIndex == startBreakIndex) { diff --git a/thirdparty/rive/source/text/raw_text.cpp b/thirdparty/rive/source/text/raw_text.cpp index 29b74fbc6..423be2bb2 100644 --- a/thirdparty/rive/source/text/raw_text.cpp +++ b/thirdparty/rive/source/text/raw_text.cpp @@ -2,6 +2,7 @@ #include "rive/text/raw_text.hpp" #include "rive/text_engine.hpp" #include "rive/factory.hpp" +#include "rive/shapes/paint/color.hpp" using namespace rive; @@ -13,7 +14,8 @@ void RawText::append(const std::string& text, rcp font, float size, float lineHeight, - float letterSpacing) + float letterSpacing, + ColorInt foregroundColor) { int styleIndex = 0; for (RenderStyle& style : m_styles) @@ -24,9 +26,13 @@ void RawText::append(const std::string& text, } styleIndex++; } - if (styleIndex == m_styles.size()) + if (styleIndex == (int)m_styles.size()) { - m_styles.push_back({paint, true}); + m_styles.emplace_back(); + auto& style = m_styles.back(); + style.paint = paint; + style.isEmpty = true; + style.foregroundColor = foregroundColor; } m_styled.append(font, size, lineHeight, letterSpacing, text, styleIndex); m_dirty = true; @@ -112,6 +118,7 @@ void RawText::update() style.isEmpty = true; } m_renderStyles.clear(); + m_drawCommands.clear(); if (m_styled.empty()) { return; @@ -189,7 +196,6 @@ void RawText::update() isEllipsisLineLast = lastLineIndex == ellipsisLine; int lineIndex = 0; - paragraphIndex = 0; switch (m_sizing) { case TextSizing::autoWidth: @@ -292,8 +298,6 @@ void RawText::update() GlyphID glyphId = run->glyphs[glyphIndex]; float advance = run->advances[glyphIndex]; - RawPath path = font->getPath(glyphId); - assert(run->styleId < m_styles.size()); RenderStyle* style = &m_styles[run->styleId]; assert(style != nullptr); @@ -306,15 +310,32 @@ void RawText::update() renderY + offset.y); x += advance; - style->path.addPathClockwise(path, &transform); - if (style->isEmpty) + if (font->isColorGlyph(glyphId)) + { + RawTextDrawCommand cmd; + cmd.type = RawTextDrawCommand::kColorGlyph; + cmd.colorGlyph = {run->font, + glyphId, + transform, + style->foregroundColor}; + m_drawCommands.push_back(std::move(cmd)); + } + else { - // This was the first path added to the style, so let's mark - // it in our draw list. - style->isEmpty = false; + RawPath path = font->getPath(glyphId); + style->path.addPathClockwise(path, &transform); - m_renderStyles.push_back(style); + if (style->isEmpty) + { + style->isEmpty = false; + m_renderStyles.push_back(style); + + RawTextDrawCommand cmd; + cmd.type = RawTextDrawCommand::kStylePath; + cmd.style = style; + m_drawCommands.push_back(std::move(cmd)); + } } } if (lineIndex == ellipsisLine) @@ -354,12 +375,41 @@ void RawText::render(Renderer* renderer, rcp paint) renderer->save(); renderer->clipPath(m_clipRenderPath.get()); } - for (auto style : m_renderStyles) + for (auto& cmd : m_drawCommands) { - auto renderPaint = paint ? paint.get() : style->paint.get(); - if (renderPaint != nullptr) + if (cmd.type == RawTextDrawCommand::kStylePath) { - renderer->drawPath(style->path.renderPath(m_factory), renderPaint); + auto renderPaint = paint ? paint.get() : cmd.style->paint.get(); + if (renderPaint != nullptr) + { + renderer->drawPath(cmd.style->path.renderPath(m_factory), + renderPaint); + } + } + else + { + // Draw color glyph layers. + std::vector layers; + auto& info = cmd.colorGlyph; + size_t count = info.font->getColorLayers(info.glyphId, + layers, + info.foregroundColor); + if (count > 0) + { + renderer->save(); + renderer->transform(info.transform); + for (auto& layer : layers) + { + auto renderPath = + m_factory->makeRenderPath(layer.path, + FillRule::nonZero); + auto layerPaint = m_factory->makeRenderPaint(); + layerPaint->style(RenderPaintStyle::fill); + layerPaint->color(layer.color); + renderer->drawPath(renderPath.get(), layerPaint.get()); + } + renderer->restore(); + } } } if (m_overflow == TextOverflow::clipped && m_clipRenderPath) diff --git a/thirdparty/rive/source/text/raw_text_input.cpp b/thirdparty/rive/source/text/raw_text_input.cpp index be6bb2272..d933c66bf 100644 --- a/thirdparty/rive/source/text/raw_text_input.cpp +++ b/thirdparty/rive/source/text/raw_text_input.cpp @@ -50,7 +50,6 @@ void RawTextInput::draw(Factory* factory, void RawTextInput::backspace(int32_t direction) { Cursor startingCursor = m_cursor; - int32_t offset = direction > 0 ? 0 : -1; if (!m_cursor.isCollapsed()) { erase(); @@ -59,15 +58,37 @@ void RawTextInput::backspace(int32_t direction) } m_idealCursorX = -1.0f; - auto index = m_cursor.first().codePointIndex(offset); - - if (index >= m_text.size() - 1) + ensureShape(); + const auto& glyphLookup = m_shape.glyphLookup(); + if (direction > 0) { - return; + // Delete forward: erase the full glyph cluster at cursor position. + auto index = m_cursor.first().codePointIndex(); + if (index >= m_text.size() - 1) + { + return; + } + uint32_t clusterCount = glyphLookup.count(index); + m_text.erase(m_text.begin() + index, + m_text.begin() + index + clusterCount); + auto position = CursorPosition(index); + m_cursor = Cursor::collapsed(position); + } + else + { + // Backspace: erase the full glyph cluster before cursor position. + auto index = m_cursor.first().codePointIndex(); + if (index == 0) + { + return; + } + uint32_t clusterStart = glyphLookup.glyphStart(index - 1); + uint32_t clusterCount = glyphLookup.count(clusterStart); + m_text.erase(m_text.begin() + clusterStart, + m_text.begin() + clusterStart + clusterCount); + auto position = CursorPosition(clusterStart); + m_cursor = Cursor::collapsed(position); } - m_text.erase(m_text.begin() + index); - auto position = CursorPosition(index); - m_cursor = Cursor::collapsed(position); flag(Flags::shapeDirty | Flags::measureDirty | Flags::selectionDirty); captureJournalEntry(startingCursor); } @@ -201,17 +222,10 @@ void RawTextInput::computeVisualPositionFromCursor() m_cursorVisualPosition = cursorVisualPosition(m_cursor.end()); } -RawTextInput::Flags RawTextInput::update(Factory* factory) +void RawTextInput::ensureShape() { - Flags updated = Flags::none; - if (m_textRun.font == nullptr) - { - return updated; - } - bool updateTextPath = false; if (unflag(Flags::shapeDirty)) { - updated |= Flags::shapeDirty; m_textRun.unicharCount = (uint32_t)m_text.size(); m_shape.shape(m_text, Span(&m_textRun, 1), @@ -223,6 +237,21 @@ RawTextInput::Flags RawTextInput::update(Factory* factory) m_origin, m_overflow, m_paragraphSpacing); + } +} + +RawTextInput::Flags RawTextInput::update(Factory* factory) +{ + Flags updated = Flags::none; + if (m_textRun.font == nullptr) + { + return updated; + } + bool updateTextPath = false; + if (flagged(Flags::shapeDirty)) + { + updated |= Flags::shapeDirty; + ensureShape(); updateTextPath = true; } if (unflag(Flags::selectionDirty)) @@ -455,6 +484,7 @@ void RawTextInput::cursorHorizontal(int32_t offset, CursorBoundary boundary, bool select) { + ensureShape(); m_idealCursorX = -1.0f; CursorPosition end = m_cursor.end(); @@ -462,9 +492,28 @@ void RawTextInput::cursorHorizontal(int32_t offset, switch (boundary) { case CursorBoundary::character: - position = - CursorPosition::atIndex(end.codePointIndex(offset), m_shape); + { + const auto& glyphLookup = m_shape.glyphLookup(); + uint32_t nextIndex = end.codePointIndex(offset); + // Skip over interior codepoints of multi-codepoint glyphs. + if (offset > 0) + { + while (nextIndex < (uint32_t)(m_text.size() - 1) && + !glyphLookup.isGlyphBoundary(nextIndex)) + { + nextIndex++; + } + } + else + { + while (nextIndex > 0 && !glyphLookup.isGlyphBoundary(nextIndex)) + { + nextIndex--; + } + } + position = CursorPosition::atIndex(nextIndex, m_shape); break; + } case CursorBoundary::line: { auto line = orderedLine(end); @@ -656,6 +705,7 @@ void RawTextInput::cursorRight(CursorBoundary boundary, bool select) void RawTextInput::cursorUp(bool select) { + ensureShape(); if (m_idealCursorX == -1.0f) { m_idealCursorX = m_cursorVisualPosition.x(); @@ -680,6 +730,7 @@ void RawTextInput::cursorUp(bool select) void RawTextInput::cursorDown(bool select) { + ensureShape(); if (m_idealCursorX == -1.0f) { m_idealCursorX = m_cursorVisualPosition.x(); @@ -705,6 +756,7 @@ void RawTextInput::cursorDown(bool select) void RawTextInput::moveCursorTo(Vec2D translation, bool select) { + ensureShape(); m_idealCursorX = -1.0f; auto position = CursorPosition::fromTranslation(translation, m_shape); @@ -763,6 +815,21 @@ void RawTextInput::text(std::string value) captureJournalEntry(startingCursor); } +void RawTextInput::textPreserveCursor(std::string value) +{ + Cursor startingCursor = m_cursor; + m_idealCursorX = -1.0f; + setTextPrivate(value); + uint32_t maxIndex = static_cast(length()); + CursorPosition start( + std::min(startingCursor.start().codePointIndex(), maxIndex)); + CursorPosition end( + std::min(startingCursor.end().codePointIndex(), maxIndex)); + m_cursor = Cursor(start, end); + flag(Flags::shapeDirty | Flags::measureDirty | Flags::selectionDirty); + captureJournalEntry(startingCursor); +} + size_t RawTextInput::length() const { if (empty()) @@ -818,12 +885,12 @@ void RawTextInput::redo() bool RawTextInput::flagged(RawTextInput::Flags mask) const { - return m_flags & mask; + return enums::any_flag_set(m_flags, mask); } bool RawTextInput::unflag(RawTextInput::Flags mask) { - if (m_flags & mask) + if (enums::any_flag_set(m_flags, mask)) { m_flags &= ~mask; return true; @@ -863,14 +930,14 @@ AABB RawTextInput::measure(float maxWidth, float maxHeight) if (!m_measuringShape) { force = true; - m_measuringShape = rivestd::make_unique(); + m_measuringShape = std::make_unique(); } if (unflag(Flags::measureDirty) || force) { m_textRun.unicharCount = (uint32_t)m_text.size(); m_measuringShape->shape(m_text, Span(&m_textRun, 1), - TextSizing::autoHeight, + m_sizing, maxWidth, maxHeight, m_align, diff --git a/thirdparty/rive/source/text/text.cpp b/thirdparty/rive/source/text/text.cpp index 3f88c99d4..ebd79287f 100644 --- a/thirdparty/rive/source/text/text.cpp +++ b/thirdparty/rive/source/text/text.cpp @@ -9,11 +9,139 @@ using namespace rive; #include "rive/text/text_value_run.hpp" #include "rive/text/text_modifier_group.hpp" #include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/color.hpp" +#include "rive/shapes/paint/blend_mode.hpp" +#include "rive/shapes/paint/image_sampler.hpp" +#include "rive/viewmodel/viewmodel_instance_string.hpp" #include "rive/artboard.hpp" #include "rive/factory.hpp" #include "rive/clip_result.hpp" +#include "rive/generated/core_registry.hpp" #include +TextValueRunProperty::TextValueRunProperty( + Core* textValueRun, + TextValueRunListener* textValueRunListener, + ViewModelInstanceValue* instanceValue, + uint16_t propertyKey, + SymbolType symbolType) : + PropertySymbolDependentSingle(textValueRun, + textValueRunListener, + instanceValue, + propertyKey), + m_symbolType(symbolType) +{} + +void TextValueRunProperty::writeValue() +{ + switch (m_symbolType) + { + case SymbolType::textContent: + CoreRegistry::setString( + m_coreObject, + m_propertyKey, + m_instanceValue->as() + ->propertyValue()); + break; + case SymbolType::textStyle: + { + auto stylePaints = + static_cast(m_coreObjectListener) + ->text() + ->textStylePaints(); + auto styleValue = + m_instanceValue->as()->propertyValue(); + for (size_t i = 0; i < stylePaints.size(); i++) + { + auto stylePaint = stylePaints[i]; + if (stylePaint->name() == styleValue) + { + m_coreObject->as()->style(stylePaint); + break; + } + else if (i == 0) + { + m_coreObject->as()->style(stylePaint); + } + } + break; + } + default: + break; + } +} + +TextValueRunListener::TextValueRunListener(TextValueRun* textValueRun, + rcp instance, + Text* text) : + CoreObjectListener(textValueRun, instance), m_text(text) +{ + createProperties(); +} + +void TextValueRunListener::markDirty() { m_text->markShapeDirty(); } + +void TextValueRunListener::createProperties() +{ + createPropertyListener(SymbolType::textStyle); + createPropertyListener(SymbolType::textContent); +} + +TextValueRunProperty* TextValueRunListener::createSinglePropertyListener( + SymbolType symbolType) +{ + uint16_t propertyKey = 0; + switch (symbolType) + { + case SymbolType::textStyle: + propertyKey = TextValueRunBase::styleIdPropertyKey; + break; + case SymbolType::textContent: + propertyKey = TextValueRunBase::textPropertyKey; + break; + default: + break; + } + auto prop = m_instance->propertyValue(symbolType); + if (prop != nullptr && prop->is()) + { + auto vpl = new TextValueRunProperty(m_core, + this, + prop, + propertyKey, + symbolType); + return vpl; + } + return nullptr; +} + +void TextValueRunListener::createPropertyListener(SymbolType symbolType) +{ + TextValueRunProperty* listener = nullptr; + switch (symbolType) + { + case SymbolType::textStyle: + case SymbolType::textContent: + listener = createSinglePropertyListener(symbolType); + break; + default: + break; + } + if (listener != nullptr) + { + listener->writeValue(); + m_properties.push_back(listener); + } +} + +Text::~Text() +{ + for (auto& textValueRun : m_valueRunListeners) + { + delete textValueRun; + } +} + Vec2D Text::measureLayout(float width, LayoutMeasureMode widthMode, float height, @@ -64,8 +192,9 @@ void Text::clearRenderStyles() style->rewindPath(); } m_renderStyles.clear(); + m_drawCommands.clear(); - for (TextValueRun* textValueRun : m_runs) + for (TextValueRun* textValueRun : m_allRuns) { textValueRun->resetHitTest(); } @@ -80,6 +209,7 @@ TextBoundsInfo Text::computeBoundsInfo() float y = 0.0f; float minY = 0.0f; float maxWidth = 0.0f; + float ellipsedHeight = 0; if (textOrigin() == TextOrigin::baseline && !m_lines.empty() && !m_lines[0].empty()) { @@ -92,8 +222,7 @@ TextBoundsInfo Text::computeBoundsInfo() // Find the line to put the ellipsis on (line before the one that // overflows). bool wantEllipsis = overflow() == TextOverflow::ellipsis && - effectiveSizing() == TextSizing::fixed && - verticalAlign() == VerticalTextAlign::top; + effectiveSizing() == TextSizing::fixed; int lastLineIndex = -1; for (const SimpleArray& paragraphLines : m_lines) @@ -112,6 +241,7 @@ TextBoundsInfo Text::computeBoundsInfo() lastLineIndex++; if (wantEllipsis && y + line.bottom <= effectiveHeight()) { + ellipsedHeight = y + line.bottom; ellipsisLine++; } } @@ -122,12 +252,12 @@ TextBoundsInfo Text::computeBoundsInfo() } y += paragraphSpace; } - auto totalHeight = y; if (wantEllipsis && ellipsisLine == -1) { // Nothing fits, just show the first line and ellipse it. ellipsisLine = 0; } + auto totalHeight = ellipsisLine > 0 ? ellipsedHeight : y; isEllipsisLineLast = lastLineIndex == ellipsisLine; return { minY, @@ -342,8 +472,6 @@ void Text::buildRenderStyles() GlyphID glyphId = run->glyphs[glyphIndex]; float advance = run->advances[glyphIndex]; - RawPath path = font->getPath(glyphId); - // Step 6.1: translate to the glyph's origin and scale. Vec2D curPos(curX, renderY); float centerX = advance / 2.0f; @@ -385,21 +513,41 @@ void Text::buildRenderStyles() curPos.y + offset.y) * pathTransform; - path.transformInPlace(pathTransform); - - assert(run->styleId < m_runs.size()); - TextValueRun* textValueRun = m_runs[run->styleId]; + assert(run->styleId < m_allRuns.size()); + TextValueRun* textValueRun = m_allRuns[run->styleId]; TextStylePaint* style = textValueRun->style(); - // TextValueRun::onAddedDirty botches loading if it cannot - // resolve a style, so we're confident we have a style here. assert(style != nullptr); - if (style->addPath(path, opacity)) + // Check for color glyph (emoji) -- draw individually + // with per-layer colors instead of accumulating. + if (font->isColorGlyph(glyphId)) { - // This was the first path added to the style, so let's - // mark it in our draw list. - m_renderStyles.push_back(style); - style->propagateOpacity(renderOpacity()); + TextDrawCommand cmd; + cmd.type = TextDrawCommand::kColorGlyph; + cmd.colorGlyph = {run->font, + glyphId, + pathTransform, + style->foregroundColor(), + opacity}; + m_drawCommands.push_back(std::move(cmd)); + } + else + { + RawPath path = font->getPath(glyphId); + path.transformInPlace(pathTransform); + + if (style->addPath(path, opacity)) + { + // This was the first path added to the style, so + // let's mark it in our draw list. + m_renderStyles.push_back(style); + style->propagateOpacity(renderOpacity()); + + TextDrawCommand cmd; + cmd.type = TextDrawCommand::kStylePath; + cmd.style = style; + m_drawCommands.push_back(std::move(cmd)); + } } // Bounds of the glyph @@ -486,7 +634,7 @@ void Text::buildRenderStyles() #endif // Step 8: cleanup - for (TextValueRun* textValueRun : m_runs) + for (TextValueRun* textValueRun : m_allRuns) { if (textValueRun->isHitTarget()) { @@ -503,33 +651,104 @@ const TextStylePaint* Text::styleFromShaperId(uint16_t id) const void Text::draw(Renderer* renderer) { - ClipResult clipResult = applyClip(renderer); - if (clipResult == ClipResult::noClip) + if (m_needsSaveOperation) { - // We didn't clip, so make sure to save as we'll be doing some - // transformations. renderer->save(); } - if (clipResult != ClipResult::emptyClip) + // For now we need to check both empty() and hasRenderPath() in + // ShapePaintPath because the raw path gets cleared when the render path + // is created. + if (overflow() == TextOverflow::clipped && + (!m_clipPath.empty() || m_clipPath.hasRenderPath())) + { + renderer->clipPath(m_clipPath.renderPath(this)); + } + auto worldTransform = shapeWorldTransform(); + for (auto& cmd : m_drawCommands) { - // For now we need to check both empty() and hasRenderPath() in - // ShapePaintPath because the raw path gets cleared when the render path - // is created. - if (overflow() == TextOverflow::clipped && - (!m_clipPath.empty() || m_clipPath.hasRenderPath())) + if (cmd.type == TextDrawCommand::kStylePath) { - renderer->clipPath(m_clipPath.renderPath(this)); + cmd.style->draw(renderer, worldTransform); } - auto worldTransform = shapeWorldTransform(); - for (auto style : m_renderStyles) + else { - style->draw(renderer, worldTransform); + drawColorGlyph(renderer, cmd.colorGlyph, worldTransform); + } + } + if (m_needsSaveOperation) + { + renderer->restore(); + } +} + +void Text::drawColorGlyph(Renderer* renderer, + const TextDrawCommand::ColorGlyphInfo& info, + const Mat2D& worldTransform) +{ + std::vector layers; + size_t count = + info.font->getColorLayers(info.glyphId, layers, info.foregroundColor); + if (count == 0) + { + return; + } + + Factory* factory = artboard()->factory(); + renderer->save(); + renderer->transform(worldTransform * info.transform); + + for (auto& layer : layers) + { + if (layer.paintType == Font::ColorGlyphPaintType::image) + { + // Decode and draw bitmap emoji (SBIX/CBDT). + ColorGlyphCacheKey cacheKey{info.font.get(), info.glyphId}; + auto it = m_emojiImageCache.find(cacheKey); + if (it == m_emojiImageCache.end()) + { + auto image = factory->decodeImage( + {layer.imageBytes.data(), layer.imageBytes.size()}); + it = + m_emojiImageCache.emplace(cacheKey, std::move(image)).first; + } + if (it->second != nullptr) + { + renderer->save(); + // Transform from glyph space: position at bearing and + // scale from image pixels to glyph extent units. + float scaleX = layer.imageExtentX / (float)layer.imageWidth; + float scaleY = layer.imageExtentY / (float)layer.imageHeight; + renderer->transform(Mat2D(scaleX, + 0, + 0, + scaleY, + layer.imageBearingX, + layer.imageBearingY)); + renderer->drawImage(it->second.get(), + ImageSampler::LinearClamp(), + BlendMode::srcOver, + info.opacity); + renderer->restore(); + } + } + else + { + auto renderPath = + factory->makeRenderPath(layer.path, FillRule::nonZero); + auto renderPaint = factory->makeRenderPaint(); + renderPaint->style(RenderPaintStyle::fill); + renderPaint->color(colorModulateOpacity(layer.color, info.opacity)); + renderer->drawPath(renderPath.get(), renderPaint.get()); } } renderer->restore(); } -void Text::addRun(TextValueRun* run) { m_runs.push_back(run); } +void Text::addRun(TextValueRun* run) +{ + m_runs.push_back(run); + m_allRuns.push_back(run); +} void Text::addModifierGroup(TextModifierGroup* group) { @@ -618,7 +837,7 @@ bool Text::makeStyled(StyledText& styledText, bool withModifiers) const { styledText.clear(); uint16_t runIndex = 0; - for (auto valueRun : m_runs) + for (auto valueRun : m_allRuns) { auto style = valueRun->style(); const std::string& text = valueRun->text(); @@ -724,9 +943,9 @@ void Text::update(ComponentDirt value) bool precomputeModifierCoverage = modifierRangesNeedShape(); bool parentIsLayoutNotArtboard = parent()->is() && !parent()->is(); - if (precomputeModifierCoverage) + if (precomputeModifierCoverage && + makeStyled(m_modifierStyledText, false)) { - makeStyled(m_modifierStyledText, false); auto runs = m_modifierStyledText.runs(); m_modifierShape = runs[0].font->shapeText(m_modifierStyledText.unichars(), runs); @@ -785,6 +1004,7 @@ void Text::update(ComponentDirt value) } m_orderedLines.clear(); m_ellipsisRun = {}; + m_emojiImageCache.clear(); // Immediately build render styles so dimensions get computed. buildRenderStyles(); @@ -853,8 +1073,7 @@ Vec2D Text::measure(Vec2D maxSize) } int ellipsisLine = -1; bool wantEllipsis = overflow() == TextOverflow::ellipsis && - sizing() == TextSizing::fixed && - verticalAlign() == VerticalTextAlign::top; + sizing() == TextSizing::fixed; for (const SimpleArray& paragraphLines : lines) { @@ -947,6 +1166,7 @@ void Text::originYChanged() #else // Text disabled. +Text::~Text() {} void Text::draw(Renderer* renderer) {} Core* Text::hitTest(HitInfo*, const Mat2D&) { return nullptr; } void Text::addRun(TextValueRun* run) {} @@ -996,4 +1216,65 @@ TextAlign Text::align() const } return m_layoutDirection == LayoutDirection::ltr ? TextAlign::left : TextAlign::right; -} \ No newline at end of file +} + +void Text::updateList(std::vector>* list) +{ +#ifdef WITH_RIVE_TEXT + buildTextStylePaints(); + m_allRuns.clear(); + m_allRuns.assign(m_runs.begin(), m_runs.end()); + auto currentSize = m_valueRunListeners.size(); + size_t index = 0; + for (auto& listItem : *list) + { + auto instance = listItem->viewModelInstance(); + if (instance) + { + TextValueRun* textRun; + if (index < currentSize) + { + auto textRunListener = m_valueRunListeners[index]; + textRunListener->remap(instance); + textRun = textRunListener->textValueRun(); + } + else + { + textRun = new TextValueRun(); + textRun->textComponent(this); + auto textRunListener = + new TextValueRunListener(textRun, instance, this); + m_valueRunListeners.push_back(textRunListener); + } + if (textRun) + { + m_allRuns.push_back(textRun); + } + index++; + } + } + while (m_valueRunListeners.size() > index) + { + auto valueRun = m_valueRunListeners.back(); + m_valueRunListeners.pop_back(); + delete valueRun; + } + markShapeDirty(); +#endif +} + +#ifdef WITH_RIVE_TEXT +void Text::buildTextStylePaints() +{ + if (m_textStylePaints.size() == 0) + { + for (auto& child : children()) + { + if (child->coreType() == TextStylePaint::typeKey) + { + m_textStylePaints.push_back(child->as()); + } + } + } +} +#endif \ No newline at end of file diff --git a/thirdparty/rive/source/text/text_engine.cpp b/thirdparty/rive/source/text/text_engine.cpp index 68b585259..96aed7803 100644 --- a/thirdparty/rive/source/text/text_engine.cpp +++ b/thirdparty/rive/source/text/text_engine.cpp @@ -100,11 +100,11 @@ uint32_t OrderedLine::firstCodePointIndex(const GlyphLookup& glyphLookup) const if (run->dir() == TextDirection::rtl) { // If the final run is RTL we want to add the length of the final glyph - // to get the actual last available code unit in the line. + // to get the actual last available codepoint in the line. firstCodePointIndex += glyphLookup.count(run->textIndices[glyphIndex]); } // Clamp ignoring last zero width space for editing. - return std::min(firstCodePointIndex, glyphLookup.lastCodeUnitIndex() - 1); + return std::min(firstCodePointIndex, glyphLookup.lastCodePointIndex() - 1); } uint32_t OrderedLine::lastCodePointIndex(const GlyphLookup& glyphLookup) const @@ -127,7 +127,7 @@ uint32_t OrderedLine::lastCodePointIndex(const GlyphLookup& glyphLookup) const lastCodePointIndex += glyphLookup.count(run->textIndices[glyphIndex]); } // Clamp ignoring last zero width space for editing. - return std::min(lastCodePointIndex, glyphLookup.lastCodeUnitIndex() - 1); + return std::min(lastCodePointIndex, glyphLookup.lastCodePointIndex() - 1); } bool OrderedLine::containsCodePointIndex(const GlyphLookup& glyphLookup, diff --git a/thirdparty/rive/source/text/text_input.cpp b/thirdparty/rive/source/text/text_input.cpp index 789485e87..4e4132f2b 100644 --- a/thirdparty/rive/source/text/text_input.cpp +++ b/thirdparty/rive/source/text/text_input.cpp @@ -4,6 +4,13 @@ #include "rive/math/mat2d.hpp" #include "rive/artboard.hpp" #include "rive/factory.hpp" +#include "rive/constraints/scrolling/scroll_constraint.hpp" +#include + +#if defined(__EMSCRIPTEN__) +#include +#include +#endif using namespace rive; @@ -11,13 +18,48 @@ void TextInput::draw(Renderer* renderer) {} Core* TextInput::hitTest(HitInfo*, const Mat2D&) { return nullptr; } +bool TextInput::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + // TextInput must check its own bounds before delegating to parent. + // Unlike layouts, we always check bounds regardless of clip state. + Mat2D inverseWorld; + if (!worldTransform().invert(&inverseWorld)) + { + return false; + } + + Vec2D localPosition = inverseWorld * position; + if (!localBounds().contains(localPosition)) + { + return false; + } + + // Bounds check passed, now check parent hierarchy + return Drawable::hitTestPoint(position, skipOnUnclipped, isPrimaryHit); +} + void TextInput::textChanged() +{ + m_sourceText = m_Text; +#ifdef WITH_RIVE_TEXT + syncDisplayedTextFromSource(false); +#endif +#ifdef WITH_RIVE_LAYOUT + markLayoutNodeDirty(); +#endif + markShapeDirty(); +} +void TextInput::selectionRadiusChanged() { #ifdef WITH_RIVE_TEXT - m_rawTextInput.text(m_Text); + m_rawTextInput.selectionCornerRadius(selectionRadius()); + markShapeDirty(); #endif } -void TextInput::selectionRadiusChanged() {} + +void TextInput::multilineChanged() { updateMultiline(true); } void TextInput::markPaintDirty() { addDirt(ComponentDirt::Paint); } @@ -37,14 +79,34 @@ StatusCode TextInput::onAddedClean(CoreContext* context) Super::onAddedClean(context); m_textStyle = children().first(); + m_sourceText = m_Text; #ifdef WITH_RIVE_TEXT if (m_textStyle != nullptr && m_textStyle->font() != nullptr) { m_rawTextInput.font(m_textStyle->font()); + m_rawTextInput.fontSize(m_textStyle->fontSize()); } - m_rawTextInput.text(m_Text); + syncDisplayedTextFromSource(false); #endif + + if (parent() != nullptr) + { + auto parentParent = parent()->parent(); + if (parentParent != nullptr && parentParent->is()) + { + for (Constraint* constraint : + parentParent->as()->constraints()) + { + if (constraint->is()) + { + m_scrollConstraint = constraint->as(); + break; + } + } + } + } + updateMultiline(); return m_textStyle == nullptr ? StatusCode::MissingObject : StatusCode::Ok; } @@ -55,8 +117,9 @@ void TextInput::update(ComponentDirt value) if (hasDirt(value, ComponentDirt::Paint | ComponentDirt::TextShape)) { Factory* factory = artboard()->factory(); + m_rawTextInput.fontSize(m_textStyle->fontSize()); RawTextInput::Flags changed = m_rawTextInput.update(factory); - if ((changed & RawTextInput::Flags::shapeDirty) != 0) + if (enums::is_flag_set(changed, RawTextInput::Flags::shapeDirty)) { m_worldBounds = worldTransform().mapBoundingBox(m_rawTextInput.bounds()); @@ -68,13 +131,67 @@ void TextInput::update(ComponentDirt value) } #endif } - if ((changed & RawTextInput::Flags::selectionDirty) != 0) + if (enums::is_flag_set(changed, RawTextInput::Flags::selectionDirty)) { for (auto child : children()) { child->invalidateStrokeEffects(); } } + // Skip scroll adjustment during drag - edge scrolling handles it. + if (m_scrollX == 0.0f && m_scrollY == 0.0f && + m_scrollConstraint != nullptr && !m_isDragging) + { + CursorVisualPosition cursorPosition = + m_rawTextInput.cursorVisualPosition(); + float viewportWidth = m_scrollConstraint->viewportWidth(); + float viewportHeight = m_scrollConstraint->viewportHeight(); + const float cursorWidth = 1.0f; + bool useHorizontalScroll = + !multiline() && m_scrollConstraint->constrainsHorizontal(); + bool useVerticalScroll = + multiline() && m_scrollConstraint->constrainsVertical(); + + float viewportX = + cursorPosition.x() + m_scrollConstraint->scrollOffsetX(); + float viewportTop = + cursorPosition.top() + m_scrollConstraint->scrollOffsetY(); + float viewportBottom = + cursorPosition.bottom() + m_scrollConstraint->scrollOffsetY(); + + if (useHorizontalScroll && viewportX < 0.0f) + { + m_scrollConstraint->stopPhysics(); + + float scrollOffset = + m_scrollConstraint->scrollOffsetX() - viewportX; + m_scrollConstraint->scrollOffsetX(scrollOffset); + } + else if (useHorizontalScroll && + viewportX > viewportWidth - cursorWidth) + { + m_scrollConstraint->stopPhysics(); + + float scrollOffset = m_scrollConstraint->scrollOffsetX() - + (viewportX - viewportWidth + cursorWidth); + m_scrollConstraint->scrollOffsetX(scrollOffset); + } + + if (useVerticalScroll && viewportTop < 0.0f) + { + m_scrollConstraint->stopPhysics(); + float scrollOffset = + m_scrollConstraint->scrollOffsetY() - viewportTop; + m_scrollConstraint->scrollOffsetY(scrollOffset); + } + else if (useVerticalScroll && viewportBottom > viewportHeight) + { + m_scrollConstraint->stopPhysics(); + float scrollOffset = m_scrollConstraint->scrollOffsetY() - + (viewportBottom - viewportHeight); + m_scrollConstraint->scrollOffsetY(scrollOffset); + } + } } #endif } @@ -102,11 +219,513 @@ void TextInput::controlSize(Vec2D size, LayoutScaleType widthScaleType, LayoutScaleType heightScaleType, LayoutDirection direction) +{ + m_layoutWidth = size.x; + updateMultiline(); +} + +std::string TextInput::strippedLineBreaks(const std::string& text) +{ + std::string stripped; + stripped.reserve(text.size()); + bool inLineBreak = false; + for (char c : text) + { + if (c == '\n' || c == '\r') + { + if (!inLineBreak) + { + stripped.push_back(' '); + inLineBreak = true; + } + } + else + { + stripped.push_back(c); + inLineBreak = false; + } + } + return stripped; +} + +std::string TextInput::displayedText() const +{ + return multiline() ? m_sourceText : strippedLineBreaks(m_sourceText); +} + +void TextInput::syncDisplayedTextFromSource(bool preserveCursor) { #ifdef WITH_RIVE_TEXT - m_rawTextInput.maxWidth(size.x); - m_rawTextInput.sizing(TextSizing::autoHeight); + std::string nextDisplayText = displayedText(); + if (m_rawTextInput.text() == nextDisplayText) + { + return; + } + if (preserveCursor) + { + m_rawTextInput.textPreserveCursor(nextDisplayText); + } + else + { + m_rawTextInput.text(nextDisplayText); + } +#endif +} + +void TextInput::syncSourceTextFromRaw() +{ +#ifdef WITH_RIVE_TEXT + std::string rawText = m_rawTextInput.text(); + if (!multiline()) + { + std::string singleLineText = strippedLineBreaks(rawText); + if (singleLineText != rawText) + { + m_rawTextInput.textPreserveCursor(singleLineText); + rawText = std::move(singleLineText); + } + } + m_sourceText = std::move(rawText); + text(m_sourceText); +#endif +} + +#ifdef WITH_RIVE_TEXT +static CursorBoundary cursorBoundary(KeyModifiers modifiers) +{ + if ((modifiers & KeyModifiers::meta) != KeyModifiers::none) + { + return CursorBoundary::line; + } + if ((modifiers & KeyModifiers::alt) != KeyModifiers::none) + { + if ((modifiers & KeyModifiers::ctrl) != KeyModifiers::none) + { + return CursorBoundary::subWord; + } + return CursorBoundary::word; + } + return CursorBoundary::character; +} + +#if defined(__EMSCRIPTEN__) +EM_JS(bool, isWindowsBrowser, (), { + return Boolean(navigator.platform.indexOf('Win') > -1); +}); +#endif +static KeyModifiers systemModifier() +{ +#if defined(__EMSCRIPTEN__) + return isWindowsBrowser() ? KeyModifiers::ctrl : KeyModifiers::meta; +#elif defined(RIVE_WINDOWS) + return KeyModifiers::ctrl; +#else + return KeyModifiers::meta; +#endif +} + +#endif + +void TextInput::updateMultiline(bool syncDisplayedText) +{ +#ifdef WITH_RIVE_TEXT + if (multiline()) + { + m_rawTextInput.maxWidth(m_layoutWidth); + m_rawTextInput.sizing(TextSizing::autoHeight); + } + else + { + m_rawTextInput.maxWidth(0); + m_rawTextInput.sizing(TextSizing::autoWidth); + } + + if (m_scrollConstraint != nullptr) + { + if (multiline() && m_scrollConstraint->scrollOffsetX() != 0.0f) + { + m_scrollConstraint->stopPhysics(); + m_scrollConstraint->scrollOffsetX(0.0f); + } + else if (!multiline() && m_scrollConstraint->scrollOffsetY() != 0.0f) + { + m_scrollConstraint->stopPhysics(); + m_scrollConstraint->scrollOffsetY(0.0f); + } + } + + if (syncDisplayedText) + { + syncDisplayedTextFromSource(true); + } + +#ifdef WITH_RIVE_LAYOUT + markLayoutNodeDirty(); +#endif addDirt(ComponentDirt::TextShape); #endif -} \ No newline at end of file +} + +bool TextInput::keyInput(Key value, + KeyModifiers modifiers, + bool isPressed, + bool isRepeat) +{ +#ifdef WITH_RIVE_TEXT + if (isPressed) + { + switch (value) + { + case Key::z: + + if ((modifiers & (systemModifier() | KeyModifiers::shift)) == + (systemModifier() | KeyModifiers::shift)) + { + m_rawTextInput.redo(); + syncSourceTextFromRaw(); + markShapeDirty(); + return true; + } + else if ((modifiers & systemModifier()) != KeyModifiers::none) + { + m_rawTextInput.undo(); + syncSourceTextFromRaw(); + markShapeDirty(); + return true; + } + break; + case Key::backspace: + m_rawTextInput.backspace(-1); + syncSourceTextFromRaw(); + markShapeDirty(); + return true; + case Key::deleteKey: + m_rawTextInput.backspace(1); + syncSourceTextFromRaw(); + markShapeDirty(); + return true; + case Key::left: + m_rawTextInput.cursorLeft(cursorBoundary(modifiers), + (modifiers & KeyModifiers::shift) != + KeyModifiers::none); + markPaintDirty(); + return true; + case Key::right: + m_rawTextInput.cursorRight(cursorBoundary(modifiers), + (modifiers & KeyModifiers::shift) != + KeyModifiers::none); + markPaintDirty(); + return true; + case Key::up: + m_rawTextInput.cursorUp((modifiers & KeyModifiers::shift) != + KeyModifiers::none); + markPaintDirty(); + return true; + case Key::down: + m_rawTextInput.cursorDown((modifiers & KeyModifiers::shift) != + KeyModifiers::none); + markPaintDirty(); + return true; + case Key::enter: + if (!multiline()) + { + return false; + } + m_rawTextInput.insert("\n"); + syncSourceTextFromRaw(); + markPaintDirty(); + return true; + default: + return false; + } + } +#endif + return false; +} + +bool TextInput::textInput(const std::string& value) +{ +#ifdef WITH_RIVE_TEXT + std::string textToInsert = multiline() ? value : strippedLineBreaks(value); + if (textToInsert.empty()) + { + return true; + } + m_rawTextInput.insert(textToInsert); + syncSourceTextFromRaw(); + markShapeDirty(); +#endif + return true; +} + +void TextInput::focused() +{ + // TODO: Implement focus visual feedback +} + +void TextInput::blurred() +{ + // TODO: Implement blur visual feedback +} + +bool TextInput::worldPosition(Vec2D& outPosition) +{ + // TextInput is a TransformComponent, so we can access worldTransform + // directly + Vec2D localPos = worldTranslation(); + + // Transform to root artboard space (handles nested artboards) + auto* ab = artboard(); + if (ab) + { + outPosition = ab->rootTransform(localPos); + } + else + { + outPosition = localPos; + } + return true; +} + +bool TextInput::worldBounds(AABB& outBounds) +{ + // m_worldBounds is computed in update() via + // worldTransform().mapBoundingBox() + if (m_worldBounds.isEmptyOrNaN()) + { + return false; + } + + // Transform to root artboard space (handles nested artboards) + auto* ab = artboard(); + if (ab) + { + Vec2D minPt = ab->rootTransform(m_worldBounds.min()); + Vec2D maxPt = ab->rootTransform(m_worldBounds.max()); + outBounds = AABB(minPt, maxPt); + } + else + { + outBounds = m_worldBounds; + } + return true; +} + +float TextInput::edgeScrollSpeedForDistance(float distanceFromEdge) const +{ + static constexpr float kEdgeScrollBaseSpeed = 45.0f; + static constexpr float kEdgeScrollMaxSpeed = 400.0f; + static constexpr float kEdgeScrollSpeedRamp = 4.0f; + float speed = + kEdgeScrollBaseSpeed + distanceFromEdge * kEdgeScrollSpeedRamp; + return std::max(kEdgeScrollBaseSpeed, std::min(kEdgeScrollMaxSpeed, speed)); +} + +float TextInput::edgeActivationDistance(float position, float edgeStart) const +{ + return position >= edgeStart ? 0.0f : edgeStart - position; +} + +bool TextInput::worldToLocalWithViewport(Vec2D worldPosition, + Vec2D& outLocal, + bool enableAutoScroll) +{ + m_scrollX = 0.0f; + m_scrollY = 0.0f; + + // Get the inverse of the world transform to convert to local coordinates + Mat2D inverseWorld; + if (!worldTransform().invert(&inverseWorld)) + { + return false; + } + + Vec2D localPos = inverseWorld * worldPosition; + + // If we have a scroll constraint, handle viewport clamping and edge + // detection. + if (m_scrollConstraint != nullptr) + { + float viewportWidth = m_scrollConstraint->viewportWidth(); + float viewportHeight = m_scrollConstraint->viewportHeight(); + float scrollOffsetX = m_scrollConstraint->scrollOffsetX(); + float scrollOffsetY = m_scrollConstraint->scrollOffsetY(); + const float edgeThreshold = 20.0f; + bool useHorizontalScroll = + !multiline() && m_scrollConstraint->constrainsHorizontal(); + bool useVerticalScroll = + multiline() && m_scrollConstraint->constrainsVertical(); + + if (useHorizontalScroll) + { + // Convert to viewport-relative coordinates. + float viewportX = localPos.x + scrollOffsetX; + float leftDistance = + edgeActivationDistance(viewportX, edgeThreshold); + float rightDistance = + edgeActivationDistance(viewportWidth - viewportX, + edgeThreshold); + + // Edge detection for auto-scrolling. + if (enableAutoScroll && leftDistance > 0.0f) + { + m_scrollX = edgeScrollSpeedForDistance(leftDistance); + if (viewportX < 0.0f) + { + localPos.x = -scrollOffsetX; + } + } + else if (enableAutoScroll && rightDistance > 0.0f) + { + m_scrollX = -edgeScrollSpeedForDistance(rightDistance); + if (viewportX > viewportWidth) + { + localPos.x = viewportWidth - scrollOffsetX; + } + } + } + + if (useVerticalScroll) + { + // Convert to viewport-relative coordinates. + float viewportY = localPos.y + scrollOffsetY; + float topDistance = + edgeActivationDistance(viewportY, edgeThreshold); + float bottomDistance = + edgeActivationDistance(viewportHeight - viewportY, + edgeThreshold); + + // Edge detection for auto-scrolling. + if (enableAutoScroll && topDistance > 0.0f) + { + m_scrollY = edgeScrollSpeedForDistance(topDistance); + if (viewportY < 0.0f) + { + localPos.y = -scrollOffsetY; + } + } + else if (enableAutoScroll && bottomDistance > 0.0f) + { + m_scrollY = -edgeScrollSpeedForDistance(bottomDistance); + if (viewportY > viewportHeight) + { + localPos.y = viewportHeight - scrollOffsetY; + } + } + } + } + + outLocal = localPos; + return true; +} + +void TextInput::startDrag(Vec2D worldPosition) +{ +#ifdef WITH_RIVE_TEXT + m_isDragging = true; + m_lastDragWorldPosition = worldPosition; + + Vec2D localPos; + if (!worldToLocalWithViewport(worldPosition, localPos, false)) + { + return; + } + + m_rawTextInput.moveCursorTo(localPos, false); + markPaintDirty(); + // Note: Focus is handled by TextInputListenerGroup which can cross + // artboard boundaries to find the appropriate FocusData. +#endif +} + +void TextInput::drag(Vec2D worldPosition) +{ +#ifdef WITH_RIVE_TEXT + m_lastDragWorldPosition = worldPosition; + + Vec2D localPos; + if (!worldToLocalWithViewport(worldPosition, localPos, true)) + { + return; + } + + m_rawTextInput.moveCursorTo(localPos, true); + markPaintDirty(); +#endif +} + +void TextInput::endDrag(Vec2D worldPosition) +{ + m_isDragging = false; + m_lastDragWorldPosition = Vec2D(NAN, NAN); + m_scrollX = 0.0f; + m_scrollY = 0.0f; +} + +bool TextInput::advanceDrag(float elapsedSeconds) +{ +#ifdef WITH_RIVE_TEXT + if (!m_isDragging) + { + m_scrollX = 0.0f; + m_scrollY = 0.0f; + return false; + } + + if ((m_scrollX == 0.0f && m_scrollY == 0.0f) || + m_scrollConstraint == nullptr) + { + return false; + } + + m_scrollConstraint->stopPhysics(); + if (m_scrollX != 0.0f) + { + float scrollDeltaX = m_scrollX * elapsedSeconds; + float newScrollOffsetX = + m_scrollConstraint->scrollOffsetX() + scrollDeltaX; + if (!m_scrollConstraint->infinite()) + { + newScrollOffsetX = std::max(m_scrollConstraint->maxOffsetX(), + std::min(0.0f, newScrollOffsetX)); + } + m_scrollConstraint->scrollOffsetX(newScrollOffsetX); + } + if (m_scrollY != 0.0f) + { + float scrollDeltaY = m_scrollY * elapsedSeconds; + float newScrollOffsetY = + m_scrollConstraint->scrollOffsetY() + scrollDeltaY; + if (!m_scrollConstraint->infinite()) + { + newScrollOffsetY = std::max(m_scrollConstraint->maxOffsetY(), + std::min(0.0f, newScrollOffsetY)); + } + m_scrollConstraint->scrollOffsetY(newScrollOffsetY); + } + + // Keep selection/caret in sync while edge-scrolling even if pointer isn't + // moving. + if (std::isfinite(m_lastDragWorldPosition.x) && + std::isfinite(m_lastDragWorldPosition.y)) + { + Vec2D localPos; + if (worldToLocalWithViewport(m_lastDragWorldPosition, localPos, true)) + { + m_rawTextInput.moveCursorTo(localPos, true); + markPaintDirty(); + } + } + + // Continue scrolling while still dragging + return m_isDragging; +#else + return false; +#endif +} + +bool TextInput::advanceComponent(float elapsedSeconds, AdvanceFlags flags) +{ + return advanceDrag(elapsedSeconds); +} diff --git a/thirdparty/rive/source/text/text_input_drawable.cpp b/thirdparty/rive/source/text/text_input_drawable.cpp index 0d23472dd..fe3e2fd7d 100644 --- a/thirdparty/rive/source/text/text_input_drawable.cpp +++ b/thirdparty/rive/source/text/text_input_drawable.cpp @@ -32,33 +32,24 @@ const Mat2D& TextInputDrawable::shapeWorldTransform() const void TextInputDrawable::draw(Renderer* renderer) { - if (renderOpacity() == 0.0f) + for (auto shapePaint : m_ShapePaints) { - return; - } - ClipResult clipResult = applyClip(renderer); - - if (clipResult != ClipResult::emptyClip) - { - for (auto shapePaint : m_ShapePaints) + if (!shapePaint->isVisible()) + { + continue; + } + auto shapePaintPath = shapePaint->pickPath(this); + if (shapePaintPath == nullptr) { - if (!shapePaint->isVisible()) - { - continue; - } - auto shapePaintPath = shapePaint->pickPath(this); - if (shapePaintPath == nullptr) - { - continue; - } - shapePaint->draw(renderer, - shapePaintPath, - textInput()->worldTransform()); + continue; } + shapePaint->draw(renderer, + shapePaintPath, + textInput()->worldTransform()); } +} - if (clipResult != ClipResult::noClip) - { - renderer->restore(); - } +bool TextInputDrawable::willDraw() +{ + return Super::willDraw() && renderOpacity() != 0.0f; } \ No newline at end of file diff --git a/thirdparty/rive/source/text/text_input_selected_text.cpp b/thirdparty/rive/source/text/text_input_selected_text.cpp index 766e98fbe..f58607248 100644 --- a/thirdparty/rive/source/text/text_input_selected_text.cpp +++ b/thirdparty/rive/source/text/text_input_selected_text.cpp @@ -6,6 +6,19 @@ using namespace rive; Core* TextInputSelectedText::hitTest(HitInfo*, const Mat2D&) { return nullptr; } +StatusCode TextInputSelectedText::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } +#ifdef WITH_RIVE_TEXT + textInput()->rawTextInput()->separateSelectionText(true); +#endif + return StatusCode::Ok; +} + ShapePaintPath* TextInputSelectedText::localClockwisePath() { #ifdef WITH_RIVE_TEXT diff --git a/thirdparty/rive/source/text/text_modifier_group.cpp b/thirdparty/rive/source/text/text_modifier_group.cpp index 86ad52575..cc9999623 100644 --- a/thirdparty/rive/source/text/text_modifier_group.cpp +++ b/thirdparty/rive/source/text/text_modifier_group.cpp @@ -134,7 +134,7 @@ float TextModifierGroup::glyphCoverage(uint32_t textIndex, { c += coverage(textIndex + i); } - return c /= (float)codePointCount; + return c / (float)codePointCount; } void TextModifierGroup::onTextWorldTransformDirty() diff --git a/thirdparty/rive/source/text/text_style.cpp b/thirdparty/rive/source/text/text_style.cpp index 0624de1bd..4d6f4e499 100644 --- a/thirdparty/rive/source/text/text_style.cpp +++ b/thirdparty/rive/source/text/text_style.cpp @@ -26,12 +26,18 @@ void TextStyle::addFeature(TextStyleFeature* feature) void TextStyle::onDirty(ComponentDirt dirt) { - if ((dirt & ComponentDirt::TextShape) == ComponentDirt::TextShape) + // This can happen if the Text is in a Solo which is propagating its + // collapsed state during its onAddedClean (which could be called before + // ours, so m_text might still be null). + if (m_text != nullptr) { - m_text->markShapeDirty(); - if (m_variationHelper != nullptr) + if ((dirt & ComponentDirt::TextShape) == ComponentDirt::TextShape) { - m_variationHelper->addDirt(ComponentDirt::TextShape); + m_text->markShapeDirty(); + if (m_variationHelper != nullptr) + { + m_variationHelper->addDirt(ComponentDirt::TextShape); + } } } } @@ -49,7 +55,7 @@ StatusCode TextStyle::onAddedClean(CoreContext* context) // This ensures context propagates to variation helper too. if (!m_variations.empty() || !m_styleFeatures.empty()) { - m_variationHelper = rivestd::make_unique(this); + m_variationHelper = std::make_unique(this); } if (m_variationHelper != nullptr) { @@ -72,11 +78,24 @@ const rcp TextStyle::font() const return m_variableFont; } + // Lazily build the variable font if variations/features are present but + // the variable font hasn't been created yet. This ensures the very first + // shape/measure uses the intended axes (e.g. wght) rather than the font's + // default axis values. + if ((!m_variations.empty() || !m_styleFeatures.empty())) + { + updateVariableFont(); + if (m_variableFont != nullptr) + { + return m_variableFont; + } + } + auto asset = fontAsset(); return asset == nullptr ? nullptr : asset->font(); } -void TextStyle::updateVariableFont() +void TextStyle::updateVariableFont() const { auto asset = fontAsset(); rcp baseFont = asset == nullptr ? nullptr : asset->font(); @@ -118,7 +137,7 @@ void TextStyle::buildDependencies() uint32_t TextStyle::assetId() { return this->fontAssetId(); } -void TextStyle::setAsset(FileAsset* asset) +void TextStyle::setAsset(rcp asset) { if (asset->is()) { diff --git a/thirdparty/rive/source/text/text_style_paint.cpp b/thirdparty/rive/source/text/text_style_paint.cpp index d7f210d16..877488d38 100644 --- a/thirdparty/rive/source/text/text_style_paint.cpp +++ b/thirdparty/rive/source/text/text_style_paint.cpp @@ -2,6 +2,8 @@ #include "rive/text/text.hpp" #include "rive/text/text_variation_helper.hpp" #include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/fill.hpp" +#include "rive/shapes/paint/solid_color.hpp" #include "rive/shapes/paint/feather.hpp" #include "rive/artboard.hpp" #include "rive/factory.hpp" @@ -98,6 +100,20 @@ void TextStylePaint::draw(Renderer* renderer, const Mat2D& worldTransform) } } +ColorInt TextStylePaint::foregroundColor() const +{ + for (auto shapePaint : m_ShapePaints) + { + if (shapePaint->is() && shapePaint->paint()->is()) + { + return (ColorInt)shapePaint->paint() + ->as() + ->colorValue(); + } + } + return 0xFF000000; +} + const Mat2D& TextStylePaint::shapeWorldTransform() const { return parent()->as()->shapeWorldTransform(); diff --git a/thirdparty/rive/source/text/text_value_run.cpp b/thirdparty/rive/source/text/text_value_run.cpp index 39f2b5eb1..d1ba4fd02 100644 --- a/thirdparty/rive/source/text/text_value_run.cpp +++ b/thirdparty/rive/source/text/text_value_run.cpp @@ -11,10 +11,17 @@ using namespace rive; void TextValueRun::textChanged() { m_length = -1; - parent()->as()->markShapeDirty(); + textComponent()->markShapeDirty(); } -Text* TextValueRun::textComponent() const { return parent()->as(); } +Text* TextValueRun::textComponent() const +{ + if (m_textComponent) + { + return m_textComponent; + } + return parent()->as(); +} StatusCode TextValueRun::onAddedClean(CoreContext* context) { @@ -57,14 +64,14 @@ void TextValueRun::styleIdChanged() if (coreObject != nullptr && coreObject->is()) { m_style = static_cast(coreObject); - parent()->as()->markShapeDirty(); + textComponent()->markShapeDirty(); } } uint32_t TextValueRun::offset() const { #ifdef WITH_RIVE_TEXT - Text* text = parent()->as(); + Text* text = textComponent(); uint32_t offset = 0; for (TextValueRun* run : text->runs()) @@ -104,7 +111,7 @@ void TextValueRun::computeHitContours() { if (!m_rectanglesToContour) { - m_rectanglesToContour = rivestd::make_unique(); + m_rectanglesToContour = std::make_unique(); } else { @@ -188,4 +195,16 @@ bool TextValueRun::hitTestHiFi(const Vec2D& position, float hitRadius) return tester.wasHit(); } -void TextValueRun::isHitTarget(bool value) { m_isHitTarget = value; } \ No newline at end of file +void TextValueRun::isHitTarget(bool value) { m_isHitTarget = value; } + +bool TextValueRun::hitTestPoint(const Vec2D& position, + bool skipOnUnclipped, + bool isPrimaryHit) +{ + if (hitTestAABB(position) && + Component::hitTestPoint(position, skipOnUnclipped, isPrimaryHit)) + { + return hitTestHiFi(position, 2); + } + return false; +} \ No newline at end of file diff --git a/thirdparty/rive/source/texture_archive.cpp b/thirdparty/rive/source/texture_archive.cpp new file mode 100644 index 000000000..25340b6cf --- /dev/null +++ b/thirdparty/rive/source/texture_archive.cpp @@ -0,0 +1,306 @@ +#include "rive/texture_archive.hpp" + +#include +#include +#include +#include + +using namespace rive; + +namespace +{ +// Per-texture descriptor on disk: 4*u16 + 4*u8 + 1*u8(format) = 13 bytes. +constexpr size_t kDescriptorSize = 13; +// Per-mip entry on disk: 3*u32 = 12 bytes. +constexpr size_t kMipEntrySize = 12; + +// Defensive caps to bound allocation and reject hostile inputs early. +constexpr uint16_t kMaxTextures = 4096; +constexpr uint8_t kMaxMipsPerTexture = 16; +// 256 MB per mip is far above any realistic compressed texture. +constexpr uint32_t kMaxBytesPerMip = 256u * 1024u * 1024u; +} // namespace + +// --------------------------------------------------------------------------- +// Binary file format (.rtex) +// +// [4] Magic: "RTEX" +// [2] Version: uint16_t (currently 1) +// [2] TextureCount: uint16_t +// [per texture]: +// [2] width: uint16_t (original, un-padded) +// [2] height: uint16_t +// [2] paddedWidth: uint16_t +// [2] paddedHeight: uint16_t +// [1] blockSizeX: uint8_t +// [1] blockSizeY: uint8_t +// [1] bytesPerBlock:uint8_t +// [1] numMips: uint8_t +// [1] format: uint8_t (GPUTextureFormat) +// [per mip (numMips entries)]: +// [4] blocksX: uint32_t +// [4] blocksY: uint32_t +// [4] bytesTotal: uint32_t +// [data blob: all mip data for every texture, in declaration order] +// --------------------------------------------------------------------------- + +void TextureDirectory::addTexture(TextureData& td) +{ + const uint8_t* oldBase = dataBlob.empty() ? nullptr : dataBlob.data(); + + std::vector offsets; + offsets.reserve(td.mipLevels.size()); + for (auto& mip : td.mipLevels) + { + offsets.push_back(dataBlob.size()); + dataBlob.insert(dataBlob.end(), + mip.blocks, + mip.blocks + mip.bytesTotal); + } + + const uint8_t* newBase = dataBlob.data(); + + if (oldBase != nullptr && oldBase != newBase) + { + for (auto& existing : dir) + for (auto& mip : existing.mipLevels) + mip.blocks = newBase + (mip.blocks - oldBase); + } + + for (size_t i = 0; i < td.mipLevels.size(); ++i) + td.mipLevels[i].blocks = newBase + offsets[i]; + + dir.push_back(td); +} + +bool TextureDirectory::exportArchive(const std::string& path) +{ + FILE* fp = std::fopen(path.c_str(), "wb"); + if (!fp) + { + std::fprintf(stderr, + "TextureDirectory::exportArchive: cannot open '%s'\n", + path.c_str()); + return false; + } + + TextureArchiveHeader header; + std::memcpy(header.magic, + TextureArchiveHeader::kMagic, + sizeof(header.magic)); + header.version = TextureArchiveHeader::kCurrentVersion; + header.textureCount = static_cast(dir.size()); + std::fwrite(&header, sizeof(header), 1, fp); + + for (const auto& td : dir) + { + std::fwrite(&td.width, sizeof(td.width), 1, fp); + std::fwrite(&td.height, sizeof(td.height), 1, fp); + std::fwrite(&td.paddedWidth, sizeof(td.paddedWidth), 1, fp); + std::fwrite(&td.paddedHeight, sizeof(td.paddedHeight), 1, fp); + std::fwrite(&td.blockSizeX, sizeof(td.blockSizeX), 1, fp); + std::fwrite(&td.blockSizeY, sizeof(td.blockSizeY), 1, fp); + std::fwrite(&td.bytesPerBlock, sizeof(td.bytesPerBlock), 1, fp); + std::fwrite(&td.numMips, sizeof(td.numMips), 1, fp); + const uint8_t fmt = static_cast(td.format); + std::fwrite(&fmt, sizeof(fmt), 1, fp); + + for (const auto& mip : td.mipLevels) + { + const uint32_t bx = static_cast(mip.blocksX); + const uint32_t by = static_cast(mip.blocksY); + const uint32_t bt = mip.bytesTotal; + std::fwrite(&bx, sizeof(bx), 1, fp); + std::fwrite(&by, sizeof(by), 1, fp); + std::fwrite(&bt, sizeof(bt), 1, fp); + } + } + + std::fwrite(dataBlob.data(), 1, dataBlob.size(), fp); + std::fclose(fp); + return true; +} + +bool TextureDirectory::import(Span texBytes) +{ + dir.clear(); + dataBlob.clear(); + + if (texBytes.size() < sizeof(TextureArchiveHeader)) + { + printf("TextureDirectory::import: file too small\n"); + return false; + } + + const uint8_t* p = texBytes.data(); + const uint8_t* end = p + texBytes.size(); + + TextureArchiveHeader header; + std::memcpy(&header, p, sizeof(header)); + p += sizeof(header); + + if (std::memcmp(header.magic, + TextureArchiveHeader::kMagic, + sizeof(header.magic)) != 0) + { + printf("TextureDirectory::import: bad magic\n"); + return false; + } + if (header.version != TextureArchiveHeader::kCurrentVersion) + { + printf("TextureDirectory::import: unsupported version %u\n", + static_cast(header.version)); + return false; + } + + const uint16_t count = header.textureCount; + if (count > kMaxTextures) + { + printf("TextureDirectory::import: textureCount %u exceeds cap %u\n", + static_cast(count), + static_cast(kMaxTextures)); + return false; + } + + struct MipDesc + { + uint32_t blocksX, blocksY, bytesTotal; + }; + struct TexDesc + { + TextureData td; + std::vector mips; + }; + + std::vector descs(count); + size_t totalData = 0; + + for (auto& desc : descs) + { + TextureData& td = desc.td; + if (static_cast(end - p) < kDescriptorSize) + { + printf("TextureDirectory::import: truncated descriptor\n"); + return false; + } + std::memcpy(&td.width, p, 2); + p += 2; + std::memcpy(&td.height, p, 2); + p += 2; + std::memcpy(&td.paddedWidth, p, 2); + p += 2; + std::memcpy(&td.paddedHeight, p, 2); + p += 2; + td.blockSizeX = *p++; + td.blockSizeY = *p++; + td.bytesPerBlock = *p++; + td.numMips = *p++; + td.format = static_cast(*p++); + + if (td.numMips > kMaxMipsPerTexture) + { + printf("TextureDirectory::import: numMips %u exceeds cap %u\n", + static_cast(td.numMips), + static_cast(kMaxMipsPerTexture)); + return false; + } + desc.mips.resize(td.numMips); + const size_t mipTableBytes = + static_cast(td.numMips) * kMipEntrySize; + if (static_cast(end - p) < mipTableBytes) + { + printf("TextureDirectory::import: truncated mip table\n"); + return false; + } + td.totalBytes = 0; + for (auto& m : desc.mips) + { + std::memcpy(&m.blocksX, p, 4); + p += 4; + std::memcpy(&m.blocksY, p, 4); + p += 4; + std::memcpy(&m.bytesTotal, p, 4); + p += 4; + if (m.bytesTotal > kMaxBytesPerMip) + { + printf("TextureDirectory::import: mip bytesTotal %u " + "exceeds cap %u\n", + static_cast(m.bytesTotal), + static_cast(kMaxBytesPerMip)); + return false; + } + // Sum without overflow: cap remaining headroom. + if (m.bytesTotal > + std::numeric_limits::max() - td.totalBytes) + { + printf("TextureDirectory::import: totalBytes overflow\n"); + return false; + } + td.totalBytes += m.bytesTotal; + } + if (td.totalBytes > std::numeric_limits::max() - totalData) + { + printf("TextureDirectory::import: totalData overflow\n"); + return false; + } + totalData += td.totalBytes; + } + + if (static_cast(end - p) != totalData) + { + printf("TextureDirectory::import: blob size mismatch " + "(expected %zu, got %zu)\n", + totalData, + static_cast(end - p)); + return false; + } + + dataBlob.assign(p, end); + const uint8_t* blob = dataBlob.data(); + size_t offset = 0; + + dir.reserve(count); + for (auto& desc : descs) + { + TextureData& td = desc.td; + td.mipLevels.resize(desc.mips.size()); + for (size_t i = 0; i < desc.mips.size(); i++) + { + const MipDesc& m = desc.mips[i]; + if (m.blocksX > std::numeric_limits::max() || + m.blocksY > std::numeric_limits::max()) + { + printf("TextureDirectory::import: blocks dimension " + "exceeds uint16\n"); + return false; + } + td.mipLevels[i].blocksX = static_cast(m.blocksX); + td.mipLevels[i].blocksY = static_cast(m.blocksY); + td.mipLevels[i].bytesTotal = m.bytesTotal; + td.mipLevels[i].blocks = blob + offset; + offset += m.bytesTotal; + } + dir.push_back(std::move(td)); + } + + return true; +} + +bool TextureDirectory::import(const std::string& path) +{ + std::ifstream in(path, std::ios::binary | std::ios::ate); + if (!in) + { + printf("TextureDirectory::import: cannot open %s\n", path.c_str()); + return false; + } + const std::streamsize len = in.tellg(); + in.seekg(0, std::ios::beg); + std::vector buf(static_cast(len)); + if (!in.read(reinterpret_cast(buf.data()), len)) + { + printf("TextureDirectory::import: read failed for %s\n", path.c_str()); + return false; + } + return import(Span(buf.data(), buf.size())); +} diff --git a/thirdparty/rive/source/viewmodel/property_symbol_dependent.cpp b/thirdparty/rive/source/viewmodel/property_symbol_dependent.cpp new file mode 100644 index 000000000..abfc0c304 --- /dev/null +++ b/thirdparty/rive/source/viewmodel/property_symbol_dependent.cpp @@ -0,0 +1,81 @@ +#include "rive/viewmodel/property_symbol_dependent.hpp" + +using namespace rive; + +PropertySymbolDependent::PropertySymbolDependent( + Core* core, + CoreObjectListener* coreObjectListener, + ViewModelInstanceValue* instanceValue) : + m_coreObject(core), + m_coreObjectListener(coreObjectListener), + m_instanceValue(instanceValue) +{ + if (m_instanceValue != nullptr) + { + m_instanceValue->addDependent(this); + } +} + +PropertySymbolDependent::~PropertySymbolDependent() +{ + + if (m_instanceValue != nullptr) + { + m_instanceValue->removeDependent(this); + } +} + +void PropertySymbolDependent::addDirt(ComponentDirt value, bool recurse) +{ + writeValue(); + m_coreObjectListener->markDirty(); +} + +PropertySymbolDependentSingle::PropertySymbolDependentSingle( + Core* core, + CoreObjectListener* coreObjectListener, + ViewModelInstanceValue* instanceValue, + uint16_t propertyKey) : + PropertySymbolDependent(core, coreObjectListener, instanceValue), + m_propertyKey(propertyKey) +{} + +PropertySymbolDependentMulti::PropertySymbolDependentMulti( + Core* core, + CoreObjectListener* coreObjectListener, + ViewModelInstanceValue* instanceValue, + std::vector propertyKeys) : + PropertySymbolDependent(core, coreObjectListener, instanceValue), + m_propertyKeys(propertyKeys) +{} + +CoreObjectListener::CoreObjectListener(Core* core, + rcp instance) : + m_core(core), m_instance(instance) +{} + +CoreObjectListener::~CoreObjectListener() +{ + delete m_core; + deleteProperties(); +} + +void CoreObjectListener::createProperties() { deleteProperties(); } + +void CoreObjectListener::deleteProperties() +{ + for (auto& property : m_properties) + { + delete property; + } + m_properties.clear(); +} + +void CoreObjectListener::remap(rcp instance) +{ + if (instance != m_instance) + { + m_instance = instance; + createProperties(); + } +} \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_artboard_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_artboard_runtime.cpp new file mode 100644 index 000000000..8061a19f4 --- /dev/null +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_artboard_runtime.cpp @@ -0,0 +1,31 @@ + +#include "rive/viewmodel/runtime/viewmodel_instance_artboard_runtime.hpp" + +// Default namespace for Rive Cpp code +using namespace rive; + +void ViewModelInstanceArtboardRuntime::value( + rcp bindableArtboard) +{ + auto* artboardValue = + m_viewModelInstanceValue->as(); + // Runtime rebinding should clear any previously bound instance so switching + // to a new artboard without a VMI will not accidentally keep using stale + // data. + artboardValue->boundViewModelInstance(nullptr); + artboardValue->asset(bindableArtboard); +} + +void ViewModelInstanceArtboardRuntime::viewModelInstance( + rcp viewModelInstance) +{ + m_viewModelInstanceValue->as() + ->boundViewModelInstance(viewModelInstance); +} + +#ifdef TESTING +rcp ViewModelInstanceArtboardRuntime::testing_value() +{ + return m_viewModelInstanceValue->as()->asset(); +} +#endif diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_asset_image_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_asset_image_runtime.cpp index aba56793a..0dcbc5a2e 100644 --- a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_asset_image_runtime.cpp +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_asset_image_runtime.cpp @@ -9,3 +9,12 @@ void ViewModelInstanceAssetImageRuntime::value(RenderImage* renderImage) m_viewModelInstanceValue->as()->value( renderImage); } + +#ifdef TESTING +RenderImage* ViewModelInstanceAssetImageRuntime::testing_value() +{ + return m_viewModelInstanceValue->as() + ->asset() + ->renderImage(); +} +#endif diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_enum_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_enum_runtime.cpp index 5e95fed80..705d37ffe 100644 --- a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_enum_runtime.cpp +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_enum_runtime.cpp @@ -60,4 +60,14 @@ std::vector ViewModelInstanceEnumRuntime::values() const stringValues.push_back(value->key()); } return stringValues; +} + +std::string ViewModelInstanceEnumRuntime::enumType() const +{ + auto enumProperty = m_viewModelInstanceValue->viewModelProperty() + ->as(); + assert(enumProperty); + auto dataEnum = enumProperty->dataEnum(); + assert(dataEnum); + return dataEnum->enumName(); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_list_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_list_runtime.cpp index 6cb96ca55..dd5514043 100644 --- a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_list_runtime.cpp +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_list_runtime.cpp @@ -6,20 +6,12 @@ // Default namespace for Rive Cpp code using namespace rive; -ViewModelInstanceListRuntime::~ViewModelInstanceListRuntime() -{ - for (auto& list : m_itemsMap) - { - list.first->unref(); - list.second->unref(); - } -} - -ViewModelInstanceRuntime* ViewModelInstanceListRuntime::instanceAt(int index) +rcp ViewModelInstanceListRuntime::instanceAt( + int index) { auto listItems = m_viewModelInstanceValue->as()->listItems(); - if (index > listItems.size() || index < 0) + if (index >= listItems.size() || index < 0) { return nullptr; } @@ -31,32 +23,46 @@ ViewModelInstanceRuntime* ViewModelInstanceListRuntime::instanceAt(int index) auto it = m_itemsMap.find(listItem); if (it != m_itemsMap.end()) { - return it->second; + return rcp(it->second); } auto instanceRuntime = - new ViewModelInstanceRuntime(listItem->viewModelInstance()); + make_rcp(listItem->viewModelInstance()); m_itemsMap[listItem] = instanceRuntime; - return instanceRuntime; + return rcp(instanceRuntime); } void ViewModelInstanceListRuntime::addInstance( ViewModelInstanceRuntime* instanceRuntime) { - instanceRuntime->ref(); - auto listItem = new ViewModelInstanceListItem(); + auto listItem = make_rcp(); listItem->viewModelInstance(instanceRuntime->instance()); auto list = m_viewModelInstanceValue->as(); - m_itemsMap[listItem] = instanceRuntime; + m_itemsMap[listItem] = ref_rcp(instanceRuntime); list->addItem(listItem); } +bool ViewModelInstanceListRuntime::addInstanceAt( + ViewModelInstanceRuntime* instanceRuntime, + int index) +{ + auto listItem = make_rcp(); + auto list = m_viewModelInstanceValue->as(); + if (list->addItemAt(listItem, index)) + { + listItem->viewModelInstance(instanceRuntime->instance()); + m_itemsMap[listItem] = ref_rcp(instanceRuntime); + return true; + } + return false; +} + void ViewModelInstanceListRuntime::removeInstance( ViewModelInstanceRuntime* instanceRuntime) { auto instanceList = m_viewModelInstanceValue->as(); auto listItems = instanceList->listItems(); // The same instance might be present multiple times in the list - std::vector itemsToRemove; + std::vector> itemsToRemove; for (auto& item : listItems) { if (item->viewModelInstance().get() == @@ -70,8 +76,7 @@ void ViewModelInstanceListRuntime::removeInstance( auto it = m_itemsMap.find(item); if (it != m_itemsMap.end()) { - it->first->unref(); - it->second->unref(); + m_itemsMap.erase(it); } instanceList->removeItem(item); } @@ -81,7 +86,6 @@ void ViewModelInstanceListRuntime::removeInstanceAt(int index) { auto instanceList = m_viewModelInstanceValue->as(); auto listItems = instanceList->listItems(); - std::vector itemsToRemove; if (index >= 0 && index < listItems.size()) { auto listItem = listItems[index]; @@ -90,8 +94,7 @@ void ViewModelInstanceListRuntime::removeInstanceAt(int index) auto it = m_itemsMap.find(listItem); if (it != m_itemsMap.end()) { - it->first->unref(); - it->second->unref(); + m_itemsMap.erase(it); } } } @@ -102,6 +105,12 @@ void ViewModelInstanceListRuntime::swap(uint32_t a, uint32_t b) instanceList->swap(a, b); } +void ViewModelInstanceListRuntime::removeAllInstances() +{ + m_viewModelInstanceValue->as()->removeAllItems(); + m_itemsMap.clear(); +} + size_t ViewModelInstanceListRuntime::size() const { auto listItems = diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_runtime.cpp index 21f33d301..55e23e891 100644 --- a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_runtime.cpp +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_runtime.cpp @@ -43,6 +43,11 @@ const std::string& ViewModelInstanceRuntime::name() const return m_viewModelInstance->name(); } +const std::string& ViewModelInstanceRuntime::viewModelName() const +{ + return m_viewModelInstance->viewModel()->name(); +} + size_t ViewModelInstanceRuntime::propertyCount() const { return m_viewModelInstance->propertyValues().size(); @@ -104,6 +109,24 @@ ViewModelInstanceValueRuntime* ViewModelInstanceRuntime::property( case DataType::boolean: return viewModelInstanceRuntime->propertyBoolean( propertyName); + case DataType::color: + return viewModelInstanceRuntime->propertyColor( + propertyName); + case DataType::assetImage: + return viewModelInstanceRuntime->propertyImage( + propertyName); + case DataType::artboard: + return viewModelInstanceRuntime->propertyArtboard( + propertyName); + case DataType::list: + return viewModelInstanceRuntime->propertyList( + propertyName); + case DataType::enumType: + return viewModelInstanceRuntime->propertyEnum( + propertyName); + case DataType::trigger: + return viewModelInstanceRuntime->propertyTrigger( + propertyName); default: break; } @@ -265,27 +288,27 @@ rcp ViewModelInstanceRuntime::instanceRuntime( auto itr = m_viewModelInstances.find(name); if (itr != m_viewModelInstances.end()) { - return static_cast>(itr->second); + return itr->second; } auto viewModelInstance = viewModelInstanceProperty(name); if (viewModelInstance != nullptr) { - auto viewModelInstanceRef = rcp( - new ViewModelInstanceRuntime(viewModelInstance)); + auto viewModelInstanceRef = + make_rcp(viewModelInstance); m_viewModelInstances[name] = viewModelInstanceRef; return viewModelInstanceRef; } return nullptr; } -ViewModelInstanceRuntime* ViewModelInstanceRuntime::propertyViewModel( +rcp ViewModelInstanceRuntime::propertyViewModel( const std::string& path) const { const auto propertyName = getPropertyNameFromPath(path); auto viewModelInstance = viewModelInstanceFromFullPath(path); if (viewModelInstance != nullptr) { - return viewModelInstance->instanceRuntime(propertyName).get(); + return viewModelInstance->instanceRuntime(propertyName); } return nullptr; } @@ -306,6 +329,22 @@ ViewModelInstanceAssetImageRuntime* ViewModelInstanceRuntime::propertyImage( return nullptr; } +ViewModelInstanceArtboardRuntime* ViewModelInstanceRuntime::propertyArtboard( + const std::string& path) const +{ + const auto propertyName = getPropertyNameFromPath(path); + auto viewModelInstance = viewModelInstanceFromFullPath(path); + if (viewModelInstance != nullptr) + { + + return viewModelInstance + ->getPropertyInstance( + propertyName); + } + return nullptr; +} + bool ViewModelInstanceRuntime::replaceViewModel( const std::string& path, ViewModelInstanceRuntime* value) const @@ -336,8 +375,7 @@ bool ViewModelInstanceRuntime::replaceViewModelByName( } if (!isStored) { - value->ref(); - m_viewModelInstances[name] = rcp(value); + m_viewModelInstances[name] = ref_rcp(value); } return true; } diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_value_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_value_runtime.cpp index b4f91156a..fce5ca719 100644 --- a/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_value_runtime.cpp +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_instance_value_runtime.cpp @@ -24,6 +24,8 @@ ViewModelInstanceValueRuntime::ViewModelInstanceValueRuntime( instanceValue->addDependent(this); } +void ViewModelInstanceValueRuntime::relinkDataBind() {} + void ViewModelInstanceValueRuntime::addDirt(ComponentDirt dirt, bool recurse) { m_hasChanged = true; diff --git a/thirdparty/rive/source/viewmodel/runtime/viewmodel_runtime.cpp b/thirdparty/rive/source/viewmodel/runtime/viewmodel_runtime.cpp index f99869dc3..f625b8c94 100644 --- a/thirdparty/rive/source/viewmodel/runtime/viewmodel_runtime.cpp +++ b/thirdparty/rive/source/viewmodel/runtime/viewmodel_runtime.cpp @@ -1,6 +1,7 @@ #include "rive/viewmodel/runtime/viewmodel_runtime.hpp" #include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property_asset_image.hpp" #include "rive/viewmodel/viewmodel_property_string.hpp" #include "rive/viewmodel/viewmodel_property_number.hpp" #include "rive/viewmodel/viewmodel_property_boolean.hpp" @@ -10,7 +11,9 @@ #include "rive/viewmodel/viewmodel_property_enum_custom.hpp" #include "rive/viewmodel/viewmodel_property_enum_system.hpp" #include "rive/viewmodel/viewmodel_property_trigger.hpp" +#include "rive/viewmodel/viewmodel_property_symbol_list_index.hpp" #include "rive/viewmodel/viewmodel_property_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property_artboard.hpp" #include "rive/file.hpp" #include "rive/refcnt.hpp" @@ -71,6 +74,15 @@ std::vector ViewModelRuntime::buildPropertiesData( case ViewModelPropertyViewModelBase::typeKey: type = DataType::viewModel; break; + case ViewModelPropertySymbolListIndex::typeKey: + type = DataType::symbolListIndex; + break; + case ViewModelPropertyAssetImage::typeKey: + type = DataType::assetImage; + break; + case ViewModelPropertyArtboard::typeKey: + type = DataType::artboard; + break; default: break; } @@ -96,7 +108,7 @@ std::vector ViewModelRuntime::instanceNames() const return names; } -ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromIndex( +rcp ViewModelRuntime::createInstanceFromIndex( const size_t index) const { auto viewModelInstance = m_viewModel->instance(index); @@ -117,7 +129,7 @@ ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromIndex( return nullptr; } -ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromName( +rcp ViewModelRuntime::createInstanceFromName( const std::string& name) const { auto viewModelInstance = m_viewModel->instance(name); @@ -139,7 +151,7 @@ ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromName( return nullptr; } -ViewModelInstanceRuntime* ViewModelRuntime::createDefaultInstance() const +rcp ViewModelRuntime::createDefaultInstance() const { auto viewModelInstance = m_file->createDefaultViewModelInstance(m_viewModel); @@ -152,21 +164,20 @@ ViewModelInstanceRuntime* ViewModelRuntime::createDefaultInstance() const return createInstance(); } -ViewModelInstanceRuntime* ViewModelRuntime::createInstance() const +rcp ViewModelRuntime::createInstance() const { auto instance = m_file->createViewModelInstance(m_viewModel); return createRuntimeInstance(instance); } -ViewModelInstanceRuntime* ViewModelRuntime::createRuntimeInstance( +rcp ViewModelRuntime::createRuntimeInstance( rcp instance) const { if (instance != nullptr) { auto viewModelInstanceRuntime = rcp( new ViewModelInstanceRuntime(instance)); - m_viewModelInstanceRuntimes.push_back(viewModelInstanceRuntime); - return viewModelInstanceRuntime.get(); + return viewModelInstanceRuntime; } return nullptr; } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel.cpp b/thirdparty/rive/source/viewmodel/viewmodel.cpp index 792d6e4ae..830b403c2 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel.cpp @@ -31,11 +31,23 @@ ViewModelProperty* ViewModel::property(size_t index) return nullptr; } -ViewModelProperty* ViewModel::property(const std::string& name) +ViewModelProperty* ViewModel::property(const std::string& propName) { for (auto property : m_Properties) { - if (property->name() == name) + if (property->name() == propName) + { + return property; + } + } + return nullptr; +} + +ViewModelProperty* ViewModel::property(const SymbolType symbolType) +{ + for (auto property : m_Properties) + { + if (property->symbolTypeValue() == static_cast(symbolType)) { return property; } @@ -80,4 +92,23 @@ ViewModelInstance* ViewModel::instance(const std::string& name) return nullptr; } -size_t ViewModel::instanceCount() const { return m_Instances.size(); } \ No newline at end of file +size_t ViewModel::instanceCount() const { return m_Instances.size(); } + +rcp ViewModel::createInstance() +{ + if (m_file) + { + return m_file->createViewModelInstance(this); + } + return nullptr; +} + +rcp ViewModel::createFromInstance( + const std::string& instanceName) +{ + if (m_file) + { + return m_file->createViewModelInstance(this->name(), instanceName); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance.cpp index 95b3398cc..ddd33cdc0 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance.cpp @@ -5,11 +5,16 @@ #include "rive/viewmodel/viewmodel_instance.hpp" #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance_symbol_list_index.hpp" +#include "rive/file.hpp" #include "rive/importers/viewmodel_importer.hpp" +#include "rive/importers/artboard_importer.hpp" #include "rive/viewmodel/viewmodel_property_viewmodel.hpp" #include "rive/core_context.hpp" #include "rive/refcnt.hpp" +#include "rive/artboard.hpp" using namespace rive; @@ -17,7 +22,15 @@ ViewModelInstance::~ViewModelInstance() { for (auto& value : m_PropertyValues) { - value->unref(); + if (value->is()) + { + auto vmInstanceViewModel = value->as(); + if (vmInstanceViewModel->referenceViewModelInstance()) + { + vmInstanceViewModel->referenceViewModelInstance()->removeParent( + this); + } + } } m_PropertyValues.clear(); if (m_ViewModel != nullptr) @@ -28,7 +41,27 @@ ViewModelInstance::~ViewModelInstance() void ViewModelInstance::addValue(ViewModelInstanceValue* value) { - m_PropertyValues.push_back(value); + // Check if already added (can happen when both import() and onAddedDirty() + // add the same value). + for (const auto& existing : m_PropertyValues) + { + if (existing.get() == value) + { + return; + } + } + if (value) + { + value->viewModelInstance(this); + } + if (value->viewModelProperty() != nullptr && + (SymbolType)value->viewModelProperty()->symbolTypeValue() != + SymbolType::none) + { + propertyValue((SymbolType)value->viewModelProperty()->symbolTypeValue(), + value); + } + m_PropertyValues.push_back(rcp(value)); } ViewModelInstanceValue* ViewModelInstance::propertyValue(const uint32_t id) @@ -37,7 +70,7 @@ ViewModelInstanceValue* ViewModelInstance::propertyValue(const uint32_t id) { if (value->viewModelPropertyId() == id) { - return value; + return value.get(); } } return nullptr; @@ -57,8 +90,16 @@ bool ViewModelInstance::replaceViewModelByName(const std::string& name, viewModelProperty->as() ->viewModelReferenceId()) { + auto previousViewModelInstance = + propertyValue->as() + ->referenceViewModelInstance(); propertyValue->as() ->referenceViewModelInstance(value); + rebindDependents(); + if (previousViewModelInstance) + { + previousViewModelInstance->rebindProperties(); + } return true; } break; @@ -68,18 +109,60 @@ bool ViewModelInstance::replaceViewModelByName(const std::string& name, return false; } -ViewModelInstanceValue* ViewModelInstance::propertyValue( - const std::string& name) +bool ViewModelInstance::replaceViewModelByProperty( + ViewModelInstanceViewModel* property, + rcp value) { - auto viewModelProperty = viewModel()->property(name); - if (viewModelProperty != nullptr) + for (auto& propertyValue : m_PropertyValues) { - for (auto value : m_PropertyValues) + if (propertyValue.get() == property) { - if (value->viewModelProperty() == viewModelProperty) + auto previousViewModelInstance = + propertyValue->as() + ->referenceViewModelInstance(); + propertyValue->as() + ->referenceViewModelInstance(value); + rebindDependents(); + if (previousViewModelInstance) { - return value; + previousViewModelInstance->rebindProperties(); } + return true; + } + } + return false; +} + +void ViewModelInstance::propertyValue(const SymbolType symbolType, + ViewModelInstanceValue* value) +{ + if (symbolType != SymbolType::none) + { + m_propertySymbols[symbolType] = value; + } +} + +ViewModelInstanceValue* ViewModelInstance::propertyValue( + const SymbolType symbolType) +{ + + auto propertyIt = m_propertySymbols.find(symbolType); + if (propertyIt != m_propertySymbols.end()) + { + return propertyIt->second; + } + return nullptr; +} + +ViewModelInstanceValue* ViewModelInstance::propertyValue( + const std::string& name) +{ + for (auto value : m_PropertyValues) + { + if (value->viewModelProperty() && + value->viewModelProperty()->name() == name) + { + return value.get(); } } return nullptr; @@ -112,7 +195,8 @@ void ViewModelInstance::setRoot(rcp value) } } -std::vector ViewModelInstance::propertyValues() +const std::vector>& ViewModelInstance:: + propertyValues() { return m_PropertyValues; } @@ -121,10 +205,17 @@ Core* ViewModelInstance::clone() const { auto cloned = new ViewModelInstance(); cloned->copy(*this); - for (auto propertyValue : m_PropertyValues) + + // If we have an artboard, it means we will be in the artboard's object + // list which will clone our property values for us + if (artboard() == nullptr) { - auto clonedValue = propertyValue->clone()->as(); - cloned->addValue(clonedValue); + for (auto propertyValue : m_PropertyValues) + { + auto clonedValue = + propertyValue->clone()->as(); + cloned->addValue(clonedValue); + } } cloned->viewModel(viewModel()); return cloned; @@ -140,6 +231,22 @@ StatusCode ViewModelInstance::import(ImportStack& importStack) } viewModelImporter->addInstance(this); + + auto artboardImporter = + importStack.latest(ArtboardBase::typeKey); + if (artboardImporter != nullptr) + { + return Super::import(importStack); + } + + // Only add ViewModelInstances at the File level if they are not + // in the Component hierarchy. + auto file = viewModelImporter->file(); + if (file != nullptr) + { + file->addFileViewModelInstance(this); + } + return StatusCode::Ok; } @@ -178,14 +285,74 @@ void ViewModelInstance::advanced() } } -ViewModelInstanceValue* ViewModelInstance::symbol(int coreType) +void ViewModelInstance::addParent(ViewModelInstance* parent) { - for (auto& value : m_PropertyValues) + if (!parent) + { + return; + } + auto p = std::find(m_parents.begin(), m_parents.end(), parent); + if (p == m_parents.end()) + { + m_parents.push_back(parent); + } +} + +void ViewModelInstance::removeParent(ViewModelInstance* parent) +{ + m_parents.erase(std::remove(m_parents.begin(), m_parents.end(), parent), + m_parents.end()); +} + +void ViewModelInstance::addDependent(DataBindContainer* dependent) +{ + if (!dependent) + { + return; + } + auto p = std::find(m_dependents.begin(), m_dependents.end(), dependent); + if (p == m_dependents.end()) { - if (value->coreType() == coreType) + m_dependents.push_back(dependent); + } +} + +void ViewModelInstance::removeDependent(DataBindContainer* dependent) +{ + m_dependents.erase( + std::remove(m_dependents.begin(), m_dependents.end(), dependent), + m_dependents.end()); +} + +void ViewModelInstance::rebindProperties() +{ + for (auto& property : m_PropertyValues) + { + auto dependents = property->dependents(); + for (auto& dependent : dependents) { - return value; + dependent->relinkDataBind(); + } + if (property->is()) + { + auto viewModelInstance = property->as() + ->referenceViewModelInstance(); + if (viewModelInstance) + { + viewModelInstance->rebindProperties(); + } } } - return nullptr; -} \ No newline at end of file +} + +void ViewModelInstance::rebindDependents() +{ + for (auto& dependent : m_dependents) + { + dependent->relinkDataContext(); + } + for (auto& parent : m_parents) + { + parent->rebindDependents(); + } +} diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_artboard.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_artboard.cpp new file mode 100644 index 000000000..4c9ffd2e1 --- /dev/null +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_artboard.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_artboard.hpp" +#include "rive/component_dirt.hpp" +#include "rive/refcnt.hpp" + +using namespace rive; + +void ViewModelInstanceArtboard::propertyValueChanged() +{ + m_bindableArtboard = nullptr; + addDirt(ComponentDirt::Bindings); +#ifdef WITH_RIVE_TOOLS + if (m_changedCallback != nullptr) + { + m_changedCallback(this, propertyValue()); + } +#endif + onValueChanged(); +} + +void ViewModelInstanceArtboard::asset(rcp value) +{ + propertyValue(-1); + m_bindableArtboard = value; + addDirt(ComponentDirt::Bindings); +} + +void ViewModelInstanceArtboard::applyValue(DataValueInteger* dataValue) +{ + propertyValue(dataValue->value()); +} + +void ViewModelInstanceArtboard::boundViewModelInstance( + rcp value) +{ + m_boundViewModelInstance = value; +} + +void ViewModelInstanceArtboard::advanced() +{ + if (m_boundViewModelInstance != nullptr) + { + m_boundViewModelInstance->advanced(); + } + + ViewModelInstanceValue::advanced(); +} \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_asset_image.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_asset_image.cpp index 768c098af..7ef0ab291 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_asset_image.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_asset_image.cpp @@ -5,9 +5,15 @@ #include "rive/viewmodel/viewmodel_instance_asset_image.hpp" #include "rive/component_dirt.hpp" #include "rive/refcnt.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_asset_image.hpp" using namespace rive; +ViewModelInstanceAssetImage::ViewModelInstanceAssetImage() : + m_imageAsset(rcp(new ImageAsset())) +{} + void ViewModelInstanceAssetImage::propertyValueChanged() { addDirt(ComponentDirt::Bindings); @@ -17,18 +23,56 @@ void ViewModelInstanceAssetImage::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); } void ViewModelInstanceAssetImage::value(RenderImage* image) { - if (m_imageAsset.renderImage() == image || image == nullptr) + if (m_imageAsset->renderImage() == image) { + propertyValue(-1); return; } +#ifdef WITH_RIVE_TOOLS + const bool alreadySentinel = (propertyValue() == static_cast(-1)); +#endif + if (image == nullptr) + { + m_imageAsset->renderImage(nullptr); + } + else + { + image->ref(); + m_imageAsset->renderImage(rcp(image)); + } +#ifdef WITH_RIVE_TOOLS + if (!alreadySentinel) + { + propertyValue(-1); + } + else if (m_changedCallback != nullptr) + { + m_changedCallback(this, propertyValue()); + } +#else propertyValue(-1); - image->ref(); - m_imageAsset.renderImage(rcp(image)); +#endif addDirt(ComponentDirt::Bindings); + onValueChanged(); +} + +void ViewModelInstanceAssetImage::applyValue(DataValueInteger* dataValue) +{ + if (dataValue && dataValue->is()) + { + auto renderImage = dataValue->as()->imageValue(); + value(renderImage); + if (renderImage) + { + return; + } + } + propertyValue(dataValue->value()); } Core* ViewModelInstanceAssetImage::clone() const diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_boolean.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_boolean.cpp index 72b85f3c8..1d55eeee9 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_boolean.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_boolean.cpp @@ -16,4 +16,10 @@ void ViewModelInstanceBoolean::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); +} + +void ViewModelInstanceBoolean::applyValue(DataValueBoolean* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_color.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_color.cpp index 468f6d0c0..5c11b8e3a 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_color.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_color.cpp @@ -16,4 +16,10 @@ void ViewModelInstanceColor::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); +} + +void ViewModelInstanceColor::applyValue(DataValueColor* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_enum.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_enum.cpp index 7c0728d65..e981f5773 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_enum.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_enum.cpp @@ -17,6 +17,7 @@ void ViewModelInstanceEnum::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); } bool ViewModelInstanceEnum::value(std::string name) @@ -40,4 +41,9 @@ bool ViewModelInstanceEnum::value(uint32_t index) return true; } return false; +} + +void ViewModelInstanceEnum::applyValue(DataValueInteger* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_list.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_list.cpp index fd792db38..c0f774643 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_list.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_list.cpp @@ -10,40 +10,66 @@ using namespace rive; ViewModelInstanceList::~ViewModelInstanceList() { - for (auto item : m_ListItems) + if (parentViewModelInstance()) { - item->unref(); + for (auto& item : m_ListItems) + { + if (item->viewModelInstance() != nullptr) + { + item->viewModelInstance()->removeParent( + parentViewModelInstance()); + } + } } } void ViewModelInstanceList::propertyValueChanged() { addDirt(ComponentDirt::Bindings); +#ifdef WITH_RIVE_TOOLS + if (m_changedCallback != nullptr) + { + m_changedCallback(this); + } +#endif + onValueChanged(); } -void ViewModelInstanceList::addItem(ViewModelInstanceListItem* item) +void ViewModelInstanceList::addItem(rcp item) { - item->ref(); m_ListItems.push_back(item); + if (item->viewModelInstance()) + { + item->viewModelInstance()->addParent(parentViewModelInstance()); + } propertyValueChanged(); } -void ViewModelInstanceList::internalAddItem(ViewModelInstanceListItem* item) +bool ViewModelInstanceList::addItemAt(rcp item, + int index) { - // For ViewModelInstanceListItems that are built as a core object - // we skip the ref since core has already reffed it - m_ListItems.push_back(item); + if (index >= 0 && index <= m_ListItems.size()) + { + m_ListItems.insert(m_ListItems.begin() + index, item); + + if (item->viewModelInstance()) + { + item->viewModelInstance()->addParent(parentViewModelInstance()); + } + propertyValueChanged(); + return true; + } + return false; } -void ViewModelInstanceList::insertItem(int index, - ViewModelInstanceListItem* item) +void ViewModelInstanceList::internalAddItem(rcp item) { - // TODO: @hernan decide if we want to return a boolean - if (index < m_ListItems.size()) + // For ViewModelInstanceListItems that are built as a core object + // we skip the ref since core has already reffed it + m_ListItems.push_back(item); + if (item->viewModelInstance()) { - item->ref(); - m_ListItems.insert(m_ListItems.begin() + index, item); - propertyValueChanged(); + item->viewModelInstance()->addParent(parentViewModelInstance()); } } @@ -53,21 +79,99 @@ void ViewModelInstanceList::removeItem(int index) if (index >= 0 && index < m_ListItems.size()) { auto listItem = m_ListItems[index]; + if (listItem->viewModelInstance()) + { + listItem->viewModelInstance()->removeParent( + parentViewModelInstance()); + } m_ListItems.erase(m_ListItems.begin() + index); - listItem->unref(); propertyValueChanged(); } } -void ViewModelInstanceList::removeItem(ViewModelInstanceListItem* listItem) +rcp ViewModelInstanceList::pop() +{ + if (m_ListItems.size() > 0) + { + + auto listItem = m_ListItems.back(); + m_ListItems.pop_back(); + propertyValueChanged(); + return listItem; + } + return nullptr; +} + +rcp ViewModelInstanceList::shift() +{ + if (m_ListItems.size() > 0) + { + + auto listItem = m_ListItems.front(); + removeItem(0); + return listItem; + } + return nullptr; +} + +void ViewModelInstanceList::removeItem(rcp listItem) { auto noSpaceEnd = std::remove(m_ListItems.begin(), m_ListItems.end(), listItem); m_ListItems.erase(noSpaceEnd, m_ListItems.end()); + if (listItem->viewModelInstance()) + { + listItem->viewModelInstance()->removeParent(parentViewModelInstance()); + } propertyValueChanged(); } -ViewModelInstanceListItem* ViewModelInstanceList::item(uint32_t index) +void ViewModelInstanceList::removeAllItems() +{ + if (m_ListItems.size() > 0) + { + for (auto& listItem : m_ListItems) + { + if (listItem->viewModelInstance()) + { + listItem->viewModelInstance()->removeParent( + parentViewModelInstance()); + } + } + m_ListItems.clear(); + propertyValueChanged(); + } +} + +void ViewModelInstanceList::removeAllItemsWithViewModelInstance( + ViewModelInstance* viewModelInstance) +{ + if (viewModelInstance == nullptr || m_ListItems.empty()) + { + return; + } + + bool changed = false; + for (auto it = m_ListItems.begin(); it != m_ListItems.end();) + { + if ((*it)->viewModelInstance().get() == viewModelInstance) + { + (*it)->viewModelInstance()->removeParent(parentViewModelInstance()); + it = m_ListItems.erase(it); + changed = true; + } + else + { + ++it; + } + } + if (changed) + { + propertyValueChanged(); + } +} + +rcp ViewModelInstanceList::item(uint32_t index) { if (index < m_ListItems.size()) { @@ -86,6 +190,40 @@ void ViewModelInstanceList::swap(uint32_t index1, uint32_t index2) } } +void ViewModelInstanceList::updateList( + std::vector>* list) +{ + if (list == nullptr) + { + return; + } + + // Detach old children from this host instance before replacing the list. + if (parentViewModelInstance()) + { + for (auto& item : m_ListItems) + { + if (item->viewModelInstance() != nullptr) + { + item->viewModelInstance()->removeParent( + parentViewModelInstance()); + } + } + } + + m_ListItems.clear(); + m_ListItems.reserve(list->size()); + for (auto& item : *list) + { + m_ListItems.push_back(item); + if (parentViewModelInstance() && item->viewModelInstance() != nullptr) + { + item->viewModelInstance()->addParent(parentViewModelInstance()); + } + } + propertyValueChanged(); +} + Core* ViewModelInstanceList::clone() const { auto cloned = new ViewModelInstanceList(); @@ -93,7 +231,19 @@ Core* ViewModelInstanceList::clone() const for (auto property : m_ListItems) { auto clonedValue = property->clone()->as(); - cloned->internalAddItem(clonedValue); + cloned->internalAddItem(rcp(clonedValue)); } return cloned; +} + +void ViewModelInstanceList::advanced() +{ + for (auto item : m_ListItems) + { + if (item->viewModelInstance() != nullptr) + { + item->viewModelInstance()->advanced(); + } + } + ViewModelInstanceValue::advanced(); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_list_item.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_list_item.cpp index 715f9c2f1..0dcb108d7 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_list_item.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_list_item.cpp @@ -17,7 +17,7 @@ StatusCode ViewModelInstanceListItem::import(ImportStack& importStack) { return StatusCode::MissingObject; } - viewModelInstanceList->addItem(this); + viewModelInstanceList->addItem(rcp(this)); return Super::import(importStack); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_number.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_number.cpp index cbd5e094c..59856fbff 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_number.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_number.cpp @@ -16,4 +16,10 @@ void ViewModelInstanceNumber::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); +} + +void ViewModelInstanceNumber::applyValue(DataValueNumber* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_string.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_string.cpp index 58505eba5..83b38b170 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_string.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_string.cpp @@ -16,4 +16,10 @@ void ViewModelInstanceString::propertyValueChanged() m_changedCallback(this, propertyValue().c_str()); } #endif + onValueChanged(); +} + +void ViewModelInstanceString::applyValue(DataValueString* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_symbol_list_index.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_symbol_list_index.cpp index db43f2d0a..02f893da5 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_symbol_list_index.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_symbol_list_index.cpp @@ -16,4 +16,10 @@ void ViewModelInstanceSymbolListIndex::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); +} + +void ViewModelInstanceSymbolListIndex::applyValue(DataValueInteger* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_trigger.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_trigger.cpp index 9f50c0f76..a5db70108 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_trigger.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_trigger.cpp @@ -16,10 +16,18 @@ void ViewModelInstanceTrigger::propertyValueChanged() m_changedCallback(this, propertyValue()); } #endif + onValueChanged(); } void ViewModelInstanceTrigger::advanced() { + SuppressDelegation suppress(this); propertyValue(0); - m_usedLayers.clear(); + + ViewModelInstanceValue::advanced(); +} + +void ViewModelInstanceTrigger::applyValue(DataValueInteger* dataValue) +{ + propertyValue(dataValue->value()); } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_value.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_value.cpp index 074db3566..e5ae3d8b6 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_value.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_value.cpp @@ -1,15 +1,38 @@ #include #include #include +#include +#include "rive/artboard.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_property_symbol_list_index.hpp" +#include "rive/importers/artboard_importer.hpp" #include "rive/importers/viewmodel_instance_importer.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/refcnt.hpp" using namespace rive; +StatusCode ViewModelInstanceValue::onAddedDirty(CoreContext* context) +{ + StatusCode result = Super::onAddedDirty(context); + if (result != StatusCode::Ok) + { + return result; + } + + // If parent is a ViewModelInstance, register with it. + // This handles stateful ViewModelInstances (children of NestedArtboard) + // where values are cloned separately during artboard cloning. + if (parent() != nullptr && parent()->is()) + { + parent()->as()->addValue(this); + } + + return StatusCode::Ok; +} + StatusCode ViewModelInstanceValue::import(ImportStack& importStack) { auto viewModelInstanceImporter = @@ -21,24 +44,58 @@ StatusCode ViewModelInstanceValue::import(ImportStack& importStack) } viewModelInstanceImporter->addValue(this); - return Super::import(importStack); + // If we're inside an artboard context, import through Component so we're + // added to the artboard's object list and can be resolved by ID. + auto artboardImporter = + importStack.latest(ArtboardBase::typeKey); + if (artboardImporter != nullptr) + { + return Super::import(importStack); + } + + return Core::import(importStack); +} + +bool ViewModelInstanceValue::hasChanged() +{ + return enums::is_flag_set(m_changeFlags, ValueFlags::valueChanged); +} + +void ViewModelInstanceValue::registerSymbol() +{ + + if (m_ViewModelProperty != nullptr && m_viewModelInstance != nullptr) + { + if (m_ViewModelProperty->is()) + { + m_viewModelInstance->propertyValue(SymbolType::itemIndex, this); + } + else if ((SymbolType)m_ViewModelProperty->symbolTypeValue() != + SymbolType::none) + { + m_viewModelInstance->propertyValue( + (SymbolType)m_ViewModelProperty->symbolTypeValue(), + this); + } + } } void ViewModelInstanceValue::viewModelProperty(ViewModelProperty* value) { m_ViewModelProperty = value; + registerSymbol(); } ViewModelProperty* ViewModelInstanceValue::viewModelProperty() { return m_ViewModelProperty; } -void ViewModelInstanceValue::addDependent(Dirtyable* value) +void ViewModelInstanceValue::addDependent(ViewModelValueDependent* value) { m_DependencyHelper.addDependent(value); } -void ViewModelInstanceValue::removeDependent(Dirtyable* value) +void ViewModelInstanceValue::removeDependent(ViewModelValueDependent* value) { m_DependencyHelper.removeDependent(value); } @@ -62,4 +119,84 @@ const std::string& ViewModelInstanceValue::name() const return m_ViewModelProperty->constName(); }; return defaultName; +} + +void ViewModelInstanceValue::advanced() +{ + m_usedLayers.clear(); + m_changeFlags &= ~ValueFlags::valueChanged; +} + +void ViewModelInstanceValue::viewModelInstance(ViewModelInstance* value) +{ + m_viewModelInstance = value; + registerSymbol(); +} + +void ViewModelInstanceValue::addDelegate( + ViewModelInstanceValueDelegate* delegate) +{ + m_delegates.push_back(delegate); + m_changeFlags |= ValueFlags::delegatesChanged; +} + +void ViewModelInstanceValue::removeDelegate( + ViewModelInstanceValueDelegate* delegate) +{ + auto itr = std::find(m_delegates.begin(), m_delegates.end(), delegate); + if (itr == m_delegates.end()) + { + return; + } + m_delegates.erase(itr); + m_changeFlags |= ValueFlags::delegatesChanged; +} + +bool ViewModelInstanceValue::suppressDelegation() +{ + if (enums::is_flag_set(m_changeFlags, ValueFlags::delegating)) + { + return false; + } + m_changeFlags |= ValueFlags::delegating; + return true; +} + +void ViewModelInstanceValue::restoreDelegation() +{ + m_changeFlags &= ~ValueFlags::delegating; +} + +void ViewModelInstanceValue::onValueChanged() +{ + m_changeFlags |= ValueFlags::valueChanged; + + if (enums::is_flag_set(m_changeFlags, ValueFlags::delegatesChanged)) + { + m_delegatesCopy.clear(); + std::copy(m_delegates.begin(), + m_delegates.end(), + std::back_inserter(m_delegatesCopy)); + m_changeFlags &= ~ValueFlags::delegatesChanged; + } + + if (enums::is_flag_set(m_changeFlags, ValueFlags::delegating)) + { + // We're already calling delegates for this value change, changing the + // value in a delegate will not report the change. + return; + } + + // Flag to guard against calling this recursively. + m_changeFlags |= ValueFlags::delegating; + + // Iterate over a copy of the delegates in case delegates get changed in + // valueChanged callbacks. + for (auto delegate : m_delegatesCopy) + { + delegate->valueChanged(); + } + + // Clear guard flag. + m_changeFlags &= ~ValueFlags::delegating; } \ No newline at end of file diff --git a/thirdparty/rive/source/viewmodel/viewmodel_instance_viewmodel.cpp b/thirdparty/rive/source/viewmodel/viewmodel_instance_viewmodel.cpp index a5fac9614..b009dd754 100644 --- a/thirdparty/rive/source/viewmodel/viewmodel_instance_viewmodel.cpp +++ b/thirdparty/rive/source/viewmodel/viewmodel_instance_viewmodel.cpp @@ -3,15 +3,38 @@ #include #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/data_bind/data_values/data_value_viewmodel.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property_viewmodel.hpp" +#include "rive/refcnt.hpp" +#include "rive/backboard.hpp" +#include "rive/file.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/backboard_importer.hpp" +#include "rive/importers/artboard_importer.hpp" +#include "rive/importers/viewmodel_instance_importer.hpp" using namespace rive; -ViewModelInstanceViewModel::~ViewModelInstanceViewModel() {} +void ViewModelInstanceViewModel::propertyValueChanged() +{ + addDirt(ComponentDirt::Bindings); +#ifdef WITH_RIVE_TOOLS + if (m_changedCallback != nullptr) + { + m_changedCallback(this); + } +#endif + onValueChanged(); +} void ViewModelInstanceViewModel::setRoot(rcp value) { Super::setRoot(value); - m_referenceViewModelInstance->setRoot(value); + if (m_referenceViewModelInstance) + { + m_referenceViewModelInstance->setRoot(value); + } } void ViewModelInstanceViewModel::advanced() @@ -20,4 +43,97 @@ void ViewModelInstanceViewModel::advanced() { m_referenceViewModelInstance->advanced(); } +} + +StatusCode ViewModelInstanceViewModel::import(ImportStack& importStack) +{ + auto status = Super::import(importStack); + auto artboardImporter = + importStack.latest(ArtboardBase::typeKey); + if (artboardImporter != nullptr) + { + + auto backboardImporter = + importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + auto file = backboardImporter->file(); + // Look for the referenced view model instance of this property + // In order to find it we need to go through some steps: + // - find the view model instance this property belongs to (O(1)) + // - find the view model from which its an instance of (O(1)) + // - find the view model property from which this is an instance of + // (O(1)) + // - find the view model the property is referencing to (O(1)) + // - find the specific instance this instance value is pointing to + // (O(1)) + if (file) + { + auto viewModelInstanceImporter = + importStack.latest( + ViewModelInstance::typeKey); + auto viewModelInstance = + viewModelInstanceImporter->viewModelInstance(); + if (viewModelInstance) + { + auto viewModel = + file->viewModel(viewModelInstance->viewModelId()); + if (viewModel) + { + auto viewModelProperty = + viewModel->property(viewModelPropertyId()); + if (viewModelProperty != nullptr && + viewModelProperty->is()) + { + auto viewModelPropertyViewModel = + viewModelProperty->as(); + auto referencedViewModel = file->viewModel( + viewModelPropertyViewModel->viewModelReferenceId()); + if (referencedViewModel) + { + auto instance = + referencedViewModel->instance(propertyValue()); + if (instance) + { + referenceViewModelInstance(ref_rcp(instance)); + } + } + } + } + } + } + } + + return status; +} + +void ViewModelInstanceViewModel::updateViewModel(ViewModelInstance* value) +{ + m_viewModelInstance->replaceViewModelByProperty(this, ref_rcp(value)); + auto dependentsSnapshot = dependents(); + for (auto& dependent : dependentsSnapshot) + { + dependent->relinkDataBind(); + } +} + +void ViewModelInstanceViewModel::applyValue(DataValueViewModel* dataValue) +{ + updateViewModel(dataValue->value()); +} + +Core* ViewModelInstanceViewModel::clone() const +{ + ViewModelInstanceViewModel* cloned = ViewModelInstanceViewModelBase::clone() + ->as(); + if (m_referenceViewModelInstance) + { + auto clonedInstance = m_referenceViewModelInstance->clone(); + cloned->referenceViewModelInstance( + rcp(clonedInstance->as())); + cloned->viewModelInstance(m_viewModelInstance); + } + return cloned; } \ No newline at end of file diff --git a/thirdparty/rive/source/virtualizing_component.cpp b/thirdparty/rive/source/virtualizing_component.cpp new file mode 100644 index 000000000..e1d74f5da --- /dev/null +++ b/thirdparty/rive/source/virtualizing_component.cpp @@ -0,0 +1,16 @@ +#include "rive/artboard.hpp" +#include "rive/artboard_component_list.hpp" +#include "rive/component.hpp" +#include "rive/virtualizing_component.hpp" + +using namespace rive; + +VirtualizingComponent* VirtualizingComponent::from(Component* component) +{ + switch (component->coreType()) + { + case ArtboardComponentList::typeKey: + return component->as(); + } + return nullptr; +} \ No newline at end of file diff --git a/thirdparty/rive_decoders/include/rive/decoders/bitmap_decoder.hpp b/thirdparty/rive_decoders/include/rive/decoders/bitmap_decoder.hpp index 3feb42e69..785fe92b8 100644 --- a/thirdparty/rive_decoders/include/rive/decoders/bitmap_decoder.hpp +++ b/thirdparty/rive_decoders/include/rive/decoders/bitmap_decoder.hpp @@ -5,6 +5,7 @@ #ifndef _RIVE_BITMAP_DECODER_HPP_ #define _RIVE_BITMAP_DECODER_HPP_ +#include #include #include @@ -23,23 +24,21 @@ class Bitmap Bitmap(uint32_t width, uint32_t height, + size_t numBytes, PixelFormat pixelFormat, std::unique_ptr bytes); - Bitmap(uint32_t width, - uint32_t height, - PixelFormat pixelFormat, - const uint8_t* bytes); - private: uint32_t m_Width; uint32_t m_Height; + size_t m_NumBytes; PixelFormat m_PixelFormat; std::unique_ptr m_Bytes; public: uint32_t width() const { return m_Width; } uint32_t height() const { return m_Height; } + size_t numBytes() const { return m_NumBytes; } PixelFormat pixelFormat() const { return m_PixelFormat; } const uint8_t* bytes() const { return m_Bytes.get(); } std::unique_ptr detachBytes() diff --git a/thirdparty/rive_decoders/rive_decoders.cpp b/thirdparty/rive_decoders/rive_decoders.cpp index 06650540d..456d38268 100644 --- a/thirdparty/rive_decoders/rive_decoders.cpp +++ b/thirdparty/rive_decoders/rive_decoders.cpp @@ -21,8 +21,11 @@ #include "rive_decoders.h" +// BEGIN YUP GENERATED RIVE DECODER INCLUDES #include "source/bitmap_decoder.cpp" #include "source/bitmap_decoder_thirdparty.cpp" +// END YUP GENERATED RIVE DECODER INCLUDES + #if RIVE_JPEG #include "source/decode_jpeg.cpp" diff --git a/thirdparty/rive_decoders/rive_decoders.h b/thirdparty/rive_decoders/rive_decoders.h index d246ff573..e65dabfe2 100644 --- a/thirdparty/rive_decoders/rive_decoders.h +++ b/thirdparty/rive_decoders/rive_decoders.h @@ -26,7 +26,7 @@ ID: rive_decoders vendor: rive - version: 1.0 + version: 0.1.62 name: Rive Decoders. description: The Rive Decoders is a companion library for raster image decoding backends (libpng, libwebp, libjpeg). website: https://github.com/rive-app/rive-runtime diff --git a/thirdparty/rive_decoders/source/bitmap_decoder.cpp b/thirdparty/rive_decoders/source/bitmap_decoder.cpp index 979b2e510..268d7a629 100644 --- a/thirdparty/rive_decoders/source/bitmap_decoder.cpp +++ b/thirdparty/rive_decoders/source/bitmap_decoder.cpp @@ -12,21 +12,16 @@ namespace rive { Bitmap::Bitmap(uint32_t width, uint32_t height, + size_t numBytes, PixelFormat pixelFormat, std::unique_ptr bytes) : m_Width(width), m_Height(height), + m_NumBytes(numBytes), m_PixelFormat(pixelFormat), m_Bytes(std::move(bytes)) {} -Bitmap::Bitmap(uint32_t width, - uint32_t height, - PixelFormat pixelFormat, - const uint8_t* bytes) : - Bitmap(width, height, pixelFormat, std::unique_ptr(bytes)) -{} - static size_t bytes_per_pixel(Bitmap::PixelFormat format) { switch (format) @@ -103,6 +98,7 @@ void Bitmap::pixelFormat(PixelFormat format) m_Bytes = std::move(toBytes); m_PixelFormat = format; + m_NumBytes = toSizeInBytes; } } // namespace rive diff --git a/thirdparty/rive_decoders/source/bitmap_decoder_thirdparty.cpp b/thirdparty/rive_decoders/source/bitmap_decoder_thirdparty.cpp index 2d9b85c59..644e6fe45 100644 --- a/thirdparty/rive_decoders/source/bitmap_decoder_thirdparty.cpp +++ b/thirdparty/rive_decoders/source/bitmap_decoder_thirdparty.cpp @@ -13,7 +13,7 @@ #include #if TARGET_OS_IPHONE -#import +#include #include #elif TARGET_OS_MAC #include @@ -204,6 +204,7 @@ std::unique_ptr Bitmap::decode(const uint8_t bytes[], size_t byteCount) return std::make_unique(image.width, image.height, + image.width * image.height * 4, // CG always premultiplies alpha. PixelFormat::RGBAPremul, std::move(image.pixels)); diff --git a/thirdparty/rive_decoders/source/decode_jpeg.cpp b/thirdparty/rive_decoders/source/decode_jpeg.cpp index 06336523f..2e3d19514 100644 --- a/thirdparty/rive_decoders/source/decode_jpeg.cpp +++ b/thirdparty/rive_decoders/source/decode_jpeg.cpp @@ -10,8 +10,6 @@ #include #include -namespace rive { - struct my_error_mgr { struct jpeg_error_mgr pub; @@ -126,10 +124,19 @@ std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount) // Step 8: Release JPEG decompression object jpeg_destroy_decompress(&cinfo); + // This assert can fire for corrupted/truncated JPEGs on some platforms. + // Don't abort; treat mismatch as decode failure. + const size_t expectedSize = static_cast(cinfo.output_width) * + static_cast(cinfo.output_height) * 3; + + if (pixelBufferSize != expectedSize) + { + return nullptr; + } + return std::make_unique(cinfo.output_width, cinfo.output_height, + pixelBufferSize, Bitmap::PixelFormat::RGB, std::move(pixelBuffer)); -} - -} // namespace rive +} \ No newline at end of file diff --git a/thirdparty/rive_decoders/source/decode_png.cpp b/thirdparty/rive_decoders/source/decode_png.cpp index a76484611..ea1f941f2 100644 --- a/thirdparty/rive_decoders/source/decode_png.cpp +++ b/thirdparty/rive_decoders/source/decode_png.cpp @@ -3,9 +3,7 @@ */ #include "rive/decoders/bitmap_decoder.hpp" - -#include - +#include "png.h" #include #include #include @@ -157,8 +155,11 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) pixelFormat = Bitmap::PixelFormat::RGB; break; } + + assert(pixelBufferSize == height * width * channels); return std::make_unique(width, height, + pixelBufferSize, pixelFormat, std::move(pixelBuffer)); } diff --git a/thirdparty/rive_decoders/source/decode_webp.cpp b/thirdparty/rive_decoders/source/decode_webp.cpp index ffd484c0e..2a5c35798 100644 --- a/thirdparty/rive_decoders/source/decode_webp.cpp +++ b/thirdparty/rive_decoders/source/decode_webp.cpp @@ -1,10 +1,10 @@ #include "rive/decoders/bitmap_decoder.hpp" - -#include - +#include "webp/decode.h" +#include "webp/demux.h" #include #include #include +#include namespace rive { @@ -68,8 +68,10 @@ std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount) WebPDemuxReleaseIterator(¤tFrame); WebPDemuxDelete(demuxer); + assert(pixelBufferSize == height * width * 4); return std::make_unique(width, height, + pixelBufferSize, Bitmap::PixelFormat::RGBA, std::move(pixelBuffer)); } diff --git a/thirdparty/rive_renderer/include/rive/renderer/async_pipeline_manager.hpp b/thirdparty/rive_renderer/include/rive/renderer/async_pipeline_manager.hpp new file mode 100644 index 000000000..05b722a17 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/async_pipeline_manager.hpp @@ -0,0 +1,686 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/gpu.hpp" +#include "rive/renderer/render_context.hpp" + +#include +#include +#include +#include +#include + +namespace rive::gpu +{ + +enum class PipelineCreateType +{ + sync, + async, +}; + +enum class PipelineStatus +{ + notReady, + ready, + errored, +}; + +struct StandardPipelineProps +{ + DrawType drawType; + ShaderFeatures shaderFeatures; + InterlockMode interlockMode; + ShaderMiscFlags shaderMiscFlags; +#ifdef WITH_RIVE_TOOLS + SynthesizedFailureType synthesizedFailureType = + SynthesizedFailureType::none; +#endif + + uint32_t createKey(const PlatformFeatures&) const + { + return gpu::ShaderUniqueKey(drawType, + shaderFeatures, + interlockMode, + shaderMiscFlags); + } +}; + +// Helper class to manage asynchronous creation of a pipeline (i.e. a +// combination of a vertex/pixel shader) +template class AsyncPipelineManager +{ +public: + using PipelineProps = typename PipelineType::PipelineProps; + using VertexShaderType = typename PipelineType::VertexShaderType; + using FragmentShaderType = typename PipelineType::FragmentShaderType; + + // The pipeline key might be 32- or 64-bit depending on renderer, so detect + // which it is. + using PipelineKey = decltype(std::declval().createKey( + std::declval())); + + AsyncPipelineManager(ShaderCompilationMode mode) : m_mode(mode) {} + + AsyncPipelineManager(const AsyncPipelineManager&) = delete; + AsyncPipelineManager& operator=(const AsyncPipelineManager&) = delete; + virtual ~AsyncPipelineManager() + { + // If we created a background thread, it's important for the derived + // class to have already called shutdownBackgroundThread before + // destructing its own internal state (otherwise the thread might be + // mid-shader-creation when it unloads its context). + assert(!m_jobThread.joinable()); + } + + const PipelineType* tryGetPipeline(const PipelineProps& propsIn, + const PlatformFeatures& platformFeatures) + { + PipelineProps props = propsIn; + + ShaderFeatures ubershaderFeatures = + gpu::UbershaderFeaturesMaskFor(props.shaderFeatures, + props.drawType, + props.interlockMode, + props.shaderMiscFlags, + platformFeatures); + + PipelineCreateType createType; + + switch (m_mode) + { + case ShaderCompilationMode::allowAsynchronous: + default: + // If this is an ubershader equivalent, we want to create this + // draw program synchronously so that it is available + // immediately + createType = (props.shaderFeatures == ubershaderFeatures) + ? PipelineCreateType::sync + : PipelineCreateType::async; + break; + + case ShaderCompilationMode::onlyUbershaders: + // For ubershader-only loading, we'll always use the full + // ubershader + // feature flags and always load synchronously. + props.shaderFeatures = ubershaderFeatures; + [[fallthrough]]; + + case ShaderCompilationMode::alwaysSynchronous: + createType = PipelineCreateType::sync; + break; + } + + PipelineKey key = props.createKey(platformFeatures); + + auto iter = m_pipelines.find(key); + +#ifdef WITH_RIVE_TOOLS + // If requested, synthesize a complete failure to get an ubershader + // (i.e. pretend we attempted to load the current shader asynchronously + // and tried to fall back on an uber, which failed) (Don't fail on + // "renderPassResolve" in atomic mode because if we fail that one the + // unit test won't see the clear color.) + if (props.synthesizedFailureType == + gpu::SynthesizedFailureType::ubershaderLoad && + props.drawType != DrawType::renderPassResolve) + { + return nullptr; + } + + if (props.shaderFeatures == ubershaderFeatures) + { + // Otherwise, do not synthesize compilation failure for an + // ubershader. + props.synthesizedFailureType = gpu::SynthesizedFailureType::none; + + if (iter == m_pipelines.end()) + { + // If we're going to try to create this ubershader, test to see + // if it's even a valid combination of properties + assert(isValidUbershaderPipelineProps(props, platformFeatures)); + } + } +#endif + + if (iter == m_pipelines.end()) + { + // We haven't encountered this shader key yet so it's time to ask + // the render context to create the program. If it's happening + // asynchronously, it might return us an incomplete pipeline + // (for, say, WebGL where there is background shader compilation), + // or it might return a nullptr/nullopt value (which means it + // queued the work into our jobQueue and we'll get it later) + auto pipeline = + createPipeline(createType, key, props, platformFeatures); + + iter = m_pipelines.insert({key, std::move(pipeline)}).first; + + if (createType == PipelineCreateType::sync) + { + // If we asked to create a synchronous one, return it + // imemdiately (regardless of whether background compilation + // has finished or not - the render context is in charge of + // stalling on an incomplete shader when it gets one) + assert(iter->second); + + if (getPipelineStatus(*iter->second) != PipelineStatus::errored) + { + return &*iter->second; + } + + if (props.shaderFeatures == ubershaderFeatures) + { + // Ubershader creation failed +#ifdef WITH_RIVE_TOOLS + assert(props.synthesizedFailureType != + SynthesizedFailureType::none); +#else + assert(false && "Ubershader creation failed"); +#endif + return nullptr; + } + + // This pipeline failed to build for some reason, but we can + // (potentially) fall back on the ubershader. + assert(props.shaderFeatures != ubershaderFeatures); + } + } + + if (!iter->second) + { + // We don't have this shader yet, so run through the list of + // completed shaders and see if it's done yet. + if (processCompletedJobs(key)) + { + assert(iter->second); + } + else if (props.shaderFeatures == ubershaderFeatures) + { + // This ubershader must have been queued by the user so we need + // to block until it's ready (or failed), since we can't render + // without it (this wait will attempt to move it to the front of + // the line so we don't have to wait on every shader that may + // have been queued before it) + waitForPipelineForRender(key); + assert(iter->second); + } + } + + if (iter->second) + { + if (auto status = getPipelineStatus(*iter->second); + status == PipelineStatus::ready) + { + // The program is present and ready to go! + return &*iter->second; + } + else if (status != PipelineStatus::errored) + { + assert(status == PipelineStatus::notReady); + + // The program was not ready yet so attempt to move its creation + // process forward. + if (advanceCreation(*iter->second, props)) + { + // The program was not previously ready, but it is now. + return &*iter->second; + } + } + } + + if (props.shaderFeatures == ubershaderFeatures) + { + // The only way to get here for an ubershader should be for it to + // have failed to compile. + assert(iter->second && + getPipelineStatus(*iter->second) == PipelineStatus::errored); + return nullptr; + } + + // The pipeline is still not ready, so instead return an ubershader + // version (with all functionality enabled). This will create + // synchronously so we're guaranteed to have a valid return from this + // call. + assert(props.shaderFeatures != ubershaderFeatures); + auto ubershaderProps = props; + ubershaderProps.shaderFeatures = ubershaderFeatures; + return tryGetPipeline(ubershaderProps, platformFeatures); + } + + const VertexShaderType& getVertexShaderSynchronous( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode) + { + // Remove any non-vertex-shader features before doing the key + shaderFeatures &= kVertexShaderFeaturesMask; + + return getSharedObjectSynchronous( + gpu::ShaderUniqueKey(drawType, + shaderFeatures, + interlockMode, + ShaderMiscFlags::none), + m_vertexShaderMap, + [&]() { + return createVertexShader(drawType, + shaderFeatures, + interlockMode); + }); + } + + const FragmentShaderType& getFragmentShaderSynchronous( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags miscFlags) + { + return getSharedObjectSynchronous(gpu::ShaderUniqueKey(drawType, + shaderFeatures, + interlockMode, + miscFlags), + m_fragmentShaderMap, + [&]() { + return createFragmentShader( + drawType, + shaderFeatures, + interlockMode, + miscFlags); + }); + } + + void clearCache() + { + std::unique_lock lock{m_mutex}; + + // Start by clearing the job queue. + m_jobQueue.clear(); + + // Now wait for the background thread(s) to finish any work they are + // actively doing. + while (m_activePipelineCreationCount > 0) + { + m_jobCompleteCV.wait(lock); + } + + // Clear all of the rest of our cached everything - we'll start over. + m_completedJobs.clear(); + m_vertexShaderMap.clear(); + m_fragmentShaderMap.clear(); + m_pipelines.clear(); + clearCacheInternal(); + } + + void waitForAllBackgroundPipelineCreation() + { + { + std::unique_lock lock{m_mutex}; + while (m_currentThreadPipelineKey.has_value() || + !m_jobQueue.empty()) + { + m_jobCompleteCV.wait(lock); + } + } + + // Since all the jobs are done, go ahead and get them all into the + // pipeline list. + processCompletedJobs(); + } + +protected: + bool queuePipelineIfNotFound(const PipelineProps& props, + const PlatformFeatures& platformFeatures) + { + PipelineKey key = props.createKey(platformFeatures); + auto iter = m_pipelines.find(key); + if (iter != m_pipelines.end()) + { + // This is already in our pipelines list which means it was already + // created. + return false; + } + + auto pipeline = createPipeline(PipelineCreateType::async, + key, + props, + platformFeatures); + m_pipelines.insert({key, std::move(pipeline)}); + return true; + } + + void waitForPipelineForRender(PipelineKey key) + { + auto iter = m_pipelines.find(key); + assert(iter != m_pipelines.end() && + "waiting on pipeline that hasn't been queued or created"); + + if (iter->second) + { + // It's already completed, we don't have to do anything. + return; + } + + // Do a quick first-effort processing of any completed jobs to see + // if it's already done before manipulating the job queue. + if (processCompletedJobs(key)) + { + assert(iter->second); + return; + } + + { + // We want this pipeline now, so move it to the front of the + // queue if it's still in it (if it's *not* in the queue then it + // either finished after the above processing or it's already + // being processed by the thread) + std::lock_guard lock{m_mutex}; + auto queueIter = + std::find_if(m_jobQueue.begin(), + m_jobQueue.end(), + [key](auto& e) { return e.key == key; }); + + if (queueIter != m_jobQueue.end()) + { + auto params = std::move(*queueIter); + m_jobQueue.erase(queueIter); + m_jobQueue.push_front(std::move(params)); + } + } + + while (true) + { + { + std::unique_lock lock{m_mutex}; + if (m_completedJobs.empty()) + { + // Nothing to process yet so wait until we have + // something. + m_jobCompleteCV.wait(lock); + } + } + + // We now have at least one thing in the completed jobs list, so + // process anything that's there (at least until we reach the job we + // care about) + if (processCompletedJobs(key)) + { + assert(iter->second); + return; + } + } + } + + virtual std::unique_ptr createVertexShader( + DrawType, + ShaderFeatures, + InterlockMode) = 0; + + virtual std::unique_ptr createFragmentShader( + DrawType, + ShaderFeatures, + InterlockMode, + ShaderMiscFlags) = 0; + + // This function is called to create a pipeline when we don't have one + // with its key already. It can be called in either "sync" or "async" mode. + // - In async mode, the function should either: + // - call queueBackgroundJob with the supplied parameters so that it will + // be processed by the background thread (like D3D does) + // - create the shader using the target API's built-in async/parallel + // thread creation model (like GL does) + // - In sync mode, the shader should be created immediately. This mode is + // used either when compiling the fallback "ubershader" version of a + // drawType (as it is required immediately), or when the background job + // thread wants to create a shader (so the implementation of sync mode + // needs to be thread-safe when using the target API in that case) + virtual std::unique_ptr createPipeline( + PipelineCreateType, + PipelineKey key, + const PipelineProps&, + const PlatformFeatures&) = 0; + + // For renderers like GL that have a polling/step-based async setup, + // override this function to return whether or not the pipeline is + // fully ready or still loading. + virtual PipelineStatus getPipelineStatus(const PipelineType&) const = 0; + + // For renderers like GL that have a step-based async setup, + // override this function to attempt to move the shader along its progress. + virtual bool advanceCreation(PipelineType&, const PipelineProps&) + { + return false; // do nothing by default + } + + // If renderers have extra state, this is where they can clear it while + // within the safety of the mutex lock + virtual void clearCacheInternal() {} + +#if !defined(NDEBUG) + virtual bool isValidUbershaderPipelineProps( + const PipelineProps& props, + const PlatformFeatures& platformFeatures) + { + bool found = true; + auto curKey = ShaderUniqueKey(props.drawType, + props.shaderFeatures, + props.interlockMode, + props.shaderMiscFlags); + + ForEachUbershaderPermutation( + props.interlockMode, + platformFeatures, + [&found, curKey, &props](DrawType drawType, + ShaderFeatures shaderFeatures, + ShaderMiscFlags shaderMiscFlags) { + auto testKey = ShaderUniqueKey(drawType, + shaderFeatures, + props.interlockMode, + shaderMiscFlags); + if (testKey == curKey) + { + found = true; + } + return !found; // Keep going if we didn't find a match. + }); + + return found; + } +#endif + + // Called by the render context to use the background threading model to + // create pipeline + void queueBackgroundJob(PipelineKey key, + const PipelineProps& props, + const PlatformFeatures& platformFeatures) + { + // start the job thread if we haven't already + if (!m_jobThread.joinable()) + { + m_jobThread = + std::thread{[this] { backgroundShaderCompilationThread(); }}; + } + + std::unique_lock lock{m_mutex}; + + m_jobQueue.push_back({props, key, &platformFeatures}); + m_newJobCV.notify_one(); + } + + void shutdownBackgroundThread() + { + if (m_jobThread.joinable()) + { + { + std::unique_lock lock{m_mutex}; + m_isDone = true; + } + + m_newJobCV.notify_all(); + m_jobThread.join(); + } + } + + template + SharedObject& getSharedObjectSynchronous( + KeyType key, + std::unordered_map>& map, + CreateFunc&& createFunc) + { + // See if the object exists already first + { + std::unique_lock lock{m_mutex}; + + auto iter = map.find(key); + if (iter != map.end()) + { + while (iter->second == nullptr) + { + // This is either a synchronous object request and an + // asynchronous build is running it *or* it's on an async + // thread and another thread is running it - either way we + // need to wait for the thread making this object to finish + // (so we only build it once) + m_sharedObjectReadyCV.wait(lock); + } + + return *iter->second; + } + + // Insert an empty entry into the object map so the other threads + // don't try to double-up on creation of this object + map.try_emplace(key); + } + + // Now that we're outside of the lock, ask the renderer context to + // create the object + auto object = createFunc(); + + { + std::unique_lock lock{m_mutex}; + + auto iter = map.find(key); + assert(iter != map.end()); + assert(iter->second == nullptr); + iter->second = std::move(object); + m_sharedObjectReadyCV.notify_all(); + return *iter->second; + } + } + +private: + struct JobParams + { + PipelineProps props; + PipelineKey key; + const PlatformFeatures* platformFeatures; + }; + + struct CompletedJob + { + PipelineKey key; + std::unique_ptr program; + }; + + bool processCompletedJobs( + std::optional targetKey = std::nullopt) + { + while (true) + { + CompletedJob completedJob; + { + std::lock_guard lock{m_mutex}; + if (m_completedJobs.empty()) + { + // Nothing in the queue so if there was a key to + // specifically stop on, we didn't reach it (if there wasn't + // one, we still return success since we processed every + // available completed job). + return !targetKey.has_value(); + } + + completedJob = std::move(m_completedJobs.back()); + m_completedJobs.pop_back(); + } + + // Threaded pipelines are expected to be ready (or errored) when + // they are in the completed stack. + assert(getPipelineStatus(*completedJob.program) != + PipelineStatus::notReady); + + m_pipelines[completedJob.key] = std::move(completedJob.program); + if (targetKey.has_value() && completedJob.key == *targetKey) + { + return true; + } + } + + return !targetKey.has_value(); + } + + void backgroundShaderCompilationThread() + { + while (true) + { + JobParams nextJob; + { + std::unique_lock lock{m_mutex}; + + while (!m_isDone && m_jobQueue.empty()) + { + m_newJobCV.wait(lock); + } + + if (m_isDone) + { + return; + } + + nextJob = std::move(m_jobQueue.front()); + m_jobQueue.pop_front(); + m_currentThreadPipelineKey = nextJob.key; + m_activePipelineCreationCount++; + } + + auto newPipeline = createPipeline(PipelineCreateType::sync, + nextJob.key, + nextJob.props, + *nextJob.platformFeatures); + + { + std::unique_lock lock{m_mutex}; + m_completedJobs.push_back({ + nextJob.key, + std::move(newPipeline), + }); + + m_currentThreadPipelineKey.reset(); + m_activePipelineCreationCount--; + m_jobCompleteCV.notify_all(); + } + } + } + + std::unordered_map> + m_vertexShaderMap; + std::unordered_map> + m_fragmentShaderMap; + std::unordered_map> m_pipelines; + + std::deque m_jobQueue; + std::vector m_completedJobs; + + bool m_isDone = false; + uint32_t m_activePipelineCreationCount = 0; + const ShaderCompilationMode m_mode = ShaderCompilationMode::standard; + std::thread m_jobThread; + std::optional m_currentThreadPipelineKey; + std::mutex m_mutex; + std::condition_variable m_newJobCV; + std::condition_variable m_jobCompleteCV; + std::condition_variable m_sharedObjectReadyCV; +}; + +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d.hpp index 56587c36d..5fb27e3ab 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d.hpp @@ -8,6 +8,8 @@ #include #include +#include "rive/renderer/render_context.hpp" + using Microsoft::WRL::ComPtr; #define VERIFY_OK(CODE) \ @@ -20,6 +22,7 @@ using Microsoft::WRL::ComPtr; static_cast(__LINE__), \ std::system_category().message(hr).c_str(), \ #CODE); \ + fflush(stderr); \ abort(); \ } \ } @@ -38,8 +41,11 @@ struct D3DCapabilities struct D3DContextOptions { + ShaderCompilationMode shaderCompilationMode = + ShaderCompilationMode::standard; bool disableRasterizerOrderedViews = false; // Primarily for testing. bool disableTypedUAVLoadStore = false; // Primarily for testing. bool isIntel = false; + bool isIntelArc = false; }; } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d_utils.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d_utils.hpp new file mode 100644 index 000000000..efd878280 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d/d3d_utils.hpp @@ -0,0 +1,18 @@ +/* + * Copyright 2025 Rive + */ +#include +#include "rive/renderer/render_context.hpp" +#include "rive/texture_archive.hpp" +#include + +namespace rive::gpu +{ +namespace d3d_utils +{ +bool GetWStringFromString(const char*, std::wstring& outString); + +DXGI_FORMAT convert_format(GPUTextureFormat format); + +}; // namespace d3d_utils +}; // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d/pipeline_manager.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d/pipeline_manager.hpp index 4c741a7f2..c6ac0ec8d 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/d3d/pipeline_manager.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d/pipeline_manager.hpp @@ -3,6 +3,7 @@ */ #pragma once +#include "rive/renderer/async_pipeline_manager.hpp" #include "rive/renderer/d3d/d3d.hpp" #include "rive/renderer/gpu.hpp" @@ -13,195 +14,121 @@ namespace rive::gpu { namespace d3d_utils { -// generates a shader using ostringstream -std::string build_shader(DrawType drawType, - ShaderFeatures shaderFeatures, - InterlockMode interlockMode, - ShaderMiscFlags shaderMiscFlags, - const D3DCapabilities& d3dCapabilities); -// compile shader to source using "main" as an entry point -ComPtr compile_vertex_source_to_blob(const std::string& source, - const char* target); -// compile shader to source using "main" as an entry point -ComPtr compile_pixel_source_to_blob(const std::string& source, - const char* target); +ComPtr compile_shader_to_blob(DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + const D3DCapabilities& d3dCapabilities, + const char* target); } // namespace d3d_utils // Handles managing and compiling shaders. // Has hooks to allow managing pipelines for d3d12 -// Will also manages threading for just in time compiling of shaders once -// thats in -template -class D3DPipelineManager +template +class D3DPipelineManager : public AsyncPipelineManager { + using Super = AsyncPipelineManager; + public: - // everything needed to compile a vertex + pixel shader combo - struct ShaderCompileRequest - { - DrawType drawType; - ShaderFeatures shaderFeatures; - InterlockMode interlockMode; - ShaderMiscFlags shaderMiscFlags; - const D3DCapabilities& d3dCapabilities; - }; - - // shader compiler result including keys for m_drawVertexShaders and - // m_drawPixelShaders - struct ShaderCompileResult - { - uint32_t vertexShaderKey; - uint32_t pixelShaderKey; - struct VertexResult - { - bool hasResult = false; - VetexShaderType vertexShaderResult; - } vertexResult; - struct PixelResult - { - bool hasResult = false; - PixelShaderType pixelShaderResult; - } pixelResult; - // needed for d3d12 - void* resultData = nullptr; - }; + using VertexShaderType = typename PipelineType::VertexShaderType; + using FragmentShaderType = typename PipelineType::FragmentShaderType; + + const D3DCapabilities d3dCapabilities() const { return m_d3dCapabilities; } + DeviceType* device() const { return m_device.Get(); } D3DPipelineManager(ComPtr device, const D3DCapabilities& capabilities, + ShaderCompilationMode shaderCompilationMode, const char* vertexTarget, const char* pixelTarget) : - m_device(std::move(device)), + Super(shaderCompilationMode), + m_device(device), m_d3dCapabilities(capabilities), m_vertexTarget(vertexTarget), m_pixelTarget(pixelTarget) {} - - const D3DCapabilities d3dCapabilities() const { return m_d3dCapabilities; } - - DeviceType* device() const { return m_device.Get(); } + virtual ~D3DPipelineManager() = default; protected: - // called when shaderCompileWorker finished compiling the source shader to - // blobs and now we need to convert that to the platform specific shader - // tpes i.e. ID3D11Vertex/PixelShader for 11 and ID3D12PilineState for 12. - // note: this could be called on a background thread - virtual void compileBlobToFinalType(const ShaderCompileRequest&, - ComPtr vertexShader, - ComPtr pixelShader, - ShaderCompileResult*) = 0; - - // get shaders with given compiler request. returns true and sets - // outShaderResult on succes, returns false and outShaderResult is undefined - // on failure - bool getShader(const ShaderCompileRequest& shaderCompileRequest, - ShaderCompileResult* outShaderResult) - { - // dont pass nullptr here - assert(outShaderResult); + using PipelineProps = typename Super::PipelineProps; - outShaderResult->vertexShaderKey = gpu::ShaderUniqueKey( - shaderCompileRequest.drawType, - shaderCompileRequest.shaderFeatures & kVertexShaderFeaturesMask, - shaderCompileRequest.interlockMode, - gpu::ShaderMiscFlags::none); + virtual std::unique_ptr + compilePixelShaderBlobToFinalType(ComPtr blob) = 0; - outShaderResult->pixelShaderKey = - ShaderUniqueKey(shaderCompileRequest.drawType, - shaderCompileRequest.shaderFeatures, - shaderCompileRequest.interlockMode, - shaderCompileRequest.shaderMiscFlags); + virtual std::unique_ptr + compileVertexShaderBlobToFinalType(DrawType drawType, + ComPtr blob) = 0; - auto vertexEntry = - m_drawVertexShaders.find(outShaderResult->vertexShaderKey); - - auto pixelEntry = - m_drawPixelShaders.find(outShaderResult->pixelShaderKey); - - if (vertexEntry != m_drawVertexShaders.end()) - { - outShaderResult->vertexResult.hasResult = true; - outShaderResult->vertexResult.vertexShaderResult = - vertexEntry->second; - } + virtual std::unique_ptr linkPipeline( + const PipelineProps& props, + const VertexShaderType& vs, + const FragmentShaderType& ps) = 0; - if (pixelEntry != m_drawPixelShaders.end()) - { - outShaderResult->pixelResult.hasResult = true; - outShaderResult->pixelResult.pixelShaderResult = pixelEntry->second; - } - - if (vertexEntry == m_drawVertexShaders.end() || - pixelEntry == m_drawPixelShaders.end()) - { - if (!shaderCompileWorker(shaderCompileRequest, outShaderResult)) - { - // eventually this means background shader compile happening, so - // we would set uber shader here and return - RIVE_UNREACHABLE(); - } - if (vertexEntry == m_drawVertexShaders.end()) - { - assert(outShaderResult->vertexResult.hasResult); - m_drawVertexShaders.insert( - {outShaderResult->vertexShaderKey, - outShaderResult->vertexResult.vertexShaderResult}); - } - - if (pixelEntry == m_drawPixelShaders.end()) - { - assert(outShaderResult->pixelResult.hasResult); - m_drawPixelShaders.insert( - {outShaderResult->pixelShaderKey, - outShaderResult->pixelResult.pixelShaderResult}); - } - } - - return true; + virtual PipelineStatus getPipelineStatus( + const PipelineType& pipeline) const override final + { + // D3D pipelines never exist in the waiting state, they spring to + // life completed (or errored) + return pipeline.succeeded() ? PipelineStatus::ready + : PipelineStatus::errored; } private: - // build shader (currnetly runs synchronously but will be async eventually) - bool shaderCompileWorker(const ShaderCompileRequest& compileRequest, - ShaderCompileResult* outShaderResult) + virtual std::unique_ptr createVertexShader( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode) override { - assert(outShaderResult->vertexResult.hasResult == false || - outShaderResult->pixelResult.hasResult == false); - - auto shader = d3d_utils::build_shader(compileRequest.drawType, - compileRequest.shaderFeatures, - compileRequest.interlockMode, - compileRequest.shaderMiscFlags, - compileRequest.d3dCapabilities); + auto blob = d3d_utils::compile_shader_to_blob(drawType, + shaderFeatures, + interlockMode, + ShaderMiscFlags::none, + m_d3dCapabilities, + m_vertexTarget); + + return compileVertexShaderBlobToFinalType(drawType, blob.Get()); + } - ComPtr vertexShader; - ComPtr pixelShader; + virtual std::unique_ptr createFragmentShader( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags miscFlags) override + { + auto blob = d3d_utils::compile_shader_to_blob(drawType, + shaderFeatures, + interlockMode, + miscFlags, + m_d3dCapabilities, + m_pixelTarget); + + return compilePixelShaderBlobToFinalType(blob.Get()); + } - if (!outShaderResult->vertexResult.hasResult) + virtual std::unique_ptr createPipeline( + PipelineCreateType createType, + uint32_t key, + const PipelineProps& props, + const PlatformFeatures& platformFeatures) override final + { + if (createType == PipelineCreateType::async) { - vertexShader = - d3d_utils::compile_vertex_source_to_blob(shader, - m_vertexTarget); + this->queueBackgroundJob(key, props, platformFeatures); + return nullptr; } - if (!outShaderResult->pixelResult.hasResult) - { - pixelShader = - d3d_utils::compile_pixel_source_to_blob(shader, m_pixelTarget); - } + auto& vs = this->getVertexShaderSynchronous(props.drawType, + props.shaderFeatures, + props.interlockMode); - compileBlobToFinalType(compileRequest, - vertexShader, - pixelShader, - outShaderResult); + auto& ps = this->getFragmentShaderSynchronous(props.drawType, + props.shaderFeatures, + props.interlockMode, + props.shaderMiscFlags); - return true; + return linkPipeline(props, vs, ps); } -private: - std::unordered_map m_drawVertexShaders; - std::unordered_map m_drawPixelShaders; - ComPtr m_device; const D3DCapabilities m_d3dCapabilities; @@ -209,4 +136,4 @@ class D3DPipelineManager const char* m_pixelTarget; }; -}; // namespace rive::gpu +}; // namespace rive::gpu \ No newline at end of file diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d11/render_context_d3d_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d11/render_context_d3d_impl.hpp index 892ee48be..34adb009e 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/d3d11/render_context_d3d_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d11/render_context_d3d_impl.hpp @@ -65,20 +65,50 @@ struct D3D11DrawVertexShader ComPtr shader; }; +struct D3D11DrawPixelShader +{ + ComPtr shader; +}; + +struct D3D11DrawPipeline +{ + using VertexShaderType = D3D11DrawVertexShader; + using FragmentShaderType = D3D11DrawPixelShader; + using PipelineProps = gpu::StandardPipelineProps; + + VertexShaderType m_vertexShader; + FragmentShaderType m_pixelShader; + + bool succeeded() const + { + return m_vertexShader.shader != nullptr && + m_pixelShader.shader != nullptr; + } +}; + class D3D11PipelineManager - : public D3DPipelineManager, - ID3D11Device> + : public D3DPipelineManager { -public: - D3D11PipelineManager(ComPtr context, - ComPtr device, - const D3DCapabilities& capabilities); + using Super = D3DPipelineManager; - void setPipelineState(rive::gpu::DrawType, - rive::gpu::ShaderFeatures, - rive::gpu::InterlockMode, - rive::gpu::ShaderMiscFlags); +public: + D3D11PipelineManager(ComPtr, + ComPtr, + const D3DCapabilities&, + ShaderCompilationMode); + + ~D3D11PipelineManager() { shutdownBackgroundThread(); } + + [[nodiscard]] bool setPipelineState(DrawType, + ShaderFeatures, + InterlockMode, + ShaderMiscFlags, + const PlatformFeatures& +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType +#endif + ); void setColorRampState() const { @@ -111,10 +141,16 @@ class D3D11PipelineManager } protected: - virtual void compileBlobToFinalType(const ShaderCompileRequest&, - ComPtr vertexShader, - ComPtr pixelShader, - ShaderCompileResult*) override; + virtual std::unique_ptr + compilePixelShaderBlobToFinalType(ComPtr) override; + + virtual std::unique_ptr + compileVertexShaderBlobToFinalType(DrawType, ComPtr) override; + + virtual std::unique_ptr linkPipeline( + const PipelineProps&, + const D3D11DrawVertexShader&, + const D3D11DrawPixelShader&) override; private: ComPtr m_context; @@ -147,6 +183,15 @@ class RenderContextD3DImpl : public RenderContextHelperImpl return make_rcp(this, width, height); } + rcp adoptImageTexture(ComPtr image, + uint32_t width, + uint32_t height); + +#ifdef RIVE_CANVAS + rcp makeRenderCanvas(uint32_t width, + uint32_t height) override; +#endif + const D3DCapabilities& d3dCapabilities() const { return m_d3dCapabilities; } ID3D11Device* gpu() const { return m_gpu.Get(); } ID3D11DeviceContext* gpuContext() const { return m_gpuContext.Get(); } @@ -167,7 +212,8 @@ class RenderContextD3DImpl : public RenderContextHelperImpl private: RenderContextD3DImpl(ComPtr, ComPtr, - const D3DCapabilities&); + const D3DCapabilities&, + const D3DContextOptions&); rcp makeRenderBuffer(RenderBufferType, RenderBufferFlags, @@ -176,6 +222,7 @@ class RenderContextD3DImpl : public RenderContextHelperImpl rcp makeImageTexture(uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat, const uint8_t imageDataRGBAPremul[]) override; std::unique_ptr makeUniformBufferRing( @@ -243,7 +290,8 @@ class RenderContextD3DImpl : public RenderContextHelperImpl ComPtr m_samplerStates[rive::ImageSampler::MAX_SAMPLER_PERMUTATIONS]; - ComPtr m_atlasRasterState; + ComPtr m_atlasFillRasterState; + ComPtr m_atlasStrokeRasterState; ComPtr m_backCulledRasterState[2]; ComPtr m_doubleSidedRasterState[2]; diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_pipeline_manager.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_pipeline_manager.hpp index d03c0e5c2..5de08bc45 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_pipeline_manager.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_pipeline_manager.hpp @@ -5,6 +5,9 @@ #include "rive/renderer/d3d12/d3d12.hpp" #include "rive/renderer/d3d/pipeline_manager.hpp" #include "rive/renderer/gpu.hpp" + +namespace rive::gpu +{ // holds all shader stuff including inputlayouts, source blobs and pipeline // states struct D3D12DrawVertexShader @@ -14,20 +17,33 @@ struct D3D12DrawVertexShader ComPtr m_shader; }; -namespace rive::gpu +struct D3D12DrawPixelShader +{ + ComPtr m_shader; +}; + +struct D3D12Pipeline { + using VertexShaderType = D3D12DrawVertexShader; + using FragmentShaderType = D3D12DrawPixelShader; + using PipelineProps = gpu::StandardPipelineProps; + + ComPtr m_d3dPipelineState; + + bool succeeded() const { return m_d3dPipelineState != nullptr; } +}; + class D3D12PipelineManager - : D3DPipelineManager, ID3D12Device> + : public D3DPipelineManager { + using Super = D3DPipelineManager; + public: - D3D12PipelineManager(ComPtr device, - const D3DCapabilities& capabilities); + D3D12PipelineManager(ComPtr, + const D3DCapabilities&, + ShaderCompilationMode); - ID3D12PipelineState* getDrawPipelineState( - DrawType drawType, - gpu::ShaderFeatures shaderFeatures, - gpu::InterlockMode interlockMode, - gpu::ShaderMiscFlags shaderMiscFlags); + ~D3D12PipelineManager() { shutdownBackgroundThread(); } void compileTesselationPipeline(); void compileGradientPipeline(); @@ -64,14 +80,18 @@ class D3D12PipelineManager } protected: - virtual void compileBlobToFinalType(const ShaderCompileRequest&, - ComPtr vertexShader, - ComPtr pixelShader, - ShaderCompileResult*) override; + virtual std::unique_ptr + compileVertexShaderBlobToFinalType(DrawType, ComPtr) override; -private: - std::unordered_map> m_drawPipelines; + virtual std::unique_ptr + compilePixelShaderBlobToFinalType(ComPtr blob) override; + virtual std::unique_ptr linkPipeline( + const PipelineProps&, + const D3D12DrawVertexShader&, + const D3D12DrawPixelShader&) override; + +private: // maybe these could be moved to D3DPipelineState but to do so // required a lot of extra complexity that didnt seem worth it ComPtr m_tesselationPipeline; diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_utils.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_utils.hpp index 87eaa12bb..e73302df6 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_utils.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d12/d3d12_utils.hpp @@ -65,6 +65,13 @@ class D3D12DescriptorHeap : public GPUResource UINT numElements, UINT elementByteStride, UINT64 firstElement); + void markSrvToIndex(ID3D12Device* device, + D3D12Buffer* resource, + UINT index, + UINT numElements, + UINT elementByteStride, + UINT gpuByteStride, + UINT64 firstElement); void markUavToIndex(ID3D12Device* device, D3D12Buffer* resource, DXGI_FORMAT format, @@ -77,6 +84,17 @@ class D3D12DescriptorHeap : public GPUResource void markSrvToIndex(ID3D12Device* device, D3D12TextureArray* resource, UINT index); + // Write a null-resource SRV descriptor at `index` so the slot is valid for + // SetGraphicsRootDescriptorTable even when the source resource isn't + // currently allocated. Without this, recycled cpu-heap slots can retain + // descriptors pointing at released resources and trip GPU-Based Validation + // (id=1042) when the SRV table is bound. + void markNullTexture2DSrvToIndex(ID3D12Device* device, + UINT index, + DXGI_FORMAT format); + void markNullStructuredBufferSrvToIndex(ID3D12Device* device, + UINT index, + UINT elementByteStride); void markUavToIndex(ID3D12Device* device, D3D12Texture* resource, DXGI_FORMAT format, @@ -127,6 +145,7 @@ class D3D12Resource : public GPUResource ID3D12Resource* resource() const { return m_resource.Get(); } const D3D12_RESOURCE_DESC& desc() const { return m_desc; } + D3D12_RESOURCE_STATES lastState() const { return m_lastState; } #if DEBUG LPCWSTR m_name = L""; @@ -446,10 +465,13 @@ class D3D12ResourceManager : public GPUResourceManager D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON, D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE); + // D3D12 requires buffers on the UPLOAD heap to be created in + // D3D12_RESOURCE_STATE_GENERIC_READ and to remain in that state for their + // lifetime; the runtime returns E_INVALIDARG otherwise. rcp makeUploadBuffer( UINT size, D3D12_RESOURCE_FLAGS bindFlags = D3D12_RESOURCE_FLAG_NONE, - D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COPY_SOURCE, + D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE); rcp makeVolatileBuffer( @@ -465,7 +487,7 @@ class D3D12ResourceManager : public GPUResourceManager rcp uploadBuffer = makeUploadBuffer(sizeInBytes, D3D12_RESOURCE_FLAG_NONE, - D3D12_RESOURCE_STATE_COPY_SOURCE); + D3D12_RESOURCE_STATE_GENERIC_READ); rcp constBuffer = makeBuffer(sizeInBytes, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COMMON); diff --git a/thirdparty/rive_renderer/include/rive/renderer/d3d12/render_context_d3d12_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/d3d12/render_context_d3d12_impl.hpp index 3ae9b5a9b..e5a0ae128 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/d3d12/render_context_d3d12_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/d3d12/render_context_d3d12_impl.hpp @@ -105,8 +105,16 @@ class RenderContextD3D12Impl : public RenderContextImpl uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) override; + rcp adoptImageTexture(rcp imageTexture); + +#ifdef RIVE_CANVAS + rcp makeRenderCanvas(uint32_t width, + uint32_t height) override; +#endif + #define IMPLEMENT_RIVE_BUFFER(Name, m_buffer) \ void resize##Name(size_t sizeInBytes) override \ { \ @@ -168,6 +176,14 @@ class RenderContextD3D12Impl : public RenderContextImpl ComPtr device() const { return m_device; } + // Set the command queue used by makeCommandBuffer(). Must be called + // before any ScriptedCanvas flush if canvas support is needed. + void setCommandQueue(ID3D12CommandQueue* queue) { m_canvasQueue = queue; } + ID3D12CommandQueue* commandQueue() const { return m_canvasQueue; } + + void* makeCommandBuffer() override; + void commitCommandBuffer(void* commandBuffer) override; + rcp manager() const { return m_resourceManager; } const D3DCapabilities& d3dCapabilities() const { return m_capabilities; } @@ -186,7 +202,8 @@ class RenderContextD3D12Impl : public RenderContextImpl private: RenderContextD3D12Impl(ComPtr, ID3D12GraphicsCommandList*, - const D3DCapabilities&); + const D3DCapabilities&, + ShaderCompilationMode); void blitSubRect(ID3D12GraphicsCommandList* cmdList, D3D12Texture* dst, @@ -194,6 +211,7 @@ class RenderContextD3D12Impl : public RenderContextImpl const IAABB& rect); ComPtr m_device; + ID3D12CommandQueue* m_canvasQueue = nullptr; const D3DCapabilities m_capabilities; rcp m_gradientTexture; @@ -273,5 +291,6 @@ class RenderContextD3D12Impl : public RenderContextImpl std::chrono::steady_clock::now(); bool m_isFirstFlushOfFrame = true; + bool m_usesCopyCommandList = false; }; } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/draw.hpp b/thirdparty/rive_renderer/include/rive/renderer/draw.hpp index 53921988f..234ebe2fb 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/draw.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/draw.hpp @@ -58,7 +58,23 @@ class Draw gpu::DrawContents drawContents() const { return m_drawContents; } bool isOpaque() const { - return m_drawContents & gpu::DrawContents::opaquePaint; + return enums::is_flag_set(m_drawContents, + gpu::DrawContents::opaquePaint); + } + bool isClipUpdate() const + { + return enums::is_flag_set(m_drawContents, + gpu::DrawContents::clipUpdate); + } + bool hasActiveClip() const + { + return enums::is_flag_set(m_drawContents, + gpu::DrawContents::activeClip); + } + bool hasAdvancedBlend() const + { + return enums::is_flag_set(m_drawContents, + gpu::DrawContents::advancedBlend); } uint32_t clipID() const { return m_clipID; } bool hasClipRect() const { return m_clipRectInverseMatrix != nullptr; } @@ -130,8 +146,8 @@ class Draw // // NOTE: Subpasses are not necessarily rendered one after the other. // Separate, non-overlapping draws may have gotten sorted between subpasses. - virtual void pushToRenderContext(RenderContext::LogicalFlush*, - int subpassIndex) = 0; + virtual gpu::DrawBatch* pushToRenderContext(RenderContext::LogicalFlush*, + int subpassIndex) = 0; // We can't have a destructor because we're block-allocated. Instead, the // client calls this method before clearing the drawList to release all our @@ -176,6 +192,7 @@ class Draw // WebGL msaa), this is a linked list of all the draws from a single batch // whose bounding boxes needs to be blitted to the "dstRead" texture before // drawing. +public: const Draw mutable* m_nextDstRead = nullptr; }; @@ -195,6 +212,7 @@ class PathDraw : public Draw rcp, FillRule, const RiveRenderPaint*, + float modulatedOpacity, RawPath* scratchPath); // Determines how coverage is calculated for antialiasing and feathers. @@ -204,6 +222,7 @@ class PathDraw : public Draw enum class CoverageType { pixelLocalStorage, // InterlockMode::rasterOrdering and atomics + clockwise, // InterlockMode::clockwise clockwiseAtomic, // InterlockMode::clockwiseAtomic msaa, // InterlockMode::msaa atlas, // Any InterlockMode may opt to use atlas coverage for large @@ -215,6 +234,7 @@ class PathDraw : public Draw rcp, FillRule, const RiveRenderPaint*, + float modulatedOpacity, CoverageType, const RenderContext::FrameDescriptor&); @@ -239,6 +259,16 @@ class PathDraw : public Draw return m_contourDirections; } + // Is the draw an "outermost" (i.e., non-nested) clip update? + // Outermost clip updates reset the clip buffer entirely, rather than + // subtracting coverage from what's already there. + bool isOutermostClipUpdate() const + { + return (m_drawContents & (gpu::DrawContents::clipUpdate | + gpu::DrawContents::activeClip)) == + gpu::DrawContents::clipUpdate; + } + // Only used when rendering coverage via the atlas. const gpu::AtlasTransform& atlasTransform() const { @@ -252,14 +282,29 @@ class PathDraw : public Draw { return m_coverageBufferRange; } + // Returns true if this path will need borrowed coverage prepass(es) in + // clockwiseAtomic mode. + // NOTE: Since the interlock mode isn't known at this level, the + // responsibility is on the caller to only use this method in + // clockwiseAtomic mode. Otherwise, there are never borrowed coverage + // prepasses. + bool needsBorrowedCoveragePrepass() const + { + assert(m_coverageType == CoverageType::clockwiseAtomic); + return !isStroke() && // Strokes don't have negative coverage. + !isOutermostClipUpdate(); // Outermost (i.e., non-nested) + // clockwiseAtomic clips render + // directly to the clip buffer in a + // single pass. + } GrInnerFanTriangulator* triangulator() const { return m_triangulator; } bool allocateResources(RenderContext::LogicalFlush*) override; void countSubpasses() override; - void pushToRenderContext(RenderContext::LogicalFlush*, - int subpassIndex) override; + gpu::DrawBatch* pushToRenderContext(RenderContext::LogicalFlush*, + int subpassIndex) override; // Called after pushToRenderContext(), and only when this draw uses an atlas // for tessellation. In the CoverageType::atlas case, pushToRenderContext() @@ -305,7 +350,7 @@ class PathDraw : public Draw // Calls LogicalFlush::pushOuterCubicsDraw() or // LogicalFlush::pushMidpointFanDraw() for this PathDraw. - void pushTessellationDraw( + gpu::DrawBatch& pushTessellationDraw( RenderContext::LogicalFlush*, uint32_t tessVertexCount, uint32_t tessLocation, @@ -355,7 +400,7 @@ class PathDraw : public Draw const RiveRenderPath* const m_pathRef; const FillRule m_pathFillRule; // Fill rule can mutate on RenderPath. - const Gradient* m_gradientRef; + const Gradient* m_gradientRef; // Already modulated if opacity != 1.0 const gpu::PaintType m_paintType; const CoverageType m_coverageType; float m_strokeRadius = 0; @@ -449,8 +494,8 @@ class ImageRectDraw : public Draw float opacity() const { return m_opacity; } - void pushToRenderContext(RenderContext::LogicalFlush*, - int subpassIndex) override; + gpu::DrawBatch* pushToRenderContext(RenderContext::LogicalFlush*, + int subpassIndex) override; protected: const float m_opacity; @@ -477,8 +522,8 @@ class ImageMeshDraw : public Draw uint32_t indexCount() const { return m_indexCount; } float opacity() const { return m_opacity; } - void pushToRenderContext(RenderContext::LogicalFlush*, - int subpassIndex) override; + gpu::DrawBatch* pushToRenderContext(RenderContext::LogicalFlush*, + int subpassIndex) override; void releaseRefs() override; @@ -490,10 +535,9 @@ class ImageMeshDraw : public Draw const float m_opacity; }; -// Resets the stencil clip by either entirely erasing the existing clip, or -// intersecting it with a nested clip (i.e., erasing the region outside the -// nested clip). -class StencilClipReset : public Draw +// Resets the clip by either entirely erasing the existing clip, or intersecting +// it with a nested clip (i.e., erasing the region outside the nested clip). +class ClipReset : public Draw { public: enum class ResetAction @@ -502,15 +546,15 @@ class StencilClipReset : public Draw intersectPreviousClip, }; - StencilClipReset(RenderContext*, - uint32_t previousClipID, - gpu::DrawContents previousClipDrawContents, - ResetAction); + ClipReset(RenderContext*, + uint32_t previousClipID, + gpu::DrawContents previousClipDrawContents, + ResetAction); uint32_t previousClipID() const { return m_previousClipID; } - void pushToRenderContext(RenderContext::LogicalFlush*, - int subpassIndex) override; + gpu::DrawBatch* pushToRenderContext(RenderContext::LogicalFlush*, + int subpassIndex) override; protected: const uint32_t m_previousClipID; diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/gl_state.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/gl_state.hpp index c4b678cfd..d083fa257 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/gl_state.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/gl_state.hpp @@ -4,6 +4,7 @@ #pragma once +#include "rive/math/aabb.hpp" #include "rive/renderer/gl/gles3.hpp" #include "rive/refcnt.hpp" #include "rive/renderer/gpu.hpp" @@ -23,13 +24,23 @@ class GLState : public RefCnt void invalidate(); + // Set the scissor with a top-down oriented box. (GLState will Y-flip the + // box before passing it to GL, which is why this function needs + // renderTargetHeight.) + void setScissor(IAABB, uint32_t renderTargetHeight); + // Set the scissor with the raw values that will be passed to glScissor(). + void setScissorRaw(uint32_t left, + uint32_t top, + uint32_t width, + uint32_t height); + void disableScissor(); void setDepthStencilEnabled(bool depthEnabled, bool stencilEnabled); void setCullFace(GLenum); - void setBlendEquation(gpu::BlendEquation); - void disableBlending() { setBlendEquation(gpu::BlendEquation::none); } void setWriteMasks(bool colorWriteMask, bool depthWriteMask, uint8_t stencilWriteMask); + void setBlendEquation(gpu::BlendEquation); + void disableBlending() { setBlendEquation(gpu::BlendEquation::none); } void setPipelineState(const gpu::PipelineState&); void bindProgram(GLuint); @@ -42,11 +53,13 @@ class GLState : public RefCnt private: const GLCapabilities m_capabilities; - gpu::BlendEquation m_blendEquation; + std::array m_scissorBox; + bool m_scissorEnabled; bool m_depthTestEnabled; bool m_stencilTestEnabled; bool m_colorWriteMask; bool m_depthWriteMask; + gpu::BlendEquation m_blendEquation; GLuint m_stencilWriteMask; GLenum m_cullFace; GLuint m_boundProgramID; @@ -56,9 +69,11 @@ class GLState : public RefCnt struct { - bool blendEquation : 1; + bool scissorBox : 1; + bool scissorEnabled : 1; bool depthStencilEnabled : 1; bool writeMasks : 1; + bool blendEquation : 1; bool cullFace : 1; bool boundProgramID : 1; bool boundVAO : 1; diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/gl_utils.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/gl_utils.hpp index e9783d4c5..1590f8a0b 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/gl_utils.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/gl_utils.hpp @@ -22,33 +22,56 @@ namespace glutils // renames from minify.py.) constexpr static char BASE_INSTANCE_UNIFORM_NAME[] = "_baseInstance"; -void CompileAndAttachShader(GLuint program, - GLenum type, - const char* source, - const GLCapabilities&); - -void CompileAndAttachShader(GLuint program, - GLenum type, - const char* defines[], - size_t numDefines, - const char* sources[], - size_t numSources, - const GLCapabilities&); - -[[nodiscard]] GLuint CompileShader(GLuint type, - const char* source, - const GLCapabilities&); - -[[nodiscard]] GLuint CompileShader(GLuint type, - const char* defines[], - size_t numDefines, - const char* sources[], - size_t numSources, - const GLCapabilities&); - -[[nodiscard]] GLuint CompileRawGLSL(GLenum shaderType, const char* rawGLSL); - -void LinkProgram(GLuint program); +#ifdef DEBUG +void PrintShaderCompilationErrors(GLuint shader); +void PrintLinkProgramErrors(GLuint program); +#endif + +enum class DebugPrintErrorAndAbort +{ + no, + yes, +}; + +void CompileAndAttachShader( + GLuint program, + GLenum type, + const char* source, + const GLCapabilities&, + DebugPrintErrorAndAbort = DebugPrintErrorAndAbort::yes); + +void CompileAndAttachShader( + GLuint program, + GLenum type, + const char* defines[], + size_t numDefines, + const char* sources[], + size_t numSources, + const GLCapabilities&, + DebugPrintErrorAndAbort = DebugPrintErrorAndAbort::yes); + +[[nodiscard]] GLuint CompileShader( + GLuint type, + const char* source, + const GLCapabilities&, + DebugPrintErrorAndAbort = DebugPrintErrorAndAbort::yes); + +[[nodiscard]] GLuint CompileShader( + GLuint type, + const char* defines[], + size_t numDefines, + const char* sources[], + size_t numSources, + const GLCapabilities&, + DebugPrintErrorAndAbort = DebugPrintErrorAndAbort::yes); + +[[nodiscard]] GLuint CompileRawGLSL( + GLenum shaderType, + const char* rawGLSL, + DebugPrintErrorAndAbort = DebugPrintErrorAndAbort::yes); + +void LinkProgram(GLuint program, + DebugPrintErrorAndAbort = DebugPrintErrorAndAbort::yes); class GLObject { @@ -245,9 +268,4 @@ void BlitFramebuffer(rive::IAABB bounds, GLbitfield mask = GL_COLOR_BUFFER_BIT); void Uniform1iByName(GLuint programID, const char* name, GLint value); - -// ANGLE_shader_pixel_local_storage enum values had a breaking change in early -// 2025. Return true if we can verify that we're running on the latest -// ANGLE_shader_pixel_local_storage spec. -bool validate_pixel_local_storage_angle(); } // namespace glutils diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/gles3.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/gles3.hpp index 9d0eba070..5d0452682 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/gles3.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/gles3.hpp @@ -13,6 +13,8 @@ #define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 #define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 #define glFramebufferFetchBarrierQCOM(...) RIVE_UNREACHABLE() +#define glFramebufferPixelLocalStorageSizeEXT(...) RIVE_UNREACHABLE() +#define glClearPixelLocalStorageuiEXT(...) RIVE_UNREACHABLE() #endif #ifdef RIVE_ANDROID @@ -49,12 +51,12 @@ #define GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE 0x96EC #define GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE 0x96ED extern bool webgl_enable_WEBGL_shader_pixel_local_storage_coherent(); -extern bool webgl_enable_WEBGL_provoking_vertex(); extern bool webgl_shader_pixel_local_storage_is_coherent(); extern void glFramebufferTexturePixelLocalStorageANGLE(GLint plane, GLuint backingtexture, GLint level, - GLint layer); + GLint layer, + GLenum usage); extern void glFramebufferPixelLocalClearValuefvANGLE(GLint plane, const GLfloat value[4]); extern void glBeginPixelLocalStorageANGLE(GLsizei n, const GLenum loadops[]); @@ -69,6 +71,7 @@ extern void glGetFramebufferPixelLocalStorageParameterivANGLE(GLint plane, #define GL_FIRST_VERTEX_CONVENTION_ANGLE 0x8E4D #define GL_LAST_VERTEX_CONVENTION_ANGLE 0x8E4E #define GL_PROVOKING_VERTEX_ANGLE 0x8E4F +extern bool webgl_enable_WEBGL_provoking_vertex(); extern void glProvokingVertexANGLE(GLenum provokeMode); #endif @@ -90,6 +93,7 @@ extern void glProvokingVertexANGLE(GLenum provokeMode); #define GL_HSL_COLOR_KHR 0x92AF #define GL_HSL_LUMINOSITY_KHR 0x92B0 #define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#define glBlendBarrierKHR(...) RIVE_UNREACHABLE() #endif #ifndef GL_EXT_clip_cull_distance @@ -100,6 +104,12 @@ extern void glProvokingVertexANGLE(GLenum provokeMode); #define GL_CLIP_DISTANCE3_EXT 0x3003 #endif +#ifndef GL_KHR_parallel_shader_compile +#define GL_KHR_parallel_shader_compile 1 +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_COMPLETION_STATUS_KHR 0x91B1 +#endif + #endif // RIVE_WEBGL #if defined(RIVE_ANDROID) || defined(RIVE_WEBGL) @@ -113,32 +123,65 @@ struct GLCapabilities { GLCapabilities() { memset(this, 0, sizeof(*this)); } - bool isContextVersionAtLeast(int major, int minor) const + static bool IsVersionAtLeast(uint32_t aMajor, + uint32_t aMinor, + uint32_t bMajor, + uint32_t bMinor) { - return ((contextVersionMajor << 16) | contextVersionMinor) >= - ((major << 16) | minor); + uint64_t a = (static_cast(aMajor) << 32) | aMinor; + uint64_t b = (static_cast(bMajor) << 32) | bMinor; + return a >= b; + } + bool isContextVersionAtLeast(uint32_t major, uint32_t minor) const + { + return IsVersionAtLeast(contextVersionMajor, + contextVersionMinor, + major, + minor); + } + bool isVendorDriverVersionAtLeast(uint32_t major, uint32_t minor) const + { + return IsVersionAtLeast(vendorDriverVersionMajor, + vendorDriverVersionMinor, + major, + minor); } - - // GL version. - int contextVersionMajor; - int contextVersionMinor; // Driver info. bool isGLES : 1; - bool isANGLEOrWebGL : 1; + // Is the system OpenGL driver ANGLE? (Not WebGL via ANGLE, but the actual + // system driver (which can also be true in a situation like + // WebGL (probably ANGLE) -> System OpenGL ES (also ANGLE) -> Vulkan)). + bool isANGLESystemDriver : 1; bool isAdreno : 1; bool isMali : 1; bool isPowerVR : 1; + // GL version. + uint32_t contextVersionMajor; + uint32_t contextVersionMinor; + uint32_t vendorDriverVersionMajor; + uint32_t vendorDriverVersionMinor; + uint32_t adrenoSeries; + // Workarounds. - // Some devices crash when issuing draw commands with a large instancecount. - uint32_t maxSupportedInstancesPerDrawCommand = ~0u; + // Many devices crash on draw commands with a large instancecount, or when + // drawing many instances without a glFlush to break them up. + uint32_t maxSupportedInstancesPerFlush; // Chrome 136 crashes when trying to run Rive because it attempts to enable // blending on the tessellation texture, which is invalid for an integer // render target. The workaround is to use a floating-point tessellation // texture. // https://issues.chromium.org/issues/416294709 - bool needsFloatingPointTessellationTexture = false; + bool needsFloatingPointTessellationTexture; + // PowerVR Rogue GE8300, OpenGL ES 3.2 build 1.10@5187610 has severe pixel + // local storage corruption issues with our renderer. Using some of the + // EXT_shader_pixel_local_storage2 API is an apparent workaround that comes + // with worse performance and other, less severe visual artifacts. + bool usePixelLocalStorage2AsWorkaround; + // ANGLE_shader_pixel_local_storage is currently broken with + // GL_TEXTURE_2D_ARRAY on ANGLE's d3d11 renderer. + bool avoidTexture2DArrayWithWebGLPLS; // Extensions bool ANGLE_base_vertex_base_instance_shader_builtin : 1; @@ -150,31 +193,63 @@ struct GLCapabilities bool ARB_fragment_shader_interlock : 1; bool ARB_shader_image_load_store : 1; bool ARB_shader_storage_buffer_object : 1; + bool OES_shader_image_atomic : 1; bool KHR_blend_equation_advanced : 1; bool KHR_blend_equation_advanced_coherent : 1; + bool KHR_parallel_shader_compile : 1; bool EXT_base_instance : 1; bool EXT_clip_cull_distance : 1; bool EXT_color_buffer_half_float : 1; - bool EXT_float_blend : 1; // Implies EXT_color_buffer_float. + bool OES_texture_half_float_linear : 1; + bool EXT_color_buffer_float : 1; + bool EXT_float_blend : 1; bool EXT_multisampled_render_to_texture : 1; bool EXT_shader_framebuffer_fetch : 1; bool EXT_shader_pixel_local_storage : 1; + bool EXT_shader_pixel_local_storage2 : 1; bool INTEL_fragment_shader_ordering : 1; bool QCOM_shader_framebuffer_fetch_noncoherent : 1; + + // Texture compression extensions. + bool EXT_texture_compression_s3tc : 1; // BC1/BC2/BC3 + bool EXT_texture_compression_bptc : 1; // BC7 + bool KHR_texture_compression_astc_ldr : 1; + // ETC2 is core in GLES 3.0+; tracked here for desktop GL (ARB_ES3_compat). + bool supportsETC2 : 1; }; #ifdef RIVE_ANDROID -// Android doesn't load extension functions for us. +// EXT_base_instance. extern PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glDrawArraysInstancedBaseInstanceEXT; extern PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glDrawElementsInstancedBaseInstanceEXT; extern PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glDrawElementsInstancedBaseVertexBaseInstanceEXT; + +// QCOM_shader_framebuffer_fetch_noncoherent. extern PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC glFramebufferFetchBarrierQCOM; + +// EXT_multisampled_render_to_texture. extern PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT; extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; -void LoadGLESExtensions(const GLCapabilities&); + +// KHR_blend_equation_advanced. +extern PFNGLBLENDBARRIERKHRPROC glBlendBarrierKHR; + +// EXT_shader_pixel_local_storage2. +extern PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC + glFramebufferPixelLocalStorageSizeEXT; +extern PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC glClearPixelLocalStorageuiEXT; + +// KHR_parallel_shader_compilation +extern PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glMaxShaderCompilerThreadsKHR; + +// Android doesn't load extension functions for us (also, possibly some +// extensions are reported as present but the functions don't actually exist, +// this call will clear the capabilities flags for extensions that don't load, +// accordingly). +void LoadAndValidateGLESExtensions(GLCapabilities*); #endif diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/load_gles_extensions.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/load_gles_extensions.hpp new file mode 100644 index 000000000..1695c6546 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/load_gles_extensions.hpp @@ -0,0 +1,10 @@ +/* + * Copyright 2025 Rive + */ + +// Bridge header for Ore GL backend — includes the platform-appropriate GL +// headers via gles3.hpp so ore headers can use GL types (GLuint, GLenum, etc.). + +#pragma once + +#include "rive/renderer/gl/gles3.hpp" diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/load_store_actions_ext.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/load_store_actions_ext.hpp index fbd87af4a..6fcbe84ae 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/load_store_actions_ext.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/load_store_actions_ext.hpp @@ -5,7 +5,7 @@ #pragma once #include "rive/renderer/gpu.hpp" -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" #include namespace rive::gpu @@ -16,13 +16,14 @@ namespace rive::gpu enum class LoadStoreActionsEXT { none = 0, - clearColor = 1, - loadColor = 2, - storeColor = 4, - clearCoverage = 8, - clearClip = 16, + clearColor = 1 << 0, + loadColor = 1 << 1, + storeColor = 1 << 2, + clearCoverage = 1 << 3, + clearClip = 1 << 4, }; -RIVE_MAKE_ENUM_BITSET(LoadStoreActionsEXT) + +constexpr static uint32_t LOAD_STORE_ACTIONS_EXT_COUNT = 5; // Determines the specific load actions that need to be emulated for the given // render pass, and unpacks the clear color, if required. diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/render_buffer_gl_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/render_buffer_gl_impl.hpp index 46576f5b0..003e60dc4 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/render_buffer_gl_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/render_buffer_gl_impl.hpp @@ -44,9 +44,11 @@ class RenderBufferGLImpl GLState* state() const { return m_state.get(); } private: +#ifndef RIVE_WEBGL // Returns whether glMapBufferRange() is supported for our buffer. If not, // we use m_fallbackMappedMemory. bool canMapBuffer() const; +#endif const GLenum m_target; GLuint m_bufferID = 0; diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/render_context_gl_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/render_context_gl_impl.hpp index dfcc56600..9e4af3717 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/render_context_gl_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/render_context_gl_impl.hpp @@ -4,10 +4,12 @@ #pragma once +#include "rive/renderer/async_pipeline_manager.hpp" #include "rive/renderer/gl/gl_state.hpp" #include "rive/renderer/gl/gl_utils.hpp" #include "rive/renderer/render_context_helper_impl.hpp" -#include + +#include namespace rive { @@ -18,6 +20,9 @@ class RiveRenderPaint; namespace rive::gpu { class RenderTargetGL; +#ifdef RIVE_CANVAS +class CanvasMirrorTextureGLImpl; +#endif // OpenGL backend implementation of RenderContextImpl. class RenderContextGLImpl : public RenderContextHelperImpl @@ -25,6 +30,8 @@ class RenderContextGLImpl : public RenderContextHelperImpl public: struct ContextOptions { + ShaderCompilationMode shaderCompilationMode = + ShaderCompilationMode::standard; bool disablePixelLocalStorage = false; bool disableFragmentShaderInterlock = false; }; @@ -46,6 +53,7 @@ class RenderContextGLImpl : public RenderContextHelperImpl rcp makeImageTexture(uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) override; // Takes ownership of textureID and responsibility for deleting it. @@ -53,6 +61,62 @@ class RenderContextGLImpl : public RenderContextHelperImpl uint32_t height, GLuint textureID); +#ifdef RIVE_CANVAS + rcp makeRenderCanvas(uint32_t width, + uint32_t height) override; + + // GL-only: returns a Y-flipped companion of a Rive 2D RenderCanvas + // texture, lazily allocating it on first call. Returns nullptr if + // `sourceTex` is not a canvas target (i.e. it's a regular image). + // Called directly from lua_gpu.cpp behind #ifdef ORE_BACKEND_GL. + // See dev/ore_canvas_import_invariant.md. + rcp getCanvasImportMirror(gpu::Texture* sourceTex, + uint32_t width, + uint32_t height); + + // ── Canvas mirror registry (GL/WebGL only) ───────────────────────── + // + // Implements the "imported canvas mirror" pattern for the Rive 2D + // RenderCanvas → Ore boundary. On GL the PLS-rendered canvas is + // bottom-up in memory; consumers that sample it from a WGSL shader + // need a top-up companion texture. The registry tracks the source + // canvas GLuint, lazily allocates a companion + a pair of FBOs the + // first time wrapRiveTexture is called for it, and arranges for the + // companion to be Y-flip-blitted at the end of the source canvas's + // own flush() (when GL state is clean). + // + // Lifetime: registerCanvasTarget is called from makeRenderCanvas; + // unregisterCanvasTarget is called from the canvas-target texture's + // destructor (CanvasTargetTextureGLImpl) so the entry is freed when + // the source GLuint is released. Mirror textures live independently + // via the RiveRenderImage returned to the caller; their destruction + // releases their FBOs and clears the entry's mirror pointer (but + // not the registry slot itself, which dies with the source). + // + // See dev/ore_canvas_import_invariant.md for the full architecture + // discussion. + + void registerCanvasTarget(GLuint sourceTex); + void unregisterCanvasTarget(GLuint sourceTex); + + // Looks up an existing mirror for `sourceTex` and allocates one if + // none exists yet. Returns nullptr if `sourceTex` was never registered + // (i.e. is not a canvas target — caller should fall through to a + // direct view of the source). The returned RiveRenderImage owns the + // companion GLuint; when its refcount drops to zero, the companion + // (and its FBOs) are released. + rcp getOrCreateCanvasMirror(GLuint sourceTex, + uint32_t width, + uint32_t height); + + // Called from RenderContextGLImpl::flush after the post-flush + // glFlush() barrier. Walks the registry for `targetTex`; if there is + // a registered entry with a non-null mirror, runs the Y-flip blit + // from source → mirror. Cheap O(1) hash lookup with a negative-case + // early-out — non-canvas targets pay nothing. + void blitMirrorIfRegistered(GLuint targetTex); +#endif + // Called *after* the GL context has been modified externally. // Re-binds Rive internal resources and invalidates the internal cache of GL // state. @@ -71,6 +135,46 @@ class RenderContextGLImpl : public RenderContextHelperImpl GLState* state() const { return m_state.get(); } + // Storage type and rendering method for the feather atlas. + // + // Ideally we would always use r32f or r16f, but floating point color + // buffers are only supported via extensions in GL. + // + // These are sorted with the most preferred types higher up in the list. + enum class AtlasRenderType + { + r16f, // Most preferred. Balances performances with precision. + r32f, // Uses HW blending to count coverage. + + r32uiFramebufferFetch, // Stores coverage as fp32 bits in a uint. + r8PixelLocalStorageEXT, + r32uiPixelLocalStorageANGLE, + + r32iAtomicTexture, // Stores coverage as 16:16 fixed point. + + rgba8, // Low quality, but always supported. Uses HW blending and breaks + // up coverage into all 4 components of an RGBA texture. + }; + + AtlasRenderType atlasRenderType() const { return m_atlasRenderType; } + +#ifdef WITH_RIVE_TOOLS + // Changes the context's AtlasRenderType for testing purposes. If + // atlasDesiredRenderType is not supported, the next supported + // AtlasRenderType down the list is chosen. + // + // Returns the original AtlasRenderType from before this call was made. + // + // NOTE: this also calls releaseResources() on the owning RenderContext to + // ensure the atlas texture gets reallocated. + AtlasRenderType testingOnly_resetAtlasDesiredRenderType( + RenderContext* owningRenderContext, + AtlasRenderType atlasDesiredRenderType); + + bool testingOnly_setBlendAdvancedCoherentKHRSupported(bool supported); + bool testingOnly_setBlendAdvancedKHRSupported(bool supported); +#endif + private: class DrawProgram; @@ -80,14 +184,18 @@ class RenderContextGLImpl : public RenderContextHelperImpl public: virtual void init(rcp) {} - virtual bool supportsRasterOrdering(const GLCapabilities&) const = 0; - virtual bool supportsFragmentShaderAtomics( - const GLCapabilities&) const = 0; + // Sets any supported interlock modes in PlatformFeatures to true. + // Leaves the rest unchanged. + virtual void getSupportedInterlockModes(const GLCapabilities&, + PlatformFeatures*) const = 0; - virtual void activatePixelLocalStorage(RenderContextGLImpl*, - const FlushDescriptor&) = 0; - virtual void deactivatePixelLocalStorage(RenderContextGLImpl*, - const FlushDescriptor&) = 0; + virtual void resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) + {} + virtual void resizeAtomicCoverageBacking(uint32_t width, + uint32_t height) + {} // Depending on how we handle PLS atomic resolves, the // PixelLocalStorageImpl may require certain flags. @@ -102,6 +210,19 @@ class RenderContextGLImpl : public RenderContextHelperImpl gpu::InterlockMode, std::vector* defines) const = 0; + // Certain PLS draws require implementation-specific pipeline state that + // differs from the general pipeline state. + virtual void applyPipelineStateOverrides(const DrawBatch&, + const FlushDescriptor&, + const PlatformFeatures&, + PipelineState*) const + {} + + virtual void activatePixelLocalStorage(RenderContextGLImpl*, + const FlushDescriptor&) = 0; + virtual void deactivatePixelLocalStorage(RenderContextGLImpl*, + const FlushDescriptor&) = 0; + void ensureRasterOrderingEnabled(RenderContextGLImpl*, const gpu::FlushDescriptor&, bool enabled); @@ -129,7 +250,6 @@ class RenderContextGLImpl : public RenderContextHelperImpl }; class PLSImplEXTNative; - class PLSImplFramebufferFetch; class PLSImplWebGL; class PLSImplRWTexture; @@ -141,11 +261,15 @@ class RenderContextGLImpl : public RenderContextHelperImpl static std::unique_ptr MakeContext( const char* rendererString, GLCapabilities, - std::unique_ptr); + std::unique_ptr, + ShaderCompilationMode); RenderContextGLImpl(const char* rendererString, GLCapabilities, - std::unique_ptr); + std::unique_ptr, + ShaderCompilationMode); + + void buildAtlasRenderPipelines(); std::unique_ptr makeUniformBufferRing( size_t capacityInBytes) override; @@ -158,9 +282,42 @@ class RenderContextGLImpl : public RenderContextHelperImpl void resizeGradientTexture(uint32_t width, uint32_t height) override; void resizeTessellationTexture(uint32_t width, uint32_t height) override; void resizeAtlasTexture(uint32_t width, uint32_t height) override; + void resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) override; + void resizeAtomicCoverageBacking(uint32_t width, uint32_t height) override; + + void preBeginFrame(RenderContext*) override; void flush(const FlushDescriptor&) override; + // We have observed Adreno 308 crash when drawing too many instances spread + // across any number of draw calls. This class breaks them up with glFlush + // in order to fix the crashes. + class GLFlushInjector + { + public: + GLFlushInjector(const GLCapabilities& capabilities) : + m_maxSupportedInstancesPerFlush( + capabilities.maxSupportedInstancesPerFlush) + {} + + void flushBeforeInstancedDrawIfNeeded(uint32_t nextInstanceCount) + { + if (m_currentFlushInstanceCount + nextInstanceCount > + m_maxSupportedInstancesPerFlush) + { + glFlush(); + m_currentFlushInstanceCount = 0; + } + m_currentFlushInstanceCount += nextInstanceCount; + } + + private: + const uint32_t m_maxSupportedInstancesPerFlush; + uint32_t m_currentFlushInstanceCount = 0; + }; + // Issues the equivalent of glDrawElementsInstancedBaseInstanceEXT(), // assuming no vertex attribs are instanced, indices are uint16_t, and // applying workarounds for known driver bugs. @@ -174,7 +331,8 @@ class RenderContextGLImpl : public RenderContextHelperImpl uint32_t baseIndex, uint32_t instanceCount, uint32_t baseInstance, - GLint baseInstanceUniformLocation); + GLint baseInstanceUniformLocation, + GLFlushInjector*); GLCapabilities m_capabilities; @@ -196,7 +354,7 @@ class RenderContextGLImpl : public RenderContextHelperImpl glutils::Framebuffer m_tessellateFBO; GLuint m_tessVertexTexture = 0; - // Atlas rendering. + // Renders feathers to the atlas texture. class AtlasProgram { public: @@ -220,49 +378,74 @@ class RenderContextGLImpl : public RenderContextHelperImpl GLint m_baseInstanceUniformLocation = -1; }; + // Atlas rendering pipelines. + AtlasRenderType m_atlasRenderType; glutils::Shader m_atlasVertexShader; AtlasProgram m_atlasFillProgram; AtlasProgram m_atlasStrokeProgram; + gpu::PipelineState m_atlasFillPipelineState; + gpu::PipelineState m_atlasStrokePipelineState; + // Pipelines for clearing and resolving atlases into a GL_R8 texture for + // sampling. + glutils::Shader m_atlasResolveVertexShader; + glutils::Program m_atlasClearProgram = glutils::Program::Zero(); + glutils::Program m_atlasResolveProgram = glutils::Program::Zero(); + glutils::VAO m_atlasResolveVAO; + glutils::Texture m_atlasRenderTexture = glutils::Texture::Zero(); glutils::Texture m_atlasTexture = glutils::Texture::Zero(); - glutils::Framebuffer m_atlasFBO; + glutils::Framebuffer m_atlasRenderFBO = glutils::Framebuffer::Zero(); + glutils::Framebuffer m_atlasResolveFBO = glutils::Framebuffer::Zero(); - // Wraps a compiled GL shader of draw_path.glsl or draw_image_mesh.glsl, - // either vertex or fragment, with a specific set of features enabled via - // #define. The set of features to enable is dictated by ShaderFeatures. + // Wraps a compiled GL "draw" shader, either vertex or fragment, with a + // specific set of features enabled via #define. The set of features to + // enable is dictated by ShaderFeatures. class DrawShader { public: + DrawShader() = default; DrawShader(const DrawShader&) = delete; DrawShader& operator=(const DrawShader&) = delete; + DrawShader(DrawShader&&); + DrawShader& operator=(DrawShader&&); DrawShader(RenderContextGLImpl* renderContextImpl, GLenum shaderType, gpu::DrawType drawType, - ShaderFeatures shaderFeatures, + gpu::ShaderFeatures shaderFeatures, gpu::InterlockMode interlockMode, gpu::ShaderMiscFlags shaderMiscFlags); - ~DrawShader() { glDeleteShader(m_id); } + ~DrawShader(); GLuint id() const { return m_id; } private: - GLuint m_id; + GLuint m_id = 0; }; - // Wraps a compiled and linked GL program of draw_path.glsl or - // draw_image_mesh.glsl, with a specific set of features enabled via - // #define. The set of features to enable is dictated by ShaderFeatures. + // Wraps a compiled and linked GL "draw" program, with a specific set of + // features enabled via #define. The set of features to enable is dictated + // by ShaderFeatures. class DrawProgram { public: + using PipelineProps = StandardPipelineProps; + using VertexShaderType = DrawShader; + using FragmentShaderType = DrawShader; + DrawProgram(const DrawProgram&) = delete; DrawProgram& operator=(const DrawProgram&) = delete; DrawProgram(RenderContextGLImpl*, + PipelineCreateType, gpu::DrawType, gpu::ShaderFeatures, gpu::InterlockMode, - gpu::ShaderMiscFlags); + gpu::ShaderMiscFlags +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType +#endif + ); ~DrawProgram(); GLuint id() const { return m_id; } @@ -271,17 +454,64 @@ class RenderContextGLImpl : public RenderContextHelperImpl return m_baseInstanceUniformLocation; } + PipelineStatus status() const { return m_pipelineStatus; } + + bool advanceCreation(RenderContextGLImpl*, + PipelineCreateType, + gpu::DrawType, + gpu::ShaderFeatures, + gpu::InterlockMode, + gpu::ShaderMiscFlags); + private: - DrawShader m_fragmentShader; - GLuint m_id; + const DrawShader* m_fragmentShader = nullptr; + const DrawShader* m_vertexShader = nullptr; + PipelineStatus m_pipelineStatus = PipelineStatus::notReady; + GLuint m_id = 0; GLint m_baseInstanceUniformLocation = -1; const rcp m_state; +#ifdef WITH_RIVE_TOOLS + SynthesizedFailureType m_synthesizedFailureType = + SynthesizedFailureType::none; +#endif }; - // Not all programs have a unique vertex shader, so we cache and reuse them - // where possible. - std::map m_vertexShaders; - std::map m_drawPrograms; + class GLPipelineManager : public AsyncPipelineManager + { + using Super = AsyncPipelineManager; + + public: + GLPipelineManager(ShaderCompilationMode, RenderContextGLImpl*); + + protected: + virtual std::unique_ptr createVertexShader( + DrawType, + ShaderFeatures, + InterlockMode) override; + + virtual std::unique_ptr createFragmentShader( + DrawType, + ShaderFeatures, + InterlockMode, + ShaderMiscFlags) override; + + virtual std::unique_ptr createPipeline( + PipelineCreateType createType, + uint32_t key, + const PipelineProps&, + const PlatformFeatures&) override; + + virtual PipelineStatus getPipelineStatus( + const DrawProgram& state) const override; + + virtual bool advanceCreation(DrawProgram&, + const PipelineProps&) override; + + private: + RenderContextGLImpl* m_context; + }; + + GLPipelineManager m_pipelineManager; // Vertex/index buffers for drawing paths. glutils::VAO m_drawVAO; @@ -302,5 +532,38 @@ class RenderContextGLImpl : public RenderContextHelperImpl glutils::Program m_blitAsDrawProgram = glutils::Program::Zero(); const rcp m_state; + + bool m_testForAdvancedBlendError = false; + +#ifdef RIVE_CANVAS + // Imported canvas mirror registry. See registerCanvasTarget / + // getOrCreateCanvasMirror / blitMirrorIfRegistered above. + struct CanvasMirrorEntry + { + // Set in registerCanvasTarget. Identifies an entry as "this is a + // PLS canvas target". Source GLuint is the hash key, so it is + // implicit (not stored in the entry). + + // Lazily allocated by getOrCreateCanvasMirror. Null until the + // first time this canvas is imported via Image:view(). + // Non-owning — the mirror RiveRenderImage owns the GLuint and + // the wrapping rcp keeps it alive. + GLuint mirrorTex = 0; + uint32_t width = 0; + uint32_t height = 0; + + // Persistent FBOs that the blit reuses every frame. Allocated + // when the mirror is first created. Released when the entry's + // owning canvas is unregistered. + GLuint readFBO = 0; + GLuint drawFBO = 0; + + // True iff a mirror has been allocated for this entry. The blit + // hook in flush() only fires when this is true. + bool hasMirror = false; + }; + std::unordered_map m_canvasMirrors; + friend class CanvasMirrorTextureGLImpl; +#endif }; } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/gl/render_target_gl.hpp b/thirdparty/rive_renderer/include/rive/renderer/gl/render_target_gl.hpp index cdbaa11c3..a01fdd167 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gl/render_target_gl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gl/render_target_gl.hpp @@ -24,31 +24,19 @@ class RenderTargetGL : public RenderTarget, // that targets the texture. virtual void bindDestinationFramebuffer(GLenum target) = 0; - // Ensures backing textures for the internal PLS planes are allocated. - // Does not allocate an offscreen target texture. - // Does not allocate an "scratchColor" texture if InterlockMode is - // experimentalAtomics. - virtual void allocateInternalPLSTextures(gpu::InterlockMode) = 0; - - // Specifies which PLS planes to enable when a render target is bound. - enum class DrawBufferMask - { - color = 1 << 0, - clip = 1 << 1, - scratchColor = 1 << 2, - coverage = 1 << 3, - - rasterOrderingBuffers = color | coverage | clip | scratchColor, - atomicBuffers = color | coverage | clip, - }; - - // Binds a framebuffer with all allocated textures attached as color - // attachments. Used for clearing, blitting, and for rendering with - // EXT_shader_framebuffer_fetch. - // - // 'drawBufferCount' specifies the number of glDrawBuffers to enable, - // starting with GL_COLOR_ATTACHMENT0. Ignored for GL_READ_FRAMEBUFFER. - virtual void bindInternalFramebuffer(GLenum target, DrawBufferMask) = 0; + // Returns a texture handle that can be rendered to (e.g., for rendering via + // shader images, ANGLE_shader_pixel_local_storage, or + // EXT_multisampled_render_to_texture). When rendering to an external + // framebuffer, this is an internal texture allocation that the caller must + // blit back to the main framebuffer at the end of a render pass. Otherwise, + // this is the same target texture provided by the client. + virtual GLuint renderTexture() = 0; + + // Binds a framebuffer with renderTexture() attached. When rendering to an + // external framebuffer, this is an internal FBO that the caller must blit + // back to the main framebuffer at the end of a render pass. Otherwise, it's + // the main framebuffer we render to normally. + virtual void bindTextureFramebuffer(GLenum target) = 0; // Binds a "headless" framebuffer to GL_DRAW_FRAMEBUFFER with no color // attachments and no enabled draw buffers. @@ -61,10 +49,6 @@ class RenderTargetGL : public RenderTarget, // will also be bound to their corresponding pixel local storage planes. virtual void bindHeadlessFramebuffer(const GLCapabilities&) = 0; - // Binds the allocated textures to their corresponding GL image binding - // slots. - virtual void bindAsImageTextures(DrawBufferMask) = 0; - enum class MSAAResolveAction { automatic, // The MSAA framebuffer will be resolved automatically. @@ -83,17 +67,29 @@ class RenderTargetGL : public RenderTarget, const IAABB* preserveBounds = nullptr, bool* isFBO0 = nullptr) = 0; - // Binds the internal framebuffer as a texture that can be used to fetch the - // destination color (for blending). - virtual void bindInternalDstTexture(GLenum activeTexture) = 0; +#ifdef GL_ANGLE_shader_pixel_local_storage + // ANGLE_shader_pixel_local_storage requires all backing textures in a + // render pass to have identical dimensions, so we can't use the context's + // "TransientPLSBacking" resource. Instead, this method ensures backing + // textures of identical width & height to the render target are allocated. + virtual void allocateWebGLPLSBacking(const GLCapabilities&) = 0; +#endif + + // Returns a texture that may be used in the absence of + // KHR_blend_equation_advanced to make a copy of the render target for + // blending. + GLuint dstColorTexture(); + void bindDstColorFramebuffer(GLenum target); protected: RenderTargetGL(uint32_t width, uint32_t height) : RenderTarget(width, height) {} -}; -RIVE_MAKE_ENUM_BITSET(RenderTargetGL::DrawBufferMask); +private: + glutils::Texture m_dstColorTexture = glutils::Texture::Zero(); + glutils::Framebuffer m_dstColorFramebuffer = glutils::Framebuffer::Zero(); +}; // GL render target that draws to an external texture provided by the client. // @@ -115,43 +111,42 @@ class TextureRenderTargetGL { m_externalTextureID = externalTextureID; m_framebufferTargetAttachmentDirty = true; - m_framebufferTargetPLSBindingDirty = true; + m_webglPLSBindingsDirty = true; } void bindDestinationFramebuffer(GLenum target) final { - bindInternalFramebuffer(target, DrawBufferMask::color); + bindTextureFramebuffer(target); } - void allocateInternalPLSTextures(gpu::InterlockMode) final; - void bindInternalFramebuffer(GLenum target, DrawBufferMask) final; + GLuint renderTexture() final { return externalTextureID(); } + void bindTextureFramebuffer(GLenum target) final; void bindHeadlessFramebuffer(const GLCapabilities&) final; - void bindAsImageTextures(DrawBufferMask) final; MSAAResolveAction bindMSAAFramebuffer(RenderContextGLImpl*, int sampleCount, const IAABB* preserveBounds, bool* isFBO0) final; - void bindInternalDstTexture(GLenum activeTexture) final; + +#ifdef GL_ANGLE_shader_pixel_local_storage + void allocateWebGLPLSBacking(const GLCapabilities&) final; +#endif private: // Not owned or deleted by us. GLuint m_externalTextureID = 0; glutils::Framebuffer m_framebufferID = glutils::Framebuffer::Zero(); - glutils::Texture m_coverageTexture = glutils::Texture::Zero(); - glutils::Texture m_clipTexture = glutils::Texture::Zero(); - glutils::Texture m_scratchColorTexture = glutils::Texture::Zero(); glutils::Framebuffer m_headlessFramebuffer = glutils::Framebuffer::Zero(); - // GL enables the first drawBuffer by default. - DrawBufferMask m_internalDrawBufferMask = DrawBufferMask::color; - // For framebuffer color attachments. bool m_framebufferTargetAttachmentDirty = false; - bool m_framebufferInternalAttachmentsDirty = false; // For ANGLE_shader_pixel_local_storage attachments. - bool m_framebufferTargetPLSBindingDirty = false; - bool m_framebufferInternalPLSBindingsDirty = false; + glutils::Texture m_webglPLSBackingR32UI = glutils::Texture::Zero(); + // Fallback for when backing PLS planes with GL_TEXTURE_2D_ARRAY is broken + // (i.e., on ANGLE's d3d11 renderer). + glutils::Texture m_webglPLSBackingR32UIFallback = glutils::Texture::Zero(); + glutils::Texture m_webglPLSBackingRGBA8 = glutils::Texture::Zero(); + bool m_webglPLSBindingsDirty = false; glutils::Framebuffer m_msaaFramebuffer = glutils::Framebuffer::Zero(); glutils::Renderbuffer m_msaaColorBuffer = glutils::Renderbuffer::Zero(); @@ -187,15 +182,17 @@ class FramebufferRenderTargetGL void allocateOffscreenTargetTexture(); void bindDestinationFramebuffer(GLenum target) final; - void allocateInternalPLSTextures(gpu::InterlockMode) final; - void bindInternalFramebuffer(GLenum target, DrawBufferMask) final; + GLuint renderTexture() final; + void bindTextureFramebuffer(GLenum target) final; void bindHeadlessFramebuffer(const GLCapabilities&) final; - void bindAsImageTextures(DrawBufferMask) final; MSAAResolveAction bindMSAAFramebuffer(RenderContextGLImpl*, int sampleCount, const IAABB* preserveBounds, bool* isFBO0) final; - void bindInternalDstTexture(GLenum activeTexture) final; + +#ifdef GL_ANGLE_shader_pixel_local_storage + void allocateWebGLPLSBacking(const GLCapabilities&) final; +#endif private: // Ownership of this object is not assumed; the client must delete it when diff --git a/thirdparty/rive_renderer/include/rive/renderer/gpu.hpp b/thirdparty/rive_renderer/include/rive/renderer/gpu.hpp index d459d1f93..ec2fb9b65 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gpu.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gpu.hpp @@ -4,8 +4,9 @@ #pragma once -#include "rive/enum_bitset.hpp" +#include "rive/enums.hpp" #include "rive/math/aabb.hpp" +#include "rive/math/bitwise.hpp" #include "rive/math/mat2d.hpp" #include "rive/math/vec2d.hpp" #include "rive/math/simd.hpp" @@ -14,6 +15,11 @@ #include "rive/renderer/trivial_block_allocator.hpp" #include "rive/shapes/paint/image_sampler.hpp" +#include + +// Use the define to run the feather LUT code +// #define RIVE_GENERATE_FEATHER_LUT + namespace rive { class GrInnerFanTriangulator; @@ -38,6 +44,11 @@ class Gradient; class RenderContextImpl; class RenderTarget; class Texture; +enum class DitherMode; + +// Global MipMap LOD Bias to apply to samplers. Going lower leads to sharper +// filtering at the expense of potential shimmering. +constexpr static float MIP_MAP_LOD_BIAS = -.5f; // Tessellate in parametric space until each segment is within 1/4 pixel of the // true curve. @@ -108,19 +119,23 @@ constexpr static uint32_t kGradTextureWidthInSimpleRamps = // Depth/stencil parameters constexpr static float DEPTH_MIN = 0.0f; constexpr static float DEPTH_MAX = 1.0f; -constexpr static uint32_t STENCIL_CLEAR = 0u; +constexpr static uint8_t STENCIL_CLEAR = 0u; -// Backend-specific capabilities/workarounds and fine tunin// g. +// Backend-specific capabilities/workarounds and fine tuning. struct PlatformFeatures { - // InterlockMode::rasterOrdering. - bool supportsRasterOrdering = false; - // InterlockMode::atomics. - bool supportsFragmentShaderAtomics = false; - // Experimental rendering mode selected by InterlockMode::clockwiseAtomic. - bool supportsClockwiseAtomicRendering = false; + // Supported InterlockModes. + // FIXME: MSAA is implicit even though it isn't implemented on all backends. + bool supportsRasterOrderingMode = false; + bool supportsAtomicMode = false; + bool supportsClockwiseMode = false; + // InterlockMode::Clockwise with fixedFunctionColorOutput and srcOver blend. + // (Only viable for frames that don't use advanced blend.) + bool supportsClockwiseFixedFunctionMode = false; + bool supportsClockwiseAtomicMode = false; // Use KHR_blend_equation_advanced in msaa mode? - bool supportsKHRBlendEquations = false; + bool supportsBlendAdvancedKHR = false; + bool supportsBlendAdvancedCoherentKHR = false; // Required for @ENABLE_CLIP_RECT in msaa mode. bool supportsClipPlanes = false; bool avoidFlatVaryings = false; @@ -183,8 +198,18 @@ struct PlatformFeatures bool clipSpaceBottomUp = false; bool framebufferBottomUp = false; // Backend cannot initialize PLS with typical clear/load APIs in atomic - // mode. Issue a "DrawType::atomicInitialize" draw instead. - bool atomicPLSMustBeInitializedAsDraw = false; + // mode. Issue a "DrawType::renderPassInitialize" draw instead. + bool atomicPLSInitNeedsDraw = false; + // Backend API does not support initializing our (transient) MSAA color + // buffer with the existing (non-MSAA) target texture at the beginning of a + // render pass. Draw the previous renderTarget contents into it manually via + // DrawType::renderPassInitialize when LoadAction::preserveRenderTarget is + // specified. + bool msaaColorPreserveNeedsDraw = false; + // Workaround for Qualcomm. Framebuffer reads on Qualcomm seem to not work + // in clockwiseAtomic mode unless we issue a simple, 1-pixel draw that reads + // the framebuffer between borrowed coverage and the main draws. + bool clockwiseAtomicBorrowedCoverageBarrierNeedsRenderPassInit = false; // Workaround for precision issues. Determines how far apart we space unique // path IDs when they will be bit-casted to fp16. uint8_t pathIDGranularity = 1; @@ -194,6 +219,11 @@ struct PlatformFeatures // clockwiseFill/atomic mode. 2^27 bytes is the minimum storage buffer size // requirement in the Vulkan, GL, and D3D11 specs. Metal guarantees 256 MB. size_t maxCoverageBufferLength = (1 << 27) / sizeof(uint32_t); + + // GPU compressed texture format support (queried per backend at init). + bool supportsTextureCompressionBC = false; // BC1/BC2/BC3/BC7 + bool supportsTextureCompressionASTC = false; // ASTC LDR (any block size) + bool supportsTextureCompressionETC2 = false; // ETC2 RGB8 / RGBA8 }; // Gradient color stops are implemented as a horizontal span of pixels in a @@ -616,12 +646,6 @@ enum class DrawType : uint8_t imageRect, imageMesh, - // Clear/init PLS data when we can't do it with existing clear/load APIs. - atomicInitialize, - - // Resolve PLS data to the final renderTarget color in atomic mode. - atomicResolve, - // MSAA strokes can't be merged with fills because they require their own // dedicated stencil settings. msaaStrokes, @@ -639,8 +663,20 @@ enum class DrawType : uint8_t // type is included in order to support the "retrofittedcubictriangles" GM. msaaOuterCubics, - // Clear or intersect (based on DrawContents) the stencil clip bit. - msaaStencilClipReset, + // Clear or intersect (based on DrawContents) the clip value. + clipReset, + + // Clear/init render pass data with a fullscreen draw when we can't do it + // with existing clear/load APIs. (e.g., for pixel local storage in buffers + // that don't have copy/clear commands, or preserving existing color data in + // a transient MSAA arrachment). + renderPassInitialize, + + // Resolve render pass data (e.g., by applying the final deferred color in + // atomic mode, or copying an offscreen attachment to the final + // renderTarget). + renderPassResolve, + }; constexpr static bool DrawTypeIsImageDraw(DrawType drawType) @@ -655,8 +691,6 @@ constexpr static bool DrawTypeIsImageDraw(DrawType drawType) case DrawType::outerCurvePatches: case DrawType::interiorTriangulation: case DrawType::atlasBlit: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -664,7 +698,9 @@ constexpr static bool DrawTypeIsImageDraw(DrawType drawType) case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: return false; } RIVE_UNREACHABLE(); @@ -696,9 +732,9 @@ constexpr static uint32_t PatchIndexCount(DrawType drawType) case DrawType::atlasBlit: case DrawType::imageRect: case DrawType::imageMesh: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); } RIVE_UNREACHABLE(); @@ -728,9 +764,9 @@ constexpr static uint32_t PatchBaseIndex(DrawType drawType) case DrawType::atlasBlit: case DrawType::imageRect: case DrawType::imageMesh: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); } RIVE_UNREACHABLE(); @@ -749,6 +785,11 @@ enum class InterlockMode { rasterOrdering, atomics, + // Overrides every path's fill rule with clockwise, and implements the + // clockwise algorithm using raster ordering hardware. + // TODO: Once polished, this mode can be mixed into "rasterOrdering" and + // used selectively for clockwise paths. + clockwise, // Use an experimental path rendering algorithm that utilizes atomics // without barriers. This requires that we override all paths' fill rules // (winding or even/odd) with a "clockwise" fill rule, where only regions @@ -756,7 +797,11 @@ enum class InterlockMode clockwiseAtomic, msaa, }; -constexpr static size_t kInterlockModeCount = 4; +constexpr static size_t INTERLOCK_MODE_COUNT = 5; +// # of bits required to contain an InterlockMode. +constexpr static size_t INTERLOCK_MODE_BIT_COUNT = 3; +static_assert(INTERLOCK_MODE_COUNT <= (1 << INTERLOCK_MODE_BIT_COUNT)); +static_assert(INTERLOCK_MODE_COUNT > (1 << (INTERLOCK_MODE_BIT_COUNT - 1))); // Low-level batch of scissored geometry for rendering to the offscreen atlas. struct AtlasDrawBatch @@ -785,15 +830,21 @@ enum class ShaderFeatures ENABLE_EVEN_ODD = 1 << 4, ENABLE_NESTED_CLIPPING = 1 << 5, ENABLE_HSL_BLEND_MODES = 1 << 6, + ENABLE_DITHER = 1 << 7, }; -RIVE_MAKE_ENUM_BITSET(ShaderFeatures) -constexpr static size_t kShaderFeatureCount = 7; + +constexpr static size_t kShaderFeatureCount = 8; constexpr static ShaderFeatures kAllShaderFeatures = static_cast((1 << kShaderFeatureCount) - 1); constexpr static ShaderFeatures kVertexShaderFeaturesMask = ShaderFeatures::ENABLE_CLIPPING | ShaderFeatures::ENABLE_CLIP_RECT | ShaderFeatures::ENABLE_ADVANCED_BLEND | ShaderFeatures::ENABLE_FEATHER; +// These shader features change the way atomic pipelines are set up (or cause +// validation failures when enabled but not used) +constexpr static ShaderFeatures kExclusiveAtomicUbershaderFeaturesMask = + ShaderFeatures::ENABLE_ADVANCED_BLEND; + constexpr static ShaderFeatures ShaderFeaturesMaskFor( InterlockMode interlockMode) { @@ -803,14 +854,21 @@ constexpr static ShaderFeatures ShaderFeaturesMaskFor( return kAllShaderFeatures; case InterlockMode::atomics: return kAllShaderFeatures & ~ShaderFeatures::ENABLE_NESTED_CLIPPING; + case InterlockMode::clockwise: + return kAllShaderFeatures & ~ShaderFeatures::ENABLE_EVEN_ODD; case InterlockMode::clockwiseAtomic: - // TODO: shader features aren't fully implemented yet in - // clockwiseAtomic mode. - return ShaderFeatures::ENABLE_FEATHER; + return kAllShaderFeatures & + // clockwiseAtomic never supports even/odd fill rule. + ~ShaderFeatures::ENABLE_EVEN_ODD & + // clockwiseAtomic requires special blend state for nested + // clip updates, so they need their own draw anyway and the + // ENABLE_NESTED_CLIPPING feature isn't necessary. + ~ShaderFeatures::ENABLE_NESTED_CLIPPING; case InterlockMode::msaa: return ShaderFeatures::ENABLE_CLIP_RECT | ShaderFeatures::ENABLE_ADVANCED_BLEND | - ShaderFeatures::ENABLE_HSL_BLEND_MODES; + ShaderFeatures::ENABLE_HSL_BLEND_MODES | + ShaderFeatures::ENABLE_DITHER; } RIVE_UNREACHABLE(); } @@ -832,29 +890,40 @@ enum class ShaderMiscFlags : uint32_t // get filled. clockwiseFill = 1 << 1, - // clockwiseAtomic mode only. This shader is a prepass that only subtracts - // (counterclockwise) borrowed coverage from the coverage buffer. It doesn't - // output color or clip. - borrowedCoveragePrepass = 1 << 2, + // clockwise and clockwiseAtomic only: This is a specialized shader that + // only renders to the clip buffer. It doesn't output color. + clipUpdateOnly = 1 << 2, - // DrawType::atomicInitialize only. Also store the color clear value to PLS - // when drawing a clear, in addition to clearing the other PLS planes. - storeColorClear = 1 << 3, + // clockwiseAtomic only: This is a specialized shader that only subtracts + // coverage from the existing clip contents (i.e., nested clip updates). + // It doesn't output color. + nestedClipUpdateOnly = 1 << 3, - // DrawType::atomicInitialize only. Swizzle the existing framebuffer + // clockwise and clockwiseAtomic modes only. This shader renders a pass that + // only subtracts (counterclockwise) borrowed coverage from the coverage + // buffer. It doesn't output color or clip. + // If drawing interior triangulations, every fragment will be the first of + // the path at its pixel, so it can blindly overwrite coverage without + // reading the buffer and subtracting. + borrowedCoveragePass = 1 << 4, + + // DrawType::renderPassInitialize only. Also store the color clear value to + // PLS when drawing a clear, in addition to clearing the other PLS planes. + storeColorClear = 1 << 5, + + // DrawType::renderPassInitialize only. Swizzle the existing framebuffer // contents from BGRA to RGBA. (For when this data had to get copied from a // BGRA target.) - swizzleColorBGRAToRGBA = 1 << 4, + swizzleColorBGRAToRGBA = 1 << 6, - // DrawType::atomicResolve only. Optimization for when rendering to an + // DrawType::renderPassResolve only. Optimization for when rendering to an // offscreen texture. // // It renders the final "resolve" operation directly to the renderTarget in // a single pass, instead of (1) resolving the offscreen texture, and then // (2) copying the offscreen texture to back the renderTarget. - coalescedResolveAndTransfer = 1 << 5, + coalescedResolveAndTransfer = 1 << 7, }; -RIVE_MAKE_ENUM_BITSET(ShaderMiscFlags) constexpr static ShaderFeatures ShaderFeaturesMaskFor( DrawType drawType, @@ -866,12 +935,13 @@ constexpr static ShaderFeatures ShaderFeaturesMaskFor( case DrawType::imageRect: case DrawType::imageMesh: case DrawType::atlasBlit: - if (interlockMode != gpu::InterlockMode::atomics) + if (interlockMode != InterlockMode::atomics) { mask = ShaderFeatures::ENABLE_CLIPPING | ShaderFeatures::ENABLE_CLIP_RECT | ShaderFeatures::ENABLE_ADVANCED_BLEND | - ShaderFeatures::ENABLE_HSL_BLEND_MODES; + ShaderFeatures::ENABLE_HSL_BLEND_MODES | + ShaderFeatures::ENABLE_DITHER; break; } // Since atomic mode has to resolve previous draws, images need to @@ -888,21 +958,104 @@ constexpr static ShaderFeatures ShaderFeaturesMaskFor( case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::atomicResolve: mask = kAllShaderFeatures; break; - case DrawType::atomicInitialize: - assert(interlockMode == gpu::InterlockMode::atomics); - mask = ShaderFeatures::ENABLE_CLIPPING | - ShaderFeatures::ENABLE_ADVANCED_BLEND; + case DrawType::clipReset: + mask = ShaderFeatures::ENABLE_DITHER; + break; + case DrawType::renderPassInitialize: + if (interlockMode == InterlockMode::atomics) + { + // Atomic mode initializes clipping and color (when advanced + // blend is active). + mask = ShaderFeatures::ENABLE_CLIPPING | + ShaderFeatures::ENABLE_ADVANCED_BLEND | + ShaderFeatures::ENABLE_DITHER; + } + else if (interlockMode == InterlockMode::msaa) + { + // MSAA mode only needs to initialize color, and only when + // preserving the render target but using a transient MSAA + // attachment. + mask = ShaderFeatures::ENABLE_DITHER; + } + else + { + // The renderPassInitialize draw in clockwiseAtomic mode is just + // a simple workaround that draws a single pixel. No Rive + // ShaderFeatures needed. + assert(interlockMode == InterlockMode::clockwiseAtomic); + mask = ShaderFeatures::NONE; + } break; - case DrawType::msaaStencilClipReset: - mask = ShaderFeatures::NONE; + case DrawType::renderPassResolve: + if (interlockMode == InterlockMode::atomics) + { + mask = kAllShaderFeatures; + } + else + { + assert(interlockMode == InterlockMode::rasterOrdering || + interlockMode == InterlockMode::msaa); + mask = ShaderFeatures::ENABLE_DITHER; + } break; } return mask & ShaderFeaturesMaskFor(interlockMode); } +// Returns the flags that are valid for an ubershader version of the currently- +// requested shader feature set. There are some shader features that change +// how the render passes are set up in atomic mode that need to be accounted +// for beyond just using ShaderFeaturesMaskFor. +constexpr static ShaderFeatures UbershaderFeaturesMaskFor( + ShaderFeatures requestedFeatures, + DrawType drawType, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + const PlatformFeatures& platformFeatures) +{ + ShaderFeatures outFeatures = ShaderFeaturesMaskFor(drawType, interlockMode); + if (interlockMode == InterlockMode::atomics) + { + // Turn off the exclusive atomic features unless they're set in our + // requested feature flags. + outFeatures &= + (requestedFeatures | ~kExclusiveAtomicUbershaderFeaturesMask); + } + + // Ensure that we haven't dropped features we care about somehow + assert((requestedFeatures & outFeatures) == requestedFeatures); + + // ENABLE_CLIP_RECT shouldn't be set if we're in MSAA mode without clip + // plane support. + if (interlockMode == InterlockMode::msaa && + !platformFeatures.supportsClipPlanes) + { + outFeatures &= ~ShaderFeatures::ENABLE_CLIP_RECT; + } + + // Borrowed coverage and anything with fixedFunctionColorOutput cannot + // coexist with ENABLE_ADVANCED_BLEND + if (enums::any_flag_set(shaderMiscFlags, + ShaderMiscFlags::borrowedCoveragePass | + ShaderMiscFlags::fixedFunctionColorOutput)) + { + outFeatures &= ~ShaderFeatures::ENABLE_ADVANCED_BLEND; + } + + // in atomic mode, coalescedResolveAndTransfer currently implies advanced + // blend. + if (interlockMode == InterlockMode::atomics && + enums::is_flag_set(shaderMiscFlags, + ShaderMiscFlags::coalescedResolveAndTransfer)) + { + outFeatures |= ShaderFeatures::ENABLE_ADVANCED_BLEND; + } + + return outFeatures; +} + // Returns a unique value that can be used to key a shader. uint32_t ShaderUniqueKey(DrawType, ShaderFeatures, @@ -911,6 +1064,11 @@ uint32_t ShaderUniqueKey(DrawType, extern const char* GetShaderFeatureGLSLName(ShaderFeatures feature); +void ForEachUbershaderPermutation( + InterlockMode, + const PlatformFeatures&, + const std::function&); + // Flags indicating the contents of a draw. These don't affect shaders, but in // msaa mode they are needed to break up batching. (msaa needs different // stencil/blend state, depending on the DrawContents.) @@ -929,10 +1087,43 @@ enum class DrawContents nonZeroFill = 1 << 4, evenOddFill = 1 << 5, activeClip = 1 << 6, - clipUpdate = 1 << 7, - advancedBlend = 1 << 8, + advancedBlend = 1 << 7, + // Put clip updates last because they use an entirely different shader in + // clockwise mode. + clipUpdate = 1 << 8, + }; -RIVE_MAKE_ENUM_BITSET(DrawContents) + +// These are the only draw contents flags that apply to the pipeline state (and +// they only matter for MSAA) +constexpr static DrawContents DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE = + DrawContents::activeClip | DrawContents::clipUpdate | + DrawContents::clockwiseFill | DrawContents::evenOddFill | + DrawContents::opaquePaint; + +enum class StencilType +{ + disabled, + activeStencilClip, + borrowedCoverage, + forwardClippedByBackward, + backwardTriangleCleanup, + stencilNestedOrEvenOdd, + evenOddDrawAndReset, + nestedClipReset, + clipReset, +}; + +constexpr uint32_t STENCIL_TYPE_BIT_COUNT = 4; + +struct StencilInfo +{ + StencilType stencilType; + DrawContents drawContentsMask; + bool areDrawContentsValid = true; +}; + +StencilInfo get_stencil_info(InterlockMode, DrawType, DrawContents); // A nestedClip draw updates the clip buffer while simultaneously clipping // against the outerClip that is currently in the clip buffer. @@ -947,32 +1138,39 @@ enum class BarrierFlags : uint8_t // Pixel-local dependency in the PLS planes. (Atomic mode only.) Ensure // prior draws complete at each pixel before beginning new ones. plsAtomic = 1 << 0, - plsAtomicPostInit = 1 << 1, // Once after the initial clear/load. - plsAtomicPreResolve = 1 << 2, // Once before the final resolve. + plsAtomicPreResolve = 1 << 1, // Once before the final resolve. + + // MSAA needs a special barrier (e.g., subpass transition) after manually + // loading the render target into the transient MSAA attachment. + msaaPostInit = 1 << 2, // Pixel-local dependency in the coverage buffer. (clockwiseAtomic mode // only.) All "borrowed coverage" draws have now been issued. Ensure they // complete at each pixel before beginning the "forward coverage" draws. clockwiseBorrowedCoverage = 1 << 3, - // The next DrawBatch needs to perform an advanced blend, but on the current - // hardware, we can only fetch the dst color via a separate texture. (MSAA - // mode only.) Prepare a dstColorTexture with the current framebuffer - // contents. If we're lucky, this will be a Vulkan input attachment. On GL, - // this is a literal MSAA resolve & blit to a separate texture. - dstColorTexture = 1 << 4, + // The next DrawBatch needs to perform an advanced blend, but the current + // hardware requires an implementation-dependent barrier before reading the + // dstColor (pipeline barrier for input attachments, KHR blend barrier, or + // even a full MSAA resolve & blit into a separate texture.) + dstBlend = 1 << 4, + + // Special barrier (e.g., subpass transition) issued prior to a manual + // render pass resolve. (Only applicable with + // FlushDescriptor::manuallyResolved.) + preManualResolve = 1 << 5, // Only prevent future DrawBatches from being combined with the current // drawList. (No GPU dependencies.) - drawBatchBreak = 1 << 5, + drawBatchBreak = 1 << 6, }; -RIVE_MAKE_ENUM_BITSET(BarrierFlags); // Low-level batch of geometry to submit to the GPU. struct DrawBatch { DrawBatch(DrawType drawType_, - gpu::ShaderMiscFlags shaderMiscFlags_, + ShaderMiscFlags shaderMiscFlags_, + DrawContents drawContents_, uint32_t elementCount_, uint32_t baseElement_, rive::BlendMode blendMode_, @@ -980,6 +1178,7 @@ struct DrawBatch BarrierFlags barrierFlags_) : drawType(drawType_), shaderMiscFlags(shaderMiscFlags_), + drawContents(drawContents_), elementCount(elementCount_), baseElement(baseElement_), firstBlendMode(blendMode_), @@ -988,13 +1187,13 @@ struct DrawBatch {} const DrawType drawType; - const ShaderMiscFlags shaderMiscFlags; + ShaderMiscFlags shaderMiscFlags; + DrawContents drawContents; uint32_t elementCount; // Vertex, index, or instance count. uint32_t baseElement; // Base vertex, index, or instance. rive::BlendMode firstBlendMode; BarrierFlags barriers; // Barriers to execute before drawing this batch. - DrawContents drawContents = DrawContents::none; ShaderFeatures shaderFeatures = ShaderFeatures::NONE; // DrawType::imageRect and DrawType::imageMesh. @@ -1012,6 +1211,17 @@ struct DrawBatch // bounding boxes needs to be blitted to the "dstRead" texture before // drawing. const Draw* dstReadList = nullptr; + + // Pointer to the next DrawBatchatch in the list that has a + // "BarrierFlags::dstBlend" barrier. + // When we need advanced blend but the underlying graphics API doesn't + // support reading the framebuffer, this can be helpful for breaking up the + // drawList into multiple render passes with framebuffer copies in between. + const DrawBatch* nextDstBlendBarrier = nullptr; + // Link to the next batch to render in the drawList. DrawBatch always exists + // in a linked list. + + const DrawBatch* next = nullptr; }; // Simple gradients only have 2 texels, so we write them to mapped texture @@ -1022,6 +1232,18 @@ struct TwoTexelRamp }; static_assert(sizeof(TwoTexelRamp) == 8 * sizeof(uint8_t)); +#ifdef WITH_RIVE_TOOLS + +enum class SynthesizedFailureType +{ + none, + ubershaderLoad, + shaderCompilation, + pipelineCreation, +}; + +#endif + // Detailed description of exactly how a RenderContextImpl should bind its // buffers and draw a flush. A typical flush is done in 4 steps: // @@ -1043,20 +1265,42 @@ struct FlushDescriptor RenderTarget* renderTarget = nullptr; ShaderFeatures combinedShaderFeatures = ShaderFeatures::NONE; InterlockMode interlockMode = InterlockMode::rasterOrdering; - // Atomic mode only: there a no advanced blend modes, so we can render - // directly to the main target with fixed function (src-over) blending. - bool atomicFixedFunctionColorOutput = false; int msaaSampleCount = 0; // (0 unless interlockMode is msaa.) LoadAction colorLoadAction = LoadAction::clear; ColorInt colorClearValue = 0; // When loadAction == LoadAction::clear. uint32_t coverageClearValue = 0; float depthClearValue = DEPTH_MAX; - ColorInt stencilClearValue = STENCIL_CLEAR; + uint8_t stencilClearValue = STENCIL_CLEAR; IAABB renderTargetUpdateBounds; // drawBounds, or renderTargetBounds if // loadAction == LoadAction::clear. + // If nonzero, frames are split up into virtual tiles of this size. + // + // As of now, each tile gets drawn in a separate render pass. The purpose of + // these virtual tiles, for now, is to break the frame up into smaller + // chunks so that Rive can be pre-empted by other rendering processes. This + // is only supported on Vulkan/non-msaa. + // + // TODO: We could also explore a different type of virtual tiling that + // reduces barriers in atomic mode, but that is not how this feature works + // currently. + uint32_t virtualTileWidth = 0; + uint32_t virtualTileHeight = 0; + + // True if the drawList ends with a "renderPassResolve" draw, in which case + // the backend may need to perform special setup for a custom resolve. + bool manuallyResolved = false; + + // True if shaders will never read the color buffer, meaning, the render + // pass can use a more efficient setup that renders to a standard color + // attachment and handles all blending via built-in blend state. + // NOTE: This may be false even if all paints use srcOver because some + // rendering modes (e.g., rasterOrdering with evenOdd/nonZero) always read + // the color buffer, regardless of blend mode. + bool fixedFunctionColorOutput = false; + // Physical size of the atlas texture. uint16_t atlasTextureWidth; uint16_t atlasTextureHeight; @@ -1098,12 +1342,14 @@ struct FlushDescriptor bool clockwiseFillOverride = false; bool hasTriangleVertices = false; bool wireframe = false; + DitherMode ditherMode; #ifdef WITH_RIVE_TOOLS // Synthesize compilation failures to make sure the device handles them // gracefully. (e.g., by falling back on an uber shader or at least not // crashing.) Valid compilations may fail in the real world if the device is // pressed for resources or in a bad state. - bool synthesizeCompilationFailures = false; + SynthesizedFailureType synthesizedFailureType = + SynthesizedFailureType::none; #endif // Command buffer that rendering commands will be added to. @@ -1125,6 +1371,13 @@ struct FlushDescriptor // List of draws in the main render pass. These are rendered directly to the // renderTarget. const BlockAllocatedLinkedList* drawList = nullptr; + const DrawBatch* firstDstBlendBarrier = nullptr; + + // This tracks any barriers that will not be handled by DrawBatches (e.g., + // renderpass-specific barriers that won't be handled because the batch list + // is empty). The backend may need to issue these barriers before finishing + // the render pass. + BarrierFlags unresolvedBarriers = BarrierFlags::none; }; // Returns the area of the (potentially non-rectangular) quadrilateral that @@ -1201,12 +1454,27 @@ struct FlushUniforms // significant "32 - CLOCKWISE_COVERAGE_BIT_COUNT" bits of coverage buffer // values. (clockwiseAtomic mode only.) WRITEONLY uint32_t m_coverageBufferPrefix; + // GLSL doesn't appear to provide a lightweight, region-local barrier for + // memory ordering outside of memoryBarrier*(), which have severe + // consequences for tiling. When we are already relying on other API level + // barriers and only need to guard against instruction reordering, we can + // multiply by a tiny epsilon instead, and introduce artifical dependencies + // that enforce ordering but don't actually have an effect on the final + // outcome. + WRITEONLY float m_epsilonForPseudoMemoryBarrier; // Spacing between adjacent path IDs (1 if IEEE compliant). WRITEONLY uint32_t m_pathIDGranularity; WRITEONLY float m_vertexDiscardValue; + WRITEONLY float m_mipMapLODBias; + WRITEONLY uint32_t m_maxPathId; + WRITEONLY float m_ditherScale; + WRITEONLY float m_ditherBias; + // Amount by which to multiply a computed dither value when storing as + // RGB10 (as opposed to writing it out to the framebuffer). + WRITEONLY float m_ditherConversionToRGB10; WRITEONLY uint32_t m_wireframeEnabled; // Forces coverage to solid. // Uniform blocks must be multiples of 256 bytes in size. - WRITEONLY uint8_t m_padTo256Bytes[256 - 80]; + WRITEONLY uint8_t m_padTo256Bytes[256 - 104]; }; static_assert(sizeof(FlushUniforms) == 256); @@ -1471,11 +1739,11 @@ size_t StorageTextureBufferSize(size_t bufferSizeInBytes, // winding, or both? enum class WindingFaces { + none = 0, negative = 1 << 0, positive = 1 << 1, all = negative | positive, }; -RIVE_MAKE_ENUM_BITSET(WindingFaces) // Represents a block of mapped GPU memory. Since it can be extremely expensive // to read mapped memory, we use this class to enforce the write-only nature of @@ -1500,13 +1768,19 @@ template class WriteOnlyMappedMemory using MapResourceBufferFn = void* (RenderContextImpl::*)(size_t mapSizeInBytes); - void mapElements(RenderContextImpl* impl, - MapResourceBufferFn mapFn, - size_t elementCount) + [[nodiscard]] bool mapElements(RenderContextImpl* impl, + MapResourceBufferFn mapFn, + size_t elementCount) { assert(m_mappedMemory == nullptr); void* ptr = (impl->*mapFn)(elementCount * sizeof(T)); + if (ptr == nullptr) + { + return false; + } + reset(reinterpret_cast(ptr), elementCount); + return true; } using UnmapResourceBufferFn = @@ -1515,10 +1789,12 @@ template class WriteOnlyMappedMemory UnmapResourceBufferFn unmapFn, size_t elementCount) { - assert(m_mappedMemory != nullptr); - assert(m_mappingEnd - m_mappedMemory == elementCount); - (impl->*unmapFn)(elementCount * sizeof(T)); - reset(); + if (m_mappedMemory != nullptr) + { + assert(m_mappingEnd - m_mappedMemory == elementCount); + (impl->*unmapFn)(elementCount * sizeof(T)); + reset(); + } } operator bool() const { return m_mappedMemory; } @@ -1609,10 +1885,10 @@ enum class StencilCompareOp : uint8_t struct StencilFaceOps { - StencilOp failOp; - StencilOp passOp; - StencilOp depthFailOp; - StencilCompareOp compareOp; + StencilOp failOp = StencilOp::keep; + StencilOp passOp = StencilOp::keep; + StencilOp depthFailOp = StencilOp::keep; + StencilCompareOp compareOp = StencilCompareOp::always; }; enum class CullFace : uint8_t @@ -1622,6 +1898,8 @@ enum class CullFace : uint8_t counterclockwise, }; +constexpr uint32_t CULL_FACE_BIT_COUNT = 2; + // Blend equation to select for the fixed-function GPU pipeline (not our own // in-shader blending). For now, the backend is free to decide whether it will // use premultiplied alpha or not. @@ -1633,7 +1911,8 @@ enum class BlendEquation : uint8_t // Core hardware blend equations supported on all platforms. srcOver = static_cast(rive::BlendMode::srcOver), plus = srcOver + 1, - max = plus + 1, + min = srcOver + 2, + max = srcOver + 3, // "Advanced" hardware blend equations. // PlatformFeatures::supportsKHRBlendEquations is required. @@ -1654,57 +1933,93 @@ enum class BlendEquation : uint8_t luminosity = static_cast(rive::BlendMode::luminosity), }; -// Common pipeline state that applies to every low-level draw and every backend. -struct PipelineState +struct DepthState { bool depthTestEnabled; bool depthWriteEnabled; - bool stencilTestEnabled; - bool stencilDoubleSided; - uint8_t stencilCompareMask; - uint8_t stencilWriteMask; - uint8_t stencilReference; +}; + +DepthState get_depth_state(InterlockMode interlockMode, + DrawType drawType, + DrawContents drawContents); + +CullFace get_cull_face(DrawType drawType); +bool get_color_write_enable(DrawType drawType, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + bool fixedFunctionColorOutput, + DrawContents drawContents); + +// Common pipeline state that applies to every Rive draw and every backend. +struct PipelineState +{ + // Depth. + bool depthTestEnabled = false; + bool depthWriteEnabled = true; + + // Stencil. + bool stencilTestEnabled = false; + uint8_t stencilCompareMask = 0xff; + uint8_t stencilWriteMask = 0xff; + uint8_t stencilReference = 0; StencilFaceOps stencilFrontOps; StencilFaceOps stencilBackOps; - CullFace cullFace; - BlendEquation blendEquation; - bool colorWriteEnabled; + bool stencilDoubleSided = false; // Use stencilFrontOps for both faces? + + CullFace cullFace = CullFace::none; + BlendEquation blendEquation = BlendEquation::none; + bool colorWriteEnabled = true; }; +// Returns a unique value that can be used to key a whole pipeline. +uint64_t pipeline_unique_key(DrawType, + ShaderFeatures, + InterlockMode, + ShaderMiscFlags, + DrawContents, + bool fixedFunctionColorOutput, + rive::BlendMode, + const PlatformFeatures&); + +PipelineState get_pipeline_state(DrawType, + InterlockMode, + ShaderMiscFlags, + DrawContents, + bool fixedFunctionColorOutput, + rive::BlendMode, + const PlatformFeatures&); + void get_pipeline_state(const DrawBatch&, const FlushDescriptor&, const PlatformFeatures&, PipelineState*); -constexpr static PipelineState COLOR_ONLY_PIPELINE_STATE = { - .depthTestEnabled = false, - .depthWriteEnabled = false, - .stencilTestEnabled = false, - .stencilWriteMask = 0, - .cullFace = CullFace::none, - .blendEquation = BlendEquation::none, - .colorWriteEnabled = true, -}; +// Default PipelineState values as specified in OpenGL. +constexpr static PipelineState GL_DEFAULT_PIPELINE_STATE = {}; -constexpr static PipelineState ATLAS_FILL_PIPELINE_STATE = { - .depthTestEnabled = false, - .depthWriteEnabled = false, - .stencilTestEnabled = false, - .stencilWriteMask = 0, - .cullFace = CullFace::counterclockwise, - .blendEquation = BlendEquation::plus, - .colorWriteEnabled = true, -}; +// Helper to create PipelineState with no depth/stencil and custom blend/cull. +constexpr inline PipelineState make_flat_pipeline_state(CullFace cull, + BlendEquation blend) +{ + PipelineState s{}; + s.depthTestEnabled = false; + s.depthWriteEnabled = false; + s.stencilTestEnabled = false; + s.stencilWriteMask = 0; + s.cullFace = cull; + s.blendEquation = blend; + s.colorWriteEnabled = true; + return s; +} -constexpr static PipelineState ATLAS_STROKE_PIPELINE_STATE = { - .depthTestEnabled = false, - .depthWriteEnabled = false, - .stencilTestEnabled = false, - .stencilWriteMask = 0, - .cullFace = CullFace::counterclockwise, - .blendEquation = BlendEquation::max, - .colorWriteEnabled = true, -}; +constexpr static PipelineState COLOR_ONLY_PIPELINE_STATE = + make_flat_pipeline_state(CullFace::none, BlendEquation::none); + +constexpr static PipelineState ATLAS_FILL_PIPELINE_STATE = + make_flat_pipeline_state(CullFace::none, BlendEquation::plus); + +constexpr static PipelineState ATLAS_STROKE_PIPELINE_STATE = + make_flat_pipeline_state(CullFace::counterclockwise, BlendEquation::max); float4 cast_f16_to_f32(uint16x4 x); uint16x4 cast_f32_to_f16(float4); @@ -1718,7 +2033,7 @@ extern const uint16_t g_inverseGaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE]; // Code to generate g_gaussianIntegralTableF16 and // g_inverseGaussianIntegralTableF32. This is left in the codebase but #ifdef'd // out in case we ever want to change any parameters of the built-in tables. -#if 0 +#ifdef RIVE_GENERATE_FEATHER_LUT void generate_gausian_integral_table(float (&)[GAUSSIAN_TABLE_SIZE]); void generate_inverse_gausian_integral_table(float (&)[GAUSSIAN_TABLE_SIZE]); #endif diff --git a/thirdparty/rive_renderer/include/rive/renderer/gpu_resource.hpp b/thirdparty/rive_renderer/include/rive/renderer/gpu_resource.hpp index 23bcf41c0..5fc3c651a 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/gpu_resource.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/gpu_resource.hpp @@ -19,6 +19,11 @@ class GPUResource : public RefCnt public: virtual ~GPUResource(); + // GPUResource classes should default to non-copyable (they're typically + // going to contain handles that would get double-freed if copied) + GPUResource(const GPUResource&) = delete; + GPUResource& operator=(const GPUResource&) = delete; + GPUResourceManager* manager() const { return m_manager.get(); } protected: diff --git a/thirdparty/rive_renderer/include/rive/renderer/metal/render_context_metal_impl.h b/thirdparty/rive_renderer/include/rive/renderer/metal/render_context_metal_impl.h index 01ca28cb9..1111fc903 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/metal/render_context_metal_impl.h +++ b/thirdparty/rive_renderer/include/rive/renderer/metal/render_context_metal_impl.h @@ -94,12 +94,18 @@ class RenderContextMetalImpl : public RenderContextHelperImpl // Wait for shaders to compile inline with rendering (causing jank), // instead of compiling asynchronously in a background thread. // (Primarily for testing.) - bool synchronousShaderCompilations = false; + ShaderCompilationMode shaderCompilationMode = + ShaderCompilationMode::standard; // (macOS only -- ignored on iOS). Override // m_platformFeatures.supportsRasterOrdering to false, forcing us to // always render in atomic mode. bool disableFramebufferReads = false; + +#ifdef WITH_RIVE_TOOLS + SynthesizedFailureType synthesizedFailureType = + SynthesizedFailureType::none; +#endif }; static std::unique_ptr MakeContext(id, @@ -114,6 +120,13 @@ class RenderContextMetalImpl : public RenderContextHelperImpl id gpu() const { return m_gpu; } + // Set the command queue used by makeCommandBuffer(). Must be called + // before any ScriptedCanvas flush if canvas support is needed. + void setCommandQueue(id queue) { m_commandQueue = queue; } + + void* makeCommandBuffer() override; + void commitCommandBuffer(void* commandBuffer) override; + rcp makeRenderTarget(MTLPixelFormat, uint32_t width, uint32_t height); @@ -125,8 +138,14 @@ class RenderContextMetalImpl : public RenderContextHelperImpl rcp makeImageTexture(uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) override; +#ifdef RIVE_CANVAS + rcp makeRenderCanvas(uint32_t width, + uint32_t height) override; +#endif + // Atomic mode requires a barrier between overlapping draws. We have to // implement this barrier in various different ways, depending on which // hardware we're on. @@ -203,6 +222,7 @@ class RenderContextMetalImpl : public RenderContextHelperImpl const ContextOptions m_contextOptions; const id m_gpu; + id m_commandQueue = nil; MetalFeatures m_metalFeatures; std::unique_ptr m_backgroundShaderCompiler; diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group.hpp new file mode 100644 index 000000000..28990154a --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group.hpp @@ -0,0 +1,277 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" + +#include + +#if defined(ORE_BACKEND_METAL) +#import +#endif +#if defined(ORE_BACKEND_D3D11) +#include +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +#endif + +namespace rive::ore +{ + +class Context; + +// Pre-baked resource bindings that can be reused across many draw calls. +// Holds strong rcp<> references to all bound resources (Buffer, TextureView, +// Sampler), ensuring they remain alive for the BindGroup's lifetime. +// +// Created via Context::makeBindGroup(). Bound via RenderPass::setBindGroup(). +class BindGroup : public RefCnt +{ +public: + uint32_t dynamicOffsetCount() const { return m_dynamicOffsetCount; } + uint32_t groupIndex() const + { + return m_layoutRef ? m_layoutRef->groupIndex() : 0; + } + BindGroupLayout* layout() const { return m_layoutRef.get(); } + Context* context() const { return m_context; } + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class RenderPass; + + BindGroup() = default; + + uint32_t m_dynamicOffsetCount = 0; + + // The layout this BindGroup conforms to. Holds the per-backend native + // layout handle alive for the BindGroup's lifetime — Vulkan's + // VkDescriptorSetLayout in particular must outlive every VkDescriptorSet + // allocated from it. Replaces the prior `m_vkPipelineRef` (which kept + // the layout alive transitively via the pipeline). + rcp m_layoutRef; + + // Lifecycle: hold rcp<> refs to all bound resources so they stay alive + // even if the caller drops their references before the BindGroup is + // destroyed. + std::vector> m_retainedBuffers; + std::vector> m_retainedViews; + std::vector> m_retainedSamplers; + + // Context back-pointer set in makeBindGroup(). Used by the Lua GC + // to call context->deferBindGroupDestroy() instead of dropping the + // last rcp<> directly, keeping the object alive until endFrame(). + Context* m_context = nullptr; + + // Vulkan: VkDescriptorSetLayout lifetime is governed by `m_layoutRef` + // above (the BindGroupLayout owns the DSL handle). The descriptor set + // is allocated from Context's persistent pool at makeBindGroup time. +#if defined(ORE_BACKEND_VK) + VkDescriptorSet m_vkDescriptorSet = VK_NULL_HANDLE; +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::BindGroup m_wgpuBindGroup; + // wgpu handles are internally ref-counted; no extra Pipeline ref needed. +#endif +#if defined(ORE_BACKEND_D3D12) + // Descriptors pre-copied to CPU heap at makeBindGroup() time. + // Copied to GPU heap at setBindGroup() time. + // + // Arrays are indexed by SLOT (0-7, matching the shader's `register(t/s/b)` + // index), not by insertion order. Unbound slots have their bit cleared in + // the corresponding *SlotMask; setBindGroup() fills them with null + // descriptors so the root-signature-declared 8-slot tables are fully + // populated. Storing by slot is essential: the root sig's SRV and sampler + // descriptor tables assume GPU-heap slot == shader register, so packing by + // insertion order (the prior layout) silently read from wrong slots when + // the script used a non-dense binding layout. + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dSrvHandles[8] = {}; + // Weak refs to the underlying textures bound at each SRV slot. Used by + // `d3d12ApplyBindGroup` to insert a state-transition barrier when the + // texture isn't already in a shader-resource state (e.g. a + // depth-stencil texture born in `DEPTH_WRITE` and never attached to a + // render pass — the GBV `id=1358 Incompatible texture barrier + // layout` case the `ore_binding_shadow_sampler_d32` GM hits). + // `m_retainedViews` keeps the views alive; the textures are owned by + // those views, so the raw pointers here are safe for the BindGroup's + // lifetime. + Texture* m_d3dSrvTextures[8] = {}; + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dSamplerHandles[8] = {}; + D3D12_GPU_VIRTUAL_ADDRESS m_d3dUBOAddresses[8] = {}; + // UBO byte sizes per slot. Used by `setBindGroup` to create CBV + // descriptors on-the-fly into the shader-visible heap (D3D12 CBVs + // live inside the merged CBV/SRV/UAV descriptor table). + uint32_t m_d3dUBOSizes[8] = {}; + uint8_t m_d3dSrvSlotMask = 0; // bit i = slot i has a bound SRV + uint8_t m_d3dSamplerSlotMask = 0; // bit i = slot i has a bound sampler + uint8_t m_d3dUBOSlotMask = 0; // bit i = slot i has a bound UBO + // bit i = slot i's UBO has hasDynamicOffset=true. setBindGroup() consumes + // one entry from dynamicOffsets[] per set bit, in ascending slot order. + uint8_t m_d3dUBODynamicOffsetMask = 0; +#endif +#if defined(ORE_BACKEND_METAL) + // Metal: flat resource arrays applied at setBindGroup time. + // + // Per-stage Metal slots are stored independently per resource: Metal + // has separate VS / FS argument tables, and the allocator is free to + // assign different per-stage slots, so VS-only UBO A and FS-only UBO B + // can share Metal slot 0 in their own stages. Each `*Slot` is + // `BindingMap::kAbsent` when the binding isn't visible to that stage; + // setBindGroup then skips the per-stage emit instead of forwarding `0` + // (which would clobber another resource's slot). + // + // `binding` carries the WGSL `@binding` value, used as the sort key + // for dynamic-offset ordering: WebGPU requires `dynamicOffsets[i]` to + // be consumed in BindGroupLayout entry order, which is ascending + // `@binding` within a kind. Sorting at construction time makes the + // BindGroup robust to callers who pass `desc.ubos[]` in any order. + struct MTLBufferBinding + { + id buffer = nil; + uint32_t offset = 0; + uint32_t binding = 0; // WGSL @binding — sort key for dynamicOffsets[]. + uint16_t vsSlot = 0xFFFF; // BindingMap::kAbsent. + uint16_t fsSlot = 0xFFFF; + // Populated from `BindGroupLayout::hasDynamicOffset(binding)` at + // makeBindGroup time. setBindGroup consumes one `dynamicOffsets[]` + // entry per `hasDynamicOffset=true` UBO in `binding`-ascending order. + bool hasDynamicOffset = false; + }; + struct MTLTextureBinding + { + id texture = nil; + uint16_t vsSlot = 0xFFFF; + uint16_t fsSlot = 0xFFFF; + }; + struct MTLSamplerBinding + { + id sampler = nil; + uint16_t vsSlot = 0xFFFF; + uint16_t fsSlot = 0xFFFF; + }; + std::vector m_mtlBuffers; + std::vector m_mtlTextures; + std::vector m_mtlSamplers; +#endif +#if defined(ORE_BACKEND_GL) + // GL: single slot per binding (GL has a flat global namespace across + // stages, no per-stage register split). `binding` carries the WGSL + // `@binding` value, used as the sort key for dynamic-offset ordering + // (consumed in BindGroupLayout-entry order regardless of the + // caller-supplied `desc.ubos[]` shape). + struct GLUBOBinding + { + unsigned int buffer = 0; + uint32_t offset = 0; + uint32_t size = 0; + uint32_t binding = 0; // WGSL @binding — sort key for dynamicOffsets[]. + uint32_t slot = 0; // GL binding point (allocator's global slot). + // Populated from `BindGroupLayout::hasDynamicOffset(binding)` at + // makeBindGroup time. setBindGroup consumes one `dynamicOffsets[]` + // entry per `hasDynamicOffset=true` UBO in `binding`-ascending order. + bool hasDynamicOffset = false; + }; + struct GLTexBinding + { + unsigned int texture = 0; + unsigned int target = 0; + uint32_t slot = 0; + }; + struct GLSamplerBinding + { + unsigned int sampler = 0; + uint32_t slot = 0; + }; + std::vector m_glUBOs; + std::vector m_glTextures; + std::vector m_glSamplers; +#endif +#if defined(ORE_BACKEND_D3D11) + // D3D11: store resource pointers + per-stage register slots. + // + // D3D11 has independent VS / PS register namespaces (`b0` in VS is a + // different register than `b0` in PS). The allocator is free to assign + // different per-stage register numbers, so VS-only and PS-only + // resources can share register 0 in their own stages. Each `*Slot` is + // `BindingMap::kAbsent` when the binding isn't visible to that stage; + // setBindGroup then skips the per-stage `VSSet*` / `PSSet*` call so + // we don't overwrite another resource's slot. + // + // `binding` carries the WGSL `@binding` value, used as the sort key + // for dynamic-offset ordering (same shape as the Metal binding) so + // `dynamicOffsets[]` consumption matches BindGroupLayout-entry + // order regardless of caller-supplied `desc.ubos[]` shape. + // + // `offset`/`size` are in bytes; applied via VSSetConstantBuffers1 / + // PSSetConstantBuffers1 (which take firstConstant / numConstants in + // 16-byte units — D3D11 requires 256-byte alignment ≡ 16 constants). + struct D3D11UBOBinding + { + ID3D11Buffer* buffer = nullptr; // Weak ref; rcp held in + // m_retainedBuffers. + uint32_t binding = 0; // WGSL @binding — sort key for dynamicOffsets[]. + uint16_t vsSlot = 0xFFFF; // BindingMap::kAbsent. + uint16_t psSlot = 0xFFFF; + uint32_t offset = 0; + uint32_t size = 0; + // Populated from `BindGroupLayout::hasDynamicOffset(binding)` at + // makeBindGroup time. setBindGroup consumes one `dynamicOffsets[]` + // entry per `hasDynamicOffset=true` UBO in `binding`-ascending order. + bool hasDynamicOffset = false; + }; + struct D3D11TexBinding + { + ID3D11ShaderResourceView* srv = nullptr; // Weak ref. + uint16_t vsSlot = 0xFFFF; + uint16_t psSlot = 0xFFFF; + }; + struct D3D11SamplerBinding + { + ID3D11SamplerState* sampler = nullptr; // Weak ref. + uint16_t vsSlot = 0xFFFF; + uint16_t psSlot = 0xFFFF; + }; + std::vector m_d3d11UBOs; + std::vector m_d3d11Textures; + std::vector m_d3d11Samplers; +#endif + +public: + void onRefCntReachedZero() const; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group_layout.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group_layout.hpp new file mode 100644 index 000000000..30a85819c --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_bind_group_layout.hpp @@ -0,0 +1,167 @@ +/* + * Copyright 2026 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" +#include "rive/renderer/ore/ore_binding_map.hpp" + +#include +#include + +// Only the backends that store a native handle on `BindGroupLayout` need +// their headers here. Metal / D3D11 / GL keep entries-only layouts (no +// native handle), so their backend headers are NOT pulled in — that lets +// the cross-backend `ore_bind_group_layout.cpp` compile as plain C++. +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +#endif + +namespace rive::ore +{ + +class Context; + +#if defined(ORE_BACKEND_D3D12) +// Per-group root-parameter metadata for D3D12. Moved from `Pipeline` (where +// it was historically derived from the binding map at pipeline build time) +// onto `BindGroupLayout` so multiple pipelines that share a layout produce +// the same per-group descriptor-table shape. The composing root signature +// is still per-pipeline (D3D12 root sigs are cross-group). +struct D3D12GroupRootParams +{ + int8_t cbvSrvUavRootParamIdx = -1; + int8_t samplerRootParamIdx = -1; + uint8_t cbvCount = 0; + uint8_t srvCount = 0; + uint8_t uavCount = 0; + uint8_t samplerCount = 0; + uint8_t cbvBaseGlobalSlot = 0; + uint8_t srvBaseGlobalSlot = 0; + uint8_t uavBaseGlobalSlot = 0; + uint8_t samplerBaseGlobalSlot = 0; +}; +#endif + +// Public Ore type — created via `Context::makeBindGroupLayout`. Carries the +// user-supplied entries plus per-backend baked layout handles. +// +// Lifetime: outlives any `Pipeline` or `BindGroup` that references it. +// `Pipeline` holds `rcp m_layouts[kMaxBindGroups]`; +// `BindGroup` holds `rcp m_layoutRef`. Vulkan's +// `vkDestroyDescriptorSetLayout` runs only after the last consumer drops. +class BindGroupLayout : public RefCnt +{ +public: + uint32_t groupIndex() const { return m_groupIndex; } + const std::vector& entries() const + { + return m_entries; + } + +#if defined(ORE_BACKEND_D3D12) + // D3D12-only: per-group descriptor-table shape (counts + base global + // slots). Read by `buildPerPipelineRootSig` to compose the root sig. + const D3D12GroupRootParams& d3dGroupParams() const + { + return m_d3dGroupParams; + } +#endif + + // True if entry for `binding` (within this layout's group) is a UBO + // declared with `hasDynamicOffset = true`. Replaces + // `Pipeline::isDynamicUBO()`. Each backend's BindGroup caches this at + // makeBindGroup time per-slot to know when to consume from + // `dynamicOffsets[]` at setBindGroup time. + bool hasDynamicOffset(uint32_t binding) const; + + // Find the entry for a given binding. Returns nullptr if not present. + const BindGroupLayoutEntry* findEntry(uint32_t binding) const; + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + + BindGroupLayout() = default; + + uint32_t m_groupIndex = 0; + std::vector m_entries; + + // Context back-pointer for deferred-destruction routing through + // Context::vkDeferDestroy / d3dDeferDestroy. Weak ref. + Context* m_context = nullptr; + +#if defined(ORE_BACKEND_VK) + VkDevice m_vkDevice = VK_NULL_HANDLE; + VkDescriptorSetLayout m_vkDSL = VK_NULL_HANDLE; + PFN_vkDestroyDescriptorSetLayout m_vkDestroyDescriptorSetLayout = nullptr; +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::BindGroupLayout m_wgpuBGL; +#endif +#if defined(ORE_BACKEND_D3D12) + D3D12GroupRootParams m_d3dGroupParams; +#endif + // Metal / D3D11 / GL / D3D12-bind-side: the user-supplied entries above + // plus shader-resolved native slots per-stage are sufficient to drive + // makeBindGroup for those backends. Slots are looked up via the + // pipeline's BindingMap at makeBindGroup time and validated against + // this layout at makePipeline time. + +public: + void onRefCntReachedZero() const; +}; + +// Validate user-supplied layouts against the shader's reflected binding map. +// +// Walks every entry in `bindingMap` and confirms the layout for that group +// declares a matching entry: same WGSL @binding, kind, visibility >= +// shader's stageMask, texture dim/sample type compatible. +// +// Returns true on success. On failure, populates `*outError` with a human- +// readable diagnostic (e.g. "@group(1) @binding(0): layout declares +// uniformBuffer but shader expects sampledTexture") and returns false. Never +// asserts. +// +// Called by every backend's `makePipeline` after the user-supplied layouts +// have been collected, before any backend-specific build work. +bool validateLayoutsAgainstBindingMap(const BindingMap& bindingMap, + BindGroupLayout* const* layouts, + uint32_t layoutCount, + std::string* outError); + +// Color outputs require a fragment shader. Mirrors Dawn's +// ValidateRenderPipelineDescriptor invariant. Depth-only pipelines +// (colorCount == 0) may legitimately omit the fragment module — the +// rasterizer still writes depth. +bool validateColorRequiresFragment(uint32_t colorCount, + bool hasFragmentModule, + std::string* outError); + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_binding_map.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_binding_map.hpp new file mode 100644 index 000000000..76a20c381 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_binding_map.hpp @@ -0,0 +1,317 @@ +/* + * Copyright 2026 Rive + */ + +#pragma once + +// Portable C++ binding map matching the on-disk RSTB schema. Runtime +// parses one of these out of an RSTB sidecar via `fromBlob`; the +// editor-side toolchain produces the blob via `toBlob`. +// +// Usage pattern: +// ore::BindingMap bm; +// ore::BindingMap::fromBlob(bytes, size, &bm); +// uint32_t metalSlot = bm.lookup(group, binding, +// ore::ResourceKind::UniformBuffer, +// ore::BindingMap::Stage::VS); +// +// BindingMap is owned by `ore::Pipeline` — populated at pipeline creation +// from the RSTB sidecar, consumed by each flatten backend's +// `makeBindGroup`. Vulkan/WebGPU construct it for reflection parity but +// never read it at bind time. + +#include +#include +#include +#include +#include + +namespace rive::ore +{ + +// ---------------------------------------------------------------------------- +// Reserved native slots +// +// Ore reserves a small number of native slots in each backend's slot +// namespace for its own internal machinery (push-constant emulation, +// dynamic-sized storage-buffer length arrays). The binding-map +// allocator must never hand out a user binding at one of these slots, even +// though no current Ore feature consumes them — they are forward-compat +// scaffolding so that adding push constants or compute storage buffers +// later cannot collide with a slot a user shader has already allocated. +// +// Values must agree with the RSTB-emit path in scripting_workspace. +// ---------------------------------------------------------------------------- + +// Metal `[[buffer(30)]]` reservation. Metal's hardware buffer table is 31 +// slots (`MTLBufferTableSize`); reserving the topmost matches Dawn's MSL +// backend convention (`kImmediateBlockBufferSlot`). Targets: +// 1. Push-constant emulation (Vulkan native, D3D12 root constants — Metal +// has no equivalent, must be emulated as a buffer bind). +// 2. Sizes buffer for dynamic-sized storage-buffer `arrayLength()` +// lookups (compute path, currently disabled — see +// `Features::storageBuffers`). +constexpr uint32_t kMetalReservedBufferSlot = 30; + +// Maximum buffer slot the binding-map allocator may assign to a user +// binding on Metal. Allocator stops at this; overflow is a hard error. +constexpr uint32_t kMetalMaxUserBufferSlot = kMetalReservedBufferSlot - 1; + +// ---------------------------------------------------------------------------- +// ResourceKind +// +// Numeric values are the frozen on-disk RSTB schema. Never renumber +// existing variants; new variants append at the next integer. +// ---------------------------------------------------------------------------- + +enum class ResourceKind : uint8_t +{ + UniformBuffer = 0, + StorageBufferRO = 1, + StorageBufferRW = 2, + SampledTexture = 3, + StorageTexture = 4, + Sampler = 5, + ComparisonSampler = 6, +}; + +// ---------------------------------------------------------------------------- +// TextureViewDim / TextureSampleType +// +// Mirror Dawn's `wgpu::TextureViewDimension` and `wgpu::TextureSampleType` +// (matching numeric values) so the WebGPU backend can cast straight into +// the Dawn enums when building `BindGroupLayoutEntry.texture`. The values +// are what Dawn's frontend validator compares against the shader's reflected +// `BindingInfo` (see `ValidateCompatibilityOfSingleBindingWithLayout` in +// Dawn's `ShaderModule.cpp`). +// +// Carried per-entry in `BindingMap::Entry` for every backend — non-WebGPU +// backends ignore these fields since VK/D3D/Metal descriptor types are +// dimension-agnostic. +// +// Numeric values are frozen on-disk RSTB schema. +// ---------------------------------------------------------------------------- + +enum class TextureViewDim : uint8_t +{ + Undefined = 0, + D1 = 1, + D2 = 2, + D2Array = 3, + Cube = 4, + CubeArray = 5, + D3 = 6, +}; + +enum class TextureSampleType : uint8_t +{ + Undefined = 0, + Float = 1, + UnfilterableFloat = 2, + Depth = 3, + Sint = 4, + Uint = 5, +}; + +// ---------------------------------------------------------------------------- +// BindingMap +// ---------------------------------------------------------------------------- + +class BindingMap +{ +public: + // Shader stage index for per-stage slot lookup. Order matches the + // fixed-width per-stage backend-slot fields in the on-disk RSTB row. + enum class Stage : uint8_t + { + VS = 0, + FS = 1, + CS = 2, + }; + + // Stage bitmask bits, frozen RSTB schema. + static constexpr uint32_t kStageVertex = 1u << 0; + static constexpr uint32_t kStageFragment = 1u << 1; + static constexpr uint32_t kStageCompute = 1u << 2; + + // Sentinel for a per-stage slot that the resource is not visible to. + // The 16-bit width fits every real slot on every backend + // (Metal: 31, D3D11: 128, GL: ~64). + static constexpr uint16_t kAbsent = UINT16_MAX; + + // RSTB blob version byte. Bumped when the on-disk schema changes in a + // way that renders old blobs unreadable. A mismatch on load is a loud + // error, never a silent misbind. + static constexpr uint8_t kBlobVersion = 2; + + // Allocator version currently supported. Pipelines load with this + // value; any blob stamped with a different version fails `fromBlob` + // with a clear error. + // + // WebGPU-aligned global-counter-per-kind allocation. + static constexpr uint8_t kAllocatorVersion = 1; + + // One row of the binding map. Layout matches the on-disk RSTB row + // but packed tighter (fewer bits where the semantics allow). + struct Entry + { + uint8_t group; + uint8_t binding; + ResourceKind kind; + uint8_t stageMask; // Bitwise-OR of kStage* bits. + uint8_t backendSpace; // D3D12 register space / Vulkan set = group. + uint16_t backendSlot[3] = {kAbsent, kAbsent, kAbsent}; // [VS, FS, CS] + // Texture reflection — populated for SampledTexture / + // StorageTexture kinds; `Undefined` / `false` elsewhere. Consumed + // by the WebGPU backend's BGL builder to feed Dawn's frontend + // shader-vs-layout compatibility check. Ignored by VK / D3D / + // Metal which bind textures via dimension-agnostic descriptors. + TextureViewDim textureViewDim = TextureViewDim::Undefined; + TextureSampleType textureSampleType = TextureSampleType::Undefined; + bool textureMultisampled = false; + }; + + BindingMap() = default; + + // Parse a blob produced by `toBlob` (or by the RSTB-emit path in + // scripting_workspace). Returns a populated `BindingMap` + `true` on + // success; empty map + `false` on any size/version mismatch. The + // caller is expected to surface a clear error on failure — never + // fall back to a different layout silently. + // + // First two bytes of the blob are `kBlobVersion` and + // `kAllocatorVersion`; mismatch either and parse fails loudly. + // Serialization (`toBlob`) lives in the tooling-gated portion of the API. + static bool fromBlob(const uint8_t* data, size_t size, BindingMap* out); + + // Per-stage backend-slot lookup. Returns kAbsent when the resource + // is not in the map, or not visible to the requested stage, or the + // map entry's kind doesn't match the caller's expected kind. + // + // `Sampler` and `ComparisonSampler` are treated as interchangeable + // — the runtime binding API (both Luau-facing `GPUSampler` and the + // C++ `BindGroupDesc::SampEntry`) is a single "sampler" category, + // so the caller can't distinguish them at bind time. The allocator + // stores whichever kind was declared in WGSL; this helper accepts + // either side's query. + // + // The single hot path the flatten-backend `makeBindGroup` calls at + // pipeline-binding time. + uint16_t lookup(uint32_t group, + uint32_t binding, + ResourceKind kind, + Stage stage) const + { + const Entry* e = findEntry(group, binding); + if (e == nullptr) + return kAbsent; + const bool kindMatches = + e->kind == kind || + // Collapse sampler / comparison-sampler into one bind-API + // category. See the docstring above for rationale. + ((kind == ResourceKind::Sampler || + kind == ResourceKind::ComparisonSampler) && + (e->kind == ResourceKind::Sampler || + e->kind == ResourceKind::ComparisonSampler)); + if (!kindMatches) + return kAbsent; + const uint32_t stageBit = 1u << static_cast(stage); + if ((e->stageMask & stageBit) == 0) + return kAbsent; + return e->backendSlot[static_cast(stage)]; + } + + size_t size() const { return m_entries.size(); } + bool empty() const { return m_entries.empty(); } + + // Iteration accessor. Used by every flatten backend's layout + // builder at pipeline creation time (Vulkan DSL, D3D12 root sig, + // WebGPU BGL) to walk the map's entries and emit one layout + // entry per binding. Runtime-available because those builders + // ship in non-tooling runtimes (`rive_native` without + // `WITH_RIVE_TOOLS`). + const Entry& at(size_t i) const { return m_entries[i]; } + + // ---------------------------------------------------------------- + // Tooling-only API. Compiled only in builds that define + // WITH_RIVE_TOOLS (editor, scripting_workspace, unit_tests). The + // shipped runtime binary has none of this — no std::sort, no + // serialization, no state flag. + // ---------------------------------------------------------------- +#ifdef WITH_RIVE_TOOLS + // Serialize to the on-disk RSTB sidecar format. Consumed by the + // RSTB emit path in scripting_workspace; mirrored by fromBlob + // which is always available at runtime. + std::vector toBlob() const; + + // Test / tooling construction: push entries in any order, then + // finalize to sort into the canonical (group, binding) order. + void push(const Entry& e) + { + m_entries.push_back(e); + m_finalized = false; + } + + void finalize(); + + bool isFinalized() const { return m_finalized; } + + // Iteration accessor returning the backing vector — tooling-only + // because raw vector access is used by RSTB emit / inspectors + // that may modify via const_cast patterns. Runtime code uses + // `at(i)` + `size()` above. + const std::vector& entries() const { return m_entries; } + + // Slot-unaware lookup for tools that want the full entry. + const Entry* lookupEntry(uint32_t group, uint32_t binding) const + { + return findEntry(group, binding); + } +#endif + +private: + // Internal binary search — not tooling-gated because lookup() uses it + // on the hot runtime path. + const Entry* findEntry(uint32_t group, uint32_t binding) const + { +#ifdef WITH_RIVE_TOOLS + assert(m_finalized && "BindingMap::lookup before finalize"); +#endif + auto it = std::lower_bound( + m_entries.begin(), + m_entries.end(), + std::pair{group, binding}, + [](const Entry& e, const std::pair& key) { + return std::pair{e.group, e.binding} < key; + }); + if (it == m_entries.end() || it->group != group || + it->binding != binding) + { + return nullptr; + } + return &*it; + } + + std::vector m_entries; +#ifdef WITH_RIVE_TOOLS + bool m_finalized = false; +#endif +}; + +// Shared helper for flatten-backend `makeBindGroup` implementations. +// Asserts on missing binding in debug builds; returns kAbsent in release +// so the caller can recover / skip the invalid bind (matches how D3D12 +// handles "slot not set" via its slot-mask bitmap). +inline uint16_t lookupBackendSlot(const BindingMap& map, + uint32_t group, + uint32_t binding, + ResourceKind kind, + BindingMap::Stage stage) +{ + uint16_t slot = map.lookup(group, binding, kind, stage); + assert(slot != BindingMap::kAbsent && + "BindingMap lookup failed for (group, binding, kind, stage)"); + return slot; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_buffer.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_buffer.hpp new file mode 100644 index 000000000..e940f6d8f --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_buffer.hpp @@ -0,0 +1,119 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" + +#if defined(ORE_BACKEND_METAL) +#import +#endif +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// GL object handles are GLuint = unsigned int; no glad needed in the header. +#if defined(ORE_BACKEND_D3D11) +#include +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +VK_DEFINE_HANDLE(VmaAllocator); +VK_DEFINE_HANDLE(VmaAllocation); +#endif + +namespace rive::ore +{ + +class Context; +#if defined(ORE_BACKEND_VK) +class ContextVulkan; +#endif +#if defined(ORE_BACKEND_D3D12) +class ContextD3D12; +#endif + +class Buffer : public RefCnt +{ +public: + uint32_t size() const { return m_size; } + BufferUsage usage() const { return m_usage; } + + void update(const void* data, uint32_t size, uint32_t offset = 0); + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class RenderPass; + + Buffer(uint32_t size, BufferUsage usage) : m_size(size), m_usage(usage) {} + + uint32_t m_size; + BufferUsage m_usage; + +#if defined(ORE_BACKEND_METAL) + id m_mtlBuffer = nil; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glBuffer = 0; + unsigned int m_glTarget = 0; +#endif +#if defined(ORE_BACKEND_D3D11) + Microsoft::WRL::ComPtr m_d3d11Buffer; + ID3D11DeviceContext* m_d3d11Context = + nullptr; // Weak ref, set by Context::makeBuffer. +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::Buffer m_wgpuBuffer; + wgpu::Queue + m_wgpuQueue; // Weak ref (addref'd copy), set by Context::makeBuffer. +#endif +#if defined(ORE_BACKEND_VK) + VkBuffer m_vkBuffer = VK_NULL_HANDLE; + VmaAllocation m_vmaAllocation = VK_NULL_HANDLE; + void* m_vkMappedPtr = nullptr; + VkDevice m_vkDevice = VK_NULL_HANDLE; // Weak ref. + VmaAllocator m_vmaAllocator = VK_NULL_HANDLE; // Weak ref. + // Back-ref so onRefCntReachedZero() can route the vmaDestroyBuffer call + // through ContextVulkan::vkDeferDestroy() in external-CB mode. Weak ref. + ContextVulkan* m_vkOreContext = nullptr; +#endif +#if defined(ORE_BACKEND_D3D12) + // UPLOAD heap — persistently mapped; GPU reads directly (acceptable for + // tests). + Microsoft::WRL::ComPtr m_d3dBuffer; + void* m_d3dMappedPtr = nullptr; + // Back-ref so onRefCntReachedZero() can route the ComPtr release through + // ContextD3D12::d3dDeferDestroy() in external-CL mode. Weak ref. + ContextD3D12* m_d3dOreContext = nullptr; +#endif + +public: + void onRefCntReachedZero() const; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context.hpp new file mode 100644 index 000000000..76094c035 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context.hpp @@ -0,0 +1,274 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" + +namespace rive::gpu +{ +class RenderCanvas; +class Texture; +} // namespace rive::gpu + +namespace rive::ore +{ + +// Backend-agnostic Ore graphics context. +// +// Held only via std::unique_ptr. Concrete subclasses live in +// per-backend headers and own the GPU-API state and dispatch: +// +// ore_context_metal.hpp → ContextMetal::Make(id, +// id) +// ore_context_gl.hpp → ContextGL::Make() +// ore_context_d3d11.hpp → ContextD3D11::Make(ID3D11Device*, +// ID3D11DeviceContext*) +// ore_context_d3d12.hpp → ContextD3D12::Make(ID3D12Device*, +// ID3D12CommandQueue*) +// ore_context_wgpu.hpp → ContextWGPU::Make(wgpu::Device, wgpu::Queue, +// wgpu::BackendType) +// ore_context_vulkan.hpp → ContextVulkan::Make(VkInstance, ..., +// VmaAllocator, +// PFN_vkGetInstanceProcAddr) +// +// Backend-specific public methods (the typed external-CL beginFrame +// overloads, Vulkan render-pass cache lookup, WGPU GLES detection, etc.) +// live on the per-backend subclasses, not on this base — so this header +// pulls in no GPU-API headers and stays free of #ifdef branches. +// +// To call a backend-specific method, hold the subclass type at the call +// site (the subclass `Make` factory returns std::unique_ptr, +// which converts implicitly to std::unique_ptr for cross-backend +// use). Code that only needs the cross-backend API takes Context*. +class Context +{ +public: + virtual ~Context() = default; + + // Resource factories. + virtual rcp makeBuffer(const BufferDesc& desc) = 0; + virtual rcp makeTexture(const TextureDesc& desc) = 0; + virtual rcp makeTextureView(const TextureViewDesc& desc) = 0; + virtual rcp makeSampler(const SamplerDesc& desc) = 0; + virtual rcp makeShaderModule( + const ShaderModuleDesc& desc) = 0; + virtual rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) = 0; + virtual rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) = 0; + virtual rcp makeBindGroup(const BindGroupDesc& desc) = 0; + + virtual RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) = 0; + + // Frame lifecycle (owned-CL form). For external-CL mode, see the + // typed beginFrame overload on the relevant per-backend subclass + // (ContextVulkan::beginFrame(VkCommandBuffer), + // ContextD3D12::beginFrame(ID3D12GraphicsCommandList*), + // ContextWGPU::beginFrame(wgpu::CommandEncoder)). + virtual void beginFrame() = 0; + virtual void endFrame() = 0; + + // Block until the most recent endFrame() submission completes on the + // GPU. Call this before destroying Ore resources (textures, views, + // pipelines) that were used in the current frame. Not needed if + // resources stay alive until the next beginFrame(), which waits + // automatically. + virtual void waitForGPU() = 0; + + virtual rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) = 0; + virtual rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) = 0; + + // ------------------------------------------------------------------------ + // Cross-cutting state and accessors. Non-virtual; live on this base + // because they are uniform across backends. + // ------------------------------------------------------------------------ + + const Features& features() const { return m_features; } + + // Defer destruction of a BindGroup until after the GPU fence in endFrame(). + // Call this instead of dropping the last rcp<> directly — keeps the object + // alive until the GPU is done with any command buffers that reference it. + void deferBindGroupDestroy(rcp bg) + { + m_deferredBindGroups.push_back(std::move(bg)); + } + + // Active render pass tracking — used by Lua bindings to auto-finish + // stale passes and by backends that enforce one-encoder-at-a-time. + RenderPass* activeRenderPass() const { return m_activeRenderPass; } + void setActiveRenderPass(RenderPass* pass) { m_activeRenderPass = pass; } + + // Called at the top of every backend's beginRenderPass(). If a prior pass + // is still open, finish it — matches the Lua binding's auto-finish + // contract and means backends that enforce one-encoder-at-a-time (Metal, + // D3D12) won't assert when a second beginRenderPass happens within the + // same command buffer. Does not clear m_activeRenderPass, because the + // pointer identity is owned by the Lua wrapper that called setActive…(). + inline void finishActiveRenderPass() + { + if (m_activeRenderPass && !m_activeRenderPass->isFinished()) + { + m_activeRenderPass->finish(); + } + } + + // Last validation error — set by setPipeline() / setBindGroup() when + // format or layout checks fail. Cleared at beginFrame(). The Lua layer + // reads this after native calls and fires luaL_error() if non-empty. + const std::string& lastError() const { return m_lastError; } + void clearLastError() { m_lastError.clear(); } + + // Populate m_lastError with a printf-style message. Used by factory + // methods to report construction failures to the Lua layer in lieu of + // fprintf(stderr) / assert — which either spam the console or abort + // the process. + void setLastError(const char* fmt, ...) +#if defined(__GNUC__) || defined(__clang__) + __attribute__((format(printf, 2, 3))) +#endif + { + va_list args; + va_start(args, fmt); + char buf[1024]; + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + m_lastError = buf; + } + + Context(const Context&) = delete; + Context& operator=(const Context&) = delete; + Context(Context&&) = delete; + Context& operator=(Context&&) = delete; + +protected: + Context() = default; + + Features m_features; + + // Non-null while a RenderPass created by this context is still open. + // beginRenderPass() auto-finishes any previous open pass so backends + // that enforce one-encoder-at-a-time (Metal, D3D12) don't assert. + RenderPass* m_activeRenderPass = nullptr; + + // Deferred destruction queues — cleared after endFrame() fence wait. + // The rcp<> keeps objects alive until the GPU is done with them. + std::vector> m_deferredBindGroups; + + // Last validation error from setPipeline() / setBindGroup(). + std::string m_lastError; +}; + +// ============================================================================ +// RenderPass inline helpers — defined here rather than in ore_render_pass.hpp +// because they depend on Pipeline::desc() / TextureView::texture()->format(), +// which are pulled in by this header's full set of Ore includes. +// ============================================================================ + +inline void RenderPass::populateAttachmentMetadata(const RenderPassDesc& desc) +{ + m_colorCount = desc.colorCount; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + TextureView* view = desc.colorAttachments[i].view; + if (!view || !view->texture()) + continue; + m_colorFormats[i] = view->texture()->format(); + m_sampleCount = view->texture()->sampleCount(); + } + if (desc.depthStencil.view && desc.depthStencil.view->texture()) + { + m_depthFormat = desc.depthStencil.view->texture()->format(); + m_hasDepth = true; + // If no colour attachments drove sampleCount, take it from depth. + if (desc.colorCount == 0) + { + m_sampleCount = desc.depthStencil.view->texture()->sampleCount(); + } + } +} + +inline bool RenderPass::checkPipelineCompat(const Pipeline* pipeline) const +{ + if (!pipeline) + return true; + const PipelineDesc& pd = pipeline->desc(); + + if (pd.colorCount != m_colorCount) + { + if (m_context) + m_context->setLastError( + "setPipeline: pipeline has %u color targets but render pass " + "was begun with %u", + pd.colorCount, + m_colorCount); + return false; + } + for (uint32_t i = 0; i < m_colorCount; ++i) + { + if (pd.colorTargets[i].format != m_colorFormats[i]) + { + if (m_context) + m_context->setLastError( + "setPipeline: color target %u format mismatch " + "(pipeline=%u, pass=%u)", + i, + static_cast(pd.colorTargets[i].format), + static_cast(m_colorFormats[i])); + return false; + } + } + if (pd.sampleCount != m_sampleCount) + { + if (m_context) + m_context->setLastError( + "setPipeline: sample count mismatch (pipeline=%u, pass=%u)", + pd.sampleCount, + m_sampleCount); + return false; + } + // DepthStencilState::format == rgba8unorm is the "no depth" sentinel + // (see ore_types.hpp:443). Treat that as "pipeline has no depth." + const bool pipelineHasDepth = + pd.depthStencil.format != TextureFormat::rgba8unorm; + if (pipelineHasDepth != m_hasDepth) + { + if (m_context) + m_context->setLastError( + "setPipeline: depth attachment %s (pipeline=%d, pass=%d)", + pipelineHasDepth ? "pipeline expects depth but pass has none" + : "pipeline has no depth but pass provides it", + (int)pipelineHasDepth, + (int)m_hasDepth); + return false; + } + if (pipelineHasDepth && pd.depthStencil.format != m_depthFormat) + { + if (m_context) + m_context->setLastError( + "setPipeline: depth format mismatch (pipeline=%u, pass=%u)", + static_cast(pd.depthStencil.format), + static_cast(m_depthFormat)); + return false; + } + return true; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d11.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d11.hpp new file mode 100644 index 000000000..2ce88c62b --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d11.hpp @@ -0,0 +1,84 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/ore/ore_context.hpp" + +#include +#include // ID3D11DeviceContext1 for offset-range CB binds +#include + +namespace rive::ore +{ + +class ContextD3D11 : public Context +{ +public: + static std::unique_ptr Make(ID3D11Device* device, + ID3D11DeviceContext* context); + + ~ContextD3D11() override; + + rcp makeBuffer(const BufferDesc& desc) override; + rcp makeTexture(const TextureDesc& desc) override; + rcp makeTextureView(const TextureViewDesc& desc) override; + rcp makeSampler(const SamplerDesc& desc) override; + rcp makeShaderModule(const ShaderModuleDesc& desc) override; + rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) override; + rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) override; + rcp makeBindGroup(const BindGroupDesc& desc) override; + + RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) override; + + void beginFrame() override; + void endFrame() override; + void waitForGPU() override; + + rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) override; + rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) override; + + ContextD3D11(const ContextD3D11&) = delete; + ContextD3D11& operator=(const ContextD3D11&) = delete; + +private: + friend class RenderPass; + friend class BindGroup; + friend class Texture; + + ContextD3D11() = default; + + // D3D11 implementation helpers — defined in ore_context_d3d11.cpp. + rcp d3d11MakeBuffer(const BufferDesc& desc); + rcp d3d11MakeTexture(const TextureDesc& desc); + rcp d3d11MakeTextureView(const TextureViewDesc& desc); + rcp d3d11MakeSampler(const SamplerDesc& desc); + rcp d3d11MakeShaderModule(const ShaderModuleDesc& desc); + rcp d3d11MakePipeline(const PipelineDesc& desc, + std::string* outError); + rcp d3d11MakeBindGroup(const BindGroupDesc& desc); + rcp d3d11MakeBindGroupLayout( + const BindGroupLayoutDesc& desc); + RenderPass d3d11BeginRenderPass(const RenderPassDesc& desc, + std::string* outError); + rcp d3d11WrapCanvasTexture(gpu::RenderCanvas* canvas); + rcp d3d11WrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h); + + Microsoft::WRL::ComPtr m_d3d11Device; + Microsoft::WRL::ComPtr m_d3d11Context; + // 11.1 context for offset-range constant-buffer binds + // (VSSetConstantBuffers1 / PSSetConstantBuffers1). Acquired via QI at + // Make(); nullptr on pre-11.1 drivers, in which case static-offset and + // dynamic-offset UBOs fall back to whole-buffer binds. + Microsoft::WRL::ComPtr m_d3d11Context1; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d12.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d12.hpp new file mode 100644 index 000000000..9db48188d --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_d3d12.hpp @@ -0,0 +1,162 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/ore/ore_context.hpp" + +#include +#include +#include +#include + +namespace rive::ore +{ + +class ContextD3D12 : public Context +{ +public: + // Takes the D3D12 device and command queue. Ore shares the caller's + // queue so that canvas-texture renders are visible to the host renderer + // without cross-queue synchronization. + static std::unique_ptr Make(ID3D12Device* device, + ID3D12CommandQueue* queue); + + ~ContextD3D12() override; + + rcp makeBuffer(const BufferDesc& desc) override; + rcp makeTexture(const TextureDesc& desc) override; + rcp makeTextureView(const TextureViewDesc& desc) override; + rcp makeSampler(const SamplerDesc& desc) override; + rcp makeShaderModule(const ShaderModuleDesc& desc) override; + rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) override; + rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) override; + rcp makeBindGroup(const BindGroupDesc& desc) override; + + RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) override; + + void beginFrame() override; + void endFrame() override; + void waitForGPU() override; + + rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) override; + rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) override; + + // External-CL mode: Ore records into the host's + // ID3D12GraphicsCommandList (already reset and open) instead of owning + // its own. The host retains ownership of Close/ExecuteCommandLists/the + // frame fence. Contract: the host must have waited on the prior frame's + // completion fence before calling beginFrame(externalCl) again, so + // deferred-destroy closures can be drained safely. Enables cross-engine + // read-after-write (Rive writes, Ore reads) that the owned-CL model + // cannot support. + void beginFrame(ID3D12GraphicsCommandList* externalCl); + + // Called by Ore resource onRefCntReachedZero() implementations. If the + // context is in external-CL mode, the closure is queued and drained at + // the next beginFrame(), after the host has waited on the prior frame + // fence. In owned-CL mode the closure runs immediately — Ore's endFrame() + // does its own ExecuteCommandLists + WaitForFence, so by the time the + // next owned frame begins, any objects referenced by the previous frame's + // CL are safe to release. + void d3dDeferDestroy(std::function destroy); + + ContextD3D12(const ContextD3D12&) = delete; + ContextD3D12& operator=(const ContextD3D12&) = delete; + +private: + friend class RenderPass; + friend class BindGroup; + friend class Texture; + + ContextD3D12() = default; + + // D3D12 implementation helpers — defined in ore_context_d3d12.cpp. + rcp d3d12MakeBuffer(const BufferDesc& desc); + rcp d3d12MakeTexture(const TextureDesc& desc); + rcp d3d12MakeTextureView(const TextureViewDesc& desc); + rcp d3d12MakeSampler(const SamplerDesc& desc); + rcp d3d12MakeShaderModule(const ShaderModuleDesc& desc); + rcp d3d12MakePipeline(const PipelineDesc& desc, + std::string* outError); + rcp d3d12MakeBindGroup(const BindGroupDesc& desc); + rcp d3d12MakeBindGroupLayout( + const BindGroupLayoutDesc& desc); + RenderPass d3d12BeginRenderPass(const RenderPassDesc& desc, + std::string* outError); + rcp d3d12WrapCanvasTexture(gpu::RenderCanvas* canvas); + rcp d3d12WrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h); + + Microsoft::WRL::ComPtr m_d3dDevice; + Microsoft::WRL::ComPtr m_d3dQueue; + Microsoft::WRL::ComPtr m_d3dAllocator; + // ComPtr that owns the command list Ore allocates for owned-CL frames. + // Not used directly by recording code — see m_d3dCmdList below. + Microsoft::WRL::ComPtr m_d3dOwnedCmdList; + // Active command list for the current frame. Points at m_d3dOwnedCmdList + // in owned-CL mode and at the host-provided command list in external-CL + // mode. All recording code reads through this pointer, so the two modes + // share one code path. + ID3D12GraphicsCommandList* m_d3dCmdList = nullptr; + // Separate allocator/list for texture uploads (flushed at beginFrame). + Microsoft::WRL::ComPtr m_d3dUploadAllocator; + Microsoft::WRL::ComPtr m_d3dUploadCmdList; + bool m_d3dUploadListOpen = false; + Microsoft::WRL::ComPtr m_d3dFence; + uint64_t m_d3dFenceValue = 0; + HANDLE m_d3dFenceEvent = nullptr; + // CPU-visible descriptor heaps for creating descriptors at + // resource-creation time. + Microsoft::WRL::ComPtr m_d3dCpuSrvHeap; + Microsoft::WRL::ComPtr m_d3dCpuRtvHeap; + Microsoft::WRL::ComPtr m_d3dCpuDsvHeap; + Microsoft::WRL::ComPtr m_d3dCpuSamplerHeap; + UINT m_d3dCpuSrvAllocated = 0; + UINT m_d3dCpuRtvAllocated = 0; + UINT m_d3dCpuDsvAllocated = 0; + UINT m_d3dCpuSamplerAllocated = 0; + UINT m_d3dSrvDescSize = 0; + UINT m_d3dRtvDescSize = 0; + UINT m_d3dDsvDescSize = 0; + UINT m_d3dSamplerDescSize = 0; + // Null descriptors for unused descriptor-table slots. + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dNullSrv = {}; + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dNullSampler = {}; + // GPU-visible heaps: reset at beginFrame, allocated linearly per draw. + Microsoft::WRL::ComPtr m_d3dGpuSrvHeap; + Microsoft::WRL::ComPtr m_d3dGpuSamplerHeap; + UINT m_d3dGpuSrvAllocated = 0; + UINT m_d3dGpuSamplerAllocated = 0; + // Upload buffers kept alive until the frame fence-wait completes. + std::vector> m_d3dPendingUploads; + // True while the current frame is recording into a host-provided command + // list. endFrame() skips Close/Execute/Wait when set; next beginFrame() + // drains deferred destroys. + bool m_d3dExternalCmdList = false; + // Deferred-destroy closures (pipelines, samplers, buffers, textures, + // views) queued while m_d3dExternalCmdList is true, drained at the next + // beginFrame() or in the destructor after a GPU idle. + std::vector> m_d3dDeferredDestroys; + // Drain the deferred-destroy queue. Caller is responsible for ensuring + // the prior GPU work has completed (via our fence or the host's). + void d3dDrainDeferred(); + // Helpers called by RenderPass to allocate and resolve descriptor handles. + UINT d3d12AllocGpuSrvSlots(UINT count); + UINT d3d12AllocGpuSamplerSlots(UINT count); + D3D12_CPU_DESCRIPTOR_HANDLE d3d12GpuSrvCpuHandle(UINT index) const; + D3D12_GPU_DESCRIPTOR_HANDLE d3d12GpuSrvGpuHandle(UINT index) const; + D3D12_CPU_DESCRIPTOR_HANDLE d3d12GpuSamplerCpuHandle(UINT index) const; + D3D12_GPU_DESCRIPTOR_HANDLE d3d12GpuSamplerGpuHandle(UINT index) const; + // Flush any open upload command list (called from beginFrame). + void d3d12FlushUploads(); +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_gl.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_gl.hpp new file mode 100644 index 000000000..de760d2be --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_gl.hpp @@ -0,0 +1,68 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/ore/ore_context.hpp" + +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// The private GL state only needs 'int' (GLint is always int), keeping this +// header free of glad so it can be included without glad in the search path. + +namespace rive::ore +{ + +class ContextGL : public Context +{ +public: + static std::unique_ptr Make(); + + ~ContextGL() override; + + rcp makeBuffer(const BufferDesc& desc) override; + rcp makeTexture(const TextureDesc& desc) override; + rcp makeTextureView(const TextureViewDesc& desc) override; + rcp makeSampler(const SamplerDesc& desc) override; + rcp makeShaderModule(const ShaderModuleDesc& desc) override; + rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) override; + rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) override; + rcp makeBindGroup(const BindGroupDesc& desc) override; + + RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) override; + + void beginFrame() override; + void endFrame() override; + void waitForGPU() override; + + rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) override; + rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) override; + + ContextGL(const ContextGL&) = delete; + ContextGL& operator=(const ContextGL&) = delete; + +private: + friend class RenderPass; + friend class BindGroup; + friend class Texture; + + ContextGL() = default; + + // GL state tracking for save/restore at frame boundaries. + // NOTE: GL_ELEMENT_ARRAY_BUFFER is intentionally excluded — it is VAO + // state, so restoring the VAO implicitly restores the element buffer. + struct GLSavedState + { + int program = 0; + int arrayBuffer = 0; + int framebuffer = 0; + int vertexArray = 0; + } m_savedState; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_metal.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_metal.hpp new file mode 100644 index 000000000..4e60fe750 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_metal.hpp @@ -0,0 +1,75 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/ore/ore_context.hpp" + +#import + +namespace rive::ore +{ + +class ContextMetal : public Context +{ +public: + static std::unique_ptr Make(id device, + id queue); + + ~ContextMetal() override; + + rcp makeBuffer(const BufferDesc& desc) override; + rcp makeTexture(const TextureDesc& desc) override; + rcp makeTextureView(const TextureViewDesc& desc) override; + rcp makeSampler(const SamplerDesc& desc) override; + rcp makeShaderModule(const ShaderModuleDesc& desc) override; + rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) override; + rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) override; + rcp makeBindGroup(const BindGroupDesc& desc) override; + + RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) override; + + void beginFrame() override; + void endFrame() override; + void waitForGPU() override; + + rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) override; + rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) override; + + ContextMetal(const ContextMetal&) = delete; + ContextMetal& operator=(const ContextMetal&) = delete; + +private: + friend class RenderPass; + friend class BindGroup; + friend class Texture; + + ContextMetal() = default; + + // Metal implementation helpers — defined in ore_context_metal.mm. + // The public make*/begin*/wrap* overrides delegate to these. + void mtlPopulateFeatures(id device); + rcp mtlMakeBuffer(const BufferDesc& desc); + rcp mtlMakeTexture(const TextureDesc& desc); + rcp mtlMakeTextureView(const TextureViewDesc& desc); + rcp mtlMakeSampler(const SamplerDesc& desc); + rcp mtlMakeShaderModule(const ShaderModuleDesc& desc); + rcp mtlMakePipeline(const PipelineDesc& desc, + std::string* outError); + rcp mtlMakeBindGroup(const BindGroupDesc& desc); + RenderPass mtlBeginRenderPass(const RenderPassDesc& desc, + std::string* outError); + rcp mtlWrapCanvasTexture(gpu::RenderCanvas* canvas); + + id m_mtlDevice = nil; + id m_mtlQueue = nil; + id m_mtlCommandBuffer = nil; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_vulkan.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_vulkan.hpp new file mode 100644 index 000000000..32ded7f11 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_vulkan.hpp @@ -0,0 +1,273 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/ore/ore_context.hpp" + +#include +#include +#include +#include + +namespace rive::ore +{ + +// Key used to cache VkRenderPass objects (one per unique format+load/store +// combination). Stored by value — small enough for linear scan. +// +// `colorHasResolve[i]` flags MSAA color attachments that should resolve +// into a single-sample target at end-of-pass. The render pass declares +// a parallel set of resolve attachments and the framebuffer must +// include the resolve image views (handled in beginRenderPass). A +// resolve attachment is meaningful only when `sampleCount > 1`; a +// single-sample render pass with `colorHasResolve[i] = true` produces +// an invalid Vulkan render pass. +struct VKRenderPassKey +{ + TextureFormat colorFormats[4] = {}; + uint32_t colorCount = 0; + LoadOp colorLoadOps[4] = {}; + StoreOp colorStoreOps[4] = {}; + bool colorHasResolve[4] = {}; + TextureFormat depthFormat = TextureFormat::depth24plusStencil8; + LoadOp depthLoadOp = LoadOp::dontCare; + StoreOp depthStoreOp = StoreOp::discard; + bool hasDepth = false; + uint32_t sampleCount = 1; + + bool operator==(const VKRenderPassKey& o) const + { + if (colorCount != o.colorCount || hasDepth != o.hasDepth || + sampleCount != o.sampleCount) + return false; + for (uint32_t i = 0; i < colorCount; ++i) + { + if (colorFormats[i] != o.colorFormats[i] || + colorLoadOps[i] != o.colorLoadOps[i] || + colorStoreOps[i] != o.colorStoreOps[i] || + colorHasResolve[i] != o.colorHasResolve[i]) + return false; + } + if (hasDepth && + (depthFormat != o.depthFormat || depthLoadOp != o.depthLoadOp || + depthStoreOp != o.depthStoreOp)) + return false; + return true; + } +}; + +class ContextVulkan : public Context +{ +public: + // The caller is responsible for creating all Vulkan objects and the VMA + // allocator. Ore does not manage device lifetime. + static std::unique_ptr Make( + VkInstance instance, + VkPhysicalDevice physicalDevice, + VkDevice device, + VkQueue queue, + uint32_t queueFamilyIndex, + VmaAllocator allocator, + PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr); + + ~ContextVulkan() override; + + rcp makeBuffer(const BufferDesc& desc) override; + rcp makeTexture(const TextureDesc& desc) override; + rcp makeTextureView(const TextureViewDesc& desc) override; + rcp makeSampler(const SamplerDesc& desc) override; + rcp makeShaderModule(const ShaderModuleDesc& desc) override; + rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) override; + rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) override; + rcp makeBindGroup(const BindGroupDesc& desc) override; + + RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) override; + + void beginFrame() override; + void endFrame() override; + void waitForGPU() override; + + rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) override; + rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) override; + + // External-CB mode: Ore records into the host's VkCommandBuffer (already + // begun by the caller) instead of owning its own CB. The host retains + // ownership of BeginCommandBuffer/EndCommandBuffer/QueueSubmit and the + // frame fence. Contract: by the time beginFrame(externalCb) is called + // again for a new frame, the host must have waited on the prior frame's + // completion fence so deferred-destroy lists can be drained safely. + // Enables cross-engine read-after-write (e.g. Rive renders into a canvas + // then Ore samples it) that the owned-CB model cannot support, because + // all recordings land in a single submission. + void beginFrame(VkCommandBuffer externalCb); + + // Called by Ore resource onRefCntReachedZero() implementations. If the + // context is currently in external-CB mode, the closure is queued to + // run after the host has submitted and waited on the current CB. In + // owned-CB mode the closure runs immediately. + void vkDeferDestroy(std::function destroy); + + // Look up or create a VkRenderPass compatible with the given key. + // Called by makePipeline() (with DONT_CARE ops) and beginRenderPass(). + VkRenderPass getOrCreateRenderPass(const VKRenderPassKey&); + + // Vulkan function dispatch table. + // Populated by Make(); all call sites use m_vk.Xxx(...) to avoid direct + // vkXxx() symbols which are stripped when VK_NO_PROTOTYPES is defined. +#define ORE_VK_INSTANCE_COMMANDS(F) \ + F(GetDeviceProcAddr) \ + F(GetPhysicalDeviceProperties) \ + F(GetPhysicalDeviceFeatures) + +#define ORE_VK_DEVICE_COMMANDS(F) \ + F(AllocateCommandBuffers) \ + F(AllocateDescriptorSets) \ + F(FreeDescriptorSets) \ + F(BeginCommandBuffer) \ + F(CmdBeginRenderPass) \ + F(CmdBindDescriptorSets) \ + F(CmdBindIndexBuffer) \ + F(CmdBindPipeline) \ + F(CmdBindVertexBuffers) \ + F(CmdCopyBufferToImage) \ + F(CmdDraw) \ + F(CmdDrawIndexed) \ + F(CmdEndRenderPass) \ + F(CmdPipelineBarrier) \ + F(CmdSetBlendConstants) \ + F(CmdSetScissor) \ + F(CmdSetStencilReference) \ + F(CmdSetViewport) \ + F(CreateCommandPool) \ + F(CreateDescriptorPool) \ + F(CreateDescriptorSetLayout) \ + F(CreateFramebuffer) \ + F(CreateGraphicsPipelines) \ + F(CreateImageView) \ + F(CreatePipelineLayout) \ + F(CreateRenderPass) \ + F(CreateSampler) \ + F(CreateShaderModule) \ + F(DestroyCommandPool) \ + F(DestroyDescriptorPool) \ + F(DestroyDescriptorSetLayout) \ + F(DestroyFramebuffer) \ + F(DestroyImageView) \ + F(DestroyPipeline) \ + F(DestroyPipelineLayout) \ + F(DestroyRenderPass) \ + F(DestroySampler) \ + F(DestroyShaderModule) \ + F(EndCommandBuffer) \ + F(CreateFence) \ + F(DestroyFence) \ + F(WaitForFences) \ + F(ResetFences) \ + F(QueueSubmit) \ + F(QueueWaitIdle) \ + F(ResetCommandBuffer) \ + F(ResetDescriptorPool) \ + F(UpdateDescriptorSets) + + struct VkFn + { +#define DECLARE_VK_CMD(CMD) PFN_vk##CMD CMD = nullptr; + ORE_VK_INSTANCE_COMMANDS(DECLARE_VK_CMD) + ORE_VK_DEVICE_COMMANDS(DECLARE_VK_CMD) +#undef DECLARE_VK_CMD + }; + + ContextVulkan(const ContextVulkan&) = delete; + ContextVulkan& operator=(const ContextVulkan&) = delete; + +private: + friend class RenderPass; + friend class BindGroup; + friend class Texture; + + ContextVulkan() = default; + + VkFn m_vk; + VkPhysicalDevice m_vkPhysicalDevice = VK_NULL_HANDLE; + VkDevice m_vkDevice = VK_NULL_HANDLE; + VkQueue m_vkQueue = VK_NULL_HANDLE; + uint32_t m_vkQueueFamily = 0; + VmaAllocator m_vmaAllocator = VK_NULL_HANDLE; + VkCommandPool m_vkCommandPool = VK_NULL_HANDLE; + VkCommandBuffer m_vkCommandBuffer = VK_NULL_HANDLE; + // True while the current frame is recording into a host-provided CB. + // endFrame() skips End/Submit/Wait when set; next beginFrame() drains + // deferred destroys. + bool m_vkExternalCmdBuf = false; + VkDescriptorPool m_vkDescriptorPool = VK_NULL_HANDLE; + VkFence m_vkFrameFence = VK_NULL_HANDLE; + // Framebuffers whose destruction is deferred until the next beginFrame() + // fence-wait (they are still referenced by the in-flight command buffer + // until the fence signals). + std::vector m_vkDeferredFramebuffers; + // Staging buffers whose destruction is deferred until endFrame() submits + // and waits on the fence. Texture::upload() records copy commands into + // the frame command buffer, so the staging buffer must stay alive until + // the command buffer finishes executing. + struct DeferredVmaBuffer + { + VkBuffer buffer; + VmaAllocation allocation; + }; + std::vector m_vkDeferredStagingBuffers; + // Generic deferred-destroy closures (pipelines, samplers, etc.) for + // external-CB mode, where Ore cannot vkDestroy* an object the moment its + // refcount reaches zero because the host's CB still references it. + std::vector> m_vkDeferredDestroys; + // Persistent descriptor pool for long-lived BindGroup objects. Created + // with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT so individual + // sets can be freed in BindGroup::onRefCntReachedZero() without affecting + // other allocations. + VkDescriptorPool m_vkPersistentDescriptorPool = VK_NULL_HANDLE; + + // Lazy-created shared empty `VkDescriptorSetLayout`. Substituted for null + // entries in `PipelineDesc::bindGroupLayouts[]` so Vulkan's + // `VkPipelineLayoutCreateInfo::pSetLayouts` array is fully populated with + // valid handles (Vulkan spec VUID-VkPipelineLayoutCreateInfo- + // graphicsPipelineLibrary-06753 forbids `VK_NULL_HANDLE` slots without + // the graphicsPipelineLibrary feature). Destroyed at Context teardown via + // `vkDeferDestroy` if needed. + VkDescriptorSetLayout m_vkEmptyDSL = VK_NULL_HANDLE; + VkDescriptorSetLayout vkGetOrCreateEmptyDSL(); + // Render pass cache — typically <10 entries, keyed on format+load/store + // ops. + std::vector> m_vkRenderPassCache; + + // Pending UNDEFINED → SHADER_READ_ONLY_OPTIMAL layout transitions for + // textures bound as sampled images in a BindGroup before their VkImage + // layout has been initialized by upload() or a render pass. A render- + // target-capable texture that is sampled without first being rendered + // into would otherwise violate VUID-vkCmdDraw-None-09600 — the descriptor + // declares SHADER_READ_ONLY_OPTIMAL but the image is still + // VK_IMAGE_LAYOUT_UNDEFINED from creation. Recorded in makeBindGroup() + // and flushed onto the frame command buffer at beginFrame() / at the + // start of beginRenderPass(), before any draw can reference the + // descriptor. Matches WebGPU's lazy-initialize-on-first-use semantic. + // The rcp pins the image alive until the barrier is recorded. + struct VkPendingImageTransition + { + rcp texture; + VkImageAspectFlags aspectMask; + }; + std::vector m_vkPendingInitialTransitions; + void vkFlushPendingInitialTransitions(); + + // Drain framebuffers/staging buffers and deferred destroy closures from + // the previous frame. Caller is responsible for ensuring the prior GPU + // work has completed (via our fence or the host's). + void vkDrainDeferred(); +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_wgpu.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_wgpu.hpp new file mode 100644 index 000000000..44891d535 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_context_wgpu.hpp @@ -0,0 +1,92 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/ore/ore_context.hpp" + +#include +#ifndef RIVE_DAWN +#include +#endif + +namespace rive::ore +{ + +class ContextWGPU : public Context +{ +public: + // backendType is wgpu::BackendType::OpenGLES or wgpu::BackendType::Vulkan, + // obtained from RenderContextWebGPUImpl::capabilities().backendType. + static std::unique_ptr Make(wgpu::Device device, + wgpu::Queue queue, + wgpu::BackendType backendType); + + ~ContextWGPU() override; + + rcp makeBuffer(const BufferDesc& desc) override; + rcp makeTexture(const TextureDesc& desc) override; + rcp makeTextureView(const TextureViewDesc& desc) override; + rcp makeSampler(const SamplerDesc& desc) override; + rcp makeShaderModule(const ShaderModuleDesc& desc) override; + rcp makeBindGroupLayout( + const BindGroupLayoutDesc& desc) override; + rcp makePipeline(const PipelineDesc& desc, + std::string* outError = nullptr) override; + rcp makeBindGroup(const BindGroupDesc& desc) override; + + RenderPass beginRenderPass(const RenderPassDesc& desc, + std::string* outError = nullptr) override; + + void beginFrame() override; + void endFrame() override; + void waitForGPU() override; + + rcp wrapCanvasTexture(gpu::RenderCanvas* canvas) override; + rcp wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t width, + uint32_t height) override; + + // External-encoder mode: Ore records into the host's wgpu::CommandEncoder + // (already created by the caller) instead of owning its own. The host + // retains ownership of Finish()/Submit() and frame sequencing. Unlike + // Vulkan and D3D12, no deferred-destroy queue is needed: wgpu handles are + // refcounted and command encoders / buffers pin referenced resources + // until GPU completion, so dropping the C++ wrapper while the encoder + // still references the resource is safe by WebGPU semantics. + // + // Enables cross-engine read-after-write (e.g. Rive renders into a canvas + // then Ore samples it) that the owned-encoder model cannot support — + // same motivation as the VK/D3D12 external overloads. + void beginFrame(wgpu::CommandEncoder externalEncoder); + + // Returns true when the runtime target is OpenGL ES (wagyu GLSLRAW path). + // Use this to select between GLES and Vulkan GLSL shader source. + bool isGLES() const { return m_wgpuBackend == WGPUBackend::OpenGLES; } + + ContextWGPU(const ContextWGPU&) = delete; + ContextWGPU& operator=(const ContextWGPU&) = delete; + +private: + friend class RenderPass; + friend class BindGroup; + friend class Texture; + + ContextWGPU() = default; + + enum class WGPUBackend + { + OpenGLES, + Vulkan + }; + WGPUBackend m_wgpuBackend = WGPUBackend::Vulkan; + wgpu::Device m_wgpuDevice; + wgpu::Queue m_wgpuQueue; + wgpu::CommandEncoder m_wgpuCommandEncoder; + // True while the current frame is recording into a host-provided encoder. + // endFrame() skips Finish()/Submit() when set. + bool m_wgpuExternalEncoder = false; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_pipeline.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_pipeline.hpp new file mode 100644 index 000000000..a2915dd5a --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_pipeline.hpp @@ -0,0 +1,179 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" + +#include + +#if defined(ORE_BACKEND_METAL) +#import +#endif +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// GL object handles are GLuint = unsigned int; no glad needed in the header. +#if defined(ORE_BACKEND_D3D11) +#include +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +#endif + +namespace rive::ore +{ + +class Context; +#if defined(ORE_BACKEND_VK) +class ContextVulkan; +#endif +#if defined(ORE_BACKEND_D3D12) +class ContextD3D12; +#endif + +class Pipeline : public RefCnt +{ +public: + const PipelineDesc& desc() const { return m_desc; } + + // (group, binding) → per-backend native slot map for this pipeline's + // resources. Copied from the vertex / fragment ShaderModule at + // construction. Consumed by each flatten-backend's `makeBindGroup` + // to translate a `BindGroupDesc::*Entry::slot` (= WGSL `@binding`) + // into the backend's native slot (Metal buffer index, HLSL register, + // GL binding point, D3D12 `BaseShaderRegister`). + BindingMap m_bindingMap; + + // Layouts the pipeline was created with — one per `@group(N)`. Keeps + // them alive (the per-backend native handles inside the layouts are + // referenced by the pipeline's compiled state). Used by `setBindGroup` + // to verify `bg->layout() == m_layouts[g]` (pointer-equality check + // matching WebGPU's exact-layout requirement). + rcp m_layouts[kMaxBindGroups]; + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class RenderPass; + + Pipeline(const PipelineDesc& desc) : m_desc(desc) + { + // Propagate the binding map from the VS module (or FS if VS is + // absent, e.g. blit-only pipelines). The two modules are + // compiled from a single WGSL source so their maps agree, and + // every module is required to carry a populated map. + if (desc.vertexModule != nullptr) + { + m_bindingMap = desc.vertexModule->m_bindingMap; + } + else if (desc.fragmentModule != nullptr) + { + m_bindingMap = desc.fragmentModule->m_bindingMap; + } + + // Stash the user-supplied layouts. Backends overwrite NULL + // entries (groups the shader doesn't bind) with a no-op + // BindGroupLayout if needed for empty-set semantics. + const uint32_t count = std::min(desc.bindGroupLayoutCount, + static_cast(kMaxBindGroups)); + for (uint32_t i = 0; i < count; ++i) + { + m_layouts[i] = ref_rcp(desc.bindGroupLayouts[i]); + } + } + + PipelineDesc m_desc; + +#if defined(ORE_BACKEND_METAL) + id m_mtlPipeline = nil; + id m_mtlDepthStencil = nil; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glProgram = 0; +#endif +#if defined(ORE_BACKEND_D3D11) + Microsoft::WRL::ComPtr m_d3dInputLayout; + Microsoft::WRL::ComPtr m_d3dRasterizer; + Microsoft::WRL::ComPtr m_d3dDepthStencil; + Microsoft::WRL::ComPtr m_d3dBlend; + ID3D11VertexShader* m_d3dVS = nullptr; + ID3D11PixelShader* m_d3dPS = nullptr; + // Strong refs to keep ShaderModules alive for the lifetime of the + // Pipeline. Without these, Luau GC can destroy the ScriptedShader + // (and its ShaderModules) while the Pipeline still references them, + // causing use-after-free crashes in the D3D11 driver. + rcp m_vsModule; + rcp m_psModule; +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::Device m_wgpuDevice; // Needed to create bind groups at draw time. + wgpu::RenderPipeline m_wgpuPipeline; + wgpu::PipelineLayout m_wgpuPipelineLayout; +#endif +#if defined(ORE_BACKEND_VK) + VkDevice m_vkDevice = VK_NULL_HANDLE; + VkPipelineLayout m_vkPipelineLayout = VK_NULL_HANDLE; + VkPipeline m_vkPipeline = VK_NULL_HANDLE; + VkPrimitiveTopology m_vkTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + // Function pointers for cleanup (loaded by Context::makePipeline). + PFN_vkDestroyPipeline m_vkDestroyPipeline = nullptr; + PFN_vkDestroyPipelineLayout m_vkDestroyPipelineLayout = nullptr; + // Back-ref so onRefCntReachedZero() can route the actual vkDestroy* calls + // through ContextVulkan::vkDeferDestroy() when an external command buffer + // is active (the host hasn't submitted yet). Weak ref. + ContextVulkan* m_vkOreContext = nullptr; +#endif +#if defined(ORE_BACKEND_D3D12) + Microsoft::WRL::ComPtr m_d3dPSO; + // Per-pipeline root signature composed from per-group descriptor-table + // shapes carried by each `m_layouts[g]->m_d3dGroupParams`. The root + // sig itself is per-pipeline (cross-group) but consumes the layouts' + // per-group params at build time. + Microsoft::WRL::ComPtr m_d3dRootSigOwned; + // Per-group root-parameter indices (set at root sig build time) + + // per-kind register ranges (mirrored from each layout's + // m_d3dGroupParams). Consumed at setBindGroup time to dispatch + // descriptor writes into the right root parameter. + D3D12GroupRootParams m_d3dGroupParams[kMaxBindGroups]{}; + D3D12_PRIMITIVE_TOPOLOGY m_d3dTopology = + D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + UINT m_d3dVertexStrides[8] = {}; // Per-slot vertex strides. + // Back-ref so onRefCntReachedZero() can route the ComPtr release through + // ContextD3D12::d3dDeferDestroy() when an external command list is active. + // Weak ref. + ContextD3D12* m_d3dOreContext = nullptr; +#endif + +public: + void onRefCntReachedZero() const; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_render_pass.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_render_pass.hpp new file mode 100644 index 000000000..4b66d2bb3 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_render_pass.hpp @@ -0,0 +1,407 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" + +#if defined(ORE_BACKEND_METAL) +#import +#endif +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// GL object handles are GLuint = unsigned int; no glad needed in the header. +#if defined(ORE_BACKEND_D3D11) +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +namespace rive::gpu +{ +class RenderTargetVulkan; +} +#endif + +namespace rive::ore +{ + +class Buffer; +class TextureView; +class Sampler; +class Pipeline; +class BindGroup; +class Context; +#if defined(ORE_BACKEND_VK) +class ContextVulkan; +#endif +#if defined(ORE_BACKEND_D3D12) +class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) +class ContextWGPU; +#endif + +class RenderPass +{ +public: + void setPipeline(Pipeline* pipeline); + + void setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset = 0); + void setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset = 0); + + // Bind a pre-created BindGroup, optionally overriding dynamic UBO offsets. + // Dynamic-ness is declared on the pipeline (`PipelineDesc::dynamicUBOs`) + // and cached per-slot on the BindGroup at creation. + // dynamicOffsets: one uint32 per dynamic UBO in this group, in the order + // they appear in `BindGroupDesc::ubos` (matches WebGPU semantics when + // the caller lists UBOs in ascending-slot order, the typical pattern). + void setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets = nullptr, + uint32_t dynamicOffsetCount = 0); + + void setViewport(float x, + float y, + float width, + float height, + float minDepth = 0.0f, + float maxDepth = 1.0f); + void setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height); + + void setStencilReference(uint32_t ref); + void setBlendColor(float r, float g, float b, float a); + + void draw(uint32_t vertexCount, + uint32_t instanceCount = 1, + uint32_t firstVertex = 0, + uint32_t firstInstance = 0); + + void drawIndexed(uint32_t indexCount, + uint32_t instanceCount = 1, + uint32_t firstIndex = 0, + int32_t baseVertex = 0, + uint32_t firstInstance = 0); + + void finish(); + bool isFinished() const { return m_finished; } + + ~RenderPass(); + + RenderPass(RenderPass&& other) noexcept; + RenderPass& operator=(RenderPass&&) noexcept; + RenderPass(const RenderPass&) = delete; + RenderPass& operator=(const RenderPass&) = delete; + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + + RenderPass() = default; + + bool m_finished = false; + + // Attachment metadata — populated by beginRenderPass() from the + // RenderPassDesc via populateAttachmentMetadata(). Used by setPipeline() + // for format/sampleCount validation (matches WebGPU spec: validation at + // setPipeline time). + TextureFormat m_colorFormats[4] = {}; + uint32_t m_colorCount = 0; + TextureFormat m_depthFormat = {}; + bool m_hasDepth = false; + uint32_t m_sampleCount = 1; + + // Cross-backend back-pointer used by the pipeline-compat validator to + // route errors through Context::setLastError(). Populated by every + // backend's beginRenderPass() alongside the per-backend context fields + // (m_vkContext, m_wgpuContext, ...). Weak ref. + Context* m_context = nullptr; + + // Lifecycle: strong refs to bound BindGroups prevent Lua GC from freeing + // them between setBindGroup() and finish(). Released in finish(). + rcp m_boundGroups[kMaxBindGroups]; + + void validate() const; + + // Populate attachment metadata from the descriptor. Called by every + // backend's beginRenderPass() immediately after constructing the + // RenderPass; defined inline because it only reads cross-backend + // texture/view accessors that are uniform across backends. + inline void populateAttachmentMetadata(const RenderPassDesc& desc); + + // WebGPU-spec pipeline/attachment compatibility check, invoked from + // every backend's setPipeline(). Compares the pipeline's declared + // color/depth formats and sampleCount against the attachments this + // pass was begun with. Returns true on match; on mismatch populates + // Context::lastError() and returns false. + inline bool checkPipelineCompat(const Pipeline* pipeline) const; + + // Move cross-backend fields (m_context, attachment metadata, + // m_boundGroups) from `other` into `*this` and clear them on `other`. + // Called from every backend's move ctor / move-assign so that new + // cross-backend fields only need to be wired once. + inline void moveCrossBackendFieldsFrom(RenderPass& other) + { + m_finished = other.m_finished; + for (uint32_t i = 0; i < 4; ++i) + m_colorFormats[i] = other.m_colorFormats[i]; + m_colorCount = other.m_colorCount; + m_depthFormat = other.m_depthFormat; + m_hasDepth = other.m_hasDepth; + m_sampleCount = other.m_sampleCount; + m_context = other.m_context; + for (uint32_t i = 0; i < kMaxBindGroups; ++i) + m_boundGroups[i] = std::move(other.m_boundGroups[i]); + other.m_finished = true; + other.m_context = nullptr; + } + + // Shared across all non-Metal backends that track the current + // pipeline. Strong ref (rcp) — same lifetime guarantee as + // `m_boundGroups[]`. The Lua bridge can GC its `Pipeline` userdata + // between `setPipeline` and `finish`, so a raw pointer would + // dangle by the next `draw()`. The rcp keeps the Pipeline alive + // until `finish()` clears the field. +#if defined(ORE_BACKEND_GL) || defined(ORE_BACKEND_D3D11) || \ + defined(ORE_BACKEND_WGPU) || defined(ORE_BACKEND_VK) + rcp m_currentPipeline; +#endif + + // GL keeps an explicit stencil-reference cache because + // `glStencilFuncSeparate` bundles compare + ref + readMask into a + // single call — re-applying compare from the new pipeline at + // `setPipeline` time would otherwise drop any reference value the + // caller set earlier on the pass. WebGPU semantics are pass-state: + // `setStencilReference` persists across pipeline changes. + // Other backends either keep stencil ref on the encoder/cmd-buf + // (Metal, Vulkan dynamic state, D3D12 OMSetStencilRef) or rebind it + // via the API directly without losing the value. +#if defined(ORE_BACKEND_GL) + uint32_t m_glStencilRef = 0; +#endif + +#if defined(ORE_BACKEND_METAL) + // Metal implementation helpers — shared by metal-only and metal+gl builds. + // Defined inline in ore_render_pass_metal.mm. + inline void mtlSetPipeline(Pipeline* pipeline); + inline void mtlSetVertexBuffer(uint32_t slot, + Buffer* buffer, + uint32_t offset); + inline void mtlSetIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset); + inline void mtlSetBindGroup(BindGroup* bg, + uint32_t groupIndex, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount); + inline void mtlSetViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth); + inline void mtlSetScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height); + inline void mtlSetStencilRef(uint32_t ref); + inline void mtlSetBlendColor(float r, float g, float b, float a); + inline void mtlDraw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + inline void mtlDrawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance); + inline void mtlFinish(); + + id m_mtlEncoder = nil; + id m_mtlCommandBuffer = nil; + id m_mtlIndexBuffer = nil; + MTLIndexType m_mtlIndexType = MTLIndexTypeUInt16; + uint32_t m_mtlIndexBufferOffset = 0; + MTLPrimitiveType m_mtlPrimitiveType = MTLPrimitiveTypeTriangle; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glFBO = 0; + unsigned int m_glVAO = 0; + unsigned int m_prevVAO = 0; // Saved host VAO to restore in finish(). + unsigned int m_prevFBO = 0; // Saved host FBO to restore in finish(). + bool m_ownsFBO = false; + bool m_ownsVAO = false; + // (Cross-backend m_context lives outside this guard — see line ~117.) + uint32_t m_viewportWidth = 0; + uint32_t m_viewportHeight = 0; + uint32_t m_maxSamplerSlot = 0; // Track highest sampler slot for cleanup. + uint32_t m_maxAttribSlot = 0; // Track highest vertex attrib for cleanup. + bool m_usedSamplers = false; + bool m_usedAttribs = false; + IndexFormat m_glIndexFormat = IndexFormat::uint16; + + // MSAA resolve targets (populated by beginRenderPass when + // ColorAttachment::resolveTarget is set). + struct GLResolveInfo + { + uint32_t colorIndex = 0; + unsigned int resolveTex = 0; + unsigned int resolveTarget = 0; // GL target (e.g. GL_TEXTURE_2D). + uint32_t width = 0; + uint32_t height = 0; + }; + GLResolveInfo m_glResolves[4] = {}; + uint32_t m_glResolveCount = 0; +#endif +#if defined(ORE_BACKEND_D3D11) + ID3D11DeviceContext* m_d3d11Context = nullptr; + D3D11_PRIMITIVE_TOPOLOGY m_d3d11Topology = + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + DXGI_FORMAT m_d3d11IndexFormat = DXGI_FORMAT_R16_UINT; + uint32_t m_d3d11IndexOffset = 0; + uint32_t m_d3d11StencilRef = 0; + float m_d3d11BlendFactor[4] = {}; + // MSAA resolve: pairs of (msaaTexture, resolveTexture) + format + + // per-view subresource indices. D3D11 subresource index is + // mipLevel + (arraySlice * mipCount), so recording both endpoints + // at pass-begin time (where the view desc is accessible) means + // finish() just passes them through to ResolveSubresource. + struct D3D11ResolveEntry + { + ID3D11Resource* msaa = nullptr; + ID3D11Resource* resolve = nullptr; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + uint32_t msaaSubresource = 0; + uint32_t resolveSubresource = 0; + }; + D3D11ResolveEntry m_d3d11Resolves[4]; + uint32_t m_d3d11ResolveCount = 0; +#endif +#if defined(ORE_BACKEND_WGPU) + ContextWGPU* m_wgpuContext = nullptr; + wgpu::RenderPassEncoder m_wgpuPassEncoder; + wgpu::Buffer m_wgpuIndexBuffer; + wgpu::IndexFormat m_wgpuIndexFormat = wgpu::IndexFormat::Uint16; + uint64_t m_wgpuIndexOffset = 0; +#endif +#if defined(ORE_BACKEND_VK) + ContextVulkan* m_vkContext = nullptr; + VkCommandBuffer m_vkCmdBuf = VK_NULL_HANDLE; // Weak ref (owned by Context). + VkFramebuffer m_vkFramebuffer = + VK_NULL_HANDLE; // Created per-pass, destroyed in finish(). + VkBuffer m_vkIndexBuffer = VK_NULL_HANDLE; + VkIndexType m_vkIndexType = VK_INDEX_TYPE_UINT16; + VkDeviceSize m_vkIndexOffset = 0; + // Color attachment images for the post-render layout transition + // (COLOR_ATTACHMENT_OPTIMAL → SHADER_READ_ONLY_OPTIMAL). + VkImage m_vkColorImages[4] = {}; + uint32_t m_vkColorBaseLayer[4] = {}; + uint32_t m_vkColorLayerCount[4] = {}; + uint32_t m_vkColorCount = 0; + // Weak back-refs to Rive's render targets so finish() can update their + // lastAccess tracking after the layout transition. + gpu::RenderTargetVulkan* m_vkColorRenderTargets[4] = {}; + // Depth attachment image for the post-render barrier + // (DEPTH_STENCIL_ATTACHMENT_OPTIMAL → SHADER_READ_ONLY_OPTIMAL). + VkImage m_vkDepthImage = VK_NULL_HANDLE; + uint32_t m_vkDepthBaseLayer = 0; + uint32_t m_vkDepthLayerCount = 0; +#endif +#if defined(ORE_BACKEND_D3D12) + // D3D12 setBindGroup body — shared between the D3D12-only translation + // unit (ore_render_pass_d3d12.cpp) and the combined D3D11+D3D12 one + // (ore_render_pass_d3d11_d3d12.cpp). Defined inline in + // ore_d3d12_bind_group_apply.hpp, which both .cpp files include. + inline void d3d12ApplyBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount); + + ID3D12GraphicsCommandList* m_d3dCmdList = + nullptr; // Weak ref (owned by Context). + ID3D12Device* m_d3dDevice = nullptr; // Weak ref. + ContextD3D12* m_d3dContext = nullptr; // Weak ref. + // Strong ref — same Lua-GC reasoning as the cross-backend + // `m_currentPipeline` above. The D3D12-only field exists because + // D3D12's setPipeline path is split between this TU and the + // d3d11+d3d12 combined TU; both share this storage. + rcp m_d3dCurrentPipeline; + // Root signature currently bound on the command list. Compared against + // each new pipeline's `m_d3dRootSigOwned` in `setPipeline` so we only + // call `SetGraphicsRootSignature` when the sig actually changes (each + // Ore D3D12 pipeline owns its own per-pipeline root sig — RFC v5 + // §3.2.2). Weak ref; freed by the owning Pipeline. + ID3D12RootSignature* m_d3dCurrentRootSig = nullptr; + // Pending descriptor state (accumulated per setPipeline/setBindGroup). + D3D12_GPU_VIRTUAL_ADDRESS m_d3dPendingUBOs[8] = {}; + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dPendingSrvHandles[8] = {}; + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dPendingSamplerHandles[8] = {}; + DXGI_FORMAT m_d3dIndexFormat = DXGI_FORMAT_R16_UINT; + uint32_t m_d3dIndexOffset = 0; + uint32_t m_d3dStencilRef = 0; + float m_d3dBlendFactor[4] = {}; + // Color attachment resources for barrier in finish() (RT → final). + // Parallel arrays: m_d3dColorTextures provides the Ore Texture back-ref so + // finish() can keep Texture::m_d3dCurrentState in sync with the actual + // resource state after the end-of-pass transition. + ID3D12Resource* m_d3dColorResources[4] = {}; + Texture* m_d3dColorTextures[4] = {}; + D3D12_RESOURCE_STATES m_d3dColorFinalStates[4] = {}; + uint32_t m_d3dColorCount = 0; + ID3D12Resource* m_d3dDepthResource = nullptr; + Texture* m_d3dDepthTexture = nullptr; + D3D12_RESOURCE_STATES m_d3dDepthFinalState = D3D12_RESOURCE_STATE_COMMON; + // MSAA resolve pairs (populated at beginRenderPass, executed in finish). + // D3D12 subresource index is mipLevel + arraySlice * mipCount for the + // common single-plane case. + struct D3D12ResolveEntry + { + ID3D12Resource* msaa = nullptr; + ID3D12Resource* resolve = nullptr; + // Back-ref to the resolve target's Ore Texture so finish() can update + // Texture::m_d3dCurrentState after the resolve barrier chain. + Texture* resolveTex = nullptr; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + uint32_t msaaSubresource = 0; + uint32_t resolveSubresource = 0; + // Resolve target's prior state, to restore after resolve. + D3D12_RESOURCE_STATES resolvePriorState = D3D12_RESOURCE_STATE_COMMON; + // Resolve target's final state (what finish() should leave it in). + D3D12_RESOURCE_STATES resolveFinalState = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + }; + D3D12ResolveEntry m_d3dResolves[4] = {}; + uint32_t m_d3dResolveCount = 0; +#endif +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_sampler.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_sampler.hpp new file mode 100644 index 000000000..30f23849e --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_sampler.hpp @@ -0,0 +1,98 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" + +#if defined(ORE_BACKEND_METAL) +#import +#endif +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// GL object handles are GLuint = unsigned int; no glad needed in the header. +#if defined(ORE_BACKEND_D3D11) +#include +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +#endif + +namespace rive::ore +{ + +class Context; +#if defined(ORE_BACKEND_VK) +class ContextVulkan; +#endif +#if defined(ORE_BACKEND_D3D12) +class ContextD3D12; +#endif + +class Sampler : public RefCnt +{ +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class RenderPass; + + Sampler() = default; + +#if defined(ORE_BACKEND_METAL) + id m_mtlSampler = nil; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glSampler = 0; +#endif +#if defined(ORE_BACKEND_D3D11) + Microsoft::WRL::ComPtr m_d3dSampler; +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::Sampler m_wgpuSampler; +#endif +#if defined(ORE_BACKEND_VK) + VkSampler m_vkSampler = VK_NULL_HANDLE; + VkDevice m_vkDevice = VK_NULL_HANDLE; // Weak ref. + PFN_vkDestroySampler m_vkDestroySampler = nullptr; + // Back-ref so onRefCntReachedZero() can route destruction through + // ContextVulkan::vkDeferDestroy() in external-CB mode. Weak ref. + ContextVulkan* m_vkOreContext = nullptr; +#endif +#if defined(ORE_BACKEND_D3D12) + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dSamplerHandle = {}; // {0} = invalid. + // Back-ref so onRefCntReachedZero() can route destruction through + // ContextD3D12::d3dDeferDestroy() in external-CL mode. Weak ref. + ContextD3D12* m_d3dOreContext = nullptr; +#endif + +public: + void onRefCntReachedZero() const; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_shader_module.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_shader_module.hpp new file mode 100644 index 000000000..6f499c5ca --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_shader_module.hpp @@ -0,0 +1,307 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_binding_map.hpp" +#include "rive/renderer/ore/ore_types.hpp" + +#include +#include +#include +#include + +#if defined(ORE_BACKEND_METAL) +#import +#endif +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// GL object handles are GLuint = unsigned int; no glad needed in the header. +#if defined(ORE_BACKEND_D3D11) +#include +#include +#include +#include +#include +#include +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +#endif + +namespace rive::ore +{ + +class Context; + +class ShaderModule : public RefCnt +{ +public: + /// Texture-sampler pair from RSTB shader reflection. + /// Records which texture binding is paired with which sampler binding + /// in the shader's sampling expressions. Used by the GL backend to bind + /// sampler objects to the correct texture unit. + struct TextureSamplerPair + { + uint8_t textureGroup; + uint8_t textureBinding; + uint8_t samplerGroup; + uint8_t samplerBinding; + }; + + std::vector m_textureSamplerPairs; + + // (group, binding) → per-backend native slot map for this shader's + // resources. Parsed from the RSTB binding-map sidecar by each + // backend's `makeShaderModule` (via `applyBindingMapFromDesc` + // below). Consumed by `Pipeline`, which copies it from its vertex / + // fragment modules at construction. + BindingMap m_bindingMap; + +#ifdef TRACK_RIVE_SHADER_ID + // Set from desc.shaderAssetId in applyBindingMapFromDesc. + uint32_t m_shaderAssetId = 0; + uint32_t shaderAssetId() const { return m_shaderAssetId; } +#endif + + // Helper for backend `makeShaderModule` paths: parse the binding-map + // sidecar bytes (`desc.bindingMapBytes`) into `m_bindingMap`. The + // sidecar is mandatory; runtime backends rely on it to translate + // `@group/@binding` to native slots. + void applyBindingMapFromDesc(const ShaderModuleDesc& desc) + { + assert(desc.bindingMapBytes != nullptr && desc.bindingMapSize > 0 && + "ShaderModuleDesc::bindingMapBytes is required"); + const bool ok = BindingMap::fromBlob(desc.bindingMapBytes, + desc.bindingMapSize, + &m_bindingMap); + assert(ok && "binding-map sidecar failed to parse"); + (void)ok; + applyGLFixupFromDesc(desc); +#ifdef TRACK_RIVE_SHADER_ID + m_shaderAssetId = desc.shaderAssetId; +#endif + } + + // One entry in the GL program-link fixup table: tells the runtime + // which GL binding point / texture unit each named uniform should + // land on, letting `oreGLFixupProgramBindings` call + // `glUniformBlockBinding` / `glUniform1i` without parsing the + // emitted GLSL names at runtime. + struct GLFixupEntry + { + enum class Kind : uint8_t + { + UBOBlock = 0, + SamplerUniform = 1, + }; + Kind kind; + uint8_t slot; + std::string name; + }; + + // Parsed fixup table. Populated from the stage's RSTB sidecar (target + // 14 = VS, target 15 = FS). Empty for non-GL backends, where these + // sidecars are not part of the variant set. + // `oreGLFixupProgramBindings` iterates both stages' tables at + // `glLinkProgram` time. + std::vector m_glFixup; + + // Helper: parse `desc.glFixupBytes` (RSTB GL fixup blob format) + // into `m_glFixup`. No-op when the sidecar is absent or malformed. + void applyGLFixupFromDesc(const ShaderModuleDesc& desc) + { + if (desc.glFixupBytes == nullptr || desc.glFixupSize < 3) + return; + const uint8_t* p = desc.glFixupBytes; + const uint8_t* end = p + desc.glFixupSize; + if (*p++ != 1) // version + return; + uint16_t count = uint16_t(p[0]) | (uint16_t(p[1]) << 8); + p += 2; + m_glFixup.reserve(count); + for (uint16_t i = 0; i < count; ++i) + { + if (end - p < 4) + return; + GLFixupEntry e; + e.kind = static_cast(*p++); + e.slot = *p++; + uint16_t nameLen = uint16_t(p[0]) | (uint16_t(p[1]) << 8); + p += 2; + if (end - p < nameLen) + return; + e.name.assign(reinterpret_cast(p), nameLen); + p += nameLen; + m_glFixup.push_back(std::move(e)); + } + } + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class Pipeline; + + ShaderModule() = default; + +#if defined(ORE_BACKEND_METAL) + id m_mtlLibrary = nil; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glShader = 0; + unsigned int m_glShaderType = 0; // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER. +#endif +#if defined(ORE_BACKEND_D3D11) + std::vector m_bytecode; + ShaderStage m_stage = ShaderStage::autoDetect; + Microsoft::WRL::ComPtr m_d3dVertexShader; + Microsoft::WRL::ComPtr m_d3dPixelShader; + + // HLSL source compiled at first pipeline use via ensureD3DShaders. + std::string m_hlslSource; + std::string m_hlslEntryPoint; + + // Guards ensureD3DShaders against concurrent first-call from two + // pipelines sharing this ShaderModule. + std::once_flag m_d3dInitFlag; + + // outError, if non-null, receives the D3DCompile error log so the + // caller can route it to Context::m_lastError. + void ensureD3DShaders(ID3D11Device* device, std::string* outError = nullptr) + { + std::call_once(m_d3dInitFlag, + [&]() { ensureD3DShadersImpl(device, outError); }); + } + + void ensureD3DShadersImpl(ID3D11Device* device, std::string* outError) + { + if (m_hlslSource.empty()) + return; + + // Normalize line endings (SPIRV-Cross outputs \r\n on Windows). + m_hlslSource.erase( + std::remove(m_hlslSource.begin(), m_hlslSource.end(), '\r'), + m_hlslSource.end()); + + const char* target = + (m_stage == ShaderStage::fragment) ? "ps_5_0" : "vs_5_0"; + const char* entry = + m_hlslEntryPoint.empty() ? "main" : m_hlslEntryPoint.c_str(); + Microsoft::WRL::ComPtr compiledBlob; + Microsoft::WRL::ComPtr errors; + HRESULT hr = D3DCompile(m_hlslSource.c_str(), + m_hlslSource.size(), + nullptr, + nullptr, + nullptr, + entry, + target, + D3DCOMPILE_ENABLE_STRICTNESS | + D3DCOMPILE_OPTIMIZATION_LEVEL3, + 0, + compiledBlob.GetAddressOf(), + errors.GetAddressOf()); + if (FAILED(hr)) + { + if (outError) + { + const char* errMsg = + errors + ? static_cast(errors->GetBufferPointer()) + : "(no error log)"; + char buf[1024]; + snprintf(buf, + sizeof(buf), + "D3DCompile failed (entry=%s target=%s " + "hr=0x%08x): %s", + entry, + target, + static_cast(hr), + errMsg); + *outError = buf; + } + return; + } + + const void* code = compiledBlob->GetBufferPointer(); + SIZE_T codeSize = compiledBlob->GetBufferSize(); + // Store compiled bytecode for CreateInputLayout. + m_bytecode.assign(static_cast(code), + static_cast(code) + codeSize); + + if (m_stage == ShaderStage::fragment) + { + device->CreatePixelShader(code, + codeSize, + nullptr, + m_d3dPixelShader.GetAddressOf()); + } + else if (m_stage == ShaderStage::vertex) + { + device->CreateVertexShader(code, + codeSize, + nullptr, + m_d3dVertexShader.GetAddressOf()); + } + else + { + HRESULT hr = + device->CreateVertexShader(code, + codeSize, + nullptr, + m_d3dVertexShader.GetAddressOf()); + if (FAILED(hr)) + { + device->CreatePixelShader(code, + codeSize, + nullptr, + m_d3dPixelShader.GetAddressOf()); + } + } + } +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::ShaderModule m_wgpuShaderModule; +#endif +#if defined(ORE_BACKEND_VK) + VkShaderModule m_vkShaderModule = VK_NULL_HANDLE; + VkDevice m_vkDevice = VK_NULL_HANDLE; // Weak ref. + PFN_vkDestroyShaderModule m_vkDestroyShaderModule = nullptr; +#endif +#if defined(ORE_BACKEND_D3D12) + std::vector m_d3dBytecode; + bool m_d3dIsVertex = false; // True = VS, False = PS. +#endif + +public: + void onRefCntReachedZero() const; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_texture.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_texture.hpp new file mode 100644 index 000000000..e4229935a --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_texture.hpp @@ -0,0 +1,250 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/ore/ore_types.hpp" + +#if defined(ORE_BACKEND_METAL) +#import +#endif +// Note: load_gles_extensions.hpp (glad) is intentionally NOT included here. +// GL object handles are GLuint = unsigned int; no glad needed in the header. +#if defined(ORE_BACKEND_D3D11) +#include +#include +#endif +#if defined(ORE_BACKEND_D3D12) +#include +#include +#endif +#if defined(ORE_BACKEND_WGPU) +#include +#endif +#if defined(ORE_BACKEND_VK) +#include +VK_DEFINE_HANDLE(VmaAllocator); +VK_DEFINE_HANDLE(VmaAllocation); +namespace rive::gpu +{ +class RenderTargetVulkan; +} +#endif + +namespace rive::ore +{ + +class Context; +#if defined(ORE_BACKEND_VK) +class ContextVulkan; +#endif +#if defined(ORE_BACKEND_D3D12) +class ContextD3D12; +#endif + +class Texture : public RefCnt +{ +public: + uint32_t width() const { return m_width; } + uint32_t height() const { return m_height; } + uint32_t depthOrArrayLayers() const { return m_depthOrArrayLayers; } + TextureFormat format() const { return m_format; } + TextureType type() const { return m_type; } + uint32_t numMipmaps() const { return m_numMipmaps; } + uint32_t sampleCount() const { return m_sampleCount; } + bool isRenderTarget() const { return m_renderTarget; } + + void upload(const TextureDataDesc& data); + +#if defined(ORE_BACKEND_METAL) + id mtlTexture() const { return m_mtlTexture; } +#endif + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class TextureView; + friend class RenderPass; + + Texture(const TextureDesc& desc) : + m_width(desc.width), + m_height(desc.height), + m_depthOrArrayLayers(desc.depthOrArrayLayers), + m_format(desc.format), + m_type(desc.type), + m_renderTarget(desc.renderTarget), + m_numMipmaps(desc.numMipmaps), + m_sampleCount(desc.sampleCount) + {} + + uint32_t m_width; + uint32_t m_height; + uint32_t m_depthOrArrayLayers; + TextureFormat m_format; + TextureType m_type; + bool m_renderTarget; + uint32_t m_numMipmaps; + uint32_t m_sampleCount; + +#if defined(ORE_BACKEND_METAL) + id m_mtlTexture = nil; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glTexture = 0; + unsigned int m_glRenderbuffer = 0; // Non-zero for MSAA render targets + // (renderbuffer-backed, not texture). + unsigned int m_glTarget = 0; + bool m_glOwnsTexture = true; // False for borrowed textures (e.g. + // wrapCanvasTexture). +#endif +#if defined(ORE_BACKEND_D3D11) + Microsoft::WRL::ComPtr m_d3d11Texture; + ID3D11DeviceContext* m_d3d11Context = + nullptr; // Weak ref, set by Context::makeTexture. +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::Texture m_wgpuTexture; + wgpu::Queue + m_wgpuQueue; // Weak ref (addref'd copy), set by Context::makeTexture. +#endif +#if defined(ORE_BACKEND_VK) + VkImage m_vkImage = VK_NULL_HANDLE; + VmaAllocation m_vmaAllocation = VK_NULL_HANDLE; + VkImageLayout m_vkLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkDevice m_vkDevice = VK_NULL_HANDLE; // Weak ref. + VmaAllocator m_vmaAllocator = VK_NULL_HANDLE; // Weak ref. + // Back-pointer to the owning ContextVulkan. upload() reads the current + // frame CB and VK dispatch table through it, and onRefCntReachedZero() + // routes vmaDestroyImage through ContextVulkan::vkDeferDestroy() in + // external-CB mode. + ContextVulkan* m_vkOreContext = nullptr; +#endif +#if defined(ORE_BACKEND_D3D12) + Microsoft::WRL::ComPtr m_d3dTexture; + D3D12_RESOURCE_STATES m_d3dCurrentState = D3D12_RESOURCE_STATE_COMMON; + bool m_d3dIsExternal = false; // true for wrapCanvasTexture. + ID3D12Device* m_d3dDevice = nullptr; // Weak ref. + // Set by ContextD3D12::makeTexture so upload() can schedule copy commands. + ContextD3D12* m_d3dOreContext = nullptr; // Weak ref. +#endif + +public: + void onRefCntReachedZero() const; +}; + +class TextureView : public RefCnt +{ +public: + Texture* texture() const { return m_texture.get(); } + TextureViewDimension dimension() const { return m_dimension; } + TextureAspect aspect() const { return m_aspect; } + uint32_t baseMipLevel() const { return m_baseMipLevel; } + uint32_t mipCount() const { return m_mipCount; } + uint32_t baseLayer() const { return m_baseLayer; } + uint32_t layerCount() const { return m_layerCount; } + +#if defined(ORE_BACKEND_METAL) + id mtlTexture() const + { + return m_mtlTextureView ? m_mtlTextureView : m_texture->m_mtlTexture; + } +#endif + +private: + friend class Context; +#if defined(ORE_BACKEND_METAL) + friend class ContextMetal; +#endif +#if defined(ORE_BACKEND_GL) + friend class ContextGL; +#endif +#if defined(ORE_BACKEND_D3D11) + friend class ContextD3D11; +#endif +#if defined(ORE_BACKEND_D3D12) + friend class ContextD3D12; +#endif +#if defined(ORE_BACKEND_WGPU) + friend class ContextWGPU; +#endif +#if defined(ORE_BACKEND_VK) + friend class ContextVulkan; +#endif + friend class RenderPass; + + TextureView(rcp texture, const TextureViewDesc& desc) : + m_texture(std::move(texture)), + m_dimension(desc.dimension), + m_aspect(desc.aspect), + m_baseMipLevel(desc.baseMipLevel), + m_mipCount(desc.mipCount), + m_baseLayer(desc.baseLayer), + m_layerCount(desc.layerCount) + {} + + rcp m_texture; + TextureViewDimension m_dimension; + TextureAspect m_aspect; + uint32_t m_baseMipLevel; + uint32_t m_mipCount; + uint32_t m_baseLayer; + uint32_t m_layerCount; + +#if defined(ORE_BACKEND_METAL) + id m_mtlTextureView = nil; +#endif +#if defined(ORE_BACKEND_GL) + unsigned int m_glTextureView = 0; // GL 4.3 view, or 0 (use base texture). +#endif +#if defined(ORE_BACKEND_D3D11) + Microsoft::WRL::ComPtr m_d3dSRV; + Microsoft::WRL::ComPtr m_d3dRTV; + Microsoft::WRL::ComPtr m_d3dDSV; +#endif +#if defined(ORE_BACKEND_WGPU) + wgpu::TextureView m_wgpuTextureView; +#endif +#if defined(ORE_BACKEND_VK) + VkImageView m_vkImageView = VK_NULL_HANDLE; + VkDevice m_vkDevice = VK_NULL_HANDLE; // Weak ref. + PFN_vkDestroyImageView m_vkDestroyImageView = nullptr; + // Set only for canvas-backed views (wrapCanvasTexture). Used by + // RenderPass::finish() to update Rive's layout tracking. + gpu::RenderTargetVulkan* m_vkRenderTarget = nullptr; // Weak ref. + // Back-ref so onRefCntReachedZero() can route the destroy through + // ContextVulkan::vkDeferDestroy() in external-CB mode. Weak ref. + ContextVulkan* m_vkOreContext = nullptr; +#endif +#if defined(ORE_BACKEND_D3D12) + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dSrvHandle = {}; // {0} = invalid. + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dRtvHandle = {}; + D3D12_CPU_DESCRIPTOR_HANDLE m_d3dDsvHandle = {}; + // Back-ref so onRefCntReachedZero() can route destruction through + // ContextD3D12::d3dDeferDestroy() in external-CL mode. Weak ref. + ContextD3D12* m_d3dOreContext = nullptr; +#endif + +public: + void onRefCntReachedZero() const; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/ore/ore_types.hpp b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_types.hpp new file mode 100644 index 000000000..77fe27d73 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/ore/ore_types.hpp @@ -0,0 +1,745 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include + +namespace rive::ore +{ + +// ============================================================================ +// Constants +// ============================================================================ + +// Maximum number of bind groups Ore supports per pipeline. WebGPU's +// `maxBindGroups` minimum is 4, and Ore sits at that minimum. Backends +// preallocate per-group structures using this +// constant (Vulkan DSLs, WebGPU BGLs, D3D12 root params, RenderPass +// `m_boundGroups`). Single source of truth across every backend's +// per-group array, the public `BindGroupDesc::groupIndex` validity +// range, and Lua-side validation in `gpubindgroup_construct` / +// `setBindGroup`. +constexpr uint32_t kMaxBindGroups = 4; + +// ============================================================================ +// Enums +// ============================================================================ + +enum class BufferUsage : uint8_t +{ + vertex, + index, + uniform, +}; + +enum class ShaderLanguage : uint8_t +{ + glsl, // GLSL via wagyu (GLSLRAW for GLES, GLSL/glslang for Vulkan). + wgsl, // WGSL — works on both GLES and Vulkan wagyu paths, no pragma needed. +}; + +enum class ShaderStage : uint8_t +{ + autoDetect, // Infer from source content (legacy gl_Position heuristic). + vertex, + fragment, +}; + +enum class TextureFormat : uint8_t +{ + // 8-bit + r8unorm, + rg8unorm, + rgba8unorm, + rgba8snorm, + bgra8unorm, + + // 16-bit float + rgba16float, + rg16float, + r16float, + + // 32-bit float + rgba32float, + rg32float, + r32float, + + // Packed + rgb10a2unorm, + r11g11b10float, + + // Depth/stencil + depth16unorm, + depth24plusStencil8, + depth32float, + depth32floatStencil8, + + // Compressed (runtime support via Features query) + bc1unorm, + bc3unorm, + bc7unorm, + etc2rgb8, + etc2rgba8, + astc4x4, + astc6x6, + astc8x8, +}; + +// Returns bytes per texel for uncompressed formats, or 0 for block-compressed +// formats (which require block-based stride calculation). +inline uint32_t textureFormatBytesPerTexel(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return 1; + case TextureFormat::rg8unorm: + return 2; + case TextureFormat::rgba8unorm: + return 4; + case TextureFormat::rgba8snorm: + return 4; + case TextureFormat::bgra8unorm: + return 4; + case TextureFormat::rgba16float: + return 8; + case TextureFormat::rg16float: + return 4; + case TextureFormat::r16float: + return 2; + case TextureFormat::rgba32float: + return 16; + case TextureFormat::rg32float: + return 8; + case TextureFormat::r32float: + return 4; + case TextureFormat::rgb10a2unorm: + return 4; + case TextureFormat::r11g11b10float: + return 4; + case TextureFormat::depth16unorm: + return 2; + case TextureFormat::depth24plusStencil8: + return 4; + case TextureFormat::depth32float: + return 4; + case TextureFormat::depth32floatStencil8: + return 8; + default: + return 0; // block-compressed + } +} + +enum class TextureType : uint8_t +{ + texture2D, + cube, + texture3D, + array2D, +}; + +enum class TextureViewDimension : uint8_t +{ + texture2D, + cube, + texture3D, + array2D, + cubeArray, +}; + +enum class TextureAspect : uint8_t +{ + all, + depthOnly, + stencilOnly, +}; + +enum class Filter : uint8_t +{ + nearest, + linear, +}; + +enum class WrapMode : uint8_t +{ + repeat, + mirrorRepeat, + clampToEdge, +}; + +enum class CompareFunction : uint8_t +{ + none, // Not a comparison (default for samplers = normal filtering). + never, + less, + equal, + lessEqual, + greater, + notEqual, + greaterEqual, + always, +}; + +enum class PrimitiveTopology : uint8_t +{ + pointList, + lineList, + lineStrip, + triangleList, + triangleStrip, +}; + +enum class IndexFormat : uint8_t +{ + none, + uint16, + uint32, +}; + +enum class VertexFormat : uint8_t +{ + float1, + float2, + float3, + float4, + uint8x4, + sint8x4, + unorm8x4, + snorm8x4, + uint16x2, + sint16x2, + unorm16x2, + snorm16x2, + uint16x4, + sint16x4, + float16x2, + float16x4, + uint32, + uint32x2, + uint32x3, + uint32x4, + sint32, + sint32x2, + sint32x3, + sint32x4, +}; + +enum class VertexStepMode : uint8_t +{ + vertex, + instance, +}; + +enum class CullMode : uint8_t +{ + none, + front, + back, +}; + +enum class FaceWinding : uint8_t +{ + clockwise, + counterClockwise, +}; + +enum class BlendFactor : uint8_t +{ + zero, + one, + srcColor, + oneMinusSrcColor, + srcAlpha, + oneMinusSrcAlpha, + dstColor, + oneMinusDstColor, + dstAlpha, + oneMinusDstAlpha, + srcAlphaSaturated, + blendColor, + oneMinusBlendColor, +}; + +enum class BlendOp : uint8_t +{ + add, + subtract, + reverseSubtract, + min, + max, +}; + +enum class StencilOp : uint8_t +{ + keep, + zero, + replace, + incrementClamp, + decrementClamp, + invert, + incrementWrap, + decrementWrap, +}; + +enum class LoadOp : uint8_t +{ + clear, + load, + dontCare, +}; + +enum class StoreOp : uint8_t +{ + store, + discard, +}; + +enum class ColorWriteMask : uint8_t +{ + none = 0, + red = 1 << 0, + green = 1 << 1, + blue = 1 << 2, + alpha = 1 << 3, + all = 0xF, +}; + +inline ColorWriteMask operator|(ColorWriteMask a, ColorWriteMask b) +{ + return static_cast(static_cast(a) | + static_cast(b)); +} + +inline ColorWriteMask operator&(ColorWriteMask a, ColorWriteMask b) +{ + return static_cast(static_cast(a) & + static_cast(b)); +} + +// ============================================================================ +// Forward declarations +// ============================================================================ + +class Buffer; +class Texture; +class TextureView; +class Sampler; +class ShaderModule; +class Pipeline; +class BindGroupLayout; + +// ============================================================================ +// Descriptor Structs +// ============================================================================ + +struct BufferDesc +{ + BufferUsage usage; + uint32_t size = 0; + const void* data = nullptr; + bool immutable = false; // GPU-only allocation; data must be non-null; no + // update() calls allowed after creation. + const char* label = nullptr; +}; + +struct TextureDesc +{ + uint32_t width = 0; + uint32_t height = 0; + uint32_t depthOrArrayLayers = 1; + TextureFormat format = TextureFormat::rgba8unorm; + TextureType type = TextureType::texture2D; + bool renderTarget = false; + uint32_t numMipmaps = 1; + uint32_t sampleCount = 1; + const char* label = nullptr; +}; + +struct TextureViewDesc +{ + Texture* texture = nullptr; + TextureViewDimension dimension = TextureViewDimension::texture2D; + TextureAspect aspect = TextureAspect::all; + uint32_t baseMipLevel = 0; + uint32_t mipCount = 1; + uint32_t baseLayer = 0; + uint32_t layerCount = 1; +}; + +struct TextureDataDesc +{ + const void* data = nullptr; + uint32_t bytesPerRow = 0; + uint32_t rowsPerImage = 0; + uint32_t mipLevel = 0; + uint32_t layer = 0; + uint32_t x = 0, y = 0, z = 0; + uint32_t width = 0, height = 0, depth = 1; +}; + +struct SamplerDesc +{ + Filter minFilter = Filter::nearest; + Filter magFilter = Filter::nearest; + Filter mipmapFilter = Filter::nearest; + WrapMode wrapU = WrapMode::clampToEdge; + WrapMode wrapV = WrapMode::clampToEdge; + WrapMode wrapW = WrapMode::clampToEdge; + CompareFunction compare = CompareFunction::none; + float minLod = 0.0f; + float maxLod = 32.0f; + uint32_t maxAnisotropy = 1; + const char* label = nullptr; +}; + +struct ShaderModuleDesc +{ + const void* code = nullptr; + uint32_t codeSize = 0; + ShaderLanguage language = ShaderLanguage::glsl; + ShaderStage stage = ShaderStage::autoDetect; + const char* label = nullptr; + + // D3D11 only: HLSL source for runtime compilation via D3DCompile. + // When set, the shader is compiled at first use (ensureD3DShaders) + // rather than from pre-compiled DXBC. This is required on AMD because + // D3DCompile produces different DXBC per process context. + const char* hlslSource = nullptr; + uint32_t hlslSourceSize = 0; + const char* hlslEntryPoint = nullptr; + + // Required binding-map sidecar bytes from the RSTB (target IDs 10-13, + // 16, one per source backend). `makeShaderModule` parses them via + // `ore::BindingMap::fromBlob` into `ShaderModule::m_bindingMap`. The + // sidecar is mandatory: a missing or unparseable blob is a programming + // error, not a fallback condition. + const uint8_t* bindingMapBytes = nullptr; + uint32_t bindingMapSize = 0; + + // GL program-link fixup blob from the RSTB (target IDs 14/15, one per + // GLSL stage). Consumed by `oreGLFixupProgramBindings` at + // `glLinkProgram` time to call `glUniformBlockBinding` / `glUniform1i` + // by uniform name — no runtime string parsing. Required when the + // module's source target is GLSL (target 1); null for other targets. + const uint8_t* glFixupBytes = nullptr; + uint32_t glFixupSize = 0; + + // Source ShaderAsset id (FileAsset::assetId()), or 0 if synthesized. + // Storage on ShaderModule is gated by TRACK_RIVE_SHADER_ID. + uint32_t shaderAssetId = 0; +}; + +struct VertexAttribute +{ + VertexFormat format = VertexFormat::float4; + uint32_t offset = 0; + uint32_t shaderSlot = 0; +}; + +struct VertexBufferLayout +{ + uint32_t stride = 0; + VertexStepMode stepMode = VertexStepMode::vertex; + const VertexAttribute* attributes = nullptr; + uint32_t attributeCount = 0; +}; + +struct BlendState +{ + BlendFactor srcColor = BlendFactor::one; + BlendFactor dstColor = BlendFactor::zero; + BlendOp colorOp = BlendOp::add; + BlendFactor srcAlpha = BlendFactor::one; + BlendFactor dstAlpha = BlendFactor::zero; + BlendOp alphaOp = BlendOp::add; +}; + +struct ColorTargetState +{ + TextureFormat format = TextureFormat::bgra8unorm; + bool blendEnabled = false; + BlendState blend; + ColorWriteMask writeMask = ColorWriteMask::all; +}; + +struct StencilFaceState +{ + CompareFunction compare = CompareFunction::always; + StencilOp failOp = StencilOp::keep; + StencilOp depthFailOp = StencilOp::keep; + StencilOp passOp = StencilOp::keep; +}; + +struct DepthStencilState +{ + // rgba8unorm is the sentinel for "no depth/stencil attachment" (checked by + // the Vulkan backend in ore_pipeline_vulkan.cpp). Set this to an actual + // depth format to attach a depth/stencil buffer to the pipeline. + TextureFormat format = TextureFormat::rgba8unorm; + CompareFunction depthCompare = CompareFunction::always; + bool depthWriteEnabled = false; + int32_t depthBias = 0; + float depthBiasSlopeScale = 0.0f; + float depthBiasClamp = 0.0f; +}; + +// ============================================================================ +// BindGroupLayout Descriptor, explicit layout, Dawn-shaped. +// +// One layout per WGSL `@group(N)`. Created via `Context::makeBindGroupLayout` +// and consumed by both `PipelineDesc::bindGroupLayouts[]` and +// `BindGroupDesc::layout`. Replaces the previous "BindGroup is built against +// a Pipeline" coupling — the layout is the contract that pipelines and bind +// groups agree on, so a single BindGroup can be used with any pipeline that +// declares the same layout for its corresponding group. +// ============================================================================ + +// Resource kind a layout entry describes. Values intentionally distinct from +// `ore::ResourceKind` (in ore_binding_map.hpp) so the public layout API +// doesn't drag the binding-map header into every translation unit. The two +// are mapped 1:1 inside the layout-creation code. +enum class BindingKind : uint8_t +{ + uniformBuffer, + storageBufferRO, + storageBufferRW, + sampledTexture, + storageTexture, + sampler, + comparisonSampler, +}; + +// Stage-visibility bits. Bitwise-OR of `kStageVS` / `kStageFS` (compute is +// reserved for future use). Mirrors WebGPU's `GPUShaderStage` flagset. +struct StageVisibility +{ + static constexpr uint8_t kVertex = 1u << 0; + static constexpr uint8_t kFragment = 1u << 1; + static constexpr uint8_t kCompute = 1u << 2; + + uint8_t mask = kVertex | kFragment; +}; + +struct BindGroupLayoutEntry +{ + // WGSL `@binding(N)` value this entry describes. The (group, binding) + // pair must agree with the shader's reflected binding map; mismatch + // is rejected at `makePipeline` time with a clear error. + uint32_t binding = 0; + + BindingKind kind = BindingKind::uniformBuffer; + + // Stage-visibility mask. Default vertex+fragment matches the most + // common case; visibility narrower than the shader's reflected + // stageMask is rejected at makePipeline (broader is fine). + StageVisibility visibility; + + // UBO-only: declares the binding will receive a dynamic offset at + // `setBindGroup` time. Vulkan DSL picks + // `VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC` vs `UNIFORM_BUFFER`; + // D3D12 uses a root CBV instead of an in-table CBV; Metal / GL / + // D3D11 cache the flag for per-draw `setVertexBuffer` offset apply. + bool hasDynamicOffset = false; + + // Texture-only: dimension + sample type + multisampled. Drives the + // WebGPU BGL entry's `texture.{viewDimension, sampleType, multisampled}`. + // Ignored for non-texture kinds. + TextureViewDimension textureViewDim = TextureViewDimension::texture2D; + // sampleType is one of "float", "unfilterable-float", "depth", "sint", + // "uint" in WebGPU. Encoded compactly here as a small enum that + // backends map to the Dawn enum. + enum class SampleType : uint8_t + { + floatFilterable, + floatUnfilterable, + depth, + sint, + uint, + }; + SampleType textureSampleType = SampleType::floatFilterable; + bool textureMultisampled = false; + + // UBO-only: smallest valid bind size for this entry. 0 = no minimum + // (use the full buffer range). Matches WebGPU's + // `BindGroupLayoutEntry::buffer.minBindingSize`. Currently advisory — + // backends don't yet enforce. + uint32_t minBindingSize = 0; + + // Pre-resolved native slots, per-stage. Populated by the caller from + // the shader's binding map (typically via the GM helper + // `makeLayoutFromShader(ctx, shader, group)`). Used by backends with + // no native layout object (Metal: buffer index; D3D11: per-stage + // register; GL: global slot). Vulkan and WebGPU ignore — those + // backends use `binding` directly (per-set namespace). + // + // 0xFFFFFFFF = `kAbsent` (binding not visible to that stage). Default + // is "absent in all stages" so a layout-without-shader-resolution + // works on Vulkan/WebGPU but fails loudly on Metal/D3D11/GL. + static constexpr uint32_t kNativeSlotAbsent = 0xFFFFFFFFu; + uint32_t nativeSlotVS = kNativeSlotAbsent; + uint32_t nativeSlotFS = kNativeSlotAbsent; + uint32_t nativeSlotCS = kNativeSlotAbsent; +}; + +struct BindGroupLayoutDesc +{ + // WGSL `@group(N)` this layout describes. Valid range [0, kMaxBindGroups). + uint32_t groupIndex = 0; + + const BindGroupLayoutEntry* entries = nullptr; + uint32_t entryCount = 0; + + const char* label = nullptr; +}; + +struct PipelineDesc +{ + ShaderModule* vertexModule = nullptr; + const char* vertexEntryPoint = "vs_main"; + ShaderModule* fragmentModule = nullptr; + const char* fragmentEntryPoint = "fs_main"; + + const VertexBufferLayout* vertexBuffers = nullptr; + uint32_t vertexBufferCount = 0; + + PrimitiveTopology topology = PrimitiveTopology::triangleList; + IndexFormat indexFormat = IndexFormat::none; + CullMode cullMode = CullMode::none; + FaceWinding winding = FaceWinding::counterClockwise; + + ColorTargetState colorTargets[4] = {}; + uint32_t colorCount = 1; + + DepthStencilState depthStencil; + + StencilFaceState stencilFront; + StencilFaceState stencilBack; + uint8_t stencilReadMask = 0xFF; + uint8_t stencilWriteMask = 0xFF; + + uint32_t sampleCount = 1; + + // Explicit bind-group layouts — one entry per `@group(N)` the shader + // declares bindings for. `bindGroupLayouts[g]` is the layout used when + // a BindGroup is bound at group index `g` via + // `RenderPass::setBindGroup(g, ...)`. NULL entries are allowed for + // groups the shader doesn't use. + // + // Required (no auto-derive). Mismatch with the shader's reflected + // binding map causes `makePipeline` to set lastError + return null. + BindGroupLayout* const* bindGroupLayouts = nullptr; + uint32_t bindGroupLayoutCount = 0; + + const char* label = nullptr; +}; + +struct ClearColor +{ + float r = 0.0f, g = 0.0f, b = 0.0f, a = 1.0f; +}; + +struct ColorAttachment +{ + TextureView* view = nullptr; + TextureView* resolveTarget = nullptr; + LoadOp loadOp = LoadOp::clear; + StoreOp storeOp = StoreOp::store; + ClearColor clearColor; +}; + +struct DepthStencilAttachment +{ + TextureView* view = nullptr; + LoadOp depthLoadOp = LoadOp::clear; + StoreOp depthStoreOp = StoreOp::store; + float depthClearValue = 1.0f; + LoadOp stencilLoadOp = LoadOp::clear; + StoreOp stencilStoreOp = StoreOp::discard; + uint32_t stencilClearValue = 0; +}; + +struct RenderPassDesc +{ + ColorAttachment colorAttachments[4] = {}; + uint32_t colorCount = 1; + DepthStencilAttachment depthStencil; + const char* label = nullptr; +}; + +// ============================================================================ +// BindGroup Descriptor +// ============================================================================ + +struct BindGroupDesc +{ + // The layout the BindGroup conforms to. The layout's `groupIndex` + // determines which `setBindGroup(g, ...)` slot this BindGroup is + // bindable at. Resource kinds and per-slot expectations come from the + // layout's entries. + BindGroupLayout* layout = nullptr; + + struct UBOEntry + { + uint32_t slot = 0; // WGSL @binding within the layout's group. + Buffer* buffer = nullptr; + uint32_t offset = 0; + uint32_t size = 0; + }; + struct TexEntry + { + uint32_t slot = 0; + TextureView* view = nullptr; + }; + struct SampEntry + { + uint32_t slot = 0; + Sampler* sampler = nullptr; + }; + + const UBOEntry* ubos = nullptr; + uint32_t uboCount = 0; + const TexEntry* textures = nullptr; + uint32_t textureCount = 0; + const SampEntry* samplers = nullptr; + uint32_t samplerCount = 0; + const char* label = nullptr; +}; + +// ============================================================================ +// Features — runtime capability query +// ============================================================================ + +struct Features +{ + bool colorBufferFloat = false; + bool perTargetBlend = false; + bool perTargetWriteMask = false; + bool textureViewSampling = false; + bool drawBaseInstance = false; + bool depthBiasClamp = false; + bool anisotropicFiltering = false; + bool texture3D = false; + bool textureArrays = false; + bool computeShaders = false; + bool storageBuffers = false; + + bool bc = false; + bool etc2 = false; + bool astc = false; + + uint32_t maxColorAttachments = 4; + uint32_t maxTextureSize2D = 4096; + uint32_t maxTextureSizeCube = 4096; + uint32_t maxTextureSize3D = 256; + uint32_t maxUniformBufferSize = 16384; + uint32_t maxVertexAttributes = 16; + uint32_t maxSamplers = 16; + // Maximum MSAA sample count supported for color render targets. + // Scripts should query this before creating MSAA textures; values are + // always a power-of-two (1, 2, 4, 8). Conservative default: 4. + uint32_t maxSamples = 4; +}; + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/include/rive/renderer/render_canvas.hpp b/thirdparty/rive_renderer/include/rive/renderer/render_canvas.hpp new file mode 100644 index 000000000..3f2868ad9 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/render_canvas.hpp @@ -0,0 +1,39 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/refcnt.hpp" +#include "rive/renderer/render_target.hpp" +#include "rive/renderer/rive_render_image.hpp" + +namespace rive::gpu +{ + +// A GPU texture that can be used as both a render target (for rendering into) +// and a render image (for compositing into Rive draws). Enables off-screen +// rendering for 3D content (Ore), cached 2D content, or any render-to-texture +// use case. +class RenderCanvas : public RefCnt +{ +public: + RenderCanvas(rcp image, rcp target) : + m_renderImage(std::move(image)), m_renderTarget(std::move(target)) + {} + + uint32_t width() const { return m_renderTarget->width(); } + uint32_t height() const { return m_renderTarget->height(); } + + // Use as a RenderImage for compositing into Rive draws. + RiveRenderImage* renderImage() { return m_renderImage.get(); } + + // Use as a RenderTarget for rendering into this texture. + RenderTarget* renderTarget() { return m_renderTarget.get(); } + +private: + rcp m_renderImage; + rcp m_renderTarget; +}; + +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/render_context.hpp b/thirdparty/rive_renderer/include/rive/renderer/render_context.hpp index 86723f98b..6b969e7c2 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/render_context.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/render_context.hpp @@ -7,7 +7,11 @@ #include "rive/math/vec2d.hpp" #include "rive/renderer/gpu.hpp" #include "rive/renderer/rive_render_factory.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif #include "rive/renderer/render_target.hpp" +#include "rive/renderer/shader_compilation_mode.hpp" #include "rive/renderer/sk_rectanizer_skyline.hpp" #include "rive/renderer/trivial_block_allocator.hpp" #include "rive/shapes/paint/color.hpp" @@ -30,12 +34,21 @@ class GradientLibrary; class IntersectionBoard; class ImageMeshDraw; class ImageRectDraw; -class StencilClipReset; +class ClipReset; class Draw; class Gradient; class RenderContextImpl; class PathDraw; +// Various types of ordered dithering we can add to reduce banding +// https://en.wikipedia.org/wiki/Ordered_dithering +// https://blog.demofox.org/2022/01/01/interleaved-gradient-noise-a-different-kind-of-low-discrepancy-sequence/ +enum class DitherMode +{ + none, + interleavedGradientNoise, +}; + // Used as a key for complex gradients. class GradientContentKey { @@ -91,9 +104,23 @@ class RenderContext : public RiveRenderFactory ColorInt clearColor = 0; // If nonzero, the number of MSAA samples to use. // Setting this to a nonzero value forces msaa mode. - int msaaSampleCount = 0; + uint32_t msaaSampleCount = 0; // Use atomic mode (preferred) or msaa instead of rasterOrdering. bool disableRasterOrdering = false; + DitherMode ditherMode = DitherMode::interleavedGradientNoise; + + // If nonzero, frames are split up into virtual tiles of this size. + // + // As of now, each tile gets drawn in a separate render pass. The + // purpose of these virtual tiles, for now, is to break the frame up + // into smaller chunks so that Rive can be pre-empted by other rendering + // processes. This is only supported on Vulkan/non-msaa. + // + // TODO: We could also explore a different type of virtual tiling that + // reduces barriers in atomic mode, but that is not how this feature + // works currently. + uint32_t virtualTileWidth = 0; + uint32_t virtualTileHeight = 0; // Testing flags. bool wireframe = false; @@ -107,7 +134,8 @@ class RenderContext : public RiveRenderFactory // gracefully. (e.g., by falling back on an uber shader or at least not // crashing.) Valid compilations may fail in the real world if the // device is pressed for resources or in a bad state. - bool synthesizeCompilationFailures = false; + gpu::SynthesizedFailureType synthesizedFailureType = + gpu::SynthesizedFailureType::none; #endif }; @@ -210,6 +238,7 @@ class RenderContext : public RiveRenderFactory // Command buffer that rendering commands will be added to. // - VkCommandBuffer on Vulkan. // - id on Metal. + // - WGPUCommandEncoder on WebGPU. // - Unused otherwise. void* externalCommandBuffer = nullptr; @@ -274,12 +303,18 @@ class RenderContext : public RiveRenderFactory size_t) override; rcp decodeImage(Span) override; +#ifdef RIVE_CANVAS + // Creates a RenderCanvas: a GPU texture usable as both a render target + // (for rendering into) and a render image (for compositing into draws). + rcp makeRenderCanvas(uint32_t width, uint32_t height); +#endif + private: friend class Draw; friend class PathDraw; friend class ImageRectDraw; friend class ImageMeshDraw; - friend class StencilClipReset; + friend class ClipReset; friend class ::PushRetrofittedTrianglesGMDraw; // For testing. friend class ::RenderContextTest; // For testing. @@ -299,7 +334,7 @@ class RenderContext : public RiveRenderFactory // LogicalFlush::LayoutCounters. struct ResourceAllocationCounts { - constexpr static int NUM_ELEMENTS = 14; + constexpr static int NUM_ELEMENTS = 19; using VecType = simd::gvec; RIVE_ALWAYS_INLINE VecType toVec() const @@ -311,15 +346,16 @@ class RenderContext : public RiveRenderFactory return vec; } - RIVE_ALWAYS_INLINE ResourceAllocationCounts(const VecType& vec) + static RIVE_ALWAYS_INLINE ResourceAllocationCounts + FromVec(const VecType& vec) { - static_assert(sizeof(*this) == sizeof(size_t) * NUM_ELEMENTS); - static_assert(sizeof(VecType) >= sizeof(*this)); - RIVE_INLINE_MEMCPY(this, &vec, sizeof(*this)); + ResourceAllocationCounts allocs; + static_assert(sizeof(allocs) == sizeof(size_t) * NUM_ELEMENTS); + static_assert(sizeof(VecType) >= sizeof(allocs)); + RIVE_INLINE_MEMCPY(&allocs, &vec, sizeof(allocs)); + return allocs; } - ResourceAllocationCounts() = default; - size_t flushUniformBufferCount = 0; size_t imageDrawUniformBufferCount = 0; size_t pathBufferCount = 0; @@ -333,7 +369,12 @@ class RenderContext : public RiveRenderFactory size_t tessTextureHeight = 0; size_t atlasTextureWidth = 0; size_t atlasTextureHeight = 0; - size_t coverageBufferLength = 0; // clockwiseAtomic mode only. + size_t plsTransientBackingWidth = 0; + size_t plsTransientBackingHeight = 0; + size_t plsTransientBackingPlaneCount = 0; + size_t plsAtomicCoverageBackingWidth = 0; // atomic mode only. + size_t plsAtomicCoverageBackingHeight = 0; // atomic mode only. + size_t coverageBufferLength = 0; // clockwiseAtomic mode only. }; // Reallocates GPU resources and updates m_currentResourceAllocations. @@ -341,7 +382,7 @@ class RenderContext : public RiveRenderFactory // size would not change. void setResourceSizes(ResourceAllocationCounts, bool forceRealloc = false); - void mapResourceBuffers(const ResourceAllocationCounts&); + [[nodiscard]] bool mapResourceBuffers(const ResourceAllocationCounts&); void unmapResourceBuffers(const ResourceAllocationCounts&); // Returns the next coverage buffer prefix to use in a logical flush. @@ -549,6 +590,7 @@ class RenderContext : public RiveRenderFactory uint32_t maxTessTextureHeight = 0; uint32_t maxAtlasWidth = 0; uint32_t maxAtlasHeight = 0; + uint32_t maxPLSTransientBackingPlaneCount = 0; size_t maxCoverageBufferLength = 0; }; @@ -653,12 +695,16 @@ class RenderContext : public RiveRenderFactory // contour ID that is guaranteed to not be the same ID as any neighbors. void pushPaddingVertices(uint32_t count, uint32_t tessLocation); + // Schedules barriers that will be issued immediately before the next + // draw. + void pushBarriers(BarrierFlags); + // Pushes a "midpointFanPatches" draw to the list. Path, contour, and // cubic data are pushed separately. // // Also adds the PathDraw to a dstRead list if one is // required, and if this is the path's first subpass. - void pushMidpointFanDraw( + gpu::DrawBatch& pushMidpointFanDraw( const PathDraw*, gpu::DrawType, uint32_t tessVertexCount, @@ -670,7 +716,7 @@ class RenderContext : public RiveRenderFactory // // Also adds the PathDraw to a dstRead list if one is // required, and if this is the path's first subpass. - void pushOuterCubicsDraw( + gpu::DrawBatch& pushOuterCubicsDraw( const PathDraw*, gpu::DrawType, uint32_t tessVertexCount, @@ -680,27 +726,27 @@ class RenderContext : public RiveRenderFactory // Writes out triangle verties for the desired WindingFaces and pushes // an "interiorTriangulation" draw to the list. // Returns the number of vertices actually written. - size_t pushInteriorTriangulationDraw( + gpu::DrawBatch* pushInteriorTriangulationDraw( const PathDraw*, uint32_t pathID, gpu::WindingFaces, - gpu::ShaderMiscFlags = gpu::ShaderMiscFlags::none); + gpu::ShaderMiscFlags RIVE_DEBUG_CODE(, size_t* vertexCounter)); // Pushes a screen-space rectangle to the draw list, whose pixel // coverage is determined by the atlas region associated with the given // pathID. - void pushAtlasBlit(PathDraw*, uint32_t pathID); + gpu::DrawBatch& pushAtlasBlit(PathDraw*, uint32_t pathID); // Pushes an "imageRect" to the draw list. // This should only be used when we in atomic mode. Otherwise, images // should be drawn as rectangular paths with an image paint. - void pushImageRectDraw(ImageRectDraw*); + gpu::DrawBatch& pushImageRectDraw(ImageRectDraw*); // Pushes an "imageMesh" draw to the list. - void pushImageMeshDraw(ImageMeshDraw*); + gpu::DrawBatch& pushImageMeshDraw(ImageMeshDraw*); - // Pushes a "stencilClipReset" draw to the list. - void pushStencilClipResetDraw(StencilClipReset*); + // Pushes a "clipReset" draw to the list. + gpu::DrawBatch& pushClipResetDraw(ClipReset*); private: friend class TessellationWriter; @@ -722,6 +768,17 @@ class RenderContext : public RiveRenderFactory uint32_t elementCount, uint32_t baseElement); + // Adds a batch to the list of draws that use a dstBarrier. + void addBatchToDstBarrierList(DrawBatch* batch) + { + assert(m_dstBlendBarrierListTail != nullptr); + assert(*m_dstBlendBarrierListTail == nullptr); + assert(batch->nextDstBlendBarrier == nullptr); + assert(enums::is_flag_set(batch->barriers, BarrierFlags::dstBlend)); + *m_dstBlendBarrierListTail = batch; + m_dstBlendBarrierListTail = &batch->nextDstBlendBarrier; + } + // Instance pointer to the outer parent class. RenderContext* const m_ctx; @@ -757,8 +814,9 @@ class RenderContext : public RiveRenderFactory // gpu::DrawBatch objects during writeResources(). std::vector m_draws; IAABB m_combinedDrawBounds; + gpu::DrawContents m_combinedDrawContents; - // Layout state. + // State computed during layout. uint32_t m_pathPaddingCount; uint32_t m_paintPaddingCount; uint32_t m_paintAuxPaddingCount; @@ -768,12 +826,17 @@ class RenderContext : public RiveRenderFactory uint32_t m_outerCubicTessEndLocation; uint32_t m_outerCubicTessVertexIdx; uint32_t m_midpointFanTessVertexIdx; - gpu::GradTextureLayout m_gradTextureLayout; + gpu::ShaderMiscFlags m_baselineShaderMiscFlags; gpu::FlushDescriptor m_flushDesc; BlockAllocatedLinkedList m_drawList; + const DrawBatch* m_firstDstBlendBarrier; + // Final "next" pointer in the list of DrawBatches that have dstBlend + // barriers. + const DrawBatch** m_dstBlendBarrierListTail; + gpu::ShaderFeatures m_combinedShaderFeatures; // Most recent path and contour state. @@ -781,7 +844,7 @@ class RenderContext : public RiveRenderFactory uint32_t m_currentContourID; // Atlas for offscreen feathering. - std::unique_ptr m_atlasRectanizer; + std::unique_ptr m_atlasRectanizer; uint32_t m_atlasMaxX = 0; uint32_t m_atlasMaxY = 0; std::vector m_pendingAtlasDraws; diff --git a/thirdparty/rive_renderer/include/rive/renderer/render_context_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/render_context_impl.hpp index 80eac2605..722f631e1 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/render_context_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/render_context_impl.hpp @@ -5,10 +5,13 @@ #pragma once #include "rive/renderer/render_context.hpp" -#include "rive/renderer/texture.hpp" +#include "rive/texture_archive.hpp" namespace rive::gpu { +#ifdef RIVE_CANVAS +class RenderCanvas; +#endif class Texture; // This class manages GPU buffers and isues the actual rendering commands from @@ -42,8 +45,18 @@ class RenderContextImpl uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) = 0; +#ifdef RIVE_CANVAS + // Creates a RenderCanvas: a GPU texture usable as both a render target + // and a render image. Returns nullptr if not supported by this backend. + virtual rcp makeRenderCanvas(uint32_t width, uint32_t height) + { + return nullptr; + } +#endif + // Resize GPU buffers. These methods cannot fail, and must allocate the // exact size requested. // @@ -67,6 +80,24 @@ class RenderContextImpl virtual void resizeTessVertexSpanBuffer(size_t sizeInBytes) = 0; virtual void resizeTriangleVertexBuffer(size_t sizeInBytes) = 0; + virtual void preBeginFrame(RenderContext*) {} + + // Returns true if the render context should end the drawList with a batch + // of type DrawType::renderPassResolve (and set "manuallyResolved" in the + // flush descriptor). + // This may be used, e.g., to manually resolve MSAA or to transfer pixels + // from an offscreen texture back to the main render target. + virtual bool wantsManualRenderPassResolve( + gpu::InterlockMode, + const RenderTarget*, + const IAABB& renderTargetUpdateBounds, + uint32_t virtualTileWidth, + uint32_t virtualTileHeight, + gpu::DrawContents combinedDrawContents) const + { + return false; + } + // Perform any bookkeeping or other tasks that need to run before // RenderContext begins accessing GPU resources for the flush. (Update // counters, advance buffer pools, etc.) @@ -111,6 +142,19 @@ class RenderContextImpl // Override this method to support atlas feathering. assert(width == 0 && height == 0); } + // Not all APIs support pure memoryless pixel local storage. This optional + // resource is a space to store PLS data that does not persist outside a + // render pass. (Namely, coverage, clip, and scratch.) + // NOTE: It is specified as a TEXTURE_2D_ARRAY because that gets better + // cache performance on Intel Arc than separate textures. + constexpr static uint32_t PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT = 3; + virtual void resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) + {} + // Used in atomic mode. Similar to transient PLS backing, except it's a + // single 2D resource that also supports atomic operations. + virtual void resizeAtomicCoverageBacking(uint32_t width, uint32_t height) {} virtual void resizeCoverageBuffer(size_t sizeInBytes) { // Override this method to support the experimental clockwiseAtomic @@ -136,6 +180,16 @@ class RenderContextImpl // Called after all logical flushes in a frame have completed. virtual void postFlush(const RenderContext::FlushResources&) {} + // Creates a platform-specific command buffer for use with flush(). + // Returns an opaque pointer that should be passed as + // FlushResources::externalCommandBuffer. + // The default implementation returns nullptr (not supported). + virtual void* makeCommandBuffer() { return nullptr; } + + // Commits a command buffer previously created by makeCommandBuffer(). + // Called after flush() to submit the GPU work. + virtual void commitCommandBuffer(void* commandBuffer) {} + // Steady clock, used to determine when we should trim our resource // allocations. virtual double secondsNow() const = 0; @@ -144,3 +198,17 @@ class RenderContextImpl PlatformFeatures m_platformFeatures; }; } // namespace rive::gpu + +#if defined(ORE_BACKEND_GL) && defined(RIVE_CANVAS) +namespace rive +{ +class RiveRenderImage; +// Returns a Y-flipped companion of a GL canvas texture, or nullptr on +// non-GL backends. Hides the RenderContextGLImpl downcast so callers +// don't need GL headers. +rcp getCanvasImportMirrorGL(gpu::RenderContext*, + gpu::Texture* sourceTex, + uint32_t width, + uint32_t height); +} // namespace rive +#endif diff --git a/thirdparty/rive_renderer/include/rive/renderer/rive_render_image.hpp b/thirdparty/rive_renderer/include/rive/renderer/rive_render_image.hpp index 38ced55ed..d901ac77f 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/rive_render_image.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/rive_render_image.hpp @@ -4,7 +4,11 @@ #pragma once +#include "rive/renderer.hpp" #include "rive/renderer/texture.hpp" +#ifdef __EMSCRIPTEN__ +#include +#endif namespace rive { @@ -18,7 +22,7 @@ class RiveRenderImage : public LITE_RTTI_OVERRIDE(RenderImage, RiveRenderImage) } rcp refTexture() const { return m_texture; } - const gpu::Texture* getTexture() const { return m_texture.get(); } + gpu::Texture* getTexture() { return m_texture.get(); } protected: RiveRenderImage(int width, int height) diff --git a/thirdparty/rive_renderer/include/rive/renderer/rive_renderer.hpp b/thirdparty/rive_renderer/include/rive/renderer/rive_renderer.hpp index 1fb60049b..dd8d930e3 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/rive_renderer.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/rive_renderer.hpp @@ -47,6 +47,7 @@ class RiveRenderer : public Renderer uint32_t indexCount, BlendMode, float opacity) override; + void modulateOpacity(float opacity) override; // Determines if a path is an axis-aligned rectangle that can be represented // by rive::AABB. @@ -62,6 +63,10 @@ class RiveRenderer : public Renderer { return m_stack.back().clipRectMatrix; } + float currentModulatedOpacity() const + { + return m_stack.back().modulatedOpacity; + } #endif private: @@ -93,6 +98,7 @@ class RiveRenderer : public Renderer Mat2D clipRectMatrix; const gpu::ClipRectInverseMatrix* clipRectInverseMatrix = nullptr; bool clipIsEmpty = false; + float modulatedOpacity = 1.0f; }; std::vector m_stack{1}; diff --git a/thirdparty/rive_renderer/include/rive/renderer/shader_compilation_mode.hpp b/thirdparty/rive_renderer/include/rive/renderer/shader_compilation_mode.hpp new file mode 100644 index 000000000..f54fe7825 --- /dev/null +++ b/thirdparty/rive_renderer/include/rive/renderer/shader_compilation_mode.hpp @@ -0,0 +1,18 @@ +/* + * Copyright 2026 Rive + */ + +#pragma once + +namespace rive::gpu +{ +enum class ShaderCompilationMode +{ + allowAsynchronous, + alwaysSynchronous, + onlyUbershaders, + + // The default mode is to allow asynchronous compilation where available. + standard = allowAsynchronous, +}; +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/include/rive/renderer/sk_rectanizer_skyline.hpp b/thirdparty/rive_renderer/include/rive/renderer/sk_rectanizer_skyline.hpp index 1b78d058d..3ad4bc417 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/sk_rectanizer_skyline.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/sk_rectanizer_skyline.hpp @@ -15,7 +15,7 @@ #include #include -namespace skgpu +namespace rive { // Pack rectangles and track the current silhouette // Based, in part, on Jukka Jylanki's work at http://clb.demon.fi @@ -82,4 +82,4 @@ class RectanizerSkyline // at x,y. void addSkylineLevel(int skylineIndex, int x, int y, int width, int height); }; -} // End of namespace skgpu +} // End of namespace rive diff --git a/thirdparty/rive_renderer/include/rive/renderer/stack_vector.hpp b/thirdparty/rive_renderer/include/rive/renderer/stack_vector.hpp index 736b43c72..a5462f2c4 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/stack_vector.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/stack_vector.hpp @@ -26,6 +26,30 @@ template class StackVector return m_data[index]; } + const T& front() const + { + assert(m_size > 0); + return m_data[0]; + } + + T& front() + { + assert(m_size > 0); + return m_data[0]; + } + + const T& back() const + { + assert(m_size > 0); + return m_data[m_size - 1]; + } + + T& back() + { + assert(m_size > 0); + return m_data[m_size - 1]; + } + T& push_back(const T& ele) { T* ret = push(1); @@ -54,8 +78,19 @@ template class StackVector } const T* data() const { return m_data; } + T* data() { return m_data; } + + const T* dataOrNull() const { return m_size != 0 ? m_data : nullptr; } + T* dataOrNull() { return m_size != 0 ? m_data : nullptr; } + const uint32_t size() const { return m_size; } + T* begin() { return m_data; } + T* end() { return m_data + m_size; } + + const T* begin() const { return m_data; } + const T* end() const { return m_data + m_size; } + private: uint32_t m_size = 0; T m_data[MAX_CAPACITY]; @@ -73,7 +108,7 @@ template class StackVector return ret; } - static_assert(std::is_pod::value == - true); // Currently only supports POD types + // Currently only supports POD types. + static_assert(std::is_pod::value == true); }; } // namespace rive diff --git a/thirdparty/rive_renderer/include/rive/renderer/texture.hpp b/thirdparty/rive_renderer/include/rive/renderer/texture.hpp index ff3021c88..8c7cc5f2b 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/texture.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/texture.hpp @@ -5,7 +5,6 @@ #pragma once #include "rive/refcnt.hpp" -#include "rive/renderer/render_context_impl.hpp" namespace rive::gpu { @@ -15,6 +14,9 @@ class Texture : public RefCnt Texture(uint32_t width, uint32_t height); virtual ~Texture() {} + Texture(const Texture&) = delete; + Texture& operator=(const Texture&) = delete; + uint32_t width() const { return m_width; } uint32_t height() const { return m_height; } @@ -22,6 +24,12 @@ class Texture : public RefCnt // this class. uint32_t textureResourceHash() const { return m_textureResourceHash; } + // Returns the backend-native texture handle (id, GLuint, + // VkImage, etc.) as a void pointer. Used by + // ore::Context::wrapRiveTexture() to bridge Rive renderer images into the + // Ore GPU abstraction. Default returns nullptr (backend must override). + virtual void* nativeHandle() const { return nullptr; } + protected: uint32_t m_width; uint32_t m_height; diff --git a/thirdparty/rive_renderer/include/rive/renderer/trivial_block_allocator.hpp b/thirdparty/rive_renderer/include/rive/renderer/trivial_block_allocator.hpp index a0aeb5b2a..68b551392 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/trivial_block_allocator.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/trivial_block_allocator.hpp @@ -139,16 +139,22 @@ template class BlockAllocatedLinkedList bool empty() const { return count() == 0; } - T& tail() const + T* tail() const { assert(!empty()); - return m_tail->data; + return m_tail; + } + + T* head() const + { + assert(!empty()); + return m_head; } template - T& emplace_back(TrivialBlockAllocator& allocator, Args... args) + T* emplace_back(TrivialBlockAllocator& allocator, Args... args) { - Node* node = allocator.make(std::forward(args)...); + T* node = allocator.make(std::forward(args)...); assert(static_cast(m_head) == static_cast(m_tail)); if (m_head == nullptr) { @@ -160,7 +166,7 @@ template class BlockAllocatedLinkedList } m_tail = node; ++m_count; - return m_tail->data; + return m_tail; } void reset() @@ -170,28 +176,19 @@ template class BlockAllocatedLinkedList m_count = 0; } - struct Node - { - template - Node(Args... args) : data(std::forward(args)...) - {} - T data; - Node* next = nullptr; - }; - template class Iter { public: - Iter(Node* current) : m_current(current) {} + Iter(T* current) : m_current(current) {} bool operator!=(const Iter& other) const { return m_current != other.m_current; } void operator++() { m_current = m_current->next; } - U& operator*() { return m_current->data; } + U& operator*() { return *m_current; } private: - Node* m_current; + const T* m_current; }; Iter begin() { return {m_head}; } Iter end() { return {nullptr}; } @@ -199,8 +196,8 @@ template class BlockAllocatedLinkedList Iter end() const { return {nullptr}; } private: - Node* m_head = nullptr; - Node* m_tail = nullptr; + T* m_head = nullptr; + T* m_tail = nullptr; size_t m_count = 0; }; diff --git a/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp index 32c23bf3a..c146652b4 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp @@ -4,31 +4,72 @@ #pragma once -#include "rive/renderer/render_context_impl.hpp" -#include "rive/renderer/vulkan/vulkan_context.hpp" +#ifdef RIVE_VULKAN + #include -#include #include -#include "rive/shapes/paint/image_sampler.hpp" +#include "rive/renderer/render_context_impl.hpp" +#include "rive/renderer/vulkan/vulkan_context.hpp" namespace rive::gpu { +class DrawPipelineLayoutVulkan; +class RenderTargetVulkan; class RenderTargetVulkanImpl; -class DrawShaderVulkan; +class PipelineManagerVulkan; +enum class RenderPassOptionsVulkan; class RenderContextVulkanImpl : public RenderContextImpl { public: + struct ContextOptions + { + bool forceAtomicMode = false; + + // Dithering does better when we evaluate our blend equations in medium + // precision from the fragment shader, vs letting it happen in the blend + // unit (which, presumably, must be lower precision). For this reason, + // an app may wish to disable "fixed function" rendering for clockwise + // mode. + bool disableClockwiseFixedFunctionMode = false; + + ShaderCompilationMode shaderCompilationMode = + ShaderCompilationMode::standard; + }; + + static std::unique_ptr MakeContext(VkInstance, + VkPhysicalDevice, + VkDevice, + const VulkanFeatures&, + PFN_vkGetInstanceProcAddr, + const ContextOptions&); + static std::unique_ptr MakeContext( - VkInstance, - VkPhysicalDevice, - VkDevice, - const VulkanFeatures&, - PFN_vkGetInstanceProcAddr); + VkInstance instance, + VkPhysicalDevice physicalDevice, + VkDevice device, + const VulkanFeatures& vulkanFeatures, + PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) + { + return MakeContext(instance, + physicalDevice, + device, + vulkanFeatures, + fp_vkGetInstanceProcAddr, + ContextOptions{}); + } + ~RenderContextVulkanImpl(); VulkanContext* vulkanContext() const { return m_vk.get(); } + // Set the queue and queue family index used by makeCommandBuffer(). + // Must be called before any ScriptedCanvas flush. + void setCanvasQueue(VkQueue queue, uint32_t queueFamilyIndex); + + void* makeCommandBuffer() override; + void commitCommandBuffer(void* commandBuffer) override; + rcp makeRenderTarget( uint32_t width, uint32_t height, @@ -42,16 +83,40 @@ class RenderContextVulkanImpl : public RenderContextImpl rcp makeImageTexture(uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) override; +#ifdef RIVE_CANVAS + rcp makeRenderCanvas(uint32_t width, + uint32_t height) override; +#endif + void hotloadShaders(rive::Span spirvData); + void startAsyncPipelineCreation(InterlockMode, + VkFormat framebufferFormat, + VkImageUsageFlags framebufferUsage, + LoadAction colorLoadAction); + + void startAsyncPipelineCreation(InterlockMode, + RenderTargetVulkan& renderTarget, + LoadAction); + + void waitForAsyncPipelineCreation(); + private: - RenderContextVulkanImpl(rcp, - const VkPhysicalDeviceProperties&); + RenderContextVulkanImpl(rcp, const ContextOptions&); // Called outside the constructor so we can use virtual methods. - void initGPUObjects(); + void initGPUObjects(ShaderCompilationMode); + + bool wantsManualRenderPassResolve( + gpu::InterlockMode, + const RenderTarget*, + const IAABB& renderTargetUpdateBounds, + uint32_t virtualTileWidth, + uint32_t virtualTileHeight, + gpu::DrawContents combinedDrawContents) const override; void prepareToFlush(uint64_t nextFrameNumber, uint64_t safeFrameNumber) override; @@ -107,8 +172,48 @@ class RenderContextVulkanImpl : public RenderContextImpl void resizeGradientTexture(uint32_t width, uint32_t height) override; void resizeTessellationTexture(uint32_t width, uint32_t height) override; void resizeAtlasTexture(uint32_t width, uint32_t height) override; + void resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) override; + void resizeAtomicCoverageBacking(uint32_t width, uint32_t height) override; void resizeCoverageBuffer(size_t sizeInBytes) override; + // Lazy accessors for PLS backing resources. These are lazy because our + // Vulkan backend needs different allocations based on interlock mode and + // other factors. + vkutil::Image* plsTransientImageArray(); + vkutil::ImageView* plsTransientCoverageView(); + vkutil::ImageView* plsTransientClipView(); + rcp makePLSTransientImageView(VkFormat, + uint32_t index, + const char* debugName); + // Used by rasterOrdering to stash the original dst color before overwriting + // it, and by atomic as the clip buffer. + vkutil::Texture2D* plsTransientScratchColorTexture(); + // Used by clockwise and clockwiseAtomic to save an intermediate RGB blend + // color across overlapping fragments. + vkutil::Texture2D* plsBlendStorageTexture_RGB10_A2(); + // Used by clockwiseAtomic as the clip buffer. + vkutil::Texture2D* plsTransientClipTexture_R16F(); + + // The offscreen color texture is not transient and supports PLS. It is used + // in place of the renderTarget (via copying in and out) when the + // renderTarget doesn't support PLS. + vkutil::Texture2D* accessPLSOffscreenColorTexture( + VkCommandBuffer, + const vkutil::ImageAccess&, + vkutil::ImageAccessAction = + vkutil::ImageAccessAction::preserveContents); + vkutil::Texture2D* clearPLSOffscreenColorTexture( + VkCommandBuffer, + ColorInt, + const vkutil::ImageAccess& dstAccessAfterClear); + vkutil::Texture2D* copyRenderTargetToPLSOffscreenColorTexture( + VkCommandBuffer, + RenderTargetVulkan*, + const IAABB& copyBounds, + const vkutil::ImageAccess& dstAccessAfterCopy); + // Wraps a VkDescriptorPool created specifically for a PLS flush, and tracks // its allocated descriptor sets. class DescriptorSetPool final : public vkutil::Resource @@ -124,8 +229,114 @@ class RenderContextVulkanImpl : public RenderContextImpl VkDescriptorPool m_vkDescriptorPool; }; + // Pool of DescriptorSetPool instances. + class DescriptorSetPoolPool : public GPUResourcePool + { + public: + constexpr static size_t MAX_POOL_SIZE = 64; + DescriptorSetPoolPool(rcp manager) : + GPUResourcePool(std::move(manager), MAX_POOL_SIZE) + {} + + rcp acquire(); + }; + + // High-level allocator of VkDescriptorSets. These are intended to be scoped + // to a single flush. + class DescriptorSetAllocator + { + public: + DescriptorSetAllocator(RenderContextVulkanImpl*); + ~DescriptorSetAllocator(); + + const VkDescriptorSet& perFlushDescriptorSet() const + { + return m_perFlushDescriptorSet; + } + + VkDescriptorSet allocatePerDrawDescriptorSet(); + VkDescriptorSet allocateDescriptorSet(VkDescriptorSetLayout); + + private: + const rcp m_descriptorSetPoolPool; + rcp m_descriptorSetPool; + const VkDescriptorSet m_perFlushDescriptorSet; + const VkDescriptorSetLayout m_perDrawDescriptorSetLayout; + // Image textures are the only binding that can be updated multiple + // times per flush, and a VkDescriptorSetPool can only update a fixed + // number of image bindings, so we track this in order to know when it's + // time to allocate a new pool. + uint32_t m_imageTextureUpdateCount = 0; + }; + + // Encapsulates state for the main "draw" render pass, providing mechanisms + // to restart and interrupt if needed. + class DrawRenderPass + { + public: + DrawRenderPass(RenderContextVulkanImpl*, + const FlushDescriptor&, + gpu::LoadAction overrideColorLoadAction, + const IAABB& drawBounds, + VkImageView colorImageView, + VkImageView msaaColorSeedImageView, + VkImageView msaaResolveImageView, + RenderPassOptionsVulkan, + const IAABB& scissor); + + const IAABB& drawBounds() const { return m_drawBounds; } + const IAABB& scissor() const { return m_scissor; } + + const DrawPipelineLayoutVulkan& pipelineLayout() const + { + return m_pipelineLayout; + } + + RenderPassOptionsVulkan renderPassOptions() const + { + return m_renderPassOptions; + } + + // Ends the current render pass and starts a new one with the given + // properties. + void restart(gpu::LoadAction colorLoadAction, + RenderPassOptionsVulkan renderPassOptions, + const IAABB& scissor); + + // Some early Android tilers are known to crash when a render pass is + // too complex. This is a mechanism to interrupt and begin a new render + // pass on affected devices after a pre-set, internal complexity is + // reached. + void interruptIfNeeded(uint32_t nextTessPatchCount, + uint32_t pendingTessPatchCount); + + private: + const DrawPipelineLayoutVulkan& begin( + gpu::LoadAction overrideColorLoadAction, + RenderPassOptionsVulkan, + const IAABB& scissor); + + RenderContextVulkanImpl* const m_impl; + const FlushDescriptor& m_desc; + const IAABB m_drawBounds; + const VkImageView m_colorImageView; + const VkImageView m_msaaColorSeedImageView; + const VkImageView m_msaaResolveImageView; + const DrawPipelineLayoutVulkan& m_pipelineLayout; + + // Initialized by beginDrawRenderPass(). + RenderPassOptionsVulkan m_renderPassOptions; + IAABB m_scissor; + uint32_t m_patchCountInCurrentDrawPass; + }; + void flush(const FlushDescriptor&) override; + void submitDrawList(const FlushDescriptor&, + DescriptorSetAllocator*, + DrawRenderPass*, + uint32_t pendingTessPatchCount); + void postFlush(const RenderContext::FlushResources&) override; double secondsNow() const override @@ -135,8 +346,36 @@ class RenderContextVulkanImpl : public RenderContextImpl } const rcp m_vk; - const uint32_t m_vendorID; - const VkFormat m_atlasFormat; + + // Canvas command buffer support (set via setCanvasQueue). + VkQueue m_canvasQueue = VK_NULL_HANDLE; + uint32_t m_canvasQueueFamilyIndex = 0; + VkCommandPool m_canvasCommandPool = VK_NULL_HANDLE; + + struct DriverWorkarounds + { + // Some early Android tilers are known to crash when a render pass is + // too complex. On these devices, we limit the maximum number of + // instances that can be issued in a single render pass. + uint32_t maxInstancesPerRenderPass = UINT32_MAX; + bool needsInterruptibleRenderPasses() const + { + // If we have a limit on maxInstancesPerRenderPass, then our render + // passes need to be interruptible so we can close them off and + // start new ones in case we encounter too many instances. + return maxInstancesPerRenderPass != UINT32_MAX; + } + // Early Xclipse drivers struggle with our manual msaa resolve, so we + // always do automatic fullscreen resolves on that GPU family. + bool avoidManualMSAAResolves = false; + // Some Android drivers (some Android 12 and earlier Adreno drivers) + // have issues with having both a self-dependency for dst reads and + // resolve attachments. For now we just always manually resolve these + // render passes that use advanced blend on Qualcomm. + bool needsManualMSAAResolveAfterDstRead = true; + }; + + const DriverWorkarounds m_workarounds; // Rive buffer pools. These don't need to be rcp<> because the destructor of // RenderContextVulkanImpl is already synchronized. @@ -165,26 +404,12 @@ class RenderContextVulkanImpl : public RenderContextImpl std::chrono::steady_clock::time_point m_localEpoch = std::chrono::steady_clock::now(); - // Samplers. - VkSampler m_linearSampler; - VkSampler m_imageSamplers[ImageSampler::MAX_SAMPLER_PERMUTATIONS]; - // Bound when there is not an image paint. rcp m_nullImageTexture; - // With the exception of PLS texture bindings, which differ by interlock - // mode, all other shaders use the same shared descriptor set layouts. - VkDescriptorSetLayout m_perFlushDescriptorSetLayout; - VkDescriptorSetLayout m_perDrawDescriptorSetLayout; - VkDescriptorSetLayout m_immutableSamplerDescriptorSetLayout; - VkDescriptorSetLayout m_emptyDescriptorSetLayout; // For when a set isn't - // used by a shader. - VkDescriptorPool m_staticDescriptorPool; // For descriptorSets that never - // change between frames. - VkDescriptorSet m_nullImageDescriptorSet; - VkDescriptorSet m_immutableSamplerDescriptorSet; // Empty since samplers are - // immutable, but also - // required by Vulkan. + // Common base class for a pipeline that renders a texture resource at the + // beginning of a flush, which is then read during the main draw pass. + class ResourceTexturePipeline; // Renders color ramps to the gradient texture. class ColorRampPipeline; @@ -197,6 +422,7 @@ class RenderContextVulkanImpl : public RenderContextImpl std::unique_ptr m_tessellatePipeline; rcp m_tessSpanIndexBuffer; rcp m_tessTexture; + rcp m_tesselationSyncIssueWorkaroundTexture; rcp m_tessTextureFramebuffer; // Renders feathers to the atlas. @@ -205,60 +431,22 @@ class RenderContextVulkanImpl : public RenderContextImpl rcp m_atlasTexture; rcp m_atlasFramebuffer; + // Pixel local storage backing resources. + VkImageUsageFlags m_plsTransientUsageFlags; + VkExtent3D m_plsExtent = {0, 0, 1}; + uint32_t m_plsTransientPlaneCount = 0; + rcp m_plsTransientImageArray; + rcp m_plsTransientCoverageView; + rcp m_plsTransientClipView; + rcp m_plsTransientScratchColorTexture; + rcp m_plsBlendStorageTexture_RGB10_A2; + rcp m_plsTransientClipTexture_R16F; + rcp m_plsOffscreenColorTexture; + rcp m_plsAtomicCoverageTexture; + // Coverage buffer used by shaders in clockwiseAtomic mode. rcp m_coverageBuffer; - // Rive-specific options for configuring a flush's VkPipelineLayout. - enum class DrawPipelineLayoutOptions - { - none = 0, - - // No need to attach the COLOR texture as an input attachment. There are - // no advanced blend modes so we can use built-in hardware blending. - fixedFunctionColorOutput = 1 << 0, - - // Use an offscreen texture to render color, but also attach the real - // target texture at the COALESCED_ATOMIC_RESOLVE index, and render to - // it directly in the atomic resolve step. - coalescedResolveAndTransfer = 1 << 1, - }; - constexpr static int DRAW_PIPELINE_LAYOUT_OPTION_COUNT = 2; - - // A VkPipelineLayout for each - // interlockMode x [all DrawPipelineLayoutOptions permutations]. - constexpr static uint32_t DrawPipelineLayoutIdx( - gpu::InterlockMode interlockMode, - DrawPipelineLayoutOptions options) - { - return (static_cast(interlockMode) - << DRAW_PIPELINE_LAYOUT_OPTION_COUNT) | - static_cast(options); - } - constexpr static int DRAW_PIPELINE_LAYOUT_COUNT = - gpu::kInterlockModeCount * (1 << DRAW_PIPELINE_LAYOUT_OPTION_COUNT); - constexpr static int DRAW_PIPELINE_LAYOUT_BIT_COUNT = - DRAW_PIPELINE_LAYOUT_OPTION_COUNT + 2; - static_assert((1 << DRAW_PIPELINE_LAYOUT_BIT_COUNT) >= - DRAW_PIPELINE_LAYOUT_COUNT); - static_assert((1 << (DRAW_PIPELINE_LAYOUT_BIT_COUNT - 1)) < - DRAW_PIPELINE_LAYOUT_COUNT); - RIVE_DECL_ENUM_BITSET_FRIENDS(DrawPipelineLayoutOptions); - - // VkPipelineLayout wrapper for Rive flushes. - class DrawPipelineLayout; - std::array, DRAW_PIPELINE_LAYOUT_COUNT> - m_drawPipelineLayouts; - - // VkRenderPass wrapper for Rive flushes. - class RenderPass; - std::unordered_map> m_renderPasses; - - // VkPipeline wrapper for Rive draw calls. - class DrawPipeline; - std::unordered_map> - m_drawShaders; - std::unordered_map> m_drawPipelines; - // Gaussian integral table for feathering. rcp m_featherTexture; @@ -267,19 +455,10 @@ class RenderContextVulkanImpl : public RenderContextImpl rcp m_imageRectVertexBuffer; rcp m_imageRectIndexBuffer; - // Pool of DescriptorSetPool instances for flushing. - class DescriptorSetPoolPool : public GPUResourcePool - { - public: - constexpr static size_t MAX_POOL_SIZE = 64; - DescriptorSetPoolPool(rcp manager) : - GPUResourcePool(std::move(manager), MAX_POOL_SIZE) - {} - - rcp acquire(); - }; - rcp m_descriptorSetPoolPool; + + std::unique_ptr m_pipelineManager; }; -RIVE_MAKE_ENUM_BITSET(RenderContextVulkanImpl::DrawPipelineLayoutOptions); } // namespace rive::gpu + +#endif diff --git a/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_target_vulkan.hpp b/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_target_vulkan.hpp index b22b3ed49..6111f9eaf 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_target_vulkan.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/vulkan/render_target_vulkan.hpp @@ -19,16 +19,26 @@ class RenderTargetVulkan : public RenderTarget return m_targetUsageFlags; } - // Returns the target image in the requested layout, performing a pipeline - // barrier if necessary. + // Raw handle accessors — no layout transition. Used by ORE to wrap the + // canvas backing image at wrapCanvasTexture() time. + virtual VkImage targetImage() const = 0; + virtual VkImageView targetImageView() const = 0; + + // Called by ORE's RenderPass::finish() after it has transitioned the image + // to SHADER_READ_ONLY_OPTIMAL, so Rive's own barrier logic sees the correct + // layout on the next draw. + virtual void updateLastAccess(const vkutil::ImageAccess&) {} + + // Performs a pipeline barrier and returns the target image in the requested + // layout. virtual VkImage accessTargetImage( VkCommandBuffer, const vkutil::ImageAccess& dstAccess, vkutil::ImageAccessAction = vkutil::ImageAccessAction::preserveContents) = 0; - // Returns the target image view, with its image in the requested layout, - // performing a pipeline barrier if necessary. + // Performs a pipeline barrier, transitions the target image to the + // requested layout, and returns the target image view. virtual VkImageView accessTargetImageView( VkCommandBuffer, const vkutil::ImageAccess& dstAccess, @@ -44,26 +54,33 @@ class RenderTargetVulkan : public RenderTarget VkFormat framebufferFormat, VkImageUsageFlags targetUsageFlags); - // Returns the offscreen texture in the requested layout, performing a - // pipeline barrier if necessary. + // Performs pipeline barriers, clears the target image, transitions the + // target image to the requested layout, and returns target image view. + VkImageView clearTargetImageView( + VkCommandBuffer, + ColorInt clearColor, + const vkutil::ImageAccess& dstAccessAfterClear); + + // Performs a pipeline barrier and returns the offscreen texture in the + // requested layout. vkutil::Texture2D* accessOffscreenColorTexture( VkCommandBuffer, const vkutil::ImageAccess& dstAccess, vkutil::ImageAccessAction = vkutil::ImageAccessAction::preserveContents); - // InterlockMode::rasterOrdering. - vkutil::Texture2D* clipTextureR32UI(); - vkutil::Texture2D* scratchColorTexture(); - vkutil::Texture2D* coverageTexture(); - - // InterlockMode::atomics. - vkutil::Texture2D* clipTextureRGBA8(); - vkutil::Texture2D* coverageAtomicTexture(); + // Performs pipeline barriers, copies the target image into the + // offscreen color texture (for the intended purpose of supporting + // gpu::LoadAction::preserveRenderTarget), and returns the offscreen texture + // in the requested layout. + vkutil::Texture2D* copyTargetImageToOffscreenColorTexture( + VkCommandBuffer, + const vkutil::ImageAccess& dstAccessAfterCopy, + const IAABB& copyBounds); // InterlockMode::msaa. - vkutil::Texture2D* depthStencilTexture(); - vkutil::ImageView* depthStencilTextureView(); + vkutil::Texture2D* msaaColorTexture(); + vkutil::Texture2D* msaaDepthStencilTexture(); const rcp m_vk; const VkFormat m_framebufferFormat; @@ -73,17 +90,9 @@ class RenderTargetVulkan : public RenderTarget // VK_ACCESS_INPUT_ATTACHMENT_READ_BIT rcp m_offscreenColorTexture; - // InterlockMode::rasterOrdering. - rcp m_clipTextureR32UI; - rcp m_scratchColorTexture; - rcp m_coverageTexture; - - // InterlockMode::atomics. - rcp m_clipTextureRGBA8; - rcp m_coverageAtomicTexture; - // InterlockMode::msaa. - rcp m_depthStencilTexture; + rcp m_msaaColorTexture; + rcp m_msaaDepthStencilTexture; }; class RenderTargetVulkanImpl : public RenderTargetVulkan @@ -115,6 +124,14 @@ class RenderTargetVulkanImpl : public RenderTargetVulkan return m_targetLastAccess; } + VkImage targetImage() const override { return m_targetImage; } + VkImageView targetImageView() const override { return m_targetImageView; } + + void updateLastAccess(const vkutil::ImageAccess& a) override + { + m_targetLastAccess = a; + } + VkImage accessTargetImage( VkCommandBuffer, const vkutil::ImageAccess& dstAccess, diff --git a/thirdparty/rive_renderer/include/rive/renderer/vulkan/vkutil.hpp b/thirdparty/rive_renderer/include/rive/renderer/vulkan/vkutil.hpp index 868080cb6..8944f5538 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/vulkan/vkutil.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/vulkan/vkutil.hpp @@ -22,12 +22,15 @@ class VulkanContext; namespace rive::gpu::vkutil { +const char* string_from_vk_result(VkResult); + inline static void vk_check(VkResult res, const char* file, int line) { if (res != VK_SUCCESS) { fprintf(stderr, - "Vulkan error %i at line: %i in file: %s\n", + "Vulkan error %s (%i) at line: %i in file: %s\n", + string_from_vk_result(res), res, line, file); @@ -112,6 +115,9 @@ class BufferPool : public GPUResourcePool public: BufferPool(rcp, VkBufferUsageFlags, VkDeviceSize size = 0); + BufferPool(const BufferPool&) = delete; + BufferPool& operator=(const BufferPool&) = delete; + VkDeviceSize size() const { return m_targetSize; } void setTargetSize(VkDeviceSize size); @@ -144,7 +150,7 @@ class Image : public Resource private: friend class ::rive::gpu::VulkanContext; - Image(rcp, const VkImageCreateInfo&); + Image(rcp, const VkImageCreateInfo&, const char* name); VkImageCreateInfo m_info; VmaAllocation m_vmaAllocation; @@ -166,7 +172,8 @@ class ImageView : public Resource ImageView(rcp, rcp textureRef, - const VkImageViewCreateInfo&); + const VkImageViewCreateInfo&, + const char* name); const rcp m_textureRefOrNull; VkImageViewCreateInfo m_info; @@ -207,12 +214,12 @@ class Texture2D : public rive::gpu::Texture return m_imageView->vkImageViewAddressOf(); } ImageAccess& lastAccess() { return m_lastAccess; } + void* nativeHandle() const override { return (void*)vkImage(); } // Deferred mechanism for uploading image data without a command buffer. - void stageContentsForUpload(const void* imageData, - size_t imageDataSizeInBytes); - bool hasUpdates() const { return m_imageUploadBuffer != nullptr; } - void synchronize(VkCommandBuffer); + void scheduleUpload(const void* imageDataRGBAPremul, + size_t imageDataSizeInBytes); + void scheduleUpload(rcp imageBufferRGBAPremul); void barrier(VkCommandBuffer, const ImageAccess& dstAccess, @@ -226,6 +233,44 @@ class Texture2D : public rive::gpu::Texture // point. void generateMipmaps(VkCommandBuffer, const ImageAccess& dstAccess); + // These methods are inlined intentionally, in order to avoid function calls + // in the common usecase. + inline void prepareForVertexOrFragmentShaderRead( + VkCommandBuffer commandBuffer) + { + if (m_imageUploadBuffer != nullptr) + { + applyImageUploadBuffer(commandBuffer); + } + constexpr static ImageAccess READ_ACCESS = { + .pipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = VK_ACCESS_SHADER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + if (m_lastAccess != READ_ACCESS) + { + barrier(commandBuffer, READ_ACCESS); + } + } + + inline void prepareForFragmentShaderRead(VkCommandBuffer commandBuffer) + { + if (m_imageUploadBuffer != nullptr) + { + applyImageUploadBuffer(commandBuffer); + } + constexpr static ImageAccess READ_ACCESS = { + .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = VK_ACCESS_SHADER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + if (m_lastAccess != READ_ACCESS) + { + barrier(commandBuffer, READ_ACCESS); + } + } + // Simple mechanism for caching and reusing a descriptor set for this // texture within a frame. VkDescriptorSet getCachedDescriptorSet(uint64_t frameNumber, @@ -249,7 +294,9 @@ class Texture2D : public rive::gpu::Texture protected: friend class ::rive::gpu::VulkanContext; - Texture2D(rcp vk, VkImageCreateInfo); + void applyImageUploadBuffer(VkCommandBuffer); + + Texture2D(rcp vk, VkImageCreateInfo, const char* name); rcp m_image; rcp m_imageView; @@ -368,4 +415,13 @@ inline VkFormat get_preferred_depth_stencil_format(bool isD24S8Supported) return isD24S8Supported ? VK_FORMAT_D24_UNORM_S8_UINT : VK_FORMAT_D32_SFLOAT_S8_UINT; } + +inline VkRect2D rect2d(const IAABB& iaabb) +{ + return { + .offset = {iaabb.left, iaabb.top}, + .extent = {static_cast(iaabb.width()), + static_cast(iaabb.height())}, + }; +} } // namespace rive::gpu::vkutil diff --git a/thirdparty/rive_renderer/include/rive/renderer/vulkan/vulkan_context.hpp b/thirdparty/rive_renderer/include/rive/renderer/vulkan/vulkan_context.hpp index 5f4e9c0c6..581ea6dcf 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/vulkan/vulkan_context.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/vulkan/vulkan_context.hpp @@ -16,15 +16,27 @@ namespace rive::gpu // supported. struct VulkanFeatures { - uint32_t apiVersion = VK_API_VERSION_1_0; + uint32_t apiVersion = VK_API_VERSION_1_1; // VkPhysicalDeviceFeatures. bool independentBlend = false; bool fillModeNonSolid = false; bool fragmentStoresAndAtomics = false; + bool shaderClipDistance = false; // EXT_rasterization_order_attachment_access. bool rasterizationOrderColorAttachmentAccess = false; + + // VK_EXT_fragment_shader_interlock. + bool fragmentShaderPixelInterlock = false; + + // Indicates a nonconformant driver, like MoltenVK. + bool VK_KHR_portability_subset = false; + + // VkPhysicalDeviceFeatures – texture compression. + bool textureCompressionBC = false; // BC1/BC2/BC3/BC7 + bool textureCompressionASTC_LDR = false; // ASTC LDR + bool textureCompressionETC2 = false; // ETC2 }; // Wraps a VkDevice, function dispatch table, and VMA library instance. @@ -54,10 +66,13 @@ class VulkanContext : public GPUResourceManager #define RIVE_VULKAN_INSTANCE_COMMANDS(F) \ F(GetDeviceProcAddr) \ F(GetPhysicalDeviceFormatProperties) \ - F(GetPhysicalDeviceProperties) + F(GetPhysicalDeviceProperties) \ + F(SetDebugUtilsObjectNameEXT) #define RIVE_VULKAN_DEVICE_COMMANDS(F) \ + F(AllocateCommandBuffers) \ F(AllocateDescriptorSets) \ + F(BeginCommandBuffer) \ F(CmdBeginRenderPass) \ F(CmdBindDescriptorSets) \ F(CmdBindIndexBuffer) \ @@ -74,6 +89,7 @@ class VulkanContext : public GPUResourceManager F(CmdPipelineBarrier) \ F(CmdSetScissor) \ F(CmdSetViewport) \ + F(CreateCommandPool) \ F(CreateDescriptorPool) \ F(CreateDescriptorSetLayout) \ F(CreateFramebuffer) \ @@ -83,6 +99,7 @@ class VulkanContext : public GPUResourceManager F(CreateRenderPass) \ F(CreateSampler) \ F(CreateShaderModule) \ + F(DestroyCommandPool) \ F(DestroyDescriptorPool) \ F(DestroyDescriptorSetLayout) \ F(DestroyFramebuffer) \ @@ -92,6 +109,10 @@ class VulkanContext : public GPUResourceManager F(DestroyRenderPass) \ F(DestroySampler) \ F(DestroyShaderModule) \ + F(EndCommandBuffer) \ + F(FreeCommandBuffers) \ + F(QueueSubmit) \ + F(QueueWaitIdle) \ F(ResetDescriptorPool) \ F(UpdateDescriptorSets) @@ -102,18 +123,26 @@ class VulkanContext : public GPUResourceManager VmaAllocator allocator() const { return m_vmaAllocator; } + const VkPhysicalDeviceProperties& physicalDeviceProperties() const + { + return m_physicalDeviceProperties; + } + bool isFormatSupportedWithFeatureFlags(VkFormat, VkFormatFeatureFlagBits); bool supportsD24S8() const { return m_supportsD24S8; } // Resource allocation. rcp makeBuffer(const VkBufferCreateInfo&, vkutil::Mappability); - rcp makeImage(const VkImageCreateInfo&); - rcp makeImageView(rcp); + rcp makeImage(const VkImageCreateInfo&, const char* name); + rcp makeImageView(rcp, const char* name); rcp makeImageView(rcp, - const VkImageViewCreateInfo&); - rcp makeExternalImageView(const VkImageViewCreateInfo&); - rcp makeTexture2D(const VkImageCreateInfo&); + const VkImageViewCreateInfo&, + const char* name); + rcp makeExternalImageView(const VkImageViewCreateInfo&, + const char* name); + rcp makeTexture2D(const VkImageCreateInfo&, + const char* name); rcp makeFramebuffer(const VkFramebufferCreateInfo&); // Helpers. @@ -167,14 +196,24 @@ class VulkanContext : public GPUResourceManager VkDependencyFlags, VkBufferMemoryBarrier); + void clearColorImage(VkCommandBuffer, ColorInt, VkImage, VkImageLayout); + void blitSubRect(VkCommandBuffer commandBuffer, - VkImage src, - VkImage dst, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, const IAABB&); + void setDebugNameIfEnabled(uint64_t handle, + VkObjectType objectType, + const char* name); + private: const VmaAllocator m_vmaAllocator; + VkPhysicalDeviceProperties m_physicalDeviceProperties; + // Vulkan spec: must support one of D24S8 and D32S8. bool m_supportsD24S8 = false; }; diff --git a/thirdparty/rive_renderer/include/rive/renderer/webgpu/em_js_handle.hpp b/thirdparty/rive_renderer/include/rive/renderer/webgpu/em_js_handle.hpp deleted file mode 100644 index 70967191b..000000000 --- a/thirdparty/rive_renderer/include/rive/renderer/webgpu/em_js_handle.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#pragma once - -#include "rive/rive_types.hpp" - -#ifdef RIVE_DAWN -#include -#endif - -#ifdef RIVE_WEBGPU -#include -#include -#include -#endif - -// RAII object that stores and releases a handle to a WebGPU object passed from -// Javascript. Original source: -// https://github.com/emscripten-core/emscripten/blob/08cca043d8ba313d774bec8153fab66b70a6fe60/test/webgpu_jsvalstore.cpp -class EmJsHandle -{ -public: - EmJsHandle() : m_handle(0) {} - explicit EmJsHandle(int handle) : m_handle(handle) {} - ~EmJsHandle(); - - EmJsHandle(const EmJsHandle&) = delete; - EmJsHandle& operator=(const EmJsHandle&) = delete; - - EmJsHandle(EmJsHandle&& rhs) : m_handle(rhs.m_handle) { rhs.m_handle = 0; } - EmJsHandle& operator=(EmJsHandle&& rhs); - - int get() const { return m_handle; } - - wgpu::ShaderModule compileSPIRVShaderModule(wgpu::Device device, - const uint32_t* code, - uint32_t codeSize); - - wgpu::ShaderModule compileShaderModule(wgpu::Device device, - const char* language, - const char* source); - -private: - int m_handle; -}; diff --git a/thirdparty/rive_renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp b/thirdparty/rive_renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp index 964bc4d6b..e9d269b55 100644 --- a/thirdparty/rive_renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp +++ b/thirdparty/rive_renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp @@ -5,84 +5,73 @@ #pragma once #include "rive/renderer/render_context_helper_impl.hpp" -#include "rive/renderer/webgpu/em_js_handle.hpp" -#include "rive/renderer/gl/load_store_actions_ext.hpp" #include #include -namespace rive::gpu -{ -class RenderContextWebGPUVulkan; +#ifdef RIVE_WAGYU +#include "rive/renderer/gl/load_store_actions_ext.hpp" +#endif -class RenderTargetWebGPU : public RenderTarget +namespace rive::gpu { -public: - wgpu::TextureFormat framebufferFormat() const - { - return m_framebufferFormat; - } - - void setTargetTextureView(wgpu::TextureView); - -private: - friend class RenderContextWebGPUImpl; - friend class RenderContextWebGPUVulkan; - - RenderTargetWebGPU(wgpu::Device device, - wgpu::TextureFormat framebufferFormat, - uint32_t width, - uint32_t height, - wgpu::TextureUsage additionalTextureFlags); - - const wgpu::TextureFormat m_framebufferFormat; - - wgpu::Texture m_coverageTexture; - wgpu::Texture m_clipTexture; - wgpu::Texture m_scratchColorTexture; - - wgpu::TextureView m_targetTextureView; - wgpu::TextureView m_coverageTextureView; - wgpu::TextureView m_clipTextureView; - wgpu::TextureView m_scratchColorTextureView; -}; +class RenderTargetWebGPU; class RenderContextWebGPUImpl : public RenderContextHelperImpl { public: + struct ContextOptions + {}; + enum class PixelLocalStorageType { // Pixel local storage cannot be supported; make a best reasonable // effort to draw shapes. none, +#ifdef RIVE_WAGYU // Backend is OpenGL ES 3.1+ and has GL_EXT_shader_pixel_local_storage. // Use "raw-glsl" shaders that take advantage of the extension. - EXT_shader_pixel_local_storage, + GL_EXT_shader_pixel_local_storage, // Backend is Vulkan with VK_EXT_rasterization_order_attachment_access. // Use nonstandard WebGPU APIs to set up vulkan input attachments and // subpassLoad() in shaders. - subpassLoad, + VK_EXT_rasterization_order_attachment_access, +#endif }; - struct ContextOptions + struct Capabilities { + wgpu::BackendType backendType = wgpu::BackendType::Undefined; +#ifdef RIVE_WAGYU + // Driver extensions. + bool VK_EXT_rasterization_order_attachment_access = false; + bool GL_EXT_shader_pixel_local_storage = false; + bool GL_EXT_shader_pixel_local_storage2 = false; + PixelLocalStorageType plsType = PixelLocalStorageType::none; - bool disableStorageBuffers = false; - // Invert Y when drawing to client-provided RenderTargets. - // TODO: We may need to eventually make this configurable - // per-RenderTarget. - bool invertRenderTargetY = false; - // Invert the front face when drawing to client-provied RenderTargets. - bool invertRenderTargetFrontFace = false; + + // Rive requires 4 storage buffers in the vertex shader. We polyfill + // them if the hardware doesn't support this. + bool polyfillVertexStorageBuffers = false; +#endif }; - static std::unique_ptr MakeContext(wgpu::Device, + static std::unique_ptr MakeContext(wgpu::Adapter, + wgpu::Device, wgpu::Queue, const ContextOptions&); virtual ~RenderContextWebGPUImpl(); + wgpu::Device device() const { return m_device; } + wgpu::Queue queue() const { return m_queue; } + + void* makeCommandBuffer() override; + void commitCommandBuffer(void* commandBuffer) override; + const ContextOptions& contextOptions() const { return m_contextOptions; } + const Capabilities& capabilities() const { return m_capabilities; } + virtual rcp makeRenderTarget(wgpu::TextureFormat, uint32_t width, uint32_t height); @@ -94,59 +83,68 @@ class RenderContextWebGPUImpl : public RenderContextHelperImpl rcp makeImageTexture(uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) override; -protected: - RenderContextWebGPUImpl(wgpu::Device device, - wgpu::Queue queue, - const ContextOptions&); +#ifdef RIVE_CANVAS + rcp makeRenderCanvas(uint32_t width, + uint32_t height) override; +#endif - // Create the BindGroupLayout that binds the PLS attachments as textures. - // This is not necessary on all implementations. - virtual wgpu::BindGroupLayout initTextureBindGroup() - { - // Only supported by RenderContextWebGPUVulkan for now. - RIVE_UNREACHABLE(); - } +private: + RenderContextWebGPUImpl(wgpu::Adapter, + wgpu::Device, + wgpu::Queue, + const ContextOptions&); // Create a standard PLS "draw" pipeline for the current implementation. - virtual wgpu::RenderPipeline makeDrawPipeline( - rive::gpu::DrawType drawType, - wgpu::TextureFormat framebufferFormat, - wgpu::ShaderModule vertexShader, - wgpu::ShaderModule fragmentShader, - EmJsHandle* pipelineJSHandleIfNeeded); - - // Create a standard PLS "draw" render pass for the current implementation. - virtual wgpu::RenderPassEncoder makePLSRenderPass( - wgpu::CommandEncoder, - const RenderTargetWebGPU*, - wgpu::LoadOp, - const wgpu::Color& clearColor, - EmJsHandle* renderPassJSHandleIfNeeded); + wgpu::RenderPipeline makeDrawPipeline(rive::gpu::DrawType, + gpu::InterlockMode, + gpu::ShaderMiscFlags, + wgpu::TextureFormat framebufferFormat, + wgpu::ShaderModule vertexShader, + wgpu::ShaderModule fragmentShader, + const gpu::PipelineState&); + + // Begin a Rive render pass that uses pixel local storage. + wgpu::RenderPassEncoder beginPLSRenderPass(wgpu::CommandEncoder, + const FlushDescriptor&); + + // Specifies how to load MSAA color/depth/stencil attachments when beginning + // an MSAA render pass. + enum class MSAABeginType : bool + { + primary, + restartAfterDstCopy, + }; - wgpu::Device device() const { return m_device; } - wgpu::FrontFace frontFaceForRenderTargetDraws() const + // Specifies how to store MSAA color/depth/stencil attachments when ending + // an MSAA render pass. + enum class MSAAEndType : bool { - return m_contextOptions.invertRenderTargetFrontFace - ? wgpu::FrontFace::CCW - : wgpu::FrontFace::CW; - } + finish, + breakForDstCopy, + }; + + // Begin a Rive render pass that uses MSAA. + wgpu::RenderPassEncoder beginMSAARenderPass(wgpu::CommandEncoder, + MSAABeginType, + MSAAEndType, + const FlushDescriptor&); + + // Set the initial render pass state for draws (viewport, bindings, etc.). + void initDrawRenderPass(wgpu::RenderPassEncoder, const FlushDescriptor&); + wgpu::PipelineLayout drawPipelineLayout() const { return m_drawPipelineLayout; } -private: // Called outside the constructor so we can use virtual methods. void initGPUObjects(); void generateMipmaps(wgpu::Texture); - // PLS always expects a clockwise front face. - constexpr static wgpu::FrontFace kFrontFaceForOffscreenDraws = - wgpu::FrontFace::CW; - std::unique_ptr makeUniformBufferRing( size_t capacityInBytes) override; std::unique_ptr makeStorageBufferRing( @@ -164,25 +162,29 @@ class RenderContextWebGPUImpl : public RenderContextHelperImpl const wgpu::Device m_device; const wgpu::Queue m_queue; const ContextOptions m_contextOptions; + Capabilities m_capabilities; constexpr static int COLOR_RAMP_BINDINGS_COUNT = 1; constexpr static int TESS_BINDINGS_COUNT = 6; constexpr static int ATLAS_BINDINGS_COUNT = 7; - constexpr static int DRAW_BINDINGS_COUNT = 10; + constexpr static int DRAW_BINDINGS_COUNT = 11; std::array m_perFlushBindingLayouts; +#ifdef RIVE_WAGYU // Draws emulated render-pass load/store actions for // EXT_shader_pixel_local_storage. class LoadStoreEXTPipeline; - std::map m_loadStoreEXTPipelines; - EmJsHandle m_loadStoreEXTVertexShaderHandle; + std::map m_loadStoreEXTPipelines; wgpu::ShaderModule m_loadStoreEXTVertexShader; std::unique_ptr m_loadStoreEXTUniforms; +#endif +#ifndef RIVE_WAGYU // Blits texture-to-texture using a draw command. class BlitTextureAsDrawPipeline; std::unique_ptr m_blitTextureAsDrawPipeline; +#endif // Renders color ramps to the gradient texture. class ColorRampPipeline; @@ -205,10 +207,10 @@ class RenderContextWebGPUImpl : public RenderContextHelperImpl // Draw paths and image meshes using the gradient and tessellation textures. class DrawPipeline; - std::map m_drawPipelines; + std::map m_drawPipelines; wgpu::BindGroupLayout m_drawBindGroupLayouts[4 /*BINDINGS_SET_COUNT*/]; wgpu::Sampler m_linearSampler; - wgpu::Sampler m_mipmapSampler; + wgpu::Sampler m_imageSamplers[ImageSampler::MAX_SAMPLER_PERMUTATIONS]; wgpu::BindGroup m_samplerBindings; wgpu::PipelineLayout m_drawPipelineLayout; wgpu::BindGroupLayout m_emptyBindingsLayout; // For when a set is unused. @@ -219,8 +221,87 @@ class RenderContextWebGPUImpl : public RenderContextHelperImpl wgpu::Texture m_featherTexture; wgpu::TextureView m_featherTextureView; - // Bound when there is not an image paint. - wgpu::Texture m_nullImagePaintTexture; - wgpu::TextureView m_nullImagePaintTextureView; + // Bound when a texture binding is unused. + wgpu::Texture m_nullTexture; + wgpu::TextureView m_nullTextureView; +}; + +class RenderTargetWebGPU : public RenderTarget +{ +public: + wgpu::TextureFormat framebufferFormat() const + { + return m_framebufferFormat; + } + + wgpu::Texture targetTexture() const { return m_targetTexture; }; + wgpu::TextureView targetTextureView() const { return m_targetTextureView; }; + void setTargetTextureView(wgpu::TextureView, wgpu::Texture); + +protected: + RenderTargetWebGPU(wgpu::Device device, + const RenderContextWebGPUImpl::Capabilities&, + wgpu::TextureFormat framebufferFormat, + uint32_t width, + uint32_t height); + + // Lazily loaded render pass resources. + wgpu::TextureView coverageTextureView(); + wgpu::TextureView clipTextureView(); + wgpu::TextureView scratchColorTextureView(); + wgpu::TextureView msaaColorTextureView(); + wgpu::TextureView msaaDepthStencilTextureView(); + wgpu::Texture dstColorTexture(); + wgpu::TextureView dstColorTextureView(); + + // Copies a sub-rectangle of the targetTexture to the dstColorTexture for + // shader blending. Shaders can't read from the targetTexture itself because + // it's also the resolveTarget. + void copyTargetToDstColorTexture(wgpu::CommandEncoder, IAABB dstReadBounds); + +private: + friend class RenderContextWebGPUImpl; + + const wgpu::Device m_device; + const wgpu::TextureFormat m_framebufferFormat; + wgpu::TextureUsage m_transientPLSUsage; + + wgpu::Texture m_targetTexture; + wgpu::Texture m_coverageTexture; + wgpu::Texture m_clipTexture; + wgpu::Texture m_scratchColorTexture; + wgpu::Texture m_msaaColorTexture; + wgpu::Texture m_msaaDepthStencilTexture; + wgpu::Texture m_dstColorTexture; + + wgpu::TextureView m_targetTextureView; + wgpu::TextureView m_coverageTextureView; + wgpu::TextureView m_clipTextureView; + wgpu::TextureView m_scratchColorTextureView; + wgpu::TextureView m_msaaColorTextureView; + wgpu::TextureView m_msaaDepthStencilTextureView; + wgpu::TextureView m_dstColorTextureView; +}; + +class TextureWebGPUImpl : public Texture +{ +public: + TextureWebGPUImpl(uint32_t width, uint32_t height, wgpu::Texture texture) : + Texture(width, height), + m_texture(std::move(texture)), + m_textureView(m_texture.CreateView()) + {} + + wgpu::Texture texture() const { return m_texture; } + wgpu::TextureView textureView() const { return m_textureView; } + void* nativeHandle() const override + { + // Return the raw WGPUTexture handle. + return m_texture.Get(); + } + +private: + wgpu::Texture m_texture; + wgpu::TextureView m_textureView; }; } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/rive_renderer.cpp b/thirdparty/rive_renderer/rive_renderer.cpp index ced390e78..34a791dec 100644 --- a/thirdparty/rive_renderer/rive_renderer.cpp +++ b/thirdparty/rive_renderer/rive_renderer.cpp @@ -35,6 +35,7 @@ #include "rive_renderer.h" +// BEGIN YUP GENERATED RIVE RENDERER INCLUDES #include "source/rive_renderer.cpp" #include "source/render_context.cpp" #include "source/rive_render_paint.cpp" @@ -48,6 +49,9 @@ #include "source/gpu.cpp" #include "source/rive_render_factory.cpp" #include "source/render_context_helper_impl.cpp" +#include "source/gpu_resource.cpp" +// END YUP GENERATED RIVE RENDERER INCLUDES + #if __clang__ #pragma clang diagnostic pop diff --git a/thirdparty/rive_renderer/rive_renderer.h b/thirdparty/rive_renderer/rive_renderer.h index 6fc1cbb7f..2d2482a10 100644 --- a/thirdparty/rive_renderer/rive_renderer.h +++ b/thirdparty/rive_renderer/rive_renderer.h @@ -26,7 +26,7 @@ ID: rive_renderer vendor: rive - version: 1.0 + version: 0.1.62 name: Rive Renderer. description: The Rive Renderer is a vector and raster graphics renderer custom-built for Rive content, for animation, and for runtime. website: https://github.com/rive-app/rive-runtime diff --git a/thirdparty/rive_renderer/source/d3d/d3d_utils.cpp b/thirdparty/rive_renderer/source/d3d/d3d_utils.cpp new file mode 100644 index 000000000..b48e1e8ec --- /dev/null +++ b/thirdparty/rive_renderer/source/d3d/d3d_utils.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/d3d/d3d_utils.hpp" + +#include +#include +#include +#include +#include "rive/renderer/d3d/d3d.hpp" +namespace rive::gpu +{ +namespace d3d_utils +{ + +DXGI_FORMAT convert_format(GPUTextureFormat format) +{ + switch (format) + { + case GPUTextureFormat::rgba32: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case GPUTextureFormat::bc1: + return DXGI_FORMAT_BC1_UNORM; + case GPUTextureFormat::bc2: + return DXGI_FORMAT_BC2_UNORM; + case GPUTextureFormat::bc3: + return DXGI_FORMAT_BC3_UNORM; + case GPUTextureFormat::bc7: + return DXGI_FORMAT_BC7_UNORM; + default: + return DXGI_FORMAT_R8G8B8A8_UNORM; + } +} + +bool GetWStringFromString(const char* cString, std::wstring& outString) +{ + int len = MultiByteToWideChar(CP_UTF8, 0, cString, -1, nullptr, 0); + if (len <= 0) + { + std::cerr + << "Failed to get required size for gpu name filter wide string with error " + << GetLastError() << "\n"; + return false; + } + + outString.resize(len - 1, 0); + + if (MultiByteToWideChar(CP_UTF8, 0, cString, -1, &outString[0], len) <= 0) + { + std::cerr + << "Failed to conver gpu name filter to wide string with error " + << GetLastError() << "\n"; + return false; + } + + return true; +} +} // namespace d3d_utils +} // namespace rive::gpu \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/d3d/pipeline_manager.cpp b/thirdparty/rive_renderer/source/d3d/pipeline_manager.cpp index 114155e58..1ab053bbe 100644 --- a/thirdparty/rive_renderer/source/d3d/pipeline_manager.cpp +++ b/thirdparty/rive_renderer/source/d3d/pipeline_manager.cpp @@ -8,40 +8,42 @@ #include +#include "generated/shaders/image_draw_uniforms.glsl.hpp" +#include "generated/shaders/flush_uniforms.glsl.hpp" #include "generated/shaders/advanced_blend.glsl.hpp" #include "generated/shaders/atomic_draw.glsl.hpp" -#include "generated/shaders/color_ramp.glsl.hpp" #include "generated/shaders/constants.glsl.hpp" #include "generated/shaders/common.glsl.hpp" -#include "generated/shaders/draw_image_mesh.glsl.hpp" +#include "generated/shaders/draw_image_mesh.vert.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" #include "generated/shaders/draw_path_common.glsl.hpp" -#include "generated/shaders/draw_path.glsl.hpp" +#include "generated/shaders/draw_path.vert.hpp" +#include "generated/shaders/draw_raster_order_path.frag.hpp" #include "generated/shaders/hlsl.glsl.hpp" -#include "generated/shaders/bezier_utils.glsl.hpp" -#include "generated/shaders/render_atlas.glsl.hpp" -#include "generated/shaders/tessellate.glsl.hpp" namespace rive::gpu::d3d_utils { -std::string build_shader(DrawType drawType, - ShaderFeatures shaderFeatures, - InterlockMode interlockMode, - ShaderMiscFlags shaderMiscFlags, - const D3DCapabilities& d3dCapabilities) +static std::string build_shader(DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + const D3DCapabilities& d3dCapabilities, + const char* shaderTypeDefine) { + std::ostringstream s; + s << "#define " << shaderTypeDefine << '\n'; for (size_t i = 0; i < kShaderFeatureCount; ++i) { - ShaderFeatures feature = static_cast(1 << i); - if (shaderFeatures & feature) + const auto feature = ShaderFeatures(1 << i); + if (enums::is_flag_set(shaderFeatures, feature)) { s << "#define " << GetShaderFeatureGLSLName(feature) << " 1\n"; } } if (d3dCapabilities.supportsRasterizerOrderedViews) { - if (interlockMode == InterlockMode::rasterOrdering && - drawType != DrawType::interiorTriangulation) + if (interlockMode == InterlockMode::rasterOrdering) { s << "#define " << GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS << '\n'; } @@ -54,11 +56,13 @@ std::string build_shader(DrawType drawType, { s << "#define " << GLSL_ENABLE_MIN_16_PRECISION << '\n'; } - if (shaderMiscFlags & ShaderMiscFlags::fixedFunctionColorOutput) + if (enums::is_flag_set(shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) { s << "#define " << GLSL_FIXED_FUNCTION_COLOR_OUTPUT << '\n'; } - if (shaderMiscFlags & ShaderMiscFlags::coalescedResolveAndTransfer) + if (enums::is_flag_set(shaderMiscFlags, + ShaderMiscFlags::coalescedResolveAndTransfer)) { s << "#define " << GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER << '\n'; if (!d3dCapabilities.allowsUAVSlot0WithColorOutput) @@ -67,7 +71,7 @@ std::string build_shader(DrawType drawType, << COALESCED_OFFSCREEN_COLOR_PLANE_IDX << '\n'; } } - if (shaderMiscFlags & ShaderMiscFlags::clockwiseFill) + if (enums::is_flag_set(shaderMiscFlags, ShaderMiscFlags::clockwiseFill)) { s << "#define " << GLSL_CLOCKWISE_FILL << " 1\n"; } @@ -78,12 +82,12 @@ std::string build_shader(DrawType drawType, case DrawType::outerCurvePatches: s << "#define " << GLSL_DRAW_PATH << '\n'; break; - case DrawType::atlasBlit: - s << "#define " << GLSL_ATLAS_BLIT << " 1\n"; - [[fallthrough]]; case DrawType::interiorTriangulation: s << "#define " << GLSL_DRAW_INTERIOR_TRIANGLES << '\n'; break; + case DrawType::atlasBlit: + s << "#define " << GLSL_ATLAS_BLIT << " 1\n"; + break; case DrawType::imageRect: assert(interlockMode == InterlockMode::atomics); s << "#define " << GLSL_DRAW_IMAGE << '\n'; @@ -93,12 +97,11 @@ std::string build_shader(DrawType drawType, s << "#define " << GLSL_DRAW_IMAGE << '\n'; s << "#define " << GLSL_DRAW_IMAGE_MESH << '\n'; break; - case DrawType::atomicResolve: + case DrawType::renderPassResolve: assert(interlockMode == InterlockMode::atomics); s << "#define " << GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS << '\n'; s << "#define " << GLSL_RESOLVE_PLS << '\n'; break; - case DrawType::atomicInitialize: case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -106,125 +109,108 @@ std::string build_shader(DrawType drawType, case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: RIVE_UNREACHABLE(); } s << glsl::constants << '\n'; s << glsl::hlsl << '\n'; + s << glsl::flush_uniforms << '\n'; s << glsl::common << '\n'; - if (shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND) + if (enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_ADVANCED_BLEND)) { s << glsl::advanced_blend << '\n'; } - switch (drawType) + if (drawType == DrawType::imageMesh || drawType == DrawType::imageRect) { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - s << glsl::draw_path_common << '\n'; - s << (interlockMode == InterlockMode::rasterOrdering - ? glsl::draw_path - : glsl::atomic_draw) - << '\n'; - break; - case DrawType::interiorTriangulation: - case DrawType::atlasBlit: - s << glsl::draw_path_common << '\n'; - s << (interlockMode == InterlockMode::rasterOrdering - ? glsl::draw_path - : glsl::atomic_draw) - << '\n'; - break; - case DrawType::imageRect: - assert(interlockMode == InterlockMode::atomics); - s << glsl::draw_path_common << '\n'; - s << glsl::atomic_draw << '\n'; - break; - case DrawType::imageMesh: - if (interlockMode == InterlockMode::rasterOrdering) - { - s << glsl::draw_image_mesh << '\n'; - } - else - { + s << glsl::image_draw_uniforms << '\n'; + } + if (interlockMode == InterlockMode::rasterOrdering) + { + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + case DrawType::interiorTriangulation: s << glsl::draw_path_common << '\n'; - s << glsl::atomic_draw << '\n'; - } - break; - case DrawType::atomicResolve: - case DrawType::msaaStencilClipReset: - assert(interlockMode == InterlockMode::atomics); - s << glsl::draw_path_common << '\n'; - s << glsl::atomic_draw << '\n'; - break; - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - RIVE_UNREACHABLE(); + s << glsl::draw_path_vert << '\n'; + s << glsl::draw_raster_order_path_frag << '\n'; + break; + case DrawType::atlasBlit: + s << glsl::draw_path_common << '\n'; + s << glsl::draw_path_vert << '\n'; + s << glsl::draw_mesh_frag << '\n'; + break; + case DrawType::imageMesh: + s << glsl::draw_image_mesh_vert << '\n'; + s << glsl::draw_mesh_frag << '\n'; + break; + case DrawType::imageRect: + case DrawType::renderPassResolve: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + RIVE_UNREACHABLE(); + } + } + else + { + assert(interlockMode == InterlockMode::atomics); + s << glsl::draw_path_common << '\n'; + s << glsl::atomic_draw << '\n'; } return s.str(); } -ComPtr compile_pixel_source_to_blob(const std::string& sharedSource, - const char* target) +static const char* shader_type_define_from_target(const char* target) { - std::ostringstream source; - source << "#define " << GLSL_FRAGMENT << '\n'; - source << sharedSource; - - const std::string& sourceStr = source.str(); - ComPtr blob; - ComPtr errors; - HRESULT hr = D3DCompile(sourceStr.c_str(), - sourceStr.length(), - nullptr, - nullptr, - nullptr, - "main", - target, - D3DCOMPILE_ENABLE_STRICTNESS, - 0, - &blob, - &errors); - if (errors && errors->GetBufferPointer()) + if (target[0] == 'v') { - fprintf(stderr, "Errors or warnings compiling shader.\n"); - int l = 1; - std::stringstream stream(sourceStr); - std::string lineStr; - while (std::getline(stream, lineStr, '\n')) - { - fprintf(stderr, "%4i| %s\n", l++, lineStr.c_str()); - } - fprintf(stderr, - "%s\n", - reinterpret_cast(errors->GetBufferPointer())); - abort(); + return GLSL_VERTEX; } - if (FAILED(hr)) + else if (target[0] == 'p') { - fprintf(stderr, "Failed to compile shader.\n"); - abort(); + return GLSL_FRAGMENT; } - return blob; + + assert(false); + return ""; } -ComPtr compile_vertex_source_to_blob(const std::string& sharedSource, - const char* target) +ComPtr compile_shader_to_blob(DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + const D3DCapabilities& d3dCapabilities, + const char* target) { - std::ostringstream source; - source << "#define " << GLSL_VERTEX << '\n'; - source << sharedSource; + const std::string& sourceStr = + build_shader(drawType, + shaderFeatures, + interlockMode, + shaderMiscFlags, + d3dCapabilities, + shader_type_define_from_target(target)); - const std::string& sourceStr = source.str(); ComPtr blob; ComPtr errors; + +#ifdef RIVE_RAW_SHADERS + UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | + D3DCOMPILE_SKIP_OPTIMIZATION; +#else + UINT flags = D3DCOMPILE_ENABLE_STRICTNESS; +#endif + HRESULT hr = D3DCompile(sourceStr.c_str(), sourceStr.length(), nullptr, @@ -232,7 +218,7 @@ ComPtr compile_vertex_source_to_blob(const std::string& sharedSource, nullptr, "main", target, - D3DCOMPILE_ENABLE_STRICTNESS, + flags, 0, &blob, &errors); @@ -258,4 +244,4 @@ ComPtr compile_vertex_source_to_blob(const std::string& sharedSource, } return blob; } -}; // namespace rive::gpu::d3d_utils \ No newline at end of file +}; // namespace rive::gpu::d3d_utils diff --git a/thirdparty/rive_renderer/source/d3d11/render_context_d3d_impl.cpp b/thirdparty/rive_renderer/source/d3d11/render_context_d3d_impl.cpp index f0b6ebe1b..91f74d138 100644 --- a/thirdparty/rive_renderer/source/d3d11/render_context_d3d_impl.cpp +++ b/thirdparty/rive_renderer/source/d3d11/render_context_d3d_impl.cpp @@ -6,23 +6,15 @@ #include "rive/renderer/d3d/d3d_constants.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif #include "rive/renderer/texture.hpp" +#include "rive/profiler/profiler_macros.h" #include -#include - -#include "generated/shaders/advanced_blend.glsl.hpp" -#include "generated/shaders/atomic_draw.glsl.hpp" -#include "generated/shaders/color_ramp.glsl.hpp" -#include "generated/shaders/constants.glsl.hpp" -#include "generated/shaders/common.glsl.hpp" -#include "generated/shaders/draw_image_mesh.glsl.hpp" -#include "generated/shaders/draw_path_common.glsl.hpp" -#include "generated/shaders/draw_path.glsl.hpp" -#include "generated/shaders/hlsl.glsl.hpp" -#include "generated/shaders/bezier_utils.glsl.hpp" -#include "generated/shaders/render_atlas.glsl.hpp" -#include "generated/shaders/tessellate.glsl.hpp" + +#include "generated/shaders/tessellate.glsl.exports.h" // offline shaders namespace shader @@ -103,10 +95,9 @@ static ComPtr make_simple_2d_uav( D3D11PipelineManager::D3D11PipelineManager( ComPtr context, ComPtr device, - const D3DCapabilities& capabilities) : - D3DPipelineManager, - ID3D11Device>(device, capabilities, "vs_5_0", "ps_5_0"), + const D3DCapabilities& capabilities, + ShaderCompilationMode shaderCompilationMode) : + Super(device, capabilities, shaderCompilationMode, "vs_5_0", "ps_5_0"), m_context(context) { D3D11_INPUT_ELEMENT_DESC spanDesc = {GLSL_a_span, @@ -219,153 +210,180 @@ D3D11PipelineManager::D3D11PipelineManager( &m_atlasStrokePixelShader)); } -void D3D11PipelineManager::setPipelineState( - rive::gpu::DrawType drawType, - rive::gpu::ShaderFeatures features, - rive::gpu::InterlockMode interlockMode, - rive::gpu::ShaderMiscFlags miscFlags) +bool D3D11PipelineManager::setPipelineState( + DrawType drawType, + ShaderFeatures features, + InterlockMode interlockMode, + ShaderMiscFlags miscFlags, + const PlatformFeatures& platformFeatures +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType synthesizedFailureType +#endif +) { - ShaderCompileResult result{}; - if (!getShader( - {drawType, features, interlockMode, miscFlags, d3dCapabilities()}, - &result)) + auto* pipeline = tryGetPipeline( + { + .drawType = drawType, + .shaderFeatures = features, + .interlockMode = interlockMode, + .shaderMiscFlags = miscFlags, +#ifdef WITH_RIVE_TOOLS + .synthesizedFailureType = synthesizedFailureType, +#endif + }, + platformFeatures); + + if (pipeline == nullptr) { - // this should never happen - RIVE_UNREACHABLE(); + return false; } - assert(result.vertexResult.hasResult); - assert(result.pixelResult.hasResult); - - m_context->IASetInputLayout( - result.vertexResult.vertexShaderResult.layout.Get()); - m_context->VSSetShader(result.vertexResult.vertexShaderResult.shader.Get(), - NULL, - 0); - m_context->PSSetShader(result.pixelResult.pixelShaderResult.Get(), NULL, 0); + m_context->IASetInputLayout(pipeline->m_vertexShader.layout.Get()); + m_context->VSSetShader(pipeline->m_vertexShader.shader.Get(), nullptr, 0); + m_context->PSSetShader(pipeline->m_pixelShader.shader.Get(), nullptr, 0); + return true; } -void D3D11PipelineManager::compileBlobToFinalType( - const ShaderCompileRequest& request, - ComPtr vertexShader, - ComPtr pixelShader, - ShaderCompileResult* result) +std::unique_ptr D3D11PipelineManager:: + compileVertexShaderBlobToFinalType(DrawType drawType, ComPtr blob) { - if (result->vertexResult.hasResult == false) + D3D11_INPUT_ELEMENT_DESC layoutDesc[2]; + uint32_t vertexAttribCount; + switch (drawType) { - D3D11_INPUT_ELEMENT_DESC layoutDesc[2]; - uint32_t vertexAttribCount; - switch (request.drawType) - { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - layoutDesc[0] = {GLSL_a_patchVertexData, - 0, - DXGI_FORMAT_R32G32B32A32_FLOAT, - PATCH_VERTEX_DATA_SLOT, - D3D11_APPEND_ALIGNED_ELEMENT, - D3D11_INPUT_PER_VERTEX_DATA, - 0}; - layoutDesc[1] = {GLSL_a_mirroredVertexData, - 0, - DXGI_FORMAT_R32G32B32A32_FLOAT, - PATCH_VERTEX_DATA_SLOT, - D3D11_APPEND_ALIGNED_ELEMENT, - D3D11_INPUT_PER_VERTEX_DATA, - 0}; - vertexAttribCount = 2; - break; - case DrawType::interiorTriangulation: - case DrawType::atlasBlit: - layoutDesc[0] = {GLSL_a_triangleVertex, - 0, - DXGI_FORMAT_R32G32B32_FLOAT, - TRIANGLE_VERTEX_DATA_SLOT, - 0, - D3D11_INPUT_PER_VERTEX_DATA, - 0}; - vertexAttribCount = 1; - break; - case DrawType::imageRect: - layoutDesc[0] = {GLSL_a_imageRectVertex, - 0, - DXGI_FORMAT_R32G32B32A32_FLOAT, - IMAGE_RECT_VERTEX_DATA_SLOT, - 0, - D3D11_INPUT_PER_VERTEX_DATA, - 0}; - vertexAttribCount = 1; - break; - case DrawType::imageMesh: - layoutDesc[0] = {GLSL_a_position, - 0, - DXGI_FORMAT_R32G32_FLOAT, - IMAGE_MESH_VERTEX_DATA_SLOT, - D3D11_APPEND_ALIGNED_ELEMENT, - D3D11_INPUT_PER_VERTEX_DATA, - 0}; - layoutDesc[1] = {GLSL_a_texCoord, - 0, - DXGI_FORMAT_R32G32_FLOAT, - IMAGE_MESH_UV_DATA_SLOT, - D3D11_APPEND_ALIGNED_ELEMENT, - D3D11_INPUT_PER_VERTEX_DATA, - 0}; - vertexAttribCount = 2; - break; - case DrawType::atomicResolve: - vertexAttribCount = 0; - break; - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); - } + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + layoutDesc[0] = {GLSL_a_patchVertexData, + 0, + DXGI_FORMAT_R32G32B32A32_FLOAT, + PATCH_VERTEX_DATA_SLOT, + D3D11_APPEND_ALIGNED_ELEMENT, + D3D11_INPUT_PER_VERTEX_DATA, + 0}; + layoutDesc[1] = {GLSL_a_mirroredVertexData, + 0, + DXGI_FORMAT_R32G32B32A32_FLOAT, + PATCH_VERTEX_DATA_SLOT, + D3D11_APPEND_ALIGNED_ELEMENT, + D3D11_INPUT_PER_VERTEX_DATA, + 0}; + vertexAttribCount = 2; + break; + case DrawType::interiorTriangulation: + case DrawType::atlasBlit: + layoutDesc[0] = {GLSL_a_triangleVertex, + 0, + DXGI_FORMAT_R32G32B32_FLOAT, + TRIANGLE_VERTEX_DATA_SLOT, + 0, + D3D11_INPUT_PER_VERTEX_DATA, + 0}; + vertexAttribCount = 1; + break; + case DrawType::imageRect: + layoutDesc[0] = {GLSL_a_imageRectVertex, + 0, + DXGI_FORMAT_R32G32B32A32_FLOAT, + IMAGE_RECT_VERTEX_DATA_SLOT, + 0, + D3D11_INPUT_PER_VERTEX_DATA, + 0}; + vertexAttribCount = 1; + break; + case DrawType::imageMesh: + layoutDesc[0] = {GLSL_a_position, + 0, + DXGI_FORMAT_R32G32_FLOAT, + IMAGE_MESH_VERTEX_DATA_SLOT, + D3D11_APPEND_ALIGNED_ELEMENT, + D3D11_INPUT_PER_VERTEX_DATA, + 0}; + layoutDesc[1] = {GLSL_a_texCoord, + 0, + DXGI_FORMAT_R32G32_FLOAT, + IMAGE_MESH_UV_DATA_SLOT, + D3D11_APPEND_ALIGNED_ELEMENT, + D3D11_INPUT_PER_VERTEX_DATA, + 0}; + vertexAttribCount = 2; + break; + case DrawType::renderPassResolve: + vertexAttribCount = 0; + break; + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + RIVE_UNREACHABLE(); + } - VERIFY_OK(device()->CreateInputLayout( - layoutDesc, - vertexAttribCount, - vertexShader->GetBufferPointer(), - vertexShader->GetBufferSize(), - &result->vertexResult.vertexShaderResult.layout)); - VERIFY_OK(device()->CreateVertexShader( - vertexShader->GetBufferPointer(), - vertexShader->GetBufferSize(), - nullptr, - &result->vertexResult.vertexShaderResult.shader)); + auto result = std::make_unique(); + + VERIFY_OK(device()->CreateInputLayout(layoutDesc, + vertexAttribCount, + blob->GetBufferPointer(), + blob->GetBufferSize(), + &result->layout)); + VERIFY_OK(device()->CreateVertexShader(blob->GetBufferPointer(), + blob->GetBufferSize(), + nullptr, + &result->shader)); + return result; +} - result->vertexResult.hasResult = true; - } +std::unique_ptr D3D11PipelineManager :: + compilePixelShaderBlobToFinalType(ComPtr blob) +{ + auto result = std::make_unique(); - if (result->pixelResult.hasResult == false) - { - ComPtr pixelShaderResult; + VERIFY_OK(device()->CreatePixelShader(blob->GetBufferPointer(), + blob->GetBufferSize(), + nullptr, + &result->shader)); - VERIFY_OK(device()->CreatePixelShader(pixelShader->GetBufferPointer(), - pixelShader->GetBufferSize(), - nullptr, - &pixelShaderResult)); + return result; +} - result->pixelResult.pixelShaderResult = std::move(pixelShaderResult); - result->pixelResult.hasResult = true; +std::unique_ptr D3D11PipelineManager::linkPipeline( + const PipelineProps& props, + const D3D11DrawVertexShader& vs, + const D3D11DrawPixelShader& ps) +{ + // For D3D11 this just puts the vs and ps into a single structure together. + auto pipeline = std::make_unique(); +#ifdef WITH_RIVE_TOOLS + if (props.synthesizedFailureType == + SynthesizedFailureType::pipelineCreation || + props.synthesizedFailureType == + SynthesizedFailureType::shaderCompilation) + { + // An empty result is what counts as "failed" + return pipeline; } +#else + std::ignore = props; +#endif + + pipeline->m_vertexShader = vs; + pipeline->m_pixelShader = ps; + return pipeline; } static D3D11_FILTER filter_for_sampler_filter_options(ImageFilter option) { switch (option) { - case ImageFilter::trilinear: - return D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_LINEAR; case ImageFilter::nearest: return D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_POINT; + case ImageFilter::bilinear: + return D3D11_FILTER::D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; } RIVE_UNREACHABLE(); @@ -394,6 +412,9 @@ std::unique_ptr RenderContextD3DImpl::MakeContext( ComPtr gpuContext, const D3DContextOptions& contextOptions) { +#if defined(RIVE_MICROPROFILE) + MicroProfileGpuInitD3D11(gpu.Get()); +#endif D3DCapabilities d3dCapabilities; D3D11_FEATURE_DATA_D3D11_OPTIONS2 d3d11Options2; @@ -466,25 +487,32 @@ std::unique_ptr RenderContextD3DImpl::MakeContext( auto renderContextImpl = std::unique_ptr( new RenderContextD3DImpl(std::move(gpu), std::move(gpuContext), - d3dCapabilities)); + d3dCapabilities, + contextOptions)); return std::make_unique(std::move(renderContextImpl)); } RenderContextD3DImpl::RenderContextD3DImpl( ComPtr gpu, ComPtr gpuContext, - const D3DCapabilities& d3dCapabilities) : - m_pipelineManager(gpuContext, gpu, d3dCapabilities), + const D3DCapabilities& d3dCapabilities, + const D3DContextOptions& d3dContextOptions) : + m_pipelineManager(gpuContext, + gpu, + d3dCapabilities, + d3dContextOptions.shaderCompilationMode), m_d3dCapabilities(d3dCapabilities), m_gpu(std::move(gpu)), m_gpuContext(std::move(gpuContext)) { m_platformFeatures.clipSpaceBottomUp = true; m_platformFeatures.framebufferBottomUp = false; - m_platformFeatures.supportsRasterOrdering = + m_platformFeatures.supportsRasterOrderingMode = d3dCapabilities.supportsRasterizerOrderedViews; - m_platformFeatures.supportsFragmentShaderAtomics = true; + m_platformFeatures.supportsAtomicMode = true; m_platformFeatures.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + // BC1–BC7 are required at D3D feature level 11.0+. + m_platformFeatures.supportsTextureCompressionBC = true; // Create a default raster state for path and offscreen draws. D3D11_RASTERIZER_DESC rasterDesc; @@ -509,11 +537,18 @@ RenderContextD3DImpl::RenderContextD3DImpl( &rasterDesc, m_backCulledRasterState[0].ReleaseAndGetAddressOf())); - // ...And with scissor for the atlas. + // ...And with scissor and no culling for the atlas fill. + rasterDesc.CullMode = D3D11_CULL_NONE; rasterDesc.ScissorEnable = TRUE; VERIFY_OK(m_gpu->CreateRasterizerState( &rasterDesc, - m_atlasRasterState.ReleaseAndGetAddressOf())); + m_atlasFillRasterState.ReleaseAndGetAddressOf())); + + // ...And with culling back on for the atlas stroke. + rasterDesc.CullMode = D3D11_CULL_BACK; + VERIFY_OK(m_gpu->CreateRasterizerState( + &rasterDesc, + m_atlasStrokeRasterState.ReleaseAndGetAddressOf())); // ...And with wireframe for debugging. rasterDesc.ScissorEnable = FALSE; @@ -661,9 +696,9 @@ RenderContextD3DImpl::RenderContextD3DImpl( mipmapSamplerDesc.AddressV = address_mode_for_sampler_filter_options(yWrap); mipmapSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - mipmapSamplerDesc.MipLODBias = 0.0f; mipmapSamplerDesc.MaxAnisotropy = 1; mipmapSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + mipmapSamplerDesc.MipLODBias = 0.0f; mipmapSamplerDesc.MinLOD = 0; mipmapSamplerDesc.MaxLOD = D3D11_FLOAT32_MAX; VERIFY_OK(m_gpu->CreateSamplerState( @@ -772,7 +807,8 @@ class RenderBufferD3DImpl m_desc.BindFlags = type() == RenderBufferType::vertex ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER; - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { m_desc.Usage = D3D11_USAGE_IMMUTABLE; m_desc.CPUAccessFlags = 0; @@ -793,7 +829,8 @@ class RenderBufferD3DImpl protected: void* onMap() override { - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { assert(m_mappedMemoryForImmutableBuffer); return m_mappedMemoryForImmutableBuffer.get(); @@ -812,7 +849,8 @@ class RenderBufferD3DImpl void onUnmap() override { - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { assert(!m_buffer); D3D11_SUBRESOURCE_DATA bufferDataDesc{}; @@ -852,42 +890,107 @@ rcp RenderContextD3DImpl::makeRenderBuffer( class TextureD3DImpl : public Texture { public: + TextureD3DImpl(RenderContextD3DImpl* renderContextImpl, + ComPtr image, + UINT width, + UINT height) : + Texture(width, height), m_texture(image) + { + // Create a view. + VERIFY_OK(renderContextImpl->gpu()->CreateShaderResourceView( + m_texture.Get(), + NULL, + m_srv.ReleaseAndGetAddressOf())); + } + TextureD3DImpl(RenderContextD3DImpl* renderContextImpl, UINT width, UINT height, UINT mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) : Texture(width, height) { - m_texture = renderContextImpl->makeSimple2DTexture( - DXGI_FORMAT_R8G8B8A8_UNORM, - width, - height, - mipLevelCount, - D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, - D3D11_RESOURCE_MISC_GENERATE_MIPS); - - // Specify the top-level image in the mipmap chain. - D3D11_BOX box; - box.left = 0; - box.right = width; - box.top = 0; - box.bottom = height; - box.front = 0; - box.back = 1; - renderContextImpl->gpuContext()->UpdateSubresource(m_texture.Get(), - 0, - &box, - imageDataRGBAPremul, - width * 4, - 0); + if (format == GPUTextureFormat::bc7) + { + m_texture = renderContextImpl->makeSimple2DTexture( + DXGI_FORMAT_BC7_UNORM, + width, + height, + mipLevelCount, + D3D11_BIND_SHADER_RESOURCE); + + // Specify the top-level image in the mipmap chain. + int W = width; + int H = height; + + const uint8_t* pData = imageDataRGBAPremul; + for (UINT i = 0; i < mipLevelCount; i++) + { + D3D11_BOX box; + box.left = 0; + box.right = math::round_up_to_multiple_of<4>(W); + box.top = 0; + box.bottom = math::round_up_to_multiple_of<4>(H); + box.front = 0; + box.back = 1; + + int BX = (W + 3) / 4; + int BY = (H + 3) / 4; + + renderContextImpl->gpuContext()->UpdateSubresource( + m_texture.Get(), + i, + &box, + pData, + BX * 16, + 0); + + pData += (BX * BY * 16); + + W = W / 2; + H = H / 2; + } + } + else if (format == GPUTextureFormat::rgba32) + { + m_texture = renderContextImpl->makeSimple2DTexture( + DXGI_FORMAT_R8G8B8A8_UNORM, + width, + height, + mipLevelCount, + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, + D3D11_RESOURCE_MISC_GENERATE_MIPS); + + // Specify the top-level image in the mipmap chain. + D3D11_BOX box; + box.left = 0; + box.right = width; + box.top = 0; + box.bottom = height; + box.front = 0; + box.back = 1; + renderContextImpl->gpuContext()->UpdateSubresource( + m_texture.Get(), + 0, + &box, + imageDataRGBAPremul, + width * 4, + 0); + } + else + { + assert(!"unsupported format"); + } // Create a view and generate mipmaps. VERIFY_OK(renderContextImpl->gpu()->CreateShaderResourceView( m_texture.Get(), NULL, m_srv.ReleaseAndGetAddressOf())); - renderContextImpl->gpuContext()->GenerateMips(m_srv.Get()); + + if (format == GPUTextureFormat::rgba32) + renderContextImpl->gpuContext()->GenerateMips(m_srv.Get()); } ID3D11ShaderResourceView* srv() const { return m_srv.Get(); } @@ -895,6 +998,10 @@ class TextureD3DImpl : public Texture { return m_srv.GetAddressOf(); } + void* nativeHandle() const override + { + return static_cast(m_texture.Get()); + } private: ComPtr m_texture; @@ -905,15 +1012,48 @@ rcp RenderContextD3DImpl::makeImageTexture( uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) { return make_rcp(this, width, height, mipLevelCount, + format, imageDataRGBAPremul); } +rcp RenderContextD3DImpl::adoptImageTexture( + ComPtr image, + uint32_t width, + uint32_t height) +{ + return make_rcp(this, image, width, height); +} + +#ifdef RIVE_CANVAS +rcp RenderContextD3DImpl::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + auto texture = makeSimple2DTexture(DXGI_FORMAT_R8G8B8A8_UNORM, + width, + height, + 1, + D3D11_BIND_UNORDERED_ACCESS | + D3D11_BIND_RENDER_TARGET | + D3D11_BIND_SHADER_RESOURCE); + + auto renderTarget = makeRenderTarget(width, height); + renderTarget->setTargetTexture(texture); + + auto renderImage = + make_rcp(adoptImageTexture(texture, width, height)); + + return make_rcp(std::move(renderImage), + std::move(renderTarget)); +} +#endif + class BufferRingD3D : public BufferRing { public: @@ -1303,7 +1443,7 @@ void RenderContextD3DImpl::resizeAtlasTexture(uint32_t width, uint32_t height) } else { - m_atlasTexture = makeSimple2DTexture(DXGI_FORMAT_R32_FLOAT, + m_atlasTexture = makeSimple2DTexture(DXGI_FORMAT_R16_FLOAT, width, height, 1, @@ -1382,6 +1522,7 @@ static D3D11_RECT make_scissor(const TAABB scissor) void RenderContextD3DImpl::flush(const FlushDescriptor& desc) { + RIVE_PROF_GPUNAME_L(0, "RiveFlush"); assert(desc.interlockMode != gpu::InterlockMode::clockwiseAtomic); auto renderTarget = static_cast(desc.renderTarget); @@ -1525,6 +1666,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) // Tessellate all curves into vertices in the tessellation texture. if (desc.tessVertexSpanCount > 0) { + RIVE_PROF_GPUNAME_L(1, "Tessellate Curves"); + ID3D11Buffer* tessSpanBuffer = flush_buffer(m_gpuContext.Get(), tessSpanBufferRing()); UINT tessStride = sizeof(TessVertexSpan); @@ -1607,6 +1750,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) // Render the atlas if we have any offscreen feathers. if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0) { + RIVE_PROF_GPUNAME_L(1, "atlasRender"); + float clearZero[4]{}; m_gpuContext->ClearRenderTargetView(m_atlasTextureRTV.Get(), clearZero); @@ -1616,7 +1761,6 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) m_gpuContext->IASetIndexBuffer(m_patchIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0); - m_gpuContext->RSSetState(m_atlasRasterState.Get()); D3D11_VIEWPORT viewport = {0, 0, @@ -1632,6 +1776,7 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) if (desc.atlasFillBatchCount != 0) { + m_gpuContext->RSSetState(m_atlasFillRasterState.Get()); m_pipelineManager.setAtlasFillState(); m_gpuContext->OMSetBlendState(m_plusBlendState.Get(), NULL, @@ -1659,6 +1804,7 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) if (desc.atlasStrokeBatchCount != 0) { + m_gpuContext->RSSetState(m_atlasStrokeRasterState.Get()); m_pipelineManager.setAtlasStrokeState(); m_gpuContext->OMSetBlendState(m_maxBlendState.Get(), NULL, @@ -1689,65 +1835,76 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) } // Setup and clear the PLS textures. - switch (desc.colorLoadAction) - { - case gpu::LoadAction::clear: - if (desc.atomicFixedFunctionColorOutput) - { - float clearColor4f[4]; - UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f); - m_gpuContext->ClearRenderTargetView(renderTarget->targetRTV(), - clearColor4f); - } - else if (m_d3dCapabilities.supportsTypedUAVLoadStore) - { - float clearColor4f[4]; - UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f); - m_gpuContext->ClearUnorderedAccessViewFloat( - renderTarget->targetUAV(), - clearColor4f); - } - else - { - UINT clearColorui[4] = { - gpu::SwizzleRiveColorToRGBAPremul(desc.colorClearValue)}; - m_gpuContext->ClearUnorderedAccessViewUint( - renderTarget->targetUAV(), - clearColorui); - } - break; - case gpu::LoadAction::preserveRenderTarget: - if (!desc.atomicFixedFunctionColorOutput && - !renderTarget->targetTextureSupportsUAV()) - { - // We're rendering to an offscreen UAV and preserving the - // target. Copy the target texture over. - blit_sub_rect(m_gpuContext.Get(), - renderTarget->offscreenTexture(), - renderTarget->targetTexture(), - desc.renderTargetUpdateBounds); - } - break; - case gpu::LoadAction::dontCare: - break; - } - if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING) - { - constexpr static UINT kZero[4]{}; - m_gpuContext->ClearUnorderedAccessViewUint(renderTarget->clipUAV(), - kZero); - } { - UINT coverageClear[4]{desc.coverageClearValue}; - m_gpuContext->ClearUnorderedAccessViewUint(renderTarget->coverageUAV(), - coverageClear); + RIVE_PROF_GPUNAME_L(1, "clearPLSTextures"); + switch (desc.colorLoadAction) + { + + case gpu::LoadAction::clear: + if (desc.fixedFunctionColorOutput) + { + float clearColor4f[4]; + UnpackColorToRGBA32FPremul(desc.colorClearValue, + clearColor4f); + m_gpuContext->ClearRenderTargetView( + renderTarget->targetRTV(), + clearColor4f); + } + else if (m_d3dCapabilities.supportsTypedUAVLoadStore) + { + float clearColor4f[4]; + UnpackColorToRGBA32FPremul(desc.colorClearValue, + clearColor4f); + m_gpuContext->ClearUnorderedAccessViewFloat( + renderTarget->targetUAV(), + clearColor4f); + } + else + { + UINT clearColorui[4] = {gpu::SwizzleRiveColorToRGBAPremul( + desc.colorClearValue)}; + m_gpuContext->ClearUnorderedAccessViewUint( + renderTarget->targetUAV(), + clearColorui); + } + break; + case gpu::LoadAction::preserveRenderTarget: + if (!desc.fixedFunctionColorOutput && + !renderTarget->targetTextureSupportsUAV()) + { + // We're rendering to an offscreen UAV and preserving the + // target. Copy the target texture over. + blit_sub_rect(m_gpuContext.Get(), + renderTarget->offscreenTexture(), + renderTarget->targetTexture(), + desc.renderTargetUpdateBounds); + } + break; + case gpu::LoadAction::dontCare: + break; + } + if (enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING)) + { + constexpr static UINT kZero[4]{}; + m_gpuContext->ClearUnorderedAccessViewUint(renderTarget->clipUAV(), + kZero); + } + { + UINT coverageClear[4]{desc.coverageClearValue}; + m_gpuContext->ClearUnorderedAccessViewUint( + renderTarget->coverageUAV(), + coverageClear); + } } + RIVE_PROF_GPUNAME_L(1, "DrawList"); + // Execute the DrawList. ID3D11RenderTargetView* targetRTV = - desc.atomicFixedFunctionColorOutput ? renderTarget->targetRTV() : NULL; + desc.fixedFunctionColorOutput ? renderTarget->targetRTV() : NULL; ID3D11UnorderedAccessView* plsUAVs[] = { - desc.atomicFixedFunctionColorOutput ? NULL : renderTarget->targetUAV(), + desc.fixedFunctionColorOutput ? NULL : renderTarget->targetUAV(), renderTarget->clipUAV(), desc.interlockMode == gpu::InterlockMode::rasterOrdering ? renderTarget->scratchColorUAV() @@ -1759,16 +1916,16 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) static_assert(SCRATCH_COLOR_PLANE_IDX == 2); static_assert(COVERAGE_PLANE_IDX == 3); m_gpuContext->OMSetRenderTargetsAndUnorderedAccessViews( - desc.atomicFixedFunctionColorOutput ? 1 : 0, + desc.fixedFunctionColorOutput ? 1 : 0, &targetRTV, NULL, - desc.atomicFixedFunctionColorOutput ? 1 : 0, - desc.atomicFixedFunctionColorOutput ? std::size(plsUAVs) - 1 - : std::size(plsUAVs), - desc.atomicFixedFunctionColorOutput ? plsUAVs + 1 : plsUAVs, + desc.fixedFunctionColorOutput ? 1 : 0, + desc.fixedFunctionColorOutput ? std::size(plsUAVs) - 1 + : std::size(plsUAVs), + desc.fixedFunctionColorOutput ? plsUAVs + 1 : plsUAVs, NULL); - if (desc.atomicFixedFunctionColorOutput) + if (desc.fixedFunctionColorOutput) { // When rendering directly to the target RTV, we use the built-in blend // hardware for opacity and antialiasing. @@ -1800,50 +1957,57 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) bool renderPassHasCoalescedResolveAndTransfer = desc.interlockMode == gpu::InterlockMode::atomics && - !desc.atomicFixedFunctionColorOutput && + !desc.fixedFunctionColorOutput && !renderTarget->targetTextureSupportsUAV(); for (const DrawBatch& batch : *desc.drawList) { DrawType drawType = batch.drawType; + auto shaderFeatures = desc.interlockMode == gpu::InterlockMode::atomics ? desc.combinedShaderFeatures : batch.shaderFeatures; auto shaderMiscFlags = batch.shaderMiscFlags; - if (drawType == gpu::DrawType::atomicResolve && + if (drawType == gpu::DrawType::renderPassResolve && renderPassHasCoalescedResolveAndTransfer) { + assert(desc.interlockMode == gpu::InterlockMode::atomics); shaderMiscFlags |= gpu::ShaderMiscFlags::coalescedResolveAndTransfer; } - if (desc.atomicFixedFunctionColorOutput) - { - shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput; - } - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && - (batch.drawContents & gpu::DrawContents::clockwiseFill)) + + if (!m_pipelineManager.setPipelineState(drawType, + shaderFeatures, + desc.interlockMode, + shaderMiscFlags, + m_platformFeatures +#ifdef WITH_RIVE_TOOLS + , + desc.synthesizedFailureType +#endif + )) { - shaderMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill; + // There was an issue getting either the requested pipeline state or + // its ubershader counterpart so we cannot draw anything. + continue; } - m_pipelineManager.setPipelineState(drawType, - shaderFeatures, - desc.interlockMode, - shaderMiscFlags); - if (auto imageTextureD3D = static_cast(batch.imageTexture)) { m_gpuContext->PSSetShaderResources(IMAGE_TEXTURE_IDX, 1, imageTextureD3D->srvAddressOf()); + } + + { // we should never get a sampler option that is greater then our // array size assert(batch.imageSampler.asKey() < ImageSampler::MAX_SAMPLER_PERMUTATIONS); ID3D11SamplerState* samplers[1] = { m_samplerStates[batch.imageSampler.asKey()].Get()}; - m_gpuContext->PSSetSamplers(IMAGE_SAMPLER_IDX, 1, samplers); + m_gpuContext->PSSetSamplers(IMAGE_TEXTURE_IDX, 1, samplers); } switch (drawType) @@ -1866,6 +2030,7 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) &drawUniforms, 0, 0); + RIVE_PROF_GPUNAME_L(2, "Patches"); m_gpuContext->DrawIndexedInstanced(PatchIndexCount(drawType), batch.elementCount, PatchBaseIndex(drawType), @@ -1880,11 +2045,17 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_gpuContext->RSSetState( m_backCulledRasterState[desc.wireframe].Get()); + RIVE_PROF_GPUNAME_L(2, + drawType == DrawType::atlasBlit + ? "atlasBlit" + : "interiorTriangulation"); m_gpuContext->Draw(batch.elementCount, batch.baseElement); break; } case DrawType::imageRect: { + RIVE_PROF_GPUNAME_L(2, "imageRect"); + m_gpuContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_gpuContext->IASetIndexBuffer(m_imageRectIndexBuffer.Get(), @@ -1906,6 +2077,7 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) } case DrawType::imageMesh: { + RIVE_PROF_GPUNAME_L(2, "imageMesh"); LITE_RTTI_CAST_OR_BREAK(vertexBuffer, RenderBufferD3DImpl*, batch.vertexBuffer); @@ -1945,7 +2117,10 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) 0); break; } - case DrawType::atomicResolve: + case DrawType::renderPassResolve: + { + RIVE_PROF_GPUNAME_L(1, "renderPassResolve"); + assert(desc.interlockMode == gpu::InterlockMode::atomics); m_gpuContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); @@ -1956,8 +2131,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) // the PLS resolve, so we don't have to copy to it after the // render pass. (And ince we're changing the render target, // this also better be the final batch of the render pass.) - assert(&batch == &desc.drawList->tail()); - assert(!desc.atomicFixedFunctionColorOutput); + assert(&batch == desc.drawList->tail()); + assert(!desc.fixedFunctionColorOutput); assert(!renderTarget->targetTextureSupportsUAV()); ID3D11RenderTargetView* resolveRTV = renderTarget->targetRTV(); @@ -1984,8 +2159,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) NULL); } m_gpuContext->Draw(4, 0); - break; - case DrawType::atomicInitialize: + } + break; case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -1993,7 +2168,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: RIVE_UNREACHABLE(); } } @@ -2001,9 +2177,11 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc) if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && !renderTarget->targetTextureSupportsUAV()) { + RIVE_PROF_GPUNAME_L(1, "blit_sub_rect"); + // We rendered to an offscreen UAV and did not resolve to the // renderTarget. Copy back to the main target. - assert(!desc.atomicFixedFunctionColorOutput); + assert(!desc.fixedFunctionColorOutput); assert(!renderPassHasCoalescedResolveAndTransfer); blit_sub_rect(m_gpuContext.Get(), renderTarget->targetTexture(), diff --git a/thirdparty/rive_renderer/source/d3d12/d3d12_pipeline_manager.cpp b/thirdparty/rive_renderer/source/d3d12/d3d12_pipeline_manager.cpp index 47706598e..4d38d7657 100644 --- a/thirdparty/rive_renderer/source/d3d12/d3d12_pipeline_manager.cpp +++ b/thirdparty/rive_renderer/source/d3d12/d3d12_pipeline_manager.cpp @@ -4,18 +4,7 @@ #include "rive/renderer/d3d12/d3d12_pipeline_manager.hpp" #include "rive/renderer/d3d/d3d_constants.hpp" -#include "generated/shaders/advanced_blend.glsl.hpp" -#include "generated/shaders/atomic_draw.glsl.hpp" -#include "generated/shaders/color_ramp.glsl.hpp" -#include "generated/shaders/constants.glsl.hpp" -#include "generated/shaders/common.glsl.hpp" -#include "generated/shaders/draw_image_mesh.glsl.hpp" -#include "generated/shaders/draw_path_common.glsl.hpp" -#include "generated/shaders/draw_path.glsl.hpp" -#include "generated/shaders/hlsl.glsl.hpp" -#include "generated/shaders/bezier_utils.glsl.hpp" -#include "generated/shaders/render_atlas.glsl.hpp" -#include "generated/shaders/tessellate.glsl.hpp" +#include "generated/shaders/tessellate.glsl.exports.h" // offline shaders namespace shader @@ -60,12 +49,9 @@ namespace rive::gpu D3D12PipelineManager::D3D12PipelineManager( ComPtr device, - const D3DCapabilities& capabilities) : - D3DPipelineManager, ID3D12Device>( - device, - capabilities, - "vs_5_1", - "ps_5_1") + const D3DCapabilities& capabilities, + ShaderCompilationMode shaderCompilationMode) : + Super(device, capabilities, shaderCompilationMode, "vs_5_1", "ps_5_1") { VERIFY_OK( this->device()->CreateRootSignature(0, @@ -74,136 +60,107 @@ D3D12PipelineManager::D3D12PipelineManager( IID_PPV_ARGS(&m_rootSignature))); } -ID3D12PipelineState* D3D12PipelineManager::getDrawPipelineState( - DrawType drawType, - gpu::ShaderFeatures shaderFeatures, - gpu::InterlockMode interlockMode, - gpu::ShaderMiscFlags shaderMiscFlags) +std::unique_ptr D3D12PipelineManager:: + compileVertexShaderBlobToFinalType(DrawType drawType, ComPtr blob) { - uint32_t pixelShaderKey = ShaderUniqueKey(drawType, - shaderFeatures, - interlockMode, - shaderMiscFlags); - - auto pipelineEntry = m_drawPipelines.find(pixelShaderKey); - if (pipelineEntry != m_drawPipelines.end()) + auto result = std::make_unique(); + switch (drawType) { - return pipelineEntry->second.Get(); - } - - ShaderCompileResult result{}; - if (!getShader({drawType, - shaderFeatures, - interlockMode, - shaderMiscFlags, - d3dCapabilities()}, - &result)) - { - // this should never happen - RIVE_UNREACHABLE(); + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + result->m_layoutDesc[0] = { + GLSL_a_patchVertexData, + 0, + DXGI_FORMAT_R32G32B32A32_FLOAT, + PATCH_VERTEX_DATA_SLOT, + D3D12_APPEND_ALIGNED_ELEMENT, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}; + result->m_layoutDesc[1] = { + GLSL_a_mirroredVertexData, + 0, + DXGI_FORMAT_R32G32B32A32_FLOAT, + PATCH_VERTEX_DATA_SLOT, + D3D12_APPEND_ALIGNED_ELEMENT, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}; + result->m_vertexAttribCount = 2; + break; + case DrawType::interiorTriangulation: + case DrawType::atlasBlit: + result->m_layoutDesc[0] = { + GLSL_a_triangleVertex, + 0, + DXGI_FORMAT_R32G32B32_FLOAT, + TRIANGLE_VERTEX_DATA_SLOT, + 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}; + result->m_vertexAttribCount = 1; + break; + case DrawType::imageRect: + result->m_layoutDesc[0] = { + GLSL_a_imageRectVertex, + 0, + DXGI_FORMAT_R32G32B32A32_FLOAT, + IMAGE_RECT_VERTEX_DATA_SLOT, + 0, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}; + result->m_vertexAttribCount = 1; + break; + case DrawType::imageMesh: + result->m_layoutDesc[0] = { + GLSL_a_position, + 0, + DXGI_FORMAT_R32G32_FLOAT, + IMAGE_MESH_VERTEX_DATA_SLOT, + D3D12_APPEND_ALIGNED_ELEMENT, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}; + result->m_layoutDesc[1] = { + GLSL_a_texCoord, + 0, + DXGI_FORMAT_R32G32_FLOAT, + IMAGE_MESH_UV_DATA_SLOT, + D3D12_APPEND_ALIGNED_ELEMENT, + D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, + 0}; + result->m_vertexAttribCount = 2; + break; + case DrawType::renderPassResolve: + result->m_vertexAttribCount = 0; + break; + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + RIVE_UNREACHABLE(); } - return static_cast(result.resultData); + result->m_shader = blob; + return result; } -void D3D12PipelineManager::compileBlobToFinalType( - const ShaderCompileRequest& request, - ComPtr vertexShader, - ComPtr pixelShader, - ShaderCompileResult* result) +std::unique_ptr D3D12PipelineManager:: + compilePixelShaderBlobToFinalType(ComPtr blob) { - if (!result->vertexResult.hasResult) - { - switch (request.drawType) - { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - result->vertexResult.vertexShaderResult.m_layoutDesc[0] = { - GLSL_a_patchVertexData, - 0, - DXGI_FORMAT_R32G32B32A32_FLOAT, - PATCH_VERTEX_DATA_SLOT, - D3D12_APPEND_ALIGNED_ELEMENT, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}; - result->vertexResult.vertexShaderResult.m_layoutDesc[1] = { - GLSL_a_mirroredVertexData, - 0, - DXGI_FORMAT_R32G32B32A32_FLOAT, - PATCH_VERTEX_DATA_SLOT, - D3D12_APPEND_ALIGNED_ELEMENT, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}; - result->vertexResult.vertexShaderResult.m_vertexAttribCount = 2; - break; - case DrawType::interiorTriangulation: - case DrawType::atlasBlit: - result->vertexResult.vertexShaderResult.m_layoutDesc[0] = { - GLSL_a_triangleVertex, - 0, - DXGI_FORMAT_R32G32B32_FLOAT, - TRIANGLE_VERTEX_DATA_SLOT, - 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}; - result->vertexResult.vertexShaderResult.m_vertexAttribCount = 1; - break; - case DrawType::imageRect: - result->vertexResult.vertexShaderResult.m_layoutDesc[0] = { - GLSL_a_imageRectVertex, - 0, - DXGI_FORMAT_R32G32B32A32_FLOAT, - IMAGE_RECT_VERTEX_DATA_SLOT, - 0, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}; - result->vertexResult.vertexShaderResult.m_vertexAttribCount = 1; - break; - case DrawType::imageMesh: - result->vertexResult.vertexShaderResult.m_layoutDesc[0] = { - GLSL_a_position, - 0, - DXGI_FORMAT_R32G32_FLOAT, - IMAGE_MESH_VERTEX_DATA_SLOT, - D3D12_APPEND_ALIGNED_ELEMENT, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}; - result->vertexResult.vertexShaderResult.m_layoutDesc[1] = { - GLSL_a_texCoord, - 0, - DXGI_FORMAT_R32G32_FLOAT, - IMAGE_MESH_UV_DATA_SLOT, - D3D12_APPEND_ALIGNED_ELEMENT, - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, - 0}; - result->vertexResult.vertexShaderResult.m_vertexAttribCount = 2; - break; - case DrawType::atomicResolve: - result->vertexResult.vertexShaderResult.m_vertexAttribCount = 0; - break; - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); - } - - result->vertexResult.vertexShaderResult.m_shader = vertexShader; - result->vertexResult.hasResult = true; - } - - if (result->pixelResult.hasResult == false) - { - result->pixelResult.pixelShaderResult = pixelShader; - result->pixelResult.hasResult = true; - } + auto result = std::make_unique(); + result->m_shader = std::move(blob); + return result; +} +std::unique_ptr D3D12PipelineManager::linkPipeline( + const PipelineProps& props, + const D3D12DrawVertexShader& vs, + const D3D12DrawPixelShader& ps) +{ ComPtr pipelineState; D3D12_RASTERIZER_DESC rasterDesc = {}; @@ -216,7 +173,7 @@ void D3D12PipelineManager::compileBlobToFinalType( rasterDesc.MultisampleEnable = FALSE; rasterDesc.AntialiasedLineEnable = FALSE; - switch (request.drawType) + switch (props.drawType) { case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: @@ -227,10 +184,9 @@ void D3D12PipelineManager::compileBlobToFinalType( break; case DrawType::imageRect: case DrawType::imageMesh: - case DrawType::atomicResolve: + case DrawType::renderPassResolve: rasterDesc.CullMode = D3D12_CULL_MODE_NONE; break; - case DrawType::atomicInitialize: case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -238,15 +194,15 @@ void D3D12PipelineManager::compileBlobToFinalType( case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: break; } D3D12_BLEND_DESC blendDesc{}; blendDesc.RenderTarget[0].BlendEnable = - request.shaderMiscFlags & - (ShaderMiscFlags::fixedFunctionColorOutput | - ShaderMiscFlags::coalescedResolveAndTransfer); + enums::is_flag_set(props.shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput); blendDesc.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE; blendDesc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; @@ -254,20 +210,17 @@ void D3D12PipelineManager::compileBlobToFinalType( blendDesc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; blendDesc.RenderTarget[0].RenderTargetWriteMask = - request.shaderMiscFlags & (ShaderMiscFlags::fixedFunctionColorOutput | - ShaderMiscFlags::coalescedResolveAndTransfer) + enums::any_flag_set(props.shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput | + ShaderMiscFlags::coalescedResolveAndTransfer) ? D3D12_COLOR_WRITE_ENABLE_ALL : 0; D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; - psoDesc.InputLayout = { - result->vertexResult.vertexShaderResult.m_layoutDesc, - result->vertexResult.vertexShaderResult.m_vertexAttribCount}; + psoDesc.InputLayout = {vs.m_layoutDesc, vs.m_vertexAttribCount}; psoDesc.pRootSignature = m_rootSignature.Get(); - psoDesc.VS = CD3DX12_SHADER_BYTECODE( - result->vertexResult.vertexShaderResult.m_shader.Get()); - psoDesc.PS = - CD3DX12_SHADER_BYTECODE(result->pixelResult.pixelShaderResult.Get()); + psoDesc.VS = CD3DX12_SHADER_BYTECODE(vs.m_shader.Get()); + psoDesc.PS = CD3DX12_SHADER_BYTECODE(ps.m_shader.Get()); psoDesc.RasterizerState = rasterDesc; psoDesc.BlendState = blendDesc; psoDesc.DepthStencilState.DepthEnable = FALSE; @@ -278,13 +231,22 @@ void D3D12PipelineManager::compileBlobToFinalType( psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; - VERIFY_OK( - device()->CreateGraphicsPipelineState(&psoDesc, - IID_PPV_ARGS(&pipelineState))); + auto result = std::make_unique(); +#ifdef WITH_RIVE_TOOLS + if (props.synthesizedFailureType == + SynthesizedFailureType::pipelineCreation || + props.synthesizedFailureType == + SynthesizedFailureType::shaderCompilation) + { + // An empty result is what counts as "failed" + return result; + } +#endif - result->resultData = - m_drawPipelines.insert({result->pixelShaderKey, pipelineState}) - .first->second.Get(); + VERIFY_OK(device()->CreateGraphicsPipelineState( + &psoDesc, + IID_PPV_ARGS(&result->m_d3dPipelineState))); + return result; } void D3D12PipelineManager::compileTesselationPipeline() @@ -475,7 +437,7 @@ void D3D12PipelineManager::compileAtlasPipeline() psoDesc.SampleMask = UINT_MAX; psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; psoDesc.NumRenderTargets = 1; - psoDesc.RTVFormats[0] = DXGI_FORMAT_R32_FLOAT; + psoDesc.RTVFormats[0] = DXGI_FORMAT_R16_FLOAT; psoDesc.SampleDesc.Count = 1; VERIFY_OK(device()->CreateGraphicsPipelineState( @@ -484,6 +446,7 @@ void D3D12PipelineManager::compileAtlasPipeline() psoDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; psoDesc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; + psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; psoDesc.PS = {shader::atlas::fill::g_main, std::size(shader::atlas::fill::g_main)}; @@ -492,4 +455,4 @@ void D3D12PipelineManager::compileAtlasPipeline() &psoDesc, IID_PPV_ARGS(&m_atlasFillPipeline))); } -} // namespace rive::gpu \ No newline at end of file +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/d3d12/d3d12_utils.cpp b/thirdparty/rive_renderer/source/d3d12/d3d12_utils.cpp index 62f40634b..f9f3d181b 100644 --- a/thirdparty/rive_renderer/source/d3d12/d3d12_utils.cpp +++ b/thirdparty/rive_renderer/source/d3d12/d3d12_utils.cpp @@ -128,6 +128,37 @@ void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device, device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle); } +void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device, + D3D12Buffer* resource, + UINT index, + UINT numElements, + UINT elementByteStride, + UINT gpuByteStride, + UINT64 firstElement) +{ + assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + assert(elementByteStride % gpuByteStride == 0); + + const UINT cpuScale = elementByteStride / gpuByteStride; + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + srvDesc.Buffer.FirstElement = firstElement * cpuScale; + srvDesc.Buffer.NumElements = numElements * cpuScale; + srvDesc.Buffer.StructureByteStride = gpuByteStride; + srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + srvDesc.Format = resource->desc().Format; + + CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle( + m_heap->GetCPUDescriptorHandleForHeapStart(), + index, + m_heapDescriptorSize); + + device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle); +} + void D3D12DescriptorHeap::markUavToIndex(ID3D12Device* device, D3D12Buffer* resource, DXGI_FORMAT format, @@ -180,6 +211,51 @@ void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device, device->CreateShaderResourceView(resource->resource(), &srvDesc, srvHandle); } +void D3D12DescriptorHeap::markNullTexture2DSrvToIndex(ID3D12Device* device, + UINT index, + DXGI_FORMAT format) +{ + assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Format = format; + srvDesc.Texture2D.MipLevels = 1; + srvDesc.Texture2D.PlaneSlice = 0; + + CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle( + m_heap->GetCPUDescriptorHandleForHeapStart(), + index, + m_heapDescriptorSize); + + device->CreateShaderResourceView(nullptr, &srvDesc, srvHandle); +} + +void D3D12DescriptorHeap::markNullStructuredBufferSrvToIndex( + ID3D12Device* device, + UINT index, + UINT elementByteStride) +{ + assert(m_type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + srvDesc.Format = DXGI_FORMAT_UNKNOWN; + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.NumElements = 0; + srvDesc.Buffer.StructureByteStride = elementByteStride; + srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + + CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle( + m_heap->GetCPUDescriptorHandleForHeapStart(), + index, + m_heapDescriptorSize); + + device->CreateShaderResourceView(nullptr, &srvDesc, srvHandle); +} + void D3D12DescriptorHeap::markSrvToIndex(ID3D12Device* device, D3D12TextureArray* resource, UINT index) @@ -236,6 +312,11 @@ void D3D12DescriptorHeap::markRtvToIndex(ID3D12Device* device, D3D12_RENDER_TARGET_VIEW_DESC RTVDesc = {}; RTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + RTVDesc.Format = resource->desc().Format; + if (DXGI_FORMAT_R8G8B8A8_TYPELESS == RTVDesc.Format) + { + RTVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + } RTVDesc.Texture2D.MipSlice = 0; CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle( @@ -379,7 +460,7 @@ void D3D12VolatileBuffer::resizeBuffers(UINT newSize) { m_uploadBuffer = d3d()->makeUploadBuffer(newSize, D3D12_RESOURCE_FLAG_NONE, - D3D12_RESOURCE_STATE_COPY_SOURCE); + D3D12_RESOURCE_STATE_GENERIC_READ); m_gpuBuffer = d3d()->makeBuffer(newSize, m_bindFlags, D3D12_RESOURCE_STATE_COMMON, diff --git a/thirdparty/rive_renderer/source/d3d12/render_context_d3d12_impl.cpp b/thirdparty/rive_renderer/source/d3d12/render_context_d3d12_impl.cpp index 42a227183..074920473 100644 --- a/thirdparty/rive_renderer/source/d3d12/render_context_d3d12_impl.cpp +++ b/thirdparty/rive_renderer/source/d3d12/render_context_d3d12_impl.cpp @@ -4,17 +4,18 @@ #include "rive/renderer/d3d12/render_context_d3d12_impl.hpp" #include "rive/renderer/d3d/d3d_constants.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif +#include "rive/profiler/profiler_macros.h" +#include "rive/renderer/d3d/d3d_utils.hpp" + // needed for root sig and heap constants #include "shaders/d3d/root.sig" -#ifdef RIVE_DECODERS -#include "rive/decoders/bitmap_decoder.hpp" -#endif - #include #include -#include // this is defined here instead of root_sig becaise the gpu does not care about // the number of rtvs this is gradient, tess, atlas and color static constexpr UINT NUM_RTV_HEAP_DESCRIPTORS = 4; @@ -25,14 +26,14 @@ static constexpr D3D12_FILTER filter_for_sampler_options(ImageFilter option) { switch (option) { - case ImageFilter::trilinear: - return D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; case ImageFilter::nearest: - return D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT; + return D3D12_FILTER_MIN_MAG_MIP_POINT; + case ImageFilter::bilinear: + return D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; } RIVE_UNREACHABLE(); - return D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; + return D3D12_FILTER_MIN_MAG_MIP_LINEAR; }; static constexpr D3D12_TEXTURE_ADDRESS_MODE address_mode_for_sampler_option( @@ -95,51 +96,113 @@ void RenderContextD3D12Impl::blitSubRect(ID3D12GraphicsCommandList* cmdList, class TextureD3D12Impl : public Texture { public: + TextureD3D12Impl(rcp externalTexture) : + Texture(static_cast(externalTexture->width()), + static_cast(externalTexture->height())), + m_gpuTexture(std::move(externalTexture)) + {} + TextureD3D12Impl(D3D12ResourceManager* manager, UINT width, UINT height, UINT mipLevel, - const uint8_t imageDataRGBA[]) : - Texture(width, height), - m_gpuTexture(manager->make2DTexture(width, - height, - mipLevel, - DXGI_FORMAT_R8G8B8A8_UNORM, - D3D12_RESOURCE_FLAG_NONE, - D3D12_RESOURCE_STATE_COPY_DEST)) + GPUTextureFormat format, + const uint8_t imageData[], + bool usesCommandList) : + Texture(width, height) + { - D3D12_SUBRESOURCE_DATA srcData; - srcData.pData = imageDataRGBA; - srcData.RowPitch = width * 4; - srcData.SlicePitch = srcData.RowPitch * height; - - UINT numRows; - UINT64 rowSizeInBtes; - UINT64 totalBytes; - auto desc = m_gpuTexture->resource()->GetDesc(); - manager->device()->GetCopyableFootprints(&desc, - 0, - 1, - 0, - &m_uploadFootprint, - &numRows, - &rowSizeInBtes, - &totalBytes); - - m_uploadBuffer = manager->makeUploadBuffer( - static_cast(totalBytes) + - D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); - - D3D12_MEMCPY_DEST DestData = { - m_uploadBuffer->map(), - m_uploadFootprint.Footprint.RowPitch, - SIZE_T(m_uploadFootprint.Footprint.RowPitch * numRows)}; - - MemcpySubresource(&DestData, - &srcData, - static_cast(rowSizeInBtes), - numRows, - m_uploadFootprint.Footprint.Depth); + DXGI_FORMAT d3dFormat = d3d_utils::convert_format(format); + + m_gpuTexture = manager->make2DTexture( + width, + height, + mipLevel, + d3dFormat, + D3D12_RESOURCE_FLAG_NONE, + usesCommandList ? D3D12_RESOURCE_STATE_COMMON + : D3D12_RESOURCE_STATE_COPY_DEST); + + if (format == GPUTextureFormat::bc7) + { + // imageData contains already compressed data, so we can directly + // upload it to the GPU All mip levels are in this sequentially + auto desc = m_gpuTexture->resource()->GetDesc(); + + UINT numRows = 0; + UINT64 rowSizeInBytes = 0; + UINT64 totalBytes = 0; + + m_subresourceFootprints.resize(mipLevel); + + manager->device()->GetCopyableFootprints( + &desc, + 0, // First subresource + mipLevel, // Number of mips + 0, // Base offset + m_subresourceFootprints.data(), // One footprint per mip + &numRows, + &rowSizeInBytes, + &totalBytes); + + m_uploadBuffer = manager->makeUploadBuffer( + static_cast(totalBytes) + + D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); + + uint8_t* dst = reinterpret_cast(m_uploadBuffer->map()); + const uint8_t* src = imageData; + + for (UINT mip = 0; mip < mipLevel; ++mip) + { + const auto& fp = m_subresourceFootprints[mip].Footprint; + + UINT64 mipSize = fp.RowPitch * fp.Height; + + memcpy(dst + m_subresourceFootprints[mip].Offset, src, mipSize); + + src += mipSize; // advance to next mip in your BC7 blob + } + } + else if (format == GPUTextureFormat::rgba32) + { + D3D12_SUBRESOURCE_DATA srcData; + srcData.pData = imageData; + srcData.RowPitch = width * 4; + srcData.SlicePitch = srcData.RowPitch * height; + + UINT numRows; + UINT64 rowSizeInBtes; + UINT64 totalBytes; + auto desc = m_gpuTexture->resource()->GetDesc(); + SNAME_D3D12_OBJECT(m_gpuTexture, "riveImage"); + manager->device()->GetCopyableFootprints(&desc, + 0, + 1, + 0, + &m_uploadFootprint, + &numRows, + &rowSizeInBtes, + &totalBytes); + + m_uploadBuffer = manager->makeUploadBuffer( + static_cast(totalBytes) + + D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); + + D3D12_MEMCPY_DEST DestData = { + m_uploadBuffer->map(), + m_uploadFootprint.Footprint.RowPitch, + SIZE_T(m_uploadFootprint.Footprint.RowPitch * numRows)}; + + MemcpySubresource(&DestData, + &srcData, + static_cast(rowSizeInBtes), + numRows, + m_uploadFootprint.Footprint.Depth); + } + else + { + assert(!"unsupported format"); + } } D3D12Texture* synchronize(ID3D12GraphicsCommandList* copyList, @@ -148,17 +211,37 @@ class TextureD3D12Impl : public Texture { if (m_uploadBuffer) { - const CD3DX12_TEXTURE_COPY_LOCATION dst(m_gpuTexture->resource(), - 0); - const CD3DX12_TEXTURE_COPY_LOCATION src(m_uploadBuffer->resource(), - m_uploadFootprint); - - copyList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + if (!m_subresourceFootprints.empty()) + { + // BC7: copy each mip level to its own subresource. + for (UINT mip = 0; + mip < static_cast(m_subresourceFootprints.size()); + ++mip) + { + const CD3DX12_TEXTURE_COPY_LOCATION dst( + m_gpuTexture->resource(), + mip); + const CD3DX12_TEXTURE_COPY_LOCATION src( + m_uploadBuffer->resource(), + m_subresourceFootprints[mip]); + copyList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + } + } + else + { + // RGBA: single subresource copy. + const CD3DX12_TEXTURE_COPY_LOCATION dst( + m_gpuTexture->resource(), + 0); + const CD3DX12_TEXTURE_COPY_LOCATION src( + m_uploadBuffer->resource(), + m_uploadFootprint); + copyList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + } manager->transition(cmdList, m_gpuTexture.get(), D3D12_RESOURCE_STATE_GENERIC_READ); - m_uploadBuffer = nullptr; } @@ -166,11 +249,18 @@ class TextureD3D12Impl : public Texture } D3D12Texture* resource() const { return m_gpuTexture.get(); } + void* nativeHandle() const override + { + return static_cast(m_gpuTexture.get()); + } private: mutable rcp m_uploadBuffer; - const rcp m_gpuTexture; - D3D12_PLACED_SUBRESOURCE_FOOTPRINT m_uploadFootprint; + rcp m_gpuTexture; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT + m_uploadFootprint; // RGBA path (single subresource) + std::vector + m_subresourceFootprints; // BC7 path (per-mip) }; class RenderBufferD3D12Impl @@ -189,7 +279,8 @@ class RenderBufferD3D12Impl m_uploadBuffer = manager->makeUploadBuffer(static_cast(sizeInBytes)); - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { mappedOnceMempry = m_uploadBuffer->map(); } @@ -213,7 +304,9 @@ class RenderBufferD3D12Impl D3D12_RESOURCE_STATE_COMMON); cmdList->ResourceBarrier(1, &barrier); - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set( + flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { m_uploadBuffer = nullptr; } @@ -227,7 +320,8 @@ class RenderBufferD3D12Impl { assert(m_uploadBuffer); needsUpload = true; - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { assert(mappedOnceMempry); return mappedOnceMempry; @@ -241,7 +335,8 @@ class RenderBufferD3D12Impl void onUnmap() override { assert(m_uploadBuffer); - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { assert(mappedOnceMempry); m_uploadBuffer->unmap(); @@ -322,7 +417,7 @@ void RenderTargetD3D12::setTargetTexture(ComPtr tex) m_targetTexture = m_manager->makeExternalTexture(tex, D3D12_RESOURCE_STATE_PRESENT); - SNAME_D3D12_OBJECT(m_targetTexture, "color"); + SNAME_D3D12_OBJECT(m_targetTexture, "colorExternal"); } D3D12Texture* RenderTargetD3D12::offscreenTexture() @@ -411,7 +506,7 @@ void RenderTargetD3D12::markScratchColorUAV(D3D12DescriptorHeap* heap) 1, DXGI_FORMAT_R8G8B8A8_TYPELESS, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_HEAP_FLAG_ALLOW_SHADER_ATOMICS); SNAME_D3D12_OBJECT(m_scratchColorTexture, "scratchColor"); } @@ -459,7 +554,7 @@ std::unique_ptr RenderContextD3D12Impl::MakeContext( sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS)))) { d3dCapabilities.supportsRasterizerOrderedViews = - d3d12Options.ROVsSupported; + d3d12Options.ROVsSupported && !contextOptions.isIntelArc; if (d3d12Options.TypedUAVLoadAdditionalFormats) { // TypedUAVLoadAdditionalFormats is true. Now check if we can @@ -506,17 +601,21 @@ std::unique_ptr RenderContextD3D12Impl::MakeContext( d3dCapabilities.isIntel = contextOptions.isIntel; auto renderContextImpl = std::unique_ptr( - new RenderContextD3D12Impl(device, copyCommandList, d3dCapabilities)); + new RenderContextD3D12Impl(device, + copyCommandList, + d3dCapabilities, + contextOptions.shaderCompilationMode)); return std::make_unique(std::move(renderContextImpl)); } RenderContextD3D12Impl::RenderContextD3D12Impl( ComPtr device, ID3D12GraphicsCommandList* copyCommandList, - const D3DCapabilities& capabilities) : + const D3DCapabilities& capabilities, + ShaderCompilationMode shaderCompilationMode) : m_device(device), m_capabilities(capabilities), - m_pipelineManager(device, capabilities), + m_pipelineManager(device, capabilities, shaderCompilationMode), m_resourceManager(make_rcp(device)), m_flushUniformBufferPool(m_resourceManager, sizeof(FlushUniforms)), m_imageDrawUniformBufferPool(m_resourceManager, sizeof(ImageDrawUniforms)), @@ -544,10 +643,12 @@ RenderContextD3D12Impl::RenderContextD3D12Impl( m_platformFeatures.clipSpaceBottomUp = true; m_platformFeatures.framebufferBottomUp = false; - m_platformFeatures.supportsRasterOrdering = + m_platformFeatures.supportsRasterOrderingMode = m_capabilities.supportsRasterizerOrderedViews; - m_platformFeatures.supportsFragmentShaderAtomics = true; + m_platformFeatures.supportsAtomicMode = true; m_platformFeatures.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; + // BC1–BC7 are required at D3D feature level 11.0+. + m_platformFeatures.supportsTextureCompressionBC = true; m_rtvHeap = m_resourceManager->makeHeap(NUM_RTV_HEAP_DESCRIPTORS, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, @@ -619,7 +720,7 @@ RenderContextD3D12Impl::RenderContextD3D12Impl( 1, DXGI_FORMAT_R16_FLOAT, D3D12_RESOURCE_FLAG_NONE, - D3D12_RESOURCE_STATE_COPY_DEST); + D3D12_RESOURCE_STATE_COMMON); NAME_D3D12_OBJECT(m_featherTexture); auto featherUploadBuffer = m_resourceManager->makeUploadBuffer( sizeof(gpu::g_inverseGaussianIntegralTableF16) * 2); @@ -649,10 +750,6 @@ RenderContextD3D12Impl::RenderContextD3D12Impl( 1, 1, &updateData2); - - m_resourceManager->transition(copyCommandList, - m_featherTexture.get(), - D3D12_RESOURCE_STATE_COMMON); } rcp RenderContextD3D12Impl::makeRenderBuffer( @@ -670,15 +767,48 @@ rcp RenderContextD3D12Impl::makeImageTexture( uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) { return make_rcp(m_resourceManager.get(), width, height, mipLevelCount, - imageDataRGBAPremul); + format, + imageDataRGBAPremul, + m_usesCopyCommandList); } +rcp RenderContextD3D12Impl::adoptImageTexture( + rcp imageTexture) +{ + return make_rcp(std::move(imageTexture)); +} + +#ifdef RIVE_CANVAS +rcp RenderContextD3D12Impl::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + auto texture = + manager()->make2DTexture(width, + height, + 1, + DXGI_FORMAT_R8G8B8A8_UNORM, + D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS | + D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, + D3D12_RESOURCE_STATE_COMMON); + + auto renderTarget = make_rcp(this, width, height); + renderTarget->setTargetTexture(texture); + + auto renderImage = + make_rcp(adoptImageTexture(std::move(texture))); + + return make_rcp(std::move(renderImage), + std::move(renderTarget)); +} +#endif + void rive::gpu::RenderContextD3D12Impl::resizeGradientTexture(uint32_t width, uint32_t height) { @@ -737,13 +867,13 @@ void rive::gpu::RenderContextD3D12Impl::resizeAtlasTexture(uint32_t width, else { - D3D12_CLEAR_VALUE clear{DXGI_FORMAT_R32_FLOAT, {}}; + D3D12_CLEAR_VALUE clear{DXGI_FORMAT_R16_FLOAT, {}}; m_atlasTexture = m_resourceManager->make2DTexture( width, height, 1, - DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R16_FLOAT, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_STATE_COMMON, D3D12_HEAP_FLAG_NONE, @@ -756,6 +886,73 @@ void rive::gpu::RenderContextD3D12Impl::resizeAtlasTexture(uint32_t width, } } +// Internal struct to hold D3D12 canvas command buffer resources. +// Allocated by makeCommandBuffer(), freed by commitCommandBuffer(). +struct CanvasCommandBuffer +{ + RenderContextD3D12Impl::CommandLists lists; + ComPtr allocator; + ComPtr commandList; +}; + +void* RenderContextD3D12Impl::makeCommandBuffer() +{ + if (m_canvasQueue == nullptr) + { + return nullptr; + } + auto* cb = new CanvasCommandBuffer(); + HRESULT hr = + m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(&cb->allocator)); + if (FAILED(hr)) + { + delete cb; + return nullptr; + } + hr = m_device->CreateCommandList(0, + D3D12_COMMAND_LIST_TYPE_DIRECT, + cb->allocator.Get(), + nullptr, + IID_PPV_ARGS(&cb->commandList)); + if (FAILED(hr)) + { + delete cb; + return nullptr; + } + cb->lists.copyComandList = nullptr; // use direct list for everything + cb->lists.directComandList = cb->commandList.Get(); + return &cb->lists; +} + +void RenderContextD3D12Impl::commitCommandBuffer(void* commandBuffer) +{ + if (commandBuffer == nullptr) + { + return; + } + // Recover the CanvasCommandBuffer from the CommandLists pointer. + auto* lists = static_cast(commandBuffer); + auto* cb = reinterpret_cast( + reinterpret_cast(lists) - offsetof(CanvasCommandBuffer, lists)); + cb->commandList->Close(); + ID3D12CommandList* ppCommandLists[] = {cb->commandList.Get()}; + m_canvasQueue->ExecuteCommandLists(1, ppCommandLists); + + // Wait for completion so the canvas texture is ready for compositing. + ComPtr fence; + m_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); + m_canvasQueue->Signal(fence.Get(), 1); + if (fence->GetCompletedValue() < 1) + { + HANDLE event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + fence->SetEventOnCompletion(1, event); + WaitForSingleObject(event, INFINITE); + CloseHandle(event); + } + delete cb; +} + void RenderContextD3D12Impl::prepareToFlush(uint64_t nextFrameNumber, uint64_t safeFrameNumber) { @@ -776,7 +973,14 @@ void RenderContextD3D12Impl::prepareToFlush(uint64_t nextFrameNumber, // Advance the context frame and delete resources that are no longer // referenced by in-flight command buffers. - m_resourceManager->advanceFrameNumber(nextFrameNumber, safeFrameNumber); + // When nextFrameNumber is 0 this is a canvas pre-pass flush that uses its + // own command buffer (via makeCommandBuffer/commitCommandBuffer). Skip + // advancing the frame number because the pre-pass executes synchronously + // and doesn't participate in frame lifetime tracking. + if (nextFrameNumber != 0) + { + m_resourceManager->advanceFrameNumber(nextFrameNumber, safeFrameNumber); + } // Acquire buffers for the flush. m_flushUniformBuffer = m_flushUniformBufferPool.acquire(); @@ -812,6 +1016,7 @@ void RenderContextD3D12Impl::prepareToFlush(uint64_t nextFrameNumber, void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) { + RIVE_PROF_GPUNAME_L(0, "RiveFlush"); CommandLists* commandLists = static_cast(desc.externalCommandBuffer); assert(commandLists); @@ -821,7 +1026,15 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) // it's ok but less efficient to use one command list for everything // and a copy command list may not be guaranteed on certain platforms if (!copyCmdList) + { copyCmdList = cmdList; + m_usesCopyCommandList = false; + } + else + { + m_usesCopyCommandList = true; + } + assert(copyCmdList); assert(cmdList); @@ -900,25 +1113,50 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) targetTexture, TARGET_RTV_HEAP_OFFSET); // mark all the texture srvs, these also only need to be done once per - // flush since the texture aren't re created per logical flush + // flush since the texture aren't re created per logical flush. When + // the source texture is not currently allocated we still need to write + // a valid (null) descriptor — the cpu heap is acquired from a pool and + // can retain stale descriptors from prior frames, which would trip + // GPU-Based Validation (id=1042) when STATIC_SRV is bound. if (m_gradientTexture) { m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), m_gradientTexture.get(), GRAD_IMAGE_HEAP_OFFSET); } + else + { + m_cpuSrvUavCbvHeap->markNullTexture2DSrvToIndex( + m_device.Get(), + GRAD_IMAGE_HEAP_OFFSET, + DXGI_FORMAT_R8G8B8A8_UNORM); + } if (m_tesselationTexture) { m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), m_tesselationTexture.get(), TESS_IMAGE_HEAP_OFFSET); } + else + { + m_cpuSrvUavCbvHeap->markNullTexture2DSrvToIndex( + m_device.Get(), + TESS_IMAGE_HEAP_OFFSET, + DXGI_FORMAT_R32G32B32A32_UINT); + } if (m_atlasTexture) { m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), m_atlasTexture.get(), ATLAS_IMAGE_HEAP_OFFSET); } + else + { + m_cpuSrvUavCbvHeap->markNullTexture2DSrvToIndex( + m_device.Get(), + ATLAS_IMAGE_HEAP_OFFSET, + DXGI_FORMAT_R16_FLOAT); + } assert(m_featherTexture); m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), m_featherTexture.get(), @@ -993,51 +1231,83 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) if (desc.pathCount > 0) { - m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), - m_pathBuffer->resource(), - PATH_BUFFER_HEAP_OFFSET, - desc.pathCount, - sizeof(PathData), - desc.firstPath); - - m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), - m_paintBuffer->resource(), - PAINT_BUFFER_HEAP_OFFSET, - desc.pathCount, - sizeof(PaintData), - desc.firstPaint); - - m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), - m_paintAuxBuffer->resource(), - PAINT_AUX_BUFFER_HEAP_OFFSET, - desc.pathCount, - sizeof(PaintAuxData), - desc.firstPaintAux); + m_cpuSrvUavCbvHeap->markSrvToIndex( + m_device.Get(), + m_pathBuffer->resource(), + PATH_BUFFER_HEAP_OFFSET, + desc.pathCount, + sizeof(PathData), + StorageBufferElementSizeInBytes(PathData::kBufferStructure), + desc.firstPath); + + m_cpuSrvUavCbvHeap->markSrvToIndex( + m_device.Get(), + m_paintBuffer->resource(), + PAINT_BUFFER_HEAP_OFFSET, + desc.pathCount, + sizeof(PaintData), + StorageBufferElementSizeInBytes(PaintData::kBufferStructure), + desc.firstPaint); + + m_cpuSrvUavCbvHeap->markSrvToIndex( + m_device.Get(), + m_paintAuxBuffer->resource(), + PAINT_AUX_BUFFER_HEAP_OFFSET, + desc.pathCount, + sizeof(PaintAuxData), + StorageBufferElementSizeInBytes(PaintAuxData::kBufferStructure), + desc.firstPaintAux); + } + else + { + // Same reason as the texture-SRV null-fallback above — recycled cpu + // heap slots may retain stale buffer descriptors. + m_cpuSrvUavCbvHeap->markNullStructuredBufferSrvToIndex( + m_device.Get(), + PATH_BUFFER_HEAP_OFFSET, + StorageBufferElementSizeInBytes(PathData::kBufferStructure)); + m_cpuSrvUavCbvHeap->markNullStructuredBufferSrvToIndex( + m_device.Get(), + PAINT_BUFFER_HEAP_OFFSET, + StorageBufferElementSizeInBytes(PaintData::kBufferStructure)); + m_cpuSrvUavCbvHeap->markNullStructuredBufferSrvToIndex( + m_device.Get(), + PAINT_AUX_BUFFER_HEAP_OFFSET, + StorageBufferElementSizeInBytes(PaintAuxData::kBufferStructure)); } if (desc.contourCount > 0) { - m_cpuSrvUavCbvHeap->markSrvToIndex(m_device.Get(), - m_contourBuffer->resource(), - CONTOUR_BUFFER_HEAP_OFFSET, - desc.contourCount, - sizeof(ContourData), - desc.firstContour); + m_cpuSrvUavCbvHeap->markSrvToIndex( + m_device.Get(), + m_contourBuffer->resource(), + CONTOUR_BUFFER_HEAP_OFFSET, + desc.contourCount, + sizeof(ContourData), + StorageBufferElementSizeInBytes(ContourData::kBufferStructure), + desc.firstContour); + } + else + { + m_cpuSrvUavCbvHeap->markNullStructuredBufferSrvToIndex( + m_device.Get(), + CONTOUR_BUFFER_HEAP_OFFSET, + StorageBufferElementSizeInBytes(ContourData::kBufferStructure)); } // copy to gpu heap + const UINT dynamicSrvHeapIndex = + m_heapDescriptorOffset + DYNAMIC_SRV_UAV_HEAP_DESCRIPTOPR_START; m_device->CopyDescriptorsSimple( NUM_DYNAMIC_SRV_HEAP_DESCRIPTORS, - m_srvUavCbvHeap->cpuHandleForUpload( - m_heapDescriptorOffset + DYNAMIC_SRV_UAV_HEAP_DESCRIPTOPR_START), + m_srvUavCbvHeap->cpuHandleForUpload(dynamicSrvHeapIndex), m_cpuSrvUavCbvHeap->cpuHandleForIndex( DYNAMIC_SRV_UAV_HEAP_DESCRIPTOPR_START), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); cmdList->SetGraphicsRootDescriptorTable( DYNAMIC_SRV_SIG_INDEX, - m_srvUavCbvHeap->gpuHandleForIndex( - m_heapDescriptorOffset + DYNAMIC_SRV_UAV_HEAP_DESCRIPTOPR_START)); + m_srvUavCbvHeap->gpuHandleForIndex(dynamicSrvHeapIndex)); if (desc.gradSpanCount) { @@ -1092,6 +1362,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) if (desc.tessVertexSpanCount) { + RIVE_PROF_GPUNAME_L(1, "Tessellate Curves"); + m_resourceManager->transition(cmdList, m_tesselationTexture.get(), D3D12_RESOURCE_STATE_RENDER_TARGET); @@ -1137,6 +1409,16 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) m_resourceManager->transition(cmdList, m_tesselationTexture.get(), D3D12_RESOURCE_STATE_GENERIC_READ); + + if (m_capabilities.isIntel) + { + // workaround similiar to d3d11. + // Intel needs this which is basically a + // "VK_DEPENDENCY_BY_REGION_BIT" pipeline barrier + const auto barrier = + CD3DX12_RESOURCE_BARRIER::Aliasing(nullptr, nullptr); + cmdList->ResourceBarrier(1, &barrier); + } } D3D12_VERTEX_BUFFER_VIEW NULL_VIEW; @@ -1164,6 +1446,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0) { + RIVE_PROF_GPUNAME_L(1, "atlasRender"); m_resourceManager->transition(cmdList, m_atlasTexture.get(), D3D12_RESOURCE_STATE_RENDER_TARGET); @@ -1252,97 +1535,105 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) cmdList->RSSetScissorRects(1, &scissorRect); // Setup and clear the PLS textures. - - if (desc.atomicFixedFunctionColorOutput) { - m_resourceManager->transition(cmdList, - targetTexture, - D3D12_RESOURCE_STATE_RENDER_TARGET); - - auto rtvHandle = m_rtvHeap->cpuHandleForIndex(TARGET_RTV_HEAP_OFFSET); - cmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); - - if (desc.colorLoadAction == gpu::LoadAction::clear) + RIVE_PROF_GPUNAME_L(1, "clearPLSTextures"); + if (desc.fixedFunctionColorOutput) { - float clearColor4f[4]; - UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f); - cmdList->ClearRenderTargetView(rtvHandle, clearColor4f, 0, nullptr); - } - } - else // !desc.atomicFixedFunctionColorOutput - { - if (renderTarget->targetTextureSupportsUAV()) - { - m_resourceManager->transition( - cmdList, - targetTexture, - D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - } + m_resourceManager->transition(cmdList, + targetTexture, + D3D12_RESOURCE_STATE_RENDER_TARGET); - if (desc.colorLoadAction == gpu::LoadAction::clear) - { - auto tex = renderTarget->targetTextureSupportsUAV() - ? renderTarget->targetTexture()->resource() - : renderTarget->offscreenTexture()->resource(); + auto rtvHandle = + m_rtvHeap->cpuHandleForIndex(TARGET_RTV_HEAP_OFFSET); + cmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); - if (m_capabilities.supportsTypedUAVLoadStore) + if (desc.colorLoadAction == gpu::LoadAction::clear) { float clearColor4f[4]; UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f); + cmdList->ClearRenderTargetView(rtvHandle, + clearColor4f, + 0, + nullptr); + } + } + else // !desc.fixedFunctionColorOutput + { + if (renderTarget->targetTextureSupportsUAV()) + { + m_resourceManager->transition( + cmdList, + targetTexture, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + } + + if (desc.colorLoadAction == gpu::LoadAction::clear) + { + auto tex = renderTarget->targetTextureSupportsUAV() + ? renderTarget->targetTexture()->resource() + : renderTarget->offscreenTexture()->resource(); - auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex( - ATOMIC_COLOR_HEAP_OFFSET); - auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex( - ATOMIC_COLOR_HEAP_OFFSET); - m_resourceManager->clearUAV(cmdList, - tex, - gpuHandle, - cpuHandle, - clearColor4f, - desc.interlockMode == - InterlockMode::atomics); + if (m_capabilities.supportsTypedUAVLoadStore) + { + float clearColor4f[4]; + UnpackColorToRGBA32FPremul(desc.colorClearValue, + clearColor4f); + + auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex( + ATOMIC_COLOR_HEAP_OFFSET); + auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex( + ATOMIC_COLOR_HEAP_OFFSET); + m_resourceManager->clearUAV(cmdList, + tex, + gpuHandle, + cpuHandle, + clearColor4f, + desc.interlockMode == + InterlockMode::atomics); + } + else + { + UINT clearColorui[4] = {gpu::SwizzleRiveColorToRGBAPremul( + desc.colorClearValue)}; + + auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex( + ATOMIC_COLOR_HEAP_OFFSET); + auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex( + ATOMIC_COLOR_HEAP_OFFSET); + + m_resourceManager->clearUAV(cmdList, + tex, + gpuHandle, + cpuHandle, + clearColorui, + desc.interlockMode == + InterlockMode::atomics); + } } - else + if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget && + !renderTarget->targetTextureSupportsUAV()) { - UINT clearColorui[4] = { - gpu::SwizzleRiveColorToRGBAPremul(desc.colorClearValue)}; - - auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex( - ATOMIC_COLOR_HEAP_OFFSET); - auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex( - ATOMIC_COLOR_HEAP_OFFSET); - - m_resourceManager->clearUAV(cmdList, - tex, - gpuHandle, - cpuHandle, - clearColorui, - desc.interlockMode == - InterlockMode::atomics); + auto offscreenTex = renderTarget->offscreenTexture(); + blitSubRect(cmdList, + offscreenTex, + renderTarget->targetTexture(), + desc.renderTargetUpdateBounds); + + m_resourceManager->transition( + cmdList, + offscreenTex, + D3D12_RESOURCE_STATE_UNORDERED_ACCESS); } } - if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget && - !renderTarget->targetTextureSupportsUAV()) - { - auto offscreenTex = renderTarget->offscreenTexture(); - blitSubRect(cmdList, - offscreenTex, - renderTarget->targetTexture(), - desc.renderTargetUpdateBounds); - - m_resourceManager->transition( - cmdList, - offscreenTex, - D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - } } bool renderPassHasCoalescedResolveAndTransfer = desc.interlockMode == gpu::InterlockMode::atomics && - !desc.atomicFixedFunctionColorOutput && + !desc.fixedFunctionColorOutput && !renderTarget->targetTextureSupportsUAV(); - if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING) + if (enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING)) { constexpr static UINT kZero[4]{}; auto gpuHandle = @@ -1386,6 +1677,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) m_heapDescriptorOffset += imageDescriptorOffset; + RIVE_PROF_GPUNAME_L(1, "DrawList"); for (const DrawBatch& batch : *desc.drawList) { assert(batch.elementCount != 0); @@ -1395,32 +1687,30 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) ? desc.combinedShaderFeatures : batch.shaderFeatures; auto shaderMiscFlags = batch.shaderMiscFlags; - if (drawType == gpu::DrawType::atomicResolve && + if (drawType == gpu::DrawType::renderPassResolve && renderPassHasCoalescedResolveAndTransfer) { + assert(desc.interlockMode == gpu::InterlockMode::atomics); shaderMiscFlags |= gpu::ShaderMiscFlags::coalescedResolveAndTransfer; } - if (desc.atomicFixedFunctionColorOutput) - { - shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput; - } - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && - (batch.drawContents & gpu::DrawContents::clockwiseFill)) - { - shaderMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill; - } - auto pipeline = - m_pipelineManager.getDrawPipelineState(drawType, - shaderFeatures, - desc.interlockMode, - shaderMiscFlags); - cmdList->SetPipelineState(pipeline); + auto* pipeline = m_pipelineManager.tryGetPipeline( + { + .drawType = drawType, + .shaderFeatures = shaderFeatures, + .interlockMode = desc.interlockMode, + .shaderMiscFlags = shaderMiscFlags, +#ifdef WITH_RIVE_TOOLS + .synthesizedFailureType = desc.synthesizedFailureType, +#endif + }, + m_platformFeatures); // all atomic barriers are the same for dx12 - if (batch.barriers & - (BarrierFlags::plsAtomicPreResolve | BarrierFlags::plsAtomic)) + if (enums::any_flag_set(batch.barriers, + BarrierFlags::plsAtomicPreResolve | + BarrierFlags::plsAtomic)) { assert(desc.interlockMode == gpu::InterlockMode::atomics); auto target = renderTarget->targetTextureSupportsUAV() @@ -1435,13 +1725,22 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) renderTarget->clip()->resource())}; cmdList->ResourceBarrier( - desc.combinedShaderFeatures & - gpu::ShaderFeatures::ENABLE_CLIPPING + enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING) ? 3 : 2, barriers); } + if (pipeline == nullptr) + { + // There was an issue getting either the requested pipeline state or + // its ubershader counterpart so we cannot draw anything. + continue; + } + + cmdList->SetPipelineState(pipeline->m_d3dPipelineState.Get()); + if (auto imageTextureD3D12 = static_cast(batch.imageTexture)) { @@ -1476,20 +1775,61 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) if (++m_samplerHeapDescriptorOffset >= MAX_DESCRIPTOR_SAMPLER_HEAPS_PER_FLUSH) { - auto oldHeap = m_samplerHeap; m_samplerHeap = m_samplerHeapPool.acquire(); m_samplerHeapDescriptorOffset = IMAGE_SAMPLER_HEAP_OFFSET; - // copy the imutable sampelrs to the new heap - m_device->CopyDescriptorsSimple( - IMAGE_SAMPLER_HEAP_OFFSET, - m_samplerHeap->cpuHandleForUpload(0), - oldHeap->cpuHandleForUpload(0), - D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + // Re-create the immutable samplers in the new heap. + // CopyDescriptorsSimple from the old heap is invalid: + // shader-visible heaps are CPU-write-only per D3D12 + // spec, and reading from one as a copy source produces + // garbage descriptors (validation fires id=654, GPU + // eventually TDRs). Mirror the initial-flush block that + // creates these from m_linearSampler directly. + m_samplerHeap->markSamplerToIndex(m_device.Get(), + m_linearSampler, + TESS_SAMPLER_HEAP_OFFSET); + m_samplerHeap->markSamplerToIndex(m_device.Get(), + m_linearSampler, + GRAD_SAMPLER_HEAP_OFFSET); + m_samplerHeap->markSamplerToIndex( + m_device.Get(), + m_linearSampler, + FEATHER_SAMPLER_HEAP_OFFSET); + m_samplerHeap->markSamplerToIndex( + m_device.Get(), + m_linearSampler, + ATLAS_SAMPLER_HEAP_OFFSET); ID3D12DescriptorHeap* ppHeaps[] = {m_srvUavCbvHeap->heap(), m_samplerHeap->heap()}; cmdList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); + + // SetDescriptorHeaps invalidates every previously-bound + // root descriptor table. Re-bind every table that was + // set up earlier in this flush, otherwise GPU-Based + // Validation fires id=554 on every subsequent draw and + // the runtime eventually TDRs the device. + cmdList->SetGraphicsRootDescriptorTable( + STATIC_SRV_SIG_INDEX, + m_srvUavCbvHeap->gpuHandleForIndex( + STATIC_SRV_UAV_HEAP_DESCRIPTOPR_START)); + cmdList->SetGraphicsRootDescriptorTable( + UAV_SIG_INDEX, + m_srvUavCbvHeap->gpuHandleForIndex( + UAV_START_HEAP_INDEX)); + cmdList->SetGraphicsRootDescriptorTable( + SAMPLER_SIG_INDEX, + m_samplerHeap->gpuHandleForIndex(0)); + cmdList->SetGraphicsRootDescriptorTable( + DYNAMIC_SRV_SIG_INDEX, + m_srvUavCbvHeap->gpuHandleForIndex( + dynamicSrvHeapIndex)); + cmdList->SetGraphicsRootDescriptorTable( + IMAGE_SIG_INDEX, + m_srvUavCbvHeap->gpuHandleForIndex( + m_heapDescriptorOffset - 1)); + // DYNAMIC_SAMPLER_SIG_INDEX is rebound by the existing + // call below. } m_samplerHeap->markSamplerToIndex( @@ -1512,6 +1852,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: { + RIVE_PROF_GPUNAME_L(2, "Patches"); cmdList->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); auto IBV = m_pathPatchIndexBuffer->indexBufferView(); @@ -1530,6 +1871,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) case DrawType::interiorTriangulation: case DrawType::atlasBlit: { + RIVE_PROF_GPUNAME_L(2, "interiorTriangulation||atlasBlit"); cmdList->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); cmdList->DrawInstanced(batch.elementCount, @@ -1540,6 +1882,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) } case DrawType::imageRect: { + RIVE_PROF_GPUNAME_L(2, "imageRect"); + cmdList->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); auto IBV = m_imageRectIndexBuffer->indexBufferView(); @@ -1560,6 +1904,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) } case DrawType::imageMesh: { + RIVE_PROF_GPUNAME_L(2, "imageMesh"); + LITE_RTTI_CAST_OR_BREAK(vertexBuffer, RenderBufferD3D12Impl*, batch.vertexBuffer); @@ -1600,13 +1946,17 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) 0); break; } - case DrawType::atomicResolve: + case DrawType::renderPassResolve: + { + RIVE_PROF_GPUNAME_L(1, "renderPassResolve"); + assert(desc.interlockMode == gpu::InterlockMode::atomics); cmdList->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); cmdList->DrawInstanced(4, 1, 0, 0); break; - case DrawType::atomicInitialize: + } + case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -1614,7 +1964,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: RIVE_UNREACHABLE(); } } @@ -1622,9 +1973,11 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && !renderTarget->targetTextureSupportsUAV()) { + RIVE_PROF_GPUNAME_L(1, "blit_sub_rect"); + // We rendered to an offscreen UAV and did not resolve to the // renderTarget. Copy back to the main target. - assert(!desc.atomicFixedFunctionColorOutput); + assert(!desc.fixedFunctionColorOutput); assert(!renderPassHasCoalescedResolveAndTransfer); blitSubRect(cmdList, renderTarget->targetTexture(), @@ -1642,10 +1995,10 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc) D3D12_RESOURCE_STATE_UNORDERED_ACCESS); } - if (desc.atomicFixedFunctionColorOutput || + if (desc.fixedFunctionColorOutput || renderPassHasCoalescedResolveAndTransfer || (renderTarget->targetTextureSupportsUAV() && - !desc.atomicFixedFunctionColorOutput)) + !desc.fixedFunctionColorOutput)) { m_resourceManager->transition(cmdList, targetTexture, @@ -1670,4 +2023,4 @@ void RenderContextD3D12Impl::postFlush(const RenderContext::FlushResources&) m_cpuSrvUavCbvHeapPool.recycle(std::move(m_cpuSrvUavCbvHeap)); m_samplerHeapPool.recycle(std::move(m_samplerHeap)); } -}; // namespace rive::gpu \ No newline at end of file +}; // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/draw.cpp b/thirdparty/rive_renderer/source/draw.cpp index 66aacb98e..2d8be0cab 100644 --- a/thirdparty/rive_renderer/source/draw.cpp +++ b/thirdparty/rive_renderer/source/draw.cpp @@ -12,6 +12,7 @@ #include "rive/renderer/texture.hpp" #include "gradient.hpp" #include "shaders/constants.glsl" +#include "rive/profiler/profiler_macros.h" namespace rive::gpu { @@ -368,7 +369,7 @@ void Draw::setClipID(uint32_t clipID) // For clipUpdates, m_clipID refers to the ID we are writing to the stencil // buffer (NOT the ID we are clipping against). It therefore doesn't affect // the activeClip flag in that case. - if (!(m_drawContents & gpu::DrawContents::clipUpdate)) + if (!enums::is_flag_set(m_drawContents, gpu::DrawContents::clipUpdate)) { if (m_clipID != 0) { @@ -401,15 +402,19 @@ PathDraw::CoverageType PathDraw::SelectCoverageType( return CoverageType::atlas; } } - if (interlockMode == gpu::InterlockMode::msaa) + switch (interlockMode) { - return CoverageType::msaa; + case gpu::InterlockMode::rasterOrdering: + case gpu::InterlockMode::atomics: + return CoverageType::pixelLocalStorage; + case gpu::InterlockMode::clockwise: + return CoverageType::clockwise; + case gpu::InterlockMode::clockwiseAtomic: + return CoverageType::clockwiseAtomic; + case gpu::InterlockMode::msaa: + return CoverageType::msaa; } - if (interlockMode == gpu::InterlockMode::clockwiseAtomic) - { - return CoverageType::clockwiseAtomic; - } - return CoverageType::pixelLocalStorage; + RIVE_UNREACHABLE(); } DrawUniquePtr PathDraw::Make(RenderContext* context, @@ -417,8 +422,10 @@ DrawUniquePtr PathDraw::Make(RenderContext* context, rcp path, FillRule fillRule, const RiveRenderPaint* paint, + float modulatedOpacity, RawPath* scratchPath) { + RIVE_PROF_SCOPE_L(2); assert(path != nullptr); assert(paint != nullptr); @@ -506,6 +513,7 @@ DrawUniquePtr PathDraw::Make(RenderContext* context, std::move(path), fillRule, paint, + modulatedOpacity, coverageType, context->frameDescriptor()); if (doTriangulation) @@ -530,6 +538,7 @@ PathDraw::PathDraw(IAABB pixelBounds, rcp path, FillRule initialFillRule, const RiveRenderPaint* paint, + float modulatedOpacity, CoverageType coverageType, const RenderContext::FrameDescriptor& frameDesc) : Draw(pixelBounds, @@ -541,7 +550,7 @@ PathDraw::PathDraw(IAABB pixelBounds, m_pathRef(path.release()), m_pathFillRule(frameDesc.clockwiseFillOverride ? FillRule::clockwise : initialFillRule), - m_gradientRef(safe_ref(paint->getGradient())), + m_gradientRef(paint->getGradientWithOpacity(modulatedOpacity).release()), m_paintType(paint->getType()), m_coverageType(coverageType) { @@ -626,7 +635,8 @@ PathDraw::PathDraw(IAABB pixelBounds, if (det < 0) { m_contourDirections = - m_coverageType == CoverageType::msaa + (m_coverageType == CoverageType::msaa || + m_coverageType == CoverageType::atlas) ? gpu::ContourDirections::reverse : gpu::ContourDirections::forwardThenReverse; m_contourFlags |= NEGATE_PATH_FILL_COVERAGE_FLAG; // ignored by msaa @@ -634,7 +644,8 @@ PathDraw::PathDraw(IAABB pixelBounds, else { m_contourDirections = - m_coverageType == CoverageType::msaa + (m_coverageType == CoverageType::msaa || + m_coverageType == CoverageType::atlas) ? gpu::ContourDirections::forward : gpu::ContourDirections::reverseThenForward; } @@ -648,12 +659,18 @@ PathDraw::PathDraw(IAABB pixelBounds, // For clockwiseFill, this is also our opportunity to logically // reverse the winding of the path, if it is predominantly // counterclockwise. - m_contourDirections = gpu::ContourDirections::forwardThenReverse; + m_contourDirections = + (m_coverageType == CoverageType::atlas) + ? gpu::ContourDirections::reverse + : gpu::ContourDirections::forwardThenReverse; m_contourFlags |= NEGATE_PATH_FILL_COVERAGE_FLAG; } else { - m_contourDirections = gpu::ContourDirections::reverseThenForward; + m_contourDirections = + (m_coverageType == CoverageType::atlas) + ? gpu::ContourDirections::forward + : gpu::ContourDirections::reverseThenForward; } } else @@ -679,6 +696,27 @@ PathDraw::PathDraw(IAABB pixelBounds, m_simplePaintValue = paint->getSimpleValue(); + // Apply modulated opacity to the paint value. + // Gradient modulation is handled upfront in the gradient initialization. + if (modulatedOpacity != 1.0f) + { + switch (m_paintType) + { + case gpu::PaintType::solidColor: + m_simplePaintValue.color = + colorModulateOpacity(m_simplePaintValue.color, + modulatedOpacity); + break; + case gpu::PaintType::image: + m_simplePaintValue.imageOpacity *= modulatedOpacity; + break; + case gpu::PaintType::linearGradient: + case gpu::PaintType::radialGradient: + case gpu::PaintType::clipUpdate: + break; + } + } + if (m_coverageType == CoverageType::atlas) { // Reserve two triangles for our on-screen rectangle that reads coverage @@ -695,6 +733,7 @@ PathDraw::PathDraw(IAABB pixelBounds, void PathDraw::releaseRefs() { + RIVE_PROF_SCOPE_L(2) Draw::releaseRefs(); RIVE_DEBUG_CODE(m_pathRef->unlockRawPathMutations();) m_pathRef->unref(); @@ -704,6 +743,7 @@ void PathDraw::releaseRefs() void PathDraw::initForMidpointFan(RenderContext* context, const RiveRenderPaint* paint) { + RIVE_PROF_SCOPE_L(2) // Only call init() once. assert((m_resourceCounts.midpointFanTessVertexCount | m_resourceCounts.outerCubicTessVertexCount) == 0); @@ -1330,7 +1370,10 @@ void PathDraw::initForInteriorTriangulation(RenderContext* context, RawPath* scratchPath, TriangulatorAxis triangulatorAxis) { + RIVE_PROF_SCOPE_L(2) + PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() assert(simd::all(m_resourceCounts.toVec() == 0)); // Only call init() once. + POP_DISABLE_CLANG_SIMD_ABI_WARNING() assert(!isStrokeOrFeather()); assert(m_strokeRadius == 0); @@ -1348,20 +1391,26 @@ void PathDraw::initForInteriorTriangulation(RenderContext* context, bool PathDraw::allocateResources(RenderContext::LogicalFlush* flush) { + RIVE_PROF_SCOPE_L(2) const RenderContext::FrameDescriptor& frameDesc = flush->frameDescriptor(); // Allocate a gradient if needed. Do this first since it's more expensive to // fail after setting up an atlas draw than a gradient draw. - if (m_gradientRef != nullptr && - !flush->allocateGradient(m_gradientRef, - &m_simplePaintValue.colorRampLocation)) + if (m_gradientRef != nullptr) { - return false; + if (!flush->allocateGradient(m_gradientRef, + &m_simplePaintValue.colorRampLocation)) + { + return false; + } } // Allocate a coverage buffer range or atlas region if needed. if (m_coverageType == CoverageType::atlas || - m_coverageType == CoverageType::clockwiseAtomic) + (m_coverageType == CoverageType::clockwiseAtomic && + // Outermost (i.e., non-nested) clockwiseAtomic clips render directly + // to the clip buffer without using the coverage buffer. + !isOutermostClipUpdate())) { constexpr static int PADDING = 2; @@ -1427,22 +1476,37 @@ bool PathDraw::allocateResources(RenderContext::LogicalFlush* flush) void PathDraw::countSubpasses() { + RIVE_PROF_SCOPE_L(2) m_subpassCount = 1; m_prepassCount = 0; switch (m_coverageType) { - case CoverageType::pixelLocalStorage: case CoverageType::atlas: + assert(m_triangulator == nullptr); m_subpassCount = 1; break; + case CoverageType::pixelLocalStorage: + m_subpassCount = (m_triangulator != nullptr) + ? 2 // outer cubics, interior triangles + : 1; + break; + + case CoverageType::clockwise: + m_subpassCount = + (m_triangulator != nullptr) + ? 3 // ccw interior tris, outer cubics, cw interior tris + : 1; + break; + case CoverageType::clockwiseAtomic: - if (!isStroke()) + m_subpassCount = (m_triangulator != nullptr) ? 2 : 1; + if (needsBorrowedCoveragePrepass()) { - m_prepassCount = 1; // Borrowed coverage. + // Add prepasses for borrowed coverage. + m_prepassCount = m_subpassCount; } - m_subpassCount = 1; break; case CoverageType::msaa: @@ -1455,10 +1519,11 @@ void PathDraw::countSubpasses() gpu::kNestedClipUpdateMask) { // Nested clip updates only have a stencil pass. (The reset is - // handled by a separate msaaStencilClipReset draw.) + // handled by a separate ClipReset draw.) m_subpassCount = 1; } - else if (m_drawContents & gpu::DrawContents::evenOddFill) + else if (enums::is_flag_set(m_drawContents, + gpu::DrawContents::evenOddFill)) { m_subpassCount = 2; // MSAA "slow" path: stencil-then-cover. } @@ -1470,8 +1535,9 @@ void PathDraw::countSubpasses() if (isOpaque()) { const bool usesClipping = - m_drawContents & (gpu::DrawContents::activeClip | - gpu::DrawContents::clipUpdate); + enums::any_flag_set(m_drawContents, + gpu::DrawContents::activeClip | + gpu::DrawContents::clipUpdate); if (!usesClipping) { // Render this path front-to-back instead of back-to-front. @@ -1482,18 +1548,13 @@ void PathDraw::countSubpasses() } } } - - if (m_triangulator != nullptr) - { - // Each tessellation draw has a corresponding interior triangles draw. - m_prepassCount *= 2; - m_subpassCount *= 2; - } } -void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, - int subpassIndex) +gpu::DrawBatch* PathDraw::pushToRenderContext( + RenderContext::LogicalFlush* flush, + int subpassIndex) { + RIVE_PROF_SCOPE_L(2) // Make sure the rawPath in our path reference hasn't changed since we began // holding! assert(m_rawPathMutationID == m_pathRef->getRawPathMutationID()); @@ -1506,7 +1567,7 @@ void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, m_resourceCounts.midpointFanTessVertexCount); if (tessVertexCount == 0) { - return; + return nullptr; } if (m_pathID == 0) @@ -1518,36 +1579,60 @@ void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, switch (m_coverageType) { case CoverageType::pixelLocalStorage: + case CoverageType::clockwise: { - if (subpassIndex == 0) + const int mainSubpassIdx = + (m_coverageType == CoverageType::clockwise && + m_triangulator != nullptr) + ? 1 + : 0; + if (subpassIndex == mainSubpassIdx) { // Tessellation (midpoint fan or outer cubic). uint32_t tessLocation = allocateTessellationVertices(flush, tessVertexCount); pushTessellationData(flush, tessVertexCount, tessLocation); - pushTessellationDraw(flush, tessVertexCount, tessLocation); + return &pushTessellationDraw(flush, + tessVertexCount, + tessLocation); } else { // Interior triangles. assert(m_triangulator != nullptr); - assert(subpassIndex == 1); - RIVE_DEBUG_CODE(m_numInteriorTriangleVerticesPushed +=) - flush->pushInteriorTriangulationDraw(this, - m_pathID, - gpu::WindingFaces::all); + assert((m_coverageType == CoverageType::pixelLocalStorage && + subpassIndex == 1) || + (m_coverageType == CoverageType::clockwise && + (subpassIndex == 0 || subpassIndex == 2))); + gpu::DrawBatch* batch = flush->pushInteriorTriangulationDraw( + this, + m_pathID, + (m_coverageType == CoverageType::clockwise) + // Clockwise mode renders counterclockwise (borrowed + // coverage) interior triangles in a separate pass. + ? (subpassIndex == 0) ? gpu::WindingFaces::negative + : gpu::WindingFaces::positive + : gpu::WindingFaces::all, + (subpassIndex == 0) // => CoverageType::clockwise + ? gpu::ShaderMiscFlags::borrowedCoveragePass + : gpu::ShaderMiscFlags::none RIVE_DEBUG_CODE( + , + &m_numInteriorTriangleVerticesPushed)); assert(m_numInteriorTriangleVerticesPushed <= m_triangulator->maxVertexCount()); + return batch; } - break; + RIVE_UNREACHABLE(); } case CoverageType::clockwiseAtomic: - if (!isStroke()) + { + if (m_prepassCount != 0) { // The subpass and prepass each emit half the vertices. assert(m_prepassCount == m_subpassCount); assert(tessVertexCount % 2 == 0); + assert(needsBorrowedCoveragePrepass()); tessVertexCount /= 2; } switch (subpassIndex) @@ -1556,43 +1641,46 @@ void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, assert(!isStroke()); m_prepassTessLocation = allocateTessellationVertices(flush, tessVertexCount); - pushTessellationDraw( + return &pushTessellationDraw( flush, tessVertexCount, m_prepassTessLocation, - gpu::ShaderMiscFlags::borrowedCoveragePrepass); - break; + gpu::ShaderMiscFlags::borrowedCoveragePass); case 0: // Tessellation (midpointFan or outerCubic). { uint32_t tessLocation = allocateTessellationVertices(flush, tessVertexCount); pushTessellationData(flush, tessVertexCount, tessLocation); - pushTessellationDraw(flush, tessVertexCount, tessLocation); - break; + return &pushTessellationDraw(flush, + tessVertexCount, + tessLocation); } case -2: // Interior triangles (borrowed). case 1: // Interior triangles. + { assert(!isStroke()); assert(m_triangulator != nullptr); - RIVE_DEBUG_CODE(m_numInteriorTriangleVerticesPushed +=) - flush->pushInteriorTriangulationDraw( - this, - m_pathID, - subpassIndex < 0 ? gpu::WindingFaces::negative - : gpu::WindingFaces::positive, - subpassIndex < 0 - ? gpu::ShaderMiscFlags::borrowedCoveragePrepass - : gpu::ShaderMiscFlags::none); + gpu::DrawBatch* batch = + flush->pushInteriorTriangulationDraw( + this, + m_pathID, + m_prepassCount == 0 ? gpu::WindingFaces::all + : subpassIndex < 0 ? gpu::WindingFaces::negative + : gpu::WindingFaces::positive, + subpassIndex < 0 + ? gpu::ShaderMiscFlags::borrowedCoveragePass + : gpu::ShaderMiscFlags::none RIVE_DEBUG_CODE( + , + &m_numInteriorTriangleVerticesPushed)); assert(m_numInteriorTriangleVerticesPushed <= m_triangulator->maxVertexCount()); - break; - - default: - RIVE_UNREACHABLE(); + return batch; + } } - break; + RIVE_UNREACHABLE(); + } case CoverageType::msaa: { @@ -1609,7 +1697,7 @@ void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, } constexpr static gpu::DrawType MSAA_FILL_TYPES[][3] = { // Nested clip update (passCount == 1; the reset is handled by a - // separate msaaStencilClipReset draw.) + // separate ClipReset draw.) { gpu::DrawType::msaaMidpointFanPathsStencil, }, @@ -1632,11 +1720,10 @@ void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, gpu::DrawType msaaDrawType = isStroke() ? gpu::DrawType::msaaStrokes : MSAA_FILL_TYPES[passCount - 1][passIdx]; - flush->pushMidpointFanDraw(this, - msaaDrawType, - tessVertexCount, - m_msaaTessLocation); - break; + return &flush->pushMidpointFanDraw(this, + msaaDrawType, + tessVertexCount, + m_msaaTessLocation); } case CoverageType::atlas: @@ -1645,28 +1732,30 @@ void PathDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, // offscreen atlas is handled separately, outside the subpass // system. assert(subpassIndex == 0); - flush->pushAtlasBlit(this, m_pathID); - break; + return &flush->pushAtlasBlit(this, m_pathID); } + + RIVE_UNREACHABLE(); } -void PathDraw::pushTessellationDraw(RenderContext::LogicalFlush* flush, - uint32_t tessVertexCount, - uint32_t tessLocation, - gpu::ShaderMiscFlags shaderMiscFlags) +gpu::DrawBatch& PathDraw::pushTessellationDraw( + RenderContext::LogicalFlush* flush, + uint32_t tessVertexCount, + uint32_t tessLocation, + gpu::ShaderMiscFlags shaderMiscFlags) { if (m_triangulator != nullptr) { assert(!isStroke()); - flush->pushOuterCubicsDraw(this, - gpu::DrawType::outerCurvePatches, - tessVertexCount, - tessLocation, - shaderMiscFlags); + return flush->pushOuterCubicsDraw(this, + gpu::DrawType::outerCurvePatches, + tessVertexCount, + tessLocation, + shaderMiscFlags); } else { - flush->pushMidpointFanDraw( + return flush->pushMidpointFanDraw( this, isFeatheredFill() ? gpu::DrawType::midpointFanCenterAAPatches : gpu::DrawType::midpointFanPatches, @@ -1680,6 +1769,7 @@ void PathDraw::pushAtlasTessellation(RenderContext::LogicalFlush* flush, uint32_t* tessVertexCount, uint32_t* tessBaseVertex) { + RIVE_PROF_SCOPE_L(2) assert(m_coverageType == CoverageType::atlas); assert(m_resourceCounts.outerCubicTessVertexCount == 0 || m_resourceCounts.midpointFanTessVertexCount == 0); @@ -1702,6 +1792,7 @@ void PathDraw::pushTessellationData(RenderContext::LogicalFlush* flush, uint32_t tessVertexCount, uint32_t tessLocation) { + RIVE_PROF_SCOPE_L(2) // Determine where to fill in forward and mirrored tessellations. uint32_t forwardTessVertexCount, forwardTessLocation, mirroredTessVertexCount, mirroredTessLocation; @@ -1718,14 +1809,14 @@ void PathDraw::pushTessellationData(RenderContext::LogicalFlush* flush, mirroredTessLocation = tessLocation + tessVertexCount; break; case gpu::ContourDirections::reverseThenForward: - if (m_coverageType == CoverageType::clockwiseAtomic && !isStroke()) + if (m_coverageType == CoverageType::clockwiseAtomic && + m_prepassTessLocation != 0) // With padding, this will only be + // zero if it's not needed. { // The tessellation for borrowed coverage was allocated at a // different location than the forward tessellation, both with // "tessVertexCount" vertices. - assert(m_prepassTessLocation != 0); // With padding, this will - // only be zero if it wasn't - // initialized. + assert(needsBorrowedCoveragePrepass()); forwardTessVertexCount = mirroredTessVertexCount = tessVertexCount; forwardTessLocation = tessLocation; @@ -1744,14 +1835,14 @@ void PathDraw::pushTessellationData(RenderContext::LogicalFlush* flush, } break; case gpu::ContourDirections::forwardThenReverse: - if (m_coverageType == CoverageType::clockwiseAtomic && !isStroke()) + if (m_coverageType == CoverageType::clockwiseAtomic && + m_prepassTessLocation != 0) // With padding, this will only be + // zero if it's not needed. { // The tessellation for borrowed coverage was allocated at a // different location than the forward tessellation, both with // "tessVertexCount" vertices. - assert(m_prepassTessLocation != 0); // With padding, this will - // only be zero if it wasn't - // initialized. + assert(needsBorrowedCoveragePrepass()); forwardTessVertexCount = mirroredTessVertexCount = tessVertexCount; forwardTessLocation = m_prepassTessLocation; @@ -1798,6 +1889,7 @@ void PathDraw::pushTessellationData(RenderContext::LogicalFlush* flush, void PathDraw::pushMidpointFanTessellationData( RenderContext::TessellationWriter* tessWriter) { + RIVE_PROF_SCOPE_L(3) const RawPath& rawPath = m_pathRef->getRawPath(); RawPath::Iter startOfContour = rawPath.begin(); for (size_t i = 0; i < m_resourceCounts.contourCount; ++i) @@ -2185,6 +2277,7 @@ void PathDraw::pushEmulatedStrokeCapAsJoinBeforeCubic( uint32_t strokeCapSegmentCount, uint32_t contourIDWithFlags) { + RIVE_PROF_SCOPE_L(3) // Reverse the cubic and push it with zero parametric and polar segments, // and a 180-degree join tangent. This results in a solitary join, // positioned immediately before the provided cubic, that looks like the @@ -2209,6 +2302,7 @@ void PathDraw::iterateInteriorTriangulation( TriangulatorAxis triangulatorAxis, RenderContext::TessellationWriter* tessWriter) { + RIVE_PROF_SCOPE_L(2) Vec2D chops[kMaxCurveSubdivisions * 3 + 1]; const RawPath& rawPath = m_pathRef->getRawPath(); assert(!rawPath.empty()); @@ -2464,11 +2558,12 @@ ImageRectDraw::ImageRectDraw(RenderContext* context, m_resourceCounts.imageDrawCount = 1; } -void ImageRectDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, - int subpassIndex) +gpu::DrawBatch* ImageRectDraw::pushToRenderContext( + RenderContext::LogicalFlush* flush, + int subpassIndex) { assert(subpassIndex == 0); - flush->pushImageRectDraw(this); + return &flush->pushImageRectDraw(this); } ImageMeshDraw::ImageMeshDraw(IAABB pixelBounds, @@ -2500,11 +2595,12 @@ ImageMeshDraw::ImageMeshDraw(IAABB pixelBounds, m_resourceCounts.imageDrawCount = 1; } -void ImageMeshDraw::pushToRenderContext(RenderContext::LogicalFlush* flush, - int subpassIndex) +gpu::DrawBatch* ImageMeshDraw::pushToRenderContext( + RenderContext::LogicalFlush* flush, + int subpassIndex) { assert(subpassIndex == 0); - flush->pushImageMeshDraw(this); + return &flush->pushImageMeshDraw(this); } void ImageMeshDraw::releaseRefs() @@ -2515,10 +2611,10 @@ void ImageMeshDraw::releaseRefs() m_indexBufferRef->unref(); } -StencilClipReset::StencilClipReset(RenderContext* context, - uint32_t previousClipID, - gpu::DrawContents previousClipDrawContents, - ResetAction resetAction) : +ClipReset::ClipReset(RenderContext* context, + uint32_t previousClipID, + gpu::DrawContents previousClipDrawContents, + ResetAction resetAction) : Draw(context->getClipContentBounds(previousClipID), Mat2D(), BlendMode::srcOver, @@ -2543,10 +2639,11 @@ StencilClipReset::StencilClipReset(RenderContext* context, m_resourceCounts.maxTriangleVertexCount = 6; } -void StencilClipReset::pushToRenderContext(RenderContext::LogicalFlush* flush, - int subpassIndex) +gpu::DrawBatch* ClipReset::pushToRenderContext( + RenderContext::LogicalFlush* flush, + int subpassIndex) { assert(subpassIndex == 0); - flush->pushStencilClipResetDraw(this); + return &flush->pushClipResetDraw(this); } } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.exports.h b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.hpp index 68a781c45..881f8be5e 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.glsl.hpp @@ -1,14 +1,14 @@ #pragma once -#include "advanced_blend.exports.h" +#include "advanced_blend.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char advanced_blend[] = R"===(#ifdef HB -#ifdef KD +const char advanced_blend[] = R"===(#ifdef EB +#ifdef VD layout( -#ifdef XB +#ifdef SB blend_support_all_equations #else blend_support_multiply,blend_support_screen,blend_support_overlay,blend_support_darken,blend_support_lighten,blend_support_colordodge,blend_support_colorburn,blend_support_hardlight,blend_support_softlight,blend_support_difference,blend_support_exclusion @@ -16,14 +16,14 @@ blend_support_multiply,blend_support_screen,blend_support_overlay,blend_support_ )out; #endif #ifdef FB -#ifdef XB -g V7(A B0){return min(min(B0.x,B0.y),B0.z);}g N9(A B0){return max(max(B0.x,B0.y),B0.z);}g W7(A B0){return dot(B0,K0(.30,.59,.11));}g O9(A B0){return N9(B0)-V7(B0);}A kc(A j){g p3=W7(j);g P9=V7(j);g Q9=N9(j);if(P9<.0)j=p3+((j-p3)*p3)/(p3-P9);if(Q9>1.)j=p3+((j-p3)*(1.-p3))/(Q9-p3);return j;}A X7(A L4,A Y7){g lc=W7(L4);g mc=W7(Y7);g nc=mc-lc;A j=L4+K0(nc);return kc(j);}A R9(A L4,A oc,A Y7){g pc=V7(L4);g S9=O9(L4);g qc=O9(oc);A j;if(S9>.0){j=(L4-pc)*qc/S9;}else{j=K0(.0);}return X7(j,Y7);} +#ifdef SB +d gb(r J1){return dot(J1,T0(.30,.59,.11));}r j9(r hb,r k9){d l9=gb(k9);r m9=hb-gb(hb);D ib=A2(l9,1.0-l9)/max(A2(n9),A2(-d3(m9),G5(m9)));d be=min(G0(1.0),min(ib.x,ib.y));return m9*be+l9;}r jb(r Q7,r kb,r k9){float ce=G5(kb)-d3(kb);Q7-=d3(Q7);float de=G5(Q7);float B2=ce/max(n9,de);return j9(Q7*B2,k9);} #endif -A rc(A e0,i X0,a0 Z7){A h0=Y3(X0);A L0;switch(Z7){case sc:L0=e0.xyz*h0.xyz;break;case tc:L0=e0.xyz+h0.xyz-e0.xyz*h0.xyz;break;case uc:{for(int C=0;C<3;++C){if(h0[C]<=.5)L0[C]=2.*e0[C]*h0[C];else L0[C]=1.-2.*(1.-e0[C])*(1.-h0[C]);}break;}case vc:L0=min(e0.xyz,h0.xyz);break;case wc:L0=max(e0.xyz,h0.xyz);break;case xc:{X0.xyz=clamp(X0.xyz,K0(.0),X0.www);A T9=clamp(1.-e0,K0(.0),K0(1.))*X0.w;L0=mix(min(K0(1.),X0.xyz/T9),sign(X0.xyz),equal(T9,K0(.0)));break;}case zc:{e0=clamp(e0,K0(.0),K0(1.));X0.xyz=clamp(X0.xyz,K0(.0),X0.www);if(X0.w==.0)X0.w=1.;A U9=X0.w-X0.xyz;L0=1.-mix(min(K0(1.),U9/(e0*X0.w)),sign(U9),equal(e0,K0(.0)));break;}case Ac:{for(int C=0;C<3;++C){if(e0[C]<=.5)L0[C]=2.*e0[C]*h0[C];else L0[C]=1.-2.*(1.-e0[C])*(1.-h0[C]);}break;}case Bc:{for(int C=0;C<3;++C){if(e0[C]<=0.5)L0[C]=h0[C]-(1.-2.*e0[C])*h0[C]*(1.-h0[C]);else if(h0[C]<=.25)L0[C]=h0[C]+(2.*e0[C]-1.)*h0[C]*((16.*h0[C]-12.)*h0[C]+3.);else L0[C]=h0[C]+(2.*e0[C]-1.)*(sqrt(h0[C])-h0[C]);}break;}case Cc:L0=abs(h0.xyz-e0.xyz);break;case Dc:L0=e0.xyz+h0.xyz-2.*e0.xyz*h0.xyz;break; -#ifdef XB -case Ec:if(XB){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=R9(e0.xyz,h0.xyz,h0.xyz);}break;case Fc:if(XB){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=R9(h0.xyz,e0.xyz,h0.xyz);}break;case Gc:if(XB){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=X7(e0.xyz,h0.xyz);}break;case Hc:if(XB){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=X7(h0.xyz,e0.xyz);}break; +r ee(r k0,i z1,X o9){r o0=B6(z1);r d1;switch(o9){case fe:d1=k0.xyz*o0.xyz;break;case ge:d1=k0.xyz+o0.xyz-k0.xyz*o0.xyz;break;case he:{r C6=k0*o0;d1=2.0*mix(C6,k0+o0-C6-0.5,greaterThan(o0,T0(0.5)));break;}case ie:d1=min(k0.xyz,o0.xyz);break;case je:d1=max(k0.xyz,o0.xyz);break;case ke:{z1.xyz=clamp(z1.xyz,T0(.0),z1.www);r lb=clamp(1.-k0,T0(.0),T0(1.))*z1.w;d1=mix(min(T0(1.),z1.xyz/lb),sign(z1.xyz),equal(lb,T0(.0)));break;}case me:{k0=clamp(k0,T0(.0),T0(1.));z1.xyz=clamp(z1.xyz,T0(.0),z1.www);if(z1.w==.0)z1.w=1.;r mb=z1.w-z1.xyz;d1=1.-mix(min(T0(1.),mb/(k0*z1.w)),sign(mb),equal(k0,T0(.0)));break;}case ne:{r C6=k0*o0;d1=2.0*mix(C6,k0+o0-C6-0.5,greaterThan(k0,T0(0.5)));break;}case oe:{for(int D0=0;D0<3;++D0){if(k0[D0]<=0.5)d1[D0]=(1.0-o0[D0]);else if(o0[D0]<=0.25)d1[D0]=((16.0*o0[D0]-12.0)*o0[D0]+3.0);else d1[D0]=(inversesqrt(o0[D0])-1.0);}d1=o0+o0*(2.0*k0-1.0)*d1;break;}case pe:d1=abs(o0.xyz-k0.xyz);break;case qe:d1=k0.xyz+o0.xyz-2.*k0.xyz*o0.xyz;break; +#ifdef SB +case re:if(SB){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=jb(k0.xyz,o0.xyz,o0.xyz);}break;case se:if(SB){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=jb(o0.xyz,k0.xyz,o0.xyz);}break;case te:if(SB){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=j9(k0.xyz,o0.xyz);}break;case ue:if(SB){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=j9(o0.xyz,k0.xyz);}break; #endif -}return L0;}d A M4(A e0,i X0,a0 Z7){A L0=rc(e0,X0,Z7);G z5=Z3(X0.w,1.-X0.w);return C0(Ic(L0,e0),z5);} +}return d1;}e r R4(r k0,i z1,X o9){r d1=ee(k0,z1,o9);return mix(k0,d1,T0(z1.w));} #endif #endif )==="; diff --git a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.minified.glsl index 532ab9eb5..1710be95e 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/advanced_blend.minified.glsl @@ -10,12 +10,12 @@ blend_support_multiply,blend_support_screen,blend_support_overlay,blend_support_ #endif #ifdef ENABLE_ADVANCED_BLEND #ifdef ENABLE_HSL_BLEND_MODES -g V7(A B0){return min(min(B0.x,B0.y),B0.z);}g N9(A B0){return max(max(B0.x,B0.y),B0.z);}g W7(A B0){return dot(B0,K0(.30,.59,.11));}g O9(A B0){return N9(B0)-V7(B0);}A kc(A j){g p3=W7(j);g P9=V7(j);g Q9=N9(j);if(P9<.0)j=p3+((j-p3)*p3)/(p3-P9);if(Q9>1.)j=p3+((j-p3)*(1.-p3))/(Q9-p3);return j;}A X7(A L4,A Y7){g lc=W7(L4);g mc=W7(Y7);g nc=mc-lc;A j=L4+K0(nc);return kc(j);}A R9(A L4,A oc,A Y7){g pc=V7(L4);g S9=O9(L4);g qc=O9(oc);A j;if(S9>.0){j=(L4-pc)*qc/S9;}else{j=K0(.0);}return X7(j,Y7);} +d gb(r J1){return dot(J1,T0(.30,.59,.11));}r j9(r hb,r k9){d l9=gb(k9);r m9=hb-gb(hb);D ib=A2(l9,1.0-l9)/max(A2(n9),A2(-d3(m9),G5(m9)));d be=min(G0(1.0),min(ib.x,ib.y));return m9*be+l9;}r jb(r Q7,r kb,r k9){float ce=G5(kb)-d3(kb);Q7-=d3(Q7);float de=G5(Q7);float B2=ce/max(n9,de);return j9(Q7*B2,k9);} #endif -A rc(A e0,i X0,a0 Z7){A h0=Y3(X0);A L0;switch(Z7){case sc:L0=e0.xyz*h0.xyz;break;case tc:L0=e0.xyz+h0.xyz-e0.xyz*h0.xyz;break;case uc:{for(int C=0;C<3;++C){if(h0[C]<=.5)L0[C]=2.*e0[C]*h0[C];else L0[C]=1.-2.*(1.-e0[C])*(1.-h0[C]);}break;}case vc:L0=min(e0.xyz,h0.xyz);break;case wc:L0=max(e0.xyz,h0.xyz);break;case xc:{X0.xyz=clamp(X0.xyz,K0(.0),X0.www);A T9=clamp(1.-e0,K0(.0),K0(1.))*X0.w;L0=mix(min(K0(1.),X0.xyz/T9),sign(X0.xyz),equal(T9,K0(.0)));break;}case zc:{e0=clamp(e0,K0(.0),K0(1.));X0.xyz=clamp(X0.xyz,K0(.0),X0.www);if(X0.w==.0)X0.w=1.;A U9=X0.w-X0.xyz;L0=1.-mix(min(K0(1.),U9/(e0*X0.w)),sign(U9),equal(e0,K0(.0)));break;}case Ac:{for(int C=0;C<3;++C){if(e0[C]<=.5)L0[C]=2.*e0[C]*h0[C];else L0[C]=1.-2.*(1.-e0[C])*(1.-h0[C]);}break;}case Bc:{for(int C=0;C<3;++C){if(e0[C]<=0.5)L0[C]=h0[C]-(1.-2.*e0[C])*h0[C]*(1.-h0[C]);else if(h0[C]<=.25)L0[C]=h0[C]+(2.*e0[C]-1.)*h0[C]*((16.*h0[C]-12.)*h0[C]+3.);else L0[C]=h0[C]+(2.*e0[C]-1.)*(sqrt(h0[C])-h0[C]);}break;}case Cc:L0=abs(h0.xyz-e0.xyz);break;case Dc:L0=e0.xyz+h0.xyz-2.*e0.xyz*h0.xyz;break; +r ee(r k0,i z1,X o9){r o0=B6(z1);r d1;switch(o9){case fe:d1=k0.xyz*o0.xyz;break;case ge:d1=k0.xyz+o0.xyz-k0.xyz*o0.xyz;break;case he:{r C6=k0*o0;d1=2.0*mix(C6,k0+o0-C6-0.5,greaterThan(o0,T0(0.5)));break;}case ie:d1=min(k0.xyz,o0.xyz);break;case je:d1=max(k0.xyz,o0.xyz);break;case ke:{z1.xyz=clamp(z1.xyz,T0(.0),z1.www);r lb=clamp(1.-k0,T0(.0),T0(1.))*z1.w;d1=mix(min(T0(1.),z1.xyz/lb),sign(z1.xyz),equal(lb,T0(.0)));break;}case me:{k0=clamp(k0,T0(.0),T0(1.));z1.xyz=clamp(z1.xyz,T0(.0),z1.www);if(z1.w==.0)z1.w=1.;r mb=z1.w-z1.xyz;d1=1.-mix(min(T0(1.),mb/(k0*z1.w)),sign(mb),equal(k0,T0(.0)));break;}case ne:{r C6=k0*o0;d1=2.0*mix(C6,k0+o0-C6-0.5,greaterThan(k0,T0(0.5)));break;}case oe:{for(int D0=0;D0<3;++D0){if(k0[D0]<=0.5)d1[D0]=(1.0-o0[D0]);else if(o0[D0]<=0.25)d1[D0]=((16.0*o0[D0]-12.0)*o0[D0]+3.0);else d1[D0]=(inversesqrt(o0[D0])-1.0);}d1=o0+o0*(2.0*k0-1.0)*d1;break;}case pe:d1=abs(o0.xyz-k0.xyz);break;case qe:d1=k0.xyz+o0.xyz-2.*k0.xyz*o0.xyz;break; #ifdef ENABLE_HSL_BLEND_MODES -case Ec:if(ENABLE_HSL_BLEND_MODES){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=R9(e0.xyz,h0.xyz,h0.xyz);}break;case Fc:if(ENABLE_HSL_BLEND_MODES){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=R9(h0.xyz,e0.xyz,h0.xyz);}break;case Gc:if(ENABLE_HSL_BLEND_MODES){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=X7(e0.xyz,h0.xyz);}break;case Hc:if(ENABLE_HSL_BLEND_MODES){e0.xyz=clamp(e0.xyz,K0(.0),K0(1.));L0=X7(h0.xyz,e0.xyz);}break; +case re:if(ENABLE_HSL_BLEND_MODES){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=jb(k0.xyz,o0.xyz,o0.xyz);}break;case se:if(ENABLE_HSL_BLEND_MODES){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=jb(o0.xyz,k0.xyz,o0.xyz);}break;case te:if(ENABLE_HSL_BLEND_MODES){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=j9(k0.xyz,o0.xyz);}break;case ue:if(ENABLE_HSL_BLEND_MODES){k0.xyz=clamp(k0.xyz,T0(.0),T0(1.));d1=j9(o0.xyz,k0.xyz);}break; #endif -}return L0;}d A M4(A e0,i X0,a0 Z7){A L0=rc(e0,X0,Z7);G z5=Z3(X0.w,1.-X0.w);return C0(Ic(L0,e0),z5);} +}return d1;}e r R4(r k0,i z1,X o9){r d1=ee(k0,z1,o9);return mix(k0,d1,T0(z1.w));} #endif #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.exports.h b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.hpp index c123d5898..a3e51efe0 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.glsl.hpp @@ -1,384 +1,387 @@ #pragma once -#include "atomic_draw.exports.h" +#include "atomic_draw.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char atomic_draw[] = R"===(#ifdef KC -#ifdef AB -U0(f0)i0(0,f,LB);i0(1,f,MB);V0 +const char atomic_draw[] = R"===(#ifdef BD +#ifdef BB +A1(c0)r0(0,g,TB);r0(1,g,UB);B1 #endif -o1 -#ifdef EB -n0 H(0,f,D); +h2 +#ifdef GB +J0 d0(0,g,I); #else -n0 H(0,G,D); +J0 d0(0,D,I); #endif -L2 H(1,a0,j0);p1 -#ifdef AB -q1(PB,f0,B,n,K){l0(n,B,LB,f);l0(n,B,MB,f); -#ifdef EB -L(D,f); +S4 d0(1,X,z0);Z1 +#ifdef BB +C1(XB,c0,G,v,S){v0(v,G,TB,g);v0(v,G,UB,g); +#ifdef GB +Y(I,g); #else -L(D,G); +Y(I,D); #endif -L(j0,a0);f Q;uint R;c J;f O;if(E6(LB,MB,K,R,J,O Y1)){ -#ifdef EB -D=O; +Y(z0,X);g O;uint m0;c i0;g J;if(p9(TB,UB,S,m0,i0,J p3)){ +#ifdef GB +I=J; #else -D.xy=F6(O.xy); +I.xy=R7(J.xy); #endif -j0=Q1(R);Q=F2(J);}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(D);P(j0);h1(Q);} +z0=i2(m0);O=H3(i0);}else{O=g(k.O2,k.O2,k.O2,k.O2);}l0(I);l0(z0);D1(O);} #endif #endif -#ifdef GB -#ifdef AB -U0(f0)i0(0,a4,IB);V0 +#if defined(CB)||defined(DB) +#ifdef BB +A1(c0)r0(0,I3,JB);B1 #endif -o1 -#ifdef CB -n0 H(0,c,Q0); +h2 +#ifdef DB +J0 d0(0,c,C2); #else -OB H(0,g,i1); +NB d0(0,d,l1); #endif -L2 H(1,a0,j0);p1 -#ifdef AB -q1(PB,f0,B,n,K){l0(n,B,IB,Z); -#ifdef CB -L(Q0,c); +S4 d0(1,X,z0);Z1 +#ifdef BB +C1(XB,c0,G,v,S){v0(v,G,JB,V); +#ifdef DB +Y(C2,c); #else -L(i1,g); +Y(l1,d); #endif -L(j0,a0);uint R;c J; -#ifdef CB -J=a8(IB,R,Q0 Y1); +Y(z0,X);uint m0;c i0; +#ifdef DB +i0=nb(JB,m0,C2 p3); #else -J=c8(IB,R,i1 Y1); +i0=ob(JB,m0,l1 p3); #endif -j0=Q1(R);f Q=F2(J); -#ifdef CB -P(Q0); +z0=i2(m0);g O=H3(i0); +#ifdef DB +l0(C2); #else -P(i1); +l0(l1); #endif -P(j0);h1(Q);} +l0(z0);D1(O);} #endif #endif -#ifdef TC -#ifdef AB -U0(f0)i0(0,f,YB);V0 -#endif -o1 n0 H(0,c,q0);n0 H(1,g,c4); +#ifdef CD #ifdef BB -n0 H(2,f,R0); +A1(c0)r0(0,g,YB);B1 #endif -p1 -#ifdef AB -G6(PB,f0,B,n,K){l0(n,B,YB,f);L(q0,c);L(c4,g); -#ifdef BB -L(R0,f); +h2 J0 d0(0,c,U0);J0 d0(1,d,T4); +#ifdef Z +J0 d0(2,g,N0); #endif -bool d8=YB.z==.0||YB.w==.0;c4=d8?.0:1.;c J=YB.xy;S D0=D1(m0.H6);S A5=transpose(inverse(D0));if(!d8){float e8=q3*f8(A5[1])/dot(D0[1],A5[1]);if(e8>=.5){J.x=.5;c4*=d4(.5/e8);}else{J.x+=e8*YB.z;}float g8=q3*f8(A5[0])/dot(D0[0],A5[0]);if(g8>=.5){J.y=.5;c4*=d4(.5/g8);}else{J.y+=g8*YB.w;}}q0=J;J=C0(D0,J)+m0.S0;if(d8){c e4=C0(A5,YB.zw);e4*=f8(e4)/dot(e4,e4);J+=q3*e4;} +Z1 #ifdef BB -if(BB){R0=I6(D1(m0.R1),m0.Z1,J);} +S7(XB,c0,G,v,S){v0(v,G,YB,g);Y(U0,c);Y(T4,d); +#ifdef Z +Y(N0,g); #endif -f Q=F2(J);P(q0);P(c4); -#ifdef BB -P(R0); +bool q9=YB.z==.0||YB.w==.0;T4=q9?.0:1.;c i0=YB.xy;a0 Y0=j2(A0.r9);a0 D6=transpose(inverse(Y0));if(!q9){float v9=k4*w9(D6[1])/dot(Y0[1],D6[1]);if(v9>=.5){i0.x=.5;T4*=l4(.5/v9);}else{i0.x+=v9*YB.z;}float x9=k4*w9(D6[0])/dot(Y0[0],D6[0]);if(x9>=.5){i0.y=.5;T4*=l4(.5/x9);}else{i0.y+=x9*YB.w;}}U0=i0;i0=Z0(Y0,i0)+A0.a2;if(q9){c J3=Z0(D6,YB.zw);J3*=w9(J3)/dot(J3,J3);i0+=k4*J3;} +#ifdef Z +if(Z){N0=T7(j2(A0.k2),A0.D2,i0);} #endif -h1(Q);} +g O=H3(i0);l0(U0);l0(T4); +#ifdef Z +l0(N0); #endif -#elif defined(UD) -#ifdef AB -U0(a2)i0(0,c,SB);V0 U0(v2)i0(1,c,TB);V0 +D1(O);} #endif -o1 n0 H(0,c,q0); +#elif defined(KB) #ifdef BB -n0 H(1,f,R0); +A1(e3)r0(0,c,FC);B1 A1(q3)r0(1,c,GC);B1 #endif -p1 -#ifdef AB -N4(PB,a2,c2,v2,w2,n){l0(n,c2,SB,c);l0(n,w2,TB,c);L(q0,c); -#ifdef BB -L(R0,f); +h2 J0 d0(0,c,U0); +#ifdef Z +J0 d0(1,g,N0); #endif -S D0=D1(m0.H6);c J=C0(D0,SB)+m0.S0;q0=TB; +Z1 #ifdef BB -if(BB){R0=I6(D1(m0.R1),m0.Z1,J);} +E6(XB,e3,f3,q3,r3,v){v0(v,f3,FC,c);v0(v,r3,GC,c);Y(U0,c); +#ifdef Z +Y(N0,g); #endif -f Q=F2(J);P(q0); -#ifdef BB -P(R0); +a0 Y0=j2(A0.r9);c i0=Z0(Y0,FC)+A0.a2;U0=GC; +#ifdef Z +if(Z){N0=T7(j2(A0.k2),A0.D2,i0);} #endif -h1(Q);} +g O=H3(i0);l0(U0); +#ifdef Z +l0(N0); #endif +D1(O);} #endif -#ifdef VD -#ifdef AB -U0(f0)V0 #endif -o1 p1 -#ifdef AB -q1(PB,f0,B,n,K){c0 S1;S1.x=(n&1)==0?q.J6.x:q.J6.z;S1.y=(n&2)==0?q.J6.y:q.J6.w;f Q=F2(c(S1));h1(Q);} +#ifdef OE +#ifdef BB +A1(c0)B1 #endif +h2 Z1 +#ifdef BB +C1(XB,c0,G,v,S){U l2;l2.x=(v&1)==0?k.U7.x:k.U7.z;l2.y=(v&2)==0?k.U7.y:k.U7.w;g O=H3(c(l2));D1(O);} #endif -#ifdef UC #endif -#ifdef HB -x2 -#ifndef QB -#ifdef LD -#define h8 LD +#ifdef WD +#endif +#ifdef EB +K1 +#ifndef K +#ifdef XD +#define y9 XD #else -#define h8 i8 +#define y9 P2 #endif -#ifdef LC -O4(h8,H0); +#ifdef TC +m4(y9,j0); #else -M0(h8,H0); +p0(y9,j0); #endif #endif -#ifdef ZB -#define r3 i -#define j8 I0 -#define K6 E1(.0) -#define V9(m) ((m).w!=.0) -#ifdef T +#ifdef PC +#define n4 i +#define z9 H0 +#define V7 B0(.0) +#define pb(q) ((q).w!=.0) +#ifdef M #ifndef HC -M0(B5,r1); +p0(Q2,e0); #else -O4(B5,r1); +m4(Q2,e0); #endif #endif #else -#define r3 uint -#define K6 0u -#define j8 j1 -#define V9(m) ((m)!=0u) -#ifdef T -Y0(B5,r1); -#endif -#endif -f4(k8,v3);y2 w3 g4(l8,W9,DC);h4(m8,X9,KB);x3 d uint Jc(float x){return uint(round(x*n8+o8));}d g L6(uint x){return d4(float(x)*Y9+(-o8*Y9));} -#ifdef T -d void Z9(uint Z0,r3 I1,i4(g)E){ -#ifdef ZB -if(all(lessThan(abs(I1.xy-unpackUnorm4x8(Z0).xy),Z3(.25/255.))))E=min(E,I1.z);else E=.0; +#define n4 uint +#define V7 0u +#define z9 e1 +#define pb(q) ((q)!=0u) +#ifdef M +f1(Q2,e0); +#endif +#endif +o4(F6,p4);L1 K3 H5(qb,ve,UC);I5(rb,we,OB);L3 e uint xe(float x){return uint(round(x*A9+B9));}e d W7(uint x){return l4(float(x)*sb+(-B9*sb));}X X7(X m0){ +#ifdef PE +m0=min(m0,k.ye); +#endif +return m0;} +#ifdef M +e void tb(uint V0,n4 O0,U4(d)n){ +#ifdef PC +if(all(lessThan(abs(O0.xy-unpackUnorm4x8(V0).xy),A2(.25/255.))))n=min(n,O0.z);else n=.0; #else -if(Z0==I1>>16)E=min(E,unpackHalf2x16(I1).x);else E=.0; +if(V0==O0>>16)n=min(n,unpackHalf2x16(O0).x);else n=.0; #endif } #endif -d void M6(uint R,g F1,k1(i)U -#if defined(T)&&!defined(HC) -,i4(r3)a1 +e void Y7(uint m0,d n0,g1(i)P +#if defined(M)&&!defined(HC) +,U4(n4)q1 #endif -C5 y3){N0 F0=k4(DC,R);g E=F1;if((F0.x&(Kc|p8))!=0u){E=abs(E); +G6 r4){W0 r1=J5(UC,m0);d n=n0;if((r1.x&(ze|C9))!=0u){n=abs(n); #ifdef IC -if(IC&&(F0.x&p8)!=0u){E=1.-abs(fract(E*.5)*2.+-1.);} +if(IC&&(r1.x&C9)!=0u){n=1.-abs(fract(n*.5)*2.+-1.);} #endif -}E=clamp(E,v1(.0),v1(1.)); -#ifdef T -if(T){uint Z0=F0.x>>16u;if(Z0!=0u){Z9(Z0,j8(r1),E);}} +}n=clamp(n,G0(.0),G0(1.)); +#ifdef M +if(M){uint V0=r1.x>>16u;if(V0!=0u){tb(V0,z9(e0),n);}} #endif -#ifdef BB -if(BB&&(F0.x&Lc)!=0u){S D0=D1(w0(KB,R*4u+2u));f S0=w0(KB,R*4u+3u);c Mc=C0(D0,y0)+S0.xy;G aa=F6(abs(Mc)*S0.zw-S0.zw);g l4=clamp(min(aa.x,aa.y)+.5,.0,1.);E=min(E,l4);} +#ifdef Z +if(Z&&(r1.x&Ae)!=0u){a0 Y0=j2(P0(OB,m0*4u+2u));g a2=P0(OB,m0*4u+3u);c Be=Z0(Y0,T)+a2.xy;D ub=R7(abs(Be)*a2.zw-a2.zw);d V4=clamp(min(ub.x,ub.y)+.5,.0,1.);n=min(n,V4);} #endif -uint J1=F0.x&0xfu;if(J1<=q8){U=unpackUnorm4x8(F0.y); -#ifdef T -if(T&&J1==N6){ +uint g3=r1.x&0xfu;if(g3<=vb){P=unpackUnorm4x8(r1.y); +#ifdef M +if(M&&g3==Z7){ #ifndef HC -#ifdef ZB -a1.xy=U.zw;a1.z=E;a1.w=1.; +#ifdef PC +q1.xy=P.zw;q1.z=n;q1.w=1.; #else -a1=F0.y|packHalf2x16(Z3(E,.0)); +q1=r1.y|packHalf2x16(A2(n,.0)); #endif #endif -U=E1(.0);} +P=B0(.0);} #endif -}else{S D0=D1(w0(KB,R*4u));f S0=w0(KB,R*4u+1u);c G2=C0(D0,y0)+S0.xy;float t=J1==O6?G2.x:length(G2);t=clamp(t,.0,1.);float x=t*S0.z+S0.w;float y=uintBitsToFloat(F0.y);U=T1(MC,r8,c(x,y),.0);}U.w*=E; -#if!defined(QB)&&defined(FB) -a0 z3;if(FB&&U.w!=.0&&(z3=Q1((F0.x>>4)&0xfu))!=0u){i w1=I0(H0);U.xyz=M4(U.xyz,w1,z3);} +}else{a0 Y0=j2(P0(OB,m0*4u));g a2=P0(OB,m0*4u+1u);c W4=Z0(Y0,T)+a2.xy;float t=g3==E9?W4.x:length(W4);t=clamp(t,.0,1.);float x=t*a2.z+a2.w;float y=uintBitsToFloat(r1.y);P=m2(DD,wb,c(x,y),.0);}P.w*=n; +#if!defined(K)&&defined(FB) +X n2;if(FB&&P.w!=.0&&(n2=i2((r1.x>>4)&0xfu))!=K5){i M1=H0(j0);P.xyz=R4(P.xyz,M1,n2);} #endif -#ifndef ZB -U.xyz*=U.w; +#if defined(VB)&&(defined(K)||defined(HC)) +P=h3(P); #endif -} -#if!defined(QB)&&!defined(LC) -d void P6(i U y3){ -#ifndef ZB -if(U.w==.0)return;float D5=1.-U.w;if(D5!=.0)U+=I0(H0)*D5; +P.xyz*=P.w;} +#if!defined(K)&&!defined(TC) +e void a8(i P r4){ +#ifndef PC +if(P.w==.0)return;float H6=1.-P.w;if(H6!=.0)P+=H0(j0)*H6; #endif -T0(H0,U);} +C0(j0,P);} #endif -#if defined(T)&&!defined(HC) -d void v8(r3 a1 y3){ -#ifdef ZB -T0(r1,a1); +#if defined(M)&&!defined(HC) +e void F9(n4 q1 r4){ +#ifdef PC +C0(e0,q1); #else -if(a1!=0u)l1(r1,a1); +if(q1!=0u)h1(e0,q1); #endif } #endif -#ifdef QB -#define E5 A3 -#define ca F5 -#define Q4 P4 +#ifdef K +#define I6 o2 +#define xb v4 +#define L5 i3 #else -#define E5 z2 -#define ca R4 -#define Q4 M2 +#define I6 v1 +#define xb M5 +#define L5 c2 #endif -#ifdef KC -E5(NB){ -#ifdef EB -N(D,f); +#ifdef BD +I6(HB){ +#ifdef GB +B(I,g); #else -N(D,G); +B(I,D); #endif -N(j0,a0);g Q6; -#ifdef EB -if(EB&&w8(D)){Q6=R6(D x1);}else if(EB&&S6(D)){Q6=S4(D x1);}else +B(z0,X);d c8; +#ifdef GB +if(GB&&yb(I)){c8=w4(I i1);}else if(GB&&zb(I)){c8=d8(I i1);}else #endif -{Q6=min(min(v1(D.x),abs(v1(D.y))),v1(1.));}i U=E1(.0); -#ifdef T -r3 a1=K6; +{c8=min(min(G0(I.x),abs(G0(I.y))),G0(1.));}i P=B0(.0); +#ifdef M +n4 q1=V7; #endif -uint T6=Jc(Q6);uint da=(ea(j0)<>T4);if(N2==j0){if(!U6(D)){T6+=U1-max(da,U1);T6-=x8;H5(v3,T6);}}else{g F1=L6(U1&V6);M6(N2,F1,U -#ifdef T -,a1 +uint e8=xe(c8);uint Ab=(Bb(z0)<>N5);E1=X7(E1);if(E1==z0){if(!P5(I)){e8+=p2-max(Ab,p2);e8-=G9;Q5(p4,e8);}}else{d n0=W7(p2&f8);Y7(E1,n0,P +#ifdef M +,q1 #endif -Y2 G1);} -#ifdef QB -K1=U; +R2 U1);}P.xyz=M3(P.xyz,T.xy,k.v3,k.w3); +#ifdef K +m1=P; #else -P6(U G1); +a8(P U1); #endif -#ifdef T -v8(a1 G1); +#ifdef M +F9(q1 U1); #endif -Q4} +L5} #endif -#ifdef GB -E5(NB){ -#ifdef CB -N(Q0,c); +#if defined(CB)||defined(DB) +I6(HB){ +#ifdef DB +B(C2,c); #else -N(i1,g); +B(l1,d); #endif -N(j0,a0);uint U1=m4(v3);a0 N2=Q1(U1>>T4);uint y8; -#ifndef CB -if(N2==j0){y8=U1;}else +B(z0,X);uint p2=N3(p4);X E1=i2(p2>>N5);E1=X7(E1);uint H9; +#ifndef DB +if(E1==z0){H9=p2;}else #endif -{y8=(ea(j0)<>T4);g z8=L6(U1&V6);i U; -#ifdef T -r3 a1=K6; +uint p2=N3(p4);X E1=i2(p2>>N5);E1=X7(E1);d J9=W7(p2&f8);i P; +#ifdef M +n4 q1=V7; #endif -M6(N2,z8,U -#ifdef T -,a1 +Y7(E1,J9,P +#ifdef M +,q1 #endif -Y2 G1); -#ifdef ZB -U.xyz*=U.w; +R2 U1); +#ifdef M +if(M&&A0.V0!=0u){n4 O0=pb(q1)?q1:z9(e0);tb(A0.V0,O0,S5);} #endif -#ifdef T -if(T&&m0.Z0!=0u){r3 I1=V9(a1)?a1:j8(r1);Z9(m0.Z0,I1,W4);} +#if!defined(K)&&defined(FB) +if(FB&&A0.n2!=K5){i M1=H0(j0)*(1.-P.w)+P;x4.xyz=R4(B6(x4),M1,i2(A0.n2))*x4.w;} #endif -#if!defined(QB)&&defined(FB) -if(FB&&m0.z3!=B8){i w1=I0(H0)*(1.-U.w)+U;V4.xyz=M4(Y3(V4),w1,Q1(m0.z3))*V4.w;} +x4*=S5*l4(A0.y4); +#if defined(VB) +x4=h3(x4); #endif -V4*=W4*d4(m0.H2);U=U*(1.-V4.w)+V4; -#ifdef QB -K1=U; +P=P*(1.-x4.w)+x4;P.xyz=M3(P.xyz,T.xy,k.v3,k.w3); +#ifdef K +m1=P; #else -P6(U G1); +a8(P U1); #endif -#ifdef T -v8(a1 G1); +#ifdef M +F9(q1 U1); #endif -n4(v3,x8);Q4} +O3(p4,G9);L5} #endif -#ifdef WD -E5(NB){ -#ifdef XD -T0(H0,unpackUnorm4x8(q.Oc)); +#ifdef QE +I6(HB){ +#ifdef RE +C0(j0,unpackUnorm4x8(k.De)); #endif -#ifdef YD -i j=I0(H0);T0(H0,j.zyxw); +#ifdef SE +i j=H0(j0);C0(j0,j.zyxw); #endif -n4(v3,q.Pc); -#ifdef T -if(T){l1(r1,0u);} +O3(p4,k.Ee); +#ifdef M +if(M){h1(e0,0u);} #endif -#ifdef QB +#ifdef K discard; #endif -Q4} +L5} #endif #ifdef HC -#ifdef LC -A3(NB) +#ifdef TC +o2(HB) #else -E5(NB) +I6(HB) #endif -{uint U1=m4(v3);g F1=L6(U1&V6);a0 N2=Q1(U1>>T4);i U;M6(N2,F1,U Y2 G1); -#ifdef LC -#ifdef ZB -U.xyz*=U.w; -#endif -float D5=1.-U.w;if(D5!=.0)U+=I0(H0)*D5;K1=U;P4 +{uint p2=N3(p4);d n0=W7(p2&f8);X E1=i2(p2>>N5);E1=X7(E1);i P;Y7(E1,n0,P R2 U1); +#ifdef TC +float H6=1.-P.w;if(H6!=.0)P+=H0(j0)*H6;m1=P;i3 #else -#ifdef QB -K1=U; +P.xyz=M3(P.xyz,T.xy,k.v3,k.w3); +#ifdef K +m1=P; #else -P6(U G1); +a8(P U1); #endif -Q4 +L5 #endif } #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.minified.glsl index 107cf0cb1..c7a88e385 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/atomic_draw.minified.glsl @@ -1,377 +1,380 @@ #ifdef DRAW_PATH #ifdef VERTEX -U0(f0)i0(0,f,LB);i0(1,f,MB);V0 +A1(c0)r0(0,g,TB);r0(1,g,UB);B1 #endif -o1 +h2 #ifdef ENABLE_FEATHER -n0 H(0,f,D); +J0 d0(0,g,I); #else -n0 H(0,G,D); +J0 d0(0,D,I); #endif -L2 H(1,a0,j0);p1 +S4 d0(1,X,z0);Z1 #ifdef VERTEX -q1(PB,f0,B,n,K){l0(n,B,LB,f);l0(n,B,MB,f); +C1(XB,c0,G,v,S){v0(v,G,TB,g);v0(v,G,UB,g); #ifdef ENABLE_FEATHER -L(D,f); +Y(I,g); #else -L(D,G); +Y(I,D); #endif -L(j0,a0);f Q;uint R;c J;f O;if(E6(LB,MB,K,R,J,O Y1)){ +Y(z0,X);g O;uint m0;c i0;g J;if(p9(TB,UB,S,m0,i0,J p3)){ #ifdef ENABLE_FEATHER -D=O; +I=J; #else -D.xy=F6(O.xy); +I.xy=R7(J.xy); #endif -j0=Q1(R);Q=F2(J);}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(D);P(j0);h1(Q);} +z0=i2(m0);O=H3(i0);}else{O=g(k.O2,k.O2,k.O2,k.O2);}l0(I);l0(z0);D1(O);} #endif #endif -#ifdef DRAW_INTERIOR_TRIANGLES +#if defined(DRAW_INTERIOR_TRIANGLES)||defined(ATLAS_BLIT) #ifdef VERTEX -U0(f0)i0(0,a4,IB);V0 +A1(c0)r0(0,I3,JB);B1 #endif -o1 +h2 #ifdef ATLAS_BLIT -n0 H(0,c,Q0); +J0 d0(0,c,C2); #else -OPTIONALLY_FLAT H(0,g,i1); +OPTIONALLY_FLAT d0(0,d,l1); #endif -L2 H(1,a0,j0);p1 +S4 d0(1,X,z0);Z1 #ifdef VERTEX -q1(PB,f0,B,n,K){l0(n,B,IB,Z); +C1(XB,c0,G,v,S){v0(v,G,JB,V); #ifdef ATLAS_BLIT -L(Q0,c); +Y(C2,c); #else -L(i1,g); +Y(l1,d); #endif -L(j0,a0);uint R;c J; +Y(z0,X);uint m0;c i0; #ifdef ATLAS_BLIT -J=a8(IB,R,Q0 Y1); +i0=nb(JB,m0,C2 p3); #else -J=c8(IB,R,i1 Y1); +i0=ob(JB,m0,l1 p3); #endif -j0=Q1(R);f Q=F2(J); +z0=i2(m0);g O=H3(i0); #ifdef ATLAS_BLIT -P(Q0); +l0(C2); #else -P(i1); +l0(l1); #endif -P(j0);h1(Q);} +l0(z0);D1(O);} #endif #endif #ifdef DRAW_IMAGE_RECT #ifdef VERTEX -U0(f0)i0(0,f,YB);V0 +A1(c0)r0(0,g,YB);B1 #endif -o1 n0 H(0,c,q0);n0 H(1,g,c4); +h2 J0 d0(0,c,U0);J0 d0(1,d,T4); #ifdef ENABLE_CLIP_RECT -n0 H(2,f,R0); +J0 d0(2,g,N0); #endif -p1 +Z1 #ifdef VERTEX -G6(PB,f0,B,n,K){l0(n,B,YB,f);L(q0,c);L(c4,g); +S7(XB,c0,G,v,S){v0(v,G,YB,g);Y(U0,c);Y(T4,d); #ifdef ENABLE_CLIP_RECT -L(R0,f); +Y(N0,g); #endif -bool d8=YB.z==.0||YB.w==.0;c4=d8?.0:1.;c J=YB.xy;S D0=D1(m0.H6);S A5=transpose(inverse(D0));if(!d8){float e8=q3*f8(A5[1])/dot(D0[1],A5[1]);if(e8>=.5){J.x=.5;c4*=d4(.5/e8);}else{J.x+=e8*YB.z;}float g8=q3*f8(A5[0])/dot(D0[0],A5[0]);if(g8>=.5){J.y=.5;c4*=d4(.5/g8);}else{J.y+=g8*YB.w;}}q0=J;J=C0(D0,J)+m0.S0;if(d8){c e4=C0(A5,YB.zw);e4*=f8(e4)/dot(e4,e4);J+=q3*e4;} +bool q9=YB.z==.0||YB.w==.0;T4=q9?.0:1.;c i0=YB.xy;a0 Y0=j2(A0.r9);a0 D6=transpose(inverse(Y0));if(!q9){float v9=k4*w9(D6[1])/dot(Y0[1],D6[1]);if(v9>=.5){i0.x=.5;T4*=l4(.5/v9);}else{i0.x+=v9*YB.z;}float x9=k4*w9(D6[0])/dot(Y0[0],D6[0]);if(x9>=.5){i0.y=.5;T4*=l4(.5/x9);}else{i0.y+=x9*YB.w;}}U0=i0;i0=Z0(Y0,i0)+A0.a2;if(q9){c J3=Z0(D6,YB.zw);J3*=w9(J3)/dot(J3,J3);i0+=k4*J3;} #ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT){R0=I6(D1(m0.R1),m0.Z1,J);} +if(ENABLE_CLIP_RECT){N0=T7(j2(A0.k2),A0.D2,i0);} #endif -f Q=F2(J);P(q0);P(c4); +g O=H3(i0);l0(U0);l0(T4); #ifdef ENABLE_CLIP_RECT -P(R0); +l0(N0); #endif -h1(Q);} +D1(O);} #endif #elif defined(DRAW_IMAGE_MESH) #ifdef VERTEX -U0(a2)i0(0,c,SB);V0 U0(v2)i0(1,c,TB);V0 +A1(e3)r0(0,c,FC);B1 A1(q3)r0(1,c,GC);B1 #endif -o1 n0 H(0,c,q0); +h2 J0 d0(0,c,U0); #ifdef ENABLE_CLIP_RECT -n0 H(1,f,R0); +J0 d0(1,g,N0); #endif -p1 +Z1 #ifdef VERTEX -N4(PB,a2,c2,v2,w2,n){l0(n,c2,SB,c);l0(n,w2,TB,c);L(q0,c); +E6(XB,e3,f3,q3,r3,v){v0(v,f3,FC,c);v0(v,r3,GC,c);Y(U0,c); #ifdef ENABLE_CLIP_RECT -L(R0,f); +Y(N0,g); #endif -S D0=D1(m0.H6);c J=C0(D0,SB)+m0.S0;q0=TB; +a0 Y0=j2(A0.r9);c i0=Z0(Y0,FC)+A0.a2;U0=GC; #ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT){R0=I6(D1(m0.R1),m0.Z1,J);} +if(ENABLE_CLIP_RECT){N0=T7(j2(A0.k2),A0.D2,i0);} #endif -f Q=F2(J);P(q0); +g O=H3(i0);l0(U0); #ifdef ENABLE_CLIP_RECT -P(R0); +l0(N0); #endif -h1(Q);} +D1(O);} #endif #endif #ifdef DRAW_RENDER_TARGET_UPDATE_BOUNDS #ifdef VERTEX -U0(f0)V0 +A1(c0)B1 #endif -o1 p1 +h2 Z1 #ifdef VERTEX -q1(PB,f0,B,n,K){c0 S1;S1.x=(n&1)==0?q.J6.x:q.J6.z;S1.y=(n&2)==0?q.J6.y:q.J6.w;f Q=F2(c(S1));h1(Q);} +C1(XB,c0,G,v,S){U l2;l2.x=(v&1)==0?k.U7.x:k.U7.z;l2.y=(v&2)==0?k.U7.y:k.U7.w;g O=H3(c(l2));D1(O);} #endif #endif #ifdef DRAW_IMAGE #endif #ifdef FRAGMENT -x2 +K1 #ifndef FIXED_FUNCTION_COLOR_OUTPUT #ifdef COLOR_PLANE_IDX_OVERRIDE -#define h8 COLOR_PLANE_IDX_OVERRIDE +#define y9 COLOR_PLANE_IDX_OVERRIDE #else -#define h8 i8 +#define y9 P2 #endif #ifdef COALESCED_PLS_RESOLVE_AND_TRANSFER -O4(h8,H0); +m4(y9,j0); #else -M0(h8,H0); +p0(y9,j0); #endif #endif #ifdef PLS_BLEND_SRC_OVER -#define r3 i -#define j8 I0 -#define K6 E1(.0) -#define V9(m) ((m).w!=.0) +#define n4 i +#define z9 H0 +#define V7 B0(.0) +#define pb(q) ((q).w!=.0) #ifdef ENABLE_CLIPPING #ifndef RESOLVE_PLS -M0(B5,r1); +p0(Q2,e0); #else -O4(B5,r1); +m4(Q2,e0); #endif #endif #else -#define r3 uint -#define K6 0u -#define j8 j1 -#define V9(m) ((m)!=0u) +#define n4 uint +#define V7 0u +#define z9 e1 +#define pb(q) ((q)!=0u) #ifdef ENABLE_CLIPPING -Y0(B5,r1); +f1(Q2,e0); #endif #endif -f4(k8,v3);y2 w3 g4(l8,W9,DC);h4(m8,X9,KB);x3 d uint Jc(float x){return uint(round(x*n8+o8));}d g L6(uint x){return d4(float(x)*Y9+(-o8*Y9));} +o4(F6,p4);L1 K3 H5(qb,ve,UC);I5(rb,we,OB);L3 e uint xe(float x){return uint(round(x*A9+B9));}e d W7(uint x){return l4(float(x)*sb+(-B9*sb));}X X7(X m0){ +#ifdef NEEDS_PATH_ID_CLAMP_WORKAROUND +m0=min(m0,k.ye); +#endif +return m0;} #ifdef ENABLE_CLIPPING -d void Z9(uint Z0,r3 I1,i4(g)E){ +e void tb(uint V0,n4 O0,U4(d)n){ #ifdef PLS_BLEND_SRC_OVER -if(all(lessThan(abs(I1.xy-unpackUnorm4x8(Z0).xy),Z3(.25/255.))))E=min(E,I1.z);else E=.0; +if(all(lessThan(abs(O0.xy-unpackUnorm4x8(V0).xy),A2(.25/255.))))n=min(n,O0.z);else n=.0; #else -if(Z0==I1>>16)E=min(E,unpackHalf2x16(I1).x);else E=.0; +if(V0==O0>>16)n=min(n,unpackHalf2x16(O0).x);else n=.0; #endif } #endif -d void M6(uint R,g F1,k1(i)U +e void Y7(uint m0,d n0,g1(i)P #if defined(ENABLE_CLIPPING)&&!defined(RESOLVE_PLS) -,i4(r3)a1 +,U4(n4)q1 #endif -C5 y3){N0 F0=k4(DC,R);g E=F1;if((F0.x&(Kc|p8))!=0u){E=abs(E); +G6 r4){W0 r1=J5(UC,m0);d n=n0;if((r1.x&(ze|C9))!=0u){n=abs(n); #ifdef ENABLE_EVEN_ODD -if(ENABLE_EVEN_ODD&&(F0.x&p8)!=0u){E=1.-abs(fract(E*.5)*2.+-1.);} +if(ENABLE_EVEN_ODD&&(r1.x&C9)!=0u){n=1.-abs(fract(n*.5)*2.+-1.);} #endif -}E=clamp(E,v1(.0),v1(1.)); +}n=clamp(n,G0(.0),G0(1.)); #ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING){uint Z0=F0.x>>16u;if(Z0!=0u){Z9(Z0,j8(r1),E);}} +if(ENABLE_CLIPPING){uint V0=r1.x>>16u;if(V0!=0u){tb(V0,z9(e0),n);}} #endif #ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT&&(F0.x&Lc)!=0u){S D0=D1(w0(KB,R*4u+2u));f S0=w0(KB,R*4u+3u);c Mc=C0(D0,y0)+S0.xy;G aa=F6(abs(Mc)*S0.zw-S0.zw);g l4=clamp(min(aa.x,aa.y)+.5,.0,1.);E=min(E,l4);} +if(ENABLE_CLIP_RECT&&(r1.x&Ae)!=0u){a0 Y0=j2(P0(OB,m0*4u+2u));g a2=P0(OB,m0*4u+3u);c Be=Z0(Y0,T)+a2.xy;D ub=R7(abs(Be)*a2.zw-a2.zw);d V4=clamp(min(ub.x,ub.y)+.5,.0,1.);n=min(n,V4);} #endif -uint J1=F0.x&0xfu;if(J1<=q8){U=unpackUnorm4x8(F0.y); +uint g3=r1.x&0xfu;if(g3<=vb){P=unpackUnorm4x8(r1.y); #ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING&&J1==N6){ +if(ENABLE_CLIPPING&&g3==Z7){ #ifndef RESOLVE_PLS #ifdef PLS_BLEND_SRC_OVER -a1.xy=U.zw;a1.z=E;a1.w=1.; +q1.xy=P.zw;q1.z=n;q1.w=1.; #else -a1=F0.y|packHalf2x16(Z3(E,.0)); +q1=r1.y|packHalf2x16(A2(n,.0)); #endif #endif -U=E1(.0);} +P=B0(.0);} #endif -}else{S D0=D1(w0(KB,R*4u));f S0=w0(KB,R*4u+1u);c G2=C0(D0,y0)+S0.xy;float t=J1==O6?G2.x:length(G2);t=clamp(t,.0,1.);float x=t*S0.z+S0.w;float y=uintBitsToFloat(F0.y);U=T1(MC,r8,c(x,y),.0);}U.w*=E; +}else{a0 Y0=j2(P0(OB,m0*4u));g a2=P0(OB,m0*4u+1u);c W4=Z0(Y0,T)+a2.xy;float t=g3==E9?W4.x:length(W4);t=clamp(t,.0,1.);float x=t*a2.z+a2.w;float y=uintBitsToFloat(r1.y);P=m2(DD,wb,c(x,y),.0);}P.w*=n; #if!defined(FIXED_FUNCTION_COLOR_OUTPUT)&&defined(ENABLE_ADVANCED_BLEND) -a0 z3;if(ENABLE_ADVANCED_BLEND&&U.w!=.0&&(z3=Q1((F0.x>>4)&0xfu))!=0u){i w1=I0(H0);U.xyz=M4(U.xyz,w1,z3);} +X n2;if(ENABLE_ADVANCED_BLEND&&P.w!=.0&&(n2=i2((r1.x>>4)&0xfu))!=K5){i M1=H0(j0);P.xyz=R4(P.xyz,M1,n2);} #endif -#ifndef PLS_BLEND_SRC_OVER -U.xyz*=U.w; +#if defined(NEEDS_GAMMA_CORRECTION)&&(defined(FIXED_FUNCTION_COLOR_OUTPUT)||defined(RESOLVE_PLS)) +P=h3(P); #endif -} +P.xyz*=P.w;} #if!defined(FIXED_FUNCTION_COLOR_OUTPUT)&&!defined(COALESCED_PLS_RESOLVE_AND_TRANSFER) -d void P6(i U y3){ +e void a8(i P r4){ #ifndef PLS_BLEND_SRC_OVER -if(U.w==.0)return;float D5=1.-U.w;if(D5!=.0)U+=I0(H0)*D5; +if(P.w==.0)return;float H6=1.-P.w;if(H6!=.0)P+=H0(j0)*H6; #endif -T0(H0,U);} +C0(j0,P);} #endif #if defined(ENABLE_CLIPPING)&&!defined(RESOLVE_PLS) -d void v8(r3 a1 y3){ +e void F9(n4 q1 r4){ #ifdef PLS_BLEND_SRC_OVER -T0(r1,a1); +C0(e0,q1); #else -if(a1!=0u)l1(r1,a1); +if(q1!=0u)h1(e0,q1); #endif } #endif #ifdef FIXED_FUNCTION_COLOR_OUTPUT -#define E5 A3 -#define ca F5 -#define Q4 P4 +#define I6 o2 +#define xb v4 +#define L5 i3 #else -#define E5 z2 -#define ca R4 -#define Q4 M2 +#define I6 v1 +#define xb M5 +#define L5 c2 #endif #ifdef DRAW_PATH -E5(NB){ +I6(HB){ #ifdef ENABLE_FEATHER -N(D,f); +B(I,g); #else -N(D,G); +B(I,D); #endif -N(j0,a0);g Q6; +B(z0,X);d c8; #ifdef ENABLE_FEATHER -if(ENABLE_FEATHER&&w8(D)){Q6=R6(D x1);}else if(ENABLE_FEATHER&&S6(D)){Q6=S4(D x1);}else +if(ENABLE_FEATHER&&yb(I)){c8=w4(I i1);}else if(ENABLE_FEATHER&&zb(I)){c8=d8(I i1);}else #endif -{Q6=min(min(v1(D.x),abs(v1(D.y))),v1(1.));}i U=E1(.0); +{c8=min(min(G0(I.x),abs(G0(I.y))),G0(1.));}i P=B0(.0); #ifdef ENABLE_CLIPPING -r3 a1=K6; +n4 q1=V7; #endif -uint T6=Jc(Q6);uint da=(ea(j0)<>T4);if(N2==j0){if(!U6(D)){T6+=U1-max(da,U1);T6-=x8;H5(v3,T6);}}else{g F1=L6(U1&V6);M6(N2,F1,U +uint e8=xe(c8);uint Ab=(Bb(z0)<>N5);E1=X7(E1);if(E1==z0){if(!P5(I)){e8+=p2-max(Ab,p2);e8-=G9;Q5(p4,e8);}}else{d n0=W7(p2&f8);Y7(E1,n0,P #ifdef ENABLE_CLIPPING -,a1 +,q1 #endif -Y2 G1);} +R2 U1);}P.xyz=M3(P.xyz,T.xy,k.v3,k.w3); #ifdef FIXED_FUNCTION_COLOR_OUTPUT -K1=U; +m1=P; #else -P6(U G1); +a8(P U1); #endif #ifdef ENABLE_CLIPPING -v8(a1 G1); +F9(q1 U1); #endif -Q4} +L5} #endif -#ifdef DRAW_INTERIOR_TRIANGLES -E5(NB){ +#if defined(DRAW_INTERIOR_TRIANGLES)||defined(ATLAS_BLIT) +I6(HB){ #ifdef ATLAS_BLIT -N(Q0,c); +B(C2,c); #else -N(i1,g); +B(l1,d); #endif -N(j0,a0);uint U1=m4(v3);a0 N2=Q1(U1>>T4);uint y8; +B(z0,X);uint p2=N3(p4);X E1=i2(p2>>N5);E1=X7(E1);uint H9; #ifndef ATLAS_BLIT -if(N2==j0){y8=U1;}else +if(E1==z0){H9=p2;}else #endif -{y8=(ea(j0)<>T4);g z8=L6(U1&V6);i U; +uint p2=N3(p4);X E1=i2(p2>>N5);E1=X7(E1);d J9=W7(p2&f8);i P; #ifdef ENABLE_CLIPPING -r3 a1=K6; +n4 q1=V7; #endif -M6(N2,z8,U +Y7(E1,J9,P #ifdef ENABLE_CLIPPING -,a1 -#endif -Y2 G1); -#ifdef PLS_BLEND_SRC_OVER -U.xyz*=U.w; +,q1 #endif +R2 U1); #ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING&&m0.Z0!=0u){r3 I1=V9(a1)?a1:j8(r1);Z9(m0.Z0,I1,W4);} +if(ENABLE_CLIPPING&&A0.V0!=0u){n4 O0=pb(q1)?q1:z9(e0);tb(A0.V0,O0,S5);} #endif #if!defined(FIXED_FUNCTION_COLOR_OUTPUT)&&defined(ENABLE_ADVANCED_BLEND) -if(ENABLE_ADVANCED_BLEND&&m0.z3!=B8){i w1=I0(H0)*(1.-U.w)+U;V4.xyz=M4(Y3(V4),w1,Q1(m0.z3))*V4.w;} +if(ENABLE_ADVANCED_BLEND&&A0.n2!=K5){i M1=H0(j0)*(1.-P.w)+P;x4.xyz=R4(B6(x4),M1,i2(A0.n2))*x4.w;} +#endif +x4*=S5*l4(A0.y4); +#if defined(NEEDS_GAMMA_CORRECTION) +x4=h3(x4); #endif -V4*=W4*d4(m0.H2);U=U*(1.-V4.w)+V4; +P=P*(1.-x4.w)+x4;P.xyz=M3(P.xyz,T.xy,k.v3,k.w3); #ifdef FIXED_FUNCTION_COLOR_OUTPUT -K1=U; +m1=P; #else -P6(U G1); +a8(P U1); #endif #ifdef ENABLE_CLIPPING -v8(a1 G1); +F9(q1 U1); #endif -n4(v3,x8);Q4} +O3(p4,G9);L5} #endif #ifdef INITIALIZE_PLS -E5(NB){ +I6(HB){ #ifdef STORE_COLOR_CLEAR -T0(H0,unpackUnorm4x8(q.Oc)); +C0(j0,unpackUnorm4x8(k.De)); #endif #ifdef SWIZZLE_COLOR_BGRA_TO_RGBA -i j=I0(H0);T0(H0,j.zyxw); +i j=H0(j0);C0(j0,j.zyxw); #endif -n4(v3,q.Pc); +O3(p4,k.Ee); #ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING){l1(r1,0u);} +if(ENABLE_CLIPPING){h1(e0,0u);} #endif #ifdef FIXED_FUNCTION_COLOR_OUTPUT discard; #endif -Q4} +L5} #endif #ifdef RESOLVE_PLS #ifdef COALESCED_PLS_RESOLVE_AND_TRANSFER -A3(NB) +o2(HB) #else -E5(NB) +I6(HB) #endif -{uint U1=m4(v3);g F1=L6(U1&V6);a0 N2=Q1(U1>>T4);i U;M6(N2,F1,U Y2 G1); +{uint p2=N3(p4);d n0=W7(p2&f8);X E1=i2(p2>>N5);E1=X7(E1);i P;Y7(E1,n0,P R2 U1); #ifdef COALESCED_PLS_RESOLVE_AND_TRANSFER -#ifdef PLS_BLEND_SRC_OVER -U.xyz*=U.w; -#endif -float D5=1.-U.w;if(D5!=.0)U+=I0(H0)*D5;K1=U;P4 +float H6=1.-P.w;if(H6!=.0)P+=H0(j0)*H6;m1=P;i3 #else +P.xyz=M3(P.xyz,T.xy,k.v3,k.w3); #ifdef FIXED_FUNCTION_COLOR_OUTPUT -K1=U; +m1=P; #else -P6(U G1); +a8(P U1); #endif -Q4 +L5 #endif } #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.exports.h b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.hpp index 9bcd81915..1940ffe27 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.glsl.hpp @@ -1,21 +1,21 @@ #pragma once -#include "bezier_utils.exports.h" +#include "bezier_utils.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char bezier_utils[] = R"===(#ifndef fa -#define fa f +const char bezier_utils[] = R"===(#ifndef Cb +#define Cb g #endif -#ifndef J5 -#define J5 c +#ifndef J6 +#define J6 c #endif -d float C8(c k,c b){float Qc=dot(k,b);float ga=dot(k,k)*dot(b,b);return(ga==.0)?1.:clamp(Qc*inversesqrt(ga),-1.,1.);}d void Rc(c o0,c p0,c x0,c z0,k1(c)o,k1(c)r,k1(c)L1){L1=p0-o0;c K5=x0-p0;c X6=z0-o0;r=K5-L1;o=-3.*K5+X6;}d S D8(c o0,c p0,c x0,c z0){S t;t[0]=(any(notEqual(o0,p0))?p0:any(notEqual(p0,x0))?x0:z0)-o0;t[1]=z0-(any(notEqual(z0,x0))?x0:any(notEqual(x0,p0))?p0:o0);return t;}d float Sc(c o0,c p0,c x0,c z0,float c1,float Tc){c o,r,L1;Rc(o0,p0,x0,z0,o,r,L1);c L5=3.*(((o*c1)+2.*r)*c1+L1);float ha=length(L5);if(ha==.0){return.0;}L5*=1./ha;float Y6=2.*dot(o,L5);float M5=3.*(Y6*c1+4.*dot(r,L5))*c1+6.*dot(L1,L5);float E8=min(c1,1.-c1);float Uc=(Y6*E8*E8+M5)*E8;float ia=min(Tc,Uc*.9999);float A2;if(Y6==.0){A2=ia/M5;}else{float d0=1./Y6;float b=M5*d0,B0=-ia*d0;float N5=(-1./3.)*b,O5=.5*B0;float ja=O5*O5-N5*N5*N5;if(ja<.0){float Z6=sqrt(N5);float O0=acos(O5/(Z6*Z6*Z6));A2=-2.*Z6*cos(O0*(1./3.)+(-O2*2./3.));}else{float o=pow(abs(O5)+sqrt(ja),1./3.);if(O5<.0)o=-o;A2=o!=.0?o+N5/o:.0;}}A2=abs(A2);f t0011=c1+fa(-A2,-A2,A2,A2);f ka=(o.xyxy*t0011+2.*r.xyxy)*t0011+L1.xyxy;S d2=D8(o0,p0,x0,z0);c Vc=t0011.x<1e-3?d2[0]:ka.xy;c Wc=t0011.z>1.-1e-3?d2[1]:ka.zw;return acos(C8(Vc,Wc));}d float a7(float k,float b){k=b<.0?-k:k;b=abs(b);return k>.0?(k1.-1e-3?E2[1]:Hb.zw;return acos(K9(Ke,Le));}e float k8(float o,float b){o=b<.0?-o:o;b=abs(b);return o>.0?(oX4.y?P5.x:P5.y;return max(X4.x,X4.y); +float o=3.*A4;float Lb=A4+z4;float J1=z4;float q2=sqrt(max(A4*A4+Kb*z4,.0));if(Lb<.0)q2=-q2;q2+=Lb;c P6=J6(k8(q2,o),k8(J1,q2));c T5=3.*(P6*(P6*(P6*A4-(z4+A4))+z4));T5=abs(T5);N9=T5.x>T5.y?P6.x:P6.y;return max(T5.x,T5.y); #else -float pa=3.*D3;float r=-C3-D3;float L1=C3;float t=.5;for(int C=0;C<3;++C){float qa=pa*t;t=a7(qa*t-L1,2.*(qa+r));}F8=t;return abs(t*(t*(t*pa+3.*r)+3.*L1)); +float Mb=3.*A4;float F=-z4-A4;float d2=z4;float t=.5;for(int D0=0;D0<3;++D0){float Nb=Mb*t;t=k8(Nb*t-d2,2.*(Nb+F));}N9=t;return abs(t*(t*(t*Mb+3.*F)+3.*d2)); #endif } )==="; diff --git a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.minified.glsl index b1892add7..ba6dbe88a 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/bezier_utils.minified.glsl @@ -1,13 +1,13 @@ -#ifndef fa -#define fa f +#ifndef Cb +#define Cb g #endif -#ifndef J5 -#define J5 c +#ifndef J6 +#define J6 c #endif -d float C8(c k,c b){float Qc=dot(k,b);float ga=dot(k,k)*dot(b,b);return(ga==.0)?1.:clamp(Qc*inversesqrt(ga),-1.,1.);}d void Rc(c o0,c p0,c x0,c z0,k1(c)o,k1(c)r,k1(c)L1){L1=p0-o0;c K5=x0-p0;c X6=z0-o0;r=K5-L1;o=-3.*K5+X6;}d S D8(c o0,c p0,c x0,c z0){S t;t[0]=(any(notEqual(o0,p0))?p0:any(notEqual(p0,x0))?x0:z0)-o0;t[1]=z0-(any(notEqual(z0,x0))?x0:any(notEqual(x0,p0))?p0:o0);return t;}d float Sc(c o0,c p0,c x0,c z0,float c1,float Tc){c o,r,L1;Rc(o0,p0,x0,z0,o,r,L1);c L5=3.*(((o*c1)+2.*r)*c1+L1);float ha=length(L5);if(ha==.0){return.0;}L5*=1./ha;float Y6=2.*dot(o,L5);float M5=3.*(Y6*c1+4.*dot(r,L5))*c1+6.*dot(L1,L5);float E8=min(c1,1.-c1);float Uc=(Y6*E8*E8+M5)*E8;float ia=min(Tc,Uc*.9999);float A2;if(Y6==.0){A2=ia/M5;}else{float d0=1./Y6;float b=M5*d0,B0=-ia*d0;float N5=(-1./3.)*b,O5=.5*B0;float ja=O5*O5-N5*N5*N5;if(ja<.0){float Z6=sqrt(N5);float O0=acos(O5/(Z6*Z6*Z6));A2=-2.*Z6*cos(O0*(1./3.)+(-O2*2./3.));}else{float o=pow(abs(O5)+sqrt(ja),1./3.);if(O5<.0)o=-o;A2=o!=.0?o+N5/o:.0;}}A2=abs(A2);f t0011=c1+fa(-A2,-A2,A2,A2);f ka=(o.xyxy*t0011+2.*r.xyxy)*t0011+L1.xyxy;S d2=D8(o0,p0,x0,z0);c Vc=t0011.x<1e-3?d2[0]:ka.xy;c Wc=t0011.z>1.-1e-3?d2[1]:ka.zw;return acos(C8(Vc,Wc));}d float a7(float k,float b){k=b<.0?-k:k;b=abs(b);return k>.0?(k1.-1e-3?E2[1]:Hb.zw;return acos(K9(Ke,Le));}e float k8(float o,float b){o=b<.0?-o:o;b=abs(b);return o>.0?(oX4.y?P5.x:P5.y;return max(X4.x,X4.y); +float o=3.*A4;float Lb=A4+z4;float J1=z4;float q2=sqrt(max(A4*A4+Kb*z4,.0));if(Lb<.0)q2=-q2;q2+=Lb;c P6=J6(k8(q2,o),k8(J1,q2));c T5=3.*(P6*(P6*(P6*A4-(z4+A4))+z4));T5=abs(T5);N9=T5.x>T5.y?P6.x:P6.y;return max(T5.x,T5.y); #else -float pa=3.*D3;float r=-C3-D3;float L1=C3;float t=.5;for(int C=0;C<3;++C){float qa=pa*t;t=a7(qa*t-L1,2.*(qa+r));}F8=t;return abs(t*(t*(t*pa+3.*r)+3.*L1)); +float Mb=3.*A4;float F=-z4-A4;float d2=z4;float t=.5;for(int D0=0;D0<3;++D0){float Nb=Mb*t;t=k8(Nb*t-d2,2.*(Nb+F));}N9=t;return abs(t*(t*(t*Mb+3.*F)+3.*d2)); #endif } \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.exports.h b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.hpp index dd4a8bdda..84aabb9a7 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.glsl.hpp @@ -1,34 +1,42 @@ #pragma once -#include "blit_texture_as_draw.exports.h" +#include "blit_texture_as_draw.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char blit_texture_as_draw[] = R"===(o1 -#ifndef NC -n0 H(0,c,q0); +const char blit_texture_as_draw[] = R"===(h2 +#ifdef WC +J0 d0(0,c,U0); #endif -p1 -#ifdef AB -P2 Q2 E3 F3 q1(ZD,f0,B,n,K){c S1;S1.x=(n&1)==0?-1.:1.;S1.y=(n&2)==0?-1.:1.; -#ifndef NC -L(q0,c);q0.x=S1.x*.5+.5;q0.y=S1.y*-.5+.5;P(q0); +Z1 +#ifdef BB +P3 Q3 B4 C4 A1(c0)B1 C1(TE,c0,G,v,S){c l2;l2.x=(v&1)==0?-1.:1.;l2.y=(v&2)==0?-1.:1.; +#ifdef WC +Y(U0,c);U0.x=l2.x*.5+.5;U0.y=l2.y*-.5+.5;l0(U0); #endif -f Q=f(S1,0,1);h1(Q);} +g O=g(l2,0,1);D1(O);} #endif -#ifdef HB -R2 C2(0,0,VC);S2 -#ifndef NC -p4 G3(0,Yc)q4 +#ifdef EB +y3 +#ifdef ED +Ne(Y4,R3,ZB); +#else +U2(Y4,R3,ZB); +#endif +z3 +#ifdef WC +Z4 S3(Oe)a5 #endif -e2(i,MD){i G8; -#ifndef NC -N(q0,c);G8=T1(VC,Yc,q0,.0); +V2(i,YD){i l8; +#ifdef WC +B(U0,c);l8=Q6(ZB,Oe,U0,.0); +#elif defined(ED) +l8=(m8(ZB,0,U(floor(T.xy)))+m8(ZB,1,U(floor(T.xy)))+m8(ZB,2,U(floor(T.xy)))+m8(ZB,3,U(floor(T.xy))))*0.25; #else -G8=d1(VC,c0(floor(y0.xy))); +l8=F1(ZB,U(floor(T.xy))); #endif -f2(G8);} +F2(l8);} #endif )==="; } // namespace glsl diff --git a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.minified.glsl index 87edbae8b..a61321ead 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/blit_texture_as_draw.minified.glsl @@ -1,25 +1,33 @@ -o1 -#ifndef USE_TEXEL_FETCH_WITH_FRAG_COORD -n0 H(0,c,q0); +h2 +#ifdef USE_FILTERING +J0 d0(0,c,U0); #endif -p1 +Z1 #ifdef VERTEX -P2 Q2 E3 F3 q1(ZD,f0,B,n,K){c S1;S1.x=(n&1)==0?-1.:1.;S1.y=(n&2)==0?-1.:1.; -#ifndef USE_TEXEL_FETCH_WITH_FRAG_COORD -L(q0,c);q0.x=S1.x*.5+.5;q0.y=S1.y*-.5+.5;P(q0); +P3 Q3 B4 C4 A1(c0)B1 C1(TE,c0,G,v,S){c l2;l2.x=(v&1)==0?-1.:1.;l2.y=(v&2)==0?-1.:1.; +#ifdef USE_FILTERING +Y(U0,c);U0.x=l2.x*.5+.5;U0.y=l2.y*-.5+.5;l0(U0); #endif -f Q=f(S1,0,1);h1(Q);} +g O=g(l2,0,1);D1(O);} #endif #ifdef FRAGMENT -R2 C2(0,0,VC);S2 -#ifndef USE_TEXEL_FETCH_WITH_FRAG_COORD -p4 G3(0,Yc)q4 +y3 +#ifdef SOURCE_TEXTURE_MSAA +Ne(Y4,R3,ZB); +#else +U2(Y4,R3,ZB); +#endif +z3 +#ifdef USE_FILTERING +Z4 S3(Oe)a5 #endif -e2(i,MD){i G8; -#ifndef USE_TEXEL_FETCH_WITH_FRAG_COORD -N(q0,c);G8=T1(VC,Yc,q0,.0); +V2(i,YD){i l8; +#ifdef USE_FILTERING +B(U0,c);l8=Q6(ZB,Oe,U0,.0); +#elif defined(SOURCE_TEXTURE_MSAA) +l8=(m8(ZB,0,U(floor(T.xy)))+m8(ZB,1,U(floor(T.xy)))+m8(ZB,2,U(floor(T.xy)))+m8(ZB,3,U(floor(T.xy))))*0.25; #else -G8=d1(VC,c0(floor(y0.xy))); +l8=F1(ZB,U(floor(T.xy))); #endif -f2(G8);} +F2(l8);} #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.hpp new file mode 100644 index 000000000..69ac5fab2 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.glsl.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "clear_clockwise_atomic_clip.glsl.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char clear_clockwise_atomic_clip[] = R"===(#ifdef BB +A1(c0)r0(0,I3,JB);B1 C1(XB,c0,G,v,S){v0(v,G,JB,I3);g O=H3(JB.xy);D1(O);} +#endif +#ifdef EB +K1 +#ifndef K +p0(P2,j0); +#endif +p0(Q2,e0);L1 c5(HB){C0(e0,B0(.0,.0,.0,1.));T3(B0(.0));} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.minified.glsl new file mode 100644 index 000000000..5fe3ee3ed --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/clear_clockwise_atomic_clip.minified.glsl @@ -0,0 +1,10 @@ +#ifdef VERTEX +A1(c0)r0(0,I3,JB);B1 C1(XB,c0,G,v,S){v0(v,G,JB,I3);g O=H3(JB.xy);D1(O);} +#endif +#ifdef FRAGMENT +K1 +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(P2,j0); +#endif +p0(Q2,e0);L1 c5(HB){C0(e0,B0(.0,.0,.0,1.));T3(B0(.0));} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.exports.h b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.hpp index f826bd8f1..93de6bf7b 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.glsl.hpp @@ -1,31 +1,35 @@ #pragma once -#include "color_ramp.exports.h" +#include "color_ramp.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char color_ramp[] = R"===(#ifdef AB -U0(f0) -#ifdef H8 -i0(0,uint,WC);i0(1,uint,XC);i0(2,uint,YC);i0(3,uint,ZC); +const char color_ramp[] = R"===(#ifdef BB +A1(c0) +#ifdef O9 +r0(0,uint,FD);r0(1,uint,GD);r0(2,uint,HD);r0(3,uint,ID); #else -i0(0,M,AC); +r0(0,Q,AC); #endif -V0 +B1 #endif -o1 n0 H(0,i,Q5);p1 -#ifdef AB -P2 Q2 E3 F3 i Zc(uint j){return ra((M(j,j,j,j)>>M(16,8,0,24))&0xffu)/255.;}q1(AE,f0,B,n,K){ -#ifdef H8 -l0(K,B,WC,uint);l0(K,B,XC,uint);l0(K,B,YC,uint);l0(K,B,ZC,uint);M AC=M(WC,XC,YC,ZC); +h2 J0 d0(0,i,R6);Z1 +#ifdef BB +P3 Q3 B4 C4 i Pe(uint j){return Ob((Q(j,j,j,j)>>Q(16,8,0,24))&0xffu)/255.;}C1(UE,c0,G,v,S){ +#ifdef O9 +v0(S,G,FD,uint);v0(S,G,GD,uint);v0(S,G,HD,uint);v0(S,G,ID,uint);Q AC=Q(FD,GD,HD,ID); #else -l0(K,B,AC,M); +v0(S,G,AC,Q); #endif -L(Q5,i);int c7=n>>1;float x=float(c7<=1?AC.x&0xffffu:AC.x>>16)/65536.;float I8=(n&1)==0?.0:1.;if(q.sa<.0){I8=1.-I8;}uint R5=AC.y;float y=float(R5&~ad)+I8;if((R5&ta)!=0u&&c7==0){if((R5&J8)!=0u)x=.0;else x-=ua;}if((R5&va)!=0u&&c7==3){if((R5&J8)!=0u)x=1.;else x+=ua;}Q5=Zc(c7<=1?AC.z:AC.w);f Q=d7(c(x,y),2.,q.sa);P(Q5);h1(Q);} +Y(R6,i);int n8=v>>1;float x=float(n8<=1?AC.x&0xffffu:AC.x>>16)/65536.;float P9=(v&1)==0?.0:1.;if(k.Pb<.0){P9=1.-P9;}uint S6=AC.y;float y=float(S6&~Qe)+P9;if((S6&Qb)!=0u&&n8==0){if((S6&Q9)!=0u)x=.0;else x-=Rb;}if((S6&Sb)!=0u&&n8==3){if((S6&Q9)!=0u)x=1.;else x+=Rb;}R6=Pe(n8<=1?AC.z:AC.w);g O=o8(c(x,y),2.,k.Pb); +#ifdef JC +O.y=-O.y; #endif -#ifdef HB -R2 S2 e2(i,BE){N(Q5,i);f2(Q5);} +l0(R6);D1(O);} +#endif +#ifdef EB +y3 z3 V2(i,VE){B(R6,i);F2(R6);} #endif )==="; } // namespace glsl diff --git a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.minified.glsl index 3a81006b8..007c4d6bf 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/color_ramp.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/color_ramp.minified.glsl @@ -1,22 +1,26 @@ #ifdef VERTEX -U0(f0) -#ifdef H8 -i0(0,uint,WC);i0(1,uint,XC);i0(2,uint,YC);i0(3,uint,ZC); +A1(c0) +#ifdef O9 +r0(0,uint,FD);r0(1,uint,GD);r0(2,uint,HD);r0(3,uint,ID); #else -i0(0,M,AC); +r0(0,Q,AC); #endif -V0 +B1 #endif -o1 n0 H(0,i,Q5);p1 +h2 J0 d0(0,i,R6);Z1 #ifdef VERTEX -P2 Q2 E3 F3 i Zc(uint j){return ra((M(j,j,j,j)>>M(16,8,0,24))&0xffu)/255.;}q1(AE,f0,B,n,K){ -#ifdef H8 -l0(K,B,WC,uint);l0(K,B,XC,uint);l0(K,B,YC,uint);l0(K,B,ZC,uint);M AC=M(WC,XC,YC,ZC); +P3 Q3 B4 C4 i Pe(uint j){return Ob((Q(j,j,j,j)>>Q(16,8,0,24))&0xffu)/255.;}C1(UE,c0,G,v,S){ +#ifdef O9 +v0(S,G,FD,uint);v0(S,G,GD,uint);v0(S,G,HD,uint);v0(S,G,ID,uint);Q AC=Q(FD,GD,HD,ID); #else -l0(K,B,AC,M); +v0(S,G,AC,Q); #endif -L(Q5,i);int c7=n>>1;float x=float(c7<=1?AC.x&0xffffu:AC.x>>16)/65536.;float I8=(n&1)==0?.0:1.;if(q.sa<.0){I8=1.-I8;}uint R5=AC.y;float y=float(R5&~ad)+I8;if((R5&ta)!=0u&&c7==0){if((R5&J8)!=0u)x=.0;else x-=ua;}if((R5&va)!=0u&&c7==3){if((R5&J8)!=0u)x=1.;else x+=ua;}Q5=Zc(c7<=1?AC.z:AC.w);f Q=d7(c(x,y),2.,q.sa);P(Q5);h1(Q);} +Y(R6,i);int n8=v>>1;float x=float(n8<=1?AC.x&0xffffu:AC.x>>16)/65536.;float P9=(v&1)==0?.0:1.;if(k.Pb<.0){P9=1.-P9;}uint S6=AC.y;float y=float(S6&~Qe)+P9;if((S6&Qb)!=0u&&n8==0){if((S6&Q9)!=0u)x=.0;else x-=Rb;}if((S6&Sb)!=0u&&n8==3){if((S6&Q9)!=0u)x=1.;else x+=Rb;}R6=Pe(n8<=1?AC.z:AC.w);g O=o8(c(x,y),2.,k.Pb); +#ifdef POST_INVERT_Y +O.y=-O.y; +#endif +l0(R6);D1(O);} #endif #ifdef FRAGMENT -R2 S2 e2(i,BE){N(Q5,i);f2(Q5);} +y3 z3 V2(i,VE){B(R6,i);F2(R6);} #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/common.exports.h b/thirdparty/rive_renderer/source/generated/shaders/common.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/common.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/common.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/common.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/common.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/common.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/common.glsl.hpp index 46ae03257..b29111e8c 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/common.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/common.glsl.hpp @@ -1,60 +1,80 @@ #pragma once -#include "common.exports.h" +#include "common.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char common[] = R"===(#define O2 3.14159265359 -#define e7 6.28318530718 -#define S5 1.57079632679 -#ifndef DB -#define q3 float(.5) +const char common[] = R"===(#define x3 3.14159265359 +#define p8 6.28318530718 +#define T6 1.57079632679 +#ifndef AB +#define k4 float(.5) #else -#define q3 float(.0) -#endif -#define F2(l) d7(l,q.bd,q.cd) -#ifdef CE -#define wa(g0,e,a) r4(g0,e,a) -#define H3 f -#define K8(m) m -#define Y4(m) m -#define L8(m) uintBitsToFloat(m) -#define v4(m) floatBitsToUint(m) +#define k4 float(.0) +#endif +#define H3(l) o8(l,k.Re,k.Se) +#ifdef WE +#define Tb(N,f,a) d5(N,f,a) +#define D4 g +#define R9(q) q +#define U5(q) q +#define S9(q) uintBitsToFloat(q) +#define e5(q) floatBitsToUint(q) #else -#define wa(g0,e,a) I3(g0,e,a) -#define H3 M -#define K8(m) floatBitsToUint(m) -#define Y4(m) uintBitsToFloat(m) -#define L8(m) m -#define v4(m) m -#endif -#define J3(m) T5(JC,M8,m,xa,float(xa),.0).x -#define Z4(m) T5(JC,M8,m,ya,float(ya),.0).x -#ifdef za -d g d4(float x){return x;}d g f7(uint x){return float(x);}d g dd(a0 x){return float(x);}d g N8(int x){return float(x);}d i I5(f xyzw){return xyzw;}d G F6(c xy){return xy;}d i ra(M xyzw){return vec4(xyzw);}d a0 O8(g x){return uint(x);}d a0 Q1(uint x){return x;} +#define Tb(N,f,a) E4(N,f,a) +#define D4 Q +#define R9(q) floatBitsToUint(q) +#define U5(q) uintBitsToFloat(q) +#define S9(q) q +#define e5(q) q +#endif +#define Te(a,l,q8) F1(a,U(l)+U(-1,0))q8,F1(a,U(l)+U(0,0))q8,F1(a,U(l)+U(0,-1))q8,F1(a,U(l)+U(-1,-1))q8 +#define f5(q) U6(QC,T9,q,Ub,float(Ub),.0).x +#define Wb(q) U6(QC,T9,q,Vb,float(Vb),.0).x +#ifdef Xb +e d l4(float x){return x;}e d V5(uint x){return float(x);}e d Ue(X x){return float(x);}e d U9(int x){return float(x);}e i X4(g xyzw){return xyzw;}e D R7(c xy){return xy;}e i Ob(Q xyzw){return vec4(xyzw);}e X W5(d x){return uint(x);}e X i2(uint x){return x;} #else -d g d4(float x){return(g)x;}d g f7(uint x){return(g)x;}d g dd(a0 x){return(g)x;}d g N8(int x){return(g)x;}d i I5(f xyzw){return(i)xyzw;}d G F6(c xy){return(G)xy;}d i ra(M xyzw){return(i)xyzw;}d a0 O8(g x){return(a0)x;}d a0 Q1(uint x){return(a0)x;} +e d l4(float x){return(d)x;}e d V5(uint x){return(d)x;}e d Ue(X x){return(d)x;}e d U9(int x){return(d)x;}e i X4(g xyzw){return(i)xyzw;}e D R7(c xy){return(D)xy;}e i Ob(Q xyzw){return(i)xyzw;}e X W5(d x){return(X)x;}e X i2(uint x){return(X)x;} +#endif +e d G0(d x){return x;}e D A2(D xy){return xy;}e D A2(d x,d y){D L;L.x=x,L.y=y;return L;}e D A2(d x){D L;L.x=x,L.y=x;return L;}e c J6(float x){return c(x,x);}e r T0(d x,d y,d z){r L;L.x=x,L.y=y,L.z=z;return L;}e r T0(d x){r L;L.x=x,L.y=x,L.z=x;return L;}e i B0(d x,d y,d z,d w){i L;L.x=x,L.y=y,L.z=z,L.w=w;return L;}e i B0(r xyz,d w){i L;L.xyz=xyz;L.w=w;return L;}e i B0(d x){i L;L.x=x,L.y=x,L.z=x,L.w=x;return L;}e i B0(i x){return x;}e F4 Ve(bool b){return F4(b,b);}e V6 wh(r o,r b,r J1){V6 L;L[0]=o;L[1]=b;L[2]=J1;return L;}e W6 xh(r o,r b){W6 L;L[0]=o;L[1]=b;return L;}e g5 yh(i o,i b,i J1,i We){g5 L;L[0]=o;L[1]=b;L[2]=J1;L[3]=We;return L;}e a0 j2(g x){return a0(x.xy,x.zw);}e uint Bb(X x){return x;}e c X5(c o,c b,float t){return(b-o)*t+o;}e d r8(uint Yb,uint Y5){return Yb==0u?.0:unpackHalf2x16((Yb+Xe)*Y5).x;}e float Zb(c e2){e2=normalize(e2);float j1=acos(clamp(e2.x,-1.,1.));return e2.y>=.0?j1:-j1;}e i zh(i j){return B0(j.xyz*j.w,j.w);}e r B6(i V9){return V9.xyz*(V9.w!=.0?1./V9.w:.0);}e d d3(D X6){return min(X6.x,X6.y);}e d d3(r ac){return min(d3(ac.xy),ac.z);}e d d3(i bc){D X6=min(bc.xy,bc.zw);d Ye=min(X6.x,X6.y);return Ye;}e d G5(D Y6){return max(Y6.x,Y6.y);}e d G5(r cc){return max(G5(cc.xy),cc.z);}e d G5(i dc){D Y6=max(dc.xy,dc.zw);d Ze=max(Y6.x,Y6.y);return Ze;}e float w9(c x){return abs(x.x)+abs(x.y);}e d W9(d x,d X9,d Y9){ +#if defined(XE)||defined(RC) +#ifdef RC +if(RC==af) +#endif +{if(xX9)return x;else return X9;else return Y9;} #endif -d g v1(g x){return x;}d G Z3(G xy){return xy;}d G Z3(g x,g y){G V;V.x=x,V.y=y;return V;}d G Z3(g x){G V;V.x=x,V.y=x;return V;}d c J5(float x){return c(x,x);}d A K0(g x,g y,g z){A V;V.x=x,V.y=y,V.z=z;return V;}d A K0(g x){A V;V.x=x,V.y=x,V.z=x;return V;}d i E1(g x,g y,g z,g w){i V;V.x=x,V.y=y,V.z=z,V.w=w;return V;}d i E1(A xyz,g w){i V;V.xyz=xyz;V.w=w;return V;}d i E1(g x){i V;V.x=x,V.y=x,V.z=x,V.w=x;return V;}d a5 ed(bool b){return a5(b,b);}d U5 qf(A k,A b,A B0){U5 V;V[0]=k;V[1]=b;V[2]=B0;return V;}d V5 Ic(A k,A b){V5 V;V[0]=k;V[1]=b;return V;}d S D1(f x){return S(x.xy,x.zw);}d uint ea(a0 x){return x;}d uint Aa(uint Y){return(Y&fd)-1u;}d c c5(c k,c b,float t){return(b-k)*t+k;}d g g7(uint Ba,uint d5){return Ba==0u?.0:unpackHalf2x16((Ba+gd)*d5).x;}d float Ca(c M1){M1=normalize(M1);float O0=acos(clamp(M1.x,-1.,1.));return M1.y>=.0?O0:-O0;}d i rf(i j){return E1(j.xyz*j.w,j.w);}d A Y3(i P8){return P8.xyz*(P8.w!=.0?1./P8.w:.0);}d g A8(i Da){G Ea=min(Da.xy,Da.zw);g hd=min(Ea.x,Ea.y);return hd;}d float f8(c x){return abs(x.x)+abs(x.y);} -#ifndef UNIFORM_DEFINITIONS_AUTO_GENERATED -e5(K3,VB)float sa;float Fa;float bd;float cd;uint Ga;uint id;uint Oc;uint Pc;h7 J6;c U4;c Ha;uint Z2;uint d5;float C1;uint jd;W5(q) +return clamp(x,X9,Y9);}e d ec(c K0,d B2,d j3){d bf=fract(0.06711056*K0.x+0.00583715*K0.y);d cf=fract(52.9829189*bf);return(cf*B2)+j3;} +#if 0 +e d Ah(c K0,float B2,float j3){int x=int(K0.x);int y=int(K0.y);int fc=(x^y);int b=(y>>1)&1;b|=(fc&2);b|=(y&1)<<2;b|=(fc&1)<<3;float df=float(b);d ef=l4(df)/16.0;return(ef*B2)+j3;}e d Bh(c K0,float B2,float j3){K0.y*=0.5;K0.x=fract(K0.x*0.5+K0.y);K0.y=fract(K0.y);float J3=(K0.y*0.5+K0.x);return(J3*B2)+j3;} #endif -#ifdef AB -d f d7(c Ia,float kd,float Ja){return f(Ia.x*kd-1.,Ia.y*Ja-sign(Ja),0.,1.);} -#ifndef DB -d f I6(S R1,c Z1,c Q8){c R8=abs(R1[0])+abs(R1[1]);if(R8.x!=.0&&R8.y!=.0){c d0=1./R8;c w4=C0(R1,Q8)+Z1;const float ld=.5;return f(w4,-w4)*d0.xyxy+d0.xyxy+ld;}else{return Z1.xyxy;}} +#ifdef IB +e d Z9(c K0,d B2,d j3){return IB?ec(K0,B2,j3):.0;}e r M3(r j,c K0,d B2,d j3){return IB?(ec(K0,B2,j3)+j):j;} #else -d float S8(uint X5){return 1.-float(X5)*(2./32768.);} +e d Z9(c K0,float B2,float j3){return 0.;}e r M3(r j,c K0,d B2,d j3){return j;} +#endif #ifdef BB -d void Ka(S R1,c Z1,c Q8){if(R1!=S(0)){c w4=C0(R1,Q8)+Z1.xy;gl_ClipDistance[0]=w4.x+1.;gl_ClipDistance[1]=w4.y+1.;gl_ClipDistance[2]=1.-w4.x;gl_ClipDistance[3]=1.-w4.y;}else{gl_ClipDistance[0]=gl_ClipDistance[1]=gl_ClipDistance[2]=gl_ClipDistance[3]=Z1.x-.5;}} +e g o8(c gc,float ff,float hc){return g(gc.x*ff-1.,gc.y*hc-sign(hc),0.,1.);} +#ifndef AB +e g T7(a0 k2,c D2,c aa){c ba=abs(k2[0])+abs(k2[1]);if(ba.x!=.0&&ba.y!=.0){c H=1./ba;c h5=Z0(k2,aa)+D2;const float gf=.5;return g(h5,-h5)*H.xyxy+H.xyxy+gf;}else{return D2.xyxy;}} +#else +e float ca(uint Z6){return 1.-float(Z6)*(2./32768.);} +#ifdef Z +e void ic(a0 k2,c D2,c aa a7){ +#ifndef ZD +if(any(notEqual(g(k2),g(.0,.0,.0,.0)))){c h5=Z0(k2,aa)+D2.xy;gl_ClipDistance[0]=h5.x+1.;gl_ClipDistance[1]=h5.y+1.;gl_ClipDistance[2]=1.-h5.x;gl_ClipDistance[3]=1.-h5.y;}else{gl_ClipDistance[0]=gl_ClipDistance[1]=gl_ClipDistance[2]=gl_ClipDistance[3]=D2.x-.5;} +#endif +} +#endif #endif #endif +#ifdef EB +#ifdef VB +e d h3(d j){return(j<=0.04045)?j/12.92:pow(abs((j+0.055)/1.055),2.4);}e r h3(r j){return T0(h3(j.x),h3(j.y),h3(j.z));}e i h3(i j){return B0(h3(j.xyz),j.w);} #endif -#ifdef UC -#ifndef UNIFORM_DEFINITIONS_AUTO_GENERATED -e5(f5,EC)f H6;c S0;float H2;float sf;f R1;c Z1;uint Z0;uint z3;uint X5;W5(m0) #endif +#if defined(EB)&&defined(AB)&&!defined(K) +e i jc(g5 c7,int v8){if(v8==0xf){return(c7[0]+c7[1]+c7[2]+c7[3])*.25;}else{i hf=g(notEqual(v8&Z5(1,2,4,8),Z5(0)));i L=Z0(c7,hf);int w8=(v8&5)+((v8>>1)&5);w8=(w8&3)+(w8>>2);L*=1./float(w8);return L;}} #endif )==="; } // namespace glsl diff --git a/thirdparty/rive_renderer/source/generated/shaders/common.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/common.minified.glsl index 8be32e1d3..ec1af4ebb 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/common.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/common.minified.glsl @@ -1,51 +1,71 @@ -#define O2 3.14159265359 -#define e7 6.28318530718 -#define S5 1.57079632679 +#define x3 3.14159265359 +#define p8 6.28318530718 +#define T6 1.57079632679 #ifndef RENDER_MODE_MSAA -#define q3 float(.5) +#define k4 float(.5) #else -#define q3 float(.0) +#define k4 float(.0) #endif -#define F2(l) d7(l,q.bd,q.cd) +#define H3(l) o8(l,k.Re,k.Se) #ifdef TESS_TEXTURE_FLOATING_POINT -#define wa(g0,e,a) r4(g0,e,a) -#define H3 f -#define K8(m) m -#define Y4(m) m -#define L8(m) uintBitsToFloat(m) -#define v4(m) floatBitsToUint(m) +#define Tb(N,f,a) d5(N,f,a) +#define D4 g +#define R9(q) q +#define U5(q) q +#define S9(q) uintBitsToFloat(q) +#define e5(q) floatBitsToUint(q) #else -#define wa(g0,e,a) I3(g0,e,a) -#define H3 M -#define K8(m) floatBitsToUint(m) -#define Y4(m) uintBitsToFloat(m) -#define L8(m) m -#define v4(m) m -#endif -#define J3(m) T5(JC,M8,m,xa,float(xa),.0).x -#define Z4(m) T5(JC,M8,m,ya,float(ya),.0).x -#ifdef za -d g d4(float x){return x;}d g f7(uint x){return float(x);}d g dd(a0 x){return float(x);}d g N8(int x){return float(x);}d i I5(f xyzw){return xyzw;}d G F6(c xy){return xy;}d i ra(M xyzw){return vec4(xyzw);}d a0 O8(g x){return uint(x);}d a0 Q1(uint x){return x;} +#define Tb(N,f,a) E4(N,f,a) +#define D4 Q +#define R9(q) floatBitsToUint(q) +#define U5(q) uintBitsToFloat(q) +#define S9(q) q +#define e5(q) q +#endif +#define Te(a,l,q8) F1(a,U(l)+U(-1,0))q8,F1(a,U(l)+U(0,0))q8,F1(a,U(l)+U(0,-1))q8,F1(a,U(l)+U(-1,-1))q8 +#define f5(q) U6(QC,T9,q,Ub,float(Ub),.0).x +#define Wb(q) U6(QC,T9,q,Vb,float(Vb),.0).x +#ifdef Xb +e d l4(float x){return x;}e d V5(uint x){return float(x);}e d Ue(X x){return float(x);}e d U9(int x){return float(x);}e i X4(g xyzw){return xyzw;}e D R7(c xy){return xy;}e i Ob(Q xyzw){return vec4(xyzw);}e X W5(d x){return uint(x);}e X i2(uint x){return x;} #else -d g d4(float x){return(g)x;}d g f7(uint x){return(g)x;}d g dd(a0 x){return(g)x;}d g N8(int x){return(g)x;}d i I5(f xyzw){return(i)xyzw;}d G F6(c xy){return(G)xy;}d i ra(M xyzw){return(i)xyzw;}d a0 O8(g x){return(a0)x;}d a0 Q1(uint x){return(a0)x;} +e d l4(float x){return(d)x;}e d V5(uint x){return(d)x;}e d Ue(X x){return(d)x;}e d U9(int x){return(d)x;}e i X4(g xyzw){return(i)xyzw;}e D R7(c xy){return(D)xy;}e i Ob(Q xyzw){return(i)xyzw;}e X W5(d x){return(X)x;}e X i2(uint x){return(X)x;} +#endif +e d G0(d x){return x;}e D A2(D xy){return xy;}e D A2(d x,d y){D L;L.x=x,L.y=y;return L;}e D A2(d x){D L;L.x=x,L.y=x;return L;}e c J6(float x){return c(x,x);}e r T0(d x,d y,d z){r L;L.x=x,L.y=y,L.z=z;return L;}e r T0(d x){r L;L.x=x,L.y=x,L.z=x;return L;}e i B0(d x,d y,d z,d w){i L;L.x=x,L.y=y,L.z=z,L.w=w;return L;}e i B0(r xyz,d w){i L;L.xyz=xyz;L.w=w;return L;}e i B0(d x){i L;L.x=x,L.y=x,L.z=x,L.w=x;return L;}e i B0(i x){return x;}e F4 Ve(bool b){return F4(b,b);}e V6 wh(r o,r b,r J1){V6 L;L[0]=o;L[1]=b;L[2]=J1;return L;}e W6 xh(r o,r b){W6 L;L[0]=o;L[1]=b;return L;}e g5 yh(i o,i b,i J1,i We){g5 L;L[0]=o;L[1]=b;L[2]=J1;L[3]=We;return L;}e a0 j2(g x){return a0(x.xy,x.zw);}e uint Bb(X x){return x;}e c X5(c o,c b,float t){return(b-o)*t+o;}e d r8(uint Yb,uint Y5){return Yb==0u?.0:unpackHalf2x16((Yb+Xe)*Y5).x;}e float Zb(c e2){e2=normalize(e2);float j1=acos(clamp(e2.x,-1.,1.));return e2.y>=.0?j1:-j1;}e i zh(i j){return B0(j.xyz*j.w,j.w);}e r B6(i V9){return V9.xyz*(V9.w!=.0?1./V9.w:.0);}e d d3(D X6){return min(X6.x,X6.y);}e d d3(r ac){return min(d3(ac.xy),ac.z);}e d d3(i bc){D X6=min(bc.xy,bc.zw);d Ye=min(X6.x,X6.y);return Ye;}e d G5(D Y6){return max(Y6.x,Y6.y);}e d G5(r cc){return max(G5(cc.xy),cc.z);}e d G5(i dc){D Y6=max(dc.xy,dc.zw);d Ze=max(Y6.x,Y6.y);return Ze;}e float w9(c x){return abs(x.x)+abs(x.y);}e d W9(d x,d X9,d Y9){ +#if defined(GL_RENDERER_MALI)||defined(VULKAN_VENDOR_ID) +#ifdef VULKAN_VENDOR_ID +if(VULKAN_VENDOR_ID==af) #endif -d g v1(g x){return x;}d G Z3(G xy){return xy;}d G Z3(g x,g y){G V;V.x=x,V.y=y;return V;}d G Z3(g x){G V;V.x=x,V.y=x;return V;}d c J5(float x){return c(x,x);}d A K0(g x,g y,g z){A V;V.x=x,V.y=y,V.z=z;return V;}d A K0(g x){A V;V.x=x,V.y=x,V.z=x;return V;}d i E1(g x,g y,g z,g w){i V;V.x=x,V.y=y,V.z=z,V.w=w;return V;}d i E1(A xyz,g w){i V;V.xyz=xyz;V.w=w;return V;}d i E1(g x){i V;V.x=x,V.y=x,V.z=x,V.w=x;return V;}d a5 ed(bool b){return a5(b,b);}d U5 qf(A k,A b,A B0){U5 V;V[0]=k;V[1]=b;V[2]=B0;return V;}d V5 Ic(A k,A b){V5 V;V[0]=k;V[1]=b;return V;}d S D1(f x){return S(x.xy,x.zw);}d uint ea(a0 x){return x;}d uint Aa(uint Y){return(Y&fd)-1u;}d c c5(c k,c b,float t){return(b-k)*t+k;}d g g7(uint Ba,uint d5){return Ba==0u?.0:unpackHalf2x16((Ba+gd)*d5).x;}d float Ca(c M1){M1=normalize(M1);float O0=acos(clamp(M1.x,-1.,1.));return M1.y>=.0?O0:-O0;}d i rf(i j){return E1(j.xyz*j.w,j.w);}d A Y3(i P8){return P8.xyz*(P8.w!=.0?1./P8.w:.0);}d g A8(i Da){G Ea=min(Da.xy,Da.zw);g hd=min(Ea.x,Ea.y);return hd;}d float f8(c x){return abs(x.x)+abs(x.y);} -#ifndef UNIFORM_DEFINITIONS_AUTO_GENERATED -e5(K3,VB)float sa;float Fa;float bd;float cd;uint Ga;uint id;uint Oc;uint Pc;h7 J6;c U4;c Ha;uint Z2;uint d5;float C1;uint jd;W5(q) +{if(xX9)return x;else return X9;else return Y9;} +#endif +return clamp(x,X9,Y9);}e d ec(c K0,d B2,d j3){d bf=fract(0.06711056*K0.x+0.00583715*K0.y);d cf=fract(52.9829189*bf);return(cf*B2)+j3;} +#if 0 +e d Ah(c K0,float B2,float j3){int x=int(K0.x);int y=int(K0.y);int fc=(x^y);int b=(y>>1)&1;b|=(fc&2);b|=(y&1)<<2;b|=(fc&1)<<3;float df=float(b);d ef=l4(df)/16.0;return(ef*B2)+j3;}e d Bh(c K0,float B2,float j3){K0.y*=0.5;K0.x=fract(K0.x*0.5+K0.y);K0.y=fract(K0.y);float J3=(K0.y*0.5+K0.x);return(J3*B2)+j3;} +#endif +#ifdef ENABLE_DITHER +e d Z9(c K0,d B2,d j3){return ENABLE_DITHER?ec(K0,B2,j3):.0;}e r M3(r j,c K0,d B2,d j3){return ENABLE_DITHER?(ec(K0,B2,j3)+j):j;} +#else +e d Z9(c K0,float B2,float j3){return 0.;}e r M3(r j,c K0,d B2,d j3){return j;} #endif #ifdef VERTEX -d f d7(c Ia,float kd,float Ja){return f(Ia.x*kd-1.,Ia.y*Ja-sign(Ja),0.,1.);} +e g o8(c gc,float ff,float hc){return g(gc.x*ff-1.,gc.y*hc-sign(hc),0.,1.);} #ifndef RENDER_MODE_MSAA -d f I6(S R1,c Z1,c Q8){c R8=abs(R1[0])+abs(R1[1]);if(R8.x!=.0&&R8.y!=.0){c d0=1./R8;c w4=C0(R1,Q8)+Z1;const float ld=.5;return f(w4,-w4)*d0.xyxy+d0.xyxy+ld;}else{return Z1.xyxy;}} +e g T7(a0 k2,c D2,c aa){c ba=abs(k2[0])+abs(k2[1]);if(ba.x!=.0&&ba.y!=.0){c H=1./ba;c h5=Z0(k2,aa)+D2;const float gf=.5;return g(h5,-h5)*H.xyxy+H.xyxy+gf;}else{return D2.xyxy;}} #else -d float S8(uint X5){return 1.-float(X5)*(2./32768.);} +e float ca(uint Z6){return 1.-float(Z6)*(2./32768.);} #ifdef ENABLE_CLIP_RECT -d void Ka(S R1,c Z1,c Q8){if(R1!=S(0)){c w4=C0(R1,Q8)+Z1.xy;gl_ClipDistance[0]=w4.x+1.;gl_ClipDistance[1]=w4.y+1.;gl_ClipDistance[2]=1.-w4.x;gl_ClipDistance[3]=1.-w4.y;}else{gl_ClipDistance[0]=gl_ClipDistance[1]=gl_ClipDistance[2]=gl_ClipDistance[3]=Z1.x-.5;}} +e void ic(a0 k2,c D2,c aa a7){ +#ifndef DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS +if(any(notEqual(g(k2),g(.0,.0,.0,.0)))){c h5=Z0(k2,aa)+D2.xy;gl_ClipDistance[0]=h5.x+1.;gl_ClipDistance[1]=h5.y+1.;gl_ClipDistance[2]=1.-h5.x;gl_ClipDistance[3]=1.-h5.y;}else{gl_ClipDistance[0]=gl_ClipDistance[1]=gl_ClipDistance[2]=gl_ClipDistance[3]=D2.x-.5;} +#endif +} +#endif #endif #endif +#ifdef FRAGMENT +#ifdef NEEDS_GAMMA_CORRECTION +e d h3(d j){return(j<=0.04045)?j/12.92:pow(abs((j+0.055)/1.055),2.4);}e r h3(r j){return T0(h3(j.x),h3(j.y),h3(j.z));}e i h3(i j){return B0(h3(j.xyz),j.w);} #endif -#ifdef DRAW_IMAGE -#ifndef UNIFORM_DEFINITIONS_AUTO_GENERATED -e5(f5,EC)f H6;c S0;float H2;float sf;f R1;c Z1;uint Z0;uint z3;uint X5;W5(m0) #endif +#if defined(FRAGMENT)&&defined(RENDER_MODE_MSAA)&&!defined(FIXED_FUNCTION_COLOR_OUTPUT) +e i jc(g5 c7,int v8){if(v8==0xf){return(c7[0]+c7[1]+c7[2]+c7[3])*.25;}else{i hf=g(notEqual(v8&Z5(1,2,4,8),Z5(0)));i L=Z0(c7,hf);int w8=(v8&5)+((v8>>1)&5);w8=(w8&3)+(w8>>2);L*=1./float(w8);return L;}} #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/constants.exports.h b/thirdparty/rive_renderer/source/generated/shaders/constants.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/constants.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.hpp index daa7b9822..38822cdf8 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/constants.glsl.hpp @@ -1,119 +1,125 @@ #pragma once -#include "constants.exports.h" +#include "constants.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char constants[] = R"===(#define md float(2048) -#define La 11 -#define T8 float(512) -#define ua float(0.001953125) -#define U8 float(3) -#define xa 0 -#define ya 1 -#define Ma 3u -#define nd (Ma+1u) -#define Na 7 -#define Oa 0x7fu -#define ta 0x80000000u -#define va 0x40000000u -#define J8 0x20000000u -#define ad (ta|va|J8) -#define Pa (1u<<31u) -#define od (1u<<29u) -#define a3 (7u<<26u) -#define pd (5u<<26u) -#define qd (4u<<26u) -#define i7 (2u<<26u) -#define j7 (1u<<26u) -#define k7 (1u<<25u) -#define rd (1u<<24u) -#define T2 (1u<<23u) -#define V8 (1u<<22u) -#define Qa (1u<<21u) -#define l7 (1u<<20u) -#define Ra (1u<<19u) -#define fd 0xffffu -#define sd 0u -#define m7 0 -#define Sa 1 -#define Ta 2 -#define m7 0 -#define Sa 1 -#define Ta 2 -#define N6 0u -#define q8 1u -#define O6 2u -#define td 3u -#define ud 4u -#define Kc 0x100u -#define p8 0x200u -#define Lc 0x400u -#define U2 0 -#define Y5 1 -#define K3 0 -#define Ua 1 -#define f5 2 -#define Va 3 -#define l8 4 -#define m8 5 -#define Wa 6 -#define vd 7 -#define wd 8 -#define Xa 9 -#define Z5 10 -#define Ya 11 -#define W8 12 -#define X8 13 -#define Za 14 -#define g5 15 -#define P0(e) (2+e) -#define ab 2 -#define a6 3 -#define i8 0 -#define B5 1 -#define bb 2 -#define k8 3 -#define xd 4 -#define gd 1023u -#define B8 0u -#define tc 1u -#define uc 2u -#define vc 3u -#define wc 4u -#define xc 5u -#define zc 6u -#define Ac 7u -#define Bc 8u -#define Cc 9u -#define Dc 10u -#define sc 11u -#define Ec 12u -#define Fc 13u -#define Gc 14u -#define Hc 15u -#define n8 float(2048) -#define Y9 float(0.00048828125) -#define o8 float(1<<16) -#define x8 (1u<<16) -#define T4 17u -#define V6 0x1ffffu -#define Y8 0x1ffffu -#define Z8 float(2048) -#define a9 float(0.00048828125) -#define c6 (1u<<16) -#define yd 0x13B5u -#define zd 0 -#define Ad 1 -#define Bd 2 -#define Cd 3 -#define Dd 4 -#define Ed 5 -#define Fd 6 -#define Gd 7 -#define Hd 8 -#define Id 9 +const char constants[] = R"===(#define jf float(2048) +#define kc 11 +#define da float(512) +#define Rb float(0.001953125) +#define ea float(3) +#define Ub 0 +#define Vb 1 +#define lc 3u +#define kf (lc+1u) +#define lf float(1.0) +#define mc 7 +#define nc 0x7fu +#define Qb 0x80000000u +#define Sb 0x40000000u +#define Q9 0x20000000u +#define Qe (Qb|Sb|Q9) +#define oc (1u<<31u) +#define mf (1u<<29u) +#define U3 (7u<<26u) +#define nf (5u<<26u) +#define of (4u<<26u) +#define x8 (2u<<26u) +#define y8 (1u<<26u) +#define z8 (1u<<25u) +#define pf (1u<<24u) +#define A3 (1u<<23u) +#define fa (1u<<22u) +#define pc (1u<<21u) +#define A8 (1u<<20u) +#define qc (1u<<19u) +#define rc 0xffffu +#define qf .0 +#define B8 0 +#define sc 1 +#define tc 2 +#define B8 0 +#define sc 1 +#define tc 2 +#define Z7 0u +#define vb 1u +#define E9 2u +#define rf 3u +#define ze 0x100u +#define C9 0x200u +#define Ae 0x400u +#define X2 0 +#define Y4 1 +#define k3 0 +#define uc 1 +#define a6 2 +#define vc 3 +#define qb 4 +#define rb 5 +#define wc 6 +#define ga 7 +#define sf 8 +#define xc 9 +#define d7 10 +#define yc 11 +#define R3 12 +#define tf 13 +#define c6 14 +#define uf 14 +#define Q0(f) (2+f) +#define B3 2 +#define vf 3 +#define P2 0 +#define Q2 1 +#define d6 2 +#define F6 3 +#define Xe 1023u +#define n9 6.2e-5 +#define K5 0u +#define ge 1u +#define he 2u +#define ie 3u +#define je 4u +#define ke 5u +#define me 6u +#define ne 7u +#define oe 8u +#define pe 9u +#define qe 10u +#define fe 11u +#define re 12u +#define se 13u +#define te 14u +#define ue 15u +#define A9 float(2048) +#define sb float(0.00048828125) +#define B9 float(1<<16) +#define G9 (1u<<16) +#define N5 17u +#define f8 0x1ffffu +#define wf float(1024) +#define ha float(0.0009765625) +#define ia 19u +#define i5 (1u<<(ia-1u)) +#define ja ((1u< -// { -// -// float sa; // Offset: 0 -// float Fa; // Offset: 4 -// float bd; // Offset: 8 -// float cd; // Offset: 12 -// uint Ga; // Offset: 16 -// uint id; // Offset: 20 -// uint Oc; // Offset: 24 -// uint Pc; // Offset: 28 -// int4 J6; // Offset: 32 -// float2 U4; // Offset: 48 -// float2 Ha; // Offset: 56 -// uint Z2; // Offset: 64 -// uint d5; // Offset: 68 -// float C1; // Offset: 72 -// uint jd; // Offset: 76 -// -// } q; // Offset: 0 Size: 80 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim HLSL Bind Count -// ------------------------------ ---------- ------- ----------- -------------- ------ -// VB cbuffer NA NA cb0 1 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// AC 0 xyzw 0 NONE uint xyzw -// SV_VertexID 0 x 1 VERTID uint x -// SV_InstanceID 0 x 2 INSTID uint -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// TEXCOORD 0 xyzw 0 NONE float xyzw -// SV_Position 0 xyzw 1 POS float xyzw -// -vs_5_0 -dcl_globalFlags refactoringAllowed -dcl_constantbuffer CB0[1], immediateIndexed -dcl_input v0.xyzw -dcl_input_sgv v1.x, vertex_id -dcl_output o0.xyzw -dcl_output_siv o1.xyzw, position -dcl_temps 2 -ushr r0.x, v1.x, l(1) -ige r0.y, l(1), r0.x -ieq r0.xz, r0.xxxx, l(0, 0, 3, 0) -movc r1.z, r0.y, v0.z, v0.w -ushr r1.xyw, r1.zzzz, l(16, 8, 0, 24) -and r1.xyzw, r1.xyzw, l(255, 255, 255, 255) -utof r1.xyzw, r1.xyzw -mul o0.xyzw, r1.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) -ushr r0.w, v0.x, l(16) -and r1.xyzw, v0.xyyy, l(0x0000ffff, 0x1fffffff, 0x80000000, 0x20000000) -movc r0.y, r0.y, r1.x, r0.w -utof r0.y, r0.y -mad r0.w, r0.y, l(0.000015), l(-0.001953) -mul r0.y, r0.y, l(0.000015) -movc r0.w, r1.w, l(0), r0.w -ine r1.x, r1.z, l(0) -and r0.x, r0.x, r1.x -movc r0.x, r0.x, r0.w, r0.y -add r0.y, r0.x, l(0.001953) -movc r0.y, r1.w, l(1.000000), r0.y -utof r0.w, r1.y -and r1.x, v0.y, l(0x40000000) -ine r1.x, r1.x, l(0) -and r0.z, r0.z, r1.x -movc r0.x, r0.z, r0.y, r0.x -mad o1.x, r0.x, l(2.000000), l(-1.000000) -and r0.x, v1.x, l(1) -movc r0.xy, r0.xxxx, l(1.000000,0,0,0), l(0,1.000000,0,0) -lt r0.z, cb0[0].x, l(0.000000) -movc r0.x, r0.z, r0.y, r0.x -add r0.x, r0.x, r0.w -lt r0.y, l(0.000000), cb0[0].x -iadd r0.y, -r0.y, r0.z -itof r0.y, r0.y -mad o1.y, r0.x, cb0[0].x, -r0.y -mov o1.zw, l(0,0,0,1.000000) -ret -// Approximately 37 instruction slots used -#endif - -const BYTE g_main[] = -{ - 68, 88, 66, 67, 20, 224, - 173, 88, 36, 114, 91, 130, - 108, 185, 74, 215, 95, 3, - 88, 249, 1, 0, 0, 0, - 48, 9, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 200, 2, 0, 0, 64, 3, - 0, 0, 152, 3, 0, 0, - 148, 8, 0, 0, 82, 68, - 69, 70, 140, 2, 0, 0, - 1, 0, 0, 0, 96, 0, - 0, 0, 1, 0, 0, 0, - 60, 0, 0, 0, 0, 5, - 254, 255, 0, 1, 0, 0, - 100, 2, 0, 0, 82, 68, - 49, 49, 60, 0, 0, 0, - 24, 0, 0, 0, 32, 0, - 0, 0, 40, 0, 0, 0, - 36, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 92, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 86, 66, 0, 171, - 92, 0, 0, 0, 1, 0, - 0, 0, 120, 0, 0, 0, - 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 160, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 0, 0, - 2, 0, 0, 0, 64, 2, - 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 113, 0, - 60, 117, 110, 110, 97, 109, - 101, 100, 62, 0, 115, 97, - 0, 102, 108, 111, 97, 116, - 0, 171, 171, 171, 0, 0, - 3, 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 175, 0, 0, 0, 70, 97, - 0, 98, 100, 0, 99, 100, - 0, 71, 97, 0, 100, 119, - 111, 114, 100, 0, 171, 171, - 0, 0, 19, 0, 1, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 232, 0, 0, 0, - 105, 100, 0, 79, 99, 0, - 80, 99, 0, 74, 54, 0, - 105, 110, 116, 52, 0, 171, - 171, 171, 1, 0, 2, 0, - 1, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32, 1, - 0, 0, 85, 52, 0, 102, - 108, 111, 97, 116, 50, 0, - 171, 171, 1, 0, 3, 0, - 1, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 79, 1, - 0, 0, 72, 97, 0, 90, - 50, 0, 100, 53, 0, 67, - 49, 0, 106, 100, 0, 171, - 172, 0, 0, 0, 184, 0, - 0, 0, 0, 0, 0, 0, - 220, 0, 0, 0, 184, 0, - 0, 0, 4, 0, 0, 0, - 223, 0, 0, 0, 184, 0, - 0, 0, 8, 0, 0, 0, - 226, 0, 0, 0, 184, 0, - 0, 0, 12, 0, 0, 0, - 229, 0, 0, 0, 240, 0, - 0, 0, 16, 0, 0, 0, - 20, 1, 0, 0, 240, 0, - 0, 0, 20, 0, 0, 0, - 23, 1, 0, 0, 240, 0, - 0, 0, 24, 0, 0, 0, - 26, 1, 0, 0, 240, 0, - 0, 0, 28, 0, 0, 0, - 29, 1, 0, 0, 40, 1, - 0, 0, 32, 0, 0, 0, - 76, 1, 0, 0, 88, 1, - 0, 0, 48, 0, 0, 0, - 124, 1, 0, 0, 88, 1, - 0, 0, 56, 0, 0, 0, - 127, 1, 0, 0, 240, 0, - 0, 0, 64, 0, 0, 0, - 130, 1, 0, 0, 240, 0, - 0, 0, 68, 0, 0, 0, - 133, 1, 0, 0, 184, 0, - 0, 0, 72, 0, 0, 0, - 136, 1, 0, 0, 240, 0, - 0, 0, 76, 0, 0, 0, - 5, 0, 0, 0, 1, 0, - 20, 0, 0, 0, 15, 0, - 140, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 162, 0, 0, 0, - 77, 105, 99, 114, 111, 115, - 111, 102, 116, 32, 40, 82, - 41, 32, 72, 76, 83, 76, - 32, 83, 104, 97, 100, 101, - 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 49, - 48, 46, 49, 0, 73, 83, - 71, 78, 112, 0, 0, 0, - 3, 0, 0, 0, 8, 0, - 0, 0, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 15, 15, - 0, 0, 83, 0, 0, 0, - 0, 0, 0, 0, 6, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 1, - 0, 0, 95, 0, 0, 0, - 0, 0, 0, 0, 8, 0, - 0, 0, 1, 0, 0, 0, - 2, 0, 0, 0, 1, 0, - 0, 0, 65, 67, 0, 83, - 86, 95, 86, 101, 114, 116, - 101, 120, 73, 68, 0, 83, - 86, 95, 73, 110, 115, 116, - 97, 110, 99, 101, 73, 68, - 0, 171, 171, 171, 79, 83, - 71, 78, 80, 0, 0, 0, - 2, 0, 0, 0, 8, 0, - 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 15, 0, - 0, 0, 65, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 1, 0, 0, 0, 15, 0, - 0, 0, 84, 69, 88, 67, - 79, 79, 82, 68, 0, 83, - 86, 95, 80, 111, 115, 105, - 116, 105, 111, 110, 0, 171, - 171, 171, 83, 72, 69, 88, - 244, 4, 0, 0, 80, 0, - 1, 0, 61, 1, 0, 0, - 106, 8, 0, 1, 89, 0, - 0, 4, 70, 142, 32, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 95, 0, 0, 3, - 242, 16, 16, 0, 0, 0, - 0, 0, 96, 0, 0, 4, - 18, 16, 16, 0, 1, 0, - 0, 0, 6, 0, 0, 0, - 101, 0, 0, 3, 242, 32, - 16, 0, 0, 0, 0, 0, - 103, 0, 0, 4, 242, 32, - 16, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 104, 0, - 0, 2, 2, 0, 0, 0, - 85, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 16, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 1, 0, 0, 0, 33, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 32, 0, 0, 10, - 82, 0, 16, 0, 0, 0, - 0, 0, 6, 0, 16, 0, - 0, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 66, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 42, 16, 16, 0, - 0, 0, 0, 0, 58, 16, - 16, 0, 0, 0, 0, 0, - 85, 0, 0, 10, 178, 0, - 16, 0, 1, 0, 0, 0, - 166, 10, 16, 0, 1, 0, - 0, 0, 2, 64, 0, 0, - 16, 0, 0, 0, 8, 0, - 0, 0, 0, 0, 0, 0, - 24, 0, 0, 0, 1, 0, - 0, 10, 242, 0, 16, 0, - 1, 0, 0, 0, 70, 14, - 16, 0, 1, 0, 0, 0, - 2, 64, 0, 0, 255, 0, - 0, 0, 255, 0, 0, 0, - 255, 0, 0, 0, 255, 0, - 0, 0, 86, 0, 0, 5, - 242, 0, 16, 0, 1, 0, - 0, 0, 70, 14, 16, 0, - 1, 0, 0, 0, 56, 0, - 0, 10, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 14, - 16, 0, 1, 0, 0, 0, - 2, 64, 0, 0, 129, 128, - 128, 59, 129, 128, 128, 59, - 129, 128, 128, 59, 129, 128, - 128, 59, 85, 0, 0, 7, - 130, 0, 16, 0, 0, 0, - 0, 0, 10, 16, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 16, 0, 0, 0, - 1, 0, 0, 10, 242, 0, - 16, 0, 1, 0, 0, 0, - 70, 21, 16, 0, 0, 0, - 0, 0, 2, 64, 0, 0, - 255, 255, 0, 0, 255, 255, - 255, 31, 0, 0, 0, 128, - 0, 0, 0, 32, 55, 0, - 0, 9, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 86, 0, - 0, 5, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 130, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 55, 1, 64, - 0, 0, 0, 0, 0, 187, - 56, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 55, 55, 0, - 0, 9, 130, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 39, 0, - 0, 7, 18, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 55, 0, 0, 9, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 59, 55, 0, - 0, 9, 34, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 26, 0, 16, 0, - 0, 0, 0, 0, 86, 0, - 0, 5, 130, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 1, 0, 0, 0, - 1, 0, 0, 7, 18, 0, - 16, 0, 1, 0, 0, 0, - 26, 16, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 64, 39, 0, - 0, 7, 18, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 7, - 66, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 55, 0, 0, 9, 18, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 18, 32, - 16, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 64, 1, 64, - 0, 0, 0, 0, 128, 191, - 1, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 16, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 1, 0, 0, 0, 55, 0, - 0, 15, 50, 0, 16, 0, - 0, 0, 0, 0, 6, 0, - 16, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, - 0, 8, 66, 0, 16, 0, - 0, 0, 0, 0, 10, 128, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 18, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 49, 0, - 0, 8, 34, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 10, 128, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 30, 0, 0, 8, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 43, 0, 0, 5, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 50, 0, - 0, 11, 34, 32, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 10, 128, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 54, 0, 0, 8, 194, 32, - 16, 0, 1, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 128, 63, 62, 0, 0, 1, - 83, 84, 65, 84, 148, 0, - 0, 0, 37, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 4, 0, 0, 0, - 9, 0, 0, 0, 5, 0, - 0, 0, 9, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 8, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h deleted file mode 100644 index 1747dce86..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h +++ /dev/null @@ -1,2417 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 10.1 -// -// -// Buffer Definitions: -// -// cbuffer VB -// { -// -// struct -// { -// -// float sa; // Offset: 0 -// float Fa; // Offset: 4 -// float bd; // Offset: 8 -// float cd; // Offset: 12 -// uint Ga; // Offset: 16 -// uint id; // Offset: 20 -// uint Oc; // Offset: 24 -// uint Pc; // Offset: 28 -// int4 J6; // Offset: 32 -// float2 U4; // Offset: 48 -// float2 Ha; // Offset: 56 -// uint Z2; // Offset: 64 -// uint d5; // Offset: 68 -// float C1; // Offset: 72 -// uint jd; // Offset: 76 -// -// } q; // Offset: 0 Size: 80 -// -// } -// -// cbuffer Mf -// { -// -// uint ze; // Offset: 0 Size: 4 -// uint PENf; // Offset: 4 Size: 4 [unused] -// uint PEOf; // Offset: 8 Size: 4 [unused] -// uint PEPf; // Offset: 12 Size: 4 [unused] -// -// } -// -// Resource bind info for JB -// { -// -// uint4 $Element; // Offset: 0 Size: 16 -// -// } -// -// Resource bind info for QC -// { -// -// uint4 $Element; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim HLSL Bind Count -// ------------------------------ ---------- ------- ----------- -------------- ------ -// JB texture struct r/o t3 1 -// QC texture struct r/o t6 1 -// BC texture uint4 2d t8 1 -// VB cbuffer NA NA cb0 1 -// Mf cbuffer NA NA cb1 1 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// LB 0 xyzw 0 NONE float xyzw -// MB 0 xyzw 1 NONE float xyz -// SV_VertexID 0 x 2 VERTID uint -// SV_InstanceID 0 x 3 INSTID uint x -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// TEXCOORD 0 xyzw 0 NONE float xyzw -// SV_Position 0 xyzw 1 POS float xyzw -// -vs_5_0 -dcl_globalFlags refactoringAllowed -dcl_constantbuffer CB0[5], immediateIndexed -dcl_constantbuffer CB1[1], immediateIndexed -dcl_resource_structured t3, 16 -dcl_resource_structured t6, 16 -dcl_resource_texture2d (uint,uint,uint,uint) t8 -dcl_input v0.xyzw -dcl_input v1.xyz -dcl_input_sgv v3.x, instance_id -dcl_output o0.xyzw -dcl_output_siv o1.xyzw, position -dcl_temps 14 -iadd r0.x, v3.x, cb1[0].x -ftoi r1.x, v0.x -ishr r0.y, v0.w, l(2) -and r0.z, v0.w, l(3) -iadd r0.w, r0.y, l(-1) -imin r0.w, r0.w, r1.x -imad r0.x, r0.x, r0.y, r0.w -and r2.x, r0.x, l(2047) -ishr r2.y, r0.x, l(11) -mov r2.zw, l(0,0,0,0) -ld_indexable(texture2d)(uint,uint,uint,uint) r2.xyzw, r2.xyzw, t8.xyzw -and r3.xy, r2.wwww, l(0x0000ffff, 0x00800000, 0, 0) -iadd r0.y, r3.x, l(-1) -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r4.xyzw, r0.y, l(0), t6.xyzw -bfi r3.xz, l(16, 0, 16, 0), l(2, 0, 2, 0), r4.zzzz, l(0, 0, 2, 0) -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r5.xyzw, r3.x, l(0), t3.xyzw -iadd r0.y, r3.x, l(1) -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r6.xyzw, r0.y, l(0), t3.xyzw -ftoi r7.x, v1.x -mov r7.yz, v1.yyzy -mov r1.yz, v0.yyzy -movc r1.xyz, r3.yyyy, r7.zxyz, r1.zxyz -ine r0.y, r0.w, r1.y -if_nz r0.y - iadd r0.y, r0.x, r1.y - iadd r0.y, -r0.w, r0.y - and r7.x, r0.y, l(2047) - ishr r7.y, r0.y, l(11) - mov r7.zw, l(0,0,0,0) - ld_indexable(texture2d)(uint,uint,uint,uint) r7.xyzw, r7.xyzw, t8.wxyz - and r0.w, r7.x, l(0x0080ffff) - and r3.x, r2.w, l(0x0080ffff) - ine r0.w, r0.w, r3.x - if_nz r0.w - eq r0.w, r6.z, l(0.000000) - ne r3.x, r4.x, l(0.000000) - or r0.w, r0.w, r3.x - if_nz r0.w - and r8.x, r4.w, l(2047) - ishr r8.y, r4.w, l(11) - mov r8.zw, l(0,0,0,0) - ld_indexable(texture2d)(uint,uint,uint,uint) r7.xyzw, r8.xyzw, t8.wxyz - mov r0.x, r4.w - mov r2.xyz, r7.yzwy - else - mov r7.x, r2.w - endif - else - mov r0.x, r0.y - mov r2.xyz, r7.yzwy - endif - and r0.y, r7.x, l(0xff7fffff) - iadd r2.w, r3.y, r0.y -endif -and r0.y, r2.w, l(0x1c000000) -ieq r0.w, r0.y, l(0x04000000) -ieq r3.x, r0.z, l(0) -and r0.w, r0.w, r3.x -if_nz r0.w - and r3.x, r2.z, l(0x0000ffff) - utof r7.z, r3.x - ushr r3.x, r2.z, l(16) - utof r3.x, r3.x - add r3.y, -r7.z, l(-1.000000) - add r3.w, -r7.z, r3.x - add r3.w, r3.w, l(1.000000) - ftoi r8.xy, r3.ywyy - and r3.y, r2.w, l(0x00800000) - ineg r8.zw, r8.xxxy - movc r3.yw, r3.yyyy, r8.zzzw, r8.xxxy - iadd r3.yw, r0.xxxx, r3.yyyw - and r8.xy, r3.ywyy, l(2047, 2047, 0, 0) - ishr r9.xy, r3.ywyy, l(11, 11, 0, 0) - mov r8.z, r9.x - mov r8.w, l(0) - ld_indexable(texture2d)(uint,uint,uint,uint) r3.yw, r8.xzww, t8.xzyw - mov r9.zw, r8.yyyw - ld_indexable(texture2d)(uint,uint,uint,uint) r8.xy, r9.zyww, t8.zwxy - and r4.z, r8.y, l(0x0080ffff) - and r3.w, r3.w, l(0x0080ffff) - ine r3.w, r3.w, r4.z - if_nz r3.w - and r9.x, r4.w, l(2047) - ishr r9.y, r4.w, l(11) - mov r9.zw, l(0,0,0,0) - ld_indexable(texture2d)(uint,uint,uint,uint) r8.x, r9.xyzw, t8.zwxy - endif - add r3.w, -r3.y, r8.x - lt r4.z, l(3.141593), |r3.w| - lt r4.w, l(0.000000), r3.w - lt r8.y, r3.w, l(0.000000) - iadd r4.w, -r4.w, r8.y - itof r4.w, r4.w - mad r4.w, -r4.w, l(6.283185), r3.w - movc r9.y, r4.z, r4.w, r3.w - add r3.xw, r3.xxxx, l(-2.000000, 0.000000, 0.000000, -3.000000) - mul r4.z, r3.x, |r9.y| - mul r4.z, r4.z, l(0.318310) - round_ne r4.z, r4.z - max r4.z, r4.z, l(1.000000) - min r10.w, r3.w, r4.z - add r7.w, r3.x, -r10.w - ge r3.x, r7.w, r7.z - lt r3.w, l(0.000000), r9.y - lt r4.z, r9.y, l(0.000000) - iadd r3.w, -r3.w, r4.z - itof r3.w, r3.w - mad r3.w, r3.w, l(3.141593), -r9.y - mov r7.y, -r3.w - eq r3.w, r7.w, r7.z - movc r7.x, r3.w, -r1.z, r1.z - add r4.zw, r7.wwww, l(0.000000, 0.000000, 1.000000, 2.000000) - eq r3.w, r4.z, r7.z - add r10.z, -r4.w, r7.z - mov r10.x, r1.z - movc r9.xzw, r3.wwww, l(0,0,0,0), r10.xxzw - movc r7.xyzw, r3.xxxx, r7.xyzw, r9.xyzw - eq r3.x, r7.w, r7.z - div r3.w, r7.z, r7.w - mad r3.w, r7.y, r3.w, r3.y - movc r2.z, r3.x, r8.x, r3.w - mov r3.x, r7.x - mov r7.x, r3.y -else - mov r3.x, r1.z -endif -sincos r8.x, r9.x, r2.z -mov r8.y, -r9.x -ne r3.yw, r6.wwwz, l(0.000000, 0.000000, 0.000000, 0.000000) -dp2 r9.x, r8.xyxx, r5.xzxx -dp2 r9.y, r8.xyxx, r5.ywyy -dp2 r4.z, r9.xyxx, r9.xyxx -sqrt r4.w, r4.z -div r4.w, l(1.000000, 1.000000, 1.000000, 1.000000), r4.w -max r4.w, r4.w, r6.w -movc r3.y, r3.y, r4.w, r6.w -if_nz r3.w - mul r3.w, r5.z, r5.y - mad r3.w, r5.x, r5.w, -r3.w - lt r4.w, l(0.000000), r3.w - lt r3.w, r3.w, l(0.000000) - iadd r3.w, -r4.w, r3.w - itof r3.w, r3.w - mul r3.w, r3.w, r3.x - and r7.zw, r2.wwww, l(0, 0, 0x00100000, 0x00080000) - min r4.w, r3.w, l(0.000000) - movc r3.w, r7.z, r4.w, r3.w - max r4.w, r3.w, l(0.000000) - movc r3.w, r7.w, r4.w, r3.w - ne r4.w, r3.y, l(0.000000) - add r6.w, |r9.y|, |r9.x| - div r4.z, l(1.000000, 1.000000, 1.000000, 1.000000), r4.z - mul r4.z, r4.z, r6.w - mul r4.z, r4.z, l(0.500000) - movc r9.x, r4.w, r3.y, r4.z - lt r4.z, r6.z, r9.x - eq r6.w, r3.y, l(0.000000) - and r4.z, r4.z, r6.w - div r9.y, r6.z, r9.x - mov r10.x, r6.z - mov r10.y, l(1.000000) - movc r6.zw, r4.zzzz, r9.xxxy, r10.xxxy - add r4.z, r9.x, r6.z - mul r8.zw, r4.zzzz, r8.xxxy - mul r10.x, r3.w, r4.z - add r7.w, r9.x, r9.x - div r7.w, l(1.000000, 1.000000, 1.000000, 1.000000), r7.w - mov r10.y, -r10.x - add r9.yz, r6.zzzz, r10.xxyx - mad r9.yz, r7.wwww, r9.yyzy, l(0.000000, 0.500000, 0.500000, 0.000000) - ult r7.w, l(0x08000000), r0.y - if_nz r7.w - and r10.xyzw, r2.wwww, l(0x00400000, 0x00800000, 0x02000000, 0x00200000) - movc r11.xyz, r10.xxzx, l(2,-2,1.000000,0), l(-2,2,0.250000,0) - movc r7.w, r10.y, r11.y, r11.x - iadd r0.x, r0.x, r7.w - and r12.x, r0.x, l(2047) - ishr r12.y, r0.x, l(11) - mov r12.zw, l(0,0,0,0) - ld_indexable(texture2d)(uint,uint,uint,uint) r0.x, r12.xyzw, t8.zxyw - add r0.x, -r2.z, r0.x - lt r7.w, l(3.141593), |r0.x| - add r10.y, -|r0.x|, l(6.283185) - movc r0.x, r7.w, r10.y, |r0.x| - ine r7.w, r10.x, l(0) - ine r10.x, r7.z, l(0) - ieq r7.w, r7.w, r10.x - movc r7.w, r7.w, l(-0.500000), l(0.500000) - mad r7.w, r0.x, r7.w, r2.z - sincos r10.x, r11.x, r7.w - mov r10.y, -r11.x - dp2 r11.x, r10.xyxx, r5.xzxx - dp2 r11.y, r10.xyxx, r5.ywyy - add r7.w, |r11.y|, |r11.x| - dp2 r10.z, r11.xyxx, r11.xyxx - div r10.z, l(1.000000, 1.000000, 1.000000, 1.000000), r10.z - mul r7.w, r7.w, r10.z - mul r0.x, r0.x, l(0.500000) - sincos null, r0.x, r0.x - ieq r11.xy, r0.yyyy, l(0x14000000, 0x10000000, 0, 0) - ge r0.y, r0.x, l(0.250000) - and r0.y, r0.y, r11.y - or r0.y, r0.y, r11.x - max r10.z, r11.z, r0.x - div r10.z, l(1.000000, 1.000000, 1.000000, 1.000000), r10.z - mul r10.z, r6.z, r10.z - mul r11.x, r7.w, l(0.500000) - mad r6.z, r6.z, r0.x, r11.x - movc r0.y, r0.y, r10.z, r6.z - mad r0.y, r7.w, l(0.500000), r0.y - mul r6.z, r9.x, l(0.125000) - mad r6.z, r0.y, r0.x, r6.z - ge r6.z, r6.z, r4.z - div r0.x, l(1.000000, 1.000000, 1.000000, 1.000000), r0.x - mul r0.x, r0.x, r4.z - mul r11.xyzw, r0.xxyy, r10.xyyx - dp2 r12.x, r8.zwzz, r8.zwzz - dp2 r12.y, r11.zwzz, r11.zwzz - mul r0.x, r8.w, r11.w - mad r0.x, r8.z, r11.z, -r0.x - div r0.x, l(1.000000, 1.000000, 1.000000, 1.000000), r0.x - mul r13.xz, r11.zzwz, l(1.000000, 0.000000, -1.000000, 0.000000) - mul r13.yw, r8.wwwz, l(0.000000, -1.000000, 0.000000, 1.000000) - mul r13.xyzw, r0.xxxx, r13.xyzw - dp2 r13.x, r13.xyxx, r12.xyxx - dp2 r13.y, r13.zwzz, r12.xyxx - movc r11.xy, r6.zzzz, r11.xyxx, r13.xyxx - movc r8.zw, r10.wwww, r11.xxxy, r8.zzzw - mul r10.zw, |r3.wwww|, r8.zzzw - dp2 r0.x, r10.zwzz, r10.xyxx - add r0.x, -r0.x, r0.y - div r9.w, r0.x, r7.w - movc r9.yz, r7.zzzz, r9.yywy, r9.wwzw - endif - mul r0.xy, r6.wwww, r9.yzyy - max r1.y, r0.y, l(0.000100) - mad r0.y, -r9.y, r6.w, l(-2.000000) - movc r1.x, r4.w, r0.y, r0.x - mul r0.xy, r3.wwww, r8.zwzz - dp2 r9.x, r0.xyxx, r5.xzxx - dp2 r9.y, r0.xyxx, r5.ywyy - ine r0.x, r0.z, l(0) - mov o0.zw, l(0,0,0,0) -else - ne r0.y, r3.y, l(0.000000) - if_nz r0.y - lt r0.y, r7.y, l(0.000000) - add r10.x, r7.y, r7.x - mov r10.y, -r7.y - movc r4.zw, r0.yyyy, r10.xxxy, r7.xxxy - add r0.y, r2.z, -r4.z - add r0.y, r0.y, l(1.570796) - mul r0.y, r0.y, l(0.159155) - ge r2.z, r0.y, -r0.y - frc r0.y, |r0.y| - movc r0.y, r2.z, r0.y, -r0.y - mad r0.y, r0.y, l(6.283185), l(-1.570796) - max r0.y, r0.y, l(0.000000) - min r0.y, r4.w, r0.y - mul r2.z, r4.w, l(0.500000) - lt r2.z, r2.z, r0.y - add r3.w, -r0.y, r4.w - movc r0.y, r2.z, r3.w, r0.y - sincos r7.x, r10.x, r0.y - mov r7.y, r10.x - mad r6.zw, -r7.xxxy, |r3.xxxx|, l(0.000000, 0.000000, 1.000000, 1.000000) - mul r7.xy, r6.zwzz, l(0.500000, 0.500000, 0.000000, 0.000000) - add r0.y, r4.w, l(-1.570796) - lt r0.y, |r0.y|, l(0.001000) - sincos r10.x, r11.x, r4.w - div r2.z, r10.x, r11.x - add r3.w, -r4.w, l(1.570796) - lt r4.z, l(0.000000), r3.w - lt r3.w, r3.w, l(0.000000) - iadd r3.w, -r4.z, r3.w - itof r3.w, r3.w - max r4.z, |r2.z|, l(0.000001) - div r4.z, r3.w, r4.z - ge r3.w, r4.z, l(0.000000) - mad r10.xy, -r6.zwzz, l(0.500000, 0.500000, 0.000000, 0.000000), l(1.000000, -2.000000, 0.000000, 0.000000) - mad r6.z, -r10.x, r2.z, r7.y - mad r2.z, r7.x, r2.z, r7.y - movc r4.w, r3.w, r6.z, r2.z - movc r10.zw, r0.yyyy, l(0,0,0,0), r4.zzzw - max r0.y, r7.x, l(0.000000) - add r10.x, r0.y, l(0.250000) - mov r7.xw, r1.xxxx - mov r7.yz, l(0,-2.000000,1000000.000000,0) - movc r1.xyzw, r0.wwww, r10.xyzw, r7.xyzw - mul r0.y, r3.y, r3.x - mul r0.yw, r8.xxxy, r0.yyyy - dp2 r9.x, r0.ywyy, r5.xzxx - dp2 r9.y, r0.ywyy, r5.ywyy - mov o0.zw, r1.zzzw - else - mul r0.y, r5.z, r5.y - mad r0.y, r5.x, r5.w, -r0.y - div r0.y, l(1.000000, 1.000000, 1.000000, 1.000000), r0.y - mul r7.xyzw, r5.wyzx, l(1.000000, -1.000000, -1.000000, 1.000000) - mul r7.xyzw, r0.yyyy, r7.xyzw - mul r0.yw, r3.xxxx, r8.xxxy - dp2 r3.x, r7.xyxx, r0.ywyy - dp2 r3.y, r7.zwzz, r0.ywyy - lt r0.yw, l(0.000000, 0.000000, 0.000000, 0.000000), r3.xxxy - lt r1.zw, r3.xxxy, l(0.000000, 0.000000, 0.000000, 0.000000) - iadd r0.yw, -r0.yyyw, r1.zzzw - itof r0.yw, r0.yyyw - mul r9.xy, r0.ywyy, l(0.500000, 0.500000, 0.000000, 0.000000) - mov o0.zw, l(0,0,0,0) - mov r1.y, l(-1.000000) - endif - and r3.xyw, r2.wwww, l(0x00800000, 0x01000000, 0, 0x80000000) - ine r3.xyw, r3.xyxw, l(0, 0, 0, 0) - ine r0.y, r3.y, r3.x - movc r1.x, r0.y, -r1.x, r1.x - ieq r0.y, r0.z, l(2) - movc r2.xy, r0.yyyy, r4.xyxx, r2.xyxx - ine r0.y, r0.z, l(1) - and r0.x, r0.y, r3.w -endif -dp2 r3.x, r2.xyxx, r5.xzxx -dp2 r3.y, r2.xyxx, r5.ywyy -add r0.yz, r9.xxyx, r3.xxyx -add r0.yz, r6.xxyx, r0.yyzy -movc r0.w, cb0[4].w, l(1.000000), l(0) -add r1.zw, -r1.xxxy, l(0.000000, 0.000000, 1.000000, -1.000000) -mad r1.zw, r0.wwww, r1.zzzw, r1.xxxy -movc o0.xy, r0.xxxx, r1.xyxx, r1.zwzz -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r1.xyz, r3.z, l(4), t3.xyzx -mad r0.yz, r0.yyzy, r1.xxxx, r1.yyzy -mad r1.x, r0.y, cb0[3].z, l(-1.000000) -lt r0.y, l(0.000000), cb0[3].w -lt r0.w, cb0[3].w, l(0.000000) -iadd r0.y, -r0.y, r0.w -itof r0.y, r0.y -mad r1.y, r0.z, cb0[3].w, -r0.y -mov r1.zw, l(0,0,0,1.000000) -movc o1.xyzw, r0.xxxx, cb0[4].zzzz, r1.xyzw -ret -// Approximately 339 instruction slots used -#endif - -const BYTE g_main[] = -{ - 68, 88, 66, 67, 127, 48, - 214, 0, 182, 194, 196, 84, - 216, 209, 78, 226, 108, 71, - 10, 252, 1, 0, 0, 0, - 56, 46, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 248, 4, 0, 0, 136, 5, - 0, 0, 224, 5, 0, 0, - 156, 45, 0, 0, 82, 68, - 69, 70, 188, 4, 0, 0, - 4, 0, 0, 0, 236, 0, - 0, 0, 5, 0, 0, 0, - 60, 0, 0, 0, 0, 5, - 254, 255, 0, 1, 0, 0, - 148, 4, 0, 0, 82, 68, - 49, 49, 60, 0, 0, 0, - 24, 0, 0, 0, 32, 0, - 0, 0, 40, 0, 0, 0, - 36, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 220, 0, 0, 0, 5, 0, - 0, 0, 6, 0, 0, 0, - 1, 0, 0, 0, 16, 0, - 0, 0, 3, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 223, 0, 0, 0, - 5, 0, 0, 0, 6, 0, - 0, 0, 1, 0, 0, 0, - 16, 0, 0, 0, 6, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 226, 0, - 0, 0, 2, 0, 0, 0, - 4, 0, 0, 0, 4, 0, - 0, 0, 255, 255, 255, 255, - 8, 0, 0, 0, 1, 0, - 0, 0, 13, 0, 0, 0, - 229, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 232, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 74, 66, - 0, 81, 67, 0, 66, 67, - 0, 86, 66, 0, 77, 102, - 0, 171, 229, 0, 0, 0, - 1, 0, 0, 0, 76, 1, - 0, 0, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 232, 0, 0, 0, - 4, 0, 0, 0, 56, 3, - 0, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 220, 0, 0, 0, - 1, 0, 0, 0, 16, 4, - 0, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 223, 0, 0, 0, - 1, 0, 0, 0, 108, 4, - 0, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 116, 1, 0, 0, - 0, 0, 0, 0, 80, 0, - 0, 0, 2, 0, 0, 0, - 20, 3, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 113, 0, 60, 117, 110, 110, - 97, 109, 101, 100, 62, 0, - 115, 97, 0, 102, 108, 111, - 97, 116, 0, 171, 171, 171, - 0, 0, 3, 0, 1, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 131, 1, 0, 0, - 70, 97, 0, 98, 100, 0, - 99, 100, 0, 71, 97, 0, - 100, 119, 111, 114, 100, 0, - 171, 171, 0, 0, 19, 0, - 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 188, 1, - 0, 0, 105, 100, 0, 79, - 99, 0, 80, 99, 0, 74, - 54, 0, 105, 110, 116, 52, - 0, 171, 171, 171, 1, 0, - 2, 0, 1, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 244, 1, 0, 0, 85, 52, - 0, 102, 108, 111, 97, 116, - 50, 0, 171, 171, 1, 0, - 3, 0, 1, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 35, 2, 0, 0, 72, 97, - 0, 90, 50, 0, 100, 53, - 0, 67, 49, 0, 106, 100, - 0, 171, 128, 1, 0, 0, - 140, 1, 0, 0, 0, 0, - 0, 0, 176, 1, 0, 0, - 140, 1, 0, 0, 4, 0, - 0, 0, 179, 1, 0, 0, - 140, 1, 0, 0, 8, 0, - 0, 0, 182, 1, 0, 0, - 140, 1, 0, 0, 12, 0, - 0, 0, 185, 1, 0, 0, - 196, 1, 0, 0, 16, 0, - 0, 0, 232, 1, 0, 0, - 196, 1, 0, 0, 20, 0, - 0, 0, 235, 1, 0, 0, - 196, 1, 0, 0, 24, 0, - 0, 0, 238, 1, 0, 0, - 196, 1, 0, 0, 28, 0, - 0, 0, 241, 1, 0, 0, - 252, 1, 0, 0, 32, 0, - 0, 0, 32, 2, 0, 0, - 44, 2, 0, 0, 48, 0, - 0, 0, 80, 2, 0, 0, - 44, 2, 0, 0, 56, 0, - 0, 0, 83, 2, 0, 0, - 196, 1, 0, 0, 64, 0, - 0, 0, 86, 2, 0, 0, - 196, 1, 0, 0, 68, 0, - 0, 0, 89, 2, 0, 0, - 140, 1, 0, 0, 72, 0, - 0, 0, 92, 2, 0, 0, - 196, 1, 0, 0, 76, 0, - 0, 0, 5, 0, 0, 0, - 1, 0, 20, 0, 0, 0, - 15, 0, 96, 2, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 118, 1, - 0, 0, 216, 3, 0, 0, - 0, 0, 0, 0, 4, 0, - 0, 0, 2, 0, 0, 0, - 220, 3, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 0, 4, 0, 0, 4, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 220, 3, - 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 5, 4, - 0, 0, 8, 0, 0, 0, - 4, 0, 0, 0, 0, 0, - 0, 0, 220, 3, 0, 0, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 10, 4, 0, 0, - 12, 0, 0, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 220, 3, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 122, 101, 0, 171, 0, 0, - 19, 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 188, 1, 0, 0, 80, 69, - 78, 102, 0, 80, 69, 79, - 102, 0, 80, 69, 80, 102, - 0, 171, 56, 4, 0, 0, - 0, 0, 0, 0, 16, 0, - 0, 0, 2, 0, 0, 0, - 72, 4, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 36, 69, 108, 101, 109, 101, - 110, 116, 0, 117, 105, 110, - 116, 52, 0, 171, 1, 0, - 19, 0, 1, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 65, 4, 0, 0, 56, 4, - 0, 0, 0, 0, 0, 0, - 16, 0, 0, 0, 2, 0, - 0, 0, 72, 4, 0, 0, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 77, 105, 99, 114, - 111, 115, 111, 102, 116, 32, - 40, 82, 41, 32, 72, 76, - 83, 76, 32, 83, 104, 97, - 100, 101, 114, 32, 67, 111, - 109, 112, 105, 108, 101, 114, - 32, 49, 48, 46, 49, 0, - 73, 83, 71, 78, 136, 0, - 0, 0, 4, 0, 0, 0, - 8, 0, 0, 0, 104, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 15, 15, 0, 0, 107, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 7, 0, 0, 110, 0, - 0, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 1, 0, - 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 122, 0, - 0, 0, 0, 0, 0, 0, - 8, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 1, 1, 0, 0, 76, 66, - 0, 77, 66, 0, 83, 86, - 95, 86, 101, 114, 116, 101, - 120, 73, 68, 0, 83, 86, - 95, 73, 110, 115, 116, 97, - 110, 99, 101, 73, 68, 0, - 79, 83, 71, 78, 80, 0, - 0, 0, 2, 0, 0, 0, - 8, 0, 0, 0, 56, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 15, 0, 0, 0, 65, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 0, 0, 0, 84, 69, - 88, 67, 79, 79, 82, 68, - 0, 83, 86, 95, 80, 111, - 115, 105, 116, 105, 111, 110, - 0, 171, 171, 171, 83, 72, - 69, 88, 180, 39, 0, 0, - 80, 0, 1, 0, 237, 9, - 0, 0, 106, 8, 0, 1, - 89, 0, 0, 4, 70, 142, - 32, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 89, 0, - 0, 4, 70, 142, 32, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 162, 0, 0, 4, - 0, 112, 16, 0, 3, 0, - 0, 0, 16, 0, 0, 0, - 162, 0, 0, 4, 0, 112, - 16, 0, 6, 0, 0, 0, - 16, 0, 0, 0, 88, 24, - 0, 4, 0, 112, 16, 0, - 8, 0, 0, 0, 68, 68, - 0, 0, 95, 0, 0, 3, - 242, 16, 16, 0, 0, 0, - 0, 0, 95, 0, 0, 3, - 114, 16, 16, 0, 1, 0, - 0, 0, 96, 0, 0, 4, - 18, 16, 16, 0, 3, 0, - 0, 0, 8, 0, 0, 0, - 101, 0, 0, 3, 242, 32, - 16, 0, 0, 0, 0, 0, - 103, 0, 0, 4, 242, 32, - 16, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 104, 0, - 0, 2, 14, 0, 0, 0, - 30, 0, 0, 8, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 16, 16, 0, 3, 0, - 0, 0, 10, 128, 32, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 27, 0, 0, 5, - 18, 0, 16, 0, 1, 0, - 0, 0, 10, 16, 16, 0, - 0, 0, 0, 0, 42, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 58, 16, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 2, 0, - 0, 0, 1, 0, 0, 7, - 66, 0, 16, 0, 0, 0, - 0, 0, 58, 16, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 3, 0, 0, 0, - 30, 0, 0, 7, 130, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 255, 255, 255, 255, 37, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 35, 0, 0, 9, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 0, 0, - 0, 0, 1, 0, 0, 7, - 18, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 255, 7, 0, 0, - 42, 0, 0, 7, 34, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 11, 0, 0, 0, 54, 0, - 0, 8, 194, 0, 16, 0, - 2, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 45, 0, 0, 137, 194, 0, - 0, 128, 3, 17, 17, 0, - 242, 0, 16, 0, 2, 0, - 0, 0, 70, 14, 16, 0, - 2, 0, 0, 0, 70, 126, - 16, 0, 8, 0, 0, 0, - 1, 0, 0, 10, 50, 0, - 16, 0, 3, 0, 0, 0, - 246, 15, 16, 0, 2, 0, - 0, 0, 2, 64, 0, 0, - 255, 255, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 30, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 255, 255, - 255, 255, 167, 0, 0, 139, - 2, 131, 0, 128, 131, 153, - 25, 0, 242, 0, 16, 0, - 4, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 70, 126, 16, 0, - 6, 0, 0, 0, 140, 0, - 0, 20, 82, 0, 16, 0, - 3, 0, 0, 0, 2, 64, - 0, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 16, 0, - 0, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 166, 10, 16, 0, - 4, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 167, 0, 0, 139, 2, 131, - 0, 128, 131, 153, 25, 0, - 242, 0, 16, 0, 5, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 70, 126, 16, 0, 3, 0, - 0, 0, 30, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 1, 0, 0, 0, - 167, 0, 0, 139, 2, 131, - 0, 128, 131, 153, 25, 0, - 242, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 70, 126, 16, 0, 3, 0, - 0, 0, 27, 0, 0, 5, - 18, 0, 16, 0, 7, 0, - 0, 0, 10, 16, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 98, 0, 16, 0, - 7, 0, 0, 0, 86, 22, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 98, 0, - 16, 0, 1, 0, 0, 0, - 86, 22, 16, 0, 0, 0, - 0, 0, 55, 0, 0, 9, - 114, 0, 16, 0, 1, 0, - 0, 0, 86, 5, 16, 0, - 3, 0, 0, 0, 38, 9, - 16, 0, 7, 0, 0, 0, - 38, 9, 16, 0, 1, 0, - 0, 0, 39, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 1, 0, 0, 0, - 31, 0, 4, 3, 26, 0, - 16, 0, 0, 0, 0, 0, - 30, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 30, 0, - 0, 8, 34, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 1, 0, 0, 7, 18, 0, - 16, 0, 7, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 255, 7, 0, 0, 42, 0, - 0, 7, 34, 0, 16, 0, - 7, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 11, 0, - 0, 0, 54, 0, 0, 8, - 194, 0, 16, 0, 7, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 45, 0, - 0, 137, 194, 0, 0, 128, - 3, 17, 17, 0, 242, 0, - 16, 0, 7, 0, 0, 0, - 70, 14, 16, 0, 7, 0, - 0, 0, 54, 121, 16, 0, - 8, 0, 0, 0, 1, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 7, 0, 0, 0, - 1, 64, 0, 0, 255, 255, - 128, 0, 1, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 255, 255, 128, 0, - 39, 0, 0, 7, 130, 0, - 16, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 31, 0, - 4, 3, 58, 0, 16, 0, - 0, 0, 0, 0, 24, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 6, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 57, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 60, 0, 0, 7, 130, 0, - 16, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 31, 0, - 4, 3, 58, 0, 16, 0, - 0, 0, 0, 0, 1, 0, - 0, 7, 18, 0, 16, 0, - 8, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 255, 7, - 0, 0, 42, 0, 0, 7, - 34, 0, 16, 0, 8, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 11, 0, 0, 0, - 54, 0, 0, 8, 194, 0, - 16, 0, 8, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 45, 0, 0, 137, - 194, 0, 0, 128, 3, 17, - 17, 0, 242, 0, 16, 0, - 7, 0, 0, 0, 70, 14, - 16, 0, 8, 0, 0, 0, - 54, 121, 16, 0, 8, 0, - 0, 0, 54, 0, 0, 5, - 18, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 54, 0, - 0, 5, 114, 0, 16, 0, - 2, 0, 0, 0, 150, 7, - 16, 0, 7, 0, 0, 0, - 18, 0, 0, 1, 54, 0, - 0, 5, 18, 0, 16, 0, - 7, 0, 0, 0, 58, 0, - 16, 0, 2, 0, 0, 0, - 21, 0, 0, 1, 18, 0, - 0, 1, 54, 0, 0, 5, - 18, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 114, 0, 16, 0, - 2, 0, 0, 0, 150, 7, - 16, 0, 7, 0, 0, 0, - 21, 0, 0, 1, 1, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 7, 0, 0, 0, - 1, 64, 0, 0, 255, 255, - 127, 255, 30, 0, 0, 7, - 130, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 21, 0, 0, 1, 1, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 28, 32, 0, 0, 7, - 130, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 4, - 32, 0, 0, 7, 18, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 31, 0, 4, 3, - 58, 0, 16, 0, 0, 0, - 0, 0, 1, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 255, 255, 0, 0, - 86, 0, 0, 5, 66, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 85, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 16, 0, 0, 0, - 86, 0, 0, 5, 18, 0, - 16, 0, 3, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 0, 0, 0, 8, - 34, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 128, - 65, 0, 0, 0, 7, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 191, 0, 0, - 0, 8, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 7, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 0, 0, 0, 7, 130, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 27, 0, - 0, 5, 50, 0, 16, 0, - 8, 0, 0, 0, 214, 5, - 16, 0, 3, 0, 0, 0, - 1, 0, 0, 7, 34, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 0, 40, 0, - 0, 5, 194, 0, 16, 0, - 8, 0, 0, 0, 6, 4, - 16, 0, 8, 0, 0, 0, - 55, 0, 0, 9, 162, 0, - 16, 0, 3, 0, 0, 0, - 86, 5, 16, 0, 3, 0, - 0, 0, 166, 14, 16, 0, - 8, 0, 0, 0, 6, 4, - 16, 0, 8, 0, 0, 0, - 30, 0, 0, 7, 162, 0, - 16, 0, 3, 0, 0, 0, - 6, 0, 16, 0, 0, 0, - 0, 0, 86, 13, 16, 0, - 3, 0, 0, 0, 1, 0, - 0, 10, 50, 0, 16, 0, - 8, 0, 0, 0, 214, 5, - 16, 0, 3, 0, 0, 0, - 2, 64, 0, 0, 255, 7, - 0, 0, 255, 7, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 42, 0, 0, 10, - 50, 0, 16, 0, 9, 0, - 0, 0, 214, 5, 16, 0, - 3, 0, 0, 0, 2, 64, - 0, 0, 11, 0, 0, 0, - 11, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 66, 0, - 16, 0, 8, 0, 0, 0, - 10, 0, 16, 0, 9, 0, - 0, 0, 54, 0, 0, 5, - 130, 0, 16, 0, 8, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 45, 0, - 0, 137, 194, 0, 0, 128, - 3, 17, 17, 0, 162, 0, - 16, 0, 3, 0, 0, 0, - 134, 15, 16, 0, 8, 0, - 0, 0, 134, 125, 16, 0, - 8, 0, 0, 0, 54, 0, - 0, 5, 194, 0, 16, 0, - 9, 0, 0, 0, 86, 13, - 16, 0, 8, 0, 0, 0, - 45, 0, 0, 137, 194, 0, - 0, 128, 3, 17, 17, 0, - 50, 0, 16, 0, 8, 0, - 0, 0, 102, 15, 16, 0, - 9, 0, 0, 0, 230, 116, - 16, 0, 8, 0, 0, 0, - 1, 0, 0, 7, 66, 0, - 16, 0, 4, 0, 0, 0, - 26, 0, 16, 0, 8, 0, - 0, 0, 1, 64, 0, 0, - 255, 255, 128, 0, 1, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 255, 255, - 128, 0, 39, 0, 0, 7, - 130, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 31, 0, 4, 3, 58, 0, - 16, 0, 3, 0, 0, 0, - 1, 0, 0, 7, 18, 0, - 16, 0, 9, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 255, 7, 0, 0, 42, 0, - 0, 7, 34, 0, 16, 0, - 9, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 11, 0, - 0, 0, 54, 0, 0, 8, - 194, 0, 16, 0, 9, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 45, 0, - 0, 137, 194, 0, 0, 128, - 3, 17, 17, 0, 18, 0, - 16, 0, 8, 0, 0, 0, - 70, 14, 16, 0, 9, 0, - 0, 0, 230, 116, 16, 0, - 8, 0, 0, 0, 21, 0, - 0, 1, 0, 0, 0, 8, - 130, 0, 16, 0, 3, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 8, 0, 0, 0, 49, 0, - 0, 8, 66, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 219, 15, 73, 64, - 58, 0, 16, 128, 129, 0, - 0, 0, 3, 0, 0, 0, - 49, 0, 0, 7, 130, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 49, 0, - 0, 7, 34, 0, 16, 0, - 8, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 30, 0, 0, 8, - 130, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 26, 0, 16, 0, - 8, 0, 0, 0, 43, 0, - 0, 5, 130, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 50, 0, 0, 10, 130, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 128, 65, 0, - 0, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 219, 15, - 201, 64, 58, 0, 16, 0, - 3, 0, 0, 0, 55, 0, - 0, 9, 34, 0, 16, 0, - 9, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 0, 0, - 0, 10, 146, 0, 16, 0, - 3, 0, 0, 0, 6, 0, - 16, 0, 3, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 192, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 64, 192, 56, 0, 0, 8, - 66, 0, 16, 0, 4, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 128, 129, 0, 0, 0, - 9, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 131, 249, - 162, 62, 64, 0, 0, 5, - 66, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 52, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 51, 0, 0, 7, - 130, 0, 16, 0, 10, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 0, 0, 0, 8, 130, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 10, 0, - 0, 0, 29, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 42, 0, - 16, 0, 7, 0, 0, 0, - 49, 0, 0, 7, 130, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 9, 0, 0, 0, 49, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 26, 0, - 16, 0, 9, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 30, 0, 0, 8, - 130, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 43, 0, - 0, 5, 130, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 50, 0, 0, 10, 130, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 219, 15, 73, 64, 26, 0, - 16, 128, 65, 0, 0, 0, - 9, 0, 0, 0, 54, 0, - 0, 6, 34, 0, 16, 0, - 7, 0, 0, 0, 58, 0, - 16, 128, 65, 0, 0, 0, - 3, 0, 0, 0, 24, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 7, 0, 0, 0, - 42, 0, 16, 0, 7, 0, - 0, 0, 55, 0, 0, 10, - 18, 0, 16, 0, 7, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 0, 0, 0, 10, 194, 0, - 16, 0, 4, 0, 0, 0, - 246, 15, 16, 0, 7, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 128, 63, - 0, 0, 0, 64, 24, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 7, 0, - 0, 0, 0, 0, 0, 8, - 66, 0, 16, 0, 10, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 7, 0, 0, 0, 54, 0, - 0, 5, 18, 0, 16, 0, - 10, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 55, 0, 0, 12, 210, 0, - 16, 0, 9, 0, 0, 0, - 246, 15, 16, 0, 3, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 14, - 16, 0, 10, 0, 0, 0, - 55, 0, 0, 9, 242, 0, - 16, 0, 7, 0, 0, 0, - 6, 0, 16, 0, 3, 0, - 0, 0, 70, 14, 16, 0, - 7, 0, 0, 0, 70, 14, - 16, 0, 9, 0, 0, 0, - 24, 0, 0, 7, 18, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 7, 0, - 0, 0, 42, 0, 16, 0, - 7, 0, 0, 0, 14, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 7, 0, 0, 0, - 58, 0, 16, 0, 7, 0, - 0, 0, 50, 0, 0, 9, - 130, 0, 16, 0, 3, 0, - 0, 0, 26, 0, 16, 0, - 7, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 26, 0, 16, 0, 3, 0, - 0, 0, 55, 0, 0, 9, - 66, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 0, 8, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 54, 0, 0, 5, - 18, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 7, 0, 0, 0, 54, 0, - 0, 5, 18, 0, 16, 0, - 7, 0, 0, 0, 26, 0, - 16, 0, 3, 0, 0, 0, - 18, 0, 0, 1, 54, 0, - 0, 5, 18, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 21, 0, 0, 1, 77, 0, - 0, 7, 18, 0, 16, 0, - 8, 0, 0, 0, 18, 0, - 16, 0, 9, 0, 0, 0, - 42, 0, 16, 0, 2, 0, - 0, 0, 54, 0, 0, 6, - 34, 0, 16, 0, 8, 0, - 0, 0, 10, 0, 16, 128, - 65, 0, 0, 0, 9, 0, - 0, 0, 57, 0, 0, 10, - 162, 0, 16, 0, 3, 0, - 0, 0, 246, 11, 16, 0, - 6, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 9, 0, 0, 0, - 70, 0, 16, 0, 8, 0, - 0, 0, 134, 0, 16, 0, - 5, 0, 0, 0, 15, 0, - 0, 7, 34, 0, 16, 0, - 9, 0, 0, 0, 70, 0, - 16, 0, 8, 0, 0, 0, - 214, 5, 16, 0, 5, 0, - 0, 0, 15, 0, 0, 7, - 66, 0, 16, 0, 4, 0, - 0, 0, 70, 0, 16, 0, - 9, 0, 0, 0, 70, 0, - 16, 0, 9, 0, 0, 0, - 75, 0, 0, 5, 130, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 14, 0, 0, 10, - 130, 0, 16, 0, 4, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 58, 0, - 16, 0, 4, 0, 0, 0, - 52, 0, 0, 7, 130, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 6, 0, 0, 0, 55, 0, - 0, 9, 34, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 6, 0, 0, 0, 31, 0, - 4, 3, 58, 0, 16, 0, - 3, 0, 0, 0, 56, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 26, 0, 16, 0, 5, 0, - 0, 0, 50, 0, 0, 10, - 130, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 5, 0, 0, 0, 58, 0, - 16, 0, 5, 0, 0, 0, - 58, 0, 16, 128, 65, 0, - 0, 0, 3, 0, 0, 0, - 49, 0, 0, 7, 130, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 49, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 30, 0, 0, 8, - 130, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 43, 0, - 0, 5, 130, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 56, 0, 0, 7, 130, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 1, 0, - 0, 10, 194, 0, 16, 0, - 7, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 16, 0, 0, 0, - 8, 0, 51, 0, 0, 7, - 130, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 130, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 7, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 52, 0, 0, 7, 130, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 55, 0, - 0, 9, 130, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 7, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 57, 0, - 0, 7, 130, 0, 16, 0, - 4, 0, 0, 0, 26, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, - 130, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 128, - 129, 0, 0, 0, 9, 0, - 0, 0, 10, 0, 16, 128, - 129, 0, 0, 0, 9, 0, - 0, 0, 14, 0, 0, 10, - 66, 0, 16, 0, 4, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 42, 0, - 16, 0, 4, 0, 0, 0, - 56, 0, 0, 7, 66, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 6, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 63, 55, 0, 0, 9, - 18, 0, 16, 0, 9, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 26, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 49, 0, 0, 7, - 66, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 24, 0, 0, 7, 130, 0, - 16, 0, 6, 0, 0, 0, - 26, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 6, 0, - 0, 0, 14, 0, 0, 7, - 34, 0, 16, 0, 9, 0, - 0, 0, 42, 0, 16, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 54, 0, 0, 5, 18, 0, - 16, 0, 10, 0, 0, 0, - 42, 0, 16, 0, 6, 0, - 0, 0, 54, 0, 0, 5, - 34, 0, 16, 0, 10, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 55, 0, - 0, 9, 194, 0, 16, 0, - 6, 0, 0, 0, 166, 10, - 16, 0, 4, 0, 0, 0, - 6, 4, 16, 0, 9, 0, - 0, 0, 6, 4, 16, 0, - 10, 0, 0, 0, 0, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 42, 0, 16, 0, 6, 0, - 0, 0, 56, 0, 0, 7, - 194, 0, 16, 0, 8, 0, - 0, 0, 166, 10, 16, 0, - 4, 0, 0, 0, 6, 4, - 16, 0, 8, 0, 0, 0, - 56, 0, 0, 7, 18, 0, - 16, 0, 10, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 0, 0, - 0, 7, 130, 0, 16, 0, - 7, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 10, 0, 16, 0, 9, 0, - 0, 0, 14, 0, 0, 10, - 130, 0, 16, 0, 7, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 58, 0, - 16, 0, 7, 0, 0, 0, - 54, 0, 0, 6, 34, 0, - 16, 0, 10, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 10, 0, 0, 0, - 0, 0, 0, 7, 98, 0, - 16, 0, 9, 0, 0, 0, - 166, 10, 16, 0, 6, 0, - 0, 0, 6, 1, 16, 0, - 10, 0, 0, 0, 50, 0, - 0, 12, 98, 0, 16, 0, - 9, 0, 0, 0, 246, 15, - 16, 0, 7, 0, 0, 0, - 86, 6, 16, 0, 9, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 63, 0, 0, 0, 63, - 0, 0, 0, 0, 79, 0, - 0, 7, 130, 0, 16, 0, - 7, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 8, - 26, 0, 16, 0, 0, 0, - 0, 0, 31, 0, 4, 3, - 58, 0, 16, 0, 7, 0, - 0, 0, 1, 0, 0, 10, - 242, 0, 16, 0, 10, 0, - 0, 0, 246, 15, 16, 0, - 2, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 64, 0, - 0, 0, 128, 0, 0, 0, - 0, 2, 0, 0, 32, 0, - 55, 0, 0, 15, 114, 0, - 16, 0, 11, 0, 0, 0, - 6, 2, 16, 0, 10, 0, - 0, 0, 2, 64, 0, 0, - 2, 0, 0, 0, 254, 255, - 255, 255, 0, 0, 128, 63, - 0, 0, 0, 0, 2, 64, - 0, 0, 254, 255, 255, 255, - 2, 0, 0, 0, 0, 0, - 128, 62, 0, 0, 0, 0, - 55, 0, 0, 9, 130, 0, - 16, 0, 7, 0, 0, 0, - 26, 0, 16, 0, 10, 0, - 0, 0, 26, 0, 16, 0, - 11, 0, 0, 0, 10, 0, - 16, 0, 11, 0, 0, 0, - 30, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 1, 0, - 0, 7, 18, 0, 16, 0, - 12, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 255, 7, - 0, 0, 42, 0, 0, 7, - 34, 0, 16, 0, 12, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 11, 0, 0, 0, - 54, 0, 0, 8, 194, 0, - 16, 0, 12, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 45, 0, 0, 137, - 194, 0, 0, 128, 3, 17, - 17, 0, 18, 0, 16, 0, - 0, 0, 0, 0, 70, 14, - 16, 0, 12, 0, 0, 0, - 38, 125, 16, 0, 8, 0, - 0, 0, 0, 0, 0, 8, - 18, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 128, - 65, 0, 0, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 49, 0, - 0, 8, 130, 0, 16, 0, - 7, 0, 0, 0, 1, 64, - 0, 0, 219, 15, 73, 64, - 10, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 34, 0, - 16, 0, 10, 0, 0, 0, - 10, 0, 16, 128, 193, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 219, 15, - 201, 64, 55, 0, 0, 10, - 18, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 26, 0, - 16, 0, 10, 0, 0, 0, - 10, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 39, 0, 0, 7, 130, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 0, 10, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 39, 0, - 0, 7, 18, 0, 16, 0, - 10, 0, 0, 0, 42, 0, - 16, 0, 7, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 32, 0, 0, 7, - 130, 0, 16, 0, 7, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 10, 0, - 16, 0, 10, 0, 0, 0, - 55, 0, 0, 9, 130, 0, - 16, 0, 7, 0, 0, 0, - 58, 0, 16, 0, 7, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 191, 1, 64, - 0, 0, 0, 0, 0, 63, - 50, 0, 0, 9, 130, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 42, 0, - 16, 0, 2, 0, 0, 0, - 77, 0, 0, 7, 18, 0, - 16, 0, 10, 0, 0, 0, - 18, 0, 16, 0, 11, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 54, 0, - 0, 6, 34, 0, 16, 0, - 10, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 11, 0, 0, 0, 15, 0, - 0, 7, 18, 0, 16, 0, - 11, 0, 0, 0, 70, 0, - 16, 0, 10, 0, 0, 0, - 134, 0, 16, 0, 5, 0, - 0, 0, 15, 0, 0, 7, - 34, 0, 16, 0, 11, 0, - 0, 0, 70, 0, 16, 0, - 10, 0, 0, 0, 214, 5, - 16, 0, 5, 0, 0, 0, - 0, 0, 0, 9, 130, 0, - 16, 0, 7, 0, 0, 0, - 26, 0, 16, 128, 129, 0, - 0, 0, 11, 0, 0, 0, - 10, 0, 16, 128, 129, 0, - 0, 0, 11, 0, 0, 0, - 15, 0, 0, 7, 66, 0, - 16, 0, 10, 0, 0, 0, - 70, 0, 16, 0, 11, 0, - 0, 0, 70, 0, 16, 0, - 11, 0, 0, 0, 14, 0, - 0, 10, 66, 0, 16, 0, - 10, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 42, 0, 16, 0, 10, 0, - 0, 0, 56, 0, 0, 7, - 130, 0, 16, 0, 7, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 42, 0, - 16, 0, 10, 0, 0, 0, - 56, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 63, 77, 0, - 0, 6, 0, 208, 0, 0, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 32, 0, - 0, 10, 50, 0, 16, 0, - 11, 0, 0, 0, 86, 5, - 16, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 20, 0, 0, 0, 16, - 0, 0, 0, 0, 0, 0, - 0, 0, 29, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 62, - 1, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 11, 0, 0, 0, 60, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 11, 0, - 0, 0, 52, 0, 0, 7, - 66, 0, 16, 0, 10, 0, - 0, 0, 42, 0, 16, 0, - 11, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 14, 0, 0, 10, 66, 0, - 16, 0, 10, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, - 128, 63, 42, 0, 16, 0, - 10, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 10, 0, 0, 0, 42, 0, - 16, 0, 6, 0, 0, 0, - 42, 0, 16, 0, 10, 0, - 0, 0, 56, 0, 0, 7, - 18, 0, 16, 0, 11, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 63, - 50, 0, 0, 9, 66, 0, - 16, 0, 6, 0, 0, 0, - 42, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 11, 0, 0, 0, - 55, 0, 0, 9, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 10, 0, 0, 0, 42, 0, - 16, 0, 6, 0, 0, 0, - 50, 0, 0, 9, 34, 0, - 16, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 7, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 63, 26, 0, - 16, 0, 0, 0, 0, 0, - 56, 0, 0, 7, 66, 0, - 16, 0, 6, 0, 0, 0, - 10, 0, 16, 0, 9, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 62, 50, 0, - 0, 9, 66, 0, 16, 0, - 6, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 6, 0, 0, 0, 29, 0, - 0, 7, 66, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 6, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 14, 0, 0, 10, - 18, 0, 16, 0, 0, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 10, 0, - 16, 0, 0, 0, 0, 0, - 56, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 56, 0, - 0, 7, 242, 0, 16, 0, - 11, 0, 0, 0, 6, 5, - 16, 0, 0, 0, 0, 0, - 70, 1, 16, 0, 10, 0, - 0, 0, 15, 0, 0, 7, - 18, 0, 16, 0, 12, 0, - 0, 0, 230, 10, 16, 0, - 8, 0, 0, 0, 230, 10, - 16, 0, 8, 0, 0, 0, - 15, 0, 0, 7, 34, 0, - 16, 0, 12, 0, 0, 0, - 230, 10, 16, 0, 11, 0, - 0, 0, 230, 10, 16, 0, - 11, 0, 0, 0, 56, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 8, 0, 0, 0, - 58, 0, 16, 0, 11, 0, - 0, 0, 50, 0, 0, 10, - 18, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 8, 0, 0, 0, 42, 0, - 16, 0, 11, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 14, 0, 0, 10, 18, 0, - 16, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, - 128, 63, 10, 0, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 10, 82, 0, 16, 0, - 13, 0, 0, 0, 166, 11, - 16, 0, 11, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 0, - 0, 0, 128, 191, 0, 0, - 0, 0, 56, 0, 0, 10, - 162, 0, 16, 0, 13, 0, - 0, 0, 246, 11, 16, 0, - 8, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 128, 191, 0, 0, - 0, 0, 0, 0, 128, 63, - 56, 0, 0, 7, 242, 0, - 16, 0, 13, 0, 0, 0, - 6, 0, 16, 0, 0, 0, - 0, 0, 70, 14, 16, 0, - 13, 0, 0, 0, 15, 0, - 0, 7, 18, 0, 16, 0, - 13, 0, 0, 0, 70, 0, - 16, 0, 13, 0, 0, 0, - 70, 0, 16, 0, 12, 0, - 0, 0, 15, 0, 0, 7, - 34, 0, 16, 0, 13, 0, - 0, 0, 230, 10, 16, 0, - 13, 0, 0, 0, 70, 0, - 16, 0, 12, 0, 0, 0, - 55, 0, 0, 9, 50, 0, - 16, 0, 11, 0, 0, 0, - 166, 10, 16, 0, 6, 0, - 0, 0, 70, 0, 16, 0, - 11, 0, 0, 0, 70, 0, - 16, 0, 13, 0, 0, 0, - 55, 0, 0, 9, 194, 0, - 16, 0, 8, 0, 0, 0, - 246, 15, 16, 0, 10, 0, - 0, 0, 6, 4, 16, 0, - 11, 0, 0, 0, 166, 14, - 16, 0, 8, 0, 0, 0, - 56, 0, 0, 8, 194, 0, - 16, 0, 10, 0, 0, 0, - 246, 15, 16, 128, 129, 0, - 0, 0, 3, 0, 0, 0, - 166, 14, 16, 0, 8, 0, - 0, 0, 15, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 230, 10, 16, 0, - 10, 0, 0, 0, 70, 0, - 16, 0, 10, 0, 0, 0, - 0, 0, 0, 8, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 14, 0, 0, 7, - 130, 0, 16, 0, 9, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 7, 0, 0, 0, - 55, 0, 0, 9, 98, 0, - 16, 0, 9, 0, 0, 0, - 166, 10, 16, 0, 7, 0, - 0, 0, 86, 7, 16, 0, - 9, 0, 0, 0, 246, 14, - 16, 0, 9, 0, 0, 0, - 21, 0, 0, 1, 56, 0, - 0, 7, 50, 0, 16, 0, - 0, 0, 0, 0, 246, 15, - 16, 0, 6, 0, 0, 0, - 150, 5, 16, 0, 9, 0, - 0, 0, 52, 0, 0, 7, - 34, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 23, 183, 209, 56, - 50, 0, 0, 10, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 9, 0, 0, 0, - 58, 0, 16, 0, 6, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 192, 55, 0, - 0, 9, 18, 0, 16, 0, - 1, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 7, 50, 0, 16, 0, - 0, 0, 0, 0, 246, 15, - 16, 0, 3, 0, 0, 0, - 230, 10, 16, 0, 8, 0, - 0, 0, 15, 0, 0, 7, - 18, 0, 16, 0, 9, 0, - 0, 0, 70, 0, 16, 0, - 0, 0, 0, 0, 134, 0, - 16, 0, 5, 0, 0, 0, - 15, 0, 0, 7, 34, 0, - 16, 0, 9, 0, 0, 0, - 70, 0, 16, 0, 0, 0, - 0, 0, 214, 5, 16, 0, - 5, 0, 0, 0, 39, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 8, - 194, 32, 16, 0, 0, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 0, - 0, 1, 57, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 31, 0, 4, 3, 26, 0, - 16, 0, 0, 0, 0, 0, - 49, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 7, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 7, 18, 0, 16, 0, - 10, 0, 0, 0, 26, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 0, 7, 0, - 0, 0, 54, 0, 0, 6, - 34, 0, 16, 0, 10, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 7, 0, - 0, 0, 55, 0, 0, 9, - 194, 0, 16, 0, 4, 0, - 0, 0, 86, 5, 16, 0, - 0, 0, 0, 0, 6, 4, - 16, 0, 10, 0, 0, 0, - 6, 4, 16, 0, 7, 0, - 0, 0, 0, 0, 0, 8, - 34, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 4, 0, 0, 0, 0, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 219, 15, - 201, 63, 56, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 131, 249, 34, 62, - 29, 0, 0, 8, 66, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 26, 0, 0, 6, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 128, - 129, 0, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 10, - 34, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 219, 15, 201, 64, 1, 64, - 0, 0, 219, 15, 201, 191, - 52, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 51, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 56, 0, 0, 7, - 66, 0, 16, 0, 2, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 63, - 49, 0, 0, 7, 66, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 0, 0, - 0, 8, 130, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 55, 0, 0, 9, 34, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 2, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 77, 0, 0, 7, 18, 0, - 16, 0, 7, 0, 0, 0, - 18, 0, 16, 0, 10, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 34, 0, 16, 0, - 7, 0, 0, 0, 10, 0, - 16, 0, 10, 0, 0, 0, - 50, 0, 0, 14, 194, 0, - 16, 0, 6, 0, 0, 0, - 6, 4, 16, 128, 65, 0, - 0, 0, 7, 0, 0, 0, - 6, 0, 16, 128, 129, 0, - 0, 0, 3, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 56, 0, 0, 10, - 50, 0, 16, 0, 7, 0, - 0, 0, 230, 10, 16, 0, - 6, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 63, - 0, 0, 0, 63, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 219, 15, 201, 191, 49, 0, - 0, 8, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 128, 129, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 111, 18, 131, 58, - 77, 0, 0, 7, 18, 0, - 16, 0, 10, 0, 0, 0, - 18, 0, 16, 0, 11, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 14, 0, - 0, 7, 66, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 10, 0, 0, 0, - 10, 0, 16, 0, 11, 0, - 0, 0, 0, 0, 0, 8, - 130, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 219, 15, 201, 63, 49, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 49, 0, 0, 7, - 130, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 30, 0, 0, 8, 130, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 128, 65, 0, - 0, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 43, 0, 0, 5, - 130, 0, 16, 0, 3, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 52, 0, - 0, 8, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 128, 129, 0, 0, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 189, 55, 134, 53, - 14, 0, 0, 7, 66, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 29, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 50, 0, 0, 16, - 50, 0, 16, 0, 10, 0, - 0, 0, 230, 10, 16, 128, - 65, 0, 0, 0, 6, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 63, 0, 0, - 0, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 128, 63, - 0, 0, 0, 192, 0, 0, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 10, 66, 0, - 16, 0, 6, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 10, 0, 0, 0, - 42, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 7, 0, 0, 0, 50, 0, - 0, 9, 66, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 7, 0, 0, 0, - 42, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 7, 0, 0, 0, 55, 0, - 0, 9, 130, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 6, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 55, 0, - 0, 12, 194, 0, 16, 0, - 10, 0, 0, 0, 86, 5, - 16, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 166, 14, 16, 0, - 4, 0, 0, 0, 52, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 7, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7, - 18, 0, 16, 0, 10, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 62, - 54, 0, 0, 5, 146, 0, - 16, 0, 7, 0, 0, 0, - 6, 0, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 8, - 98, 0, 16, 0, 7, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 192, 0, 36, 116, 73, - 0, 0, 0, 0, 55, 0, - 0, 9, 242, 0, 16, 0, - 1, 0, 0, 0, 246, 15, - 16, 0, 0, 0, 0, 0, - 70, 14, 16, 0, 10, 0, - 0, 0, 70, 14, 16, 0, - 7, 0, 0, 0, 56, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 3, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 56, 0, 0, 7, - 162, 0, 16, 0, 0, 0, - 0, 0, 6, 4, 16, 0, - 8, 0, 0, 0, 86, 5, - 16, 0, 0, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 9, 0, 0, 0, - 214, 5, 16, 0, 0, 0, - 0, 0, 134, 0, 16, 0, - 5, 0, 0, 0, 15, 0, - 0, 7, 34, 0, 16, 0, - 9, 0, 0, 0, 214, 5, - 16, 0, 0, 0, 0, 0, - 214, 5, 16, 0, 5, 0, - 0, 0, 54, 0, 0, 5, - 194, 32, 16, 0, 0, 0, - 0, 0, 166, 14, 16, 0, - 1, 0, 0, 0, 18, 0, - 0, 1, 56, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 5, 0, 0, 0, 26, 0, - 16, 0, 5, 0, 0, 0, - 50, 0, 0, 10, 34, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 5, 0, 0, 0, 26, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 14, 0, - 0, 10, 34, 0, 16, 0, - 0, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 26, 0, 16, 0, 0, 0, - 0, 0, 56, 0, 0, 10, - 242, 0, 16, 0, 7, 0, - 0, 0, 118, 2, 16, 0, - 5, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 128, 63, - 0, 0, 128, 191, 0, 0, - 128, 191, 0, 0, 128, 63, - 56, 0, 0, 7, 242, 0, - 16, 0, 7, 0, 0, 0, - 86, 5, 16, 0, 0, 0, - 0, 0, 70, 14, 16, 0, - 7, 0, 0, 0, 56, 0, - 0, 7, 162, 0, 16, 0, - 0, 0, 0, 0, 6, 0, - 16, 0, 3, 0, 0, 0, - 6, 4, 16, 0, 8, 0, - 0, 0, 15, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 70, 0, 16, 0, - 7, 0, 0, 0, 214, 5, - 16, 0, 0, 0, 0, 0, - 15, 0, 0, 7, 34, 0, - 16, 0, 3, 0, 0, 0, - 230, 10, 16, 0, 7, 0, - 0, 0, 214, 5, 16, 0, - 0, 0, 0, 0, 49, 0, - 0, 10, 162, 0, 16, 0, - 0, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 6, 4, 16, 0, 3, 0, - 0, 0, 49, 0, 0, 10, - 194, 0, 16, 0, 1, 0, - 0, 0, 6, 4, 16, 0, - 3, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 30, 0, 0, 8, 162, 0, - 16, 0, 0, 0, 0, 0, - 86, 13, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 166, 14, 16, 0, 1, 0, - 0, 0, 43, 0, 0, 5, - 162, 0, 16, 0, 0, 0, - 0, 0, 86, 13, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 10, 50, 0, 16, 0, - 9, 0, 0, 0, 214, 5, - 16, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 63, 0, 0, 0, 63, - 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 8, - 194, 32, 16, 0, 0, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 34, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 191, - 21, 0, 0, 1, 1, 0, - 0, 10, 178, 0, 16, 0, - 3, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, - 0, 128, 39, 0, 0, 10, - 178, 0, 16, 0, 3, 0, - 0, 0, 70, 12, 16, 0, - 3, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 39, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 55, 0, - 0, 10, 18, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 32, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 2, 0, 0, 0, - 55, 0, 0, 9, 50, 0, - 16, 0, 2, 0, 0, 0, - 86, 5, 16, 0, 0, 0, - 0, 0, 70, 0, 16, 0, - 4, 0, 0, 0, 70, 0, - 16, 0, 2, 0, 0, 0, - 39, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 21, 0, 0, 1, - 15, 0, 0, 7, 18, 0, - 16, 0, 3, 0, 0, 0, - 70, 0, 16, 0, 2, 0, - 0, 0, 134, 0, 16, 0, - 5, 0, 0, 0, 15, 0, - 0, 7, 34, 0, 16, 0, - 3, 0, 0, 0, 70, 0, - 16, 0, 2, 0, 0, 0, - 214, 5, 16, 0, 5, 0, - 0, 0, 0, 0, 0, 7, - 98, 0, 16, 0, 0, 0, - 0, 0, 6, 1, 16, 0, - 9, 0, 0, 0, 6, 1, - 16, 0, 3, 0, 0, 0, - 0, 0, 0, 7, 98, 0, - 16, 0, 0, 0, 0, 0, - 6, 1, 16, 0, 6, 0, - 0, 0, 86, 6, 16, 0, - 0, 0, 0, 0, 55, 0, - 0, 10, 130, 0, 16, 0, - 0, 0, 0, 0, 58, 128, - 32, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 1, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 11, - 194, 0, 16, 0, 1, 0, - 0, 0, 6, 4, 16, 128, - 65, 0, 0, 0, 1, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 128, 63, - 0, 0, 128, 191, 50, 0, - 0, 9, 194, 0, 16, 0, - 1, 0, 0, 0, 246, 15, - 16, 0, 0, 0, 0, 0, - 166, 14, 16, 0, 1, 0, - 0, 0, 6, 4, 16, 0, - 1, 0, 0, 0, 55, 0, - 0, 9, 50, 32, 16, 0, - 0, 0, 0, 0, 6, 0, - 16, 0, 0, 0, 0, 0, - 70, 0, 16, 0, 1, 0, - 0, 0, 230, 10, 16, 0, - 1, 0, 0, 0, 167, 0, - 0, 139, 2, 131, 0, 128, - 131, 153, 25, 0, 114, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 4, 0, 0, 0, 70, 114, - 16, 0, 3, 0, 0, 0, - 50, 0, 0, 9, 98, 0, - 16, 0, 0, 0, 0, 0, - 86, 6, 16, 0, 0, 0, - 0, 0, 6, 0, 16, 0, - 1, 0, 0, 0, 86, 6, - 16, 0, 1, 0, 0, 0, - 50, 0, 0, 10, 18, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 42, 128, 32, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 191, 49, 0, - 0, 8, 34, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 58, 128, 32, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 49, 0, 0, 8, 130, 0, - 16, 0, 0, 0, 0, 0, - 58, 128, 32, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 30, 0, 0, 8, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 43, 0, - 0, 5, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 50, 0, 0, 11, 34, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 58, 128, 32, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 8, - 194, 0, 16, 0, 1, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 128, 63, 55, 0, - 0, 10, 242, 32, 16, 0, - 1, 0, 0, 0, 6, 0, - 16, 0, 0, 0, 0, 0, - 166, 138, 32, 0, 0, 0, - 0, 0, 4, 0, 0, 0, - 70, 14, 16, 0, 1, 0, - 0, 0, 62, 0, 0, 1, - 83, 84, 65, 84, 148, 0, - 0, 0, 83, 1, 0, 0, - 14, 0, 0, 0, 0, 0, - 0, 0, 5, 0, 0, 0, - 163, 0, 0, 0, 39, 0, - 0, 0, 27, 0, 0, 0, - 6, 0, 0, 0, 8, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 29, 0, 0, 0, 32, 0, - 0, 0, 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h deleted file mode 100644 index 58e0c4ce0..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h +++ /dev/null @@ -1,352 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 10.1 -// -// -// Resource Bindings: -// -// Name Type Format Dim HLSL Bind Count -// ------------------------------ ---------- ------- ----------- -------------- ------ -// M8 sampler NA NA s10 1 -// JC texture float 1darray t10 1 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// TEXCOORD 0 xyzw 0 NONE float xyzw -// SV_Position 0 xyzw 1 POS float -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_Target 0 x 0 TARGET float x -// -ps_5_0 -dcl_globalFlags refactoringAllowed -dcl_sampler s10, mode_default -dcl_resource_texture1darray (float,float,float,float) t10 -dcl_input_ps linear noperspective v0.xyzw -dcl_output o0.x -dcl_temps 6 -max r0.x, v0.w, l(0.000000) -ge r0.z, v0.z, l(0.000000) -mov r0.y, l(0) -sample_l_indexable(texture1darray)(float,float,float,float) r0.y, r0.xyxx, t10.yxzw, s10, l(0.000000) -and r0.y, r0.y, r0.z -lt r0.z, |v0.z|, l(1000.000000) -if_nz r0.z - add r0.z, |v0.x|, l(-0.250000) - add r0.w, -v0.y, l(-2.000000) - add r1.x, -r0.x, r0.w - mul r1.y, r1.x, l(0.598413) - mad r2.xyzw, r1.xxxx, l(0.125000, 0.375000, 0.625000, 0.875000), r0.xxxx - mad r0.x, r0.w, v0.z, r0.z - mad r3.xyzw, r2.zxwy, -v0.zzzz, r0.xxxx - mov r4.xz, r3.yywy - mov r4.yw, l(0,0,0,0) - sample_l_indexable(texture1darray)(float,float,float,float) r5.x, r4.xyxx, t10.xyzw, s10, l(0.000000) - sample_l_indexable(texture1darray)(float,float,float,float) r5.y, r4.zwzz, t10.yxzw, s10, l(0.000000) - mov r3.yw, l(0,0,0,0) - sample_l_indexable(texture1darray)(float,float,float,float) r5.z, r3.xyxx, t10.yzxw, s10, l(0.000000) - sample_l_indexable(texture1darray)(float,float,float,float) r5.w, r3.zwzz, t10.yzwx, s10, l(0.000000) - mad r2.xyzw, r2.xyzw, l(5.095931, 5.095931, 5.095931, 5.095931), l(-2.547965, -2.547965, -2.547965, -2.547965) - mul r2.xyzw, r2.xyzw, -r2.xyzw - exp r2.xyzw, r2.xyzw - dp4 r0.x, r5.xyzw, r2.xyzw - mad r0.y, r0.x, r1.y, r0.y -endif -lt r0.x, l(0.000000), v0.x -lt r0.z, v0.x, l(0.000000) -iadd r0.x, -r0.x, r0.z -itof r0.x, r0.x -mul o0.x, r0.x, r0.y -ret -// Approximately 33 instruction slots used -#endif - -const BYTE g_main[] = -{ - 68, 88, 66, 67, 217, 220, - 138, 177, 184, 179, 84, 150, - 127, 197, 117, 110, 61, 197, - 78, 54, 1, 0, 0, 0, - 132, 6, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 232, 0, 0, 0, 64, 1, - 0, 0, 116, 1, 0, 0, - 232, 5, 0, 0, 82, 68, - 69, 70, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, - 60, 0, 0, 0, 0, 5, - 255, 255, 0, 1, 0, 0, - 130, 0, 0, 0, 82, 68, - 49, 49, 60, 0, 0, 0, - 24, 0, 0, 0, 32, 0, - 0, 0, 40, 0, 0, 0, - 36, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 124, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 127, 0, 0, 0, - 2, 0, 0, 0, 5, 0, - 0, 0, 3, 0, 0, 0, - 255, 255, 255, 255, 10, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 77, 56, - 0, 74, 67, 0, 77, 105, - 99, 114, 111, 115, 111, 102, - 116, 32, 40, 82, 41, 32, - 72, 76, 83, 76, 32, 83, - 104, 97, 100, 101, 114, 32, - 67, 111, 109, 112, 105, 108, - 101, 114, 32, 49, 48, 46, - 49, 0, 171, 171, 73, 83, - 71, 78, 80, 0, 0, 0, - 2, 0, 0, 0, 8, 0, - 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 15, 15, - 0, 0, 65, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 1, 0, 0, 0, 15, 0, - 0, 0, 84, 69, 88, 67, - 79, 79, 82, 68, 0, 83, - 86, 95, 80, 111, 115, 105, - 116, 105, 111, 110, 0, 171, - 171, 171, 79, 83, 71, 78, - 44, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 1, 14, 0, 0, - 83, 86, 95, 84, 97, 114, - 103, 101, 116, 0, 171, 171, - 83, 72, 69, 88, 108, 4, - 0, 0, 80, 0, 0, 0, - 27, 1, 0, 0, 106, 8, - 0, 1, 90, 0, 0, 3, - 0, 96, 16, 0, 10, 0, - 0, 0, 88, 56, 0, 4, - 0, 112, 16, 0, 10, 0, - 0, 0, 85, 85, 0, 0, - 98, 32, 0, 3, 242, 16, - 16, 0, 0, 0, 0, 0, - 101, 0, 0, 3, 18, 32, - 16, 0, 0, 0, 0, 0, - 104, 0, 0, 2, 6, 0, - 0, 0, 52, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 58, 16, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 29, 0, 0, 7, 66, 0, - 16, 0, 0, 0, 0, 0, - 42, 16, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 34, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 72, 0, 0, 141, 194, 1, - 0, 128, 67, 85, 21, 0, - 34, 0, 16, 0, 0, 0, - 0, 0, 70, 0, 16, 0, - 0, 0, 0, 0, 22, 126, - 16, 0, 10, 0, 0, 0, - 0, 96, 16, 0, 10, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 49, 0, 0, 8, - 66, 0, 16, 0, 0, 0, - 0, 0, 42, 16, 16, 128, - 129, 0, 0, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 122, 68, 31, 0, - 4, 3, 42, 0, 16, 0, - 0, 0, 0, 0, 0, 0, - 0, 8, 66, 0, 16, 0, - 0, 0, 0, 0, 10, 16, - 16, 128, 129, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 190, - 0, 0, 0, 8, 130, 0, - 16, 0, 0, 0, 0, 0, - 26, 16, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 192, 0, 0, 0, 8, - 18, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 7, 34, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 159, 49, - 25, 63, 50, 0, 0, 12, - 242, 0, 16, 0, 2, 0, - 0, 0, 6, 0, 16, 0, - 1, 0, 0, 0, 2, 64, - 0, 0, 255, 255, 255, 61, - 0, 0, 192, 62, 0, 0, - 32, 63, 255, 255, 95, 63, - 6, 0, 16, 0, 0, 0, - 0, 0, 50, 0, 0, 9, - 18, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 42, 16, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 50, 0, 0, 10, - 242, 0, 16, 0, 3, 0, - 0, 0, 38, 7, 16, 0, - 2, 0, 0, 0, 166, 26, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 6, 0, - 16, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 82, 0, - 16, 0, 4, 0, 0, 0, - 86, 7, 16, 0, 3, 0, - 0, 0, 54, 0, 0, 8, - 162, 0, 16, 0, 4, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 72, 0, - 0, 141, 194, 1, 0, 128, - 67, 85, 21, 0, 18, 0, - 16, 0, 5, 0, 0, 0, - 70, 0, 16, 0, 4, 0, - 0, 0, 70, 126, 16, 0, - 10, 0, 0, 0, 0, 96, - 16, 0, 10, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 72, 0, 0, 141, - 194, 1, 0, 128, 67, 85, - 21, 0, 34, 0, 16, 0, - 5, 0, 0, 0, 230, 10, - 16, 0, 4, 0, 0, 0, - 22, 126, 16, 0, 10, 0, - 0, 0, 0, 96, 16, 0, - 10, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 54, 0, 0, 8, 162, 0, - 16, 0, 3, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 72, 0, 0, 141, - 194, 1, 0, 128, 67, 85, - 21, 0, 66, 0, 16, 0, - 5, 0, 0, 0, 70, 0, - 16, 0, 3, 0, 0, 0, - 150, 124, 16, 0, 10, 0, - 0, 0, 0, 96, 16, 0, - 10, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 72, 0, 0, 141, 194, 1, - 0, 128, 67, 85, 21, 0, - 130, 0, 16, 0, 5, 0, - 0, 0, 230, 10, 16, 0, - 3, 0, 0, 0, 150, 115, - 16, 0, 10, 0, 0, 0, - 0, 96, 16, 0, 10, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 50, 0, - 0, 15, 242, 0, 16, 0, - 2, 0, 0, 0, 70, 14, - 16, 0, 2, 0, 0, 0, - 2, 64, 0, 0, 221, 17, - 163, 64, 221, 17, 163, 64, - 221, 17, 163, 64, 221, 17, - 163, 64, 2, 64, 0, 0, - 221, 17, 35, 192, 221, 17, - 35, 192, 221, 17, 35, 192, - 221, 17, 35, 192, 56, 0, - 0, 8, 242, 0, 16, 0, - 2, 0, 0, 0, 70, 14, - 16, 0, 2, 0, 0, 0, - 70, 14, 16, 128, 65, 0, - 0, 0, 2, 0, 0, 0, - 25, 0, 0, 5, 242, 0, - 16, 0, 2, 0, 0, 0, - 70, 14, 16, 0, 2, 0, - 0, 0, 17, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 70, 14, 16, 0, - 5, 0, 0, 0, 70, 14, - 16, 0, 2, 0, 0, 0, - 50, 0, 0, 9, 34, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 21, 0, 0, 1, 49, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 10, 16, 16, 0, 0, 0, - 0, 0, 49, 0, 0, 7, - 66, 0, 16, 0, 0, 0, - 0, 0, 10, 16, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 30, 0, 0, 8, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 43, 0, 0, 5, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 7, 18, 32, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 62, 0, 0, 1, - 83, 84, 65, 84, 148, 0, - 0, 0, 33, 0, 0, 0, - 6, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, - 18, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h deleted file mode 100644 index f9548dfc9..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h +++ /dev/null @@ -1,195 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 10.1 -// -// -// Resource Bindings: -// -// Name Type Format Dim HLSL Bind Count -// ------------------------------ ---------- ------- ----------- -------------- ------ -// M8 sampler NA NA s10 1 -// JC texture float 1darray t10 1 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// TEXCOORD 0 xyzw 0 NONE float xy -// SV_Position 0 xyzw 1 POS float -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_Target 0 x 0 TARGET float x -// -ps_5_0 -dcl_globalFlags refactoringAllowed -dcl_sampler s10, mode_default -dcl_resource_texture1darray (float,float,float,float) t10 -dcl_input_ps linear noperspective v0.xy -dcl_output o0.x -dcl_temps 1 -add r0.x, v0.x, l(3.000000) -mov r0.yw, l(0,0,0,0) -sample_l_indexable(texture1darray)(float,float,float,float) r0.x, r0.xyxx, t10.xyzw, s10, l(0.000000) -add r0.x, -r0.x, l(1.000000) -add r0.z, -v0.y, l(1.000000) -sample_l_indexable(texture1darray)(float,float,float,float) r0.y, r0.zwzz, t10.yxzw, s10, l(0.000000) -add o0.x, -r0.y, r0.x -ret -// Approximately 8 instruction slots used -#endif - -const BYTE g_main[] = -{ - 68, 88, 66, 67, 165, 25, - 130, 128, 89, 132, 241, 41, - 156, 101, 68, 43, 180, 42, - 208, 205, 1, 0, 0, 0, - 104, 3, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 232, 0, 0, 0, 64, 1, - 0, 0, 116, 1, 0, 0, - 204, 2, 0, 0, 82, 68, - 69, 70, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, - 60, 0, 0, 0, 0, 5, - 255, 255, 0, 1, 0, 0, - 130, 0, 0, 0, 82, 68, - 49, 49, 60, 0, 0, 0, - 24, 0, 0, 0, 32, 0, - 0, 0, 40, 0, 0, 0, - 36, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 124, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 127, 0, 0, 0, - 2, 0, 0, 0, 5, 0, - 0, 0, 3, 0, 0, 0, - 255, 255, 255, 255, 10, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 77, 56, - 0, 74, 67, 0, 77, 105, - 99, 114, 111, 115, 111, 102, - 116, 32, 40, 82, 41, 32, - 72, 76, 83, 76, 32, 83, - 104, 97, 100, 101, 114, 32, - 67, 111, 109, 112, 105, 108, - 101, 114, 32, 49, 48, 46, - 49, 0, 171, 171, 73, 83, - 71, 78, 80, 0, 0, 0, - 2, 0, 0, 0, 8, 0, - 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 15, 3, - 0, 0, 65, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 1, 0, 0, 0, 15, 0, - 0, 0, 84, 69, 88, 67, - 79, 79, 82, 68, 0, 83, - 86, 95, 80, 111, 115, 105, - 116, 105, 111, 110, 0, 171, - 171, 171, 79, 83, 71, 78, - 44, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 1, 14, 0, 0, - 83, 86, 95, 84, 97, 114, - 103, 101, 116, 0, 171, 171, - 83, 72, 69, 88, 80, 1, - 0, 0, 80, 0, 0, 0, - 84, 0, 0, 0, 106, 8, - 0, 1, 90, 0, 0, 3, - 0, 96, 16, 0, 10, 0, - 0, 0, 88, 56, 0, 4, - 0, 112, 16, 0, 10, 0, - 0, 0, 85, 85, 0, 0, - 98, 32, 0, 3, 50, 16, - 16, 0, 0, 0, 0, 0, - 101, 0, 0, 3, 18, 32, - 16, 0, 0, 0, 0, 0, - 104, 0, 0, 2, 1, 0, - 0, 0, 0, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 16, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 64, 64, - 54, 0, 0, 8, 162, 0, - 16, 0, 0, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 72, 0, 0, 141, - 194, 1, 0, 128, 67, 85, - 21, 0, 18, 0, 16, 0, - 0, 0, 0, 0, 70, 0, - 16, 0, 0, 0, 0, 0, - 70, 126, 16, 0, 10, 0, - 0, 0, 0, 96, 16, 0, - 10, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 8, - 66, 0, 16, 0, 0, 0, - 0, 0, 26, 16, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 72, 0, - 0, 141, 194, 1, 0, 128, - 67, 85, 21, 0, 34, 0, - 16, 0, 0, 0, 0, 0, - 230, 10, 16, 0, 0, 0, - 0, 0, 22, 126, 16, 0, - 10, 0, 0, 0, 0, 96, - 16, 0, 10, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 8, - 18, 32, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 62, 0, - 0, 1, 83, 84, 65, 84, - 148, 0, 0, 0, 8, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 2, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h deleted file mode 100644 index 4f18f5c26..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h +++ /dev/null @@ -1,123 +0,0 @@ -#if 0 -Disassembly failed -#endif - -const BYTE g_ROOT_SIG[] = -{ - 68, 88, 66, 67, 3, 61, - 92, 108, 130, 101, 197, 191, - 222, 129, 206, 39, 2, 17, - 14, 98, 1, 0, 0, 0, - 180, 2, 0, 0, 1, 0, - 0, 0, 36, 0, 0, 0, - 82, 84, 83, 48, 136, 2, - 0, 0, 2, 0, 0, 0, - 9, 0, 0, 0, 24, 0, - 0, 0, 0, 0, 0, 0, - 136, 2, 0, 0, 1, 0, - 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 132, 0, - 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 144, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 156, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 168, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 1, - 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 120, 1, - 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 152, 1, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 104, 2, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, - 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 2, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 4, 0, 0, 0, - 176, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 1, 0, 0, 0, - 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 1, 0, 0, 0, - 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 1, 0, 0, 0, - 6, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 255, 255, 255, 255, 4, 0, - 0, 0, 24, 1, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 1, 0, - 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 1, 0, - 0, 0, 10, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 1, 0, - 0, 0, 11, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 255, 255, 255, 255, - 1, 0, 0, 0, 128, 1, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 255, 255, - 255, 255, 4, 0, 0, 0, - 160, 1, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 255, 255, 255, 255, 1, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, - 255, 255, 255, 255, 1, 0, - 0, 0, 1, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 255, 255, 255, 255, 1, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, - 255, 255, 255, 255, 4, 0, - 0, 0, 8, 2, 0, 0, - 3, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 3, 0, 0, 0, 1, 0, - 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 3, 0, 0, 0, 1, 0, - 0, 0, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 3, 0, 0, 0, 1, 0, - 0, 0, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 1, 0, 0, 0, 112, 2, - 0, 0, 3, 0, 0, 0, - 1, 0, 0, 0, 13, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 255, 255, - 255, 255 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h deleted file mode 100644 index b3ad63769..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h +++ /dev/null @@ -1,1418 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 10.1 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// TEXCOORD 0 xyzw 0 NONE float xyzw -// TEXCOORD 1 xyzw 1 NONE float xyzw -// TEXCOORD 2 xyzw 2 NONE float xyzw -// TEXCOORD 3 xyz 3 NONE float xyz -// TEXCOORD 4 x 4 NONE uint x -// SV_Position 0 xyzw 5 POS float -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_Target 0 xyzw 0 TARGET uint xyzw -// -ps_5_0 -dcl_globalFlags refactoringAllowed -dcl_input_ps linear noperspective v0.xyzw -dcl_input_ps linear noperspective v1.xyzw -dcl_input_ps linear noperspective v2.xyzw -dcl_input_ps linear noperspective v3.xyz -dcl_input_ps constant v4.x -dcl_output o0.xyzw -dcl_temps 10 -ne r0.xy, v0.zwzz, v0.xyxx -or r0.x, r0.y, r0.x -ne r0.yz, v0.zzwz, v1.xxyx -or r0.y, r0.z, r0.y -movc r0.zw, r0.yyyy, v1.xxxy, v1.zzzw -movc r0.xz, r0.xxxx, v0.zzwz, r0.zzwz -add r0.xz, r0.xxzx, -v0.xxyx -ne r1.xy, v1.xyxx, v1.zwzz -or r0.w, r1.y, r1.x -movc r1.xy, r0.yyyy, v0.zwzz, v0.xyxx -movc r0.yw, r0.wwww, v1.xxxy, r1.xxxy -add r0.yw, -r0.yyyw, v1.zzzw -round_ni r1.x, v2.x -max r1.w, r1.x, l(0.000000) -ftou r2.x, v2.z -and r2.y, r2.x, l(1023) -utof r3.x, r2.y -ushr r2.x, r2.x, l(10) -utof r2.y, r2.x -add r1.z, -r2.y, v2.y -ge r2.w, r1.z, r1.w -add r2.z, -r1.z, r1.w -and r4.xyz, v4.xxxx, l(0xe3ffffff, 0x1c000000, 0x02000000, 0) -ult r3.w, l(0x08000000), r4.y -lt r5.xy, r2.zzzz, l(2.500000, 3.500000, 0.000000, 0.000000) -or r4.w, v4.x, l(0x00400000) -movc r4.w, r5.x, r4.w, v4.x -lt r5.x, l(1.500000), r2.z -and r5.x, r5.y, r5.x -or r5.y, r4.w, l(0x00200000) -movc r2.x, r5.x, r5.y, r4.w -ine r4.z, r4.z, l(0) -ieq r4.y, r4.y, l(0x04000000) -or r4.y, r4.y, r4.z -add r4.zw, r2.yyyz, l(0.000000, 0.000000, -2.000000, -1.000000) -movc r5.yz, r4.yyyy, r4.zzwz, r2.yyzy -mov r5.x, v4.x -movc r5.xzw, r3.wwww, r2.xxyz, r5.xxyz -lt r2.x, v3.z, l(0.000000) -movc r2.x, r2.x, l(0x00100000), l(0x00080000) -or r2.z, r2.x, r5.x -mov r1.xy, v1.xyxx -mov r5.xy, v1.zwzz -movc r1.xyzw, r2.wwww, r1.xyzw, r5.xyzw -movc r4.yz, r2.wwww, v0.xxyx, v1.zzwz -movc r0.xz, r2.wwww, r0.xxzx, r0.yywy -mov r3.y, v2.w -mov r3.z, r4.x -mov r2.x, l(1.000000) -mov r2.y, v3.z -movc r3.xyw, r2.wwww, r3.xyxz, r2.xyxz -eq r2.x, r1.w, l(0.000000) -eq r2.y, r1.z, r1.w -or r2.x, r2.y, r2.x -and r2.y, r3.w, l(0x1c000000) -ult r2.z, l(0x08000000), r2.y -or r2.x, r2.z, r2.x -if_nz r2.x - movc r0.yw, r2.wwww, r0.yyyw, v3.xxxy - mul r2.x, r1.z, l(0.500000) - lt r2.x, r1.w, r2.x - movc r3.xy, r2.xxxx, r4.yzyy, v1.zwzz - movc r0.yw, r2.xxxx, r0.xxxz, r0.yyyw - dp2 r2.x, r0.ywyy, r0.ywyy - rsq r2.x, r2.x - mul r0.yw, r0.yyyw, r2.xxxx - max r0.y, r0.y, l(-1.000000) - min r0.y, r0.y, l(1.000000) - add r2.x, -|r0.y|, l(1.000000) - sqrt r2.x, r2.x - mad r2.z, |r0.y|, l(-0.018729), l(0.074261) - mad r2.z, r2.z, |r0.y|, l(-0.212114) - mad r2.z, r2.z, |r0.y|, l(1.570729) - mul r4.x, r2.x, r2.z - mad r4.x, r4.x, l(-2.000000), l(3.141593) - lt r0.y, r0.y, -r0.y - and r0.y, r0.y, r4.x - mad r0.y, r2.z, r2.x, r0.y - ge r0.w, r0.w, l(0.000000) - movc r0.y, r0.w, r0.y, -r0.y -else - movc r2.xz, r2.wwww, v0.zzwz, v1.zzwz - and r0.w, r3.w, l(0x80000000) - if_nz r0.w - mov r3.xy, r2.xzxx - mov r0.y, l(0) - else - eq r0.w, r1.z, r3.x - if_nz r0.w - div r5.x, r1.w, r3.x - mov r5.y, l(0) - mov r0.w, l(0) - else - add r4.xw, -r4.yyyz, r2.xxxz - add r5.zw, -r4.yyyz, v1.zzzw - add r6.xy, r1.xyxx, -r2.xzxx - add r6.zw, -r4.xxxw, r6.xxxy - mad r5.zw, r6.xxxy, l(0.000000, 0.000000, -3.000000, -3.000000), r5.zzzw - add r2.w, r3.x, r3.x - mul r6.xy, r2.wwww, r6.zwzz - mul r2.w, r3.x, r3.x - mul r7.xy, r2.wwww, r4.xwxx - add r2.w, r3.x, l(-1.000000) - min r2.w, r1.w, r2.w - dp2 r7.z, r0.xzxx, r0.xzxx - rsq r7.z, r7.z - mul r0.xz, r0.xxzx, r7.zzzz - add r7.z, r1.w, l(1.000000) - mul r7.z, |r3.y|, r7.z - mov r7.w, l(0) - mov r8.x, l(9) - loop - ilt r8.y, r8.x, l(0) - breakc_nz r8.y - itof r8.y, r8.x - exp r8.y, r8.y - add r8.y, r7.w, r8.y - ge r8.z, r2.w, r8.y - mad r9.xy, r8.yyyy, r5.zwzz, r6.xyxx - mad r9.xy, r8.yyyy, r9.xyxx, r7.xyxx - dp2 r8.w, r9.xyxx, r9.xyxx - rsq r8.w, r8.w - mul r9.xy, r8.wwww, r9.xyxx - dp2 r8.w, r9.xyxx, r0.xzxx - mad r9.x, r8.y, -|r3.y|, r7.z - min r9.x, r9.x, l(3.141593) - sincos null, r9.x, r9.x - ge r8.w, r8.w, r9.x - movc r8.y, r8.w, r8.y, r7.w - movc r7.w, r8.z, r8.y, r7.w - iadd r8.x, r8.x, l(-1) - endloop - div r2.w, r7.w, r3.x - add r6.x, r1.w, -r7.w - max r0.x, r0.x, l(-1.000000) - min r0.x, r0.x, l(1.000000) - add r6.y, -|r0.x|, l(1.000000) - sqrt r6.y, r6.y - mad r7.x, |r0.x|, l(-0.018729), l(0.074261) - mad r7.x, r7.x, |r0.x|, l(-0.212114) - mad r7.x, r7.x, |r0.x|, l(1.570729) - mul r7.y, r6.y, r7.x - mad r7.y, r7.y, l(-2.000000), l(3.141593) - lt r0.x, r0.x, -r0.x - and r0.x, r0.x, r7.y - mad r0.x, r7.x, r6.y, r0.x - ge r0.z, r0.z, l(0.000000) - movc r0.x, r0.z, r0.x, -r0.x - mad r0.w, r6.x, r3.y, r0.x - sincos r7.x, r0.x, r0.w - mov r7.y, -r0.x - dp2 r8.z, r7.xyxx, r5.zwzz - dp2 r0.x, r7.xyxx, r6.zwzz - dp2 r8.x, r7.xyxx, r4.xwxx - mul r0.z, r8.x, r8.z - mad r0.z, r0.x, r0.x, -r0.z - max r0.z, r0.z, l(0.000000) - sqrt r0.z, r0.z - lt r4.x, l(0.000000), r0.x - movc r0.z, r4.x, -r0.z, r0.z - add r8.y, -r0.x, r0.z - mul r0.x, r8.y, r8.z - mul r0.x, r0.x, l(-0.500000) - mad r0.z, r8.y, r8.y, r0.x - mad r0.x, r8.z, r8.x, r0.x - lt r0.x, |r0.z|, |r0.x| - movc r0.xz, r0.xxxx, r8.yyzy, r8.xxyx - ne r4.x, r0.z, l(0.000000) - div r0.x, r0.x, r0.z - and r0.x, r0.x, r4.x - mov_sat r0.x, r0.x - eq r0.z, r6.x, l(0.000000) - movc r5.y, r0.z, l(0), r0.x - max r5.x, r2.w, r5.y - endif - add r0.xz, -r4.yyzy, r2.xxzx - mad r0.xz, r0.xxzx, r5.xxxx, r4.yyzy - add r4.xy, r1.xyxx, -r2.xzxx - mad r2.xz, r4.xxyx, r5.xxxx, r2.xxzx - add r4.xy, -r1.xyxx, v1.zwzz - mad r1.xy, r4.xyxx, r5.xxxx, r1.xyxx - add r4.xy, -r0.xzxx, r2.xzxx - mad r0.xz, r4.xxyx, r5.xxxx, r0.xxzx - add r1.xy, -r2.xzxx, r1.xyxx - mad r1.xy, r1.xyxx, r5.xxxx, r2.xzxx - add r1.xy, -r0.xzxx, r1.xyxx - mad r3.xy, r1.xyxx, r5.xxxx, r0.xzxx - ne r0.x, r5.y, r5.x - dp2 r0.z, r1.xyxx, r1.xyxx - rsq r0.z, r0.z - mul r1.xy, r0.zzzz, r1.xyxx - max r0.z, r1.x, l(-1.000000) - min r0.z, r0.z, l(1.000000) - add r1.x, -|r0.z|, l(1.000000) - sqrt r1.x, r1.x - mad r2.x, |r0.z|, l(-0.018729), l(0.074261) - mad r2.x, r2.x, |r0.z|, l(-0.212114) - mad r2.x, r2.x, |r0.z|, l(1.570729) - mul r2.z, r1.x, r2.x - mad r2.z, r2.z, l(-2.000000), l(3.141593) - lt r0.z, r0.z, -r0.z - and r0.z, r0.z, r2.z - mad r0.z, r2.x, r1.x, r0.z - ge r1.x, r1.y, l(0.000000) - movc r0.z, r1.x, r0.z, -r0.z - movc r0.y, r0.x, r0.z, r0.w - endif -endif -ieq r0.x, r2.y, l(0x04000000) -ftou r0.zw, r1.zzzw -ishl r0.z, r0.z, l(16) -or r0.z, r0.w, r0.z -mul r0.y, r0.y, l(0.159155) -ge r0.w, r0.y, -r0.y -frc r0.y, |r0.y| -movc r0.y, r0.w, r0.y, -r0.y -mul r0.y, r0.y, l(6.283185) -movc r3.z, r0.x, r0.z, r0.y -mov o0.xyzw, r3.xyzw -ret -// Approximately 220 instruction slots used -#endif - -const BYTE g_main[] = -{ - 68, 88, 66, 67, 225, 236, - 243, 192, 161, 17, 15, 154, - 184, 138, 170, 204, 240, 23, - 147, 97, 1, 0, 0, 0, - 40, 27, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 160, 0, 0, 0, 88, 1, - 0, 0, 140, 1, 0, 0, - 140, 26, 0, 0, 82, 68, - 69, 70, 100, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 60, 0, 0, 0, 0, 5, - 255, 255, 0, 1, 0, 0, - 60, 0, 0, 0, 82, 68, - 49, 49, 60, 0, 0, 0, - 24, 0, 0, 0, 32, 0, - 0, 0, 40, 0, 0, 0, - 36, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 77, 105, 99, 114, 111, 115, - 111, 102, 116, 32, 40, 82, - 41, 32, 72, 76, 83, 76, - 32, 83, 104, 97, 100, 101, - 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 49, - 48, 46, 49, 0, 73, 83, - 71, 78, 176, 0, 0, 0, - 6, 0, 0, 0, 8, 0, - 0, 0, 152, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 15, 15, - 0, 0, 152, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 1, 0, 0, 0, 15, 15, - 0, 0, 152, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 2, 0, 0, 0, 15, 15, - 0, 0, 152, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, - 3, 0, 0, 0, 7, 7, - 0, 0, 152, 0, 0, 0, - 4, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 4, 0, 0, 0, 1, 1, - 0, 0, 161, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 5, 0, 0, 0, 15, 0, - 0, 0, 84, 69, 88, 67, - 79, 79, 82, 68, 0, 83, - 86, 95, 80, 111, 115, 105, - 116, 105, 111, 110, 0, 171, - 171, 171, 79, 83, 71, 78, - 44, 0, 0, 0, 1, 0, - 0, 0, 8, 0, 0, 0, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 83, 86, 95, 84, 97, 114, - 103, 101, 116, 0, 171, 171, - 83, 72, 69, 88, 248, 24, - 0, 0, 80, 0, 0, 0, - 62, 6, 0, 0, 106, 8, - 0, 1, 98, 32, 0, 3, - 242, 16, 16, 0, 0, 0, - 0, 0, 98, 32, 0, 3, - 242, 16, 16, 0, 1, 0, - 0, 0, 98, 32, 0, 3, - 242, 16, 16, 0, 2, 0, - 0, 0, 98, 32, 0, 3, - 114, 16, 16, 0, 3, 0, - 0, 0, 98, 8, 0, 3, - 18, 16, 16, 0, 4, 0, - 0, 0, 101, 0, 0, 3, - 242, 32, 16, 0, 0, 0, - 0, 0, 104, 0, 0, 2, - 10, 0, 0, 0, 57, 0, - 0, 7, 50, 0, 16, 0, - 0, 0, 0, 0, 230, 26, - 16, 0, 0, 0, 0, 0, - 70, 16, 16, 0, 0, 0, - 0, 0, 60, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 57, 0, 0, 7, 98, 0, - 16, 0, 0, 0, 0, 0, - 166, 27, 16, 0, 0, 0, - 0, 0, 6, 17, 16, 0, - 1, 0, 0, 0, 60, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 55, 0, 0, 9, - 194, 0, 16, 0, 0, 0, - 0, 0, 86, 5, 16, 0, - 0, 0, 0, 0, 6, 20, - 16, 0, 1, 0, 0, 0, - 166, 30, 16, 0, 1, 0, - 0, 0, 55, 0, 0, 9, - 82, 0, 16, 0, 0, 0, - 0, 0, 6, 0, 16, 0, - 0, 0, 0, 0, 166, 27, - 16, 0, 0, 0, 0, 0, - 166, 11, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 8, - 82, 0, 16, 0, 0, 0, - 0, 0, 6, 2, 16, 0, - 0, 0, 0, 0, 6, 17, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 57, 0, - 0, 7, 50, 0, 16, 0, - 1, 0, 0, 0, 70, 16, - 16, 0, 1, 0, 0, 0, - 230, 26, 16, 0, 1, 0, - 0, 0, 60, 0, 0, 7, - 130, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 55, 0, 0, 9, 50, 0, - 16, 0, 1, 0, 0, 0, - 86, 5, 16, 0, 0, 0, - 0, 0, 230, 26, 16, 0, - 0, 0, 0, 0, 70, 16, - 16, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 162, 0, - 16, 0, 0, 0, 0, 0, - 246, 15, 16, 0, 0, 0, - 0, 0, 6, 20, 16, 0, - 1, 0, 0, 0, 6, 4, - 16, 0, 1, 0, 0, 0, - 0, 0, 0, 8, 162, 0, - 16, 0, 0, 0, 0, 0, - 86, 13, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 166, 30, 16, 0, 1, 0, - 0, 0, 65, 0, 0, 5, - 18, 0, 16, 0, 1, 0, - 0, 0, 10, 16, 16, 0, - 2, 0, 0, 0, 52, 0, - 0, 7, 130, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 28, 0, 0, 5, - 18, 0, 16, 0, 2, 0, - 0, 0, 42, 16, 16, 0, - 2, 0, 0, 0, 1, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 255, 3, - 0, 0, 86, 0, 0, 5, - 18, 0, 16, 0, 3, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 85, 0, - 0, 7, 18, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 10, 0, - 0, 0, 86, 0, 0, 5, - 34, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 0, 0, - 0, 8, 66, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 128, 65, 0, 0, 0, - 2, 0, 0, 0, 26, 16, - 16, 0, 2, 0, 0, 0, - 29, 0, 0, 7, 130, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 0, 0, - 0, 8, 66, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 1, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 1, 0, 0, 10, 114, 0, - 16, 0, 4, 0, 0, 0, - 6, 16, 16, 0, 4, 0, - 0, 0, 2, 64, 0, 0, - 255, 255, 255, 227, 0, 0, - 0, 28, 0, 0, 0, 2, - 0, 0, 0, 0, 79, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 8, - 26, 0, 16, 0, 4, 0, - 0, 0, 49, 0, 0, 10, - 50, 0, 16, 0, 5, 0, - 0, 0, 166, 10, 16, 0, - 2, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 32, 64, - 0, 0, 96, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 60, 0, 0, 7, 130, 0, - 16, 0, 4, 0, 0, 0, - 10, 16, 16, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 64, 0, 55, 0, - 0, 9, 130, 0, 16, 0, - 4, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 10, 16, 16, 0, - 4, 0, 0, 0, 49, 0, - 0, 7, 18, 0, 16, 0, - 5, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 192, 63, - 42, 0, 16, 0, 2, 0, - 0, 0, 1, 0, 0, 7, - 18, 0, 16, 0, 5, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 60, 0, 0, 7, 34, 0, - 16, 0, 5, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 32, 0, 55, 0, - 0, 9, 18, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 26, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 39, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 32, 0, 0, 7, - 34, 0, 16, 0, 4, 0, - 0, 0, 26, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 4, - 60, 0, 0, 7, 34, 0, - 16, 0, 4, 0, 0, 0, - 26, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 0, 0, - 0, 10, 194, 0, 16, 0, - 4, 0, 0, 0, 86, 9, - 16, 0, 2, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 192, 0, 0, - 128, 191, 55, 0, 0, 9, - 98, 0, 16, 0, 5, 0, - 0, 0, 86, 5, 16, 0, - 4, 0, 0, 0, 166, 11, - 16, 0, 4, 0, 0, 0, - 86, 6, 16, 0, 2, 0, - 0, 0, 54, 0, 0, 5, - 18, 0, 16, 0, 5, 0, - 0, 0, 10, 16, 16, 0, - 4, 0, 0, 0, 55, 0, - 0, 9, 210, 0, 16, 0, - 5, 0, 0, 0, 246, 15, - 16, 0, 3, 0, 0, 0, - 6, 9, 16, 0, 2, 0, - 0, 0, 6, 9, 16, 0, - 5, 0, 0, 0, 49, 0, - 0, 7, 18, 0, 16, 0, - 2, 0, 0, 0, 42, 16, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 9, - 18, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 16, 0, - 1, 64, 0, 0, 0, 0, - 8, 0, 60, 0, 0, 7, - 66, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 54, 0, 0, 5, 50, 0, - 16, 0, 1, 0, 0, 0, - 70, 16, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 50, 0, 16, 0, 5, 0, - 0, 0, 230, 26, 16, 0, - 1, 0, 0, 0, 55, 0, - 0, 9, 242, 0, 16, 0, - 1, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 70, 14, 16, 0, 1, 0, - 0, 0, 70, 14, 16, 0, - 5, 0, 0, 0, 55, 0, - 0, 9, 98, 0, 16, 0, - 4, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 6, 17, 16, 0, 0, 0, - 0, 0, 166, 27, 16, 0, - 1, 0, 0, 0, 55, 0, - 0, 9, 82, 0, 16, 0, - 0, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 6, 2, 16, 0, 0, 0, - 0, 0, 86, 7, 16, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 34, 0, 16, 0, - 3, 0, 0, 0, 58, 16, - 16, 0, 2, 0, 0, 0, - 54, 0, 0, 5, 66, 0, - 16, 0, 3, 0, 0, 0, - 10, 0, 16, 0, 4, 0, - 0, 0, 54, 0, 0, 5, - 18, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 54, 0, - 0, 5, 34, 0, 16, 0, - 2, 0, 0, 0, 42, 16, - 16, 0, 3, 0, 0, 0, - 55, 0, 0, 9, 178, 0, - 16, 0, 3, 0, 0, 0, - 246, 15, 16, 0, 2, 0, - 0, 0, 70, 8, 16, 0, - 3, 0, 0, 0, 70, 8, - 16, 0, 2, 0, 0, 0, - 24, 0, 0, 7, 18, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 24, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 60, 0, 0, 7, - 18, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 1, 0, 0, 7, 34, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 28, 79, 0, - 0, 7, 66, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 8, - 26, 0, 16, 0, 2, 0, - 0, 0, 60, 0, 0, 7, - 18, 0, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 31, 0, 4, 3, 10, 0, - 16, 0, 2, 0, 0, 0, - 55, 0, 0, 9, 162, 0, - 16, 0, 0, 0, 0, 0, - 246, 15, 16, 0, 2, 0, - 0, 0, 86, 13, 16, 0, - 0, 0, 0, 0, 6, 20, - 16, 0, 3, 0, 0, 0, - 56, 0, 0, 7, 18, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 63, 49, 0, - 0, 7, 18, 0, 16, 0, - 2, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 55, 0, 0, 9, - 50, 0, 16, 0, 3, 0, - 0, 0, 6, 0, 16, 0, - 2, 0, 0, 0, 150, 5, - 16, 0, 4, 0, 0, 0, - 230, 26, 16, 0, 1, 0, - 0, 0, 55, 0, 0, 9, - 162, 0, 16, 0, 0, 0, - 0, 0, 6, 0, 16, 0, - 2, 0, 0, 0, 6, 8, - 16, 0, 0, 0, 0, 0, - 86, 13, 16, 0, 0, 0, - 0, 0, 15, 0, 0, 7, - 18, 0, 16, 0, 2, 0, - 0, 0, 214, 5, 16, 0, - 0, 0, 0, 0, 214, 5, - 16, 0, 0, 0, 0, 0, - 68, 0, 0, 5, 18, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 56, 0, 0, 7, - 162, 0, 16, 0, 0, 0, - 0, 0, 86, 13, 16, 0, - 0, 0, 0, 0, 6, 0, - 16, 0, 2, 0, 0, 0, - 52, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 191, 51, 0, - 0, 7, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 8, - 18, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 128, - 193, 0, 0, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 75, 0, - 0, 5, 18, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 50, 0, 0, 10, 66, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 48, 110, - 153, 188, 1, 64, 0, 0, - 39, 22, 152, 61, 50, 0, - 0, 10, 66, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 132, 52, - 89, 190, 50, 0, 0, 10, - 66, 0, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 128, 129, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 164, 13, 201, 63, - 56, 0, 0, 7, 18, 0, - 16, 0, 4, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 50, 0, - 0, 9, 18, 0, 16, 0, - 4, 0, 0, 0, 10, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 192, 1, 64, 0, 0, - 219, 15, 73, 64, 49, 0, - 0, 8, 34, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 4, 0, 0, 0, 50, 0, - 0, 9, 34, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 29, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 10, - 34, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 18, 0, 0, 1, 55, 0, - 0, 9, 82, 0, 16, 0, - 2, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 166, 27, 16, 0, 0, 0, - 0, 0, 166, 27, 16, 0, - 1, 0, 0, 0, 1, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 128, 31, 0, 4, 3, - 58, 0, 16, 0, 0, 0, - 0, 0, 54, 0, 0, 5, - 50, 0, 16, 0, 3, 0, - 0, 0, 134, 0, 16, 0, - 2, 0, 0, 0, 54, 0, - 0, 5, 34, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 18, 0, 0, 1, 24, 0, - 0, 7, 130, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 31, 0, 4, 3, - 58, 0, 16, 0, 0, 0, - 0, 0, 14, 0, 0, 7, - 18, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 54, 0, 0, 5, 34, 0, - 16, 0, 5, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 5, - 130, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 18, 0, - 0, 1, 0, 0, 0, 8, - 146, 0, 16, 0, 4, 0, - 0, 0, 86, 9, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 6, 8, 16, 0, - 2, 0, 0, 0, 0, 0, - 0, 8, 194, 0, 16, 0, - 5, 0, 0, 0, 86, 9, - 16, 128, 65, 0, 0, 0, - 4, 0, 0, 0, 166, 30, - 16, 0, 1, 0, 0, 0, - 0, 0, 0, 8, 50, 0, - 16, 0, 6, 0, 0, 0, - 70, 0, 16, 0, 1, 0, - 0, 0, 134, 0, 16, 128, - 65, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 8, - 194, 0, 16, 0, 6, 0, - 0, 0, 6, 12, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 6, 4, 16, 0, - 6, 0, 0, 0, 50, 0, - 0, 12, 194, 0, 16, 0, - 5, 0, 0, 0, 6, 4, - 16, 0, 6, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 64, 192, 0, 0, - 64, 192, 166, 14, 16, 0, - 5, 0, 0, 0, 0, 0, - 0, 7, 130, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 56, 0, 0, 7, - 50, 0, 16, 0, 6, 0, - 0, 0, 246, 15, 16, 0, - 2, 0, 0, 0, 230, 10, - 16, 0, 6, 0, 0, 0, - 56, 0, 0, 7, 130, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 56, 0, - 0, 7, 50, 0, 16, 0, - 7, 0, 0, 0, 246, 15, - 16, 0, 2, 0, 0, 0, - 198, 0, 16, 0, 4, 0, - 0, 0, 0, 0, 0, 7, - 130, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 191, - 51, 0, 0, 7, 130, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 58, 0, 16, 0, - 2, 0, 0, 0, 15, 0, - 0, 7, 66, 0, 16, 0, - 7, 0, 0, 0, 134, 0, - 16, 0, 0, 0, 0, 0, - 134, 0, 16, 0, 0, 0, - 0, 0, 68, 0, 0, 5, - 66, 0, 16, 0, 7, 0, - 0, 0, 42, 0, 16, 0, - 7, 0, 0, 0, 56, 0, - 0, 7, 82, 0, 16, 0, - 0, 0, 0, 0, 6, 2, - 16, 0, 0, 0, 0, 0, - 166, 10, 16, 0, 7, 0, - 0, 0, 0, 0, 0, 7, - 66, 0, 16, 0, 7, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 56, 0, 0, 8, 66, 0, - 16, 0, 7, 0, 0, 0, - 26, 0, 16, 128, 129, 0, - 0, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 7, 0, - 0, 0, 54, 0, 0, 5, - 130, 0, 16, 0, 7, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 18, 0, 16, 0, - 8, 0, 0, 0, 1, 64, - 0, 0, 9, 0, 0, 0, - 48, 0, 0, 1, 34, 0, - 0, 7, 34, 0, 16, 0, - 8, 0, 0, 0, 10, 0, - 16, 0, 8, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 3, 0, 4, 3, - 26, 0, 16, 0, 8, 0, - 0, 0, 43, 0, 0, 5, - 34, 0, 16, 0, 8, 0, - 0, 0, 10, 0, 16, 0, - 8, 0, 0, 0, 25, 0, - 0, 5, 34, 0, 16, 0, - 8, 0, 0, 0, 26, 0, - 16, 0, 8, 0, 0, 0, - 0, 0, 0, 7, 34, 0, - 16, 0, 8, 0, 0, 0, - 58, 0, 16, 0, 7, 0, - 0, 0, 26, 0, 16, 0, - 8, 0, 0, 0, 29, 0, - 0, 7, 66, 0, 16, 0, - 8, 0, 0, 0, 58, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 0, 8, 0, - 0, 0, 50, 0, 0, 9, - 50, 0, 16, 0, 9, 0, - 0, 0, 86, 5, 16, 0, - 8, 0, 0, 0, 230, 10, - 16, 0, 5, 0, 0, 0, - 70, 0, 16, 0, 6, 0, - 0, 0, 50, 0, 0, 9, - 50, 0, 16, 0, 9, 0, - 0, 0, 86, 5, 16, 0, - 8, 0, 0, 0, 70, 0, - 16, 0, 9, 0, 0, 0, - 70, 0, 16, 0, 7, 0, - 0, 0, 15, 0, 0, 7, - 130, 0, 16, 0, 8, 0, - 0, 0, 70, 0, 16, 0, - 9, 0, 0, 0, 70, 0, - 16, 0, 9, 0, 0, 0, - 68, 0, 0, 5, 130, 0, - 16, 0, 8, 0, 0, 0, - 58, 0, 16, 0, 8, 0, - 0, 0, 56, 0, 0, 7, - 50, 0, 16, 0, 9, 0, - 0, 0, 246, 15, 16, 0, - 8, 0, 0, 0, 70, 0, - 16, 0, 9, 0, 0, 0, - 15, 0, 0, 7, 130, 0, - 16, 0, 8, 0, 0, 0, - 70, 0, 16, 0, 9, 0, - 0, 0, 134, 0, 16, 0, - 0, 0, 0, 0, 50, 0, - 0, 10, 18, 0, 16, 0, - 9, 0, 0, 0, 26, 0, - 16, 0, 8, 0, 0, 0, - 26, 0, 16, 128, 193, 0, - 0, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 7, 0, - 0, 0, 51, 0, 0, 7, - 18, 0, 16, 0, 9, 0, - 0, 0, 10, 0, 16, 0, - 9, 0, 0, 0, 1, 64, - 0, 0, 219, 15, 73, 64, - 77, 0, 0, 6, 0, 208, - 0, 0, 18, 0, 16, 0, - 9, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 29, 0, 0, 7, 130, 0, - 16, 0, 8, 0, 0, 0, - 58, 0, 16, 0, 8, 0, - 0, 0, 10, 0, 16, 0, - 9, 0, 0, 0, 55, 0, - 0, 9, 34, 0, 16, 0, - 8, 0, 0, 0, 58, 0, - 16, 0, 8, 0, 0, 0, - 26, 0, 16, 0, 8, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 55, 0, - 0, 9, 130, 0, 16, 0, - 7, 0, 0, 0, 42, 0, - 16, 0, 8, 0, 0, 0, - 26, 0, 16, 0, 8, 0, - 0, 0, 58, 0, 16, 0, - 7, 0, 0, 0, 30, 0, - 0, 7, 18, 0, 16, 0, - 8, 0, 0, 0, 10, 0, - 16, 0, 8, 0, 0, 0, - 1, 64, 0, 0, 255, 255, - 255, 255, 22, 0, 0, 1, - 14, 0, 0, 7, 130, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 7, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 0, 0, - 0, 8, 18, 0, 16, 0, - 6, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 128, 65, 0, - 0, 0, 7, 0, 0, 0, - 52, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 191, 51, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 0, 8, - 34, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 128, - 193, 0, 0, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 75, 0, - 0, 5, 34, 0, 16, 0, - 6, 0, 0, 0, 26, 0, - 16, 0, 6, 0, 0, 0, - 50, 0, 0, 10, 18, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 48, 110, - 153, 188, 1, 64, 0, 0, - 39, 22, 152, 61, 50, 0, - 0, 10, 18, 0, 16, 0, - 7, 0, 0, 0, 10, 0, - 16, 0, 7, 0, 0, 0, - 10, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 132, 52, - 89, 190, 50, 0, 0, 10, - 18, 0, 16, 0, 7, 0, - 0, 0, 10, 0, 16, 0, - 7, 0, 0, 0, 10, 0, - 16, 128, 129, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 164, 13, 201, 63, - 56, 0, 0, 7, 34, 0, - 16, 0, 7, 0, 0, 0, - 26, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 7, 0, 0, 0, 50, 0, - 0, 9, 34, 0, 16, 0, - 7, 0, 0, 0, 26, 0, - 16, 0, 7, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 192, 1, 64, 0, 0, - 219, 15, 73, 64, 49, 0, - 0, 8, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 7, 0, 0, 0, 50, 0, - 0, 9, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 7, 0, 0, 0, - 26, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 29, 0, - 0, 7, 66, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 10, - 18, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 130, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 77, 0, 0, 7, 18, 0, - 16, 0, 7, 0, 0, 0, - 18, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 54, 0, - 0, 6, 34, 0, 16, 0, - 7, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 15, 0, - 0, 7, 66, 0, 16, 0, - 8, 0, 0, 0, 70, 0, - 16, 0, 7, 0, 0, 0, - 230, 10, 16, 0, 5, 0, - 0, 0, 15, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 70, 0, 16, 0, - 7, 0, 0, 0, 230, 10, - 16, 0, 6, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 8, 0, 0, 0, - 70, 0, 16, 0, 7, 0, - 0, 0, 198, 0, 16, 0, - 4, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 8, 0, 0, 0, - 42, 0, 16, 0, 8, 0, - 0, 0, 50, 0, 0, 10, - 66, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 52, 0, 0, 7, 66, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 75, 0, - 0, 5, 66, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 49, 0, 0, 7, 18, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 55, 0, - 0, 10, 66, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 8, - 34, 0, 16, 0, 8, 0, - 0, 0, 10, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 56, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 8, 0, 0, 0, - 42, 0, 16, 0, 8, 0, - 0, 0, 56, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 191, - 50, 0, 0, 9, 66, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 8, 0, - 0, 0, 26, 0, 16, 0, - 8, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 18, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 8, 0, - 0, 0, 10, 0, 16, 0, - 8, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 49, 0, 0, 9, 18, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 129, 0, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 82, 0, - 16, 0, 0, 0, 0, 0, - 6, 0, 16, 0, 0, 0, - 0, 0, 86, 6, 16, 0, - 8, 0, 0, 0, 6, 1, - 16, 0, 8, 0, 0, 0, - 57, 0, 0, 7, 18, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 14, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 4, 0, 0, 0, - 54, 32, 0, 5, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 24, 0, 0, 7, - 66, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 34, 0, - 16, 0, 5, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 52, 0, 0, 7, 18, 0, - 16, 0, 5, 0, 0, 0, - 58, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 21, 0, - 0, 1, 0, 0, 0, 8, - 82, 0, 16, 0, 0, 0, - 0, 0, 86, 6, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 6, 2, 16, 0, - 2, 0, 0, 0, 50, 0, - 0, 9, 82, 0, 16, 0, - 0, 0, 0, 0, 6, 2, - 16, 0, 0, 0, 0, 0, - 6, 0, 16, 0, 5, 0, - 0, 0, 86, 6, 16, 0, - 4, 0, 0, 0, 0, 0, - 0, 8, 50, 0, 16, 0, - 4, 0, 0, 0, 70, 0, - 16, 0, 1, 0, 0, 0, - 134, 0, 16, 128, 65, 0, - 0, 0, 2, 0, 0, 0, - 50, 0, 0, 9, 82, 0, - 16, 0, 2, 0, 0, 0, - 6, 1, 16, 0, 4, 0, - 0, 0, 6, 0, 16, 0, - 5, 0, 0, 0, 6, 2, - 16, 0, 2, 0, 0, 0, - 0, 0, 0, 8, 50, 0, - 16, 0, 4, 0, 0, 0, - 70, 0, 16, 128, 65, 0, - 0, 0, 1, 0, 0, 0, - 230, 26, 16, 0, 1, 0, - 0, 0, 50, 0, 0, 9, - 50, 0, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 4, 0, 0, 0, 6, 0, - 16, 0, 5, 0, 0, 0, - 70, 0, 16, 0, 1, 0, - 0, 0, 0, 0, 0, 8, - 50, 0, 16, 0, 4, 0, - 0, 0, 134, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 134, 0, 16, 0, - 2, 0, 0, 0, 50, 0, - 0, 9, 82, 0, 16, 0, - 0, 0, 0, 0, 6, 1, - 16, 0, 4, 0, 0, 0, - 6, 0, 16, 0, 5, 0, - 0, 0, 6, 2, 16, 0, - 0, 0, 0, 0, 0, 0, - 0, 8, 50, 0, 16, 0, - 1, 0, 0, 0, 134, 0, - 16, 128, 65, 0, 0, 0, - 2, 0, 0, 0, 70, 0, - 16, 0, 1, 0, 0, 0, - 50, 0, 0, 9, 50, 0, - 16, 0, 1, 0, 0, 0, - 70, 0, 16, 0, 1, 0, - 0, 0, 6, 0, 16, 0, - 5, 0, 0, 0, 134, 0, - 16, 0, 2, 0, 0, 0, - 0, 0, 0, 8, 50, 0, - 16, 0, 1, 0, 0, 0, - 134, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 70, 0, 16, 0, 1, 0, - 0, 0, 50, 0, 0, 9, - 50, 0, 16, 0, 3, 0, - 0, 0, 70, 0, 16, 0, - 1, 0, 0, 0, 6, 0, - 16, 0, 5, 0, 0, 0, - 134, 0, 16, 0, 0, 0, - 0, 0, 57, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 15, 0, 0, 7, 66, 0, - 16, 0, 0, 0, 0, 0, - 70, 0, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 1, 0, 0, 0, 68, 0, - 0, 5, 66, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 56, 0, 0, 7, 50, 0, - 16, 0, 1, 0, 0, 0, - 166, 10, 16, 0, 0, 0, - 0, 0, 70, 0, 16, 0, - 1, 0, 0, 0, 52, 0, - 0, 7, 66, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 191, 51, 0, 0, 7, - 66, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 0, 0, 0, 8, 18, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 128, 193, 0, - 0, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 75, 0, 0, 5, - 18, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 1, 0, 0, 0, 50, 0, - 0, 10, 18, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 128, 129, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 48, 110, 153, 188, - 1, 64, 0, 0, 39, 22, - 152, 61, 50, 0, 0, 10, - 18, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 128, 129, 0, 0, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 132, 52, 89, 190, - 50, 0, 0, 10, 18, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 128, - 129, 0, 0, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 164, 13, 201, 63, 56, 0, - 0, 7, 66, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 50, 0, 0, 9, - 66, 0, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 192, - 1, 64, 0, 0, 219, 15, - 73, 64, 49, 0, 0, 8, - 66, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 7, 66, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 2, 0, - 0, 0, 50, 0, 0, 9, - 66, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 29, 0, 0, 7, - 18, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 10, 66, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 55, 0, - 0, 9, 34, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 21, 0, - 0, 1, 21, 0, 0, 1, - 32, 0, 0, 7, 18, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 4, 28, 0, - 0, 5, 194, 0, 16, 0, - 0, 0, 0, 0, 166, 14, - 16, 0, 1, 0, 0, 0, - 41, 0, 0, 7, 66, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 16, 0, 0, 0, 60, 0, - 0, 7, 66, 0, 16, 0, - 0, 0, 0, 0, 58, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 56, 0, 0, 7, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 131, 249, 34, 62, - 29, 0, 0, 8, 130, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 26, 0, 0, 6, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 128, - 129, 0, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 10, - 34, 0, 16, 0, 0, 0, - 0, 0, 58, 0, 16, 0, - 0, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 56, 0, 0, 7, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 219, 15, 201, 64, 55, 0, - 0, 9, 66, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 14, - 16, 0, 3, 0, 0, 0, - 62, 0, 0, 1, 83, 84, - 65, 84, 148, 0, 0, 0, - 220, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 130, 0, - 0, 0, 6, 0, 0, 0, - 22, 0, 0, 0, 4, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 0, - 0, 0, 28, 0, 0, 0, - 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h deleted file mode 100644 index 0bc8d0890..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h +++ /dev/null @@ -1,2369 +0,0 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 10.1 -// -// -// Buffer Definitions: -// -// cbuffer VB -// { -// -// struct -// { -// -// float sa; // Offset: 0 -// float Fa; // Offset: 4 -// float bd; // Offset: 8 -// float cd; // Offset: 12 -// uint Ga; // Offset: 16 -// uint id; // Offset: 20 -// uint Oc; // Offset: 24 -// uint Pc; // Offset: 28 -// int4 J6; // Offset: 32 -// float2 U4; // Offset: 48 -// float2 Ha; // Offset: 56 -// uint Z2; // Offset: 64 -// uint d5; // Offset: 68 -// float C1; // Offset: 72 -// uint jd; // Offset: 76 -// -// } q; // Offset: 0 Size: 80 -// -// } -// -// Resource bind info for JB -// { -// -// uint4 $Element; // Offset: 0 Size: 16 -// -// } -// -// Resource bind info for QC -// { -// -// uint4 $Element; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim HLSL Bind Count -// ------------------------------ ---------- ------- ----------- -------------- ------ -// M8 sampler NA NA s10 1 -// JB texture struct r/o t3 1 -// QC texture struct r/o t6 1 -// JC texture float 1darray t10 1 -// VB cbuffer NA NA cb0 1 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// RC 0 xyzw 0 NONE float xyzw -// SC 0 xyzw 1 NONE float xyzw -// GC 0 xyzw 2 NONE float xyzw -// RB 0 xyzw 3 NONE uint xyzw -// SV_VertexID 0 x 4 VERTID uint x -// SV_InstanceID 0 x 5 INSTID uint -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// TEXCOORD 0 xyzw 0 NONE float xyzw -// TEXCOORD 1 xyzw 1 NONE float xyzw -// TEXCOORD 2 xyzw 2 NONE float xyzw -// TEXCOORD 3 xyz 3 NONE float xyz -// TEXCOORD 4 x 4 NONE uint x -// SV_Position 0 xyzw 5 POS float xyzw -// -vs_5_0 -dcl_globalFlags refactoringAllowed -dcl_constantbuffer CB0[1], immediateIndexed -dcl_sampler s10, mode_default -dcl_resource_structured t3, 16 -dcl_resource_structured t6, 16 -dcl_resource_texture1darray (float,float,float,float) t10 -dcl_input v0.xyzw -dcl_input v1.xyzw -dcl_input v2.xyzw -dcl_input v3.xyzw -dcl_input_sgv v4.x, vertex_id -dcl_output o0.xyzw -dcl_output o1.xyzw -dcl_output o2.xyzw -dcl_output o3.xyz -dcl_output o4.x -dcl_output_siv o5.xyzw, position -dcl_temps 10 -ult r0.x, v4.x, l(4) -movc r0.y, r0.x, v2.z, v2.w -movc r0.x, r0.x, v3.x, v3.y -ibfe r0.z, l(16), l(0), r0.x -ishr r0.x, r0.x, l(16) -itof r0.xz, r0.xxzx -and r1.xy, v4.xxxx, l(1, 2, 0, 0) -movc r0.w, r1.x, r0.x, r0.z -add r1.x, r0.y, l(1.000000) -movc r1.x, r1.y, r0.y, r1.x -add r1.y, -r0.z, r0.x -mul r1.y, r1.y, cb0[0].y -lt r1.y, r1.y, l(0.000000) -mad r0.y, r0.y, l(2.000000), l(1.000000) -add r0.y, -r1.x, r0.y -movc r0.y, r1.y, r0.y, r1.x -ubfe r1.x, l(10), l(10), v3.z -ushr r1.y, v3.z, l(20) -and r2.xyzw, v3.zwww, l(1023, 0x0000ffff, 0x20000000, 0x1e000000) -iadd r1.z, r2.y, l(-1) -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r1.z, r1.z, l(8), t6.xxxx -movc r1.z, v3.w, r1.z, l(0) -ishl r1.w, r1.z, l(2) -bfi r2.y, l(30), l(2), r1.z, l(1) -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r3.xy, r2.y, l(8), t3.xyxx -movc r3.xy, r1.zzzz, r3.xyxx, l(0,0,0,0) -ne r1.z, r3.y, l(0.000000) -eq r2.y, r3.x, l(0.000000) -and r1.z, r1.z, r2.y -if_nz r1.z - add r4.xyzw, -v0.xyzw, v1.zwxy - dp2 r1.z, r4.xyxx, r4.xyxx - sqrt r2.y, r1.z - ne r3.x, r2.y, l(0.000000) - if_nz r3.x - mul r3.xz, r4.yyxy, l(-1.000000, 0.000000, 1.000000, 0.000000) - div r3.xz, r3.xxzx, r2.yyyy - add r5.xy, -v0.xyxx, v1.xyxx - dp2 r2.y, r3.xzxx, r5.xyxx - add r5.xy, -v0.xyxx, v0.zwzz - dp2 r3.x, r3.xzxx, r5.xyxx - add r2.y, -r2.y, r3.x - mul r3.z, r2.y, l(3.000000) - add r2.y, -r2.y, -r3.x - mov r3.w, l(0.500000) - mov r5.x, l(0) - loop - ige r5.y, r5.x, l(3) - breakc_nz r5.y - mul r5.y, r3.w, r3.z - mad r5.y, r5.y, r3.w, -r3.x - mad r5.z, r3.z, r3.w, r2.y - add r5.w, r5.z, r5.z - lt r5.z, r5.z, l(0.000000) - movc r5.y, r5.z, -r5.y, r5.y - lt r5.z, l(0.000000), r5.y - lt r6.x, r5.y, |r5.w| - div r5.y, r5.y, |r5.w| - movc r5.y, r6.x, r5.y, l(1.000000) - and r3.w, r5.y, r5.z - iadd r5.x, r5.x, l(1) - endloop - mul r2.y, r2.y, l(3.000000) - mad r2.y, r3.w, r3.z, r2.y - mul r3.x, r3.x, l(3.000000) - mad r2.y, r3.w, r2.y, r3.x - mul r2.y, r2.y, r3.w - mov r2.y, |r2.y| - else - mov r3.w, l(0.500000) - mov r2.y, l(0) - endif - mul r3.x, r3.y, l(0.333333) - add r5.xyzw, -v0.xyxy, v0.zwzw - add r6.xy, r4.zwzz, -r5.zwzz - mad r7.xyzw, r4.zwzw, l(-3.000000, -3.000000, -3.000000, -3.000000), r4.xyxy - add r8.xyzw, r6.xyxy, r6.xyxy - mad r4.zw, r7.zzzw, r3.wwww, r8.xxxy - mad r4.zw, r4.zzzw, r3.wwww, r5.xxxy - mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 3.000000, 3.000000) - dp2 r3.z, r4.zwzz, r4.zwzz - sqrt r3.z, r3.z - ne r6.z, r3.z, l(0.000000) - if_nz r6.z - div r3.z, l(1.000000, 1.000000, 1.000000, 1.000000), r3.z - mul r4.zw, r3.zzzz, r4.zzzw - dp2 r3.z, r7.zwzz, r4.zwzz - add r6.z, r3.z, r3.z - dp2 r6.x, r6.xyxx, r4.zwzz - mul r6.x, r6.x, l(4.000000) - mad r6.x, r6.z, r3.w, r6.x - mul r6.x, r3.w, r6.x - dp2 r4.z, r5.zwzz, r4.zwzz - mul r4.z, r4.z, l(6.000000) - mad r4.z, r6.x, l(3.000000), r4.z - add r4.w, -r3.w, l(1.000000) - min r4.w, r3.w, r4.w - mul r6.x, r4.w, r4.w - mad r6.x, r6.x, r6.z, r4.z - mul r4.w, r4.w, r6.x - mul r4.w, r4.w, l(0.999900) - min r4.w, r3.x, r4.w - eq r3.z, r3.z, l(0.000000) - if_nz r3.z - div r3.z, r4.w, r4.z - else - div r6.x, l(1.000000, 1.000000, 1.000000, 1.000000), r6.z - mul r4.z, r4.z, r6.x - mul r4.w, -r4.w, r6.x - mul r4.z, r4.z, l(-0.333333) - mul r6.x, r4.w, l(0.500000) - mul r6.y, r4.z, r4.z - mul r6.y, r4.z, r6.y - mad r6.y, r6.x, r6.x, -r6.y - lt r6.z, r6.y, l(0.000000) - sqrt r6.w, r4.z - mul r9.x, r6.w, r6.w - mul r9.x, r6.w, r9.x - div r9.x, r6.x, r9.x - add r9.y, -|r9.x|, l(1.000000) - sqrt r9.y, r9.y - mad r9.z, |r9.x|, l(-0.018729), l(0.074261) - mad r9.z, r9.z, |r9.x|, l(-0.212114) - mad r9.z, r9.z, |r9.x|, l(1.570729) - mul r9.w, r9.y, r9.z - mad r9.w, r9.w, l(-2.000000), l(3.141593) - lt r9.x, r9.x, -r9.x - and r9.x, r9.x, r9.w - mad r9.x, r9.z, r9.y, r9.x - mul r6.w, r6.w, l(-2.000000) - mad r9.x, r9.x, l(0.333333), l(-2.094395) - sincos null, r9.x, r9.x - mul r6.w, r6.w, r9.x - sqrt r6.y, r6.y - add r6.x, r6.y, |r6.x| - log r6.x, r6.x - mul r6.x, r6.x, l(0.333333) - exp r6.x, r6.x - lt r4.w, r4.w, l(0.000000) - movc r4.w, r4.w, -r6.x, r6.x - ne r6.x, r4.w, l(0.000000) - div r4.z, r4.z, r4.w - add r4.z, r4.z, r4.w - and r4.z, r4.z, r6.x - movc r3.z, r6.z, r6.w, r4.z - endif - mov r6.zw, |r3.zzzz| - mov r6.xy, -r6.wwww - add r6.xyzw, r3.wwww, r6.xyzw - mad r7.xyzw, r7.xyzw, r6.xyzw, r8.xyzw - mad r5.xyzw, r7.xyzw, r6.xyzw, r5.xyzw - ne r3.zw, v0.zzzw, v0.xxxy - or r3.z, r3.w, r3.z - ne r4.zw, v0.zzzw, v1.xxxy - or r3.w, r4.w, r4.z - movc r4.zw, r3.wwww, v1.xxxy, v1.zzzw - movc r4.zw, r3.zzzz, v0.zzzw, r4.zzzw - add r4.zw, r4.zzzw, -v0.xxxy - ne r6.xz, v1.xxyx, v1.zzwz - or r3.z, r6.z, r6.x - movc r6.xz, r3.wwww, v0.zzwz, v0.xxyx - movc r3.zw, r3.zzzz, v1.xxxy, r6.xxxz - add r3.zw, -r3.zzzw, v1.zzzw - lt r6.x, r6.y, l(0.001000) - movc r4.zw, r6.xxxx, r4.zzzw, r5.xxxy - lt r5.x, l(0.999000), r6.w - movc r3.zw, r5.xxxx, r3.zzzw, r5.zzzw - dp2 r5.x, r4.zwzz, r3.zwzz - dp2 r4.z, r4.zwzz, r4.zwzz - dp2 r3.z, r3.zwzz, r3.zwzz - mul r3.z, r3.z, r4.z - eq r3.w, r3.z, l(0.000000) - rsq r3.z, r3.z - mul r3.z, r3.z, r5.x - max r3.z, r3.z, l(-1.000000) - min r3.z, r3.z, l(1.000000) - movc r3.z, r3.w, l(1.000000), r3.z - add r3.w, -|r3.z|, l(1.000000) - sqrt r3.w, r3.w - mad r4.z, |r3.z|, l(-0.018729), l(0.074261) - mad r4.z, r4.z, |r3.z|, l(-0.212114) - mad r4.z, r4.z, |r3.z|, l(1.570729) - mul r4.w, r3.w, r4.z - mad r4.w, r4.w, l(-2.000000), l(3.141593) - lt r3.z, r3.z, -r3.z - and r3.z, r3.z, r4.w - mad r3.z, r4.z, r3.w, r3.z - else - mov r3.z, l(0) - endif - mad r3.z, -r3.z, l(0.318310), l(1.000000) - mul r3.x, r3.x, r3.x - div r1.z, r1.z, r3.x - add r1.z, r1.z, l(-1.000000) - mul r1.z, r1.z, l(0.500000) - min r1.z, r1.z, r3.z - min r1.z, r1.z, l(0.990000) - mul r5.x, r1.z, l(0.500000) - mov r5.y, l(1.000000) - sample_l_indexable(texture1darray)(float,float,float,float) r1.z, r5.xyxx, t10.yzxw, s10, l(0.000000) - mad r1.z, r1.z, l(-2.000000), l(1.000000) - mul r1.z, r3.y, r1.z - lt r3.x, l(0.000000), r1.z - lt r3.y, r1.z, r2.y - div r1.z, r1.z, r2.y - movc r1.z, r3.y, r1.z, l(1.000000) - and r1.z, r1.z, r3.x - mad r3.xyzw, r4.xyxy, l(0.333333, 0.333333, 0.666667, 0.666667), v0.xyxy - add r3.xy, r3.xyxx, -v0.zwzz - mad r4.xy, r1.zzzz, r3.xyxx, v0.zwzz - add r3.xy, r3.zwzz, -v1.xyxx - mad r3.xy, r1.zzzz, r3.xyxx, v1.xyxx -else - mov r4.xy, v0.zwzz - mov r3.xy, v1.xyxx -endif -ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r5.xyzw, r1.w, l(0), t3.xyzw -mad r1.zw, r4.xxxy, l(0.000000, 0.000000, -2.000000, -2.000000), r3.xxxy -add r1.zw, r1.zzzw, v0.xxxy -dp2 r6.x, r1.zwzz, r5.xzxx -dp2 r6.y, r1.zwzz, r5.ywyy -mad r1.zw, r3.xxxy, l(0.000000, 0.000000, -2.000000, -2.000000), v1.zzzw -add r1.zw, r4.xxxy, r1.zzzw -dp2 r7.x, r1.zwzz, r5.xzxx -dp2 r7.y, r1.zwzz, r5.ywyy -dp2 r1.z, r6.xyxx, r6.xyxx -dp2 r1.w, r7.xyxx, r7.xyxx -max r1.z, r1.w, r1.z -sqrt r1.z, r1.z -mul r1.z, r1.z, l(3.000000) -sqrt r1.z, r1.z -round_pi r1.z, r1.z -max r1.z, r1.z, l(1.000000) -ftou r1.z, r1.z -umin r1.z, r2.x, r1.z -movc r1.z, r2.z, r1.z, r2.x -iadd r1.w, r1.x, r1.z -iadd r1.w, r1.y, r1.w -iadd r1.w, r1.w, l(-1) -ne r2.xy, r4.xyxx, v0.xyxx -or r2.x, r2.y, r2.x -ne r2.yz, r3.xxyx, r4.xxyx -or r2.y, r2.z, r2.y -movc r5.xy, r2.yyyy, r3.xyxx, v1.zwzz -movc r2.xz, r2.xxxx, r4.xxyx, r5.xxyx -add r2.xz, r2.xxzx, -v0.xxyx -ne r5.xy, r3.xyxx, v1.zwzz -or r5.x, r5.y, r5.x -movc r5.yz, r2.yyyy, r4.xxyx, v0.xxyx -movc r5.xy, r5.xxxx, r3.xyxx, r5.yzyy -add r5.xy, -r5.xyxx, v1.zwzz -dp2 r2.y, r2.xzxx, r5.xyxx -dp2 r5.z, r2.xzxx, r2.xzxx -dp2 r5.w, r5.xyxx, r5.xyxx -mul r5.z, r5.w, r5.z -eq r6.x, r5.z, l(0.000000) -rsq r5.z, r5.z -mul r2.yz, r2.yyzy, r5.zzxz -max r2.y, r2.y, l(-1.000000) -min r2.y, r2.y, l(1.000000) -movc r2.y, r6.x, l(1.000000), r2.y -add r5.z, -|r2.y|, l(1.000000) -sqrt r5.z, r5.z -mad r6.x, |r2.y|, l(-0.018729), l(0.074261) -mad r6.x, r6.x, |r2.y|, l(-0.212114) -mad r6.x, r6.x, |r2.y|, l(1.570729) -mul r6.y, r5.z, r6.x -mad r6.y, r6.y, l(-2.000000), l(3.141593) -lt r2.y, r2.y, -r2.y -and r2.y, r2.y, r6.y -mad r2.y, r6.x, r5.z, r2.y -utof r1.x, r1.x -div r1.x, r2.y, r1.x -add r6.xy, r3.xyxx, -v0.xyxx -add r6.zw, -r4.yyyx, v1.wwwz -mul r2.y, r6.w, r6.y -mad r2.y, r6.x, r6.z, -r2.y -eq r5.z, r2.y, l(0.000000) -mad r2.x, r2.x, r5.y, -r2.z -movc r2.x, r5.z, r2.x, r2.y -lt r2.x, r2.x, l(0.000000) -movc o2.w, r2.x, -r1.x, r1.x -utof r1.x, r1.w -add r1.w, -r0.w, r0.x -add o2.x, -|r1.w|, r1.x -imad r1.z, r1.y, l(1024), r1.z -utof o2.z, r1.z -dp2 r1.z, r5.xyxx, v2.xyxx -dp2 r1.w, v2.xyxx, v2.xyxx -mul r1.w, r1.w, r5.w -eq r2.x, r1.w, l(0.000000) -rsq r1.w, r1.w -mul r1.z, r1.w, r1.z -max r1.z, r1.z, l(-1.000000) -min r1.z, r1.z, l(1.000000) -movc r1.z, r2.x, l(1.000000), r1.z -add r1.w, -|r1.z|, l(1.000000) -sqrt r1.w, r1.w -mad r2.x, |r1.z|, l(-0.018729), l(0.074261) -mad r2.x, r2.x, |r1.z|, l(-0.212114) -mad r2.x, r2.x, |r1.z|, l(1.570729) -mul r2.y, r1.w, r2.x -mad r2.y, r2.y, l(-2.000000), l(3.141593) -lt r1.z, r1.z, -r1.z -and r1.z, r1.z, r2.y -mad r1.z, r2.x, r1.w, r1.z -utof r1.y, r1.y -ieq r1.w, r2.w, l(0x0a000000) -add r2.x, r1.y, l(-2.000000) -movc r1.y, r1.w, r2.x, r1.y -div r1.y, r1.z, r1.y -mul r1.z, r5.y, v2.x -mad r1.z, r5.x, v2.y, -r1.z -lt r1.z, r1.z, l(0.000000) -movc o3.z, r1.z, -r1.y, r1.y -lt r0.x, r0.x, r0.z -or r0.z, v3.w, l(0x00800000) -movc o4.x, r0.x, r0.z, v3.w -mad o5.x, r0.w, l(0.000977), l(-1.000000) -lt r0.x, l(0.000000), cb0[0].y -lt r0.z, cb0[0].y, l(0.000000) -iadd r0.x, -r0.x, r0.z -itof r0.x, r0.x -mad o5.y, r0.y, cb0[0].y, -r0.x -mov r4.zw, v0.xxxy -mov o0.xyzw, r4.zwxy -mov r3.zw, v1.zzzw -mov o1.xyzw, r3.xyzw -mov o2.y, r1.x -mov o5.zw, l(0,0,0,1.000000) -mov o3.xy, v2.xyxx -ret -// Approximately 332 instruction slots used -#endif - -const BYTE g_main[] = -{ - 68, 88, 66, 67, 11, 244, - 197, 21, 189, 32, 150, 132, - 173, 16, 80, 177, 133, 110, - 217, 193, 1, 0, 0, 0, - 52, 45, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 8, 4, 0, 0, 208, 4, - 0, 0, 136, 5, 0, 0, - 152, 44, 0, 0, 82, 68, - 69, 70, 204, 3, 0, 0, - 3, 0, 0, 0, 236, 0, - 0, 0, 5, 0, 0, 0, - 60, 0, 0, 0, 0, 5, - 254, 255, 0, 1, 0, 0, - 164, 3, 0, 0, 82, 68, - 49, 49, 60, 0, 0, 0, - 24, 0, 0, 0, 32, 0, - 0, 0, 40, 0, 0, 0, - 36, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 0, 0, - 220, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 223, 0, 0, 0, - 5, 0, 0, 0, 6, 0, - 0, 0, 1, 0, 0, 0, - 16, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 226, 0, - 0, 0, 5, 0, 0, 0, - 6, 0, 0, 0, 1, 0, - 0, 0, 16, 0, 0, 0, - 6, 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0, 0, - 229, 0, 0, 0, 2, 0, - 0, 0, 5, 0, 0, 0, - 3, 0, 0, 0, 255, 255, - 255, 255, 10, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 232, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 77, 56, - 0, 74, 66, 0, 81, 67, - 0, 74, 67, 0, 86, 66, - 0, 171, 232, 0, 0, 0, - 1, 0, 0, 0, 52, 1, - 0, 0, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 223, 0, 0, 0, - 1, 0, 0, 0, 32, 3, - 0, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 226, 0, 0, 0, - 1, 0, 0, 0, 124, 3, - 0, 0, 16, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 92, 1, 0, 0, - 0, 0, 0, 0, 80, 0, - 0, 0, 2, 0, 0, 0, - 252, 2, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 113, 0, 60, 117, 110, 110, - 97, 109, 101, 100, 62, 0, - 115, 97, 0, 102, 108, 111, - 97, 116, 0, 171, 171, 171, - 0, 0, 3, 0, 1, 0, - 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 107, 1, 0, 0, - 70, 97, 0, 98, 100, 0, - 99, 100, 0, 71, 97, 0, - 100, 119, 111, 114, 100, 0, - 171, 171, 0, 0, 19, 0, - 1, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 164, 1, - 0, 0, 105, 100, 0, 79, - 99, 0, 80, 99, 0, 74, - 54, 0, 105, 110, 116, 52, - 0, 171, 171, 171, 1, 0, - 2, 0, 1, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 220, 1, 0, 0, 85, 52, - 0, 102, 108, 111, 97, 116, - 50, 0, 171, 171, 1, 0, - 3, 0, 1, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 11, 2, 0, 0, 72, 97, - 0, 90, 50, 0, 100, 53, - 0, 67, 49, 0, 106, 100, - 0, 171, 104, 1, 0, 0, - 116, 1, 0, 0, 0, 0, - 0, 0, 152, 1, 0, 0, - 116, 1, 0, 0, 4, 0, - 0, 0, 155, 1, 0, 0, - 116, 1, 0, 0, 8, 0, - 0, 0, 158, 1, 0, 0, - 116, 1, 0, 0, 12, 0, - 0, 0, 161, 1, 0, 0, - 172, 1, 0, 0, 16, 0, - 0, 0, 208, 1, 0, 0, - 172, 1, 0, 0, 20, 0, - 0, 0, 211, 1, 0, 0, - 172, 1, 0, 0, 24, 0, - 0, 0, 214, 1, 0, 0, - 172, 1, 0, 0, 28, 0, - 0, 0, 217, 1, 0, 0, - 228, 1, 0, 0, 32, 0, - 0, 0, 8, 2, 0, 0, - 20, 2, 0, 0, 48, 0, - 0, 0, 56, 2, 0, 0, - 20, 2, 0, 0, 56, 0, - 0, 0, 59, 2, 0, 0, - 172, 1, 0, 0, 64, 0, - 0, 0, 62, 2, 0, 0, - 172, 1, 0, 0, 68, 0, - 0, 0, 65, 2, 0, 0, - 116, 1, 0, 0, 72, 0, - 0, 0, 68, 2, 0, 0, - 172, 1, 0, 0, 76, 0, - 0, 0, 5, 0, 0, 0, - 1, 0, 20, 0, 0, 0, - 15, 0, 72, 2, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 94, 1, - 0, 0, 72, 3, 0, 0, - 0, 0, 0, 0, 16, 0, - 0, 0, 2, 0, 0, 0, - 88, 3, 0, 0, 0, 0, - 0, 0, 255, 255, 255, 255, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 36, 69, 108, 101, 109, 101, - 110, 116, 0, 117, 105, 110, - 116, 52, 0, 171, 1, 0, - 19, 0, 1, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 81, 3, 0, 0, 72, 3, - 0, 0, 0, 0, 0, 0, - 16, 0, 0, 0, 2, 0, - 0, 0, 88, 3, 0, 0, - 0, 0, 0, 0, 255, 255, - 255, 255, 0, 0, 0, 0, - 255, 255, 255, 255, 0, 0, - 0, 0, 77, 105, 99, 114, - 111, 115, 111, 102, 116, 32, - 40, 82, 41, 32, 72, 76, - 83, 76, 32, 83, 104, 97, - 100, 101, 114, 32, 67, 111, - 109, 112, 105, 108, 101, 114, - 32, 49, 48, 46, 49, 0, - 73, 83, 71, 78, 192, 0, - 0, 0, 6, 0, 0, 0, - 8, 0, 0, 0, 152, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 15, 15, 0, 0, 155, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 15, 0, 0, 158, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 2, 0, 0, 0, - 15, 15, 0, 0, 161, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 15, 15, 0, 0, 164, 0, - 0, 0, 0, 0, 0, 0, - 6, 0, 0, 0, 1, 0, - 0, 0, 4, 0, 0, 0, - 1, 1, 0, 0, 176, 0, - 0, 0, 0, 0, 0, 0, - 8, 0, 0, 0, 1, 0, - 0, 0, 5, 0, 0, 0, - 1, 0, 0, 0, 82, 67, - 0, 83, 67, 0, 71, 67, - 0, 82, 66, 0, 83, 86, - 95, 86, 101, 114, 116, 101, - 120, 73, 68, 0, 83, 86, - 95, 73, 110, 115, 116, 97, - 110, 99, 101, 73, 68, 0, - 171, 171, 79, 83, 71, 78, - 176, 0, 0, 0, 6, 0, - 0, 0, 8, 0, 0, 0, - 152, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 152, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 1, 0, - 0, 0, 15, 0, 0, 0, - 152, 0, 0, 0, 2, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 2, 0, - 0, 0, 15, 0, 0, 0, - 152, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 3, 0, - 0, 0, 7, 8, 0, 0, - 152, 0, 0, 0, 4, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 4, 0, - 0, 0, 1, 14, 0, 0, - 161, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 5, 0, - 0, 0, 15, 0, 0, 0, - 84, 69, 88, 67, 79, 79, - 82, 68, 0, 83, 86, 95, - 80, 111, 115, 105, 116, 105, - 111, 110, 0, 171, 171, 171, - 83, 72, 69, 88, 8, 39, - 0, 0, 80, 0, 1, 0, - 194, 9, 0, 0, 106, 8, - 0, 1, 89, 0, 0, 4, - 70, 142, 32, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 90, 0, 0, 3, 0, 96, - 16, 0, 10, 0, 0, 0, - 162, 0, 0, 4, 0, 112, - 16, 0, 3, 0, 0, 0, - 16, 0, 0, 0, 162, 0, - 0, 4, 0, 112, 16, 0, - 6, 0, 0, 0, 16, 0, - 0, 0, 88, 56, 0, 4, - 0, 112, 16, 0, 10, 0, - 0, 0, 85, 85, 0, 0, - 95, 0, 0, 3, 242, 16, - 16, 0, 0, 0, 0, 0, - 95, 0, 0, 3, 242, 16, - 16, 0, 1, 0, 0, 0, - 95, 0, 0, 3, 242, 16, - 16, 0, 2, 0, 0, 0, - 95, 0, 0, 3, 242, 16, - 16, 0, 3, 0, 0, 0, - 96, 0, 0, 4, 18, 16, - 16, 0, 4, 0, 0, 0, - 6, 0, 0, 0, 101, 0, - 0, 3, 242, 32, 16, 0, - 0, 0, 0, 0, 101, 0, - 0, 3, 242, 32, 16, 0, - 1, 0, 0, 0, 101, 0, - 0, 3, 242, 32, 16, 0, - 2, 0, 0, 0, 101, 0, - 0, 3, 114, 32, 16, 0, - 3, 0, 0, 0, 101, 0, - 0, 3, 18, 32, 16, 0, - 4, 0, 0, 0, 103, 0, - 0, 4, 242, 32, 16, 0, - 5, 0, 0, 0, 1, 0, - 0, 0, 104, 0, 0, 2, - 10, 0, 0, 0, 79, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 16, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 4, 0, - 0, 0, 55, 0, 0, 9, - 34, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 42, 16, - 16, 0, 2, 0, 0, 0, - 58, 16, 16, 0, 2, 0, - 0, 0, 55, 0, 0, 9, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 10, 16, - 16, 0, 3, 0, 0, 0, - 26, 16, 16, 0, 3, 0, - 0, 0, 139, 0, 0, 9, - 66, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 16, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 0, 7, - 18, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 1, 64, - 0, 0, 16, 0, 0, 0, - 43, 0, 0, 5, 82, 0, - 16, 0, 0, 0, 0, 0, - 6, 2, 16, 0, 0, 0, - 0, 0, 1, 0, 0, 10, - 50, 0, 16, 0, 1, 0, - 0, 0, 6, 16, 16, 0, - 4, 0, 0, 0, 2, 64, - 0, 0, 1, 0, 0, 0, - 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 130, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 18, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 55, 0, - 0, 9, 18, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 1, 0, 0, 0, 0, 0, - 0, 8, 34, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 56, 0, 0, 8, 34, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 1, 0, - 0, 0, 26, 128, 32, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 49, 0, 0, 7, - 34, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 34, 0, - 16, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 64, 1, 64, - 0, 0, 0, 0, 128, 63, - 0, 0, 0, 8, 34, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 128, 65, 0, - 0, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 0, 0, - 0, 0, 55, 0, 0, 9, - 34, 0, 16, 0, 0, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 138, 0, 0, 9, - 18, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 10, 0, 0, 0, 1, 64, - 0, 0, 10, 0, 0, 0, - 42, 16, 16, 0, 3, 0, - 0, 0, 85, 0, 0, 7, - 34, 0, 16, 0, 1, 0, - 0, 0, 42, 16, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 20, 0, 0, 0, - 1, 0, 0, 10, 242, 0, - 16, 0, 2, 0, 0, 0, - 230, 31, 16, 0, 3, 0, - 0, 0, 2, 64, 0, 0, - 255, 3, 0, 0, 255, 255, - 0, 0, 0, 0, 0, 32, - 0, 0, 0, 30, 30, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 255, 255, - 255, 255, 167, 0, 0, 139, - 2, 131, 0, 128, 131, 153, - 25, 0, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 8, 0, - 0, 0, 6, 112, 16, 0, - 6, 0, 0, 0, 55, 0, - 0, 9, 66, 0, 16, 0, - 1, 0, 0, 0, 58, 16, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 41, 0, - 0, 7, 130, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 2, 0, - 0, 0, 140, 0, 0, 11, - 34, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 30, 0, 0, 0, 1, 64, - 0, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 1, 0, 0, 0, 167, 0, - 0, 139, 2, 131, 0, 128, - 131, 153, 25, 0, 50, 0, - 16, 0, 3, 0, 0, 0, - 26, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 8, 0, 0, 0, 70, 112, - 16, 0, 3, 0, 0, 0, - 55, 0, 0, 12, 50, 0, - 16, 0, 3, 0, 0, 0, - 166, 10, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 3, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 57, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 24, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 31, 0, 4, 3, 42, 0, - 16, 0, 1, 0, 0, 0, - 0, 0, 0, 8, 242, 0, - 16, 0, 4, 0, 0, 0, - 70, 30, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 230, 20, 16, 0, 1, 0, - 0, 0, 15, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 4, 0, 0, 0, 70, 0, - 16, 0, 4, 0, 0, 0, - 75, 0, 0, 5, 34, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 57, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 31, 0, 4, 3, 10, 0, - 16, 0, 3, 0, 0, 0, - 56, 0, 0, 10, 82, 0, - 16, 0, 3, 0, 0, 0, - 86, 4, 16, 0, 4, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 191, 0, 0, - 0, 0, 0, 0, 128, 63, - 0, 0, 0, 0, 14, 0, - 0, 7, 82, 0, 16, 0, - 3, 0, 0, 0, 6, 2, - 16, 0, 3, 0, 0, 0, - 86, 5, 16, 0, 2, 0, - 0, 0, 0, 0, 0, 8, - 50, 0, 16, 0, 5, 0, - 0, 0, 70, 16, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 70, 16, 16, 0, - 1, 0, 0, 0, 15, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 134, 0, - 16, 0, 3, 0, 0, 0, - 70, 0, 16, 0, 5, 0, - 0, 0, 0, 0, 0, 8, - 50, 0, 16, 0, 5, 0, - 0, 0, 70, 16, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 230, 26, 16, 0, - 0, 0, 0, 0, 15, 0, - 0, 7, 18, 0, 16, 0, - 3, 0, 0, 0, 134, 0, - 16, 0, 3, 0, 0, 0, - 70, 0, 16, 0, 5, 0, - 0, 0, 0, 0, 0, 8, - 34, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 64, 64, 0, 0, 0, 9, - 34, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 2, 0, - 0, 0, 10, 0, 16, 128, - 65, 0, 0, 0, 3, 0, - 0, 0, 54, 0, 0, 5, - 130, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 63, 54, 0, - 0, 5, 18, 0, 16, 0, - 5, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 48, 0, 0, 1, 33, 0, - 0, 7, 34, 0, 16, 0, - 5, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 1, 64, 0, 0, 3, 0, - 0, 0, 3, 0, 4, 3, - 26, 0, 16, 0, 5, 0, - 0, 0, 56, 0, 0, 7, - 34, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 50, 0, 0, 10, 34, 0, - 16, 0, 5, 0, 0, 0, - 26, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 3, 0, 0, 0, 50, 0, - 0, 9, 66, 0, 16, 0, - 5, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 0, 0, - 0, 7, 130, 0, 16, 0, - 5, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 42, 0, 16, 0, 5, 0, - 0, 0, 49, 0, 0, 7, - 66, 0, 16, 0, 5, 0, - 0, 0, 42, 0, 16, 0, - 5, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 10, 34, 0, - 16, 0, 5, 0, 0, 0, - 42, 0, 16, 0, 5, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 5, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 49, 0, - 0, 7, 66, 0, 16, 0, - 5, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 26, 0, 16, 0, 5, 0, - 0, 0, 49, 0, 0, 8, - 18, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 58, 0, - 16, 128, 129, 0, 0, 0, - 5, 0, 0, 0, 14, 0, - 0, 8, 34, 0, 16, 0, - 5, 0, 0, 0, 26, 0, - 16, 0, 5, 0, 0, 0, - 58, 0, 16, 128, 129, 0, - 0, 0, 5, 0, 0, 0, - 55, 0, 0, 9, 34, 0, - 16, 0, 5, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 1, 0, 0, 7, 130, 0, - 16, 0, 3, 0, 0, 0, - 26, 0, 16, 0, 5, 0, - 0, 0, 42, 0, 16, 0, - 5, 0, 0, 0, 30, 0, - 0, 7, 18, 0, 16, 0, - 5, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 1, 64, 0, 0, 1, 0, - 0, 0, 22, 0, 0, 1, - 56, 0, 0, 7, 34, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 64, 64, 50, 0, - 0, 9, 34, 0, 16, 0, - 2, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 56, 0, - 0, 7, 18, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 64, 64, 50, 0, 0, 9, - 34, 0, 16, 0, 2, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 56, 0, 0, 7, - 34, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 54, 0, 0, 6, 34, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 128, 129, 0, - 0, 0, 2, 0, 0, 0, - 18, 0, 0, 1, 54, 0, - 0, 5, 130, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 63, - 54, 0, 0, 5, 34, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 21, 0, 0, 1, - 56, 0, 0, 7, 18, 0, - 16, 0, 3, 0, 0, 0, - 26, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 171, 170, 170, 62, 0, 0, - 0, 8, 242, 0, 16, 0, - 5, 0, 0, 0, 70, 20, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 230, 30, - 16, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 50, 0, - 16, 0, 6, 0, 0, 0, - 230, 10, 16, 0, 4, 0, - 0, 0, 230, 10, 16, 128, - 65, 0, 0, 0, 5, 0, - 0, 0, 50, 0, 0, 12, - 242, 0, 16, 0, 7, 0, - 0, 0, 230, 14, 16, 0, - 4, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 64, 192, - 0, 0, 64, 192, 0, 0, - 64, 192, 0, 0, 64, 192, - 70, 4, 16, 0, 4, 0, - 0, 0, 0, 0, 0, 7, - 242, 0, 16, 0, 8, 0, - 0, 0, 70, 4, 16, 0, - 6, 0, 0, 0, 70, 4, - 16, 0, 6, 0, 0, 0, - 50, 0, 0, 9, 194, 0, - 16, 0, 4, 0, 0, 0, - 166, 14, 16, 0, 7, 0, - 0, 0, 246, 15, 16, 0, - 3, 0, 0, 0, 6, 4, - 16, 0, 8, 0, 0, 0, - 50, 0, 0, 9, 194, 0, - 16, 0, 4, 0, 0, 0, - 166, 14, 16, 0, 4, 0, - 0, 0, 246, 15, 16, 0, - 3, 0, 0, 0, 6, 4, - 16, 0, 5, 0, 0, 0, - 56, 0, 0, 10, 194, 0, - 16, 0, 4, 0, 0, 0, - 166, 14, 16, 0, 4, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 64, 64, - 0, 0, 64, 64, 15, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 230, 10, - 16, 0, 4, 0, 0, 0, - 230, 10, 16, 0, 4, 0, - 0, 0, 75, 0, 0, 5, - 66, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 3, 0, 0, 0, 57, 0, - 0, 7, 66, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 31, 0, 4, 3, - 42, 0, 16, 0, 6, 0, - 0, 0, 14, 0, 0, 10, - 66, 0, 16, 0, 3, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 42, 0, - 16, 0, 3, 0, 0, 0, - 56, 0, 0, 7, 194, 0, - 16, 0, 4, 0, 0, 0, - 166, 10, 16, 0, 3, 0, - 0, 0, 166, 14, 16, 0, - 4, 0, 0, 0, 15, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 230, 10, - 16, 0, 7, 0, 0, 0, - 230, 10, 16, 0, 4, 0, - 0, 0, 0, 0, 0, 7, - 66, 0, 16, 0, 6, 0, - 0, 0, 42, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 6, 0, 0, 0, - 70, 0, 16, 0, 6, 0, - 0, 0, 230, 10, 16, 0, - 4, 0, 0, 0, 56, 0, - 0, 7, 18, 0, 16, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 6, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 64, 50, 0, 0, 9, - 18, 0, 16, 0, 6, 0, - 0, 0, 42, 0, 16, 0, - 6, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 56, 0, 0, 7, - 18, 0, 16, 0, 6, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 0, 6, 0, 0, 0, - 15, 0, 0, 7, 66, 0, - 16, 0, 4, 0, 0, 0, - 230, 10, 16, 0, 5, 0, - 0, 0, 230, 10, 16, 0, - 4, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 192, 64, 50, 0, 0, 9, - 66, 0, 16, 0, 4, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 64, 64, - 42, 0, 16, 0, 4, 0, - 0, 0, 0, 0, 0, 8, - 130, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 51, 0, - 0, 7, 130, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 56, 0, 0, 7, - 18, 0, 16, 0, 6, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 50, 0, 0, 9, 18, 0, - 16, 0, 6, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 42, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 56, 0, 0, 7, 130, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 56, 0, - 0, 7, 130, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 114, 249, - 127, 63, 51, 0, 0, 7, - 130, 0, 16, 0, 4, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 24, 0, 0, 7, 66, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 31, 0, - 4, 3, 42, 0, 16, 0, - 3, 0, 0, 0, 14, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 18, 0, 0, 1, - 14, 0, 0, 10, 18, 0, - 16, 0, 6, 0, 0, 0, - 2, 64, 0, 0, 0, 0, - 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, - 128, 63, 42, 0, 16, 0, - 6, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 56, 0, 0, 8, - 130, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 4, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 171, 170, - 170, 190, 56, 0, 0, 7, - 18, 0, 16, 0, 6, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 63, - 56, 0, 0, 7, 34, 0, - 16, 0, 6, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 56, 0, - 0, 7, 34, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 26, 0, 16, 0, 6, 0, - 0, 0, 50, 0, 0, 10, - 34, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 6, 0, 0, 0, - 26, 0, 16, 128, 65, 0, - 0, 0, 6, 0, 0, 0, - 49, 0, 0, 7, 66, 0, - 16, 0, 6, 0, 0, 0, - 26, 0, 16, 0, 6, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 75, 0, - 0, 5, 130, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 56, 0, 0, 7, 18, 0, - 16, 0, 9, 0, 0, 0, - 58, 0, 16, 0, 6, 0, - 0, 0, 58, 0, 16, 0, - 6, 0, 0, 0, 56, 0, - 0, 7, 18, 0, 16, 0, - 9, 0, 0, 0, 58, 0, - 16, 0, 6, 0, 0, 0, - 10, 0, 16, 0, 9, 0, - 0, 0, 14, 0, 0, 7, - 18, 0, 16, 0, 9, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 0, 0, 0, 8, 34, 0, - 16, 0, 9, 0, 0, 0, - 10, 0, 16, 128, 193, 0, - 0, 0, 9, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 75, 0, 0, 5, - 34, 0, 16, 0, 9, 0, - 0, 0, 26, 0, 16, 0, - 9, 0, 0, 0, 50, 0, - 0, 10, 66, 0, 16, 0, - 9, 0, 0, 0, 10, 0, - 16, 128, 129, 0, 0, 0, - 9, 0, 0, 0, 1, 64, - 0, 0, 48, 110, 153, 188, - 1, 64, 0, 0, 39, 22, - 152, 61, 50, 0, 0, 10, - 66, 0, 16, 0, 9, 0, - 0, 0, 42, 0, 16, 0, - 9, 0, 0, 0, 10, 0, - 16, 128, 129, 0, 0, 0, - 9, 0, 0, 0, 1, 64, - 0, 0, 132, 52, 89, 190, - 50, 0, 0, 10, 66, 0, - 16, 0, 9, 0, 0, 0, - 42, 0, 16, 0, 9, 0, - 0, 0, 10, 0, 16, 128, - 129, 0, 0, 0, 9, 0, - 0, 0, 1, 64, 0, 0, - 164, 13, 201, 63, 56, 0, - 0, 7, 130, 0, 16, 0, - 9, 0, 0, 0, 26, 0, - 16, 0, 9, 0, 0, 0, - 42, 0, 16, 0, 9, 0, - 0, 0, 50, 0, 0, 9, - 130, 0, 16, 0, 9, 0, - 0, 0, 58, 0, 16, 0, - 9, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 192, - 1, 64, 0, 0, 219, 15, - 73, 64, 49, 0, 0, 8, - 18, 0, 16, 0, 9, 0, - 0, 0, 10, 0, 16, 0, - 9, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 9, 0, 0, 0, 1, 0, - 0, 7, 18, 0, 16, 0, - 9, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 58, 0, 16, 0, 9, 0, - 0, 0, 50, 0, 0, 9, - 18, 0, 16, 0, 9, 0, - 0, 0, 42, 0, 16, 0, - 9, 0, 0, 0, 26, 0, - 16, 0, 9, 0, 0, 0, - 10, 0, 16, 0, 9, 0, - 0, 0, 56, 0, 0, 7, - 130, 0, 16, 0, 6, 0, - 0, 0, 58, 0, 16, 0, - 6, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 192, - 50, 0, 0, 9, 18, 0, - 16, 0, 9, 0, 0, 0, - 10, 0, 16, 0, 9, 0, - 0, 0, 1, 64, 0, 0, - 171, 170, 170, 62, 1, 64, - 0, 0, 146, 10, 6, 192, - 77, 0, 0, 6, 0, 208, - 0, 0, 18, 0, 16, 0, - 9, 0, 0, 0, 10, 0, - 16, 0, 9, 0, 0, 0, - 56, 0, 0, 7, 130, 0, - 16, 0, 6, 0, 0, 0, - 58, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 9, 0, 0, 0, 75, 0, - 0, 5, 34, 0, 16, 0, - 6, 0, 0, 0, 26, 0, - 16, 0, 6, 0, 0, 0, - 0, 0, 0, 8, 18, 0, - 16, 0, 6, 0, 0, 0, - 26, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 128, - 129, 0, 0, 0, 6, 0, - 0, 0, 47, 0, 0, 5, - 18, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 56, 0, - 0, 7, 18, 0, 16, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 6, 0, 0, 0, - 1, 64, 0, 0, 171, 170, - 170, 62, 25, 0, 0, 5, - 18, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 49, 0, - 0, 7, 130, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 10, - 130, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 4, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 6, 0, 0, 0, 10, 0, - 16, 0, 6, 0, 0, 0, - 57, 0, 0, 7, 18, 0, - 16, 0, 6, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 14, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 0, 0, 0, 7, - 66, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 1, 0, 0, 7, 66, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 55, 0, - 0, 9, 66, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 6, 0, 0, 0, - 58, 0, 16, 0, 6, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 21, 0, - 0, 1, 54, 0, 0, 6, - 194, 0, 16, 0, 6, 0, - 0, 0, 166, 10, 16, 128, - 129, 0, 0, 0, 3, 0, - 0, 0, 54, 0, 0, 6, - 50, 0, 16, 0, 6, 0, - 0, 0, 246, 15, 16, 128, - 65, 0, 0, 0, 6, 0, - 0, 0, 0, 0, 0, 7, - 242, 0, 16, 0, 6, 0, - 0, 0, 246, 15, 16, 0, - 3, 0, 0, 0, 70, 14, - 16, 0, 6, 0, 0, 0, - 50, 0, 0, 9, 242, 0, - 16, 0, 7, 0, 0, 0, - 70, 14, 16, 0, 7, 0, - 0, 0, 70, 14, 16, 0, - 6, 0, 0, 0, 70, 14, - 16, 0, 8, 0, 0, 0, - 50, 0, 0, 9, 242, 0, - 16, 0, 5, 0, 0, 0, - 70, 14, 16, 0, 7, 0, - 0, 0, 70, 14, 16, 0, - 6, 0, 0, 0, 70, 14, - 16, 0, 5, 0, 0, 0, - 57, 0, 0, 7, 194, 0, - 16, 0, 3, 0, 0, 0, - 166, 30, 16, 0, 0, 0, - 0, 0, 6, 20, 16, 0, - 0, 0, 0, 0, 60, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 57, 0, 0, 7, - 194, 0, 16, 0, 4, 0, - 0, 0, 166, 30, 16, 0, - 0, 0, 0, 0, 6, 20, - 16, 0, 1, 0, 0, 0, - 60, 0, 0, 7, 130, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 55, 0, - 0, 9, 194, 0, 16, 0, - 4, 0, 0, 0, 246, 15, - 16, 0, 3, 0, 0, 0, - 6, 20, 16, 0, 1, 0, - 0, 0, 166, 30, 16, 0, - 1, 0, 0, 0, 55, 0, - 0, 9, 194, 0, 16, 0, - 4, 0, 0, 0, 166, 10, - 16, 0, 3, 0, 0, 0, - 166, 30, 16, 0, 0, 0, - 0, 0, 166, 14, 16, 0, - 4, 0, 0, 0, 0, 0, - 0, 8, 194, 0, 16, 0, - 4, 0, 0, 0, 166, 14, - 16, 0, 4, 0, 0, 0, - 6, 20, 16, 128, 65, 0, - 0, 0, 0, 0, 0, 0, - 57, 0, 0, 7, 82, 0, - 16, 0, 6, 0, 0, 0, - 6, 17, 16, 0, 1, 0, - 0, 0, 166, 27, 16, 0, - 1, 0, 0, 0, 60, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 6, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 55, 0, 0, 9, - 82, 0, 16, 0, 6, 0, - 0, 0, 246, 15, 16, 0, - 3, 0, 0, 0, 166, 27, - 16, 0, 0, 0, 0, 0, - 6, 17, 16, 0, 0, 0, - 0, 0, 55, 0, 0, 9, - 194, 0, 16, 0, 3, 0, - 0, 0, 166, 10, 16, 0, - 3, 0, 0, 0, 6, 20, - 16, 0, 1, 0, 0, 0, - 6, 8, 16, 0, 6, 0, - 0, 0, 0, 0, 0, 8, - 194, 0, 16, 0, 3, 0, - 0, 0, 166, 14, 16, 128, - 65, 0, 0, 0, 3, 0, - 0, 0, 166, 30, 16, 0, - 1, 0, 0, 0, 49, 0, - 0, 7, 18, 0, 16, 0, - 6, 0, 0, 0, 26, 0, - 16, 0, 6, 0, 0, 0, - 1, 64, 0, 0, 111, 18, - 131, 58, 55, 0, 0, 9, - 194, 0, 16, 0, 4, 0, - 0, 0, 6, 0, 16, 0, - 6, 0, 0, 0, 166, 14, - 16, 0, 4, 0, 0, 0, - 6, 4, 16, 0, 5, 0, - 0, 0, 49, 0, 0, 7, - 18, 0, 16, 0, 5, 0, - 0, 0, 1, 64, 0, 0, - 119, 190, 127, 63, 58, 0, - 16, 0, 6, 0, 0, 0, - 55, 0, 0, 9, 194, 0, - 16, 0, 3, 0, 0, 0, - 6, 0, 16, 0, 5, 0, - 0, 0, 166, 14, 16, 0, - 3, 0, 0, 0, 166, 14, - 16, 0, 5, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 5, 0, 0, 0, - 230, 10, 16, 0, 4, 0, - 0, 0, 230, 10, 16, 0, - 3, 0, 0, 0, 15, 0, - 0, 7, 66, 0, 16, 0, - 4, 0, 0, 0, 230, 10, - 16, 0, 4, 0, 0, 0, - 230, 10, 16, 0, 4, 0, - 0, 0, 15, 0, 0, 7, - 66, 0, 16, 0, 3, 0, - 0, 0, 230, 10, 16, 0, - 3, 0, 0, 0, 230, 10, - 16, 0, 3, 0, 0, 0, - 56, 0, 0, 7, 66, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 4, 0, 0, 0, 24, 0, - 0, 7, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 68, 0, 0, 5, - 66, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 3, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 10, 0, 16, 0, 5, 0, - 0, 0, 52, 0, 0, 7, - 66, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 191, - 51, 0, 0, 7, 66, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 55, 0, - 0, 9, 66, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 42, 0, 16, 0, - 3, 0, 0, 0, 0, 0, - 0, 8, 130, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 128, 193, 0, 0, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 75, 0, 0, 5, 130, 0, - 16, 0, 3, 0, 0, 0, - 58, 0, 16, 0, 3, 0, - 0, 0, 50, 0, 0, 10, - 66, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 128, - 129, 0, 0, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 48, 110, 153, 188, 1, 64, - 0, 0, 39, 22, 152, 61, - 50, 0, 0, 10, 66, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 42, 0, 16, 128, - 129, 0, 0, 0, 3, 0, - 0, 0, 1, 64, 0, 0, - 132, 52, 89, 190, 50, 0, - 0, 10, 66, 0, 16, 0, - 4, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 42, 0, 16, 128, 129, 0, - 0, 0, 3, 0, 0, 0, - 1, 64, 0, 0, 164, 13, - 201, 63, 56, 0, 0, 7, - 130, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 4, 0, 0, 0, - 50, 0, 0, 9, 130, 0, - 16, 0, 4, 0, 0, 0, - 58, 0, 16, 0, 4, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 192, 1, 64, - 0, 0, 219, 15, 73, 64, - 49, 0, 0, 8, 66, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 128, - 65, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 7, - 66, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 3, 0, 0, 0, 58, 0, - 16, 0, 4, 0, 0, 0, - 50, 0, 0, 9, 66, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 4, 0, - 0, 0, 58, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 0, 3, 0, 0, 0, - 18, 0, 0, 1, 54, 0, - 0, 5, 66, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 21, 0, 0, 1, 50, 0, - 0, 10, 66, 0, 16, 0, - 3, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 131, 249, 162, 62, - 1, 64, 0, 0, 0, 0, - 128, 63, 56, 0, 0, 7, - 18, 0, 16, 0, 3, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 10, 0, - 16, 0, 3, 0, 0, 0, - 14, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 3, 0, 0, 0, 0, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 191, 56, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 63, - 51, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 3, 0, 0, 0, 51, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 164, 112, - 125, 63, 56, 0, 0, 7, - 18, 0, 16, 0, 5, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 63, - 54, 0, 0, 5, 34, 0, - 16, 0, 5, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 72, 0, 0, 141, - 194, 1, 0, 128, 67, 85, - 21, 0, 66, 0, 16, 0, - 1, 0, 0, 0, 70, 0, - 16, 0, 5, 0, 0, 0, - 150, 124, 16, 0, 10, 0, - 0, 0, 0, 96, 16, 0, - 10, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 9, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 192, 1, 64, - 0, 0, 0, 0, 128, 63, - 56, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 49, 0, - 0, 7, 18, 0, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 49, 0, 0, 7, - 34, 0, 16, 0, 3, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 14, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 55, 0, - 0, 9, 66, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 1, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 3, 0, - 0, 0, 50, 0, 0, 12, - 242, 0, 16, 0, 3, 0, - 0, 0, 70, 4, 16, 0, - 4, 0, 0, 0, 2, 64, - 0, 0, 171, 170, 170, 62, - 171, 170, 170, 62, 171, 170, - 42, 63, 171, 170, 42, 63, - 70, 20, 16, 0, 0, 0, - 0, 0, 0, 0, 0, 8, - 50, 0, 16, 0, 3, 0, - 0, 0, 70, 0, 16, 0, - 3, 0, 0, 0, 230, 26, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 50, 0, - 0, 9, 50, 0, 16, 0, - 4, 0, 0, 0, 166, 10, - 16, 0, 1, 0, 0, 0, - 70, 0, 16, 0, 3, 0, - 0, 0, 230, 26, 16, 0, - 0, 0, 0, 0, 0, 0, - 0, 8, 50, 0, 16, 0, - 3, 0, 0, 0, 230, 10, - 16, 0, 3, 0, 0, 0, - 70, 16, 16, 128, 65, 0, - 0, 0, 1, 0, 0, 0, - 50, 0, 0, 9, 50, 0, - 16, 0, 3, 0, 0, 0, - 166, 10, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 3, 0, 0, 0, 70, 16, - 16, 0, 1, 0, 0, 0, - 18, 0, 0, 1, 54, 0, - 0, 5, 50, 0, 16, 0, - 4, 0, 0, 0, 230, 26, - 16, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 50, 0, - 16, 0, 3, 0, 0, 0, - 70, 16, 16, 0, 1, 0, - 0, 0, 21, 0, 0, 1, - 167, 0, 0, 139, 2, 131, - 0, 128, 131, 153, 25, 0, - 242, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 70, 126, 16, 0, 3, 0, - 0, 0, 50, 0, 0, 12, - 194, 0, 16, 0, 1, 0, - 0, 0, 6, 4, 16, 0, - 4, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 192, 0, 0, 0, 192, - 6, 4, 16, 0, 3, 0, - 0, 0, 0, 0, 0, 7, - 194, 0, 16, 0, 1, 0, - 0, 0, 166, 14, 16, 0, - 1, 0, 0, 0, 6, 20, - 16, 0, 0, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 6, 0, 0, 0, - 230, 10, 16, 0, 1, 0, - 0, 0, 134, 0, 16, 0, - 5, 0, 0, 0, 15, 0, - 0, 7, 34, 0, 16, 0, - 6, 0, 0, 0, 230, 10, - 16, 0, 1, 0, 0, 0, - 214, 5, 16, 0, 5, 0, - 0, 0, 50, 0, 0, 12, - 194, 0, 16, 0, 1, 0, - 0, 0, 6, 4, 16, 0, - 3, 0, 0, 0, 2, 64, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 192, 0, 0, 0, 192, - 166, 30, 16, 0, 1, 0, - 0, 0, 0, 0, 0, 7, - 194, 0, 16, 0, 1, 0, - 0, 0, 6, 4, 16, 0, - 4, 0, 0, 0, 166, 14, - 16, 0, 1, 0, 0, 0, - 15, 0, 0, 7, 18, 0, - 16, 0, 7, 0, 0, 0, - 230, 10, 16, 0, 1, 0, - 0, 0, 134, 0, 16, 0, - 5, 0, 0, 0, 15, 0, - 0, 7, 34, 0, 16, 0, - 7, 0, 0, 0, 230, 10, - 16, 0, 1, 0, 0, 0, - 214, 5, 16, 0, 5, 0, - 0, 0, 15, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 6, 0, 0, 0, 70, 0, - 16, 0, 6, 0, 0, 0, - 15, 0, 0, 7, 130, 0, - 16, 0, 1, 0, 0, 0, - 70, 0, 16, 0, 7, 0, - 0, 0, 70, 0, 16, 0, - 7, 0, 0, 0, 52, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 75, 0, 0, 5, - 66, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 56, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 64, 64, 75, 0, 0, 5, - 66, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 66, 0, - 0, 5, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 52, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 28, 0, - 0, 5, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 84, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 55, 0, - 0, 9, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 30, 0, - 0, 7, 130, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 30, 0, 0, 7, - 130, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 30, 0, 0, 7, 130, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 255, 255, 255, 255, 57, 0, - 0, 7, 50, 0, 16, 0, - 2, 0, 0, 0, 70, 0, - 16, 0, 4, 0, 0, 0, - 70, 16, 16, 0, 0, 0, - 0, 0, 60, 0, 0, 7, - 18, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 57, 0, 0, 7, 98, 0, - 16, 0, 2, 0, 0, 0, - 6, 1, 16, 0, 3, 0, - 0, 0, 6, 1, 16, 0, - 4, 0, 0, 0, 60, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 0, 2, 0, - 0, 0, 55, 0, 0, 9, - 50, 0, 16, 0, 5, 0, - 0, 0, 86, 5, 16, 0, - 2, 0, 0, 0, 70, 0, - 16, 0, 3, 0, 0, 0, - 230, 26, 16, 0, 1, 0, - 0, 0, 55, 0, 0, 9, - 82, 0, 16, 0, 2, 0, - 0, 0, 6, 0, 16, 0, - 2, 0, 0, 0, 6, 1, - 16, 0, 4, 0, 0, 0, - 6, 1, 16, 0, 5, 0, - 0, 0, 0, 0, 0, 8, - 82, 0, 16, 0, 2, 0, - 0, 0, 6, 2, 16, 0, - 2, 0, 0, 0, 6, 17, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 57, 0, - 0, 7, 50, 0, 16, 0, - 5, 0, 0, 0, 70, 0, - 16, 0, 3, 0, 0, 0, - 230, 26, 16, 0, 1, 0, - 0, 0, 60, 0, 0, 7, - 18, 0, 16, 0, 5, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 55, 0, 0, 9, 98, 0, - 16, 0, 5, 0, 0, 0, - 86, 5, 16, 0, 2, 0, - 0, 0, 6, 1, 16, 0, - 4, 0, 0, 0, 6, 17, - 16, 0, 0, 0, 0, 0, - 55, 0, 0, 9, 50, 0, - 16, 0, 5, 0, 0, 0, - 6, 0, 16, 0, 5, 0, - 0, 0, 70, 0, 16, 0, - 3, 0, 0, 0, 150, 5, - 16, 0, 5, 0, 0, 0, - 0, 0, 0, 8, 50, 0, - 16, 0, 5, 0, 0, 0, - 70, 0, 16, 128, 65, 0, - 0, 0, 5, 0, 0, 0, - 230, 26, 16, 0, 1, 0, - 0, 0, 15, 0, 0, 7, - 34, 0, 16, 0, 2, 0, - 0, 0, 134, 0, 16, 0, - 2, 0, 0, 0, 70, 0, - 16, 0, 5, 0, 0, 0, - 15, 0, 0, 7, 66, 0, - 16, 0, 5, 0, 0, 0, - 134, 0, 16, 0, 2, 0, - 0, 0, 134, 0, 16, 0, - 2, 0, 0, 0, 15, 0, - 0, 7, 130, 0, 16, 0, - 5, 0, 0, 0, 70, 0, - 16, 0, 5, 0, 0, 0, - 70, 0, 16, 0, 5, 0, - 0, 0, 56, 0, 0, 7, - 66, 0, 16, 0, 5, 0, - 0, 0, 58, 0, 16, 0, - 5, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 24, 0, 0, 7, 18, 0, - 16, 0, 6, 0, 0, 0, - 42, 0, 16, 0, 5, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 68, 0, - 0, 5, 66, 0, 16, 0, - 5, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 56, 0, 0, 7, 98, 0, - 16, 0, 2, 0, 0, 0, - 86, 6, 16, 0, 2, 0, - 0, 0, 166, 8, 16, 0, - 5, 0, 0, 0, 52, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 191, 51, 0, 0, 7, - 34, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 55, 0, 0, 9, 34, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 26, 0, - 16, 0, 2, 0, 0, 0, - 0, 0, 0, 8, 66, 0, - 16, 0, 5, 0, 0, 0, - 26, 0, 16, 128, 193, 0, - 0, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 75, 0, 0, 5, - 66, 0, 16, 0, 5, 0, - 0, 0, 42, 0, 16, 0, - 5, 0, 0, 0, 50, 0, - 0, 10, 18, 0, 16, 0, - 6, 0, 0, 0, 26, 0, - 16, 128, 129, 0, 0, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 48, 110, 153, 188, - 1, 64, 0, 0, 39, 22, - 152, 61, 50, 0, 0, 10, - 18, 0, 16, 0, 6, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 26, 0, - 16, 128, 129, 0, 0, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 132, 52, 89, 190, - 50, 0, 0, 10, 18, 0, - 16, 0, 6, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 128, - 129, 0, 0, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 164, 13, 201, 63, 56, 0, - 0, 7, 34, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 10, 0, 16, 0, 6, 0, - 0, 0, 50, 0, 0, 9, - 34, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 0, - 6, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 192, - 1, 64, 0, 0, 219, 15, - 73, 64, 49, 0, 0, 8, - 34, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 128, 65, 0, 0, 0, - 2, 0, 0, 0, 1, 0, - 0, 7, 34, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 0, 6, 0, - 0, 0, 50, 0, 0, 9, - 34, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 6, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 26, 0, 16, 0, 2, 0, - 0, 0, 86, 0, 0, 5, - 18, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 1, 0, 0, 0, 14, 0, - 0, 7, 18, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 0, 0, 0, 8, - 50, 0, 16, 0, 6, 0, - 0, 0, 70, 0, 16, 0, - 3, 0, 0, 0, 70, 16, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 8, 194, 0, 16, 0, - 6, 0, 0, 0, 86, 1, - 16, 128, 65, 0, 0, 0, - 4, 0, 0, 0, 246, 27, - 16, 0, 1, 0, 0, 0, - 56, 0, 0, 7, 34, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 0, - 6, 0, 0, 0, 50, 0, - 0, 10, 34, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 6, 0, 0, 0, - 42, 0, 16, 0, 6, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 2, 0, - 0, 0, 24, 0, 0, 7, - 66, 0, 16, 0, 5, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 50, 0, 0, 10, 18, 0, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 5, 0, 0, 0, 42, 0, - 16, 128, 65, 0, 0, 0, - 2, 0, 0, 0, 55, 0, - 0, 9, 18, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 0, 5, 0, 0, 0, - 10, 0, 16, 0, 2, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 49, 0, - 0, 7, 18, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 55, 0, 0, 10, - 130, 32, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 86, 0, 0, 5, 18, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 0, 0, 0, 8, - 130, 0, 16, 0, 1, 0, - 0, 0, 58, 0, 16, 128, - 65, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 16, 0, - 0, 0, 0, 0, 0, 0, - 0, 8, 18, 32, 16, 0, - 2, 0, 0, 0, 58, 0, - 16, 128, 193, 0, 0, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 1, 0, 0, 0, - 35, 0, 0, 9, 66, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 4, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 86, 0, 0, 5, 66, 32, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 15, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 70, 0, 16, 0, - 5, 0, 0, 0, 70, 16, - 16, 0, 2, 0, 0, 0, - 15, 0, 0, 7, 130, 0, - 16, 0, 1, 0, 0, 0, - 70, 16, 16, 0, 2, 0, - 0, 0, 70, 16, 16, 0, - 2, 0, 0, 0, 56, 0, - 0, 7, 130, 0, 16, 0, - 1, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 0, 5, 0, - 0, 0, 24, 0, 0, 7, - 18, 0, 16, 0, 2, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 68, 0, 0, 5, 130, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 56, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 52, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 191, 51, 0, - 0, 7, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 128, 63, 55, 0, 0, 9, - 66, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 63, - 42, 0, 16, 0, 1, 0, - 0, 0, 0, 0, 0, 8, - 130, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 128, - 193, 0, 0, 0, 1, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 63, 75, 0, - 0, 5, 130, 0, 16, 0, - 1, 0, 0, 0, 58, 0, - 16, 0, 1, 0, 0, 0, - 50, 0, 0, 10, 18, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 128, 129, 0, - 0, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 48, 110, - 153, 188, 1, 64, 0, 0, - 39, 22, 152, 61, 50, 0, - 0, 10, 18, 0, 16, 0, - 2, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 42, 0, 16, 128, 129, 0, - 0, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 132, 52, - 89, 190, 50, 0, 0, 10, - 18, 0, 16, 0, 2, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 42, 0, - 16, 128, 129, 0, 0, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 164, 13, 201, 63, - 56, 0, 0, 7, 34, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 10, 0, 16, 0, - 2, 0, 0, 0, 50, 0, - 0, 9, 34, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 0, 2, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 192, 1, 64, 0, 0, - 219, 15, 73, 64, 49, 0, - 0, 8, 66, 0, 16, 0, - 1, 0, 0, 0, 42, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 128, 65, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 2, 0, 0, 0, 50, 0, - 0, 9, 66, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 58, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 86, 0, - 0, 5, 34, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 1, 0, 0, 0, - 32, 0, 0, 7, 130, 0, - 16, 0, 1, 0, 0, 0, - 58, 0, 16, 0, 2, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 10, 0, 0, - 0, 7, 18, 0, 16, 0, - 2, 0, 0, 0, 26, 0, - 16, 0, 1, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 192, 55, 0, 0, 9, - 34, 0, 16, 0, 1, 0, - 0, 0, 58, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 2, 0, 0, 0, - 26, 0, 16, 0, 1, 0, - 0, 0, 14, 0, 0, 7, - 34, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 26, 0, - 16, 0, 1, 0, 0, 0, - 56, 0, 0, 7, 66, 0, - 16, 0, 1, 0, 0, 0, - 26, 0, 16, 0, 5, 0, - 0, 0, 10, 16, 16, 0, - 2, 0, 0, 0, 50, 0, - 0, 10, 66, 0, 16, 0, - 1, 0, 0, 0, 10, 0, - 16, 0, 5, 0, 0, 0, - 26, 16, 16, 0, 2, 0, - 0, 0, 42, 0, 16, 128, - 65, 0, 0, 0, 1, 0, - 0, 0, 49, 0, 0, 7, - 66, 0, 16, 0, 1, 0, - 0, 0, 42, 0, 16, 0, - 1, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 0, 0, - 55, 0, 0, 10, 66, 32, - 16, 0, 3, 0, 0, 0, - 42, 0, 16, 0, 1, 0, - 0, 0, 26, 0, 16, 128, - 65, 0, 0, 0, 1, 0, - 0, 0, 26, 0, 16, 0, - 1, 0, 0, 0, 49, 0, - 0, 7, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 0, 0, 0, 0, 0, - 42, 0, 16, 0, 0, 0, - 0, 0, 60, 0, 0, 7, - 66, 0, 16, 0, 0, 0, - 0, 0, 58, 16, 16, 0, - 3, 0, 0, 0, 1, 64, - 0, 0, 0, 0, 128, 0, - 55, 0, 0, 9, 18, 32, - 16, 0, 4, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 42, 0, 16, 0, - 0, 0, 0, 0, 58, 16, - 16, 0, 3, 0, 0, 0, - 50, 0, 0, 9, 18, 32, - 16, 0, 5, 0, 0, 0, - 58, 0, 16, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 128, 58, 1, 64, - 0, 0, 0, 0, 128, 191, - 49, 0, 0, 8, 18, 0, - 16, 0, 0, 0, 0, 0, - 1, 64, 0, 0, 0, 0, - 0, 0, 26, 128, 32, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 49, 0, 0, 8, - 66, 0, 16, 0, 0, 0, - 0, 0, 26, 128, 32, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 64, 0, 0, - 0, 0, 0, 0, 30, 0, - 0, 8, 18, 0, 16, 0, - 0, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 42, 0, - 16, 0, 0, 0, 0, 0, - 43, 0, 0, 5, 18, 0, - 16, 0, 0, 0, 0, 0, - 10, 0, 16, 0, 0, 0, - 0, 0, 50, 0, 0, 11, - 34, 32, 16, 0, 5, 0, - 0, 0, 26, 0, 16, 0, - 0, 0, 0, 0, 26, 128, - 32, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, - 16, 128, 65, 0, 0, 0, - 0, 0, 0, 0, 54, 0, - 0, 5, 194, 0, 16, 0, - 4, 0, 0, 0, 6, 20, - 16, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 0, 0, 0, 0, - 230, 4, 16, 0, 4, 0, - 0, 0, 54, 0, 0, 5, - 194, 0, 16, 0, 3, 0, - 0, 0, 166, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 1, 0, 0, 0, 70, 14, - 16, 0, 3, 0, 0, 0, - 54, 0, 0, 5, 34, 32, - 16, 0, 2, 0, 0, 0, - 10, 0, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 8, - 194, 32, 16, 0, 5, 0, - 0, 0, 2, 64, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 128, 63, 54, 0, - 0, 5, 50, 32, 16, 0, - 3, 0, 0, 0, 70, 16, - 16, 0, 2, 0, 0, 0, - 62, 0, 0, 1, 83, 84, - 65, 84, 148, 0, 0, 0, - 76, 1, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, - 11, 0, 0, 0, 223, 0, - 0, 0, 11, 0, 0, 0, - 20, 0, 0, 0, 5, 0, - 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 16, 0, - 0, 0, 31, 0, 0, 0, - 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 -}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.hpp new file mode 100644 index 000000000..eeea34879 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.frag.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "draw_clockwise_atomic_borrowed_coverage.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_clockwise_atomic_borrowed_coverage_frag[] = R"===(#ifdef EB +K3 Ea(ga,Td,S0);L3 void main(){ +#ifdef CB +Y(l1,d); +#else +Y(I,z2); +#endif +B(a3,W0);B(i4,c);d q0= +#ifdef CB +l1; +#else +Xa(I); +#endif +W0 y6=W0(floor(i4));uint N7=a3.y;uint T1=a3.x+ya(y6,N7);uint Ud=q7(abs(q0));uint O7=k.W1|(i5-Ud);uint c3=A7(S0,T1,O7);if(c3>=k.W1){uint oh=c3-max(c3,O7);Fa(S0,T1,oh-Ud);}} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.minified.frag new file mode 100644 index 000000000..31e640672 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_borrowed_coverage.minified.frag @@ -0,0 +1,15 @@ +#ifdef FRAGMENT +K3 Ea(ga,Td,S0);L3 void main(){ +#ifdef DRAW_INTERIOR_TRIANGLES +Y(l1,d); +#else +Y(I,z2); +#endif +B(a3,W0);B(i4,c);d q0= +#ifdef DRAW_INTERIOR_TRIANGLES +l1; +#else +Xa(I); +#endif +W0 y6=W0(floor(i4));uint N7=a3.y;uint T1=a3.x+ya(y6,N7);uint Ud=q7(abs(q0));uint O7=k.W1|(i5-Ud);uint c3=A7(S0,T1,O7);if(c3>=k.W1){uint oh=c3-max(c3,O7);Fa(S0,T1,oh-Ud);}} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.hpp new file mode 100644 index 000000000..dda002f28 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.frag.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "draw_clockwise_atomic_clip.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_clockwise_atomic_clip_frag[] = R"===(#ifdef EB +K1 +#ifndef K +p0(P2,j0); +#endif +ld(Q2,e0);L1 +#ifdef SC +K3 Ea(ga,Td,S0);L3 +#endif +#ifdef K +#define c5 o2 +#define T3(o5) m1=o5;i3 +#else +#define c5 v1 +#define T3(o5) C0(j0,o5);c2; +#endif +c5(HB){ +#ifdef CB +B(l1,d);d q0=l1; +#else +B(I,z2);d q0=I.x; +#endif +#ifdef SC +if(SC){B(a3,W0);B(i4,c);uint N7=a3.y;uint T1=a3.x+ya(W0(floor(i4)),N7);uint p1=kd(S0,T1);d Ya;if(q0>=1.&&(p1=(k.W1|i5))){Ya=.0;}else{d Vd=q0;d g9=q0;if(p1.0){uint Za=Fa(S0,T1,q7(abs(g9)));Vd=Aa(Za)+q0;}Ya=1.-Vd;}C0(e0,B0(Ya));T3(B0(1.))}else +#endif +{C0(e0,B0(q0));T3(B0(.0))}} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.minified.frag new file mode 100644 index 000000000..646b352de --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_clip.minified.frag @@ -0,0 +1,27 @@ +#ifdef FRAGMENT +K1 +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(P2,j0); +#endif +ld(Q2,e0);L1 +#ifdef NESTED_CLIP_UPDATE_ONLY +K3 Ea(ga,Td,S0);L3 +#endif +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +#define c5 o2 +#define T3(o5) m1=o5;i3 +#else +#define c5 v1 +#define T3(o5) C0(j0,o5);c2; +#endif +c5(HB){ +#ifdef DRAW_INTERIOR_TRIANGLES +B(l1,d);d q0=l1; +#else +B(I,z2);d q0=I.x; +#endif +#ifdef NESTED_CLIP_UPDATE_ONLY +if(NESTED_CLIP_UPDATE_ONLY){B(a3,W0);B(i4,c);uint N7=a3.y;uint T1=a3.x+ya(W0(floor(i4)),N7);uint p1=kd(S0,T1);d Ya;if(q0>=1.&&(p1=(k.W1|i5))){Ya=.0;}else{d Vd=q0;d g9=q0;if(p1.0){uint Za=Fa(S0,T1,q7(abs(g9)));Vd=Aa(Za)+q0;}Ya=1.-Vd;}C0(e0,B0(Ya));T3(B0(1.))}else +#endif +{C0(e0,B0(q0));T3(B0(.0))}} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.hpp new file mode 100644 index 000000000..54ade5962 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.frag.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include "draw_clockwise_atomic_path.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_clockwise_atomic_path_frag[] = R"===(#ifdef EB +K1 +#ifndef K +p0(P2,j0); +#endif +p0(Q2,e0); +#ifndef K +md(d6,z6); +#endif +L1 K3 Ea(ga,Td,S0);L3 e void ph(U4(float)l3,d q0,uint T1,g1(uint)p1,g1(d)G3){ +#ifdef K +if(min(l3,q0)>=1.){return;} +#endif +d q;uint Wd=q7(abs(q0));p1=A7(S0,T1,k.W1|Wd);if(p1=1.&&(p1=(k.W1|i5))){return;} +#endif +if(p1.0){uint Za=Fa(S0,T1,ab);d V1=Aa(Za);d H1=V1+Q4;V1=clamp(V1,.0,1.);H1=clamp(H1,.0,1.); +#ifndef K +G3=H1; +#endif +q+=(1.-q*l3)*K8(V1,H1,l3);}l3*=q;}c5(HB){B(k1,g); +#ifdef CB +Y(l1,d); +#else +Y(I,z2); +#endif +B(z0,d); +#ifdef M +B(S1,D); +#endif +#ifdef Z +B(N0,g); +#endif +#ifdef FB +B(Y1,d); +#endif +B(a3,W0);B(i4,c);i F0=M7(k1,1. R2); +#ifndef K +i bb=H0(j0); +#endif +d q0= +#ifdef CB +l1; +#else +Xa(I); +#endif +c y6=i4; +#ifndef K +y6+=(bb.xy+bb.zw)*k.ng; +#endif +y6=floor(y6);uint N7=a3.y;uint T1=a3.x+ya(W0(y6),N7);d I1=1.; +#ifdef Z +if(Z){d cb=d3(X4(N0));I1=min(cb,I1);} +#endif +#ifdef M +if(M&&S1.x!=.0){d db=H0(e0).x;I1=min(db,I1);} +#endif +I1=max(I1,.0);q0=clamp(q0,.0,I1);uint p1;float G3; +#ifndef CB +if(P5(I)){ph(F0.w,q0,T1,p1,G3);}else +#endif +{qh(F0.w,q0,T1,p1,G3);} +#ifdef IB +d E5;if(IB){E5=Z9(T.xy,k.v3,k.w3);} +#endif +#ifndef K +if(F0.w>.0){bool rh=p1>=k.W1&&(p1&e7)!=0u;if(!rh){F0.xyz=R4(F0.xyz,bb,W5(Y1));if(G3<1.){r P7=F0.xyz; +#ifdef IB +if(IB){P7+=E5*k.bd;} +#endif +sg(z6,B0(P7,.0));memoryBarrier();pg(S0,T1,e7);}}else{F0.xyz=rg(z6).xyz;}} +#endif +F0.xyz*=F0.w; +#ifdef IB +if(IB){F0.xyz+=E5;} +#endif +C0(e0,B0(.0));T3(F0);} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.minified.frag new file mode 100644 index 000000000..a398867f4 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_atomic_path.minified.frag @@ -0,0 +1,109 @@ +#ifdef FRAGMENT +K1 +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(P2,j0); +#endif +p0(Q2,e0); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +md(d6,z6); +#endif +L1 K3 Ea(ga,Td,S0);L3 e void ph(U4(float)l3,d q0,uint T1,g1(uint)p1,g1(d)G3){ +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +if(min(l3,q0)>=1.){return;} +#endif +d q;uint Wd=q7(abs(q0));p1=A7(S0,T1,k.W1|Wd);if(p1=1.&&(p1=(k.W1|i5))){return;} +#endif +if(p1.0){uint Za=Fa(S0,T1,ab);d V1=Aa(Za);d H1=V1+Q4;V1=clamp(V1,.0,1.);H1=clamp(H1,.0,1.); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +G3=H1; +#endif +q+=(1.-q*l3)*K8(V1,H1,l3);}l3*=q;}c5(HB){B(k1,g); +#ifdef DRAW_INTERIOR_TRIANGLES +Y(l1,d); +#else +Y(I,z2); +#endif +B(z0,d); +#ifdef ENABLE_CLIPPING +B(S1,D); +#endif +#ifdef ENABLE_CLIP_RECT +B(N0,g); +#endif +#ifdef ENABLE_ADVANCED_BLEND +B(Y1,d); +#endif +B(a3,W0);B(i4,c);i F0=M7(k1,1. R2); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +i bb=H0(j0); +#endif +d q0= +#ifdef DRAW_INTERIOR_TRIANGLES +l1; +#else +Xa(I); +#endif +c y6=i4; +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +y6+=(bb.xy+bb.zw)*k.ng; +#endif +y6=floor(y6);uint N7=a3.y;uint T1=a3.x+ya(W0(y6),N7);d I1=1.; +#ifdef ENABLE_CLIP_RECT +if(ENABLE_CLIP_RECT){d cb=d3(X4(N0));I1=min(cb,I1);} +#endif +#ifdef ENABLE_CLIPPING +if(ENABLE_CLIPPING&&S1.x!=.0){d db=H0(e0).x;I1=min(db,I1);} +#endif +I1=max(I1,.0);q0=clamp(q0,.0,I1);uint p1;float G3; +#ifndef DRAW_INTERIOR_TRIANGLES +if(P5(I)){ph(F0.w,q0,T1,p1,G3);}else +#endif +{qh(F0.w,q0,T1,p1,G3);} +#ifdef ENABLE_DITHER +d E5;if(ENABLE_DITHER){E5=Z9(T.xy,k.v3,k.w3);} +#endif +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +if(F0.w>.0){bool rh=p1>=k.W1&&(p1&e7)!=0u;if(!rh){F0.xyz=R4(F0.xyz,bb,W5(Y1));if(G3<1.){r P7=F0.xyz; +#ifdef ENABLE_DITHER +if(ENABLE_DITHER){P7+=E5*k.bd;} +#endif +sg(z6,B0(P7,.0));memoryBarrier();pg(S0,T1,e7);}}else{F0.xyz=rg(z6).xyz;}} +#endif +F0.xyz*=F0.w; +#ifdef ENABLE_DITHER +if(ENABLE_DITHER){F0.xyz+=E5;} +#endif +C0(e0,B0(.0));T3(F0);} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.hpp new file mode 100644 index 000000000..43d3f1d15 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.frag.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "draw_clockwise_clip.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_clockwise_clip_frag[] = R"===(#ifdef EB +K1 +#ifndef K +p0(P2,j0); +#endif +f1(Q2,e0); +#ifndef K +Q8(d6,f4); +#endif +f1(F6,S0);L1 v1(HB){B(S1,D);d V0=-S1.x; +#ifdef CB +B(l1,d);d q0=l1; +#else +B(I,z2);d q0=I.x; +#endif +v2;D O0;d F5,o3; +#if defined(CB)&&defined(QB) +if(QB){o3=q0;}else +#endif +{O0=unpackHalf2x16(e1(e0));F5=O0.y;d P4=F5==V0?O0.x:G0(.0);o3=P4+q0;} +#ifdef NC +d D5=S1.y;if(NC&&D5!=.0){d j4=.0; +#if defined(CB)&&defined(QB) +if(QB){O0=unpackHalf2x16(e1(e0));F5=O0.y;} +#endif +if(F5!=V0){j4=F5==D5?O0.x:.0;h1(S0,packHalf2x16(A2(j4,qf)));}else{j4=unpackHalf2x16(e1(S0)).x;X1(S0);}o3=min(o3,j4);}else +#endif +{X1(S0);}h1(e0,packHalf2x16(A2(o3,V0))); +#ifndef K +r2(j0); +#endif +w2;c2;} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.minified.frag new file mode 100644 index 000000000..8fb40a214 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_clip.minified.frag @@ -0,0 +1,33 @@ +#ifdef FRAGMENT +K1 +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(P2,j0); +#endif +f1(Q2,e0); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +Q8(d6,f4); +#endif +f1(F6,S0);L1 v1(HB){B(S1,D);d V0=-S1.x; +#ifdef DRAW_INTERIOR_TRIANGLES +B(l1,d);d q0=l1; +#else +B(I,z2);d q0=I.x; +#endif +v2;D O0;d F5,o3; +#if defined(DRAW_INTERIOR_TRIANGLES)&&defined(BORROWED_COVERAGE_PASS) +if(BORROWED_COVERAGE_PASS){o3=q0;}else +#endif +{O0=unpackHalf2x16(e1(e0));F5=O0.y;d P4=F5==V0?O0.x:G0(.0);o3=P4+q0;} +#ifdef ENABLE_NESTED_CLIPPING +d D5=S1.y;if(ENABLE_NESTED_CLIPPING&&D5!=.0){d j4=.0; +#if defined(DRAW_INTERIOR_TRIANGLES)&&defined(BORROWED_COVERAGE_PASS) +if(BORROWED_COVERAGE_PASS){O0=unpackHalf2x16(e1(e0));F5=O0.y;} +#endif +if(F5!=V0){j4=F5==D5?O0.x:.0;h1(S0,packHalf2x16(A2(j4,qf)));}else{j4=unpackHalf2x16(e1(S0)).x;X1(S0);}o3=min(o3,j4);}else +#endif +{X1(S0);}h1(e0,packHalf2x16(A2(o3,V0))); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +r2(j0); +#endif +w2;c2;} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.glsl.hpp deleted file mode 100644 index 20b7ac283..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.glsl.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "draw_clockwise_image_mesh.exports.h" - -namespace rive { -namespace gpu { -namespace glsl { -const char draw_clockwise_image_mesh[] = R"===(#ifdef AB -U0(a2)i0(0,c,SB);V0 U0(v2)i0(1,c,TB);V0 -#endif -o1 n0 H(0,c,q0);p1 -#ifdef AB -P2 Q2 N4(PB,a2,c2,v2,w2,n){l0(n,c2,SB,c);l0(n,w2,TB,c);L(q0,c);c J=C0(D1(m0.H6),SB)+m0.S0;q0=TB;f Q=F2(J);P(q0);h1(Q);} -#endif -#ifdef HB -R2 C2(Y5,W8,UB);S2 p4 G3(X8,B3)q4 w3 x3 e2(i,NB){N(q0,c);i n7=o4(UB,B3,q0);n7=E1(Y3(n7),n7.w*m0.H2);f2(n7);} -#endif -)==="; -} // namespace glsl -} // namespace gpu -} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.minified.glsl deleted file mode 100644 index 6d4172b44..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_image_mesh.minified.glsl +++ /dev/null @@ -1,10 +0,0 @@ -#ifdef VERTEX -U0(a2)i0(0,c,SB);V0 U0(v2)i0(1,c,TB);V0 -#endif -o1 n0 H(0,c,q0);p1 -#ifdef VERTEX -P2 Q2 N4(PB,a2,c2,v2,w2,n){l0(n,c2,SB,c);l0(n,w2,TB,c);L(q0,c);c J=C0(D1(m0.H6),SB)+m0.S0;q0=TB;f Q=F2(J);P(q0);h1(Q);} -#endif -#ifdef FRAGMENT -R2 C2(Y5,W8,UB);S2 p4 G3(X8,B3)q4 w3 x3 e2(i,NB){N(q0,c);i n7=o4(UB,B3,q0);n7=E1(Y3(n7),n7.w*m0.H2);f2(n7);} -#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.hpp new file mode 100644 index 000000000..a793713db --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.frag.hpp @@ -0,0 +1,115 @@ +#pragma once + +#include "draw_clockwise_path.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_clockwise_path_frag[] = R"===(#ifdef EB +K1 +#ifndef K +p0(P2,j0); +#endif +f1(Q2,e0); +#ifndef K +Q8(d6,z6); +#endif +f1(F6,S0);L1 +#ifdef K +o2(HB) +#else +v1(HB) +#endif +{B(k1,g); +#ifdef CB +B(l1,d); +#else +B(I,z2); +#endif +B(z0,d); +#ifdef M +B(S1,D); +#endif +#ifdef Z +B(N0,g); +#endif +#ifdef FB +B(Y1,d); +#endif +d q0= +#ifdef CB +l1; +#else +Xa(I); +#endif +i F0;d I1; +#if defined(CB)&&defined(QB) +if(!QB) +#endif +{F0=M7(k1,1. R2);I1=1.; +#ifdef Z +if(Z){d cb=d3(X4(N0));I1=min(cb,I1);} +#endif +}v2; +#if defined(CB)&&defined(QB) +if(QB){h1(S0,packHalf2x16(A2(q0,z0))); +#ifndef K +r2(j0); +#endif +}else +#endif +{D O4=unpackHalf2x16(e1(S0));d h9=O4.y;d P4=h9==z0?O4.x:G0(.0);d Zd= +#ifndef CB +P5(I)?max(P4,q0): +#endif +P4+q0; +#ifdef M +if(M&&S1.x!=.0){D O0=unpackHalf2x16(e1(e0));d F5=O0.y;d db=F5==S1.x?O0.x:G0(.0);I1=min(db,I1);} +#endif +I1=max(I1,.0);d V1=W9(P4,.0,I1);d H1=W9(Zd,.0,I1); +#ifdef IB +d E5;if(IB){E5=Z9(T.xy,k.v3,k.w3);} +#endif +#ifndef K +i M1=H0(j0); +#ifdef FB +if(FB){if(Y1!=V5(K5)&&H1!=.0){if(V1==.0){F0.xyz=R4(F0.xyz,M1,W5(Y1)); +#ifndef CB +if(H1=1. +#else +#define ae F0.w>=1. +#endif +od(ae,S0,packHalf2x16(A2(Zd,z0))); +#else +X1(S0); +#endif +#ifndef K +nd(F0.w==.0,j0,M1*(1.-F0.w)+F0); +#endif +}X1(e0);w2; +#ifdef K +m1=F0;i3 +#else +c2; +#endif +} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.glsl.hpp deleted file mode 100644 index 60353aad1..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.glsl.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -#include "draw_clockwise_path.exports.h" - -namespace rive { -namespace gpu { -namespace glsl { -const char draw_clockwise_path[] = R"===(#ifdef KC -#ifdef AB -U0(f0)i0(0,f,LB);i0(1,f,MB);V0 -#endif -o1 L2 H(0,a0,j0);n0 H(1,f,D);n0 H(2,c,Q0);L2 H(3,N0,V2);H(4,c,c3);p1 -#ifdef AB -q1(PB,f0,B,n,K){l0(n,B,LB,f);l0(n,B,MB,f);L(j0,a0);L(D,f);L(V2,N0);L(c3,c);f Q;uint R;c J;if(E6(LB,MB,K,R,J,D Y1)){M L3=w0(JB,R*4u+3u);j0=R;V2=L3.xy;c3=J+uintBitsToFloat(L3.zw);Q=F2(J);}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(j0);P(D);P(V2);P(c3);h1(Q);} -#endif -#endif -#ifdef GB -#ifdef AB -U0(f0)i0(0,a4,IB);V0 -#endif -o1 L2 H(0,a0,j0); -#ifdef CB -n0 H(1,c,Q0); -#else -OB H(1,g,i1);L2 H(2,N0,V2);H(3,c,c3); -#endif -p1 -#ifdef AB -q1(PB,f0,B,n,K){l0(n,B,IB,Z); -#ifdef CB -L(Q0,c); -#else -#endif -L(j0,a0); -#ifdef CB -L(Q0,c); -#else -L(i1,g);L(V2,N0);L(c3,c); -#endif -uint R;c J; -#ifdef CB -J=a8(IB,R,Q0 Y1); -#else -J=c8(IB,R,i1 Y1);M L3=w0(JB,R*4u+3u);V2=L3.xy;c3=J+uintBitsToFloat(L3.zw); -#endif -j0=Q1(R);f Q=F2(J);P(j0); -#ifdef CB -P(Q0); -#else -P(i1);P(V2);P(c3); -#endif -h1(Q);} -#endif -#endif -#ifdef HB -w3 g4(l8,W9,DC);h4(m8,X9,KB);Jd(vd,Kf,h5);x3 -#ifdef OC -d void Kd(g o7,uint N1){uint cb=uint(abs(o7)*Z8+.5);uint db=q.Z2|(c6-cb);uint W2=c9(h5,N1,db);if(W2>=q.Z2){uint Ld=W2-max(W2,db);eb(h5,N1,Ld-cb);}} -#endif -d void Md(i4(float)d3,g r0,uint N1){if(min(d3,r0)>=1.){return;}g m;uint Nd=uint(abs(r0)*Z8+.5);uint W2=c9(h5,N1,q.Z2|Nd);if(W2=1.&&(d9=(q.Z2|c6))){return;}g m=.0;uint e9=uint(abs(M3)*Z8+.5);if(d9.0){uint Qd=eb(h5,N1,e9);g g2=N8(int((Qd&Y8)-c6))*a9;g e3=g2+M3;g2=clamp(g2,.0,1.);e3=clamp(e3,.0,1.);g hb=1.-g2*d3;if(hb<=.0)discard;m+=(1.-m*d3)*(e3-g2)/hb;}d3*=m;}e2(i,NB){N(j0,a0); -#ifdef Lf -N(D,f); -#elif defined(CB) -N(Q0,c); -#else -N(i1,g); -#endif -#ifndef CB -N(V2,N0);N(c3,c); -#endif -i I2;uint R=j0;N0 F0=k4(DC,R);uint J1=F0.x&0xfu;if(J1<=q8){I2=unpackUnorm4x8(F0.y);}else{S D0=D1(w0(KB,R*4u));f S0=w0(KB,R*4u+1u);c G2=C0(D0,y0)+S0.xy;if(J1!=ud){float t=J1==O6?G2.x:length(G2);t=clamp(t,.0,1.);float x=t*S0.z+S0.w;float y=uintBitsToFloat(F0.y);I2=T1(MC,r8,c(x,y),.0);}else{float H2=uintBitsToFloat(F0.y);float d6=S0.z;I2=T1(UB,B3,G2,d6);I2=E1(Y3(I2),I2.w*H2);}}if(I2.w==.0){discard;} -#ifdef CB -I2.w*=W6(Q0,q.U4 x1); -#else -uint N1=V2.x;uint Rd=V2.y;N0 i5=N0(floor(c3));N1+=(i5.y>>5)*(Rd<<5)+(i5.x>>5)*(32<<5);N1+=((i5.x&0x1f)>>2)*(32<<2)+((i5.y&0x1f)>>2)*(4<<2);N1+=(i5.y&0x3)*4+(i5.x&0x3); -#ifdef OC -if(OC){ -#ifdef GB -g o7=-i1; -#else -g r0; -#ifdef EB -if(EB&&S6(D)){r0=S4(D x1);}else -#endif -{r0=D.x;}g o7=max(-r0,.0); -#endif -Kd(o7,N1);discard;} -#endif -#ifndef GB -if(U6(D)){g r0; -#ifdef EB -if(EB&&w8(D)){r0=R6(D x1);}else -#endif -{r0=min(D.x,D.y);}r0=clamp(r0,.0,1.);Md(I2.w,r0,N1);}else -#endif -{ -#ifdef GB -g r0=i1; -#else -g r0; -#ifdef EB -if(EB&&S6(D)){r0=S4(D x1);}else -#endif -{r0=D.x;}r0=clamp(r0,.0,1.); -#endif -Od(I2.w,r0,N1);} -#endif -f2(I2);} -#endif -)==="; -} // namespace glsl -} // namespace gpu -} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.frag new file mode 100644 index 000000000..e1e8b3f4d --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.frag @@ -0,0 +1,104 @@ +#ifdef FRAGMENT +K1 +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(P2,j0); +#endif +f1(Q2,e0); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +Q8(d6,z6); +#endif +f1(F6,S0);L1 +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +o2(HB) +#else +v1(HB) +#endif +{B(k1,g); +#ifdef DRAW_INTERIOR_TRIANGLES +B(l1,d); +#else +B(I,z2); +#endif +B(z0,d); +#ifdef ENABLE_CLIPPING +B(S1,D); +#endif +#ifdef ENABLE_CLIP_RECT +B(N0,g); +#endif +#ifdef ENABLE_ADVANCED_BLEND +B(Y1,d); +#endif +d q0= +#ifdef DRAW_INTERIOR_TRIANGLES +l1; +#else +Xa(I); +#endif +i F0;d I1; +#if defined(DRAW_INTERIOR_TRIANGLES)&&defined(BORROWED_COVERAGE_PASS) +if(!BORROWED_COVERAGE_PASS) +#endif +{F0=M7(k1,1. R2);I1=1.; +#ifdef ENABLE_CLIP_RECT +if(ENABLE_CLIP_RECT){d cb=d3(X4(N0));I1=min(cb,I1);} +#endif +}v2; +#if defined(DRAW_INTERIOR_TRIANGLES)&&defined(BORROWED_COVERAGE_PASS) +if(BORROWED_COVERAGE_PASS){h1(S0,packHalf2x16(A2(q0,z0))); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +r2(j0); +#endif +}else +#endif +{D O4=unpackHalf2x16(e1(S0));d h9=O4.y;d P4=h9==z0?O4.x:G0(.0);d Zd= +#ifndef DRAW_INTERIOR_TRIANGLES +P5(I)?max(P4,q0): +#endif +P4+q0; +#ifdef ENABLE_CLIPPING +if(ENABLE_CLIPPING&&S1.x!=.0){D O0=unpackHalf2x16(e1(e0));d F5=O0.y;d db=F5==S1.x?O0.x:G0(.0);I1=min(db,I1);} +#endif +I1=max(I1,.0);d V1=W9(P4,.0,I1);d H1=W9(Zd,.0,I1); +#ifdef ENABLE_DITHER +d E5;if(ENABLE_DITHER){E5=Z9(T.xy,k.v3,k.w3);} +#endif +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +i M1=H0(j0); +#ifdef ENABLE_ADVANCED_BLEND +if(ENABLE_ADVANCED_BLEND){if(Y1!=V5(K5)&&H1!=.0){if(V1==.0){F0.xyz=R4(F0.xyz,M1,W5(Y1)); +#ifndef DRAW_INTERIOR_TRIANGLES +if(H1=1. +#else +#define ae F0.w>=1. +#endif +od(ae,S0,packHalf2x16(A2(Zd,z0))); +#else +X1(S0); +#endif +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +nd(F0.w==.0,j0,M1*(1.-F0.w)+F0); +#endif +}X1(e0);w2; +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +m1=F0;i3 +#else +c2; +#endif +} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.glsl deleted file mode 100644 index 6383edd0e..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_clockwise_path.minified.glsl +++ /dev/null @@ -1,110 +0,0 @@ -#ifdef DRAW_PATH -#ifdef VERTEX -U0(f0)i0(0,f,LB);i0(1,f,MB);V0 -#endif -o1 L2 H(0,a0,j0);n0 H(1,f,D);n0 H(2,c,Q0);L2 H(3,N0,V2);H(4,c,c3);p1 -#ifdef VERTEX -q1(PB,f0,B,n,K){l0(n,B,LB,f);l0(n,B,MB,f);L(j0,a0);L(D,f);L(V2,N0);L(c3,c);f Q;uint R;c J;if(E6(LB,MB,K,R,J,D Y1)){M L3=w0(JB,R*4u+3u);j0=R;V2=L3.xy;c3=J+uintBitsToFloat(L3.zw);Q=F2(J);}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(j0);P(D);P(V2);P(c3);h1(Q);} -#endif -#endif -#ifdef DRAW_INTERIOR_TRIANGLES -#ifdef VERTEX -U0(f0)i0(0,a4,IB);V0 -#endif -o1 L2 H(0,a0,j0); -#ifdef ATLAS_BLIT -n0 H(1,c,Q0); -#else -OPTIONALLY_FLAT H(1,g,i1);L2 H(2,N0,V2);H(3,c,c3); -#endif -p1 -#ifdef VERTEX -q1(PB,f0,B,n,K){l0(n,B,IB,Z); -#ifdef ATLAS_BLIT -L(Q0,c); -#else -#endif -L(j0,a0); -#ifdef ATLAS_BLIT -L(Q0,c); -#else -L(i1,g);L(V2,N0);L(c3,c); -#endif -uint R;c J; -#ifdef ATLAS_BLIT -J=a8(IB,R,Q0 Y1); -#else -J=c8(IB,R,i1 Y1);M L3=w0(JB,R*4u+3u);V2=L3.xy;c3=J+uintBitsToFloat(L3.zw); -#endif -j0=Q1(R);f Q=F2(J);P(j0); -#ifdef ATLAS_BLIT -P(Q0); -#else -P(i1);P(V2);P(c3); -#endif -h1(Q);} -#endif -#endif -#ifdef FRAGMENT -w3 g4(l8,W9,DC);h4(m8,X9,KB);Jd(vd,Kf,h5);x3 -#ifdef BORROWED_COVERAGE_PREPASS -d void Kd(g o7,uint N1){uint cb=uint(abs(o7)*Z8+.5);uint db=q.Z2|(c6-cb);uint W2=c9(h5,N1,db);if(W2>=q.Z2){uint Ld=W2-max(W2,db);eb(h5,N1,Ld-cb);}} -#endif -d void Md(i4(float)d3,g r0,uint N1){if(min(d3,r0)>=1.){return;}g m;uint Nd=uint(abs(r0)*Z8+.5);uint W2=c9(h5,N1,q.Z2|Nd);if(W2=1.&&(d9=(q.Z2|c6))){return;}g m=.0;uint e9=uint(abs(M3)*Z8+.5);if(d9.0){uint Qd=eb(h5,N1,e9);g g2=N8(int((Qd&Y8)-c6))*a9;g e3=g2+M3;g2=clamp(g2,.0,1.);e3=clamp(e3,.0,1.);g hb=1.-g2*d3;if(hb<=.0)discard;m+=(1.-m*d3)*(e3-g2)/hb;}d3*=m;}e2(i,NB){N(j0,a0); -#ifdef Lf -N(D,f); -#elif defined(ATLAS_BLIT) -N(Q0,c); -#else -N(i1,g); -#endif -#ifndef ATLAS_BLIT -N(V2,N0);N(c3,c); -#endif -i I2;uint R=j0;N0 F0=k4(DC,R);uint J1=F0.x&0xfu;if(J1<=q8){I2=unpackUnorm4x8(F0.y);}else{S D0=D1(w0(KB,R*4u));f S0=w0(KB,R*4u+1u);c G2=C0(D0,y0)+S0.xy;if(J1!=ud){float t=J1==O6?G2.x:length(G2);t=clamp(t,.0,1.);float x=t*S0.z+S0.w;float y=uintBitsToFloat(F0.y);I2=T1(MC,r8,c(x,y),.0);}else{float H2=uintBitsToFloat(F0.y);float d6=S0.z;I2=T1(UB,B3,G2,d6);I2=E1(Y3(I2),I2.w*H2);}}if(I2.w==.0){discard;} -#ifdef ATLAS_BLIT -I2.w*=W6(Q0,q.U4 x1); -#else -uint N1=V2.x;uint Rd=V2.y;N0 i5=N0(floor(c3));N1+=(i5.y>>5)*(Rd<<5)+(i5.x>>5)*(32<<5);N1+=((i5.x&0x1f)>>2)*(32<<2)+((i5.y&0x1f)>>2)*(4<<2);N1+=(i5.y&0x3)*4+(i5.x&0x3); -#ifdef BORROWED_COVERAGE_PREPASS -if(BORROWED_COVERAGE_PREPASS){ -#ifdef DRAW_INTERIOR_TRIANGLES -g o7=-i1; -#else -g r0; -#ifdef ENABLE_FEATHER -if(ENABLE_FEATHER&&S6(D)){r0=S4(D x1);}else -#endif -{r0=D.x;}g o7=max(-r0,.0); -#endif -Kd(o7,N1);discard;} -#endif -#ifndef DRAW_INTERIOR_TRIANGLES -if(U6(D)){g r0; -#ifdef ENABLE_FEATHER -if(ENABLE_FEATHER&&w8(D)){r0=R6(D x1);}else -#endif -{r0=min(D.x,D.y);}r0=clamp(r0,.0,1.);Md(I2.w,r0,N1);}else -#endif -{ -#ifdef DRAW_INTERIOR_TRIANGLES -g r0=i1; -#else -g r0; -#ifdef ENABLE_FEATHER -if(ENABLE_FEATHER&&S6(D)){r0=S4(D x1);}else -#endif -{r0=D.x;}r0=clamp(r0,.0,1.); -#endif -Od(I2.w,r0,N1);} -#endif -f2(I2);} -#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_combinations.metal b/thirdparty/rive_renderer/source/generated/shaders/draw_combinations.metal index 5561996ce..2386bd6f4 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_combinations.metal +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_combinations.metal @@ -1,59 +1,72 @@ #define VERTEX -#define ENABLE_CLIPPING 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_ADVANCED_BLEND 1 +#define ENABLE_CLIP_RECT 1 #define ENABLE_FEATHER 1 -namespace p111100000 +#define ENABLE_CLIPPING 1 +#define DRAW_PATH 1 +namespace p1111000000 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" } -#undef ENABLE_CLIPPING -#undef ENABLE_CLIP_RECT +#undef DRAW_PATH #undef ENABLE_ADVANCED_BLEND +#undef ENABLE_CLIP_RECT #undef ENABLE_FEATHER +#undef ENABLE_CLIPPING #undef VERTEX #define FRAGMENT -#define ENABLE_CLIPPING 1 -#define ENABLE_NESTED_CLIPPING 1 -#define ENABLE_ADVANCED_BLEND 1 +#define ENABLE_DITHER 1 #define ENABLE_EVEN_ODD 1 +#define ENABLE_ADVANCED_BLEND 1 #define ENABLE_HSL_BLEND_MODES 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_FEATHER 1 -namespace p111111100 +#define ENABLE_CLIPPING 1 +#define ENABLE_NESTED_CLIPPING 1 +#define ENABLE_CLIP_RECT 1 +#define DRAW_PATH 1 +namespace p1111111100 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" } -#undef ENABLE_CLIPPING -#undef ENABLE_NESTED_CLIPPING -#undef ENABLE_ADVANCED_BLEND +#undef DRAW_PATH +#undef ENABLE_DITHER #undef ENABLE_EVEN_ODD +#undef ENABLE_ADVANCED_BLEND #undef ENABLE_HSL_BLEND_MODES -#undef ENABLE_CLIP_RECT #undef ENABLE_FEATHER +#undef ENABLE_CLIPPING +#undef ENABLE_NESTED_CLIPPING +#undef ENABLE_CLIP_RECT #undef FRAGMENT #define FRAGMENT -#define ENABLE_CLIPPING 1 -#define ENABLE_NESTED_CLIPPING 1 -#define ENABLE_ADVANCED_BLEND 1 +#define ENABLE_DITHER 1 #define ENABLE_EVEN_ODD 1 +#define ENABLE_ADVANCED_BLEND 1 #define ENABLE_HSL_BLEND_MODES 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_FEATHER 1 +#define ENABLE_CLIPPING 1 +#define ENABLE_NESTED_CLIPPING 1 +#define ENABLE_CLIP_RECT 1 #define CLOCKWISE_FILL 1 -namespace c111111100 +#define DRAW_PATH 1 +namespace c1111111100 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" } -#undef ENABLE_CLIPPING -#undef ENABLE_NESTED_CLIPPING -#undef ENABLE_ADVANCED_BLEND +#undef DRAW_PATH +#undef ENABLE_DITHER #undef ENABLE_EVEN_ODD +#undef ENABLE_ADVANCED_BLEND #undef ENABLE_HSL_BLEND_MODES -#undef ENABLE_CLIP_RECT #undef ENABLE_FEATHER +#undef ENABLE_CLIPPING +#undef ENABLE_NESTED_CLIPPING +#undef ENABLE_CLIP_RECT #undef FRAGMENT #undef CLOCKWISE_FILL @@ -61,128 +74,161 @@ namespace c111111100 #define DRAW_INTERIOR_TRIANGLES 1 #define ENABLE_CLIPPING 1 #define ENABLE_ADVANCED_BLEND 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_FEATHER 1 -namespace p111100010 +#define ENABLE_CLIP_RECT 1 +#define DRAW_PATH 1 +namespace p1111000010 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" } +#undef DRAW_PATH #undef DRAW_INTERIOR_TRIANGLES #undef ENABLE_CLIPPING #undef ENABLE_ADVANCED_BLEND -#undef ENABLE_CLIP_RECT #undef ENABLE_FEATHER +#undef ENABLE_CLIP_RECT #undef VERTEX #define FRAGMENT -#define DRAW_INTERIOR_TRIANGLES 1 -#define ENABLE_CLIPPING 1 -#define ENABLE_NESTED_CLIPPING 1 -#define ENABLE_ADVANCED_BLEND 1 +#define ENABLE_DITHER 1 #define ENABLE_EVEN_ODD 1 +#define ENABLE_ADVANCED_BLEND 1 #define ENABLE_HSL_BLEND_MODES 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_FEATHER 1 -namespace p111111110 +#define ENABLE_CLIPPING 1 +#define ENABLE_NESTED_CLIPPING 1 +#define DRAW_INTERIOR_TRIANGLES 1 +#define ENABLE_CLIP_RECT 1 +#define DRAW_PATH 1 +namespace p1111111110 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" } -#undef DRAW_INTERIOR_TRIANGLES -#undef ENABLE_CLIPPING -#undef ENABLE_NESTED_CLIPPING -#undef ENABLE_ADVANCED_BLEND +#undef DRAW_PATH +#undef ENABLE_DITHER #undef ENABLE_EVEN_ODD +#undef ENABLE_ADVANCED_BLEND #undef ENABLE_HSL_BLEND_MODES -#undef ENABLE_CLIP_RECT #undef ENABLE_FEATHER +#undef ENABLE_CLIPPING +#undef ENABLE_NESTED_CLIPPING +#undef DRAW_INTERIOR_TRIANGLES +#undef ENABLE_CLIP_RECT #undef FRAGMENT #define FRAGMENT -#define DRAW_INTERIOR_TRIANGLES 1 -#define ENABLE_CLIPPING 1 -#define ENABLE_NESTED_CLIPPING 1 -#define ENABLE_ADVANCED_BLEND 1 +#define ENABLE_DITHER 1 #define ENABLE_EVEN_ODD 1 +#define ENABLE_ADVANCED_BLEND 1 #define ENABLE_HSL_BLEND_MODES 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_FEATHER 1 +#define ENABLE_CLIPPING 1 +#define ENABLE_NESTED_CLIPPING 1 +#define DRAW_INTERIOR_TRIANGLES 1 +#define ENABLE_CLIP_RECT 1 #define CLOCKWISE_FILL 1 -namespace c111111110 +#define DRAW_PATH 1 +namespace c1111111110 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" } -#undef DRAW_INTERIOR_TRIANGLES -#undef ENABLE_CLIPPING -#undef ENABLE_NESTED_CLIPPING -#undef ENABLE_ADVANCED_BLEND +#undef DRAW_PATH +#undef ENABLE_DITHER #undef ENABLE_EVEN_ODD +#undef ENABLE_ADVANCED_BLEND #undef ENABLE_HSL_BLEND_MODES -#undef ENABLE_CLIP_RECT #undef ENABLE_FEATHER +#undef ENABLE_CLIPPING +#undef ENABLE_NESTED_CLIPPING +#undef DRAW_INTERIOR_TRIANGLES +#undef ENABLE_CLIP_RECT #undef FRAGMENT #undef CLOCKWISE_FILL #define VERTEX +#define ATLAS_BLIT 1 #define ENABLE_ADVANCED_BLEND 1 -#define ENABLE_CLIP_RECT 1 -#define DRAW_INTERIOR_TRIANGLES 1 #define ENABLE_CLIPPING 1 -#define ATLAS_BLIT 1 -namespace p111000011 +#define DRAW_INTERIOR_TRIANGLES 1 +#define ENABLE_CLIP_RECT 1 +#define DRAW_PATH 1 +namespace p1110000011 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_mesh.minified.frag" } +#undef DRAW_PATH +#undef ATLAS_BLIT #undef ENABLE_ADVANCED_BLEND -#undef ENABLE_CLIP_RECT -#undef DRAW_INTERIOR_TRIANGLES #undef ENABLE_CLIPPING -#undef ATLAS_BLIT +#undef DRAW_INTERIOR_TRIANGLES +#undef ENABLE_CLIP_RECT #undef VERTEX #define FRAGMENT +#define ENABLE_DITHER 1 +#define ATLAS_BLIT 1 #define ENABLE_ADVANCED_BLEND 1 #define ENABLE_HSL_BLEND_MODES 1 +#define ENABLE_CLIPPING 1 #define DRAW_INTERIOR_TRIANGLES 1 #define ENABLE_CLIP_RECT 1 -#define ENABLE_CLIPPING 1 -#define ATLAS_BLIT 1 -namespace p111000111 +#define DRAW_PATH 1 +namespace p1110001111 { -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_mesh.minified.frag" } +#undef DRAW_PATH +#undef ENABLE_DITHER +#undef ATLAS_BLIT #undef ENABLE_ADVANCED_BLEND #undef ENABLE_HSL_BLEND_MODES +#undef ENABLE_CLIPPING #undef DRAW_INTERIOR_TRIANGLES #undef ENABLE_CLIP_RECT -#undef ENABLE_CLIPPING -#undef ATLAS_BLIT #undef FRAGMENT #define VERTEX -#define ENABLE_CLIPPING 1 -#define ENABLE_CLIP_RECT 1 #define ENABLE_ADVANCED_BLEND 1 -namespace m111000000 +#define ENABLE_CLIP_RECT 1 +#define ENABLE_CLIPPING 1 +#define DRAW_IMAGE 1 +#define DRAW_IMAGE_MESH 1 +namespace m1110000000 { -#include "draw_image_mesh.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_mesh.minified.frag" } -#undef ENABLE_CLIPPING -#undef ENABLE_CLIP_RECT +#undef DRAW_IMAGE_MESH +#undef DRAW_IMAGE #undef ENABLE_ADVANCED_BLEND +#undef ENABLE_CLIP_RECT +#undef ENABLE_CLIPPING #undef VERTEX #define FRAGMENT +#define ENABLE_DITHER 1 +#define ENABLE_ADVANCED_BLEND 1 +#define ENABLE_HSL_BLEND_MODES 1 #define ENABLE_CLIPPING 1 #define ENABLE_CLIP_RECT 1 -#define ENABLE_HSL_BLEND_MODES 1 -#define ENABLE_ADVANCED_BLEND 1 -namespace m111000100 +#define DRAW_IMAGE 1 +#define DRAW_IMAGE_MESH 1 +namespace m1110001100 { -#include "draw_image_mesh.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_mesh.minified.frag" } +#undef DRAW_IMAGE_MESH +#undef DRAW_IMAGE +#undef ENABLE_DITHER +#undef ENABLE_ADVANCED_BLEND +#undef ENABLE_HSL_BLEND_MODES #undef ENABLE_CLIPPING #undef ENABLE_CLIP_RECT -#undef ENABLE_HSL_BLEND_MODES -#undef ENABLE_ADVANCED_BLEND #undef FRAGMENT diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.minified.vert b/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.minified.vert new file mode 100644 index 000000000..89d16fb6e --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.minified.vert @@ -0,0 +1,3 @@ +#ifdef VERTEX +void main(){gl_Position.x=(gl_VertexID&1)==0?-1.:1.;gl_Position.y=(gl_VertexID&2)==0?-1.:1.;gl_Position.z=0.;gl_Position.w=1.;} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.hpp new file mode 100644 index 000000000..a893a72d9 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_fullscreen_quad.vert.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "draw_fullscreen_quad.vert.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_fullscreen_quad_vert[] = R"===(#ifdef BB +void main(){gl_Position.x=(gl_VertexID&1)==0?-1.:1.;gl_Position.y=(gl_VertexID&2)==0?-1.:1.;gl_Position.z=0.;gl_Position.w=1.;} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.glsl.hpp deleted file mode 100644 index f3f961bc3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.glsl.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include "draw_image_mesh.exports.h" - -namespace rive { -namespace gpu { -namespace glsl { -const char draw_image_mesh[] = R"===(#ifdef AB -U0(a2)i0(0,c,SB);V0 U0(v2)i0(1,c,TB);V0 -#endif -o1 n0 H(0,c,q0); -#ifdef T -OB H(1,g,j5); -#endif -#ifdef BB -n0 H(2,f,R0); -#endif -p1 -#ifdef AB -P2 Q2 N4(PB,a2,c2,v2,w2,n){l0(n,c2,SB,c);l0(n,w2,TB,c);L(q0,c); -#ifdef T -L(j5,g); -#endif -#ifdef BB -L(R0,f); -#endif -c J=C0(D1(m0.H6),SB)+m0.S0;q0=TB; -#ifdef T -if(T){j5=g7(m0.Z0,q.d5);} -#endif -#ifdef BB -if(BB){ -#ifndef DB -R0=I6(D1(m0.R1),m0.Z1,J); -#else -Ka(D1(m0.R1),m0.Z1,J); -#endif -} -#endif -f Q=F2(J); -#ifdef DB -Q.z=S8(m0.X5); -#endif -P(q0); -#ifdef T -P(j5); -#endif -#ifdef BB -P(R0); -#endif -h1(Q);} -#endif -#ifdef HB -R2 C2(Y5,W8,UB); -#ifdef DB -#ifdef FB -C2(U2,Za,PC); -#endif -#endif -S2 p4 G3(X8,B3)q4 w3 x3 -#ifndef DB -x2 M0(i8,H0);Y0(B5,r1);M0(bb,N3);Y0(k8,x4);y2 R4(NB){N(q0,c); -#ifdef T -N(j5,g); -#endif -#ifdef BB -N(R0,f); -#endif -i j=o4(UB,B3,q0);g E=1.; -#ifdef BB -if(BB){g l4=A8(I5(R0));E=clamp(l4,v1(.0),E);} -#endif -h2; -#ifdef T -if(T&&j5!=.0){G I1=unpackHalf2x16(j1(r1));g k5=I1.y;g Sd=k5==j5?I1.x:v1(.0);E=min(E,Sd);} -#endif -i w1=I0(H0); -#ifdef FB -if(FB&&m0.z3!=B8){j.xyz=M4(Y3(j),w1,Q1(m0.z3))*j.w;} -#endif -j*=m0.H2*E;j+=w1*(1.-j.w);T0(H0,j);i2(r1);i2(x4);j2;M2;} -#else -e2(i,NB){N(q0,c);i j=o4(UB,B3,q0)*m0.H2; -#ifdef FB -if(FB){i w1=d1(PC,c0(floor(y0.xy)));j.xyz=M4(Y3(j),w1,m0.z3);j.xyz*=j.w;} -#endif -f2(j);} -#endif -#endif -)==="; -} // namespace glsl -} // namespace gpu -} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.glsl deleted file mode 100644 index f6712c2eb..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.glsl +++ /dev/null @@ -1,82 +0,0 @@ -#ifdef VERTEX -U0(a2)i0(0,c,SB);V0 U0(v2)i0(1,c,TB);V0 -#endif -o1 n0 H(0,c,q0); -#ifdef ENABLE_CLIPPING -OPTIONALLY_FLAT H(1,g,j5); -#endif -#ifdef ENABLE_CLIP_RECT -n0 H(2,f,R0); -#endif -p1 -#ifdef VERTEX -P2 Q2 N4(PB,a2,c2,v2,w2,n){l0(n,c2,SB,c);l0(n,w2,TB,c);L(q0,c); -#ifdef ENABLE_CLIPPING -L(j5,g); -#endif -#ifdef ENABLE_CLIP_RECT -L(R0,f); -#endif -c J=C0(D1(m0.H6),SB)+m0.S0;q0=TB; -#ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING){j5=g7(m0.Z0,q.d5);} -#endif -#ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT){ -#ifndef RENDER_MODE_MSAA -R0=I6(D1(m0.R1),m0.Z1,J); -#else -Ka(D1(m0.R1),m0.Z1,J); -#endif -} -#endif -f Q=F2(J); -#ifdef RENDER_MODE_MSAA -Q.z=S8(m0.X5); -#endif -P(q0); -#ifdef ENABLE_CLIPPING -P(j5); -#endif -#ifdef ENABLE_CLIP_RECT -P(R0); -#endif -h1(Q);} -#endif -#ifdef FRAGMENT -R2 C2(Y5,W8,UB); -#ifdef RENDER_MODE_MSAA -#ifdef ENABLE_ADVANCED_BLEND -C2(U2,Za,PC); -#endif -#endif -S2 p4 G3(X8,B3)q4 w3 x3 -#ifndef RENDER_MODE_MSAA -x2 M0(i8,H0);Y0(B5,r1);M0(bb,N3);Y0(k8,x4);y2 R4(NB){N(q0,c); -#ifdef ENABLE_CLIPPING -N(j5,g); -#endif -#ifdef ENABLE_CLIP_RECT -N(R0,f); -#endif -i j=o4(UB,B3,q0);g E=1.; -#ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT){g l4=A8(I5(R0));E=clamp(l4,v1(.0),E);} -#endif -h2; -#ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING&&j5!=.0){G I1=unpackHalf2x16(j1(r1));g k5=I1.y;g Sd=k5==j5?I1.x:v1(.0);E=min(E,Sd);} -#endif -i w1=I0(H0); -#ifdef ENABLE_ADVANCED_BLEND -if(ENABLE_ADVANCED_BLEND&&m0.z3!=B8){j.xyz=M4(Y3(j),w1,Q1(m0.z3))*j.w;} -#endif -j*=m0.H2*E;j+=w1*(1.-j.w);T0(H0,j);i2(r1);i2(x4);j2;M2;} -#else -e2(i,NB){N(q0,c);i j=o4(UB,B3,q0)*m0.H2; -#ifdef ENABLE_ADVANCED_BLEND -if(ENABLE_ADVANCED_BLEND){i w1=d1(PC,c0(floor(y0.xy)));j.xyz=M4(Y3(j),w1,m0.z3);j.xyz*=j.w;} -#endif -f2(j);} -#endif -#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.vert b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.vert new file mode 100644 index 000000000..700e77dc3 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.minified.vert @@ -0,0 +1,48 @@ +#ifdef VERTEX +A1(e3)r0(0,c,FC);B1 A1(q3)r0(1,c,GC);B1 +#endif +h2 J0 d0(0,c,U0); +#ifdef ENABLE_CLIPPING +OPTIONALLY_FLAT d0(1,d,F3); +#endif +#if defined(ENABLE_CLIP_RECT)&&!defined(RENDER_MODE_MSAA) +J0 d0(2,g,N0); +#endif +Z1 +#ifdef VERTEX +P3 Q3 E6(XB,e3,f3,q3,r3,v){v0(v,f3,FC,c);v0(v,r3,GC,c);Y(U0,c); +#ifdef ENABLE_CLIPPING +Y(F3,d); +#endif +#if defined(ENABLE_CLIP_RECT)&&!defined(RENDER_MODE_MSAA) +Y(N0,g); +#endif +c i0=Z0(j2(A0.r9),FC)+A0.a2;U0=GC; +#ifdef ENABLE_CLIPPING +if(ENABLE_CLIPPING){F3=r8(A0.V0,k.Y5);} +#endif +#ifdef ENABLE_CLIP_RECT +if(ENABLE_CLIP_RECT){ +#ifndef RENDER_MODE_MSAA +N0=T7(j2(A0.k2),A0.D2,i0 r5); +#else +ic(j2(A0.k2),A0.D2,i0 r5); +#endif +} +#endif +g O=H3(i0); +#ifdef POST_INVERT_Y +O.y=-O.y; +#endif +#ifdef RENDER_MODE_MSAA +O.z=ca(A0.Z6); +#endif +l0(U0); +#ifdef ENABLE_CLIPPING +l0(F3); +#endif +#if defined(ENABLE_CLIP_RECT)&&!defined(RENDER_MODE_MSAA) +l0(N0); +#endif +D1(O);} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.hpp new file mode 100644 index 000000000..22bb66a93 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_image_mesh.vert.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include "draw_image_mesh.vert.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_image_mesh_vert[] = R"===(#ifdef BB +A1(e3)r0(0,c,FC);B1 A1(q3)r0(1,c,GC);B1 +#endif +h2 J0 d0(0,c,U0); +#ifdef M +NB d0(1,d,F3); +#endif +#if defined(Z)&&!defined(AB) +J0 d0(2,g,N0); +#endif +Z1 +#ifdef BB +P3 Q3 E6(XB,e3,f3,q3,r3,v){v0(v,f3,FC,c);v0(v,r3,GC,c);Y(U0,c); +#ifdef M +Y(F3,d); +#endif +#if defined(Z)&&!defined(AB) +Y(N0,g); +#endif +c i0=Z0(j2(A0.r9),FC)+A0.a2;U0=GC; +#ifdef M +if(M){F3=r8(A0.V0,k.Y5);} +#endif +#ifdef Z +if(Z){ +#ifndef AB +N0=T7(j2(A0.k2),A0.D2,i0 r5); +#else +ic(j2(A0.k2),A0.D2,i0 r5); +#endif +} +#endif +g O=H3(i0); +#ifdef JC +O.y=-O.y; +#endif +#ifdef AB +O.z=ca(A0.Z6); +#endif +l0(U0); +#ifdef M +l0(F3); +#endif +#if defined(Z)&&!defined(AB) +l0(N0); +#endif +D1(O);} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.hpp new file mode 100644 index 000000000..6c0e6464b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.frag.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "draw_input_attachment.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_input_attachment_frag[] = R"===(#ifdef EB +layout(input_attachment_index=0, +#ifdef NE +binding=NE, +#else +binding=0, +#endif +set=B3)uniform lowp subpassInput sh;layout(location=0)out i eb;void main(){eb=subpassLoad(sh);} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.minified.frag new file mode 100644 index 000000000..fa8036d53 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_input_attachment.minified.frag @@ -0,0 +1,9 @@ +#ifdef FRAGMENT +layout(input_attachment_index=0, +#ifdef INPUT_ATTACHMENT_BINDING +binding=INPUT_ATTACHMENT_BINDING, +#else +binding=0, +#endif +set=B3)uniform lowp subpassInput sh;layout(location=0)out i eb;void main(){eb=subpassLoad(sh);} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.hpp new file mode 100644 index 000000000..91c2640e3 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.frag.hpp @@ -0,0 +1,124 @@ +#pragma once + +#include "draw_mesh.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_mesh_frag[] = R"===(#ifdef EB +#if(defined(K)&&!defined(M))||defined(PB) +#undef fb +#else +#define fb +#endif +K1 +#ifndef K +p0(P2,j0); +#endif +#ifndef PB +f1(Q2,e0); +#ifndef K +p0(d6,f4); +#endif +f1(F6,S0); +#else +p0(Q2,e0); +#endif +L1 +#ifdef KB +y3 U2(Y4,R3,DC);z3 Z4 S3(R5)a5 K3 L3 +#endif +#ifdef K +#ifdef KB +v4(HB) +#else +o2(HB) +#endif +#else +#ifdef KB +M5(HB) +#else +v1(HB) +#endif +#endif +{ +#ifdef DB +B(k1,g);B(C2,c); +#endif +#ifdef KB +B(U0,c); +#endif +#ifdef M +B(F3,d); +#endif +#ifdef Z +B(N0,g); +#endif +#if defined(DB)&&defined(FB) +B(Y1,d); +#endif +#ifdef DB +i j=M7(k1,1. R2);d n=clamp(m2(VC,I9,C2,.0).x,G0(.0),G0(1.)); +#endif +#ifdef KB +i j=y7(DC,R5,U0,k.ad);d n=1.; +#endif +#ifdef Z +if(Z){d V4=max(d3(X4(N0)),G0(.0));n=min(V4,n);} +#endif +#ifdef fb +v2; +#endif +#if defined(M) +if(M&&F3!=.0){d o3; +#ifndef PB +D O0=unpackHalf2x16(e1(e0));d A6=O0.y;o3=max(A6==F3?O0.x:G0(.0),G0(.0)); +#else +o3=H0(e0).x; +#endif +o3=max(o3,G0(.0));n=min(n,o3);} +#endif +#ifdef KB +n*=A0.y4; +#endif +#if!defined(K) +i M1=H0(j0); +#ifdef FB +if(FB){ +#ifdef DB +X n2=W5(Y1); +#endif +#ifdef KB +j.xyz=B6(j);X n2=i2(A0.n2); +#endif +if(n2!=K5){j.xyz=R4(j.xyz,M1,n2);}j.w*=n;j.xyz*=j.w;}else +#endif +{j*=n;} +#ifdef VB +if(VB){j=h3(j);} +#endif +j.xyz=M3(j.xyz,T.xy,k.v3,k.w3); +#ifndef PB +j=M1*(1.-j.w)+j; +#endif +C0(j0,j); +#endif +#ifndef PB +X1(e0);X1(S0); +#else +C0(e0,B0(.0)); +#endif +#ifdef fb +w2; +#endif +#ifdef K +j=(j*n);j.xyz=M3(j.xyz,T.xy,k.v3,k.w3);m1=j;i3 +#else +c2; +#endif +} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.minified.frag new file mode 100644 index 000000000..5343e2ecd --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_mesh.minified.frag @@ -0,0 +1,113 @@ +#ifdef FRAGMENT +#if(defined(FIXED_FUNCTION_COLOR_OUTPUT)&&!defined(ENABLE_CLIPPING))||defined(RENDER_MODE_CLOCKWISE_ATOMIC) +#undef fb +#else +#define fb +#endif +K1 +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(P2,j0); +#endif +#ifndef RENDER_MODE_CLOCKWISE_ATOMIC +f1(Q2,e0); +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +p0(d6,f4); +#endif +f1(F6,S0); +#else +p0(Q2,e0); +#endif +L1 +#ifdef DRAW_IMAGE_MESH +y3 U2(Y4,R3,DC);z3 Z4 S3(R5)a5 K3 L3 +#endif +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +#ifdef DRAW_IMAGE_MESH +v4(HB) +#else +o2(HB) +#endif +#else +#ifdef DRAW_IMAGE_MESH +M5(HB) +#else +v1(HB) +#endif +#endif +{ +#ifdef ATLAS_BLIT +B(k1,g);B(C2,c); +#endif +#ifdef DRAW_IMAGE_MESH +B(U0,c); +#endif +#ifdef ENABLE_CLIPPING +B(F3,d); +#endif +#ifdef ENABLE_CLIP_RECT +B(N0,g); +#endif +#if defined(ATLAS_BLIT)&&defined(ENABLE_ADVANCED_BLEND) +B(Y1,d); +#endif +#ifdef ATLAS_BLIT +i j=M7(k1,1. R2);d n=clamp(m2(VC,I9,C2,.0).x,G0(.0),G0(1.)); +#endif +#ifdef DRAW_IMAGE_MESH +i j=y7(DC,R5,U0,k.ad);d n=1.; +#endif +#ifdef ENABLE_CLIP_RECT +if(ENABLE_CLIP_RECT){d V4=max(d3(X4(N0)),G0(.0));n=min(V4,n);} +#endif +#ifdef fb +v2; +#endif +#if defined(ENABLE_CLIPPING) +if(ENABLE_CLIPPING&&F3!=.0){d o3; +#ifndef RENDER_MODE_CLOCKWISE_ATOMIC +D O0=unpackHalf2x16(e1(e0));d A6=O0.y;o3=max(A6==F3?O0.x:G0(.0),G0(.0)); +#else +o3=H0(e0).x; +#endif +o3=max(o3,G0(.0));n=min(n,o3);} +#endif +#ifdef DRAW_IMAGE_MESH +n*=A0.y4; +#endif +#if!defined(FIXED_FUNCTION_COLOR_OUTPUT) +i M1=H0(j0); +#ifdef ENABLE_ADVANCED_BLEND +if(ENABLE_ADVANCED_BLEND){ +#ifdef ATLAS_BLIT +X n2=W5(Y1); +#endif +#ifdef DRAW_IMAGE_MESH +j.xyz=B6(j);X n2=i2(A0.n2); +#endif +if(n2!=K5){j.xyz=R4(j.xyz,M1,n2);}j.w*=n;j.xyz*=j.w;}else +#endif +{j*=n;} +#ifdef NEEDS_GAMMA_CORRECTION +if(NEEDS_GAMMA_CORRECTION){j=h3(j);} +#endif +j.xyz=M3(j.xyz,T.xy,k.v3,k.w3); +#ifndef RENDER_MODE_CLOCKWISE_ATOMIC +j=M1*(1.-j.w)+j; +#endif +C0(j0,j); +#endif +#ifndef RENDER_MODE_CLOCKWISE_ATOMIC +X1(e0);X1(S0); +#else +C0(e0,B0(.0)); +#endif +#ifdef fb +w2; +#endif +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +j=(j*n);j.xyz=M3(j.xyz,T.xy,k.v3,k.w3);m1=j;i3 +#else +c2; +#endif +} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.hpp new file mode 100644 index 000000000..f1eb9998a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.frag.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "draw_msaa_object.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_msaa_object_frag[] = R"===(#ifdef EB +#ifdef KB +y3 U2(Y4,R3,DC); +#ifdef FB +g7(JD); +#endif +z3 Z4 S3(R5)a5 +#endif +V2(i,HB){ +#ifdef KB +B(U0,c); +#else +B(k1,g); +#ifdef DB +B(C2,c); +#endif +#ifdef FB +B(Y1,d); +#endif +#endif +#ifdef KB +i j=y7(DC,R5,U0,k.ad)*A0.y4; +#else +d n= +#ifdef DB +clamp(m2(VC,I9,C2,.0).x,G0(.0),G0(1.)); +#else +1.; +#endif +i j=M7(k1,n R2); +#endif +#if defined(FB)&&!defined(K) +#ifdef KB +j.xyz=B6(j);X n2=i2(A0.n2); +#else +X n2=W5(Y1); +#endif +i M1=S8(JD);j.xyz=R4(j.xyz,M1,n2);j.xyz*=j.w; +#elif defined(ME)&&defined(K)&&!defined(KB) +j.xyz*=j.w; +#endif +#ifdef VB +if(VB){j=h3(j);} +#endif +j.xyz=M3(j.xyz,T.xy,k.v3,k.w3);F2(j);} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.minified.frag new file mode 100644 index 000000000..58de372e3 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_object.minified.frag @@ -0,0 +1,46 @@ +#ifdef FRAGMENT +#ifdef DRAW_IMAGE_MESH +y3 U2(Y4,R3,DC); +#ifdef ENABLE_ADVANCED_BLEND +g7(JD); +#endif +z3 Z4 S3(R5)a5 +#endif +V2(i,HB){ +#ifdef DRAW_IMAGE_MESH +B(U0,c); +#else +B(k1,g); +#ifdef ATLAS_BLIT +B(C2,c); +#endif +#ifdef ENABLE_ADVANCED_BLEND +B(Y1,d); +#endif +#endif +#ifdef DRAW_IMAGE_MESH +i j=y7(DC,R5,U0,k.ad)*A0.y4; +#else +d n= +#ifdef ATLAS_BLIT +clamp(m2(VC,I9,C2,.0).x,G0(.0),G0(1.)); +#else +1.; +#endif +i j=M7(k1,n R2); +#endif +#if defined(ENABLE_ADVANCED_BLEND)&&!defined(FIXED_FUNCTION_COLOR_OUTPUT) +#ifdef DRAW_IMAGE_MESH +j.xyz=B6(j);X n2=i2(A0.n2); +#else +X n2=W5(Y1); +#endif +i M1=S8(JD);j.xyz=R4(j.xyz,M1,n2);j.xyz*=j.w; +#elif defined(SPEC_CONST_NONE)&&defined(FIXED_FUNCTION_COLOR_OUTPUT)&&!defined(DRAW_IMAGE_MESH) +j.xyz*=j.w; +#endif +#ifdef NEEDS_GAMMA_CORRECTION +if(NEEDS_GAMMA_CORRECTION){j=h3(j);} +#endif +j.xyz=M3(j.xyz,T.xy,k.v3,k.w3);F2(j);} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.hpp new file mode 100644 index 000000000..2b88068ff --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.frag.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "draw_msaa_resolve.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_msaa_resolve_frag[] = R"===(#ifdef EB +layout(input_attachment_index=0,binding=P2,set=B3)uniform lowp subpassInputMS i9;layout(location=0)out i eb;void main(){eb=(subpassLoad(i9,0)+subpassLoad(i9,1)+subpassLoad(i9,2)+subpassLoad(i9,3))*.25;} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.minified.frag new file mode 100644 index 000000000..5aada3ac8 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_msaa_resolve.minified.frag @@ -0,0 +1,3 @@ +#ifdef FRAGMENT +layout(input_attachment_index=0,binding=P2,set=B3)uniform lowp subpassInputMS i9;layout(location=0)out i eb;void main(){eb=(subpassLoad(i9,0)+subpassLoad(i9,1)+subpassLoad(i9,2)+subpassLoad(i9,3))*.25;} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_path.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_path.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_path.glsl.hpp deleted file mode 100644 index 023aec0d2..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_path.glsl.hpp +++ /dev/null @@ -1,294 +0,0 @@ -#pragma once - -#include "draw_path.exports.h" - -namespace rive { -namespace gpu { -namespace glsl { -const char draw_path[] = R"===(#ifdef FB -#define o6 !FB -#else -#define o6 true -#endif -#ifdef AB -U0(f0) -#ifdef GB -i0(0,a4,IB); -#else -i0(0,f,LB);i0(1,f,MB); -#endif -V0 -#endif -o1 n0 H(0,f,H1); -#ifdef CB -n0 H(1,c,Q0); -#elif!defined(DB) -#ifdef GB -OB H(1,g,i1); -#elif defined(EB) -n0 H(2,f,D); -#else -n0 H(2,G,D); -#endif -OB H(3,g,j0); -#endif -#ifdef T -OB H(4,G,i3); -#endif -#ifdef BB -n0 H(5,f,R0); -#endif -#ifdef FB -OB H(6,g,U3); -#endif -p1 -#ifdef AB -q1(PB,f0,B,n,K){ -#ifdef GB -l0(n,B,IB,Z); -#else -l0(n,B,LB,f);l0(n,B,MB,f); -#endif -L(H1,f); -#ifdef CB -L(Q0,c); -#elif!defined(DB) -#ifdef GB -L(i1,g); -#elif defined(EB) -L(D,f); -#else -L(D,G); -#endif -L(j0,g); -#endif -#ifdef T -L(i3,G); -#endif -#ifdef BB -L(R0,f); -#endif -#ifdef FB -L(U3,g); -#endif -bool Eb=false;uint R;c J; -#ifdef DB -a0 z7; -#endif -#ifdef CB -J=a8(IB,R, -#ifdef DB -z7, -#endif -Q0 Y1); -#elif defined(GB) -J=c8(IB,R -#ifdef DB -,z7 -#else -,i1 -#endif -Y1); -#else -f O;Eb=!E6(LB,MB,K,R,J -#ifndef DB -,O -#else -,z7 -#endif -Y1); -#ifndef DB -#ifdef EB -D=O; -#else -D.xy=F6(O.xy); -#endif -#endif -#endif -N0 F0=k4(DC,R); -#if!defined(CB)&&!defined(DB) -j0=g7(R,q.d5);if((F0.x&p8)!=0u)j0=-j0; -#endif -uint J1=F0.x&0xfu; -#ifdef T -if(T){uint te=(J1==N6?F0.y:F0.x)>>16;g Z0=g7(te,q.d5);if(J1==N6)Z0=-Z0;i3.x=Z0;} -#endif -#ifdef FB -if(FB){U3=float((F0.x>>4)&0xfu);} -#endif -c p6=J; -#ifdef DE -p6.y=float(q.id)-p6.y; -#endif -#ifdef BB -if(BB){S R1=D1(w0(KB,R*4u+2u));f Z1=w0(KB,R*4u+3u); -#ifndef DB -R0=I6(R1,Z1.xy,p6); -#else -Ka(R1,Z1.xy,p6); -#endif -} -#endif -if(J1==q8){i j=unpackUnorm4x8(F0.y);if(o6)j.xyz*=j.w;H1=f(j);} -#ifdef T -else if(T&&J1==N6){g A7=g7(F0.x>>16,q.d5);i3.y=A7;} -#endif -else{S ue=D1(w0(KB,R*4u));f B7=w0(KB,R*4u+1u);c G2=C0(ue,p6)+B7.xy;if(J1==O6||J1==td){H1.w=-uintBitsToFloat(F0.y);float ve=B7.z;if(ve>.9){H1.z=2.;}else{H1.z=B7.w;}if(J1==O6){H1.y=.0;H1.x=G2.x;}else{H1.z=-H1.z;H1.xy=G2.xy;}}else{float H2=uintBitsToFloat(F0.y);float d6=B7.z;H1=f(G2.x,G2.y,H2,-2.-d6);}}f Q;if(!Eb){Q=F2(J); -#ifdef EE -Q.y=-Q.y; -#endif -#ifdef DB -Q.z=S8(z7); -#endif -}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(H1); -#ifdef CB -P(Q0); -#elif!defined(DB) -#ifdef GB -P(i1); -#elif defined(EB) -P(D); -#else -P(D); -#endif -P(j0); -#endif -#ifdef T -P(i3); -#endif -#ifdef BB -P(R0); -#endif -#ifdef FB -P(U3); -#endif -h1(Q);} -#endif -#ifdef HB -w3 x3 d i Fb(f J2,float E C5){i j;if(J2.w>=.0){j=I5(J2);if(o6)j*=E;else j.w*=E;}else if(J2.w>-1.){float t=J2.z>.0?J2.x:length(J2.xy);t=clamp(t,.0,1.);float Gb=abs(J2.z);float x=Gb>1.?(1.-1./T8)*t+(.5/T8):(1./T8)*t+Gb;float we=-J2.w;j=T1(MC,r8,c(x,we),.0);j.w*=E;if(o6)j.xyz*=j.w;}else{g d6=-J2.w-2.;j=C7(UB,B3,J2.xy,d6);g H2=J2.z*E;if(o6)j*=H2;else j=E1(Y3(j),j.w*H2);}return j;} -#ifndef DB -x2 M0(i8,H0);Y0(B5,r1);M0(bb,N3);Y0(k8,x4);y2 z2(NB){N(H1,f); -#ifdef CB -N(Q0,c); -#elif!defined(DB) -#ifdef GB -N(i1,g); -#elif defined(EB) -N(D,f); -#else -N(D,G); -#endif -N(j0,g); -#endif -#ifdef T -N(i3,G); -#endif -#ifdef BB -N(R0,f); -#endif -#ifdef FB -N(U3,g); -#endif -#if!defined(GB)||defined(CB) -h2; -#endif -g E; -#ifdef CB -E=W6(Q0,q.U4 x1); -#else -G L3=unpackHalf2x16(j1(x4));g Hb=L3.y;g F1=Hb==j0?L3.x:v1(.0); -#ifdef GB -F1+=i1;i2(x4); -#else -if(U6(D)){g r0; -#ifdef EB -if(EB&&w8(D)){r0=R6(D x1);}else -#endif -{r0=min(D.x,D.y);}F1=max(r0,F1);}else{g r0; -#if defined(EB) -if(EB&&S6(D)){r0=S4(D x1);}else -#endif -{r0=D.x;}F1+=r0;}l1(x4,packHalf2x16(Z3(F1,j0))); -#endif -#ifdef AD -if(AD){ -#ifdef BD -if(BD==yd){if(F1<.0)E=.0;else if(F1<=1.)E=F1;else E=1.;}else -#endif -{E=clamp(F1,v1(.0),v1(1.));}}else -#endif -{E=abs(F1); -#ifdef IC -if(IC&&j0<.0){E=1.-v1(abs(fract(E*.5)*2.+-1.));} -#endif -E=min(E,v1(1.));} -#endif -#ifdef T -if(T&&i3.x<.0){g Z0=-i3.x; -#ifdef CD -if(CD){g A7=i3.y;if(A7!=.0){G I1=unpackHalf2x16(j1(r1));g k5=I1.y;g D7;if(k5!=Z0){D7=k5==A7?I1.x:.0; -#ifndef GB -T0(N3,E1(D7,.0,.0,.0)); -#endif -}else{D7=I0(N3).x; -#ifndef GB -E2(N3); -#endif -}E=min(E,D7);}} -#endif -l1(r1,packHalf2x16(Z3(E,Z0)));E2(H0);}else -#endif -{ -#ifdef T -if(T){g Z0=i3.x;if(Z0!=.0){G I1=unpackHalf2x16(j1(r1));g k5=I1.y;E=(k5==Z0)?min(I1.x,E):v1(.0);}} -#endif -#ifdef BB -if(BB){g l4=A8(I5(R0));E=clamp(l4,v1(.0),E);} -#endif -i j=Fb(H1,E Y2);i w1; -#ifdef CB -w1=I0(H0); -#else -if(Hb!=j0){w1=I0(H0); -#ifndef GB -T0(N3,w1); -#endif -}else{w1=I0(N3); -#ifndef GB -E2(N3); -#endif -} -#endif -#ifdef FB -if(FB){if(U3!=f7(B8)){j.xyz=M4(j.xyz,w1,O8(U3));}j.xyz*=j.w;} -#endif -j+=w1*(1.-j.w);T0(H0,j);i2(r1);} -#if!defined(GB)||defined(CB) -j2; -#endif -M2;} -#else -e2(i,NB){N(H1,f); -#ifdef CB -N(Q0,c); -#endif -#ifdef FB -N(U3,g); -#endif -g E= -#ifdef CB -W6(Q0,q.U4 x1); -#else -1.; -#endif -i j=Fb(H1,E Y2); -#ifdef FB -if(FB){i w1=d1(PC,c0(floor(y0.xy)));j.xyz=M4(j.xyz,w1,O8(U3));j.xyz*=j.w;} -#endif -f2(j);} -#endif -#endif -)==="; -} // namespace glsl -} // namespace gpu -} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.glsl deleted file mode 100644 index c9bd34066..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.glsl +++ /dev/null @@ -1,283 +0,0 @@ -#ifdef ENABLE_ADVANCED_BLEND -#define o6 !ENABLE_ADVANCED_BLEND -#else -#define o6 true -#endif -#ifdef VERTEX -U0(f0) -#ifdef DRAW_INTERIOR_TRIANGLES -i0(0,a4,IB); -#else -i0(0,f,LB);i0(1,f,MB); -#endif -V0 -#endif -o1 n0 H(0,f,H1); -#ifdef ATLAS_BLIT -n0 H(1,c,Q0); -#elif!defined(RENDER_MODE_MSAA) -#ifdef DRAW_INTERIOR_TRIANGLES -OPTIONALLY_FLAT H(1,g,i1); -#elif defined(ENABLE_FEATHER) -n0 H(2,f,D); -#else -n0 H(2,G,D); -#endif -OPTIONALLY_FLAT H(3,g,j0); -#endif -#ifdef ENABLE_CLIPPING -OPTIONALLY_FLAT H(4,G,i3); -#endif -#ifdef ENABLE_CLIP_RECT -n0 H(5,f,R0); -#endif -#ifdef ENABLE_ADVANCED_BLEND -OPTIONALLY_FLAT H(6,g,U3); -#endif -p1 -#ifdef VERTEX -q1(PB,f0,B,n,K){ -#ifdef DRAW_INTERIOR_TRIANGLES -l0(n,B,IB,Z); -#else -l0(n,B,LB,f);l0(n,B,MB,f); -#endif -L(H1,f); -#ifdef ATLAS_BLIT -L(Q0,c); -#elif!defined(RENDER_MODE_MSAA) -#ifdef DRAW_INTERIOR_TRIANGLES -L(i1,g); -#elif defined(ENABLE_FEATHER) -L(D,f); -#else -L(D,G); -#endif -L(j0,g); -#endif -#ifdef ENABLE_CLIPPING -L(i3,G); -#endif -#ifdef ENABLE_CLIP_RECT -L(R0,f); -#endif -#ifdef ENABLE_ADVANCED_BLEND -L(U3,g); -#endif -bool Eb=false;uint R;c J; -#ifdef RENDER_MODE_MSAA -a0 z7; -#endif -#ifdef ATLAS_BLIT -J=a8(IB,R, -#ifdef RENDER_MODE_MSAA -z7, -#endif -Q0 Y1); -#elif defined(DRAW_INTERIOR_TRIANGLES) -J=c8(IB,R -#ifdef RENDER_MODE_MSAA -,z7 -#else -,i1 -#endif -Y1); -#else -f O;Eb=!E6(LB,MB,K,R,J -#ifndef RENDER_MODE_MSAA -,O -#else -,z7 -#endif -Y1); -#ifndef RENDER_MODE_MSAA -#ifdef ENABLE_FEATHER -D=O; -#else -D.xy=F6(O.xy); -#endif -#endif -#endif -N0 F0=k4(DC,R); -#if!defined(ATLAS_BLIT)&&!defined(RENDER_MODE_MSAA) -j0=g7(R,q.d5);if((F0.x&p8)!=0u)j0=-j0; -#endif -uint J1=F0.x&0xfu; -#ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING){uint te=(J1==N6?F0.y:F0.x)>>16;g Z0=g7(te,q.d5);if(J1==N6)Z0=-Z0;i3.x=Z0;} -#endif -#ifdef ENABLE_ADVANCED_BLEND -if(ENABLE_ADVANCED_BLEND){U3=float((F0.x>>4)&0xfu);} -#endif -c p6=J; -#ifdef FRAMEBUFFER_BOTTOM_UP -p6.y=float(q.id)-p6.y; -#endif -#ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT){S R1=D1(w0(KB,R*4u+2u));f Z1=w0(KB,R*4u+3u); -#ifndef RENDER_MODE_MSAA -R0=I6(R1,Z1.xy,p6); -#else -Ka(R1,Z1.xy,p6); -#endif -} -#endif -if(J1==q8){i j=unpackUnorm4x8(F0.y);if(o6)j.xyz*=j.w;H1=f(j);} -#ifdef ENABLE_CLIPPING -else if(ENABLE_CLIPPING&&J1==N6){g A7=g7(F0.x>>16,q.d5);i3.y=A7;} -#endif -else{S ue=D1(w0(KB,R*4u));f B7=w0(KB,R*4u+1u);c G2=C0(ue,p6)+B7.xy;if(J1==O6||J1==td){H1.w=-uintBitsToFloat(F0.y);float ve=B7.z;if(ve>.9){H1.z=2.;}else{H1.z=B7.w;}if(J1==O6){H1.y=.0;H1.x=G2.x;}else{H1.z=-H1.z;H1.xy=G2.xy;}}else{float H2=uintBitsToFloat(F0.y);float d6=B7.z;H1=f(G2.x,G2.y,H2,-2.-d6);}}f Q;if(!Eb){Q=F2(J); -#ifdef POST_INVERT_Y -Q.y=-Q.y; -#endif -#ifdef RENDER_MODE_MSAA -Q.z=S8(z7); -#endif -}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(H1); -#ifdef ATLAS_BLIT -P(Q0); -#elif!defined(RENDER_MODE_MSAA) -#ifdef DRAW_INTERIOR_TRIANGLES -P(i1); -#elif defined(ENABLE_FEATHER) -P(D); -#else -P(D); -#endif -P(j0); -#endif -#ifdef ENABLE_CLIPPING -P(i3); -#endif -#ifdef ENABLE_CLIP_RECT -P(R0); -#endif -#ifdef ENABLE_ADVANCED_BLEND -P(U3); -#endif -h1(Q);} -#endif -#ifdef FRAGMENT -w3 x3 d i Fb(f J2,float E C5){i j;if(J2.w>=.0){j=I5(J2);if(o6)j*=E;else j.w*=E;}else if(J2.w>-1.){float t=J2.z>.0?J2.x:length(J2.xy);t=clamp(t,.0,1.);float Gb=abs(J2.z);float x=Gb>1.?(1.-1./T8)*t+(.5/T8):(1./T8)*t+Gb;float we=-J2.w;j=T1(MC,r8,c(x,we),.0);j.w*=E;if(o6)j.xyz*=j.w;}else{g d6=-J2.w-2.;j=C7(UB,B3,J2.xy,d6);g H2=J2.z*E;if(o6)j*=H2;else j=E1(Y3(j),j.w*H2);}return j;} -#ifndef RENDER_MODE_MSAA -x2 M0(i8,H0);Y0(B5,r1);M0(bb,N3);Y0(k8,x4);y2 z2(NB){N(H1,f); -#ifdef ATLAS_BLIT -N(Q0,c); -#elif!defined(RENDER_MODE_MSAA) -#ifdef DRAW_INTERIOR_TRIANGLES -N(i1,g); -#elif defined(ENABLE_FEATHER) -N(D,f); -#else -N(D,G); -#endif -N(j0,g); -#endif -#ifdef ENABLE_CLIPPING -N(i3,G); -#endif -#ifdef ENABLE_CLIP_RECT -N(R0,f); -#endif -#ifdef ENABLE_ADVANCED_BLEND -N(U3,g); -#endif -#if!defined(DRAW_INTERIOR_TRIANGLES)||defined(ATLAS_BLIT) -h2; -#endif -g E; -#ifdef ATLAS_BLIT -E=W6(Q0,q.U4 x1); -#else -G L3=unpackHalf2x16(j1(x4));g Hb=L3.y;g F1=Hb==j0?L3.x:v1(.0); -#ifdef DRAW_INTERIOR_TRIANGLES -F1+=i1;i2(x4); -#else -if(U6(D)){g r0; -#ifdef ENABLE_FEATHER -if(ENABLE_FEATHER&&w8(D)){r0=R6(D x1);}else -#endif -{r0=min(D.x,D.y);}F1=max(r0,F1);}else{g r0; -#if defined(ENABLE_FEATHER) -if(ENABLE_FEATHER&&S6(D)){r0=S4(D x1);}else -#endif -{r0=D.x;}F1+=r0;}l1(x4,packHalf2x16(Z3(F1,j0))); -#endif -#ifdef CLOCKWISE_FILL -if(CLOCKWISE_FILL){ -#ifdef VULKAN_VENDOR_ID -if(VULKAN_VENDOR_ID==yd){if(F1<.0)E=.0;else if(F1<=1.)E=F1;else E=1.;}else -#endif -{E=clamp(F1,v1(.0),v1(1.));}}else -#endif -{E=abs(F1); -#ifdef ENABLE_EVEN_ODD -if(ENABLE_EVEN_ODD&&j0<.0){E=1.-v1(abs(fract(E*.5)*2.+-1.));} -#endif -E=min(E,v1(1.));} -#endif -#ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING&&i3.x<.0){g Z0=-i3.x; -#ifdef ENABLE_NESTED_CLIPPING -if(ENABLE_NESTED_CLIPPING){g A7=i3.y;if(A7!=.0){G I1=unpackHalf2x16(j1(r1));g k5=I1.y;g D7;if(k5!=Z0){D7=k5==A7?I1.x:.0; -#ifndef DRAW_INTERIOR_TRIANGLES -T0(N3,E1(D7,.0,.0,.0)); -#endif -}else{D7=I0(N3).x; -#ifndef DRAW_INTERIOR_TRIANGLES -E2(N3); -#endif -}E=min(E,D7);}} -#endif -l1(r1,packHalf2x16(Z3(E,Z0)));E2(H0);}else -#endif -{ -#ifdef ENABLE_CLIPPING -if(ENABLE_CLIPPING){g Z0=i3.x;if(Z0!=.0){G I1=unpackHalf2x16(j1(r1));g k5=I1.y;E=(k5==Z0)?min(I1.x,E):v1(.0);}} -#endif -#ifdef ENABLE_CLIP_RECT -if(ENABLE_CLIP_RECT){g l4=A8(I5(R0));E=clamp(l4,v1(.0),E);} -#endif -i j=Fb(H1,E Y2);i w1; -#ifdef ATLAS_BLIT -w1=I0(H0); -#else -if(Hb!=j0){w1=I0(H0); -#ifndef DRAW_INTERIOR_TRIANGLES -T0(N3,w1); -#endif -}else{w1=I0(N3); -#ifndef DRAW_INTERIOR_TRIANGLES -E2(N3); -#endif -} -#endif -#ifdef ENABLE_ADVANCED_BLEND -if(ENABLE_ADVANCED_BLEND){if(U3!=f7(B8)){j.xyz=M4(j.xyz,w1,O8(U3));}j.xyz*=j.w;} -#endif -j+=w1*(1.-j.w);T0(H0,j);i2(r1);} -#if!defined(DRAW_INTERIOR_TRIANGLES)||defined(ATLAS_BLIT) -j2; -#endif -M2;} -#else -e2(i,NB){N(H1,f); -#ifdef ATLAS_BLIT -N(Q0,c); -#endif -#ifdef ENABLE_ADVANCED_BLEND -N(U3,g); -#endif -g E= -#ifdef ATLAS_BLIT -W6(Q0,q.U4 x1); -#else -1.; -#endif -i j=Fb(H1,E Y2); -#ifdef ENABLE_ADVANCED_BLEND -if(ENABLE_ADVANCED_BLEND){i w1=d1(PC,c0(floor(y0.xy)));j.xyz=M4(j.xyz,w1,O8(U3));j.xyz*=j.w;} -#endif -f2(j);} -#endif -#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.vert b/thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.vert new file mode 100644 index 000000000..d356d4a29 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_path.minified.vert @@ -0,0 +1,205 @@ +#undef C5 +#ifdef NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#define C5 false +#elif defined(ENABLE_ADVANCED_BLEND) +#define C5 !ENABLE_ADVANCED_BLEND +#else +#define C5 true +#endif +#undef z2 +#ifdef ENABLE_FEATHER +#define z2 g +#else +#define z2 D +#endif +#ifdef VERTEX +A1(c0) +#if defined(DRAW_INTERIOR_TRIANGLES)||defined(ATLAS_BLIT) +r0(0,I3,JB); +#else +r0(0,g,TB);r0(1,g,UB); +#endif +B1 +#endif +h2 J0 d0(0,g,k1); +#ifdef ATLAS_BLIT +J0 d0(1,c,C2); +#elif!defined(RENDER_MODE_MSAA) +#ifdef DRAW_INTERIOR_TRIANGLES +OPTIONALLY_FLAT d0(1,d,l1); +#else +J0 d0(2,z2,I); +#endif +OPTIONALLY_FLAT d0(3,d,z0); +#endif +#ifdef ENABLE_CLIPPING +#ifdef ATLAS_BLIT +OPTIONALLY_FLAT d0(4,d,F3); +#else +OPTIONALLY_FLAT d0(4,D,S1); +#endif +#endif +#if defined(ENABLE_CLIP_RECT)&&!defined(RENDER_MODE_MSAA) +J0 d0(5,g,N0); +#endif +#ifdef ENABLE_ADVANCED_BLEND +OPTIONALLY_FLAT d0(6,d,Y1); +#endif +#ifdef RENDER_MODE_CLOCKWISE_ATOMIC +S4 d0(7,W0,a3);d0(8,c,i4); +#endif +Z1 +#ifdef VERTEX +C1(XB,c0,G,v,S){ +#if defined(DRAW_INTERIOR_TRIANGLES)||defined(ATLAS_BLIT) +v0(v,G,JB,V); +#else +v0(v,G,TB,g);v0(v,G,UB,g); +#endif +Y(k1,g); +#ifdef ATLAS_BLIT +Y(C2,c); +#elif!defined(RENDER_MODE_MSAA) +#ifdef DRAW_INTERIOR_TRIANGLES +Y(l1,d); +#else +Y(I,z2); +#endif +Y(z0,d); +#endif +#ifdef ENABLE_CLIPPING +#ifdef ATLAS_BLIT +Y(F3,d); +#else +Y(S1,D); +#endif +#endif +#if defined(ENABLE_CLIP_RECT)&&!defined(RENDER_MODE_MSAA) +Y(N0,g); +#endif +#ifdef ENABLE_ADVANCED_BLEND +Y(Y1,d); +#endif +#ifdef RENDER_MODE_CLOCKWISE_ATOMIC +Y(a3,W0);Y(i4,c); +#endif +bool Pd=false;uint m0;c i0; +#ifdef RENDER_MODE_MSAA +X e9; +#endif +#ifdef ATLAS_BLIT +i0=nb(JB,m0, +#ifdef RENDER_MODE_MSAA +e9, +#endif +C2 p3); +#elif defined(DRAW_INTERIOR_TRIANGLES) +i0=ob(JB,m0 +#ifdef RENDER_MODE_MSAA +,e9 +#else +,l1 +#endif +p3); +#else +g J;Pd=!p9(TB,UB,S,m0,i0 +#ifndef RENDER_MODE_MSAA +,J +#else +,e9 +#endif +p3); +#ifndef RENDER_MODE_MSAA +#ifdef ENABLE_FEATHER +I=J; +#else +I.xy=R7(J.xy); +#endif +#endif +#endif +W0 r1=J5(UC,m0); +#if!defined(ATLAS_BLIT)&&!defined(RENDER_MODE_MSAA) +z0=r8(m0,k.Y5);if((r1.x&C9)!=0u)z0=-z0; +#endif +uint g3=r1.x&0xfu; +#ifdef ENABLE_CLIPPING +if(ENABLE_CLIPPING){uint jh=(g3==Z7?r1.y:r1.x)>>16;d V0=r8(jh,k.Y5);if(g3==Z7)V0=-V0; +#ifdef ATLAS_BLIT +F3=V0; +#else +S1.x=V0; +#endif +} +#endif +#ifdef ENABLE_ADVANCED_BLEND +if(ENABLE_ADVANCED_BLEND){Y1=float((r1.x>>4)&0xfu);} +#endif +c K0=i0; +#ifdef FRAMEBUFFER_BOTTOM_UP +K0.y=float(k.mg)-K0.y; +#endif +#ifdef ENABLE_CLIP_RECT +if(ENABLE_CLIP_RECT){a0 k2=j2(P0(OB,m0*4u+2u));g D2=P0(OB,m0*4u+3u); +#ifndef RENDER_MODE_MSAA +N0=T7(k2,D2.xy,K0); +#else +ic(k2,D2.xy,K0 r5); +#endif +} +#endif +if(g3==vb){i j=unpackUnorm4x8(r1.y);if(C5)j.xyz*=j.w;k1=g(j);} +#if defined(ENABLE_CLIPPING)&&!defined(ATLAS_BLIT) +else if(ENABLE_CLIPPING&&g3==Z7){d D5=r8(r1.x>>16,k.Y5);S1.y=D5;} +#endif +else{a0 kh=j2(P0(OB,m0*4u));g f9=P0(OB,m0*4u+1u);c W4=Z0(kh,K0)+f9.xy;if(g3==E9||g3==rf){k1.w=-uintBitsToFloat(r1.y);float lh=f9.z;if(lh>.9){k1.z=2.;}else{k1.z=f9.w;}if(g3==E9){k1.y=.0;k1.x=W4.x;}else{k1.z=-k1.z;k1.xy=W4.xy;}}else{float y4=uintBitsToFloat(r1.y);float Wa=f9.z;k1=g(W4.x,W4.y,y4,-2.-Wa);}}g O;if(!Pd){O=H3(i0); +#ifdef POST_INVERT_Y +O.y=-O.y; +#endif +#ifdef RENDER_MODE_MSAA +O.z=ca(e9); +#elif defined(RENDER_MODE_CLOCKWISE_ATOMIC) +Q O4=P0(LB,m0*4u+3u);a3=O4.xy;i4=i0+uintBitsToFloat(O4.zw); +#endif +}else{O=g(k.O2,k.O2,k.O2,k.O2);}l0(k1); +#ifdef ATLAS_BLIT +l0(C2); +#elif!defined(RENDER_MODE_MSAA) +#ifdef DRAW_INTERIOR_TRIANGLES +l0(l1); +#else +l0(I); +#endif +l0(z0); +#endif +#ifdef ENABLE_CLIPPING +#ifdef ATLAS_BLIT +l0(F3); +#else +l0(S1); +#endif +#endif +#if defined(ENABLE_CLIP_RECT)&&!defined(RENDER_MODE_MSAA) +l0(N0); +#endif +#ifdef ENABLE_ADVANCED_BLEND +l0(Y1); +#endif +#ifdef RENDER_MODE_CLOCKWISE_ATOMIC +l0(a3);l0(i4); +#endif +D1(O);} +#endif +#ifdef FRAGMENT +K3 L3 e i M7(g n3,float n G6){i j;if(n3.w>=.0){j=X4(n3);if(C5)j*=n;else j.w*=n;}else if(n3.w>-1.){float t=n3.z>.0?n3.x:length(n3.xy);t=clamp(t,.0,1.);float Qd=abs(n3.z);float x=Qd>1.?(1.-1./da)*t+(.5/da):(1./da)*t+Qd;float mh=-n3.w;j=m2(DD,wb,c(x,mh),.0);j.w*=n;if(C5)j.xyz*=j.w;}else{d Wa=-n3.w-2.;j=Q6(DC,R5,n3.xy,Wa);d y4=n3.z*n;if(C5)j*=y4;else j=B0(B6(j),j.w*y4);}return j;} +#if!defined(DRAW_INTERIOR_TRIANGLES)&&!defined(ATLAS_BLIT) +e d Rd(z2 J C3){ +#ifdef ENABLE_FEATHER +if(ENABLE_FEATHER&&yb(J))return w4(J i1);else +#endif +return min(J.x,J.y);}e d Sd(z2 J C3){ +#if defined(ENABLE_FEATHER) +if(ENABLE_FEATHER&&zb(J))return d8(J i1);else +#endif +return J.x;}e d Xa(z2 J C3){if(P5(J))return Rd(J i1);else return Sd(J i1);}e d nh(d P4,z2 J C3){if(P5(J)){d q0=Rd(J i1);return max(q0,P4);}else{d q0=Sd(J i1);return P4+q0;}} +#endif +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.hpp new file mode 100644 index 000000000..33e488542 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_path.vert.hpp @@ -0,0 +1,216 @@ +#pragma once + +#include "draw_path.vert.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_path_vert[] = R"===(#undef C5 +#ifdef OF +#define C5 false +#elif defined(FB) +#define C5 !FB +#else +#define C5 true +#endif +#undef z2 +#ifdef GB +#define z2 g +#else +#define z2 D +#endif +#ifdef BB +A1(c0) +#if defined(CB)||defined(DB) +r0(0,I3,JB); +#else +r0(0,g,TB);r0(1,g,UB); +#endif +B1 +#endif +h2 J0 d0(0,g,k1); +#ifdef DB +J0 d0(1,c,C2); +#elif!defined(AB) +#ifdef CB +NB d0(1,d,l1); +#else +J0 d0(2,z2,I); +#endif +NB d0(3,d,z0); +#endif +#ifdef M +#ifdef DB +NB d0(4,d,F3); +#else +NB d0(4,D,S1); +#endif +#endif +#if defined(Z)&&!defined(AB) +J0 d0(5,g,N0); +#endif +#ifdef FB +NB d0(6,d,Y1); +#endif +#ifdef PB +S4 d0(7,W0,a3);d0(8,c,i4); +#endif +Z1 +#ifdef BB +C1(XB,c0,G,v,S){ +#if defined(CB)||defined(DB) +v0(v,G,JB,V); +#else +v0(v,G,TB,g);v0(v,G,UB,g); +#endif +Y(k1,g); +#ifdef DB +Y(C2,c); +#elif!defined(AB) +#ifdef CB +Y(l1,d); +#else +Y(I,z2); +#endif +Y(z0,d); +#endif +#ifdef M +#ifdef DB +Y(F3,d); +#else +Y(S1,D); +#endif +#endif +#if defined(Z)&&!defined(AB) +Y(N0,g); +#endif +#ifdef FB +Y(Y1,d); +#endif +#ifdef PB +Y(a3,W0);Y(i4,c); +#endif +bool Pd=false;uint m0;c i0; +#ifdef AB +X e9; +#endif +#ifdef DB +i0=nb(JB,m0, +#ifdef AB +e9, +#endif +C2 p3); +#elif defined(CB) +i0=ob(JB,m0 +#ifdef AB +,e9 +#else +,l1 +#endif +p3); +#else +g J;Pd=!p9(TB,UB,S,m0,i0 +#ifndef AB +,J +#else +,e9 +#endif +p3); +#ifndef AB +#ifdef GB +I=J; +#else +I.xy=R7(J.xy); +#endif +#endif +#endif +W0 r1=J5(UC,m0); +#if!defined(DB)&&!defined(AB) +z0=r8(m0,k.Y5);if((r1.x&C9)!=0u)z0=-z0; +#endif +uint g3=r1.x&0xfu; +#ifdef M +if(M){uint jh=(g3==Z7?r1.y:r1.x)>>16;d V0=r8(jh,k.Y5);if(g3==Z7)V0=-V0; +#ifdef DB +F3=V0; +#else +S1.x=V0; +#endif +} +#endif +#ifdef FB +if(FB){Y1=float((r1.x>>4)&0xfu);} +#endif +c K0=i0; +#ifdef PF +K0.y=float(k.mg)-K0.y; +#endif +#ifdef Z +if(Z){a0 k2=j2(P0(OB,m0*4u+2u));g D2=P0(OB,m0*4u+3u); +#ifndef AB +N0=T7(k2,D2.xy,K0); +#else +ic(k2,D2.xy,K0 r5); +#endif +} +#endif +if(g3==vb){i j=unpackUnorm4x8(r1.y);if(C5)j.xyz*=j.w;k1=g(j);} +#if defined(M)&&!defined(DB) +else if(M&&g3==Z7){d D5=r8(r1.x>>16,k.Y5);S1.y=D5;} +#endif +else{a0 kh=j2(P0(OB,m0*4u));g f9=P0(OB,m0*4u+1u);c W4=Z0(kh,K0)+f9.xy;if(g3==E9||g3==rf){k1.w=-uintBitsToFloat(r1.y);float lh=f9.z;if(lh>.9){k1.z=2.;}else{k1.z=f9.w;}if(g3==E9){k1.y=.0;k1.x=W4.x;}else{k1.z=-k1.z;k1.xy=W4.xy;}}else{float y4=uintBitsToFloat(r1.y);float Wa=f9.z;k1=g(W4.x,W4.y,y4,-2.-Wa);}}g O;if(!Pd){O=H3(i0); +#ifdef JC +O.y=-O.y; +#endif +#ifdef AB +O.z=ca(e9); +#elif defined(PB) +Q O4=P0(LB,m0*4u+3u);a3=O4.xy;i4=i0+uintBitsToFloat(O4.zw); +#endif +}else{O=g(k.O2,k.O2,k.O2,k.O2);}l0(k1); +#ifdef DB +l0(C2); +#elif!defined(AB) +#ifdef CB +l0(l1); +#else +l0(I); +#endif +l0(z0); +#endif +#ifdef M +#ifdef DB +l0(F3); +#else +l0(S1); +#endif +#endif +#if defined(Z)&&!defined(AB) +l0(N0); +#endif +#ifdef FB +l0(Y1); +#endif +#ifdef PB +l0(a3);l0(i4); +#endif +D1(O);} +#endif +#ifdef EB +K3 L3 e i M7(g n3,float n G6){i j;if(n3.w>=.0){j=X4(n3);if(C5)j*=n;else j.w*=n;}else if(n3.w>-1.){float t=n3.z>.0?n3.x:length(n3.xy);t=clamp(t,.0,1.);float Qd=abs(n3.z);float x=Qd>1.?(1.-1./da)*t+(.5/da):(1./da)*t+Qd;float mh=-n3.w;j=m2(DD,wb,c(x,mh),.0);j.w*=n;if(C5)j.xyz*=j.w;}else{d Wa=-n3.w-2.;j=Q6(DC,R5,n3.xy,Wa);d y4=n3.z*n;if(C5)j*=y4;else j=B0(B6(j),j.w*y4);}return j;} +#if!defined(CB)&&!defined(DB) +e d Rd(z2 J C3){ +#ifdef GB +if(GB&&yb(J))return w4(J i1);else +#endif +return min(J.x,J.y);}e d Sd(z2 J C3){ +#if defined(GB) +if(GB&&zb(J))return d8(J i1);else +#endif +return J.x;}e d Xa(z2 J C3){if(P5(J))return Rd(J i1);else return Sd(J i1);}e d nh(d P4,z2 J C3){if(P5(J)){d q0=Rd(J i1);return max(q0,P4);}else{d q0=Sd(J i1);return P4+q0;}} +#endif +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.hpp index 8dc0a175b..55fb99d02 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.glsl.hpp @@ -1,126 +1,134 @@ #pragma once -#include "draw_path_common.exports.h" +#include "draw_path_common.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char draw_path_common[] = R"===(#define e6 -2. -#define ib -1.5 -#define jb .25 -#define p7 1e3 -#define kb (p7*p7) -#ifdef AB -P2 wa(U2,wd,BC); -#ifdef EB -l5(U2,Z5,JC); +const char draw_path_common[] = R"===(#define f7 -2. +#define Ac -1.5 +#define Bc .25 +#define C8 1e3 +#define Cc (C8*C8) +#ifdef BB +P3 Tb(X2,sf,BC); +#ifdef GB +e6(X2,d7,QC); #endif -Q2 E3 O3(Va,Td,JB);g4(l8,W9,DC);h4(m8,X9,KB);O3(Wa,Ud,QC);F3 +Q3 B4 G4(vc,Jf,LB);H5(qb,ve,UC);I5(rb,we,OB);G4(wc,Kf,XC);C4 #endif -#if defined(EB)||defined(CB) -P3(Z5,M8) +#if defined(GB)||defined(DB) +V3(d7,T9) #endif -#ifdef HB -R2 C2(U2,Xa,MC); -#if defined(EB)||defined(CB) -l5(U2,Z5,JC); +#ifdef EB +y3 U2(X2,xc,DD); +#if defined(GB)||defined(DB) +e6(X2,d7,QC); #endif -#ifdef CB -y4(Y5,Ya,ND); +#ifdef DB +j5(X2,yc,VC); #endif -C2(Y5,W8,UB); -#if defined(DB)&&defined(FB) -C2(U2,Za,PC); +U2(Y4,R3,DC); +#if defined(AB)&&defined(FB)&&!defined(K) +g7(JD); #endif -S2 P3(Xa,r8) -#ifdef CB -P3(Ya,Vd) +z3 V3(xc,wb) +#ifdef DB +V3(yc,I9) #endif -p4 G3(X8,B3)q4 +Z4 S3(R5)a5 #endif -#ifdef HB -d bool U6(f O){return O.y>=.0;}d bool U6(G O){return O.y>=.0;} +#ifdef EB +e bool P5(g J){return J.y>=.0;}e bool P5(D J){return J.y>=.0;} #endif -#if defined(HB)&&defined(EB) -d bool w8(f O){return O.x=.0?m5.y-(1.-m5.x)*g9:m5.y+m5.x*g9;}f O;O.x=max(m5.x,.0)+jb;O.y=-m5.y+e6;O.z=f3;O.w=z4;return O;} +#ifdef BB +g Dc(float la,c D8,float G1){c f6=(1.-D8*abs(G1))*.5;float W3,k5;if(abs(la-T6)<1./C8){W3=.0;k5=.0;}else{float ma=tan(la);W3=sign(T6-la)/max(abs(ma),1./Cc);k5=W3>=.0?f6.y-(1.-f6.x)*ma:f6.y+f6.x*ma;}g J;J.x=max(f6.x,.0)+Bc;J.y=-f6.y+f7;J.z=W3;J.w=k5;return J;} #endif -#ifdef EB -d g S4(f O n5){g f3=O.z;g z4=max(O.w,.0);g o5=f3>=.0?J3(z4):.0;if(abs(f3)=.0?f5(k5):.0;if(abs(W3)>La);}d float ob(S D0,c ae){c M1=C0(D0,ae);return(abs(M1.x)+abs(M1.y))*(1./dot(M1,M1));}d bool E6(f f6,f j9,int K,k1(uint)D2,k1(c)be -#ifndef DB -,k1(f)n1 +#if defined(BB)&&defined(BD) +e U l5(int Fc){return U(Fc&((1<>kc);}e float Gc(a0 Y0,c Pf){c e2=Z0(Y0,Pf);return(abs(e2.x)+abs(e2.y))*(1./dot(e2,e2));}e bool p9(g h7,g na,int S,g1(uint)Y2,g1(c)Qf +#ifndef AB +,g1(g)N1 #else -,k1(a0)g6 +,g1(X)i7 #endif -q5){int r7=int(f6.x);float m1=f6.y;float k9=f6.z;int pb=floatBitsToInt(f6.w)>>2;int h6=floatBitsToInt(f6.w)&3;int l9=min(r7,pb-1);int Q3=K*pb+l9;H3 B4=d1(BC,A4(Q3));uint Y=v4(B4.w);M m9=w0(QC,Aa(Y));c qb=uintBitsToFloat(m9.xy);D2=m9.z&0xffffu;uint rb=m9.w;S D0=D1(uintBitsToFloat(w0(JB,D2*4u)));M R3=w0(JB,D2*4u+1u);c S0=uintBitsToFloat(R3.xy);float k2=uintBitsToFloat(R3.z);float l2=uintBitsToFloat(R3.w);uint sb=Y&T2;if(sb!=0u){r7=int(j9.x);m1=j9.y;k9=j9.z;}if(r7!=l9){int tb=Q3+r7-l9;H3 ub=d1(BC,A4(tb));if((v4(ub.w)&(T2|0xffffu))!=(Y&(T2|0xffffu))){bool ce=k2==.0||qb.x!=.0;if(ce){Q3=int(rb);B4=d1(BC,A4(Q3));}}else{Q3=tb;B4=ub;}Y=(v4(B4.w)&~T2)|sb;}float O0; -#ifdef EB -float i6;float e1;if((Y&a3)==j7&&h6==m7){uint vb=v4(B4.z);float g3=float(vb&0xffffu);float O1=float(vb>>16);c0 v7=c0(-g3-1.,O1-g3+1.);if((Y&T2)!=0u)v7=-v7;H3 wb=d1(BC,A4(Q3+v7.x));H3 n9=d1(BC,A4(Q3+v7.y));if((v4(n9.w)&(T2|0xffffu))!=(v4(wb.w)&(T2|0xffffu))){n9=d1(BC,A4(int(rb)));}i6=Y4(wb.z);float xb=Y4(n9.z);e1=xb-i6;if(abs(e1)>O2)e1-=e7*sign(e1);float o9=O1+1.-float(Ma);float yb=clamp(round(abs(e1)/O2*o9),1.,o9-1.);float j6=o9-yb;if(g3<=j6){e1=-(O2*sign(e1)-e1);O1=j6;if(g3==j6)m1=-m1;}else if(g3==j6+1.){g3=.0;O1=.0;m1=.0;}else{g3-=j6+2.;O1=yb;}if(g3==O1){O0=xb;}else{O0=i6+e1*(g3/O1);}}else +h6){int E8=int(h7.x);float G1=h7.y;float oa=h7.z;int Hc=floatBitsToInt(h7.w)>>2;int j7=floatBitsToInt(h7.w)&3;int pa=min(E8,Hc-1);int H4=S*Hc+pa;D4 m5=F1(BC,l5(H4));uint f0=e5(m5.w);uint F8=max(f0&rc,1u);Q qa=P0(XC,F8-1u);c Ic=uintBitsToFloat(qa.xy);Y2=qa.z&0xffffu;uint Jc=qa.w;a0 Y0=j2(uintBitsToFloat(P0(LB,Y2*4u)));Q I4=P0(LB,Y2*4u+1u);c a2=uintBitsToFloat(I4.xy);float G2=uintBitsToFloat(I4.z);float H2=uintBitsToFloat(I4.w);uint Kc=f0&A3;if(Kc!=0u){E8=int(na.x);G1=na.y;oa=na.z;}if(E8!=pa){int Lc=H4+E8-pa;D4 Mc=F1(BC,l5(Lc));if((e5(Mc.w)&(A3|0xffffu))!=(f0&(A3|0xffffu))){bool Rf=G2==.0||Ic.x!=.0;if(Rf){H4=int(Jc);m5=F1(BC,l5(H4));}}else{H4=Lc;m5=Mc;}f0=(e5(m5.w)&~A3)|Kc;}float j1; +#ifdef GB +float k7;float x1;if((f0&U3)==y8&&j7==B8){uint Nc=e5(m5.z);float X3=float(Nc&0xffffu);float f2=float(Nc>>16);U G8=U(-X3-1.,f2-X3+1.);if((f0&A3)!=0u)G8=-G8;D4 Oc=F1(BC,l5(H4+G8.x));D4 ra=F1(BC,l5(H4+G8.y));if((e5(ra.w)&(A3|0xffffu))!=(e5(Oc.w)&(A3|0xffffu))){ra=F1(BC,l5(int(Jc)));}k7=U5(Oc.z);float Pc=U5(ra.z);x1=Pc-k7;if(abs(x1)>x3)x1-=p8*sign(x1);float sa=f2+1.-float(lc);float Qc=clamp(round(abs(x1)/x3*sa),1.,sa-1.);float l7=sa-Qc;if(X3<=l7){x1=-(x3*sign(x1)-x1);f2=l7;if(X3==l7)G1=-G1;}else if(X3==l7+1.){X3=.0;f2=.0;G1=.0;}else{X3-=l7+2.;f2=Qc;}if(X3==f2){j1=Pc;}else{j1=k7+x1*(X3/f2);}}else #endif -{O0=Y4(B4.z);}c B2=c(sin(O0),-cos(O0));c zb=Y4(B4.xy);c w7=c(0,0);if(l2!=.0){l2=max(l2,(U8/3.)/length(C0(D0,B2)));}if(k2!=.0){m1*=sign(determinant(D0));if((Y&l7)!=0u)m1=min(m1,.0);if((Y&Ra)!=0u)m1=max(m1,.0);float S3=l2!=.0?l2:ob(D0,B2)*q3;g Ab=1.;if(S3>k2&&l2==.0){Ab=d4(k2)/d4(S3);k2=S3;}c C4=B2*(k2+S3); -#ifndef DB -float x=m1*(k2+S3);n1.xy=(1./(S3*2.))*(c(x,-x)+k2)+.5;n1.zw=J5(.0); +{j1=U5(m5.z);}c T2=c(sin(j1),-cos(j1));c Rc=U5(m5.xy);c H8=c(0,0);if(H2!=.0){H2=max(H2,(ea/3.)/length(Z0(Y0,T2)));}if(G2!=.0){G1*=sign(determinant(Y0));if((f0&A8)!=0u)G1=min(G1,.0);if((f0&qc)!=0u)G1=max(G1,.0);float J4=H2!=.0?H2:Gc(Y0,T2)*k4;d Sc=1.;if(J4>G2&&H2==.0){Sc=l4(G2)/l4(J4);G2=J4;}c n5=T2*(G2+J4); +#ifndef AB +float x=G1*(G2+J4);N1.xy=(1./(J4*2.))*(c(x,-x)+G2)+.5;N1.zw=J6(.0); #endif -uint p9=Y&a3;if(p9>i7){int k6=2;if((Y&V8)==0u)k6=-k6;if((Y&T2)!=0u)k6=-k6;c0 de=A4(Q3+k6);H3 ee=d1(BC,de);float fe=Y4(ee.z);float l6=abs(fe-O0);if(l6>O2)l6=e7-l6;bool x7=(Y&V8)!=0u;bool ge=(Y&l7)!=0u;float Bb=l6*(x7==ge?-.5:.5)+O0;c y7=c(sin(Bb),-cos(Bb));float q9=ob(D0,y7);float m6=cos(l6*.5);float r9;if((p9==pd)||(p9==qd&&m6>=.25)){float he=(Y&k7)!=0u?1.:.25;r9=k2*(1./max(m6,he));}else{r9=k2*m6+q9*.5;}float v9=r9+q9*q3;if((Y&Qa)!=0u){float Cb=k2+S3;float ie=S3*.125;if(Cb<=v9*m6+ie){float je=Cb*(1./m6);C4=y7*je;}else{c w9=y7*v9;c ke=c(dot(C4,C4),dot(w9,w9));C4=C0(ke,inverse(S(C4,w9)));}}c le=abs(m1)*C4;float Db=(v9-dot(le,y7))/(q9*(q3*2.)); -#ifndef DB -if((Y&l7)!=0u)n1.y=Db;else n1.x=Db; +uint ta=f0&U3;if(ta>x8){int m7=2;if((f0&fa)==0u)m7=-m7;if((f0&A3)!=0u)m7=-m7;U Sf=l5(H4+m7);D4 Tf=F1(BC,Sf);float Uf=U5(Tf.z);float n7=abs(Uf-j1);if(n7>x3)n7=p8-n7;bool I8=(f0&fa)!=0u;bool Vf=(f0&A8)!=0u;float Tc=n7*(I8==Vf?-.5:.5)+j1;c J8=c(sin(Tc),-cos(Tc));float ua=Gc(Y0,J8);float o7=cos(n7*.5);float va;if((ta==nf)||(ta==of&&o7>=.25)){float Wf=(f0&z8)!=0u?1.:.25;va=G2*(1./max(o7,Wf));}else{va=G2*o7+ua*.5;}float wa=va+ua*k4;if((f0&pc)!=0u){float Uc=G2+J4;float Xf=J4*.125;if(Uc<=wa*o7+Xf){float Yf=Uc*(1./o7);n5=J8*Yf;}else{c xa=J8*wa;c Zf=c(dot(n5,n5),dot(xa,xa));n5=Z0(Zf,inverse(a0(n5,xa)));}}c ag=abs(G1)*n5;float Vc=(wa-dot(ag,J8))/(ua*(k4*2.)); +#ifndef AB +if((f0&A8)!=0u)N1.y=Vc;else N1.x=Vc; #endif } -#ifndef DB -n1.xy*=Ab;n1.y=max(n1.y,1e-4);if(l2!=.0){n1.x=e6-n1.x;} -#endif -w7=C0(D0,m1*C4);if(h6!=m7)return false;}else{ -#ifndef DB -n1=f(k9,-1.,.0,.0); -#ifdef EB -if(l2!=.0){n1.y=e6;n1.z=kb;n1.w=k9;if((Y&a3)==j7&&h6==m7){if(e1<.0){i6+=e1;e1=-e1;}float h3=O0-i6;h3=mod(h3+S5,e7)-S5;h3=clamp(h3,.0,e1);if(h3>e1*.5){h3=e1-h3;}c q7=c(sin(h3),cos(h3)); +#ifndef AB +N1.xy*=Sc;N1.y=max(N1.y,1e-4);if(H2!=.0){N1.x=f7-N1.x;} +#endif +H8=Z0(Y0,G1*n5);if(j7!=B8)return false;}else{ +#ifndef AB +N1=g(oa,-1.,.0,.0); +#ifdef GB +if(H2!=.0){N1.y=f7;N1.z=Cc;N1.w=oa;if((f0&U3)==y8&&j7==B8){if(x1<.0){k7+=x1;x1=-x1;}float Y3=j1-k7;Y3=mod(Y3+T6,p8)-T6;Y3=clamp(Y3,.0,x1);if(Y3>x1*.5){Y3=x1-Y3;}c D8=c(sin(Y3),cos(Y3)); #if 0 -float y1=1.+.33*log2(S5/(O2-min(e1,O2-O2/16.)));f me=lb(e1,q7,.5*(y1/3.));float ne=S4(me x1);float oe=Z4(ne);float pe=(.5-oe)*(U8*2.);float qe=y1/max(pe,y1);m1*=qe; +float O1=1.+.33*log2(T6/(x3-min(x1,x3-x3/16.)));g bg=Dc(x1,D8,.5*(O1/3.));float cg=d8(bg i1);float dg=Wb(cg);float eg=(.5-dg)*(ea*2.);float fg=O1/max(eg,O1);G1*=fg; #endif -n1=lb(e1,q7,m1);}w7=C0(D0,(m1*l2)*B2);}else +N1=Dc(x1,D8,G1);}H8=Z0(Y0,(G1*H2)*T2);}else #endif -{w7=sign(C0(m1*B2,inverse(D0)))*q3;}if(bool(Y&T2)!=bool(Y&rd)){n1.x=-n1.x;} +{H8=sign(Z0(G1*T2,inverse(Y0)))*k4;}if(bool(f0&A3)!=bool(f0&pf)){N1*=g(-1.,+1.,+1.,+1.);} #endif -if(h6==Ta)zb=qb;if((Y&Pa)!=0u&&h6!=Sa){return false;}}be=C0(D0,zb)+w7+S0; -#ifdef DB -M T3=w0(JB,D2*4u+2u);g6=Q1(T3.x); +if(j7==tc)Rc=Ic;if((f0&oc)!=0u&&j7!=sc){return false;}}Qf=Z0(Y0,Rc)+H8+a2; +#ifdef AB +Q K4=P0(LB,Y2*4u+2u);i7=i2(K4.x); #else -n1.xy=mix(n1.xy,c(1.,-1.),ed(q.jd!=0u)); +N1.xy=mix(N1.xy,c(1.,-1.),Ve(k.gg!=0u)); #endif return true;} #endif -#if defined(AB)&&defined(GB) -d c c8(Z r5,k1(uint)D2 -#ifdef DB -,k1(a0)g6 +#if defined(BB)&&defined(CB) +e c ob(V i6,g1(uint)Y2 +#ifdef AB +,g1(X)i7 #else -,k1(g)re +,g1(d)hg #endif -q5){D2=floatBitsToUint(r5.z)&0xffffu; -#ifdef DB -M T3=w0(JB,D2*4u+2u);g6=Q1(T3.x); +h6){Y2=floatBitsToUint(i6.z)&0xffffu; +#ifdef AB +Q K4=P0(LB,Y2*4u+2u);i7=i2(K4.x); #else -re=N8(floatBitsToInt(r5.z)>>16); +hg=U9(floatBitsToInt(i6.z)>>16); #endif -c v5=r5.xy;S D0=D1(uintBitsToFloat(w0(JB,D2*4u)));M R3=w0(JB,D2*4u+1u);c S0=uintBitsToFloat(R3.xy);v5=C0(D0,v5)+S0;return v5;} +c j6=i6.xy;a0 Y0=j2(uintBitsToFloat(P0(LB,Y2*4u)));Q I4=P0(LB,Y2*4u+1u);c a2=uintBitsToFloat(I4.xy);j6=Z0(Y0,j6)+a2;return j6;} #endif -#if defined(AB)&&defined(CB) -d c a8(Z r5,k1(uint)D2, -#ifdef DB -k1(a0)g6, +#if defined(BB)&&defined(DB) +e c nb(V i6,g1(uint)Y2, +#ifdef AB +g1(X)i7, #endif -k1(c)se q5){D2=floatBitsToUint(r5.z)&0xffffu;M T3=w0(JB,D2*4u+2u); -#ifdef DB -g6=Q1(T3.x); +g1(c)ig h6){Y2=floatBitsToUint(i6.z)&0xffffu;Q K4=P0(LB,Y2*4u+2u); +#ifdef AB +i7=i2(K4.x); +#endif +c j6=i6.xy;V p7=uintBitsToFloat(K4.yzw);ig=(j6*p7.x+p7.yz)*k.jg;return j6;} +#endif +e d K8(d V1,d H1,d l3){return(H1-V1)/max(1.-V1*l3,n9);} +#ifdef PB +#ifdef K +#define c5 o2 +#define T3(o5) m1=o5;i3 +#else +#define c5 v1 +#define T3(o5) C0(j0,o5);c2; #endif -c v5=r5.xy;Z n6=uintBitsToFloat(T3.yzw);se=v5*n6.x+n6.yz;return v5;} +e uint ya(W0 k6,uint kg){uint za=(k6.y>>5u)*(kg<<5u)+(k6.x>>5u)*(32u<<5u);za+=((k6.x&0x1fu)>>2u)*(32u<<2u)+((k6.y&0x1fu)>>2u)*(4u<<2u);za+=(k6.y&0x3u)*4u+(k6.x&0x3u);return za;}e d Aa(uint lg){return U9(int((lg&ja)-i5))*ha;}e uint q7(d n){return uint(n*wf+.5);} #endif )==="; } // namespace glsl diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.minified.glsl index 80bc07612..6eed5009a 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_path_common.minified.glsl @@ -1,117 +1,125 @@ -#define e6 -2. -#define ib -1.5 -#define jb .25 -#define p7 1e3 -#define kb (p7*p7) +#define f7 -2. +#define Ac -1.5 +#define Bc .25 +#define C8 1e3 +#define Cc (C8*C8) #ifdef VERTEX -P2 wa(U2,wd,BC); +P3 Tb(X2,sf,BC); #ifdef ENABLE_FEATHER -l5(U2,Z5,JC); +e6(X2,d7,QC); #endif -Q2 E3 O3(Va,Td,JB);g4(l8,W9,DC);h4(m8,X9,KB);O3(Wa,Ud,QC);F3 +Q3 B4 G4(vc,Jf,LB);H5(qb,ve,UC);I5(rb,we,OB);G4(wc,Kf,XC);C4 #endif #if defined(ENABLE_FEATHER)||defined(ATLAS_BLIT) -P3(Z5,M8) +V3(d7,T9) #endif #ifdef FRAGMENT -R2 C2(U2,Xa,MC); +y3 U2(X2,xc,DD); #if defined(ENABLE_FEATHER)||defined(ATLAS_BLIT) -l5(U2,Z5,JC); +e6(X2,d7,QC); #endif #ifdef ATLAS_BLIT -y4(Y5,Ya,ND); +j5(X2,yc,VC); #endif -C2(Y5,W8,UB); -#if defined(RENDER_MODE_MSAA)&&defined(ENABLE_ADVANCED_BLEND) -C2(U2,Za,PC); +U2(Y4,R3,DC); +#if defined(RENDER_MODE_MSAA)&&defined(ENABLE_ADVANCED_BLEND)&&!defined(FIXED_FUNCTION_COLOR_OUTPUT) +g7(JD); #endif -S2 P3(Xa,r8) +z3 V3(xc,wb) #ifdef ATLAS_BLIT -P3(Ya,Vd) +V3(yc,I9) #endif -p4 G3(X8,B3)q4 +Z4 S3(R5)a5 #endif #ifdef FRAGMENT -d bool U6(f O){return O.y>=.0;}d bool U6(G O){return O.y>=.0;} +e bool P5(g J){return J.y>=.0;}e bool P5(D J){return J.y>=.0;} #endif #if defined(FRAGMENT)&&defined(ENABLE_FEATHER) -d bool w8(f O){return O.x=.0?m5.y-(1.-m5.x)*g9:m5.y+m5.x*g9;}f O;O.x=max(m5.x,.0)+jb;O.y=-m5.y+e6;O.z=f3;O.w=z4;return O;} +g Dc(float la,c D8,float G1){c f6=(1.-D8*abs(G1))*.5;float W3,k5;if(abs(la-T6)<1./C8){W3=.0;k5=.0;}else{float ma=tan(la);W3=sign(T6-la)/max(abs(ma),1./Cc);k5=W3>=.0?f6.y-(1.-f6.x)*ma:f6.y+f6.x*ma;}g J;J.x=max(f6.x,.0)+Bc;J.y=-f6.y+f7;J.z=W3;J.w=k5;return J;} #endif #ifdef ENABLE_FEATHER -d g S4(f O n5){g f3=O.z;g z4=max(O.w,.0);g o5=f3>=.0?J3(z4):.0;if(abs(f3)=.0?f5(k5):.0;if(abs(W3)>La);}d float ob(S D0,c ae){c M1=C0(D0,ae);return(abs(M1.x)+abs(M1.y))*(1./dot(M1,M1));}d bool E6(f f6,f j9,int K,k1(uint)D2,k1(c)be +e U l5(int Fc){return U(Fc&((1<>kc);}e float Gc(a0 Y0,c Pf){c e2=Z0(Y0,Pf);return(abs(e2.x)+abs(e2.y))*(1./dot(e2,e2));}e bool p9(g h7,g na,int S,g1(uint)Y2,g1(c)Qf #ifndef RENDER_MODE_MSAA -,k1(f)n1 +,g1(g)N1 #else -,k1(a0)g6 +,g1(X)i7 #endif -q5){int r7=int(f6.x);float m1=f6.y;float k9=f6.z;int pb=floatBitsToInt(f6.w)>>2;int h6=floatBitsToInt(f6.w)&3;int l9=min(r7,pb-1);int Q3=K*pb+l9;H3 B4=d1(BC,A4(Q3));uint Y=v4(B4.w);M m9=w0(QC,Aa(Y));c qb=uintBitsToFloat(m9.xy);D2=m9.z&0xffffu;uint rb=m9.w;S D0=D1(uintBitsToFloat(w0(JB,D2*4u)));M R3=w0(JB,D2*4u+1u);c S0=uintBitsToFloat(R3.xy);float k2=uintBitsToFloat(R3.z);float l2=uintBitsToFloat(R3.w);uint sb=Y&T2;if(sb!=0u){r7=int(j9.x);m1=j9.y;k9=j9.z;}if(r7!=l9){int tb=Q3+r7-l9;H3 ub=d1(BC,A4(tb));if((v4(ub.w)&(T2|0xffffu))!=(Y&(T2|0xffffu))){bool ce=k2==.0||qb.x!=.0;if(ce){Q3=int(rb);B4=d1(BC,A4(Q3));}}else{Q3=tb;B4=ub;}Y=(v4(B4.w)&~T2)|sb;}float O0; +h6){int E8=int(h7.x);float G1=h7.y;float oa=h7.z;int Hc=floatBitsToInt(h7.w)>>2;int j7=floatBitsToInt(h7.w)&3;int pa=min(E8,Hc-1);int H4=S*Hc+pa;D4 m5=F1(BC,l5(H4));uint f0=e5(m5.w);uint F8=max(f0&rc,1u);Q qa=P0(XC,F8-1u);c Ic=uintBitsToFloat(qa.xy);Y2=qa.z&0xffffu;uint Jc=qa.w;a0 Y0=j2(uintBitsToFloat(P0(LB,Y2*4u)));Q I4=P0(LB,Y2*4u+1u);c a2=uintBitsToFloat(I4.xy);float G2=uintBitsToFloat(I4.z);float H2=uintBitsToFloat(I4.w);uint Kc=f0&A3;if(Kc!=0u){E8=int(na.x);G1=na.y;oa=na.z;}if(E8!=pa){int Lc=H4+E8-pa;D4 Mc=F1(BC,l5(Lc));if((e5(Mc.w)&(A3|0xffffu))!=(f0&(A3|0xffffu))){bool Rf=G2==.0||Ic.x!=.0;if(Rf){H4=int(Jc);m5=F1(BC,l5(H4));}}else{H4=Lc;m5=Mc;}f0=(e5(m5.w)&~A3)|Kc;}float j1; #ifdef ENABLE_FEATHER -float i6;float e1;if((Y&a3)==j7&&h6==m7){uint vb=v4(B4.z);float g3=float(vb&0xffffu);float O1=float(vb>>16);c0 v7=c0(-g3-1.,O1-g3+1.);if((Y&T2)!=0u)v7=-v7;H3 wb=d1(BC,A4(Q3+v7.x));H3 n9=d1(BC,A4(Q3+v7.y));if((v4(n9.w)&(T2|0xffffu))!=(v4(wb.w)&(T2|0xffffu))){n9=d1(BC,A4(int(rb)));}i6=Y4(wb.z);float xb=Y4(n9.z);e1=xb-i6;if(abs(e1)>O2)e1-=e7*sign(e1);float o9=O1+1.-float(Ma);float yb=clamp(round(abs(e1)/O2*o9),1.,o9-1.);float j6=o9-yb;if(g3<=j6){e1=-(O2*sign(e1)-e1);O1=j6;if(g3==j6)m1=-m1;}else if(g3==j6+1.){g3=.0;O1=.0;m1=.0;}else{g3-=j6+2.;O1=yb;}if(g3==O1){O0=xb;}else{O0=i6+e1*(g3/O1);}}else +float k7;float x1;if((f0&U3)==y8&&j7==B8){uint Nc=e5(m5.z);float X3=float(Nc&0xffffu);float f2=float(Nc>>16);U G8=U(-X3-1.,f2-X3+1.);if((f0&A3)!=0u)G8=-G8;D4 Oc=F1(BC,l5(H4+G8.x));D4 ra=F1(BC,l5(H4+G8.y));if((e5(ra.w)&(A3|0xffffu))!=(e5(Oc.w)&(A3|0xffffu))){ra=F1(BC,l5(int(Jc)));}k7=U5(Oc.z);float Pc=U5(ra.z);x1=Pc-k7;if(abs(x1)>x3)x1-=p8*sign(x1);float sa=f2+1.-float(lc);float Qc=clamp(round(abs(x1)/x3*sa),1.,sa-1.);float l7=sa-Qc;if(X3<=l7){x1=-(x3*sign(x1)-x1);f2=l7;if(X3==l7)G1=-G1;}else if(X3==l7+1.){X3=.0;f2=.0;G1=.0;}else{X3-=l7+2.;f2=Qc;}if(X3==f2){j1=Pc;}else{j1=k7+x1*(X3/f2);}}else #endif -{O0=Y4(B4.z);}c B2=c(sin(O0),-cos(O0));c zb=Y4(B4.xy);c w7=c(0,0);if(l2!=.0){l2=max(l2,(U8/3.)/length(C0(D0,B2)));}if(k2!=.0){m1*=sign(determinant(D0));if((Y&l7)!=0u)m1=min(m1,.0);if((Y&Ra)!=0u)m1=max(m1,.0);float S3=l2!=.0?l2:ob(D0,B2)*q3;g Ab=1.;if(S3>k2&&l2==.0){Ab=d4(k2)/d4(S3);k2=S3;}c C4=B2*(k2+S3); +{j1=U5(m5.z);}c T2=c(sin(j1),-cos(j1));c Rc=U5(m5.xy);c H8=c(0,0);if(H2!=.0){H2=max(H2,(ea/3.)/length(Z0(Y0,T2)));}if(G2!=.0){G1*=sign(determinant(Y0));if((f0&A8)!=0u)G1=min(G1,.0);if((f0&qc)!=0u)G1=max(G1,.0);float J4=H2!=.0?H2:Gc(Y0,T2)*k4;d Sc=1.;if(J4>G2&&H2==.0){Sc=l4(G2)/l4(J4);G2=J4;}c n5=T2*(G2+J4); #ifndef RENDER_MODE_MSAA -float x=m1*(k2+S3);n1.xy=(1./(S3*2.))*(c(x,-x)+k2)+.5;n1.zw=J5(.0); +float x=G1*(G2+J4);N1.xy=(1./(J4*2.))*(c(x,-x)+G2)+.5;N1.zw=J6(.0); #endif -uint p9=Y&a3;if(p9>i7){int k6=2;if((Y&V8)==0u)k6=-k6;if((Y&T2)!=0u)k6=-k6;c0 de=A4(Q3+k6);H3 ee=d1(BC,de);float fe=Y4(ee.z);float l6=abs(fe-O0);if(l6>O2)l6=e7-l6;bool x7=(Y&V8)!=0u;bool ge=(Y&l7)!=0u;float Bb=l6*(x7==ge?-.5:.5)+O0;c y7=c(sin(Bb),-cos(Bb));float q9=ob(D0,y7);float m6=cos(l6*.5);float r9;if((p9==pd)||(p9==qd&&m6>=.25)){float he=(Y&k7)!=0u?1.:.25;r9=k2*(1./max(m6,he));}else{r9=k2*m6+q9*.5;}float v9=r9+q9*q3;if((Y&Qa)!=0u){float Cb=k2+S3;float ie=S3*.125;if(Cb<=v9*m6+ie){float je=Cb*(1./m6);C4=y7*je;}else{c w9=y7*v9;c ke=c(dot(C4,C4),dot(w9,w9));C4=C0(ke,inverse(S(C4,w9)));}}c le=abs(m1)*C4;float Db=(v9-dot(le,y7))/(q9*(q3*2.)); +uint ta=f0&U3;if(ta>x8){int m7=2;if((f0&fa)==0u)m7=-m7;if((f0&A3)!=0u)m7=-m7;U Sf=l5(H4+m7);D4 Tf=F1(BC,Sf);float Uf=U5(Tf.z);float n7=abs(Uf-j1);if(n7>x3)n7=p8-n7;bool I8=(f0&fa)!=0u;bool Vf=(f0&A8)!=0u;float Tc=n7*(I8==Vf?-.5:.5)+j1;c J8=c(sin(Tc),-cos(Tc));float ua=Gc(Y0,J8);float o7=cos(n7*.5);float va;if((ta==nf)||(ta==of&&o7>=.25)){float Wf=(f0&z8)!=0u?1.:.25;va=G2*(1./max(o7,Wf));}else{va=G2*o7+ua*.5;}float wa=va+ua*k4;if((f0&pc)!=0u){float Uc=G2+J4;float Xf=J4*.125;if(Uc<=wa*o7+Xf){float Yf=Uc*(1./o7);n5=J8*Yf;}else{c xa=J8*wa;c Zf=c(dot(n5,n5),dot(xa,xa));n5=Z0(Zf,inverse(a0(n5,xa)));}}c ag=abs(G1)*n5;float Vc=(wa-dot(ag,J8))/(ua*(k4*2.)); #ifndef RENDER_MODE_MSAA -if((Y&l7)!=0u)n1.y=Db;else n1.x=Db; +if((f0&A8)!=0u)N1.y=Vc;else N1.x=Vc; #endif } #ifndef RENDER_MODE_MSAA -n1.xy*=Ab;n1.y=max(n1.y,1e-4);if(l2!=.0){n1.x=e6-n1.x;} +N1.xy*=Sc;N1.y=max(N1.y,1e-4);if(H2!=.0){N1.x=f7-N1.x;} #endif -w7=C0(D0,m1*C4);if(h6!=m7)return false;}else{ +H8=Z0(Y0,G1*n5);if(j7!=B8)return false;}else{ #ifndef RENDER_MODE_MSAA -n1=f(k9,-1.,.0,.0); +N1=g(oa,-1.,.0,.0); #ifdef ENABLE_FEATHER -if(l2!=.0){n1.y=e6;n1.z=kb;n1.w=k9;if((Y&a3)==j7&&h6==m7){if(e1<.0){i6+=e1;e1=-e1;}float h3=O0-i6;h3=mod(h3+S5,e7)-S5;h3=clamp(h3,.0,e1);if(h3>e1*.5){h3=e1-h3;}c q7=c(sin(h3),cos(h3)); +if(H2!=.0){N1.y=f7;N1.z=Cc;N1.w=oa;if((f0&U3)==y8&&j7==B8){if(x1<.0){k7+=x1;x1=-x1;}float Y3=j1-k7;Y3=mod(Y3+T6,p8)-T6;Y3=clamp(Y3,.0,x1);if(Y3>x1*.5){Y3=x1-Y3;}c D8=c(sin(Y3),cos(Y3)); #if 0 -float y1=1.+.33*log2(S5/(O2-min(e1,O2-O2/16.)));f me=lb(e1,q7,.5*(y1/3.));float ne=S4(me x1);float oe=Z4(ne);float pe=(.5-oe)*(U8*2.);float qe=y1/max(pe,y1);m1*=qe; +float O1=1.+.33*log2(T6/(x3-min(x1,x3-x3/16.)));g bg=Dc(x1,D8,.5*(O1/3.));float cg=d8(bg i1);float dg=Wb(cg);float eg=(.5-dg)*(ea*2.);float fg=O1/max(eg,O1);G1*=fg; #endif -n1=lb(e1,q7,m1);}w7=C0(D0,(m1*l2)*B2);}else +N1=Dc(x1,D8,G1);}H8=Z0(Y0,(G1*H2)*T2);}else #endif -{w7=sign(C0(m1*B2,inverse(D0)))*q3;}if(bool(Y&T2)!=bool(Y&rd)){n1.x=-n1.x;} +{H8=sign(Z0(G1*T2,inverse(Y0)))*k4;}if(bool(f0&A3)!=bool(f0&pf)){N1*=g(-1.,+1.,+1.,+1.);} #endif -if(h6==Ta)zb=qb;if((Y&Pa)!=0u&&h6!=Sa){return false;}}be=C0(D0,zb)+w7+S0; +if(j7==tc)Rc=Ic;if((f0&oc)!=0u&&j7!=sc){return false;}}Qf=Z0(Y0,Rc)+H8+a2; #ifdef RENDER_MODE_MSAA -M T3=w0(JB,D2*4u+2u);g6=Q1(T3.x); +Q K4=P0(LB,Y2*4u+2u);i7=i2(K4.x); #else -n1.xy=mix(n1.xy,c(1.,-1.),ed(q.jd!=0u)); +N1.xy=mix(N1.xy,c(1.,-1.),Ve(k.gg!=0u)); #endif return true;} #endif #if defined(VERTEX)&&defined(DRAW_INTERIOR_TRIANGLES) -d c c8(Z r5,k1(uint)D2 +e c ob(V i6,g1(uint)Y2 #ifdef RENDER_MODE_MSAA -,k1(a0)g6 +,g1(X)i7 #else -,k1(g)re +,g1(d)hg #endif -q5){D2=floatBitsToUint(r5.z)&0xffffu; +h6){Y2=floatBitsToUint(i6.z)&0xffffu; #ifdef RENDER_MODE_MSAA -M T3=w0(JB,D2*4u+2u);g6=Q1(T3.x); +Q K4=P0(LB,Y2*4u+2u);i7=i2(K4.x); #else -re=N8(floatBitsToInt(r5.z)>>16); +hg=U9(floatBitsToInt(i6.z)>>16); #endif -c v5=r5.xy;S D0=D1(uintBitsToFloat(w0(JB,D2*4u)));M R3=w0(JB,D2*4u+1u);c S0=uintBitsToFloat(R3.xy);v5=C0(D0,v5)+S0;return v5;} +c j6=i6.xy;a0 Y0=j2(uintBitsToFloat(P0(LB,Y2*4u)));Q I4=P0(LB,Y2*4u+1u);c a2=uintBitsToFloat(I4.xy);j6=Z0(Y0,j6)+a2;return j6;} #endif #if defined(VERTEX)&&defined(ATLAS_BLIT) -d c a8(Z r5,k1(uint)D2, +e c nb(V i6,g1(uint)Y2, #ifdef RENDER_MODE_MSAA -k1(a0)g6, +g1(X)i7, #endif -k1(c)se q5){D2=floatBitsToUint(r5.z)&0xffffu;M T3=w0(JB,D2*4u+2u); +g1(c)ig h6){Y2=floatBitsToUint(i6.z)&0xffffu;Q K4=P0(LB,Y2*4u+2u); #ifdef RENDER_MODE_MSAA -g6=Q1(T3.x); +i7=i2(K4.x); +#endif +c j6=i6.xy;V p7=uintBitsToFloat(K4.yzw);ig=(j6*p7.x+p7.yz)*k.jg;return j6;} +#endif +e d K8(d V1,d H1,d l3){return(H1-V1)/max(1.-V1*l3,n9);} +#ifdef RENDER_MODE_CLOCKWISE_ATOMIC +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +#define c5 o2 +#define T3(o5) m1=o5;i3 +#else +#define c5 v1 +#define T3(o5) C0(j0,o5);c2; #endif -c v5=r5.xy;Z n6=uintBitsToFloat(T3.yzw);se=v5*n6.x+n6.yz;return v5;} +e uint ya(W0 k6,uint kg){uint za=(k6.y>>5u)*(kg<<5u)+(k6.x>>5u)*(32u<<5u);za+=((k6.x&0x1fu)>>2u)*(32u<<2u)+((k6.y&0x1fu)>>2u)*(4u<<2u);za+=(k6.y&0x3u)*4u+(k6.x&0x3u);return za;}e d Aa(uint lg){return U9(int((lg&ja)-i5))*ha;}e uint q7(d n){return uint(n*wf+.5);} #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.exports.h b/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.hpp b/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.hpp new file mode 100644 index 000000000..3d7fa852a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.frag.hpp @@ -0,0 +1,89 @@ +#pragma once + +#include "draw_raster_order_path.frag.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char draw_raster_order_path_frag[] = R"===(#ifdef EB +K1 p0(P2,j0);f1(Q2,e0);p0(d6,f4);f1(F6,H7);L1 v1(HB){B(k1,g); +#ifdef CB +B(l1,d); +#else +B(I,z2); +#endif +B(z0,d); +#ifdef M +B(S1,D); +#endif +#ifdef Z +B(N0,g); +#endif +#ifdef FB +B(Y1,d); +#endif +#if!defined(CB) +v2; +#endif +D O4=unpackHalf2x16(e1(H7));d h9=O4.y;d n0=h9==z0?O4.x:G0(.0); +#ifdef CB +n0+=l1;X1(H7); +#else +n0=nh(n0,I i1);h1(H7,packHalf2x16(A2(n0,z0))); +#endif +d n; +#ifdef YC +if(YC){n=W9(n0,G0(.0),G0(1.));}else +#endif +{n=abs(n0); +#ifdef IC +if(IC&&z0<.0){n=1.-G0(abs(fract(n*.5)*2.+-1.));} +#endif +n=min(n,G0(1.));} +#ifdef M +if(M&&S1.x<.0){d V0=-S1.x; +#ifdef NC +if(NC){d D5=S1.y;if(D5!=.0){D O0=unpackHalf2x16(e1(e0));d A6=O0.y;d j4;if(A6!=V0){j4=A6==D5?O0.x:.0; +#ifndef CB +C0(f4,B0(j4,.0,.0,.0)); +#endif +}else{j4=H0(f4).x; +#ifndef CB +r2(f4); +#endif +}n=min(n,j4);}} +#endif +h1(e0,packHalf2x16(A2(n,V0)));r2(j0);}else +#endif +{ +#ifdef M +if(M){d V0=S1.x;if(V0!=.0){D O0=unpackHalf2x16(e1(e0));d A6=O0.y;n=(A6==V0)?min(O0.x,n):G0(.0);}} +#endif +#ifdef Z +if(Z){d V4=d3(X4(N0));n=clamp(V4,G0(.0),n);} +#endif +i j=M7(k1,n R2);i M1;if(h9!=z0){M1=H0(j0); +#ifndef CB +C0(f4,M1); +#endif +}else{M1=H0(f4); +#ifndef CB +r2(f4); +#endif +} +#ifdef FB +if(FB){if(Y1!=V5(K5)){j.xyz=R4(j.xyz,M1,W5(Y1));}j.xyz*=j.w;} +#endif +#ifdef VB +if(VB){j=h3(j);} +#endif +j+=M1*(1.-j.w);j.xyz=M3(j.xyz,T.xy,k.v3,k.w3);C0(j0,j);X1(e0);} +#if!defined(CB) +w2; +#endif +c2;} +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.minified.frag b/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.minified.frag new file mode 100644 index 000000000..7fe54098b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/draw_raster_order_path.minified.frag @@ -0,0 +1,78 @@ +#ifdef FRAGMENT +K1 p0(P2,j0);f1(Q2,e0);p0(d6,f4);f1(F6,H7);L1 v1(HB){B(k1,g); +#ifdef DRAW_INTERIOR_TRIANGLES +B(l1,d); +#else +B(I,z2); +#endif +B(z0,d); +#ifdef ENABLE_CLIPPING +B(S1,D); +#endif +#ifdef ENABLE_CLIP_RECT +B(N0,g); +#endif +#ifdef ENABLE_ADVANCED_BLEND +B(Y1,d); +#endif +#if!defined(DRAW_INTERIOR_TRIANGLES) +v2; +#endif +D O4=unpackHalf2x16(e1(H7));d h9=O4.y;d n0=h9==z0?O4.x:G0(.0); +#ifdef DRAW_INTERIOR_TRIANGLES +n0+=l1;X1(H7); +#else +n0=nh(n0,I i1);h1(H7,packHalf2x16(A2(n0,z0))); +#endif +d n; +#ifdef CLOCKWISE_FILL +if(CLOCKWISE_FILL){n=W9(n0,G0(.0),G0(1.));}else +#endif +{n=abs(n0); +#ifdef ENABLE_EVEN_ODD +if(ENABLE_EVEN_ODD&&z0<.0){n=1.-G0(abs(fract(n*.5)*2.+-1.));} +#endif +n=min(n,G0(1.));} +#ifdef ENABLE_CLIPPING +if(ENABLE_CLIPPING&&S1.x<.0){d V0=-S1.x; +#ifdef ENABLE_NESTED_CLIPPING +if(ENABLE_NESTED_CLIPPING){d D5=S1.y;if(D5!=.0){D O0=unpackHalf2x16(e1(e0));d A6=O0.y;d j4;if(A6!=V0){j4=A6==D5?O0.x:.0; +#ifndef DRAW_INTERIOR_TRIANGLES +C0(f4,B0(j4,.0,.0,.0)); +#endif +}else{j4=H0(f4).x; +#ifndef DRAW_INTERIOR_TRIANGLES +r2(f4); +#endif +}n=min(n,j4);}} +#endif +h1(e0,packHalf2x16(A2(n,V0)));r2(j0);}else +#endif +{ +#ifdef ENABLE_CLIPPING +if(ENABLE_CLIPPING){d V0=S1.x;if(V0!=.0){D O0=unpackHalf2x16(e1(e0));d A6=O0.y;n=(A6==V0)?min(O0.x,n):G0(.0);}} +#endif +#ifdef ENABLE_CLIP_RECT +if(ENABLE_CLIP_RECT){d V4=d3(X4(N0));n=clamp(V4,G0(.0),n);} +#endif +i j=M7(k1,n R2);i M1;if(h9!=z0){M1=H0(j0); +#ifndef DRAW_INTERIOR_TRIANGLES +C0(f4,M1); +#endif +}else{M1=H0(f4); +#ifndef DRAW_INTERIOR_TRIANGLES +r2(f4); +#endif +} +#ifdef ENABLE_ADVANCED_BLEND +if(ENABLE_ADVANCED_BLEND){if(Y1!=V5(K5)){j.xyz=R4(j.xyz,M1,W5(Y1));}j.xyz*=j.w;} +#endif +#ifdef NEEDS_GAMMA_CORRECTION +if(NEEDS_GAMMA_CORRECTION){j=h3(j);} +#endif +j+=M1*(1.-j.w);j.xyz=M3(j.xyz,T.xy,k.v3,k.w3);C0(j0,j);X1(e0);} +#if!defined(DRAW_INTERIOR_TRIANGLES) +w2; +#endif +c2;} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.hpp new file mode 100644 index 000000000..5331c2814 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.glsl.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "flush_uniforms.glsl.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char flush_uniforms[] = R"===(#ifndef I2 +#define I2(Z3) float Z3; +#endif +#ifndef Z2 +#define Z2(Z3) uint Z3; +#endif +#ifndef Wc +#define Wc(Z3) Z5 Z3; +#endif +#ifndef r7 +#define r7(Z3) c Z3; +#endif +#ifndef Ba +#define Ba(Z3) g Z3; +#endif +#ifndef Xc +#define Xc MB +#endif +l6(k3,Xc)I2(Pb)I2(Yc)I2(Re)I2(Se)Z2(m6)Z2(mg)Z2(De)Z2(Ee)Wc(U7)r7(jg)r7(Zc)Z2(W1)I2(ng)Z2(Y5)I2(O2)I2(ad)Z2(ye)I2(v3)I2(w3)I2(bd)Z2(gg)v7(k) +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.minified.glsl new file mode 100644 index 000000000..3473d2997 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/flush_uniforms.minified.glsl @@ -0,0 +1,19 @@ +#ifndef I2 +#define I2(Z3) float Z3; +#endif +#ifndef Z2 +#define Z2(Z3) uint Z3; +#endif +#ifndef Wc +#define Wc(Z3) Z5 Z3; +#endif +#ifndef r7 +#define r7(Z3) c Z3; +#endif +#ifndef Ba +#define Ba(Z3) g Z3; +#endif +#ifndef Xc +#define Xc MB +#endif +l6(k3,Xc)I2(Pb)I2(Yc)I2(Re)I2(Se)Z2(m6)Z2(mg)Z2(De)Z2(Ee)Wc(U7)r7(jg)r7(Zc)Z2(W1)I2(ng)Z2(Y5)I2(O2)I2(ad)Z2(ye)I2(v3)I2(w3)I2(bd)Z2(gg)v7(k) \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/glsl.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/glsl.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.hpp index b8993470e..5ca72ff19 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/glsl.glsl.hpp @@ -1,331 +1,381 @@ #pragma once -#include "glsl.exports.h" +#include "glsl.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char glsl[] = R"===(#define za -#ifndef WB -#define WB __VERSION__ +const char glsl[] = R"===(#define Xb +#ifndef CC +#define CC __VERSION__ #endif #define c vec2 -#define Z vec3 -#define a4 vec3 -#define f vec4 -#define g mediump float -#define G mediump vec2 -#define A mediump vec3 +#define V vec3 +#define I3 vec3 +#define g vec4 +#define d mediump float +#define D mediump vec2 +#define r mediump vec3 #define i mediump vec4 -#define U5 mediump mat3x3 -#define V5 mediump mat2x3 -#define c0 ivec2 -#define h7 ivec4 -#define N0 uvec2 -#define M uvec4 -#define a0 mediump uint -#define a5 bvec2 -#define G7 bvec3 -#define S mat2 -#define d -#define k1(P1) out P1 -#define i4(P1) inout P1 +#define V6 mediump mat3x3 +#define W6 mediump mat2x3 +#define g5 mediump mat4x4 +#define U ivec2 +#define Z5 ivec4 +#define W0 uvec2 +#define Q uvec4 +#define X mediump uint +#define F4 bvec2 +#define n6 bvec3 +#define w7 bvec4 +#define a0 mat2 +#define e +#define g1(g2) out g2 +#define U4(g2) inout g2 #ifdef GL_ANGLE_base_vertex_base_instance_shader_builtin #extension GL_ANGLE_base_vertex_base_instance_shader_builtin:require #endif -#ifdef KD +#ifdef VD #extension GL_KHR_blend_equation_advanced:require #endif -#if defined(DB)&&defined(BB)&&defined(GL_ES) +#ifdef KD +#extension GL_EXT_shader_framebuffer_fetch:require +#elif defined(LD) +#extension GL_EXT_shader_pixel_local_storage:require +#elif defined(EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +#extension GL_ANGLE_shader_pixel_local_storage:require +#elif defined(MD) +#ifdef GL_ARB_shader_image_load_store +#extension GL_ARB_shader_image_load_store:require +#endif +#ifdef GL_OES_shader_image_atomic +#extension GL_OES_shader_image_atomic:require +#endif +#endif +#if defined(AB)&&defined(Z)&&defined(GL_ES)&&!defined(ZD) #ifdef GL_EXT_clip_cull_distance #extension GL_EXT_clip_cull_distance:require #elif defined(GL_ANGLE_clip_cull_distance) #extension GL_ANGLE_clip_cull_distance:require #endif #endif -#if WB>=310 -#define e5(e,a) layout(binding=e,std140)uniform a{ +#if CC>=310 +#define l6(f,a) layout(binding=f,std140)uniform a{ #else -#define e5(e,a) layout(std140)uniform a{ -#endif -#define W5(a) }a; -#define U0(a) -#define i0(e,W,a) layout(location=e)in W a -#define V0 -#define l0(H7,B,a,W) -#ifdef AB -#if WB>=310 -#define H(e,W,a) layout(location=e)out W a +#define l6(f,a) layout(std140)uniform a{ +#endif +#define v7(a) }a; +#define A1(a) +#define r0(f,W,a) layout(location=f)in W a +#define B1 +#define v0(N8,G,a,W) +#ifdef BB +#if CC>=310 +#define d0(f,W,a) layout(location=f)out W a #else -#define H(e,W,a) out W a +#define d0(f,W,a) out W a #endif #else -#if WB>=310 -#define H(e,W,a) layout(location=e)in W a +#if CC>=310 +#define d0(f,W,a) layout(location=f)in W a #else -#define H(e,W,a) in W a +#define d0(f,W,a) in W a #endif #endif -#define L2 flat -#define o1 -#define p1 -#ifdef CC -#define n0 +#define S4 flat +#define h2 +#define Z1 +#ifdef WB +#define J0 #else #ifdef GL_NV_shader_noperspective_interpolation #extension GL_NV_shader_noperspective_interpolation:require -#define n0 noperspective +#define J0 noperspective #else -#define n0 +#define J0 #endif #endif -#ifdef AB -#define P2 -#define Q2 +#ifdef BB +#define P3 +#define Q3 #endif -#ifdef HB -#define R2 -#define S2 -#endif -#define p4 -#define q4 -#ifdef CC -#define I3(g0,e,a) layout(set=g0,binding=e)uniform highp utexture2D a -#define r4(g0,e,a) layout(set=g0,binding=e)uniform highp texture2D a -#define C2(g0,e,a) layout(set=g0,binding=e)uniform mediump texture2D a -#define y4(g0,e,a) layout(binding=e)uniform mediump texture2D a -#elif WB>=310 -#define I3(g0,e,a) layout(binding=e)uniform highp usampler2D a -#define r4(g0,e,a) layout(binding=e)uniform highp sampler2D a -#define C2(g0,e,a) layout(binding=e)uniform mediump sampler2D a -#define y4(g0,e,a) layout(binding=e)uniform mediump sampler2D a +#ifdef EB +#define y3 +#define z3 +#endif +#define Z4 +#define a5 +#ifdef WB +#define E4(N,f,a) layout(set=N,binding=f)uniform highp utexture2D a +#define d5(N,f,a) layout(set=N,binding=f)uniform highp texture2D a +#define U2(N,f,a) layout(set=N,binding=f)uniform mediump texture2D a +#define j5(N,f,a) layout(binding=f)uniform mediump texture2D a +#if defined(EB)&&defined(AB) +#endif +#elif CC>=310 +#define E4(N,f,a) layout(binding=f)uniform highp usampler2D a +#define d5(N,f,a) layout(binding=f)uniform highp sampler2D a +#define U2(N,f,a) layout(binding=f)uniform mediump sampler2D a +#define j5(N,f,a) layout(binding=f)uniform mediump sampler2D a #else -#define I3(g0,e,a) uniform highp usampler2D a -#define r4(g0,e,a) uniform highp sampler2D a -#define C2(g0,e,a) uniform mediump sampler2D a -#define y4(g0,e,a) uniform mediump sampler2D a -#endif -#ifdef CC -#define P3(m2,a) layout(set=ab,binding=m2)uniform mediump sampler a; -#define G3(m2,a) layout(set=Y5,binding=m2)uniform mediump sampler a; -#define D4(a,p,l) texture(sampler2D(a,p),l) -#define T1(a,p,l,G0) textureLod(sampler2D(a,p),l,G0) +#define E4(N,f,a) uniform highp usampler2D a +#define d5(N,f,a) uniform highp sampler2D a +#define U2(N,f,a) uniform mediump sampler2D a +#define j5(N,f,a) uniform mediump sampler2D a +#endif +#ifdef WB +#define o6(N,f,a) layout(set=N,binding=f)uniform mediump sampler a; +#ifdef YE +#define V3(x7,a) layout(set=vf,binding=x7)uniform mediump sampler a; +#define S3(a) o6(Y4,uf,a) #else -#define P3(m2,a) -#define G3(m2,a) -#define D4(a,p,l) texture(a,l) -#define T1(a,p,l,G0) textureLod(a,l,G0) -#endif -#define o4(A0,p,l) D4(A0,p,l) -#define C7(A0,p,l,G0) T1(A0,p,l,G0) -#define l5(g0,e,a) y4(g0,e,a) -#define T5(a,p,m,w5,K7,G0) T1(a,p,c(m,K7),G0) -#define xe(g0,e,a) I3(g0,e,a) -#define n5 -#define x1 -#define d1(a,l) texelFetch(a,l,0) -#ifdef CC -#define p5(a,p,l,X2) textureGather(sampler2D(a,p),(l)*(X2)) -#elif WB>=310 -#define p5(a,p,l,X2) textureGather(a,(l)*(X2)) +#define V3(x7,a) layout(set=X2,binding=x7)uniform mediump sampler a; +#define S3(a) o6(Y4,R3,a) +#endif +#define p5(a,p,l) texture(sampler2D(a,p),l) +#define m2(a,p,l,X0) textureLod(sampler2D(a,p),l,X0) +#define q5(a,p,l,P1) texture(sampler2D(a,p),l,P1) +#if defined(EB)&&defined(AB) +#extension GL_OES_sample_variables:require +#endif #else -#define p5(a,p,l,X2) E1(d1(a,c0(l)+c0(-1,0)).x,d1(a,c0(l)+c0(0,0)).x,d1(a,c0(l)+c0(0,-1)).x,d1(a,c0(l)+c0(-1,-1)).x) -#endif -#define E3 -#define F3 -#define w3 -#define x3 -#ifdef FE -#define g4(e,f1,a) I3(U2,e,a) -#define O3(e,f1,a) xe(U2,e,a) -#define h4(e,f1,a) r4(U2,e,a) -#define w0(a,v0) d1(a,c0((v0)&Oa,(v0)>>Na)) -#define k4(a,v0) d1(a,c0((v0)&Oa,(v0)>>Na)).xy +#define V3(x7,a) +#define o6(N,f,a) +#define S3(a) +#define p5(a,p,l) texture(a,l) +#define m2(a,p,l,X0) textureLod(a,l,X0) +#define q5(a,p,l,P1) texture(a,l,P1) +#endif +#define g8(h0,p,l) p5(h0,p,l) +#define Q6(h0,p,l,X0) m2(h0,p,l,X0) +#define y7(h0,p,l,P1) q5(h0,p,l,P1) +#define e6(N,f,a) j5(N,f,a) +#define U6(a,p,q,p6,P8,X0) m2(a,p,c(q,P8),X0) +#define og(N,f,a) E4(N,f,a) +#define C3 +#define i1 +#define F1(a,l) texelFetch(a,l,0) +#ifdef WB +#elif CC>=310 +#else +#endif +#define B4 +#define C4 +#define K3 +#define L3 +#ifdef ZE +#define H5(f,y1,a) E4(X2,f,a) +#define G4(f,y1,a) og(X2,f,a) +#define I5(f,y1,a) d5(X2,f,a) +#define P0(a,y0) F1(a,U((y0)&nc,(y0)>>mc)) +#define J5(a,y0) F1(a,U((y0)&nc,(y0)>>mc)).xy #else #ifdef GL_ARB_shader_storage_buffer_object #extension GL_ARB_shader_storage_buffer_object:require #endif -#define g4(e,f1,a) layout(std430,binding=e)readonly buffer f1{N0 V3[];}a -#define O3(e,f1,a) layout(std430,binding=e)readonly buffer f1{M V3[];}a -#define h4(e,f1,a) layout(std430,binding=e)readonly buffer f1{f V3[];}a -#define Jd(e,f1,a) layout(std430,binding=e)buffer f1{uint V3[];}a -#define w0(a,v0) a.V3[v0] -#define k4(a,v0) a.V3[v0] -#define Pd(a,v0) a.V3[v0] -#define c9(a,v0,m) atomicMax(a.V3[v0],m) -#define eb(a,v0,m) atomicAdd(a.V3[v0],m) -#endif -#ifdef _EXPORTED_PLS_IMPL_ANGLE +#define H5(f,y1,a) layout(std430,binding=f)readonly buffer y1{W0 d4[];}a +#define G4(f,y1,a) layout(std430,binding=f)readonly buffer y1{Q d4[];}a +#define I5(f,y1,a) layout(std430,binding=f)readonly buffer y1{g d4[];}a +#define Ea(f,y1,a) layout(std430,binding=f)buffer y1{uint d4[];}a +#define P0(a,y0) a.d4[y0] +#define J5(a,y0) a.d4[y0] +#define kd(a,y0) a.d4[y0] +#define A7(a,y0,q) atomicMax(a.d4[y0],q) +#define Fa(a,y0,q) atomicAdd(a.d4[y0],q) +#define pg(a,y0,q) atomicOr(a.d4[y0],q) +#endif +#ifdef EXPORTED_PLS_IMPL_ANGLE #extension GL_ANGLE_shader_pixel_local_storage:require -#define x2 -#define M0(e,a) layout(binding=e,rgba8)uniform lowp pixelLocalANGLE a -#define Y0(e,a) layout(binding=e,r32ui)uniform highp upixelLocalANGLE a -#define y2 -#define I0(h) pixelLocalLoadANGLE(h) -#define j1(h) pixelLocalLoadANGLE(h).x -#define T0(h,F) pixelLocalStoreANGLE(h,F) -#define l1(h,F) pixelLocalStoreANGLE(h,uvec4(F)) -#define E2(h) -#define i2(h) -#define h2 -#define j2 -#endif -#ifdef GE -#extension GL_EXT_shader_pixel_local_storage:enable -#define x2 __pixel_localEXT z1{ -#define M0(e,a) layout(rgba8)lowp vec4 a -#define Y0(e,a) layout(r32ui)highp uint a -#define y2 }; -#define I0(h) h -#define j1(h) h -#define T0(h,F) h=(F) -#define l1(h,F) h=(F) -#define E2(h) h=h -#define i2(h) h=h -#define h2 -#define j2 -#endif -#ifdef HE -#extension GL_EXT_shader_framebuffer_fetch:require -#define x2 -#define M0(e,a) layout(location=e)inout lowp vec4 a -#define Y0(e,a) layout(location=e)inout highp uvec4 a -#define y2 -#define I0(h) h -#define j1(h) h.x -#define T0(h,F) h=(F) -#define l1(h,F) h.x=(F) -#define E2(h) T0(h,I0(h)) -#define i2(h) l1(h,j1(h)) -#define h2 -#define j2 -#endif -#ifdef IE +#define K1 +#define p0(f,a) layout(binding=f,rgba8)uniform mediump pixelLocalANGLE a +#define f1(f,a) layout(binding=f,r32ui)uniform highp upixelLocalANGLE a +#define L1 +#define H0(h) pixelLocalLoadANGLE(h) +#define e1(h) pixelLocalLoadANGLE(h).x +#define C0(h,C) pixelLocalStoreANGLE(h,C) +#define h1(h,C) pixelLocalStoreANGLE(h,uvec4(C)) +#define r2(h) +#define X1(h) +#define v2 +#define w2 +#endif +#ifdef AF +#ifdef K +#extension GL_EXT_shader_pixel_local_storage2:require +#else +#extension GL_EXT_shader_pixel_local_storage:require +#endif +#define K1 __pixel_localEXT n1{ +#define p0(f,a) layout(rgba8)mediump vec4 a +#define Q8(f,a) layout(rgb10_a2)mediump vec4 a +#define f1(f,a) layout(r32ui)highp uint a +#define L1 }; +#define H0(h) h +#define e1(h) h +#define C0(h,C) h=(C) +#define h1(h,C) h=(C) +#define r2(h) h=h +#define X1(h) h=h +#define v2 +#define w2 +#ifdef K +#define o2(a) layout(location=0,rgba8)out i m1;v1(a) +#define v4(a) layout(location=0,rgba8)out i m1;v1(a) +#endif +#endif +#ifdef BF #ifdef GL_ARB_shader_image_load_store #extension GL_ARB_shader_image_load_store:require #endif #if defined(GL_ARB_fragment_shader_interlock) #extension GL_ARB_fragment_shader_interlock:require -#define h2 beginInvocationInterlockARB() -#define j2 endInvocationInterlockARB() +#define v2 beginInvocationInterlockARB() +#define w2 endInvocationInterlockARB() #elif defined(GL_INTEL_fragment_shader_ordering) #extension GL_INTEL_fragment_shader_ordering:require -#define h2 beginFragmentShaderOrderingINTEL() -#define j2 +#define v2 beginFragmentShaderOrderingINTEL() +#define w2 #else -#define h2 -#define j2 -#endif -#define x2 -#ifdef CC -#define M0(e,a) layout(set=a6,binding=e,rgba8)uniform lowp coherent image2D a -#define Y0(e,a) layout(set=a6,binding=e,r32ui)uniform highp coherent uimage2D a +#define v2 +#define w2 +#endif +#define K1 +#ifdef WB +#define p0(f,a) layout(set=B3,binding=f,rgba8)uniform mediump coherent image2D a +#define Q8(f,a) layout(set=B3,binding=f,rgb10_a2)uniform mediump coherent image2D a +#define f1(f,a) layout(set=B3,binding=f,r32ui)uniform highp coherent uimage2D a #else -#define M0(e,a) layout(binding=e,rgba8)uniform lowp coherent image2D a -#define Y0(e,a) layout(binding=e,r32ui)uniform highp coherent uimage2D a -#endif -#define y2 -#define I0(h) imageLoad(h,I) -#define j1(h) imageLoad(h,I).x -#define T0(h,F) imageStore(h,I,F) -#define l1(h,F) imageStore(h,I,uvec4(F)) -#define E2(h) -#define i2(h) -#ifndef DD -#define DD -#endif -#endif -#ifdef JE -#define x2 -#define O4(e,a) layout(input_attachment_index=e,binding=e,set=a6)uniform lowp subpassInput q6##a; -#define M0(e,a) O4(e,a);layout(location=e)out lowp vec4 a -#define Y0(e,a) layout(input_attachment_index=e,binding=e,set=a6)uniform highp usubpassInput q6##a;layout(location=e)out highp uvec4 a -#define y2 -#define I0(h) subpassLoad(q6##h) -#define j1(h) subpassLoad(q6##h).x -#define T0(h,F) h=(F) -#define l1(h,F) h.x=(F) -#define E2(h) T0(h,subpassLoad(q6##h)) -#define i2(h) l1(h,subpassLoad(q6##h).x) -#define h2 -#define j2 -#endif -#ifdef KE -#define x2 -#define M0(e,a) layout(location=e)out lowp vec4 a -#define Y0(e,a) layout(location=e)out highp uvec4 a -#define y2 -#define I0(h) vec4(0) -#define j1(h) 0u -#define T0(h,F) h=(F) -#define l1(h,F) h.x=(F) -#define E2(h) h=vec4(0) -#define i2(h) h.x=0u -#define h2 -#define j2 -#endif -#ifdef CC +#define p0(f,a) layout(binding=f,rgba8)uniform mediump coherent image2D a +#define Q8(f,a) layout(binding=f,rgb10_a2)uniform mediump coherent image2D a +#define f1(f,a) layout(binding=f,r32ui)uniform highp coherent uimage2D a +#endif +#define L1 +#define H0(h) imageLoad(h,E) +#define e1(h) imageLoad(h,E).x +#define C0(h,C) imageStore(h,E,C) +#define h1(h,C) imageStore(h,E,uvec4(C)) +#define r2(h) +#define X1(h) +#ifndef ND +#define ND +#endif +#endif +#ifdef CF +#define K1 +#define m4(f,a) layout(input_attachment_index=f,binding=f,set=B3)uniform mediump subpassInput B7##a +#define ld(f,a) layout(location=f)out mediump vec4 a +#define p0(f,a) m4(f,a);ld(f,a) +#define f1(f,a) layout(input_attachment_index=f,binding=f,set=B3)uniform highp usubpassInput B7##a;layout(location=f)out highp uvec4 a +#define L1 +#define H0(h) subpassLoad(B7##h) +#define e1(h) subpassLoad(B7##h).x +#define C0(h,C) h=(C) +#define h1(h,C) h.x=(C) +#define r2(h) C0(h,subpassLoad(B7##h)) +#define X1(h) h1(h,subpassLoad(B7##h).x) +#define v2 +#define w2 +#endif +#ifdef DF +#define K1 +#define p0(f,a) layout(location=f)out mediump vec4 a +#define f1(f,a) layout(location=f)out highp uvec4 a +#define L1 +#define H0(h) vec4(0) +#define e1(h) 0u +#define C0(h,C) h=(C) +#define h1(h,C) h.x=(C) +#define r2(h) h=vec4(0) +#define X1(h) h.x=0u +#define v2 +#define w2 +#endif +#ifndef m4 +#define m4 p0 +#endif +#ifdef WB #define gl_VertexID gl_VertexIndex #endif -#ifdef OD -#ifdef CC -#define L7 gl_InstanceIndex +#ifdef AE +#ifdef WB +#define R8 gl_InstanceIndex #else -#ifdef ED -uniform highp int ED; -#define L7 (gl_InstanceID+ED) +#ifdef OD +uniform highp int OD; +#define R8 (gl_InstanceID+OD) #else -#define L7 (gl_InstanceID+gl_BaseInstance) +#define R8 (gl_InstanceID+gl_BaseInstance) #endif #endif #else -#define L7 0 -#endif -#define q5 -#define Y1 -#define q1(a,f0,B,n,K) void main(){int n=gl_VertexID;int K=L7; -#define G6 q1 -#define N4(a,a2,c2,v2,w2,n) q1(a,a2,c2,n,K) -#define L(a,W) -#define P(a) -#define N(a,W) -#define h1(g1) gl_Position=g1;} -#define e2(E4,a) layout(location=0)out E4 ye;void main() -#define f2(F) ye=F -#define y0 gl_FragCoord.xy -#define C5 -#define Y2 -#ifdef DD -#ifdef CC -#define f4(e,a) layout(set=a6,binding=e,r32ui)uniform highp coherent uimage2D a +#define R8 0 +#endif +#define h6 +#define p3 +#define a7 +#define r5 +#define C1(a,c0,G,v,S) void main(){int v=gl_VertexID;int S=R8; +#define S7 C1 +#define E6(a,e3,f3,q3,r3,v) C1(a,e3,f3,v,S) +#define Y(a,W) +#define l0(a) +#define B(a,W) +#define D1(L0) gl_Position=L0;} +#define V2(Q1,a) layout(location=0)out Q1 qg;void main() +#define q6 V2 +#define r6 gl_FrontFacing +#define F2(C) qg=C +#define T gl_FragCoord.xy +#define G6 +#define R2 +#ifdef ND +#ifdef WB +#define o4(f,a) layout(set=B3,binding=f,r32ui)uniform highp coherent uimage2D a +#define md(f,a) layout(set=B3,binding=f,rgb10_a2)uniform mediump coherent image2D a +#else +#define o4(f,a) layout(binding=f,r32ui)uniform highp coherent uimage2D a +#define md(f,a) layout(binding=f,rgb10_a2)uniform mediump coherent image2D a; +#endif +#define N3(h) imageLoad(h,E).x +#define O3(h,C) imageStore(h,E,uvec4(C)) +#define rg(h) imageLoad(h,E) +#define sg(h,C) imageStore(h,E,C) +#define O5(h,q) imageAtomicMax(h,E,q) +#define Q5(h,q) imageAtomicAdd(h,E,q) +#define r4 ,U E +#define U1 ,E +#define v1(a) void main(){U E=ivec2(floor(T)); +#define c2 } +#define nd(C7,h,C) if(!(C7)){C0(h,C);} +#define od(C7,h,C) if(!(C7)){h1(h,C);} #else -#define f4(e,a) layout(binding=e,r32ui)uniform highp coherent uimage2D a -#endif -#define m4(h) imageLoad(h,I).x -#define n4(h,F) imageStore(h,I,uvec4(F)) -#define G5(h,m) imageAtomicMax(h,I,m) -#define H5(h,m) imageAtomicAdd(h,I,m) -#define y3 ,c0 I -#define G1 ,I -#define z2(a) void main(){c0 I=ivec2(floor(y0)); -#define M2 } +#define r4 +#define U1 +#define v1(a) void main() +#define c2 +#define nd(C7,h,C) C0(h,C); +#define od(C7,h,C) h1(h,C); +#endif +#define M5(a) v1(a) +#ifndef o2 +#define o2(a) layout(location=0)out i m1;v1(a) +#endif +#ifndef v4 +#define v4(a) layout(location=0)out i m1;v1(a) +#endif +#define i3 c2 +#if defined(WB)&&!defined(EF) +#define g7(a) layout(input_attachment_index=0,binding=P2,set=B3)uniform mediump subpassInputMS a +#define S8(a) jc(mat4(subpassLoad(a,0),subpassLoad(a,1),subpassLoad(a,2),subpassLoad(a,3)),gl_SampleMaskIn[0]) #else -#define y3 -#define G1 -#define z2(a) void main() -#define M2 -#endif -#define R4(a) z2(a) -#define A3(a) layout(location=0)out i K1;z2(a) -#define F5(a) layout(location=0)out i K1;z2(a) -#define P4 M2 -#define C0(o,r) ((o)*(r)) -precision highp float;precision highp int; -#if WB<310 -d i unpackUnorm4x8(uint u){M A1=M(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return f(A1)*(1./255.);} +#define g7(a) U2(X2,tf,a) +#define S8(a) texelFetch(a,ivec2(floor(T.xy)),0) #endif -#if WB>=310&&defined(AB)&&defined(DB)&&defined(BB) -out gl_PerVertex{float gl_ClipDistance[4];f gl_Position;}; +#define Z0(A,F) ((A)*(F)) +precision highp float;precision highp int; +#if CC<310 +e i tg(uint u){Q R1=Q(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return g(R1)*(1./255.);} +#define unpackUnorm4x8 tg #endif )==="; } // namespace glsl diff --git a/thirdparty/rive_renderer/source/generated/shaders/glsl.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/glsl.minified.glsl index b692a00ad..cf644202d 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/glsl.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/glsl.minified.glsl @@ -1,35 +1,51 @@ -#define za +#define Xb #ifndef GLSL_VERSION #define GLSL_VERSION __VERSION__ #endif #define c vec2 -#define Z vec3 -#define a4 vec3 -#define f vec4 -#define g mediump float -#define G mediump vec2 -#define A mediump vec3 +#define V vec3 +#define I3 vec3 +#define g vec4 +#define d mediump float +#define D mediump vec2 +#define r mediump vec3 #define i mediump vec4 -#define U5 mediump mat3x3 -#define V5 mediump mat2x3 -#define c0 ivec2 -#define h7 ivec4 -#define N0 uvec2 -#define M uvec4 -#define a0 mediump uint -#define a5 bvec2 -#define G7 bvec3 -#define S mat2 -#define d -#define k1(P1) out P1 -#define i4(P1) inout P1 +#define V6 mediump mat3x3 +#define W6 mediump mat2x3 +#define g5 mediump mat4x4 +#define U ivec2 +#define Z5 ivec4 +#define W0 uvec2 +#define Q uvec4 +#define X mediump uint +#define F4 bvec2 +#define n6 bvec3 +#define w7 bvec4 +#define a0 mat2 +#define e +#define g1(g2) out g2 +#define U4(g2) inout g2 #ifdef GL_ANGLE_base_vertex_base_instance_shader_builtin #extension GL_ANGLE_base_vertex_base_instance_shader_builtin:require #endif #ifdef ENABLE_KHR_BLEND #extension GL_KHR_blend_equation_advanced:require #endif -#if defined(RENDER_MODE_MSAA)&&defined(ENABLE_CLIP_RECT)&&defined(GL_ES) +#ifdef ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH +#extension GL_EXT_shader_framebuffer_fetch:require +#elif defined(ATLAS_RENDER_TARGET_R8_PLS_EXT) +#extension GL_EXT_shader_pixel_local_storage:require +#elif defined(ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +#extension GL_ANGLE_shader_pixel_local_storage:require +#elif defined(ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE) +#ifdef GL_ARB_shader_image_load_store +#extension GL_ARB_shader_image_load_store:require +#endif +#ifdef GL_OES_shader_image_atomic +#extension GL_OES_shader_image_atomic:require +#endif +#endif +#if defined(RENDER_MODE_MSAA)&&defined(ENABLE_CLIP_RECT)&&defined(GL_ES)&&!defined(DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS) #ifdef GL_EXT_clip_cull_distance #extension GL_EXT_clip_cull_distance:require #elif defined(GL_ANGLE_clip_cull_distance) @@ -37,161 +53,168 @@ #endif #endif #if GLSL_VERSION>=310 -#define e5(e,a) layout(binding=e,std140)uniform a{ +#define l6(f,a) layout(binding=f,std140)uniform a{ #else -#define e5(e,a) layout(std140)uniform a{ +#define l6(f,a) layout(std140)uniform a{ #endif -#define W5(a) }a; -#define U0(a) -#define i0(e,W,a) layout(location=e)in W a -#define V0 -#define l0(H7,B,a,W) +#define v7(a) }a; +#define A1(a) +#define r0(f,W,a) layout(location=f)in W a +#define B1 +#define v0(N8,G,a,W) #ifdef VERTEX #if GLSL_VERSION>=310 -#define H(e,W,a) layout(location=e)out W a +#define d0(f,W,a) layout(location=f)out W a #else -#define H(e,W,a) out W a +#define d0(f,W,a) out W a #endif #else #if GLSL_VERSION>=310 -#define H(e,W,a) layout(location=e)in W a +#define d0(f,W,a) layout(location=f)in W a #else -#define H(e,W,a) in W a +#define d0(f,W,a) in W a #endif #endif -#define L2 flat -#define o1 -#define p1 -#ifdef TARGET_VULKAN -#define n0 +#define S4 flat +#define h2 +#define Z1 +#ifdef TARGET_SPIRV +#define J0 #else #ifdef GL_NV_shader_noperspective_interpolation #extension GL_NV_shader_noperspective_interpolation:require -#define n0 noperspective +#define J0 noperspective #else -#define n0 +#define J0 #endif #endif #ifdef VERTEX -#define P2 -#define Q2 +#define P3 +#define Q3 #endif #ifdef FRAGMENT -#define R2 -#define S2 -#endif -#define p4 -#define q4 -#ifdef TARGET_VULKAN -#define I3(g0,e,a) layout(set=g0,binding=e)uniform highp utexture2D a -#define r4(g0,e,a) layout(set=g0,binding=e)uniform highp texture2D a -#define C2(g0,e,a) layout(set=g0,binding=e)uniform mediump texture2D a -#define y4(g0,e,a) layout(binding=e)uniform mediump texture2D a +#define y3 +#define z3 +#endif +#define Z4 +#define a5 +#ifdef TARGET_SPIRV +#define E4(N,f,a) layout(set=N,binding=f)uniform highp utexture2D a +#define d5(N,f,a) layout(set=N,binding=f)uniform highp texture2D a +#define U2(N,f,a) layout(set=N,binding=f)uniform mediump texture2D a +#define j5(N,f,a) layout(binding=f)uniform mediump texture2D a +#if defined(FRAGMENT)&&defined(RENDER_MODE_MSAA) +#endif #elif GLSL_VERSION>=310 -#define I3(g0,e,a) layout(binding=e)uniform highp usampler2D a -#define r4(g0,e,a) layout(binding=e)uniform highp sampler2D a -#define C2(g0,e,a) layout(binding=e)uniform mediump sampler2D a -#define y4(g0,e,a) layout(binding=e)uniform mediump sampler2D a +#define E4(N,f,a) layout(binding=f)uniform highp usampler2D a +#define d5(N,f,a) layout(binding=f)uniform highp sampler2D a +#define U2(N,f,a) layout(binding=f)uniform mediump sampler2D a +#define j5(N,f,a) layout(binding=f)uniform mediump sampler2D a #else -#define I3(g0,e,a) uniform highp usampler2D a -#define r4(g0,e,a) uniform highp sampler2D a -#define C2(g0,e,a) uniform mediump sampler2D a -#define y4(g0,e,a) uniform mediump sampler2D a -#endif -#ifdef TARGET_VULKAN -#define P3(m2,a) layout(set=ab,binding=m2)uniform mediump sampler a; -#define G3(m2,a) layout(set=Y5,binding=m2)uniform mediump sampler a; -#define D4(a,p,l) texture(sampler2D(a,p),l) -#define T1(a,p,l,G0) textureLod(sampler2D(a,p),l,G0) +#define E4(N,f,a) uniform highp usampler2D a +#define d5(N,f,a) uniform highp sampler2D a +#define U2(N,f,a) uniform mediump sampler2D a +#define j5(N,f,a) uniform mediump sampler2D a +#endif +#ifdef TARGET_SPIRV +#define o6(N,f,a) layout(set=N,binding=f)uniform mediump sampler a; +#ifdef USE_WEBGPU_SAMPLERS +#define V3(x7,a) layout(set=vf,binding=x7)uniform mediump sampler a; +#define S3(a) o6(Y4,uf,a) +#else +#define V3(x7,a) layout(set=X2,binding=x7)uniform mediump sampler a; +#define S3(a) o6(Y4,R3,a) +#endif +#define p5(a,p,l) texture(sampler2D(a,p),l) +#define m2(a,p,l,X0) textureLod(sampler2D(a,p),l,X0) +#define q5(a,p,l,P1) texture(sampler2D(a,p),l,P1) +#if defined(FRAGMENT)&&defined(RENDER_MODE_MSAA) +#extension GL_OES_sample_variables:require +#endif #else -#define P3(m2,a) -#define G3(m2,a) -#define D4(a,p,l) texture(a,l) -#define T1(a,p,l,G0) textureLod(a,l,G0) -#endif -#define o4(A0,p,l) D4(A0,p,l) -#define C7(A0,p,l,G0) T1(A0,p,l,G0) -#define l5(g0,e,a) y4(g0,e,a) -#define T5(a,p,m,w5,K7,G0) T1(a,p,c(m,K7),G0) -#define xe(g0,e,a) I3(g0,e,a) -#define n5 -#define x1 -#define d1(a,l) texelFetch(a,l,0) -#ifdef TARGET_VULKAN -#define p5(a,p,l,X2) textureGather(sampler2D(a,p),(l)*(X2)) +#define V3(x7,a) +#define o6(N,f,a) +#define S3(a) +#define p5(a,p,l) texture(a,l) +#define m2(a,p,l,X0) textureLod(a,l,X0) +#define q5(a,p,l,P1) texture(a,l,P1) +#endif +#define g8(h0,p,l) p5(h0,p,l) +#define Q6(h0,p,l,X0) m2(h0,p,l,X0) +#define y7(h0,p,l,P1) q5(h0,p,l,P1) +#define e6(N,f,a) j5(N,f,a) +#define U6(a,p,q,p6,P8,X0) m2(a,p,c(q,P8),X0) +#define og(N,f,a) E4(N,f,a) +#define C3 +#define i1 +#define F1(a,l) texelFetch(a,l,0) +#ifdef TARGET_SPIRV #elif GLSL_VERSION>=310 -#define p5(a,p,l,X2) textureGather(a,(l)*(X2)) #else -#define p5(a,p,l,X2) E1(d1(a,c0(l)+c0(-1,0)).x,d1(a,c0(l)+c0(0,0)).x,d1(a,c0(l)+c0(0,-1)).x,d1(a,c0(l)+c0(-1,-1)).x) #endif -#define E3 -#define F3 -#define w3 -#define x3 +#define B4 +#define C4 +#define K3 +#define L3 #ifdef DISABLE_SHADER_STORAGE_BUFFERS -#define g4(e,f1,a) I3(U2,e,a) -#define O3(e,f1,a) xe(U2,e,a) -#define h4(e,f1,a) r4(U2,e,a) -#define w0(a,v0) d1(a,c0((v0)&Oa,(v0)>>Na)) -#define k4(a,v0) d1(a,c0((v0)&Oa,(v0)>>Na)).xy +#define H5(f,y1,a) E4(X2,f,a) +#define G4(f,y1,a) og(X2,f,a) +#define I5(f,y1,a) d5(X2,f,a) +#define P0(a,y0) F1(a,U((y0)&nc,(y0)>>mc)) +#define J5(a,y0) F1(a,U((y0)&nc,(y0)>>mc)).xy #else #ifdef GL_ARB_shader_storage_buffer_object #extension GL_ARB_shader_storage_buffer_object:require #endif -#define g4(e,f1,a) layout(std430,binding=e)readonly buffer f1{N0 V3[];}a -#define O3(e,f1,a) layout(std430,binding=e)readonly buffer f1{M V3[];}a -#define h4(e,f1,a) layout(std430,binding=e)readonly buffer f1{f V3[];}a -#define Jd(e,f1,a) layout(std430,binding=e)buffer f1{uint V3[];}a -#define w0(a,v0) a.V3[v0] -#define k4(a,v0) a.V3[v0] -#define Pd(a,v0) a.V3[v0] -#define c9(a,v0,m) atomicMax(a.V3[v0],m) -#define eb(a,v0,m) atomicAdd(a.V3[v0],m) +#define H5(f,y1,a) layout(std430,binding=f)readonly buffer y1{W0 d4[];}a +#define G4(f,y1,a) layout(std430,binding=f)readonly buffer y1{Q d4[];}a +#define I5(f,y1,a) layout(std430,binding=f)readonly buffer y1{g d4[];}a +#define Ea(f,y1,a) layout(std430,binding=f)buffer y1{uint d4[];}a +#define P0(a,y0) a.d4[y0] +#define J5(a,y0) a.d4[y0] +#define kd(a,y0) a.d4[y0] +#define A7(a,y0,q) atomicMax(a.d4[y0],q) +#define Fa(a,y0,q) atomicAdd(a.d4[y0],q) +#define pg(a,y0,q) atomicOr(a.d4[y0],q) #endif #ifdef PLS_IMPL_ANGLE #extension GL_ANGLE_shader_pixel_local_storage:require -#define x2 -#define M0(e,a) layout(binding=e,rgba8)uniform lowp pixelLocalANGLE a -#define Y0(e,a) layout(binding=e,r32ui)uniform highp upixelLocalANGLE a -#define y2 -#define I0(h) pixelLocalLoadANGLE(h) -#define j1(h) pixelLocalLoadANGLE(h).x -#define T0(h,F) pixelLocalStoreANGLE(h,F) -#define l1(h,F) pixelLocalStoreANGLE(h,uvec4(F)) -#define E2(h) -#define i2(h) -#define h2 -#define j2 +#define K1 +#define p0(f,a) layout(binding=f,rgba8)uniform mediump pixelLocalANGLE a +#define f1(f,a) layout(binding=f,r32ui)uniform highp upixelLocalANGLE a +#define L1 +#define H0(h) pixelLocalLoadANGLE(h) +#define e1(h) pixelLocalLoadANGLE(h).x +#define C0(h,C) pixelLocalStoreANGLE(h,C) +#define h1(h,C) pixelLocalStoreANGLE(h,uvec4(C)) +#define r2(h) +#define X1(h) +#define v2 +#define w2 #endif #ifdef PLS_IMPL_EXT_NATIVE -#extension GL_EXT_shader_pixel_local_storage:enable -#define x2 __pixel_localEXT z1{ -#define M0(e,a) layout(rgba8)lowp vec4 a -#define Y0(e,a) layout(r32ui)highp uint a -#define y2 }; -#define I0(h) h -#define j1(h) h -#define T0(h,F) h=(F) -#define l1(h,F) h=(F) -#define E2(h) h=h -#define i2(h) h=h -#define h2 -#define j2 +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +#extension GL_EXT_shader_pixel_local_storage2:require +#else +#extension GL_EXT_shader_pixel_local_storage:require +#endif +#define K1 __pixel_localEXT n1{ +#define p0(f,a) layout(rgba8)mediump vec4 a +#define Q8(f,a) layout(rgb10_a2)mediump vec4 a +#define f1(f,a) layout(r32ui)highp uint a +#define L1 }; +#define H0(h) h +#define e1(h) h +#define C0(h,C) h=(C) +#define h1(h,C) h=(C) +#define r2(h) h=h +#define X1(h) h=h +#define v2 +#define w2 +#ifdef FIXED_FUNCTION_COLOR_OUTPUT +#define o2(a) layout(location=0,rgba8)out i m1;v1(a) +#define v4(a) layout(location=0,rgba8)out i m1;v1(a) #endif -#ifdef PLS_IMPL_FRAMEBUFFER_FETCH -#extension GL_EXT_shader_framebuffer_fetch:require -#define x2 -#define M0(e,a) layout(location=e)inout lowp vec4 a -#define Y0(e,a) layout(location=e)inout highp uvec4 a -#define y2 -#define I0(h) h -#define j1(h) h.x -#define T0(h,F) h=(F) -#define l1(h,F) h.x=(F) -#define E2(h) T0(h,I0(h)) -#define i2(h) l1(h,j1(h)) -#define h2 -#define j2 #endif #ifdef PLS_IMPL_STORAGE_TEXTURE #ifdef GL_ARB_shader_image_load_store @@ -199,124 +222,151 @@ #endif #if defined(GL_ARB_fragment_shader_interlock) #extension GL_ARB_fragment_shader_interlock:require -#define h2 beginInvocationInterlockARB() -#define j2 endInvocationInterlockARB() +#define v2 beginInvocationInterlockARB() +#define w2 endInvocationInterlockARB() #elif defined(GL_INTEL_fragment_shader_ordering) #extension GL_INTEL_fragment_shader_ordering:require -#define h2 beginFragmentShaderOrderingINTEL() -#define j2 +#define v2 beginFragmentShaderOrderingINTEL() +#define w2 #else -#define h2 -#define j2 -#endif -#define x2 -#ifdef TARGET_VULKAN -#define M0(e,a) layout(set=a6,binding=e,rgba8)uniform lowp coherent image2D a -#define Y0(e,a) layout(set=a6,binding=e,r32ui)uniform highp coherent uimage2D a +#define v2 +#define w2 +#endif +#define K1 +#ifdef TARGET_SPIRV +#define p0(f,a) layout(set=B3,binding=f,rgba8)uniform mediump coherent image2D a +#define Q8(f,a) layout(set=B3,binding=f,rgb10_a2)uniform mediump coherent image2D a +#define f1(f,a) layout(set=B3,binding=f,r32ui)uniform highp coherent uimage2D a #else -#define M0(e,a) layout(binding=e,rgba8)uniform lowp coherent image2D a -#define Y0(e,a) layout(binding=e,r32ui)uniform highp coherent uimage2D a -#endif -#define y2 -#define I0(h) imageLoad(h,I) -#define j1(h) imageLoad(h,I).x -#define T0(h,F) imageStore(h,I,F) -#define l1(h,F) imageStore(h,I,uvec4(F)) -#define E2(h) -#define i2(h) +#define p0(f,a) layout(binding=f,rgba8)uniform mediump coherent image2D a +#define Q8(f,a) layout(binding=f,rgb10_a2)uniform mediump coherent image2D a +#define f1(f,a) layout(binding=f,r32ui)uniform highp coherent uimage2D a +#endif +#define L1 +#define H0(h) imageLoad(h,E) +#define e1(h) imageLoad(h,E).x +#define C0(h,C) imageStore(h,E,C) +#define h1(h,C) imageStore(h,E,uvec4(C)) +#define r2(h) +#define X1(h) #ifndef USING_PLS_STORAGE_TEXTURES #define USING_PLS_STORAGE_TEXTURES #endif #endif #ifdef PLS_IMPL_SUBPASS_LOAD -#define x2 -#define O4(e,a) layout(input_attachment_index=e,binding=e,set=a6)uniform lowp subpassInput q6##a; -#define M0(e,a) O4(e,a);layout(location=e)out lowp vec4 a -#define Y0(e,a) layout(input_attachment_index=e,binding=e,set=a6)uniform highp usubpassInput q6##a;layout(location=e)out highp uvec4 a -#define y2 -#define I0(h) subpassLoad(q6##h) -#define j1(h) subpassLoad(q6##h).x -#define T0(h,F) h=(F) -#define l1(h,F) h.x=(F) -#define E2(h) T0(h,subpassLoad(q6##h)) -#define i2(h) l1(h,subpassLoad(q6##h).x) -#define h2 -#define j2 +#define K1 +#define m4(f,a) layout(input_attachment_index=f,binding=f,set=B3)uniform mediump subpassInput B7##a +#define ld(f,a) layout(location=f)out mediump vec4 a +#define p0(f,a) m4(f,a);ld(f,a) +#define f1(f,a) layout(input_attachment_index=f,binding=f,set=B3)uniform highp usubpassInput B7##a;layout(location=f)out highp uvec4 a +#define L1 +#define H0(h) subpassLoad(B7##h) +#define e1(h) subpassLoad(B7##h).x +#define C0(h,C) h=(C) +#define h1(h,C) h.x=(C) +#define r2(h) C0(h,subpassLoad(B7##h)) +#define X1(h) h1(h,subpassLoad(B7##h).x) +#define v2 +#define w2 #endif #ifdef PLS_IMPL_NONE -#define x2 -#define M0(e,a) layout(location=e)out lowp vec4 a -#define Y0(e,a) layout(location=e)out highp uvec4 a -#define y2 -#define I0(h) vec4(0) -#define j1(h) 0u -#define T0(h,F) h=(F) -#define l1(h,F) h.x=(F) -#define E2(h) h=vec4(0) -#define i2(h) h.x=0u -#define h2 -#define j2 -#endif -#ifdef TARGET_VULKAN +#define K1 +#define p0(f,a) layout(location=f)out mediump vec4 a +#define f1(f,a) layout(location=f)out highp uvec4 a +#define L1 +#define H0(h) vec4(0) +#define e1(h) 0u +#define C0(h,C) h=(C) +#define h1(h,C) h.x=(C) +#define r2(h) h=vec4(0) +#define X1(h) h.x=0u +#define v2 +#define w2 +#endif +#ifndef m4 +#define m4 p0 +#endif +#ifdef TARGET_SPIRV #define gl_VertexID gl_VertexIndex #endif #ifdef ENABLE_INSTANCE_INDEX -#ifdef TARGET_VULKAN -#define L7 gl_InstanceIndex +#ifdef TARGET_SPIRV +#define R8 gl_InstanceIndex #else #ifdef BASE_INSTANCE_UNIFORM_NAME uniform highp int BASE_INSTANCE_UNIFORM_NAME; -#define L7 (gl_InstanceID+BASE_INSTANCE_UNIFORM_NAME) +#define R8 (gl_InstanceID+BASE_INSTANCE_UNIFORM_NAME) #else -#define L7 (gl_InstanceID+gl_BaseInstance) +#define R8 (gl_InstanceID+gl_BaseInstance) #endif #endif #else -#define L7 0 -#endif -#define q5 -#define Y1 -#define q1(a,f0,B,n,K) void main(){int n=gl_VertexID;int K=L7; -#define G6 q1 -#define N4(a,a2,c2,v2,w2,n) q1(a,a2,c2,n,K) -#define L(a,W) -#define P(a) -#define N(a,W) -#define h1(g1) gl_Position=g1;} -#define e2(E4,a) layout(location=0)out E4 ye;void main() -#define f2(F) ye=F -#define y0 gl_FragCoord.xy -#define C5 -#define Y2 +#define R8 0 +#endif +#define h6 +#define p3 +#define a7 +#define r5 +#define C1(a,c0,G,v,S) void main(){int v=gl_VertexID;int S=R8; +#define S7 C1 +#define E6(a,e3,f3,q3,r3,v) C1(a,e3,f3,v,S) +#define Y(a,W) +#define l0(a) +#define B(a,W) +#define D1(L0) gl_Position=L0;} +#define V2(Q1,a) layout(location=0)out Q1 qg;void main() +#define q6 V2 +#define r6 gl_FrontFacing +#define F2(C) qg=C +#define T gl_FragCoord.xy +#define G6 +#define R2 #ifdef USING_PLS_STORAGE_TEXTURES -#ifdef TARGET_VULKAN -#define f4(e,a) layout(set=a6,binding=e,r32ui)uniform highp coherent uimage2D a +#ifdef TARGET_SPIRV +#define o4(f,a) layout(set=B3,binding=f,r32ui)uniform highp coherent uimage2D a +#define md(f,a) layout(set=B3,binding=f,rgb10_a2)uniform mediump coherent image2D a #else -#define f4(e,a) layout(binding=e,r32ui)uniform highp coherent uimage2D a -#endif -#define m4(h) imageLoad(h,I).x -#define n4(h,F) imageStore(h,I,uvec4(F)) -#define G5(h,m) imageAtomicMax(h,I,m) -#define H5(h,m) imageAtomicAdd(h,I,m) -#define y3 ,c0 I -#define G1 ,I -#define z2(a) void main(){c0 I=ivec2(floor(y0)); -#define M2 } +#define o4(f,a) layout(binding=f,r32ui)uniform highp coherent uimage2D a +#define md(f,a) layout(binding=f,rgb10_a2)uniform mediump coherent image2D a; +#endif +#define N3(h) imageLoad(h,E).x +#define O3(h,C) imageStore(h,E,uvec4(C)) +#define rg(h) imageLoad(h,E) +#define sg(h,C) imageStore(h,E,C) +#define O5(h,q) imageAtomicMax(h,E,q) +#define Q5(h,q) imageAtomicAdd(h,E,q) +#define r4 ,U E +#define U1 ,E +#define v1(a) void main(){U E=ivec2(floor(T)); +#define c2 } +#define nd(C7,h,C) if(!(C7)){C0(h,C);} +#define od(C7,h,C) if(!(C7)){h1(h,C);} #else -#define y3 -#define G1 -#define z2(a) void main() -#define M2 -#endif -#define R4(a) z2(a) -#define A3(a) layout(location=0)out i K1;z2(a) -#define F5(a) layout(location=0)out i K1;z2(a) -#define P4 M2 -#define C0(o,r) ((o)*(r)) +#define r4 +#define U1 +#define v1(a) void main() +#define c2 +#define nd(C7,h,C) C0(h,C); +#define od(C7,h,C) h1(h,C); +#endif +#define M5(a) v1(a) +#ifndef o2 +#define o2(a) layout(location=0)out i m1;v1(a) +#endif +#ifndef v4 +#define v4(a) layout(location=0)out i m1;v1(a) +#endif +#define i3 c2 +#if defined(TARGET_SPIRV)&&!defined(INPUT_ATTACHMENT_NONE) +#define g7(a) layout(input_attachment_index=0,binding=P2,set=B3)uniform mediump subpassInputMS a +#define S8(a) jc(mat4(subpassLoad(a,0),subpassLoad(a,1),subpassLoad(a,2),subpassLoad(a,3)),gl_SampleMaskIn[0]) +#else +#define g7(a) U2(X2,tf,a) +#define S8(a) texelFetch(a,ivec2(floor(T.xy)),0) +#endif +#define Z0(A,F) ((A)*(F)) precision highp float;precision highp int; #if GLSL_VERSION<310 -d i unpackUnorm4x8(uint u){M A1=M(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return f(A1)*(1./255.);} -#endif -#if GLSL_VERSION>=310&&defined(VERTEX)&&defined(RENDER_MODE_MSAA)&&defined(ENABLE_CLIP_RECT) -out gl_PerVertex{float gl_ClipDistance[4];f gl_Position;}; +e i tg(uint u){Q R1=Q(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return g(R1)*(1./255.);} +#define unpackUnorm4x8 tg #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/hlsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/hlsl.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/hlsl.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.hpp index 0d66a9ace..c4a80ed31 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/hlsl.glsl.hpp @@ -1,6 +1,6 @@ #pragma once -#include "hlsl.exports.h" +#include "hlsl.glsl.exports.h" namespace rive { namespace gpu { @@ -8,153 +8,161 @@ namespace glsl { const char hlsl[] = R"===(#pragma warning(disable:3550) #pragma warning(disable:4000) #ifndef _ARE_TOKEN_NAMES_PRESERVED -#define g half -#define G half2 -#define A half3 +#define d half +#define D half2 +#define r half3 #define i half4 #define c float2 -#define Z float3 -#define f float4 -#define a5 bool2 -#define G7 bool3 -#define N0 uint2 -#define M uint4 -#define c0 int2 -#define h7 int4 -#define S float2x2 -#define U5 half3x3 -#define V5 half2x3 +#define V float3 +#define g float4 +#define F4 bool2 +#define n6 bool3 +#define w7 bool4 +#define W0 uint2 +#define Q uint4 +#define U int2 +#define Z5 int4 +#define a0 float2x2 +#define V6 half3x3 +#define W6 half2x3 +#define g5 half4x4 #endif -typedef Z a4; -#ifdef PD -#define a0 min16uint +typedef V I3; +#ifdef BE +#define X min16uint #else -#define a0 uint +#define X uint #endif -#define d inline -#define k1(P1) out P1 -#define i4(P1) inout P1 -#define U0(a) struct a{ -#define i0(e,W,a) W a:a -#define V0 }; -#define l0(H7,B,a,W) W a=B.a -#define Qb(e) register(b##e) -#define e5(e,a) cbuffer a:Qb(e){struct{ -#define W5(a) }a;} -#define o1 struct k0{ -#define n0 noperspective -#define OB nointerpolation -#define L2 nointerpolation -#define H(e,W,a) W a:TEXCOORD##e -#define p1 f g1:SV_Position;}; -#define L(a,W) W a -#define P(a) X.a=a -#define N(a,W) W a=X.a -#ifdef AB -#define P2 -#define Q2 +#define e inline +#define g1(g2) out g2 +#define U4(g2) inout g2 +#define A1(a) struct a{ +#define r0(f,W,a) W a:a +#define B1 }; +#define v0(N8,G,a,W) W a=G.a +#define rd(f) register(b##f) +#define l6(f,a) cbuffer a:rd(f){struct{ +#define v7(a) }a;} +#define h2 struct g0{ +#define J0 noperspective +#define NB nointerpolation +#define S4 nointerpolation +#define d0(f,W,a) W a:TEXCOORD##f +#define Z1 g L0:SV_Position;}; +#define Y(a,W) W a +#define l0(a) R.a=a +#define B(a,W) W a=R.a +#ifdef BB +#define P3 +#define Q3 #endif -#ifdef HB -#define R2 -#define S2 +#ifdef EB +#define y3 +#define z3 #endif -#define p4 -#define q4 -#define I3(g0,e,a) uniform Texture2Da:register(t##e) -#define r4(g0,e,a) uniform Texture2Da:register(t##e) -#define C2(g0,e,a) uniform Texture2Da:register(t##e) -#define y4(g0,e,a) uniform Texture2Da:register(t##e) -#define l5(g0,e,a) uniform Texture1DArraya:register(t##e) -#define F4(m2,a) SamplerState a:register(s##m2); -#define P3 F4 -#define G3 F4 -#define d1(a,l) a[l] -#define D4(a,p,l) a.Sample(p,l) -#define T1(a,p,l,G0) a.SampleLevel(p,l,G0) -#define p5(a,p,l,X2) a.Gather(p,(l)*(X2)) -#define T5(a,p,m,w5,K7,G0) a.SampleLevel(p,c(m,w5),G0) -#define o4(A0,p,l) D4(A0,p,l) -#define C7(A0,p,l,G0) T1(A0,p,l,G0) -#define h2 -#define j2 -#ifdef QD -#define n2 RasterizerOrderedTexture2D +#define Z4 +#define a5 +#define E4(N,f,a) uniform Texture2Da:register(t##f) +#define d5(N,f,a) uniform Texture2Da:register(t##f) +#define U2(N,f,a) uniform Texture2Da:register(t##f) +#define j5(N,f,a) uniform Texture2Da:register(t##f) +#define e6(N,f,a) uniform Texture1DArraya:register(t##f) +#define v5(f,a) SamplerState a:register(s##f); +#define V3 v5 +#define o6(N,f,a) v5(f,a) +#define S3(a) v5(R3,a) +#define F1(a,l) a[l] +#define p5(a,p,l) a.Sample(p,l) +#define m2(a,p,l,X0) a.SampleLevel(p,l,X0) +#define q5(a,p,l,P1) a.SampleBias(p,l,P1) +#define U6(a,p,q,p6,P8,X0) a.SampleLevel(p,c(q,p6),X0) +#define g8(h0,p,l) p5(h0,p,l) +#define Q6(h0,p,l,X0) m2(h0,p,l,X0) +#define y7(h0,p,l,P1) q5(h0,p,l,P1) +#define v2 +#define w2 +#ifdef CE +#define J2 RasterizerOrderedTexture2D #else -#define n2 RWTexture2D +#define J2 RWTexture2D #endif -#define x2 -#ifdef FC -#define M0(e,a) uniform n2a:register(u##e) +#define K1 +#ifdef KC +#define p0(f,a) uniform J2a:register(u##f) #else -#define M0(e,a) uniform n2a:register(u##e) +#define p0(f,a) uniform J2a:register(u##f) #endif -#define O4 M0 -#define Y0(e,a) uniform n2a:register(u##e) -#define f4 Y0 -#define m4 j1 -#define n4 l1 -#define y2 -#ifdef FC -#define I0(h) h[I] +#define m4 p0 +#define f1(f,a) uniform J2a:register(u##f) +#define o4 f1 +#define N3 e1 +#define O3 h1 +#define L1 +#ifdef KC +#define H0(h) h[E] #else -#define I0(h) unpackUnorm4x8(h[I]) +#define H0(h) unpackUnorm4x8(h[E]) #endif -#define j1(h) h[I] -#ifdef FC -#define T0(h,F) h[I]=(F) +#define e1(h) h[E] +#ifdef KC +#define C0(h,C) h[E]=(C) #else -#define T0(h,F) h[I]=packUnorm4x8(F) +#define C0(h,C) h[E]=packUnorm4x8(C) #endif -#define l1(h,F) h[I]=(F) -d uint r6(n2G4,c0 I,uint x){uint B1;InterlockedMax(G4[I],x,B1);return B1;} -#define G5(h,m) r6(h,I,m) -d uint v6(n2G4,c0 I,uint x){uint B1;InterlockedAdd(G4[I],x,B1);return B1;} -#define H5(h,m) v6(h,I,m) -#define E2(h) -#define i2(h) -#define q5 -#define Y1 -#define n5 -#define x1 -#define q1(a,f0,B,n,K) cbuffer Mf:Qb(Ua){uint ze;uint a##Nf;uint a##Of;uint a##Pf;}k0 main(f0 B,uint n:SV_VertexID,uint A9:SV_InstanceID){uint K=A9+ze;k0 X; -#define G6(a,f0,B,n,K) k0 main(f0 B,uint n:SV_VertexID){k0 X;f g1; -#define N4(a,a2,c2,v2,w2,n) k0 main(a2 c2,v2 w2,uint n:SV_VertexID){k0 X;f g1; -#define h1(w6) X.g1=w6;}return X; -#define e2(E4,a) E4 main(k0 X):SV_Target{ -#define f2(F) return F;} -#define C5 ,c y0 -#define Y2 ,y0 -#define y3 ,c0 I -#define G1 ,I -#define z2(a) [earlydepthstencil]void main(k0 X){c y0=X.g1.xy;c0 I=c0(floor(y0)); -#define R4(a) z2(a) -#define M2 } -#define A3(a) [earlydepthstencil]i main(k0 X):SV_Target{c y0=X.g1.xy;c0 I=c0(floor(y0));i K1; -#define F5(a) A3(a) -#define P4 }return K1; +#define h1(h,C) h[E]=(C) +e uint w5(J2m3,U E,uint x){uint a1;InterlockedMax(m3[E],x,a1);return a1;} +#define O5(h,q) w5(h,E,q) +e uint x5(J2m3,U E,uint x){uint a1;InterlockedAdd(m3[E],x,a1);return a1;} +#define Q5(h,q) x5(h,E,q) +#define r2(h) +#define X1(h) +#define h6 +#define p3 +#define C3 +#define i1 +#define a7 +#define r5 +#define C1(a,c0,G,v,S) cbuffer ei:rd(uc){uint ug;uint a##fi;uint a##gi;uint a##hi;}g0 main(c0 G,uint v:SV_VertexID,uint D7:SV_InstanceID){uint S=D7+ug;g0 R; +#define S7(a,c0,G,v,S) g0 main(c0 G,uint v:SV_VertexID){g0 R;g L0; +#define E6(a,e3,f3,q3,r3,v) g0 main(e3 f3,q3 r3,uint v:SV_VertexID){g0 R;g L0; +#define D1(y5) R.L0=y5;}return R; +#define V2(Q1,a) Q1 main(g0 R):SV_Target{ +#define q6(Q1,a) Q1 main(g0 R,bool r6:SV_IsFrontFace):SV_Target{ +#define F2(C) return C;} +#define G6 ,c T +#define R2 ,T +#define r4 ,U E +#define U1 ,E +#define v1(a) [earlydepthstencil]void main(g0 R){c T=R.L0.xy;U E=U(floor(T)); +#define M5(a) v1(a) +#define c2 } +#define o2(a) [earlydepthstencil]i main(g0 R):SV_Target{c T=R.L0.xy;U E=U(floor(T));i m1; +#define v4(a) o2(a) +#define i3 }return m1; #define uintBitsToFloat asfloat #define floatBitsToInt asint #define floatBitsToUint asuint #define inversesqrt rsqrt -#define equal(o,r) ((o)==(r)) -#define notEqual(o,r) ((o)!=(r)) -#define lessThan(o,r) ((o)<(r)) -#define C0(o,r) mul(r,o) -#define E3 -#define F3 -#define w3 -#define x3 -#define g4(e,f1,a) StructuredBuffera:register(t##e) -#define O3(e,f1,a) StructuredBuffera:register(t##e) -#define h4(e,f1,a) StructuredBuffera:register(t##e) -#define w0(a,v0) a[v0] -#define k4(a,v0) a[v0] -d G unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return G(f16tof32(x),f16tof32(y));}d uint packHalf2x16(c M1){uint x=f32tof16(M1.x);uint y=f32tof16(M1.y);return(y<<16)|x;}d i unpackUnorm4x8(uint u){M A1=M(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(A1)*(1./255.);}d uint packUnorm4x8(i j){M A1=(M(j*255.)&0xff)<(F)) +#define Z0(A,F) mul(F,A) +#define B4 +#define C4 +#define K3 +#define L3 +#define H5(f,y1,a) StructuredBuffera:register(t##f) +#define G4(f,y1,a) StructuredBuffera:register(t##f) +#define I5(f,y1,a) StructuredBuffera:register(t##f) +#define P0(a,y0) a[y0] +#define J5(a,y0) a[y0] +e D unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return D(f16tof32(x),f16tof32(y));}e uint packHalf2x16(c e2){uint x=f32tof16(e2.x);uint y=f32tof16(e2.y);return(y<<16)|x;}e i unpackUnorm4x8(uint u){Q R1=Q(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(R1)*(1./255.);}e uint packUnorm4x8(i j){Q R1=(Q(j*255.)&0xff)<a:register(t##e) -#define r4(g0,e,a) uniform Texture2Da:register(t##e) -#define C2(g0,e,a) uniform Texture2Da:register(t##e) -#define y4(g0,e,a) uniform Texture2Da:register(t##e) -#define l5(g0,e,a) uniform Texture1DArraya:register(t##e) -#define F4(m2,a) SamplerState a:register(s##m2); -#define P3 F4 -#define G3 F4 -#define d1(a,l) a[l] -#define D4(a,p,l) a.Sample(p,l) -#define T1(a,p,l,G0) a.SampleLevel(p,l,G0) -#define p5(a,p,l,X2) a.Gather(p,(l)*(X2)) -#define T5(a,p,m,w5,K7,G0) a.SampleLevel(p,c(m,w5),G0) -#define o4(A0,p,l) D4(A0,p,l) -#define C7(A0,p,l,G0) T1(A0,p,l,G0) -#define h2 -#define j2 +#define Z4 +#define a5 +#define E4(N,f,a) uniform Texture2Da:register(t##f) +#define d5(N,f,a) uniform Texture2Da:register(t##f) +#define U2(N,f,a) uniform Texture2Da:register(t##f) +#define j5(N,f,a) uniform Texture2Da:register(t##f) +#define e6(N,f,a) uniform Texture1DArraya:register(t##f) +#define v5(f,a) SamplerState a:register(s##f); +#define V3 v5 +#define o6(N,f,a) v5(f,a) +#define S3(a) v5(R3,a) +#define F1(a,l) a[l] +#define p5(a,p,l) a.Sample(p,l) +#define m2(a,p,l,X0) a.SampleLevel(p,l,X0) +#define q5(a,p,l,P1) a.SampleBias(p,l,P1) +#define U6(a,p,q,p6,P8,X0) a.SampleLevel(p,c(q,p6),X0) +#define g8(h0,p,l) p5(h0,p,l) +#define Q6(h0,p,l,X0) m2(h0,p,l,X0) +#define y7(h0,p,l,P1) q5(h0,p,l,P1) +#define v2 +#define w2 #ifdef ENABLE_RASTERIZER_ORDERED_VIEWS -#define n2 RasterizerOrderedTexture2D +#define J2 RasterizerOrderedTexture2D #else -#define n2 RWTexture2D +#define J2 RWTexture2D #endif -#define x2 +#define K1 #ifdef ENABLE_TYPED_UAV_LOAD_STORE -#define M0(e,a) uniform n2a:register(u##e) +#define p0(f,a) uniform J2a:register(u##f) #else -#define M0(e,a) uniform n2a:register(u##e) +#define p0(f,a) uniform J2a:register(u##f) #endif -#define O4 M0 -#define Y0(e,a) uniform n2a:register(u##e) -#define f4 Y0 -#define m4 j1 -#define n4 l1 -#define y2 +#define m4 p0 +#define f1(f,a) uniform J2a:register(u##f) +#define o4 f1 +#define N3 e1 +#define O3 h1 +#define L1 #ifdef ENABLE_TYPED_UAV_LOAD_STORE -#define I0(h) h[I] +#define H0(h) h[E] #else -#define I0(h) unpackUnorm4x8(h[I]) +#define H0(h) unpackUnorm4x8(h[E]) #endif -#define j1(h) h[I] +#define e1(h) h[E] #ifdef ENABLE_TYPED_UAV_LOAD_STORE -#define T0(h,F) h[I]=(F) +#define C0(h,C) h[E]=(C) #else -#define T0(h,F) h[I]=packUnorm4x8(F) +#define C0(h,C) h[E]=packUnorm4x8(C) #endif -#define l1(h,F) h[I]=(F) -d uint r6(n2G4,c0 I,uint x){uint B1;InterlockedMax(G4[I],x,B1);return B1;} -#define G5(h,m) r6(h,I,m) -d uint v6(n2G4,c0 I,uint x){uint B1;InterlockedAdd(G4[I],x,B1);return B1;} -#define H5(h,m) v6(h,I,m) -#define E2(h) -#define i2(h) -#define q5 -#define Y1 -#define n5 -#define x1 -#define q1(a,f0,B,n,K) cbuffer Mf:Qb(Ua){uint ze;uint a##Nf;uint a##Of;uint a##Pf;}k0 main(f0 B,uint n:SV_VertexID,uint A9:SV_InstanceID){uint K=A9+ze;k0 X; -#define G6(a,f0,B,n,K) k0 main(f0 B,uint n:SV_VertexID){k0 X;f g1; -#define N4(a,a2,c2,v2,w2,n) k0 main(a2 c2,v2 w2,uint n:SV_VertexID){k0 X;f g1; -#define h1(w6) X.g1=w6;}return X; -#define e2(E4,a) E4 main(k0 X):SV_Target{ -#define f2(F) return F;} -#define C5 ,c y0 -#define Y2 ,y0 -#define y3 ,c0 I -#define G1 ,I -#define z2(a) [earlydepthstencil]void main(k0 X){c y0=X.g1.xy;c0 I=c0(floor(y0)); -#define R4(a) z2(a) -#define M2 } -#define A3(a) [earlydepthstencil]i main(k0 X):SV_Target{c y0=X.g1.xy;c0 I=c0(floor(y0));i K1; -#define F5(a) A3(a) -#define P4 }return K1; +#define h1(h,C) h[E]=(C) +e uint w5(J2m3,U E,uint x){uint a1;InterlockedMax(m3[E],x,a1);return a1;} +#define O5(h,q) w5(h,E,q) +e uint x5(J2m3,U E,uint x){uint a1;InterlockedAdd(m3[E],x,a1);return a1;} +#define Q5(h,q) x5(h,E,q) +#define r2(h) +#define X1(h) +#define h6 +#define p3 +#define C3 +#define i1 +#define a7 +#define r5 +#define C1(a,c0,G,v,S) cbuffer ei:rd(uc){uint ug;uint a##fi;uint a##gi;uint a##hi;}g0 main(c0 G,uint v:SV_VertexID,uint D7:SV_InstanceID){uint S=D7+ug;g0 R; +#define S7(a,c0,G,v,S) g0 main(c0 G,uint v:SV_VertexID){g0 R;g L0; +#define E6(a,e3,f3,q3,r3,v) g0 main(e3 f3,q3 r3,uint v:SV_VertexID){g0 R;g L0; +#define D1(y5) R.L0=y5;}return R; +#define V2(Q1,a) Q1 main(g0 R):SV_Target{ +#define q6(Q1,a) Q1 main(g0 R,bool r6:SV_IsFrontFace):SV_Target{ +#define F2(C) return C;} +#define G6 ,c T +#define R2 ,T +#define r4 ,U E +#define U1 ,E +#define v1(a) [earlydepthstencil]void main(g0 R){c T=R.L0.xy;U E=U(floor(T)); +#define M5(a) v1(a) +#define c2 } +#define o2(a) [earlydepthstencil]i main(g0 R):SV_Target{c T=R.L0.xy;U E=U(floor(T));i m1; +#define v4(a) o2(a) +#define i3 }return m1; #define uintBitsToFloat asfloat #define floatBitsToInt asint #define floatBitsToUint asuint #define inversesqrt rsqrt -#define equal(o,r) ((o)==(r)) -#define notEqual(o,r) ((o)!=(r)) -#define lessThan(o,r) ((o)<(r)) -#define C0(o,r) mul(r,o) -#define E3 -#define F3 -#define w3 -#define x3 -#define g4(e,f1,a) StructuredBuffera:register(t##e) -#define O3(e,f1,a) StructuredBuffera:register(t##e) -#define h4(e,f1,a) StructuredBuffera:register(t##e) -#define w0(a,v0) a[v0] -#define k4(a,v0) a[v0] -d G unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return G(f16tof32(x),f16tof32(y));}d uint packHalf2x16(c M1){uint x=f32tof16(M1.x);uint y=f32tof16(M1.y);return(y<<16)|x;}d i unpackUnorm4x8(uint u){M A1=M(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(A1)*(1./255.);}d uint packUnorm4x8(i j){M A1=(M(j*255.)&0xff)<(F)) +#define Z0(A,F) mul(F,A) +#define B4 +#define C4 +#define K3 +#define L3 +#define H5(f,y1,a) StructuredBuffera:register(t##f) +#define G4(f,y1,a) StructuredBuffera:register(t##f) +#define I5(f,y1,a) StructuredBuffera:register(t##f) +#define P0(a,y0) a[y0] +#define J5(a,y0) a[y0] +e D unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return D(f16tof32(x),f16tof32(y));}e uint packHalf2x16(c e2){uint x=f32tof16(e2.x);uint y=f32tof16(e2.y);return(y<<16)|x;}e i unpackUnorm4x8(uint u){Q R1=Q(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(R1)*(1./255.);}e uint packUnorm4x8(i j){Q R1=(Q(j*255.)&0xff)<p%6x9wT?xUV~KwpM%3&3%0T z-~HcjCYiYj6{d>Q??yU<*FrVbV*{iftM+ZN?yfEGw=!(=h%>#!>g%4 z#J?8SNX&Rw<{_$wgmT1>5QB|l6~md25DMRCyix}L8HN{K;j_1}{BcZn6IYA{()UIc zBcb%Wm@EY=lBZ>N1B$U>`6FfeSVWWpH6(hZl;1tANGfHc!}1YZU(0b*UZh=-gyo~8 zJV7#p9(+MRsYro}=bdFMMq#E-1m&Z+EJ-T*Nro9BWusA9oK%2;AIzV#Am{&3?jh$t zuPz1_&%DURaj^aWy?V&S&#zsa02zFr9J%-fs}W%3$7OKjGc#hg`QU^q@c`sxoe6_AbRu4VtC& ze+4Gg=5DI1{(pi76b*&R3XqM84h)GSR43>L z5h@J2A%seR?mA+W&>KWWe&jC*6*+<-pCeQXbPo^;;uRo9DPZa~RJEu8iAjev7mZ<5 zC+x<0V#4-9;oF+N6xv@nr1_okF$lkF?PbEUFcYpUV#4_Xopdl(dR^BJn>$7pnEl3y(6aE;VcR7Lfj0f?e9+rAfy;X48Ab22+1I=jWT?JD0 z3Ah+Ys~bBR>2~fYRg_>&I~y(TXQ?knr;Qtn64bOXUcxXfDTa9~?_bRF?|3Q3If|Dv z&fBnbAf1qPm*%(BwmgOUCoJW9QNCi0|#xaG(4WmLkrg`L8L4 zsuN(_m|{FCygA>Vrw+63T%s;yY{vvUFo9)y`Cbj%mhq3yjHjADjo`aThEC!)2znx= zI?jJICZiw}29K}i$TvfsVU`3v6REsjis}$7Gs~|Nj*e&K&ovoP9p{|JWCh&?OK56v92R&t1Ybd&M4sZ&phraFxW@9rxe%InG{`y+WacJf- z#`2Bb@6dULPqmD#Td=h-Z)Rm0O=mpGzai3cDz@R|RLO#Rt5k_h`Oq3P21w90LHCB*A(^p^@hV&TnBSZ>rW0WYes78`@&gUl-YUve^V=XBPsTW z2KHlWz3{>Mc>jLotWS-z^xd$fH)!b{u=H}Pdd*dlU{z$GD#BeJF)!~9F7F;#-pySR zF|X(iu80h*=;hY-nrkD$+TMZMUhcYH^SVfIU9Uio4GT<-3iii$*rO}V3fr^ zzK}Wk>(*?{XZHU9nhNMN delta 2227 zcmZ8i4N%+G9hYQb*|I>!*g=2^A|y-{+X&l%e07x|0kY5*?$RvHWs3}$#R(8&8wND3 zZQ%xzu@(>+1F zHb1y`i_xEmeD>i_+zqh-luk&TBQ-$?(Vcl2UIUmK9x58K_hxG`UFR8Q+rnQH$E->TD zn*ppRIc2AS^=PrqFa{K0dTFeO#XMmQD8NiI_`jqO9t;bghrf!F4{!;jhr5qUARnL> zNFS)+tKtOmfm#K!J6V*41NFR(kE=fV!}H z4z1K33#0hBu?oWNVH$st!(S5cp9JvJ37idU6}UCbDi#9M>46HSKgtYN6pclT!btHn zLNIRyM1qMySLbwVVZi%31wo@go~2a+0@q7Hyr66va|gZ+d_P#+x^pLsT%sx}(Z|DE zbQK10`@sweGFJH1e7=fbTeSGcA>OD@NY`;j8rD!q{d(!Nrbrf-HF;~lSL$$iES*k| z&)K!l)zsl?^R>wySDV-8Xlrx=-wr98D3=-t1LJj6IU1T8o2nhIrpFuW8bPxCTV>5H zha5iZ6ZRU%9&6M3%F+W((yIiMx~rmHX0!8^&1{8~AS$KORFA>V+G(cM>2tI+JIyvL zYqeSItTdf!TwUk%cn`HXT1vV*+$9Yiu9l_}kE_#Z_H?xQT&=@tW>evBz^=hyMcP=P zI+;B{tL9bWAP@_xXa*4Ps>B%}E~>rw58uZ`%r&0uOIo*eXJS6Mqj>|ZA0$}vg3o?E< zF5{h-WK<|$5%3AEvSA9Jr13^hd78r~Sfw+L`~5WjeAcv_Is7B&$WhfVi_%oZ2h z`xch59yjFO4R(AYW)DQO$Ha)TCMQtCjJp9RrS@-;ci@?$@P&5c{qrx%wuI8hVf(|NTQxru!CPS5 z2jQnm=8^2UoSYjF2hc*MpsegyWuxcH&ultp&9t4HI{V9d<&$Inlsz@;OppHd?bm9b zdyP0WlE@rZ?~uHul4kS4V(*JN>zKY%(Z!X$bJwmW7OyOvzm~YMcx~x=RaR`-7|%B( zIqhexlWCWtR~M?(S71o`M*7_~?WtC@s+|vJ>NhnARK9A}dF~xP5X}E>4!Btk8iL-G zc-O}rSTxDPt^PvM)Ew37%`TfO^c*{q;{t@@@O^ezxDvzr}mcZ<{PI^-?2N#&VE;Ggov_#bx7;;H}u diff --git a/thirdparty/rive_renderer/source/generated/shaders/ios/draw.air b/thirdparty/rive_renderer/source/generated/shaders/ios/draw.air index 10c44d42b1b40d83b70ddc89c5a6f22c9031e2d7..b6d1c3929090932d05ca29abaef640e0cfceff67 100644 GIT binary patch literal 37424 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%0AY+1Or#k6jWOfqnFGcX1!%ew)3q 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 literal 139584 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

aYRL6^Lxc*I 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 diff --git a/thirdparty/rive_renderer/source/generated/shaders/ios/rive_pls_ios_simulator.metallib b/thirdparty/rive_renderer/source/generated/shaders/ios/rive_pls_ios_simulator.metallib index 91ba14883ca514c105720f490bb63a31b1f60bae..3d56043e9e7f49b46e7953e9157b4dca5299da28 100644 GIT binary patch literal 140826 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 X&l30rgdbyryZ(P@r#Cv`fzST~4gmJ~ literal 140000 zcmeFa349bq+W6l+Gnwg3CX>!Vn2<^6NjO3hLgyePoO2}v2sj*K5QLswCX&FA1PF*a zS55*B8Zo-8J3-XAq7H``72P=kL>P29)PU$tFk-~G8llm{p`N) z$A(OGJzZT@U0vr>->P1?EMJaeER2JB4|g2Pb5h{5YY6X&%V#$F;gY^*^_!U3 zEBJA^M!0~|IRw+B!a<{B`gE0iWSaL>7+AKJ&r(A)eb=H}I{Tk*3A-as7%R*9^BteR z@%Hu>-?P)hIkOO&qAp?>`r`eEh+C?|Ev+HY@w5;BE z@4@})Yp33~;?ul>bKW?(eUI$T0|~x3_)X2OUyehi|5e;39XcfsJTam9U!xZEub#)- zaca{SS>byY+&hLvT}*x0eDvJA-Z*F?yrFpG;CnHc-&Fnar{Zuc|1a_9Ltp+M{r)-D z{k*deX6)Th{&m%~RcFV3RC49Y8!!Je^t;)ajo(YX;Y!1YhnwZKV1Cp3)-Q*<><8iA z$+~094dxWH{DQ4_g{a{H$w2t4-=5qvWnP(bcD1Xm#P__x!^4&O!u6ZjS+C%i-n+L5 zOrO5UpZ|T&UO$?eYl+ovP=wsM^ZxyXJ0Hx>`0(g6wW9LM-A{hAtL8ax99&bpp?K3g z&ld;3srmCS$Ds&C01i|Je;9|=&u?3{LEGJWvhwQI*V&W48~f1p{a-GR(a+!0fAsMK z&5wBFK#z!n$`=Q}DGh;Y6pmk$4yX+NFb+4zzi{_APq{fKkFj%3FJ1dwh4lg%xc<UycK+4?WcY)B`_EhsffB3GIttIdJ97 zJs%w0K7(yM@#tOee#Uv`Me3fn9>3(i^TQ3tmrZdg zZMmU$D=~-uRTIeNH~`GU-{t=D z=xdL*wM@L9f8To(w;t+Z*vB7BojNAy-bY{jwlSe-#rS@1IpqykJ7IXZ$TxKOP3?!j z9PVBIaD8R);KIUyKhFAV;JOd*pM7M?g~_!Sq`89~6RJ1G96v$N3+%{iq-Fn|Ui8KDLeyLJ5ePl9|w-x(SC|Vf}b22-qMi6wu?eWI#8% zE)ihZ7a$B`NuW1{VW=74>Ed_Ex;gW>WLowkxKS`ZfQX9aY%kPCPu*K7&Q2$vN|crd@GeD%oOPORwS6X3nHs?qU&!JqUhAFB^9q#RE5C z%>=Jj%iB`R+g8S|?%-_}HDuDf+A_l?g11%5)5i9-$DYKgi;|d2?ZG|m;&&wCp7!8@ zcJXmt?8ma$i|*L7I&nW9qs=n0XJXvVwGEkM!`3|BCUZlLreO<4APLReLNshjXvowy zY|i6tHaAq68Zr}joAMeqVg0h$tLb5bI9;%45Kj)p3)=injTumvKoZOANZ(3p8OBmBH15nocrUbKqc z?ZFo%D5}_2Q^VE-o>tSaxy-O7uc2DgP(?Llx=^e(x83&fFZDvuv3(M;8;^yEz4Jq_ z+IU-uh7ASqfG8!mCNyj?H*AJygruN()d{>UC?MVg2|O%B8~hZF1*rncu^>g(KEuqz zx~%ht>^4Pqw<5aJG2^f-%c7WWbj-w}kLa*S^BB7%1`?sGJ=SRxpM(U5bZ8H@Lz+m$ zSMVM!iC*IzEKG`TwAd292g^g)IPFD7ZN|kYmY025R<%GmY z-Nlg*krL4(Ib>bGRLXD7W~oF<+L*0pNEw+6aeGUX$J=6IPcJiQw7goTp{mSKQ`@km z(U7fSXTg8ZOWV}JLpijTx1~oD{i%yPXy$E_^0qR(8qZ0kNw~qxtA+nA?&n(GR?mMV zWO!Ri$ecVl0c$nIgBMg~=D`VANBF>uyvqFGYRCw$n2;*zFt3=95k4~^H4uTJxG^Ck z0}9#ViB%Q2A$jmy$%Jg6P~>m@y13txye$-OE5+Lgjy=ENtV)HR<<>7aQ=z-I4*NyE zVZ16S@?1lq^zm9N-9i)u_=Zv-)NayW32wr4I0ktEBjHag*@b0GheloWxJN_;p@k+# z3Ky|@<;N3noQ5+3{;Z~ikQDx{tK%|>h{~}T*3H64!R55rHc?b)zNsZ}!rbE=MPiPM zRY$W_W;|fAC}2rKz|yRMWlX?bTD(rAGU0VmDz0%Z#&4(iPfPjFF#PAV{QYh|Z6?|L zG&9Za-#I>yg&lyr{0#V=PH4qlz2edcd{(0(%jjs4dkSH7+XlfEEaXd4cugxz7szAn zsN9N6=>U&2L$s4Ut6MRvg+0qz+ft+9-B0kKF3@OrTQ%%WwGA4oA<7vl954xc>5z4F z$R~rsL6tC_?27pqYCuVhT^(CWH_bR|nBh`nA7;-yYM5zc&u|V#Y+`u#m+_{RLAK>h z(>7>K4H|~G2`anm0pRUsZNnO0(Z*x$m1$?cl8=vO67Ft%|Hh_Ka4?6bST&e#UwB42wf>qP#&<&`_l@)Rdt@ zQzL4qF*iiLvoz!{Sjg8ZVV_C(i8Q2_5)QyqPzf=YY_WD(EL0+wbg`G*;=bOPt9Wdw zXfdjN_84Y3RpWdQ!Zd8I<<+(=&c9{~K`9V>U+hV>xL<;*;|FnQ9>h*b%%GaPtj>_- zbj+|QW__9dA1;i|y+j z-P0TMF+?CQYKFxy>#!l(=*VhOWIG)*J8jwB4tU0y&b-4L2p+_0gQu#E`tZ1LfC>51 z%^jpdKBYrGr9!?{3D=RrPiP@nzj1RvcMJPe!s~SWi08_DrR-Evs(?>&Vr-x_Tgc-LOk;tHftdD8ib#c!a+}L|4IwLF$u3h3M9}( zLyd_yjc(YgK^1*XEpPMnx@u@VIv}BVkR`D#6twM7QqrCzB3N}T6LWLBL(_`SU)2Vy zi0xs#WAE>hDRTni=^c^`(4!)_RJnj!UQ$(EzJA^2 zqB3>Wn(FecB{GesqJ*j}sZm!@o4gmP^fWpxJtc$Apb|V6N=qgWi6$*XPSxdADMjlm zHRTm0Da9r0)>lJT zSCnS>rAV-NDza(TSC`ko1Ecfub(_>xuP+?s%zBi zib~d$7cW3AyivS$=1DeWtyo{AMt-j;UsqgGizHPg>SAP8*HmpRs_{myd|l~!Pk`0x zTyeX>WcDv*Lk9_ zT)qLtIYXu>rRC$ELOBJ)XuT>Tp7*Ql(_1N zSh)PTKKcf_Ea&CNIHf)I$$j<|Cp{pWJScC+txfoe4dP+{*SWcoG5xxd6*W>`nVGj0 zyYE38zXIo{g|(Tt_w)>0Ty^o|?yEf~S2=s^?_9|ZU8WwjNL_SjZS}nPr0S=m$1`;+ z?PvQ|4V>(|a`xj(xq)~0c33j9M<1bIJ@mTe(7`Ehq`mgq;c2ffX5G~}DS6>LB?B)8 zr|fuf;EUj$DPNwhT-Vw=ijhPv3S97L^?{^EpH6Z_k9P;4_xwDxSL4A9;#Va=JHXpo zplO4;#{o5Nw#%WvB0k<83@H!I6jV{(`ZY4+6Gr%%3aagpK2&*!e5Mj!vuJg^EeW1h zrM3ZTL{z61X!ba=4&yWS8D_OQSZkqy5?|^SU!uf)YV_N$i?yr8u6A*^w<1*A@Q`a% zNUtgc+C~(&Gf>%Z!Q?q-?la8T1C0xNmf0{98XA)WsxeGWVc4I*4Cly_QN1LAzhx(H z-ZW!4jtBBdINJHm?KhyK$?JAvPOJrM$&nJ;9XU5nJOuyA6kS{b`)oWGaXc<>kg^## zAz?G~z)`4{A};?~U=`s|?Y*@FS?zDqxfoQ2n~ON8E);p){K+fSvvy-Yaf71f(b-{D4(QL+bE`pmRY+Qz4kF12TwPQV$ISzn%iUhCF13R zZ>1rZEt2bX!G^W`hIeXZ1 z%!)bt6mvQhbM`CdSlF`@5(^df@_fUcuHJg-C@b@N??L?z?o>B> zxmnuU+bE6SX3K~>`fRjbE>dW_m`;f)AVajSjlGgGd|odV7~|a1hG^DGjD7#?!6(-d z-O{#o#NNGO)4@AtwB3B&EUf92bg*d<_b{|WU|svVq<~%WxUZ|H6X+$HA z3hGLs#M%%)mVBV6DoZy<{7-Ek8l_{{2Fg2LPZN@HMr=PSE}o+V#_ZGJER5Z1L1hKG zR>2<{Z{@=uk`=%oI*^INa3KpEE8q`$$({p^_iKIU{_Du1m!e6xuoedC~fHsGUwJP1%%Dnwpui5zKP0vs;(oKDYqlp}q=u zlbJDDje0nf%hy+@rl-&;^yKPt6j06jDiro`eM%e56QOwioIa%z66ROwQ%J8q#WPvwi&*T(pqkOe zBGrHy4NNYMP>%eJ=B11cecjDvY|zVS=pjW9@|=Rvf%pnU9tS^T?7CRj2tPG2O8Oav z3$$ME*kVrV#22MwAyyy%wDN@wiWm(H@j-)=^+VlFA*vUTt7G5+AtgZ*8q{qwu}0{JZy`X>ay#8kkCea}R0fgm1DWAQsYl;|8osnR!lUm9NBWL%zrLdp z^c}{0GGUm$qoh%^SEtQp(RsRP@Z>ig#lJ~MVfW}LFpPqihblX)DVUY>XHaP!l%jzb z=otjV^bD`ZCFtZLoDwfEaemVm{H8DXkJcA7qx?HkUoatI8HOQ!!SP+Ph*4qB8uSzKW8I?d)35>F<*3>{h8Z;2Yhr}a>|KP>FmC#LxLHW<94vN49=oG-0 zb?et?K<%L^DXJ;oG&I!yu>!%bGk|oBC+5<6Eex|8XuU=dPw-OpDlA>FOm&(ruuoOc zPFfX_$(F&7Lggey>6{aS0KK{?O+j(f$Mx7V7VVws5;TsQx+reeIRPuG)h1A6a!aXr zUEu4DJ5IlJ`k60x?BDsK^H|H|fr@nzl5-;lls)TwgTdb|xW5`kgFE>!HdF^y&v+qd zM$&f&lOFZT``00P)ctD>3yPAy+iG|kT>mb*WNcdeH-;>6zY**G>RQ8h?&&aSP6 z?lDqrz|2_{XtT>2GGV&T+hK;D-iR4K=oLGErjxmu;Qh?39us>O6eXY;X%B|ZBy=@@ zy59?vj%cnF_1mj|I6r#DqhWa;W-cKmp*Id1^4^j2b`X$k>`C0pW(*SrR@O4v81fh9 z{|@Vjvsh$3nhh&sZ|LAv)1G-#&$J~B8EOcaUd^mf;>psfM#XfPK5SIXYBPW;8|D;2 ztsM>X5&INbPPU~t(IgRrnjMWJ{GDe{Ki@Zzp$&d~m!Q`q{MyC6tO~ip2tk()vqOJ% zaeJ-8&q?7oSVgC>1S!3T&uGH%p&=7815BE<@fb&4@-IA2OCQSlJaaHs&OSg`58`V7 zY$fX|V>p9!M>j#4^NK8I4>}!-u}qCKQrKJ4~E3_&W_t{;^Fz(0C~9j zr)QL{F-X~WyW-}VHE(OE$>MDW?OquhW{$VO6zJ_9-!pNJ^oCH1p~Urye=uZg++uFf zh#EFRnSzvrsdwKnb6AdofMD_)8^n5~Gck%AEo{Wzq4L;;j?huoC{DSyB5NEw%RmL2 zgOAm4VBR{Kyo%lsdX<44nW8(fWa%q9i}!8r3+@_^-D{E9z1G$rRS4SP+;7p{YzjZm zRepy~@iG`Sd#Y$OMngJ_aFbNjXwNbQD)uIavr6Tze0mSBd0)9+dS^K2izgW-Bx2q< zqxDI$IGpn$RN74xhOL47(&Df+F^K5&F6L$&|%Tyk*?L>=8i2@He@G;Bm&sDR5c>U(RI z<3gTn!JMI5yBL>0p0+GmbTR_9J!MNdn09&{EfR45=?vv$Q0#!x*P(6!2;(@+)0tsd z9SfQKnluDP#Dlunt1=k)3%l`vmM2~ZO*=pl8_b@$M|kH9Zog`rVr-M@p3Z8QGSrw|hyq?6+#Ql6OnZ``} zVP5ylNr+T;CTU`^=jY>sc!7hqV}dx5onlcfp62tnG4a1?Of0_&^Y&`i(3lwJ?U|C{ z^Y(UguxDl-G8me-FSFK2J%eZT+URk6*`Kpn47vmd+&ihu7DZWAU_o6mtEoSBPX@-) z!Z{jnYbA^4Wvqou(2JnJjw#}vXuJpv0C*-v_IhPe=*AKL2X(NA-5y#ljUkcOTI5>L zRK~ul_4tHBWAc=-XSu^Y|LzB#PdsSDNioI~e!6$W?Yr`ec*7 F@#wA@4i~QZ`HjChMRStVmb-1Fm6A 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 diff --git a/thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_appletvos.metallib b/thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_appletvos.metallib new file mode 100644 index 0000000000000000000000000000000000000000..d2b0d56cc0fac84b0972eaac1ee36e8177de6dda GIT binary patch literal 144106 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

_Yboz& zQZKee6|vVo%hPLzJ@bG)Q{F+Ib@0`*;SYMBKZM-;hD_BdENkPOcJsfXlCf#oe6H zr~yOCLN8cc&V5!c*sJFaNOv(FYGbakvTw0)%7*;PUFJsign^ihj5jkLdv*HD*{`OC zrM=p=@AU%9!-Mr3u#FaC<2G{R{Jy^PA1*rDbLiy2T>o26?SMR&VQ;3s{yHSMEMPvG zIT@(NYm<7v+za_F&%gUp{_5l}53g!+$E^;S_h?o411nAQil_X2y=gb(&wMhnM82^} zy>ULup$Vxo2M!I+^> zAhjr@CImGLQgb1-^GIz7sXc_$W*15ux(oM;=c>|sin` zlGJkR%9^_Cv>8RGVLbapkvaypoV%vHzS*Rg+-+cLdQ%Adl=AvE)+tGLfWAG7DQv7B zOqT617A?TID-1JF+Wgj>SM{0P#+8$BaH-ka?WD=|q9W>2TiAhip(2DCuoXbiCk>KC z`tu~K_OQWkBT!LRFUSIS-P2J3zsN-Z+y=(HM7zeoSbWo4?Nbcnm;sYteoPzMXAen8 z=n*^If^qwe0G61@;D9%MJox9$YQ{V_U_p3GHOwTN+;8I|8Nk8x!uJE$5+TdDG(KI& zWz0Snez9}$V7Gv+1K2fk`USi!>meJJi3=jncp9ouLxZ6JxuhKtR)kCsLEwQlPMH^( zZbb;|Bnp{+29W6*9)(Qrppoe|W@g_cgiN<^ULXXaen3*!#`!$~G^Mx*Ve^VCVRuj@ zb?r(5$Vinofr+1&cmQB&O0-O6#Q9o+9eRcda1XwTKW=Id_@QNL5n&+t(>oYT5W#2x z!n0AGEhi#Y$-E;}b9Re*gJk>o-3)F#cb&l*SmhQj)hP2|ldL7f_%rH=rmkvdCc8`G zj9^~`wA*=k-o`>J2?Tle?DJ02WD|Vf#%hUQWH4I!sm+e8A(LM%a8p{D*+ca3jN(4v z7&7s@avIHk%$na#+HZz^@d^VNoO^=!({~zI>Ftj*+c-f0TT3~kk_Q#zTW$s*o)mz1 zq;t^LDPc*2CZ&7~;WLS4Tx^1hcIekG!=}TKIg*L2Hm&*bxTljfZ4nK=iJ|ZM@ISjZGqdd#^1oUSHvZuWo(p3?GuPC2nIh{@% z>#NMPuaN9D?C;)T3b^aECa@Kf0W4{Ys9#C`Py1Qiq{$F`C|^goiGRfwms-(k9^Oa@V%bzIRM)7Jdf+xVVEE3d;SdSXrkNE zJkqBpn{3qW z*T;D{$~}o*53f2Sm!)KQINwHz!9z*$!uj;{>pC-kKD!)-`S{=9fI-{nM*cU>Z^Zw` zkHu{X`e{rpUZ>fL@j0RZt=Iq_D@(3Cc^l${`}Cv*?EUJHITg5)5rU~;-I;)Lwl1>ncn3!RPm-x54&lgIpTBT{hx7W{8Aum8>8nnCoU%ZX4A zZk;jz8@JlU`PKq%Z7y&c)OdbDLU1ef{}%t7$*z$VCSIH8OFhc}mf_=GTS?w0zsktP z-}b%xdmnbKBaR6i9|zqh(pZ*H4++x8eH?UgPc^$nIOwpAfy_A~c*J;FPQtYgd~M

MU2M@5Ld~G^INYQ9tn`0?XNb{L-vMnyc9-Mh7 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 aiVx1Ye}2O^kpavp{0JO874jn|0sbF*fGyns literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_appletvsimulator.metallib b/thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_appletvsimulator.metallib new file mode 100644 index 0000000000000000000000000000000000000000..d59b667dfa59a0822198bfc66b0f85dacd62947f GIT binary patch literal 144570 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

7oy!Xq}Dr8t8-e0{p&0 z*pP$552gLm)%)%1_e4O_-EaL)Luve?^}E8ge!noZelPu*^?T{9>-Qt>^?MfFiz>Wx zX#K80>vzTA`n?pb-Eu#EXu3!Wf~_V&>?7Z*;USF=JfSJ>mVFLtC%bH&O$-kk z2Gl-(gU1`R_<~h%WcDX1-IkOy?TOu%kbR)Q(j~T7!us$j4Z^A2I(V3s)PX16&?a`m zqbS|fW-LpQNi*^-GbN|Ts+v;CT#?1JAP5qIR;`w&PRtJ}rF30loM0W1c zJP@ip1fJ*P6JCV!tTxCEaOYA3g;VK#6GVHV5I721Ke!iKD6|J)b-zB%|CgWUQ<`8( zm)LAc*=I^TV{tv}3u$eiyibFk$W^wdU?B(1Sca0c(cVr2dH_`uPu0LP-!j;_m>X8<-0ZK?rgpk{EpIHWcm+vaWk7M&IvCEN(? z2`mHiID>bKL$-f`xMFB~{3Wmtw|F1G{|hnUX?JR+FvV_3IUt<6&y;k=GPzzC(kM*X zr}+ji=d2!&IXu+ei=L}gwFO229I!Cgz9~|sED^i57UM8=#t@DQ^d;p zy9w8GYz#fJZV;+b!@%J<(Jthb$9E;H3s3|y`W`Y3 z!$N9FtONGm-q_eecC>)@a7xV_d5Y_?>pj#GdyokCYsTL+y)5MdxL8sUnIX)#WQAg5 zMR-6no>FLh9hLeBE}jR9s0HI}KJoH}Sd{vYrcM_=q}jW2G`74&dDazda3JsrU{Ow) zkjnj>A&m1T|Bez7(s%$=Zo^d+5Zk;l&t2S9ULW8MWhLO z`~&ucEw}@F(nia8TnQfoL)epidxe_60UVrUSn{yQ5R@&aSSo1QT($B^6V5 z4pM?UR-=^oawzj#dq+8h4|`vDyW~&5wxkRMzcr~>R=<7u&ZI`3K8N3NgIO=WExbec ze@I`%aT;aMe@L!_FzpD3<=rA080ZK39>p#Cp5OqDXMi@T;Q?F{kZJ-9p*kp_LTw0` z=?IvM4_oLM#;TP>K#tl#1mvrmh=4+MFA-o=E5!}k%m$Gm{TBm$G7`4g(E9mTJ<_jw zr2k|+(l^i%@25vf^s;e}LR%ivB>~Q7OF+(L-HrHhX^Gt0DWpZ3fdcnL{QPfX zeTH;pKLgKM%>#Mv@{p4ZiJIY#0UmP0Wfv}qXjWS zfKddDR$%lah5{HRz~}@9BL)VboTRIO(Sy_?0dz<3N8{{Y5! zh!F{lCScUHk%D*-T0RySF973NV5~-ralm*P7%u~3KVppUV!E|@uUP4R`W&E{qNV!) z&E%CD-NiVyTY%llUO;TcJBZ!Mv)jCQE#rji=7|7udXM!wcn^@%$T=TL&2z7GNUJBZ znehd&^8GDoA9oz5PinvTr0wrs`!T|x_R2DPWgERRL6>W!P{`fBJ&$_?&y4if}k#k;WgsDECKnAXIwR>gT zy|#>-{RY#1%75xLz=sUa$sC?nGCY6F@K~wS?*C|vj)vOZV;}w$=4Qy2Uqii@D0hm8nZ=D;L+N zF0rOAX{cP>n7U+p>JnS(lIF_AyE^_$U~j^Cs8<$EWZ6NdT>CG4-O6Z}RyqyP@{5Lt zcH_Z-hO$-{66YO0Ee4rN+

=v!UIlpMs1%z0h-8zUMO)o{hDh&)yCh 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_xros_simulator.metallib b/thirdparty/rive_renderer/source/generated/shaders/ios/rive_renderer_xros_simulator.metallib new file mode 100644 index 0000000000000000000000000000000000000000..7d172f9780fc8a6354e2a6cdee42d4cabcd48fed GIT binary patch literal 144378 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 Z44*H7OpE~6s{;FhkVzca)C!rC3II=VOP~M% literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/ios/tessellate.air b/thirdparty/rive_renderer/source/generated/shaders/ios/tessellate.air index 4f9ac56ec561fab27d499f1e7f2232354771e0b2..86fe6a35acc82fdbe75ee8239fab6711a8e1bcc4 100644 GIT binary patch delta 9015 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 QQf*yTjdY1UGd<~l0Mydv+5i9m delta 8524 zcmZX33w%>m*6%sVX>yvR?MYhN(I5Q`ArEop0n@CuvgT=9iqk z_kXXw_Fil6_1GuY=J6e=U-+~52z)Z&x2F6^YA*W35rs@dR0@HZwNE^{1o@kg(H-p>01uUOyBYs2$wxm=D^+7=c0u7D%Yh?6IvGkw>ks8 zzT}V)ap0?I*9gur9lLp8_Q4bH<3a85`A!qb(RjlI%zZA~Bs{6A_Av8(pRFNeWe!?U zmXo{e8Rv2pZdbpWeXQZdmctael=#Gt7p?e4=BJmi?sA&3VPS;Ki!Q>FZ2Wz@>*p<9 z2wB<94itY|$^YP;({`U>G2vx>km1MuwB0Aj%@0y`N{}bu_kV`I%0_GY9ZA2(EEmjr zZkvz2V6($)<+d94H*I#bwC- zg!2QzZKJq*DDEzxjy{2`$-qc6^#n2lGiuL$Plg-9ZBjGb%@iX*thqgs%1i;=7#)0X zC8TKmu-JC}m+Flty)hX7@a5k^&%WGP(M4=r1U$h6WBl1X<~K7tVT}k2ABYqll5!vBoIf ziy$O4W6Oj!i8^J12j-ibb%jKJ$%jj5&m zRsG<~UVHaQ>H|`~k^28l`SlC89-Q*#LnZ@PjYxq10si zrv8spYgnvLQBSEbx0>X8>D|!T`C;W_^>i?QWw0JklhTJqut&X%MA~U~3Wu-L$ULLYq*11nL>}Y5*wKUYr zlx=e>cb9G4RM2)m_-j=R{I%*n%H?I1yH!BBsqtx3i)wkA%wMT&;UdSFK~F zE?ceLL~A|YrYn<{>y~R*c?vRCdK?*!X=QX7CEMQ6VrtyfP@+=ON>ynY?GaCt%rG=G zH9x(>)F^M;WtP|O+R|7rZ`!iEp`>Zoj+QOkJ$2Je7G!Bzbej-}82$jxn$Z))gCcGo z-YMy#ikoS>F(nV@Plx(0ptv5ugH6!Mp8-G{0Ji`*%K$S0_$>ev0DQ{;G5}r#zyo!@h8AP~a%W`st9GuPq7F*Mk&aMOK<5dZj}nyJRa? zkyxEXuX1QAE;-cDQ?DN`b7&sFWUEn;-_mK{8`6F-r>V&E=4_Guig84{N$;8$DvW4L zA}rFWDfyUHYPFHKqRp;ADbqx=$DwIo!?C<;;Gd_SwaEe1KQ+#O!^#)sSlRN3Hs_?K z;ufp)G%9vEN+ZFXbAbwmW`{ZzXg(Al)iK=tw)qUWlXm3u#mD(C6pz?{{Kg>}3rfcA z8m@kNSbc*fj|5HJ0YCq|c@(V}XO&7?iPQlrzs<{4ssC>A?K-dKe{n6XiB4_y^DoVy z_R@~k{NIke$S#?%-R0u4aHKc%$;<4L)+Rq6D3;EkUZfo_rLKLIe=c$vm4{I|*=BVG z1=SDTVlSBpEwNVW!}KWYA=jYbqAbEHCEIA7TBOQ9ujW-1blZ1Qmj%fsZu@H9D@Mt% z(xS`d_xg|83rOyVVRsL^pyFjCkI^#qhMIS^fD|dOSbN!zGsLdB4wGn(O;qrrs7Mj= zrOpb7RM<&c=jN%f*Jy{2cbnGvc`CtKihrJFU*$zhT?Bf4bZDG6?`o<_U^J(HL+c3s zex8-|+DMnp^PePT>4CcVyiGiUPLF*f_8GU(fuGuc<7;1h%lU|#J-wUtcm9P4{{qE7 zYvs52cS>^1EeKCi&26FbY{~Dt4qbWu%FEvzI(_&|_+nSd?ZzEP1Jl1iXRJJ;_K)Qi@0=@t>+Mw? z$IJ(g>kEn>{&Pd=>6F7~R^HimxU}naV2aFMZK~_v*1RmQsQD%FEZ2c`49DB=kA3yw z7o$s)>vK;5!>l*yxBB1l^`DjhN%{8Mz;TuRS$!eH?arA;cAUQbLGht8w?8O3eWvlK zbv8IZ50-QF$)m_Ob;(wmr4HhL5(R&k%&Eh``;C_`MHnv_h=M;~rE_Qq^~ha1=GeuY z9{&OGpu>x9%&j$3Qatkl%{fD0c^r<&ZoI)ajq^Nm@pQ#rdYF)mNF22j0ZQkqtiZcIxAmm6=zMgy?oDa#j?!m1?TU)`Bw#JCuUX zv<8YpYK%RNRe{ygjRXNAF{#Shj@;n`C823!gU2+fy-Z+05EF$Ue}ov8j%_GrLgixk zVMo=%qiBf=xp~jPzIo4Lu)+tsdGDTOCR2^DlW-i*VXFAYT~!E5gf$}?iQiTX4I3S8 z4BMFox@u$rOZ~4J7SS~e58?hAEmRQJPtAfBf_s+!1i@Izc}R34CZZdmpWKN5J|whK z_?Pd|_wNp#YI+H+!?vCIXK^x1u<_SIqam;djN(UGp*WnG*w(lral*(1?CWzTvE zRUyD%$P9VwldWg=LFHShlvtXHe~zc#a;NroaR?P#eQtYf&)0j}rps8rs`C8j^l6^+ z(@mCNX(2Q)+EEK;!^v4mAj)nEX`nSo*l0(30vM`xB(vNcAV>j%93Yqn1lxgN6bJ?a zJhZf>_9BsG?n^J?ylv(GzD5yFTKE0nK^u6zIlmI@LbI0ina&@0e)Ikm&ALYFYkTQe z+R}Lf)6Vp7d^ap?e$QrZ55eyt`8`zUfUI+X?i{G-98h;YukU=`(D{5#=YX+uU^BnR z+&R$Nnc~~AU)QpQSuKjJraq~=Go^Cqrl>dr8fI30;NTAHCv#hK7@zlu^gza$!U3tXy0``iRV;w zm?r{Bd%bf;S%;-EFFi_3u*k3y*O=`yWgIWU%0{k=(P=E+bIK0F8!WcbhCbZ36$z!- z=EDJHE3i4IL+gF1&!fbwH!=}44~}qc z@|ES-D^ysSVX%(gXHFyO8oJgPwN8SwL-b{$+tF?kKLp;^#M_y#GRxi=^Y z%^*t^!^F6zC_=ciPS|ps*IWUcld72rlHPVAlH=2~9wH@r+}!zEG{XC` zf!%7No!5#{J6i0z=0cx|jyaNb2TXVgfzCKffr0Cz20ygH&lom^dce*gcE(gJGP#~D@ z?34qFWL-2562t}i18*@ZVzpfn6|<#wuXpK*9GBetQ92F#;=^EHBzoE)CHHU5fH|`z zXIDia@PeSl%NarIU+?3+=H{KGu}mw7#)^uj5Tlm)KDNl&dP58j4P9u>;@n|Y8uMyT z`Esi0NvCM$oEG-7Id_@fKZ6Pk+F@KJV`5k6SXw4`7WKzz^qL`eEK+cFuugmR{3zR3> zi~X>{6%pOaE|Q9F-cildcwmu0iTyYtY8L#F&i)myfLmbAQ zF!~r`b$UaT*uqdB!P9|yGL#^>LyANslIA8lp7PDqP8mVI$Y{ufm=ZUN*`h9zjB3Sc zv%uk*+(9H)^JEv90Ues5+N~n zg_VZKXo-ST4_4{YFhkCv2e6NXo5n>pd01p%XFKRV`xrkYRMeJ{W*adopF{NIheVKn$9(ghSMtg;nu}jOOVUD?|uDDIw4&y8yb7(M& zkg@XJNpX4VM)H;_5;7~5UV^bxd-O2h%?)gHT`ETBxuy8=%QYA1(ed;*rJR1jlbK!8 z;`bCC{`14dn(|>^X4~DI1Vf8)w#ND}wIL)7Y=t#`;NKodIE&t8l~YRnoj`^$F+6&- z%(wNvoYxgA{3-Q#@GI4Gpo2-}2f7oMd%Wl5#ZwnsZ<%%U45Kx)&3dgxr^Yv9V{8;HOm@CJ{PI(P$!$&E$T!HdvN27a4 zqN8pPQ949Cu2?aWvIgJl-ZH9gM|jznQr6_}@MKHAWo>m{Belq!)|_{V4Rttrpi7E3 zD?1F`uB1r2ZpsbqKO?E4B|^(!bp+gSt9woz-saEEv}S4VTgHG^9ca;+$&e7;2OcP) z`9G}YR*N69XZc-+Ck0~11QmvJm{&8@o)44hfVs-t^xkhoxOR2G6&I(g*EYI0eG-z>-#U4K82 z{2D0KP-vt(3^TVXJB;v{F2#<@jp{tcyWs8eu!2H+z(=T~n*3QC9zJ9Qw=M}0;mfcC z>X0z2Y9e@b=(*c1I)h~<>x-ctE5d0&SXm?N#AR}`cA zNNKacCM+a#&or^Gr3Df?C`u122=r7~f$dNiIs~jpSeYrL-mVoDzT}-NX)<`d<{`j+H zl2RT8ga0R*mE);(n6l(7Rna9JP;EK!IT={|-o1ZMW{B$0X1}F|#borUkoo0T#45)1*e|aF!|U-Y>){c5g_zE6%S!~vI)CbYdC46D!gn2$mpIa~3JyeSMUAZ# z!qcyFB0}&}@f;-VNH-ceFh%^j@n1v=*%P%ob@a$mit8FHnseWf&&2!4bN&;eh zJc=khM+(v()snrH)+8C@T4Q;_-E?iCH8^R!TC%6o3XY^78%iLNK~;js!hn~66k}4_ z?6FGEcLnpZoq-yxS@5blRSv0{Hz>c(`)K^id{S!ToAY1qv$$( zDJ?Oj{nu0&vOS6Q3z9{G>QTqy3h+k;@W!0&{!GuALMnTNV-|*$#mi|)Ano7xjaldU zs&EE+#*~hUBiyvwH#KfpSfG!rP+$YYU{C))UJi& zo#C9y6K;9lE1qsShc1M^LFkipPW9a(R#uli0y@P8)t4y2a}oY^>;{BA?pIT1?Vm(k z+dYBBSUuf=@b=Oj1UzEfx_%j!)yqow*4aX%(0R=~D3n2zHfEs9*R~##dOd4PQds6b z&(@L}bde`i^8Vr=d8-OI$HVbjICXCl-523%!2i3oih_{HWJIw9Qu4IWt(%`9wypQP zUuwwrUF|TZvY)XnbV1Bmfc*vztdG3}a=fe)j8RHL3o(o5A$ivP?2nfc+(ahf6}PCN z6@P7z6OcF-W3RyA(aHB&E3 zBGN)aP{%# zu)=yVV`j4;usY`>q0RsoFReKzB-E?}qwS!tb2;p`hpVv`1sKm{_I6{YX8p)TGbX-X z72$uB@*j-X*yhOmgXRg-}7Ql z4YP%Dmt8Az!_s5kF)%wUa|RO*&$Lk+dlD9*`Mu|| zvc%&1C#9oj{-hZ7rq5zQMxB*8ne)#nYS?M(9*tcRTF%)s=U@wmj9961g*$%3?ml6Z5Ave^7^q))m4slta(Gkx%RHud#mXGD{DJGbvMQSXhC*T2$BSjNSR9HI?;Co z75V1BT9dAey4{b&-n2Ie5ad%J5V4P*XIvJ%{6f+^&#J@<3Tib>6Fwxcn+at(l$lVb zGa!88{Y;(ezo{xhSBao{6@E;~T1ZEgL30W_?Kv7vuV4zu>r~!_;+gKlggSp4_!W;d87Aec@FEb xI?uN9hgrX_^1M?n@Bg8^63u{rcVOJSvJ#US29|7jx>=#}JT|{18tf3{e*h+a)rJ57 diff --git a/thirdparty/rive_renderer/source/generated/shaders/macosx/color_ramp.air b/thirdparty/rive_renderer/source/generated/shaders/macosx/color_ramp.air index bd3ec013d3bf020d906d7e5a9bd653eaa8fe2ee2..3d87e2c1b04c20483f6c1563709c69c57a648ce1 100644 GIT binary patch delta 2013 zcmZ9N4^R`?9mhADKf5Fw2r*!g#4aLUfRMy&49M7P{#<}ckbp-EUI!8&KoCL>0)s$j9V zINp@mzFo|#F;$4XI9hTV^;txQ3Q<%&97e}W4!)8=DVMW#oMcHvbR5?t>5F8n(=h>y zQ&EHpf>?#fq#sXy(;Fh86u}czXJc6fjN~V%S3hW&&S!kWVC_MB*gM_Few)#cgO!2RF+hbNrnoZWEQ=KeT^v*hvO>m7<^IhPjX@A*ElJ_L%l=;` z=VgxyhqxO6-2k5{_yU8W0)2END)!8B$oERw5LAPMz;;m8+sDOeln+T~?4!;jDSEEP zZ((w^eixHl;2&i!cy1^n5uW6{XAGEh?+nZmpo9qD8RON4&s9T#4HT-zDv$vk#YyB%$f%1%d*J+Ir2uwMu!qS!zVdRa9S<}!0)ssMb4 zOJI|hP!wb4ia(^o$8+iMw{&t3$t~u`)r9zxYxg?? zi=&Cb05=#vcA0L;NbY36SKe#W@h;=MpNqrMoO#0@&Q+jU#>l)$ul!ZJi?-GR|`JDhI4d&0r%9p znLz&$2k?_{(!W$joJ+7SsEj%;(a(BcHRItv#(9L`gUvhZqRS7t>cg)~ZvS67L5hbN zUvQl9{}#6nY4Ia(KonUQfM4^#QV;wEFX-X8!SrIpk7tqz3&SIeR~Fy@)5zpoAI9cR z<$c}eJTogSZ@_)psBa4q`^aG)TV=-Y{Mbww^V!bKBP85q))RHP=Vwh2%m93TIOES z-Nxv>{tP6ZDvBX2f~!naoiK%}6-xWd4B#Kz!s@_wq1)5Uf}84bythfEf4XG##?MDs zkSerO^@)^$ zno)LX8(LXE;}JGL6Q*-Qx|3(`3Hr~>4Ta@eZ2O^`vqO=r59`Kci=E?)?>VT;_;HwVJRkw-P zym_@Sc;wIe?wliel_WfY9uNpJIrgDsuk|6XQppnQ9(A{j z@(R}kF<5LauC9vn&ZVv3qE^!T9#+gsd&nD4ez@npKok|jBF+pyqVPvt1Cmi@nmM0k z!zIr+VCvstar}?ur*5N)6LlK}DQ9D3Vm@n~y0Rs^34d(#Fxa&XXrm5kKa!M>NqDL(m8Jtwl zr^AfSLA?3}TqNYDvAVEs-Os4+i?#`LCo}T|SMPNekgrKv$q6>qEXqXJQL+DR5A!y4 zT2#cAfR}TOx-VLl%Ro=aJVVfDUELwI#ok(Fq7!*Thm+3kiY7%9p;mM&9EAEu)LP2R X7|6mv*J|o|)C9F7Rk3-Lf!Y5Cp-IEW delta 1798 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 OYP)q!F+rO6?|%V$2!Cb( diff --git a/thirdparty/rive_renderer/source/generated/shaders/macosx/rive_pls_macosx.metallib b/thirdparty/rive_renderer/source/generated/shaders/macosx/rive_pls_macosx.metallib index bffc71d50ce0624d7850244790434cb98ef1096f..4e1e9643496414fec5c09a4e87bb659cc3953c34 100644 GIT binary patch literal 143578 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 literal 141664 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 delta 7964 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 +#define Z0(A,F) ((A)*(F)) #define inversesqrt rsqrt -#define e5(e,a) struct a{ -#define W5(a) }; -#define U0(a) struct a{ -#define i0(e,W,a) W a -#define V0 }; -#define l0(H7,B,a,W) W a=B[H7].a -#define o1 struct k0{ -#define H(e,W,a) W a -#define L2 [[flat]] -#define n0 [[center_no_perspective]] -#ifndef OB -#define OB +#define l6(f,a) struct a{ +#define v7(a) }; +#define A1(a) struct a{ +#define r0(f,W,a) W a +#define B1 }; +#define v0(N8,G,a,W) W a=G[N8].a +#define h2 struct g0{ +#define d0(f,W,a) W a +#define S4 [[flat]] +#define J0 [[center_no_perspective]] +#ifndef NB +#define NB #endif -#define p1 f g1[[position]][[invariant]];}; -#define L(a,W) thread W&a=X.a -#define P(a) -#define N(a,W) W a=X.a -#define E3 struct M7{ -#define F3 }; -#define w3 struct H4{ -#define x3 }; -#define g4(e,f1,a) constant N0*a[[buffer(P0(e))]] -#define O3(e,f1,a) constant M*a[[buffer(P0(e))]] -#define h4(e,f1,a) constant f*a[[buffer(P0(e))]] -#define w0(a,v0) W1.a[v0] -#define k4(a,v0) W1.a[v0] -#define P2 struct N7{ -#define Q2 }; -#define R2 struct l3{ -#define S2 }; -#define p4 struct x6{ -#define q4 }; -#define I3(g0,e,a) [[texture(e)]]texture2da -#define r4(g0,e,a) [[texture(e)]]texture2da -#define C2(g0,e,a) [[texture(e)]]texture2da -#define y4(g0,e,a) [[texture(e)]]texture2da -#define l5(g0,e,a) [[texture(e)]]texture1d_arraya -#define P3(m2,a) constexpr sampler a(filter::linear,mip_filter::none); -#define G3(Ae,a) [[sampler(Ae)]]sampler a; -#define d1(A0,l) J0.A0.read(N0(l)) -#define D4(A0,p,l) J0.A0.sample(p,l) -#define T1(A0,p,l,G0) J0.A0.sample(p,l,level(G0)) -#define p5(A0,p,l,X2) J0.A0.gather(p,(l)*(X2)) -#define o4(A0,p,l) J0.A0.sample(I4.p,l) -#define C7(A0,p,l,G0) J0.A0.sample(I4.p,l,level(G0)) -#define T5(A0,p,m,w5,K7,G0) J0.A0.sample(p,m,w5) -#define q5 ,constant VB&q,N7 J0,M7 W1 -#define Y1 ,q,J0,W1 -#ifdef OD -#define q1(a,f0,B,n,K) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],uint K[[instance_id]],constant uint&Be[[buffer(P0(Ua))]],constant VB&q[[buffer(P0(K3))]],constant f0*B[[buffer(0)]],N7 J0,M7 W1){K+=Be;k0 X; +#define Z1 g L0[[position]][[invariant]];}; +#define Y(a,W) thread W&a=R.a +#define l0(a) +#define B(a,W) W a=R.a +#define B4 struct T8{ +#define C4 }; +#define K3 struct z5{ +#define L3 }; +#define H5(f,y1,a) constant W0*a[[buffer(Q0(f))]] +#define G4(f,y1,a) constant Q*a[[buffer(Q0(f))]] +#define I5(f,y1,a) constant g*a[[buffer(Q0(f))]] +#define P0(a,y0) x2.a[y0] +#define J5(a,y0) x2.a[y0] +#define P3 struct U8{ +#define Q3 }; +#define y3 struct E3{ +#define z3 }; +#define Z4 struct E7{ +#define a5 }; +#define E4(N,f,a) [[texture(f)]]texture2da +#define d5(N,f,a) [[texture(f)]]texture2da +#define U2(N,f,a) [[texture(f)]]texture2da +#define j5(N,f,a) [[texture(f)]]texture2da +#define e6(N,f,a) [[texture(f)]]texture1d_arraya +#define V3(x7,a) constexpr sampler a(filter::linear,mip_filter::none); +#define o6(N,f,a) [[sampler(f)]]sampler a; +#define S3(a) [[sampler(R3)]]sampler a; +#define F1(h0,l) M0.h0.read(W0(l)) +#define p5(h0,p,l) M0.h0.sample(p,l) +#define m2(h0,p,l,X0) M0.h0.sample(p,l,level(X0)) +#define q5(h0,p,l,P1) M0.h0.sample(p,l,bias(P1)) +#define g8(h0,p,l) M0.h0.sample(L4.p,l) +#define Q6(h0,p,l,X0) M0.h0.sample(L4.p,l,level(X0)) +#define y7(h0,p,l,P1) M0.h0.sample(L4.p,l,bias(P1)) +#define U6(h0,p,q,p6,P8,X0) M0.h0.sample(p,q,p6) +#define h6 ,constant MB&k,U8 M0,T8 x2 +#define p3 ,k,M0,x2 +#ifdef AE +#define C1(a,c0,G,v,S) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],uint S[[instance_id]],constant uint&vg[[buffer(Q0(uc))]],constant MB&k[[buffer(Q0(k3))]],constant c0*G[[buffer(0)]],U8 M0,T8 x2){S+=vg;g0 R; #else -#define q1(a,f0,B,n,K) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],uint K[[instance_id]],constant VB&q[[buffer(P0(K3))]],constant f0*B[[buffer(0)]],N7 J0,M7 W1){k0 X; +#define C1(a,c0,G,v,S) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],uint S[[instance_id]],constant MB&k[[buffer(Q0(k3))]],constant c0*G[[buffer(0)]],U8 M0,T8 x2){g0 R; #endif -#define G6(a,f0,B,n,K) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],constant VB&q[[buffer(P0(K3))]],constant EC&m0[[buffer(P0(f5))]],constant f0*B[[buffer(0)]],N7 J0,M7 W1){k0 X; -#define N4(a,a2,c2,v2,w2,n) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],constant VB&q[[buffer(P0(K3))]],constant EC&m0[[buffer(P0(f5))]],constant a2*c2[[buffer(0)]],constant v2*w2[[buffer(1)]]){k0 X; -#define h1(w6) X.g1=w6;}return X; -#define e2(E4,a) E4 __attribute__((visibility("default")))fragment a(k0 X[[stage_in]],l3 J0){ -#define f2(F) return F;} -#define C5 ,c y0,l3 J0,H4 W1,x6 I4 -#define Y2 ,y0,J0,W1,I4 -#define n5 ,l3 J0 -#define x1 ,J0 -#ifdef LE -#define x2 struct z1{ -#ifdef ME -#define M0(e,a) device uint*a[[buffer(P0(e+g5)),raster_order_group(0)]] -#define Y0(e,a) device uint*a[[buffer(P0(e+g5)),raster_order_group(0)]] -#define f4(e,a) device atomic_uint*a[[buffer(P0(e+g5)),raster_order_group(0)]] +#define S7(a,c0,G,v,S) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],constant MB&k[[buffer(Q0(k3))]],constant LC&A0[[buffer(Q0(a6))]],constant c0*G[[buffer(0)]],U8 M0,T8 x2){g0 R; +#define E6(a,e3,f3,q3,r3,v) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],constant MB&k[[buffer(Q0(k3))]],constant LC&A0[[buffer(Q0(a6))]],constant e3*f3[[buffer(0)]],constant q3*r3[[buffer(1)]]){g0 R; +#define D1(y5) R.L0=y5;}return R; +#define V2(Q1,a) Q1 __attribute__((visibility("default")))fragment a(g0 R[[stage_in]],E3 M0){ +#define q6(Q1,a) Q1 __attribute__((visibility("default")))fragment a(g0 R[[stage_in]],E3 M0,bool r6[[front_facing]]){ +#define F2(C) return C;} +#define G6 ,c T,E3 M0,z5 x2,E7 L4 +#define R2 ,T,M0,x2,L4 +#define C3 ,E3 M0 +#define i1 ,M0 +#define a7 +#define r5 +#ifdef FF +#define K1 struct n1{ +#ifdef GF +#define p0(f,a) device uint*a[[buffer(Q0(f+c6)),raster_order_group(0)]] +#define f1(f,a) device uint*a[[buffer(Q0(f+c6)),raster_order_group(0)]] +#define o4(f,a) device atomic_uint*a[[buffer(Q0(f+c6)),raster_order_group(0)]] #else -#define M0(e,a) device uint*a[[buffer(P0(e+g5))]] -#define Y0(e,a) device uint*a[[buffer(P0(e+g5))]] -#define f4(e,a) device atomic_uint*a[[buffer(P0(e+g5))]] +#define p0(f,a) device uint*a[[buffer(Q0(f+c6))]] +#define f1(f,a) device uint*a[[buffer(Q0(f+c6))]] +#define o4(f,a) device atomic_uint*a[[buffer(Q0(f+c6))]] #endif -#define y2 }; -#define y3 ,z1 E0,uint K2 -#define G1 ,E0,K2 -#define I0(h) unpackUnorm4x8(E0.h[K2]) -#define j1(h) E0.h[K2] -#define m4(h) atomic_load_explicit(&E0.h[K2],memory_order::memory_order_relaxed) -#define T0(h,F) E0.h[K2]=packUnorm4x8(F) -#define l1(h,F) E0.h[K2]=(F) -#define n4(h,F) atomic_store_explicit(&E0.h[K2],F,memory_order::memory_order_relaxed) -#define E2(h) -#define i2(h) -#define G5(h,m) atomic_fetch_max_explicit(&E0.h[K2],m,memory_order::memory_order_relaxed) -#define H5(h,m) atomic_fetch_add_explicit(&E0.h[K2],m,memory_order::memory_order_relaxed) -#define h2 -#define j2 -#define y6(a) __attribute__((visibility("default")))fragment a(z1 E0,constant VB&q[[buffer(P0(K3))]],k0 X[[stage_in]],l3 J0,x6 I4,H4 W1){c y0=X.g1.xy;N0 I=N0(metal::floor(y0));uint K2=I.y*q.Ga+I.x; -#define Rb(a) __attribute__((visibility("default")))fragment a(z1 E0,constant VB&q[[buffer(P0(K3))]],constant EC&m0[[buffer(P0(f5))]],k0 X[[stage_in]],x6 I4,l3 J0,H4 W1){c y0=X.g1.xy;N0 I=N0(metal::floor(y0));uint K2=I.y*q.Ga+I.x; -#define z2(a) void y6(a) -#define R4(a) void Rb(a) -#define M2 } -#define A3(a) i y6(a){i K1; -#define F5(a) i Rb(a){i K1; -#define P4 }return K1;M2 +#define L1 }; +#define r4 ,n1 R0,uint c1 +#define U1 ,R0,c1 +#define H0(h) unpackUnorm4x8(R0.h[c1]) +#define e1(h) R0.h[c1] +#define N3(h) atomic_load_explicit(&R0.h[c1],memory_order::memory_order_relaxed) +#define C0(h,C) R0.h[c1]=packUnorm4x8(C) +#define h1(h,C) R0.h[c1]=(C) +#define O3(h,C) atomic_store_explicit(&R0.h[c1],C,memory_order::memory_order_relaxed) +#define r2(h) +#define X1(h) +#define O5(h,q) atomic_fetch_max_explicit(&R0.h[c1],q,memory_order::memory_order_relaxed) +#define Q5(h,q) atomic_fetch_add_explicit(&R0.h[c1],q,memory_order::memory_order_relaxed) +#define v2 +#define w2 +#define F7(a) __attribute__((visibility("default")))fragment a(n1 R0,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,E7 L4,z5 x2){c T=R.L0.xy;W0 E=W0(metal::floor(T));uint c1=E.y*k.m6+E.x; +#define td(a) __attribute__((visibility("default")))fragment a(n1 R0,constant MB&k[[buffer(Q0(k3))]],constant LC&A0[[buffer(Q0(a6))]],g0 R[[stage_in]],E7 L4,E3 M0,z5 x2){c T=R.L0.xy;W0 E=W0(metal::floor(T));uint c1=E.y*k.m6+E.x; +#define v1(a) void F7(a) +#define M5(a) void td(a) +#define c2 } +#define o2(a) i F7(a){i m1; +#define v4(a) i td(a){i m1; +#define i3 }return m1;c2 #else -#define x2 struct z1{ -#define M0(e,a) [[color(e)]]i a -#define Y0(e,a) [[color(e)]]uint a -#define f4 Y0 -#define y2 }; -#define y3 ,thread z1&m3,thread z1&E0 -#define G1 ,m3,E0 -#define I0(h) m3.h -#define j1(h) m3.h -#define m4(h) j1 -#define T0(h,F) E0.h=(F) -#define l1(h,F) E0.h=(F) -#define n4(h) l1 -#define E2(h) E0.h=m3.h -#define i2(h) E0.h=m3.h -d uint r6(thread uint&h0,uint x){uint B1=h0;h0=metal::max(B1,x);return B1;} -#define G5(h,m) r6(E0.h,m) -d uint v6(thread uint&h0,uint x){uint B1=h0;h0=B1+x;return B1;} -#define H5(h,m) v6(E0.h,m) -#define h2 -#define j2 -#define y6(a,...) z1 __attribute__((visibility("default")))fragment a(__VA_ARGS__){c y0[[maybe_unused]]=X.g1.xy;z1 E0; -#define z2(a,...) y6(a,z1 m3,constant VB&q[[buffer(P0(K3))]],k0 X[[stage_in]],x6 I4,l3 J0,H4 W1) -#define R4(a) y6(a,z1 m3,k0 X[[stage_in]],l3 J0,H4 W1,x6 I4,constant EC&m0[[buffer(P0(f5))]]) -#define M2 }return E0; -#define Sb(a,...) struct Ce{i De[[j(0)]];z1 E0;};Ce __attribute__((visibility("default")))fragment a(__VA_ARGS__){c y0[[maybe_unused]]=X.g1.xy;i K1;z1 E0; -#define A3(a) Sb(a,z1 m3,k0 X[[stage_in]],l3 J0,H4 W1) -#define F5(a) Sb(a,z1 m3,k0 X[[stage_in]],l3 J0,H4 W1,__VA_ARGS__ constant EC&m0[[buffer(P0(f5))]]) -#define P4 }return{.De=K1,.E0=E0}; +#define K1 struct n1{ +#define p0(f,a) [[color(f)]]i a +#define f1(f,a) [[color(f)]]uint a +#define o4 f1 +#define L1 }; +#define r4 ,thread n1&e4,thread n1&R0 +#define U1 ,e4,R0 +#define H0(h) e4.h +#define e1(h) e4.h +#define N3(h) e1 +#define C0(h,C) R0.h=(C) +#define h1(h,C) R0.h=(C) +#define O3(h) h1 +#define r2(h) R0.h=e4.h +#define X1(h) R0.h=e4.h +e uint w5(thread uint&o0,uint x){uint a1=o0;o0=metal::max(a1,x);return a1;} +#define O5(h,q) w5(R0.h,q) +e uint x5(thread uint&o0,uint x){uint a1=o0;o0=a1+x;return a1;} +#define Q5(h,q) x5(R0.h,q) +#define v2 +#define w2 +#define F7(a,...) n1 __attribute__((visibility("default")))fragment a(__VA_ARGS__){c T[[maybe_unused]]=R.L0.xy;n1 R0; +#define v1(a,...) F7(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E7 L4,E3 M0,z5 x2) +#define M5(a) F7(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,z5 x2,E7 L4,constant LC&A0[[buffer(Q0(a6))]]) +#define c2 }return R0; +#define ud(a,...) struct wg{i xg[[j(0)]];n1 R0;};wg __attribute__((visibility("default")))fragment a(__VA_ARGS__){c T[[maybe_unused]]=R.L0.xy;i m1;n1 R0; +#define o2(a) ud(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,z5 x2) +#define v4(a) ud(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,z5 x2,__VA_ARGS__ constant LC&A0[[buffer(Q0(a6))]]) +#define i3 }return{.xg=m1,.R0=R0}; #endif -#define O4 M0 +#define m4 p0 #define discard discard_fragment() -using namespace metal;templated vecfloatBitsToUint(vecx){return as_type>(x);}templated vecfloatBitsToInt(vecx){return as_type>(x);}d uint floatBitsToUint(float x){return as_type(x);}d int floatBitsToInt(float x){return as_type(x);}templated vecuintBitsToFloat(vecx){return as_type>(x);}d float uintBitsToFloat(uint x){return as_type(x);}d G unpackHalf2x16(uint x){return as_type(x);}d uint packHalf2x16(G x){return as_type(x);}d i unpackUnorm4x8(uint x){return unpack_unorm4x8_to_half(x);}d uint packUnorm4x8(i x){return pack_half_to_unorm4x8(x);}d S inverse(S W0){S C9=S(W0[1][1],-W0[0][1],-W0[1][0],W0[0][0]);float Ee=(C9[0][0]*W0[0][0])+(C9[0][1]*W0[1][0]);return C9*(1/Ee);}d A mix(A k,A b,G7 B0){A z6;for(int C=0;C<3;++C)z6[C]=B0[C]?b[C]:k[C];return z6;}d c mix(c k,c b,a5 B0){c z6;for(int C=0;C<2;++C)z6[C]=B0[C]?b[C]:k[C];return z6;}d c mix(c k,c b,float t){return mix(k,b,c(t));}d float mod(float x,float y){return fmod(x,y);} +using namespace metal;templatee vecfloatBitsToUint(vecx){return as_type>(x);}templatee vecfloatBitsToInt(vecx){return as_type>(x);}e uint floatBitsToUint(float x){return as_type(x);}e int floatBitsToInt(float x){return as_type(x);}templatee vecuintBitsToFloat(vecx){return as_type>(x);}e float uintBitsToFloat(uint x){return as_type(x);}e D unpackHalf2x16(uint x){return as_type(x);}e uint packHalf2x16(D x){return as_type(x);}e i unpackUnorm4x8(uint x){return unpack_unorm4x8_to_half(x);}e uint packUnorm4x8(i x){return pack_half_to_unorm4x8(x);}e a0 inverse(a0 o1){a0 Ha=a0(o1[1][1],-o1[0][1],-o1[1][0],o1[0][0]);float yg=(Ha[0][0]*o1[0][0])+(Ha[0][1]*o1[1][0]);return Ha*(1/yg);}e r mix(r o,r b,n6 J1){r G7;for(int D0=0;D0<3;++D0)G7[D0]=J1[D0]?b[D0]:o[D0];return G7;}e c mix(c o,c b,F4 J1){c G7;for(int D0=0;D0<2;++D0)G7[D0]=J1[D0]?b[D0]:o[D0];return G7;}e c mix(c o,c b,float t){return mix(o,b,c(t));}e float mod(float x,float y){return fmod(x,y);} )==="; } // namespace glsl } // namespace gpu diff --git a/thirdparty/rive_renderer/source/generated/shaders/metal.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/metal.minified.glsl index 89a2e7272..5320c9117 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/metal.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/metal.minified.glsl @@ -1,159 +1,167 @@ #ifndef _ARE_TOKEN_NAMES_PRESERVED -#define g half -#define G half2 -#define A half3 +#define d half +#define D half2 +#define r half3 #define i half4 -#define a0 ushort +#define X ushort #define c float2 -#define Z float3 -#define a4 packed_float3 -#define f float4 -#define a5 bool2 -#define G7 bool3 -#define N0 uint2 -#define M uint4 -#define c0 int2 -#define h7 int4 -#define a0 ushort -#define S float2x2 -#define U5 half3x3 -#define V5 half2x3 +#define V float3 +#define I3 packed_float3 +#define g float4 +#define F4 bool2 +#define n6 bool3 +#define w7 bool4 +#define W0 uint2 +#define Q uint4 +#define U int2 +#define Z5 int4 +#define X ushort +#define a0 float2x2 +#define V6 half3x3 +#define W6 half2x3 +#define g5 half4x4 #endif -#define d inline -#define k1(P1) thread P1& -#define i4(P1) thread P1& -#define equal(o,r) ((o)==(r)) -#define notEqual(o,r) ((o)!=(r)) -#define lessThan(o,r) ((o)<(r)) -#define C0(o,r) ((o)*(r)) +#define e inline +#define g1(g2) thread g2& +#define U4(g2) thread g2& +#define equal(A,F) ((A)==(F)) +#define notEqual(A,F) ((A)!=(F)) +#define lessThan(A,F) ((A)<(F)) +#define greaterThan(A,F) ((A)>(F)) +#define Z0(A,F) ((A)*(F)) #define inversesqrt rsqrt -#define e5(e,a) struct a{ -#define W5(a) }; -#define U0(a) struct a{ -#define i0(e,W,a) W a -#define V0 }; -#define l0(H7,B,a,W) W a=B[H7].a -#define o1 struct k0{ -#define H(e,W,a) W a -#define L2 [[flat]] -#define n0 [[center_no_perspective]] +#define l6(f,a) struct a{ +#define v7(a) }; +#define A1(a) struct a{ +#define r0(f,W,a) W a +#define B1 }; +#define v0(N8,G,a,W) W a=G[N8].a +#define h2 struct g0{ +#define d0(f,W,a) W a +#define S4 [[flat]] +#define J0 [[center_no_perspective]] #ifndef OPTIONALLY_FLAT #define OPTIONALLY_FLAT #endif -#define p1 f g1[[position]][[invariant]];}; -#define L(a,W) thread W&a=X.a -#define P(a) -#define N(a,W) W a=X.a -#define E3 struct M7{ -#define F3 }; -#define w3 struct H4{ -#define x3 }; -#define g4(e,f1,a) constant N0*a[[buffer(P0(e))]] -#define O3(e,f1,a) constant M*a[[buffer(P0(e))]] -#define h4(e,f1,a) constant f*a[[buffer(P0(e))]] -#define w0(a,v0) W1.a[v0] -#define k4(a,v0) W1.a[v0] -#define P2 struct N7{ -#define Q2 }; -#define R2 struct l3{ -#define S2 }; -#define p4 struct x6{ -#define q4 }; -#define I3(g0,e,a) [[texture(e)]]texture2da -#define r4(g0,e,a) [[texture(e)]]texture2da -#define C2(g0,e,a) [[texture(e)]]texture2da -#define y4(g0,e,a) [[texture(e)]]texture2da -#define l5(g0,e,a) [[texture(e)]]texture1d_arraya -#define P3(m2,a) constexpr sampler a(filter::linear,mip_filter::none); -#define G3(Ae,a) [[sampler(Ae)]]sampler a; -#define d1(A0,l) J0.A0.read(N0(l)) -#define D4(A0,p,l) J0.A0.sample(p,l) -#define T1(A0,p,l,G0) J0.A0.sample(p,l,level(G0)) -#define p5(A0,p,l,X2) J0.A0.gather(p,(l)*(X2)) -#define o4(A0,p,l) J0.A0.sample(I4.p,l) -#define C7(A0,p,l,G0) J0.A0.sample(I4.p,l,level(G0)) -#define T5(A0,p,m,w5,K7,G0) J0.A0.sample(p,m,w5) -#define q5 ,constant VB&q,N7 J0,M7 W1 -#define Y1 ,q,J0,W1 +#define Z1 g L0[[position]][[invariant]];}; +#define Y(a,W) thread W&a=R.a +#define l0(a) +#define B(a,W) W a=R.a +#define B4 struct T8{ +#define C4 }; +#define K3 struct z5{ +#define L3 }; +#define H5(f,y1,a) constant W0*a[[buffer(Q0(f))]] +#define G4(f,y1,a) constant Q*a[[buffer(Q0(f))]] +#define I5(f,y1,a) constant g*a[[buffer(Q0(f))]] +#define P0(a,y0) x2.a[y0] +#define J5(a,y0) x2.a[y0] +#define P3 struct U8{ +#define Q3 }; +#define y3 struct E3{ +#define z3 }; +#define Z4 struct E7{ +#define a5 }; +#define E4(N,f,a) [[texture(f)]]texture2da +#define d5(N,f,a) [[texture(f)]]texture2da +#define U2(N,f,a) [[texture(f)]]texture2da +#define j5(N,f,a) [[texture(f)]]texture2da +#define e6(N,f,a) [[texture(f)]]texture1d_arraya +#define V3(x7,a) constexpr sampler a(filter::linear,mip_filter::none); +#define o6(N,f,a) [[sampler(f)]]sampler a; +#define S3(a) [[sampler(R3)]]sampler a; +#define F1(h0,l) M0.h0.read(W0(l)) +#define p5(h0,p,l) M0.h0.sample(p,l) +#define m2(h0,p,l,X0) M0.h0.sample(p,l,level(X0)) +#define q5(h0,p,l,P1) M0.h0.sample(p,l,bias(P1)) +#define g8(h0,p,l) M0.h0.sample(L4.p,l) +#define Q6(h0,p,l,X0) M0.h0.sample(L4.p,l,level(X0)) +#define y7(h0,p,l,P1) M0.h0.sample(L4.p,l,bias(P1)) +#define U6(h0,p,q,p6,P8,X0) M0.h0.sample(p,q,p6) +#define h6 ,constant MB&k,U8 M0,T8 x2 +#define p3 ,k,M0,x2 #ifdef ENABLE_INSTANCE_INDEX -#define q1(a,f0,B,n,K) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],uint K[[instance_id]],constant uint&Be[[buffer(P0(Ua))]],constant VB&q[[buffer(P0(K3))]],constant f0*B[[buffer(0)]],N7 J0,M7 W1){K+=Be;k0 X; +#define C1(a,c0,G,v,S) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],uint S[[instance_id]],constant uint&vg[[buffer(Q0(uc))]],constant MB&k[[buffer(Q0(k3))]],constant c0*G[[buffer(0)]],U8 M0,T8 x2){S+=vg;g0 R; #else -#define q1(a,f0,B,n,K) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],uint K[[instance_id]],constant VB&q[[buffer(P0(K3))]],constant f0*B[[buffer(0)]],N7 J0,M7 W1){k0 X; +#define C1(a,c0,G,v,S) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],uint S[[instance_id]],constant MB&k[[buffer(Q0(k3))]],constant c0*G[[buffer(0)]],U8 M0,T8 x2){g0 R; #endif -#define G6(a,f0,B,n,K) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],constant VB&q[[buffer(P0(K3))]],constant EC&m0[[buffer(P0(f5))]],constant f0*B[[buffer(0)]],N7 J0,M7 W1){k0 X; -#define N4(a,a2,c2,v2,w2,n) __attribute__((visibility("default")))k0 vertex a(uint n[[vertex_id]],constant VB&q[[buffer(P0(K3))]],constant EC&m0[[buffer(P0(f5))]],constant a2*c2[[buffer(0)]],constant v2*w2[[buffer(1)]]){k0 X; -#define h1(w6) X.g1=w6;}return X; -#define e2(E4,a) E4 __attribute__((visibility("default")))fragment a(k0 X[[stage_in]],l3 J0){ -#define f2(F) return F;} -#define C5 ,c y0,l3 J0,H4 W1,x6 I4 -#define Y2 ,y0,J0,W1,I4 -#define n5 ,l3 J0 -#define x1 ,J0 +#define S7(a,c0,G,v,S) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],constant MB&k[[buffer(Q0(k3))]],constant LC&A0[[buffer(Q0(a6))]],constant c0*G[[buffer(0)]],U8 M0,T8 x2){g0 R; +#define E6(a,e3,f3,q3,r3,v) __attribute__((visibility("default")))g0 vertex a(uint v[[vertex_id]],constant MB&k[[buffer(Q0(k3))]],constant LC&A0[[buffer(Q0(a6))]],constant e3*f3[[buffer(0)]],constant q3*r3[[buffer(1)]]){g0 R; +#define D1(y5) R.L0=y5;}return R; +#define V2(Q1,a) Q1 __attribute__((visibility("default")))fragment a(g0 R[[stage_in]],E3 M0){ +#define q6(Q1,a) Q1 __attribute__((visibility("default")))fragment a(g0 R[[stage_in]],E3 M0,bool r6[[front_facing]]){ +#define F2(C) return C;} +#define G6 ,c T,E3 M0,z5 x2,E7 L4 +#define R2 ,T,M0,x2,L4 +#define C3 ,E3 M0 +#define i1 ,M0 +#define a7 +#define r5 #ifdef PLS_IMPL_DEVICE_BUFFER -#define x2 struct z1{ +#define K1 struct n1{ #ifdef PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED -#define M0(e,a) device uint*a[[buffer(P0(e+g5)),raster_order_group(0)]] -#define Y0(e,a) device uint*a[[buffer(P0(e+g5)),raster_order_group(0)]] -#define f4(e,a) device atomic_uint*a[[buffer(P0(e+g5)),raster_order_group(0)]] +#define p0(f,a) device uint*a[[buffer(Q0(f+c6)),raster_order_group(0)]] +#define f1(f,a) device uint*a[[buffer(Q0(f+c6)),raster_order_group(0)]] +#define o4(f,a) device atomic_uint*a[[buffer(Q0(f+c6)),raster_order_group(0)]] #else -#define M0(e,a) device uint*a[[buffer(P0(e+g5))]] -#define Y0(e,a) device uint*a[[buffer(P0(e+g5))]] -#define f4(e,a) device atomic_uint*a[[buffer(P0(e+g5))]] +#define p0(f,a) device uint*a[[buffer(Q0(f+c6))]] +#define f1(f,a) device uint*a[[buffer(Q0(f+c6))]] +#define o4(f,a) device atomic_uint*a[[buffer(Q0(f+c6))]] #endif -#define y2 }; -#define y3 ,z1 E0,uint K2 -#define G1 ,E0,K2 -#define I0(h) unpackUnorm4x8(E0.h[K2]) -#define j1(h) E0.h[K2] -#define m4(h) atomic_load_explicit(&E0.h[K2],memory_order::memory_order_relaxed) -#define T0(h,F) E0.h[K2]=packUnorm4x8(F) -#define l1(h,F) E0.h[K2]=(F) -#define n4(h,F) atomic_store_explicit(&E0.h[K2],F,memory_order::memory_order_relaxed) -#define E2(h) -#define i2(h) -#define G5(h,m) atomic_fetch_max_explicit(&E0.h[K2],m,memory_order::memory_order_relaxed) -#define H5(h,m) atomic_fetch_add_explicit(&E0.h[K2],m,memory_order::memory_order_relaxed) -#define h2 -#define j2 -#define y6(a) __attribute__((visibility("default")))fragment a(z1 E0,constant VB&q[[buffer(P0(K3))]],k0 X[[stage_in]],l3 J0,x6 I4,H4 W1){c y0=X.g1.xy;N0 I=N0(metal::floor(y0));uint K2=I.y*q.Ga+I.x; -#define Rb(a) __attribute__((visibility("default")))fragment a(z1 E0,constant VB&q[[buffer(P0(K3))]],constant EC&m0[[buffer(P0(f5))]],k0 X[[stage_in]],x6 I4,l3 J0,H4 W1){c y0=X.g1.xy;N0 I=N0(metal::floor(y0));uint K2=I.y*q.Ga+I.x; -#define z2(a) void y6(a) -#define R4(a) void Rb(a) -#define M2 } -#define A3(a) i y6(a){i K1; -#define F5(a) i Rb(a){i K1; -#define P4 }return K1;M2 +#define L1 }; +#define r4 ,n1 R0,uint c1 +#define U1 ,R0,c1 +#define H0(h) unpackUnorm4x8(R0.h[c1]) +#define e1(h) R0.h[c1] +#define N3(h) atomic_load_explicit(&R0.h[c1],memory_order::memory_order_relaxed) +#define C0(h,C) R0.h[c1]=packUnorm4x8(C) +#define h1(h,C) R0.h[c1]=(C) +#define O3(h,C) atomic_store_explicit(&R0.h[c1],C,memory_order::memory_order_relaxed) +#define r2(h) +#define X1(h) +#define O5(h,q) atomic_fetch_max_explicit(&R0.h[c1],q,memory_order::memory_order_relaxed) +#define Q5(h,q) atomic_fetch_add_explicit(&R0.h[c1],q,memory_order::memory_order_relaxed) +#define v2 +#define w2 +#define F7(a) __attribute__((visibility("default")))fragment a(n1 R0,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,E7 L4,z5 x2){c T=R.L0.xy;W0 E=W0(metal::floor(T));uint c1=E.y*k.m6+E.x; +#define td(a) __attribute__((visibility("default")))fragment a(n1 R0,constant MB&k[[buffer(Q0(k3))]],constant LC&A0[[buffer(Q0(a6))]],g0 R[[stage_in]],E7 L4,E3 M0,z5 x2){c T=R.L0.xy;W0 E=W0(metal::floor(T));uint c1=E.y*k.m6+E.x; +#define v1(a) void F7(a) +#define M5(a) void td(a) +#define c2 } +#define o2(a) i F7(a){i m1; +#define v4(a) i td(a){i m1; +#define i3 }return m1;c2 #else -#define x2 struct z1{ -#define M0(e,a) [[color(e)]]i a -#define Y0(e,a) [[color(e)]]uint a -#define f4 Y0 -#define y2 }; -#define y3 ,thread z1&m3,thread z1&E0 -#define G1 ,m3,E0 -#define I0(h) m3.h -#define j1(h) m3.h -#define m4(h) j1 -#define T0(h,F) E0.h=(F) -#define l1(h,F) E0.h=(F) -#define n4(h) l1 -#define E2(h) E0.h=m3.h -#define i2(h) E0.h=m3.h -d uint r6(thread uint&h0,uint x){uint B1=h0;h0=metal::max(B1,x);return B1;} -#define G5(h,m) r6(E0.h,m) -d uint v6(thread uint&h0,uint x){uint B1=h0;h0=B1+x;return B1;} -#define H5(h,m) v6(E0.h,m) -#define h2 -#define j2 -#define y6(a,...) z1 __attribute__((visibility("default")))fragment a(__VA_ARGS__){c y0[[maybe_unused]]=X.g1.xy;z1 E0; -#define z2(a,...) y6(a,z1 m3,constant VB&q[[buffer(P0(K3))]],k0 X[[stage_in]],x6 I4,l3 J0,H4 W1) -#define R4(a) y6(a,z1 m3,k0 X[[stage_in]],l3 J0,H4 W1,x6 I4,constant EC&m0[[buffer(P0(f5))]]) -#define M2 }return E0; -#define Sb(a,...) struct Ce{i De[[j(0)]];z1 E0;};Ce __attribute__((visibility("default")))fragment a(__VA_ARGS__){c y0[[maybe_unused]]=X.g1.xy;i K1;z1 E0; -#define A3(a) Sb(a,z1 m3,k0 X[[stage_in]],l3 J0,H4 W1) -#define F5(a) Sb(a,z1 m3,k0 X[[stage_in]],l3 J0,H4 W1,__VA_ARGS__ constant EC&m0[[buffer(P0(f5))]]) -#define P4 }return{.De=K1,.E0=E0}; +#define K1 struct n1{ +#define p0(f,a) [[color(f)]]i a +#define f1(f,a) [[color(f)]]uint a +#define o4 f1 +#define L1 }; +#define r4 ,thread n1&e4,thread n1&R0 +#define U1 ,e4,R0 +#define H0(h) e4.h +#define e1(h) e4.h +#define N3(h) e1 +#define C0(h,C) R0.h=(C) +#define h1(h,C) R0.h=(C) +#define O3(h) h1 +#define r2(h) R0.h=e4.h +#define X1(h) R0.h=e4.h +e uint w5(thread uint&o0,uint x){uint a1=o0;o0=metal::max(a1,x);return a1;} +#define O5(h,q) w5(R0.h,q) +e uint x5(thread uint&o0,uint x){uint a1=o0;o0=a1+x;return a1;} +#define Q5(h,q) x5(R0.h,q) +#define v2 +#define w2 +#define F7(a,...) n1 __attribute__((visibility("default")))fragment a(__VA_ARGS__){c T[[maybe_unused]]=R.L0.xy;n1 R0; +#define v1(a,...) F7(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E7 L4,E3 M0,z5 x2) +#define M5(a) F7(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,z5 x2,E7 L4,constant LC&A0[[buffer(Q0(a6))]]) +#define c2 }return R0; +#define ud(a,...) struct wg{i xg[[j(0)]];n1 R0;};wg __attribute__((visibility("default")))fragment a(__VA_ARGS__){c T[[maybe_unused]]=R.L0.xy;i m1;n1 R0; +#define o2(a) ud(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,z5 x2) +#define v4(a) ud(a,n1 e4,constant MB&k[[buffer(Q0(k3))]],g0 R[[stage_in]],E3 M0,z5 x2,__VA_ARGS__ constant LC&A0[[buffer(Q0(a6))]]) +#define i3 }return{.xg=m1,.R0=R0}; #endif -#define O4 M0 +#define m4 p0 #define discard discard_fragment() -using namespace metal;templated vecfloatBitsToUint(vecx){return as_type>(x);}templated vecfloatBitsToInt(vecx){return as_type>(x);}d uint floatBitsToUint(float x){return as_type(x);}d int floatBitsToInt(float x){return as_type(x);}templated vecuintBitsToFloat(vecx){return as_type>(x);}d float uintBitsToFloat(uint x){return as_type(x);}d G unpackHalf2x16(uint x){return as_type(x);}d uint packHalf2x16(G x){return as_type(x);}d i unpackUnorm4x8(uint x){return unpack_unorm4x8_to_half(x);}d uint packUnorm4x8(i x){return pack_half_to_unorm4x8(x);}d S inverse(S W0){S C9=S(W0[1][1],-W0[0][1],-W0[1][0],W0[0][0]);float Ee=(C9[0][0]*W0[0][0])+(C9[0][1]*W0[1][0]);return C9*(1/Ee);}d A mix(A k,A b,G7 B0){A z6;for(int C=0;C<3;++C)z6[C]=B0[C]?b[C]:k[C];return z6;}d c mix(c k,c b,a5 B0){c z6;for(int C=0;C<2;++C)z6[C]=B0[C]?b[C]:k[C];return z6;}d c mix(c k,c b,float t){return mix(k,b,c(t));}d float mod(float x,float y){return fmod(x,y);} \ No newline at end of file +using namespace metal;templatee vecfloatBitsToUint(vecx){return as_type>(x);}templatee vecfloatBitsToInt(vecx){return as_type>(x);}e uint floatBitsToUint(float x){return as_type(x);}e int floatBitsToInt(float x){return as_type(x);}templatee vecuintBitsToFloat(vecx){return as_type>(x);}e float uintBitsToFloat(uint x){return as_type(x);}e D unpackHalf2x16(uint x){return as_type(x);}e uint packHalf2x16(D x){return as_type(x);}e i unpackUnorm4x8(uint x){return unpack_unorm4x8_to_half(x);}e uint packUnorm4x8(i x){return pack_half_to_unorm4x8(x);}e a0 inverse(a0 o1){a0 Ha=a0(o1[1][1],-o1[0][1],-o1[1][0],o1[0][0]);float yg=(Ha[0][0]*o1[0][0])+(Ha[0][1]*o1[1][0]);return Ha*(1/yg);}e r mix(r o,r b,n6 J1){r G7;for(int D0=0;D0<3;++D0)G7[D0]=J1[D0]?b[D0]:o[D0];return G7;}e c mix(c o,c b,F4 J1){c G7;for(int D0=0;D0<2;++D0)G7[D0]=J1[D0]?b[D0]:o[D0];return G7;}e c mix(c o,c b,float t){return mix(o,b,c(t));}e float mod(float x,float y){return fmod(x,y);} \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.exports.h b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.hpp index 061387c3e..079945c95 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.glsl.hpp @@ -1,69 +1,73 @@ #pragma once -#include "pls_load_store_ext.exports.h" +#include "pls_load_store_ext.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char pls_load_store_ext[] = R"===(#ifdef AB -void main(){gl_Position=vec4(mix(vec2(-1,1),vec2(1,-1),equal(gl_VertexID&ivec2(1,2),ivec2(0))),0,1);} +const char pls_load_store_ext[] = R"===(#ifdef BB +void main(){gl_Position=vec4(mix(vec2(-1,1),vec2(1,-1),equal(gl_VertexID&ivec2(1,2),ivec2(0))),0,1); +#ifdef JC +gl_Position.y=-gl_Position.y; #endif -#ifdef HB +} +#endif +#ifdef EB #extension GL_EXT_shader_pixel_local_storage:require #ifdef GL_ARM_shader_framebuffer_fetch #extension GL_ARM_shader_framebuffer_fetch:require #else #extension GL_EXT_shader_framebuffer_fetch:require #endif -#ifdef RD +#ifdef DE #if __VERSION__>=310 -layout(binding=0,std140)uniform Rf{uniform highp vec4 Fe;}Ge; +layout(binding=0,std140)uniform ki{uniform highp vec4 zg;}Ag; #else -uniform mediump vec4 SD; +uniform mediump vec4 EE; #endif #endif #ifdef GL_EXT_shader_pixel_local_storage -#ifdef FD -__pixel_local_inEXT z1 +#ifdef PD +__pixel_local_inEXT n1 #else -__pixel_local_outEXT z1 +__pixel_local_outEXT n1 #endif -{layout(rgba8)mediump vec4 H0;layout(r32ui)highp uint r1;layout(rgba8)mediump vec4 N3;layout(r32ui)highp uint x4;}; +{layout(rgba8)mediump vec4 j0;layout(r32ui)highp uint e0;layout(rgba8)mediump vec4 f4;layout(r32ui)highp uint H7;}; #ifndef GL_ARM_shader_framebuffer_fetch -#ifdef TD -layout(location=0)inout mediump vec4 D9; +#ifdef FE +layout(location=0)inout mediump vec4 Ia; #endif #endif -#ifdef FD -layout(location=0)out mediump vec4 D9; +#ifdef PD +layout(location=0)out mediump vec4 Ia; #endif void main(){ -#ifdef RD +#ifdef DE #if __VERSION__>=310 -H0=Ge.Fe; +j0=Ag.zg; #else -H0=SD; +j0=EE; #endif #endif -#ifdef TD +#ifdef FE #ifdef GL_ARM_shader_framebuffer_fetch -H0=gl_LastFragColorARM; +j0=gl_LastFragColorARM; #else -H0=D9; +j0=Ia; #endif #endif -#ifdef NE -x4=0u; +#ifdef QD +H7=0u; #endif -#ifdef OE -r1=0u; +#ifdef HF +e0=0u; #endif -#ifdef FD -D9=H0; +#ifdef PD +Ia=j0; #endif } #else -layout(location=0)out mediump vec4 He;void main(){He=vec4(0,1,0,1);} +layout(location=0)out mediump vec4 Bg;void main(){Bg=vec4(0,1,0,1);} #endif #endif )==="; diff --git a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.minified.glsl index e21df2b4a..41c651dfc 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/pls_load_store_ext.minified.glsl @@ -1,5 +1,9 @@ #ifdef VERTEX -void main(){gl_Position=vec4(mix(vec2(-1,1),vec2(1,-1),equal(gl_VertexID&ivec2(1,2),ivec2(0))),0,1);} +void main(){gl_Position=vec4(mix(vec2(-1,1),vec2(1,-1),equal(gl_VertexID&ivec2(1,2),ivec2(0))),0,1); +#ifdef POST_INVERT_Y +gl_Position.y=-gl_Position.y; +#endif +} #endif #ifdef FRAGMENT #extension GL_EXT_shader_pixel_local_storage:require @@ -10,52 +14,52 @@ void main(){gl_Position=vec4(mix(vec2(-1,1),vec2(1,-1),equal(gl_VertexID&ivec2(1 #endif #ifdef CLEAR_COLOR #if __VERSION__>=310 -layout(binding=0,std140)uniform Rf{uniform highp vec4 Fe;}Ge; +layout(binding=0,std140)uniform ki{uniform highp vec4 zg;}Ag; #else -uniform mediump vec4 SD; +uniform mediump vec4 EE; #endif #endif #ifdef GL_EXT_shader_pixel_local_storage #ifdef STORE_COLOR -__pixel_local_inEXT z1 +__pixel_local_inEXT n1 #else -__pixel_local_outEXT z1 +__pixel_local_outEXT n1 #endif -{layout(rgba8)mediump vec4 H0;layout(r32ui)highp uint r1;layout(rgba8)mediump vec4 N3;layout(r32ui)highp uint x4;}; +{layout(rgba8)mediump vec4 j0;layout(r32ui)highp uint e0;layout(rgba8)mediump vec4 f4;layout(r32ui)highp uint H7;}; #ifndef GL_ARM_shader_framebuffer_fetch #ifdef LOAD_COLOR -layout(location=0)inout mediump vec4 D9; +layout(location=0)inout mediump vec4 Ia; #endif #endif #ifdef STORE_COLOR -layout(location=0)out mediump vec4 D9; +layout(location=0)out mediump vec4 Ia; #endif void main(){ #ifdef CLEAR_COLOR #if __VERSION__>=310 -H0=Ge.Fe; +j0=Ag.zg; #else -H0=SD; +j0=EE; #endif #endif #ifdef LOAD_COLOR #ifdef GL_ARM_shader_framebuffer_fetch -H0=gl_LastFragColorARM; +j0=gl_LastFragColorARM; #else -H0=D9; +j0=Ia; #endif #endif #ifdef CLEAR_COVERAGE -x4=0u; +H7=0u; #endif #ifdef CLEAR_CLIP -r1=0u; +e0=0u; #endif #ifdef STORE_COLOR -D9=H0; +Ia=j0; #endif } #else -layout(location=0)out mediump vec4 He;void main(){He=vec4(0,1,0,1);} +layout(location=0)out mediump vec4 Bg;void main(){Bg=vec4(0,1,0,1);} #endif #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.exports.h b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.hpp index ad1c697ff..0740732b4 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.glsl.hpp @@ -1,23 +1,71 @@ #pragma once -#include "render_atlas.exports.h" +#include "render_atlas.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char render_atlas[] = R"===(#ifdef AB -U0(f0)i0(0,f,LB);i0(1,f,MB);V0 +const char render_atlas[] = R"===(#ifdef BB +A1(c0)r0(0,g,TB);r0(1,g,UB);B1 #endif -o1 n0 H(0,f,D);p1 -#ifdef AB -q1(PE,f0,B,n,K){l0(n,B,LB,f);l0(n,B,MB,f);L(D,f);f Q;uint R;c J;if(E6(LB,MB,K,R,J,D Y1)){M T3=w0(JB,R*4u+2u);Z n6=uintBitsToFloat(T3.yzw);J=J*n6.x+n6.yz;Q=d7(J,q.Ha.x,q.Ha.y);}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(D);h1(Q);} +h2 J0 d0(0,g,I);Z1 +#ifdef BB +C1(IF,c0,G,v,S){v0(v,G,TB,g);v0(v,G,UB,g);Y(I,g);g O;uint m0;c i0;if(p9(TB,UB,S,m0,i0,I p3)){Q K4=P0(LB,m0*4u+2u);V p7=uintBitsToFloat(K4.yzw);i0=i0*p7.x+p7.yz;O=o8(i0,k.Zc.x,k.Zc.y); +#ifdef JC +O.y=-O.y; #endif -#ifdef HB -#ifdef QE -e2(float,RE){N(D,f);f2(S4(D x1));} +}else{O=g(k.O2,k.O2,k.O2,k.O2);}l0(I);D1(O);} +#endif +#ifdef EB +#ifdef EC +e d v6(g J,bool Cg C3){d n=d8(J i1);if(!Cg)n=-n;return n;} +#endif +#ifdef KD +layout(location=0)inout Q n0; +#ifdef EC +void main(){float n=uintBitsToFloat(n0.x);n+=v6(I,gl_FrontFacing i1);n0.x=floatBitsToUint(n);} +#endif +#ifdef MC +void main(){float n=uintBitsToFloat(n0.x);n=max(n,w4(I));n0.x=floatBitsToUint(n);} +#endif +#elif defined(LD) +__pixel_localEXT n1{layout(r32f)float n0;}; +#ifdef EC +void main(){n0+=v6(I,gl_FrontFacing i1);} +#endif +#ifdef MC +void main(){n0=max(n0,w4(I));} +#endif +#elif defined(EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +layout(binding=0,r32ui)uniform highp upixelLocalANGLE n0; +#ifdef EC +void main(){float n=uintBitsToFloat(pixelLocalLoadANGLE(n0).x);n+=v6(I,gl_FrontFacing i1);pixelLocalStoreANGLE(n0,Q(floatBitsToUint(n)));} +#endif +#ifdef MC +void main(){float n=uintBitsToFloat(pixelLocalLoadANGLE(n0).x);n=max(n,w4(I));pixelLocalStoreANGLE(n0,Q(floatBitsToUint(n)));} +#endif +#elif defined(MD) +layout(binding=0,r32i)uniform highp coherent iimage2D V8;ivec2 vd(){return ivec2(floor(T));}int wd(float n){return int(n*zc);} +#ifdef EC +void main(){int n=wd(v6(I,gl_FrontFacing i1));imageAtomicAdd(V8,vd(),n);} +#endif +#ifdef MC +void main(){int n=wd(w4(I));imageAtomicMax(V8,vd(),n);} +#endif +#elif defined(GE) +#ifdef EC +q6(i,HE){B(I,g);d n=v6(I,r6 i1);if(abs(n)>lf-1e-3){F2(n>.0?B0(.0,.0,1./255.,.0):B0(.0,.0,.0,1./255.));}else{n*=1./ka;F2(B0(max(n,.0),max(-n,.0),.0,.0));}} +#endif +#ifdef MC +V2(i,IE){B(I,g);d n=w4(I i1);n*=1./ka;F2(B0(n,.0,.0,.0));} +#endif +#else +#ifdef EC +q6(float,HE){B(I,g);F2(v6(I,r6 i1));} +#endif +#ifdef MC +V2(float,IE){B(I,g);F2(w4(I i1));} #endif -#ifdef SE -e2(float,TE){N(D,f);f2(R6(D x1));} #endif #endif )==="; diff --git a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.minified.glsl index 6ddd6914d..e54a9f5f9 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/render_atlas.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/render_atlas.minified.glsl @@ -1,15 +1,63 @@ #ifdef VERTEX -U0(f0)i0(0,f,LB);i0(1,f,MB);V0 +A1(c0)r0(0,g,TB);r0(1,g,UB);B1 #endif -o1 n0 H(0,f,D);p1 +h2 J0 d0(0,g,I);Z1 #ifdef VERTEX -q1(PE,f0,B,n,K){l0(n,B,LB,f);l0(n,B,MB,f);L(D,f);f Q;uint R;c J;if(E6(LB,MB,K,R,J,D Y1)){M T3=w0(JB,R*4u+2u);Z n6=uintBitsToFloat(T3.yzw);J=J*n6.x+n6.yz;Q=d7(J,q.Ha.x,q.Ha.y);}else{Q=f(q.C1,q.C1,q.C1,q.C1);}P(D);h1(Q);} +C1(IF,c0,G,v,S){v0(v,G,TB,g);v0(v,G,UB,g);Y(I,g);g O;uint m0;c i0;if(p9(TB,UB,S,m0,i0,I p3)){Q K4=P0(LB,m0*4u+2u);V p7=uintBitsToFloat(K4.yzw);i0=i0*p7.x+p7.yz;O=o8(i0,k.Zc.x,k.Zc.y); +#ifdef POST_INVERT_Y +O.y=-O.y; +#endif +}else{O=g(k.O2,k.O2,k.O2,k.O2);}l0(I);D1(O);} #endif #ifdef FRAGMENT #ifdef ATLAS_FEATHERED_FILL -e2(float,RE){N(D,f);f2(S4(D x1));} +e d v6(g J,bool Cg C3){d n=d8(J i1);if(!Cg)n=-n;return n;} +#endif +#ifdef ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH +layout(location=0)inout Q n0; +#ifdef ATLAS_FEATHERED_FILL +void main(){float n=uintBitsToFloat(n0.x);n+=v6(I,gl_FrontFacing i1);n0.x=floatBitsToUint(n);} +#endif +#ifdef ATLAS_FEATHERED_STROKE +void main(){float n=uintBitsToFloat(n0.x);n=max(n,w4(I));n0.x=floatBitsToUint(n);} +#endif +#elif defined(ATLAS_RENDER_TARGET_R8_PLS_EXT) +__pixel_localEXT n1{layout(r32f)float n0;}; +#ifdef ATLAS_FEATHERED_FILL +void main(){n0+=v6(I,gl_FrontFacing i1);} +#endif +#ifdef ATLAS_FEATHERED_STROKE +void main(){n0=max(n0,w4(I));} +#endif +#elif defined(ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +layout(binding=0,r32ui)uniform highp upixelLocalANGLE n0; +#ifdef ATLAS_FEATHERED_FILL +void main(){float n=uintBitsToFloat(pixelLocalLoadANGLE(n0).x);n+=v6(I,gl_FrontFacing i1);pixelLocalStoreANGLE(n0,Q(floatBitsToUint(n)));} +#endif +#ifdef ATLAS_FEATHERED_STROKE +void main(){float n=uintBitsToFloat(pixelLocalLoadANGLE(n0).x);n=max(n,w4(I));pixelLocalStoreANGLE(n0,Q(floatBitsToUint(n)));} +#endif +#elif defined(ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE) +layout(binding=0,r32i)uniform highp coherent iimage2D V8;ivec2 vd(){return ivec2(floor(T));}int wd(float n){return int(n*zc);} +#ifdef ATLAS_FEATHERED_FILL +void main(){int n=wd(v6(I,gl_FrontFacing i1));imageAtomicAdd(V8,vd(),n);} +#endif +#ifdef ATLAS_FEATHERED_STROKE +void main(){int n=wd(w4(I));imageAtomicMax(V8,vd(),n);} +#endif +#elif defined(ATLAS_RENDER_TARGET_RGBA8_UNORM) +#ifdef ATLAS_FEATHERED_FILL +q6(i,HE){B(I,g);d n=v6(I,r6 i1);if(abs(n)>lf-1e-3){F2(n>.0?B0(.0,.0,1./255.,.0):B0(.0,.0,.0,1./255.));}else{n*=1./ka;F2(B0(max(n,.0),max(-n,.0),.0,.0));}} +#endif +#ifdef ATLAS_FEATHERED_STROKE +V2(i,IE){B(I,g);d n=w4(I i1);n*=1./ka;F2(B0(n,.0,.0,.0));} +#endif +#else +#ifdef ATLAS_FEATHERED_FILL +q6(float,HE){B(I,g);F2(v6(I,r6 i1));} #endif #ifdef ATLAS_FEATHERED_STROKE -e2(float,TE){N(D,f);f2(R6(D x1));} +V2(float,IE){B(I,g);F2(w4(I i1));} +#endif #endif #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.hpp new file mode 100644 index 000000000..5f38da58e --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.glsl.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "resolve_atlas.glsl.exports.h" + +namespace rive { +namespace gpu { +namespace glsl { +const char resolve_atlas[] = R"===(#ifdef BB +C1(JF,c0,G,v,S){g O;O.x=(v!=2)?-1.:3.;O.y=(v!=1)?-1.:3.;O.zw=c(.0,1.);D1(O);} +#endif +#ifdef EB +e ivec2 xd(){return ivec2(floor(gl_FragCoord));} +#ifdef KD +layout(location=0)inout Q n0;layout(location=1)out i g4;void main(){g4.x=uintBitsToFloat(n0.x);} +#elif defined(LD) +#ifdef QD +__pixel_local_outEXT n1{layout(r32f)float n0;}; +#else +__pixel_local_inEXT n1{layout(r32f)float n0;};layout(location=0)out i g4; +#endif +void main(){ +#ifdef QD +n0=.0; +#else +g4.x=n0; +#endif +} +#elif defined(EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +layout(binding=0,r32ui)uniform highp upixelLocalANGLE n0;layout(location=0)out i g4;void main(){g4.x=uintBitsToFloat(pixelLocalLoadANGLE(n0).x);} +#elif defined(MD) +layout(binding=0,r32i)uniform highp coherent iimage2D V8;layout(location=0)out i g4;void main(){g4.x=float(imageLoad(V8,xd()).x)*(1./zc);} +#elif defined(GE) +U2(X2,0,JE);layout(location=0)out i g4;void main(){i J=F1(JE,xd());g4.x=(J.x-J.y)*ka+(J.z-J.w)*255.;} +#endif +#endif +)==="; +} // namespace glsl +} // namespace gpu +} // namespace rive \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.minified.glsl new file mode 100644 index 000000000..7c969a207 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/resolve_atlas.minified.glsl @@ -0,0 +1,28 @@ +#ifdef VERTEX +C1(JF,c0,G,v,S){g O;O.x=(v!=2)?-1.:3.;O.y=(v!=1)?-1.:3.;O.zw=c(.0,1.);D1(O);} +#endif +#ifdef FRAGMENT +e ivec2 xd(){return ivec2(floor(gl_FragCoord));} +#ifdef ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH +layout(location=0)inout Q n0;layout(location=1)out i g4;void main(){g4.x=uintBitsToFloat(n0.x);} +#elif defined(ATLAS_RENDER_TARGET_R8_PLS_EXT) +#ifdef CLEAR_COVERAGE +__pixel_local_outEXT n1{layout(r32f)float n0;}; +#else +__pixel_local_inEXT n1{layout(r32f)float n0;};layout(location=0)out i g4; +#endif +void main(){ +#ifdef CLEAR_COVERAGE +n0=.0; +#else +g4.x=n0; +#endif +} +#elif defined(ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +layout(binding=0,r32ui)uniform highp upixelLocalANGLE n0;layout(location=0)out i g4;void main(){g4.x=uintBitsToFloat(pixelLocalLoadANGLE(n0).x);} +#elif defined(ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE) +layout(binding=0,r32i)uniform highp coherent iimage2D V8;layout(location=0)out i g4;void main(){g4.x=float(imageLoad(V8,xd()).x)*(1./zc);} +#elif defined(ATLAS_RENDER_TARGET_RGBA8_UNORM) +U2(X2,0,JE);layout(location=0)out i g4;void main(){i J=F1(JE,xd());g4.x=(J.x-J.y)*ka+(J.z-J.w)*255.;} +#endif +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/rhi.exports.h b/thirdparty/rive_renderer/source/generated/shaders/rhi.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/rhi.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.hpp index 04dc0b227..dc39f0106 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/rhi.glsl.hpp @@ -1,6 +1,6 @@ #pragma once -#include "rhi.exports.h" +#include "rhi.glsl.exports.h" namespace rive { namespace gpu { @@ -8,159 +8,220 @@ namespace glsl { const char rhi[] = R"===(#pragma warning(disable:3550) #pragma warning(disable:4000) #ifndef _ARE_TOKEN_NAMES_PRESERVED -#define g half -#define G half2 -#define A half3 +#define d half +#define D half2 +#define r half3 #define i half4 -#define a0 ushort +#define X ushort #define c float2 -#define Z float3 -#define f float4 -#define a5 bool2 -#define G7 bool3 -#define N0 uint2 -#define M uint4 -#define c0 int2 -#define h7 int4 -#define a0 ushort -#define S float2x2 -#define U5 half3x3 -#define V5 half2x3 -#endif -typedef Z a4; -#ifdef PD -#if Ie -typedef min16uint a0; +#define V float3 +#define g float4 +#define F4 bool2 +#define n6 bool3 +#define w7 bool4 +#define W0 uint2 +#define Q uint4 +#define U int2 +#define Z5 int4 +#define X ushort +#define a0 float2x2 +#define V6 half3x3 +#define W6 half2x3 +#define g5 half4x4 #endif +typedef V I3; +#ifdef BE +#if Dg +typedef min16uint X; +#endif +#else +#if Dg +typedef uint X; +#endif +#endif +#define yd(A,F) A##F +#define e inline +#define g1(g2) out g2 +#define U4(g2) inout g2 +#define A1(a) struct a{ +#define r0(f,W,a) W a:yd(li,f) +#define B1 }; +#define v0(N8,G,a,W) W a=G.a +#define l6(f,a) cbuffer a{struct{ +#define v7(a) }a;} +#define h2 struct g0{ +#define J0 noperspective +#define NB nointerpolation +#define S4 nointerpolation +#define d0(f,W,a) W a:yd(TEXCOORD,f) +#ifdef KE +#define Z1 g L0:SV_Position;g Eg:SV_ClipDistance;}; +#else +#define Z1 g L0:SV_Position;}; +#endif +#define Y(a,W) W a +#define l0(a) R.a=a +#define B(a,W) W a=R.a +#ifdef BB +#define P3 +#define Q3 +#endif +#ifdef EB +#define y3 +#define z3 +#endif +#define Z4 +#define a5 +#define E4(N,f,a) uniform Texture2Da +#define d5(N,f,a) uniform Texture2Da +#ifdef ED +#define Ne(N,f,a) uniform Texture2DMSa +#endif +#define U2(N,f,a) uniform Texture2Da +#define j5(N,f,a) uniform Texture2Da +#define e6(N,f,a) uniform Texture2DArraya +#define v5(f,a) SamplerState a; +#define V3 v5 +#define o6(N,f,a) v5(f,a) +#define S3(a) v5(R3,a) +#ifdef oi +#define m8(a,Fg,l) a.pi(l,Fg) +#endif +#define F1(a,l) a[l] +#define p5(a,p,l) a.Sample(p,l) +#define m2(a,p,l,X0) a.SampleLevel(p,l,X0) +#define q5(a,p,l,P1) a.SampleBias(p,l,P1) +#define U6(a,p,q,p6,P8,X0) a.SampleLevel(p,V(q,0.5,p6),X0) +#define g8(h0,p,l) p5(h0,p,l) +#define Q6(h0,p,l,X0) m2(h0,p,l,X0) +#define y7(h0,p,l,P1) q5(h0,p,l,P1) +#define v2 +#define w2 +#ifdef CE +#define J2 RasterizerOrderedTexture2D +#else +#define J2 RWTexture2D +#endif +#if defined(EB)&&defined(AB) +#ifdef KF +#define g7(a) [[ri::input_attachment_index(P2)]]SubpassInputMSa +#define S8(a) jc(g5(a.Ja(0),a.Ja(1),a.Ja(2),a.Ja(3)),Ka) +#else +#define g7(a) Texture2D a +#define S8(a) a[E] +#endif +#endif +#define K1 +#define L1 +#ifdef KC +#define p0(f,a) uniform J2a #else -#if Ie -typedef uint a0; -#endif -#endif -#define Tb(o,r) o##r -#define d inline -#define k1(P1) out P1 -#define i4(P1) inout P1 -#define U0(a) struct a{ -#define i0(e,W,a) W a:Tb(Sf,e) -#define V0 }; -#define l0(H7,B,a,W) W a=B.a -#define e5(e,a) cbuffer a{struct{ -#define W5(a) }a;} -#define o1 struct k0{ -#define n0 noperspective -#define OB nointerpolation -#define L2 nointerpolation -#define H(e,W,a) W a:Tb(TEXCOORD,e) -#define p1 f g1:SV_Position;}; -#define L(a,W) W a -#define P(a) X.a=a -#define N(a,W) W a=X.a -#ifdef AB -#define P2 -#define Q2 -#endif -#ifdef HB -#define R2 -#define S2 -#endif -#define p4 -#define q4 -#define I3(g0,e,a) uniform Texture2Da -#define r4(g0,e,a) uniform Texture2Da -#define C2(g0,e,a) uniform Texture2Da -#define y4(g0,e,a) uniform Texture2Da -#define l5(g0,e,a) uniform Texture2DArraya -#define F4(m2,a) SamplerState a; -#define P3 F4 -#define G3 F4 -#define d1(a,l) a[l] -#define D4(a,p,l) a.Sample(p,l) -#define T1(a,p,l,G0) a.SampleLevel(p,l,G0) -#define p5(a,p,l,X2) a.Gather(p,(l)*(X2)) -#define T5(a,p,m,w5,K7,G0) a.SampleLevel(p,Z(m,0.5,w5),G0) -#define o4(A0,p,l) D4(A0,p,l) -#define C7(A0,p,l,G0) T1(A0,p,l,G0) -#define h2 -#define j2 -#ifdef QD -#define n2 RasterizerOrderedTexture2D +#define p0(f,a) uniform J2a +#endif +#define m4 p0 +#define f1(f,a) uniform J2a +#define N3 e1 +#define O3 h1 +#if COMPILER_METAL||FORCE_ATOMIC_BUFFER +#define o4(f,a) uniform RWBuffera +#define N3(h) h[c1] +#define O3(h,C) h[c1]=C #else -#define n2 RWTexture2D +#define o4 f1 +#define N3 e1 +#define O3 h1 #endif -#define x2 -#ifdef FC -#define M0(e,a) uniform n2a +#ifdef KC +#define H0(h) h[E] #else -#define M0(e,a) uniform n2a -#endif -#define O4 M0 -#define Y0(e,a) uniform n2a -#define f4 Y0 -#define m4 j1 -#define n4 l1 -#define y2 -#ifdef FC -#define I0(h) h[I] +#define H0(h) unpackUnorm4x8(h[E]) +#endif +#define e1(h) h[E] +#ifdef KC +#define C0(h,C) h[E]=(C) #else -#define I0(h) unpackUnorm4x8(h[I]) +#define C0(h,C) h[E]=packUnorm4x8(C) #endif -#define j1(h) h[I] -#ifdef FC -#define T0(h,F) h[I]=(F) +#define h1(h,C) h[E]=(C) +#if COMPILER_METAL||FORCE_ATOMIC_BUFFER +e uint w5(RWBufferm3,uint c1,uint x){uint a1;InterlockedMax(m3[c1],x,a1);return a1;} +#define O5(h,q) w5(h,c1,q) +e uint x5(RWBufferm3,uint c1,uint x){uint a1;InterlockedAdd(m3[c1],x,a1);return a1;} +#define Q5(h,q) x5(h,c1,q) #else -#define T0(h,F) h[I]=packUnorm4x8(F) -#endif -#define l1(h,F) h[I]=(F) -d uint r6(n2G4,c0 I,uint x){uint B1;InterlockedMax(G4[I],x,B1);return B1;} -#define G5(h,m) r6(h,I,m) -d uint v6(n2G4,c0 I,uint x){uint B1;InterlockedAdd(G4[I],x,B1);return B1;} -#define H5(h,m) v6(h,I,m) -#define E2(h) -#define i2(h) -#define q5 -#define Y1 -#define n5 -#define x1 -#define q1(a,f0,B,n,K) uint baseInstance;k0 a(f0 B,uint n:SV_VertexID,uint A9:SV_InstanceID){uint K=A9+baseInstance;k0 X; -#define G6(a,f0,B,n,K) k0 a(f0 B,uint n:SV_VertexID){k0 X;f g1; -#define N4(a,a2,c2,v2,w2,n) k0 a(a2 c2,v2 w2,uint n:SV_VertexID){k0 X;f g1; -#define h1(w6) X.g1=w6;}return X; -#define e2(E4,a) E4 a(k0 X):SV_Target{ -#define f2(F) return F;} -#define C5 ,c y0 -#define Y2 ,y0 -#define y3 ,c0 I -#define G1 ,I -#define z2(a) Ke void a(k0 X){c y0=X.g1.xy;c0 I=c0(floor(y0)); -#define R4(a) z2(a) -#define M2 } -#define A3(a) Ke i a(k0 X):SV_Target{c y0=X.g1.xy;c0 I=c0(floor(y0));i K1; -#define F5(a) A3(a) -#define P4 }return K1; +e uint w5(J2m3,U E,uint x){uint a1;InterlockedMax(m3[E],x,a1);return a1;} +#define O5(h,q) w5(h,E,q) +e uint x5(J2m3,U E,uint x){uint a1;InterlockedAdd(m3[E],x,a1);return a1;} +#define Q5(h,q) x5(h,E,q) +#endif +#define r2(h) +#define X1(h) +#define h6 +#define p3 +#define C3 +#define i1 +#ifdef LE +#define C1(a,c0,G,v,S) uint baseInstance;g a(c0 G,uint v:SV_VertexID,uint D7:SV_InstanceID):SV_Position{uint S=D7+baseInstance; +#define D1(y5) return y5;} +#else +#define C1(a,c0,G,v,S) uint baseInstance;g0 a(c0 G,uint v:SV_VertexID,uint D7:SV_InstanceID){uint S=D7+baseInstance;g0 R; +#define S7(a,c0,G,v,S) g0 a(c0 G,uint v:SV_VertexID){g0 R;g L0; +#define E6(a,e3,f3,q3,r3,v) g0 a(e3 f3,q3 r3,uint v:SV_VertexID){g0 R;g L0; +#define D1(y5) R.L0=y5;}return R; +#endif +#ifdef LE +#define V2(Q1,a) EARLYDEPTHSTENCIL Q1 a(g L0:SV_Position):SV_Target{c T=L0.xy; +#define q6(Q1,a) ti Q1 a(g L0:SV_Position,uint Ka:SV_Coverage,bool La:SV_IsFrontFace):SV_Target{c T=L0.xy;bool r6=!La; +#else +#define V2(Q1,a) EARLYDEPTHSTENCIL Q1 a(g0 R,uint Ka:SV_Coverage):SV_Target{c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x; +#define q6(Q1,a) Q1 a(g0 R,uint Ka:SV_Coverage,bool La:SV_IsFrontFace):SV_Target{c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x;bool r6=!La; +#endif +#define F2(C) return C;} +#ifdef KE +#define a7 ,out g gl_ClipDistance +#define r5 ,R.Eg +#else +#define a7 +#define r5 +#endif +#define G6 ,c T +#define R2 ,T +#define r4 ,U E +#define U1 ,E +#define v1(a) EARLYDEPTHSTENCIL void a(g0 R){c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x; +#define M5(a) v1(a) +#if defined(K)&&defined(KB) +#define c2 i3 +#else +#define c2 } +#endif +#define o2(a) EARLYDEPTHSTENCIL i a(g0 R):SV_Target{c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x;i m1; +#define v4(a) o2(a) +#define i3 }return m1; #define uintBitsToFloat asfloat #define floatBitsToInt asint #define floatBitsToUint asuint #define inversesqrt rsqrt -#define equal(o,r) ((o)==(r)) -#define notEqual(o,r) ((o)!=(r)) -#define lessThan(o,r) ((o)<(r)) -#define C0(o,r) mul(r,o) -#define E3 -#define F3 -#define w3 -#define x3 -#define g4(e,f1,a) StructuredBuffera -#define O3(e,f1,a) StructuredBuffera -#define h4(e,f1,a) StructuredBuffera -#define w0(a,v0) a[v0] -#define k4(a,v0) a[v0] -d G unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return G(f16tof32(x),f16tof32(y));}d uint packHalf2x16(c M1){uint x=f32tof16(M1.x);uint y=f32tof16(M1.y);return(y<<16)|x;}d i unpackUnorm4x8(uint u){M A1=M(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(A1)*(1./255.);}d uint packUnorm4x8(i j){M A1=(M(j*255.)&0xff)<(F)) +#define Z0(A,F) mul(F,A) +#define B4 +#define C4 +#define K3 +#define L3 +#define H5(f,y1,a) StructuredBuffera +#define G4(f,y1,a) StructuredBuffera +#define I5(f,y1,a) StructuredBuffera +#define P0(a,y0) a[y0] +#define J5(a,y0) a[y0] +e D unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return D(f16tof32(x),f16tof32(y));}e uint packHalf2x16(c e2){uint x=f32tof16(e2.x);uint y=f32tof16(e2.y);return(y<<16)|x;}e i unpackUnorm4x8(uint u){Q R1=Q(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(R1)*(1./255.);}e uint packUnorm4x8(i j){Q R1=(Q(j*255.)&0xff)<a -#define r4(g0,e,a) uniform Texture2Da -#define C2(g0,e,a) uniform Texture2Da -#define y4(g0,e,a) uniform Texture2Da -#define l5(g0,e,a) uniform Texture2DArraya -#define F4(m2,a) SamplerState a; -#define P3 F4 -#define G3 F4 -#define d1(a,l) a[l] -#define D4(a,p,l) a.Sample(p,l) -#define T1(a,p,l,G0) a.SampleLevel(p,l,G0) -#define p5(a,p,l,X2) a.Gather(p,(l)*(X2)) -#define T5(a,p,m,w5,K7,G0) a.SampleLevel(p,Z(m,0.5,w5),G0) -#define o4(A0,p,l) D4(A0,p,l) -#define C7(A0,p,l,G0) T1(A0,p,l,G0) -#define h2 -#define j2 +#define y3 +#define z3 +#endif +#define Z4 +#define a5 +#define E4(N,f,a) uniform Texture2Da +#define d5(N,f,a) uniform Texture2Da +#ifdef SOURCE_TEXTURE_MSAA +#define Ne(N,f,a) uniform Texture2DMSa +#endif +#define U2(N,f,a) uniform Texture2Da +#define j5(N,f,a) uniform Texture2Da +#define e6(N,f,a) uniform Texture2DArraya +#define v5(f,a) SamplerState a; +#define V3 v5 +#define o6(N,f,a) v5(f,a) +#define S3(a) v5(R3,a) +#ifdef oi +#define m8(a,Fg,l) a.pi(l,Fg) +#endif +#define F1(a,l) a[l] +#define p5(a,p,l) a.Sample(p,l) +#define m2(a,p,l,X0) a.SampleLevel(p,l,X0) +#define q5(a,p,l,P1) a.SampleBias(p,l,P1) +#define U6(a,p,q,p6,P8,X0) a.SampleLevel(p,V(q,0.5,p6),X0) +#define g8(h0,p,l) p5(h0,p,l) +#define Q6(h0,p,l,X0) m2(h0,p,l,X0) +#define y7(h0,p,l,P1) q5(h0,p,l,P1) +#define v2 +#define w2 #ifdef ENABLE_RASTERIZER_ORDERED_VIEWS -#define n2 RasterizerOrderedTexture2D +#define J2 RasterizerOrderedTexture2D +#else +#define J2 RWTexture2D +#endif +#if defined(FRAGMENT)&&defined(RENDER_MODE_MSAA) +#ifdef SUPPORTS_SUBPASS_LOAD +#define g7(a) [[ri::input_attachment_index(P2)]]SubpassInputMSa +#define S8(a) jc(g5(a.Ja(0),a.Ja(1),a.Ja(2),a.Ja(3)),Ka) #else -#define n2 RWTexture2D +#define g7(a) Texture2D a +#define S8(a) a[E] #endif -#define x2 +#endif +#define K1 +#define L1 #ifdef ENABLE_TYPED_UAV_LOAD_STORE -#define M0(e,a) uniform n2a +#define p0(f,a) uniform J2a +#else +#define p0(f,a) uniform J2a +#endif +#define m4 p0 +#define f1(f,a) uniform J2a +#define N3 e1 +#define O3 h1 +#if COMPILER_METAL||FORCE_ATOMIC_BUFFER +#define o4(f,a) uniform RWBuffera +#define N3(h) h[c1] +#define O3(h,C) h[c1]=C #else -#define M0(e,a) uniform n2a -#endif -#define O4 M0 -#define Y0(e,a) uniform n2a -#define f4 Y0 -#define m4 j1 -#define n4 l1 -#define y2 +#define o4 f1 +#define N3 e1 +#define O3 h1 +#endif #ifdef ENABLE_TYPED_UAV_LOAD_STORE -#define I0(h) h[I] +#define H0(h) h[E] #else -#define I0(h) unpackUnorm4x8(h[I]) +#define H0(h) unpackUnorm4x8(h[E]) #endif -#define j1(h) h[I] +#define e1(h) h[E] #ifdef ENABLE_TYPED_UAV_LOAD_STORE -#define T0(h,F) h[I]=(F) +#define C0(h,C) h[E]=(C) +#else +#define C0(h,C) h[E]=packUnorm4x8(C) +#endif +#define h1(h,C) h[E]=(C) +#if COMPILER_METAL||FORCE_ATOMIC_BUFFER +e uint w5(RWBufferm3,uint c1,uint x){uint a1;InterlockedMax(m3[c1],x,a1);return a1;} +#define O5(h,q) w5(h,c1,q) +e uint x5(RWBufferm3,uint c1,uint x){uint a1;InterlockedAdd(m3[c1],x,a1);return a1;} +#define Q5(h,q) x5(h,c1,q) +#else +e uint w5(J2m3,U E,uint x){uint a1;InterlockedMax(m3[E],x,a1);return a1;} +#define O5(h,q) w5(h,E,q) +e uint x5(J2m3,U E,uint x){uint a1;InterlockedAdd(m3[E],x,a1);return a1;} +#define Q5(h,q) x5(h,E,q) +#endif +#define r2(h) +#define X1(h) +#define h6 +#define p3 +#define C3 +#define i1 +#ifdef NO_VARYING +#define C1(a,c0,G,v,S) uint baseInstance;g a(c0 G,uint v:SV_VertexID,uint D7:SV_InstanceID):SV_Position{uint S=D7+baseInstance; +#define D1(y5) return y5;} +#else +#define C1(a,c0,G,v,S) uint baseInstance;g0 a(c0 G,uint v:SV_VertexID,uint D7:SV_InstanceID){uint S=D7+baseInstance;g0 R; +#define S7(a,c0,G,v,S) g0 a(c0 G,uint v:SV_VertexID){g0 R;g L0; +#define E6(a,e3,f3,q3,r3,v) g0 a(e3 f3,q3 r3,uint v:SV_VertexID){g0 R;g L0; +#define D1(y5) R.L0=y5;}return R; +#endif +#ifdef NO_VARYING +#define V2(Q1,a) EARLYDEPTHSTENCIL Q1 a(g L0:SV_Position):SV_Target{c T=L0.xy; +#define q6(Q1,a) ti Q1 a(g L0:SV_Position,uint Ka:SV_Coverage,bool La:SV_IsFrontFace):SV_Target{c T=L0.xy;bool r6=!La; +#else +#define V2(Q1,a) EARLYDEPTHSTENCIL Q1 a(g0 R,uint Ka:SV_Coverage):SV_Target{c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x; +#define q6(Q1,a) Q1 a(g0 R,uint Ka:SV_Coverage,bool La:SV_IsFrontFace):SV_Target{c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x;bool r6=!La; +#endif +#define F2(C) return C;} +#ifdef NEEDS_CLIP_DISTANCE +#define a7 ,out g gl_ClipDistance +#define r5 ,R.Eg #else -#define T0(h,F) h[I]=packUnorm4x8(F) -#endif -#define l1(h,F) h[I]=(F) -d uint r6(n2G4,c0 I,uint x){uint B1;InterlockedMax(G4[I],x,B1);return B1;} -#define G5(h,m) r6(h,I,m) -d uint v6(n2G4,c0 I,uint x){uint B1;InterlockedAdd(G4[I],x,B1);return B1;} -#define H5(h,m) v6(h,I,m) -#define E2(h) -#define i2(h) -#define q5 -#define Y1 -#define n5 -#define x1 -#define q1(a,f0,B,n,K) uint baseInstance;k0 a(f0 B,uint n:SV_VertexID,uint A9:SV_InstanceID){uint K=A9+baseInstance;k0 X; -#define G6(a,f0,B,n,K) k0 a(f0 B,uint n:SV_VertexID){k0 X;f g1; -#define N4(a,a2,c2,v2,w2,n) k0 a(a2 c2,v2 w2,uint n:SV_VertexID){k0 X;f g1; -#define h1(w6) X.g1=w6;}return X; -#define e2(E4,a) E4 a(k0 X):SV_Target{ -#define f2(F) return F;} -#define C5 ,c y0 -#define Y2 ,y0 -#define y3 ,c0 I -#define G1 ,I -#define z2(a) Ke void a(k0 X){c y0=X.g1.xy;c0 I=c0(floor(y0)); -#define R4(a) z2(a) -#define M2 } -#define A3(a) Ke i a(k0 X):SV_Target{c y0=X.g1.xy;c0 I=c0(floor(y0));i K1; -#define F5(a) A3(a) -#define P4 }return K1; +#define a7 +#define r5 +#endif +#define G6 ,c T +#define R2 ,T +#define r4 ,U E +#define U1 ,E +#define v1(a) EARLYDEPTHSTENCIL void a(g0 R){c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x; +#define M5(a) v1(a) +#if defined(FIXED_FUNCTION_COLOR_OUTPUT)&&defined(DRAW_IMAGE_MESH) +#define c2 i3 +#else +#define c2 } +#endif +#define o2(a) EARLYDEPTHSTENCIL i a(g0 R):SV_Target{c T=R.L0.xy;U E=U(floor(T));uint c1=E.y*k.m6+E.x;i m1; +#define v4(a) o2(a) +#define i3 }return m1; #define uintBitsToFloat asfloat #define floatBitsToInt asint #define floatBitsToUint asuint #define inversesqrt rsqrt -#define equal(o,r) ((o)==(r)) -#define notEqual(o,r) ((o)!=(r)) -#define lessThan(o,r) ((o)<(r)) -#define C0(o,r) mul(r,o) -#define E3 -#define F3 -#define w3 -#define x3 -#define g4(e,f1,a) StructuredBuffera -#define O3(e,f1,a) StructuredBuffera -#define h4(e,f1,a) StructuredBuffera -#define w0(a,v0) a[v0] -#define k4(a,v0) a[v0] -d G unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return G(f16tof32(x),f16tof32(y));}d uint packHalf2x16(c M1){uint x=f32tof16(M1.x);uint y=f32tof16(M1.y);return(y<<16)|x;}d i unpackUnorm4x8(uint u){M A1=M(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(A1)*(1./255.);}d uint packUnorm4x8(i j){M A1=(M(j*255.)&0xff)<(F)) +#define Z0(A,F) mul(F,A) +#define B4 +#define C4 +#define K3 +#define L3 +#define H5(f,y1,a) StructuredBuffera +#define G4(f,y1,a) StructuredBuffera +#define I5(f,y1,a) StructuredBuffera +#define P0(a,y0) a[y0] +#define J5(a,y0) a[y0] +e D unpackHalf2x16(uint u){uint y=(u>>16);uint x=u&0xffffu;return D(f16tof32(x),f16tof32(y));}e uint packHalf2x16(c e2){uint x=f32tof16(e2.x);uint y=f32tof16(e2.y);return(y<<16)|x;}e i unpackUnorm4x8(uint u){Q R1=Q(u&0xffu,(u>>8)&0xffu,(u>>16)&0xffu,u>>24);return i(R1)*(1./255.);}e uint packUnorm4x8(i j){Q R1=(Q(j*255.)&0xff)<1!XkTxUS577`B8mZopX&IO|m=o>I(N zOwFmBPKpSGIF+S21(juKqGmRD%sI||uYbMUmw#P*@jcJ;4&Si8?_0x9L%Y5mi(;Fi zYtgCL)KHX1_o5w2QCRLr*|q3U^05<+o^ZgT#WN2W^rZuJ+^(nv=(~NQ|c=O`E%5PD|^YmPL!27q^_ccu8wZ^9f7l%~(8p z{=7w`jhtgAPaZpAO!JHd3&?reoR;P}v*)!m&z#*#zS$?Y=-0`dmEY`nGv+LrnH}2W zk^9x2cK?X{lV%l#cr(~M9qMR1JRw9$&@mOrOV=xUuL99(hnpIi}`2 z06wnrI~06Mm0Ro)xrf0gk2H6Oa;#^~X+E4G8#RA^>rDO3wHlw%qicAbxu(~!*Tow3 z`7L-%<^KwJ!53@#tK#T~KL4rSSo~FeTI;mAWlUr7x2{RmF+;)|Z!?u~yV>ixm zv@CevQZ>GzaK39dm$-@3wG+G#*hB7mu*HZK=)>ZT?cV;dze?;3#{bWxpsH0Y~m)c{nb})o^~bYn!!Dcb1et{d%~{c z(8b$9%q7nCy2iurUkSU`L;s`=HtY8VdKSnqNaPDdFQ2Zccc5!ZQ+XNqBa`CnY>L;du!!NO)nw ztqCtq_~e97P5AVL&rJBNgwIZRX~O3ud|tvABz#fAmn6JA;mZ^LUcy%ob*cS^W(!d(*XnsCpAdnY_G;YkS}o$xUUe=Xsu34cA|;}ZTx!pA4vlJKmA zznSof37?ek+=S;Pd}_j{CwxZ2XD9sM2`@|d+=S0h_$B)lf!bqTLe_|b$nB>Y&y&m{b8!oN!RxrCoj z_=SXDO!%dQH&%E@?k+B!Cf16Qco&e*TfNJ(v3$Pt8B=Xn?l0XctZ#4lwv^h{cZPqi z)cL0@8;cz&wW}My7p1v;b~Ju(O6}^q!TV8~%l!KDSY7(tKK*&EDgD*0?}$>bJwNGx zBwQ`pHy&($^#Ryzhwncg!54tHN&F13@nJt3Z2fZEej#U3EIlmvMJ4~tz5+gK;l)G4 zehvJxF>4PAz7l@UJ4cV)iCXRkA4qmfpXtMA1DIn-@W*R>eejpy%a$%3VxKpGjgK*V z6>L9a3|<2}2I_lK*XtGT1>OvnJGO678l!ed#eEluv2a}9;`Gq}ZAxwCwO!WvE~kSP zeezu)Y+JMu5Pj(2pch5kICie_;bHGu@}+Adm+u*oYj?2k1U+~nZvuN=Jo91OJZx(p zd_45EZ*t#7JU-9!mGh$?-2Qn+oxYDmodfk};+k(T*fDj!I;Os-IENk6L&0+WhEm#& zQmeS{9cqzxIGnVl|LDqQF5{=b`73kVZn^I%Y7xH>;ya6Du?p-sXwOG*b3R-Vea$If zU1>dO*&48ZYb#BzpL|`V?M^?}gUzAuMoKPwTRY{x+o;*DKZ2bf6k8pRLldVt{!|(D zwLZD;JRZ*T*TLp+tfKFKLF*1T{#`JCrH}D)-*eQ$|3e8%^xO9qkLaK8BOd14hQ>+V zkF?8uCsEVh73>^vU6|i--wusqOw`u|-@;2xFYG?U$2>KDAY6BK^UHmHSJOVM!p3NK zOnnA-Oux*W)z7i;Q2PMIcUygJm-iaW;NEXC_ns5nebxJ8aQF3l6Ib`18FowWo579u z-WlBWadYB(WA~mOcDeWU;MV7JLFPUi1UKIWiRn9t~!2q9rqn5+GFW^ zQ05ocao?Z9ZhL)4%iQ<0%zZD+yftxk-zURv>3e5z$M1wXKC6!VE}Q+2uj9T0hu!Ct z-!kUG&HqXr_j^ya`#m>vzX4_L_uS0=#uMD~<2v3UwMToW#NF%sP8;!#Z;!;)dnT^k zZzbVxxn~{sn@QO1Z{IrJFLC|+mJ~LI_k@?hYMvez-Pqx^{T?Fsd#rx*$l)`_AHdp%v15C^PMk@FMOlYfn`qTjG8&LzXeuXU-`ccR`b4T8=OOG;XjQ& zt7&t-%ELAttftMmD-YW{#HeX=p31}K_eeEu&QW>T{KliE&GjM=+dt6NBBwlTexvl> zuFZKZ58G^F)U>%qSL*O;0)d=~P% zr_U5}pPRV#m)|^(CEn*HZ`%5(>*HK$K=Zj`D)Y*D)(FuazC)t`+Uh`<>uk z8@ai5hMVKe%DxL&Ew1aXU}My$a2;H4yMfj7Im37~>(g%A-1qV|@Vlbg2>R^)u>|bB zW-eHNxjr#QetXRRr@;01y;Og>KH+~VIQyRl*WdS6{pI?E|LNfDe+FEC-)r@k>!ZK( z&+nYtwRumJhi!MTnl|@;x!AoukHJ#7T8zOm@L8NO26BC(jpu-~|G9AeV+`c_g#UTq z?0-I7{}=IQw4+*FVNUu21yyqRMXHd~T43tru8LoA)@mHs@V$@GH!nC%E?V zK5(@rPW}5*s)hfzz-kMKcP)GytQPC#Qn11_HiF@?C<@+@`&3HtiN&lQp&YC&jx@U zKW+O{$|L8G!R8u4kKV@j9`Ku#zME^)?^W=IuJ-v_o%ZC6stosT|i+z-~@ z`51LR09TJ|_rGAZck#J{IKQ#{1g>t}`{eyO*yAJGqwPUXHQ&X=(Uyn6wjuVsRbZwG zQAMFG+Nf^cb(9|F^&85=a5eLaqs@p9hIhdBE8DA@kRyxjm+^BYg}`7yYC?!u`(d>;pE>x?nx_!Dq- zzX3)3lW^l5GwtVA>)|P|_cHA zKv&at6*%8d{pPNw&G$}u#QhRoE$*k!!0ng!Q`=%*eT=nT+PxOPr}Xez_$};NxSH2O zY<}0{b71F0Jo7ydR@V? z`Mm1--UwIoyIRz>32t4s<7!H|_!>(6^>YvV4LGjJwP3k6^ZL7m{_z~{Zx?Fudj{3D z)i)pAdYnVXE`Vzv&Z#YOECg%w^w7uov=e^?jMrJeKlUAC~s>HA)Zr>9^fKz}1Wq zo8L9`M{wR({{&a_8*r?XSK;chuSOor*jN7ywjS%(-#TnZH~QjXJM?*-Q_XgWqaB;U z{W#C#I@+!`z-q(E8PBe7!qvS7-Y-XEdka3y5>31Lod16Tmp0mPJy;&Li>O~M_$3vO zcaLwu_3;Sp+m%LDZQ7-1#*(T{`%a}%@O)icSC>J|X^zmAgN@f;%{g;9SYK^kZ@&Yo z*-q_mQ<0js>%ektj@MtodHmjitL5?g8(iII!5F{4!(;rk$C&&BT-vDX2CzKZ@lUYz zFR%Ld9$3xy|A_w=+_>0x-Uq9BdN_{W16|)ApqWD-`*tIxnz^)p2v&xSGES8UF*~)xv)Vu-d)!%X>g~xSHeQzVubFhx?MY&vEwS zbYBuXo<2YC2)=?mF`l+%Cp7iA*X|6qPs1yl?dea9dbDR3uPI#+swy>5}C32u&fHkC$kc_Me-$F;STJ4e0N&P!vRd;5U%KEE$qZ8-BL_VoSWv8QW~di#S*8*RFcv6YAI z7O-0I+bSM&;dZz_9--Y)Y0mx7?lg{*RBhT_l}6Ea|GOJvPIJUP@ke0e^^bevkHPwC zbG&Y*RI{D#U;BgAwB1Uja&3;)0B|0w&%@Omt9YjP54gJXB*yOmc#NO+7?Ur6OB;3l zkhuLzt-1(kz2%5U}-ib}_d^D%==CK|2b12w&_d@rC zVQ~8~va&@E^_;_8<}hYB*n0H6gHj&05n#1=ha3qvzxN_-`Cg=-_J|!-#YSI8!ySLe zD164CsmD9|;b7y`BW^6%IM;f_jYCuSdfA5~z{aZEkGt?!Gl%z)Bf<6ek@0BieycUd z1hAU%cM~tSKEJn51h1x)uc4d-Uq>0=+b6^IQI9rG0o#t?N5Rb->+LIWebnQd{Lx@@ zX~VS~U)$3kqAl-B?oW~X7;wH991AxlkJ;DI)MKotg4K+*4sB|Y^Xp(WxqIqyU~^99 z`}{!oH{fcX9t=m>=1UoK?Z>0*W1hH{&0urnd*gqh>FZ%T^ihkLX<%dWy>U94G1h5} zK57v&18j_QE%wHlXvQFyG5V-Q|Gt3181wa@l!xs=u=iGNdr->5b}(4~7?;6dHBXNi z7h?}X(=HxD>HcJ!hk*~{9K@OTg5i~}|4^_z{6~WIcU)|Xb9fY7UH=i3a`&U3(oYZf zBme)`PvC1g-A}~EyPrG=wq3^G3zkRjhs2fbK5)sadRM`%&$#=+C8u8<$@v7_T)AIQ z!qsCgJ_Yvwv#G~5{2AD|+`pg0)g$g{u>bE(eHryR2EPECPh0GZzXW?7{3fW~c0Nj} z9{qa;tQNVS1+To^20OQ=Faq*N;QGXAUiCF-+VnT?J(OzhE6x$;gYzQtt^=DleC65K znDAW>HlMx^P|CwLnjC6zZO6b}GkG649Il^-IrLGBn6Y4E@;)#QZj9H&7=6?t<_NGc zc^^0uZVZ2Aj6Q0%)qQRP*ckJTr<8|n64>>xZ6c*SY#ZsHnzl_eNd74;JDBtT0f62d A4*&oF literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.h new file mode 100644 index 000000000..7bb4ca772 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.h @@ -0,0 +1,1658 @@ +#pragma once + +const uint32_t atomic_draw_atlas_blit_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000b7a,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000388, + 0x00000437,0x00000439,0x00000454,0x00000462,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000139,0x0000674e, + 0x00030005,0x000002aa,0x0000674d,0x00030005,0x00000321,0x00006576,0x00040006,0x00000321, + 0x00000000,0x00003464,0x00030005,0x00000323,0x00004355,0x00030005,0x00000333,0x0000674b, + 0x00030005,0x0000034c,0x00006747,0x00040005,0x0000035a,0x30653742,0x00000000,0x00030005, + 0x00000365,0x00006748,0x00030005,0x00000373,0x00006577,0x00040006,0x00000373,0x00000000, + 0x00003464,0x00030005,0x00000375,0x0000424f,0x00060005,0x00000388,0x465f6c67,0x43676172, + 0x64726f6f,0x00000000,0x00030005,0x000003f3,0x00004444,0x00030005,0x000003f7,0x00006277, + 0x00030005,0x00000404,0x00006749,0x00040005,0x0000041a,0x306a3742,0x00000000,0x00030005, + 0x00000437,0x0000306a,0x00030005,0x00000439,0x00003065,0x00030005,0x0000043b,0x00000045, + 0x00030005,0x00000440,0x00003270,0x00030005,0x00000443,0x00003470,0x00030005,0x00000449, + 0x00003145,0x00040005,0x0000044d,0x61726170,0x0000006d,0x00040005,0x0000044f,0x61726170, + 0x0000006d,0x00030005,0x00000452,0x00003948,0x00030005,0x00000454,0x0000307a,0x00040005, + 0x00000455,0x61726170,0x0000006d,0x00030005,0x0000045b,0x0000006e,0x00030005,0x0000045c, + 0x00004356,0x00030005,0x0000045e,0x00003949,0x00030005,0x00000462,0x00003243,0x00040005, + 0x00000466,0x61726170,0x0000006d,0x00040005,0x00000468,0x61726170,0x0000006d,0x00030005, + 0x0000046b,0x00006543,0x00030005,0x00000478,0x00000050,0x00040005,0x00000479,0x61726170, + 0x0000006d,0x00030005,0x0000047b,0x00003171,0x00040005,0x0000047c,0x61726170,0x0000006d, + 0x00030005,0x0000047e,0x0000394a,0x00040005,0x00000482,0x61726170,0x0000006d,0x00040005, + 0x00000484,0x61726170,0x0000006d,0x00040005,0x00000486,0x61726170,0x0000006d,0x00040005, + 0x00000488,0x61726170,0x0000006d,0x00040005,0x00000489,0x61726170,0x0000006d,0x00030005, + 0x00000491,0x0000424d,0x00040006,0x00000491,0x00000000,0x00003376,0x00040006,0x00000491, + 0x00000001,0x00003377,0x00030005,0x00000493,0x0000006b,0x00040005,0x00000496,0x61726170, + 0x0000006d,0x00040005,0x00000499,0x61726170,0x0000006d,0x00040005,0x0000049c,0x61726170, + 0x0000006d,0x00040005,0x000004a0,0x61726170,0x0000006d,0x00040005,0x000004aa,0x61726170, + 0x0000006d,0x00040005,0x000004af,0x61726170,0x0000006d,0x00040047,0x00000139,0x00000001, + 0x00000007,0x00040047,0x000002aa,0x00000001,0x00000006,0x00040047,0x00000320,0x00000006, + 0x00000008,0x00030047,0x00000321,0x00000003,0x00040048,0x00000321,0x00000000,0x00000018, + 0x00050048,0x00000321,0x00000000,0x00000023,0x00000000,0x00030047,0x00000323,0x00000018, + 0x00040047,0x00000323,0x00000021,0x00000004,0x00040047,0x00000323,0x00000022,0x00000000, + 0x00040047,0x00000333,0x00000001,0x00000004,0x00040047,0x0000034c,0x00000001,0x00000000, + 0x00030047,0x0000035a,0x00000000,0x00040047,0x0000035a,0x00000021,0x00000001,0x00040047, + 0x0000035a,0x00000022,0x00000002,0x00040047,0x0000035a,0x0000002b,0x00000001,0x00040047, + 0x00000365,0x00000001,0x00000001,0x00040047,0x00000372,0x00000006,0x00000010,0x00030047, + 0x00000373,0x00000003,0x00040048,0x00000373,0x00000000,0x00000018,0x00050048,0x00000373, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000375,0x00000018,0x00040047,0x00000375, + 0x00000021,0x00000005,0x00040047,0x00000375,0x00000022,0x00000000,0x00040047,0x00000388, + 0x0000000b,0x0000000f,0x00030047,0x000003f3,0x00000000,0x00040047,0x000003f3,0x00000021, + 0x00000009,0x00040047,0x000003f3,0x00000022,0x00000000,0x00030047,0x000003f7,0x00000000, + 0x00040047,0x000003f7,0x00000021,0x00000009,0x00040047,0x000003f7,0x00000022,0x00000000, + 0x00040047,0x00000404,0x00000001,0x00000002,0x00030047,0x0000041a,0x00000000,0x00040047, + 0x0000041a,0x00000021,0x00000000,0x00040047,0x0000041a,0x00000022,0x00000002,0x00040047, + 0x0000041a,0x0000002b,0x00000000,0x00030047,0x00000437,0x00000000,0x00040047,0x00000437, + 0x0000001e,0x00000000,0x00030047,0x00000439,0x00000000,0x00040047,0x00000439,0x0000001e, + 0x00000001,0x00030047,0x00000443,0x00000017,0x00040047,0x00000443,0x00000021,0x00000003, + 0x00040047,0x00000443,0x00000022,0x00000002,0x00030047,0x00000449,0x00000000,0x00030047, + 0x0000044f,0x00000000,0x00030047,0x00000450,0x00000000,0x00030047,0x00000454,0x00000000, + 0x00030047,0x00000454,0x0000000e,0x00040047,0x00000454,0x0000001e,0x00000001,0x00030047, + 0x00000455,0x00000000,0x00030047,0x00000456,0x00000000,0x00030047,0x0000045b,0x00000000, + 0x00030047,0x0000045c,0x00000000,0x00040047,0x0000045c,0x00000021,0x0000000b,0x00040047, + 0x0000045c,0x00000022,0x00000000,0x00030047,0x0000045d,0x00000000,0x00030047,0x0000045e, + 0x00000000,0x00040047,0x0000045e,0x00000021,0x0000000b,0x00040047,0x0000045e,0x00000022, + 0x00000000,0x00030047,0x0000045f,0x00000000,0x00040047,0x00000462,0x0000001e,0x00000000, + 0x00030047,0x00000464,0x00000000,0x00030047,0x00000465,0x00000000,0x00030047,0x00000466, + 0x00000000,0x00030047,0x00000468,0x00000000,0x00030047,0x0000046a,0x00000000,0x00030047, + 0x0000046c,0x00000000,0x00030047,0x0000046e,0x00000000,0x00030047,0x0000046f,0x00000000, + 0x00030047,0x00000470,0x00000000,0x00030047,0x00000478,0x00000000,0x00030047,0x00000479, + 0x00000000,0x00030047,0x0000047b,0x00000000,0x00030047,0x0000047c,0x00000000,0x00030047, + 0x0000047e,0x00000000,0x00030047,0x00000485,0x00000000,0x00030047,0x00000486,0x00000000, + 0x00030047,0x00000487,0x00000000,0x00030047,0x00000488,0x00000000,0x00030047,0x00000489, + 0x00000000,0x00030047,0x0000048a,0x00000000,0x00030047,0x00000491,0x00000002,0x00050048, + 0x00000491,0x00000000,0x00000023,0x00000058,0x00050048,0x00000491,0x00000001,0x00000023, + 0x0000005c,0x00040047,0x00000493,0x00000021,0x00000000,0x00040047,0x00000493,0x00000022, + 0x00000000,0x00030047,0x00000496,0x00000000,0x00030047,0x00000497,0x00000000,0x00030047, + 0x00000498,0x00000000,0x00030047,0x0000049c,0x00000000,0x00030047,0x000004a0,0x00000000, + 0x00030047,0x000004aa,0x00000000,0x00030047,0x000004ab,0x00000000,0x00030047,0x000004af, + 0x00000000,0x00030047,0x000004b0,0x00000000,0x00030047,0x000004c0,0x00000000,0x00030047, + 0x000004c1,0x00000000,0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c5,0x00000000, + 0x00030047,0x000004c7,0x00000000,0x00030047,0x000004cb,0x00000000,0x00030047,0x000004cd, + 0x00000000,0x00030047,0x000004cf,0x00000000,0x00030047,0x000004d0,0x00000000,0x00030047, + 0x000004d2,0x00000000,0x00030047,0x000004d3,0x00000000,0x00030047,0x000004d4,0x00000000, + 0x00030047,0x000004d6,0x00000000,0x00030047,0x000004d8,0x00000000,0x00030047,0x000004da, + 0x00000000,0x00030047,0x000004dc,0x00000000,0x00030047,0x000004de,0x00000000,0x00030047, + 0x000004df,0x00000000,0x00030047,0x000004e0,0x00000000,0x00030047,0x000004e2,0x00000000, + 0x00030047,0x000004e4,0x00000000,0x00030047,0x000004e6,0x00000000,0x00030047,0x000004e8, + 0x00000000,0x00030047,0x000004ea,0x00000000,0x00030047,0x000004ec,0x00000000,0x00030047, + 0x000004f3,0x00000000,0x00030047,0x000004f4,0x00000000,0x00030047,0x000004f7,0x00000000, + 0x00030047,0x000004f9,0x00000000,0x00030047,0x000004fa,0x00000000,0x00030047,0x000004fb, + 0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047,0x000004ff,0x00000000,0x00030047, + 0x00000504,0x00000000,0x00030047,0x00000506,0x00000000,0x00030047,0x00000508,0x00000000, + 0x00030047,0x00000511,0x00000000,0x00030047,0x00000513,0x00000000,0x00030047,0x00000514, + 0x00000000,0x00030047,0x00000515,0x00000000,0x00030047,0x00000516,0x00000000,0x00030047, + 0x0000051b,0x00000000,0x00030047,0x00000521,0x00000000,0x00030047,0x00000522,0x00000000, + 0x00030047,0x0000052b,0x00000000,0x00030047,0x0000052c,0x00000000,0x00030047,0x0000052d, + 0x00000000,0x00030047,0x0000052e,0x00000000,0x00030047,0x0000052f,0x00000000,0x00030047, + 0x00000530,0x00000000,0x00030047,0x00000531,0x00000000,0x00030047,0x00000534,0x00000000, + 0x00030047,0x00000537,0x00000000,0x00030047,0x0000053f,0x00000000,0x00030047,0x00000540, + 0x00000000,0x00030047,0x00000542,0x00000000,0x00030047,0x0000056b,0x00000000,0x00030047, + 0x0000056d,0x00000000,0x00030047,0x0000056e,0x00000000,0x00030047,0x0000056f,0x00000000, + 0x00030047,0x00000570,0x00000000,0x00030047,0x00000571,0x00000000,0x00030047,0x00000572, + 0x00000000,0x00030047,0x00000573,0x00000000,0x00030047,0x00000582,0x00000000,0x00030047, + 0x00000588,0x00000000,0x00030047,0x000005b5,0x00000000,0x00030047,0x000005b6,0x00000000, + 0x00030047,0x000005bb,0x00000000,0x00030047,0x000005bd,0x00000000,0x00030047,0x000005bf, + 0x00000000,0x00030047,0x000005c0,0x00000000,0x00030047,0x000005c4,0x00000000,0x00030047, + 0x000005d2,0x00000000,0x00030047,0x000005d3,0x00000000,0x00030047,0x000005d4,0x00000000, + 0x00030047,0x000005d5,0x00000000,0x00030047,0x000005d6,0x00000000,0x00030047,0x000005d7, + 0x00000000,0x00030047,0x000005e1,0x00000000,0x00030047,0x000005e2,0x00000000,0x00030047, + 0x000005e3,0x00000000,0x00030047,0x000005e4,0x00000000,0x00030047,0x000005eb,0x00000000, + 0x00030047,0x000005ed,0x00000000,0x00030047,0x000005ee,0x00000000,0x00030047,0x000005f0, + 0x00000000,0x00030047,0x000005f1,0x00000000,0x00030047,0x000005f3,0x00000000,0x00030047, + 0x000005f4,0x00000000,0x00030047,0x000005fe,0x00000000,0x00030047,0x00000600,0x00000000, + 0x00030047,0x00000601,0x00000000,0x00030047,0x00000604,0x00000000,0x00030047,0x00000605, + 0x00000000,0x00030047,0x00000607,0x00000000,0x00030047,0x00000609,0x00000000,0x00030047, + 0x0000060b,0x00000000,0x00030047,0x00000619,0x00000000,0x00030047,0x0000061a,0x00000000, + 0x00030047,0x0000061d,0x00000000,0x00030047,0x0000061e,0x00000000,0x00030047,0x0000061f, + 0x00000000,0x00030047,0x00000621,0x00000000,0x00030047,0x00000623,0x00000000,0x00030047, + 0x00000625,0x00000000,0x00030047,0x00000627,0x00000000,0x00030047,0x00000629,0x00000000, + 0x00030047,0x00000637,0x00000000,0x00030047,0x00000638,0x00000000,0x00030047,0x0000063b, + 0x00000000,0x00030047,0x0000063c,0x00000000,0x00030047,0x0000063d,0x00000000,0x00030047, + 0x0000063e,0x00000000,0x00030047,0x0000063f,0x00000000,0x00030047,0x00000640,0x00000000, + 0x00030047,0x00000641,0x00000000,0x00030047,0x00000643,0x00000000,0x00030047,0x00000644, + 0x00000000,0x00030047,0x00000645,0x00000000,0x00030047,0x00000647,0x00000000,0x00030047, + 0x00000648,0x00000000,0x00030047,0x0000064a,0x00000000,0x00030047,0x0000064c,0x00000000, + 0x00030047,0x0000064d,0x00000000,0x00030047,0x0000064e,0x00000000,0x00030047,0x0000064f, + 0x00000000,0x00030047,0x00000650,0x00000000,0x00030047,0x00000651,0x00000000,0x00030047, + 0x00000652,0x00000000,0x00030047,0x00000653,0x00000000,0x00030047,0x00000654,0x00000000, + 0x00030047,0x00000655,0x00000000,0x00030047,0x00000656,0x00000000,0x00030047,0x00000657, + 0x00000000,0x00030047,0x00000658,0x00000000,0x00030047,0x00000659,0x00000000,0x00030047, + 0x0000065a,0x00000000,0x00030047,0x0000065b,0x00000000,0x00030047,0x0000065c,0x00000000, + 0x00030047,0x0000065d,0x00000000,0x00030047,0x0000065e,0x00000000,0x00030047,0x0000065f, + 0x00000000,0x00030047,0x00000661,0x00000000,0x00030047,0x00000662,0x00000000,0x00030047, + 0x00000663,0x00000000,0x00030047,0x00000664,0x00000000,0x00030047,0x00000665,0x00000000, + 0x00030047,0x00000666,0x00000000,0x00030047,0x00000667,0x00000000,0x00030047,0x00000668, + 0x00000000,0x00030047,0x00000669,0x00000000,0x00030047,0x0000066a,0x00000000,0x00030047, + 0x0000066b,0x00000000,0x00030047,0x0000066c,0x00000000,0x00030047,0x0000066d,0x00000000, + 0x00030047,0x0000066e,0x00000000,0x00030047,0x0000066f,0x00000000,0x00030047,0x00000670, + 0x00000000,0x00030047,0x00000671,0x00000000,0x00030047,0x00000672,0x00000000,0x00030047, + 0x00000673,0x00000000,0x00030047,0x00000675,0x00000000,0x00030047,0x00000677,0x00000000, + 0x00030047,0x00000679,0x00000000,0x00030047,0x0000067a,0x00000000,0x00030047,0x0000067b, + 0x00000000,0x00030047,0x0000067d,0x00000000,0x00030047,0x0000067e,0x00000000,0x00030047, + 0x0000067f,0x00000000,0x00030047,0x00000680,0x00000000,0x00030047,0x00000681,0x00000000, + 0x00030047,0x00000682,0x00000000,0x00030047,0x00000683,0x00000000,0x00030047,0x00000685, + 0x00000000,0x00030047,0x00000686,0x00000000,0x00030047,0x00000687,0x00000000,0x00030047, + 0x00000688,0x00000000,0x00030047,0x00000689,0x00000000,0x00030047,0x0000068a,0x00000000, + 0x00030047,0x0000068b,0x00000000,0x00030047,0x0000068c,0x00000000,0x00030047,0x0000068d, + 0x00000000,0x00030047,0x0000068e,0x00000000,0x00030047,0x0000068f,0x00000000,0x00030047, + 0x00000691,0x00000000,0x00030047,0x00000692,0x00000000,0x00030047,0x00000693,0x00000000, + 0x00030047,0x00000695,0x00000000,0x00030047,0x00000696,0x00000000,0x00030047,0x00000697, + 0x00000000,0x00030047,0x00000699,0x00000000,0x00030047,0x0000069a,0x00000000,0x00030047, + 0x0000069b,0x00000000,0x00030047,0x0000069d,0x00000000,0x00030047,0x0000069e,0x00000000, + 0x00030047,0x000006a0,0x00000000,0x00030047,0x000006a1,0x00000000,0x00030047,0x000006a2, + 0x00000000,0x00030047,0x000006a9,0x00000000,0x00030047,0x000006aa,0x00000000,0x00030047, + 0x000006ad,0x00000000,0x00030047,0x000006af,0x00000000,0x00030047,0x000006b0,0x00000000, + 0x00030047,0x000006b2,0x00000000,0x00030047,0x000006b3,0x00000000,0x00030047,0x000006b4, + 0x00000000,0x00030047,0x000006b5,0x00000000,0x00030047,0x000006b6,0x00000000,0x00030047, + 0x000006b7,0x00000000,0x00030047,0x000006b8,0x00000000,0x00030047,0x000006b9,0x00000000, + 0x00030047,0x000006ba,0x00000000,0x00030047,0x000006bc,0x00000000,0x00030047,0x000006bd, + 0x00000000,0x00030047,0x000006bf,0x00000000,0x00030047,0x000006c2,0x00000000,0x00030047, + 0x000006c3,0x00000000,0x00030047,0x000006c4,0x00000000,0x00030047,0x000006c6,0x00000000, + 0x00030047,0x000006c7,0x00000000,0x00030047,0x000006c8,0x00000000,0x00030047,0x000006d0, + 0x00000000,0x00030047,0x000006d6,0x00000000,0x00030047,0x000006d7,0x00000000,0x00030047, + 0x000006d8,0x00000000,0x00030047,0x000006d9,0x00000000,0x00030047,0x000006da,0x00000000, + 0x00030047,0x000006dc,0x00000000,0x00030047,0x000006dd,0x00000000,0x00030047,0x000006df, + 0x00000000,0x00030047,0x000006e0,0x00000000,0x00030047,0x000006e1,0x00000000,0x00030047, + 0x000006e2,0x00000000,0x00030047,0x000006e3,0x00000000,0x00030047,0x000006e4,0x00000000, + 0x00030047,0x000006e5,0x00000000,0x00030047,0x000006e7,0x00000000,0x00030047,0x000006e8, + 0x00000000,0x00030047,0x000006e9,0x00000000,0x00030047,0x000006eb,0x00000000,0x00030047, + 0x000006ec,0x00000000,0x00030047,0x000006ed,0x00000000,0x00030047,0x000006ee,0x00000000, + 0x00030047,0x000006ef,0x00000000,0x00030047,0x000006f0,0x00000000,0x00030047,0x000006f1, + 0x00000000,0x00030047,0x000006f2,0x00000000,0x00030047,0x000006f3,0x00000000,0x00030047, + 0x000006f4,0x00000000,0x00030047,0x000006f5,0x00000000,0x00030047,0x000006f7,0x00000000, + 0x00030047,0x000006f8,0x00000000,0x00030047,0x000006f9,0x00000000,0x00030047,0x00000702, + 0x00000000,0x00030047,0x00000708,0x00000000,0x00030047,0x00000709,0x00000000,0x00030047, + 0x0000070e,0x00000000,0x00030047,0x00000714,0x00000000,0x00030047,0x00000715,0x00000000, + 0x00030047,0x00000716,0x00000000,0x00030047,0x00000719,0x00000000,0x00030047,0x0000071a, + 0x00000000,0x00030047,0x0000071b,0x00000000,0x00030047,0x00000721,0x00000000,0x00030047, + 0x00000722,0x00000000,0x00030047,0x00000723,0x00000000,0x00030047,0x0000072b,0x00000000, + 0x00030047,0x0000072c,0x00000000,0x00030047,0x0000072d,0x00000000,0x00030047,0x0000072e, + 0x00000000,0x00030047,0x0000072f,0x00000000,0x00030047,0x00000730,0x00000000,0x00030047, + 0x00000731,0x00000000,0x00030047,0x00000732,0x00000000,0x00030047,0x00000733,0x00000000, + 0x00030047,0x00000735,0x00000000,0x00030047,0x00000736,0x00000000,0x00030047,0x00000737, + 0x00000000,0x00030047,0x00000738,0x00000000,0x00030047,0x0000073a,0x00000000,0x00030047, + 0x0000073b,0x00000000,0x00030047,0x0000073c,0x00000000,0x00030047,0x0000073d,0x00000000, + 0x00030047,0x0000073e,0x00000000,0x00030047,0x0000073f,0x00000000,0x00030047,0x00000740, + 0x00000000,0x00030047,0x00000741,0x00000000,0x00030047,0x00000744,0x00000000,0x00030047, + 0x00000747,0x00000000,0x00030047,0x00000748,0x00000000,0x00030047,0x00000749,0x00000000, + 0x00030047,0x0000074a,0x00000000,0x00030047,0x0000074f,0x00000000,0x00030047,0x00000752, + 0x00000000,0x00030047,0x00000753,0x00000000,0x00030047,0x00000754,0x00000000,0x00030047, + 0x00000755,0x00000000,0x00030047,0x0000075a,0x00000000,0x00030047,0x0000075d,0x00000000, + 0x00030047,0x0000075e,0x00000000,0x00030047,0x0000075f,0x00000000,0x00030047,0x00000764, + 0x00000000,0x00030047,0x00000767,0x00000000,0x00030047,0x00000768,0x00000000,0x00030047, + 0x00000769,0x00000000,0x00030047,0x0000076d,0x00000000,0x00030047,0x0000076e,0x00000000, + 0x00030047,0x0000076f,0x00000000,0x00030047,0x00000771,0x00000000,0x00030047,0x00000772, + 0x00000000,0x00030047,0x00000774,0x00000000,0x00030047,0x00000778,0x00000000,0x00030047, + 0x00000779,0x00000000,0x00030047,0x0000077c,0x00000000,0x00030047,0x0000077d,0x00000000, + 0x00030047,0x0000077e,0x00000000,0x00030047,0x0000077f,0x00000000,0x00030047,0x00000781, + 0x00000000,0x00030047,0x00000783,0x00000000,0x00030047,0x00000785,0x00000000,0x00030047, + 0x00000787,0x00000000,0x00030047,0x00000788,0x00000000,0x00030047,0x00000789,0x00000000, + 0x00030047,0x0000078b,0x00000000,0x00030047,0x0000078d,0x00000000,0x00030047,0x0000078f, + 0x00000000,0x00030047,0x00000791,0x00000000,0x00030047,0x00000792,0x00000000,0x00030047, + 0x00000793,0x00000000,0x00030047,0x00000795,0x00000000,0x00030047,0x00000797,0x00000000, + 0x00030047,0x00000799,0x00000000,0x00030047,0x0000079b,0x00000000,0x00030047,0x0000079c, + 0x00000000,0x00030047,0x0000079d,0x00000000,0x00030047,0x0000079f,0x00000000,0x00030047, + 0x000007a1,0x00000000,0x00030047,0x000007a3,0x00000000,0x00030047,0x000007a5,0x00000000, + 0x00030047,0x000007a6,0x00000000,0x00030047,0x000007a7,0x00000000,0x00030047,0x000007a9, + 0x00000000,0x00030047,0x000007ab,0x00000000,0x00030047,0x000007ad,0x00000000,0x00030047, + 0x000007af,0x00000000,0x00030047,0x000007b0,0x00000000,0x00030047,0x000007b1,0x00000000, + 0x00030047,0x000007b3,0x00000000,0x00030047,0x000007b5,0x00000000,0x00030047,0x000007b7, + 0x00000000,0x00030047,0x000007b9,0x00000000,0x00030047,0x000007ba,0x00000000,0x00030047, + 0x000007bb,0x00000000,0x00030047,0x000007bd,0x00000000,0x00030047,0x000007bf,0x00000000, + 0x00030047,0x000007c1,0x00000000,0x00030047,0x000007c3,0x00000000,0x00030047,0x000007c4, + 0x00000000,0x00030047,0x000007c5,0x00000000,0x00030047,0x000007c7,0x00000000,0x00030047, + 0x000007c9,0x00000000,0x00030047,0x000007cb,0x00000000,0x00030047,0x000007cd,0x00000000, + 0x00030047,0x000007ce,0x00000000,0x00030047,0x000007cf,0x00000000,0x00030047,0x000007d1, + 0x00000000,0x00030047,0x000007d3,0x00000000,0x00030047,0x000007d5,0x00000000,0x00030047, + 0x000007d7,0x00000000,0x00030047,0x000007d8,0x00000000,0x00030047,0x000007d9,0x00000000, + 0x00030047,0x000007db,0x00000000,0x00030047,0x000007dd,0x00000000,0x00030047,0x000007df, + 0x00000000,0x00030047,0x000007e1,0x00000000,0x00030047,0x000007e2,0x00000000,0x00030047, + 0x000007e3,0x00000000,0x00030047,0x000007e5,0x00000000,0x00030047,0x000007e7,0x00000000, + 0x00030047,0x000007e9,0x00000000,0x00030047,0x000007eb,0x00000000,0x00030047,0x000007ec, + 0x00000000,0x00030047,0x000007ed,0x00000000,0x00030047,0x000007ef,0x00000000,0x00030047, + 0x000007f1,0x00000000,0x00030047,0x000007f3,0x00000000,0x00030047,0x000007f5,0x00000000, + 0x00030047,0x000007f6,0x00000000,0x00030047,0x000007f7,0x00000000,0x00030047,0x000007f9, + 0x00000000,0x00030047,0x000007fb,0x00000000,0x00030047,0x000007fd,0x00000000,0x00030047, + 0x000007ff,0x00000000,0x00030047,0x00000800,0x00000000,0x00030047,0x00000801,0x00000000, + 0x00030047,0x00000803,0x00000000,0x00030047,0x00000805,0x00000000,0x00030047,0x00000807, + 0x00000000,0x00030047,0x00000809,0x00000000,0x00030047,0x0000080b,0x00000000,0x00030047, + 0x0000080c,0x00000000,0x00030047,0x0000080d,0x00000000,0x00030047,0x0000080f,0x00000000, + 0x00030047,0x00000811,0x00000000,0x00030047,0x00000812,0x00000000,0x00030047,0x00000813, + 0x00000000,0x00030047,0x00000815,0x00000000,0x00030047,0x00000817,0x00000000,0x00030047, + 0x00000819,0x00000000,0x00030047,0x0000081a,0x00000000,0x00030047,0x0000081c,0x00000000, + 0x00030047,0x0000081d,0x00000000,0x00030047,0x0000081e,0x00000000,0x00030047,0x0000081f, + 0x00000000,0x00030047,0x00000825,0x00000000,0x00030047,0x00000828,0x00000000,0x00030047, + 0x0000082a,0x00000000,0x00030047,0x0000082b,0x00000000,0x00030047,0x0000082d,0x00000000, + 0x00030047,0x0000082e,0x00000000,0x00030047,0x00000831,0x00000000,0x00030047,0x00000832, + 0x00000000,0x00030047,0x00000833,0x00000000,0x00030047,0x00000836,0x00000000,0x00030047, + 0x00000838,0x00000000,0x00030047,0x00000839,0x00000000,0x00030047,0x0000083a,0x00000000, + 0x00030047,0x0000083b,0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x0000083e, + 0x00000000,0x00030047,0x00000841,0x00000000,0x00030047,0x00000842,0x00000000,0x00030047, + 0x00000843,0x00000000,0x00030047,0x00000846,0x00000000,0x00030047,0x00000848,0x00000000, + 0x00030047,0x00000849,0x00000000,0x00030047,0x0000084a,0x00000000,0x00030047,0x0000084b, + 0x00000000,0x00030047,0x0000084d,0x00000000,0x00030047,0x0000084e,0x00000000,0x00030047, + 0x00000851,0x00000000,0x00030047,0x00000852,0x00000000,0x00030047,0x00000853,0x00000000, + 0x00030047,0x00000856,0x00000000,0x00030047,0x00000858,0x00000000,0x00030047,0x00000859, + 0x00000000,0x00030047,0x0000085a,0x00000000,0x00030047,0x0000085b,0x00000000,0x00030047, + 0x0000085d,0x00000000,0x00030047,0x0000085e,0x00000000,0x00030047,0x00000861,0x00000000, + 0x00030047,0x00000862,0x00000000,0x00030047,0x00000863,0x00000000,0x00030047,0x00000866, + 0x00000000,0x00030047,0x00000868,0x00000000,0x00030047,0x00000869,0x00000000,0x00030047, + 0x0000086a,0x00000000,0x00030047,0x0000086b,0x00000000,0x00030047,0x0000086c,0x00000000, + 0x00030047,0x0000086d,0x00000000,0x00030047,0x0000086e,0x00000000,0x00030047,0x0000086f, + 0x00000000,0x00030047,0x00000870,0x00000000,0x00030047,0x00000871,0x00000000,0x00030047, + 0x00000872,0x00000000,0x00030047,0x00000873,0x00000000,0x00030047,0x00000874,0x00000000, + 0x00030047,0x00000875,0x00000000,0x00030047,0x00000876,0x00000000,0x00030047,0x00000877, + 0x00000000,0x00030047,0x00000878,0x00000000,0x00030047,0x0000087a,0x00000000,0x00030047, + 0x0000087c,0x00000000,0x00030047,0x0000087d,0x00000000,0x00030047,0x0000087f,0x00000000, + 0x00030047,0x00000880,0x00000000,0x00030047,0x00000881,0x00000000,0x00030047,0x00000882, + 0x00000000,0x00030047,0x00000883,0x00000000,0x00030047,0x00000886,0x00000000,0x00030047, + 0x00000888,0x00000000,0x00030047,0x00000889,0x00000000,0x00030047,0x0000088c,0x00000000, + 0x00030047,0x0000088d,0x00000000,0x00030047,0x00000890,0x00000000,0x00030047,0x00000892, + 0x00000000,0x00030047,0x00000893,0x00000000,0x00030047,0x00000894,0x00000000,0x00030047, + 0x00000895,0x00000000,0x00030047,0x00000896,0x00000000,0x00030047,0x00000897,0x00000000, + 0x00030047,0x00000898,0x00000000,0x00030047,0x00000899,0x00000000,0x00030047,0x0000089a, + 0x00000000,0x00030047,0x0000089b,0x00000000,0x00030047,0x0000089c,0x00000000,0x00030047, + 0x0000089d,0x00000000,0x00030047,0x0000089e,0x00000000,0x00030047,0x000008a0,0x00000000, + 0x00030047,0x000008a2,0x00000000,0x00030047,0x000008a3,0x00000000,0x00030047,0x000008a4, + 0x00000000,0x00030047,0x000008a6,0x00000000,0x00030047,0x000008a8,0x00000000,0x00030047, + 0x000008aa,0x00000000,0x00030047,0x000008ac,0x00000000,0x00030047,0x000008ad,0x00000000, + 0x00030047,0x000008ae,0x00000000,0x00030047,0x000008af,0x00000000,0x00030047,0x000008b0, + 0x00000000,0x00030047,0x000008b2,0x00000000,0x00030047,0x000008b4,0x00000000,0x00030047, + 0x000008b5,0x00000000,0x00030047,0x000008b6,0x00000000,0x00030047,0x000008b8,0x00000000, + 0x00030047,0x000008ba,0x00000000,0x00030047,0x000008bc,0x00000000,0x00030047,0x000008be, + 0x00000000,0x00030047,0x000008bf,0x00000000,0x00030047,0x000008c0,0x00000000,0x00030047, + 0x000008c2,0x00000000,0x00030047,0x000008c4,0x00000000,0x00030047,0x000008c6,0x00000000, + 0x00030047,0x000008c7,0x00000000,0x00030047,0x000008c8,0x00000000,0x00030047,0x000008ca, + 0x00000000,0x00030047,0x000008cc,0x00000000,0x00030047,0x000008ce,0x00000000,0x00030047, + 0x000008cf,0x00000000,0x00030047,0x000008d0,0x00000000,0x00030047,0x000008d2,0x00000000, + 0x00030047,0x000008d3,0x00000000,0x00030047,0x000008d6,0x00000000,0x00030047,0x000008d7, + 0x00000000,0x00030047,0x000008d8,0x00000000,0x00030047,0x000008db,0x00000000,0x00030047, + 0x000008dd,0x00000000,0x00030047,0x000008de,0x00000000,0x00030047,0x000008df,0x00000000, + 0x00030047,0x000008e0,0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008e3, + 0x00000000,0x00030047,0x000008e6,0x00000000,0x00030047,0x000008e7,0x00000000,0x00030047, + 0x000008e8,0x00000000,0x00030047,0x000008eb,0x00000000,0x00030047,0x000008ed,0x00000000, + 0x00030047,0x000008ee,0x00000000,0x00030047,0x000008ef,0x00000000,0x00030047,0x000008f0, + 0x00000000,0x00030047,0x000008f2,0x00000000,0x00030047,0x000008f4,0x00000000,0x00030047, + 0x000008f6,0x00000000,0x00030047,0x000008f7,0x00000000,0x00030047,0x000008f9,0x00000000, + 0x00030047,0x000008fa,0x00000000,0x00030047,0x000008fb,0x00000000,0x00030047,0x000008fd, + 0x00000000,0x00030047,0x000008ff,0x00000000,0x00030047,0x00000901,0x00000000,0x00030047, + 0x00000903,0x00000000,0x00030047,0x00000904,0x00000000,0x00030047,0x00000905,0x00000000, + 0x00030047,0x00000907,0x00000000,0x00030047,0x00000909,0x00000000,0x00030047,0x0000090b, + 0x00000000,0x00030047,0x0000090d,0x00000000,0x00030047,0x0000090f,0x00000000,0x00030047, + 0x00000910,0x00000000,0x00030047,0x00000911,0x00000000,0x00030047,0x00000913,0x00000000, + 0x00030047,0x00000915,0x00000000,0x00030047,0x00000916,0x00000000,0x00030047,0x00000917, + 0x00000000,0x00030047,0x00000919,0x00000000,0x00030047,0x0000091b,0x00000000,0x00030047, + 0x0000091d,0x00000000,0x00030047,0x0000091e,0x00000000,0x00030047,0x00000920,0x00000000, + 0x00030047,0x00000921,0x00000000,0x00030047,0x00000922,0x00000000,0x00030047,0x00000923, + 0x00000000,0x00030047,0x00000929,0x00000000,0x00030047,0x0000092c,0x00000000,0x00030047, + 0x0000092e,0x00000000,0x00030047,0x0000092f,0x00000000,0x00030047,0x00000931,0x00000000, + 0x00030047,0x00000932,0x00000000,0x00030047,0x00000935,0x00000000,0x00030047,0x00000936, + 0x00000000,0x00030047,0x00000937,0x00000000,0x00030047,0x0000093a,0x00000000,0x00030047, + 0x0000093c,0x00000000,0x00030047,0x0000093d,0x00000000,0x00030047,0x0000093e,0x00000000, + 0x00030047,0x0000093f,0x00000000,0x00030047,0x00000941,0x00000000,0x00030047,0x00000942, + 0x00000000,0x00030047,0x00000945,0x00000000,0x00030047,0x00000946,0x00000000,0x00030047, + 0x00000947,0x00000000,0x00030047,0x0000094a,0x00000000,0x00030047,0x0000094c,0x00000000, + 0x00030047,0x0000094d,0x00000000,0x00030047,0x0000094e,0x00000000,0x00030047,0x0000094f, + 0x00000000,0x00030047,0x00000951,0x00000000,0x00030047,0x00000952,0x00000000,0x00030047, + 0x00000955,0x00000000,0x00030047,0x00000956,0x00000000,0x00030047,0x00000957,0x00000000, + 0x00030047,0x0000095a,0x00000000,0x00030047,0x0000095c,0x00000000,0x00030047,0x0000095d, + 0x00000000,0x00030047,0x0000095e,0x00000000,0x00030047,0x0000095f,0x00000000,0x00030047, + 0x00000961,0x00000000,0x00030047,0x00000962,0x00000000,0x00030047,0x00000965,0x00000000, + 0x00030047,0x00000966,0x00000000,0x00030047,0x00000967,0x00000000,0x00030047,0x0000096a, + 0x00000000,0x00030047,0x0000096c,0x00000000,0x00030047,0x0000096d,0x00000000,0x00030047, + 0x0000096e,0x00000000,0x00030047,0x0000096f,0x00000000,0x00030047,0x00000970,0x00000000, + 0x00030047,0x00000971,0x00000000,0x00030047,0x00000972,0x00000000,0x00030047,0x00000973, + 0x00000000,0x00030047,0x00000974,0x00000000,0x00030047,0x00000975,0x00000000,0x00030047, + 0x00000976,0x00000000,0x00030047,0x00000977,0x00000000,0x00030047,0x00000978,0x00000000, + 0x00030047,0x00000979,0x00000000,0x00030047,0x0000097a,0x00000000,0x00030047,0x0000097b, + 0x00000000,0x00030047,0x0000097c,0x00000000,0x00030047,0x0000097e,0x00000000,0x00030047, + 0x00000980,0x00000000,0x00030047,0x00000981,0x00000000,0x00030047,0x00000983,0x00000000, + 0x00030047,0x00000984,0x00000000,0x00030047,0x00000985,0x00000000,0x00030047,0x00000986, + 0x00000000,0x00030047,0x00000987,0x00000000,0x00030047,0x0000098a,0x00000000,0x00030047, + 0x0000098c,0x00000000,0x00030047,0x0000098d,0x00000000,0x00030047,0x00000990,0x00000000, + 0x00030047,0x00000991,0x00000000,0x00030047,0x00000994,0x00000000,0x00030047,0x00000996, + 0x00000000,0x00030047,0x00000997,0x00000000,0x00030047,0x00000998,0x00000000,0x00030047, + 0x00000999,0x00000000,0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099b,0x00000000, + 0x00030047,0x0000099c,0x00000000,0x00030047,0x0000099d,0x00000000,0x00030047,0x0000099e, + 0x00000000,0x00030047,0x0000099f,0x00000000,0x00030047,0x000009a0,0x00000000,0x00030047, + 0x000009a1,0x00000000,0x00030047,0x000009a2,0x00000000,0x00030047,0x000009a4,0x00000000, + 0x00030047,0x000009a6,0x00000000,0x00030047,0x000009a7,0x00000000,0x00030047,0x000009a8, + 0x00000000,0x00030047,0x000009aa,0x00000000,0x00030047,0x000009ac,0x00000000,0x00030047, + 0x000009ae,0x00000000,0x00030047,0x000009b0,0x00000000,0x00030047,0x000009b1,0x00000000, + 0x00030047,0x000009b2,0x00000000,0x00030047,0x000009b3,0x00000000,0x00030047,0x000009b4, + 0x00000000,0x00030047,0x000009b6,0x00000000,0x00030047,0x000009b8,0x00000000,0x00030047, + 0x000009b9,0x00000000,0x00030047,0x000009ba,0x00000000,0x00030047,0x000009bc,0x00000000, + 0x00030047,0x000009be,0x00000000,0x00030047,0x000009c0,0x00000000,0x00030047,0x000009c2, + 0x00000000,0x00030047,0x000009c3,0x00000000,0x00030047,0x000009c4,0x00000000,0x00030047, + 0x000009c6,0x00000000,0x00030047,0x000009c8,0x00000000,0x00030047,0x000009ca,0x00000000, + 0x00030047,0x000009cb,0x00000000,0x00030047,0x000009cc,0x00000000,0x00030047,0x000009ce, + 0x00000000,0x00030047,0x000009d0,0x00000000,0x00030047,0x000009d2,0x00000000,0x00030047, + 0x000009d3,0x00000000,0x00030047,0x000009d4,0x00000000,0x00030047,0x000009d6,0x00000000, + 0x00030047,0x000009d7,0x00000000,0x00030047,0x000009da,0x00000000,0x00030047,0x000009db, + 0x00000000,0x00030047,0x000009dc,0x00000000,0x00030047,0x000009df,0x00000000,0x00030047, + 0x000009e1,0x00000000,0x00030047,0x000009e2,0x00000000,0x00030047,0x000009e3,0x00000000, + 0x00030047,0x000009e4,0x00000000,0x00030047,0x000009e6,0x00000000,0x00030047,0x000009e7, + 0x00000000,0x00030047,0x000009ea,0x00000000,0x00030047,0x000009eb,0x00000000,0x00030047, + 0x000009ec,0x00000000,0x00030047,0x000009ef,0x00000000,0x00030047,0x000009f1,0x00000000, + 0x00030047,0x000009f2,0x00000000,0x00030047,0x000009f3,0x00000000,0x00030047,0x000009f4, + 0x00000000,0x00030047,0x000009f6,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047, + 0x000009fa,0x00000000,0x00030047,0x000009fb,0x00000000,0x00030047,0x000009fd,0x00000000, + 0x00030047,0x000009fe,0x00000000,0x00030047,0x000009ff,0x00000000,0x00030047,0x00000a01, + 0x00000000,0x00030047,0x00000a03,0x00000000,0x00030047,0x00000a05,0x00000000,0x00030047, + 0x00000a07,0x00000000,0x00030047,0x00000a08,0x00000000,0x00030047,0x00000a09,0x00000000, + 0x00030047,0x00000a0b,0x00000000,0x00030047,0x00000a0d,0x00000000,0x00030047,0x00000a0f, + 0x00000000,0x00030047,0x00000a11,0x00000000,0x00030047,0x00000a12,0x00000000,0x00030047, + 0x00000a13,0x00000000,0x00030047,0x00000a14,0x00000000,0x00030047,0x00000a15,0x00000000, + 0x00030047,0x00000a16,0x00000000,0x00030047,0x00000a17,0x00000000,0x00030047,0x00000a18, + 0x00000000,0x00030047,0x00000a19,0x00000000,0x00030047,0x00000a1a,0x00000000,0x00030047, + 0x00000a1b,0x00000000,0x00030047,0x00000a1c,0x00000000,0x00030047,0x00000a1d,0x00000000, + 0x00030047,0x00000a1e,0x00000000,0x00030047,0x00000a1f,0x00000000,0x00030047,0x00000a20, + 0x00000000,0x00030047,0x00000a22,0x00000000,0x00030047,0x00000a24,0x00000000,0x00030047, + 0x00000a25,0x00000000,0x00030047,0x00000a27,0x00000000,0x00030047,0x00000a28,0x00000000, + 0x00030047,0x00000a29,0x00000000,0x00030047,0x00000a2a,0x00000000,0x00030047,0x00000a2b, + 0x00000000,0x00030047,0x00000a2e,0x00000000,0x00030047,0x00000a30,0x00000000,0x00030047, + 0x00000a31,0x00000000,0x00030047,0x00000a34,0x00000000,0x00030047,0x00000a35,0x00000000, + 0x00030047,0x00000a38,0x00000000,0x00030047,0x00000a3a,0x00000000,0x00030047,0x00000a3b, + 0x00000000,0x00030047,0x00000a3c,0x00000000,0x00030047,0x00000a3d,0x00000000,0x00030047, + 0x00000a3e,0x00000000,0x00030047,0x00000a3f,0x00000000,0x00030047,0x00000a40,0x00000000, + 0x00030047,0x00000a41,0x00000000,0x00030047,0x00000a42,0x00000000,0x00030047,0x00000a43, + 0x00000000,0x00030047,0x00000a44,0x00000000,0x00030047,0x00000a45,0x00000000,0x00030047, + 0x00000a46,0x00000000,0x00030047,0x00000a48,0x00000000,0x00030047,0x00000a4a,0x00000000, + 0x00030047,0x00000a4b,0x00000000,0x00030047,0x00000a4c,0x00000000,0x00030047,0x00000a4e, + 0x00000000,0x00030047,0x00000a50,0x00000000,0x00030047,0x00000a52,0x00000000,0x00030047, + 0x00000a54,0x00000000,0x00030047,0x00000a55,0x00000000,0x00030047,0x00000a56,0x00000000, + 0x00030047,0x00000a57,0x00000000,0x00030047,0x00000a58,0x00000000,0x00030047,0x00000a5a, + 0x00000000,0x00030047,0x00000a5c,0x00000000,0x00030047,0x00000a5d,0x00000000,0x00030047, + 0x00000a5e,0x00000000,0x00030047,0x00000a60,0x00000000,0x00030047,0x00000a62,0x00000000, + 0x00030047,0x00000a64,0x00000000,0x00030047,0x00000a66,0x00000000,0x00030047,0x00000a67, + 0x00000000,0x00030047,0x00000a68,0x00000000,0x00030047,0x00000a6a,0x00000000,0x00030047, + 0x00000a6c,0x00000000,0x00030047,0x00000a6e,0x00000000,0x00030047,0x00000a6f,0x00000000, + 0x00030047,0x00000a70,0x00000000,0x00030047,0x00000a72,0x00000000,0x00030047,0x00000a74, + 0x00000000,0x00030047,0x00000a76,0x00000000,0x00030047,0x00000a77,0x00000000,0x00030047, + 0x00000a78,0x00000000,0x00030047,0x00000a7a,0x00000000,0x00030047,0x00000a7b,0x00000000, + 0x00030047,0x00000a7e,0x00000000,0x00030047,0x00000a7f,0x00000000,0x00030047,0x00000a80, + 0x00000000,0x00030047,0x00000a83,0x00000000,0x00030047,0x00000a85,0x00000000,0x00030047, + 0x00000a86,0x00000000,0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a88,0x00000000, + 0x00030047,0x00000a8a,0x00000000,0x00030047,0x00000a8b,0x00000000,0x00030047,0x00000a8e, + 0x00000000,0x00030047,0x00000a8f,0x00000000,0x00030047,0x00000a90,0x00000000,0x00030047, + 0x00000a93,0x00000000,0x00030047,0x00000a95,0x00000000,0x00030047,0x00000a96,0x00000000, + 0x00030047,0x00000a97,0x00000000,0x00030047,0x00000a98,0x00000000,0x00030047,0x00000a9a, + 0x00000000,0x00030047,0x00000a9c,0x00000000,0x00030047,0x00000a9e,0x00000000,0x00030047, + 0x00000a9f,0x00000000,0x00030047,0x00000aa1,0x00000000,0x00030047,0x00000aa2,0x00000000, + 0x00030047,0x00000aa3,0x00000000,0x00030047,0x00000aa5,0x00000000,0x00030047,0x00000aa7, + 0x00000000,0x00030047,0x00000aa9,0x00000000,0x00030047,0x00000aab,0x00000000,0x00030047, + 0x00000aac,0x00000000,0x00030047,0x00000aad,0x00000000,0x00030047,0x00000aaf,0x00000000, + 0x00030047,0x00000ab1,0x00000000,0x00030047,0x00000ab3,0x00000000,0x00030047,0x00000ab5, + 0x00000000,0x00030047,0x00000ab6,0x00000000,0x00030047,0x00000ab7,0x00000000,0x00030047, + 0x00000ab8,0x00000000,0x00030047,0x00000ab9,0x00000000,0x00030047,0x00000aba,0x00000000, + 0x00030047,0x00000abb,0x00000000,0x00030047,0x00000abc,0x00000000,0x00030047,0x00000abd, + 0x00000000,0x00030047,0x00000abe,0x00000000,0x00030047,0x00000abf,0x00000000,0x00030047, + 0x00000ac0,0x00000000,0x00030047,0x00000ac1,0x00000000,0x00030047,0x00000ac2,0x00000000, + 0x00030047,0x00000ac3,0x00000000,0x00030047,0x00000ac4,0x00000000,0x00030047,0x00000ac6, + 0x00000000,0x00030047,0x00000ac8,0x00000000,0x00030047,0x00000ac9,0x00000000,0x00030047, + 0x00000acb,0x00000000,0x00030047,0x00000acc,0x00000000,0x00030047,0x00000acd,0x00000000, + 0x00030047,0x00000ace,0x00000000,0x00030047,0x00000acf,0x00000000,0x00030047,0x00000ad2, + 0x00000000,0x00030047,0x00000ad4,0x00000000,0x00030047,0x00000ad5,0x00000000,0x00030047, + 0x00000ad8,0x00000000,0x00030047,0x00000ad9,0x00000000,0x00030047,0x00000adc,0x00000000, + 0x00030047,0x00000ade,0x00000000,0x00030047,0x00000adf,0x00000000,0x00030047,0x00000ae0, + 0x00000000,0x00030047,0x00000ae1,0x00000000,0x00030047,0x00000ae2,0x00000000,0x00030047, + 0x00000ae3,0x00000000,0x00030047,0x00000ae4,0x00000000,0x00030047,0x00000ae5,0x00000000, + 0x00030047,0x00000ae6,0x00000000,0x00030047,0x00000ae7,0x00000000,0x00030047,0x00000ae8, + 0x00000000,0x00030047,0x00000ae9,0x00000000,0x00030047,0x00000aea,0x00000000,0x00030047, + 0x00000aec,0x00000000,0x00030047,0x00000aee,0x00000000,0x00030047,0x00000aef,0x00000000, + 0x00030047,0x00000af0,0x00000000,0x00030047,0x00000af2,0x00000000,0x00030047,0x00000af4, + 0x00000000,0x00030047,0x00000af6,0x00000000,0x00030047,0x00000af8,0x00000000,0x00030047, + 0x00000af9,0x00000000,0x00030047,0x00000afa,0x00000000,0x00030047,0x00000afb,0x00000000, + 0x00030047,0x00000afc,0x00000000,0x00030047,0x00000afe,0x00000000,0x00030047,0x00000b00, + 0x00000000,0x00030047,0x00000b01,0x00000000,0x00030047,0x00000b02,0x00000000,0x00030047, + 0x00000b04,0x00000000,0x00030047,0x00000b06,0x00000000,0x00030047,0x00000b08,0x00000000, + 0x00030047,0x00000b0a,0x00000000,0x00030047,0x00000b0b,0x00000000,0x00030047,0x00000b0c, + 0x00000000,0x00030047,0x00000b0e,0x00000000,0x00030047,0x00000b10,0x00000000,0x00030047, + 0x00000b12,0x00000000,0x00030047,0x00000b13,0x00000000,0x00030047,0x00000b14,0x00000000, + 0x00030047,0x00000b16,0x00000000,0x00030047,0x00000b18,0x00000000,0x00030047,0x00000b1a, + 0x00000000,0x00030047,0x00000b1b,0x00000000,0x00030047,0x00000b1c,0x00000000,0x00030047, + 0x00000b1e,0x00000000,0x00030047,0x00000b1f,0x00000000,0x00030047,0x00000b22,0x00000000, + 0x00030047,0x00000b23,0x00000000,0x00030047,0x00000b24,0x00000000,0x00030047,0x00000b27, + 0x00000000,0x00030047,0x00000b29,0x00000000,0x00030047,0x00000b2a,0x00000000,0x00030047, + 0x00000b2b,0x00000000,0x00030047,0x00000b2c,0x00000000,0x00030047,0x00000b2e,0x00000000, + 0x00030047,0x00000b2f,0x00000000,0x00030047,0x00000b32,0x00000000,0x00030047,0x00000b33, + 0x00000000,0x00030047,0x00000b34,0x00000000,0x00030047,0x00000b37,0x00000000,0x00030047, + 0x00000b39,0x00000000,0x00030047,0x00000b3a,0x00000000,0x00030047,0x00000b3b,0x00000000, + 0x00030047,0x00000b3c,0x00000000,0x00030047,0x00000b3e,0x00000000,0x00030047,0x00000b40, + 0x00000000,0x00030047,0x00000b42,0x00000000,0x00030047,0x00000b43,0x00000000,0x00030047, + 0x00000b45,0x00000000,0x00030047,0x00000b46,0x00000000,0x00030047,0x00000b47,0x00000000, + 0x00030047,0x00000b49,0x00000000,0x00030047,0x00000b4b,0x00000000,0x00030047,0x00000b4d, + 0x00000000,0x00030047,0x00000b4f,0x00000000,0x00030047,0x00000b50,0x00000000,0x00030047, + 0x00000b52,0x00000000,0x00030047,0x00000b53,0x00000000,0x00030047,0x00000b54,0x00000000, + 0x00030047,0x00000b58,0x00000000,0x00030047,0x00000b59,0x00000000,0x00030047,0x00000b5b, + 0x00000000,0x00030047,0x00000b5c,0x00000000,0x00030047,0x00000b5d,0x00000000,0x00030047, + 0x00000b5f,0x00000000,0x00030047,0x00000b61,0x00000000,0x00030047,0x00000b62,0x00000000, + 0x00030047,0x00000b63,0x00000000,0x00030047,0x00000b64,0x00000000,0x00030047,0x00000b6e, + 0x00000000,0x00030047,0x00000b6f,0x00000000,0x00030047,0x00000b70,0x00000000,0x00030047, + 0x00000b71,0x00000000,0x00030047,0x00000b72,0x00000000,0x00030047,0x00000b73,0x00000000, + 0x00030047,0x00000b74,0x00000000,0x00030047,0x00000b75,0x00000000,0x00030047,0x00000b77, + 0x00000000,0x00030047,0x00000b79,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006, + 0x00040017,0x0000000c,0x00000006,0x00000002,0x00040020,0x0000000d,0x00000007,0x0000000c, + 0x00040015,0x00000012,0x00000020,0x00000000,0x00040020,0x00000013,0x00000007,0x00000012, + 0x00040017,0x00000024,0x00000006,0x00000003,0x00040017,0x0000002f,0x00000006,0x00000004, + 0x00040020,0x00000034,0x00000007,0x0000002f,0x00040018,0x00000035,0x0000000c,0x00000002, + 0x00040020,0x00000045,0x00000007,0x00000024,0x00040015,0x00000083,0x00000020,0x00000001, + 0x00040017,0x00000084,0x00000083,0x00000002,0x00040020,0x00000085,0x00000007,0x00000084, + 0x0004002b,0x00000012,0x000000ab,0x00000000,0x0004002b,0x00000012,0x000000ae,0x00000001, + 0x0004002b,0x00000012,0x000000c1,0x00000002,0x0004002b,0x00000012,0x000000d8,0x00000003, + 0x0004002b,0x00000006,0x000000e1,0x3f800000,0x0004002b,0x00000006,0x000000e2,0x00000000, + 0x00020014,0x000000f5,0x0004002b,0x00000006,0x00000123,0x3d897143,0x0004002b,0x00000006, + 0x00000127,0x3bbf4590,0x0004002b,0x00000006,0x0000012e,0x4253ee82,0x00030030,0x000000f5, + 0x00000139,0x0004002b,0x00000006,0x0000014d,0x3e99999a,0x0004002b,0x00000006,0x0000014e, + 0x3f170a3d,0x0004002b,0x00000006,0x0000014f,0x3de147ae,0x0004002b,0x00000006,0x00000169, + 0x388205ff,0x0004002b,0x00000006,0x000001cf,0x40000000,0x0004002b,0x00000006,0x000001d6, + 0x3f000000,0x00040017,0x000001dc,0x000000f5,0x00000003,0x00040020,0x00000258,0x00000007, + 0x00000083,0x0004002b,0x00000083,0x0000025a,0x00000000,0x0004002b,0x00000083,0x00000261, + 0x00000003,0x0004002b,0x00000006,0x00000273,0x3e800000,0x0004002b,0x00000006,0x00000278, + 0x41800000,0x0004002b,0x00000006,0x0000027d,0x41400000,0x0004002b,0x00000006,0x00000283, + 0x40400000,0x0004002b,0x00000083,0x0000028f,0x00000001,0x00030030,0x000000f5,0x000002aa, + 0x0004002b,0x00000006,0x000002fe,0x3a000000,0x0004002b,0x00000006,0x00000300,0xc2000000, + 0x0004002b,0x00000006,0x00000310,0x3a808081,0x00040017,0x00000313,0x000000f5,0x00000002, + 0x00040017,0x0000031d,0x00000012,0x00000002,0x00040020,0x0000031e,0x00000007,0x0000031d, + 0x0003001d,0x00000320,0x0000031d,0x0003001e,0x00000321,0x00000320,0x00040020,0x00000322, + 0x00000002,0x00000321,0x0004003b,0x00000322,0x00000323,0x00000002,0x00040020,0x00000325, + 0x00000002,0x0000031d,0x0004002b,0x00000012,0x0000032c,0x00000300,0x00030030,0x000000f5, + 0x00000333,0x0004002b,0x00000012,0x00000338,0x00000200,0x0004002b,0x00000006,0x00000342, + 0xbf800000,0x00030030,0x000000f5,0x0000034c,0x0004002b,0x00000012,0x00000352,0x00000010, + 0x00090019,0x00000358,0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000000,0x00040020,0x00000359,0x00000000,0x00000358,0x0004003b,0x00000359,0x0000035a, + 0x00000000,0x0005002c,0x00000084,0x0000035c,0x0000025a,0x0000025a,0x00030030,0x000000f5, + 0x00000365,0x0004002b,0x00000012,0x0000036a,0x00000400,0x00040020,0x00000370,0x00000007, + 0x00000035,0x0003001d,0x00000372,0x0000002f,0x0003001e,0x00000373,0x00000372,0x00040020, + 0x00000374,0x00000002,0x00000373,0x0004003b,0x00000374,0x00000375,0x00000002,0x0004002b, + 0x00000012,0x00000377,0x00000004,0x00040020,0x0000037b,0x00000002,0x0000002f,0x00040020, + 0x00000387,0x00000001,0x0000002f,0x0004003b,0x00000387,0x00000388,0x00000001,0x0004002b, + 0x00000012,0x000003a8,0x0000000f,0x00090019,0x000003f1,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000003f2,0x00000000,0x000003f1, + 0x0004003b,0x000003f2,0x000003f3,0x00000000,0x0002001a,0x000003f5,0x00040020,0x000003f6, + 0x00000000,0x000003f5,0x0004003b,0x000003f6,0x000003f7,0x00000000,0x0003001b,0x000003f9, + 0x000003f1,0x00030030,0x000000f5,0x00000404,0x0004002b,0x00000083,0x00000410,0x00000004, + 0x0004003b,0x00000359,0x0000041a,0x00000000,0x00040020,0x00000436,0x00000003,0x0000002f, + 0x0004003b,0x00000436,0x00000437,0x00000003,0x0004003b,0x00000436,0x00000439,0x00000003, + 0x00090019,0x00000441,0x00000012,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000021,0x00040020,0x00000442,0x00000000,0x00000441,0x0004003b,0x00000442,0x00000443, + 0x00000000,0x00040017,0x00000446,0x00000012,0x00000004,0x0004002b,0x00000012,0x0000044b, + 0x00000011,0x00040020,0x00000453,0x00000001,0x00000012,0x0004003b,0x00000453,0x00000454, + 0x00000001,0x0004002b,0x00000012,0x00000459,0x00010000,0x0004003b,0x000003f2,0x0000045c, + 0x00000000,0x0004003b,0x000003f6,0x0000045e,0x00000000,0x00040020,0x00000461,0x00000001, + 0x0000000c,0x0004003b,0x00000461,0x00000462,0x00000001,0x0004002b,0x00000006,0x0000046d, + 0x45000000,0x0004002b,0x00000012,0x00000480,0x0001ffff,0x0004001e,0x00000491,0x00000006, + 0x00000006,0x00040020,0x00000492,0x00000002,0x00000491,0x0004003b,0x00000492,0x00000493, + 0x00000002,0x00040020,0x0000049d,0x00000002,0x00000006,0x0006002c,0x00000024,0x000004be, + 0x000000e1,0x000000e1,0x000000e1,0x0006002c,0x00000024,0x000004bf,0x000001d6,0x000001d6, + 0x000001d6,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003b,0x00000007,0x00000b62,0x00000007,0x0004003b,0x00000007,0x00000b63,0x00000007, + 0x0004003b,0x00000007,0x00000b64,0x00000007,0x0004003b,0x00000045,0x00000b50,0x00000007, + 0x0004003b,0x0000000d,0x00000b51,0x00000007,0x0004003b,0x00000007,0x00000b52,0x00000007, + 0x0004003b,0x00000007,0x00000b53,0x00000007,0x0004003b,0x00000045,0x00000b54,0x00000007, + 0x0004003b,0x00000045,0x00000b46,0x00000007,0x0004003b,0x00000045,0x00000b47,0x00000007, + 0x0004003b,0x00000007,0x00000b43,0x00000007,0x0004003b,0x0000000d,0x00000b3b,0x00000007, + 0x0004003b,0x0000000d,0x00000b3c,0x00000007,0x0004003b,0x00000007,0x00000b34,0x00000007, + 0x0004003b,0x0000000d,0x00000b2b,0x00000007,0x0004003b,0x00000007,0x00000b2c,0x00000007, + 0x0004003b,0x00000007,0x00000b24,0x00000007,0x0004003b,0x0000000d,0x00000b1b,0x00000007, + 0x0004003b,0x00000007,0x00000b1c,0x00000007,0x0004003b,0x0000000d,0x00000b13,0x00000007, + 0x0004003b,0x0000000d,0x00000b14,0x00000007,0x0004003b,0x0000000d,0x00000b0b,0x00000007, + 0x0004003b,0x0000000d,0x00000b0c,0x00000007,0x0004003b,0x00000045,0x00000b01,0x00000007, + 0x0004003b,0x00000045,0x00000b02,0x00000007,0x0004003b,0x00000007,0x00000af9,0x00000007, + 0x0004003b,0x00000007,0x00000afa,0x00000007,0x0004003b,0x00000007,0x00000afb,0x00000007, + 0x0004003b,0x00000007,0x00000afc,0x00000007,0x0004003b,0x00000045,0x00000aef,0x00000007, + 0x0004003b,0x00000045,0x00000af0,0x00000007,0x0004003b,0x00000007,0x00000ae7,0x00000007, + 0x0004003b,0x00000007,0x00000ae8,0x00000007,0x0004003b,0x00000007,0x00000ae9,0x00000007, + 0x0004003b,0x00000007,0x00000aea,0x00000007,0x0004003b,0x00000007,0x00000ab6,0x00000007, + 0x0004003b,0x00000045,0x00000ab7,0x00000007,0x0004003b,0x00000045,0x00000ab8,0x00000007, + 0x0004003b,0x00000045,0x00000ab9,0x00000007,0x0004003b,0x0000000d,0x00000aba,0x00000007, + 0x0004003b,0x00000007,0x00000abb,0x00000007,0x0004003b,0x00000007,0x00000abc,0x00000007, + 0x0004003b,0x00000007,0x00000abd,0x00000007,0x0004003b,0x00000045,0x00000abe,0x00000007, + 0x0004003b,0x00000045,0x00000abf,0x00000007,0x0004003b,0x00000007,0x00000ac0,0x00000007, + 0x0004003b,0x00000007,0x00000ac1,0x00000007,0x0004003b,0x00000007,0x00000ac2,0x00000007, + 0x0004003b,0x00000007,0x00000ac3,0x00000007,0x0004003b,0x00000045,0x00000ac4,0x00000007, + 0x0004003b,0x00000045,0x00000aac,0x00000007,0x0004003b,0x00000045,0x00000aad,0x00000007, + 0x0004003b,0x00000045,0x00000aa2,0x00000007,0x0004003b,0x00000045,0x00000aa3,0x00000007, + 0x0004003b,0x00000007,0x00000a9f,0x00000007,0x0004003b,0x0000000d,0x00000a97,0x00000007, + 0x0004003b,0x0000000d,0x00000a98,0x00000007,0x0004003b,0x00000007,0x00000a90,0x00000007, + 0x0004003b,0x0000000d,0x00000a87,0x00000007,0x0004003b,0x00000007,0x00000a88,0x00000007, + 0x0004003b,0x00000007,0x00000a80,0x00000007,0x0004003b,0x0000000d,0x00000a77,0x00000007, + 0x0004003b,0x00000007,0x00000a78,0x00000007,0x0004003b,0x0000000d,0x00000a6f,0x00000007, + 0x0004003b,0x0000000d,0x00000a70,0x00000007,0x0004003b,0x0000000d,0x00000a67,0x00000007, + 0x0004003b,0x0000000d,0x00000a68,0x00000007,0x0004003b,0x00000045,0x00000a5d,0x00000007, + 0x0004003b,0x00000045,0x00000a5e,0x00000007,0x0004003b,0x00000007,0x00000a55,0x00000007, + 0x0004003b,0x00000007,0x00000a56,0x00000007,0x0004003b,0x00000007,0x00000a57,0x00000007, + 0x0004003b,0x00000007,0x00000a58,0x00000007,0x0004003b,0x00000045,0x00000a4b,0x00000007, + 0x0004003b,0x00000045,0x00000a4c,0x00000007,0x0004003b,0x00000007,0x00000a43,0x00000007, + 0x0004003b,0x00000007,0x00000a44,0x00000007,0x0004003b,0x00000007,0x00000a45,0x00000007, + 0x0004003b,0x00000007,0x00000a46,0x00000007,0x0004003b,0x00000007,0x00000a12,0x00000007, + 0x0004003b,0x00000045,0x00000a13,0x00000007,0x0004003b,0x00000045,0x00000a14,0x00000007, + 0x0004003b,0x00000045,0x00000a15,0x00000007,0x0004003b,0x0000000d,0x00000a16,0x00000007, + 0x0004003b,0x00000007,0x00000a17,0x00000007,0x0004003b,0x00000007,0x00000a18,0x00000007, + 0x0004003b,0x00000007,0x00000a19,0x00000007,0x0004003b,0x00000045,0x00000a1a,0x00000007, + 0x0004003b,0x00000045,0x00000a1b,0x00000007,0x0004003b,0x00000007,0x00000a1c,0x00000007, + 0x0004003b,0x00000007,0x00000a1d,0x00000007,0x0004003b,0x00000007,0x00000a1e,0x00000007, + 0x0004003b,0x00000007,0x00000a1f,0x00000007,0x0004003b,0x00000045,0x00000a20,0x00000007, + 0x0004003b,0x00000045,0x00000a08,0x00000007,0x0004003b,0x00000045,0x00000a09,0x00000007, + 0x0004003b,0x00000045,0x000009fe,0x00000007,0x0004003b,0x00000045,0x000009ff,0x00000007, + 0x0004003b,0x00000007,0x000009fb,0x00000007,0x0004003b,0x0000000d,0x000009f3,0x00000007, + 0x0004003b,0x0000000d,0x000009f4,0x00000007,0x0004003b,0x00000007,0x000009ec,0x00000007, + 0x0004003b,0x0000000d,0x000009e3,0x00000007,0x0004003b,0x00000007,0x000009e4,0x00000007, + 0x0004003b,0x00000007,0x000009dc,0x00000007,0x0004003b,0x0000000d,0x000009d3,0x00000007, + 0x0004003b,0x00000007,0x000009d4,0x00000007,0x0004003b,0x0000000d,0x000009cb,0x00000007, + 0x0004003b,0x0000000d,0x000009cc,0x00000007,0x0004003b,0x0000000d,0x000009c3,0x00000007, + 0x0004003b,0x0000000d,0x000009c4,0x00000007,0x0004003b,0x00000045,0x000009b9,0x00000007, + 0x0004003b,0x00000045,0x000009ba,0x00000007,0x0004003b,0x00000007,0x000009b1,0x00000007, + 0x0004003b,0x00000007,0x000009b2,0x00000007,0x0004003b,0x00000007,0x000009b3,0x00000007, + 0x0004003b,0x00000007,0x000009b4,0x00000007,0x0004003b,0x00000045,0x000009a7,0x00000007, + 0x0004003b,0x00000045,0x000009a8,0x00000007,0x0004003b,0x00000007,0x0000099f,0x00000007, + 0x0004003b,0x00000007,0x000009a0,0x00000007,0x0004003b,0x00000007,0x000009a1,0x00000007, + 0x0004003b,0x00000007,0x000009a2,0x00000007,0x0004003b,0x00000007,0x0000096e,0x00000007, + 0x0004003b,0x00000045,0x0000096f,0x00000007,0x0004003b,0x00000045,0x00000970,0x00000007, + 0x0004003b,0x00000045,0x00000971,0x00000007,0x0004003b,0x0000000d,0x00000972,0x00000007, + 0x0004003b,0x00000007,0x00000973,0x00000007,0x0004003b,0x00000007,0x00000974,0x00000007, + 0x0004003b,0x00000007,0x00000975,0x00000007,0x0004003b,0x00000045,0x00000976,0x00000007, + 0x0004003b,0x00000045,0x00000977,0x00000007,0x0004003b,0x00000007,0x00000978,0x00000007, + 0x0004003b,0x00000007,0x00000979,0x00000007,0x0004003b,0x00000007,0x0000097a,0x00000007, + 0x0004003b,0x00000007,0x0000097b,0x00000007,0x0004003b,0x00000045,0x0000097c,0x00000007, + 0x0004003b,0x00000007,0x00000967,0x00000007,0x0004003b,0x0000000d,0x0000095e,0x00000007, + 0x0004003b,0x00000007,0x0000095f,0x00000007,0x0004003b,0x00000007,0x00000957,0x00000007, + 0x0004003b,0x0000000d,0x0000094e,0x00000007,0x0004003b,0x00000007,0x0000094f,0x00000007, + 0x0004003b,0x00000007,0x00000947,0x00000007,0x0004003b,0x0000000d,0x0000093e,0x00000007, + 0x0004003b,0x00000007,0x0000093f,0x00000007,0x0004003b,0x00000007,0x00000937,0x00000007, + 0x0004003b,0x0000000d,0x0000092e,0x00000007,0x0004003b,0x00000007,0x0000092f,0x00000007, + 0x0004003b,0x00000007,0x0000090e,0x00000007,0x0004003b,0x00000045,0x0000090f,0x00000007, + 0x0004003b,0x00000045,0x00000910,0x00000007,0x0004003b,0x00000045,0x00000911,0x00000007, + 0x0004003b,0x00000007,0x00000912,0x00000007,0x0004003b,0x00000045,0x00000913,0x00000007, + 0x0004003b,0x00000007,0x00000914,0x00000007,0x0004003b,0x00000045,0x00000915,0x00000007, + 0x0004003b,0x00000045,0x00000916,0x00000007,0x0004003b,0x00000045,0x00000917,0x00000007, + 0x0004003b,0x00000045,0x00000904,0x00000007,0x0004003b,0x00000045,0x00000905,0x00000007, + 0x0004003b,0x00000045,0x000008fa,0x00000007,0x0004003b,0x00000045,0x000008fb,0x00000007, + 0x0004003b,0x00000007,0x000008f7,0x00000007,0x0004003b,0x0000000d,0x000008ef,0x00000007, + 0x0004003b,0x0000000d,0x000008f0,0x00000007,0x0004003b,0x00000007,0x000008e8,0x00000007, + 0x0004003b,0x0000000d,0x000008df,0x00000007,0x0004003b,0x00000007,0x000008e0,0x00000007, + 0x0004003b,0x00000007,0x000008d8,0x00000007,0x0004003b,0x0000000d,0x000008cf,0x00000007, + 0x0004003b,0x00000007,0x000008d0,0x00000007,0x0004003b,0x0000000d,0x000008c7,0x00000007, + 0x0004003b,0x0000000d,0x000008c8,0x00000007,0x0004003b,0x0000000d,0x000008bf,0x00000007, + 0x0004003b,0x0000000d,0x000008c0,0x00000007,0x0004003b,0x00000045,0x000008b5,0x00000007, + 0x0004003b,0x00000045,0x000008b6,0x00000007,0x0004003b,0x00000007,0x000008ad,0x00000007, + 0x0004003b,0x00000007,0x000008ae,0x00000007,0x0004003b,0x00000007,0x000008af,0x00000007, + 0x0004003b,0x00000007,0x000008b0,0x00000007,0x0004003b,0x00000045,0x000008a3,0x00000007, + 0x0004003b,0x00000045,0x000008a4,0x00000007,0x0004003b,0x00000007,0x0000089b,0x00000007, + 0x0004003b,0x00000007,0x0000089c,0x00000007,0x0004003b,0x00000007,0x0000089d,0x00000007, + 0x0004003b,0x00000007,0x0000089e,0x00000007,0x0004003b,0x00000007,0x0000086a,0x00000007, + 0x0004003b,0x00000045,0x0000086b,0x00000007,0x0004003b,0x00000045,0x0000086c,0x00000007, + 0x0004003b,0x00000045,0x0000086d,0x00000007,0x0004003b,0x0000000d,0x0000086e,0x00000007, + 0x0004003b,0x00000007,0x0000086f,0x00000007,0x0004003b,0x00000007,0x00000870,0x00000007, + 0x0004003b,0x00000007,0x00000871,0x00000007,0x0004003b,0x00000045,0x00000872,0x00000007, + 0x0004003b,0x00000045,0x00000873,0x00000007,0x0004003b,0x00000007,0x00000874,0x00000007, + 0x0004003b,0x00000007,0x00000875,0x00000007,0x0004003b,0x00000007,0x00000876,0x00000007, + 0x0004003b,0x00000007,0x00000877,0x00000007,0x0004003b,0x00000045,0x00000878,0x00000007, + 0x0004003b,0x00000007,0x00000863,0x00000007,0x0004003b,0x0000000d,0x0000085a,0x00000007, + 0x0004003b,0x00000007,0x0000085b,0x00000007,0x0004003b,0x00000007,0x00000853,0x00000007, + 0x0004003b,0x0000000d,0x0000084a,0x00000007,0x0004003b,0x00000007,0x0000084b,0x00000007, + 0x0004003b,0x00000007,0x00000843,0x00000007,0x0004003b,0x0000000d,0x0000083a,0x00000007, + 0x0004003b,0x00000007,0x0000083b,0x00000007,0x0004003b,0x00000007,0x00000833,0x00000007, + 0x0004003b,0x0000000d,0x0000082a,0x00000007,0x0004003b,0x00000007,0x0000082b,0x00000007, + 0x0004003b,0x00000007,0x0000080a,0x00000007,0x0004003b,0x00000045,0x0000080b,0x00000007, + 0x0004003b,0x00000045,0x0000080c,0x00000007,0x0004003b,0x00000045,0x0000080d,0x00000007, + 0x0004003b,0x00000007,0x0000080e,0x00000007,0x0004003b,0x00000045,0x0000080f,0x00000007, + 0x0004003b,0x00000007,0x00000810,0x00000007,0x0004003b,0x00000045,0x00000811,0x00000007, + 0x0004003b,0x00000045,0x00000812,0x00000007,0x0004003b,0x00000045,0x00000813,0x00000007, + 0x0004003b,0x00000045,0x00000800,0x00000007,0x0004003b,0x00000045,0x00000801,0x00000007, + 0x0004003b,0x00000045,0x000007f6,0x00000007,0x0004003b,0x00000045,0x000007f7,0x00000007, + 0x0004003b,0x00000045,0x000007ec,0x00000007,0x0004003b,0x00000045,0x000007ed,0x00000007, + 0x0004003b,0x00000045,0x000007e2,0x00000007,0x0004003b,0x00000045,0x000007e3,0x00000007, + 0x0004003b,0x00000045,0x000007d8,0x00000007,0x0004003b,0x00000045,0x000007d9,0x00000007, + 0x0004003b,0x00000045,0x000007ce,0x00000007,0x0004003b,0x00000045,0x000007cf,0x00000007, + 0x0004003b,0x00000045,0x000007c4,0x00000007,0x0004003b,0x00000045,0x000007c5,0x00000007, + 0x0004003b,0x00000045,0x000007ba,0x00000007,0x0004003b,0x00000045,0x000007bb,0x00000007, + 0x0004003b,0x00000045,0x000007b0,0x00000007,0x0004003b,0x00000045,0x000007b1,0x00000007, + 0x0004003b,0x00000045,0x000007a6,0x00000007,0x0004003b,0x00000045,0x000007a7,0x00000007, + 0x0004003b,0x00000045,0x0000079c,0x00000007,0x0004003b,0x00000045,0x0000079d,0x00000007, + 0x0004003b,0x00000045,0x00000792,0x00000007,0x0004003b,0x00000045,0x00000793,0x00000007, + 0x0004003b,0x00000045,0x00000788,0x00000007,0x0004003b,0x00000045,0x00000789,0x00000007, + 0x0004003b,0x00000045,0x0000077e,0x00000007,0x0004003b,0x00000045,0x0000077f,0x00000007, + 0x0004003b,0x00000007,0x0000076e,0x00000007,0x0004003b,0x00000045,0x0000076f,0x00000007, + 0x0004003b,0x00000045,0x0000064d,0x00000007,0x0004003b,0x00000034,0x0000064e,0x00000007, + 0x0004003b,0x00000045,0x0000064f,0x00000007,0x0004003b,0x00000045,0x00000650,0x00000007, + 0x0004003b,0x00000007,0x00000651,0x00000007,0x0004003b,0x00000007,0x00000652,0x00000007, + 0x0004003b,0x00000045,0x00000653,0x00000007,0x0004003b,0x00000007,0x00000654,0x00000007, + 0x0004003b,0x00000007,0x00000655,0x00000007,0x0004003b,0x00000007,0x00000656,0x00000007, + 0x0004003b,0x00000007,0x00000657,0x00000007,0x0004003b,0x00000007,0x00000658,0x00000007, + 0x0004003b,0x00000007,0x00000659,0x00000007,0x0004003b,0x00000007,0x0000065a,0x00000007, + 0x0004003b,0x00000045,0x0000065b,0x00000007,0x0004003b,0x00000007,0x0000065c,0x00000007, + 0x0004003b,0x00000007,0x0000065d,0x00000007,0x0004003b,0x00000045,0x0000065e,0x00000007, + 0x0004003b,0x00000007,0x0000065f,0x00000007,0x0004003b,0x00000258,0x00000660,0x00000007, + 0x0004003b,0x00000007,0x00000661,0x00000007,0x0004003b,0x00000007,0x00000662,0x00000007, + 0x0004003b,0x00000045,0x00000663,0x00000007,0x0004003b,0x00000045,0x00000664,0x00000007, + 0x0004003b,0x00000045,0x00000665,0x00000007,0x0004003b,0x00000007,0x00000666,0x00000007, + 0x0004003b,0x00000007,0x00000667,0x00000007,0x0004003b,0x00000045,0x00000668,0x00000007, + 0x0004003b,0x00000045,0x00000669,0x00000007,0x0004003b,0x00000045,0x0000066a,0x00000007, + 0x0004003b,0x00000007,0x0000066b,0x00000007,0x0004003b,0x00000007,0x0000066c,0x00000007, + 0x0004003b,0x00000045,0x0000066d,0x00000007,0x0004003b,0x00000045,0x0000066e,0x00000007, + 0x0004003b,0x00000007,0x0000066f,0x00000007,0x0004003b,0x00000007,0x00000670,0x00000007, + 0x0004003b,0x00000045,0x00000671,0x00000007,0x0004003b,0x00000045,0x00000672,0x00000007, + 0x0004003b,0x00000045,0x00000673,0x00000007,0x0004003b,0x00000045,0x0000063c,0x00000007, + 0x0004003b,0x00000045,0x0000063d,0x00000007,0x0004003b,0x00000034,0x0000063e,0x00000007, + 0x0004003b,0x00000013,0x0000063f,0x00000007,0x0004003b,0x00000007,0x00000640,0x00000007, + 0x0004003b,0x00000045,0x00000641,0x00000007,0x0004003b,0x00000013,0x00000637,0x00000007, + 0x0004003b,0x00000013,0x00000638,0x00000007,0x0004003b,0x00000370,0x0000062a,0x00000007, + 0x0004003b,0x00000034,0x0000061e,0x00000007,0x0004003b,0x00000034,0x0000061f,0x00000007, + 0x0004003b,0x0000000d,0x00000619,0x00000007,0x0004003b,0x0000000d,0x0000061a,0x00000007, + 0x0004003b,0x00000370,0x0000060c,0x00000007,0x0004003b,0x0000000d,0x00000604,0x00000007, + 0x0004003b,0x0000000d,0x00000605,0x00000007,0x0004003b,0x00000007,0x000005f1,0x00000007, + 0x0004003b,0x00000007,0x000005ee,0x00000007,0x0004003b,0x00000007,0x000005eb,0x00000007, + 0x0004003b,0x0000031e,0x000004f8,0x00000007,0x0004003b,0x00000007,0x000004f9,0x00000007, + 0x0004003b,0x00000007,0x000004fa,0x00000007,0x0004003b,0x00000007,0x000004fb,0x00000007, + 0x0004003b,0x00000013,0x000004fc,0x00000007,0x0004003b,0x00000013,0x000004fd,0x00000007, + 0x0004003b,0x00000034,0x000004fe,0x00000007,0x0004003b,0x00000007,0x000004ff,0x00000007, + 0x0004003b,0x00000370,0x00000500,0x00000007,0x0004003b,0x00000034,0x00000501,0x00000007, + 0x0004003b,0x00000034,0x00000502,0x00000007,0x0004003b,0x0000000d,0x00000503,0x00000007, + 0x0004003b,0x0000000d,0x00000504,0x00000007,0x0004003b,0x0000000d,0x00000505,0x00000007, + 0x0004003b,0x00000007,0x00000506,0x00000007,0x0004003b,0x00000013,0x00000507,0x00000007, + 0x0004003b,0x00000007,0x00000508,0x00000007,0x0004003b,0x00000370,0x00000509,0x00000007, + 0x0004003b,0x00000034,0x0000050a,0x00000007,0x0004003b,0x00000034,0x0000050b,0x00000007, + 0x0004003b,0x0000000d,0x0000050c,0x00000007,0x0004003b,0x00000007,0x0000050d,0x00000007, + 0x0004003b,0x00000007,0x0000050e,0x00000007,0x0004003b,0x00000007,0x0000050f,0x00000007, + 0x0004003b,0x00000007,0x00000510,0x00000007,0x0004003b,0x00000013,0x00000511,0x00000007, + 0x0004003b,0x00000013,0x00000512,0x00000007,0x0004003b,0x00000034,0x00000513,0x00000007, + 0x0004003b,0x00000045,0x00000514,0x00000007,0x0004003b,0x00000034,0x00000515,0x00000007, + 0x0004003b,0x00000013,0x00000516,0x00000007,0x0004003b,0x00000007,0x000004f3,0x00000007, + 0x0004003b,0x00000007,0x000004f4,0x00000007,0x0004003b,0x00000007,0x000004eb,0x00000007, + 0x0004003b,0x00000007,0x000004ec,0x00000007,0x0004003b,0x00000034,0x000004df,0x00000007, + 0x0004003b,0x00000034,0x000004e0,0x00000007,0x0004003b,0x00000034,0x000004d3,0x00000007, + 0x0004003b,0x00000034,0x000004d4,0x00000007,0x0004003b,0x00000007,0x000004d0,0x00000007, + 0x0004003b,0x00000007,0x000004cd,0x00000007,0x0004003b,0x00000013,0x000004c8,0x00000007, + 0x0004003b,0x00000013,0x000004c9,0x00000007,0x0004003b,0x00000013,0x000004c5,0x00000007, + 0x0004003b,0x00000013,0x000004c0,0x00000007,0x0004003b,0x00000013,0x000004c1,0x00000007, + 0x0004003b,0x00000085,0x0000043b,0x00000007,0x0004003b,0x00000013,0x00000440,0x00000007, + 0x0004003b,0x00000013,0x00000449,0x00000007,0x0004003b,0x00000013,0x0000044d,0x00000007, + 0x0004003b,0x00000013,0x0000044f,0x00000007,0x0004003b,0x00000013,0x00000452,0x00000007, + 0x0004003b,0x00000013,0x00000455,0x00000007,0x0004003b,0x00000007,0x0000045b,0x00000007, + 0x0004003b,0x00000007,0x00000466,0x00000007,0x0004003b,0x00000007,0x00000468,0x00000007, + 0x0004003b,0x00000258,0x0000046b,0x00000007,0x0004003b,0x00000034,0x00000478,0x00000007, + 0x0004003b,0x00000007,0x00000479,0x00000007,0x0004003b,0x00000034,0x0000047b,0x00000007, + 0x0004003b,0x00000007,0x0000047c,0x00000007,0x0004003b,0x00000007,0x0000047e,0x00000007, + 0x0004003b,0x00000013,0x00000482,0x00000007,0x0004003b,0x00000013,0x00000484,0x00000007, + 0x0004003b,0x00000007,0x00000486,0x00000007,0x0004003b,0x00000034,0x00000488,0x00000007, + 0x0004003b,0x00000034,0x00000489,0x00000007,0x0004003b,0x00000045,0x00000496,0x00000007, + 0x0004003b,0x0000000d,0x00000499,0x00000007,0x0004003b,0x00000007,0x0000049c,0x00000007, + 0x0004003b,0x00000007,0x000004a0,0x00000007,0x0004003b,0x00000034,0x000004aa,0x00000007, + 0x0004003b,0x00000034,0x000004af,0x00000007,0x0004003d,0x0000002f,0x0000043c,0x00000388, + 0x0007004f,0x0000000c,0x0000043d,0x0000043c,0x0000043c,0x00000000,0x00000001,0x0006000c, + 0x0000000c,0x0000043e,0x00000001,0x00000008,0x0000043d,0x0004006e,0x00000084,0x0000043f, + 0x0000043e,0x0003003e,0x0000043b,0x0000043f,0x0004003d,0x00000441,0x00000444,0x00000443, + 0x0004003d,0x00000084,0x00000445,0x0000043b,0x00050062,0x00000446,0x00000447,0x00000444, + 0x00000445,0x00050051,0x00000012,0x00000448,0x00000447,0x00000000,0x0003003e,0x00000440, + 0x00000448,0x0004003d,0x00000012,0x0000044a,0x00000440,0x000500c2,0x00000012,0x0000044c, + 0x0000044a,0x0000044b,0x0003003e,0x0000044d,0x0000044c,0x0004003d,0x00000012,0x000004c3, + 0x0000044d,0x0003003e,0x000004c0,0x000004c3,0x0004003d,0x00000012,0x000004c4,0x000004c0, + 0x0003003e,0x000004c1,0x000004c4,0x0004003d,0x00000012,0x0000044e,0x000004c1,0x0003003e, + 0x00000449,0x0000044e,0x0004003d,0x00000012,0x00000450,0x00000449,0x0003003e,0x0000044f, + 0x00000450,0x0004003d,0x00000012,0x000004c7,0x0000044f,0x0003003e,0x000004c5,0x000004c7, + 0x0004003d,0x00000012,0x00000451,0x000004c5,0x0003003e,0x00000449,0x00000451,0x0004003d, + 0x00000012,0x00000456,0x00000454,0x0003003e,0x00000455,0x00000456,0x0004003d,0x00000012, + 0x000004cb,0x00000455,0x0003003e,0x000004c8,0x000004cb,0x0004003d,0x00000012,0x000004cc, + 0x000004c8,0x0003003e,0x000004c9,0x000004cc,0x0004003d,0x00000012,0x00000457,0x000004c9, + 0x000500c4,0x00000012,0x00000458,0x00000457,0x0000044b,0x00050080,0x00000012,0x0000045a, + 0x00000458,0x00000459,0x0003003e,0x00000452,0x0000045a,0x0004003d,0x000003f1,0x0000045d, + 0x0000045c,0x0004003d,0x000003f5,0x0000045f,0x0000045e,0x00050056,0x000003f9,0x00000460, + 0x0000045d,0x0000045f,0x0004003d,0x0000000c,0x00000463,0x00000462,0x00070058,0x0000002f, + 0x00000464,0x00000460,0x00000463,0x00000002,0x000000e2,0x00050051,0x00000006,0x00000465, + 0x00000464,0x00000000,0x0003003e,0x00000466,0x000000e2,0x0004003d,0x00000006,0x000004cf, + 0x00000466,0x0003003e,0x000004cd,0x000004cf,0x0004003d,0x00000006,0x00000467,0x000004cd, + 0x0003003e,0x00000468,0x000000e1,0x0004003d,0x00000006,0x000004d2,0x00000468,0x0003003e, + 0x000004d0,0x000004d2,0x0004003d,0x00000006,0x00000469,0x000004d0,0x0008000c,0x00000006, + 0x0000046a,0x00000001,0x0000002b,0x00000465,0x00000467,0x00000469,0x0003003e,0x0000045b, + 0x0000046a,0x0004003d,0x00000006,0x0000046c,0x0000045b,0x00050085,0x00000006,0x0000046e, + 0x0000046c,0x0000046d,0x0006000c,0x00000006,0x0000046f,0x00000001,0x00000001,0x0000046e, + 0x0004006e,0x00000083,0x00000470,0x0000046f,0x0003003e,0x0000046b,0x00000470,0x0004003d, + 0x00000441,0x00000471,0x00000443,0x0004003d,0x00000084,0x00000472,0x0000043b,0x0004003d, + 0x00000012,0x00000473,0x00000452,0x0004003d,0x00000083,0x00000474,0x0000046b,0x0004007c, + 0x00000012,0x00000475,0x00000474,0x00050080,0x00000012,0x00000476,0x00000473,0x00000475, + 0x00070050,0x00000446,0x00000477,0x00000476,0x00000476,0x00000476,0x00000476,0x00040063, + 0x00000471,0x00000472,0x00000477,0x0003003e,0x00000479,0x000000e2,0x0004003d,0x00000006, + 0x000004d6,0x00000479,0x00050041,0x00000007,0x000004d7,0x000004d3,0x000000ab,0x0003003e, + 0x000004d7,0x000004d6,0x0004003d,0x00000006,0x000004d8,0x00000479,0x00050041,0x00000007, + 0x000004d9,0x000004d3,0x000000ae,0x0003003e,0x000004d9,0x000004d8,0x0004003d,0x00000006, + 0x000004da,0x00000479,0x00050041,0x00000007,0x000004db,0x000004d3,0x000000c1,0x0003003e, + 0x000004db,0x000004da,0x0004003d,0x00000006,0x000004dc,0x00000479,0x00050041,0x00000007, + 0x000004dd,0x000004d3,0x000000d8,0x0003003e,0x000004dd,0x000004dc,0x0004003d,0x0000002f, + 0x000004de,0x000004d3,0x0003003e,0x000004d4,0x000004de,0x0004003d,0x0000002f,0x0000047a, + 0x000004d4,0x0003003e,0x00000478,0x0000047a,0x0003003e,0x0000047c,0x000000e2,0x0004003d, + 0x00000006,0x000004e2,0x0000047c,0x00050041,0x00000007,0x000004e3,0x000004df,0x000000ab, + 0x0003003e,0x000004e3,0x000004e2,0x0004003d,0x00000006,0x000004e4,0x0000047c,0x00050041, + 0x00000007,0x000004e5,0x000004df,0x000000ae,0x0003003e,0x000004e5,0x000004e4,0x0004003d, + 0x00000006,0x000004e6,0x0000047c,0x00050041,0x00000007,0x000004e7,0x000004df,0x000000c1, + 0x0003003e,0x000004e7,0x000004e6,0x0004003d,0x00000006,0x000004e8,0x0000047c,0x00050041, + 0x00000007,0x000004e9,0x000004df,0x000000d8,0x0003003e,0x000004e9,0x000004e8,0x0004003d, + 0x0000002f,0x000004ea,0x000004df,0x0003003e,0x000004e0,0x000004ea,0x0004003d,0x0000002f, + 0x0000047d,0x000004e0,0x0003003e,0x0000047b,0x0000047d,0x0004003d,0x00000012,0x0000047f, + 0x00000440,0x000500c7,0x00000012,0x00000481,0x0000047f,0x00000480,0x0003003e,0x00000482, + 0x00000481,0x0004003d,0x00000012,0x000004ee,0x00000482,0x00040070,0x00000006,0x000004ef, + 0x000004ee,0x00050085,0x00000006,0x000004f0,0x000004ef,0x000002fe,0x00050081,0x00000006, + 0x000004f1,0x000004f0,0x00000300,0x0003003e,0x000004eb,0x000004f1,0x0004003d,0x00000006, + 0x000004f6,0x000004eb,0x0003003e,0x000004f3,0x000004f6,0x0004003d,0x00000006,0x000004f7, + 0x000004f3,0x0003003e,0x000004f4,0x000004f7,0x0004003d,0x00000006,0x000004f2,0x000004f4, + 0x0003003e,0x000004ec,0x000004f2,0x0004003d,0x00000006,0x00000483,0x000004ec,0x0003003e, + 0x0000047e,0x00000483,0x0004003d,0x00000012,0x00000485,0x00000449,0x0003003e,0x00000484, + 0x00000485,0x0004003d,0x00000006,0x00000487,0x0000047e,0x0003003e,0x00000486,0x00000487, + 0x0004003d,0x0000002f,0x0000048a,0x0000047b,0x0003003e,0x00000489,0x0000048a,0x0004003d, + 0x00000012,0x00000518,0x00000484,0x00060041,0x00000325,0x00000519,0x00000323,0x0000025a, + 0x00000518,0x0004003d,0x0000031d,0x0000051a,0x00000519,0x0003003e,0x000004f8,0x0000051a, + 0x0004003d,0x00000006,0x0000051b,0x00000486,0x0003003e,0x000004f9,0x0000051b,0x00050041, + 0x00000013,0x0000051c,0x000004f8,0x000000ab,0x0004003d,0x00000012,0x0000051d,0x0000051c, + 0x000500c7,0x00000012,0x0000051e,0x0000051d,0x0000032c,0x000500ab,0x000000f5,0x0000051f, + 0x0000051e,0x000000ab,0x000300f7,0x00000533,0x00000000,0x000400fa,0x0000051f,0x00000520, + 0x00000533,0x000200f8,0x00000520,0x0004003d,0x00000006,0x00000521,0x000004f9,0x0006000c, + 0x00000006,0x00000522,0x00000001,0x00000004,0x00000521,0x0003003e,0x000004f9,0x00000522, + 0x000300f7,0x00000528,0x00000000,0x000400fa,0x00000333,0x00000523,0x00000528,0x000200f8, + 0x00000523,0x0004003d,0x00000012,0x00000525,0x0000051c,0x000500c7,0x00000012,0x00000526, + 0x00000525,0x00000338,0x000500ab,0x000000f5,0x00000527,0x00000526,0x000000ab,0x000200f9, + 0x00000528,0x000200f8,0x00000528,0x000700f5,0x000000f5,0x00000529,0x00000333,0x00000520, + 0x00000527,0x00000523,0x000300f7,0x00000532,0x00000000,0x000400fa,0x00000529,0x0000052a, + 0x00000532,0x000200f8,0x0000052a,0x0004003d,0x00000006,0x0000052b,0x000004f9,0x00050085, + 0x00000006,0x0000052c,0x0000052b,0x000001d6,0x0006000c,0x00000006,0x0000052d,0x00000001, + 0x0000000a,0x0000052c,0x00050085,0x00000006,0x0000052e,0x0000052d,0x000001cf,0x00050081, + 0x00000006,0x0000052f,0x0000052e,0x00000342,0x0006000c,0x00000006,0x00000530,0x00000001, + 0x00000004,0x0000052f,0x00050083,0x00000006,0x00000531,0x000000e1,0x00000530,0x0003003e, + 0x000004f9,0x00000531,0x000200f9,0x00000532,0x000200f8,0x00000532,0x000200f9,0x00000533, + 0x000200f8,0x00000533,0x0004003d,0x00000006,0x00000534,0x000004f9,0x0003003e,0x000004fa, + 0x000000e2,0x0004003d,0x00000006,0x000005ed,0x000004fa,0x0003003e,0x000005eb,0x000005ed, + 0x0004003d,0x00000006,0x00000535,0x000005eb,0x0003003e,0x000004fb,0x000000e1,0x0004003d, + 0x00000006,0x000005f0,0x000004fb,0x0003003e,0x000005ee,0x000005f0,0x0004003d,0x00000006, + 0x00000536,0x000005ee,0x0008000c,0x00000006,0x00000537,0x00000001,0x0000002b,0x00000534, + 0x00000535,0x00000536,0x0003003e,0x000004f9,0x00000537,0x000300f7,0x00000546,0x00000000, + 0x000400fa,0x0000034c,0x00000538,0x00000546,0x000200f8,0x00000538,0x0004003d,0x00000012, + 0x0000053a,0x0000051c,0x000500c2,0x00000012,0x0000053b,0x0000053a,0x00000352,0x0003003e, + 0x000004fc,0x0000053b,0x0004003d,0x00000012,0x0000053c,0x000004fc,0x000500ab,0x000000f5, + 0x0000053d,0x0000053c,0x000000ab,0x000300f7,0x00000545,0x00000000,0x000400fa,0x0000053d, + 0x0000053e,0x00000545,0x000200f8,0x0000053e,0x0004003d,0x00000358,0x0000053f,0x0000035a, + 0x00050062,0x0000002f,0x00000540,0x0000053f,0x0000035c,0x0004003d,0x00000012,0x00000541, + 0x000004fc,0x0003003e,0x000004fd,0x00000541,0x0003003e,0x000004fe,0x00000540,0x0004003d, + 0x00000006,0x00000542,0x000004f9,0x0003003e,0x000004ff,0x00000542,0x0004003d,0x0000002f, + 0x000005f3,0x000004fe,0x0007004f,0x0000000c,0x000005f4,0x000005f3,0x000005f3,0x00000000, + 0x00000001,0x0004003d,0x00000012,0x000005f5,0x000004fd,0x0006000c,0x0000002f,0x000005f6, + 0x00000001,0x00000040,0x000005f5,0x0007004f,0x0000000c,0x000005f7,0x000005f6,0x000005f6, + 0x00000000,0x00000001,0x00050083,0x0000000c,0x000005f8,0x000005f4,0x000005f7,0x0006000c, + 0x0000000c,0x000005f9,0x00000001,0x00000004,0x000005f8,0x0003003e,0x000005f1,0x00000310, + 0x0004003d,0x00000006,0x00000607,0x000005f1,0x00050041,0x00000007,0x00000608,0x00000604, + 0x000000ab,0x0003003e,0x00000608,0x00000607,0x0004003d,0x00000006,0x00000609,0x000005f1, + 0x00050041,0x00000007,0x0000060a,0x00000604,0x000000ae,0x0003003e,0x0000060a,0x00000609, + 0x0004003d,0x0000000c,0x0000060b,0x00000604,0x0003003e,0x00000605,0x0000060b,0x0004003d, + 0x0000000c,0x000005fa,0x00000605,0x000500b8,0x00000313,0x000005fb,0x000005f9,0x000005fa, + 0x0004009b,0x000000f5,0x000005fc,0x000005fb,0x000300f7,0x00000603,0x00000000,0x000400fa, + 0x000005fc,0x000005fd,0x00000602,0x000200f8,0x000005fd,0x0004003d,0x00000006,0x000005fe, + 0x000004ff,0x00050041,0x00000007,0x000005ff,0x000004fe,0x000000c1,0x0004003d,0x00000006, + 0x00000600,0x000005ff,0x0007000c,0x00000006,0x00000601,0x00000001,0x00000025,0x000005fe, + 0x00000600,0x0003003e,0x000004ff,0x00000601,0x000200f9,0x00000603,0x000200f8,0x00000602, + 0x0003003e,0x000004ff,0x000000e2,0x000200f9,0x00000603,0x000200f8,0x00000603,0x0004003d, + 0x00000006,0x00000544,0x000004ff,0x0003003e,0x000004f9,0x00000544,0x000200f9,0x00000545, + 0x000200f8,0x00000545,0x000200f9,0x00000546,0x000200f8,0x00000546,0x000300f7,0x0000054c, + 0x00000000,0x000400fa,0x00000365,0x00000547,0x0000054c,0x000200f8,0x00000547,0x0004003d, + 0x00000012,0x00000549,0x0000051c,0x000500c7,0x00000012,0x0000054a,0x00000549,0x0000036a, + 0x000500ab,0x000000f5,0x0000054b,0x0000054a,0x000000ab,0x000200f9,0x0000054c,0x000200f8, + 0x0000054c,0x000700f5,0x000000f5,0x0000054d,0x00000365,0x00000546,0x0000054b,0x00000547, + 0x000300f7,0x00000574,0x00000000,0x000400fa,0x0000054d,0x0000054e,0x00000574,0x000200f8, + 0x0000054e,0x0004003d,0x00000012,0x0000054f,0x00000484,0x00050084,0x00000012,0x00000550, + 0x0000054f,0x00000377,0x00050080,0x00000012,0x00000551,0x00000550,0x000000c1,0x00060041, + 0x0000037b,0x00000552,0x00000375,0x0000025a,0x00000551,0x0004003d,0x0000002f,0x00000553, + 0x00000552,0x0003003e,0x00000501,0x00000553,0x0004003d,0x0000002f,0x0000060e,0x00000501, + 0x0004003d,0x0000002f,0x00000610,0x00000501,0x00050051,0x00000006,0x00000612,0x0000060e, + 0x00000000,0x00050051,0x00000006,0x00000613,0x0000060e,0x00000001,0x00050051,0x00000006, + 0x00000614,0x00000610,0x00000002,0x00050051,0x00000006,0x00000615,0x00000610,0x00000003, + 0x00050050,0x0000000c,0x00000616,0x00000612,0x00000613,0x00050050,0x0000000c,0x00000617, + 0x00000614,0x00000615,0x00050050,0x00000035,0x00000618,0x00000616,0x00000617,0x0003003e, + 0x0000060c,0x00000618,0x0004003d,0x00000035,0x00000554,0x0000060c,0x0003003e,0x00000500, + 0x00000554,0x0004003d,0x00000012,0x00000555,0x00000484,0x00050084,0x00000012,0x00000556, + 0x00000555,0x00000377,0x00050080,0x00000012,0x00000557,0x00000556,0x000000d8,0x00060041, + 0x0000037b,0x00000558,0x00000375,0x0000025a,0x00000557,0x0004003d,0x0000002f,0x00000559, + 0x00000558,0x0003003e,0x00000502,0x00000559,0x0004003d,0x00000035,0x0000055a,0x00000500, + 0x00050091,0x0000000c,0x0000055d,0x0000055a,0x0000043d,0x0004003d,0x0000002f,0x0000055e, + 0x00000502,0x0007004f,0x0000000c,0x0000055f,0x0000055e,0x0000055e,0x00000000,0x00000001, + 0x00050081,0x0000000c,0x00000560,0x0000055d,0x0000055f,0x0003003e,0x00000503,0x00000560, + 0x0004003d,0x0000000c,0x00000561,0x00000503,0x0006000c,0x0000000c,0x00000562,0x00000001, + 0x00000004,0x00000561,0x0004003d,0x0000002f,0x00000563,0x00000502,0x0007004f,0x0000000c, + 0x00000564,0x00000563,0x00000563,0x00000002,0x00000003,0x00050085,0x0000000c,0x00000565, + 0x00000562,0x00000564,0x0004003d,0x0000002f,0x00000566,0x00000502,0x0007004f,0x0000000c, + 0x00000567,0x00000566,0x00000566,0x00000002,0x00000003,0x00050083,0x0000000c,0x00000568, + 0x00000565,0x00000567,0x0003003e,0x00000505,0x00000568,0x0004003d,0x0000000c,0x0000061c, + 0x00000505,0x0003003e,0x00000619,0x0000061c,0x0004003d,0x0000000c,0x0000061d,0x00000619, + 0x0003003e,0x0000061a,0x0000061d,0x0004003d,0x0000000c,0x00000569,0x0000061a,0x0003003e, + 0x00000504,0x00000569,0x00050041,0x00000007,0x0000056a,0x00000504,0x000000ab,0x0004003d, + 0x00000006,0x0000056b,0x0000056a,0x00050041,0x00000007,0x0000056c,0x00000504,0x000000ae, + 0x0004003d,0x00000006,0x0000056d,0x0000056c,0x0007000c,0x00000006,0x0000056e,0x00000001, + 0x00000025,0x0000056b,0x0000056d,0x00050081,0x00000006,0x0000056f,0x0000056e,0x000001d6, + 0x0008000c,0x00000006,0x00000570,0x00000001,0x0000002b,0x0000056f,0x000000e2,0x000000e1, + 0x0003003e,0x00000506,0x00000570,0x0004003d,0x00000006,0x00000571,0x000004f9,0x0004003d, + 0x00000006,0x00000572,0x00000506,0x0007000c,0x00000006,0x00000573,0x00000001,0x00000025, + 0x00000571,0x00000572,0x0003003e,0x000004f9,0x00000573,0x000200f9,0x00000574,0x000200f8, + 0x00000574,0x0004003d,0x00000012,0x00000576,0x0000051c,0x000500c7,0x00000012,0x00000577, + 0x00000576,0x000003a8,0x0003003e,0x00000507,0x00000577,0x0004003d,0x00000012,0x00000578, + 0x00000507,0x000500b2,0x000000f5,0x00000579,0x00000578,0x000000ae,0x000300f7,0x000005bc, + 0x00000000,0x000400fa,0x00000579,0x0000057a,0x0000058d,0x000200f8,0x0000057a,0x00050041, + 0x00000013,0x0000057b,0x000004f8,0x000000ae,0x0004003d,0x00000012,0x0000057c,0x0000057b, + 0x0006000c,0x0000002f,0x0000057d,0x00000001,0x00000040,0x0000057c,0x0003003e,0x00000488, + 0x0000057d,0x0004003d,0x00000012,0x0000057e,0x00000507,0x000500aa,0x000000f5,0x0000057f, + 0x0000057e,0x000000ab,0x000500a7,0x000000f5,0x00000580,0x0000034c,0x0000057f,0x000300f7, + 0x0000058c,0x00000000,0x000400fa,0x00000580,0x00000581,0x0000058c,0x000200f8,0x00000581, + 0x0004003d,0x0000002f,0x00000582,0x00000488,0x00050041,0x00000007,0x00000584,0x00000489, + 0x000000ab,0x00050051,0x00000006,0x00000585,0x00000582,0x00000002,0x0003003e,0x00000584, + 0x00000585,0x00050041,0x00000007,0x00000586,0x00000489,0x000000ae,0x00050051,0x00000006, + 0x00000587,0x00000582,0x00000003,0x0003003e,0x00000586,0x00000587,0x0004003d,0x00000006, + 0x00000588,0x000004f9,0x00050041,0x00000007,0x00000589,0x00000489,0x000000c1,0x0003003e, + 0x00000589,0x00000588,0x00050041,0x00000007,0x0000058a,0x00000489,0x000000d8,0x0003003e, + 0x0000058a,0x000000e1,0x0003003e,0x00000508,0x000000e2,0x0004003d,0x00000006,0x00000621, + 0x00000508,0x00050041,0x00000007,0x00000622,0x0000061e,0x000000ab,0x0003003e,0x00000622, + 0x00000621,0x0004003d,0x00000006,0x00000623,0x00000508,0x00050041,0x00000007,0x00000624, + 0x0000061e,0x000000ae,0x0003003e,0x00000624,0x00000623,0x0004003d,0x00000006,0x00000625, + 0x00000508,0x00050041,0x00000007,0x00000626,0x0000061e,0x000000c1,0x0003003e,0x00000626, + 0x00000625,0x0004003d,0x00000006,0x00000627,0x00000508,0x00050041,0x00000007,0x00000628, + 0x0000061e,0x000000d8,0x0003003e,0x00000628,0x00000627,0x0004003d,0x0000002f,0x00000629, + 0x0000061e,0x0003003e,0x0000061f,0x00000629,0x0004003d,0x0000002f,0x0000058b,0x0000061f, + 0x0003003e,0x00000488,0x0000058b,0x000200f9,0x0000058c,0x000200f8,0x0000058c,0x000200f9, + 0x000005bc,0x000200f8,0x0000058d,0x0004003d,0x00000012,0x0000058e,0x00000484,0x00050084, + 0x00000012,0x0000058f,0x0000058e,0x00000377,0x00060041,0x0000037b,0x00000590,0x00000375, + 0x0000025a,0x0000058f,0x0004003d,0x0000002f,0x00000591,0x00000590,0x0003003e,0x0000050a, + 0x00000591,0x0004003d,0x0000002f,0x0000062c,0x0000050a,0x0004003d,0x0000002f,0x0000062e, + 0x0000050a,0x00050051,0x00000006,0x00000630,0x0000062c,0x00000000,0x00050051,0x00000006, + 0x00000631,0x0000062c,0x00000001,0x00050051,0x00000006,0x00000632,0x0000062e,0x00000002, + 0x00050051,0x00000006,0x00000633,0x0000062e,0x00000003,0x00050050,0x0000000c,0x00000634, + 0x00000630,0x00000631,0x00050050,0x0000000c,0x00000635,0x00000632,0x00000633,0x00050050, + 0x00000035,0x00000636,0x00000634,0x00000635,0x0003003e,0x0000062a,0x00000636,0x0004003d, + 0x00000035,0x00000592,0x0000062a,0x0003003e,0x00000509,0x00000592,0x0004003d,0x00000012, + 0x00000593,0x00000484,0x00050084,0x00000012,0x00000594,0x00000593,0x00000377,0x00050080, + 0x00000012,0x00000595,0x00000594,0x000000ae,0x00060041,0x0000037b,0x00000596,0x00000375, + 0x0000025a,0x00000595,0x0004003d,0x0000002f,0x00000597,0x00000596,0x0003003e,0x0000050b, + 0x00000597,0x0004003d,0x00000035,0x00000598,0x00000509,0x00050091,0x0000000c,0x0000059b, + 0x00000598,0x0000043d,0x0004003d,0x0000002f,0x0000059c,0x0000050b,0x0007004f,0x0000000c, + 0x0000059d,0x0000059c,0x0000059c,0x00000000,0x00000001,0x00050081,0x0000000c,0x0000059e, + 0x0000059b,0x0000059d,0x0003003e,0x0000050c,0x0000059e,0x0004003d,0x00000012,0x0000059f, + 0x00000507,0x000500aa,0x000000f5,0x000005a0,0x0000059f,0x000000c1,0x000300f7,0x000005a7, + 0x00000000,0x000400fa,0x000005a0,0x000005a1,0x000005a4,0x000200f8,0x000005a1,0x00050041, + 0x00000007,0x000005a2,0x0000050c,0x000000ab,0x0004003d,0x00000006,0x000005a3,0x000005a2, + 0x0003003e,0x0000050e,0x000005a3,0x000200f9,0x000005a7,0x000200f8,0x000005a4,0x0004003d, + 0x0000000c,0x000005a5,0x0000050c,0x0006000c,0x00000006,0x000005a6,0x00000001,0x00000042, + 0x000005a5,0x0003003e,0x0000050e,0x000005a6,0x000200f9,0x000005a7,0x000200f8,0x000005a7, + 0x0004003d,0x00000006,0x000005a8,0x0000050e,0x0003003e,0x0000050d,0x000005a8,0x0004003d, + 0x00000006,0x000005a9,0x0000050d,0x0008000c,0x00000006,0x000005aa,0x00000001,0x0000002b, + 0x000005a9,0x000000e2,0x000000e1,0x0003003e,0x0000050d,0x000005aa,0x0004003d,0x00000006, + 0x000005ab,0x0000050d,0x00050041,0x00000007,0x000005ac,0x0000050b,0x000000c1,0x0004003d, + 0x00000006,0x000005ad,0x000005ac,0x00050085,0x00000006,0x000005ae,0x000005ab,0x000005ad, + 0x00050041,0x00000007,0x000005af,0x0000050b,0x000000d8,0x0004003d,0x00000006,0x000005b0, + 0x000005af,0x00050081,0x00000006,0x000005b1,0x000005ae,0x000005b0,0x0003003e,0x0000050f, + 0x000005b1,0x00050041,0x00000013,0x000005b2,0x000004f8,0x000000ae,0x0004003d,0x00000012, + 0x000005b3,0x000005b2,0x0004007c,0x00000006,0x000005b4,0x000005b3,0x0003003e,0x00000510, + 0x000005b4,0x0004003d,0x000003f1,0x000005b5,0x000003f3,0x0004003d,0x000003f5,0x000005b6, + 0x000003f7,0x00050056,0x000003f9,0x000005b7,0x000005b5,0x000005b6,0x0004003d,0x00000006, + 0x000005b8,0x0000050f,0x0004003d,0x00000006,0x000005b9,0x00000510,0x00050050,0x0000000c, + 0x000005ba,0x000005b8,0x000005b9,0x00070058,0x0000002f,0x000005bb,0x000005b7,0x000005ba, + 0x00000002,0x000000e2,0x0003003e,0x00000488,0x000005bb,0x000200f9,0x000005bc,0x000200f8, + 0x000005bc,0x0004003d,0x00000006,0x000005bd,0x000004f9,0x00050041,0x00000007,0x000005be, + 0x00000488,0x000000d8,0x0004003d,0x00000006,0x000005bf,0x000005be,0x00050085,0x00000006, + 0x000005c0,0x000005bf,0x000005bd,0x0003003e,0x000005be,0x000005c0,0x000300f7,0x000005c6, + 0x00000000,0x000400fa,0x00000404,0x000005c2,0x000005c6,0x000200f8,0x000005c2,0x0004003d, + 0x00000006,0x000005c4,0x000005be,0x000500b7,0x000000f5,0x000005c5,0x000005c4,0x000000e2, + 0x000200f9,0x000005c6,0x000200f8,0x000005c6,0x000700f5,0x000000f5,0x000005c7,0x00000404, + 0x000005bc,0x000005c5,0x000005c2,0x000300f7,0x000005cf,0x00000000,0x000400fa,0x000005c7, + 0x000005c8,0x000005cf,0x000200f8,0x000005c8,0x0004003d,0x00000012,0x000005ca,0x0000051c, + 0x000500c2,0x00000012,0x000005cb,0x000005ca,0x00000410,0x000500c7,0x00000012,0x000005cc, + 0x000005cb,0x000003a8,0x0003003e,0x00000512,0x000005cc,0x0004003d,0x00000012,0x0000063a, + 0x00000512,0x0003003e,0x00000637,0x0000063a,0x0004003d,0x00000012,0x0000063b,0x00000637, + 0x0003003e,0x00000638,0x0000063b,0x0004003d,0x00000012,0x000005cd,0x00000638,0x0003003e, + 0x00000511,0x000005cd,0x000500ab,0x000000f5,0x000005ce,0x000005cd,0x000000ab,0x000200f9, + 0x000005cf,0x000200f8,0x000005cf,0x000700f5,0x000000f5,0x000005d0,0x000005c7,0x000005c6, + 0x000005ce,0x000005c8,0x000300f7,0x000005df,0x00000000,0x000400fa,0x000005d0,0x000005d1, + 0x000005df,0x000200f8,0x000005d1,0x0004003d,0x00000358,0x000005d2,0x0000041a,0x00050062, + 0x0000002f,0x000005d3,0x000005d2,0x0000035c,0x0003003e,0x00000513,0x000005d3,0x0004003d, + 0x0000002f,0x000005d4,0x00000488,0x0008004f,0x00000024,0x000005d5,0x000005d4,0x000005d4, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x00000514,0x000005d5,0x0004003d,0x0000002f, + 0x000005d6,0x00000513,0x0003003e,0x00000515,0x000005d6,0x0004003d,0x00000012,0x000005d7, + 0x00000511,0x0003003e,0x00000516,0x000005d7,0x0004003d,0x00000024,0x00000643,0x00000514, + 0x0003003e,0x0000063d,0x00000643,0x0004003d,0x0000002f,0x00000644,0x00000515,0x0003003e, + 0x0000063e,0x00000644,0x0004003d,0x00000012,0x00000645,0x00000516,0x0003003e,0x0000063f, + 0x00000645,0x0004003d,0x0000002f,0x00000675,0x0000063e,0x0003003e,0x0000064e,0x00000675, + 0x0004003d,0x0000002f,0x00000771,0x0000064e,0x0008004f,0x00000024,0x00000772,0x00000771, + 0x00000771,0x00000000,0x00000001,0x00000002,0x00050041,0x00000007,0x00000773,0x0000064e, + 0x000000d8,0x0004003d,0x00000006,0x00000774,0x00000773,0x000500b7,0x000000f5,0x00000775, + 0x00000774,0x000000e2,0x000300f7,0x0000077b,0x00000000,0x000400fa,0x00000775,0x00000776, + 0x0000077a,0x000200f8,0x00000776,0x0004003d,0x00000006,0x00000778,0x00000773,0x00050088, + 0x00000006,0x00000779,0x000000e1,0x00000778,0x0003003e,0x0000076e,0x00000779,0x000200f9, + 0x0000077b,0x000200f8,0x0000077a,0x0003003e,0x0000076e,0x000000e2,0x000200f9,0x0000077b, + 0x000200f8,0x0000077b,0x0004003d,0x00000006,0x0000077c,0x0000076e,0x0005008e,0x00000024, + 0x0000077d,0x00000772,0x0000077c,0x0003003e,0x0000076f,0x0000077d,0x0004003d,0x00000024, + 0x00000676,0x0000076f,0x0003003e,0x0000064d,0x00000676,0x0004003d,0x00000012,0x00000677, + 0x0000063f,0x000300f7,0x0000076c,0x00000000,0x002100fb,0x00000677,0x0000076c,0x0000000b, + 0x00000678,0x00000001,0x0000067c,0x00000002,0x00000684,0x00000003,0x00000694,0x00000004, + 0x00000698,0x00000005,0x0000069c,0x00000006,0x000006be,0x00000007,0x000006ea,0x00000008, + 0x000006fa,0x00000009,0x00000734,0x0000000a,0x00000739,0x0000000c,0x00000742,0x0000000d, + 0x0000074d,0x0000000e,0x00000758,0x0000000f,0x00000762,0x000200f8,0x00000678,0x0004003d, + 0x00000024,0x00000679,0x0000063d,0x0004003d,0x00000024,0x0000067a,0x0000064d,0x00050085, + 0x00000024,0x0000067b,0x00000679,0x0000067a,0x0003003e,0x0000064f,0x0000067b,0x000200f9, + 0x0000076c,0x000200f8,0x0000067c,0x0004003d,0x00000024,0x0000067d,0x0000063d,0x0004003d, + 0x00000024,0x0000067e,0x0000064d,0x00050081,0x00000024,0x0000067f,0x0000067d,0x0000067e, + 0x0004003d,0x00000024,0x00000680,0x0000063d,0x0004003d,0x00000024,0x00000681,0x0000064d, + 0x00050085,0x00000024,0x00000682,0x00000680,0x00000681,0x00050083,0x00000024,0x00000683, + 0x0000067f,0x00000682,0x0003003e,0x0000064f,0x00000683,0x000200f9,0x0000076c,0x000200f8, + 0x00000684,0x0004003d,0x00000024,0x00000685,0x0000063d,0x0004003d,0x00000024,0x00000686, + 0x0000064d,0x00050085,0x00000024,0x00000687,0x00000685,0x00000686,0x0003003e,0x00000650, + 0x00000687,0x0004003d,0x00000024,0x00000688,0x00000650,0x0004003d,0x00000024,0x00000689, + 0x0000063d,0x0004003d,0x00000024,0x0000068a,0x0000064d,0x00050081,0x00000024,0x0000068b, + 0x00000689,0x0000068a,0x0004003d,0x00000024,0x0000068c,0x00000650,0x00050083,0x00000024, + 0x0000068d,0x0000068b,0x0000068c,0x00050083,0x00000024,0x0000068e,0x0000068d,0x000004bf, + 0x0004003d,0x00000024,0x0000068f,0x0000064d,0x0003003e,0x00000651,0x000001d6,0x0004003d, + 0x00000006,0x00000781,0x00000651,0x00050041,0x00000007,0x00000782,0x0000077e,0x000000ab, + 0x0003003e,0x00000782,0x00000781,0x0004003d,0x00000006,0x00000783,0x00000651,0x00050041, + 0x00000007,0x00000784,0x0000077e,0x000000ae,0x0003003e,0x00000784,0x00000783,0x0004003d, + 0x00000006,0x00000785,0x00000651,0x00050041,0x00000007,0x00000786,0x0000077e,0x000000c1, + 0x0003003e,0x00000786,0x00000785,0x0004003d,0x00000024,0x00000787,0x0000077e,0x0003003e, + 0x0000077f,0x00000787,0x0004003d,0x00000024,0x00000690,0x0000077f,0x000500ba,0x000001dc, + 0x00000691,0x0000068f,0x00000690,0x000600a9,0x00000024,0x00000692,0x00000691,0x0000068e, + 0x00000688,0x0005008e,0x00000024,0x00000693,0x00000692,0x000001cf,0x0003003e,0x0000064f, + 0x00000693,0x000200f9,0x0000076c,0x000200f8,0x00000694,0x0004003d,0x00000024,0x00000695, + 0x0000063d,0x0004003d,0x00000024,0x00000696,0x0000064d,0x0007000c,0x00000024,0x00000697, + 0x00000001,0x00000025,0x00000695,0x00000696,0x0003003e,0x0000064f,0x00000697,0x000200f9, + 0x0000076c,0x000200f8,0x00000698,0x0004003d,0x00000024,0x00000699,0x0000063d,0x0004003d, + 0x00000024,0x0000069a,0x0000064d,0x0007000c,0x00000024,0x0000069b,0x00000001,0x00000028, + 0x00000699,0x0000069a,0x0003003e,0x0000064f,0x0000069b,0x000200f9,0x0000076c,0x000200f8, + 0x0000069c,0x0004003d,0x0000002f,0x0000069d,0x0000063e,0x0008004f,0x00000024,0x0000069e, + 0x0000069d,0x0000069d,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000652,0x000000e2, + 0x0004003d,0x00000006,0x0000078b,0x00000652,0x00050041,0x00000007,0x0000078c,0x00000788, + 0x000000ab,0x0003003e,0x0000078c,0x0000078b,0x0004003d,0x00000006,0x0000078d,0x00000652, + 0x00050041,0x00000007,0x0000078e,0x00000788,0x000000ae,0x0003003e,0x0000078e,0x0000078d, + 0x0004003d,0x00000006,0x0000078f,0x00000652,0x00050041,0x00000007,0x00000790,0x00000788, + 0x000000c1,0x0003003e,0x00000790,0x0000078f,0x0004003d,0x00000024,0x00000791,0x00000788, + 0x0003003e,0x00000789,0x00000791,0x0004003d,0x00000024,0x0000069f,0x00000789,0x0004003d, + 0x0000002f,0x000006a0,0x0000063e,0x0008004f,0x00000024,0x000006a1,0x000006a0,0x000006a0, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024,0x000006a2,0x00000001,0x0000002b, + 0x0000069e,0x0000069f,0x000006a1,0x00050041,0x00000007,0x000006a3,0x0000063e,0x000000ab, + 0x00050051,0x00000006,0x000006a4,0x000006a2,0x00000000,0x0003003e,0x000006a3,0x000006a4, + 0x00050041,0x00000007,0x000006a5,0x0000063e,0x000000ae,0x00050051,0x00000006,0x000006a6, + 0x000006a2,0x00000001,0x0003003e,0x000006a5,0x000006a6,0x00050041,0x00000007,0x000006a7, + 0x0000063e,0x000000c1,0x00050051,0x00000006,0x000006a8,0x000006a2,0x00000002,0x0003003e, + 0x000006a7,0x000006a8,0x0004003d,0x00000024,0x000006a9,0x0000063d,0x00050083,0x00000024, + 0x000006aa,0x000004be,0x000006a9,0x0003003e,0x00000654,0x000000e2,0x0004003d,0x00000006, + 0x00000795,0x00000654,0x00050041,0x00000007,0x00000796,0x00000792,0x000000ab,0x0003003e, + 0x00000796,0x00000795,0x0004003d,0x00000006,0x00000797,0x00000654,0x00050041,0x00000007, + 0x00000798,0x00000792,0x000000ae,0x0003003e,0x00000798,0x00000797,0x0004003d,0x00000006, + 0x00000799,0x00000654,0x00050041,0x00000007,0x0000079a,0x00000792,0x000000c1,0x0003003e, + 0x0000079a,0x00000799,0x0004003d,0x00000024,0x0000079b,0x00000792,0x0003003e,0x00000793, + 0x0000079b,0x0004003d,0x00000024,0x000006ab,0x00000793,0x0003003e,0x00000655,0x000000e1, + 0x0004003d,0x00000006,0x0000079f,0x00000655,0x00050041,0x00000007,0x000007a0,0x0000079c, + 0x000000ab,0x0003003e,0x000007a0,0x0000079f,0x0004003d,0x00000006,0x000007a1,0x00000655, + 0x00050041,0x00000007,0x000007a2,0x0000079c,0x000000ae,0x0003003e,0x000007a2,0x000007a1, + 0x0004003d,0x00000006,0x000007a3,0x00000655,0x00050041,0x00000007,0x000007a4,0x0000079c, + 0x000000c1,0x0003003e,0x000007a4,0x000007a3,0x0004003d,0x00000024,0x000007a5,0x0000079c, + 0x0003003e,0x0000079d,0x000007a5,0x0004003d,0x00000024,0x000006ac,0x0000079d,0x0008000c, + 0x00000024,0x000006ad,0x00000001,0x0000002b,0x000006aa,0x000006ab,0x000006ac,0x00050041, + 0x00000007,0x000006ae,0x0000063e,0x000000d8,0x0004003d,0x00000006,0x000006af,0x000006ae, + 0x0005008e,0x00000024,0x000006b0,0x000006ad,0x000006af,0x0003003e,0x00000653,0x000006b0, + 0x0003003e,0x00000656,0x000000e1,0x0004003d,0x00000006,0x000007a9,0x00000656,0x00050041, + 0x00000007,0x000007aa,0x000007a6,0x000000ab,0x0003003e,0x000007aa,0x000007a9,0x0004003d, + 0x00000006,0x000007ab,0x00000656,0x00050041,0x00000007,0x000007ac,0x000007a6,0x000000ae, + 0x0003003e,0x000007ac,0x000007ab,0x0004003d,0x00000006,0x000007ad,0x00000656,0x00050041, + 0x00000007,0x000007ae,0x000007a6,0x000000c1,0x0003003e,0x000007ae,0x000007ad,0x0004003d, + 0x00000024,0x000007af,0x000007a6,0x0003003e,0x000007a7,0x000007af,0x0004003d,0x00000024, + 0x000006b1,0x000007a7,0x0004003d,0x0000002f,0x000006b2,0x0000063e,0x0008004f,0x00000024, + 0x000006b3,0x000006b2,0x000006b2,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000024, + 0x000006b4,0x00000653,0x00050088,0x00000024,0x000006b5,0x000006b3,0x000006b4,0x0007000c, + 0x00000024,0x000006b6,0x00000001,0x00000025,0x000006b1,0x000006b5,0x0004003d,0x0000002f, + 0x000006b7,0x0000063e,0x0008004f,0x00000024,0x000006b8,0x000006b7,0x000006b7,0x00000000, + 0x00000001,0x00000002,0x0006000c,0x00000024,0x000006b9,0x00000001,0x00000006,0x000006b8, + 0x0004003d,0x00000024,0x000006ba,0x00000653,0x0003003e,0x00000657,0x000000e2,0x0004003d, + 0x00000006,0x000007b3,0x00000657,0x00050041,0x00000007,0x000007b4,0x000007b0,0x000000ab, + 0x0003003e,0x000007b4,0x000007b3,0x0004003d,0x00000006,0x000007b5,0x00000657,0x00050041, + 0x00000007,0x000007b6,0x000007b0,0x000000ae,0x0003003e,0x000007b6,0x000007b5,0x0004003d, + 0x00000006,0x000007b7,0x00000657,0x00050041,0x00000007,0x000007b8,0x000007b0,0x000000c1, + 0x0003003e,0x000007b8,0x000007b7,0x0004003d,0x00000024,0x000007b9,0x000007b0,0x0003003e, + 0x000007b1,0x000007b9,0x0004003d,0x00000024,0x000006bb,0x000007b1,0x000500b4,0x000001dc, + 0x000006bc,0x000006ba,0x000006bb,0x000600a9,0x00000024,0x000006bd,0x000006bc,0x000006b9, + 0x000006b6,0x0003003e,0x0000064f,0x000006bd,0x000200f9,0x0000076c,0x000200f8,0x000006be, + 0x0004003d,0x00000024,0x000006bf,0x0000063d,0x0003003e,0x00000658,0x000000e2,0x0004003d, + 0x00000006,0x000007bd,0x00000658,0x00050041,0x00000007,0x000007be,0x000007ba,0x000000ab, + 0x0003003e,0x000007be,0x000007bd,0x0004003d,0x00000006,0x000007bf,0x00000658,0x00050041, + 0x00000007,0x000007c0,0x000007ba,0x000000ae,0x0003003e,0x000007c0,0x000007bf,0x0004003d, + 0x00000006,0x000007c1,0x00000658,0x00050041,0x00000007,0x000007c2,0x000007ba,0x000000c1, + 0x0003003e,0x000007c2,0x000007c1,0x0004003d,0x00000024,0x000007c3,0x000007ba,0x0003003e, + 0x000007bb,0x000007c3,0x0004003d,0x00000024,0x000006c0,0x000007bb,0x0003003e,0x00000659, + 0x000000e1,0x0004003d,0x00000006,0x000007c7,0x00000659,0x00050041,0x00000007,0x000007c8, + 0x000007c4,0x000000ab,0x0003003e,0x000007c8,0x000007c7,0x0004003d,0x00000006,0x000007c9, + 0x00000659,0x00050041,0x00000007,0x000007ca,0x000007c4,0x000000ae,0x0003003e,0x000007ca, + 0x000007c9,0x0004003d,0x00000006,0x000007cb,0x00000659,0x00050041,0x00000007,0x000007cc, + 0x000007c4,0x000000c1,0x0003003e,0x000007cc,0x000007cb,0x0004003d,0x00000024,0x000007cd, + 0x000007c4,0x0003003e,0x000007c5,0x000007cd,0x0004003d,0x00000024,0x000006c1,0x000007c5, + 0x0008000c,0x00000024,0x000006c2,0x00000001,0x0000002b,0x000006bf,0x000006c0,0x000006c1, + 0x0003003e,0x0000063d,0x000006c2,0x0004003d,0x0000002f,0x000006c3,0x0000063e,0x0008004f, + 0x00000024,0x000006c4,0x000006c3,0x000006c3,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x0000065a,0x000000e2,0x0004003d,0x00000006,0x000007d1,0x0000065a,0x00050041,0x00000007, + 0x000007d2,0x000007ce,0x000000ab,0x0003003e,0x000007d2,0x000007d1,0x0004003d,0x00000006, + 0x000007d3,0x0000065a,0x00050041,0x00000007,0x000007d4,0x000007ce,0x000000ae,0x0003003e, + 0x000007d4,0x000007d3,0x0004003d,0x00000006,0x000007d5,0x0000065a,0x00050041,0x00000007, + 0x000007d6,0x000007ce,0x000000c1,0x0003003e,0x000007d6,0x000007d5,0x0004003d,0x00000024, + 0x000007d7,0x000007ce,0x0003003e,0x000007cf,0x000007d7,0x0004003d,0x00000024,0x000006c5, + 0x000007cf,0x0004003d,0x0000002f,0x000006c6,0x0000063e,0x0008004f,0x00000024,0x000006c7, + 0x000006c6,0x000006c6,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024,0x000006c8, + 0x00000001,0x0000002b,0x000006c4,0x000006c5,0x000006c7,0x00050041,0x00000007,0x000006c9, + 0x0000063e,0x000000ab,0x00050051,0x00000006,0x000006ca,0x000006c8,0x00000000,0x0003003e, + 0x000006c9,0x000006ca,0x00050041,0x00000007,0x000006cb,0x0000063e,0x000000ae,0x00050051, + 0x00000006,0x000006cc,0x000006c8,0x00000001,0x0003003e,0x000006cb,0x000006cc,0x00050041, + 0x00000007,0x000006cd,0x0000063e,0x000000c1,0x00050051,0x00000006,0x000006ce,0x000006c8, + 0x00000002,0x0003003e,0x000006cd,0x000006ce,0x00050041,0x00000007,0x000006cf,0x0000063e, + 0x000000d8,0x0004003d,0x00000006,0x000006d0,0x000006cf,0x000500b4,0x000000f5,0x000006d1, + 0x000006d0,0x000000e2,0x000300f7,0x000006d4,0x00000000,0x000400fa,0x000006d1,0x000006d2, + 0x000006d4,0x000200f8,0x000006d2,0x0003003e,0x000006cf,0x000000e1,0x000200f9,0x000006d4, + 0x000200f8,0x000006d4,0x0004003d,0x00000006,0x000006d6,0x000006cf,0x0004003d,0x0000002f, + 0x000006d7,0x0000063e,0x0008004f,0x00000024,0x000006d8,0x000006d7,0x000006d7,0x00000000, + 0x00000001,0x00000002,0x00060050,0x00000024,0x000006d9,0x000006d6,0x000006d6,0x000006d6, + 0x00050083,0x00000024,0x000006da,0x000006d9,0x000006d8,0x0003003e,0x0000065b,0x000006da, + 0x0003003e,0x0000065c,0x000000e1,0x0004003d,0x00000006,0x000007db,0x0000065c,0x00050041, + 0x00000007,0x000007dc,0x000007d8,0x000000ab,0x0003003e,0x000007dc,0x000007db,0x0004003d, + 0x00000006,0x000007dd,0x0000065c,0x00050041,0x00000007,0x000007de,0x000007d8,0x000000ae, + 0x0003003e,0x000007de,0x000007dd,0x0004003d,0x00000006,0x000007df,0x0000065c,0x00050041, + 0x00000007,0x000007e0,0x000007d8,0x000000c1,0x0003003e,0x000007e0,0x000007df,0x0004003d, + 0x00000024,0x000007e1,0x000007d8,0x0003003e,0x000007d9,0x000007e1,0x0004003d,0x00000024, + 0x000006db,0x000007d9,0x0004003d,0x00000024,0x000006dc,0x0000065b,0x0004003d,0x00000024, + 0x000006dd,0x0000063d,0x0004003d,0x00000006,0x000006df,0x000006cf,0x0005008e,0x00000024, + 0x000006e0,0x000006dd,0x000006df,0x00050088,0x00000024,0x000006e1,0x000006dc,0x000006e0, + 0x0007000c,0x00000024,0x000006e2,0x00000001,0x00000025,0x000006db,0x000006e1,0x0004003d, + 0x00000024,0x000006e3,0x0000065b,0x0006000c,0x00000024,0x000006e4,0x00000001,0x00000006, + 0x000006e3,0x0004003d,0x00000024,0x000006e5,0x0000063d,0x0003003e,0x0000065d,0x000000e2, + 0x0004003d,0x00000006,0x000007e5,0x0000065d,0x00050041,0x00000007,0x000007e6,0x000007e2, + 0x000000ab,0x0003003e,0x000007e6,0x000007e5,0x0004003d,0x00000006,0x000007e7,0x0000065d, + 0x00050041,0x00000007,0x000007e8,0x000007e2,0x000000ae,0x0003003e,0x000007e8,0x000007e7, + 0x0004003d,0x00000006,0x000007e9,0x0000065d,0x00050041,0x00000007,0x000007ea,0x000007e2, + 0x000000c1,0x0003003e,0x000007ea,0x000007e9,0x0004003d,0x00000024,0x000007eb,0x000007e2, + 0x0003003e,0x000007e3,0x000007eb,0x0004003d,0x00000024,0x000006e6,0x000007e3,0x000500b4, + 0x000001dc,0x000006e7,0x000006e5,0x000006e6,0x000600a9,0x00000024,0x000006e8,0x000006e7, + 0x000006e4,0x000006e2,0x00050083,0x00000024,0x000006e9,0x000004be,0x000006e8,0x0003003e, + 0x0000064f,0x000006e9,0x000200f9,0x0000076c,0x000200f8,0x000006ea,0x0004003d,0x00000024, + 0x000006eb,0x0000063d,0x0004003d,0x00000024,0x000006ec,0x0000064d,0x00050085,0x00000024, + 0x000006ed,0x000006eb,0x000006ec,0x0003003e,0x0000065e,0x000006ed,0x0004003d,0x00000024, + 0x000006ee,0x0000065e,0x0004003d,0x00000024,0x000006ef,0x0000063d,0x0004003d,0x00000024, + 0x000006f0,0x0000064d,0x00050081,0x00000024,0x000006f1,0x000006ef,0x000006f0,0x0004003d, + 0x00000024,0x000006f2,0x0000065e,0x00050083,0x00000024,0x000006f3,0x000006f1,0x000006f2, + 0x00050083,0x00000024,0x000006f4,0x000006f3,0x000004bf,0x0004003d,0x00000024,0x000006f5, + 0x0000063d,0x0003003e,0x0000065f,0x000001d6,0x0004003d,0x00000006,0x000007ef,0x0000065f, + 0x00050041,0x00000007,0x000007f0,0x000007ec,0x000000ab,0x0003003e,0x000007f0,0x000007ef, + 0x0004003d,0x00000006,0x000007f1,0x0000065f,0x00050041,0x00000007,0x000007f2,0x000007ec, + 0x000000ae,0x0003003e,0x000007f2,0x000007f1,0x0004003d,0x00000006,0x000007f3,0x0000065f, + 0x00050041,0x00000007,0x000007f4,0x000007ec,0x000000c1,0x0003003e,0x000007f4,0x000007f3, + 0x0004003d,0x00000024,0x000007f5,0x000007ec,0x0003003e,0x000007ed,0x000007f5,0x0004003d, + 0x00000024,0x000006f6,0x000007ed,0x000500ba,0x000001dc,0x000006f7,0x000006f5,0x000006f6, + 0x000600a9,0x00000024,0x000006f8,0x000006f7,0x000006f4,0x000006ee,0x0005008e,0x00000024, + 0x000006f9,0x000006f8,0x000001cf,0x0003003e,0x0000064f,0x000006f9,0x000200f9,0x0000076c, + 0x000200f8,0x000006fa,0x0003003e,0x00000660,0x0000025a,0x000200f9,0x000006fb,0x000200f8, + 0x000006fb,0x0004003d,0x00000083,0x000006fd,0x00000660,0x000500b1,0x000000f5,0x000006fe, + 0x000006fd,0x00000261,0x000400f6,0x0000072a,0x00000727,0x00000000,0x000400fa,0x000006fe, + 0x000006ff,0x0000072a,0x000200f8,0x000006ff,0x0004003d,0x00000083,0x00000700,0x00000660, + 0x00050041,0x00000007,0x00000701,0x0000063d,0x00000700,0x0004003d,0x00000006,0x00000702, + 0x00000701,0x000500bc,0x000000f5,0x00000703,0x00000702,0x000001d6,0x000300f7,0x00000726, + 0x00000000,0x000400fa,0x00000703,0x00000704,0x0000070b,0x000200f8,0x00000704,0x0004003d, + 0x00000083,0x00000705,0x00000660,0x0004003d,0x00000083,0x00000706,0x00000660,0x00050041, + 0x00000007,0x00000707,0x0000064d,0x00000706,0x0004003d,0x00000006,0x00000708,0x00000707, + 0x00050083,0x00000006,0x00000709,0x000000e1,0x00000708,0x00050041,0x00000007,0x0000070a, + 0x0000064f,0x00000705,0x0003003e,0x0000070a,0x00000709,0x000200f9,0x00000726,0x000200f8, + 0x0000070b,0x0004003d,0x00000083,0x0000070c,0x00000660,0x00050041,0x00000007,0x0000070d, + 0x0000064d,0x0000070c,0x0004003d,0x00000006,0x0000070e,0x0000070d,0x000500bc,0x000000f5, + 0x0000070f,0x0000070e,0x00000273,0x000300f7,0x00000725,0x00000000,0x000400fa,0x0000070f, + 0x00000710,0x0000071d,0x000200f8,0x00000710,0x0004003d,0x00000083,0x00000711,0x00000660, + 0x0004003d,0x00000083,0x00000712,0x00000660,0x00050041,0x00000007,0x00000713,0x0000064d, + 0x00000712,0x0004003d,0x00000006,0x00000714,0x00000713,0x00050085,0x00000006,0x00000715, + 0x00000278,0x00000714,0x00050083,0x00000006,0x00000716,0x00000715,0x0000027d,0x0004003d, + 0x00000083,0x00000717,0x00000660,0x00050041,0x00000007,0x00000718,0x0000064d,0x00000717, + 0x0004003d,0x00000006,0x00000719,0x00000718,0x00050085,0x00000006,0x0000071a,0x00000716, + 0x00000719,0x00050081,0x00000006,0x0000071b,0x0000071a,0x00000283,0x00050041,0x00000007, + 0x0000071c,0x0000064f,0x00000711,0x0003003e,0x0000071c,0x0000071b,0x000200f9,0x00000725, + 0x000200f8,0x0000071d,0x0004003d,0x00000083,0x0000071e,0x00000660,0x0004003d,0x00000083, + 0x0000071f,0x00000660,0x00050041,0x00000007,0x00000720,0x0000064d,0x0000071f,0x0004003d, + 0x00000006,0x00000721,0x00000720,0x0006000c,0x00000006,0x00000722,0x00000001,0x00000020, + 0x00000721,0x00050083,0x00000006,0x00000723,0x00000722,0x000000e1,0x00050041,0x00000007, + 0x00000724,0x0000064f,0x0000071e,0x0003003e,0x00000724,0x00000723,0x000200f9,0x00000725, + 0x000200f8,0x00000725,0x000200f9,0x00000726,0x000200f8,0x00000726,0x000200f9,0x00000727, + 0x000200f8,0x00000727,0x0004003d,0x00000083,0x00000728,0x00000660,0x00050080,0x00000083, + 0x00000729,0x00000728,0x0000028f,0x0003003e,0x00000660,0x00000729,0x000200f9,0x000006fb, + 0x000200f8,0x0000072a,0x0004003d,0x00000024,0x0000072b,0x0000064d,0x0004003d,0x00000024, + 0x0000072c,0x0000064d,0x0004003d,0x00000024,0x0000072d,0x0000063d,0x0005008e,0x00000024, + 0x0000072e,0x0000072d,0x000001cf,0x00050083,0x00000024,0x0000072f,0x0000072e,0x000004be, + 0x00050085,0x00000024,0x00000730,0x0000072c,0x0000072f,0x0004003d,0x00000024,0x00000731, + 0x0000064f,0x00050085,0x00000024,0x00000732,0x00000730,0x00000731,0x00050081,0x00000024, + 0x00000733,0x0000072b,0x00000732,0x0003003e,0x0000064f,0x00000733,0x000200f9,0x0000076c, + 0x000200f8,0x00000734,0x0004003d,0x00000024,0x00000735,0x0000064d,0x0004003d,0x00000024, + 0x00000736,0x0000063d,0x00050083,0x00000024,0x00000737,0x00000735,0x00000736,0x0006000c, + 0x00000024,0x00000738,0x00000001,0x00000004,0x00000737,0x0003003e,0x0000064f,0x00000738, + 0x000200f9,0x0000076c,0x000200f8,0x00000739,0x0004003d,0x00000024,0x0000073a,0x0000063d, + 0x0004003d,0x00000024,0x0000073b,0x0000064d,0x00050081,0x00000024,0x0000073c,0x0000073a, + 0x0000073b,0x0004003d,0x00000024,0x0000073d,0x0000063d,0x0005008e,0x00000024,0x0000073e, + 0x0000073d,0x000001cf,0x0004003d,0x00000024,0x0000073f,0x0000064d,0x00050085,0x00000024, + 0x00000740,0x0000073e,0x0000073f,0x00050083,0x00000024,0x00000741,0x0000073c,0x00000740, + 0x0003003e,0x0000064f,0x00000741,0x000200f9,0x0000076c,0x000200f8,0x00000742,0x000300f7, + 0x0000074c,0x00000000,0x000400fa,0x000002aa,0x00000743,0x0000074c,0x000200f8,0x00000743, + 0x0004003d,0x00000024,0x00000744,0x0000063d,0x0003003e,0x00000661,0x000000e2,0x0004003d, + 0x00000006,0x000007f9,0x00000661,0x00050041,0x00000007,0x000007fa,0x000007f6,0x000000ab, + 0x0003003e,0x000007fa,0x000007f9,0x0004003d,0x00000006,0x000007fb,0x00000661,0x00050041, + 0x00000007,0x000007fc,0x000007f6,0x000000ae,0x0003003e,0x000007fc,0x000007fb,0x0004003d, + 0x00000006,0x000007fd,0x00000661,0x00050041,0x00000007,0x000007fe,0x000007f6,0x000000c1, + 0x0003003e,0x000007fe,0x000007fd,0x0004003d,0x00000024,0x000007ff,0x000007f6,0x0003003e, + 0x000007f7,0x000007ff,0x0004003d,0x00000024,0x00000745,0x000007f7,0x0003003e,0x00000662, + 0x000000e1,0x0004003d,0x00000006,0x00000803,0x00000662,0x00050041,0x00000007,0x00000804, + 0x00000800,0x000000ab,0x0003003e,0x00000804,0x00000803,0x0004003d,0x00000006,0x00000805, + 0x00000662,0x00050041,0x00000007,0x00000806,0x00000800,0x000000ae,0x0003003e,0x00000806, + 0x00000805,0x0004003d,0x00000006,0x00000807,0x00000662,0x00050041,0x00000007,0x00000808, + 0x00000800,0x000000c1,0x0003003e,0x00000808,0x00000807,0x0004003d,0x00000024,0x00000809, + 0x00000800,0x0003003e,0x00000801,0x00000809,0x0004003d,0x00000024,0x00000746,0x00000801, + 0x0008000c,0x00000024,0x00000747,0x00000001,0x0000002b,0x00000744,0x00000745,0x00000746, + 0x0003003e,0x0000063d,0x00000747,0x0004003d,0x00000024,0x00000748,0x0000063d,0x0003003e, + 0x00000663,0x00000748,0x0004003d,0x00000024,0x00000749,0x0000064d,0x0003003e,0x00000664, + 0x00000749,0x0004003d,0x00000024,0x0000074a,0x0000064d,0x0003003e,0x00000665,0x0000074a, + 0x0004003d,0x00000024,0x00000815,0x00000664,0x0003003e,0x0000080b,0x00000815,0x0004003d, + 0x00000024,0x0000082d,0x0000080b,0x0007004f,0x0000000c,0x0000082e,0x0000082d,0x0000082d, + 0x00000000,0x00000001,0x0003003e,0x0000082a,0x0000082e,0x00050041,0x00000007,0x00000835, + 0x0000082a,0x000000ab,0x0004003d,0x00000006,0x00000836,0x00000835,0x00050041,0x00000007, + 0x00000837,0x0000082a,0x000000ae,0x0004003d,0x00000006,0x00000838,0x00000837,0x0007000c, + 0x00000006,0x00000839,0x00000001,0x00000028,0x00000836,0x00000838,0x0003003e,0x00000833, + 0x00000839,0x0004003d,0x00000006,0x0000082f,0x00000833,0x00050041,0x00000007,0x00000830, + 0x0000080b,0x000000c1,0x0004003d,0x00000006,0x00000831,0x00000830,0x0007000c,0x00000006, + 0x00000832,0x00000001,0x00000028,0x0000082f,0x00000831,0x0003003e,0x0000082b,0x00000832, + 0x0004003d,0x00000006,0x00000816,0x0000082b,0x0004003d,0x00000024,0x00000817,0x00000664, + 0x0003003e,0x0000080c,0x00000817,0x0004003d,0x00000024,0x0000083d,0x0000080c,0x0007004f, + 0x0000000c,0x0000083e,0x0000083d,0x0000083d,0x00000000,0x00000001,0x0003003e,0x0000083a, + 0x0000083e,0x00050041,0x00000007,0x00000845,0x0000083a,0x000000ab,0x0004003d,0x00000006, + 0x00000846,0x00000845,0x00050041,0x00000007,0x00000847,0x0000083a,0x000000ae,0x0004003d, + 0x00000006,0x00000848,0x00000847,0x0007000c,0x00000006,0x00000849,0x00000001,0x00000025, + 0x00000846,0x00000848,0x0003003e,0x00000843,0x00000849,0x0004003d,0x00000006,0x0000083f, + 0x00000843,0x00050041,0x00000007,0x00000840,0x0000080c,0x000000c1,0x0004003d,0x00000006, + 0x00000841,0x00000840,0x0007000c,0x00000006,0x00000842,0x00000001,0x00000025,0x0000083f, + 0x00000841,0x0003003e,0x0000083b,0x00000842,0x0004003d,0x00000006,0x00000818,0x0000083b, + 0x00050083,0x00000006,0x00000819,0x00000816,0x00000818,0x0003003e,0x0000080a,0x00000819, + 0x0004003d,0x00000024,0x0000081a,0x00000663,0x0003003e,0x0000080d,0x0000081a,0x0004003d, + 0x00000024,0x0000084d,0x0000080d,0x0007004f,0x0000000c,0x0000084e,0x0000084d,0x0000084d, + 0x00000000,0x00000001,0x0003003e,0x0000084a,0x0000084e,0x00050041,0x00000007,0x00000855, + 0x0000084a,0x000000ab,0x0004003d,0x00000006,0x00000856,0x00000855,0x00050041,0x00000007, + 0x00000857,0x0000084a,0x000000ae,0x0004003d,0x00000006,0x00000858,0x00000857,0x0007000c, + 0x00000006,0x00000859,0x00000001,0x00000025,0x00000856,0x00000858,0x0003003e,0x00000853, + 0x00000859,0x0004003d,0x00000006,0x0000084f,0x00000853,0x00050041,0x00000007,0x00000850, + 0x0000080d,0x000000c1,0x0004003d,0x00000006,0x00000851,0x00000850,0x0007000c,0x00000006, + 0x00000852,0x00000001,0x00000025,0x0000084f,0x00000851,0x0003003e,0x0000084b,0x00000852, + 0x0004003d,0x00000006,0x0000081b,0x0000084b,0x0004003d,0x00000024,0x0000081c,0x00000663, + 0x00060050,0x00000024,0x0000081d,0x0000081b,0x0000081b,0x0000081b,0x00050083,0x00000024, + 0x0000081e,0x0000081c,0x0000081d,0x0003003e,0x00000663,0x0000081e,0x0004003d,0x00000024, + 0x0000081f,0x00000663,0x0003003e,0x0000080f,0x0000081f,0x0004003d,0x00000024,0x0000085d, + 0x0000080f,0x0007004f,0x0000000c,0x0000085e,0x0000085d,0x0000085d,0x00000000,0x00000001, + 0x0003003e,0x0000085a,0x0000085e,0x00050041,0x00000007,0x00000865,0x0000085a,0x000000ab, + 0x0004003d,0x00000006,0x00000866,0x00000865,0x00050041,0x00000007,0x00000867,0x0000085a, + 0x000000ae,0x0004003d,0x00000006,0x00000868,0x00000867,0x0007000c,0x00000006,0x00000869, + 0x00000001,0x00000028,0x00000866,0x00000868,0x0003003e,0x00000863,0x00000869,0x0004003d, + 0x00000006,0x0000085f,0x00000863,0x00050041,0x00000007,0x00000860,0x0000080f,0x000000c1, + 0x0004003d,0x00000006,0x00000861,0x00000860,0x0007000c,0x00000006,0x00000862,0x00000001, + 0x00000028,0x0000085f,0x00000861,0x0003003e,0x0000085b,0x00000862,0x0004003d,0x00000006, + 0x00000820,0x0000085b,0x0003003e,0x0000080e,0x00000820,0x0004003d,0x00000006,0x00000821, + 0x0000080a,0x0004003d,0x00000006,0x00000822,0x0000080e,0x0007000c,0x00000006,0x00000823, + 0x00000001,0x00000028,0x00000169,0x00000822,0x00050088,0x00000006,0x00000824,0x00000821, + 0x00000823,0x0003003e,0x00000810,0x00000824,0x0004003d,0x00000024,0x00000825,0x00000663, + 0x0004003d,0x00000006,0x00000826,0x00000810,0x0005008e,0x00000024,0x00000827,0x00000825, + 0x00000826,0x0003003e,0x00000811,0x00000827,0x0004003d,0x00000024,0x00000828,0x00000665, + 0x0003003e,0x00000812,0x00000828,0x0004003d,0x00000024,0x0000087a,0x00000812,0x0003003e, + 0x0000086b,0x0000087a,0x0004003d,0x00000024,0x000008a0,0x0000086b,0x0003003e,0x0000089b, + 0x0000014d,0x0003003e,0x0000089c,0x0000014e,0x0003003e,0x0000089d,0x0000014f,0x0004003d, + 0x00000006,0x000008a6,0x0000089b,0x00050041,0x00000007,0x000008a7,0x000008a3,0x000000ab, + 0x0003003e,0x000008a7,0x000008a6,0x0004003d,0x00000006,0x000008a8,0x0000089c,0x00050041, + 0x00000007,0x000008a9,0x000008a3,0x000000ae,0x0003003e,0x000008a9,0x000008a8,0x0004003d, + 0x00000006,0x000008aa,0x0000089d,0x00050041,0x00000007,0x000008ab,0x000008a3,0x000000c1, + 0x0003003e,0x000008ab,0x000008aa,0x0004003d,0x00000024,0x000008ac,0x000008a3,0x0003003e, + 0x000008a4,0x000008ac,0x0004003d,0x00000024,0x000008a1,0x000008a4,0x00050094,0x00000006, + 0x000008a2,0x000008a0,0x000008a1,0x0003003e,0x0000089e,0x000008a2,0x0004003d,0x00000006, + 0x0000087b,0x0000089e,0x0003003e,0x0000086a,0x0000087b,0x0004003d,0x00000024,0x0000087c, + 0x00000811,0x0004003d,0x00000024,0x0000087d,0x00000811,0x0003003e,0x0000086d,0x0000087d, + 0x0004003d,0x00000024,0x000008b2,0x0000086d,0x0003003e,0x000008ad,0x0000014d,0x0003003e, + 0x000008ae,0x0000014e,0x0003003e,0x000008af,0x0000014f,0x0004003d,0x00000006,0x000008b8, + 0x000008ad,0x00050041,0x00000007,0x000008b9,0x000008b5,0x000000ab,0x0003003e,0x000008b9, + 0x000008b8,0x0004003d,0x00000006,0x000008ba,0x000008ae,0x00050041,0x00000007,0x000008bb, + 0x000008b5,0x000000ae,0x0003003e,0x000008bb,0x000008ba,0x0004003d,0x00000006,0x000008bc, + 0x000008af,0x00050041,0x00000007,0x000008bd,0x000008b5,0x000000c1,0x0003003e,0x000008bd, + 0x000008bc,0x0004003d,0x00000024,0x000008be,0x000008b5,0x0003003e,0x000008b6,0x000008be, + 0x0004003d,0x00000024,0x000008b3,0x000008b6,0x00050094,0x00000006,0x000008b4,0x000008b2, + 0x000008b3,0x0003003e,0x000008b0,0x000008b4,0x0004003d,0x00000006,0x0000087e,0x000008b0, + 0x00060050,0x00000024,0x0000087f,0x0000087e,0x0000087e,0x0000087e,0x00050083,0x00000024, + 0x00000880,0x0000087c,0x0000087f,0x0003003e,0x0000086c,0x00000880,0x0004003d,0x00000006, + 0x00000881,0x0000086a,0x00050083,0x00000006,0x00000882,0x000000e1,0x00000881,0x0004003d, + 0x00000006,0x00000883,0x0000086a,0x0003003e,0x0000086f,0x00000883,0x0003003e,0x00000870, + 0x00000882,0x0004003d,0x00000006,0x000008c2,0x0000086f,0x00050041,0x00000007,0x000008c3, + 0x000008bf,0x000000ab,0x0003003e,0x000008c3,0x000008c2,0x0004003d,0x00000006,0x000008c4, + 0x00000870,0x00050041,0x00000007,0x000008c5,0x000008bf,0x000000ae,0x0003003e,0x000008c5, + 0x000008c4,0x0004003d,0x0000000c,0x000008c6,0x000008bf,0x0003003e,0x000008c0,0x000008c6, + 0x0004003d,0x0000000c,0x00000884,0x000008c0,0x0003003e,0x00000871,0x00000169,0x0004003d, + 0x00000006,0x000008ca,0x00000871,0x00050041,0x00000007,0x000008cb,0x000008c7,0x000000ab, + 0x0003003e,0x000008cb,0x000008ca,0x0004003d,0x00000006,0x000008cc,0x00000871,0x00050041, + 0x00000007,0x000008cd,0x000008c7,0x000000ae,0x0003003e,0x000008cd,0x000008cc,0x0004003d, + 0x0000000c,0x000008ce,0x000008c7,0x0003003e,0x000008c8,0x000008ce,0x0004003d,0x0000000c, + 0x00000885,0x000008c8,0x0004003d,0x00000024,0x00000886,0x0000086c,0x0003003e,0x00000872, + 0x00000886,0x0004003d,0x00000024,0x000008d2,0x00000872,0x0007004f,0x0000000c,0x000008d3, + 0x000008d2,0x000008d2,0x00000000,0x00000001,0x0003003e,0x000008cf,0x000008d3,0x00050041, + 0x00000007,0x000008da,0x000008cf,0x000000ab,0x0004003d,0x00000006,0x000008db,0x000008da, + 0x00050041,0x00000007,0x000008dc,0x000008cf,0x000000ae,0x0004003d,0x00000006,0x000008dd, + 0x000008dc,0x0007000c,0x00000006,0x000008de,0x00000001,0x00000025,0x000008db,0x000008dd, + 0x0003003e,0x000008d8,0x000008de,0x0004003d,0x00000006,0x000008d4,0x000008d8,0x00050041, + 0x00000007,0x000008d5,0x00000872,0x000000c1,0x0004003d,0x00000006,0x000008d6,0x000008d5, + 0x0007000c,0x00000006,0x000008d7,0x00000001,0x00000025,0x000008d4,0x000008d6,0x0003003e, + 0x000008d0,0x000008d7,0x0004003d,0x00000006,0x00000887,0x000008d0,0x0004007f,0x00000006, + 0x00000888,0x00000887,0x0004003d,0x00000024,0x00000889,0x0000086c,0x0003003e,0x00000873, + 0x00000889,0x0004003d,0x00000024,0x000008e2,0x00000873,0x0007004f,0x0000000c,0x000008e3, + 0x000008e2,0x000008e2,0x00000000,0x00000001,0x0003003e,0x000008df,0x000008e3,0x00050041, + 0x00000007,0x000008ea,0x000008df,0x000000ab,0x0004003d,0x00000006,0x000008eb,0x000008ea, + 0x00050041,0x00000007,0x000008ec,0x000008df,0x000000ae,0x0004003d,0x00000006,0x000008ed, + 0x000008ec,0x0007000c,0x00000006,0x000008ee,0x00000001,0x00000028,0x000008eb,0x000008ed, + 0x0003003e,0x000008e8,0x000008ee,0x0004003d,0x00000006,0x000008e4,0x000008e8,0x00050041, + 0x00000007,0x000008e5,0x00000873,0x000000c1,0x0004003d,0x00000006,0x000008e6,0x000008e5, + 0x0007000c,0x00000006,0x000008e7,0x00000001,0x00000028,0x000008e4,0x000008e6,0x0003003e, + 0x000008e0,0x000008e7,0x0004003d,0x00000006,0x0000088a,0x000008e0,0x0003003e,0x00000874, + 0x00000888,0x0003003e,0x00000875,0x0000088a,0x0004003d,0x00000006,0x000008f2,0x00000874, + 0x00050041,0x00000007,0x000008f3,0x000008ef,0x000000ab,0x0003003e,0x000008f3,0x000008f2, + 0x0004003d,0x00000006,0x000008f4,0x00000875,0x00050041,0x00000007,0x000008f5,0x000008ef, + 0x000000ae,0x0003003e,0x000008f5,0x000008f4,0x0004003d,0x0000000c,0x000008f6,0x000008ef, + 0x0003003e,0x000008f0,0x000008f6,0x0004003d,0x0000000c,0x0000088b,0x000008f0,0x0007000c, + 0x0000000c,0x0000088c,0x00000001,0x00000028,0x00000885,0x0000088b,0x00050088,0x0000000c, + 0x0000088d,0x00000884,0x0000088c,0x0003003e,0x0000086e,0x0000088d,0x0003003e,0x00000877, + 0x000000e1,0x0004003d,0x00000006,0x000008f9,0x00000877,0x0003003e,0x000008f7,0x000008f9, + 0x0004003d,0x00000006,0x0000088e,0x000008f7,0x00050041,0x00000007,0x0000088f,0x0000086e, + 0x000000ab,0x0004003d,0x00000006,0x00000890,0x0000088f,0x00050041,0x00000007,0x00000891, + 0x0000086e,0x000000ae,0x0004003d,0x00000006,0x00000892,0x00000891,0x0007000c,0x00000006, + 0x00000893,0x00000001,0x00000025,0x00000890,0x00000892,0x0007000c,0x00000006,0x00000894, + 0x00000001,0x00000025,0x0000088e,0x00000893,0x0003003e,0x00000876,0x00000894,0x0004003d, + 0x00000024,0x00000895,0x0000086c,0x0004003d,0x00000006,0x00000896,0x00000876,0x0005008e, + 0x00000024,0x00000897,0x00000895,0x00000896,0x0004003d,0x00000006,0x00000898,0x0000086a, + 0x00060050,0x00000024,0x00000899,0x00000898,0x00000898,0x00000898,0x00050081,0x00000024, + 0x0000089a,0x00000897,0x00000899,0x0003003e,0x00000878,0x0000089a,0x0004003d,0x00000024, + 0x00000829,0x00000878,0x0003003e,0x00000813,0x00000829,0x0004003d,0x00000024,0x0000074b, + 0x00000813,0x0003003e,0x0000064f,0x0000074b,0x000200f9,0x0000074c,0x000200f8,0x0000074c, + 0x000200f9,0x0000076c,0x000200f8,0x0000074d,0x000300f7,0x00000757,0x00000000,0x000400fa, + 0x000002aa,0x0000074e,0x00000757,0x000200f8,0x0000074e,0x0004003d,0x00000024,0x0000074f, + 0x0000063d,0x0003003e,0x00000666,0x000000e2,0x0004003d,0x00000006,0x000008fd,0x00000666, + 0x00050041,0x00000007,0x000008fe,0x000008fa,0x000000ab,0x0003003e,0x000008fe,0x000008fd, + 0x0004003d,0x00000006,0x000008ff,0x00000666,0x00050041,0x00000007,0x00000900,0x000008fa, + 0x000000ae,0x0003003e,0x00000900,0x000008ff,0x0004003d,0x00000006,0x00000901,0x00000666, + 0x00050041,0x00000007,0x00000902,0x000008fa,0x000000c1,0x0003003e,0x00000902,0x00000901, + 0x0004003d,0x00000024,0x00000903,0x000008fa,0x0003003e,0x000008fb,0x00000903,0x0004003d, + 0x00000024,0x00000750,0x000008fb,0x0003003e,0x00000667,0x000000e1,0x0004003d,0x00000006, + 0x00000907,0x00000667,0x00050041,0x00000007,0x00000908,0x00000904,0x000000ab,0x0003003e, + 0x00000908,0x00000907,0x0004003d,0x00000006,0x00000909,0x00000667,0x00050041,0x00000007, + 0x0000090a,0x00000904,0x000000ae,0x0003003e,0x0000090a,0x00000909,0x0004003d,0x00000006, + 0x0000090b,0x00000667,0x00050041,0x00000007,0x0000090c,0x00000904,0x000000c1,0x0003003e, + 0x0000090c,0x0000090b,0x0004003d,0x00000024,0x0000090d,0x00000904,0x0003003e,0x00000905, + 0x0000090d,0x0004003d,0x00000024,0x00000751,0x00000905,0x0008000c,0x00000024,0x00000752, + 0x00000001,0x0000002b,0x0000074f,0x00000750,0x00000751,0x0003003e,0x0000063d,0x00000752, + 0x0004003d,0x00000024,0x00000753,0x0000064d,0x0003003e,0x00000668,0x00000753,0x0004003d, + 0x00000024,0x00000754,0x0000063d,0x0003003e,0x00000669,0x00000754,0x0004003d,0x00000024, + 0x00000755,0x0000064d,0x0003003e,0x0000066a,0x00000755,0x0004003d,0x00000024,0x00000919, + 0x00000669,0x0003003e,0x0000090f,0x00000919,0x0004003d,0x00000024,0x00000931,0x0000090f, + 0x0007004f,0x0000000c,0x00000932,0x00000931,0x00000931,0x00000000,0x00000001,0x0003003e, + 0x0000092e,0x00000932,0x00050041,0x00000007,0x00000939,0x0000092e,0x000000ab,0x0004003d, + 0x00000006,0x0000093a,0x00000939,0x00050041,0x00000007,0x0000093b,0x0000092e,0x000000ae, + 0x0004003d,0x00000006,0x0000093c,0x0000093b,0x0007000c,0x00000006,0x0000093d,0x00000001, + 0x00000028,0x0000093a,0x0000093c,0x0003003e,0x00000937,0x0000093d,0x0004003d,0x00000006, + 0x00000933,0x00000937,0x00050041,0x00000007,0x00000934,0x0000090f,0x000000c1,0x0004003d, + 0x00000006,0x00000935,0x00000934,0x0007000c,0x00000006,0x00000936,0x00000001,0x00000028, + 0x00000933,0x00000935,0x0003003e,0x0000092f,0x00000936,0x0004003d,0x00000006,0x0000091a, + 0x0000092f,0x0004003d,0x00000024,0x0000091b,0x00000669,0x0003003e,0x00000910,0x0000091b, + 0x0004003d,0x00000024,0x00000941,0x00000910,0x0007004f,0x0000000c,0x00000942,0x00000941, + 0x00000941,0x00000000,0x00000001,0x0003003e,0x0000093e,0x00000942,0x00050041,0x00000007, + 0x00000949,0x0000093e,0x000000ab,0x0004003d,0x00000006,0x0000094a,0x00000949,0x00050041, + 0x00000007,0x0000094b,0x0000093e,0x000000ae,0x0004003d,0x00000006,0x0000094c,0x0000094b, + 0x0007000c,0x00000006,0x0000094d,0x00000001,0x00000025,0x0000094a,0x0000094c,0x0003003e, + 0x00000947,0x0000094d,0x0004003d,0x00000006,0x00000943,0x00000947,0x00050041,0x00000007, + 0x00000944,0x00000910,0x000000c1,0x0004003d,0x00000006,0x00000945,0x00000944,0x0007000c, + 0x00000006,0x00000946,0x00000001,0x00000025,0x00000943,0x00000945,0x0003003e,0x0000093f, + 0x00000946,0x0004003d,0x00000006,0x0000091c,0x0000093f,0x00050083,0x00000006,0x0000091d, + 0x0000091a,0x0000091c,0x0003003e,0x0000090e,0x0000091d,0x0004003d,0x00000024,0x0000091e, + 0x00000668,0x0003003e,0x00000911,0x0000091e,0x0004003d,0x00000024,0x00000951,0x00000911, + 0x0007004f,0x0000000c,0x00000952,0x00000951,0x00000951,0x00000000,0x00000001,0x0003003e, + 0x0000094e,0x00000952,0x00050041,0x00000007,0x00000959,0x0000094e,0x000000ab,0x0004003d, + 0x00000006,0x0000095a,0x00000959,0x00050041,0x00000007,0x0000095b,0x0000094e,0x000000ae, + 0x0004003d,0x00000006,0x0000095c,0x0000095b,0x0007000c,0x00000006,0x0000095d,0x00000001, + 0x00000025,0x0000095a,0x0000095c,0x0003003e,0x00000957,0x0000095d,0x0004003d,0x00000006, + 0x00000953,0x00000957,0x00050041,0x00000007,0x00000954,0x00000911,0x000000c1,0x0004003d, + 0x00000006,0x00000955,0x00000954,0x0007000c,0x00000006,0x00000956,0x00000001,0x00000025, + 0x00000953,0x00000955,0x0003003e,0x0000094f,0x00000956,0x0004003d,0x00000006,0x0000091f, + 0x0000094f,0x0004003d,0x00000024,0x00000920,0x00000668,0x00060050,0x00000024,0x00000921, + 0x0000091f,0x0000091f,0x0000091f,0x00050083,0x00000024,0x00000922,0x00000920,0x00000921, + 0x0003003e,0x00000668,0x00000922,0x0004003d,0x00000024,0x00000923,0x00000668,0x0003003e, + 0x00000913,0x00000923,0x0004003d,0x00000024,0x00000961,0x00000913,0x0007004f,0x0000000c, + 0x00000962,0x00000961,0x00000961,0x00000000,0x00000001,0x0003003e,0x0000095e,0x00000962, + 0x00050041,0x00000007,0x00000969,0x0000095e,0x000000ab,0x0004003d,0x00000006,0x0000096a, + 0x00000969,0x00050041,0x00000007,0x0000096b,0x0000095e,0x000000ae,0x0004003d,0x00000006, + 0x0000096c,0x0000096b,0x0007000c,0x00000006,0x0000096d,0x00000001,0x00000028,0x0000096a, + 0x0000096c,0x0003003e,0x00000967,0x0000096d,0x0004003d,0x00000006,0x00000963,0x00000967, + 0x00050041,0x00000007,0x00000964,0x00000913,0x000000c1,0x0004003d,0x00000006,0x00000965, + 0x00000964,0x0007000c,0x00000006,0x00000966,0x00000001,0x00000028,0x00000963,0x00000965, + 0x0003003e,0x0000095f,0x00000966,0x0004003d,0x00000006,0x00000924,0x0000095f,0x0003003e, + 0x00000912,0x00000924,0x0004003d,0x00000006,0x00000925,0x0000090e,0x0004003d,0x00000006, + 0x00000926,0x00000912,0x0007000c,0x00000006,0x00000927,0x00000001,0x00000028,0x00000169, + 0x00000926,0x00050088,0x00000006,0x00000928,0x00000925,0x00000927,0x0003003e,0x00000914, + 0x00000928,0x0004003d,0x00000024,0x00000929,0x00000668,0x0004003d,0x00000006,0x0000092a, + 0x00000914,0x0005008e,0x00000024,0x0000092b,0x00000929,0x0000092a,0x0003003e,0x00000915, + 0x0000092b,0x0004003d,0x00000024,0x0000092c,0x0000066a,0x0003003e,0x00000916,0x0000092c, + 0x0004003d,0x00000024,0x0000097e,0x00000916,0x0003003e,0x0000096f,0x0000097e,0x0004003d, + 0x00000024,0x000009a4,0x0000096f,0x0003003e,0x0000099f,0x0000014d,0x0003003e,0x000009a0, + 0x0000014e,0x0003003e,0x000009a1,0x0000014f,0x0004003d,0x00000006,0x000009aa,0x0000099f, + 0x00050041,0x00000007,0x000009ab,0x000009a7,0x000000ab,0x0003003e,0x000009ab,0x000009aa, + 0x0004003d,0x00000006,0x000009ac,0x000009a0,0x00050041,0x00000007,0x000009ad,0x000009a7, + 0x000000ae,0x0003003e,0x000009ad,0x000009ac,0x0004003d,0x00000006,0x000009ae,0x000009a1, + 0x00050041,0x00000007,0x000009af,0x000009a7,0x000000c1,0x0003003e,0x000009af,0x000009ae, + 0x0004003d,0x00000024,0x000009b0,0x000009a7,0x0003003e,0x000009a8,0x000009b0,0x0004003d, + 0x00000024,0x000009a5,0x000009a8,0x00050094,0x00000006,0x000009a6,0x000009a4,0x000009a5, + 0x0003003e,0x000009a2,0x000009a6,0x0004003d,0x00000006,0x0000097f,0x000009a2,0x0003003e, + 0x0000096e,0x0000097f,0x0004003d,0x00000024,0x00000980,0x00000915,0x0004003d,0x00000024, + 0x00000981,0x00000915,0x0003003e,0x00000971,0x00000981,0x0004003d,0x00000024,0x000009b6, + 0x00000971,0x0003003e,0x000009b1,0x0000014d,0x0003003e,0x000009b2,0x0000014e,0x0003003e, + 0x000009b3,0x0000014f,0x0004003d,0x00000006,0x000009bc,0x000009b1,0x00050041,0x00000007, + 0x000009bd,0x000009b9,0x000000ab,0x0003003e,0x000009bd,0x000009bc,0x0004003d,0x00000006, + 0x000009be,0x000009b2,0x00050041,0x00000007,0x000009bf,0x000009b9,0x000000ae,0x0003003e, + 0x000009bf,0x000009be,0x0004003d,0x00000006,0x000009c0,0x000009b3,0x00050041,0x00000007, + 0x000009c1,0x000009b9,0x000000c1,0x0003003e,0x000009c1,0x000009c0,0x0004003d,0x00000024, + 0x000009c2,0x000009b9,0x0003003e,0x000009ba,0x000009c2,0x0004003d,0x00000024,0x000009b7, + 0x000009ba,0x00050094,0x00000006,0x000009b8,0x000009b6,0x000009b7,0x0003003e,0x000009b4, + 0x000009b8,0x0004003d,0x00000006,0x00000982,0x000009b4,0x00060050,0x00000024,0x00000983, + 0x00000982,0x00000982,0x00000982,0x00050083,0x00000024,0x00000984,0x00000980,0x00000983, + 0x0003003e,0x00000970,0x00000984,0x0004003d,0x00000006,0x00000985,0x0000096e,0x00050083, + 0x00000006,0x00000986,0x000000e1,0x00000985,0x0004003d,0x00000006,0x00000987,0x0000096e, + 0x0003003e,0x00000973,0x00000987,0x0003003e,0x00000974,0x00000986,0x0004003d,0x00000006, + 0x000009c6,0x00000973,0x00050041,0x00000007,0x000009c7,0x000009c3,0x000000ab,0x0003003e, + 0x000009c7,0x000009c6,0x0004003d,0x00000006,0x000009c8,0x00000974,0x00050041,0x00000007, + 0x000009c9,0x000009c3,0x000000ae,0x0003003e,0x000009c9,0x000009c8,0x0004003d,0x0000000c, + 0x000009ca,0x000009c3,0x0003003e,0x000009c4,0x000009ca,0x0004003d,0x0000000c,0x00000988, + 0x000009c4,0x0003003e,0x00000975,0x00000169,0x0004003d,0x00000006,0x000009ce,0x00000975, + 0x00050041,0x00000007,0x000009cf,0x000009cb,0x000000ab,0x0003003e,0x000009cf,0x000009ce, + 0x0004003d,0x00000006,0x000009d0,0x00000975,0x00050041,0x00000007,0x000009d1,0x000009cb, + 0x000000ae,0x0003003e,0x000009d1,0x000009d0,0x0004003d,0x0000000c,0x000009d2,0x000009cb, + 0x0003003e,0x000009cc,0x000009d2,0x0004003d,0x0000000c,0x00000989,0x000009cc,0x0004003d, + 0x00000024,0x0000098a,0x00000970,0x0003003e,0x00000976,0x0000098a,0x0004003d,0x00000024, + 0x000009d6,0x00000976,0x0007004f,0x0000000c,0x000009d7,0x000009d6,0x000009d6,0x00000000, + 0x00000001,0x0003003e,0x000009d3,0x000009d7,0x00050041,0x00000007,0x000009de,0x000009d3, + 0x000000ab,0x0004003d,0x00000006,0x000009df,0x000009de,0x00050041,0x00000007,0x000009e0, + 0x000009d3,0x000000ae,0x0004003d,0x00000006,0x000009e1,0x000009e0,0x0007000c,0x00000006, + 0x000009e2,0x00000001,0x00000025,0x000009df,0x000009e1,0x0003003e,0x000009dc,0x000009e2, + 0x0004003d,0x00000006,0x000009d8,0x000009dc,0x00050041,0x00000007,0x000009d9,0x00000976, + 0x000000c1,0x0004003d,0x00000006,0x000009da,0x000009d9,0x0007000c,0x00000006,0x000009db, + 0x00000001,0x00000025,0x000009d8,0x000009da,0x0003003e,0x000009d4,0x000009db,0x0004003d, + 0x00000006,0x0000098b,0x000009d4,0x0004007f,0x00000006,0x0000098c,0x0000098b,0x0004003d, + 0x00000024,0x0000098d,0x00000970,0x0003003e,0x00000977,0x0000098d,0x0004003d,0x00000024, + 0x000009e6,0x00000977,0x0007004f,0x0000000c,0x000009e7,0x000009e6,0x000009e6,0x00000000, + 0x00000001,0x0003003e,0x000009e3,0x000009e7,0x00050041,0x00000007,0x000009ee,0x000009e3, + 0x000000ab,0x0004003d,0x00000006,0x000009ef,0x000009ee,0x00050041,0x00000007,0x000009f0, + 0x000009e3,0x000000ae,0x0004003d,0x00000006,0x000009f1,0x000009f0,0x0007000c,0x00000006, + 0x000009f2,0x00000001,0x00000028,0x000009ef,0x000009f1,0x0003003e,0x000009ec,0x000009f2, + 0x0004003d,0x00000006,0x000009e8,0x000009ec,0x00050041,0x00000007,0x000009e9,0x00000977, + 0x000000c1,0x0004003d,0x00000006,0x000009ea,0x000009e9,0x0007000c,0x00000006,0x000009eb, + 0x00000001,0x00000028,0x000009e8,0x000009ea,0x0003003e,0x000009e4,0x000009eb,0x0004003d, + 0x00000006,0x0000098e,0x000009e4,0x0003003e,0x00000978,0x0000098c,0x0003003e,0x00000979, + 0x0000098e,0x0004003d,0x00000006,0x000009f6,0x00000978,0x00050041,0x00000007,0x000009f7, + 0x000009f3,0x000000ab,0x0003003e,0x000009f7,0x000009f6,0x0004003d,0x00000006,0x000009f8, + 0x00000979,0x00050041,0x00000007,0x000009f9,0x000009f3,0x000000ae,0x0003003e,0x000009f9, + 0x000009f8,0x0004003d,0x0000000c,0x000009fa,0x000009f3,0x0003003e,0x000009f4,0x000009fa, + 0x0004003d,0x0000000c,0x0000098f,0x000009f4,0x0007000c,0x0000000c,0x00000990,0x00000001, + 0x00000028,0x00000989,0x0000098f,0x00050088,0x0000000c,0x00000991,0x00000988,0x00000990, + 0x0003003e,0x00000972,0x00000991,0x0003003e,0x0000097b,0x000000e1,0x0004003d,0x00000006, + 0x000009fd,0x0000097b,0x0003003e,0x000009fb,0x000009fd,0x0004003d,0x00000006,0x00000992, + 0x000009fb,0x00050041,0x00000007,0x00000993,0x00000972,0x000000ab,0x0004003d,0x00000006, + 0x00000994,0x00000993,0x00050041,0x00000007,0x00000995,0x00000972,0x000000ae,0x0004003d, + 0x00000006,0x00000996,0x00000995,0x0007000c,0x00000006,0x00000997,0x00000001,0x00000025, + 0x00000994,0x00000996,0x0007000c,0x00000006,0x00000998,0x00000001,0x00000025,0x00000992, + 0x00000997,0x0003003e,0x0000097a,0x00000998,0x0004003d,0x00000024,0x00000999,0x00000970, + 0x0004003d,0x00000006,0x0000099a,0x0000097a,0x0005008e,0x00000024,0x0000099b,0x00000999, + 0x0000099a,0x0004003d,0x00000006,0x0000099c,0x0000096e,0x00060050,0x00000024,0x0000099d, + 0x0000099c,0x0000099c,0x0000099c,0x00050081,0x00000024,0x0000099e,0x0000099b,0x0000099d, + 0x0003003e,0x0000097c,0x0000099e,0x0004003d,0x00000024,0x0000092d,0x0000097c,0x0003003e, + 0x00000917,0x0000092d,0x0004003d,0x00000024,0x00000756,0x00000917,0x0003003e,0x0000064f, + 0x00000756,0x000200f9,0x00000757,0x000200f8,0x00000757,0x000200f9,0x0000076c,0x000200f8, + 0x00000758,0x000300f7,0x00000761,0x00000000,0x000400fa,0x000002aa,0x00000759,0x00000761, + 0x000200f8,0x00000759,0x0004003d,0x00000024,0x0000075a,0x0000063d,0x0003003e,0x0000066b, + 0x000000e2,0x0004003d,0x00000006,0x00000a01,0x0000066b,0x00050041,0x00000007,0x00000a02, + 0x000009fe,0x000000ab,0x0003003e,0x00000a02,0x00000a01,0x0004003d,0x00000006,0x00000a03, + 0x0000066b,0x00050041,0x00000007,0x00000a04,0x000009fe,0x000000ae,0x0003003e,0x00000a04, + 0x00000a03,0x0004003d,0x00000006,0x00000a05,0x0000066b,0x00050041,0x00000007,0x00000a06, + 0x000009fe,0x000000c1,0x0003003e,0x00000a06,0x00000a05,0x0004003d,0x00000024,0x00000a07, + 0x000009fe,0x0003003e,0x000009ff,0x00000a07,0x0004003d,0x00000024,0x0000075b,0x000009ff, + 0x0003003e,0x0000066c,0x000000e1,0x0004003d,0x00000006,0x00000a0b,0x0000066c,0x00050041, + 0x00000007,0x00000a0c,0x00000a08,0x000000ab,0x0003003e,0x00000a0c,0x00000a0b,0x0004003d, + 0x00000006,0x00000a0d,0x0000066c,0x00050041,0x00000007,0x00000a0e,0x00000a08,0x000000ae, + 0x0003003e,0x00000a0e,0x00000a0d,0x0004003d,0x00000006,0x00000a0f,0x0000066c,0x00050041, + 0x00000007,0x00000a10,0x00000a08,0x000000c1,0x0003003e,0x00000a10,0x00000a0f,0x0004003d, + 0x00000024,0x00000a11,0x00000a08,0x0003003e,0x00000a09,0x00000a11,0x0004003d,0x00000024, + 0x0000075c,0x00000a09,0x0008000c,0x00000024,0x0000075d,0x00000001,0x0000002b,0x0000075a, + 0x0000075b,0x0000075c,0x0003003e,0x0000063d,0x0000075d,0x0004003d,0x00000024,0x0000075e, + 0x0000063d,0x0003003e,0x0000066d,0x0000075e,0x0004003d,0x00000024,0x0000075f,0x0000064d, + 0x0003003e,0x0000066e,0x0000075f,0x0004003d,0x00000024,0x00000a22,0x0000066e,0x0003003e, + 0x00000a13,0x00000a22,0x0004003d,0x00000024,0x00000a48,0x00000a13,0x0003003e,0x00000a43, + 0x0000014d,0x0003003e,0x00000a44,0x0000014e,0x0003003e,0x00000a45,0x0000014f,0x0004003d, + 0x00000006,0x00000a4e,0x00000a43,0x00050041,0x00000007,0x00000a4f,0x00000a4b,0x000000ab, + 0x0003003e,0x00000a4f,0x00000a4e,0x0004003d,0x00000006,0x00000a50,0x00000a44,0x00050041, + 0x00000007,0x00000a51,0x00000a4b,0x000000ae,0x0003003e,0x00000a51,0x00000a50,0x0004003d, + 0x00000006,0x00000a52,0x00000a45,0x00050041,0x00000007,0x00000a53,0x00000a4b,0x000000c1, + 0x0003003e,0x00000a53,0x00000a52,0x0004003d,0x00000024,0x00000a54,0x00000a4b,0x0003003e, + 0x00000a4c,0x00000a54,0x0004003d,0x00000024,0x00000a49,0x00000a4c,0x00050094,0x00000006, + 0x00000a4a,0x00000a48,0x00000a49,0x0003003e,0x00000a46,0x00000a4a,0x0004003d,0x00000006, + 0x00000a23,0x00000a46,0x0003003e,0x00000a12,0x00000a23,0x0004003d,0x00000024,0x00000a24, + 0x0000066d,0x0004003d,0x00000024,0x00000a25,0x0000066d,0x0003003e,0x00000a15,0x00000a25, + 0x0004003d,0x00000024,0x00000a5a,0x00000a15,0x0003003e,0x00000a55,0x0000014d,0x0003003e, + 0x00000a56,0x0000014e,0x0003003e,0x00000a57,0x0000014f,0x0004003d,0x00000006,0x00000a60, + 0x00000a55,0x00050041,0x00000007,0x00000a61,0x00000a5d,0x000000ab,0x0003003e,0x00000a61, + 0x00000a60,0x0004003d,0x00000006,0x00000a62,0x00000a56,0x00050041,0x00000007,0x00000a63, + 0x00000a5d,0x000000ae,0x0003003e,0x00000a63,0x00000a62,0x0004003d,0x00000006,0x00000a64, + 0x00000a57,0x00050041,0x00000007,0x00000a65,0x00000a5d,0x000000c1,0x0003003e,0x00000a65, + 0x00000a64,0x0004003d,0x00000024,0x00000a66,0x00000a5d,0x0003003e,0x00000a5e,0x00000a66, + 0x0004003d,0x00000024,0x00000a5b,0x00000a5e,0x00050094,0x00000006,0x00000a5c,0x00000a5a, + 0x00000a5b,0x0003003e,0x00000a58,0x00000a5c,0x0004003d,0x00000006,0x00000a26,0x00000a58, + 0x00060050,0x00000024,0x00000a27,0x00000a26,0x00000a26,0x00000a26,0x00050083,0x00000024, + 0x00000a28,0x00000a24,0x00000a27,0x0003003e,0x00000a14,0x00000a28,0x0004003d,0x00000006, + 0x00000a29,0x00000a12,0x00050083,0x00000006,0x00000a2a,0x000000e1,0x00000a29,0x0004003d, + 0x00000006,0x00000a2b,0x00000a12,0x0003003e,0x00000a17,0x00000a2b,0x0003003e,0x00000a18, + 0x00000a2a,0x0004003d,0x00000006,0x00000a6a,0x00000a17,0x00050041,0x00000007,0x00000a6b, + 0x00000a67,0x000000ab,0x0003003e,0x00000a6b,0x00000a6a,0x0004003d,0x00000006,0x00000a6c, + 0x00000a18,0x00050041,0x00000007,0x00000a6d,0x00000a67,0x000000ae,0x0003003e,0x00000a6d, + 0x00000a6c,0x0004003d,0x0000000c,0x00000a6e,0x00000a67,0x0003003e,0x00000a68,0x00000a6e, + 0x0004003d,0x0000000c,0x00000a2c,0x00000a68,0x0003003e,0x00000a19,0x00000169,0x0004003d, + 0x00000006,0x00000a72,0x00000a19,0x00050041,0x00000007,0x00000a73,0x00000a6f,0x000000ab, + 0x0003003e,0x00000a73,0x00000a72,0x0004003d,0x00000006,0x00000a74,0x00000a19,0x00050041, + 0x00000007,0x00000a75,0x00000a6f,0x000000ae,0x0003003e,0x00000a75,0x00000a74,0x0004003d, + 0x0000000c,0x00000a76,0x00000a6f,0x0003003e,0x00000a70,0x00000a76,0x0004003d,0x0000000c, + 0x00000a2d,0x00000a70,0x0004003d,0x00000024,0x00000a2e,0x00000a14,0x0003003e,0x00000a1a, + 0x00000a2e,0x0004003d,0x00000024,0x00000a7a,0x00000a1a,0x0007004f,0x0000000c,0x00000a7b, + 0x00000a7a,0x00000a7a,0x00000000,0x00000001,0x0003003e,0x00000a77,0x00000a7b,0x00050041, + 0x00000007,0x00000a82,0x00000a77,0x000000ab,0x0004003d,0x00000006,0x00000a83,0x00000a82, + 0x00050041,0x00000007,0x00000a84,0x00000a77,0x000000ae,0x0004003d,0x00000006,0x00000a85, + 0x00000a84,0x0007000c,0x00000006,0x00000a86,0x00000001,0x00000025,0x00000a83,0x00000a85, + 0x0003003e,0x00000a80,0x00000a86,0x0004003d,0x00000006,0x00000a7c,0x00000a80,0x00050041, + 0x00000007,0x00000a7d,0x00000a1a,0x000000c1,0x0004003d,0x00000006,0x00000a7e,0x00000a7d, + 0x0007000c,0x00000006,0x00000a7f,0x00000001,0x00000025,0x00000a7c,0x00000a7e,0x0003003e, + 0x00000a78,0x00000a7f,0x0004003d,0x00000006,0x00000a2f,0x00000a78,0x0004007f,0x00000006, + 0x00000a30,0x00000a2f,0x0004003d,0x00000024,0x00000a31,0x00000a14,0x0003003e,0x00000a1b, + 0x00000a31,0x0004003d,0x00000024,0x00000a8a,0x00000a1b,0x0007004f,0x0000000c,0x00000a8b, + 0x00000a8a,0x00000a8a,0x00000000,0x00000001,0x0003003e,0x00000a87,0x00000a8b,0x00050041, + 0x00000007,0x00000a92,0x00000a87,0x000000ab,0x0004003d,0x00000006,0x00000a93,0x00000a92, + 0x00050041,0x00000007,0x00000a94,0x00000a87,0x000000ae,0x0004003d,0x00000006,0x00000a95, + 0x00000a94,0x0007000c,0x00000006,0x00000a96,0x00000001,0x00000028,0x00000a93,0x00000a95, + 0x0003003e,0x00000a90,0x00000a96,0x0004003d,0x00000006,0x00000a8c,0x00000a90,0x00050041, + 0x00000007,0x00000a8d,0x00000a1b,0x000000c1,0x0004003d,0x00000006,0x00000a8e,0x00000a8d, + 0x0007000c,0x00000006,0x00000a8f,0x00000001,0x00000028,0x00000a8c,0x00000a8e,0x0003003e, + 0x00000a88,0x00000a8f,0x0004003d,0x00000006,0x00000a32,0x00000a88,0x0003003e,0x00000a1c, + 0x00000a30,0x0003003e,0x00000a1d,0x00000a32,0x0004003d,0x00000006,0x00000a9a,0x00000a1c, + 0x00050041,0x00000007,0x00000a9b,0x00000a97,0x000000ab,0x0003003e,0x00000a9b,0x00000a9a, + 0x0004003d,0x00000006,0x00000a9c,0x00000a1d,0x00050041,0x00000007,0x00000a9d,0x00000a97, + 0x000000ae,0x0003003e,0x00000a9d,0x00000a9c,0x0004003d,0x0000000c,0x00000a9e,0x00000a97, + 0x0003003e,0x00000a98,0x00000a9e,0x0004003d,0x0000000c,0x00000a33,0x00000a98,0x0007000c, + 0x0000000c,0x00000a34,0x00000001,0x00000028,0x00000a2d,0x00000a33,0x00050088,0x0000000c, + 0x00000a35,0x00000a2c,0x00000a34,0x0003003e,0x00000a16,0x00000a35,0x0003003e,0x00000a1f, + 0x000000e1,0x0004003d,0x00000006,0x00000aa1,0x00000a1f,0x0003003e,0x00000a9f,0x00000aa1, + 0x0004003d,0x00000006,0x00000a36,0x00000a9f,0x00050041,0x00000007,0x00000a37,0x00000a16, + 0x000000ab,0x0004003d,0x00000006,0x00000a38,0x00000a37,0x00050041,0x00000007,0x00000a39, + 0x00000a16,0x000000ae,0x0004003d,0x00000006,0x00000a3a,0x00000a39,0x0007000c,0x00000006, + 0x00000a3b,0x00000001,0x00000025,0x00000a38,0x00000a3a,0x0007000c,0x00000006,0x00000a3c, + 0x00000001,0x00000025,0x00000a36,0x00000a3b,0x0003003e,0x00000a1e,0x00000a3c,0x0004003d, + 0x00000024,0x00000a3d,0x00000a14,0x0004003d,0x00000006,0x00000a3e,0x00000a1e,0x0005008e, + 0x00000024,0x00000a3f,0x00000a3d,0x00000a3e,0x0004003d,0x00000006,0x00000a40,0x00000a12, + 0x00060050,0x00000024,0x00000a41,0x00000a40,0x00000a40,0x00000a40,0x00050081,0x00000024, + 0x00000a42,0x00000a3f,0x00000a41,0x0003003e,0x00000a20,0x00000a42,0x0004003d,0x00000024, + 0x00000760,0x00000a20,0x0003003e,0x0000064f,0x00000760,0x000200f9,0x00000761,0x000200f8, + 0x00000761,0x000200f9,0x0000076c,0x000200f8,0x00000762,0x000300f7,0x0000076b,0x00000000, + 0x000400fa,0x000002aa,0x00000763,0x0000076b,0x000200f8,0x00000763,0x0004003d,0x00000024, + 0x00000764,0x0000063d,0x0003003e,0x0000066f,0x000000e2,0x0004003d,0x00000006,0x00000aa5, + 0x0000066f,0x00050041,0x00000007,0x00000aa6,0x00000aa2,0x000000ab,0x0003003e,0x00000aa6, + 0x00000aa5,0x0004003d,0x00000006,0x00000aa7,0x0000066f,0x00050041,0x00000007,0x00000aa8, + 0x00000aa2,0x000000ae,0x0003003e,0x00000aa8,0x00000aa7,0x0004003d,0x00000006,0x00000aa9, + 0x0000066f,0x00050041,0x00000007,0x00000aaa,0x00000aa2,0x000000c1,0x0003003e,0x00000aaa, + 0x00000aa9,0x0004003d,0x00000024,0x00000aab,0x00000aa2,0x0003003e,0x00000aa3,0x00000aab, + 0x0004003d,0x00000024,0x00000765,0x00000aa3,0x0003003e,0x00000670,0x000000e1,0x0004003d, + 0x00000006,0x00000aaf,0x00000670,0x00050041,0x00000007,0x00000ab0,0x00000aac,0x000000ab, + 0x0003003e,0x00000ab0,0x00000aaf,0x0004003d,0x00000006,0x00000ab1,0x00000670,0x00050041, + 0x00000007,0x00000ab2,0x00000aac,0x000000ae,0x0003003e,0x00000ab2,0x00000ab1,0x0004003d, + 0x00000006,0x00000ab3,0x00000670,0x00050041,0x00000007,0x00000ab4,0x00000aac,0x000000c1, + 0x0003003e,0x00000ab4,0x00000ab3,0x0004003d,0x00000024,0x00000ab5,0x00000aac,0x0003003e, + 0x00000aad,0x00000ab5,0x0004003d,0x00000024,0x00000766,0x00000aad,0x0008000c,0x00000024, + 0x00000767,0x00000001,0x0000002b,0x00000764,0x00000765,0x00000766,0x0003003e,0x0000063d, + 0x00000767,0x0004003d,0x00000024,0x00000768,0x0000064d,0x0003003e,0x00000671,0x00000768, + 0x0004003d,0x00000024,0x00000769,0x0000063d,0x0003003e,0x00000672,0x00000769,0x0004003d, + 0x00000024,0x00000ac6,0x00000672,0x0003003e,0x00000ab7,0x00000ac6,0x0004003d,0x00000024, + 0x00000aec,0x00000ab7,0x0003003e,0x00000ae7,0x0000014d,0x0003003e,0x00000ae8,0x0000014e, + 0x0003003e,0x00000ae9,0x0000014f,0x0004003d,0x00000006,0x00000af2,0x00000ae7,0x00050041, + 0x00000007,0x00000af3,0x00000aef,0x000000ab,0x0003003e,0x00000af3,0x00000af2,0x0004003d, + 0x00000006,0x00000af4,0x00000ae8,0x00050041,0x00000007,0x00000af5,0x00000aef,0x000000ae, + 0x0003003e,0x00000af5,0x00000af4,0x0004003d,0x00000006,0x00000af6,0x00000ae9,0x00050041, + 0x00000007,0x00000af7,0x00000aef,0x000000c1,0x0003003e,0x00000af7,0x00000af6,0x0004003d, + 0x00000024,0x00000af8,0x00000aef,0x0003003e,0x00000af0,0x00000af8,0x0004003d,0x00000024, + 0x00000aed,0x00000af0,0x00050094,0x00000006,0x00000aee,0x00000aec,0x00000aed,0x0003003e, + 0x00000aea,0x00000aee,0x0004003d,0x00000006,0x00000ac7,0x00000aea,0x0003003e,0x00000ab6, + 0x00000ac7,0x0004003d,0x00000024,0x00000ac8,0x00000671,0x0004003d,0x00000024,0x00000ac9, + 0x00000671,0x0003003e,0x00000ab9,0x00000ac9,0x0004003d,0x00000024,0x00000afe,0x00000ab9, + 0x0003003e,0x00000af9,0x0000014d,0x0003003e,0x00000afa,0x0000014e,0x0003003e,0x00000afb, + 0x0000014f,0x0004003d,0x00000006,0x00000b04,0x00000af9,0x00050041,0x00000007,0x00000b05, + 0x00000b01,0x000000ab,0x0003003e,0x00000b05,0x00000b04,0x0004003d,0x00000006,0x00000b06, + 0x00000afa,0x00050041,0x00000007,0x00000b07,0x00000b01,0x000000ae,0x0003003e,0x00000b07, + 0x00000b06,0x0004003d,0x00000006,0x00000b08,0x00000afb,0x00050041,0x00000007,0x00000b09, + 0x00000b01,0x000000c1,0x0003003e,0x00000b09,0x00000b08,0x0004003d,0x00000024,0x00000b0a, + 0x00000b01,0x0003003e,0x00000b02,0x00000b0a,0x0004003d,0x00000024,0x00000aff,0x00000b02, + 0x00050094,0x00000006,0x00000b00,0x00000afe,0x00000aff,0x0003003e,0x00000afc,0x00000b00, + 0x0004003d,0x00000006,0x00000aca,0x00000afc,0x00060050,0x00000024,0x00000acb,0x00000aca, + 0x00000aca,0x00000aca,0x00050083,0x00000024,0x00000acc,0x00000ac8,0x00000acb,0x0003003e, + 0x00000ab8,0x00000acc,0x0004003d,0x00000006,0x00000acd,0x00000ab6,0x00050083,0x00000006, + 0x00000ace,0x000000e1,0x00000acd,0x0004003d,0x00000006,0x00000acf,0x00000ab6,0x0003003e, + 0x00000abb,0x00000acf,0x0003003e,0x00000abc,0x00000ace,0x0004003d,0x00000006,0x00000b0e, + 0x00000abb,0x00050041,0x00000007,0x00000b0f,0x00000b0b,0x000000ab,0x0003003e,0x00000b0f, + 0x00000b0e,0x0004003d,0x00000006,0x00000b10,0x00000abc,0x00050041,0x00000007,0x00000b11, + 0x00000b0b,0x000000ae,0x0003003e,0x00000b11,0x00000b10,0x0004003d,0x0000000c,0x00000b12, + 0x00000b0b,0x0003003e,0x00000b0c,0x00000b12,0x0004003d,0x0000000c,0x00000ad0,0x00000b0c, + 0x0003003e,0x00000abd,0x00000169,0x0004003d,0x00000006,0x00000b16,0x00000abd,0x00050041, + 0x00000007,0x00000b17,0x00000b13,0x000000ab,0x0003003e,0x00000b17,0x00000b16,0x0004003d, + 0x00000006,0x00000b18,0x00000abd,0x00050041,0x00000007,0x00000b19,0x00000b13,0x000000ae, + 0x0003003e,0x00000b19,0x00000b18,0x0004003d,0x0000000c,0x00000b1a,0x00000b13,0x0003003e, + 0x00000b14,0x00000b1a,0x0004003d,0x0000000c,0x00000ad1,0x00000b14,0x0004003d,0x00000024, + 0x00000ad2,0x00000ab8,0x0003003e,0x00000abe,0x00000ad2,0x0004003d,0x00000024,0x00000b1e, + 0x00000abe,0x0007004f,0x0000000c,0x00000b1f,0x00000b1e,0x00000b1e,0x00000000,0x00000001, + 0x0003003e,0x00000b1b,0x00000b1f,0x00050041,0x00000007,0x00000b26,0x00000b1b,0x000000ab, + 0x0004003d,0x00000006,0x00000b27,0x00000b26,0x00050041,0x00000007,0x00000b28,0x00000b1b, + 0x000000ae,0x0004003d,0x00000006,0x00000b29,0x00000b28,0x0007000c,0x00000006,0x00000b2a, + 0x00000001,0x00000025,0x00000b27,0x00000b29,0x0003003e,0x00000b24,0x00000b2a,0x0004003d, + 0x00000006,0x00000b20,0x00000b24,0x00050041,0x00000007,0x00000b21,0x00000abe,0x000000c1, + 0x0004003d,0x00000006,0x00000b22,0x00000b21,0x0007000c,0x00000006,0x00000b23,0x00000001, + 0x00000025,0x00000b20,0x00000b22,0x0003003e,0x00000b1c,0x00000b23,0x0004003d,0x00000006, + 0x00000ad3,0x00000b1c,0x0004007f,0x00000006,0x00000ad4,0x00000ad3,0x0004003d,0x00000024, + 0x00000ad5,0x00000ab8,0x0003003e,0x00000abf,0x00000ad5,0x0004003d,0x00000024,0x00000b2e, + 0x00000abf,0x0007004f,0x0000000c,0x00000b2f,0x00000b2e,0x00000b2e,0x00000000,0x00000001, + 0x0003003e,0x00000b2b,0x00000b2f,0x00050041,0x00000007,0x00000b36,0x00000b2b,0x000000ab, + 0x0004003d,0x00000006,0x00000b37,0x00000b36,0x00050041,0x00000007,0x00000b38,0x00000b2b, + 0x000000ae,0x0004003d,0x00000006,0x00000b39,0x00000b38,0x0007000c,0x00000006,0x00000b3a, + 0x00000001,0x00000028,0x00000b37,0x00000b39,0x0003003e,0x00000b34,0x00000b3a,0x0004003d, + 0x00000006,0x00000b30,0x00000b34,0x00050041,0x00000007,0x00000b31,0x00000abf,0x000000c1, + 0x0004003d,0x00000006,0x00000b32,0x00000b31,0x0007000c,0x00000006,0x00000b33,0x00000001, + 0x00000028,0x00000b30,0x00000b32,0x0003003e,0x00000b2c,0x00000b33,0x0004003d,0x00000006, + 0x00000ad6,0x00000b2c,0x0003003e,0x00000ac0,0x00000ad4,0x0003003e,0x00000ac1,0x00000ad6, + 0x0004003d,0x00000006,0x00000b3e,0x00000ac0,0x00050041,0x00000007,0x00000b3f,0x00000b3b, + 0x000000ab,0x0003003e,0x00000b3f,0x00000b3e,0x0004003d,0x00000006,0x00000b40,0x00000ac1, + 0x00050041,0x00000007,0x00000b41,0x00000b3b,0x000000ae,0x0003003e,0x00000b41,0x00000b40, + 0x0004003d,0x0000000c,0x00000b42,0x00000b3b,0x0003003e,0x00000b3c,0x00000b42,0x0004003d, + 0x0000000c,0x00000ad7,0x00000b3c,0x0007000c,0x0000000c,0x00000ad8,0x00000001,0x00000028, + 0x00000ad1,0x00000ad7,0x00050088,0x0000000c,0x00000ad9,0x00000ad0,0x00000ad8,0x0003003e, + 0x00000aba,0x00000ad9,0x0003003e,0x00000ac3,0x000000e1,0x0004003d,0x00000006,0x00000b45, + 0x00000ac3,0x0003003e,0x00000b43,0x00000b45,0x0004003d,0x00000006,0x00000ada,0x00000b43, + 0x00050041,0x00000007,0x00000adb,0x00000aba,0x000000ab,0x0004003d,0x00000006,0x00000adc, + 0x00000adb,0x00050041,0x00000007,0x00000add,0x00000aba,0x000000ae,0x0004003d,0x00000006, + 0x00000ade,0x00000add,0x0007000c,0x00000006,0x00000adf,0x00000001,0x00000025,0x00000adc, + 0x00000ade,0x0007000c,0x00000006,0x00000ae0,0x00000001,0x00000025,0x00000ada,0x00000adf, + 0x0003003e,0x00000ac2,0x00000ae0,0x0004003d,0x00000024,0x00000ae1,0x00000ab8,0x0004003d, + 0x00000006,0x00000ae2,0x00000ac2,0x0005008e,0x00000024,0x00000ae3,0x00000ae1,0x00000ae2, + 0x0004003d,0x00000006,0x00000ae4,0x00000ab6,0x00060050,0x00000024,0x00000ae5,0x00000ae4, + 0x00000ae4,0x00000ae4,0x00050081,0x00000024,0x00000ae6,0x00000ae3,0x00000ae5,0x0003003e, + 0x00000ac4,0x00000ae6,0x0004003d,0x00000024,0x0000076a,0x00000ac4,0x0003003e,0x0000064f, + 0x0000076a,0x000200f9,0x0000076b,0x000200f8,0x0000076b,0x000200f9,0x0000076c,0x000200f8, + 0x0000076c,0x0004003d,0x00000024,0x0000076d,0x0000064f,0x0003003e,0x00000673,0x0000076d, + 0x0004003d,0x00000024,0x00000646,0x00000673,0x0003003e,0x0000063c,0x00000646,0x0004003d, + 0x00000024,0x00000647,0x00000514,0x0004003d,0x00000024,0x00000648,0x0000063c,0x00050041, + 0x00000007,0x00000649,0x00000515,0x000000d8,0x0004003d,0x00000006,0x0000064a,0x00000649, + 0x0003003e,0x00000640,0x0000064a,0x0004003d,0x00000006,0x00000b49,0x00000640,0x00050041, + 0x00000007,0x00000b4a,0x00000b46,0x000000ab,0x0003003e,0x00000b4a,0x00000b49,0x0004003d, + 0x00000006,0x00000b4b,0x00000640,0x00050041,0x00000007,0x00000b4c,0x00000b46,0x000000ae, + 0x0003003e,0x00000b4c,0x00000b4b,0x0004003d,0x00000006,0x00000b4d,0x00000640,0x00050041, + 0x00000007,0x00000b4e,0x00000b46,0x000000c1,0x0003003e,0x00000b4e,0x00000b4d,0x0004003d, + 0x00000024,0x00000b4f,0x00000b46,0x0003003e,0x00000b47,0x00000b4f,0x0004003d,0x00000024, + 0x0000064b,0x00000b47,0x0008000c,0x00000024,0x0000064c,0x00000001,0x0000002e,0x00000647, + 0x00000648,0x0000064b,0x0003003e,0x00000641,0x0000064c,0x0004003d,0x00000024,0x000005d8, + 0x00000641,0x00050041,0x00000007,0x000005d9,0x00000488,0x000000ab,0x00050051,0x00000006, + 0x000005da,0x000005d8,0x00000000,0x0003003e,0x000005d9,0x000005da,0x00050041,0x00000007, + 0x000005db,0x00000488,0x000000ae,0x00050051,0x00000006,0x000005dc,0x000005d8,0x00000001, + 0x0003003e,0x000005db,0x000005dc,0x00050041,0x00000007,0x000005dd,0x00000488,0x000000c1, + 0x00050051,0x00000006,0x000005de,0x000005d8,0x00000002,0x0003003e,0x000005dd,0x000005de, + 0x000200f9,0x000005df,0x000200f8,0x000005df,0x0004003d,0x00000006,0x000005e1,0x000005be, + 0x0004003d,0x0000002f,0x000005e2,0x00000488,0x0008004f,0x00000024,0x000005e3,0x000005e2, + 0x000005e2,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000024,0x000005e4,0x000005e3, + 0x000005e1,0x00050041,0x00000007,0x000005e5,0x00000488,0x000000ab,0x00050051,0x00000006, + 0x000005e6,0x000005e4,0x00000000,0x0003003e,0x000005e5,0x000005e6,0x00050041,0x00000007, + 0x000005e7,0x00000488,0x000000ae,0x00050051,0x00000006,0x000005e8,0x000005e4,0x00000001, + 0x0003003e,0x000005e7,0x000005e8,0x00050041,0x00000007,0x000005e9,0x00000488,0x000000c1, + 0x00050051,0x00000006,0x000005ea,0x000005e4,0x00000002,0x0003003e,0x000005e9,0x000005ea, + 0x0004003d,0x0000002f,0x0000048e,0x00000488,0x0003003e,0x00000478,0x0000048e,0x0004003d, + 0x0000002f,0x0000048f,0x00000489,0x0003003e,0x0000047b,0x0000048f,0x0004003d,0x0000002f, + 0x00000497,0x00000478,0x0008004f,0x00000024,0x00000498,0x00000497,0x00000497,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x00000496,0x00000498,0x0003003e,0x00000499,0x0000043d, + 0x00050041,0x0000049d,0x0000049e,0x00000493,0x000000ab,0x0004003d,0x00000006,0x0000049f, + 0x0000049e,0x0003003e,0x0000049c,0x0000049f,0x00050041,0x0000049d,0x000004a1,0x00000493, + 0x000000ae,0x0004003d,0x00000006,0x000004a2,0x000004a1,0x0003003e,0x000004a0,0x000004a2, + 0x000300f7,0x00000b60,0x00000000,0x000400fa,0x00000139,0x00000b56,0x00000b5e,0x000200f8, + 0x00000b56,0x0004003d,0x0000000c,0x00000b57,0x00000499,0x0003003e,0x00000b51,0x00000b57, + 0x0004003d,0x00000006,0x00000b58,0x0000049c,0x0003003e,0x00000b52,0x00000b58,0x0004003d, + 0x00000006,0x00000b59,0x000004a0,0x0003003e,0x00000b53,0x00000b59,0x00050041,0x00000007, + 0x00000b66,0x00000b51,0x000000ab,0x0004003d,0x00000006,0x00000b67,0x00000b66,0x00050085, + 0x00000006,0x00000b68,0x00000123,0x00000b67,0x00050041,0x00000007,0x00000b69,0x00000b51, + 0x000000ae,0x0004003d,0x00000006,0x00000b6a,0x00000b69,0x00050085,0x00000006,0x00000b6b, + 0x00000127,0x00000b6a,0x00050081,0x00000006,0x00000b6c,0x00000b68,0x00000b6b,0x0006000c, + 0x00000006,0x00000b6d,0x00000001,0x0000000a,0x00000b6c,0x0003003e,0x00000b62,0x00000b6d, + 0x0004003d,0x00000006,0x00000b6e,0x00000b62,0x00050085,0x00000006,0x00000b6f,0x0000012e, + 0x00000b6e,0x0006000c,0x00000006,0x00000b70,0x00000001,0x0000000a,0x00000b6f,0x0003003e, + 0x00000b63,0x00000b70,0x0004003d,0x00000006,0x00000b71,0x00000b63,0x0004003d,0x00000006, + 0x00000b72,0x00000b52,0x00050085,0x00000006,0x00000b73,0x00000b71,0x00000b72,0x0004003d, + 0x00000006,0x00000b74,0x00000b53,0x00050081,0x00000006,0x00000b75,0x00000b73,0x00000b74, + 0x0003003e,0x00000b64,0x00000b75,0x0004003d,0x00000006,0x00000b5a,0x00000b64,0x0004003d, + 0x00000024,0x00000b5b,0x00000496,0x00060050,0x00000024,0x00000b5c,0x00000b5a,0x00000b5a, + 0x00000b5a,0x00050081,0x00000024,0x00000b5d,0x00000b5c,0x00000b5b,0x0003003e,0x00000b50, + 0x00000b5d,0x000200f9,0x00000b60,0x000200f8,0x00000b5e,0x0004003d,0x00000024,0x00000b5f, + 0x00000496,0x0003003e,0x00000b50,0x00000b5f,0x000200f9,0x00000b60,0x000200f8,0x00000b60, + 0x0004003d,0x00000024,0x00000b61,0x00000b50,0x0003003e,0x00000b54,0x00000b61,0x0004003d, + 0x00000024,0x000004a3,0x00000b54,0x00050041,0x00000007,0x000004a4,0x00000478,0x000000ab, + 0x00050051,0x00000006,0x000004a5,0x000004a3,0x00000000,0x0003003e,0x000004a4,0x000004a5, + 0x00050041,0x00000007,0x000004a6,0x00000478,0x000000ae,0x00050051,0x00000006,0x000004a7, + 0x000004a3,0x00000001,0x0003003e,0x000004a6,0x000004a7,0x00050041,0x00000007,0x000004a8, + 0x00000478,0x000000c1,0x00050051,0x00000006,0x000004a9,0x000004a3,0x00000002,0x0003003e, + 0x000004a8,0x000004a9,0x0004003d,0x0000002f,0x000004ab,0x00000478,0x0003003e,0x000004aa, + 0x000004ab,0x0004003d,0x0000002f,0x00000b77,0x000004aa,0x0003003e,0x00000437,0x00000b77, + 0x0004003d,0x0000002f,0x000004b0,0x0000047b,0x0003003e,0x000004af,0x000004b0,0x0004003d, + 0x0000002f,0x00000b79,0x000004af,0x0003003e,0x00000439,0x00000b79,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..581aebfb8f2683b94cae52fc5fd8c6a2c6a94102 GIT binary patch literal 52928 zcmZ9V1-w+{_J#*JSg0TrvD2go#f`o`5B`6{aNDI;-hy?<6cXwlVBg(bws@JZA z-GPN(<^Mi&_RIghvwv*9=Ur=k>x&(;XJ*enwO4AsN~u(5*`C0)O0_A;77Y zX|1n1DoScpR9h{SN-wIhD%J1WV@SuoorX+3Z0LxQQ-(~PHgU?((IbZpn?7ok1cy)}KECr+F)f;e(5Rm@&{)$s4+8dk$q8eF%c z{l?->t;eotpY4Y#k6BF5;I`r}McxkLNjuiqJHy3zyAiVk_Nr1(>_evv9bc|fRqFje zx^}6r^gg@SxX*#GF- zrNfEUoRV**xKGi)BP-&LlAc_Q<>(6EvC`ekZC90!{~upfX}vAI18(Sih|6tkBJ+S-NU094q+A4R0z|7gp$IVix=y zOSEl2#}k@`TpUw1TyuPp3qN)7kxSiQp<9NZ?KOB{##S00y-Nsr6A zx%@2jh2zxYg6T`0vahP_%W-l3+_Fm+k1saq3U<7d8D7$4`08m=mHlNwp}@j751jE{Dy$9ZGDGFO$E zHW>nK;`{$LYnM2$uuzZlh`CQN=MdZBwIs*|XSph9vBIa zQZVO0=iwY^=KN>o{AcFeXPzI-dCv9|gE`;X&biKfN-*a+_OE?(WcZxdTzWv**l(~M zqLuByxsUl}vCjGBd|2bFUAi#%qF~O6j=3tBbD`}Ef;lJJerNC#!Ha?y2mdShncx?K zUkZLD_|@Rof?p4QBlykWw}ameen0rb;E#eo4qg)cY4GR4Uj~02{B7{k;9r7&4_+4h zXYgOa{{$}&uHxjXg=2H&;8lay4sIB{PVlD@O{De2R{=0Sn$H&CxRCTzZU#@ z@EgJZ34Sy9t>Eh5CBdHre;WKv@OQ!A2mcuSQ}EK@UxNP$E?;C6`)w^QI0~)`t`odU z@M^(zgEt6n9K3OGli*E)Hw|tcym|1J!CM8l4&E)eZSWq!?Sk6}?-|@7xMOhV;Jt#o z1a}SIC%AiXkKmrcy@GoO_X*xFxNmU3;QfOS2<{(zVDNz8gMtSJ9~^v0@Sxzq!9#+F z1`i7!9y}s=Wbmlq(ZPoWj|m;PY6CS_@v;IgHH)QHTbmP(}T|lJ~R02;B$h{4L(2kg5V2- zFAlyW_|o9ZgRcm_D){Q)Yl3eMz9sm!;5&lv48A+~p5S|f?+d;^_<`UDgC7chIQY@v z$AT9IKNbUa!7K6MNAbG6YVc~oYXz?p zyl!x#;0=Ns2X7d>X>hY(KFM`|S_W?uylrr+;O&C958feo$KaiUcM0A#xOMPu!EJ)u z2JaEvF1UU0p1~c0I|lC++%@L|DY zg2x9>2%Z=`Ie1F&wBVV+M+P4qd`$4M!NΩ#7~KlsGplY&nUJ~jCC;4_2I4n8ON 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 E0ej4>FaQ7m literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.h new file mode 100644 index 000000000..348a29f30 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.h @@ -0,0 +1,134 @@ +#pragma once + +const uint32_t atomic_draw_atlas_blit_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000000ec,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000006b,0x0000006e,0x00000072, + 0x00000075,0x0000007e,0x00000093,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x00000041,0x0000664a,0x00040006,0x00000041,0x00000000,0x00003464, + 0x00030005,0x00000043,0x0000424c,0x00030005,0x0000005d,0x0000424d,0x00040006,0x0000005d, + 0x00000000,0x00006250,0x00040006,0x0000005d,0x00000001,0x00006359,0x00040006,0x0000005d, + 0x00000002,0x00006552,0x00040006,0x0000005d,0x00000003,0x00006553,0x00040006,0x0000005d, + 0x00000004,0x0000366d,0x00040006,0x0000005d,0x00000005,0x0000676d,0x00040006,0x0000005d, + 0x00000006,0x00006544,0x00040006,0x0000005d,0x00000007,0x00006545,0x00040006,0x0000005d, + 0x00000008,0x00003755,0x00040006,0x0000005d,0x00000009,0x0000676a,0x00040006,0x0000005d, + 0x0000000a,0x0000635a,0x00040006,0x0000005d,0x0000000b,0x00003157,0x00040006,0x0000005d, + 0x0000000c,0x0000676e,0x00040006,0x0000005d,0x0000000d,0x00003559,0x00040006,0x0000005d, + 0x0000000e,0x0000324f,0x00040006,0x0000005d,0x0000000f,0x00006461,0x00040006,0x0000005d, + 0x00000010,0x00006579,0x00040006,0x0000005d,0x00000011,0x00003376,0x00040006,0x0000005d, + 0x00000012,0x00003377,0x00040006,0x0000005d,0x00000013,0x00006462,0x00040006,0x0000005d, + 0x00000014,0x00006767,0x00030005,0x0000005f,0x0000006b,0x00060005,0x0000006b,0x565f6c67, + 0x65747265,0x646e4978,0x00007865,0x00070005,0x0000006e,0x495f6c67,0x6174736e,0x4965636e, + 0x7865646e,0x00000000,0x00030005,0x00000072,0x0000424a,0x00030005,0x00000075,0x00003243, + 0x00030005,0x0000007e,0x0000307a,0x00060005,0x00000091,0x505f6c67,0x65567265,0x78657472, + 0x00000000,0x00060006,0x00000091,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006, + 0x00000091,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000091, + 0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000091,0x00000003, + 0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000093,0x00000000,0x00030005, + 0x000000a6,0x00004342,0x00030005,0x000000a9,0x00004351,0x00030005,0x000000ac,0x00006576, + 0x00040006,0x000000ac,0x00000000,0x00003464,0x00030005,0x000000ae,0x00004355,0x00030005, + 0x000000b0,0x00006577,0x00040006,0x000000b0,0x00000000,0x00003464,0x00030005,0x000000b2, + 0x0000424f,0x00030005,0x000000b4,0x0000664b,0x00040006,0x000000b4,0x00000000,0x00003464, + 0x00030005,0x000000b6,0x00004358,0x00030005,0x000000b9,0x00003954,0x00040047,0x00000040, + 0x00000006,0x00000010,0x00030047,0x00000041,0x00000003,0x00040048,0x00000041,0x00000000, + 0x00000018,0x00050048,0x00000041,0x00000000,0x00000023,0x00000000,0x00030047,0x00000043, + 0x00000018,0x00040047,0x00000043,0x00000021,0x00000003,0x00040047,0x00000043,0x00000022, + 0x00000000,0x00030047,0x0000005d,0x00000002,0x00050048,0x0000005d,0x00000000,0x00000023, + 0x00000000,0x00050048,0x0000005d,0x00000001,0x00000023,0x00000004,0x00050048,0x0000005d, + 0x00000002,0x00000023,0x00000008,0x00050048,0x0000005d,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x0000005d,0x00000004,0x00000023,0x00000010,0x00050048,0x0000005d,0x00000005, + 0x00000023,0x00000014,0x00050048,0x0000005d,0x00000006,0x00000023,0x00000018,0x00050048, + 0x0000005d,0x00000007,0x00000023,0x0000001c,0x00050048,0x0000005d,0x00000008,0x00000023, + 0x00000020,0x00050048,0x0000005d,0x00000009,0x00000023,0x00000030,0x00050048,0x0000005d, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x0000005d,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x0000005d,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000005d,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x0000005d,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x0000005d,0x0000000f,0x00000023,0x00000050,0x00050048,0x0000005d,0x00000010,0x00000023, + 0x00000054,0x00050048,0x0000005d,0x00000011,0x00000023,0x00000058,0x00050048,0x0000005d, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x0000005d,0x00000013,0x00000023,0x00000060, + 0x00050048,0x0000005d,0x00000014,0x00000023,0x00000064,0x00040047,0x0000005f,0x00000021, + 0x00000000,0x00040047,0x0000005f,0x00000022,0x00000000,0x00040047,0x0000006b,0x0000000b, + 0x0000002a,0x00040047,0x0000006e,0x0000000b,0x0000002b,0x00040047,0x00000072,0x0000001e, + 0x00000000,0x00040047,0x00000075,0x0000001e,0x00000000,0x00030047,0x0000007e,0x00000000, + 0x00030047,0x0000007e,0x0000000e,0x00040047,0x0000007e,0x0000001e,0x00000001,0x00030047, + 0x00000091,0x00000002,0x00050048,0x00000091,0x00000000,0x0000000b,0x00000000,0x00050048, + 0x00000091,0x00000001,0x0000000b,0x00000001,0x00050048,0x00000091,0x00000002,0x0000000b, + 0x00000003,0x00050048,0x00000091,0x00000003,0x0000000b,0x00000004,0x00040047,0x000000a6, + 0x00000021,0x00000008,0x00040047,0x000000a6,0x00000022,0x00000000,0x00030047,0x000000a9, + 0x00000000,0x00040047,0x000000a9,0x00000021,0x0000000a,0x00040047,0x000000a9,0x00000022, + 0x00000000,0x00040047,0x000000ab,0x00000006,0x00000008,0x00030047,0x000000ac,0x00000003, + 0x00040048,0x000000ac,0x00000000,0x00000018,0x00050048,0x000000ac,0x00000000,0x00000023, + 0x00000000,0x00030047,0x000000ae,0x00000018,0x00040047,0x000000ae,0x00000021,0x00000004, + 0x00040047,0x000000ae,0x00000022,0x00000000,0x00040047,0x000000af,0x00000006,0x00000010, + 0x00030047,0x000000b0,0x00000003,0x00040048,0x000000b0,0x00000000,0x00000018,0x00050048, + 0x000000b0,0x00000000,0x00000023,0x00000000,0x00030047,0x000000b2,0x00000018,0x00040047, + 0x000000b2,0x00000021,0x00000005,0x00040047,0x000000b2,0x00000022,0x00000000,0x00040047, + 0x000000b3,0x00000006,0x00000010,0x00030047,0x000000b4,0x00000003,0x00040048,0x000000b4, + 0x00000000,0x00000018,0x00050048,0x000000b4,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000b6,0x00000018,0x00040047,0x000000b6,0x00000021,0x00000006,0x00040047,0x000000b6, + 0x00000022,0x00000000,0x00030047,0x000000b9,0x00000000,0x00040047,0x000000b9,0x00000021, + 0x0000000a,0x00040047,0x000000b9,0x00000022,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00030016,0x0000000c, + 0x00000020,0x00040017,0x0000000d,0x0000000c,0x00000002,0x00040017,0x00000010,0x0000000c, + 0x00000004,0x00040017,0x00000017,0x0000000c,0x00000003,0x0004002b,0x0000000c,0x00000029, + 0x3f800000,0x0004002b,0x00000006,0x0000002b,0x00000001,0x0004002b,0x0000000c,0x00000033, + 0x00000000,0x0004002b,0x00000006,0x00000037,0x00000002,0x0004002b,0x00000006,0x0000003b, + 0x0000ffff,0x00040017,0x0000003d,0x00000006,0x00000004,0x0003001d,0x00000040,0x0000003d, + 0x0003001e,0x00000041,0x00000040,0x00040020,0x00000042,0x00000002,0x00000041,0x0004003b, + 0x00000042,0x00000043,0x00000002,0x00040015,0x00000044,0x00000020,0x00000001,0x0004002b, + 0x00000044,0x00000045,0x00000000,0x0004002b,0x00000006,0x00000047,0x00000004,0x00040020, + 0x0000004a,0x00000002,0x0000003d,0x00040017,0x00000051,0x00000006,0x00000003,0x00040017, + 0x0000005c,0x00000044,0x00000004,0x0017001e,0x0000005d,0x0000000c,0x0000000c,0x0000000c, + 0x0000000c,0x00000006,0x00000006,0x00000006,0x00000006,0x0000005c,0x0000000d,0x0000000d, + 0x00000006,0x0000000c,0x00000006,0x0000000c,0x0000000c,0x00000006,0x0000000c,0x0000000c, + 0x0000000c,0x00000006,0x00040020,0x0000005e,0x00000002,0x0000005d,0x0004003b,0x0000005e, + 0x0000005f,0x00000002,0x0004002b,0x00000044,0x00000060,0x00000009,0x00040020,0x00000061, + 0x00000002,0x0000000d,0x00040020,0x0000006a,0x00000001,0x00000044,0x0004003b,0x0000006a, + 0x0000006b,0x00000001,0x0004003b,0x0000006a,0x0000006e,0x00000001,0x00040020,0x00000071, + 0x00000001,0x00000017,0x0004003b,0x00000071,0x00000072,0x00000001,0x00040020,0x00000074, + 0x00000003,0x0000000d,0x0004003b,0x00000074,0x00000075,0x00000003,0x00040020,0x0000007d, + 0x00000003,0x00000006,0x0004003b,0x0000007d,0x0000007e,0x00000003,0x0004002b,0x00000044, + 0x00000084,0x00000002,0x0004002b,0x00000044,0x00000085,0x00000003,0x00040020,0x00000089, + 0x00000002,0x0000000c,0x0004001c,0x00000090,0x0000000c,0x0000002b,0x0006001e,0x00000091, + 0x00000010,0x0000000c,0x00000090,0x00000090,0x00040020,0x00000092,0x00000003,0x00000091, + 0x0004003b,0x00000092,0x00000093,0x00000003,0x00040020,0x00000095,0x00000003,0x00000010, + 0x00090019,0x000000a4,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x000000a5,0x00000000,0x000000a4,0x0004003b,0x000000a5,0x000000a6, + 0x00000000,0x00090019,0x000000a7,0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x000000a8,0x00000000,0x000000a7,0x0004003b,0x000000a8, + 0x000000a9,0x00000000,0x00040017,0x000000aa,0x00000006,0x00000002,0x0003001d,0x000000ab, + 0x000000aa,0x0003001e,0x000000ac,0x000000ab,0x00040020,0x000000ad,0x00000002,0x000000ac, + 0x0004003b,0x000000ad,0x000000ae,0x00000002,0x0003001d,0x000000af,0x00000010,0x0003001e, + 0x000000b0,0x000000af,0x00040020,0x000000b1,0x00000002,0x000000b0,0x0004003b,0x000000b1, + 0x000000b2,0x00000002,0x0003001d,0x000000b3,0x0000003d,0x0003001e,0x000000b4,0x000000b3, + 0x00040020,0x000000b5,0x00000002,0x000000b4,0x0004003b,0x000000b5,0x000000b6,0x00000002, + 0x0002001a,0x000000b7,0x00040020,0x000000b8,0x00000000,0x000000b7,0x0004003b,0x000000b8, + 0x000000b9,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000017,0x00000077,0x00000072,0x00050051,0x0000000c,0x000000c0, + 0x00000077,0x00000002,0x0004007c,0x00000006,0x000000c1,0x000000c0,0x000500c7,0x00000006, + 0x000000c2,0x000000c1,0x0000003b,0x00050084,0x00000006,0x000000c4,0x000000c2,0x00000047, + 0x00050080,0x00000006,0x000000c5,0x000000c4,0x00000037,0x00060041,0x0000004a,0x000000c6, + 0x00000043,0x00000045,0x000000c5,0x0004003d,0x0000003d,0x000000c7,0x000000c6,0x0007004f, + 0x0000000d,0x000000c9,0x00000077,0x00000077,0x00000000,0x00000001,0x0008004f,0x00000051, + 0x000000cb,0x000000c7,0x000000c7,0x00000001,0x00000002,0x00000003,0x0004007c,0x00000017, + 0x000000cc,0x000000cb,0x00050051,0x0000000c,0x000000cf,0x000000cc,0x00000000,0x0005008e, + 0x0000000d,0x000000d0,0x000000c9,0x000000cf,0x0007004f,0x0000000d,0x000000d2,0x000000cc, + 0x000000cc,0x00000001,0x00000002,0x00050081,0x0000000d,0x000000d3,0x000000d0,0x000000d2, + 0x00050041,0x00000061,0x000000d4,0x0000005f,0x00000060,0x0004003d,0x0000000d,0x000000d5, + 0x000000d4,0x00050085,0x0000000d,0x000000d6,0x000000d3,0x000000d5,0x0003003e,0x00000075, + 0x000000d6,0x0003003e,0x0000007e,0x000000c2,0x00050041,0x00000089,0x0000008a,0x0000005f, + 0x00000084,0x0004003d,0x0000000c,0x0000008b,0x0000008a,0x00050041,0x00000089,0x0000008d, + 0x0000005f,0x00000085,0x0004003d,0x0000000c,0x0000008e,0x0000008d,0x00050051,0x0000000c, + 0x000000e0,0x00000077,0x00000000,0x00050085,0x0000000c,0x000000e2,0x000000e0,0x0000008b, + 0x00050083,0x0000000c,0x000000e3,0x000000e2,0x00000029,0x00050051,0x0000000c,0x000000e5, + 0x00000077,0x00000001,0x00050085,0x0000000c,0x000000e7,0x000000e5,0x0000008e,0x0006000c, + 0x0000000c,0x000000e9,0x00000001,0x00000006,0x0000008e,0x00050083,0x0000000c,0x000000ea, + 0x000000e7,0x000000e9,0x00070050,0x00000010,0x000000eb,0x000000e3,0x000000ea,0x00000033, + 0x00000029,0x00050041,0x00000095,0x00000096,0x00000093,0x00000045,0x0003003e,0x00000096, + 0x000000eb,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_atlas_blit.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ec43841210169eaa39452cd44efb25ec4d2fdd27 GIT binary patch literal 4140 zcmZ9O+fQ6o6vht>Q?RYQSQRyupna+&O_knEgL2JK!~lgVHR>=h2OK&KIG55kYHEZB zH8v`#e?hIcs(9D8YShNqMC0w*XpHgl2l!&@_d91V&W^iT-Rt|-ZSQ^d+C!>-M`IAw z1sj5<;O`(FTZ4Krfw*+Vr&G{N!vnRh8cc{QAbn zvX$K2LNP2C!%8Jv4Np{S^4lh(Sslz(74(1|oeI`#5)9%NygjjBBfRM0ZNigY z{I$X}s?RxRrE|B^IxXgzV)nkUtgCRSln+n9H%9kP{Gn2%nk!9(&JxFS9|zob;$HS> z-Q?wdp3==G?+bC>;jkR178D!v=*m4jUny|s#5P9$eA9?8l&YhJQ`#*tv5oI5TTijD z&|8Stv}WU5W2+U5Yc|%iLIMr+^P0PRV*NGgBTl~{ox9AvL1)-~d`tQf=eH_-(fOe> z%3jv8>>ZR3c6V=u;~ z9mgFsj{V|i`(iEh9Ncz^`B4w9)#KDS)8kkxT(8H`i*WrOM?b<1 zdK^6oH|%lj6K>4o=uNnBkE1`~9`rbR6mG)fI3qZ>EFN89(j<_lAD9dxOrP4ufw6hc6tnam2u-JPsX> zyFx8`lRfgS4JUg{1@tQe8#=yxZ^MaiL-2-p?pB;D74>vnJLzw`bJp*iH-mlB^VrFa zPAyv}*st}ru-~_5Y1TJH(_wRl^s7COUf8TM=O_E;@+ zYLSmx;G|Y6;B8`HL-)@cY`)ucBkChNf04xZ<2uEVw^hQpUKV<;RnjaQy#^)@O#gs6 zV{o&>FT&9S{*I>YSxnU3-sJ}7+UN}Rt#IytC!v)0zB8LmZo zmu7IQtlgSfBiuoUdmP6ed!@HZ>LkalA!f;y%!f4;*n|-X6G{^#4bi@%vaa1B@To z-lTncA@OgJF!&b#h)HYi5X&7~lyJXB#B!DwC2+(&CLhk`Q^`fiCHa6qlfdy-EIICT z$J58B9ruNF`2CVDMGk2GQqm*olVE2Z?EjJk+mQaU;ckB=VI2sgPBNrlsu9g!OYleF zSu1;Ez0I00OYpHhed9Py!5OWM{NGBbfz4`uC!JWt@;>SOzZXXgK3(E+ntzb+7EDOk z2YG*#z%RSFpQIBDf0tHS(+r1BUvie@qwk)PkZ(ysKEB7Z5_t1@PC7oz67xAD9p3i) zvvfN*)W%5lF+huw>=W^rc# literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.h new file mode 100644 index 000000000..b3b427288 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.h @@ -0,0 +1,527 @@ +#pragma once + +const uint32_t atomic_draw_image_mesh_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000431,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000165, + 0x000001ed,0x000001fb,0x00000202,0x00000281,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000c3,0x0000674e, + 0x00030005,0x000000fb,0x00006576,0x00040006,0x000000fb,0x00000000,0x00003464,0x00030005, + 0x000000fd,0x00004355,0x00030005,0x0000010e,0x0000674b,0x00030005,0x00000129,0x00006747, + 0x00040005,0x00000137,0x30653742,0x00000000,0x00030005,0x00000142,0x00006748,0x00030005, + 0x00000150,0x00006577,0x00040006,0x00000150,0x00000000,0x00003464,0x00030005,0x00000152, + 0x0000424f,0x00060005,0x00000165,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x000001d0,0x00004444,0x00030005,0x000001d4,0x00006277,0x00030005,0x000001ed,0x00003065, + 0x00030005,0x000001ef,0x00000045,0x00030005,0x000001f4,0x00003478,0x00030005,0x000001f5, + 0x00004344,0x00030005,0x000001f7,0x00003552,0x00030005,0x000001fb,0x00003055,0x00030005, + 0x000001fe,0x00003553,0x00030005,0x00000201,0x00003456,0x00030005,0x00000202,0x0000304e, + 0x00040005,0x00000203,0x61726170,0x0000006d,0x00040005,0x00000206,0x61726170,0x0000006d, + 0x00040005,0x00000209,0x61726170,0x0000006d,0x00030005,0x0000020d,0x00003270,0x00030005, + 0x00000210,0x00003470,0x00030005,0x00000216,0x00003145,0x00040005,0x0000021a,0x61726170, + 0x0000006d,0x00040005,0x0000021c,0x61726170,0x0000006d,0x00030005,0x0000021f,0x0000394a, + 0x00040005,0x00000223,0x61726170,0x0000006d,0x00030005,0x00000225,0x00003171,0x00040005, + 0x00000226,0x61726170,0x0000006d,0x00030005,0x00000228,0x00000050,0x00040005,0x00000229, + 0x61726170,0x0000006d,0x00040005,0x0000022b,0x61726170,0x0000006d,0x00040005,0x0000022d, + 0x61726170,0x0000006d,0x00040005,0x0000022e,0x61726170,0x0000006d,0x00030005,0x00000237, + 0x0000434c,0x00040006,0x00000237,0x00000000,0x00003479,0x00040006,0x00000237,0x00000001, + 0x00003056,0x00030005,0x00000239,0x00003041,0x00030005,0x00000242,0x0000304f,0x00040005, + 0x0000024e,0x61726170,0x0000006d,0x00040005,0x00000251,0x61726170,0x0000006d,0x00040005, + 0x00000253,0x61726170,0x0000006d,0x00040005,0x00000259,0x61726170,0x0000006d,0x00030005, + 0x00000269,0x0000424d,0x00040006,0x00000269,0x00000000,0x00003376,0x00040006,0x00000269, + 0x00000001,0x00003377,0x00030005,0x0000026b,0x0000006b,0x00040005,0x0000026e,0x61726170, + 0x0000006d,0x00040005,0x00000271,0x61726170,0x0000006d,0x00040005,0x00000274,0x61726170, + 0x0000006d,0x00040005,0x00000277,0x61726170,0x0000006d,0x00030005,0x00000281,0x0000316d, + 0x00040005,0x00000283,0x61726170,0x0000006d,0x00040047,0x000000c3,0x00000001,0x00000007, + 0x00040047,0x000000fa,0x00000006,0x00000008,0x00030047,0x000000fb,0x00000003,0x00040048, + 0x000000fb,0x00000000,0x00000018,0x00050048,0x000000fb,0x00000000,0x00000023,0x00000000, + 0x00030047,0x000000fd,0x00000018,0x00040047,0x000000fd,0x00000021,0x00000004,0x00040047, + 0x000000fd,0x00000022,0x00000000,0x00040047,0x0000010e,0x00000001,0x00000004,0x00040047, + 0x00000129,0x00000001,0x00000000,0x00030047,0x00000137,0x00000000,0x00040047,0x00000137, + 0x00000021,0x00000001,0x00040047,0x00000137,0x00000022,0x00000002,0x00040047,0x00000137, + 0x0000002b,0x00000001,0x00040047,0x00000142,0x00000001,0x00000001,0x00040047,0x0000014f, + 0x00000006,0x00000010,0x00030047,0x00000150,0x00000003,0x00040048,0x00000150,0x00000000, + 0x00000018,0x00050048,0x00000150,0x00000000,0x00000023,0x00000000,0x00030047,0x00000152, + 0x00000018,0x00040047,0x00000152,0x00000021,0x00000005,0x00040047,0x00000152,0x00000022, + 0x00000000,0x00040047,0x00000165,0x0000000b,0x0000000f,0x00030047,0x000001d0,0x00000000, + 0x00040047,0x000001d0,0x00000021,0x00000009,0x00040047,0x000001d0,0x00000022,0x00000000, + 0x00030047,0x000001d4,0x00000000,0x00040047,0x000001d4,0x00000021,0x00000009,0x00040047, + 0x000001d4,0x00000022,0x00000000,0x00030047,0x000001ed,0x00000000,0x00040047,0x000001ed, + 0x0000001e,0x00000001,0x00030047,0x000001f4,0x00000000,0x00030047,0x000001f5,0x00000000, + 0x00040047,0x000001f5,0x00000021,0x0000000c,0x00040047,0x000001f5,0x00000022,0x00000001, + 0x00030047,0x000001f6,0x00000000,0x00030047,0x000001f7,0x00000000,0x00040047,0x000001f7, + 0x00000021,0x0000000c,0x00040047,0x000001f7,0x00000022,0x00000001,0x00030047,0x000001f8, + 0x00000000,0x00040047,0x000001fb,0x0000001e,0x00000000,0x00030047,0x000001fd,0x00000000, + 0x00030047,0x000001fe,0x00000000,0x00030047,0x00000201,0x00000000,0x00040047,0x00000202, + 0x0000001e,0x00000001,0x00030047,0x00000206,0x00000000,0x00030047,0x00000208,0x00000000, + 0x00030047,0x00000209,0x00000000,0x00030047,0x0000020b,0x00000000,0x00030047,0x0000020c, + 0x00000000,0x00030047,0x00000210,0x00000017,0x00040047,0x00000210,0x00000021,0x00000003, + 0x00040047,0x00000210,0x00000022,0x00000002,0x00030047,0x00000216,0x00000000,0x00030047, + 0x0000021c,0x00000000,0x00030047,0x0000021d,0x00000000,0x00030047,0x0000021f,0x00000000, + 0x00030047,0x00000225,0x00000000,0x00030047,0x00000226,0x00000000,0x00030047,0x00000228, + 0x00000000,0x00030047,0x0000022a,0x00000000,0x00030047,0x0000022b,0x00000000,0x00030047, + 0x0000022c,0x00000000,0x00030047,0x0000022d,0x00000000,0x00030047,0x0000022e,0x00000000, + 0x00030047,0x0000022f,0x00000000,0x00030047,0x00000237,0x00000002,0x00050048,0x00000237, + 0x00000000,0x00000023,0x00000018,0x00050048,0x00000237,0x00000001,0x00000023,0x00000038, + 0x00040047,0x00000239,0x00000021,0x00000002,0x00040047,0x00000239,0x00000022,0x00000000, + 0x00030047,0x00000242,0x00000000,0x00030047,0x00000244,0x00000000,0x00030047,0x00000246, + 0x00000000,0x00030047,0x00000249,0x00000000,0x00030047,0x0000024b,0x00000000,0x00030047, + 0x0000024c,0x00000000,0x00030047,0x0000024d,0x00000000,0x00030047,0x00000251,0x00000000, + 0x00030047,0x00000252,0x00000000,0x00030047,0x00000253,0x00000000,0x00030047,0x00000254, + 0x00000000,0x00030047,0x00000257,0x00000000,0x00030047,0x0000025e,0x00000000,0x00030047, + 0x0000025f,0x00000000,0x00030047,0x00000260,0x00000000,0x00030047,0x00000261,0x00000000, + 0x00030047,0x00000263,0x00000000,0x00030047,0x00000264,0x00000000,0x00030047,0x00000265, + 0x00000000,0x00030047,0x00000266,0x00000000,0x00030047,0x00000267,0x00000000,0x00030047, + 0x00000269,0x00000002,0x00050048,0x00000269,0x00000000,0x00000023,0x00000058,0x00050048, + 0x00000269,0x00000001,0x00000023,0x0000005c,0x00040047,0x0000026b,0x00000021,0x00000000, + 0x00040047,0x0000026b,0x00000022,0x00000000,0x00030047,0x0000026e,0x00000000,0x00030047, + 0x0000026f,0x00000000,0x00030047,0x00000270,0x00000000,0x00030047,0x00000274,0x00000000, + 0x00030047,0x00000277,0x00000000,0x00030047,0x00000281,0x00000000,0x00040047,0x00000281, + 0x0000001e,0x00000000,0x00030047,0x00000282,0x00000000,0x00030047,0x00000283,0x00000000, + 0x00030047,0x00000284,0x00000000,0x00030047,0x00000296,0x00000000,0x00030047,0x00000297, + 0x00000000,0x00030047,0x0000029a,0x00000000,0x00030047,0x0000029b,0x00000000,0x00030047, + 0x0000029c,0x00000000,0x00030047,0x0000029d,0x00000000,0x00030047,0x0000029f,0x00000000, + 0x00030047,0x000002a0,0x00000000,0x00030047,0x000002a1,0x00000000,0x00030047,0x000002a2, + 0x00000000,0x00030047,0x000002a3,0x00000000,0x00030047,0x000002a5,0x00000000,0x00030047, + 0x000002a7,0x00000000,0x00030047,0x000002a8,0x00000000,0x00030047,0x000002a9,0x00000000, + 0x00030047,0x000002aa,0x00000000,0x00030047,0x000002ac,0x00000000,0x00030047,0x000002ad, + 0x00000000,0x00030047,0x000002ae,0x00000000,0x00030047,0x000002b1,0x00000000,0x00030047, + 0x000002b2,0x00000000,0x00030047,0x000002b4,0x00000000,0x00030047,0x000002b6,0x00000000, + 0x00030047,0x000002bd,0x00000000,0x00030047,0x000002be,0x00000000,0x00030047,0x000002c1, + 0x00000000,0x00030047,0x000002c2,0x00000000,0x00030047,0x000002c3,0x00000000,0x00030047, + 0x000002c5,0x00000000,0x00030047,0x000002c7,0x00000000,0x00030047,0x000002c9,0x00000000, + 0x00030047,0x000002cb,0x00000000,0x00030047,0x000002cd,0x00000000,0x00030047,0x000002cf, + 0x00000000,0x00030047,0x000002d0,0x00000000,0x00030047,0x000002d1,0x00000000,0x00030047, + 0x000002d4,0x00000000,0x00030047,0x000002d5,0x00000000,0x00030047,0x000002da,0x00000000, + 0x00030047,0x000002dc,0x00000000,0x00030047,0x000002de,0x00000000,0x00030047,0x000002eb, + 0x00000000,0x00030047,0x000002f1,0x00000000,0x00030047,0x000002f2,0x00000000,0x00030047, + 0x000002fb,0x00000000,0x00030047,0x000002fc,0x00000000,0x00030047,0x000002fd,0x00000000, + 0x00030047,0x000002fe,0x00000000,0x00030047,0x000002ff,0x00000000,0x00030047,0x00000300, + 0x00000000,0x00030047,0x00000301,0x00000000,0x00030047,0x00000304,0x00000000,0x00030047, + 0x00000307,0x00000000,0x00030047,0x0000030f,0x00000000,0x00030047,0x00000310,0x00000000, + 0x00030047,0x00000312,0x00000000,0x00030047,0x0000033b,0x00000000,0x00030047,0x0000033d, + 0x00000000,0x00030047,0x0000033e,0x00000000,0x00030047,0x0000033f,0x00000000,0x00030047, + 0x00000340,0x00000000,0x00030047,0x00000341,0x00000000,0x00030047,0x00000342,0x00000000, + 0x00030047,0x00000343,0x00000000,0x00030047,0x00000352,0x00000000,0x00030047,0x00000358, + 0x00000000,0x00030047,0x00000385,0x00000000,0x00030047,0x00000386,0x00000000,0x00030047, + 0x0000038b,0x00000000,0x00030047,0x0000038d,0x00000000,0x00030047,0x0000038f,0x00000000, + 0x00030047,0x00000390,0x00000000,0x00030047,0x00000393,0x00000000,0x00030047,0x00000394, + 0x00000000,0x00030047,0x00000395,0x00000000,0x00030047,0x00000396,0x00000000,0x00030047, + 0x0000039d,0x00000000,0x00030047,0x0000039f,0x00000000,0x00030047,0x000003a0,0x00000000, + 0x00030047,0x000003a2,0x00000000,0x00030047,0x000003a3,0x00000000,0x00030047,0x000003a5, + 0x00000000,0x00030047,0x000003a6,0x00000000,0x00030047,0x000003b0,0x00000000,0x00030047, + 0x000003b2,0x00000000,0x00030047,0x000003b3,0x00000000,0x00030047,0x000003b6,0x00000000, + 0x00030047,0x000003b7,0x00000000,0x00030047,0x000003b9,0x00000000,0x00030047,0x000003bb, + 0x00000000,0x00030047,0x000003bd,0x00000000,0x00030047,0x000003cb,0x00000000,0x00030047, + 0x000003cc,0x00000000,0x00030047,0x000003cf,0x00000000,0x00030047,0x000003d0,0x00000000, + 0x00030047,0x000003d1,0x00000000,0x00030047,0x000003d3,0x00000000,0x00030047,0x000003d5, + 0x00000000,0x00030047,0x000003d7,0x00000000,0x00030047,0x000003d9,0x00000000,0x00030047, + 0x000003db,0x00000000,0x00030047,0x000003e9,0x00000000,0x00030047,0x000003eb,0x00000000, + 0x00030047,0x000003ec,0x00000000,0x00030047,0x000003f6,0x00000000,0x00030047,0x000003f8, + 0x00000000,0x00030047,0x000003f9,0x00000000,0x00030047,0x000003fc,0x00000000,0x00030047, + 0x000003fd,0x00000000,0x00030047,0x000003ff,0x00000000,0x00030047,0x00000401,0x00000000, + 0x00030047,0x00000403,0x00000000,0x00030047,0x00000404,0x00000000,0x00030047,0x00000405, + 0x00000000,0x00030047,0x00000408,0x00000000,0x00030047,0x00000409,0x00000000,0x00030047, + 0x0000040b,0x00000000,0x00030047,0x0000040c,0x00000000,0x00030047,0x0000040d,0x00000000, + 0x00030047,0x00000411,0x00000000,0x00030047,0x00000412,0x00000000,0x00030047,0x00000414, + 0x00000000,0x00030047,0x00000415,0x00000000,0x00030047,0x00000416,0x00000000,0x00030047, + 0x00000418,0x00000000,0x00030047,0x0000041a,0x00000000,0x00030047,0x0000041b,0x00000000, + 0x00030047,0x0000041c,0x00000000,0x00030047,0x0000041d,0x00000000,0x00030047,0x00000427, + 0x00000000,0x00030047,0x00000428,0x00000000,0x00030047,0x00000429,0x00000000,0x00030047, + 0x0000042a,0x00000000,0x00030047,0x0000042b,0x00000000,0x00030047,0x0000042c,0x00000000, + 0x00030047,0x0000042d,0x00000000,0x00030047,0x0000042e,0x00000000,0x00030047,0x00000430, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, + 0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017,0x0000000c,0x00000006, + 0x00000004,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040017,0x00000012,0x00000006, + 0x00000002,0x00040020,0x00000013,0x00000007,0x00000012,0x00040015,0x00000018,0x00000020, + 0x00000000,0x00040020,0x00000019,0x00000007,0x00000018,0x00040018,0x00000029,0x00000012, + 0x00000002,0x00040017,0x00000038,0x00000006,0x00000003,0x00040020,0x00000039,0x00000007, + 0x00000038,0x00040015,0x0000004e,0x00000020,0x00000001,0x00040017,0x0000004f,0x0000004e, + 0x00000002,0x00040020,0x00000050,0x00000007,0x0000004f,0x0004002b,0x00000018,0x00000077, + 0x00000000,0x0004002b,0x00000018,0x0000007a,0x00000001,0x0004002b,0x00000018,0x00000085, + 0x00000002,0x0004002b,0x00000018,0x00000088,0x00000003,0x0004002b,0x00000006,0x00000091, + 0x3f800000,0x0004002b,0x00000006,0x00000092,0x00000000,0x0004002b,0x00000006,0x000000ac, + 0x3d897143,0x0004002b,0x00000006,0x000000b0,0x3bbf4590,0x0004002b,0x00000006,0x000000b7, + 0x4253ee82,0x00020014,0x000000c2,0x00030030,0x000000c2,0x000000c3,0x0004002b,0x00000006, + 0x000000d8,0x3a000000,0x0004002b,0x00000006,0x000000da,0xc2000000,0x0004002b,0x00000006, + 0x000000ea,0x3a808081,0x00040017,0x000000ed,0x000000c2,0x00000002,0x00040017,0x000000f7, + 0x00000018,0x00000002,0x00040020,0x000000f8,0x00000007,0x000000f7,0x0003001d,0x000000fa, + 0x000000f7,0x0003001e,0x000000fb,0x000000fa,0x00040020,0x000000fc,0x00000002,0x000000fb, + 0x0004003b,0x000000fc,0x000000fd,0x00000002,0x0004002b,0x0000004e,0x000000fe,0x00000000, + 0x00040020,0x00000100,0x00000002,0x000000f7,0x0004002b,0x00000018,0x00000107,0x00000300, + 0x00030030,0x000000c2,0x0000010e,0x0004002b,0x00000018,0x00000113,0x00000200,0x0004002b, + 0x00000006,0x0000011a,0x3f000000,0x0004002b,0x00000006,0x0000011d,0x40000000,0x0004002b, + 0x00000006,0x0000011f,0xbf800000,0x00030030,0x000000c2,0x00000129,0x0004002b,0x00000018, + 0x0000012f,0x00000010,0x00090019,0x00000135,0x00000006,0x00000006,0x00000000,0x00000000, + 0x00000000,0x00000002,0x00000000,0x00040020,0x00000136,0x00000000,0x00000135,0x0004003b, + 0x00000136,0x00000137,0x00000000,0x0005002c,0x0000004f,0x00000139,0x000000fe,0x000000fe, + 0x00030030,0x000000c2,0x00000142,0x0004002b,0x00000018,0x00000147,0x00000400,0x00040020, + 0x0000014d,0x00000007,0x00000029,0x0003001d,0x0000014f,0x0000000c,0x0003001e,0x00000150, + 0x0000014f,0x00040020,0x00000151,0x00000002,0x00000150,0x0004003b,0x00000151,0x00000152, + 0x00000002,0x0004002b,0x00000018,0x00000154,0x00000004,0x00040020,0x00000158,0x00000002, + 0x0000000c,0x00040020,0x00000164,0x00000001,0x0000000c,0x0004003b,0x00000164,0x00000165, + 0x00000001,0x0004002b,0x00000018,0x00000185,0x0000000f,0x00090019,0x000001ce,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000001cf, + 0x00000000,0x000001ce,0x0004003b,0x000001cf,0x000001d0,0x00000000,0x0002001a,0x000001d2, + 0x00040020,0x000001d3,0x00000000,0x000001d2,0x0004003b,0x000001d3,0x000001d4,0x00000000, + 0x0003001b,0x000001d6,0x000001ce,0x00040020,0x000001ec,0x00000003,0x0000000c,0x0004003b, + 0x000001ec,0x000001ed,0x00000003,0x0004003b,0x000001cf,0x000001f5,0x00000000,0x0004003b, + 0x000001d3,0x000001f7,0x00000000,0x00040020,0x000001fa,0x00000001,0x00000012,0x0004003b, + 0x000001fa,0x000001fb,0x00000001,0x0004003b,0x00000164,0x00000202,0x00000001,0x00090019, + 0x0000020e,0x00000018,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000021, + 0x00040020,0x0000020f,0x00000000,0x0000020e,0x0004003b,0x0000020f,0x00000210,0x00000000, + 0x00040017,0x00000213,0x00000018,0x00000004,0x0004002b,0x00000018,0x00000218,0x00000011, + 0x0004002b,0x00000018,0x00000221,0x0001ffff,0x0004001e,0x00000237,0x00000006,0x00000018, + 0x00040020,0x00000238,0x00000002,0x00000237,0x0004003b,0x00000238,0x00000239,0x00000002, + 0x00040020,0x0000023b,0x00000002,0x00000018,0x00040020,0x0000025a,0x00000002,0x00000006, + 0x0004001e,0x00000269,0x00000006,0x00000006,0x00040020,0x0000026a,0x00000002,0x00000269, + 0x0004003b,0x0000026a,0x0000026b,0x00000002,0x0004003b,0x000001ec,0x00000281,0x00000003, + 0x0004002b,0x00000018,0x0000028a,0x00010000,0x0007002c,0x00000213,0x0000028b,0x0000028a, + 0x0000028a,0x0000028a,0x0000028a,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003b,0x00000007,0x0000041b,0x00000007,0x0004003b,0x00000007, + 0x0000041c,0x00000007,0x0004003b,0x00000007,0x0000041d,0x00000007,0x0004003b,0x00000039, + 0x00000409,0x00000007,0x0004003b,0x00000013,0x0000040a,0x00000007,0x0004003b,0x00000007, + 0x0000040b,0x00000007,0x0004003b,0x00000007,0x0000040c,0x00000007,0x0004003b,0x00000039, + 0x0000040d,0x00000007,0x0004003b,0x00000007,0x00000404,0x00000007,0x0004003b,0x00000007, + 0x00000405,0x00000007,0x0004003b,0x00000013,0x000003fc,0x00000007,0x0004003b,0x00000013, + 0x000003fd,0x00000007,0x0004003b,0x00000007,0x000003e9,0x00000007,0x0004003b,0x0000014d, + 0x000003dc,0x00000007,0x0004003b,0x0000000d,0x000003d0,0x00000007,0x0004003b,0x0000000d, + 0x000003d1,0x00000007,0x0004003b,0x00000013,0x000003cb,0x00000007,0x0004003b,0x00000013, + 0x000003cc,0x00000007,0x0004003b,0x0000014d,0x000003be,0x00000007,0x0004003b,0x00000013, + 0x000003b6,0x00000007,0x0004003b,0x00000013,0x000003b7,0x00000007,0x0004003b,0x00000007, + 0x000003a3,0x00000007,0x0004003b,0x00000007,0x000003a0,0x00000007,0x0004003b,0x00000007, + 0x0000039d,0x00000007,0x0004003b,0x000000f8,0x000002ce,0x00000007,0x0004003b,0x00000007, + 0x000002cf,0x00000007,0x0004003b,0x00000007,0x000002d0,0x00000007,0x0004003b,0x00000007, + 0x000002d1,0x00000007,0x0004003b,0x00000019,0x000002d2,0x00000007,0x0004003b,0x00000019, + 0x000002d3,0x00000007,0x0004003b,0x0000000d,0x000002d4,0x00000007,0x0004003b,0x00000007, + 0x000002d5,0x00000007,0x0004003b,0x0000014d,0x000002d6,0x00000007,0x0004003b,0x0000000d, + 0x000002d7,0x00000007,0x0004003b,0x0000000d,0x000002d8,0x00000007,0x0004003b,0x00000013, + 0x000002d9,0x00000007,0x0004003b,0x00000013,0x000002da,0x00000007,0x0004003b,0x00000013, + 0x000002db,0x00000007,0x0004003b,0x00000007,0x000002dc,0x00000007,0x0004003b,0x00000019, + 0x000002dd,0x00000007,0x0004003b,0x00000007,0x000002de,0x00000007,0x0004003b,0x0000014d, + 0x000002df,0x00000007,0x0004003b,0x0000000d,0x000002e0,0x00000007,0x0004003b,0x0000000d, + 0x000002e1,0x00000007,0x0004003b,0x00000013,0x000002e2,0x00000007,0x0004003b,0x00000007, + 0x000002e3,0x00000007,0x0004003b,0x00000007,0x000002e4,0x00000007,0x0004003b,0x00000007, + 0x000002e5,0x00000007,0x0004003b,0x00000007,0x000002e6,0x00000007,0x0004003b,0x0000000d, + 0x000002c2,0x00000007,0x0004003b,0x0000000d,0x000002c3,0x00000007,0x0004003b,0x00000007, + 0x000002bd,0x00000007,0x0004003b,0x00000007,0x000002be,0x00000007,0x0004003b,0x00000007, + 0x000002b5,0x00000007,0x0004003b,0x00000007,0x000002b6,0x00000007,0x0004003b,0x00000019, + 0x000002b2,0x00000007,0x0004003b,0x00000019,0x000002ad,0x00000007,0x0004003b,0x00000019, + 0x000002ae,0x00000007,0x0004003b,0x00000007,0x000002aa,0x00000007,0x0004003b,0x00000013, + 0x0000029b,0x00000007,0x0004003b,0x00000007,0x0000029c,0x00000007,0x0004003b,0x00000007, + 0x0000029d,0x00000007,0x0004003b,0x0000000d,0x00000296,0x00000007,0x0004003b,0x0000000d, + 0x00000297,0x00000007,0x0004003b,0x00000050,0x000001ef,0x00000007,0x0004003b,0x0000000d, + 0x000001f4,0x00000007,0x0004003b,0x00000007,0x000001fe,0x00000007,0x0004003b,0x00000007, + 0x00000201,0x00000007,0x0004003b,0x0000000d,0x00000203,0x00000007,0x0004003b,0x0000000d, + 0x00000206,0x00000007,0x0004003b,0x00000007,0x00000209,0x00000007,0x0004003b,0x00000019, + 0x0000020d,0x00000007,0x0004003b,0x00000019,0x00000216,0x00000007,0x0004003b,0x00000019, + 0x0000021a,0x00000007,0x0004003b,0x00000019,0x0000021c,0x00000007,0x0004003b,0x00000007, + 0x0000021f,0x00000007,0x0004003b,0x00000019,0x00000223,0x00000007,0x0004003b,0x0000000d, + 0x00000225,0x00000007,0x0004003b,0x00000007,0x00000226,0x00000007,0x0004003b,0x0000000d, + 0x00000228,0x00000007,0x0004003b,0x00000019,0x00000229,0x00000007,0x0004003b,0x00000007, + 0x0000022b,0x00000007,0x0004003b,0x0000000d,0x0000022d,0x00000007,0x0004003b,0x0000000d, + 0x0000022e,0x00000007,0x0004003b,0x0000000d,0x00000242,0x00000007,0x0004003b,0x0000000d, + 0x00000246,0x00000007,0x0004003b,0x00000019,0x0000024e,0x00000007,0x0004003b,0x0000000d, + 0x00000251,0x00000007,0x0004003b,0x00000007,0x00000253,0x00000007,0x0004003b,0x00000007, + 0x00000259,0x00000007,0x0004003b,0x00000039,0x0000026e,0x00000007,0x0004003b,0x00000013, + 0x00000271,0x00000007,0x0004003b,0x00000007,0x00000274,0x00000007,0x0004003b,0x00000007, + 0x00000277,0x00000007,0x0004003b,0x0000000d,0x00000283,0x00000007,0x0004003d,0x0000000c, + 0x000001f0,0x00000165,0x0007004f,0x00000012,0x000001f1,0x000001f0,0x000001f0,0x00000000, + 0x00000001,0x0006000c,0x00000012,0x000001f2,0x00000001,0x00000008,0x000001f1,0x0004006e, + 0x0000004f,0x000001f3,0x000001f2,0x0003003e,0x000001ef,0x000001f3,0x0004003d,0x000001ce, + 0x000001f6,0x000001f5,0x0004003d,0x000001d2,0x000001f8,0x000001f7,0x00050056,0x000001d6, + 0x000001f9,0x000001f6,0x000001f8,0x0004003d,0x00000012,0x000001fc,0x000001fb,0x00050057, + 0x0000000c,0x000001fd,0x000001f9,0x000001fc,0x0003003e,0x000001f4,0x000001fd,0x0003003e, + 0x000001fe,0x00000091,0x000300f7,0x00000200,0x00000000,0x000400fa,0x00000142,0x000001ff, + 0x00000200,0x000200f8,0x000001ff,0x0004003d,0x0000000c,0x00000204,0x00000202,0x0003003e, + 0x00000203,0x00000204,0x0004003d,0x0000000c,0x00000299,0x00000203,0x0003003e,0x00000296, + 0x00000299,0x0004003d,0x0000000c,0x0000029a,0x00000296,0x0003003e,0x00000297,0x0000029a, + 0x0004003d,0x0000000c,0x00000205,0x00000297,0x0003003e,0x00000206,0x00000205,0x0004003d, + 0x0000000c,0x0000029f,0x00000206,0x0007004f,0x00000012,0x000002a0,0x0000029f,0x0000029f, + 0x00000000,0x00000001,0x0004003d,0x0000000c,0x000002a1,0x00000206,0x0007004f,0x00000012, + 0x000002a2,0x000002a1,0x000002a1,0x00000002,0x00000003,0x0007000c,0x00000012,0x000002a3, + 0x00000001,0x00000025,0x000002a0,0x000002a2,0x0003003e,0x0000029b,0x000002a3,0x00050041, + 0x00000007,0x000002a4,0x0000029b,0x00000077,0x0004003d,0x00000006,0x000002a5,0x000002a4, + 0x00050041,0x00000007,0x000002a6,0x0000029b,0x0000007a,0x0004003d,0x00000006,0x000002a7, + 0x000002a6,0x0007000c,0x00000006,0x000002a8,0x00000001,0x00000025,0x000002a5,0x000002a7, + 0x0003003e,0x0000029c,0x000002a8,0x0004003d,0x00000006,0x000002a9,0x0000029c,0x0003003e, + 0x0000029d,0x000002a9,0x0004003d,0x00000006,0x00000207,0x0000029d,0x0003003e,0x00000201, + 0x00000207,0x0004003d,0x00000006,0x00000208,0x00000201,0x0003003e,0x00000209,0x00000092, + 0x0004003d,0x00000006,0x000002ac,0x00000209,0x0003003e,0x000002aa,0x000002ac,0x0004003d, + 0x00000006,0x0000020a,0x000002aa,0x0004003d,0x00000006,0x0000020b,0x000001fe,0x0008000c, + 0x00000006,0x0000020c,0x00000001,0x0000002b,0x00000208,0x0000020a,0x0000020b,0x0003003e, + 0x000001fe,0x0000020c,0x000200f9,0x00000200,0x000200f8,0x00000200,0x0004003d,0x0000020e, + 0x00000211,0x00000210,0x0004003d,0x0000004f,0x00000212,0x000001ef,0x00050062,0x00000213, + 0x00000214,0x00000211,0x00000212,0x00050051,0x00000018,0x00000215,0x00000214,0x00000000, + 0x0003003e,0x0000020d,0x00000215,0x0004003d,0x00000018,0x00000217,0x0000020d,0x000500c2, + 0x00000018,0x00000219,0x00000217,0x00000218,0x0003003e,0x0000021a,0x00000219,0x0004003d, + 0x00000018,0x000002b0,0x0000021a,0x0003003e,0x000002ad,0x000002b0,0x0004003d,0x00000018, + 0x000002b1,0x000002ad,0x0003003e,0x000002ae,0x000002b1,0x0004003d,0x00000018,0x0000021b, + 0x000002ae,0x0003003e,0x00000216,0x0000021b,0x0004003d,0x00000018,0x0000021d,0x00000216, + 0x0003003e,0x0000021c,0x0000021d,0x0004003d,0x00000018,0x000002b4,0x0000021c,0x0003003e, + 0x000002b2,0x000002b4,0x0004003d,0x00000018,0x0000021e,0x000002b2,0x0003003e,0x00000216, + 0x0000021e,0x0004003d,0x00000018,0x00000220,0x0000020d,0x000500c7,0x00000018,0x00000222, + 0x00000220,0x00000221,0x0003003e,0x00000223,0x00000222,0x0004003d,0x00000018,0x000002b8, + 0x00000223,0x00040070,0x00000006,0x000002b9,0x000002b8,0x00050085,0x00000006,0x000002ba, + 0x000002b9,0x000000d8,0x00050081,0x00000006,0x000002bb,0x000002ba,0x000000da,0x0003003e, + 0x000002b5,0x000002bb,0x0004003d,0x00000006,0x000002c0,0x000002b5,0x0003003e,0x000002bd, + 0x000002c0,0x0004003d,0x00000006,0x000002c1,0x000002bd,0x0003003e,0x000002be,0x000002c1, + 0x0004003d,0x00000006,0x000002bc,0x000002be,0x0003003e,0x000002b6,0x000002bc,0x0004003d, + 0x00000006,0x00000224,0x000002b6,0x0003003e,0x0000021f,0x00000224,0x0003003e,0x00000226, + 0x00000092,0x0004003d,0x00000006,0x000002c5,0x00000226,0x00050041,0x00000007,0x000002c6, + 0x000002c2,0x00000077,0x0003003e,0x000002c6,0x000002c5,0x0004003d,0x00000006,0x000002c7, + 0x00000226,0x00050041,0x00000007,0x000002c8,0x000002c2,0x0000007a,0x0003003e,0x000002c8, + 0x000002c7,0x0004003d,0x00000006,0x000002c9,0x00000226,0x00050041,0x00000007,0x000002ca, + 0x000002c2,0x00000085,0x0003003e,0x000002ca,0x000002c9,0x0004003d,0x00000006,0x000002cb, + 0x00000226,0x00050041,0x00000007,0x000002cc,0x000002c2,0x00000088,0x0003003e,0x000002cc, + 0x000002cb,0x0004003d,0x0000000c,0x000002cd,0x000002c2,0x0003003e,0x000002c3,0x000002cd, + 0x0004003d,0x0000000c,0x00000227,0x000002c3,0x0003003e,0x00000225,0x00000227,0x0004003d, + 0x00000018,0x0000022a,0x00000216,0x0003003e,0x00000229,0x0000022a,0x0004003d,0x00000006, + 0x0000022c,0x0000021f,0x0003003e,0x0000022b,0x0000022c,0x0004003d,0x0000000c,0x0000022f, + 0x00000225,0x0003003e,0x0000022e,0x0000022f,0x0004003d,0x00000018,0x000002e8,0x00000229, + 0x00060041,0x00000100,0x000002e9,0x000000fd,0x000000fe,0x000002e8,0x0004003d,0x000000f7, + 0x000002ea,0x000002e9,0x0003003e,0x000002ce,0x000002ea,0x0004003d,0x00000006,0x000002eb, + 0x0000022b,0x0003003e,0x000002cf,0x000002eb,0x00050041,0x00000019,0x000002ec,0x000002ce, + 0x00000077,0x0004003d,0x00000018,0x000002ed,0x000002ec,0x000500c7,0x00000018,0x000002ee, + 0x000002ed,0x00000107,0x000500ab,0x000000c2,0x000002ef,0x000002ee,0x00000077,0x000300f7, + 0x00000303,0x00000000,0x000400fa,0x000002ef,0x000002f0,0x00000303,0x000200f8,0x000002f0, + 0x0004003d,0x00000006,0x000002f1,0x000002cf,0x0006000c,0x00000006,0x000002f2,0x00000001, + 0x00000004,0x000002f1,0x0003003e,0x000002cf,0x000002f2,0x000300f7,0x000002f8,0x00000000, + 0x000400fa,0x0000010e,0x000002f3,0x000002f8,0x000200f8,0x000002f3,0x0004003d,0x00000018, + 0x000002f5,0x000002ec,0x000500c7,0x00000018,0x000002f6,0x000002f5,0x00000113,0x000500ab, + 0x000000c2,0x000002f7,0x000002f6,0x00000077,0x000200f9,0x000002f8,0x000200f8,0x000002f8, + 0x000700f5,0x000000c2,0x000002f9,0x0000010e,0x000002f0,0x000002f7,0x000002f3,0x000300f7, + 0x00000302,0x00000000,0x000400fa,0x000002f9,0x000002fa,0x00000302,0x000200f8,0x000002fa, + 0x0004003d,0x00000006,0x000002fb,0x000002cf,0x00050085,0x00000006,0x000002fc,0x000002fb, + 0x0000011a,0x0006000c,0x00000006,0x000002fd,0x00000001,0x0000000a,0x000002fc,0x00050085, + 0x00000006,0x000002fe,0x000002fd,0x0000011d,0x00050081,0x00000006,0x000002ff,0x000002fe, + 0x0000011f,0x0006000c,0x00000006,0x00000300,0x00000001,0x00000004,0x000002ff,0x00050083, + 0x00000006,0x00000301,0x00000091,0x00000300,0x0003003e,0x000002cf,0x00000301,0x000200f9, + 0x00000302,0x000200f8,0x00000302,0x000200f9,0x00000303,0x000200f8,0x00000303,0x0004003d, + 0x00000006,0x00000304,0x000002cf,0x0003003e,0x000002d0,0x00000092,0x0004003d,0x00000006, + 0x0000039f,0x000002d0,0x0003003e,0x0000039d,0x0000039f,0x0004003d,0x00000006,0x00000305, + 0x0000039d,0x0003003e,0x000002d1,0x00000091,0x0004003d,0x00000006,0x000003a2,0x000002d1, + 0x0003003e,0x000003a0,0x000003a2,0x0004003d,0x00000006,0x00000306,0x000003a0,0x0008000c, + 0x00000006,0x00000307,0x00000001,0x0000002b,0x00000304,0x00000305,0x00000306,0x0003003e, + 0x000002cf,0x00000307,0x000300f7,0x00000316,0x00000000,0x000400fa,0x00000129,0x00000308, + 0x00000316,0x000200f8,0x00000308,0x0004003d,0x00000018,0x0000030a,0x000002ec,0x000500c2, + 0x00000018,0x0000030b,0x0000030a,0x0000012f,0x0003003e,0x000002d2,0x0000030b,0x0004003d, + 0x00000018,0x0000030c,0x000002d2,0x000500ab,0x000000c2,0x0000030d,0x0000030c,0x00000077, + 0x000300f7,0x00000315,0x00000000,0x000400fa,0x0000030d,0x0000030e,0x00000315,0x000200f8, + 0x0000030e,0x0004003d,0x00000135,0x0000030f,0x00000137,0x00050062,0x0000000c,0x00000310, + 0x0000030f,0x00000139,0x0004003d,0x00000018,0x00000311,0x000002d2,0x0003003e,0x000002d3, + 0x00000311,0x0003003e,0x000002d4,0x00000310,0x0004003d,0x00000006,0x00000312,0x000002cf, + 0x0003003e,0x000002d5,0x00000312,0x0004003d,0x0000000c,0x000003a5,0x000002d4,0x0007004f, + 0x00000012,0x000003a6,0x000003a5,0x000003a5,0x00000000,0x00000001,0x0004003d,0x00000018, + 0x000003a7,0x000002d3,0x0006000c,0x0000000c,0x000003a8,0x00000001,0x00000040,0x000003a7, + 0x0007004f,0x00000012,0x000003a9,0x000003a8,0x000003a8,0x00000000,0x00000001,0x00050083, + 0x00000012,0x000003aa,0x000003a6,0x000003a9,0x0006000c,0x00000012,0x000003ab,0x00000001, + 0x00000004,0x000003aa,0x0003003e,0x000003a3,0x000000ea,0x0004003d,0x00000006,0x000003b9, + 0x000003a3,0x00050041,0x00000007,0x000003ba,0x000003b6,0x00000077,0x0003003e,0x000003ba, + 0x000003b9,0x0004003d,0x00000006,0x000003bb,0x000003a3,0x00050041,0x00000007,0x000003bc, + 0x000003b6,0x0000007a,0x0003003e,0x000003bc,0x000003bb,0x0004003d,0x00000012,0x000003bd, + 0x000003b6,0x0003003e,0x000003b7,0x000003bd,0x0004003d,0x00000012,0x000003ac,0x000003b7, + 0x000500b8,0x000000ed,0x000003ad,0x000003ab,0x000003ac,0x0004009b,0x000000c2,0x000003ae, + 0x000003ad,0x000300f7,0x000003b5,0x00000000,0x000400fa,0x000003ae,0x000003af,0x000003b4, + 0x000200f8,0x000003af,0x0004003d,0x00000006,0x000003b0,0x000002d5,0x00050041,0x00000007, + 0x000003b1,0x000002d4,0x00000085,0x0004003d,0x00000006,0x000003b2,0x000003b1,0x0007000c, + 0x00000006,0x000003b3,0x00000001,0x00000025,0x000003b0,0x000003b2,0x0003003e,0x000002d5, + 0x000003b3,0x000200f9,0x000003b5,0x000200f8,0x000003b4,0x0003003e,0x000002d5,0x00000092, + 0x000200f9,0x000003b5,0x000200f8,0x000003b5,0x0004003d,0x00000006,0x00000314,0x000002d5, + 0x0003003e,0x000002cf,0x00000314,0x000200f9,0x00000315,0x000200f8,0x00000315,0x000200f9, + 0x00000316,0x000200f8,0x00000316,0x000300f7,0x0000031c,0x00000000,0x000400fa,0x00000142, + 0x00000317,0x0000031c,0x000200f8,0x00000317,0x0004003d,0x00000018,0x00000319,0x000002ec, + 0x000500c7,0x00000018,0x0000031a,0x00000319,0x00000147,0x000500ab,0x000000c2,0x0000031b, + 0x0000031a,0x00000077,0x000200f9,0x0000031c,0x000200f8,0x0000031c,0x000700f5,0x000000c2, + 0x0000031d,0x00000142,0x00000316,0x0000031b,0x00000317,0x000300f7,0x00000344,0x00000000, + 0x000400fa,0x0000031d,0x0000031e,0x00000344,0x000200f8,0x0000031e,0x0004003d,0x00000018, + 0x0000031f,0x00000229,0x00050084,0x00000018,0x00000320,0x0000031f,0x00000154,0x00050080, + 0x00000018,0x00000321,0x00000320,0x00000085,0x00060041,0x00000158,0x00000322,0x00000152, + 0x000000fe,0x00000321,0x0004003d,0x0000000c,0x00000323,0x00000322,0x0003003e,0x000002d7, + 0x00000323,0x0004003d,0x0000000c,0x000003c0,0x000002d7,0x0004003d,0x0000000c,0x000003c2, + 0x000002d7,0x00050051,0x00000006,0x000003c4,0x000003c0,0x00000000,0x00050051,0x00000006, + 0x000003c5,0x000003c0,0x00000001,0x00050051,0x00000006,0x000003c6,0x000003c2,0x00000002, + 0x00050051,0x00000006,0x000003c7,0x000003c2,0x00000003,0x00050050,0x00000012,0x000003c8, + 0x000003c4,0x000003c5,0x00050050,0x00000012,0x000003c9,0x000003c6,0x000003c7,0x00050050, + 0x00000029,0x000003ca,0x000003c8,0x000003c9,0x0003003e,0x000003be,0x000003ca,0x0004003d, + 0x00000029,0x00000324,0x000003be,0x0003003e,0x000002d6,0x00000324,0x0004003d,0x00000018, + 0x00000325,0x00000229,0x00050084,0x00000018,0x00000326,0x00000325,0x00000154,0x00050080, + 0x00000018,0x00000327,0x00000326,0x00000088,0x00060041,0x00000158,0x00000328,0x00000152, + 0x000000fe,0x00000327,0x0004003d,0x0000000c,0x00000329,0x00000328,0x0003003e,0x000002d8, + 0x00000329,0x0004003d,0x00000029,0x0000032a,0x000002d6,0x00050091,0x00000012,0x0000032d, + 0x0000032a,0x000001f1,0x0004003d,0x0000000c,0x0000032e,0x000002d8,0x0007004f,0x00000012, + 0x0000032f,0x0000032e,0x0000032e,0x00000000,0x00000001,0x00050081,0x00000012,0x00000330, + 0x0000032d,0x0000032f,0x0003003e,0x000002d9,0x00000330,0x0004003d,0x00000012,0x00000331, + 0x000002d9,0x0006000c,0x00000012,0x00000332,0x00000001,0x00000004,0x00000331,0x0004003d, + 0x0000000c,0x00000333,0x000002d8,0x0007004f,0x00000012,0x00000334,0x00000333,0x00000333, + 0x00000002,0x00000003,0x00050085,0x00000012,0x00000335,0x00000332,0x00000334,0x0004003d, + 0x0000000c,0x00000336,0x000002d8,0x0007004f,0x00000012,0x00000337,0x00000336,0x00000336, + 0x00000002,0x00000003,0x00050083,0x00000012,0x00000338,0x00000335,0x00000337,0x0003003e, + 0x000002db,0x00000338,0x0004003d,0x00000012,0x000003ce,0x000002db,0x0003003e,0x000003cb, + 0x000003ce,0x0004003d,0x00000012,0x000003cf,0x000003cb,0x0003003e,0x000003cc,0x000003cf, + 0x0004003d,0x00000012,0x00000339,0x000003cc,0x0003003e,0x000002da,0x00000339,0x00050041, + 0x00000007,0x0000033a,0x000002da,0x00000077,0x0004003d,0x00000006,0x0000033b,0x0000033a, + 0x00050041,0x00000007,0x0000033c,0x000002da,0x0000007a,0x0004003d,0x00000006,0x0000033d, + 0x0000033c,0x0007000c,0x00000006,0x0000033e,0x00000001,0x00000025,0x0000033b,0x0000033d, + 0x00050081,0x00000006,0x0000033f,0x0000033e,0x0000011a,0x0008000c,0x00000006,0x00000340, + 0x00000001,0x0000002b,0x0000033f,0x00000092,0x00000091,0x0003003e,0x000002dc,0x00000340, + 0x0004003d,0x00000006,0x00000341,0x000002cf,0x0004003d,0x00000006,0x00000342,0x000002dc, + 0x0007000c,0x00000006,0x00000343,0x00000001,0x00000025,0x00000341,0x00000342,0x0003003e, + 0x000002cf,0x00000343,0x000200f9,0x00000344,0x000200f8,0x00000344,0x0004003d,0x00000018, + 0x00000346,0x000002ec,0x000500c7,0x00000018,0x00000347,0x00000346,0x00000185,0x0003003e, + 0x000002dd,0x00000347,0x0004003d,0x00000018,0x00000348,0x000002dd,0x000500b2,0x000000c2, + 0x00000349,0x00000348,0x0000007a,0x000300f7,0x0000038c,0x00000000,0x000400fa,0x00000349, + 0x0000034a,0x0000035d,0x000200f8,0x0000034a,0x00050041,0x00000019,0x0000034b,0x000002ce, + 0x0000007a,0x0004003d,0x00000018,0x0000034c,0x0000034b,0x0006000c,0x0000000c,0x0000034d, + 0x00000001,0x00000040,0x0000034c,0x0003003e,0x0000022d,0x0000034d,0x0004003d,0x00000018, + 0x0000034e,0x000002dd,0x000500aa,0x000000c2,0x0000034f,0x0000034e,0x00000077,0x000500a7, + 0x000000c2,0x00000350,0x00000129,0x0000034f,0x000300f7,0x0000035c,0x00000000,0x000400fa, + 0x00000350,0x00000351,0x0000035c,0x000200f8,0x00000351,0x0004003d,0x0000000c,0x00000352, + 0x0000022d,0x00050041,0x00000007,0x00000354,0x0000022e,0x00000077,0x00050051,0x00000006, + 0x00000355,0x00000352,0x00000002,0x0003003e,0x00000354,0x00000355,0x00050041,0x00000007, + 0x00000356,0x0000022e,0x0000007a,0x00050051,0x00000006,0x00000357,0x00000352,0x00000003, + 0x0003003e,0x00000356,0x00000357,0x0004003d,0x00000006,0x00000358,0x000002cf,0x00050041, + 0x00000007,0x00000359,0x0000022e,0x00000085,0x0003003e,0x00000359,0x00000358,0x00050041, + 0x00000007,0x0000035a,0x0000022e,0x00000088,0x0003003e,0x0000035a,0x00000091,0x0003003e, + 0x000002de,0x00000092,0x0004003d,0x00000006,0x000003d3,0x000002de,0x00050041,0x00000007, + 0x000003d4,0x000003d0,0x00000077,0x0003003e,0x000003d4,0x000003d3,0x0004003d,0x00000006, + 0x000003d5,0x000002de,0x00050041,0x00000007,0x000003d6,0x000003d0,0x0000007a,0x0003003e, + 0x000003d6,0x000003d5,0x0004003d,0x00000006,0x000003d7,0x000002de,0x00050041,0x00000007, + 0x000003d8,0x000003d0,0x00000085,0x0003003e,0x000003d8,0x000003d7,0x0004003d,0x00000006, + 0x000003d9,0x000002de,0x00050041,0x00000007,0x000003da,0x000003d0,0x00000088,0x0003003e, + 0x000003da,0x000003d9,0x0004003d,0x0000000c,0x000003db,0x000003d0,0x0003003e,0x000003d1, + 0x000003db,0x0004003d,0x0000000c,0x0000035b,0x000003d1,0x0003003e,0x0000022d,0x0000035b, + 0x000200f9,0x0000035c,0x000200f8,0x0000035c,0x000200f9,0x0000038c,0x000200f8,0x0000035d, + 0x0004003d,0x00000018,0x0000035e,0x00000229,0x00050084,0x00000018,0x0000035f,0x0000035e, + 0x00000154,0x00060041,0x00000158,0x00000360,0x00000152,0x000000fe,0x0000035f,0x0004003d, + 0x0000000c,0x00000361,0x00000360,0x0003003e,0x000002e0,0x00000361,0x0004003d,0x0000000c, + 0x000003de,0x000002e0,0x0004003d,0x0000000c,0x000003e0,0x000002e0,0x00050051,0x00000006, + 0x000003e2,0x000003de,0x00000000,0x00050051,0x00000006,0x000003e3,0x000003de,0x00000001, + 0x00050051,0x00000006,0x000003e4,0x000003e0,0x00000002,0x00050051,0x00000006,0x000003e5, + 0x000003e0,0x00000003,0x00050050,0x00000012,0x000003e6,0x000003e2,0x000003e3,0x00050050, + 0x00000012,0x000003e7,0x000003e4,0x000003e5,0x00050050,0x00000029,0x000003e8,0x000003e6, + 0x000003e7,0x0003003e,0x000003dc,0x000003e8,0x0004003d,0x00000029,0x00000362,0x000003dc, + 0x0003003e,0x000002df,0x00000362,0x0004003d,0x00000018,0x00000363,0x00000229,0x00050084, + 0x00000018,0x00000364,0x00000363,0x00000154,0x00050080,0x00000018,0x00000365,0x00000364, + 0x0000007a,0x00060041,0x00000158,0x00000366,0x00000152,0x000000fe,0x00000365,0x0004003d, + 0x0000000c,0x00000367,0x00000366,0x0003003e,0x000002e1,0x00000367,0x0004003d,0x00000029, + 0x00000368,0x000002df,0x00050091,0x00000012,0x0000036b,0x00000368,0x000001f1,0x0004003d, + 0x0000000c,0x0000036c,0x000002e1,0x0007004f,0x00000012,0x0000036d,0x0000036c,0x0000036c, + 0x00000000,0x00000001,0x00050081,0x00000012,0x0000036e,0x0000036b,0x0000036d,0x0003003e, + 0x000002e2,0x0000036e,0x0004003d,0x00000018,0x0000036f,0x000002dd,0x000500aa,0x000000c2, + 0x00000370,0x0000036f,0x00000085,0x000300f7,0x00000377,0x00000000,0x000400fa,0x00000370, + 0x00000371,0x00000374,0x000200f8,0x00000371,0x00050041,0x00000007,0x00000372,0x000002e2, + 0x00000077,0x0004003d,0x00000006,0x00000373,0x00000372,0x0003003e,0x000002e4,0x00000373, + 0x000200f9,0x00000377,0x000200f8,0x00000374,0x0004003d,0x00000012,0x00000375,0x000002e2, + 0x0006000c,0x00000006,0x00000376,0x00000001,0x00000042,0x00000375,0x0003003e,0x000002e4, + 0x00000376,0x000200f9,0x00000377,0x000200f8,0x00000377,0x0004003d,0x00000006,0x00000378, + 0x000002e4,0x0003003e,0x000002e3,0x00000378,0x0004003d,0x00000006,0x00000379,0x000002e3, + 0x0008000c,0x00000006,0x0000037a,0x00000001,0x0000002b,0x00000379,0x00000092,0x00000091, + 0x0003003e,0x000002e3,0x0000037a,0x0004003d,0x00000006,0x0000037b,0x000002e3,0x00050041, + 0x00000007,0x0000037c,0x000002e1,0x00000085,0x0004003d,0x00000006,0x0000037d,0x0000037c, + 0x00050085,0x00000006,0x0000037e,0x0000037b,0x0000037d,0x00050041,0x00000007,0x0000037f, + 0x000002e1,0x00000088,0x0004003d,0x00000006,0x00000380,0x0000037f,0x00050081,0x00000006, + 0x00000381,0x0000037e,0x00000380,0x0003003e,0x000002e5,0x00000381,0x00050041,0x00000019, + 0x00000382,0x000002ce,0x0000007a,0x0004003d,0x00000018,0x00000383,0x00000382,0x0004007c, + 0x00000006,0x00000384,0x00000383,0x0003003e,0x000002e6,0x00000384,0x0004003d,0x000001ce, + 0x00000385,0x000001d0,0x0004003d,0x000001d2,0x00000386,0x000001d4,0x00050056,0x000001d6, + 0x00000387,0x00000385,0x00000386,0x0004003d,0x00000006,0x00000388,0x000002e5,0x0004003d, + 0x00000006,0x00000389,0x000002e6,0x00050050,0x00000012,0x0000038a,0x00000388,0x00000389, + 0x00070058,0x0000000c,0x0000038b,0x00000387,0x0000038a,0x00000002,0x00000092,0x0003003e, + 0x0000022d,0x0000038b,0x000200f9,0x0000038c,0x000200f8,0x0000038c,0x0004003d,0x00000006, + 0x0000038d,0x000002cf,0x00050041,0x00000007,0x0000038e,0x0000022d,0x00000088,0x0004003d, + 0x00000006,0x0000038f,0x0000038e,0x00050085,0x00000006,0x00000390,0x0000038f,0x0000038d, + 0x0003003e,0x0000038e,0x00000390,0x0004003d,0x00000006,0x00000393,0x0000038e,0x0004003d, + 0x0000000c,0x00000394,0x0000022d,0x0008004f,0x00000038,0x00000395,0x00000394,0x00000394, + 0x00000000,0x00000001,0x00000002,0x0005008e,0x00000038,0x00000396,0x00000395,0x00000393, + 0x00050041,0x00000007,0x00000397,0x0000022d,0x00000077,0x00050051,0x00000006,0x00000398, + 0x00000396,0x00000000,0x0003003e,0x00000397,0x00000398,0x00050041,0x00000007,0x00000399, + 0x0000022d,0x0000007a,0x00050051,0x00000006,0x0000039a,0x00000396,0x00000001,0x0003003e, + 0x00000399,0x0000039a,0x00050041,0x00000007,0x0000039b,0x0000022d,0x00000085,0x00050051, + 0x00000006,0x0000039c,0x00000396,0x00000002,0x0003003e,0x0000039b,0x0000039c,0x0004003d, + 0x0000000c,0x00000233,0x0000022d,0x0003003e,0x00000228,0x00000233,0x0004003d,0x0000000c, + 0x00000234,0x0000022e,0x0003003e,0x00000225,0x00000234,0x000300f7,0x00000236,0x00000000, + 0x000400fa,0x00000129,0x00000235,0x00000236,0x000200f8,0x00000235,0x00050041,0x0000023b, + 0x0000023c,0x00000239,0x0000007a,0x0004003d,0x00000018,0x0000023d,0x0000023c,0x000500ab, + 0x000000c2,0x0000023e,0x0000023d,0x00000077,0x000200f9,0x00000236,0x000200f8,0x00000236, + 0x000700f5,0x000000c2,0x0000023f,0x00000129,0x0000038c,0x0000023e,0x00000235,0x000300f7, + 0x00000241,0x00000000,0x000400fa,0x0000023f,0x00000240,0x00000241,0x000200f8,0x00000240, + 0x00050041,0x00000007,0x00000243,0x00000225,0x00000088,0x0004003d,0x00000006,0x00000244, + 0x00000243,0x000500b7,0x000000c2,0x00000245,0x00000244,0x00000092,0x000300f7,0x00000248, + 0x00000000,0x000400fa,0x00000245,0x00000247,0x0000024a,0x000200f8,0x00000247,0x0004003d, + 0x0000000c,0x00000249,0x00000225,0x0003003e,0x00000246,0x00000249,0x000200f9,0x00000248, + 0x000200f8,0x0000024a,0x0004003d,0x00000135,0x0000024b,0x00000137,0x00050062,0x0000000c, + 0x0000024c,0x0000024b,0x00000139,0x0003003e,0x00000246,0x0000024c,0x000200f9,0x00000248, + 0x000200f8,0x00000248,0x0004003d,0x0000000c,0x0000024d,0x00000246,0x0003003e,0x00000242, + 0x0000024d,0x00050041,0x0000023b,0x0000024f,0x00000239,0x0000007a,0x0004003d,0x00000018, + 0x00000250,0x0000024f,0x0003003e,0x0000024e,0x00000250,0x0004003d,0x0000000c,0x00000252, + 0x00000242,0x0003003e,0x00000251,0x00000252,0x0004003d,0x00000006,0x00000254,0x000001fe, + 0x0003003e,0x00000253,0x00000254,0x0004003d,0x0000000c,0x000003eb,0x00000251,0x0007004f, + 0x00000012,0x000003ec,0x000003eb,0x000003eb,0x00000000,0x00000001,0x0004003d,0x00000018, + 0x000003ed,0x0000024e,0x0006000c,0x0000000c,0x000003ee,0x00000001,0x00000040,0x000003ed, + 0x0007004f,0x00000012,0x000003ef,0x000003ee,0x000003ee,0x00000000,0x00000001,0x00050083, + 0x00000012,0x000003f0,0x000003ec,0x000003ef,0x0006000c,0x00000012,0x000003f1,0x00000001, + 0x00000004,0x000003f0,0x0003003e,0x000003e9,0x000000ea,0x0004003d,0x00000006,0x000003ff, + 0x000003e9,0x00050041,0x00000007,0x00000400,0x000003fc,0x00000077,0x0003003e,0x00000400, + 0x000003ff,0x0004003d,0x00000006,0x00000401,0x000003e9,0x00050041,0x00000007,0x00000402, + 0x000003fc,0x0000007a,0x0003003e,0x00000402,0x00000401,0x0004003d,0x00000012,0x00000403, + 0x000003fc,0x0003003e,0x000003fd,0x00000403,0x0004003d,0x00000012,0x000003f2,0x000003fd, + 0x000500b8,0x000000ed,0x000003f3,0x000003f1,0x000003f2,0x0004009b,0x000000c2,0x000003f4, + 0x000003f3,0x000300f7,0x000003fb,0x00000000,0x000400fa,0x000003f4,0x000003f5,0x000003fa, + 0x000200f8,0x000003f5,0x0004003d,0x00000006,0x000003f6,0x00000253,0x00050041,0x00000007, + 0x000003f7,0x00000251,0x00000085,0x0004003d,0x00000006,0x000003f8,0x000003f7,0x0007000c, + 0x00000006,0x000003f9,0x00000001,0x00000025,0x000003f6,0x000003f8,0x0003003e,0x00000253, + 0x000003f9,0x000200f9,0x000003fb,0x000200f8,0x000003fa,0x0003003e,0x00000253,0x00000092, + 0x000200f9,0x000003fb,0x000200f8,0x000003fb,0x0004003d,0x00000006,0x00000256,0x00000253, + 0x0003003e,0x000001fe,0x00000256,0x000200f9,0x00000241,0x000200f8,0x00000241,0x0004003d, + 0x00000006,0x00000257,0x000001fe,0x00050041,0x0000025a,0x0000025b,0x00000239,0x00000077, + 0x0004003d,0x00000006,0x0000025c,0x0000025b,0x0003003e,0x00000259,0x0000025c,0x0004003d, + 0x00000006,0x00000407,0x00000259,0x0003003e,0x00000404,0x00000407,0x0004003d,0x00000006, + 0x00000408,0x00000404,0x0003003e,0x00000405,0x00000408,0x0004003d,0x00000006,0x0000025d, + 0x00000405,0x00050085,0x00000006,0x0000025e,0x00000257,0x0000025d,0x0004003d,0x0000000c, + 0x0000025f,0x000001f4,0x0005008e,0x0000000c,0x00000260,0x0000025f,0x0000025e,0x0003003e, + 0x000001f4,0x00000260,0x0004003d,0x0000000c,0x00000261,0x00000228,0x00050041,0x00000007, + 0x00000262,0x000001f4,0x00000088,0x0004003d,0x00000006,0x00000263,0x00000262,0x00050083, + 0x00000006,0x00000264,0x00000091,0x00000263,0x0005008e,0x0000000c,0x00000265,0x00000261, + 0x00000264,0x0004003d,0x0000000c,0x00000266,0x000001f4,0x00050081,0x0000000c,0x00000267, + 0x00000265,0x00000266,0x0003003e,0x00000228,0x00000267,0x0004003d,0x0000000c,0x0000026f, + 0x00000228,0x0008004f,0x00000038,0x00000270,0x0000026f,0x0000026f,0x00000000,0x00000001, + 0x00000002,0x0003003e,0x0000026e,0x00000270,0x0003003e,0x00000271,0x000001f1,0x00050041, + 0x0000025a,0x00000275,0x0000026b,0x00000077,0x0004003d,0x00000006,0x00000276,0x00000275, + 0x0003003e,0x00000274,0x00000276,0x00050041,0x0000025a,0x00000278,0x0000026b,0x0000007a, + 0x0004003d,0x00000006,0x00000279,0x00000278,0x0003003e,0x00000277,0x00000279,0x000300f7, + 0x00000419,0x00000000,0x000400fa,0x000000c3,0x0000040f,0x00000417,0x000200f8,0x0000040f, + 0x0004003d,0x00000012,0x00000410,0x00000271,0x0003003e,0x0000040a,0x00000410,0x0004003d, + 0x00000006,0x00000411,0x00000274,0x0003003e,0x0000040b,0x00000411,0x0004003d,0x00000006, + 0x00000412,0x00000277,0x0003003e,0x0000040c,0x00000412,0x00050041,0x00000007,0x0000041f, + 0x0000040a,0x00000077,0x0004003d,0x00000006,0x00000420,0x0000041f,0x00050085,0x00000006, + 0x00000421,0x000000ac,0x00000420,0x00050041,0x00000007,0x00000422,0x0000040a,0x0000007a, + 0x0004003d,0x00000006,0x00000423,0x00000422,0x00050085,0x00000006,0x00000424,0x000000b0, + 0x00000423,0x00050081,0x00000006,0x00000425,0x00000421,0x00000424,0x0006000c,0x00000006, + 0x00000426,0x00000001,0x0000000a,0x00000425,0x0003003e,0x0000041b,0x00000426,0x0004003d, + 0x00000006,0x00000427,0x0000041b,0x00050085,0x00000006,0x00000428,0x000000b7,0x00000427, + 0x0006000c,0x00000006,0x00000429,0x00000001,0x0000000a,0x00000428,0x0003003e,0x0000041c, + 0x00000429,0x0004003d,0x00000006,0x0000042a,0x0000041c,0x0004003d,0x00000006,0x0000042b, + 0x0000040b,0x00050085,0x00000006,0x0000042c,0x0000042a,0x0000042b,0x0004003d,0x00000006, + 0x0000042d,0x0000040c,0x00050081,0x00000006,0x0000042e,0x0000042c,0x0000042d,0x0003003e, + 0x0000041d,0x0000042e,0x0004003d,0x00000006,0x00000413,0x0000041d,0x0004003d,0x00000038, + 0x00000414,0x0000026e,0x00060050,0x00000038,0x00000415,0x00000413,0x00000413,0x00000413, + 0x00050081,0x00000038,0x00000416,0x00000415,0x00000414,0x0003003e,0x00000409,0x00000416, + 0x000200f9,0x00000419,0x000200f8,0x00000417,0x0004003d,0x00000038,0x00000418,0x0000026e, + 0x0003003e,0x00000409,0x00000418,0x000200f9,0x00000419,0x000200f8,0x00000419,0x0004003d, + 0x00000038,0x0000041a,0x00000409,0x0003003e,0x0000040d,0x0000041a,0x0004003d,0x00000038, + 0x0000027a,0x0000040d,0x00050041,0x00000007,0x0000027b,0x00000228,0x00000077,0x00050051, + 0x00000006,0x0000027c,0x0000027a,0x00000000,0x0003003e,0x0000027b,0x0000027c,0x00050041, + 0x00000007,0x0000027d,0x00000228,0x0000007a,0x00050051,0x00000006,0x0000027e,0x0000027a, + 0x00000001,0x0003003e,0x0000027d,0x0000027e,0x00050041,0x00000007,0x0000027f,0x00000228, + 0x00000085,0x00050051,0x00000006,0x00000280,0x0000027a,0x00000002,0x0003003e,0x0000027f, + 0x00000280,0x0004003d,0x0000000c,0x00000282,0x00000228,0x0003003e,0x00000281,0x00000282, + 0x0004003d,0x0000000c,0x00000284,0x00000225,0x0003003e,0x00000283,0x00000284,0x0004003d, + 0x0000000c,0x00000430,0x00000283,0x0003003e,0x000001ed,0x00000430,0x0004003d,0x0000020e, + 0x00000288,0x00000210,0x0004003d,0x0000004f,0x00000289,0x000001ef,0x00040063,0x00000288, + 0x00000289,0x0000028b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..71d12d9828f90e3487e4fc7336719b799ce9de48 GIT binary patch literal 16720 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

987Z_LmIG^(O zdrtTNZaDwi4{$#Gwc)CfT`cb%@UmSVO#5c~aDRNi6s*nkkEi^?XkQMdn_FK`?r@Ij z|DE);BpSJw|#kNWwmLp%0O?$8cC8zj-R1Fm*#7;GQBAm>rLHVUVCSA6bBn-WfU4(ylS z9d8^yBf0&OT|D!DlVCREc6;LDW&1%et@y$bcVFw8{NHdsj?#WK(o)qT?Z?rSO{hiM zPexj@eE&CoUHvpfOfgFPS+Mf_Y2K^*Z20(#Nea8J5!D(7W)f=X|*Q3FkE?S5?j^zqTpWV4&gK@#S?ja-xhPn5OMfa z`JIA$`JKaQQkAc@a+hdg@X_YG<3Ou6Ul&YcyCxVf+x5XTwri8)W!p8F#&%cAZCDF7I7Ta1kBUpVk z2aX8eHeBplzg`}VU*zF<@u5|jBZHOE&nk0NG-dKPEW?MUUUS8FE6!WRctyAv)@NgY z^C|l)NA`Ly!)qS>D&@?pihXlzv?_Z`_zg+=BsR{c{BI5J{Zxbj@_CG2eYZ`x2X%ScDz1V{qN7UY=1d1oYwcmlfsp&J@Mpl zn&dE!3r6MVMiYaN`hJ&kwCdZu;J%)m5>7LJtsQ3tJFFdSrzXu$GN0hOu1*UUyYDHd zN29Cv53%9qqnOHzqaFHrMzHeMLTkdA;rcOkWUCnT9z!fKlsP+CJ$!$k9535B!L)jY zd}Fxy_9C{v7x81SvTqudt-iiF-1r-#@_9=%dOgp-HCQ=%m3v#Ta<26%cWyMg^Q8|9 zf|aG~#~_)W>*9)3&m`hDTw z!uimvjqeE7j^ghO7q_mrcZKtzAD#Cj)~$px4CF@hges^%+3*Hm1 zOdqrNMx)nQzb}}ktUB0e74rkZG+f(07%b-Wyzky6{6pb1$&uk0w)s67bM_BM=Oa#? z%Z~($(f7vxjK)SiKhL1UhErAzcM}xJ#*8tdu76UX|{XmtLEB*!b(j9@X?4oi-+Syzq-_S+5H;lX&7yEo^6f9)st zh0`QQiVc08>-(drx9(a07S6uc$W}2Ph|VTC_|!Ac-=nF6Pd$r07|h4B7`t}T`5qO_N1I<6{Hi4LwD0||9_iw}A{ejoOJ-bY zY{T!DM&oRr`tF#<=36Gb%DpCKXtnOYHe6fie5~y=ga4VfS-bJqh12+o$wn*xS;5xG z8vkR0`Sf+=*l2X~R~u&sd)}Z|J#&J^VyoE41&g&{)RyDJ`O&pSy|nV57fh>t>6Boa zNk#FXI6QwP1uZ5*sz@82fj^eXqfVBZ_l7mUvHrorN|)qUw^!Onxle3t@$Rck z`TFi(Jifkn#LM=^#Guu=eN(t=#+<18qc?~1bBMu*R%PB2tc>|kW!{P>IVZ~Sp;ei; z1uN6aNT2^AB>mH|1+Q|cYhj$v#k*A9Z4&V Ze0^W>&S2kH92+|ueo@lX>B%lh{||i7y?Ouu literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.h new file mode 100644 index 000000000..8dc682fa0 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.h @@ -0,0 +1,2923 @@ +#pragma once + +const uint32_t atomic_draw_image_mesh_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00001123,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000039c, + 0x0000044b,0x0000044d,0x0000045b,0x00000462,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x0000014d,0x0000674e, + 0x00030005,0x000002be,0x0000674d,0x00030005,0x00000335,0x00006576,0x00040006,0x00000335, + 0x00000000,0x00003464,0x00030005,0x00000337,0x00004355,0x00030005,0x00000347,0x0000674b, + 0x00030005,0x00000360,0x00006747,0x00040005,0x0000036e,0x30653742,0x00000000,0x00030005, + 0x00000379,0x00006748,0x00030005,0x00000387,0x00006577,0x00040006,0x00000387,0x00000000, + 0x00003464,0x00030005,0x00000389,0x0000424f,0x00060005,0x0000039c,0x465f6c67,0x43676172, + 0x64726f6f,0x00000000,0x00030005,0x00000407,0x00004444,0x00030005,0x0000040b,0x00006277, + 0x00030005,0x00000418,0x00006749,0x00040005,0x0000042e,0x306a3742,0x00000000,0x00030005, + 0x0000044b,0x0000306a,0x00030005,0x0000044d,0x00003065,0x00030005,0x0000044f,0x00000045, + 0x00030005,0x00000454,0x00003478,0x00030005,0x00000455,0x00004344,0x00030005,0x00000457, + 0x00003552,0x00030005,0x0000045b,0x00003055,0x00030005,0x0000045e,0x00003553,0x00030005, + 0x00000461,0x00003456,0x00030005,0x00000462,0x0000304e,0x00040005,0x00000463,0x61726170, + 0x0000006d,0x00040005,0x00000466,0x61726170,0x0000006d,0x00040005,0x00000469,0x61726170, + 0x0000006d,0x00030005,0x0000046d,0x00003270,0x00030005,0x00000470,0x00003470,0x00030005, + 0x00000476,0x00003145,0x00040005,0x0000047a,0x61726170,0x0000006d,0x00040005,0x0000047c, + 0x61726170,0x0000006d,0x00030005,0x0000047f,0x0000394a,0x00040005,0x00000483,0x61726170, + 0x0000006d,0x00030005,0x00000485,0x00003171,0x00040005,0x00000486,0x61726170,0x0000006d, + 0x00030005,0x00000488,0x00000050,0x00040005,0x00000489,0x61726170,0x0000006d,0x00040005, + 0x0000048b,0x61726170,0x0000006d,0x00040005,0x0000048d,0x61726170,0x0000006d,0x00040005, + 0x0000048e,0x61726170,0x0000006d,0x00030005,0x00000497,0x0000434c,0x00040006,0x00000497, + 0x00000000,0x00003479,0x00040006,0x00000497,0x00000001,0x00003056,0x00040006,0x00000497, + 0x00000002,0x0000326e,0x00030005,0x00000499,0x00003041,0x00030005,0x000004a2,0x0000304f, + 0x00040005,0x000004ae,0x61726170,0x0000006d,0x00040005,0x000004b1,0x61726170,0x0000006d, + 0x00040005,0x000004b3,0x61726170,0x0000006d,0x00030005,0x000004c0,0x0000314d,0x00040005, + 0x000004c9,0x61726170,0x0000006d,0x00040005,0x000004cc,0x61726170,0x0000006d,0x00040005, + 0x000004d0,0x61726170,0x0000006d,0x00040005,0x000004d1,0x61726170,0x0000006d,0x00040005, + 0x000004d3,0x61726170,0x0000006d,0x00040005,0x000004e0,0x61726170,0x0000006d,0x00030005, + 0x000004f0,0x0000424d,0x00040006,0x000004f0,0x00000000,0x00003376,0x00040006,0x000004f0, + 0x00000001,0x00003377,0x00030005,0x000004f2,0x0000006b,0x00040005,0x000004f5,0x61726170, + 0x0000006d,0x00040005,0x000004f8,0x61726170,0x0000006d,0x00040005,0x000004fb,0x61726170, + 0x0000006d,0x00040005,0x000004fe,0x61726170,0x0000006d,0x00040005,0x00000508,0x61726170, + 0x0000006d,0x00040005,0x0000050d,0x61726170,0x0000006d,0x00040047,0x0000014d,0x00000001, + 0x00000007,0x00040047,0x000002be,0x00000001,0x00000006,0x00040047,0x00000334,0x00000006, + 0x00000008,0x00030047,0x00000335,0x00000003,0x00040048,0x00000335,0x00000000,0x00000018, + 0x00050048,0x00000335,0x00000000,0x00000023,0x00000000,0x00030047,0x00000337,0x00000018, + 0x00040047,0x00000337,0x00000021,0x00000004,0x00040047,0x00000337,0x00000022,0x00000000, + 0x00040047,0x00000347,0x00000001,0x00000004,0x00040047,0x00000360,0x00000001,0x00000000, + 0x00030047,0x0000036e,0x00000000,0x00040047,0x0000036e,0x00000021,0x00000001,0x00040047, + 0x0000036e,0x00000022,0x00000002,0x00040047,0x0000036e,0x0000002b,0x00000001,0x00040047, + 0x00000379,0x00000001,0x00000001,0x00040047,0x00000386,0x00000006,0x00000010,0x00030047, + 0x00000387,0x00000003,0x00040048,0x00000387,0x00000000,0x00000018,0x00050048,0x00000387, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000389,0x00000018,0x00040047,0x00000389, + 0x00000021,0x00000005,0x00040047,0x00000389,0x00000022,0x00000000,0x00040047,0x0000039c, + 0x0000000b,0x0000000f,0x00030047,0x00000407,0x00000000,0x00040047,0x00000407,0x00000021, + 0x00000009,0x00040047,0x00000407,0x00000022,0x00000000,0x00030047,0x0000040b,0x00000000, + 0x00040047,0x0000040b,0x00000021,0x00000009,0x00040047,0x0000040b,0x00000022,0x00000000, + 0x00040047,0x00000418,0x00000001,0x00000002,0x00030047,0x0000042e,0x00000000,0x00040047, + 0x0000042e,0x00000021,0x00000000,0x00040047,0x0000042e,0x00000022,0x00000002,0x00040047, + 0x0000042e,0x0000002b,0x00000000,0x00030047,0x0000044b,0x00000000,0x00040047,0x0000044b, + 0x0000001e,0x00000000,0x00030047,0x0000044d,0x00000000,0x00040047,0x0000044d,0x0000001e, + 0x00000001,0x00030047,0x00000454,0x00000000,0x00030047,0x00000455,0x00000000,0x00040047, + 0x00000455,0x00000021,0x0000000c,0x00040047,0x00000455,0x00000022,0x00000001,0x00030047, + 0x00000456,0x00000000,0x00030047,0x00000457,0x00000000,0x00040047,0x00000457,0x00000021, + 0x0000000c,0x00040047,0x00000457,0x00000022,0x00000001,0x00030047,0x00000458,0x00000000, + 0x00040047,0x0000045b,0x0000001e,0x00000000,0x00030047,0x0000045d,0x00000000,0x00030047, + 0x0000045e,0x00000000,0x00030047,0x00000461,0x00000000,0x00040047,0x00000462,0x0000001e, + 0x00000001,0x00030047,0x00000466,0x00000000,0x00030047,0x00000468,0x00000000,0x00030047, + 0x00000469,0x00000000,0x00030047,0x0000046b,0x00000000,0x00030047,0x0000046c,0x00000000, + 0x00030047,0x00000470,0x00000017,0x00040047,0x00000470,0x00000021,0x00000003,0x00040047, + 0x00000470,0x00000022,0x00000002,0x00030047,0x00000476,0x00000000,0x00030047,0x0000047c, + 0x00000000,0x00030047,0x0000047d,0x00000000,0x00030047,0x0000047f,0x00000000,0x00030047, + 0x00000485,0x00000000,0x00030047,0x00000486,0x00000000,0x00030047,0x00000488,0x00000000, + 0x00030047,0x0000048a,0x00000000,0x00030047,0x0000048b,0x00000000,0x00030047,0x0000048c, + 0x00000000,0x00030047,0x0000048d,0x00000000,0x00030047,0x0000048e,0x00000000,0x00030047, + 0x0000048f,0x00000000,0x00030047,0x00000497,0x00000002,0x00050048,0x00000497,0x00000000, + 0x00000023,0x00000018,0x00050048,0x00000497,0x00000001,0x00000023,0x00000038,0x00050048, + 0x00000497,0x00000002,0x00000023,0x0000003c,0x00040047,0x00000499,0x00000021,0x00000002, + 0x00040047,0x00000499,0x00000022,0x00000000,0x00030047,0x000004a2,0x00000000,0x00030047, + 0x000004a4,0x00000000,0x00030047,0x000004a6,0x00000000,0x00030047,0x000004a9,0x00000000, + 0x00030047,0x000004ab,0x00000000,0x00030047,0x000004ac,0x00000000,0x00030047,0x000004ad, + 0x00000000,0x00030047,0x000004b1,0x00000000,0x00030047,0x000004b2,0x00000000,0x00030047, + 0x000004b3,0x00000000,0x00030047,0x000004b4,0x00000000,0x00030047,0x000004c0,0x00000000, + 0x00030047,0x000004c1,0x00000000,0x00030047,0x000004c2,0x00000000,0x00030047,0x000004c4, + 0x00000000,0x00030047,0x000004c5,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047, + 0x000004c7,0x00000000,0x00030047,0x000004c8,0x00000000,0x00030047,0x000004c9,0x00000000, + 0x00030047,0x000004ca,0x00000000,0x00030047,0x000004d0,0x00000000,0x00030047,0x000004d1, + 0x00000000,0x00030047,0x000004d2,0x00000000,0x00030047,0x000004d3,0x00000000,0x00030047, + 0x000004d6,0x00000000,0x00030047,0x000004d7,0x00000000,0x00030047,0x000004de,0x00000000, + 0x00030047,0x000004e5,0x00000000,0x00030047,0x000004e6,0x00000000,0x00030047,0x000004e7, + 0x00000000,0x00030047,0x000004e8,0x00000000,0x00030047,0x000004ea,0x00000000,0x00030047, + 0x000004eb,0x00000000,0x00030047,0x000004ec,0x00000000,0x00030047,0x000004ed,0x00000000, + 0x00030047,0x000004ee,0x00000000,0x00030047,0x000004f0,0x00000002,0x00050048,0x000004f0, + 0x00000000,0x00000023,0x00000058,0x00050048,0x000004f0,0x00000001,0x00000023,0x0000005c, + 0x00040047,0x000004f2,0x00000021,0x00000000,0x00040047,0x000004f2,0x00000022,0x00000000, + 0x00030047,0x000004f5,0x00000000,0x00030047,0x000004f6,0x00000000,0x00030047,0x000004f7, + 0x00000000,0x00030047,0x000004fb,0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047, + 0x00000508,0x00000000,0x00030047,0x00000509,0x00000000,0x00030047,0x0000050d,0x00000000, + 0x00030047,0x0000050e,0x00000000,0x00030047,0x00000520,0x00000000,0x00030047,0x00000521, + 0x00000000,0x00030047,0x00000524,0x00000000,0x00030047,0x00000525,0x00000000,0x00030047, + 0x00000526,0x00000000,0x00030047,0x00000527,0x00000000,0x00030047,0x00000529,0x00000000, + 0x00030047,0x0000052a,0x00000000,0x00030047,0x0000052b,0x00000000,0x00030047,0x0000052c, + 0x00000000,0x00030047,0x0000052d,0x00000000,0x00030047,0x0000052f,0x00000000,0x00030047, + 0x00000531,0x00000000,0x00030047,0x00000532,0x00000000,0x00030047,0x00000533,0x00000000, + 0x00030047,0x00000534,0x00000000,0x00030047,0x00000536,0x00000000,0x00030047,0x00000537, + 0x00000000,0x00030047,0x00000538,0x00000000,0x00030047,0x0000053b,0x00000000,0x00030047, + 0x0000053c,0x00000000,0x00030047,0x0000053e,0x00000000,0x00030047,0x00000540,0x00000000, + 0x00030047,0x00000547,0x00000000,0x00030047,0x00000548,0x00000000,0x00030047,0x0000054b, + 0x00000000,0x00030047,0x0000054c,0x00000000,0x00030047,0x0000054d,0x00000000,0x00030047, + 0x0000054f,0x00000000,0x00030047,0x00000551,0x00000000,0x00030047,0x00000553,0x00000000, + 0x00030047,0x00000555,0x00000000,0x00030047,0x00000557,0x00000000,0x00030047,0x00000559, + 0x00000000,0x00030047,0x0000055a,0x00000000,0x00030047,0x0000055b,0x00000000,0x00030047, + 0x0000055e,0x00000000,0x00030047,0x0000055f,0x00000000,0x00030047,0x00000564,0x00000000, + 0x00030047,0x00000566,0x00000000,0x00030047,0x00000568,0x00000000,0x00030047,0x00000571, + 0x00000000,0x00030047,0x00000573,0x00000000,0x00030047,0x00000574,0x00000000,0x00030047, + 0x00000575,0x00000000,0x00030047,0x00000576,0x00000000,0x00030047,0x0000057b,0x00000000, + 0x00030047,0x00000581,0x00000000,0x00030047,0x00000582,0x00000000,0x00030047,0x0000058b, + 0x00000000,0x00030047,0x0000058c,0x00000000,0x00030047,0x0000058d,0x00000000,0x00030047, + 0x0000058e,0x00000000,0x00030047,0x0000058f,0x00000000,0x00030047,0x00000590,0x00000000, + 0x00030047,0x00000591,0x00000000,0x00030047,0x00000594,0x00000000,0x00030047,0x00000597, + 0x00000000,0x00030047,0x0000059f,0x00000000,0x00030047,0x000005a0,0x00000000,0x00030047, + 0x000005a2,0x00000000,0x00030047,0x000005cb,0x00000000,0x00030047,0x000005cd,0x00000000, + 0x00030047,0x000005ce,0x00000000,0x00030047,0x000005cf,0x00000000,0x00030047,0x000005d0, + 0x00000000,0x00030047,0x000005d1,0x00000000,0x00030047,0x000005d2,0x00000000,0x00030047, + 0x000005d3,0x00000000,0x00030047,0x000005e2,0x00000000,0x00030047,0x000005e8,0x00000000, + 0x00030047,0x00000615,0x00000000,0x00030047,0x00000616,0x00000000,0x00030047,0x0000061b, + 0x00000000,0x00030047,0x0000061d,0x00000000,0x00030047,0x0000061f,0x00000000,0x00030047, + 0x00000620,0x00000000,0x00030047,0x00000624,0x00000000,0x00030047,0x00000632,0x00000000, + 0x00030047,0x00000633,0x00000000,0x00030047,0x00000634,0x00000000,0x00030047,0x00000635, + 0x00000000,0x00030047,0x00000636,0x00000000,0x00030047,0x00000637,0x00000000,0x00030047, + 0x00000641,0x00000000,0x00030047,0x00000642,0x00000000,0x00030047,0x00000643,0x00000000, + 0x00030047,0x00000644,0x00000000,0x00030047,0x0000064b,0x00000000,0x00030047,0x0000064d, + 0x00000000,0x00030047,0x0000064e,0x00000000,0x00030047,0x00000650,0x00000000,0x00030047, + 0x00000651,0x00000000,0x00030047,0x00000653,0x00000000,0x00030047,0x00000654,0x00000000, + 0x00030047,0x0000065e,0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000661, + 0x00000000,0x00030047,0x00000664,0x00000000,0x00030047,0x00000665,0x00000000,0x00030047, + 0x00000667,0x00000000,0x00030047,0x00000669,0x00000000,0x00030047,0x0000066b,0x00000000, + 0x00030047,0x00000679,0x00000000,0x00030047,0x0000067a,0x00000000,0x00030047,0x0000067d, + 0x00000000,0x00030047,0x0000067e,0x00000000,0x00030047,0x0000067f,0x00000000,0x00030047, + 0x00000681,0x00000000,0x00030047,0x00000683,0x00000000,0x00030047,0x00000685,0x00000000, + 0x00030047,0x00000687,0x00000000,0x00030047,0x00000689,0x00000000,0x00030047,0x00000697, + 0x00000000,0x00030047,0x00000698,0x00000000,0x00030047,0x0000069b,0x00000000,0x00030047, + 0x0000069c,0x00000000,0x00030047,0x0000069d,0x00000000,0x00030047,0x0000069e,0x00000000, + 0x00030047,0x0000069f,0x00000000,0x00030047,0x000006a0,0x00000000,0x00030047,0x000006a1, + 0x00000000,0x00030047,0x000006a3,0x00000000,0x00030047,0x000006a4,0x00000000,0x00030047, + 0x000006a5,0x00000000,0x00030047,0x000006a7,0x00000000,0x00030047,0x000006a8,0x00000000, + 0x00030047,0x000006aa,0x00000000,0x00030047,0x000006ac,0x00000000,0x00030047,0x000006ad, + 0x00000000,0x00030047,0x000006ae,0x00000000,0x00030047,0x000006af,0x00000000,0x00030047, + 0x000006b0,0x00000000,0x00030047,0x000006b1,0x00000000,0x00030047,0x000006b2,0x00000000, + 0x00030047,0x000006b3,0x00000000,0x00030047,0x000006b4,0x00000000,0x00030047,0x000006b5, + 0x00000000,0x00030047,0x000006b6,0x00000000,0x00030047,0x000006b7,0x00000000,0x00030047, + 0x000006b8,0x00000000,0x00030047,0x000006b9,0x00000000,0x00030047,0x000006ba,0x00000000, + 0x00030047,0x000006bb,0x00000000,0x00030047,0x000006bc,0x00000000,0x00030047,0x000006bd, + 0x00000000,0x00030047,0x000006be,0x00000000,0x00030047,0x000006bf,0x00000000,0x00030047, + 0x000006c1,0x00000000,0x00030047,0x000006c2,0x00000000,0x00030047,0x000006c3,0x00000000, + 0x00030047,0x000006c4,0x00000000,0x00030047,0x000006c5,0x00000000,0x00030047,0x000006c6, + 0x00000000,0x00030047,0x000006c7,0x00000000,0x00030047,0x000006c8,0x00000000,0x00030047, + 0x000006c9,0x00000000,0x00030047,0x000006ca,0x00000000,0x00030047,0x000006cb,0x00000000, + 0x00030047,0x000006cc,0x00000000,0x00030047,0x000006cd,0x00000000,0x00030047,0x000006ce, + 0x00000000,0x00030047,0x000006cf,0x00000000,0x00030047,0x000006d0,0x00000000,0x00030047, + 0x000006d1,0x00000000,0x00030047,0x000006d2,0x00000000,0x00030047,0x000006d3,0x00000000, + 0x00030047,0x000006d5,0x00000000,0x00030047,0x000006d7,0x00000000,0x00030047,0x000006d9, + 0x00000000,0x00030047,0x000006da,0x00000000,0x00030047,0x000006db,0x00000000,0x00030047, + 0x000006dd,0x00000000,0x00030047,0x000006de,0x00000000,0x00030047,0x000006df,0x00000000, + 0x00030047,0x000006e0,0x00000000,0x00030047,0x000006e1,0x00000000,0x00030047,0x000006e2, + 0x00000000,0x00030047,0x000006e3,0x00000000,0x00030047,0x000006e5,0x00000000,0x00030047, + 0x000006e6,0x00000000,0x00030047,0x000006e7,0x00000000,0x00030047,0x000006e8,0x00000000, + 0x00030047,0x000006e9,0x00000000,0x00030047,0x000006ea,0x00000000,0x00030047,0x000006eb, + 0x00000000,0x00030047,0x000006ec,0x00000000,0x00030047,0x000006ed,0x00000000,0x00030047, + 0x000006ee,0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047,0x000006f1,0x00000000, + 0x00030047,0x000006f2,0x00000000,0x00030047,0x000006f3,0x00000000,0x00030047,0x000006f5, + 0x00000000,0x00030047,0x000006f6,0x00000000,0x00030047,0x000006f7,0x00000000,0x00030047, + 0x000006f9,0x00000000,0x00030047,0x000006fa,0x00000000,0x00030047,0x000006fb,0x00000000, + 0x00030047,0x000006fd,0x00000000,0x00030047,0x000006fe,0x00000000,0x00030047,0x00000700, + 0x00000000,0x00030047,0x00000701,0x00000000,0x00030047,0x00000702,0x00000000,0x00030047, + 0x00000709,0x00000000,0x00030047,0x0000070a,0x00000000,0x00030047,0x0000070d,0x00000000, + 0x00030047,0x0000070f,0x00000000,0x00030047,0x00000710,0x00000000,0x00030047,0x00000712, + 0x00000000,0x00030047,0x00000713,0x00000000,0x00030047,0x00000714,0x00000000,0x00030047, + 0x00000715,0x00000000,0x00030047,0x00000716,0x00000000,0x00030047,0x00000717,0x00000000, + 0x00030047,0x00000718,0x00000000,0x00030047,0x00000719,0x00000000,0x00030047,0x0000071a, + 0x00000000,0x00030047,0x0000071c,0x00000000,0x00030047,0x0000071d,0x00000000,0x00030047, + 0x0000071f,0x00000000,0x00030047,0x00000722,0x00000000,0x00030047,0x00000723,0x00000000, + 0x00030047,0x00000724,0x00000000,0x00030047,0x00000726,0x00000000,0x00030047,0x00000727, + 0x00000000,0x00030047,0x00000728,0x00000000,0x00030047,0x00000730,0x00000000,0x00030047, + 0x00000736,0x00000000,0x00030047,0x00000737,0x00000000,0x00030047,0x00000738,0x00000000, + 0x00030047,0x00000739,0x00000000,0x00030047,0x0000073a,0x00000000,0x00030047,0x0000073c, + 0x00000000,0x00030047,0x0000073d,0x00000000,0x00030047,0x0000073f,0x00000000,0x00030047, + 0x00000740,0x00000000,0x00030047,0x00000741,0x00000000,0x00030047,0x00000742,0x00000000, + 0x00030047,0x00000743,0x00000000,0x00030047,0x00000744,0x00000000,0x00030047,0x00000745, + 0x00000000,0x00030047,0x00000747,0x00000000,0x00030047,0x00000748,0x00000000,0x00030047, + 0x00000749,0x00000000,0x00030047,0x0000074b,0x00000000,0x00030047,0x0000074c,0x00000000, + 0x00030047,0x0000074d,0x00000000,0x00030047,0x0000074e,0x00000000,0x00030047,0x0000074f, + 0x00000000,0x00030047,0x00000750,0x00000000,0x00030047,0x00000751,0x00000000,0x00030047, + 0x00000752,0x00000000,0x00030047,0x00000753,0x00000000,0x00030047,0x00000754,0x00000000, + 0x00030047,0x00000755,0x00000000,0x00030047,0x00000757,0x00000000,0x00030047,0x00000758, + 0x00000000,0x00030047,0x00000759,0x00000000,0x00030047,0x00000762,0x00000000,0x00030047, + 0x00000768,0x00000000,0x00030047,0x00000769,0x00000000,0x00030047,0x0000076e,0x00000000, + 0x00030047,0x00000774,0x00000000,0x00030047,0x00000775,0x00000000,0x00030047,0x00000776, + 0x00000000,0x00030047,0x00000779,0x00000000,0x00030047,0x0000077a,0x00000000,0x00030047, + 0x0000077b,0x00000000,0x00030047,0x00000781,0x00000000,0x00030047,0x00000782,0x00000000, + 0x00030047,0x00000783,0x00000000,0x00030047,0x0000078b,0x00000000,0x00030047,0x0000078c, + 0x00000000,0x00030047,0x0000078d,0x00000000,0x00030047,0x0000078e,0x00000000,0x00030047, + 0x0000078f,0x00000000,0x00030047,0x00000790,0x00000000,0x00030047,0x00000791,0x00000000, + 0x00030047,0x00000792,0x00000000,0x00030047,0x00000793,0x00000000,0x00030047,0x00000795, + 0x00000000,0x00030047,0x00000796,0x00000000,0x00030047,0x00000797,0x00000000,0x00030047, + 0x00000798,0x00000000,0x00030047,0x0000079a,0x00000000,0x00030047,0x0000079b,0x00000000, + 0x00030047,0x0000079c,0x00000000,0x00030047,0x0000079d,0x00000000,0x00030047,0x0000079e, + 0x00000000,0x00030047,0x0000079f,0x00000000,0x00030047,0x000007a0,0x00000000,0x00030047, + 0x000007a1,0x00000000,0x00030047,0x000007a4,0x00000000,0x00030047,0x000007a7,0x00000000, + 0x00030047,0x000007a8,0x00000000,0x00030047,0x000007a9,0x00000000,0x00030047,0x000007aa, + 0x00000000,0x00030047,0x000007af,0x00000000,0x00030047,0x000007b2,0x00000000,0x00030047, + 0x000007b3,0x00000000,0x00030047,0x000007b4,0x00000000,0x00030047,0x000007b5,0x00000000, + 0x00030047,0x000007ba,0x00000000,0x00030047,0x000007bd,0x00000000,0x00030047,0x000007be, + 0x00000000,0x00030047,0x000007bf,0x00000000,0x00030047,0x000007c4,0x00000000,0x00030047, + 0x000007c7,0x00000000,0x00030047,0x000007c8,0x00000000,0x00030047,0x000007c9,0x00000000, + 0x00030047,0x000007cd,0x00000000,0x00030047,0x000007ce,0x00000000,0x00030047,0x000007cf, + 0x00000000,0x00030047,0x000007d1,0x00000000,0x00030047,0x000007d2,0x00000000,0x00030047, + 0x000007d4,0x00000000,0x00030047,0x000007d8,0x00000000,0x00030047,0x000007d9,0x00000000, + 0x00030047,0x000007dc,0x00000000,0x00030047,0x000007dd,0x00000000,0x00030047,0x000007de, + 0x00000000,0x00030047,0x000007df,0x00000000,0x00030047,0x000007e1,0x00000000,0x00030047, + 0x000007e3,0x00000000,0x00030047,0x000007e5,0x00000000,0x00030047,0x000007e7,0x00000000, + 0x00030047,0x000007e8,0x00000000,0x00030047,0x000007e9,0x00000000,0x00030047,0x000007eb, + 0x00000000,0x00030047,0x000007ed,0x00000000,0x00030047,0x000007ef,0x00000000,0x00030047, + 0x000007f1,0x00000000,0x00030047,0x000007f2,0x00000000,0x00030047,0x000007f3,0x00000000, + 0x00030047,0x000007f5,0x00000000,0x00030047,0x000007f7,0x00000000,0x00030047,0x000007f9, + 0x00000000,0x00030047,0x000007fb,0x00000000,0x00030047,0x000007fc,0x00000000,0x00030047, + 0x000007fd,0x00000000,0x00030047,0x000007ff,0x00000000,0x00030047,0x00000801,0x00000000, + 0x00030047,0x00000803,0x00000000,0x00030047,0x00000805,0x00000000,0x00030047,0x00000806, + 0x00000000,0x00030047,0x00000807,0x00000000,0x00030047,0x00000809,0x00000000,0x00030047, + 0x0000080b,0x00000000,0x00030047,0x0000080d,0x00000000,0x00030047,0x0000080f,0x00000000, + 0x00030047,0x00000810,0x00000000,0x00030047,0x00000811,0x00000000,0x00030047,0x00000813, + 0x00000000,0x00030047,0x00000815,0x00000000,0x00030047,0x00000817,0x00000000,0x00030047, + 0x00000819,0x00000000,0x00030047,0x0000081a,0x00000000,0x00030047,0x0000081b,0x00000000, + 0x00030047,0x0000081d,0x00000000,0x00030047,0x0000081f,0x00000000,0x00030047,0x00000821, + 0x00000000,0x00030047,0x00000823,0x00000000,0x00030047,0x00000824,0x00000000,0x00030047, + 0x00000825,0x00000000,0x00030047,0x00000827,0x00000000,0x00030047,0x00000829,0x00000000, + 0x00030047,0x0000082b,0x00000000,0x00030047,0x0000082d,0x00000000,0x00030047,0x0000082e, + 0x00000000,0x00030047,0x0000082f,0x00000000,0x00030047,0x00000831,0x00000000,0x00030047, + 0x00000833,0x00000000,0x00030047,0x00000835,0x00000000,0x00030047,0x00000837,0x00000000, + 0x00030047,0x00000838,0x00000000,0x00030047,0x00000839,0x00000000,0x00030047,0x0000083b, + 0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x0000083f,0x00000000,0x00030047, + 0x00000841,0x00000000,0x00030047,0x00000842,0x00000000,0x00030047,0x00000843,0x00000000, + 0x00030047,0x00000845,0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000849, + 0x00000000,0x00030047,0x0000084b,0x00000000,0x00030047,0x0000084c,0x00000000,0x00030047, + 0x0000084d,0x00000000,0x00030047,0x0000084f,0x00000000,0x00030047,0x00000851,0x00000000, + 0x00030047,0x00000853,0x00000000,0x00030047,0x00000855,0x00000000,0x00030047,0x00000856, + 0x00000000,0x00030047,0x00000857,0x00000000,0x00030047,0x00000859,0x00000000,0x00030047, + 0x0000085b,0x00000000,0x00030047,0x0000085d,0x00000000,0x00030047,0x0000085f,0x00000000, + 0x00030047,0x00000860,0x00000000,0x00030047,0x00000861,0x00000000,0x00030047,0x00000863, + 0x00000000,0x00030047,0x00000865,0x00000000,0x00030047,0x00000867,0x00000000,0x00030047, + 0x00000869,0x00000000,0x00030047,0x0000086b,0x00000000,0x00030047,0x0000086c,0x00000000, + 0x00030047,0x0000086d,0x00000000,0x00030047,0x0000086f,0x00000000,0x00030047,0x00000871, + 0x00000000,0x00030047,0x00000872,0x00000000,0x00030047,0x00000873,0x00000000,0x00030047, + 0x00000875,0x00000000,0x00030047,0x00000877,0x00000000,0x00030047,0x00000879,0x00000000, + 0x00030047,0x0000087a,0x00000000,0x00030047,0x0000087c,0x00000000,0x00030047,0x0000087d, + 0x00000000,0x00030047,0x0000087e,0x00000000,0x00030047,0x0000087f,0x00000000,0x00030047, + 0x00000885,0x00000000,0x00030047,0x00000888,0x00000000,0x00030047,0x0000088a,0x00000000, + 0x00030047,0x0000088b,0x00000000,0x00030047,0x0000088d,0x00000000,0x00030047,0x0000088e, + 0x00000000,0x00030047,0x00000891,0x00000000,0x00030047,0x00000892,0x00000000,0x00030047, + 0x00000893,0x00000000,0x00030047,0x00000896,0x00000000,0x00030047,0x00000898,0x00000000, + 0x00030047,0x00000899,0x00000000,0x00030047,0x0000089a,0x00000000,0x00030047,0x0000089b, + 0x00000000,0x00030047,0x0000089d,0x00000000,0x00030047,0x0000089e,0x00000000,0x00030047, + 0x000008a1,0x00000000,0x00030047,0x000008a2,0x00000000,0x00030047,0x000008a3,0x00000000, + 0x00030047,0x000008a6,0x00000000,0x00030047,0x000008a8,0x00000000,0x00030047,0x000008a9, + 0x00000000,0x00030047,0x000008aa,0x00000000,0x00030047,0x000008ab,0x00000000,0x00030047, + 0x000008ad,0x00000000,0x00030047,0x000008ae,0x00000000,0x00030047,0x000008b1,0x00000000, + 0x00030047,0x000008b2,0x00000000,0x00030047,0x000008b3,0x00000000,0x00030047,0x000008b6, + 0x00000000,0x00030047,0x000008b8,0x00000000,0x00030047,0x000008b9,0x00000000,0x00030047, + 0x000008ba,0x00000000,0x00030047,0x000008bb,0x00000000,0x00030047,0x000008bd,0x00000000, + 0x00030047,0x000008be,0x00000000,0x00030047,0x000008c1,0x00000000,0x00030047,0x000008c2, + 0x00000000,0x00030047,0x000008c3,0x00000000,0x00030047,0x000008c6,0x00000000,0x00030047, + 0x000008c8,0x00000000,0x00030047,0x000008c9,0x00000000,0x00030047,0x000008ca,0x00000000, + 0x00030047,0x000008cb,0x00000000,0x00030047,0x000008cc,0x00000000,0x00030047,0x000008cd, + 0x00000000,0x00030047,0x000008ce,0x00000000,0x00030047,0x000008cf,0x00000000,0x00030047, + 0x000008d0,0x00000000,0x00030047,0x000008d1,0x00000000,0x00030047,0x000008d2,0x00000000, + 0x00030047,0x000008d3,0x00000000,0x00030047,0x000008d4,0x00000000,0x00030047,0x000008d5, + 0x00000000,0x00030047,0x000008d6,0x00000000,0x00030047,0x000008d7,0x00000000,0x00030047, + 0x000008d8,0x00000000,0x00030047,0x000008da,0x00000000,0x00030047,0x000008dc,0x00000000, + 0x00030047,0x000008dd,0x00000000,0x00030047,0x000008df,0x00000000,0x00030047,0x000008e0, + 0x00000000,0x00030047,0x000008e1,0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047, + 0x000008e3,0x00000000,0x00030047,0x000008e6,0x00000000,0x00030047,0x000008e8,0x00000000, + 0x00030047,0x000008e9,0x00000000,0x00030047,0x000008ec,0x00000000,0x00030047,0x000008ed, + 0x00000000,0x00030047,0x000008f0,0x00000000,0x00030047,0x000008f2,0x00000000,0x00030047, + 0x000008f3,0x00000000,0x00030047,0x000008f4,0x00000000,0x00030047,0x000008f5,0x00000000, + 0x00030047,0x000008f6,0x00000000,0x00030047,0x000008f7,0x00000000,0x00030047,0x000008f8, + 0x00000000,0x00030047,0x000008f9,0x00000000,0x00030047,0x000008fa,0x00000000,0x00030047, + 0x000008fb,0x00000000,0x00030047,0x000008fc,0x00000000,0x00030047,0x000008fd,0x00000000, + 0x00030047,0x000008fe,0x00000000,0x00030047,0x00000900,0x00000000,0x00030047,0x00000902, + 0x00000000,0x00030047,0x00000903,0x00000000,0x00030047,0x00000904,0x00000000,0x00030047, + 0x00000906,0x00000000,0x00030047,0x00000908,0x00000000,0x00030047,0x0000090a,0x00000000, + 0x00030047,0x0000090c,0x00000000,0x00030047,0x0000090d,0x00000000,0x00030047,0x0000090e, + 0x00000000,0x00030047,0x0000090f,0x00000000,0x00030047,0x00000910,0x00000000,0x00030047, + 0x00000912,0x00000000,0x00030047,0x00000914,0x00000000,0x00030047,0x00000915,0x00000000, + 0x00030047,0x00000916,0x00000000,0x00030047,0x00000918,0x00000000,0x00030047,0x0000091a, + 0x00000000,0x00030047,0x0000091c,0x00000000,0x00030047,0x0000091e,0x00000000,0x00030047, + 0x0000091f,0x00000000,0x00030047,0x00000920,0x00000000,0x00030047,0x00000922,0x00000000, + 0x00030047,0x00000924,0x00000000,0x00030047,0x00000926,0x00000000,0x00030047,0x00000927, + 0x00000000,0x00030047,0x00000928,0x00000000,0x00030047,0x0000092a,0x00000000,0x00030047, + 0x0000092c,0x00000000,0x00030047,0x0000092e,0x00000000,0x00030047,0x0000092f,0x00000000, + 0x00030047,0x00000930,0x00000000,0x00030047,0x00000932,0x00000000,0x00030047,0x00000933, + 0x00000000,0x00030047,0x00000936,0x00000000,0x00030047,0x00000937,0x00000000,0x00030047, + 0x00000938,0x00000000,0x00030047,0x0000093b,0x00000000,0x00030047,0x0000093d,0x00000000, + 0x00030047,0x0000093e,0x00000000,0x00030047,0x0000093f,0x00000000,0x00030047,0x00000940, + 0x00000000,0x00030047,0x00000942,0x00000000,0x00030047,0x00000943,0x00000000,0x00030047, + 0x00000946,0x00000000,0x00030047,0x00000947,0x00000000,0x00030047,0x00000948,0x00000000, + 0x00030047,0x0000094b,0x00000000,0x00030047,0x0000094d,0x00000000,0x00030047,0x0000094e, + 0x00000000,0x00030047,0x0000094f,0x00000000,0x00030047,0x00000950,0x00000000,0x00030047, + 0x00000952,0x00000000,0x00030047,0x00000954,0x00000000,0x00030047,0x00000956,0x00000000, + 0x00030047,0x00000957,0x00000000,0x00030047,0x00000959,0x00000000,0x00030047,0x0000095a, + 0x00000000,0x00030047,0x0000095b,0x00000000,0x00030047,0x0000095d,0x00000000,0x00030047, + 0x0000095f,0x00000000,0x00030047,0x00000961,0x00000000,0x00030047,0x00000963,0x00000000, + 0x00030047,0x00000964,0x00000000,0x00030047,0x00000965,0x00000000,0x00030047,0x00000967, + 0x00000000,0x00030047,0x00000969,0x00000000,0x00030047,0x0000096b,0x00000000,0x00030047, + 0x0000096d,0x00000000,0x00030047,0x0000096f,0x00000000,0x00030047,0x00000970,0x00000000, + 0x00030047,0x00000971,0x00000000,0x00030047,0x00000973,0x00000000,0x00030047,0x00000975, + 0x00000000,0x00030047,0x00000976,0x00000000,0x00030047,0x00000977,0x00000000,0x00030047, + 0x00000979,0x00000000,0x00030047,0x0000097b,0x00000000,0x00030047,0x0000097d,0x00000000, + 0x00030047,0x0000097e,0x00000000,0x00030047,0x00000980,0x00000000,0x00030047,0x00000981, + 0x00000000,0x00030047,0x00000982,0x00000000,0x00030047,0x00000983,0x00000000,0x00030047, + 0x00000989,0x00000000,0x00030047,0x0000098c,0x00000000,0x00030047,0x0000098e,0x00000000, + 0x00030047,0x0000098f,0x00000000,0x00030047,0x00000991,0x00000000,0x00030047,0x00000992, + 0x00000000,0x00030047,0x00000995,0x00000000,0x00030047,0x00000996,0x00000000,0x00030047, + 0x00000997,0x00000000,0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099c,0x00000000, + 0x00030047,0x0000099d,0x00000000,0x00030047,0x0000099e,0x00000000,0x00030047,0x0000099f, + 0x00000000,0x00030047,0x000009a1,0x00000000,0x00030047,0x000009a2,0x00000000,0x00030047, + 0x000009a5,0x00000000,0x00030047,0x000009a6,0x00000000,0x00030047,0x000009a7,0x00000000, + 0x00030047,0x000009aa,0x00000000,0x00030047,0x000009ac,0x00000000,0x00030047,0x000009ad, + 0x00000000,0x00030047,0x000009ae,0x00000000,0x00030047,0x000009af,0x00000000,0x00030047, + 0x000009b1,0x00000000,0x00030047,0x000009b2,0x00000000,0x00030047,0x000009b5,0x00000000, + 0x00030047,0x000009b6,0x00000000,0x00030047,0x000009b7,0x00000000,0x00030047,0x000009ba, + 0x00000000,0x00030047,0x000009bc,0x00000000,0x00030047,0x000009bd,0x00000000,0x00030047, + 0x000009be,0x00000000,0x00030047,0x000009bf,0x00000000,0x00030047,0x000009c1,0x00000000, + 0x00030047,0x000009c2,0x00000000,0x00030047,0x000009c5,0x00000000,0x00030047,0x000009c6, + 0x00000000,0x00030047,0x000009c7,0x00000000,0x00030047,0x000009ca,0x00000000,0x00030047, + 0x000009cc,0x00000000,0x00030047,0x000009cd,0x00000000,0x00030047,0x000009ce,0x00000000, + 0x00030047,0x000009cf,0x00000000,0x00030047,0x000009d0,0x00000000,0x00030047,0x000009d1, + 0x00000000,0x00030047,0x000009d2,0x00000000,0x00030047,0x000009d3,0x00000000,0x00030047, + 0x000009d4,0x00000000,0x00030047,0x000009d5,0x00000000,0x00030047,0x000009d6,0x00000000, + 0x00030047,0x000009d7,0x00000000,0x00030047,0x000009d8,0x00000000,0x00030047,0x000009d9, + 0x00000000,0x00030047,0x000009da,0x00000000,0x00030047,0x000009db,0x00000000,0x00030047, + 0x000009dc,0x00000000,0x00030047,0x000009de,0x00000000,0x00030047,0x000009e0,0x00000000, + 0x00030047,0x000009e1,0x00000000,0x00030047,0x000009e3,0x00000000,0x00030047,0x000009e4, + 0x00000000,0x00030047,0x000009e5,0x00000000,0x00030047,0x000009e6,0x00000000,0x00030047, + 0x000009e7,0x00000000,0x00030047,0x000009ea,0x00000000,0x00030047,0x000009ec,0x00000000, + 0x00030047,0x000009ed,0x00000000,0x00030047,0x000009f0,0x00000000,0x00030047,0x000009f1, + 0x00000000,0x00030047,0x000009f4,0x00000000,0x00030047,0x000009f6,0x00000000,0x00030047, + 0x000009f7,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047,0x000009f9,0x00000000, + 0x00030047,0x000009fa,0x00000000,0x00030047,0x000009fb,0x00000000,0x00030047,0x000009fc, + 0x00000000,0x00030047,0x000009fd,0x00000000,0x00030047,0x000009fe,0x00000000,0x00030047, + 0x000009ff,0x00000000,0x00030047,0x00000a00,0x00000000,0x00030047,0x00000a01,0x00000000, + 0x00030047,0x00000a02,0x00000000,0x00030047,0x00000a04,0x00000000,0x00030047,0x00000a06, + 0x00000000,0x00030047,0x00000a07,0x00000000,0x00030047,0x00000a08,0x00000000,0x00030047, + 0x00000a0a,0x00000000,0x00030047,0x00000a0c,0x00000000,0x00030047,0x00000a0e,0x00000000, + 0x00030047,0x00000a10,0x00000000,0x00030047,0x00000a11,0x00000000,0x00030047,0x00000a12, + 0x00000000,0x00030047,0x00000a13,0x00000000,0x00030047,0x00000a14,0x00000000,0x00030047, + 0x00000a16,0x00000000,0x00030047,0x00000a18,0x00000000,0x00030047,0x00000a19,0x00000000, + 0x00030047,0x00000a1a,0x00000000,0x00030047,0x00000a1c,0x00000000,0x00030047,0x00000a1e, + 0x00000000,0x00030047,0x00000a20,0x00000000,0x00030047,0x00000a22,0x00000000,0x00030047, + 0x00000a23,0x00000000,0x00030047,0x00000a24,0x00000000,0x00030047,0x00000a26,0x00000000, + 0x00030047,0x00000a28,0x00000000,0x00030047,0x00000a2a,0x00000000,0x00030047,0x00000a2b, + 0x00000000,0x00030047,0x00000a2c,0x00000000,0x00030047,0x00000a2e,0x00000000,0x00030047, + 0x00000a30,0x00000000,0x00030047,0x00000a32,0x00000000,0x00030047,0x00000a33,0x00000000, + 0x00030047,0x00000a34,0x00000000,0x00030047,0x00000a36,0x00000000,0x00030047,0x00000a37, + 0x00000000,0x00030047,0x00000a3a,0x00000000,0x00030047,0x00000a3b,0x00000000,0x00030047, + 0x00000a3c,0x00000000,0x00030047,0x00000a3f,0x00000000,0x00030047,0x00000a41,0x00000000, + 0x00030047,0x00000a42,0x00000000,0x00030047,0x00000a43,0x00000000,0x00030047,0x00000a44, + 0x00000000,0x00030047,0x00000a46,0x00000000,0x00030047,0x00000a47,0x00000000,0x00030047, + 0x00000a4a,0x00000000,0x00030047,0x00000a4b,0x00000000,0x00030047,0x00000a4c,0x00000000, + 0x00030047,0x00000a4f,0x00000000,0x00030047,0x00000a51,0x00000000,0x00030047,0x00000a52, + 0x00000000,0x00030047,0x00000a53,0x00000000,0x00030047,0x00000a54,0x00000000,0x00030047, + 0x00000a56,0x00000000,0x00030047,0x00000a58,0x00000000,0x00030047,0x00000a5a,0x00000000, + 0x00030047,0x00000a5b,0x00000000,0x00030047,0x00000a5d,0x00000000,0x00030047,0x00000a5e, + 0x00000000,0x00030047,0x00000a5f,0x00000000,0x00030047,0x00000a61,0x00000000,0x00030047, + 0x00000a63,0x00000000,0x00030047,0x00000a65,0x00000000,0x00030047,0x00000a67,0x00000000, + 0x00030047,0x00000a68,0x00000000,0x00030047,0x00000a69,0x00000000,0x00030047,0x00000a6b, + 0x00000000,0x00030047,0x00000a6d,0x00000000,0x00030047,0x00000a6f,0x00000000,0x00030047, + 0x00000a71,0x00000000,0x00030047,0x00000a72,0x00000000,0x00030047,0x00000a73,0x00000000, + 0x00030047,0x00000a74,0x00000000,0x00030047,0x00000a75,0x00000000,0x00030047,0x00000a76, + 0x00000000,0x00030047,0x00000a77,0x00000000,0x00030047,0x00000a78,0x00000000,0x00030047, + 0x00000a79,0x00000000,0x00030047,0x00000a7a,0x00000000,0x00030047,0x00000a7b,0x00000000, + 0x00030047,0x00000a7c,0x00000000,0x00030047,0x00000a7d,0x00000000,0x00030047,0x00000a7e, + 0x00000000,0x00030047,0x00000a7f,0x00000000,0x00030047,0x00000a80,0x00000000,0x00030047, + 0x00000a82,0x00000000,0x00030047,0x00000a84,0x00000000,0x00030047,0x00000a85,0x00000000, + 0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a88,0x00000000,0x00030047,0x00000a89, + 0x00000000,0x00030047,0x00000a8a,0x00000000,0x00030047,0x00000a8b,0x00000000,0x00030047, + 0x00000a8e,0x00000000,0x00030047,0x00000a90,0x00000000,0x00030047,0x00000a91,0x00000000, + 0x00030047,0x00000a94,0x00000000,0x00030047,0x00000a95,0x00000000,0x00030047,0x00000a98, + 0x00000000,0x00030047,0x00000a9a,0x00000000,0x00030047,0x00000a9b,0x00000000,0x00030047, + 0x00000a9c,0x00000000,0x00030047,0x00000a9d,0x00000000,0x00030047,0x00000a9e,0x00000000, + 0x00030047,0x00000a9f,0x00000000,0x00030047,0x00000aa0,0x00000000,0x00030047,0x00000aa1, + 0x00000000,0x00030047,0x00000aa2,0x00000000,0x00030047,0x00000aa3,0x00000000,0x00030047, + 0x00000aa4,0x00000000,0x00030047,0x00000aa5,0x00000000,0x00030047,0x00000aa6,0x00000000, + 0x00030047,0x00000aa8,0x00000000,0x00030047,0x00000aaa,0x00000000,0x00030047,0x00000aab, + 0x00000000,0x00030047,0x00000aac,0x00000000,0x00030047,0x00000aae,0x00000000,0x00030047, + 0x00000ab0,0x00000000,0x00030047,0x00000ab2,0x00000000,0x00030047,0x00000ab4,0x00000000, + 0x00030047,0x00000ab5,0x00000000,0x00030047,0x00000ab6,0x00000000,0x00030047,0x00000ab7, + 0x00000000,0x00030047,0x00000ab8,0x00000000,0x00030047,0x00000aba,0x00000000,0x00030047, + 0x00000abc,0x00000000,0x00030047,0x00000abd,0x00000000,0x00030047,0x00000abe,0x00000000, + 0x00030047,0x00000ac0,0x00000000,0x00030047,0x00000ac2,0x00000000,0x00030047,0x00000ac4, + 0x00000000,0x00030047,0x00000ac6,0x00000000,0x00030047,0x00000ac7,0x00000000,0x00030047, + 0x00000ac8,0x00000000,0x00030047,0x00000aca,0x00000000,0x00030047,0x00000acc,0x00000000, + 0x00030047,0x00000ace,0x00000000,0x00030047,0x00000acf,0x00000000,0x00030047,0x00000ad0, + 0x00000000,0x00030047,0x00000ad2,0x00000000,0x00030047,0x00000ad4,0x00000000,0x00030047, + 0x00000ad6,0x00000000,0x00030047,0x00000ad7,0x00000000,0x00030047,0x00000ad8,0x00000000, + 0x00030047,0x00000ada,0x00000000,0x00030047,0x00000adb,0x00000000,0x00030047,0x00000ade, + 0x00000000,0x00030047,0x00000adf,0x00000000,0x00030047,0x00000ae0,0x00000000,0x00030047, + 0x00000ae3,0x00000000,0x00030047,0x00000ae5,0x00000000,0x00030047,0x00000ae6,0x00000000, + 0x00030047,0x00000ae7,0x00000000,0x00030047,0x00000ae8,0x00000000,0x00030047,0x00000aea, + 0x00000000,0x00030047,0x00000aeb,0x00000000,0x00030047,0x00000aee,0x00000000,0x00030047, + 0x00000aef,0x00000000,0x00030047,0x00000af0,0x00000000,0x00030047,0x00000af3,0x00000000, + 0x00030047,0x00000af5,0x00000000,0x00030047,0x00000af6,0x00000000,0x00030047,0x00000af7, + 0x00000000,0x00030047,0x00000af8,0x00000000,0x00030047,0x00000afa,0x00000000,0x00030047, + 0x00000afc,0x00000000,0x00030047,0x00000afe,0x00000000,0x00030047,0x00000aff,0x00000000, + 0x00030047,0x00000b01,0x00000000,0x00030047,0x00000b02,0x00000000,0x00030047,0x00000b03, + 0x00000000,0x00030047,0x00000b05,0x00000000,0x00030047,0x00000b07,0x00000000,0x00030047, + 0x00000b09,0x00000000,0x00030047,0x00000b0b,0x00000000,0x00030047,0x00000b0c,0x00000000, + 0x00030047,0x00000b0d,0x00000000,0x00030047,0x00000b0f,0x00000000,0x00030047,0x00000b11, + 0x00000000,0x00030047,0x00000b13,0x00000000,0x00030047,0x00000b15,0x00000000,0x00030047, + 0x00000b16,0x00000000,0x00030047,0x00000b17,0x00000000,0x00030047,0x00000b18,0x00000000, + 0x00030047,0x00000b19,0x00000000,0x00030047,0x00000b1a,0x00000000,0x00030047,0x00000b1b, + 0x00000000,0x00030047,0x00000b1c,0x00000000,0x00030047,0x00000b1d,0x00000000,0x00030047, + 0x00000b1e,0x00000000,0x00030047,0x00000b1f,0x00000000,0x00030047,0x00000b20,0x00000000, + 0x00030047,0x00000b21,0x00000000,0x00030047,0x00000b22,0x00000000,0x00030047,0x00000b23, + 0x00000000,0x00030047,0x00000b24,0x00000000,0x00030047,0x00000b26,0x00000000,0x00030047, + 0x00000b28,0x00000000,0x00030047,0x00000b29,0x00000000,0x00030047,0x00000b2b,0x00000000, + 0x00030047,0x00000b2c,0x00000000,0x00030047,0x00000b2d,0x00000000,0x00030047,0x00000b2e, + 0x00000000,0x00030047,0x00000b2f,0x00000000,0x00030047,0x00000b32,0x00000000,0x00030047, + 0x00000b34,0x00000000,0x00030047,0x00000b35,0x00000000,0x00030047,0x00000b38,0x00000000, + 0x00030047,0x00000b39,0x00000000,0x00030047,0x00000b3c,0x00000000,0x00030047,0x00000b3e, + 0x00000000,0x00030047,0x00000b3f,0x00000000,0x00030047,0x00000b40,0x00000000,0x00030047, + 0x00000b41,0x00000000,0x00030047,0x00000b42,0x00000000,0x00030047,0x00000b43,0x00000000, + 0x00030047,0x00000b44,0x00000000,0x00030047,0x00000b45,0x00000000,0x00030047,0x00000b46, + 0x00000000,0x00030047,0x00000b47,0x00000000,0x00030047,0x00000b48,0x00000000,0x00030047, + 0x00000b49,0x00000000,0x00030047,0x00000b4a,0x00000000,0x00030047,0x00000b4c,0x00000000, + 0x00030047,0x00000b4e,0x00000000,0x00030047,0x00000b4f,0x00000000,0x00030047,0x00000b50, + 0x00000000,0x00030047,0x00000b52,0x00000000,0x00030047,0x00000b54,0x00000000,0x00030047, + 0x00000b56,0x00000000,0x00030047,0x00000b58,0x00000000,0x00030047,0x00000b59,0x00000000, + 0x00030047,0x00000b5a,0x00000000,0x00030047,0x00000b5b,0x00000000,0x00030047,0x00000b5c, + 0x00000000,0x00030047,0x00000b5e,0x00000000,0x00030047,0x00000b60,0x00000000,0x00030047, + 0x00000b61,0x00000000,0x00030047,0x00000b62,0x00000000,0x00030047,0x00000b64,0x00000000, + 0x00030047,0x00000b66,0x00000000,0x00030047,0x00000b68,0x00000000,0x00030047,0x00000b6a, + 0x00000000,0x00030047,0x00000b6b,0x00000000,0x00030047,0x00000b6c,0x00000000,0x00030047, + 0x00000b6e,0x00000000,0x00030047,0x00000b70,0x00000000,0x00030047,0x00000b72,0x00000000, + 0x00030047,0x00000b73,0x00000000,0x00030047,0x00000b74,0x00000000,0x00030047,0x00000b76, + 0x00000000,0x00030047,0x00000b78,0x00000000,0x00030047,0x00000b7a,0x00000000,0x00030047, + 0x00000b7b,0x00000000,0x00030047,0x00000b7c,0x00000000,0x00030047,0x00000b7e,0x00000000, + 0x00030047,0x00000b7f,0x00000000,0x00030047,0x00000b82,0x00000000,0x00030047,0x00000b83, + 0x00000000,0x00030047,0x00000b84,0x00000000,0x00030047,0x00000b87,0x00000000,0x00030047, + 0x00000b89,0x00000000,0x00030047,0x00000b8a,0x00000000,0x00030047,0x00000b8b,0x00000000, + 0x00030047,0x00000b8c,0x00000000,0x00030047,0x00000b8e,0x00000000,0x00030047,0x00000b8f, + 0x00000000,0x00030047,0x00000b92,0x00000000,0x00030047,0x00000b93,0x00000000,0x00030047, + 0x00000b94,0x00000000,0x00030047,0x00000b97,0x00000000,0x00030047,0x00000b99,0x00000000, + 0x00030047,0x00000b9a,0x00000000,0x00030047,0x00000b9b,0x00000000,0x00030047,0x00000b9c, + 0x00000000,0x00030047,0x00000b9e,0x00000000,0x00030047,0x00000ba0,0x00000000,0x00030047, + 0x00000ba2,0x00000000,0x00030047,0x00000ba3,0x00000000,0x00030047,0x00000ba5,0x00000000, + 0x00030047,0x00000ba6,0x00000000,0x00030047,0x00000ba7,0x00000000,0x00030047,0x00000ba9, + 0x00000000,0x00030047,0x00000bab,0x00000000,0x00030047,0x00000bad,0x00000000,0x00030047, + 0x00000baf,0x00000000,0x00030047,0x00000bb0,0x00000000,0x00030047,0x00000bb2,0x00000000, + 0x00030047,0x00000bb3,0x00000000,0x00030047,0x00000bbd,0x00000000,0x00030047,0x00000bbf, + 0x00000000,0x00030047,0x00000bc0,0x00000000,0x00030047,0x00000bc3,0x00000000,0x00030047, + 0x00000bc4,0x00000000,0x00030047,0x00000bc6,0x00000000,0x00030047,0x00000bc8,0x00000000, + 0x00030047,0x00000bca,0x00000000,0x00030047,0x00000bcb,0x00000000,0x00030047,0x00000bcc, + 0x00000000,0x00030047,0x00000bce,0x00000000,0x00030047,0x00000bcf,0x00000000,0x00030047, + 0x00000bd1,0x00000000,0x00030047,0x00000bd5,0x00000000,0x00030047,0x00000bd6,0x00000000, + 0x00030047,0x00000bd9,0x00000000,0x00030047,0x00000bda,0x00000000,0x00030047,0x00000bdb, + 0x00000000,0x00030047,0x00000bdc,0x00000000,0x00030047,0x00000bdf,0x00000000,0x00030047, + 0x00000be0,0x00000000,0x00030047,0x00000be1,0x00000000,0x00030047,0x00000be2,0x00000000, + 0x00030047,0x00000be3,0x00000000,0x00030047,0x00000be4,0x00000000,0x00030047,0x00000be5, + 0x00000000,0x00030047,0x00000be7,0x00000000,0x00030047,0x00000be8,0x00000000,0x00030047, + 0x00000be9,0x00000000,0x00030047,0x00000beb,0x00000000,0x00030047,0x00000bec,0x00000000, + 0x00030047,0x00000bee,0x00000000,0x00030047,0x00000bf0,0x00000000,0x00030047,0x00000bf1, + 0x00000000,0x00030047,0x00000bf2,0x00000000,0x00030047,0x00000bf3,0x00000000,0x00030047, + 0x00000bf4,0x00000000,0x00030047,0x00000bf5,0x00000000,0x00030047,0x00000bf6,0x00000000, + 0x00030047,0x00000bf7,0x00000000,0x00030047,0x00000bf8,0x00000000,0x00030047,0x00000bf9, + 0x00000000,0x00030047,0x00000bfa,0x00000000,0x00030047,0x00000bfb,0x00000000,0x00030047, + 0x00000bfc,0x00000000,0x00030047,0x00000bfd,0x00000000,0x00030047,0x00000bfe,0x00000000, + 0x00030047,0x00000bff,0x00000000,0x00030047,0x00000c00,0x00000000,0x00030047,0x00000c01, + 0x00000000,0x00030047,0x00000c02,0x00000000,0x00030047,0x00000c03,0x00000000,0x00030047, + 0x00000c05,0x00000000,0x00030047,0x00000c06,0x00000000,0x00030047,0x00000c07,0x00000000, + 0x00030047,0x00000c08,0x00000000,0x00030047,0x00000c09,0x00000000,0x00030047,0x00000c0a, + 0x00000000,0x00030047,0x00000c0b,0x00000000,0x00030047,0x00000c0c,0x00000000,0x00030047, + 0x00000c0d,0x00000000,0x00030047,0x00000c0e,0x00000000,0x00030047,0x00000c0f,0x00000000, + 0x00030047,0x00000c10,0x00000000,0x00030047,0x00000c11,0x00000000,0x00030047,0x00000c12, + 0x00000000,0x00030047,0x00000c13,0x00000000,0x00030047,0x00000c14,0x00000000,0x00030047, + 0x00000c15,0x00000000,0x00030047,0x00000c16,0x00000000,0x00030047,0x00000c17,0x00000000, + 0x00030047,0x00000c19,0x00000000,0x00030047,0x00000c1b,0x00000000,0x00030047,0x00000c1d, + 0x00000000,0x00030047,0x00000c1e,0x00000000,0x00030047,0x00000c1f,0x00000000,0x00030047, + 0x00000c21,0x00000000,0x00030047,0x00000c22,0x00000000,0x00030047,0x00000c23,0x00000000, + 0x00030047,0x00000c24,0x00000000,0x00030047,0x00000c25,0x00000000,0x00030047,0x00000c26, + 0x00000000,0x00030047,0x00000c27,0x00000000,0x00030047,0x00000c29,0x00000000,0x00030047, + 0x00000c2a,0x00000000,0x00030047,0x00000c2b,0x00000000,0x00030047,0x00000c2c,0x00000000, + 0x00030047,0x00000c2d,0x00000000,0x00030047,0x00000c2e,0x00000000,0x00030047,0x00000c2f, + 0x00000000,0x00030047,0x00000c30,0x00000000,0x00030047,0x00000c31,0x00000000,0x00030047, + 0x00000c32,0x00000000,0x00030047,0x00000c33,0x00000000,0x00030047,0x00000c35,0x00000000, + 0x00030047,0x00000c36,0x00000000,0x00030047,0x00000c37,0x00000000,0x00030047,0x00000c39, + 0x00000000,0x00030047,0x00000c3a,0x00000000,0x00030047,0x00000c3b,0x00000000,0x00030047, + 0x00000c3d,0x00000000,0x00030047,0x00000c3e,0x00000000,0x00030047,0x00000c3f,0x00000000, + 0x00030047,0x00000c41,0x00000000,0x00030047,0x00000c42,0x00000000,0x00030047,0x00000c44, + 0x00000000,0x00030047,0x00000c45,0x00000000,0x00030047,0x00000c46,0x00000000,0x00030047, + 0x00000c4d,0x00000000,0x00030047,0x00000c4e,0x00000000,0x00030047,0x00000c51,0x00000000, + 0x00030047,0x00000c53,0x00000000,0x00030047,0x00000c54,0x00000000,0x00030047,0x00000c56, + 0x00000000,0x00030047,0x00000c57,0x00000000,0x00030047,0x00000c58,0x00000000,0x00030047, + 0x00000c59,0x00000000,0x00030047,0x00000c5a,0x00000000,0x00030047,0x00000c5b,0x00000000, + 0x00030047,0x00000c5c,0x00000000,0x00030047,0x00000c5d,0x00000000,0x00030047,0x00000c5e, + 0x00000000,0x00030047,0x00000c60,0x00000000,0x00030047,0x00000c61,0x00000000,0x00030047, + 0x00000c63,0x00000000,0x00030047,0x00000c66,0x00000000,0x00030047,0x00000c67,0x00000000, + 0x00030047,0x00000c68,0x00000000,0x00030047,0x00000c6a,0x00000000,0x00030047,0x00000c6b, + 0x00000000,0x00030047,0x00000c6c,0x00000000,0x00030047,0x00000c74,0x00000000,0x00030047, + 0x00000c7a,0x00000000,0x00030047,0x00000c7b,0x00000000,0x00030047,0x00000c7c,0x00000000, + 0x00030047,0x00000c7d,0x00000000,0x00030047,0x00000c7e,0x00000000,0x00030047,0x00000c80, + 0x00000000,0x00030047,0x00000c81,0x00000000,0x00030047,0x00000c83,0x00000000,0x00030047, + 0x00000c84,0x00000000,0x00030047,0x00000c85,0x00000000,0x00030047,0x00000c86,0x00000000, + 0x00030047,0x00000c87,0x00000000,0x00030047,0x00000c88,0x00000000,0x00030047,0x00000c89, + 0x00000000,0x00030047,0x00000c8b,0x00000000,0x00030047,0x00000c8c,0x00000000,0x00030047, + 0x00000c8d,0x00000000,0x00030047,0x00000c8f,0x00000000,0x00030047,0x00000c90,0x00000000, + 0x00030047,0x00000c91,0x00000000,0x00030047,0x00000c92,0x00000000,0x00030047,0x00000c93, + 0x00000000,0x00030047,0x00000c94,0x00000000,0x00030047,0x00000c95,0x00000000,0x00030047, + 0x00000c96,0x00000000,0x00030047,0x00000c97,0x00000000,0x00030047,0x00000c98,0x00000000, + 0x00030047,0x00000c99,0x00000000,0x00030047,0x00000c9b,0x00000000,0x00030047,0x00000c9c, + 0x00000000,0x00030047,0x00000c9d,0x00000000,0x00030047,0x00000ca6,0x00000000,0x00030047, + 0x00000cac,0x00000000,0x00030047,0x00000cad,0x00000000,0x00030047,0x00000cb2,0x00000000, + 0x00030047,0x00000cb8,0x00000000,0x00030047,0x00000cb9,0x00000000,0x00030047,0x00000cba, + 0x00000000,0x00030047,0x00000cbd,0x00000000,0x00030047,0x00000cbe,0x00000000,0x00030047, + 0x00000cbf,0x00000000,0x00030047,0x00000cc5,0x00000000,0x00030047,0x00000cc6,0x00000000, + 0x00030047,0x00000cc7,0x00000000,0x00030047,0x00000ccf,0x00000000,0x00030047,0x00000cd0, + 0x00000000,0x00030047,0x00000cd1,0x00000000,0x00030047,0x00000cd2,0x00000000,0x00030047, + 0x00000cd3,0x00000000,0x00030047,0x00000cd4,0x00000000,0x00030047,0x00000cd5,0x00000000, + 0x00030047,0x00000cd6,0x00000000,0x00030047,0x00000cd7,0x00000000,0x00030047,0x00000cd9, + 0x00000000,0x00030047,0x00000cda,0x00000000,0x00030047,0x00000cdb,0x00000000,0x00030047, + 0x00000cdc,0x00000000,0x00030047,0x00000cde,0x00000000,0x00030047,0x00000cdf,0x00000000, + 0x00030047,0x00000ce0,0x00000000,0x00030047,0x00000ce1,0x00000000,0x00030047,0x00000ce2, + 0x00000000,0x00030047,0x00000ce3,0x00000000,0x00030047,0x00000ce4,0x00000000,0x00030047, + 0x00000ce5,0x00000000,0x00030047,0x00000ce8,0x00000000,0x00030047,0x00000ceb,0x00000000, + 0x00030047,0x00000cec,0x00000000,0x00030047,0x00000ced,0x00000000,0x00030047,0x00000cee, + 0x00000000,0x00030047,0x00000cf3,0x00000000,0x00030047,0x00000cf6,0x00000000,0x00030047, + 0x00000cf7,0x00000000,0x00030047,0x00000cf8,0x00000000,0x00030047,0x00000cf9,0x00000000, + 0x00030047,0x00000cfe,0x00000000,0x00030047,0x00000d01,0x00000000,0x00030047,0x00000d02, + 0x00000000,0x00030047,0x00000d03,0x00000000,0x00030047,0x00000d08,0x00000000,0x00030047, + 0x00000d0b,0x00000000,0x00030047,0x00000d0c,0x00000000,0x00030047,0x00000d0d,0x00000000, + 0x00030047,0x00000d11,0x00000000,0x00030047,0x00000d12,0x00000000,0x00030047,0x00000d13, + 0x00000000,0x00030047,0x00000d15,0x00000000,0x00030047,0x00000d16,0x00000000,0x00030047, + 0x00000d18,0x00000000,0x00030047,0x00000d1c,0x00000000,0x00030047,0x00000d1d,0x00000000, + 0x00030047,0x00000d20,0x00000000,0x00030047,0x00000d21,0x00000000,0x00030047,0x00000d22, + 0x00000000,0x00030047,0x00000d23,0x00000000,0x00030047,0x00000d25,0x00000000,0x00030047, + 0x00000d27,0x00000000,0x00030047,0x00000d29,0x00000000,0x00030047,0x00000d2b,0x00000000, + 0x00030047,0x00000d2c,0x00000000,0x00030047,0x00000d2d,0x00000000,0x00030047,0x00000d2f, + 0x00000000,0x00030047,0x00000d31,0x00000000,0x00030047,0x00000d33,0x00000000,0x00030047, + 0x00000d35,0x00000000,0x00030047,0x00000d36,0x00000000,0x00030047,0x00000d37,0x00000000, + 0x00030047,0x00000d39,0x00000000,0x00030047,0x00000d3b,0x00000000,0x00030047,0x00000d3d, + 0x00000000,0x00030047,0x00000d3f,0x00000000,0x00030047,0x00000d40,0x00000000,0x00030047, + 0x00000d41,0x00000000,0x00030047,0x00000d43,0x00000000,0x00030047,0x00000d45,0x00000000, + 0x00030047,0x00000d47,0x00000000,0x00030047,0x00000d49,0x00000000,0x00030047,0x00000d4a, + 0x00000000,0x00030047,0x00000d4b,0x00000000,0x00030047,0x00000d4d,0x00000000,0x00030047, + 0x00000d4f,0x00000000,0x00030047,0x00000d51,0x00000000,0x00030047,0x00000d53,0x00000000, + 0x00030047,0x00000d54,0x00000000,0x00030047,0x00000d55,0x00000000,0x00030047,0x00000d57, + 0x00000000,0x00030047,0x00000d59,0x00000000,0x00030047,0x00000d5b,0x00000000,0x00030047, + 0x00000d5d,0x00000000,0x00030047,0x00000d5e,0x00000000,0x00030047,0x00000d5f,0x00000000, + 0x00030047,0x00000d61,0x00000000,0x00030047,0x00000d63,0x00000000,0x00030047,0x00000d65, + 0x00000000,0x00030047,0x00000d67,0x00000000,0x00030047,0x00000d68,0x00000000,0x00030047, + 0x00000d69,0x00000000,0x00030047,0x00000d6b,0x00000000,0x00030047,0x00000d6d,0x00000000, + 0x00030047,0x00000d6f,0x00000000,0x00030047,0x00000d71,0x00000000,0x00030047,0x00000d72, + 0x00000000,0x00030047,0x00000d73,0x00000000,0x00030047,0x00000d75,0x00000000,0x00030047, + 0x00000d77,0x00000000,0x00030047,0x00000d79,0x00000000,0x00030047,0x00000d7b,0x00000000, + 0x00030047,0x00000d7c,0x00000000,0x00030047,0x00000d7d,0x00000000,0x00030047,0x00000d7f, + 0x00000000,0x00030047,0x00000d81,0x00000000,0x00030047,0x00000d83,0x00000000,0x00030047, + 0x00000d85,0x00000000,0x00030047,0x00000d86,0x00000000,0x00030047,0x00000d87,0x00000000, + 0x00030047,0x00000d89,0x00000000,0x00030047,0x00000d8b,0x00000000,0x00030047,0x00000d8d, + 0x00000000,0x00030047,0x00000d8f,0x00000000,0x00030047,0x00000d90,0x00000000,0x00030047, + 0x00000d91,0x00000000,0x00030047,0x00000d93,0x00000000,0x00030047,0x00000d95,0x00000000, + 0x00030047,0x00000d97,0x00000000,0x00030047,0x00000d99,0x00000000,0x00030047,0x00000d9a, + 0x00000000,0x00030047,0x00000d9b,0x00000000,0x00030047,0x00000d9d,0x00000000,0x00030047, + 0x00000d9f,0x00000000,0x00030047,0x00000da1,0x00000000,0x00030047,0x00000da3,0x00000000, + 0x00030047,0x00000da4,0x00000000,0x00030047,0x00000da5,0x00000000,0x00030047,0x00000da7, + 0x00000000,0x00030047,0x00000da9,0x00000000,0x00030047,0x00000dab,0x00000000,0x00030047, + 0x00000dad,0x00000000,0x00030047,0x00000daf,0x00000000,0x00030047,0x00000db0,0x00000000, + 0x00030047,0x00000db1,0x00000000,0x00030047,0x00000db3,0x00000000,0x00030047,0x00000db5, + 0x00000000,0x00030047,0x00000db6,0x00000000,0x00030047,0x00000db7,0x00000000,0x00030047, + 0x00000db9,0x00000000,0x00030047,0x00000dbb,0x00000000,0x00030047,0x00000dbd,0x00000000, + 0x00030047,0x00000dbe,0x00000000,0x00030047,0x00000dc0,0x00000000,0x00030047,0x00000dc1, + 0x00000000,0x00030047,0x00000dc2,0x00000000,0x00030047,0x00000dc3,0x00000000,0x00030047, + 0x00000dc9,0x00000000,0x00030047,0x00000dcc,0x00000000,0x00030047,0x00000dce,0x00000000, + 0x00030047,0x00000dcf,0x00000000,0x00030047,0x00000dd1,0x00000000,0x00030047,0x00000dd2, + 0x00000000,0x00030047,0x00000dd5,0x00000000,0x00030047,0x00000dd6,0x00000000,0x00030047, + 0x00000dd7,0x00000000,0x00030047,0x00000dda,0x00000000,0x00030047,0x00000ddc,0x00000000, + 0x00030047,0x00000ddd,0x00000000,0x00030047,0x00000dde,0x00000000,0x00030047,0x00000ddf, + 0x00000000,0x00030047,0x00000de1,0x00000000,0x00030047,0x00000de2,0x00000000,0x00030047, + 0x00000de5,0x00000000,0x00030047,0x00000de6,0x00000000,0x00030047,0x00000de7,0x00000000, + 0x00030047,0x00000dea,0x00000000,0x00030047,0x00000dec,0x00000000,0x00030047,0x00000ded, + 0x00000000,0x00030047,0x00000dee,0x00000000,0x00030047,0x00000def,0x00000000,0x00030047, + 0x00000df1,0x00000000,0x00030047,0x00000df2,0x00000000,0x00030047,0x00000df5,0x00000000, + 0x00030047,0x00000df6,0x00000000,0x00030047,0x00000df7,0x00000000,0x00030047,0x00000dfa, + 0x00000000,0x00030047,0x00000dfc,0x00000000,0x00030047,0x00000dfd,0x00000000,0x00030047, + 0x00000dfe,0x00000000,0x00030047,0x00000dff,0x00000000,0x00030047,0x00000e01,0x00000000, + 0x00030047,0x00000e02,0x00000000,0x00030047,0x00000e05,0x00000000,0x00030047,0x00000e06, + 0x00000000,0x00030047,0x00000e07,0x00000000,0x00030047,0x00000e0a,0x00000000,0x00030047, + 0x00000e0c,0x00000000,0x00030047,0x00000e0d,0x00000000,0x00030047,0x00000e0e,0x00000000, + 0x00030047,0x00000e0f,0x00000000,0x00030047,0x00000e10,0x00000000,0x00030047,0x00000e11, + 0x00000000,0x00030047,0x00000e12,0x00000000,0x00030047,0x00000e13,0x00000000,0x00030047, + 0x00000e14,0x00000000,0x00030047,0x00000e15,0x00000000,0x00030047,0x00000e16,0x00000000, + 0x00030047,0x00000e17,0x00000000,0x00030047,0x00000e18,0x00000000,0x00030047,0x00000e19, + 0x00000000,0x00030047,0x00000e1a,0x00000000,0x00030047,0x00000e1b,0x00000000,0x00030047, + 0x00000e1c,0x00000000,0x00030047,0x00000e1e,0x00000000,0x00030047,0x00000e20,0x00000000, + 0x00030047,0x00000e21,0x00000000,0x00030047,0x00000e23,0x00000000,0x00030047,0x00000e24, + 0x00000000,0x00030047,0x00000e25,0x00000000,0x00030047,0x00000e26,0x00000000,0x00030047, + 0x00000e27,0x00000000,0x00030047,0x00000e2a,0x00000000,0x00030047,0x00000e2c,0x00000000, + 0x00030047,0x00000e2d,0x00000000,0x00030047,0x00000e30,0x00000000,0x00030047,0x00000e31, + 0x00000000,0x00030047,0x00000e34,0x00000000,0x00030047,0x00000e36,0x00000000,0x00030047, + 0x00000e37,0x00000000,0x00030047,0x00000e38,0x00000000,0x00030047,0x00000e39,0x00000000, + 0x00030047,0x00000e3a,0x00000000,0x00030047,0x00000e3b,0x00000000,0x00030047,0x00000e3c, + 0x00000000,0x00030047,0x00000e3d,0x00000000,0x00030047,0x00000e3e,0x00000000,0x00030047, + 0x00000e3f,0x00000000,0x00030047,0x00000e40,0x00000000,0x00030047,0x00000e41,0x00000000, + 0x00030047,0x00000e42,0x00000000,0x00030047,0x00000e44,0x00000000,0x00030047,0x00000e46, + 0x00000000,0x00030047,0x00000e47,0x00000000,0x00030047,0x00000e48,0x00000000,0x00030047, + 0x00000e4a,0x00000000,0x00030047,0x00000e4c,0x00000000,0x00030047,0x00000e4e,0x00000000, + 0x00030047,0x00000e50,0x00000000,0x00030047,0x00000e51,0x00000000,0x00030047,0x00000e52, + 0x00000000,0x00030047,0x00000e53,0x00000000,0x00030047,0x00000e54,0x00000000,0x00030047, + 0x00000e56,0x00000000,0x00030047,0x00000e58,0x00000000,0x00030047,0x00000e59,0x00000000, + 0x00030047,0x00000e5a,0x00000000,0x00030047,0x00000e5c,0x00000000,0x00030047,0x00000e5e, + 0x00000000,0x00030047,0x00000e60,0x00000000,0x00030047,0x00000e62,0x00000000,0x00030047, + 0x00000e63,0x00000000,0x00030047,0x00000e64,0x00000000,0x00030047,0x00000e66,0x00000000, + 0x00030047,0x00000e68,0x00000000,0x00030047,0x00000e6a,0x00000000,0x00030047,0x00000e6b, + 0x00000000,0x00030047,0x00000e6c,0x00000000,0x00030047,0x00000e6e,0x00000000,0x00030047, + 0x00000e70,0x00000000,0x00030047,0x00000e72,0x00000000,0x00030047,0x00000e73,0x00000000, + 0x00030047,0x00000e74,0x00000000,0x00030047,0x00000e76,0x00000000,0x00030047,0x00000e77, + 0x00000000,0x00030047,0x00000e7a,0x00000000,0x00030047,0x00000e7b,0x00000000,0x00030047, + 0x00000e7c,0x00000000,0x00030047,0x00000e7f,0x00000000,0x00030047,0x00000e81,0x00000000, + 0x00030047,0x00000e82,0x00000000,0x00030047,0x00000e83,0x00000000,0x00030047,0x00000e84, + 0x00000000,0x00030047,0x00000e86,0x00000000,0x00030047,0x00000e87,0x00000000,0x00030047, + 0x00000e8a,0x00000000,0x00030047,0x00000e8b,0x00000000,0x00030047,0x00000e8c,0x00000000, + 0x00030047,0x00000e8f,0x00000000,0x00030047,0x00000e91,0x00000000,0x00030047,0x00000e92, + 0x00000000,0x00030047,0x00000e93,0x00000000,0x00030047,0x00000e94,0x00000000,0x00030047, + 0x00000e96,0x00000000,0x00030047,0x00000e98,0x00000000,0x00030047,0x00000e9a,0x00000000, + 0x00030047,0x00000e9b,0x00000000,0x00030047,0x00000e9d,0x00000000,0x00030047,0x00000e9e, + 0x00000000,0x00030047,0x00000e9f,0x00000000,0x00030047,0x00000ea1,0x00000000,0x00030047, + 0x00000ea3,0x00000000,0x00030047,0x00000ea5,0x00000000,0x00030047,0x00000ea7,0x00000000, + 0x00030047,0x00000ea8,0x00000000,0x00030047,0x00000ea9,0x00000000,0x00030047,0x00000eab, + 0x00000000,0x00030047,0x00000ead,0x00000000,0x00030047,0x00000eaf,0x00000000,0x00030047, + 0x00000eb1,0x00000000,0x00030047,0x00000eb3,0x00000000,0x00030047,0x00000eb4,0x00000000, + 0x00030047,0x00000eb5,0x00000000,0x00030047,0x00000eb7,0x00000000,0x00030047,0x00000eb9, + 0x00000000,0x00030047,0x00000eba,0x00000000,0x00030047,0x00000ebb,0x00000000,0x00030047, + 0x00000ebd,0x00000000,0x00030047,0x00000ebf,0x00000000,0x00030047,0x00000ec1,0x00000000, + 0x00030047,0x00000ec2,0x00000000,0x00030047,0x00000ec4,0x00000000,0x00030047,0x00000ec5, + 0x00000000,0x00030047,0x00000ec6,0x00000000,0x00030047,0x00000ec7,0x00000000,0x00030047, + 0x00000ecd,0x00000000,0x00030047,0x00000ed0,0x00000000,0x00030047,0x00000ed2,0x00000000, + 0x00030047,0x00000ed3,0x00000000,0x00030047,0x00000ed5,0x00000000,0x00030047,0x00000ed6, + 0x00000000,0x00030047,0x00000ed9,0x00000000,0x00030047,0x00000eda,0x00000000,0x00030047, + 0x00000edb,0x00000000,0x00030047,0x00000ede,0x00000000,0x00030047,0x00000ee0,0x00000000, + 0x00030047,0x00000ee1,0x00000000,0x00030047,0x00000ee2,0x00000000,0x00030047,0x00000ee3, + 0x00000000,0x00030047,0x00000ee5,0x00000000,0x00030047,0x00000ee6,0x00000000,0x00030047, + 0x00000ee9,0x00000000,0x00030047,0x00000eea,0x00000000,0x00030047,0x00000eeb,0x00000000, + 0x00030047,0x00000eee,0x00000000,0x00030047,0x00000ef0,0x00000000,0x00030047,0x00000ef1, + 0x00000000,0x00030047,0x00000ef2,0x00000000,0x00030047,0x00000ef3,0x00000000,0x00030047, + 0x00000ef5,0x00000000,0x00030047,0x00000ef6,0x00000000,0x00030047,0x00000ef9,0x00000000, + 0x00030047,0x00000efa,0x00000000,0x00030047,0x00000efb,0x00000000,0x00030047,0x00000efe, + 0x00000000,0x00030047,0x00000f00,0x00000000,0x00030047,0x00000f01,0x00000000,0x00030047, + 0x00000f02,0x00000000,0x00030047,0x00000f03,0x00000000,0x00030047,0x00000f05,0x00000000, + 0x00030047,0x00000f06,0x00000000,0x00030047,0x00000f09,0x00000000,0x00030047,0x00000f0a, + 0x00000000,0x00030047,0x00000f0b,0x00000000,0x00030047,0x00000f0e,0x00000000,0x00030047, + 0x00000f10,0x00000000,0x00030047,0x00000f11,0x00000000,0x00030047,0x00000f12,0x00000000, + 0x00030047,0x00000f13,0x00000000,0x00030047,0x00000f14,0x00000000,0x00030047,0x00000f15, + 0x00000000,0x00030047,0x00000f16,0x00000000,0x00030047,0x00000f17,0x00000000,0x00030047, + 0x00000f18,0x00000000,0x00030047,0x00000f19,0x00000000,0x00030047,0x00000f1a,0x00000000, + 0x00030047,0x00000f1b,0x00000000,0x00030047,0x00000f1c,0x00000000,0x00030047,0x00000f1d, + 0x00000000,0x00030047,0x00000f1e,0x00000000,0x00030047,0x00000f1f,0x00000000,0x00030047, + 0x00000f20,0x00000000,0x00030047,0x00000f22,0x00000000,0x00030047,0x00000f24,0x00000000, + 0x00030047,0x00000f25,0x00000000,0x00030047,0x00000f27,0x00000000,0x00030047,0x00000f28, + 0x00000000,0x00030047,0x00000f29,0x00000000,0x00030047,0x00000f2a,0x00000000,0x00030047, + 0x00000f2b,0x00000000,0x00030047,0x00000f2e,0x00000000,0x00030047,0x00000f30,0x00000000, + 0x00030047,0x00000f31,0x00000000,0x00030047,0x00000f34,0x00000000,0x00030047,0x00000f35, + 0x00000000,0x00030047,0x00000f38,0x00000000,0x00030047,0x00000f3a,0x00000000,0x00030047, + 0x00000f3b,0x00000000,0x00030047,0x00000f3c,0x00000000,0x00030047,0x00000f3d,0x00000000, + 0x00030047,0x00000f3e,0x00000000,0x00030047,0x00000f3f,0x00000000,0x00030047,0x00000f40, + 0x00000000,0x00030047,0x00000f41,0x00000000,0x00030047,0x00000f42,0x00000000,0x00030047, + 0x00000f43,0x00000000,0x00030047,0x00000f44,0x00000000,0x00030047,0x00000f45,0x00000000, + 0x00030047,0x00000f46,0x00000000,0x00030047,0x00000f48,0x00000000,0x00030047,0x00000f4a, + 0x00000000,0x00030047,0x00000f4b,0x00000000,0x00030047,0x00000f4c,0x00000000,0x00030047, + 0x00000f4e,0x00000000,0x00030047,0x00000f50,0x00000000,0x00030047,0x00000f52,0x00000000, + 0x00030047,0x00000f54,0x00000000,0x00030047,0x00000f55,0x00000000,0x00030047,0x00000f56, + 0x00000000,0x00030047,0x00000f57,0x00000000,0x00030047,0x00000f58,0x00000000,0x00030047, + 0x00000f5a,0x00000000,0x00030047,0x00000f5c,0x00000000,0x00030047,0x00000f5d,0x00000000, + 0x00030047,0x00000f5e,0x00000000,0x00030047,0x00000f60,0x00000000,0x00030047,0x00000f62, + 0x00000000,0x00030047,0x00000f64,0x00000000,0x00030047,0x00000f66,0x00000000,0x00030047, + 0x00000f67,0x00000000,0x00030047,0x00000f68,0x00000000,0x00030047,0x00000f6a,0x00000000, + 0x00030047,0x00000f6c,0x00000000,0x00030047,0x00000f6e,0x00000000,0x00030047,0x00000f6f, + 0x00000000,0x00030047,0x00000f70,0x00000000,0x00030047,0x00000f72,0x00000000,0x00030047, + 0x00000f74,0x00000000,0x00030047,0x00000f76,0x00000000,0x00030047,0x00000f77,0x00000000, + 0x00030047,0x00000f78,0x00000000,0x00030047,0x00000f7a,0x00000000,0x00030047,0x00000f7b, + 0x00000000,0x00030047,0x00000f7e,0x00000000,0x00030047,0x00000f7f,0x00000000,0x00030047, + 0x00000f80,0x00000000,0x00030047,0x00000f83,0x00000000,0x00030047,0x00000f85,0x00000000, + 0x00030047,0x00000f86,0x00000000,0x00030047,0x00000f87,0x00000000,0x00030047,0x00000f88, + 0x00000000,0x00030047,0x00000f8a,0x00000000,0x00030047,0x00000f8b,0x00000000,0x00030047, + 0x00000f8e,0x00000000,0x00030047,0x00000f8f,0x00000000,0x00030047,0x00000f90,0x00000000, + 0x00030047,0x00000f93,0x00000000,0x00030047,0x00000f95,0x00000000,0x00030047,0x00000f96, + 0x00000000,0x00030047,0x00000f97,0x00000000,0x00030047,0x00000f98,0x00000000,0x00030047, + 0x00000f9a,0x00000000,0x00030047,0x00000f9c,0x00000000,0x00030047,0x00000f9e,0x00000000, + 0x00030047,0x00000f9f,0x00000000,0x00030047,0x00000fa1,0x00000000,0x00030047,0x00000fa2, + 0x00000000,0x00030047,0x00000fa3,0x00000000,0x00030047,0x00000fa5,0x00000000,0x00030047, + 0x00000fa7,0x00000000,0x00030047,0x00000fa9,0x00000000,0x00030047,0x00000fab,0x00000000, + 0x00030047,0x00000fac,0x00000000,0x00030047,0x00000fad,0x00000000,0x00030047,0x00000faf, + 0x00000000,0x00030047,0x00000fb1,0x00000000,0x00030047,0x00000fb3,0x00000000,0x00030047, + 0x00000fb5,0x00000000,0x00030047,0x00000fb6,0x00000000,0x00030047,0x00000fb7,0x00000000, + 0x00030047,0x00000fb8,0x00000000,0x00030047,0x00000fb9,0x00000000,0x00030047,0x00000fba, + 0x00000000,0x00030047,0x00000fbb,0x00000000,0x00030047,0x00000fbc,0x00000000,0x00030047, + 0x00000fbd,0x00000000,0x00030047,0x00000fbe,0x00000000,0x00030047,0x00000fbf,0x00000000, + 0x00030047,0x00000fc0,0x00000000,0x00030047,0x00000fc1,0x00000000,0x00030047,0x00000fc2, + 0x00000000,0x00030047,0x00000fc3,0x00000000,0x00030047,0x00000fc4,0x00000000,0x00030047, + 0x00000fc6,0x00000000,0x00030047,0x00000fc8,0x00000000,0x00030047,0x00000fc9,0x00000000, + 0x00030047,0x00000fcb,0x00000000,0x00030047,0x00000fcc,0x00000000,0x00030047,0x00000fcd, + 0x00000000,0x00030047,0x00000fce,0x00000000,0x00030047,0x00000fcf,0x00000000,0x00030047, + 0x00000fd2,0x00000000,0x00030047,0x00000fd4,0x00000000,0x00030047,0x00000fd5,0x00000000, + 0x00030047,0x00000fd8,0x00000000,0x00030047,0x00000fd9,0x00000000,0x00030047,0x00000fdc, + 0x00000000,0x00030047,0x00000fde,0x00000000,0x00030047,0x00000fdf,0x00000000,0x00030047, + 0x00000fe0,0x00000000,0x00030047,0x00000fe1,0x00000000,0x00030047,0x00000fe2,0x00000000, + 0x00030047,0x00000fe3,0x00000000,0x00030047,0x00000fe4,0x00000000,0x00030047,0x00000fe5, + 0x00000000,0x00030047,0x00000fe6,0x00000000,0x00030047,0x00000fe7,0x00000000,0x00030047, + 0x00000fe8,0x00000000,0x00030047,0x00000fe9,0x00000000,0x00030047,0x00000fea,0x00000000, + 0x00030047,0x00000fec,0x00000000,0x00030047,0x00000fee,0x00000000,0x00030047,0x00000fef, + 0x00000000,0x00030047,0x00000ff0,0x00000000,0x00030047,0x00000ff2,0x00000000,0x00030047, + 0x00000ff4,0x00000000,0x00030047,0x00000ff6,0x00000000,0x00030047,0x00000ff8,0x00000000, + 0x00030047,0x00000ff9,0x00000000,0x00030047,0x00000ffa,0x00000000,0x00030047,0x00000ffb, + 0x00000000,0x00030047,0x00000ffc,0x00000000,0x00030047,0x00000ffe,0x00000000,0x00030047, + 0x00001000,0x00000000,0x00030047,0x00001001,0x00000000,0x00030047,0x00001002,0x00000000, + 0x00030047,0x00001004,0x00000000,0x00030047,0x00001006,0x00000000,0x00030047,0x00001008, + 0x00000000,0x00030047,0x0000100a,0x00000000,0x00030047,0x0000100b,0x00000000,0x00030047, + 0x0000100c,0x00000000,0x00030047,0x0000100e,0x00000000,0x00030047,0x00001010,0x00000000, + 0x00030047,0x00001012,0x00000000,0x00030047,0x00001013,0x00000000,0x00030047,0x00001014, + 0x00000000,0x00030047,0x00001016,0x00000000,0x00030047,0x00001018,0x00000000,0x00030047, + 0x0000101a,0x00000000,0x00030047,0x0000101b,0x00000000,0x00030047,0x0000101c,0x00000000, + 0x00030047,0x0000101e,0x00000000,0x00030047,0x0000101f,0x00000000,0x00030047,0x00001022, + 0x00000000,0x00030047,0x00001023,0x00000000,0x00030047,0x00001024,0x00000000,0x00030047, + 0x00001027,0x00000000,0x00030047,0x00001029,0x00000000,0x00030047,0x0000102a,0x00000000, + 0x00030047,0x0000102b,0x00000000,0x00030047,0x0000102c,0x00000000,0x00030047,0x0000102e, + 0x00000000,0x00030047,0x0000102f,0x00000000,0x00030047,0x00001032,0x00000000,0x00030047, + 0x00001033,0x00000000,0x00030047,0x00001034,0x00000000,0x00030047,0x00001037,0x00000000, + 0x00030047,0x00001039,0x00000000,0x00030047,0x0000103a,0x00000000,0x00030047,0x0000103b, + 0x00000000,0x00030047,0x0000103c,0x00000000,0x00030047,0x0000103e,0x00000000,0x00030047, + 0x00001040,0x00000000,0x00030047,0x00001042,0x00000000,0x00030047,0x00001043,0x00000000, + 0x00030047,0x00001045,0x00000000,0x00030047,0x00001046,0x00000000,0x00030047,0x00001047, + 0x00000000,0x00030047,0x00001049,0x00000000,0x00030047,0x0000104b,0x00000000,0x00030047, + 0x0000104d,0x00000000,0x00030047,0x0000104f,0x00000000,0x00030047,0x00001050,0x00000000, + 0x00030047,0x00001051,0x00000000,0x00030047,0x00001053,0x00000000,0x00030047,0x00001055, + 0x00000000,0x00030047,0x00001057,0x00000000,0x00030047,0x00001059,0x00000000,0x00030047, + 0x0000105a,0x00000000,0x00030047,0x0000105b,0x00000000,0x00030047,0x0000105c,0x00000000, + 0x00030047,0x0000105d,0x00000000,0x00030047,0x0000105e,0x00000000,0x00030047,0x0000105f, + 0x00000000,0x00030047,0x00001060,0x00000000,0x00030047,0x00001061,0x00000000,0x00030047, + 0x00001062,0x00000000,0x00030047,0x00001063,0x00000000,0x00030047,0x00001064,0x00000000, + 0x00030047,0x00001065,0x00000000,0x00030047,0x00001066,0x00000000,0x00030047,0x00001067, + 0x00000000,0x00030047,0x00001068,0x00000000,0x00030047,0x0000106a,0x00000000,0x00030047, + 0x0000106c,0x00000000,0x00030047,0x0000106d,0x00000000,0x00030047,0x0000106f,0x00000000, + 0x00030047,0x00001070,0x00000000,0x00030047,0x00001071,0x00000000,0x00030047,0x00001072, + 0x00000000,0x00030047,0x00001073,0x00000000,0x00030047,0x00001076,0x00000000,0x00030047, + 0x00001078,0x00000000,0x00030047,0x00001079,0x00000000,0x00030047,0x0000107c,0x00000000, + 0x00030047,0x0000107d,0x00000000,0x00030047,0x00001080,0x00000000,0x00030047,0x00001082, + 0x00000000,0x00030047,0x00001083,0x00000000,0x00030047,0x00001084,0x00000000,0x00030047, + 0x00001085,0x00000000,0x00030047,0x00001086,0x00000000,0x00030047,0x00001087,0x00000000, + 0x00030047,0x00001088,0x00000000,0x00030047,0x00001089,0x00000000,0x00030047,0x0000108a, + 0x00000000,0x00030047,0x0000108b,0x00000000,0x00030047,0x0000108c,0x00000000,0x00030047, + 0x0000108d,0x00000000,0x00030047,0x0000108e,0x00000000,0x00030047,0x00001090,0x00000000, + 0x00030047,0x00001092,0x00000000,0x00030047,0x00001093,0x00000000,0x00030047,0x00001094, + 0x00000000,0x00030047,0x00001096,0x00000000,0x00030047,0x00001098,0x00000000,0x00030047, + 0x0000109a,0x00000000,0x00030047,0x0000109c,0x00000000,0x00030047,0x0000109d,0x00000000, + 0x00030047,0x0000109e,0x00000000,0x00030047,0x0000109f,0x00000000,0x00030047,0x000010a0, + 0x00000000,0x00030047,0x000010a2,0x00000000,0x00030047,0x000010a4,0x00000000,0x00030047, + 0x000010a5,0x00000000,0x00030047,0x000010a6,0x00000000,0x00030047,0x000010a8,0x00000000, + 0x00030047,0x000010aa,0x00000000,0x00030047,0x000010ac,0x00000000,0x00030047,0x000010ae, + 0x00000000,0x00030047,0x000010af,0x00000000,0x00030047,0x000010b0,0x00000000,0x00030047, + 0x000010b2,0x00000000,0x00030047,0x000010b4,0x00000000,0x00030047,0x000010b6,0x00000000, + 0x00030047,0x000010b7,0x00000000,0x00030047,0x000010b8,0x00000000,0x00030047,0x000010ba, + 0x00000000,0x00030047,0x000010bc,0x00000000,0x00030047,0x000010be,0x00000000,0x00030047, + 0x000010bf,0x00000000,0x00030047,0x000010c0,0x00000000,0x00030047,0x000010c2,0x00000000, + 0x00030047,0x000010c3,0x00000000,0x00030047,0x000010c6,0x00000000,0x00030047,0x000010c7, + 0x00000000,0x00030047,0x000010c8,0x00000000,0x00030047,0x000010cb,0x00000000,0x00030047, + 0x000010cd,0x00000000,0x00030047,0x000010ce,0x00000000,0x00030047,0x000010cf,0x00000000, + 0x00030047,0x000010d0,0x00000000,0x00030047,0x000010d2,0x00000000,0x00030047,0x000010d3, + 0x00000000,0x00030047,0x000010d6,0x00000000,0x00030047,0x000010d7,0x00000000,0x00030047, + 0x000010d8,0x00000000,0x00030047,0x000010db,0x00000000,0x00030047,0x000010dd,0x00000000, + 0x00030047,0x000010de,0x00000000,0x00030047,0x000010df,0x00000000,0x00030047,0x000010e0, + 0x00000000,0x00030047,0x000010e2,0x00000000,0x00030047,0x000010e4,0x00000000,0x00030047, + 0x000010e6,0x00000000,0x00030047,0x000010e7,0x00000000,0x00030047,0x000010e9,0x00000000, + 0x00030047,0x000010ea,0x00000000,0x00030047,0x000010eb,0x00000000,0x00030047,0x000010ed, + 0x00000000,0x00030047,0x000010ef,0x00000000,0x00030047,0x000010f1,0x00000000,0x00030047, + 0x000010f3,0x00000000,0x00030047,0x000010f4,0x00000000,0x00030047,0x000010f5,0x00000000, + 0x00030047,0x000010f8,0x00000000,0x00030047,0x000010f9,0x00000000,0x00030047,0x000010fb, + 0x00000000,0x00030047,0x000010fc,0x00000000,0x00030047,0x000010fd,0x00000000,0x00030047, + 0x00001101,0x00000000,0x00030047,0x00001102,0x00000000,0x00030047,0x00001104,0x00000000, + 0x00030047,0x00001105,0x00000000,0x00030047,0x00001106,0x00000000,0x00030047,0x00001108, + 0x00000000,0x00030047,0x0000110a,0x00000000,0x00030047,0x0000110b,0x00000000,0x00030047, + 0x0000110c,0x00000000,0x00030047,0x0000110d,0x00000000,0x00030047,0x00001117,0x00000000, + 0x00030047,0x00001118,0x00000000,0x00030047,0x00001119,0x00000000,0x00030047,0x0000111a, + 0x00000000,0x00030047,0x0000111b,0x00000000,0x00030047,0x0000111c,0x00000000,0x00030047, + 0x0000111d,0x00000000,0x00030047,0x0000111e,0x00000000,0x00030047,0x00001120,0x00000000, + 0x00030047,0x00001122,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017, + 0x0000000c,0x00000006,0x00000004,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040017, + 0x00000012,0x00000006,0x00000002,0x00040020,0x00000013,0x00000007,0x00000012,0x00040015, + 0x00000018,0x00000020,0x00000000,0x00040020,0x00000019,0x00000007,0x00000018,0x00040017, + 0x0000002a,0x00000006,0x00000003,0x00040018,0x00000039,0x00000012,0x00000002,0x00040020, + 0x00000046,0x00000007,0x0000002a,0x00040015,0x00000088,0x00000020,0x00000001,0x00040017, + 0x00000089,0x00000088,0x00000002,0x00040020,0x0000008a,0x00000007,0x00000089,0x0004002b, + 0x00000018,0x000000b5,0x00000000,0x0004002b,0x00000018,0x000000b8,0x00000001,0x0004002b, + 0x00000018,0x000000cb,0x00000002,0x0004002b,0x00000018,0x000000e2,0x00000003,0x0004002b, + 0x00000006,0x000000eb,0x3f800000,0x0004002b,0x00000006,0x000000ec,0x00000000,0x00020014, + 0x000000fa,0x0004002b,0x00000006,0x00000137,0x3d897143,0x0004002b,0x00000006,0x0000013b, + 0x3bbf4590,0x0004002b,0x00000006,0x00000142,0x4253ee82,0x00030030,0x000000fa,0x0000014d, + 0x0004002b,0x00000006,0x00000161,0x3e99999a,0x0004002b,0x00000006,0x00000162,0x3f170a3d, + 0x0004002b,0x00000006,0x00000163,0x3de147ae,0x0004002b,0x00000006,0x0000017d,0x388205ff, + 0x0004002b,0x00000006,0x000001e3,0x40000000,0x0004002b,0x00000006,0x000001ea,0x3f000000, + 0x00040017,0x000001f0,0x000000fa,0x00000003,0x00040020,0x0000026c,0x00000007,0x00000088, + 0x0004002b,0x00000088,0x0000026e,0x00000000,0x0004002b,0x00000088,0x00000275,0x00000003, + 0x0004002b,0x00000006,0x00000287,0x3e800000,0x0004002b,0x00000006,0x0000028c,0x41800000, + 0x0004002b,0x00000006,0x00000291,0x41400000,0x0004002b,0x00000006,0x00000297,0x40400000, + 0x0004002b,0x00000088,0x000002a3,0x00000001,0x00030030,0x000000fa,0x000002be,0x0004002b, + 0x00000006,0x00000312,0x3a000000,0x0004002b,0x00000006,0x00000314,0xc2000000,0x0004002b, + 0x00000006,0x00000324,0x3a808081,0x00040017,0x00000327,0x000000fa,0x00000002,0x00040017, + 0x00000331,0x00000018,0x00000002,0x00040020,0x00000332,0x00000007,0x00000331,0x0003001d, + 0x00000334,0x00000331,0x0003001e,0x00000335,0x00000334,0x00040020,0x00000336,0x00000002, + 0x00000335,0x0004003b,0x00000336,0x00000337,0x00000002,0x00040020,0x00000339,0x00000002, + 0x00000331,0x0004002b,0x00000018,0x00000340,0x00000300,0x00030030,0x000000fa,0x00000347, + 0x0004002b,0x00000018,0x0000034c,0x00000200,0x0004002b,0x00000006,0x00000356,0xbf800000, + 0x00030030,0x000000fa,0x00000360,0x0004002b,0x00000018,0x00000366,0x00000010,0x00090019, + 0x0000036c,0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002,0x00000000, + 0x00040020,0x0000036d,0x00000000,0x0000036c,0x0004003b,0x0000036d,0x0000036e,0x00000000, + 0x0005002c,0x00000089,0x00000370,0x0000026e,0x0000026e,0x00030030,0x000000fa,0x00000379, + 0x0004002b,0x00000018,0x0000037e,0x00000400,0x00040020,0x00000384,0x00000007,0x00000039, + 0x0003001d,0x00000386,0x0000000c,0x0003001e,0x00000387,0x00000386,0x00040020,0x00000388, + 0x00000002,0x00000387,0x0004003b,0x00000388,0x00000389,0x00000002,0x0004002b,0x00000018, + 0x0000038b,0x00000004,0x00040020,0x0000038f,0x00000002,0x0000000c,0x00040020,0x0000039b, + 0x00000001,0x0000000c,0x0004003b,0x0000039b,0x0000039c,0x00000001,0x0004002b,0x00000018, + 0x000003bc,0x0000000f,0x00090019,0x00000405,0x00000006,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x00000406,0x00000000,0x00000405,0x0004003b, + 0x00000406,0x00000407,0x00000000,0x0002001a,0x00000409,0x00040020,0x0000040a,0x00000000, + 0x00000409,0x0004003b,0x0000040a,0x0000040b,0x00000000,0x0003001b,0x0000040d,0x00000405, + 0x00030030,0x000000fa,0x00000418,0x0004002b,0x00000088,0x00000424,0x00000004,0x0004003b, + 0x0000036d,0x0000042e,0x00000000,0x00040020,0x0000044a,0x00000003,0x0000000c,0x0004003b, + 0x0000044a,0x0000044b,0x00000003,0x0004003b,0x0000044a,0x0000044d,0x00000003,0x0004003b, + 0x00000406,0x00000455,0x00000000,0x0004003b,0x0000040a,0x00000457,0x00000000,0x00040020, + 0x0000045a,0x00000001,0x00000012,0x0004003b,0x0000045a,0x0000045b,0x00000001,0x0004003b, + 0x0000039b,0x00000462,0x00000001,0x00090019,0x0000046e,0x00000018,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x0000046f,0x00000000,0x0000046e, + 0x0004003b,0x0000046f,0x00000470,0x00000000,0x00040017,0x00000473,0x00000018,0x00000004, + 0x0004002b,0x00000018,0x00000478,0x00000011,0x0004002b,0x00000018,0x00000481,0x0001ffff, + 0x0005001e,0x00000497,0x00000006,0x00000018,0x00000018,0x00040020,0x00000498,0x00000002, + 0x00000497,0x0004003b,0x00000498,0x00000499,0x00000002,0x00040020,0x0000049b,0x00000002, + 0x00000018,0x00040020,0x000004e1,0x00000002,0x00000006,0x0004001e,0x000004f0,0x00000006, + 0x00000006,0x00040020,0x000004f1,0x00000002,0x000004f0,0x0004003b,0x000004f1,0x000004f2, + 0x00000002,0x0004002b,0x00000018,0x00000514,0x00010000,0x0007002c,0x00000473,0x00000515, + 0x00000514,0x00000514,0x00000514,0x00000514,0x0006002c,0x0000002a,0x0000051e,0x000000eb, + 0x000000eb,0x000000eb,0x0006002c,0x0000002a,0x0000051f,0x000001ea,0x000001ea,0x000001ea, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b, + 0x00000007,0x0000110b,0x00000007,0x0004003b,0x00000007,0x0000110c,0x00000007,0x0004003b, + 0x00000007,0x0000110d,0x00000007,0x0004003b,0x00000046,0x000010f9,0x00000007,0x0004003b, + 0x00000013,0x000010fa,0x00000007,0x0004003b,0x00000007,0x000010fb,0x00000007,0x0004003b, + 0x00000007,0x000010fc,0x00000007,0x0004003b,0x00000046,0x000010fd,0x00000007,0x0004003b, + 0x00000007,0x000010f4,0x00000007,0x0004003b,0x00000007,0x000010f5,0x00000007,0x0004003b, + 0x00000046,0x000010ea,0x00000007,0x0004003b,0x00000046,0x000010eb,0x00000007,0x0004003b, + 0x00000007,0x000010e7,0x00000007,0x0004003b,0x00000013,0x000010df,0x00000007,0x0004003b, + 0x00000013,0x000010e0,0x00000007,0x0004003b,0x00000007,0x000010d8,0x00000007,0x0004003b, + 0x00000013,0x000010cf,0x00000007,0x0004003b,0x00000007,0x000010d0,0x00000007,0x0004003b, + 0x00000007,0x000010c8,0x00000007,0x0004003b,0x00000013,0x000010bf,0x00000007,0x0004003b, + 0x00000007,0x000010c0,0x00000007,0x0004003b,0x00000013,0x000010b7,0x00000007,0x0004003b, + 0x00000013,0x000010b8,0x00000007,0x0004003b,0x00000013,0x000010af,0x00000007,0x0004003b, + 0x00000013,0x000010b0,0x00000007,0x0004003b,0x00000046,0x000010a5,0x00000007,0x0004003b, + 0x00000046,0x000010a6,0x00000007,0x0004003b,0x00000007,0x0000109d,0x00000007,0x0004003b, + 0x00000007,0x0000109e,0x00000007,0x0004003b,0x00000007,0x0000109f,0x00000007,0x0004003b, + 0x00000007,0x000010a0,0x00000007,0x0004003b,0x00000046,0x00001093,0x00000007,0x0004003b, + 0x00000046,0x00001094,0x00000007,0x0004003b,0x00000007,0x0000108b,0x00000007,0x0004003b, + 0x00000007,0x0000108c,0x00000007,0x0004003b,0x00000007,0x0000108d,0x00000007,0x0004003b, + 0x00000007,0x0000108e,0x00000007,0x0004003b,0x00000007,0x0000105a,0x00000007,0x0004003b, + 0x00000046,0x0000105b,0x00000007,0x0004003b,0x00000046,0x0000105c,0x00000007,0x0004003b, + 0x00000046,0x0000105d,0x00000007,0x0004003b,0x00000013,0x0000105e,0x00000007,0x0004003b, + 0x00000007,0x0000105f,0x00000007,0x0004003b,0x00000007,0x00001060,0x00000007,0x0004003b, + 0x00000007,0x00001061,0x00000007,0x0004003b,0x00000046,0x00001062,0x00000007,0x0004003b, + 0x00000046,0x00001063,0x00000007,0x0004003b,0x00000007,0x00001064,0x00000007,0x0004003b, + 0x00000007,0x00001065,0x00000007,0x0004003b,0x00000007,0x00001066,0x00000007,0x0004003b, + 0x00000007,0x00001067,0x00000007,0x0004003b,0x00000046,0x00001068,0x00000007,0x0004003b, + 0x00000046,0x00001050,0x00000007,0x0004003b,0x00000046,0x00001051,0x00000007,0x0004003b, + 0x00000046,0x00001046,0x00000007,0x0004003b,0x00000046,0x00001047,0x00000007,0x0004003b, + 0x00000007,0x00001043,0x00000007,0x0004003b,0x00000013,0x0000103b,0x00000007,0x0004003b, + 0x00000013,0x0000103c,0x00000007,0x0004003b,0x00000007,0x00001034,0x00000007,0x0004003b, + 0x00000013,0x0000102b,0x00000007,0x0004003b,0x00000007,0x0000102c,0x00000007,0x0004003b, + 0x00000007,0x00001024,0x00000007,0x0004003b,0x00000013,0x0000101b,0x00000007,0x0004003b, + 0x00000007,0x0000101c,0x00000007,0x0004003b,0x00000013,0x00001013,0x00000007,0x0004003b, + 0x00000013,0x00001014,0x00000007,0x0004003b,0x00000013,0x0000100b,0x00000007,0x0004003b, + 0x00000013,0x0000100c,0x00000007,0x0004003b,0x00000046,0x00001001,0x00000007,0x0004003b, + 0x00000046,0x00001002,0x00000007,0x0004003b,0x00000007,0x00000ff9,0x00000007,0x0004003b, + 0x00000007,0x00000ffa,0x00000007,0x0004003b,0x00000007,0x00000ffb,0x00000007,0x0004003b, + 0x00000007,0x00000ffc,0x00000007,0x0004003b,0x00000046,0x00000fef,0x00000007,0x0004003b, + 0x00000046,0x00000ff0,0x00000007,0x0004003b,0x00000007,0x00000fe7,0x00000007,0x0004003b, + 0x00000007,0x00000fe8,0x00000007,0x0004003b,0x00000007,0x00000fe9,0x00000007,0x0004003b, + 0x00000007,0x00000fea,0x00000007,0x0004003b,0x00000007,0x00000fb6,0x00000007,0x0004003b, + 0x00000046,0x00000fb7,0x00000007,0x0004003b,0x00000046,0x00000fb8,0x00000007,0x0004003b, + 0x00000046,0x00000fb9,0x00000007,0x0004003b,0x00000013,0x00000fba,0x00000007,0x0004003b, + 0x00000007,0x00000fbb,0x00000007,0x0004003b,0x00000007,0x00000fbc,0x00000007,0x0004003b, + 0x00000007,0x00000fbd,0x00000007,0x0004003b,0x00000046,0x00000fbe,0x00000007,0x0004003b, + 0x00000046,0x00000fbf,0x00000007,0x0004003b,0x00000007,0x00000fc0,0x00000007,0x0004003b, + 0x00000007,0x00000fc1,0x00000007,0x0004003b,0x00000007,0x00000fc2,0x00000007,0x0004003b, + 0x00000007,0x00000fc3,0x00000007,0x0004003b,0x00000046,0x00000fc4,0x00000007,0x0004003b, + 0x00000046,0x00000fac,0x00000007,0x0004003b,0x00000046,0x00000fad,0x00000007,0x0004003b, + 0x00000046,0x00000fa2,0x00000007,0x0004003b,0x00000046,0x00000fa3,0x00000007,0x0004003b, + 0x00000007,0x00000f9f,0x00000007,0x0004003b,0x00000013,0x00000f97,0x00000007,0x0004003b, + 0x00000013,0x00000f98,0x00000007,0x0004003b,0x00000007,0x00000f90,0x00000007,0x0004003b, + 0x00000013,0x00000f87,0x00000007,0x0004003b,0x00000007,0x00000f88,0x00000007,0x0004003b, + 0x00000007,0x00000f80,0x00000007,0x0004003b,0x00000013,0x00000f77,0x00000007,0x0004003b, + 0x00000007,0x00000f78,0x00000007,0x0004003b,0x00000013,0x00000f6f,0x00000007,0x0004003b, + 0x00000013,0x00000f70,0x00000007,0x0004003b,0x00000013,0x00000f67,0x00000007,0x0004003b, + 0x00000013,0x00000f68,0x00000007,0x0004003b,0x00000046,0x00000f5d,0x00000007,0x0004003b, + 0x00000046,0x00000f5e,0x00000007,0x0004003b,0x00000007,0x00000f55,0x00000007,0x0004003b, + 0x00000007,0x00000f56,0x00000007,0x0004003b,0x00000007,0x00000f57,0x00000007,0x0004003b, + 0x00000007,0x00000f58,0x00000007,0x0004003b,0x00000046,0x00000f4b,0x00000007,0x0004003b, + 0x00000046,0x00000f4c,0x00000007,0x0004003b,0x00000007,0x00000f43,0x00000007,0x0004003b, + 0x00000007,0x00000f44,0x00000007,0x0004003b,0x00000007,0x00000f45,0x00000007,0x0004003b, + 0x00000007,0x00000f46,0x00000007,0x0004003b,0x00000007,0x00000f12,0x00000007,0x0004003b, + 0x00000046,0x00000f13,0x00000007,0x0004003b,0x00000046,0x00000f14,0x00000007,0x0004003b, + 0x00000046,0x00000f15,0x00000007,0x0004003b,0x00000013,0x00000f16,0x00000007,0x0004003b, + 0x00000007,0x00000f17,0x00000007,0x0004003b,0x00000007,0x00000f18,0x00000007,0x0004003b, + 0x00000007,0x00000f19,0x00000007,0x0004003b,0x00000046,0x00000f1a,0x00000007,0x0004003b, + 0x00000046,0x00000f1b,0x00000007,0x0004003b,0x00000007,0x00000f1c,0x00000007,0x0004003b, + 0x00000007,0x00000f1d,0x00000007,0x0004003b,0x00000007,0x00000f1e,0x00000007,0x0004003b, + 0x00000007,0x00000f1f,0x00000007,0x0004003b,0x00000046,0x00000f20,0x00000007,0x0004003b, + 0x00000007,0x00000f0b,0x00000007,0x0004003b,0x00000013,0x00000f02,0x00000007,0x0004003b, + 0x00000007,0x00000f03,0x00000007,0x0004003b,0x00000007,0x00000efb,0x00000007,0x0004003b, + 0x00000013,0x00000ef2,0x00000007,0x0004003b,0x00000007,0x00000ef3,0x00000007,0x0004003b, + 0x00000007,0x00000eeb,0x00000007,0x0004003b,0x00000013,0x00000ee2,0x00000007,0x0004003b, + 0x00000007,0x00000ee3,0x00000007,0x0004003b,0x00000007,0x00000edb,0x00000007,0x0004003b, + 0x00000013,0x00000ed2,0x00000007,0x0004003b,0x00000007,0x00000ed3,0x00000007,0x0004003b, + 0x00000007,0x00000eb2,0x00000007,0x0004003b,0x00000046,0x00000eb3,0x00000007,0x0004003b, + 0x00000046,0x00000eb4,0x00000007,0x0004003b,0x00000046,0x00000eb5,0x00000007,0x0004003b, + 0x00000007,0x00000eb6,0x00000007,0x0004003b,0x00000046,0x00000eb7,0x00000007,0x0004003b, + 0x00000007,0x00000eb8,0x00000007,0x0004003b,0x00000046,0x00000eb9,0x00000007,0x0004003b, + 0x00000046,0x00000eba,0x00000007,0x0004003b,0x00000046,0x00000ebb,0x00000007,0x0004003b, + 0x00000046,0x00000ea8,0x00000007,0x0004003b,0x00000046,0x00000ea9,0x00000007,0x0004003b, + 0x00000046,0x00000e9e,0x00000007,0x0004003b,0x00000046,0x00000e9f,0x00000007,0x0004003b, + 0x00000007,0x00000e9b,0x00000007,0x0004003b,0x00000013,0x00000e93,0x00000007,0x0004003b, + 0x00000013,0x00000e94,0x00000007,0x0004003b,0x00000007,0x00000e8c,0x00000007,0x0004003b, + 0x00000013,0x00000e83,0x00000007,0x0004003b,0x00000007,0x00000e84,0x00000007,0x0004003b, + 0x00000007,0x00000e7c,0x00000007,0x0004003b,0x00000013,0x00000e73,0x00000007,0x0004003b, + 0x00000007,0x00000e74,0x00000007,0x0004003b,0x00000013,0x00000e6b,0x00000007,0x0004003b, + 0x00000013,0x00000e6c,0x00000007,0x0004003b,0x00000013,0x00000e63,0x00000007,0x0004003b, + 0x00000013,0x00000e64,0x00000007,0x0004003b,0x00000046,0x00000e59,0x00000007,0x0004003b, + 0x00000046,0x00000e5a,0x00000007,0x0004003b,0x00000007,0x00000e51,0x00000007,0x0004003b, + 0x00000007,0x00000e52,0x00000007,0x0004003b,0x00000007,0x00000e53,0x00000007,0x0004003b, + 0x00000007,0x00000e54,0x00000007,0x0004003b,0x00000046,0x00000e47,0x00000007,0x0004003b, + 0x00000046,0x00000e48,0x00000007,0x0004003b,0x00000007,0x00000e3f,0x00000007,0x0004003b, + 0x00000007,0x00000e40,0x00000007,0x0004003b,0x00000007,0x00000e41,0x00000007,0x0004003b, + 0x00000007,0x00000e42,0x00000007,0x0004003b,0x00000007,0x00000e0e,0x00000007,0x0004003b, + 0x00000046,0x00000e0f,0x00000007,0x0004003b,0x00000046,0x00000e10,0x00000007,0x0004003b, + 0x00000046,0x00000e11,0x00000007,0x0004003b,0x00000013,0x00000e12,0x00000007,0x0004003b, + 0x00000007,0x00000e13,0x00000007,0x0004003b,0x00000007,0x00000e14,0x00000007,0x0004003b, + 0x00000007,0x00000e15,0x00000007,0x0004003b,0x00000046,0x00000e16,0x00000007,0x0004003b, + 0x00000046,0x00000e17,0x00000007,0x0004003b,0x00000007,0x00000e18,0x00000007,0x0004003b, + 0x00000007,0x00000e19,0x00000007,0x0004003b,0x00000007,0x00000e1a,0x00000007,0x0004003b, + 0x00000007,0x00000e1b,0x00000007,0x0004003b,0x00000046,0x00000e1c,0x00000007,0x0004003b, + 0x00000007,0x00000e07,0x00000007,0x0004003b,0x00000013,0x00000dfe,0x00000007,0x0004003b, + 0x00000007,0x00000dff,0x00000007,0x0004003b,0x00000007,0x00000df7,0x00000007,0x0004003b, + 0x00000013,0x00000dee,0x00000007,0x0004003b,0x00000007,0x00000def,0x00000007,0x0004003b, + 0x00000007,0x00000de7,0x00000007,0x0004003b,0x00000013,0x00000dde,0x00000007,0x0004003b, + 0x00000007,0x00000ddf,0x00000007,0x0004003b,0x00000007,0x00000dd7,0x00000007,0x0004003b, + 0x00000013,0x00000dce,0x00000007,0x0004003b,0x00000007,0x00000dcf,0x00000007,0x0004003b, + 0x00000007,0x00000dae,0x00000007,0x0004003b,0x00000046,0x00000daf,0x00000007,0x0004003b, + 0x00000046,0x00000db0,0x00000007,0x0004003b,0x00000046,0x00000db1,0x00000007,0x0004003b, + 0x00000007,0x00000db2,0x00000007,0x0004003b,0x00000046,0x00000db3,0x00000007,0x0004003b, + 0x00000007,0x00000db4,0x00000007,0x0004003b,0x00000046,0x00000db5,0x00000007,0x0004003b, + 0x00000046,0x00000db6,0x00000007,0x0004003b,0x00000046,0x00000db7,0x00000007,0x0004003b, + 0x00000046,0x00000da4,0x00000007,0x0004003b,0x00000046,0x00000da5,0x00000007,0x0004003b, + 0x00000046,0x00000d9a,0x00000007,0x0004003b,0x00000046,0x00000d9b,0x00000007,0x0004003b, + 0x00000046,0x00000d90,0x00000007,0x0004003b,0x00000046,0x00000d91,0x00000007,0x0004003b, + 0x00000046,0x00000d86,0x00000007,0x0004003b,0x00000046,0x00000d87,0x00000007,0x0004003b, + 0x00000046,0x00000d7c,0x00000007,0x0004003b,0x00000046,0x00000d7d,0x00000007,0x0004003b, + 0x00000046,0x00000d72,0x00000007,0x0004003b,0x00000046,0x00000d73,0x00000007,0x0004003b, + 0x00000046,0x00000d68,0x00000007,0x0004003b,0x00000046,0x00000d69,0x00000007,0x0004003b, + 0x00000046,0x00000d5e,0x00000007,0x0004003b,0x00000046,0x00000d5f,0x00000007,0x0004003b, + 0x00000046,0x00000d54,0x00000007,0x0004003b,0x00000046,0x00000d55,0x00000007,0x0004003b, + 0x00000046,0x00000d4a,0x00000007,0x0004003b,0x00000046,0x00000d4b,0x00000007,0x0004003b, + 0x00000046,0x00000d40,0x00000007,0x0004003b,0x00000046,0x00000d41,0x00000007,0x0004003b, + 0x00000046,0x00000d36,0x00000007,0x0004003b,0x00000046,0x00000d37,0x00000007,0x0004003b, + 0x00000046,0x00000d2c,0x00000007,0x0004003b,0x00000046,0x00000d2d,0x00000007,0x0004003b, + 0x00000046,0x00000d22,0x00000007,0x0004003b,0x00000046,0x00000d23,0x00000007,0x0004003b, + 0x00000007,0x00000d12,0x00000007,0x0004003b,0x00000046,0x00000d13,0x00000007,0x0004003b, + 0x00000046,0x00000bf1,0x00000007,0x0004003b,0x0000000d,0x00000bf2,0x00000007,0x0004003b, + 0x00000046,0x00000bf3,0x00000007,0x0004003b,0x00000046,0x00000bf4,0x00000007,0x0004003b, + 0x00000007,0x00000bf5,0x00000007,0x0004003b,0x00000007,0x00000bf6,0x00000007,0x0004003b, + 0x00000046,0x00000bf7,0x00000007,0x0004003b,0x00000007,0x00000bf8,0x00000007,0x0004003b, + 0x00000007,0x00000bf9,0x00000007,0x0004003b,0x00000007,0x00000bfa,0x00000007,0x0004003b, + 0x00000007,0x00000bfb,0x00000007,0x0004003b,0x00000007,0x00000bfc,0x00000007,0x0004003b, + 0x00000007,0x00000bfd,0x00000007,0x0004003b,0x00000007,0x00000bfe,0x00000007,0x0004003b, + 0x00000046,0x00000bff,0x00000007,0x0004003b,0x00000007,0x00000c00,0x00000007,0x0004003b, + 0x00000007,0x00000c01,0x00000007,0x0004003b,0x00000046,0x00000c02,0x00000007,0x0004003b, + 0x00000007,0x00000c03,0x00000007,0x0004003b,0x0000026c,0x00000c04,0x00000007,0x0004003b, + 0x00000007,0x00000c05,0x00000007,0x0004003b,0x00000007,0x00000c06,0x00000007,0x0004003b, + 0x00000046,0x00000c07,0x00000007,0x0004003b,0x00000046,0x00000c08,0x00000007,0x0004003b, + 0x00000046,0x00000c09,0x00000007,0x0004003b,0x00000007,0x00000c0a,0x00000007,0x0004003b, + 0x00000007,0x00000c0b,0x00000007,0x0004003b,0x00000046,0x00000c0c,0x00000007,0x0004003b, + 0x00000046,0x00000c0d,0x00000007,0x0004003b,0x00000046,0x00000c0e,0x00000007,0x0004003b, + 0x00000007,0x00000c0f,0x00000007,0x0004003b,0x00000007,0x00000c10,0x00000007,0x0004003b, + 0x00000046,0x00000c11,0x00000007,0x0004003b,0x00000046,0x00000c12,0x00000007,0x0004003b, + 0x00000007,0x00000c13,0x00000007,0x0004003b,0x00000007,0x00000c14,0x00000007,0x0004003b, + 0x00000046,0x00000c15,0x00000007,0x0004003b,0x00000046,0x00000c16,0x00000007,0x0004003b, + 0x00000046,0x00000c17,0x00000007,0x0004003b,0x00000046,0x00000be0,0x00000007,0x0004003b, + 0x00000046,0x00000be1,0x00000007,0x0004003b,0x0000000d,0x00000be2,0x00000007,0x0004003b, + 0x00000019,0x00000be3,0x00000007,0x0004003b,0x00000007,0x00000be4,0x00000007,0x0004003b, + 0x00000046,0x00000be5,0x00000007,0x0004003b,0x00000019,0x00000bdb,0x00000007,0x0004003b, + 0x00000019,0x00000bdc,0x00000007,0x0004003b,0x00000007,0x00000bcb,0x00000007,0x0004003b, + 0x00000046,0x00000bcc,0x00000007,0x0004003b,0x00000013,0x00000bc3,0x00000007,0x0004003b, + 0x00000013,0x00000bc4,0x00000007,0x0004003b,0x00000007,0x00000bb0,0x00000007,0x0004003b, + 0x00000046,0x00000ba6,0x00000007,0x0004003b,0x00000046,0x00000ba7,0x00000007,0x0004003b, + 0x00000007,0x00000ba3,0x00000007,0x0004003b,0x00000013,0x00000b9b,0x00000007,0x0004003b, + 0x00000013,0x00000b9c,0x00000007,0x0004003b,0x00000007,0x00000b94,0x00000007,0x0004003b, + 0x00000013,0x00000b8b,0x00000007,0x0004003b,0x00000007,0x00000b8c,0x00000007,0x0004003b, + 0x00000007,0x00000b84,0x00000007,0x0004003b,0x00000013,0x00000b7b,0x00000007,0x0004003b, + 0x00000007,0x00000b7c,0x00000007,0x0004003b,0x00000013,0x00000b73,0x00000007,0x0004003b, + 0x00000013,0x00000b74,0x00000007,0x0004003b,0x00000013,0x00000b6b,0x00000007,0x0004003b, + 0x00000013,0x00000b6c,0x00000007,0x0004003b,0x00000046,0x00000b61,0x00000007,0x0004003b, + 0x00000046,0x00000b62,0x00000007,0x0004003b,0x00000007,0x00000b59,0x00000007,0x0004003b, + 0x00000007,0x00000b5a,0x00000007,0x0004003b,0x00000007,0x00000b5b,0x00000007,0x0004003b, + 0x00000007,0x00000b5c,0x00000007,0x0004003b,0x00000046,0x00000b4f,0x00000007,0x0004003b, + 0x00000046,0x00000b50,0x00000007,0x0004003b,0x00000007,0x00000b47,0x00000007,0x0004003b, + 0x00000007,0x00000b48,0x00000007,0x0004003b,0x00000007,0x00000b49,0x00000007,0x0004003b, + 0x00000007,0x00000b4a,0x00000007,0x0004003b,0x00000007,0x00000b16,0x00000007,0x0004003b, + 0x00000046,0x00000b17,0x00000007,0x0004003b,0x00000046,0x00000b18,0x00000007,0x0004003b, + 0x00000046,0x00000b19,0x00000007,0x0004003b,0x00000013,0x00000b1a,0x00000007,0x0004003b, + 0x00000007,0x00000b1b,0x00000007,0x0004003b,0x00000007,0x00000b1c,0x00000007,0x0004003b, + 0x00000007,0x00000b1d,0x00000007,0x0004003b,0x00000046,0x00000b1e,0x00000007,0x0004003b, + 0x00000046,0x00000b1f,0x00000007,0x0004003b,0x00000007,0x00000b20,0x00000007,0x0004003b, + 0x00000007,0x00000b21,0x00000007,0x0004003b,0x00000007,0x00000b22,0x00000007,0x0004003b, + 0x00000007,0x00000b23,0x00000007,0x0004003b,0x00000046,0x00000b24,0x00000007,0x0004003b, + 0x00000046,0x00000b0c,0x00000007,0x0004003b,0x00000046,0x00000b0d,0x00000007,0x0004003b, + 0x00000046,0x00000b02,0x00000007,0x0004003b,0x00000046,0x00000b03,0x00000007,0x0004003b, + 0x00000007,0x00000aff,0x00000007,0x0004003b,0x00000013,0x00000af7,0x00000007,0x0004003b, + 0x00000013,0x00000af8,0x00000007,0x0004003b,0x00000007,0x00000af0,0x00000007,0x0004003b, + 0x00000013,0x00000ae7,0x00000007,0x0004003b,0x00000007,0x00000ae8,0x00000007,0x0004003b, + 0x00000007,0x00000ae0,0x00000007,0x0004003b,0x00000013,0x00000ad7,0x00000007,0x0004003b, + 0x00000007,0x00000ad8,0x00000007,0x0004003b,0x00000013,0x00000acf,0x00000007,0x0004003b, + 0x00000013,0x00000ad0,0x00000007,0x0004003b,0x00000013,0x00000ac7,0x00000007,0x0004003b, + 0x00000013,0x00000ac8,0x00000007,0x0004003b,0x00000046,0x00000abd,0x00000007,0x0004003b, + 0x00000046,0x00000abe,0x00000007,0x0004003b,0x00000007,0x00000ab5,0x00000007,0x0004003b, + 0x00000007,0x00000ab6,0x00000007,0x0004003b,0x00000007,0x00000ab7,0x00000007,0x0004003b, + 0x00000007,0x00000ab8,0x00000007,0x0004003b,0x00000046,0x00000aab,0x00000007,0x0004003b, + 0x00000046,0x00000aac,0x00000007,0x0004003b,0x00000007,0x00000aa3,0x00000007,0x0004003b, + 0x00000007,0x00000aa4,0x00000007,0x0004003b,0x00000007,0x00000aa5,0x00000007,0x0004003b, + 0x00000007,0x00000aa6,0x00000007,0x0004003b,0x00000007,0x00000a72,0x00000007,0x0004003b, + 0x00000046,0x00000a73,0x00000007,0x0004003b,0x00000046,0x00000a74,0x00000007,0x0004003b, + 0x00000046,0x00000a75,0x00000007,0x0004003b,0x00000013,0x00000a76,0x00000007,0x0004003b, + 0x00000007,0x00000a77,0x00000007,0x0004003b,0x00000007,0x00000a78,0x00000007,0x0004003b, + 0x00000007,0x00000a79,0x00000007,0x0004003b,0x00000046,0x00000a7a,0x00000007,0x0004003b, + 0x00000046,0x00000a7b,0x00000007,0x0004003b,0x00000007,0x00000a7c,0x00000007,0x0004003b, + 0x00000007,0x00000a7d,0x00000007,0x0004003b,0x00000007,0x00000a7e,0x00000007,0x0004003b, + 0x00000007,0x00000a7f,0x00000007,0x0004003b,0x00000046,0x00000a80,0x00000007,0x0004003b, + 0x00000046,0x00000a68,0x00000007,0x0004003b,0x00000046,0x00000a69,0x00000007,0x0004003b, + 0x00000046,0x00000a5e,0x00000007,0x0004003b,0x00000046,0x00000a5f,0x00000007,0x0004003b, + 0x00000007,0x00000a5b,0x00000007,0x0004003b,0x00000013,0x00000a53,0x00000007,0x0004003b, + 0x00000013,0x00000a54,0x00000007,0x0004003b,0x00000007,0x00000a4c,0x00000007,0x0004003b, + 0x00000013,0x00000a43,0x00000007,0x0004003b,0x00000007,0x00000a44,0x00000007,0x0004003b, + 0x00000007,0x00000a3c,0x00000007,0x0004003b,0x00000013,0x00000a33,0x00000007,0x0004003b, + 0x00000007,0x00000a34,0x00000007,0x0004003b,0x00000013,0x00000a2b,0x00000007,0x0004003b, + 0x00000013,0x00000a2c,0x00000007,0x0004003b,0x00000013,0x00000a23,0x00000007,0x0004003b, + 0x00000013,0x00000a24,0x00000007,0x0004003b,0x00000046,0x00000a19,0x00000007,0x0004003b, + 0x00000046,0x00000a1a,0x00000007,0x0004003b,0x00000007,0x00000a11,0x00000007,0x0004003b, + 0x00000007,0x00000a12,0x00000007,0x0004003b,0x00000007,0x00000a13,0x00000007,0x0004003b, + 0x00000007,0x00000a14,0x00000007,0x0004003b,0x00000046,0x00000a07,0x00000007,0x0004003b, + 0x00000046,0x00000a08,0x00000007,0x0004003b,0x00000007,0x000009ff,0x00000007,0x0004003b, + 0x00000007,0x00000a00,0x00000007,0x0004003b,0x00000007,0x00000a01,0x00000007,0x0004003b, + 0x00000007,0x00000a02,0x00000007,0x0004003b,0x00000007,0x000009ce,0x00000007,0x0004003b, + 0x00000046,0x000009cf,0x00000007,0x0004003b,0x00000046,0x000009d0,0x00000007,0x0004003b, + 0x00000046,0x000009d1,0x00000007,0x0004003b,0x00000013,0x000009d2,0x00000007,0x0004003b, + 0x00000007,0x000009d3,0x00000007,0x0004003b,0x00000007,0x000009d4,0x00000007,0x0004003b, + 0x00000007,0x000009d5,0x00000007,0x0004003b,0x00000046,0x000009d6,0x00000007,0x0004003b, + 0x00000046,0x000009d7,0x00000007,0x0004003b,0x00000007,0x000009d8,0x00000007,0x0004003b, + 0x00000007,0x000009d9,0x00000007,0x0004003b,0x00000007,0x000009da,0x00000007,0x0004003b, + 0x00000007,0x000009db,0x00000007,0x0004003b,0x00000046,0x000009dc,0x00000007,0x0004003b, + 0x00000007,0x000009c7,0x00000007,0x0004003b,0x00000013,0x000009be,0x00000007,0x0004003b, + 0x00000007,0x000009bf,0x00000007,0x0004003b,0x00000007,0x000009b7,0x00000007,0x0004003b, + 0x00000013,0x000009ae,0x00000007,0x0004003b,0x00000007,0x000009af,0x00000007,0x0004003b, + 0x00000007,0x000009a7,0x00000007,0x0004003b,0x00000013,0x0000099e,0x00000007,0x0004003b, + 0x00000007,0x0000099f,0x00000007,0x0004003b,0x00000007,0x00000997,0x00000007,0x0004003b, + 0x00000013,0x0000098e,0x00000007,0x0004003b,0x00000007,0x0000098f,0x00000007,0x0004003b, + 0x00000007,0x0000096e,0x00000007,0x0004003b,0x00000046,0x0000096f,0x00000007,0x0004003b, + 0x00000046,0x00000970,0x00000007,0x0004003b,0x00000046,0x00000971,0x00000007,0x0004003b, + 0x00000007,0x00000972,0x00000007,0x0004003b,0x00000046,0x00000973,0x00000007,0x0004003b, + 0x00000007,0x00000974,0x00000007,0x0004003b,0x00000046,0x00000975,0x00000007,0x0004003b, + 0x00000046,0x00000976,0x00000007,0x0004003b,0x00000046,0x00000977,0x00000007,0x0004003b, + 0x00000046,0x00000964,0x00000007,0x0004003b,0x00000046,0x00000965,0x00000007,0x0004003b, + 0x00000046,0x0000095a,0x00000007,0x0004003b,0x00000046,0x0000095b,0x00000007,0x0004003b, + 0x00000007,0x00000957,0x00000007,0x0004003b,0x00000013,0x0000094f,0x00000007,0x0004003b, + 0x00000013,0x00000950,0x00000007,0x0004003b,0x00000007,0x00000948,0x00000007,0x0004003b, + 0x00000013,0x0000093f,0x00000007,0x0004003b,0x00000007,0x00000940,0x00000007,0x0004003b, + 0x00000007,0x00000938,0x00000007,0x0004003b,0x00000013,0x0000092f,0x00000007,0x0004003b, + 0x00000007,0x00000930,0x00000007,0x0004003b,0x00000013,0x00000927,0x00000007,0x0004003b, + 0x00000013,0x00000928,0x00000007,0x0004003b,0x00000013,0x0000091f,0x00000007,0x0004003b, + 0x00000013,0x00000920,0x00000007,0x0004003b,0x00000046,0x00000915,0x00000007,0x0004003b, + 0x00000046,0x00000916,0x00000007,0x0004003b,0x00000007,0x0000090d,0x00000007,0x0004003b, + 0x00000007,0x0000090e,0x00000007,0x0004003b,0x00000007,0x0000090f,0x00000007,0x0004003b, + 0x00000007,0x00000910,0x00000007,0x0004003b,0x00000046,0x00000903,0x00000007,0x0004003b, + 0x00000046,0x00000904,0x00000007,0x0004003b,0x00000007,0x000008fb,0x00000007,0x0004003b, + 0x00000007,0x000008fc,0x00000007,0x0004003b,0x00000007,0x000008fd,0x00000007,0x0004003b, + 0x00000007,0x000008fe,0x00000007,0x0004003b,0x00000007,0x000008ca,0x00000007,0x0004003b, + 0x00000046,0x000008cb,0x00000007,0x0004003b,0x00000046,0x000008cc,0x00000007,0x0004003b, + 0x00000046,0x000008cd,0x00000007,0x0004003b,0x00000013,0x000008ce,0x00000007,0x0004003b, + 0x00000007,0x000008cf,0x00000007,0x0004003b,0x00000007,0x000008d0,0x00000007,0x0004003b, + 0x00000007,0x000008d1,0x00000007,0x0004003b,0x00000046,0x000008d2,0x00000007,0x0004003b, + 0x00000046,0x000008d3,0x00000007,0x0004003b,0x00000007,0x000008d4,0x00000007,0x0004003b, + 0x00000007,0x000008d5,0x00000007,0x0004003b,0x00000007,0x000008d6,0x00000007,0x0004003b, + 0x00000007,0x000008d7,0x00000007,0x0004003b,0x00000046,0x000008d8,0x00000007,0x0004003b, + 0x00000007,0x000008c3,0x00000007,0x0004003b,0x00000013,0x000008ba,0x00000007,0x0004003b, + 0x00000007,0x000008bb,0x00000007,0x0004003b,0x00000007,0x000008b3,0x00000007,0x0004003b, + 0x00000013,0x000008aa,0x00000007,0x0004003b,0x00000007,0x000008ab,0x00000007,0x0004003b, + 0x00000007,0x000008a3,0x00000007,0x0004003b,0x00000013,0x0000089a,0x00000007,0x0004003b, + 0x00000007,0x0000089b,0x00000007,0x0004003b,0x00000007,0x00000893,0x00000007,0x0004003b, + 0x00000013,0x0000088a,0x00000007,0x0004003b,0x00000007,0x0000088b,0x00000007,0x0004003b, + 0x00000007,0x0000086a,0x00000007,0x0004003b,0x00000046,0x0000086b,0x00000007,0x0004003b, + 0x00000046,0x0000086c,0x00000007,0x0004003b,0x00000046,0x0000086d,0x00000007,0x0004003b, + 0x00000007,0x0000086e,0x00000007,0x0004003b,0x00000046,0x0000086f,0x00000007,0x0004003b, + 0x00000007,0x00000870,0x00000007,0x0004003b,0x00000046,0x00000871,0x00000007,0x0004003b, + 0x00000046,0x00000872,0x00000007,0x0004003b,0x00000046,0x00000873,0x00000007,0x0004003b, + 0x00000046,0x00000860,0x00000007,0x0004003b,0x00000046,0x00000861,0x00000007,0x0004003b, + 0x00000046,0x00000856,0x00000007,0x0004003b,0x00000046,0x00000857,0x00000007,0x0004003b, + 0x00000046,0x0000084c,0x00000007,0x0004003b,0x00000046,0x0000084d,0x00000007,0x0004003b, + 0x00000046,0x00000842,0x00000007,0x0004003b,0x00000046,0x00000843,0x00000007,0x0004003b, + 0x00000046,0x00000838,0x00000007,0x0004003b,0x00000046,0x00000839,0x00000007,0x0004003b, + 0x00000046,0x0000082e,0x00000007,0x0004003b,0x00000046,0x0000082f,0x00000007,0x0004003b, + 0x00000046,0x00000824,0x00000007,0x0004003b,0x00000046,0x00000825,0x00000007,0x0004003b, + 0x00000046,0x0000081a,0x00000007,0x0004003b,0x00000046,0x0000081b,0x00000007,0x0004003b, + 0x00000046,0x00000810,0x00000007,0x0004003b,0x00000046,0x00000811,0x00000007,0x0004003b, + 0x00000046,0x00000806,0x00000007,0x0004003b,0x00000046,0x00000807,0x00000007,0x0004003b, + 0x00000046,0x000007fc,0x00000007,0x0004003b,0x00000046,0x000007fd,0x00000007,0x0004003b, + 0x00000046,0x000007f2,0x00000007,0x0004003b,0x00000046,0x000007f3,0x00000007,0x0004003b, + 0x00000046,0x000007e8,0x00000007,0x0004003b,0x00000046,0x000007e9,0x00000007,0x0004003b, + 0x00000046,0x000007de,0x00000007,0x0004003b,0x00000046,0x000007df,0x00000007,0x0004003b, + 0x00000007,0x000007ce,0x00000007,0x0004003b,0x00000046,0x000007cf,0x00000007,0x0004003b, + 0x00000046,0x000006ad,0x00000007,0x0004003b,0x0000000d,0x000006ae,0x00000007,0x0004003b, + 0x00000046,0x000006af,0x00000007,0x0004003b,0x00000046,0x000006b0,0x00000007,0x0004003b, + 0x00000007,0x000006b1,0x00000007,0x0004003b,0x00000007,0x000006b2,0x00000007,0x0004003b, + 0x00000046,0x000006b3,0x00000007,0x0004003b,0x00000007,0x000006b4,0x00000007,0x0004003b, + 0x00000007,0x000006b5,0x00000007,0x0004003b,0x00000007,0x000006b6,0x00000007,0x0004003b, + 0x00000007,0x000006b7,0x00000007,0x0004003b,0x00000007,0x000006b8,0x00000007,0x0004003b, + 0x00000007,0x000006b9,0x00000007,0x0004003b,0x00000007,0x000006ba,0x00000007,0x0004003b, + 0x00000046,0x000006bb,0x00000007,0x0004003b,0x00000007,0x000006bc,0x00000007,0x0004003b, + 0x00000007,0x000006bd,0x00000007,0x0004003b,0x00000046,0x000006be,0x00000007,0x0004003b, + 0x00000007,0x000006bf,0x00000007,0x0004003b,0x0000026c,0x000006c0,0x00000007,0x0004003b, + 0x00000007,0x000006c1,0x00000007,0x0004003b,0x00000007,0x000006c2,0x00000007,0x0004003b, + 0x00000046,0x000006c3,0x00000007,0x0004003b,0x00000046,0x000006c4,0x00000007,0x0004003b, + 0x00000046,0x000006c5,0x00000007,0x0004003b,0x00000007,0x000006c6,0x00000007,0x0004003b, + 0x00000007,0x000006c7,0x00000007,0x0004003b,0x00000046,0x000006c8,0x00000007,0x0004003b, + 0x00000046,0x000006c9,0x00000007,0x0004003b,0x00000046,0x000006ca,0x00000007,0x0004003b, + 0x00000007,0x000006cb,0x00000007,0x0004003b,0x00000007,0x000006cc,0x00000007,0x0004003b, + 0x00000046,0x000006cd,0x00000007,0x0004003b,0x00000046,0x000006ce,0x00000007,0x0004003b, + 0x00000007,0x000006cf,0x00000007,0x0004003b,0x00000007,0x000006d0,0x00000007,0x0004003b, + 0x00000046,0x000006d1,0x00000007,0x0004003b,0x00000046,0x000006d2,0x00000007,0x0004003b, + 0x00000046,0x000006d3,0x00000007,0x0004003b,0x00000046,0x0000069c,0x00000007,0x0004003b, + 0x00000046,0x0000069d,0x00000007,0x0004003b,0x0000000d,0x0000069e,0x00000007,0x0004003b, + 0x00000019,0x0000069f,0x00000007,0x0004003b,0x00000007,0x000006a0,0x00000007,0x0004003b, + 0x00000046,0x000006a1,0x00000007,0x0004003b,0x00000019,0x00000697,0x00000007,0x0004003b, + 0x00000019,0x00000698,0x00000007,0x0004003b,0x00000384,0x0000068a,0x00000007,0x0004003b, + 0x0000000d,0x0000067e,0x00000007,0x0004003b,0x0000000d,0x0000067f,0x00000007,0x0004003b, + 0x00000013,0x00000679,0x00000007,0x0004003b,0x00000013,0x0000067a,0x00000007,0x0004003b, + 0x00000384,0x0000066c,0x00000007,0x0004003b,0x00000013,0x00000664,0x00000007,0x0004003b, + 0x00000013,0x00000665,0x00000007,0x0004003b,0x00000007,0x00000651,0x00000007,0x0004003b, + 0x00000007,0x0000064e,0x00000007,0x0004003b,0x00000007,0x0000064b,0x00000007,0x0004003b, + 0x00000332,0x00000558,0x00000007,0x0004003b,0x00000007,0x00000559,0x00000007,0x0004003b, + 0x00000007,0x0000055a,0x00000007,0x0004003b,0x00000007,0x0000055b,0x00000007,0x0004003b, + 0x00000019,0x0000055c,0x00000007,0x0004003b,0x00000019,0x0000055d,0x00000007,0x0004003b, + 0x0000000d,0x0000055e,0x00000007,0x0004003b,0x00000007,0x0000055f,0x00000007,0x0004003b, + 0x00000384,0x00000560,0x00000007,0x0004003b,0x0000000d,0x00000561,0x00000007,0x0004003b, + 0x0000000d,0x00000562,0x00000007,0x0004003b,0x00000013,0x00000563,0x00000007,0x0004003b, + 0x00000013,0x00000564,0x00000007,0x0004003b,0x00000013,0x00000565,0x00000007,0x0004003b, + 0x00000007,0x00000566,0x00000007,0x0004003b,0x00000019,0x00000567,0x00000007,0x0004003b, + 0x00000007,0x00000568,0x00000007,0x0004003b,0x00000384,0x00000569,0x00000007,0x0004003b, + 0x0000000d,0x0000056a,0x00000007,0x0004003b,0x0000000d,0x0000056b,0x00000007,0x0004003b, + 0x00000013,0x0000056c,0x00000007,0x0004003b,0x00000007,0x0000056d,0x00000007,0x0004003b, + 0x00000007,0x0000056e,0x00000007,0x0004003b,0x00000007,0x0000056f,0x00000007,0x0004003b, + 0x00000007,0x00000570,0x00000007,0x0004003b,0x00000019,0x00000571,0x00000007,0x0004003b, + 0x00000019,0x00000572,0x00000007,0x0004003b,0x0000000d,0x00000573,0x00000007,0x0004003b, + 0x00000046,0x00000574,0x00000007,0x0004003b,0x0000000d,0x00000575,0x00000007,0x0004003b, + 0x00000019,0x00000576,0x00000007,0x0004003b,0x0000000d,0x0000054c,0x00000007,0x0004003b, + 0x0000000d,0x0000054d,0x00000007,0x0004003b,0x00000007,0x00000547,0x00000007,0x0004003b, + 0x00000007,0x00000548,0x00000007,0x0004003b,0x00000007,0x0000053f,0x00000007,0x0004003b, + 0x00000007,0x00000540,0x00000007,0x0004003b,0x00000019,0x0000053c,0x00000007,0x0004003b, + 0x00000019,0x00000537,0x00000007,0x0004003b,0x00000019,0x00000538,0x00000007,0x0004003b, + 0x00000007,0x00000534,0x00000007,0x0004003b,0x00000013,0x00000525,0x00000007,0x0004003b, + 0x00000007,0x00000526,0x00000007,0x0004003b,0x00000007,0x00000527,0x00000007,0x0004003b, + 0x0000000d,0x00000520,0x00000007,0x0004003b,0x0000000d,0x00000521,0x00000007,0x0004003b, + 0x0000008a,0x0000044f,0x00000007,0x0004003b,0x0000000d,0x00000454,0x00000007,0x0004003b, + 0x00000007,0x0000045e,0x00000007,0x0004003b,0x00000007,0x00000461,0x00000007,0x0004003b, + 0x0000000d,0x00000463,0x00000007,0x0004003b,0x0000000d,0x00000466,0x00000007,0x0004003b, + 0x00000007,0x00000469,0x00000007,0x0004003b,0x00000019,0x0000046d,0x00000007,0x0004003b, + 0x00000019,0x00000476,0x00000007,0x0004003b,0x00000019,0x0000047a,0x00000007,0x0004003b, + 0x00000019,0x0000047c,0x00000007,0x0004003b,0x00000007,0x0000047f,0x00000007,0x0004003b, + 0x00000019,0x00000483,0x00000007,0x0004003b,0x0000000d,0x00000485,0x00000007,0x0004003b, + 0x00000007,0x00000486,0x00000007,0x0004003b,0x0000000d,0x00000488,0x00000007,0x0004003b, + 0x00000019,0x00000489,0x00000007,0x0004003b,0x00000007,0x0000048b,0x00000007,0x0004003b, + 0x0000000d,0x0000048d,0x00000007,0x0004003b,0x0000000d,0x0000048e,0x00000007,0x0004003b, + 0x0000000d,0x000004a2,0x00000007,0x0004003b,0x0000000d,0x000004a6,0x00000007,0x0004003b, + 0x00000019,0x000004ae,0x00000007,0x0004003b,0x0000000d,0x000004b1,0x00000007,0x0004003b, + 0x00000007,0x000004b3,0x00000007,0x0004003b,0x0000000d,0x000004c0,0x00000007,0x0004003b, + 0x0000000d,0x000004c9,0x00000007,0x0004003b,0x00000019,0x000004cc,0x00000007,0x0004003b, + 0x00000046,0x000004d0,0x00000007,0x0004003b,0x0000000d,0x000004d1,0x00000007,0x0004003b, + 0x00000019,0x000004d3,0x00000007,0x0004003b,0x00000007,0x000004e0,0x00000007,0x0004003b, + 0x00000046,0x000004f5,0x00000007,0x0004003b,0x00000013,0x000004f8,0x00000007,0x0004003b, + 0x00000007,0x000004fb,0x00000007,0x0004003b,0x00000007,0x000004fe,0x00000007,0x0004003b, + 0x0000000d,0x00000508,0x00000007,0x0004003b,0x0000000d,0x0000050d,0x00000007,0x0004003d, + 0x0000000c,0x00000450,0x0000039c,0x0007004f,0x00000012,0x00000451,0x00000450,0x00000450, + 0x00000000,0x00000001,0x0006000c,0x00000012,0x00000452,0x00000001,0x00000008,0x00000451, + 0x0004006e,0x00000089,0x00000453,0x00000452,0x0003003e,0x0000044f,0x00000453,0x0004003d, + 0x00000405,0x00000456,0x00000455,0x0004003d,0x00000409,0x00000458,0x00000457,0x00050056, + 0x0000040d,0x00000459,0x00000456,0x00000458,0x0004003d,0x00000012,0x0000045c,0x0000045b, + 0x00050057,0x0000000c,0x0000045d,0x00000459,0x0000045c,0x0003003e,0x00000454,0x0000045d, + 0x0003003e,0x0000045e,0x000000eb,0x000300f7,0x00000460,0x00000000,0x000400fa,0x00000379, + 0x0000045f,0x00000460,0x000200f8,0x0000045f,0x0004003d,0x0000000c,0x00000464,0x00000462, + 0x0003003e,0x00000463,0x00000464,0x0004003d,0x0000000c,0x00000523,0x00000463,0x0003003e, + 0x00000520,0x00000523,0x0004003d,0x0000000c,0x00000524,0x00000520,0x0003003e,0x00000521, + 0x00000524,0x0004003d,0x0000000c,0x00000465,0x00000521,0x0003003e,0x00000466,0x00000465, + 0x0004003d,0x0000000c,0x00000529,0x00000466,0x0007004f,0x00000012,0x0000052a,0x00000529, + 0x00000529,0x00000000,0x00000001,0x0004003d,0x0000000c,0x0000052b,0x00000466,0x0007004f, + 0x00000012,0x0000052c,0x0000052b,0x0000052b,0x00000002,0x00000003,0x0007000c,0x00000012, + 0x0000052d,0x00000001,0x00000025,0x0000052a,0x0000052c,0x0003003e,0x00000525,0x0000052d, + 0x00050041,0x00000007,0x0000052e,0x00000525,0x000000b5,0x0004003d,0x00000006,0x0000052f, + 0x0000052e,0x00050041,0x00000007,0x00000530,0x00000525,0x000000b8,0x0004003d,0x00000006, + 0x00000531,0x00000530,0x0007000c,0x00000006,0x00000532,0x00000001,0x00000025,0x0000052f, + 0x00000531,0x0003003e,0x00000526,0x00000532,0x0004003d,0x00000006,0x00000533,0x00000526, + 0x0003003e,0x00000527,0x00000533,0x0004003d,0x00000006,0x00000467,0x00000527,0x0003003e, + 0x00000461,0x00000467,0x0004003d,0x00000006,0x00000468,0x00000461,0x0003003e,0x00000469, + 0x000000ec,0x0004003d,0x00000006,0x00000536,0x00000469,0x0003003e,0x00000534,0x00000536, + 0x0004003d,0x00000006,0x0000046a,0x00000534,0x0004003d,0x00000006,0x0000046b,0x0000045e, + 0x0008000c,0x00000006,0x0000046c,0x00000001,0x0000002b,0x00000468,0x0000046a,0x0000046b, + 0x0003003e,0x0000045e,0x0000046c,0x000200f9,0x00000460,0x000200f8,0x00000460,0x0004003d, + 0x0000046e,0x00000471,0x00000470,0x0004003d,0x00000089,0x00000472,0x0000044f,0x00050062, + 0x00000473,0x00000474,0x00000471,0x00000472,0x00050051,0x00000018,0x00000475,0x00000474, + 0x00000000,0x0003003e,0x0000046d,0x00000475,0x0004003d,0x00000018,0x00000477,0x0000046d, + 0x000500c2,0x00000018,0x00000479,0x00000477,0x00000478,0x0003003e,0x0000047a,0x00000479, + 0x0004003d,0x00000018,0x0000053a,0x0000047a,0x0003003e,0x00000537,0x0000053a,0x0004003d, + 0x00000018,0x0000053b,0x00000537,0x0003003e,0x00000538,0x0000053b,0x0004003d,0x00000018, + 0x0000047b,0x00000538,0x0003003e,0x00000476,0x0000047b,0x0004003d,0x00000018,0x0000047d, + 0x00000476,0x0003003e,0x0000047c,0x0000047d,0x0004003d,0x00000018,0x0000053e,0x0000047c, + 0x0003003e,0x0000053c,0x0000053e,0x0004003d,0x00000018,0x0000047e,0x0000053c,0x0003003e, + 0x00000476,0x0000047e,0x0004003d,0x00000018,0x00000480,0x0000046d,0x000500c7,0x00000018, + 0x00000482,0x00000480,0x00000481,0x0003003e,0x00000483,0x00000482,0x0004003d,0x00000018, + 0x00000542,0x00000483,0x00040070,0x00000006,0x00000543,0x00000542,0x00050085,0x00000006, + 0x00000544,0x00000543,0x00000312,0x00050081,0x00000006,0x00000545,0x00000544,0x00000314, + 0x0003003e,0x0000053f,0x00000545,0x0004003d,0x00000006,0x0000054a,0x0000053f,0x0003003e, + 0x00000547,0x0000054a,0x0004003d,0x00000006,0x0000054b,0x00000547,0x0003003e,0x00000548, + 0x0000054b,0x0004003d,0x00000006,0x00000546,0x00000548,0x0003003e,0x00000540,0x00000546, + 0x0004003d,0x00000006,0x00000484,0x00000540,0x0003003e,0x0000047f,0x00000484,0x0003003e, + 0x00000486,0x000000ec,0x0004003d,0x00000006,0x0000054f,0x00000486,0x00050041,0x00000007, + 0x00000550,0x0000054c,0x000000b5,0x0003003e,0x00000550,0x0000054f,0x0004003d,0x00000006, + 0x00000551,0x00000486,0x00050041,0x00000007,0x00000552,0x0000054c,0x000000b8,0x0003003e, + 0x00000552,0x00000551,0x0004003d,0x00000006,0x00000553,0x00000486,0x00050041,0x00000007, + 0x00000554,0x0000054c,0x000000cb,0x0003003e,0x00000554,0x00000553,0x0004003d,0x00000006, + 0x00000555,0x00000486,0x00050041,0x00000007,0x00000556,0x0000054c,0x000000e2,0x0003003e, + 0x00000556,0x00000555,0x0004003d,0x0000000c,0x00000557,0x0000054c,0x0003003e,0x0000054d, + 0x00000557,0x0004003d,0x0000000c,0x00000487,0x0000054d,0x0003003e,0x00000485,0x00000487, + 0x0004003d,0x00000018,0x0000048a,0x00000476,0x0003003e,0x00000489,0x0000048a,0x0004003d, + 0x00000006,0x0000048c,0x0000047f,0x0003003e,0x0000048b,0x0000048c,0x0004003d,0x0000000c, + 0x0000048f,0x00000485,0x0003003e,0x0000048e,0x0000048f,0x0004003d,0x00000018,0x00000578, + 0x00000489,0x00060041,0x00000339,0x00000579,0x00000337,0x0000026e,0x00000578,0x0004003d, + 0x00000331,0x0000057a,0x00000579,0x0003003e,0x00000558,0x0000057a,0x0004003d,0x00000006, + 0x0000057b,0x0000048b,0x0003003e,0x00000559,0x0000057b,0x00050041,0x00000019,0x0000057c, + 0x00000558,0x000000b5,0x0004003d,0x00000018,0x0000057d,0x0000057c,0x000500c7,0x00000018, + 0x0000057e,0x0000057d,0x00000340,0x000500ab,0x000000fa,0x0000057f,0x0000057e,0x000000b5, + 0x000300f7,0x00000593,0x00000000,0x000400fa,0x0000057f,0x00000580,0x00000593,0x000200f8, + 0x00000580,0x0004003d,0x00000006,0x00000581,0x00000559,0x0006000c,0x00000006,0x00000582, + 0x00000001,0x00000004,0x00000581,0x0003003e,0x00000559,0x00000582,0x000300f7,0x00000588, + 0x00000000,0x000400fa,0x00000347,0x00000583,0x00000588,0x000200f8,0x00000583,0x0004003d, + 0x00000018,0x00000585,0x0000057c,0x000500c7,0x00000018,0x00000586,0x00000585,0x0000034c, + 0x000500ab,0x000000fa,0x00000587,0x00000586,0x000000b5,0x000200f9,0x00000588,0x000200f8, + 0x00000588,0x000700f5,0x000000fa,0x00000589,0x00000347,0x00000580,0x00000587,0x00000583, + 0x000300f7,0x00000592,0x00000000,0x000400fa,0x00000589,0x0000058a,0x00000592,0x000200f8, + 0x0000058a,0x0004003d,0x00000006,0x0000058b,0x00000559,0x00050085,0x00000006,0x0000058c, + 0x0000058b,0x000001ea,0x0006000c,0x00000006,0x0000058d,0x00000001,0x0000000a,0x0000058c, + 0x00050085,0x00000006,0x0000058e,0x0000058d,0x000001e3,0x00050081,0x00000006,0x0000058f, + 0x0000058e,0x00000356,0x0006000c,0x00000006,0x00000590,0x00000001,0x00000004,0x0000058f, + 0x00050083,0x00000006,0x00000591,0x000000eb,0x00000590,0x0003003e,0x00000559,0x00000591, + 0x000200f9,0x00000592,0x000200f8,0x00000592,0x000200f9,0x00000593,0x000200f8,0x00000593, + 0x0004003d,0x00000006,0x00000594,0x00000559,0x0003003e,0x0000055a,0x000000ec,0x0004003d, + 0x00000006,0x0000064d,0x0000055a,0x0003003e,0x0000064b,0x0000064d,0x0004003d,0x00000006, + 0x00000595,0x0000064b,0x0003003e,0x0000055b,0x000000eb,0x0004003d,0x00000006,0x00000650, + 0x0000055b,0x0003003e,0x0000064e,0x00000650,0x0004003d,0x00000006,0x00000596,0x0000064e, + 0x0008000c,0x00000006,0x00000597,0x00000001,0x0000002b,0x00000594,0x00000595,0x00000596, + 0x0003003e,0x00000559,0x00000597,0x000300f7,0x000005a6,0x00000000,0x000400fa,0x00000360, + 0x00000598,0x000005a6,0x000200f8,0x00000598,0x0004003d,0x00000018,0x0000059a,0x0000057c, + 0x000500c2,0x00000018,0x0000059b,0x0000059a,0x00000366,0x0003003e,0x0000055c,0x0000059b, + 0x0004003d,0x00000018,0x0000059c,0x0000055c,0x000500ab,0x000000fa,0x0000059d,0x0000059c, + 0x000000b5,0x000300f7,0x000005a5,0x00000000,0x000400fa,0x0000059d,0x0000059e,0x000005a5, + 0x000200f8,0x0000059e,0x0004003d,0x0000036c,0x0000059f,0x0000036e,0x00050062,0x0000000c, + 0x000005a0,0x0000059f,0x00000370,0x0004003d,0x00000018,0x000005a1,0x0000055c,0x0003003e, + 0x0000055d,0x000005a1,0x0003003e,0x0000055e,0x000005a0,0x0004003d,0x00000006,0x000005a2, + 0x00000559,0x0003003e,0x0000055f,0x000005a2,0x0004003d,0x0000000c,0x00000653,0x0000055e, + 0x0007004f,0x00000012,0x00000654,0x00000653,0x00000653,0x00000000,0x00000001,0x0004003d, + 0x00000018,0x00000655,0x0000055d,0x0006000c,0x0000000c,0x00000656,0x00000001,0x00000040, + 0x00000655,0x0007004f,0x00000012,0x00000657,0x00000656,0x00000656,0x00000000,0x00000001, + 0x00050083,0x00000012,0x00000658,0x00000654,0x00000657,0x0006000c,0x00000012,0x00000659, + 0x00000001,0x00000004,0x00000658,0x0003003e,0x00000651,0x00000324,0x0004003d,0x00000006, + 0x00000667,0x00000651,0x00050041,0x00000007,0x00000668,0x00000664,0x000000b5,0x0003003e, + 0x00000668,0x00000667,0x0004003d,0x00000006,0x00000669,0x00000651,0x00050041,0x00000007, + 0x0000066a,0x00000664,0x000000b8,0x0003003e,0x0000066a,0x00000669,0x0004003d,0x00000012, + 0x0000066b,0x00000664,0x0003003e,0x00000665,0x0000066b,0x0004003d,0x00000012,0x0000065a, + 0x00000665,0x000500b8,0x00000327,0x0000065b,0x00000659,0x0000065a,0x0004009b,0x000000fa, + 0x0000065c,0x0000065b,0x000300f7,0x00000663,0x00000000,0x000400fa,0x0000065c,0x0000065d, + 0x00000662,0x000200f8,0x0000065d,0x0004003d,0x00000006,0x0000065e,0x0000055f,0x00050041, + 0x00000007,0x0000065f,0x0000055e,0x000000cb,0x0004003d,0x00000006,0x00000660,0x0000065f, + 0x0007000c,0x00000006,0x00000661,0x00000001,0x00000025,0x0000065e,0x00000660,0x0003003e, + 0x0000055f,0x00000661,0x000200f9,0x00000663,0x000200f8,0x00000662,0x0003003e,0x0000055f, + 0x000000ec,0x000200f9,0x00000663,0x000200f8,0x00000663,0x0004003d,0x00000006,0x000005a4, + 0x0000055f,0x0003003e,0x00000559,0x000005a4,0x000200f9,0x000005a5,0x000200f8,0x000005a5, + 0x000200f9,0x000005a6,0x000200f8,0x000005a6,0x000300f7,0x000005ac,0x00000000,0x000400fa, + 0x00000379,0x000005a7,0x000005ac,0x000200f8,0x000005a7,0x0004003d,0x00000018,0x000005a9, + 0x0000057c,0x000500c7,0x00000018,0x000005aa,0x000005a9,0x0000037e,0x000500ab,0x000000fa, + 0x000005ab,0x000005aa,0x000000b5,0x000200f9,0x000005ac,0x000200f8,0x000005ac,0x000700f5, + 0x000000fa,0x000005ad,0x00000379,0x000005a6,0x000005ab,0x000005a7,0x000300f7,0x000005d4, + 0x00000000,0x000400fa,0x000005ad,0x000005ae,0x000005d4,0x000200f8,0x000005ae,0x0004003d, + 0x00000018,0x000005af,0x00000489,0x00050084,0x00000018,0x000005b0,0x000005af,0x0000038b, + 0x00050080,0x00000018,0x000005b1,0x000005b0,0x000000cb,0x00060041,0x0000038f,0x000005b2, + 0x00000389,0x0000026e,0x000005b1,0x0004003d,0x0000000c,0x000005b3,0x000005b2,0x0003003e, + 0x00000561,0x000005b3,0x0004003d,0x0000000c,0x0000066e,0x00000561,0x0004003d,0x0000000c, + 0x00000670,0x00000561,0x00050051,0x00000006,0x00000672,0x0000066e,0x00000000,0x00050051, + 0x00000006,0x00000673,0x0000066e,0x00000001,0x00050051,0x00000006,0x00000674,0x00000670, + 0x00000002,0x00050051,0x00000006,0x00000675,0x00000670,0x00000003,0x00050050,0x00000012, + 0x00000676,0x00000672,0x00000673,0x00050050,0x00000012,0x00000677,0x00000674,0x00000675, + 0x00050050,0x00000039,0x00000678,0x00000676,0x00000677,0x0003003e,0x0000066c,0x00000678, + 0x0004003d,0x00000039,0x000005b4,0x0000066c,0x0003003e,0x00000560,0x000005b4,0x0004003d, + 0x00000018,0x000005b5,0x00000489,0x00050084,0x00000018,0x000005b6,0x000005b5,0x0000038b, + 0x00050080,0x00000018,0x000005b7,0x000005b6,0x000000e2,0x00060041,0x0000038f,0x000005b8, + 0x00000389,0x0000026e,0x000005b7,0x0004003d,0x0000000c,0x000005b9,0x000005b8,0x0003003e, + 0x00000562,0x000005b9,0x0004003d,0x00000039,0x000005ba,0x00000560,0x00050091,0x00000012, + 0x000005bd,0x000005ba,0x00000451,0x0004003d,0x0000000c,0x000005be,0x00000562,0x0007004f, + 0x00000012,0x000005bf,0x000005be,0x000005be,0x00000000,0x00000001,0x00050081,0x00000012, + 0x000005c0,0x000005bd,0x000005bf,0x0003003e,0x00000563,0x000005c0,0x0004003d,0x00000012, + 0x000005c1,0x00000563,0x0006000c,0x00000012,0x000005c2,0x00000001,0x00000004,0x000005c1, + 0x0004003d,0x0000000c,0x000005c3,0x00000562,0x0007004f,0x00000012,0x000005c4,0x000005c3, + 0x000005c3,0x00000002,0x00000003,0x00050085,0x00000012,0x000005c5,0x000005c2,0x000005c4, + 0x0004003d,0x0000000c,0x000005c6,0x00000562,0x0007004f,0x00000012,0x000005c7,0x000005c6, + 0x000005c6,0x00000002,0x00000003,0x00050083,0x00000012,0x000005c8,0x000005c5,0x000005c7, + 0x0003003e,0x00000565,0x000005c8,0x0004003d,0x00000012,0x0000067c,0x00000565,0x0003003e, + 0x00000679,0x0000067c,0x0004003d,0x00000012,0x0000067d,0x00000679,0x0003003e,0x0000067a, + 0x0000067d,0x0004003d,0x00000012,0x000005c9,0x0000067a,0x0003003e,0x00000564,0x000005c9, + 0x00050041,0x00000007,0x000005ca,0x00000564,0x000000b5,0x0004003d,0x00000006,0x000005cb, + 0x000005ca,0x00050041,0x00000007,0x000005cc,0x00000564,0x000000b8,0x0004003d,0x00000006, + 0x000005cd,0x000005cc,0x0007000c,0x00000006,0x000005ce,0x00000001,0x00000025,0x000005cb, + 0x000005cd,0x00050081,0x00000006,0x000005cf,0x000005ce,0x000001ea,0x0008000c,0x00000006, + 0x000005d0,0x00000001,0x0000002b,0x000005cf,0x000000ec,0x000000eb,0x0003003e,0x00000566, + 0x000005d0,0x0004003d,0x00000006,0x000005d1,0x00000559,0x0004003d,0x00000006,0x000005d2, + 0x00000566,0x0007000c,0x00000006,0x000005d3,0x00000001,0x00000025,0x000005d1,0x000005d2, + 0x0003003e,0x00000559,0x000005d3,0x000200f9,0x000005d4,0x000200f8,0x000005d4,0x0004003d, + 0x00000018,0x000005d6,0x0000057c,0x000500c7,0x00000018,0x000005d7,0x000005d6,0x000003bc, + 0x0003003e,0x00000567,0x000005d7,0x0004003d,0x00000018,0x000005d8,0x00000567,0x000500b2, + 0x000000fa,0x000005d9,0x000005d8,0x000000b8,0x000300f7,0x0000061c,0x00000000,0x000400fa, + 0x000005d9,0x000005da,0x000005ed,0x000200f8,0x000005da,0x00050041,0x00000019,0x000005db, + 0x00000558,0x000000b8,0x0004003d,0x00000018,0x000005dc,0x000005db,0x0006000c,0x0000000c, + 0x000005dd,0x00000001,0x00000040,0x000005dc,0x0003003e,0x0000048d,0x000005dd,0x0004003d, + 0x00000018,0x000005de,0x00000567,0x000500aa,0x000000fa,0x000005df,0x000005de,0x000000b5, + 0x000500a7,0x000000fa,0x000005e0,0x00000360,0x000005df,0x000300f7,0x000005ec,0x00000000, + 0x000400fa,0x000005e0,0x000005e1,0x000005ec,0x000200f8,0x000005e1,0x0004003d,0x0000000c, + 0x000005e2,0x0000048d,0x00050041,0x00000007,0x000005e4,0x0000048e,0x000000b5,0x00050051, + 0x00000006,0x000005e5,0x000005e2,0x00000002,0x0003003e,0x000005e4,0x000005e5,0x00050041, + 0x00000007,0x000005e6,0x0000048e,0x000000b8,0x00050051,0x00000006,0x000005e7,0x000005e2, + 0x00000003,0x0003003e,0x000005e6,0x000005e7,0x0004003d,0x00000006,0x000005e8,0x00000559, + 0x00050041,0x00000007,0x000005e9,0x0000048e,0x000000cb,0x0003003e,0x000005e9,0x000005e8, + 0x00050041,0x00000007,0x000005ea,0x0000048e,0x000000e2,0x0003003e,0x000005ea,0x000000eb, + 0x0003003e,0x00000568,0x000000ec,0x0004003d,0x00000006,0x00000681,0x00000568,0x00050041, + 0x00000007,0x00000682,0x0000067e,0x000000b5,0x0003003e,0x00000682,0x00000681,0x0004003d, + 0x00000006,0x00000683,0x00000568,0x00050041,0x00000007,0x00000684,0x0000067e,0x000000b8, + 0x0003003e,0x00000684,0x00000683,0x0004003d,0x00000006,0x00000685,0x00000568,0x00050041, + 0x00000007,0x00000686,0x0000067e,0x000000cb,0x0003003e,0x00000686,0x00000685,0x0004003d, + 0x00000006,0x00000687,0x00000568,0x00050041,0x00000007,0x00000688,0x0000067e,0x000000e2, + 0x0003003e,0x00000688,0x00000687,0x0004003d,0x0000000c,0x00000689,0x0000067e,0x0003003e, + 0x0000067f,0x00000689,0x0004003d,0x0000000c,0x000005eb,0x0000067f,0x0003003e,0x0000048d, + 0x000005eb,0x000200f9,0x000005ec,0x000200f8,0x000005ec,0x000200f9,0x0000061c,0x000200f8, + 0x000005ed,0x0004003d,0x00000018,0x000005ee,0x00000489,0x00050084,0x00000018,0x000005ef, + 0x000005ee,0x0000038b,0x00060041,0x0000038f,0x000005f0,0x00000389,0x0000026e,0x000005ef, + 0x0004003d,0x0000000c,0x000005f1,0x000005f0,0x0003003e,0x0000056a,0x000005f1,0x0004003d, + 0x0000000c,0x0000068c,0x0000056a,0x0004003d,0x0000000c,0x0000068e,0x0000056a,0x00050051, + 0x00000006,0x00000690,0x0000068c,0x00000000,0x00050051,0x00000006,0x00000691,0x0000068c, + 0x00000001,0x00050051,0x00000006,0x00000692,0x0000068e,0x00000002,0x00050051,0x00000006, + 0x00000693,0x0000068e,0x00000003,0x00050050,0x00000012,0x00000694,0x00000690,0x00000691, + 0x00050050,0x00000012,0x00000695,0x00000692,0x00000693,0x00050050,0x00000039,0x00000696, + 0x00000694,0x00000695,0x0003003e,0x0000068a,0x00000696,0x0004003d,0x00000039,0x000005f2, + 0x0000068a,0x0003003e,0x00000569,0x000005f2,0x0004003d,0x00000018,0x000005f3,0x00000489, + 0x00050084,0x00000018,0x000005f4,0x000005f3,0x0000038b,0x00050080,0x00000018,0x000005f5, + 0x000005f4,0x000000b8,0x00060041,0x0000038f,0x000005f6,0x00000389,0x0000026e,0x000005f5, + 0x0004003d,0x0000000c,0x000005f7,0x000005f6,0x0003003e,0x0000056b,0x000005f7,0x0004003d, + 0x00000039,0x000005f8,0x00000569,0x00050091,0x00000012,0x000005fb,0x000005f8,0x00000451, + 0x0004003d,0x0000000c,0x000005fc,0x0000056b,0x0007004f,0x00000012,0x000005fd,0x000005fc, + 0x000005fc,0x00000000,0x00000001,0x00050081,0x00000012,0x000005fe,0x000005fb,0x000005fd, + 0x0003003e,0x0000056c,0x000005fe,0x0004003d,0x00000018,0x000005ff,0x00000567,0x000500aa, + 0x000000fa,0x00000600,0x000005ff,0x000000cb,0x000300f7,0x00000607,0x00000000,0x000400fa, + 0x00000600,0x00000601,0x00000604,0x000200f8,0x00000601,0x00050041,0x00000007,0x00000602, + 0x0000056c,0x000000b5,0x0004003d,0x00000006,0x00000603,0x00000602,0x0003003e,0x0000056e, + 0x00000603,0x000200f9,0x00000607,0x000200f8,0x00000604,0x0004003d,0x00000012,0x00000605, + 0x0000056c,0x0006000c,0x00000006,0x00000606,0x00000001,0x00000042,0x00000605,0x0003003e, + 0x0000056e,0x00000606,0x000200f9,0x00000607,0x000200f8,0x00000607,0x0004003d,0x00000006, + 0x00000608,0x0000056e,0x0003003e,0x0000056d,0x00000608,0x0004003d,0x00000006,0x00000609, + 0x0000056d,0x0008000c,0x00000006,0x0000060a,0x00000001,0x0000002b,0x00000609,0x000000ec, + 0x000000eb,0x0003003e,0x0000056d,0x0000060a,0x0004003d,0x00000006,0x0000060b,0x0000056d, + 0x00050041,0x00000007,0x0000060c,0x0000056b,0x000000cb,0x0004003d,0x00000006,0x0000060d, + 0x0000060c,0x00050085,0x00000006,0x0000060e,0x0000060b,0x0000060d,0x00050041,0x00000007, + 0x0000060f,0x0000056b,0x000000e2,0x0004003d,0x00000006,0x00000610,0x0000060f,0x00050081, + 0x00000006,0x00000611,0x0000060e,0x00000610,0x0003003e,0x0000056f,0x00000611,0x00050041, + 0x00000019,0x00000612,0x00000558,0x000000b8,0x0004003d,0x00000018,0x00000613,0x00000612, + 0x0004007c,0x00000006,0x00000614,0x00000613,0x0003003e,0x00000570,0x00000614,0x0004003d, + 0x00000405,0x00000615,0x00000407,0x0004003d,0x00000409,0x00000616,0x0000040b,0x00050056, + 0x0000040d,0x00000617,0x00000615,0x00000616,0x0004003d,0x00000006,0x00000618,0x0000056f, + 0x0004003d,0x00000006,0x00000619,0x00000570,0x00050050,0x00000012,0x0000061a,0x00000618, + 0x00000619,0x00070058,0x0000000c,0x0000061b,0x00000617,0x0000061a,0x00000002,0x000000ec, + 0x0003003e,0x0000048d,0x0000061b,0x000200f9,0x0000061c,0x000200f8,0x0000061c,0x0004003d, + 0x00000006,0x0000061d,0x00000559,0x00050041,0x00000007,0x0000061e,0x0000048d,0x000000e2, + 0x0004003d,0x00000006,0x0000061f,0x0000061e,0x00050085,0x00000006,0x00000620,0x0000061f, + 0x0000061d,0x0003003e,0x0000061e,0x00000620,0x000300f7,0x00000626,0x00000000,0x000400fa, + 0x00000418,0x00000622,0x00000626,0x000200f8,0x00000622,0x0004003d,0x00000006,0x00000624, + 0x0000061e,0x000500b7,0x000000fa,0x00000625,0x00000624,0x000000ec,0x000200f9,0x00000626, + 0x000200f8,0x00000626,0x000700f5,0x000000fa,0x00000627,0x00000418,0x0000061c,0x00000625, + 0x00000622,0x000300f7,0x0000062f,0x00000000,0x000400fa,0x00000627,0x00000628,0x0000062f, + 0x000200f8,0x00000628,0x0004003d,0x00000018,0x0000062a,0x0000057c,0x000500c2,0x00000018, + 0x0000062b,0x0000062a,0x00000424,0x000500c7,0x00000018,0x0000062c,0x0000062b,0x000003bc, + 0x0003003e,0x00000572,0x0000062c,0x0004003d,0x00000018,0x0000069a,0x00000572,0x0003003e, + 0x00000697,0x0000069a,0x0004003d,0x00000018,0x0000069b,0x00000697,0x0003003e,0x00000698, + 0x0000069b,0x0004003d,0x00000018,0x0000062d,0x00000698,0x0003003e,0x00000571,0x0000062d, + 0x000500ab,0x000000fa,0x0000062e,0x0000062d,0x000000b5,0x000200f9,0x0000062f,0x000200f8, + 0x0000062f,0x000700f5,0x000000fa,0x00000630,0x00000627,0x00000626,0x0000062e,0x00000628, + 0x000300f7,0x0000063f,0x00000000,0x000400fa,0x00000630,0x00000631,0x0000063f,0x000200f8, + 0x00000631,0x0004003d,0x0000036c,0x00000632,0x0000042e,0x00050062,0x0000000c,0x00000633, + 0x00000632,0x00000370,0x0003003e,0x00000573,0x00000633,0x0004003d,0x0000000c,0x00000634, + 0x0000048d,0x0008004f,0x0000002a,0x00000635,0x00000634,0x00000634,0x00000000,0x00000001, + 0x00000002,0x0003003e,0x00000574,0x00000635,0x0004003d,0x0000000c,0x00000636,0x00000573, + 0x0003003e,0x00000575,0x00000636,0x0004003d,0x00000018,0x00000637,0x00000571,0x0003003e, + 0x00000576,0x00000637,0x0004003d,0x0000002a,0x000006a3,0x00000574,0x0003003e,0x0000069d, + 0x000006a3,0x0004003d,0x0000000c,0x000006a4,0x00000575,0x0003003e,0x0000069e,0x000006a4, + 0x0004003d,0x00000018,0x000006a5,0x00000576,0x0003003e,0x0000069f,0x000006a5,0x0004003d, + 0x0000000c,0x000006d5,0x0000069e,0x0003003e,0x000006ae,0x000006d5,0x0004003d,0x0000000c, + 0x000007d1,0x000006ae,0x0008004f,0x0000002a,0x000007d2,0x000007d1,0x000007d1,0x00000000, + 0x00000001,0x00000002,0x00050041,0x00000007,0x000007d3,0x000006ae,0x000000e2,0x0004003d, + 0x00000006,0x000007d4,0x000007d3,0x000500b7,0x000000fa,0x000007d5,0x000007d4,0x000000ec, + 0x000300f7,0x000007db,0x00000000,0x000400fa,0x000007d5,0x000007d6,0x000007da,0x000200f8, + 0x000007d6,0x0004003d,0x00000006,0x000007d8,0x000007d3,0x00050088,0x00000006,0x000007d9, + 0x000000eb,0x000007d8,0x0003003e,0x000007ce,0x000007d9,0x000200f9,0x000007db,0x000200f8, + 0x000007da,0x0003003e,0x000007ce,0x000000ec,0x000200f9,0x000007db,0x000200f8,0x000007db, + 0x0004003d,0x00000006,0x000007dc,0x000007ce,0x0005008e,0x0000002a,0x000007dd,0x000007d2, + 0x000007dc,0x0003003e,0x000007cf,0x000007dd,0x0004003d,0x0000002a,0x000006d6,0x000007cf, + 0x0003003e,0x000006ad,0x000006d6,0x0004003d,0x00000018,0x000006d7,0x0000069f,0x000300f7, + 0x000007cc,0x00000000,0x002100fb,0x000006d7,0x000007cc,0x0000000b,0x000006d8,0x00000001, + 0x000006dc,0x00000002,0x000006e4,0x00000003,0x000006f4,0x00000004,0x000006f8,0x00000005, + 0x000006fc,0x00000006,0x0000071e,0x00000007,0x0000074a,0x00000008,0x0000075a,0x00000009, + 0x00000794,0x0000000a,0x00000799,0x0000000c,0x000007a2,0x0000000d,0x000007ad,0x0000000e, + 0x000007b8,0x0000000f,0x000007c2,0x000200f8,0x000006d8,0x0004003d,0x0000002a,0x000006d9, + 0x0000069d,0x0004003d,0x0000002a,0x000006da,0x000006ad,0x00050085,0x0000002a,0x000006db, + 0x000006d9,0x000006da,0x0003003e,0x000006af,0x000006db,0x000200f9,0x000007cc,0x000200f8, + 0x000006dc,0x0004003d,0x0000002a,0x000006dd,0x0000069d,0x0004003d,0x0000002a,0x000006de, + 0x000006ad,0x00050081,0x0000002a,0x000006df,0x000006dd,0x000006de,0x0004003d,0x0000002a, + 0x000006e0,0x0000069d,0x0004003d,0x0000002a,0x000006e1,0x000006ad,0x00050085,0x0000002a, + 0x000006e2,0x000006e0,0x000006e1,0x00050083,0x0000002a,0x000006e3,0x000006df,0x000006e2, + 0x0003003e,0x000006af,0x000006e3,0x000200f9,0x000007cc,0x000200f8,0x000006e4,0x0004003d, + 0x0000002a,0x000006e5,0x0000069d,0x0004003d,0x0000002a,0x000006e6,0x000006ad,0x00050085, + 0x0000002a,0x000006e7,0x000006e5,0x000006e6,0x0003003e,0x000006b0,0x000006e7,0x0004003d, + 0x0000002a,0x000006e8,0x000006b0,0x0004003d,0x0000002a,0x000006e9,0x0000069d,0x0004003d, + 0x0000002a,0x000006ea,0x000006ad,0x00050081,0x0000002a,0x000006eb,0x000006e9,0x000006ea, + 0x0004003d,0x0000002a,0x000006ec,0x000006b0,0x00050083,0x0000002a,0x000006ed,0x000006eb, + 0x000006ec,0x00050083,0x0000002a,0x000006ee,0x000006ed,0x0000051f,0x0004003d,0x0000002a, + 0x000006ef,0x000006ad,0x0003003e,0x000006b1,0x000001ea,0x0004003d,0x00000006,0x000007e1, + 0x000006b1,0x00050041,0x00000007,0x000007e2,0x000007de,0x000000b5,0x0003003e,0x000007e2, + 0x000007e1,0x0004003d,0x00000006,0x000007e3,0x000006b1,0x00050041,0x00000007,0x000007e4, + 0x000007de,0x000000b8,0x0003003e,0x000007e4,0x000007e3,0x0004003d,0x00000006,0x000007e5, + 0x000006b1,0x00050041,0x00000007,0x000007e6,0x000007de,0x000000cb,0x0003003e,0x000007e6, + 0x000007e5,0x0004003d,0x0000002a,0x000007e7,0x000007de,0x0003003e,0x000007df,0x000007e7, + 0x0004003d,0x0000002a,0x000006f0,0x000007df,0x000500ba,0x000001f0,0x000006f1,0x000006ef, + 0x000006f0,0x000600a9,0x0000002a,0x000006f2,0x000006f1,0x000006ee,0x000006e8,0x0005008e, + 0x0000002a,0x000006f3,0x000006f2,0x000001e3,0x0003003e,0x000006af,0x000006f3,0x000200f9, + 0x000007cc,0x000200f8,0x000006f4,0x0004003d,0x0000002a,0x000006f5,0x0000069d,0x0004003d, + 0x0000002a,0x000006f6,0x000006ad,0x0007000c,0x0000002a,0x000006f7,0x00000001,0x00000025, + 0x000006f5,0x000006f6,0x0003003e,0x000006af,0x000006f7,0x000200f9,0x000007cc,0x000200f8, + 0x000006f8,0x0004003d,0x0000002a,0x000006f9,0x0000069d,0x0004003d,0x0000002a,0x000006fa, + 0x000006ad,0x0007000c,0x0000002a,0x000006fb,0x00000001,0x00000028,0x000006f9,0x000006fa, + 0x0003003e,0x000006af,0x000006fb,0x000200f9,0x000007cc,0x000200f8,0x000006fc,0x0004003d, + 0x0000000c,0x000006fd,0x0000069e,0x0008004f,0x0000002a,0x000006fe,0x000006fd,0x000006fd, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x000006b2,0x000000ec,0x0004003d,0x00000006, + 0x000007eb,0x000006b2,0x00050041,0x00000007,0x000007ec,0x000007e8,0x000000b5,0x0003003e, + 0x000007ec,0x000007eb,0x0004003d,0x00000006,0x000007ed,0x000006b2,0x00050041,0x00000007, + 0x000007ee,0x000007e8,0x000000b8,0x0003003e,0x000007ee,0x000007ed,0x0004003d,0x00000006, + 0x000007ef,0x000006b2,0x00050041,0x00000007,0x000007f0,0x000007e8,0x000000cb,0x0003003e, + 0x000007f0,0x000007ef,0x0004003d,0x0000002a,0x000007f1,0x000007e8,0x0003003e,0x000007e9, + 0x000007f1,0x0004003d,0x0000002a,0x000006ff,0x000007e9,0x0004003d,0x0000000c,0x00000700, + 0x0000069e,0x0008004f,0x0000002a,0x00000701,0x00000700,0x00000700,0x00000003,0x00000003, + 0x00000003,0x0008000c,0x0000002a,0x00000702,0x00000001,0x0000002b,0x000006fe,0x000006ff, + 0x00000701,0x00050041,0x00000007,0x00000703,0x0000069e,0x000000b5,0x00050051,0x00000006, + 0x00000704,0x00000702,0x00000000,0x0003003e,0x00000703,0x00000704,0x00050041,0x00000007, + 0x00000705,0x0000069e,0x000000b8,0x00050051,0x00000006,0x00000706,0x00000702,0x00000001, + 0x0003003e,0x00000705,0x00000706,0x00050041,0x00000007,0x00000707,0x0000069e,0x000000cb, + 0x00050051,0x00000006,0x00000708,0x00000702,0x00000002,0x0003003e,0x00000707,0x00000708, + 0x0004003d,0x0000002a,0x00000709,0x0000069d,0x00050083,0x0000002a,0x0000070a,0x0000051e, + 0x00000709,0x0003003e,0x000006b4,0x000000ec,0x0004003d,0x00000006,0x000007f5,0x000006b4, + 0x00050041,0x00000007,0x000007f6,0x000007f2,0x000000b5,0x0003003e,0x000007f6,0x000007f5, + 0x0004003d,0x00000006,0x000007f7,0x000006b4,0x00050041,0x00000007,0x000007f8,0x000007f2, + 0x000000b8,0x0003003e,0x000007f8,0x000007f7,0x0004003d,0x00000006,0x000007f9,0x000006b4, + 0x00050041,0x00000007,0x000007fa,0x000007f2,0x000000cb,0x0003003e,0x000007fa,0x000007f9, + 0x0004003d,0x0000002a,0x000007fb,0x000007f2,0x0003003e,0x000007f3,0x000007fb,0x0004003d, + 0x0000002a,0x0000070b,0x000007f3,0x0003003e,0x000006b5,0x000000eb,0x0004003d,0x00000006, + 0x000007ff,0x000006b5,0x00050041,0x00000007,0x00000800,0x000007fc,0x000000b5,0x0003003e, + 0x00000800,0x000007ff,0x0004003d,0x00000006,0x00000801,0x000006b5,0x00050041,0x00000007, + 0x00000802,0x000007fc,0x000000b8,0x0003003e,0x00000802,0x00000801,0x0004003d,0x00000006, + 0x00000803,0x000006b5,0x00050041,0x00000007,0x00000804,0x000007fc,0x000000cb,0x0003003e, + 0x00000804,0x00000803,0x0004003d,0x0000002a,0x00000805,0x000007fc,0x0003003e,0x000007fd, + 0x00000805,0x0004003d,0x0000002a,0x0000070c,0x000007fd,0x0008000c,0x0000002a,0x0000070d, + 0x00000001,0x0000002b,0x0000070a,0x0000070b,0x0000070c,0x00050041,0x00000007,0x0000070e, + 0x0000069e,0x000000e2,0x0004003d,0x00000006,0x0000070f,0x0000070e,0x0005008e,0x0000002a, + 0x00000710,0x0000070d,0x0000070f,0x0003003e,0x000006b3,0x00000710,0x0003003e,0x000006b6, + 0x000000eb,0x0004003d,0x00000006,0x00000809,0x000006b6,0x00050041,0x00000007,0x0000080a, + 0x00000806,0x000000b5,0x0003003e,0x0000080a,0x00000809,0x0004003d,0x00000006,0x0000080b, + 0x000006b6,0x00050041,0x00000007,0x0000080c,0x00000806,0x000000b8,0x0003003e,0x0000080c, + 0x0000080b,0x0004003d,0x00000006,0x0000080d,0x000006b6,0x00050041,0x00000007,0x0000080e, + 0x00000806,0x000000cb,0x0003003e,0x0000080e,0x0000080d,0x0004003d,0x0000002a,0x0000080f, + 0x00000806,0x0003003e,0x00000807,0x0000080f,0x0004003d,0x0000002a,0x00000711,0x00000807, + 0x0004003d,0x0000000c,0x00000712,0x0000069e,0x0008004f,0x0000002a,0x00000713,0x00000712, + 0x00000712,0x00000000,0x00000001,0x00000002,0x0004003d,0x0000002a,0x00000714,0x000006b3, + 0x00050088,0x0000002a,0x00000715,0x00000713,0x00000714,0x0007000c,0x0000002a,0x00000716, + 0x00000001,0x00000025,0x00000711,0x00000715,0x0004003d,0x0000000c,0x00000717,0x0000069e, + 0x0008004f,0x0000002a,0x00000718,0x00000717,0x00000717,0x00000000,0x00000001,0x00000002, + 0x0006000c,0x0000002a,0x00000719,0x00000001,0x00000006,0x00000718,0x0004003d,0x0000002a, + 0x0000071a,0x000006b3,0x0003003e,0x000006b7,0x000000ec,0x0004003d,0x00000006,0x00000813, + 0x000006b7,0x00050041,0x00000007,0x00000814,0x00000810,0x000000b5,0x0003003e,0x00000814, + 0x00000813,0x0004003d,0x00000006,0x00000815,0x000006b7,0x00050041,0x00000007,0x00000816, + 0x00000810,0x000000b8,0x0003003e,0x00000816,0x00000815,0x0004003d,0x00000006,0x00000817, + 0x000006b7,0x00050041,0x00000007,0x00000818,0x00000810,0x000000cb,0x0003003e,0x00000818, + 0x00000817,0x0004003d,0x0000002a,0x00000819,0x00000810,0x0003003e,0x00000811,0x00000819, + 0x0004003d,0x0000002a,0x0000071b,0x00000811,0x000500b4,0x000001f0,0x0000071c,0x0000071a, + 0x0000071b,0x000600a9,0x0000002a,0x0000071d,0x0000071c,0x00000719,0x00000716,0x0003003e, + 0x000006af,0x0000071d,0x000200f9,0x000007cc,0x000200f8,0x0000071e,0x0004003d,0x0000002a, + 0x0000071f,0x0000069d,0x0003003e,0x000006b8,0x000000ec,0x0004003d,0x00000006,0x0000081d, + 0x000006b8,0x00050041,0x00000007,0x0000081e,0x0000081a,0x000000b5,0x0003003e,0x0000081e, + 0x0000081d,0x0004003d,0x00000006,0x0000081f,0x000006b8,0x00050041,0x00000007,0x00000820, + 0x0000081a,0x000000b8,0x0003003e,0x00000820,0x0000081f,0x0004003d,0x00000006,0x00000821, + 0x000006b8,0x00050041,0x00000007,0x00000822,0x0000081a,0x000000cb,0x0003003e,0x00000822, + 0x00000821,0x0004003d,0x0000002a,0x00000823,0x0000081a,0x0003003e,0x0000081b,0x00000823, + 0x0004003d,0x0000002a,0x00000720,0x0000081b,0x0003003e,0x000006b9,0x000000eb,0x0004003d, + 0x00000006,0x00000827,0x000006b9,0x00050041,0x00000007,0x00000828,0x00000824,0x000000b5, + 0x0003003e,0x00000828,0x00000827,0x0004003d,0x00000006,0x00000829,0x000006b9,0x00050041, + 0x00000007,0x0000082a,0x00000824,0x000000b8,0x0003003e,0x0000082a,0x00000829,0x0004003d, + 0x00000006,0x0000082b,0x000006b9,0x00050041,0x00000007,0x0000082c,0x00000824,0x000000cb, + 0x0003003e,0x0000082c,0x0000082b,0x0004003d,0x0000002a,0x0000082d,0x00000824,0x0003003e, + 0x00000825,0x0000082d,0x0004003d,0x0000002a,0x00000721,0x00000825,0x0008000c,0x0000002a, + 0x00000722,0x00000001,0x0000002b,0x0000071f,0x00000720,0x00000721,0x0003003e,0x0000069d, + 0x00000722,0x0004003d,0x0000000c,0x00000723,0x0000069e,0x0008004f,0x0000002a,0x00000724, + 0x00000723,0x00000723,0x00000000,0x00000001,0x00000002,0x0003003e,0x000006ba,0x000000ec, + 0x0004003d,0x00000006,0x00000831,0x000006ba,0x00050041,0x00000007,0x00000832,0x0000082e, + 0x000000b5,0x0003003e,0x00000832,0x00000831,0x0004003d,0x00000006,0x00000833,0x000006ba, + 0x00050041,0x00000007,0x00000834,0x0000082e,0x000000b8,0x0003003e,0x00000834,0x00000833, + 0x0004003d,0x00000006,0x00000835,0x000006ba,0x00050041,0x00000007,0x00000836,0x0000082e, + 0x000000cb,0x0003003e,0x00000836,0x00000835,0x0004003d,0x0000002a,0x00000837,0x0000082e, + 0x0003003e,0x0000082f,0x00000837,0x0004003d,0x0000002a,0x00000725,0x0000082f,0x0004003d, + 0x0000000c,0x00000726,0x0000069e,0x0008004f,0x0000002a,0x00000727,0x00000726,0x00000726, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x0000002a,0x00000728,0x00000001,0x0000002b, + 0x00000724,0x00000725,0x00000727,0x00050041,0x00000007,0x00000729,0x0000069e,0x000000b5, + 0x00050051,0x00000006,0x0000072a,0x00000728,0x00000000,0x0003003e,0x00000729,0x0000072a, + 0x00050041,0x00000007,0x0000072b,0x0000069e,0x000000b8,0x00050051,0x00000006,0x0000072c, + 0x00000728,0x00000001,0x0003003e,0x0000072b,0x0000072c,0x00050041,0x00000007,0x0000072d, + 0x0000069e,0x000000cb,0x00050051,0x00000006,0x0000072e,0x00000728,0x00000002,0x0003003e, + 0x0000072d,0x0000072e,0x00050041,0x00000007,0x0000072f,0x0000069e,0x000000e2,0x0004003d, + 0x00000006,0x00000730,0x0000072f,0x000500b4,0x000000fa,0x00000731,0x00000730,0x000000ec, + 0x000300f7,0x00000734,0x00000000,0x000400fa,0x00000731,0x00000732,0x00000734,0x000200f8, + 0x00000732,0x0003003e,0x0000072f,0x000000eb,0x000200f9,0x00000734,0x000200f8,0x00000734, + 0x0004003d,0x00000006,0x00000736,0x0000072f,0x0004003d,0x0000000c,0x00000737,0x0000069e, + 0x0008004f,0x0000002a,0x00000738,0x00000737,0x00000737,0x00000000,0x00000001,0x00000002, + 0x00060050,0x0000002a,0x00000739,0x00000736,0x00000736,0x00000736,0x00050083,0x0000002a, + 0x0000073a,0x00000739,0x00000738,0x0003003e,0x000006bb,0x0000073a,0x0003003e,0x000006bc, + 0x000000eb,0x0004003d,0x00000006,0x0000083b,0x000006bc,0x00050041,0x00000007,0x0000083c, + 0x00000838,0x000000b5,0x0003003e,0x0000083c,0x0000083b,0x0004003d,0x00000006,0x0000083d, + 0x000006bc,0x00050041,0x00000007,0x0000083e,0x00000838,0x000000b8,0x0003003e,0x0000083e, + 0x0000083d,0x0004003d,0x00000006,0x0000083f,0x000006bc,0x00050041,0x00000007,0x00000840, + 0x00000838,0x000000cb,0x0003003e,0x00000840,0x0000083f,0x0004003d,0x0000002a,0x00000841, + 0x00000838,0x0003003e,0x00000839,0x00000841,0x0004003d,0x0000002a,0x0000073b,0x00000839, + 0x0004003d,0x0000002a,0x0000073c,0x000006bb,0x0004003d,0x0000002a,0x0000073d,0x0000069d, + 0x0004003d,0x00000006,0x0000073f,0x0000072f,0x0005008e,0x0000002a,0x00000740,0x0000073d, + 0x0000073f,0x00050088,0x0000002a,0x00000741,0x0000073c,0x00000740,0x0007000c,0x0000002a, + 0x00000742,0x00000001,0x00000025,0x0000073b,0x00000741,0x0004003d,0x0000002a,0x00000743, + 0x000006bb,0x0006000c,0x0000002a,0x00000744,0x00000001,0x00000006,0x00000743,0x0004003d, + 0x0000002a,0x00000745,0x0000069d,0x0003003e,0x000006bd,0x000000ec,0x0004003d,0x00000006, + 0x00000845,0x000006bd,0x00050041,0x00000007,0x00000846,0x00000842,0x000000b5,0x0003003e, + 0x00000846,0x00000845,0x0004003d,0x00000006,0x00000847,0x000006bd,0x00050041,0x00000007, + 0x00000848,0x00000842,0x000000b8,0x0003003e,0x00000848,0x00000847,0x0004003d,0x00000006, + 0x00000849,0x000006bd,0x00050041,0x00000007,0x0000084a,0x00000842,0x000000cb,0x0003003e, + 0x0000084a,0x00000849,0x0004003d,0x0000002a,0x0000084b,0x00000842,0x0003003e,0x00000843, + 0x0000084b,0x0004003d,0x0000002a,0x00000746,0x00000843,0x000500b4,0x000001f0,0x00000747, + 0x00000745,0x00000746,0x000600a9,0x0000002a,0x00000748,0x00000747,0x00000744,0x00000742, + 0x00050083,0x0000002a,0x00000749,0x0000051e,0x00000748,0x0003003e,0x000006af,0x00000749, + 0x000200f9,0x000007cc,0x000200f8,0x0000074a,0x0004003d,0x0000002a,0x0000074b,0x0000069d, + 0x0004003d,0x0000002a,0x0000074c,0x000006ad,0x00050085,0x0000002a,0x0000074d,0x0000074b, + 0x0000074c,0x0003003e,0x000006be,0x0000074d,0x0004003d,0x0000002a,0x0000074e,0x000006be, + 0x0004003d,0x0000002a,0x0000074f,0x0000069d,0x0004003d,0x0000002a,0x00000750,0x000006ad, + 0x00050081,0x0000002a,0x00000751,0x0000074f,0x00000750,0x0004003d,0x0000002a,0x00000752, + 0x000006be,0x00050083,0x0000002a,0x00000753,0x00000751,0x00000752,0x00050083,0x0000002a, + 0x00000754,0x00000753,0x0000051f,0x0004003d,0x0000002a,0x00000755,0x0000069d,0x0003003e, + 0x000006bf,0x000001ea,0x0004003d,0x00000006,0x0000084f,0x000006bf,0x00050041,0x00000007, + 0x00000850,0x0000084c,0x000000b5,0x0003003e,0x00000850,0x0000084f,0x0004003d,0x00000006, + 0x00000851,0x000006bf,0x00050041,0x00000007,0x00000852,0x0000084c,0x000000b8,0x0003003e, + 0x00000852,0x00000851,0x0004003d,0x00000006,0x00000853,0x000006bf,0x00050041,0x00000007, + 0x00000854,0x0000084c,0x000000cb,0x0003003e,0x00000854,0x00000853,0x0004003d,0x0000002a, + 0x00000855,0x0000084c,0x0003003e,0x0000084d,0x00000855,0x0004003d,0x0000002a,0x00000756, + 0x0000084d,0x000500ba,0x000001f0,0x00000757,0x00000755,0x00000756,0x000600a9,0x0000002a, + 0x00000758,0x00000757,0x00000754,0x0000074e,0x0005008e,0x0000002a,0x00000759,0x00000758, + 0x000001e3,0x0003003e,0x000006af,0x00000759,0x000200f9,0x000007cc,0x000200f8,0x0000075a, + 0x0003003e,0x000006c0,0x0000026e,0x000200f9,0x0000075b,0x000200f8,0x0000075b,0x0004003d, + 0x00000088,0x0000075d,0x000006c0,0x000500b1,0x000000fa,0x0000075e,0x0000075d,0x00000275, + 0x000400f6,0x0000078a,0x00000787,0x00000000,0x000400fa,0x0000075e,0x0000075f,0x0000078a, + 0x000200f8,0x0000075f,0x0004003d,0x00000088,0x00000760,0x000006c0,0x00050041,0x00000007, + 0x00000761,0x0000069d,0x00000760,0x0004003d,0x00000006,0x00000762,0x00000761,0x000500bc, + 0x000000fa,0x00000763,0x00000762,0x000001ea,0x000300f7,0x00000786,0x00000000,0x000400fa, + 0x00000763,0x00000764,0x0000076b,0x000200f8,0x00000764,0x0004003d,0x00000088,0x00000765, + 0x000006c0,0x0004003d,0x00000088,0x00000766,0x000006c0,0x00050041,0x00000007,0x00000767, + 0x000006ad,0x00000766,0x0004003d,0x00000006,0x00000768,0x00000767,0x00050083,0x00000006, + 0x00000769,0x000000eb,0x00000768,0x00050041,0x00000007,0x0000076a,0x000006af,0x00000765, + 0x0003003e,0x0000076a,0x00000769,0x000200f9,0x00000786,0x000200f8,0x0000076b,0x0004003d, + 0x00000088,0x0000076c,0x000006c0,0x00050041,0x00000007,0x0000076d,0x000006ad,0x0000076c, + 0x0004003d,0x00000006,0x0000076e,0x0000076d,0x000500bc,0x000000fa,0x0000076f,0x0000076e, + 0x00000287,0x000300f7,0x00000785,0x00000000,0x000400fa,0x0000076f,0x00000770,0x0000077d, + 0x000200f8,0x00000770,0x0004003d,0x00000088,0x00000771,0x000006c0,0x0004003d,0x00000088, + 0x00000772,0x000006c0,0x00050041,0x00000007,0x00000773,0x000006ad,0x00000772,0x0004003d, + 0x00000006,0x00000774,0x00000773,0x00050085,0x00000006,0x00000775,0x0000028c,0x00000774, + 0x00050083,0x00000006,0x00000776,0x00000775,0x00000291,0x0004003d,0x00000088,0x00000777, + 0x000006c0,0x00050041,0x00000007,0x00000778,0x000006ad,0x00000777,0x0004003d,0x00000006, + 0x00000779,0x00000778,0x00050085,0x00000006,0x0000077a,0x00000776,0x00000779,0x00050081, + 0x00000006,0x0000077b,0x0000077a,0x00000297,0x00050041,0x00000007,0x0000077c,0x000006af, + 0x00000771,0x0003003e,0x0000077c,0x0000077b,0x000200f9,0x00000785,0x000200f8,0x0000077d, + 0x0004003d,0x00000088,0x0000077e,0x000006c0,0x0004003d,0x00000088,0x0000077f,0x000006c0, + 0x00050041,0x00000007,0x00000780,0x000006ad,0x0000077f,0x0004003d,0x00000006,0x00000781, + 0x00000780,0x0006000c,0x00000006,0x00000782,0x00000001,0x00000020,0x00000781,0x00050083, + 0x00000006,0x00000783,0x00000782,0x000000eb,0x00050041,0x00000007,0x00000784,0x000006af, + 0x0000077e,0x0003003e,0x00000784,0x00000783,0x000200f9,0x00000785,0x000200f8,0x00000785, + 0x000200f9,0x00000786,0x000200f8,0x00000786,0x000200f9,0x00000787,0x000200f8,0x00000787, + 0x0004003d,0x00000088,0x00000788,0x000006c0,0x00050080,0x00000088,0x00000789,0x00000788, + 0x000002a3,0x0003003e,0x000006c0,0x00000789,0x000200f9,0x0000075b,0x000200f8,0x0000078a, + 0x0004003d,0x0000002a,0x0000078b,0x000006ad,0x0004003d,0x0000002a,0x0000078c,0x000006ad, + 0x0004003d,0x0000002a,0x0000078d,0x0000069d,0x0005008e,0x0000002a,0x0000078e,0x0000078d, + 0x000001e3,0x00050083,0x0000002a,0x0000078f,0x0000078e,0x0000051e,0x00050085,0x0000002a, + 0x00000790,0x0000078c,0x0000078f,0x0004003d,0x0000002a,0x00000791,0x000006af,0x00050085, + 0x0000002a,0x00000792,0x00000790,0x00000791,0x00050081,0x0000002a,0x00000793,0x0000078b, + 0x00000792,0x0003003e,0x000006af,0x00000793,0x000200f9,0x000007cc,0x000200f8,0x00000794, + 0x0004003d,0x0000002a,0x00000795,0x000006ad,0x0004003d,0x0000002a,0x00000796,0x0000069d, + 0x00050083,0x0000002a,0x00000797,0x00000795,0x00000796,0x0006000c,0x0000002a,0x00000798, + 0x00000001,0x00000004,0x00000797,0x0003003e,0x000006af,0x00000798,0x000200f9,0x000007cc, + 0x000200f8,0x00000799,0x0004003d,0x0000002a,0x0000079a,0x0000069d,0x0004003d,0x0000002a, + 0x0000079b,0x000006ad,0x00050081,0x0000002a,0x0000079c,0x0000079a,0x0000079b,0x0004003d, + 0x0000002a,0x0000079d,0x0000069d,0x0005008e,0x0000002a,0x0000079e,0x0000079d,0x000001e3, + 0x0004003d,0x0000002a,0x0000079f,0x000006ad,0x00050085,0x0000002a,0x000007a0,0x0000079e, + 0x0000079f,0x00050083,0x0000002a,0x000007a1,0x0000079c,0x000007a0,0x0003003e,0x000006af, + 0x000007a1,0x000200f9,0x000007cc,0x000200f8,0x000007a2,0x000300f7,0x000007ac,0x00000000, + 0x000400fa,0x000002be,0x000007a3,0x000007ac,0x000200f8,0x000007a3,0x0004003d,0x0000002a, + 0x000007a4,0x0000069d,0x0003003e,0x000006c1,0x000000ec,0x0004003d,0x00000006,0x00000859, + 0x000006c1,0x00050041,0x00000007,0x0000085a,0x00000856,0x000000b5,0x0003003e,0x0000085a, + 0x00000859,0x0004003d,0x00000006,0x0000085b,0x000006c1,0x00050041,0x00000007,0x0000085c, + 0x00000856,0x000000b8,0x0003003e,0x0000085c,0x0000085b,0x0004003d,0x00000006,0x0000085d, + 0x000006c1,0x00050041,0x00000007,0x0000085e,0x00000856,0x000000cb,0x0003003e,0x0000085e, + 0x0000085d,0x0004003d,0x0000002a,0x0000085f,0x00000856,0x0003003e,0x00000857,0x0000085f, + 0x0004003d,0x0000002a,0x000007a5,0x00000857,0x0003003e,0x000006c2,0x000000eb,0x0004003d, + 0x00000006,0x00000863,0x000006c2,0x00050041,0x00000007,0x00000864,0x00000860,0x000000b5, + 0x0003003e,0x00000864,0x00000863,0x0004003d,0x00000006,0x00000865,0x000006c2,0x00050041, + 0x00000007,0x00000866,0x00000860,0x000000b8,0x0003003e,0x00000866,0x00000865,0x0004003d, + 0x00000006,0x00000867,0x000006c2,0x00050041,0x00000007,0x00000868,0x00000860,0x000000cb, + 0x0003003e,0x00000868,0x00000867,0x0004003d,0x0000002a,0x00000869,0x00000860,0x0003003e, + 0x00000861,0x00000869,0x0004003d,0x0000002a,0x000007a6,0x00000861,0x0008000c,0x0000002a, + 0x000007a7,0x00000001,0x0000002b,0x000007a4,0x000007a5,0x000007a6,0x0003003e,0x0000069d, + 0x000007a7,0x0004003d,0x0000002a,0x000007a8,0x0000069d,0x0003003e,0x000006c3,0x000007a8, + 0x0004003d,0x0000002a,0x000007a9,0x000006ad,0x0003003e,0x000006c4,0x000007a9,0x0004003d, + 0x0000002a,0x000007aa,0x000006ad,0x0003003e,0x000006c5,0x000007aa,0x0004003d,0x0000002a, + 0x00000875,0x000006c4,0x0003003e,0x0000086b,0x00000875,0x0004003d,0x0000002a,0x0000088d, + 0x0000086b,0x0007004f,0x00000012,0x0000088e,0x0000088d,0x0000088d,0x00000000,0x00000001, + 0x0003003e,0x0000088a,0x0000088e,0x00050041,0x00000007,0x00000895,0x0000088a,0x000000b5, + 0x0004003d,0x00000006,0x00000896,0x00000895,0x00050041,0x00000007,0x00000897,0x0000088a, + 0x000000b8,0x0004003d,0x00000006,0x00000898,0x00000897,0x0007000c,0x00000006,0x00000899, + 0x00000001,0x00000028,0x00000896,0x00000898,0x0003003e,0x00000893,0x00000899,0x0004003d, + 0x00000006,0x0000088f,0x00000893,0x00050041,0x00000007,0x00000890,0x0000086b,0x000000cb, + 0x0004003d,0x00000006,0x00000891,0x00000890,0x0007000c,0x00000006,0x00000892,0x00000001, + 0x00000028,0x0000088f,0x00000891,0x0003003e,0x0000088b,0x00000892,0x0004003d,0x00000006, + 0x00000876,0x0000088b,0x0004003d,0x0000002a,0x00000877,0x000006c4,0x0003003e,0x0000086c, + 0x00000877,0x0004003d,0x0000002a,0x0000089d,0x0000086c,0x0007004f,0x00000012,0x0000089e, + 0x0000089d,0x0000089d,0x00000000,0x00000001,0x0003003e,0x0000089a,0x0000089e,0x00050041, + 0x00000007,0x000008a5,0x0000089a,0x000000b5,0x0004003d,0x00000006,0x000008a6,0x000008a5, + 0x00050041,0x00000007,0x000008a7,0x0000089a,0x000000b8,0x0004003d,0x00000006,0x000008a8, + 0x000008a7,0x0007000c,0x00000006,0x000008a9,0x00000001,0x00000025,0x000008a6,0x000008a8, + 0x0003003e,0x000008a3,0x000008a9,0x0004003d,0x00000006,0x0000089f,0x000008a3,0x00050041, + 0x00000007,0x000008a0,0x0000086c,0x000000cb,0x0004003d,0x00000006,0x000008a1,0x000008a0, + 0x0007000c,0x00000006,0x000008a2,0x00000001,0x00000025,0x0000089f,0x000008a1,0x0003003e, + 0x0000089b,0x000008a2,0x0004003d,0x00000006,0x00000878,0x0000089b,0x00050083,0x00000006, + 0x00000879,0x00000876,0x00000878,0x0003003e,0x0000086a,0x00000879,0x0004003d,0x0000002a, + 0x0000087a,0x000006c3,0x0003003e,0x0000086d,0x0000087a,0x0004003d,0x0000002a,0x000008ad, + 0x0000086d,0x0007004f,0x00000012,0x000008ae,0x000008ad,0x000008ad,0x00000000,0x00000001, + 0x0003003e,0x000008aa,0x000008ae,0x00050041,0x00000007,0x000008b5,0x000008aa,0x000000b5, + 0x0004003d,0x00000006,0x000008b6,0x000008b5,0x00050041,0x00000007,0x000008b7,0x000008aa, + 0x000000b8,0x0004003d,0x00000006,0x000008b8,0x000008b7,0x0007000c,0x00000006,0x000008b9, + 0x00000001,0x00000025,0x000008b6,0x000008b8,0x0003003e,0x000008b3,0x000008b9,0x0004003d, + 0x00000006,0x000008af,0x000008b3,0x00050041,0x00000007,0x000008b0,0x0000086d,0x000000cb, + 0x0004003d,0x00000006,0x000008b1,0x000008b0,0x0007000c,0x00000006,0x000008b2,0x00000001, + 0x00000025,0x000008af,0x000008b1,0x0003003e,0x000008ab,0x000008b2,0x0004003d,0x00000006, + 0x0000087b,0x000008ab,0x0004003d,0x0000002a,0x0000087c,0x000006c3,0x00060050,0x0000002a, + 0x0000087d,0x0000087b,0x0000087b,0x0000087b,0x00050083,0x0000002a,0x0000087e,0x0000087c, + 0x0000087d,0x0003003e,0x000006c3,0x0000087e,0x0004003d,0x0000002a,0x0000087f,0x000006c3, + 0x0003003e,0x0000086f,0x0000087f,0x0004003d,0x0000002a,0x000008bd,0x0000086f,0x0007004f, + 0x00000012,0x000008be,0x000008bd,0x000008bd,0x00000000,0x00000001,0x0003003e,0x000008ba, + 0x000008be,0x00050041,0x00000007,0x000008c5,0x000008ba,0x000000b5,0x0004003d,0x00000006, + 0x000008c6,0x000008c5,0x00050041,0x00000007,0x000008c7,0x000008ba,0x000000b8,0x0004003d, + 0x00000006,0x000008c8,0x000008c7,0x0007000c,0x00000006,0x000008c9,0x00000001,0x00000028, + 0x000008c6,0x000008c8,0x0003003e,0x000008c3,0x000008c9,0x0004003d,0x00000006,0x000008bf, + 0x000008c3,0x00050041,0x00000007,0x000008c0,0x0000086f,0x000000cb,0x0004003d,0x00000006, + 0x000008c1,0x000008c0,0x0007000c,0x00000006,0x000008c2,0x00000001,0x00000028,0x000008bf, + 0x000008c1,0x0003003e,0x000008bb,0x000008c2,0x0004003d,0x00000006,0x00000880,0x000008bb, + 0x0003003e,0x0000086e,0x00000880,0x0004003d,0x00000006,0x00000881,0x0000086a,0x0004003d, + 0x00000006,0x00000882,0x0000086e,0x0007000c,0x00000006,0x00000883,0x00000001,0x00000028, + 0x0000017d,0x00000882,0x00050088,0x00000006,0x00000884,0x00000881,0x00000883,0x0003003e, + 0x00000870,0x00000884,0x0004003d,0x0000002a,0x00000885,0x000006c3,0x0004003d,0x00000006, + 0x00000886,0x00000870,0x0005008e,0x0000002a,0x00000887,0x00000885,0x00000886,0x0003003e, + 0x00000871,0x00000887,0x0004003d,0x0000002a,0x00000888,0x000006c5,0x0003003e,0x00000872, + 0x00000888,0x0004003d,0x0000002a,0x000008da,0x00000872,0x0003003e,0x000008cb,0x000008da, + 0x0004003d,0x0000002a,0x00000900,0x000008cb,0x0003003e,0x000008fb,0x00000161,0x0003003e, + 0x000008fc,0x00000162,0x0003003e,0x000008fd,0x00000163,0x0004003d,0x00000006,0x00000906, + 0x000008fb,0x00050041,0x00000007,0x00000907,0x00000903,0x000000b5,0x0003003e,0x00000907, + 0x00000906,0x0004003d,0x00000006,0x00000908,0x000008fc,0x00050041,0x00000007,0x00000909, + 0x00000903,0x000000b8,0x0003003e,0x00000909,0x00000908,0x0004003d,0x00000006,0x0000090a, + 0x000008fd,0x00050041,0x00000007,0x0000090b,0x00000903,0x000000cb,0x0003003e,0x0000090b, + 0x0000090a,0x0004003d,0x0000002a,0x0000090c,0x00000903,0x0003003e,0x00000904,0x0000090c, + 0x0004003d,0x0000002a,0x00000901,0x00000904,0x00050094,0x00000006,0x00000902,0x00000900, + 0x00000901,0x0003003e,0x000008fe,0x00000902,0x0004003d,0x00000006,0x000008db,0x000008fe, + 0x0003003e,0x000008ca,0x000008db,0x0004003d,0x0000002a,0x000008dc,0x00000871,0x0004003d, + 0x0000002a,0x000008dd,0x00000871,0x0003003e,0x000008cd,0x000008dd,0x0004003d,0x0000002a, + 0x00000912,0x000008cd,0x0003003e,0x0000090d,0x00000161,0x0003003e,0x0000090e,0x00000162, + 0x0003003e,0x0000090f,0x00000163,0x0004003d,0x00000006,0x00000918,0x0000090d,0x00050041, + 0x00000007,0x00000919,0x00000915,0x000000b5,0x0003003e,0x00000919,0x00000918,0x0004003d, + 0x00000006,0x0000091a,0x0000090e,0x00050041,0x00000007,0x0000091b,0x00000915,0x000000b8, + 0x0003003e,0x0000091b,0x0000091a,0x0004003d,0x00000006,0x0000091c,0x0000090f,0x00050041, + 0x00000007,0x0000091d,0x00000915,0x000000cb,0x0003003e,0x0000091d,0x0000091c,0x0004003d, + 0x0000002a,0x0000091e,0x00000915,0x0003003e,0x00000916,0x0000091e,0x0004003d,0x0000002a, + 0x00000913,0x00000916,0x00050094,0x00000006,0x00000914,0x00000912,0x00000913,0x0003003e, + 0x00000910,0x00000914,0x0004003d,0x00000006,0x000008de,0x00000910,0x00060050,0x0000002a, + 0x000008df,0x000008de,0x000008de,0x000008de,0x00050083,0x0000002a,0x000008e0,0x000008dc, + 0x000008df,0x0003003e,0x000008cc,0x000008e0,0x0004003d,0x00000006,0x000008e1,0x000008ca, + 0x00050083,0x00000006,0x000008e2,0x000000eb,0x000008e1,0x0004003d,0x00000006,0x000008e3, + 0x000008ca,0x0003003e,0x000008cf,0x000008e3,0x0003003e,0x000008d0,0x000008e2,0x0004003d, + 0x00000006,0x00000922,0x000008cf,0x00050041,0x00000007,0x00000923,0x0000091f,0x000000b5, + 0x0003003e,0x00000923,0x00000922,0x0004003d,0x00000006,0x00000924,0x000008d0,0x00050041, + 0x00000007,0x00000925,0x0000091f,0x000000b8,0x0003003e,0x00000925,0x00000924,0x0004003d, + 0x00000012,0x00000926,0x0000091f,0x0003003e,0x00000920,0x00000926,0x0004003d,0x00000012, + 0x000008e4,0x00000920,0x0003003e,0x000008d1,0x0000017d,0x0004003d,0x00000006,0x0000092a, + 0x000008d1,0x00050041,0x00000007,0x0000092b,0x00000927,0x000000b5,0x0003003e,0x0000092b, + 0x0000092a,0x0004003d,0x00000006,0x0000092c,0x000008d1,0x00050041,0x00000007,0x0000092d, + 0x00000927,0x000000b8,0x0003003e,0x0000092d,0x0000092c,0x0004003d,0x00000012,0x0000092e, + 0x00000927,0x0003003e,0x00000928,0x0000092e,0x0004003d,0x00000012,0x000008e5,0x00000928, + 0x0004003d,0x0000002a,0x000008e6,0x000008cc,0x0003003e,0x000008d2,0x000008e6,0x0004003d, + 0x0000002a,0x00000932,0x000008d2,0x0007004f,0x00000012,0x00000933,0x00000932,0x00000932, + 0x00000000,0x00000001,0x0003003e,0x0000092f,0x00000933,0x00050041,0x00000007,0x0000093a, + 0x0000092f,0x000000b5,0x0004003d,0x00000006,0x0000093b,0x0000093a,0x00050041,0x00000007, + 0x0000093c,0x0000092f,0x000000b8,0x0004003d,0x00000006,0x0000093d,0x0000093c,0x0007000c, + 0x00000006,0x0000093e,0x00000001,0x00000025,0x0000093b,0x0000093d,0x0003003e,0x00000938, + 0x0000093e,0x0004003d,0x00000006,0x00000934,0x00000938,0x00050041,0x00000007,0x00000935, + 0x000008d2,0x000000cb,0x0004003d,0x00000006,0x00000936,0x00000935,0x0007000c,0x00000006, + 0x00000937,0x00000001,0x00000025,0x00000934,0x00000936,0x0003003e,0x00000930,0x00000937, + 0x0004003d,0x00000006,0x000008e7,0x00000930,0x0004007f,0x00000006,0x000008e8,0x000008e7, + 0x0004003d,0x0000002a,0x000008e9,0x000008cc,0x0003003e,0x000008d3,0x000008e9,0x0004003d, + 0x0000002a,0x00000942,0x000008d3,0x0007004f,0x00000012,0x00000943,0x00000942,0x00000942, + 0x00000000,0x00000001,0x0003003e,0x0000093f,0x00000943,0x00050041,0x00000007,0x0000094a, + 0x0000093f,0x000000b5,0x0004003d,0x00000006,0x0000094b,0x0000094a,0x00050041,0x00000007, + 0x0000094c,0x0000093f,0x000000b8,0x0004003d,0x00000006,0x0000094d,0x0000094c,0x0007000c, + 0x00000006,0x0000094e,0x00000001,0x00000028,0x0000094b,0x0000094d,0x0003003e,0x00000948, + 0x0000094e,0x0004003d,0x00000006,0x00000944,0x00000948,0x00050041,0x00000007,0x00000945, + 0x000008d3,0x000000cb,0x0004003d,0x00000006,0x00000946,0x00000945,0x0007000c,0x00000006, + 0x00000947,0x00000001,0x00000028,0x00000944,0x00000946,0x0003003e,0x00000940,0x00000947, + 0x0004003d,0x00000006,0x000008ea,0x00000940,0x0003003e,0x000008d4,0x000008e8,0x0003003e, + 0x000008d5,0x000008ea,0x0004003d,0x00000006,0x00000952,0x000008d4,0x00050041,0x00000007, + 0x00000953,0x0000094f,0x000000b5,0x0003003e,0x00000953,0x00000952,0x0004003d,0x00000006, + 0x00000954,0x000008d5,0x00050041,0x00000007,0x00000955,0x0000094f,0x000000b8,0x0003003e, + 0x00000955,0x00000954,0x0004003d,0x00000012,0x00000956,0x0000094f,0x0003003e,0x00000950, + 0x00000956,0x0004003d,0x00000012,0x000008eb,0x00000950,0x0007000c,0x00000012,0x000008ec, + 0x00000001,0x00000028,0x000008e5,0x000008eb,0x00050088,0x00000012,0x000008ed,0x000008e4, + 0x000008ec,0x0003003e,0x000008ce,0x000008ed,0x0003003e,0x000008d7,0x000000eb,0x0004003d, + 0x00000006,0x00000959,0x000008d7,0x0003003e,0x00000957,0x00000959,0x0004003d,0x00000006, + 0x000008ee,0x00000957,0x00050041,0x00000007,0x000008ef,0x000008ce,0x000000b5,0x0004003d, + 0x00000006,0x000008f0,0x000008ef,0x00050041,0x00000007,0x000008f1,0x000008ce,0x000000b8, + 0x0004003d,0x00000006,0x000008f2,0x000008f1,0x0007000c,0x00000006,0x000008f3,0x00000001, + 0x00000025,0x000008f0,0x000008f2,0x0007000c,0x00000006,0x000008f4,0x00000001,0x00000025, + 0x000008ee,0x000008f3,0x0003003e,0x000008d6,0x000008f4,0x0004003d,0x0000002a,0x000008f5, + 0x000008cc,0x0004003d,0x00000006,0x000008f6,0x000008d6,0x0005008e,0x0000002a,0x000008f7, + 0x000008f5,0x000008f6,0x0004003d,0x00000006,0x000008f8,0x000008ca,0x00060050,0x0000002a, + 0x000008f9,0x000008f8,0x000008f8,0x000008f8,0x00050081,0x0000002a,0x000008fa,0x000008f7, + 0x000008f9,0x0003003e,0x000008d8,0x000008fa,0x0004003d,0x0000002a,0x00000889,0x000008d8, + 0x0003003e,0x00000873,0x00000889,0x0004003d,0x0000002a,0x000007ab,0x00000873,0x0003003e, + 0x000006af,0x000007ab,0x000200f9,0x000007ac,0x000200f8,0x000007ac,0x000200f9,0x000007cc, + 0x000200f8,0x000007ad,0x000300f7,0x000007b7,0x00000000,0x000400fa,0x000002be,0x000007ae, + 0x000007b7,0x000200f8,0x000007ae,0x0004003d,0x0000002a,0x000007af,0x0000069d,0x0003003e, + 0x000006c6,0x000000ec,0x0004003d,0x00000006,0x0000095d,0x000006c6,0x00050041,0x00000007, + 0x0000095e,0x0000095a,0x000000b5,0x0003003e,0x0000095e,0x0000095d,0x0004003d,0x00000006, + 0x0000095f,0x000006c6,0x00050041,0x00000007,0x00000960,0x0000095a,0x000000b8,0x0003003e, + 0x00000960,0x0000095f,0x0004003d,0x00000006,0x00000961,0x000006c6,0x00050041,0x00000007, + 0x00000962,0x0000095a,0x000000cb,0x0003003e,0x00000962,0x00000961,0x0004003d,0x0000002a, + 0x00000963,0x0000095a,0x0003003e,0x0000095b,0x00000963,0x0004003d,0x0000002a,0x000007b0, + 0x0000095b,0x0003003e,0x000006c7,0x000000eb,0x0004003d,0x00000006,0x00000967,0x000006c7, + 0x00050041,0x00000007,0x00000968,0x00000964,0x000000b5,0x0003003e,0x00000968,0x00000967, + 0x0004003d,0x00000006,0x00000969,0x000006c7,0x00050041,0x00000007,0x0000096a,0x00000964, + 0x000000b8,0x0003003e,0x0000096a,0x00000969,0x0004003d,0x00000006,0x0000096b,0x000006c7, + 0x00050041,0x00000007,0x0000096c,0x00000964,0x000000cb,0x0003003e,0x0000096c,0x0000096b, + 0x0004003d,0x0000002a,0x0000096d,0x00000964,0x0003003e,0x00000965,0x0000096d,0x0004003d, + 0x0000002a,0x000007b1,0x00000965,0x0008000c,0x0000002a,0x000007b2,0x00000001,0x0000002b, + 0x000007af,0x000007b0,0x000007b1,0x0003003e,0x0000069d,0x000007b2,0x0004003d,0x0000002a, + 0x000007b3,0x000006ad,0x0003003e,0x000006c8,0x000007b3,0x0004003d,0x0000002a,0x000007b4, + 0x0000069d,0x0003003e,0x000006c9,0x000007b4,0x0004003d,0x0000002a,0x000007b5,0x000006ad, + 0x0003003e,0x000006ca,0x000007b5,0x0004003d,0x0000002a,0x00000979,0x000006c9,0x0003003e, + 0x0000096f,0x00000979,0x0004003d,0x0000002a,0x00000991,0x0000096f,0x0007004f,0x00000012, + 0x00000992,0x00000991,0x00000991,0x00000000,0x00000001,0x0003003e,0x0000098e,0x00000992, + 0x00050041,0x00000007,0x00000999,0x0000098e,0x000000b5,0x0004003d,0x00000006,0x0000099a, + 0x00000999,0x00050041,0x00000007,0x0000099b,0x0000098e,0x000000b8,0x0004003d,0x00000006, + 0x0000099c,0x0000099b,0x0007000c,0x00000006,0x0000099d,0x00000001,0x00000028,0x0000099a, + 0x0000099c,0x0003003e,0x00000997,0x0000099d,0x0004003d,0x00000006,0x00000993,0x00000997, + 0x00050041,0x00000007,0x00000994,0x0000096f,0x000000cb,0x0004003d,0x00000006,0x00000995, + 0x00000994,0x0007000c,0x00000006,0x00000996,0x00000001,0x00000028,0x00000993,0x00000995, + 0x0003003e,0x0000098f,0x00000996,0x0004003d,0x00000006,0x0000097a,0x0000098f,0x0004003d, + 0x0000002a,0x0000097b,0x000006c9,0x0003003e,0x00000970,0x0000097b,0x0004003d,0x0000002a, + 0x000009a1,0x00000970,0x0007004f,0x00000012,0x000009a2,0x000009a1,0x000009a1,0x00000000, + 0x00000001,0x0003003e,0x0000099e,0x000009a2,0x00050041,0x00000007,0x000009a9,0x0000099e, + 0x000000b5,0x0004003d,0x00000006,0x000009aa,0x000009a9,0x00050041,0x00000007,0x000009ab, + 0x0000099e,0x000000b8,0x0004003d,0x00000006,0x000009ac,0x000009ab,0x0007000c,0x00000006, + 0x000009ad,0x00000001,0x00000025,0x000009aa,0x000009ac,0x0003003e,0x000009a7,0x000009ad, + 0x0004003d,0x00000006,0x000009a3,0x000009a7,0x00050041,0x00000007,0x000009a4,0x00000970, + 0x000000cb,0x0004003d,0x00000006,0x000009a5,0x000009a4,0x0007000c,0x00000006,0x000009a6, + 0x00000001,0x00000025,0x000009a3,0x000009a5,0x0003003e,0x0000099f,0x000009a6,0x0004003d, + 0x00000006,0x0000097c,0x0000099f,0x00050083,0x00000006,0x0000097d,0x0000097a,0x0000097c, + 0x0003003e,0x0000096e,0x0000097d,0x0004003d,0x0000002a,0x0000097e,0x000006c8,0x0003003e, + 0x00000971,0x0000097e,0x0004003d,0x0000002a,0x000009b1,0x00000971,0x0007004f,0x00000012, + 0x000009b2,0x000009b1,0x000009b1,0x00000000,0x00000001,0x0003003e,0x000009ae,0x000009b2, + 0x00050041,0x00000007,0x000009b9,0x000009ae,0x000000b5,0x0004003d,0x00000006,0x000009ba, + 0x000009b9,0x00050041,0x00000007,0x000009bb,0x000009ae,0x000000b8,0x0004003d,0x00000006, + 0x000009bc,0x000009bb,0x0007000c,0x00000006,0x000009bd,0x00000001,0x00000025,0x000009ba, + 0x000009bc,0x0003003e,0x000009b7,0x000009bd,0x0004003d,0x00000006,0x000009b3,0x000009b7, + 0x00050041,0x00000007,0x000009b4,0x00000971,0x000000cb,0x0004003d,0x00000006,0x000009b5, + 0x000009b4,0x0007000c,0x00000006,0x000009b6,0x00000001,0x00000025,0x000009b3,0x000009b5, + 0x0003003e,0x000009af,0x000009b6,0x0004003d,0x00000006,0x0000097f,0x000009af,0x0004003d, + 0x0000002a,0x00000980,0x000006c8,0x00060050,0x0000002a,0x00000981,0x0000097f,0x0000097f, + 0x0000097f,0x00050083,0x0000002a,0x00000982,0x00000980,0x00000981,0x0003003e,0x000006c8, + 0x00000982,0x0004003d,0x0000002a,0x00000983,0x000006c8,0x0003003e,0x00000973,0x00000983, + 0x0004003d,0x0000002a,0x000009c1,0x00000973,0x0007004f,0x00000012,0x000009c2,0x000009c1, + 0x000009c1,0x00000000,0x00000001,0x0003003e,0x000009be,0x000009c2,0x00050041,0x00000007, + 0x000009c9,0x000009be,0x000000b5,0x0004003d,0x00000006,0x000009ca,0x000009c9,0x00050041, + 0x00000007,0x000009cb,0x000009be,0x000000b8,0x0004003d,0x00000006,0x000009cc,0x000009cb, + 0x0007000c,0x00000006,0x000009cd,0x00000001,0x00000028,0x000009ca,0x000009cc,0x0003003e, + 0x000009c7,0x000009cd,0x0004003d,0x00000006,0x000009c3,0x000009c7,0x00050041,0x00000007, + 0x000009c4,0x00000973,0x000000cb,0x0004003d,0x00000006,0x000009c5,0x000009c4,0x0007000c, + 0x00000006,0x000009c6,0x00000001,0x00000028,0x000009c3,0x000009c5,0x0003003e,0x000009bf, + 0x000009c6,0x0004003d,0x00000006,0x00000984,0x000009bf,0x0003003e,0x00000972,0x00000984, + 0x0004003d,0x00000006,0x00000985,0x0000096e,0x0004003d,0x00000006,0x00000986,0x00000972, + 0x0007000c,0x00000006,0x00000987,0x00000001,0x00000028,0x0000017d,0x00000986,0x00050088, + 0x00000006,0x00000988,0x00000985,0x00000987,0x0003003e,0x00000974,0x00000988,0x0004003d, + 0x0000002a,0x00000989,0x000006c8,0x0004003d,0x00000006,0x0000098a,0x00000974,0x0005008e, + 0x0000002a,0x0000098b,0x00000989,0x0000098a,0x0003003e,0x00000975,0x0000098b,0x0004003d, + 0x0000002a,0x0000098c,0x000006ca,0x0003003e,0x00000976,0x0000098c,0x0004003d,0x0000002a, + 0x000009de,0x00000976,0x0003003e,0x000009cf,0x000009de,0x0004003d,0x0000002a,0x00000a04, + 0x000009cf,0x0003003e,0x000009ff,0x00000161,0x0003003e,0x00000a00,0x00000162,0x0003003e, + 0x00000a01,0x00000163,0x0004003d,0x00000006,0x00000a0a,0x000009ff,0x00050041,0x00000007, + 0x00000a0b,0x00000a07,0x000000b5,0x0003003e,0x00000a0b,0x00000a0a,0x0004003d,0x00000006, + 0x00000a0c,0x00000a00,0x00050041,0x00000007,0x00000a0d,0x00000a07,0x000000b8,0x0003003e, + 0x00000a0d,0x00000a0c,0x0004003d,0x00000006,0x00000a0e,0x00000a01,0x00050041,0x00000007, + 0x00000a0f,0x00000a07,0x000000cb,0x0003003e,0x00000a0f,0x00000a0e,0x0004003d,0x0000002a, + 0x00000a10,0x00000a07,0x0003003e,0x00000a08,0x00000a10,0x0004003d,0x0000002a,0x00000a05, + 0x00000a08,0x00050094,0x00000006,0x00000a06,0x00000a04,0x00000a05,0x0003003e,0x00000a02, + 0x00000a06,0x0004003d,0x00000006,0x000009df,0x00000a02,0x0003003e,0x000009ce,0x000009df, + 0x0004003d,0x0000002a,0x000009e0,0x00000975,0x0004003d,0x0000002a,0x000009e1,0x00000975, + 0x0003003e,0x000009d1,0x000009e1,0x0004003d,0x0000002a,0x00000a16,0x000009d1,0x0003003e, + 0x00000a11,0x00000161,0x0003003e,0x00000a12,0x00000162,0x0003003e,0x00000a13,0x00000163, + 0x0004003d,0x00000006,0x00000a1c,0x00000a11,0x00050041,0x00000007,0x00000a1d,0x00000a19, + 0x000000b5,0x0003003e,0x00000a1d,0x00000a1c,0x0004003d,0x00000006,0x00000a1e,0x00000a12, + 0x00050041,0x00000007,0x00000a1f,0x00000a19,0x000000b8,0x0003003e,0x00000a1f,0x00000a1e, + 0x0004003d,0x00000006,0x00000a20,0x00000a13,0x00050041,0x00000007,0x00000a21,0x00000a19, + 0x000000cb,0x0003003e,0x00000a21,0x00000a20,0x0004003d,0x0000002a,0x00000a22,0x00000a19, + 0x0003003e,0x00000a1a,0x00000a22,0x0004003d,0x0000002a,0x00000a17,0x00000a1a,0x00050094, + 0x00000006,0x00000a18,0x00000a16,0x00000a17,0x0003003e,0x00000a14,0x00000a18,0x0004003d, + 0x00000006,0x000009e2,0x00000a14,0x00060050,0x0000002a,0x000009e3,0x000009e2,0x000009e2, + 0x000009e2,0x00050083,0x0000002a,0x000009e4,0x000009e0,0x000009e3,0x0003003e,0x000009d0, + 0x000009e4,0x0004003d,0x00000006,0x000009e5,0x000009ce,0x00050083,0x00000006,0x000009e6, + 0x000000eb,0x000009e5,0x0004003d,0x00000006,0x000009e7,0x000009ce,0x0003003e,0x000009d3, + 0x000009e7,0x0003003e,0x000009d4,0x000009e6,0x0004003d,0x00000006,0x00000a26,0x000009d3, + 0x00050041,0x00000007,0x00000a27,0x00000a23,0x000000b5,0x0003003e,0x00000a27,0x00000a26, + 0x0004003d,0x00000006,0x00000a28,0x000009d4,0x00050041,0x00000007,0x00000a29,0x00000a23, + 0x000000b8,0x0003003e,0x00000a29,0x00000a28,0x0004003d,0x00000012,0x00000a2a,0x00000a23, + 0x0003003e,0x00000a24,0x00000a2a,0x0004003d,0x00000012,0x000009e8,0x00000a24,0x0003003e, + 0x000009d5,0x0000017d,0x0004003d,0x00000006,0x00000a2e,0x000009d5,0x00050041,0x00000007, + 0x00000a2f,0x00000a2b,0x000000b5,0x0003003e,0x00000a2f,0x00000a2e,0x0004003d,0x00000006, + 0x00000a30,0x000009d5,0x00050041,0x00000007,0x00000a31,0x00000a2b,0x000000b8,0x0003003e, + 0x00000a31,0x00000a30,0x0004003d,0x00000012,0x00000a32,0x00000a2b,0x0003003e,0x00000a2c, + 0x00000a32,0x0004003d,0x00000012,0x000009e9,0x00000a2c,0x0004003d,0x0000002a,0x000009ea, + 0x000009d0,0x0003003e,0x000009d6,0x000009ea,0x0004003d,0x0000002a,0x00000a36,0x000009d6, + 0x0007004f,0x00000012,0x00000a37,0x00000a36,0x00000a36,0x00000000,0x00000001,0x0003003e, + 0x00000a33,0x00000a37,0x00050041,0x00000007,0x00000a3e,0x00000a33,0x000000b5,0x0004003d, + 0x00000006,0x00000a3f,0x00000a3e,0x00050041,0x00000007,0x00000a40,0x00000a33,0x000000b8, + 0x0004003d,0x00000006,0x00000a41,0x00000a40,0x0007000c,0x00000006,0x00000a42,0x00000001, + 0x00000025,0x00000a3f,0x00000a41,0x0003003e,0x00000a3c,0x00000a42,0x0004003d,0x00000006, + 0x00000a38,0x00000a3c,0x00050041,0x00000007,0x00000a39,0x000009d6,0x000000cb,0x0004003d, + 0x00000006,0x00000a3a,0x00000a39,0x0007000c,0x00000006,0x00000a3b,0x00000001,0x00000025, + 0x00000a38,0x00000a3a,0x0003003e,0x00000a34,0x00000a3b,0x0004003d,0x00000006,0x000009eb, + 0x00000a34,0x0004007f,0x00000006,0x000009ec,0x000009eb,0x0004003d,0x0000002a,0x000009ed, + 0x000009d0,0x0003003e,0x000009d7,0x000009ed,0x0004003d,0x0000002a,0x00000a46,0x000009d7, + 0x0007004f,0x00000012,0x00000a47,0x00000a46,0x00000a46,0x00000000,0x00000001,0x0003003e, + 0x00000a43,0x00000a47,0x00050041,0x00000007,0x00000a4e,0x00000a43,0x000000b5,0x0004003d, + 0x00000006,0x00000a4f,0x00000a4e,0x00050041,0x00000007,0x00000a50,0x00000a43,0x000000b8, + 0x0004003d,0x00000006,0x00000a51,0x00000a50,0x0007000c,0x00000006,0x00000a52,0x00000001, + 0x00000028,0x00000a4f,0x00000a51,0x0003003e,0x00000a4c,0x00000a52,0x0004003d,0x00000006, + 0x00000a48,0x00000a4c,0x00050041,0x00000007,0x00000a49,0x000009d7,0x000000cb,0x0004003d, + 0x00000006,0x00000a4a,0x00000a49,0x0007000c,0x00000006,0x00000a4b,0x00000001,0x00000028, + 0x00000a48,0x00000a4a,0x0003003e,0x00000a44,0x00000a4b,0x0004003d,0x00000006,0x000009ee, + 0x00000a44,0x0003003e,0x000009d8,0x000009ec,0x0003003e,0x000009d9,0x000009ee,0x0004003d, + 0x00000006,0x00000a56,0x000009d8,0x00050041,0x00000007,0x00000a57,0x00000a53,0x000000b5, + 0x0003003e,0x00000a57,0x00000a56,0x0004003d,0x00000006,0x00000a58,0x000009d9,0x00050041, + 0x00000007,0x00000a59,0x00000a53,0x000000b8,0x0003003e,0x00000a59,0x00000a58,0x0004003d, + 0x00000012,0x00000a5a,0x00000a53,0x0003003e,0x00000a54,0x00000a5a,0x0004003d,0x00000012, + 0x000009ef,0x00000a54,0x0007000c,0x00000012,0x000009f0,0x00000001,0x00000028,0x000009e9, + 0x000009ef,0x00050088,0x00000012,0x000009f1,0x000009e8,0x000009f0,0x0003003e,0x000009d2, + 0x000009f1,0x0003003e,0x000009db,0x000000eb,0x0004003d,0x00000006,0x00000a5d,0x000009db, + 0x0003003e,0x00000a5b,0x00000a5d,0x0004003d,0x00000006,0x000009f2,0x00000a5b,0x00050041, + 0x00000007,0x000009f3,0x000009d2,0x000000b5,0x0004003d,0x00000006,0x000009f4,0x000009f3, + 0x00050041,0x00000007,0x000009f5,0x000009d2,0x000000b8,0x0004003d,0x00000006,0x000009f6, + 0x000009f5,0x0007000c,0x00000006,0x000009f7,0x00000001,0x00000025,0x000009f4,0x000009f6, + 0x0007000c,0x00000006,0x000009f8,0x00000001,0x00000025,0x000009f2,0x000009f7,0x0003003e, + 0x000009da,0x000009f8,0x0004003d,0x0000002a,0x000009f9,0x000009d0,0x0004003d,0x00000006, + 0x000009fa,0x000009da,0x0005008e,0x0000002a,0x000009fb,0x000009f9,0x000009fa,0x0004003d, + 0x00000006,0x000009fc,0x000009ce,0x00060050,0x0000002a,0x000009fd,0x000009fc,0x000009fc, + 0x000009fc,0x00050081,0x0000002a,0x000009fe,0x000009fb,0x000009fd,0x0003003e,0x000009dc, + 0x000009fe,0x0004003d,0x0000002a,0x0000098d,0x000009dc,0x0003003e,0x00000977,0x0000098d, + 0x0004003d,0x0000002a,0x000007b6,0x00000977,0x0003003e,0x000006af,0x000007b6,0x000200f9, + 0x000007b7,0x000200f8,0x000007b7,0x000200f9,0x000007cc,0x000200f8,0x000007b8,0x000300f7, + 0x000007c1,0x00000000,0x000400fa,0x000002be,0x000007b9,0x000007c1,0x000200f8,0x000007b9, + 0x0004003d,0x0000002a,0x000007ba,0x0000069d,0x0003003e,0x000006cb,0x000000ec,0x0004003d, + 0x00000006,0x00000a61,0x000006cb,0x00050041,0x00000007,0x00000a62,0x00000a5e,0x000000b5, + 0x0003003e,0x00000a62,0x00000a61,0x0004003d,0x00000006,0x00000a63,0x000006cb,0x00050041, + 0x00000007,0x00000a64,0x00000a5e,0x000000b8,0x0003003e,0x00000a64,0x00000a63,0x0004003d, + 0x00000006,0x00000a65,0x000006cb,0x00050041,0x00000007,0x00000a66,0x00000a5e,0x000000cb, + 0x0003003e,0x00000a66,0x00000a65,0x0004003d,0x0000002a,0x00000a67,0x00000a5e,0x0003003e, + 0x00000a5f,0x00000a67,0x0004003d,0x0000002a,0x000007bb,0x00000a5f,0x0003003e,0x000006cc, + 0x000000eb,0x0004003d,0x00000006,0x00000a6b,0x000006cc,0x00050041,0x00000007,0x00000a6c, + 0x00000a68,0x000000b5,0x0003003e,0x00000a6c,0x00000a6b,0x0004003d,0x00000006,0x00000a6d, + 0x000006cc,0x00050041,0x00000007,0x00000a6e,0x00000a68,0x000000b8,0x0003003e,0x00000a6e, + 0x00000a6d,0x0004003d,0x00000006,0x00000a6f,0x000006cc,0x00050041,0x00000007,0x00000a70, + 0x00000a68,0x000000cb,0x0003003e,0x00000a70,0x00000a6f,0x0004003d,0x0000002a,0x00000a71, + 0x00000a68,0x0003003e,0x00000a69,0x00000a71,0x0004003d,0x0000002a,0x000007bc,0x00000a69, + 0x0008000c,0x0000002a,0x000007bd,0x00000001,0x0000002b,0x000007ba,0x000007bb,0x000007bc, + 0x0003003e,0x0000069d,0x000007bd,0x0004003d,0x0000002a,0x000007be,0x0000069d,0x0003003e, + 0x000006cd,0x000007be,0x0004003d,0x0000002a,0x000007bf,0x000006ad,0x0003003e,0x000006ce, + 0x000007bf,0x0004003d,0x0000002a,0x00000a82,0x000006ce,0x0003003e,0x00000a73,0x00000a82, + 0x0004003d,0x0000002a,0x00000aa8,0x00000a73,0x0003003e,0x00000aa3,0x00000161,0x0003003e, + 0x00000aa4,0x00000162,0x0003003e,0x00000aa5,0x00000163,0x0004003d,0x00000006,0x00000aae, + 0x00000aa3,0x00050041,0x00000007,0x00000aaf,0x00000aab,0x000000b5,0x0003003e,0x00000aaf, + 0x00000aae,0x0004003d,0x00000006,0x00000ab0,0x00000aa4,0x00050041,0x00000007,0x00000ab1, + 0x00000aab,0x000000b8,0x0003003e,0x00000ab1,0x00000ab0,0x0004003d,0x00000006,0x00000ab2, + 0x00000aa5,0x00050041,0x00000007,0x00000ab3,0x00000aab,0x000000cb,0x0003003e,0x00000ab3, + 0x00000ab2,0x0004003d,0x0000002a,0x00000ab4,0x00000aab,0x0003003e,0x00000aac,0x00000ab4, + 0x0004003d,0x0000002a,0x00000aa9,0x00000aac,0x00050094,0x00000006,0x00000aaa,0x00000aa8, + 0x00000aa9,0x0003003e,0x00000aa6,0x00000aaa,0x0004003d,0x00000006,0x00000a83,0x00000aa6, + 0x0003003e,0x00000a72,0x00000a83,0x0004003d,0x0000002a,0x00000a84,0x000006cd,0x0004003d, + 0x0000002a,0x00000a85,0x000006cd,0x0003003e,0x00000a75,0x00000a85,0x0004003d,0x0000002a, + 0x00000aba,0x00000a75,0x0003003e,0x00000ab5,0x00000161,0x0003003e,0x00000ab6,0x00000162, + 0x0003003e,0x00000ab7,0x00000163,0x0004003d,0x00000006,0x00000ac0,0x00000ab5,0x00050041, + 0x00000007,0x00000ac1,0x00000abd,0x000000b5,0x0003003e,0x00000ac1,0x00000ac0,0x0004003d, + 0x00000006,0x00000ac2,0x00000ab6,0x00050041,0x00000007,0x00000ac3,0x00000abd,0x000000b8, + 0x0003003e,0x00000ac3,0x00000ac2,0x0004003d,0x00000006,0x00000ac4,0x00000ab7,0x00050041, + 0x00000007,0x00000ac5,0x00000abd,0x000000cb,0x0003003e,0x00000ac5,0x00000ac4,0x0004003d, + 0x0000002a,0x00000ac6,0x00000abd,0x0003003e,0x00000abe,0x00000ac6,0x0004003d,0x0000002a, + 0x00000abb,0x00000abe,0x00050094,0x00000006,0x00000abc,0x00000aba,0x00000abb,0x0003003e, + 0x00000ab8,0x00000abc,0x0004003d,0x00000006,0x00000a86,0x00000ab8,0x00060050,0x0000002a, + 0x00000a87,0x00000a86,0x00000a86,0x00000a86,0x00050083,0x0000002a,0x00000a88,0x00000a84, + 0x00000a87,0x0003003e,0x00000a74,0x00000a88,0x0004003d,0x00000006,0x00000a89,0x00000a72, + 0x00050083,0x00000006,0x00000a8a,0x000000eb,0x00000a89,0x0004003d,0x00000006,0x00000a8b, + 0x00000a72,0x0003003e,0x00000a77,0x00000a8b,0x0003003e,0x00000a78,0x00000a8a,0x0004003d, + 0x00000006,0x00000aca,0x00000a77,0x00050041,0x00000007,0x00000acb,0x00000ac7,0x000000b5, + 0x0003003e,0x00000acb,0x00000aca,0x0004003d,0x00000006,0x00000acc,0x00000a78,0x00050041, + 0x00000007,0x00000acd,0x00000ac7,0x000000b8,0x0003003e,0x00000acd,0x00000acc,0x0004003d, + 0x00000012,0x00000ace,0x00000ac7,0x0003003e,0x00000ac8,0x00000ace,0x0004003d,0x00000012, + 0x00000a8c,0x00000ac8,0x0003003e,0x00000a79,0x0000017d,0x0004003d,0x00000006,0x00000ad2, + 0x00000a79,0x00050041,0x00000007,0x00000ad3,0x00000acf,0x000000b5,0x0003003e,0x00000ad3, + 0x00000ad2,0x0004003d,0x00000006,0x00000ad4,0x00000a79,0x00050041,0x00000007,0x00000ad5, + 0x00000acf,0x000000b8,0x0003003e,0x00000ad5,0x00000ad4,0x0004003d,0x00000012,0x00000ad6, + 0x00000acf,0x0003003e,0x00000ad0,0x00000ad6,0x0004003d,0x00000012,0x00000a8d,0x00000ad0, + 0x0004003d,0x0000002a,0x00000a8e,0x00000a74,0x0003003e,0x00000a7a,0x00000a8e,0x0004003d, + 0x0000002a,0x00000ada,0x00000a7a,0x0007004f,0x00000012,0x00000adb,0x00000ada,0x00000ada, + 0x00000000,0x00000001,0x0003003e,0x00000ad7,0x00000adb,0x00050041,0x00000007,0x00000ae2, + 0x00000ad7,0x000000b5,0x0004003d,0x00000006,0x00000ae3,0x00000ae2,0x00050041,0x00000007, + 0x00000ae4,0x00000ad7,0x000000b8,0x0004003d,0x00000006,0x00000ae5,0x00000ae4,0x0007000c, + 0x00000006,0x00000ae6,0x00000001,0x00000025,0x00000ae3,0x00000ae5,0x0003003e,0x00000ae0, + 0x00000ae6,0x0004003d,0x00000006,0x00000adc,0x00000ae0,0x00050041,0x00000007,0x00000add, + 0x00000a7a,0x000000cb,0x0004003d,0x00000006,0x00000ade,0x00000add,0x0007000c,0x00000006, + 0x00000adf,0x00000001,0x00000025,0x00000adc,0x00000ade,0x0003003e,0x00000ad8,0x00000adf, + 0x0004003d,0x00000006,0x00000a8f,0x00000ad8,0x0004007f,0x00000006,0x00000a90,0x00000a8f, + 0x0004003d,0x0000002a,0x00000a91,0x00000a74,0x0003003e,0x00000a7b,0x00000a91,0x0004003d, + 0x0000002a,0x00000aea,0x00000a7b,0x0007004f,0x00000012,0x00000aeb,0x00000aea,0x00000aea, + 0x00000000,0x00000001,0x0003003e,0x00000ae7,0x00000aeb,0x00050041,0x00000007,0x00000af2, + 0x00000ae7,0x000000b5,0x0004003d,0x00000006,0x00000af3,0x00000af2,0x00050041,0x00000007, + 0x00000af4,0x00000ae7,0x000000b8,0x0004003d,0x00000006,0x00000af5,0x00000af4,0x0007000c, + 0x00000006,0x00000af6,0x00000001,0x00000028,0x00000af3,0x00000af5,0x0003003e,0x00000af0, + 0x00000af6,0x0004003d,0x00000006,0x00000aec,0x00000af0,0x00050041,0x00000007,0x00000aed, + 0x00000a7b,0x000000cb,0x0004003d,0x00000006,0x00000aee,0x00000aed,0x0007000c,0x00000006, + 0x00000aef,0x00000001,0x00000028,0x00000aec,0x00000aee,0x0003003e,0x00000ae8,0x00000aef, + 0x0004003d,0x00000006,0x00000a92,0x00000ae8,0x0003003e,0x00000a7c,0x00000a90,0x0003003e, + 0x00000a7d,0x00000a92,0x0004003d,0x00000006,0x00000afa,0x00000a7c,0x00050041,0x00000007, + 0x00000afb,0x00000af7,0x000000b5,0x0003003e,0x00000afb,0x00000afa,0x0004003d,0x00000006, + 0x00000afc,0x00000a7d,0x00050041,0x00000007,0x00000afd,0x00000af7,0x000000b8,0x0003003e, + 0x00000afd,0x00000afc,0x0004003d,0x00000012,0x00000afe,0x00000af7,0x0003003e,0x00000af8, + 0x00000afe,0x0004003d,0x00000012,0x00000a93,0x00000af8,0x0007000c,0x00000012,0x00000a94, + 0x00000001,0x00000028,0x00000a8d,0x00000a93,0x00050088,0x00000012,0x00000a95,0x00000a8c, + 0x00000a94,0x0003003e,0x00000a76,0x00000a95,0x0003003e,0x00000a7f,0x000000eb,0x0004003d, + 0x00000006,0x00000b01,0x00000a7f,0x0003003e,0x00000aff,0x00000b01,0x0004003d,0x00000006, + 0x00000a96,0x00000aff,0x00050041,0x00000007,0x00000a97,0x00000a76,0x000000b5,0x0004003d, + 0x00000006,0x00000a98,0x00000a97,0x00050041,0x00000007,0x00000a99,0x00000a76,0x000000b8, + 0x0004003d,0x00000006,0x00000a9a,0x00000a99,0x0007000c,0x00000006,0x00000a9b,0x00000001, + 0x00000025,0x00000a98,0x00000a9a,0x0007000c,0x00000006,0x00000a9c,0x00000001,0x00000025, + 0x00000a96,0x00000a9b,0x0003003e,0x00000a7e,0x00000a9c,0x0004003d,0x0000002a,0x00000a9d, + 0x00000a74,0x0004003d,0x00000006,0x00000a9e,0x00000a7e,0x0005008e,0x0000002a,0x00000a9f, + 0x00000a9d,0x00000a9e,0x0004003d,0x00000006,0x00000aa0,0x00000a72,0x00060050,0x0000002a, + 0x00000aa1,0x00000aa0,0x00000aa0,0x00000aa0,0x00050081,0x0000002a,0x00000aa2,0x00000a9f, + 0x00000aa1,0x0003003e,0x00000a80,0x00000aa2,0x0004003d,0x0000002a,0x000007c0,0x00000a80, + 0x0003003e,0x000006af,0x000007c0,0x000200f9,0x000007c1,0x000200f8,0x000007c1,0x000200f9, + 0x000007cc,0x000200f8,0x000007c2,0x000300f7,0x000007cb,0x00000000,0x000400fa,0x000002be, + 0x000007c3,0x000007cb,0x000200f8,0x000007c3,0x0004003d,0x0000002a,0x000007c4,0x0000069d, + 0x0003003e,0x000006cf,0x000000ec,0x0004003d,0x00000006,0x00000b05,0x000006cf,0x00050041, + 0x00000007,0x00000b06,0x00000b02,0x000000b5,0x0003003e,0x00000b06,0x00000b05,0x0004003d, + 0x00000006,0x00000b07,0x000006cf,0x00050041,0x00000007,0x00000b08,0x00000b02,0x000000b8, + 0x0003003e,0x00000b08,0x00000b07,0x0004003d,0x00000006,0x00000b09,0x000006cf,0x00050041, + 0x00000007,0x00000b0a,0x00000b02,0x000000cb,0x0003003e,0x00000b0a,0x00000b09,0x0004003d, + 0x0000002a,0x00000b0b,0x00000b02,0x0003003e,0x00000b03,0x00000b0b,0x0004003d,0x0000002a, + 0x000007c5,0x00000b03,0x0003003e,0x000006d0,0x000000eb,0x0004003d,0x00000006,0x00000b0f, + 0x000006d0,0x00050041,0x00000007,0x00000b10,0x00000b0c,0x000000b5,0x0003003e,0x00000b10, + 0x00000b0f,0x0004003d,0x00000006,0x00000b11,0x000006d0,0x00050041,0x00000007,0x00000b12, + 0x00000b0c,0x000000b8,0x0003003e,0x00000b12,0x00000b11,0x0004003d,0x00000006,0x00000b13, + 0x000006d0,0x00050041,0x00000007,0x00000b14,0x00000b0c,0x000000cb,0x0003003e,0x00000b14, + 0x00000b13,0x0004003d,0x0000002a,0x00000b15,0x00000b0c,0x0003003e,0x00000b0d,0x00000b15, + 0x0004003d,0x0000002a,0x000007c6,0x00000b0d,0x0008000c,0x0000002a,0x000007c7,0x00000001, + 0x0000002b,0x000007c4,0x000007c5,0x000007c6,0x0003003e,0x0000069d,0x000007c7,0x0004003d, + 0x0000002a,0x000007c8,0x000006ad,0x0003003e,0x000006d1,0x000007c8,0x0004003d,0x0000002a, + 0x000007c9,0x0000069d,0x0003003e,0x000006d2,0x000007c9,0x0004003d,0x0000002a,0x00000b26, + 0x000006d2,0x0003003e,0x00000b17,0x00000b26,0x0004003d,0x0000002a,0x00000b4c,0x00000b17, + 0x0003003e,0x00000b47,0x00000161,0x0003003e,0x00000b48,0x00000162,0x0003003e,0x00000b49, + 0x00000163,0x0004003d,0x00000006,0x00000b52,0x00000b47,0x00050041,0x00000007,0x00000b53, + 0x00000b4f,0x000000b5,0x0003003e,0x00000b53,0x00000b52,0x0004003d,0x00000006,0x00000b54, + 0x00000b48,0x00050041,0x00000007,0x00000b55,0x00000b4f,0x000000b8,0x0003003e,0x00000b55, + 0x00000b54,0x0004003d,0x00000006,0x00000b56,0x00000b49,0x00050041,0x00000007,0x00000b57, + 0x00000b4f,0x000000cb,0x0003003e,0x00000b57,0x00000b56,0x0004003d,0x0000002a,0x00000b58, + 0x00000b4f,0x0003003e,0x00000b50,0x00000b58,0x0004003d,0x0000002a,0x00000b4d,0x00000b50, + 0x00050094,0x00000006,0x00000b4e,0x00000b4c,0x00000b4d,0x0003003e,0x00000b4a,0x00000b4e, + 0x0004003d,0x00000006,0x00000b27,0x00000b4a,0x0003003e,0x00000b16,0x00000b27,0x0004003d, + 0x0000002a,0x00000b28,0x000006d1,0x0004003d,0x0000002a,0x00000b29,0x000006d1,0x0003003e, + 0x00000b19,0x00000b29,0x0004003d,0x0000002a,0x00000b5e,0x00000b19,0x0003003e,0x00000b59, + 0x00000161,0x0003003e,0x00000b5a,0x00000162,0x0003003e,0x00000b5b,0x00000163,0x0004003d, + 0x00000006,0x00000b64,0x00000b59,0x00050041,0x00000007,0x00000b65,0x00000b61,0x000000b5, + 0x0003003e,0x00000b65,0x00000b64,0x0004003d,0x00000006,0x00000b66,0x00000b5a,0x00050041, + 0x00000007,0x00000b67,0x00000b61,0x000000b8,0x0003003e,0x00000b67,0x00000b66,0x0004003d, + 0x00000006,0x00000b68,0x00000b5b,0x00050041,0x00000007,0x00000b69,0x00000b61,0x000000cb, + 0x0003003e,0x00000b69,0x00000b68,0x0004003d,0x0000002a,0x00000b6a,0x00000b61,0x0003003e, + 0x00000b62,0x00000b6a,0x0004003d,0x0000002a,0x00000b5f,0x00000b62,0x00050094,0x00000006, + 0x00000b60,0x00000b5e,0x00000b5f,0x0003003e,0x00000b5c,0x00000b60,0x0004003d,0x00000006, + 0x00000b2a,0x00000b5c,0x00060050,0x0000002a,0x00000b2b,0x00000b2a,0x00000b2a,0x00000b2a, + 0x00050083,0x0000002a,0x00000b2c,0x00000b28,0x00000b2b,0x0003003e,0x00000b18,0x00000b2c, + 0x0004003d,0x00000006,0x00000b2d,0x00000b16,0x00050083,0x00000006,0x00000b2e,0x000000eb, + 0x00000b2d,0x0004003d,0x00000006,0x00000b2f,0x00000b16,0x0003003e,0x00000b1b,0x00000b2f, + 0x0003003e,0x00000b1c,0x00000b2e,0x0004003d,0x00000006,0x00000b6e,0x00000b1b,0x00050041, + 0x00000007,0x00000b6f,0x00000b6b,0x000000b5,0x0003003e,0x00000b6f,0x00000b6e,0x0004003d, + 0x00000006,0x00000b70,0x00000b1c,0x00050041,0x00000007,0x00000b71,0x00000b6b,0x000000b8, + 0x0003003e,0x00000b71,0x00000b70,0x0004003d,0x00000012,0x00000b72,0x00000b6b,0x0003003e, + 0x00000b6c,0x00000b72,0x0004003d,0x00000012,0x00000b30,0x00000b6c,0x0003003e,0x00000b1d, + 0x0000017d,0x0004003d,0x00000006,0x00000b76,0x00000b1d,0x00050041,0x00000007,0x00000b77, + 0x00000b73,0x000000b5,0x0003003e,0x00000b77,0x00000b76,0x0004003d,0x00000006,0x00000b78, + 0x00000b1d,0x00050041,0x00000007,0x00000b79,0x00000b73,0x000000b8,0x0003003e,0x00000b79, + 0x00000b78,0x0004003d,0x00000012,0x00000b7a,0x00000b73,0x0003003e,0x00000b74,0x00000b7a, + 0x0004003d,0x00000012,0x00000b31,0x00000b74,0x0004003d,0x0000002a,0x00000b32,0x00000b18, + 0x0003003e,0x00000b1e,0x00000b32,0x0004003d,0x0000002a,0x00000b7e,0x00000b1e,0x0007004f, + 0x00000012,0x00000b7f,0x00000b7e,0x00000b7e,0x00000000,0x00000001,0x0003003e,0x00000b7b, + 0x00000b7f,0x00050041,0x00000007,0x00000b86,0x00000b7b,0x000000b5,0x0004003d,0x00000006, + 0x00000b87,0x00000b86,0x00050041,0x00000007,0x00000b88,0x00000b7b,0x000000b8,0x0004003d, + 0x00000006,0x00000b89,0x00000b88,0x0007000c,0x00000006,0x00000b8a,0x00000001,0x00000025, + 0x00000b87,0x00000b89,0x0003003e,0x00000b84,0x00000b8a,0x0004003d,0x00000006,0x00000b80, + 0x00000b84,0x00050041,0x00000007,0x00000b81,0x00000b1e,0x000000cb,0x0004003d,0x00000006, + 0x00000b82,0x00000b81,0x0007000c,0x00000006,0x00000b83,0x00000001,0x00000025,0x00000b80, + 0x00000b82,0x0003003e,0x00000b7c,0x00000b83,0x0004003d,0x00000006,0x00000b33,0x00000b7c, + 0x0004007f,0x00000006,0x00000b34,0x00000b33,0x0004003d,0x0000002a,0x00000b35,0x00000b18, + 0x0003003e,0x00000b1f,0x00000b35,0x0004003d,0x0000002a,0x00000b8e,0x00000b1f,0x0007004f, + 0x00000012,0x00000b8f,0x00000b8e,0x00000b8e,0x00000000,0x00000001,0x0003003e,0x00000b8b, + 0x00000b8f,0x00050041,0x00000007,0x00000b96,0x00000b8b,0x000000b5,0x0004003d,0x00000006, + 0x00000b97,0x00000b96,0x00050041,0x00000007,0x00000b98,0x00000b8b,0x000000b8,0x0004003d, + 0x00000006,0x00000b99,0x00000b98,0x0007000c,0x00000006,0x00000b9a,0x00000001,0x00000028, + 0x00000b97,0x00000b99,0x0003003e,0x00000b94,0x00000b9a,0x0004003d,0x00000006,0x00000b90, + 0x00000b94,0x00050041,0x00000007,0x00000b91,0x00000b1f,0x000000cb,0x0004003d,0x00000006, + 0x00000b92,0x00000b91,0x0007000c,0x00000006,0x00000b93,0x00000001,0x00000028,0x00000b90, + 0x00000b92,0x0003003e,0x00000b8c,0x00000b93,0x0004003d,0x00000006,0x00000b36,0x00000b8c, + 0x0003003e,0x00000b20,0x00000b34,0x0003003e,0x00000b21,0x00000b36,0x0004003d,0x00000006, + 0x00000b9e,0x00000b20,0x00050041,0x00000007,0x00000b9f,0x00000b9b,0x000000b5,0x0003003e, + 0x00000b9f,0x00000b9e,0x0004003d,0x00000006,0x00000ba0,0x00000b21,0x00050041,0x00000007, + 0x00000ba1,0x00000b9b,0x000000b8,0x0003003e,0x00000ba1,0x00000ba0,0x0004003d,0x00000012, + 0x00000ba2,0x00000b9b,0x0003003e,0x00000b9c,0x00000ba2,0x0004003d,0x00000012,0x00000b37, + 0x00000b9c,0x0007000c,0x00000012,0x00000b38,0x00000001,0x00000028,0x00000b31,0x00000b37, + 0x00050088,0x00000012,0x00000b39,0x00000b30,0x00000b38,0x0003003e,0x00000b1a,0x00000b39, + 0x0003003e,0x00000b23,0x000000eb,0x0004003d,0x00000006,0x00000ba5,0x00000b23,0x0003003e, + 0x00000ba3,0x00000ba5,0x0004003d,0x00000006,0x00000b3a,0x00000ba3,0x00050041,0x00000007, + 0x00000b3b,0x00000b1a,0x000000b5,0x0004003d,0x00000006,0x00000b3c,0x00000b3b,0x00050041, + 0x00000007,0x00000b3d,0x00000b1a,0x000000b8,0x0004003d,0x00000006,0x00000b3e,0x00000b3d, + 0x0007000c,0x00000006,0x00000b3f,0x00000001,0x00000025,0x00000b3c,0x00000b3e,0x0007000c, + 0x00000006,0x00000b40,0x00000001,0x00000025,0x00000b3a,0x00000b3f,0x0003003e,0x00000b22, + 0x00000b40,0x0004003d,0x0000002a,0x00000b41,0x00000b18,0x0004003d,0x00000006,0x00000b42, + 0x00000b22,0x0005008e,0x0000002a,0x00000b43,0x00000b41,0x00000b42,0x0004003d,0x00000006, + 0x00000b44,0x00000b16,0x00060050,0x0000002a,0x00000b45,0x00000b44,0x00000b44,0x00000b44, + 0x00050081,0x0000002a,0x00000b46,0x00000b43,0x00000b45,0x0003003e,0x00000b24,0x00000b46, + 0x0004003d,0x0000002a,0x000007ca,0x00000b24,0x0003003e,0x000006af,0x000007ca,0x000200f9, + 0x000007cb,0x000200f8,0x000007cb,0x000200f9,0x000007cc,0x000200f8,0x000007cc,0x0004003d, + 0x0000002a,0x000007cd,0x000006af,0x0003003e,0x000006d3,0x000007cd,0x0004003d,0x0000002a, + 0x000006a6,0x000006d3,0x0003003e,0x0000069c,0x000006a6,0x0004003d,0x0000002a,0x000006a7, + 0x00000574,0x0004003d,0x0000002a,0x000006a8,0x0000069c,0x00050041,0x00000007,0x000006a9, + 0x00000575,0x000000e2,0x0004003d,0x00000006,0x000006aa,0x000006a9,0x0003003e,0x000006a0, + 0x000006aa,0x0004003d,0x00000006,0x00000ba9,0x000006a0,0x00050041,0x00000007,0x00000baa, + 0x00000ba6,0x000000b5,0x0003003e,0x00000baa,0x00000ba9,0x0004003d,0x00000006,0x00000bab, + 0x000006a0,0x00050041,0x00000007,0x00000bac,0x00000ba6,0x000000b8,0x0003003e,0x00000bac, + 0x00000bab,0x0004003d,0x00000006,0x00000bad,0x000006a0,0x00050041,0x00000007,0x00000bae, + 0x00000ba6,0x000000cb,0x0003003e,0x00000bae,0x00000bad,0x0004003d,0x0000002a,0x00000baf, + 0x00000ba6,0x0003003e,0x00000ba7,0x00000baf,0x0004003d,0x0000002a,0x000006ab,0x00000ba7, + 0x0008000c,0x0000002a,0x000006ac,0x00000001,0x0000002e,0x000006a7,0x000006a8,0x000006ab, + 0x0003003e,0x000006a1,0x000006ac,0x0004003d,0x0000002a,0x00000638,0x000006a1,0x00050041, + 0x00000007,0x00000639,0x0000048d,0x000000b5,0x00050051,0x00000006,0x0000063a,0x00000638, + 0x00000000,0x0003003e,0x00000639,0x0000063a,0x00050041,0x00000007,0x0000063b,0x0000048d, + 0x000000b8,0x00050051,0x00000006,0x0000063c,0x00000638,0x00000001,0x0003003e,0x0000063b, + 0x0000063c,0x00050041,0x00000007,0x0000063d,0x0000048d,0x000000cb,0x00050051,0x00000006, + 0x0000063e,0x00000638,0x00000002,0x0003003e,0x0000063d,0x0000063e,0x000200f9,0x0000063f, + 0x000200f8,0x0000063f,0x0004003d,0x00000006,0x00000641,0x0000061e,0x0004003d,0x0000000c, + 0x00000642,0x0000048d,0x0008004f,0x0000002a,0x00000643,0x00000642,0x00000642,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x0000002a,0x00000644,0x00000643,0x00000641,0x00050041, + 0x00000007,0x00000645,0x0000048d,0x000000b5,0x00050051,0x00000006,0x00000646,0x00000644, + 0x00000000,0x0003003e,0x00000645,0x00000646,0x00050041,0x00000007,0x00000647,0x0000048d, + 0x000000b8,0x00050051,0x00000006,0x00000648,0x00000644,0x00000001,0x0003003e,0x00000647, + 0x00000648,0x00050041,0x00000007,0x00000649,0x0000048d,0x000000cb,0x00050051,0x00000006, + 0x0000064a,0x00000644,0x00000002,0x0003003e,0x00000649,0x0000064a,0x0004003d,0x0000000c, + 0x00000493,0x0000048d,0x0003003e,0x00000488,0x00000493,0x0004003d,0x0000000c,0x00000494, + 0x0000048e,0x0003003e,0x00000485,0x00000494,0x000300f7,0x00000496,0x00000000,0x000400fa, + 0x00000360,0x00000495,0x00000496,0x000200f8,0x00000495,0x00050041,0x0000049b,0x0000049c, + 0x00000499,0x000000b8,0x0004003d,0x00000018,0x0000049d,0x0000049c,0x000500ab,0x000000fa, + 0x0000049e,0x0000049d,0x000000b5,0x000200f9,0x00000496,0x000200f8,0x00000496,0x000700f5, + 0x000000fa,0x0000049f,0x00000360,0x0000063f,0x0000049e,0x00000495,0x000300f7,0x000004a1, + 0x00000000,0x000400fa,0x0000049f,0x000004a0,0x000004a1,0x000200f8,0x000004a0,0x00050041, + 0x00000007,0x000004a3,0x00000485,0x000000e2,0x0004003d,0x00000006,0x000004a4,0x000004a3, + 0x000500b7,0x000000fa,0x000004a5,0x000004a4,0x000000ec,0x000300f7,0x000004a8,0x00000000, + 0x000400fa,0x000004a5,0x000004a7,0x000004aa,0x000200f8,0x000004a7,0x0004003d,0x0000000c, + 0x000004a9,0x00000485,0x0003003e,0x000004a6,0x000004a9,0x000200f9,0x000004a8,0x000200f8, + 0x000004aa,0x0004003d,0x0000036c,0x000004ab,0x0000036e,0x00050062,0x0000000c,0x000004ac, + 0x000004ab,0x00000370,0x0003003e,0x000004a6,0x000004ac,0x000200f9,0x000004a8,0x000200f8, + 0x000004a8,0x0004003d,0x0000000c,0x000004ad,0x000004a6,0x0003003e,0x000004a2,0x000004ad, + 0x00050041,0x0000049b,0x000004af,0x00000499,0x000000b8,0x0004003d,0x00000018,0x000004b0, + 0x000004af,0x0003003e,0x000004ae,0x000004b0,0x0004003d,0x0000000c,0x000004b2,0x000004a2, + 0x0003003e,0x000004b1,0x000004b2,0x0004003d,0x00000006,0x000004b4,0x0000045e,0x0003003e, + 0x000004b3,0x000004b4,0x0004003d,0x0000000c,0x00000bb2,0x000004b1,0x0007004f,0x00000012, + 0x00000bb3,0x00000bb2,0x00000bb2,0x00000000,0x00000001,0x0004003d,0x00000018,0x00000bb4, + 0x000004ae,0x0006000c,0x0000000c,0x00000bb5,0x00000001,0x00000040,0x00000bb4,0x0007004f, + 0x00000012,0x00000bb6,0x00000bb5,0x00000bb5,0x00000000,0x00000001,0x00050083,0x00000012, + 0x00000bb7,0x00000bb3,0x00000bb6,0x0006000c,0x00000012,0x00000bb8,0x00000001,0x00000004, + 0x00000bb7,0x0003003e,0x00000bb0,0x00000324,0x0004003d,0x00000006,0x00000bc6,0x00000bb0, + 0x00050041,0x00000007,0x00000bc7,0x00000bc3,0x000000b5,0x0003003e,0x00000bc7,0x00000bc6, + 0x0004003d,0x00000006,0x00000bc8,0x00000bb0,0x00050041,0x00000007,0x00000bc9,0x00000bc3, + 0x000000b8,0x0003003e,0x00000bc9,0x00000bc8,0x0004003d,0x00000012,0x00000bca,0x00000bc3, + 0x0003003e,0x00000bc4,0x00000bca,0x0004003d,0x00000012,0x00000bb9,0x00000bc4,0x000500b8, + 0x00000327,0x00000bba,0x00000bb8,0x00000bb9,0x0004009b,0x000000fa,0x00000bbb,0x00000bba, + 0x000300f7,0x00000bc2,0x00000000,0x000400fa,0x00000bbb,0x00000bbc,0x00000bc1,0x000200f8, + 0x00000bbc,0x0004003d,0x00000006,0x00000bbd,0x000004b3,0x00050041,0x00000007,0x00000bbe, + 0x000004b1,0x000000cb,0x0004003d,0x00000006,0x00000bbf,0x00000bbe,0x0007000c,0x00000006, + 0x00000bc0,0x00000001,0x00000025,0x00000bbd,0x00000bbf,0x0003003e,0x000004b3,0x00000bc0, + 0x000200f9,0x00000bc2,0x000200f8,0x00000bc1,0x0003003e,0x000004b3,0x000000ec,0x000200f9, + 0x00000bc2,0x000200f8,0x00000bc2,0x0004003d,0x00000006,0x000004b6,0x000004b3,0x0003003e, + 0x0000045e,0x000004b6,0x000200f9,0x000004a1,0x000200f8,0x000004a1,0x000300f7,0x000004b8, + 0x00000000,0x000400fa,0x00000418,0x000004b7,0x000004b8,0x000200f8,0x000004b7,0x00050041, + 0x0000049b,0x000004ba,0x00000499,0x000000cb,0x0004003d,0x00000018,0x000004bb,0x000004ba, + 0x000500ab,0x000000fa,0x000004bc,0x000004bb,0x000000b5,0x000200f9,0x000004b8,0x000200f8, + 0x000004b8,0x000700f5,0x000000fa,0x000004bd,0x00000418,0x000004a1,0x000004bc,0x000004b7, + 0x000300f7,0x000004bf,0x00000000,0x000400fa,0x000004bd,0x000004be,0x000004bf,0x000200f8, + 0x000004be,0x0004003d,0x0000036c,0x000004c1,0x0000042e,0x00050062,0x0000000c,0x000004c2, + 0x000004c1,0x00000370,0x00050041,0x00000007,0x000004c3,0x00000488,0x000000e2,0x0004003d, + 0x00000006,0x000004c4,0x000004c3,0x00050083,0x00000006,0x000004c5,0x000000eb,0x000004c4, + 0x0005008e,0x0000000c,0x000004c6,0x000004c2,0x000004c5,0x0004003d,0x0000000c,0x000004c7, + 0x00000488,0x00050081,0x0000000c,0x000004c8,0x000004c6,0x000004c7,0x0003003e,0x000004c0, + 0x000004c8,0x0004003d,0x0000000c,0x000004ca,0x00000454,0x0003003e,0x000004c9,0x000004ca, + 0x0004003d,0x0000000c,0x00000bce,0x000004c9,0x0008004f,0x0000002a,0x00000bcf,0x00000bce, + 0x00000bce,0x00000000,0x00000001,0x00000002,0x00050041,0x00000007,0x00000bd0,0x000004c9, + 0x000000e2,0x0004003d,0x00000006,0x00000bd1,0x00000bd0,0x000500b7,0x000000fa,0x00000bd2, + 0x00000bd1,0x000000ec,0x000300f7,0x00000bd8,0x00000000,0x000400fa,0x00000bd2,0x00000bd3, + 0x00000bd7,0x000200f8,0x00000bd3,0x0004003d,0x00000006,0x00000bd5,0x00000bd0,0x00050088, + 0x00000006,0x00000bd6,0x000000eb,0x00000bd5,0x0003003e,0x00000bcb,0x00000bd6,0x000200f9, + 0x00000bd8,0x000200f8,0x00000bd7,0x0003003e,0x00000bcb,0x000000ec,0x000200f9,0x00000bd8, + 0x000200f8,0x00000bd8,0x0004003d,0x00000006,0x00000bd9,0x00000bcb,0x0005008e,0x0000002a, + 0x00000bda,0x00000bcf,0x00000bd9,0x0003003e,0x00000bcc,0x00000bda,0x0004003d,0x0000002a, + 0x000004cb,0x00000bcc,0x00050041,0x0000049b,0x000004cd,0x00000499,0x000000cb,0x0004003d, + 0x00000018,0x000004ce,0x000004cd,0x0003003e,0x000004cc,0x000004ce,0x0004003d,0x00000018, + 0x00000bde,0x000004cc,0x0003003e,0x00000bdb,0x00000bde,0x0004003d,0x00000018,0x00000bdf, + 0x00000bdb,0x0003003e,0x00000bdc,0x00000bdf,0x0004003d,0x00000018,0x000004cf,0x00000bdc, + 0x0003003e,0x000004d0,0x000004cb,0x0004003d,0x0000000c,0x000004d2,0x000004c0,0x0003003e, + 0x000004d1,0x000004d2,0x0003003e,0x000004d3,0x000004cf,0x0004003d,0x0000002a,0x00000be7, + 0x000004d0,0x0003003e,0x00000be1,0x00000be7,0x0004003d,0x0000000c,0x00000be8,0x000004d1, + 0x0003003e,0x00000be2,0x00000be8,0x0004003d,0x00000018,0x00000be9,0x000004d3,0x0003003e, + 0x00000be3,0x00000be9,0x0004003d,0x0000000c,0x00000c19,0x00000be2,0x0003003e,0x00000bf2, + 0x00000c19,0x0004003d,0x0000000c,0x00000d15,0x00000bf2,0x0008004f,0x0000002a,0x00000d16, + 0x00000d15,0x00000d15,0x00000000,0x00000001,0x00000002,0x00050041,0x00000007,0x00000d17, + 0x00000bf2,0x000000e2,0x0004003d,0x00000006,0x00000d18,0x00000d17,0x000500b7,0x000000fa, + 0x00000d19,0x00000d18,0x000000ec,0x000300f7,0x00000d1f,0x00000000,0x000400fa,0x00000d19, + 0x00000d1a,0x00000d1e,0x000200f8,0x00000d1a,0x0004003d,0x00000006,0x00000d1c,0x00000d17, + 0x00050088,0x00000006,0x00000d1d,0x000000eb,0x00000d1c,0x0003003e,0x00000d12,0x00000d1d, + 0x000200f9,0x00000d1f,0x000200f8,0x00000d1e,0x0003003e,0x00000d12,0x000000ec,0x000200f9, + 0x00000d1f,0x000200f8,0x00000d1f,0x0004003d,0x00000006,0x00000d20,0x00000d12,0x0005008e, + 0x0000002a,0x00000d21,0x00000d16,0x00000d20,0x0003003e,0x00000d13,0x00000d21,0x0004003d, + 0x0000002a,0x00000c1a,0x00000d13,0x0003003e,0x00000bf1,0x00000c1a,0x0004003d,0x00000018, + 0x00000c1b,0x00000be3,0x000300f7,0x00000d10,0x00000000,0x002100fb,0x00000c1b,0x00000d10, + 0x0000000b,0x00000c1c,0x00000001,0x00000c20,0x00000002,0x00000c28,0x00000003,0x00000c38, + 0x00000004,0x00000c3c,0x00000005,0x00000c40,0x00000006,0x00000c62,0x00000007,0x00000c8e, + 0x00000008,0x00000c9e,0x00000009,0x00000cd8,0x0000000a,0x00000cdd,0x0000000c,0x00000ce6, + 0x0000000d,0x00000cf1,0x0000000e,0x00000cfc,0x0000000f,0x00000d06,0x000200f8,0x00000c1c, + 0x0004003d,0x0000002a,0x00000c1d,0x00000be1,0x0004003d,0x0000002a,0x00000c1e,0x00000bf1, + 0x00050085,0x0000002a,0x00000c1f,0x00000c1d,0x00000c1e,0x0003003e,0x00000bf3,0x00000c1f, + 0x000200f9,0x00000d10,0x000200f8,0x00000c20,0x0004003d,0x0000002a,0x00000c21,0x00000be1, + 0x0004003d,0x0000002a,0x00000c22,0x00000bf1,0x00050081,0x0000002a,0x00000c23,0x00000c21, + 0x00000c22,0x0004003d,0x0000002a,0x00000c24,0x00000be1,0x0004003d,0x0000002a,0x00000c25, + 0x00000bf1,0x00050085,0x0000002a,0x00000c26,0x00000c24,0x00000c25,0x00050083,0x0000002a, + 0x00000c27,0x00000c23,0x00000c26,0x0003003e,0x00000bf3,0x00000c27,0x000200f9,0x00000d10, + 0x000200f8,0x00000c28,0x0004003d,0x0000002a,0x00000c29,0x00000be1,0x0004003d,0x0000002a, + 0x00000c2a,0x00000bf1,0x00050085,0x0000002a,0x00000c2b,0x00000c29,0x00000c2a,0x0003003e, + 0x00000bf4,0x00000c2b,0x0004003d,0x0000002a,0x00000c2c,0x00000bf4,0x0004003d,0x0000002a, + 0x00000c2d,0x00000be1,0x0004003d,0x0000002a,0x00000c2e,0x00000bf1,0x00050081,0x0000002a, + 0x00000c2f,0x00000c2d,0x00000c2e,0x0004003d,0x0000002a,0x00000c30,0x00000bf4,0x00050083, + 0x0000002a,0x00000c31,0x00000c2f,0x00000c30,0x00050083,0x0000002a,0x00000c32,0x00000c31, + 0x0000051f,0x0004003d,0x0000002a,0x00000c33,0x00000bf1,0x0003003e,0x00000bf5,0x000001ea, + 0x0004003d,0x00000006,0x00000d25,0x00000bf5,0x00050041,0x00000007,0x00000d26,0x00000d22, + 0x000000b5,0x0003003e,0x00000d26,0x00000d25,0x0004003d,0x00000006,0x00000d27,0x00000bf5, + 0x00050041,0x00000007,0x00000d28,0x00000d22,0x000000b8,0x0003003e,0x00000d28,0x00000d27, + 0x0004003d,0x00000006,0x00000d29,0x00000bf5,0x00050041,0x00000007,0x00000d2a,0x00000d22, + 0x000000cb,0x0003003e,0x00000d2a,0x00000d29,0x0004003d,0x0000002a,0x00000d2b,0x00000d22, + 0x0003003e,0x00000d23,0x00000d2b,0x0004003d,0x0000002a,0x00000c34,0x00000d23,0x000500ba, + 0x000001f0,0x00000c35,0x00000c33,0x00000c34,0x000600a9,0x0000002a,0x00000c36,0x00000c35, + 0x00000c32,0x00000c2c,0x0005008e,0x0000002a,0x00000c37,0x00000c36,0x000001e3,0x0003003e, + 0x00000bf3,0x00000c37,0x000200f9,0x00000d10,0x000200f8,0x00000c38,0x0004003d,0x0000002a, + 0x00000c39,0x00000be1,0x0004003d,0x0000002a,0x00000c3a,0x00000bf1,0x0007000c,0x0000002a, + 0x00000c3b,0x00000001,0x00000025,0x00000c39,0x00000c3a,0x0003003e,0x00000bf3,0x00000c3b, + 0x000200f9,0x00000d10,0x000200f8,0x00000c3c,0x0004003d,0x0000002a,0x00000c3d,0x00000be1, + 0x0004003d,0x0000002a,0x00000c3e,0x00000bf1,0x0007000c,0x0000002a,0x00000c3f,0x00000001, + 0x00000028,0x00000c3d,0x00000c3e,0x0003003e,0x00000bf3,0x00000c3f,0x000200f9,0x00000d10, + 0x000200f8,0x00000c40,0x0004003d,0x0000000c,0x00000c41,0x00000be2,0x0008004f,0x0000002a, + 0x00000c42,0x00000c41,0x00000c41,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000bf6, + 0x000000ec,0x0004003d,0x00000006,0x00000d2f,0x00000bf6,0x00050041,0x00000007,0x00000d30, + 0x00000d2c,0x000000b5,0x0003003e,0x00000d30,0x00000d2f,0x0004003d,0x00000006,0x00000d31, + 0x00000bf6,0x00050041,0x00000007,0x00000d32,0x00000d2c,0x000000b8,0x0003003e,0x00000d32, + 0x00000d31,0x0004003d,0x00000006,0x00000d33,0x00000bf6,0x00050041,0x00000007,0x00000d34, + 0x00000d2c,0x000000cb,0x0003003e,0x00000d34,0x00000d33,0x0004003d,0x0000002a,0x00000d35, + 0x00000d2c,0x0003003e,0x00000d2d,0x00000d35,0x0004003d,0x0000002a,0x00000c43,0x00000d2d, + 0x0004003d,0x0000000c,0x00000c44,0x00000be2,0x0008004f,0x0000002a,0x00000c45,0x00000c44, + 0x00000c44,0x00000003,0x00000003,0x00000003,0x0008000c,0x0000002a,0x00000c46,0x00000001, + 0x0000002b,0x00000c42,0x00000c43,0x00000c45,0x00050041,0x00000007,0x00000c47,0x00000be2, + 0x000000b5,0x00050051,0x00000006,0x00000c48,0x00000c46,0x00000000,0x0003003e,0x00000c47, + 0x00000c48,0x00050041,0x00000007,0x00000c49,0x00000be2,0x000000b8,0x00050051,0x00000006, + 0x00000c4a,0x00000c46,0x00000001,0x0003003e,0x00000c49,0x00000c4a,0x00050041,0x00000007, + 0x00000c4b,0x00000be2,0x000000cb,0x00050051,0x00000006,0x00000c4c,0x00000c46,0x00000002, + 0x0003003e,0x00000c4b,0x00000c4c,0x0004003d,0x0000002a,0x00000c4d,0x00000be1,0x00050083, + 0x0000002a,0x00000c4e,0x0000051e,0x00000c4d,0x0003003e,0x00000bf8,0x000000ec,0x0004003d, + 0x00000006,0x00000d39,0x00000bf8,0x00050041,0x00000007,0x00000d3a,0x00000d36,0x000000b5, + 0x0003003e,0x00000d3a,0x00000d39,0x0004003d,0x00000006,0x00000d3b,0x00000bf8,0x00050041, + 0x00000007,0x00000d3c,0x00000d36,0x000000b8,0x0003003e,0x00000d3c,0x00000d3b,0x0004003d, + 0x00000006,0x00000d3d,0x00000bf8,0x00050041,0x00000007,0x00000d3e,0x00000d36,0x000000cb, + 0x0003003e,0x00000d3e,0x00000d3d,0x0004003d,0x0000002a,0x00000d3f,0x00000d36,0x0003003e, + 0x00000d37,0x00000d3f,0x0004003d,0x0000002a,0x00000c4f,0x00000d37,0x0003003e,0x00000bf9, + 0x000000eb,0x0004003d,0x00000006,0x00000d43,0x00000bf9,0x00050041,0x00000007,0x00000d44, + 0x00000d40,0x000000b5,0x0003003e,0x00000d44,0x00000d43,0x0004003d,0x00000006,0x00000d45, + 0x00000bf9,0x00050041,0x00000007,0x00000d46,0x00000d40,0x000000b8,0x0003003e,0x00000d46, + 0x00000d45,0x0004003d,0x00000006,0x00000d47,0x00000bf9,0x00050041,0x00000007,0x00000d48, + 0x00000d40,0x000000cb,0x0003003e,0x00000d48,0x00000d47,0x0004003d,0x0000002a,0x00000d49, + 0x00000d40,0x0003003e,0x00000d41,0x00000d49,0x0004003d,0x0000002a,0x00000c50,0x00000d41, + 0x0008000c,0x0000002a,0x00000c51,0x00000001,0x0000002b,0x00000c4e,0x00000c4f,0x00000c50, + 0x00050041,0x00000007,0x00000c52,0x00000be2,0x000000e2,0x0004003d,0x00000006,0x00000c53, + 0x00000c52,0x0005008e,0x0000002a,0x00000c54,0x00000c51,0x00000c53,0x0003003e,0x00000bf7, + 0x00000c54,0x0003003e,0x00000bfa,0x000000eb,0x0004003d,0x00000006,0x00000d4d,0x00000bfa, + 0x00050041,0x00000007,0x00000d4e,0x00000d4a,0x000000b5,0x0003003e,0x00000d4e,0x00000d4d, + 0x0004003d,0x00000006,0x00000d4f,0x00000bfa,0x00050041,0x00000007,0x00000d50,0x00000d4a, + 0x000000b8,0x0003003e,0x00000d50,0x00000d4f,0x0004003d,0x00000006,0x00000d51,0x00000bfa, + 0x00050041,0x00000007,0x00000d52,0x00000d4a,0x000000cb,0x0003003e,0x00000d52,0x00000d51, + 0x0004003d,0x0000002a,0x00000d53,0x00000d4a,0x0003003e,0x00000d4b,0x00000d53,0x0004003d, + 0x0000002a,0x00000c55,0x00000d4b,0x0004003d,0x0000000c,0x00000c56,0x00000be2,0x0008004f, + 0x0000002a,0x00000c57,0x00000c56,0x00000c56,0x00000000,0x00000001,0x00000002,0x0004003d, + 0x0000002a,0x00000c58,0x00000bf7,0x00050088,0x0000002a,0x00000c59,0x00000c57,0x00000c58, + 0x0007000c,0x0000002a,0x00000c5a,0x00000001,0x00000025,0x00000c55,0x00000c59,0x0004003d, + 0x0000000c,0x00000c5b,0x00000be2,0x0008004f,0x0000002a,0x00000c5c,0x00000c5b,0x00000c5b, + 0x00000000,0x00000001,0x00000002,0x0006000c,0x0000002a,0x00000c5d,0x00000001,0x00000006, + 0x00000c5c,0x0004003d,0x0000002a,0x00000c5e,0x00000bf7,0x0003003e,0x00000bfb,0x000000ec, + 0x0004003d,0x00000006,0x00000d57,0x00000bfb,0x00050041,0x00000007,0x00000d58,0x00000d54, + 0x000000b5,0x0003003e,0x00000d58,0x00000d57,0x0004003d,0x00000006,0x00000d59,0x00000bfb, + 0x00050041,0x00000007,0x00000d5a,0x00000d54,0x000000b8,0x0003003e,0x00000d5a,0x00000d59, + 0x0004003d,0x00000006,0x00000d5b,0x00000bfb,0x00050041,0x00000007,0x00000d5c,0x00000d54, + 0x000000cb,0x0003003e,0x00000d5c,0x00000d5b,0x0004003d,0x0000002a,0x00000d5d,0x00000d54, + 0x0003003e,0x00000d55,0x00000d5d,0x0004003d,0x0000002a,0x00000c5f,0x00000d55,0x000500b4, + 0x000001f0,0x00000c60,0x00000c5e,0x00000c5f,0x000600a9,0x0000002a,0x00000c61,0x00000c60, + 0x00000c5d,0x00000c5a,0x0003003e,0x00000bf3,0x00000c61,0x000200f9,0x00000d10,0x000200f8, + 0x00000c62,0x0004003d,0x0000002a,0x00000c63,0x00000be1,0x0003003e,0x00000bfc,0x000000ec, + 0x0004003d,0x00000006,0x00000d61,0x00000bfc,0x00050041,0x00000007,0x00000d62,0x00000d5e, + 0x000000b5,0x0003003e,0x00000d62,0x00000d61,0x0004003d,0x00000006,0x00000d63,0x00000bfc, + 0x00050041,0x00000007,0x00000d64,0x00000d5e,0x000000b8,0x0003003e,0x00000d64,0x00000d63, + 0x0004003d,0x00000006,0x00000d65,0x00000bfc,0x00050041,0x00000007,0x00000d66,0x00000d5e, + 0x000000cb,0x0003003e,0x00000d66,0x00000d65,0x0004003d,0x0000002a,0x00000d67,0x00000d5e, + 0x0003003e,0x00000d5f,0x00000d67,0x0004003d,0x0000002a,0x00000c64,0x00000d5f,0x0003003e, + 0x00000bfd,0x000000eb,0x0004003d,0x00000006,0x00000d6b,0x00000bfd,0x00050041,0x00000007, + 0x00000d6c,0x00000d68,0x000000b5,0x0003003e,0x00000d6c,0x00000d6b,0x0004003d,0x00000006, + 0x00000d6d,0x00000bfd,0x00050041,0x00000007,0x00000d6e,0x00000d68,0x000000b8,0x0003003e, + 0x00000d6e,0x00000d6d,0x0004003d,0x00000006,0x00000d6f,0x00000bfd,0x00050041,0x00000007, + 0x00000d70,0x00000d68,0x000000cb,0x0003003e,0x00000d70,0x00000d6f,0x0004003d,0x0000002a, + 0x00000d71,0x00000d68,0x0003003e,0x00000d69,0x00000d71,0x0004003d,0x0000002a,0x00000c65, + 0x00000d69,0x0008000c,0x0000002a,0x00000c66,0x00000001,0x0000002b,0x00000c63,0x00000c64, + 0x00000c65,0x0003003e,0x00000be1,0x00000c66,0x0004003d,0x0000000c,0x00000c67,0x00000be2, + 0x0008004f,0x0000002a,0x00000c68,0x00000c67,0x00000c67,0x00000000,0x00000001,0x00000002, + 0x0003003e,0x00000bfe,0x000000ec,0x0004003d,0x00000006,0x00000d75,0x00000bfe,0x00050041, + 0x00000007,0x00000d76,0x00000d72,0x000000b5,0x0003003e,0x00000d76,0x00000d75,0x0004003d, + 0x00000006,0x00000d77,0x00000bfe,0x00050041,0x00000007,0x00000d78,0x00000d72,0x000000b8, + 0x0003003e,0x00000d78,0x00000d77,0x0004003d,0x00000006,0x00000d79,0x00000bfe,0x00050041, + 0x00000007,0x00000d7a,0x00000d72,0x000000cb,0x0003003e,0x00000d7a,0x00000d79,0x0004003d, + 0x0000002a,0x00000d7b,0x00000d72,0x0003003e,0x00000d73,0x00000d7b,0x0004003d,0x0000002a, + 0x00000c69,0x00000d73,0x0004003d,0x0000000c,0x00000c6a,0x00000be2,0x0008004f,0x0000002a, + 0x00000c6b,0x00000c6a,0x00000c6a,0x00000003,0x00000003,0x00000003,0x0008000c,0x0000002a, + 0x00000c6c,0x00000001,0x0000002b,0x00000c68,0x00000c69,0x00000c6b,0x00050041,0x00000007, + 0x00000c6d,0x00000be2,0x000000b5,0x00050051,0x00000006,0x00000c6e,0x00000c6c,0x00000000, + 0x0003003e,0x00000c6d,0x00000c6e,0x00050041,0x00000007,0x00000c6f,0x00000be2,0x000000b8, + 0x00050051,0x00000006,0x00000c70,0x00000c6c,0x00000001,0x0003003e,0x00000c6f,0x00000c70, + 0x00050041,0x00000007,0x00000c71,0x00000be2,0x000000cb,0x00050051,0x00000006,0x00000c72, + 0x00000c6c,0x00000002,0x0003003e,0x00000c71,0x00000c72,0x00050041,0x00000007,0x00000c73, + 0x00000be2,0x000000e2,0x0004003d,0x00000006,0x00000c74,0x00000c73,0x000500b4,0x000000fa, + 0x00000c75,0x00000c74,0x000000ec,0x000300f7,0x00000c78,0x00000000,0x000400fa,0x00000c75, + 0x00000c76,0x00000c78,0x000200f8,0x00000c76,0x0003003e,0x00000c73,0x000000eb,0x000200f9, + 0x00000c78,0x000200f8,0x00000c78,0x0004003d,0x00000006,0x00000c7a,0x00000c73,0x0004003d, + 0x0000000c,0x00000c7b,0x00000be2,0x0008004f,0x0000002a,0x00000c7c,0x00000c7b,0x00000c7b, + 0x00000000,0x00000001,0x00000002,0x00060050,0x0000002a,0x00000c7d,0x00000c7a,0x00000c7a, + 0x00000c7a,0x00050083,0x0000002a,0x00000c7e,0x00000c7d,0x00000c7c,0x0003003e,0x00000bff, + 0x00000c7e,0x0003003e,0x00000c00,0x000000eb,0x0004003d,0x00000006,0x00000d7f,0x00000c00, + 0x00050041,0x00000007,0x00000d80,0x00000d7c,0x000000b5,0x0003003e,0x00000d80,0x00000d7f, + 0x0004003d,0x00000006,0x00000d81,0x00000c00,0x00050041,0x00000007,0x00000d82,0x00000d7c, + 0x000000b8,0x0003003e,0x00000d82,0x00000d81,0x0004003d,0x00000006,0x00000d83,0x00000c00, + 0x00050041,0x00000007,0x00000d84,0x00000d7c,0x000000cb,0x0003003e,0x00000d84,0x00000d83, + 0x0004003d,0x0000002a,0x00000d85,0x00000d7c,0x0003003e,0x00000d7d,0x00000d85,0x0004003d, + 0x0000002a,0x00000c7f,0x00000d7d,0x0004003d,0x0000002a,0x00000c80,0x00000bff,0x0004003d, + 0x0000002a,0x00000c81,0x00000be1,0x0004003d,0x00000006,0x00000c83,0x00000c73,0x0005008e, + 0x0000002a,0x00000c84,0x00000c81,0x00000c83,0x00050088,0x0000002a,0x00000c85,0x00000c80, + 0x00000c84,0x0007000c,0x0000002a,0x00000c86,0x00000001,0x00000025,0x00000c7f,0x00000c85, + 0x0004003d,0x0000002a,0x00000c87,0x00000bff,0x0006000c,0x0000002a,0x00000c88,0x00000001, + 0x00000006,0x00000c87,0x0004003d,0x0000002a,0x00000c89,0x00000be1,0x0003003e,0x00000c01, + 0x000000ec,0x0004003d,0x00000006,0x00000d89,0x00000c01,0x00050041,0x00000007,0x00000d8a, + 0x00000d86,0x000000b5,0x0003003e,0x00000d8a,0x00000d89,0x0004003d,0x00000006,0x00000d8b, + 0x00000c01,0x00050041,0x00000007,0x00000d8c,0x00000d86,0x000000b8,0x0003003e,0x00000d8c, + 0x00000d8b,0x0004003d,0x00000006,0x00000d8d,0x00000c01,0x00050041,0x00000007,0x00000d8e, + 0x00000d86,0x000000cb,0x0003003e,0x00000d8e,0x00000d8d,0x0004003d,0x0000002a,0x00000d8f, + 0x00000d86,0x0003003e,0x00000d87,0x00000d8f,0x0004003d,0x0000002a,0x00000c8a,0x00000d87, + 0x000500b4,0x000001f0,0x00000c8b,0x00000c89,0x00000c8a,0x000600a9,0x0000002a,0x00000c8c, + 0x00000c8b,0x00000c88,0x00000c86,0x00050083,0x0000002a,0x00000c8d,0x0000051e,0x00000c8c, + 0x0003003e,0x00000bf3,0x00000c8d,0x000200f9,0x00000d10,0x000200f8,0x00000c8e,0x0004003d, + 0x0000002a,0x00000c8f,0x00000be1,0x0004003d,0x0000002a,0x00000c90,0x00000bf1,0x00050085, + 0x0000002a,0x00000c91,0x00000c8f,0x00000c90,0x0003003e,0x00000c02,0x00000c91,0x0004003d, + 0x0000002a,0x00000c92,0x00000c02,0x0004003d,0x0000002a,0x00000c93,0x00000be1,0x0004003d, + 0x0000002a,0x00000c94,0x00000bf1,0x00050081,0x0000002a,0x00000c95,0x00000c93,0x00000c94, + 0x0004003d,0x0000002a,0x00000c96,0x00000c02,0x00050083,0x0000002a,0x00000c97,0x00000c95, + 0x00000c96,0x00050083,0x0000002a,0x00000c98,0x00000c97,0x0000051f,0x0004003d,0x0000002a, + 0x00000c99,0x00000be1,0x0003003e,0x00000c03,0x000001ea,0x0004003d,0x00000006,0x00000d93, + 0x00000c03,0x00050041,0x00000007,0x00000d94,0x00000d90,0x000000b5,0x0003003e,0x00000d94, + 0x00000d93,0x0004003d,0x00000006,0x00000d95,0x00000c03,0x00050041,0x00000007,0x00000d96, + 0x00000d90,0x000000b8,0x0003003e,0x00000d96,0x00000d95,0x0004003d,0x00000006,0x00000d97, + 0x00000c03,0x00050041,0x00000007,0x00000d98,0x00000d90,0x000000cb,0x0003003e,0x00000d98, + 0x00000d97,0x0004003d,0x0000002a,0x00000d99,0x00000d90,0x0003003e,0x00000d91,0x00000d99, + 0x0004003d,0x0000002a,0x00000c9a,0x00000d91,0x000500ba,0x000001f0,0x00000c9b,0x00000c99, + 0x00000c9a,0x000600a9,0x0000002a,0x00000c9c,0x00000c9b,0x00000c98,0x00000c92,0x0005008e, + 0x0000002a,0x00000c9d,0x00000c9c,0x000001e3,0x0003003e,0x00000bf3,0x00000c9d,0x000200f9, + 0x00000d10,0x000200f8,0x00000c9e,0x0003003e,0x00000c04,0x0000026e,0x000200f9,0x00000c9f, + 0x000200f8,0x00000c9f,0x0004003d,0x00000088,0x00000ca1,0x00000c04,0x000500b1,0x000000fa, + 0x00000ca2,0x00000ca1,0x00000275,0x000400f6,0x00000cce,0x00000ccb,0x00000000,0x000400fa, + 0x00000ca2,0x00000ca3,0x00000cce,0x000200f8,0x00000ca3,0x0004003d,0x00000088,0x00000ca4, + 0x00000c04,0x00050041,0x00000007,0x00000ca5,0x00000be1,0x00000ca4,0x0004003d,0x00000006, + 0x00000ca6,0x00000ca5,0x000500bc,0x000000fa,0x00000ca7,0x00000ca6,0x000001ea,0x000300f7, + 0x00000cca,0x00000000,0x000400fa,0x00000ca7,0x00000ca8,0x00000caf,0x000200f8,0x00000ca8, + 0x0004003d,0x00000088,0x00000ca9,0x00000c04,0x0004003d,0x00000088,0x00000caa,0x00000c04, + 0x00050041,0x00000007,0x00000cab,0x00000bf1,0x00000caa,0x0004003d,0x00000006,0x00000cac, + 0x00000cab,0x00050083,0x00000006,0x00000cad,0x000000eb,0x00000cac,0x00050041,0x00000007, + 0x00000cae,0x00000bf3,0x00000ca9,0x0003003e,0x00000cae,0x00000cad,0x000200f9,0x00000cca, + 0x000200f8,0x00000caf,0x0004003d,0x00000088,0x00000cb0,0x00000c04,0x00050041,0x00000007, + 0x00000cb1,0x00000bf1,0x00000cb0,0x0004003d,0x00000006,0x00000cb2,0x00000cb1,0x000500bc, + 0x000000fa,0x00000cb3,0x00000cb2,0x00000287,0x000300f7,0x00000cc9,0x00000000,0x000400fa, + 0x00000cb3,0x00000cb4,0x00000cc1,0x000200f8,0x00000cb4,0x0004003d,0x00000088,0x00000cb5, + 0x00000c04,0x0004003d,0x00000088,0x00000cb6,0x00000c04,0x00050041,0x00000007,0x00000cb7, + 0x00000bf1,0x00000cb6,0x0004003d,0x00000006,0x00000cb8,0x00000cb7,0x00050085,0x00000006, + 0x00000cb9,0x0000028c,0x00000cb8,0x00050083,0x00000006,0x00000cba,0x00000cb9,0x00000291, + 0x0004003d,0x00000088,0x00000cbb,0x00000c04,0x00050041,0x00000007,0x00000cbc,0x00000bf1, + 0x00000cbb,0x0004003d,0x00000006,0x00000cbd,0x00000cbc,0x00050085,0x00000006,0x00000cbe, + 0x00000cba,0x00000cbd,0x00050081,0x00000006,0x00000cbf,0x00000cbe,0x00000297,0x00050041, + 0x00000007,0x00000cc0,0x00000bf3,0x00000cb5,0x0003003e,0x00000cc0,0x00000cbf,0x000200f9, + 0x00000cc9,0x000200f8,0x00000cc1,0x0004003d,0x00000088,0x00000cc2,0x00000c04,0x0004003d, + 0x00000088,0x00000cc3,0x00000c04,0x00050041,0x00000007,0x00000cc4,0x00000bf1,0x00000cc3, + 0x0004003d,0x00000006,0x00000cc5,0x00000cc4,0x0006000c,0x00000006,0x00000cc6,0x00000001, + 0x00000020,0x00000cc5,0x00050083,0x00000006,0x00000cc7,0x00000cc6,0x000000eb,0x00050041, + 0x00000007,0x00000cc8,0x00000bf3,0x00000cc2,0x0003003e,0x00000cc8,0x00000cc7,0x000200f9, + 0x00000cc9,0x000200f8,0x00000cc9,0x000200f9,0x00000cca,0x000200f8,0x00000cca,0x000200f9, + 0x00000ccb,0x000200f8,0x00000ccb,0x0004003d,0x00000088,0x00000ccc,0x00000c04,0x00050080, + 0x00000088,0x00000ccd,0x00000ccc,0x000002a3,0x0003003e,0x00000c04,0x00000ccd,0x000200f9, + 0x00000c9f,0x000200f8,0x00000cce,0x0004003d,0x0000002a,0x00000ccf,0x00000bf1,0x0004003d, + 0x0000002a,0x00000cd0,0x00000bf1,0x0004003d,0x0000002a,0x00000cd1,0x00000be1,0x0005008e, + 0x0000002a,0x00000cd2,0x00000cd1,0x000001e3,0x00050083,0x0000002a,0x00000cd3,0x00000cd2, + 0x0000051e,0x00050085,0x0000002a,0x00000cd4,0x00000cd0,0x00000cd3,0x0004003d,0x0000002a, + 0x00000cd5,0x00000bf3,0x00050085,0x0000002a,0x00000cd6,0x00000cd4,0x00000cd5,0x00050081, + 0x0000002a,0x00000cd7,0x00000ccf,0x00000cd6,0x0003003e,0x00000bf3,0x00000cd7,0x000200f9, + 0x00000d10,0x000200f8,0x00000cd8,0x0004003d,0x0000002a,0x00000cd9,0x00000bf1,0x0004003d, + 0x0000002a,0x00000cda,0x00000be1,0x00050083,0x0000002a,0x00000cdb,0x00000cd9,0x00000cda, + 0x0006000c,0x0000002a,0x00000cdc,0x00000001,0x00000004,0x00000cdb,0x0003003e,0x00000bf3, + 0x00000cdc,0x000200f9,0x00000d10,0x000200f8,0x00000cdd,0x0004003d,0x0000002a,0x00000cde, + 0x00000be1,0x0004003d,0x0000002a,0x00000cdf,0x00000bf1,0x00050081,0x0000002a,0x00000ce0, + 0x00000cde,0x00000cdf,0x0004003d,0x0000002a,0x00000ce1,0x00000be1,0x0005008e,0x0000002a, + 0x00000ce2,0x00000ce1,0x000001e3,0x0004003d,0x0000002a,0x00000ce3,0x00000bf1,0x00050085, + 0x0000002a,0x00000ce4,0x00000ce2,0x00000ce3,0x00050083,0x0000002a,0x00000ce5,0x00000ce0, + 0x00000ce4,0x0003003e,0x00000bf3,0x00000ce5,0x000200f9,0x00000d10,0x000200f8,0x00000ce6, + 0x000300f7,0x00000cf0,0x00000000,0x000400fa,0x000002be,0x00000ce7,0x00000cf0,0x000200f8, + 0x00000ce7,0x0004003d,0x0000002a,0x00000ce8,0x00000be1,0x0003003e,0x00000c05,0x000000ec, + 0x0004003d,0x00000006,0x00000d9d,0x00000c05,0x00050041,0x00000007,0x00000d9e,0x00000d9a, + 0x000000b5,0x0003003e,0x00000d9e,0x00000d9d,0x0004003d,0x00000006,0x00000d9f,0x00000c05, + 0x00050041,0x00000007,0x00000da0,0x00000d9a,0x000000b8,0x0003003e,0x00000da0,0x00000d9f, + 0x0004003d,0x00000006,0x00000da1,0x00000c05,0x00050041,0x00000007,0x00000da2,0x00000d9a, + 0x000000cb,0x0003003e,0x00000da2,0x00000da1,0x0004003d,0x0000002a,0x00000da3,0x00000d9a, + 0x0003003e,0x00000d9b,0x00000da3,0x0004003d,0x0000002a,0x00000ce9,0x00000d9b,0x0003003e, + 0x00000c06,0x000000eb,0x0004003d,0x00000006,0x00000da7,0x00000c06,0x00050041,0x00000007, + 0x00000da8,0x00000da4,0x000000b5,0x0003003e,0x00000da8,0x00000da7,0x0004003d,0x00000006, + 0x00000da9,0x00000c06,0x00050041,0x00000007,0x00000daa,0x00000da4,0x000000b8,0x0003003e, + 0x00000daa,0x00000da9,0x0004003d,0x00000006,0x00000dab,0x00000c06,0x00050041,0x00000007, + 0x00000dac,0x00000da4,0x000000cb,0x0003003e,0x00000dac,0x00000dab,0x0004003d,0x0000002a, + 0x00000dad,0x00000da4,0x0003003e,0x00000da5,0x00000dad,0x0004003d,0x0000002a,0x00000cea, + 0x00000da5,0x0008000c,0x0000002a,0x00000ceb,0x00000001,0x0000002b,0x00000ce8,0x00000ce9, + 0x00000cea,0x0003003e,0x00000be1,0x00000ceb,0x0004003d,0x0000002a,0x00000cec,0x00000be1, + 0x0003003e,0x00000c07,0x00000cec,0x0004003d,0x0000002a,0x00000ced,0x00000bf1,0x0003003e, + 0x00000c08,0x00000ced,0x0004003d,0x0000002a,0x00000cee,0x00000bf1,0x0003003e,0x00000c09, + 0x00000cee,0x0004003d,0x0000002a,0x00000db9,0x00000c08,0x0003003e,0x00000daf,0x00000db9, + 0x0004003d,0x0000002a,0x00000dd1,0x00000daf,0x0007004f,0x00000012,0x00000dd2,0x00000dd1, + 0x00000dd1,0x00000000,0x00000001,0x0003003e,0x00000dce,0x00000dd2,0x00050041,0x00000007, + 0x00000dd9,0x00000dce,0x000000b5,0x0004003d,0x00000006,0x00000dda,0x00000dd9,0x00050041, + 0x00000007,0x00000ddb,0x00000dce,0x000000b8,0x0004003d,0x00000006,0x00000ddc,0x00000ddb, + 0x0007000c,0x00000006,0x00000ddd,0x00000001,0x00000028,0x00000dda,0x00000ddc,0x0003003e, + 0x00000dd7,0x00000ddd,0x0004003d,0x00000006,0x00000dd3,0x00000dd7,0x00050041,0x00000007, + 0x00000dd4,0x00000daf,0x000000cb,0x0004003d,0x00000006,0x00000dd5,0x00000dd4,0x0007000c, + 0x00000006,0x00000dd6,0x00000001,0x00000028,0x00000dd3,0x00000dd5,0x0003003e,0x00000dcf, + 0x00000dd6,0x0004003d,0x00000006,0x00000dba,0x00000dcf,0x0004003d,0x0000002a,0x00000dbb, + 0x00000c08,0x0003003e,0x00000db0,0x00000dbb,0x0004003d,0x0000002a,0x00000de1,0x00000db0, + 0x0007004f,0x00000012,0x00000de2,0x00000de1,0x00000de1,0x00000000,0x00000001,0x0003003e, + 0x00000dde,0x00000de2,0x00050041,0x00000007,0x00000de9,0x00000dde,0x000000b5,0x0004003d, + 0x00000006,0x00000dea,0x00000de9,0x00050041,0x00000007,0x00000deb,0x00000dde,0x000000b8, + 0x0004003d,0x00000006,0x00000dec,0x00000deb,0x0007000c,0x00000006,0x00000ded,0x00000001, + 0x00000025,0x00000dea,0x00000dec,0x0003003e,0x00000de7,0x00000ded,0x0004003d,0x00000006, + 0x00000de3,0x00000de7,0x00050041,0x00000007,0x00000de4,0x00000db0,0x000000cb,0x0004003d, + 0x00000006,0x00000de5,0x00000de4,0x0007000c,0x00000006,0x00000de6,0x00000001,0x00000025, + 0x00000de3,0x00000de5,0x0003003e,0x00000ddf,0x00000de6,0x0004003d,0x00000006,0x00000dbc, + 0x00000ddf,0x00050083,0x00000006,0x00000dbd,0x00000dba,0x00000dbc,0x0003003e,0x00000dae, + 0x00000dbd,0x0004003d,0x0000002a,0x00000dbe,0x00000c07,0x0003003e,0x00000db1,0x00000dbe, + 0x0004003d,0x0000002a,0x00000df1,0x00000db1,0x0007004f,0x00000012,0x00000df2,0x00000df1, + 0x00000df1,0x00000000,0x00000001,0x0003003e,0x00000dee,0x00000df2,0x00050041,0x00000007, + 0x00000df9,0x00000dee,0x000000b5,0x0004003d,0x00000006,0x00000dfa,0x00000df9,0x00050041, + 0x00000007,0x00000dfb,0x00000dee,0x000000b8,0x0004003d,0x00000006,0x00000dfc,0x00000dfb, + 0x0007000c,0x00000006,0x00000dfd,0x00000001,0x00000025,0x00000dfa,0x00000dfc,0x0003003e, + 0x00000df7,0x00000dfd,0x0004003d,0x00000006,0x00000df3,0x00000df7,0x00050041,0x00000007, + 0x00000df4,0x00000db1,0x000000cb,0x0004003d,0x00000006,0x00000df5,0x00000df4,0x0007000c, + 0x00000006,0x00000df6,0x00000001,0x00000025,0x00000df3,0x00000df5,0x0003003e,0x00000def, + 0x00000df6,0x0004003d,0x00000006,0x00000dbf,0x00000def,0x0004003d,0x0000002a,0x00000dc0, + 0x00000c07,0x00060050,0x0000002a,0x00000dc1,0x00000dbf,0x00000dbf,0x00000dbf,0x00050083, + 0x0000002a,0x00000dc2,0x00000dc0,0x00000dc1,0x0003003e,0x00000c07,0x00000dc2,0x0004003d, + 0x0000002a,0x00000dc3,0x00000c07,0x0003003e,0x00000db3,0x00000dc3,0x0004003d,0x0000002a, + 0x00000e01,0x00000db3,0x0007004f,0x00000012,0x00000e02,0x00000e01,0x00000e01,0x00000000, + 0x00000001,0x0003003e,0x00000dfe,0x00000e02,0x00050041,0x00000007,0x00000e09,0x00000dfe, + 0x000000b5,0x0004003d,0x00000006,0x00000e0a,0x00000e09,0x00050041,0x00000007,0x00000e0b, + 0x00000dfe,0x000000b8,0x0004003d,0x00000006,0x00000e0c,0x00000e0b,0x0007000c,0x00000006, + 0x00000e0d,0x00000001,0x00000028,0x00000e0a,0x00000e0c,0x0003003e,0x00000e07,0x00000e0d, + 0x0004003d,0x00000006,0x00000e03,0x00000e07,0x00050041,0x00000007,0x00000e04,0x00000db3, + 0x000000cb,0x0004003d,0x00000006,0x00000e05,0x00000e04,0x0007000c,0x00000006,0x00000e06, + 0x00000001,0x00000028,0x00000e03,0x00000e05,0x0003003e,0x00000dff,0x00000e06,0x0004003d, + 0x00000006,0x00000dc4,0x00000dff,0x0003003e,0x00000db2,0x00000dc4,0x0004003d,0x00000006, + 0x00000dc5,0x00000dae,0x0004003d,0x00000006,0x00000dc6,0x00000db2,0x0007000c,0x00000006, + 0x00000dc7,0x00000001,0x00000028,0x0000017d,0x00000dc6,0x00050088,0x00000006,0x00000dc8, + 0x00000dc5,0x00000dc7,0x0003003e,0x00000db4,0x00000dc8,0x0004003d,0x0000002a,0x00000dc9, + 0x00000c07,0x0004003d,0x00000006,0x00000dca,0x00000db4,0x0005008e,0x0000002a,0x00000dcb, + 0x00000dc9,0x00000dca,0x0003003e,0x00000db5,0x00000dcb,0x0004003d,0x0000002a,0x00000dcc, + 0x00000c09,0x0003003e,0x00000db6,0x00000dcc,0x0004003d,0x0000002a,0x00000e1e,0x00000db6, + 0x0003003e,0x00000e0f,0x00000e1e,0x0004003d,0x0000002a,0x00000e44,0x00000e0f,0x0003003e, + 0x00000e3f,0x00000161,0x0003003e,0x00000e40,0x00000162,0x0003003e,0x00000e41,0x00000163, + 0x0004003d,0x00000006,0x00000e4a,0x00000e3f,0x00050041,0x00000007,0x00000e4b,0x00000e47, + 0x000000b5,0x0003003e,0x00000e4b,0x00000e4a,0x0004003d,0x00000006,0x00000e4c,0x00000e40, + 0x00050041,0x00000007,0x00000e4d,0x00000e47,0x000000b8,0x0003003e,0x00000e4d,0x00000e4c, + 0x0004003d,0x00000006,0x00000e4e,0x00000e41,0x00050041,0x00000007,0x00000e4f,0x00000e47, + 0x000000cb,0x0003003e,0x00000e4f,0x00000e4e,0x0004003d,0x0000002a,0x00000e50,0x00000e47, + 0x0003003e,0x00000e48,0x00000e50,0x0004003d,0x0000002a,0x00000e45,0x00000e48,0x00050094, + 0x00000006,0x00000e46,0x00000e44,0x00000e45,0x0003003e,0x00000e42,0x00000e46,0x0004003d, + 0x00000006,0x00000e1f,0x00000e42,0x0003003e,0x00000e0e,0x00000e1f,0x0004003d,0x0000002a, + 0x00000e20,0x00000db5,0x0004003d,0x0000002a,0x00000e21,0x00000db5,0x0003003e,0x00000e11, + 0x00000e21,0x0004003d,0x0000002a,0x00000e56,0x00000e11,0x0003003e,0x00000e51,0x00000161, + 0x0003003e,0x00000e52,0x00000162,0x0003003e,0x00000e53,0x00000163,0x0004003d,0x00000006, + 0x00000e5c,0x00000e51,0x00050041,0x00000007,0x00000e5d,0x00000e59,0x000000b5,0x0003003e, + 0x00000e5d,0x00000e5c,0x0004003d,0x00000006,0x00000e5e,0x00000e52,0x00050041,0x00000007, + 0x00000e5f,0x00000e59,0x000000b8,0x0003003e,0x00000e5f,0x00000e5e,0x0004003d,0x00000006, + 0x00000e60,0x00000e53,0x00050041,0x00000007,0x00000e61,0x00000e59,0x000000cb,0x0003003e, + 0x00000e61,0x00000e60,0x0004003d,0x0000002a,0x00000e62,0x00000e59,0x0003003e,0x00000e5a, + 0x00000e62,0x0004003d,0x0000002a,0x00000e57,0x00000e5a,0x00050094,0x00000006,0x00000e58, + 0x00000e56,0x00000e57,0x0003003e,0x00000e54,0x00000e58,0x0004003d,0x00000006,0x00000e22, + 0x00000e54,0x00060050,0x0000002a,0x00000e23,0x00000e22,0x00000e22,0x00000e22,0x00050083, + 0x0000002a,0x00000e24,0x00000e20,0x00000e23,0x0003003e,0x00000e10,0x00000e24,0x0004003d, + 0x00000006,0x00000e25,0x00000e0e,0x00050083,0x00000006,0x00000e26,0x000000eb,0x00000e25, + 0x0004003d,0x00000006,0x00000e27,0x00000e0e,0x0003003e,0x00000e13,0x00000e27,0x0003003e, + 0x00000e14,0x00000e26,0x0004003d,0x00000006,0x00000e66,0x00000e13,0x00050041,0x00000007, + 0x00000e67,0x00000e63,0x000000b5,0x0003003e,0x00000e67,0x00000e66,0x0004003d,0x00000006, + 0x00000e68,0x00000e14,0x00050041,0x00000007,0x00000e69,0x00000e63,0x000000b8,0x0003003e, + 0x00000e69,0x00000e68,0x0004003d,0x00000012,0x00000e6a,0x00000e63,0x0003003e,0x00000e64, + 0x00000e6a,0x0004003d,0x00000012,0x00000e28,0x00000e64,0x0003003e,0x00000e15,0x0000017d, + 0x0004003d,0x00000006,0x00000e6e,0x00000e15,0x00050041,0x00000007,0x00000e6f,0x00000e6b, + 0x000000b5,0x0003003e,0x00000e6f,0x00000e6e,0x0004003d,0x00000006,0x00000e70,0x00000e15, + 0x00050041,0x00000007,0x00000e71,0x00000e6b,0x000000b8,0x0003003e,0x00000e71,0x00000e70, + 0x0004003d,0x00000012,0x00000e72,0x00000e6b,0x0003003e,0x00000e6c,0x00000e72,0x0004003d, + 0x00000012,0x00000e29,0x00000e6c,0x0004003d,0x0000002a,0x00000e2a,0x00000e10,0x0003003e, + 0x00000e16,0x00000e2a,0x0004003d,0x0000002a,0x00000e76,0x00000e16,0x0007004f,0x00000012, + 0x00000e77,0x00000e76,0x00000e76,0x00000000,0x00000001,0x0003003e,0x00000e73,0x00000e77, + 0x00050041,0x00000007,0x00000e7e,0x00000e73,0x000000b5,0x0004003d,0x00000006,0x00000e7f, + 0x00000e7e,0x00050041,0x00000007,0x00000e80,0x00000e73,0x000000b8,0x0004003d,0x00000006, + 0x00000e81,0x00000e80,0x0007000c,0x00000006,0x00000e82,0x00000001,0x00000025,0x00000e7f, + 0x00000e81,0x0003003e,0x00000e7c,0x00000e82,0x0004003d,0x00000006,0x00000e78,0x00000e7c, + 0x00050041,0x00000007,0x00000e79,0x00000e16,0x000000cb,0x0004003d,0x00000006,0x00000e7a, + 0x00000e79,0x0007000c,0x00000006,0x00000e7b,0x00000001,0x00000025,0x00000e78,0x00000e7a, + 0x0003003e,0x00000e74,0x00000e7b,0x0004003d,0x00000006,0x00000e2b,0x00000e74,0x0004007f, + 0x00000006,0x00000e2c,0x00000e2b,0x0004003d,0x0000002a,0x00000e2d,0x00000e10,0x0003003e, + 0x00000e17,0x00000e2d,0x0004003d,0x0000002a,0x00000e86,0x00000e17,0x0007004f,0x00000012, + 0x00000e87,0x00000e86,0x00000e86,0x00000000,0x00000001,0x0003003e,0x00000e83,0x00000e87, + 0x00050041,0x00000007,0x00000e8e,0x00000e83,0x000000b5,0x0004003d,0x00000006,0x00000e8f, + 0x00000e8e,0x00050041,0x00000007,0x00000e90,0x00000e83,0x000000b8,0x0004003d,0x00000006, + 0x00000e91,0x00000e90,0x0007000c,0x00000006,0x00000e92,0x00000001,0x00000028,0x00000e8f, + 0x00000e91,0x0003003e,0x00000e8c,0x00000e92,0x0004003d,0x00000006,0x00000e88,0x00000e8c, + 0x00050041,0x00000007,0x00000e89,0x00000e17,0x000000cb,0x0004003d,0x00000006,0x00000e8a, + 0x00000e89,0x0007000c,0x00000006,0x00000e8b,0x00000001,0x00000028,0x00000e88,0x00000e8a, + 0x0003003e,0x00000e84,0x00000e8b,0x0004003d,0x00000006,0x00000e2e,0x00000e84,0x0003003e, + 0x00000e18,0x00000e2c,0x0003003e,0x00000e19,0x00000e2e,0x0004003d,0x00000006,0x00000e96, + 0x00000e18,0x00050041,0x00000007,0x00000e97,0x00000e93,0x000000b5,0x0003003e,0x00000e97, + 0x00000e96,0x0004003d,0x00000006,0x00000e98,0x00000e19,0x00050041,0x00000007,0x00000e99, + 0x00000e93,0x000000b8,0x0003003e,0x00000e99,0x00000e98,0x0004003d,0x00000012,0x00000e9a, + 0x00000e93,0x0003003e,0x00000e94,0x00000e9a,0x0004003d,0x00000012,0x00000e2f,0x00000e94, + 0x0007000c,0x00000012,0x00000e30,0x00000001,0x00000028,0x00000e29,0x00000e2f,0x00050088, + 0x00000012,0x00000e31,0x00000e28,0x00000e30,0x0003003e,0x00000e12,0x00000e31,0x0003003e, + 0x00000e1b,0x000000eb,0x0004003d,0x00000006,0x00000e9d,0x00000e1b,0x0003003e,0x00000e9b, + 0x00000e9d,0x0004003d,0x00000006,0x00000e32,0x00000e9b,0x00050041,0x00000007,0x00000e33, + 0x00000e12,0x000000b5,0x0004003d,0x00000006,0x00000e34,0x00000e33,0x00050041,0x00000007, + 0x00000e35,0x00000e12,0x000000b8,0x0004003d,0x00000006,0x00000e36,0x00000e35,0x0007000c, + 0x00000006,0x00000e37,0x00000001,0x00000025,0x00000e34,0x00000e36,0x0007000c,0x00000006, + 0x00000e38,0x00000001,0x00000025,0x00000e32,0x00000e37,0x0003003e,0x00000e1a,0x00000e38, + 0x0004003d,0x0000002a,0x00000e39,0x00000e10,0x0004003d,0x00000006,0x00000e3a,0x00000e1a, + 0x0005008e,0x0000002a,0x00000e3b,0x00000e39,0x00000e3a,0x0004003d,0x00000006,0x00000e3c, + 0x00000e0e,0x00060050,0x0000002a,0x00000e3d,0x00000e3c,0x00000e3c,0x00000e3c,0x00050081, + 0x0000002a,0x00000e3e,0x00000e3b,0x00000e3d,0x0003003e,0x00000e1c,0x00000e3e,0x0004003d, + 0x0000002a,0x00000dcd,0x00000e1c,0x0003003e,0x00000db7,0x00000dcd,0x0004003d,0x0000002a, + 0x00000cef,0x00000db7,0x0003003e,0x00000bf3,0x00000cef,0x000200f9,0x00000cf0,0x000200f8, + 0x00000cf0,0x000200f9,0x00000d10,0x000200f8,0x00000cf1,0x000300f7,0x00000cfb,0x00000000, + 0x000400fa,0x000002be,0x00000cf2,0x00000cfb,0x000200f8,0x00000cf2,0x0004003d,0x0000002a, + 0x00000cf3,0x00000be1,0x0003003e,0x00000c0a,0x000000ec,0x0004003d,0x00000006,0x00000ea1, + 0x00000c0a,0x00050041,0x00000007,0x00000ea2,0x00000e9e,0x000000b5,0x0003003e,0x00000ea2, + 0x00000ea1,0x0004003d,0x00000006,0x00000ea3,0x00000c0a,0x00050041,0x00000007,0x00000ea4, + 0x00000e9e,0x000000b8,0x0003003e,0x00000ea4,0x00000ea3,0x0004003d,0x00000006,0x00000ea5, + 0x00000c0a,0x00050041,0x00000007,0x00000ea6,0x00000e9e,0x000000cb,0x0003003e,0x00000ea6, + 0x00000ea5,0x0004003d,0x0000002a,0x00000ea7,0x00000e9e,0x0003003e,0x00000e9f,0x00000ea7, + 0x0004003d,0x0000002a,0x00000cf4,0x00000e9f,0x0003003e,0x00000c0b,0x000000eb,0x0004003d, + 0x00000006,0x00000eab,0x00000c0b,0x00050041,0x00000007,0x00000eac,0x00000ea8,0x000000b5, + 0x0003003e,0x00000eac,0x00000eab,0x0004003d,0x00000006,0x00000ead,0x00000c0b,0x00050041, + 0x00000007,0x00000eae,0x00000ea8,0x000000b8,0x0003003e,0x00000eae,0x00000ead,0x0004003d, + 0x00000006,0x00000eaf,0x00000c0b,0x00050041,0x00000007,0x00000eb0,0x00000ea8,0x000000cb, + 0x0003003e,0x00000eb0,0x00000eaf,0x0004003d,0x0000002a,0x00000eb1,0x00000ea8,0x0003003e, + 0x00000ea9,0x00000eb1,0x0004003d,0x0000002a,0x00000cf5,0x00000ea9,0x0008000c,0x0000002a, + 0x00000cf6,0x00000001,0x0000002b,0x00000cf3,0x00000cf4,0x00000cf5,0x0003003e,0x00000be1, + 0x00000cf6,0x0004003d,0x0000002a,0x00000cf7,0x00000bf1,0x0003003e,0x00000c0c,0x00000cf7, + 0x0004003d,0x0000002a,0x00000cf8,0x00000be1,0x0003003e,0x00000c0d,0x00000cf8,0x0004003d, + 0x0000002a,0x00000cf9,0x00000bf1,0x0003003e,0x00000c0e,0x00000cf9,0x0004003d,0x0000002a, + 0x00000ebd,0x00000c0d,0x0003003e,0x00000eb3,0x00000ebd,0x0004003d,0x0000002a,0x00000ed5, + 0x00000eb3,0x0007004f,0x00000012,0x00000ed6,0x00000ed5,0x00000ed5,0x00000000,0x00000001, + 0x0003003e,0x00000ed2,0x00000ed6,0x00050041,0x00000007,0x00000edd,0x00000ed2,0x000000b5, + 0x0004003d,0x00000006,0x00000ede,0x00000edd,0x00050041,0x00000007,0x00000edf,0x00000ed2, + 0x000000b8,0x0004003d,0x00000006,0x00000ee0,0x00000edf,0x0007000c,0x00000006,0x00000ee1, + 0x00000001,0x00000028,0x00000ede,0x00000ee0,0x0003003e,0x00000edb,0x00000ee1,0x0004003d, + 0x00000006,0x00000ed7,0x00000edb,0x00050041,0x00000007,0x00000ed8,0x00000eb3,0x000000cb, + 0x0004003d,0x00000006,0x00000ed9,0x00000ed8,0x0007000c,0x00000006,0x00000eda,0x00000001, + 0x00000028,0x00000ed7,0x00000ed9,0x0003003e,0x00000ed3,0x00000eda,0x0004003d,0x00000006, + 0x00000ebe,0x00000ed3,0x0004003d,0x0000002a,0x00000ebf,0x00000c0d,0x0003003e,0x00000eb4, + 0x00000ebf,0x0004003d,0x0000002a,0x00000ee5,0x00000eb4,0x0007004f,0x00000012,0x00000ee6, + 0x00000ee5,0x00000ee5,0x00000000,0x00000001,0x0003003e,0x00000ee2,0x00000ee6,0x00050041, + 0x00000007,0x00000eed,0x00000ee2,0x000000b5,0x0004003d,0x00000006,0x00000eee,0x00000eed, + 0x00050041,0x00000007,0x00000eef,0x00000ee2,0x000000b8,0x0004003d,0x00000006,0x00000ef0, + 0x00000eef,0x0007000c,0x00000006,0x00000ef1,0x00000001,0x00000025,0x00000eee,0x00000ef0, + 0x0003003e,0x00000eeb,0x00000ef1,0x0004003d,0x00000006,0x00000ee7,0x00000eeb,0x00050041, + 0x00000007,0x00000ee8,0x00000eb4,0x000000cb,0x0004003d,0x00000006,0x00000ee9,0x00000ee8, + 0x0007000c,0x00000006,0x00000eea,0x00000001,0x00000025,0x00000ee7,0x00000ee9,0x0003003e, + 0x00000ee3,0x00000eea,0x0004003d,0x00000006,0x00000ec0,0x00000ee3,0x00050083,0x00000006, + 0x00000ec1,0x00000ebe,0x00000ec0,0x0003003e,0x00000eb2,0x00000ec1,0x0004003d,0x0000002a, + 0x00000ec2,0x00000c0c,0x0003003e,0x00000eb5,0x00000ec2,0x0004003d,0x0000002a,0x00000ef5, + 0x00000eb5,0x0007004f,0x00000012,0x00000ef6,0x00000ef5,0x00000ef5,0x00000000,0x00000001, + 0x0003003e,0x00000ef2,0x00000ef6,0x00050041,0x00000007,0x00000efd,0x00000ef2,0x000000b5, + 0x0004003d,0x00000006,0x00000efe,0x00000efd,0x00050041,0x00000007,0x00000eff,0x00000ef2, + 0x000000b8,0x0004003d,0x00000006,0x00000f00,0x00000eff,0x0007000c,0x00000006,0x00000f01, + 0x00000001,0x00000025,0x00000efe,0x00000f00,0x0003003e,0x00000efb,0x00000f01,0x0004003d, + 0x00000006,0x00000ef7,0x00000efb,0x00050041,0x00000007,0x00000ef8,0x00000eb5,0x000000cb, + 0x0004003d,0x00000006,0x00000ef9,0x00000ef8,0x0007000c,0x00000006,0x00000efa,0x00000001, + 0x00000025,0x00000ef7,0x00000ef9,0x0003003e,0x00000ef3,0x00000efa,0x0004003d,0x00000006, + 0x00000ec3,0x00000ef3,0x0004003d,0x0000002a,0x00000ec4,0x00000c0c,0x00060050,0x0000002a, + 0x00000ec5,0x00000ec3,0x00000ec3,0x00000ec3,0x00050083,0x0000002a,0x00000ec6,0x00000ec4, + 0x00000ec5,0x0003003e,0x00000c0c,0x00000ec6,0x0004003d,0x0000002a,0x00000ec7,0x00000c0c, + 0x0003003e,0x00000eb7,0x00000ec7,0x0004003d,0x0000002a,0x00000f05,0x00000eb7,0x0007004f, + 0x00000012,0x00000f06,0x00000f05,0x00000f05,0x00000000,0x00000001,0x0003003e,0x00000f02, + 0x00000f06,0x00050041,0x00000007,0x00000f0d,0x00000f02,0x000000b5,0x0004003d,0x00000006, + 0x00000f0e,0x00000f0d,0x00050041,0x00000007,0x00000f0f,0x00000f02,0x000000b8,0x0004003d, + 0x00000006,0x00000f10,0x00000f0f,0x0007000c,0x00000006,0x00000f11,0x00000001,0x00000028, + 0x00000f0e,0x00000f10,0x0003003e,0x00000f0b,0x00000f11,0x0004003d,0x00000006,0x00000f07, + 0x00000f0b,0x00050041,0x00000007,0x00000f08,0x00000eb7,0x000000cb,0x0004003d,0x00000006, + 0x00000f09,0x00000f08,0x0007000c,0x00000006,0x00000f0a,0x00000001,0x00000028,0x00000f07, + 0x00000f09,0x0003003e,0x00000f03,0x00000f0a,0x0004003d,0x00000006,0x00000ec8,0x00000f03, + 0x0003003e,0x00000eb6,0x00000ec8,0x0004003d,0x00000006,0x00000ec9,0x00000eb2,0x0004003d, + 0x00000006,0x00000eca,0x00000eb6,0x0007000c,0x00000006,0x00000ecb,0x00000001,0x00000028, + 0x0000017d,0x00000eca,0x00050088,0x00000006,0x00000ecc,0x00000ec9,0x00000ecb,0x0003003e, + 0x00000eb8,0x00000ecc,0x0004003d,0x0000002a,0x00000ecd,0x00000c0c,0x0004003d,0x00000006, + 0x00000ece,0x00000eb8,0x0005008e,0x0000002a,0x00000ecf,0x00000ecd,0x00000ece,0x0003003e, + 0x00000eb9,0x00000ecf,0x0004003d,0x0000002a,0x00000ed0,0x00000c0e,0x0003003e,0x00000eba, + 0x00000ed0,0x0004003d,0x0000002a,0x00000f22,0x00000eba,0x0003003e,0x00000f13,0x00000f22, + 0x0004003d,0x0000002a,0x00000f48,0x00000f13,0x0003003e,0x00000f43,0x00000161,0x0003003e, + 0x00000f44,0x00000162,0x0003003e,0x00000f45,0x00000163,0x0004003d,0x00000006,0x00000f4e, + 0x00000f43,0x00050041,0x00000007,0x00000f4f,0x00000f4b,0x000000b5,0x0003003e,0x00000f4f, + 0x00000f4e,0x0004003d,0x00000006,0x00000f50,0x00000f44,0x00050041,0x00000007,0x00000f51, + 0x00000f4b,0x000000b8,0x0003003e,0x00000f51,0x00000f50,0x0004003d,0x00000006,0x00000f52, + 0x00000f45,0x00050041,0x00000007,0x00000f53,0x00000f4b,0x000000cb,0x0003003e,0x00000f53, + 0x00000f52,0x0004003d,0x0000002a,0x00000f54,0x00000f4b,0x0003003e,0x00000f4c,0x00000f54, + 0x0004003d,0x0000002a,0x00000f49,0x00000f4c,0x00050094,0x00000006,0x00000f4a,0x00000f48, + 0x00000f49,0x0003003e,0x00000f46,0x00000f4a,0x0004003d,0x00000006,0x00000f23,0x00000f46, + 0x0003003e,0x00000f12,0x00000f23,0x0004003d,0x0000002a,0x00000f24,0x00000eb9,0x0004003d, + 0x0000002a,0x00000f25,0x00000eb9,0x0003003e,0x00000f15,0x00000f25,0x0004003d,0x0000002a, + 0x00000f5a,0x00000f15,0x0003003e,0x00000f55,0x00000161,0x0003003e,0x00000f56,0x00000162, + 0x0003003e,0x00000f57,0x00000163,0x0004003d,0x00000006,0x00000f60,0x00000f55,0x00050041, + 0x00000007,0x00000f61,0x00000f5d,0x000000b5,0x0003003e,0x00000f61,0x00000f60,0x0004003d, + 0x00000006,0x00000f62,0x00000f56,0x00050041,0x00000007,0x00000f63,0x00000f5d,0x000000b8, + 0x0003003e,0x00000f63,0x00000f62,0x0004003d,0x00000006,0x00000f64,0x00000f57,0x00050041, + 0x00000007,0x00000f65,0x00000f5d,0x000000cb,0x0003003e,0x00000f65,0x00000f64,0x0004003d, + 0x0000002a,0x00000f66,0x00000f5d,0x0003003e,0x00000f5e,0x00000f66,0x0004003d,0x0000002a, + 0x00000f5b,0x00000f5e,0x00050094,0x00000006,0x00000f5c,0x00000f5a,0x00000f5b,0x0003003e, + 0x00000f58,0x00000f5c,0x0004003d,0x00000006,0x00000f26,0x00000f58,0x00060050,0x0000002a, + 0x00000f27,0x00000f26,0x00000f26,0x00000f26,0x00050083,0x0000002a,0x00000f28,0x00000f24, + 0x00000f27,0x0003003e,0x00000f14,0x00000f28,0x0004003d,0x00000006,0x00000f29,0x00000f12, + 0x00050083,0x00000006,0x00000f2a,0x000000eb,0x00000f29,0x0004003d,0x00000006,0x00000f2b, + 0x00000f12,0x0003003e,0x00000f17,0x00000f2b,0x0003003e,0x00000f18,0x00000f2a,0x0004003d, + 0x00000006,0x00000f6a,0x00000f17,0x00050041,0x00000007,0x00000f6b,0x00000f67,0x000000b5, + 0x0003003e,0x00000f6b,0x00000f6a,0x0004003d,0x00000006,0x00000f6c,0x00000f18,0x00050041, + 0x00000007,0x00000f6d,0x00000f67,0x000000b8,0x0003003e,0x00000f6d,0x00000f6c,0x0004003d, + 0x00000012,0x00000f6e,0x00000f67,0x0003003e,0x00000f68,0x00000f6e,0x0004003d,0x00000012, + 0x00000f2c,0x00000f68,0x0003003e,0x00000f19,0x0000017d,0x0004003d,0x00000006,0x00000f72, + 0x00000f19,0x00050041,0x00000007,0x00000f73,0x00000f6f,0x000000b5,0x0003003e,0x00000f73, + 0x00000f72,0x0004003d,0x00000006,0x00000f74,0x00000f19,0x00050041,0x00000007,0x00000f75, + 0x00000f6f,0x000000b8,0x0003003e,0x00000f75,0x00000f74,0x0004003d,0x00000012,0x00000f76, + 0x00000f6f,0x0003003e,0x00000f70,0x00000f76,0x0004003d,0x00000012,0x00000f2d,0x00000f70, + 0x0004003d,0x0000002a,0x00000f2e,0x00000f14,0x0003003e,0x00000f1a,0x00000f2e,0x0004003d, + 0x0000002a,0x00000f7a,0x00000f1a,0x0007004f,0x00000012,0x00000f7b,0x00000f7a,0x00000f7a, + 0x00000000,0x00000001,0x0003003e,0x00000f77,0x00000f7b,0x00050041,0x00000007,0x00000f82, + 0x00000f77,0x000000b5,0x0004003d,0x00000006,0x00000f83,0x00000f82,0x00050041,0x00000007, + 0x00000f84,0x00000f77,0x000000b8,0x0004003d,0x00000006,0x00000f85,0x00000f84,0x0007000c, + 0x00000006,0x00000f86,0x00000001,0x00000025,0x00000f83,0x00000f85,0x0003003e,0x00000f80, + 0x00000f86,0x0004003d,0x00000006,0x00000f7c,0x00000f80,0x00050041,0x00000007,0x00000f7d, + 0x00000f1a,0x000000cb,0x0004003d,0x00000006,0x00000f7e,0x00000f7d,0x0007000c,0x00000006, + 0x00000f7f,0x00000001,0x00000025,0x00000f7c,0x00000f7e,0x0003003e,0x00000f78,0x00000f7f, + 0x0004003d,0x00000006,0x00000f2f,0x00000f78,0x0004007f,0x00000006,0x00000f30,0x00000f2f, + 0x0004003d,0x0000002a,0x00000f31,0x00000f14,0x0003003e,0x00000f1b,0x00000f31,0x0004003d, + 0x0000002a,0x00000f8a,0x00000f1b,0x0007004f,0x00000012,0x00000f8b,0x00000f8a,0x00000f8a, + 0x00000000,0x00000001,0x0003003e,0x00000f87,0x00000f8b,0x00050041,0x00000007,0x00000f92, + 0x00000f87,0x000000b5,0x0004003d,0x00000006,0x00000f93,0x00000f92,0x00050041,0x00000007, + 0x00000f94,0x00000f87,0x000000b8,0x0004003d,0x00000006,0x00000f95,0x00000f94,0x0007000c, + 0x00000006,0x00000f96,0x00000001,0x00000028,0x00000f93,0x00000f95,0x0003003e,0x00000f90, + 0x00000f96,0x0004003d,0x00000006,0x00000f8c,0x00000f90,0x00050041,0x00000007,0x00000f8d, + 0x00000f1b,0x000000cb,0x0004003d,0x00000006,0x00000f8e,0x00000f8d,0x0007000c,0x00000006, + 0x00000f8f,0x00000001,0x00000028,0x00000f8c,0x00000f8e,0x0003003e,0x00000f88,0x00000f8f, + 0x0004003d,0x00000006,0x00000f32,0x00000f88,0x0003003e,0x00000f1c,0x00000f30,0x0003003e, + 0x00000f1d,0x00000f32,0x0004003d,0x00000006,0x00000f9a,0x00000f1c,0x00050041,0x00000007, + 0x00000f9b,0x00000f97,0x000000b5,0x0003003e,0x00000f9b,0x00000f9a,0x0004003d,0x00000006, + 0x00000f9c,0x00000f1d,0x00050041,0x00000007,0x00000f9d,0x00000f97,0x000000b8,0x0003003e, + 0x00000f9d,0x00000f9c,0x0004003d,0x00000012,0x00000f9e,0x00000f97,0x0003003e,0x00000f98, + 0x00000f9e,0x0004003d,0x00000012,0x00000f33,0x00000f98,0x0007000c,0x00000012,0x00000f34, + 0x00000001,0x00000028,0x00000f2d,0x00000f33,0x00050088,0x00000012,0x00000f35,0x00000f2c, + 0x00000f34,0x0003003e,0x00000f16,0x00000f35,0x0003003e,0x00000f1f,0x000000eb,0x0004003d, + 0x00000006,0x00000fa1,0x00000f1f,0x0003003e,0x00000f9f,0x00000fa1,0x0004003d,0x00000006, + 0x00000f36,0x00000f9f,0x00050041,0x00000007,0x00000f37,0x00000f16,0x000000b5,0x0004003d, + 0x00000006,0x00000f38,0x00000f37,0x00050041,0x00000007,0x00000f39,0x00000f16,0x000000b8, + 0x0004003d,0x00000006,0x00000f3a,0x00000f39,0x0007000c,0x00000006,0x00000f3b,0x00000001, + 0x00000025,0x00000f38,0x00000f3a,0x0007000c,0x00000006,0x00000f3c,0x00000001,0x00000025, + 0x00000f36,0x00000f3b,0x0003003e,0x00000f1e,0x00000f3c,0x0004003d,0x0000002a,0x00000f3d, + 0x00000f14,0x0004003d,0x00000006,0x00000f3e,0x00000f1e,0x0005008e,0x0000002a,0x00000f3f, + 0x00000f3d,0x00000f3e,0x0004003d,0x00000006,0x00000f40,0x00000f12,0x00060050,0x0000002a, + 0x00000f41,0x00000f40,0x00000f40,0x00000f40,0x00050081,0x0000002a,0x00000f42,0x00000f3f, + 0x00000f41,0x0003003e,0x00000f20,0x00000f42,0x0004003d,0x0000002a,0x00000ed1,0x00000f20, + 0x0003003e,0x00000ebb,0x00000ed1,0x0004003d,0x0000002a,0x00000cfa,0x00000ebb,0x0003003e, + 0x00000bf3,0x00000cfa,0x000200f9,0x00000cfb,0x000200f8,0x00000cfb,0x000200f9,0x00000d10, + 0x000200f8,0x00000cfc,0x000300f7,0x00000d05,0x00000000,0x000400fa,0x000002be,0x00000cfd, + 0x00000d05,0x000200f8,0x00000cfd,0x0004003d,0x0000002a,0x00000cfe,0x00000be1,0x0003003e, + 0x00000c0f,0x000000ec,0x0004003d,0x00000006,0x00000fa5,0x00000c0f,0x00050041,0x00000007, + 0x00000fa6,0x00000fa2,0x000000b5,0x0003003e,0x00000fa6,0x00000fa5,0x0004003d,0x00000006, + 0x00000fa7,0x00000c0f,0x00050041,0x00000007,0x00000fa8,0x00000fa2,0x000000b8,0x0003003e, + 0x00000fa8,0x00000fa7,0x0004003d,0x00000006,0x00000fa9,0x00000c0f,0x00050041,0x00000007, + 0x00000faa,0x00000fa2,0x000000cb,0x0003003e,0x00000faa,0x00000fa9,0x0004003d,0x0000002a, + 0x00000fab,0x00000fa2,0x0003003e,0x00000fa3,0x00000fab,0x0004003d,0x0000002a,0x00000cff, + 0x00000fa3,0x0003003e,0x00000c10,0x000000eb,0x0004003d,0x00000006,0x00000faf,0x00000c10, + 0x00050041,0x00000007,0x00000fb0,0x00000fac,0x000000b5,0x0003003e,0x00000fb0,0x00000faf, + 0x0004003d,0x00000006,0x00000fb1,0x00000c10,0x00050041,0x00000007,0x00000fb2,0x00000fac, + 0x000000b8,0x0003003e,0x00000fb2,0x00000fb1,0x0004003d,0x00000006,0x00000fb3,0x00000c10, + 0x00050041,0x00000007,0x00000fb4,0x00000fac,0x000000cb,0x0003003e,0x00000fb4,0x00000fb3, + 0x0004003d,0x0000002a,0x00000fb5,0x00000fac,0x0003003e,0x00000fad,0x00000fb5,0x0004003d, + 0x0000002a,0x00000d00,0x00000fad,0x0008000c,0x0000002a,0x00000d01,0x00000001,0x0000002b, + 0x00000cfe,0x00000cff,0x00000d00,0x0003003e,0x00000be1,0x00000d01,0x0004003d,0x0000002a, + 0x00000d02,0x00000be1,0x0003003e,0x00000c11,0x00000d02,0x0004003d,0x0000002a,0x00000d03, + 0x00000bf1,0x0003003e,0x00000c12,0x00000d03,0x0004003d,0x0000002a,0x00000fc6,0x00000c12, + 0x0003003e,0x00000fb7,0x00000fc6,0x0004003d,0x0000002a,0x00000fec,0x00000fb7,0x0003003e, + 0x00000fe7,0x00000161,0x0003003e,0x00000fe8,0x00000162,0x0003003e,0x00000fe9,0x00000163, + 0x0004003d,0x00000006,0x00000ff2,0x00000fe7,0x00050041,0x00000007,0x00000ff3,0x00000fef, + 0x000000b5,0x0003003e,0x00000ff3,0x00000ff2,0x0004003d,0x00000006,0x00000ff4,0x00000fe8, + 0x00050041,0x00000007,0x00000ff5,0x00000fef,0x000000b8,0x0003003e,0x00000ff5,0x00000ff4, + 0x0004003d,0x00000006,0x00000ff6,0x00000fe9,0x00050041,0x00000007,0x00000ff7,0x00000fef, + 0x000000cb,0x0003003e,0x00000ff7,0x00000ff6,0x0004003d,0x0000002a,0x00000ff8,0x00000fef, + 0x0003003e,0x00000ff0,0x00000ff8,0x0004003d,0x0000002a,0x00000fed,0x00000ff0,0x00050094, + 0x00000006,0x00000fee,0x00000fec,0x00000fed,0x0003003e,0x00000fea,0x00000fee,0x0004003d, + 0x00000006,0x00000fc7,0x00000fea,0x0003003e,0x00000fb6,0x00000fc7,0x0004003d,0x0000002a, + 0x00000fc8,0x00000c11,0x0004003d,0x0000002a,0x00000fc9,0x00000c11,0x0003003e,0x00000fb9, + 0x00000fc9,0x0004003d,0x0000002a,0x00000ffe,0x00000fb9,0x0003003e,0x00000ff9,0x00000161, + 0x0003003e,0x00000ffa,0x00000162,0x0003003e,0x00000ffb,0x00000163,0x0004003d,0x00000006, + 0x00001004,0x00000ff9,0x00050041,0x00000007,0x00001005,0x00001001,0x000000b5,0x0003003e, + 0x00001005,0x00001004,0x0004003d,0x00000006,0x00001006,0x00000ffa,0x00050041,0x00000007, + 0x00001007,0x00001001,0x000000b8,0x0003003e,0x00001007,0x00001006,0x0004003d,0x00000006, + 0x00001008,0x00000ffb,0x00050041,0x00000007,0x00001009,0x00001001,0x000000cb,0x0003003e, + 0x00001009,0x00001008,0x0004003d,0x0000002a,0x0000100a,0x00001001,0x0003003e,0x00001002, + 0x0000100a,0x0004003d,0x0000002a,0x00000fff,0x00001002,0x00050094,0x00000006,0x00001000, + 0x00000ffe,0x00000fff,0x0003003e,0x00000ffc,0x00001000,0x0004003d,0x00000006,0x00000fca, + 0x00000ffc,0x00060050,0x0000002a,0x00000fcb,0x00000fca,0x00000fca,0x00000fca,0x00050083, + 0x0000002a,0x00000fcc,0x00000fc8,0x00000fcb,0x0003003e,0x00000fb8,0x00000fcc,0x0004003d, + 0x00000006,0x00000fcd,0x00000fb6,0x00050083,0x00000006,0x00000fce,0x000000eb,0x00000fcd, + 0x0004003d,0x00000006,0x00000fcf,0x00000fb6,0x0003003e,0x00000fbb,0x00000fcf,0x0003003e, + 0x00000fbc,0x00000fce,0x0004003d,0x00000006,0x0000100e,0x00000fbb,0x00050041,0x00000007, + 0x0000100f,0x0000100b,0x000000b5,0x0003003e,0x0000100f,0x0000100e,0x0004003d,0x00000006, + 0x00001010,0x00000fbc,0x00050041,0x00000007,0x00001011,0x0000100b,0x000000b8,0x0003003e, + 0x00001011,0x00001010,0x0004003d,0x00000012,0x00001012,0x0000100b,0x0003003e,0x0000100c, + 0x00001012,0x0004003d,0x00000012,0x00000fd0,0x0000100c,0x0003003e,0x00000fbd,0x0000017d, + 0x0004003d,0x00000006,0x00001016,0x00000fbd,0x00050041,0x00000007,0x00001017,0x00001013, + 0x000000b5,0x0003003e,0x00001017,0x00001016,0x0004003d,0x00000006,0x00001018,0x00000fbd, + 0x00050041,0x00000007,0x00001019,0x00001013,0x000000b8,0x0003003e,0x00001019,0x00001018, + 0x0004003d,0x00000012,0x0000101a,0x00001013,0x0003003e,0x00001014,0x0000101a,0x0004003d, + 0x00000012,0x00000fd1,0x00001014,0x0004003d,0x0000002a,0x00000fd2,0x00000fb8,0x0003003e, + 0x00000fbe,0x00000fd2,0x0004003d,0x0000002a,0x0000101e,0x00000fbe,0x0007004f,0x00000012, + 0x0000101f,0x0000101e,0x0000101e,0x00000000,0x00000001,0x0003003e,0x0000101b,0x0000101f, + 0x00050041,0x00000007,0x00001026,0x0000101b,0x000000b5,0x0004003d,0x00000006,0x00001027, + 0x00001026,0x00050041,0x00000007,0x00001028,0x0000101b,0x000000b8,0x0004003d,0x00000006, + 0x00001029,0x00001028,0x0007000c,0x00000006,0x0000102a,0x00000001,0x00000025,0x00001027, + 0x00001029,0x0003003e,0x00001024,0x0000102a,0x0004003d,0x00000006,0x00001020,0x00001024, + 0x00050041,0x00000007,0x00001021,0x00000fbe,0x000000cb,0x0004003d,0x00000006,0x00001022, + 0x00001021,0x0007000c,0x00000006,0x00001023,0x00000001,0x00000025,0x00001020,0x00001022, + 0x0003003e,0x0000101c,0x00001023,0x0004003d,0x00000006,0x00000fd3,0x0000101c,0x0004007f, + 0x00000006,0x00000fd4,0x00000fd3,0x0004003d,0x0000002a,0x00000fd5,0x00000fb8,0x0003003e, + 0x00000fbf,0x00000fd5,0x0004003d,0x0000002a,0x0000102e,0x00000fbf,0x0007004f,0x00000012, + 0x0000102f,0x0000102e,0x0000102e,0x00000000,0x00000001,0x0003003e,0x0000102b,0x0000102f, + 0x00050041,0x00000007,0x00001036,0x0000102b,0x000000b5,0x0004003d,0x00000006,0x00001037, + 0x00001036,0x00050041,0x00000007,0x00001038,0x0000102b,0x000000b8,0x0004003d,0x00000006, + 0x00001039,0x00001038,0x0007000c,0x00000006,0x0000103a,0x00000001,0x00000028,0x00001037, + 0x00001039,0x0003003e,0x00001034,0x0000103a,0x0004003d,0x00000006,0x00001030,0x00001034, + 0x00050041,0x00000007,0x00001031,0x00000fbf,0x000000cb,0x0004003d,0x00000006,0x00001032, + 0x00001031,0x0007000c,0x00000006,0x00001033,0x00000001,0x00000028,0x00001030,0x00001032, + 0x0003003e,0x0000102c,0x00001033,0x0004003d,0x00000006,0x00000fd6,0x0000102c,0x0003003e, + 0x00000fc0,0x00000fd4,0x0003003e,0x00000fc1,0x00000fd6,0x0004003d,0x00000006,0x0000103e, + 0x00000fc0,0x00050041,0x00000007,0x0000103f,0x0000103b,0x000000b5,0x0003003e,0x0000103f, + 0x0000103e,0x0004003d,0x00000006,0x00001040,0x00000fc1,0x00050041,0x00000007,0x00001041, + 0x0000103b,0x000000b8,0x0003003e,0x00001041,0x00001040,0x0004003d,0x00000012,0x00001042, + 0x0000103b,0x0003003e,0x0000103c,0x00001042,0x0004003d,0x00000012,0x00000fd7,0x0000103c, + 0x0007000c,0x00000012,0x00000fd8,0x00000001,0x00000028,0x00000fd1,0x00000fd7,0x00050088, + 0x00000012,0x00000fd9,0x00000fd0,0x00000fd8,0x0003003e,0x00000fba,0x00000fd9,0x0003003e, + 0x00000fc3,0x000000eb,0x0004003d,0x00000006,0x00001045,0x00000fc3,0x0003003e,0x00001043, + 0x00001045,0x0004003d,0x00000006,0x00000fda,0x00001043,0x00050041,0x00000007,0x00000fdb, + 0x00000fba,0x000000b5,0x0004003d,0x00000006,0x00000fdc,0x00000fdb,0x00050041,0x00000007, + 0x00000fdd,0x00000fba,0x000000b8,0x0004003d,0x00000006,0x00000fde,0x00000fdd,0x0007000c, + 0x00000006,0x00000fdf,0x00000001,0x00000025,0x00000fdc,0x00000fde,0x0007000c,0x00000006, + 0x00000fe0,0x00000001,0x00000025,0x00000fda,0x00000fdf,0x0003003e,0x00000fc2,0x00000fe0, + 0x0004003d,0x0000002a,0x00000fe1,0x00000fb8,0x0004003d,0x00000006,0x00000fe2,0x00000fc2, + 0x0005008e,0x0000002a,0x00000fe3,0x00000fe1,0x00000fe2,0x0004003d,0x00000006,0x00000fe4, + 0x00000fb6,0x00060050,0x0000002a,0x00000fe5,0x00000fe4,0x00000fe4,0x00000fe4,0x00050081, + 0x0000002a,0x00000fe6,0x00000fe3,0x00000fe5,0x0003003e,0x00000fc4,0x00000fe6,0x0004003d, + 0x0000002a,0x00000d04,0x00000fc4,0x0003003e,0x00000bf3,0x00000d04,0x000200f9,0x00000d05, + 0x000200f8,0x00000d05,0x000200f9,0x00000d10,0x000200f8,0x00000d06,0x000300f7,0x00000d0f, + 0x00000000,0x000400fa,0x000002be,0x00000d07,0x00000d0f,0x000200f8,0x00000d07,0x0004003d, + 0x0000002a,0x00000d08,0x00000be1,0x0003003e,0x00000c13,0x000000ec,0x0004003d,0x00000006, + 0x00001049,0x00000c13,0x00050041,0x00000007,0x0000104a,0x00001046,0x000000b5,0x0003003e, + 0x0000104a,0x00001049,0x0004003d,0x00000006,0x0000104b,0x00000c13,0x00050041,0x00000007, + 0x0000104c,0x00001046,0x000000b8,0x0003003e,0x0000104c,0x0000104b,0x0004003d,0x00000006, + 0x0000104d,0x00000c13,0x00050041,0x00000007,0x0000104e,0x00001046,0x000000cb,0x0003003e, + 0x0000104e,0x0000104d,0x0004003d,0x0000002a,0x0000104f,0x00001046,0x0003003e,0x00001047, + 0x0000104f,0x0004003d,0x0000002a,0x00000d09,0x00001047,0x0003003e,0x00000c14,0x000000eb, + 0x0004003d,0x00000006,0x00001053,0x00000c14,0x00050041,0x00000007,0x00001054,0x00001050, + 0x000000b5,0x0003003e,0x00001054,0x00001053,0x0004003d,0x00000006,0x00001055,0x00000c14, + 0x00050041,0x00000007,0x00001056,0x00001050,0x000000b8,0x0003003e,0x00001056,0x00001055, + 0x0004003d,0x00000006,0x00001057,0x00000c14,0x00050041,0x00000007,0x00001058,0x00001050, + 0x000000cb,0x0003003e,0x00001058,0x00001057,0x0004003d,0x0000002a,0x00001059,0x00001050, + 0x0003003e,0x00001051,0x00001059,0x0004003d,0x0000002a,0x00000d0a,0x00001051,0x0008000c, + 0x0000002a,0x00000d0b,0x00000001,0x0000002b,0x00000d08,0x00000d09,0x00000d0a,0x0003003e, + 0x00000be1,0x00000d0b,0x0004003d,0x0000002a,0x00000d0c,0x00000bf1,0x0003003e,0x00000c15, + 0x00000d0c,0x0004003d,0x0000002a,0x00000d0d,0x00000be1,0x0003003e,0x00000c16,0x00000d0d, + 0x0004003d,0x0000002a,0x0000106a,0x00000c16,0x0003003e,0x0000105b,0x0000106a,0x0004003d, + 0x0000002a,0x00001090,0x0000105b,0x0003003e,0x0000108b,0x00000161,0x0003003e,0x0000108c, + 0x00000162,0x0003003e,0x0000108d,0x00000163,0x0004003d,0x00000006,0x00001096,0x0000108b, + 0x00050041,0x00000007,0x00001097,0x00001093,0x000000b5,0x0003003e,0x00001097,0x00001096, + 0x0004003d,0x00000006,0x00001098,0x0000108c,0x00050041,0x00000007,0x00001099,0x00001093, + 0x000000b8,0x0003003e,0x00001099,0x00001098,0x0004003d,0x00000006,0x0000109a,0x0000108d, + 0x00050041,0x00000007,0x0000109b,0x00001093,0x000000cb,0x0003003e,0x0000109b,0x0000109a, + 0x0004003d,0x0000002a,0x0000109c,0x00001093,0x0003003e,0x00001094,0x0000109c,0x0004003d, + 0x0000002a,0x00001091,0x00001094,0x00050094,0x00000006,0x00001092,0x00001090,0x00001091, + 0x0003003e,0x0000108e,0x00001092,0x0004003d,0x00000006,0x0000106b,0x0000108e,0x0003003e, + 0x0000105a,0x0000106b,0x0004003d,0x0000002a,0x0000106c,0x00000c15,0x0004003d,0x0000002a, + 0x0000106d,0x00000c15,0x0003003e,0x0000105d,0x0000106d,0x0004003d,0x0000002a,0x000010a2, + 0x0000105d,0x0003003e,0x0000109d,0x00000161,0x0003003e,0x0000109e,0x00000162,0x0003003e, + 0x0000109f,0x00000163,0x0004003d,0x00000006,0x000010a8,0x0000109d,0x00050041,0x00000007, + 0x000010a9,0x000010a5,0x000000b5,0x0003003e,0x000010a9,0x000010a8,0x0004003d,0x00000006, + 0x000010aa,0x0000109e,0x00050041,0x00000007,0x000010ab,0x000010a5,0x000000b8,0x0003003e, + 0x000010ab,0x000010aa,0x0004003d,0x00000006,0x000010ac,0x0000109f,0x00050041,0x00000007, + 0x000010ad,0x000010a5,0x000000cb,0x0003003e,0x000010ad,0x000010ac,0x0004003d,0x0000002a, + 0x000010ae,0x000010a5,0x0003003e,0x000010a6,0x000010ae,0x0004003d,0x0000002a,0x000010a3, + 0x000010a6,0x00050094,0x00000006,0x000010a4,0x000010a2,0x000010a3,0x0003003e,0x000010a0, + 0x000010a4,0x0004003d,0x00000006,0x0000106e,0x000010a0,0x00060050,0x0000002a,0x0000106f, + 0x0000106e,0x0000106e,0x0000106e,0x00050083,0x0000002a,0x00001070,0x0000106c,0x0000106f, + 0x0003003e,0x0000105c,0x00001070,0x0004003d,0x00000006,0x00001071,0x0000105a,0x00050083, + 0x00000006,0x00001072,0x000000eb,0x00001071,0x0004003d,0x00000006,0x00001073,0x0000105a, + 0x0003003e,0x0000105f,0x00001073,0x0003003e,0x00001060,0x00001072,0x0004003d,0x00000006, + 0x000010b2,0x0000105f,0x00050041,0x00000007,0x000010b3,0x000010af,0x000000b5,0x0003003e, + 0x000010b3,0x000010b2,0x0004003d,0x00000006,0x000010b4,0x00001060,0x00050041,0x00000007, + 0x000010b5,0x000010af,0x000000b8,0x0003003e,0x000010b5,0x000010b4,0x0004003d,0x00000012, + 0x000010b6,0x000010af,0x0003003e,0x000010b0,0x000010b6,0x0004003d,0x00000012,0x00001074, + 0x000010b0,0x0003003e,0x00001061,0x0000017d,0x0004003d,0x00000006,0x000010ba,0x00001061, + 0x00050041,0x00000007,0x000010bb,0x000010b7,0x000000b5,0x0003003e,0x000010bb,0x000010ba, + 0x0004003d,0x00000006,0x000010bc,0x00001061,0x00050041,0x00000007,0x000010bd,0x000010b7, + 0x000000b8,0x0003003e,0x000010bd,0x000010bc,0x0004003d,0x00000012,0x000010be,0x000010b7, + 0x0003003e,0x000010b8,0x000010be,0x0004003d,0x00000012,0x00001075,0x000010b8,0x0004003d, + 0x0000002a,0x00001076,0x0000105c,0x0003003e,0x00001062,0x00001076,0x0004003d,0x0000002a, + 0x000010c2,0x00001062,0x0007004f,0x00000012,0x000010c3,0x000010c2,0x000010c2,0x00000000, + 0x00000001,0x0003003e,0x000010bf,0x000010c3,0x00050041,0x00000007,0x000010ca,0x000010bf, + 0x000000b5,0x0004003d,0x00000006,0x000010cb,0x000010ca,0x00050041,0x00000007,0x000010cc, + 0x000010bf,0x000000b8,0x0004003d,0x00000006,0x000010cd,0x000010cc,0x0007000c,0x00000006, + 0x000010ce,0x00000001,0x00000025,0x000010cb,0x000010cd,0x0003003e,0x000010c8,0x000010ce, + 0x0004003d,0x00000006,0x000010c4,0x000010c8,0x00050041,0x00000007,0x000010c5,0x00001062, + 0x000000cb,0x0004003d,0x00000006,0x000010c6,0x000010c5,0x0007000c,0x00000006,0x000010c7, + 0x00000001,0x00000025,0x000010c4,0x000010c6,0x0003003e,0x000010c0,0x000010c7,0x0004003d, + 0x00000006,0x00001077,0x000010c0,0x0004007f,0x00000006,0x00001078,0x00001077,0x0004003d, + 0x0000002a,0x00001079,0x0000105c,0x0003003e,0x00001063,0x00001079,0x0004003d,0x0000002a, + 0x000010d2,0x00001063,0x0007004f,0x00000012,0x000010d3,0x000010d2,0x000010d2,0x00000000, + 0x00000001,0x0003003e,0x000010cf,0x000010d3,0x00050041,0x00000007,0x000010da,0x000010cf, + 0x000000b5,0x0004003d,0x00000006,0x000010db,0x000010da,0x00050041,0x00000007,0x000010dc, + 0x000010cf,0x000000b8,0x0004003d,0x00000006,0x000010dd,0x000010dc,0x0007000c,0x00000006, + 0x000010de,0x00000001,0x00000028,0x000010db,0x000010dd,0x0003003e,0x000010d8,0x000010de, + 0x0004003d,0x00000006,0x000010d4,0x000010d8,0x00050041,0x00000007,0x000010d5,0x00001063, + 0x000000cb,0x0004003d,0x00000006,0x000010d6,0x000010d5,0x0007000c,0x00000006,0x000010d7, + 0x00000001,0x00000028,0x000010d4,0x000010d6,0x0003003e,0x000010d0,0x000010d7,0x0004003d, + 0x00000006,0x0000107a,0x000010d0,0x0003003e,0x00001064,0x00001078,0x0003003e,0x00001065, + 0x0000107a,0x0004003d,0x00000006,0x000010e2,0x00001064,0x00050041,0x00000007,0x000010e3, + 0x000010df,0x000000b5,0x0003003e,0x000010e3,0x000010e2,0x0004003d,0x00000006,0x000010e4, + 0x00001065,0x00050041,0x00000007,0x000010e5,0x000010df,0x000000b8,0x0003003e,0x000010e5, + 0x000010e4,0x0004003d,0x00000012,0x000010e6,0x000010df,0x0003003e,0x000010e0,0x000010e6, + 0x0004003d,0x00000012,0x0000107b,0x000010e0,0x0007000c,0x00000012,0x0000107c,0x00000001, + 0x00000028,0x00001075,0x0000107b,0x00050088,0x00000012,0x0000107d,0x00001074,0x0000107c, + 0x0003003e,0x0000105e,0x0000107d,0x0003003e,0x00001067,0x000000eb,0x0004003d,0x00000006, + 0x000010e9,0x00001067,0x0003003e,0x000010e7,0x000010e9,0x0004003d,0x00000006,0x0000107e, + 0x000010e7,0x00050041,0x00000007,0x0000107f,0x0000105e,0x000000b5,0x0004003d,0x00000006, + 0x00001080,0x0000107f,0x00050041,0x00000007,0x00001081,0x0000105e,0x000000b8,0x0004003d, + 0x00000006,0x00001082,0x00001081,0x0007000c,0x00000006,0x00001083,0x00000001,0x00000025, + 0x00001080,0x00001082,0x0007000c,0x00000006,0x00001084,0x00000001,0x00000025,0x0000107e, + 0x00001083,0x0003003e,0x00001066,0x00001084,0x0004003d,0x0000002a,0x00001085,0x0000105c, + 0x0004003d,0x00000006,0x00001086,0x00001066,0x0005008e,0x0000002a,0x00001087,0x00001085, + 0x00001086,0x0004003d,0x00000006,0x00001088,0x0000105a,0x00060050,0x0000002a,0x00001089, + 0x00001088,0x00001088,0x00001088,0x00050081,0x0000002a,0x0000108a,0x00001087,0x00001089, + 0x0003003e,0x00001068,0x0000108a,0x0004003d,0x0000002a,0x00000d0e,0x00001068,0x0003003e, + 0x00000bf3,0x00000d0e,0x000200f9,0x00000d0f,0x000200f8,0x00000d0f,0x000200f9,0x00000d10, + 0x000200f8,0x00000d10,0x0004003d,0x0000002a,0x00000d11,0x00000bf3,0x0003003e,0x00000c17, + 0x00000d11,0x0004003d,0x0000002a,0x00000bea,0x00000c17,0x0003003e,0x00000be0,0x00000bea, + 0x0004003d,0x0000002a,0x00000beb,0x000004d0,0x0004003d,0x0000002a,0x00000bec,0x00000be0, + 0x00050041,0x00000007,0x00000bed,0x000004d1,0x000000e2,0x0004003d,0x00000006,0x00000bee, + 0x00000bed,0x0003003e,0x00000be4,0x00000bee,0x0004003d,0x00000006,0x000010ed,0x00000be4, + 0x00050041,0x00000007,0x000010ee,0x000010ea,0x000000b5,0x0003003e,0x000010ee,0x000010ed, + 0x0004003d,0x00000006,0x000010ef,0x00000be4,0x00050041,0x00000007,0x000010f0,0x000010ea, + 0x000000b8,0x0003003e,0x000010f0,0x000010ef,0x0004003d,0x00000006,0x000010f1,0x00000be4, + 0x00050041,0x00000007,0x000010f2,0x000010ea,0x000000cb,0x0003003e,0x000010f2,0x000010f1, + 0x0004003d,0x0000002a,0x000010f3,0x000010ea,0x0003003e,0x000010eb,0x000010f3,0x0004003d, + 0x0000002a,0x00000bef,0x000010eb,0x0008000c,0x0000002a,0x00000bf0,0x00000001,0x0000002e, + 0x00000beb,0x00000bec,0x00000bef,0x0003003e,0x00000be5,0x00000bf0,0x0004003d,0x0000002a, + 0x000004d4,0x00000be5,0x00050041,0x00000007,0x000004d5,0x00000454,0x000000e2,0x0004003d, + 0x00000006,0x000004d6,0x000004d5,0x0005008e,0x0000002a,0x000004d7,0x000004d4,0x000004d6, + 0x00050041,0x00000007,0x000004d8,0x00000454,0x000000b5,0x00050051,0x00000006,0x000004d9, + 0x000004d7,0x00000000,0x0003003e,0x000004d8,0x000004d9,0x00050041,0x00000007,0x000004da, + 0x00000454,0x000000b8,0x00050051,0x00000006,0x000004db,0x000004d7,0x00000001,0x0003003e, + 0x000004da,0x000004db,0x00050041,0x00000007,0x000004dc,0x00000454,0x000000cb,0x00050051, + 0x00000006,0x000004dd,0x000004d7,0x00000002,0x0003003e,0x000004dc,0x000004dd,0x000200f9, + 0x000004bf,0x000200f8,0x000004bf,0x0004003d,0x00000006,0x000004de,0x0000045e,0x00050041, + 0x000004e1,0x000004e2,0x00000499,0x000000b5,0x0004003d,0x00000006,0x000004e3,0x000004e2, + 0x0003003e,0x000004e0,0x000004e3,0x0004003d,0x00000006,0x000010f7,0x000004e0,0x0003003e, + 0x000010f4,0x000010f7,0x0004003d,0x00000006,0x000010f8,0x000010f4,0x0003003e,0x000010f5, + 0x000010f8,0x0004003d,0x00000006,0x000004e4,0x000010f5,0x00050085,0x00000006,0x000004e5, + 0x000004de,0x000004e4,0x0004003d,0x0000000c,0x000004e6,0x00000454,0x0005008e,0x0000000c, + 0x000004e7,0x000004e6,0x000004e5,0x0003003e,0x00000454,0x000004e7,0x0004003d,0x0000000c, + 0x000004e8,0x00000488,0x00050041,0x00000007,0x000004e9,0x00000454,0x000000e2,0x0004003d, + 0x00000006,0x000004ea,0x000004e9,0x00050083,0x00000006,0x000004eb,0x000000eb,0x000004ea, + 0x0005008e,0x0000000c,0x000004ec,0x000004e8,0x000004eb,0x0004003d,0x0000000c,0x000004ed, + 0x00000454,0x00050081,0x0000000c,0x000004ee,0x000004ec,0x000004ed,0x0003003e,0x00000488, + 0x000004ee,0x0004003d,0x0000000c,0x000004f6,0x00000488,0x0008004f,0x0000002a,0x000004f7, + 0x000004f6,0x000004f6,0x00000000,0x00000001,0x00000002,0x0003003e,0x000004f5,0x000004f7, + 0x0003003e,0x000004f8,0x00000451,0x00050041,0x000004e1,0x000004fc,0x000004f2,0x000000b5, + 0x0004003d,0x00000006,0x000004fd,0x000004fc,0x0003003e,0x000004fb,0x000004fd,0x00050041, + 0x000004e1,0x000004ff,0x000004f2,0x000000b8,0x0004003d,0x00000006,0x00000500,0x000004ff, + 0x0003003e,0x000004fe,0x00000500,0x000300f7,0x00001109,0x00000000,0x000400fa,0x0000014d, + 0x000010ff,0x00001107,0x000200f8,0x000010ff,0x0004003d,0x00000012,0x00001100,0x000004f8, + 0x0003003e,0x000010fa,0x00001100,0x0004003d,0x00000006,0x00001101,0x000004fb,0x0003003e, + 0x000010fb,0x00001101,0x0004003d,0x00000006,0x00001102,0x000004fe,0x0003003e,0x000010fc, + 0x00001102,0x00050041,0x00000007,0x0000110f,0x000010fa,0x000000b5,0x0004003d,0x00000006, + 0x00001110,0x0000110f,0x00050085,0x00000006,0x00001111,0x00000137,0x00001110,0x00050041, + 0x00000007,0x00001112,0x000010fa,0x000000b8,0x0004003d,0x00000006,0x00001113,0x00001112, + 0x00050085,0x00000006,0x00001114,0x0000013b,0x00001113,0x00050081,0x00000006,0x00001115, + 0x00001111,0x00001114,0x0006000c,0x00000006,0x00001116,0x00000001,0x0000000a,0x00001115, + 0x0003003e,0x0000110b,0x00001116,0x0004003d,0x00000006,0x00001117,0x0000110b,0x00050085, + 0x00000006,0x00001118,0x00000142,0x00001117,0x0006000c,0x00000006,0x00001119,0x00000001, + 0x0000000a,0x00001118,0x0003003e,0x0000110c,0x00001119,0x0004003d,0x00000006,0x0000111a, + 0x0000110c,0x0004003d,0x00000006,0x0000111b,0x000010fb,0x00050085,0x00000006,0x0000111c, + 0x0000111a,0x0000111b,0x0004003d,0x00000006,0x0000111d,0x000010fc,0x00050081,0x00000006, + 0x0000111e,0x0000111c,0x0000111d,0x0003003e,0x0000110d,0x0000111e,0x0004003d,0x00000006, + 0x00001103,0x0000110d,0x0004003d,0x0000002a,0x00001104,0x000004f5,0x00060050,0x0000002a, + 0x00001105,0x00001103,0x00001103,0x00001103,0x00050081,0x0000002a,0x00001106,0x00001105, + 0x00001104,0x0003003e,0x000010f9,0x00001106,0x000200f9,0x00001109,0x000200f8,0x00001107, + 0x0004003d,0x0000002a,0x00001108,0x000004f5,0x0003003e,0x000010f9,0x00001108,0x000200f9, + 0x00001109,0x000200f8,0x00001109,0x0004003d,0x0000002a,0x0000110a,0x000010f9,0x0003003e, + 0x000010fd,0x0000110a,0x0004003d,0x0000002a,0x00000501,0x000010fd,0x00050041,0x00000007, + 0x00000502,0x00000488,0x000000b5,0x00050051,0x00000006,0x00000503,0x00000501,0x00000000, + 0x0003003e,0x00000502,0x00000503,0x00050041,0x00000007,0x00000504,0x00000488,0x000000b8, + 0x00050051,0x00000006,0x00000505,0x00000501,0x00000001,0x0003003e,0x00000504,0x00000505, + 0x00050041,0x00000007,0x00000506,0x00000488,0x000000cb,0x00050051,0x00000006,0x00000507, + 0x00000501,0x00000002,0x0003003e,0x00000506,0x00000507,0x0004003d,0x0000000c,0x00000509, + 0x00000488,0x0003003e,0x00000508,0x00000509,0x0004003d,0x0000000c,0x00001120,0x00000508, + 0x0003003e,0x0000044b,0x00001120,0x0004003d,0x0000000c,0x0000050e,0x00000485,0x0003003e, + 0x0000050d,0x0000050e,0x0004003d,0x0000000c,0x00001122,0x0000050d,0x0003003e,0x0000044d, + 0x00001122,0x0004003d,0x0000046e,0x00000512,0x00000470,0x0004003d,0x00000089,0x00000513, + 0x0000044f,0x00040063,0x00000512,0x00000513,0x00000515,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_mesh.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..a16c56769848d6c1f39ba63306264a1d9f247cee GIT binary patch literal 93404 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 mCZ}em4uPwc2l>2xyG{e($^2IXi4vv)1$Mb=iCE z{qECR|HkD-(O0Z0Rup&k73Ek{^urWz%St^lxqEV?voJTZdCS#0tS)M$pFS5B7nJq@ ze-FYYyR$IUo^7NV=W4|gF_YU1q6bPFSj>N@hwb6awLNTaj&1H? zJKb#duxq+E^B)9{XLuQSAEy-cINYM0&94C8eOS*dN~?1J|g(d)%GjvhS=h=H26A>IQa? zv4TxcB;=|J%U#WbrG(cW3Ka1-|o|p1(J`o%z2VeAkxV{A%!2>Z$9$5Sf|l z&A$VDEL+bS@O>Zb&A$_Te}*ptAIRd@f)7#Ovv>~sUc~$N1Nl~cx-nl}K_G0!Ydd$O z)AU<_U0(Xz`;u?A7j`#~vnpe%InRN)?XBj~@n&^*yK|n2bBnE3ch2?r4Lh{YqPK0Y z?4M)bp6p*??>boRSKBeioi^rW>`Cs5_V2L$7Cl#ONBF&hy*K6i1NQyNPumfGf5M(h z`Tl}^YpSd52)}dK`%}L2*n9W}C#dT;?fGAUh<&%jn@U`LzxHV-D_%l7Hdd<3*<(4+ zJ^YN3TbFUQ#I4V`fy51G++gDPyt?_k^XA){ao&5m8#B(kFE@&~pA+cI5!VxV1GYna z5mw&PFv11wANX)wLOEtd2QbmhjZHcdJchmz5~TC;XQNv zH9=M1ovQXgX#>08V!TQA!J+@lXzz--wXJ1*;Jnsv;jLAzyL!i>R=i_z?*iwweA}Xy zwzZ-s;=I4Q7hils1-P`bq@ci zrEM+qSxeljRV&Ve9nNX%8)qvH--~#;`pbF$pzMfLmYv3U^~B-RqRT< z>nQ)hTogAA6L&26jG}Ky_;}(1`}<^`A-<#~w0n>JnlG?x4l(zGVE4a-m`i*Dk#qi` zWE(I3Jh~4txBlXjiF5uDY-61le+BLNgumF|61j*!jcv}WVeNsxCB{CE*3a7diq9l2 z`u7Cb^9}qow)fcc{uX)^aefHq8MM8~C3+Fs7}u)E=^Og3c3{`~EPn3W8m?9B8!8uT zd;Tr>1+e=w{@ZEJoa@2gM{9eZhOm53?Sq_iig7(a`>J*;&>pv2QDuVlG;wanYUQ3)c z!|z{-v-ULkT>tBcIn5E=8`#F{FSio?CZex%uFcplASaPiDc2XV^^}%82isiy-_5liAaAZW@sBw5YutG24Pl$tz3FdG>)wENSXZC- zB3lvbs;B6J-^_=x?VaKPmP2h#dufdEpG$Xe1Ge9?>phjY_hEZh-p}aS`@!<&{xs{b z?^l53W8a$+W~$3wnK)FJy9!{eBVtDqCq2z>+|LI9<}`;f`ovzZ!FKJ6BdJn9%s!02 z7SbI0x(~T6*z!4dJy_oNEANwi{~sCcnZ5Iz%&{BW82f0?Jp;ejGilBo@olQT>;86r z2l4mzdBnT!yY^i~K7781tc;K_$Xmy6$9%iM`e@5X&RZe%cRtQ(65CqNdB3gaejZ2v2=TXm46#RI{r^k$t;qiY DhUfOc literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.h new file mode 100644 index 000000000..69244c19c --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.h @@ -0,0 +1,533 @@ +#pragma once + +const uint32_t atomic_draw_image_rect_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000436,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000b000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000165, + 0x000001ed,0x000001fb,0x00000200,0x00000207,0x00000286,0x00030010,0x00000004,0x00000007, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000c3, + 0x0000674e,0x00030005,0x000000fb,0x00006576,0x00040006,0x000000fb,0x00000000,0x00003464, + 0x00030005,0x000000fd,0x00004355,0x00030005,0x0000010e,0x0000674b,0x00030005,0x00000129, + 0x00006747,0x00040005,0x00000137,0x30653742,0x00000000,0x00030005,0x00000142,0x00006748, + 0x00030005,0x00000150,0x00006577,0x00040006,0x00000150,0x00000000,0x00003464,0x00030005, + 0x00000152,0x0000424f,0x00060005,0x00000165,0x465f6c67,0x43676172,0x64726f6f,0x00000000, + 0x00030005,0x000001d0,0x00004444,0x00030005,0x000001d4,0x00006277,0x00030005,0x000001ed, + 0x00003065,0x00030005,0x000001ef,0x00000045,0x00030005,0x000001f4,0x00003478,0x00030005, + 0x000001f5,0x00004344,0x00030005,0x000001f7,0x00003552,0x00030005,0x000001fb,0x00003055, + 0x00030005,0x000001fe,0x00003553,0x00030005,0x00000200,0x00003454,0x00030005,0x00000206, + 0x00003456,0x00030005,0x00000207,0x0000304e,0x00040005,0x00000208,0x61726170,0x0000006d, + 0x00040005,0x0000020b,0x61726170,0x0000006d,0x00040005,0x0000020e,0x61726170,0x0000006d, + 0x00030005,0x00000212,0x00003270,0x00030005,0x00000215,0x00003470,0x00030005,0x0000021b, + 0x00003145,0x00040005,0x0000021f,0x61726170,0x0000006d,0x00040005,0x00000221,0x61726170, + 0x0000006d,0x00030005,0x00000224,0x0000394a,0x00040005,0x00000228,0x61726170,0x0000006d, + 0x00030005,0x0000022a,0x00003171,0x00040005,0x0000022b,0x61726170,0x0000006d,0x00030005, + 0x0000022d,0x00000050,0x00040005,0x0000022e,0x61726170,0x0000006d,0x00040005,0x00000230, + 0x61726170,0x0000006d,0x00040005,0x00000232,0x61726170,0x0000006d,0x00040005,0x00000233, + 0x61726170,0x0000006d,0x00030005,0x0000023c,0x0000434c,0x00040006,0x0000023c,0x00000000, + 0x00003479,0x00040006,0x0000023c,0x00000001,0x00003056,0x00030005,0x0000023e,0x00003041, + 0x00030005,0x00000247,0x0000304f,0x00040005,0x00000253,0x61726170,0x0000006d,0x00040005, + 0x00000256,0x61726170,0x0000006d,0x00040005,0x00000258,0x61726170,0x0000006d,0x00040005, + 0x0000025e,0x61726170,0x0000006d,0x00030005,0x0000026e,0x0000424d,0x00040006,0x0000026e, + 0x00000000,0x00003376,0x00040006,0x0000026e,0x00000001,0x00003377,0x00030005,0x00000270, + 0x0000006b,0x00040005,0x00000273,0x61726170,0x0000006d,0x00040005,0x00000276,0x61726170, + 0x0000006d,0x00040005,0x00000279,0x61726170,0x0000006d,0x00040005,0x0000027c,0x61726170, + 0x0000006d,0x00030005,0x00000286,0x0000316d,0x00040005,0x00000288,0x61726170,0x0000006d, + 0x00040047,0x000000c3,0x00000001,0x00000007,0x00040047,0x000000fa,0x00000006,0x00000008, + 0x00030047,0x000000fb,0x00000003,0x00040048,0x000000fb,0x00000000,0x00000018,0x00050048, + 0x000000fb,0x00000000,0x00000023,0x00000000,0x00030047,0x000000fd,0x00000018,0x00040047, + 0x000000fd,0x00000021,0x00000004,0x00040047,0x000000fd,0x00000022,0x00000000,0x00040047, + 0x0000010e,0x00000001,0x00000004,0x00040047,0x00000129,0x00000001,0x00000000,0x00030047, + 0x00000137,0x00000000,0x00040047,0x00000137,0x00000021,0x00000001,0x00040047,0x00000137, + 0x00000022,0x00000002,0x00040047,0x00000137,0x0000002b,0x00000001,0x00040047,0x00000142, + 0x00000001,0x00000001,0x00040047,0x0000014f,0x00000006,0x00000010,0x00030047,0x00000150, + 0x00000003,0x00040048,0x00000150,0x00000000,0x00000018,0x00050048,0x00000150,0x00000000, + 0x00000023,0x00000000,0x00030047,0x00000152,0x00000018,0x00040047,0x00000152,0x00000021, + 0x00000005,0x00040047,0x00000152,0x00000022,0x00000000,0x00040047,0x00000165,0x0000000b, + 0x0000000f,0x00030047,0x000001d0,0x00000000,0x00040047,0x000001d0,0x00000021,0x00000009, + 0x00040047,0x000001d0,0x00000022,0x00000000,0x00030047,0x000001d4,0x00000000,0x00040047, + 0x000001d4,0x00000021,0x00000009,0x00040047,0x000001d4,0x00000022,0x00000000,0x00030047, + 0x000001ed,0x00000000,0x00040047,0x000001ed,0x0000001e,0x00000001,0x00030047,0x000001f4, + 0x00000000,0x00030047,0x000001f5,0x00000000,0x00040047,0x000001f5,0x00000021,0x0000000c, + 0x00040047,0x000001f5,0x00000022,0x00000001,0x00030047,0x000001f6,0x00000000,0x00030047, + 0x000001f7,0x00000000,0x00040047,0x000001f7,0x00000021,0x0000000c,0x00040047,0x000001f7, + 0x00000022,0x00000001,0x00030047,0x000001f8,0x00000000,0x00040047,0x000001fb,0x0000001e, + 0x00000000,0x00030047,0x000001fd,0x00000000,0x00030047,0x000001fe,0x00000000,0x00030047, + 0x00000200,0x00000000,0x00040047,0x00000200,0x0000001e,0x00000001,0x00030047,0x00000201, + 0x00000000,0x00030047,0x00000202,0x00000000,0x00030047,0x00000203,0x00000000,0x00030047, + 0x00000206,0x00000000,0x00040047,0x00000207,0x0000001e,0x00000002,0x00030047,0x0000020b, + 0x00000000,0x00030047,0x0000020d,0x00000000,0x00030047,0x0000020e,0x00000000,0x00030047, + 0x00000210,0x00000000,0x00030047,0x00000211,0x00000000,0x00030047,0x00000215,0x00000017, + 0x00040047,0x00000215,0x00000021,0x00000003,0x00040047,0x00000215,0x00000022,0x00000002, + 0x00030047,0x0000021b,0x00000000,0x00030047,0x00000221,0x00000000,0x00030047,0x00000222, + 0x00000000,0x00030047,0x00000224,0x00000000,0x00030047,0x0000022a,0x00000000,0x00030047, + 0x0000022b,0x00000000,0x00030047,0x0000022d,0x00000000,0x00030047,0x0000022f,0x00000000, + 0x00030047,0x00000230,0x00000000,0x00030047,0x00000231,0x00000000,0x00030047,0x00000232, + 0x00000000,0x00030047,0x00000233,0x00000000,0x00030047,0x00000234,0x00000000,0x00030047, + 0x0000023c,0x00000002,0x00050048,0x0000023c,0x00000000,0x00000023,0x00000018,0x00050048, + 0x0000023c,0x00000001,0x00000023,0x00000038,0x00040047,0x0000023e,0x00000021,0x00000002, + 0x00040047,0x0000023e,0x00000022,0x00000000,0x00030047,0x00000247,0x00000000,0x00030047, + 0x00000249,0x00000000,0x00030047,0x0000024b,0x00000000,0x00030047,0x0000024e,0x00000000, + 0x00030047,0x00000250,0x00000000,0x00030047,0x00000251,0x00000000,0x00030047,0x00000252, + 0x00000000,0x00030047,0x00000256,0x00000000,0x00030047,0x00000257,0x00000000,0x00030047, + 0x00000258,0x00000000,0x00030047,0x00000259,0x00000000,0x00030047,0x0000025c,0x00000000, + 0x00030047,0x00000263,0x00000000,0x00030047,0x00000264,0x00000000,0x00030047,0x00000265, + 0x00000000,0x00030047,0x00000266,0x00000000,0x00030047,0x00000268,0x00000000,0x00030047, + 0x00000269,0x00000000,0x00030047,0x0000026a,0x00000000,0x00030047,0x0000026b,0x00000000, + 0x00030047,0x0000026c,0x00000000,0x00030047,0x0000026e,0x00000002,0x00050048,0x0000026e, + 0x00000000,0x00000023,0x00000058,0x00050048,0x0000026e,0x00000001,0x00000023,0x0000005c, + 0x00040047,0x00000270,0x00000021,0x00000000,0x00040047,0x00000270,0x00000022,0x00000000, + 0x00030047,0x00000273,0x00000000,0x00030047,0x00000274,0x00000000,0x00030047,0x00000275, + 0x00000000,0x00030047,0x00000279,0x00000000,0x00030047,0x0000027c,0x00000000,0x00030047, + 0x00000286,0x00000000,0x00040047,0x00000286,0x0000001e,0x00000000,0x00030047,0x00000287, + 0x00000000,0x00030047,0x00000288,0x00000000,0x00030047,0x00000289,0x00000000,0x00030047, + 0x0000029b,0x00000000,0x00030047,0x0000029c,0x00000000,0x00030047,0x0000029f,0x00000000, + 0x00030047,0x000002a0,0x00000000,0x00030047,0x000002a1,0x00000000,0x00030047,0x000002a2, + 0x00000000,0x00030047,0x000002a4,0x00000000,0x00030047,0x000002a5,0x00000000,0x00030047, + 0x000002a6,0x00000000,0x00030047,0x000002a7,0x00000000,0x00030047,0x000002a8,0x00000000, + 0x00030047,0x000002aa,0x00000000,0x00030047,0x000002ac,0x00000000,0x00030047,0x000002ad, + 0x00000000,0x00030047,0x000002ae,0x00000000,0x00030047,0x000002af,0x00000000,0x00030047, + 0x000002b1,0x00000000,0x00030047,0x000002b2,0x00000000,0x00030047,0x000002b3,0x00000000, + 0x00030047,0x000002b6,0x00000000,0x00030047,0x000002b7,0x00000000,0x00030047,0x000002b9, + 0x00000000,0x00030047,0x000002bb,0x00000000,0x00030047,0x000002c2,0x00000000,0x00030047, + 0x000002c3,0x00000000,0x00030047,0x000002c6,0x00000000,0x00030047,0x000002c7,0x00000000, + 0x00030047,0x000002c8,0x00000000,0x00030047,0x000002ca,0x00000000,0x00030047,0x000002cc, + 0x00000000,0x00030047,0x000002ce,0x00000000,0x00030047,0x000002d0,0x00000000,0x00030047, + 0x000002d2,0x00000000,0x00030047,0x000002d4,0x00000000,0x00030047,0x000002d5,0x00000000, + 0x00030047,0x000002d6,0x00000000,0x00030047,0x000002d9,0x00000000,0x00030047,0x000002da, + 0x00000000,0x00030047,0x000002df,0x00000000,0x00030047,0x000002e1,0x00000000,0x00030047, + 0x000002e3,0x00000000,0x00030047,0x000002f0,0x00000000,0x00030047,0x000002f6,0x00000000, + 0x00030047,0x000002f7,0x00000000,0x00030047,0x00000300,0x00000000,0x00030047,0x00000301, + 0x00000000,0x00030047,0x00000302,0x00000000,0x00030047,0x00000303,0x00000000,0x00030047, + 0x00000304,0x00000000,0x00030047,0x00000305,0x00000000,0x00030047,0x00000306,0x00000000, + 0x00030047,0x00000309,0x00000000,0x00030047,0x0000030c,0x00000000,0x00030047,0x00000314, + 0x00000000,0x00030047,0x00000315,0x00000000,0x00030047,0x00000317,0x00000000,0x00030047, + 0x00000340,0x00000000,0x00030047,0x00000342,0x00000000,0x00030047,0x00000343,0x00000000, + 0x00030047,0x00000344,0x00000000,0x00030047,0x00000345,0x00000000,0x00030047,0x00000346, + 0x00000000,0x00030047,0x00000347,0x00000000,0x00030047,0x00000348,0x00000000,0x00030047, + 0x00000357,0x00000000,0x00030047,0x0000035d,0x00000000,0x00030047,0x0000038a,0x00000000, + 0x00030047,0x0000038b,0x00000000,0x00030047,0x00000390,0x00000000,0x00030047,0x00000392, + 0x00000000,0x00030047,0x00000394,0x00000000,0x00030047,0x00000395,0x00000000,0x00030047, + 0x00000398,0x00000000,0x00030047,0x00000399,0x00000000,0x00030047,0x0000039a,0x00000000, + 0x00030047,0x0000039b,0x00000000,0x00030047,0x000003a2,0x00000000,0x00030047,0x000003a4, + 0x00000000,0x00030047,0x000003a5,0x00000000,0x00030047,0x000003a7,0x00000000,0x00030047, + 0x000003a8,0x00000000,0x00030047,0x000003aa,0x00000000,0x00030047,0x000003ab,0x00000000, + 0x00030047,0x000003b5,0x00000000,0x00030047,0x000003b7,0x00000000,0x00030047,0x000003b8, + 0x00000000,0x00030047,0x000003bb,0x00000000,0x00030047,0x000003bc,0x00000000,0x00030047, + 0x000003be,0x00000000,0x00030047,0x000003c0,0x00000000,0x00030047,0x000003c2,0x00000000, + 0x00030047,0x000003d0,0x00000000,0x00030047,0x000003d1,0x00000000,0x00030047,0x000003d4, + 0x00000000,0x00030047,0x000003d5,0x00000000,0x00030047,0x000003d6,0x00000000,0x00030047, + 0x000003d8,0x00000000,0x00030047,0x000003da,0x00000000,0x00030047,0x000003dc,0x00000000, + 0x00030047,0x000003de,0x00000000,0x00030047,0x000003e0,0x00000000,0x00030047,0x000003ee, + 0x00000000,0x00030047,0x000003f0,0x00000000,0x00030047,0x000003f1,0x00000000,0x00030047, + 0x000003fb,0x00000000,0x00030047,0x000003fd,0x00000000,0x00030047,0x000003fe,0x00000000, + 0x00030047,0x00000401,0x00000000,0x00030047,0x00000402,0x00000000,0x00030047,0x00000404, + 0x00000000,0x00030047,0x00000406,0x00000000,0x00030047,0x00000408,0x00000000,0x00030047, + 0x00000409,0x00000000,0x00030047,0x0000040a,0x00000000,0x00030047,0x0000040d,0x00000000, + 0x00030047,0x0000040e,0x00000000,0x00030047,0x00000410,0x00000000,0x00030047,0x00000411, + 0x00000000,0x00030047,0x00000412,0x00000000,0x00030047,0x00000416,0x00000000,0x00030047, + 0x00000417,0x00000000,0x00030047,0x00000419,0x00000000,0x00030047,0x0000041a,0x00000000, + 0x00030047,0x0000041b,0x00000000,0x00030047,0x0000041d,0x00000000,0x00030047,0x0000041f, + 0x00000000,0x00030047,0x00000420,0x00000000,0x00030047,0x00000421,0x00000000,0x00030047, + 0x00000422,0x00000000,0x00030047,0x0000042c,0x00000000,0x00030047,0x0000042d,0x00000000, + 0x00030047,0x0000042e,0x00000000,0x00030047,0x0000042f,0x00000000,0x00030047,0x00000430, + 0x00000000,0x00030047,0x00000431,0x00000000,0x00030047,0x00000432,0x00000000,0x00030047, + 0x00000433,0x00000000,0x00030047,0x00000435,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007, + 0x00000006,0x00040017,0x0000000c,0x00000006,0x00000004,0x00040020,0x0000000d,0x00000007, + 0x0000000c,0x00040017,0x00000012,0x00000006,0x00000002,0x00040020,0x00000013,0x00000007, + 0x00000012,0x00040015,0x00000018,0x00000020,0x00000000,0x00040020,0x00000019,0x00000007, + 0x00000018,0x00040018,0x00000029,0x00000012,0x00000002,0x00040017,0x00000038,0x00000006, + 0x00000003,0x00040020,0x00000039,0x00000007,0x00000038,0x00040015,0x0000004e,0x00000020, + 0x00000001,0x00040017,0x0000004f,0x0000004e,0x00000002,0x00040020,0x00000050,0x00000007, + 0x0000004f,0x0004002b,0x00000018,0x00000077,0x00000000,0x0004002b,0x00000018,0x0000007a, + 0x00000001,0x0004002b,0x00000018,0x00000085,0x00000002,0x0004002b,0x00000018,0x00000088, + 0x00000003,0x0004002b,0x00000006,0x00000091,0x3f800000,0x0004002b,0x00000006,0x00000092, + 0x00000000,0x0004002b,0x00000006,0x000000ac,0x3d897143,0x0004002b,0x00000006,0x000000b0, + 0x3bbf4590,0x0004002b,0x00000006,0x000000b7,0x4253ee82,0x00020014,0x000000c2,0x00030030, + 0x000000c2,0x000000c3,0x0004002b,0x00000006,0x000000d8,0x3a000000,0x0004002b,0x00000006, + 0x000000da,0xc2000000,0x0004002b,0x00000006,0x000000ea,0x3a808081,0x00040017,0x000000ed, + 0x000000c2,0x00000002,0x00040017,0x000000f7,0x00000018,0x00000002,0x00040020,0x000000f8, + 0x00000007,0x000000f7,0x0003001d,0x000000fa,0x000000f7,0x0003001e,0x000000fb,0x000000fa, + 0x00040020,0x000000fc,0x00000002,0x000000fb,0x0004003b,0x000000fc,0x000000fd,0x00000002, + 0x0004002b,0x0000004e,0x000000fe,0x00000000,0x00040020,0x00000100,0x00000002,0x000000f7, + 0x0004002b,0x00000018,0x00000107,0x00000300,0x00030030,0x000000c2,0x0000010e,0x0004002b, + 0x00000018,0x00000113,0x00000200,0x0004002b,0x00000006,0x0000011a,0x3f000000,0x0004002b, + 0x00000006,0x0000011d,0x40000000,0x0004002b,0x00000006,0x0000011f,0xbf800000,0x00030030, + 0x000000c2,0x00000129,0x0004002b,0x00000018,0x0000012f,0x00000010,0x00090019,0x00000135, + 0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020, + 0x00000136,0x00000000,0x00000135,0x0004003b,0x00000136,0x00000137,0x00000000,0x0005002c, + 0x0000004f,0x00000139,0x000000fe,0x000000fe,0x00030030,0x000000c2,0x00000142,0x0004002b, + 0x00000018,0x00000147,0x00000400,0x00040020,0x0000014d,0x00000007,0x00000029,0x0003001d, + 0x0000014f,0x0000000c,0x0003001e,0x00000150,0x0000014f,0x00040020,0x00000151,0x00000002, + 0x00000150,0x0004003b,0x00000151,0x00000152,0x00000002,0x0004002b,0x00000018,0x00000154, + 0x00000004,0x00040020,0x00000158,0x00000002,0x0000000c,0x00040020,0x00000164,0x00000001, + 0x0000000c,0x0004003b,0x00000164,0x00000165,0x00000001,0x0004002b,0x00000018,0x00000185, + 0x0000000f,0x00090019,0x000001ce,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x000001cf,0x00000000,0x000001ce,0x0004003b,0x000001cf, + 0x000001d0,0x00000000,0x0002001a,0x000001d2,0x00040020,0x000001d3,0x00000000,0x000001d2, + 0x0004003b,0x000001d3,0x000001d4,0x00000000,0x0003001b,0x000001d6,0x000001ce,0x00040020, + 0x000001ec,0x00000003,0x0000000c,0x0004003b,0x000001ec,0x000001ed,0x00000003,0x0004003b, + 0x000001cf,0x000001f5,0x00000000,0x0004003b,0x000001d3,0x000001f7,0x00000000,0x00040020, + 0x000001fa,0x00000001,0x00000012,0x0004003b,0x000001fa,0x000001fb,0x00000001,0x00040020, + 0x000001ff,0x00000001,0x00000006,0x0004003b,0x000001ff,0x00000200,0x00000001,0x0004003b, + 0x00000164,0x00000207,0x00000001,0x00090019,0x00000213,0x00000018,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x00000214,0x00000000,0x00000213, + 0x0004003b,0x00000214,0x00000215,0x00000000,0x00040017,0x00000218,0x00000018,0x00000004, + 0x0004002b,0x00000018,0x0000021d,0x00000011,0x0004002b,0x00000018,0x00000226,0x0001ffff, + 0x0004001e,0x0000023c,0x00000006,0x00000018,0x00040020,0x0000023d,0x00000002,0x0000023c, + 0x0004003b,0x0000023d,0x0000023e,0x00000002,0x00040020,0x00000240,0x00000002,0x00000018, + 0x00040020,0x0000025f,0x00000002,0x00000006,0x0004001e,0x0000026e,0x00000006,0x00000006, + 0x00040020,0x0000026f,0x00000002,0x0000026e,0x0004003b,0x0000026f,0x00000270,0x00000002, + 0x0004003b,0x000001ec,0x00000286,0x00000003,0x0004002b,0x00000018,0x0000028f,0x00010000, + 0x0007002c,0x00000218,0x00000290,0x0000028f,0x0000028f,0x0000028f,0x0000028f,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000007, + 0x00000420,0x00000007,0x0004003b,0x00000007,0x00000421,0x00000007,0x0004003b,0x00000007, + 0x00000422,0x00000007,0x0004003b,0x00000039,0x0000040e,0x00000007,0x0004003b,0x00000013, + 0x0000040f,0x00000007,0x0004003b,0x00000007,0x00000410,0x00000007,0x0004003b,0x00000007, + 0x00000411,0x00000007,0x0004003b,0x00000039,0x00000412,0x00000007,0x0004003b,0x00000007, + 0x00000409,0x00000007,0x0004003b,0x00000007,0x0000040a,0x00000007,0x0004003b,0x00000013, + 0x00000401,0x00000007,0x0004003b,0x00000013,0x00000402,0x00000007,0x0004003b,0x00000007, + 0x000003ee,0x00000007,0x0004003b,0x0000014d,0x000003e1,0x00000007,0x0004003b,0x0000000d, + 0x000003d5,0x00000007,0x0004003b,0x0000000d,0x000003d6,0x00000007,0x0004003b,0x00000013, + 0x000003d0,0x00000007,0x0004003b,0x00000013,0x000003d1,0x00000007,0x0004003b,0x0000014d, + 0x000003c3,0x00000007,0x0004003b,0x00000013,0x000003bb,0x00000007,0x0004003b,0x00000013, + 0x000003bc,0x00000007,0x0004003b,0x00000007,0x000003a8,0x00000007,0x0004003b,0x00000007, + 0x000003a5,0x00000007,0x0004003b,0x00000007,0x000003a2,0x00000007,0x0004003b,0x000000f8, + 0x000002d3,0x00000007,0x0004003b,0x00000007,0x000002d4,0x00000007,0x0004003b,0x00000007, + 0x000002d5,0x00000007,0x0004003b,0x00000007,0x000002d6,0x00000007,0x0004003b,0x00000019, + 0x000002d7,0x00000007,0x0004003b,0x00000019,0x000002d8,0x00000007,0x0004003b,0x0000000d, + 0x000002d9,0x00000007,0x0004003b,0x00000007,0x000002da,0x00000007,0x0004003b,0x0000014d, + 0x000002db,0x00000007,0x0004003b,0x0000000d,0x000002dc,0x00000007,0x0004003b,0x0000000d, + 0x000002dd,0x00000007,0x0004003b,0x00000013,0x000002de,0x00000007,0x0004003b,0x00000013, + 0x000002df,0x00000007,0x0004003b,0x00000013,0x000002e0,0x00000007,0x0004003b,0x00000007, + 0x000002e1,0x00000007,0x0004003b,0x00000019,0x000002e2,0x00000007,0x0004003b,0x00000007, + 0x000002e3,0x00000007,0x0004003b,0x0000014d,0x000002e4,0x00000007,0x0004003b,0x0000000d, + 0x000002e5,0x00000007,0x0004003b,0x0000000d,0x000002e6,0x00000007,0x0004003b,0x00000013, + 0x000002e7,0x00000007,0x0004003b,0x00000007,0x000002e8,0x00000007,0x0004003b,0x00000007, + 0x000002e9,0x00000007,0x0004003b,0x00000007,0x000002ea,0x00000007,0x0004003b,0x00000007, + 0x000002eb,0x00000007,0x0004003b,0x0000000d,0x000002c7,0x00000007,0x0004003b,0x0000000d, + 0x000002c8,0x00000007,0x0004003b,0x00000007,0x000002c2,0x00000007,0x0004003b,0x00000007, + 0x000002c3,0x00000007,0x0004003b,0x00000007,0x000002ba,0x00000007,0x0004003b,0x00000007, + 0x000002bb,0x00000007,0x0004003b,0x00000019,0x000002b7,0x00000007,0x0004003b,0x00000019, + 0x000002b2,0x00000007,0x0004003b,0x00000019,0x000002b3,0x00000007,0x0004003b,0x00000007, + 0x000002af,0x00000007,0x0004003b,0x00000013,0x000002a0,0x00000007,0x0004003b,0x00000007, + 0x000002a1,0x00000007,0x0004003b,0x00000007,0x000002a2,0x00000007,0x0004003b,0x0000000d, + 0x0000029b,0x00000007,0x0004003b,0x0000000d,0x0000029c,0x00000007,0x0004003b,0x00000050, + 0x000001ef,0x00000007,0x0004003b,0x0000000d,0x000001f4,0x00000007,0x0004003b,0x00000007, + 0x000001fe,0x00000007,0x0004003b,0x00000007,0x00000206,0x00000007,0x0004003b,0x0000000d, + 0x00000208,0x00000007,0x0004003b,0x0000000d,0x0000020b,0x00000007,0x0004003b,0x00000007, + 0x0000020e,0x00000007,0x0004003b,0x00000019,0x00000212,0x00000007,0x0004003b,0x00000019, + 0x0000021b,0x00000007,0x0004003b,0x00000019,0x0000021f,0x00000007,0x0004003b,0x00000019, + 0x00000221,0x00000007,0x0004003b,0x00000007,0x00000224,0x00000007,0x0004003b,0x00000019, + 0x00000228,0x00000007,0x0004003b,0x0000000d,0x0000022a,0x00000007,0x0004003b,0x00000007, + 0x0000022b,0x00000007,0x0004003b,0x0000000d,0x0000022d,0x00000007,0x0004003b,0x00000019, + 0x0000022e,0x00000007,0x0004003b,0x00000007,0x00000230,0x00000007,0x0004003b,0x0000000d, + 0x00000232,0x00000007,0x0004003b,0x0000000d,0x00000233,0x00000007,0x0004003b,0x0000000d, + 0x00000247,0x00000007,0x0004003b,0x0000000d,0x0000024b,0x00000007,0x0004003b,0x00000019, + 0x00000253,0x00000007,0x0004003b,0x0000000d,0x00000256,0x00000007,0x0004003b,0x00000007, + 0x00000258,0x00000007,0x0004003b,0x00000007,0x0000025e,0x00000007,0x0004003b,0x00000039, + 0x00000273,0x00000007,0x0004003b,0x00000013,0x00000276,0x00000007,0x0004003b,0x00000007, + 0x00000279,0x00000007,0x0004003b,0x00000007,0x0000027c,0x00000007,0x0004003b,0x0000000d, + 0x00000288,0x00000007,0x0004003d,0x0000000c,0x000001f0,0x00000165,0x0007004f,0x00000012, + 0x000001f1,0x000001f0,0x000001f0,0x00000000,0x00000001,0x0006000c,0x00000012,0x000001f2, + 0x00000001,0x00000008,0x000001f1,0x0004006e,0x0000004f,0x000001f3,0x000001f2,0x0003003e, + 0x000001ef,0x000001f3,0x0004003d,0x000001ce,0x000001f6,0x000001f5,0x0004003d,0x000001d2, + 0x000001f8,0x000001f7,0x00050056,0x000001d6,0x000001f9,0x000001f6,0x000001f8,0x0004003d, + 0x00000012,0x000001fc,0x000001fb,0x00050057,0x0000000c,0x000001fd,0x000001f9,0x000001fc, + 0x0003003e,0x000001f4,0x000001fd,0x0003003e,0x000001fe,0x00000091,0x0004003d,0x00000006, + 0x00000201,0x00000200,0x0004003d,0x00000006,0x00000202,0x000001fe,0x0007000c,0x00000006, + 0x00000203,0x00000001,0x00000025,0x00000201,0x00000202,0x0003003e,0x000001fe,0x00000203, + 0x000300f7,0x00000205,0x00000000,0x000400fa,0x00000142,0x00000204,0x00000205,0x000200f8, + 0x00000204,0x0004003d,0x0000000c,0x00000209,0x00000207,0x0003003e,0x00000208,0x00000209, + 0x0004003d,0x0000000c,0x0000029e,0x00000208,0x0003003e,0x0000029b,0x0000029e,0x0004003d, + 0x0000000c,0x0000029f,0x0000029b,0x0003003e,0x0000029c,0x0000029f,0x0004003d,0x0000000c, + 0x0000020a,0x0000029c,0x0003003e,0x0000020b,0x0000020a,0x0004003d,0x0000000c,0x000002a4, + 0x0000020b,0x0007004f,0x00000012,0x000002a5,0x000002a4,0x000002a4,0x00000000,0x00000001, + 0x0004003d,0x0000000c,0x000002a6,0x0000020b,0x0007004f,0x00000012,0x000002a7,0x000002a6, + 0x000002a6,0x00000002,0x00000003,0x0007000c,0x00000012,0x000002a8,0x00000001,0x00000025, + 0x000002a5,0x000002a7,0x0003003e,0x000002a0,0x000002a8,0x00050041,0x00000007,0x000002a9, + 0x000002a0,0x00000077,0x0004003d,0x00000006,0x000002aa,0x000002a9,0x00050041,0x00000007, + 0x000002ab,0x000002a0,0x0000007a,0x0004003d,0x00000006,0x000002ac,0x000002ab,0x0007000c, + 0x00000006,0x000002ad,0x00000001,0x00000025,0x000002aa,0x000002ac,0x0003003e,0x000002a1, + 0x000002ad,0x0004003d,0x00000006,0x000002ae,0x000002a1,0x0003003e,0x000002a2,0x000002ae, + 0x0004003d,0x00000006,0x0000020c,0x000002a2,0x0003003e,0x00000206,0x0000020c,0x0004003d, + 0x00000006,0x0000020d,0x00000206,0x0003003e,0x0000020e,0x00000092,0x0004003d,0x00000006, + 0x000002b1,0x0000020e,0x0003003e,0x000002af,0x000002b1,0x0004003d,0x00000006,0x0000020f, + 0x000002af,0x0004003d,0x00000006,0x00000210,0x000001fe,0x0008000c,0x00000006,0x00000211, + 0x00000001,0x0000002b,0x0000020d,0x0000020f,0x00000210,0x0003003e,0x000001fe,0x00000211, + 0x000200f9,0x00000205,0x000200f8,0x00000205,0x0004003d,0x00000213,0x00000216,0x00000215, + 0x0004003d,0x0000004f,0x00000217,0x000001ef,0x00050062,0x00000218,0x00000219,0x00000216, + 0x00000217,0x00050051,0x00000018,0x0000021a,0x00000219,0x00000000,0x0003003e,0x00000212, + 0x0000021a,0x0004003d,0x00000018,0x0000021c,0x00000212,0x000500c2,0x00000018,0x0000021e, + 0x0000021c,0x0000021d,0x0003003e,0x0000021f,0x0000021e,0x0004003d,0x00000018,0x000002b5, + 0x0000021f,0x0003003e,0x000002b2,0x000002b5,0x0004003d,0x00000018,0x000002b6,0x000002b2, + 0x0003003e,0x000002b3,0x000002b6,0x0004003d,0x00000018,0x00000220,0x000002b3,0x0003003e, + 0x0000021b,0x00000220,0x0004003d,0x00000018,0x00000222,0x0000021b,0x0003003e,0x00000221, + 0x00000222,0x0004003d,0x00000018,0x000002b9,0x00000221,0x0003003e,0x000002b7,0x000002b9, + 0x0004003d,0x00000018,0x00000223,0x000002b7,0x0003003e,0x0000021b,0x00000223,0x0004003d, + 0x00000018,0x00000225,0x00000212,0x000500c7,0x00000018,0x00000227,0x00000225,0x00000226, + 0x0003003e,0x00000228,0x00000227,0x0004003d,0x00000018,0x000002bd,0x00000228,0x00040070, + 0x00000006,0x000002be,0x000002bd,0x00050085,0x00000006,0x000002bf,0x000002be,0x000000d8, + 0x00050081,0x00000006,0x000002c0,0x000002bf,0x000000da,0x0003003e,0x000002ba,0x000002c0, + 0x0004003d,0x00000006,0x000002c5,0x000002ba,0x0003003e,0x000002c2,0x000002c5,0x0004003d, + 0x00000006,0x000002c6,0x000002c2,0x0003003e,0x000002c3,0x000002c6,0x0004003d,0x00000006, + 0x000002c1,0x000002c3,0x0003003e,0x000002bb,0x000002c1,0x0004003d,0x00000006,0x00000229, + 0x000002bb,0x0003003e,0x00000224,0x00000229,0x0003003e,0x0000022b,0x00000092,0x0004003d, + 0x00000006,0x000002ca,0x0000022b,0x00050041,0x00000007,0x000002cb,0x000002c7,0x00000077, + 0x0003003e,0x000002cb,0x000002ca,0x0004003d,0x00000006,0x000002cc,0x0000022b,0x00050041, + 0x00000007,0x000002cd,0x000002c7,0x0000007a,0x0003003e,0x000002cd,0x000002cc,0x0004003d, + 0x00000006,0x000002ce,0x0000022b,0x00050041,0x00000007,0x000002cf,0x000002c7,0x00000085, + 0x0003003e,0x000002cf,0x000002ce,0x0004003d,0x00000006,0x000002d0,0x0000022b,0x00050041, + 0x00000007,0x000002d1,0x000002c7,0x00000088,0x0003003e,0x000002d1,0x000002d0,0x0004003d, + 0x0000000c,0x000002d2,0x000002c7,0x0003003e,0x000002c8,0x000002d2,0x0004003d,0x0000000c, + 0x0000022c,0x000002c8,0x0003003e,0x0000022a,0x0000022c,0x0004003d,0x00000018,0x0000022f, + 0x0000021b,0x0003003e,0x0000022e,0x0000022f,0x0004003d,0x00000006,0x00000231,0x00000224, + 0x0003003e,0x00000230,0x00000231,0x0004003d,0x0000000c,0x00000234,0x0000022a,0x0003003e, + 0x00000233,0x00000234,0x0004003d,0x00000018,0x000002ed,0x0000022e,0x00060041,0x00000100, + 0x000002ee,0x000000fd,0x000000fe,0x000002ed,0x0004003d,0x000000f7,0x000002ef,0x000002ee, + 0x0003003e,0x000002d3,0x000002ef,0x0004003d,0x00000006,0x000002f0,0x00000230,0x0003003e, + 0x000002d4,0x000002f0,0x00050041,0x00000019,0x000002f1,0x000002d3,0x00000077,0x0004003d, + 0x00000018,0x000002f2,0x000002f1,0x000500c7,0x00000018,0x000002f3,0x000002f2,0x00000107, + 0x000500ab,0x000000c2,0x000002f4,0x000002f3,0x00000077,0x000300f7,0x00000308,0x00000000, + 0x000400fa,0x000002f4,0x000002f5,0x00000308,0x000200f8,0x000002f5,0x0004003d,0x00000006, + 0x000002f6,0x000002d4,0x0006000c,0x00000006,0x000002f7,0x00000001,0x00000004,0x000002f6, + 0x0003003e,0x000002d4,0x000002f7,0x000300f7,0x000002fd,0x00000000,0x000400fa,0x0000010e, + 0x000002f8,0x000002fd,0x000200f8,0x000002f8,0x0004003d,0x00000018,0x000002fa,0x000002f1, + 0x000500c7,0x00000018,0x000002fb,0x000002fa,0x00000113,0x000500ab,0x000000c2,0x000002fc, + 0x000002fb,0x00000077,0x000200f9,0x000002fd,0x000200f8,0x000002fd,0x000700f5,0x000000c2, + 0x000002fe,0x0000010e,0x000002f5,0x000002fc,0x000002f8,0x000300f7,0x00000307,0x00000000, + 0x000400fa,0x000002fe,0x000002ff,0x00000307,0x000200f8,0x000002ff,0x0004003d,0x00000006, + 0x00000300,0x000002d4,0x00050085,0x00000006,0x00000301,0x00000300,0x0000011a,0x0006000c, + 0x00000006,0x00000302,0x00000001,0x0000000a,0x00000301,0x00050085,0x00000006,0x00000303, + 0x00000302,0x0000011d,0x00050081,0x00000006,0x00000304,0x00000303,0x0000011f,0x0006000c, + 0x00000006,0x00000305,0x00000001,0x00000004,0x00000304,0x00050083,0x00000006,0x00000306, + 0x00000091,0x00000305,0x0003003e,0x000002d4,0x00000306,0x000200f9,0x00000307,0x000200f8, + 0x00000307,0x000200f9,0x00000308,0x000200f8,0x00000308,0x0004003d,0x00000006,0x00000309, + 0x000002d4,0x0003003e,0x000002d5,0x00000092,0x0004003d,0x00000006,0x000003a4,0x000002d5, + 0x0003003e,0x000003a2,0x000003a4,0x0004003d,0x00000006,0x0000030a,0x000003a2,0x0003003e, + 0x000002d6,0x00000091,0x0004003d,0x00000006,0x000003a7,0x000002d6,0x0003003e,0x000003a5, + 0x000003a7,0x0004003d,0x00000006,0x0000030b,0x000003a5,0x0008000c,0x00000006,0x0000030c, + 0x00000001,0x0000002b,0x00000309,0x0000030a,0x0000030b,0x0003003e,0x000002d4,0x0000030c, + 0x000300f7,0x0000031b,0x00000000,0x000400fa,0x00000129,0x0000030d,0x0000031b,0x000200f8, + 0x0000030d,0x0004003d,0x00000018,0x0000030f,0x000002f1,0x000500c2,0x00000018,0x00000310, + 0x0000030f,0x0000012f,0x0003003e,0x000002d7,0x00000310,0x0004003d,0x00000018,0x00000311, + 0x000002d7,0x000500ab,0x000000c2,0x00000312,0x00000311,0x00000077,0x000300f7,0x0000031a, + 0x00000000,0x000400fa,0x00000312,0x00000313,0x0000031a,0x000200f8,0x00000313,0x0004003d, + 0x00000135,0x00000314,0x00000137,0x00050062,0x0000000c,0x00000315,0x00000314,0x00000139, + 0x0004003d,0x00000018,0x00000316,0x000002d7,0x0003003e,0x000002d8,0x00000316,0x0003003e, + 0x000002d9,0x00000315,0x0004003d,0x00000006,0x00000317,0x000002d4,0x0003003e,0x000002da, + 0x00000317,0x0004003d,0x0000000c,0x000003aa,0x000002d9,0x0007004f,0x00000012,0x000003ab, + 0x000003aa,0x000003aa,0x00000000,0x00000001,0x0004003d,0x00000018,0x000003ac,0x000002d8, + 0x0006000c,0x0000000c,0x000003ad,0x00000001,0x00000040,0x000003ac,0x0007004f,0x00000012, + 0x000003ae,0x000003ad,0x000003ad,0x00000000,0x00000001,0x00050083,0x00000012,0x000003af, + 0x000003ab,0x000003ae,0x0006000c,0x00000012,0x000003b0,0x00000001,0x00000004,0x000003af, + 0x0003003e,0x000003a8,0x000000ea,0x0004003d,0x00000006,0x000003be,0x000003a8,0x00050041, + 0x00000007,0x000003bf,0x000003bb,0x00000077,0x0003003e,0x000003bf,0x000003be,0x0004003d, + 0x00000006,0x000003c0,0x000003a8,0x00050041,0x00000007,0x000003c1,0x000003bb,0x0000007a, + 0x0003003e,0x000003c1,0x000003c0,0x0004003d,0x00000012,0x000003c2,0x000003bb,0x0003003e, + 0x000003bc,0x000003c2,0x0004003d,0x00000012,0x000003b1,0x000003bc,0x000500b8,0x000000ed, + 0x000003b2,0x000003b0,0x000003b1,0x0004009b,0x000000c2,0x000003b3,0x000003b2,0x000300f7, + 0x000003ba,0x00000000,0x000400fa,0x000003b3,0x000003b4,0x000003b9,0x000200f8,0x000003b4, + 0x0004003d,0x00000006,0x000003b5,0x000002da,0x00050041,0x00000007,0x000003b6,0x000002d9, + 0x00000085,0x0004003d,0x00000006,0x000003b7,0x000003b6,0x0007000c,0x00000006,0x000003b8, + 0x00000001,0x00000025,0x000003b5,0x000003b7,0x0003003e,0x000002da,0x000003b8,0x000200f9, + 0x000003ba,0x000200f8,0x000003b9,0x0003003e,0x000002da,0x00000092,0x000200f9,0x000003ba, + 0x000200f8,0x000003ba,0x0004003d,0x00000006,0x00000319,0x000002da,0x0003003e,0x000002d4, + 0x00000319,0x000200f9,0x0000031a,0x000200f8,0x0000031a,0x000200f9,0x0000031b,0x000200f8, + 0x0000031b,0x000300f7,0x00000321,0x00000000,0x000400fa,0x00000142,0x0000031c,0x00000321, + 0x000200f8,0x0000031c,0x0004003d,0x00000018,0x0000031e,0x000002f1,0x000500c7,0x00000018, + 0x0000031f,0x0000031e,0x00000147,0x000500ab,0x000000c2,0x00000320,0x0000031f,0x00000077, + 0x000200f9,0x00000321,0x000200f8,0x00000321,0x000700f5,0x000000c2,0x00000322,0x00000142, + 0x0000031b,0x00000320,0x0000031c,0x000300f7,0x00000349,0x00000000,0x000400fa,0x00000322, + 0x00000323,0x00000349,0x000200f8,0x00000323,0x0004003d,0x00000018,0x00000324,0x0000022e, + 0x00050084,0x00000018,0x00000325,0x00000324,0x00000154,0x00050080,0x00000018,0x00000326, + 0x00000325,0x00000085,0x00060041,0x00000158,0x00000327,0x00000152,0x000000fe,0x00000326, + 0x0004003d,0x0000000c,0x00000328,0x00000327,0x0003003e,0x000002dc,0x00000328,0x0004003d, + 0x0000000c,0x000003c5,0x000002dc,0x0004003d,0x0000000c,0x000003c7,0x000002dc,0x00050051, + 0x00000006,0x000003c9,0x000003c5,0x00000000,0x00050051,0x00000006,0x000003ca,0x000003c5, + 0x00000001,0x00050051,0x00000006,0x000003cb,0x000003c7,0x00000002,0x00050051,0x00000006, + 0x000003cc,0x000003c7,0x00000003,0x00050050,0x00000012,0x000003cd,0x000003c9,0x000003ca, + 0x00050050,0x00000012,0x000003ce,0x000003cb,0x000003cc,0x00050050,0x00000029,0x000003cf, + 0x000003cd,0x000003ce,0x0003003e,0x000003c3,0x000003cf,0x0004003d,0x00000029,0x00000329, + 0x000003c3,0x0003003e,0x000002db,0x00000329,0x0004003d,0x00000018,0x0000032a,0x0000022e, + 0x00050084,0x00000018,0x0000032b,0x0000032a,0x00000154,0x00050080,0x00000018,0x0000032c, + 0x0000032b,0x00000088,0x00060041,0x00000158,0x0000032d,0x00000152,0x000000fe,0x0000032c, + 0x0004003d,0x0000000c,0x0000032e,0x0000032d,0x0003003e,0x000002dd,0x0000032e,0x0004003d, + 0x00000029,0x0000032f,0x000002db,0x00050091,0x00000012,0x00000332,0x0000032f,0x000001f1, + 0x0004003d,0x0000000c,0x00000333,0x000002dd,0x0007004f,0x00000012,0x00000334,0x00000333, + 0x00000333,0x00000000,0x00000001,0x00050081,0x00000012,0x00000335,0x00000332,0x00000334, + 0x0003003e,0x000002de,0x00000335,0x0004003d,0x00000012,0x00000336,0x000002de,0x0006000c, + 0x00000012,0x00000337,0x00000001,0x00000004,0x00000336,0x0004003d,0x0000000c,0x00000338, + 0x000002dd,0x0007004f,0x00000012,0x00000339,0x00000338,0x00000338,0x00000002,0x00000003, + 0x00050085,0x00000012,0x0000033a,0x00000337,0x00000339,0x0004003d,0x0000000c,0x0000033b, + 0x000002dd,0x0007004f,0x00000012,0x0000033c,0x0000033b,0x0000033b,0x00000002,0x00000003, + 0x00050083,0x00000012,0x0000033d,0x0000033a,0x0000033c,0x0003003e,0x000002e0,0x0000033d, + 0x0004003d,0x00000012,0x000003d3,0x000002e0,0x0003003e,0x000003d0,0x000003d3,0x0004003d, + 0x00000012,0x000003d4,0x000003d0,0x0003003e,0x000003d1,0x000003d4,0x0004003d,0x00000012, + 0x0000033e,0x000003d1,0x0003003e,0x000002df,0x0000033e,0x00050041,0x00000007,0x0000033f, + 0x000002df,0x00000077,0x0004003d,0x00000006,0x00000340,0x0000033f,0x00050041,0x00000007, + 0x00000341,0x000002df,0x0000007a,0x0004003d,0x00000006,0x00000342,0x00000341,0x0007000c, + 0x00000006,0x00000343,0x00000001,0x00000025,0x00000340,0x00000342,0x00050081,0x00000006, + 0x00000344,0x00000343,0x0000011a,0x0008000c,0x00000006,0x00000345,0x00000001,0x0000002b, + 0x00000344,0x00000092,0x00000091,0x0003003e,0x000002e1,0x00000345,0x0004003d,0x00000006, + 0x00000346,0x000002d4,0x0004003d,0x00000006,0x00000347,0x000002e1,0x0007000c,0x00000006, + 0x00000348,0x00000001,0x00000025,0x00000346,0x00000347,0x0003003e,0x000002d4,0x00000348, + 0x000200f9,0x00000349,0x000200f8,0x00000349,0x0004003d,0x00000018,0x0000034b,0x000002f1, + 0x000500c7,0x00000018,0x0000034c,0x0000034b,0x00000185,0x0003003e,0x000002e2,0x0000034c, + 0x0004003d,0x00000018,0x0000034d,0x000002e2,0x000500b2,0x000000c2,0x0000034e,0x0000034d, + 0x0000007a,0x000300f7,0x00000391,0x00000000,0x000400fa,0x0000034e,0x0000034f,0x00000362, + 0x000200f8,0x0000034f,0x00050041,0x00000019,0x00000350,0x000002d3,0x0000007a,0x0004003d, + 0x00000018,0x00000351,0x00000350,0x0006000c,0x0000000c,0x00000352,0x00000001,0x00000040, + 0x00000351,0x0003003e,0x00000232,0x00000352,0x0004003d,0x00000018,0x00000353,0x000002e2, + 0x000500aa,0x000000c2,0x00000354,0x00000353,0x00000077,0x000500a7,0x000000c2,0x00000355, + 0x00000129,0x00000354,0x000300f7,0x00000361,0x00000000,0x000400fa,0x00000355,0x00000356, + 0x00000361,0x000200f8,0x00000356,0x0004003d,0x0000000c,0x00000357,0x00000232,0x00050041, + 0x00000007,0x00000359,0x00000233,0x00000077,0x00050051,0x00000006,0x0000035a,0x00000357, + 0x00000002,0x0003003e,0x00000359,0x0000035a,0x00050041,0x00000007,0x0000035b,0x00000233, + 0x0000007a,0x00050051,0x00000006,0x0000035c,0x00000357,0x00000003,0x0003003e,0x0000035b, + 0x0000035c,0x0004003d,0x00000006,0x0000035d,0x000002d4,0x00050041,0x00000007,0x0000035e, + 0x00000233,0x00000085,0x0003003e,0x0000035e,0x0000035d,0x00050041,0x00000007,0x0000035f, + 0x00000233,0x00000088,0x0003003e,0x0000035f,0x00000091,0x0003003e,0x000002e3,0x00000092, + 0x0004003d,0x00000006,0x000003d8,0x000002e3,0x00050041,0x00000007,0x000003d9,0x000003d5, + 0x00000077,0x0003003e,0x000003d9,0x000003d8,0x0004003d,0x00000006,0x000003da,0x000002e3, + 0x00050041,0x00000007,0x000003db,0x000003d5,0x0000007a,0x0003003e,0x000003db,0x000003da, + 0x0004003d,0x00000006,0x000003dc,0x000002e3,0x00050041,0x00000007,0x000003dd,0x000003d5, + 0x00000085,0x0003003e,0x000003dd,0x000003dc,0x0004003d,0x00000006,0x000003de,0x000002e3, + 0x00050041,0x00000007,0x000003df,0x000003d5,0x00000088,0x0003003e,0x000003df,0x000003de, + 0x0004003d,0x0000000c,0x000003e0,0x000003d5,0x0003003e,0x000003d6,0x000003e0,0x0004003d, + 0x0000000c,0x00000360,0x000003d6,0x0003003e,0x00000232,0x00000360,0x000200f9,0x00000361, + 0x000200f8,0x00000361,0x000200f9,0x00000391,0x000200f8,0x00000362,0x0004003d,0x00000018, + 0x00000363,0x0000022e,0x00050084,0x00000018,0x00000364,0x00000363,0x00000154,0x00060041, + 0x00000158,0x00000365,0x00000152,0x000000fe,0x00000364,0x0004003d,0x0000000c,0x00000366, + 0x00000365,0x0003003e,0x000002e5,0x00000366,0x0004003d,0x0000000c,0x000003e3,0x000002e5, + 0x0004003d,0x0000000c,0x000003e5,0x000002e5,0x00050051,0x00000006,0x000003e7,0x000003e3, + 0x00000000,0x00050051,0x00000006,0x000003e8,0x000003e3,0x00000001,0x00050051,0x00000006, + 0x000003e9,0x000003e5,0x00000002,0x00050051,0x00000006,0x000003ea,0x000003e5,0x00000003, + 0x00050050,0x00000012,0x000003eb,0x000003e7,0x000003e8,0x00050050,0x00000012,0x000003ec, + 0x000003e9,0x000003ea,0x00050050,0x00000029,0x000003ed,0x000003eb,0x000003ec,0x0003003e, + 0x000003e1,0x000003ed,0x0004003d,0x00000029,0x00000367,0x000003e1,0x0003003e,0x000002e4, + 0x00000367,0x0004003d,0x00000018,0x00000368,0x0000022e,0x00050084,0x00000018,0x00000369, + 0x00000368,0x00000154,0x00050080,0x00000018,0x0000036a,0x00000369,0x0000007a,0x00060041, + 0x00000158,0x0000036b,0x00000152,0x000000fe,0x0000036a,0x0004003d,0x0000000c,0x0000036c, + 0x0000036b,0x0003003e,0x000002e6,0x0000036c,0x0004003d,0x00000029,0x0000036d,0x000002e4, + 0x00050091,0x00000012,0x00000370,0x0000036d,0x000001f1,0x0004003d,0x0000000c,0x00000371, + 0x000002e6,0x0007004f,0x00000012,0x00000372,0x00000371,0x00000371,0x00000000,0x00000001, + 0x00050081,0x00000012,0x00000373,0x00000370,0x00000372,0x0003003e,0x000002e7,0x00000373, + 0x0004003d,0x00000018,0x00000374,0x000002e2,0x000500aa,0x000000c2,0x00000375,0x00000374, + 0x00000085,0x000300f7,0x0000037c,0x00000000,0x000400fa,0x00000375,0x00000376,0x00000379, + 0x000200f8,0x00000376,0x00050041,0x00000007,0x00000377,0x000002e7,0x00000077,0x0004003d, + 0x00000006,0x00000378,0x00000377,0x0003003e,0x000002e9,0x00000378,0x000200f9,0x0000037c, + 0x000200f8,0x00000379,0x0004003d,0x00000012,0x0000037a,0x000002e7,0x0006000c,0x00000006, + 0x0000037b,0x00000001,0x00000042,0x0000037a,0x0003003e,0x000002e9,0x0000037b,0x000200f9, + 0x0000037c,0x000200f8,0x0000037c,0x0004003d,0x00000006,0x0000037d,0x000002e9,0x0003003e, + 0x000002e8,0x0000037d,0x0004003d,0x00000006,0x0000037e,0x000002e8,0x0008000c,0x00000006, + 0x0000037f,0x00000001,0x0000002b,0x0000037e,0x00000092,0x00000091,0x0003003e,0x000002e8, + 0x0000037f,0x0004003d,0x00000006,0x00000380,0x000002e8,0x00050041,0x00000007,0x00000381, + 0x000002e6,0x00000085,0x0004003d,0x00000006,0x00000382,0x00000381,0x00050085,0x00000006, + 0x00000383,0x00000380,0x00000382,0x00050041,0x00000007,0x00000384,0x000002e6,0x00000088, + 0x0004003d,0x00000006,0x00000385,0x00000384,0x00050081,0x00000006,0x00000386,0x00000383, + 0x00000385,0x0003003e,0x000002ea,0x00000386,0x00050041,0x00000019,0x00000387,0x000002d3, + 0x0000007a,0x0004003d,0x00000018,0x00000388,0x00000387,0x0004007c,0x00000006,0x00000389, + 0x00000388,0x0003003e,0x000002eb,0x00000389,0x0004003d,0x000001ce,0x0000038a,0x000001d0, + 0x0004003d,0x000001d2,0x0000038b,0x000001d4,0x00050056,0x000001d6,0x0000038c,0x0000038a, + 0x0000038b,0x0004003d,0x00000006,0x0000038d,0x000002ea,0x0004003d,0x00000006,0x0000038e, + 0x000002eb,0x00050050,0x00000012,0x0000038f,0x0000038d,0x0000038e,0x00070058,0x0000000c, + 0x00000390,0x0000038c,0x0000038f,0x00000002,0x00000092,0x0003003e,0x00000232,0x00000390, + 0x000200f9,0x00000391,0x000200f8,0x00000391,0x0004003d,0x00000006,0x00000392,0x000002d4, + 0x00050041,0x00000007,0x00000393,0x00000232,0x00000088,0x0004003d,0x00000006,0x00000394, + 0x00000393,0x00050085,0x00000006,0x00000395,0x00000394,0x00000392,0x0003003e,0x00000393, + 0x00000395,0x0004003d,0x00000006,0x00000398,0x00000393,0x0004003d,0x0000000c,0x00000399, + 0x00000232,0x0008004f,0x00000038,0x0000039a,0x00000399,0x00000399,0x00000000,0x00000001, + 0x00000002,0x0005008e,0x00000038,0x0000039b,0x0000039a,0x00000398,0x00050041,0x00000007, + 0x0000039c,0x00000232,0x00000077,0x00050051,0x00000006,0x0000039d,0x0000039b,0x00000000, + 0x0003003e,0x0000039c,0x0000039d,0x00050041,0x00000007,0x0000039e,0x00000232,0x0000007a, + 0x00050051,0x00000006,0x0000039f,0x0000039b,0x00000001,0x0003003e,0x0000039e,0x0000039f, + 0x00050041,0x00000007,0x000003a0,0x00000232,0x00000085,0x00050051,0x00000006,0x000003a1, + 0x0000039b,0x00000002,0x0003003e,0x000003a0,0x000003a1,0x0004003d,0x0000000c,0x00000238, + 0x00000232,0x0003003e,0x0000022d,0x00000238,0x0004003d,0x0000000c,0x00000239,0x00000233, + 0x0003003e,0x0000022a,0x00000239,0x000300f7,0x0000023b,0x00000000,0x000400fa,0x00000129, + 0x0000023a,0x0000023b,0x000200f8,0x0000023a,0x00050041,0x00000240,0x00000241,0x0000023e, + 0x0000007a,0x0004003d,0x00000018,0x00000242,0x00000241,0x000500ab,0x000000c2,0x00000243, + 0x00000242,0x00000077,0x000200f9,0x0000023b,0x000200f8,0x0000023b,0x000700f5,0x000000c2, + 0x00000244,0x00000129,0x00000391,0x00000243,0x0000023a,0x000300f7,0x00000246,0x00000000, + 0x000400fa,0x00000244,0x00000245,0x00000246,0x000200f8,0x00000245,0x00050041,0x00000007, + 0x00000248,0x0000022a,0x00000088,0x0004003d,0x00000006,0x00000249,0x00000248,0x000500b7, + 0x000000c2,0x0000024a,0x00000249,0x00000092,0x000300f7,0x0000024d,0x00000000,0x000400fa, + 0x0000024a,0x0000024c,0x0000024f,0x000200f8,0x0000024c,0x0004003d,0x0000000c,0x0000024e, + 0x0000022a,0x0003003e,0x0000024b,0x0000024e,0x000200f9,0x0000024d,0x000200f8,0x0000024f, + 0x0004003d,0x00000135,0x00000250,0x00000137,0x00050062,0x0000000c,0x00000251,0x00000250, + 0x00000139,0x0003003e,0x0000024b,0x00000251,0x000200f9,0x0000024d,0x000200f8,0x0000024d, + 0x0004003d,0x0000000c,0x00000252,0x0000024b,0x0003003e,0x00000247,0x00000252,0x00050041, + 0x00000240,0x00000254,0x0000023e,0x0000007a,0x0004003d,0x00000018,0x00000255,0x00000254, + 0x0003003e,0x00000253,0x00000255,0x0004003d,0x0000000c,0x00000257,0x00000247,0x0003003e, + 0x00000256,0x00000257,0x0004003d,0x00000006,0x00000259,0x000001fe,0x0003003e,0x00000258, + 0x00000259,0x0004003d,0x0000000c,0x000003f0,0x00000256,0x0007004f,0x00000012,0x000003f1, + 0x000003f0,0x000003f0,0x00000000,0x00000001,0x0004003d,0x00000018,0x000003f2,0x00000253, + 0x0006000c,0x0000000c,0x000003f3,0x00000001,0x00000040,0x000003f2,0x0007004f,0x00000012, + 0x000003f4,0x000003f3,0x000003f3,0x00000000,0x00000001,0x00050083,0x00000012,0x000003f5, + 0x000003f1,0x000003f4,0x0006000c,0x00000012,0x000003f6,0x00000001,0x00000004,0x000003f5, + 0x0003003e,0x000003ee,0x000000ea,0x0004003d,0x00000006,0x00000404,0x000003ee,0x00050041, + 0x00000007,0x00000405,0x00000401,0x00000077,0x0003003e,0x00000405,0x00000404,0x0004003d, + 0x00000006,0x00000406,0x000003ee,0x00050041,0x00000007,0x00000407,0x00000401,0x0000007a, + 0x0003003e,0x00000407,0x00000406,0x0004003d,0x00000012,0x00000408,0x00000401,0x0003003e, + 0x00000402,0x00000408,0x0004003d,0x00000012,0x000003f7,0x00000402,0x000500b8,0x000000ed, + 0x000003f8,0x000003f6,0x000003f7,0x0004009b,0x000000c2,0x000003f9,0x000003f8,0x000300f7, + 0x00000400,0x00000000,0x000400fa,0x000003f9,0x000003fa,0x000003ff,0x000200f8,0x000003fa, + 0x0004003d,0x00000006,0x000003fb,0x00000258,0x00050041,0x00000007,0x000003fc,0x00000256, + 0x00000085,0x0004003d,0x00000006,0x000003fd,0x000003fc,0x0007000c,0x00000006,0x000003fe, + 0x00000001,0x00000025,0x000003fb,0x000003fd,0x0003003e,0x00000258,0x000003fe,0x000200f9, + 0x00000400,0x000200f8,0x000003ff,0x0003003e,0x00000258,0x00000092,0x000200f9,0x00000400, + 0x000200f8,0x00000400,0x0004003d,0x00000006,0x0000025b,0x00000258,0x0003003e,0x000001fe, + 0x0000025b,0x000200f9,0x00000246,0x000200f8,0x00000246,0x0004003d,0x00000006,0x0000025c, + 0x000001fe,0x00050041,0x0000025f,0x00000260,0x0000023e,0x00000077,0x0004003d,0x00000006, + 0x00000261,0x00000260,0x0003003e,0x0000025e,0x00000261,0x0004003d,0x00000006,0x0000040c, + 0x0000025e,0x0003003e,0x00000409,0x0000040c,0x0004003d,0x00000006,0x0000040d,0x00000409, + 0x0003003e,0x0000040a,0x0000040d,0x0004003d,0x00000006,0x00000262,0x0000040a,0x00050085, + 0x00000006,0x00000263,0x0000025c,0x00000262,0x0004003d,0x0000000c,0x00000264,0x000001f4, + 0x0005008e,0x0000000c,0x00000265,0x00000264,0x00000263,0x0003003e,0x000001f4,0x00000265, + 0x0004003d,0x0000000c,0x00000266,0x0000022d,0x00050041,0x00000007,0x00000267,0x000001f4, + 0x00000088,0x0004003d,0x00000006,0x00000268,0x00000267,0x00050083,0x00000006,0x00000269, + 0x00000091,0x00000268,0x0005008e,0x0000000c,0x0000026a,0x00000266,0x00000269,0x0004003d, + 0x0000000c,0x0000026b,0x000001f4,0x00050081,0x0000000c,0x0000026c,0x0000026a,0x0000026b, + 0x0003003e,0x0000022d,0x0000026c,0x0004003d,0x0000000c,0x00000274,0x0000022d,0x0008004f, + 0x00000038,0x00000275,0x00000274,0x00000274,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x00000273,0x00000275,0x0003003e,0x00000276,0x000001f1,0x00050041,0x0000025f,0x0000027a, + 0x00000270,0x00000077,0x0004003d,0x00000006,0x0000027b,0x0000027a,0x0003003e,0x00000279, + 0x0000027b,0x00050041,0x0000025f,0x0000027d,0x00000270,0x0000007a,0x0004003d,0x00000006, + 0x0000027e,0x0000027d,0x0003003e,0x0000027c,0x0000027e,0x000300f7,0x0000041e,0x00000000, + 0x000400fa,0x000000c3,0x00000414,0x0000041c,0x000200f8,0x00000414,0x0004003d,0x00000012, + 0x00000415,0x00000276,0x0003003e,0x0000040f,0x00000415,0x0004003d,0x00000006,0x00000416, + 0x00000279,0x0003003e,0x00000410,0x00000416,0x0004003d,0x00000006,0x00000417,0x0000027c, + 0x0003003e,0x00000411,0x00000417,0x00050041,0x00000007,0x00000424,0x0000040f,0x00000077, + 0x0004003d,0x00000006,0x00000425,0x00000424,0x00050085,0x00000006,0x00000426,0x000000ac, + 0x00000425,0x00050041,0x00000007,0x00000427,0x0000040f,0x0000007a,0x0004003d,0x00000006, + 0x00000428,0x00000427,0x00050085,0x00000006,0x00000429,0x000000b0,0x00000428,0x00050081, + 0x00000006,0x0000042a,0x00000426,0x00000429,0x0006000c,0x00000006,0x0000042b,0x00000001, + 0x0000000a,0x0000042a,0x0003003e,0x00000420,0x0000042b,0x0004003d,0x00000006,0x0000042c, + 0x00000420,0x00050085,0x00000006,0x0000042d,0x000000b7,0x0000042c,0x0006000c,0x00000006, + 0x0000042e,0x00000001,0x0000000a,0x0000042d,0x0003003e,0x00000421,0x0000042e,0x0004003d, + 0x00000006,0x0000042f,0x00000421,0x0004003d,0x00000006,0x00000430,0x00000410,0x00050085, + 0x00000006,0x00000431,0x0000042f,0x00000430,0x0004003d,0x00000006,0x00000432,0x00000411, + 0x00050081,0x00000006,0x00000433,0x00000431,0x00000432,0x0003003e,0x00000422,0x00000433, + 0x0004003d,0x00000006,0x00000418,0x00000422,0x0004003d,0x00000038,0x00000419,0x00000273, + 0x00060050,0x00000038,0x0000041a,0x00000418,0x00000418,0x00000418,0x00050081,0x00000038, + 0x0000041b,0x0000041a,0x00000419,0x0003003e,0x0000040e,0x0000041b,0x000200f9,0x0000041e, + 0x000200f8,0x0000041c,0x0004003d,0x00000038,0x0000041d,0x00000273,0x0003003e,0x0000040e, + 0x0000041d,0x000200f9,0x0000041e,0x000200f8,0x0000041e,0x0004003d,0x00000038,0x0000041f, + 0x0000040e,0x0003003e,0x00000412,0x0000041f,0x0004003d,0x00000038,0x0000027f,0x00000412, + 0x00050041,0x00000007,0x00000280,0x0000022d,0x00000077,0x00050051,0x00000006,0x00000281, + 0x0000027f,0x00000000,0x0003003e,0x00000280,0x00000281,0x00050041,0x00000007,0x00000282, + 0x0000022d,0x0000007a,0x00050051,0x00000006,0x00000283,0x0000027f,0x00000001,0x0003003e, + 0x00000282,0x00000283,0x00050041,0x00000007,0x00000284,0x0000022d,0x00000085,0x00050051, + 0x00000006,0x00000285,0x0000027f,0x00000002,0x0003003e,0x00000284,0x00000285,0x0004003d, + 0x0000000c,0x00000287,0x0000022d,0x0003003e,0x00000286,0x00000287,0x0004003d,0x0000000c, + 0x00000289,0x0000022a,0x0003003e,0x00000288,0x00000289,0x0004003d,0x0000000c,0x00000435, + 0x00000288,0x0003003e,0x000001ed,0x00000435,0x0004003d,0x00000213,0x0000028d,0x00000215, + 0x0004003d,0x0000004f,0x0000028e,0x000001ef,0x00040063,0x0000028d,0x0000028e,0x00000290, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..de9e81c85c1519c4cbbd46b1a282dc21b97aecd6 GIT binary patch literal 16904 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

5u@#!E5_#e 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.h new file mode 100644 index 000000000..46c15bab4 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.h @@ -0,0 +1,236 @@ +#pragma once + +const uint32_t atomic_draw_image_rect_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000220,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000090,0x00000093,0x00000098, + 0x000000a7,0x000000ff,0x00000121,0x00000143,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00060005,0x00000090,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00070005,0x00000093,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005, + 0x00000098,0x00004259,0x00030005,0x000000a7,0x00003454,0x00030005,0x000000ae,0x0000434c, + 0x00040006,0x000000ae,0x00000000,0x00003972,0x00040006,0x000000ae,0x00000001,0x00003261, + 0x00040006,0x000000ae,0x00000002,0x00003479,0x00040006,0x000000ae,0x00000003,0x00006969, + 0x00040006,0x000000ae,0x00000004,0x0000326b,0x00040006,0x000000ae,0x00000005,0x00003244, + 0x00040006,0x000000ae,0x00000006,0x00003056,0x00040006,0x000000ae,0x00000007,0x0000326e, + 0x00040006,0x000000ae,0x00000008,0x0000365a,0x00030005,0x000000b0,0x00003041,0x00030005, + 0x000000ff,0x00003055,0x00030005,0x0000011d,0x00006748,0x00030005,0x00000121,0x0000304e, + 0x00030005,0x00000131,0x0000424d,0x00040006,0x00000131,0x00000000,0x00006250,0x00040006, + 0x00000131,0x00000001,0x00006359,0x00040006,0x00000131,0x00000002,0x00006552,0x00040006, + 0x00000131,0x00000003,0x00006553,0x00040006,0x00000131,0x00000004,0x0000366d,0x00040006, + 0x00000131,0x00000005,0x0000676d,0x00040006,0x00000131,0x00000006,0x00006544,0x00040006, + 0x00000131,0x00000007,0x00006545,0x00040006,0x00000131,0x00000008,0x00003755,0x00040006, + 0x00000131,0x00000009,0x0000676a,0x00040006,0x00000131,0x0000000a,0x0000635a,0x00040006, + 0x00000131,0x0000000b,0x00003157,0x00040006,0x00000131,0x0000000c,0x0000676e,0x00040006, + 0x00000131,0x0000000d,0x00003559,0x00040006,0x00000131,0x0000000e,0x0000324f,0x00040006, + 0x00000131,0x0000000f,0x00006461,0x00040006,0x00000131,0x00000010,0x00006579,0x00040006, + 0x00000131,0x00000011,0x00003376,0x00040006,0x00000131,0x00000012,0x00003377,0x00040006, + 0x00000131,0x00000013,0x00006462,0x00040006,0x00000131,0x00000014,0x00006767,0x00030005, + 0x00000133,0x0000006b,0x00060005,0x00000141,0x505f6c67,0x65567265,0x78657472,0x00000000, + 0x00060006,0x00000141,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000141, + 0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000141,0x00000002, + 0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000141,0x00000003,0x435f6c67, + 0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000143,0x00000000,0x00030005,0x00000153, + 0x00004342,0x00030005,0x00000156,0x00004351,0x00030005,0x00000159,0x0000664a,0x00040006, + 0x00000159,0x00000000,0x00003464,0x00030005,0x0000015b,0x0000424c,0x00030005,0x0000015e, + 0x00006576,0x00040006,0x0000015e,0x00000000,0x00003464,0x00030005,0x00000160,0x00004355, + 0x00030005,0x00000162,0x00006577,0x00040006,0x00000162,0x00000000,0x00003464,0x00030005, + 0x00000164,0x0000424f,0x00030005,0x00000166,0x0000664b,0x00040006,0x00000166,0x00000000, + 0x00003464,0x00030005,0x00000168,0x00004358,0x00030005,0x0000016b,0x00003954,0x00040047, + 0x00000090,0x0000000b,0x0000002a,0x00040047,0x00000093,0x0000000b,0x0000002b,0x00040047, + 0x00000098,0x0000001e,0x00000000,0x00030047,0x000000a7,0x00000000,0x00040047,0x000000a7, + 0x0000001e,0x00000001,0x00030047,0x000000ae,0x00000002,0x00050048,0x000000ae,0x00000000, + 0x00000023,0x00000000,0x00050048,0x000000ae,0x00000001,0x00000023,0x00000010,0x00050048, + 0x000000ae,0x00000002,0x00000023,0x00000018,0x00050048,0x000000ae,0x00000003,0x00000023, + 0x0000001c,0x00050048,0x000000ae,0x00000004,0x00000023,0x00000020,0x00050048,0x000000ae, + 0x00000005,0x00000023,0x00000030,0x00050048,0x000000ae,0x00000006,0x00000023,0x00000038, + 0x00050048,0x000000ae,0x00000007,0x00000023,0x0000003c,0x00050048,0x000000ae,0x00000008, + 0x00000023,0x00000040,0x00040047,0x000000b0,0x00000021,0x00000002,0x00040047,0x000000b0, + 0x00000022,0x00000000,0x00030047,0x000000d3,0x00000000,0x00030047,0x000000d4,0x00000000, + 0x00030047,0x000000f3,0x00000000,0x00030047,0x000000f4,0x00000000,0x00040047,0x000000ff, + 0x0000001e,0x00000000,0x00040047,0x0000011d,0x00000001,0x00000001,0x00040047,0x00000121, + 0x0000001e,0x00000002,0x00030047,0x00000131,0x00000002,0x00050048,0x00000131,0x00000000, + 0x00000023,0x00000000,0x00050048,0x00000131,0x00000001,0x00000023,0x00000004,0x00050048, + 0x00000131,0x00000002,0x00000023,0x00000008,0x00050048,0x00000131,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x00000131,0x00000004,0x00000023,0x00000010,0x00050048,0x00000131, + 0x00000005,0x00000023,0x00000014,0x00050048,0x00000131,0x00000006,0x00000023,0x00000018, + 0x00050048,0x00000131,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000131,0x00000008, + 0x00000023,0x00000020,0x00050048,0x00000131,0x00000009,0x00000023,0x00000030,0x00050048, + 0x00000131,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000131,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x00000131,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000131, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x00000131,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x00000131,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000131,0x00000010, + 0x00000023,0x00000054,0x00050048,0x00000131,0x00000011,0x00000023,0x00000058,0x00050048, + 0x00000131,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000131,0x00000013,0x00000023, + 0x00000060,0x00050048,0x00000131,0x00000014,0x00000023,0x00000064,0x00040047,0x00000133, + 0x00000021,0x00000000,0x00040047,0x00000133,0x00000022,0x00000000,0x00030047,0x00000141, + 0x00000002,0x00050048,0x00000141,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000141, + 0x00000001,0x0000000b,0x00000001,0x00050048,0x00000141,0x00000002,0x0000000b,0x00000003, + 0x00050048,0x00000141,0x00000003,0x0000000b,0x00000004,0x00040047,0x00000153,0x00000021, + 0x00000008,0x00040047,0x00000153,0x00000022,0x00000000,0x00030047,0x00000156,0x00000000, + 0x00040047,0x00000156,0x00000021,0x0000000a,0x00040047,0x00000156,0x00000022,0x00000000, + 0x00040047,0x00000158,0x00000006,0x00000010,0x00030047,0x00000159,0x00000003,0x00040048, + 0x00000159,0x00000000,0x00000018,0x00050048,0x00000159,0x00000000,0x00000023,0x00000000, + 0x00030047,0x0000015b,0x00000018,0x00040047,0x0000015b,0x00000021,0x00000003,0x00040047, + 0x0000015b,0x00000022,0x00000000,0x00040047,0x0000015d,0x00000006,0x00000008,0x00030047, + 0x0000015e,0x00000003,0x00040048,0x0000015e,0x00000000,0x00000018,0x00050048,0x0000015e, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000160,0x00000018,0x00040047,0x00000160, + 0x00000021,0x00000004,0x00040047,0x00000160,0x00000022,0x00000000,0x00040047,0x00000161, + 0x00000006,0x00000010,0x00030047,0x00000162,0x00000003,0x00040048,0x00000162,0x00000000, + 0x00000018,0x00050048,0x00000162,0x00000000,0x00000023,0x00000000,0x00030047,0x00000164, + 0x00000018,0x00040047,0x00000164,0x00000021,0x00000005,0x00040047,0x00000164,0x00000022, + 0x00000000,0x00040047,0x00000165,0x00000006,0x00000010,0x00030047,0x00000166,0x00000003, + 0x00040048,0x00000166,0x00000000,0x00000018,0x00050048,0x00000166,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000168,0x00000018,0x00040047,0x00000168,0x00000021,0x00000006, + 0x00040047,0x00000168,0x00000022,0x00000000,0x00030047,0x0000016b,0x00000000,0x00040047, + 0x0000016b,0x00000021,0x0000000a,0x00040047,0x0000016b,0x00000022,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x0000000c,0x00000006,0x00000004,0x00040017,0x0000000e,0x00000006,0x00000002,0x00040018, + 0x0000000f,0x0000000e,0x00000002,0x0004002b,0x00000006,0x0000002f,0x3f800000,0x0004002b, + 0x00000006,0x00000030,0x00000000,0x00040015,0x0000003a,0x00000020,0x00000000,0x0004002b, + 0x0000003a,0x0000003b,0x00000000,0x0004002b,0x0000003a,0x0000003f,0x00000001,0x00040015, + 0x00000056,0x00000020,0x00000001,0x0004002b,0x00000056,0x00000057,0x00000000,0x0004002b, + 0x00000056,0x0000005b,0x00000001,0x00020014,0x00000060,0x0004002b,0x00000006,0x00000084, + 0x3f000000,0x00040020,0x0000008f,0x00000001,0x00000056,0x0004003b,0x0000008f,0x00000090, + 0x00000001,0x0004003b,0x0000008f,0x00000093,0x00000001,0x00040020,0x00000097,0x00000001, + 0x0000000c,0x0004003b,0x00000097,0x00000098,0x00000001,0x0004002b,0x0000003a,0x00000099, + 0x00000002,0x00040020,0x0000009a,0x00000001,0x00000006,0x0004002b,0x0000003a,0x000000a1, + 0x00000003,0x00040020,0x000000a6,0x00000003,0x00000006,0x0004003b,0x000000a6,0x000000a7, + 0x00000003,0x000b001e,0x000000ae,0x0000000c,0x0000000e,0x00000006,0x00000006,0x0000000c, + 0x0000000e,0x0000003a,0x0000003a,0x0000003a,0x00040020,0x000000af,0x00000002,0x000000ae, + 0x0004003b,0x000000af,0x000000b0,0x00000002,0x00040020,0x000000b2,0x00000002,0x0000000c, + 0x00040020,0x000000fe,0x00000003,0x0000000e,0x0004003b,0x000000fe,0x000000ff,0x00000003, + 0x00040020,0x00000104,0x00000002,0x0000000e,0x00030030,0x00000060,0x0000011d,0x00040020, + 0x00000120,0x00000003,0x0000000c,0x0004003b,0x00000120,0x00000121,0x00000003,0x0004002b, + 0x00000056,0x00000122,0x00000004,0x0004002b,0x00000056,0x00000127,0x00000005,0x00040017, + 0x00000130,0x00000056,0x00000004,0x0017001e,0x00000131,0x00000006,0x00000006,0x00000006, + 0x00000006,0x0000003a,0x0000003a,0x0000003a,0x0000003a,0x00000130,0x0000000e,0x0000000e, + 0x0000003a,0x00000006,0x0000003a,0x00000006,0x00000006,0x0000003a,0x00000006,0x00000006, + 0x00000006,0x0000003a,0x00040020,0x00000132,0x00000002,0x00000131,0x0004003b,0x00000132, + 0x00000133,0x00000002,0x0004002b,0x00000056,0x00000134,0x00000002,0x0004002b,0x00000056, + 0x00000135,0x00000003,0x00040020,0x00000139,0x00000002,0x00000006,0x0004001c,0x00000140, + 0x00000006,0x0000003f,0x0006001e,0x00000141,0x0000000c,0x00000006,0x00000140,0x00000140, + 0x00040020,0x00000142,0x00000003,0x00000141,0x0004003b,0x00000142,0x00000143,0x00000003, + 0x00090019,0x00000151,0x0000003a,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x00000152,0x00000000,0x00000151,0x0004003b,0x00000152,0x00000153, + 0x00000000,0x00090019,0x00000154,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x00000155,0x00000000,0x00000154,0x0004003b,0x00000155, + 0x00000156,0x00000000,0x00040017,0x00000157,0x0000003a,0x00000004,0x0003001d,0x00000158, + 0x00000157,0x0003001e,0x00000159,0x00000158,0x00040020,0x0000015a,0x00000002,0x00000159, + 0x0004003b,0x0000015a,0x0000015b,0x00000002,0x00040017,0x0000015c,0x0000003a,0x00000002, + 0x0003001d,0x0000015d,0x0000015c,0x0003001e,0x0000015e,0x0000015d,0x00040020,0x0000015f, + 0x00000002,0x0000015e,0x0004003b,0x0000015f,0x00000160,0x00000002,0x0003001d,0x00000161, + 0x0000000c,0x0003001e,0x00000162,0x00000161,0x00040020,0x00000163,0x00000002,0x00000162, + 0x0004003b,0x00000163,0x00000164,0x00000002,0x0003001d,0x00000165,0x00000157,0x0003001e, + 0x00000166,0x00000165,0x00040020,0x00000167,0x00000002,0x00000166,0x0004003b,0x00000167, + 0x00000168,0x00000002,0x0002001a,0x00000169,0x00040020,0x0000016a,0x00000000,0x00000169, + 0x0004003b,0x0000016a,0x0000016b,0x00000000,0x0005002c,0x0000000e,0x0000021e,0x0000002f, + 0x0000002f,0x0007002c,0x0000000c,0x0000021f,0x00000084,0x00000084,0x00000084,0x00000084, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041, + 0x0000009a,0x0000009b,0x00000098,0x00000099,0x0004003d,0x00000006,0x0000009c,0x0000009b, + 0x000500b4,0x00000060,0x0000009d,0x0000009c,0x00000030,0x000400a8,0x00000060,0x0000009e, + 0x0000009d,0x000300f7,0x000000a0,0x00000000,0x000400fa,0x0000009e,0x0000009f,0x000000a0, + 0x000200f8,0x0000009f,0x00050041,0x0000009a,0x000000a2,0x00000098,0x000000a1,0x0004003d, + 0x00000006,0x000000a3,0x000000a2,0x000500b4,0x00000060,0x000000a4,0x000000a3,0x00000030, + 0x000200f9,0x000000a0,0x000200f8,0x000000a0,0x000700f5,0x00000060,0x000000a5,0x0000009d, + 0x00000005,0x000000a4,0x0000009f,0x000600a9,0x00000006,0x000000a9,0x000000a5,0x00000030, + 0x0000002f,0x0003003e,0x000000a7,0x000000a9,0x0004003d,0x0000000c,0x000000ab,0x00000098, + 0x0007004f,0x0000000e,0x000000ac,0x000000ab,0x000000ab,0x00000000,0x00000001,0x00050041, + 0x000000b2,0x000000b3,0x000000b0,0x00000057,0x0004003d,0x0000000c,0x000000b4,0x000000b3, + 0x00050051,0x00000006,0x00000179,0x000000b4,0x00000000,0x00050051,0x00000006,0x0000017a, + 0x000000b4,0x00000001,0x00050051,0x00000006,0x0000017b,0x000000b4,0x00000002,0x00050051, + 0x00000006,0x0000017c,0x000000b4,0x00000003,0x00050050,0x0000000e,0x0000017d,0x00000179, + 0x0000017a,0x00050050,0x0000000e,0x0000017e,0x0000017b,0x0000017c,0x00050050,0x0000000f, + 0x0000017f,0x0000017d,0x0000017e,0x0006000c,0x0000000f,0x000000b8,0x00000001,0x00000022, + 0x0000017f,0x00040054,0x0000000f,0x000000b9,0x000000b8,0x000400a8,0x00000060,0x000000bb, + 0x000000a5,0x000300f7,0x000000bd,0x00000000,0x000400fa,0x000000bb,0x000000bc,0x000000bd, + 0x000200f8,0x000000bc,0x00050051,0x0000000e,0x000000c1,0x000000b9,0x00000001,0x00050051, + 0x00000006,0x00000183,0x000000c1,0x00000000,0x0006000c,0x00000006,0x00000184,0x00000001, + 0x00000004,0x00000183,0x00050051,0x00000006,0x00000186,0x000000c1,0x00000001,0x0006000c, + 0x00000006,0x00000187,0x00000001,0x00000004,0x00000186,0x00050081,0x00000006,0x00000188, + 0x00000184,0x00000187,0x00050085,0x00000006,0x000000c3,0x00000084,0x00000188,0x00050094, + 0x00000006,0x000000c8,0x0000017e,0x000000c1,0x00050088,0x00000006,0x000000c9,0x000000c3, + 0x000000c8,0x000500be,0x00000060,0x000000cb,0x000000c9,0x00000084,0x000300f7,0x000000cd, + 0x00000000,0x000400fa,0x000000cb,0x000000cc,0x000000d5,0x000200f8,0x000000d5,0x00050085, + 0x00000006,0x000000d9,0x000000c9,0x0000009c,0x00050051,0x00000006,0x000000db,0x000000ab, + 0x00000000,0x00050081,0x00000006,0x000000dc,0x000000db,0x000000d9,0x00060052,0x0000000e, + 0x00000201,0x000000dc,0x000000ac,0x00000000,0x000200f9,0x000000cd,0x000200f8,0x000000cc, + 0x00060052,0x0000000e,0x000001fe,0x00000084,0x000000ac,0x00000000,0x00050088,0x00000006, + 0x000000d0,0x00000084,0x000000c9,0x0004003d,0x00000006,0x000000d3,0x000000a7,0x00050085, + 0x00000006,0x000000d4,0x000000d3,0x000000d0,0x0003003e,0x000000a7,0x000000d4,0x000200f9, + 0x000000cd,0x000200f8,0x000000cd,0x000700f5,0x0000000e,0x00000214,0x000001fe,0x000000cc, + 0x00000201,0x000000d5,0x00050051,0x0000000e,0x000000e1,0x000000b9,0x00000000,0x00050051, + 0x00000006,0x00000191,0x000000e1,0x00000000,0x0006000c,0x00000006,0x00000192,0x00000001, + 0x00000004,0x00000191,0x00050051,0x00000006,0x00000194,0x000000e1,0x00000001,0x0006000c, + 0x00000006,0x00000195,0x00000001,0x00000004,0x00000194,0x00050081,0x00000006,0x00000196, + 0x00000192,0x00000195,0x00050085,0x00000006,0x000000e3,0x00000084,0x00000196,0x00050094, + 0x00000006,0x000000e8,0x0000017d,0x000000e1,0x00050088,0x00000006,0x000000e9,0x000000e3, + 0x000000e8,0x000500be,0x00000060,0x000000eb,0x000000e9,0x00000084,0x000300f7,0x000000ed, + 0x00000000,0x000400fa,0x000000eb,0x000000ec,0x000000f5,0x000200f8,0x000000f5,0x00050041, + 0x0000009a,0x000000f7,0x00000098,0x000000a1,0x0004003d,0x00000006,0x000000f8,0x000000f7, + 0x00050085,0x00000006,0x000000f9,0x000000e9,0x000000f8,0x00050051,0x00000006,0x000000fb, + 0x00000214,0x00000001,0x00050081,0x00000006,0x000000fc,0x000000fb,0x000000f9,0x00060052, + 0x0000000e,0x0000020b,0x000000fc,0x00000214,0x00000001,0x000200f9,0x000000ed,0x000200f8, + 0x000000ec,0x00060052,0x0000000e,0x00000208,0x00000084,0x00000214,0x00000001,0x00050088, + 0x00000006,0x000000f0,0x00000084,0x000000e9,0x0004003d,0x00000006,0x000000f3,0x000000a7, + 0x00050085,0x00000006,0x000000f4,0x000000f3,0x000000f0,0x0003003e,0x000000a7,0x000000f4, + 0x000200f9,0x000000ed,0x000200f8,0x000000ed,0x000700f5,0x0000000e,0x00000216,0x00000208, + 0x000000ec,0x0000020b,0x000000f5,0x000200f9,0x000000bd,0x000200f8,0x000000bd,0x000700f5, + 0x0000000e,0x00000215,0x000000ac,0x000000a0,0x00000216,0x000000ed,0x0003003e,0x000000ff, + 0x00000215,0x00050091,0x0000000e,0x00000103,0x0000017f,0x00000215,0x00050041,0x00000104, + 0x00000105,0x000000b0,0x0000005b,0x0004003d,0x0000000e,0x00000106,0x00000105,0x00050081, + 0x0000000e,0x00000107,0x00000103,0x00000106,0x000300f7,0x0000010a,0x00000000,0x000400fa, + 0x000000a5,0x00000109,0x0000010a,0x000200f8,0x00000109,0x0007004f,0x0000000e,0x0000010e, + 0x000000ab,0x000000ab,0x00000002,0x00000003,0x00050091,0x0000000e,0x0000010f,0x000000b9, + 0x0000010e,0x00050051,0x00000006,0x0000019f,0x0000010f,0x00000000,0x0006000c,0x00000006, + 0x000001a0,0x00000001,0x00000004,0x0000019f,0x00050051,0x00000006,0x000001a2,0x0000010f, + 0x00000001,0x0006000c,0x00000006,0x000001a3,0x00000001,0x00000004,0x000001a2,0x00050081, + 0x00000006,0x000001a4,0x000001a0,0x000001a3,0x00050094,0x00000006,0x00000115,0x0000010f, + 0x0000010f,0x00050088,0x00000006,0x00000116,0x000001a4,0x00000115,0x0005008e,0x0000000e, + 0x00000118,0x0000010f,0x00000116,0x0005008e,0x0000000e,0x0000011a,0x00000118,0x00000084, + 0x00050081,0x0000000e,0x0000011c,0x00000107,0x0000011a,0x000200f9,0x0000010a,0x000200f8, + 0x0000010a,0x000700f5,0x0000000e,0x00000217,0x00000107,0x000000bd,0x0000011c,0x00000109, + 0x000300f7,0x0000011f,0x00000000,0x000400fa,0x0000011d,0x0000011e,0x0000011f,0x000200f8, + 0x0000011e,0x00050041,0x000000b2,0x00000124,0x000000b0,0x00000122,0x0004003d,0x0000000c, + 0x00000125,0x00000124,0x00050051,0x00000006,0x000001ab,0x00000125,0x00000000,0x00050051, + 0x00000006,0x000001ac,0x00000125,0x00000001,0x00050051,0x00000006,0x000001ad,0x00000125, + 0x00000002,0x00050051,0x00000006,0x000001ae,0x00000125,0x00000003,0x00050050,0x0000000e, + 0x000001af,0x000001ab,0x000001ac,0x00050050,0x0000000e,0x000001b0,0x000001ad,0x000001ae, + 0x00050050,0x0000000f,0x000001b1,0x000001af,0x000001b0,0x00050041,0x00000104,0x0000012a, + 0x000000b0,0x00000127,0x0004003d,0x0000000e,0x0000012b,0x0000012a,0x000300f7,0x000001e7, + 0x00000000,0x000300fb,0x0000003b,0x000001b9,0x000200f8,0x000001b9,0x0006000c,0x0000000e, + 0x000001bc,0x00000001,0x00000004,0x000001af,0x0006000c,0x0000000e,0x000001bf,0x00000001, + 0x00000004,0x000001b0,0x00050081,0x0000000e,0x000001c0,0x000001bc,0x000001bf,0x00050051, + 0x00000006,0x000001c2,0x000001c0,0x00000000,0x000500b7,0x00000060,0x000001c3,0x000001c2, + 0x00000030,0x000300f7,0x000001c8,0x00000000,0x000400fa,0x000001c3,0x000001c4,0x000001c8, + 0x000200f8,0x000001c4,0x00050051,0x00000006,0x000001c6,0x000001c0,0x00000001,0x000500b7, + 0x00000060,0x000001c7,0x000001c6,0x00000030,0x000200f9,0x000001c8,0x000200f8,0x000001c8, + 0x000700f5,0x00000060,0x000001c9,0x000001c3,0x000001b9,0x000001c7,0x000001c4,0x000300f7, + 0x000001e6,0x00000000,0x000400fa,0x000001c9,0x000001ca,0x000001e3,0x000200f8,0x000001e3, + 0x0009004f,0x0000000c,0x000001e5,0x0000012b,0x0000012b,0x00000000,0x00000001,0x00000000, + 0x00000001,0x000200f9,0x000001e7,0x000200f8,0x000001ca,0x00050088,0x0000000e,0x000001cd, + 0x0000021e,0x000001c0,0x00050091,0x0000000e,0x000001d0,0x000001b1,0x00000217,0x00050081, + 0x0000000e,0x000001d2,0x000001d0,0x0000012b,0x0004007f,0x0000000e,0x000001d5,0x000001d2, + 0x00050051,0x00000006,0x000001d6,0x000001d2,0x00000000,0x00050051,0x00000006,0x000001d7, + 0x000001d2,0x00000001,0x00050051,0x00000006,0x000001d8,0x000001d5,0x00000000,0x00050051, + 0x00000006,0x000001d9,0x000001d5,0x00000001,0x00070050,0x0000000c,0x000001da,0x000001d6, + 0x000001d7,0x000001d8,0x000001d9,0x0009004f,0x0000000c,0x000001dc,0x000001cd,0x000001cd, + 0x00000000,0x00000001,0x00000000,0x00000001,0x00050085,0x0000000c,0x000001dd,0x000001da, + 0x000001dc,0x00050081,0x0000000c,0x000001e0,0x000001dd,0x000001dc,0x00050081,0x0000000c, + 0x000001e2,0x000001e0,0x0000021f,0x000200f9,0x000001e7,0x000200f8,0x000001e6,0x000100ff, + 0x000200f8,0x000001e7,0x000700f5,0x0000000c,0x00000218,0x000001e2,0x000001ca,0x000001e5, + 0x000001e3,0x0003003e,0x00000121,0x00000218,0x000200f9,0x0000011f,0x000200f8,0x0000011f, + 0x00050041,0x00000139,0x0000013a,0x00000133,0x00000134,0x0004003d,0x00000006,0x0000013b, + 0x0000013a,0x00050041,0x00000139,0x0000013d,0x00000133,0x00000135,0x0004003d,0x00000006, + 0x0000013e,0x0000013d,0x00050051,0x00000006,0x000001ec,0x00000217,0x00000000,0x00050085, + 0x00000006,0x000001ee,0x000001ec,0x0000013b,0x00050083,0x00000006,0x000001ef,0x000001ee, + 0x0000002f,0x00050051,0x00000006,0x000001f1,0x00000217,0x00000001,0x00050085,0x00000006, + 0x000001f3,0x000001f1,0x0000013e,0x0006000c,0x00000006,0x000001f5,0x00000001,0x00000006, + 0x0000013e,0x00050083,0x00000006,0x000001f6,0x000001f3,0x000001f5,0x00070050,0x0000000c, + 0x000001f7,0x000001ef,0x000001f6,0x00000030,0x0000002f,0x00050041,0x00000120,0x00000145, + 0x00000143,0x00000057,0x0003003e,0x00000145,0x000001f7,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_image_rect.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..192f1c6ef937b5437f8c08d2f6516006b29c6459 GIT binary patch literal 7420 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 AJ0)lol&N=127`B9NroBNeO*d+(=`qk8 zQ8VY`cv4GK1Vq9#r>v{;vcb|s%|{yy&~-?U zqUcieDS8$^X(-BLr=lxLQCRLz*{A4U^2yUaJMG~1W%CXm{;5NB+`gy<=(|JFyJ)2J zTsV8dB8uWz3@>v2owKoPQB39Bkr;ib6x2WsMe($D;wMjQ9(UaM=Jqenp4ZaW+`epa z+wA!*&2yHYbP{y&oReGTF2k>nev@YXXLI}Pg-cpn+FD!M+nblQoW5*%TTAmv%NNaE zwqWt1cG5=9$unk5o;Im@?vf?s{8DR6bL)adEzR>5w2^PYsV(~TG-u_vVA0&x<@2&b zH#~B`y3y`?$$!lJq7ZKeo2NToVvl*lYqmGQ$4{u?55QBam|f}fA%9?p}`d{MP0p8L|nB7q`vR&s=NpnK-eA*PClj4SQXz zQJ92^RANqV!y|MVC`s}vZ3(J_s;?LXghVpuUxyt=MwkacPaUa(C zb>-qaQEY?rqqWT6Q1k##pwH_4z%#3Qb_H*(x1s0{Us|`CZNnSN z`)6U*-|5LVncU7t>+QiQe~q#`XU~$?=BRh;6l|L*JqB=2p=H5`l&bL!h4WUsxx`JJ z-UGo0gFWQVYwHfXb6f6VF6Va**XDW?M9Elf=At{D{Gep_UeGuE4+q$<9ZUa)!h0h6 z757KVEe1D+&o=N&NYL380S41_%8|nEn(N?@DXnhF|Rnc;hp67 zVZz?O5%2w*apY1rSJ=8Gzn%&APPk9PeG_&qh&-+Zfn5gzyAA~2BVpHr(DzN)dq4F3 z6Lt*<-TOcAK?!^BOTC9;9dNGAN}9u^_IXan*7cwX>=Ar$jh5HVHNwMdcv!+C6Ly^l zpK%Ghzt;4|a;?bYKCRQ%P`Gx~{2Gd55@!Z##* zcf$84{6NBwCcHM`bqTLe__2gHB>Z^7n-YF9;U6dbLc%{y_@jikBwQ|1Ofu(j7Zq#@JS*Ymgl8u_C*gSswK6TU3r%M-pb;j0r~o$z%D-qY1A~cwNFzCj3;wKT7!Ngr7|LIX<@1}*aBBV8FZxzk-@W16QEFG;6~1$+^G{he7Q0Yt zS2unTrMY}IGkzaR?dk*ILn+N=e*JlDE&Xku{yhGd{_56uRH@gVPxL<;t`_Z^3O2v` zLD+4F?+G5kmw>w@eg@e1u%89Cez|QwpR*`BjtG81$+z0Cf=^g_;pnhm3tu^D-QmG+ zf}iuJ&yMd$E%$&AA-ko|%;B>U%rPqXrW)T6{AchL9UY_W^NV2PW6WLw+s_z-SHX^f z`d-xaT7?IKH-qJl?dz1rs2yH$pS5Ew9M?BFJ@kKzQk!{gmvz3)>0m{ld=?Me7HtGX zAG$l}MbSBqy=r`H*!z^cV_oF(IX-gj3HF(Lcb<5gz+M;6eAqS*+d3E@4}I;M+-H4{ z|KNGa`7so3|2(5kpZBBAVfr(1%{LP4m^xn_Q{Mxe!;Y!X`Evb6Q`(MFtGLhgYLRy= zoV2C?#L8wa<7dM8D|6d!x$gmL5x*4TJAq^IFxYX>o{!+>e54}!np5ukgU24UY%N&7 zb(JR9Prkm=_N1R1z~<2R7nEG~&UVUucTlrkzXdx#D7HBqhbB&Q{H`+UYkhLxDLkC# zuYt|sSViCefVLCd__x9Ql|IJHeRog`|8n3_^lzYYZH|}za^DZsw08%4jh*+#>(>j7 zV^ZX6f^XTRm_mj-sQ-Zs0y8i`t-M%Yvb@#-uTe>d>H{QK5xby$|#P`AOo*j0%`*v{a zbKlS0y+645Iuh64XN<7Rea;AO>9b7cKJ#Smvr+I@@n6Y+2DkM2Idh+(Gxs?-gn~+h3ox!{5^9?cnzBs>Jobx{hCyxcyyS$9-mxeA=%|T;1pRu-o2mC9Zx$;-bHHTi?xzo9~u7erp}St&ZPb$9>0%_FDR$lli%I-1nof+g{(nGWR_!bKm~@|TQ{d*cjLpCNw*R`c|*=*#M??bi^w-y`)~L=K+; zegoDvh85TADIbl^J?T|W_anK!zX$6xhgI3VX)~uj>c^tFSG`{8z%r+ELd_i7-vp~| zsQljotGTb)2Iq)c_|K-#YTBHS^03VTt7&s?%ER_2V$`%b59ML=dz_j!=b$`nep6A? z=KUZK+h5VuBBwlTe%CW+aKG8P7vDiYeOCPkSReIw$^9Os#|Mmyws$%I$?2XajyxZL z9WU$j{*b?qkMa5%qs@E8+!5#ZAT@2?_wulv3|7vLyKJ91-Rrwy^Et!%yocps^BbhvSIMn!Z?Kxr9nM{~K47c!)b8B%8Ko~+ zn|XUs%FXNC-42}R?)Gr!ZuD~pxZ^1|*N$*=oC$ZH?gUngKJN@RMtvstoAZAcuzEh{ z5^vqsr`@)>4*AX$efB$?+Bo{`{k$0L+Px60zg(a2_gh`|UkcaX_c;CK`h&c6i(PB;82H^#Eymys zu=`t#fn1+xqu&;@|5xDp#~8@<3IDUe+5c>~{xJq}eZs#3oc&k8^^Y-->l6Jvr?T6( z)4}qv?G9Gc)}KFxGrehi&M>eT^xD#2D>giQQeb+ z;c88s*6ZG-7XDuYt1Tg~_tg1dwYcvt0IO}pwxYThFNCXaLNn*NU^R1^;}Wo%wu>m` zVfzMHP20tk^00j!tftLp9C_IG0jp^nL@C$i*zF6Bb$cjS9&!7F^*3%mO1U=Y>p@_z zgSG=H<&pCau(`(3Bj4}u1iwM)JFzzXUIE_))@F{Cl=7(C@5a`tZ55^5dF?aAJz)Kv z*HP!aaP_!${|{Ds8=sgL-+`+e=YH`6u!r+P+kKpB&I@t0<$kbjh_&+pFw=ynqRaxo5y?dlF;LZ-Ujr|5>nF%$MiDYB9%u4)(BKZO?P6S+CeUP2~PD*l$@r zhkAd%09W&SR@C(qxOLf%%PHmJD=78X&oTKaIIhW+V7WH)`g?)?@qF!X25O!jRM%PG z0yOJ!4jFqgT>Dr~ZIR;?ur^N*eVkuDqqm}2hd$;}TL{+2xv1Sf_#MFSq0t9_gHVgT z^h~hd5*%0k<@$ubzf)xYv*7y2UMkl|f7@_&WjB}KB;;XR1Xg>9KKNaBG1xY%uO{Am zehFCJxpf+)hu2trDd(x2USn~z(cfge9?_?ExYxq{JAC}DM!hds^Y`WvwISik<(VLQ6h7Z2N^&&!-@wnH54_$_!S z=XqR5+x0uJ+E{YNGw>^Lb+3W@^Z)nY(ncGu2Ft^C4)v=AKd<7x zLwX&*2G_?UwDT*Csyej`(2ONjr*>hbQSh8zyRW_uF{e2~y9jK&{%X#di^2M8^Llqs zs@YEMuThbjwyVH$ZI0Jwa2~(c;c9vO-hiw7Oc~?%COpPZdyL5+z@?44t^v!V9dCiH ze^u4LKZDhLuaEe@z>SM_=dWNjPY=h@J<$96Z)oPw$G)wmR5O?Mx4~+$CjA|3ylaxS zsPi3guJa#oHBbJ?T-%Gy`7VNa^ojWQz&ZYXxSA(_WqhoaA0U`RAKQE#rCPLkC6%dZ z^E<3OZ2s=5rp<4%^057r7&UFzg5|LWeF#?bKGfg2`Vm|`eEwDWxR!>`7Bux(r$}9n zpL5E1?OqG>mA}YY@^uRu66yu))#YNH~4{YbI1DCA5A~xa=i3Wif zJ~_T}eWEQ_g0ufsaQ*F%{&Ic7|7vjdzXq;6}3I><8ZaSCmswpF80Jvz|}lG9LE(^{2^%O(8s>rOq^Qu?UUfV zo*W8SbN;$^j0AhQc4!;M`Dsq)lQ{0H;b3#;J>^qq>ehQJHo5cBoW`5ScDRp@02}XG z=$ddC+`7f=P;K!j2Q*C9(`}2l!xtbuv)xBeg!TiRJQ{2}f=`8;H}1D-aDCKg z@ebpYkS;ZwB>cl^(k`C0O!46Cft}jX2+tb$5tQ?eQHz-W0UML| z#?PY}W1Yt6qZTn=02||6i?#7YG-Hs<7=6^Df1ki$jQRRe%ENXD*u7O-e@eO6Vj!jW zq-FRX1~xv%X(U+9(<8>oTqDr5i$_tqUfG8+;3GJPbLO>SY^Ccz8Y~b0@nHQOC)-lq z7jSj`$5Bq;bbWe+etWn+`TwxK1OGm!eGwb)`f?xGb{T&cSRT3W7gx5s!6mQieE@EK z#@z!hIsNKE&d1>9%Kh2^SC6^*IN1MJrXJUHBiOjyzaPNWBW@Ge|9_^wg8CeTC&1>@ z7VG2>!CnWy5o))ck5Z~f|DFV^Mee7-H{q`yd42?rJlf5(mQp?PJPlS0{tVdhioDN) z^-&L>=fI9z^x=81e(Kh-j#4fBzYA8Ad+&V@?A)5k2*@9V>l3GW)gMCBroVabq*QZm zJ4c)k&Wp(VFxb4|E6={hgzp-#`SiV)QXaO6nG7~2 zuM1P)#&}JP(MK&}jshE#*M+0u#_(6h=%Z#^UH7JejWOR;N_p6h0lOY(n@%YY+Y9th PP1}n!Nd6HmJB;(+1-Am! literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.h new file mode 100644 index 000000000..d3d3eae05 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.h @@ -0,0 +1,1648 @@ +#pragma once + +const uint32_t atomic_draw_interior_triangles_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000b74,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000388, + 0x00000437,0x00000439,0x00000454,0x00000464,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000139,0x0000674e, + 0x00030005,0x000002aa,0x0000674d,0x00030005,0x00000321,0x00006576,0x00040006,0x00000321, + 0x00000000,0x00003464,0x00030005,0x00000323,0x00004355,0x00030005,0x00000333,0x0000674b, + 0x00030005,0x0000034c,0x00006747,0x00040005,0x0000035a,0x30653742,0x00000000,0x00030005, + 0x00000365,0x00006748,0x00030005,0x00000373,0x00006577,0x00040006,0x00000373,0x00000000, + 0x00003464,0x00030005,0x00000375,0x0000424f,0x00060005,0x00000388,0x465f6c67,0x43676172, + 0x64726f6f,0x00000000,0x00030005,0x000003f3,0x00004444,0x00030005,0x000003f7,0x00006277, + 0x00030005,0x00000404,0x00006749,0x00040005,0x0000041a,0x306a3742,0x00000000,0x00030005, + 0x00000437,0x0000306a,0x00030005,0x00000439,0x00003065,0x00030005,0x0000043b,0x00000045, + 0x00030005,0x00000440,0x00003270,0x00030005,0x00000443,0x00003470,0x00030005,0x00000449, + 0x00003145,0x00040005,0x0000044d,0x61726170,0x0000006d,0x00040005,0x0000044f,0x61726170, + 0x0000006d,0x00030005,0x00000454,0x0000307a,0x00030005,0x00000459,0x00003948,0x00040005, + 0x0000045c,0x61726170,0x0000006d,0x00030005,0x00000462,0x0000006e,0x00030005,0x00000464, + 0x0000316c,0x00030005,0x00000466,0x00006543,0x00030005,0x00000473,0x00000050,0x00040005, + 0x00000474,0x61726170,0x0000006d,0x00030005,0x00000476,0x00003171,0x00040005,0x00000477, + 0x61726170,0x0000006d,0x00030005,0x0000047e,0x0000394a,0x00040005,0x00000482,0x61726170, + 0x0000006d,0x00040005,0x00000484,0x61726170,0x0000006d,0x00040005,0x00000486,0x61726170, + 0x0000006d,0x00040005,0x00000488,0x61726170,0x0000006d,0x00040005,0x00000489,0x61726170, + 0x0000006d,0x00030005,0x00000491,0x0000424d,0x00040006,0x00000491,0x00000000,0x00003376, + 0x00040006,0x00000491,0x00000001,0x00003377,0x00030005,0x00000493,0x0000006b,0x00040005, + 0x00000496,0x61726170,0x0000006d,0x00040005,0x00000499,0x61726170,0x0000006d,0x00040005, + 0x0000049c,0x61726170,0x0000006d,0x00040005,0x000004a0,0x61726170,0x0000006d,0x00040005, + 0x000004aa,0x61726170,0x0000006d,0x00040005,0x000004af,0x61726170,0x0000006d,0x00040047, + 0x00000139,0x00000001,0x00000007,0x00040047,0x000002aa,0x00000001,0x00000006,0x00040047, + 0x00000320,0x00000006,0x00000008,0x00030047,0x00000321,0x00000003,0x00040048,0x00000321, + 0x00000000,0x00000018,0x00050048,0x00000321,0x00000000,0x00000023,0x00000000,0x00030047, + 0x00000323,0x00000018,0x00040047,0x00000323,0x00000021,0x00000004,0x00040047,0x00000323, + 0x00000022,0x00000000,0x00040047,0x00000333,0x00000001,0x00000004,0x00040047,0x0000034c, + 0x00000001,0x00000000,0x00030047,0x0000035a,0x00000000,0x00040047,0x0000035a,0x00000021, + 0x00000001,0x00040047,0x0000035a,0x00000022,0x00000002,0x00040047,0x0000035a,0x0000002b, + 0x00000001,0x00040047,0x00000365,0x00000001,0x00000001,0x00040047,0x00000372,0x00000006, + 0x00000010,0x00030047,0x00000373,0x00000003,0x00040048,0x00000373,0x00000000,0x00000018, + 0x00050048,0x00000373,0x00000000,0x00000023,0x00000000,0x00030047,0x00000375,0x00000018, + 0x00040047,0x00000375,0x00000021,0x00000005,0x00040047,0x00000375,0x00000022,0x00000000, + 0x00040047,0x00000388,0x0000000b,0x0000000f,0x00030047,0x000003f3,0x00000000,0x00040047, + 0x000003f3,0x00000021,0x00000009,0x00040047,0x000003f3,0x00000022,0x00000000,0x00030047, + 0x000003f7,0x00000000,0x00040047,0x000003f7,0x00000021,0x00000009,0x00040047,0x000003f7, + 0x00000022,0x00000000,0x00040047,0x00000404,0x00000001,0x00000002,0x00030047,0x0000041a, + 0x00000000,0x00040047,0x0000041a,0x00000021,0x00000000,0x00040047,0x0000041a,0x00000022, + 0x00000002,0x00040047,0x0000041a,0x0000002b,0x00000000,0x00030047,0x00000437,0x00000000, + 0x00040047,0x00000437,0x0000001e,0x00000000,0x00030047,0x00000439,0x00000000,0x00040047, + 0x00000439,0x0000001e,0x00000001,0x00030047,0x00000443,0x00000017,0x00040047,0x00000443, + 0x00000021,0x00000003,0x00040047,0x00000443,0x00000022,0x00000002,0x00030047,0x00000449, + 0x00000000,0x00030047,0x0000044f,0x00000000,0x00030047,0x00000450,0x00000000,0x00030047, + 0x00000452,0x00000000,0x00030047,0x00000454,0x00000000,0x00030047,0x00000454,0x0000000e, + 0x00040047,0x00000454,0x0000001e,0x00000001,0x00030047,0x00000455,0x00000000,0x00030047, + 0x0000045c,0x00000000,0x00030047,0x00000462,0x00000000,0x00030047,0x00000464,0x00000000, + 0x00030047,0x00000464,0x0000000e,0x00040047,0x00000464,0x0000001e,0x00000000,0x00030047, + 0x00000465,0x00000000,0x00030047,0x00000467,0x00000000,0x00030047,0x00000469,0x00000000, + 0x00030047,0x0000046a,0x00000000,0x00030047,0x0000046b,0x00000000,0x00030047,0x00000473, + 0x00000000,0x00030047,0x00000474,0x00000000,0x00030047,0x00000476,0x00000000,0x00030047, + 0x00000477,0x00000000,0x00030047,0x00000479,0x00000000,0x00030047,0x0000047e,0x00000000, + 0x00030047,0x00000485,0x00000000,0x00030047,0x00000486,0x00000000,0x00030047,0x00000487, + 0x00000000,0x00030047,0x00000488,0x00000000,0x00030047,0x00000489,0x00000000,0x00030047, + 0x0000048a,0x00000000,0x00030047,0x00000491,0x00000002,0x00050048,0x00000491,0x00000000, + 0x00000023,0x00000058,0x00050048,0x00000491,0x00000001,0x00000023,0x0000005c,0x00040047, + 0x00000493,0x00000021,0x00000000,0x00040047,0x00000493,0x00000022,0x00000000,0x00030047, + 0x00000496,0x00000000,0x00030047,0x00000497,0x00000000,0x00030047,0x00000498,0x00000000, + 0x00030047,0x0000049c,0x00000000,0x00030047,0x000004a0,0x00000000,0x00030047,0x000004aa, + 0x00000000,0x00030047,0x000004ab,0x00000000,0x00030047,0x000004af,0x00000000,0x00030047, + 0x000004b0,0x00000000,0x00030047,0x000004c0,0x00000000,0x00030047,0x000004c1,0x00000000, + 0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c5,0x00000000,0x00030047,0x000004c7, + 0x00000000,0x00030047,0x000004cb,0x00000000,0x00030047,0x000004cd,0x00000000,0x00030047, + 0x000004ce,0x00000000,0x00030047,0x000004d0,0x00000000,0x00030047,0x000004d2,0x00000000, + 0x00030047,0x000004d4,0x00000000,0x00030047,0x000004d6,0x00000000,0x00030047,0x000004d8, + 0x00000000,0x00030047,0x000004d9,0x00000000,0x00030047,0x000004da,0x00000000,0x00030047, + 0x000004dc,0x00000000,0x00030047,0x000004de,0x00000000,0x00030047,0x000004e0,0x00000000, + 0x00030047,0x000004e2,0x00000000,0x00030047,0x000004e4,0x00000000,0x00030047,0x000004e6, + 0x00000000,0x00030047,0x000004ed,0x00000000,0x00030047,0x000004ee,0x00000000,0x00030047, + 0x000004f1,0x00000000,0x00030047,0x000004f3,0x00000000,0x00030047,0x000004f4,0x00000000, + 0x00030047,0x000004f5,0x00000000,0x00030047,0x000004f8,0x00000000,0x00030047,0x000004f9, + 0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047,0x00000500,0x00000000,0x00030047, + 0x00000502,0x00000000,0x00030047,0x0000050b,0x00000000,0x00030047,0x0000050d,0x00000000, + 0x00030047,0x0000050e,0x00000000,0x00030047,0x0000050f,0x00000000,0x00030047,0x00000510, + 0x00000000,0x00030047,0x00000515,0x00000000,0x00030047,0x0000051b,0x00000000,0x00030047, + 0x0000051c,0x00000000,0x00030047,0x00000525,0x00000000,0x00030047,0x00000526,0x00000000, + 0x00030047,0x00000527,0x00000000,0x00030047,0x00000528,0x00000000,0x00030047,0x00000529, + 0x00000000,0x00030047,0x0000052a,0x00000000,0x00030047,0x0000052b,0x00000000,0x00030047, + 0x0000052e,0x00000000,0x00030047,0x00000531,0x00000000,0x00030047,0x00000539,0x00000000, + 0x00030047,0x0000053a,0x00000000,0x00030047,0x0000053c,0x00000000,0x00030047,0x00000565, + 0x00000000,0x00030047,0x00000567,0x00000000,0x00030047,0x00000568,0x00000000,0x00030047, + 0x00000569,0x00000000,0x00030047,0x0000056a,0x00000000,0x00030047,0x0000056b,0x00000000, + 0x00030047,0x0000056c,0x00000000,0x00030047,0x0000056d,0x00000000,0x00030047,0x0000057c, + 0x00000000,0x00030047,0x00000582,0x00000000,0x00030047,0x000005af,0x00000000,0x00030047, + 0x000005b0,0x00000000,0x00030047,0x000005b5,0x00000000,0x00030047,0x000005b7,0x00000000, + 0x00030047,0x000005b9,0x00000000,0x00030047,0x000005ba,0x00000000,0x00030047,0x000005be, + 0x00000000,0x00030047,0x000005cc,0x00000000,0x00030047,0x000005cd,0x00000000,0x00030047, + 0x000005ce,0x00000000,0x00030047,0x000005cf,0x00000000,0x00030047,0x000005d0,0x00000000, + 0x00030047,0x000005d1,0x00000000,0x00030047,0x000005db,0x00000000,0x00030047,0x000005dc, + 0x00000000,0x00030047,0x000005dd,0x00000000,0x00030047,0x000005de,0x00000000,0x00030047, + 0x000005e5,0x00000000,0x00030047,0x000005e7,0x00000000,0x00030047,0x000005e8,0x00000000, + 0x00030047,0x000005ea,0x00000000,0x00030047,0x000005eb,0x00000000,0x00030047,0x000005ed, + 0x00000000,0x00030047,0x000005ee,0x00000000,0x00030047,0x000005f8,0x00000000,0x00030047, + 0x000005fa,0x00000000,0x00030047,0x000005fb,0x00000000,0x00030047,0x000005fe,0x00000000, + 0x00030047,0x000005ff,0x00000000,0x00030047,0x00000601,0x00000000,0x00030047,0x00000603, + 0x00000000,0x00030047,0x00000605,0x00000000,0x00030047,0x00000613,0x00000000,0x00030047, + 0x00000614,0x00000000,0x00030047,0x00000617,0x00000000,0x00030047,0x00000618,0x00000000, + 0x00030047,0x00000619,0x00000000,0x00030047,0x0000061b,0x00000000,0x00030047,0x0000061d, + 0x00000000,0x00030047,0x0000061f,0x00000000,0x00030047,0x00000621,0x00000000,0x00030047, + 0x00000623,0x00000000,0x00030047,0x00000631,0x00000000,0x00030047,0x00000632,0x00000000, + 0x00030047,0x00000635,0x00000000,0x00030047,0x00000636,0x00000000,0x00030047,0x00000637, + 0x00000000,0x00030047,0x00000638,0x00000000,0x00030047,0x00000639,0x00000000,0x00030047, + 0x0000063a,0x00000000,0x00030047,0x0000063b,0x00000000,0x00030047,0x0000063d,0x00000000, + 0x00030047,0x0000063e,0x00000000,0x00030047,0x0000063f,0x00000000,0x00030047,0x00000641, + 0x00000000,0x00030047,0x00000642,0x00000000,0x00030047,0x00000644,0x00000000,0x00030047, + 0x00000646,0x00000000,0x00030047,0x00000647,0x00000000,0x00030047,0x00000648,0x00000000, + 0x00030047,0x00000649,0x00000000,0x00030047,0x0000064a,0x00000000,0x00030047,0x0000064b, + 0x00000000,0x00030047,0x0000064c,0x00000000,0x00030047,0x0000064d,0x00000000,0x00030047, + 0x0000064e,0x00000000,0x00030047,0x0000064f,0x00000000,0x00030047,0x00000650,0x00000000, + 0x00030047,0x00000651,0x00000000,0x00030047,0x00000652,0x00000000,0x00030047,0x00000653, + 0x00000000,0x00030047,0x00000654,0x00000000,0x00030047,0x00000655,0x00000000,0x00030047, + 0x00000656,0x00000000,0x00030047,0x00000657,0x00000000,0x00030047,0x00000658,0x00000000, + 0x00030047,0x00000659,0x00000000,0x00030047,0x0000065b,0x00000000,0x00030047,0x0000065c, + 0x00000000,0x00030047,0x0000065d,0x00000000,0x00030047,0x0000065e,0x00000000,0x00030047, + 0x0000065f,0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000661,0x00000000, + 0x00030047,0x00000662,0x00000000,0x00030047,0x00000663,0x00000000,0x00030047,0x00000664, + 0x00000000,0x00030047,0x00000665,0x00000000,0x00030047,0x00000666,0x00000000,0x00030047, + 0x00000667,0x00000000,0x00030047,0x00000668,0x00000000,0x00030047,0x00000669,0x00000000, + 0x00030047,0x0000066a,0x00000000,0x00030047,0x0000066b,0x00000000,0x00030047,0x0000066c, + 0x00000000,0x00030047,0x0000066d,0x00000000,0x00030047,0x0000066f,0x00000000,0x00030047, + 0x00000671,0x00000000,0x00030047,0x00000673,0x00000000,0x00030047,0x00000674,0x00000000, + 0x00030047,0x00000675,0x00000000,0x00030047,0x00000677,0x00000000,0x00030047,0x00000678, + 0x00000000,0x00030047,0x00000679,0x00000000,0x00030047,0x0000067a,0x00000000,0x00030047, + 0x0000067b,0x00000000,0x00030047,0x0000067c,0x00000000,0x00030047,0x0000067d,0x00000000, + 0x00030047,0x0000067f,0x00000000,0x00030047,0x00000680,0x00000000,0x00030047,0x00000681, + 0x00000000,0x00030047,0x00000682,0x00000000,0x00030047,0x00000683,0x00000000,0x00030047, + 0x00000684,0x00000000,0x00030047,0x00000685,0x00000000,0x00030047,0x00000686,0x00000000, + 0x00030047,0x00000687,0x00000000,0x00030047,0x00000688,0x00000000,0x00030047,0x00000689, + 0x00000000,0x00030047,0x0000068b,0x00000000,0x00030047,0x0000068c,0x00000000,0x00030047, + 0x0000068d,0x00000000,0x00030047,0x0000068f,0x00000000,0x00030047,0x00000690,0x00000000, + 0x00030047,0x00000691,0x00000000,0x00030047,0x00000693,0x00000000,0x00030047,0x00000694, + 0x00000000,0x00030047,0x00000695,0x00000000,0x00030047,0x00000697,0x00000000,0x00030047, + 0x00000698,0x00000000,0x00030047,0x0000069a,0x00000000,0x00030047,0x0000069b,0x00000000, + 0x00030047,0x0000069c,0x00000000,0x00030047,0x000006a3,0x00000000,0x00030047,0x000006a4, + 0x00000000,0x00030047,0x000006a7,0x00000000,0x00030047,0x000006a9,0x00000000,0x00030047, + 0x000006aa,0x00000000,0x00030047,0x000006ac,0x00000000,0x00030047,0x000006ad,0x00000000, + 0x00030047,0x000006ae,0x00000000,0x00030047,0x000006af,0x00000000,0x00030047,0x000006b0, + 0x00000000,0x00030047,0x000006b1,0x00000000,0x00030047,0x000006b2,0x00000000,0x00030047, + 0x000006b3,0x00000000,0x00030047,0x000006b4,0x00000000,0x00030047,0x000006b6,0x00000000, + 0x00030047,0x000006b7,0x00000000,0x00030047,0x000006b9,0x00000000,0x00030047,0x000006bc, + 0x00000000,0x00030047,0x000006bd,0x00000000,0x00030047,0x000006be,0x00000000,0x00030047, + 0x000006c0,0x00000000,0x00030047,0x000006c1,0x00000000,0x00030047,0x000006c2,0x00000000, + 0x00030047,0x000006ca,0x00000000,0x00030047,0x000006d0,0x00000000,0x00030047,0x000006d1, + 0x00000000,0x00030047,0x000006d2,0x00000000,0x00030047,0x000006d3,0x00000000,0x00030047, + 0x000006d4,0x00000000,0x00030047,0x000006d6,0x00000000,0x00030047,0x000006d7,0x00000000, + 0x00030047,0x000006d9,0x00000000,0x00030047,0x000006da,0x00000000,0x00030047,0x000006db, + 0x00000000,0x00030047,0x000006dc,0x00000000,0x00030047,0x000006dd,0x00000000,0x00030047, + 0x000006de,0x00000000,0x00030047,0x000006df,0x00000000,0x00030047,0x000006e1,0x00000000, + 0x00030047,0x000006e2,0x00000000,0x00030047,0x000006e3,0x00000000,0x00030047,0x000006e5, + 0x00000000,0x00030047,0x000006e6,0x00000000,0x00030047,0x000006e7,0x00000000,0x00030047, + 0x000006e8,0x00000000,0x00030047,0x000006e9,0x00000000,0x00030047,0x000006ea,0x00000000, + 0x00030047,0x000006eb,0x00000000,0x00030047,0x000006ec,0x00000000,0x00030047,0x000006ed, + 0x00000000,0x00030047,0x000006ee,0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047, + 0x000006f1,0x00000000,0x00030047,0x000006f2,0x00000000,0x00030047,0x000006f3,0x00000000, + 0x00030047,0x000006fc,0x00000000,0x00030047,0x00000702,0x00000000,0x00030047,0x00000703, + 0x00000000,0x00030047,0x00000708,0x00000000,0x00030047,0x0000070e,0x00000000,0x00030047, + 0x0000070f,0x00000000,0x00030047,0x00000710,0x00000000,0x00030047,0x00000713,0x00000000, + 0x00030047,0x00000714,0x00000000,0x00030047,0x00000715,0x00000000,0x00030047,0x0000071b, + 0x00000000,0x00030047,0x0000071c,0x00000000,0x00030047,0x0000071d,0x00000000,0x00030047, + 0x00000725,0x00000000,0x00030047,0x00000726,0x00000000,0x00030047,0x00000727,0x00000000, + 0x00030047,0x00000728,0x00000000,0x00030047,0x00000729,0x00000000,0x00030047,0x0000072a, + 0x00000000,0x00030047,0x0000072b,0x00000000,0x00030047,0x0000072c,0x00000000,0x00030047, + 0x0000072d,0x00000000,0x00030047,0x0000072f,0x00000000,0x00030047,0x00000730,0x00000000, + 0x00030047,0x00000731,0x00000000,0x00030047,0x00000732,0x00000000,0x00030047,0x00000734, + 0x00000000,0x00030047,0x00000735,0x00000000,0x00030047,0x00000736,0x00000000,0x00030047, + 0x00000737,0x00000000,0x00030047,0x00000738,0x00000000,0x00030047,0x00000739,0x00000000, + 0x00030047,0x0000073a,0x00000000,0x00030047,0x0000073b,0x00000000,0x00030047,0x0000073e, + 0x00000000,0x00030047,0x00000741,0x00000000,0x00030047,0x00000742,0x00000000,0x00030047, + 0x00000743,0x00000000,0x00030047,0x00000744,0x00000000,0x00030047,0x00000749,0x00000000, + 0x00030047,0x0000074c,0x00000000,0x00030047,0x0000074d,0x00000000,0x00030047,0x0000074e, + 0x00000000,0x00030047,0x0000074f,0x00000000,0x00030047,0x00000754,0x00000000,0x00030047, + 0x00000757,0x00000000,0x00030047,0x00000758,0x00000000,0x00030047,0x00000759,0x00000000, + 0x00030047,0x0000075e,0x00000000,0x00030047,0x00000761,0x00000000,0x00030047,0x00000762, + 0x00000000,0x00030047,0x00000763,0x00000000,0x00030047,0x00000767,0x00000000,0x00030047, + 0x00000768,0x00000000,0x00030047,0x00000769,0x00000000,0x00030047,0x0000076b,0x00000000, + 0x00030047,0x0000076c,0x00000000,0x00030047,0x0000076e,0x00000000,0x00030047,0x00000772, + 0x00000000,0x00030047,0x00000773,0x00000000,0x00030047,0x00000776,0x00000000,0x00030047, + 0x00000777,0x00000000,0x00030047,0x00000778,0x00000000,0x00030047,0x00000779,0x00000000, + 0x00030047,0x0000077b,0x00000000,0x00030047,0x0000077d,0x00000000,0x00030047,0x0000077f, + 0x00000000,0x00030047,0x00000781,0x00000000,0x00030047,0x00000782,0x00000000,0x00030047, + 0x00000783,0x00000000,0x00030047,0x00000785,0x00000000,0x00030047,0x00000787,0x00000000, + 0x00030047,0x00000789,0x00000000,0x00030047,0x0000078b,0x00000000,0x00030047,0x0000078c, + 0x00000000,0x00030047,0x0000078d,0x00000000,0x00030047,0x0000078f,0x00000000,0x00030047, + 0x00000791,0x00000000,0x00030047,0x00000793,0x00000000,0x00030047,0x00000795,0x00000000, + 0x00030047,0x00000796,0x00000000,0x00030047,0x00000797,0x00000000,0x00030047,0x00000799, + 0x00000000,0x00030047,0x0000079b,0x00000000,0x00030047,0x0000079d,0x00000000,0x00030047, + 0x0000079f,0x00000000,0x00030047,0x000007a0,0x00000000,0x00030047,0x000007a1,0x00000000, + 0x00030047,0x000007a3,0x00000000,0x00030047,0x000007a5,0x00000000,0x00030047,0x000007a7, + 0x00000000,0x00030047,0x000007a9,0x00000000,0x00030047,0x000007aa,0x00000000,0x00030047, + 0x000007ab,0x00000000,0x00030047,0x000007ad,0x00000000,0x00030047,0x000007af,0x00000000, + 0x00030047,0x000007b1,0x00000000,0x00030047,0x000007b3,0x00000000,0x00030047,0x000007b4, + 0x00000000,0x00030047,0x000007b5,0x00000000,0x00030047,0x000007b7,0x00000000,0x00030047, + 0x000007b9,0x00000000,0x00030047,0x000007bb,0x00000000,0x00030047,0x000007bd,0x00000000, + 0x00030047,0x000007be,0x00000000,0x00030047,0x000007bf,0x00000000,0x00030047,0x000007c1, + 0x00000000,0x00030047,0x000007c3,0x00000000,0x00030047,0x000007c5,0x00000000,0x00030047, + 0x000007c7,0x00000000,0x00030047,0x000007c8,0x00000000,0x00030047,0x000007c9,0x00000000, + 0x00030047,0x000007cb,0x00000000,0x00030047,0x000007cd,0x00000000,0x00030047,0x000007cf, + 0x00000000,0x00030047,0x000007d1,0x00000000,0x00030047,0x000007d2,0x00000000,0x00030047, + 0x000007d3,0x00000000,0x00030047,0x000007d5,0x00000000,0x00030047,0x000007d7,0x00000000, + 0x00030047,0x000007d9,0x00000000,0x00030047,0x000007db,0x00000000,0x00030047,0x000007dc, + 0x00000000,0x00030047,0x000007dd,0x00000000,0x00030047,0x000007df,0x00000000,0x00030047, + 0x000007e1,0x00000000,0x00030047,0x000007e3,0x00000000,0x00030047,0x000007e5,0x00000000, + 0x00030047,0x000007e6,0x00000000,0x00030047,0x000007e7,0x00000000,0x00030047,0x000007e9, + 0x00000000,0x00030047,0x000007eb,0x00000000,0x00030047,0x000007ed,0x00000000,0x00030047, + 0x000007ef,0x00000000,0x00030047,0x000007f0,0x00000000,0x00030047,0x000007f1,0x00000000, + 0x00030047,0x000007f3,0x00000000,0x00030047,0x000007f5,0x00000000,0x00030047,0x000007f7, + 0x00000000,0x00030047,0x000007f9,0x00000000,0x00030047,0x000007fa,0x00000000,0x00030047, + 0x000007fb,0x00000000,0x00030047,0x000007fd,0x00000000,0x00030047,0x000007ff,0x00000000, + 0x00030047,0x00000801,0x00000000,0x00030047,0x00000803,0x00000000,0x00030047,0x00000805, + 0x00000000,0x00030047,0x00000806,0x00000000,0x00030047,0x00000807,0x00000000,0x00030047, + 0x00000809,0x00000000,0x00030047,0x0000080b,0x00000000,0x00030047,0x0000080c,0x00000000, + 0x00030047,0x0000080d,0x00000000,0x00030047,0x0000080f,0x00000000,0x00030047,0x00000811, + 0x00000000,0x00030047,0x00000813,0x00000000,0x00030047,0x00000814,0x00000000,0x00030047, + 0x00000816,0x00000000,0x00030047,0x00000817,0x00000000,0x00030047,0x00000818,0x00000000, + 0x00030047,0x00000819,0x00000000,0x00030047,0x0000081f,0x00000000,0x00030047,0x00000822, + 0x00000000,0x00030047,0x00000824,0x00000000,0x00030047,0x00000825,0x00000000,0x00030047, + 0x00000827,0x00000000,0x00030047,0x00000828,0x00000000,0x00030047,0x0000082b,0x00000000, + 0x00030047,0x0000082c,0x00000000,0x00030047,0x0000082d,0x00000000,0x00030047,0x00000830, + 0x00000000,0x00030047,0x00000832,0x00000000,0x00030047,0x00000833,0x00000000,0x00030047, + 0x00000834,0x00000000,0x00030047,0x00000835,0x00000000,0x00030047,0x00000837,0x00000000, + 0x00030047,0x00000838,0x00000000,0x00030047,0x0000083b,0x00000000,0x00030047,0x0000083c, + 0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x00000840,0x00000000,0x00030047, + 0x00000842,0x00000000,0x00030047,0x00000843,0x00000000,0x00030047,0x00000844,0x00000000, + 0x00030047,0x00000845,0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000848, + 0x00000000,0x00030047,0x0000084b,0x00000000,0x00030047,0x0000084c,0x00000000,0x00030047, + 0x0000084d,0x00000000,0x00030047,0x00000850,0x00000000,0x00030047,0x00000852,0x00000000, + 0x00030047,0x00000853,0x00000000,0x00030047,0x00000854,0x00000000,0x00030047,0x00000855, + 0x00000000,0x00030047,0x00000857,0x00000000,0x00030047,0x00000858,0x00000000,0x00030047, + 0x0000085b,0x00000000,0x00030047,0x0000085c,0x00000000,0x00030047,0x0000085d,0x00000000, + 0x00030047,0x00000860,0x00000000,0x00030047,0x00000862,0x00000000,0x00030047,0x00000863, + 0x00000000,0x00030047,0x00000864,0x00000000,0x00030047,0x00000865,0x00000000,0x00030047, + 0x00000866,0x00000000,0x00030047,0x00000867,0x00000000,0x00030047,0x00000868,0x00000000, + 0x00030047,0x00000869,0x00000000,0x00030047,0x0000086a,0x00000000,0x00030047,0x0000086b, + 0x00000000,0x00030047,0x0000086c,0x00000000,0x00030047,0x0000086d,0x00000000,0x00030047, + 0x0000086e,0x00000000,0x00030047,0x0000086f,0x00000000,0x00030047,0x00000870,0x00000000, + 0x00030047,0x00000871,0x00000000,0x00030047,0x00000872,0x00000000,0x00030047,0x00000874, + 0x00000000,0x00030047,0x00000876,0x00000000,0x00030047,0x00000877,0x00000000,0x00030047, + 0x00000879,0x00000000,0x00030047,0x0000087a,0x00000000,0x00030047,0x0000087b,0x00000000, + 0x00030047,0x0000087c,0x00000000,0x00030047,0x0000087d,0x00000000,0x00030047,0x00000880, + 0x00000000,0x00030047,0x00000882,0x00000000,0x00030047,0x00000883,0x00000000,0x00030047, + 0x00000886,0x00000000,0x00030047,0x00000887,0x00000000,0x00030047,0x0000088a,0x00000000, + 0x00030047,0x0000088c,0x00000000,0x00030047,0x0000088d,0x00000000,0x00030047,0x0000088e, + 0x00000000,0x00030047,0x0000088f,0x00000000,0x00030047,0x00000890,0x00000000,0x00030047, + 0x00000891,0x00000000,0x00030047,0x00000892,0x00000000,0x00030047,0x00000893,0x00000000, + 0x00030047,0x00000894,0x00000000,0x00030047,0x00000895,0x00000000,0x00030047,0x00000896, + 0x00000000,0x00030047,0x00000897,0x00000000,0x00030047,0x00000898,0x00000000,0x00030047, + 0x0000089a,0x00000000,0x00030047,0x0000089c,0x00000000,0x00030047,0x0000089d,0x00000000, + 0x00030047,0x0000089e,0x00000000,0x00030047,0x000008a0,0x00000000,0x00030047,0x000008a2, + 0x00000000,0x00030047,0x000008a4,0x00000000,0x00030047,0x000008a6,0x00000000,0x00030047, + 0x000008a7,0x00000000,0x00030047,0x000008a8,0x00000000,0x00030047,0x000008a9,0x00000000, + 0x00030047,0x000008aa,0x00000000,0x00030047,0x000008ac,0x00000000,0x00030047,0x000008ae, + 0x00000000,0x00030047,0x000008af,0x00000000,0x00030047,0x000008b0,0x00000000,0x00030047, + 0x000008b2,0x00000000,0x00030047,0x000008b4,0x00000000,0x00030047,0x000008b6,0x00000000, + 0x00030047,0x000008b8,0x00000000,0x00030047,0x000008b9,0x00000000,0x00030047,0x000008ba, + 0x00000000,0x00030047,0x000008bc,0x00000000,0x00030047,0x000008be,0x00000000,0x00030047, + 0x000008c0,0x00000000,0x00030047,0x000008c1,0x00000000,0x00030047,0x000008c2,0x00000000, + 0x00030047,0x000008c4,0x00000000,0x00030047,0x000008c6,0x00000000,0x00030047,0x000008c8, + 0x00000000,0x00030047,0x000008c9,0x00000000,0x00030047,0x000008ca,0x00000000,0x00030047, + 0x000008cc,0x00000000,0x00030047,0x000008cd,0x00000000,0x00030047,0x000008d0,0x00000000, + 0x00030047,0x000008d1,0x00000000,0x00030047,0x000008d2,0x00000000,0x00030047,0x000008d5, + 0x00000000,0x00030047,0x000008d7,0x00000000,0x00030047,0x000008d8,0x00000000,0x00030047, + 0x000008d9,0x00000000,0x00030047,0x000008da,0x00000000,0x00030047,0x000008dc,0x00000000, + 0x00030047,0x000008dd,0x00000000,0x00030047,0x000008e0,0x00000000,0x00030047,0x000008e1, + 0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008e5,0x00000000,0x00030047, + 0x000008e7,0x00000000,0x00030047,0x000008e8,0x00000000,0x00030047,0x000008e9,0x00000000, + 0x00030047,0x000008ea,0x00000000,0x00030047,0x000008ec,0x00000000,0x00030047,0x000008ee, + 0x00000000,0x00030047,0x000008f0,0x00000000,0x00030047,0x000008f1,0x00000000,0x00030047, + 0x000008f3,0x00000000,0x00030047,0x000008f4,0x00000000,0x00030047,0x000008f5,0x00000000, + 0x00030047,0x000008f7,0x00000000,0x00030047,0x000008f9,0x00000000,0x00030047,0x000008fb, + 0x00000000,0x00030047,0x000008fd,0x00000000,0x00030047,0x000008fe,0x00000000,0x00030047, + 0x000008ff,0x00000000,0x00030047,0x00000901,0x00000000,0x00030047,0x00000903,0x00000000, + 0x00030047,0x00000905,0x00000000,0x00030047,0x00000907,0x00000000,0x00030047,0x00000909, + 0x00000000,0x00030047,0x0000090a,0x00000000,0x00030047,0x0000090b,0x00000000,0x00030047, + 0x0000090d,0x00000000,0x00030047,0x0000090f,0x00000000,0x00030047,0x00000910,0x00000000, + 0x00030047,0x00000911,0x00000000,0x00030047,0x00000913,0x00000000,0x00030047,0x00000915, + 0x00000000,0x00030047,0x00000917,0x00000000,0x00030047,0x00000918,0x00000000,0x00030047, + 0x0000091a,0x00000000,0x00030047,0x0000091b,0x00000000,0x00030047,0x0000091c,0x00000000, + 0x00030047,0x0000091d,0x00000000,0x00030047,0x00000923,0x00000000,0x00030047,0x00000926, + 0x00000000,0x00030047,0x00000928,0x00000000,0x00030047,0x00000929,0x00000000,0x00030047, + 0x0000092b,0x00000000,0x00030047,0x0000092c,0x00000000,0x00030047,0x0000092f,0x00000000, + 0x00030047,0x00000930,0x00000000,0x00030047,0x00000931,0x00000000,0x00030047,0x00000934, + 0x00000000,0x00030047,0x00000936,0x00000000,0x00030047,0x00000937,0x00000000,0x00030047, + 0x00000938,0x00000000,0x00030047,0x00000939,0x00000000,0x00030047,0x0000093b,0x00000000, + 0x00030047,0x0000093c,0x00000000,0x00030047,0x0000093f,0x00000000,0x00030047,0x00000940, + 0x00000000,0x00030047,0x00000941,0x00000000,0x00030047,0x00000944,0x00000000,0x00030047, + 0x00000946,0x00000000,0x00030047,0x00000947,0x00000000,0x00030047,0x00000948,0x00000000, + 0x00030047,0x00000949,0x00000000,0x00030047,0x0000094b,0x00000000,0x00030047,0x0000094c, + 0x00000000,0x00030047,0x0000094f,0x00000000,0x00030047,0x00000950,0x00000000,0x00030047, + 0x00000951,0x00000000,0x00030047,0x00000954,0x00000000,0x00030047,0x00000956,0x00000000, + 0x00030047,0x00000957,0x00000000,0x00030047,0x00000958,0x00000000,0x00030047,0x00000959, + 0x00000000,0x00030047,0x0000095b,0x00000000,0x00030047,0x0000095c,0x00000000,0x00030047, + 0x0000095f,0x00000000,0x00030047,0x00000960,0x00000000,0x00030047,0x00000961,0x00000000, + 0x00030047,0x00000964,0x00000000,0x00030047,0x00000966,0x00000000,0x00030047,0x00000967, + 0x00000000,0x00030047,0x00000968,0x00000000,0x00030047,0x00000969,0x00000000,0x00030047, + 0x0000096a,0x00000000,0x00030047,0x0000096b,0x00000000,0x00030047,0x0000096c,0x00000000, + 0x00030047,0x0000096d,0x00000000,0x00030047,0x0000096e,0x00000000,0x00030047,0x0000096f, + 0x00000000,0x00030047,0x00000970,0x00000000,0x00030047,0x00000971,0x00000000,0x00030047, + 0x00000972,0x00000000,0x00030047,0x00000973,0x00000000,0x00030047,0x00000974,0x00000000, + 0x00030047,0x00000975,0x00000000,0x00030047,0x00000976,0x00000000,0x00030047,0x00000978, + 0x00000000,0x00030047,0x0000097a,0x00000000,0x00030047,0x0000097b,0x00000000,0x00030047, + 0x0000097d,0x00000000,0x00030047,0x0000097e,0x00000000,0x00030047,0x0000097f,0x00000000, + 0x00030047,0x00000980,0x00000000,0x00030047,0x00000981,0x00000000,0x00030047,0x00000984, + 0x00000000,0x00030047,0x00000986,0x00000000,0x00030047,0x00000987,0x00000000,0x00030047, + 0x0000098a,0x00000000,0x00030047,0x0000098b,0x00000000,0x00030047,0x0000098e,0x00000000, + 0x00030047,0x00000990,0x00000000,0x00030047,0x00000991,0x00000000,0x00030047,0x00000992, + 0x00000000,0x00030047,0x00000993,0x00000000,0x00030047,0x00000994,0x00000000,0x00030047, + 0x00000995,0x00000000,0x00030047,0x00000996,0x00000000,0x00030047,0x00000997,0x00000000, + 0x00030047,0x00000998,0x00000000,0x00030047,0x00000999,0x00000000,0x00030047,0x0000099a, + 0x00000000,0x00030047,0x0000099b,0x00000000,0x00030047,0x0000099c,0x00000000,0x00030047, + 0x0000099e,0x00000000,0x00030047,0x000009a0,0x00000000,0x00030047,0x000009a1,0x00000000, + 0x00030047,0x000009a2,0x00000000,0x00030047,0x000009a4,0x00000000,0x00030047,0x000009a6, + 0x00000000,0x00030047,0x000009a8,0x00000000,0x00030047,0x000009aa,0x00000000,0x00030047, + 0x000009ab,0x00000000,0x00030047,0x000009ac,0x00000000,0x00030047,0x000009ad,0x00000000, + 0x00030047,0x000009ae,0x00000000,0x00030047,0x000009b0,0x00000000,0x00030047,0x000009b2, + 0x00000000,0x00030047,0x000009b3,0x00000000,0x00030047,0x000009b4,0x00000000,0x00030047, + 0x000009b6,0x00000000,0x00030047,0x000009b8,0x00000000,0x00030047,0x000009ba,0x00000000, + 0x00030047,0x000009bc,0x00000000,0x00030047,0x000009bd,0x00000000,0x00030047,0x000009be, + 0x00000000,0x00030047,0x000009c0,0x00000000,0x00030047,0x000009c2,0x00000000,0x00030047, + 0x000009c4,0x00000000,0x00030047,0x000009c5,0x00000000,0x00030047,0x000009c6,0x00000000, + 0x00030047,0x000009c8,0x00000000,0x00030047,0x000009ca,0x00000000,0x00030047,0x000009cc, + 0x00000000,0x00030047,0x000009cd,0x00000000,0x00030047,0x000009ce,0x00000000,0x00030047, + 0x000009d0,0x00000000,0x00030047,0x000009d1,0x00000000,0x00030047,0x000009d4,0x00000000, + 0x00030047,0x000009d5,0x00000000,0x00030047,0x000009d6,0x00000000,0x00030047,0x000009d9, + 0x00000000,0x00030047,0x000009db,0x00000000,0x00030047,0x000009dc,0x00000000,0x00030047, + 0x000009dd,0x00000000,0x00030047,0x000009de,0x00000000,0x00030047,0x000009e0,0x00000000, + 0x00030047,0x000009e1,0x00000000,0x00030047,0x000009e4,0x00000000,0x00030047,0x000009e5, + 0x00000000,0x00030047,0x000009e6,0x00000000,0x00030047,0x000009e9,0x00000000,0x00030047, + 0x000009eb,0x00000000,0x00030047,0x000009ec,0x00000000,0x00030047,0x000009ed,0x00000000, + 0x00030047,0x000009ee,0x00000000,0x00030047,0x000009f0,0x00000000,0x00030047,0x000009f2, + 0x00000000,0x00030047,0x000009f4,0x00000000,0x00030047,0x000009f5,0x00000000,0x00030047, + 0x000009f7,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047,0x000009f9,0x00000000, + 0x00030047,0x000009fb,0x00000000,0x00030047,0x000009fd,0x00000000,0x00030047,0x000009ff, + 0x00000000,0x00030047,0x00000a01,0x00000000,0x00030047,0x00000a02,0x00000000,0x00030047, + 0x00000a03,0x00000000,0x00030047,0x00000a05,0x00000000,0x00030047,0x00000a07,0x00000000, + 0x00030047,0x00000a09,0x00000000,0x00030047,0x00000a0b,0x00000000,0x00030047,0x00000a0c, + 0x00000000,0x00030047,0x00000a0d,0x00000000,0x00030047,0x00000a0e,0x00000000,0x00030047, + 0x00000a0f,0x00000000,0x00030047,0x00000a10,0x00000000,0x00030047,0x00000a11,0x00000000, + 0x00030047,0x00000a12,0x00000000,0x00030047,0x00000a13,0x00000000,0x00030047,0x00000a14, + 0x00000000,0x00030047,0x00000a15,0x00000000,0x00030047,0x00000a16,0x00000000,0x00030047, + 0x00000a17,0x00000000,0x00030047,0x00000a18,0x00000000,0x00030047,0x00000a19,0x00000000, + 0x00030047,0x00000a1a,0x00000000,0x00030047,0x00000a1c,0x00000000,0x00030047,0x00000a1e, + 0x00000000,0x00030047,0x00000a1f,0x00000000,0x00030047,0x00000a21,0x00000000,0x00030047, + 0x00000a22,0x00000000,0x00030047,0x00000a23,0x00000000,0x00030047,0x00000a24,0x00000000, + 0x00030047,0x00000a25,0x00000000,0x00030047,0x00000a28,0x00000000,0x00030047,0x00000a2a, + 0x00000000,0x00030047,0x00000a2b,0x00000000,0x00030047,0x00000a2e,0x00000000,0x00030047, + 0x00000a2f,0x00000000,0x00030047,0x00000a32,0x00000000,0x00030047,0x00000a34,0x00000000, + 0x00030047,0x00000a35,0x00000000,0x00030047,0x00000a36,0x00000000,0x00030047,0x00000a37, + 0x00000000,0x00030047,0x00000a38,0x00000000,0x00030047,0x00000a39,0x00000000,0x00030047, + 0x00000a3a,0x00000000,0x00030047,0x00000a3b,0x00000000,0x00030047,0x00000a3c,0x00000000, + 0x00030047,0x00000a3d,0x00000000,0x00030047,0x00000a3e,0x00000000,0x00030047,0x00000a3f, + 0x00000000,0x00030047,0x00000a40,0x00000000,0x00030047,0x00000a42,0x00000000,0x00030047, + 0x00000a44,0x00000000,0x00030047,0x00000a45,0x00000000,0x00030047,0x00000a46,0x00000000, + 0x00030047,0x00000a48,0x00000000,0x00030047,0x00000a4a,0x00000000,0x00030047,0x00000a4c, + 0x00000000,0x00030047,0x00000a4e,0x00000000,0x00030047,0x00000a4f,0x00000000,0x00030047, + 0x00000a50,0x00000000,0x00030047,0x00000a51,0x00000000,0x00030047,0x00000a52,0x00000000, + 0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a56,0x00000000,0x00030047,0x00000a57, + 0x00000000,0x00030047,0x00000a58,0x00000000,0x00030047,0x00000a5a,0x00000000,0x00030047, + 0x00000a5c,0x00000000,0x00030047,0x00000a5e,0x00000000,0x00030047,0x00000a60,0x00000000, + 0x00030047,0x00000a61,0x00000000,0x00030047,0x00000a62,0x00000000,0x00030047,0x00000a64, + 0x00000000,0x00030047,0x00000a66,0x00000000,0x00030047,0x00000a68,0x00000000,0x00030047, + 0x00000a69,0x00000000,0x00030047,0x00000a6a,0x00000000,0x00030047,0x00000a6c,0x00000000, + 0x00030047,0x00000a6e,0x00000000,0x00030047,0x00000a70,0x00000000,0x00030047,0x00000a71, + 0x00000000,0x00030047,0x00000a72,0x00000000,0x00030047,0x00000a74,0x00000000,0x00030047, + 0x00000a75,0x00000000,0x00030047,0x00000a78,0x00000000,0x00030047,0x00000a79,0x00000000, + 0x00030047,0x00000a7a,0x00000000,0x00030047,0x00000a7d,0x00000000,0x00030047,0x00000a7f, + 0x00000000,0x00030047,0x00000a80,0x00000000,0x00030047,0x00000a81,0x00000000,0x00030047, + 0x00000a82,0x00000000,0x00030047,0x00000a84,0x00000000,0x00030047,0x00000a85,0x00000000, + 0x00030047,0x00000a88,0x00000000,0x00030047,0x00000a89,0x00000000,0x00030047,0x00000a8a, + 0x00000000,0x00030047,0x00000a8d,0x00000000,0x00030047,0x00000a8f,0x00000000,0x00030047, + 0x00000a90,0x00000000,0x00030047,0x00000a91,0x00000000,0x00030047,0x00000a92,0x00000000, + 0x00030047,0x00000a94,0x00000000,0x00030047,0x00000a96,0x00000000,0x00030047,0x00000a98, + 0x00000000,0x00030047,0x00000a99,0x00000000,0x00030047,0x00000a9b,0x00000000,0x00030047, + 0x00000a9c,0x00000000,0x00030047,0x00000a9d,0x00000000,0x00030047,0x00000a9f,0x00000000, + 0x00030047,0x00000aa1,0x00000000,0x00030047,0x00000aa3,0x00000000,0x00030047,0x00000aa5, + 0x00000000,0x00030047,0x00000aa6,0x00000000,0x00030047,0x00000aa7,0x00000000,0x00030047, + 0x00000aa9,0x00000000,0x00030047,0x00000aab,0x00000000,0x00030047,0x00000aad,0x00000000, + 0x00030047,0x00000aaf,0x00000000,0x00030047,0x00000ab0,0x00000000,0x00030047,0x00000ab1, + 0x00000000,0x00030047,0x00000ab2,0x00000000,0x00030047,0x00000ab3,0x00000000,0x00030047, + 0x00000ab4,0x00000000,0x00030047,0x00000ab5,0x00000000,0x00030047,0x00000ab6,0x00000000, + 0x00030047,0x00000ab7,0x00000000,0x00030047,0x00000ab8,0x00000000,0x00030047,0x00000ab9, + 0x00000000,0x00030047,0x00000aba,0x00000000,0x00030047,0x00000abb,0x00000000,0x00030047, + 0x00000abc,0x00000000,0x00030047,0x00000abd,0x00000000,0x00030047,0x00000abe,0x00000000, + 0x00030047,0x00000ac0,0x00000000,0x00030047,0x00000ac2,0x00000000,0x00030047,0x00000ac3, + 0x00000000,0x00030047,0x00000ac5,0x00000000,0x00030047,0x00000ac6,0x00000000,0x00030047, + 0x00000ac7,0x00000000,0x00030047,0x00000ac8,0x00000000,0x00030047,0x00000ac9,0x00000000, + 0x00030047,0x00000acc,0x00000000,0x00030047,0x00000ace,0x00000000,0x00030047,0x00000acf, + 0x00000000,0x00030047,0x00000ad2,0x00000000,0x00030047,0x00000ad3,0x00000000,0x00030047, + 0x00000ad6,0x00000000,0x00030047,0x00000ad8,0x00000000,0x00030047,0x00000ad9,0x00000000, + 0x00030047,0x00000ada,0x00000000,0x00030047,0x00000adb,0x00000000,0x00030047,0x00000adc, + 0x00000000,0x00030047,0x00000add,0x00000000,0x00030047,0x00000ade,0x00000000,0x00030047, + 0x00000adf,0x00000000,0x00030047,0x00000ae0,0x00000000,0x00030047,0x00000ae1,0x00000000, + 0x00030047,0x00000ae2,0x00000000,0x00030047,0x00000ae3,0x00000000,0x00030047,0x00000ae4, + 0x00000000,0x00030047,0x00000ae6,0x00000000,0x00030047,0x00000ae8,0x00000000,0x00030047, + 0x00000ae9,0x00000000,0x00030047,0x00000aea,0x00000000,0x00030047,0x00000aec,0x00000000, + 0x00030047,0x00000aee,0x00000000,0x00030047,0x00000af0,0x00000000,0x00030047,0x00000af2, + 0x00000000,0x00030047,0x00000af3,0x00000000,0x00030047,0x00000af4,0x00000000,0x00030047, + 0x00000af5,0x00000000,0x00030047,0x00000af6,0x00000000,0x00030047,0x00000af8,0x00000000, + 0x00030047,0x00000afa,0x00000000,0x00030047,0x00000afb,0x00000000,0x00030047,0x00000afc, + 0x00000000,0x00030047,0x00000afe,0x00000000,0x00030047,0x00000b00,0x00000000,0x00030047, + 0x00000b02,0x00000000,0x00030047,0x00000b04,0x00000000,0x00030047,0x00000b05,0x00000000, + 0x00030047,0x00000b06,0x00000000,0x00030047,0x00000b08,0x00000000,0x00030047,0x00000b0a, + 0x00000000,0x00030047,0x00000b0c,0x00000000,0x00030047,0x00000b0d,0x00000000,0x00030047, + 0x00000b0e,0x00000000,0x00030047,0x00000b10,0x00000000,0x00030047,0x00000b12,0x00000000, + 0x00030047,0x00000b14,0x00000000,0x00030047,0x00000b15,0x00000000,0x00030047,0x00000b16, + 0x00000000,0x00030047,0x00000b18,0x00000000,0x00030047,0x00000b19,0x00000000,0x00030047, + 0x00000b1c,0x00000000,0x00030047,0x00000b1d,0x00000000,0x00030047,0x00000b1e,0x00000000, + 0x00030047,0x00000b21,0x00000000,0x00030047,0x00000b23,0x00000000,0x00030047,0x00000b24, + 0x00000000,0x00030047,0x00000b25,0x00000000,0x00030047,0x00000b26,0x00000000,0x00030047, + 0x00000b28,0x00000000,0x00030047,0x00000b29,0x00000000,0x00030047,0x00000b2c,0x00000000, + 0x00030047,0x00000b2d,0x00000000,0x00030047,0x00000b2e,0x00000000,0x00030047,0x00000b31, + 0x00000000,0x00030047,0x00000b33,0x00000000,0x00030047,0x00000b34,0x00000000,0x00030047, + 0x00000b35,0x00000000,0x00030047,0x00000b36,0x00000000,0x00030047,0x00000b38,0x00000000, + 0x00030047,0x00000b3a,0x00000000,0x00030047,0x00000b3c,0x00000000,0x00030047,0x00000b3d, + 0x00000000,0x00030047,0x00000b3f,0x00000000,0x00030047,0x00000b40,0x00000000,0x00030047, + 0x00000b41,0x00000000,0x00030047,0x00000b43,0x00000000,0x00030047,0x00000b45,0x00000000, + 0x00030047,0x00000b47,0x00000000,0x00030047,0x00000b49,0x00000000,0x00030047,0x00000b4a, + 0x00000000,0x00030047,0x00000b4c,0x00000000,0x00030047,0x00000b4d,0x00000000,0x00030047, + 0x00000b4e,0x00000000,0x00030047,0x00000b52,0x00000000,0x00030047,0x00000b53,0x00000000, + 0x00030047,0x00000b55,0x00000000,0x00030047,0x00000b56,0x00000000,0x00030047,0x00000b57, + 0x00000000,0x00030047,0x00000b59,0x00000000,0x00030047,0x00000b5b,0x00000000,0x00030047, + 0x00000b5c,0x00000000,0x00030047,0x00000b5d,0x00000000,0x00030047,0x00000b5e,0x00000000, + 0x00030047,0x00000b68,0x00000000,0x00030047,0x00000b69,0x00000000,0x00030047,0x00000b6a, + 0x00000000,0x00030047,0x00000b6b,0x00000000,0x00030047,0x00000b6c,0x00000000,0x00030047, + 0x00000b6d,0x00000000,0x00030047,0x00000b6e,0x00000000,0x00030047,0x00000b6f,0x00000000, + 0x00030047,0x00000b71,0x00000000,0x00030047,0x00000b73,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040020,0x00000007, + 0x00000007,0x00000006,0x00040017,0x0000000c,0x00000006,0x00000002,0x00040020,0x0000000d, + 0x00000007,0x0000000c,0x00040015,0x00000012,0x00000020,0x00000000,0x00040020,0x00000013, + 0x00000007,0x00000012,0x00040017,0x00000024,0x00000006,0x00000003,0x00040017,0x0000002f, + 0x00000006,0x00000004,0x00040020,0x00000034,0x00000007,0x0000002f,0x00040018,0x00000035, + 0x0000000c,0x00000002,0x00040020,0x00000045,0x00000007,0x00000024,0x00040015,0x00000083, + 0x00000020,0x00000001,0x00040017,0x00000084,0x00000083,0x00000002,0x00040020,0x00000085, + 0x00000007,0x00000084,0x0004002b,0x00000012,0x000000ab,0x00000000,0x0004002b,0x00000012, + 0x000000ae,0x00000001,0x0004002b,0x00000012,0x000000c1,0x00000002,0x0004002b,0x00000012, + 0x000000d8,0x00000003,0x0004002b,0x00000006,0x000000e1,0x3f800000,0x0004002b,0x00000006, + 0x000000e2,0x00000000,0x00020014,0x000000f5,0x0004002b,0x00000006,0x00000123,0x3d897143, + 0x0004002b,0x00000006,0x00000127,0x3bbf4590,0x0004002b,0x00000006,0x0000012e,0x4253ee82, + 0x00030030,0x000000f5,0x00000139,0x0004002b,0x00000006,0x0000014d,0x3e99999a,0x0004002b, + 0x00000006,0x0000014e,0x3f170a3d,0x0004002b,0x00000006,0x0000014f,0x3de147ae,0x0004002b, + 0x00000006,0x00000169,0x388205ff,0x0004002b,0x00000006,0x000001cf,0x40000000,0x0004002b, + 0x00000006,0x000001d6,0x3f000000,0x00040017,0x000001dc,0x000000f5,0x00000003,0x00040020, + 0x00000258,0x00000007,0x00000083,0x0004002b,0x00000083,0x0000025a,0x00000000,0x0004002b, + 0x00000083,0x00000261,0x00000003,0x0004002b,0x00000006,0x00000273,0x3e800000,0x0004002b, + 0x00000006,0x00000278,0x41800000,0x0004002b,0x00000006,0x0000027d,0x41400000,0x0004002b, + 0x00000006,0x00000283,0x40400000,0x0004002b,0x00000083,0x0000028f,0x00000001,0x00030030, + 0x000000f5,0x000002aa,0x0004002b,0x00000006,0x000002fe,0x3a000000,0x0004002b,0x00000006, + 0x00000300,0xc2000000,0x0004002b,0x00000006,0x00000310,0x3a808081,0x00040017,0x00000313, + 0x000000f5,0x00000002,0x00040017,0x0000031d,0x00000012,0x00000002,0x00040020,0x0000031e, + 0x00000007,0x0000031d,0x0003001d,0x00000320,0x0000031d,0x0003001e,0x00000321,0x00000320, + 0x00040020,0x00000322,0x00000002,0x00000321,0x0004003b,0x00000322,0x00000323,0x00000002, + 0x00040020,0x00000325,0x00000002,0x0000031d,0x0004002b,0x00000012,0x0000032c,0x00000300, + 0x00030030,0x000000f5,0x00000333,0x0004002b,0x00000012,0x00000338,0x00000200,0x0004002b, + 0x00000006,0x00000342,0xbf800000,0x00030030,0x000000f5,0x0000034c,0x0004002b,0x00000012, + 0x00000352,0x00000010,0x00090019,0x00000358,0x00000006,0x00000006,0x00000000,0x00000000, + 0x00000000,0x00000002,0x00000000,0x00040020,0x00000359,0x00000000,0x00000358,0x0004003b, + 0x00000359,0x0000035a,0x00000000,0x0005002c,0x00000084,0x0000035c,0x0000025a,0x0000025a, + 0x00030030,0x000000f5,0x00000365,0x0004002b,0x00000012,0x0000036a,0x00000400,0x00040020, + 0x00000370,0x00000007,0x00000035,0x0003001d,0x00000372,0x0000002f,0x0003001e,0x00000373, + 0x00000372,0x00040020,0x00000374,0x00000002,0x00000373,0x0004003b,0x00000374,0x00000375, + 0x00000002,0x0004002b,0x00000012,0x00000377,0x00000004,0x00040020,0x0000037b,0x00000002, + 0x0000002f,0x00040020,0x00000387,0x00000001,0x0000002f,0x0004003b,0x00000387,0x00000388, + 0x00000001,0x0004002b,0x00000012,0x000003a8,0x0000000f,0x00090019,0x000003f1,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000003f2, + 0x00000000,0x000003f1,0x0004003b,0x000003f2,0x000003f3,0x00000000,0x0002001a,0x000003f5, + 0x00040020,0x000003f6,0x00000000,0x000003f5,0x0004003b,0x000003f6,0x000003f7,0x00000000, + 0x0003001b,0x000003f9,0x000003f1,0x00030030,0x000000f5,0x00000404,0x0004002b,0x00000083, + 0x00000410,0x00000004,0x0004003b,0x00000359,0x0000041a,0x00000000,0x00040020,0x00000436, + 0x00000003,0x0000002f,0x0004003b,0x00000436,0x00000437,0x00000003,0x0004003b,0x00000436, + 0x00000439,0x00000003,0x00090019,0x00000441,0x00000012,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000002,0x00000021,0x00040020,0x00000442,0x00000000,0x00000441,0x0004003b, + 0x00000442,0x00000443,0x00000000,0x00040017,0x00000446,0x00000012,0x00000004,0x0004002b, + 0x00000012,0x0000044b,0x00000011,0x00040020,0x00000453,0x00000001,0x00000012,0x0004003b, + 0x00000453,0x00000454,0x00000001,0x0004002b,0x00000012,0x00000460,0x00010000,0x00040020, + 0x00000463,0x00000001,0x00000006,0x0004003b,0x00000463,0x00000464,0x00000001,0x0004002b, + 0x00000006,0x00000468,0x45000000,0x0004002b,0x00000012,0x00000480,0x0001ffff,0x0004001e, + 0x00000491,0x00000006,0x00000006,0x00040020,0x00000492,0x00000002,0x00000491,0x0004003b, + 0x00000492,0x00000493,0x00000002,0x00040020,0x0000049d,0x00000002,0x00000006,0x0006002c, + 0x00000024,0x000004be,0x000000e1,0x000000e1,0x000000e1,0x0006002c,0x00000024,0x000004bf, + 0x000001d6,0x000001d6,0x000001d6,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003b,0x00000007,0x00000b5c,0x00000007,0x0004003b,0x00000007, + 0x00000b5d,0x00000007,0x0004003b,0x00000007,0x00000b5e,0x00000007,0x0004003b,0x00000045, + 0x00000b4a,0x00000007,0x0004003b,0x0000000d,0x00000b4b,0x00000007,0x0004003b,0x00000007, + 0x00000b4c,0x00000007,0x0004003b,0x00000007,0x00000b4d,0x00000007,0x0004003b,0x00000045, + 0x00000b4e,0x00000007,0x0004003b,0x00000045,0x00000b40,0x00000007,0x0004003b,0x00000045, + 0x00000b41,0x00000007,0x0004003b,0x00000007,0x00000b3d,0x00000007,0x0004003b,0x0000000d, + 0x00000b35,0x00000007,0x0004003b,0x0000000d,0x00000b36,0x00000007,0x0004003b,0x00000007, + 0x00000b2e,0x00000007,0x0004003b,0x0000000d,0x00000b25,0x00000007,0x0004003b,0x00000007, + 0x00000b26,0x00000007,0x0004003b,0x00000007,0x00000b1e,0x00000007,0x0004003b,0x0000000d, + 0x00000b15,0x00000007,0x0004003b,0x00000007,0x00000b16,0x00000007,0x0004003b,0x0000000d, + 0x00000b0d,0x00000007,0x0004003b,0x0000000d,0x00000b0e,0x00000007,0x0004003b,0x0000000d, + 0x00000b05,0x00000007,0x0004003b,0x0000000d,0x00000b06,0x00000007,0x0004003b,0x00000045, + 0x00000afb,0x00000007,0x0004003b,0x00000045,0x00000afc,0x00000007,0x0004003b,0x00000007, + 0x00000af3,0x00000007,0x0004003b,0x00000007,0x00000af4,0x00000007,0x0004003b,0x00000007, + 0x00000af5,0x00000007,0x0004003b,0x00000007,0x00000af6,0x00000007,0x0004003b,0x00000045, + 0x00000ae9,0x00000007,0x0004003b,0x00000045,0x00000aea,0x00000007,0x0004003b,0x00000007, + 0x00000ae1,0x00000007,0x0004003b,0x00000007,0x00000ae2,0x00000007,0x0004003b,0x00000007, + 0x00000ae3,0x00000007,0x0004003b,0x00000007,0x00000ae4,0x00000007,0x0004003b,0x00000007, + 0x00000ab0,0x00000007,0x0004003b,0x00000045,0x00000ab1,0x00000007,0x0004003b,0x00000045, + 0x00000ab2,0x00000007,0x0004003b,0x00000045,0x00000ab3,0x00000007,0x0004003b,0x0000000d, + 0x00000ab4,0x00000007,0x0004003b,0x00000007,0x00000ab5,0x00000007,0x0004003b,0x00000007, + 0x00000ab6,0x00000007,0x0004003b,0x00000007,0x00000ab7,0x00000007,0x0004003b,0x00000045, + 0x00000ab8,0x00000007,0x0004003b,0x00000045,0x00000ab9,0x00000007,0x0004003b,0x00000007, + 0x00000aba,0x00000007,0x0004003b,0x00000007,0x00000abb,0x00000007,0x0004003b,0x00000007, + 0x00000abc,0x00000007,0x0004003b,0x00000007,0x00000abd,0x00000007,0x0004003b,0x00000045, + 0x00000abe,0x00000007,0x0004003b,0x00000045,0x00000aa6,0x00000007,0x0004003b,0x00000045, + 0x00000aa7,0x00000007,0x0004003b,0x00000045,0x00000a9c,0x00000007,0x0004003b,0x00000045, + 0x00000a9d,0x00000007,0x0004003b,0x00000007,0x00000a99,0x00000007,0x0004003b,0x0000000d, + 0x00000a91,0x00000007,0x0004003b,0x0000000d,0x00000a92,0x00000007,0x0004003b,0x00000007, + 0x00000a8a,0x00000007,0x0004003b,0x0000000d,0x00000a81,0x00000007,0x0004003b,0x00000007, + 0x00000a82,0x00000007,0x0004003b,0x00000007,0x00000a7a,0x00000007,0x0004003b,0x0000000d, + 0x00000a71,0x00000007,0x0004003b,0x00000007,0x00000a72,0x00000007,0x0004003b,0x0000000d, + 0x00000a69,0x00000007,0x0004003b,0x0000000d,0x00000a6a,0x00000007,0x0004003b,0x0000000d, + 0x00000a61,0x00000007,0x0004003b,0x0000000d,0x00000a62,0x00000007,0x0004003b,0x00000045, + 0x00000a57,0x00000007,0x0004003b,0x00000045,0x00000a58,0x00000007,0x0004003b,0x00000007, + 0x00000a4f,0x00000007,0x0004003b,0x00000007,0x00000a50,0x00000007,0x0004003b,0x00000007, + 0x00000a51,0x00000007,0x0004003b,0x00000007,0x00000a52,0x00000007,0x0004003b,0x00000045, + 0x00000a45,0x00000007,0x0004003b,0x00000045,0x00000a46,0x00000007,0x0004003b,0x00000007, + 0x00000a3d,0x00000007,0x0004003b,0x00000007,0x00000a3e,0x00000007,0x0004003b,0x00000007, + 0x00000a3f,0x00000007,0x0004003b,0x00000007,0x00000a40,0x00000007,0x0004003b,0x00000007, + 0x00000a0c,0x00000007,0x0004003b,0x00000045,0x00000a0d,0x00000007,0x0004003b,0x00000045, + 0x00000a0e,0x00000007,0x0004003b,0x00000045,0x00000a0f,0x00000007,0x0004003b,0x0000000d, + 0x00000a10,0x00000007,0x0004003b,0x00000007,0x00000a11,0x00000007,0x0004003b,0x00000007, + 0x00000a12,0x00000007,0x0004003b,0x00000007,0x00000a13,0x00000007,0x0004003b,0x00000045, + 0x00000a14,0x00000007,0x0004003b,0x00000045,0x00000a15,0x00000007,0x0004003b,0x00000007, + 0x00000a16,0x00000007,0x0004003b,0x00000007,0x00000a17,0x00000007,0x0004003b,0x00000007, + 0x00000a18,0x00000007,0x0004003b,0x00000007,0x00000a19,0x00000007,0x0004003b,0x00000045, + 0x00000a1a,0x00000007,0x0004003b,0x00000045,0x00000a02,0x00000007,0x0004003b,0x00000045, + 0x00000a03,0x00000007,0x0004003b,0x00000045,0x000009f8,0x00000007,0x0004003b,0x00000045, + 0x000009f9,0x00000007,0x0004003b,0x00000007,0x000009f5,0x00000007,0x0004003b,0x0000000d, + 0x000009ed,0x00000007,0x0004003b,0x0000000d,0x000009ee,0x00000007,0x0004003b,0x00000007, + 0x000009e6,0x00000007,0x0004003b,0x0000000d,0x000009dd,0x00000007,0x0004003b,0x00000007, + 0x000009de,0x00000007,0x0004003b,0x00000007,0x000009d6,0x00000007,0x0004003b,0x0000000d, + 0x000009cd,0x00000007,0x0004003b,0x00000007,0x000009ce,0x00000007,0x0004003b,0x0000000d, + 0x000009c5,0x00000007,0x0004003b,0x0000000d,0x000009c6,0x00000007,0x0004003b,0x0000000d, + 0x000009bd,0x00000007,0x0004003b,0x0000000d,0x000009be,0x00000007,0x0004003b,0x00000045, + 0x000009b3,0x00000007,0x0004003b,0x00000045,0x000009b4,0x00000007,0x0004003b,0x00000007, + 0x000009ab,0x00000007,0x0004003b,0x00000007,0x000009ac,0x00000007,0x0004003b,0x00000007, + 0x000009ad,0x00000007,0x0004003b,0x00000007,0x000009ae,0x00000007,0x0004003b,0x00000045, + 0x000009a1,0x00000007,0x0004003b,0x00000045,0x000009a2,0x00000007,0x0004003b,0x00000007, + 0x00000999,0x00000007,0x0004003b,0x00000007,0x0000099a,0x00000007,0x0004003b,0x00000007, + 0x0000099b,0x00000007,0x0004003b,0x00000007,0x0000099c,0x00000007,0x0004003b,0x00000007, + 0x00000968,0x00000007,0x0004003b,0x00000045,0x00000969,0x00000007,0x0004003b,0x00000045, + 0x0000096a,0x00000007,0x0004003b,0x00000045,0x0000096b,0x00000007,0x0004003b,0x0000000d, + 0x0000096c,0x00000007,0x0004003b,0x00000007,0x0000096d,0x00000007,0x0004003b,0x00000007, + 0x0000096e,0x00000007,0x0004003b,0x00000007,0x0000096f,0x00000007,0x0004003b,0x00000045, + 0x00000970,0x00000007,0x0004003b,0x00000045,0x00000971,0x00000007,0x0004003b,0x00000007, + 0x00000972,0x00000007,0x0004003b,0x00000007,0x00000973,0x00000007,0x0004003b,0x00000007, + 0x00000974,0x00000007,0x0004003b,0x00000007,0x00000975,0x00000007,0x0004003b,0x00000045, + 0x00000976,0x00000007,0x0004003b,0x00000007,0x00000961,0x00000007,0x0004003b,0x0000000d, + 0x00000958,0x00000007,0x0004003b,0x00000007,0x00000959,0x00000007,0x0004003b,0x00000007, + 0x00000951,0x00000007,0x0004003b,0x0000000d,0x00000948,0x00000007,0x0004003b,0x00000007, + 0x00000949,0x00000007,0x0004003b,0x00000007,0x00000941,0x00000007,0x0004003b,0x0000000d, + 0x00000938,0x00000007,0x0004003b,0x00000007,0x00000939,0x00000007,0x0004003b,0x00000007, + 0x00000931,0x00000007,0x0004003b,0x0000000d,0x00000928,0x00000007,0x0004003b,0x00000007, + 0x00000929,0x00000007,0x0004003b,0x00000007,0x00000908,0x00000007,0x0004003b,0x00000045, + 0x00000909,0x00000007,0x0004003b,0x00000045,0x0000090a,0x00000007,0x0004003b,0x00000045, + 0x0000090b,0x00000007,0x0004003b,0x00000007,0x0000090c,0x00000007,0x0004003b,0x00000045, + 0x0000090d,0x00000007,0x0004003b,0x00000007,0x0000090e,0x00000007,0x0004003b,0x00000045, + 0x0000090f,0x00000007,0x0004003b,0x00000045,0x00000910,0x00000007,0x0004003b,0x00000045, + 0x00000911,0x00000007,0x0004003b,0x00000045,0x000008fe,0x00000007,0x0004003b,0x00000045, + 0x000008ff,0x00000007,0x0004003b,0x00000045,0x000008f4,0x00000007,0x0004003b,0x00000045, + 0x000008f5,0x00000007,0x0004003b,0x00000007,0x000008f1,0x00000007,0x0004003b,0x0000000d, + 0x000008e9,0x00000007,0x0004003b,0x0000000d,0x000008ea,0x00000007,0x0004003b,0x00000007, + 0x000008e2,0x00000007,0x0004003b,0x0000000d,0x000008d9,0x00000007,0x0004003b,0x00000007, + 0x000008da,0x00000007,0x0004003b,0x00000007,0x000008d2,0x00000007,0x0004003b,0x0000000d, + 0x000008c9,0x00000007,0x0004003b,0x00000007,0x000008ca,0x00000007,0x0004003b,0x0000000d, + 0x000008c1,0x00000007,0x0004003b,0x0000000d,0x000008c2,0x00000007,0x0004003b,0x0000000d, + 0x000008b9,0x00000007,0x0004003b,0x0000000d,0x000008ba,0x00000007,0x0004003b,0x00000045, + 0x000008af,0x00000007,0x0004003b,0x00000045,0x000008b0,0x00000007,0x0004003b,0x00000007, + 0x000008a7,0x00000007,0x0004003b,0x00000007,0x000008a8,0x00000007,0x0004003b,0x00000007, + 0x000008a9,0x00000007,0x0004003b,0x00000007,0x000008aa,0x00000007,0x0004003b,0x00000045, + 0x0000089d,0x00000007,0x0004003b,0x00000045,0x0000089e,0x00000007,0x0004003b,0x00000007, + 0x00000895,0x00000007,0x0004003b,0x00000007,0x00000896,0x00000007,0x0004003b,0x00000007, + 0x00000897,0x00000007,0x0004003b,0x00000007,0x00000898,0x00000007,0x0004003b,0x00000007, + 0x00000864,0x00000007,0x0004003b,0x00000045,0x00000865,0x00000007,0x0004003b,0x00000045, + 0x00000866,0x00000007,0x0004003b,0x00000045,0x00000867,0x00000007,0x0004003b,0x0000000d, + 0x00000868,0x00000007,0x0004003b,0x00000007,0x00000869,0x00000007,0x0004003b,0x00000007, + 0x0000086a,0x00000007,0x0004003b,0x00000007,0x0000086b,0x00000007,0x0004003b,0x00000045, + 0x0000086c,0x00000007,0x0004003b,0x00000045,0x0000086d,0x00000007,0x0004003b,0x00000007, + 0x0000086e,0x00000007,0x0004003b,0x00000007,0x0000086f,0x00000007,0x0004003b,0x00000007, + 0x00000870,0x00000007,0x0004003b,0x00000007,0x00000871,0x00000007,0x0004003b,0x00000045, + 0x00000872,0x00000007,0x0004003b,0x00000007,0x0000085d,0x00000007,0x0004003b,0x0000000d, + 0x00000854,0x00000007,0x0004003b,0x00000007,0x00000855,0x00000007,0x0004003b,0x00000007, + 0x0000084d,0x00000007,0x0004003b,0x0000000d,0x00000844,0x00000007,0x0004003b,0x00000007, + 0x00000845,0x00000007,0x0004003b,0x00000007,0x0000083d,0x00000007,0x0004003b,0x0000000d, + 0x00000834,0x00000007,0x0004003b,0x00000007,0x00000835,0x00000007,0x0004003b,0x00000007, + 0x0000082d,0x00000007,0x0004003b,0x0000000d,0x00000824,0x00000007,0x0004003b,0x00000007, + 0x00000825,0x00000007,0x0004003b,0x00000007,0x00000804,0x00000007,0x0004003b,0x00000045, + 0x00000805,0x00000007,0x0004003b,0x00000045,0x00000806,0x00000007,0x0004003b,0x00000045, + 0x00000807,0x00000007,0x0004003b,0x00000007,0x00000808,0x00000007,0x0004003b,0x00000045, + 0x00000809,0x00000007,0x0004003b,0x00000007,0x0000080a,0x00000007,0x0004003b,0x00000045, + 0x0000080b,0x00000007,0x0004003b,0x00000045,0x0000080c,0x00000007,0x0004003b,0x00000045, + 0x0000080d,0x00000007,0x0004003b,0x00000045,0x000007fa,0x00000007,0x0004003b,0x00000045, + 0x000007fb,0x00000007,0x0004003b,0x00000045,0x000007f0,0x00000007,0x0004003b,0x00000045, + 0x000007f1,0x00000007,0x0004003b,0x00000045,0x000007e6,0x00000007,0x0004003b,0x00000045, + 0x000007e7,0x00000007,0x0004003b,0x00000045,0x000007dc,0x00000007,0x0004003b,0x00000045, + 0x000007dd,0x00000007,0x0004003b,0x00000045,0x000007d2,0x00000007,0x0004003b,0x00000045, + 0x000007d3,0x00000007,0x0004003b,0x00000045,0x000007c8,0x00000007,0x0004003b,0x00000045, + 0x000007c9,0x00000007,0x0004003b,0x00000045,0x000007be,0x00000007,0x0004003b,0x00000045, + 0x000007bf,0x00000007,0x0004003b,0x00000045,0x000007b4,0x00000007,0x0004003b,0x00000045, + 0x000007b5,0x00000007,0x0004003b,0x00000045,0x000007aa,0x00000007,0x0004003b,0x00000045, + 0x000007ab,0x00000007,0x0004003b,0x00000045,0x000007a0,0x00000007,0x0004003b,0x00000045, + 0x000007a1,0x00000007,0x0004003b,0x00000045,0x00000796,0x00000007,0x0004003b,0x00000045, + 0x00000797,0x00000007,0x0004003b,0x00000045,0x0000078c,0x00000007,0x0004003b,0x00000045, + 0x0000078d,0x00000007,0x0004003b,0x00000045,0x00000782,0x00000007,0x0004003b,0x00000045, + 0x00000783,0x00000007,0x0004003b,0x00000045,0x00000778,0x00000007,0x0004003b,0x00000045, + 0x00000779,0x00000007,0x0004003b,0x00000007,0x00000768,0x00000007,0x0004003b,0x00000045, + 0x00000769,0x00000007,0x0004003b,0x00000045,0x00000647,0x00000007,0x0004003b,0x00000034, + 0x00000648,0x00000007,0x0004003b,0x00000045,0x00000649,0x00000007,0x0004003b,0x00000045, + 0x0000064a,0x00000007,0x0004003b,0x00000007,0x0000064b,0x00000007,0x0004003b,0x00000007, + 0x0000064c,0x00000007,0x0004003b,0x00000045,0x0000064d,0x00000007,0x0004003b,0x00000007, + 0x0000064e,0x00000007,0x0004003b,0x00000007,0x0000064f,0x00000007,0x0004003b,0x00000007, + 0x00000650,0x00000007,0x0004003b,0x00000007,0x00000651,0x00000007,0x0004003b,0x00000007, + 0x00000652,0x00000007,0x0004003b,0x00000007,0x00000653,0x00000007,0x0004003b,0x00000007, + 0x00000654,0x00000007,0x0004003b,0x00000045,0x00000655,0x00000007,0x0004003b,0x00000007, + 0x00000656,0x00000007,0x0004003b,0x00000007,0x00000657,0x00000007,0x0004003b,0x00000045, + 0x00000658,0x00000007,0x0004003b,0x00000007,0x00000659,0x00000007,0x0004003b,0x00000258, + 0x0000065a,0x00000007,0x0004003b,0x00000007,0x0000065b,0x00000007,0x0004003b,0x00000007, + 0x0000065c,0x00000007,0x0004003b,0x00000045,0x0000065d,0x00000007,0x0004003b,0x00000045, + 0x0000065e,0x00000007,0x0004003b,0x00000045,0x0000065f,0x00000007,0x0004003b,0x00000007, + 0x00000660,0x00000007,0x0004003b,0x00000007,0x00000661,0x00000007,0x0004003b,0x00000045, + 0x00000662,0x00000007,0x0004003b,0x00000045,0x00000663,0x00000007,0x0004003b,0x00000045, + 0x00000664,0x00000007,0x0004003b,0x00000007,0x00000665,0x00000007,0x0004003b,0x00000007, + 0x00000666,0x00000007,0x0004003b,0x00000045,0x00000667,0x00000007,0x0004003b,0x00000045, + 0x00000668,0x00000007,0x0004003b,0x00000007,0x00000669,0x00000007,0x0004003b,0x00000007, + 0x0000066a,0x00000007,0x0004003b,0x00000045,0x0000066b,0x00000007,0x0004003b,0x00000045, + 0x0000066c,0x00000007,0x0004003b,0x00000045,0x0000066d,0x00000007,0x0004003b,0x00000045, + 0x00000636,0x00000007,0x0004003b,0x00000045,0x00000637,0x00000007,0x0004003b,0x00000034, + 0x00000638,0x00000007,0x0004003b,0x00000013,0x00000639,0x00000007,0x0004003b,0x00000007, + 0x0000063a,0x00000007,0x0004003b,0x00000045,0x0000063b,0x00000007,0x0004003b,0x00000013, + 0x00000631,0x00000007,0x0004003b,0x00000013,0x00000632,0x00000007,0x0004003b,0x00000370, + 0x00000624,0x00000007,0x0004003b,0x00000034,0x00000618,0x00000007,0x0004003b,0x00000034, + 0x00000619,0x00000007,0x0004003b,0x0000000d,0x00000613,0x00000007,0x0004003b,0x0000000d, + 0x00000614,0x00000007,0x0004003b,0x00000370,0x00000606,0x00000007,0x0004003b,0x0000000d, + 0x000005fe,0x00000007,0x0004003b,0x0000000d,0x000005ff,0x00000007,0x0004003b,0x00000007, + 0x000005eb,0x00000007,0x0004003b,0x00000007,0x000005e8,0x00000007,0x0004003b,0x00000007, + 0x000005e5,0x00000007,0x0004003b,0x0000031e,0x000004f2,0x00000007,0x0004003b,0x00000007, + 0x000004f3,0x00000007,0x0004003b,0x00000007,0x000004f4,0x00000007,0x0004003b,0x00000007, + 0x000004f5,0x00000007,0x0004003b,0x00000013,0x000004f6,0x00000007,0x0004003b,0x00000013, + 0x000004f7,0x00000007,0x0004003b,0x00000034,0x000004f8,0x00000007,0x0004003b,0x00000007, + 0x000004f9,0x00000007,0x0004003b,0x00000370,0x000004fa,0x00000007,0x0004003b,0x00000034, + 0x000004fb,0x00000007,0x0004003b,0x00000034,0x000004fc,0x00000007,0x0004003b,0x0000000d, + 0x000004fd,0x00000007,0x0004003b,0x0000000d,0x000004fe,0x00000007,0x0004003b,0x0000000d, + 0x000004ff,0x00000007,0x0004003b,0x00000007,0x00000500,0x00000007,0x0004003b,0x00000013, + 0x00000501,0x00000007,0x0004003b,0x00000007,0x00000502,0x00000007,0x0004003b,0x00000370, + 0x00000503,0x00000007,0x0004003b,0x00000034,0x00000504,0x00000007,0x0004003b,0x00000034, + 0x00000505,0x00000007,0x0004003b,0x0000000d,0x00000506,0x00000007,0x0004003b,0x00000007, + 0x00000507,0x00000007,0x0004003b,0x00000007,0x00000508,0x00000007,0x0004003b,0x00000007, + 0x00000509,0x00000007,0x0004003b,0x00000007,0x0000050a,0x00000007,0x0004003b,0x00000013, + 0x0000050b,0x00000007,0x0004003b,0x00000013,0x0000050c,0x00000007,0x0004003b,0x00000034, + 0x0000050d,0x00000007,0x0004003b,0x00000045,0x0000050e,0x00000007,0x0004003b,0x00000034, + 0x0000050f,0x00000007,0x0004003b,0x00000013,0x00000510,0x00000007,0x0004003b,0x00000007, + 0x000004ed,0x00000007,0x0004003b,0x00000007,0x000004ee,0x00000007,0x0004003b,0x00000007, + 0x000004e5,0x00000007,0x0004003b,0x00000007,0x000004e6,0x00000007,0x0004003b,0x00000034, + 0x000004d9,0x00000007,0x0004003b,0x00000034,0x000004da,0x00000007,0x0004003b,0x00000034, + 0x000004cd,0x00000007,0x0004003b,0x00000034,0x000004ce,0x00000007,0x0004003b,0x00000013, + 0x000004c8,0x00000007,0x0004003b,0x00000013,0x000004c9,0x00000007,0x0004003b,0x00000013, + 0x000004c5,0x00000007,0x0004003b,0x00000013,0x000004c0,0x00000007,0x0004003b,0x00000013, + 0x000004c1,0x00000007,0x0004003b,0x00000085,0x0000043b,0x00000007,0x0004003b,0x00000013, + 0x00000440,0x00000007,0x0004003b,0x00000013,0x00000449,0x00000007,0x0004003b,0x00000013, + 0x0000044d,0x00000007,0x0004003b,0x00000013,0x0000044f,0x00000007,0x0004003b,0x00000013, + 0x00000459,0x00000007,0x0004003b,0x00000013,0x0000045c,0x00000007,0x0004003b,0x00000007, + 0x00000462,0x00000007,0x0004003b,0x00000258,0x00000466,0x00000007,0x0004003b,0x00000034, + 0x00000473,0x00000007,0x0004003b,0x00000007,0x00000474,0x00000007,0x0004003b,0x00000034, + 0x00000476,0x00000007,0x0004003b,0x00000007,0x00000477,0x00000007,0x0004003b,0x00000007, + 0x0000047e,0x00000007,0x0004003b,0x00000013,0x00000482,0x00000007,0x0004003b,0x00000013, + 0x00000484,0x00000007,0x0004003b,0x00000007,0x00000486,0x00000007,0x0004003b,0x00000034, + 0x00000488,0x00000007,0x0004003b,0x00000034,0x00000489,0x00000007,0x0004003b,0x00000045, + 0x00000496,0x00000007,0x0004003b,0x0000000d,0x00000499,0x00000007,0x0004003b,0x00000007, + 0x0000049c,0x00000007,0x0004003b,0x00000007,0x000004a0,0x00000007,0x0004003b,0x00000034, + 0x000004aa,0x00000007,0x0004003b,0x00000034,0x000004af,0x00000007,0x0004003d,0x0000002f, + 0x0000043c,0x00000388,0x0007004f,0x0000000c,0x0000043d,0x0000043c,0x0000043c,0x00000000, + 0x00000001,0x0006000c,0x0000000c,0x0000043e,0x00000001,0x00000008,0x0000043d,0x0004006e, + 0x00000084,0x0000043f,0x0000043e,0x0003003e,0x0000043b,0x0000043f,0x0004003d,0x00000441, + 0x00000444,0x00000443,0x0004003d,0x00000084,0x00000445,0x0000043b,0x00050062,0x00000446, + 0x00000447,0x00000444,0x00000445,0x00050051,0x00000012,0x00000448,0x00000447,0x00000000, + 0x0003003e,0x00000440,0x00000448,0x0004003d,0x00000012,0x0000044a,0x00000440,0x000500c2, + 0x00000012,0x0000044c,0x0000044a,0x0000044b,0x0003003e,0x0000044d,0x0000044c,0x0004003d, + 0x00000012,0x000004c3,0x0000044d,0x0003003e,0x000004c0,0x000004c3,0x0004003d,0x00000012, + 0x000004c4,0x000004c0,0x0003003e,0x000004c1,0x000004c4,0x0004003d,0x00000012,0x0000044e, + 0x000004c1,0x0003003e,0x00000449,0x0000044e,0x0004003d,0x00000012,0x00000450,0x00000449, + 0x0003003e,0x0000044f,0x00000450,0x0004003d,0x00000012,0x000004c7,0x0000044f,0x0003003e, + 0x000004c5,0x000004c7,0x0004003d,0x00000012,0x00000451,0x000004c5,0x0003003e,0x00000449, + 0x00000451,0x0004003d,0x00000012,0x00000452,0x00000449,0x0004003d,0x00000012,0x00000455, + 0x00000454,0x000500aa,0x000000f5,0x00000456,0x00000452,0x00000455,0x000300f7,0x00000458, + 0x00000000,0x000400fa,0x00000456,0x00000457,0x0000045b,0x000200f8,0x00000457,0x0004003d, + 0x00000012,0x0000045a,0x00000440,0x0003003e,0x00000459,0x0000045a,0x000200f9,0x00000458, + 0x000200f8,0x0000045b,0x0003003e,0x0000045c,0x00000455,0x0004003d,0x00000012,0x000004cb, + 0x0000045c,0x0003003e,0x000004c8,0x000004cb,0x0004003d,0x00000012,0x000004cc,0x000004c8, + 0x0003003e,0x000004c9,0x000004cc,0x0004003d,0x00000012,0x0000045e,0x000004c9,0x000500c4, + 0x00000012,0x0000045f,0x0000045e,0x0000044b,0x00050080,0x00000012,0x00000461,0x0000045f, + 0x00000460,0x0003003e,0x00000459,0x00000461,0x000200f9,0x00000458,0x000200f8,0x00000458, + 0x0004003d,0x00000006,0x00000465,0x00000464,0x0003003e,0x00000462,0x00000465,0x0004003d, + 0x00000006,0x00000467,0x00000462,0x00050085,0x00000006,0x00000469,0x00000467,0x00000468, + 0x0006000c,0x00000006,0x0000046a,0x00000001,0x00000001,0x00000469,0x0004006e,0x00000083, + 0x0000046b,0x0000046a,0x0003003e,0x00000466,0x0000046b,0x0004003d,0x00000441,0x0000046c, + 0x00000443,0x0004003d,0x00000084,0x0000046d,0x0000043b,0x0004003d,0x00000012,0x0000046e, + 0x00000459,0x0004003d,0x00000083,0x0000046f,0x00000466,0x0004007c,0x00000012,0x00000470, + 0x0000046f,0x00050080,0x00000012,0x00000471,0x0000046e,0x00000470,0x00070050,0x00000446, + 0x00000472,0x00000471,0x00000471,0x00000471,0x00000471,0x00040063,0x0000046c,0x0000046d, + 0x00000472,0x0003003e,0x00000474,0x000000e2,0x0004003d,0x00000006,0x000004d0,0x00000474, + 0x00050041,0x00000007,0x000004d1,0x000004cd,0x000000ab,0x0003003e,0x000004d1,0x000004d0, + 0x0004003d,0x00000006,0x000004d2,0x00000474,0x00050041,0x00000007,0x000004d3,0x000004cd, + 0x000000ae,0x0003003e,0x000004d3,0x000004d2,0x0004003d,0x00000006,0x000004d4,0x00000474, + 0x00050041,0x00000007,0x000004d5,0x000004cd,0x000000c1,0x0003003e,0x000004d5,0x000004d4, + 0x0004003d,0x00000006,0x000004d6,0x00000474,0x00050041,0x00000007,0x000004d7,0x000004cd, + 0x000000d8,0x0003003e,0x000004d7,0x000004d6,0x0004003d,0x0000002f,0x000004d8,0x000004cd, + 0x0003003e,0x000004ce,0x000004d8,0x0004003d,0x0000002f,0x00000475,0x000004ce,0x0003003e, + 0x00000473,0x00000475,0x0003003e,0x00000477,0x000000e2,0x0004003d,0x00000006,0x000004dc, + 0x00000477,0x00050041,0x00000007,0x000004dd,0x000004d9,0x000000ab,0x0003003e,0x000004dd, + 0x000004dc,0x0004003d,0x00000006,0x000004de,0x00000477,0x00050041,0x00000007,0x000004df, + 0x000004d9,0x000000ae,0x0003003e,0x000004df,0x000004de,0x0004003d,0x00000006,0x000004e0, + 0x00000477,0x00050041,0x00000007,0x000004e1,0x000004d9,0x000000c1,0x0003003e,0x000004e1, + 0x000004e0,0x0004003d,0x00000006,0x000004e2,0x00000477,0x00050041,0x00000007,0x000004e3, + 0x000004d9,0x000000d8,0x0003003e,0x000004e3,0x000004e2,0x0004003d,0x0000002f,0x000004e4, + 0x000004d9,0x0003003e,0x000004da,0x000004e4,0x0004003d,0x0000002f,0x00000478,0x000004da, + 0x0003003e,0x00000476,0x00000478,0x0004003d,0x00000012,0x00000479,0x00000449,0x000500ab, + 0x000000f5,0x0000047b,0x00000479,0x00000455,0x000300f7,0x0000047d,0x00000000,0x000400fa, + 0x0000047b,0x0000047c,0x0000047d,0x000200f8,0x0000047c,0x0004003d,0x00000012,0x0000047f, + 0x00000440,0x000500c7,0x00000012,0x00000481,0x0000047f,0x00000480,0x0003003e,0x00000482, + 0x00000481,0x0004003d,0x00000012,0x000004e8,0x00000482,0x00040070,0x00000006,0x000004e9, + 0x000004e8,0x00050085,0x00000006,0x000004ea,0x000004e9,0x000002fe,0x00050081,0x00000006, + 0x000004eb,0x000004ea,0x00000300,0x0003003e,0x000004e5,0x000004eb,0x0004003d,0x00000006, + 0x000004f0,0x000004e5,0x0003003e,0x000004ed,0x000004f0,0x0004003d,0x00000006,0x000004f1, + 0x000004ed,0x0003003e,0x000004ee,0x000004f1,0x0004003d,0x00000006,0x000004ec,0x000004ee, + 0x0003003e,0x000004e6,0x000004ec,0x0004003d,0x00000006,0x00000483,0x000004e6,0x0003003e, + 0x0000047e,0x00000483,0x0004003d,0x00000012,0x00000485,0x00000449,0x0003003e,0x00000484, + 0x00000485,0x0004003d,0x00000006,0x00000487,0x0000047e,0x0003003e,0x00000486,0x00000487, + 0x0004003d,0x0000002f,0x0000048a,0x00000476,0x0003003e,0x00000489,0x0000048a,0x0004003d, + 0x00000012,0x00000512,0x00000484,0x00060041,0x00000325,0x00000513,0x00000323,0x0000025a, + 0x00000512,0x0004003d,0x0000031d,0x00000514,0x00000513,0x0003003e,0x000004f2,0x00000514, + 0x0004003d,0x00000006,0x00000515,0x00000486,0x0003003e,0x000004f3,0x00000515,0x00050041, + 0x00000013,0x00000516,0x000004f2,0x000000ab,0x0004003d,0x00000012,0x00000517,0x00000516, + 0x000500c7,0x00000012,0x00000518,0x00000517,0x0000032c,0x000500ab,0x000000f5,0x00000519, + 0x00000518,0x000000ab,0x000300f7,0x0000052d,0x00000000,0x000400fa,0x00000519,0x0000051a, + 0x0000052d,0x000200f8,0x0000051a,0x0004003d,0x00000006,0x0000051b,0x000004f3,0x0006000c, + 0x00000006,0x0000051c,0x00000001,0x00000004,0x0000051b,0x0003003e,0x000004f3,0x0000051c, + 0x000300f7,0x00000522,0x00000000,0x000400fa,0x00000333,0x0000051d,0x00000522,0x000200f8, + 0x0000051d,0x0004003d,0x00000012,0x0000051f,0x00000516,0x000500c7,0x00000012,0x00000520, + 0x0000051f,0x00000338,0x000500ab,0x000000f5,0x00000521,0x00000520,0x000000ab,0x000200f9, + 0x00000522,0x000200f8,0x00000522,0x000700f5,0x000000f5,0x00000523,0x00000333,0x0000051a, + 0x00000521,0x0000051d,0x000300f7,0x0000052c,0x00000000,0x000400fa,0x00000523,0x00000524, + 0x0000052c,0x000200f8,0x00000524,0x0004003d,0x00000006,0x00000525,0x000004f3,0x00050085, + 0x00000006,0x00000526,0x00000525,0x000001d6,0x0006000c,0x00000006,0x00000527,0x00000001, + 0x0000000a,0x00000526,0x00050085,0x00000006,0x00000528,0x00000527,0x000001cf,0x00050081, + 0x00000006,0x00000529,0x00000528,0x00000342,0x0006000c,0x00000006,0x0000052a,0x00000001, + 0x00000004,0x00000529,0x00050083,0x00000006,0x0000052b,0x000000e1,0x0000052a,0x0003003e, + 0x000004f3,0x0000052b,0x000200f9,0x0000052c,0x000200f8,0x0000052c,0x000200f9,0x0000052d, + 0x000200f8,0x0000052d,0x0004003d,0x00000006,0x0000052e,0x000004f3,0x0003003e,0x000004f4, + 0x000000e2,0x0004003d,0x00000006,0x000005e7,0x000004f4,0x0003003e,0x000005e5,0x000005e7, + 0x0004003d,0x00000006,0x0000052f,0x000005e5,0x0003003e,0x000004f5,0x000000e1,0x0004003d, + 0x00000006,0x000005ea,0x000004f5,0x0003003e,0x000005e8,0x000005ea,0x0004003d,0x00000006, + 0x00000530,0x000005e8,0x0008000c,0x00000006,0x00000531,0x00000001,0x0000002b,0x0000052e, + 0x0000052f,0x00000530,0x0003003e,0x000004f3,0x00000531,0x000300f7,0x00000540,0x00000000, + 0x000400fa,0x0000034c,0x00000532,0x00000540,0x000200f8,0x00000532,0x0004003d,0x00000012, + 0x00000534,0x00000516,0x000500c2,0x00000012,0x00000535,0x00000534,0x00000352,0x0003003e, + 0x000004f6,0x00000535,0x0004003d,0x00000012,0x00000536,0x000004f6,0x000500ab,0x000000f5, + 0x00000537,0x00000536,0x000000ab,0x000300f7,0x0000053f,0x00000000,0x000400fa,0x00000537, + 0x00000538,0x0000053f,0x000200f8,0x00000538,0x0004003d,0x00000358,0x00000539,0x0000035a, + 0x00050062,0x0000002f,0x0000053a,0x00000539,0x0000035c,0x0004003d,0x00000012,0x0000053b, + 0x000004f6,0x0003003e,0x000004f7,0x0000053b,0x0003003e,0x000004f8,0x0000053a,0x0004003d, + 0x00000006,0x0000053c,0x000004f3,0x0003003e,0x000004f9,0x0000053c,0x0004003d,0x0000002f, + 0x000005ed,0x000004f8,0x0007004f,0x0000000c,0x000005ee,0x000005ed,0x000005ed,0x00000000, + 0x00000001,0x0004003d,0x00000012,0x000005ef,0x000004f7,0x0006000c,0x0000002f,0x000005f0, + 0x00000001,0x00000040,0x000005ef,0x0007004f,0x0000000c,0x000005f1,0x000005f0,0x000005f0, + 0x00000000,0x00000001,0x00050083,0x0000000c,0x000005f2,0x000005ee,0x000005f1,0x0006000c, + 0x0000000c,0x000005f3,0x00000001,0x00000004,0x000005f2,0x0003003e,0x000005eb,0x00000310, + 0x0004003d,0x00000006,0x00000601,0x000005eb,0x00050041,0x00000007,0x00000602,0x000005fe, + 0x000000ab,0x0003003e,0x00000602,0x00000601,0x0004003d,0x00000006,0x00000603,0x000005eb, + 0x00050041,0x00000007,0x00000604,0x000005fe,0x000000ae,0x0003003e,0x00000604,0x00000603, + 0x0004003d,0x0000000c,0x00000605,0x000005fe,0x0003003e,0x000005ff,0x00000605,0x0004003d, + 0x0000000c,0x000005f4,0x000005ff,0x000500b8,0x00000313,0x000005f5,0x000005f3,0x000005f4, + 0x0004009b,0x000000f5,0x000005f6,0x000005f5,0x000300f7,0x000005fd,0x00000000,0x000400fa, + 0x000005f6,0x000005f7,0x000005fc,0x000200f8,0x000005f7,0x0004003d,0x00000006,0x000005f8, + 0x000004f9,0x00050041,0x00000007,0x000005f9,0x000004f8,0x000000c1,0x0004003d,0x00000006, + 0x000005fa,0x000005f9,0x0007000c,0x00000006,0x000005fb,0x00000001,0x00000025,0x000005f8, + 0x000005fa,0x0003003e,0x000004f9,0x000005fb,0x000200f9,0x000005fd,0x000200f8,0x000005fc, + 0x0003003e,0x000004f9,0x000000e2,0x000200f9,0x000005fd,0x000200f8,0x000005fd,0x0004003d, + 0x00000006,0x0000053e,0x000004f9,0x0003003e,0x000004f3,0x0000053e,0x000200f9,0x0000053f, + 0x000200f8,0x0000053f,0x000200f9,0x00000540,0x000200f8,0x00000540,0x000300f7,0x00000546, + 0x00000000,0x000400fa,0x00000365,0x00000541,0x00000546,0x000200f8,0x00000541,0x0004003d, + 0x00000012,0x00000543,0x00000516,0x000500c7,0x00000012,0x00000544,0x00000543,0x0000036a, + 0x000500ab,0x000000f5,0x00000545,0x00000544,0x000000ab,0x000200f9,0x00000546,0x000200f8, + 0x00000546,0x000700f5,0x000000f5,0x00000547,0x00000365,0x00000540,0x00000545,0x00000541, + 0x000300f7,0x0000056e,0x00000000,0x000400fa,0x00000547,0x00000548,0x0000056e,0x000200f8, + 0x00000548,0x0004003d,0x00000012,0x00000549,0x00000484,0x00050084,0x00000012,0x0000054a, + 0x00000549,0x00000377,0x00050080,0x00000012,0x0000054b,0x0000054a,0x000000c1,0x00060041, + 0x0000037b,0x0000054c,0x00000375,0x0000025a,0x0000054b,0x0004003d,0x0000002f,0x0000054d, + 0x0000054c,0x0003003e,0x000004fb,0x0000054d,0x0004003d,0x0000002f,0x00000608,0x000004fb, + 0x0004003d,0x0000002f,0x0000060a,0x000004fb,0x00050051,0x00000006,0x0000060c,0x00000608, + 0x00000000,0x00050051,0x00000006,0x0000060d,0x00000608,0x00000001,0x00050051,0x00000006, + 0x0000060e,0x0000060a,0x00000002,0x00050051,0x00000006,0x0000060f,0x0000060a,0x00000003, + 0x00050050,0x0000000c,0x00000610,0x0000060c,0x0000060d,0x00050050,0x0000000c,0x00000611, + 0x0000060e,0x0000060f,0x00050050,0x00000035,0x00000612,0x00000610,0x00000611,0x0003003e, + 0x00000606,0x00000612,0x0004003d,0x00000035,0x0000054e,0x00000606,0x0003003e,0x000004fa, + 0x0000054e,0x0004003d,0x00000012,0x0000054f,0x00000484,0x00050084,0x00000012,0x00000550, + 0x0000054f,0x00000377,0x00050080,0x00000012,0x00000551,0x00000550,0x000000d8,0x00060041, + 0x0000037b,0x00000552,0x00000375,0x0000025a,0x00000551,0x0004003d,0x0000002f,0x00000553, + 0x00000552,0x0003003e,0x000004fc,0x00000553,0x0004003d,0x00000035,0x00000554,0x000004fa, + 0x00050091,0x0000000c,0x00000557,0x00000554,0x0000043d,0x0004003d,0x0000002f,0x00000558, + 0x000004fc,0x0007004f,0x0000000c,0x00000559,0x00000558,0x00000558,0x00000000,0x00000001, + 0x00050081,0x0000000c,0x0000055a,0x00000557,0x00000559,0x0003003e,0x000004fd,0x0000055a, + 0x0004003d,0x0000000c,0x0000055b,0x000004fd,0x0006000c,0x0000000c,0x0000055c,0x00000001, + 0x00000004,0x0000055b,0x0004003d,0x0000002f,0x0000055d,0x000004fc,0x0007004f,0x0000000c, + 0x0000055e,0x0000055d,0x0000055d,0x00000002,0x00000003,0x00050085,0x0000000c,0x0000055f, + 0x0000055c,0x0000055e,0x0004003d,0x0000002f,0x00000560,0x000004fc,0x0007004f,0x0000000c, + 0x00000561,0x00000560,0x00000560,0x00000002,0x00000003,0x00050083,0x0000000c,0x00000562, + 0x0000055f,0x00000561,0x0003003e,0x000004ff,0x00000562,0x0004003d,0x0000000c,0x00000616, + 0x000004ff,0x0003003e,0x00000613,0x00000616,0x0004003d,0x0000000c,0x00000617,0x00000613, + 0x0003003e,0x00000614,0x00000617,0x0004003d,0x0000000c,0x00000563,0x00000614,0x0003003e, + 0x000004fe,0x00000563,0x00050041,0x00000007,0x00000564,0x000004fe,0x000000ab,0x0004003d, + 0x00000006,0x00000565,0x00000564,0x00050041,0x00000007,0x00000566,0x000004fe,0x000000ae, + 0x0004003d,0x00000006,0x00000567,0x00000566,0x0007000c,0x00000006,0x00000568,0x00000001, + 0x00000025,0x00000565,0x00000567,0x00050081,0x00000006,0x00000569,0x00000568,0x000001d6, + 0x0008000c,0x00000006,0x0000056a,0x00000001,0x0000002b,0x00000569,0x000000e2,0x000000e1, + 0x0003003e,0x00000500,0x0000056a,0x0004003d,0x00000006,0x0000056b,0x000004f3,0x0004003d, + 0x00000006,0x0000056c,0x00000500,0x0007000c,0x00000006,0x0000056d,0x00000001,0x00000025, + 0x0000056b,0x0000056c,0x0003003e,0x000004f3,0x0000056d,0x000200f9,0x0000056e,0x000200f8, + 0x0000056e,0x0004003d,0x00000012,0x00000570,0x00000516,0x000500c7,0x00000012,0x00000571, + 0x00000570,0x000003a8,0x0003003e,0x00000501,0x00000571,0x0004003d,0x00000012,0x00000572, + 0x00000501,0x000500b2,0x000000f5,0x00000573,0x00000572,0x000000ae,0x000300f7,0x000005b6, + 0x00000000,0x000400fa,0x00000573,0x00000574,0x00000587,0x000200f8,0x00000574,0x00050041, + 0x00000013,0x00000575,0x000004f2,0x000000ae,0x0004003d,0x00000012,0x00000576,0x00000575, + 0x0006000c,0x0000002f,0x00000577,0x00000001,0x00000040,0x00000576,0x0003003e,0x00000488, + 0x00000577,0x0004003d,0x00000012,0x00000578,0x00000501,0x000500aa,0x000000f5,0x00000579, + 0x00000578,0x000000ab,0x000500a7,0x000000f5,0x0000057a,0x0000034c,0x00000579,0x000300f7, + 0x00000586,0x00000000,0x000400fa,0x0000057a,0x0000057b,0x00000586,0x000200f8,0x0000057b, + 0x0004003d,0x0000002f,0x0000057c,0x00000488,0x00050041,0x00000007,0x0000057e,0x00000489, + 0x000000ab,0x00050051,0x00000006,0x0000057f,0x0000057c,0x00000002,0x0003003e,0x0000057e, + 0x0000057f,0x00050041,0x00000007,0x00000580,0x00000489,0x000000ae,0x00050051,0x00000006, + 0x00000581,0x0000057c,0x00000003,0x0003003e,0x00000580,0x00000581,0x0004003d,0x00000006, + 0x00000582,0x000004f3,0x00050041,0x00000007,0x00000583,0x00000489,0x000000c1,0x0003003e, + 0x00000583,0x00000582,0x00050041,0x00000007,0x00000584,0x00000489,0x000000d8,0x0003003e, + 0x00000584,0x000000e1,0x0003003e,0x00000502,0x000000e2,0x0004003d,0x00000006,0x0000061b, + 0x00000502,0x00050041,0x00000007,0x0000061c,0x00000618,0x000000ab,0x0003003e,0x0000061c, + 0x0000061b,0x0004003d,0x00000006,0x0000061d,0x00000502,0x00050041,0x00000007,0x0000061e, + 0x00000618,0x000000ae,0x0003003e,0x0000061e,0x0000061d,0x0004003d,0x00000006,0x0000061f, + 0x00000502,0x00050041,0x00000007,0x00000620,0x00000618,0x000000c1,0x0003003e,0x00000620, + 0x0000061f,0x0004003d,0x00000006,0x00000621,0x00000502,0x00050041,0x00000007,0x00000622, + 0x00000618,0x000000d8,0x0003003e,0x00000622,0x00000621,0x0004003d,0x0000002f,0x00000623, + 0x00000618,0x0003003e,0x00000619,0x00000623,0x0004003d,0x0000002f,0x00000585,0x00000619, + 0x0003003e,0x00000488,0x00000585,0x000200f9,0x00000586,0x000200f8,0x00000586,0x000200f9, + 0x000005b6,0x000200f8,0x00000587,0x0004003d,0x00000012,0x00000588,0x00000484,0x00050084, + 0x00000012,0x00000589,0x00000588,0x00000377,0x00060041,0x0000037b,0x0000058a,0x00000375, + 0x0000025a,0x00000589,0x0004003d,0x0000002f,0x0000058b,0x0000058a,0x0003003e,0x00000504, + 0x0000058b,0x0004003d,0x0000002f,0x00000626,0x00000504,0x0004003d,0x0000002f,0x00000628, + 0x00000504,0x00050051,0x00000006,0x0000062a,0x00000626,0x00000000,0x00050051,0x00000006, + 0x0000062b,0x00000626,0x00000001,0x00050051,0x00000006,0x0000062c,0x00000628,0x00000002, + 0x00050051,0x00000006,0x0000062d,0x00000628,0x00000003,0x00050050,0x0000000c,0x0000062e, + 0x0000062a,0x0000062b,0x00050050,0x0000000c,0x0000062f,0x0000062c,0x0000062d,0x00050050, + 0x00000035,0x00000630,0x0000062e,0x0000062f,0x0003003e,0x00000624,0x00000630,0x0004003d, + 0x00000035,0x0000058c,0x00000624,0x0003003e,0x00000503,0x0000058c,0x0004003d,0x00000012, + 0x0000058d,0x00000484,0x00050084,0x00000012,0x0000058e,0x0000058d,0x00000377,0x00050080, + 0x00000012,0x0000058f,0x0000058e,0x000000ae,0x00060041,0x0000037b,0x00000590,0x00000375, + 0x0000025a,0x0000058f,0x0004003d,0x0000002f,0x00000591,0x00000590,0x0003003e,0x00000505, + 0x00000591,0x0004003d,0x00000035,0x00000592,0x00000503,0x00050091,0x0000000c,0x00000595, + 0x00000592,0x0000043d,0x0004003d,0x0000002f,0x00000596,0x00000505,0x0007004f,0x0000000c, + 0x00000597,0x00000596,0x00000596,0x00000000,0x00000001,0x00050081,0x0000000c,0x00000598, + 0x00000595,0x00000597,0x0003003e,0x00000506,0x00000598,0x0004003d,0x00000012,0x00000599, + 0x00000501,0x000500aa,0x000000f5,0x0000059a,0x00000599,0x000000c1,0x000300f7,0x000005a1, + 0x00000000,0x000400fa,0x0000059a,0x0000059b,0x0000059e,0x000200f8,0x0000059b,0x00050041, + 0x00000007,0x0000059c,0x00000506,0x000000ab,0x0004003d,0x00000006,0x0000059d,0x0000059c, + 0x0003003e,0x00000508,0x0000059d,0x000200f9,0x000005a1,0x000200f8,0x0000059e,0x0004003d, + 0x0000000c,0x0000059f,0x00000506,0x0006000c,0x00000006,0x000005a0,0x00000001,0x00000042, + 0x0000059f,0x0003003e,0x00000508,0x000005a0,0x000200f9,0x000005a1,0x000200f8,0x000005a1, + 0x0004003d,0x00000006,0x000005a2,0x00000508,0x0003003e,0x00000507,0x000005a2,0x0004003d, + 0x00000006,0x000005a3,0x00000507,0x0008000c,0x00000006,0x000005a4,0x00000001,0x0000002b, + 0x000005a3,0x000000e2,0x000000e1,0x0003003e,0x00000507,0x000005a4,0x0004003d,0x00000006, + 0x000005a5,0x00000507,0x00050041,0x00000007,0x000005a6,0x00000505,0x000000c1,0x0004003d, + 0x00000006,0x000005a7,0x000005a6,0x00050085,0x00000006,0x000005a8,0x000005a5,0x000005a7, + 0x00050041,0x00000007,0x000005a9,0x00000505,0x000000d8,0x0004003d,0x00000006,0x000005aa, + 0x000005a9,0x00050081,0x00000006,0x000005ab,0x000005a8,0x000005aa,0x0003003e,0x00000509, + 0x000005ab,0x00050041,0x00000013,0x000005ac,0x000004f2,0x000000ae,0x0004003d,0x00000012, + 0x000005ad,0x000005ac,0x0004007c,0x00000006,0x000005ae,0x000005ad,0x0003003e,0x0000050a, + 0x000005ae,0x0004003d,0x000003f1,0x000005af,0x000003f3,0x0004003d,0x000003f5,0x000005b0, + 0x000003f7,0x00050056,0x000003f9,0x000005b1,0x000005af,0x000005b0,0x0004003d,0x00000006, + 0x000005b2,0x00000509,0x0004003d,0x00000006,0x000005b3,0x0000050a,0x00050050,0x0000000c, + 0x000005b4,0x000005b2,0x000005b3,0x00070058,0x0000002f,0x000005b5,0x000005b1,0x000005b4, + 0x00000002,0x000000e2,0x0003003e,0x00000488,0x000005b5,0x000200f9,0x000005b6,0x000200f8, + 0x000005b6,0x0004003d,0x00000006,0x000005b7,0x000004f3,0x00050041,0x00000007,0x000005b8, + 0x00000488,0x000000d8,0x0004003d,0x00000006,0x000005b9,0x000005b8,0x00050085,0x00000006, + 0x000005ba,0x000005b9,0x000005b7,0x0003003e,0x000005b8,0x000005ba,0x000300f7,0x000005c0, + 0x00000000,0x000400fa,0x00000404,0x000005bc,0x000005c0,0x000200f8,0x000005bc,0x0004003d, + 0x00000006,0x000005be,0x000005b8,0x000500b7,0x000000f5,0x000005bf,0x000005be,0x000000e2, + 0x000200f9,0x000005c0,0x000200f8,0x000005c0,0x000700f5,0x000000f5,0x000005c1,0x00000404, + 0x000005b6,0x000005bf,0x000005bc,0x000300f7,0x000005c9,0x00000000,0x000400fa,0x000005c1, + 0x000005c2,0x000005c9,0x000200f8,0x000005c2,0x0004003d,0x00000012,0x000005c4,0x00000516, + 0x000500c2,0x00000012,0x000005c5,0x000005c4,0x00000410,0x000500c7,0x00000012,0x000005c6, + 0x000005c5,0x000003a8,0x0003003e,0x0000050c,0x000005c6,0x0004003d,0x00000012,0x00000634, + 0x0000050c,0x0003003e,0x00000631,0x00000634,0x0004003d,0x00000012,0x00000635,0x00000631, + 0x0003003e,0x00000632,0x00000635,0x0004003d,0x00000012,0x000005c7,0x00000632,0x0003003e, + 0x0000050b,0x000005c7,0x000500ab,0x000000f5,0x000005c8,0x000005c7,0x000000ab,0x000200f9, + 0x000005c9,0x000200f8,0x000005c9,0x000700f5,0x000000f5,0x000005ca,0x000005c1,0x000005c0, + 0x000005c8,0x000005c2,0x000300f7,0x000005d9,0x00000000,0x000400fa,0x000005ca,0x000005cb, + 0x000005d9,0x000200f8,0x000005cb,0x0004003d,0x00000358,0x000005cc,0x0000041a,0x00050062, + 0x0000002f,0x000005cd,0x000005cc,0x0000035c,0x0003003e,0x0000050d,0x000005cd,0x0004003d, + 0x0000002f,0x000005ce,0x00000488,0x0008004f,0x00000024,0x000005cf,0x000005ce,0x000005ce, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x0000050e,0x000005cf,0x0004003d,0x0000002f, + 0x000005d0,0x0000050d,0x0003003e,0x0000050f,0x000005d0,0x0004003d,0x00000012,0x000005d1, + 0x0000050b,0x0003003e,0x00000510,0x000005d1,0x0004003d,0x00000024,0x0000063d,0x0000050e, + 0x0003003e,0x00000637,0x0000063d,0x0004003d,0x0000002f,0x0000063e,0x0000050f,0x0003003e, + 0x00000638,0x0000063e,0x0004003d,0x00000012,0x0000063f,0x00000510,0x0003003e,0x00000639, + 0x0000063f,0x0004003d,0x0000002f,0x0000066f,0x00000638,0x0003003e,0x00000648,0x0000066f, + 0x0004003d,0x0000002f,0x0000076b,0x00000648,0x0008004f,0x00000024,0x0000076c,0x0000076b, + 0x0000076b,0x00000000,0x00000001,0x00000002,0x00050041,0x00000007,0x0000076d,0x00000648, + 0x000000d8,0x0004003d,0x00000006,0x0000076e,0x0000076d,0x000500b7,0x000000f5,0x0000076f, + 0x0000076e,0x000000e2,0x000300f7,0x00000775,0x00000000,0x000400fa,0x0000076f,0x00000770, + 0x00000774,0x000200f8,0x00000770,0x0004003d,0x00000006,0x00000772,0x0000076d,0x00050088, + 0x00000006,0x00000773,0x000000e1,0x00000772,0x0003003e,0x00000768,0x00000773,0x000200f9, + 0x00000775,0x000200f8,0x00000774,0x0003003e,0x00000768,0x000000e2,0x000200f9,0x00000775, + 0x000200f8,0x00000775,0x0004003d,0x00000006,0x00000776,0x00000768,0x0005008e,0x00000024, + 0x00000777,0x0000076c,0x00000776,0x0003003e,0x00000769,0x00000777,0x0004003d,0x00000024, + 0x00000670,0x00000769,0x0003003e,0x00000647,0x00000670,0x0004003d,0x00000012,0x00000671, + 0x00000639,0x000300f7,0x00000766,0x00000000,0x002100fb,0x00000671,0x00000766,0x0000000b, + 0x00000672,0x00000001,0x00000676,0x00000002,0x0000067e,0x00000003,0x0000068e,0x00000004, + 0x00000692,0x00000005,0x00000696,0x00000006,0x000006b8,0x00000007,0x000006e4,0x00000008, + 0x000006f4,0x00000009,0x0000072e,0x0000000a,0x00000733,0x0000000c,0x0000073c,0x0000000d, + 0x00000747,0x0000000e,0x00000752,0x0000000f,0x0000075c,0x000200f8,0x00000672,0x0004003d, + 0x00000024,0x00000673,0x00000637,0x0004003d,0x00000024,0x00000674,0x00000647,0x00050085, + 0x00000024,0x00000675,0x00000673,0x00000674,0x0003003e,0x00000649,0x00000675,0x000200f9, + 0x00000766,0x000200f8,0x00000676,0x0004003d,0x00000024,0x00000677,0x00000637,0x0004003d, + 0x00000024,0x00000678,0x00000647,0x00050081,0x00000024,0x00000679,0x00000677,0x00000678, + 0x0004003d,0x00000024,0x0000067a,0x00000637,0x0004003d,0x00000024,0x0000067b,0x00000647, + 0x00050085,0x00000024,0x0000067c,0x0000067a,0x0000067b,0x00050083,0x00000024,0x0000067d, + 0x00000679,0x0000067c,0x0003003e,0x00000649,0x0000067d,0x000200f9,0x00000766,0x000200f8, + 0x0000067e,0x0004003d,0x00000024,0x0000067f,0x00000637,0x0004003d,0x00000024,0x00000680, + 0x00000647,0x00050085,0x00000024,0x00000681,0x0000067f,0x00000680,0x0003003e,0x0000064a, + 0x00000681,0x0004003d,0x00000024,0x00000682,0x0000064a,0x0004003d,0x00000024,0x00000683, + 0x00000637,0x0004003d,0x00000024,0x00000684,0x00000647,0x00050081,0x00000024,0x00000685, + 0x00000683,0x00000684,0x0004003d,0x00000024,0x00000686,0x0000064a,0x00050083,0x00000024, + 0x00000687,0x00000685,0x00000686,0x00050083,0x00000024,0x00000688,0x00000687,0x000004bf, + 0x0004003d,0x00000024,0x00000689,0x00000647,0x0003003e,0x0000064b,0x000001d6,0x0004003d, + 0x00000006,0x0000077b,0x0000064b,0x00050041,0x00000007,0x0000077c,0x00000778,0x000000ab, + 0x0003003e,0x0000077c,0x0000077b,0x0004003d,0x00000006,0x0000077d,0x0000064b,0x00050041, + 0x00000007,0x0000077e,0x00000778,0x000000ae,0x0003003e,0x0000077e,0x0000077d,0x0004003d, + 0x00000006,0x0000077f,0x0000064b,0x00050041,0x00000007,0x00000780,0x00000778,0x000000c1, + 0x0003003e,0x00000780,0x0000077f,0x0004003d,0x00000024,0x00000781,0x00000778,0x0003003e, + 0x00000779,0x00000781,0x0004003d,0x00000024,0x0000068a,0x00000779,0x000500ba,0x000001dc, + 0x0000068b,0x00000689,0x0000068a,0x000600a9,0x00000024,0x0000068c,0x0000068b,0x00000688, + 0x00000682,0x0005008e,0x00000024,0x0000068d,0x0000068c,0x000001cf,0x0003003e,0x00000649, + 0x0000068d,0x000200f9,0x00000766,0x000200f8,0x0000068e,0x0004003d,0x00000024,0x0000068f, + 0x00000637,0x0004003d,0x00000024,0x00000690,0x00000647,0x0007000c,0x00000024,0x00000691, + 0x00000001,0x00000025,0x0000068f,0x00000690,0x0003003e,0x00000649,0x00000691,0x000200f9, + 0x00000766,0x000200f8,0x00000692,0x0004003d,0x00000024,0x00000693,0x00000637,0x0004003d, + 0x00000024,0x00000694,0x00000647,0x0007000c,0x00000024,0x00000695,0x00000001,0x00000028, + 0x00000693,0x00000694,0x0003003e,0x00000649,0x00000695,0x000200f9,0x00000766,0x000200f8, + 0x00000696,0x0004003d,0x0000002f,0x00000697,0x00000638,0x0008004f,0x00000024,0x00000698, + 0x00000697,0x00000697,0x00000000,0x00000001,0x00000002,0x0003003e,0x0000064c,0x000000e2, + 0x0004003d,0x00000006,0x00000785,0x0000064c,0x00050041,0x00000007,0x00000786,0x00000782, + 0x000000ab,0x0003003e,0x00000786,0x00000785,0x0004003d,0x00000006,0x00000787,0x0000064c, + 0x00050041,0x00000007,0x00000788,0x00000782,0x000000ae,0x0003003e,0x00000788,0x00000787, + 0x0004003d,0x00000006,0x00000789,0x0000064c,0x00050041,0x00000007,0x0000078a,0x00000782, + 0x000000c1,0x0003003e,0x0000078a,0x00000789,0x0004003d,0x00000024,0x0000078b,0x00000782, + 0x0003003e,0x00000783,0x0000078b,0x0004003d,0x00000024,0x00000699,0x00000783,0x0004003d, + 0x0000002f,0x0000069a,0x00000638,0x0008004f,0x00000024,0x0000069b,0x0000069a,0x0000069a, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024,0x0000069c,0x00000001,0x0000002b, + 0x00000698,0x00000699,0x0000069b,0x00050041,0x00000007,0x0000069d,0x00000638,0x000000ab, + 0x00050051,0x00000006,0x0000069e,0x0000069c,0x00000000,0x0003003e,0x0000069d,0x0000069e, + 0x00050041,0x00000007,0x0000069f,0x00000638,0x000000ae,0x00050051,0x00000006,0x000006a0, + 0x0000069c,0x00000001,0x0003003e,0x0000069f,0x000006a0,0x00050041,0x00000007,0x000006a1, + 0x00000638,0x000000c1,0x00050051,0x00000006,0x000006a2,0x0000069c,0x00000002,0x0003003e, + 0x000006a1,0x000006a2,0x0004003d,0x00000024,0x000006a3,0x00000637,0x00050083,0x00000024, + 0x000006a4,0x000004be,0x000006a3,0x0003003e,0x0000064e,0x000000e2,0x0004003d,0x00000006, + 0x0000078f,0x0000064e,0x00050041,0x00000007,0x00000790,0x0000078c,0x000000ab,0x0003003e, + 0x00000790,0x0000078f,0x0004003d,0x00000006,0x00000791,0x0000064e,0x00050041,0x00000007, + 0x00000792,0x0000078c,0x000000ae,0x0003003e,0x00000792,0x00000791,0x0004003d,0x00000006, + 0x00000793,0x0000064e,0x00050041,0x00000007,0x00000794,0x0000078c,0x000000c1,0x0003003e, + 0x00000794,0x00000793,0x0004003d,0x00000024,0x00000795,0x0000078c,0x0003003e,0x0000078d, + 0x00000795,0x0004003d,0x00000024,0x000006a5,0x0000078d,0x0003003e,0x0000064f,0x000000e1, + 0x0004003d,0x00000006,0x00000799,0x0000064f,0x00050041,0x00000007,0x0000079a,0x00000796, + 0x000000ab,0x0003003e,0x0000079a,0x00000799,0x0004003d,0x00000006,0x0000079b,0x0000064f, + 0x00050041,0x00000007,0x0000079c,0x00000796,0x000000ae,0x0003003e,0x0000079c,0x0000079b, + 0x0004003d,0x00000006,0x0000079d,0x0000064f,0x00050041,0x00000007,0x0000079e,0x00000796, + 0x000000c1,0x0003003e,0x0000079e,0x0000079d,0x0004003d,0x00000024,0x0000079f,0x00000796, + 0x0003003e,0x00000797,0x0000079f,0x0004003d,0x00000024,0x000006a6,0x00000797,0x0008000c, + 0x00000024,0x000006a7,0x00000001,0x0000002b,0x000006a4,0x000006a5,0x000006a6,0x00050041, + 0x00000007,0x000006a8,0x00000638,0x000000d8,0x0004003d,0x00000006,0x000006a9,0x000006a8, + 0x0005008e,0x00000024,0x000006aa,0x000006a7,0x000006a9,0x0003003e,0x0000064d,0x000006aa, + 0x0003003e,0x00000650,0x000000e1,0x0004003d,0x00000006,0x000007a3,0x00000650,0x00050041, + 0x00000007,0x000007a4,0x000007a0,0x000000ab,0x0003003e,0x000007a4,0x000007a3,0x0004003d, + 0x00000006,0x000007a5,0x00000650,0x00050041,0x00000007,0x000007a6,0x000007a0,0x000000ae, + 0x0003003e,0x000007a6,0x000007a5,0x0004003d,0x00000006,0x000007a7,0x00000650,0x00050041, + 0x00000007,0x000007a8,0x000007a0,0x000000c1,0x0003003e,0x000007a8,0x000007a7,0x0004003d, + 0x00000024,0x000007a9,0x000007a0,0x0003003e,0x000007a1,0x000007a9,0x0004003d,0x00000024, + 0x000006ab,0x000007a1,0x0004003d,0x0000002f,0x000006ac,0x00000638,0x0008004f,0x00000024, + 0x000006ad,0x000006ac,0x000006ac,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000024, + 0x000006ae,0x0000064d,0x00050088,0x00000024,0x000006af,0x000006ad,0x000006ae,0x0007000c, + 0x00000024,0x000006b0,0x00000001,0x00000025,0x000006ab,0x000006af,0x0004003d,0x0000002f, + 0x000006b1,0x00000638,0x0008004f,0x00000024,0x000006b2,0x000006b1,0x000006b1,0x00000000, + 0x00000001,0x00000002,0x0006000c,0x00000024,0x000006b3,0x00000001,0x00000006,0x000006b2, + 0x0004003d,0x00000024,0x000006b4,0x0000064d,0x0003003e,0x00000651,0x000000e2,0x0004003d, + 0x00000006,0x000007ad,0x00000651,0x00050041,0x00000007,0x000007ae,0x000007aa,0x000000ab, + 0x0003003e,0x000007ae,0x000007ad,0x0004003d,0x00000006,0x000007af,0x00000651,0x00050041, + 0x00000007,0x000007b0,0x000007aa,0x000000ae,0x0003003e,0x000007b0,0x000007af,0x0004003d, + 0x00000006,0x000007b1,0x00000651,0x00050041,0x00000007,0x000007b2,0x000007aa,0x000000c1, + 0x0003003e,0x000007b2,0x000007b1,0x0004003d,0x00000024,0x000007b3,0x000007aa,0x0003003e, + 0x000007ab,0x000007b3,0x0004003d,0x00000024,0x000006b5,0x000007ab,0x000500b4,0x000001dc, + 0x000006b6,0x000006b4,0x000006b5,0x000600a9,0x00000024,0x000006b7,0x000006b6,0x000006b3, + 0x000006b0,0x0003003e,0x00000649,0x000006b7,0x000200f9,0x00000766,0x000200f8,0x000006b8, + 0x0004003d,0x00000024,0x000006b9,0x00000637,0x0003003e,0x00000652,0x000000e2,0x0004003d, + 0x00000006,0x000007b7,0x00000652,0x00050041,0x00000007,0x000007b8,0x000007b4,0x000000ab, + 0x0003003e,0x000007b8,0x000007b7,0x0004003d,0x00000006,0x000007b9,0x00000652,0x00050041, + 0x00000007,0x000007ba,0x000007b4,0x000000ae,0x0003003e,0x000007ba,0x000007b9,0x0004003d, + 0x00000006,0x000007bb,0x00000652,0x00050041,0x00000007,0x000007bc,0x000007b4,0x000000c1, + 0x0003003e,0x000007bc,0x000007bb,0x0004003d,0x00000024,0x000007bd,0x000007b4,0x0003003e, + 0x000007b5,0x000007bd,0x0004003d,0x00000024,0x000006ba,0x000007b5,0x0003003e,0x00000653, + 0x000000e1,0x0004003d,0x00000006,0x000007c1,0x00000653,0x00050041,0x00000007,0x000007c2, + 0x000007be,0x000000ab,0x0003003e,0x000007c2,0x000007c1,0x0004003d,0x00000006,0x000007c3, + 0x00000653,0x00050041,0x00000007,0x000007c4,0x000007be,0x000000ae,0x0003003e,0x000007c4, + 0x000007c3,0x0004003d,0x00000006,0x000007c5,0x00000653,0x00050041,0x00000007,0x000007c6, + 0x000007be,0x000000c1,0x0003003e,0x000007c6,0x000007c5,0x0004003d,0x00000024,0x000007c7, + 0x000007be,0x0003003e,0x000007bf,0x000007c7,0x0004003d,0x00000024,0x000006bb,0x000007bf, + 0x0008000c,0x00000024,0x000006bc,0x00000001,0x0000002b,0x000006b9,0x000006ba,0x000006bb, + 0x0003003e,0x00000637,0x000006bc,0x0004003d,0x0000002f,0x000006bd,0x00000638,0x0008004f, + 0x00000024,0x000006be,0x000006bd,0x000006bd,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x00000654,0x000000e2,0x0004003d,0x00000006,0x000007cb,0x00000654,0x00050041,0x00000007, + 0x000007cc,0x000007c8,0x000000ab,0x0003003e,0x000007cc,0x000007cb,0x0004003d,0x00000006, + 0x000007cd,0x00000654,0x00050041,0x00000007,0x000007ce,0x000007c8,0x000000ae,0x0003003e, + 0x000007ce,0x000007cd,0x0004003d,0x00000006,0x000007cf,0x00000654,0x00050041,0x00000007, + 0x000007d0,0x000007c8,0x000000c1,0x0003003e,0x000007d0,0x000007cf,0x0004003d,0x00000024, + 0x000007d1,0x000007c8,0x0003003e,0x000007c9,0x000007d1,0x0004003d,0x00000024,0x000006bf, + 0x000007c9,0x0004003d,0x0000002f,0x000006c0,0x00000638,0x0008004f,0x00000024,0x000006c1, + 0x000006c0,0x000006c0,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024,0x000006c2, + 0x00000001,0x0000002b,0x000006be,0x000006bf,0x000006c1,0x00050041,0x00000007,0x000006c3, + 0x00000638,0x000000ab,0x00050051,0x00000006,0x000006c4,0x000006c2,0x00000000,0x0003003e, + 0x000006c3,0x000006c4,0x00050041,0x00000007,0x000006c5,0x00000638,0x000000ae,0x00050051, + 0x00000006,0x000006c6,0x000006c2,0x00000001,0x0003003e,0x000006c5,0x000006c6,0x00050041, + 0x00000007,0x000006c7,0x00000638,0x000000c1,0x00050051,0x00000006,0x000006c8,0x000006c2, + 0x00000002,0x0003003e,0x000006c7,0x000006c8,0x00050041,0x00000007,0x000006c9,0x00000638, + 0x000000d8,0x0004003d,0x00000006,0x000006ca,0x000006c9,0x000500b4,0x000000f5,0x000006cb, + 0x000006ca,0x000000e2,0x000300f7,0x000006ce,0x00000000,0x000400fa,0x000006cb,0x000006cc, + 0x000006ce,0x000200f8,0x000006cc,0x0003003e,0x000006c9,0x000000e1,0x000200f9,0x000006ce, + 0x000200f8,0x000006ce,0x0004003d,0x00000006,0x000006d0,0x000006c9,0x0004003d,0x0000002f, + 0x000006d1,0x00000638,0x0008004f,0x00000024,0x000006d2,0x000006d1,0x000006d1,0x00000000, + 0x00000001,0x00000002,0x00060050,0x00000024,0x000006d3,0x000006d0,0x000006d0,0x000006d0, + 0x00050083,0x00000024,0x000006d4,0x000006d3,0x000006d2,0x0003003e,0x00000655,0x000006d4, + 0x0003003e,0x00000656,0x000000e1,0x0004003d,0x00000006,0x000007d5,0x00000656,0x00050041, + 0x00000007,0x000007d6,0x000007d2,0x000000ab,0x0003003e,0x000007d6,0x000007d5,0x0004003d, + 0x00000006,0x000007d7,0x00000656,0x00050041,0x00000007,0x000007d8,0x000007d2,0x000000ae, + 0x0003003e,0x000007d8,0x000007d7,0x0004003d,0x00000006,0x000007d9,0x00000656,0x00050041, + 0x00000007,0x000007da,0x000007d2,0x000000c1,0x0003003e,0x000007da,0x000007d9,0x0004003d, + 0x00000024,0x000007db,0x000007d2,0x0003003e,0x000007d3,0x000007db,0x0004003d,0x00000024, + 0x000006d5,0x000007d3,0x0004003d,0x00000024,0x000006d6,0x00000655,0x0004003d,0x00000024, + 0x000006d7,0x00000637,0x0004003d,0x00000006,0x000006d9,0x000006c9,0x0005008e,0x00000024, + 0x000006da,0x000006d7,0x000006d9,0x00050088,0x00000024,0x000006db,0x000006d6,0x000006da, + 0x0007000c,0x00000024,0x000006dc,0x00000001,0x00000025,0x000006d5,0x000006db,0x0004003d, + 0x00000024,0x000006dd,0x00000655,0x0006000c,0x00000024,0x000006de,0x00000001,0x00000006, + 0x000006dd,0x0004003d,0x00000024,0x000006df,0x00000637,0x0003003e,0x00000657,0x000000e2, + 0x0004003d,0x00000006,0x000007df,0x00000657,0x00050041,0x00000007,0x000007e0,0x000007dc, + 0x000000ab,0x0003003e,0x000007e0,0x000007df,0x0004003d,0x00000006,0x000007e1,0x00000657, + 0x00050041,0x00000007,0x000007e2,0x000007dc,0x000000ae,0x0003003e,0x000007e2,0x000007e1, + 0x0004003d,0x00000006,0x000007e3,0x00000657,0x00050041,0x00000007,0x000007e4,0x000007dc, + 0x000000c1,0x0003003e,0x000007e4,0x000007e3,0x0004003d,0x00000024,0x000007e5,0x000007dc, + 0x0003003e,0x000007dd,0x000007e5,0x0004003d,0x00000024,0x000006e0,0x000007dd,0x000500b4, + 0x000001dc,0x000006e1,0x000006df,0x000006e0,0x000600a9,0x00000024,0x000006e2,0x000006e1, + 0x000006de,0x000006dc,0x00050083,0x00000024,0x000006e3,0x000004be,0x000006e2,0x0003003e, + 0x00000649,0x000006e3,0x000200f9,0x00000766,0x000200f8,0x000006e4,0x0004003d,0x00000024, + 0x000006e5,0x00000637,0x0004003d,0x00000024,0x000006e6,0x00000647,0x00050085,0x00000024, + 0x000006e7,0x000006e5,0x000006e6,0x0003003e,0x00000658,0x000006e7,0x0004003d,0x00000024, + 0x000006e8,0x00000658,0x0004003d,0x00000024,0x000006e9,0x00000637,0x0004003d,0x00000024, + 0x000006ea,0x00000647,0x00050081,0x00000024,0x000006eb,0x000006e9,0x000006ea,0x0004003d, + 0x00000024,0x000006ec,0x00000658,0x00050083,0x00000024,0x000006ed,0x000006eb,0x000006ec, + 0x00050083,0x00000024,0x000006ee,0x000006ed,0x000004bf,0x0004003d,0x00000024,0x000006ef, + 0x00000637,0x0003003e,0x00000659,0x000001d6,0x0004003d,0x00000006,0x000007e9,0x00000659, + 0x00050041,0x00000007,0x000007ea,0x000007e6,0x000000ab,0x0003003e,0x000007ea,0x000007e9, + 0x0004003d,0x00000006,0x000007eb,0x00000659,0x00050041,0x00000007,0x000007ec,0x000007e6, + 0x000000ae,0x0003003e,0x000007ec,0x000007eb,0x0004003d,0x00000006,0x000007ed,0x00000659, + 0x00050041,0x00000007,0x000007ee,0x000007e6,0x000000c1,0x0003003e,0x000007ee,0x000007ed, + 0x0004003d,0x00000024,0x000007ef,0x000007e6,0x0003003e,0x000007e7,0x000007ef,0x0004003d, + 0x00000024,0x000006f0,0x000007e7,0x000500ba,0x000001dc,0x000006f1,0x000006ef,0x000006f0, + 0x000600a9,0x00000024,0x000006f2,0x000006f1,0x000006ee,0x000006e8,0x0005008e,0x00000024, + 0x000006f3,0x000006f2,0x000001cf,0x0003003e,0x00000649,0x000006f3,0x000200f9,0x00000766, + 0x000200f8,0x000006f4,0x0003003e,0x0000065a,0x0000025a,0x000200f9,0x000006f5,0x000200f8, + 0x000006f5,0x0004003d,0x00000083,0x000006f7,0x0000065a,0x000500b1,0x000000f5,0x000006f8, + 0x000006f7,0x00000261,0x000400f6,0x00000724,0x00000721,0x00000000,0x000400fa,0x000006f8, + 0x000006f9,0x00000724,0x000200f8,0x000006f9,0x0004003d,0x00000083,0x000006fa,0x0000065a, + 0x00050041,0x00000007,0x000006fb,0x00000637,0x000006fa,0x0004003d,0x00000006,0x000006fc, + 0x000006fb,0x000500bc,0x000000f5,0x000006fd,0x000006fc,0x000001d6,0x000300f7,0x00000720, + 0x00000000,0x000400fa,0x000006fd,0x000006fe,0x00000705,0x000200f8,0x000006fe,0x0004003d, + 0x00000083,0x000006ff,0x0000065a,0x0004003d,0x00000083,0x00000700,0x0000065a,0x00050041, + 0x00000007,0x00000701,0x00000647,0x00000700,0x0004003d,0x00000006,0x00000702,0x00000701, + 0x00050083,0x00000006,0x00000703,0x000000e1,0x00000702,0x00050041,0x00000007,0x00000704, + 0x00000649,0x000006ff,0x0003003e,0x00000704,0x00000703,0x000200f9,0x00000720,0x000200f8, + 0x00000705,0x0004003d,0x00000083,0x00000706,0x0000065a,0x00050041,0x00000007,0x00000707, + 0x00000647,0x00000706,0x0004003d,0x00000006,0x00000708,0x00000707,0x000500bc,0x000000f5, + 0x00000709,0x00000708,0x00000273,0x000300f7,0x0000071f,0x00000000,0x000400fa,0x00000709, + 0x0000070a,0x00000717,0x000200f8,0x0000070a,0x0004003d,0x00000083,0x0000070b,0x0000065a, + 0x0004003d,0x00000083,0x0000070c,0x0000065a,0x00050041,0x00000007,0x0000070d,0x00000647, + 0x0000070c,0x0004003d,0x00000006,0x0000070e,0x0000070d,0x00050085,0x00000006,0x0000070f, + 0x00000278,0x0000070e,0x00050083,0x00000006,0x00000710,0x0000070f,0x0000027d,0x0004003d, + 0x00000083,0x00000711,0x0000065a,0x00050041,0x00000007,0x00000712,0x00000647,0x00000711, + 0x0004003d,0x00000006,0x00000713,0x00000712,0x00050085,0x00000006,0x00000714,0x00000710, + 0x00000713,0x00050081,0x00000006,0x00000715,0x00000714,0x00000283,0x00050041,0x00000007, + 0x00000716,0x00000649,0x0000070b,0x0003003e,0x00000716,0x00000715,0x000200f9,0x0000071f, + 0x000200f8,0x00000717,0x0004003d,0x00000083,0x00000718,0x0000065a,0x0004003d,0x00000083, + 0x00000719,0x0000065a,0x00050041,0x00000007,0x0000071a,0x00000647,0x00000719,0x0004003d, + 0x00000006,0x0000071b,0x0000071a,0x0006000c,0x00000006,0x0000071c,0x00000001,0x00000020, + 0x0000071b,0x00050083,0x00000006,0x0000071d,0x0000071c,0x000000e1,0x00050041,0x00000007, + 0x0000071e,0x00000649,0x00000718,0x0003003e,0x0000071e,0x0000071d,0x000200f9,0x0000071f, + 0x000200f8,0x0000071f,0x000200f9,0x00000720,0x000200f8,0x00000720,0x000200f9,0x00000721, + 0x000200f8,0x00000721,0x0004003d,0x00000083,0x00000722,0x0000065a,0x00050080,0x00000083, + 0x00000723,0x00000722,0x0000028f,0x0003003e,0x0000065a,0x00000723,0x000200f9,0x000006f5, + 0x000200f8,0x00000724,0x0004003d,0x00000024,0x00000725,0x00000647,0x0004003d,0x00000024, + 0x00000726,0x00000647,0x0004003d,0x00000024,0x00000727,0x00000637,0x0005008e,0x00000024, + 0x00000728,0x00000727,0x000001cf,0x00050083,0x00000024,0x00000729,0x00000728,0x000004be, + 0x00050085,0x00000024,0x0000072a,0x00000726,0x00000729,0x0004003d,0x00000024,0x0000072b, + 0x00000649,0x00050085,0x00000024,0x0000072c,0x0000072a,0x0000072b,0x00050081,0x00000024, + 0x0000072d,0x00000725,0x0000072c,0x0003003e,0x00000649,0x0000072d,0x000200f9,0x00000766, + 0x000200f8,0x0000072e,0x0004003d,0x00000024,0x0000072f,0x00000647,0x0004003d,0x00000024, + 0x00000730,0x00000637,0x00050083,0x00000024,0x00000731,0x0000072f,0x00000730,0x0006000c, + 0x00000024,0x00000732,0x00000001,0x00000004,0x00000731,0x0003003e,0x00000649,0x00000732, + 0x000200f9,0x00000766,0x000200f8,0x00000733,0x0004003d,0x00000024,0x00000734,0x00000637, + 0x0004003d,0x00000024,0x00000735,0x00000647,0x00050081,0x00000024,0x00000736,0x00000734, + 0x00000735,0x0004003d,0x00000024,0x00000737,0x00000637,0x0005008e,0x00000024,0x00000738, + 0x00000737,0x000001cf,0x0004003d,0x00000024,0x00000739,0x00000647,0x00050085,0x00000024, + 0x0000073a,0x00000738,0x00000739,0x00050083,0x00000024,0x0000073b,0x00000736,0x0000073a, + 0x0003003e,0x00000649,0x0000073b,0x000200f9,0x00000766,0x000200f8,0x0000073c,0x000300f7, + 0x00000746,0x00000000,0x000400fa,0x000002aa,0x0000073d,0x00000746,0x000200f8,0x0000073d, + 0x0004003d,0x00000024,0x0000073e,0x00000637,0x0003003e,0x0000065b,0x000000e2,0x0004003d, + 0x00000006,0x000007f3,0x0000065b,0x00050041,0x00000007,0x000007f4,0x000007f0,0x000000ab, + 0x0003003e,0x000007f4,0x000007f3,0x0004003d,0x00000006,0x000007f5,0x0000065b,0x00050041, + 0x00000007,0x000007f6,0x000007f0,0x000000ae,0x0003003e,0x000007f6,0x000007f5,0x0004003d, + 0x00000006,0x000007f7,0x0000065b,0x00050041,0x00000007,0x000007f8,0x000007f0,0x000000c1, + 0x0003003e,0x000007f8,0x000007f7,0x0004003d,0x00000024,0x000007f9,0x000007f0,0x0003003e, + 0x000007f1,0x000007f9,0x0004003d,0x00000024,0x0000073f,0x000007f1,0x0003003e,0x0000065c, + 0x000000e1,0x0004003d,0x00000006,0x000007fd,0x0000065c,0x00050041,0x00000007,0x000007fe, + 0x000007fa,0x000000ab,0x0003003e,0x000007fe,0x000007fd,0x0004003d,0x00000006,0x000007ff, + 0x0000065c,0x00050041,0x00000007,0x00000800,0x000007fa,0x000000ae,0x0003003e,0x00000800, + 0x000007ff,0x0004003d,0x00000006,0x00000801,0x0000065c,0x00050041,0x00000007,0x00000802, + 0x000007fa,0x000000c1,0x0003003e,0x00000802,0x00000801,0x0004003d,0x00000024,0x00000803, + 0x000007fa,0x0003003e,0x000007fb,0x00000803,0x0004003d,0x00000024,0x00000740,0x000007fb, + 0x0008000c,0x00000024,0x00000741,0x00000001,0x0000002b,0x0000073e,0x0000073f,0x00000740, + 0x0003003e,0x00000637,0x00000741,0x0004003d,0x00000024,0x00000742,0x00000637,0x0003003e, + 0x0000065d,0x00000742,0x0004003d,0x00000024,0x00000743,0x00000647,0x0003003e,0x0000065e, + 0x00000743,0x0004003d,0x00000024,0x00000744,0x00000647,0x0003003e,0x0000065f,0x00000744, + 0x0004003d,0x00000024,0x0000080f,0x0000065e,0x0003003e,0x00000805,0x0000080f,0x0004003d, + 0x00000024,0x00000827,0x00000805,0x0007004f,0x0000000c,0x00000828,0x00000827,0x00000827, + 0x00000000,0x00000001,0x0003003e,0x00000824,0x00000828,0x00050041,0x00000007,0x0000082f, + 0x00000824,0x000000ab,0x0004003d,0x00000006,0x00000830,0x0000082f,0x00050041,0x00000007, + 0x00000831,0x00000824,0x000000ae,0x0004003d,0x00000006,0x00000832,0x00000831,0x0007000c, + 0x00000006,0x00000833,0x00000001,0x00000028,0x00000830,0x00000832,0x0003003e,0x0000082d, + 0x00000833,0x0004003d,0x00000006,0x00000829,0x0000082d,0x00050041,0x00000007,0x0000082a, + 0x00000805,0x000000c1,0x0004003d,0x00000006,0x0000082b,0x0000082a,0x0007000c,0x00000006, + 0x0000082c,0x00000001,0x00000028,0x00000829,0x0000082b,0x0003003e,0x00000825,0x0000082c, + 0x0004003d,0x00000006,0x00000810,0x00000825,0x0004003d,0x00000024,0x00000811,0x0000065e, + 0x0003003e,0x00000806,0x00000811,0x0004003d,0x00000024,0x00000837,0x00000806,0x0007004f, + 0x0000000c,0x00000838,0x00000837,0x00000837,0x00000000,0x00000001,0x0003003e,0x00000834, + 0x00000838,0x00050041,0x00000007,0x0000083f,0x00000834,0x000000ab,0x0004003d,0x00000006, + 0x00000840,0x0000083f,0x00050041,0x00000007,0x00000841,0x00000834,0x000000ae,0x0004003d, + 0x00000006,0x00000842,0x00000841,0x0007000c,0x00000006,0x00000843,0x00000001,0x00000025, + 0x00000840,0x00000842,0x0003003e,0x0000083d,0x00000843,0x0004003d,0x00000006,0x00000839, + 0x0000083d,0x00050041,0x00000007,0x0000083a,0x00000806,0x000000c1,0x0004003d,0x00000006, + 0x0000083b,0x0000083a,0x0007000c,0x00000006,0x0000083c,0x00000001,0x00000025,0x00000839, + 0x0000083b,0x0003003e,0x00000835,0x0000083c,0x0004003d,0x00000006,0x00000812,0x00000835, + 0x00050083,0x00000006,0x00000813,0x00000810,0x00000812,0x0003003e,0x00000804,0x00000813, + 0x0004003d,0x00000024,0x00000814,0x0000065d,0x0003003e,0x00000807,0x00000814,0x0004003d, + 0x00000024,0x00000847,0x00000807,0x0007004f,0x0000000c,0x00000848,0x00000847,0x00000847, + 0x00000000,0x00000001,0x0003003e,0x00000844,0x00000848,0x00050041,0x00000007,0x0000084f, + 0x00000844,0x000000ab,0x0004003d,0x00000006,0x00000850,0x0000084f,0x00050041,0x00000007, + 0x00000851,0x00000844,0x000000ae,0x0004003d,0x00000006,0x00000852,0x00000851,0x0007000c, + 0x00000006,0x00000853,0x00000001,0x00000025,0x00000850,0x00000852,0x0003003e,0x0000084d, + 0x00000853,0x0004003d,0x00000006,0x00000849,0x0000084d,0x00050041,0x00000007,0x0000084a, + 0x00000807,0x000000c1,0x0004003d,0x00000006,0x0000084b,0x0000084a,0x0007000c,0x00000006, + 0x0000084c,0x00000001,0x00000025,0x00000849,0x0000084b,0x0003003e,0x00000845,0x0000084c, + 0x0004003d,0x00000006,0x00000815,0x00000845,0x0004003d,0x00000024,0x00000816,0x0000065d, + 0x00060050,0x00000024,0x00000817,0x00000815,0x00000815,0x00000815,0x00050083,0x00000024, + 0x00000818,0x00000816,0x00000817,0x0003003e,0x0000065d,0x00000818,0x0004003d,0x00000024, + 0x00000819,0x0000065d,0x0003003e,0x00000809,0x00000819,0x0004003d,0x00000024,0x00000857, + 0x00000809,0x0007004f,0x0000000c,0x00000858,0x00000857,0x00000857,0x00000000,0x00000001, + 0x0003003e,0x00000854,0x00000858,0x00050041,0x00000007,0x0000085f,0x00000854,0x000000ab, + 0x0004003d,0x00000006,0x00000860,0x0000085f,0x00050041,0x00000007,0x00000861,0x00000854, + 0x000000ae,0x0004003d,0x00000006,0x00000862,0x00000861,0x0007000c,0x00000006,0x00000863, + 0x00000001,0x00000028,0x00000860,0x00000862,0x0003003e,0x0000085d,0x00000863,0x0004003d, + 0x00000006,0x00000859,0x0000085d,0x00050041,0x00000007,0x0000085a,0x00000809,0x000000c1, + 0x0004003d,0x00000006,0x0000085b,0x0000085a,0x0007000c,0x00000006,0x0000085c,0x00000001, + 0x00000028,0x00000859,0x0000085b,0x0003003e,0x00000855,0x0000085c,0x0004003d,0x00000006, + 0x0000081a,0x00000855,0x0003003e,0x00000808,0x0000081a,0x0004003d,0x00000006,0x0000081b, + 0x00000804,0x0004003d,0x00000006,0x0000081c,0x00000808,0x0007000c,0x00000006,0x0000081d, + 0x00000001,0x00000028,0x00000169,0x0000081c,0x00050088,0x00000006,0x0000081e,0x0000081b, + 0x0000081d,0x0003003e,0x0000080a,0x0000081e,0x0004003d,0x00000024,0x0000081f,0x0000065d, + 0x0004003d,0x00000006,0x00000820,0x0000080a,0x0005008e,0x00000024,0x00000821,0x0000081f, + 0x00000820,0x0003003e,0x0000080b,0x00000821,0x0004003d,0x00000024,0x00000822,0x0000065f, + 0x0003003e,0x0000080c,0x00000822,0x0004003d,0x00000024,0x00000874,0x0000080c,0x0003003e, + 0x00000865,0x00000874,0x0004003d,0x00000024,0x0000089a,0x00000865,0x0003003e,0x00000895, + 0x0000014d,0x0003003e,0x00000896,0x0000014e,0x0003003e,0x00000897,0x0000014f,0x0004003d, + 0x00000006,0x000008a0,0x00000895,0x00050041,0x00000007,0x000008a1,0x0000089d,0x000000ab, + 0x0003003e,0x000008a1,0x000008a0,0x0004003d,0x00000006,0x000008a2,0x00000896,0x00050041, + 0x00000007,0x000008a3,0x0000089d,0x000000ae,0x0003003e,0x000008a3,0x000008a2,0x0004003d, + 0x00000006,0x000008a4,0x00000897,0x00050041,0x00000007,0x000008a5,0x0000089d,0x000000c1, + 0x0003003e,0x000008a5,0x000008a4,0x0004003d,0x00000024,0x000008a6,0x0000089d,0x0003003e, + 0x0000089e,0x000008a6,0x0004003d,0x00000024,0x0000089b,0x0000089e,0x00050094,0x00000006, + 0x0000089c,0x0000089a,0x0000089b,0x0003003e,0x00000898,0x0000089c,0x0004003d,0x00000006, + 0x00000875,0x00000898,0x0003003e,0x00000864,0x00000875,0x0004003d,0x00000024,0x00000876, + 0x0000080b,0x0004003d,0x00000024,0x00000877,0x0000080b,0x0003003e,0x00000867,0x00000877, + 0x0004003d,0x00000024,0x000008ac,0x00000867,0x0003003e,0x000008a7,0x0000014d,0x0003003e, + 0x000008a8,0x0000014e,0x0003003e,0x000008a9,0x0000014f,0x0004003d,0x00000006,0x000008b2, + 0x000008a7,0x00050041,0x00000007,0x000008b3,0x000008af,0x000000ab,0x0003003e,0x000008b3, + 0x000008b2,0x0004003d,0x00000006,0x000008b4,0x000008a8,0x00050041,0x00000007,0x000008b5, + 0x000008af,0x000000ae,0x0003003e,0x000008b5,0x000008b4,0x0004003d,0x00000006,0x000008b6, + 0x000008a9,0x00050041,0x00000007,0x000008b7,0x000008af,0x000000c1,0x0003003e,0x000008b7, + 0x000008b6,0x0004003d,0x00000024,0x000008b8,0x000008af,0x0003003e,0x000008b0,0x000008b8, + 0x0004003d,0x00000024,0x000008ad,0x000008b0,0x00050094,0x00000006,0x000008ae,0x000008ac, + 0x000008ad,0x0003003e,0x000008aa,0x000008ae,0x0004003d,0x00000006,0x00000878,0x000008aa, + 0x00060050,0x00000024,0x00000879,0x00000878,0x00000878,0x00000878,0x00050083,0x00000024, + 0x0000087a,0x00000876,0x00000879,0x0003003e,0x00000866,0x0000087a,0x0004003d,0x00000006, + 0x0000087b,0x00000864,0x00050083,0x00000006,0x0000087c,0x000000e1,0x0000087b,0x0004003d, + 0x00000006,0x0000087d,0x00000864,0x0003003e,0x00000869,0x0000087d,0x0003003e,0x0000086a, + 0x0000087c,0x0004003d,0x00000006,0x000008bc,0x00000869,0x00050041,0x00000007,0x000008bd, + 0x000008b9,0x000000ab,0x0003003e,0x000008bd,0x000008bc,0x0004003d,0x00000006,0x000008be, + 0x0000086a,0x00050041,0x00000007,0x000008bf,0x000008b9,0x000000ae,0x0003003e,0x000008bf, + 0x000008be,0x0004003d,0x0000000c,0x000008c0,0x000008b9,0x0003003e,0x000008ba,0x000008c0, + 0x0004003d,0x0000000c,0x0000087e,0x000008ba,0x0003003e,0x0000086b,0x00000169,0x0004003d, + 0x00000006,0x000008c4,0x0000086b,0x00050041,0x00000007,0x000008c5,0x000008c1,0x000000ab, + 0x0003003e,0x000008c5,0x000008c4,0x0004003d,0x00000006,0x000008c6,0x0000086b,0x00050041, + 0x00000007,0x000008c7,0x000008c1,0x000000ae,0x0003003e,0x000008c7,0x000008c6,0x0004003d, + 0x0000000c,0x000008c8,0x000008c1,0x0003003e,0x000008c2,0x000008c8,0x0004003d,0x0000000c, + 0x0000087f,0x000008c2,0x0004003d,0x00000024,0x00000880,0x00000866,0x0003003e,0x0000086c, + 0x00000880,0x0004003d,0x00000024,0x000008cc,0x0000086c,0x0007004f,0x0000000c,0x000008cd, + 0x000008cc,0x000008cc,0x00000000,0x00000001,0x0003003e,0x000008c9,0x000008cd,0x00050041, + 0x00000007,0x000008d4,0x000008c9,0x000000ab,0x0004003d,0x00000006,0x000008d5,0x000008d4, + 0x00050041,0x00000007,0x000008d6,0x000008c9,0x000000ae,0x0004003d,0x00000006,0x000008d7, + 0x000008d6,0x0007000c,0x00000006,0x000008d8,0x00000001,0x00000025,0x000008d5,0x000008d7, + 0x0003003e,0x000008d2,0x000008d8,0x0004003d,0x00000006,0x000008ce,0x000008d2,0x00050041, + 0x00000007,0x000008cf,0x0000086c,0x000000c1,0x0004003d,0x00000006,0x000008d0,0x000008cf, + 0x0007000c,0x00000006,0x000008d1,0x00000001,0x00000025,0x000008ce,0x000008d0,0x0003003e, + 0x000008ca,0x000008d1,0x0004003d,0x00000006,0x00000881,0x000008ca,0x0004007f,0x00000006, + 0x00000882,0x00000881,0x0004003d,0x00000024,0x00000883,0x00000866,0x0003003e,0x0000086d, + 0x00000883,0x0004003d,0x00000024,0x000008dc,0x0000086d,0x0007004f,0x0000000c,0x000008dd, + 0x000008dc,0x000008dc,0x00000000,0x00000001,0x0003003e,0x000008d9,0x000008dd,0x00050041, + 0x00000007,0x000008e4,0x000008d9,0x000000ab,0x0004003d,0x00000006,0x000008e5,0x000008e4, + 0x00050041,0x00000007,0x000008e6,0x000008d9,0x000000ae,0x0004003d,0x00000006,0x000008e7, + 0x000008e6,0x0007000c,0x00000006,0x000008e8,0x00000001,0x00000028,0x000008e5,0x000008e7, + 0x0003003e,0x000008e2,0x000008e8,0x0004003d,0x00000006,0x000008de,0x000008e2,0x00050041, + 0x00000007,0x000008df,0x0000086d,0x000000c1,0x0004003d,0x00000006,0x000008e0,0x000008df, + 0x0007000c,0x00000006,0x000008e1,0x00000001,0x00000028,0x000008de,0x000008e0,0x0003003e, + 0x000008da,0x000008e1,0x0004003d,0x00000006,0x00000884,0x000008da,0x0003003e,0x0000086e, + 0x00000882,0x0003003e,0x0000086f,0x00000884,0x0004003d,0x00000006,0x000008ec,0x0000086e, + 0x00050041,0x00000007,0x000008ed,0x000008e9,0x000000ab,0x0003003e,0x000008ed,0x000008ec, + 0x0004003d,0x00000006,0x000008ee,0x0000086f,0x00050041,0x00000007,0x000008ef,0x000008e9, + 0x000000ae,0x0003003e,0x000008ef,0x000008ee,0x0004003d,0x0000000c,0x000008f0,0x000008e9, + 0x0003003e,0x000008ea,0x000008f0,0x0004003d,0x0000000c,0x00000885,0x000008ea,0x0007000c, + 0x0000000c,0x00000886,0x00000001,0x00000028,0x0000087f,0x00000885,0x00050088,0x0000000c, + 0x00000887,0x0000087e,0x00000886,0x0003003e,0x00000868,0x00000887,0x0003003e,0x00000871, + 0x000000e1,0x0004003d,0x00000006,0x000008f3,0x00000871,0x0003003e,0x000008f1,0x000008f3, + 0x0004003d,0x00000006,0x00000888,0x000008f1,0x00050041,0x00000007,0x00000889,0x00000868, + 0x000000ab,0x0004003d,0x00000006,0x0000088a,0x00000889,0x00050041,0x00000007,0x0000088b, + 0x00000868,0x000000ae,0x0004003d,0x00000006,0x0000088c,0x0000088b,0x0007000c,0x00000006, + 0x0000088d,0x00000001,0x00000025,0x0000088a,0x0000088c,0x0007000c,0x00000006,0x0000088e, + 0x00000001,0x00000025,0x00000888,0x0000088d,0x0003003e,0x00000870,0x0000088e,0x0004003d, + 0x00000024,0x0000088f,0x00000866,0x0004003d,0x00000006,0x00000890,0x00000870,0x0005008e, + 0x00000024,0x00000891,0x0000088f,0x00000890,0x0004003d,0x00000006,0x00000892,0x00000864, + 0x00060050,0x00000024,0x00000893,0x00000892,0x00000892,0x00000892,0x00050081,0x00000024, + 0x00000894,0x00000891,0x00000893,0x0003003e,0x00000872,0x00000894,0x0004003d,0x00000024, + 0x00000823,0x00000872,0x0003003e,0x0000080d,0x00000823,0x0004003d,0x00000024,0x00000745, + 0x0000080d,0x0003003e,0x00000649,0x00000745,0x000200f9,0x00000746,0x000200f8,0x00000746, + 0x000200f9,0x00000766,0x000200f8,0x00000747,0x000300f7,0x00000751,0x00000000,0x000400fa, + 0x000002aa,0x00000748,0x00000751,0x000200f8,0x00000748,0x0004003d,0x00000024,0x00000749, + 0x00000637,0x0003003e,0x00000660,0x000000e2,0x0004003d,0x00000006,0x000008f7,0x00000660, + 0x00050041,0x00000007,0x000008f8,0x000008f4,0x000000ab,0x0003003e,0x000008f8,0x000008f7, + 0x0004003d,0x00000006,0x000008f9,0x00000660,0x00050041,0x00000007,0x000008fa,0x000008f4, + 0x000000ae,0x0003003e,0x000008fa,0x000008f9,0x0004003d,0x00000006,0x000008fb,0x00000660, + 0x00050041,0x00000007,0x000008fc,0x000008f4,0x000000c1,0x0003003e,0x000008fc,0x000008fb, + 0x0004003d,0x00000024,0x000008fd,0x000008f4,0x0003003e,0x000008f5,0x000008fd,0x0004003d, + 0x00000024,0x0000074a,0x000008f5,0x0003003e,0x00000661,0x000000e1,0x0004003d,0x00000006, + 0x00000901,0x00000661,0x00050041,0x00000007,0x00000902,0x000008fe,0x000000ab,0x0003003e, + 0x00000902,0x00000901,0x0004003d,0x00000006,0x00000903,0x00000661,0x00050041,0x00000007, + 0x00000904,0x000008fe,0x000000ae,0x0003003e,0x00000904,0x00000903,0x0004003d,0x00000006, + 0x00000905,0x00000661,0x00050041,0x00000007,0x00000906,0x000008fe,0x000000c1,0x0003003e, + 0x00000906,0x00000905,0x0004003d,0x00000024,0x00000907,0x000008fe,0x0003003e,0x000008ff, + 0x00000907,0x0004003d,0x00000024,0x0000074b,0x000008ff,0x0008000c,0x00000024,0x0000074c, + 0x00000001,0x0000002b,0x00000749,0x0000074a,0x0000074b,0x0003003e,0x00000637,0x0000074c, + 0x0004003d,0x00000024,0x0000074d,0x00000647,0x0003003e,0x00000662,0x0000074d,0x0004003d, + 0x00000024,0x0000074e,0x00000637,0x0003003e,0x00000663,0x0000074e,0x0004003d,0x00000024, + 0x0000074f,0x00000647,0x0003003e,0x00000664,0x0000074f,0x0004003d,0x00000024,0x00000913, + 0x00000663,0x0003003e,0x00000909,0x00000913,0x0004003d,0x00000024,0x0000092b,0x00000909, + 0x0007004f,0x0000000c,0x0000092c,0x0000092b,0x0000092b,0x00000000,0x00000001,0x0003003e, + 0x00000928,0x0000092c,0x00050041,0x00000007,0x00000933,0x00000928,0x000000ab,0x0004003d, + 0x00000006,0x00000934,0x00000933,0x00050041,0x00000007,0x00000935,0x00000928,0x000000ae, + 0x0004003d,0x00000006,0x00000936,0x00000935,0x0007000c,0x00000006,0x00000937,0x00000001, + 0x00000028,0x00000934,0x00000936,0x0003003e,0x00000931,0x00000937,0x0004003d,0x00000006, + 0x0000092d,0x00000931,0x00050041,0x00000007,0x0000092e,0x00000909,0x000000c1,0x0004003d, + 0x00000006,0x0000092f,0x0000092e,0x0007000c,0x00000006,0x00000930,0x00000001,0x00000028, + 0x0000092d,0x0000092f,0x0003003e,0x00000929,0x00000930,0x0004003d,0x00000006,0x00000914, + 0x00000929,0x0004003d,0x00000024,0x00000915,0x00000663,0x0003003e,0x0000090a,0x00000915, + 0x0004003d,0x00000024,0x0000093b,0x0000090a,0x0007004f,0x0000000c,0x0000093c,0x0000093b, + 0x0000093b,0x00000000,0x00000001,0x0003003e,0x00000938,0x0000093c,0x00050041,0x00000007, + 0x00000943,0x00000938,0x000000ab,0x0004003d,0x00000006,0x00000944,0x00000943,0x00050041, + 0x00000007,0x00000945,0x00000938,0x000000ae,0x0004003d,0x00000006,0x00000946,0x00000945, + 0x0007000c,0x00000006,0x00000947,0x00000001,0x00000025,0x00000944,0x00000946,0x0003003e, + 0x00000941,0x00000947,0x0004003d,0x00000006,0x0000093d,0x00000941,0x00050041,0x00000007, + 0x0000093e,0x0000090a,0x000000c1,0x0004003d,0x00000006,0x0000093f,0x0000093e,0x0007000c, + 0x00000006,0x00000940,0x00000001,0x00000025,0x0000093d,0x0000093f,0x0003003e,0x00000939, + 0x00000940,0x0004003d,0x00000006,0x00000916,0x00000939,0x00050083,0x00000006,0x00000917, + 0x00000914,0x00000916,0x0003003e,0x00000908,0x00000917,0x0004003d,0x00000024,0x00000918, + 0x00000662,0x0003003e,0x0000090b,0x00000918,0x0004003d,0x00000024,0x0000094b,0x0000090b, + 0x0007004f,0x0000000c,0x0000094c,0x0000094b,0x0000094b,0x00000000,0x00000001,0x0003003e, + 0x00000948,0x0000094c,0x00050041,0x00000007,0x00000953,0x00000948,0x000000ab,0x0004003d, + 0x00000006,0x00000954,0x00000953,0x00050041,0x00000007,0x00000955,0x00000948,0x000000ae, + 0x0004003d,0x00000006,0x00000956,0x00000955,0x0007000c,0x00000006,0x00000957,0x00000001, + 0x00000025,0x00000954,0x00000956,0x0003003e,0x00000951,0x00000957,0x0004003d,0x00000006, + 0x0000094d,0x00000951,0x00050041,0x00000007,0x0000094e,0x0000090b,0x000000c1,0x0004003d, + 0x00000006,0x0000094f,0x0000094e,0x0007000c,0x00000006,0x00000950,0x00000001,0x00000025, + 0x0000094d,0x0000094f,0x0003003e,0x00000949,0x00000950,0x0004003d,0x00000006,0x00000919, + 0x00000949,0x0004003d,0x00000024,0x0000091a,0x00000662,0x00060050,0x00000024,0x0000091b, + 0x00000919,0x00000919,0x00000919,0x00050083,0x00000024,0x0000091c,0x0000091a,0x0000091b, + 0x0003003e,0x00000662,0x0000091c,0x0004003d,0x00000024,0x0000091d,0x00000662,0x0003003e, + 0x0000090d,0x0000091d,0x0004003d,0x00000024,0x0000095b,0x0000090d,0x0007004f,0x0000000c, + 0x0000095c,0x0000095b,0x0000095b,0x00000000,0x00000001,0x0003003e,0x00000958,0x0000095c, + 0x00050041,0x00000007,0x00000963,0x00000958,0x000000ab,0x0004003d,0x00000006,0x00000964, + 0x00000963,0x00050041,0x00000007,0x00000965,0x00000958,0x000000ae,0x0004003d,0x00000006, + 0x00000966,0x00000965,0x0007000c,0x00000006,0x00000967,0x00000001,0x00000028,0x00000964, + 0x00000966,0x0003003e,0x00000961,0x00000967,0x0004003d,0x00000006,0x0000095d,0x00000961, + 0x00050041,0x00000007,0x0000095e,0x0000090d,0x000000c1,0x0004003d,0x00000006,0x0000095f, + 0x0000095e,0x0007000c,0x00000006,0x00000960,0x00000001,0x00000028,0x0000095d,0x0000095f, + 0x0003003e,0x00000959,0x00000960,0x0004003d,0x00000006,0x0000091e,0x00000959,0x0003003e, + 0x0000090c,0x0000091e,0x0004003d,0x00000006,0x0000091f,0x00000908,0x0004003d,0x00000006, + 0x00000920,0x0000090c,0x0007000c,0x00000006,0x00000921,0x00000001,0x00000028,0x00000169, + 0x00000920,0x00050088,0x00000006,0x00000922,0x0000091f,0x00000921,0x0003003e,0x0000090e, + 0x00000922,0x0004003d,0x00000024,0x00000923,0x00000662,0x0004003d,0x00000006,0x00000924, + 0x0000090e,0x0005008e,0x00000024,0x00000925,0x00000923,0x00000924,0x0003003e,0x0000090f, + 0x00000925,0x0004003d,0x00000024,0x00000926,0x00000664,0x0003003e,0x00000910,0x00000926, + 0x0004003d,0x00000024,0x00000978,0x00000910,0x0003003e,0x00000969,0x00000978,0x0004003d, + 0x00000024,0x0000099e,0x00000969,0x0003003e,0x00000999,0x0000014d,0x0003003e,0x0000099a, + 0x0000014e,0x0003003e,0x0000099b,0x0000014f,0x0004003d,0x00000006,0x000009a4,0x00000999, + 0x00050041,0x00000007,0x000009a5,0x000009a1,0x000000ab,0x0003003e,0x000009a5,0x000009a4, + 0x0004003d,0x00000006,0x000009a6,0x0000099a,0x00050041,0x00000007,0x000009a7,0x000009a1, + 0x000000ae,0x0003003e,0x000009a7,0x000009a6,0x0004003d,0x00000006,0x000009a8,0x0000099b, + 0x00050041,0x00000007,0x000009a9,0x000009a1,0x000000c1,0x0003003e,0x000009a9,0x000009a8, + 0x0004003d,0x00000024,0x000009aa,0x000009a1,0x0003003e,0x000009a2,0x000009aa,0x0004003d, + 0x00000024,0x0000099f,0x000009a2,0x00050094,0x00000006,0x000009a0,0x0000099e,0x0000099f, + 0x0003003e,0x0000099c,0x000009a0,0x0004003d,0x00000006,0x00000979,0x0000099c,0x0003003e, + 0x00000968,0x00000979,0x0004003d,0x00000024,0x0000097a,0x0000090f,0x0004003d,0x00000024, + 0x0000097b,0x0000090f,0x0003003e,0x0000096b,0x0000097b,0x0004003d,0x00000024,0x000009b0, + 0x0000096b,0x0003003e,0x000009ab,0x0000014d,0x0003003e,0x000009ac,0x0000014e,0x0003003e, + 0x000009ad,0x0000014f,0x0004003d,0x00000006,0x000009b6,0x000009ab,0x00050041,0x00000007, + 0x000009b7,0x000009b3,0x000000ab,0x0003003e,0x000009b7,0x000009b6,0x0004003d,0x00000006, + 0x000009b8,0x000009ac,0x00050041,0x00000007,0x000009b9,0x000009b3,0x000000ae,0x0003003e, + 0x000009b9,0x000009b8,0x0004003d,0x00000006,0x000009ba,0x000009ad,0x00050041,0x00000007, + 0x000009bb,0x000009b3,0x000000c1,0x0003003e,0x000009bb,0x000009ba,0x0004003d,0x00000024, + 0x000009bc,0x000009b3,0x0003003e,0x000009b4,0x000009bc,0x0004003d,0x00000024,0x000009b1, + 0x000009b4,0x00050094,0x00000006,0x000009b2,0x000009b0,0x000009b1,0x0003003e,0x000009ae, + 0x000009b2,0x0004003d,0x00000006,0x0000097c,0x000009ae,0x00060050,0x00000024,0x0000097d, + 0x0000097c,0x0000097c,0x0000097c,0x00050083,0x00000024,0x0000097e,0x0000097a,0x0000097d, + 0x0003003e,0x0000096a,0x0000097e,0x0004003d,0x00000006,0x0000097f,0x00000968,0x00050083, + 0x00000006,0x00000980,0x000000e1,0x0000097f,0x0004003d,0x00000006,0x00000981,0x00000968, + 0x0003003e,0x0000096d,0x00000981,0x0003003e,0x0000096e,0x00000980,0x0004003d,0x00000006, + 0x000009c0,0x0000096d,0x00050041,0x00000007,0x000009c1,0x000009bd,0x000000ab,0x0003003e, + 0x000009c1,0x000009c0,0x0004003d,0x00000006,0x000009c2,0x0000096e,0x00050041,0x00000007, + 0x000009c3,0x000009bd,0x000000ae,0x0003003e,0x000009c3,0x000009c2,0x0004003d,0x0000000c, + 0x000009c4,0x000009bd,0x0003003e,0x000009be,0x000009c4,0x0004003d,0x0000000c,0x00000982, + 0x000009be,0x0003003e,0x0000096f,0x00000169,0x0004003d,0x00000006,0x000009c8,0x0000096f, + 0x00050041,0x00000007,0x000009c9,0x000009c5,0x000000ab,0x0003003e,0x000009c9,0x000009c8, + 0x0004003d,0x00000006,0x000009ca,0x0000096f,0x00050041,0x00000007,0x000009cb,0x000009c5, + 0x000000ae,0x0003003e,0x000009cb,0x000009ca,0x0004003d,0x0000000c,0x000009cc,0x000009c5, + 0x0003003e,0x000009c6,0x000009cc,0x0004003d,0x0000000c,0x00000983,0x000009c6,0x0004003d, + 0x00000024,0x00000984,0x0000096a,0x0003003e,0x00000970,0x00000984,0x0004003d,0x00000024, + 0x000009d0,0x00000970,0x0007004f,0x0000000c,0x000009d1,0x000009d0,0x000009d0,0x00000000, + 0x00000001,0x0003003e,0x000009cd,0x000009d1,0x00050041,0x00000007,0x000009d8,0x000009cd, + 0x000000ab,0x0004003d,0x00000006,0x000009d9,0x000009d8,0x00050041,0x00000007,0x000009da, + 0x000009cd,0x000000ae,0x0004003d,0x00000006,0x000009db,0x000009da,0x0007000c,0x00000006, + 0x000009dc,0x00000001,0x00000025,0x000009d9,0x000009db,0x0003003e,0x000009d6,0x000009dc, + 0x0004003d,0x00000006,0x000009d2,0x000009d6,0x00050041,0x00000007,0x000009d3,0x00000970, + 0x000000c1,0x0004003d,0x00000006,0x000009d4,0x000009d3,0x0007000c,0x00000006,0x000009d5, + 0x00000001,0x00000025,0x000009d2,0x000009d4,0x0003003e,0x000009ce,0x000009d5,0x0004003d, + 0x00000006,0x00000985,0x000009ce,0x0004007f,0x00000006,0x00000986,0x00000985,0x0004003d, + 0x00000024,0x00000987,0x0000096a,0x0003003e,0x00000971,0x00000987,0x0004003d,0x00000024, + 0x000009e0,0x00000971,0x0007004f,0x0000000c,0x000009e1,0x000009e0,0x000009e0,0x00000000, + 0x00000001,0x0003003e,0x000009dd,0x000009e1,0x00050041,0x00000007,0x000009e8,0x000009dd, + 0x000000ab,0x0004003d,0x00000006,0x000009e9,0x000009e8,0x00050041,0x00000007,0x000009ea, + 0x000009dd,0x000000ae,0x0004003d,0x00000006,0x000009eb,0x000009ea,0x0007000c,0x00000006, + 0x000009ec,0x00000001,0x00000028,0x000009e9,0x000009eb,0x0003003e,0x000009e6,0x000009ec, + 0x0004003d,0x00000006,0x000009e2,0x000009e6,0x00050041,0x00000007,0x000009e3,0x00000971, + 0x000000c1,0x0004003d,0x00000006,0x000009e4,0x000009e3,0x0007000c,0x00000006,0x000009e5, + 0x00000001,0x00000028,0x000009e2,0x000009e4,0x0003003e,0x000009de,0x000009e5,0x0004003d, + 0x00000006,0x00000988,0x000009de,0x0003003e,0x00000972,0x00000986,0x0003003e,0x00000973, + 0x00000988,0x0004003d,0x00000006,0x000009f0,0x00000972,0x00050041,0x00000007,0x000009f1, + 0x000009ed,0x000000ab,0x0003003e,0x000009f1,0x000009f0,0x0004003d,0x00000006,0x000009f2, + 0x00000973,0x00050041,0x00000007,0x000009f3,0x000009ed,0x000000ae,0x0003003e,0x000009f3, + 0x000009f2,0x0004003d,0x0000000c,0x000009f4,0x000009ed,0x0003003e,0x000009ee,0x000009f4, + 0x0004003d,0x0000000c,0x00000989,0x000009ee,0x0007000c,0x0000000c,0x0000098a,0x00000001, + 0x00000028,0x00000983,0x00000989,0x00050088,0x0000000c,0x0000098b,0x00000982,0x0000098a, + 0x0003003e,0x0000096c,0x0000098b,0x0003003e,0x00000975,0x000000e1,0x0004003d,0x00000006, + 0x000009f7,0x00000975,0x0003003e,0x000009f5,0x000009f7,0x0004003d,0x00000006,0x0000098c, + 0x000009f5,0x00050041,0x00000007,0x0000098d,0x0000096c,0x000000ab,0x0004003d,0x00000006, + 0x0000098e,0x0000098d,0x00050041,0x00000007,0x0000098f,0x0000096c,0x000000ae,0x0004003d, + 0x00000006,0x00000990,0x0000098f,0x0007000c,0x00000006,0x00000991,0x00000001,0x00000025, + 0x0000098e,0x00000990,0x0007000c,0x00000006,0x00000992,0x00000001,0x00000025,0x0000098c, + 0x00000991,0x0003003e,0x00000974,0x00000992,0x0004003d,0x00000024,0x00000993,0x0000096a, + 0x0004003d,0x00000006,0x00000994,0x00000974,0x0005008e,0x00000024,0x00000995,0x00000993, + 0x00000994,0x0004003d,0x00000006,0x00000996,0x00000968,0x00060050,0x00000024,0x00000997, + 0x00000996,0x00000996,0x00000996,0x00050081,0x00000024,0x00000998,0x00000995,0x00000997, + 0x0003003e,0x00000976,0x00000998,0x0004003d,0x00000024,0x00000927,0x00000976,0x0003003e, + 0x00000911,0x00000927,0x0004003d,0x00000024,0x00000750,0x00000911,0x0003003e,0x00000649, + 0x00000750,0x000200f9,0x00000751,0x000200f8,0x00000751,0x000200f9,0x00000766,0x000200f8, + 0x00000752,0x000300f7,0x0000075b,0x00000000,0x000400fa,0x000002aa,0x00000753,0x0000075b, + 0x000200f8,0x00000753,0x0004003d,0x00000024,0x00000754,0x00000637,0x0003003e,0x00000665, + 0x000000e2,0x0004003d,0x00000006,0x000009fb,0x00000665,0x00050041,0x00000007,0x000009fc, + 0x000009f8,0x000000ab,0x0003003e,0x000009fc,0x000009fb,0x0004003d,0x00000006,0x000009fd, + 0x00000665,0x00050041,0x00000007,0x000009fe,0x000009f8,0x000000ae,0x0003003e,0x000009fe, + 0x000009fd,0x0004003d,0x00000006,0x000009ff,0x00000665,0x00050041,0x00000007,0x00000a00, + 0x000009f8,0x000000c1,0x0003003e,0x00000a00,0x000009ff,0x0004003d,0x00000024,0x00000a01, + 0x000009f8,0x0003003e,0x000009f9,0x00000a01,0x0004003d,0x00000024,0x00000755,0x000009f9, + 0x0003003e,0x00000666,0x000000e1,0x0004003d,0x00000006,0x00000a05,0x00000666,0x00050041, + 0x00000007,0x00000a06,0x00000a02,0x000000ab,0x0003003e,0x00000a06,0x00000a05,0x0004003d, + 0x00000006,0x00000a07,0x00000666,0x00050041,0x00000007,0x00000a08,0x00000a02,0x000000ae, + 0x0003003e,0x00000a08,0x00000a07,0x0004003d,0x00000006,0x00000a09,0x00000666,0x00050041, + 0x00000007,0x00000a0a,0x00000a02,0x000000c1,0x0003003e,0x00000a0a,0x00000a09,0x0004003d, + 0x00000024,0x00000a0b,0x00000a02,0x0003003e,0x00000a03,0x00000a0b,0x0004003d,0x00000024, + 0x00000756,0x00000a03,0x0008000c,0x00000024,0x00000757,0x00000001,0x0000002b,0x00000754, + 0x00000755,0x00000756,0x0003003e,0x00000637,0x00000757,0x0004003d,0x00000024,0x00000758, + 0x00000637,0x0003003e,0x00000667,0x00000758,0x0004003d,0x00000024,0x00000759,0x00000647, + 0x0003003e,0x00000668,0x00000759,0x0004003d,0x00000024,0x00000a1c,0x00000668,0x0003003e, + 0x00000a0d,0x00000a1c,0x0004003d,0x00000024,0x00000a42,0x00000a0d,0x0003003e,0x00000a3d, + 0x0000014d,0x0003003e,0x00000a3e,0x0000014e,0x0003003e,0x00000a3f,0x0000014f,0x0004003d, + 0x00000006,0x00000a48,0x00000a3d,0x00050041,0x00000007,0x00000a49,0x00000a45,0x000000ab, + 0x0003003e,0x00000a49,0x00000a48,0x0004003d,0x00000006,0x00000a4a,0x00000a3e,0x00050041, + 0x00000007,0x00000a4b,0x00000a45,0x000000ae,0x0003003e,0x00000a4b,0x00000a4a,0x0004003d, + 0x00000006,0x00000a4c,0x00000a3f,0x00050041,0x00000007,0x00000a4d,0x00000a45,0x000000c1, + 0x0003003e,0x00000a4d,0x00000a4c,0x0004003d,0x00000024,0x00000a4e,0x00000a45,0x0003003e, + 0x00000a46,0x00000a4e,0x0004003d,0x00000024,0x00000a43,0x00000a46,0x00050094,0x00000006, + 0x00000a44,0x00000a42,0x00000a43,0x0003003e,0x00000a40,0x00000a44,0x0004003d,0x00000006, + 0x00000a1d,0x00000a40,0x0003003e,0x00000a0c,0x00000a1d,0x0004003d,0x00000024,0x00000a1e, + 0x00000667,0x0004003d,0x00000024,0x00000a1f,0x00000667,0x0003003e,0x00000a0f,0x00000a1f, + 0x0004003d,0x00000024,0x00000a54,0x00000a0f,0x0003003e,0x00000a4f,0x0000014d,0x0003003e, + 0x00000a50,0x0000014e,0x0003003e,0x00000a51,0x0000014f,0x0004003d,0x00000006,0x00000a5a, + 0x00000a4f,0x00050041,0x00000007,0x00000a5b,0x00000a57,0x000000ab,0x0003003e,0x00000a5b, + 0x00000a5a,0x0004003d,0x00000006,0x00000a5c,0x00000a50,0x00050041,0x00000007,0x00000a5d, + 0x00000a57,0x000000ae,0x0003003e,0x00000a5d,0x00000a5c,0x0004003d,0x00000006,0x00000a5e, + 0x00000a51,0x00050041,0x00000007,0x00000a5f,0x00000a57,0x000000c1,0x0003003e,0x00000a5f, + 0x00000a5e,0x0004003d,0x00000024,0x00000a60,0x00000a57,0x0003003e,0x00000a58,0x00000a60, + 0x0004003d,0x00000024,0x00000a55,0x00000a58,0x00050094,0x00000006,0x00000a56,0x00000a54, + 0x00000a55,0x0003003e,0x00000a52,0x00000a56,0x0004003d,0x00000006,0x00000a20,0x00000a52, + 0x00060050,0x00000024,0x00000a21,0x00000a20,0x00000a20,0x00000a20,0x00050083,0x00000024, + 0x00000a22,0x00000a1e,0x00000a21,0x0003003e,0x00000a0e,0x00000a22,0x0004003d,0x00000006, + 0x00000a23,0x00000a0c,0x00050083,0x00000006,0x00000a24,0x000000e1,0x00000a23,0x0004003d, + 0x00000006,0x00000a25,0x00000a0c,0x0003003e,0x00000a11,0x00000a25,0x0003003e,0x00000a12, + 0x00000a24,0x0004003d,0x00000006,0x00000a64,0x00000a11,0x00050041,0x00000007,0x00000a65, + 0x00000a61,0x000000ab,0x0003003e,0x00000a65,0x00000a64,0x0004003d,0x00000006,0x00000a66, + 0x00000a12,0x00050041,0x00000007,0x00000a67,0x00000a61,0x000000ae,0x0003003e,0x00000a67, + 0x00000a66,0x0004003d,0x0000000c,0x00000a68,0x00000a61,0x0003003e,0x00000a62,0x00000a68, + 0x0004003d,0x0000000c,0x00000a26,0x00000a62,0x0003003e,0x00000a13,0x00000169,0x0004003d, + 0x00000006,0x00000a6c,0x00000a13,0x00050041,0x00000007,0x00000a6d,0x00000a69,0x000000ab, + 0x0003003e,0x00000a6d,0x00000a6c,0x0004003d,0x00000006,0x00000a6e,0x00000a13,0x00050041, + 0x00000007,0x00000a6f,0x00000a69,0x000000ae,0x0003003e,0x00000a6f,0x00000a6e,0x0004003d, + 0x0000000c,0x00000a70,0x00000a69,0x0003003e,0x00000a6a,0x00000a70,0x0004003d,0x0000000c, + 0x00000a27,0x00000a6a,0x0004003d,0x00000024,0x00000a28,0x00000a0e,0x0003003e,0x00000a14, + 0x00000a28,0x0004003d,0x00000024,0x00000a74,0x00000a14,0x0007004f,0x0000000c,0x00000a75, + 0x00000a74,0x00000a74,0x00000000,0x00000001,0x0003003e,0x00000a71,0x00000a75,0x00050041, + 0x00000007,0x00000a7c,0x00000a71,0x000000ab,0x0004003d,0x00000006,0x00000a7d,0x00000a7c, + 0x00050041,0x00000007,0x00000a7e,0x00000a71,0x000000ae,0x0004003d,0x00000006,0x00000a7f, + 0x00000a7e,0x0007000c,0x00000006,0x00000a80,0x00000001,0x00000025,0x00000a7d,0x00000a7f, + 0x0003003e,0x00000a7a,0x00000a80,0x0004003d,0x00000006,0x00000a76,0x00000a7a,0x00050041, + 0x00000007,0x00000a77,0x00000a14,0x000000c1,0x0004003d,0x00000006,0x00000a78,0x00000a77, + 0x0007000c,0x00000006,0x00000a79,0x00000001,0x00000025,0x00000a76,0x00000a78,0x0003003e, + 0x00000a72,0x00000a79,0x0004003d,0x00000006,0x00000a29,0x00000a72,0x0004007f,0x00000006, + 0x00000a2a,0x00000a29,0x0004003d,0x00000024,0x00000a2b,0x00000a0e,0x0003003e,0x00000a15, + 0x00000a2b,0x0004003d,0x00000024,0x00000a84,0x00000a15,0x0007004f,0x0000000c,0x00000a85, + 0x00000a84,0x00000a84,0x00000000,0x00000001,0x0003003e,0x00000a81,0x00000a85,0x00050041, + 0x00000007,0x00000a8c,0x00000a81,0x000000ab,0x0004003d,0x00000006,0x00000a8d,0x00000a8c, + 0x00050041,0x00000007,0x00000a8e,0x00000a81,0x000000ae,0x0004003d,0x00000006,0x00000a8f, + 0x00000a8e,0x0007000c,0x00000006,0x00000a90,0x00000001,0x00000028,0x00000a8d,0x00000a8f, + 0x0003003e,0x00000a8a,0x00000a90,0x0004003d,0x00000006,0x00000a86,0x00000a8a,0x00050041, + 0x00000007,0x00000a87,0x00000a15,0x000000c1,0x0004003d,0x00000006,0x00000a88,0x00000a87, + 0x0007000c,0x00000006,0x00000a89,0x00000001,0x00000028,0x00000a86,0x00000a88,0x0003003e, + 0x00000a82,0x00000a89,0x0004003d,0x00000006,0x00000a2c,0x00000a82,0x0003003e,0x00000a16, + 0x00000a2a,0x0003003e,0x00000a17,0x00000a2c,0x0004003d,0x00000006,0x00000a94,0x00000a16, + 0x00050041,0x00000007,0x00000a95,0x00000a91,0x000000ab,0x0003003e,0x00000a95,0x00000a94, + 0x0004003d,0x00000006,0x00000a96,0x00000a17,0x00050041,0x00000007,0x00000a97,0x00000a91, + 0x000000ae,0x0003003e,0x00000a97,0x00000a96,0x0004003d,0x0000000c,0x00000a98,0x00000a91, + 0x0003003e,0x00000a92,0x00000a98,0x0004003d,0x0000000c,0x00000a2d,0x00000a92,0x0007000c, + 0x0000000c,0x00000a2e,0x00000001,0x00000028,0x00000a27,0x00000a2d,0x00050088,0x0000000c, + 0x00000a2f,0x00000a26,0x00000a2e,0x0003003e,0x00000a10,0x00000a2f,0x0003003e,0x00000a19, + 0x000000e1,0x0004003d,0x00000006,0x00000a9b,0x00000a19,0x0003003e,0x00000a99,0x00000a9b, + 0x0004003d,0x00000006,0x00000a30,0x00000a99,0x00050041,0x00000007,0x00000a31,0x00000a10, + 0x000000ab,0x0004003d,0x00000006,0x00000a32,0x00000a31,0x00050041,0x00000007,0x00000a33, + 0x00000a10,0x000000ae,0x0004003d,0x00000006,0x00000a34,0x00000a33,0x0007000c,0x00000006, + 0x00000a35,0x00000001,0x00000025,0x00000a32,0x00000a34,0x0007000c,0x00000006,0x00000a36, + 0x00000001,0x00000025,0x00000a30,0x00000a35,0x0003003e,0x00000a18,0x00000a36,0x0004003d, + 0x00000024,0x00000a37,0x00000a0e,0x0004003d,0x00000006,0x00000a38,0x00000a18,0x0005008e, + 0x00000024,0x00000a39,0x00000a37,0x00000a38,0x0004003d,0x00000006,0x00000a3a,0x00000a0c, + 0x00060050,0x00000024,0x00000a3b,0x00000a3a,0x00000a3a,0x00000a3a,0x00050081,0x00000024, + 0x00000a3c,0x00000a39,0x00000a3b,0x0003003e,0x00000a1a,0x00000a3c,0x0004003d,0x00000024, + 0x0000075a,0x00000a1a,0x0003003e,0x00000649,0x0000075a,0x000200f9,0x0000075b,0x000200f8, + 0x0000075b,0x000200f9,0x00000766,0x000200f8,0x0000075c,0x000300f7,0x00000765,0x00000000, + 0x000400fa,0x000002aa,0x0000075d,0x00000765,0x000200f8,0x0000075d,0x0004003d,0x00000024, + 0x0000075e,0x00000637,0x0003003e,0x00000669,0x000000e2,0x0004003d,0x00000006,0x00000a9f, + 0x00000669,0x00050041,0x00000007,0x00000aa0,0x00000a9c,0x000000ab,0x0003003e,0x00000aa0, + 0x00000a9f,0x0004003d,0x00000006,0x00000aa1,0x00000669,0x00050041,0x00000007,0x00000aa2, + 0x00000a9c,0x000000ae,0x0003003e,0x00000aa2,0x00000aa1,0x0004003d,0x00000006,0x00000aa3, + 0x00000669,0x00050041,0x00000007,0x00000aa4,0x00000a9c,0x000000c1,0x0003003e,0x00000aa4, + 0x00000aa3,0x0004003d,0x00000024,0x00000aa5,0x00000a9c,0x0003003e,0x00000a9d,0x00000aa5, + 0x0004003d,0x00000024,0x0000075f,0x00000a9d,0x0003003e,0x0000066a,0x000000e1,0x0004003d, + 0x00000006,0x00000aa9,0x0000066a,0x00050041,0x00000007,0x00000aaa,0x00000aa6,0x000000ab, + 0x0003003e,0x00000aaa,0x00000aa9,0x0004003d,0x00000006,0x00000aab,0x0000066a,0x00050041, + 0x00000007,0x00000aac,0x00000aa6,0x000000ae,0x0003003e,0x00000aac,0x00000aab,0x0004003d, + 0x00000006,0x00000aad,0x0000066a,0x00050041,0x00000007,0x00000aae,0x00000aa6,0x000000c1, + 0x0003003e,0x00000aae,0x00000aad,0x0004003d,0x00000024,0x00000aaf,0x00000aa6,0x0003003e, + 0x00000aa7,0x00000aaf,0x0004003d,0x00000024,0x00000760,0x00000aa7,0x0008000c,0x00000024, + 0x00000761,0x00000001,0x0000002b,0x0000075e,0x0000075f,0x00000760,0x0003003e,0x00000637, + 0x00000761,0x0004003d,0x00000024,0x00000762,0x00000647,0x0003003e,0x0000066b,0x00000762, + 0x0004003d,0x00000024,0x00000763,0x00000637,0x0003003e,0x0000066c,0x00000763,0x0004003d, + 0x00000024,0x00000ac0,0x0000066c,0x0003003e,0x00000ab1,0x00000ac0,0x0004003d,0x00000024, + 0x00000ae6,0x00000ab1,0x0003003e,0x00000ae1,0x0000014d,0x0003003e,0x00000ae2,0x0000014e, + 0x0003003e,0x00000ae3,0x0000014f,0x0004003d,0x00000006,0x00000aec,0x00000ae1,0x00050041, + 0x00000007,0x00000aed,0x00000ae9,0x000000ab,0x0003003e,0x00000aed,0x00000aec,0x0004003d, + 0x00000006,0x00000aee,0x00000ae2,0x00050041,0x00000007,0x00000aef,0x00000ae9,0x000000ae, + 0x0003003e,0x00000aef,0x00000aee,0x0004003d,0x00000006,0x00000af0,0x00000ae3,0x00050041, + 0x00000007,0x00000af1,0x00000ae9,0x000000c1,0x0003003e,0x00000af1,0x00000af0,0x0004003d, + 0x00000024,0x00000af2,0x00000ae9,0x0003003e,0x00000aea,0x00000af2,0x0004003d,0x00000024, + 0x00000ae7,0x00000aea,0x00050094,0x00000006,0x00000ae8,0x00000ae6,0x00000ae7,0x0003003e, + 0x00000ae4,0x00000ae8,0x0004003d,0x00000006,0x00000ac1,0x00000ae4,0x0003003e,0x00000ab0, + 0x00000ac1,0x0004003d,0x00000024,0x00000ac2,0x0000066b,0x0004003d,0x00000024,0x00000ac3, + 0x0000066b,0x0003003e,0x00000ab3,0x00000ac3,0x0004003d,0x00000024,0x00000af8,0x00000ab3, + 0x0003003e,0x00000af3,0x0000014d,0x0003003e,0x00000af4,0x0000014e,0x0003003e,0x00000af5, + 0x0000014f,0x0004003d,0x00000006,0x00000afe,0x00000af3,0x00050041,0x00000007,0x00000aff, + 0x00000afb,0x000000ab,0x0003003e,0x00000aff,0x00000afe,0x0004003d,0x00000006,0x00000b00, + 0x00000af4,0x00050041,0x00000007,0x00000b01,0x00000afb,0x000000ae,0x0003003e,0x00000b01, + 0x00000b00,0x0004003d,0x00000006,0x00000b02,0x00000af5,0x00050041,0x00000007,0x00000b03, + 0x00000afb,0x000000c1,0x0003003e,0x00000b03,0x00000b02,0x0004003d,0x00000024,0x00000b04, + 0x00000afb,0x0003003e,0x00000afc,0x00000b04,0x0004003d,0x00000024,0x00000af9,0x00000afc, + 0x00050094,0x00000006,0x00000afa,0x00000af8,0x00000af9,0x0003003e,0x00000af6,0x00000afa, + 0x0004003d,0x00000006,0x00000ac4,0x00000af6,0x00060050,0x00000024,0x00000ac5,0x00000ac4, + 0x00000ac4,0x00000ac4,0x00050083,0x00000024,0x00000ac6,0x00000ac2,0x00000ac5,0x0003003e, + 0x00000ab2,0x00000ac6,0x0004003d,0x00000006,0x00000ac7,0x00000ab0,0x00050083,0x00000006, + 0x00000ac8,0x000000e1,0x00000ac7,0x0004003d,0x00000006,0x00000ac9,0x00000ab0,0x0003003e, + 0x00000ab5,0x00000ac9,0x0003003e,0x00000ab6,0x00000ac8,0x0004003d,0x00000006,0x00000b08, + 0x00000ab5,0x00050041,0x00000007,0x00000b09,0x00000b05,0x000000ab,0x0003003e,0x00000b09, + 0x00000b08,0x0004003d,0x00000006,0x00000b0a,0x00000ab6,0x00050041,0x00000007,0x00000b0b, + 0x00000b05,0x000000ae,0x0003003e,0x00000b0b,0x00000b0a,0x0004003d,0x0000000c,0x00000b0c, + 0x00000b05,0x0003003e,0x00000b06,0x00000b0c,0x0004003d,0x0000000c,0x00000aca,0x00000b06, + 0x0003003e,0x00000ab7,0x00000169,0x0004003d,0x00000006,0x00000b10,0x00000ab7,0x00050041, + 0x00000007,0x00000b11,0x00000b0d,0x000000ab,0x0003003e,0x00000b11,0x00000b10,0x0004003d, + 0x00000006,0x00000b12,0x00000ab7,0x00050041,0x00000007,0x00000b13,0x00000b0d,0x000000ae, + 0x0003003e,0x00000b13,0x00000b12,0x0004003d,0x0000000c,0x00000b14,0x00000b0d,0x0003003e, + 0x00000b0e,0x00000b14,0x0004003d,0x0000000c,0x00000acb,0x00000b0e,0x0004003d,0x00000024, + 0x00000acc,0x00000ab2,0x0003003e,0x00000ab8,0x00000acc,0x0004003d,0x00000024,0x00000b18, + 0x00000ab8,0x0007004f,0x0000000c,0x00000b19,0x00000b18,0x00000b18,0x00000000,0x00000001, + 0x0003003e,0x00000b15,0x00000b19,0x00050041,0x00000007,0x00000b20,0x00000b15,0x000000ab, + 0x0004003d,0x00000006,0x00000b21,0x00000b20,0x00050041,0x00000007,0x00000b22,0x00000b15, + 0x000000ae,0x0004003d,0x00000006,0x00000b23,0x00000b22,0x0007000c,0x00000006,0x00000b24, + 0x00000001,0x00000025,0x00000b21,0x00000b23,0x0003003e,0x00000b1e,0x00000b24,0x0004003d, + 0x00000006,0x00000b1a,0x00000b1e,0x00050041,0x00000007,0x00000b1b,0x00000ab8,0x000000c1, + 0x0004003d,0x00000006,0x00000b1c,0x00000b1b,0x0007000c,0x00000006,0x00000b1d,0x00000001, + 0x00000025,0x00000b1a,0x00000b1c,0x0003003e,0x00000b16,0x00000b1d,0x0004003d,0x00000006, + 0x00000acd,0x00000b16,0x0004007f,0x00000006,0x00000ace,0x00000acd,0x0004003d,0x00000024, + 0x00000acf,0x00000ab2,0x0003003e,0x00000ab9,0x00000acf,0x0004003d,0x00000024,0x00000b28, + 0x00000ab9,0x0007004f,0x0000000c,0x00000b29,0x00000b28,0x00000b28,0x00000000,0x00000001, + 0x0003003e,0x00000b25,0x00000b29,0x00050041,0x00000007,0x00000b30,0x00000b25,0x000000ab, + 0x0004003d,0x00000006,0x00000b31,0x00000b30,0x00050041,0x00000007,0x00000b32,0x00000b25, + 0x000000ae,0x0004003d,0x00000006,0x00000b33,0x00000b32,0x0007000c,0x00000006,0x00000b34, + 0x00000001,0x00000028,0x00000b31,0x00000b33,0x0003003e,0x00000b2e,0x00000b34,0x0004003d, + 0x00000006,0x00000b2a,0x00000b2e,0x00050041,0x00000007,0x00000b2b,0x00000ab9,0x000000c1, + 0x0004003d,0x00000006,0x00000b2c,0x00000b2b,0x0007000c,0x00000006,0x00000b2d,0x00000001, + 0x00000028,0x00000b2a,0x00000b2c,0x0003003e,0x00000b26,0x00000b2d,0x0004003d,0x00000006, + 0x00000ad0,0x00000b26,0x0003003e,0x00000aba,0x00000ace,0x0003003e,0x00000abb,0x00000ad0, + 0x0004003d,0x00000006,0x00000b38,0x00000aba,0x00050041,0x00000007,0x00000b39,0x00000b35, + 0x000000ab,0x0003003e,0x00000b39,0x00000b38,0x0004003d,0x00000006,0x00000b3a,0x00000abb, + 0x00050041,0x00000007,0x00000b3b,0x00000b35,0x000000ae,0x0003003e,0x00000b3b,0x00000b3a, + 0x0004003d,0x0000000c,0x00000b3c,0x00000b35,0x0003003e,0x00000b36,0x00000b3c,0x0004003d, + 0x0000000c,0x00000ad1,0x00000b36,0x0007000c,0x0000000c,0x00000ad2,0x00000001,0x00000028, + 0x00000acb,0x00000ad1,0x00050088,0x0000000c,0x00000ad3,0x00000aca,0x00000ad2,0x0003003e, + 0x00000ab4,0x00000ad3,0x0003003e,0x00000abd,0x000000e1,0x0004003d,0x00000006,0x00000b3f, + 0x00000abd,0x0003003e,0x00000b3d,0x00000b3f,0x0004003d,0x00000006,0x00000ad4,0x00000b3d, + 0x00050041,0x00000007,0x00000ad5,0x00000ab4,0x000000ab,0x0004003d,0x00000006,0x00000ad6, + 0x00000ad5,0x00050041,0x00000007,0x00000ad7,0x00000ab4,0x000000ae,0x0004003d,0x00000006, + 0x00000ad8,0x00000ad7,0x0007000c,0x00000006,0x00000ad9,0x00000001,0x00000025,0x00000ad6, + 0x00000ad8,0x0007000c,0x00000006,0x00000ada,0x00000001,0x00000025,0x00000ad4,0x00000ad9, + 0x0003003e,0x00000abc,0x00000ada,0x0004003d,0x00000024,0x00000adb,0x00000ab2,0x0004003d, + 0x00000006,0x00000adc,0x00000abc,0x0005008e,0x00000024,0x00000add,0x00000adb,0x00000adc, + 0x0004003d,0x00000006,0x00000ade,0x00000ab0,0x00060050,0x00000024,0x00000adf,0x00000ade, + 0x00000ade,0x00000ade,0x00050081,0x00000024,0x00000ae0,0x00000add,0x00000adf,0x0003003e, + 0x00000abe,0x00000ae0,0x0004003d,0x00000024,0x00000764,0x00000abe,0x0003003e,0x00000649, + 0x00000764,0x000200f9,0x00000765,0x000200f8,0x00000765,0x000200f9,0x00000766,0x000200f8, + 0x00000766,0x0004003d,0x00000024,0x00000767,0x00000649,0x0003003e,0x0000066d,0x00000767, + 0x0004003d,0x00000024,0x00000640,0x0000066d,0x0003003e,0x00000636,0x00000640,0x0004003d, + 0x00000024,0x00000641,0x0000050e,0x0004003d,0x00000024,0x00000642,0x00000636,0x00050041, + 0x00000007,0x00000643,0x0000050f,0x000000d8,0x0004003d,0x00000006,0x00000644,0x00000643, + 0x0003003e,0x0000063a,0x00000644,0x0004003d,0x00000006,0x00000b43,0x0000063a,0x00050041, + 0x00000007,0x00000b44,0x00000b40,0x000000ab,0x0003003e,0x00000b44,0x00000b43,0x0004003d, + 0x00000006,0x00000b45,0x0000063a,0x00050041,0x00000007,0x00000b46,0x00000b40,0x000000ae, + 0x0003003e,0x00000b46,0x00000b45,0x0004003d,0x00000006,0x00000b47,0x0000063a,0x00050041, + 0x00000007,0x00000b48,0x00000b40,0x000000c1,0x0003003e,0x00000b48,0x00000b47,0x0004003d, + 0x00000024,0x00000b49,0x00000b40,0x0003003e,0x00000b41,0x00000b49,0x0004003d,0x00000024, + 0x00000645,0x00000b41,0x0008000c,0x00000024,0x00000646,0x00000001,0x0000002e,0x00000641, + 0x00000642,0x00000645,0x0003003e,0x0000063b,0x00000646,0x0004003d,0x00000024,0x000005d2, + 0x0000063b,0x00050041,0x00000007,0x000005d3,0x00000488,0x000000ab,0x00050051,0x00000006, + 0x000005d4,0x000005d2,0x00000000,0x0003003e,0x000005d3,0x000005d4,0x00050041,0x00000007, + 0x000005d5,0x00000488,0x000000ae,0x00050051,0x00000006,0x000005d6,0x000005d2,0x00000001, + 0x0003003e,0x000005d5,0x000005d6,0x00050041,0x00000007,0x000005d7,0x00000488,0x000000c1, + 0x00050051,0x00000006,0x000005d8,0x000005d2,0x00000002,0x0003003e,0x000005d7,0x000005d8, + 0x000200f9,0x000005d9,0x000200f8,0x000005d9,0x0004003d,0x00000006,0x000005db,0x000005b8, + 0x0004003d,0x0000002f,0x000005dc,0x00000488,0x0008004f,0x00000024,0x000005dd,0x000005dc, + 0x000005dc,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000024,0x000005de,0x000005dd, + 0x000005db,0x00050041,0x00000007,0x000005df,0x00000488,0x000000ab,0x00050051,0x00000006, + 0x000005e0,0x000005de,0x00000000,0x0003003e,0x000005df,0x000005e0,0x00050041,0x00000007, + 0x000005e1,0x00000488,0x000000ae,0x00050051,0x00000006,0x000005e2,0x000005de,0x00000001, + 0x0003003e,0x000005e1,0x000005e2,0x00050041,0x00000007,0x000005e3,0x00000488,0x000000c1, + 0x00050051,0x00000006,0x000005e4,0x000005de,0x00000002,0x0003003e,0x000005e3,0x000005e4, + 0x0004003d,0x0000002f,0x0000048e,0x00000488,0x0003003e,0x00000473,0x0000048e,0x0004003d, + 0x0000002f,0x0000048f,0x00000489,0x0003003e,0x00000476,0x0000048f,0x000200f9,0x0000047d, + 0x000200f8,0x0000047d,0x0004003d,0x0000002f,0x00000497,0x00000473,0x0008004f,0x00000024, + 0x00000498,0x00000497,0x00000497,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000496, + 0x00000498,0x0003003e,0x00000499,0x0000043d,0x00050041,0x0000049d,0x0000049e,0x00000493, + 0x000000ab,0x0004003d,0x00000006,0x0000049f,0x0000049e,0x0003003e,0x0000049c,0x0000049f, + 0x00050041,0x0000049d,0x000004a1,0x00000493,0x000000ae,0x0004003d,0x00000006,0x000004a2, + 0x000004a1,0x0003003e,0x000004a0,0x000004a2,0x000300f7,0x00000b5a,0x00000000,0x000400fa, + 0x00000139,0x00000b50,0x00000b58,0x000200f8,0x00000b50,0x0004003d,0x0000000c,0x00000b51, + 0x00000499,0x0003003e,0x00000b4b,0x00000b51,0x0004003d,0x00000006,0x00000b52,0x0000049c, + 0x0003003e,0x00000b4c,0x00000b52,0x0004003d,0x00000006,0x00000b53,0x000004a0,0x0003003e, + 0x00000b4d,0x00000b53,0x00050041,0x00000007,0x00000b60,0x00000b4b,0x000000ab,0x0004003d, + 0x00000006,0x00000b61,0x00000b60,0x00050085,0x00000006,0x00000b62,0x00000123,0x00000b61, + 0x00050041,0x00000007,0x00000b63,0x00000b4b,0x000000ae,0x0004003d,0x00000006,0x00000b64, + 0x00000b63,0x00050085,0x00000006,0x00000b65,0x00000127,0x00000b64,0x00050081,0x00000006, + 0x00000b66,0x00000b62,0x00000b65,0x0006000c,0x00000006,0x00000b67,0x00000001,0x0000000a, + 0x00000b66,0x0003003e,0x00000b5c,0x00000b67,0x0004003d,0x00000006,0x00000b68,0x00000b5c, + 0x00050085,0x00000006,0x00000b69,0x0000012e,0x00000b68,0x0006000c,0x00000006,0x00000b6a, + 0x00000001,0x0000000a,0x00000b69,0x0003003e,0x00000b5d,0x00000b6a,0x0004003d,0x00000006, + 0x00000b6b,0x00000b5d,0x0004003d,0x00000006,0x00000b6c,0x00000b4c,0x00050085,0x00000006, + 0x00000b6d,0x00000b6b,0x00000b6c,0x0004003d,0x00000006,0x00000b6e,0x00000b4d,0x00050081, + 0x00000006,0x00000b6f,0x00000b6d,0x00000b6e,0x0003003e,0x00000b5e,0x00000b6f,0x0004003d, + 0x00000006,0x00000b54,0x00000b5e,0x0004003d,0x00000024,0x00000b55,0x00000496,0x00060050, + 0x00000024,0x00000b56,0x00000b54,0x00000b54,0x00000b54,0x00050081,0x00000024,0x00000b57, + 0x00000b56,0x00000b55,0x0003003e,0x00000b4a,0x00000b57,0x000200f9,0x00000b5a,0x000200f8, + 0x00000b58,0x0004003d,0x00000024,0x00000b59,0x00000496,0x0003003e,0x00000b4a,0x00000b59, + 0x000200f9,0x00000b5a,0x000200f8,0x00000b5a,0x0004003d,0x00000024,0x00000b5b,0x00000b4a, + 0x0003003e,0x00000b4e,0x00000b5b,0x0004003d,0x00000024,0x000004a3,0x00000b4e,0x00050041, + 0x00000007,0x000004a4,0x00000473,0x000000ab,0x00050051,0x00000006,0x000004a5,0x000004a3, + 0x00000000,0x0003003e,0x000004a4,0x000004a5,0x00050041,0x00000007,0x000004a6,0x00000473, + 0x000000ae,0x00050051,0x00000006,0x000004a7,0x000004a3,0x00000001,0x0003003e,0x000004a6, + 0x000004a7,0x00050041,0x00000007,0x000004a8,0x00000473,0x000000c1,0x00050051,0x00000006, + 0x000004a9,0x000004a3,0x00000002,0x0003003e,0x000004a8,0x000004a9,0x0004003d,0x0000002f, + 0x000004ab,0x00000473,0x0003003e,0x000004aa,0x000004ab,0x0004003d,0x0000002f,0x00000b71, + 0x000004aa,0x0003003e,0x00000437,0x00000b71,0x0004003d,0x0000002f,0x000004b0,0x00000476, + 0x0003003e,0x000004af,0x000004b0,0x0004003d,0x0000002f,0x00000b73,0x000004af,0x0003003e, + 0x00000439,0x00000b73,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..56058dd533bd93cd21a71add047086d7cd6adf60 GIT binary patch literal 52592 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.h new file mode 100644 index 000000000..338e589ef --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.h @@ -0,0 +1,138 @@ +#pragma once + +const uint32_t atomic_draw_interior_triangles_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000012c,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000008d,0x00000090,0x00000094, + 0x00000097,0x000000a0,0x000000b8,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x0000006a,0x0000664a,0x00040006,0x0000006a,0x00000000,0x00003464, + 0x00030005,0x0000006c,0x0000424c,0x00060005,0x0000008d,0x565f6c67,0x65747265,0x646e4978, + 0x00007865,0x00070005,0x00000090,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000, + 0x00030005,0x00000094,0x0000424a,0x00030005,0x00000097,0x0000316c,0x00030005,0x000000a0, + 0x0000307a,0x00030005,0x000000a6,0x0000424d,0x00040006,0x000000a6,0x00000000,0x00006250, + 0x00040006,0x000000a6,0x00000001,0x00006359,0x00040006,0x000000a6,0x00000002,0x00006552, + 0x00040006,0x000000a6,0x00000003,0x00006553,0x00040006,0x000000a6,0x00000004,0x0000366d, + 0x00040006,0x000000a6,0x00000005,0x0000676d,0x00040006,0x000000a6,0x00000006,0x00006544, + 0x00040006,0x000000a6,0x00000007,0x00006545,0x00040006,0x000000a6,0x00000008,0x00003755, + 0x00040006,0x000000a6,0x00000009,0x0000676a,0x00040006,0x000000a6,0x0000000a,0x0000635a, + 0x00040006,0x000000a6,0x0000000b,0x00003157,0x00040006,0x000000a6,0x0000000c,0x0000676e, + 0x00040006,0x000000a6,0x0000000d,0x00003559,0x00040006,0x000000a6,0x0000000e,0x0000324f, + 0x00040006,0x000000a6,0x0000000f,0x00006461,0x00040006,0x000000a6,0x00000010,0x00006579, + 0x00040006,0x000000a6,0x00000011,0x00003376,0x00040006,0x000000a6,0x00000012,0x00003377, + 0x00040006,0x000000a6,0x00000013,0x00006462,0x00040006,0x000000a6,0x00000014,0x00006767, + 0x00030005,0x000000a8,0x0000006b,0x00060005,0x000000b6,0x505f6c67,0x65567265,0x78657472, + 0x00000000,0x00060006,0x000000b6,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006, + 0x000000b6,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x000000b6, + 0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x000000b6,0x00000003, + 0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000000b8,0x00000000,0x00030005, + 0x000000cb,0x00004342,0x00030005,0x000000ce,0x00004351,0x00030005,0x000000d0,0x00006576, + 0x00040006,0x000000d0,0x00000000,0x00003464,0x00030005,0x000000d2,0x00004355,0x00030005, + 0x000000d4,0x00006577,0x00040006,0x000000d4,0x00000000,0x00003464,0x00030005,0x000000d6, + 0x0000424f,0x00030005,0x000000d8,0x0000664b,0x00040006,0x000000d8,0x00000000,0x00003464, + 0x00030005,0x000000da,0x00004358,0x00030005,0x000000dd,0x00003954,0x00040047,0x00000069, + 0x00000006,0x00000010,0x00030047,0x0000006a,0x00000003,0x00040048,0x0000006a,0x00000000, + 0x00000018,0x00050048,0x0000006a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000006c, + 0x00000018,0x00040047,0x0000006c,0x00000021,0x00000003,0x00040047,0x0000006c,0x00000022, + 0x00000000,0x00040047,0x0000008d,0x0000000b,0x0000002a,0x00040047,0x00000090,0x0000000b, + 0x0000002b,0x00040047,0x00000094,0x0000001e,0x00000000,0x00030047,0x00000097,0x00000000, + 0x00030047,0x00000097,0x0000000e,0x00040047,0x00000097,0x0000001e,0x00000000,0x00030047, + 0x000000a0,0x00000000,0x00030047,0x000000a0,0x0000000e,0x00040047,0x000000a0,0x0000001e, + 0x00000001,0x00030047,0x000000a6,0x00000002,0x00050048,0x000000a6,0x00000000,0x00000023, + 0x00000000,0x00050048,0x000000a6,0x00000001,0x00000023,0x00000004,0x00050048,0x000000a6, + 0x00000002,0x00000023,0x00000008,0x00050048,0x000000a6,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x000000a6,0x00000004,0x00000023,0x00000010,0x00050048,0x000000a6,0x00000005, + 0x00000023,0x00000014,0x00050048,0x000000a6,0x00000006,0x00000023,0x00000018,0x00050048, + 0x000000a6,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000a6,0x00000008,0x00000023, + 0x00000020,0x00050048,0x000000a6,0x00000009,0x00000023,0x00000030,0x00050048,0x000000a6, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x000000a6,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x000000a6,0x0000000c,0x00000023,0x00000044,0x00050048,0x000000a6,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x000000a6,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x000000a6,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000a6,0x00000010,0x00000023, + 0x00000054,0x00050048,0x000000a6,0x00000011,0x00000023,0x00000058,0x00050048,0x000000a6, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x000000a6,0x00000013,0x00000023,0x00000060, + 0x00050048,0x000000a6,0x00000014,0x00000023,0x00000064,0x00040047,0x000000a8,0x00000021, + 0x00000000,0x00040047,0x000000a8,0x00000022,0x00000000,0x00030047,0x000000b6,0x00000002, + 0x00050048,0x000000b6,0x00000000,0x0000000b,0x00000000,0x00050048,0x000000b6,0x00000001, + 0x0000000b,0x00000001,0x00050048,0x000000b6,0x00000002,0x0000000b,0x00000003,0x00050048, + 0x000000b6,0x00000003,0x0000000b,0x00000004,0x00040047,0x000000cb,0x00000021,0x00000008, + 0x00040047,0x000000cb,0x00000022,0x00000000,0x00030047,0x000000ce,0x00000000,0x00040047, + 0x000000ce,0x00000021,0x0000000a,0x00040047,0x000000ce,0x00000022,0x00000000,0x00040047, + 0x000000cf,0x00000006,0x00000008,0x00030047,0x000000d0,0x00000003,0x00040048,0x000000d0, + 0x00000000,0x00000018,0x00050048,0x000000d0,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000d2,0x00000018,0x00040047,0x000000d2,0x00000021,0x00000004,0x00040047,0x000000d2, + 0x00000022,0x00000000,0x00040047,0x000000d3,0x00000006,0x00000010,0x00030047,0x000000d4, + 0x00000003,0x00040048,0x000000d4,0x00000000,0x00000018,0x00050048,0x000000d4,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000000d6,0x00000018,0x00040047,0x000000d6,0x00000021, + 0x00000005,0x00040047,0x000000d6,0x00000022,0x00000000,0x00040047,0x000000d7,0x00000006, + 0x00000010,0x00030047,0x000000d8,0x00000003,0x00040048,0x000000d8,0x00000000,0x00000018, + 0x00050048,0x000000d8,0x00000000,0x00000023,0x00000000,0x00030047,0x000000da,0x00000018, + 0x00040047,0x000000da,0x00000021,0x00000006,0x00040047,0x000000da,0x00000022,0x00000000, + 0x00030047,0x000000dd,0x00000000,0x00040047,0x000000dd,0x00000021,0x0000000a,0x00040047, + 0x000000dd,0x00000022,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00040015,0x00000006,0x00000020,0x00000001,0x00030016,0x00000008,0x00000020,0x00040015, + 0x0000000d,0x00000020,0x00000000,0x00040017,0x00000013,0x00000008,0x00000004,0x00040017, + 0x00000015,0x00000008,0x00000002,0x00040018,0x00000016,0x00000015,0x00000002,0x00040017, + 0x00000023,0x00000008,0x00000003,0x0004002b,0x00000008,0x0000003a,0x3f800000,0x0004002b, + 0x00000008,0x0000003b,0x00000000,0x0004002b,0x0000000d,0x0000004b,0x00000001,0x0004002b, + 0x0000000d,0x0000005a,0x0000ffff,0x0004002b,0x00000006,0x0000005f,0x00000010,0x00040017, + 0x00000068,0x0000000d,0x00000004,0x0003001d,0x00000069,0x00000068,0x0003001e,0x0000006a, + 0x00000069,0x00040020,0x0000006b,0x00000002,0x0000006a,0x0004003b,0x0000006b,0x0000006c, + 0x00000002,0x0004002b,0x00000006,0x0000006d,0x00000000,0x0004002b,0x0000000d,0x0000006f, + 0x00000004,0x00040020,0x00000071,0x00000002,0x00000068,0x00040017,0x0000007f,0x0000000d, + 0x00000002,0x00040020,0x0000008c,0x00000001,0x00000006,0x0004003b,0x0000008c,0x0000008d, + 0x00000001,0x0004003b,0x0000008c,0x00000090,0x00000001,0x00040020,0x00000093,0x00000001, + 0x00000023,0x0004003b,0x00000093,0x00000094,0x00000001,0x00040020,0x00000096,0x00000003, + 0x00000008,0x0004003b,0x00000096,0x00000097,0x00000003,0x00040020,0x0000009f,0x00000003, + 0x0000000d,0x0004003b,0x0000009f,0x000000a0,0x00000003,0x00040017,0x000000a5,0x00000006, + 0x00000004,0x0017001e,0x000000a6,0x00000008,0x00000008,0x00000008,0x00000008,0x0000000d, + 0x0000000d,0x0000000d,0x0000000d,0x000000a5,0x00000015,0x00000015,0x0000000d,0x00000008, + 0x0000000d,0x00000008,0x00000008,0x0000000d,0x00000008,0x00000008,0x00000008,0x0000000d, + 0x00040020,0x000000a7,0x00000002,0x000000a6,0x0004003b,0x000000a7,0x000000a8,0x00000002, + 0x0004002b,0x00000006,0x000000a9,0x00000002,0x0004002b,0x00000006,0x000000aa,0x00000003, + 0x00040020,0x000000ae,0x00000002,0x00000008,0x0004001c,0x000000b5,0x00000008,0x0000004b, + 0x0006001e,0x000000b6,0x00000013,0x00000008,0x000000b5,0x000000b5,0x00040020,0x000000b7, + 0x00000003,0x000000b6,0x0004003b,0x000000b7,0x000000b8,0x00000003,0x00040020,0x000000ba, + 0x00000003,0x00000013,0x00090019,0x000000c9,0x0000000d,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x000000ca,0x00000000,0x000000c9,0x0004003b, + 0x000000ca,0x000000cb,0x00000000,0x00090019,0x000000cc,0x00000008,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000000cd,0x00000000,0x000000cc, + 0x0004003b,0x000000cd,0x000000ce,0x00000000,0x0003001d,0x000000cf,0x0000007f,0x0003001e, + 0x000000d0,0x000000cf,0x00040020,0x000000d1,0x00000002,0x000000d0,0x0004003b,0x000000d1, + 0x000000d2,0x00000002,0x0003001d,0x000000d3,0x00000013,0x0003001e,0x000000d4,0x000000d3, + 0x00040020,0x000000d5,0x00000002,0x000000d4,0x0004003b,0x000000d5,0x000000d6,0x00000002, + 0x0003001d,0x000000d7,0x00000068,0x0003001e,0x000000d8,0x000000d7,0x00040020,0x000000d9, + 0x00000002,0x000000d8,0x0004003b,0x000000d9,0x000000da,0x00000002,0x0002001a,0x000000db, + 0x00040020,0x000000dc,0x00000000,0x000000db,0x0004003b,0x000000dc,0x000000dd,0x00000000, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d, + 0x00000023,0x00000099,0x00000094,0x00050051,0x00000008,0x000000e7,0x00000099,0x00000002, + 0x0004007c,0x0000000d,0x000000e8,0x000000e7,0x000500c7,0x0000000d,0x000000e9,0x000000e8, + 0x0000005a,0x0004007c,0x00000006,0x000000ec,0x000000e7,0x000500c3,0x00000006,0x000000ed, + 0x000000ec,0x0000005f,0x0004006f,0x00000008,0x00000109,0x000000ed,0x0007004f,0x00000015, + 0x000000f0,0x00000099,0x00000099,0x00000000,0x00000001,0x00050084,0x0000000d,0x000000f2, + 0x000000e9,0x0000006f,0x00060041,0x00000071,0x000000f3,0x0000006c,0x0000006d,0x000000f2, + 0x0004003d,0x00000068,0x000000f4,0x000000f3,0x0004007c,0x00000013,0x000000f5,0x000000f4, + 0x00050051,0x00000008,0x00000111,0x000000f5,0x00000000,0x00050051,0x00000008,0x00000112, + 0x000000f5,0x00000001,0x00050051,0x00000008,0x00000113,0x000000f5,0x00000002,0x00050051, + 0x00000008,0x00000114,0x000000f5,0x00000003,0x00050050,0x00000015,0x00000115,0x00000111, + 0x00000112,0x00050050,0x00000015,0x00000116,0x00000113,0x00000114,0x00050050,0x00000016, + 0x00000117,0x00000115,0x00000116,0x00050080,0x0000000d,0x000000f9,0x000000f2,0x0000004b, + 0x00060041,0x00000071,0x000000fa,0x0000006c,0x0000006d,0x000000f9,0x0004003d,0x00000068, + 0x000000fb,0x000000fa,0x0007004f,0x0000007f,0x000000fd,0x000000fb,0x000000fb,0x00000000, + 0x00000001,0x0004007c,0x00000015,0x000000fe,0x000000fd,0x00050091,0x00000015,0x00000101, + 0x00000117,0x000000f0,0x00050081,0x00000015,0x00000103,0x00000101,0x000000fe,0x0003003e, + 0x00000097,0x00000109,0x0003003e,0x000000a0,0x000000e9,0x00050041,0x000000ae,0x000000af, + 0x000000a8,0x000000a9,0x0004003d,0x00000008,0x000000b0,0x000000af,0x00050041,0x000000ae, + 0x000000b2,0x000000a8,0x000000aa,0x0004003d,0x00000008,0x000000b3,0x000000b2,0x00050051, + 0x00000008,0x00000120,0x00000103,0x00000000,0x00050085,0x00000008,0x00000122,0x00000120, + 0x000000b0,0x00050083,0x00000008,0x00000123,0x00000122,0x0000003a,0x00050051,0x00000008, + 0x00000125,0x00000103,0x00000001,0x00050085,0x00000008,0x00000127,0x00000125,0x000000b3, + 0x0006000c,0x00000008,0x00000129,0x00000001,0x00000006,0x000000b3,0x00050083,0x00000008, + 0x0000012a,0x00000127,0x00000129,0x00070050,0x00000013,0x0000012b,0x00000123,0x0000012a, + 0x0000003b,0x0000003a,0x00050041,0x000000ba,0x000000bb,0x000000b8,0x0000006d,0x0003003e, + 0x000000bb,0x0000012b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_interior_triangles.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..50853a1b9e4e34d1d5fd3cc2d0bc1b53ed125776 GIT binary patch literal 4272 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.h new file mode 100644 index 000000000..13d9d77f6 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.h @@ -0,0 +1,1873 @@ +#pragma once + +const uint32_t atomic_draw_path_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000d63,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000047b, + 0x00000525,0x00000527,0x00000531,0x00000563,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000161,0x0000674e, + 0x00030005,0x000002d2,0x0000674d,0x00030005,0x00000343,0x00004351,0x00030005,0x00000347, + 0x00003954,0x00030005,0x00000414,0x00006576,0x00040006,0x00000414,0x00000000,0x00003464, + 0x00030005,0x00000416,0x00004355,0x00030005,0x00000426,0x0000674b,0x00030005,0x0000043f, + 0x00006747,0x00040005,0x0000044d,0x30653742,0x00000000,0x00030005,0x00000458,0x00006748, + 0x00030005,0x00000466,0x00006577,0x00040006,0x00000466,0x00000000,0x00003464,0x00030005, + 0x00000468,0x0000424f,0x00060005,0x0000047b,0x465f6c67,0x43676172,0x64726f6f,0x00000000, + 0x00030005,0x000004e4,0x00004444,0x00030005,0x000004e6,0x00006277,0x00030005,0x000004f2, + 0x00006749,0x00040005,0x00000508,0x306a3742,0x00000000,0x00030005,0x00000525,0x0000306a, + 0x00030005,0x00000527,0x00003065,0x00030005,0x00000529,0x00000045,0x00030005,0x0000052e, + 0x0000674a,0x00030005,0x00000531,0x00000049,0x00040005,0x00000532,0x61726170,0x0000006d, + 0x00030005,0x00000538,0x00003863,0x00040005,0x00000539,0x61726170,0x0000006d,0x00040005, + 0x0000053f,0x61726170,0x0000006d,0x00040005,0x00000545,0x61726170,0x0000006d,0x00040005, + 0x00000549,0x61726170,0x0000006d,0x00040005,0x0000054e,0x61726170,0x0000006d,0x00040005, + 0x00000554,0x61726170,0x0000006d,0x00030005,0x00000557,0x00000050,0x00040005,0x00000558, + 0x61726170,0x0000006d,0x00030005,0x0000055a,0x00003171,0x00040005,0x0000055b,0x61726170, + 0x0000006d,0x00030005,0x0000055d,0x00003865,0x00040005,0x0000055e,0x61726170,0x0000006d, + 0x00030005,0x00000561,0x00006241,0x00030005,0x00000563,0x0000307a,0x00040005,0x00000564, + 0x61726170,0x0000006d,0x00030005,0x0000056b,0x00003270,0x00030005,0x0000056e,0x00003470, + 0x00030005,0x00000574,0x00003145,0x00040005,0x00000577,0x61726170,0x0000006d,0x00040005, + 0x00000579,0x61726170,0x0000006d,0x00040005,0x00000581,0x61726170,0x0000006d,0x00030005, + 0x00000596,0x0000306e,0x00040005,0x0000059a,0x61726170,0x0000006d,0x00040005,0x0000059c, + 0x61726170,0x0000006d,0x00040005,0x0000059e,0x61726170,0x0000006d,0x00040005,0x000005a0, + 0x61726170,0x0000006d,0x00040005,0x000005a1,0x61726170,0x0000006d,0x00030005,0x000005a9, + 0x0000424d,0x00040006,0x000005a9,0x00000000,0x00003376,0x00040006,0x000005a9,0x00000001, + 0x00003377,0x00030005,0x000005ab,0x0000006b,0x00040005,0x000005ae,0x61726170,0x0000006d, + 0x00040005,0x000005b1,0x61726170,0x0000006d,0x00040005,0x000005b4,0x61726170,0x0000006d, + 0x00040005,0x000005b8,0x61726170,0x0000006d,0x00040005,0x000005c2,0x61726170,0x0000006d, + 0x00040005,0x000005c7,0x61726170,0x0000006d,0x00040047,0x00000161,0x00000001,0x00000007, + 0x00040047,0x000002d2,0x00000001,0x00000006,0x00030047,0x00000343,0x00000000,0x00040047, + 0x00000343,0x00000021,0x0000000a,0x00040047,0x00000343,0x00000022,0x00000000,0x00030047, + 0x00000347,0x00000000,0x00040047,0x00000347,0x00000021,0x0000000a,0x00040047,0x00000347, + 0x00000022,0x00000000,0x00040047,0x00000413,0x00000006,0x00000008,0x00030047,0x00000414, + 0x00000003,0x00040048,0x00000414,0x00000000,0x00000018,0x00050048,0x00000414,0x00000000, + 0x00000023,0x00000000,0x00030047,0x00000416,0x00000018,0x00040047,0x00000416,0x00000021, + 0x00000004,0x00040047,0x00000416,0x00000022,0x00000000,0x00040047,0x00000426,0x00000001, + 0x00000004,0x00040047,0x0000043f,0x00000001,0x00000000,0x00030047,0x0000044d,0x00000000, + 0x00040047,0x0000044d,0x00000021,0x00000001,0x00040047,0x0000044d,0x00000022,0x00000002, + 0x00040047,0x0000044d,0x0000002b,0x00000001,0x00040047,0x00000458,0x00000001,0x00000001, + 0x00040047,0x00000465,0x00000006,0x00000010,0x00030047,0x00000466,0x00000003,0x00040048, + 0x00000466,0x00000000,0x00000018,0x00050048,0x00000466,0x00000000,0x00000023,0x00000000, + 0x00030047,0x00000468,0x00000018,0x00040047,0x00000468,0x00000021,0x00000005,0x00040047, + 0x00000468,0x00000022,0x00000000,0x00040047,0x0000047b,0x0000000b,0x0000000f,0x00030047, + 0x000004e4,0x00000000,0x00040047,0x000004e4,0x00000021,0x00000009,0x00040047,0x000004e4, + 0x00000022,0x00000000,0x00030047,0x000004e6,0x00000000,0x00040047,0x000004e6,0x00000021, + 0x00000009,0x00040047,0x000004e6,0x00000022,0x00000000,0x00040047,0x000004f2,0x00000001, + 0x00000002,0x00030047,0x00000508,0x00000000,0x00040047,0x00000508,0x00000021,0x00000000, + 0x00040047,0x00000508,0x00000022,0x00000002,0x00040047,0x00000508,0x0000002b,0x00000000, + 0x00030047,0x00000525,0x00000000,0x00040047,0x00000525,0x0000001e,0x00000000,0x00030047, + 0x00000527,0x00000000,0x00040047,0x00000527,0x0000001e,0x00000001,0x00040047,0x0000052e, + 0x00000001,0x00000003,0x00040047,0x00000531,0x0000001e,0x00000000,0x00030047,0x00000538, + 0x00000000,0x00030047,0x00000549,0x00000000,0x00030047,0x0000054e,0x00000000,0x00030047, + 0x00000552,0x00000000,0x00030047,0x00000553,0x00000000,0x00030047,0x00000554,0x00000000, + 0x00030047,0x00000556,0x00000000,0x00030047,0x00000557,0x00000000,0x00030047,0x00000558, + 0x00000000,0x00030047,0x0000055a,0x00000000,0x00030047,0x0000055b,0x00000000,0x00030047, + 0x0000055f,0x00000000,0x00030047,0x00000563,0x00000000,0x00030047,0x00000563,0x0000000e, + 0x00040047,0x00000563,0x0000001e,0x00000001,0x00030047,0x00000564,0x00000000,0x00030047, + 0x00000565,0x00000000,0x00030047,0x0000056e,0x00000017,0x00040047,0x0000056e,0x00000021, + 0x00000003,0x00040047,0x0000056e,0x00000022,0x00000002,0x00030047,0x00000574,0x00000000, + 0x00030047,0x00000579,0x00000000,0x00030047,0x0000057a,0x00000000,0x00030047,0x0000057c, + 0x00000000,0x00030047,0x00000596,0x00000000,0x00030047,0x0000059d,0x00000000,0x00030047, + 0x0000059e,0x00000000,0x00030047,0x0000059f,0x00000000,0x00030047,0x000005a0,0x00000000, + 0x00030047,0x000005a1,0x00000000,0x00030047,0x000005a2,0x00000000,0x00030047,0x000005a9, + 0x00000002,0x00050048,0x000005a9,0x00000000,0x00000023,0x00000058,0x00050048,0x000005a9, + 0x00000001,0x00000023,0x0000005c,0x00040047,0x000005ab,0x00000021,0x00000000,0x00040047, + 0x000005ab,0x00000022,0x00000000,0x00030047,0x000005ae,0x00000000,0x00030047,0x000005af, + 0x00000000,0x00030047,0x000005b0,0x00000000,0x00030047,0x000005b4,0x00000000,0x00030047, + 0x000005b8,0x00000000,0x00030047,0x000005c2,0x00000000,0x00030047,0x000005c3,0x00000000, + 0x00030047,0x000005c7,0x00000000,0x00030047,0x000005c8,0x00000000,0x00030047,0x000005df, + 0x00000000,0x00030047,0x000005e0,0x00000000,0x00030047,0x000005e5,0x00000000,0x00030047, + 0x000005e6,0x00000000,0x00030047,0x000005f1,0x00000000,0x00030047,0x000005f2,0x00000000, + 0x00030047,0x000005fb,0x00000000,0x00030047,0x00000601,0x00000000,0x00030047,0x00000602, + 0x00000000,0x00030047,0x00000603,0x00000000,0x00030047,0x00000604,0x00000000,0x00030047, + 0x00000605,0x00000000,0x00030047,0x00000606,0x00000000,0x00030047,0x00000607,0x00000000, + 0x00030047,0x00000608,0x00000000,0x00030047,0x00000609,0x00000000,0x00030047,0x0000060a, + 0x00000000,0x00030047,0x0000060b,0x00000000,0x00030047,0x0000060c,0x00000000,0x00030047, + 0x0000060d,0x00000000,0x00030047,0x0000060e,0x00000000,0x00030047,0x0000060f,0x00000000, + 0x00030047,0x00000610,0x00000000,0x00030047,0x00000611,0x00000000,0x00030047,0x00000612, + 0x00000000,0x00030047,0x00000613,0x00000000,0x00030047,0x00000614,0x00000000,0x00030047, + 0x00000615,0x00000000,0x00030047,0x00000616,0x00000000,0x00030047,0x0000061d,0x00000000, + 0x00030047,0x00000620,0x00000000,0x00030047,0x00000621,0x00000000,0x00030047,0x00000623, + 0x00000000,0x00030047,0x00000624,0x00000000,0x00030047,0x00000625,0x00000000,0x00030047, + 0x00000626,0x00000000,0x00030047,0x00000629,0x00000000,0x00030047,0x0000062a,0x00000000, + 0x00030047,0x0000062b,0x00000000,0x00030047,0x00000636,0x00000000,0x00030047,0x00000637, + 0x00000000,0x00030047,0x00000638,0x00000000,0x00030047,0x00000639,0x00000000,0x00030047, + 0x0000063a,0x00000000,0x00030047,0x0000063b,0x00000000,0x00030047,0x0000063d,0x00000000, + 0x00030047,0x0000063e,0x00000000,0x00030047,0x0000063f,0x00000000,0x00030047,0x00000640, + 0x00000000,0x00030047,0x00000641,0x00000000,0x00030047,0x00000642,0x00000000,0x00030047, + 0x00000643,0x00000000,0x00030047,0x00000644,0x00000000,0x00030047,0x00000645,0x00000000, + 0x00030047,0x00000646,0x00000000,0x00030047,0x00000647,0x00000000,0x00030047,0x00000648, + 0x00000000,0x00030047,0x00000649,0x00000000,0x00030047,0x0000064a,0x00000000,0x00030047, + 0x0000064b,0x00000000,0x00030047,0x0000064c,0x00000000,0x00030047,0x0000064f,0x00000000, + 0x00030047,0x00000650,0x00000000,0x00030047,0x00000652,0x00000000,0x00030047,0x00000653, + 0x00000000,0x00030047,0x00000656,0x00000000,0x00030047,0x00000657,0x00000000,0x00030047, + 0x00000659,0x00000000,0x00030047,0x0000065a,0x00000000,0x00030047,0x0000065d,0x00000000, + 0x00030047,0x0000065e,0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000661, + 0x00000000,0x00030047,0x00000664,0x00000000,0x00030047,0x00000665,0x00000000,0x00030047, + 0x0000066c,0x00000000,0x00030047,0x0000066d,0x00000000,0x00030047,0x0000066e,0x00000000, + 0x00030047,0x0000066f,0x00000000,0x00030047,0x00000670,0x00000000,0x00030047,0x00000671, + 0x00000000,0x00030047,0x00000672,0x00000000,0x00030047,0x00000673,0x00000000,0x00030047, + 0x00000674,0x00000000,0x00030047,0x00000675,0x00000000,0x00030047,0x00000676,0x00000000, + 0x00030047,0x00000677,0x00000000,0x00030047,0x00000678,0x00000000,0x00030047,0x00000679, + 0x00000000,0x00030047,0x0000067a,0x00000000,0x00030047,0x0000067c,0x00000000,0x00030047, + 0x00000681,0x00000000,0x00030047,0x00000682,0x00000000,0x00030047,0x00000683,0x00000000, + 0x00030047,0x00000685,0x00000000,0x00030047,0x00000687,0x00000000,0x00030047,0x00000689, + 0x00000000,0x00030047,0x0000068b,0x00000000,0x00030047,0x0000068d,0x00000000,0x00030047, + 0x0000068e,0x00000000,0x00030047,0x0000068f,0x00000000,0x00030047,0x00000691,0x00000000, + 0x00030047,0x00000693,0x00000000,0x00030047,0x00000695,0x00000000,0x00030047,0x00000697, + 0x00000000,0x00030047,0x00000699,0x00000000,0x00030047,0x0000069a,0x00000000,0x00030047, + 0x0000069c,0x00000000,0x00030047,0x0000069d,0x00000000,0x00030047,0x0000069f,0x00000000, + 0x00030047,0x000006a0,0x00000000,0x00030047,0x000006a2,0x00000000,0x00030047,0x000006a3, + 0x00000000,0x00030047,0x000006a4,0x00000000,0x00030047,0x000006a6,0x00000000,0x00030047, + 0x000006a8,0x00000000,0x00030047,0x000006aa,0x00000000,0x00030047,0x000006ac,0x00000000, + 0x00030047,0x000006ae,0x00000000,0x00030047,0x000006af,0x00000000,0x00030047,0x000006b0, + 0x00000000,0x00030047,0x000006b2,0x00000000,0x00030047,0x000006b4,0x00000000,0x00030047, + 0x000006b6,0x00000000,0x00030047,0x000006b8,0x00000000,0x00030047,0x000006ba,0x00000000, + 0x00030047,0x000006c5,0x00000000,0x00030047,0x000006c7,0x00000000,0x00030047,0x000006c8, + 0x00000000,0x00030047,0x000006cb,0x00000000,0x00030047,0x000006cc,0x00000000,0x00030047, + 0x000006ce,0x00000000,0x00030047,0x000006d5,0x00000000,0x00030047,0x000006dc,0x00000000, + 0x00030047,0x000006dd,0x00000000,0x00030047,0x000006e0,0x00000000,0x00030047,0x000006e2, + 0x00000000,0x00030047,0x000006e3,0x00000000,0x00030047,0x000006e4,0x00000000,0x00030047, + 0x000006e7,0x00000000,0x00030047,0x000006e8,0x00000000,0x00030047,0x000006ed,0x00000000, + 0x00030047,0x000006ef,0x00000000,0x00030047,0x000006f1,0x00000000,0x00030047,0x000006fa, + 0x00000000,0x00030047,0x000006fc,0x00000000,0x00030047,0x000006fd,0x00000000,0x00030047, + 0x000006fe,0x00000000,0x00030047,0x000006ff,0x00000000,0x00030047,0x00000704,0x00000000, + 0x00030047,0x0000070a,0x00000000,0x00030047,0x0000070b,0x00000000,0x00030047,0x00000714, + 0x00000000,0x00030047,0x00000715,0x00000000,0x00030047,0x00000716,0x00000000,0x00030047, + 0x00000717,0x00000000,0x00030047,0x00000718,0x00000000,0x00030047,0x00000719,0x00000000, + 0x00030047,0x0000071a,0x00000000,0x00030047,0x0000071d,0x00000000,0x00030047,0x00000720, + 0x00000000,0x00030047,0x00000728,0x00000000,0x00030047,0x00000729,0x00000000,0x00030047, + 0x0000072b,0x00000000,0x00030047,0x00000754,0x00000000,0x00030047,0x00000756,0x00000000, + 0x00030047,0x00000757,0x00000000,0x00030047,0x00000758,0x00000000,0x00030047,0x00000759, + 0x00000000,0x00030047,0x0000075a,0x00000000,0x00030047,0x0000075b,0x00000000,0x00030047, + 0x0000075c,0x00000000,0x00030047,0x0000076b,0x00000000,0x00030047,0x00000771,0x00000000, + 0x00030047,0x0000079e,0x00000000,0x00030047,0x0000079f,0x00000000,0x00030047,0x000007a4, + 0x00000000,0x00030047,0x000007a6,0x00000000,0x00030047,0x000007a8,0x00000000,0x00030047, + 0x000007a9,0x00000000,0x00030047,0x000007ad,0x00000000,0x00030047,0x000007bb,0x00000000, + 0x00030047,0x000007bc,0x00000000,0x00030047,0x000007bd,0x00000000,0x00030047,0x000007be, + 0x00000000,0x00030047,0x000007bf,0x00000000,0x00030047,0x000007c0,0x00000000,0x00030047, + 0x000007ca,0x00000000,0x00030047,0x000007cb,0x00000000,0x00030047,0x000007cc,0x00000000, + 0x00030047,0x000007cd,0x00000000,0x00030047,0x000007d4,0x00000000,0x00030047,0x000007d6, + 0x00000000,0x00030047,0x000007d7,0x00000000,0x00030047,0x000007d9,0x00000000,0x00030047, + 0x000007da,0x00000000,0x00030047,0x000007dc,0x00000000,0x00030047,0x000007dd,0x00000000, + 0x00030047,0x000007e7,0x00000000,0x00030047,0x000007e9,0x00000000,0x00030047,0x000007ea, + 0x00000000,0x00030047,0x000007ed,0x00000000,0x00030047,0x000007ee,0x00000000,0x00030047, + 0x000007f0,0x00000000,0x00030047,0x000007f2,0x00000000,0x00030047,0x000007f4,0x00000000, + 0x00030047,0x00000802,0x00000000,0x00030047,0x00000803,0x00000000,0x00030047,0x00000806, + 0x00000000,0x00030047,0x00000807,0x00000000,0x00030047,0x00000808,0x00000000,0x00030047, + 0x0000080a,0x00000000,0x00030047,0x0000080c,0x00000000,0x00030047,0x0000080e,0x00000000, + 0x00030047,0x00000810,0x00000000,0x00030047,0x00000812,0x00000000,0x00030047,0x00000820, + 0x00000000,0x00030047,0x00000821,0x00000000,0x00030047,0x00000824,0x00000000,0x00030047, + 0x00000825,0x00000000,0x00030047,0x00000826,0x00000000,0x00030047,0x00000827,0x00000000, + 0x00030047,0x00000828,0x00000000,0x00030047,0x00000829,0x00000000,0x00030047,0x0000082a, + 0x00000000,0x00030047,0x0000082c,0x00000000,0x00030047,0x0000082d,0x00000000,0x00030047, + 0x0000082e,0x00000000,0x00030047,0x00000830,0x00000000,0x00030047,0x00000831,0x00000000, + 0x00030047,0x00000833,0x00000000,0x00030047,0x00000835,0x00000000,0x00030047,0x00000836, + 0x00000000,0x00030047,0x00000837,0x00000000,0x00030047,0x00000838,0x00000000,0x00030047, + 0x00000839,0x00000000,0x00030047,0x0000083a,0x00000000,0x00030047,0x0000083b,0x00000000, + 0x00030047,0x0000083c,0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x0000083e, + 0x00000000,0x00030047,0x0000083f,0x00000000,0x00030047,0x00000840,0x00000000,0x00030047, + 0x00000841,0x00000000,0x00030047,0x00000842,0x00000000,0x00030047,0x00000843,0x00000000, + 0x00030047,0x00000844,0x00000000,0x00030047,0x00000845,0x00000000,0x00030047,0x00000846, + 0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000848,0x00000000,0x00030047, + 0x0000084a,0x00000000,0x00030047,0x0000084b,0x00000000,0x00030047,0x0000084c,0x00000000, + 0x00030047,0x0000084d,0x00000000,0x00030047,0x0000084e,0x00000000,0x00030047,0x0000084f, + 0x00000000,0x00030047,0x00000850,0x00000000,0x00030047,0x00000851,0x00000000,0x00030047, + 0x00000852,0x00000000,0x00030047,0x00000853,0x00000000,0x00030047,0x00000854,0x00000000, + 0x00030047,0x00000855,0x00000000,0x00030047,0x00000856,0x00000000,0x00030047,0x00000857, + 0x00000000,0x00030047,0x00000858,0x00000000,0x00030047,0x00000859,0x00000000,0x00030047, + 0x0000085a,0x00000000,0x00030047,0x0000085b,0x00000000,0x00030047,0x0000085c,0x00000000, + 0x00030047,0x0000085e,0x00000000,0x00030047,0x00000860,0x00000000,0x00030047,0x00000862, + 0x00000000,0x00030047,0x00000863,0x00000000,0x00030047,0x00000864,0x00000000,0x00030047, + 0x00000866,0x00000000,0x00030047,0x00000867,0x00000000,0x00030047,0x00000868,0x00000000, + 0x00030047,0x00000869,0x00000000,0x00030047,0x0000086a,0x00000000,0x00030047,0x0000086b, + 0x00000000,0x00030047,0x0000086c,0x00000000,0x00030047,0x0000086e,0x00000000,0x00030047, + 0x0000086f,0x00000000,0x00030047,0x00000870,0x00000000,0x00030047,0x00000871,0x00000000, + 0x00030047,0x00000872,0x00000000,0x00030047,0x00000873,0x00000000,0x00030047,0x00000874, + 0x00000000,0x00030047,0x00000875,0x00000000,0x00030047,0x00000876,0x00000000,0x00030047, + 0x00000877,0x00000000,0x00030047,0x00000878,0x00000000,0x00030047,0x0000087a,0x00000000, + 0x00030047,0x0000087b,0x00000000,0x00030047,0x0000087c,0x00000000,0x00030047,0x0000087e, + 0x00000000,0x00030047,0x0000087f,0x00000000,0x00030047,0x00000880,0x00000000,0x00030047, + 0x00000882,0x00000000,0x00030047,0x00000883,0x00000000,0x00030047,0x00000884,0x00000000, + 0x00030047,0x00000886,0x00000000,0x00030047,0x00000887,0x00000000,0x00030047,0x00000889, + 0x00000000,0x00030047,0x0000088a,0x00000000,0x00030047,0x0000088b,0x00000000,0x00030047, + 0x00000892,0x00000000,0x00030047,0x00000893,0x00000000,0x00030047,0x00000896,0x00000000, + 0x00030047,0x00000898,0x00000000,0x00030047,0x00000899,0x00000000,0x00030047,0x0000089b, + 0x00000000,0x00030047,0x0000089c,0x00000000,0x00030047,0x0000089d,0x00000000,0x00030047, + 0x0000089e,0x00000000,0x00030047,0x0000089f,0x00000000,0x00030047,0x000008a0,0x00000000, + 0x00030047,0x000008a1,0x00000000,0x00030047,0x000008a2,0x00000000,0x00030047,0x000008a3, + 0x00000000,0x00030047,0x000008a5,0x00000000,0x00030047,0x000008a6,0x00000000,0x00030047, + 0x000008a8,0x00000000,0x00030047,0x000008ab,0x00000000,0x00030047,0x000008ac,0x00000000, + 0x00030047,0x000008ad,0x00000000,0x00030047,0x000008af,0x00000000,0x00030047,0x000008b0, + 0x00000000,0x00030047,0x000008b1,0x00000000,0x00030047,0x000008b9,0x00000000,0x00030047, + 0x000008bf,0x00000000,0x00030047,0x000008c0,0x00000000,0x00030047,0x000008c1,0x00000000, + 0x00030047,0x000008c2,0x00000000,0x00030047,0x000008c3,0x00000000,0x00030047,0x000008c5, + 0x00000000,0x00030047,0x000008c6,0x00000000,0x00030047,0x000008c8,0x00000000,0x00030047, + 0x000008c9,0x00000000,0x00030047,0x000008ca,0x00000000,0x00030047,0x000008cb,0x00000000, + 0x00030047,0x000008cc,0x00000000,0x00030047,0x000008cd,0x00000000,0x00030047,0x000008ce, + 0x00000000,0x00030047,0x000008d0,0x00000000,0x00030047,0x000008d1,0x00000000,0x00030047, + 0x000008d2,0x00000000,0x00030047,0x000008d4,0x00000000,0x00030047,0x000008d5,0x00000000, + 0x00030047,0x000008d6,0x00000000,0x00030047,0x000008d7,0x00000000,0x00030047,0x000008d8, + 0x00000000,0x00030047,0x000008d9,0x00000000,0x00030047,0x000008da,0x00000000,0x00030047, + 0x000008db,0x00000000,0x00030047,0x000008dc,0x00000000,0x00030047,0x000008dd,0x00000000, + 0x00030047,0x000008de,0x00000000,0x00030047,0x000008e0,0x00000000,0x00030047,0x000008e1, + 0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008eb,0x00000000,0x00030047, + 0x000008f1,0x00000000,0x00030047,0x000008f2,0x00000000,0x00030047,0x000008f7,0x00000000, + 0x00030047,0x000008fd,0x00000000,0x00030047,0x000008fe,0x00000000,0x00030047,0x000008ff, + 0x00000000,0x00030047,0x00000902,0x00000000,0x00030047,0x00000903,0x00000000,0x00030047, + 0x00000904,0x00000000,0x00030047,0x0000090a,0x00000000,0x00030047,0x0000090b,0x00000000, + 0x00030047,0x0000090c,0x00000000,0x00030047,0x00000914,0x00000000,0x00030047,0x00000915, + 0x00000000,0x00030047,0x00000916,0x00000000,0x00030047,0x00000917,0x00000000,0x00030047, + 0x00000918,0x00000000,0x00030047,0x00000919,0x00000000,0x00030047,0x0000091a,0x00000000, + 0x00030047,0x0000091b,0x00000000,0x00030047,0x0000091c,0x00000000,0x00030047,0x0000091e, + 0x00000000,0x00030047,0x0000091f,0x00000000,0x00030047,0x00000920,0x00000000,0x00030047, + 0x00000921,0x00000000,0x00030047,0x00000923,0x00000000,0x00030047,0x00000924,0x00000000, + 0x00030047,0x00000925,0x00000000,0x00030047,0x00000926,0x00000000,0x00030047,0x00000927, + 0x00000000,0x00030047,0x00000928,0x00000000,0x00030047,0x00000929,0x00000000,0x00030047, + 0x0000092a,0x00000000,0x00030047,0x0000092d,0x00000000,0x00030047,0x00000930,0x00000000, + 0x00030047,0x00000931,0x00000000,0x00030047,0x00000932,0x00000000,0x00030047,0x00000933, + 0x00000000,0x00030047,0x00000938,0x00000000,0x00030047,0x0000093b,0x00000000,0x00030047, + 0x0000093c,0x00000000,0x00030047,0x0000093d,0x00000000,0x00030047,0x0000093e,0x00000000, + 0x00030047,0x00000943,0x00000000,0x00030047,0x00000946,0x00000000,0x00030047,0x00000947, + 0x00000000,0x00030047,0x00000948,0x00000000,0x00030047,0x0000094d,0x00000000,0x00030047, + 0x00000950,0x00000000,0x00030047,0x00000951,0x00000000,0x00030047,0x00000952,0x00000000, + 0x00030047,0x00000956,0x00000000,0x00030047,0x00000957,0x00000000,0x00030047,0x00000958, + 0x00000000,0x00030047,0x0000095a,0x00000000,0x00030047,0x0000095b,0x00000000,0x00030047, + 0x0000095d,0x00000000,0x00030047,0x00000961,0x00000000,0x00030047,0x00000962,0x00000000, + 0x00030047,0x00000965,0x00000000,0x00030047,0x00000966,0x00000000,0x00030047,0x00000967, + 0x00000000,0x00030047,0x00000968,0x00000000,0x00030047,0x0000096a,0x00000000,0x00030047, + 0x0000096c,0x00000000,0x00030047,0x0000096e,0x00000000,0x00030047,0x00000970,0x00000000, + 0x00030047,0x00000971,0x00000000,0x00030047,0x00000972,0x00000000,0x00030047,0x00000974, + 0x00000000,0x00030047,0x00000976,0x00000000,0x00030047,0x00000978,0x00000000,0x00030047, + 0x0000097a,0x00000000,0x00030047,0x0000097b,0x00000000,0x00030047,0x0000097c,0x00000000, + 0x00030047,0x0000097e,0x00000000,0x00030047,0x00000980,0x00000000,0x00030047,0x00000982, + 0x00000000,0x00030047,0x00000984,0x00000000,0x00030047,0x00000985,0x00000000,0x00030047, + 0x00000986,0x00000000,0x00030047,0x00000988,0x00000000,0x00030047,0x0000098a,0x00000000, + 0x00030047,0x0000098c,0x00000000,0x00030047,0x0000098e,0x00000000,0x00030047,0x0000098f, + 0x00000000,0x00030047,0x00000990,0x00000000,0x00030047,0x00000992,0x00000000,0x00030047, + 0x00000994,0x00000000,0x00030047,0x00000996,0x00000000,0x00030047,0x00000998,0x00000000, + 0x00030047,0x00000999,0x00000000,0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099c, + 0x00000000,0x00030047,0x0000099e,0x00000000,0x00030047,0x000009a0,0x00000000,0x00030047, + 0x000009a2,0x00000000,0x00030047,0x000009a3,0x00000000,0x00030047,0x000009a4,0x00000000, + 0x00030047,0x000009a6,0x00000000,0x00030047,0x000009a8,0x00000000,0x00030047,0x000009aa, + 0x00000000,0x00030047,0x000009ac,0x00000000,0x00030047,0x000009ad,0x00000000,0x00030047, + 0x000009ae,0x00000000,0x00030047,0x000009b0,0x00000000,0x00030047,0x000009b2,0x00000000, + 0x00030047,0x000009b4,0x00000000,0x00030047,0x000009b6,0x00000000,0x00030047,0x000009b7, + 0x00000000,0x00030047,0x000009b8,0x00000000,0x00030047,0x000009ba,0x00000000,0x00030047, + 0x000009bc,0x00000000,0x00030047,0x000009be,0x00000000,0x00030047,0x000009c0,0x00000000, + 0x00030047,0x000009c1,0x00000000,0x00030047,0x000009c2,0x00000000,0x00030047,0x000009c4, + 0x00000000,0x00030047,0x000009c6,0x00000000,0x00030047,0x000009c8,0x00000000,0x00030047, + 0x000009ca,0x00000000,0x00030047,0x000009cb,0x00000000,0x00030047,0x000009cc,0x00000000, + 0x00030047,0x000009ce,0x00000000,0x00030047,0x000009d0,0x00000000,0x00030047,0x000009d2, + 0x00000000,0x00030047,0x000009d4,0x00000000,0x00030047,0x000009d5,0x00000000,0x00030047, + 0x000009d6,0x00000000,0x00030047,0x000009d8,0x00000000,0x00030047,0x000009da,0x00000000, + 0x00030047,0x000009dc,0x00000000,0x00030047,0x000009de,0x00000000,0x00030047,0x000009df, + 0x00000000,0x00030047,0x000009e0,0x00000000,0x00030047,0x000009e2,0x00000000,0x00030047, + 0x000009e4,0x00000000,0x00030047,0x000009e6,0x00000000,0x00030047,0x000009e8,0x00000000, + 0x00030047,0x000009e9,0x00000000,0x00030047,0x000009ea,0x00000000,0x00030047,0x000009ec, + 0x00000000,0x00030047,0x000009ee,0x00000000,0x00030047,0x000009f0,0x00000000,0x00030047, + 0x000009f2,0x00000000,0x00030047,0x000009f4,0x00000000,0x00030047,0x000009f5,0x00000000, + 0x00030047,0x000009f6,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047,0x000009fa, + 0x00000000,0x00030047,0x000009fb,0x00000000,0x00030047,0x000009fc,0x00000000,0x00030047, + 0x000009fe,0x00000000,0x00030047,0x00000a00,0x00000000,0x00030047,0x00000a02,0x00000000, + 0x00030047,0x00000a03,0x00000000,0x00030047,0x00000a05,0x00000000,0x00030047,0x00000a06, + 0x00000000,0x00030047,0x00000a07,0x00000000,0x00030047,0x00000a08,0x00000000,0x00030047, + 0x00000a0e,0x00000000,0x00030047,0x00000a11,0x00000000,0x00030047,0x00000a13,0x00000000, + 0x00030047,0x00000a14,0x00000000,0x00030047,0x00000a16,0x00000000,0x00030047,0x00000a17, + 0x00000000,0x00030047,0x00000a1a,0x00000000,0x00030047,0x00000a1b,0x00000000,0x00030047, + 0x00000a1c,0x00000000,0x00030047,0x00000a1f,0x00000000,0x00030047,0x00000a21,0x00000000, + 0x00030047,0x00000a22,0x00000000,0x00030047,0x00000a23,0x00000000,0x00030047,0x00000a24, + 0x00000000,0x00030047,0x00000a26,0x00000000,0x00030047,0x00000a27,0x00000000,0x00030047, + 0x00000a2a,0x00000000,0x00030047,0x00000a2b,0x00000000,0x00030047,0x00000a2c,0x00000000, + 0x00030047,0x00000a2f,0x00000000,0x00030047,0x00000a31,0x00000000,0x00030047,0x00000a32, + 0x00000000,0x00030047,0x00000a33,0x00000000,0x00030047,0x00000a34,0x00000000,0x00030047, + 0x00000a36,0x00000000,0x00030047,0x00000a37,0x00000000,0x00030047,0x00000a3a,0x00000000, + 0x00030047,0x00000a3b,0x00000000,0x00030047,0x00000a3c,0x00000000,0x00030047,0x00000a3f, + 0x00000000,0x00030047,0x00000a41,0x00000000,0x00030047,0x00000a42,0x00000000,0x00030047, + 0x00000a43,0x00000000,0x00030047,0x00000a44,0x00000000,0x00030047,0x00000a46,0x00000000, + 0x00030047,0x00000a47,0x00000000,0x00030047,0x00000a4a,0x00000000,0x00030047,0x00000a4b, + 0x00000000,0x00030047,0x00000a4c,0x00000000,0x00030047,0x00000a4f,0x00000000,0x00030047, + 0x00000a51,0x00000000,0x00030047,0x00000a52,0x00000000,0x00030047,0x00000a53,0x00000000, + 0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a55,0x00000000,0x00030047,0x00000a56, + 0x00000000,0x00030047,0x00000a57,0x00000000,0x00030047,0x00000a58,0x00000000,0x00030047, + 0x00000a59,0x00000000,0x00030047,0x00000a5a,0x00000000,0x00030047,0x00000a5b,0x00000000, + 0x00030047,0x00000a5c,0x00000000,0x00030047,0x00000a5d,0x00000000,0x00030047,0x00000a5e, + 0x00000000,0x00030047,0x00000a5f,0x00000000,0x00030047,0x00000a60,0x00000000,0x00030047, + 0x00000a61,0x00000000,0x00030047,0x00000a63,0x00000000,0x00030047,0x00000a65,0x00000000, + 0x00030047,0x00000a66,0x00000000,0x00030047,0x00000a68,0x00000000,0x00030047,0x00000a69, + 0x00000000,0x00030047,0x00000a6a,0x00000000,0x00030047,0x00000a6b,0x00000000,0x00030047, + 0x00000a6c,0x00000000,0x00030047,0x00000a6f,0x00000000,0x00030047,0x00000a71,0x00000000, + 0x00030047,0x00000a72,0x00000000,0x00030047,0x00000a75,0x00000000,0x00030047,0x00000a76, + 0x00000000,0x00030047,0x00000a79,0x00000000,0x00030047,0x00000a7b,0x00000000,0x00030047, + 0x00000a7c,0x00000000,0x00030047,0x00000a7d,0x00000000,0x00030047,0x00000a7e,0x00000000, + 0x00030047,0x00000a7f,0x00000000,0x00030047,0x00000a80,0x00000000,0x00030047,0x00000a81, + 0x00000000,0x00030047,0x00000a82,0x00000000,0x00030047,0x00000a83,0x00000000,0x00030047, + 0x00000a84,0x00000000,0x00030047,0x00000a85,0x00000000,0x00030047,0x00000a86,0x00000000, + 0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a89,0x00000000,0x00030047,0x00000a8b, + 0x00000000,0x00030047,0x00000a8c,0x00000000,0x00030047,0x00000a8d,0x00000000,0x00030047, + 0x00000a8f,0x00000000,0x00030047,0x00000a91,0x00000000,0x00030047,0x00000a93,0x00000000, + 0x00030047,0x00000a95,0x00000000,0x00030047,0x00000a96,0x00000000,0x00030047,0x00000a97, + 0x00000000,0x00030047,0x00000a98,0x00000000,0x00030047,0x00000a99,0x00000000,0x00030047, + 0x00000a9b,0x00000000,0x00030047,0x00000a9d,0x00000000,0x00030047,0x00000a9e,0x00000000, + 0x00030047,0x00000a9f,0x00000000,0x00030047,0x00000aa1,0x00000000,0x00030047,0x00000aa3, + 0x00000000,0x00030047,0x00000aa5,0x00000000,0x00030047,0x00000aa7,0x00000000,0x00030047, + 0x00000aa8,0x00000000,0x00030047,0x00000aa9,0x00000000,0x00030047,0x00000aab,0x00000000, + 0x00030047,0x00000aad,0x00000000,0x00030047,0x00000aaf,0x00000000,0x00030047,0x00000ab0, + 0x00000000,0x00030047,0x00000ab1,0x00000000,0x00030047,0x00000ab3,0x00000000,0x00030047, + 0x00000ab5,0x00000000,0x00030047,0x00000ab7,0x00000000,0x00030047,0x00000ab8,0x00000000, + 0x00030047,0x00000ab9,0x00000000,0x00030047,0x00000abb,0x00000000,0x00030047,0x00000abc, + 0x00000000,0x00030047,0x00000abf,0x00000000,0x00030047,0x00000ac0,0x00000000,0x00030047, + 0x00000ac1,0x00000000,0x00030047,0x00000ac4,0x00000000,0x00030047,0x00000ac6,0x00000000, + 0x00030047,0x00000ac7,0x00000000,0x00030047,0x00000ac8,0x00000000,0x00030047,0x00000ac9, + 0x00000000,0x00030047,0x00000acb,0x00000000,0x00030047,0x00000acc,0x00000000,0x00030047, + 0x00000acf,0x00000000,0x00030047,0x00000ad0,0x00000000,0x00030047,0x00000ad1,0x00000000, + 0x00030047,0x00000ad4,0x00000000,0x00030047,0x00000ad6,0x00000000,0x00030047,0x00000ad7, + 0x00000000,0x00030047,0x00000ad8,0x00000000,0x00030047,0x00000ad9,0x00000000,0x00030047, + 0x00000adb,0x00000000,0x00030047,0x00000add,0x00000000,0x00030047,0x00000adf,0x00000000, + 0x00030047,0x00000ae0,0x00000000,0x00030047,0x00000ae2,0x00000000,0x00030047,0x00000ae3, + 0x00000000,0x00030047,0x00000ae4,0x00000000,0x00030047,0x00000ae6,0x00000000,0x00030047, + 0x00000ae8,0x00000000,0x00030047,0x00000aea,0x00000000,0x00030047,0x00000aec,0x00000000, + 0x00030047,0x00000aed,0x00000000,0x00030047,0x00000aee,0x00000000,0x00030047,0x00000af0, + 0x00000000,0x00030047,0x00000af2,0x00000000,0x00030047,0x00000af4,0x00000000,0x00030047, + 0x00000af6,0x00000000,0x00030047,0x00000af8,0x00000000,0x00030047,0x00000af9,0x00000000, + 0x00030047,0x00000afa,0x00000000,0x00030047,0x00000afc,0x00000000,0x00030047,0x00000afe, + 0x00000000,0x00030047,0x00000aff,0x00000000,0x00030047,0x00000b00,0x00000000,0x00030047, + 0x00000b02,0x00000000,0x00030047,0x00000b04,0x00000000,0x00030047,0x00000b06,0x00000000, + 0x00030047,0x00000b07,0x00000000,0x00030047,0x00000b09,0x00000000,0x00030047,0x00000b0a, + 0x00000000,0x00030047,0x00000b0b,0x00000000,0x00030047,0x00000b0c,0x00000000,0x00030047, + 0x00000b12,0x00000000,0x00030047,0x00000b15,0x00000000,0x00030047,0x00000b17,0x00000000, + 0x00030047,0x00000b18,0x00000000,0x00030047,0x00000b1a,0x00000000,0x00030047,0x00000b1b, + 0x00000000,0x00030047,0x00000b1e,0x00000000,0x00030047,0x00000b1f,0x00000000,0x00030047, + 0x00000b20,0x00000000,0x00030047,0x00000b23,0x00000000,0x00030047,0x00000b25,0x00000000, + 0x00030047,0x00000b26,0x00000000,0x00030047,0x00000b27,0x00000000,0x00030047,0x00000b28, + 0x00000000,0x00030047,0x00000b2a,0x00000000,0x00030047,0x00000b2b,0x00000000,0x00030047, + 0x00000b2e,0x00000000,0x00030047,0x00000b2f,0x00000000,0x00030047,0x00000b30,0x00000000, + 0x00030047,0x00000b33,0x00000000,0x00030047,0x00000b35,0x00000000,0x00030047,0x00000b36, + 0x00000000,0x00030047,0x00000b37,0x00000000,0x00030047,0x00000b38,0x00000000,0x00030047, + 0x00000b3a,0x00000000,0x00030047,0x00000b3b,0x00000000,0x00030047,0x00000b3e,0x00000000, + 0x00030047,0x00000b3f,0x00000000,0x00030047,0x00000b40,0x00000000,0x00030047,0x00000b43, + 0x00000000,0x00030047,0x00000b45,0x00000000,0x00030047,0x00000b46,0x00000000,0x00030047, + 0x00000b47,0x00000000,0x00030047,0x00000b48,0x00000000,0x00030047,0x00000b4a,0x00000000, + 0x00030047,0x00000b4b,0x00000000,0x00030047,0x00000b4e,0x00000000,0x00030047,0x00000b4f, + 0x00000000,0x00030047,0x00000b50,0x00000000,0x00030047,0x00000b53,0x00000000,0x00030047, + 0x00000b55,0x00000000,0x00030047,0x00000b56,0x00000000,0x00030047,0x00000b57,0x00000000, + 0x00030047,0x00000b58,0x00000000,0x00030047,0x00000b59,0x00000000,0x00030047,0x00000b5a, + 0x00000000,0x00030047,0x00000b5b,0x00000000,0x00030047,0x00000b5c,0x00000000,0x00030047, + 0x00000b5d,0x00000000,0x00030047,0x00000b5e,0x00000000,0x00030047,0x00000b5f,0x00000000, + 0x00030047,0x00000b60,0x00000000,0x00030047,0x00000b61,0x00000000,0x00030047,0x00000b62, + 0x00000000,0x00030047,0x00000b63,0x00000000,0x00030047,0x00000b64,0x00000000,0x00030047, + 0x00000b65,0x00000000,0x00030047,0x00000b67,0x00000000,0x00030047,0x00000b69,0x00000000, + 0x00030047,0x00000b6a,0x00000000,0x00030047,0x00000b6c,0x00000000,0x00030047,0x00000b6d, + 0x00000000,0x00030047,0x00000b6e,0x00000000,0x00030047,0x00000b6f,0x00000000,0x00030047, + 0x00000b70,0x00000000,0x00030047,0x00000b73,0x00000000,0x00030047,0x00000b75,0x00000000, + 0x00030047,0x00000b76,0x00000000,0x00030047,0x00000b79,0x00000000,0x00030047,0x00000b7a, + 0x00000000,0x00030047,0x00000b7d,0x00000000,0x00030047,0x00000b7f,0x00000000,0x00030047, + 0x00000b80,0x00000000,0x00030047,0x00000b81,0x00000000,0x00030047,0x00000b82,0x00000000, + 0x00030047,0x00000b83,0x00000000,0x00030047,0x00000b84,0x00000000,0x00030047,0x00000b85, + 0x00000000,0x00030047,0x00000b86,0x00000000,0x00030047,0x00000b87,0x00000000,0x00030047, + 0x00000b88,0x00000000,0x00030047,0x00000b89,0x00000000,0x00030047,0x00000b8a,0x00000000, + 0x00030047,0x00000b8b,0x00000000,0x00030047,0x00000b8d,0x00000000,0x00030047,0x00000b8f, + 0x00000000,0x00030047,0x00000b90,0x00000000,0x00030047,0x00000b91,0x00000000,0x00030047, + 0x00000b93,0x00000000,0x00030047,0x00000b95,0x00000000,0x00030047,0x00000b97,0x00000000, + 0x00030047,0x00000b99,0x00000000,0x00030047,0x00000b9a,0x00000000,0x00030047,0x00000b9b, + 0x00000000,0x00030047,0x00000b9c,0x00000000,0x00030047,0x00000b9d,0x00000000,0x00030047, + 0x00000b9f,0x00000000,0x00030047,0x00000ba1,0x00000000,0x00030047,0x00000ba2,0x00000000, + 0x00030047,0x00000ba3,0x00000000,0x00030047,0x00000ba5,0x00000000,0x00030047,0x00000ba7, + 0x00000000,0x00030047,0x00000ba9,0x00000000,0x00030047,0x00000bab,0x00000000,0x00030047, + 0x00000bac,0x00000000,0x00030047,0x00000bad,0x00000000,0x00030047,0x00000baf,0x00000000, + 0x00030047,0x00000bb1,0x00000000,0x00030047,0x00000bb3,0x00000000,0x00030047,0x00000bb4, + 0x00000000,0x00030047,0x00000bb5,0x00000000,0x00030047,0x00000bb7,0x00000000,0x00030047, + 0x00000bb9,0x00000000,0x00030047,0x00000bbb,0x00000000,0x00030047,0x00000bbc,0x00000000, + 0x00030047,0x00000bbd,0x00000000,0x00030047,0x00000bbf,0x00000000,0x00030047,0x00000bc0, + 0x00000000,0x00030047,0x00000bc3,0x00000000,0x00030047,0x00000bc4,0x00000000,0x00030047, + 0x00000bc5,0x00000000,0x00030047,0x00000bc8,0x00000000,0x00030047,0x00000bca,0x00000000, + 0x00030047,0x00000bcb,0x00000000,0x00030047,0x00000bcc,0x00000000,0x00030047,0x00000bcd, + 0x00000000,0x00030047,0x00000bcf,0x00000000,0x00030047,0x00000bd0,0x00000000,0x00030047, + 0x00000bd3,0x00000000,0x00030047,0x00000bd4,0x00000000,0x00030047,0x00000bd5,0x00000000, + 0x00030047,0x00000bd8,0x00000000,0x00030047,0x00000bda,0x00000000,0x00030047,0x00000bdb, + 0x00000000,0x00030047,0x00000bdc,0x00000000,0x00030047,0x00000bdd,0x00000000,0x00030047, + 0x00000bdf,0x00000000,0x00030047,0x00000be1,0x00000000,0x00030047,0x00000be3,0x00000000, + 0x00030047,0x00000be4,0x00000000,0x00030047,0x00000be6,0x00000000,0x00030047,0x00000be7, + 0x00000000,0x00030047,0x00000be8,0x00000000,0x00030047,0x00000bea,0x00000000,0x00030047, + 0x00000bec,0x00000000,0x00030047,0x00000bee,0x00000000,0x00030047,0x00000bf0,0x00000000, + 0x00030047,0x00000bf1,0x00000000,0x00030047,0x00000bf2,0x00000000,0x00030047,0x00000bf4, + 0x00000000,0x00030047,0x00000bf6,0x00000000,0x00030047,0x00000bf8,0x00000000,0x00030047, + 0x00000bfa,0x00000000,0x00030047,0x00000bfb,0x00000000,0x00030047,0x00000bfc,0x00000000, + 0x00030047,0x00000bfd,0x00000000,0x00030047,0x00000bfe,0x00000000,0x00030047,0x00000bff, + 0x00000000,0x00030047,0x00000c00,0x00000000,0x00030047,0x00000c01,0x00000000,0x00030047, + 0x00000c02,0x00000000,0x00030047,0x00000c03,0x00000000,0x00030047,0x00000c04,0x00000000, + 0x00030047,0x00000c05,0x00000000,0x00030047,0x00000c06,0x00000000,0x00030047,0x00000c07, + 0x00000000,0x00030047,0x00000c08,0x00000000,0x00030047,0x00000c09,0x00000000,0x00030047, + 0x00000c0b,0x00000000,0x00030047,0x00000c0d,0x00000000,0x00030047,0x00000c0e,0x00000000, + 0x00030047,0x00000c10,0x00000000,0x00030047,0x00000c11,0x00000000,0x00030047,0x00000c12, + 0x00000000,0x00030047,0x00000c13,0x00000000,0x00030047,0x00000c14,0x00000000,0x00030047, + 0x00000c17,0x00000000,0x00030047,0x00000c19,0x00000000,0x00030047,0x00000c1a,0x00000000, + 0x00030047,0x00000c1d,0x00000000,0x00030047,0x00000c1e,0x00000000,0x00030047,0x00000c21, + 0x00000000,0x00030047,0x00000c23,0x00000000,0x00030047,0x00000c24,0x00000000,0x00030047, + 0x00000c25,0x00000000,0x00030047,0x00000c26,0x00000000,0x00030047,0x00000c27,0x00000000, + 0x00030047,0x00000c28,0x00000000,0x00030047,0x00000c29,0x00000000,0x00030047,0x00000c2a, + 0x00000000,0x00030047,0x00000c2b,0x00000000,0x00030047,0x00000c2c,0x00000000,0x00030047, + 0x00000c2d,0x00000000,0x00030047,0x00000c2e,0x00000000,0x00030047,0x00000c2f,0x00000000, + 0x00030047,0x00000c31,0x00000000,0x00030047,0x00000c33,0x00000000,0x00030047,0x00000c34, + 0x00000000,0x00030047,0x00000c35,0x00000000,0x00030047,0x00000c37,0x00000000,0x00030047, + 0x00000c39,0x00000000,0x00030047,0x00000c3b,0x00000000,0x00030047,0x00000c3d,0x00000000, + 0x00030047,0x00000c3e,0x00000000,0x00030047,0x00000c3f,0x00000000,0x00030047,0x00000c40, + 0x00000000,0x00030047,0x00000c41,0x00000000,0x00030047,0x00000c43,0x00000000,0x00030047, + 0x00000c45,0x00000000,0x00030047,0x00000c46,0x00000000,0x00030047,0x00000c47,0x00000000, + 0x00030047,0x00000c49,0x00000000,0x00030047,0x00000c4b,0x00000000,0x00030047,0x00000c4d, + 0x00000000,0x00030047,0x00000c4f,0x00000000,0x00030047,0x00000c50,0x00000000,0x00030047, + 0x00000c51,0x00000000,0x00030047,0x00000c53,0x00000000,0x00030047,0x00000c55,0x00000000, + 0x00030047,0x00000c57,0x00000000,0x00030047,0x00000c58,0x00000000,0x00030047,0x00000c59, + 0x00000000,0x00030047,0x00000c5b,0x00000000,0x00030047,0x00000c5d,0x00000000,0x00030047, + 0x00000c5f,0x00000000,0x00030047,0x00000c60,0x00000000,0x00030047,0x00000c61,0x00000000, + 0x00030047,0x00000c63,0x00000000,0x00030047,0x00000c64,0x00000000,0x00030047,0x00000c67, + 0x00000000,0x00030047,0x00000c68,0x00000000,0x00030047,0x00000c69,0x00000000,0x00030047, + 0x00000c6c,0x00000000,0x00030047,0x00000c6e,0x00000000,0x00030047,0x00000c6f,0x00000000, + 0x00030047,0x00000c70,0x00000000,0x00030047,0x00000c71,0x00000000,0x00030047,0x00000c73, + 0x00000000,0x00030047,0x00000c74,0x00000000,0x00030047,0x00000c77,0x00000000,0x00030047, + 0x00000c78,0x00000000,0x00030047,0x00000c79,0x00000000,0x00030047,0x00000c7c,0x00000000, + 0x00030047,0x00000c7e,0x00000000,0x00030047,0x00000c7f,0x00000000,0x00030047,0x00000c80, + 0x00000000,0x00030047,0x00000c81,0x00000000,0x00030047,0x00000c83,0x00000000,0x00030047, + 0x00000c85,0x00000000,0x00030047,0x00000c87,0x00000000,0x00030047,0x00000c88,0x00000000, + 0x00030047,0x00000c8a,0x00000000,0x00030047,0x00000c8b,0x00000000,0x00030047,0x00000c8c, + 0x00000000,0x00030047,0x00000c8e,0x00000000,0x00030047,0x00000c90,0x00000000,0x00030047, + 0x00000c92,0x00000000,0x00030047,0x00000c94,0x00000000,0x00030047,0x00000c95,0x00000000, + 0x00030047,0x00000c96,0x00000000,0x00030047,0x00000c98,0x00000000,0x00030047,0x00000c9a, + 0x00000000,0x00030047,0x00000c9c,0x00000000,0x00030047,0x00000c9e,0x00000000,0x00030047, + 0x00000c9f,0x00000000,0x00030047,0x00000ca0,0x00000000,0x00030047,0x00000ca1,0x00000000, + 0x00030047,0x00000ca2,0x00000000,0x00030047,0x00000ca3,0x00000000,0x00030047,0x00000ca4, + 0x00000000,0x00030047,0x00000ca5,0x00000000,0x00030047,0x00000ca6,0x00000000,0x00030047, + 0x00000ca7,0x00000000,0x00030047,0x00000ca8,0x00000000,0x00030047,0x00000ca9,0x00000000, + 0x00030047,0x00000caa,0x00000000,0x00030047,0x00000cab,0x00000000,0x00030047,0x00000cac, + 0x00000000,0x00030047,0x00000cad,0x00000000,0x00030047,0x00000caf,0x00000000,0x00030047, + 0x00000cb1,0x00000000,0x00030047,0x00000cb2,0x00000000,0x00030047,0x00000cb4,0x00000000, + 0x00030047,0x00000cb5,0x00000000,0x00030047,0x00000cb6,0x00000000,0x00030047,0x00000cb7, + 0x00000000,0x00030047,0x00000cb8,0x00000000,0x00030047,0x00000cbb,0x00000000,0x00030047, + 0x00000cbd,0x00000000,0x00030047,0x00000cbe,0x00000000,0x00030047,0x00000cc1,0x00000000, + 0x00030047,0x00000cc2,0x00000000,0x00030047,0x00000cc5,0x00000000,0x00030047,0x00000cc7, + 0x00000000,0x00030047,0x00000cc8,0x00000000,0x00030047,0x00000cc9,0x00000000,0x00030047, + 0x00000cca,0x00000000,0x00030047,0x00000ccb,0x00000000,0x00030047,0x00000ccc,0x00000000, + 0x00030047,0x00000ccd,0x00000000,0x00030047,0x00000cce,0x00000000,0x00030047,0x00000ccf, + 0x00000000,0x00030047,0x00000cd0,0x00000000,0x00030047,0x00000cd1,0x00000000,0x00030047, + 0x00000cd2,0x00000000,0x00030047,0x00000cd3,0x00000000,0x00030047,0x00000cd5,0x00000000, + 0x00030047,0x00000cd7,0x00000000,0x00030047,0x00000cd8,0x00000000,0x00030047,0x00000cd9, + 0x00000000,0x00030047,0x00000cdb,0x00000000,0x00030047,0x00000cdd,0x00000000,0x00030047, + 0x00000cdf,0x00000000,0x00030047,0x00000ce1,0x00000000,0x00030047,0x00000ce2,0x00000000, + 0x00030047,0x00000ce3,0x00000000,0x00030047,0x00000ce4,0x00000000,0x00030047,0x00000ce5, + 0x00000000,0x00030047,0x00000ce7,0x00000000,0x00030047,0x00000ce9,0x00000000,0x00030047, + 0x00000cea,0x00000000,0x00030047,0x00000ceb,0x00000000,0x00030047,0x00000ced,0x00000000, + 0x00030047,0x00000cef,0x00000000,0x00030047,0x00000cf1,0x00000000,0x00030047,0x00000cf3, + 0x00000000,0x00030047,0x00000cf4,0x00000000,0x00030047,0x00000cf5,0x00000000,0x00030047, + 0x00000cf7,0x00000000,0x00030047,0x00000cf9,0x00000000,0x00030047,0x00000cfb,0x00000000, + 0x00030047,0x00000cfc,0x00000000,0x00030047,0x00000cfd,0x00000000,0x00030047,0x00000cff, + 0x00000000,0x00030047,0x00000d01,0x00000000,0x00030047,0x00000d03,0x00000000,0x00030047, + 0x00000d04,0x00000000,0x00030047,0x00000d05,0x00000000,0x00030047,0x00000d07,0x00000000, + 0x00030047,0x00000d08,0x00000000,0x00030047,0x00000d0b,0x00000000,0x00030047,0x00000d0c, + 0x00000000,0x00030047,0x00000d0d,0x00000000,0x00030047,0x00000d10,0x00000000,0x00030047, + 0x00000d12,0x00000000,0x00030047,0x00000d13,0x00000000,0x00030047,0x00000d14,0x00000000, + 0x00030047,0x00000d15,0x00000000,0x00030047,0x00000d17,0x00000000,0x00030047,0x00000d18, + 0x00000000,0x00030047,0x00000d1b,0x00000000,0x00030047,0x00000d1c,0x00000000,0x00030047, + 0x00000d1d,0x00000000,0x00030047,0x00000d20,0x00000000,0x00030047,0x00000d22,0x00000000, + 0x00030047,0x00000d23,0x00000000,0x00030047,0x00000d24,0x00000000,0x00030047,0x00000d25, + 0x00000000,0x00030047,0x00000d27,0x00000000,0x00030047,0x00000d29,0x00000000,0x00030047, + 0x00000d2b,0x00000000,0x00030047,0x00000d2c,0x00000000,0x00030047,0x00000d2e,0x00000000, + 0x00030047,0x00000d2f,0x00000000,0x00030047,0x00000d30,0x00000000,0x00030047,0x00000d32, + 0x00000000,0x00030047,0x00000d34,0x00000000,0x00030047,0x00000d36,0x00000000,0x00030047, + 0x00000d38,0x00000000,0x00030047,0x00000d39,0x00000000,0x00030047,0x00000d3b,0x00000000, + 0x00030047,0x00000d3c,0x00000000,0x00030047,0x00000d3d,0x00000000,0x00030047,0x00000d41, + 0x00000000,0x00030047,0x00000d42,0x00000000,0x00030047,0x00000d44,0x00000000,0x00030047, + 0x00000d45,0x00000000,0x00030047,0x00000d46,0x00000000,0x00030047,0x00000d48,0x00000000, + 0x00030047,0x00000d4a,0x00000000,0x00030047,0x00000d4b,0x00000000,0x00030047,0x00000d4c, + 0x00000000,0x00030047,0x00000d4d,0x00000000,0x00030047,0x00000d57,0x00000000,0x00030047, + 0x00000d58,0x00000000,0x00030047,0x00000d59,0x00000000,0x00030047,0x00000d5a,0x00000000, + 0x00030047,0x00000d5b,0x00000000,0x00030047,0x00000d5c,0x00000000,0x00030047,0x00000d5d, + 0x00000000,0x00030047,0x00000d5e,0x00000000,0x00030047,0x00000d60,0x00000000,0x00030047, + 0x00000d62,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017,0x0000000c, + 0x00000006,0x00000002,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040015,0x00000012, + 0x00000020,0x00000000,0x00040020,0x00000013,0x00000007,0x00000012,0x00040017,0x00000024, + 0x00000006,0x00000003,0x00040017,0x0000002f,0x00000006,0x00000004,0x00040020,0x0000003b, + 0x00000007,0x0000002f,0x00040018,0x0000003c,0x0000000c,0x00000002,0x00040020,0x0000004c, + 0x00000007,0x00000024,0x00020014,0x0000007d,0x00040015,0x000000a0,0x00000020,0x00000001, + 0x00040017,0x000000a1,0x000000a0,0x00000002,0x00040020,0x000000a2,0x00000007,0x000000a1, + 0x0004002b,0x00000012,0x000000c8,0x00000000,0x0004002b,0x00000012,0x000000cb,0x00000001, + 0x0004002b,0x00000012,0x000000de,0x00000002,0x0004002b,0x00000012,0x000000f5,0x00000003, + 0x0004002b,0x00000006,0x0000010a,0x3f800000,0x0004002b,0x00000006,0x0000010b,0x00000000, + 0x0004002b,0x00000006,0x0000014b,0x3d897143,0x0004002b,0x00000006,0x0000014f,0x3bbf4590, + 0x0004002b,0x00000006,0x00000156,0x4253ee82,0x00030030,0x0000007d,0x00000161,0x0004002b, + 0x00000006,0x00000175,0x3e99999a,0x0004002b,0x00000006,0x00000176,0x3f170a3d,0x0004002b, + 0x00000006,0x00000177,0x3de147ae,0x0004002b,0x00000006,0x00000191,0x388205ff,0x0004002b, + 0x00000006,0x000001f7,0x40000000,0x0004002b,0x00000006,0x000001fe,0x3f000000,0x00040017, + 0x00000204,0x0000007d,0x00000003,0x00040020,0x00000280,0x00000007,0x000000a0,0x0004002b, + 0x000000a0,0x00000282,0x00000000,0x0004002b,0x000000a0,0x00000289,0x00000003,0x0004002b, + 0x00000006,0x0000029b,0x3e800000,0x0004002b,0x00000006,0x000002a0,0x41800000,0x0004002b, + 0x00000006,0x000002a5,0x41400000,0x0004002b,0x00000006,0x000002ab,0x40400000,0x0004002b, + 0x000000a0,0x000002b7,0x00000001,0x00030030,0x0000007d,0x000002d2,0x0004002b,0x00000006, + 0x0000032b,0xbfc00000,0x00090019,0x00000341,0x00000006,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x00000342,0x00000000,0x00000341,0x0004003b, + 0x00000342,0x00000343,0x00000000,0x0002001a,0x00000345,0x00040020,0x00000346,0x00000000, + 0x00000345,0x0004003b,0x00000346,0x00000347,0x00000000,0x0003001b,0x00000349,0x00000341, + 0x0004002b,0x00000006,0x00000353,0x447a0000,0x0004002b,0x00000006,0x00000360,0xc0000000, + 0x0004002b,0x00000006,0x00000366,0x3f19319f,0x0004002b,0x00000006,0x0000036b,0x3e55e621, + 0x0004002b,0x00000006,0x0000036c,0x3f206c99,0x0004002b,0x00000006,0x0000036d,0x3f85afd5, + 0x0004002b,0x00000006,0x0000036e,0x3fbb295d,0x0004002b,0x00000006,0x000003ab,0x40a311dd, + 0x0004002b,0x00000006,0x000003ad,0xc02311dd,0x0004002b,0x00000006,0x000003e7,0x45000000, + 0x0004002b,0x00000006,0x000003e9,0x47800000,0x0004002b,0x00000006,0x000003f1,0x3a000000, + 0x0004002b,0x00000006,0x000003f3,0xc2000000,0x0004002b,0x00000006,0x00000403,0x3a808081, + 0x00040017,0x00000406,0x0000007d,0x00000002,0x00040017,0x00000410,0x00000012,0x00000002, + 0x00040020,0x00000411,0x00000007,0x00000410,0x0003001d,0x00000413,0x00000410,0x0003001e, + 0x00000414,0x00000413,0x00040020,0x00000415,0x00000002,0x00000414,0x0004003b,0x00000415, + 0x00000416,0x00000002,0x00040020,0x00000418,0x00000002,0x00000410,0x0004002b,0x00000012, + 0x0000041f,0x00000300,0x00030030,0x0000007d,0x00000426,0x0004002b,0x00000012,0x0000042b, + 0x00000200,0x0004002b,0x00000006,0x00000435,0xbf800000,0x00030030,0x0000007d,0x0000043f, + 0x0004002b,0x00000012,0x00000445,0x00000010,0x00090019,0x0000044b,0x00000006,0x00000006, + 0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020,0x0000044c,0x00000000, + 0x0000044b,0x0004003b,0x0000044c,0x0000044d,0x00000000,0x0005002c,0x000000a1,0x0000044f, + 0x00000282,0x00000282,0x00030030,0x0000007d,0x00000458,0x0004002b,0x00000012,0x0000045d, + 0x00000400,0x00040020,0x00000463,0x00000007,0x0000003c,0x0003001d,0x00000465,0x0000002f, + 0x0003001e,0x00000466,0x00000465,0x00040020,0x00000467,0x00000002,0x00000466,0x0004003b, + 0x00000467,0x00000468,0x00000002,0x0004002b,0x00000012,0x0000046a,0x00000004,0x00040020, + 0x0000046e,0x00000002,0x0000002f,0x00040020,0x0000047a,0x00000001,0x0000002f,0x0004003b, + 0x0000047a,0x0000047b,0x00000001,0x0004002b,0x00000012,0x0000049b,0x0000000f,0x0004003b, + 0x00000342,0x000004e4,0x00000000,0x0004003b,0x00000346,0x000004e6,0x00000000,0x00030030, + 0x0000007d,0x000004f2,0x0004002b,0x000000a0,0x000004fe,0x00000004,0x0004003b,0x0000044c, + 0x00000508,0x00000000,0x00040020,0x00000524,0x00000003,0x0000002f,0x0004003b,0x00000524, + 0x00000525,0x00000003,0x0004003b,0x00000524,0x00000527,0x00000003,0x00030030,0x0000007d, + 0x0000052e,0x0004003b,0x0000047a,0x00000531,0x00000001,0x00040020,0x0000054a,0x00000001, + 0x00000006,0x00040020,0x00000562,0x00000001,0x00000012,0x0004003b,0x00000562,0x00000563, + 0x00000001,0x0004002b,0x00000012,0x00000567,0x00000011,0x00090019,0x0000056c,0x00000012, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x0000056d, + 0x00000000,0x0000056c,0x0004003b,0x0000056d,0x0000056e,0x00000000,0x00040020,0x00000571, + 0x0000000b,0x00000012,0x0004002b,0x00000012,0x0000058e,0x00010000,0x0004002b,0x00000012, + 0x00000598,0x0001ffff,0x0004001e,0x000005a9,0x00000006,0x00000006,0x00040020,0x000005aa, + 0x00000002,0x000005a9,0x0004003b,0x000005aa,0x000005ab,0x00000002,0x00040020,0x000005b5, + 0x00000002,0x00000006,0x0006002c,0x00000024,0x000005d3,0x0000010a,0x0000010a,0x0000010a, + 0x0006002c,0x00000024,0x000005d4,0x000001fe,0x000001fe,0x000001fe,0x0007002c,0x0000002f, + 0x000005d5,0x000003ad,0x000003ad,0x000003ad,0x000003ad,0x00040020,0x000005d6,0x00000007, + 0x0000007d,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003b,0x00000007,0x00000d4b,0x00000007,0x0004003b,0x00000007,0x00000d4c,0x00000007, + 0x0004003b,0x00000007,0x00000d4d,0x00000007,0x0004003b,0x0000004c,0x00000d39,0x00000007, + 0x0004003b,0x0000000d,0x00000d3a,0x00000007,0x0004003b,0x00000007,0x00000d3b,0x00000007, + 0x0004003b,0x00000007,0x00000d3c,0x00000007,0x0004003b,0x0000004c,0x00000d3d,0x00000007, + 0x0004003b,0x0000004c,0x00000d2f,0x00000007,0x0004003b,0x0000004c,0x00000d30,0x00000007, + 0x0004003b,0x00000007,0x00000d2c,0x00000007,0x0004003b,0x0000000d,0x00000d24,0x00000007, + 0x0004003b,0x0000000d,0x00000d25,0x00000007,0x0004003b,0x00000007,0x00000d1d,0x00000007, + 0x0004003b,0x0000000d,0x00000d14,0x00000007,0x0004003b,0x00000007,0x00000d15,0x00000007, + 0x0004003b,0x00000007,0x00000d0d,0x00000007,0x0004003b,0x0000000d,0x00000d04,0x00000007, + 0x0004003b,0x00000007,0x00000d05,0x00000007,0x0004003b,0x0000000d,0x00000cfc,0x00000007, + 0x0004003b,0x0000000d,0x00000cfd,0x00000007,0x0004003b,0x0000000d,0x00000cf4,0x00000007, + 0x0004003b,0x0000000d,0x00000cf5,0x00000007,0x0004003b,0x0000004c,0x00000cea,0x00000007, + 0x0004003b,0x0000004c,0x00000ceb,0x00000007,0x0004003b,0x00000007,0x00000ce2,0x00000007, + 0x0004003b,0x00000007,0x00000ce3,0x00000007,0x0004003b,0x00000007,0x00000ce4,0x00000007, + 0x0004003b,0x00000007,0x00000ce5,0x00000007,0x0004003b,0x0000004c,0x00000cd8,0x00000007, + 0x0004003b,0x0000004c,0x00000cd9,0x00000007,0x0004003b,0x00000007,0x00000cd0,0x00000007, + 0x0004003b,0x00000007,0x00000cd1,0x00000007,0x0004003b,0x00000007,0x00000cd2,0x00000007, + 0x0004003b,0x00000007,0x00000cd3,0x00000007,0x0004003b,0x00000007,0x00000c9f,0x00000007, + 0x0004003b,0x0000004c,0x00000ca0,0x00000007,0x0004003b,0x0000004c,0x00000ca1,0x00000007, + 0x0004003b,0x0000004c,0x00000ca2,0x00000007,0x0004003b,0x0000000d,0x00000ca3,0x00000007, + 0x0004003b,0x00000007,0x00000ca4,0x00000007,0x0004003b,0x00000007,0x00000ca5,0x00000007, + 0x0004003b,0x00000007,0x00000ca6,0x00000007,0x0004003b,0x0000004c,0x00000ca7,0x00000007, + 0x0004003b,0x0000004c,0x00000ca8,0x00000007,0x0004003b,0x00000007,0x00000ca9,0x00000007, + 0x0004003b,0x00000007,0x00000caa,0x00000007,0x0004003b,0x00000007,0x00000cab,0x00000007, + 0x0004003b,0x00000007,0x00000cac,0x00000007,0x0004003b,0x0000004c,0x00000cad,0x00000007, + 0x0004003b,0x0000004c,0x00000c95,0x00000007,0x0004003b,0x0000004c,0x00000c96,0x00000007, + 0x0004003b,0x0000004c,0x00000c8b,0x00000007,0x0004003b,0x0000004c,0x00000c8c,0x00000007, + 0x0004003b,0x00000007,0x00000c88,0x00000007,0x0004003b,0x0000000d,0x00000c80,0x00000007, + 0x0004003b,0x0000000d,0x00000c81,0x00000007,0x0004003b,0x00000007,0x00000c79,0x00000007, + 0x0004003b,0x0000000d,0x00000c70,0x00000007,0x0004003b,0x00000007,0x00000c71,0x00000007, + 0x0004003b,0x00000007,0x00000c69,0x00000007,0x0004003b,0x0000000d,0x00000c60,0x00000007, + 0x0004003b,0x00000007,0x00000c61,0x00000007,0x0004003b,0x0000000d,0x00000c58,0x00000007, + 0x0004003b,0x0000000d,0x00000c59,0x00000007,0x0004003b,0x0000000d,0x00000c50,0x00000007, + 0x0004003b,0x0000000d,0x00000c51,0x00000007,0x0004003b,0x0000004c,0x00000c46,0x00000007, + 0x0004003b,0x0000004c,0x00000c47,0x00000007,0x0004003b,0x00000007,0x00000c3e,0x00000007, + 0x0004003b,0x00000007,0x00000c3f,0x00000007,0x0004003b,0x00000007,0x00000c40,0x00000007, + 0x0004003b,0x00000007,0x00000c41,0x00000007,0x0004003b,0x0000004c,0x00000c34,0x00000007, + 0x0004003b,0x0000004c,0x00000c35,0x00000007,0x0004003b,0x00000007,0x00000c2c,0x00000007, + 0x0004003b,0x00000007,0x00000c2d,0x00000007,0x0004003b,0x00000007,0x00000c2e,0x00000007, + 0x0004003b,0x00000007,0x00000c2f,0x00000007,0x0004003b,0x00000007,0x00000bfb,0x00000007, + 0x0004003b,0x0000004c,0x00000bfc,0x00000007,0x0004003b,0x0000004c,0x00000bfd,0x00000007, + 0x0004003b,0x0000004c,0x00000bfe,0x00000007,0x0004003b,0x0000000d,0x00000bff,0x00000007, + 0x0004003b,0x00000007,0x00000c00,0x00000007,0x0004003b,0x00000007,0x00000c01,0x00000007, + 0x0004003b,0x00000007,0x00000c02,0x00000007,0x0004003b,0x0000004c,0x00000c03,0x00000007, + 0x0004003b,0x0000004c,0x00000c04,0x00000007,0x0004003b,0x00000007,0x00000c05,0x00000007, + 0x0004003b,0x00000007,0x00000c06,0x00000007,0x0004003b,0x00000007,0x00000c07,0x00000007, + 0x0004003b,0x00000007,0x00000c08,0x00000007,0x0004003b,0x0000004c,0x00000c09,0x00000007, + 0x0004003b,0x0000004c,0x00000bf1,0x00000007,0x0004003b,0x0000004c,0x00000bf2,0x00000007, + 0x0004003b,0x0000004c,0x00000be7,0x00000007,0x0004003b,0x0000004c,0x00000be8,0x00000007, + 0x0004003b,0x00000007,0x00000be4,0x00000007,0x0004003b,0x0000000d,0x00000bdc,0x00000007, + 0x0004003b,0x0000000d,0x00000bdd,0x00000007,0x0004003b,0x00000007,0x00000bd5,0x00000007, + 0x0004003b,0x0000000d,0x00000bcc,0x00000007,0x0004003b,0x00000007,0x00000bcd,0x00000007, + 0x0004003b,0x00000007,0x00000bc5,0x00000007,0x0004003b,0x0000000d,0x00000bbc,0x00000007, + 0x0004003b,0x00000007,0x00000bbd,0x00000007,0x0004003b,0x0000000d,0x00000bb4,0x00000007, + 0x0004003b,0x0000000d,0x00000bb5,0x00000007,0x0004003b,0x0000000d,0x00000bac,0x00000007, + 0x0004003b,0x0000000d,0x00000bad,0x00000007,0x0004003b,0x0000004c,0x00000ba2,0x00000007, + 0x0004003b,0x0000004c,0x00000ba3,0x00000007,0x0004003b,0x00000007,0x00000b9a,0x00000007, + 0x0004003b,0x00000007,0x00000b9b,0x00000007,0x0004003b,0x00000007,0x00000b9c,0x00000007, + 0x0004003b,0x00000007,0x00000b9d,0x00000007,0x0004003b,0x0000004c,0x00000b90,0x00000007, + 0x0004003b,0x0000004c,0x00000b91,0x00000007,0x0004003b,0x00000007,0x00000b88,0x00000007, + 0x0004003b,0x00000007,0x00000b89,0x00000007,0x0004003b,0x00000007,0x00000b8a,0x00000007, + 0x0004003b,0x00000007,0x00000b8b,0x00000007,0x0004003b,0x00000007,0x00000b57,0x00000007, + 0x0004003b,0x0000004c,0x00000b58,0x00000007,0x0004003b,0x0000004c,0x00000b59,0x00000007, + 0x0004003b,0x0000004c,0x00000b5a,0x00000007,0x0004003b,0x0000000d,0x00000b5b,0x00000007, + 0x0004003b,0x00000007,0x00000b5c,0x00000007,0x0004003b,0x00000007,0x00000b5d,0x00000007, + 0x0004003b,0x00000007,0x00000b5e,0x00000007,0x0004003b,0x0000004c,0x00000b5f,0x00000007, + 0x0004003b,0x0000004c,0x00000b60,0x00000007,0x0004003b,0x00000007,0x00000b61,0x00000007, + 0x0004003b,0x00000007,0x00000b62,0x00000007,0x0004003b,0x00000007,0x00000b63,0x00000007, + 0x0004003b,0x00000007,0x00000b64,0x00000007,0x0004003b,0x0000004c,0x00000b65,0x00000007, + 0x0004003b,0x00000007,0x00000b50,0x00000007,0x0004003b,0x0000000d,0x00000b47,0x00000007, + 0x0004003b,0x00000007,0x00000b48,0x00000007,0x0004003b,0x00000007,0x00000b40,0x00000007, + 0x0004003b,0x0000000d,0x00000b37,0x00000007,0x0004003b,0x00000007,0x00000b38,0x00000007, + 0x0004003b,0x00000007,0x00000b30,0x00000007,0x0004003b,0x0000000d,0x00000b27,0x00000007, + 0x0004003b,0x00000007,0x00000b28,0x00000007,0x0004003b,0x00000007,0x00000b20,0x00000007, + 0x0004003b,0x0000000d,0x00000b17,0x00000007,0x0004003b,0x00000007,0x00000b18,0x00000007, + 0x0004003b,0x00000007,0x00000af7,0x00000007,0x0004003b,0x0000004c,0x00000af8,0x00000007, + 0x0004003b,0x0000004c,0x00000af9,0x00000007,0x0004003b,0x0000004c,0x00000afa,0x00000007, + 0x0004003b,0x00000007,0x00000afb,0x00000007,0x0004003b,0x0000004c,0x00000afc,0x00000007, + 0x0004003b,0x00000007,0x00000afd,0x00000007,0x0004003b,0x0000004c,0x00000afe,0x00000007, + 0x0004003b,0x0000004c,0x00000aff,0x00000007,0x0004003b,0x0000004c,0x00000b00,0x00000007, + 0x0004003b,0x0000004c,0x00000aed,0x00000007,0x0004003b,0x0000004c,0x00000aee,0x00000007, + 0x0004003b,0x0000004c,0x00000ae3,0x00000007,0x0004003b,0x0000004c,0x00000ae4,0x00000007, + 0x0004003b,0x00000007,0x00000ae0,0x00000007,0x0004003b,0x0000000d,0x00000ad8,0x00000007, + 0x0004003b,0x0000000d,0x00000ad9,0x00000007,0x0004003b,0x00000007,0x00000ad1,0x00000007, + 0x0004003b,0x0000000d,0x00000ac8,0x00000007,0x0004003b,0x00000007,0x00000ac9,0x00000007, + 0x0004003b,0x00000007,0x00000ac1,0x00000007,0x0004003b,0x0000000d,0x00000ab8,0x00000007, + 0x0004003b,0x00000007,0x00000ab9,0x00000007,0x0004003b,0x0000000d,0x00000ab0,0x00000007, + 0x0004003b,0x0000000d,0x00000ab1,0x00000007,0x0004003b,0x0000000d,0x00000aa8,0x00000007, + 0x0004003b,0x0000000d,0x00000aa9,0x00000007,0x0004003b,0x0000004c,0x00000a9e,0x00000007, + 0x0004003b,0x0000004c,0x00000a9f,0x00000007,0x0004003b,0x00000007,0x00000a96,0x00000007, + 0x0004003b,0x00000007,0x00000a97,0x00000007,0x0004003b,0x00000007,0x00000a98,0x00000007, + 0x0004003b,0x00000007,0x00000a99,0x00000007,0x0004003b,0x0000004c,0x00000a8c,0x00000007, + 0x0004003b,0x0000004c,0x00000a8d,0x00000007,0x0004003b,0x00000007,0x00000a84,0x00000007, + 0x0004003b,0x00000007,0x00000a85,0x00000007,0x0004003b,0x00000007,0x00000a86,0x00000007, + 0x0004003b,0x00000007,0x00000a87,0x00000007,0x0004003b,0x00000007,0x00000a53,0x00000007, + 0x0004003b,0x0000004c,0x00000a54,0x00000007,0x0004003b,0x0000004c,0x00000a55,0x00000007, + 0x0004003b,0x0000004c,0x00000a56,0x00000007,0x0004003b,0x0000000d,0x00000a57,0x00000007, + 0x0004003b,0x00000007,0x00000a58,0x00000007,0x0004003b,0x00000007,0x00000a59,0x00000007, + 0x0004003b,0x00000007,0x00000a5a,0x00000007,0x0004003b,0x0000004c,0x00000a5b,0x00000007, + 0x0004003b,0x0000004c,0x00000a5c,0x00000007,0x0004003b,0x00000007,0x00000a5d,0x00000007, + 0x0004003b,0x00000007,0x00000a5e,0x00000007,0x0004003b,0x00000007,0x00000a5f,0x00000007, + 0x0004003b,0x00000007,0x00000a60,0x00000007,0x0004003b,0x0000004c,0x00000a61,0x00000007, + 0x0004003b,0x00000007,0x00000a4c,0x00000007,0x0004003b,0x0000000d,0x00000a43,0x00000007, + 0x0004003b,0x00000007,0x00000a44,0x00000007,0x0004003b,0x00000007,0x00000a3c,0x00000007, + 0x0004003b,0x0000000d,0x00000a33,0x00000007,0x0004003b,0x00000007,0x00000a34,0x00000007, + 0x0004003b,0x00000007,0x00000a2c,0x00000007,0x0004003b,0x0000000d,0x00000a23,0x00000007, + 0x0004003b,0x00000007,0x00000a24,0x00000007,0x0004003b,0x00000007,0x00000a1c,0x00000007, + 0x0004003b,0x0000000d,0x00000a13,0x00000007,0x0004003b,0x00000007,0x00000a14,0x00000007, + 0x0004003b,0x00000007,0x000009f3,0x00000007,0x0004003b,0x0000004c,0x000009f4,0x00000007, + 0x0004003b,0x0000004c,0x000009f5,0x00000007,0x0004003b,0x0000004c,0x000009f6,0x00000007, + 0x0004003b,0x00000007,0x000009f7,0x00000007,0x0004003b,0x0000004c,0x000009f8,0x00000007, + 0x0004003b,0x00000007,0x000009f9,0x00000007,0x0004003b,0x0000004c,0x000009fa,0x00000007, + 0x0004003b,0x0000004c,0x000009fb,0x00000007,0x0004003b,0x0000004c,0x000009fc,0x00000007, + 0x0004003b,0x0000004c,0x000009e9,0x00000007,0x0004003b,0x0000004c,0x000009ea,0x00000007, + 0x0004003b,0x0000004c,0x000009df,0x00000007,0x0004003b,0x0000004c,0x000009e0,0x00000007, + 0x0004003b,0x0000004c,0x000009d5,0x00000007,0x0004003b,0x0000004c,0x000009d6,0x00000007, + 0x0004003b,0x0000004c,0x000009cb,0x00000007,0x0004003b,0x0000004c,0x000009cc,0x00000007, + 0x0004003b,0x0000004c,0x000009c1,0x00000007,0x0004003b,0x0000004c,0x000009c2,0x00000007, + 0x0004003b,0x0000004c,0x000009b7,0x00000007,0x0004003b,0x0000004c,0x000009b8,0x00000007, + 0x0004003b,0x0000004c,0x000009ad,0x00000007,0x0004003b,0x0000004c,0x000009ae,0x00000007, + 0x0004003b,0x0000004c,0x000009a3,0x00000007,0x0004003b,0x0000004c,0x000009a4,0x00000007, + 0x0004003b,0x0000004c,0x00000999,0x00000007,0x0004003b,0x0000004c,0x0000099a,0x00000007, + 0x0004003b,0x0000004c,0x0000098f,0x00000007,0x0004003b,0x0000004c,0x00000990,0x00000007, + 0x0004003b,0x0000004c,0x00000985,0x00000007,0x0004003b,0x0000004c,0x00000986,0x00000007, + 0x0004003b,0x0000004c,0x0000097b,0x00000007,0x0004003b,0x0000004c,0x0000097c,0x00000007, + 0x0004003b,0x0000004c,0x00000971,0x00000007,0x0004003b,0x0000004c,0x00000972,0x00000007, + 0x0004003b,0x0000004c,0x00000967,0x00000007,0x0004003b,0x0000004c,0x00000968,0x00000007, + 0x0004003b,0x00000007,0x00000957,0x00000007,0x0004003b,0x0000004c,0x00000958,0x00000007, + 0x0004003b,0x0000004c,0x00000836,0x00000007,0x0004003b,0x0000003b,0x00000837,0x00000007, + 0x0004003b,0x0000004c,0x00000838,0x00000007,0x0004003b,0x0000004c,0x00000839,0x00000007, + 0x0004003b,0x00000007,0x0000083a,0x00000007,0x0004003b,0x00000007,0x0000083b,0x00000007, + 0x0004003b,0x0000004c,0x0000083c,0x00000007,0x0004003b,0x00000007,0x0000083d,0x00000007, + 0x0004003b,0x00000007,0x0000083e,0x00000007,0x0004003b,0x00000007,0x0000083f,0x00000007, + 0x0004003b,0x00000007,0x00000840,0x00000007,0x0004003b,0x00000007,0x00000841,0x00000007, + 0x0004003b,0x00000007,0x00000842,0x00000007,0x0004003b,0x00000007,0x00000843,0x00000007, + 0x0004003b,0x0000004c,0x00000844,0x00000007,0x0004003b,0x00000007,0x00000845,0x00000007, + 0x0004003b,0x00000007,0x00000846,0x00000007,0x0004003b,0x0000004c,0x00000847,0x00000007, + 0x0004003b,0x00000007,0x00000848,0x00000007,0x0004003b,0x00000280,0x00000849,0x00000007, + 0x0004003b,0x00000007,0x0000084a,0x00000007,0x0004003b,0x00000007,0x0000084b,0x00000007, + 0x0004003b,0x0000004c,0x0000084c,0x00000007,0x0004003b,0x0000004c,0x0000084d,0x00000007, + 0x0004003b,0x0000004c,0x0000084e,0x00000007,0x0004003b,0x00000007,0x0000084f,0x00000007, + 0x0004003b,0x00000007,0x00000850,0x00000007,0x0004003b,0x0000004c,0x00000851,0x00000007, + 0x0004003b,0x0000004c,0x00000852,0x00000007,0x0004003b,0x0000004c,0x00000853,0x00000007, + 0x0004003b,0x00000007,0x00000854,0x00000007,0x0004003b,0x00000007,0x00000855,0x00000007, + 0x0004003b,0x0000004c,0x00000856,0x00000007,0x0004003b,0x0000004c,0x00000857,0x00000007, + 0x0004003b,0x00000007,0x00000858,0x00000007,0x0004003b,0x00000007,0x00000859,0x00000007, + 0x0004003b,0x0000004c,0x0000085a,0x00000007,0x0004003b,0x0000004c,0x0000085b,0x00000007, + 0x0004003b,0x0000004c,0x0000085c,0x00000007,0x0004003b,0x0000004c,0x00000825,0x00000007, + 0x0004003b,0x0000004c,0x00000826,0x00000007,0x0004003b,0x0000003b,0x00000827,0x00000007, + 0x0004003b,0x00000013,0x00000828,0x00000007,0x0004003b,0x00000007,0x00000829,0x00000007, + 0x0004003b,0x0000004c,0x0000082a,0x00000007,0x0004003b,0x00000013,0x00000820,0x00000007, + 0x0004003b,0x00000013,0x00000821,0x00000007,0x0004003b,0x00000463,0x00000813,0x00000007, + 0x0004003b,0x0000003b,0x00000807,0x00000007,0x0004003b,0x0000003b,0x00000808,0x00000007, + 0x0004003b,0x0000000d,0x00000802,0x00000007,0x0004003b,0x0000000d,0x00000803,0x00000007, + 0x0004003b,0x00000463,0x000007f5,0x00000007,0x0004003b,0x0000000d,0x000007ed,0x00000007, + 0x0004003b,0x0000000d,0x000007ee,0x00000007,0x0004003b,0x00000007,0x000007da,0x00000007, + 0x0004003b,0x00000007,0x000007d7,0x00000007,0x0004003b,0x00000007,0x000007d4,0x00000007, + 0x0004003b,0x00000411,0x000006e1,0x00000007,0x0004003b,0x00000007,0x000006e2,0x00000007, + 0x0004003b,0x00000007,0x000006e3,0x00000007,0x0004003b,0x00000007,0x000006e4,0x00000007, + 0x0004003b,0x00000013,0x000006e5,0x00000007,0x0004003b,0x00000013,0x000006e6,0x00000007, + 0x0004003b,0x0000003b,0x000006e7,0x00000007,0x0004003b,0x00000007,0x000006e8,0x00000007, + 0x0004003b,0x00000463,0x000006e9,0x00000007,0x0004003b,0x0000003b,0x000006ea,0x00000007, + 0x0004003b,0x0000003b,0x000006eb,0x00000007,0x0004003b,0x0000000d,0x000006ec,0x00000007, + 0x0004003b,0x0000000d,0x000006ed,0x00000007,0x0004003b,0x0000000d,0x000006ee,0x00000007, + 0x0004003b,0x00000007,0x000006ef,0x00000007,0x0004003b,0x00000013,0x000006f0,0x00000007, + 0x0004003b,0x00000007,0x000006f1,0x00000007,0x0004003b,0x00000463,0x000006f2,0x00000007, + 0x0004003b,0x0000003b,0x000006f3,0x00000007,0x0004003b,0x0000003b,0x000006f4,0x00000007, + 0x0004003b,0x0000000d,0x000006f5,0x00000007,0x0004003b,0x00000007,0x000006f6,0x00000007, + 0x0004003b,0x00000007,0x000006f7,0x00000007,0x0004003b,0x00000007,0x000006f8,0x00000007, + 0x0004003b,0x00000007,0x000006f9,0x00000007,0x0004003b,0x00000013,0x000006fa,0x00000007, + 0x0004003b,0x00000013,0x000006fb,0x00000007,0x0004003b,0x0000003b,0x000006fc,0x00000007, + 0x0004003b,0x0000004c,0x000006fd,0x00000007,0x0004003b,0x0000003b,0x000006fe,0x00000007, + 0x0004003b,0x00000013,0x000006ff,0x00000007,0x0004003b,0x00000007,0x000006dc,0x00000007, + 0x0004003b,0x00000007,0x000006dd,0x00000007,0x0004003b,0x00000007,0x000006d4,0x00000007, + 0x0004003b,0x00000007,0x000006d5,0x00000007,0x0004003b,0x000005d6,0x000006cf,0x00000007, + 0x0004003b,0x00000013,0x000006cc,0x00000007,0x0004003b,0x00000013,0x000006c7,0x00000007, + 0x0004003b,0x00000013,0x000006c8,0x00000007,0x0004003b,0x00000013,0x000006c2,0x00000007, + 0x0004003b,0x00000013,0x000006c3,0x00000007,0x0004003b,0x00000013,0x000006bb,0x00000007, + 0x0004003b,0x0000003b,0x000006af,0x00000007,0x0004003b,0x0000003b,0x000006b0,0x00000007, + 0x0004003b,0x0000003b,0x000006a3,0x00000007,0x0004003b,0x0000003b,0x000006a4,0x00000007, + 0x0004003b,0x00000007,0x000006a0,0x00000007,0x0004003b,0x00000007,0x0000069d,0x00000007, + 0x0004003b,0x00000007,0x0000069a,0x00000007,0x0004003b,0x0000003b,0x0000068e,0x00000007, + 0x0004003b,0x0000003b,0x0000068f,0x00000007,0x0004003b,0x0000003b,0x00000682,0x00000007, + 0x0004003b,0x0000003b,0x00000683,0x00000007,0x0004003b,0x00000007,0x00000601,0x00000007, + 0x0004003b,0x00000007,0x00000602,0x00000007,0x0004003b,0x00000007,0x00000603,0x00000007, + 0x0004003b,0x00000007,0x00000604,0x00000007,0x0004003b,0x00000007,0x00000605,0x00000007, + 0x0004003b,0x00000007,0x00000606,0x00000007,0x0004003b,0x00000007,0x00000607,0x00000007, + 0x0004003b,0x0000003b,0x00000608,0x00000007,0x0004003b,0x00000007,0x00000609,0x00000007, + 0x0004003b,0x00000007,0x0000060a,0x00000007,0x0004003b,0x00000007,0x0000060b,0x00000007, + 0x0004003b,0x00000007,0x0000060c,0x00000007,0x0004003b,0x0000003b,0x0000060d,0x00000007, + 0x0004003b,0x0000003b,0x0000060e,0x00000007,0x0004003b,0x00000007,0x0000060f,0x00000007, + 0x0004003b,0x00000007,0x00000610,0x00000007,0x0004003b,0x00000007,0x00000611,0x00000007, + 0x0004003b,0x00000007,0x00000612,0x00000007,0x0004003b,0x0000003b,0x00000613,0x00000007, + 0x0004003b,0x0000003b,0x00000614,0x00000007,0x0004003b,0x00000007,0x00000615,0x00000007, + 0x0004003b,0x00000007,0x00000616,0x00000007,0x0004003b,0x000005d6,0x000005fc,0x00000007, + 0x0004003b,0x00000007,0x000005dc,0x00000007,0x0004003b,0x00000007,0x000005dd,0x00000007, + 0x0004003b,0x00000007,0x000005de,0x00000007,0x0004003b,0x00000007,0x000005df,0x00000007, + 0x0004003b,0x00000007,0x000005e0,0x00000007,0x0004003b,0x000005d6,0x000005d7,0x00000007, + 0x0004003b,0x000000a2,0x00000529,0x00000007,0x0004003b,0x0000003b,0x00000532,0x00000007, + 0x0004003b,0x00000007,0x00000538,0x00000007,0x0004003b,0x0000003b,0x00000539,0x00000007, + 0x0004003b,0x0000003b,0x0000053f,0x00000007,0x0004003b,0x0000003b,0x00000545,0x00000007, + 0x0004003b,0x00000007,0x00000549,0x00000007,0x0004003b,0x00000007,0x0000054e,0x00000007, + 0x0004003b,0x00000007,0x00000554,0x00000007,0x0004003b,0x0000003b,0x00000557,0x00000007, + 0x0004003b,0x00000007,0x00000558,0x00000007,0x0004003b,0x0000003b,0x0000055a,0x00000007, + 0x0004003b,0x00000007,0x0000055b,0x00000007,0x0004003b,0x00000013,0x0000055d,0x00000007, + 0x0004003b,0x00000007,0x0000055e,0x00000007,0x0004003b,0x00000013,0x00000561,0x00000007, + 0x0004003b,0x00000013,0x00000564,0x00000007,0x0004003b,0x00000013,0x0000056b,0x00000007, + 0x0004003b,0x00000013,0x00000574,0x00000007,0x0004003b,0x00000013,0x00000577,0x00000007, + 0x0004003b,0x00000013,0x00000579,0x00000007,0x0004003b,0x0000003b,0x00000581,0x00000007, + 0x0004003b,0x00000007,0x00000596,0x00000007,0x0004003b,0x00000013,0x0000059a,0x00000007, + 0x0004003b,0x00000013,0x0000059c,0x00000007,0x0004003b,0x00000007,0x0000059e,0x00000007, + 0x0004003b,0x0000003b,0x000005a0,0x00000007,0x0004003b,0x0000003b,0x000005a1,0x00000007, + 0x0004003b,0x0000004c,0x000005ae,0x00000007,0x0004003b,0x0000000d,0x000005b1,0x00000007, + 0x0004003b,0x00000007,0x000005b4,0x00000007,0x0004003b,0x00000007,0x000005b8,0x00000007, + 0x0004003b,0x0000003b,0x000005c2,0x00000007,0x0004003b,0x0000003b,0x000005c7,0x00000007, + 0x0004003d,0x0000002f,0x0000052a,0x0000047b,0x0007004f,0x0000000c,0x0000052b,0x0000052a, + 0x0000052a,0x00000000,0x00000001,0x0006000c,0x0000000c,0x0000052c,0x00000001,0x00000008, + 0x0000052b,0x0004006e,0x000000a1,0x0000052d,0x0000052c,0x0003003e,0x00000529,0x0000052d, + 0x000300f7,0x00000530,0x00000000,0x000400fa,0x0000052e,0x0000052f,0x00000530,0x000200f8, + 0x0000052f,0x0004003d,0x0000002f,0x00000533,0x00000531,0x0003003e,0x00000532,0x00000533, + 0x00050041,0x00000007,0x000005d9,0x00000532,0x000000c8,0x0004003d,0x00000006,0x000005da, + 0x000005d9,0x000500b8,0x0000007d,0x000005db,0x000005da,0x0000032b,0x0003003e,0x000005d7, + 0x000005db,0x0004003d,0x0000007d,0x00000534,0x000005d7,0x000200f9,0x00000530,0x000200f8, + 0x00000530,0x000700f5,0x0000007d,0x00000535,0x0000052e,0x00000005,0x00000534,0x0000052f, + 0x000300f7,0x00000537,0x00000000,0x000400fa,0x00000535,0x00000536,0x0000053c,0x000200f8, + 0x00000536,0x0004003d,0x0000002f,0x0000053a,0x00000531,0x0003003e,0x00000539,0x0000053a, + 0x0003003e,0x000005dc,0x0000010a,0x00050041,0x00000007,0x000005e2,0x00000539,0x000000c8, + 0x0004003d,0x00000006,0x000005e3,0x000005e2,0x00050081,0x00000006,0x000005e4,0x000002ab, + 0x000005e3,0x0003003e,0x000005dd,0x000005e4,0x0004003d,0x00000341,0x000005e5,0x00000343, + 0x0004003d,0x00000345,0x000005e6,0x00000347,0x00050056,0x00000349,0x000005e7,0x000005e5, + 0x000005e6,0x0004003d,0x00000006,0x000005e8,0x000005dd,0x00050050,0x0000000c,0x000005e9, + 0x000005e8,0x0000010b,0x00070058,0x0000002f,0x000005ea,0x000005e7,0x000005e9,0x00000002, + 0x0000010b,0x00050051,0x00000006,0x000005eb,0x000005ea,0x00000000,0x0004003d,0x00000006, + 0x000005ec,0x000005dc,0x00050083,0x00000006,0x000005ed,0x000005ec,0x000005eb,0x0003003e, + 0x000005dc,0x000005ed,0x00050041,0x00000007,0x000005ee,0x00000539,0x000000cb,0x0004003d, + 0x00000006,0x000005ef,0x000005ee,0x00050083,0x00000006,0x000005f0,0x0000010a,0x000005ef, + 0x0003003e,0x000005de,0x000005f0,0x0004003d,0x00000341,0x000005f1,0x00000343,0x0004003d, + 0x00000345,0x000005f2,0x00000347,0x00050056,0x00000349,0x000005f3,0x000005f1,0x000005f2, + 0x0004003d,0x00000006,0x000005f4,0x000005de,0x00050050,0x0000000c,0x000005f5,0x000005f4, + 0x0000010b,0x00070058,0x0000002f,0x000005f6,0x000005f3,0x000005f5,0x00000002,0x0000010b, + 0x00050051,0x00000006,0x000005f7,0x000005f6,0x00000000,0x0004003d,0x00000006,0x000005f8, + 0x000005dc,0x00050083,0x00000006,0x000005f9,0x000005f8,0x000005f7,0x0003003e,0x000005dc, + 0x000005f9,0x0004003d,0x00000006,0x000005fa,0x000005dc,0x0003003e,0x000005df,0x000005fa, + 0x0004003d,0x00000006,0x000005fb,0x000005df,0x0003003e,0x000005e0,0x000005fb,0x0004003d, + 0x00000006,0x0000053b,0x000005e0,0x0003003e,0x00000538,0x0000053b,0x000200f9,0x00000537, + 0x000200f8,0x0000053c,0x000300f7,0x0000053e,0x00000000,0x000400fa,0x0000052e,0x0000053d, + 0x0000053e,0x000200f8,0x0000053d,0x0004003d,0x0000002f,0x00000540,0x00000531,0x0003003e, + 0x0000053f,0x00000540,0x00050041,0x00000007,0x000005fe,0x0000053f,0x000000cb,0x0004003d, + 0x00000006,0x000005ff,0x000005fe,0x000500b8,0x0000007d,0x00000600,0x000005ff,0x0000032b, + 0x0003003e,0x000005fc,0x00000600,0x0004003d,0x0000007d,0x00000541,0x000005fc,0x000200f9, + 0x0000053e,0x000200f8,0x0000053e,0x000700f5,0x0000007d,0x00000542,0x0000052e,0x0000053c, + 0x00000541,0x0000053d,0x000300f7,0x00000544,0x00000000,0x000400fa,0x00000542,0x00000543, + 0x00000548,0x000200f8,0x00000543,0x0004003d,0x0000002f,0x00000546,0x00000531,0x0003003e, + 0x00000545,0x00000546,0x00050041,0x00000007,0x00000618,0x00000545,0x000000de,0x0004003d, + 0x00000006,0x00000619,0x00000618,0x0003003e,0x00000601,0x00000619,0x00050041,0x00000007, + 0x0000061a,0x00000545,0x000000f5,0x0004003d,0x00000006,0x0000061b,0x0000061a,0x0007000c, + 0x00000006,0x0000061c,0x00000001,0x00000028,0x0000061b,0x0000010b,0x0003003e,0x00000602, + 0x0000061c,0x0004003d,0x00000006,0x0000061d,0x00000601,0x000500be,0x0000007d,0x0000061e, + 0x0000061d,0x0000010b,0x000300f7,0x00000628,0x00000000,0x000400fa,0x0000061e,0x0000061f, + 0x00000627,0x000200f8,0x0000061f,0x0004003d,0x00000341,0x00000620,0x00000343,0x0004003d, + 0x00000345,0x00000621,0x00000347,0x00050056,0x00000349,0x00000622,0x00000620,0x00000621, + 0x0004003d,0x00000006,0x00000623,0x00000602,0x00050050,0x0000000c,0x00000624,0x00000623, + 0x0000010b,0x00070058,0x0000002f,0x00000625,0x00000622,0x00000624,0x00000002,0x0000010b, + 0x00050051,0x00000006,0x00000626,0x00000625,0x00000000,0x0003003e,0x00000604,0x00000626, + 0x000200f9,0x00000628,0x000200f8,0x00000627,0x0003003e,0x00000604,0x0000010b,0x000200f9, + 0x00000628,0x000200f8,0x00000628,0x0004003d,0x00000006,0x00000629,0x00000604,0x0003003e, + 0x00000603,0x00000629,0x0004003d,0x00000006,0x0000062a,0x00000601,0x0006000c,0x00000006, + 0x0000062b,0x00000001,0x00000004,0x0000062a,0x000500b8,0x0000007d,0x0000062c,0x0000062b, + 0x00000353,0x000300f7,0x0000067b,0x00000000,0x000400fa,0x0000062c,0x0000062d,0x0000067b, + 0x000200f8,0x0000062d,0x00050041,0x00000007,0x0000062e,0x00000545,0x000000c8,0x0004003d, + 0x00000006,0x0000062f,0x0000062e,0x0006000c,0x00000006,0x00000630,0x00000001,0x00000004, + 0x0000062f,0x00050083,0x00000006,0x00000631,0x00000630,0x0000029b,0x0003003e,0x00000605, + 0x00000631,0x00050041,0x00000007,0x00000632,0x00000545,0x000000cb,0x0004003d,0x00000006, + 0x00000633,0x00000632,0x00050083,0x00000006,0x00000635,0x00000360,0x00000633,0x0003003e, + 0x00000606,0x00000635,0x0004003d,0x00000006,0x00000636,0x00000606,0x0004003d,0x00000006, + 0x00000637,0x00000602,0x00050083,0x00000006,0x00000638,0x00000636,0x00000637,0x00050085, + 0x00000006,0x00000639,0x00000638,0x00000366,0x0003003e,0x00000607,0x00000639,0x0004003d, + 0x00000006,0x0000063a,0x00000602,0x0004003d,0x00000006,0x0000063b,0x00000607,0x0003003e, + 0x00000609,0x0000036b,0x0003003e,0x0000060a,0x0000036c,0x0003003e,0x0000060b,0x0000036d, + 0x0003003e,0x0000060c,0x0000036e,0x0004003d,0x00000006,0x00000685,0x00000609,0x00050041, + 0x00000007,0x00000686,0x00000682,0x000000c8,0x0003003e,0x00000686,0x00000685,0x0004003d, + 0x00000006,0x00000687,0x0000060a,0x00050041,0x00000007,0x00000688,0x00000682,0x000000cb, + 0x0003003e,0x00000688,0x00000687,0x0004003d,0x00000006,0x00000689,0x0000060b,0x00050041, + 0x00000007,0x0000068a,0x00000682,0x000000de,0x0003003e,0x0000068a,0x00000689,0x0004003d, + 0x00000006,0x0000068b,0x0000060c,0x00050041,0x00000007,0x0000068c,0x00000682,0x000000f5, + 0x0003003e,0x0000068c,0x0000068b,0x0004003d,0x0000002f,0x0000068d,0x00000682,0x0003003e, + 0x00000683,0x0000068d,0x0004003d,0x0000002f,0x0000063c,0x00000683,0x0005008e,0x0000002f, + 0x0000063d,0x0000063c,0x0000063b,0x00070050,0x0000002f,0x0000063e,0x0000063a,0x0000063a, + 0x0000063a,0x0000063a,0x00050081,0x0000002f,0x0000063f,0x0000063e,0x0000063d,0x0003003e, + 0x00000608,0x0000063f,0x0004003d,0x0000002f,0x00000640,0x00000608,0x0004003d,0x00000006, + 0x00000641,0x00000601,0x0004007f,0x00000006,0x00000642,0x00000641,0x0005008e,0x0000002f, + 0x00000643,0x00000640,0x00000642,0x0004003d,0x00000006,0x00000644,0x00000606,0x0004003d, + 0x00000006,0x00000645,0x00000601,0x00050085,0x00000006,0x00000646,0x00000644,0x00000645, + 0x0004003d,0x00000006,0x00000647,0x00000605,0x00050081,0x00000006,0x00000648,0x00000646, + 0x00000647,0x00070050,0x0000002f,0x00000649,0x00000648,0x00000648,0x00000648,0x00000648, + 0x00050081,0x0000002f,0x0000064a,0x00000643,0x00000649,0x0003003e,0x0000060d,0x0000064a, + 0x0004003d,0x00000341,0x0000064b,0x00000343,0x0004003d,0x00000345,0x0000064c,0x00000347, + 0x00050056,0x00000349,0x0000064d,0x0000064b,0x0000064c,0x00050041,0x00000007,0x0000064e, + 0x0000060d,0x000000c8,0x0004003d,0x00000006,0x0000064f,0x0000064e,0x00050050,0x0000000c, + 0x00000650,0x0000064f,0x0000010b,0x00070058,0x0000002f,0x00000651,0x0000064d,0x00000650, + 0x00000002,0x0000010b,0x0004003d,0x00000341,0x00000652,0x00000343,0x0004003d,0x00000345, + 0x00000653,0x00000347,0x00050056,0x00000349,0x00000654,0x00000652,0x00000653,0x00050041, + 0x00000007,0x00000655,0x0000060d,0x000000cb,0x0004003d,0x00000006,0x00000656,0x00000655, + 0x00050050,0x0000000c,0x00000657,0x00000656,0x0000010b,0x00070058,0x0000002f,0x00000658, + 0x00000654,0x00000657,0x00000002,0x0000010b,0x0004003d,0x00000341,0x00000659,0x00000343, + 0x0004003d,0x00000345,0x0000065a,0x00000347,0x00050056,0x00000349,0x0000065b,0x00000659, + 0x0000065a,0x00050041,0x00000007,0x0000065c,0x0000060d,0x000000de,0x0004003d,0x00000006, + 0x0000065d,0x0000065c,0x00050050,0x0000000c,0x0000065e,0x0000065d,0x0000010b,0x00070058, + 0x0000002f,0x0000065f,0x0000065b,0x0000065e,0x00000002,0x0000010b,0x0004003d,0x00000341, + 0x00000660,0x00000343,0x0004003d,0x00000345,0x00000661,0x00000347,0x00050056,0x00000349, + 0x00000662,0x00000660,0x00000661,0x00050041,0x00000007,0x00000663,0x0000060d,0x000000f5, + 0x0004003d,0x00000006,0x00000664,0x00000663,0x00050050,0x0000000c,0x00000665,0x00000664, + 0x0000010b,0x00070058,0x0000002f,0x00000666,0x00000662,0x00000665,0x00000002,0x0000010b, + 0x00050051,0x00000006,0x00000667,0x00000651,0x00000000,0x0003003e,0x0000060f,0x00000667, + 0x00050051,0x00000006,0x00000668,0x00000658,0x00000000,0x0003003e,0x00000610,0x00000668, + 0x00050051,0x00000006,0x00000669,0x0000065f,0x00000000,0x0003003e,0x00000611,0x00000669, + 0x00050051,0x00000006,0x0000066a,0x00000666,0x00000000,0x0003003e,0x00000612,0x0000066a, + 0x0004003d,0x00000006,0x00000691,0x0000060f,0x00050041,0x00000007,0x00000692,0x0000068e, + 0x000000c8,0x0003003e,0x00000692,0x00000691,0x0004003d,0x00000006,0x00000693,0x00000610, + 0x00050041,0x00000007,0x00000694,0x0000068e,0x000000cb,0x0003003e,0x00000694,0x00000693, + 0x0004003d,0x00000006,0x00000695,0x00000611,0x00050041,0x00000007,0x00000696,0x0000068e, + 0x000000de,0x0003003e,0x00000696,0x00000695,0x0004003d,0x00000006,0x00000697,0x00000612, + 0x00050041,0x00000007,0x00000698,0x0000068e,0x000000f5,0x0003003e,0x00000698,0x00000697, + 0x0004003d,0x0000002f,0x00000699,0x0000068e,0x0003003e,0x0000068f,0x00000699,0x0004003d, + 0x0000002f,0x0000066b,0x0000068f,0x0003003e,0x0000060e,0x0000066b,0x0004003d,0x0000002f, + 0x0000066c,0x00000608,0x0005008e,0x0000002f,0x0000066d,0x0000066c,0x000003ab,0x00050081, + 0x0000002f,0x0000066e,0x0000066d,0x000005d5,0x0003003e,0x00000613,0x0000066e,0x0004003d, + 0x0000002f,0x0000066f,0x00000613,0x0004007f,0x0000002f,0x00000670,0x0000066f,0x0004003d, + 0x0000002f,0x00000671,0x00000613,0x00050085,0x0000002f,0x00000672,0x00000670,0x00000671, + 0x0006000c,0x0000002f,0x00000673,0x00000001,0x0000001d,0x00000672,0x0003003e,0x00000614, + 0x00000673,0x0004003d,0x0000002f,0x00000674,0x0000060e,0x0004003d,0x0000002f,0x00000675, + 0x00000614,0x00050094,0x00000006,0x00000676,0x00000674,0x00000675,0x0004003d,0x00000006, + 0x00000677,0x00000607,0x00050085,0x00000006,0x00000678,0x00000676,0x00000677,0x0004003d, + 0x00000006,0x00000679,0x00000603,0x00050081,0x00000006,0x0000067a,0x00000679,0x00000678, + 0x0003003e,0x00000603,0x0000067a,0x000200f9,0x0000067b,0x000200f8,0x0000067b,0x0004003d, + 0x00000006,0x0000067c,0x00000603,0x00050041,0x00000007,0x0000067d,0x00000545,0x000000c8, + 0x0004003d,0x00000006,0x0000067e,0x0000067d,0x0006000c,0x00000006,0x0000067f,0x00000001, + 0x00000006,0x0000067e,0x00050085,0x00000006,0x00000680,0x0000067c,0x0000067f,0x0003003e, + 0x00000615,0x00000680,0x0004003d,0x00000006,0x00000681,0x00000615,0x0003003e,0x00000616, + 0x00000681,0x0004003d,0x00000006,0x00000547,0x00000616,0x0003003e,0x00000538,0x00000547, + 0x000200f9,0x00000544,0x000200f8,0x00000548,0x00050041,0x0000054a,0x0000054b,0x00000531, + 0x000000c8,0x0004003d,0x00000006,0x0000054c,0x0000054b,0x0003003e,0x00000549,0x0000054c, + 0x0004003d,0x00000006,0x0000069c,0x00000549,0x0003003e,0x0000069a,0x0000069c,0x0004003d, + 0x00000006,0x0000054d,0x0000069a,0x00050041,0x0000054a,0x0000054f,0x00000531,0x000000cb, + 0x0004003d,0x00000006,0x00000550,0x0000054f,0x0003003e,0x0000054e,0x00000550,0x0004003d, + 0x00000006,0x0000069f,0x0000054e,0x0003003e,0x0000069d,0x0000069f,0x0004003d,0x00000006, + 0x00000551,0x0000069d,0x0006000c,0x00000006,0x00000552,0x00000001,0x00000004,0x00000551, + 0x0007000c,0x00000006,0x00000553,0x00000001,0x00000025,0x0000054d,0x00000552,0x0003003e, + 0x00000554,0x0000010a,0x0004003d,0x00000006,0x000006a2,0x00000554,0x0003003e,0x000006a0, + 0x000006a2,0x0004003d,0x00000006,0x00000555,0x000006a0,0x0007000c,0x00000006,0x00000556, + 0x00000001,0x00000025,0x00000553,0x00000555,0x0003003e,0x00000538,0x00000556,0x000200f9, + 0x00000544,0x000200f8,0x00000544,0x000200f9,0x00000537,0x000200f8,0x00000537,0x0003003e, + 0x00000558,0x0000010b,0x0004003d,0x00000006,0x000006a6,0x00000558,0x00050041,0x00000007, + 0x000006a7,0x000006a3,0x000000c8,0x0003003e,0x000006a7,0x000006a6,0x0004003d,0x00000006, + 0x000006a8,0x00000558,0x00050041,0x00000007,0x000006a9,0x000006a3,0x000000cb,0x0003003e, + 0x000006a9,0x000006a8,0x0004003d,0x00000006,0x000006aa,0x00000558,0x00050041,0x00000007, + 0x000006ab,0x000006a3,0x000000de,0x0003003e,0x000006ab,0x000006aa,0x0004003d,0x00000006, + 0x000006ac,0x00000558,0x00050041,0x00000007,0x000006ad,0x000006a3,0x000000f5,0x0003003e, + 0x000006ad,0x000006ac,0x0004003d,0x0000002f,0x000006ae,0x000006a3,0x0003003e,0x000006a4, + 0x000006ae,0x0004003d,0x0000002f,0x00000559,0x000006a4,0x0003003e,0x00000557,0x00000559, + 0x0003003e,0x0000055b,0x0000010b,0x0004003d,0x00000006,0x000006b2,0x0000055b,0x00050041, + 0x00000007,0x000006b3,0x000006af,0x000000c8,0x0003003e,0x000006b3,0x000006b2,0x0004003d, + 0x00000006,0x000006b4,0x0000055b,0x00050041,0x00000007,0x000006b5,0x000006af,0x000000cb, + 0x0003003e,0x000006b5,0x000006b4,0x0004003d,0x00000006,0x000006b6,0x0000055b,0x00050041, + 0x00000007,0x000006b7,0x000006af,0x000000de,0x0003003e,0x000006b7,0x000006b6,0x0004003d, + 0x00000006,0x000006b8,0x0000055b,0x00050041,0x00000007,0x000006b9,0x000006af,0x000000f5, + 0x0003003e,0x000006b9,0x000006b8,0x0004003d,0x0000002f,0x000006ba,0x000006af,0x0003003e, + 0x000006b0,0x000006ba,0x0004003d,0x0000002f,0x0000055c,0x000006b0,0x0003003e,0x0000055a, + 0x0000055c,0x0004003d,0x00000006,0x0000055f,0x00000538,0x0003003e,0x0000055e,0x0000055f, + 0x0004003d,0x00000006,0x000006bd,0x0000055e,0x00050085,0x00000006,0x000006be,0x000006bd, + 0x000003e7,0x00050081,0x00000006,0x000006bf,0x000006be,0x000003e9,0x0006000c,0x00000006, + 0x000006c0,0x00000001,0x00000001,0x000006bf,0x0004006d,0x00000012,0x000006c1,0x000006c0, + 0x0003003e,0x000006bb,0x000006c1,0x0004003d,0x00000012,0x00000560,0x000006bb,0x0003003e, + 0x0000055d,0x00000560,0x0004003d,0x00000012,0x00000565,0x00000563,0x0003003e,0x00000564, + 0x00000565,0x0004003d,0x00000012,0x000006c5,0x00000564,0x0003003e,0x000006c2,0x000006c5, + 0x0004003d,0x00000012,0x000006c6,0x000006c2,0x0003003e,0x000006c3,0x000006c6,0x0004003d, + 0x00000012,0x00000566,0x000006c3,0x000500c4,0x00000012,0x00000568,0x00000566,0x00000567, + 0x0004003d,0x00000012,0x00000569,0x0000055d,0x000500c5,0x00000012,0x0000056a,0x00000568, + 0x00000569,0x0003003e,0x00000561,0x0000056a,0x0004003d,0x000000a1,0x0000056f,0x00000529, + 0x0004003d,0x00000012,0x00000570,0x00000561,0x0006003c,0x00000571,0x00000572,0x0000056e, + 0x0000056f,0x000000c8,0x000700ef,0x00000012,0x00000573,0x00000572,0x000000cb,0x000000c8, + 0x00000570,0x0003003e,0x0000056b,0x00000573,0x0004003d,0x00000012,0x00000575,0x0000056b, + 0x000500c2,0x00000012,0x00000576,0x00000575,0x00000567,0x0003003e,0x00000577,0x00000576, + 0x0004003d,0x00000012,0x000006ca,0x00000577,0x0003003e,0x000006c7,0x000006ca,0x0004003d, + 0x00000012,0x000006cb,0x000006c7,0x0003003e,0x000006c8,0x000006cb,0x0004003d,0x00000012, + 0x00000578,0x000006c8,0x0003003e,0x00000574,0x00000578,0x0004003d,0x00000012,0x0000057a, + 0x00000574,0x0003003e,0x00000579,0x0000057a,0x0004003d,0x00000012,0x000006ce,0x00000579, + 0x0003003e,0x000006cc,0x000006ce,0x0004003d,0x00000012,0x0000057b,0x000006cc,0x0003003e, + 0x00000574,0x0000057b,0x0004003d,0x00000012,0x0000057c,0x00000574,0x000500aa,0x0000007d, + 0x0000057e,0x0000057c,0x00000565,0x000300f7,0x00000580,0x00000000,0x000400fa,0x0000057e, + 0x0000057f,0x00000595,0x000200f8,0x0000057f,0x0004003d,0x0000002f,0x00000582,0x00000531, + 0x0003003e,0x00000581,0x00000582,0x00050041,0x00000007,0x000006d1,0x00000581,0x000000cb, + 0x0004003d,0x00000006,0x000006d2,0x000006d1,0x000500be,0x0000007d,0x000006d3,0x000006d2, + 0x0000010b,0x0003003e,0x000006cf,0x000006d3,0x0004003d,0x0000007d,0x00000583,0x000006cf, + 0x000400a8,0x0000007d,0x00000584,0x00000583,0x000300f7,0x00000586,0x00000000,0x000400fa, + 0x00000584,0x00000585,0x00000586,0x000200f8,0x00000585,0x0004003d,0x00000012,0x00000587, + 0x0000056b,0x0004003d,0x00000012,0x00000588,0x00000561,0x0004003d,0x00000012,0x00000589, + 0x0000056b,0x0007000c,0x00000012,0x0000058a,0x00000001,0x00000029,0x00000588,0x00000589, + 0x00050082,0x00000012,0x0000058b,0x00000587,0x0000058a,0x0004003d,0x00000012,0x0000058c, + 0x0000055d,0x00050080,0x00000012,0x0000058d,0x0000058c,0x0000058b,0x0003003e,0x0000055d, + 0x0000058d,0x0004003d,0x00000012,0x0000058f,0x0000055d,0x00050082,0x00000012,0x00000590, + 0x0000058f,0x0000058e,0x0003003e,0x0000055d,0x00000590,0x0004003d,0x000000a1,0x00000591, + 0x00000529,0x0004003d,0x00000012,0x00000592,0x0000055d,0x0006003c,0x00000571,0x00000593, + 0x0000056e,0x00000591,0x000000c8,0x000700ea,0x00000012,0x00000594,0x00000593,0x000000cb, + 0x000000c8,0x00000592,0x000200f9,0x00000586,0x000200f8,0x00000586,0x000200f9,0x00000580, + 0x000200f8,0x00000595,0x0004003d,0x00000012,0x00000597,0x0000056b,0x000500c7,0x00000012, + 0x00000599,0x00000597,0x00000598,0x0003003e,0x0000059a,0x00000599,0x0004003d,0x00000012, + 0x000006d7,0x0000059a,0x00040070,0x00000006,0x000006d8,0x000006d7,0x00050085,0x00000006, + 0x000006d9,0x000006d8,0x000003f1,0x00050081,0x00000006,0x000006da,0x000006d9,0x000003f3, + 0x0003003e,0x000006d4,0x000006da,0x0004003d,0x00000006,0x000006df,0x000006d4,0x0003003e, + 0x000006dc,0x000006df,0x0004003d,0x00000006,0x000006e0,0x000006dc,0x0003003e,0x000006dd, + 0x000006e0,0x0004003d,0x00000006,0x000006db,0x000006dd,0x0003003e,0x000006d5,0x000006db, + 0x0004003d,0x00000006,0x0000059b,0x000006d5,0x0003003e,0x00000596,0x0000059b,0x0004003d, + 0x00000012,0x0000059d,0x00000574,0x0003003e,0x0000059c,0x0000059d,0x0004003d,0x00000006, + 0x0000059f,0x00000596,0x0003003e,0x0000059e,0x0000059f,0x0004003d,0x0000002f,0x000005a2, + 0x0000055a,0x0003003e,0x000005a1,0x000005a2,0x0004003d,0x00000012,0x00000701,0x0000059c, + 0x00060041,0x00000418,0x00000702,0x00000416,0x00000282,0x00000701,0x0004003d,0x00000410, + 0x00000703,0x00000702,0x0003003e,0x000006e1,0x00000703,0x0004003d,0x00000006,0x00000704, + 0x0000059e,0x0003003e,0x000006e2,0x00000704,0x00050041,0x00000013,0x00000705,0x000006e1, + 0x000000c8,0x0004003d,0x00000012,0x00000706,0x00000705,0x000500c7,0x00000012,0x00000707, + 0x00000706,0x0000041f,0x000500ab,0x0000007d,0x00000708,0x00000707,0x000000c8,0x000300f7, + 0x0000071c,0x00000000,0x000400fa,0x00000708,0x00000709,0x0000071c,0x000200f8,0x00000709, + 0x0004003d,0x00000006,0x0000070a,0x000006e2,0x0006000c,0x00000006,0x0000070b,0x00000001, + 0x00000004,0x0000070a,0x0003003e,0x000006e2,0x0000070b,0x000300f7,0x00000711,0x00000000, + 0x000400fa,0x00000426,0x0000070c,0x00000711,0x000200f8,0x0000070c,0x0004003d,0x00000012, + 0x0000070e,0x00000705,0x000500c7,0x00000012,0x0000070f,0x0000070e,0x0000042b,0x000500ab, + 0x0000007d,0x00000710,0x0000070f,0x000000c8,0x000200f9,0x00000711,0x000200f8,0x00000711, + 0x000700f5,0x0000007d,0x00000712,0x00000426,0x00000709,0x00000710,0x0000070c,0x000300f7, + 0x0000071b,0x00000000,0x000400fa,0x00000712,0x00000713,0x0000071b,0x000200f8,0x00000713, + 0x0004003d,0x00000006,0x00000714,0x000006e2,0x00050085,0x00000006,0x00000715,0x00000714, + 0x000001fe,0x0006000c,0x00000006,0x00000716,0x00000001,0x0000000a,0x00000715,0x00050085, + 0x00000006,0x00000717,0x00000716,0x000001f7,0x00050081,0x00000006,0x00000718,0x00000717, + 0x00000435,0x0006000c,0x00000006,0x00000719,0x00000001,0x00000004,0x00000718,0x00050083, + 0x00000006,0x0000071a,0x0000010a,0x00000719,0x0003003e,0x000006e2,0x0000071a,0x000200f9, + 0x0000071b,0x000200f8,0x0000071b,0x000200f9,0x0000071c,0x000200f8,0x0000071c,0x0004003d, + 0x00000006,0x0000071d,0x000006e2,0x0003003e,0x000006e3,0x0000010b,0x0004003d,0x00000006, + 0x000007d6,0x000006e3,0x0003003e,0x000007d4,0x000007d6,0x0004003d,0x00000006,0x0000071e, + 0x000007d4,0x0003003e,0x000006e4,0x0000010a,0x0004003d,0x00000006,0x000007d9,0x000006e4, + 0x0003003e,0x000007d7,0x000007d9,0x0004003d,0x00000006,0x0000071f,0x000007d7,0x0008000c, + 0x00000006,0x00000720,0x00000001,0x0000002b,0x0000071d,0x0000071e,0x0000071f,0x0003003e, + 0x000006e2,0x00000720,0x000300f7,0x0000072f,0x00000000,0x000400fa,0x0000043f,0x00000721, + 0x0000072f,0x000200f8,0x00000721,0x0004003d,0x00000012,0x00000723,0x00000705,0x000500c2, + 0x00000012,0x00000724,0x00000723,0x00000445,0x0003003e,0x000006e5,0x00000724,0x0004003d, + 0x00000012,0x00000725,0x000006e5,0x000500ab,0x0000007d,0x00000726,0x00000725,0x000000c8, + 0x000300f7,0x0000072e,0x00000000,0x000400fa,0x00000726,0x00000727,0x0000072e,0x000200f8, + 0x00000727,0x0004003d,0x0000044b,0x00000728,0x0000044d,0x00050062,0x0000002f,0x00000729, + 0x00000728,0x0000044f,0x0004003d,0x00000012,0x0000072a,0x000006e5,0x0003003e,0x000006e6, + 0x0000072a,0x0003003e,0x000006e7,0x00000729,0x0004003d,0x00000006,0x0000072b,0x000006e2, + 0x0003003e,0x000006e8,0x0000072b,0x0004003d,0x0000002f,0x000007dc,0x000006e7,0x0007004f, + 0x0000000c,0x000007dd,0x000007dc,0x000007dc,0x00000000,0x00000001,0x0004003d,0x00000012, + 0x000007de,0x000006e6,0x0006000c,0x0000002f,0x000007df,0x00000001,0x00000040,0x000007de, + 0x0007004f,0x0000000c,0x000007e0,0x000007df,0x000007df,0x00000000,0x00000001,0x00050083, + 0x0000000c,0x000007e1,0x000007dd,0x000007e0,0x0006000c,0x0000000c,0x000007e2,0x00000001, + 0x00000004,0x000007e1,0x0003003e,0x000007da,0x00000403,0x0004003d,0x00000006,0x000007f0, + 0x000007da,0x00050041,0x00000007,0x000007f1,0x000007ed,0x000000c8,0x0003003e,0x000007f1, + 0x000007f0,0x0004003d,0x00000006,0x000007f2,0x000007da,0x00050041,0x00000007,0x000007f3, + 0x000007ed,0x000000cb,0x0003003e,0x000007f3,0x000007f2,0x0004003d,0x0000000c,0x000007f4, + 0x000007ed,0x0003003e,0x000007ee,0x000007f4,0x0004003d,0x0000000c,0x000007e3,0x000007ee, + 0x000500b8,0x00000406,0x000007e4,0x000007e2,0x000007e3,0x0004009b,0x0000007d,0x000007e5, + 0x000007e4,0x000300f7,0x000007ec,0x00000000,0x000400fa,0x000007e5,0x000007e6,0x000007eb, + 0x000200f8,0x000007e6,0x0004003d,0x00000006,0x000007e7,0x000006e8,0x00050041,0x00000007, + 0x000007e8,0x000006e7,0x000000de,0x0004003d,0x00000006,0x000007e9,0x000007e8,0x0007000c, + 0x00000006,0x000007ea,0x00000001,0x00000025,0x000007e7,0x000007e9,0x0003003e,0x000006e8, + 0x000007ea,0x000200f9,0x000007ec,0x000200f8,0x000007eb,0x0003003e,0x000006e8,0x0000010b, + 0x000200f9,0x000007ec,0x000200f8,0x000007ec,0x0004003d,0x00000006,0x0000072d,0x000006e8, + 0x0003003e,0x000006e2,0x0000072d,0x000200f9,0x0000072e,0x000200f8,0x0000072e,0x000200f9, + 0x0000072f,0x000200f8,0x0000072f,0x000300f7,0x00000735,0x00000000,0x000400fa,0x00000458, + 0x00000730,0x00000735,0x000200f8,0x00000730,0x0004003d,0x00000012,0x00000732,0x00000705, + 0x000500c7,0x00000012,0x00000733,0x00000732,0x0000045d,0x000500ab,0x0000007d,0x00000734, + 0x00000733,0x000000c8,0x000200f9,0x00000735,0x000200f8,0x00000735,0x000700f5,0x0000007d, + 0x00000736,0x00000458,0x0000072f,0x00000734,0x00000730,0x000300f7,0x0000075d,0x00000000, + 0x000400fa,0x00000736,0x00000737,0x0000075d,0x000200f8,0x00000737,0x0004003d,0x00000012, + 0x00000738,0x0000059c,0x00050084,0x00000012,0x00000739,0x00000738,0x0000046a,0x00050080, + 0x00000012,0x0000073a,0x00000739,0x000000de,0x00060041,0x0000046e,0x0000073b,0x00000468, + 0x00000282,0x0000073a,0x0004003d,0x0000002f,0x0000073c,0x0000073b,0x0003003e,0x000006ea, + 0x0000073c,0x0004003d,0x0000002f,0x000007f7,0x000006ea,0x0004003d,0x0000002f,0x000007f9, + 0x000006ea,0x00050051,0x00000006,0x000007fb,0x000007f7,0x00000000,0x00050051,0x00000006, + 0x000007fc,0x000007f7,0x00000001,0x00050051,0x00000006,0x000007fd,0x000007f9,0x00000002, + 0x00050051,0x00000006,0x000007fe,0x000007f9,0x00000003,0x00050050,0x0000000c,0x000007ff, + 0x000007fb,0x000007fc,0x00050050,0x0000000c,0x00000800,0x000007fd,0x000007fe,0x00050050, + 0x0000003c,0x00000801,0x000007ff,0x00000800,0x0003003e,0x000007f5,0x00000801,0x0004003d, + 0x0000003c,0x0000073d,0x000007f5,0x0003003e,0x000006e9,0x0000073d,0x0004003d,0x00000012, + 0x0000073e,0x0000059c,0x00050084,0x00000012,0x0000073f,0x0000073e,0x0000046a,0x00050080, + 0x00000012,0x00000740,0x0000073f,0x000000f5,0x00060041,0x0000046e,0x00000741,0x00000468, + 0x00000282,0x00000740,0x0004003d,0x0000002f,0x00000742,0x00000741,0x0003003e,0x000006eb, + 0x00000742,0x0004003d,0x0000003c,0x00000743,0x000006e9,0x00050091,0x0000000c,0x00000746, + 0x00000743,0x0000052b,0x0004003d,0x0000002f,0x00000747,0x000006eb,0x0007004f,0x0000000c, + 0x00000748,0x00000747,0x00000747,0x00000000,0x00000001,0x00050081,0x0000000c,0x00000749, + 0x00000746,0x00000748,0x0003003e,0x000006ec,0x00000749,0x0004003d,0x0000000c,0x0000074a, + 0x000006ec,0x0006000c,0x0000000c,0x0000074b,0x00000001,0x00000004,0x0000074a,0x0004003d, + 0x0000002f,0x0000074c,0x000006eb,0x0007004f,0x0000000c,0x0000074d,0x0000074c,0x0000074c, + 0x00000002,0x00000003,0x00050085,0x0000000c,0x0000074e,0x0000074b,0x0000074d,0x0004003d, + 0x0000002f,0x0000074f,0x000006eb,0x0007004f,0x0000000c,0x00000750,0x0000074f,0x0000074f, + 0x00000002,0x00000003,0x00050083,0x0000000c,0x00000751,0x0000074e,0x00000750,0x0003003e, + 0x000006ee,0x00000751,0x0004003d,0x0000000c,0x00000805,0x000006ee,0x0003003e,0x00000802, + 0x00000805,0x0004003d,0x0000000c,0x00000806,0x00000802,0x0003003e,0x00000803,0x00000806, + 0x0004003d,0x0000000c,0x00000752,0x00000803,0x0003003e,0x000006ed,0x00000752,0x00050041, + 0x00000007,0x00000753,0x000006ed,0x000000c8,0x0004003d,0x00000006,0x00000754,0x00000753, + 0x00050041,0x00000007,0x00000755,0x000006ed,0x000000cb,0x0004003d,0x00000006,0x00000756, + 0x00000755,0x0007000c,0x00000006,0x00000757,0x00000001,0x00000025,0x00000754,0x00000756, + 0x00050081,0x00000006,0x00000758,0x00000757,0x000001fe,0x0008000c,0x00000006,0x00000759, + 0x00000001,0x0000002b,0x00000758,0x0000010b,0x0000010a,0x0003003e,0x000006ef,0x00000759, + 0x0004003d,0x00000006,0x0000075a,0x000006e2,0x0004003d,0x00000006,0x0000075b,0x000006ef, + 0x0007000c,0x00000006,0x0000075c,0x00000001,0x00000025,0x0000075a,0x0000075b,0x0003003e, + 0x000006e2,0x0000075c,0x000200f9,0x0000075d,0x000200f8,0x0000075d,0x0004003d,0x00000012, + 0x0000075f,0x00000705,0x000500c7,0x00000012,0x00000760,0x0000075f,0x0000049b,0x0003003e, + 0x000006f0,0x00000760,0x0004003d,0x00000012,0x00000761,0x000006f0,0x000500b2,0x0000007d, + 0x00000762,0x00000761,0x000000cb,0x000300f7,0x000007a5,0x00000000,0x000400fa,0x00000762, + 0x00000763,0x00000776,0x000200f8,0x00000763,0x00050041,0x00000013,0x00000764,0x000006e1, + 0x000000cb,0x0004003d,0x00000012,0x00000765,0x00000764,0x0006000c,0x0000002f,0x00000766, + 0x00000001,0x00000040,0x00000765,0x0003003e,0x000005a0,0x00000766,0x0004003d,0x00000012, + 0x00000767,0x000006f0,0x000500aa,0x0000007d,0x00000768,0x00000767,0x000000c8,0x000500a7, + 0x0000007d,0x00000769,0x0000043f,0x00000768,0x000300f7,0x00000775,0x00000000,0x000400fa, + 0x00000769,0x0000076a,0x00000775,0x000200f8,0x0000076a,0x0004003d,0x0000002f,0x0000076b, + 0x000005a0,0x00050041,0x00000007,0x0000076d,0x000005a1,0x000000c8,0x00050051,0x00000006, + 0x0000076e,0x0000076b,0x00000002,0x0003003e,0x0000076d,0x0000076e,0x00050041,0x00000007, + 0x0000076f,0x000005a1,0x000000cb,0x00050051,0x00000006,0x00000770,0x0000076b,0x00000003, + 0x0003003e,0x0000076f,0x00000770,0x0004003d,0x00000006,0x00000771,0x000006e2,0x00050041, + 0x00000007,0x00000772,0x000005a1,0x000000de,0x0003003e,0x00000772,0x00000771,0x00050041, + 0x00000007,0x00000773,0x000005a1,0x000000f5,0x0003003e,0x00000773,0x0000010a,0x0003003e, + 0x000006f1,0x0000010b,0x0004003d,0x00000006,0x0000080a,0x000006f1,0x00050041,0x00000007, + 0x0000080b,0x00000807,0x000000c8,0x0003003e,0x0000080b,0x0000080a,0x0004003d,0x00000006, + 0x0000080c,0x000006f1,0x00050041,0x00000007,0x0000080d,0x00000807,0x000000cb,0x0003003e, + 0x0000080d,0x0000080c,0x0004003d,0x00000006,0x0000080e,0x000006f1,0x00050041,0x00000007, + 0x0000080f,0x00000807,0x000000de,0x0003003e,0x0000080f,0x0000080e,0x0004003d,0x00000006, + 0x00000810,0x000006f1,0x00050041,0x00000007,0x00000811,0x00000807,0x000000f5,0x0003003e, + 0x00000811,0x00000810,0x0004003d,0x0000002f,0x00000812,0x00000807,0x0003003e,0x00000808, + 0x00000812,0x0004003d,0x0000002f,0x00000774,0x00000808,0x0003003e,0x000005a0,0x00000774, + 0x000200f9,0x00000775,0x000200f8,0x00000775,0x000200f9,0x000007a5,0x000200f8,0x00000776, + 0x0004003d,0x00000012,0x00000777,0x0000059c,0x00050084,0x00000012,0x00000778,0x00000777, + 0x0000046a,0x00060041,0x0000046e,0x00000779,0x00000468,0x00000282,0x00000778,0x0004003d, + 0x0000002f,0x0000077a,0x00000779,0x0003003e,0x000006f3,0x0000077a,0x0004003d,0x0000002f, + 0x00000815,0x000006f3,0x0004003d,0x0000002f,0x00000817,0x000006f3,0x00050051,0x00000006, + 0x00000819,0x00000815,0x00000000,0x00050051,0x00000006,0x0000081a,0x00000815,0x00000001, + 0x00050051,0x00000006,0x0000081b,0x00000817,0x00000002,0x00050051,0x00000006,0x0000081c, + 0x00000817,0x00000003,0x00050050,0x0000000c,0x0000081d,0x00000819,0x0000081a,0x00050050, + 0x0000000c,0x0000081e,0x0000081b,0x0000081c,0x00050050,0x0000003c,0x0000081f,0x0000081d, + 0x0000081e,0x0003003e,0x00000813,0x0000081f,0x0004003d,0x0000003c,0x0000077b,0x00000813, + 0x0003003e,0x000006f2,0x0000077b,0x0004003d,0x00000012,0x0000077c,0x0000059c,0x00050084, + 0x00000012,0x0000077d,0x0000077c,0x0000046a,0x00050080,0x00000012,0x0000077e,0x0000077d, + 0x000000cb,0x00060041,0x0000046e,0x0000077f,0x00000468,0x00000282,0x0000077e,0x0004003d, + 0x0000002f,0x00000780,0x0000077f,0x0003003e,0x000006f4,0x00000780,0x0004003d,0x0000003c, + 0x00000781,0x000006f2,0x00050091,0x0000000c,0x00000784,0x00000781,0x0000052b,0x0004003d, + 0x0000002f,0x00000785,0x000006f4,0x0007004f,0x0000000c,0x00000786,0x00000785,0x00000785, + 0x00000000,0x00000001,0x00050081,0x0000000c,0x00000787,0x00000784,0x00000786,0x0003003e, + 0x000006f5,0x00000787,0x0004003d,0x00000012,0x00000788,0x000006f0,0x000500aa,0x0000007d, + 0x00000789,0x00000788,0x000000de,0x000300f7,0x00000790,0x00000000,0x000400fa,0x00000789, + 0x0000078a,0x0000078d,0x000200f8,0x0000078a,0x00050041,0x00000007,0x0000078b,0x000006f5, + 0x000000c8,0x0004003d,0x00000006,0x0000078c,0x0000078b,0x0003003e,0x000006f7,0x0000078c, + 0x000200f9,0x00000790,0x000200f8,0x0000078d,0x0004003d,0x0000000c,0x0000078e,0x000006f5, + 0x0006000c,0x00000006,0x0000078f,0x00000001,0x00000042,0x0000078e,0x0003003e,0x000006f7, + 0x0000078f,0x000200f9,0x00000790,0x000200f8,0x00000790,0x0004003d,0x00000006,0x00000791, + 0x000006f7,0x0003003e,0x000006f6,0x00000791,0x0004003d,0x00000006,0x00000792,0x000006f6, + 0x0008000c,0x00000006,0x00000793,0x00000001,0x0000002b,0x00000792,0x0000010b,0x0000010a, + 0x0003003e,0x000006f6,0x00000793,0x0004003d,0x00000006,0x00000794,0x000006f6,0x00050041, + 0x00000007,0x00000795,0x000006f4,0x000000de,0x0004003d,0x00000006,0x00000796,0x00000795, + 0x00050085,0x00000006,0x00000797,0x00000794,0x00000796,0x00050041,0x00000007,0x00000798, + 0x000006f4,0x000000f5,0x0004003d,0x00000006,0x00000799,0x00000798,0x00050081,0x00000006, + 0x0000079a,0x00000797,0x00000799,0x0003003e,0x000006f8,0x0000079a,0x00050041,0x00000013, + 0x0000079b,0x000006e1,0x000000cb,0x0004003d,0x00000012,0x0000079c,0x0000079b,0x0004007c, + 0x00000006,0x0000079d,0x0000079c,0x0003003e,0x000006f9,0x0000079d,0x0004003d,0x00000341, + 0x0000079e,0x000004e4,0x0004003d,0x00000345,0x0000079f,0x000004e6,0x00050056,0x00000349, + 0x000007a0,0x0000079e,0x0000079f,0x0004003d,0x00000006,0x000007a1,0x000006f8,0x0004003d, + 0x00000006,0x000007a2,0x000006f9,0x00050050,0x0000000c,0x000007a3,0x000007a1,0x000007a2, + 0x00070058,0x0000002f,0x000007a4,0x000007a0,0x000007a3,0x00000002,0x0000010b,0x0003003e, + 0x000005a0,0x000007a4,0x000200f9,0x000007a5,0x000200f8,0x000007a5,0x0004003d,0x00000006, + 0x000007a6,0x000006e2,0x00050041,0x00000007,0x000007a7,0x000005a0,0x000000f5,0x0004003d, + 0x00000006,0x000007a8,0x000007a7,0x00050085,0x00000006,0x000007a9,0x000007a8,0x000007a6, + 0x0003003e,0x000007a7,0x000007a9,0x000300f7,0x000007af,0x00000000,0x000400fa,0x000004f2, + 0x000007ab,0x000007af,0x000200f8,0x000007ab,0x0004003d,0x00000006,0x000007ad,0x000007a7, + 0x000500b7,0x0000007d,0x000007ae,0x000007ad,0x0000010b,0x000200f9,0x000007af,0x000200f8, + 0x000007af,0x000700f5,0x0000007d,0x000007b0,0x000004f2,0x000007a5,0x000007ae,0x000007ab, + 0x000300f7,0x000007b8,0x00000000,0x000400fa,0x000007b0,0x000007b1,0x000007b8,0x000200f8, + 0x000007b1,0x0004003d,0x00000012,0x000007b3,0x00000705,0x000500c2,0x00000012,0x000007b4, + 0x000007b3,0x000004fe,0x000500c7,0x00000012,0x000007b5,0x000007b4,0x0000049b,0x0003003e, + 0x000006fb,0x000007b5,0x0004003d,0x00000012,0x00000823,0x000006fb,0x0003003e,0x00000820, + 0x00000823,0x0004003d,0x00000012,0x00000824,0x00000820,0x0003003e,0x00000821,0x00000824, + 0x0004003d,0x00000012,0x000007b6,0x00000821,0x0003003e,0x000006fa,0x000007b6,0x000500ab, + 0x0000007d,0x000007b7,0x000007b6,0x000000c8,0x000200f9,0x000007b8,0x000200f8,0x000007b8, + 0x000700f5,0x0000007d,0x000007b9,0x000007b0,0x000007af,0x000007b7,0x000007b1,0x000300f7, + 0x000007c8,0x00000000,0x000400fa,0x000007b9,0x000007ba,0x000007c8,0x000200f8,0x000007ba, + 0x0004003d,0x0000044b,0x000007bb,0x00000508,0x00050062,0x0000002f,0x000007bc,0x000007bb, + 0x0000044f,0x0003003e,0x000006fc,0x000007bc,0x0004003d,0x0000002f,0x000007bd,0x000005a0, + 0x0008004f,0x00000024,0x000007be,0x000007bd,0x000007bd,0x00000000,0x00000001,0x00000002, + 0x0003003e,0x000006fd,0x000007be,0x0004003d,0x0000002f,0x000007bf,0x000006fc,0x0003003e, + 0x000006fe,0x000007bf,0x0004003d,0x00000012,0x000007c0,0x000006fa,0x0003003e,0x000006ff, + 0x000007c0,0x0004003d,0x00000024,0x0000082c,0x000006fd,0x0003003e,0x00000826,0x0000082c, + 0x0004003d,0x0000002f,0x0000082d,0x000006fe,0x0003003e,0x00000827,0x0000082d,0x0004003d, + 0x00000012,0x0000082e,0x000006ff,0x0003003e,0x00000828,0x0000082e,0x0004003d,0x0000002f, + 0x0000085e,0x00000827,0x0003003e,0x00000837,0x0000085e,0x0004003d,0x0000002f,0x0000095a, + 0x00000837,0x0008004f,0x00000024,0x0000095b,0x0000095a,0x0000095a,0x00000000,0x00000001, + 0x00000002,0x00050041,0x00000007,0x0000095c,0x00000837,0x000000f5,0x0004003d,0x00000006, + 0x0000095d,0x0000095c,0x000500b7,0x0000007d,0x0000095e,0x0000095d,0x0000010b,0x000300f7, + 0x00000964,0x00000000,0x000400fa,0x0000095e,0x0000095f,0x00000963,0x000200f8,0x0000095f, + 0x0004003d,0x00000006,0x00000961,0x0000095c,0x00050088,0x00000006,0x00000962,0x0000010a, + 0x00000961,0x0003003e,0x00000957,0x00000962,0x000200f9,0x00000964,0x000200f8,0x00000963, + 0x0003003e,0x00000957,0x0000010b,0x000200f9,0x00000964,0x000200f8,0x00000964,0x0004003d, + 0x00000006,0x00000965,0x00000957,0x0005008e,0x00000024,0x00000966,0x0000095b,0x00000965, + 0x0003003e,0x00000958,0x00000966,0x0004003d,0x00000024,0x0000085f,0x00000958,0x0003003e, + 0x00000836,0x0000085f,0x0004003d,0x00000012,0x00000860,0x00000828,0x000300f7,0x00000955, + 0x00000000,0x002100fb,0x00000860,0x00000955,0x0000000b,0x00000861,0x00000001,0x00000865, + 0x00000002,0x0000086d,0x00000003,0x0000087d,0x00000004,0x00000881,0x00000005,0x00000885, + 0x00000006,0x000008a7,0x00000007,0x000008d3,0x00000008,0x000008e3,0x00000009,0x0000091d, + 0x0000000a,0x00000922,0x0000000c,0x0000092b,0x0000000d,0x00000936,0x0000000e,0x00000941, + 0x0000000f,0x0000094b,0x000200f8,0x00000861,0x0004003d,0x00000024,0x00000862,0x00000826, + 0x0004003d,0x00000024,0x00000863,0x00000836,0x00050085,0x00000024,0x00000864,0x00000862, + 0x00000863,0x0003003e,0x00000838,0x00000864,0x000200f9,0x00000955,0x000200f8,0x00000865, + 0x0004003d,0x00000024,0x00000866,0x00000826,0x0004003d,0x00000024,0x00000867,0x00000836, + 0x00050081,0x00000024,0x00000868,0x00000866,0x00000867,0x0004003d,0x00000024,0x00000869, + 0x00000826,0x0004003d,0x00000024,0x0000086a,0x00000836,0x00050085,0x00000024,0x0000086b, + 0x00000869,0x0000086a,0x00050083,0x00000024,0x0000086c,0x00000868,0x0000086b,0x0003003e, + 0x00000838,0x0000086c,0x000200f9,0x00000955,0x000200f8,0x0000086d,0x0004003d,0x00000024, + 0x0000086e,0x00000826,0x0004003d,0x00000024,0x0000086f,0x00000836,0x00050085,0x00000024, + 0x00000870,0x0000086e,0x0000086f,0x0003003e,0x00000839,0x00000870,0x0004003d,0x00000024, + 0x00000871,0x00000839,0x0004003d,0x00000024,0x00000872,0x00000826,0x0004003d,0x00000024, + 0x00000873,0x00000836,0x00050081,0x00000024,0x00000874,0x00000872,0x00000873,0x0004003d, + 0x00000024,0x00000875,0x00000839,0x00050083,0x00000024,0x00000876,0x00000874,0x00000875, + 0x00050083,0x00000024,0x00000877,0x00000876,0x000005d4,0x0004003d,0x00000024,0x00000878, + 0x00000836,0x0003003e,0x0000083a,0x000001fe,0x0004003d,0x00000006,0x0000096a,0x0000083a, + 0x00050041,0x00000007,0x0000096b,0x00000967,0x000000c8,0x0003003e,0x0000096b,0x0000096a, + 0x0004003d,0x00000006,0x0000096c,0x0000083a,0x00050041,0x00000007,0x0000096d,0x00000967, + 0x000000cb,0x0003003e,0x0000096d,0x0000096c,0x0004003d,0x00000006,0x0000096e,0x0000083a, + 0x00050041,0x00000007,0x0000096f,0x00000967,0x000000de,0x0003003e,0x0000096f,0x0000096e, + 0x0004003d,0x00000024,0x00000970,0x00000967,0x0003003e,0x00000968,0x00000970,0x0004003d, + 0x00000024,0x00000879,0x00000968,0x000500ba,0x00000204,0x0000087a,0x00000878,0x00000879, + 0x000600a9,0x00000024,0x0000087b,0x0000087a,0x00000877,0x00000871,0x0005008e,0x00000024, + 0x0000087c,0x0000087b,0x000001f7,0x0003003e,0x00000838,0x0000087c,0x000200f9,0x00000955, + 0x000200f8,0x0000087d,0x0004003d,0x00000024,0x0000087e,0x00000826,0x0004003d,0x00000024, + 0x0000087f,0x00000836,0x0007000c,0x00000024,0x00000880,0x00000001,0x00000025,0x0000087e, + 0x0000087f,0x0003003e,0x00000838,0x00000880,0x000200f9,0x00000955,0x000200f8,0x00000881, + 0x0004003d,0x00000024,0x00000882,0x00000826,0x0004003d,0x00000024,0x00000883,0x00000836, + 0x0007000c,0x00000024,0x00000884,0x00000001,0x00000028,0x00000882,0x00000883,0x0003003e, + 0x00000838,0x00000884,0x000200f9,0x00000955,0x000200f8,0x00000885,0x0004003d,0x0000002f, + 0x00000886,0x00000827,0x0008004f,0x00000024,0x00000887,0x00000886,0x00000886,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x0000083b,0x0000010b,0x0004003d,0x00000006,0x00000974, + 0x0000083b,0x00050041,0x00000007,0x00000975,0x00000971,0x000000c8,0x0003003e,0x00000975, + 0x00000974,0x0004003d,0x00000006,0x00000976,0x0000083b,0x00050041,0x00000007,0x00000977, + 0x00000971,0x000000cb,0x0003003e,0x00000977,0x00000976,0x0004003d,0x00000006,0x00000978, + 0x0000083b,0x00050041,0x00000007,0x00000979,0x00000971,0x000000de,0x0003003e,0x00000979, + 0x00000978,0x0004003d,0x00000024,0x0000097a,0x00000971,0x0003003e,0x00000972,0x0000097a, + 0x0004003d,0x00000024,0x00000888,0x00000972,0x0004003d,0x0000002f,0x00000889,0x00000827, + 0x0008004f,0x00000024,0x0000088a,0x00000889,0x00000889,0x00000003,0x00000003,0x00000003, + 0x0008000c,0x00000024,0x0000088b,0x00000001,0x0000002b,0x00000887,0x00000888,0x0000088a, + 0x00050041,0x00000007,0x0000088c,0x00000827,0x000000c8,0x00050051,0x00000006,0x0000088d, + 0x0000088b,0x00000000,0x0003003e,0x0000088c,0x0000088d,0x00050041,0x00000007,0x0000088e, + 0x00000827,0x000000cb,0x00050051,0x00000006,0x0000088f,0x0000088b,0x00000001,0x0003003e, + 0x0000088e,0x0000088f,0x00050041,0x00000007,0x00000890,0x00000827,0x000000de,0x00050051, + 0x00000006,0x00000891,0x0000088b,0x00000002,0x0003003e,0x00000890,0x00000891,0x0004003d, + 0x00000024,0x00000892,0x00000826,0x00050083,0x00000024,0x00000893,0x000005d3,0x00000892, + 0x0003003e,0x0000083d,0x0000010b,0x0004003d,0x00000006,0x0000097e,0x0000083d,0x00050041, + 0x00000007,0x0000097f,0x0000097b,0x000000c8,0x0003003e,0x0000097f,0x0000097e,0x0004003d, + 0x00000006,0x00000980,0x0000083d,0x00050041,0x00000007,0x00000981,0x0000097b,0x000000cb, + 0x0003003e,0x00000981,0x00000980,0x0004003d,0x00000006,0x00000982,0x0000083d,0x00050041, + 0x00000007,0x00000983,0x0000097b,0x000000de,0x0003003e,0x00000983,0x00000982,0x0004003d, + 0x00000024,0x00000984,0x0000097b,0x0003003e,0x0000097c,0x00000984,0x0004003d,0x00000024, + 0x00000894,0x0000097c,0x0003003e,0x0000083e,0x0000010a,0x0004003d,0x00000006,0x00000988, + 0x0000083e,0x00050041,0x00000007,0x00000989,0x00000985,0x000000c8,0x0003003e,0x00000989, + 0x00000988,0x0004003d,0x00000006,0x0000098a,0x0000083e,0x00050041,0x00000007,0x0000098b, + 0x00000985,0x000000cb,0x0003003e,0x0000098b,0x0000098a,0x0004003d,0x00000006,0x0000098c, + 0x0000083e,0x00050041,0x00000007,0x0000098d,0x00000985,0x000000de,0x0003003e,0x0000098d, + 0x0000098c,0x0004003d,0x00000024,0x0000098e,0x00000985,0x0003003e,0x00000986,0x0000098e, + 0x0004003d,0x00000024,0x00000895,0x00000986,0x0008000c,0x00000024,0x00000896,0x00000001, + 0x0000002b,0x00000893,0x00000894,0x00000895,0x00050041,0x00000007,0x00000897,0x00000827, + 0x000000f5,0x0004003d,0x00000006,0x00000898,0x00000897,0x0005008e,0x00000024,0x00000899, + 0x00000896,0x00000898,0x0003003e,0x0000083c,0x00000899,0x0003003e,0x0000083f,0x0000010a, + 0x0004003d,0x00000006,0x00000992,0x0000083f,0x00050041,0x00000007,0x00000993,0x0000098f, + 0x000000c8,0x0003003e,0x00000993,0x00000992,0x0004003d,0x00000006,0x00000994,0x0000083f, + 0x00050041,0x00000007,0x00000995,0x0000098f,0x000000cb,0x0003003e,0x00000995,0x00000994, + 0x0004003d,0x00000006,0x00000996,0x0000083f,0x00050041,0x00000007,0x00000997,0x0000098f, + 0x000000de,0x0003003e,0x00000997,0x00000996,0x0004003d,0x00000024,0x00000998,0x0000098f, + 0x0003003e,0x00000990,0x00000998,0x0004003d,0x00000024,0x0000089a,0x00000990,0x0004003d, + 0x0000002f,0x0000089b,0x00000827,0x0008004f,0x00000024,0x0000089c,0x0000089b,0x0000089b, + 0x00000000,0x00000001,0x00000002,0x0004003d,0x00000024,0x0000089d,0x0000083c,0x00050088, + 0x00000024,0x0000089e,0x0000089c,0x0000089d,0x0007000c,0x00000024,0x0000089f,0x00000001, + 0x00000025,0x0000089a,0x0000089e,0x0004003d,0x0000002f,0x000008a0,0x00000827,0x0008004f, + 0x00000024,0x000008a1,0x000008a0,0x000008a0,0x00000000,0x00000001,0x00000002,0x0006000c, + 0x00000024,0x000008a2,0x00000001,0x00000006,0x000008a1,0x0004003d,0x00000024,0x000008a3, + 0x0000083c,0x0003003e,0x00000840,0x0000010b,0x0004003d,0x00000006,0x0000099c,0x00000840, + 0x00050041,0x00000007,0x0000099d,0x00000999,0x000000c8,0x0003003e,0x0000099d,0x0000099c, + 0x0004003d,0x00000006,0x0000099e,0x00000840,0x00050041,0x00000007,0x0000099f,0x00000999, + 0x000000cb,0x0003003e,0x0000099f,0x0000099e,0x0004003d,0x00000006,0x000009a0,0x00000840, + 0x00050041,0x00000007,0x000009a1,0x00000999,0x000000de,0x0003003e,0x000009a1,0x000009a0, + 0x0004003d,0x00000024,0x000009a2,0x00000999,0x0003003e,0x0000099a,0x000009a2,0x0004003d, + 0x00000024,0x000008a4,0x0000099a,0x000500b4,0x00000204,0x000008a5,0x000008a3,0x000008a4, + 0x000600a9,0x00000024,0x000008a6,0x000008a5,0x000008a2,0x0000089f,0x0003003e,0x00000838, + 0x000008a6,0x000200f9,0x00000955,0x000200f8,0x000008a7,0x0004003d,0x00000024,0x000008a8, + 0x00000826,0x0003003e,0x00000841,0x0000010b,0x0004003d,0x00000006,0x000009a6,0x00000841, + 0x00050041,0x00000007,0x000009a7,0x000009a3,0x000000c8,0x0003003e,0x000009a7,0x000009a6, + 0x0004003d,0x00000006,0x000009a8,0x00000841,0x00050041,0x00000007,0x000009a9,0x000009a3, + 0x000000cb,0x0003003e,0x000009a9,0x000009a8,0x0004003d,0x00000006,0x000009aa,0x00000841, + 0x00050041,0x00000007,0x000009ab,0x000009a3,0x000000de,0x0003003e,0x000009ab,0x000009aa, + 0x0004003d,0x00000024,0x000009ac,0x000009a3,0x0003003e,0x000009a4,0x000009ac,0x0004003d, + 0x00000024,0x000008a9,0x000009a4,0x0003003e,0x00000842,0x0000010a,0x0004003d,0x00000006, + 0x000009b0,0x00000842,0x00050041,0x00000007,0x000009b1,0x000009ad,0x000000c8,0x0003003e, + 0x000009b1,0x000009b0,0x0004003d,0x00000006,0x000009b2,0x00000842,0x00050041,0x00000007, + 0x000009b3,0x000009ad,0x000000cb,0x0003003e,0x000009b3,0x000009b2,0x0004003d,0x00000006, + 0x000009b4,0x00000842,0x00050041,0x00000007,0x000009b5,0x000009ad,0x000000de,0x0003003e, + 0x000009b5,0x000009b4,0x0004003d,0x00000024,0x000009b6,0x000009ad,0x0003003e,0x000009ae, + 0x000009b6,0x0004003d,0x00000024,0x000008aa,0x000009ae,0x0008000c,0x00000024,0x000008ab, + 0x00000001,0x0000002b,0x000008a8,0x000008a9,0x000008aa,0x0003003e,0x00000826,0x000008ab, + 0x0004003d,0x0000002f,0x000008ac,0x00000827,0x0008004f,0x00000024,0x000008ad,0x000008ac, + 0x000008ac,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000843,0x0000010b,0x0004003d, + 0x00000006,0x000009ba,0x00000843,0x00050041,0x00000007,0x000009bb,0x000009b7,0x000000c8, + 0x0003003e,0x000009bb,0x000009ba,0x0004003d,0x00000006,0x000009bc,0x00000843,0x00050041, + 0x00000007,0x000009bd,0x000009b7,0x000000cb,0x0003003e,0x000009bd,0x000009bc,0x0004003d, + 0x00000006,0x000009be,0x00000843,0x00050041,0x00000007,0x000009bf,0x000009b7,0x000000de, + 0x0003003e,0x000009bf,0x000009be,0x0004003d,0x00000024,0x000009c0,0x000009b7,0x0003003e, + 0x000009b8,0x000009c0,0x0004003d,0x00000024,0x000008ae,0x000009b8,0x0004003d,0x0000002f, + 0x000008af,0x00000827,0x0008004f,0x00000024,0x000008b0,0x000008af,0x000008af,0x00000003, + 0x00000003,0x00000003,0x0008000c,0x00000024,0x000008b1,0x00000001,0x0000002b,0x000008ad, + 0x000008ae,0x000008b0,0x00050041,0x00000007,0x000008b2,0x00000827,0x000000c8,0x00050051, + 0x00000006,0x000008b3,0x000008b1,0x00000000,0x0003003e,0x000008b2,0x000008b3,0x00050041, + 0x00000007,0x000008b4,0x00000827,0x000000cb,0x00050051,0x00000006,0x000008b5,0x000008b1, + 0x00000001,0x0003003e,0x000008b4,0x000008b5,0x00050041,0x00000007,0x000008b6,0x00000827, + 0x000000de,0x00050051,0x00000006,0x000008b7,0x000008b1,0x00000002,0x0003003e,0x000008b6, + 0x000008b7,0x00050041,0x00000007,0x000008b8,0x00000827,0x000000f5,0x0004003d,0x00000006, + 0x000008b9,0x000008b8,0x000500b4,0x0000007d,0x000008ba,0x000008b9,0x0000010b,0x000300f7, + 0x000008bd,0x00000000,0x000400fa,0x000008ba,0x000008bb,0x000008bd,0x000200f8,0x000008bb, + 0x0003003e,0x000008b8,0x0000010a,0x000200f9,0x000008bd,0x000200f8,0x000008bd,0x0004003d, + 0x00000006,0x000008bf,0x000008b8,0x0004003d,0x0000002f,0x000008c0,0x00000827,0x0008004f, + 0x00000024,0x000008c1,0x000008c0,0x000008c0,0x00000000,0x00000001,0x00000002,0x00060050, + 0x00000024,0x000008c2,0x000008bf,0x000008bf,0x000008bf,0x00050083,0x00000024,0x000008c3, + 0x000008c2,0x000008c1,0x0003003e,0x00000844,0x000008c3,0x0003003e,0x00000845,0x0000010a, + 0x0004003d,0x00000006,0x000009c4,0x00000845,0x00050041,0x00000007,0x000009c5,0x000009c1, + 0x000000c8,0x0003003e,0x000009c5,0x000009c4,0x0004003d,0x00000006,0x000009c6,0x00000845, + 0x00050041,0x00000007,0x000009c7,0x000009c1,0x000000cb,0x0003003e,0x000009c7,0x000009c6, + 0x0004003d,0x00000006,0x000009c8,0x00000845,0x00050041,0x00000007,0x000009c9,0x000009c1, + 0x000000de,0x0003003e,0x000009c9,0x000009c8,0x0004003d,0x00000024,0x000009ca,0x000009c1, + 0x0003003e,0x000009c2,0x000009ca,0x0004003d,0x00000024,0x000008c4,0x000009c2,0x0004003d, + 0x00000024,0x000008c5,0x00000844,0x0004003d,0x00000024,0x000008c6,0x00000826,0x0004003d, + 0x00000006,0x000008c8,0x000008b8,0x0005008e,0x00000024,0x000008c9,0x000008c6,0x000008c8, + 0x00050088,0x00000024,0x000008ca,0x000008c5,0x000008c9,0x0007000c,0x00000024,0x000008cb, + 0x00000001,0x00000025,0x000008c4,0x000008ca,0x0004003d,0x00000024,0x000008cc,0x00000844, + 0x0006000c,0x00000024,0x000008cd,0x00000001,0x00000006,0x000008cc,0x0004003d,0x00000024, + 0x000008ce,0x00000826,0x0003003e,0x00000846,0x0000010b,0x0004003d,0x00000006,0x000009ce, + 0x00000846,0x00050041,0x00000007,0x000009cf,0x000009cb,0x000000c8,0x0003003e,0x000009cf, + 0x000009ce,0x0004003d,0x00000006,0x000009d0,0x00000846,0x00050041,0x00000007,0x000009d1, + 0x000009cb,0x000000cb,0x0003003e,0x000009d1,0x000009d0,0x0004003d,0x00000006,0x000009d2, + 0x00000846,0x00050041,0x00000007,0x000009d3,0x000009cb,0x000000de,0x0003003e,0x000009d3, + 0x000009d2,0x0004003d,0x00000024,0x000009d4,0x000009cb,0x0003003e,0x000009cc,0x000009d4, + 0x0004003d,0x00000024,0x000008cf,0x000009cc,0x000500b4,0x00000204,0x000008d0,0x000008ce, + 0x000008cf,0x000600a9,0x00000024,0x000008d1,0x000008d0,0x000008cd,0x000008cb,0x00050083, + 0x00000024,0x000008d2,0x000005d3,0x000008d1,0x0003003e,0x00000838,0x000008d2,0x000200f9, + 0x00000955,0x000200f8,0x000008d3,0x0004003d,0x00000024,0x000008d4,0x00000826,0x0004003d, + 0x00000024,0x000008d5,0x00000836,0x00050085,0x00000024,0x000008d6,0x000008d4,0x000008d5, + 0x0003003e,0x00000847,0x000008d6,0x0004003d,0x00000024,0x000008d7,0x00000847,0x0004003d, + 0x00000024,0x000008d8,0x00000826,0x0004003d,0x00000024,0x000008d9,0x00000836,0x00050081, + 0x00000024,0x000008da,0x000008d8,0x000008d9,0x0004003d,0x00000024,0x000008db,0x00000847, + 0x00050083,0x00000024,0x000008dc,0x000008da,0x000008db,0x00050083,0x00000024,0x000008dd, + 0x000008dc,0x000005d4,0x0004003d,0x00000024,0x000008de,0x00000826,0x0003003e,0x00000848, + 0x000001fe,0x0004003d,0x00000006,0x000009d8,0x00000848,0x00050041,0x00000007,0x000009d9, + 0x000009d5,0x000000c8,0x0003003e,0x000009d9,0x000009d8,0x0004003d,0x00000006,0x000009da, + 0x00000848,0x00050041,0x00000007,0x000009db,0x000009d5,0x000000cb,0x0003003e,0x000009db, + 0x000009da,0x0004003d,0x00000006,0x000009dc,0x00000848,0x00050041,0x00000007,0x000009dd, + 0x000009d5,0x000000de,0x0003003e,0x000009dd,0x000009dc,0x0004003d,0x00000024,0x000009de, + 0x000009d5,0x0003003e,0x000009d6,0x000009de,0x0004003d,0x00000024,0x000008df,0x000009d6, + 0x000500ba,0x00000204,0x000008e0,0x000008de,0x000008df,0x000600a9,0x00000024,0x000008e1, + 0x000008e0,0x000008dd,0x000008d7,0x0005008e,0x00000024,0x000008e2,0x000008e1,0x000001f7, + 0x0003003e,0x00000838,0x000008e2,0x000200f9,0x00000955,0x000200f8,0x000008e3,0x0003003e, + 0x00000849,0x00000282,0x000200f9,0x000008e4,0x000200f8,0x000008e4,0x0004003d,0x000000a0, + 0x000008e6,0x00000849,0x000500b1,0x0000007d,0x000008e7,0x000008e6,0x00000289,0x000400f6, + 0x00000913,0x00000910,0x00000000,0x000400fa,0x000008e7,0x000008e8,0x00000913,0x000200f8, + 0x000008e8,0x0004003d,0x000000a0,0x000008e9,0x00000849,0x00050041,0x00000007,0x000008ea, + 0x00000826,0x000008e9,0x0004003d,0x00000006,0x000008eb,0x000008ea,0x000500bc,0x0000007d, + 0x000008ec,0x000008eb,0x000001fe,0x000300f7,0x0000090f,0x00000000,0x000400fa,0x000008ec, + 0x000008ed,0x000008f4,0x000200f8,0x000008ed,0x0004003d,0x000000a0,0x000008ee,0x00000849, + 0x0004003d,0x000000a0,0x000008ef,0x00000849,0x00050041,0x00000007,0x000008f0,0x00000836, + 0x000008ef,0x0004003d,0x00000006,0x000008f1,0x000008f0,0x00050083,0x00000006,0x000008f2, + 0x0000010a,0x000008f1,0x00050041,0x00000007,0x000008f3,0x00000838,0x000008ee,0x0003003e, + 0x000008f3,0x000008f2,0x000200f9,0x0000090f,0x000200f8,0x000008f4,0x0004003d,0x000000a0, + 0x000008f5,0x00000849,0x00050041,0x00000007,0x000008f6,0x00000836,0x000008f5,0x0004003d, + 0x00000006,0x000008f7,0x000008f6,0x000500bc,0x0000007d,0x000008f8,0x000008f7,0x0000029b, + 0x000300f7,0x0000090e,0x00000000,0x000400fa,0x000008f8,0x000008f9,0x00000906,0x000200f8, + 0x000008f9,0x0004003d,0x000000a0,0x000008fa,0x00000849,0x0004003d,0x000000a0,0x000008fb, + 0x00000849,0x00050041,0x00000007,0x000008fc,0x00000836,0x000008fb,0x0004003d,0x00000006, + 0x000008fd,0x000008fc,0x00050085,0x00000006,0x000008fe,0x000002a0,0x000008fd,0x00050083, + 0x00000006,0x000008ff,0x000008fe,0x000002a5,0x0004003d,0x000000a0,0x00000900,0x00000849, + 0x00050041,0x00000007,0x00000901,0x00000836,0x00000900,0x0004003d,0x00000006,0x00000902, + 0x00000901,0x00050085,0x00000006,0x00000903,0x000008ff,0x00000902,0x00050081,0x00000006, + 0x00000904,0x00000903,0x000002ab,0x00050041,0x00000007,0x00000905,0x00000838,0x000008fa, + 0x0003003e,0x00000905,0x00000904,0x000200f9,0x0000090e,0x000200f8,0x00000906,0x0004003d, + 0x000000a0,0x00000907,0x00000849,0x0004003d,0x000000a0,0x00000908,0x00000849,0x00050041, + 0x00000007,0x00000909,0x00000836,0x00000908,0x0004003d,0x00000006,0x0000090a,0x00000909, + 0x0006000c,0x00000006,0x0000090b,0x00000001,0x00000020,0x0000090a,0x00050083,0x00000006, + 0x0000090c,0x0000090b,0x0000010a,0x00050041,0x00000007,0x0000090d,0x00000838,0x00000907, + 0x0003003e,0x0000090d,0x0000090c,0x000200f9,0x0000090e,0x000200f8,0x0000090e,0x000200f9, + 0x0000090f,0x000200f8,0x0000090f,0x000200f9,0x00000910,0x000200f8,0x00000910,0x0004003d, + 0x000000a0,0x00000911,0x00000849,0x00050080,0x000000a0,0x00000912,0x00000911,0x000002b7, + 0x0003003e,0x00000849,0x00000912,0x000200f9,0x000008e4,0x000200f8,0x00000913,0x0004003d, + 0x00000024,0x00000914,0x00000836,0x0004003d,0x00000024,0x00000915,0x00000836,0x0004003d, + 0x00000024,0x00000916,0x00000826,0x0005008e,0x00000024,0x00000917,0x00000916,0x000001f7, + 0x00050083,0x00000024,0x00000918,0x00000917,0x000005d3,0x00050085,0x00000024,0x00000919, + 0x00000915,0x00000918,0x0004003d,0x00000024,0x0000091a,0x00000838,0x00050085,0x00000024, + 0x0000091b,0x00000919,0x0000091a,0x00050081,0x00000024,0x0000091c,0x00000914,0x0000091b, + 0x0003003e,0x00000838,0x0000091c,0x000200f9,0x00000955,0x000200f8,0x0000091d,0x0004003d, + 0x00000024,0x0000091e,0x00000836,0x0004003d,0x00000024,0x0000091f,0x00000826,0x00050083, + 0x00000024,0x00000920,0x0000091e,0x0000091f,0x0006000c,0x00000024,0x00000921,0x00000001, + 0x00000004,0x00000920,0x0003003e,0x00000838,0x00000921,0x000200f9,0x00000955,0x000200f8, + 0x00000922,0x0004003d,0x00000024,0x00000923,0x00000826,0x0004003d,0x00000024,0x00000924, + 0x00000836,0x00050081,0x00000024,0x00000925,0x00000923,0x00000924,0x0004003d,0x00000024, + 0x00000926,0x00000826,0x0005008e,0x00000024,0x00000927,0x00000926,0x000001f7,0x0004003d, + 0x00000024,0x00000928,0x00000836,0x00050085,0x00000024,0x00000929,0x00000927,0x00000928, + 0x00050083,0x00000024,0x0000092a,0x00000925,0x00000929,0x0003003e,0x00000838,0x0000092a, + 0x000200f9,0x00000955,0x000200f8,0x0000092b,0x000300f7,0x00000935,0x00000000,0x000400fa, + 0x000002d2,0x0000092c,0x00000935,0x000200f8,0x0000092c,0x0004003d,0x00000024,0x0000092d, + 0x00000826,0x0003003e,0x0000084a,0x0000010b,0x0004003d,0x00000006,0x000009e2,0x0000084a, + 0x00050041,0x00000007,0x000009e3,0x000009df,0x000000c8,0x0003003e,0x000009e3,0x000009e2, + 0x0004003d,0x00000006,0x000009e4,0x0000084a,0x00050041,0x00000007,0x000009e5,0x000009df, + 0x000000cb,0x0003003e,0x000009e5,0x000009e4,0x0004003d,0x00000006,0x000009e6,0x0000084a, + 0x00050041,0x00000007,0x000009e7,0x000009df,0x000000de,0x0003003e,0x000009e7,0x000009e6, + 0x0004003d,0x00000024,0x000009e8,0x000009df,0x0003003e,0x000009e0,0x000009e8,0x0004003d, + 0x00000024,0x0000092e,0x000009e0,0x0003003e,0x0000084b,0x0000010a,0x0004003d,0x00000006, + 0x000009ec,0x0000084b,0x00050041,0x00000007,0x000009ed,0x000009e9,0x000000c8,0x0003003e, + 0x000009ed,0x000009ec,0x0004003d,0x00000006,0x000009ee,0x0000084b,0x00050041,0x00000007, + 0x000009ef,0x000009e9,0x000000cb,0x0003003e,0x000009ef,0x000009ee,0x0004003d,0x00000006, + 0x000009f0,0x0000084b,0x00050041,0x00000007,0x000009f1,0x000009e9,0x000000de,0x0003003e, + 0x000009f1,0x000009f0,0x0004003d,0x00000024,0x000009f2,0x000009e9,0x0003003e,0x000009ea, + 0x000009f2,0x0004003d,0x00000024,0x0000092f,0x000009ea,0x0008000c,0x00000024,0x00000930, + 0x00000001,0x0000002b,0x0000092d,0x0000092e,0x0000092f,0x0003003e,0x00000826,0x00000930, + 0x0004003d,0x00000024,0x00000931,0x00000826,0x0003003e,0x0000084c,0x00000931,0x0004003d, + 0x00000024,0x00000932,0x00000836,0x0003003e,0x0000084d,0x00000932,0x0004003d,0x00000024, + 0x00000933,0x00000836,0x0003003e,0x0000084e,0x00000933,0x0004003d,0x00000024,0x000009fe, + 0x0000084d,0x0003003e,0x000009f4,0x000009fe,0x0004003d,0x00000024,0x00000a16,0x000009f4, + 0x0007004f,0x0000000c,0x00000a17,0x00000a16,0x00000a16,0x00000000,0x00000001,0x0003003e, + 0x00000a13,0x00000a17,0x00050041,0x00000007,0x00000a1e,0x00000a13,0x000000c8,0x0004003d, + 0x00000006,0x00000a1f,0x00000a1e,0x00050041,0x00000007,0x00000a20,0x00000a13,0x000000cb, + 0x0004003d,0x00000006,0x00000a21,0x00000a20,0x0007000c,0x00000006,0x00000a22,0x00000001, + 0x00000028,0x00000a1f,0x00000a21,0x0003003e,0x00000a1c,0x00000a22,0x0004003d,0x00000006, + 0x00000a18,0x00000a1c,0x00050041,0x00000007,0x00000a19,0x000009f4,0x000000de,0x0004003d, + 0x00000006,0x00000a1a,0x00000a19,0x0007000c,0x00000006,0x00000a1b,0x00000001,0x00000028, + 0x00000a18,0x00000a1a,0x0003003e,0x00000a14,0x00000a1b,0x0004003d,0x00000006,0x000009ff, + 0x00000a14,0x0004003d,0x00000024,0x00000a00,0x0000084d,0x0003003e,0x000009f5,0x00000a00, + 0x0004003d,0x00000024,0x00000a26,0x000009f5,0x0007004f,0x0000000c,0x00000a27,0x00000a26, + 0x00000a26,0x00000000,0x00000001,0x0003003e,0x00000a23,0x00000a27,0x00050041,0x00000007, + 0x00000a2e,0x00000a23,0x000000c8,0x0004003d,0x00000006,0x00000a2f,0x00000a2e,0x00050041, + 0x00000007,0x00000a30,0x00000a23,0x000000cb,0x0004003d,0x00000006,0x00000a31,0x00000a30, + 0x0007000c,0x00000006,0x00000a32,0x00000001,0x00000025,0x00000a2f,0x00000a31,0x0003003e, + 0x00000a2c,0x00000a32,0x0004003d,0x00000006,0x00000a28,0x00000a2c,0x00050041,0x00000007, + 0x00000a29,0x000009f5,0x000000de,0x0004003d,0x00000006,0x00000a2a,0x00000a29,0x0007000c, + 0x00000006,0x00000a2b,0x00000001,0x00000025,0x00000a28,0x00000a2a,0x0003003e,0x00000a24, + 0x00000a2b,0x0004003d,0x00000006,0x00000a01,0x00000a24,0x00050083,0x00000006,0x00000a02, + 0x000009ff,0x00000a01,0x0003003e,0x000009f3,0x00000a02,0x0004003d,0x00000024,0x00000a03, + 0x0000084c,0x0003003e,0x000009f6,0x00000a03,0x0004003d,0x00000024,0x00000a36,0x000009f6, + 0x0007004f,0x0000000c,0x00000a37,0x00000a36,0x00000a36,0x00000000,0x00000001,0x0003003e, + 0x00000a33,0x00000a37,0x00050041,0x00000007,0x00000a3e,0x00000a33,0x000000c8,0x0004003d, + 0x00000006,0x00000a3f,0x00000a3e,0x00050041,0x00000007,0x00000a40,0x00000a33,0x000000cb, + 0x0004003d,0x00000006,0x00000a41,0x00000a40,0x0007000c,0x00000006,0x00000a42,0x00000001, + 0x00000025,0x00000a3f,0x00000a41,0x0003003e,0x00000a3c,0x00000a42,0x0004003d,0x00000006, + 0x00000a38,0x00000a3c,0x00050041,0x00000007,0x00000a39,0x000009f6,0x000000de,0x0004003d, + 0x00000006,0x00000a3a,0x00000a39,0x0007000c,0x00000006,0x00000a3b,0x00000001,0x00000025, + 0x00000a38,0x00000a3a,0x0003003e,0x00000a34,0x00000a3b,0x0004003d,0x00000006,0x00000a04, + 0x00000a34,0x0004003d,0x00000024,0x00000a05,0x0000084c,0x00060050,0x00000024,0x00000a06, + 0x00000a04,0x00000a04,0x00000a04,0x00050083,0x00000024,0x00000a07,0x00000a05,0x00000a06, + 0x0003003e,0x0000084c,0x00000a07,0x0004003d,0x00000024,0x00000a08,0x0000084c,0x0003003e, + 0x000009f8,0x00000a08,0x0004003d,0x00000024,0x00000a46,0x000009f8,0x0007004f,0x0000000c, + 0x00000a47,0x00000a46,0x00000a46,0x00000000,0x00000001,0x0003003e,0x00000a43,0x00000a47, + 0x00050041,0x00000007,0x00000a4e,0x00000a43,0x000000c8,0x0004003d,0x00000006,0x00000a4f, + 0x00000a4e,0x00050041,0x00000007,0x00000a50,0x00000a43,0x000000cb,0x0004003d,0x00000006, + 0x00000a51,0x00000a50,0x0007000c,0x00000006,0x00000a52,0x00000001,0x00000028,0x00000a4f, + 0x00000a51,0x0003003e,0x00000a4c,0x00000a52,0x0004003d,0x00000006,0x00000a48,0x00000a4c, + 0x00050041,0x00000007,0x00000a49,0x000009f8,0x000000de,0x0004003d,0x00000006,0x00000a4a, + 0x00000a49,0x0007000c,0x00000006,0x00000a4b,0x00000001,0x00000028,0x00000a48,0x00000a4a, + 0x0003003e,0x00000a44,0x00000a4b,0x0004003d,0x00000006,0x00000a09,0x00000a44,0x0003003e, + 0x000009f7,0x00000a09,0x0004003d,0x00000006,0x00000a0a,0x000009f3,0x0004003d,0x00000006, + 0x00000a0b,0x000009f7,0x0007000c,0x00000006,0x00000a0c,0x00000001,0x00000028,0x00000191, + 0x00000a0b,0x00050088,0x00000006,0x00000a0d,0x00000a0a,0x00000a0c,0x0003003e,0x000009f9, + 0x00000a0d,0x0004003d,0x00000024,0x00000a0e,0x0000084c,0x0004003d,0x00000006,0x00000a0f, + 0x000009f9,0x0005008e,0x00000024,0x00000a10,0x00000a0e,0x00000a0f,0x0003003e,0x000009fa, + 0x00000a10,0x0004003d,0x00000024,0x00000a11,0x0000084e,0x0003003e,0x000009fb,0x00000a11, + 0x0004003d,0x00000024,0x00000a63,0x000009fb,0x0003003e,0x00000a54,0x00000a63,0x0004003d, + 0x00000024,0x00000a89,0x00000a54,0x0003003e,0x00000a84,0x00000175,0x0003003e,0x00000a85, + 0x00000176,0x0003003e,0x00000a86,0x00000177,0x0004003d,0x00000006,0x00000a8f,0x00000a84, + 0x00050041,0x00000007,0x00000a90,0x00000a8c,0x000000c8,0x0003003e,0x00000a90,0x00000a8f, + 0x0004003d,0x00000006,0x00000a91,0x00000a85,0x00050041,0x00000007,0x00000a92,0x00000a8c, + 0x000000cb,0x0003003e,0x00000a92,0x00000a91,0x0004003d,0x00000006,0x00000a93,0x00000a86, + 0x00050041,0x00000007,0x00000a94,0x00000a8c,0x000000de,0x0003003e,0x00000a94,0x00000a93, + 0x0004003d,0x00000024,0x00000a95,0x00000a8c,0x0003003e,0x00000a8d,0x00000a95,0x0004003d, + 0x00000024,0x00000a8a,0x00000a8d,0x00050094,0x00000006,0x00000a8b,0x00000a89,0x00000a8a, + 0x0003003e,0x00000a87,0x00000a8b,0x0004003d,0x00000006,0x00000a64,0x00000a87,0x0003003e, + 0x00000a53,0x00000a64,0x0004003d,0x00000024,0x00000a65,0x000009fa,0x0004003d,0x00000024, + 0x00000a66,0x000009fa,0x0003003e,0x00000a56,0x00000a66,0x0004003d,0x00000024,0x00000a9b, + 0x00000a56,0x0003003e,0x00000a96,0x00000175,0x0003003e,0x00000a97,0x00000176,0x0003003e, + 0x00000a98,0x00000177,0x0004003d,0x00000006,0x00000aa1,0x00000a96,0x00050041,0x00000007, + 0x00000aa2,0x00000a9e,0x000000c8,0x0003003e,0x00000aa2,0x00000aa1,0x0004003d,0x00000006, + 0x00000aa3,0x00000a97,0x00050041,0x00000007,0x00000aa4,0x00000a9e,0x000000cb,0x0003003e, + 0x00000aa4,0x00000aa3,0x0004003d,0x00000006,0x00000aa5,0x00000a98,0x00050041,0x00000007, + 0x00000aa6,0x00000a9e,0x000000de,0x0003003e,0x00000aa6,0x00000aa5,0x0004003d,0x00000024, + 0x00000aa7,0x00000a9e,0x0003003e,0x00000a9f,0x00000aa7,0x0004003d,0x00000024,0x00000a9c, + 0x00000a9f,0x00050094,0x00000006,0x00000a9d,0x00000a9b,0x00000a9c,0x0003003e,0x00000a99, + 0x00000a9d,0x0004003d,0x00000006,0x00000a67,0x00000a99,0x00060050,0x00000024,0x00000a68, + 0x00000a67,0x00000a67,0x00000a67,0x00050083,0x00000024,0x00000a69,0x00000a65,0x00000a68, + 0x0003003e,0x00000a55,0x00000a69,0x0004003d,0x00000006,0x00000a6a,0x00000a53,0x00050083, + 0x00000006,0x00000a6b,0x0000010a,0x00000a6a,0x0004003d,0x00000006,0x00000a6c,0x00000a53, + 0x0003003e,0x00000a58,0x00000a6c,0x0003003e,0x00000a59,0x00000a6b,0x0004003d,0x00000006, + 0x00000aab,0x00000a58,0x00050041,0x00000007,0x00000aac,0x00000aa8,0x000000c8,0x0003003e, + 0x00000aac,0x00000aab,0x0004003d,0x00000006,0x00000aad,0x00000a59,0x00050041,0x00000007, + 0x00000aae,0x00000aa8,0x000000cb,0x0003003e,0x00000aae,0x00000aad,0x0004003d,0x0000000c, + 0x00000aaf,0x00000aa8,0x0003003e,0x00000aa9,0x00000aaf,0x0004003d,0x0000000c,0x00000a6d, + 0x00000aa9,0x0003003e,0x00000a5a,0x00000191,0x0004003d,0x00000006,0x00000ab3,0x00000a5a, + 0x00050041,0x00000007,0x00000ab4,0x00000ab0,0x000000c8,0x0003003e,0x00000ab4,0x00000ab3, + 0x0004003d,0x00000006,0x00000ab5,0x00000a5a,0x00050041,0x00000007,0x00000ab6,0x00000ab0, + 0x000000cb,0x0003003e,0x00000ab6,0x00000ab5,0x0004003d,0x0000000c,0x00000ab7,0x00000ab0, + 0x0003003e,0x00000ab1,0x00000ab7,0x0004003d,0x0000000c,0x00000a6e,0x00000ab1,0x0004003d, + 0x00000024,0x00000a6f,0x00000a55,0x0003003e,0x00000a5b,0x00000a6f,0x0004003d,0x00000024, + 0x00000abb,0x00000a5b,0x0007004f,0x0000000c,0x00000abc,0x00000abb,0x00000abb,0x00000000, + 0x00000001,0x0003003e,0x00000ab8,0x00000abc,0x00050041,0x00000007,0x00000ac3,0x00000ab8, + 0x000000c8,0x0004003d,0x00000006,0x00000ac4,0x00000ac3,0x00050041,0x00000007,0x00000ac5, + 0x00000ab8,0x000000cb,0x0004003d,0x00000006,0x00000ac6,0x00000ac5,0x0007000c,0x00000006, + 0x00000ac7,0x00000001,0x00000025,0x00000ac4,0x00000ac6,0x0003003e,0x00000ac1,0x00000ac7, + 0x0004003d,0x00000006,0x00000abd,0x00000ac1,0x00050041,0x00000007,0x00000abe,0x00000a5b, + 0x000000de,0x0004003d,0x00000006,0x00000abf,0x00000abe,0x0007000c,0x00000006,0x00000ac0, + 0x00000001,0x00000025,0x00000abd,0x00000abf,0x0003003e,0x00000ab9,0x00000ac0,0x0004003d, + 0x00000006,0x00000a70,0x00000ab9,0x0004007f,0x00000006,0x00000a71,0x00000a70,0x0004003d, + 0x00000024,0x00000a72,0x00000a55,0x0003003e,0x00000a5c,0x00000a72,0x0004003d,0x00000024, + 0x00000acb,0x00000a5c,0x0007004f,0x0000000c,0x00000acc,0x00000acb,0x00000acb,0x00000000, + 0x00000001,0x0003003e,0x00000ac8,0x00000acc,0x00050041,0x00000007,0x00000ad3,0x00000ac8, + 0x000000c8,0x0004003d,0x00000006,0x00000ad4,0x00000ad3,0x00050041,0x00000007,0x00000ad5, + 0x00000ac8,0x000000cb,0x0004003d,0x00000006,0x00000ad6,0x00000ad5,0x0007000c,0x00000006, + 0x00000ad7,0x00000001,0x00000028,0x00000ad4,0x00000ad6,0x0003003e,0x00000ad1,0x00000ad7, + 0x0004003d,0x00000006,0x00000acd,0x00000ad1,0x00050041,0x00000007,0x00000ace,0x00000a5c, + 0x000000de,0x0004003d,0x00000006,0x00000acf,0x00000ace,0x0007000c,0x00000006,0x00000ad0, + 0x00000001,0x00000028,0x00000acd,0x00000acf,0x0003003e,0x00000ac9,0x00000ad0,0x0004003d, + 0x00000006,0x00000a73,0x00000ac9,0x0003003e,0x00000a5d,0x00000a71,0x0003003e,0x00000a5e, + 0x00000a73,0x0004003d,0x00000006,0x00000adb,0x00000a5d,0x00050041,0x00000007,0x00000adc, + 0x00000ad8,0x000000c8,0x0003003e,0x00000adc,0x00000adb,0x0004003d,0x00000006,0x00000add, + 0x00000a5e,0x00050041,0x00000007,0x00000ade,0x00000ad8,0x000000cb,0x0003003e,0x00000ade, + 0x00000add,0x0004003d,0x0000000c,0x00000adf,0x00000ad8,0x0003003e,0x00000ad9,0x00000adf, + 0x0004003d,0x0000000c,0x00000a74,0x00000ad9,0x0007000c,0x0000000c,0x00000a75,0x00000001, + 0x00000028,0x00000a6e,0x00000a74,0x00050088,0x0000000c,0x00000a76,0x00000a6d,0x00000a75, + 0x0003003e,0x00000a57,0x00000a76,0x0003003e,0x00000a60,0x0000010a,0x0004003d,0x00000006, + 0x00000ae2,0x00000a60,0x0003003e,0x00000ae0,0x00000ae2,0x0004003d,0x00000006,0x00000a77, + 0x00000ae0,0x00050041,0x00000007,0x00000a78,0x00000a57,0x000000c8,0x0004003d,0x00000006, + 0x00000a79,0x00000a78,0x00050041,0x00000007,0x00000a7a,0x00000a57,0x000000cb,0x0004003d, + 0x00000006,0x00000a7b,0x00000a7a,0x0007000c,0x00000006,0x00000a7c,0x00000001,0x00000025, + 0x00000a79,0x00000a7b,0x0007000c,0x00000006,0x00000a7d,0x00000001,0x00000025,0x00000a77, + 0x00000a7c,0x0003003e,0x00000a5f,0x00000a7d,0x0004003d,0x00000024,0x00000a7e,0x00000a55, + 0x0004003d,0x00000006,0x00000a7f,0x00000a5f,0x0005008e,0x00000024,0x00000a80,0x00000a7e, + 0x00000a7f,0x0004003d,0x00000006,0x00000a81,0x00000a53,0x00060050,0x00000024,0x00000a82, + 0x00000a81,0x00000a81,0x00000a81,0x00050081,0x00000024,0x00000a83,0x00000a80,0x00000a82, + 0x0003003e,0x00000a61,0x00000a83,0x0004003d,0x00000024,0x00000a12,0x00000a61,0x0003003e, + 0x000009fc,0x00000a12,0x0004003d,0x00000024,0x00000934,0x000009fc,0x0003003e,0x00000838, + 0x00000934,0x000200f9,0x00000935,0x000200f8,0x00000935,0x000200f9,0x00000955,0x000200f8, + 0x00000936,0x000300f7,0x00000940,0x00000000,0x000400fa,0x000002d2,0x00000937,0x00000940, + 0x000200f8,0x00000937,0x0004003d,0x00000024,0x00000938,0x00000826,0x0003003e,0x0000084f, + 0x0000010b,0x0004003d,0x00000006,0x00000ae6,0x0000084f,0x00050041,0x00000007,0x00000ae7, + 0x00000ae3,0x000000c8,0x0003003e,0x00000ae7,0x00000ae6,0x0004003d,0x00000006,0x00000ae8, + 0x0000084f,0x00050041,0x00000007,0x00000ae9,0x00000ae3,0x000000cb,0x0003003e,0x00000ae9, + 0x00000ae8,0x0004003d,0x00000006,0x00000aea,0x0000084f,0x00050041,0x00000007,0x00000aeb, + 0x00000ae3,0x000000de,0x0003003e,0x00000aeb,0x00000aea,0x0004003d,0x00000024,0x00000aec, + 0x00000ae3,0x0003003e,0x00000ae4,0x00000aec,0x0004003d,0x00000024,0x00000939,0x00000ae4, + 0x0003003e,0x00000850,0x0000010a,0x0004003d,0x00000006,0x00000af0,0x00000850,0x00050041, + 0x00000007,0x00000af1,0x00000aed,0x000000c8,0x0003003e,0x00000af1,0x00000af0,0x0004003d, + 0x00000006,0x00000af2,0x00000850,0x00050041,0x00000007,0x00000af3,0x00000aed,0x000000cb, + 0x0003003e,0x00000af3,0x00000af2,0x0004003d,0x00000006,0x00000af4,0x00000850,0x00050041, + 0x00000007,0x00000af5,0x00000aed,0x000000de,0x0003003e,0x00000af5,0x00000af4,0x0004003d, + 0x00000024,0x00000af6,0x00000aed,0x0003003e,0x00000aee,0x00000af6,0x0004003d,0x00000024, + 0x0000093a,0x00000aee,0x0008000c,0x00000024,0x0000093b,0x00000001,0x0000002b,0x00000938, + 0x00000939,0x0000093a,0x0003003e,0x00000826,0x0000093b,0x0004003d,0x00000024,0x0000093c, + 0x00000836,0x0003003e,0x00000851,0x0000093c,0x0004003d,0x00000024,0x0000093d,0x00000826, + 0x0003003e,0x00000852,0x0000093d,0x0004003d,0x00000024,0x0000093e,0x00000836,0x0003003e, + 0x00000853,0x0000093e,0x0004003d,0x00000024,0x00000b02,0x00000852,0x0003003e,0x00000af8, + 0x00000b02,0x0004003d,0x00000024,0x00000b1a,0x00000af8,0x0007004f,0x0000000c,0x00000b1b, + 0x00000b1a,0x00000b1a,0x00000000,0x00000001,0x0003003e,0x00000b17,0x00000b1b,0x00050041, + 0x00000007,0x00000b22,0x00000b17,0x000000c8,0x0004003d,0x00000006,0x00000b23,0x00000b22, + 0x00050041,0x00000007,0x00000b24,0x00000b17,0x000000cb,0x0004003d,0x00000006,0x00000b25, + 0x00000b24,0x0007000c,0x00000006,0x00000b26,0x00000001,0x00000028,0x00000b23,0x00000b25, + 0x0003003e,0x00000b20,0x00000b26,0x0004003d,0x00000006,0x00000b1c,0x00000b20,0x00050041, + 0x00000007,0x00000b1d,0x00000af8,0x000000de,0x0004003d,0x00000006,0x00000b1e,0x00000b1d, + 0x0007000c,0x00000006,0x00000b1f,0x00000001,0x00000028,0x00000b1c,0x00000b1e,0x0003003e, + 0x00000b18,0x00000b1f,0x0004003d,0x00000006,0x00000b03,0x00000b18,0x0004003d,0x00000024, + 0x00000b04,0x00000852,0x0003003e,0x00000af9,0x00000b04,0x0004003d,0x00000024,0x00000b2a, + 0x00000af9,0x0007004f,0x0000000c,0x00000b2b,0x00000b2a,0x00000b2a,0x00000000,0x00000001, + 0x0003003e,0x00000b27,0x00000b2b,0x00050041,0x00000007,0x00000b32,0x00000b27,0x000000c8, + 0x0004003d,0x00000006,0x00000b33,0x00000b32,0x00050041,0x00000007,0x00000b34,0x00000b27, + 0x000000cb,0x0004003d,0x00000006,0x00000b35,0x00000b34,0x0007000c,0x00000006,0x00000b36, + 0x00000001,0x00000025,0x00000b33,0x00000b35,0x0003003e,0x00000b30,0x00000b36,0x0004003d, + 0x00000006,0x00000b2c,0x00000b30,0x00050041,0x00000007,0x00000b2d,0x00000af9,0x000000de, + 0x0004003d,0x00000006,0x00000b2e,0x00000b2d,0x0007000c,0x00000006,0x00000b2f,0x00000001, + 0x00000025,0x00000b2c,0x00000b2e,0x0003003e,0x00000b28,0x00000b2f,0x0004003d,0x00000006, + 0x00000b05,0x00000b28,0x00050083,0x00000006,0x00000b06,0x00000b03,0x00000b05,0x0003003e, + 0x00000af7,0x00000b06,0x0004003d,0x00000024,0x00000b07,0x00000851,0x0003003e,0x00000afa, + 0x00000b07,0x0004003d,0x00000024,0x00000b3a,0x00000afa,0x0007004f,0x0000000c,0x00000b3b, + 0x00000b3a,0x00000b3a,0x00000000,0x00000001,0x0003003e,0x00000b37,0x00000b3b,0x00050041, + 0x00000007,0x00000b42,0x00000b37,0x000000c8,0x0004003d,0x00000006,0x00000b43,0x00000b42, + 0x00050041,0x00000007,0x00000b44,0x00000b37,0x000000cb,0x0004003d,0x00000006,0x00000b45, + 0x00000b44,0x0007000c,0x00000006,0x00000b46,0x00000001,0x00000025,0x00000b43,0x00000b45, + 0x0003003e,0x00000b40,0x00000b46,0x0004003d,0x00000006,0x00000b3c,0x00000b40,0x00050041, + 0x00000007,0x00000b3d,0x00000afa,0x000000de,0x0004003d,0x00000006,0x00000b3e,0x00000b3d, + 0x0007000c,0x00000006,0x00000b3f,0x00000001,0x00000025,0x00000b3c,0x00000b3e,0x0003003e, + 0x00000b38,0x00000b3f,0x0004003d,0x00000006,0x00000b08,0x00000b38,0x0004003d,0x00000024, + 0x00000b09,0x00000851,0x00060050,0x00000024,0x00000b0a,0x00000b08,0x00000b08,0x00000b08, + 0x00050083,0x00000024,0x00000b0b,0x00000b09,0x00000b0a,0x0003003e,0x00000851,0x00000b0b, + 0x0004003d,0x00000024,0x00000b0c,0x00000851,0x0003003e,0x00000afc,0x00000b0c,0x0004003d, + 0x00000024,0x00000b4a,0x00000afc,0x0007004f,0x0000000c,0x00000b4b,0x00000b4a,0x00000b4a, + 0x00000000,0x00000001,0x0003003e,0x00000b47,0x00000b4b,0x00050041,0x00000007,0x00000b52, + 0x00000b47,0x000000c8,0x0004003d,0x00000006,0x00000b53,0x00000b52,0x00050041,0x00000007, + 0x00000b54,0x00000b47,0x000000cb,0x0004003d,0x00000006,0x00000b55,0x00000b54,0x0007000c, + 0x00000006,0x00000b56,0x00000001,0x00000028,0x00000b53,0x00000b55,0x0003003e,0x00000b50, + 0x00000b56,0x0004003d,0x00000006,0x00000b4c,0x00000b50,0x00050041,0x00000007,0x00000b4d, + 0x00000afc,0x000000de,0x0004003d,0x00000006,0x00000b4e,0x00000b4d,0x0007000c,0x00000006, + 0x00000b4f,0x00000001,0x00000028,0x00000b4c,0x00000b4e,0x0003003e,0x00000b48,0x00000b4f, + 0x0004003d,0x00000006,0x00000b0d,0x00000b48,0x0003003e,0x00000afb,0x00000b0d,0x0004003d, + 0x00000006,0x00000b0e,0x00000af7,0x0004003d,0x00000006,0x00000b0f,0x00000afb,0x0007000c, + 0x00000006,0x00000b10,0x00000001,0x00000028,0x00000191,0x00000b0f,0x00050088,0x00000006, + 0x00000b11,0x00000b0e,0x00000b10,0x0003003e,0x00000afd,0x00000b11,0x0004003d,0x00000024, + 0x00000b12,0x00000851,0x0004003d,0x00000006,0x00000b13,0x00000afd,0x0005008e,0x00000024, + 0x00000b14,0x00000b12,0x00000b13,0x0003003e,0x00000afe,0x00000b14,0x0004003d,0x00000024, + 0x00000b15,0x00000853,0x0003003e,0x00000aff,0x00000b15,0x0004003d,0x00000024,0x00000b67, + 0x00000aff,0x0003003e,0x00000b58,0x00000b67,0x0004003d,0x00000024,0x00000b8d,0x00000b58, + 0x0003003e,0x00000b88,0x00000175,0x0003003e,0x00000b89,0x00000176,0x0003003e,0x00000b8a, + 0x00000177,0x0004003d,0x00000006,0x00000b93,0x00000b88,0x00050041,0x00000007,0x00000b94, + 0x00000b90,0x000000c8,0x0003003e,0x00000b94,0x00000b93,0x0004003d,0x00000006,0x00000b95, + 0x00000b89,0x00050041,0x00000007,0x00000b96,0x00000b90,0x000000cb,0x0003003e,0x00000b96, + 0x00000b95,0x0004003d,0x00000006,0x00000b97,0x00000b8a,0x00050041,0x00000007,0x00000b98, + 0x00000b90,0x000000de,0x0003003e,0x00000b98,0x00000b97,0x0004003d,0x00000024,0x00000b99, + 0x00000b90,0x0003003e,0x00000b91,0x00000b99,0x0004003d,0x00000024,0x00000b8e,0x00000b91, + 0x00050094,0x00000006,0x00000b8f,0x00000b8d,0x00000b8e,0x0003003e,0x00000b8b,0x00000b8f, + 0x0004003d,0x00000006,0x00000b68,0x00000b8b,0x0003003e,0x00000b57,0x00000b68,0x0004003d, + 0x00000024,0x00000b69,0x00000afe,0x0004003d,0x00000024,0x00000b6a,0x00000afe,0x0003003e, + 0x00000b5a,0x00000b6a,0x0004003d,0x00000024,0x00000b9f,0x00000b5a,0x0003003e,0x00000b9a, + 0x00000175,0x0003003e,0x00000b9b,0x00000176,0x0003003e,0x00000b9c,0x00000177,0x0004003d, + 0x00000006,0x00000ba5,0x00000b9a,0x00050041,0x00000007,0x00000ba6,0x00000ba2,0x000000c8, + 0x0003003e,0x00000ba6,0x00000ba5,0x0004003d,0x00000006,0x00000ba7,0x00000b9b,0x00050041, + 0x00000007,0x00000ba8,0x00000ba2,0x000000cb,0x0003003e,0x00000ba8,0x00000ba7,0x0004003d, + 0x00000006,0x00000ba9,0x00000b9c,0x00050041,0x00000007,0x00000baa,0x00000ba2,0x000000de, + 0x0003003e,0x00000baa,0x00000ba9,0x0004003d,0x00000024,0x00000bab,0x00000ba2,0x0003003e, + 0x00000ba3,0x00000bab,0x0004003d,0x00000024,0x00000ba0,0x00000ba3,0x00050094,0x00000006, + 0x00000ba1,0x00000b9f,0x00000ba0,0x0003003e,0x00000b9d,0x00000ba1,0x0004003d,0x00000006, + 0x00000b6b,0x00000b9d,0x00060050,0x00000024,0x00000b6c,0x00000b6b,0x00000b6b,0x00000b6b, + 0x00050083,0x00000024,0x00000b6d,0x00000b69,0x00000b6c,0x0003003e,0x00000b59,0x00000b6d, + 0x0004003d,0x00000006,0x00000b6e,0x00000b57,0x00050083,0x00000006,0x00000b6f,0x0000010a, + 0x00000b6e,0x0004003d,0x00000006,0x00000b70,0x00000b57,0x0003003e,0x00000b5c,0x00000b70, + 0x0003003e,0x00000b5d,0x00000b6f,0x0004003d,0x00000006,0x00000baf,0x00000b5c,0x00050041, + 0x00000007,0x00000bb0,0x00000bac,0x000000c8,0x0003003e,0x00000bb0,0x00000baf,0x0004003d, + 0x00000006,0x00000bb1,0x00000b5d,0x00050041,0x00000007,0x00000bb2,0x00000bac,0x000000cb, + 0x0003003e,0x00000bb2,0x00000bb1,0x0004003d,0x0000000c,0x00000bb3,0x00000bac,0x0003003e, + 0x00000bad,0x00000bb3,0x0004003d,0x0000000c,0x00000b71,0x00000bad,0x0003003e,0x00000b5e, + 0x00000191,0x0004003d,0x00000006,0x00000bb7,0x00000b5e,0x00050041,0x00000007,0x00000bb8, + 0x00000bb4,0x000000c8,0x0003003e,0x00000bb8,0x00000bb7,0x0004003d,0x00000006,0x00000bb9, + 0x00000b5e,0x00050041,0x00000007,0x00000bba,0x00000bb4,0x000000cb,0x0003003e,0x00000bba, + 0x00000bb9,0x0004003d,0x0000000c,0x00000bbb,0x00000bb4,0x0003003e,0x00000bb5,0x00000bbb, + 0x0004003d,0x0000000c,0x00000b72,0x00000bb5,0x0004003d,0x00000024,0x00000b73,0x00000b59, + 0x0003003e,0x00000b5f,0x00000b73,0x0004003d,0x00000024,0x00000bbf,0x00000b5f,0x0007004f, + 0x0000000c,0x00000bc0,0x00000bbf,0x00000bbf,0x00000000,0x00000001,0x0003003e,0x00000bbc, + 0x00000bc0,0x00050041,0x00000007,0x00000bc7,0x00000bbc,0x000000c8,0x0004003d,0x00000006, + 0x00000bc8,0x00000bc7,0x00050041,0x00000007,0x00000bc9,0x00000bbc,0x000000cb,0x0004003d, + 0x00000006,0x00000bca,0x00000bc9,0x0007000c,0x00000006,0x00000bcb,0x00000001,0x00000025, + 0x00000bc8,0x00000bca,0x0003003e,0x00000bc5,0x00000bcb,0x0004003d,0x00000006,0x00000bc1, + 0x00000bc5,0x00050041,0x00000007,0x00000bc2,0x00000b5f,0x000000de,0x0004003d,0x00000006, + 0x00000bc3,0x00000bc2,0x0007000c,0x00000006,0x00000bc4,0x00000001,0x00000025,0x00000bc1, + 0x00000bc3,0x0003003e,0x00000bbd,0x00000bc4,0x0004003d,0x00000006,0x00000b74,0x00000bbd, + 0x0004007f,0x00000006,0x00000b75,0x00000b74,0x0004003d,0x00000024,0x00000b76,0x00000b59, + 0x0003003e,0x00000b60,0x00000b76,0x0004003d,0x00000024,0x00000bcf,0x00000b60,0x0007004f, + 0x0000000c,0x00000bd0,0x00000bcf,0x00000bcf,0x00000000,0x00000001,0x0003003e,0x00000bcc, + 0x00000bd0,0x00050041,0x00000007,0x00000bd7,0x00000bcc,0x000000c8,0x0004003d,0x00000006, + 0x00000bd8,0x00000bd7,0x00050041,0x00000007,0x00000bd9,0x00000bcc,0x000000cb,0x0004003d, + 0x00000006,0x00000bda,0x00000bd9,0x0007000c,0x00000006,0x00000bdb,0x00000001,0x00000028, + 0x00000bd8,0x00000bda,0x0003003e,0x00000bd5,0x00000bdb,0x0004003d,0x00000006,0x00000bd1, + 0x00000bd5,0x00050041,0x00000007,0x00000bd2,0x00000b60,0x000000de,0x0004003d,0x00000006, + 0x00000bd3,0x00000bd2,0x0007000c,0x00000006,0x00000bd4,0x00000001,0x00000028,0x00000bd1, + 0x00000bd3,0x0003003e,0x00000bcd,0x00000bd4,0x0004003d,0x00000006,0x00000b77,0x00000bcd, + 0x0003003e,0x00000b61,0x00000b75,0x0003003e,0x00000b62,0x00000b77,0x0004003d,0x00000006, + 0x00000bdf,0x00000b61,0x00050041,0x00000007,0x00000be0,0x00000bdc,0x000000c8,0x0003003e, + 0x00000be0,0x00000bdf,0x0004003d,0x00000006,0x00000be1,0x00000b62,0x00050041,0x00000007, + 0x00000be2,0x00000bdc,0x000000cb,0x0003003e,0x00000be2,0x00000be1,0x0004003d,0x0000000c, + 0x00000be3,0x00000bdc,0x0003003e,0x00000bdd,0x00000be3,0x0004003d,0x0000000c,0x00000b78, + 0x00000bdd,0x0007000c,0x0000000c,0x00000b79,0x00000001,0x00000028,0x00000b72,0x00000b78, + 0x00050088,0x0000000c,0x00000b7a,0x00000b71,0x00000b79,0x0003003e,0x00000b5b,0x00000b7a, + 0x0003003e,0x00000b64,0x0000010a,0x0004003d,0x00000006,0x00000be6,0x00000b64,0x0003003e, + 0x00000be4,0x00000be6,0x0004003d,0x00000006,0x00000b7b,0x00000be4,0x00050041,0x00000007, + 0x00000b7c,0x00000b5b,0x000000c8,0x0004003d,0x00000006,0x00000b7d,0x00000b7c,0x00050041, + 0x00000007,0x00000b7e,0x00000b5b,0x000000cb,0x0004003d,0x00000006,0x00000b7f,0x00000b7e, + 0x0007000c,0x00000006,0x00000b80,0x00000001,0x00000025,0x00000b7d,0x00000b7f,0x0007000c, + 0x00000006,0x00000b81,0x00000001,0x00000025,0x00000b7b,0x00000b80,0x0003003e,0x00000b63, + 0x00000b81,0x0004003d,0x00000024,0x00000b82,0x00000b59,0x0004003d,0x00000006,0x00000b83, + 0x00000b63,0x0005008e,0x00000024,0x00000b84,0x00000b82,0x00000b83,0x0004003d,0x00000006, + 0x00000b85,0x00000b57,0x00060050,0x00000024,0x00000b86,0x00000b85,0x00000b85,0x00000b85, + 0x00050081,0x00000024,0x00000b87,0x00000b84,0x00000b86,0x0003003e,0x00000b65,0x00000b87, + 0x0004003d,0x00000024,0x00000b16,0x00000b65,0x0003003e,0x00000b00,0x00000b16,0x0004003d, + 0x00000024,0x0000093f,0x00000b00,0x0003003e,0x00000838,0x0000093f,0x000200f9,0x00000940, + 0x000200f8,0x00000940,0x000200f9,0x00000955,0x000200f8,0x00000941,0x000300f7,0x0000094a, + 0x00000000,0x000400fa,0x000002d2,0x00000942,0x0000094a,0x000200f8,0x00000942,0x0004003d, + 0x00000024,0x00000943,0x00000826,0x0003003e,0x00000854,0x0000010b,0x0004003d,0x00000006, + 0x00000bea,0x00000854,0x00050041,0x00000007,0x00000beb,0x00000be7,0x000000c8,0x0003003e, + 0x00000beb,0x00000bea,0x0004003d,0x00000006,0x00000bec,0x00000854,0x00050041,0x00000007, + 0x00000bed,0x00000be7,0x000000cb,0x0003003e,0x00000bed,0x00000bec,0x0004003d,0x00000006, + 0x00000bee,0x00000854,0x00050041,0x00000007,0x00000bef,0x00000be7,0x000000de,0x0003003e, + 0x00000bef,0x00000bee,0x0004003d,0x00000024,0x00000bf0,0x00000be7,0x0003003e,0x00000be8, + 0x00000bf0,0x0004003d,0x00000024,0x00000944,0x00000be8,0x0003003e,0x00000855,0x0000010a, + 0x0004003d,0x00000006,0x00000bf4,0x00000855,0x00050041,0x00000007,0x00000bf5,0x00000bf1, + 0x000000c8,0x0003003e,0x00000bf5,0x00000bf4,0x0004003d,0x00000006,0x00000bf6,0x00000855, + 0x00050041,0x00000007,0x00000bf7,0x00000bf1,0x000000cb,0x0003003e,0x00000bf7,0x00000bf6, + 0x0004003d,0x00000006,0x00000bf8,0x00000855,0x00050041,0x00000007,0x00000bf9,0x00000bf1, + 0x000000de,0x0003003e,0x00000bf9,0x00000bf8,0x0004003d,0x00000024,0x00000bfa,0x00000bf1, + 0x0003003e,0x00000bf2,0x00000bfa,0x0004003d,0x00000024,0x00000945,0x00000bf2,0x0008000c, + 0x00000024,0x00000946,0x00000001,0x0000002b,0x00000943,0x00000944,0x00000945,0x0003003e, + 0x00000826,0x00000946,0x0004003d,0x00000024,0x00000947,0x00000826,0x0003003e,0x00000856, + 0x00000947,0x0004003d,0x00000024,0x00000948,0x00000836,0x0003003e,0x00000857,0x00000948, + 0x0004003d,0x00000024,0x00000c0b,0x00000857,0x0003003e,0x00000bfc,0x00000c0b,0x0004003d, + 0x00000024,0x00000c31,0x00000bfc,0x0003003e,0x00000c2c,0x00000175,0x0003003e,0x00000c2d, + 0x00000176,0x0003003e,0x00000c2e,0x00000177,0x0004003d,0x00000006,0x00000c37,0x00000c2c, + 0x00050041,0x00000007,0x00000c38,0x00000c34,0x000000c8,0x0003003e,0x00000c38,0x00000c37, + 0x0004003d,0x00000006,0x00000c39,0x00000c2d,0x00050041,0x00000007,0x00000c3a,0x00000c34, + 0x000000cb,0x0003003e,0x00000c3a,0x00000c39,0x0004003d,0x00000006,0x00000c3b,0x00000c2e, + 0x00050041,0x00000007,0x00000c3c,0x00000c34,0x000000de,0x0003003e,0x00000c3c,0x00000c3b, + 0x0004003d,0x00000024,0x00000c3d,0x00000c34,0x0003003e,0x00000c35,0x00000c3d,0x0004003d, + 0x00000024,0x00000c32,0x00000c35,0x00050094,0x00000006,0x00000c33,0x00000c31,0x00000c32, + 0x0003003e,0x00000c2f,0x00000c33,0x0004003d,0x00000006,0x00000c0c,0x00000c2f,0x0003003e, + 0x00000bfb,0x00000c0c,0x0004003d,0x00000024,0x00000c0d,0x00000856,0x0004003d,0x00000024, + 0x00000c0e,0x00000856,0x0003003e,0x00000bfe,0x00000c0e,0x0004003d,0x00000024,0x00000c43, + 0x00000bfe,0x0003003e,0x00000c3e,0x00000175,0x0003003e,0x00000c3f,0x00000176,0x0003003e, + 0x00000c40,0x00000177,0x0004003d,0x00000006,0x00000c49,0x00000c3e,0x00050041,0x00000007, + 0x00000c4a,0x00000c46,0x000000c8,0x0003003e,0x00000c4a,0x00000c49,0x0004003d,0x00000006, + 0x00000c4b,0x00000c3f,0x00050041,0x00000007,0x00000c4c,0x00000c46,0x000000cb,0x0003003e, + 0x00000c4c,0x00000c4b,0x0004003d,0x00000006,0x00000c4d,0x00000c40,0x00050041,0x00000007, + 0x00000c4e,0x00000c46,0x000000de,0x0003003e,0x00000c4e,0x00000c4d,0x0004003d,0x00000024, + 0x00000c4f,0x00000c46,0x0003003e,0x00000c47,0x00000c4f,0x0004003d,0x00000024,0x00000c44, + 0x00000c47,0x00050094,0x00000006,0x00000c45,0x00000c43,0x00000c44,0x0003003e,0x00000c41, + 0x00000c45,0x0004003d,0x00000006,0x00000c0f,0x00000c41,0x00060050,0x00000024,0x00000c10, + 0x00000c0f,0x00000c0f,0x00000c0f,0x00050083,0x00000024,0x00000c11,0x00000c0d,0x00000c10, + 0x0003003e,0x00000bfd,0x00000c11,0x0004003d,0x00000006,0x00000c12,0x00000bfb,0x00050083, + 0x00000006,0x00000c13,0x0000010a,0x00000c12,0x0004003d,0x00000006,0x00000c14,0x00000bfb, + 0x0003003e,0x00000c00,0x00000c14,0x0003003e,0x00000c01,0x00000c13,0x0004003d,0x00000006, + 0x00000c53,0x00000c00,0x00050041,0x00000007,0x00000c54,0x00000c50,0x000000c8,0x0003003e, + 0x00000c54,0x00000c53,0x0004003d,0x00000006,0x00000c55,0x00000c01,0x00050041,0x00000007, + 0x00000c56,0x00000c50,0x000000cb,0x0003003e,0x00000c56,0x00000c55,0x0004003d,0x0000000c, + 0x00000c57,0x00000c50,0x0003003e,0x00000c51,0x00000c57,0x0004003d,0x0000000c,0x00000c15, + 0x00000c51,0x0003003e,0x00000c02,0x00000191,0x0004003d,0x00000006,0x00000c5b,0x00000c02, + 0x00050041,0x00000007,0x00000c5c,0x00000c58,0x000000c8,0x0003003e,0x00000c5c,0x00000c5b, + 0x0004003d,0x00000006,0x00000c5d,0x00000c02,0x00050041,0x00000007,0x00000c5e,0x00000c58, + 0x000000cb,0x0003003e,0x00000c5e,0x00000c5d,0x0004003d,0x0000000c,0x00000c5f,0x00000c58, + 0x0003003e,0x00000c59,0x00000c5f,0x0004003d,0x0000000c,0x00000c16,0x00000c59,0x0004003d, + 0x00000024,0x00000c17,0x00000bfd,0x0003003e,0x00000c03,0x00000c17,0x0004003d,0x00000024, + 0x00000c63,0x00000c03,0x0007004f,0x0000000c,0x00000c64,0x00000c63,0x00000c63,0x00000000, + 0x00000001,0x0003003e,0x00000c60,0x00000c64,0x00050041,0x00000007,0x00000c6b,0x00000c60, + 0x000000c8,0x0004003d,0x00000006,0x00000c6c,0x00000c6b,0x00050041,0x00000007,0x00000c6d, + 0x00000c60,0x000000cb,0x0004003d,0x00000006,0x00000c6e,0x00000c6d,0x0007000c,0x00000006, + 0x00000c6f,0x00000001,0x00000025,0x00000c6c,0x00000c6e,0x0003003e,0x00000c69,0x00000c6f, + 0x0004003d,0x00000006,0x00000c65,0x00000c69,0x00050041,0x00000007,0x00000c66,0x00000c03, + 0x000000de,0x0004003d,0x00000006,0x00000c67,0x00000c66,0x0007000c,0x00000006,0x00000c68, + 0x00000001,0x00000025,0x00000c65,0x00000c67,0x0003003e,0x00000c61,0x00000c68,0x0004003d, + 0x00000006,0x00000c18,0x00000c61,0x0004007f,0x00000006,0x00000c19,0x00000c18,0x0004003d, + 0x00000024,0x00000c1a,0x00000bfd,0x0003003e,0x00000c04,0x00000c1a,0x0004003d,0x00000024, + 0x00000c73,0x00000c04,0x0007004f,0x0000000c,0x00000c74,0x00000c73,0x00000c73,0x00000000, + 0x00000001,0x0003003e,0x00000c70,0x00000c74,0x00050041,0x00000007,0x00000c7b,0x00000c70, + 0x000000c8,0x0004003d,0x00000006,0x00000c7c,0x00000c7b,0x00050041,0x00000007,0x00000c7d, + 0x00000c70,0x000000cb,0x0004003d,0x00000006,0x00000c7e,0x00000c7d,0x0007000c,0x00000006, + 0x00000c7f,0x00000001,0x00000028,0x00000c7c,0x00000c7e,0x0003003e,0x00000c79,0x00000c7f, + 0x0004003d,0x00000006,0x00000c75,0x00000c79,0x00050041,0x00000007,0x00000c76,0x00000c04, + 0x000000de,0x0004003d,0x00000006,0x00000c77,0x00000c76,0x0007000c,0x00000006,0x00000c78, + 0x00000001,0x00000028,0x00000c75,0x00000c77,0x0003003e,0x00000c71,0x00000c78,0x0004003d, + 0x00000006,0x00000c1b,0x00000c71,0x0003003e,0x00000c05,0x00000c19,0x0003003e,0x00000c06, + 0x00000c1b,0x0004003d,0x00000006,0x00000c83,0x00000c05,0x00050041,0x00000007,0x00000c84, + 0x00000c80,0x000000c8,0x0003003e,0x00000c84,0x00000c83,0x0004003d,0x00000006,0x00000c85, + 0x00000c06,0x00050041,0x00000007,0x00000c86,0x00000c80,0x000000cb,0x0003003e,0x00000c86, + 0x00000c85,0x0004003d,0x0000000c,0x00000c87,0x00000c80,0x0003003e,0x00000c81,0x00000c87, + 0x0004003d,0x0000000c,0x00000c1c,0x00000c81,0x0007000c,0x0000000c,0x00000c1d,0x00000001, + 0x00000028,0x00000c16,0x00000c1c,0x00050088,0x0000000c,0x00000c1e,0x00000c15,0x00000c1d, + 0x0003003e,0x00000bff,0x00000c1e,0x0003003e,0x00000c08,0x0000010a,0x0004003d,0x00000006, + 0x00000c8a,0x00000c08,0x0003003e,0x00000c88,0x00000c8a,0x0004003d,0x00000006,0x00000c1f, + 0x00000c88,0x00050041,0x00000007,0x00000c20,0x00000bff,0x000000c8,0x0004003d,0x00000006, + 0x00000c21,0x00000c20,0x00050041,0x00000007,0x00000c22,0x00000bff,0x000000cb,0x0004003d, + 0x00000006,0x00000c23,0x00000c22,0x0007000c,0x00000006,0x00000c24,0x00000001,0x00000025, + 0x00000c21,0x00000c23,0x0007000c,0x00000006,0x00000c25,0x00000001,0x00000025,0x00000c1f, + 0x00000c24,0x0003003e,0x00000c07,0x00000c25,0x0004003d,0x00000024,0x00000c26,0x00000bfd, + 0x0004003d,0x00000006,0x00000c27,0x00000c07,0x0005008e,0x00000024,0x00000c28,0x00000c26, + 0x00000c27,0x0004003d,0x00000006,0x00000c29,0x00000bfb,0x00060050,0x00000024,0x00000c2a, + 0x00000c29,0x00000c29,0x00000c29,0x00050081,0x00000024,0x00000c2b,0x00000c28,0x00000c2a, + 0x0003003e,0x00000c09,0x00000c2b,0x0004003d,0x00000024,0x00000949,0x00000c09,0x0003003e, + 0x00000838,0x00000949,0x000200f9,0x0000094a,0x000200f8,0x0000094a,0x000200f9,0x00000955, + 0x000200f8,0x0000094b,0x000300f7,0x00000954,0x00000000,0x000400fa,0x000002d2,0x0000094c, + 0x00000954,0x000200f8,0x0000094c,0x0004003d,0x00000024,0x0000094d,0x00000826,0x0003003e, + 0x00000858,0x0000010b,0x0004003d,0x00000006,0x00000c8e,0x00000858,0x00050041,0x00000007, + 0x00000c8f,0x00000c8b,0x000000c8,0x0003003e,0x00000c8f,0x00000c8e,0x0004003d,0x00000006, + 0x00000c90,0x00000858,0x00050041,0x00000007,0x00000c91,0x00000c8b,0x000000cb,0x0003003e, + 0x00000c91,0x00000c90,0x0004003d,0x00000006,0x00000c92,0x00000858,0x00050041,0x00000007, + 0x00000c93,0x00000c8b,0x000000de,0x0003003e,0x00000c93,0x00000c92,0x0004003d,0x00000024, + 0x00000c94,0x00000c8b,0x0003003e,0x00000c8c,0x00000c94,0x0004003d,0x00000024,0x0000094e, + 0x00000c8c,0x0003003e,0x00000859,0x0000010a,0x0004003d,0x00000006,0x00000c98,0x00000859, + 0x00050041,0x00000007,0x00000c99,0x00000c95,0x000000c8,0x0003003e,0x00000c99,0x00000c98, + 0x0004003d,0x00000006,0x00000c9a,0x00000859,0x00050041,0x00000007,0x00000c9b,0x00000c95, + 0x000000cb,0x0003003e,0x00000c9b,0x00000c9a,0x0004003d,0x00000006,0x00000c9c,0x00000859, + 0x00050041,0x00000007,0x00000c9d,0x00000c95,0x000000de,0x0003003e,0x00000c9d,0x00000c9c, + 0x0004003d,0x00000024,0x00000c9e,0x00000c95,0x0003003e,0x00000c96,0x00000c9e,0x0004003d, + 0x00000024,0x0000094f,0x00000c96,0x0008000c,0x00000024,0x00000950,0x00000001,0x0000002b, + 0x0000094d,0x0000094e,0x0000094f,0x0003003e,0x00000826,0x00000950,0x0004003d,0x00000024, + 0x00000951,0x00000836,0x0003003e,0x0000085a,0x00000951,0x0004003d,0x00000024,0x00000952, + 0x00000826,0x0003003e,0x0000085b,0x00000952,0x0004003d,0x00000024,0x00000caf,0x0000085b, + 0x0003003e,0x00000ca0,0x00000caf,0x0004003d,0x00000024,0x00000cd5,0x00000ca0,0x0003003e, + 0x00000cd0,0x00000175,0x0003003e,0x00000cd1,0x00000176,0x0003003e,0x00000cd2,0x00000177, + 0x0004003d,0x00000006,0x00000cdb,0x00000cd0,0x00050041,0x00000007,0x00000cdc,0x00000cd8, + 0x000000c8,0x0003003e,0x00000cdc,0x00000cdb,0x0004003d,0x00000006,0x00000cdd,0x00000cd1, + 0x00050041,0x00000007,0x00000cde,0x00000cd8,0x000000cb,0x0003003e,0x00000cde,0x00000cdd, + 0x0004003d,0x00000006,0x00000cdf,0x00000cd2,0x00050041,0x00000007,0x00000ce0,0x00000cd8, + 0x000000de,0x0003003e,0x00000ce0,0x00000cdf,0x0004003d,0x00000024,0x00000ce1,0x00000cd8, + 0x0003003e,0x00000cd9,0x00000ce1,0x0004003d,0x00000024,0x00000cd6,0x00000cd9,0x00050094, + 0x00000006,0x00000cd7,0x00000cd5,0x00000cd6,0x0003003e,0x00000cd3,0x00000cd7,0x0004003d, + 0x00000006,0x00000cb0,0x00000cd3,0x0003003e,0x00000c9f,0x00000cb0,0x0004003d,0x00000024, + 0x00000cb1,0x0000085a,0x0004003d,0x00000024,0x00000cb2,0x0000085a,0x0003003e,0x00000ca2, + 0x00000cb2,0x0004003d,0x00000024,0x00000ce7,0x00000ca2,0x0003003e,0x00000ce2,0x00000175, + 0x0003003e,0x00000ce3,0x00000176,0x0003003e,0x00000ce4,0x00000177,0x0004003d,0x00000006, + 0x00000ced,0x00000ce2,0x00050041,0x00000007,0x00000cee,0x00000cea,0x000000c8,0x0003003e, + 0x00000cee,0x00000ced,0x0004003d,0x00000006,0x00000cef,0x00000ce3,0x00050041,0x00000007, + 0x00000cf0,0x00000cea,0x000000cb,0x0003003e,0x00000cf0,0x00000cef,0x0004003d,0x00000006, + 0x00000cf1,0x00000ce4,0x00050041,0x00000007,0x00000cf2,0x00000cea,0x000000de,0x0003003e, + 0x00000cf2,0x00000cf1,0x0004003d,0x00000024,0x00000cf3,0x00000cea,0x0003003e,0x00000ceb, + 0x00000cf3,0x0004003d,0x00000024,0x00000ce8,0x00000ceb,0x00050094,0x00000006,0x00000ce9, + 0x00000ce7,0x00000ce8,0x0003003e,0x00000ce5,0x00000ce9,0x0004003d,0x00000006,0x00000cb3, + 0x00000ce5,0x00060050,0x00000024,0x00000cb4,0x00000cb3,0x00000cb3,0x00000cb3,0x00050083, + 0x00000024,0x00000cb5,0x00000cb1,0x00000cb4,0x0003003e,0x00000ca1,0x00000cb5,0x0004003d, + 0x00000006,0x00000cb6,0x00000c9f,0x00050083,0x00000006,0x00000cb7,0x0000010a,0x00000cb6, + 0x0004003d,0x00000006,0x00000cb8,0x00000c9f,0x0003003e,0x00000ca4,0x00000cb8,0x0003003e, + 0x00000ca5,0x00000cb7,0x0004003d,0x00000006,0x00000cf7,0x00000ca4,0x00050041,0x00000007, + 0x00000cf8,0x00000cf4,0x000000c8,0x0003003e,0x00000cf8,0x00000cf7,0x0004003d,0x00000006, + 0x00000cf9,0x00000ca5,0x00050041,0x00000007,0x00000cfa,0x00000cf4,0x000000cb,0x0003003e, + 0x00000cfa,0x00000cf9,0x0004003d,0x0000000c,0x00000cfb,0x00000cf4,0x0003003e,0x00000cf5, + 0x00000cfb,0x0004003d,0x0000000c,0x00000cb9,0x00000cf5,0x0003003e,0x00000ca6,0x00000191, + 0x0004003d,0x00000006,0x00000cff,0x00000ca6,0x00050041,0x00000007,0x00000d00,0x00000cfc, + 0x000000c8,0x0003003e,0x00000d00,0x00000cff,0x0004003d,0x00000006,0x00000d01,0x00000ca6, + 0x00050041,0x00000007,0x00000d02,0x00000cfc,0x000000cb,0x0003003e,0x00000d02,0x00000d01, + 0x0004003d,0x0000000c,0x00000d03,0x00000cfc,0x0003003e,0x00000cfd,0x00000d03,0x0004003d, + 0x0000000c,0x00000cba,0x00000cfd,0x0004003d,0x00000024,0x00000cbb,0x00000ca1,0x0003003e, + 0x00000ca7,0x00000cbb,0x0004003d,0x00000024,0x00000d07,0x00000ca7,0x0007004f,0x0000000c, + 0x00000d08,0x00000d07,0x00000d07,0x00000000,0x00000001,0x0003003e,0x00000d04,0x00000d08, + 0x00050041,0x00000007,0x00000d0f,0x00000d04,0x000000c8,0x0004003d,0x00000006,0x00000d10, + 0x00000d0f,0x00050041,0x00000007,0x00000d11,0x00000d04,0x000000cb,0x0004003d,0x00000006, + 0x00000d12,0x00000d11,0x0007000c,0x00000006,0x00000d13,0x00000001,0x00000025,0x00000d10, + 0x00000d12,0x0003003e,0x00000d0d,0x00000d13,0x0004003d,0x00000006,0x00000d09,0x00000d0d, + 0x00050041,0x00000007,0x00000d0a,0x00000ca7,0x000000de,0x0004003d,0x00000006,0x00000d0b, + 0x00000d0a,0x0007000c,0x00000006,0x00000d0c,0x00000001,0x00000025,0x00000d09,0x00000d0b, + 0x0003003e,0x00000d05,0x00000d0c,0x0004003d,0x00000006,0x00000cbc,0x00000d05,0x0004007f, + 0x00000006,0x00000cbd,0x00000cbc,0x0004003d,0x00000024,0x00000cbe,0x00000ca1,0x0003003e, + 0x00000ca8,0x00000cbe,0x0004003d,0x00000024,0x00000d17,0x00000ca8,0x0007004f,0x0000000c, + 0x00000d18,0x00000d17,0x00000d17,0x00000000,0x00000001,0x0003003e,0x00000d14,0x00000d18, + 0x00050041,0x00000007,0x00000d1f,0x00000d14,0x000000c8,0x0004003d,0x00000006,0x00000d20, + 0x00000d1f,0x00050041,0x00000007,0x00000d21,0x00000d14,0x000000cb,0x0004003d,0x00000006, + 0x00000d22,0x00000d21,0x0007000c,0x00000006,0x00000d23,0x00000001,0x00000028,0x00000d20, + 0x00000d22,0x0003003e,0x00000d1d,0x00000d23,0x0004003d,0x00000006,0x00000d19,0x00000d1d, + 0x00050041,0x00000007,0x00000d1a,0x00000ca8,0x000000de,0x0004003d,0x00000006,0x00000d1b, + 0x00000d1a,0x0007000c,0x00000006,0x00000d1c,0x00000001,0x00000028,0x00000d19,0x00000d1b, + 0x0003003e,0x00000d15,0x00000d1c,0x0004003d,0x00000006,0x00000cbf,0x00000d15,0x0003003e, + 0x00000ca9,0x00000cbd,0x0003003e,0x00000caa,0x00000cbf,0x0004003d,0x00000006,0x00000d27, + 0x00000ca9,0x00050041,0x00000007,0x00000d28,0x00000d24,0x000000c8,0x0003003e,0x00000d28, + 0x00000d27,0x0004003d,0x00000006,0x00000d29,0x00000caa,0x00050041,0x00000007,0x00000d2a, + 0x00000d24,0x000000cb,0x0003003e,0x00000d2a,0x00000d29,0x0004003d,0x0000000c,0x00000d2b, + 0x00000d24,0x0003003e,0x00000d25,0x00000d2b,0x0004003d,0x0000000c,0x00000cc0,0x00000d25, + 0x0007000c,0x0000000c,0x00000cc1,0x00000001,0x00000028,0x00000cba,0x00000cc0,0x00050088, + 0x0000000c,0x00000cc2,0x00000cb9,0x00000cc1,0x0003003e,0x00000ca3,0x00000cc2,0x0003003e, + 0x00000cac,0x0000010a,0x0004003d,0x00000006,0x00000d2e,0x00000cac,0x0003003e,0x00000d2c, + 0x00000d2e,0x0004003d,0x00000006,0x00000cc3,0x00000d2c,0x00050041,0x00000007,0x00000cc4, + 0x00000ca3,0x000000c8,0x0004003d,0x00000006,0x00000cc5,0x00000cc4,0x00050041,0x00000007, + 0x00000cc6,0x00000ca3,0x000000cb,0x0004003d,0x00000006,0x00000cc7,0x00000cc6,0x0007000c, + 0x00000006,0x00000cc8,0x00000001,0x00000025,0x00000cc5,0x00000cc7,0x0007000c,0x00000006, + 0x00000cc9,0x00000001,0x00000025,0x00000cc3,0x00000cc8,0x0003003e,0x00000cab,0x00000cc9, + 0x0004003d,0x00000024,0x00000cca,0x00000ca1,0x0004003d,0x00000006,0x00000ccb,0x00000cab, + 0x0005008e,0x00000024,0x00000ccc,0x00000cca,0x00000ccb,0x0004003d,0x00000006,0x00000ccd, + 0x00000c9f,0x00060050,0x00000024,0x00000cce,0x00000ccd,0x00000ccd,0x00000ccd,0x00050081, + 0x00000024,0x00000ccf,0x00000ccc,0x00000cce,0x0003003e,0x00000cad,0x00000ccf,0x0004003d, + 0x00000024,0x00000953,0x00000cad,0x0003003e,0x00000838,0x00000953,0x000200f9,0x00000954, + 0x000200f8,0x00000954,0x000200f9,0x00000955,0x000200f8,0x00000955,0x0004003d,0x00000024, + 0x00000956,0x00000838,0x0003003e,0x0000085c,0x00000956,0x0004003d,0x00000024,0x0000082f, + 0x0000085c,0x0003003e,0x00000825,0x0000082f,0x0004003d,0x00000024,0x00000830,0x000006fd, + 0x0004003d,0x00000024,0x00000831,0x00000825,0x00050041,0x00000007,0x00000832,0x000006fe, + 0x000000f5,0x0004003d,0x00000006,0x00000833,0x00000832,0x0003003e,0x00000829,0x00000833, + 0x0004003d,0x00000006,0x00000d32,0x00000829,0x00050041,0x00000007,0x00000d33,0x00000d2f, + 0x000000c8,0x0003003e,0x00000d33,0x00000d32,0x0004003d,0x00000006,0x00000d34,0x00000829, + 0x00050041,0x00000007,0x00000d35,0x00000d2f,0x000000cb,0x0003003e,0x00000d35,0x00000d34, + 0x0004003d,0x00000006,0x00000d36,0x00000829,0x00050041,0x00000007,0x00000d37,0x00000d2f, + 0x000000de,0x0003003e,0x00000d37,0x00000d36,0x0004003d,0x00000024,0x00000d38,0x00000d2f, + 0x0003003e,0x00000d30,0x00000d38,0x0004003d,0x00000024,0x00000834,0x00000d30,0x0008000c, + 0x00000024,0x00000835,0x00000001,0x0000002e,0x00000830,0x00000831,0x00000834,0x0003003e, + 0x0000082a,0x00000835,0x0004003d,0x00000024,0x000007c1,0x0000082a,0x00050041,0x00000007, + 0x000007c2,0x000005a0,0x000000c8,0x00050051,0x00000006,0x000007c3,0x000007c1,0x00000000, + 0x0003003e,0x000007c2,0x000007c3,0x00050041,0x00000007,0x000007c4,0x000005a0,0x000000cb, + 0x00050051,0x00000006,0x000007c5,0x000007c1,0x00000001,0x0003003e,0x000007c4,0x000007c5, + 0x00050041,0x00000007,0x000007c6,0x000005a0,0x000000de,0x00050051,0x00000006,0x000007c7, + 0x000007c1,0x00000002,0x0003003e,0x000007c6,0x000007c7,0x000200f9,0x000007c8,0x000200f8, + 0x000007c8,0x0004003d,0x00000006,0x000007ca,0x000007a7,0x0004003d,0x0000002f,0x000007cb, + 0x000005a0,0x0008004f,0x00000024,0x000007cc,0x000007cb,0x000007cb,0x00000000,0x00000001, + 0x00000002,0x0005008e,0x00000024,0x000007cd,0x000007cc,0x000007ca,0x00050041,0x00000007, + 0x000007ce,0x000005a0,0x000000c8,0x00050051,0x00000006,0x000007cf,0x000007cd,0x00000000, + 0x0003003e,0x000007ce,0x000007cf,0x00050041,0x00000007,0x000007d0,0x000005a0,0x000000cb, + 0x00050051,0x00000006,0x000007d1,0x000007cd,0x00000001,0x0003003e,0x000007d0,0x000007d1, + 0x00050041,0x00000007,0x000007d2,0x000005a0,0x000000de,0x00050051,0x00000006,0x000007d3, + 0x000007cd,0x00000002,0x0003003e,0x000007d2,0x000007d3,0x0004003d,0x0000002f,0x000005a6, + 0x000005a0,0x0003003e,0x00000557,0x000005a6,0x0004003d,0x0000002f,0x000005a7,0x000005a1, + 0x0003003e,0x0000055a,0x000005a7,0x000200f9,0x00000580,0x000200f8,0x00000580,0x0004003d, + 0x0000002f,0x000005af,0x00000557,0x0008004f,0x00000024,0x000005b0,0x000005af,0x000005af, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x000005ae,0x000005b0,0x0003003e,0x000005b1, + 0x0000052b,0x00050041,0x000005b5,0x000005b6,0x000005ab,0x000000c8,0x0004003d,0x00000006, + 0x000005b7,0x000005b6,0x0003003e,0x000005b4,0x000005b7,0x00050041,0x000005b5,0x000005b9, + 0x000005ab,0x000000cb,0x0004003d,0x00000006,0x000005ba,0x000005b9,0x0003003e,0x000005b8, + 0x000005ba,0x000300f7,0x00000d49,0x00000000,0x000400fa,0x00000161,0x00000d3f,0x00000d47, + 0x000200f8,0x00000d3f,0x0004003d,0x0000000c,0x00000d40,0x000005b1,0x0003003e,0x00000d3a, + 0x00000d40,0x0004003d,0x00000006,0x00000d41,0x000005b4,0x0003003e,0x00000d3b,0x00000d41, + 0x0004003d,0x00000006,0x00000d42,0x000005b8,0x0003003e,0x00000d3c,0x00000d42,0x00050041, + 0x00000007,0x00000d4f,0x00000d3a,0x000000c8,0x0004003d,0x00000006,0x00000d50,0x00000d4f, + 0x00050085,0x00000006,0x00000d51,0x0000014b,0x00000d50,0x00050041,0x00000007,0x00000d52, + 0x00000d3a,0x000000cb,0x0004003d,0x00000006,0x00000d53,0x00000d52,0x00050085,0x00000006, + 0x00000d54,0x0000014f,0x00000d53,0x00050081,0x00000006,0x00000d55,0x00000d51,0x00000d54, + 0x0006000c,0x00000006,0x00000d56,0x00000001,0x0000000a,0x00000d55,0x0003003e,0x00000d4b, + 0x00000d56,0x0004003d,0x00000006,0x00000d57,0x00000d4b,0x00050085,0x00000006,0x00000d58, + 0x00000156,0x00000d57,0x0006000c,0x00000006,0x00000d59,0x00000001,0x0000000a,0x00000d58, + 0x0003003e,0x00000d4c,0x00000d59,0x0004003d,0x00000006,0x00000d5a,0x00000d4c,0x0004003d, + 0x00000006,0x00000d5b,0x00000d3b,0x00050085,0x00000006,0x00000d5c,0x00000d5a,0x00000d5b, + 0x0004003d,0x00000006,0x00000d5d,0x00000d3c,0x00050081,0x00000006,0x00000d5e,0x00000d5c, + 0x00000d5d,0x0003003e,0x00000d4d,0x00000d5e,0x0004003d,0x00000006,0x00000d43,0x00000d4d, + 0x0004003d,0x00000024,0x00000d44,0x000005ae,0x00060050,0x00000024,0x00000d45,0x00000d43, + 0x00000d43,0x00000d43,0x00050081,0x00000024,0x00000d46,0x00000d45,0x00000d44,0x0003003e, + 0x00000d39,0x00000d46,0x000200f9,0x00000d49,0x000200f8,0x00000d47,0x0004003d,0x00000024, + 0x00000d48,0x000005ae,0x0003003e,0x00000d39,0x00000d48,0x000200f9,0x00000d49,0x000200f8, + 0x00000d49,0x0004003d,0x00000024,0x00000d4a,0x00000d39,0x0003003e,0x00000d3d,0x00000d4a, + 0x0004003d,0x00000024,0x000005bb,0x00000d3d,0x00050041,0x00000007,0x000005bc,0x00000557, + 0x000000c8,0x00050051,0x00000006,0x000005bd,0x000005bb,0x00000000,0x0003003e,0x000005bc, + 0x000005bd,0x00050041,0x00000007,0x000005be,0x00000557,0x000000cb,0x00050051,0x00000006, + 0x000005bf,0x000005bb,0x00000001,0x0003003e,0x000005be,0x000005bf,0x00050041,0x00000007, + 0x000005c0,0x00000557,0x000000de,0x00050051,0x00000006,0x000005c1,0x000005bb,0x00000002, + 0x0003003e,0x000005c0,0x000005c1,0x0004003d,0x0000002f,0x000005c3,0x00000557,0x0003003e, + 0x000005c2,0x000005c3,0x0004003d,0x0000002f,0x00000d60,0x000005c2,0x0003003e,0x00000525, + 0x00000d60,0x0004003d,0x0000002f,0x000005c8,0x0000055a,0x0003003e,0x000005c7,0x000005c8, + 0x0004003d,0x0000002f,0x00000d62,0x000005c7,0x0003003e,0x00000527,0x00000d62,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ec4e79ffb7b3f7620c6949b11397249750f75b91 GIT binary patch literal 59780 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 ctC05JLwr(vmfI2Py9#OaK4? literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.h new file mode 100644 index 000000000..07e047d03 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.h @@ -0,0 +1,518 @@ +#pragma once + +const uint32_t atomic_draw_path_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000a23,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000423,0x00000426,0x00000429, + 0x0000042a,0x0000043e,0x00000441,0x0000045e,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x00000107,0x00004342,0x00030005,0x00000118,0x0000664b, + 0x00040006,0x00000118,0x00000000,0x00003464,0x00030005,0x0000011a,0x00004358,0x00030005, + 0x0000012d,0x0000664a,0x00040006,0x0000012d,0x00000000,0x00003464,0x00030005,0x0000012f, + 0x0000424c,0x00030005,0x0000040f,0x0000424d,0x00040006,0x0000040f,0x00000000,0x00006250, + 0x00040006,0x0000040f,0x00000001,0x00006359,0x00040006,0x0000040f,0x00000002,0x00006552, + 0x00040006,0x0000040f,0x00000003,0x00006553,0x00040006,0x0000040f,0x00000004,0x0000366d, + 0x00040006,0x0000040f,0x00000005,0x0000676d,0x00040006,0x0000040f,0x00000006,0x00006544, + 0x00040006,0x0000040f,0x00000007,0x00006545,0x00040006,0x0000040f,0x00000008,0x00003755, + 0x00040006,0x0000040f,0x00000009,0x0000676a,0x00040006,0x0000040f,0x0000000a,0x0000635a, + 0x00040006,0x0000040f,0x0000000b,0x00003157,0x00040006,0x0000040f,0x0000000c,0x0000676e, + 0x00040006,0x0000040f,0x0000000d,0x00003559,0x00040006,0x0000040f,0x0000000e,0x0000324f, + 0x00040006,0x0000040f,0x0000000f,0x00006461,0x00040006,0x0000040f,0x00000010,0x00006579, + 0x00040006,0x0000040f,0x00000011,0x00003376,0x00040006,0x0000040f,0x00000012,0x00003377, + 0x00040006,0x0000040f,0x00000013,0x00006462,0x00040006,0x0000040f,0x00000014,0x00006767, + 0x00030005,0x00000411,0x0000006b,0x00060005,0x00000423,0x565f6c67,0x65747265,0x646e4978, + 0x00007865,0x00070005,0x00000426,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000, + 0x00030005,0x00000429,0x00004254,0x00030005,0x0000042a,0x00004255,0x00030005,0x0000043e, + 0x00000049,0x00030005,0x00000441,0x0000307a,0x00060005,0x0000045c,0x505f6c67,0x65567265, + 0x78657472,0x00000000,0x00060006,0x0000045c,0x00000000,0x505f6c67,0x7469736f,0x006e6f69, + 0x00070006,0x0000045c,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006, + 0x0000045c,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000045c, + 0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x0000045e,0x00000000, + 0x00030005,0x0000046f,0x00004351,0x00030005,0x00000471,0x00006576,0x00040006,0x00000471, + 0x00000000,0x00003464,0x00030005,0x00000473,0x00004355,0x00030005,0x00000475,0x00006577, + 0x00040006,0x00000475,0x00000000,0x00003464,0x00030005,0x00000477,0x0000424f,0x00030005, + 0x0000047a,0x00003954,0x00040047,0x00000107,0x00000021,0x00000008,0x00040047,0x00000107, + 0x00000022,0x00000000,0x00040047,0x00000117,0x00000006,0x00000010,0x00030047,0x00000118, + 0x00000003,0x00040048,0x00000118,0x00000000,0x00000018,0x00050048,0x00000118,0x00000000, + 0x00000023,0x00000000,0x00030047,0x0000011a,0x00000018,0x00040047,0x0000011a,0x00000021, + 0x00000006,0x00040047,0x0000011a,0x00000022,0x00000000,0x00040047,0x0000012c,0x00000006, + 0x00000010,0x00030047,0x0000012d,0x00000003,0x00040048,0x0000012d,0x00000000,0x00000018, + 0x00050048,0x0000012d,0x00000000,0x00000023,0x00000000,0x00030047,0x0000012f,0x00000018, + 0x00040047,0x0000012f,0x00000021,0x00000003,0x00040047,0x0000012f,0x00000022,0x00000000, + 0x00030047,0x0000040f,0x00000002,0x00050048,0x0000040f,0x00000000,0x00000023,0x00000000, + 0x00050048,0x0000040f,0x00000001,0x00000023,0x00000004,0x00050048,0x0000040f,0x00000002, + 0x00000023,0x00000008,0x00050048,0x0000040f,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x0000040f,0x00000004,0x00000023,0x00000010,0x00050048,0x0000040f,0x00000005,0x00000023, + 0x00000014,0x00050048,0x0000040f,0x00000006,0x00000023,0x00000018,0x00050048,0x0000040f, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x0000040f,0x00000008,0x00000023,0x00000020, + 0x00050048,0x0000040f,0x00000009,0x00000023,0x00000030,0x00050048,0x0000040f,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x0000040f,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x0000040f,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000040f,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x0000040f,0x0000000e,0x00000023,0x0000004c,0x00050048,0x0000040f, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x0000040f,0x00000010,0x00000023,0x00000054, + 0x00050048,0x0000040f,0x00000011,0x00000023,0x00000058,0x00050048,0x0000040f,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x0000040f,0x00000013,0x00000023,0x00000060,0x00050048, + 0x0000040f,0x00000014,0x00000023,0x00000064,0x00040047,0x00000411,0x00000021,0x00000000, + 0x00040047,0x00000411,0x00000022,0x00000000,0x00040047,0x00000423,0x0000000b,0x0000002a, + 0x00040047,0x00000426,0x0000000b,0x0000002b,0x00040047,0x00000429,0x0000001e,0x00000000, + 0x00040047,0x0000042a,0x0000001e,0x00000001,0x00040047,0x0000043e,0x0000001e,0x00000000, + 0x00030047,0x00000441,0x00000000,0x00030047,0x00000441,0x0000000e,0x00040047,0x00000441, + 0x0000001e,0x00000001,0x00030047,0x0000045c,0x00000002,0x00050048,0x0000045c,0x00000000, + 0x0000000b,0x00000000,0x00050048,0x0000045c,0x00000001,0x0000000b,0x00000001,0x00050048, + 0x0000045c,0x00000002,0x0000000b,0x00000003,0x00050048,0x0000045c,0x00000003,0x0000000b, + 0x00000004,0x00030047,0x0000046f,0x00000000,0x00040047,0x0000046f,0x00000021,0x0000000a, + 0x00040047,0x0000046f,0x00000022,0x00000000,0x00040047,0x00000470,0x00000006,0x00000008, + 0x00030047,0x00000471,0x00000003,0x00040048,0x00000471,0x00000000,0x00000018,0x00050048, + 0x00000471,0x00000000,0x00000023,0x00000000,0x00030047,0x00000473,0x00000018,0x00040047, + 0x00000473,0x00000021,0x00000004,0x00040047,0x00000473,0x00000022,0x00000000,0x00040047, + 0x00000474,0x00000006,0x00000010,0x00030047,0x00000475,0x00000003,0x00040048,0x00000475, + 0x00000000,0x00000018,0x00050048,0x00000475,0x00000000,0x00000023,0x00000000,0x00030047, + 0x00000477,0x00000018,0x00040047,0x00000477,0x00000021,0x00000005,0x00040047,0x00000477, + 0x00000022,0x00000000,0x00030047,0x0000047a,0x00000000,0x00040047,0x0000047a,0x00000021, + 0x0000000a,0x00040047,0x0000047a,0x00000022,0x00000000,0x00030047,0x0000062a,0x00000000, + 0x00030047,0x000009b1,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040015,0x0000000c,0x00000020,0x00000000,0x00040017, + 0x00000012,0x00000006,0x00000002,0x00020014,0x00000017,0x00040017,0x00000019,0x00000017, + 0x00000002,0x00040017,0x0000001e,0x00000006,0x00000004,0x00040018,0x00000020,0x00000012, + 0x00000002,0x00040015,0x00000032,0x00000020,0x00000001,0x00040017,0x00000034,0x00000032, + 0x00000002,0x0004002b,0x00000006,0x0000005e,0x3f800000,0x0004002b,0x00000006,0x0000005f, + 0x00000000,0x0004002b,0x0000000c,0x00000069,0x00000000,0x0004002b,0x0000000c,0x0000006f, + 0x00000001,0x0004002b,0x00000006,0x00000081,0x3f000000,0x0004002b,0x00000006,0x00000084, + 0x3fc90fdb,0x0004002b,0x00000006,0x00000087,0x3a83126f,0x0004002b,0x00000006,0x00000096, + 0x358637bd,0x0004002b,0x00000006,0x000000b3,0x3e800000,0x0004002b,0x00000006,0x000000b9, + 0xc0000000,0x0004002b,0x00000032,0x000000c6,0x000007ff,0x0004002b,0x00000032,0x000000c9, + 0x0000000b,0x0004002b,0x00000032,0x000000ee,0x00000002,0x0004002b,0x00000032,0x000000f4, + 0x00000003,0x0004002b,0x00000032,0x000000f9,0x00000001,0x00040017,0x00000102,0x0000000c, + 0x00000004,0x00090019,0x00000105,0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x00000106,0x00000000,0x00000105,0x0004003b,0x00000106, + 0x00000107,0x00000000,0x0004002b,0x00000032,0x0000010c,0x00000000,0x0004002b,0x0000000c, + 0x00000113,0x0000ffff,0x0003001d,0x00000117,0x00000102,0x0003001e,0x00000118,0x00000117, + 0x00040020,0x00000119,0x00000002,0x00000118,0x0004003b,0x00000119,0x0000011a,0x00000002, + 0x00040020,0x0000011d,0x00000002,0x00000102,0x00040017,0x00000121,0x0000000c,0x00000002, + 0x0003001d,0x0000012c,0x00000102,0x0003001e,0x0000012d,0x0000012c,0x00040020,0x0000012e, + 0x00000002,0x0000012d,0x0004003b,0x0000012e,0x0000012f,0x00000002,0x0004002b,0x0000000c, + 0x00000131,0x00000004,0x0004002b,0x0000000c,0x0000014c,0x00800000,0x0004002b,0x0000000c, + 0x0000016c,0x0080ffff,0x0004002b,0x0000000c,0x0000018c,0xff7fffff,0x0004002b,0x0000000c, + 0x00000191,0x1c000000,0x0004002b,0x0000000c,0x00000193,0x04000000,0x0004002b,0x00000032, + 0x000001a3,0x00000010,0x0004002b,0x00000006,0x000001e8,0x40490fdb,0x0004002b,0x00000006, + 0x000001ec,0x40c90fdb,0x0004002b,0x00000006,0x00000221,0x40000000,0x0004002b,0x0000000c, + 0x0000025b,0x00100000,0x0004002b,0x0000000c,0x00000263,0x00080000,0x0004002b,0x0000000c, + 0x000002b1,0x08000000,0x0004002b,0x0000000c,0x000002b7,0x00400000,0x0004002b,0x00000006, + 0x000002eb,0xbf000000,0x0004002b,0x0000000c,0x00000302,0x14000000,0x0004002b,0x0000000c, + 0x00000308,0x10000000,0x0004002b,0x0000000c,0x00000312,0x02000000,0x0004002b,0x0000000c, + 0x0000032a,0x00200000,0x0004002b,0x00000006,0x00000335,0x3e000000,0x0004002b,0x00000006, + 0x00000383,0x38d1b717,0x0003002a,0x00000017,0x00000397,0x0004002b,0x00000006,0x0000039b, + 0xbf800000,0x0004002b,0x00000006,0x000003a2,0x49742400,0x0004002b,0x0000000c,0x000003ec, + 0x01000000,0x0007002c,0x0000001e,0x000003f2,0x0000039b,0x0000005e,0x0000005e,0x0000005e, + 0x0004002b,0x0000000c,0x000003fb,0x80000000,0x0005002c,0x00000012,0x0000040d,0x0000005e, + 0x0000039b,0x00040017,0x0000040e,0x00000032,0x00000004,0x0017001e,0x0000040f,0x00000006, + 0x00000006,0x00000006,0x00000006,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x0000040e, + 0x00000012,0x00000012,0x0000000c,0x00000006,0x0000000c,0x00000006,0x00000006,0x0000000c, + 0x00000006,0x00000006,0x00000006,0x0000000c,0x00040020,0x00000410,0x00000002,0x0000040f, + 0x0004003b,0x00000410,0x00000411,0x00000002,0x0004002b,0x00000032,0x00000412,0x00000014, + 0x00040020,0x00000413,0x00000002,0x0000000c,0x00030029,0x00000017,0x0000041e,0x00040020, + 0x00000422,0x00000001,0x00000032,0x0004003b,0x00000422,0x00000423,0x00000001,0x0004003b, + 0x00000422,0x00000426,0x00000001,0x00040020,0x00000428,0x00000001,0x0000001e,0x0004003b, + 0x00000428,0x00000429,0x00000001,0x0004003b,0x00000428,0x0000042a,0x00000001,0x00040020, + 0x0000043d,0x00000003,0x0000001e,0x0004003b,0x0000043d,0x0000043e,0x00000003,0x00040020, + 0x00000440,0x00000003,0x0000000c,0x0004003b,0x00000440,0x00000441,0x00000003,0x00040020, + 0x00000449,0x00000002,0x00000006,0x0004002b,0x00000032,0x00000451,0x0000000e,0x0004001c, + 0x0000045b,0x00000006,0x0000006f,0x0006001e,0x0000045c,0x0000001e,0x00000006,0x0000045b, + 0x0000045b,0x00040020,0x0000045d,0x00000003,0x0000045c,0x0004003b,0x0000045d,0x0000045e, + 0x00000003,0x00090019,0x0000046d,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x0000046e,0x00000000,0x0000046d,0x0004003b,0x0000046e, + 0x0000046f,0x00000000,0x0003001d,0x00000470,0x00000121,0x0003001e,0x00000471,0x00000470, + 0x00040020,0x00000472,0x00000002,0x00000471,0x0004003b,0x00000472,0x00000473,0x00000002, + 0x0003001d,0x00000474,0x0000001e,0x0003001e,0x00000475,0x00000474,0x00040020,0x00000476, + 0x00000002,0x00000475,0x0004003b,0x00000476,0x00000477,0x00000002,0x0002001a,0x00000478, + 0x00040020,0x00000479,0x00000000,0x00000478,0x0004003b,0x00000479,0x0000047a,0x00000000, + 0x00030001,0x00000006,0x00000917,0x00030001,0x00000012,0x000009fe,0x0005002c,0x00000012, + 0x00000a15,0x0000005e,0x0000005e,0x0005002c,0x00000012,0x00000a16,0x00000081,0x00000081, + 0x0004002b,0x00000032,0x00000a18,0xfffffffe,0x0004002b,0x00000006,0x00000a19,0x3ea2f983, + 0x0004002b,0x00000006,0x00000a1a,0xc0400000,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000032,0x00000427,0x00000426,0x0004003d, + 0x0000001e,0x0000042f,0x00000429,0x0004003d,0x0000001e,0x00000431,0x0000042a,0x000300f7, + 0x00000788,0x00000000,0x000300fb,0x00000069,0x000004da,0x000200f8,0x000004da,0x00050051, + 0x00000006,0x000004dc,0x0000042f,0x00000000,0x0004006e,0x00000032,0x000004dd,0x000004dc, + 0x00050051,0x00000006,0x000004df,0x0000042f,0x00000001,0x00050051,0x00000006,0x000004e1, + 0x0000042f,0x00000002,0x00050051,0x00000006,0x000004e3,0x0000042f,0x00000003,0x0004007c, + 0x00000032,0x000004e4,0x000004e3,0x000500c3,0x00000032,0x000004e5,0x000004e4,0x000000ee, + 0x000500c7,0x00000032,0x000004e9,0x000004e4,0x000000f4,0x00050082,0x00000032,0x000004ec, + 0x000004e5,0x000000f9,0x0007000c,0x00000032,0x000004ed,0x00000001,0x00000027,0x000004dd, + 0x000004ec,0x00050084,0x00000032,0x000004f0,0x00000427,0x000004e5,0x00050080,0x00000032, + 0x000004f2,0x000004f0,0x000004ed,0x0004003d,0x00000105,0x000004f3,0x00000107,0x000500c7, + 0x00000032,0x0000078d,0x000004f2,0x000000c6,0x000500c3,0x00000032,0x0000078f,0x000004f2, + 0x000000c9,0x00050050,0x00000034,0x00000790,0x0000078d,0x0000078f,0x0007005f,0x00000102, + 0x000004f6,0x000004f3,0x00000790,0x00000002,0x0000010c,0x00050051,0x0000000c,0x000004f8, + 0x000004f6,0x00000003,0x000500c7,0x0000000c,0x000004fa,0x000004f8,0x00000113,0x0007000c, + 0x0000000c,0x000004fb,0x00000001,0x00000029,0x000004fa,0x0000006f,0x00050082,0x0000000c, + 0x000004fd,0x000004fb,0x0000006f,0x00060041,0x0000011d,0x000004fe,0x0000011a,0x0000010c, + 0x000004fd,0x0004003d,0x00000102,0x000004ff,0x000004fe,0x0007004f,0x00000121,0x00000501, + 0x000004ff,0x000004ff,0x00000000,0x00000001,0x0004007c,0x00000012,0x00000502,0x00000501, + 0x00050051,0x0000000c,0x00000504,0x000004ff,0x00000002,0x000500c7,0x0000000c,0x00000505, + 0x00000504,0x00000113,0x00050051,0x0000000c,0x00000507,0x000004ff,0x00000003,0x00050084, + 0x0000000c,0x00000509,0x00000505,0x00000131,0x00060041,0x0000011d,0x0000050a,0x0000012f, + 0x0000010c,0x00000509,0x0004003d,0x00000102,0x0000050b,0x0000050a,0x0004007c,0x0000001e, + 0x0000050c,0x0000050b,0x00050051,0x00000006,0x00000797,0x0000050c,0x00000000,0x00050051, + 0x00000006,0x00000798,0x0000050c,0x00000001,0x00050051,0x00000006,0x00000799,0x0000050c, + 0x00000002,0x00050051,0x00000006,0x0000079a,0x0000050c,0x00000003,0x00050050,0x00000012, + 0x0000079b,0x00000797,0x00000798,0x00050050,0x00000012,0x0000079c,0x00000799,0x0000079a, + 0x00050050,0x00000020,0x0000079d,0x0000079b,0x0000079c,0x00050080,0x0000000c,0x00000510, + 0x00000509,0x0000006f,0x00060041,0x0000011d,0x00000511,0x0000012f,0x0000010c,0x00000510, + 0x0004003d,0x00000102,0x00000512,0x00000511,0x0007004f,0x00000121,0x00000514,0x00000512, + 0x00000512,0x00000000,0x00000001,0x0004007c,0x00000012,0x00000515,0x00000514,0x00050051, + 0x0000000c,0x00000517,0x00000512,0x00000002,0x0004007c,0x00000006,0x00000518,0x00000517, + 0x00050051,0x0000000c,0x0000051a,0x00000512,0x00000003,0x0004007c,0x00000006,0x0000051b, + 0x0000051a,0x000500c7,0x0000000c,0x0000051d,0x000004f8,0x0000014c,0x000500ab,0x00000017, + 0x0000051f,0x0000051d,0x00000069,0x000300f7,0x00000528,0x00000000,0x000400fa,0x0000051f, + 0x00000520,0x00000528,0x000200f8,0x00000520,0x00050051,0x00000006,0x00000522,0x00000431, + 0x00000000,0x0004006e,0x00000032,0x00000523,0x00000522,0x00050051,0x00000006,0x00000525, + 0x00000431,0x00000001,0x00050051,0x00000006,0x00000527,0x00000431,0x00000002,0x000200f9, + 0x00000528,0x000200f8,0x00000528,0x000700f5,0x00000006,0x000008fd,0x000004e1,0x000004da, + 0x00000527,0x00000520,0x000700f5,0x00000006,0x000008bf,0x000004df,0x000004da,0x00000525, + 0x00000520,0x000700f5,0x00000032,0x000008a3,0x000004dd,0x000004da,0x00000523,0x00000520, + 0x000500ab,0x00000017,0x0000052b,0x000008a3,0x000004ed,0x000300f7,0x00000558,0x00000000, + 0x000400fa,0x0000052b,0x0000052c,0x00000558,0x000200f8,0x0000052c,0x00050080,0x00000032, + 0x0000052f,0x000004f2,0x000008a3,0x00050082,0x00000032,0x00000531,0x0000052f,0x000004ed, + 0x0004003d,0x00000105,0x00000532,0x00000107,0x000500c7,0x00000032,0x000007a1,0x00000531, + 0x000000c6,0x000500c3,0x00000032,0x000007a3,0x00000531,0x000000c9,0x00050050,0x00000034, + 0x000007a4,0x000007a1,0x000007a3,0x0007005f,0x00000102,0x00000535,0x00000532,0x000007a4, + 0x00000002,0x0000010c,0x00050051,0x0000000c,0x00000537,0x00000535,0x00000003,0x000500c7, + 0x0000000c,0x00000538,0x00000537,0x0000016c,0x000500c7,0x0000000c,0x0000053a,0x000004f8, + 0x0000016c,0x000500ab,0x00000017,0x0000053b,0x00000538,0x0000053a,0x000300f7,0x00000552, + 0x00000000,0x000400fa,0x0000053b,0x0000053c,0x0000054f,0x000200f8,0x0000053c,0x000500b4, + 0x00000017,0x0000053e,0x00000518,0x0000005f,0x000400a8,0x00000017,0x0000053f,0x0000053e, + 0x000300f7,0x00000544,0x00000000,0x000400fa,0x0000053f,0x00000540,0x00000544,0x000200f8, + 0x00000540,0x00050051,0x00000006,0x00000542,0x00000502,0x00000000,0x000500b7,0x00000017, + 0x00000543,0x00000542,0x0000005f,0x000200f9,0x00000544,0x000200f8,0x00000544,0x000700f5, + 0x00000017,0x00000545,0x0000053e,0x0000053c,0x00000543,0x00000540,0x000300f7,0x0000054e, + 0x00000000,0x000400fa,0x00000545,0x00000547,0x0000054e,0x000200f8,0x00000547,0x0004007c, + 0x00000032,0x00000549,0x00000507,0x0004003d,0x00000105,0x0000054a,0x00000107,0x000500c7, + 0x00000032,0x000007a8,0x00000549,0x000000c6,0x000500c3,0x00000032,0x000007aa,0x00000549, + 0x000000c9,0x00050050,0x00000034,0x000007ab,0x000007a8,0x000007aa,0x0007005f,0x00000102, + 0x0000054d,0x0000054a,0x000007ab,0x00000002,0x0000010c,0x000200f9,0x0000054e,0x000200f8, + 0x0000054e,0x000700f5,0x00000032,0x000008b0,0x000004f2,0x00000544,0x00000549,0x00000547, + 0x000700f5,0x00000102,0x000008a8,0x000004f6,0x00000544,0x0000054d,0x00000547,0x000200f9, + 0x00000552,0x000200f8,0x0000054f,0x000200f9,0x00000552,0x000200f8,0x00000552,0x000700f5, + 0x00000032,0x000008af,0x000008b0,0x0000054e,0x00000531,0x0000054f,0x000700f5,0x00000102, + 0x000008a7,0x000008a8,0x0000054e,0x00000535,0x0000054f,0x00050051,0x0000000c,0x00000554, + 0x000008a7,0x00000003,0x000500c7,0x0000000c,0x00000555,0x00000554,0x0000018c,0x000500c5, + 0x0000000c,0x00000557,0x00000555,0x0000051d,0x000200f9,0x00000558,0x000200f8,0x00000558, + 0x000700f5,0x00000032,0x000008ae,0x000004f2,0x00000528,0x000008af,0x00000552,0x000700f5, + 0x00000102,0x000008ac,0x000004f6,0x00000528,0x000008a7,0x00000552,0x000700f5,0x0000000c, + 0x000008ab,0x000004f8,0x00000528,0x00000557,0x00000552,0x000500c7,0x0000000c,0x0000055a, + 0x000008ab,0x00000191,0x000500aa,0x00000017,0x0000055b,0x0000055a,0x00000193,0x000500aa, + 0x00000017,0x0000055d,0x000004e9,0x0000010c,0x000500a7,0x00000017,0x0000055e,0x0000055b, + 0x0000055d,0x000300f7,0x000005e9,0x00000000,0x000400fa,0x0000055e,0x0000055f,0x000005e5, + 0x000200f8,0x0000055f,0x00050051,0x0000000c,0x00000561,0x000008ac,0x00000002,0x000500c7, + 0x0000000c,0x00000563,0x00000561,0x00000113,0x00040070,0x00000006,0x00000564,0x00000563, + 0x000500c2,0x0000000c,0x00000566,0x00000561,0x000001a3,0x00040070,0x00000006,0x00000567, + 0x00000566,0x00050083,0x00000006,0x0000056a,0x0000039b,0x00000564,0x0004006e,0x00000032, + 0x0000056b,0x0000056a,0x00050083,0x00000006,0x0000056e,0x00000567,0x00000564,0x00050081, + 0x00000006,0x0000056f,0x0000056e,0x0000005e,0x0004006e,0x00000032,0x00000570,0x0000056f, + 0x00050050,0x00000034,0x00000571,0x0000056b,0x00000570,0x000500c7,0x0000000c,0x00000573, + 0x000008ab,0x0000014c,0x000500ab,0x00000017,0x00000574,0x00000573,0x00000069,0x000300f7, + 0x00000578,0x00000000,0x000400fa,0x00000574,0x00000575,0x00000578,0x000200f8,0x00000575, + 0x0004007e,0x00000034,0x00000577,0x00000571,0x000200f9,0x00000578,0x000200f8,0x00000578, + 0x000700f5,0x00000034,0x000008b2,0x00000571,0x0000055f,0x00000577,0x00000575,0x0004003d, + 0x00000105,0x00000579,0x00000107,0x00050051,0x00000032,0x0000057c,0x000008b2,0x00000000, + 0x00050080,0x00000032,0x0000057d,0x000008ae,0x0000057c,0x000500c7,0x00000032,0x000007af, + 0x0000057d,0x000000c6,0x000500c3,0x00000032,0x000007b1,0x0000057d,0x000000c9,0x00050050, + 0x00000034,0x000007b2,0x000007af,0x000007b1,0x0007005f,0x00000102,0x0000057f,0x00000579, + 0x000007b2,0x00000002,0x0000010c,0x0004003d,0x00000105,0x00000580,0x00000107,0x00050051, + 0x00000032,0x00000583,0x000008b2,0x00000001,0x00050080,0x00000032,0x00000584,0x000008ae, + 0x00000583,0x000500c7,0x00000032,0x000007b6,0x00000584,0x000000c6,0x000500c3,0x00000032, + 0x000007b8,0x00000584,0x000000c9,0x00050050,0x00000034,0x000007b9,0x000007b6,0x000007b8, + 0x0007005f,0x00000102,0x00000586,0x00000580,0x000007b9,0x00000002,0x0000010c,0x00050051, + 0x0000000c,0x00000588,0x00000586,0x00000003,0x000500c7,0x0000000c,0x00000589,0x00000588, + 0x0000016c,0x00050051,0x0000000c,0x0000058b,0x0000057f,0x00000003,0x000500c7,0x0000000c, + 0x0000058c,0x0000058b,0x0000016c,0x000500ab,0x00000017,0x0000058d,0x00000589,0x0000058c, + 0x000300f7,0x00000594,0x00000000,0x000400fa,0x0000058d,0x0000058e,0x00000594,0x000200f8, + 0x0000058e,0x0004003d,0x00000105,0x0000058f,0x00000107,0x0004007c,0x00000032,0x00000591, + 0x00000507,0x000500c7,0x00000032,0x000007bd,0x00000591,0x000000c6,0x000500c3,0x00000032, + 0x000007bf,0x00000591,0x000000c9,0x00050050,0x00000034,0x000007c0,0x000007bd,0x000007bf, + 0x0007005f,0x00000102,0x00000593,0x0000058f,0x000007c0,0x00000002,0x0000010c,0x000200f9, + 0x00000594,0x000200f8,0x00000594,0x000700f5,0x00000102,0x000008b3,0x00000586,0x00000578, + 0x00000593,0x0000058e,0x00050051,0x0000000c,0x00000596,0x0000057f,0x00000002,0x0004007c, + 0x00000006,0x00000597,0x00000596,0x00050051,0x0000000c,0x00000599,0x000008b3,0x00000002, + 0x0004007c,0x00000006,0x0000059a,0x00000599,0x00050083,0x00000006,0x0000059d,0x0000059a, + 0x00000597,0x0006000c,0x00000006,0x0000059f,0x00000001,0x00000004,0x0000059d,0x000500ba, + 0x00000017,0x000005a0,0x0000059f,0x000001e8,0x000300f7,0x000005a7,0x00000000,0x000400fa, + 0x000005a0,0x000005a1,0x000005a7,0x000200f8,0x000005a1,0x0006000c,0x00000006,0x000005a3, + 0x00000001,0x00000006,0x0000059d,0x00050085,0x00000006,0x000005a4,0x000001ec,0x000005a3, + 0x00050083,0x00000006,0x000005a6,0x0000059d,0x000005a4,0x000200f9,0x000005a7,0x000200f8, + 0x000005a7,0x000700f5,0x00000006,0x000008b7,0x0000059d,0x00000594,0x000005a6,0x000005a1, + 0x00050081,0x00000006,0x000005aa,0x00000567,0x000000b9,0x0006000c,0x00000006,0x000005ac, + 0x00000001,0x00000004,0x000008b7,0x00050085,0x00000006,0x000005ad,0x000005ac,0x00000a19, + 0x00050085,0x00000006,0x000005af,0x000005ad,0x000005aa,0x0006000c,0x00000006,0x000005b0, + 0x00000001,0x00000001,0x000005af,0x00050081,0x00000006,0x000005b2,0x00000567,0x00000a1a, + 0x0008000c,0x00000006,0x000005b3,0x00000001,0x0000002b,0x000005b0,0x0000005e,0x000005b2, + 0x00050083,0x00000006,0x000005b6,0x000005aa,0x000005b3,0x000500bc,0x00000017,0x000005b9, + 0x00000564,0x000005b6,0x000300f7,0x000005d6,0x00000000,0x000400fa,0x000005b9,0x000005ba, + 0x000005c9,0x000200f8,0x000005ba,0x0006000c,0x00000006,0x000005bc,0x00000001,0x00000006, + 0x000008b7,0x00050085,0x00000006,0x000005bd,0x000001e8,0x000005bc,0x00050083,0x00000006, + 0x000005bf,0x000005bd,0x000008b7,0x0004007f,0x00000006,0x000005c0,0x000005bf,0x000500b4, + 0x00000017,0x000005c4,0x00000564,0x000005b6,0x000300f7,0x000005c8,0x00000000,0x000400fa, + 0x000005c4,0x000005c5,0x000005c8,0x000200f8,0x000005c5,0x0004007f,0x00000006,0x000005c7, + 0x000008bf,0x000200f9,0x000005c8,0x000200f8,0x000005c8,0x000700f5,0x00000006,0x00000907, + 0x000008bf,0x000005ba,0x000005c7,0x000005c5,0x000200f9,0x000005d6,0x000200f8,0x000005c9, + 0x00050081,0x00000006,0x000005cc,0x000005b6,0x0000005e,0x000500b4,0x00000017,0x000005cd, + 0x00000564,0x000005cc,0x000300f7,0x000005d5,0x00000000,0x000400fa,0x000005cd,0x000005ce, + 0x000005cf,0x000200f8,0x000005ce,0x000200f9,0x000005d5,0x000200f8,0x000005cf,0x00050081, + 0x00000006,0x000005d1,0x000005b6,0x00000221,0x00050083,0x00000006,0x000005d3,0x00000564, + 0x000005d1,0x000200f9,0x000005d5,0x000200f8,0x000005d5,0x000700f5,0x00000006,0x000008c5, + 0x0000005f,0x000005ce,0x000005d3,0x000005cf,0x000600a9,0x00000006,0x00000a1d,0x000005cd, + 0x0000005f,0x000008bf,0x000600a9,0x00000006,0x00000a1e,0x000005cd,0x0000005f,0x000005b3, + 0x000200f9,0x000005d6,0x000200f8,0x000005d6,0x000700f5,0x00000006,0x00000906,0x00000907, + 0x000005c8,0x00000a1d,0x000005d5,0x000700f5,0x00000006,0x000008cd,0x000005c0,0x000005c8, + 0x000008b7,0x000005d5,0x000700f5,0x00000006,0x000008c6,0x000005b6,0x000005c8,0x00000a1e, + 0x000005d5,0x000700f5,0x00000006,0x000008c3,0x00000564,0x000005c8,0x000008c5,0x000005d5, + 0x000500b4,0x00000017,0x000005d9,0x000008c3,0x000008c6,0x000300f7,0x000005e4,0x00000000, + 0x000400fa,0x000005d9,0x000005da,0x000005dc,0x000200f8,0x000005da,0x000200f9,0x000005e4, + 0x000200f8,0x000005dc,0x00050088,0x00000006,0x000005e1,0x000008c3,0x000008c6,0x00050085, + 0x00000006,0x000005e2,0x000008cd,0x000005e1,0x00050081,0x00000006,0x000005e3,0x00000597, + 0x000005e2,0x000200f9,0x000005e4,0x000200f8,0x000005e4,0x000700f5,0x00000006,0x000008d1, + 0x0000059a,0x000005da,0x000005e3,0x000005dc,0x000200f9,0x000005e9,0x000200f8,0x000005e5, + 0x00050051,0x0000000c,0x000005e7,0x000008ac,0x00000002,0x0004007c,0x00000006,0x000005e8, + 0x000005e7,0x000200f9,0x000005e9,0x000200f8,0x000005e9,0x000700f5,0x00000006,0x0000091c, + 0x00000597,0x000005e4,0x00000917,0x000005e5,0x000700f5,0x00000006,0x00000913,0x000008cd, + 0x000005e4,0x00000917,0x000005e5,0x000700f5,0x00000006,0x00000904,0x00000906,0x000005e4, + 0x000008bf,0x000005e5,0x000700f5,0x00000006,0x000008d0,0x000008d1,0x000005e4,0x000005e8, + 0x000005e5,0x0006000c,0x00000006,0x000005eb,0x00000001,0x0000000d,0x000008d0,0x0006000c, + 0x00000006,0x000005ed,0x00000001,0x0000000e,0x000008d0,0x0004007f,0x00000006,0x000005ee, + 0x000005ed,0x00050050,0x00000012,0x000005ef,0x000005eb,0x000005ee,0x0007004f,0x00000121, + 0x000005f1,0x000008ac,0x000008ac,0x00000000,0x00000001,0x0004007c,0x00000012,0x000005f2, + 0x000005f1,0x000500b7,0x00000017,0x000005f4,0x0000051b,0x0000005f,0x000300f7,0x000005fd, + 0x00000000,0x000400fa,0x000005f4,0x000005f5,0x000005fd,0x000200f8,0x000005f5,0x00050091, + 0x00000012,0x000005f9,0x0000079d,0x000005ef,0x0006000c,0x00000006,0x000005fa,0x00000001, + 0x00000042,0x000005f9,0x00050088,0x00000006,0x000005fb,0x0000005e,0x000005fa,0x0007000c, + 0x00000006,0x000005fc,0x00000001,0x00000028,0x0000051b,0x000005fb,0x000200f9,0x000005fd, + 0x000200f8,0x000005fd,0x000700f5,0x00000006,0x00000902,0x0000051b,0x000005e9,0x000005fc, + 0x000005f5,0x000500b7,0x00000017,0x000005ff,0x00000518,0x0000005f,0x000300f7,0x00000775, + 0x00000000,0x000400fa,0x000005ff,0x00000600,0x00000715,0x000200f8,0x00000600,0x0006000c, + 0x00000006,0x00000602,0x00000001,0x00000021,0x0000079d,0x0006000c,0x00000006,0x00000603, + 0x00000001,0x00000006,0x00000602,0x00050085,0x00000006,0x00000605,0x00000904,0x00000603, + 0x000500c7,0x0000000c,0x00000607,0x000008ab,0x0000025b,0x000500ab,0x00000017,0x00000608, + 0x00000607,0x00000069,0x000300f7,0x0000060c,0x00000000,0x000400fa,0x00000608,0x00000609, + 0x0000060c,0x000200f8,0x00000609,0x0007000c,0x00000006,0x0000060b,0x00000001,0x00000025, + 0x00000605,0x0000005f,0x000200f9,0x0000060c,0x000200f8,0x0000060c,0x000700f5,0x00000006, + 0x00000955,0x00000605,0x00000600,0x0000060b,0x00000609,0x000500c7,0x0000000c,0x0000060e, + 0x000008ab,0x00000263,0x000500ab,0x00000017,0x0000060f,0x0000060e,0x00000069,0x000300f7, + 0x00000613,0x00000000,0x000400fa,0x0000060f,0x00000610,0x00000613,0x000200f8,0x00000610, + 0x0007000c,0x00000006,0x00000612,0x00000001,0x00000028,0x00000955,0x0000005f,0x000200f9, + 0x00000613,0x000200f8,0x00000613,0x000700f5,0x00000006,0x00000960,0x00000955,0x0000060c, + 0x00000612,0x00000610,0x000500b7,0x00000017,0x00000615,0x00000902,0x0000005f,0x000300f7, + 0x0000061d,0x00000000,0x000400fa,0x00000615,0x00000616,0x00000618,0x000200f8,0x00000616, + 0x000200f9,0x0000061d,0x000200f8,0x00000618,0x00050091,0x00000012,0x000007c6,0x0000079d, + 0x000005ef,0x00050051,0x00000006,0x000007c8,0x000007c6,0x00000000,0x0006000c,0x00000006, + 0x000007c9,0x00000001,0x00000004,0x000007c8,0x00050051,0x00000006,0x000007cb,0x000007c6, + 0x00000001,0x0006000c,0x00000006,0x000007cc,0x00000001,0x00000004,0x000007cb,0x00050081, + 0x00000006,0x000007cd,0x000007c9,0x000007cc,0x00050094,0x00000006,0x000007d0,0x000007c6, + 0x000007c6,0x00050088,0x00000006,0x000007d1,0x0000005e,0x000007d0,0x00050085,0x00000006, + 0x000007d2,0x000007cd,0x000007d1,0x00050085,0x00000006,0x0000061c,0x000007d2,0x00000081, + 0x000200f9,0x0000061d,0x000200f8,0x0000061d,0x000700f5,0x00000006,0x00000958,0x00000902, + 0x00000616,0x0000061c,0x00000618,0x000500ba,0x00000017,0x00000621,0x00000958,0x00000518, + 0x000500b4,0x00000017,0x00000623,0x00000902,0x0000005f,0x000500a7,0x00000017,0x00000624, + 0x00000621,0x00000623,0x000300f7,0x0000062c,0x00000000,0x000400fa,0x00000624,0x00000625, + 0x0000062c,0x000200f8,0x00000625,0x00050088,0x00000006,0x0000062a,0x00000518,0x00000958, + 0x000200f9,0x0000062c,0x000200f8,0x0000062c,0x000700f5,0x00000006,0x000009b1,0x0000005e, + 0x0000061d,0x0000062a,0x00000625,0x000600a9,0x00000006,0x00000a1f,0x00000624,0x00000958, + 0x00000518,0x00050081,0x00000006,0x00000630,0x00000a1f,0x00000958,0x0005008e,0x00000012, + 0x00000631,0x000005ef,0x00000630,0x00050085,0x00000006,0x00000636,0x00000960,0x00000630, + 0x00050088,0x00000006,0x00000639,0x00000081,0x00000958,0x0004007f,0x00000006,0x0000063c, + 0x00000636,0x00050050,0x00000012,0x0000063d,0x00000636,0x0000063c,0x00050050,0x00000012, + 0x0000063f,0x00000a1f,0x00000a1f,0x00050081,0x00000012,0x00000640,0x0000063d,0x0000063f, + 0x0005008e,0x00000012,0x00000641,0x00000640,0x00000639,0x00050081,0x00000012,0x00000643, + 0x00000641,0x00000a16,0x00050051,0x00000006,0x00000645,0x00000643,0x00000000,0x00050051, + 0x00000006,0x00000647,0x00000643,0x00000001,0x00070050,0x0000001e,0x00000a1c,0x00000645, + 0x00000647,0x0000005f,0x0000005f,0x000500ac,0x00000017,0x00000650,0x0000055a,0x000002b1, + 0x000300f7,0x000006f7,0x00000000,0x000400fa,0x00000650,0x00000651,0x000006f7,0x000200f8, + 0x00000651,0x000500c7,0x0000000c,0x00000653,0x000008ab,0x000002b7,0x000500aa,0x00000017, + 0x00000654,0x00000653,0x00000069,0x000600a9,0x00000032,0x00000a20,0x00000654,0x00000a18, + 0x000000ee,0x000500c7,0x0000000c,0x0000065a,0x000008ab,0x0000014c,0x000500ab,0x00000017, + 0x0000065b,0x0000065a,0x00000069,0x000300f7,0x0000065f,0x00000000,0x000400fa,0x0000065b, + 0x0000065c,0x0000065f,0x000200f8,0x0000065c,0x0004007e,0x00000032,0x0000065e,0x00000a20, + 0x000200f9,0x0000065f,0x000200f8,0x0000065f,0x000700f5,0x00000032,0x00000986,0x00000a20, + 0x00000651,0x0000065e,0x0000065c,0x00050080,0x00000032,0x00000662,0x000008ae,0x00000986, + 0x000500c7,0x00000032,0x000007e4,0x00000662,0x000000c6,0x000500c3,0x00000032,0x000007e6, + 0x00000662,0x000000c9,0x00050050,0x00000034,0x000007e7,0x000007e4,0x000007e6,0x0004003d, + 0x00000105,0x00000664,0x00000107,0x0007005f,0x00000102,0x00000666,0x00000664,0x000007e7, + 0x00000002,0x0000010c,0x00050051,0x0000000c,0x00000668,0x00000666,0x00000002,0x0004007c, + 0x00000006,0x00000669,0x00000668,0x00050083,0x00000006,0x0000066c,0x00000669,0x000008d0, + 0x0006000c,0x00000006,0x0000066d,0x00000001,0x00000004,0x0000066c,0x000500ba,0x00000017, + 0x0000066f,0x0000066d,0x000001e8,0x000300f7,0x00000673,0x00000000,0x000400fa,0x0000066f, + 0x00000670,0x00000673,0x000200f8,0x00000670,0x00050083,0x00000006,0x00000672,0x000001ec, + 0x0000066d,0x000200f9,0x00000673,0x000200f8,0x00000673,0x000700f5,0x00000006,0x0000098f, + 0x0000066d,0x0000065f,0x00000672,0x00000670,0x000500ab,0x00000017,0x00000676,0x00000653, + 0x00000069,0x000500a4,0x00000017,0x0000067d,0x00000676,0x00000608,0x000600a9,0x00000006, + 0x0000067e,0x0000067d,0x000002eb,0x00000081,0x00050085,0x00000006,0x0000067f,0x0000098f, + 0x0000067e,0x00050081,0x00000006,0x00000681,0x0000067f,0x000008d0,0x0006000c,0x00000006, + 0x00000683,0x00000001,0x0000000d,0x00000681,0x0006000c,0x00000006,0x00000685,0x00000001, + 0x0000000e,0x00000681,0x0004007f,0x00000006,0x00000686,0x00000685,0x00050050,0x00000012, + 0x00000687,0x00000683,0x00000686,0x00050091,0x00000012,0x000007ed,0x0000079d,0x00000687, + 0x00050051,0x00000006,0x000007ef,0x000007ed,0x00000000,0x0006000c,0x00000006,0x000007f0, + 0x00000001,0x00000004,0x000007ef,0x00050051,0x00000006,0x000007f2,0x000007ed,0x00000001, + 0x0006000c,0x00000006,0x000007f3,0x00000001,0x00000004,0x000007f2,0x00050081,0x00000006, + 0x000007f4,0x000007f0,0x000007f3,0x00050094,0x00000006,0x000007f7,0x000007ed,0x000007ed, + 0x00050088,0x00000006,0x000007f8,0x0000005e,0x000007f7,0x00050085,0x00000006,0x000007f9, + 0x000007f4,0x000007f8,0x00050085,0x00000006,0x0000068c,0x0000098f,0x00000081,0x0006000c, + 0x00000006,0x0000068d,0x00000001,0x0000000e,0x0000068c,0x000500aa,0x00000017,0x0000068f, + 0x0000055a,0x00000302,0x000400a8,0x00000017,0x00000690,0x0000068f,0x000300f7,0x00000697, + 0x00000000,0x000400fa,0x00000690,0x00000691,0x00000697,0x000200f8,0x00000691,0x000500aa, + 0x00000017,0x00000693,0x0000055a,0x00000308,0x000500be,0x00000017,0x00000695,0x0000068d, + 0x000000b3,0x000500a7,0x00000017,0x00000696,0x00000693,0x00000695,0x000200f9,0x00000697, + 0x000200f8,0x00000697,0x000700f5,0x00000017,0x00000698,0x0000068f,0x00000673,0x00000696, + 0x00000691,0x000300f7,0x000006ab,0x00000000,0x000400fa,0x00000698,0x00000699,0x000006a4, + 0x000200f8,0x00000699,0x000500c7,0x0000000c,0x0000069b,0x000008ab,0x00000312,0x000500ab, + 0x00000017,0x0000069c,0x0000069b,0x00000069,0x000600a9,0x00000006,0x0000069d,0x0000069c, + 0x0000005e,0x000000b3,0x0007000c,0x00000006,0x000006a1,0x00000001,0x00000028,0x0000068d, + 0x0000069d,0x00050088,0x00000006,0x000006a2,0x0000005e,0x000006a1,0x00050085,0x00000006, + 0x000006a3,0x00000a1f,0x000006a2,0x000200f9,0x000006ab,0x000200f8,0x000006a4,0x00050085, + 0x00000006,0x000006a7,0x00000a1f,0x0000068d,0x00050085,0x00000006,0x000006a9,0x000007f9, + 0x00000081,0x00050081,0x00000006,0x000006aa,0x000006a7,0x000006a9,0x000200f9,0x000006ab, + 0x000200f8,0x000006ab,0x000700f5,0x00000006,0x00000996,0x000006a3,0x00000699,0x000006aa, + 0x000006a4,0x00050085,0x00000006,0x000006ae,0x000007f9,0x00000081,0x00050081,0x00000006, + 0x000006af,0x00000996,0x000006ae,0x000500c7,0x0000000c,0x000006b1,0x000008ab,0x0000032a, + 0x000500ab,0x00000017,0x000006b2,0x000006b1,0x00000069,0x000300f7,0x000006e0,0x00000000, + 0x000400fa,0x000006b2,0x000006b3,0x000006e0,0x000200f8,0x000006b3,0x00050085,0x00000006, + 0x000006b8,0x00000958,0x00000335,0x00050085,0x00000006,0x000006bc,0x000006af,0x0000068d, + 0x00050081,0x00000006,0x000006be,0x000006bc,0x000006b8,0x000500bc,0x00000017,0x000006bf, + 0x00000630,0x000006be,0x000300f7,0x000006df,0x00000000,0x000400fa,0x000006bf,0x000006c0, + 0x000006c8,0x000200f8,0x000006c0,0x00050088,0x00000006,0x000006c3,0x0000005e,0x0000068d, + 0x00050085,0x00000006,0x000006c4,0x00000630,0x000006c3,0x0005008e,0x00000012,0x000006c7, + 0x00000687,0x000006c4,0x000200f9,0x000006df,0x000200f8,0x000006c8,0x0005008e,0x00000012, + 0x000006cb,0x00000687,0x000006af,0x00050094,0x00000006,0x000006ce,0x00000631,0x00000631, + 0x00050094,0x00000006,0x000006d1,0x000006cb,0x000006cb,0x00050050,0x00000012,0x000006d2, + 0x000006ce,0x000006d1,0x00050050,0x00000020,0x000006dc,0x00000631,0x000006cb,0x0006000c, + 0x00000020,0x000006dd,0x00000001,0x00000022,0x000006dc,0x00050090,0x00000012,0x000006de, + 0x000006d2,0x000006dd,0x000200f9,0x000006df,0x000200f8,0x000006df,0x000700f5,0x00000012, + 0x000009a6,0x000006c7,0x000006c0,0x000006de,0x000006c8,0x000200f9,0x000006e0,0x000200f8, + 0x000006e0,0x000700f5,0x00000012,0x000009a5,0x00000631,0x000006ab,0x000009a6,0x000006df, + 0x0006000c,0x00000006,0x000006e2,0x00000001,0x00000004,0x00000960,0x0005008e,0x00000012, + 0x000006e4,0x000009a5,0x000006e2,0x00050094,0x00000006,0x000006e8,0x000006e4,0x00000687, + 0x00050083,0x00000006,0x000006e9,0x000006af,0x000006e8,0x00050088,0x00000006,0x000006ec, + 0x000006e9,0x000007f9,0x000300f7,0x000006f6,0x00000000,0x000400fa,0x00000608,0x000006f0, + 0x000006f3,0x000200f8,0x000006f0,0x00060052,0x0000001e,0x0000087c,0x000006ec,0x00000a1c, + 0x00000001,0x000200f9,0x000006f6,0x000200f8,0x000006f3,0x00060052,0x0000001e,0x0000087e, + 0x000006ec,0x00000a1c,0x00000000,0x000200f9,0x000006f6,0x000200f8,0x000006f6,0x000700f5, + 0x0000001e,0x000009bb,0x0000087c,0x000006f0,0x0000087e,0x000006f3,0x000200f9,0x000006f7, + 0x000200f8,0x000006f7,0x000700f5,0x00000012,0x000009ca,0x00000631,0x0000062c,0x000009a5, + 0x000006f6,0x000700f5,0x0000001e,0x000009ba,0x00000a1c,0x0000062c,0x000009bb,0x000006f6, + 0x0007004f,0x00000012,0x000006fa,0x000009ba,0x000009ba,0x00000000,0x00000001,0x0005008e, + 0x00000012,0x000006fb,0x000006fa,0x000009b1,0x00050051,0x00000006,0x000006fd,0x000006fb, + 0x00000000,0x00060052,0x0000001e,0x00000880,0x000006fd,0x000009ba,0x00000000,0x00050051, + 0x00000006,0x000006ff,0x000006fb,0x00000001,0x0007000c,0x00000006,0x00000702,0x00000001, + 0x00000028,0x000006ff,0x00000383,0x00060052,0x0000001e,0x00000885,0x00000702,0x00000880, + 0x00000001,0x000300f7,0x0000070b,0x00000000,0x000400fa,0x00000615,0x00000706,0x0000070b, + 0x000200f8,0x00000706,0x00050083,0x00000006,0x00000709,0x000000b9,0x000006fd,0x00060052, + 0x0000001e,0x00000888,0x00000709,0x00000885,0x00000000,0x000200f9,0x0000070b,0x000200f8, + 0x0000070b,0x000700f5,0x0000001e,0x000009e9,0x00000885,0x000006f7,0x00000888,0x00000706, + 0x0005008e,0x00000012,0x0000070f,0x000009ca,0x00000960,0x00050091,0x00000012,0x00000710, + 0x0000079d,0x0000070f,0x000500ab,0x00000017,0x00000712,0x000004e9,0x0000010c,0x000300f7, + 0x00000714,0x00000000,0x000400fa,0x00000712,0x00000713,0x00000714,0x000200f8,0x00000713, + 0x000200f9,0x00000788,0x000200f8,0x00000714,0x000200f9,0x00000775,0x000200f8,0x00000715, + 0x00070050,0x0000001e,0x00000717,0x000008fd,0x0000039b,0x0000005f,0x0000005f,0x000500b7, + 0x00000017,0x00000719,0x00000902,0x0000005f,0x000300f7,0x0000075c,0x00000000,0x000400fa, + 0x00000719,0x0000071a,0x00000753,0x000200f8,0x0000071a,0x00060052,0x0000001e,0x0000088a, + 0x000000b9,0x00000717,0x00000001,0x00060052,0x0000001e,0x0000088c,0x000003a2,0x0000088a, + 0x00000002,0x00060052,0x0000001e,0x0000088e,0x000008fd,0x0000088c,0x00000003,0x000300f7, + 0x0000074b,0x00000000,0x000400fa,0x0000055e,0x00000725,0x0000074b,0x000200f8,0x00000725, + 0x000500b8,0x00000017,0x00000727,0x00000913,0x0000005f,0x000300f7,0x0000072e,0x00000000, + 0x000400fa,0x00000727,0x00000728,0x0000072e,0x000200f8,0x00000728,0x00050081,0x00000006, + 0x0000072b,0x0000091c,0x00000913,0x0004007f,0x00000006,0x0000072d,0x00000913,0x000200f9, + 0x0000072e,0x000200f8,0x0000072e,0x000700f5,0x00000006,0x00000926,0x00000913,0x00000725, + 0x0000072d,0x00000728,0x000700f5,0x00000006,0x00000925,0x0000091c,0x00000725,0x0000072b, + 0x00000728,0x00050083,0x00000006,0x00000731,0x000008d0,0x00000925,0x00050081,0x00000006, + 0x00000733,0x00000731,0x00000084,0x0005008d,0x00000006,0x00000734,0x00000733,0x000001ec, + 0x00050083,0x00000006,0x00000735,0x00000734,0x00000084,0x0008000c,0x00000006,0x00000738, + 0x00000001,0x0000002b,0x00000735,0x0000005f,0x00000926,0x00050085,0x00000006,0x0000073b, + 0x00000926,0x00000081,0x000500ba,0x00000017,0x0000073c,0x00000738,0x0000073b,0x000300f7, + 0x00000741,0x00000000,0x000400fa,0x0000073c,0x0000073d,0x00000741,0x000200f8,0x0000073d, + 0x00050083,0x00000006,0x00000740,0x00000926,0x00000738,0x000200f9,0x00000741,0x000200f8, + 0x00000741,0x000700f5,0x00000006,0x00000927,0x00000738,0x0000072e,0x00000740,0x0000073d, + 0x0006000c,0x00000006,0x00000743,0x00000001,0x0000000d,0x00000927,0x0006000c,0x00000006, + 0x00000745,0x00000001,0x0000000e,0x00000927,0x00050050,0x00000012,0x00000746,0x00000743, + 0x00000745,0x0006000c,0x00000006,0x00000804,0x00000001,0x00000004,0x00000904,0x0005008e, + 0x00000012,0x00000805,0x00000746,0x00000804,0x00050083,0x00000012,0x00000807,0x00000a15, + 0x00000805,0x0005008e,0x00000012,0x00000808,0x00000807,0x00000081,0x00050083,0x00000006, + 0x0000080a,0x00000926,0x00000084,0x0006000c,0x00000006,0x0000080b,0x00000001,0x00000004, + 0x0000080a,0x000500b8,0x00000017,0x0000080c,0x0000080b,0x00000087,0x000300f7,0x0000082d, + 0x00000000,0x000400fa,0x0000080c,0x0000080d,0x0000080e,0x000200f8,0x0000080d,0x000200f9, + 0x0000082d,0x000200f8,0x0000080e,0x0006000c,0x00000006,0x00000810,0x00000001,0x0000000f, + 0x00000926,0x00050083,0x00000006,0x00000812,0x00000084,0x00000926,0x0006000c,0x00000006, + 0x00000813,0x00000001,0x00000006,0x00000812,0x0006000c,0x00000006,0x00000815,0x00000001, + 0x00000004,0x00000810,0x0007000c,0x00000006,0x00000816,0x00000001,0x00000028,0x00000815, + 0x00000096,0x00050088,0x00000006,0x00000817,0x00000813,0x00000816,0x000500be,0x00000017, + 0x00000819,0x00000817,0x0000005f,0x000300f7,0x0000082b,0x00000000,0x000400fa,0x00000819, + 0x0000081a,0x00000823,0x000200f8,0x0000081a,0x00050051,0x00000006,0x0000081c,0x00000808, + 0x00000001,0x00050051,0x00000006,0x0000081e,0x00000808,0x00000000,0x00050083,0x00000006, + 0x0000081f,0x0000005e,0x0000081e,0x00050085,0x00000006,0x00000821,0x0000081f,0x00000810, + 0x00050083,0x00000006,0x00000822,0x0000081c,0x00000821,0x000200f9,0x0000082b,0x000200f8, + 0x00000823,0x00050051,0x00000006,0x00000825,0x00000808,0x00000001,0x00050051,0x00000006, + 0x00000827,0x00000808,0x00000000,0x00050085,0x00000006,0x00000829,0x00000827,0x00000810, + 0x00050081,0x00000006,0x0000082a,0x00000825,0x00000829,0x000200f9,0x0000082b,0x000200f8, + 0x0000082b,0x000700f5,0x00000006,0x0000092b,0x00000822,0x0000081a,0x0000082a,0x00000823, + 0x000200f9,0x0000082d,0x000200f8,0x0000082d,0x000700f5,0x00000006,0x00000941,0x0000005f, + 0x0000080d,0x0000092b,0x0000082b,0x000700f5,0x00000006,0x0000093f,0x0000005f,0x0000080d, + 0x00000817,0x0000082b,0x00050051,0x00000006,0x0000082f,0x00000808,0x00000000,0x0007000c, + 0x00000006,0x00000830,0x00000001,0x00000028,0x0000082f,0x0000005f,0x00050081,0x00000006, + 0x00000831,0x00000830,0x000000b3,0x00050051,0x00000006,0x00000834,0x00000808,0x00000001, + 0x00050083,0x00000006,0x00000836,0x000000b9,0x00000834,0x00070050,0x0000001e,0x00000a1b, + 0x00000831,0x00000836,0x0000093f,0x00000941,0x000200f9,0x0000074b,0x000200f8,0x0000074b, + 0x000700f5,0x0000001e,0x00000951,0x0000088e,0x0000071a,0x00000a1b,0x0000082d,0x00050085, + 0x00000006,0x0000074f,0x00000904,0x00000902,0x0005008e,0x00000012,0x00000751,0x000005ef, + 0x0000074f,0x00050091,0x00000012,0x00000752,0x0000079d,0x00000751,0x000200f9,0x0000075c, + 0x000200f8,0x00000753,0x0005008e,0x00000012,0x00000756,0x000005ef,0x00000904,0x0006000c, + 0x00000020,0x00000758,0x00000001,0x00000022,0x0000079d,0x00050090,0x00000012,0x00000759, + 0x00000756,0x00000758,0x0006000c,0x00000012,0x0000075a,0x00000001,0x00000006,0x00000759, + 0x0005008e,0x00000012,0x0000075b,0x0000075a,0x00000081,0x000200f9,0x0000075c,0x000200f8, + 0x0000075c,0x000700f5,0x00000012,0x000009e7,0x00000752,0x0000074b,0x0000075b,0x00000753, + 0x000700f5,0x0000001e,0x00000950,0x00000951,0x0000074b,0x00000717,0x00000753,0x000500c7, + 0x0000000c,0x0000075e,0x000008ab,0x0000014c,0x000500ab,0x00000017,0x0000075f,0x0000075e, + 0x00000069,0x000500c7,0x0000000c,0x00000761,0x000008ab,0x000003ec,0x000500ab,0x00000017, + 0x00000762,0x00000761,0x00000069,0x000500a5,0x00000017,0x00000763,0x0000075f,0x00000762, + 0x000300f7,0x00000767,0x00000000,0x000400fa,0x00000763,0x00000764,0x00000767,0x000200f8, + 0x00000764,0x00050085,0x0000001e,0x00000766,0x00000950,0x000003f2,0x000200f9,0x00000767, + 0x000200f8,0x00000767,0x000700f5,0x0000001e,0x000009eb,0x00000950,0x0000075c,0x00000766, + 0x00000764,0x000500aa,0x00000017,0x00000769,0x000004e9,0x000000ee,0x00050050,0x00000019, + 0x00000a21,0x00000769,0x00000769,0x000600a9,0x00000012,0x00000a22,0x00000a21,0x00000502, + 0x000005f2,0x000500c7,0x0000000c,0x0000076e,0x000008ab,0x000003fb,0x000500ab,0x00000017, + 0x0000076f,0x0000076e,0x00000069,0x000500ab,0x00000017,0x00000771,0x000004e9,0x000000f9, + 0x000500a7,0x00000017,0x00000772,0x0000076f,0x00000771,0x000300f7,0x00000774,0x00000000, + 0x000400fa,0x00000772,0x00000773,0x00000774,0x000200f8,0x00000773,0x000200f9,0x00000788, + 0x000200f8,0x00000774,0x000200f9,0x00000775,0x000200f8,0x00000775,0x000700f5,0x0000001e, + 0x000009e8,0x000009e9,0x00000714,0x000009eb,0x00000774,0x000700f5,0x00000012,0x000009e4, + 0x00000710,0x00000714,0x000009e7,0x00000774,0x000700f5,0x00000012,0x000009cc,0x000005f2, + 0x00000714,0x00000a22,0x00000774,0x00050091,0x00000012,0x00000778,0x0000079d,0x000009cc, + 0x00050081,0x00000012,0x0000077a,0x00000778,0x000009e4,0x00050081,0x00000012,0x0000077c, + 0x0000077a,0x00000515,0x0007004f,0x00000012,0x0000077e,0x000009e8,0x000009e8,0x00000000, + 0x00000001,0x00050041,0x00000413,0x0000077f,0x00000411,0x00000412,0x0004003d,0x0000000c, + 0x00000780,0x0000077f,0x000500ab,0x00000017,0x00000781,0x00000780,0x00000069,0x00050050, + 0x00000019,0x00000841,0x00000781,0x00000781,0x000600a9,0x00000012,0x00000783,0x00000841, + 0x0000040d,0x0000077e,0x00050051,0x00000006,0x00000785,0x00000783,0x00000000,0x00060052, + 0x0000001e,0x0000089e,0x00000785,0x000009e8,0x00000000,0x00050051,0x00000006,0x00000787, + 0x00000783,0x00000001,0x00060052,0x0000001e,0x000008a0,0x00000787,0x0000089e,0x00000001, + 0x000200f9,0x00000788,0x000200f8,0x00000788,0x000900f5,0x0000001e,0x00000a13,0x000009e9, + 0x00000713,0x000009eb,0x00000773,0x000008a0,0x00000775,0x000900f5,0x00000012,0x000009ed, + 0x000009fe,0x00000713,0x000009fe,0x00000773,0x0000077c,0x00000775,0x000900f5,0x00000017, + 0x000009ec,0x00000397,0x00000713,0x00000397,0x00000773,0x0000041e,0x00000775,0x000300f7, + 0x0000043c,0x00000000,0x000400fa,0x000009ec,0x0000043b,0x00000450,0x000200f8,0x0000043b, + 0x0003003e,0x0000043e,0x00000a13,0x0003003e,0x00000441,0x00000505,0x00050041,0x00000449, + 0x0000044a,0x00000411,0x000000ee,0x0004003d,0x00000006,0x0000044b,0x0000044a,0x00050041, + 0x00000449,0x0000044d,0x00000411,0x000000f4,0x0004003d,0x00000006,0x0000044e,0x0000044d, + 0x00050051,0x00000006,0x0000084a,0x000009ed,0x00000000,0x00050085,0x00000006,0x0000084c, + 0x0000084a,0x0000044b,0x00050083,0x00000006,0x0000084d,0x0000084c,0x0000005e,0x00050051, + 0x00000006,0x0000084f,0x000009ed,0x00000001,0x00050085,0x00000006,0x00000851,0x0000084f, + 0x0000044e,0x0006000c,0x00000006,0x00000853,0x00000001,0x00000006,0x0000044e,0x00050083, + 0x00000006,0x00000854,0x00000851,0x00000853,0x00070050,0x0000001e,0x00000855,0x0000084d, + 0x00000854,0x0000005f,0x0000005e,0x000200f9,0x0000043c,0x000200f8,0x00000450,0x00050041, + 0x00000449,0x00000452,0x00000411,0x00000451,0x0004003d,0x00000006,0x00000453,0x00000452, + 0x00070050,0x0000001e,0x0000045a,0x00000453,0x00000453,0x00000453,0x00000453,0x000200f9, + 0x0000043c,0x000200f8,0x0000043c,0x000700f5,0x0000001e,0x00000a14,0x00000855,0x0000043b, + 0x0000045a,0x00000450,0x00050041,0x0000043d,0x00000460,0x0000045e,0x0000010c,0x0003003e, + 0x00000460,0x00000a14,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_draw_path.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..4d00e8755bc0059bb0e9a2793155a3cf4a274c7f GIT binary patch literal 16432 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 P5%Ynk|9mn#HvRtqp)YJ* literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.h new file mode 100644 index 000000000..217e65c02 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.h @@ -0,0 +1,373 @@ +#pragma once + +const uint32_t atomic_resolve_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000035e,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000143, + 0x00000203,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x000000a1,0x0000674e,0x00030005,0x000000d9,0x00006576, + 0x00040006,0x000000d9,0x00000000,0x00003464,0x00030005,0x000000db,0x00004355,0x00030005, + 0x000000ec,0x0000674b,0x00030005,0x00000107,0x00006747,0x00040005,0x00000115,0x30653742, + 0x00000000,0x00030005,0x00000120,0x00006748,0x00030005,0x0000012e,0x00006577,0x00040006, + 0x0000012e,0x00000000,0x00003464,0x00030005,0x00000130,0x0000424f,0x00060005,0x00000143, + 0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x000001a5,0x00004444,0x00030005, + 0x000001a9,0x00006277,0x00030005,0x000001c1,0x00000045,0x00030005,0x000001c6,0x00003270, + 0x00030005,0x000001c9,0x00003470,0x00030005,0x000001cf,0x0000306e,0x00040005,0x000001d3, + 0x61726170,0x0000006d,0x00030005,0x000001d5,0x00003145,0x00040005,0x000001d9,0x61726170, + 0x0000006d,0x00040005,0x000001db,0x61726170,0x0000006d,0x00030005,0x000001de,0x00000050, + 0x00040005,0x000001df,0x61726170,0x0000006d,0x00040005,0x000001e1,0x61726170,0x0000006d, + 0x00040005,0x000001e3,0x61726170,0x0000006d,0x00030005,0x000001e9,0x0000424d,0x00040006, + 0x000001e9,0x00000000,0x00003376,0x00040006,0x000001e9,0x00000001,0x00003377,0x00030005, + 0x000001eb,0x0000006b,0x00040005,0x000001ee,0x61726170,0x0000006d,0x00040005,0x000001f1, + 0x61726170,0x0000006d,0x00040005,0x000001f4,0x61726170,0x0000006d,0x00040005,0x000001f8, + 0x61726170,0x0000006d,0x00030005,0x00000203,0x0000316d,0x00040047,0x000000a1,0x00000001, + 0x00000007,0x00040047,0x000000d8,0x00000006,0x00000008,0x00030047,0x000000d9,0x00000003, + 0x00040048,0x000000d9,0x00000000,0x00000018,0x00050048,0x000000d9,0x00000000,0x00000023, + 0x00000000,0x00030047,0x000000db,0x00000018,0x00040047,0x000000db,0x00000021,0x00000004, + 0x00040047,0x000000db,0x00000022,0x00000000,0x00040047,0x000000ec,0x00000001,0x00000004, + 0x00040047,0x00000107,0x00000001,0x00000000,0x00030047,0x00000115,0x00000000,0x00040047, + 0x00000115,0x00000021,0x00000001,0x00040047,0x00000115,0x00000022,0x00000002,0x00040047, + 0x00000115,0x0000002b,0x00000001,0x00040047,0x00000120,0x00000001,0x00000001,0x00040047, + 0x0000012d,0x00000006,0x00000010,0x00030047,0x0000012e,0x00000003,0x00040048,0x0000012e, + 0x00000000,0x00000018,0x00050048,0x0000012e,0x00000000,0x00000023,0x00000000,0x00030047, + 0x00000130,0x00000018,0x00040047,0x00000130,0x00000021,0x00000005,0x00040047,0x00000130, + 0x00000022,0x00000000,0x00040047,0x00000143,0x0000000b,0x0000000f,0x00030047,0x000001a5, + 0x00000000,0x00040047,0x000001a5,0x00000021,0x00000009,0x00040047,0x000001a5,0x00000022, + 0x00000000,0x00030047,0x000001a9,0x00000000,0x00040047,0x000001a9,0x00000021,0x00000009, + 0x00040047,0x000001a9,0x00000022,0x00000000,0x00030047,0x000001c9,0x00000017,0x00040047, + 0x000001c9,0x00000021,0x00000003,0x00040047,0x000001c9,0x00000022,0x00000002,0x00030047, + 0x000001cf,0x00000000,0x00030047,0x000001d5,0x00000000,0x00030047,0x000001db,0x00000000, + 0x00030047,0x000001dc,0x00000000,0x00030047,0x000001de,0x00000000,0x00030047,0x000001e0, + 0x00000000,0x00030047,0x000001e1,0x00000000,0x00030047,0x000001e2,0x00000000,0x00030047, + 0x000001e3,0x00000000,0x00030047,0x000001e9,0x00000002,0x00050048,0x000001e9,0x00000000, + 0x00000023,0x00000058,0x00050048,0x000001e9,0x00000001,0x00000023,0x0000005c,0x00040047, + 0x000001eb,0x00000021,0x00000000,0x00040047,0x000001eb,0x00000022,0x00000000,0x00030047, + 0x000001ee,0x00000000,0x00030047,0x000001ef,0x00000000,0x00030047,0x000001f0,0x00000000, + 0x00030047,0x000001f4,0x00000000,0x00030047,0x000001f8,0x00000000,0x00030047,0x00000203, + 0x00000000,0x00040047,0x00000203,0x0000001e,0x00000000,0x00030047,0x00000204,0x00000000, + 0x00030047,0x00000212,0x00000000,0x00030047,0x00000219,0x00000000,0x00030047,0x0000021a, + 0x00000000,0x00030047,0x0000021d,0x00000000,0x00030047,0x0000021e,0x00000000,0x00030047, + 0x0000021f,0x00000000,0x00030047,0x00000222,0x00000000,0x00030047,0x00000223,0x00000000, + 0x00030047,0x00000225,0x00000000,0x00030047,0x00000227,0x00000000,0x00030047,0x00000228, + 0x00000000,0x00030047,0x00000229,0x00000000,0x00030047,0x0000022c,0x00000000,0x00030047, + 0x0000022d,0x00000000,0x00030047,0x00000232,0x00000000,0x00030047,0x00000234,0x00000000, + 0x00030047,0x00000236,0x00000000,0x00030047,0x00000243,0x00000000,0x00030047,0x00000249, + 0x00000000,0x00030047,0x0000024a,0x00000000,0x00030047,0x00000253,0x00000000,0x00030047, + 0x00000254,0x00000000,0x00030047,0x00000255,0x00000000,0x00030047,0x00000256,0x00000000, + 0x00030047,0x00000257,0x00000000,0x00030047,0x00000258,0x00000000,0x00030047,0x00000259, + 0x00000000,0x00030047,0x0000025c,0x00000000,0x00030047,0x0000025f,0x00000000,0x00030047, + 0x00000267,0x00000000,0x00030047,0x00000268,0x00000000,0x00030047,0x0000026a,0x00000000, + 0x00030047,0x00000293,0x00000000,0x00030047,0x00000295,0x00000000,0x00030047,0x00000296, + 0x00000000,0x00030047,0x00000297,0x00000000,0x00030047,0x00000298,0x00000000,0x00030047, + 0x00000299,0x00000000,0x00030047,0x0000029a,0x00000000,0x00030047,0x0000029b,0x00000000, + 0x00030047,0x000002d4,0x00000000,0x00030047,0x000002d5,0x00000000,0x00030047,0x000002da, + 0x00000000,0x00030047,0x000002dc,0x00000000,0x00030047,0x000002de,0x00000000,0x00030047, + 0x000002df,0x00000000,0x00030047,0x000002e2,0x00000000,0x00030047,0x000002e3,0x00000000, + 0x00030047,0x000002e4,0x00000000,0x00030047,0x000002e5,0x00000000,0x00030047,0x000002ec, + 0x00000000,0x00030047,0x000002ee,0x00000000,0x00030047,0x000002ef,0x00000000,0x00030047, + 0x000002f1,0x00000000,0x00030047,0x000002f2,0x00000000,0x00030047,0x000002f4,0x00000000, + 0x00030047,0x000002f5,0x00000000,0x00030047,0x000002ff,0x00000000,0x00030047,0x00000301, + 0x00000000,0x00030047,0x00000302,0x00000000,0x00030047,0x00000305,0x00000000,0x00030047, + 0x00000306,0x00000000,0x00030047,0x00000308,0x00000000,0x00030047,0x0000030a,0x00000000, + 0x00030047,0x0000030c,0x00000000,0x00030047,0x0000031a,0x00000000,0x00030047,0x0000031b, + 0x00000000,0x00030047,0x0000031e,0x00000000,0x00030047,0x0000031f,0x00000000,0x00030047, + 0x00000320,0x00000000,0x00030047,0x00000322,0x00000000,0x00030047,0x00000324,0x00000000, + 0x00030047,0x00000326,0x00000000,0x00030047,0x00000328,0x00000000,0x00030047,0x0000032a, + 0x00000000,0x00030047,0x00000338,0x00000000,0x00030047,0x0000033a,0x00000000,0x00030047, + 0x0000033b,0x00000000,0x00030047,0x0000033c,0x00000000,0x00030047,0x00000340,0x00000000, + 0x00030047,0x00000341,0x00000000,0x00030047,0x00000343,0x00000000,0x00030047,0x00000344, + 0x00000000,0x00030047,0x00000345,0x00000000,0x00030047,0x00000347,0x00000000,0x00030047, + 0x00000349,0x00000000,0x00030047,0x0000034a,0x00000000,0x00030047,0x0000034b,0x00000000, + 0x00030047,0x0000034c,0x00000000,0x00030047,0x00000356,0x00000000,0x00030047,0x00000357, + 0x00000000,0x00030047,0x00000358,0x00000000,0x00030047,0x00000359,0x00000000,0x00030047, + 0x0000035a,0x00000000,0x00030047,0x0000035b,0x00000000,0x00030047,0x0000035c,0x00000000, + 0x00030047,0x0000035d,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017, + 0x0000000c,0x00000006,0x00000002,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040015, + 0x00000012,0x00000020,0x00000000,0x00040020,0x00000013,0x00000007,0x00000012,0x00040017, + 0x0000001f,0x00000006,0x00000004,0x00040020,0x00000024,0x00000007,0x0000001f,0x00040018, + 0x00000025,0x0000000c,0x00000002,0x00040017,0x00000030,0x00000006,0x00000003,0x00040020, + 0x00000031,0x00000007,0x00000030,0x00040015,0x00000046,0x00000020,0x00000001,0x00040017, + 0x00000047,0x00000046,0x00000002,0x00040020,0x00000048,0x00000007,0x00000047,0x0004002b, + 0x00000012,0x00000064,0x00000000,0x0004002b,0x00000012,0x00000067,0x00000001,0x0004002b, + 0x00000012,0x00000072,0x00000002,0x0004002b,0x00000012,0x00000075,0x00000003,0x0004002b, + 0x00000006,0x0000007e,0x3f800000,0x0004002b,0x00000006,0x0000007f,0x00000000,0x0004002b, + 0x00000006,0x0000008a,0x3d897143,0x0004002b,0x00000006,0x0000008e,0x3bbf4590,0x0004002b, + 0x00000006,0x00000095,0x4253ee82,0x00020014,0x000000a0,0x00030030,0x000000a0,0x000000a1, + 0x0004002b,0x00000006,0x000000b6,0x3a000000,0x0004002b,0x00000006,0x000000b8,0xc2000000, + 0x0004002b,0x00000006,0x000000c8,0x3a808081,0x00040017,0x000000cb,0x000000a0,0x00000002, + 0x00040017,0x000000d5,0x00000012,0x00000002,0x00040020,0x000000d6,0x00000007,0x000000d5, + 0x0003001d,0x000000d8,0x000000d5,0x0003001e,0x000000d9,0x000000d8,0x00040020,0x000000da, + 0x00000002,0x000000d9,0x0004003b,0x000000da,0x000000db,0x00000002,0x0004002b,0x00000046, + 0x000000dc,0x00000000,0x00040020,0x000000de,0x00000002,0x000000d5,0x0004002b,0x00000012, + 0x000000e5,0x00000300,0x00030030,0x000000a0,0x000000ec,0x0004002b,0x00000012,0x000000f1, + 0x00000200,0x0004002b,0x00000006,0x000000f8,0x3f000000,0x0004002b,0x00000006,0x000000fb, + 0x40000000,0x0004002b,0x00000006,0x000000fd,0xbf800000,0x00030030,0x000000a0,0x00000107, + 0x0004002b,0x00000012,0x0000010d,0x00000010,0x00090019,0x00000113,0x00000006,0x00000006, + 0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020,0x00000114,0x00000000, + 0x00000113,0x0004003b,0x00000114,0x00000115,0x00000000,0x0005002c,0x00000047,0x00000117, + 0x000000dc,0x000000dc,0x00030030,0x000000a0,0x00000120,0x0004002b,0x00000012,0x00000125, + 0x00000400,0x00040020,0x0000012b,0x00000007,0x00000025,0x0003001d,0x0000012d,0x0000001f, + 0x0003001e,0x0000012e,0x0000012d,0x00040020,0x0000012f,0x00000002,0x0000012e,0x0004003b, + 0x0000012f,0x00000130,0x00000002,0x0004002b,0x00000012,0x00000132,0x00000004,0x00040020, + 0x00000136,0x00000002,0x0000001f,0x00040020,0x00000142,0x00000001,0x0000001f,0x0004003b, + 0x00000142,0x00000143,0x00000001,0x0004002b,0x00000012,0x00000163,0x0000000f,0x00090019, + 0x000001a3,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x000001a4,0x00000000,0x000001a3,0x0004003b,0x000001a4,0x000001a5,0x00000000, + 0x0002001a,0x000001a7,0x00040020,0x000001a8,0x00000000,0x000001a7,0x0004003b,0x000001a8, + 0x000001a9,0x00000000,0x0003001b,0x000001ab,0x000001a3,0x00090019,0x000001c7,0x00000012, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x000001c8, + 0x00000000,0x000001c7,0x0004003b,0x000001c8,0x000001c9,0x00000000,0x00040017,0x000001cc, + 0x00000012,0x00000004,0x0004002b,0x00000012,0x000001d1,0x0001ffff,0x0004002b,0x00000012, + 0x000001d7,0x00000011,0x0004001e,0x000001e9,0x00000006,0x00000006,0x00040020,0x000001ea, + 0x00000002,0x000001e9,0x0004003b,0x000001ea,0x000001eb,0x00000002,0x00040020,0x000001f5, + 0x00000002,0x00000006,0x00040020,0x00000202,0x00000003,0x0000001f,0x0004003b,0x00000202, + 0x00000203,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003b,0x00000007,0x0000034a,0x00000007,0x0004003b,0x00000007,0x0000034b, + 0x00000007,0x0004003b,0x00000007,0x0000034c,0x00000007,0x0004003b,0x00000031,0x00000338, + 0x00000007,0x0004003b,0x0000000d,0x00000339,0x00000007,0x0004003b,0x00000007,0x0000033a, + 0x00000007,0x0004003b,0x00000007,0x0000033b,0x00000007,0x0004003b,0x00000031,0x0000033c, + 0x00000007,0x0004003b,0x0000012b,0x0000032b,0x00000007,0x0004003b,0x00000024,0x0000031f, + 0x00000007,0x0004003b,0x00000024,0x00000320,0x00000007,0x0004003b,0x0000000d,0x0000031a, + 0x00000007,0x0004003b,0x0000000d,0x0000031b,0x00000007,0x0004003b,0x0000012b,0x0000030d, + 0x00000007,0x0004003b,0x0000000d,0x00000305,0x00000007,0x0004003b,0x0000000d,0x00000306, + 0x00000007,0x0004003b,0x00000007,0x000002f2,0x00000007,0x0004003b,0x00000007,0x000002ef, + 0x00000007,0x0004003b,0x00000007,0x000002ec,0x00000007,0x0004003b,0x000000d6,0x00000226, + 0x00000007,0x0004003b,0x00000007,0x00000227,0x00000007,0x0004003b,0x00000007,0x00000228, + 0x00000007,0x0004003b,0x00000007,0x00000229,0x00000007,0x0004003b,0x00000013,0x0000022a, + 0x00000007,0x0004003b,0x00000013,0x0000022b,0x00000007,0x0004003b,0x00000024,0x0000022c, + 0x00000007,0x0004003b,0x00000007,0x0000022d,0x00000007,0x0004003b,0x0000012b,0x0000022e, + 0x00000007,0x0004003b,0x00000024,0x0000022f,0x00000007,0x0004003b,0x00000024,0x00000230, + 0x00000007,0x0004003b,0x0000000d,0x00000231,0x00000007,0x0004003b,0x0000000d,0x00000232, + 0x00000007,0x0004003b,0x0000000d,0x00000233,0x00000007,0x0004003b,0x00000007,0x00000234, + 0x00000007,0x0004003b,0x00000013,0x00000235,0x00000007,0x0004003b,0x00000007,0x00000236, + 0x00000007,0x0004003b,0x0000012b,0x00000237,0x00000007,0x0004003b,0x00000024,0x00000238, + 0x00000007,0x0004003b,0x00000024,0x00000239,0x00000007,0x0004003b,0x0000000d,0x0000023a, + 0x00000007,0x0004003b,0x00000007,0x0000023b,0x00000007,0x0004003b,0x00000007,0x0000023c, + 0x00000007,0x0004003b,0x00000007,0x0000023d,0x00000007,0x0004003b,0x00000007,0x0000023e, + 0x00000007,0x0004003b,0x00000013,0x00000223,0x00000007,0x0004003b,0x00000013,0x0000021e, + 0x00000007,0x0004003b,0x00000013,0x0000021f,0x00000007,0x0004003b,0x00000007,0x00000219, + 0x00000007,0x0004003b,0x00000007,0x0000021a,0x00000007,0x0004003b,0x00000007,0x00000211, + 0x00000007,0x0004003b,0x00000007,0x00000212,0x00000007,0x0004003b,0x00000048,0x000001c1, + 0x00000007,0x0004003b,0x00000013,0x000001c6,0x00000007,0x0004003b,0x00000007,0x000001cf, + 0x00000007,0x0004003b,0x00000013,0x000001d3,0x00000007,0x0004003b,0x00000013,0x000001d5, + 0x00000007,0x0004003b,0x00000013,0x000001d9,0x00000007,0x0004003b,0x00000013,0x000001db, + 0x00000007,0x0004003b,0x00000024,0x000001de,0x00000007,0x0004003b,0x00000013,0x000001df, + 0x00000007,0x0004003b,0x00000007,0x000001e1,0x00000007,0x0004003b,0x00000024,0x000001e3, + 0x00000007,0x0004003b,0x00000031,0x000001ee,0x00000007,0x0004003b,0x0000000d,0x000001f1, + 0x00000007,0x0004003b,0x00000007,0x000001f4,0x00000007,0x0004003b,0x00000007,0x000001f8, + 0x00000007,0x0004003d,0x0000001f,0x000001c2,0x00000143,0x0007004f,0x0000000c,0x000001c3, + 0x000001c2,0x000001c2,0x00000000,0x00000001,0x0006000c,0x0000000c,0x000001c4,0x00000001, + 0x00000008,0x000001c3,0x0004006e,0x00000047,0x000001c5,0x000001c4,0x0003003e,0x000001c1, + 0x000001c5,0x0004003d,0x000001c7,0x000001ca,0x000001c9,0x0004003d,0x00000047,0x000001cb, + 0x000001c1,0x00050062,0x000001cc,0x000001cd,0x000001ca,0x000001cb,0x00050051,0x00000012, + 0x000001ce,0x000001cd,0x00000000,0x0003003e,0x000001c6,0x000001ce,0x0004003d,0x00000012, + 0x000001d0,0x000001c6,0x000500c7,0x00000012,0x000001d2,0x000001d0,0x000001d1,0x0003003e, + 0x000001d3,0x000001d2,0x0004003d,0x00000012,0x00000214,0x000001d3,0x00040070,0x00000006, + 0x00000215,0x00000214,0x00050085,0x00000006,0x00000216,0x00000215,0x000000b6,0x00050081, + 0x00000006,0x00000217,0x00000216,0x000000b8,0x0003003e,0x00000211,0x00000217,0x0004003d, + 0x00000006,0x0000021c,0x00000211,0x0003003e,0x00000219,0x0000021c,0x0004003d,0x00000006, + 0x0000021d,0x00000219,0x0003003e,0x0000021a,0x0000021d,0x0004003d,0x00000006,0x00000218, + 0x0000021a,0x0003003e,0x00000212,0x00000218,0x0004003d,0x00000006,0x000001d4,0x00000212, + 0x0003003e,0x000001cf,0x000001d4,0x0004003d,0x00000012,0x000001d6,0x000001c6,0x000500c2, + 0x00000012,0x000001d8,0x000001d6,0x000001d7,0x0003003e,0x000001d9,0x000001d8,0x0004003d, + 0x00000012,0x00000221,0x000001d9,0x0003003e,0x0000021e,0x00000221,0x0004003d,0x00000012, + 0x00000222,0x0000021e,0x0003003e,0x0000021f,0x00000222,0x0004003d,0x00000012,0x000001da, + 0x0000021f,0x0003003e,0x000001d5,0x000001da,0x0004003d,0x00000012,0x000001dc,0x000001d5, + 0x0003003e,0x000001db,0x000001dc,0x0004003d,0x00000012,0x00000225,0x000001db,0x0003003e, + 0x00000223,0x00000225,0x0004003d,0x00000012,0x000001dd,0x00000223,0x0003003e,0x000001d5, + 0x000001dd,0x0004003d,0x00000012,0x000001e0,0x000001d5,0x0003003e,0x000001df,0x000001e0, + 0x0004003d,0x00000006,0x000001e2,0x000001cf,0x0003003e,0x000001e1,0x000001e2,0x0004003d, + 0x00000012,0x00000240,0x000001df,0x00060041,0x000000de,0x00000241,0x000000db,0x000000dc, + 0x00000240,0x0004003d,0x000000d5,0x00000242,0x00000241,0x0003003e,0x00000226,0x00000242, + 0x0004003d,0x00000006,0x00000243,0x000001e1,0x0003003e,0x00000227,0x00000243,0x00050041, + 0x00000013,0x00000244,0x00000226,0x00000064,0x0004003d,0x00000012,0x00000245,0x00000244, + 0x000500c7,0x00000012,0x00000246,0x00000245,0x000000e5,0x000500ab,0x000000a0,0x00000247, + 0x00000246,0x00000064,0x000300f7,0x0000025b,0x00000000,0x000400fa,0x00000247,0x00000248, + 0x0000025b,0x000200f8,0x00000248,0x0004003d,0x00000006,0x00000249,0x00000227,0x0006000c, + 0x00000006,0x0000024a,0x00000001,0x00000004,0x00000249,0x0003003e,0x00000227,0x0000024a, + 0x000300f7,0x00000250,0x00000000,0x000400fa,0x000000ec,0x0000024b,0x00000250,0x000200f8, + 0x0000024b,0x0004003d,0x00000012,0x0000024d,0x00000244,0x000500c7,0x00000012,0x0000024e, + 0x0000024d,0x000000f1,0x000500ab,0x000000a0,0x0000024f,0x0000024e,0x00000064,0x000200f9, + 0x00000250,0x000200f8,0x00000250,0x000700f5,0x000000a0,0x00000251,0x000000ec,0x00000248, + 0x0000024f,0x0000024b,0x000300f7,0x0000025a,0x00000000,0x000400fa,0x00000251,0x00000252, + 0x0000025a,0x000200f8,0x00000252,0x0004003d,0x00000006,0x00000253,0x00000227,0x00050085, + 0x00000006,0x00000254,0x00000253,0x000000f8,0x0006000c,0x00000006,0x00000255,0x00000001, + 0x0000000a,0x00000254,0x00050085,0x00000006,0x00000256,0x00000255,0x000000fb,0x00050081, + 0x00000006,0x00000257,0x00000256,0x000000fd,0x0006000c,0x00000006,0x00000258,0x00000001, + 0x00000004,0x00000257,0x00050083,0x00000006,0x00000259,0x0000007e,0x00000258,0x0003003e, + 0x00000227,0x00000259,0x000200f9,0x0000025a,0x000200f8,0x0000025a,0x000200f9,0x0000025b, + 0x000200f8,0x0000025b,0x0004003d,0x00000006,0x0000025c,0x00000227,0x0003003e,0x00000228, + 0x0000007f,0x0004003d,0x00000006,0x000002ee,0x00000228,0x0003003e,0x000002ec,0x000002ee, + 0x0004003d,0x00000006,0x0000025d,0x000002ec,0x0003003e,0x00000229,0x0000007e,0x0004003d, + 0x00000006,0x000002f1,0x00000229,0x0003003e,0x000002ef,0x000002f1,0x0004003d,0x00000006, + 0x0000025e,0x000002ef,0x0008000c,0x00000006,0x0000025f,0x00000001,0x0000002b,0x0000025c, + 0x0000025d,0x0000025e,0x0003003e,0x00000227,0x0000025f,0x000300f7,0x0000026e,0x00000000, + 0x000400fa,0x00000107,0x00000260,0x0000026e,0x000200f8,0x00000260,0x0004003d,0x00000012, + 0x00000262,0x00000244,0x000500c2,0x00000012,0x00000263,0x00000262,0x0000010d,0x0003003e, + 0x0000022a,0x00000263,0x0004003d,0x00000012,0x00000264,0x0000022a,0x000500ab,0x000000a0, + 0x00000265,0x00000264,0x00000064,0x000300f7,0x0000026d,0x00000000,0x000400fa,0x00000265, + 0x00000266,0x0000026d,0x000200f8,0x00000266,0x0004003d,0x00000113,0x00000267,0x00000115, + 0x00050062,0x0000001f,0x00000268,0x00000267,0x00000117,0x0004003d,0x00000012,0x00000269, + 0x0000022a,0x0003003e,0x0000022b,0x00000269,0x0003003e,0x0000022c,0x00000268,0x0004003d, + 0x00000006,0x0000026a,0x00000227,0x0003003e,0x0000022d,0x0000026a,0x0004003d,0x0000001f, + 0x000002f4,0x0000022c,0x0007004f,0x0000000c,0x000002f5,0x000002f4,0x000002f4,0x00000000, + 0x00000001,0x0004003d,0x00000012,0x000002f6,0x0000022b,0x0006000c,0x0000001f,0x000002f7, + 0x00000001,0x00000040,0x000002f6,0x0007004f,0x0000000c,0x000002f8,0x000002f7,0x000002f7, + 0x00000000,0x00000001,0x00050083,0x0000000c,0x000002f9,0x000002f5,0x000002f8,0x0006000c, + 0x0000000c,0x000002fa,0x00000001,0x00000004,0x000002f9,0x0003003e,0x000002f2,0x000000c8, + 0x0004003d,0x00000006,0x00000308,0x000002f2,0x00050041,0x00000007,0x00000309,0x00000305, + 0x00000064,0x0003003e,0x00000309,0x00000308,0x0004003d,0x00000006,0x0000030a,0x000002f2, + 0x00050041,0x00000007,0x0000030b,0x00000305,0x00000067,0x0003003e,0x0000030b,0x0000030a, + 0x0004003d,0x0000000c,0x0000030c,0x00000305,0x0003003e,0x00000306,0x0000030c,0x0004003d, + 0x0000000c,0x000002fb,0x00000306,0x000500b8,0x000000cb,0x000002fc,0x000002fa,0x000002fb, + 0x0004009b,0x000000a0,0x000002fd,0x000002fc,0x000300f7,0x00000304,0x00000000,0x000400fa, + 0x000002fd,0x000002fe,0x00000303,0x000200f8,0x000002fe,0x0004003d,0x00000006,0x000002ff, + 0x0000022d,0x00050041,0x00000007,0x00000300,0x0000022c,0x00000072,0x0004003d,0x00000006, + 0x00000301,0x00000300,0x0007000c,0x00000006,0x00000302,0x00000001,0x00000025,0x000002ff, + 0x00000301,0x0003003e,0x0000022d,0x00000302,0x000200f9,0x00000304,0x000200f8,0x00000303, + 0x0003003e,0x0000022d,0x0000007f,0x000200f9,0x00000304,0x000200f8,0x00000304,0x0004003d, + 0x00000006,0x0000026c,0x0000022d,0x0003003e,0x00000227,0x0000026c,0x000200f9,0x0000026d, + 0x000200f8,0x0000026d,0x000200f9,0x0000026e,0x000200f8,0x0000026e,0x000300f7,0x00000274, + 0x00000000,0x000400fa,0x00000120,0x0000026f,0x00000274,0x000200f8,0x0000026f,0x0004003d, + 0x00000012,0x00000271,0x00000244,0x000500c7,0x00000012,0x00000272,0x00000271,0x00000125, + 0x000500ab,0x000000a0,0x00000273,0x00000272,0x00000064,0x000200f9,0x00000274,0x000200f8, + 0x00000274,0x000700f5,0x000000a0,0x00000275,0x00000120,0x0000026e,0x00000273,0x0000026f, + 0x000300f7,0x0000029c,0x00000000,0x000400fa,0x00000275,0x00000276,0x0000029c,0x000200f8, + 0x00000276,0x0004003d,0x00000012,0x00000277,0x000001df,0x00050084,0x00000012,0x00000278, + 0x00000277,0x00000132,0x00050080,0x00000012,0x00000279,0x00000278,0x00000072,0x00060041, + 0x00000136,0x0000027a,0x00000130,0x000000dc,0x00000279,0x0004003d,0x0000001f,0x0000027b, + 0x0000027a,0x0003003e,0x0000022f,0x0000027b,0x0004003d,0x0000001f,0x0000030f,0x0000022f, + 0x0004003d,0x0000001f,0x00000311,0x0000022f,0x00050051,0x00000006,0x00000313,0x0000030f, + 0x00000000,0x00050051,0x00000006,0x00000314,0x0000030f,0x00000001,0x00050051,0x00000006, + 0x00000315,0x00000311,0x00000002,0x00050051,0x00000006,0x00000316,0x00000311,0x00000003, + 0x00050050,0x0000000c,0x00000317,0x00000313,0x00000314,0x00050050,0x0000000c,0x00000318, + 0x00000315,0x00000316,0x00050050,0x00000025,0x00000319,0x00000317,0x00000318,0x0003003e, + 0x0000030d,0x00000319,0x0004003d,0x00000025,0x0000027c,0x0000030d,0x0003003e,0x0000022e, + 0x0000027c,0x0004003d,0x00000012,0x0000027d,0x000001df,0x00050084,0x00000012,0x0000027e, + 0x0000027d,0x00000132,0x00050080,0x00000012,0x0000027f,0x0000027e,0x00000075,0x00060041, + 0x00000136,0x00000280,0x00000130,0x000000dc,0x0000027f,0x0004003d,0x0000001f,0x00000281, + 0x00000280,0x0003003e,0x00000230,0x00000281,0x0004003d,0x00000025,0x00000282,0x0000022e, + 0x00050091,0x0000000c,0x00000285,0x00000282,0x000001c3,0x0004003d,0x0000001f,0x00000286, + 0x00000230,0x0007004f,0x0000000c,0x00000287,0x00000286,0x00000286,0x00000000,0x00000001, + 0x00050081,0x0000000c,0x00000288,0x00000285,0x00000287,0x0003003e,0x00000231,0x00000288, + 0x0004003d,0x0000000c,0x00000289,0x00000231,0x0006000c,0x0000000c,0x0000028a,0x00000001, + 0x00000004,0x00000289,0x0004003d,0x0000001f,0x0000028b,0x00000230,0x0007004f,0x0000000c, + 0x0000028c,0x0000028b,0x0000028b,0x00000002,0x00000003,0x00050085,0x0000000c,0x0000028d, + 0x0000028a,0x0000028c,0x0004003d,0x0000001f,0x0000028e,0x00000230,0x0007004f,0x0000000c, + 0x0000028f,0x0000028e,0x0000028e,0x00000002,0x00000003,0x00050083,0x0000000c,0x00000290, + 0x0000028d,0x0000028f,0x0003003e,0x00000233,0x00000290,0x0004003d,0x0000000c,0x0000031d, + 0x00000233,0x0003003e,0x0000031a,0x0000031d,0x0004003d,0x0000000c,0x0000031e,0x0000031a, + 0x0003003e,0x0000031b,0x0000031e,0x0004003d,0x0000000c,0x00000291,0x0000031b,0x0003003e, + 0x00000232,0x00000291,0x00050041,0x00000007,0x00000292,0x00000232,0x00000064,0x0004003d, + 0x00000006,0x00000293,0x00000292,0x00050041,0x00000007,0x00000294,0x00000232,0x00000067, + 0x0004003d,0x00000006,0x00000295,0x00000294,0x0007000c,0x00000006,0x00000296,0x00000001, + 0x00000025,0x00000293,0x00000295,0x00050081,0x00000006,0x00000297,0x00000296,0x000000f8, + 0x0008000c,0x00000006,0x00000298,0x00000001,0x0000002b,0x00000297,0x0000007f,0x0000007e, + 0x0003003e,0x00000234,0x00000298,0x0004003d,0x00000006,0x00000299,0x00000227,0x0004003d, + 0x00000006,0x0000029a,0x00000234,0x0007000c,0x00000006,0x0000029b,0x00000001,0x00000025, + 0x00000299,0x0000029a,0x0003003e,0x00000227,0x0000029b,0x000200f9,0x0000029c,0x000200f8, + 0x0000029c,0x0004003d,0x00000012,0x0000029e,0x00000244,0x000500c7,0x00000012,0x0000029f, + 0x0000029e,0x00000163,0x0003003e,0x00000235,0x0000029f,0x0004003d,0x00000012,0x000002a0, + 0x00000235,0x000500b2,0x000000a0,0x000002a1,0x000002a0,0x00000067,0x000300f7,0x000002db, + 0x00000000,0x000400fa,0x000002a1,0x000002a2,0x000002ac,0x000200f8,0x000002a2,0x00050041, + 0x00000013,0x000002a3,0x00000226,0x00000067,0x0004003d,0x00000012,0x000002a4,0x000002a3, + 0x0006000c,0x0000001f,0x000002a5,0x00000001,0x00000040,0x000002a4,0x0003003e,0x000001e3, + 0x000002a5,0x0004003d,0x00000012,0x000002a6,0x00000235,0x000500aa,0x000000a0,0x000002a7, + 0x000002a6,0x00000064,0x000500a7,0x000000a0,0x000002a8,0x00000107,0x000002a7,0x000300f7, + 0x000002ab,0x00000000,0x000400fa,0x000002a8,0x000002a9,0x000002ab,0x000200f8,0x000002a9, + 0x0003003e,0x00000236,0x0000007f,0x0004003d,0x00000006,0x00000322,0x00000236,0x00050041, + 0x00000007,0x00000323,0x0000031f,0x00000064,0x0003003e,0x00000323,0x00000322,0x0004003d, + 0x00000006,0x00000324,0x00000236,0x00050041,0x00000007,0x00000325,0x0000031f,0x00000067, + 0x0003003e,0x00000325,0x00000324,0x0004003d,0x00000006,0x00000326,0x00000236,0x00050041, + 0x00000007,0x00000327,0x0000031f,0x00000072,0x0003003e,0x00000327,0x00000326,0x0004003d, + 0x00000006,0x00000328,0x00000236,0x00050041,0x00000007,0x00000329,0x0000031f,0x00000075, + 0x0003003e,0x00000329,0x00000328,0x0004003d,0x0000001f,0x0000032a,0x0000031f,0x0003003e, + 0x00000320,0x0000032a,0x0004003d,0x0000001f,0x000002aa,0x00000320,0x0003003e,0x000001e3, + 0x000002aa,0x000200f9,0x000002ab,0x000200f8,0x000002ab,0x000200f9,0x000002db,0x000200f8, + 0x000002ac,0x0004003d,0x00000012,0x000002ad,0x000001df,0x00050084,0x00000012,0x000002ae, + 0x000002ad,0x00000132,0x00060041,0x00000136,0x000002af,0x00000130,0x000000dc,0x000002ae, + 0x0004003d,0x0000001f,0x000002b0,0x000002af,0x0003003e,0x00000238,0x000002b0,0x0004003d, + 0x0000001f,0x0000032d,0x00000238,0x0004003d,0x0000001f,0x0000032f,0x00000238,0x00050051, + 0x00000006,0x00000331,0x0000032d,0x00000000,0x00050051,0x00000006,0x00000332,0x0000032d, + 0x00000001,0x00050051,0x00000006,0x00000333,0x0000032f,0x00000002,0x00050051,0x00000006, + 0x00000334,0x0000032f,0x00000003,0x00050050,0x0000000c,0x00000335,0x00000331,0x00000332, + 0x00050050,0x0000000c,0x00000336,0x00000333,0x00000334,0x00050050,0x00000025,0x00000337, + 0x00000335,0x00000336,0x0003003e,0x0000032b,0x00000337,0x0004003d,0x00000025,0x000002b1, + 0x0000032b,0x0003003e,0x00000237,0x000002b1,0x0004003d,0x00000012,0x000002b2,0x000001df, + 0x00050084,0x00000012,0x000002b3,0x000002b2,0x00000132,0x00050080,0x00000012,0x000002b4, + 0x000002b3,0x00000067,0x00060041,0x00000136,0x000002b5,0x00000130,0x000000dc,0x000002b4, + 0x0004003d,0x0000001f,0x000002b6,0x000002b5,0x0003003e,0x00000239,0x000002b6,0x0004003d, + 0x00000025,0x000002b7,0x00000237,0x00050091,0x0000000c,0x000002ba,0x000002b7,0x000001c3, + 0x0004003d,0x0000001f,0x000002bb,0x00000239,0x0007004f,0x0000000c,0x000002bc,0x000002bb, + 0x000002bb,0x00000000,0x00000001,0x00050081,0x0000000c,0x000002bd,0x000002ba,0x000002bc, + 0x0003003e,0x0000023a,0x000002bd,0x0004003d,0x00000012,0x000002be,0x00000235,0x000500aa, + 0x000000a0,0x000002bf,0x000002be,0x00000072,0x000300f7,0x000002c6,0x00000000,0x000400fa, + 0x000002bf,0x000002c0,0x000002c3,0x000200f8,0x000002c0,0x00050041,0x00000007,0x000002c1, + 0x0000023a,0x00000064,0x0004003d,0x00000006,0x000002c2,0x000002c1,0x0003003e,0x0000023c, + 0x000002c2,0x000200f9,0x000002c6,0x000200f8,0x000002c3,0x0004003d,0x0000000c,0x000002c4, + 0x0000023a,0x0006000c,0x00000006,0x000002c5,0x00000001,0x00000042,0x000002c4,0x0003003e, + 0x0000023c,0x000002c5,0x000200f9,0x000002c6,0x000200f8,0x000002c6,0x0004003d,0x00000006, + 0x000002c7,0x0000023c,0x0003003e,0x0000023b,0x000002c7,0x0004003d,0x00000006,0x000002c8, + 0x0000023b,0x0008000c,0x00000006,0x000002c9,0x00000001,0x0000002b,0x000002c8,0x0000007f, + 0x0000007e,0x0003003e,0x0000023b,0x000002c9,0x0004003d,0x00000006,0x000002ca,0x0000023b, + 0x00050041,0x00000007,0x000002cb,0x00000239,0x00000072,0x0004003d,0x00000006,0x000002cc, + 0x000002cb,0x00050085,0x00000006,0x000002cd,0x000002ca,0x000002cc,0x00050041,0x00000007, + 0x000002ce,0x00000239,0x00000075,0x0004003d,0x00000006,0x000002cf,0x000002ce,0x00050081, + 0x00000006,0x000002d0,0x000002cd,0x000002cf,0x0003003e,0x0000023d,0x000002d0,0x00050041, + 0x00000013,0x000002d1,0x00000226,0x00000067,0x0004003d,0x00000012,0x000002d2,0x000002d1, + 0x0004007c,0x00000006,0x000002d3,0x000002d2,0x0003003e,0x0000023e,0x000002d3,0x0004003d, + 0x000001a3,0x000002d4,0x000001a5,0x0004003d,0x000001a7,0x000002d5,0x000001a9,0x00050056, + 0x000001ab,0x000002d6,0x000002d4,0x000002d5,0x0004003d,0x00000006,0x000002d7,0x0000023d, + 0x0004003d,0x00000006,0x000002d8,0x0000023e,0x00050050,0x0000000c,0x000002d9,0x000002d7, + 0x000002d8,0x00070058,0x0000001f,0x000002da,0x000002d6,0x000002d9,0x00000002,0x0000007f, + 0x0003003e,0x000001e3,0x000002da,0x000200f9,0x000002db,0x000200f8,0x000002db,0x0004003d, + 0x00000006,0x000002dc,0x00000227,0x00050041,0x00000007,0x000002dd,0x000001e3,0x00000075, + 0x0004003d,0x00000006,0x000002de,0x000002dd,0x00050085,0x00000006,0x000002df,0x000002de, + 0x000002dc,0x0003003e,0x000002dd,0x000002df,0x0004003d,0x00000006,0x000002e2,0x000002dd, + 0x0004003d,0x0000001f,0x000002e3,0x000001e3,0x0008004f,0x00000030,0x000002e4,0x000002e3, + 0x000002e3,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000030,0x000002e5,0x000002e4, + 0x000002e2,0x00050041,0x00000007,0x000002e6,0x000001e3,0x00000064,0x00050051,0x00000006, + 0x000002e7,0x000002e5,0x00000000,0x0003003e,0x000002e6,0x000002e7,0x00050041,0x00000007, + 0x000002e8,0x000001e3,0x00000067,0x00050051,0x00000006,0x000002e9,0x000002e5,0x00000001, + 0x0003003e,0x000002e8,0x000002e9,0x00050041,0x00000007,0x000002ea,0x000001e3,0x00000072, + 0x00050051,0x00000006,0x000002eb,0x000002e5,0x00000002,0x0003003e,0x000002ea,0x000002eb, + 0x0004003d,0x0000001f,0x000001e7,0x000001e3,0x0003003e,0x000001de,0x000001e7,0x0004003d, + 0x0000001f,0x000001ef,0x000001de,0x0008004f,0x00000030,0x000001f0,0x000001ef,0x000001ef, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x000001ee,0x000001f0,0x0003003e,0x000001f1, + 0x000001c3,0x00050041,0x000001f5,0x000001f6,0x000001eb,0x00000064,0x0004003d,0x00000006, + 0x000001f7,0x000001f6,0x0003003e,0x000001f4,0x000001f7,0x00050041,0x000001f5,0x000001f9, + 0x000001eb,0x00000067,0x0004003d,0x00000006,0x000001fa,0x000001f9,0x0003003e,0x000001f8, + 0x000001fa,0x000300f7,0x00000348,0x00000000,0x000400fa,0x000000a1,0x0000033e,0x00000346, + 0x000200f8,0x0000033e,0x0004003d,0x0000000c,0x0000033f,0x000001f1,0x0003003e,0x00000339, + 0x0000033f,0x0004003d,0x00000006,0x00000340,0x000001f4,0x0003003e,0x0000033a,0x00000340, + 0x0004003d,0x00000006,0x00000341,0x000001f8,0x0003003e,0x0000033b,0x00000341,0x00050041, + 0x00000007,0x0000034e,0x00000339,0x00000064,0x0004003d,0x00000006,0x0000034f,0x0000034e, + 0x00050085,0x00000006,0x00000350,0x0000008a,0x0000034f,0x00050041,0x00000007,0x00000351, + 0x00000339,0x00000067,0x0004003d,0x00000006,0x00000352,0x00000351,0x00050085,0x00000006, + 0x00000353,0x0000008e,0x00000352,0x00050081,0x00000006,0x00000354,0x00000350,0x00000353, + 0x0006000c,0x00000006,0x00000355,0x00000001,0x0000000a,0x00000354,0x0003003e,0x0000034a, + 0x00000355,0x0004003d,0x00000006,0x00000356,0x0000034a,0x00050085,0x00000006,0x00000357, + 0x00000095,0x00000356,0x0006000c,0x00000006,0x00000358,0x00000001,0x0000000a,0x00000357, + 0x0003003e,0x0000034b,0x00000358,0x0004003d,0x00000006,0x00000359,0x0000034b,0x0004003d, + 0x00000006,0x0000035a,0x0000033a,0x00050085,0x00000006,0x0000035b,0x00000359,0x0000035a, + 0x0004003d,0x00000006,0x0000035c,0x0000033b,0x00050081,0x00000006,0x0000035d,0x0000035b, + 0x0000035c,0x0003003e,0x0000034c,0x0000035d,0x0004003d,0x00000006,0x00000342,0x0000034c, + 0x0004003d,0x00000030,0x00000343,0x000001ee,0x00060050,0x00000030,0x00000344,0x00000342, + 0x00000342,0x00000342,0x00050081,0x00000030,0x00000345,0x00000344,0x00000343,0x0003003e, + 0x00000338,0x00000345,0x000200f9,0x00000348,0x000200f8,0x00000346,0x0004003d,0x00000030, + 0x00000347,0x000001ee,0x0003003e,0x00000338,0x00000347,0x000200f9,0x00000348,0x000200f8, + 0x00000348,0x0004003d,0x00000030,0x00000349,0x00000338,0x0003003e,0x0000033c,0x00000349, + 0x0004003d,0x00000030,0x000001fb,0x0000033c,0x00050041,0x00000007,0x000001fc,0x000001de, + 0x00000064,0x00050051,0x00000006,0x000001fd,0x000001fb,0x00000000,0x0003003e,0x000001fc, + 0x000001fd,0x00050041,0x00000007,0x000001fe,0x000001de,0x00000067,0x00050051,0x00000006, + 0x000001ff,0x000001fb,0x00000001,0x0003003e,0x000001fe,0x000001ff,0x00050041,0x00000007, + 0x00000200,0x000001de,0x00000072,0x00050051,0x00000006,0x00000201,0x000001fb,0x00000002, + 0x0003003e,0x00000200,0x00000201,0x0004003d,0x0000001f,0x00000204,0x000001de,0x0003003e, + 0x00000203,0x00000204,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..69e3449c0cfac3baadb97d933f4ee900f87c8ff1 GIT binary patch literal 11792 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.h new file mode 100644 index 000000000..a1875c7f0 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.h @@ -0,0 +1,1569 @@ +#pragma once + +const uint32_t atomic_resolve_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000b01,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000037b, + 0x00000421,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x0000012c,0x0000674e,0x00030005,0x0000029d,0x0000674d, + 0x00030005,0x00000314,0x00006576,0x00040006,0x00000314,0x00000000,0x00003464,0x00030005, + 0x00000316,0x00004355,0x00030005,0x00000326,0x0000674b,0x00030005,0x0000033f,0x00006747, + 0x00040005,0x0000034d,0x30653742,0x00000000,0x00030005,0x00000358,0x00006748,0x00030005, + 0x00000366,0x00006577,0x00040006,0x00000366,0x00000000,0x00003464,0x00030005,0x00000368, + 0x0000424f,0x00060005,0x0000037b,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x000003dd,0x00004444,0x00030005,0x000003e1,0x00006277,0x00030005,0x000003ee,0x00006749, + 0x00040005,0x00000404,0x306a3742,0x00000000,0x00030005,0x00000421,0x0000306a,0x00030005, + 0x00000423,0x00000045,0x00030005,0x00000428,0x00003270,0x00030005,0x0000042b,0x00003470, + 0x00030005,0x00000431,0x0000306e,0x00040005,0x00000435,0x61726170,0x0000006d,0x00030005, + 0x00000437,0x00003145,0x00040005,0x0000043b,0x61726170,0x0000006d,0x00040005,0x0000043d, + 0x61726170,0x0000006d,0x00030005,0x00000440,0x00000050,0x00040005,0x00000441,0x61726170, + 0x0000006d,0x00040005,0x00000443,0x61726170,0x0000006d,0x00040005,0x00000445,0x61726170, + 0x0000006d,0x00030005,0x0000044b,0x0000424d,0x00040006,0x0000044b,0x00000000,0x00003376, + 0x00040006,0x0000044b,0x00000001,0x00003377,0x00030005,0x0000044d,0x0000006b,0x00040005, + 0x00000450,0x61726170,0x0000006d,0x00040005,0x00000453,0x61726170,0x0000006d,0x00040005, + 0x00000456,0x61726170,0x0000006d,0x00040005,0x0000045a,0x61726170,0x0000006d,0x00040005, + 0x00000464,0x61726170,0x0000006d,0x00040047,0x0000012c,0x00000001,0x00000007,0x00040047, + 0x0000029d,0x00000001,0x00000006,0x00040047,0x00000313,0x00000006,0x00000008,0x00030047, + 0x00000314,0x00000003,0x00040048,0x00000314,0x00000000,0x00000018,0x00050048,0x00000314, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000316,0x00000018,0x00040047,0x00000316, + 0x00000021,0x00000004,0x00040047,0x00000316,0x00000022,0x00000000,0x00040047,0x00000326, + 0x00000001,0x00000004,0x00040047,0x0000033f,0x00000001,0x00000000,0x00030047,0x0000034d, + 0x00000000,0x00040047,0x0000034d,0x00000021,0x00000001,0x00040047,0x0000034d,0x00000022, + 0x00000002,0x00040047,0x0000034d,0x0000002b,0x00000001,0x00040047,0x00000358,0x00000001, + 0x00000001,0x00040047,0x00000365,0x00000006,0x00000010,0x00030047,0x00000366,0x00000003, + 0x00040048,0x00000366,0x00000000,0x00000018,0x00050048,0x00000366,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000368,0x00000018,0x00040047,0x00000368,0x00000021,0x00000005, + 0x00040047,0x00000368,0x00000022,0x00000000,0x00040047,0x0000037b,0x0000000b,0x0000000f, + 0x00030047,0x000003dd,0x00000000,0x00040047,0x000003dd,0x00000021,0x00000009,0x00040047, + 0x000003dd,0x00000022,0x00000000,0x00030047,0x000003e1,0x00000000,0x00040047,0x000003e1, + 0x00000021,0x00000009,0x00040047,0x000003e1,0x00000022,0x00000000,0x00040047,0x000003ee, + 0x00000001,0x00000002,0x00030047,0x00000404,0x00000000,0x00040047,0x00000404,0x00000021, + 0x00000000,0x00040047,0x00000404,0x00000022,0x00000002,0x00040047,0x00000404,0x0000002b, + 0x00000000,0x00030047,0x00000421,0x00000000,0x00040047,0x00000421,0x0000001e,0x00000000, + 0x00030047,0x0000042b,0x00000017,0x00040047,0x0000042b,0x00000021,0x00000003,0x00040047, + 0x0000042b,0x00000022,0x00000002,0x00030047,0x00000431,0x00000000,0x00030047,0x00000437, + 0x00000000,0x00030047,0x0000043d,0x00000000,0x00030047,0x0000043e,0x00000000,0x00030047, + 0x00000440,0x00000000,0x00030047,0x00000442,0x00000000,0x00030047,0x00000443,0x00000000, + 0x00030047,0x00000444,0x00000000,0x00030047,0x00000445,0x00000000,0x00030047,0x0000044b, + 0x00000002,0x00050048,0x0000044b,0x00000000,0x00000023,0x00000058,0x00050048,0x0000044b, + 0x00000001,0x00000023,0x0000005c,0x00040047,0x0000044d,0x00000021,0x00000000,0x00040047, + 0x0000044d,0x00000022,0x00000000,0x00030047,0x00000450,0x00000000,0x00030047,0x00000451, + 0x00000000,0x00030047,0x00000452,0x00000000,0x00030047,0x00000456,0x00000000,0x00030047, + 0x0000045a,0x00000000,0x00030047,0x00000464,0x00000000,0x00030047,0x00000465,0x00000000, + 0x00030047,0x00000476,0x00000000,0x00030047,0x0000047d,0x00000000,0x00030047,0x0000047e, + 0x00000000,0x00030047,0x00000481,0x00000000,0x00030047,0x00000482,0x00000000,0x00030047, + 0x00000483,0x00000000,0x00030047,0x00000486,0x00000000,0x00030047,0x00000487,0x00000000, + 0x00030047,0x00000489,0x00000000,0x00030047,0x0000048b,0x00000000,0x00030047,0x0000048c, + 0x00000000,0x00030047,0x0000048d,0x00000000,0x00030047,0x00000490,0x00000000,0x00030047, + 0x00000491,0x00000000,0x00030047,0x00000496,0x00000000,0x00030047,0x00000498,0x00000000, + 0x00030047,0x0000049a,0x00000000,0x00030047,0x000004a3,0x00000000,0x00030047,0x000004a5, + 0x00000000,0x00030047,0x000004a6,0x00000000,0x00030047,0x000004a7,0x00000000,0x00030047, + 0x000004a8,0x00000000,0x00030047,0x000004ad,0x00000000,0x00030047,0x000004b3,0x00000000, + 0x00030047,0x000004b4,0x00000000,0x00030047,0x000004bd,0x00000000,0x00030047,0x000004be, + 0x00000000,0x00030047,0x000004bf,0x00000000,0x00030047,0x000004c0,0x00000000,0x00030047, + 0x000004c1,0x00000000,0x00030047,0x000004c2,0x00000000,0x00030047,0x000004c3,0x00000000, + 0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c9,0x00000000,0x00030047,0x000004d1, + 0x00000000,0x00030047,0x000004d2,0x00000000,0x00030047,0x000004d4,0x00000000,0x00030047, + 0x000004fd,0x00000000,0x00030047,0x000004ff,0x00000000,0x00030047,0x00000500,0x00000000, + 0x00030047,0x00000501,0x00000000,0x00030047,0x00000502,0x00000000,0x00030047,0x00000503, + 0x00000000,0x00030047,0x00000504,0x00000000,0x00030047,0x00000505,0x00000000,0x00030047, + 0x0000053e,0x00000000,0x00030047,0x0000053f,0x00000000,0x00030047,0x00000544,0x00000000, + 0x00030047,0x00000546,0x00000000,0x00030047,0x00000548,0x00000000,0x00030047,0x00000549, + 0x00000000,0x00030047,0x0000054d,0x00000000,0x00030047,0x0000055b,0x00000000,0x00030047, + 0x0000055c,0x00000000,0x00030047,0x0000055d,0x00000000,0x00030047,0x0000055e,0x00000000, + 0x00030047,0x0000055f,0x00000000,0x00030047,0x00000560,0x00000000,0x00030047,0x0000056a, + 0x00000000,0x00030047,0x0000056b,0x00000000,0x00030047,0x0000056c,0x00000000,0x00030047, + 0x0000056d,0x00000000,0x00030047,0x00000574,0x00000000,0x00030047,0x00000576,0x00000000, + 0x00030047,0x00000577,0x00000000,0x00030047,0x00000579,0x00000000,0x00030047,0x0000057a, + 0x00000000,0x00030047,0x0000057c,0x00000000,0x00030047,0x0000057d,0x00000000,0x00030047, + 0x00000587,0x00000000,0x00030047,0x00000589,0x00000000,0x00030047,0x0000058a,0x00000000, + 0x00030047,0x0000058d,0x00000000,0x00030047,0x0000058e,0x00000000,0x00030047,0x00000590, + 0x00000000,0x00030047,0x00000592,0x00000000,0x00030047,0x00000594,0x00000000,0x00030047, + 0x000005a2,0x00000000,0x00030047,0x000005a3,0x00000000,0x00030047,0x000005a6,0x00000000, + 0x00030047,0x000005a7,0x00000000,0x00030047,0x000005a8,0x00000000,0x00030047,0x000005aa, + 0x00000000,0x00030047,0x000005ac,0x00000000,0x00030047,0x000005ae,0x00000000,0x00030047, + 0x000005b0,0x00000000,0x00030047,0x000005b2,0x00000000,0x00030047,0x000005c0,0x00000000, + 0x00030047,0x000005c1,0x00000000,0x00030047,0x000005c4,0x00000000,0x00030047,0x000005c5, + 0x00000000,0x00030047,0x000005c6,0x00000000,0x00030047,0x000005c7,0x00000000,0x00030047, + 0x000005c8,0x00000000,0x00030047,0x000005c9,0x00000000,0x00030047,0x000005ca,0x00000000, + 0x00030047,0x000005cc,0x00000000,0x00030047,0x000005cd,0x00000000,0x00030047,0x000005ce, + 0x00000000,0x00030047,0x000005d0,0x00000000,0x00030047,0x000005d1,0x00000000,0x00030047, + 0x000005d3,0x00000000,0x00030047,0x000005d5,0x00000000,0x00030047,0x000005d6,0x00000000, + 0x00030047,0x000005d7,0x00000000,0x00030047,0x000005d8,0x00000000,0x00030047,0x000005d9, + 0x00000000,0x00030047,0x000005da,0x00000000,0x00030047,0x000005db,0x00000000,0x00030047, + 0x000005dc,0x00000000,0x00030047,0x000005dd,0x00000000,0x00030047,0x000005de,0x00000000, + 0x00030047,0x000005df,0x00000000,0x00030047,0x000005e0,0x00000000,0x00030047,0x000005e1, + 0x00000000,0x00030047,0x000005e2,0x00000000,0x00030047,0x000005e3,0x00000000,0x00030047, + 0x000005e4,0x00000000,0x00030047,0x000005e5,0x00000000,0x00030047,0x000005e6,0x00000000, + 0x00030047,0x000005e7,0x00000000,0x00030047,0x000005e8,0x00000000,0x00030047,0x000005ea, + 0x00000000,0x00030047,0x000005eb,0x00000000,0x00030047,0x000005ec,0x00000000,0x00030047, + 0x000005ed,0x00000000,0x00030047,0x000005ee,0x00000000,0x00030047,0x000005ef,0x00000000, + 0x00030047,0x000005f0,0x00000000,0x00030047,0x000005f1,0x00000000,0x00030047,0x000005f2, + 0x00000000,0x00030047,0x000005f3,0x00000000,0x00030047,0x000005f4,0x00000000,0x00030047, + 0x000005f5,0x00000000,0x00030047,0x000005f6,0x00000000,0x00030047,0x000005f7,0x00000000, + 0x00030047,0x000005f8,0x00000000,0x00030047,0x000005f9,0x00000000,0x00030047,0x000005fa, + 0x00000000,0x00030047,0x000005fb,0x00000000,0x00030047,0x000005fc,0x00000000,0x00030047, + 0x000005fe,0x00000000,0x00030047,0x00000600,0x00000000,0x00030047,0x00000602,0x00000000, + 0x00030047,0x00000603,0x00000000,0x00030047,0x00000604,0x00000000,0x00030047,0x00000606, + 0x00000000,0x00030047,0x00000607,0x00000000,0x00030047,0x00000608,0x00000000,0x00030047, + 0x00000609,0x00000000,0x00030047,0x0000060a,0x00000000,0x00030047,0x0000060b,0x00000000, + 0x00030047,0x0000060c,0x00000000,0x00030047,0x0000060e,0x00000000,0x00030047,0x0000060f, + 0x00000000,0x00030047,0x00000610,0x00000000,0x00030047,0x00000611,0x00000000,0x00030047, + 0x00000612,0x00000000,0x00030047,0x00000613,0x00000000,0x00030047,0x00000614,0x00000000, + 0x00030047,0x00000615,0x00000000,0x00030047,0x00000616,0x00000000,0x00030047,0x00000617, + 0x00000000,0x00030047,0x00000618,0x00000000,0x00030047,0x0000061a,0x00000000,0x00030047, + 0x0000061b,0x00000000,0x00030047,0x0000061c,0x00000000,0x00030047,0x0000061e,0x00000000, + 0x00030047,0x0000061f,0x00000000,0x00030047,0x00000620,0x00000000,0x00030047,0x00000622, + 0x00000000,0x00030047,0x00000623,0x00000000,0x00030047,0x00000624,0x00000000,0x00030047, + 0x00000626,0x00000000,0x00030047,0x00000627,0x00000000,0x00030047,0x00000629,0x00000000, + 0x00030047,0x0000062a,0x00000000,0x00030047,0x0000062b,0x00000000,0x00030047,0x00000632, + 0x00000000,0x00030047,0x00000633,0x00000000,0x00030047,0x00000636,0x00000000,0x00030047, + 0x00000638,0x00000000,0x00030047,0x00000639,0x00000000,0x00030047,0x0000063b,0x00000000, + 0x00030047,0x0000063c,0x00000000,0x00030047,0x0000063d,0x00000000,0x00030047,0x0000063e, + 0x00000000,0x00030047,0x0000063f,0x00000000,0x00030047,0x00000640,0x00000000,0x00030047, + 0x00000641,0x00000000,0x00030047,0x00000642,0x00000000,0x00030047,0x00000643,0x00000000, + 0x00030047,0x00000645,0x00000000,0x00030047,0x00000646,0x00000000,0x00030047,0x00000648, + 0x00000000,0x00030047,0x0000064b,0x00000000,0x00030047,0x0000064c,0x00000000,0x00030047, + 0x0000064d,0x00000000,0x00030047,0x0000064f,0x00000000,0x00030047,0x00000650,0x00000000, + 0x00030047,0x00000651,0x00000000,0x00030047,0x00000659,0x00000000,0x00030047,0x0000065f, + 0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000661,0x00000000,0x00030047, + 0x00000662,0x00000000,0x00030047,0x00000663,0x00000000,0x00030047,0x00000665,0x00000000, + 0x00030047,0x00000666,0x00000000,0x00030047,0x00000668,0x00000000,0x00030047,0x00000669, + 0x00000000,0x00030047,0x0000066a,0x00000000,0x00030047,0x0000066b,0x00000000,0x00030047, + 0x0000066c,0x00000000,0x00030047,0x0000066d,0x00000000,0x00030047,0x0000066e,0x00000000, + 0x00030047,0x00000670,0x00000000,0x00030047,0x00000671,0x00000000,0x00030047,0x00000672, + 0x00000000,0x00030047,0x00000674,0x00000000,0x00030047,0x00000675,0x00000000,0x00030047, + 0x00000676,0x00000000,0x00030047,0x00000677,0x00000000,0x00030047,0x00000678,0x00000000, + 0x00030047,0x00000679,0x00000000,0x00030047,0x0000067a,0x00000000,0x00030047,0x0000067b, + 0x00000000,0x00030047,0x0000067c,0x00000000,0x00030047,0x0000067d,0x00000000,0x00030047, + 0x0000067e,0x00000000,0x00030047,0x00000680,0x00000000,0x00030047,0x00000681,0x00000000, + 0x00030047,0x00000682,0x00000000,0x00030047,0x0000068b,0x00000000,0x00030047,0x00000691, + 0x00000000,0x00030047,0x00000692,0x00000000,0x00030047,0x00000697,0x00000000,0x00030047, + 0x0000069d,0x00000000,0x00030047,0x0000069e,0x00000000,0x00030047,0x0000069f,0x00000000, + 0x00030047,0x000006a2,0x00000000,0x00030047,0x000006a3,0x00000000,0x00030047,0x000006a4, + 0x00000000,0x00030047,0x000006aa,0x00000000,0x00030047,0x000006ab,0x00000000,0x00030047, + 0x000006ac,0x00000000,0x00030047,0x000006b4,0x00000000,0x00030047,0x000006b5,0x00000000, + 0x00030047,0x000006b6,0x00000000,0x00030047,0x000006b7,0x00000000,0x00030047,0x000006b8, + 0x00000000,0x00030047,0x000006b9,0x00000000,0x00030047,0x000006ba,0x00000000,0x00030047, + 0x000006bb,0x00000000,0x00030047,0x000006bc,0x00000000,0x00030047,0x000006be,0x00000000, + 0x00030047,0x000006bf,0x00000000,0x00030047,0x000006c0,0x00000000,0x00030047,0x000006c1, + 0x00000000,0x00030047,0x000006c3,0x00000000,0x00030047,0x000006c4,0x00000000,0x00030047, + 0x000006c5,0x00000000,0x00030047,0x000006c6,0x00000000,0x00030047,0x000006c7,0x00000000, + 0x00030047,0x000006c8,0x00000000,0x00030047,0x000006c9,0x00000000,0x00030047,0x000006ca, + 0x00000000,0x00030047,0x000006cd,0x00000000,0x00030047,0x000006d0,0x00000000,0x00030047, + 0x000006d1,0x00000000,0x00030047,0x000006d2,0x00000000,0x00030047,0x000006d3,0x00000000, + 0x00030047,0x000006d8,0x00000000,0x00030047,0x000006db,0x00000000,0x00030047,0x000006dc, + 0x00000000,0x00030047,0x000006dd,0x00000000,0x00030047,0x000006de,0x00000000,0x00030047, + 0x000006e3,0x00000000,0x00030047,0x000006e6,0x00000000,0x00030047,0x000006e7,0x00000000, + 0x00030047,0x000006e8,0x00000000,0x00030047,0x000006ed,0x00000000,0x00030047,0x000006f0, + 0x00000000,0x00030047,0x000006f1,0x00000000,0x00030047,0x000006f2,0x00000000,0x00030047, + 0x000006f6,0x00000000,0x00030047,0x000006f7,0x00000000,0x00030047,0x000006f8,0x00000000, + 0x00030047,0x000006fa,0x00000000,0x00030047,0x000006fb,0x00000000,0x00030047,0x000006fd, + 0x00000000,0x00030047,0x00000701,0x00000000,0x00030047,0x00000702,0x00000000,0x00030047, + 0x00000705,0x00000000,0x00030047,0x00000706,0x00000000,0x00030047,0x00000707,0x00000000, + 0x00030047,0x00000708,0x00000000,0x00030047,0x0000070a,0x00000000,0x00030047,0x0000070c, + 0x00000000,0x00030047,0x0000070e,0x00000000,0x00030047,0x00000710,0x00000000,0x00030047, + 0x00000711,0x00000000,0x00030047,0x00000712,0x00000000,0x00030047,0x00000714,0x00000000, + 0x00030047,0x00000716,0x00000000,0x00030047,0x00000718,0x00000000,0x00030047,0x0000071a, + 0x00000000,0x00030047,0x0000071b,0x00000000,0x00030047,0x0000071c,0x00000000,0x00030047, + 0x0000071e,0x00000000,0x00030047,0x00000720,0x00000000,0x00030047,0x00000722,0x00000000, + 0x00030047,0x00000724,0x00000000,0x00030047,0x00000725,0x00000000,0x00030047,0x00000726, + 0x00000000,0x00030047,0x00000728,0x00000000,0x00030047,0x0000072a,0x00000000,0x00030047, + 0x0000072c,0x00000000,0x00030047,0x0000072e,0x00000000,0x00030047,0x0000072f,0x00000000, + 0x00030047,0x00000730,0x00000000,0x00030047,0x00000732,0x00000000,0x00030047,0x00000734, + 0x00000000,0x00030047,0x00000736,0x00000000,0x00030047,0x00000738,0x00000000,0x00030047, + 0x00000739,0x00000000,0x00030047,0x0000073a,0x00000000,0x00030047,0x0000073c,0x00000000, + 0x00030047,0x0000073e,0x00000000,0x00030047,0x00000740,0x00000000,0x00030047,0x00000742, + 0x00000000,0x00030047,0x00000743,0x00000000,0x00030047,0x00000744,0x00000000,0x00030047, + 0x00000746,0x00000000,0x00030047,0x00000748,0x00000000,0x00030047,0x0000074a,0x00000000, + 0x00030047,0x0000074c,0x00000000,0x00030047,0x0000074d,0x00000000,0x00030047,0x0000074e, + 0x00000000,0x00030047,0x00000750,0x00000000,0x00030047,0x00000752,0x00000000,0x00030047, + 0x00000754,0x00000000,0x00030047,0x00000756,0x00000000,0x00030047,0x00000757,0x00000000, + 0x00030047,0x00000758,0x00000000,0x00030047,0x0000075a,0x00000000,0x00030047,0x0000075c, + 0x00000000,0x00030047,0x0000075e,0x00000000,0x00030047,0x00000760,0x00000000,0x00030047, + 0x00000761,0x00000000,0x00030047,0x00000762,0x00000000,0x00030047,0x00000764,0x00000000, + 0x00030047,0x00000766,0x00000000,0x00030047,0x00000768,0x00000000,0x00030047,0x0000076a, + 0x00000000,0x00030047,0x0000076b,0x00000000,0x00030047,0x0000076c,0x00000000,0x00030047, + 0x0000076e,0x00000000,0x00030047,0x00000770,0x00000000,0x00030047,0x00000772,0x00000000, + 0x00030047,0x00000774,0x00000000,0x00030047,0x00000775,0x00000000,0x00030047,0x00000776, + 0x00000000,0x00030047,0x00000778,0x00000000,0x00030047,0x0000077a,0x00000000,0x00030047, + 0x0000077c,0x00000000,0x00030047,0x0000077e,0x00000000,0x00030047,0x0000077f,0x00000000, + 0x00030047,0x00000780,0x00000000,0x00030047,0x00000782,0x00000000,0x00030047,0x00000784, + 0x00000000,0x00030047,0x00000786,0x00000000,0x00030047,0x00000788,0x00000000,0x00030047, + 0x00000789,0x00000000,0x00030047,0x0000078a,0x00000000,0x00030047,0x0000078c,0x00000000, + 0x00030047,0x0000078e,0x00000000,0x00030047,0x00000790,0x00000000,0x00030047,0x00000792, + 0x00000000,0x00030047,0x00000794,0x00000000,0x00030047,0x00000795,0x00000000,0x00030047, + 0x00000796,0x00000000,0x00030047,0x00000798,0x00000000,0x00030047,0x0000079a,0x00000000, + 0x00030047,0x0000079b,0x00000000,0x00030047,0x0000079c,0x00000000,0x00030047,0x0000079e, + 0x00000000,0x00030047,0x000007a0,0x00000000,0x00030047,0x000007a2,0x00000000,0x00030047, + 0x000007a3,0x00000000,0x00030047,0x000007a5,0x00000000,0x00030047,0x000007a6,0x00000000, + 0x00030047,0x000007a7,0x00000000,0x00030047,0x000007a8,0x00000000,0x00030047,0x000007ae, + 0x00000000,0x00030047,0x000007b1,0x00000000,0x00030047,0x000007b3,0x00000000,0x00030047, + 0x000007b4,0x00000000,0x00030047,0x000007b6,0x00000000,0x00030047,0x000007b7,0x00000000, + 0x00030047,0x000007ba,0x00000000,0x00030047,0x000007bb,0x00000000,0x00030047,0x000007bc, + 0x00000000,0x00030047,0x000007bf,0x00000000,0x00030047,0x000007c1,0x00000000,0x00030047, + 0x000007c2,0x00000000,0x00030047,0x000007c3,0x00000000,0x00030047,0x000007c4,0x00000000, + 0x00030047,0x000007c6,0x00000000,0x00030047,0x000007c7,0x00000000,0x00030047,0x000007ca, + 0x00000000,0x00030047,0x000007cb,0x00000000,0x00030047,0x000007cc,0x00000000,0x00030047, + 0x000007cf,0x00000000,0x00030047,0x000007d1,0x00000000,0x00030047,0x000007d2,0x00000000, + 0x00030047,0x000007d3,0x00000000,0x00030047,0x000007d4,0x00000000,0x00030047,0x000007d6, + 0x00000000,0x00030047,0x000007d7,0x00000000,0x00030047,0x000007da,0x00000000,0x00030047, + 0x000007db,0x00000000,0x00030047,0x000007dc,0x00000000,0x00030047,0x000007df,0x00000000, + 0x00030047,0x000007e1,0x00000000,0x00030047,0x000007e2,0x00000000,0x00030047,0x000007e3, + 0x00000000,0x00030047,0x000007e4,0x00000000,0x00030047,0x000007e6,0x00000000,0x00030047, + 0x000007e7,0x00000000,0x00030047,0x000007ea,0x00000000,0x00030047,0x000007eb,0x00000000, + 0x00030047,0x000007ec,0x00000000,0x00030047,0x000007ef,0x00000000,0x00030047,0x000007f1, + 0x00000000,0x00030047,0x000007f2,0x00000000,0x00030047,0x000007f3,0x00000000,0x00030047, + 0x000007f4,0x00000000,0x00030047,0x000007f5,0x00000000,0x00030047,0x000007f6,0x00000000, + 0x00030047,0x000007f7,0x00000000,0x00030047,0x000007f8,0x00000000,0x00030047,0x000007f9, + 0x00000000,0x00030047,0x000007fa,0x00000000,0x00030047,0x000007fb,0x00000000,0x00030047, + 0x000007fc,0x00000000,0x00030047,0x000007fd,0x00000000,0x00030047,0x000007fe,0x00000000, + 0x00030047,0x000007ff,0x00000000,0x00030047,0x00000800,0x00000000,0x00030047,0x00000801, + 0x00000000,0x00030047,0x00000803,0x00000000,0x00030047,0x00000805,0x00000000,0x00030047, + 0x00000806,0x00000000,0x00030047,0x00000808,0x00000000,0x00030047,0x00000809,0x00000000, + 0x00030047,0x0000080a,0x00000000,0x00030047,0x0000080b,0x00000000,0x00030047,0x0000080c, + 0x00000000,0x00030047,0x0000080f,0x00000000,0x00030047,0x00000811,0x00000000,0x00030047, + 0x00000812,0x00000000,0x00030047,0x00000815,0x00000000,0x00030047,0x00000816,0x00000000, + 0x00030047,0x00000819,0x00000000,0x00030047,0x0000081b,0x00000000,0x00030047,0x0000081c, + 0x00000000,0x00030047,0x0000081d,0x00000000,0x00030047,0x0000081e,0x00000000,0x00030047, + 0x0000081f,0x00000000,0x00030047,0x00000820,0x00000000,0x00030047,0x00000821,0x00000000, + 0x00030047,0x00000822,0x00000000,0x00030047,0x00000823,0x00000000,0x00030047,0x00000824, + 0x00000000,0x00030047,0x00000825,0x00000000,0x00030047,0x00000826,0x00000000,0x00030047, + 0x00000827,0x00000000,0x00030047,0x00000829,0x00000000,0x00030047,0x0000082b,0x00000000, + 0x00030047,0x0000082c,0x00000000,0x00030047,0x0000082d,0x00000000,0x00030047,0x0000082f, + 0x00000000,0x00030047,0x00000831,0x00000000,0x00030047,0x00000833,0x00000000,0x00030047, + 0x00000835,0x00000000,0x00030047,0x00000836,0x00000000,0x00030047,0x00000837,0x00000000, + 0x00030047,0x00000838,0x00000000,0x00030047,0x00000839,0x00000000,0x00030047,0x0000083b, + 0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x0000083e,0x00000000,0x00030047, + 0x0000083f,0x00000000,0x00030047,0x00000841,0x00000000,0x00030047,0x00000843,0x00000000, + 0x00030047,0x00000845,0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000848, + 0x00000000,0x00030047,0x00000849,0x00000000,0x00030047,0x0000084b,0x00000000,0x00030047, + 0x0000084d,0x00000000,0x00030047,0x0000084f,0x00000000,0x00030047,0x00000850,0x00000000, + 0x00030047,0x00000851,0x00000000,0x00030047,0x00000853,0x00000000,0x00030047,0x00000855, + 0x00000000,0x00030047,0x00000857,0x00000000,0x00030047,0x00000858,0x00000000,0x00030047, + 0x00000859,0x00000000,0x00030047,0x0000085b,0x00000000,0x00030047,0x0000085c,0x00000000, + 0x00030047,0x0000085f,0x00000000,0x00030047,0x00000860,0x00000000,0x00030047,0x00000861, + 0x00000000,0x00030047,0x00000864,0x00000000,0x00030047,0x00000866,0x00000000,0x00030047, + 0x00000867,0x00000000,0x00030047,0x00000868,0x00000000,0x00030047,0x00000869,0x00000000, + 0x00030047,0x0000086b,0x00000000,0x00030047,0x0000086c,0x00000000,0x00030047,0x0000086f, + 0x00000000,0x00030047,0x00000870,0x00000000,0x00030047,0x00000871,0x00000000,0x00030047, + 0x00000874,0x00000000,0x00030047,0x00000876,0x00000000,0x00030047,0x00000877,0x00000000, + 0x00030047,0x00000878,0x00000000,0x00030047,0x00000879,0x00000000,0x00030047,0x0000087b, + 0x00000000,0x00030047,0x0000087d,0x00000000,0x00030047,0x0000087f,0x00000000,0x00030047, + 0x00000880,0x00000000,0x00030047,0x00000882,0x00000000,0x00030047,0x00000883,0x00000000, + 0x00030047,0x00000884,0x00000000,0x00030047,0x00000886,0x00000000,0x00030047,0x00000888, + 0x00000000,0x00030047,0x0000088a,0x00000000,0x00030047,0x0000088c,0x00000000,0x00030047, + 0x0000088d,0x00000000,0x00030047,0x0000088e,0x00000000,0x00030047,0x00000890,0x00000000, + 0x00030047,0x00000892,0x00000000,0x00030047,0x00000894,0x00000000,0x00030047,0x00000896, + 0x00000000,0x00030047,0x00000898,0x00000000,0x00030047,0x00000899,0x00000000,0x00030047, + 0x0000089a,0x00000000,0x00030047,0x0000089c,0x00000000,0x00030047,0x0000089e,0x00000000, + 0x00030047,0x0000089f,0x00000000,0x00030047,0x000008a0,0x00000000,0x00030047,0x000008a2, + 0x00000000,0x00030047,0x000008a4,0x00000000,0x00030047,0x000008a6,0x00000000,0x00030047, + 0x000008a7,0x00000000,0x00030047,0x000008a9,0x00000000,0x00030047,0x000008aa,0x00000000, + 0x00030047,0x000008ab,0x00000000,0x00030047,0x000008ac,0x00000000,0x00030047,0x000008b2, + 0x00000000,0x00030047,0x000008b5,0x00000000,0x00030047,0x000008b7,0x00000000,0x00030047, + 0x000008b8,0x00000000,0x00030047,0x000008ba,0x00000000,0x00030047,0x000008bb,0x00000000, + 0x00030047,0x000008be,0x00000000,0x00030047,0x000008bf,0x00000000,0x00030047,0x000008c0, + 0x00000000,0x00030047,0x000008c3,0x00000000,0x00030047,0x000008c5,0x00000000,0x00030047, + 0x000008c6,0x00000000,0x00030047,0x000008c7,0x00000000,0x00030047,0x000008c8,0x00000000, + 0x00030047,0x000008ca,0x00000000,0x00030047,0x000008cb,0x00000000,0x00030047,0x000008ce, + 0x00000000,0x00030047,0x000008cf,0x00000000,0x00030047,0x000008d0,0x00000000,0x00030047, + 0x000008d3,0x00000000,0x00030047,0x000008d5,0x00000000,0x00030047,0x000008d6,0x00000000, + 0x00030047,0x000008d7,0x00000000,0x00030047,0x000008d8,0x00000000,0x00030047,0x000008da, + 0x00000000,0x00030047,0x000008db,0x00000000,0x00030047,0x000008de,0x00000000,0x00030047, + 0x000008df,0x00000000,0x00030047,0x000008e0,0x00000000,0x00030047,0x000008e3,0x00000000, + 0x00030047,0x000008e5,0x00000000,0x00030047,0x000008e6,0x00000000,0x00030047,0x000008e7, + 0x00000000,0x00030047,0x000008e8,0x00000000,0x00030047,0x000008ea,0x00000000,0x00030047, + 0x000008eb,0x00000000,0x00030047,0x000008ee,0x00000000,0x00030047,0x000008ef,0x00000000, + 0x00030047,0x000008f0,0x00000000,0x00030047,0x000008f3,0x00000000,0x00030047,0x000008f5, + 0x00000000,0x00030047,0x000008f6,0x00000000,0x00030047,0x000008f7,0x00000000,0x00030047, + 0x000008f8,0x00000000,0x00030047,0x000008f9,0x00000000,0x00030047,0x000008fa,0x00000000, + 0x00030047,0x000008fb,0x00000000,0x00030047,0x000008fc,0x00000000,0x00030047,0x000008fd, + 0x00000000,0x00030047,0x000008fe,0x00000000,0x00030047,0x000008ff,0x00000000,0x00030047, + 0x00000900,0x00000000,0x00030047,0x00000901,0x00000000,0x00030047,0x00000902,0x00000000, + 0x00030047,0x00000903,0x00000000,0x00030047,0x00000904,0x00000000,0x00030047,0x00000905, + 0x00000000,0x00030047,0x00000907,0x00000000,0x00030047,0x00000909,0x00000000,0x00030047, + 0x0000090a,0x00000000,0x00030047,0x0000090c,0x00000000,0x00030047,0x0000090d,0x00000000, + 0x00030047,0x0000090e,0x00000000,0x00030047,0x0000090f,0x00000000,0x00030047,0x00000910, + 0x00000000,0x00030047,0x00000913,0x00000000,0x00030047,0x00000915,0x00000000,0x00030047, + 0x00000916,0x00000000,0x00030047,0x00000919,0x00000000,0x00030047,0x0000091a,0x00000000, + 0x00030047,0x0000091d,0x00000000,0x00030047,0x0000091f,0x00000000,0x00030047,0x00000920, + 0x00000000,0x00030047,0x00000921,0x00000000,0x00030047,0x00000922,0x00000000,0x00030047, + 0x00000923,0x00000000,0x00030047,0x00000924,0x00000000,0x00030047,0x00000925,0x00000000, + 0x00030047,0x00000926,0x00000000,0x00030047,0x00000927,0x00000000,0x00030047,0x00000928, + 0x00000000,0x00030047,0x00000929,0x00000000,0x00030047,0x0000092a,0x00000000,0x00030047, + 0x0000092b,0x00000000,0x00030047,0x0000092d,0x00000000,0x00030047,0x0000092f,0x00000000, + 0x00030047,0x00000930,0x00000000,0x00030047,0x00000931,0x00000000,0x00030047,0x00000933, + 0x00000000,0x00030047,0x00000935,0x00000000,0x00030047,0x00000937,0x00000000,0x00030047, + 0x00000939,0x00000000,0x00030047,0x0000093a,0x00000000,0x00030047,0x0000093b,0x00000000, + 0x00030047,0x0000093c,0x00000000,0x00030047,0x0000093d,0x00000000,0x00030047,0x0000093f, + 0x00000000,0x00030047,0x00000941,0x00000000,0x00030047,0x00000942,0x00000000,0x00030047, + 0x00000943,0x00000000,0x00030047,0x00000945,0x00000000,0x00030047,0x00000947,0x00000000, + 0x00030047,0x00000949,0x00000000,0x00030047,0x0000094b,0x00000000,0x00030047,0x0000094c, + 0x00000000,0x00030047,0x0000094d,0x00000000,0x00030047,0x0000094f,0x00000000,0x00030047, + 0x00000951,0x00000000,0x00030047,0x00000953,0x00000000,0x00030047,0x00000954,0x00000000, + 0x00030047,0x00000955,0x00000000,0x00030047,0x00000957,0x00000000,0x00030047,0x00000959, + 0x00000000,0x00030047,0x0000095b,0x00000000,0x00030047,0x0000095c,0x00000000,0x00030047, + 0x0000095d,0x00000000,0x00030047,0x0000095f,0x00000000,0x00030047,0x00000960,0x00000000, + 0x00030047,0x00000963,0x00000000,0x00030047,0x00000964,0x00000000,0x00030047,0x00000965, + 0x00000000,0x00030047,0x00000968,0x00000000,0x00030047,0x0000096a,0x00000000,0x00030047, + 0x0000096b,0x00000000,0x00030047,0x0000096c,0x00000000,0x00030047,0x0000096d,0x00000000, + 0x00030047,0x0000096f,0x00000000,0x00030047,0x00000970,0x00000000,0x00030047,0x00000973, + 0x00000000,0x00030047,0x00000974,0x00000000,0x00030047,0x00000975,0x00000000,0x00030047, + 0x00000978,0x00000000,0x00030047,0x0000097a,0x00000000,0x00030047,0x0000097b,0x00000000, + 0x00030047,0x0000097c,0x00000000,0x00030047,0x0000097d,0x00000000,0x00030047,0x0000097f, + 0x00000000,0x00030047,0x00000981,0x00000000,0x00030047,0x00000983,0x00000000,0x00030047, + 0x00000984,0x00000000,0x00030047,0x00000986,0x00000000,0x00030047,0x00000987,0x00000000, + 0x00030047,0x00000988,0x00000000,0x00030047,0x0000098a,0x00000000,0x00030047,0x0000098c, + 0x00000000,0x00030047,0x0000098e,0x00000000,0x00030047,0x00000990,0x00000000,0x00030047, + 0x00000991,0x00000000,0x00030047,0x00000992,0x00000000,0x00030047,0x00000994,0x00000000, + 0x00030047,0x00000996,0x00000000,0x00030047,0x00000998,0x00000000,0x00030047,0x0000099a, + 0x00000000,0x00030047,0x0000099b,0x00000000,0x00030047,0x0000099c,0x00000000,0x00030047, + 0x0000099d,0x00000000,0x00030047,0x0000099e,0x00000000,0x00030047,0x0000099f,0x00000000, + 0x00030047,0x000009a0,0x00000000,0x00030047,0x000009a1,0x00000000,0x00030047,0x000009a2, + 0x00000000,0x00030047,0x000009a3,0x00000000,0x00030047,0x000009a4,0x00000000,0x00030047, + 0x000009a5,0x00000000,0x00030047,0x000009a6,0x00000000,0x00030047,0x000009a7,0x00000000, + 0x00030047,0x000009a8,0x00000000,0x00030047,0x000009a9,0x00000000,0x00030047,0x000009ab, + 0x00000000,0x00030047,0x000009ad,0x00000000,0x00030047,0x000009ae,0x00000000,0x00030047, + 0x000009b0,0x00000000,0x00030047,0x000009b1,0x00000000,0x00030047,0x000009b2,0x00000000, + 0x00030047,0x000009b3,0x00000000,0x00030047,0x000009b4,0x00000000,0x00030047,0x000009b7, + 0x00000000,0x00030047,0x000009b9,0x00000000,0x00030047,0x000009ba,0x00000000,0x00030047, + 0x000009bd,0x00000000,0x00030047,0x000009be,0x00000000,0x00030047,0x000009c1,0x00000000, + 0x00030047,0x000009c3,0x00000000,0x00030047,0x000009c4,0x00000000,0x00030047,0x000009c5, + 0x00000000,0x00030047,0x000009c6,0x00000000,0x00030047,0x000009c7,0x00000000,0x00030047, + 0x000009c8,0x00000000,0x00030047,0x000009c9,0x00000000,0x00030047,0x000009ca,0x00000000, + 0x00030047,0x000009cb,0x00000000,0x00030047,0x000009cc,0x00000000,0x00030047,0x000009cd, + 0x00000000,0x00030047,0x000009ce,0x00000000,0x00030047,0x000009cf,0x00000000,0x00030047, + 0x000009d1,0x00000000,0x00030047,0x000009d3,0x00000000,0x00030047,0x000009d4,0x00000000, + 0x00030047,0x000009d5,0x00000000,0x00030047,0x000009d7,0x00000000,0x00030047,0x000009d9, + 0x00000000,0x00030047,0x000009db,0x00000000,0x00030047,0x000009dd,0x00000000,0x00030047, + 0x000009de,0x00000000,0x00030047,0x000009df,0x00000000,0x00030047,0x000009e0,0x00000000, + 0x00030047,0x000009e1,0x00000000,0x00030047,0x000009e3,0x00000000,0x00030047,0x000009e5, + 0x00000000,0x00030047,0x000009e6,0x00000000,0x00030047,0x000009e7,0x00000000,0x00030047, + 0x000009e9,0x00000000,0x00030047,0x000009eb,0x00000000,0x00030047,0x000009ed,0x00000000, + 0x00030047,0x000009ef,0x00000000,0x00030047,0x000009f0,0x00000000,0x00030047,0x000009f1, + 0x00000000,0x00030047,0x000009f3,0x00000000,0x00030047,0x000009f5,0x00000000,0x00030047, + 0x000009f7,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047,0x000009f9,0x00000000, + 0x00030047,0x000009fb,0x00000000,0x00030047,0x000009fd,0x00000000,0x00030047,0x000009ff, + 0x00000000,0x00030047,0x00000a00,0x00000000,0x00030047,0x00000a01,0x00000000,0x00030047, + 0x00000a03,0x00000000,0x00030047,0x00000a04,0x00000000,0x00030047,0x00000a07,0x00000000, + 0x00030047,0x00000a08,0x00000000,0x00030047,0x00000a09,0x00000000,0x00030047,0x00000a0c, + 0x00000000,0x00030047,0x00000a0e,0x00000000,0x00030047,0x00000a0f,0x00000000,0x00030047, + 0x00000a10,0x00000000,0x00030047,0x00000a11,0x00000000,0x00030047,0x00000a13,0x00000000, + 0x00030047,0x00000a14,0x00000000,0x00030047,0x00000a17,0x00000000,0x00030047,0x00000a18, + 0x00000000,0x00030047,0x00000a19,0x00000000,0x00030047,0x00000a1c,0x00000000,0x00030047, + 0x00000a1e,0x00000000,0x00030047,0x00000a1f,0x00000000,0x00030047,0x00000a20,0x00000000, + 0x00030047,0x00000a21,0x00000000,0x00030047,0x00000a23,0x00000000,0x00030047,0x00000a25, + 0x00000000,0x00030047,0x00000a27,0x00000000,0x00030047,0x00000a28,0x00000000,0x00030047, + 0x00000a2a,0x00000000,0x00030047,0x00000a2b,0x00000000,0x00030047,0x00000a2c,0x00000000, + 0x00030047,0x00000a2e,0x00000000,0x00030047,0x00000a30,0x00000000,0x00030047,0x00000a32, + 0x00000000,0x00030047,0x00000a34,0x00000000,0x00030047,0x00000a35,0x00000000,0x00030047, + 0x00000a36,0x00000000,0x00030047,0x00000a38,0x00000000,0x00030047,0x00000a3a,0x00000000, + 0x00030047,0x00000a3c,0x00000000,0x00030047,0x00000a3e,0x00000000,0x00030047,0x00000a3f, + 0x00000000,0x00030047,0x00000a40,0x00000000,0x00030047,0x00000a41,0x00000000,0x00030047, + 0x00000a42,0x00000000,0x00030047,0x00000a43,0x00000000,0x00030047,0x00000a44,0x00000000, + 0x00030047,0x00000a45,0x00000000,0x00030047,0x00000a46,0x00000000,0x00030047,0x00000a47, + 0x00000000,0x00030047,0x00000a48,0x00000000,0x00030047,0x00000a49,0x00000000,0x00030047, + 0x00000a4a,0x00000000,0x00030047,0x00000a4b,0x00000000,0x00030047,0x00000a4c,0x00000000, + 0x00030047,0x00000a4d,0x00000000,0x00030047,0x00000a4f,0x00000000,0x00030047,0x00000a51, + 0x00000000,0x00030047,0x00000a52,0x00000000,0x00030047,0x00000a54,0x00000000,0x00030047, + 0x00000a55,0x00000000,0x00030047,0x00000a56,0x00000000,0x00030047,0x00000a57,0x00000000, + 0x00030047,0x00000a58,0x00000000,0x00030047,0x00000a5b,0x00000000,0x00030047,0x00000a5d, + 0x00000000,0x00030047,0x00000a5e,0x00000000,0x00030047,0x00000a61,0x00000000,0x00030047, + 0x00000a62,0x00000000,0x00030047,0x00000a65,0x00000000,0x00030047,0x00000a67,0x00000000, + 0x00030047,0x00000a68,0x00000000,0x00030047,0x00000a69,0x00000000,0x00030047,0x00000a6a, + 0x00000000,0x00030047,0x00000a6b,0x00000000,0x00030047,0x00000a6c,0x00000000,0x00030047, + 0x00000a6d,0x00000000,0x00030047,0x00000a6e,0x00000000,0x00030047,0x00000a6f,0x00000000, + 0x00030047,0x00000a70,0x00000000,0x00030047,0x00000a71,0x00000000,0x00030047,0x00000a72, + 0x00000000,0x00030047,0x00000a73,0x00000000,0x00030047,0x00000a75,0x00000000,0x00030047, + 0x00000a77,0x00000000,0x00030047,0x00000a78,0x00000000,0x00030047,0x00000a79,0x00000000, + 0x00030047,0x00000a7b,0x00000000,0x00030047,0x00000a7d,0x00000000,0x00030047,0x00000a7f, + 0x00000000,0x00030047,0x00000a81,0x00000000,0x00030047,0x00000a82,0x00000000,0x00030047, + 0x00000a83,0x00000000,0x00030047,0x00000a84,0x00000000,0x00030047,0x00000a85,0x00000000, + 0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a89,0x00000000,0x00030047,0x00000a8a, + 0x00000000,0x00030047,0x00000a8b,0x00000000,0x00030047,0x00000a8d,0x00000000,0x00030047, + 0x00000a8f,0x00000000,0x00030047,0x00000a91,0x00000000,0x00030047,0x00000a93,0x00000000, + 0x00030047,0x00000a94,0x00000000,0x00030047,0x00000a95,0x00000000,0x00030047,0x00000a97, + 0x00000000,0x00030047,0x00000a99,0x00000000,0x00030047,0x00000a9b,0x00000000,0x00030047, + 0x00000a9c,0x00000000,0x00030047,0x00000a9d,0x00000000,0x00030047,0x00000a9f,0x00000000, + 0x00030047,0x00000aa1,0x00000000,0x00030047,0x00000aa3,0x00000000,0x00030047,0x00000aa4, + 0x00000000,0x00030047,0x00000aa5,0x00000000,0x00030047,0x00000aa7,0x00000000,0x00030047, + 0x00000aa8,0x00000000,0x00030047,0x00000aab,0x00000000,0x00030047,0x00000aac,0x00000000, + 0x00030047,0x00000aad,0x00000000,0x00030047,0x00000ab0,0x00000000,0x00030047,0x00000ab2, + 0x00000000,0x00030047,0x00000ab3,0x00000000,0x00030047,0x00000ab4,0x00000000,0x00030047, + 0x00000ab5,0x00000000,0x00030047,0x00000ab7,0x00000000,0x00030047,0x00000ab8,0x00000000, + 0x00030047,0x00000abb,0x00000000,0x00030047,0x00000abc,0x00000000,0x00030047,0x00000abd, + 0x00000000,0x00030047,0x00000ac0,0x00000000,0x00030047,0x00000ac2,0x00000000,0x00030047, + 0x00000ac3,0x00000000,0x00030047,0x00000ac4,0x00000000,0x00030047,0x00000ac5,0x00000000, + 0x00030047,0x00000ac7,0x00000000,0x00030047,0x00000ac9,0x00000000,0x00030047,0x00000acb, + 0x00000000,0x00030047,0x00000acc,0x00000000,0x00030047,0x00000ace,0x00000000,0x00030047, + 0x00000acf,0x00000000,0x00030047,0x00000ad0,0x00000000,0x00030047,0x00000ad2,0x00000000, + 0x00030047,0x00000ad4,0x00000000,0x00030047,0x00000ad6,0x00000000,0x00030047,0x00000ad8, + 0x00000000,0x00030047,0x00000ad9,0x00000000,0x00030047,0x00000adb,0x00000000,0x00030047, + 0x00000adc,0x00000000,0x00030047,0x00000add,0x00000000,0x00030047,0x00000ae1,0x00000000, + 0x00030047,0x00000ae2,0x00000000,0x00030047,0x00000ae4,0x00000000,0x00030047,0x00000ae5, + 0x00000000,0x00030047,0x00000ae6,0x00000000,0x00030047,0x00000ae8,0x00000000,0x00030047, + 0x00000aea,0x00000000,0x00030047,0x00000aeb,0x00000000,0x00030047,0x00000aec,0x00000000, + 0x00030047,0x00000aed,0x00000000,0x00030047,0x00000af7,0x00000000,0x00030047,0x00000af8, + 0x00000000,0x00030047,0x00000af9,0x00000000,0x00030047,0x00000afa,0x00000000,0x00030047, + 0x00000afb,0x00000000,0x00030047,0x00000afc,0x00000000,0x00030047,0x00000afd,0x00000000, + 0x00030047,0x00000afe,0x00000000,0x00030047,0x00000b00,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040020,0x00000007, + 0x00000007,0x00000006,0x00040017,0x0000000c,0x00000006,0x00000002,0x00040020,0x0000000d, + 0x00000007,0x0000000c,0x00040015,0x00000012,0x00000020,0x00000000,0x00040020,0x00000013, + 0x00000007,0x00000012,0x00040017,0x00000024,0x00000006,0x00000003,0x00040017,0x0000002f, + 0x00000006,0x00000004,0x00040020,0x00000034,0x00000007,0x0000002f,0x00040018,0x00000035, + 0x0000000c,0x00000002,0x00040020,0x00000042,0x00000007,0x00000024,0x00040015,0x00000080, + 0x00000020,0x00000001,0x00040017,0x00000081,0x00000080,0x00000002,0x00040020,0x00000082, + 0x00000007,0x00000081,0x0004002b,0x00000012,0x000000a3,0x00000000,0x0004002b,0x00000012, + 0x000000a6,0x00000001,0x0004002b,0x00000012,0x000000b9,0x00000002,0x0004002b,0x00000012, + 0x000000d0,0x00000003,0x0004002b,0x00000006,0x000000d9,0x3f800000,0x0004002b,0x00000006, + 0x000000da,0x00000000,0x00020014,0x000000e8,0x0004002b,0x00000006,0x00000116,0x3d897143, + 0x0004002b,0x00000006,0x0000011a,0x3bbf4590,0x0004002b,0x00000006,0x00000121,0x4253ee82, + 0x00030030,0x000000e8,0x0000012c,0x0004002b,0x00000006,0x00000140,0x3e99999a,0x0004002b, + 0x00000006,0x00000141,0x3f170a3d,0x0004002b,0x00000006,0x00000142,0x3de147ae,0x0004002b, + 0x00000006,0x0000015c,0x388205ff,0x0004002b,0x00000006,0x000001c2,0x40000000,0x0004002b, + 0x00000006,0x000001c9,0x3f000000,0x00040017,0x000001cf,0x000000e8,0x00000003,0x00040020, + 0x0000024b,0x00000007,0x00000080,0x0004002b,0x00000080,0x0000024d,0x00000000,0x0004002b, + 0x00000080,0x00000254,0x00000003,0x0004002b,0x00000006,0x00000266,0x3e800000,0x0004002b, + 0x00000006,0x0000026b,0x41800000,0x0004002b,0x00000006,0x00000270,0x41400000,0x0004002b, + 0x00000006,0x00000276,0x40400000,0x0004002b,0x00000080,0x00000282,0x00000001,0x00030030, + 0x000000e8,0x0000029d,0x0004002b,0x00000006,0x000002f1,0x3a000000,0x0004002b,0x00000006, + 0x000002f3,0xc2000000,0x0004002b,0x00000006,0x00000303,0x3a808081,0x00040017,0x00000306, + 0x000000e8,0x00000002,0x00040017,0x00000310,0x00000012,0x00000002,0x00040020,0x00000311, + 0x00000007,0x00000310,0x0003001d,0x00000313,0x00000310,0x0003001e,0x00000314,0x00000313, + 0x00040020,0x00000315,0x00000002,0x00000314,0x0004003b,0x00000315,0x00000316,0x00000002, + 0x00040020,0x00000318,0x00000002,0x00000310,0x0004002b,0x00000012,0x0000031f,0x00000300, + 0x00030030,0x000000e8,0x00000326,0x0004002b,0x00000012,0x0000032b,0x00000200,0x0004002b, + 0x00000006,0x00000335,0xbf800000,0x00030030,0x000000e8,0x0000033f,0x0004002b,0x00000012, + 0x00000345,0x00000010,0x00090019,0x0000034b,0x00000006,0x00000006,0x00000000,0x00000000, + 0x00000000,0x00000002,0x00000000,0x00040020,0x0000034c,0x00000000,0x0000034b,0x0004003b, + 0x0000034c,0x0000034d,0x00000000,0x0005002c,0x00000081,0x0000034f,0x0000024d,0x0000024d, + 0x00030030,0x000000e8,0x00000358,0x0004002b,0x00000012,0x0000035d,0x00000400,0x00040020, + 0x00000363,0x00000007,0x00000035,0x0003001d,0x00000365,0x0000002f,0x0003001e,0x00000366, + 0x00000365,0x00040020,0x00000367,0x00000002,0x00000366,0x0004003b,0x00000367,0x00000368, + 0x00000002,0x0004002b,0x00000012,0x0000036a,0x00000004,0x00040020,0x0000036e,0x00000002, + 0x0000002f,0x00040020,0x0000037a,0x00000001,0x0000002f,0x0004003b,0x0000037a,0x0000037b, + 0x00000001,0x0004002b,0x00000012,0x0000039b,0x0000000f,0x00090019,0x000003db,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000003dc, + 0x00000000,0x000003db,0x0004003b,0x000003dc,0x000003dd,0x00000000,0x0002001a,0x000003df, + 0x00040020,0x000003e0,0x00000000,0x000003df,0x0004003b,0x000003e0,0x000003e1,0x00000000, + 0x0003001b,0x000003e3,0x000003db,0x00030030,0x000000e8,0x000003ee,0x0004002b,0x00000080, + 0x000003fa,0x00000004,0x0004003b,0x0000034c,0x00000404,0x00000000,0x00040020,0x00000420, + 0x00000003,0x0000002f,0x0004003b,0x00000420,0x00000421,0x00000003,0x00090019,0x00000429, + 0x00000012,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000021,0x00040020, + 0x0000042a,0x00000000,0x00000429,0x0004003b,0x0000042a,0x0000042b,0x00000000,0x00040017, + 0x0000042e,0x00000012,0x00000004,0x0004002b,0x00000012,0x00000433,0x0001ffff,0x0004002b, + 0x00000012,0x00000439,0x00000011,0x0004001e,0x0000044b,0x00000006,0x00000006,0x00040020, + 0x0000044c,0x00000002,0x0000044b,0x0004003b,0x0000044c,0x0000044d,0x00000002,0x00040020, + 0x00000457,0x00000002,0x00000006,0x0006002c,0x00000024,0x00000473,0x000000d9,0x000000d9, + 0x000000d9,0x0006002c,0x00000024,0x00000474,0x000001c9,0x000001c9,0x000001c9,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000007, + 0x00000aeb,0x00000007,0x0004003b,0x00000007,0x00000aec,0x00000007,0x0004003b,0x00000007, + 0x00000aed,0x00000007,0x0004003b,0x00000042,0x00000ad9,0x00000007,0x0004003b,0x0000000d, + 0x00000ada,0x00000007,0x0004003b,0x00000007,0x00000adb,0x00000007,0x0004003b,0x00000007, + 0x00000adc,0x00000007,0x0004003b,0x00000042,0x00000add,0x00000007,0x0004003b,0x00000042, + 0x00000acf,0x00000007,0x0004003b,0x00000042,0x00000ad0,0x00000007,0x0004003b,0x00000007, + 0x00000acc,0x00000007,0x0004003b,0x0000000d,0x00000ac4,0x00000007,0x0004003b,0x0000000d, + 0x00000ac5,0x00000007,0x0004003b,0x00000007,0x00000abd,0x00000007,0x0004003b,0x0000000d, + 0x00000ab4,0x00000007,0x0004003b,0x00000007,0x00000ab5,0x00000007,0x0004003b,0x00000007, + 0x00000aad,0x00000007,0x0004003b,0x0000000d,0x00000aa4,0x00000007,0x0004003b,0x00000007, + 0x00000aa5,0x00000007,0x0004003b,0x0000000d,0x00000a9c,0x00000007,0x0004003b,0x0000000d, + 0x00000a9d,0x00000007,0x0004003b,0x0000000d,0x00000a94,0x00000007,0x0004003b,0x0000000d, + 0x00000a95,0x00000007,0x0004003b,0x00000042,0x00000a8a,0x00000007,0x0004003b,0x00000042, + 0x00000a8b,0x00000007,0x0004003b,0x00000007,0x00000a82,0x00000007,0x0004003b,0x00000007, + 0x00000a83,0x00000007,0x0004003b,0x00000007,0x00000a84,0x00000007,0x0004003b,0x00000007, + 0x00000a85,0x00000007,0x0004003b,0x00000042,0x00000a78,0x00000007,0x0004003b,0x00000042, + 0x00000a79,0x00000007,0x0004003b,0x00000007,0x00000a70,0x00000007,0x0004003b,0x00000007, + 0x00000a71,0x00000007,0x0004003b,0x00000007,0x00000a72,0x00000007,0x0004003b,0x00000007, + 0x00000a73,0x00000007,0x0004003b,0x00000007,0x00000a3f,0x00000007,0x0004003b,0x00000042, + 0x00000a40,0x00000007,0x0004003b,0x00000042,0x00000a41,0x00000007,0x0004003b,0x00000042, + 0x00000a42,0x00000007,0x0004003b,0x0000000d,0x00000a43,0x00000007,0x0004003b,0x00000007, + 0x00000a44,0x00000007,0x0004003b,0x00000007,0x00000a45,0x00000007,0x0004003b,0x00000007, + 0x00000a46,0x00000007,0x0004003b,0x00000042,0x00000a47,0x00000007,0x0004003b,0x00000042, + 0x00000a48,0x00000007,0x0004003b,0x00000007,0x00000a49,0x00000007,0x0004003b,0x00000007, + 0x00000a4a,0x00000007,0x0004003b,0x00000007,0x00000a4b,0x00000007,0x0004003b,0x00000007, + 0x00000a4c,0x00000007,0x0004003b,0x00000042,0x00000a4d,0x00000007,0x0004003b,0x00000042, + 0x00000a35,0x00000007,0x0004003b,0x00000042,0x00000a36,0x00000007,0x0004003b,0x00000042, + 0x00000a2b,0x00000007,0x0004003b,0x00000042,0x00000a2c,0x00000007,0x0004003b,0x00000007, + 0x00000a28,0x00000007,0x0004003b,0x0000000d,0x00000a20,0x00000007,0x0004003b,0x0000000d, + 0x00000a21,0x00000007,0x0004003b,0x00000007,0x00000a19,0x00000007,0x0004003b,0x0000000d, + 0x00000a10,0x00000007,0x0004003b,0x00000007,0x00000a11,0x00000007,0x0004003b,0x00000007, + 0x00000a09,0x00000007,0x0004003b,0x0000000d,0x00000a00,0x00000007,0x0004003b,0x00000007, + 0x00000a01,0x00000007,0x0004003b,0x0000000d,0x000009f8,0x00000007,0x0004003b,0x0000000d, + 0x000009f9,0x00000007,0x0004003b,0x0000000d,0x000009f0,0x00000007,0x0004003b,0x0000000d, + 0x000009f1,0x00000007,0x0004003b,0x00000042,0x000009e6,0x00000007,0x0004003b,0x00000042, + 0x000009e7,0x00000007,0x0004003b,0x00000007,0x000009de,0x00000007,0x0004003b,0x00000007, + 0x000009df,0x00000007,0x0004003b,0x00000007,0x000009e0,0x00000007,0x0004003b,0x00000007, + 0x000009e1,0x00000007,0x0004003b,0x00000042,0x000009d4,0x00000007,0x0004003b,0x00000042, + 0x000009d5,0x00000007,0x0004003b,0x00000007,0x000009cc,0x00000007,0x0004003b,0x00000007, + 0x000009cd,0x00000007,0x0004003b,0x00000007,0x000009ce,0x00000007,0x0004003b,0x00000007, + 0x000009cf,0x00000007,0x0004003b,0x00000007,0x0000099b,0x00000007,0x0004003b,0x00000042, + 0x0000099c,0x00000007,0x0004003b,0x00000042,0x0000099d,0x00000007,0x0004003b,0x00000042, + 0x0000099e,0x00000007,0x0004003b,0x0000000d,0x0000099f,0x00000007,0x0004003b,0x00000007, + 0x000009a0,0x00000007,0x0004003b,0x00000007,0x000009a1,0x00000007,0x0004003b,0x00000007, + 0x000009a2,0x00000007,0x0004003b,0x00000042,0x000009a3,0x00000007,0x0004003b,0x00000042, + 0x000009a4,0x00000007,0x0004003b,0x00000007,0x000009a5,0x00000007,0x0004003b,0x00000007, + 0x000009a6,0x00000007,0x0004003b,0x00000007,0x000009a7,0x00000007,0x0004003b,0x00000007, + 0x000009a8,0x00000007,0x0004003b,0x00000042,0x000009a9,0x00000007,0x0004003b,0x00000042, + 0x00000991,0x00000007,0x0004003b,0x00000042,0x00000992,0x00000007,0x0004003b,0x00000042, + 0x00000987,0x00000007,0x0004003b,0x00000042,0x00000988,0x00000007,0x0004003b,0x00000007, + 0x00000984,0x00000007,0x0004003b,0x0000000d,0x0000097c,0x00000007,0x0004003b,0x0000000d, + 0x0000097d,0x00000007,0x0004003b,0x00000007,0x00000975,0x00000007,0x0004003b,0x0000000d, + 0x0000096c,0x00000007,0x0004003b,0x00000007,0x0000096d,0x00000007,0x0004003b,0x00000007, + 0x00000965,0x00000007,0x0004003b,0x0000000d,0x0000095c,0x00000007,0x0004003b,0x00000007, + 0x0000095d,0x00000007,0x0004003b,0x0000000d,0x00000954,0x00000007,0x0004003b,0x0000000d, + 0x00000955,0x00000007,0x0004003b,0x0000000d,0x0000094c,0x00000007,0x0004003b,0x0000000d, + 0x0000094d,0x00000007,0x0004003b,0x00000042,0x00000942,0x00000007,0x0004003b,0x00000042, + 0x00000943,0x00000007,0x0004003b,0x00000007,0x0000093a,0x00000007,0x0004003b,0x00000007, + 0x0000093b,0x00000007,0x0004003b,0x00000007,0x0000093c,0x00000007,0x0004003b,0x00000007, + 0x0000093d,0x00000007,0x0004003b,0x00000042,0x00000930,0x00000007,0x0004003b,0x00000042, + 0x00000931,0x00000007,0x0004003b,0x00000007,0x00000928,0x00000007,0x0004003b,0x00000007, + 0x00000929,0x00000007,0x0004003b,0x00000007,0x0000092a,0x00000007,0x0004003b,0x00000007, + 0x0000092b,0x00000007,0x0004003b,0x00000007,0x000008f7,0x00000007,0x0004003b,0x00000042, + 0x000008f8,0x00000007,0x0004003b,0x00000042,0x000008f9,0x00000007,0x0004003b,0x00000042, + 0x000008fa,0x00000007,0x0004003b,0x0000000d,0x000008fb,0x00000007,0x0004003b,0x00000007, + 0x000008fc,0x00000007,0x0004003b,0x00000007,0x000008fd,0x00000007,0x0004003b,0x00000007, + 0x000008fe,0x00000007,0x0004003b,0x00000042,0x000008ff,0x00000007,0x0004003b,0x00000042, + 0x00000900,0x00000007,0x0004003b,0x00000007,0x00000901,0x00000007,0x0004003b,0x00000007, + 0x00000902,0x00000007,0x0004003b,0x00000007,0x00000903,0x00000007,0x0004003b,0x00000007, + 0x00000904,0x00000007,0x0004003b,0x00000042,0x00000905,0x00000007,0x0004003b,0x00000007, + 0x000008f0,0x00000007,0x0004003b,0x0000000d,0x000008e7,0x00000007,0x0004003b,0x00000007, + 0x000008e8,0x00000007,0x0004003b,0x00000007,0x000008e0,0x00000007,0x0004003b,0x0000000d, + 0x000008d7,0x00000007,0x0004003b,0x00000007,0x000008d8,0x00000007,0x0004003b,0x00000007, + 0x000008d0,0x00000007,0x0004003b,0x0000000d,0x000008c7,0x00000007,0x0004003b,0x00000007, + 0x000008c8,0x00000007,0x0004003b,0x00000007,0x000008c0,0x00000007,0x0004003b,0x0000000d, + 0x000008b7,0x00000007,0x0004003b,0x00000007,0x000008b8,0x00000007,0x0004003b,0x00000007, + 0x00000897,0x00000007,0x0004003b,0x00000042,0x00000898,0x00000007,0x0004003b,0x00000042, + 0x00000899,0x00000007,0x0004003b,0x00000042,0x0000089a,0x00000007,0x0004003b,0x00000007, + 0x0000089b,0x00000007,0x0004003b,0x00000042,0x0000089c,0x00000007,0x0004003b,0x00000007, + 0x0000089d,0x00000007,0x0004003b,0x00000042,0x0000089e,0x00000007,0x0004003b,0x00000042, + 0x0000089f,0x00000007,0x0004003b,0x00000042,0x000008a0,0x00000007,0x0004003b,0x00000042, + 0x0000088d,0x00000007,0x0004003b,0x00000042,0x0000088e,0x00000007,0x0004003b,0x00000042, + 0x00000883,0x00000007,0x0004003b,0x00000042,0x00000884,0x00000007,0x0004003b,0x00000007, + 0x00000880,0x00000007,0x0004003b,0x0000000d,0x00000878,0x00000007,0x0004003b,0x0000000d, + 0x00000879,0x00000007,0x0004003b,0x00000007,0x00000871,0x00000007,0x0004003b,0x0000000d, + 0x00000868,0x00000007,0x0004003b,0x00000007,0x00000869,0x00000007,0x0004003b,0x00000007, + 0x00000861,0x00000007,0x0004003b,0x0000000d,0x00000858,0x00000007,0x0004003b,0x00000007, + 0x00000859,0x00000007,0x0004003b,0x0000000d,0x00000850,0x00000007,0x0004003b,0x0000000d, + 0x00000851,0x00000007,0x0004003b,0x0000000d,0x00000848,0x00000007,0x0004003b,0x0000000d, + 0x00000849,0x00000007,0x0004003b,0x00000042,0x0000083e,0x00000007,0x0004003b,0x00000042, + 0x0000083f,0x00000007,0x0004003b,0x00000007,0x00000836,0x00000007,0x0004003b,0x00000007, + 0x00000837,0x00000007,0x0004003b,0x00000007,0x00000838,0x00000007,0x0004003b,0x00000007, + 0x00000839,0x00000007,0x0004003b,0x00000042,0x0000082c,0x00000007,0x0004003b,0x00000042, + 0x0000082d,0x00000007,0x0004003b,0x00000007,0x00000824,0x00000007,0x0004003b,0x00000007, + 0x00000825,0x00000007,0x0004003b,0x00000007,0x00000826,0x00000007,0x0004003b,0x00000007, + 0x00000827,0x00000007,0x0004003b,0x00000007,0x000007f3,0x00000007,0x0004003b,0x00000042, + 0x000007f4,0x00000007,0x0004003b,0x00000042,0x000007f5,0x00000007,0x0004003b,0x00000042, + 0x000007f6,0x00000007,0x0004003b,0x0000000d,0x000007f7,0x00000007,0x0004003b,0x00000007, + 0x000007f8,0x00000007,0x0004003b,0x00000007,0x000007f9,0x00000007,0x0004003b,0x00000007, + 0x000007fa,0x00000007,0x0004003b,0x00000042,0x000007fb,0x00000007,0x0004003b,0x00000042, + 0x000007fc,0x00000007,0x0004003b,0x00000007,0x000007fd,0x00000007,0x0004003b,0x00000007, + 0x000007fe,0x00000007,0x0004003b,0x00000007,0x000007ff,0x00000007,0x0004003b,0x00000007, + 0x00000800,0x00000007,0x0004003b,0x00000042,0x00000801,0x00000007,0x0004003b,0x00000007, + 0x000007ec,0x00000007,0x0004003b,0x0000000d,0x000007e3,0x00000007,0x0004003b,0x00000007, + 0x000007e4,0x00000007,0x0004003b,0x00000007,0x000007dc,0x00000007,0x0004003b,0x0000000d, + 0x000007d3,0x00000007,0x0004003b,0x00000007,0x000007d4,0x00000007,0x0004003b,0x00000007, + 0x000007cc,0x00000007,0x0004003b,0x0000000d,0x000007c3,0x00000007,0x0004003b,0x00000007, + 0x000007c4,0x00000007,0x0004003b,0x00000007,0x000007bc,0x00000007,0x0004003b,0x0000000d, + 0x000007b3,0x00000007,0x0004003b,0x00000007,0x000007b4,0x00000007,0x0004003b,0x00000007, + 0x00000793,0x00000007,0x0004003b,0x00000042,0x00000794,0x00000007,0x0004003b,0x00000042, + 0x00000795,0x00000007,0x0004003b,0x00000042,0x00000796,0x00000007,0x0004003b,0x00000007, + 0x00000797,0x00000007,0x0004003b,0x00000042,0x00000798,0x00000007,0x0004003b,0x00000007, + 0x00000799,0x00000007,0x0004003b,0x00000042,0x0000079a,0x00000007,0x0004003b,0x00000042, + 0x0000079b,0x00000007,0x0004003b,0x00000042,0x0000079c,0x00000007,0x0004003b,0x00000042, + 0x00000789,0x00000007,0x0004003b,0x00000042,0x0000078a,0x00000007,0x0004003b,0x00000042, + 0x0000077f,0x00000007,0x0004003b,0x00000042,0x00000780,0x00000007,0x0004003b,0x00000042, + 0x00000775,0x00000007,0x0004003b,0x00000042,0x00000776,0x00000007,0x0004003b,0x00000042, + 0x0000076b,0x00000007,0x0004003b,0x00000042,0x0000076c,0x00000007,0x0004003b,0x00000042, + 0x00000761,0x00000007,0x0004003b,0x00000042,0x00000762,0x00000007,0x0004003b,0x00000042, + 0x00000757,0x00000007,0x0004003b,0x00000042,0x00000758,0x00000007,0x0004003b,0x00000042, + 0x0000074d,0x00000007,0x0004003b,0x00000042,0x0000074e,0x00000007,0x0004003b,0x00000042, + 0x00000743,0x00000007,0x0004003b,0x00000042,0x00000744,0x00000007,0x0004003b,0x00000042, + 0x00000739,0x00000007,0x0004003b,0x00000042,0x0000073a,0x00000007,0x0004003b,0x00000042, + 0x0000072f,0x00000007,0x0004003b,0x00000042,0x00000730,0x00000007,0x0004003b,0x00000042, + 0x00000725,0x00000007,0x0004003b,0x00000042,0x00000726,0x00000007,0x0004003b,0x00000042, + 0x0000071b,0x00000007,0x0004003b,0x00000042,0x0000071c,0x00000007,0x0004003b,0x00000042, + 0x00000711,0x00000007,0x0004003b,0x00000042,0x00000712,0x00000007,0x0004003b,0x00000042, + 0x00000707,0x00000007,0x0004003b,0x00000042,0x00000708,0x00000007,0x0004003b,0x00000007, + 0x000006f7,0x00000007,0x0004003b,0x00000042,0x000006f8,0x00000007,0x0004003b,0x00000042, + 0x000005d6,0x00000007,0x0004003b,0x00000034,0x000005d7,0x00000007,0x0004003b,0x00000042, + 0x000005d8,0x00000007,0x0004003b,0x00000042,0x000005d9,0x00000007,0x0004003b,0x00000007, + 0x000005da,0x00000007,0x0004003b,0x00000007,0x000005db,0x00000007,0x0004003b,0x00000042, + 0x000005dc,0x00000007,0x0004003b,0x00000007,0x000005dd,0x00000007,0x0004003b,0x00000007, + 0x000005de,0x00000007,0x0004003b,0x00000007,0x000005df,0x00000007,0x0004003b,0x00000007, + 0x000005e0,0x00000007,0x0004003b,0x00000007,0x000005e1,0x00000007,0x0004003b,0x00000007, + 0x000005e2,0x00000007,0x0004003b,0x00000007,0x000005e3,0x00000007,0x0004003b,0x00000042, + 0x000005e4,0x00000007,0x0004003b,0x00000007,0x000005e5,0x00000007,0x0004003b,0x00000007, + 0x000005e6,0x00000007,0x0004003b,0x00000042,0x000005e7,0x00000007,0x0004003b,0x00000007, + 0x000005e8,0x00000007,0x0004003b,0x0000024b,0x000005e9,0x00000007,0x0004003b,0x00000007, + 0x000005ea,0x00000007,0x0004003b,0x00000007,0x000005eb,0x00000007,0x0004003b,0x00000042, + 0x000005ec,0x00000007,0x0004003b,0x00000042,0x000005ed,0x00000007,0x0004003b,0x00000042, + 0x000005ee,0x00000007,0x0004003b,0x00000007,0x000005ef,0x00000007,0x0004003b,0x00000007, + 0x000005f0,0x00000007,0x0004003b,0x00000042,0x000005f1,0x00000007,0x0004003b,0x00000042, + 0x000005f2,0x00000007,0x0004003b,0x00000042,0x000005f3,0x00000007,0x0004003b,0x00000007, + 0x000005f4,0x00000007,0x0004003b,0x00000007,0x000005f5,0x00000007,0x0004003b,0x00000042, + 0x000005f6,0x00000007,0x0004003b,0x00000042,0x000005f7,0x00000007,0x0004003b,0x00000007, + 0x000005f8,0x00000007,0x0004003b,0x00000007,0x000005f9,0x00000007,0x0004003b,0x00000042, + 0x000005fa,0x00000007,0x0004003b,0x00000042,0x000005fb,0x00000007,0x0004003b,0x00000042, + 0x000005fc,0x00000007,0x0004003b,0x00000042,0x000005c5,0x00000007,0x0004003b,0x00000042, + 0x000005c6,0x00000007,0x0004003b,0x00000034,0x000005c7,0x00000007,0x0004003b,0x00000013, + 0x000005c8,0x00000007,0x0004003b,0x00000007,0x000005c9,0x00000007,0x0004003b,0x00000042, + 0x000005ca,0x00000007,0x0004003b,0x00000013,0x000005c0,0x00000007,0x0004003b,0x00000013, + 0x000005c1,0x00000007,0x0004003b,0x00000363,0x000005b3,0x00000007,0x0004003b,0x00000034, + 0x000005a7,0x00000007,0x0004003b,0x00000034,0x000005a8,0x00000007,0x0004003b,0x0000000d, + 0x000005a2,0x00000007,0x0004003b,0x0000000d,0x000005a3,0x00000007,0x0004003b,0x00000363, + 0x00000595,0x00000007,0x0004003b,0x0000000d,0x0000058d,0x00000007,0x0004003b,0x0000000d, + 0x0000058e,0x00000007,0x0004003b,0x00000007,0x0000057a,0x00000007,0x0004003b,0x00000007, + 0x00000577,0x00000007,0x0004003b,0x00000007,0x00000574,0x00000007,0x0004003b,0x00000311, + 0x0000048a,0x00000007,0x0004003b,0x00000007,0x0000048b,0x00000007,0x0004003b,0x00000007, + 0x0000048c,0x00000007,0x0004003b,0x00000007,0x0000048d,0x00000007,0x0004003b,0x00000013, + 0x0000048e,0x00000007,0x0004003b,0x00000013,0x0000048f,0x00000007,0x0004003b,0x00000034, + 0x00000490,0x00000007,0x0004003b,0x00000007,0x00000491,0x00000007,0x0004003b,0x00000363, + 0x00000492,0x00000007,0x0004003b,0x00000034,0x00000493,0x00000007,0x0004003b,0x00000034, + 0x00000494,0x00000007,0x0004003b,0x0000000d,0x00000495,0x00000007,0x0004003b,0x0000000d, + 0x00000496,0x00000007,0x0004003b,0x0000000d,0x00000497,0x00000007,0x0004003b,0x00000007, + 0x00000498,0x00000007,0x0004003b,0x00000013,0x00000499,0x00000007,0x0004003b,0x00000007, + 0x0000049a,0x00000007,0x0004003b,0x00000363,0x0000049b,0x00000007,0x0004003b,0x00000034, + 0x0000049c,0x00000007,0x0004003b,0x00000034,0x0000049d,0x00000007,0x0004003b,0x0000000d, + 0x0000049e,0x00000007,0x0004003b,0x00000007,0x0000049f,0x00000007,0x0004003b,0x00000007, + 0x000004a0,0x00000007,0x0004003b,0x00000007,0x000004a1,0x00000007,0x0004003b,0x00000007, + 0x000004a2,0x00000007,0x0004003b,0x00000013,0x000004a3,0x00000007,0x0004003b,0x00000013, + 0x000004a4,0x00000007,0x0004003b,0x00000034,0x000004a5,0x00000007,0x0004003b,0x00000042, + 0x000004a6,0x00000007,0x0004003b,0x00000034,0x000004a7,0x00000007,0x0004003b,0x00000013, + 0x000004a8,0x00000007,0x0004003b,0x00000013,0x00000487,0x00000007,0x0004003b,0x00000013, + 0x00000482,0x00000007,0x0004003b,0x00000013,0x00000483,0x00000007,0x0004003b,0x00000007, + 0x0000047d,0x00000007,0x0004003b,0x00000007,0x0000047e,0x00000007,0x0004003b,0x00000007, + 0x00000475,0x00000007,0x0004003b,0x00000007,0x00000476,0x00000007,0x0004003b,0x00000082, + 0x00000423,0x00000007,0x0004003b,0x00000013,0x00000428,0x00000007,0x0004003b,0x00000007, + 0x00000431,0x00000007,0x0004003b,0x00000013,0x00000435,0x00000007,0x0004003b,0x00000013, + 0x00000437,0x00000007,0x0004003b,0x00000013,0x0000043b,0x00000007,0x0004003b,0x00000013, + 0x0000043d,0x00000007,0x0004003b,0x00000034,0x00000440,0x00000007,0x0004003b,0x00000013, + 0x00000441,0x00000007,0x0004003b,0x00000007,0x00000443,0x00000007,0x0004003b,0x00000034, + 0x00000445,0x00000007,0x0004003b,0x00000042,0x00000450,0x00000007,0x0004003b,0x0000000d, + 0x00000453,0x00000007,0x0004003b,0x00000007,0x00000456,0x00000007,0x0004003b,0x00000007, + 0x0000045a,0x00000007,0x0004003b,0x00000034,0x00000464,0x00000007,0x0004003d,0x0000002f, + 0x00000424,0x0000037b,0x0007004f,0x0000000c,0x00000425,0x00000424,0x00000424,0x00000000, + 0x00000001,0x0006000c,0x0000000c,0x00000426,0x00000001,0x00000008,0x00000425,0x0004006e, + 0x00000081,0x00000427,0x00000426,0x0003003e,0x00000423,0x00000427,0x0004003d,0x00000429, + 0x0000042c,0x0000042b,0x0004003d,0x00000081,0x0000042d,0x00000423,0x00050062,0x0000042e, + 0x0000042f,0x0000042c,0x0000042d,0x00050051,0x00000012,0x00000430,0x0000042f,0x00000000, + 0x0003003e,0x00000428,0x00000430,0x0004003d,0x00000012,0x00000432,0x00000428,0x000500c7, + 0x00000012,0x00000434,0x00000432,0x00000433,0x0003003e,0x00000435,0x00000434,0x0004003d, + 0x00000012,0x00000478,0x00000435,0x00040070,0x00000006,0x00000479,0x00000478,0x00050085, + 0x00000006,0x0000047a,0x00000479,0x000002f1,0x00050081,0x00000006,0x0000047b,0x0000047a, + 0x000002f3,0x0003003e,0x00000475,0x0000047b,0x0004003d,0x00000006,0x00000480,0x00000475, + 0x0003003e,0x0000047d,0x00000480,0x0004003d,0x00000006,0x00000481,0x0000047d,0x0003003e, + 0x0000047e,0x00000481,0x0004003d,0x00000006,0x0000047c,0x0000047e,0x0003003e,0x00000476, + 0x0000047c,0x0004003d,0x00000006,0x00000436,0x00000476,0x0003003e,0x00000431,0x00000436, + 0x0004003d,0x00000012,0x00000438,0x00000428,0x000500c2,0x00000012,0x0000043a,0x00000438, + 0x00000439,0x0003003e,0x0000043b,0x0000043a,0x0004003d,0x00000012,0x00000485,0x0000043b, + 0x0003003e,0x00000482,0x00000485,0x0004003d,0x00000012,0x00000486,0x00000482,0x0003003e, + 0x00000483,0x00000486,0x0004003d,0x00000012,0x0000043c,0x00000483,0x0003003e,0x00000437, + 0x0000043c,0x0004003d,0x00000012,0x0000043e,0x00000437,0x0003003e,0x0000043d,0x0000043e, + 0x0004003d,0x00000012,0x00000489,0x0000043d,0x0003003e,0x00000487,0x00000489,0x0004003d, + 0x00000012,0x0000043f,0x00000487,0x0003003e,0x00000437,0x0000043f,0x0004003d,0x00000012, + 0x00000442,0x00000437,0x0003003e,0x00000441,0x00000442,0x0004003d,0x00000006,0x00000444, + 0x00000431,0x0003003e,0x00000443,0x00000444,0x0004003d,0x00000012,0x000004aa,0x00000441, + 0x00060041,0x00000318,0x000004ab,0x00000316,0x0000024d,0x000004aa,0x0004003d,0x00000310, + 0x000004ac,0x000004ab,0x0003003e,0x0000048a,0x000004ac,0x0004003d,0x00000006,0x000004ad, + 0x00000443,0x0003003e,0x0000048b,0x000004ad,0x00050041,0x00000013,0x000004ae,0x0000048a, + 0x000000a3,0x0004003d,0x00000012,0x000004af,0x000004ae,0x000500c7,0x00000012,0x000004b0, + 0x000004af,0x0000031f,0x000500ab,0x000000e8,0x000004b1,0x000004b0,0x000000a3,0x000300f7, + 0x000004c5,0x00000000,0x000400fa,0x000004b1,0x000004b2,0x000004c5,0x000200f8,0x000004b2, + 0x0004003d,0x00000006,0x000004b3,0x0000048b,0x0006000c,0x00000006,0x000004b4,0x00000001, + 0x00000004,0x000004b3,0x0003003e,0x0000048b,0x000004b4,0x000300f7,0x000004ba,0x00000000, + 0x000400fa,0x00000326,0x000004b5,0x000004ba,0x000200f8,0x000004b5,0x0004003d,0x00000012, + 0x000004b7,0x000004ae,0x000500c7,0x00000012,0x000004b8,0x000004b7,0x0000032b,0x000500ab, + 0x000000e8,0x000004b9,0x000004b8,0x000000a3,0x000200f9,0x000004ba,0x000200f8,0x000004ba, + 0x000700f5,0x000000e8,0x000004bb,0x00000326,0x000004b2,0x000004b9,0x000004b5,0x000300f7, + 0x000004c4,0x00000000,0x000400fa,0x000004bb,0x000004bc,0x000004c4,0x000200f8,0x000004bc, + 0x0004003d,0x00000006,0x000004bd,0x0000048b,0x00050085,0x00000006,0x000004be,0x000004bd, + 0x000001c9,0x0006000c,0x00000006,0x000004bf,0x00000001,0x0000000a,0x000004be,0x00050085, + 0x00000006,0x000004c0,0x000004bf,0x000001c2,0x00050081,0x00000006,0x000004c1,0x000004c0, + 0x00000335,0x0006000c,0x00000006,0x000004c2,0x00000001,0x00000004,0x000004c1,0x00050083, + 0x00000006,0x000004c3,0x000000d9,0x000004c2,0x0003003e,0x0000048b,0x000004c3,0x000200f9, + 0x000004c4,0x000200f8,0x000004c4,0x000200f9,0x000004c5,0x000200f8,0x000004c5,0x0004003d, + 0x00000006,0x000004c6,0x0000048b,0x0003003e,0x0000048c,0x000000da,0x0004003d,0x00000006, + 0x00000576,0x0000048c,0x0003003e,0x00000574,0x00000576,0x0004003d,0x00000006,0x000004c7, + 0x00000574,0x0003003e,0x0000048d,0x000000d9,0x0004003d,0x00000006,0x00000579,0x0000048d, + 0x0003003e,0x00000577,0x00000579,0x0004003d,0x00000006,0x000004c8,0x00000577,0x0008000c, + 0x00000006,0x000004c9,0x00000001,0x0000002b,0x000004c6,0x000004c7,0x000004c8,0x0003003e, + 0x0000048b,0x000004c9,0x000300f7,0x000004d8,0x00000000,0x000400fa,0x0000033f,0x000004ca, + 0x000004d8,0x000200f8,0x000004ca,0x0004003d,0x00000012,0x000004cc,0x000004ae,0x000500c2, + 0x00000012,0x000004cd,0x000004cc,0x00000345,0x0003003e,0x0000048e,0x000004cd,0x0004003d, + 0x00000012,0x000004ce,0x0000048e,0x000500ab,0x000000e8,0x000004cf,0x000004ce,0x000000a3, + 0x000300f7,0x000004d7,0x00000000,0x000400fa,0x000004cf,0x000004d0,0x000004d7,0x000200f8, + 0x000004d0,0x0004003d,0x0000034b,0x000004d1,0x0000034d,0x00050062,0x0000002f,0x000004d2, + 0x000004d1,0x0000034f,0x0004003d,0x00000012,0x000004d3,0x0000048e,0x0003003e,0x0000048f, + 0x000004d3,0x0003003e,0x00000490,0x000004d2,0x0004003d,0x00000006,0x000004d4,0x0000048b, + 0x0003003e,0x00000491,0x000004d4,0x0004003d,0x0000002f,0x0000057c,0x00000490,0x0007004f, + 0x0000000c,0x0000057d,0x0000057c,0x0000057c,0x00000000,0x00000001,0x0004003d,0x00000012, + 0x0000057e,0x0000048f,0x0006000c,0x0000002f,0x0000057f,0x00000001,0x00000040,0x0000057e, + 0x0007004f,0x0000000c,0x00000580,0x0000057f,0x0000057f,0x00000000,0x00000001,0x00050083, + 0x0000000c,0x00000581,0x0000057d,0x00000580,0x0006000c,0x0000000c,0x00000582,0x00000001, + 0x00000004,0x00000581,0x0003003e,0x0000057a,0x00000303,0x0004003d,0x00000006,0x00000590, + 0x0000057a,0x00050041,0x00000007,0x00000591,0x0000058d,0x000000a3,0x0003003e,0x00000591, + 0x00000590,0x0004003d,0x00000006,0x00000592,0x0000057a,0x00050041,0x00000007,0x00000593, + 0x0000058d,0x000000a6,0x0003003e,0x00000593,0x00000592,0x0004003d,0x0000000c,0x00000594, + 0x0000058d,0x0003003e,0x0000058e,0x00000594,0x0004003d,0x0000000c,0x00000583,0x0000058e, + 0x000500b8,0x00000306,0x00000584,0x00000582,0x00000583,0x0004009b,0x000000e8,0x00000585, + 0x00000584,0x000300f7,0x0000058c,0x00000000,0x000400fa,0x00000585,0x00000586,0x0000058b, + 0x000200f8,0x00000586,0x0004003d,0x00000006,0x00000587,0x00000491,0x00050041,0x00000007, + 0x00000588,0x00000490,0x000000b9,0x0004003d,0x00000006,0x00000589,0x00000588,0x0007000c, + 0x00000006,0x0000058a,0x00000001,0x00000025,0x00000587,0x00000589,0x0003003e,0x00000491, + 0x0000058a,0x000200f9,0x0000058c,0x000200f8,0x0000058b,0x0003003e,0x00000491,0x000000da, + 0x000200f9,0x0000058c,0x000200f8,0x0000058c,0x0004003d,0x00000006,0x000004d6,0x00000491, + 0x0003003e,0x0000048b,0x000004d6,0x000200f9,0x000004d7,0x000200f8,0x000004d7,0x000200f9, + 0x000004d8,0x000200f8,0x000004d8,0x000300f7,0x000004de,0x00000000,0x000400fa,0x00000358, + 0x000004d9,0x000004de,0x000200f8,0x000004d9,0x0004003d,0x00000012,0x000004db,0x000004ae, + 0x000500c7,0x00000012,0x000004dc,0x000004db,0x0000035d,0x000500ab,0x000000e8,0x000004dd, + 0x000004dc,0x000000a3,0x000200f9,0x000004de,0x000200f8,0x000004de,0x000700f5,0x000000e8, + 0x000004df,0x00000358,0x000004d8,0x000004dd,0x000004d9,0x000300f7,0x00000506,0x00000000, + 0x000400fa,0x000004df,0x000004e0,0x00000506,0x000200f8,0x000004e0,0x0004003d,0x00000012, + 0x000004e1,0x00000441,0x00050084,0x00000012,0x000004e2,0x000004e1,0x0000036a,0x00050080, + 0x00000012,0x000004e3,0x000004e2,0x000000b9,0x00060041,0x0000036e,0x000004e4,0x00000368, + 0x0000024d,0x000004e3,0x0004003d,0x0000002f,0x000004e5,0x000004e4,0x0003003e,0x00000493, + 0x000004e5,0x0004003d,0x0000002f,0x00000597,0x00000493,0x0004003d,0x0000002f,0x00000599, + 0x00000493,0x00050051,0x00000006,0x0000059b,0x00000597,0x00000000,0x00050051,0x00000006, + 0x0000059c,0x00000597,0x00000001,0x00050051,0x00000006,0x0000059d,0x00000599,0x00000002, + 0x00050051,0x00000006,0x0000059e,0x00000599,0x00000003,0x00050050,0x0000000c,0x0000059f, + 0x0000059b,0x0000059c,0x00050050,0x0000000c,0x000005a0,0x0000059d,0x0000059e,0x00050050, + 0x00000035,0x000005a1,0x0000059f,0x000005a0,0x0003003e,0x00000595,0x000005a1,0x0004003d, + 0x00000035,0x000004e6,0x00000595,0x0003003e,0x00000492,0x000004e6,0x0004003d,0x00000012, + 0x000004e7,0x00000441,0x00050084,0x00000012,0x000004e8,0x000004e7,0x0000036a,0x00050080, + 0x00000012,0x000004e9,0x000004e8,0x000000d0,0x00060041,0x0000036e,0x000004ea,0x00000368, + 0x0000024d,0x000004e9,0x0004003d,0x0000002f,0x000004eb,0x000004ea,0x0003003e,0x00000494, + 0x000004eb,0x0004003d,0x00000035,0x000004ec,0x00000492,0x00050091,0x0000000c,0x000004ef, + 0x000004ec,0x00000425,0x0004003d,0x0000002f,0x000004f0,0x00000494,0x0007004f,0x0000000c, + 0x000004f1,0x000004f0,0x000004f0,0x00000000,0x00000001,0x00050081,0x0000000c,0x000004f2, + 0x000004ef,0x000004f1,0x0003003e,0x00000495,0x000004f2,0x0004003d,0x0000000c,0x000004f3, + 0x00000495,0x0006000c,0x0000000c,0x000004f4,0x00000001,0x00000004,0x000004f3,0x0004003d, + 0x0000002f,0x000004f5,0x00000494,0x0007004f,0x0000000c,0x000004f6,0x000004f5,0x000004f5, + 0x00000002,0x00000003,0x00050085,0x0000000c,0x000004f7,0x000004f4,0x000004f6,0x0004003d, + 0x0000002f,0x000004f8,0x00000494,0x0007004f,0x0000000c,0x000004f9,0x000004f8,0x000004f8, + 0x00000002,0x00000003,0x00050083,0x0000000c,0x000004fa,0x000004f7,0x000004f9,0x0003003e, + 0x00000497,0x000004fa,0x0004003d,0x0000000c,0x000005a5,0x00000497,0x0003003e,0x000005a2, + 0x000005a5,0x0004003d,0x0000000c,0x000005a6,0x000005a2,0x0003003e,0x000005a3,0x000005a6, + 0x0004003d,0x0000000c,0x000004fb,0x000005a3,0x0003003e,0x00000496,0x000004fb,0x00050041, + 0x00000007,0x000004fc,0x00000496,0x000000a3,0x0004003d,0x00000006,0x000004fd,0x000004fc, + 0x00050041,0x00000007,0x000004fe,0x00000496,0x000000a6,0x0004003d,0x00000006,0x000004ff, + 0x000004fe,0x0007000c,0x00000006,0x00000500,0x00000001,0x00000025,0x000004fd,0x000004ff, + 0x00050081,0x00000006,0x00000501,0x00000500,0x000001c9,0x0008000c,0x00000006,0x00000502, + 0x00000001,0x0000002b,0x00000501,0x000000da,0x000000d9,0x0003003e,0x00000498,0x00000502, + 0x0004003d,0x00000006,0x00000503,0x0000048b,0x0004003d,0x00000006,0x00000504,0x00000498, + 0x0007000c,0x00000006,0x00000505,0x00000001,0x00000025,0x00000503,0x00000504,0x0003003e, + 0x0000048b,0x00000505,0x000200f9,0x00000506,0x000200f8,0x00000506,0x0004003d,0x00000012, + 0x00000508,0x000004ae,0x000500c7,0x00000012,0x00000509,0x00000508,0x0000039b,0x0003003e, + 0x00000499,0x00000509,0x0004003d,0x00000012,0x0000050a,0x00000499,0x000500b2,0x000000e8, + 0x0000050b,0x0000050a,0x000000a6,0x000300f7,0x00000545,0x00000000,0x000400fa,0x0000050b, + 0x0000050c,0x00000516,0x000200f8,0x0000050c,0x00050041,0x00000013,0x0000050d,0x0000048a, + 0x000000a6,0x0004003d,0x00000012,0x0000050e,0x0000050d,0x0006000c,0x0000002f,0x0000050f, + 0x00000001,0x00000040,0x0000050e,0x0003003e,0x00000445,0x0000050f,0x0004003d,0x00000012, + 0x00000510,0x00000499,0x000500aa,0x000000e8,0x00000511,0x00000510,0x000000a3,0x000500a7, + 0x000000e8,0x00000512,0x0000033f,0x00000511,0x000300f7,0x00000515,0x00000000,0x000400fa, + 0x00000512,0x00000513,0x00000515,0x000200f8,0x00000513,0x0003003e,0x0000049a,0x000000da, + 0x0004003d,0x00000006,0x000005aa,0x0000049a,0x00050041,0x00000007,0x000005ab,0x000005a7, + 0x000000a3,0x0003003e,0x000005ab,0x000005aa,0x0004003d,0x00000006,0x000005ac,0x0000049a, + 0x00050041,0x00000007,0x000005ad,0x000005a7,0x000000a6,0x0003003e,0x000005ad,0x000005ac, + 0x0004003d,0x00000006,0x000005ae,0x0000049a,0x00050041,0x00000007,0x000005af,0x000005a7, + 0x000000b9,0x0003003e,0x000005af,0x000005ae,0x0004003d,0x00000006,0x000005b0,0x0000049a, + 0x00050041,0x00000007,0x000005b1,0x000005a7,0x000000d0,0x0003003e,0x000005b1,0x000005b0, + 0x0004003d,0x0000002f,0x000005b2,0x000005a7,0x0003003e,0x000005a8,0x000005b2,0x0004003d, + 0x0000002f,0x00000514,0x000005a8,0x0003003e,0x00000445,0x00000514,0x000200f9,0x00000515, + 0x000200f8,0x00000515,0x000200f9,0x00000545,0x000200f8,0x00000516,0x0004003d,0x00000012, + 0x00000517,0x00000441,0x00050084,0x00000012,0x00000518,0x00000517,0x0000036a,0x00060041, + 0x0000036e,0x00000519,0x00000368,0x0000024d,0x00000518,0x0004003d,0x0000002f,0x0000051a, + 0x00000519,0x0003003e,0x0000049c,0x0000051a,0x0004003d,0x0000002f,0x000005b5,0x0000049c, + 0x0004003d,0x0000002f,0x000005b7,0x0000049c,0x00050051,0x00000006,0x000005b9,0x000005b5, + 0x00000000,0x00050051,0x00000006,0x000005ba,0x000005b5,0x00000001,0x00050051,0x00000006, + 0x000005bb,0x000005b7,0x00000002,0x00050051,0x00000006,0x000005bc,0x000005b7,0x00000003, + 0x00050050,0x0000000c,0x000005bd,0x000005b9,0x000005ba,0x00050050,0x0000000c,0x000005be, + 0x000005bb,0x000005bc,0x00050050,0x00000035,0x000005bf,0x000005bd,0x000005be,0x0003003e, + 0x000005b3,0x000005bf,0x0004003d,0x00000035,0x0000051b,0x000005b3,0x0003003e,0x0000049b, + 0x0000051b,0x0004003d,0x00000012,0x0000051c,0x00000441,0x00050084,0x00000012,0x0000051d, + 0x0000051c,0x0000036a,0x00050080,0x00000012,0x0000051e,0x0000051d,0x000000a6,0x00060041, + 0x0000036e,0x0000051f,0x00000368,0x0000024d,0x0000051e,0x0004003d,0x0000002f,0x00000520, + 0x0000051f,0x0003003e,0x0000049d,0x00000520,0x0004003d,0x00000035,0x00000521,0x0000049b, + 0x00050091,0x0000000c,0x00000524,0x00000521,0x00000425,0x0004003d,0x0000002f,0x00000525, + 0x0000049d,0x0007004f,0x0000000c,0x00000526,0x00000525,0x00000525,0x00000000,0x00000001, + 0x00050081,0x0000000c,0x00000527,0x00000524,0x00000526,0x0003003e,0x0000049e,0x00000527, + 0x0004003d,0x00000012,0x00000528,0x00000499,0x000500aa,0x000000e8,0x00000529,0x00000528, + 0x000000b9,0x000300f7,0x00000530,0x00000000,0x000400fa,0x00000529,0x0000052a,0x0000052d, + 0x000200f8,0x0000052a,0x00050041,0x00000007,0x0000052b,0x0000049e,0x000000a3,0x0004003d, + 0x00000006,0x0000052c,0x0000052b,0x0003003e,0x000004a0,0x0000052c,0x000200f9,0x00000530, + 0x000200f8,0x0000052d,0x0004003d,0x0000000c,0x0000052e,0x0000049e,0x0006000c,0x00000006, + 0x0000052f,0x00000001,0x00000042,0x0000052e,0x0003003e,0x000004a0,0x0000052f,0x000200f9, + 0x00000530,0x000200f8,0x00000530,0x0004003d,0x00000006,0x00000531,0x000004a0,0x0003003e, + 0x0000049f,0x00000531,0x0004003d,0x00000006,0x00000532,0x0000049f,0x0008000c,0x00000006, + 0x00000533,0x00000001,0x0000002b,0x00000532,0x000000da,0x000000d9,0x0003003e,0x0000049f, + 0x00000533,0x0004003d,0x00000006,0x00000534,0x0000049f,0x00050041,0x00000007,0x00000535, + 0x0000049d,0x000000b9,0x0004003d,0x00000006,0x00000536,0x00000535,0x00050085,0x00000006, + 0x00000537,0x00000534,0x00000536,0x00050041,0x00000007,0x00000538,0x0000049d,0x000000d0, + 0x0004003d,0x00000006,0x00000539,0x00000538,0x00050081,0x00000006,0x0000053a,0x00000537, + 0x00000539,0x0003003e,0x000004a1,0x0000053a,0x00050041,0x00000013,0x0000053b,0x0000048a, + 0x000000a6,0x0004003d,0x00000012,0x0000053c,0x0000053b,0x0004007c,0x00000006,0x0000053d, + 0x0000053c,0x0003003e,0x000004a2,0x0000053d,0x0004003d,0x000003db,0x0000053e,0x000003dd, + 0x0004003d,0x000003df,0x0000053f,0x000003e1,0x00050056,0x000003e3,0x00000540,0x0000053e, + 0x0000053f,0x0004003d,0x00000006,0x00000541,0x000004a1,0x0004003d,0x00000006,0x00000542, + 0x000004a2,0x00050050,0x0000000c,0x00000543,0x00000541,0x00000542,0x00070058,0x0000002f, + 0x00000544,0x00000540,0x00000543,0x00000002,0x000000da,0x0003003e,0x00000445,0x00000544, + 0x000200f9,0x00000545,0x000200f8,0x00000545,0x0004003d,0x00000006,0x00000546,0x0000048b, + 0x00050041,0x00000007,0x00000547,0x00000445,0x000000d0,0x0004003d,0x00000006,0x00000548, + 0x00000547,0x00050085,0x00000006,0x00000549,0x00000548,0x00000546,0x0003003e,0x00000547, + 0x00000549,0x000300f7,0x0000054f,0x00000000,0x000400fa,0x000003ee,0x0000054b,0x0000054f, + 0x000200f8,0x0000054b,0x0004003d,0x00000006,0x0000054d,0x00000547,0x000500b7,0x000000e8, + 0x0000054e,0x0000054d,0x000000da,0x000200f9,0x0000054f,0x000200f8,0x0000054f,0x000700f5, + 0x000000e8,0x00000550,0x000003ee,0x00000545,0x0000054e,0x0000054b,0x000300f7,0x00000558, + 0x00000000,0x000400fa,0x00000550,0x00000551,0x00000558,0x000200f8,0x00000551,0x0004003d, + 0x00000012,0x00000553,0x000004ae,0x000500c2,0x00000012,0x00000554,0x00000553,0x000003fa, + 0x000500c7,0x00000012,0x00000555,0x00000554,0x0000039b,0x0003003e,0x000004a4,0x00000555, + 0x0004003d,0x00000012,0x000005c3,0x000004a4,0x0003003e,0x000005c0,0x000005c3,0x0004003d, + 0x00000012,0x000005c4,0x000005c0,0x0003003e,0x000005c1,0x000005c4,0x0004003d,0x00000012, + 0x00000556,0x000005c1,0x0003003e,0x000004a3,0x00000556,0x000500ab,0x000000e8,0x00000557, + 0x00000556,0x000000a3,0x000200f9,0x00000558,0x000200f8,0x00000558,0x000700f5,0x000000e8, + 0x00000559,0x00000550,0x0000054f,0x00000557,0x00000551,0x000300f7,0x00000568,0x00000000, + 0x000400fa,0x00000559,0x0000055a,0x00000568,0x000200f8,0x0000055a,0x0004003d,0x0000034b, + 0x0000055b,0x00000404,0x00050062,0x0000002f,0x0000055c,0x0000055b,0x0000034f,0x0003003e, + 0x000004a5,0x0000055c,0x0004003d,0x0000002f,0x0000055d,0x00000445,0x0008004f,0x00000024, + 0x0000055e,0x0000055d,0x0000055d,0x00000000,0x00000001,0x00000002,0x0003003e,0x000004a6, + 0x0000055e,0x0004003d,0x0000002f,0x0000055f,0x000004a5,0x0003003e,0x000004a7,0x0000055f, + 0x0004003d,0x00000012,0x00000560,0x000004a3,0x0003003e,0x000004a8,0x00000560,0x0004003d, + 0x00000024,0x000005cc,0x000004a6,0x0003003e,0x000005c6,0x000005cc,0x0004003d,0x0000002f, + 0x000005cd,0x000004a7,0x0003003e,0x000005c7,0x000005cd,0x0004003d,0x00000012,0x000005ce, + 0x000004a8,0x0003003e,0x000005c8,0x000005ce,0x0004003d,0x0000002f,0x000005fe,0x000005c7, + 0x0003003e,0x000005d7,0x000005fe,0x0004003d,0x0000002f,0x000006fa,0x000005d7,0x0008004f, + 0x00000024,0x000006fb,0x000006fa,0x000006fa,0x00000000,0x00000001,0x00000002,0x00050041, + 0x00000007,0x000006fc,0x000005d7,0x000000d0,0x0004003d,0x00000006,0x000006fd,0x000006fc, + 0x000500b7,0x000000e8,0x000006fe,0x000006fd,0x000000da,0x000300f7,0x00000704,0x00000000, + 0x000400fa,0x000006fe,0x000006ff,0x00000703,0x000200f8,0x000006ff,0x0004003d,0x00000006, + 0x00000701,0x000006fc,0x00050088,0x00000006,0x00000702,0x000000d9,0x00000701,0x0003003e, + 0x000006f7,0x00000702,0x000200f9,0x00000704,0x000200f8,0x00000703,0x0003003e,0x000006f7, + 0x000000da,0x000200f9,0x00000704,0x000200f8,0x00000704,0x0004003d,0x00000006,0x00000705, + 0x000006f7,0x0005008e,0x00000024,0x00000706,0x000006fb,0x00000705,0x0003003e,0x000006f8, + 0x00000706,0x0004003d,0x00000024,0x000005ff,0x000006f8,0x0003003e,0x000005d6,0x000005ff, + 0x0004003d,0x00000012,0x00000600,0x000005c8,0x000300f7,0x000006f5,0x00000000,0x002100fb, + 0x00000600,0x000006f5,0x0000000b,0x00000601,0x00000001,0x00000605,0x00000002,0x0000060d, + 0x00000003,0x0000061d,0x00000004,0x00000621,0x00000005,0x00000625,0x00000006,0x00000647, + 0x00000007,0x00000673,0x00000008,0x00000683,0x00000009,0x000006bd,0x0000000a,0x000006c2, + 0x0000000c,0x000006cb,0x0000000d,0x000006d6,0x0000000e,0x000006e1,0x0000000f,0x000006eb, + 0x000200f8,0x00000601,0x0004003d,0x00000024,0x00000602,0x000005c6,0x0004003d,0x00000024, + 0x00000603,0x000005d6,0x00050085,0x00000024,0x00000604,0x00000602,0x00000603,0x0003003e, + 0x000005d8,0x00000604,0x000200f9,0x000006f5,0x000200f8,0x00000605,0x0004003d,0x00000024, + 0x00000606,0x000005c6,0x0004003d,0x00000024,0x00000607,0x000005d6,0x00050081,0x00000024, + 0x00000608,0x00000606,0x00000607,0x0004003d,0x00000024,0x00000609,0x000005c6,0x0004003d, + 0x00000024,0x0000060a,0x000005d6,0x00050085,0x00000024,0x0000060b,0x00000609,0x0000060a, + 0x00050083,0x00000024,0x0000060c,0x00000608,0x0000060b,0x0003003e,0x000005d8,0x0000060c, + 0x000200f9,0x000006f5,0x000200f8,0x0000060d,0x0004003d,0x00000024,0x0000060e,0x000005c6, + 0x0004003d,0x00000024,0x0000060f,0x000005d6,0x00050085,0x00000024,0x00000610,0x0000060e, + 0x0000060f,0x0003003e,0x000005d9,0x00000610,0x0004003d,0x00000024,0x00000611,0x000005d9, + 0x0004003d,0x00000024,0x00000612,0x000005c6,0x0004003d,0x00000024,0x00000613,0x000005d6, + 0x00050081,0x00000024,0x00000614,0x00000612,0x00000613,0x0004003d,0x00000024,0x00000615, + 0x000005d9,0x00050083,0x00000024,0x00000616,0x00000614,0x00000615,0x00050083,0x00000024, + 0x00000617,0x00000616,0x00000474,0x0004003d,0x00000024,0x00000618,0x000005d6,0x0003003e, + 0x000005da,0x000001c9,0x0004003d,0x00000006,0x0000070a,0x000005da,0x00050041,0x00000007, + 0x0000070b,0x00000707,0x000000a3,0x0003003e,0x0000070b,0x0000070a,0x0004003d,0x00000006, + 0x0000070c,0x000005da,0x00050041,0x00000007,0x0000070d,0x00000707,0x000000a6,0x0003003e, + 0x0000070d,0x0000070c,0x0004003d,0x00000006,0x0000070e,0x000005da,0x00050041,0x00000007, + 0x0000070f,0x00000707,0x000000b9,0x0003003e,0x0000070f,0x0000070e,0x0004003d,0x00000024, + 0x00000710,0x00000707,0x0003003e,0x00000708,0x00000710,0x0004003d,0x00000024,0x00000619, + 0x00000708,0x000500ba,0x000001cf,0x0000061a,0x00000618,0x00000619,0x000600a9,0x00000024, + 0x0000061b,0x0000061a,0x00000617,0x00000611,0x0005008e,0x00000024,0x0000061c,0x0000061b, + 0x000001c2,0x0003003e,0x000005d8,0x0000061c,0x000200f9,0x000006f5,0x000200f8,0x0000061d, + 0x0004003d,0x00000024,0x0000061e,0x000005c6,0x0004003d,0x00000024,0x0000061f,0x000005d6, + 0x0007000c,0x00000024,0x00000620,0x00000001,0x00000025,0x0000061e,0x0000061f,0x0003003e, + 0x000005d8,0x00000620,0x000200f9,0x000006f5,0x000200f8,0x00000621,0x0004003d,0x00000024, + 0x00000622,0x000005c6,0x0004003d,0x00000024,0x00000623,0x000005d6,0x0007000c,0x00000024, + 0x00000624,0x00000001,0x00000028,0x00000622,0x00000623,0x0003003e,0x000005d8,0x00000624, + 0x000200f9,0x000006f5,0x000200f8,0x00000625,0x0004003d,0x0000002f,0x00000626,0x000005c7, + 0x0008004f,0x00000024,0x00000627,0x00000626,0x00000626,0x00000000,0x00000001,0x00000002, + 0x0003003e,0x000005db,0x000000da,0x0004003d,0x00000006,0x00000714,0x000005db,0x00050041, + 0x00000007,0x00000715,0x00000711,0x000000a3,0x0003003e,0x00000715,0x00000714,0x0004003d, + 0x00000006,0x00000716,0x000005db,0x00050041,0x00000007,0x00000717,0x00000711,0x000000a6, + 0x0003003e,0x00000717,0x00000716,0x0004003d,0x00000006,0x00000718,0x000005db,0x00050041, + 0x00000007,0x00000719,0x00000711,0x000000b9,0x0003003e,0x00000719,0x00000718,0x0004003d, + 0x00000024,0x0000071a,0x00000711,0x0003003e,0x00000712,0x0000071a,0x0004003d,0x00000024, + 0x00000628,0x00000712,0x0004003d,0x0000002f,0x00000629,0x000005c7,0x0008004f,0x00000024, + 0x0000062a,0x00000629,0x00000629,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024, + 0x0000062b,0x00000001,0x0000002b,0x00000627,0x00000628,0x0000062a,0x00050041,0x00000007, + 0x0000062c,0x000005c7,0x000000a3,0x00050051,0x00000006,0x0000062d,0x0000062b,0x00000000, + 0x0003003e,0x0000062c,0x0000062d,0x00050041,0x00000007,0x0000062e,0x000005c7,0x000000a6, + 0x00050051,0x00000006,0x0000062f,0x0000062b,0x00000001,0x0003003e,0x0000062e,0x0000062f, + 0x00050041,0x00000007,0x00000630,0x000005c7,0x000000b9,0x00050051,0x00000006,0x00000631, + 0x0000062b,0x00000002,0x0003003e,0x00000630,0x00000631,0x0004003d,0x00000024,0x00000632, + 0x000005c6,0x00050083,0x00000024,0x00000633,0x00000473,0x00000632,0x0003003e,0x000005dd, + 0x000000da,0x0004003d,0x00000006,0x0000071e,0x000005dd,0x00050041,0x00000007,0x0000071f, + 0x0000071b,0x000000a3,0x0003003e,0x0000071f,0x0000071e,0x0004003d,0x00000006,0x00000720, + 0x000005dd,0x00050041,0x00000007,0x00000721,0x0000071b,0x000000a6,0x0003003e,0x00000721, + 0x00000720,0x0004003d,0x00000006,0x00000722,0x000005dd,0x00050041,0x00000007,0x00000723, + 0x0000071b,0x000000b9,0x0003003e,0x00000723,0x00000722,0x0004003d,0x00000024,0x00000724, + 0x0000071b,0x0003003e,0x0000071c,0x00000724,0x0004003d,0x00000024,0x00000634,0x0000071c, + 0x0003003e,0x000005de,0x000000d9,0x0004003d,0x00000006,0x00000728,0x000005de,0x00050041, + 0x00000007,0x00000729,0x00000725,0x000000a3,0x0003003e,0x00000729,0x00000728,0x0004003d, + 0x00000006,0x0000072a,0x000005de,0x00050041,0x00000007,0x0000072b,0x00000725,0x000000a6, + 0x0003003e,0x0000072b,0x0000072a,0x0004003d,0x00000006,0x0000072c,0x000005de,0x00050041, + 0x00000007,0x0000072d,0x00000725,0x000000b9,0x0003003e,0x0000072d,0x0000072c,0x0004003d, + 0x00000024,0x0000072e,0x00000725,0x0003003e,0x00000726,0x0000072e,0x0004003d,0x00000024, + 0x00000635,0x00000726,0x0008000c,0x00000024,0x00000636,0x00000001,0x0000002b,0x00000633, + 0x00000634,0x00000635,0x00050041,0x00000007,0x00000637,0x000005c7,0x000000d0,0x0004003d, + 0x00000006,0x00000638,0x00000637,0x0005008e,0x00000024,0x00000639,0x00000636,0x00000638, + 0x0003003e,0x000005dc,0x00000639,0x0003003e,0x000005df,0x000000d9,0x0004003d,0x00000006, + 0x00000732,0x000005df,0x00050041,0x00000007,0x00000733,0x0000072f,0x000000a3,0x0003003e, + 0x00000733,0x00000732,0x0004003d,0x00000006,0x00000734,0x000005df,0x00050041,0x00000007, + 0x00000735,0x0000072f,0x000000a6,0x0003003e,0x00000735,0x00000734,0x0004003d,0x00000006, + 0x00000736,0x000005df,0x00050041,0x00000007,0x00000737,0x0000072f,0x000000b9,0x0003003e, + 0x00000737,0x00000736,0x0004003d,0x00000024,0x00000738,0x0000072f,0x0003003e,0x00000730, + 0x00000738,0x0004003d,0x00000024,0x0000063a,0x00000730,0x0004003d,0x0000002f,0x0000063b, + 0x000005c7,0x0008004f,0x00000024,0x0000063c,0x0000063b,0x0000063b,0x00000000,0x00000001, + 0x00000002,0x0004003d,0x00000024,0x0000063d,0x000005dc,0x00050088,0x00000024,0x0000063e, + 0x0000063c,0x0000063d,0x0007000c,0x00000024,0x0000063f,0x00000001,0x00000025,0x0000063a, + 0x0000063e,0x0004003d,0x0000002f,0x00000640,0x000005c7,0x0008004f,0x00000024,0x00000641, + 0x00000640,0x00000640,0x00000000,0x00000001,0x00000002,0x0006000c,0x00000024,0x00000642, + 0x00000001,0x00000006,0x00000641,0x0004003d,0x00000024,0x00000643,0x000005dc,0x0003003e, + 0x000005e0,0x000000da,0x0004003d,0x00000006,0x0000073c,0x000005e0,0x00050041,0x00000007, + 0x0000073d,0x00000739,0x000000a3,0x0003003e,0x0000073d,0x0000073c,0x0004003d,0x00000006, + 0x0000073e,0x000005e0,0x00050041,0x00000007,0x0000073f,0x00000739,0x000000a6,0x0003003e, + 0x0000073f,0x0000073e,0x0004003d,0x00000006,0x00000740,0x000005e0,0x00050041,0x00000007, + 0x00000741,0x00000739,0x000000b9,0x0003003e,0x00000741,0x00000740,0x0004003d,0x00000024, + 0x00000742,0x00000739,0x0003003e,0x0000073a,0x00000742,0x0004003d,0x00000024,0x00000644, + 0x0000073a,0x000500b4,0x000001cf,0x00000645,0x00000643,0x00000644,0x000600a9,0x00000024, + 0x00000646,0x00000645,0x00000642,0x0000063f,0x0003003e,0x000005d8,0x00000646,0x000200f9, + 0x000006f5,0x000200f8,0x00000647,0x0004003d,0x00000024,0x00000648,0x000005c6,0x0003003e, + 0x000005e1,0x000000da,0x0004003d,0x00000006,0x00000746,0x000005e1,0x00050041,0x00000007, + 0x00000747,0x00000743,0x000000a3,0x0003003e,0x00000747,0x00000746,0x0004003d,0x00000006, + 0x00000748,0x000005e1,0x00050041,0x00000007,0x00000749,0x00000743,0x000000a6,0x0003003e, + 0x00000749,0x00000748,0x0004003d,0x00000006,0x0000074a,0x000005e1,0x00050041,0x00000007, + 0x0000074b,0x00000743,0x000000b9,0x0003003e,0x0000074b,0x0000074a,0x0004003d,0x00000024, + 0x0000074c,0x00000743,0x0003003e,0x00000744,0x0000074c,0x0004003d,0x00000024,0x00000649, + 0x00000744,0x0003003e,0x000005e2,0x000000d9,0x0004003d,0x00000006,0x00000750,0x000005e2, + 0x00050041,0x00000007,0x00000751,0x0000074d,0x000000a3,0x0003003e,0x00000751,0x00000750, + 0x0004003d,0x00000006,0x00000752,0x000005e2,0x00050041,0x00000007,0x00000753,0x0000074d, + 0x000000a6,0x0003003e,0x00000753,0x00000752,0x0004003d,0x00000006,0x00000754,0x000005e2, + 0x00050041,0x00000007,0x00000755,0x0000074d,0x000000b9,0x0003003e,0x00000755,0x00000754, + 0x0004003d,0x00000024,0x00000756,0x0000074d,0x0003003e,0x0000074e,0x00000756,0x0004003d, + 0x00000024,0x0000064a,0x0000074e,0x0008000c,0x00000024,0x0000064b,0x00000001,0x0000002b, + 0x00000648,0x00000649,0x0000064a,0x0003003e,0x000005c6,0x0000064b,0x0004003d,0x0000002f, + 0x0000064c,0x000005c7,0x0008004f,0x00000024,0x0000064d,0x0000064c,0x0000064c,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x000005e3,0x000000da,0x0004003d,0x00000006,0x0000075a, + 0x000005e3,0x00050041,0x00000007,0x0000075b,0x00000757,0x000000a3,0x0003003e,0x0000075b, + 0x0000075a,0x0004003d,0x00000006,0x0000075c,0x000005e3,0x00050041,0x00000007,0x0000075d, + 0x00000757,0x000000a6,0x0003003e,0x0000075d,0x0000075c,0x0004003d,0x00000006,0x0000075e, + 0x000005e3,0x00050041,0x00000007,0x0000075f,0x00000757,0x000000b9,0x0003003e,0x0000075f, + 0x0000075e,0x0004003d,0x00000024,0x00000760,0x00000757,0x0003003e,0x00000758,0x00000760, + 0x0004003d,0x00000024,0x0000064e,0x00000758,0x0004003d,0x0000002f,0x0000064f,0x000005c7, + 0x0008004f,0x00000024,0x00000650,0x0000064f,0x0000064f,0x00000003,0x00000003,0x00000003, + 0x0008000c,0x00000024,0x00000651,0x00000001,0x0000002b,0x0000064d,0x0000064e,0x00000650, + 0x00050041,0x00000007,0x00000652,0x000005c7,0x000000a3,0x00050051,0x00000006,0x00000653, + 0x00000651,0x00000000,0x0003003e,0x00000652,0x00000653,0x00050041,0x00000007,0x00000654, + 0x000005c7,0x000000a6,0x00050051,0x00000006,0x00000655,0x00000651,0x00000001,0x0003003e, + 0x00000654,0x00000655,0x00050041,0x00000007,0x00000656,0x000005c7,0x000000b9,0x00050051, + 0x00000006,0x00000657,0x00000651,0x00000002,0x0003003e,0x00000656,0x00000657,0x00050041, + 0x00000007,0x00000658,0x000005c7,0x000000d0,0x0004003d,0x00000006,0x00000659,0x00000658, + 0x000500b4,0x000000e8,0x0000065a,0x00000659,0x000000da,0x000300f7,0x0000065d,0x00000000, + 0x000400fa,0x0000065a,0x0000065b,0x0000065d,0x000200f8,0x0000065b,0x0003003e,0x00000658, + 0x000000d9,0x000200f9,0x0000065d,0x000200f8,0x0000065d,0x0004003d,0x00000006,0x0000065f, + 0x00000658,0x0004003d,0x0000002f,0x00000660,0x000005c7,0x0008004f,0x00000024,0x00000661, + 0x00000660,0x00000660,0x00000000,0x00000001,0x00000002,0x00060050,0x00000024,0x00000662, + 0x0000065f,0x0000065f,0x0000065f,0x00050083,0x00000024,0x00000663,0x00000662,0x00000661, + 0x0003003e,0x000005e4,0x00000663,0x0003003e,0x000005e5,0x000000d9,0x0004003d,0x00000006, + 0x00000764,0x000005e5,0x00050041,0x00000007,0x00000765,0x00000761,0x000000a3,0x0003003e, + 0x00000765,0x00000764,0x0004003d,0x00000006,0x00000766,0x000005e5,0x00050041,0x00000007, + 0x00000767,0x00000761,0x000000a6,0x0003003e,0x00000767,0x00000766,0x0004003d,0x00000006, + 0x00000768,0x000005e5,0x00050041,0x00000007,0x00000769,0x00000761,0x000000b9,0x0003003e, + 0x00000769,0x00000768,0x0004003d,0x00000024,0x0000076a,0x00000761,0x0003003e,0x00000762, + 0x0000076a,0x0004003d,0x00000024,0x00000664,0x00000762,0x0004003d,0x00000024,0x00000665, + 0x000005e4,0x0004003d,0x00000024,0x00000666,0x000005c6,0x0004003d,0x00000006,0x00000668, + 0x00000658,0x0005008e,0x00000024,0x00000669,0x00000666,0x00000668,0x00050088,0x00000024, + 0x0000066a,0x00000665,0x00000669,0x0007000c,0x00000024,0x0000066b,0x00000001,0x00000025, + 0x00000664,0x0000066a,0x0004003d,0x00000024,0x0000066c,0x000005e4,0x0006000c,0x00000024, + 0x0000066d,0x00000001,0x00000006,0x0000066c,0x0004003d,0x00000024,0x0000066e,0x000005c6, + 0x0003003e,0x000005e6,0x000000da,0x0004003d,0x00000006,0x0000076e,0x000005e6,0x00050041, + 0x00000007,0x0000076f,0x0000076b,0x000000a3,0x0003003e,0x0000076f,0x0000076e,0x0004003d, + 0x00000006,0x00000770,0x000005e6,0x00050041,0x00000007,0x00000771,0x0000076b,0x000000a6, + 0x0003003e,0x00000771,0x00000770,0x0004003d,0x00000006,0x00000772,0x000005e6,0x00050041, + 0x00000007,0x00000773,0x0000076b,0x000000b9,0x0003003e,0x00000773,0x00000772,0x0004003d, + 0x00000024,0x00000774,0x0000076b,0x0003003e,0x0000076c,0x00000774,0x0004003d,0x00000024, + 0x0000066f,0x0000076c,0x000500b4,0x000001cf,0x00000670,0x0000066e,0x0000066f,0x000600a9, + 0x00000024,0x00000671,0x00000670,0x0000066d,0x0000066b,0x00050083,0x00000024,0x00000672, + 0x00000473,0x00000671,0x0003003e,0x000005d8,0x00000672,0x000200f9,0x000006f5,0x000200f8, + 0x00000673,0x0004003d,0x00000024,0x00000674,0x000005c6,0x0004003d,0x00000024,0x00000675, + 0x000005d6,0x00050085,0x00000024,0x00000676,0x00000674,0x00000675,0x0003003e,0x000005e7, + 0x00000676,0x0004003d,0x00000024,0x00000677,0x000005e7,0x0004003d,0x00000024,0x00000678, + 0x000005c6,0x0004003d,0x00000024,0x00000679,0x000005d6,0x00050081,0x00000024,0x0000067a, + 0x00000678,0x00000679,0x0004003d,0x00000024,0x0000067b,0x000005e7,0x00050083,0x00000024, + 0x0000067c,0x0000067a,0x0000067b,0x00050083,0x00000024,0x0000067d,0x0000067c,0x00000474, + 0x0004003d,0x00000024,0x0000067e,0x000005c6,0x0003003e,0x000005e8,0x000001c9,0x0004003d, + 0x00000006,0x00000778,0x000005e8,0x00050041,0x00000007,0x00000779,0x00000775,0x000000a3, + 0x0003003e,0x00000779,0x00000778,0x0004003d,0x00000006,0x0000077a,0x000005e8,0x00050041, + 0x00000007,0x0000077b,0x00000775,0x000000a6,0x0003003e,0x0000077b,0x0000077a,0x0004003d, + 0x00000006,0x0000077c,0x000005e8,0x00050041,0x00000007,0x0000077d,0x00000775,0x000000b9, + 0x0003003e,0x0000077d,0x0000077c,0x0004003d,0x00000024,0x0000077e,0x00000775,0x0003003e, + 0x00000776,0x0000077e,0x0004003d,0x00000024,0x0000067f,0x00000776,0x000500ba,0x000001cf, + 0x00000680,0x0000067e,0x0000067f,0x000600a9,0x00000024,0x00000681,0x00000680,0x0000067d, + 0x00000677,0x0005008e,0x00000024,0x00000682,0x00000681,0x000001c2,0x0003003e,0x000005d8, + 0x00000682,0x000200f9,0x000006f5,0x000200f8,0x00000683,0x0003003e,0x000005e9,0x0000024d, + 0x000200f9,0x00000684,0x000200f8,0x00000684,0x0004003d,0x00000080,0x00000686,0x000005e9, + 0x000500b1,0x000000e8,0x00000687,0x00000686,0x00000254,0x000400f6,0x000006b3,0x000006b0, + 0x00000000,0x000400fa,0x00000687,0x00000688,0x000006b3,0x000200f8,0x00000688,0x0004003d, + 0x00000080,0x00000689,0x000005e9,0x00050041,0x00000007,0x0000068a,0x000005c6,0x00000689, + 0x0004003d,0x00000006,0x0000068b,0x0000068a,0x000500bc,0x000000e8,0x0000068c,0x0000068b, + 0x000001c9,0x000300f7,0x000006af,0x00000000,0x000400fa,0x0000068c,0x0000068d,0x00000694, + 0x000200f8,0x0000068d,0x0004003d,0x00000080,0x0000068e,0x000005e9,0x0004003d,0x00000080, + 0x0000068f,0x000005e9,0x00050041,0x00000007,0x00000690,0x000005d6,0x0000068f,0x0004003d, + 0x00000006,0x00000691,0x00000690,0x00050083,0x00000006,0x00000692,0x000000d9,0x00000691, + 0x00050041,0x00000007,0x00000693,0x000005d8,0x0000068e,0x0003003e,0x00000693,0x00000692, + 0x000200f9,0x000006af,0x000200f8,0x00000694,0x0004003d,0x00000080,0x00000695,0x000005e9, + 0x00050041,0x00000007,0x00000696,0x000005d6,0x00000695,0x0004003d,0x00000006,0x00000697, + 0x00000696,0x000500bc,0x000000e8,0x00000698,0x00000697,0x00000266,0x000300f7,0x000006ae, + 0x00000000,0x000400fa,0x00000698,0x00000699,0x000006a6,0x000200f8,0x00000699,0x0004003d, + 0x00000080,0x0000069a,0x000005e9,0x0004003d,0x00000080,0x0000069b,0x000005e9,0x00050041, + 0x00000007,0x0000069c,0x000005d6,0x0000069b,0x0004003d,0x00000006,0x0000069d,0x0000069c, + 0x00050085,0x00000006,0x0000069e,0x0000026b,0x0000069d,0x00050083,0x00000006,0x0000069f, + 0x0000069e,0x00000270,0x0004003d,0x00000080,0x000006a0,0x000005e9,0x00050041,0x00000007, + 0x000006a1,0x000005d6,0x000006a0,0x0004003d,0x00000006,0x000006a2,0x000006a1,0x00050085, + 0x00000006,0x000006a3,0x0000069f,0x000006a2,0x00050081,0x00000006,0x000006a4,0x000006a3, + 0x00000276,0x00050041,0x00000007,0x000006a5,0x000005d8,0x0000069a,0x0003003e,0x000006a5, + 0x000006a4,0x000200f9,0x000006ae,0x000200f8,0x000006a6,0x0004003d,0x00000080,0x000006a7, + 0x000005e9,0x0004003d,0x00000080,0x000006a8,0x000005e9,0x00050041,0x00000007,0x000006a9, + 0x000005d6,0x000006a8,0x0004003d,0x00000006,0x000006aa,0x000006a9,0x0006000c,0x00000006, + 0x000006ab,0x00000001,0x00000020,0x000006aa,0x00050083,0x00000006,0x000006ac,0x000006ab, + 0x000000d9,0x00050041,0x00000007,0x000006ad,0x000005d8,0x000006a7,0x0003003e,0x000006ad, + 0x000006ac,0x000200f9,0x000006ae,0x000200f8,0x000006ae,0x000200f9,0x000006af,0x000200f8, + 0x000006af,0x000200f9,0x000006b0,0x000200f8,0x000006b0,0x0004003d,0x00000080,0x000006b1, + 0x000005e9,0x00050080,0x00000080,0x000006b2,0x000006b1,0x00000282,0x0003003e,0x000005e9, + 0x000006b2,0x000200f9,0x00000684,0x000200f8,0x000006b3,0x0004003d,0x00000024,0x000006b4, + 0x000005d6,0x0004003d,0x00000024,0x000006b5,0x000005d6,0x0004003d,0x00000024,0x000006b6, + 0x000005c6,0x0005008e,0x00000024,0x000006b7,0x000006b6,0x000001c2,0x00050083,0x00000024, + 0x000006b8,0x000006b7,0x00000473,0x00050085,0x00000024,0x000006b9,0x000006b5,0x000006b8, + 0x0004003d,0x00000024,0x000006ba,0x000005d8,0x00050085,0x00000024,0x000006bb,0x000006b9, + 0x000006ba,0x00050081,0x00000024,0x000006bc,0x000006b4,0x000006bb,0x0003003e,0x000005d8, + 0x000006bc,0x000200f9,0x000006f5,0x000200f8,0x000006bd,0x0004003d,0x00000024,0x000006be, + 0x000005d6,0x0004003d,0x00000024,0x000006bf,0x000005c6,0x00050083,0x00000024,0x000006c0, + 0x000006be,0x000006bf,0x0006000c,0x00000024,0x000006c1,0x00000001,0x00000004,0x000006c0, + 0x0003003e,0x000005d8,0x000006c1,0x000200f9,0x000006f5,0x000200f8,0x000006c2,0x0004003d, + 0x00000024,0x000006c3,0x000005c6,0x0004003d,0x00000024,0x000006c4,0x000005d6,0x00050081, + 0x00000024,0x000006c5,0x000006c3,0x000006c4,0x0004003d,0x00000024,0x000006c6,0x000005c6, + 0x0005008e,0x00000024,0x000006c7,0x000006c6,0x000001c2,0x0004003d,0x00000024,0x000006c8, + 0x000005d6,0x00050085,0x00000024,0x000006c9,0x000006c7,0x000006c8,0x00050083,0x00000024, + 0x000006ca,0x000006c5,0x000006c9,0x0003003e,0x000005d8,0x000006ca,0x000200f9,0x000006f5, + 0x000200f8,0x000006cb,0x000300f7,0x000006d5,0x00000000,0x000400fa,0x0000029d,0x000006cc, + 0x000006d5,0x000200f8,0x000006cc,0x0004003d,0x00000024,0x000006cd,0x000005c6,0x0003003e, + 0x000005ea,0x000000da,0x0004003d,0x00000006,0x00000782,0x000005ea,0x00050041,0x00000007, + 0x00000783,0x0000077f,0x000000a3,0x0003003e,0x00000783,0x00000782,0x0004003d,0x00000006, + 0x00000784,0x000005ea,0x00050041,0x00000007,0x00000785,0x0000077f,0x000000a6,0x0003003e, + 0x00000785,0x00000784,0x0004003d,0x00000006,0x00000786,0x000005ea,0x00050041,0x00000007, + 0x00000787,0x0000077f,0x000000b9,0x0003003e,0x00000787,0x00000786,0x0004003d,0x00000024, + 0x00000788,0x0000077f,0x0003003e,0x00000780,0x00000788,0x0004003d,0x00000024,0x000006ce, + 0x00000780,0x0003003e,0x000005eb,0x000000d9,0x0004003d,0x00000006,0x0000078c,0x000005eb, + 0x00050041,0x00000007,0x0000078d,0x00000789,0x000000a3,0x0003003e,0x0000078d,0x0000078c, + 0x0004003d,0x00000006,0x0000078e,0x000005eb,0x00050041,0x00000007,0x0000078f,0x00000789, + 0x000000a6,0x0003003e,0x0000078f,0x0000078e,0x0004003d,0x00000006,0x00000790,0x000005eb, + 0x00050041,0x00000007,0x00000791,0x00000789,0x000000b9,0x0003003e,0x00000791,0x00000790, + 0x0004003d,0x00000024,0x00000792,0x00000789,0x0003003e,0x0000078a,0x00000792,0x0004003d, + 0x00000024,0x000006cf,0x0000078a,0x0008000c,0x00000024,0x000006d0,0x00000001,0x0000002b, + 0x000006cd,0x000006ce,0x000006cf,0x0003003e,0x000005c6,0x000006d0,0x0004003d,0x00000024, + 0x000006d1,0x000005c6,0x0003003e,0x000005ec,0x000006d1,0x0004003d,0x00000024,0x000006d2, + 0x000005d6,0x0003003e,0x000005ed,0x000006d2,0x0004003d,0x00000024,0x000006d3,0x000005d6, + 0x0003003e,0x000005ee,0x000006d3,0x0004003d,0x00000024,0x0000079e,0x000005ed,0x0003003e, + 0x00000794,0x0000079e,0x0004003d,0x00000024,0x000007b6,0x00000794,0x0007004f,0x0000000c, + 0x000007b7,0x000007b6,0x000007b6,0x00000000,0x00000001,0x0003003e,0x000007b3,0x000007b7, + 0x00050041,0x00000007,0x000007be,0x000007b3,0x000000a3,0x0004003d,0x00000006,0x000007bf, + 0x000007be,0x00050041,0x00000007,0x000007c0,0x000007b3,0x000000a6,0x0004003d,0x00000006, + 0x000007c1,0x000007c0,0x0007000c,0x00000006,0x000007c2,0x00000001,0x00000028,0x000007bf, + 0x000007c1,0x0003003e,0x000007bc,0x000007c2,0x0004003d,0x00000006,0x000007b8,0x000007bc, + 0x00050041,0x00000007,0x000007b9,0x00000794,0x000000b9,0x0004003d,0x00000006,0x000007ba, + 0x000007b9,0x0007000c,0x00000006,0x000007bb,0x00000001,0x00000028,0x000007b8,0x000007ba, + 0x0003003e,0x000007b4,0x000007bb,0x0004003d,0x00000006,0x0000079f,0x000007b4,0x0004003d, + 0x00000024,0x000007a0,0x000005ed,0x0003003e,0x00000795,0x000007a0,0x0004003d,0x00000024, + 0x000007c6,0x00000795,0x0007004f,0x0000000c,0x000007c7,0x000007c6,0x000007c6,0x00000000, + 0x00000001,0x0003003e,0x000007c3,0x000007c7,0x00050041,0x00000007,0x000007ce,0x000007c3, + 0x000000a3,0x0004003d,0x00000006,0x000007cf,0x000007ce,0x00050041,0x00000007,0x000007d0, + 0x000007c3,0x000000a6,0x0004003d,0x00000006,0x000007d1,0x000007d0,0x0007000c,0x00000006, + 0x000007d2,0x00000001,0x00000025,0x000007cf,0x000007d1,0x0003003e,0x000007cc,0x000007d2, + 0x0004003d,0x00000006,0x000007c8,0x000007cc,0x00050041,0x00000007,0x000007c9,0x00000795, + 0x000000b9,0x0004003d,0x00000006,0x000007ca,0x000007c9,0x0007000c,0x00000006,0x000007cb, + 0x00000001,0x00000025,0x000007c8,0x000007ca,0x0003003e,0x000007c4,0x000007cb,0x0004003d, + 0x00000006,0x000007a1,0x000007c4,0x00050083,0x00000006,0x000007a2,0x0000079f,0x000007a1, + 0x0003003e,0x00000793,0x000007a2,0x0004003d,0x00000024,0x000007a3,0x000005ec,0x0003003e, + 0x00000796,0x000007a3,0x0004003d,0x00000024,0x000007d6,0x00000796,0x0007004f,0x0000000c, + 0x000007d7,0x000007d6,0x000007d6,0x00000000,0x00000001,0x0003003e,0x000007d3,0x000007d7, + 0x00050041,0x00000007,0x000007de,0x000007d3,0x000000a3,0x0004003d,0x00000006,0x000007df, + 0x000007de,0x00050041,0x00000007,0x000007e0,0x000007d3,0x000000a6,0x0004003d,0x00000006, + 0x000007e1,0x000007e0,0x0007000c,0x00000006,0x000007e2,0x00000001,0x00000025,0x000007df, + 0x000007e1,0x0003003e,0x000007dc,0x000007e2,0x0004003d,0x00000006,0x000007d8,0x000007dc, + 0x00050041,0x00000007,0x000007d9,0x00000796,0x000000b9,0x0004003d,0x00000006,0x000007da, + 0x000007d9,0x0007000c,0x00000006,0x000007db,0x00000001,0x00000025,0x000007d8,0x000007da, + 0x0003003e,0x000007d4,0x000007db,0x0004003d,0x00000006,0x000007a4,0x000007d4,0x0004003d, + 0x00000024,0x000007a5,0x000005ec,0x00060050,0x00000024,0x000007a6,0x000007a4,0x000007a4, + 0x000007a4,0x00050083,0x00000024,0x000007a7,0x000007a5,0x000007a6,0x0003003e,0x000005ec, + 0x000007a7,0x0004003d,0x00000024,0x000007a8,0x000005ec,0x0003003e,0x00000798,0x000007a8, + 0x0004003d,0x00000024,0x000007e6,0x00000798,0x0007004f,0x0000000c,0x000007e7,0x000007e6, + 0x000007e6,0x00000000,0x00000001,0x0003003e,0x000007e3,0x000007e7,0x00050041,0x00000007, + 0x000007ee,0x000007e3,0x000000a3,0x0004003d,0x00000006,0x000007ef,0x000007ee,0x00050041, + 0x00000007,0x000007f0,0x000007e3,0x000000a6,0x0004003d,0x00000006,0x000007f1,0x000007f0, + 0x0007000c,0x00000006,0x000007f2,0x00000001,0x00000028,0x000007ef,0x000007f1,0x0003003e, + 0x000007ec,0x000007f2,0x0004003d,0x00000006,0x000007e8,0x000007ec,0x00050041,0x00000007, + 0x000007e9,0x00000798,0x000000b9,0x0004003d,0x00000006,0x000007ea,0x000007e9,0x0007000c, + 0x00000006,0x000007eb,0x00000001,0x00000028,0x000007e8,0x000007ea,0x0003003e,0x000007e4, + 0x000007eb,0x0004003d,0x00000006,0x000007a9,0x000007e4,0x0003003e,0x00000797,0x000007a9, + 0x0004003d,0x00000006,0x000007aa,0x00000793,0x0004003d,0x00000006,0x000007ab,0x00000797, + 0x0007000c,0x00000006,0x000007ac,0x00000001,0x00000028,0x0000015c,0x000007ab,0x00050088, + 0x00000006,0x000007ad,0x000007aa,0x000007ac,0x0003003e,0x00000799,0x000007ad,0x0004003d, + 0x00000024,0x000007ae,0x000005ec,0x0004003d,0x00000006,0x000007af,0x00000799,0x0005008e, + 0x00000024,0x000007b0,0x000007ae,0x000007af,0x0003003e,0x0000079a,0x000007b0,0x0004003d, + 0x00000024,0x000007b1,0x000005ee,0x0003003e,0x0000079b,0x000007b1,0x0004003d,0x00000024, + 0x00000803,0x0000079b,0x0003003e,0x000007f4,0x00000803,0x0004003d,0x00000024,0x00000829, + 0x000007f4,0x0003003e,0x00000824,0x00000140,0x0003003e,0x00000825,0x00000141,0x0003003e, + 0x00000826,0x00000142,0x0004003d,0x00000006,0x0000082f,0x00000824,0x00050041,0x00000007, + 0x00000830,0x0000082c,0x000000a3,0x0003003e,0x00000830,0x0000082f,0x0004003d,0x00000006, + 0x00000831,0x00000825,0x00050041,0x00000007,0x00000832,0x0000082c,0x000000a6,0x0003003e, + 0x00000832,0x00000831,0x0004003d,0x00000006,0x00000833,0x00000826,0x00050041,0x00000007, + 0x00000834,0x0000082c,0x000000b9,0x0003003e,0x00000834,0x00000833,0x0004003d,0x00000024, + 0x00000835,0x0000082c,0x0003003e,0x0000082d,0x00000835,0x0004003d,0x00000024,0x0000082a, + 0x0000082d,0x00050094,0x00000006,0x0000082b,0x00000829,0x0000082a,0x0003003e,0x00000827, + 0x0000082b,0x0004003d,0x00000006,0x00000804,0x00000827,0x0003003e,0x000007f3,0x00000804, + 0x0004003d,0x00000024,0x00000805,0x0000079a,0x0004003d,0x00000024,0x00000806,0x0000079a, + 0x0003003e,0x000007f6,0x00000806,0x0004003d,0x00000024,0x0000083b,0x000007f6,0x0003003e, + 0x00000836,0x00000140,0x0003003e,0x00000837,0x00000141,0x0003003e,0x00000838,0x00000142, + 0x0004003d,0x00000006,0x00000841,0x00000836,0x00050041,0x00000007,0x00000842,0x0000083e, + 0x000000a3,0x0003003e,0x00000842,0x00000841,0x0004003d,0x00000006,0x00000843,0x00000837, + 0x00050041,0x00000007,0x00000844,0x0000083e,0x000000a6,0x0003003e,0x00000844,0x00000843, + 0x0004003d,0x00000006,0x00000845,0x00000838,0x00050041,0x00000007,0x00000846,0x0000083e, + 0x000000b9,0x0003003e,0x00000846,0x00000845,0x0004003d,0x00000024,0x00000847,0x0000083e, + 0x0003003e,0x0000083f,0x00000847,0x0004003d,0x00000024,0x0000083c,0x0000083f,0x00050094, + 0x00000006,0x0000083d,0x0000083b,0x0000083c,0x0003003e,0x00000839,0x0000083d,0x0004003d, + 0x00000006,0x00000807,0x00000839,0x00060050,0x00000024,0x00000808,0x00000807,0x00000807, + 0x00000807,0x00050083,0x00000024,0x00000809,0x00000805,0x00000808,0x0003003e,0x000007f5, + 0x00000809,0x0004003d,0x00000006,0x0000080a,0x000007f3,0x00050083,0x00000006,0x0000080b, + 0x000000d9,0x0000080a,0x0004003d,0x00000006,0x0000080c,0x000007f3,0x0003003e,0x000007f8, + 0x0000080c,0x0003003e,0x000007f9,0x0000080b,0x0004003d,0x00000006,0x0000084b,0x000007f8, + 0x00050041,0x00000007,0x0000084c,0x00000848,0x000000a3,0x0003003e,0x0000084c,0x0000084b, + 0x0004003d,0x00000006,0x0000084d,0x000007f9,0x00050041,0x00000007,0x0000084e,0x00000848, + 0x000000a6,0x0003003e,0x0000084e,0x0000084d,0x0004003d,0x0000000c,0x0000084f,0x00000848, + 0x0003003e,0x00000849,0x0000084f,0x0004003d,0x0000000c,0x0000080d,0x00000849,0x0003003e, + 0x000007fa,0x0000015c,0x0004003d,0x00000006,0x00000853,0x000007fa,0x00050041,0x00000007, + 0x00000854,0x00000850,0x000000a3,0x0003003e,0x00000854,0x00000853,0x0004003d,0x00000006, + 0x00000855,0x000007fa,0x00050041,0x00000007,0x00000856,0x00000850,0x000000a6,0x0003003e, + 0x00000856,0x00000855,0x0004003d,0x0000000c,0x00000857,0x00000850,0x0003003e,0x00000851, + 0x00000857,0x0004003d,0x0000000c,0x0000080e,0x00000851,0x0004003d,0x00000024,0x0000080f, + 0x000007f5,0x0003003e,0x000007fb,0x0000080f,0x0004003d,0x00000024,0x0000085b,0x000007fb, + 0x0007004f,0x0000000c,0x0000085c,0x0000085b,0x0000085b,0x00000000,0x00000001,0x0003003e, + 0x00000858,0x0000085c,0x00050041,0x00000007,0x00000863,0x00000858,0x000000a3,0x0004003d, + 0x00000006,0x00000864,0x00000863,0x00050041,0x00000007,0x00000865,0x00000858,0x000000a6, + 0x0004003d,0x00000006,0x00000866,0x00000865,0x0007000c,0x00000006,0x00000867,0x00000001, + 0x00000025,0x00000864,0x00000866,0x0003003e,0x00000861,0x00000867,0x0004003d,0x00000006, + 0x0000085d,0x00000861,0x00050041,0x00000007,0x0000085e,0x000007fb,0x000000b9,0x0004003d, + 0x00000006,0x0000085f,0x0000085e,0x0007000c,0x00000006,0x00000860,0x00000001,0x00000025, + 0x0000085d,0x0000085f,0x0003003e,0x00000859,0x00000860,0x0004003d,0x00000006,0x00000810, + 0x00000859,0x0004007f,0x00000006,0x00000811,0x00000810,0x0004003d,0x00000024,0x00000812, + 0x000007f5,0x0003003e,0x000007fc,0x00000812,0x0004003d,0x00000024,0x0000086b,0x000007fc, + 0x0007004f,0x0000000c,0x0000086c,0x0000086b,0x0000086b,0x00000000,0x00000001,0x0003003e, + 0x00000868,0x0000086c,0x00050041,0x00000007,0x00000873,0x00000868,0x000000a3,0x0004003d, + 0x00000006,0x00000874,0x00000873,0x00050041,0x00000007,0x00000875,0x00000868,0x000000a6, + 0x0004003d,0x00000006,0x00000876,0x00000875,0x0007000c,0x00000006,0x00000877,0x00000001, + 0x00000028,0x00000874,0x00000876,0x0003003e,0x00000871,0x00000877,0x0004003d,0x00000006, + 0x0000086d,0x00000871,0x00050041,0x00000007,0x0000086e,0x000007fc,0x000000b9,0x0004003d, + 0x00000006,0x0000086f,0x0000086e,0x0007000c,0x00000006,0x00000870,0x00000001,0x00000028, + 0x0000086d,0x0000086f,0x0003003e,0x00000869,0x00000870,0x0004003d,0x00000006,0x00000813, + 0x00000869,0x0003003e,0x000007fd,0x00000811,0x0003003e,0x000007fe,0x00000813,0x0004003d, + 0x00000006,0x0000087b,0x000007fd,0x00050041,0x00000007,0x0000087c,0x00000878,0x000000a3, + 0x0003003e,0x0000087c,0x0000087b,0x0004003d,0x00000006,0x0000087d,0x000007fe,0x00050041, + 0x00000007,0x0000087e,0x00000878,0x000000a6,0x0003003e,0x0000087e,0x0000087d,0x0004003d, + 0x0000000c,0x0000087f,0x00000878,0x0003003e,0x00000879,0x0000087f,0x0004003d,0x0000000c, + 0x00000814,0x00000879,0x0007000c,0x0000000c,0x00000815,0x00000001,0x00000028,0x0000080e, + 0x00000814,0x00050088,0x0000000c,0x00000816,0x0000080d,0x00000815,0x0003003e,0x000007f7, + 0x00000816,0x0003003e,0x00000800,0x000000d9,0x0004003d,0x00000006,0x00000882,0x00000800, + 0x0003003e,0x00000880,0x00000882,0x0004003d,0x00000006,0x00000817,0x00000880,0x00050041, + 0x00000007,0x00000818,0x000007f7,0x000000a3,0x0004003d,0x00000006,0x00000819,0x00000818, + 0x00050041,0x00000007,0x0000081a,0x000007f7,0x000000a6,0x0004003d,0x00000006,0x0000081b, + 0x0000081a,0x0007000c,0x00000006,0x0000081c,0x00000001,0x00000025,0x00000819,0x0000081b, + 0x0007000c,0x00000006,0x0000081d,0x00000001,0x00000025,0x00000817,0x0000081c,0x0003003e, + 0x000007ff,0x0000081d,0x0004003d,0x00000024,0x0000081e,0x000007f5,0x0004003d,0x00000006, + 0x0000081f,0x000007ff,0x0005008e,0x00000024,0x00000820,0x0000081e,0x0000081f,0x0004003d, + 0x00000006,0x00000821,0x000007f3,0x00060050,0x00000024,0x00000822,0x00000821,0x00000821, + 0x00000821,0x00050081,0x00000024,0x00000823,0x00000820,0x00000822,0x0003003e,0x00000801, + 0x00000823,0x0004003d,0x00000024,0x000007b2,0x00000801,0x0003003e,0x0000079c,0x000007b2, + 0x0004003d,0x00000024,0x000006d4,0x0000079c,0x0003003e,0x000005d8,0x000006d4,0x000200f9, + 0x000006d5,0x000200f8,0x000006d5,0x000200f9,0x000006f5,0x000200f8,0x000006d6,0x000300f7, + 0x000006e0,0x00000000,0x000400fa,0x0000029d,0x000006d7,0x000006e0,0x000200f8,0x000006d7, + 0x0004003d,0x00000024,0x000006d8,0x000005c6,0x0003003e,0x000005ef,0x000000da,0x0004003d, + 0x00000006,0x00000886,0x000005ef,0x00050041,0x00000007,0x00000887,0x00000883,0x000000a3, + 0x0003003e,0x00000887,0x00000886,0x0004003d,0x00000006,0x00000888,0x000005ef,0x00050041, + 0x00000007,0x00000889,0x00000883,0x000000a6,0x0003003e,0x00000889,0x00000888,0x0004003d, + 0x00000006,0x0000088a,0x000005ef,0x00050041,0x00000007,0x0000088b,0x00000883,0x000000b9, + 0x0003003e,0x0000088b,0x0000088a,0x0004003d,0x00000024,0x0000088c,0x00000883,0x0003003e, + 0x00000884,0x0000088c,0x0004003d,0x00000024,0x000006d9,0x00000884,0x0003003e,0x000005f0, + 0x000000d9,0x0004003d,0x00000006,0x00000890,0x000005f0,0x00050041,0x00000007,0x00000891, + 0x0000088d,0x000000a3,0x0003003e,0x00000891,0x00000890,0x0004003d,0x00000006,0x00000892, + 0x000005f0,0x00050041,0x00000007,0x00000893,0x0000088d,0x000000a6,0x0003003e,0x00000893, + 0x00000892,0x0004003d,0x00000006,0x00000894,0x000005f0,0x00050041,0x00000007,0x00000895, + 0x0000088d,0x000000b9,0x0003003e,0x00000895,0x00000894,0x0004003d,0x00000024,0x00000896, + 0x0000088d,0x0003003e,0x0000088e,0x00000896,0x0004003d,0x00000024,0x000006da,0x0000088e, + 0x0008000c,0x00000024,0x000006db,0x00000001,0x0000002b,0x000006d8,0x000006d9,0x000006da, + 0x0003003e,0x000005c6,0x000006db,0x0004003d,0x00000024,0x000006dc,0x000005d6,0x0003003e, + 0x000005f1,0x000006dc,0x0004003d,0x00000024,0x000006dd,0x000005c6,0x0003003e,0x000005f2, + 0x000006dd,0x0004003d,0x00000024,0x000006de,0x000005d6,0x0003003e,0x000005f3,0x000006de, + 0x0004003d,0x00000024,0x000008a2,0x000005f2,0x0003003e,0x00000898,0x000008a2,0x0004003d, + 0x00000024,0x000008ba,0x00000898,0x0007004f,0x0000000c,0x000008bb,0x000008ba,0x000008ba, + 0x00000000,0x00000001,0x0003003e,0x000008b7,0x000008bb,0x00050041,0x00000007,0x000008c2, + 0x000008b7,0x000000a3,0x0004003d,0x00000006,0x000008c3,0x000008c2,0x00050041,0x00000007, + 0x000008c4,0x000008b7,0x000000a6,0x0004003d,0x00000006,0x000008c5,0x000008c4,0x0007000c, + 0x00000006,0x000008c6,0x00000001,0x00000028,0x000008c3,0x000008c5,0x0003003e,0x000008c0, + 0x000008c6,0x0004003d,0x00000006,0x000008bc,0x000008c0,0x00050041,0x00000007,0x000008bd, + 0x00000898,0x000000b9,0x0004003d,0x00000006,0x000008be,0x000008bd,0x0007000c,0x00000006, + 0x000008bf,0x00000001,0x00000028,0x000008bc,0x000008be,0x0003003e,0x000008b8,0x000008bf, + 0x0004003d,0x00000006,0x000008a3,0x000008b8,0x0004003d,0x00000024,0x000008a4,0x000005f2, + 0x0003003e,0x00000899,0x000008a4,0x0004003d,0x00000024,0x000008ca,0x00000899,0x0007004f, + 0x0000000c,0x000008cb,0x000008ca,0x000008ca,0x00000000,0x00000001,0x0003003e,0x000008c7, + 0x000008cb,0x00050041,0x00000007,0x000008d2,0x000008c7,0x000000a3,0x0004003d,0x00000006, + 0x000008d3,0x000008d2,0x00050041,0x00000007,0x000008d4,0x000008c7,0x000000a6,0x0004003d, + 0x00000006,0x000008d5,0x000008d4,0x0007000c,0x00000006,0x000008d6,0x00000001,0x00000025, + 0x000008d3,0x000008d5,0x0003003e,0x000008d0,0x000008d6,0x0004003d,0x00000006,0x000008cc, + 0x000008d0,0x00050041,0x00000007,0x000008cd,0x00000899,0x000000b9,0x0004003d,0x00000006, + 0x000008ce,0x000008cd,0x0007000c,0x00000006,0x000008cf,0x00000001,0x00000025,0x000008cc, + 0x000008ce,0x0003003e,0x000008c8,0x000008cf,0x0004003d,0x00000006,0x000008a5,0x000008c8, + 0x00050083,0x00000006,0x000008a6,0x000008a3,0x000008a5,0x0003003e,0x00000897,0x000008a6, + 0x0004003d,0x00000024,0x000008a7,0x000005f1,0x0003003e,0x0000089a,0x000008a7,0x0004003d, + 0x00000024,0x000008da,0x0000089a,0x0007004f,0x0000000c,0x000008db,0x000008da,0x000008da, + 0x00000000,0x00000001,0x0003003e,0x000008d7,0x000008db,0x00050041,0x00000007,0x000008e2, + 0x000008d7,0x000000a3,0x0004003d,0x00000006,0x000008e3,0x000008e2,0x00050041,0x00000007, + 0x000008e4,0x000008d7,0x000000a6,0x0004003d,0x00000006,0x000008e5,0x000008e4,0x0007000c, + 0x00000006,0x000008e6,0x00000001,0x00000025,0x000008e3,0x000008e5,0x0003003e,0x000008e0, + 0x000008e6,0x0004003d,0x00000006,0x000008dc,0x000008e0,0x00050041,0x00000007,0x000008dd, + 0x0000089a,0x000000b9,0x0004003d,0x00000006,0x000008de,0x000008dd,0x0007000c,0x00000006, + 0x000008df,0x00000001,0x00000025,0x000008dc,0x000008de,0x0003003e,0x000008d8,0x000008df, + 0x0004003d,0x00000006,0x000008a8,0x000008d8,0x0004003d,0x00000024,0x000008a9,0x000005f1, + 0x00060050,0x00000024,0x000008aa,0x000008a8,0x000008a8,0x000008a8,0x00050083,0x00000024, + 0x000008ab,0x000008a9,0x000008aa,0x0003003e,0x000005f1,0x000008ab,0x0004003d,0x00000024, + 0x000008ac,0x000005f1,0x0003003e,0x0000089c,0x000008ac,0x0004003d,0x00000024,0x000008ea, + 0x0000089c,0x0007004f,0x0000000c,0x000008eb,0x000008ea,0x000008ea,0x00000000,0x00000001, + 0x0003003e,0x000008e7,0x000008eb,0x00050041,0x00000007,0x000008f2,0x000008e7,0x000000a3, + 0x0004003d,0x00000006,0x000008f3,0x000008f2,0x00050041,0x00000007,0x000008f4,0x000008e7, + 0x000000a6,0x0004003d,0x00000006,0x000008f5,0x000008f4,0x0007000c,0x00000006,0x000008f6, + 0x00000001,0x00000028,0x000008f3,0x000008f5,0x0003003e,0x000008f0,0x000008f6,0x0004003d, + 0x00000006,0x000008ec,0x000008f0,0x00050041,0x00000007,0x000008ed,0x0000089c,0x000000b9, + 0x0004003d,0x00000006,0x000008ee,0x000008ed,0x0007000c,0x00000006,0x000008ef,0x00000001, + 0x00000028,0x000008ec,0x000008ee,0x0003003e,0x000008e8,0x000008ef,0x0004003d,0x00000006, + 0x000008ad,0x000008e8,0x0003003e,0x0000089b,0x000008ad,0x0004003d,0x00000006,0x000008ae, + 0x00000897,0x0004003d,0x00000006,0x000008af,0x0000089b,0x0007000c,0x00000006,0x000008b0, + 0x00000001,0x00000028,0x0000015c,0x000008af,0x00050088,0x00000006,0x000008b1,0x000008ae, + 0x000008b0,0x0003003e,0x0000089d,0x000008b1,0x0004003d,0x00000024,0x000008b2,0x000005f1, + 0x0004003d,0x00000006,0x000008b3,0x0000089d,0x0005008e,0x00000024,0x000008b4,0x000008b2, + 0x000008b3,0x0003003e,0x0000089e,0x000008b4,0x0004003d,0x00000024,0x000008b5,0x000005f3, + 0x0003003e,0x0000089f,0x000008b5,0x0004003d,0x00000024,0x00000907,0x0000089f,0x0003003e, + 0x000008f8,0x00000907,0x0004003d,0x00000024,0x0000092d,0x000008f8,0x0003003e,0x00000928, + 0x00000140,0x0003003e,0x00000929,0x00000141,0x0003003e,0x0000092a,0x00000142,0x0004003d, + 0x00000006,0x00000933,0x00000928,0x00050041,0x00000007,0x00000934,0x00000930,0x000000a3, + 0x0003003e,0x00000934,0x00000933,0x0004003d,0x00000006,0x00000935,0x00000929,0x00050041, + 0x00000007,0x00000936,0x00000930,0x000000a6,0x0003003e,0x00000936,0x00000935,0x0004003d, + 0x00000006,0x00000937,0x0000092a,0x00050041,0x00000007,0x00000938,0x00000930,0x000000b9, + 0x0003003e,0x00000938,0x00000937,0x0004003d,0x00000024,0x00000939,0x00000930,0x0003003e, + 0x00000931,0x00000939,0x0004003d,0x00000024,0x0000092e,0x00000931,0x00050094,0x00000006, + 0x0000092f,0x0000092d,0x0000092e,0x0003003e,0x0000092b,0x0000092f,0x0004003d,0x00000006, + 0x00000908,0x0000092b,0x0003003e,0x000008f7,0x00000908,0x0004003d,0x00000024,0x00000909, + 0x0000089e,0x0004003d,0x00000024,0x0000090a,0x0000089e,0x0003003e,0x000008fa,0x0000090a, + 0x0004003d,0x00000024,0x0000093f,0x000008fa,0x0003003e,0x0000093a,0x00000140,0x0003003e, + 0x0000093b,0x00000141,0x0003003e,0x0000093c,0x00000142,0x0004003d,0x00000006,0x00000945, + 0x0000093a,0x00050041,0x00000007,0x00000946,0x00000942,0x000000a3,0x0003003e,0x00000946, + 0x00000945,0x0004003d,0x00000006,0x00000947,0x0000093b,0x00050041,0x00000007,0x00000948, + 0x00000942,0x000000a6,0x0003003e,0x00000948,0x00000947,0x0004003d,0x00000006,0x00000949, + 0x0000093c,0x00050041,0x00000007,0x0000094a,0x00000942,0x000000b9,0x0003003e,0x0000094a, + 0x00000949,0x0004003d,0x00000024,0x0000094b,0x00000942,0x0003003e,0x00000943,0x0000094b, + 0x0004003d,0x00000024,0x00000940,0x00000943,0x00050094,0x00000006,0x00000941,0x0000093f, + 0x00000940,0x0003003e,0x0000093d,0x00000941,0x0004003d,0x00000006,0x0000090b,0x0000093d, + 0x00060050,0x00000024,0x0000090c,0x0000090b,0x0000090b,0x0000090b,0x00050083,0x00000024, + 0x0000090d,0x00000909,0x0000090c,0x0003003e,0x000008f9,0x0000090d,0x0004003d,0x00000006, + 0x0000090e,0x000008f7,0x00050083,0x00000006,0x0000090f,0x000000d9,0x0000090e,0x0004003d, + 0x00000006,0x00000910,0x000008f7,0x0003003e,0x000008fc,0x00000910,0x0003003e,0x000008fd, + 0x0000090f,0x0004003d,0x00000006,0x0000094f,0x000008fc,0x00050041,0x00000007,0x00000950, + 0x0000094c,0x000000a3,0x0003003e,0x00000950,0x0000094f,0x0004003d,0x00000006,0x00000951, + 0x000008fd,0x00050041,0x00000007,0x00000952,0x0000094c,0x000000a6,0x0003003e,0x00000952, + 0x00000951,0x0004003d,0x0000000c,0x00000953,0x0000094c,0x0003003e,0x0000094d,0x00000953, + 0x0004003d,0x0000000c,0x00000911,0x0000094d,0x0003003e,0x000008fe,0x0000015c,0x0004003d, + 0x00000006,0x00000957,0x000008fe,0x00050041,0x00000007,0x00000958,0x00000954,0x000000a3, + 0x0003003e,0x00000958,0x00000957,0x0004003d,0x00000006,0x00000959,0x000008fe,0x00050041, + 0x00000007,0x0000095a,0x00000954,0x000000a6,0x0003003e,0x0000095a,0x00000959,0x0004003d, + 0x0000000c,0x0000095b,0x00000954,0x0003003e,0x00000955,0x0000095b,0x0004003d,0x0000000c, + 0x00000912,0x00000955,0x0004003d,0x00000024,0x00000913,0x000008f9,0x0003003e,0x000008ff, + 0x00000913,0x0004003d,0x00000024,0x0000095f,0x000008ff,0x0007004f,0x0000000c,0x00000960, + 0x0000095f,0x0000095f,0x00000000,0x00000001,0x0003003e,0x0000095c,0x00000960,0x00050041, + 0x00000007,0x00000967,0x0000095c,0x000000a3,0x0004003d,0x00000006,0x00000968,0x00000967, + 0x00050041,0x00000007,0x00000969,0x0000095c,0x000000a6,0x0004003d,0x00000006,0x0000096a, + 0x00000969,0x0007000c,0x00000006,0x0000096b,0x00000001,0x00000025,0x00000968,0x0000096a, + 0x0003003e,0x00000965,0x0000096b,0x0004003d,0x00000006,0x00000961,0x00000965,0x00050041, + 0x00000007,0x00000962,0x000008ff,0x000000b9,0x0004003d,0x00000006,0x00000963,0x00000962, + 0x0007000c,0x00000006,0x00000964,0x00000001,0x00000025,0x00000961,0x00000963,0x0003003e, + 0x0000095d,0x00000964,0x0004003d,0x00000006,0x00000914,0x0000095d,0x0004007f,0x00000006, + 0x00000915,0x00000914,0x0004003d,0x00000024,0x00000916,0x000008f9,0x0003003e,0x00000900, + 0x00000916,0x0004003d,0x00000024,0x0000096f,0x00000900,0x0007004f,0x0000000c,0x00000970, + 0x0000096f,0x0000096f,0x00000000,0x00000001,0x0003003e,0x0000096c,0x00000970,0x00050041, + 0x00000007,0x00000977,0x0000096c,0x000000a3,0x0004003d,0x00000006,0x00000978,0x00000977, + 0x00050041,0x00000007,0x00000979,0x0000096c,0x000000a6,0x0004003d,0x00000006,0x0000097a, + 0x00000979,0x0007000c,0x00000006,0x0000097b,0x00000001,0x00000028,0x00000978,0x0000097a, + 0x0003003e,0x00000975,0x0000097b,0x0004003d,0x00000006,0x00000971,0x00000975,0x00050041, + 0x00000007,0x00000972,0x00000900,0x000000b9,0x0004003d,0x00000006,0x00000973,0x00000972, + 0x0007000c,0x00000006,0x00000974,0x00000001,0x00000028,0x00000971,0x00000973,0x0003003e, + 0x0000096d,0x00000974,0x0004003d,0x00000006,0x00000917,0x0000096d,0x0003003e,0x00000901, + 0x00000915,0x0003003e,0x00000902,0x00000917,0x0004003d,0x00000006,0x0000097f,0x00000901, + 0x00050041,0x00000007,0x00000980,0x0000097c,0x000000a3,0x0003003e,0x00000980,0x0000097f, + 0x0004003d,0x00000006,0x00000981,0x00000902,0x00050041,0x00000007,0x00000982,0x0000097c, + 0x000000a6,0x0003003e,0x00000982,0x00000981,0x0004003d,0x0000000c,0x00000983,0x0000097c, + 0x0003003e,0x0000097d,0x00000983,0x0004003d,0x0000000c,0x00000918,0x0000097d,0x0007000c, + 0x0000000c,0x00000919,0x00000001,0x00000028,0x00000912,0x00000918,0x00050088,0x0000000c, + 0x0000091a,0x00000911,0x00000919,0x0003003e,0x000008fb,0x0000091a,0x0003003e,0x00000904, + 0x000000d9,0x0004003d,0x00000006,0x00000986,0x00000904,0x0003003e,0x00000984,0x00000986, + 0x0004003d,0x00000006,0x0000091b,0x00000984,0x00050041,0x00000007,0x0000091c,0x000008fb, + 0x000000a3,0x0004003d,0x00000006,0x0000091d,0x0000091c,0x00050041,0x00000007,0x0000091e, + 0x000008fb,0x000000a6,0x0004003d,0x00000006,0x0000091f,0x0000091e,0x0007000c,0x00000006, + 0x00000920,0x00000001,0x00000025,0x0000091d,0x0000091f,0x0007000c,0x00000006,0x00000921, + 0x00000001,0x00000025,0x0000091b,0x00000920,0x0003003e,0x00000903,0x00000921,0x0004003d, + 0x00000024,0x00000922,0x000008f9,0x0004003d,0x00000006,0x00000923,0x00000903,0x0005008e, + 0x00000024,0x00000924,0x00000922,0x00000923,0x0004003d,0x00000006,0x00000925,0x000008f7, + 0x00060050,0x00000024,0x00000926,0x00000925,0x00000925,0x00000925,0x00050081,0x00000024, + 0x00000927,0x00000924,0x00000926,0x0003003e,0x00000905,0x00000927,0x0004003d,0x00000024, + 0x000008b6,0x00000905,0x0003003e,0x000008a0,0x000008b6,0x0004003d,0x00000024,0x000006df, + 0x000008a0,0x0003003e,0x000005d8,0x000006df,0x000200f9,0x000006e0,0x000200f8,0x000006e0, + 0x000200f9,0x000006f5,0x000200f8,0x000006e1,0x000300f7,0x000006ea,0x00000000,0x000400fa, + 0x0000029d,0x000006e2,0x000006ea,0x000200f8,0x000006e2,0x0004003d,0x00000024,0x000006e3, + 0x000005c6,0x0003003e,0x000005f4,0x000000da,0x0004003d,0x00000006,0x0000098a,0x000005f4, + 0x00050041,0x00000007,0x0000098b,0x00000987,0x000000a3,0x0003003e,0x0000098b,0x0000098a, + 0x0004003d,0x00000006,0x0000098c,0x000005f4,0x00050041,0x00000007,0x0000098d,0x00000987, + 0x000000a6,0x0003003e,0x0000098d,0x0000098c,0x0004003d,0x00000006,0x0000098e,0x000005f4, + 0x00050041,0x00000007,0x0000098f,0x00000987,0x000000b9,0x0003003e,0x0000098f,0x0000098e, + 0x0004003d,0x00000024,0x00000990,0x00000987,0x0003003e,0x00000988,0x00000990,0x0004003d, + 0x00000024,0x000006e4,0x00000988,0x0003003e,0x000005f5,0x000000d9,0x0004003d,0x00000006, + 0x00000994,0x000005f5,0x00050041,0x00000007,0x00000995,0x00000991,0x000000a3,0x0003003e, + 0x00000995,0x00000994,0x0004003d,0x00000006,0x00000996,0x000005f5,0x00050041,0x00000007, + 0x00000997,0x00000991,0x000000a6,0x0003003e,0x00000997,0x00000996,0x0004003d,0x00000006, + 0x00000998,0x000005f5,0x00050041,0x00000007,0x00000999,0x00000991,0x000000b9,0x0003003e, + 0x00000999,0x00000998,0x0004003d,0x00000024,0x0000099a,0x00000991,0x0003003e,0x00000992, + 0x0000099a,0x0004003d,0x00000024,0x000006e5,0x00000992,0x0008000c,0x00000024,0x000006e6, + 0x00000001,0x0000002b,0x000006e3,0x000006e4,0x000006e5,0x0003003e,0x000005c6,0x000006e6, + 0x0004003d,0x00000024,0x000006e7,0x000005c6,0x0003003e,0x000005f6,0x000006e7,0x0004003d, + 0x00000024,0x000006e8,0x000005d6,0x0003003e,0x000005f7,0x000006e8,0x0004003d,0x00000024, + 0x000009ab,0x000005f7,0x0003003e,0x0000099c,0x000009ab,0x0004003d,0x00000024,0x000009d1, + 0x0000099c,0x0003003e,0x000009cc,0x00000140,0x0003003e,0x000009cd,0x00000141,0x0003003e, + 0x000009ce,0x00000142,0x0004003d,0x00000006,0x000009d7,0x000009cc,0x00050041,0x00000007, + 0x000009d8,0x000009d4,0x000000a3,0x0003003e,0x000009d8,0x000009d7,0x0004003d,0x00000006, + 0x000009d9,0x000009cd,0x00050041,0x00000007,0x000009da,0x000009d4,0x000000a6,0x0003003e, + 0x000009da,0x000009d9,0x0004003d,0x00000006,0x000009db,0x000009ce,0x00050041,0x00000007, + 0x000009dc,0x000009d4,0x000000b9,0x0003003e,0x000009dc,0x000009db,0x0004003d,0x00000024, + 0x000009dd,0x000009d4,0x0003003e,0x000009d5,0x000009dd,0x0004003d,0x00000024,0x000009d2, + 0x000009d5,0x00050094,0x00000006,0x000009d3,0x000009d1,0x000009d2,0x0003003e,0x000009cf, + 0x000009d3,0x0004003d,0x00000006,0x000009ac,0x000009cf,0x0003003e,0x0000099b,0x000009ac, + 0x0004003d,0x00000024,0x000009ad,0x000005f6,0x0004003d,0x00000024,0x000009ae,0x000005f6, + 0x0003003e,0x0000099e,0x000009ae,0x0004003d,0x00000024,0x000009e3,0x0000099e,0x0003003e, + 0x000009de,0x00000140,0x0003003e,0x000009df,0x00000141,0x0003003e,0x000009e0,0x00000142, + 0x0004003d,0x00000006,0x000009e9,0x000009de,0x00050041,0x00000007,0x000009ea,0x000009e6, + 0x000000a3,0x0003003e,0x000009ea,0x000009e9,0x0004003d,0x00000006,0x000009eb,0x000009df, + 0x00050041,0x00000007,0x000009ec,0x000009e6,0x000000a6,0x0003003e,0x000009ec,0x000009eb, + 0x0004003d,0x00000006,0x000009ed,0x000009e0,0x00050041,0x00000007,0x000009ee,0x000009e6, + 0x000000b9,0x0003003e,0x000009ee,0x000009ed,0x0004003d,0x00000024,0x000009ef,0x000009e6, + 0x0003003e,0x000009e7,0x000009ef,0x0004003d,0x00000024,0x000009e4,0x000009e7,0x00050094, + 0x00000006,0x000009e5,0x000009e3,0x000009e4,0x0003003e,0x000009e1,0x000009e5,0x0004003d, + 0x00000006,0x000009af,0x000009e1,0x00060050,0x00000024,0x000009b0,0x000009af,0x000009af, + 0x000009af,0x00050083,0x00000024,0x000009b1,0x000009ad,0x000009b0,0x0003003e,0x0000099d, + 0x000009b1,0x0004003d,0x00000006,0x000009b2,0x0000099b,0x00050083,0x00000006,0x000009b3, + 0x000000d9,0x000009b2,0x0004003d,0x00000006,0x000009b4,0x0000099b,0x0003003e,0x000009a0, + 0x000009b4,0x0003003e,0x000009a1,0x000009b3,0x0004003d,0x00000006,0x000009f3,0x000009a0, + 0x00050041,0x00000007,0x000009f4,0x000009f0,0x000000a3,0x0003003e,0x000009f4,0x000009f3, + 0x0004003d,0x00000006,0x000009f5,0x000009a1,0x00050041,0x00000007,0x000009f6,0x000009f0, + 0x000000a6,0x0003003e,0x000009f6,0x000009f5,0x0004003d,0x0000000c,0x000009f7,0x000009f0, + 0x0003003e,0x000009f1,0x000009f7,0x0004003d,0x0000000c,0x000009b5,0x000009f1,0x0003003e, + 0x000009a2,0x0000015c,0x0004003d,0x00000006,0x000009fb,0x000009a2,0x00050041,0x00000007, + 0x000009fc,0x000009f8,0x000000a3,0x0003003e,0x000009fc,0x000009fb,0x0004003d,0x00000006, + 0x000009fd,0x000009a2,0x00050041,0x00000007,0x000009fe,0x000009f8,0x000000a6,0x0003003e, + 0x000009fe,0x000009fd,0x0004003d,0x0000000c,0x000009ff,0x000009f8,0x0003003e,0x000009f9, + 0x000009ff,0x0004003d,0x0000000c,0x000009b6,0x000009f9,0x0004003d,0x00000024,0x000009b7, + 0x0000099d,0x0003003e,0x000009a3,0x000009b7,0x0004003d,0x00000024,0x00000a03,0x000009a3, + 0x0007004f,0x0000000c,0x00000a04,0x00000a03,0x00000a03,0x00000000,0x00000001,0x0003003e, + 0x00000a00,0x00000a04,0x00050041,0x00000007,0x00000a0b,0x00000a00,0x000000a3,0x0004003d, + 0x00000006,0x00000a0c,0x00000a0b,0x00050041,0x00000007,0x00000a0d,0x00000a00,0x000000a6, + 0x0004003d,0x00000006,0x00000a0e,0x00000a0d,0x0007000c,0x00000006,0x00000a0f,0x00000001, + 0x00000025,0x00000a0c,0x00000a0e,0x0003003e,0x00000a09,0x00000a0f,0x0004003d,0x00000006, + 0x00000a05,0x00000a09,0x00050041,0x00000007,0x00000a06,0x000009a3,0x000000b9,0x0004003d, + 0x00000006,0x00000a07,0x00000a06,0x0007000c,0x00000006,0x00000a08,0x00000001,0x00000025, + 0x00000a05,0x00000a07,0x0003003e,0x00000a01,0x00000a08,0x0004003d,0x00000006,0x000009b8, + 0x00000a01,0x0004007f,0x00000006,0x000009b9,0x000009b8,0x0004003d,0x00000024,0x000009ba, + 0x0000099d,0x0003003e,0x000009a4,0x000009ba,0x0004003d,0x00000024,0x00000a13,0x000009a4, + 0x0007004f,0x0000000c,0x00000a14,0x00000a13,0x00000a13,0x00000000,0x00000001,0x0003003e, + 0x00000a10,0x00000a14,0x00050041,0x00000007,0x00000a1b,0x00000a10,0x000000a3,0x0004003d, + 0x00000006,0x00000a1c,0x00000a1b,0x00050041,0x00000007,0x00000a1d,0x00000a10,0x000000a6, + 0x0004003d,0x00000006,0x00000a1e,0x00000a1d,0x0007000c,0x00000006,0x00000a1f,0x00000001, + 0x00000028,0x00000a1c,0x00000a1e,0x0003003e,0x00000a19,0x00000a1f,0x0004003d,0x00000006, + 0x00000a15,0x00000a19,0x00050041,0x00000007,0x00000a16,0x000009a4,0x000000b9,0x0004003d, + 0x00000006,0x00000a17,0x00000a16,0x0007000c,0x00000006,0x00000a18,0x00000001,0x00000028, + 0x00000a15,0x00000a17,0x0003003e,0x00000a11,0x00000a18,0x0004003d,0x00000006,0x000009bb, + 0x00000a11,0x0003003e,0x000009a5,0x000009b9,0x0003003e,0x000009a6,0x000009bb,0x0004003d, + 0x00000006,0x00000a23,0x000009a5,0x00050041,0x00000007,0x00000a24,0x00000a20,0x000000a3, + 0x0003003e,0x00000a24,0x00000a23,0x0004003d,0x00000006,0x00000a25,0x000009a6,0x00050041, + 0x00000007,0x00000a26,0x00000a20,0x000000a6,0x0003003e,0x00000a26,0x00000a25,0x0004003d, + 0x0000000c,0x00000a27,0x00000a20,0x0003003e,0x00000a21,0x00000a27,0x0004003d,0x0000000c, + 0x000009bc,0x00000a21,0x0007000c,0x0000000c,0x000009bd,0x00000001,0x00000028,0x000009b6, + 0x000009bc,0x00050088,0x0000000c,0x000009be,0x000009b5,0x000009bd,0x0003003e,0x0000099f, + 0x000009be,0x0003003e,0x000009a8,0x000000d9,0x0004003d,0x00000006,0x00000a2a,0x000009a8, + 0x0003003e,0x00000a28,0x00000a2a,0x0004003d,0x00000006,0x000009bf,0x00000a28,0x00050041, + 0x00000007,0x000009c0,0x0000099f,0x000000a3,0x0004003d,0x00000006,0x000009c1,0x000009c0, + 0x00050041,0x00000007,0x000009c2,0x0000099f,0x000000a6,0x0004003d,0x00000006,0x000009c3, + 0x000009c2,0x0007000c,0x00000006,0x000009c4,0x00000001,0x00000025,0x000009c1,0x000009c3, + 0x0007000c,0x00000006,0x000009c5,0x00000001,0x00000025,0x000009bf,0x000009c4,0x0003003e, + 0x000009a7,0x000009c5,0x0004003d,0x00000024,0x000009c6,0x0000099d,0x0004003d,0x00000006, + 0x000009c7,0x000009a7,0x0005008e,0x00000024,0x000009c8,0x000009c6,0x000009c7,0x0004003d, + 0x00000006,0x000009c9,0x0000099b,0x00060050,0x00000024,0x000009ca,0x000009c9,0x000009c9, + 0x000009c9,0x00050081,0x00000024,0x000009cb,0x000009c8,0x000009ca,0x0003003e,0x000009a9, + 0x000009cb,0x0004003d,0x00000024,0x000006e9,0x000009a9,0x0003003e,0x000005d8,0x000006e9, + 0x000200f9,0x000006ea,0x000200f8,0x000006ea,0x000200f9,0x000006f5,0x000200f8,0x000006eb, + 0x000300f7,0x000006f4,0x00000000,0x000400fa,0x0000029d,0x000006ec,0x000006f4,0x000200f8, + 0x000006ec,0x0004003d,0x00000024,0x000006ed,0x000005c6,0x0003003e,0x000005f8,0x000000da, + 0x0004003d,0x00000006,0x00000a2e,0x000005f8,0x00050041,0x00000007,0x00000a2f,0x00000a2b, + 0x000000a3,0x0003003e,0x00000a2f,0x00000a2e,0x0004003d,0x00000006,0x00000a30,0x000005f8, + 0x00050041,0x00000007,0x00000a31,0x00000a2b,0x000000a6,0x0003003e,0x00000a31,0x00000a30, + 0x0004003d,0x00000006,0x00000a32,0x000005f8,0x00050041,0x00000007,0x00000a33,0x00000a2b, + 0x000000b9,0x0003003e,0x00000a33,0x00000a32,0x0004003d,0x00000024,0x00000a34,0x00000a2b, + 0x0003003e,0x00000a2c,0x00000a34,0x0004003d,0x00000024,0x000006ee,0x00000a2c,0x0003003e, + 0x000005f9,0x000000d9,0x0004003d,0x00000006,0x00000a38,0x000005f9,0x00050041,0x00000007, + 0x00000a39,0x00000a35,0x000000a3,0x0003003e,0x00000a39,0x00000a38,0x0004003d,0x00000006, + 0x00000a3a,0x000005f9,0x00050041,0x00000007,0x00000a3b,0x00000a35,0x000000a6,0x0003003e, + 0x00000a3b,0x00000a3a,0x0004003d,0x00000006,0x00000a3c,0x000005f9,0x00050041,0x00000007, + 0x00000a3d,0x00000a35,0x000000b9,0x0003003e,0x00000a3d,0x00000a3c,0x0004003d,0x00000024, + 0x00000a3e,0x00000a35,0x0003003e,0x00000a36,0x00000a3e,0x0004003d,0x00000024,0x000006ef, + 0x00000a36,0x0008000c,0x00000024,0x000006f0,0x00000001,0x0000002b,0x000006ed,0x000006ee, + 0x000006ef,0x0003003e,0x000005c6,0x000006f0,0x0004003d,0x00000024,0x000006f1,0x000005d6, + 0x0003003e,0x000005fa,0x000006f1,0x0004003d,0x00000024,0x000006f2,0x000005c6,0x0003003e, + 0x000005fb,0x000006f2,0x0004003d,0x00000024,0x00000a4f,0x000005fb,0x0003003e,0x00000a40, + 0x00000a4f,0x0004003d,0x00000024,0x00000a75,0x00000a40,0x0003003e,0x00000a70,0x00000140, + 0x0003003e,0x00000a71,0x00000141,0x0003003e,0x00000a72,0x00000142,0x0004003d,0x00000006, + 0x00000a7b,0x00000a70,0x00050041,0x00000007,0x00000a7c,0x00000a78,0x000000a3,0x0003003e, + 0x00000a7c,0x00000a7b,0x0004003d,0x00000006,0x00000a7d,0x00000a71,0x00050041,0x00000007, + 0x00000a7e,0x00000a78,0x000000a6,0x0003003e,0x00000a7e,0x00000a7d,0x0004003d,0x00000006, + 0x00000a7f,0x00000a72,0x00050041,0x00000007,0x00000a80,0x00000a78,0x000000b9,0x0003003e, + 0x00000a80,0x00000a7f,0x0004003d,0x00000024,0x00000a81,0x00000a78,0x0003003e,0x00000a79, + 0x00000a81,0x0004003d,0x00000024,0x00000a76,0x00000a79,0x00050094,0x00000006,0x00000a77, + 0x00000a75,0x00000a76,0x0003003e,0x00000a73,0x00000a77,0x0004003d,0x00000006,0x00000a50, + 0x00000a73,0x0003003e,0x00000a3f,0x00000a50,0x0004003d,0x00000024,0x00000a51,0x000005fa, + 0x0004003d,0x00000024,0x00000a52,0x000005fa,0x0003003e,0x00000a42,0x00000a52,0x0004003d, + 0x00000024,0x00000a87,0x00000a42,0x0003003e,0x00000a82,0x00000140,0x0003003e,0x00000a83, + 0x00000141,0x0003003e,0x00000a84,0x00000142,0x0004003d,0x00000006,0x00000a8d,0x00000a82, + 0x00050041,0x00000007,0x00000a8e,0x00000a8a,0x000000a3,0x0003003e,0x00000a8e,0x00000a8d, + 0x0004003d,0x00000006,0x00000a8f,0x00000a83,0x00050041,0x00000007,0x00000a90,0x00000a8a, + 0x000000a6,0x0003003e,0x00000a90,0x00000a8f,0x0004003d,0x00000006,0x00000a91,0x00000a84, + 0x00050041,0x00000007,0x00000a92,0x00000a8a,0x000000b9,0x0003003e,0x00000a92,0x00000a91, + 0x0004003d,0x00000024,0x00000a93,0x00000a8a,0x0003003e,0x00000a8b,0x00000a93,0x0004003d, + 0x00000024,0x00000a88,0x00000a8b,0x00050094,0x00000006,0x00000a89,0x00000a87,0x00000a88, + 0x0003003e,0x00000a85,0x00000a89,0x0004003d,0x00000006,0x00000a53,0x00000a85,0x00060050, + 0x00000024,0x00000a54,0x00000a53,0x00000a53,0x00000a53,0x00050083,0x00000024,0x00000a55, + 0x00000a51,0x00000a54,0x0003003e,0x00000a41,0x00000a55,0x0004003d,0x00000006,0x00000a56, + 0x00000a3f,0x00050083,0x00000006,0x00000a57,0x000000d9,0x00000a56,0x0004003d,0x00000006, + 0x00000a58,0x00000a3f,0x0003003e,0x00000a44,0x00000a58,0x0003003e,0x00000a45,0x00000a57, + 0x0004003d,0x00000006,0x00000a97,0x00000a44,0x00050041,0x00000007,0x00000a98,0x00000a94, + 0x000000a3,0x0003003e,0x00000a98,0x00000a97,0x0004003d,0x00000006,0x00000a99,0x00000a45, + 0x00050041,0x00000007,0x00000a9a,0x00000a94,0x000000a6,0x0003003e,0x00000a9a,0x00000a99, + 0x0004003d,0x0000000c,0x00000a9b,0x00000a94,0x0003003e,0x00000a95,0x00000a9b,0x0004003d, + 0x0000000c,0x00000a59,0x00000a95,0x0003003e,0x00000a46,0x0000015c,0x0004003d,0x00000006, + 0x00000a9f,0x00000a46,0x00050041,0x00000007,0x00000aa0,0x00000a9c,0x000000a3,0x0003003e, + 0x00000aa0,0x00000a9f,0x0004003d,0x00000006,0x00000aa1,0x00000a46,0x00050041,0x00000007, + 0x00000aa2,0x00000a9c,0x000000a6,0x0003003e,0x00000aa2,0x00000aa1,0x0004003d,0x0000000c, + 0x00000aa3,0x00000a9c,0x0003003e,0x00000a9d,0x00000aa3,0x0004003d,0x0000000c,0x00000a5a, + 0x00000a9d,0x0004003d,0x00000024,0x00000a5b,0x00000a41,0x0003003e,0x00000a47,0x00000a5b, + 0x0004003d,0x00000024,0x00000aa7,0x00000a47,0x0007004f,0x0000000c,0x00000aa8,0x00000aa7, + 0x00000aa7,0x00000000,0x00000001,0x0003003e,0x00000aa4,0x00000aa8,0x00050041,0x00000007, + 0x00000aaf,0x00000aa4,0x000000a3,0x0004003d,0x00000006,0x00000ab0,0x00000aaf,0x00050041, + 0x00000007,0x00000ab1,0x00000aa4,0x000000a6,0x0004003d,0x00000006,0x00000ab2,0x00000ab1, + 0x0007000c,0x00000006,0x00000ab3,0x00000001,0x00000025,0x00000ab0,0x00000ab2,0x0003003e, + 0x00000aad,0x00000ab3,0x0004003d,0x00000006,0x00000aa9,0x00000aad,0x00050041,0x00000007, + 0x00000aaa,0x00000a47,0x000000b9,0x0004003d,0x00000006,0x00000aab,0x00000aaa,0x0007000c, + 0x00000006,0x00000aac,0x00000001,0x00000025,0x00000aa9,0x00000aab,0x0003003e,0x00000aa5, + 0x00000aac,0x0004003d,0x00000006,0x00000a5c,0x00000aa5,0x0004007f,0x00000006,0x00000a5d, + 0x00000a5c,0x0004003d,0x00000024,0x00000a5e,0x00000a41,0x0003003e,0x00000a48,0x00000a5e, + 0x0004003d,0x00000024,0x00000ab7,0x00000a48,0x0007004f,0x0000000c,0x00000ab8,0x00000ab7, + 0x00000ab7,0x00000000,0x00000001,0x0003003e,0x00000ab4,0x00000ab8,0x00050041,0x00000007, + 0x00000abf,0x00000ab4,0x000000a3,0x0004003d,0x00000006,0x00000ac0,0x00000abf,0x00050041, + 0x00000007,0x00000ac1,0x00000ab4,0x000000a6,0x0004003d,0x00000006,0x00000ac2,0x00000ac1, + 0x0007000c,0x00000006,0x00000ac3,0x00000001,0x00000028,0x00000ac0,0x00000ac2,0x0003003e, + 0x00000abd,0x00000ac3,0x0004003d,0x00000006,0x00000ab9,0x00000abd,0x00050041,0x00000007, + 0x00000aba,0x00000a48,0x000000b9,0x0004003d,0x00000006,0x00000abb,0x00000aba,0x0007000c, + 0x00000006,0x00000abc,0x00000001,0x00000028,0x00000ab9,0x00000abb,0x0003003e,0x00000ab5, + 0x00000abc,0x0004003d,0x00000006,0x00000a5f,0x00000ab5,0x0003003e,0x00000a49,0x00000a5d, + 0x0003003e,0x00000a4a,0x00000a5f,0x0004003d,0x00000006,0x00000ac7,0x00000a49,0x00050041, + 0x00000007,0x00000ac8,0x00000ac4,0x000000a3,0x0003003e,0x00000ac8,0x00000ac7,0x0004003d, + 0x00000006,0x00000ac9,0x00000a4a,0x00050041,0x00000007,0x00000aca,0x00000ac4,0x000000a6, + 0x0003003e,0x00000aca,0x00000ac9,0x0004003d,0x0000000c,0x00000acb,0x00000ac4,0x0003003e, + 0x00000ac5,0x00000acb,0x0004003d,0x0000000c,0x00000a60,0x00000ac5,0x0007000c,0x0000000c, + 0x00000a61,0x00000001,0x00000028,0x00000a5a,0x00000a60,0x00050088,0x0000000c,0x00000a62, + 0x00000a59,0x00000a61,0x0003003e,0x00000a43,0x00000a62,0x0003003e,0x00000a4c,0x000000d9, + 0x0004003d,0x00000006,0x00000ace,0x00000a4c,0x0003003e,0x00000acc,0x00000ace,0x0004003d, + 0x00000006,0x00000a63,0x00000acc,0x00050041,0x00000007,0x00000a64,0x00000a43,0x000000a3, + 0x0004003d,0x00000006,0x00000a65,0x00000a64,0x00050041,0x00000007,0x00000a66,0x00000a43, + 0x000000a6,0x0004003d,0x00000006,0x00000a67,0x00000a66,0x0007000c,0x00000006,0x00000a68, + 0x00000001,0x00000025,0x00000a65,0x00000a67,0x0007000c,0x00000006,0x00000a69,0x00000001, + 0x00000025,0x00000a63,0x00000a68,0x0003003e,0x00000a4b,0x00000a69,0x0004003d,0x00000024, + 0x00000a6a,0x00000a41,0x0004003d,0x00000006,0x00000a6b,0x00000a4b,0x0005008e,0x00000024, + 0x00000a6c,0x00000a6a,0x00000a6b,0x0004003d,0x00000006,0x00000a6d,0x00000a3f,0x00060050, + 0x00000024,0x00000a6e,0x00000a6d,0x00000a6d,0x00000a6d,0x00050081,0x00000024,0x00000a6f, + 0x00000a6c,0x00000a6e,0x0003003e,0x00000a4d,0x00000a6f,0x0004003d,0x00000024,0x000006f3, + 0x00000a4d,0x0003003e,0x000005d8,0x000006f3,0x000200f9,0x000006f4,0x000200f8,0x000006f4, + 0x000200f9,0x000006f5,0x000200f8,0x000006f5,0x0004003d,0x00000024,0x000006f6,0x000005d8, + 0x0003003e,0x000005fc,0x000006f6,0x0004003d,0x00000024,0x000005cf,0x000005fc,0x0003003e, + 0x000005c5,0x000005cf,0x0004003d,0x00000024,0x000005d0,0x000004a6,0x0004003d,0x00000024, + 0x000005d1,0x000005c5,0x00050041,0x00000007,0x000005d2,0x000004a7,0x000000d0,0x0004003d, + 0x00000006,0x000005d3,0x000005d2,0x0003003e,0x000005c9,0x000005d3,0x0004003d,0x00000006, + 0x00000ad2,0x000005c9,0x00050041,0x00000007,0x00000ad3,0x00000acf,0x000000a3,0x0003003e, + 0x00000ad3,0x00000ad2,0x0004003d,0x00000006,0x00000ad4,0x000005c9,0x00050041,0x00000007, + 0x00000ad5,0x00000acf,0x000000a6,0x0003003e,0x00000ad5,0x00000ad4,0x0004003d,0x00000006, + 0x00000ad6,0x000005c9,0x00050041,0x00000007,0x00000ad7,0x00000acf,0x000000b9,0x0003003e, + 0x00000ad7,0x00000ad6,0x0004003d,0x00000024,0x00000ad8,0x00000acf,0x0003003e,0x00000ad0, + 0x00000ad8,0x0004003d,0x00000024,0x000005d4,0x00000ad0,0x0008000c,0x00000024,0x000005d5, + 0x00000001,0x0000002e,0x000005d0,0x000005d1,0x000005d4,0x0003003e,0x000005ca,0x000005d5, + 0x0004003d,0x00000024,0x00000561,0x000005ca,0x00050041,0x00000007,0x00000562,0x00000445, + 0x000000a3,0x00050051,0x00000006,0x00000563,0x00000561,0x00000000,0x0003003e,0x00000562, + 0x00000563,0x00050041,0x00000007,0x00000564,0x00000445,0x000000a6,0x00050051,0x00000006, + 0x00000565,0x00000561,0x00000001,0x0003003e,0x00000564,0x00000565,0x00050041,0x00000007, + 0x00000566,0x00000445,0x000000b9,0x00050051,0x00000006,0x00000567,0x00000561,0x00000002, + 0x0003003e,0x00000566,0x00000567,0x000200f9,0x00000568,0x000200f8,0x00000568,0x0004003d, + 0x00000006,0x0000056a,0x00000547,0x0004003d,0x0000002f,0x0000056b,0x00000445,0x0008004f, + 0x00000024,0x0000056c,0x0000056b,0x0000056b,0x00000000,0x00000001,0x00000002,0x0005008e, + 0x00000024,0x0000056d,0x0000056c,0x0000056a,0x00050041,0x00000007,0x0000056e,0x00000445, + 0x000000a3,0x00050051,0x00000006,0x0000056f,0x0000056d,0x00000000,0x0003003e,0x0000056e, + 0x0000056f,0x00050041,0x00000007,0x00000570,0x00000445,0x000000a6,0x00050051,0x00000006, + 0x00000571,0x0000056d,0x00000001,0x0003003e,0x00000570,0x00000571,0x00050041,0x00000007, + 0x00000572,0x00000445,0x000000b9,0x00050051,0x00000006,0x00000573,0x0000056d,0x00000002, + 0x0003003e,0x00000572,0x00000573,0x0004003d,0x0000002f,0x00000449,0x00000445,0x0003003e, + 0x00000440,0x00000449,0x0004003d,0x0000002f,0x00000451,0x00000440,0x0008004f,0x00000024, + 0x00000452,0x00000451,0x00000451,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000450, + 0x00000452,0x0003003e,0x00000453,0x00000425,0x00050041,0x00000457,0x00000458,0x0000044d, + 0x000000a3,0x0004003d,0x00000006,0x00000459,0x00000458,0x0003003e,0x00000456,0x00000459, + 0x00050041,0x00000457,0x0000045b,0x0000044d,0x000000a6,0x0004003d,0x00000006,0x0000045c, + 0x0000045b,0x0003003e,0x0000045a,0x0000045c,0x000300f7,0x00000ae9,0x00000000,0x000400fa, + 0x0000012c,0x00000adf,0x00000ae7,0x000200f8,0x00000adf,0x0004003d,0x0000000c,0x00000ae0, + 0x00000453,0x0003003e,0x00000ada,0x00000ae0,0x0004003d,0x00000006,0x00000ae1,0x00000456, + 0x0003003e,0x00000adb,0x00000ae1,0x0004003d,0x00000006,0x00000ae2,0x0000045a,0x0003003e, + 0x00000adc,0x00000ae2,0x00050041,0x00000007,0x00000aef,0x00000ada,0x000000a3,0x0004003d, + 0x00000006,0x00000af0,0x00000aef,0x00050085,0x00000006,0x00000af1,0x00000116,0x00000af0, + 0x00050041,0x00000007,0x00000af2,0x00000ada,0x000000a6,0x0004003d,0x00000006,0x00000af3, + 0x00000af2,0x00050085,0x00000006,0x00000af4,0x0000011a,0x00000af3,0x00050081,0x00000006, + 0x00000af5,0x00000af1,0x00000af4,0x0006000c,0x00000006,0x00000af6,0x00000001,0x0000000a, + 0x00000af5,0x0003003e,0x00000aeb,0x00000af6,0x0004003d,0x00000006,0x00000af7,0x00000aeb, + 0x00050085,0x00000006,0x00000af8,0x00000121,0x00000af7,0x0006000c,0x00000006,0x00000af9, + 0x00000001,0x0000000a,0x00000af8,0x0003003e,0x00000aec,0x00000af9,0x0004003d,0x00000006, + 0x00000afa,0x00000aec,0x0004003d,0x00000006,0x00000afb,0x00000adb,0x00050085,0x00000006, + 0x00000afc,0x00000afa,0x00000afb,0x0004003d,0x00000006,0x00000afd,0x00000adc,0x00050081, + 0x00000006,0x00000afe,0x00000afc,0x00000afd,0x0003003e,0x00000aed,0x00000afe,0x0004003d, + 0x00000006,0x00000ae3,0x00000aed,0x0004003d,0x00000024,0x00000ae4,0x00000450,0x00060050, + 0x00000024,0x00000ae5,0x00000ae3,0x00000ae3,0x00000ae3,0x00050081,0x00000024,0x00000ae6, + 0x00000ae5,0x00000ae4,0x0003003e,0x00000ad9,0x00000ae6,0x000200f9,0x00000ae9,0x000200f8, + 0x00000ae7,0x0004003d,0x00000024,0x00000ae8,0x00000450,0x0003003e,0x00000ad9,0x00000ae8, + 0x000200f9,0x00000ae9,0x000200f8,0x00000ae9,0x0004003d,0x00000024,0x00000aea,0x00000ad9, + 0x0003003e,0x00000add,0x00000aea,0x0004003d,0x00000024,0x0000045d,0x00000add,0x00050041, + 0x00000007,0x0000045e,0x00000440,0x000000a3,0x00050051,0x00000006,0x0000045f,0x0000045d, + 0x00000000,0x0003003e,0x0000045e,0x0000045f,0x00050041,0x00000007,0x00000460,0x00000440, + 0x000000a6,0x00050051,0x00000006,0x00000461,0x0000045d,0x00000001,0x0003003e,0x00000460, + 0x00000461,0x00050041,0x00000007,0x00000462,0x00000440,0x000000b9,0x00050051,0x00000006, + 0x00000463,0x0000045d,0x00000002,0x0003003e,0x00000462,0x00000463,0x0004003d,0x0000002f, + 0x00000465,0x00000440,0x0003003e,0x00000464,0x00000465,0x0004003d,0x0000002f,0x00000b00, + 0x00000464,0x0003003e,0x00000421,0x00000b00,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d03813928c32157ed1755749ea4547d0dbef1b35 GIT binary patch literal 50072 zcmZ9V1-Mn^)`d56Kok`d8$m)8yNd=vfr~9BlF}e0n1J1d2_|~L?u#9$V0R%l3M#fD znEd12tieC--jB=g9dpiaezEebz4oH!N{v@8m1>mgmg}p6 z?%s~vwaasT+>oC8X!_a@A3m}#apd|~F&#QA=g-O2dpZ9g-nVGKN&{`T+n^Qgv(8Y| zZ!GRuw=s8dzi>wkPzrI!DrYnIwb z?_aK0RciY`zN%9D3f=L4bj?y1>28_})&b0C>`wo$*`803W=!4WA1qCu_Wz$eRi%R} z^r02{hzi{|bSLFw8=Hf(6tM_j^-V%Q`R-h+lx%4&WiQ6vq4$cTA>?D^Xa6% zvpwM_H{3|9F09a-i}~PZd!udp+2+uE$i;TIoR@EdSU6+R{~udbVjp3A%jZDHFeXwT>cZ6JV@=)VvCI9;7azvQKDC^y%G_YN zEc@7()|Vy^OkTQa{r`Dume|+$kduAO%)Vr972GDcT`>ET<2wYiU)j!n#CSSuO?aPb zEZrk)%n!Dsw9sGnt(+G${pUlU+270u1Rog8KIa(rH#7U1xnJtDuMWO8cv|qS!PUXjgJ%Ta75qT(gTYS(KN~IzBl;(;HQJ134Sj4`QX{XbAn$8elhr^;8%iQ z4Sp^7jo>$f-wu8^_`TrwgFgtK8~kDLyx@<5KMwvR_|xFef3 z{B`iR!Ha^w3;sU%hu|NBe+vFN_?O^cgMSNN9Q=FmlHjGme+2&-{8#Yb!T$!AFOYm3 z<6^1cn!#1UwS!jp}~g*_Xs{B_^9Axf{zXE72G?xZ*c$M z0l|ZU2L}%c9u_45qx*>eZda|KN$Sq;F-aX z20s@3c<@uf&jim3em3~I;Mu`*f?o=LIrx>}*Mr{-ek=Ix;CF)G3w}TN!{B+r9|eCJ z{CV&f!SjQ^3|#Z$8@yU@z2LQi*A8AUxPI`4!5ar}61-_} zgW%1A8wNKD-aNQ*aFgJs!OeoV2;MTdMex?a+XQbHyhHF#!Mg~J zekgcm@Wa8620s@3WbjkLPX|96{Cx22;5orB1iuvga`0=xuLr*o{C4oW!S4mXAN)b^ zhr#oLKMDRc__N^o!CwV02woWcb?~>ri-La${xSHc;9r9m2mcYPzE%=t; zTZ5~Erw7jnzAgBU;JbqF4!$?|zTo?V9|(RhcxLb;!H)(%5&UHEGr`XWKNtLb@a*6@ z!7l{A82nQ3%fYV%zZ(2n@aw^E2EQHrPVl?I?+4Efo)`Ra@F&5a27ea(dGP$;uYwl@ zFAV-Bcv0~8!9NE76#R4WufdChmjo{j{v-IW;D3Ub1?y4S71stef@=m>1+N@jCwP_M z)q>Xut{1#!@LIv^1g{&se((mt8wPI@+#q|z&f+q$~3O+sfjNmha&kjB}_`KlrgD(ueIQY`w%Y!Ee zUlDv&@HN3xf~N*w7koqTO~KQGZwbCNczW=R;5&lv48AM)-r)O#9|(Rh_@UsL!4C&N z7W{bd6Twdh&kBAv__^TcgXaXl82obZE5WY?zaIQX@LR#}1iu&jLGaw*dBGnAe;oXI z@E5^f27eX2Ao%OxZ-W;Fe;53H@RH!A!G8q*8T?o9-@*R`{~KI>a9wBeb@XI4&sI0m z^Q}DV4c8a(m3hPRQdQ!%J`1+>^=$QO1rys)dUcifv9Bk+cG<4~mCGu%vD}ZH`b|`l zi}ujl6`IFx$)}%ll=ETVKzbLIAO39z9RQg(#vX1+THQ9r1fcI z{o-=nnmKx1OnZ!pIq#yuGDj1%5Kq~S3DC#-VCkHL{$>A!75y8$T(@<5Bg(qX3O#nY zF861G@=lVbOCCGFQE}a$%dw?Bt$$svXIa-&M3Y)4#XK?dfImOh8brnJ%@-`I9v|>zXerJP?F>EPjTXCO-q~aQLuIZ!0DTCePDO63dp=SfTfjUQ7N4isE-N-iFBERhss&m&c%z-^5_U ze^|lP*;+N5s2n95$2l*ykCvTdiI-iqy^%-e@`rIRm4!!+X^ZWOa~`EN=e^XN`>fk3 zj`OrN=a&ydW9Qs$KPBgHYwB|jPtEm1YOW!yDY@>jrai7kw5H^`&>H{L3VmIL=2|x6xt_IV{9H4qK0h>euFdVI(B$WD z1jnPthsMs|BKA}A_eg5~CP~fTC8_zF)SCSKU7EUWg>Dy``D-7VdL1fs#|q8gtC_!3 zh34;8`ziU`HT8ZKx=V%b8k+HRtI)etX#Spee&SnH=&eH&*E}@i=e~vOqZ@_BzF}zm zYlg!l_a9Sp4>C3PAyacNGBx+1t!a;Y(W$u~otk^n*32LGrL8G%tkB$_ zPCxgkt!a<@)Ty~wZB5Dj>eSq`PR)Jm)ZDwaCO`MDQ(s!4xrd+rvnw>;71&S7_Y2mH zpYJMCpAs57-+iQ??^LWQhgRr*p~-(#XyT6!jsM^ZeMp7wTA{mzW`6i?%>6;P4~?Dg z;OsA#6?*Rq-7+-!wy)4TgeG6}3cY28=DWvizeR=SyJ!1pkMEyT^Br_*zK6DE{`fB1 znv(CMQ}dm4YQC4Yraiu!POZzR6&ibu3cXT=u34e0LX*E%X!7yhyxXJy3qxb)dw=^W zd4|B6c%DtLrsVmA)I958P5hkD*m;h^eoCInuqJ+HXzUMH=&M3AzN;%V&$>7t{%b>H zpAs5B&%ijI^19IYudmQIROlNkG|%riAN6^LCpFIrrRG^7Ysv|snU8T5dVFZ&dG^Wm zi60OeJI__wPsuY{*2MP+js5V@`1h~SJX@CaJ6C9)TeF|>x2n*sLld`ah2E_~?_Qzz z2u*&T18}$SJHN?FKflXL&F{#qxxdSA$*tL5_&s@Qep7Bu$?wWj^V@Q3 z>ht?@Yf64&o|@m8r{=fjsXwdG{N_CU{O&w8zdg66eSUv#P04T2Q}a7?YvTDWx-})g zN4Mr)>^GsY^BZ;hDfykcHTn3hdTM^Jo|@mRTT}A8_0;@!-I{#-emyn6VNcEP*sUq~ zEqiKy&u&dVe$$?s-?dv)^4s>*{J!0q`uxT{HNSID&2QaP^G=1-yjQ`R?T>dWSo8e^ z?^m#<VUZH1%=J?I~DO?}TJ1VTncSUIYybHsA z^hKeupID(!sL;H_!}Ym8ex7dLSyS?Unbf>vCN=Mwv1UFls?ZmQX8gR1#_^QAkH(tu zT^5@7%PaKc(2Vzr3e7uhoDct1p|SIx8~f?+HKDQd?i>5*&y>*gXKIDME;Q|3ADTQj zROlNk^i37|=Fs$y_wTqr=vzY5AKuAhKieno<*~-kyLqgs&--~&^IoCUyo)F`?<2CN z^nRBGPgmbztV#@{A1_1lJ~ zUi;9*cMQ#Z@_s1iXZ;=&8vCIYn)gFFo_u`^-BS0z`L3gh^hw&Tx+{wBGMh?cW8tIQ z>9W@@`RAAO=2 z8{h3sENmx9W9R!la7Z_%p@W@Uah}?K?}14d3Z1(e~{v#)gk=8*N`JF*bZ` z*J%6Bg$p11a9J09Z!L|@Inl1yPVAiQ3ut`IaR)K;K)v=V(XMy9nE1Ae%~g@@_Hl)5LD`9%<~}?(P+17RPSrW z-Y1QndP|h|c`=_q)gOHKYr)3%P_X;*fS5k8uQB!q#q4V;O8DGI?BsnEhd$)xyWNMR zv5^;cpJ$4*&ksvu<2zvY`4MUC^!X3fcOJ^cIxaA-$HcTlpNXdp`th7fKJo-_QX7yI(F zV!kWH?|H<=Slw4jwAT%#`#xJt->G|nN}j2(Z>+9Yu;Js{1#RCP*|FifP)r}}8!tOH zd|U&e?R!CXY^&)=%eL^MG~?oZiS&iM#88)h;b&cZppp;kg75HOlE%imfXUCXuTdwlr}L#I`_?SR$`~$@#>O#+ zbM&QRuAirgiANLTG4l?&jK5r(`064aO$_n$VRGRo7uVrv`%V{QdsuDPR-eug(`W2c zRG)qROfh!W@dYaRu#T~xrR97rtYg@HJX_5A@R-h#W?ej@x{l#Jde~RfsF{cJ#LQJw zE!4+f9>410W51+*+M-SS*bmc3jN5omb?FDOY$s@9y(~Z1bhDvko|4^6bl((mWr-`4T_**#5r~<73_~SBbXo zDz%Tz`kF#>-Nt&HB25e*+ol#a)~{{X$wpl@y~1{VVN;j%j^pL~)eW+dlN`3)D5gH~ z*my4JCNZ)2=r@0pVxyn<7pTwJ@LeWG<72)SigW(Hmd2Lz_l-1mp0)G*eJkzx!|yp+ zB*sTulU1VKkMG2^f2sP-{`sRATT?Br|C5+{KJNT1#>T>jdE^{O{a<7w2QlSwtHeew z{J)B?(Bfm#Z(<*l@VU*!;%xJGX>2U4Bi0G$Vsb8#jXcD-{!($)|3exZi|hMX`KN5; zAcj6)r4pO_e5=+IHhkQBK-*U>#)gmk5NP}UQXOpgt`wtv4EkG)ZJPQ|JlpC&(%2pI zZxO?>)G^Cs!|vmhreMW!iu(9j7v!rUAO7XnGt1B0D;4qO_d<&~UU3aTAFozj{BEnJ znB$anl{7JKyOy+%k;LLB4|VWyeDU#tl00nRb;Nm`T16V$6s=V1U!(fi9KWg<+x;30 z=YYD>*q9fNOC800I4$oT zcK2sZG5xu{=+9cx*jSg-3)|Y#T<_qckL#)ALm%<2qXip%glXqm<;?52+hxb*?cok- z?v2q7@n~Yae(n@!{9V$-GhX7+#5n$LamL>xO+3eB;?cx7{$6p$-zQBx#~|X-#1PMM z`~Jd@Z-y9c-@0OK_?TZb+l%Lf63x10j#!`6Wu2`r&g0_-(%3jY`dGN3w2y`O-R?$W ze6%}N?V{~_NQ}*TW}$tKctn~QKDIqt*w|)ldrUU!=DFnY!lo{+IBz^58#&40bIFrp z>J#sC$x~ut@zL)GRAQr_oJ%$qW5YK^{YT?tt~L?pTx}|iEzczlq_MM|c>Xq%_Wa@Z zoHP{Uqpj=I7TW!2B&L0zOPWYy%X3LnY3li0(hPsGsQL1~$MK8f`WCX2gBaSoUiGkf zY|X{FA8sj)jqR6xZhJ8w_Bni8Y1u{#+Y{{ls)d-`>{sNjt#WJGu+#31@}b!t$w__k z5KBL|6;q#M2z9rUW_xH?_?!cK<{+2b+d)h_#NMD1ZQqV!Z2sG8Cu#C?49AzpaN_X0 z?#@MBk98Mm=ASuo%&xLw_usa=iK&O(^>!CikA2x*&kDW)!V#&MJ4v5|x0 z?_T1{D z!@8X`dA+~2mnH^#4_*6n-0C1E7e4l3=9m6(oWhsKC5}(dy^ol4pXaQTG<9;$I?IOL zbG@$^8+B;|A2zn%?kf4P{qlTu7iny4f3Vx_CZ^s@%>(Dh|A?{CZ~E#wl)lE_UrbK= zPdxc(vxiDPv`NeXTCmY3Oq(264ia+?_uuOWOJn2NZ~y&qh%|Pe*KbigHs^R&jE!+W zEk@h-oERIvXH=r?J5-Df-!#=n`|q2>#OP`2BV%{pDLwYX#f**lAf9nC_5mvSFm_^& z(1MMz!?e#mgCoUNYS;G+j*`a4Jp=l5t9;mqXL~wY%y!US_fDEfA0v&8g%A5O+ZlDM z6^Gw-dy2`2Z@Nmf=iyi}iW?I8uzv6@ z(^6A5)(=cyRFrDSMxJv@%a2PdNpp>hoxbz^J2tita#Ei>_IbatkJ7noiK%~)ax>4h zr5P)B>hoPbHsbLw)0|+#_nsJyk9~;FGRKTc3Ja{ZGx8Myaf$@^qDYe6RF`O73CKQpq{%WtDta^Pb8zRDQ0q zp2|fknGf3a7*-Oq4O!QeW-J`T7$fgLCk8v?{6Icz%rE00AN_az+TzT&vNZWPkC3m9 zG%?s+hj*rDomHi?4|S!9!Oq`xA~7mnIIoZR?A%kJbj@dK*ZSn|^($lE3-z z$y{1h8w57*dv&FGMulS}@n~WkznVDXSC=Nfx`;;;f)NCdPeTv+&b4 z&&Htb+fW_G_Ndk&zq{K=nz3QOO`~DGZY;*mJTT|p7dH{(o27c>W;?`|>znvG|=AU*=^$bl%OynYXcY=4~QP-sW0}#qYfMGB5izc{z_X z6Lb9aF?I`SY%F}p>GQ}u#c>>?F79^#d>Uiv1i^<2>{Wse-vQdu@eIf>%>uf8gPPP25vz=^ii#o($bDizQ)L{->XNRJW z*Ap?=JoX*MY&+i9cak1erR#i^wDGZgxn3J+p0K&i&7^sL&Fd9S4EdF!)KHx9jiiaM zF2;=}#_^krGrqAj@m{ZJV%+~Gg`d9i+#K4zoz($s_&!me=c-M&(_D6J9>$ZiTzBUu1?b}7;z~=33S7~o=tS`n% zjK{K@nC&31b#|8xyN_Lah{=PUHa}84Hu%$ux!O@}V{`tUq^@Gn7E`aO7TP1m?X?kSdu^q$vG8$w{OwNucCur`O|1LTUQ9n2 z<7X;!AKY8x!{+tTQkrK}y*|*ykc+&n#2MdOn)qsb%8w?-@omHz-&UG7H1VDvG%@aL*TPRyJXdYHo&9CU=5ZV#-A#+ffhNZB2Z}TPAZg+~4m2^2KUkdche#9eaiEEDUk@$( z^z}btw0-+&9N2t}>LSf{%{h^E#W;zfF6#|Hb=gO|igTaoCXJ1SkM|ks&R5;s7miSy z*gQu^N*|`hbA%?wV?Iip@kdJ&U#)h?k0!?P$A~k&r!?`NBQ!Cdhhqyrxq67v_WeiW z!G>ns-KBHf`%7bEsVTn~&*=fOdrp}n@=?cQKTu3Q#_sd~L9$Vg4}BsAo9i4brcSl| zu5*ZNZi_m^U~`>A#nfRAT<5T&j;}L_!R9(WiaL2tI$SpF92>Zgbc7fi>zBV#j~4Uc z?{9oZYQe_ecW`-*RkF`;oUo75>#wJnHazFYigV6;Nn>N-<85t!9XUBZ_m-U;UVNR@ zM>c%arypNxKCr=GiRqL3&{yjmo9CjRbT2L5M$yDLzP~u*kCP_8S~turxsbV}5;IF;GklcArBBiOGY{ z=g`4o=DMjC+9bwp3=z|&&yhomSQRCFjvFTSIbea}^SCffW5DJ)A1*yui{~6o47tcV zLY(o(OA}u$AM=DJ#_=P?89z#zc+WYS825E_;V0J+G1|W2>Hs#MBS%OxHtaq}9xuku zTrhXu4o8Z)UdK;v&YRfsyg5qRZH*SsR*dx+Y5rF9y_K=j#9$}iLiw;c{sb{L>v7VV zZ@e`5CTgE%TRTyj80@Zdl9(JG!^zUbVYlrRG4{OYaH=$I(XX#n<~@gTnm=q_-{Ymn zXz}_+6GI=ArgWk><4=+%zPec7Xkr|HvN+>UktW{j8%>PIcxvINuVck%`%Y5_u=$?D z1Zl>G-Rpaz7(4U8oO}P8B*r&OJCD~lwp`z*OXK@S^TD$%_|A}x<0d8jn4ocEG&bHP^t)mn5Z|kX5658q=V-xBF4(!w6_d;Jf1Wh!3Og|>O6Ti;*dH(2yFiSM z^~mx59x)%YZpQDvOc&?4XB67`Zj+{O*xk3=#n}D* z=pACtH4U}k^Vshc<6}E;zPqI9AMMgVG;!HK`kC7V+Xk9_h5l2z|M!XM{{+p+1hsR& zG&bI^<$V+z^}Ua>e^H;~=YwL#XZ=ux{;xFqnU4=MrLoP@fPE}|SQD z=YCYo*d6njG;!Ejr}XD>F@3^E|B1&&{}-!d{7GX+*fSb*O#T)-``cqhy9&*s=XqOjd_FJ?yF+@M!s)V=C#cvojb63n>}6nG%Y^Y zp@|`v(v;2+XZ)Gc#8=Blel#(TKTDkPXG;_Ba~+x(_w}5@Pp%1Kw0*Cs1K98_QlHt^ z+|C8EWAivJls;FB$AKos@fV3R{$gq3Jq|Q6j=w~l@s~;y?{T1sabGVh{PguaG1|V@ zH4be4TkH*Kwo(4RWnD2&VyMe{!|%FpioGtslMij*TVl2^>V2;gZQtAB`$0ameb=im z#8Ypw7;WEw#n}AJ%SV`UOU;#@lE&_sr;C{Chvd`Dj(MYq$@zLyHtZhLTVmR1s)hRa z8Ph8&@p()yh_N~Mi(>kn^YxN6cISRs?A+AHPwwYb;&bks#Mpdpyjjc~VkiD`mDoII z)5L7c_^uSA?R!s*&GY%b7#j;8&*$6H_&lCZ#Mp8^Kb6Mrn9qusoX^i?!|pMEA@-Q5 zkDq>iq!ORU{DByobI%pi@0`yMrLjBrJh5|AA3wR@QHjsFZxLhjoZKpAzI8;_qF2pGaYw{sZR{KuThDOTpVBS7PDTQ`yOdxd|h_0 zm>BHTzg8tS*S}B9F&^I(G1|VGb#z@Xjqf*=X#2JlW5d@(+(!L|d1nmoq=k83Ogpjr zww*Mwp8xH|ypx9YPdu6!$L}C6=hHQynkwxmO+4EI@n~Wk&%a$qo6f(pn0VGN@n~W^ zhFuCjKHi0cwr?vjw#jO{w(7SKGiL0>Z=n*K+pZF0!}qH?i*~MBV&>htcA<&=U3Rp6 zdx^2(<9$D#SKjsGdF4GnIj?P{iS@YKiFuch=M_zi``TVy&R5K92WjFxuV`W%-%(7P z&cBbCc+V@E7>}V-;b#oI!w7BP-ePQ?*Op?&jGcJiS%l4PuPnyq<5wLqHZMMYts)!q zjGsJ0w z8GooW@$MIz7`J^`;iqlhZH2aP4KX$}$EA8=)&a49sYKg%q!^pe7e`5BW8tGAmFw}o zEqoqNA2Bw@LoW8qzS7to)31nO436n98+IRWj}y~I)1p3p`q@h*KG!>1jLo@^5!3HH zU-Xm>yK^5ac5dq9CpYg3!{^*iPx&NcY*mC|xOJjG;m?9?UZ>((CJ;oEnw9#A(_3<;t<5lAG7>A0nIrlIz{m%It zE*o~|9wBya>fI1@ zrHS`GfhLA{_SMr0KW&c}qwQN)jE%7oyPnu%V}HTVc^+SVG5a<#uEv24-%sjuZj+bDj?Lq^RQf_K9tWBj_v5~J<=P~*Vndn)s!*|xc-!n$Id#88*@hTnBR68pZ%&+?(|`&jJt z{EK{O`#yg%lUd+8oOiODPnTI z-jxlz$Ml|9>CXL;>Ul%(!_3@MY1(o=m`&KbF zU+Y$jnM3TvU!@Y8=WM!|Z5iLSVzhl9im`b<=ZUeg@bP@UFOARR`9h2>=X1U^cE@~K z#N>Q_B^!2+d4bqtrapf9`I$<59`i?HY|j0$n11Jcej<(Cxjz*jy=Y6qk*gZGDipt*jrZV8gdmCEC7i#MtohuI@JK zH_Usw{kK2w=x!&w`?ixbv7Y~(#k>cc^-oI0|rHS`^qlqD&zpoA|{IuOojJ9trF*bbvDreqPIZSqJZl{Md{|A|~hWMA@)=j3gM zqwvu_vGlE`N__NVN{BI_W&CA5%p2`-oQ6E2T z*HVeiZU0v}u;IH=jJEI7+NH7$ANN$y+(YsG5z4%$^0_qkRK8Wo$M;mekjBP671;Ub zi~YCuZ_1zdRL)bMuz6jaFMYNaZ=YylJRcW`GyXzp;;YpU`i~~Y@fV3R{$gq3*$0V7 z6XU*KQuy(mBSzczrN)5`-(vMSx5>$}WAiw!kiJxl$AKos{kl?|@mEO`?{T1sas1Wd zjK4;jc#i{3jQe_R;is>ciP83brEy^MJ(UI0Y}?#ZVO=p!VyMe{!|%Ea#a@@c%ZIk_ zYq9UQERhdw-yLcX8#$+n(e}M5#)j_|m2K1+_*Jp5`Cb#Zlbt$BTY6ubSkLzd;&-%o zzR|=uey+Hjuej#>P@4GaVmm++p-=IRkVsoDR#jF=!OFtmySb*Iz z4;C@hzfp{aZ&FFT<9-$6_k8>&{z;4H8%>Pk7mLZ^_}|6Ed%n@c5YIVxN#UpMpT%hV z9ui~2ceBd8mi|i`o7?$Yyi|+(g(k-R`bV7c|4I|@exZqR+sg_+ZT}%g+xK5FHZUn#Mqp>wwQji-8*Jw*|0lz9kFv$A3wSIxBBq8-owg+ z&DYY8NMpm#{5>l6{M{l(+qaJDVe|a0D~*kXkLQnnUl5=Bzp)rw&fg}|*d4QJ5tH-R zKsM|i<7Q&oXs(6&_!%Srz9Bx3aXm3M=dLfN-#LHl%ZA;#HxN5F_3@LNe;W~>b3dj$ z*zny-PAzb?N_>uMtQh?6LlfzSTD(u7iE(^WF*zLHOqzJ_6KGgV7vF z^b2BQush~O@f0mS{=X!~=4GPJVdQ>UHtOT2?b}phbKBq4*1h7w$MrIr>tkR0Qs(vY zB5AIde^bfF*UR5YW8-=mcK+|hzQ$Ur{CT~+t=0!N&-ZrH{M(}52GPWL%-f4Ieg|pd ztJM$2h9<`GJBl-YCu!o@&xl78?nxgIdLF2%N?+^7kx4YeC$L4YDAT#fnaliHyXZ&8$#CsfQVjRD>IOAJN6Yp`LiE&?B6@L24zuk(q??;UTo3EFDl4kqm zdYN^_IEkSy>kYr_{w(%2@t^Xc?fXUS_57E7X#2XWJ#6G`BSzadMvM*L2w0tgj~Dy8 zj(?xGo$S<6+R{nV#CpC@7LU{7`9>4t_*2B?e8qL$snWz(7ux}v7{{L`rcLLcAST}P zjV8upm{|Df_jobdzOiC#zOFk#%$TtgKT0Jwx4pj@8@|>m(av>%n0dE8u+YTvZw{mF zJ6ntmAOF6x=k;{4=k*L?VqPzlCf4J=NX)<8?0H2KRNaRa@n~(%2nyUlGF?9CN>H*nNI~KujA=i~9I!?=F@2T<-O5=0? zpAuus`FmO#yJMayVsidw$%fryd{#^wTrX1}KVy7CB|eYw5ivIBepF1qbN(Ka#_rsY zi=CVL_{sf{N_@`UQ;ZGYzABkNct4f+95+Xd-+g#N{G1l=6KG-_|Du>2j(_3w~cO_ZG8n6GN`{DzU*`RdTFyA77KkhVK=X zX#4tzvAO?!#pKF$-cK64WBL~{xz3N14ZGLN05N@MpP@c}`v!)O_KBr$T~y+uZ*0?p z#BB>*TY9jV7+)_B5fg*m;~6S$t;NUxVPb4vCKlJr!)2pBe%kJ)5}VupRSjap_kqsE zXs(Za?Ms>0%ZsI5_jfUMsQb4{w0*BjW5f5nO0<1%h-ye*@Nar`^tjDJ^}_-f@MKbjcFzbDT4_oazve>L)f|uf8kI_Oq=P=7qT+hPp4Q#P7Pj#MnH}-eTSp%Q*cWmp-x) z$A=umU~`?mV(Ktf*Xbu4b?66mh{5JM{l(N_ysmScY}ChKE5|=dHtKl%#9(8*jBj6!jXLz9jY_nA2Z*tG><5amvGDQOsk^^y_~C<8 zHq}DE4pZ4fOE)cf3_HBA6Mv`}?f4_b#Ix?bUXGH+PW%xn(fmF9jkZxf{5`z2I`paZ zLM^OUnED*MKNHh0>VGIkJNM^e`hahq7;WDdV%o#^kr?gy{!vV>9M@0M*!{kOpT+gn zFYK=Oix4SQU~`?`V(R3vu8%Zz kyss03jlQz4_Y+fxe0^1-?c=4)*zh${iT+2e@2=(l00@y}p8x;= literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.h new file mode 100644 index 000000000..aa70c6ae7 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.h @@ -0,0 +1,130 @@ +#pragma once + +const uint32_t atomic_resolve_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000000ae,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000029,0x0000002c,0x00000068, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x00000029, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005,0x0000002c,0x495f6c67,0x6174736e, + 0x4965636e,0x7865646e,0x00000000,0x00030005,0x0000003b,0x0000424d,0x00040006,0x0000003b, + 0x00000000,0x00006250,0x00040006,0x0000003b,0x00000001,0x00006359,0x00040006,0x0000003b, + 0x00000002,0x00006552,0x00040006,0x0000003b,0x00000003,0x00006553,0x00040006,0x0000003b, + 0x00000004,0x0000366d,0x00040006,0x0000003b,0x00000005,0x0000676d,0x00040006,0x0000003b, + 0x00000006,0x00006544,0x00040006,0x0000003b,0x00000007,0x00006545,0x00040006,0x0000003b, + 0x00000008,0x00003755,0x00040006,0x0000003b,0x00000009,0x0000676a,0x00040006,0x0000003b, + 0x0000000a,0x0000635a,0x00040006,0x0000003b,0x0000000b,0x00003157,0x00040006,0x0000003b, + 0x0000000c,0x0000676e,0x00040006,0x0000003b,0x0000000d,0x00003559,0x00040006,0x0000003b, + 0x0000000e,0x0000324f,0x00040006,0x0000003b,0x0000000f,0x00006461,0x00040006,0x0000003b, + 0x00000010,0x00006579,0x00040006,0x0000003b,0x00000011,0x00003376,0x00040006,0x0000003b, + 0x00000012,0x00003377,0x00040006,0x0000003b,0x00000013,0x00006462,0x00040006,0x0000003b, + 0x00000014,0x00006767,0x00030005,0x0000003d,0x0000006b,0x00060005,0x00000066,0x505f6c67, + 0x65567265,0x78657472,0x00000000,0x00060006,0x00000066,0x00000000,0x505f6c67,0x7469736f, + 0x006e6f69,0x00070006,0x00000066,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000, + 0x00070006,0x00000066,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006, + 0x00000066,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000068, + 0x00000000,0x00030005,0x0000007a,0x00004342,0x00030005,0x0000007d,0x00004351,0x00030005, + 0x00000080,0x0000664a,0x00040006,0x00000080,0x00000000,0x00003464,0x00030005,0x00000082, + 0x0000424c,0x00030005,0x00000085,0x00006576,0x00040006,0x00000085,0x00000000,0x00003464, + 0x00030005,0x00000087,0x00004355,0x00030005,0x00000089,0x00006577,0x00040006,0x00000089, + 0x00000000,0x00003464,0x00030005,0x0000008b,0x0000424f,0x00030005,0x0000008d,0x0000664b, + 0x00040006,0x0000008d,0x00000000,0x00003464,0x00030005,0x0000008f,0x00004358,0x00030005, + 0x00000092,0x00003954,0x00040047,0x00000029,0x0000000b,0x0000002a,0x00040047,0x0000002c, + 0x0000000b,0x0000002b,0x00030047,0x0000003b,0x00000002,0x00050048,0x0000003b,0x00000000, + 0x00000023,0x00000000,0x00050048,0x0000003b,0x00000001,0x00000023,0x00000004,0x00050048, + 0x0000003b,0x00000002,0x00000023,0x00000008,0x00050048,0x0000003b,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x0000003b,0x00000004,0x00000023,0x00000010,0x00050048,0x0000003b, + 0x00000005,0x00000023,0x00000014,0x00050048,0x0000003b,0x00000006,0x00000023,0x00000018, + 0x00050048,0x0000003b,0x00000007,0x00000023,0x0000001c,0x00050048,0x0000003b,0x00000008, + 0x00000023,0x00000020,0x00050048,0x0000003b,0x00000009,0x00000023,0x00000030,0x00050048, + 0x0000003b,0x0000000a,0x00000023,0x00000038,0x00050048,0x0000003b,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x0000003b,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000003b, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x0000003b,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x0000003b,0x0000000f,0x00000023,0x00000050,0x00050048,0x0000003b,0x00000010, + 0x00000023,0x00000054,0x00050048,0x0000003b,0x00000011,0x00000023,0x00000058,0x00050048, + 0x0000003b,0x00000012,0x00000023,0x0000005c,0x00050048,0x0000003b,0x00000013,0x00000023, + 0x00000060,0x00050048,0x0000003b,0x00000014,0x00000023,0x00000064,0x00040047,0x0000003d, + 0x00000021,0x00000000,0x00040047,0x0000003d,0x00000022,0x00000000,0x00030047,0x00000066, + 0x00000002,0x00050048,0x00000066,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000066, + 0x00000001,0x0000000b,0x00000001,0x00050048,0x00000066,0x00000002,0x0000000b,0x00000003, + 0x00050048,0x00000066,0x00000003,0x0000000b,0x00000004,0x00040047,0x0000007a,0x00000021, + 0x00000008,0x00040047,0x0000007a,0x00000022,0x00000000,0x00030047,0x0000007d,0x00000000, + 0x00040047,0x0000007d,0x00000021,0x0000000a,0x00040047,0x0000007d,0x00000022,0x00000000, + 0x00040047,0x0000007f,0x00000006,0x00000010,0x00030047,0x00000080,0x00000003,0x00040048, + 0x00000080,0x00000000,0x00000018,0x00050048,0x00000080,0x00000000,0x00000023,0x00000000, + 0x00030047,0x00000082,0x00000018,0x00040047,0x00000082,0x00000021,0x00000003,0x00040047, + 0x00000082,0x00000022,0x00000000,0x00040047,0x00000084,0x00000006,0x00000008,0x00030047, + 0x00000085,0x00000003,0x00040048,0x00000085,0x00000000,0x00000018,0x00050048,0x00000085, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000087,0x00000018,0x00040047,0x00000087, + 0x00000021,0x00000004,0x00040047,0x00000087,0x00000022,0x00000000,0x00040047,0x00000088, + 0x00000006,0x00000010,0x00030047,0x00000089,0x00000003,0x00040048,0x00000089,0x00000000, + 0x00000018,0x00050048,0x00000089,0x00000000,0x00000023,0x00000000,0x00030047,0x0000008b, + 0x00000018,0x00040047,0x0000008b,0x00000021,0x00000005,0x00040047,0x0000008b,0x00000022, + 0x00000000,0x00040047,0x0000008c,0x00000006,0x00000010,0x00030047,0x0000008d,0x00000003, + 0x00040048,0x0000008d,0x00000000,0x00000018,0x00050048,0x0000008d,0x00000000,0x00000023, + 0x00000000,0x00030047,0x0000008f,0x00000018,0x00040047,0x0000008f,0x00000021,0x00000006, + 0x00040047,0x0000008f,0x00000022,0x00000000,0x00030047,0x00000092,0x00000000,0x00040047, + 0x00000092,0x00000021,0x0000000a,0x00040047,0x00000092,0x00000022,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000002,0x00040017,0x0000000a,0x00000006,0x00000004,0x00040015, + 0x00000011,0x00000020,0x00000000,0x0004002b,0x00000011,0x00000012,0x00000000,0x0004002b, + 0x00000006,0x00000017,0x3f800000,0x0004002b,0x00000011,0x00000019,0x00000001,0x0004002b, + 0x00000006,0x00000021,0x00000000,0x00040015,0x00000025,0x00000020,0x00000001,0x00040020, + 0x00000028,0x00000001,0x00000025,0x0004003b,0x00000028,0x00000029,0x00000001,0x0004003b, + 0x00000028,0x0000002c,0x00000001,0x00040017,0x0000002e,0x00000025,0x00000002,0x0004002b, + 0x00000025,0x00000032,0x00000001,0x0004002b,0x00000025,0x00000034,0x00000000,0x00020014, + 0x00000035,0x00040017,0x0000003a,0x00000025,0x00000004,0x0017001e,0x0000003b,0x00000006, + 0x00000006,0x00000006,0x00000006,0x00000011,0x00000011,0x00000011,0x00000011,0x0000003a, + 0x00000007,0x00000007,0x00000011,0x00000006,0x00000011,0x00000006,0x00000006,0x00000011, + 0x00000006,0x00000006,0x00000006,0x00000011,0x00040020,0x0000003c,0x00000002,0x0000003b, + 0x0004003b,0x0000003c,0x0000003d,0x00000002,0x0004002b,0x00000025,0x0000003e,0x00000008, + 0x00040020,0x0000003f,0x00000002,0x00000025,0x0004002b,0x00000011,0x00000043,0x00000002, + 0x0004002b,0x00000025,0x00000049,0x00000002,0x0004002b,0x00000011,0x00000052,0x00000003, + 0x0004002b,0x00000025,0x0000005b,0x00000003,0x00040020,0x0000005e,0x00000002,0x00000006, + 0x0004001c,0x00000065,0x00000006,0x00000019,0x0006001e,0x00000066,0x0000000a,0x00000006, + 0x00000065,0x00000065,0x00040020,0x00000067,0x00000003,0x00000066,0x0004003b,0x00000067, + 0x00000068,0x00000003,0x00040020,0x0000006a,0x00000003,0x0000000a,0x00090019,0x00000078, + 0x00000011,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x00000079,0x00000000,0x00000078,0x0004003b,0x00000079,0x0000007a,0x00000000,0x00090019, + 0x0000007b,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x0000007c,0x00000000,0x0000007b,0x0004003b,0x0000007c,0x0000007d,0x00000000, + 0x00040017,0x0000007e,0x00000011,0x00000004,0x0003001d,0x0000007f,0x0000007e,0x0003001e, + 0x00000080,0x0000007f,0x00040020,0x00000081,0x00000002,0x00000080,0x0004003b,0x00000081, + 0x00000082,0x00000002,0x00040017,0x00000083,0x00000011,0x00000002,0x0003001d,0x00000084, + 0x00000083,0x0003001e,0x00000085,0x00000084,0x00040020,0x00000086,0x00000002,0x00000085, + 0x0004003b,0x00000086,0x00000087,0x00000002,0x0003001d,0x00000088,0x0000000a,0x0003001e, + 0x00000089,0x00000088,0x00040020,0x0000008a,0x00000002,0x00000089,0x0004003b,0x0000008a, + 0x0000008b,0x00000002,0x0003001d,0x0000008c,0x0000007e,0x0003001e,0x0000008d,0x0000008c, + 0x00040020,0x0000008e,0x00000002,0x0000008d,0x0004003b,0x0000008e,0x0000008f,0x00000002, + 0x0002001a,0x00000090,0x00040020,0x00000091,0x00000000,0x00000090,0x0004003b,0x00000091, + 0x00000092,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000025,0x0000002a,0x00000029,0x000500c7,0x00000025,0x00000033, + 0x0000002a,0x00000032,0x000500aa,0x00000035,0x00000036,0x00000033,0x00000034,0x000300f7, + 0x00000039,0x00000000,0x000400fa,0x00000036,0x00000038,0x00000042,0x000200f8,0x00000038, + 0x00060041,0x0000003f,0x00000040,0x0000003d,0x0000003e,0x00000012,0x0004003d,0x00000025, + 0x00000041,0x00000040,0x000200f9,0x00000039,0x000200f8,0x00000042,0x00060041,0x0000003f, + 0x00000044,0x0000003d,0x0000003e,0x00000043,0x0004003d,0x00000025,0x00000045,0x00000044, + 0x000200f9,0x00000039,0x000200f8,0x00000039,0x000700f5,0x00000025,0x000000a8,0x00000041, + 0x00000038,0x00000045,0x00000042,0x000500c7,0x00000025,0x0000004a,0x0000002a,0x00000049, + 0x000500aa,0x00000035,0x0000004b,0x0000004a,0x00000034,0x000300f7,0x0000004e,0x00000000, + 0x000400fa,0x0000004b,0x0000004d,0x00000051,0x000200f8,0x0000004d,0x00060041,0x0000003f, + 0x0000004f,0x0000003d,0x0000003e,0x00000019,0x0004003d,0x00000025,0x00000050,0x0000004f, + 0x000200f9,0x0000004e,0x000200f8,0x00000051,0x00060041,0x0000003f,0x00000053,0x0000003d, + 0x0000003e,0x00000052,0x0004003d,0x00000025,0x00000054,0x00000053,0x000200f9,0x0000004e, + 0x000200f8,0x0000004e,0x000700f5,0x00000025,0x000000ab,0x00000050,0x0000004d,0x00000054, + 0x00000051,0x00050050,0x0000002e,0x000000ad,0x000000a8,0x000000ab,0x0004006f,0x00000007, + 0x0000005a,0x000000ad,0x00050041,0x0000005e,0x0000005f,0x0000003d,0x00000049,0x0004003d, + 0x00000006,0x00000060,0x0000005f,0x00050041,0x0000005e,0x00000062,0x0000003d,0x0000005b, + 0x0004003d,0x00000006,0x00000063,0x00000062,0x00050051,0x00000006,0x00000096,0x0000005a, + 0x00000000,0x00050085,0x00000006,0x00000098,0x00000096,0x00000060,0x00050083,0x00000006, + 0x00000099,0x00000098,0x00000017,0x00050051,0x00000006,0x0000009b,0x0000005a,0x00000001, + 0x00050085,0x00000006,0x0000009d,0x0000009b,0x00000063,0x0006000c,0x00000006,0x0000009f, + 0x00000001,0x00000006,0x00000063,0x00050083,0x00000006,0x000000a0,0x0000009d,0x0000009f, + 0x00070050,0x0000000a,0x000000a1,0x00000099,0x000000a0,0x00000021,0x00000017,0x00050041, + 0x0000006a,0x0000006b,0x00000068,0x00000034,0x0003003e,0x0000006b,0x000000a1,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..91004774d6bf2aade6bae4dd7dc3a08526e35745 GIT binary patch literal 4004 zcmZ9O>u*#=7{*V#T?#FNToh}tDH0O7q)`McBBj@q!eXyzLBr{G_q5%z-8Q>hXz^AH z6%p?rjK&!8o6+dM;TQiM<0Uci`JFRw&%_~b=Y5`eZ!>e=VKa?~n}eVsXbrXpzXr+J z6Eunm#BGb`q1;5SvsN#5o;v+J7Q2E>Y>3Tn`7xR#i}_Lo{ix)GWL}cdzedf!%eX0M z35IfE?|5HWo6i@cYFMi;Rr7OEII}W4E4VbX5EbgOYsGGGYBH?l7njRXwH(!IVLe){ zuT-OOcBN9NmzF9ug|(PNBO^n(!LYErte9)%C@hyMQCKWh6|ZzF!frb;on5I?D6bTK zgRCt4J!G|a_AyruUyG_rJzOb9t3i+rn&Z8RAFkBu`AQ*jE39RLbMm>;7s$IQ)~RuH zCdHiDwL*$Hn{m}=_MGg5hvS;gr0ZF&FV3ZSoA7{VugeSuJS+~z{e{$ir*Orye@yt=>2!UU@W{y&?-tG%Q~bE_npe*r;ae}J>wAT7dw8GljOV{! zcux5_+w;!x6r1qqtS!|_d?#X?V|&g%=1Z0OMCp#I!Y5hd9<(Vc&Snd~{Q9PB{ZAj1cCHkgx zzEkYb8D@81`c)V2f%MzX4xM3k52cT|c%MkW?DC>B%tJ^ zBw%_Nd_2a23OC?!^aI>QkE18xavn!tz>Rtw z`-GeHIQj!_%H!w}xHmnHK7pI|IL-*JDB=F-mqQYU;b#*loQZqF?vs9Eux|!u1IK;B zF&l>uT*l+j;kZL`(GTS24h;Lb=@ABN=-6@(hEv<7;63r&Ip;;)>zb3?X;0a=z#4;d zU|_$YnRQ~LlM8>tey)4s$(7WdiF?s zmtjBGL)lv{baK%z>5w}BfK>qYK7&|a=z?|t5`b)obNEpW*re7FfY!Ad}{erEx z2{(A_)W;y+5zQSE);olsb2|JvhmShW@Ck>huTwg<)Js0}lM>L#U9aoOhWJdCKjxpjWI`m{UnZF(of}>r^o)({?2M<{G%AGbxHap#76Jc z?ecy1Na%rX$=+B`a`sB^k^C)tV&R9s`3*=nzy4TH{0617=KJCQhq{&8f0PiL8n7j% z?dy_s_DWCLzAj6Lw|%`Tox#3XyCNBrP#?P0HzM8YYm4=yzESC{Q6I7J!{7WSq?;eT zYk|*8zkoYopgBe>{JGF yd@sQU9o}L-l8!y=quOPQ<{u>FdL%g{As_o$(0o%eFX3*x_058@|5wqwB>w@!-a$bC literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.h new file mode 100644 index 000000000..d03a14e0f --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.h @@ -0,0 +1,1520 @@ +#pragma once + +const uint32_t atomic_resolve_coalesced_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000a91,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000033f, + 0x0000041a,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x00000261,0x0000674d,0x00030005,0x000002d8,0x00006576, + 0x00040006,0x000002d8,0x00000000,0x00003464,0x00030005,0x000002da,0x00004355,0x00030005, + 0x000002ea,0x0000674b,0x00030005,0x00000303,0x00006747,0x00040005,0x00000311,0x30653742, + 0x00000000,0x00030005,0x0000031c,0x00006748,0x00030005,0x0000032a,0x00006577,0x00040006, + 0x0000032a,0x00000000,0x00003464,0x00030005,0x0000032c,0x0000424f,0x00060005,0x0000033f, + 0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x000003a1,0x00004444,0x00030005, + 0x000003a5,0x00006277,0x00030005,0x000003b2,0x00006749,0x00040005,0x000003c8,0x306a3742, + 0x00000000,0x00030005,0x000003e4,0x00000045,0x00030005,0x000003e9,0x00003270,0x00030005, + 0x000003ec,0x00003470,0x00030005,0x000003f2,0x0000306e,0x00040005,0x000003f6,0x61726170, + 0x0000006d,0x00030005,0x000003f8,0x00003145,0x00040005,0x000003fc,0x61726170,0x0000006d, + 0x00040005,0x000003fe,0x61726170,0x0000006d,0x00030005,0x00000401,0x00000050,0x00040005, + 0x00000402,0x61726170,0x0000006d,0x00040005,0x00000404,0x61726170,0x0000006d,0x00040005, + 0x00000406,0x61726170,0x0000006d,0x00030005,0x0000040b,0x00003648,0x00030005,0x0000041a, + 0x0000316d,0x00040047,0x00000261,0x00000001,0x00000006,0x00040047,0x000002d7,0x00000006, + 0x00000008,0x00030047,0x000002d8,0x00000003,0x00040048,0x000002d8,0x00000000,0x00000018, + 0x00050048,0x000002d8,0x00000000,0x00000023,0x00000000,0x00030047,0x000002da,0x00000018, + 0x00040047,0x000002da,0x00000021,0x00000004,0x00040047,0x000002da,0x00000022,0x00000000, + 0x00040047,0x000002ea,0x00000001,0x00000004,0x00040047,0x00000303,0x00000001,0x00000000, + 0x00030047,0x00000311,0x00000000,0x00040047,0x00000311,0x00000021,0x00000001,0x00040047, + 0x00000311,0x00000022,0x00000002,0x00040047,0x00000311,0x0000002b,0x00000001,0x00040047, + 0x0000031c,0x00000001,0x00000001,0x00040047,0x00000329,0x00000006,0x00000010,0x00030047, + 0x0000032a,0x00000003,0x00040048,0x0000032a,0x00000000,0x00000018,0x00050048,0x0000032a, + 0x00000000,0x00000023,0x00000000,0x00030047,0x0000032c,0x00000018,0x00040047,0x0000032c, + 0x00000021,0x00000005,0x00040047,0x0000032c,0x00000022,0x00000000,0x00040047,0x0000033f, + 0x0000000b,0x0000000f,0x00030047,0x000003a1,0x00000000,0x00040047,0x000003a1,0x00000021, + 0x00000009,0x00040047,0x000003a1,0x00000022,0x00000000,0x00030047,0x000003a5,0x00000000, + 0x00040047,0x000003a5,0x00000021,0x00000009,0x00040047,0x000003a5,0x00000022,0x00000000, + 0x00040047,0x000003b2,0x00000001,0x00000002,0x00030047,0x000003c8,0x00000000,0x00040047, + 0x000003c8,0x00000021,0x00000000,0x00040047,0x000003c8,0x00000022,0x00000002,0x00040047, + 0x000003c8,0x0000002b,0x00000000,0x00030047,0x000003ec,0x00000017,0x00040047,0x000003ec, + 0x00000021,0x00000003,0x00040047,0x000003ec,0x00000022,0x00000002,0x00030047,0x000003f2, + 0x00000000,0x00030047,0x000003f8,0x00000000,0x00030047,0x000003fe,0x00000000,0x00030047, + 0x000003ff,0x00000000,0x00030047,0x00000401,0x00000000,0x00030047,0x00000403,0x00000000, + 0x00030047,0x00000404,0x00000000,0x00030047,0x00000405,0x00000000,0x00030047,0x00000406, + 0x00000000,0x00030047,0x0000040d,0x00000000,0x00030047,0x0000040e,0x00000000,0x00030047, + 0x00000413,0x00000000,0x00030047,0x00000414,0x00000000,0x00030047,0x00000417,0x00000000, + 0x00030047,0x0000041a,0x00000000,0x00040047,0x0000041a,0x0000001e,0x00000000,0x00030047, + 0x0000041b,0x00000000,0x00030047,0x0000042e,0x00000000,0x00030047,0x00000435,0x00000000, + 0x00030047,0x00000436,0x00000000,0x00030047,0x00000439,0x00000000,0x00030047,0x0000043a, + 0x00000000,0x00030047,0x0000043b,0x00000000,0x00030047,0x0000043e,0x00000000,0x00030047, + 0x0000043f,0x00000000,0x00030047,0x00000441,0x00000000,0x00030047,0x00000443,0x00000000, + 0x00030047,0x00000444,0x00000000,0x00030047,0x00000445,0x00000000,0x00030047,0x00000448, + 0x00000000,0x00030047,0x00000449,0x00000000,0x00030047,0x0000044e,0x00000000,0x00030047, + 0x00000450,0x00000000,0x00030047,0x00000452,0x00000000,0x00030047,0x0000045b,0x00000000, + 0x00030047,0x0000045d,0x00000000,0x00030047,0x0000045e,0x00000000,0x00030047,0x0000045f, + 0x00000000,0x00030047,0x00000460,0x00000000,0x00030047,0x00000465,0x00000000,0x00030047, + 0x0000046b,0x00000000,0x00030047,0x0000046c,0x00000000,0x00030047,0x00000475,0x00000000, + 0x00030047,0x00000476,0x00000000,0x00030047,0x00000477,0x00000000,0x00030047,0x00000478, + 0x00000000,0x00030047,0x00000479,0x00000000,0x00030047,0x0000047a,0x00000000,0x00030047, + 0x0000047b,0x00000000,0x00030047,0x0000047e,0x00000000,0x00030047,0x00000481,0x00000000, + 0x00030047,0x00000489,0x00000000,0x00030047,0x0000048a,0x00000000,0x00030047,0x0000048c, + 0x00000000,0x00030047,0x000004b5,0x00000000,0x00030047,0x000004b7,0x00000000,0x00030047, + 0x000004b8,0x00000000,0x00030047,0x000004b9,0x00000000,0x00030047,0x000004ba,0x00000000, + 0x00030047,0x000004bb,0x00000000,0x00030047,0x000004bc,0x00000000,0x00030047,0x000004bd, + 0x00000000,0x00030047,0x000004f6,0x00000000,0x00030047,0x000004f7,0x00000000,0x00030047, + 0x000004fc,0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047,0x00000500,0x00000000, + 0x00030047,0x00000501,0x00000000,0x00030047,0x00000505,0x00000000,0x00030047,0x00000513, + 0x00000000,0x00030047,0x00000514,0x00000000,0x00030047,0x00000515,0x00000000,0x00030047, + 0x00000516,0x00000000,0x00030047,0x00000517,0x00000000,0x00030047,0x00000518,0x00000000, + 0x00030047,0x00000522,0x00000000,0x00030047,0x00000523,0x00000000,0x00030047,0x00000524, + 0x00000000,0x00030047,0x00000525,0x00000000,0x00030047,0x0000052c,0x00000000,0x00030047, + 0x0000052e,0x00000000,0x00030047,0x0000052f,0x00000000,0x00030047,0x00000531,0x00000000, + 0x00030047,0x00000532,0x00000000,0x00030047,0x00000534,0x00000000,0x00030047,0x00000535, + 0x00000000,0x00030047,0x0000053f,0x00000000,0x00030047,0x00000541,0x00000000,0x00030047, + 0x00000542,0x00000000,0x00030047,0x00000545,0x00000000,0x00030047,0x00000546,0x00000000, + 0x00030047,0x00000548,0x00000000,0x00030047,0x0000054a,0x00000000,0x00030047,0x0000054c, + 0x00000000,0x00030047,0x0000055a,0x00000000,0x00030047,0x0000055b,0x00000000,0x00030047, + 0x0000055e,0x00000000,0x00030047,0x0000055f,0x00000000,0x00030047,0x00000560,0x00000000, + 0x00030047,0x00000562,0x00000000,0x00030047,0x00000564,0x00000000,0x00030047,0x00000566, + 0x00000000,0x00030047,0x00000568,0x00000000,0x00030047,0x0000056a,0x00000000,0x00030047, + 0x00000578,0x00000000,0x00030047,0x00000579,0x00000000,0x00030047,0x0000057c,0x00000000, + 0x00030047,0x0000057d,0x00000000,0x00030047,0x0000057e,0x00000000,0x00030047,0x0000057f, + 0x00000000,0x00030047,0x00000580,0x00000000,0x00030047,0x00000581,0x00000000,0x00030047, + 0x00000582,0x00000000,0x00030047,0x00000584,0x00000000,0x00030047,0x00000585,0x00000000, + 0x00030047,0x00000586,0x00000000,0x00030047,0x00000588,0x00000000,0x00030047,0x00000589, + 0x00000000,0x00030047,0x0000058b,0x00000000,0x00030047,0x0000058d,0x00000000,0x00030047, + 0x0000058e,0x00000000,0x00030047,0x0000058f,0x00000000,0x00030047,0x00000590,0x00000000, + 0x00030047,0x00000591,0x00000000,0x00030047,0x00000592,0x00000000,0x00030047,0x00000593, + 0x00000000,0x00030047,0x00000594,0x00000000,0x00030047,0x00000595,0x00000000,0x00030047, + 0x00000596,0x00000000,0x00030047,0x00000597,0x00000000,0x00030047,0x00000598,0x00000000, + 0x00030047,0x00000599,0x00000000,0x00030047,0x0000059a,0x00000000,0x00030047,0x0000059b, + 0x00000000,0x00030047,0x0000059c,0x00000000,0x00030047,0x0000059d,0x00000000,0x00030047, + 0x0000059e,0x00000000,0x00030047,0x0000059f,0x00000000,0x00030047,0x000005a0,0x00000000, + 0x00030047,0x000005a2,0x00000000,0x00030047,0x000005a3,0x00000000,0x00030047,0x000005a4, + 0x00000000,0x00030047,0x000005a5,0x00000000,0x00030047,0x000005a6,0x00000000,0x00030047, + 0x000005a7,0x00000000,0x00030047,0x000005a8,0x00000000,0x00030047,0x000005a9,0x00000000, + 0x00030047,0x000005aa,0x00000000,0x00030047,0x000005ab,0x00000000,0x00030047,0x000005ac, + 0x00000000,0x00030047,0x000005ad,0x00000000,0x00030047,0x000005ae,0x00000000,0x00030047, + 0x000005af,0x00000000,0x00030047,0x000005b0,0x00000000,0x00030047,0x000005b1,0x00000000, + 0x00030047,0x000005b2,0x00000000,0x00030047,0x000005b3,0x00000000,0x00030047,0x000005b4, + 0x00000000,0x00030047,0x000005b6,0x00000000,0x00030047,0x000005b8,0x00000000,0x00030047, + 0x000005ba,0x00000000,0x00030047,0x000005bb,0x00000000,0x00030047,0x000005bc,0x00000000, + 0x00030047,0x000005be,0x00000000,0x00030047,0x000005bf,0x00000000,0x00030047,0x000005c0, + 0x00000000,0x00030047,0x000005c1,0x00000000,0x00030047,0x000005c2,0x00000000,0x00030047, + 0x000005c3,0x00000000,0x00030047,0x000005c4,0x00000000,0x00030047,0x000005c6,0x00000000, + 0x00030047,0x000005c7,0x00000000,0x00030047,0x000005c8,0x00000000,0x00030047,0x000005c9, + 0x00000000,0x00030047,0x000005ca,0x00000000,0x00030047,0x000005cb,0x00000000,0x00030047, + 0x000005cc,0x00000000,0x00030047,0x000005cd,0x00000000,0x00030047,0x000005ce,0x00000000, + 0x00030047,0x000005cf,0x00000000,0x00030047,0x000005d0,0x00000000,0x00030047,0x000005d2, + 0x00000000,0x00030047,0x000005d3,0x00000000,0x00030047,0x000005d4,0x00000000,0x00030047, + 0x000005d6,0x00000000,0x00030047,0x000005d7,0x00000000,0x00030047,0x000005d8,0x00000000, + 0x00030047,0x000005da,0x00000000,0x00030047,0x000005db,0x00000000,0x00030047,0x000005dc, + 0x00000000,0x00030047,0x000005de,0x00000000,0x00030047,0x000005df,0x00000000,0x00030047, + 0x000005e1,0x00000000,0x00030047,0x000005e2,0x00000000,0x00030047,0x000005e3,0x00000000, + 0x00030047,0x000005ea,0x00000000,0x00030047,0x000005eb,0x00000000,0x00030047,0x000005ee, + 0x00000000,0x00030047,0x000005f0,0x00000000,0x00030047,0x000005f1,0x00000000,0x00030047, + 0x000005f3,0x00000000,0x00030047,0x000005f4,0x00000000,0x00030047,0x000005f5,0x00000000, + 0x00030047,0x000005f6,0x00000000,0x00030047,0x000005f7,0x00000000,0x00030047,0x000005f8, + 0x00000000,0x00030047,0x000005f9,0x00000000,0x00030047,0x000005fa,0x00000000,0x00030047, + 0x000005fb,0x00000000,0x00030047,0x000005fd,0x00000000,0x00030047,0x000005fe,0x00000000, + 0x00030047,0x00000600,0x00000000,0x00030047,0x00000603,0x00000000,0x00030047,0x00000604, + 0x00000000,0x00030047,0x00000605,0x00000000,0x00030047,0x00000607,0x00000000,0x00030047, + 0x00000608,0x00000000,0x00030047,0x00000609,0x00000000,0x00030047,0x00000611,0x00000000, + 0x00030047,0x00000617,0x00000000,0x00030047,0x00000618,0x00000000,0x00030047,0x00000619, + 0x00000000,0x00030047,0x0000061a,0x00000000,0x00030047,0x0000061b,0x00000000,0x00030047, + 0x0000061d,0x00000000,0x00030047,0x0000061e,0x00000000,0x00030047,0x00000620,0x00000000, + 0x00030047,0x00000621,0x00000000,0x00030047,0x00000622,0x00000000,0x00030047,0x00000623, + 0x00000000,0x00030047,0x00000624,0x00000000,0x00030047,0x00000625,0x00000000,0x00030047, + 0x00000626,0x00000000,0x00030047,0x00000628,0x00000000,0x00030047,0x00000629,0x00000000, + 0x00030047,0x0000062a,0x00000000,0x00030047,0x0000062c,0x00000000,0x00030047,0x0000062d, + 0x00000000,0x00030047,0x0000062e,0x00000000,0x00030047,0x0000062f,0x00000000,0x00030047, + 0x00000630,0x00000000,0x00030047,0x00000631,0x00000000,0x00030047,0x00000632,0x00000000, + 0x00030047,0x00000633,0x00000000,0x00030047,0x00000634,0x00000000,0x00030047,0x00000635, + 0x00000000,0x00030047,0x00000636,0x00000000,0x00030047,0x00000638,0x00000000,0x00030047, + 0x00000639,0x00000000,0x00030047,0x0000063a,0x00000000,0x00030047,0x00000643,0x00000000, + 0x00030047,0x00000649,0x00000000,0x00030047,0x0000064a,0x00000000,0x00030047,0x0000064f, + 0x00000000,0x00030047,0x00000655,0x00000000,0x00030047,0x00000656,0x00000000,0x00030047, + 0x00000657,0x00000000,0x00030047,0x0000065a,0x00000000,0x00030047,0x0000065b,0x00000000, + 0x00030047,0x0000065c,0x00000000,0x00030047,0x00000662,0x00000000,0x00030047,0x00000663, + 0x00000000,0x00030047,0x00000664,0x00000000,0x00030047,0x0000066c,0x00000000,0x00030047, + 0x0000066d,0x00000000,0x00030047,0x0000066e,0x00000000,0x00030047,0x0000066f,0x00000000, + 0x00030047,0x00000670,0x00000000,0x00030047,0x00000671,0x00000000,0x00030047,0x00000672, + 0x00000000,0x00030047,0x00000673,0x00000000,0x00030047,0x00000674,0x00000000,0x00030047, + 0x00000676,0x00000000,0x00030047,0x00000677,0x00000000,0x00030047,0x00000678,0x00000000, + 0x00030047,0x00000679,0x00000000,0x00030047,0x0000067b,0x00000000,0x00030047,0x0000067c, + 0x00000000,0x00030047,0x0000067d,0x00000000,0x00030047,0x0000067e,0x00000000,0x00030047, + 0x0000067f,0x00000000,0x00030047,0x00000680,0x00000000,0x00030047,0x00000681,0x00000000, + 0x00030047,0x00000682,0x00000000,0x00030047,0x00000685,0x00000000,0x00030047,0x00000688, + 0x00000000,0x00030047,0x00000689,0x00000000,0x00030047,0x0000068a,0x00000000,0x00030047, + 0x0000068b,0x00000000,0x00030047,0x00000690,0x00000000,0x00030047,0x00000693,0x00000000, + 0x00030047,0x00000694,0x00000000,0x00030047,0x00000695,0x00000000,0x00030047,0x00000696, + 0x00000000,0x00030047,0x0000069b,0x00000000,0x00030047,0x0000069e,0x00000000,0x00030047, + 0x0000069f,0x00000000,0x00030047,0x000006a0,0x00000000,0x00030047,0x000006a5,0x00000000, + 0x00030047,0x000006a8,0x00000000,0x00030047,0x000006a9,0x00000000,0x00030047,0x000006aa, + 0x00000000,0x00030047,0x000006ae,0x00000000,0x00030047,0x000006af,0x00000000,0x00030047, + 0x000006b0,0x00000000,0x00030047,0x000006b2,0x00000000,0x00030047,0x000006b3,0x00000000, + 0x00030047,0x000006b5,0x00000000,0x00030047,0x000006b9,0x00000000,0x00030047,0x000006ba, + 0x00000000,0x00030047,0x000006bd,0x00000000,0x00030047,0x000006be,0x00000000,0x00030047, + 0x000006bf,0x00000000,0x00030047,0x000006c0,0x00000000,0x00030047,0x000006c2,0x00000000, + 0x00030047,0x000006c4,0x00000000,0x00030047,0x000006c6,0x00000000,0x00030047,0x000006c8, + 0x00000000,0x00030047,0x000006c9,0x00000000,0x00030047,0x000006ca,0x00000000,0x00030047, + 0x000006cc,0x00000000,0x00030047,0x000006ce,0x00000000,0x00030047,0x000006d0,0x00000000, + 0x00030047,0x000006d2,0x00000000,0x00030047,0x000006d3,0x00000000,0x00030047,0x000006d4, + 0x00000000,0x00030047,0x000006d6,0x00000000,0x00030047,0x000006d8,0x00000000,0x00030047, + 0x000006da,0x00000000,0x00030047,0x000006dc,0x00000000,0x00030047,0x000006dd,0x00000000, + 0x00030047,0x000006de,0x00000000,0x00030047,0x000006e0,0x00000000,0x00030047,0x000006e2, + 0x00000000,0x00030047,0x000006e4,0x00000000,0x00030047,0x000006e6,0x00000000,0x00030047, + 0x000006e7,0x00000000,0x00030047,0x000006e8,0x00000000,0x00030047,0x000006ea,0x00000000, + 0x00030047,0x000006ec,0x00000000,0x00030047,0x000006ee,0x00000000,0x00030047,0x000006f0, + 0x00000000,0x00030047,0x000006f1,0x00000000,0x00030047,0x000006f2,0x00000000,0x00030047, + 0x000006f4,0x00000000,0x00030047,0x000006f6,0x00000000,0x00030047,0x000006f8,0x00000000, + 0x00030047,0x000006fa,0x00000000,0x00030047,0x000006fb,0x00000000,0x00030047,0x000006fc, + 0x00000000,0x00030047,0x000006fe,0x00000000,0x00030047,0x00000700,0x00000000,0x00030047, + 0x00000702,0x00000000,0x00030047,0x00000704,0x00000000,0x00030047,0x00000705,0x00000000, + 0x00030047,0x00000706,0x00000000,0x00030047,0x00000708,0x00000000,0x00030047,0x0000070a, + 0x00000000,0x00030047,0x0000070c,0x00000000,0x00030047,0x0000070e,0x00000000,0x00030047, + 0x0000070f,0x00000000,0x00030047,0x00000710,0x00000000,0x00030047,0x00000712,0x00000000, + 0x00030047,0x00000714,0x00000000,0x00030047,0x00000716,0x00000000,0x00030047,0x00000718, + 0x00000000,0x00030047,0x00000719,0x00000000,0x00030047,0x0000071a,0x00000000,0x00030047, + 0x0000071c,0x00000000,0x00030047,0x0000071e,0x00000000,0x00030047,0x00000720,0x00000000, + 0x00030047,0x00000722,0x00000000,0x00030047,0x00000723,0x00000000,0x00030047,0x00000724, + 0x00000000,0x00030047,0x00000726,0x00000000,0x00030047,0x00000728,0x00000000,0x00030047, + 0x0000072a,0x00000000,0x00030047,0x0000072c,0x00000000,0x00030047,0x0000072d,0x00000000, + 0x00030047,0x0000072e,0x00000000,0x00030047,0x00000730,0x00000000,0x00030047,0x00000732, + 0x00000000,0x00030047,0x00000734,0x00000000,0x00030047,0x00000736,0x00000000,0x00030047, + 0x00000737,0x00000000,0x00030047,0x00000738,0x00000000,0x00030047,0x0000073a,0x00000000, + 0x00030047,0x0000073c,0x00000000,0x00030047,0x0000073e,0x00000000,0x00030047,0x00000740, + 0x00000000,0x00030047,0x00000741,0x00000000,0x00030047,0x00000742,0x00000000,0x00030047, + 0x00000744,0x00000000,0x00030047,0x00000746,0x00000000,0x00030047,0x00000748,0x00000000, + 0x00030047,0x0000074a,0x00000000,0x00030047,0x0000074c,0x00000000,0x00030047,0x0000074d, + 0x00000000,0x00030047,0x0000074e,0x00000000,0x00030047,0x00000750,0x00000000,0x00030047, + 0x00000752,0x00000000,0x00030047,0x00000753,0x00000000,0x00030047,0x00000754,0x00000000, + 0x00030047,0x00000756,0x00000000,0x00030047,0x00000758,0x00000000,0x00030047,0x0000075a, + 0x00000000,0x00030047,0x0000075b,0x00000000,0x00030047,0x0000075d,0x00000000,0x00030047, + 0x0000075e,0x00000000,0x00030047,0x0000075f,0x00000000,0x00030047,0x00000760,0x00000000, + 0x00030047,0x00000766,0x00000000,0x00030047,0x00000769,0x00000000,0x00030047,0x0000076b, + 0x00000000,0x00030047,0x0000076c,0x00000000,0x00030047,0x0000076e,0x00000000,0x00030047, + 0x0000076f,0x00000000,0x00030047,0x00000772,0x00000000,0x00030047,0x00000773,0x00000000, + 0x00030047,0x00000774,0x00000000,0x00030047,0x00000777,0x00000000,0x00030047,0x00000779, + 0x00000000,0x00030047,0x0000077a,0x00000000,0x00030047,0x0000077b,0x00000000,0x00030047, + 0x0000077c,0x00000000,0x00030047,0x0000077e,0x00000000,0x00030047,0x0000077f,0x00000000, + 0x00030047,0x00000782,0x00000000,0x00030047,0x00000783,0x00000000,0x00030047,0x00000784, + 0x00000000,0x00030047,0x00000787,0x00000000,0x00030047,0x00000789,0x00000000,0x00030047, + 0x0000078a,0x00000000,0x00030047,0x0000078b,0x00000000,0x00030047,0x0000078c,0x00000000, + 0x00030047,0x0000078e,0x00000000,0x00030047,0x0000078f,0x00000000,0x00030047,0x00000792, + 0x00000000,0x00030047,0x00000793,0x00000000,0x00030047,0x00000794,0x00000000,0x00030047, + 0x00000797,0x00000000,0x00030047,0x00000799,0x00000000,0x00030047,0x0000079a,0x00000000, + 0x00030047,0x0000079b,0x00000000,0x00030047,0x0000079c,0x00000000,0x00030047,0x0000079e, + 0x00000000,0x00030047,0x0000079f,0x00000000,0x00030047,0x000007a2,0x00000000,0x00030047, + 0x000007a3,0x00000000,0x00030047,0x000007a4,0x00000000,0x00030047,0x000007a7,0x00000000, + 0x00030047,0x000007a9,0x00000000,0x00030047,0x000007aa,0x00000000,0x00030047,0x000007ab, + 0x00000000,0x00030047,0x000007ac,0x00000000,0x00030047,0x000007ad,0x00000000,0x00030047, + 0x000007ae,0x00000000,0x00030047,0x000007af,0x00000000,0x00030047,0x000007b0,0x00000000, + 0x00030047,0x000007b1,0x00000000,0x00030047,0x000007b2,0x00000000,0x00030047,0x000007b3, + 0x00000000,0x00030047,0x000007b4,0x00000000,0x00030047,0x000007b5,0x00000000,0x00030047, + 0x000007b6,0x00000000,0x00030047,0x000007b7,0x00000000,0x00030047,0x000007b8,0x00000000, + 0x00030047,0x000007b9,0x00000000,0x00030047,0x000007bb,0x00000000,0x00030047,0x000007bd, + 0x00000000,0x00030047,0x000007be,0x00000000,0x00030047,0x000007c0,0x00000000,0x00030047, + 0x000007c1,0x00000000,0x00030047,0x000007c2,0x00000000,0x00030047,0x000007c3,0x00000000, + 0x00030047,0x000007c4,0x00000000,0x00030047,0x000007c7,0x00000000,0x00030047,0x000007c9, + 0x00000000,0x00030047,0x000007ca,0x00000000,0x00030047,0x000007cd,0x00000000,0x00030047, + 0x000007ce,0x00000000,0x00030047,0x000007d1,0x00000000,0x00030047,0x000007d3,0x00000000, + 0x00030047,0x000007d4,0x00000000,0x00030047,0x000007d5,0x00000000,0x00030047,0x000007d6, + 0x00000000,0x00030047,0x000007d7,0x00000000,0x00030047,0x000007d8,0x00000000,0x00030047, + 0x000007d9,0x00000000,0x00030047,0x000007da,0x00000000,0x00030047,0x000007db,0x00000000, + 0x00030047,0x000007dc,0x00000000,0x00030047,0x000007dd,0x00000000,0x00030047,0x000007de, + 0x00000000,0x00030047,0x000007df,0x00000000,0x00030047,0x000007e1,0x00000000,0x00030047, + 0x000007e3,0x00000000,0x00030047,0x000007e4,0x00000000,0x00030047,0x000007e5,0x00000000, + 0x00030047,0x000007e7,0x00000000,0x00030047,0x000007e9,0x00000000,0x00030047,0x000007eb, + 0x00000000,0x00030047,0x000007ed,0x00000000,0x00030047,0x000007ee,0x00000000,0x00030047, + 0x000007ef,0x00000000,0x00030047,0x000007f0,0x00000000,0x00030047,0x000007f1,0x00000000, + 0x00030047,0x000007f3,0x00000000,0x00030047,0x000007f5,0x00000000,0x00030047,0x000007f6, + 0x00000000,0x00030047,0x000007f7,0x00000000,0x00030047,0x000007f9,0x00000000,0x00030047, + 0x000007fb,0x00000000,0x00030047,0x000007fd,0x00000000,0x00030047,0x000007ff,0x00000000, + 0x00030047,0x00000800,0x00000000,0x00030047,0x00000801,0x00000000,0x00030047,0x00000803, + 0x00000000,0x00030047,0x00000805,0x00000000,0x00030047,0x00000807,0x00000000,0x00030047, + 0x00000808,0x00000000,0x00030047,0x00000809,0x00000000,0x00030047,0x0000080b,0x00000000, + 0x00030047,0x0000080d,0x00000000,0x00030047,0x0000080f,0x00000000,0x00030047,0x00000810, + 0x00000000,0x00030047,0x00000811,0x00000000,0x00030047,0x00000813,0x00000000,0x00030047, + 0x00000814,0x00000000,0x00030047,0x00000817,0x00000000,0x00030047,0x00000818,0x00000000, + 0x00030047,0x00000819,0x00000000,0x00030047,0x0000081c,0x00000000,0x00030047,0x0000081e, + 0x00000000,0x00030047,0x0000081f,0x00000000,0x00030047,0x00000820,0x00000000,0x00030047, + 0x00000821,0x00000000,0x00030047,0x00000823,0x00000000,0x00030047,0x00000824,0x00000000, + 0x00030047,0x00000827,0x00000000,0x00030047,0x00000828,0x00000000,0x00030047,0x00000829, + 0x00000000,0x00030047,0x0000082c,0x00000000,0x00030047,0x0000082e,0x00000000,0x00030047, + 0x0000082f,0x00000000,0x00030047,0x00000830,0x00000000,0x00030047,0x00000831,0x00000000, + 0x00030047,0x00000833,0x00000000,0x00030047,0x00000835,0x00000000,0x00030047,0x00000837, + 0x00000000,0x00030047,0x00000838,0x00000000,0x00030047,0x0000083a,0x00000000,0x00030047, + 0x0000083b,0x00000000,0x00030047,0x0000083c,0x00000000,0x00030047,0x0000083e,0x00000000, + 0x00030047,0x00000840,0x00000000,0x00030047,0x00000842,0x00000000,0x00030047,0x00000844, + 0x00000000,0x00030047,0x00000845,0x00000000,0x00030047,0x00000846,0x00000000,0x00030047, + 0x00000848,0x00000000,0x00030047,0x0000084a,0x00000000,0x00030047,0x0000084c,0x00000000, + 0x00030047,0x0000084e,0x00000000,0x00030047,0x00000850,0x00000000,0x00030047,0x00000851, + 0x00000000,0x00030047,0x00000852,0x00000000,0x00030047,0x00000854,0x00000000,0x00030047, + 0x00000856,0x00000000,0x00030047,0x00000857,0x00000000,0x00030047,0x00000858,0x00000000, + 0x00030047,0x0000085a,0x00000000,0x00030047,0x0000085c,0x00000000,0x00030047,0x0000085e, + 0x00000000,0x00030047,0x0000085f,0x00000000,0x00030047,0x00000861,0x00000000,0x00030047, + 0x00000862,0x00000000,0x00030047,0x00000863,0x00000000,0x00030047,0x00000864,0x00000000, + 0x00030047,0x0000086a,0x00000000,0x00030047,0x0000086d,0x00000000,0x00030047,0x0000086f, + 0x00000000,0x00030047,0x00000870,0x00000000,0x00030047,0x00000872,0x00000000,0x00030047, + 0x00000873,0x00000000,0x00030047,0x00000876,0x00000000,0x00030047,0x00000877,0x00000000, + 0x00030047,0x00000878,0x00000000,0x00030047,0x0000087b,0x00000000,0x00030047,0x0000087d, + 0x00000000,0x00030047,0x0000087e,0x00000000,0x00030047,0x0000087f,0x00000000,0x00030047, + 0x00000880,0x00000000,0x00030047,0x00000882,0x00000000,0x00030047,0x00000883,0x00000000, + 0x00030047,0x00000886,0x00000000,0x00030047,0x00000887,0x00000000,0x00030047,0x00000888, + 0x00000000,0x00030047,0x0000088b,0x00000000,0x00030047,0x0000088d,0x00000000,0x00030047, + 0x0000088e,0x00000000,0x00030047,0x0000088f,0x00000000,0x00030047,0x00000890,0x00000000, + 0x00030047,0x00000892,0x00000000,0x00030047,0x00000893,0x00000000,0x00030047,0x00000896, + 0x00000000,0x00030047,0x00000897,0x00000000,0x00030047,0x00000898,0x00000000,0x00030047, + 0x0000089b,0x00000000,0x00030047,0x0000089d,0x00000000,0x00030047,0x0000089e,0x00000000, + 0x00030047,0x0000089f,0x00000000,0x00030047,0x000008a0,0x00000000,0x00030047,0x000008a2, + 0x00000000,0x00030047,0x000008a3,0x00000000,0x00030047,0x000008a6,0x00000000,0x00030047, + 0x000008a7,0x00000000,0x00030047,0x000008a8,0x00000000,0x00030047,0x000008ab,0x00000000, + 0x00030047,0x000008ad,0x00000000,0x00030047,0x000008ae,0x00000000,0x00030047,0x000008af, + 0x00000000,0x00030047,0x000008b0,0x00000000,0x00030047,0x000008b1,0x00000000,0x00030047, + 0x000008b2,0x00000000,0x00030047,0x000008b3,0x00000000,0x00030047,0x000008b4,0x00000000, + 0x00030047,0x000008b5,0x00000000,0x00030047,0x000008b6,0x00000000,0x00030047,0x000008b7, + 0x00000000,0x00030047,0x000008b8,0x00000000,0x00030047,0x000008b9,0x00000000,0x00030047, + 0x000008ba,0x00000000,0x00030047,0x000008bb,0x00000000,0x00030047,0x000008bc,0x00000000, + 0x00030047,0x000008bd,0x00000000,0x00030047,0x000008bf,0x00000000,0x00030047,0x000008c1, + 0x00000000,0x00030047,0x000008c2,0x00000000,0x00030047,0x000008c4,0x00000000,0x00030047, + 0x000008c5,0x00000000,0x00030047,0x000008c6,0x00000000,0x00030047,0x000008c7,0x00000000, + 0x00030047,0x000008c8,0x00000000,0x00030047,0x000008cb,0x00000000,0x00030047,0x000008cd, + 0x00000000,0x00030047,0x000008ce,0x00000000,0x00030047,0x000008d1,0x00000000,0x00030047, + 0x000008d2,0x00000000,0x00030047,0x000008d5,0x00000000,0x00030047,0x000008d7,0x00000000, + 0x00030047,0x000008d8,0x00000000,0x00030047,0x000008d9,0x00000000,0x00030047,0x000008da, + 0x00000000,0x00030047,0x000008db,0x00000000,0x00030047,0x000008dc,0x00000000,0x00030047, + 0x000008dd,0x00000000,0x00030047,0x000008de,0x00000000,0x00030047,0x000008df,0x00000000, + 0x00030047,0x000008e0,0x00000000,0x00030047,0x000008e1,0x00000000,0x00030047,0x000008e2, + 0x00000000,0x00030047,0x000008e3,0x00000000,0x00030047,0x000008e5,0x00000000,0x00030047, + 0x000008e7,0x00000000,0x00030047,0x000008e8,0x00000000,0x00030047,0x000008e9,0x00000000, + 0x00030047,0x000008eb,0x00000000,0x00030047,0x000008ed,0x00000000,0x00030047,0x000008ef, + 0x00000000,0x00030047,0x000008f1,0x00000000,0x00030047,0x000008f2,0x00000000,0x00030047, + 0x000008f3,0x00000000,0x00030047,0x000008f4,0x00000000,0x00030047,0x000008f5,0x00000000, + 0x00030047,0x000008f7,0x00000000,0x00030047,0x000008f9,0x00000000,0x00030047,0x000008fa, + 0x00000000,0x00030047,0x000008fb,0x00000000,0x00030047,0x000008fd,0x00000000,0x00030047, + 0x000008ff,0x00000000,0x00030047,0x00000901,0x00000000,0x00030047,0x00000903,0x00000000, + 0x00030047,0x00000904,0x00000000,0x00030047,0x00000905,0x00000000,0x00030047,0x00000907, + 0x00000000,0x00030047,0x00000909,0x00000000,0x00030047,0x0000090b,0x00000000,0x00030047, + 0x0000090c,0x00000000,0x00030047,0x0000090d,0x00000000,0x00030047,0x0000090f,0x00000000, + 0x00030047,0x00000911,0x00000000,0x00030047,0x00000913,0x00000000,0x00030047,0x00000914, + 0x00000000,0x00030047,0x00000915,0x00000000,0x00030047,0x00000917,0x00000000,0x00030047, + 0x00000918,0x00000000,0x00030047,0x0000091b,0x00000000,0x00030047,0x0000091c,0x00000000, + 0x00030047,0x0000091d,0x00000000,0x00030047,0x00000920,0x00000000,0x00030047,0x00000922, + 0x00000000,0x00030047,0x00000923,0x00000000,0x00030047,0x00000924,0x00000000,0x00030047, + 0x00000925,0x00000000,0x00030047,0x00000927,0x00000000,0x00030047,0x00000928,0x00000000, + 0x00030047,0x0000092b,0x00000000,0x00030047,0x0000092c,0x00000000,0x00030047,0x0000092d, + 0x00000000,0x00030047,0x00000930,0x00000000,0x00030047,0x00000932,0x00000000,0x00030047, + 0x00000933,0x00000000,0x00030047,0x00000934,0x00000000,0x00030047,0x00000935,0x00000000, + 0x00030047,0x00000937,0x00000000,0x00030047,0x00000939,0x00000000,0x00030047,0x0000093b, + 0x00000000,0x00030047,0x0000093c,0x00000000,0x00030047,0x0000093e,0x00000000,0x00030047, + 0x0000093f,0x00000000,0x00030047,0x00000940,0x00000000,0x00030047,0x00000942,0x00000000, + 0x00030047,0x00000944,0x00000000,0x00030047,0x00000946,0x00000000,0x00030047,0x00000948, + 0x00000000,0x00030047,0x00000949,0x00000000,0x00030047,0x0000094a,0x00000000,0x00030047, + 0x0000094c,0x00000000,0x00030047,0x0000094e,0x00000000,0x00030047,0x00000950,0x00000000, + 0x00030047,0x00000952,0x00000000,0x00030047,0x00000953,0x00000000,0x00030047,0x00000954, + 0x00000000,0x00030047,0x00000955,0x00000000,0x00030047,0x00000956,0x00000000,0x00030047, + 0x00000957,0x00000000,0x00030047,0x00000958,0x00000000,0x00030047,0x00000959,0x00000000, + 0x00030047,0x0000095a,0x00000000,0x00030047,0x0000095b,0x00000000,0x00030047,0x0000095c, + 0x00000000,0x00030047,0x0000095d,0x00000000,0x00030047,0x0000095e,0x00000000,0x00030047, + 0x0000095f,0x00000000,0x00030047,0x00000960,0x00000000,0x00030047,0x00000961,0x00000000, + 0x00030047,0x00000963,0x00000000,0x00030047,0x00000965,0x00000000,0x00030047,0x00000966, + 0x00000000,0x00030047,0x00000968,0x00000000,0x00030047,0x00000969,0x00000000,0x00030047, + 0x0000096a,0x00000000,0x00030047,0x0000096b,0x00000000,0x00030047,0x0000096c,0x00000000, + 0x00030047,0x0000096f,0x00000000,0x00030047,0x00000971,0x00000000,0x00030047,0x00000972, + 0x00000000,0x00030047,0x00000975,0x00000000,0x00030047,0x00000976,0x00000000,0x00030047, + 0x00000979,0x00000000,0x00030047,0x0000097b,0x00000000,0x00030047,0x0000097c,0x00000000, + 0x00030047,0x0000097d,0x00000000,0x00030047,0x0000097e,0x00000000,0x00030047,0x0000097f, + 0x00000000,0x00030047,0x00000980,0x00000000,0x00030047,0x00000981,0x00000000,0x00030047, + 0x00000982,0x00000000,0x00030047,0x00000983,0x00000000,0x00030047,0x00000984,0x00000000, + 0x00030047,0x00000985,0x00000000,0x00030047,0x00000986,0x00000000,0x00030047,0x00000987, + 0x00000000,0x00030047,0x00000989,0x00000000,0x00030047,0x0000098b,0x00000000,0x00030047, + 0x0000098c,0x00000000,0x00030047,0x0000098d,0x00000000,0x00030047,0x0000098f,0x00000000, + 0x00030047,0x00000991,0x00000000,0x00030047,0x00000993,0x00000000,0x00030047,0x00000995, + 0x00000000,0x00030047,0x00000996,0x00000000,0x00030047,0x00000997,0x00000000,0x00030047, + 0x00000998,0x00000000,0x00030047,0x00000999,0x00000000,0x00030047,0x0000099b,0x00000000, + 0x00030047,0x0000099d,0x00000000,0x00030047,0x0000099e,0x00000000,0x00030047,0x0000099f, + 0x00000000,0x00030047,0x000009a1,0x00000000,0x00030047,0x000009a3,0x00000000,0x00030047, + 0x000009a5,0x00000000,0x00030047,0x000009a7,0x00000000,0x00030047,0x000009a8,0x00000000, + 0x00030047,0x000009a9,0x00000000,0x00030047,0x000009ab,0x00000000,0x00030047,0x000009ad, + 0x00000000,0x00030047,0x000009af,0x00000000,0x00030047,0x000009b0,0x00000000,0x00030047, + 0x000009b1,0x00000000,0x00030047,0x000009b3,0x00000000,0x00030047,0x000009b5,0x00000000, + 0x00030047,0x000009b7,0x00000000,0x00030047,0x000009b8,0x00000000,0x00030047,0x000009b9, + 0x00000000,0x00030047,0x000009bb,0x00000000,0x00030047,0x000009bc,0x00000000,0x00030047, + 0x000009bf,0x00000000,0x00030047,0x000009c0,0x00000000,0x00030047,0x000009c1,0x00000000, + 0x00030047,0x000009c4,0x00000000,0x00030047,0x000009c6,0x00000000,0x00030047,0x000009c7, + 0x00000000,0x00030047,0x000009c8,0x00000000,0x00030047,0x000009c9,0x00000000,0x00030047, + 0x000009cb,0x00000000,0x00030047,0x000009cc,0x00000000,0x00030047,0x000009cf,0x00000000, + 0x00030047,0x000009d0,0x00000000,0x00030047,0x000009d1,0x00000000,0x00030047,0x000009d4, + 0x00000000,0x00030047,0x000009d6,0x00000000,0x00030047,0x000009d7,0x00000000,0x00030047, + 0x000009d8,0x00000000,0x00030047,0x000009d9,0x00000000,0x00030047,0x000009db,0x00000000, + 0x00030047,0x000009dd,0x00000000,0x00030047,0x000009df,0x00000000,0x00030047,0x000009e0, + 0x00000000,0x00030047,0x000009e2,0x00000000,0x00030047,0x000009e3,0x00000000,0x00030047, + 0x000009e4,0x00000000,0x00030047,0x000009e6,0x00000000,0x00030047,0x000009e8,0x00000000, + 0x00030047,0x000009ea,0x00000000,0x00030047,0x000009ec,0x00000000,0x00030047,0x000009ed, + 0x00000000,0x00030047,0x000009ee,0x00000000,0x00030047,0x000009f0,0x00000000,0x00030047, + 0x000009f2,0x00000000,0x00030047,0x000009f4,0x00000000,0x00030047,0x000009f6,0x00000000, + 0x00030047,0x000009f7,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047,0x000009f9, + 0x00000000,0x00030047,0x000009fa,0x00000000,0x00030047,0x000009fb,0x00000000,0x00030047, + 0x000009fc,0x00000000,0x00030047,0x000009fd,0x00000000,0x00030047,0x000009fe,0x00000000, + 0x00030047,0x000009ff,0x00000000,0x00030047,0x00000a00,0x00000000,0x00030047,0x00000a01, + 0x00000000,0x00030047,0x00000a02,0x00000000,0x00030047,0x00000a03,0x00000000,0x00030047, + 0x00000a04,0x00000000,0x00030047,0x00000a05,0x00000000,0x00030047,0x00000a07,0x00000000, + 0x00030047,0x00000a09,0x00000000,0x00030047,0x00000a0a,0x00000000,0x00030047,0x00000a0c, + 0x00000000,0x00030047,0x00000a0d,0x00000000,0x00030047,0x00000a0e,0x00000000,0x00030047, + 0x00000a0f,0x00000000,0x00030047,0x00000a10,0x00000000,0x00030047,0x00000a13,0x00000000, + 0x00030047,0x00000a15,0x00000000,0x00030047,0x00000a16,0x00000000,0x00030047,0x00000a19, + 0x00000000,0x00030047,0x00000a1a,0x00000000,0x00030047,0x00000a1d,0x00000000,0x00030047, + 0x00000a1f,0x00000000,0x00030047,0x00000a20,0x00000000,0x00030047,0x00000a21,0x00000000, + 0x00030047,0x00000a22,0x00000000,0x00030047,0x00000a23,0x00000000,0x00030047,0x00000a24, + 0x00000000,0x00030047,0x00000a25,0x00000000,0x00030047,0x00000a26,0x00000000,0x00030047, + 0x00000a27,0x00000000,0x00030047,0x00000a28,0x00000000,0x00030047,0x00000a29,0x00000000, + 0x00030047,0x00000a2a,0x00000000,0x00030047,0x00000a2b,0x00000000,0x00030047,0x00000a2d, + 0x00000000,0x00030047,0x00000a2f,0x00000000,0x00030047,0x00000a30,0x00000000,0x00030047, + 0x00000a31,0x00000000,0x00030047,0x00000a33,0x00000000,0x00030047,0x00000a35,0x00000000, + 0x00030047,0x00000a37,0x00000000,0x00030047,0x00000a39,0x00000000,0x00030047,0x00000a3a, + 0x00000000,0x00030047,0x00000a3b,0x00000000,0x00030047,0x00000a3c,0x00000000,0x00030047, + 0x00000a3d,0x00000000,0x00030047,0x00000a3f,0x00000000,0x00030047,0x00000a41,0x00000000, + 0x00030047,0x00000a42,0x00000000,0x00030047,0x00000a43,0x00000000,0x00030047,0x00000a45, + 0x00000000,0x00030047,0x00000a47,0x00000000,0x00030047,0x00000a49,0x00000000,0x00030047, + 0x00000a4b,0x00000000,0x00030047,0x00000a4c,0x00000000,0x00030047,0x00000a4d,0x00000000, + 0x00030047,0x00000a4f,0x00000000,0x00030047,0x00000a51,0x00000000,0x00030047,0x00000a53, + 0x00000000,0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a55,0x00000000,0x00030047, + 0x00000a57,0x00000000,0x00030047,0x00000a59,0x00000000,0x00030047,0x00000a5b,0x00000000, + 0x00030047,0x00000a5c,0x00000000,0x00030047,0x00000a5d,0x00000000,0x00030047,0x00000a5f, + 0x00000000,0x00030047,0x00000a60,0x00000000,0x00030047,0x00000a63,0x00000000,0x00030047, + 0x00000a64,0x00000000,0x00030047,0x00000a65,0x00000000,0x00030047,0x00000a68,0x00000000, + 0x00030047,0x00000a6a,0x00000000,0x00030047,0x00000a6b,0x00000000,0x00030047,0x00000a6c, + 0x00000000,0x00030047,0x00000a6d,0x00000000,0x00030047,0x00000a6f,0x00000000,0x00030047, + 0x00000a70,0x00000000,0x00030047,0x00000a73,0x00000000,0x00030047,0x00000a74,0x00000000, + 0x00030047,0x00000a75,0x00000000,0x00030047,0x00000a78,0x00000000,0x00030047,0x00000a7a, + 0x00000000,0x00030047,0x00000a7b,0x00000000,0x00030047,0x00000a7c,0x00000000,0x00030047, + 0x00000a7d,0x00000000,0x00030047,0x00000a7f,0x00000000,0x00030047,0x00000a81,0x00000000, + 0x00030047,0x00000a83,0x00000000,0x00030047,0x00000a84,0x00000000,0x00030047,0x00000a86, + 0x00000000,0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a88,0x00000000,0x00030047, + 0x00000a8a,0x00000000,0x00030047,0x00000a8c,0x00000000,0x00030047,0x00000a8e,0x00000000, + 0x00030047,0x00000a90,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017, + 0x0000000c,0x00000006,0x00000002,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040015, + 0x00000012,0x00000020,0x00000000,0x00040020,0x00000013,0x00000007,0x00000012,0x00040017, + 0x00000024,0x00000006,0x00000003,0x00040017,0x0000002f,0x00000006,0x00000004,0x00040020, + 0x00000034,0x00000007,0x0000002f,0x00040018,0x00000035,0x0000000c,0x00000002,0x00040020, + 0x00000042,0x00000007,0x00000024,0x00040015,0x00000073,0x00000020,0x00000001,0x00040017, + 0x00000074,0x00000073,0x00000002,0x00040020,0x00000075,0x00000007,0x00000074,0x0004002b, + 0x00000012,0x00000091,0x00000000,0x0004002b,0x00000012,0x00000094,0x00000001,0x0004002b, + 0x00000012,0x000000a7,0x00000002,0x0004002b,0x00000012,0x000000be,0x00000003,0x0004002b, + 0x00000006,0x000000c7,0x3f800000,0x0004002b,0x00000006,0x000000c8,0x00000000,0x00020014, + 0x000000d6,0x0004002b,0x00000006,0x00000104,0x3e99999a,0x0004002b,0x00000006,0x00000105, + 0x3f170a3d,0x0004002b,0x00000006,0x00000106,0x3de147ae,0x0004002b,0x00000006,0x00000120, + 0x388205ff,0x0004002b,0x00000006,0x00000186,0x40000000,0x0004002b,0x00000006,0x0000018d, + 0x3f000000,0x00040017,0x00000193,0x000000d6,0x00000003,0x00040020,0x0000020f,0x00000007, + 0x00000073,0x0004002b,0x00000073,0x00000211,0x00000000,0x0004002b,0x00000073,0x00000218, + 0x00000003,0x0004002b,0x00000006,0x0000022a,0x3e800000,0x0004002b,0x00000006,0x0000022f, + 0x41800000,0x0004002b,0x00000006,0x00000234,0x41400000,0x0004002b,0x00000006,0x0000023a, + 0x40400000,0x0004002b,0x00000073,0x00000246,0x00000001,0x00030030,0x000000d6,0x00000261, + 0x0004002b,0x00000006,0x000002b5,0x3a000000,0x0004002b,0x00000006,0x000002b7,0xc2000000, + 0x0004002b,0x00000006,0x000002c7,0x3a808081,0x00040017,0x000002ca,0x000000d6,0x00000002, + 0x00040017,0x000002d4,0x00000012,0x00000002,0x00040020,0x000002d5,0x00000007,0x000002d4, + 0x0003001d,0x000002d7,0x000002d4,0x0003001e,0x000002d8,0x000002d7,0x00040020,0x000002d9, + 0x00000002,0x000002d8,0x0004003b,0x000002d9,0x000002da,0x00000002,0x00040020,0x000002dc, + 0x00000002,0x000002d4,0x0004002b,0x00000012,0x000002e3,0x00000300,0x00030030,0x000000d6, + 0x000002ea,0x0004002b,0x00000012,0x000002ef,0x00000200,0x0004002b,0x00000006,0x000002f9, + 0xbf800000,0x00030030,0x000000d6,0x00000303,0x0004002b,0x00000012,0x00000309,0x00000010, + 0x00090019,0x0000030f,0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000000,0x00040020,0x00000310,0x00000000,0x0000030f,0x0004003b,0x00000310,0x00000311, + 0x00000000,0x0005002c,0x00000074,0x00000313,0x00000211,0x00000211,0x00030030,0x000000d6, + 0x0000031c,0x0004002b,0x00000012,0x00000321,0x00000400,0x00040020,0x00000327,0x00000007, + 0x00000035,0x0003001d,0x00000329,0x0000002f,0x0003001e,0x0000032a,0x00000329,0x00040020, + 0x0000032b,0x00000002,0x0000032a,0x0004003b,0x0000032b,0x0000032c,0x00000002,0x0004002b, + 0x00000012,0x0000032e,0x00000004,0x00040020,0x00000332,0x00000002,0x0000002f,0x00040020, + 0x0000033e,0x00000001,0x0000002f,0x0004003b,0x0000033e,0x0000033f,0x00000001,0x0004002b, + 0x00000012,0x0000035f,0x0000000f,0x00090019,0x0000039f,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000003a0,0x00000000,0x0000039f, + 0x0004003b,0x000003a0,0x000003a1,0x00000000,0x0002001a,0x000003a3,0x00040020,0x000003a4, + 0x00000000,0x000003a3,0x0004003b,0x000003a4,0x000003a5,0x00000000,0x0003001b,0x000003a7, + 0x0000039f,0x00030030,0x000000d6,0x000003b2,0x0004002b,0x00000073,0x000003be,0x00000004, + 0x0004003b,0x00000310,0x000003c8,0x00000000,0x00090019,0x000003ea,0x00000012,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x000003eb,0x00000000, + 0x000003ea,0x0004003b,0x000003eb,0x000003ec,0x00000000,0x00040017,0x000003ef,0x00000012, + 0x00000004,0x0004002b,0x00000012,0x000003f4,0x0001ffff,0x0004002b,0x00000012,0x000003fa, + 0x00000011,0x00040020,0x00000419,0x00000003,0x0000002f,0x0004003b,0x00000419,0x0000041a, + 0x00000003,0x0006002c,0x00000024,0x0000042b,0x000000c7,0x000000c7,0x000000c7,0x0006002c, + 0x00000024,0x0000042c,0x0000018d,0x0000018d,0x0000018d,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000042,0x00000a87,0x00000007, + 0x0004003b,0x00000042,0x00000a88,0x00000007,0x0004003b,0x00000007,0x00000a84,0x00000007, + 0x0004003b,0x0000000d,0x00000a7c,0x00000007,0x0004003b,0x0000000d,0x00000a7d,0x00000007, + 0x0004003b,0x00000007,0x00000a75,0x00000007,0x0004003b,0x0000000d,0x00000a6c,0x00000007, + 0x0004003b,0x00000007,0x00000a6d,0x00000007,0x0004003b,0x00000007,0x00000a65,0x00000007, + 0x0004003b,0x0000000d,0x00000a5c,0x00000007,0x0004003b,0x00000007,0x00000a5d,0x00000007, + 0x0004003b,0x0000000d,0x00000a54,0x00000007,0x0004003b,0x0000000d,0x00000a55,0x00000007, + 0x0004003b,0x0000000d,0x00000a4c,0x00000007,0x0004003b,0x0000000d,0x00000a4d,0x00000007, + 0x0004003b,0x00000042,0x00000a42,0x00000007,0x0004003b,0x00000042,0x00000a43,0x00000007, + 0x0004003b,0x00000007,0x00000a3a,0x00000007,0x0004003b,0x00000007,0x00000a3b,0x00000007, + 0x0004003b,0x00000007,0x00000a3c,0x00000007,0x0004003b,0x00000007,0x00000a3d,0x00000007, + 0x0004003b,0x00000042,0x00000a30,0x00000007,0x0004003b,0x00000042,0x00000a31,0x00000007, + 0x0004003b,0x00000007,0x00000a28,0x00000007,0x0004003b,0x00000007,0x00000a29,0x00000007, + 0x0004003b,0x00000007,0x00000a2a,0x00000007,0x0004003b,0x00000007,0x00000a2b,0x00000007, + 0x0004003b,0x00000007,0x000009f7,0x00000007,0x0004003b,0x00000042,0x000009f8,0x00000007, + 0x0004003b,0x00000042,0x000009f9,0x00000007,0x0004003b,0x00000042,0x000009fa,0x00000007, + 0x0004003b,0x0000000d,0x000009fb,0x00000007,0x0004003b,0x00000007,0x000009fc,0x00000007, + 0x0004003b,0x00000007,0x000009fd,0x00000007,0x0004003b,0x00000007,0x000009fe,0x00000007, + 0x0004003b,0x00000042,0x000009ff,0x00000007,0x0004003b,0x00000042,0x00000a00,0x00000007, + 0x0004003b,0x00000007,0x00000a01,0x00000007,0x0004003b,0x00000007,0x00000a02,0x00000007, + 0x0004003b,0x00000007,0x00000a03,0x00000007,0x0004003b,0x00000007,0x00000a04,0x00000007, + 0x0004003b,0x00000042,0x00000a05,0x00000007,0x0004003b,0x00000042,0x000009ed,0x00000007, + 0x0004003b,0x00000042,0x000009ee,0x00000007,0x0004003b,0x00000042,0x000009e3,0x00000007, + 0x0004003b,0x00000042,0x000009e4,0x00000007,0x0004003b,0x00000007,0x000009e0,0x00000007, + 0x0004003b,0x0000000d,0x000009d8,0x00000007,0x0004003b,0x0000000d,0x000009d9,0x00000007, + 0x0004003b,0x00000007,0x000009d1,0x00000007,0x0004003b,0x0000000d,0x000009c8,0x00000007, + 0x0004003b,0x00000007,0x000009c9,0x00000007,0x0004003b,0x00000007,0x000009c1,0x00000007, + 0x0004003b,0x0000000d,0x000009b8,0x00000007,0x0004003b,0x00000007,0x000009b9,0x00000007, + 0x0004003b,0x0000000d,0x000009b0,0x00000007,0x0004003b,0x0000000d,0x000009b1,0x00000007, + 0x0004003b,0x0000000d,0x000009a8,0x00000007,0x0004003b,0x0000000d,0x000009a9,0x00000007, + 0x0004003b,0x00000042,0x0000099e,0x00000007,0x0004003b,0x00000042,0x0000099f,0x00000007, + 0x0004003b,0x00000007,0x00000996,0x00000007,0x0004003b,0x00000007,0x00000997,0x00000007, + 0x0004003b,0x00000007,0x00000998,0x00000007,0x0004003b,0x00000007,0x00000999,0x00000007, + 0x0004003b,0x00000042,0x0000098c,0x00000007,0x0004003b,0x00000042,0x0000098d,0x00000007, + 0x0004003b,0x00000007,0x00000984,0x00000007,0x0004003b,0x00000007,0x00000985,0x00000007, + 0x0004003b,0x00000007,0x00000986,0x00000007,0x0004003b,0x00000007,0x00000987,0x00000007, + 0x0004003b,0x00000007,0x00000953,0x00000007,0x0004003b,0x00000042,0x00000954,0x00000007, + 0x0004003b,0x00000042,0x00000955,0x00000007,0x0004003b,0x00000042,0x00000956,0x00000007, + 0x0004003b,0x0000000d,0x00000957,0x00000007,0x0004003b,0x00000007,0x00000958,0x00000007, + 0x0004003b,0x00000007,0x00000959,0x00000007,0x0004003b,0x00000007,0x0000095a,0x00000007, + 0x0004003b,0x00000042,0x0000095b,0x00000007,0x0004003b,0x00000042,0x0000095c,0x00000007, + 0x0004003b,0x00000007,0x0000095d,0x00000007,0x0004003b,0x00000007,0x0000095e,0x00000007, + 0x0004003b,0x00000007,0x0000095f,0x00000007,0x0004003b,0x00000007,0x00000960,0x00000007, + 0x0004003b,0x00000042,0x00000961,0x00000007,0x0004003b,0x00000042,0x00000949,0x00000007, + 0x0004003b,0x00000042,0x0000094a,0x00000007,0x0004003b,0x00000042,0x0000093f,0x00000007, + 0x0004003b,0x00000042,0x00000940,0x00000007,0x0004003b,0x00000007,0x0000093c,0x00000007, + 0x0004003b,0x0000000d,0x00000934,0x00000007,0x0004003b,0x0000000d,0x00000935,0x00000007, + 0x0004003b,0x00000007,0x0000092d,0x00000007,0x0004003b,0x0000000d,0x00000924,0x00000007, + 0x0004003b,0x00000007,0x00000925,0x00000007,0x0004003b,0x00000007,0x0000091d,0x00000007, + 0x0004003b,0x0000000d,0x00000914,0x00000007,0x0004003b,0x00000007,0x00000915,0x00000007, + 0x0004003b,0x0000000d,0x0000090c,0x00000007,0x0004003b,0x0000000d,0x0000090d,0x00000007, + 0x0004003b,0x0000000d,0x00000904,0x00000007,0x0004003b,0x0000000d,0x00000905,0x00000007, + 0x0004003b,0x00000042,0x000008fa,0x00000007,0x0004003b,0x00000042,0x000008fb,0x00000007, + 0x0004003b,0x00000007,0x000008f2,0x00000007,0x0004003b,0x00000007,0x000008f3,0x00000007, + 0x0004003b,0x00000007,0x000008f4,0x00000007,0x0004003b,0x00000007,0x000008f5,0x00000007, + 0x0004003b,0x00000042,0x000008e8,0x00000007,0x0004003b,0x00000042,0x000008e9,0x00000007, + 0x0004003b,0x00000007,0x000008e0,0x00000007,0x0004003b,0x00000007,0x000008e1,0x00000007, + 0x0004003b,0x00000007,0x000008e2,0x00000007,0x0004003b,0x00000007,0x000008e3,0x00000007, + 0x0004003b,0x00000007,0x000008af,0x00000007,0x0004003b,0x00000042,0x000008b0,0x00000007, + 0x0004003b,0x00000042,0x000008b1,0x00000007,0x0004003b,0x00000042,0x000008b2,0x00000007, + 0x0004003b,0x0000000d,0x000008b3,0x00000007,0x0004003b,0x00000007,0x000008b4,0x00000007, + 0x0004003b,0x00000007,0x000008b5,0x00000007,0x0004003b,0x00000007,0x000008b6,0x00000007, + 0x0004003b,0x00000042,0x000008b7,0x00000007,0x0004003b,0x00000042,0x000008b8,0x00000007, + 0x0004003b,0x00000007,0x000008b9,0x00000007,0x0004003b,0x00000007,0x000008ba,0x00000007, + 0x0004003b,0x00000007,0x000008bb,0x00000007,0x0004003b,0x00000007,0x000008bc,0x00000007, + 0x0004003b,0x00000042,0x000008bd,0x00000007,0x0004003b,0x00000007,0x000008a8,0x00000007, + 0x0004003b,0x0000000d,0x0000089f,0x00000007,0x0004003b,0x00000007,0x000008a0,0x00000007, + 0x0004003b,0x00000007,0x00000898,0x00000007,0x0004003b,0x0000000d,0x0000088f,0x00000007, + 0x0004003b,0x00000007,0x00000890,0x00000007,0x0004003b,0x00000007,0x00000888,0x00000007, + 0x0004003b,0x0000000d,0x0000087f,0x00000007,0x0004003b,0x00000007,0x00000880,0x00000007, + 0x0004003b,0x00000007,0x00000878,0x00000007,0x0004003b,0x0000000d,0x0000086f,0x00000007, + 0x0004003b,0x00000007,0x00000870,0x00000007,0x0004003b,0x00000007,0x0000084f,0x00000007, + 0x0004003b,0x00000042,0x00000850,0x00000007,0x0004003b,0x00000042,0x00000851,0x00000007, + 0x0004003b,0x00000042,0x00000852,0x00000007,0x0004003b,0x00000007,0x00000853,0x00000007, + 0x0004003b,0x00000042,0x00000854,0x00000007,0x0004003b,0x00000007,0x00000855,0x00000007, + 0x0004003b,0x00000042,0x00000856,0x00000007,0x0004003b,0x00000042,0x00000857,0x00000007, + 0x0004003b,0x00000042,0x00000858,0x00000007,0x0004003b,0x00000042,0x00000845,0x00000007, + 0x0004003b,0x00000042,0x00000846,0x00000007,0x0004003b,0x00000042,0x0000083b,0x00000007, + 0x0004003b,0x00000042,0x0000083c,0x00000007,0x0004003b,0x00000007,0x00000838,0x00000007, + 0x0004003b,0x0000000d,0x00000830,0x00000007,0x0004003b,0x0000000d,0x00000831,0x00000007, + 0x0004003b,0x00000007,0x00000829,0x00000007,0x0004003b,0x0000000d,0x00000820,0x00000007, + 0x0004003b,0x00000007,0x00000821,0x00000007,0x0004003b,0x00000007,0x00000819,0x00000007, + 0x0004003b,0x0000000d,0x00000810,0x00000007,0x0004003b,0x00000007,0x00000811,0x00000007, + 0x0004003b,0x0000000d,0x00000808,0x00000007,0x0004003b,0x0000000d,0x00000809,0x00000007, + 0x0004003b,0x0000000d,0x00000800,0x00000007,0x0004003b,0x0000000d,0x00000801,0x00000007, + 0x0004003b,0x00000042,0x000007f6,0x00000007,0x0004003b,0x00000042,0x000007f7,0x00000007, + 0x0004003b,0x00000007,0x000007ee,0x00000007,0x0004003b,0x00000007,0x000007ef,0x00000007, + 0x0004003b,0x00000007,0x000007f0,0x00000007,0x0004003b,0x00000007,0x000007f1,0x00000007, + 0x0004003b,0x00000042,0x000007e4,0x00000007,0x0004003b,0x00000042,0x000007e5,0x00000007, + 0x0004003b,0x00000007,0x000007dc,0x00000007,0x0004003b,0x00000007,0x000007dd,0x00000007, + 0x0004003b,0x00000007,0x000007de,0x00000007,0x0004003b,0x00000007,0x000007df,0x00000007, + 0x0004003b,0x00000007,0x000007ab,0x00000007,0x0004003b,0x00000042,0x000007ac,0x00000007, + 0x0004003b,0x00000042,0x000007ad,0x00000007,0x0004003b,0x00000042,0x000007ae,0x00000007, + 0x0004003b,0x0000000d,0x000007af,0x00000007,0x0004003b,0x00000007,0x000007b0,0x00000007, + 0x0004003b,0x00000007,0x000007b1,0x00000007,0x0004003b,0x00000007,0x000007b2,0x00000007, + 0x0004003b,0x00000042,0x000007b3,0x00000007,0x0004003b,0x00000042,0x000007b4,0x00000007, + 0x0004003b,0x00000007,0x000007b5,0x00000007,0x0004003b,0x00000007,0x000007b6,0x00000007, + 0x0004003b,0x00000007,0x000007b7,0x00000007,0x0004003b,0x00000007,0x000007b8,0x00000007, + 0x0004003b,0x00000042,0x000007b9,0x00000007,0x0004003b,0x00000007,0x000007a4,0x00000007, + 0x0004003b,0x0000000d,0x0000079b,0x00000007,0x0004003b,0x00000007,0x0000079c,0x00000007, + 0x0004003b,0x00000007,0x00000794,0x00000007,0x0004003b,0x0000000d,0x0000078b,0x00000007, + 0x0004003b,0x00000007,0x0000078c,0x00000007,0x0004003b,0x00000007,0x00000784,0x00000007, + 0x0004003b,0x0000000d,0x0000077b,0x00000007,0x0004003b,0x00000007,0x0000077c,0x00000007, + 0x0004003b,0x00000007,0x00000774,0x00000007,0x0004003b,0x0000000d,0x0000076b,0x00000007, + 0x0004003b,0x00000007,0x0000076c,0x00000007,0x0004003b,0x00000007,0x0000074b,0x00000007, + 0x0004003b,0x00000042,0x0000074c,0x00000007,0x0004003b,0x00000042,0x0000074d,0x00000007, + 0x0004003b,0x00000042,0x0000074e,0x00000007,0x0004003b,0x00000007,0x0000074f,0x00000007, + 0x0004003b,0x00000042,0x00000750,0x00000007,0x0004003b,0x00000007,0x00000751,0x00000007, + 0x0004003b,0x00000042,0x00000752,0x00000007,0x0004003b,0x00000042,0x00000753,0x00000007, + 0x0004003b,0x00000042,0x00000754,0x00000007,0x0004003b,0x00000042,0x00000741,0x00000007, + 0x0004003b,0x00000042,0x00000742,0x00000007,0x0004003b,0x00000042,0x00000737,0x00000007, + 0x0004003b,0x00000042,0x00000738,0x00000007,0x0004003b,0x00000042,0x0000072d,0x00000007, + 0x0004003b,0x00000042,0x0000072e,0x00000007,0x0004003b,0x00000042,0x00000723,0x00000007, + 0x0004003b,0x00000042,0x00000724,0x00000007,0x0004003b,0x00000042,0x00000719,0x00000007, + 0x0004003b,0x00000042,0x0000071a,0x00000007,0x0004003b,0x00000042,0x0000070f,0x00000007, + 0x0004003b,0x00000042,0x00000710,0x00000007,0x0004003b,0x00000042,0x00000705,0x00000007, + 0x0004003b,0x00000042,0x00000706,0x00000007,0x0004003b,0x00000042,0x000006fb,0x00000007, + 0x0004003b,0x00000042,0x000006fc,0x00000007,0x0004003b,0x00000042,0x000006f1,0x00000007, + 0x0004003b,0x00000042,0x000006f2,0x00000007,0x0004003b,0x00000042,0x000006e7,0x00000007, + 0x0004003b,0x00000042,0x000006e8,0x00000007,0x0004003b,0x00000042,0x000006dd,0x00000007, + 0x0004003b,0x00000042,0x000006de,0x00000007,0x0004003b,0x00000042,0x000006d3,0x00000007, + 0x0004003b,0x00000042,0x000006d4,0x00000007,0x0004003b,0x00000042,0x000006c9,0x00000007, + 0x0004003b,0x00000042,0x000006ca,0x00000007,0x0004003b,0x00000042,0x000006bf,0x00000007, + 0x0004003b,0x00000042,0x000006c0,0x00000007,0x0004003b,0x00000007,0x000006af,0x00000007, + 0x0004003b,0x00000042,0x000006b0,0x00000007,0x0004003b,0x00000042,0x0000058e,0x00000007, + 0x0004003b,0x00000034,0x0000058f,0x00000007,0x0004003b,0x00000042,0x00000590,0x00000007, + 0x0004003b,0x00000042,0x00000591,0x00000007,0x0004003b,0x00000007,0x00000592,0x00000007, + 0x0004003b,0x00000007,0x00000593,0x00000007,0x0004003b,0x00000042,0x00000594,0x00000007, + 0x0004003b,0x00000007,0x00000595,0x00000007,0x0004003b,0x00000007,0x00000596,0x00000007, + 0x0004003b,0x00000007,0x00000597,0x00000007,0x0004003b,0x00000007,0x00000598,0x00000007, + 0x0004003b,0x00000007,0x00000599,0x00000007,0x0004003b,0x00000007,0x0000059a,0x00000007, + 0x0004003b,0x00000007,0x0000059b,0x00000007,0x0004003b,0x00000042,0x0000059c,0x00000007, + 0x0004003b,0x00000007,0x0000059d,0x00000007,0x0004003b,0x00000007,0x0000059e,0x00000007, + 0x0004003b,0x00000042,0x0000059f,0x00000007,0x0004003b,0x00000007,0x000005a0,0x00000007, + 0x0004003b,0x0000020f,0x000005a1,0x00000007,0x0004003b,0x00000007,0x000005a2,0x00000007, + 0x0004003b,0x00000007,0x000005a3,0x00000007,0x0004003b,0x00000042,0x000005a4,0x00000007, + 0x0004003b,0x00000042,0x000005a5,0x00000007,0x0004003b,0x00000042,0x000005a6,0x00000007, + 0x0004003b,0x00000007,0x000005a7,0x00000007,0x0004003b,0x00000007,0x000005a8,0x00000007, + 0x0004003b,0x00000042,0x000005a9,0x00000007,0x0004003b,0x00000042,0x000005aa,0x00000007, + 0x0004003b,0x00000042,0x000005ab,0x00000007,0x0004003b,0x00000007,0x000005ac,0x00000007, + 0x0004003b,0x00000007,0x000005ad,0x00000007,0x0004003b,0x00000042,0x000005ae,0x00000007, + 0x0004003b,0x00000042,0x000005af,0x00000007,0x0004003b,0x00000007,0x000005b0,0x00000007, + 0x0004003b,0x00000007,0x000005b1,0x00000007,0x0004003b,0x00000042,0x000005b2,0x00000007, + 0x0004003b,0x00000042,0x000005b3,0x00000007,0x0004003b,0x00000042,0x000005b4,0x00000007, + 0x0004003b,0x00000042,0x0000057d,0x00000007,0x0004003b,0x00000042,0x0000057e,0x00000007, + 0x0004003b,0x00000034,0x0000057f,0x00000007,0x0004003b,0x00000013,0x00000580,0x00000007, + 0x0004003b,0x00000007,0x00000581,0x00000007,0x0004003b,0x00000042,0x00000582,0x00000007, + 0x0004003b,0x00000013,0x00000578,0x00000007,0x0004003b,0x00000013,0x00000579,0x00000007, + 0x0004003b,0x00000327,0x0000056b,0x00000007,0x0004003b,0x00000034,0x0000055f,0x00000007, + 0x0004003b,0x00000034,0x00000560,0x00000007,0x0004003b,0x0000000d,0x0000055a,0x00000007, + 0x0004003b,0x0000000d,0x0000055b,0x00000007,0x0004003b,0x00000327,0x0000054d,0x00000007, + 0x0004003b,0x0000000d,0x00000545,0x00000007,0x0004003b,0x0000000d,0x00000546,0x00000007, + 0x0004003b,0x00000007,0x00000532,0x00000007,0x0004003b,0x00000007,0x0000052f,0x00000007, + 0x0004003b,0x00000007,0x0000052c,0x00000007,0x0004003b,0x000002d5,0x00000442,0x00000007, + 0x0004003b,0x00000007,0x00000443,0x00000007,0x0004003b,0x00000007,0x00000444,0x00000007, + 0x0004003b,0x00000007,0x00000445,0x00000007,0x0004003b,0x00000013,0x00000446,0x00000007, + 0x0004003b,0x00000013,0x00000447,0x00000007,0x0004003b,0x00000034,0x00000448,0x00000007, + 0x0004003b,0x00000007,0x00000449,0x00000007,0x0004003b,0x00000327,0x0000044a,0x00000007, + 0x0004003b,0x00000034,0x0000044b,0x00000007,0x0004003b,0x00000034,0x0000044c,0x00000007, + 0x0004003b,0x0000000d,0x0000044d,0x00000007,0x0004003b,0x0000000d,0x0000044e,0x00000007, + 0x0004003b,0x0000000d,0x0000044f,0x00000007,0x0004003b,0x00000007,0x00000450,0x00000007, + 0x0004003b,0x00000013,0x00000451,0x00000007,0x0004003b,0x00000007,0x00000452,0x00000007, + 0x0004003b,0x00000327,0x00000453,0x00000007,0x0004003b,0x00000034,0x00000454,0x00000007, + 0x0004003b,0x00000034,0x00000455,0x00000007,0x0004003b,0x0000000d,0x00000456,0x00000007, + 0x0004003b,0x00000007,0x00000457,0x00000007,0x0004003b,0x00000007,0x00000458,0x00000007, + 0x0004003b,0x00000007,0x00000459,0x00000007,0x0004003b,0x00000007,0x0000045a,0x00000007, + 0x0004003b,0x00000013,0x0000045b,0x00000007,0x0004003b,0x00000013,0x0000045c,0x00000007, + 0x0004003b,0x00000034,0x0000045d,0x00000007,0x0004003b,0x00000042,0x0000045e,0x00000007, + 0x0004003b,0x00000034,0x0000045f,0x00000007,0x0004003b,0x00000013,0x00000460,0x00000007, + 0x0004003b,0x00000013,0x0000043f,0x00000007,0x0004003b,0x00000013,0x0000043a,0x00000007, + 0x0004003b,0x00000013,0x0000043b,0x00000007,0x0004003b,0x00000007,0x00000435,0x00000007, + 0x0004003b,0x00000007,0x00000436,0x00000007,0x0004003b,0x00000007,0x0000042d,0x00000007, + 0x0004003b,0x00000007,0x0000042e,0x00000007,0x0004003b,0x00000075,0x000003e4,0x00000007, + 0x0004003b,0x00000013,0x000003e9,0x00000007,0x0004003b,0x00000007,0x000003f2,0x00000007, + 0x0004003b,0x00000013,0x000003f6,0x00000007,0x0004003b,0x00000013,0x000003f8,0x00000007, + 0x0004003b,0x00000013,0x000003fc,0x00000007,0x0004003b,0x00000013,0x000003fe,0x00000007, + 0x0004003b,0x00000034,0x00000401,0x00000007,0x0004003b,0x00000013,0x00000402,0x00000007, + 0x0004003b,0x00000007,0x00000404,0x00000007,0x0004003b,0x00000034,0x00000406,0x00000007, + 0x0004003b,0x00000007,0x0000040b,0x00000007,0x0004003d,0x0000002f,0x000003e5,0x0000033f, + 0x0007004f,0x0000000c,0x000003e6,0x000003e5,0x000003e5,0x00000000,0x00000001,0x0006000c, + 0x0000000c,0x000003e7,0x00000001,0x00000008,0x000003e6,0x0004006e,0x00000074,0x000003e8, + 0x000003e7,0x0003003e,0x000003e4,0x000003e8,0x0004003d,0x000003ea,0x000003ed,0x000003ec, + 0x0004003d,0x00000074,0x000003ee,0x000003e4,0x00050062,0x000003ef,0x000003f0,0x000003ed, + 0x000003ee,0x00050051,0x00000012,0x000003f1,0x000003f0,0x00000000,0x0003003e,0x000003e9, + 0x000003f1,0x0004003d,0x00000012,0x000003f3,0x000003e9,0x000500c7,0x00000012,0x000003f5, + 0x000003f3,0x000003f4,0x0003003e,0x000003f6,0x000003f5,0x0004003d,0x00000012,0x00000430, + 0x000003f6,0x00040070,0x00000006,0x00000431,0x00000430,0x00050085,0x00000006,0x00000432, + 0x00000431,0x000002b5,0x00050081,0x00000006,0x00000433,0x00000432,0x000002b7,0x0003003e, + 0x0000042d,0x00000433,0x0004003d,0x00000006,0x00000438,0x0000042d,0x0003003e,0x00000435, + 0x00000438,0x0004003d,0x00000006,0x00000439,0x00000435,0x0003003e,0x00000436,0x00000439, + 0x0004003d,0x00000006,0x00000434,0x00000436,0x0003003e,0x0000042e,0x00000434,0x0004003d, + 0x00000006,0x000003f7,0x0000042e,0x0003003e,0x000003f2,0x000003f7,0x0004003d,0x00000012, + 0x000003f9,0x000003e9,0x000500c2,0x00000012,0x000003fb,0x000003f9,0x000003fa,0x0003003e, + 0x000003fc,0x000003fb,0x0004003d,0x00000012,0x0000043d,0x000003fc,0x0003003e,0x0000043a, + 0x0000043d,0x0004003d,0x00000012,0x0000043e,0x0000043a,0x0003003e,0x0000043b,0x0000043e, + 0x0004003d,0x00000012,0x000003fd,0x0000043b,0x0003003e,0x000003f8,0x000003fd,0x0004003d, + 0x00000012,0x000003ff,0x000003f8,0x0003003e,0x000003fe,0x000003ff,0x0004003d,0x00000012, + 0x00000441,0x000003fe,0x0003003e,0x0000043f,0x00000441,0x0004003d,0x00000012,0x00000400, + 0x0000043f,0x0003003e,0x000003f8,0x00000400,0x0004003d,0x00000012,0x00000403,0x000003f8, + 0x0003003e,0x00000402,0x00000403,0x0004003d,0x00000006,0x00000405,0x000003f2,0x0003003e, + 0x00000404,0x00000405,0x0004003d,0x00000012,0x00000462,0x00000402,0x00060041,0x000002dc, + 0x00000463,0x000002da,0x00000211,0x00000462,0x0004003d,0x000002d4,0x00000464,0x00000463, + 0x0003003e,0x00000442,0x00000464,0x0004003d,0x00000006,0x00000465,0x00000404,0x0003003e, + 0x00000443,0x00000465,0x00050041,0x00000013,0x00000466,0x00000442,0x00000091,0x0004003d, + 0x00000012,0x00000467,0x00000466,0x000500c7,0x00000012,0x00000468,0x00000467,0x000002e3, + 0x000500ab,0x000000d6,0x00000469,0x00000468,0x00000091,0x000300f7,0x0000047d,0x00000000, + 0x000400fa,0x00000469,0x0000046a,0x0000047d,0x000200f8,0x0000046a,0x0004003d,0x00000006, + 0x0000046b,0x00000443,0x0006000c,0x00000006,0x0000046c,0x00000001,0x00000004,0x0000046b, + 0x0003003e,0x00000443,0x0000046c,0x000300f7,0x00000472,0x00000000,0x000400fa,0x000002ea, + 0x0000046d,0x00000472,0x000200f8,0x0000046d,0x0004003d,0x00000012,0x0000046f,0x00000466, + 0x000500c7,0x00000012,0x00000470,0x0000046f,0x000002ef,0x000500ab,0x000000d6,0x00000471, + 0x00000470,0x00000091,0x000200f9,0x00000472,0x000200f8,0x00000472,0x000700f5,0x000000d6, + 0x00000473,0x000002ea,0x0000046a,0x00000471,0x0000046d,0x000300f7,0x0000047c,0x00000000, + 0x000400fa,0x00000473,0x00000474,0x0000047c,0x000200f8,0x00000474,0x0004003d,0x00000006, + 0x00000475,0x00000443,0x00050085,0x00000006,0x00000476,0x00000475,0x0000018d,0x0006000c, + 0x00000006,0x00000477,0x00000001,0x0000000a,0x00000476,0x00050085,0x00000006,0x00000478, + 0x00000477,0x00000186,0x00050081,0x00000006,0x00000479,0x00000478,0x000002f9,0x0006000c, + 0x00000006,0x0000047a,0x00000001,0x00000004,0x00000479,0x00050083,0x00000006,0x0000047b, + 0x000000c7,0x0000047a,0x0003003e,0x00000443,0x0000047b,0x000200f9,0x0000047c,0x000200f8, + 0x0000047c,0x000200f9,0x0000047d,0x000200f8,0x0000047d,0x0004003d,0x00000006,0x0000047e, + 0x00000443,0x0003003e,0x00000444,0x000000c8,0x0004003d,0x00000006,0x0000052e,0x00000444, + 0x0003003e,0x0000052c,0x0000052e,0x0004003d,0x00000006,0x0000047f,0x0000052c,0x0003003e, + 0x00000445,0x000000c7,0x0004003d,0x00000006,0x00000531,0x00000445,0x0003003e,0x0000052f, + 0x00000531,0x0004003d,0x00000006,0x00000480,0x0000052f,0x0008000c,0x00000006,0x00000481, + 0x00000001,0x0000002b,0x0000047e,0x0000047f,0x00000480,0x0003003e,0x00000443,0x00000481, + 0x000300f7,0x00000490,0x00000000,0x000400fa,0x00000303,0x00000482,0x00000490,0x000200f8, + 0x00000482,0x0004003d,0x00000012,0x00000484,0x00000466,0x000500c2,0x00000012,0x00000485, + 0x00000484,0x00000309,0x0003003e,0x00000446,0x00000485,0x0004003d,0x00000012,0x00000486, + 0x00000446,0x000500ab,0x000000d6,0x00000487,0x00000486,0x00000091,0x000300f7,0x0000048f, + 0x00000000,0x000400fa,0x00000487,0x00000488,0x0000048f,0x000200f8,0x00000488,0x0004003d, + 0x0000030f,0x00000489,0x00000311,0x00050062,0x0000002f,0x0000048a,0x00000489,0x00000313, + 0x0004003d,0x00000012,0x0000048b,0x00000446,0x0003003e,0x00000447,0x0000048b,0x0003003e, + 0x00000448,0x0000048a,0x0004003d,0x00000006,0x0000048c,0x00000443,0x0003003e,0x00000449, + 0x0000048c,0x0004003d,0x0000002f,0x00000534,0x00000448,0x0007004f,0x0000000c,0x00000535, + 0x00000534,0x00000534,0x00000000,0x00000001,0x0004003d,0x00000012,0x00000536,0x00000447, + 0x0006000c,0x0000002f,0x00000537,0x00000001,0x00000040,0x00000536,0x0007004f,0x0000000c, + 0x00000538,0x00000537,0x00000537,0x00000000,0x00000001,0x00050083,0x0000000c,0x00000539, + 0x00000535,0x00000538,0x0006000c,0x0000000c,0x0000053a,0x00000001,0x00000004,0x00000539, + 0x0003003e,0x00000532,0x000002c7,0x0004003d,0x00000006,0x00000548,0x00000532,0x00050041, + 0x00000007,0x00000549,0x00000545,0x00000091,0x0003003e,0x00000549,0x00000548,0x0004003d, + 0x00000006,0x0000054a,0x00000532,0x00050041,0x00000007,0x0000054b,0x00000545,0x00000094, + 0x0003003e,0x0000054b,0x0000054a,0x0004003d,0x0000000c,0x0000054c,0x00000545,0x0003003e, + 0x00000546,0x0000054c,0x0004003d,0x0000000c,0x0000053b,0x00000546,0x000500b8,0x000002ca, + 0x0000053c,0x0000053a,0x0000053b,0x0004009b,0x000000d6,0x0000053d,0x0000053c,0x000300f7, + 0x00000544,0x00000000,0x000400fa,0x0000053d,0x0000053e,0x00000543,0x000200f8,0x0000053e, + 0x0004003d,0x00000006,0x0000053f,0x00000449,0x00050041,0x00000007,0x00000540,0x00000448, + 0x000000a7,0x0004003d,0x00000006,0x00000541,0x00000540,0x0007000c,0x00000006,0x00000542, + 0x00000001,0x00000025,0x0000053f,0x00000541,0x0003003e,0x00000449,0x00000542,0x000200f9, + 0x00000544,0x000200f8,0x00000543,0x0003003e,0x00000449,0x000000c8,0x000200f9,0x00000544, + 0x000200f8,0x00000544,0x0004003d,0x00000006,0x0000048e,0x00000449,0x0003003e,0x00000443, + 0x0000048e,0x000200f9,0x0000048f,0x000200f8,0x0000048f,0x000200f9,0x00000490,0x000200f8, + 0x00000490,0x000300f7,0x00000496,0x00000000,0x000400fa,0x0000031c,0x00000491,0x00000496, + 0x000200f8,0x00000491,0x0004003d,0x00000012,0x00000493,0x00000466,0x000500c7,0x00000012, + 0x00000494,0x00000493,0x00000321,0x000500ab,0x000000d6,0x00000495,0x00000494,0x00000091, + 0x000200f9,0x00000496,0x000200f8,0x00000496,0x000700f5,0x000000d6,0x00000497,0x0000031c, + 0x00000490,0x00000495,0x00000491,0x000300f7,0x000004be,0x00000000,0x000400fa,0x00000497, + 0x00000498,0x000004be,0x000200f8,0x00000498,0x0004003d,0x00000012,0x00000499,0x00000402, + 0x00050084,0x00000012,0x0000049a,0x00000499,0x0000032e,0x00050080,0x00000012,0x0000049b, + 0x0000049a,0x000000a7,0x00060041,0x00000332,0x0000049c,0x0000032c,0x00000211,0x0000049b, + 0x0004003d,0x0000002f,0x0000049d,0x0000049c,0x0003003e,0x0000044b,0x0000049d,0x0004003d, + 0x0000002f,0x0000054f,0x0000044b,0x0004003d,0x0000002f,0x00000551,0x0000044b,0x00050051, + 0x00000006,0x00000553,0x0000054f,0x00000000,0x00050051,0x00000006,0x00000554,0x0000054f, + 0x00000001,0x00050051,0x00000006,0x00000555,0x00000551,0x00000002,0x00050051,0x00000006, + 0x00000556,0x00000551,0x00000003,0x00050050,0x0000000c,0x00000557,0x00000553,0x00000554, + 0x00050050,0x0000000c,0x00000558,0x00000555,0x00000556,0x00050050,0x00000035,0x00000559, + 0x00000557,0x00000558,0x0003003e,0x0000054d,0x00000559,0x0004003d,0x00000035,0x0000049e, + 0x0000054d,0x0003003e,0x0000044a,0x0000049e,0x0004003d,0x00000012,0x0000049f,0x00000402, + 0x00050084,0x00000012,0x000004a0,0x0000049f,0x0000032e,0x00050080,0x00000012,0x000004a1, + 0x000004a0,0x000000be,0x00060041,0x00000332,0x000004a2,0x0000032c,0x00000211,0x000004a1, + 0x0004003d,0x0000002f,0x000004a3,0x000004a2,0x0003003e,0x0000044c,0x000004a3,0x0004003d, + 0x00000035,0x000004a4,0x0000044a,0x00050091,0x0000000c,0x000004a7,0x000004a4,0x000003e6, + 0x0004003d,0x0000002f,0x000004a8,0x0000044c,0x0007004f,0x0000000c,0x000004a9,0x000004a8, + 0x000004a8,0x00000000,0x00000001,0x00050081,0x0000000c,0x000004aa,0x000004a7,0x000004a9, + 0x0003003e,0x0000044d,0x000004aa,0x0004003d,0x0000000c,0x000004ab,0x0000044d,0x0006000c, + 0x0000000c,0x000004ac,0x00000001,0x00000004,0x000004ab,0x0004003d,0x0000002f,0x000004ad, + 0x0000044c,0x0007004f,0x0000000c,0x000004ae,0x000004ad,0x000004ad,0x00000002,0x00000003, + 0x00050085,0x0000000c,0x000004af,0x000004ac,0x000004ae,0x0004003d,0x0000002f,0x000004b0, + 0x0000044c,0x0007004f,0x0000000c,0x000004b1,0x000004b0,0x000004b0,0x00000002,0x00000003, + 0x00050083,0x0000000c,0x000004b2,0x000004af,0x000004b1,0x0003003e,0x0000044f,0x000004b2, + 0x0004003d,0x0000000c,0x0000055d,0x0000044f,0x0003003e,0x0000055a,0x0000055d,0x0004003d, + 0x0000000c,0x0000055e,0x0000055a,0x0003003e,0x0000055b,0x0000055e,0x0004003d,0x0000000c, + 0x000004b3,0x0000055b,0x0003003e,0x0000044e,0x000004b3,0x00050041,0x00000007,0x000004b4, + 0x0000044e,0x00000091,0x0004003d,0x00000006,0x000004b5,0x000004b4,0x00050041,0x00000007, + 0x000004b6,0x0000044e,0x00000094,0x0004003d,0x00000006,0x000004b7,0x000004b6,0x0007000c, + 0x00000006,0x000004b8,0x00000001,0x00000025,0x000004b5,0x000004b7,0x00050081,0x00000006, + 0x000004b9,0x000004b8,0x0000018d,0x0008000c,0x00000006,0x000004ba,0x00000001,0x0000002b, + 0x000004b9,0x000000c8,0x000000c7,0x0003003e,0x00000450,0x000004ba,0x0004003d,0x00000006, + 0x000004bb,0x00000443,0x0004003d,0x00000006,0x000004bc,0x00000450,0x0007000c,0x00000006, + 0x000004bd,0x00000001,0x00000025,0x000004bb,0x000004bc,0x0003003e,0x00000443,0x000004bd, + 0x000200f9,0x000004be,0x000200f8,0x000004be,0x0004003d,0x00000012,0x000004c0,0x00000466, + 0x000500c7,0x00000012,0x000004c1,0x000004c0,0x0000035f,0x0003003e,0x00000451,0x000004c1, + 0x0004003d,0x00000012,0x000004c2,0x00000451,0x000500b2,0x000000d6,0x000004c3,0x000004c2, + 0x00000094,0x000300f7,0x000004fd,0x00000000,0x000400fa,0x000004c3,0x000004c4,0x000004ce, + 0x000200f8,0x000004c4,0x00050041,0x00000013,0x000004c5,0x00000442,0x00000094,0x0004003d, + 0x00000012,0x000004c6,0x000004c5,0x0006000c,0x0000002f,0x000004c7,0x00000001,0x00000040, + 0x000004c6,0x0003003e,0x00000406,0x000004c7,0x0004003d,0x00000012,0x000004c8,0x00000451, + 0x000500aa,0x000000d6,0x000004c9,0x000004c8,0x00000091,0x000500a7,0x000000d6,0x000004ca, + 0x00000303,0x000004c9,0x000300f7,0x000004cd,0x00000000,0x000400fa,0x000004ca,0x000004cb, + 0x000004cd,0x000200f8,0x000004cb,0x0003003e,0x00000452,0x000000c8,0x0004003d,0x00000006, + 0x00000562,0x00000452,0x00050041,0x00000007,0x00000563,0x0000055f,0x00000091,0x0003003e, + 0x00000563,0x00000562,0x0004003d,0x00000006,0x00000564,0x00000452,0x00050041,0x00000007, + 0x00000565,0x0000055f,0x00000094,0x0003003e,0x00000565,0x00000564,0x0004003d,0x00000006, + 0x00000566,0x00000452,0x00050041,0x00000007,0x00000567,0x0000055f,0x000000a7,0x0003003e, + 0x00000567,0x00000566,0x0004003d,0x00000006,0x00000568,0x00000452,0x00050041,0x00000007, + 0x00000569,0x0000055f,0x000000be,0x0003003e,0x00000569,0x00000568,0x0004003d,0x0000002f, + 0x0000056a,0x0000055f,0x0003003e,0x00000560,0x0000056a,0x0004003d,0x0000002f,0x000004cc, + 0x00000560,0x0003003e,0x00000406,0x000004cc,0x000200f9,0x000004cd,0x000200f8,0x000004cd, + 0x000200f9,0x000004fd,0x000200f8,0x000004ce,0x0004003d,0x00000012,0x000004cf,0x00000402, + 0x00050084,0x00000012,0x000004d0,0x000004cf,0x0000032e,0x00060041,0x00000332,0x000004d1, + 0x0000032c,0x00000211,0x000004d0,0x0004003d,0x0000002f,0x000004d2,0x000004d1,0x0003003e, + 0x00000454,0x000004d2,0x0004003d,0x0000002f,0x0000056d,0x00000454,0x0004003d,0x0000002f, + 0x0000056f,0x00000454,0x00050051,0x00000006,0x00000571,0x0000056d,0x00000000,0x00050051, + 0x00000006,0x00000572,0x0000056d,0x00000001,0x00050051,0x00000006,0x00000573,0x0000056f, + 0x00000002,0x00050051,0x00000006,0x00000574,0x0000056f,0x00000003,0x00050050,0x0000000c, + 0x00000575,0x00000571,0x00000572,0x00050050,0x0000000c,0x00000576,0x00000573,0x00000574, + 0x00050050,0x00000035,0x00000577,0x00000575,0x00000576,0x0003003e,0x0000056b,0x00000577, + 0x0004003d,0x00000035,0x000004d3,0x0000056b,0x0003003e,0x00000453,0x000004d3,0x0004003d, + 0x00000012,0x000004d4,0x00000402,0x00050084,0x00000012,0x000004d5,0x000004d4,0x0000032e, + 0x00050080,0x00000012,0x000004d6,0x000004d5,0x00000094,0x00060041,0x00000332,0x000004d7, + 0x0000032c,0x00000211,0x000004d6,0x0004003d,0x0000002f,0x000004d8,0x000004d7,0x0003003e, + 0x00000455,0x000004d8,0x0004003d,0x00000035,0x000004d9,0x00000453,0x00050091,0x0000000c, + 0x000004dc,0x000004d9,0x000003e6,0x0004003d,0x0000002f,0x000004dd,0x00000455,0x0007004f, + 0x0000000c,0x000004de,0x000004dd,0x000004dd,0x00000000,0x00000001,0x00050081,0x0000000c, + 0x000004df,0x000004dc,0x000004de,0x0003003e,0x00000456,0x000004df,0x0004003d,0x00000012, + 0x000004e0,0x00000451,0x000500aa,0x000000d6,0x000004e1,0x000004e0,0x000000a7,0x000300f7, + 0x000004e8,0x00000000,0x000400fa,0x000004e1,0x000004e2,0x000004e5,0x000200f8,0x000004e2, + 0x00050041,0x00000007,0x000004e3,0x00000456,0x00000091,0x0004003d,0x00000006,0x000004e4, + 0x000004e3,0x0003003e,0x00000458,0x000004e4,0x000200f9,0x000004e8,0x000200f8,0x000004e5, + 0x0004003d,0x0000000c,0x000004e6,0x00000456,0x0006000c,0x00000006,0x000004e7,0x00000001, + 0x00000042,0x000004e6,0x0003003e,0x00000458,0x000004e7,0x000200f9,0x000004e8,0x000200f8, + 0x000004e8,0x0004003d,0x00000006,0x000004e9,0x00000458,0x0003003e,0x00000457,0x000004e9, + 0x0004003d,0x00000006,0x000004ea,0x00000457,0x0008000c,0x00000006,0x000004eb,0x00000001, + 0x0000002b,0x000004ea,0x000000c8,0x000000c7,0x0003003e,0x00000457,0x000004eb,0x0004003d, + 0x00000006,0x000004ec,0x00000457,0x00050041,0x00000007,0x000004ed,0x00000455,0x000000a7, + 0x0004003d,0x00000006,0x000004ee,0x000004ed,0x00050085,0x00000006,0x000004ef,0x000004ec, + 0x000004ee,0x00050041,0x00000007,0x000004f0,0x00000455,0x000000be,0x0004003d,0x00000006, + 0x000004f1,0x000004f0,0x00050081,0x00000006,0x000004f2,0x000004ef,0x000004f1,0x0003003e, + 0x00000459,0x000004f2,0x00050041,0x00000013,0x000004f3,0x00000442,0x00000094,0x0004003d, + 0x00000012,0x000004f4,0x000004f3,0x0004007c,0x00000006,0x000004f5,0x000004f4,0x0003003e, + 0x0000045a,0x000004f5,0x0004003d,0x0000039f,0x000004f6,0x000003a1,0x0004003d,0x000003a3, + 0x000004f7,0x000003a5,0x00050056,0x000003a7,0x000004f8,0x000004f6,0x000004f7,0x0004003d, + 0x00000006,0x000004f9,0x00000459,0x0004003d,0x00000006,0x000004fa,0x0000045a,0x00050050, + 0x0000000c,0x000004fb,0x000004f9,0x000004fa,0x00070058,0x0000002f,0x000004fc,0x000004f8, + 0x000004fb,0x00000002,0x000000c8,0x0003003e,0x00000406,0x000004fc,0x000200f9,0x000004fd, + 0x000200f8,0x000004fd,0x0004003d,0x00000006,0x000004fe,0x00000443,0x00050041,0x00000007, + 0x000004ff,0x00000406,0x000000be,0x0004003d,0x00000006,0x00000500,0x000004ff,0x00050085, + 0x00000006,0x00000501,0x00000500,0x000004fe,0x0003003e,0x000004ff,0x00000501,0x000300f7, + 0x00000507,0x00000000,0x000400fa,0x000003b2,0x00000503,0x00000507,0x000200f8,0x00000503, + 0x0004003d,0x00000006,0x00000505,0x000004ff,0x000500b7,0x000000d6,0x00000506,0x00000505, + 0x000000c8,0x000200f9,0x00000507,0x000200f8,0x00000507,0x000700f5,0x000000d6,0x00000508, + 0x000003b2,0x000004fd,0x00000506,0x00000503,0x000300f7,0x00000510,0x00000000,0x000400fa, + 0x00000508,0x00000509,0x00000510,0x000200f8,0x00000509,0x0004003d,0x00000012,0x0000050b, + 0x00000466,0x000500c2,0x00000012,0x0000050c,0x0000050b,0x000003be,0x000500c7,0x00000012, + 0x0000050d,0x0000050c,0x0000035f,0x0003003e,0x0000045c,0x0000050d,0x0004003d,0x00000012, + 0x0000057b,0x0000045c,0x0003003e,0x00000578,0x0000057b,0x0004003d,0x00000012,0x0000057c, + 0x00000578,0x0003003e,0x00000579,0x0000057c,0x0004003d,0x00000012,0x0000050e,0x00000579, + 0x0003003e,0x0000045b,0x0000050e,0x000500ab,0x000000d6,0x0000050f,0x0000050e,0x00000091, + 0x000200f9,0x00000510,0x000200f8,0x00000510,0x000700f5,0x000000d6,0x00000511,0x00000508, + 0x00000507,0x0000050f,0x00000509,0x000300f7,0x00000520,0x00000000,0x000400fa,0x00000511, + 0x00000512,0x00000520,0x000200f8,0x00000512,0x0004003d,0x0000030f,0x00000513,0x000003c8, + 0x00050062,0x0000002f,0x00000514,0x00000513,0x00000313,0x0003003e,0x0000045d,0x00000514, + 0x0004003d,0x0000002f,0x00000515,0x00000406,0x0008004f,0x00000024,0x00000516,0x00000515, + 0x00000515,0x00000000,0x00000001,0x00000002,0x0003003e,0x0000045e,0x00000516,0x0004003d, + 0x0000002f,0x00000517,0x0000045d,0x0003003e,0x0000045f,0x00000517,0x0004003d,0x00000012, + 0x00000518,0x0000045b,0x0003003e,0x00000460,0x00000518,0x0004003d,0x00000024,0x00000584, + 0x0000045e,0x0003003e,0x0000057e,0x00000584,0x0004003d,0x0000002f,0x00000585,0x0000045f, + 0x0003003e,0x0000057f,0x00000585,0x0004003d,0x00000012,0x00000586,0x00000460,0x0003003e, + 0x00000580,0x00000586,0x0004003d,0x0000002f,0x000005b6,0x0000057f,0x0003003e,0x0000058f, + 0x000005b6,0x0004003d,0x0000002f,0x000006b2,0x0000058f,0x0008004f,0x00000024,0x000006b3, + 0x000006b2,0x000006b2,0x00000000,0x00000001,0x00000002,0x00050041,0x00000007,0x000006b4, + 0x0000058f,0x000000be,0x0004003d,0x00000006,0x000006b5,0x000006b4,0x000500b7,0x000000d6, + 0x000006b6,0x000006b5,0x000000c8,0x000300f7,0x000006bc,0x00000000,0x000400fa,0x000006b6, + 0x000006b7,0x000006bb,0x000200f8,0x000006b7,0x0004003d,0x00000006,0x000006b9,0x000006b4, + 0x00050088,0x00000006,0x000006ba,0x000000c7,0x000006b9,0x0003003e,0x000006af,0x000006ba, + 0x000200f9,0x000006bc,0x000200f8,0x000006bb,0x0003003e,0x000006af,0x000000c8,0x000200f9, + 0x000006bc,0x000200f8,0x000006bc,0x0004003d,0x00000006,0x000006bd,0x000006af,0x0005008e, + 0x00000024,0x000006be,0x000006b3,0x000006bd,0x0003003e,0x000006b0,0x000006be,0x0004003d, + 0x00000024,0x000005b7,0x000006b0,0x0003003e,0x0000058e,0x000005b7,0x0004003d,0x00000012, + 0x000005b8,0x00000580,0x000300f7,0x000006ad,0x00000000,0x002100fb,0x000005b8,0x000006ad, + 0x0000000b,0x000005b9,0x00000001,0x000005bd,0x00000002,0x000005c5,0x00000003,0x000005d5, + 0x00000004,0x000005d9,0x00000005,0x000005dd,0x00000006,0x000005ff,0x00000007,0x0000062b, + 0x00000008,0x0000063b,0x00000009,0x00000675,0x0000000a,0x0000067a,0x0000000c,0x00000683, + 0x0000000d,0x0000068e,0x0000000e,0x00000699,0x0000000f,0x000006a3,0x000200f8,0x000005b9, + 0x0004003d,0x00000024,0x000005ba,0x0000057e,0x0004003d,0x00000024,0x000005bb,0x0000058e, + 0x00050085,0x00000024,0x000005bc,0x000005ba,0x000005bb,0x0003003e,0x00000590,0x000005bc, + 0x000200f9,0x000006ad,0x000200f8,0x000005bd,0x0004003d,0x00000024,0x000005be,0x0000057e, + 0x0004003d,0x00000024,0x000005bf,0x0000058e,0x00050081,0x00000024,0x000005c0,0x000005be, + 0x000005bf,0x0004003d,0x00000024,0x000005c1,0x0000057e,0x0004003d,0x00000024,0x000005c2, + 0x0000058e,0x00050085,0x00000024,0x000005c3,0x000005c1,0x000005c2,0x00050083,0x00000024, + 0x000005c4,0x000005c0,0x000005c3,0x0003003e,0x00000590,0x000005c4,0x000200f9,0x000006ad, + 0x000200f8,0x000005c5,0x0004003d,0x00000024,0x000005c6,0x0000057e,0x0004003d,0x00000024, + 0x000005c7,0x0000058e,0x00050085,0x00000024,0x000005c8,0x000005c6,0x000005c7,0x0003003e, + 0x00000591,0x000005c8,0x0004003d,0x00000024,0x000005c9,0x00000591,0x0004003d,0x00000024, + 0x000005ca,0x0000057e,0x0004003d,0x00000024,0x000005cb,0x0000058e,0x00050081,0x00000024, + 0x000005cc,0x000005ca,0x000005cb,0x0004003d,0x00000024,0x000005cd,0x00000591,0x00050083, + 0x00000024,0x000005ce,0x000005cc,0x000005cd,0x00050083,0x00000024,0x000005cf,0x000005ce, + 0x0000042c,0x0004003d,0x00000024,0x000005d0,0x0000058e,0x0003003e,0x00000592,0x0000018d, + 0x0004003d,0x00000006,0x000006c2,0x00000592,0x00050041,0x00000007,0x000006c3,0x000006bf, + 0x00000091,0x0003003e,0x000006c3,0x000006c2,0x0004003d,0x00000006,0x000006c4,0x00000592, + 0x00050041,0x00000007,0x000006c5,0x000006bf,0x00000094,0x0003003e,0x000006c5,0x000006c4, + 0x0004003d,0x00000006,0x000006c6,0x00000592,0x00050041,0x00000007,0x000006c7,0x000006bf, + 0x000000a7,0x0003003e,0x000006c7,0x000006c6,0x0004003d,0x00000024,0x000006c8,0x000006bf, + 0x0003003e,0x000006c0,0x000006c8,0x0004003d,0x00000024,0x000005d1,0x000006c0,0x000500ba, + 0x00000193,0x000005d2,0x000005d0,0x000005d1,0x000600a9,0x00000024,0x000005d3,0x000005d2, + 0x000005cf,0x000005c9,0x0005008e,0x00000024,0x000005d4,0x000005d3,0x00000186,0x0003003e, + 0x00000590,0x000005d4,0x000200f9,0x000006ad,0x000200f8,0x000005d5,0x0004003d,0x00000024, + 0x000005d6,0x0000057e,0x0004003d,0x00000024,0x000005d7,0x0000058e,0x0007000c,0x00000024, + 0x000005d8,0x00000001,0x00000025,0x000005d6,0x000005d7,0x0003003e,0x00000590,0x000005d8, + 0x000200f9,0x000006ad,0x000200f8,0x000005d9,0x0004003d,0x00000024,0x000005da,0x0000057e, + 0x0004003d,0x00000024,0x000005db,0x0000058e,0x0007000c,0x00000024,0x000005dc,0x00000001, + 0x00000028,0x000005da,0x000005db,0x0003003e,0x00000590,0x000005dc,0x000200f9,0x000006ad, + 0x000200f8,0x000005dd,0x0004003d,0x0000002f,0x000005de,0x0000057f,0x0008004f,0x00000024, + 0x000005df,0x000005de,0x000005de,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000593, + 0x000000c8,0x0004003d,0x00000006,0x000006cc,0x00000593,0x00050041,0x00000007,0x000006cd, + 0x000006c9,0x00000091,0x0003003e,0x000006cd,0x000006cc,0x0004003d,0x00000006,0x000006ce, + 0x00000593,0x00050041,0x00000007,0x000006cf,0x000006c9,0x00000094,0x0003003e,0x000006cf, + 0x000006ce,0x0004003d,0x00000006,0x000006d0,0x00000593,0x00050041,0x00000007,0x000006d1, + 0x000006c9,0x000000a7,0x0003003e,0x000006d1,0x000006d0,0x0004003d,0x00000024,0x000006d2, + 0x000006c9,0x0003003e,0x000006ca,0x000006d2,0x0004003d,0x00000024,0x000005e0,0x000006ca, + 0x0004003d,0x0000002f,0x000005e1,0x0000057f,0x0008004f,0x00000024,0x000005e2,0x000005e1, + 0x000005e1,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024,0x000005e3,0x00000001, + 0x0000002b,0x000005df,0x000005e0,0x000005e2,0x00050041,0x00000007,0x000005e4,0x0000057f, + 0x00000091,0x00050051,0x00000006,0x000005e5,0x000005e3,0x00000000,0x0003003e,0x000005e4, + 0x000005e5,0x00050041,0x00000007,0x000005e6,0x0000057f,0x00000094,0x00050051,0x00000006, + 0x000005e7,0x000005e3,0x00000001,0x0003003e,0x000005e6,0x000005e7,0x00050041,0x00000007, + 0x000005e8,0x0000057f,0x000000a7,0x00050051,0x00000006,0x000005e9,0x000005e3,0x00000002, + 0x0003003e,0x000005e8,0x000005e9,0x0004003d,0x00000024,0x000005ea,0x0000057e,0x00050083, + 0x00000024,0x000005eb,0x0000042b,0x000005ea,0x0003003e,0x00000595,0x000000c8,0x0004003d, + 0x00000006,0x000006d6,0x00000595,0x00050041,0x00000007,0x000006d7,0x000006d3,0x00000091, + 0x0003003e,0x000006d7,0x000006d6,0x0004003d,0x00000006,0x000006d8,0x00000595,0x00050041, + 0x00000007,0x000006d9,0x000006d3,0x00000094,0x0003003e,0x000006d9,0x000006d8,0x0004003d, + 0x00000006,0x000006da,0x00000595,0x00050041,0x00000007,0x000006db,0x000006d3,0x000000a7, + 0x0003003e,0x000006db,0x000006da,0x0004003d,0x00000024,0x000006dc,0x000006d3,0x0003003e, + 0x000006d4,0x000006dc,0x0004003d,0x00000024,0x000005ec,0x000006d4,0x0003003e,0x00000596, + 0x000000c7,0x0004003d,0x00000006,0x000006e0,0x00000596,0x00050041,0x00000007,0x000006e1, + 0x000006dd,0x00000091,0x0003003e,0x000006e1,0x000006e0,0x0004003d,0x00000006,0x000006e2, + 0x00000596,0x00050041,0x00000007,0x000006e3,0x000006dd,0x00000094,0x0003003e,0x000006e3, + 0x000006e2,0x0004003d,0x00000006,0x000006e4,0x00000596,0x00050041,0x00000007,0x000006e5, + 0x000006dd,0x000000a7,0x0003003e,0x000006e5,0x000006e4,0x0004003d,0x00000024,0x000006e6, + 0x000006dd,0x0003003e,0x000006de,0x000006e6,0x0004003d,0x00000024,0x000005ed,0x000006de, + 0x0008000c,0x00000024,0x000005ee,0x00000001,0x0000002b,0x000005eb,0x000005ec,0x000005ed, + 0x00050041,0x00000007,0x000005ef,0x0000057f,0x000000be,0x0004003d,0x00000006,0x000005f0, + 0x000005ef,0x0005008e,0x00000024,0x000005f1,0x000005ee,0x000005f0,0x0003003e,0x00000594, + 0x000005f1,0x0003003e,0x00000597,0x000000c7,0x0004003d,0x00000006,0x000006ea,0x00000597, + 0x00050041,0x00000007,0x000006eb,0x000006e7,0x00000091,0x0003003e,0x000006eb,0x000006ea, + 0x0004003d,0x00000006,0x000006ec,0x00000597,0x00050041,0x00000007,0x000006ed,0x000006e7, + 0x00000094,0x0003003e,0x000006ed,0x000006ec,0x0004003d,0x00000006,0x000006ee,0x00000597, + 0x00050041,0x00000007,0x000006ef,0x000006e7,0x000000a7,0x0003003e,0x000006ef,0x000006ee, + 0x0004003d,0x00000024,0x000006f0,0x000006e7,0x0003003e,0x000006e8,0x000006f0,0x0004003d, + 0x00000024,0x000005f2,0x000006e8,0x0004003d,0x0000002f,0x000005f3,0x0000057f,0x0008004f, + 0x00000024,0x000005f4,0x000005f3,0x000005f3,0x00000000,0x00000001,0x00000002,0x0004003d, + 0x00000024,0x000005f5,0x00000594,0x00050088,0x00000024,0x000005f6,0x000005f4,0x000005f5, + 0x0007000c,0x00000024,0x000005f7,0x00000001,0x00000025,0x000005f2,0x000005f6,0x0004003d, + 0x0000002f,0x000005f8,0x0000057f,0x0008004f,0x00000024,0x000005f9,0x000005f8,0x000005f8, + 0x00000000,0x00000001,0x00000002,0x0006000c,0x00000024,0x000005fa,0x00000001,0x00000006, + 0x000005f9,0x0004003d,0x00000024,0x000005fb,0x00000594,0x0003003e,0x00000598,0x000000c8, + 0x0004003d,0x00000006,0x000006f4,0x00000598,0x00050041,0x00000007,0x000006f5,0x000006f1, + 0x00000091,0x0003003e,0x000006f5,0x000006f4,0x0004003d,0x00000006,0x000006f6,0x00000598, + 0x00050041,0x00000007,0x000006f7,0x000006f1,0x00000094,0x0003003e,0x000006f7,0x000006f6, + 0x0004003d,0x00000006,0x000006f8,0x00000598,0x00050041,0x00000007,0x000006f9,0x000006f1, + 0x000000a7,0x0003003e,0x000006f9,0x000006f8,0x0004003d,0x00000024,0x000006fa,0x000006f1, + 0x0003003e,0x000006f2,0x000006fa,0x0004003d,0x00000024,0x000005fc,0x000006f2,0x000500b4, + 0x00000193,0x000005fd,0x000005fb,0x000005fc,0x000600a9,0x00000024,0x000005fe,0x000005fd, + 0x000005fa,0x000005f7,0x0003003e,0x00000590,0x000005fe,0x000200f9,0x000006ad,0x000200f8, + 0x000005ff,0x0004003d,0x00000024,0x00000600,0x0000057e,0x0003003e,0x00000599,0x000000c8, + 0x0004003d,0x00000006,0x000006fe,0x00000599,0x00050041,0x00000007,0x000006ff,0x000006fb, + 0x00000091,0x0003003e,0x000006ff,0x000006fe,0x0004003d,0x00000006,0x00000700,0x00000599, + 0x00050041,0x00000007,0x00000701,0x000006fb,0x00000094,0x0003003e,0x00000701,0x00000700, + 0x0004003d,0x00000006,0x00000702,0x00000599,0x00050041,0x00000007,0x00000703,0x000006fb, + 0x000000a7,0x0003003e,0x00000703,0x00000702,0x0004003d,0x00000024,0x00000704,0x000006fb, + 0x0003003e,0x000006fc,0x00000704,0x0004003d,0x00000024,0x00000601,0x000006fc,0x0003003e, + 0x0000059a,0x000000c7,0x0004003d,0x00000006,0x00000708,0x0000059a,0x00050041,0x00000007, + 0x00000709,0x00000705,0x00000091,0x0003003e,0x00000709,0x00000708,0x0004003d,0x00000006, + 0x0000070a,0x0000059a,0x00050041,0x00000007,0x0000070b,0x00000705,0x00000094,0x0003003e, + 0x0000070b,0x0000070a,0x0004003d,0x00000006,0x0000070c,0x0000059a,0x00050041,0x00000007, + 0x0000070d,0x00000705,0x000000a7,0x0003003e,0x0000070d,0x0000070c,0x0004003d,0x00000024, + 0x0000070e,0x00000705,0x0003003e,0x00000706,0x0000070e,0x0004003d,0x00000024,0x00000602, + 0x00000706,0x0008000c,0x00000024,0x00000603,0x00000001,0x0000002b,0x00000600,0x00000601, + 0x00000602,0x0003003e,0x0000057e,0x00000603,0x0004003d,0x0000002f,0x00000604,0x0000057f, + 0x0008004f,0x00000024,0x00000605,0x00000604,0x00000604,0x00000000,0x00000001,0x00000002, + 0x0003003e,0x0000059b,0x000000c8,0x0004003d,0x00000006,0x00000712,0x0000059b,0x00050041, + 0x00000007,0x00000713,0x0000070f,0x00000091,0x0003003e,0x00000713,0x00000712,0x0004003d, + 0x00000006,0x00000714,0x0000059b,0x00050041,0x00000007,0x00000715,0x0000070f,0x00000094, + 0x0003003e,0x00000715,0x00000714,0x0004003d,0x00000006,0x00000716,0x0000059b,0x00050041, + 0x00000007,0x00000717,0x0000070f,0x000000a7,0x0003003e,0x00000717,0x00000716,0x0004003d, + 0x00000024,0x00000718,0x0000070f,0x0003003e,0x00000710,0x00000718,0x0004003d,0x00000024, + 0x00000606,0x00000710,0x0004003d,0x0000002f,0x00000607,0x0000057f,0x0008004f,0x00000024, + 0x00000608,0x00000607,0x00000607,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000024, + 0x00000609,0x00000001,0x0000002b,0x00000605,0x00000606,0x00000608,0x00050041,0x00000007, + 0x0000060a,0x0000057f,0x00000091,0x00050051,0x00000006,0x0000060b,0x00000609,0x00000000, + 0x0003003e,0x0000060a,0x0000060b,0x00050041,0x00000007,0x0000060c,0x0000057f,0x00000094, + 0x00050051,0x00000006,0x0000060d,0x00000609,0x00000001,0x0003003e,0x0000060c,0x0000060d, + 0x00050041,0x00000007,0x0000060e,0x0000057f,0x000000a7,0x00050051,0x00000006,0x0000060f, + 0x00000609,0x00000002,0x0003003e,0x0000060e,0x0000060f,0x00050041,0x00000007,0x00000610, + 0x0000057f,0x000000be,0x0004003d,0x00000006,0x00000611,0x00000610,0x000500b4,0x000000d6, + 0x00000612,0x00000611,0x000000c8,0x000300f7,0x00000615,0x00000000,0x000400fa,0x00000612, + 0x00000613,0x00000615,0x000200f8,0x00000613,0x0003003e,0x00000610,0x000000c7,0x000200f9, + 0x00000615,0x000200f8,0x00000615,0x0004003d,0x00000006,0x00000617,0x00000610,0x0004003d, + 0x0000002f,0x00000618,0x0000057f,0x0008004f,0x00000024,0x00000619,0x00000618,0x00000618, + 0x00000000,0x00000001,0x00000002,0x00060050,0x00000024,0x0000061a,0x00000617,0x00000617, + 0x00000617,0x00050083,0x00000024,0x0000061b,0x0000061a,0x00000619,0x0003003e,0x0000059c, + 0x0000061b,0x0003003e,0x0000059d,0x000000c7,0x0004003d,0x00000006,0x0000071c,0x0000059d, + 0x00050041,0x00000007,0x0000071d,0x00000719,0x00000091,0x0003003e,0x0000071d,0x0000071c, + 0x0004003d,0x00000006,0x0000071e,0x0000059d,0x00050041,0x00000007,0x0000071f,0x00000719, + 0x00000094,0x0003003e,0x0000071f,0x0000071e,0x0004003d,0x00000006,0x00000720,0x0000059d, + 0x00050041,0x00000007,0x00000721,0x00000719,0x000000a7,0x0003003e,0x00000721,0x00000720, + 0x0004003d,0x00000024,0x00000722,0x00000719,0x0003003e,0x0000071a,0x00000722,0x0004003d, + 0x00000024,0x0000061c,0x0000071a,0x0004003d,0x00000024,0x0000061d,0x0000059c,0x0004003d, + 0x00000024,0x0000061e,0x0000057e,0x0004003d,0x00000006,0x00000620,0x00000610,0x0005008e, + 0x00000024,0x00000621,0x0000061e,0x00000620,0x00050088,0x00000024,0x00000622,0x0000061d, + 0x00000621,0x0007000c,0x00000024,0x00000623,0x00000001,0x00000025,0x0000061c,0x00000622, + 0x0004003d,0x00000024,0x00000624,0x0000059c,0x0006000c,0x00000024,0x00000625,0x00000001, + 0x00000006,0x00000624,0x0004003d,0x00000024,0x00000626,0x0000057e,0x0003003e,0x0000059e, + 0x000000c8,0x0004003d,0x00000006,0x00000726,0x0000059e,0x00050041,0x00000007,0x00000727, + 0x00000723,0x00000091,0x0003003e,0x00000727,0x00000726,0x0004003d,0x00000006,0x00000728, + 0x0000059e,0x00050041,0x00000007,0x00000729,0x00000723,0x00000094,0x0003003e,0x00000729, + 0x00000728,0x0004003d,0x00000006,0x0000072a,0x0000059e,0x00050041,0x00000007,0x0000072b, + 0x00000723,0x000000a7,0x0003003e,0x0000072b,0x0000072a,0x0004003d,0x00000024,0x0000072c, + 0x00000723,0x0003003e,0x00000724,0x0000072c,0x0004003d,0x00000024,0x00000627,0x00000724, + 0x000500b4,0x00000193,0x00000628,0x00000626,0x00000627,0x000600a9,0x00000024,0x00000629, + 0x00000628,0x00000625,0x00000623,0x00050083,0x00000024,0x0000062a,0x0000042b,0x00000629, + 0x0003003e,0x00000590,0x0000062a,0x000200f9,0x000006ad,0x000200f8,0x0000062b,0x0004003d, + 0x00000024,0x0000062c,0x0000057e,0x0004003d,0x00000024,0x0000062d,0x0000058e,0x00050085, + 0x00000024,0x0000062e,0x0000062c,0x0000062d,0x0003003e,0x0000059f,0x0000062e,0x0004003d, + 0x00000024,0x0000062f,0x0000059f,0x0004003d,0x00000024,0x00000630,0x0000057e,0x0004003d, + 0x00000024,0x00000631,0x0000058e,0x00050081,0x00000024,0x00000632,0x00000630,0x00000631, + 0x0004003d,0x00000024,0x00000633,0x0000059f,0x00050083,0x00000024,0x00000634,0x00000632, + 0x00000633,0x00050083,0x00000024,0x00000635,0x00000634,0x0000042c,0x0004003d,0x00000024, + 0x00000636,0x0000057e,0x0003003e,0x000005a0,0x0000018d,0x0004003d,0x00000006,0x00000730, + 0x000005a0,0x00050041,0x00000007,0x00000731,0x0000072d,0x00000091,0x0003003e,0x00000731, + 0x00000730,0x0004003d,0x00000006,0x00000732,0x000005a0,0x00050041,0x00000007,0x00000733, + 0x0000072d,0x00000094,0x0003003e,0x00000733,0x00000732,0x0004003d,0x00000006,0x00000734, + 0x000005a0,0x00050041,0x00000007,0x00000735,0x0000072d,0x000000a7,0x0003003e,0x00000735, + 0x00000734,0x0004003d,0x00000024,0x00000736,0x0000072d,0x0003003e,0x0000072e,0x00000736, + 0x0004003d,0x00000024,0x00000637,0x0000072e,0x000500ba,0x00000193,0x00000638,0x00000636, + 0x00000637,0x000600a9,0x00000024,0x00000639,0x00000638,0x00000635,0x0000062f,0x0005008e, + 0x00000024,0x0000063a,0x00000639,0x00000186,0x0003003e,0x00000590,0x0000063a,0x000200f9, + 0x000006ad,0x000200f8,0x0000063b,0x0003003e,0x000005a1,0x00000211,0x000200f9,0x0000063c, + 0x000200f8,0x0000063c,0x0004003d,0x00000073,0x0000063e,0x000005a1,0x000500b1,0x000000d6, + 0x0000063f,0x0000063e,0x00000218,0x000400f6,0x0000066b,0x00000668,0x00000000,0x000400fa, + 0x0000063f,0x00000640,0x0000066b,0x000200f8,0x00000640,0x0004003d,0x00000073,0x00000641, + 0x000005a1,0x00050041,0x00000007,0x00000642,0x0000057e,0x00000641,0x0004003d,0x00000006, + 0x00000643,0x00000642,0x000500bc,0x000000d6,0x00000644,0x00000643,0x0000018d,0x000300f7, + 0x00000667,0x00000000,0x000400fa,0x00000644,0x00000645,0x0000064c,0x000200f8,0x00000645, + 0x0004003d,0x00000073,0x00000646,0x000005a1,0x0004003d,0x00000073,0x00000647,0x000005a1, + 0x00050041,0x00000007,0x00000648,0x0000058e,0x00000647,0x0004003d,0x00000006,0x00000649, + 0x00000648,0x00050083,0x00000006,0x0000064a,0x000000c7,0x00000649,0x00050041,0x00000007, + 0x0000064b,0x00000590,0x00000646,0x0003003e,0x0000064b,0x0000064a,0x000200f9,0x00000667, + 0x000200f8,0x0000064c,0x0004003d,0x00000073,0x0000064d,0x000005a1,0x00050041,0x00000007, + 0x0000064e,0x0000058e,0x0000064d,0x0004003d,0x00000006,0x0000064f,0x0000064e,0x000500bc, + 0x000000d6,0x00000650,0x0000064f,0x0000022a,0x000300f7,0x00000666,0x00000000,0x000400fa, + 0x00000650,0x00000651,0x0000065e,0x000200f8,0x00000651,0x0004003d,0x00000073,0x00000652, + 0x000005a1,0x0004003d,0x00000073,0x00000653,0x000005a1,0x00050041,0x00000007,0x00000654, + 0x0000058e,0x00000653,0x0004003d,0x00000006,0x00000655,0x00000654,0x00050085,0x00000006, + 0x00000656,0x0000022f,0x00000655,0x00050083,0x00000006,0x00000657,0x00000656,0x00000234, + 0x0004003d,0x00000073,0x00000658,0x000005a1,0x00050041,0x00000007,0x00000659,0x0000058e, + 0x00000658,0x0004003d,0x00000006,0x0000065a,0x00000659,0x00050085,0x00000006,0x0000065b, + 0x00000657,0x0000065a,0x00050081,0x00000006,0x0000065c,0x0000065b,0x0000023a,0x00050041, + 0x00000007,0x0000065d,0x00000590,0x00000652,0x0003003e,0x0000065d,0x0000065c,0x000200f9, + 0x00000666,0x000200f8,0x0000065e,0x0004003d,0x00000073,0x0000065f,0x000005a1,0x0004003d, + 0x00000073,0x00000660,0x000005a1,0x00050041,0x00000007,0x00000661,0x0000058e,0x00000660, + 0x0004003d,0x00000006,0x00000662,0x00000661,0x0006000c,0x00000006,0x00000663,0x00000001, + 0x00000020,0x00000662,0x00050083,0x00000006,0x00000664,0x00000663,0x000000c7,0x00050041, + 0x00000007,0x00000665,0x00000590,0x0000065f,0x0003003e,0x00000665,0x00000664,0x000200f9, + 0x00000666,0x000200f8,0x00000666,0x000200f9,0x00000667,0x000200f8,0x00000667,0x000200f9, + 0x00000668,0x000200f8,0x00000668,0x0004003d,0x00000073,0x00000669,0x000005a1,0x00050080, + 0x00000073,0x0000066a,0x00000669,0x00000246,0x0003003e,0x000005a1,0x0000066a,0x000200f9, + 0x0000063c,0x000200f8,0x0000066b,0x0004003d,0x00000024,0x0000066c,0x0000058e,0x0004003d, + 0x00000024,0x0000066d,0x0000058e,0x0004003d,0x00000024,0x0000066e,0x0000057e,0x0005008e, + 0x00000024,0x0000066f,0x0000066e,0x00000186,0x00050083,0x00000024,0x00000670,0x0000066f, + 0x0000042b,0x00050085,0x00000024,0x00000671,0x0000066d,0x00000670,0x0004003d,0x00000024, + 0x00000672,0x00000590,0x00050085,0x00000024,0x00000673,0x00000671,0x00000672,0x00050081, + 0x00000024,0x00000674,0x0000066c,0x00000673,0x0003003e,0x00000590,0x00000674,0x000200f9, + 0x000006ad,0x000200f8,0x00000675,0x0004003d,0x00000024,0x00000676,0x0000058e,0x0004003d, + 0x00000024,0x00000677,0x0000057e,0x00050083,0x00000024,0x00000678,0x00000676,0x00000677, + 0x0006000c,0x00000024,0x00000679,0x00000001,0x00000004,0x00000678,0x0003003e,0x00000590, + 0x00000679,0x000200f9,0x000006ad,0x000200f8,0x0000067a,0x0004003d,0x00000024,0x0000067b, + 0x0000057e,0x0004003d,0x00000024,0x0000067c,0x0000058e,0x00050081,0x00000024,0x0000067d, + 0x0000067b,0x0000067c,0x0004003d,0x00000024,0x0000067e,0x0000057e,0x0005008e,0x00000024, + 0x0000067f,0x0000067e,0x00000186,0x0004003d,0x00000024,0x00000680,0x0000058e,0x00050085, + 0x00000024,0x00000681,0x0000067f,0x00000680,0x00050083,0x00000024,0x00000682,0x0000067d, + 0x00000681,0x0003003e,0x00000590,0x00000682,0x000200f9,0x000006ad,0x000200f8,0x00000683, + 0x000300f7,0x0000068d,0x00000000,0x000400fa,0x00000261,0x00000684,0x0000068d,0x000200f8, + 0x00000684,0x0004003d,0x00000024,0x00000685,0x0000057e,0x0003003e,0x000005a2,0x000000c8, + 0x0004003d,0x00000006,0x0000073a,0x000005a2,0x00050041,0x00000007,0x0000073b,0x00000737, + 0x00000091,0x0003003e,0x0000073b,0x0000073a,0x0004003d,0x00000006,0x0000073c,0x000005a2, + 0x00050041,0x00000007,0x0000073d,0x00000737,0x00000094,0x0003003e,0x0000073d,0x0000073c, + 0x0004003d,0x00000006,0x0000073e,0x000005a2,0x00050041,0x00000007,0x0000073f,0x00000737, + 0x000000a7,0x0003003e,0x0000073f,0x0000073e,0x0004003d,0x00000024,0x00000740,0x00000737, + 0x0003003e,0x00000738,0x00000740,0x0004003d,0x00000024,0x00000686,0x00000738,0x0003003e, + 0x000005a3,0x000000c7,0x0004003d,0x00000006,0x00000744,0x000005a3,0x00050041,0x00000007, + 0x00000745,0x00000741,0x00000091,0x0003003e,0x00000745,0x00000744,0x0004003d,0x00000006, + 0x00000746,0x000005a3,0x00050041,0x00000007,0x00000747,0x00000741,0x00000094,0x0003003e, + 0x00000747,0x00000746,0x0004003d,0x00000006,0x00000748,0x000005a3,0x00050041,0x00000007, + 0x00000749,0x00000741,0x000000a7,0x0003003e,0x00000749,0x00000748,0x0004003d,0x00000024, + 0x0000074a,0x00000741,0x0003003e,0x00000742,0x0000074a,0x0004003d,0x00000024,0x00000687, + 0x00000742,0x0008000c,0x00000024,0x00000688,0x00000001,0x0000002b,0x00000685,0x00000686, + 0x00000687,0x0003003e,0x0000057e,0x00000688,0x0004003d,0x00000024,0x00000689,0x0000057e, + 0x0003003e,0x000005a4,0x00000689,0x0004003d,0x00000024,0x0000068a,0x0000058e,0x0003003e, + 0x000005a5,0x0000068a,0x0004003d,0x00000024,0x0000068b,0x0000058e,0x0003003e,0x000005a6, + 0x0000068b,0x0004003d,0x00000024,0x00000756,0x000005a5,0x0003003e,0x0000074c,0x00000756, + 0x0004003d,0x00000024,0x0000076e,0x0000074c,0x0007004f,0x0000000c,0x0000076f,0x0000076e, + 0x0000076e,0x00000000,0x00000001,0x0003003e,0x0000076b,0x0000076f,0x00050041,0x00000007, + 0x00000776,0x0000076b,0x00000091,0x0004003d,0x00000006,0x00000777,0x00000776,0x00050041, + 0x00000007,0x00000778,0x0000076b,0x00000094,0x0004003d,0x00000006,0x00000779,0x00000778, + 0x0007000c,0x00000006,0x0000077a,0x00000001,0x00000028,0x00000777,0x00000779,0x0003003e, + 0x00000774,0x0000077a,0x0004003d,0x00000006,0x00000770,0x00000774,0x00050041,0x00000007, + 0x00000771,0x0000074c,0x000000a7,0x0004003d,0x00000006,0x00000772,0x00000771,0x0007000c, + 0x00000006,0x00000773,0x00000001,0x00000028,0x00000770,0x00000772,0x0003003e,0x0000076c, + 0x00000773,0x0004003d,0x00000006,0x00000757,0x0000076c,0x0004003d,0x00000024,0x00000758, + 0x000005a5,0x0003003e,0x0000074d,0x00000758,0x0004003d,0x00000024,0x0000077e,0x0000074d, + 0x0007004f,0x0000000c,0x0000077f,0x0000077e,0x0000077e,0x00000000,0x00000001,0x0003003e, + 0x0000077b,0x0000077f,0x00050041,0x00000007,0x00000786,0x0000077b,0x00000091,0x0004003d, + 0x00000006,0x00000787,0x00000786,0x00050041,0x00000007,0x00000788,0x0000077b,0x00000094, + 0x0004003d,0x00000006,0x00000789,0x00000788,0x0007000c,0x00000006,0x0000078a,0x00000001, + 0x00000025,0x00000787,0x00000789,0x0003003e,0x00000784,0x0000078a,0x0004003d,0x00000006, + 0x00000780,0x00000784,0x00050041,0x00000007,0x00000781,0x0000074d,0x000000a7,0x0004003d, + 0x00000006,0x00000782,0x00000781,0x0007000c,0x00000006,0x00000783,0x00000001,0x00000025, + 0x00000780,0x00000782,0x0003003e,0x0000077c,0x00000783,0x0004003d,0x00000006,0x00000759, + 0x0000077c,0x00050083,0x00000006,0x0000075a,0x00000757,0x00000759,0x0003003e,0x0000074b, + 0x0000075a,0x0004003d,0x00000024,0x0000075b,0x000005a4,0x0003003e,0x0000074e,0x0000075b, + 0x0004003d,0x00000024,0x0000078e,0x0000074e,0x0007004f,0x0000000c,0x0000078f,0x0000078e, + 0x0000078e,0x00000000,0x00000001,0x0003003e,0x0000078b,0x0000078f,0x00050041,0x00000007, + 0x00000796,0x0000078b,0x00000091,0x0004003d,0x00000006,0x00000797,0x00000796,0x00050041, + 0x00000007,0x00000798,0x0000078b,0x00000094,0x0004003d,0x00000006,0x00000799,0x00000798, + 0x0007000c,0x00000006,0x0000079a,0x00000001,0x00000025,0x00000797,0x00000799,0x0003003e, + 0x00000794,0x0000079a,0x0004003d,0x00000006,0x00000790,0x00000794,0x00050041,0x00000007, + 0x00000791,0x0000074e,0x000000a7,0x0004003d,0x00000006,0x00000792,0x00000791,0x0007000c, + 0x00000006,0x00000793,0x00000001,0x00000025,0x00000790,0x00000792,0x0003003e,0x0000078c, + 0x00000793,0x0004003d,0x00000006,0x0000075c,0x0000078c,0x0004003d,0x00000024,0x0000075d, + 0x000005a4,0x00060050,0x00000024,0x0000075e,0x0000075c,0x0000075c,0x0000075c,0x00050083, + 0x00000024,0x0000075f,0x0000075d,0x0000075e,0x0003003e,0x000005a4,0x0000075f,0x0004003d, + 0x00000024,0x00000760,0x000005a4,0x0003003e,0x00000750,0x00000760,0x0004003d,0x00000024, + 0x0000079e,0x00000750,0x0007004f,0x0000000c,0x0000079f,0x0000079e,0x0000079e,0x00000000, + 0x00000001,0x0003003e,0x0000079b,0x0000079f,0x00050041,0x00000007,0x000007a6,0x0000079b, + 0x00000091,0x0004003d,0x00000006,0x000007a7,0x000007a6,0x00050041,0x00000007,0x000007a8, + 0x0000079b,0x00000094,0x0004003d,0x00000006,0x000007a9,0x000007a8,0x0007000c,0x00000006, + 0x000007aa,0x00000001,0x00000028,0x000007a7,0x000007a9,0x0003003e,0x000007a4,0x000007aa, + 0x0004003d,0x00000006,0x000007a0,0x000007a4,0x00050041,0x00000007,0x000007a1,0x00000750, + 0x000000a7,0x0004003d,0x00000006,0x000007a2,0x000007a1,0x0007000c,0x00000006,0x000007a3, + 0x00000001,0x00000028,0x000007a0,0x000007a2,0x0003003e,0x0000079c,0x000007a3,0x0004003d, + 0x00000006,0x00000761,0x0000079c,0x0003003e,0x0000074f,0x00000761,0x0004003d,0x00000006, + 0x00000762,0x0000074b,0x0004003d,0x00000006,0x00000763,0x0000074f,0x0007000c,0x00000006, + 0x00000764,0x00000001,0x00000028,0x00000120,0x00000763,0x00050088,0x00000006,0x00000765, + 0x00000762,0x00000764,0x0003003e,0x00000751,0x00000765,0x0004003d,0x00000024,0x00000766, + 0x000005a4,0x0004003d,0x00000006,0x00000767,0x00000751,0x0005008e,0x00000024,0x00000768, + 0x00000766,0x00000767,0x0003003e,0x00000752,0x00000768,0x0004003d,0x00000024,0x00000769, + 0x000005a6,0x0003003e,0x00000753,0x00000769,0x0004003d,0x00000024,0x000007bb,0x00000753, + 0x0003003e,0x000007ac,0x000007bb,0x0004003d,0x00000024,0x000007e1,0x000007ac,0x0003003e, + 0x000007dc,0x00000104,0x0003003e,0x000007dd,0x00000105,0x0003003e,0x000007de,0x00000106, + 0x0004003d,0x00000006,0x000007e7,0x000007dc,0x00050041,0x00000007,0x000007e8,0x000007e4, + 0x00000091,0x0003003e,0x000007e8,0x000007e7,0x0004003d,0x00000006,0x000007e9,0x000007dd, + 0x00050041,0x00000007,0x000007ea,0x000007e4,0x00000094,0x0003003e,0x000007ea,0x000007e9, + 0x0004003d,0x00000006,0x000007eb,0x000007de,0x00050041,0x00000007,0x000007ec,0x000007e4, + 0x000000a7,0x0003003e,0x000007ec,0x000007eb,0x0004003d,0x00000024,0x000007ed,0x000007e4, + 0x0003003e,0x000007e5,0x000007ed,0x0004003d,0x00000024,0x000007e2,0x000007e5,0x00050094, + 0x00000006,0x000007e3,0x000007e1,0x000007e2,0x0003003e,0x000007df,0x000007e3,0x0004003d, + 0x00000006,0x000007bc,0x000007df,0x0003003e,0x000007ab,0x000007bc,0x0004003d,0x00000024, + 0x000007bd,0x00000752,0x0004003d,0x00000024,0x000007be,0x00000752,0x0003003e,0x000007ae, + 0x000007be,0x0004003d,0x00000024,0x000007f3,0x000007ae,0x0003003e,0x000007ee,0x00000104, + 0x0003003e,0x000007ef,0x00000105,0x0003003e,0x000007f0,0x00000106,0x0004003d,0x00000006, + 0x000007f9,0x000007ee,0x00050041,0x00000007,0x000007fa,0x000007f6,0x00000091,0x0003003e, + 0x000007fa,0x000007f9,0x0004003d,0x00000006,0x000007fb,0x000007ef,0x00050041,0x00000007, + 0x000007fc,0x000007f6,0x00000094,0x0003003e,0x000007fc,0x000007fb,0x0004003d,0x00000006, + 0x000007fd,0x000007f0,0x00050041,0x00000007,0x000007fe,0x000007f6,0x000000a7,0x0003003e, + 0x000007fe,0x000007fd,0x0004003d,0x00000024,0x000007ff,0x000007f6,0x0003003e,0x000007f7, + 0x000007ff,0x0004003d,0x00000024,0x000007f4,0x000007f7,0x00050094,0x00000006,0x000007f5, + 0x000007f3,0x000007f4,0x0003003e,0x000007f1,0x000007f5,0x0004003d,0x00000006,0x000007bf, + 0x000007f1,0x00060050,0x00000024,0x000007c0,0x000007bf,0x000007bf,0x000007bf,0x00050083, + 0x00000024,0x000007c1,0x000007bd,0x000007c0,0x0003003e,0x000007ad,0x000007c1,0x0004003d, + 0x00000006,0x000007c2,0x000007ab,0x00050083,0x00000006,0x000007c3,0x000000c7,0x000007c2, + 0x0004003d,0x00000006,0x000007c4,0x000007ab,0x0003003e,0x000007b0,0x000007c4,0x0003003e, + 0x000007b1,0x000007c3,0x0004003d,0x00000006,0x00000803,0x000007b0,0x00050041,0x00000007, + 0x00000804,0x00000800,0x00000091,0x0003003e,0x00000804,0x00000803,0x0004003d,0x00000006, + 0x00000805,0x000007b1,0x00050041,0x00000007,0x00000806,0x00000800,0x00000094,0x0003003e, + 0x00000806,0x00000805,0x0004003d,0x0000000c,0x00000807,0x00000800,0x0003003e,0x00000801, + 0x00000807,0x0004003d,0x0000000c,0x000007c5,0x00000801,0x0003003e,0x000007b2,0x00000120, + 0x0004003d,0x00000006,0x0000080b,0x000007b2,0x00050041,0x00000007,0x0000080c,0x00000808, + 0x00000091,0x0003003e,0x0000080c,0x0000080b,0x0004003d,0x00000006,0x0000080d,0x000007b2, + 0x00050041,0x00000007,0x0000080e,0x00000808,0x00000094,0x0003003e,0x0000080e,0x0000080d, + 0x0004003d,0x0000000c,0x0000080f,0x00000808,0x0003003e,0x00000809,0x0000080f,0x0004003d, + 0x0000000c,0x000007c6,0x00000809,0x0004003d,0x00000024,0x000007c7,0x000007ad,0x0003003e, + 0x000007b3,0x000007c7,0x0004003d,0x00000024,0x00000813,0x000007b3,0x0007004f,0x0000000c, + 0x00000814,0x00000813,0x00000813,0x00000000,0x00000001,0x0003003e,0x00000810,0x00000814, + 0x00050041,0x00000007,0x0000081b,0x00000810,0x00000091,0x0004003d,0x00000006,0x0000081c, + 0x0000081b,0x00050041,0x00000007,0x0000081d,0x00000810,0x00000094,0x0004003d,0x00000006, + 0x0000081e,0x0000081d,0x0007000c,0x00000006,0x0000081f,0x00000001,0x00000025,0x0000081c, + 0x0000081e,0x0003003e,0x00000819,0x0000081f,0x0004003d,0x00000006,0x00000815,0x00000819, + 0x00050041,0x00000007,0x00000816,0x000007b3,0x000000a7,0x0004003d,0x00000006,0x00000817, + 0x00000816,0x0007000c,0x00000006,0x00000818,0x00000001,0x00000025,0x00000815,0x00000817, + 0x0003003e,0x00000811,0x00000818,0x0004003d,0x00000006,0x000007c8,0x00000811,0x0004007f, + 0x00000006,0x000007c9,0x000007c8,0x0004003d,0x00000024,0x000007ca,0x000007ad,0x0003003e, + 0x000007b4,0x000007ca,0x0004003d,0x00000024,0x00000823,0x000007b4,0x0007004f,0x0000000c, + 0x00000824,0x00000823,0x00000823,0x00000000,0x00000001,0x0003003e,0x00000820,0x00000824, + 0x00050041,0x00000007,0x0000082b,0x00000820,0x00000091,0x0004003d,0x00000006,0x0000082c, + 0x0000082b,0x00050041,0x00000007,0x0000082d,0x00000820,0x00000094,0x0004003d,0x00000006, + 0x0000082e,0x0000082d,0x0007000c,0x00000006,0x0000082f,0x00000001,0x00000028,0x0000082c, + 0x0000082e,0x0003003e,0x00000829,0x0000082f,0x0004003d,0x00000006,0x00000825,0x00000829, + 0x00050041,0x00000007,0x00000826,0x000007b4,0x000000a7,0x0004003d,0x00000006,0x00000827, + 0x00000826,0x0007000c,0x00000006,0x00000828,0x00000001,0x00000028,0x00000825,0x00000827, + 0x0003003e,0x00000821,0x00000828,0x0004003d,0x00000006,0x000007cb,0x00000821,0x0003003e, + 0x000007b5,0x000007c9,0x0003003e,0x000007b6,0x000007cb,0x0004003d,0x00000006,0x00000833, + 0x000007b5,0x00050041,0x00000007,0x00000834,0x00000830,0x00000091,0x0003003e,0x00000834, + 0x00000833,0x0004003d,0x00000006,0x00000835,0x000007b6,0x00050041,0x00000007,0x00000836, + 0x00000830,0x00000094,0x0003003e,0x00000836,0x00000835,0x0004003d,0x0000000c,0x00000837, + 0x00000830,0x0003003e,0x00000831,0x00000837,0x0004003d,0x0000000c,0x000007cc,0x00000831, + 0x0007000c,0x0000000c,0x000007cd,0x00000001,0x00000028,0x000007c6,0x000007cc,0x00050088, + 0x0000000c,0x000007ce,0x000007c5,0x000007cd,0x0003003e,0x000007af,0x000007ce,0x0003003e, + 0x000007b8,0x000000c7,0x0004003d,0x00000006,0x0000083a,0x000007b8,0x0003003e,0x00000838, + 0x0000083a,0x0004003d,0x00000006,0x000007cf,0x00000838,0x00050041,0x00000007,0x000007d0, + 0x000007af,0x00000091,0x0004003d,0x00000006,0x000007d1,0x000007d0,0x00050041,0x00000007, + 0x000007d2,0x000007af,0x00000094,0x0004003d,0x00000006,0x000007d3,0x000007d2,0x0007000c, + 0x00000006,0x000007d4,0x00000001,0x00000025,0x000007d1,0x000007d3,0x0007000c,0x00000006, + 0x000007d5,0x00000001,0x00000025,0x000007cf,0x000007d4,0x0003003e,0x000007b7,0x000007d5, + 0x0004003d,0x00000024,0x000007d6,0x000007ad,0x0004003d,0x00000006,0x000007d7,0x000007b7, + 0x0005008e,0x00000024,0x000007d8,0x000007d6,0x000007d7,0x0004003d,0x00000006,0x000007d9, + 0x000007ab,0x00060050,0x00000024,0x000007da,0x000007d9,0x000007d9,0x000007d9,0x00050081, + 0x00000024,0x000007db,0x000007d8,0x000007da,0x0003003e,0x000007b9,0x000007db,0x0004003d, + 0x00000024,0x0000076a,0x000007b9,0x0003003e,0x00000754,0x0000076a,0x0004003d,0x00000024, + 0x0000068c,0x00000754,0x0003003e,0x00000590,0x0000068c,0x000200f9,0x0000068d,0x000200f8, + 0x0000068d,0x000200f9,0x000006ad,0x000200f8,0x0000068e,0x000300f7,0x00000698,0x00000000, + 0x000400fa,0x00000261,0x0000068f,0x00000698,0x000200f8,0x0000068f,0x0004003d,0x00000024, + 0x00000690,0x0000057e,0x0003003e,0x000005a7,0x000000c8,0x0004003d,0x00000006,0x0000083e, + 0x000005a7,0x00050041,0x00000007,0x0000083f,0x0000083b,0x00000091,0x0003003e,0x0000083f, + 0x0000083e,0x0004003d,0x00000006,0x00000840,0x000005a7,0x00050041,0x00000007,0x00000841, + 0x0000083b,0x00000094,0x0003003e,0x00000841,0x00000840,0x0004003d,0x00000006,0x00000842, + 0x000005a7,0x00050041,0x00000007,0x00000843,0x0000083b,0x000000a7,0x0003003e,0x00000843, + 0x00000842,0x0004003d,0x00000024,0x00000844,0x0000083b,0x0003003e,0x0000083c,0x00000844, + 0x0004003d,0x00000024,0x00000691,0x0000083c,0x0003003e,0x000005a8,0x000000c7,0x0004003d, + 0x00000006,0x00000848,0x000005a8,0x00050041,0x00000007,0x00000849,0x00000845,0x00000091, + 0x0003003e,0x00000849,0x00000848,0x0004003d,0x00000006,0x0000084a,0x000005a8,0x00050041, + 0x00000007,0x0000084b,0x00000845,0x00000094,0x0003003e,0x0000084b,0x0000084a,0x0004003d, + 0x00000006,0x0000084c,0x000005a8,0x00050041,0x00000007,0x0000084d,0x00000845,0x000000a7, + 0x0003003e,0x0000084d,0x0000084c,0x0004003d,0x00000024,0x0000084e,0x00000845,0x0003003e, + 0x00000846,0x0000084e,0x0004003d,0x00000024,0x00000692,0x00000846,0x0008000c,0x00000024, + 0x00000693,0x00000001,0x0000002b,0x00000690,0x00000691,0x00000692,0x0003003e,0x0000057e, + 0x00000693,0x0004003d,0x00000024,0x00000694,0x0000058e,0x0003003e,0x000005a9,0x00000694, + 0x0004003d,0x00000024,0x00000695,0x0000057e,0x0003003e,0x000005aa,0x00000695,0x0004003d, + 0x00000024,0x00000696,0x0000058e,0x0003003e,0x000005ab,0x00000696,0x0004003d,0x00000024, + 0x0000085a,0x000005aa,0x0003003e,0x00000850,0x0000085a,0x0004003d,0x00000024,0x00000872, + 0x00000850,0x0007004f,0x0000000c,0x00000873,0x00000872,0x00000872,0x00000000,0x00000001, + 0x0003003e,0x0000086f,0x00000873,0x00050041,0x00000007,0x0000087a,0x0000086f,0x00000091, + 0x0004003d,0x00000006,0x0000087b,0x0000087a,0x00050041,0x00000007,0x0000087c,0x0000086f, + 0x00000094,0x0004003d,0x00000006,0x0000087d,0x0000087c,0x0007000c,0x00000006,0x0000087e, + 0x00000001,0x00000028,0x0000087b,0x0000087d,0x0003003e,0x00000878,0x0000087e,0x0004003d, + 0x00000006,0x00000874,0x00000878,0x00050041,0x00000007,0x00000875,0x00000850,0x000000a7, + 0x0004003d,0x00000006,0x00000876,0x00000875,0x0007000c,0x00000006,0x00000877,0x00000001, + 0x00000028,0x00000874,0x00000876,0x0003003e,0x00000870,0x00000877,0x0004003d,0x00000006, + 0x0000085b,0x00000870,0x0004003d,0x00000024,0x0000085c,0x000005aa,0x0003003e,0x00000851, + 0x0000085c,0x0004003d,0x00000024,0x00000882,0x00000851,0x0007004f,0x0000000c,0x00000883, + 0x00000882,0x00000882,0x00000000,0x00000001,0x0003003e,0x0000087f,0x00000883,0x00050041, + 0x00000007,0x0000088a,0x0000087f,0x00000091,0x0004003d,0x00000006,0x0000088b,0x0000088a, + 0x00050041,0x00000007,0x0000088c,0x0000087f,0x00000094,0x0004003d,0x00000006,0x0000088d, + 0x0000088c,0x0007000c,0x00000006,0x0000088e,0x00000001,0x00000025,0x0000088b,0x0000088d, + 0x0003003e,0x00000888,0x0000088e,0x0004003d,0x00000006,0x00000884,0x00000888,0x00050041, + 0x00000007,0x00000885,0x00000851,0x000000a7,0x0004003d,0x00000006,0x00000886,0x00000885, + 0x0007000c,0x00000006,0x00000887,0x00000001,0x00000025,0x00000884,0x00000886,0x0003003e, + 0x00000880,0x00000887,0x0004003d,0x00000006,0x0000085d,0x00000880,0x00050083,0x00000006, + 0x0000085e,0x0000085b,0x0000085d,0x0003003e,0x0000084f,0x0000085e,0x0004003d,0x00000024, + 0x0000085f,0x000005a9,0x0003003e,0x00000852,0x0000085f,0x0004003d,0x00000024,0x00000892, + 0x00000852,0x0007004f,0x0000000c,0x00000893,0x00000892,0x00000892,0x00000000,0x00000001, + 0x0003003e,0x0000088f,0x00000893,0x00050041,0x00000007,0x0000089a,0x0000088f,0x00000091, + 0x0004003d,0x00000006,0x0000089b,0x0000089a,0x00050041,0x00000007,0x0000089c,0x0000088f, + 0x00000094,0x0004003d,0x00000006,0x0000089d,0x0000089c,0x0007000c,0x00000006,0x0000089e, + 0x00000001,0x00000025,0x0000089b,0x0000089d,0x0003003e,0x00000898,0x0000089e,0x0004003d, + 0x00000006,0x00000894,0x00000898,0x00050041,0x00000007,0x00000895,0x00000852,0x000000a7, + 0x0004003d,0x00000006,0x00000896,0x00000895,0x0007000c,0x00000006,0x00000897,0x00000001, + 0x00000025,0x00000894,0x00000896,0x0003003e,0x00000890,0x00000897,0x0004003d,0x00000006, + 0x00000860,0x00000890,0x0004003d,0x00000024,0x00000861,0x000005a9,0x00060050,0x00000024, + 0x00000862,0x00000860,0x00000860,0x00000860,0x00050083,0x00000024,0x00000863,0x00000861, + 0x00000862,0x0003003e,0x000005a9,0x00000863,0x0004003d,0x00000024,0x00000864,0x000005a9, + 0x0003003e,0x00000854,0x00000864,0x0004003d,0x00000024,0x000008a2,0x00000854,0x0007004f, + 0x0000000c,0x000008a3,0x000008a2,0x000008a2,0x00000000,0x00000001,0x0003003e,0x0000089f, + 0x000008a3,0x00050041,0x00000007,0x000008aa,0x0000089f,0x00000091,0x0004003d,0x00000006, + 0x000008ab,0x000008aa,0x00050041,0x00000007,0x000008ac,0x0000089f,0x00000094,0x0004003d, + 0x00000006,0x000008ad,0x000008ac,0x0007000c,0x00000006,0x000008ae,0x00000001,0x00000028, + 0x000008ab,0x000008ad,0x0003003e,0x000008a8,0x000008ae,0x0004003d,0x00000006,0x000008a4, + 0x000008a8,0x00050041,0x00000007,0x000008a5,0x00000854,0x000000a7,0x0004003d,0x00000006, + 0x000008a6,0x000008a5,0x0007000c,0x00000006,0x000008a7,0x00000001,0x00000028,0x000008a4, + 0x000008a6,0x0003003e,0x000008a0,0x000008a7,0x0004003d,0x00000006,0x00000865,0x000008a0, + 0x0003003e,0x00000853,0x00000865,0x0004003d,0x00000006,0x00000866,0x0000084f,0x0004003d, + 0x00000006,0x00000867,0x00000853,0x0007000c,0x00000006,0x00000868,0x00000001,0x00000028, + 0x00000120,0x00000867,0x00050088,0x00000006,0x00000869,0x00000866,0x00000868,0x0003003e, + 0x00000855,0x00000869,0x0004003d,0x00000024,0x0000086a,0x000005a9,0x0004003d,0x00000006, + 0x0000086b,0x00000855,0x0005008e,0x00000024,0x0000086c,0x0000086a,0x0000086b,0x0003003e, + 0x00000856,0x0000086c,0x0004003d,0x00000024,0x0000086d,0x000005ab,0x0003003e,0x00000857, + 0x0000086d,0x0004003d,0x00000024,0x000008bf,0x00000857,0x0003003e,0x000008b0,0x000008bf, + 0x0004003d,0x00000024,0x000008e5,0x000008b0,0x0003003e,0x000008e0,0x00000104,0x0003003e, + 0x000008e1,0x00000105,0x0003003e,0x000008e2,0x00000106,0x0004003d,0x00000006,0x000008eb, + 0x000008e0,0x00050041,0x00000007,0x000008ec,0x000008e8,0x00000091,0x0003003e,0x000008ec, + 0x000008eb,0x0004003d,0x00000006,0x000008ed,0x000008e1,0x00050041,0x00000007,0x000008ee, + 0x000008e8,0x00000094,0x0003003e,0x000008ee,0x000008ed,0x0004003d,0x00000006,0x000008ef, + 0x000008e2,0x00050041,0x00000007,0x000008f0,0x000008e8,0x000000a7,0x0003003e,0x000008f0, + 0x000008ef,0x0004003d,0x00000024,0x000008f1,0x000008e8,0x0003003e,0x000008e9,0x000008f1, + 0x0004003d,0x00000024,0x000008e6,0x000008e9,0x00050094,0x00000006,0x000008e7,0x000008e5, + 0x000008e6,0x0003003e,0x000008e3,0x000008e7,0x0004003d,0x00000006,0x000008c0,0x000008e3, + 0x0003003e,0x000008af,0x000008c0,0x0004003d,0x00000024,0x000008c1,0x00000856,0x0004003d, + 0x00000024,0x000008c2,0x00000856,0x0003003e,0x000008b2,0x000008c2,0x0004003d,0x00000024, + 0x000008f7,0x000008b2,0x0003003e,0x000008f2,0x00000104,0x0003003e,0x000008f3,0x00000105, + 0x0003003e,0x000008f4,0x00000106,0x0004003d,0x00000006,0x000008fd,0x000008f2,0x00050041, + 0x00000007,0x000008fe,0x000008fa,0x00000091,0x0003003e,0x000008fe,0x000008fd,0x0004003d, + 0x00000006,0x000008ff,0x000008f3,0x00050041,0x00000007,0x00000900,0x000008fa,0x00000094, + 0x0003003e,0x00000900,0x000008ff,0x0004003d,0x00000006,0x00000901,0x000008f4,0x00050041, + 0x00000007,0x00000902,0x000008fa,0x000000a7,0x0003003e,0x00000902,0x00000901,0x0004003d, + 0x00000024,0x00000903,0x000008fa,0x0003003e,0x000008fb,0x00000903,0x0004003d,0x00000024, + 0x000008f8,0x000008fb,0x00050094,0x00000006,0x000008f9,0x000008f7,0x000008f8,0x0003003e, + 0x000008f5,0x000008f9,0x0004003d,0x00000006,0x000008c3,0x000008f5,0x00060050,0x00000024, + 0x000008c4,0x000008c3,0x000008c3,0x000008c3,0x00050083,0x00000024,0x000008c5,0x000008c1, + 0x000008c4,0x0003003e,0x000008b1,0x000008c5,0x0004003d,0x00000006,0x000008c6,0x000008af, + 0x00050083,0x00000006,0x000008c7,0x000000c7,0x000008c6,0x0004003d,0x00000006,0x000008c8, + 0x000008af,0x0003003e,0x000008b4,0x000008c8,0x0003003e,0x000008b5,0x000008c7,0x0004003d, + 0x00000006,0x00000907,0x000008b4,0x00050041,0x00000007,0x00000908,0x00000904,0x00000091, + 0x0003003e,0x00000908,0x00000907,0x0004003d,0x00000006,0x00000909,0x000008b5,0x00050041, + 0x00000007,0x0000090a,0x00000904,0x00000094,0x0003003e,0x0000090a,0x00000909,0x0004003d, + 0x0000000c,0x0000090b,0x00000904,0x0003003e,0x00000905,0x0000090b,0x0004003d,0x0000000c, + 0x000008c9,0x00000905,0x0003003e,0x000008b6,0x00000120,0x0004003d,0x00000006,0x0000090f, + 0x000008b6,0x00050041,0x00000007,0x00000910,0x0000090c,0x00000091,0x0003003e,0x00000910, + 0x0000090f,0x0004003d,0x00000006,0x00000911,0x000008b6,0x00050041,0x00000007,0x00000912, + 0x0000090c,0x00000094,0x0003003e,0x00000912,0x00000911,0x0004003d,0x0000000c,0x00000913, + 0x0000090c,0x0003003e,0x0000090d,0x00000913,0x0004003d,0x0000000c,0x000008ca,0x0000090d, + 0x0004003d,0x00000024,0x000008cb,0x000008b1,0x0003003e,0x000008b7,0x000008cb,0x0004003d, + 0x00000024,0x00000917,0x000008b7,0x0007004f,0x0000000c,0x00000918,0x00000917,0x00000917, + 0x00000000,0x00000001,0x0003003e,0x00000914,0x00000918,0x00050041,0x00000007,0x0000091f, + 0x00000914,0x00000091,0x0004003d,0x00000006,0x00000920,0x0000091f,0x00050041,0x00000007, + 0x00000921,0x00000914,0x00000094,0x0004003d,0x00000006,0x00000922,0x00000921,0x0007000c, + 0x00000006,0x00000923,0x00000001,0x00000025,0x00000920,0x00000922,0x0003003e,0x0000091d, + 0x00000923,0x0004003d,0x00000006,0x00000919,0x0000091d,0x00050041,0x00000007,0x0000091a, + 0x000008b7,0x000000a7,0x0004003d,0x00000006,0x0000091b,0x0000091a,0x0007000c,0x00000006, + 0x0000091c,0x00000001,0x00000025,0x00000919,0x0000091b,0x0003003e,0x00000915,0x0000091c, + 0x0004003d,0x00000006,0x000008cc,0x00000915,0x0004007f,0x00000006,0x000008cd,0x000008cc, + 0x0004003d,0x00000024,0x000008ce,0x000008b1,0x0003003e,0x000008b8,0x000008ce,0x0004003d, + 0x00000024,0x00000927,0x000008b8,0x0007004f,0x0000000c,0x00000928,0x00000927,0x00000927, + 0x00000000,0x00000001,0x0003003e,0x00000924,0x00000928,0x00050041,0x00000007,0x0000092f, + 0x00000924,0x00000091,0x0004003d,0x00000006,0x00000930,0x0000092f,0x00050041,0x00000007, + 0x00000931,0x00000924,0x00000094,0x0004003d,0x00000006,0x00000932,0x00000931,0x0007000c, + 0x00000006,0x00000933,0x00000001,0x00000028,0x00000930,0x00000932,0x0003003e,0x0000092d, + 0x00000933,0x0004003d,0x00000006,0x00000929,0x0000092d,0x00050041,0x00000007,0x0000092a, + 0x000008b8,0x000000a7,0x0004003d,0x00000006,0x0000092b,0x0000092a,0x0007000c,0x00000006, + 0x0000092c,0x00000001,0x00000028,0x00000929,0x0000092b,0x0003003e,0x00000925,0x0000092c, + 0x0004003d,0x00000006,0x000008cf,0x00000925,0x0003003e,0x000008b9,0x000008cd,0x0003003e, + 0x000008ba,0x000008cf,0x0004003d,0x00000006,0x00000937,0x000008b9,0x00050041,0x00000007, + 0x00000938,0x00000934,0x00000091,0x0003003e,0x00000938,0x00000937,0x0004003d,0x00000006, + 0x00000939,0x000008ba,0x00050041,0x00000007,0x0000093a,0x00000934,0x00000094,0x0003003e, + 0x0000093a,0x00000939,0x0004003d,0x0000000c,0x0000093b,0x00000934,0x0003003e,0x00000935, + 0x0000093b,0x0004003d,0x0000000c,0x000008d0,0x00000935,0x0007000c,0x0000000c,0x000008d1, + 0x00000001,0x00000028,0x000008ca,0x000008d0,0x00050088,0x0000000c,0x000008d2,0x000008c9, + 0x000008d1,0x0003003e,0x000008b3,0x000008d2,0x0003003e,0x000008bc,0x000000c7,0x0004003d, + 0x00000006,0x0000093e,0x000008bc,0x0003003e,0x0000093c,0x0000093e,0x0004003d,0x00000006, + 0x000008d3,0x0000093c,0x00050041,0x00000007,0x000008d4,0x000008b3,0x00000091,0x0004003d, + 0x00000006,0x000008d5,0x000008d4,0x00050041,0x00000007,0x000008d6,0x000008b3,0x00000094, + 0x0004003d,0x00000006,0x000008d7,0x000008d6,0x0007000c,0x00000006,0x000008d8,0x00000001, + 0x00000025,0x000008d5,0x000008d7,0x0007000c,0x00000006,0x000008d9,0x00000001,0x00000025, + 0x000008d3,0x000008d8,0x0003003e,0x000008bb,0x000008d9,0x0004003d,0x00000024,0x000008da, + 0x000008b1,0x0004003d,0x00000006,0x000008db,0x000008bb,0x0005008e,0x00000024,0x000008dc, + 0x000008da,0x000008db,0x0004003d,0x00000006,0x000008dd,0x000008af,0x00060050,0x00000024, + 0x000008de,0x000008dd,0x000008dd,0x000008dd,0x00050081,0x00000024,0x000008df,0x000008dc, + 0x000008de,0x0003003e,0x000008bd,0x000008df,0x0004003d,0x00000024,0x0000086e,0x000008bd, + 0x0003003e,0x00000858,0x0000086e,0x0004003d,0x00000024,0x00000697,0x00000858,0x0003003e, + 0x00000590,0x00000697,0x000200f9,0x00000698,0x000200f8,0x00000698,0x000200f9,0x000006ad, + 0x000200f8,0x00000699,0x000300f7,0x000006a2,0x00000000,0x000400fa,0x00000261,0x0000069a, + 0x000006a2,0x000200f8,0x0000069a,0x0004003d,0x00000024,0x0000069b,0x0000057e,0x0003003e, + 0x000005ac,0x000000c8,0x0004003d,0x00000006,0x00000942,0x000005ac,0x00050041,0x00000007, + 0x00000943,0x0000093f,0x00000091,0x0003003e,0x00000943,0x00000942,0x0004003d,0x00000006, + 0x00000944,0x000005ac,0x00050041,0x00000007,0x00000945,0x0000093f,0x00000094,0x0003003e, + 0x00000945,0x00000944,0x0004003d,0x00000006,0x00000946,0x000005ac,0x00050041,0x00000007, + 0x00000947,0x0000093f,0x000000a7,0x0003003e,0x00000947,0x00000946,0x0004003d,0x00000024, + 0x00000948,0x0000093f,0x0003003e,0x00000940,0x00000948,0x0004003d,0x00000024,0x0000069c, + 0x00000940,0x0003003e,0x000005ad,0x000000c7,0x0004003d,0x00000006,0x0000094c,0x000005ad, + 0x00050041,0x00000007,0x0000094d,0x00000949,0x00000091,0x0003003e,0x0000094d,0x0000094c, + 0x0004003d,0x00000006,0x0000094e,0x000005ad,0x00050041,0x00000007,0x0000094f,0x00000949, + 0x00000094,0x0003003e,0x0000094f,0x0000094e,0x0004003d,0x00000006,0x00000950,0x000005ad, + 0x00050041,0x00000007,0x00000951,0x00000949,0x000000a7,0x0003003e,0x00000951,0x00000950, + 0x0004003d,0x00000024,0x00000952,0x00000949,0x0003003e,0x0000094a,0x00000952,0x0004003d, + 0x00000024,0x0000069d,0x0000094a,0x0008000c,0x00000024,0x0000069e,0x00000001,0x0000002b, + 0x0000069b,0x0000069c,0x0000069d,0x0003003e,0x0000057e,0x0000069e,0x0004003d,0x00000024, + 0x0000069f,0x0000057e,0x0003003e,0x000005ae,0x0000069f,0x0004003d,0x00000024,0x000006a0, + 0x0000058e,0x0003003e,0x000005af,0x000006a0,0x0004003d,0x00000024,0x00000963,0x000005af, + 0x0003003e,0x00000954,0x00000963,0x0004003d,0x00000024,0x00000989,0x00000954,0x0003003e, + 0x00000984,0x00000104,0x0003003e,0x00000985,0x00000105,0x0003003e,0x00000986,0x00000106, + 0x0004003d,0x00000006,0x0000098f,0x00000984,0x00050041,0x00000007,0x00000990,0x0000098c, + 0x00000091,0x0003003e,0x00000990,0x0000098f,0x0004003d,0x00000006,0x00000991,0x00000985, + 0x00050041,0x00000007,0x00000992,0x0000098c,0x00000094,0x0003003e,0x00000992,0x00000991, + 0x0004003d,0x00000006,0x00000993,0x00000986,0x00050041,0x00000007,0x00000994,0x0000098c, + 0x000000a7,0x0003003e,0x00000994,0x00000993,0x0004003d,0x00000024,0x00000995,0x0000098c, + 0x0003003e,0x0000098d,0x00000995,0x0004003d,0x00000024,0x0000098a,0x0000098d,0x00050094, + 0x00000006,0x0000098b,0x00000989,0x0000098a,0x0003003e,0x00000987,0x0000098b,0x0004003d, + 0x00000006,0x00000964,0x00000987,0x0003003e,0x00000953,0x00000964,0x0004003d,0x00000024, + 0x00000965,0x000005ae,0x0004003d,0x00000024,0x00000966,0x000005ae,0x0003003e,0x00000956, + 0x00000966,0x0004003d,0x00000024,0x0000099b,0x00000956,0x0003003e,0x00000996,0x00000104, + 0x0003003e,0x00000997,0x00000105,0x0003003e,0x00000998,0x00000106,0x0004003d,0x00000006, + 0x000009a1,0x00000996,0x00050041,0x00000007,0x000009a2,0x0000099e,0x00000091,0x0003003e, + 0x000009a2,0x000009a1,0x0004003d,0x00000006,0x000009a3,0x00000997,0x00050041,0x00000007, + 0x000009a4,0x0000099e,0x00000094,0x0003003e,0x000009a4,0x000009a3,0x0004003d,0x00000006, + 0x000009a5,0x00000998,0x00050041,0x00000007,0x000009a6,0x0000099e,0x000000a7,0x0003003e, + 0x000009a6,0x000009a5,0x0004003d,0x00000024,0x000009a7,0x0000099e,0x0003003e,0x0000099f, + 0x000009a7,0x0004003d,0x00000024,0x0000099c,0x0000099f,0x00050094,0x00000006,0x0000099d, + 0x0000099b,0x0000099c,0x0003003e,0x00000999,0x0000099d,0x0004003d,0x00000006,0x00000967, + 0x00000999,0x00060050,0x00000024,0x00000968,0x00000967,0x00000967,0x00000967,0x00050083, + 0x00000024,0x00000969,0x00000965,0x00000968,0x0003003e,0x00000955,0x00000969,0x0004003d, + 0x00000006,0x0000096a,0x00000953,0x00050083,0x00000006,0x0000096b,0x000000c7,0x0000096a, + 0x0004003d,0x00000006,0x0000096c,0x00000953,0x0003003e,0x00000958,0x0000096c,0x0003003e, + 0x00000959,0x0000096b,0x0004003d,0x00000006,0x000009ab,0x00000958,0x00050041,0x00000007, + 0x000009ac,0x000009a8,0x00000091,0x0003003e,0x000009ac,0x000009ab,0x0004003d,0x00000006, + 0x000009ad,0x00000959,0x00050041,0x00000007,0x000009ae,0x000009a8,0x00000094,0x0003003e, + 0x000009ae,0x000009ad,0x0004003d,0x0000000c,0x000009af,0x000009a8,0x0003003e,0x000009a9, + 0x000009af,0x0004003d,0x0000000c,0x0000096d,0x000009a9,0x0003003e,0x0000095a,0x00000120, + 0x0004003d,0x00000006,0x000009b3,0x0000095a,0x00050041,0x00000007,0x000009b4,0x000009b0, + 0x00000091,0x0003003e,0x000009b4,0x000009b3,0x0004003d,0x00000006,0x000009b5,0x0000095a, + 0x00050041,0x00000007,0x000009b6,0x000009b0,0x00000094,0x0003003e,0x000009b6,0x000009b5, + 0x0004003d,0x0000000c,0x000009b7,0x000009b0,0x0003003e,0x000009b1,0x000009b7,0x0004003d, + 0x0000000c,0x0000096e,0x000009b1,0x0004003d,0x00000024,0x0000096f,0x00000955,0x0003003e, + 0x0000095b,0x0000096f,0x0004003d,0x00000024,0x000009bb,0x0000095b,0x0007004f,0x0000000c, + 0x000009bc,0x000009bb,0x000009bb,0x00000000,0x00000001,0x0003003e,0x000009b8,0x000009bc, + 0x00050041,0x00000007,0x000009c3,0x000009b8,0x00000091,0x0004003d,0x00000006,0x000009c4, + 0x000009c3,0x00050041,0x00000007,0x000009c5,0x000009b8,0x00000094,0x0004003d,0x00000006, + 0x000009c6,0x000009c5,0x0007000c,0x00000006,0x000009c7,0x00000001,0x00000025,0x000009c4, + 0x000009c6,0x0003003e,0x000009c1,0x000009c7,0x0004003d,0x00000006,0x000009bd,0x000009c1, + 0x00050041,0x00000007,0x000009be,0x0000095b,0x000000a7,0x0004003d,0x00000006,0x000009bf, + 0x000009be,0x0007000c,0x00000006,0x000009c0,0x00000001,0x00000025,0x000009bd,0x000009bf, + 0x0003003e,0x000009b9,0x000009c0,0x0004003d,0x00000006,0x00000970,0x000009b9,0x0004007f, + 0x00000006,0x00000971,0x00000970,0x0004003d,0x00000024,0x00000972,0x00000955,0x0003003e, + 0x0000095c,0x00000972,0x0004003d,0x00000024,0x000009cb,0x0000095c,0x0007004f,0x0000000c, + 0x000009cc,0x000009cb,0x000009cb,0x00000000,0x00000001,0x0003003e,0x000009c8,0x000009cc, + 0x00050041,0x00000007,0x000009d3,0x000009c8,0x00000091,0x0004003d,0x00000006,0x000009d4, + 0x000009d3,0x00050041,0x00000007,0x000009d5,0x000009c8,0x00000094,0x0004003d,0x00000006, + 0x000009d6,0x000009d5,0x0007000c,0x00000006,0x000009d7,0x00000001,0x00000028,0x000009d4, + 0x000009d6,0x0003003e,0x000009d1,0x000009d7,0x0004003d,0x00000006,0x000009cd,0x000009d1, + 0x00050041,0x00000007,0x000009ce,0x0000095c,0x000000a7,0x0004003d,0x00000006,0x000009cf, + 0x000009ce,0x0007000c,0x00000006,0x000009d0,0x00000001,0x00000028,0x000009cd,0x000009cf, + 0x0003003e,0x000009c9,0x000009d0,0x0004003d,0x00000006,0x00000973,0x000009c9,0x0003003e, + 0x0000095d,0x00000971,0x0003003e,0x0000095e,0x00000973,0x0004003d,0x00000006,0x000009db, + 0x0000095d,0x00050041,0x00000007,0x000009dc,0x000009d8,0x00000091,0x0003003e,0x000009dc, + 0x000009db,0x0004003d,0x00000006,0x000009dd,0x0000095e,0x00050041,0x00000007,0x000009de, + 0x000009d8,0x00000094,0x0003003e,0x000009de,0x000009dd,0x0004003d,0x0000000c,0x000009df, + 0x000009d8,0x0003003e,0x000009d9,0x000009df,0x0004003d,0x0000000c,0x00000974,0x000009d9, + 0x0007000c,0x0000000c,0x00000975,0x00000001,0x00000028,0x0000096e,0x00000974,0x00050088, + 0x0000000c,0x00000976,0x0000096d,0x00000975,0x0003003e,0x00000957,0x00000976,0x0003003e, + 0x00000960,0x000000c7,0x0004003d,0x00000006,0x000009e2,0x00000960,0x0003003e,0x000009e0, + 0x000009e2,0x0004003d,0x00000006,0x00000977,0x000009e0,0x00050041,0x00000007,0x00000978, + 0x00000957,0x00000091,0x0004003d,0x00000006,0x00000979,0x00000978,0x00050041,0x00000007, + 0x0000097a,0x00000957,0x00000094,0x0004003d,0x00000006,0x0000097b,0x0000097a,0x0007000c, + 0x00000006,0x0000097c,0x00000001,0x00000025,0x00000979,0x0000097b,0x0007000c,0x00000006, + 0x0000097d,0x00000001,0x00000025,0x00000977,0x0000097c,0x0003003e,0x0000095f,0x0000097d, + 0x0004003d,0x00000024,0x0000097e,0x00000955,0x0004003d,0x00000006,0x0000097f,0x0000095f, + 0x0005008e,0x00000024,0x00000980,0x0000097e,0x0000097f,0x0004003d,0x00000006,0x00000981, + 0x00000953,0x00060050,0x00000024,0x00000982,0x00000981,0x00000981,0x00000981,0x00050081, + 0x00000024,0x00000983,0x00000980,0x00000982,0x0003003e,0x00000961,0x00000983,0x0004003d, + 0x00000024,0x000006a1,0x00000961,0x0003003e,0x00000590,0x000006a1,0x000200f9,0x000006a2, + 0x000200f8,0x000006a2,0x000200f9,0x000006ad,0x000200f8,0x000006a3,0x000300f7,0x000006ac, + 0x00000000,0x000400fa,0x00000261,0x000006a4,0x000006ac,0x000200f8,0x000006a4,0x0004003d, + 0x00000024,0x000006a5,0x0000057e,0x0003003e,0x000005b0,0x000000c8,0x0004003d,0x00000006, + 0x000009e6,0x000005b0,0x00050041,0x00000007,0x000009e7,0x000009e3,0x00000091,0x0003003e, + 0x000009e7,0x000009e6,0x0004003d,0x00000006,0x000009e8,0x000005b0,0x00050041,0x00000007, + 0x000009e9,0x000009e3,0x00000094,0x0003003e,0x000009e9,0x000009e8,0x0004003d,0x00000006, + 0x000009ea,0x000005b0,0x00050041,0x00000007,0x000009eb,0x000009e3,0x000000a7,0x0003003e, + 0x000009eb,0x000009ea,0x0004003d,0x00000024,0x000009ec,0x000009e3,0x0003003e,0x000009e4, + 0x000009ec,0x0004003d,0x00000024,0x000006a6,0x000009e4,0x0003003e,0x000005b1,0x000000c7, + 0x0004003d,0x00000006,0x000009f0,0x000005b1,0x00050041,0x00000007,0x000009f1,0x000009ed, + 0x00000091,0x0003003e,0x000009f1,0x000009f0,0x0004003d,0x00000006,0x000009f2,0x000005b1, + 0x00050041,0x00000007,0x000009f3,0x000009ed,0x00000094,0x0003003e,0x000009f3,0x000009f2, + 0x0004003d,0x00000006,0x000009f4,0x000005b1,0x00050041,0x00000007,0x000009f5,0x000009ed, + 0x000000a7,0x0003003e,0x000009f5,0x000009f4,0x0004003d,0x00000024,0x000009f6,0x000009ed, + 0x0003003e,0x000009ee,0x000009f6,0x0004003d,0x00000024,0x000006a7,0x000009ee,0x0008000c, + 0x00000024,0x000006a8,0x00000001,0x0000002b,0x000006a5,0x000006a6,0x000006a7,0x0003003e, + 0x0000057e,0x000006a8,0x0004003d,0x00000024,0x000006a9,0x0000058e,0x0003003e,0x000005b2, + 0x000006a9,0x0004003d,0x00000024,0x000006aa,0x0000057e,0x0003003e,0x000005b3,0x000006aa, + 0x0004003d,0x00000024,0x00000a07,0x000005b3,0x0003003e,0x000009f8,0x00000a07,0x0004003d, + 0x00000024,0x00000a2d,0x000009f8,0x0003003e,0x00000a28,0x00000104,0x0003003e,0x00000a29, + 0x00000105,0x0003003e,0x00000a2a,0x00000106,0x0004003d,0x00000006,0x00000a33,0x00000a28, + 0x00050041,0x00000007,0x00000a34,0x00000a30,0x00000091,0x0003003e,0x00000a34,0x00000a33, + 0x0004003d,0x00000006,0x00000a35,0x00000a29,0x00050041,0x00000007,0x00000a36,0x00000a30, + 0x00000094,0x0003003e,0x00000a36,0x00000a35,0x0004003d,0x00000006,0x00000a37,0x00000a2a, + 0x00050041,0x00000007,0x00000a38,0x00000a30,0x000000a7,0x0003003e,0x00000a38,0x00000a37, + 0x0004003d,0x00000024,0x00000a39,0x00000a30,0x0003003e,0x00000a31,0x00000a39,0x0004003d, + 0x00000024,0x00000a2e,0x00000a31,0x00050094,0x00000006,0x00000a2f,0x00000a2d,0x00000a2e, + 0x0003003e,0x00000a2b,0x00000a2f,0x0004003d,0x00000006,0x00000a08,0x00000a2b,0x0003003e, + 0x000009f7,0x00000a08,0x0004003d,0x00000024,0x00000a09,0x000005b2,0x0004003d,0x00000024, + 0x00000a0a,0x000005b2,0x0003003e,0x000009fa,0x00000a0a,0x0004003d,0x00000024,0x00000a3f, + 0x000009fa,0x0003003e,0x00000a3a,0x00000104,0x0003003e,0x00000a3b,0x00000105,0x0003003e, + 0x00000a3c,0x00000106,0x0004003d,0x00000006,0x00000a45,0x00000a3a,0x00050041,0x00000007, + 0x00000a46,0x00000a42,0x00000091,0x0003003e,0x00000a46,0x00000a45,0x0004003d,0x00000006, + 0x00000a47,0x00000a3b,0x00050041,0x00000007,0x00000a48,0x00000a42,0x00000094,0x0003003e, + 0x00000a48,0x00000a47,0x0004003d,0x00000006,0x00000a49,0x00000a3c,0x00050041,0x00000007, + 0x00000a4a,0x00000a42,0x000000a7,0x0003003e,0x00000a4a,0x00000a49,0x0004003d,0x00000024, + 0x00000a4b,0x00000a42,0x0003003e,0x00000a43,0x00000a4b,0x0004003d,0x00000024,0x00000a40, + 0x00000a43,0x00050094,0x00000006,0x00000a41,0x00000a3f,0x00000a40,0x0003003e,0x00000a3d, + 0x00000a41,0x0004003d,0x00000006,0x00000a0b,0x00000a3d,0x00060050,0x00000024,0x00000a0c, + 0x00000a0b,0x00000a0b,0x00000a0b,0x00050083,0x00000024,0x00000a0d,0x00000a09,0x00000a0c, + 0x0003003e,0x000009f9,0x00000a0d,0x0004003d,0x00000006,0x00000a0e,0x000009f7,0x00050083, + 0x00000006,0x00000a0f,0x000000c7,0x00000a0e,0x0004003d,0x00000006,0x00000a10,0x000009f7, + 0x0003003e,0x000009fc,0x00000a10,0x0003003e,0x000009fd,0x00000a0f,0x0004003d,0x00000006, + 0x00000a4f,0x000009fc,0x00050041,0x00000007,0x00000a50,0x00000a4c,0x00000091,0x0003003e, + 0x00000a50,0x00000a4f,0x0004003d,0x00000006,0x00000a51,0x000009fd,0x00050041,0x00000007, + 0x00000a52,0x00000a4c,0x00000094,0x0003003e,0x00000a52,0x00000a51,0x0004003d,0x0000000c, + 0x00000a53,0x00000a4c,0x0003003e,0x00000a4d,0x00000a53,0x0004003d,0x0000000c,0x00000a11, + 0x00000a4d,0x0003003e,0x000009fe,0x00000120,0x0004003d,0x00000006,0x00000a57,0x000009fe, + 0x00050041,0x00000007,0x00000a58,0x00000a54,0x00000091,0x0003003e,0x00000a58,0x00000a57, + 0x0004003d,0x00000006,0x00000a59,0x000009fe,0x00050041,0x00000007,0x00000a5a,0x00000a54, + 0x00000094,0x0003003e,0x00000a5a,0x00000a59,0x0004003d,0x0000000c,0x00000a5b,0x00000a54, + 0x0003003e,0x00000a55,0x00000a5b,0x0004003d,0x0000000c,0x00000a12,0x00000a55,0x0004003d, + 0x00000024,0x00000a13,0x000009f9,0x0003003e,0x000009ff,0x00000a13,0x0004003d,0x00000024, + 0x00000a5f,0x000009ff,0x0007004f,0x0000000c,0x00000a60,0x00000a5f,0x00000a5f,0x00000000, + 0x00000001,0x0003003e,0x00000a5c,0x00000a60,0x00050041,0x00000007,0x00000a67,0x00000a5c, + 0x00000091,0x0004003d,0x00000006,0x00000a68,0x00000a67,0x00050041,0x00000007,0x00000a69, + 0x00000a5c,0x00000094,0x0004003d,0x00000006,0x00000a6a,0x00000a69,0x0007000c,0x00000006, + 0x00000a6b,0x00000001,0x00000025,0x00000a68,0x00000a6a,0x0003003e,0x00000a65,0x00000a6b, + 0x0004003d,0x00000006,0x00000a61,0x00000a65,0x00050041,0x00000007,0x00000a62,0x000009ff, + 0x000000a7,0x0004003d,0x00000006,0x00000a63,0x00000a62,0x0007000c,0x00000006,0x00000a64, + 0x00000001,0x00000025,0x00000a61,0x00000a63,0x0003003e,0x00000a5d,0x00000a64,0x0004003d, + 0x00000006,0x00000a14,0x00000a5d,0x0004007f,0x00000006,0x00000a15,0x00000a14,0x0004003d, + 0x00000024,0x00000a16,0x000009f9,0x0003003e,0x00000a00,0x00000a16,0x0004003d,0x00000024, + 0x00000a6f,0x00000a00,0x0007004f,0x0000000c,0x00000a70,0x00000a6f,0x00000a6f,0x00000000, + 0x00000001,0x0003003e,0x00000a6c,0x00000a70,0x00050041,0x00000007,0x00000a77,0x00000a6c, + 0x00000091,0x0004003d,0x00000006,0x00000a78,0x00000a77,0x00050041,0x00000007,0x00000a79, + 0x00000a6c,0x00000094,0x0004003d,0x00000006,0x00000a7a,0x00000a79,0x0007000c,0x00000006, + 0x00000a7b,0x00000001,0x00000028,0x00000a78,0x00000a7a,0x0003003e,0x00000a75,0x00000a7b, + 0x0004003d,0x00000006,0x00000a71,0x00000a75,0x00050041,0x00000007,0x00000a72,0x00000a00, + 0x000000a7,0x0004003d,0x00000006,0x00000a73,0x00000a72,0x0007000c,0x00000006,0x00000a74, + 0x00000001,0x00000028,0x00000a71,0x00000a73,0x0003003e,0x00000a6d,0x00000a74,0x0004003d, + 0x00000006,0x00000a17,0x00000a6d,0x0003003e,0x00000a01,0x00000a15,0x0003003e,0x00000a02, + 0x00000a17,0x0004003d,0x00000006,0x00000a7f,0x00000a01,0x00050041,0x00000007,0x00000a80, + 0x00000a7c,0x00000091,0x0003003e,0x00000a80,0x00000a7f,0x0004003d,0x00000006,0x00000a81, + 0x00000a02,0x00050041,0x00000007,0x00000a82,0x00000a7c,0x00000094,0x0003003e,0x00000a82, + 0x00000a81,0x0004003d,0x0000000c,0x00000a83,0x00000a7c,0x0003003e,0x00000a7d,0x00000a83, + 0x0004003d,0x0000000c,0x00000a18,0x00000a7d,0x0007000c,0x0000000c,0x00000a19,0x00000001, + 0x00000028,0x00000a12,0x00000a18,0x00050088,0x0000000c,0x00000a1a,0x00000a11,0x00000a19, + 0x0003003e,0x000009fb,0x00000a1a,0x0003003e,0x00000a04,0x000000c7,0x0004003d,0x00000006, + 0x00000a86,0x00000a04,0x0003003e,0x00000a84,0x00000a86,0x0004003d,0x00000006,0x00000a1b, + 0x00000a84,0x00050041,0x00000007,0x00000a1c,0x000009fb,0x00000091,0x0004003d,0x00000006, + 0x00000a1d,0x00000a1c,0x00050041,0x00000007,0x00000a1e,0x000009fb,0x00000094,0x0004003d, + 0x00000006,0x00000a1f,0x00000a1e,0x0007000c,0x00000006,0x00000a20,0x00000001,0x00000025, + 0x00000a1d,0x00000a1f,0x0007000c,0x00000006,0x00000a21,0x00000001,0x00000025,0x00000a1b, + 0x00000a20,0x0003003e,0x00000a03,0x00000a21,0x0004003d,0x00000024,0x00000a22,0x000009f9, + 0x0004003d,0x00000006,0x00000a23,0x00000a03,0x0005008e,0x00000024,0x00000a24,0x00000a22, + 0x00000a23,0x0004003d,0x00000006,0x00000a25,0x000009f7,0x00060050,0x00000024,0x00000a26, + 0x00000a25,0x00000a25,0x00000a25,0x00050081,0x00000024,0x00000a27,0x00000a24,0x00000a26, + 0x0003003e,0x00000a05,0x00000a27,0x0004003d,0x00000024,0x000006ab,0x00000a05,0x0003003e, + 0x00000590,0x000006ab,0x000200f9,0x000006ac,0x000200f8,0x000006ac,0x000200f9,0x000006ad, + 0x000200f8,0x000006ad,0x0004003d,0x00000024,0x000006ae,0x00000590,0x0003003e,0x000005b4, + 0x000006ae,0x0004003d,0x00000024,0x00000587,0x000005b4,0x0003003e,0x0000057d,0x00000587, + 0x0004003d,0x00000024,0x00000588,0x0000045e,0x0004003d,0x00000024,0x00000589,0x0000057d, + 0x00050041,0x00000007,0x0000058a,0x0000045f,0x000000be,0x0004003d,0x00000006,0x0000058b, + 0x0000058a,0x0003003e,0x00000581,0x0000058b,0x0004003d,0x00000006,0x00000a8a,0x00000581, + 0x00050041,0x00000007,0x00000a8b,0x00000a87,0x00000091,0x0003003e,0x00000a8b,0x00000a8a, + 0x0004003d,0x00000006,0x00000a8c,0x00000581,0x00050041,0x00000007,0x00000a8d,0x00000a87, + 0x00000094,0x0003003e,0x00000a8d,0x00000a8c,0x0004003d,0x00000006,0x00000a8e,0x00000581, + 0x00050041,0x00000007,0x00000a8f,0x00000a87,0x000000a7,0x0003003e,0x00000a8f,0x00000a8e, + 0x0004003d,0x00000024,0x00000a90,0x00000a87,0x0003003e,0x00000a88,0x00000a90,0x0004003d, + 0x00000024,0x0000058c,0x00000a88,0x0008000c,0x00000024,0x0000058d,0x00000001,0x0000002e, + 0x00000588,0x00000589,0x0000058c,0x0003003e,0x00000582,0x0000058d,0x0004003d,0x00000024, + 0x00000519,0x00000582,0x00050041,0x00000007,0x0000051a,0x00000406,0x00000091,0x00050051, + 0x00000006,0x0000051b,0x00000519,0x00000000,0x0003003e,0x0000051a,0x0000051b,0x00050041, + 0x00000007,0x0000051c,0x00000406,0x00000094,0x00050051,0x00000006,0x0000051d,0x00000519, + 0x00000001,0x0003003e,0x0000051c,0x0000051d,0x00050041,0x00000007,0x0000051e,0x00000406, + 0x000000a7,0x00050051,0x00000006,0x0000051f,0x00000519,0x00000002,0x0003003e,0x0000051e, + 0x0000051f,0x000200f9,0x00000520,0x000200f8,0x00000520,0x0004003d,0x00000006,0x00000522, + 0x000004ff,0x0004003d,0x0000002f,0x00000523,0x00000406,0x0008004f,0x00000024,0x00000524, + 0x00000523,0x00000523,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000024,0x00000525, + 0x00000524,0x00000522,0x00050041,0x00000007,0x00000526,0x00000406,0x00000091,0x00050051, + 0x00000006,0x00000527,0x00000525,0x00000000,0x0003003e,0x00000526,0x00000527,0x00050041, + 0x00000007,0x00000528,0x00000406,0x00000094,0x00050051,0x00000006,0x00000529,0x00000525, + 0x00000001,0x0003003e,0x00000528,0x00000529,0x00050041,0x00000007,0x0000052a,0x00000406, + 0x000000a7,0x00050051,0x00000006,0x0000052b,0x00000525,0x00000002,0x0003003e,0x0000052a, + 0x0000052b,0x0004003d,0x0000002f,0x0000040a,0x00000406,0x0003003e,0x00000401,0x0000040a, + 0x00050041,0x00000007,0x0000040c,0x00000401,0x000000be,0x0004003d,0x00000006,0x0000040d, + 0x0000040c,0x00050083,0x00000006,0x0000040e,0x000000c7,0x0000040d,0x0003003e,0x0000040b, + 0x0000040e,0x0004003d,0x00000006,0x0000040f,0x0000040b,0x000500b7,0x000000d6,0x00000410, + 0x0000040f,0x000000c8,0x000300f7,0x00000412,0x00000000,0x000400fa,0x00000410,0x00000411, + 0x00000412,0x000200f8,0x00000411,0x0004003d,0x0000030f,0x00000413,0x000003c8,0x00050062, + 0x0000002f,0x00000414,0x00000413,0x00000313,0x0004003d,0x00000006,0x00000415,0x0000040b, + 0x0005008e,0x0000002f,0x00000416,0x00000414,0x00000415,0x0004003d,0x0000002f,0x00000417, + 0x00000401,0x00050081,0x0000002f,0x00000418,0x00000417,0x00000416,0x0003003e,0x00000401, + 0x00000418,0x000200f9,0x00000412,0x000200f8,0x00000412,0x0004003d,0x0000002f,0x0000041b, + 0x00000401,0x0003003e,0x0000041a,0x0000041b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..cda0d5bce97559dcba34b69be3029a0fcbe8e957 GIT binary patch literal 48504 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%0AFH3((2V;N=^Xc`(%4uy7JA|OnB1Sq&RlSP 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 b0XDV|_k+^)*A`Qs*tJxm|J54VPRsuRZ)Gk~ literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.h new file mode 100644 index 000000000..86e392670 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.h @@ -0,0 +1,130 @@ +#pragma once + +const uint32_t atomic_resolve_coalesced_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000000ae,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000029,0x0000002c,0x00000068, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x00000029, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005,0x0000002c,0x495f6c67,0x6174736e, + 0x4965636e,0x7865646e,0x00000000,0x00030005,0x0000003b,0x0000424d,0x00040006,0x0000003b, + 0x00000000,0x00006250,0x00040006,0x0000003b,0x00000001,0x00006359,0x00040006,0x0000003b, + 0x00000002,0x00006552,0x00040006,0x0000003b,0x00000003,0x00006553,0x00040006,0x0000003b, + 0x00000004,0x0000366d,0x00040006,0x0000003b,0x00000005,0x0000676d,0x00040006,0x0000003b, + 0x00000006,0x00006544,0x00040006,0x0000003b,0x00000007,0x00006545,0x00040006,0x0000003b, + 0x00000008,0x00003755,0x00040006,0x0000003b,0x00000009,0x0000676a,0x00040006,0x0000003b, + 0x0000000a,0x0000635a,0x00040006,0x0000003b,0x0000000b,0x00003157,0x00040006,0x0000003b, + 0x0000000c,0x0000676e,0x00040006,0x0000003b,0x0000000d,0x00003559,0x00040006,0x0000003b, + 0x0000000e,0x0000324f,0x00040006,0x0000003b,0x0000000f,0x00006461,0x00040006,0x0000003b, + 0x00000010,0x00006579,0x00040006,0x0000003b,0x00000011,0x00003376,0x00040006,0x0000003b, + 0x00000012,0x00003377,0x00040006,0x0000003b,0x00000013,0x00006462,0x00040006,0x0000003b, + 0x00000014,0x00006767,0x00030005,0x0000003d,0x0000006b,0x00060005,0x00000066,0x505f6c67, + 0x65567265,0x78657472,0x00000000,0x00060006,0x00000066,0x00000000,0x505f6c67,0x7469736f, + 0x006e6f69,0x00070006,0x00000066,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000, + 0x00070006,0x00000066,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006, + 0x00000066,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000068, + 0x00000000,0x00030005,0x0000007a,0x00004342,0x00030005,0x0000007d,0x00004351,0x00030005, + 0x00000080,0x0000664a,0x00040006,0x00000080,0x00000000,0x00003464,0x00030005,0x00000082, + 0x0000424c,0x00030005,0x00000085,0x00006576,0x00040006,0x00000085,0x00000000,0x00003464, + 0x00030005,0x00000087,0x00004355,0x00030005,0x00000089,0x00006577,0x00040006,0x00000089, + 0x00000000,0x00003464,0x00030005,0x0000008b,0x0000424f,0x00030005,0x0000008d,0x0000664b, + 0x00040006,0x0000008d,0x00000000,0x00003464,0x00030005,0x0000008f,0x00004358,0x00030005, + 0x00000092,0x00003954,0x00040047,0x00000029,0x0000000b,0x0000002a,0x00040047,0x0000002c, + 0x0000000b,0x0000002b,0x00030047,0x0000003b,0x00000002,0x00050048,0x0000003b,0x00000000, + 0x00000023,0x00000000,0x00050048,0x0000003b,0x00000001,0x00000023,0x00000004,0x00050048, + 0x0000003b,0x00000002,0x00000023,0x00000008,0x00050048,0x0000003b,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x0000003b,0x00000004,0x00000023,0x00000010,0x00050048,0x0000003b, + 0x00000005,0x00000023,0x00000014,0x00050048,0x0000003b,0x00000006,0x00000023,0x00000018, + 0x00050048,0x0000003b,0x00000007,0x00000023,0x0000001c,0x00050048,0x0000003b,0x00000008, + 0x00000023,0x00000020,0x00050048,0x0000003b,0x00000009,0x00000023,0x00000030,0x00050048, + 0x0000003b,0x0000000a,0x00000023,0x00000038,0x00050048,0x0000003b,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x0000003b,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000003b, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x0000003b,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x0000003b,0x0000000f,0x00000023,0x00000050,0x00050048,0x0000003b,0x00000010, + 0x00000023,0x00000054,0x00050048,0x0000003b,0x00000011,0x00000023,0x00000058,0x00050048, + 0x0000003b,0x00000012,0x00000023,0x0000005c,0x00050048,0x0000003b,0x00000013,0x00000023, + 0x00000060,0x00050048,0x0000003b,0x00000014,0x00000023,0x00000064,0x00040047,0x0000003d, + 0x00000021,0x00000000,0x00040047,0x0000003d,0x00000022,0x00000000,0x00030047,0x00000066, + 0x00000002,0x00050048,0x00000066,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000066, + 0x00000001,0x0000000b,0x00000001,0x00050048,0x00000066,0x00000002,0x0000000b,0x00000003, + 0x00050048,0x00000066,0x00000003,0x0000000b,0x00000004,0x00040047,0x0000007a,0x00000021, + 0x00000008,0x00040047,0x0000007a,0x00000022,0x00000000,0x00030047,0x0000007d,0x00000000, + 0x00040047,0x0000007d,0x00000021,0x0000000a,0x00040047,0x0000007d,0x00000022,0x00000000, + 0x00040047,0x0000007f,0x00000006,0x00000010,0x00030047,0x00000080,0x00000003,0x00040048, + 0x00000080,0x00000000,0x00000018,0x00050048,0x00000080,0x00000000,0x00000023,0x00000000, + 0x00030047,0x00000082,0x00000018,0x00040047,0x00000082,0x00000021,0x00000003,0x00040047, + 0x00000082,0x00000022,0x00000000,0x00040047,0x00000084,0x00000006,0x00000008,0x00030047, + 0x00000085,0x00000003,0x00040048,0x00000085,0x00000000,0x00000018,0x00050048,0x00000085, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000087,0x00000018,0x00040047,0x00000087, + 0x00000021,0x00000004,0x00040047,0x00000087,0x00000022,0x00000000,0x00040047,0x00000088, + 0x00000006,0x00000010,0x00030047,0x00000089,0x00000003,0x00040048,0x00000089,0x00000000, + 0x00000018,0x00050048,0x00000089,0x00000000,0x00000023,0x00000000,0x00030047,0x0000008b, + 0x00000018,0x00040047,0x0000008b,0x00000021,0x00000005,0x00040047,0x0000008b,0x00000022, + 0x00000000,0x00040047,0x0000008c,0x00000006,0x00000010,0x00030047,0x0000008d,0x00000003, + 0x00040048,0x0000008d,0x00000000,0x00000018,0x00050048,0x0000008d,0x00000000,0x00000023, + 0x00000000,0x00030047,0x0000008f,0x00000018,0x00040047,0x0000008f,0x00000021,0x00000006, + 0x00040047,0x0000008f,0x00000022,0x00000000,0x00030047,0x00000092,0x00000000,0x00040047, + 0x00000092,0x00000021,0x0000000a,0x00040047,0x00000092,0x00000022,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000002,0x00040017,0x0000000a,0x00000006,0x00000004,0x00040015, + 0x00000011,0x00000020,0x00000000,0x0004002b,0x00000011,0x00000012,0x00000000,0x0004002b, + 0x00000006,0x00000017,0x3f800000,0x0004002b,0x00000011,0x00000019,0x00000001,0x0004002b, + 0x00000006,0x00000021,0x00000000,0x00040015,0x00000025,0x00000020,0x00000001,0x00040020, + 0x00000028,0x00000001,0x00000025,0x0004003b,0x00000028,0x00000029,0x00000001,0x0004003b, + 0x00000028,0x0000002c,0x00000001,0x00040017,0x0000002e,0x00000025,0x00000002,0x0004002b, + 0x00000025,0x00000032,0x00000001,0x0004002b,0x00000025,0x00000034,0x00000000,0x00020014, + 0x00000035,0x00040017,0x0000003a,0x00000025,0x00000004,0x0017001e,0x0000003b,0x00000006, + 0x00000006,0x00000006,0x00000006,0x00000011,0x00000011,0x00000011,0x00000011,0x0000003a, + 0x00000007,0x00000007,0x00000011,0x00000006,0x00000011,0x00000006,0x00000006,0x00000011, + 0x00000006,0x00000006,0x00000006,0x00000011,0x00040020,0x0000003c,0x00000002,0x0000003b, + 0x0004003b,0x0000003c,0x0000003d,0x00000002,0x0004002b,0x00000025,0x0000003e,0x00000008, + 0x00040020,0x0000003f,0x00000002,0x00000025,0x0004002b,0x00000011,0x00000043,0x00000002, + 0x0004002b,0x00000025,0x00000049,0x00000002,0x0004002b,0x00000011,0x00000052,0x00000003, + 0x0004002b,0x00000025,0x0000005b,0x00000003,0x00040020,0x0000005e,0x00000002,0x00000006, + 0x0004001c,0x00000065,0x00000006,0x00000019,0x0006001e,0x00000066,0x0000000a,0x00000006, + 0x00000065,0x00000065,0x00040020,0x00000067,0x00000003,0x00000066,0x0004003b,0x00000067, + 0x00000068,0x00000003,0x00040020,0x0000006a,0x00000003,0x0000000a,0x00090019,0x00000078, + 0x00000011,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x00000079,0x00000000,0x00000078,0x0004003b,0x00000079,0x0000007a,0x00000000,0x00090019, + 0x0000007b,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x0000007c,0x00000000,0x0000007b,0x0004003b,0x0000007c,0x0000007d,0x00000000, + 0x00040017,0x0000007e,0x00000011,0x00000004,0x0003001d,0x0000007f,0x0000007e,0x0003001e, + 0x00000080,0x0000007f,0x00040020,0x00000081,0x00000002,0x00000080,0x0004003b,0x00000081, + 0x00000082,0x00000002,0x00040017,0x00000083,0x00000011,0x00000002,0x0003001d,0x00000084, + 0x00000083,0x0003001e,0x00000085,0x00000084,0x00040020,0x00000086,0x00000002,0x00000085, + 0x0004003b,0x00000086,0x00000087,0x00000002,0x0003001d,0x00000088,0x0000000a,0x0003001e, + 0x00000089,0x00000088,0x00040020,0x0000008a,0x00000002,0x00000089,0x0004003b,0x0000008a, + 0x0000008b,0x00000002,0x0003001d,0x0000008c,0x0000007e,0x0003001e,0x0000008d,0x0000008c, + 0x00040020,0x0000008e,0x00000002,0x0000008d,0x0004003b,0x0000008e,0x0000008f,0x00000002, + 0x0002001a,0x00000090,0x00040020,0x00000091,0x00000000,0x00000090,0x0004003b,0x00000091, + 0x00000092,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000025,0x0000002a,0x00000029,0x000500c7,0x00000025,0x00000033, + 0x0000002a,0x00000032,0x000500aa,0x00000035,0x00000036,0x00000033,0x00000034,0x000300f7, + 0x00000039,0x00000000,0x000400fa,0x00000036,0x00000038,0x00000042,0x000200f8,0x00000038, + 0x00060041,0x0000003f,0x00000040,0x0000003d,0x0000003e,0x00000012,0x0004003d,0x00000025, + 0x00000041,0x00000040,0x000200f9,0x00000039,0x000200f8,0x00000042,0x00060041,0x0000003f, + 0x00000044,0x0000003d,0x0000003e,0x00000043,0x0004003d,0x00000025,0x00000045,0x00000044, + 0x000200f9,0x00000039,0x000200f8,0x00000039,0x000700f5,0x00000025,0x000000a8,0x00000041, + 0x00000038,0x00000045,0x00000042,0x000500c7,0x00000025,0x0000004a,0x0000002a,0x00000049, + 0x000500aa,0x00000035,0x0000004b,0x0000004a,0x00000034,0x000300f7,0x0000004e,0x00000000, + 0x000400fa,0x0000004b,0x0000004d,0x00000051,0x000200f8,0x0000004d,0x00060041,0x0000003f, + 0x0000004f,0x0000003d,0x0000003e,0x00000019,0x0004003d,0x00000025,0x00000050,0x0000004f, + 0x000200f9,0x0000004e,0x000200f8,0x00000051,0x00060041,0x0000003f,0x00000053,0x0000003d, + 0x0000003e,0x00000052,0x0004003d,0x00000025,0x00000054,0x00000053,0x000200f9,0x0000004e, + 0x000200f8,0x0000004e,0x000700f5,0x00000025,0x000000ab,0x00000050,0x0000004d,0x00000054, + 0x00000051,0x00050050,0x0000002e,0x000000ad,0x000000a8,0x000000ab,0x0004006f,0x00000007, + 0x0000005a,0x000000ad,0x00050041,0x0000005e,0x0000005f,0x0000003d,0x00000049,0x0004003d, + 0x00000006,0x00000060,0x0000005f,0x00050041,0x0000005e,0x00000062,0x0000003d,0x0000005b, + 0x0004003d,0x00000006,0x00000063,0x00000062,0x00050051,0x00000006,0x00000096,0x0000005a, + 0x00000000,0x00050085,0x00000006,0x00000098,0x00000096,0x00000060,0x00050083,0x00000006, + 0x00000099,0x00000098,0x00000017,0x00050051,0x00000006,0x0000009b,0x0000005a,0x00000001, + 0x00050085,0x00000006,0x0000009d,0x0000009b,0x00000063,0x0006000c,0x00000006,0x0000009f, + 0x00000001,0x00000006,0x00000063,0x00050083,0x00000006,0x000000a0,0x0000009d,0x0000009f, + 0x00070050,0x0000000a,0x000000a1,0x00000099,0x000000a0,0x00000021,0x00000017,0x00050041, + 0x0000006a,0x0000006b,0x00000068,0x00000034,0x0003003e,0x0000006b,0x000000a1,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/atomic_resolve_coalesced.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..91004774d6bf2aade6bae4dd7dc3a08526e35745 GIT binary patch literal 4004 zcmZ9O>u*#=7{*V#T?#FNToh}tDH0O7q)`McBBj@q!eXyzLBr{G_q5%z-8Q>hXz^AH z6%p?rjK&!8o6+dM;TQiM<0Uci`JFRw&%_~b=Y5`eZ!>e=VKa?~n}eVsXbrXpzXr+J z6Eunm#BGb`q1;5SvsN#5o;v+J7Q2E>Y>3Tn`7xR#i}_Lo{ix)GWL}cdzedf!%eX0M z35IfE?|5HWo6i@cYFMi;Rr7OEII}W4E4VbX5EbgOYsGGGYBH?l7njRXwH(!IVLe){ zuT-OOcBN9NmzF9ug|(PNBO^n(!LYErte9)%C@hyMQCKWh6|ZzF!frb;on5I?D6bTK zgRCt4J!G|a_AyruUyG_rJzOb9t3i+rn&Z8RAFkBu`AQ*jE39RLbMm>;7s$IQ)~RuH zCdHiDwL*$Hn{m}=_MGg5hvS;gr0ZF&FV3ZSoA7{VugeSuJS+~z{e{$ir*Orye@yt=>2!UU@W{y&?-tG%Q~bE_npe*r;ae}J>wAT7dw8GljOV{! zcux5_+w;!x6r1qqtS!|_d?#X?V|&g%=1Z0OMCp#I!Y5hd9<(Vc&Snd~{Q9PB{ZAj1cCHkgx zzEkYb8D@81`c)V2f%MzX4xM3k52cT|c%MkW?DC>B%tJ^ zBw%_Nd_2a23OC?!^aI>QkE18xavn!tz>Rtw z`-GeHIQj!_%H!w}xHmnHK7pI|IL-*JDB=F-mqQYU;b#*loQZqF?vs9Eux|!u1IK;B zF&l>uT*l+j;kZL`(GTS24h;Lb=@ABN=-6@(hEv<7;63r&Ip;;)>zb3?X;0a=z#4;d zU|_$YnRQ~LlM8>tey)4s$(7WdiF?s zmtjBGL)lv{baK%z>5w}BfK>qYK7&|a=z?|t5`b)obNEpW*re7FfY!Ad}{erEx z2{(A_)W;y+5zQSE);olsb2|JvhmShW@Ck>huTwg<)Js0}lM>L#U9aoOhWJdCKjxpjWI`m{UnZF(of}>r^o)({?2M<{G%AGbxHap#76Jc z?ecy1Na%rX$=+B`a`sB^k^C)tV&R9s`3*=nzy4TH{0617=KJCQhq{&8f0PiL8n7j% z?dy_s_DWCLzAj6Lw|%`Tox#3XyCNBrP#?P0HzM8YYm4=yzESC{Q6I7J!{7WSq?;eT zYk|*8zkoYopgBe>{JGF yd@sQU9o}L-l8!y=quOPQ<{u>FdL%g{As_o$(0o%eFX3*x_058@|5wqwB>w@!-a$bC literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.h new file mode 100644 index 000000000..a7c7e84f3 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.h @@ -0,0 +1,64 @@ +#pragma once + +const uint32_t blit_texture_as_draw_filtered_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000023,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000016,0x0000001b,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x0000000c,0x0000425a,0x00030005,0x00000010,0x0000654f,0x00030005,0x00000016, + 0x00003055,0x00030005,0x0000001b,0x00006771,0x00030005,0x00000020,0x0000424d,0x00040006, + 0x00000020,0x00000000,0x00006250,0x00040006,0x00000020,0x00000001,0x00006359,0x00040006, + 0x00000020,0x00000002,0x00006552,0x00040006,0x00000020,0x00000003,0x00006553,0x00040006, + 0x00000020,0x00000004,0x0000366d,0x00040006,0x00000020,0x00000005,0x0000676d,0x00040006, + 0x00000020,0x00000006,0x00006544,0x00040006,0x00000020,0x00000007,0x00006545,0x00040006, + 0x00000020,0x00000008,0x00003755,0x00040006,0x00000020,0x00000009,0x0000676a,0x00040006, + 0x00000020,0x0000000a,0x0000635a,0x00040006,0x00000020,0x0000000b,0x00003157,0x00040006, + 0x00000020,0x0000000c,0x0000676e,0x00040006,0x00000020,0x0000000d,0x00003559,0x00040006, + 0x00000020,0x0000000e,0x0000324f,0x00040006,0x00000020,0x0000000f,0x00006461,0x00040006, + 0x00000020,0x00000010,0x00006579,0x00040006,0x00000020,0x00000011,0x00003376,0x00040006, + 0x00000020,0x00000012,0x00003377,0x00040006,0x00000020,0x00000013,0x00006462,0x00040006, + 0x00000020,0x00000014,0x00006767,0x00030005,0x00000022,0x0000006b,0x00030047,0x0000000c, + 0x00000000,0x00040047,0x0000000c,0x00000021,0x0000000c,0x00040047,0x0000000c,0x00000022, + 0x00000001,0x00030047,0x0000000d,0x00000000,0x00030047,0x00000010,0x00000000,0x00040047, + 0x00000010,0x00000021,0x0000000c,0x00040047,0x00000010,0x00000022,0x00000001,0x00030047, + 0x00000011,0x00000000,0x00040047,0x00000016,0x0000001e,0x00000000,0x00030047,0x00000019, + 0x00000000,0x00030047,0x0000001b,0x00000000,0x00040047,0x0000001b,0x0000001e,0x00000000, + 0x00030047,0x00000020,0x00000002,0x00050048,0x00000020,0x00000000,0x00000023,0x00000000, + 0x00050048,0x00000020,0x00000001,0x00000023,0x00000004,0x00050048,0x00000020,0x00000002, + 0x00000023,0x00000008,0x00050048,0x00000020,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x00000020,0x00000004,0x00000023,0x00000010,0x00050048,0x00000020,0x00000005,0x00000023, + 0x00000014,0x00050048,0x00000020,0x00000006,0x00000023,0x00000018,0x00050048,0x00000020, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x00000020,0x00000008,0x00000023,0x00000020, + 0x00050048,0x00000020,0x00000009,0x00000023,0x00000030,0x00050048,0x00000020,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x00000020,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x00000020,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000020,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x00000020,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000020, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x00000020,0x00000010,0x00000023,0x00000054, + 0x00050048,0x00000020,0x00000011,0x00000023,0x00000058,0x00050048,0x00000020,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x00000020,0x00000013,0x00000023,0x00000060,0x00050048, + 0x00000020,0x00000014,0x00000023,0x00000064,0x00040047,0x00000022,0x00000021,0x00000000, + 0x00040047,0x00000022,0x00000022,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004, + 0x00090019,0x0000000a,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x0000000b,0x00000000,0x0000000a,0x0004003b,0x0000000b,0x0000000c, + 0x00000000,0x0002001a,0x0000000e,0x00040020,0x0000000f,0x00000000,0x0000000e,0x0004003b, + 0x0000000f,0x00000010,0x00000000,0x0003001b,0x00000012,0x0000000a,0x00040017,0x00000014, + 0x00000006,0x00000002,0x00040020,0x00000015,0x00000001,0x00000014,0x0004003b,0x00000015, + 0x00000016,0x00000001,0x0004002b,0x00000006,0x00000018,0x00000000,0x00040020,0x0000001a, + 0x00000003,0x00000007,0x0004003b,0x0000001a,0x0000001b,0x00000003,0x00040015,0x0000001d, + 0x00000020,0x00000000,0x00040015,0x0000001e,0x00000020,0x00000001,0x00040017,0x0000001f, + 0x0000001e,0x00000004,0x0017001e,0x00000020,0x00000006,0x00000006,0x00000006,0x00000006, + 0x0000001d,0x0000001d,0x0000001d,0x0000001d,0x0000001f,0x00000014,0x00000014,0x0000001d, + 0x00000006,0x0000001d,0x00000006,0x00000006,0x0000001d,0x00000006,0x00000006,0x00000006, + 0x0000001d,0x00040020,0x00000021,0x00000002,0x00000020,0x0004003b,0x00000021,0x00000022, + 0x00000002,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003d,0x0000000a,0x0000000d,0x0000000c,0x0004003d,0x0000000e,0x00000011,0x00000010, + 0x00050056,0x00000012,0x00000013,0x0000000d,0x00000011,0x0004003d,0x00000014,0x00000017, + 0x00000016,0x00070058,0x00000007,0x00000019,0x00000013,0x00000017,0x00000002,0x00000018, + 0x0003003e,0x0000001b,0x00000019,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ef0032f1483b379fa640dd4012826036e55c489a GIT binary patch literal 1908 zcmZ9M>rWFw6vanMp@8xb0RhDYKAI4GfFwqvgrf9YS;R=DsRNy=ElpdO%#(Z z*B7Fha-(ioGvl%rMtqppSk{=94qgW+%V}5VereIL8+WC$|Nd~-kH6NMLC24~SDo5< z;MaStmf%(WB4~7_n?P5r9{X|a^12;#+Cd!q-QZ`p*9rVqFKTqdt0>mC>7J!ZrBp8Z zjq7XedD{;Bb{GYIGwf);@FqZ4V9$Xrj2i7;(+cuZ*t_Ia_g(FOw(A`EwDOAfA?Kba za)g}wem_rgPx%MwN3;_;aZt}NzMVEQj4y}UGu7knk-`0XwzKbfeZSOMseVLw&*<^H zXmCOJAM z_Wi!_4})ig>t_7};d7mj&uhxRX_S;x7g3VW!_7L z%X_c%QL@jX$$5VQ9l6zc!o2amZa_|~C(}QUI^lThRL2@P-Y?~H1CD#99Ba@~d&Ln0+!w>)5u94C|9-qbJwfoEUi;c<-^d%W_(ebBHyCf} rCw%=V6`s;JXyDOM-+~7IRpk&K@qd60p7ZeXtxm%;zWtFiI~sohj^}vY literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.h new file mode 100644 index 000000000..2787bbef5 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.h @@ -0,0 +1,78 @@ +#pragma once + +const uint32_t blit_texture_as_draw_filtered_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000047,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000a,0x00000026,0x0000003f, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000a, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x00000026,0x00003055,0x00060005, + 0x0000003d,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000003d,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x0000003d,0x00000001,0x505f6c67,0x746e696f, + 0x657a6953,0x00000000,0x00070006,0x0000003d,0x00000002,0x435f6c67,0x4470696c,0x61747369, + 0x0065636e,0x00070006,0x0000003d,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e, + 0x00030005,0x0000003f,0x00000000,0x00030005,0x00000044,0x0000424d,0x00040006,0x00000044, + 0x00000000,0x00006250,0x00040006,0x00000044,0x00000001,0x00006359,0x00040006,0x00000044, + 0x00000002,0x00006552,0x00040006,0x00000044,0x00000003,0x00006553,0x00040006,0x00000044, + 0x00000004,0x0000366d,0x00040006,0x00000044,0x00000005,0x0000676d,0x00040006,0x00000044, + 0x00000006,0x00006544,0x00040006,0x00000044,0x00000007,0x00006545,0x00040006,0x00000044, + 0x00000008,0x00003755,0x00040006,0x00000044,0x00000009,0x0000676a,0x00040006,0x00000044, + 0x0000000a,0x0000635a,0x00040006,0x00000044,0x0000000b,0x00003157,0x00040006,0x00000044, + 0x0000000c,0x0000676e,0x00040006,0x00000044,0x0000000d,0x00003559,0x00040006,0x00000044, + 0x0000000e,0x0000324f,0x00040006,0x00000044,0x0000000f,0x00006461,0x00040006,0x00000044, + 0x00000010,0x00006579,0x00040006,0x00000044,0x00000011,0x00003376,0x00040006,0x00000044, + 0x00000012,0x00003377,0x00040006,0x00000044,0x00000013,0x00006462,0x00040006,0x00000044, + 0x00000014,0x00006767,0x00030005,0x00000046,0x0000006b,0x00040047,0x0000000a,0x0000000b, + 0x0000002a,0x00040047,0x00000026,0x0000001e,0x00000000,0x00030047,0x0000003d,0x00000002, + 0x00050048,0x0000003d,0x00000000,0x0000000b,0x00000000,0x00050048,0x0000003d,0x00000001, + 0x0000000b,0x00000001,0x00050048,0x0000003d,0x00000002,0x0000000b,0x00000003,0x00050048, + 0x0000003d,0x00000003,0x0000000b,0x00000004,0x00030047,0x00000044,0x00000002,0x00050048, + 0x00000044,0x00000000,0x00000023,0x00000000,0x00050048,0x00000044,0x00000001,0x00000023, + 0x00000004,0x00050048,0x00000044,0x00000002,0x00000023,0x00000008,0x00050048,0x00000044, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x00000044,0x00000004,0x00000023,0x00000010, + 0x00050048,0x00000044,0x00000005,0x00000023,0x00000014,0x00050048,0x00000044,0x00000006, + 0x00000023,0x00000018,0x00050048,0x00000044,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x00000044,0x00000008,0x00000023,0x00000020,0x00050048,0x00000044,0x00000009,0x00000023, + 0x00000030,0x00050048,0x00000044,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000044, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x00000044,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x00000044,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000044,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x00000044,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x00000044,0x00000010,0x00000023,0x00000054,0x00050048,0x00000044,0x00000011,0x00000023, + 0x00000058,0x00050048,0x00000044,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000044, + 0x00000013,0x00000023,0x00000060,0x00050048,0x00000044,0x00000014,0x00000023,0x00000064, + 0x00040047,0x00000046,0x00000021,0x00000000,0x00040047,0x00000046,0x00000022,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020, + 0x00000001,0x00040020,0x00000009,0x00000001,0x00000006,0x0004003b,0x00000009,0x0000000a, + 0x00000001,0x0004002b,0x00000006,0x0000000d,0x00000000,0x00030016,0x0000000e,0x00000020, + 0x00040017,0x0000000f,0x0000000e,0x00000002,0x0004002b,0x00000006,0x00000013,0x00000001, + 0x00020014,0x00000015,0x0004002b,0x0000000e,0x00000017,0xbf800000,0x0004002b,0x0000000e, + 0x00000018,0x3f800000,0x00040015,0x0000001a,0x00000020,0x00000000,0x0004002b,0x0000001a, + 0x0000001b,0x00000000,0x0004002b,0x00000006,0x0000001f,0x00000002,0x0004002b,0x0000001a, + 0x00000023,0x00000001,0x00040020,0x00000025,0x00000003,0x0000000f,0x0004003b,0x00000025, + 0x00000026,0x00000003,0x0004002b,0x0000000e,0x00000029,0x3f000000,0x00040020,0x0000002c, + 0x00000003,0x0000000e,0x0004002b,0x0000000e,0x00000030,0xbf000000,0x00040017,0x00000034, + 0x0000000e,0x00000004,0x0004002b,0x0000000e,0x00000038,0x00000000,0x0004001c,0x0000003c, + 0x0000000e,0x00000023,0x0006001e,0x0000003d,0x00000034,0x0000000e,0x0000003c,0x0000003c, + 0x00040020,0x0000003e,0x00000003,0x0000003d,0x0004003b,0x0000003e,0x0000003f,0x00000003, + 0x00040020,0x00000041,0x00000003,0x00000034,0x00040017,0x00000043,0x00000006,0x00000004, + 0x0017001e,0x00000044,0x0000000e,0x0000000e,0x0000000e,0x0000000e,0x0000001a,0x0000001a, + 0x0000001a,0x0000001a,0x00000043,0x0000000f,0x0000000f,0x0000001a,0x0000000e,0x0000001a, + 0x0000000e,0x0000000e,0x0000001a,0x0000000e,0x0000000e,0x0000000e,0x0000001a,0x00040020, + 0x00000045,0x00000002,0x00000044,0x0004003b,0x00000045,0x00000046,0x00000002,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000006, + 0x0000000b,0x0000000a,0x000500c7,0x00000006,0x00000014,0x0000000b,0x00000013,0x000500aa, + 0x00000015,0x00000016,0x00000014,0x0000000d,0x000600a9,0x0000000e,0x00000019,0x00000016, + 0x00000017,0x00000018,0x000500c7,0x00000006,0x00000020,0x0000000b,0x0000001f,0x000500aa, + 0x00000015,0x00000021,0x00000020,0x0000000d,0x000600a9,0x0000000e,0x00000022,0x00000021, + 0x00000017,0x00000018,0x00050085,0x0000000e,0x0000002a,0x00000019,0x00000029,0x00050081, + 0x0000000e,0x0000002b,0x0000002a,0x00000029,0x00050041,0x0000002c,0x0000002d,0x00000026, + 0x0000001b,0x0003003e,0x0000002d,0x0000002b,0x00050085,0x0000000e,0x00000031,0x00000022, + 0x00000030,0x00050081,0x0000000e,0x00000032,0x00000031,0x00000029,0x00050041,0x0000002c, + 0x00000033,0x00000026,0x00000023,0x0003003e,0x00000033,0x00000032,0x00070050,0x00000034, + 0x0000003b,0x00000019,0x00000022,0x00000038,0x00000018,0x00050041,0x00000041,0x00000042, + 0x0000003f,0x0000000d,0x0003003e,0x00000042,0x0000003b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..c42e1e06457f8ab9fb4528338683c910deadb9d0 GIT binary patch literal 2364 zcmZ9N*-jKe6ow0i!370T7PsIak;ILtD4HlB>tHg53Ao3k9cG%bv1!P3kK2`A_%Qks zUV7sLd1K=LO?S~1i=0&b|5@ssQ)lQx_rxJ%x=f!rY|18GgQi=I5!c(<%azT_RGc)X zZr{0qMZYO@46zxIAFD^QTMHu2M(uI=uJek=6j*h~D6NxS8H+wG{H1bb1eur_9SeZ5>+ z@#_2giuoz@y)cM;uMxBqFL>``r}`>hW*0>Du-$MCin4HPD5`eqXolW1zon}mMGgO> zF-6rwZBNw+Y-UrNs^3b@1jVL2XZct6;(&a`9_rZBw+35qs?iF5k>@`eg#lcL+)4RF-5#b%jpB}$*^63+Pelxc}CLB5T$Aw?s$@Trh>$h?| zAY5zY_=NB$C!ay#_tUxlr0@p^pAz13{D*{_x}V;z>ikYpR&U9hT(4x9nHZC>%CcoH z=Lrq+7=aj+k)x5Xbt!@g|ldHXMDn z96oUL&T_mv9R08yZx46c;dpbj$GlW$@(%E zaBB|7Y`|3I%tu1-uJ0x~E zQn-1p$DJqpgiscVS5jH`oKNZa7jBgk`Fb2Co|68cUf3# z9{X!LU{4-a&%9{;q^{dKpkrRGp4nlY7yCdvdU6<3=lC63A9M)!%xUKy^yCFjzg?+* zA=Bf_y-V782kspc!yIytE7a}^KGcoCV{7;S&lZ#0itOkocaR%+HRERVyGBPIENb{8 zrl@^ZEIIP~VNQOD1v8s)y#Ehzy#0s-p85GMEABrdfoC3=0qbAV8Gqi{`j6{elDPgC zh2gFLH{C^C{$CQCcmA4jS2G@NK^*UXT{0s<7mWR1(rWFw6vf9D%1e2OfPmrxA5928KoX--0x2JAN_c1?CTkxH7TZ$0Ez1AsALJJk z&#&8YZ@kH5?m2sA=FXYhW;5#}&fRenZq%*2BxYPjj1!mZ&-ub}VI%I=HePORqL_5q zz7Wln8*xLL8O?IN#fN!~WsPa+;B|nqtaf$omlh4VahETI?~iuF_-nZqb;7uN-6>y2 zVWoF*A$VQ6imF}dCeZDdPQtj{Y&W7#BZ}j&8~yC|I#GDhYgN1T>sG97{hs+^F<;mZ ztL?V-ylq5bquz?bTD_zF>NgR(QT80@>aA*{SF?g)DePT_Rrg)(f4=J+`Lyz)_95q< zr*edx`+mPn@<90q>2unNoH(qc7~jsSDaMy0?dkQndu(vOp6&Geu)a5Sme=Qm_lzFD z_YEEuK7Ezy$AquU`f=fNQ_qC(r)R02`?rk#p77aL`h8Nk_&mi^!sS|u@$A;rGb4QS zBK>|}_=mx>!WFarf$*iy$LBTW-!$^dsf)H$Kn}$cgo2`o~cx9B=J)tbybGJeM7C+|zTcLC0M@ zM~}eao#*HixQB+LSKuBQj`QFG!_hNvn}(xr;C2j0@4&q?9JRvj8IJdWJ1`t?09P;^ zy##k?IPM8|VmRIju4Fj+3huMv=qUoC7psd=#B6gJ(F6&YXfduzdOEB2SNS6#qb+>BNo5tNBjok sE&YVAAEm-m`UVX=8tPlnz`v3l!Xy3<(7|&aUcS|7c*eIsa%M;4FPFb~-v9sr literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.h new file mode 100644 index 000000000..6d01adb7e --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.h @@ -0,0 +1,78 @@ +#pragma once + +const uint32_t blit_texture_as_draw_filtered_webgpu_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000047,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000a,0x00000026,0x0000003f, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000a, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x00000026,0x00003055,0x00060005, + 0x0000003d,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000003d,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x0000003d,0x00000001,0x505f6c67,0x746e696f, + 0x657a6953,0x00000000,0x00070006,0x0000003d,0x00000002,0x435f6c67,0x4470696c,0x61747369, + 0x0065636e,0x00070006,0x0000003d,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e, + 0x00030005,0x0000003f,0x00000000,0x00030005,0x00000044,0x0000424d,0x00040006,0x00000044, + 0x00000000,0x00006250,0x00040006,0x00000044,0x00000001,0x00006359,0x00040006,0x00000044, + 0x00000002,0x00006552,0x00040006,0x00000044,0x00000003,0x00006553,0x00040006,0x00000044, + 0x00000004,0x0000366d,0x00040006,0x00000044,0x00000005,0x0000676d,0x00040006,0x00000044, + 0x00000006,0x00006544,0x00040006,0x00000044,0x00000007,0x00006545,0x00040006,0x00000044, + 0x00000008,0x00003755,0x00040006,0x00000044,0x00000009,0x0000676a,0x00040006,0x00000044, + 0x0000000a,0x0000635a,0x00040006,0x00000044,0x0000000b,0x00003157,0x00040006,0x00000044, + 0x0000000c,0x0000676e,0x00040006,0x00000044,0x0000000d,0x00003559,0x00040006,0x00000044, + 0x0000000e,0x0000324f,0x00040006,0x00000044,0x0000000f,0x00006461,0x00040006,0x00000044, + 0x00000010,0x00006579,0x00040006,0x00000044,0x00000011,0x00003376,0x00040006,0x00000044, + 0x00000012,0x00003377,0x00040006,0x00000044,0x00000013,0x00006462,0x00040006,0x00000044, + 0x00000014,0x00006767,0x00030005,0x00000046,0x0000006b,0x00040047,0x0000000a,0x0000000b, + 0x0000002a,0x00040047,0x00000026,0x0000001e,0x00000000,0x00030047,0x0000003d,0x00000002, + 0x00050048,0x0000003d,0x00000000,0x0000000b,0x00000000,0x00050048,0x0000003d,0x00000001, + 0x0000000b,0x00000001,0x00050048,0x0000003d,0x00000002,0x0000000b,0x00000003,0x00050048, + 0x0000003d,0x00000003,0x0000000b,0x00000004,0x00030047,0x00000044,0x00000002,0x00050048, + 0x00000044,0x00000000,0x00000023,0x00000000,0x00050048,0x00000044,0x00000001,0x00000023, + 0x00000004,0x00050048,0x00000044,0x00000002,0x00000023,0x00000008,0x00050048,0x00000044, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x00000044,0x00000004,0x00000023,0x00000010, + 0x00050048,0x00000044,0x00000005,0x00000023,0x00000014,0x00050048,0x00000044,0x00000006, + 0x00000023,0x00000018,0x00050048,0x00000044,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x00000044,0x00000008,0x00000023,0x00000020,0x00050048,0x00000044,0x00000009,0x00000023, + 0x00000030,0x00050048,0x00000044,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000044, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x00000044,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x00000044,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000044,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x00000044,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x00000044,0x00000010,0x00000023,0x00000054,0x00050048,0x00000044,0x00000011,0x00000023, + 0x00000058,0x00050048,0x00000044,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000044, + 0x00000013,0x00000023,0x00000060,0x00050048,0x00000044,0x00000014,0x00000023,0x00000064, + 0x00040047,0x00000046,0x00000021,0x00000000,0x00040047,0x00000046,0x00000022,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020, + 0x00000001,0x00040020,0x00000009,0x00000001,0x00000006,0x0004003b,0x00000009,0x0000000a, + 0x00000001,0x0004002b,0x00000006,0x0000000d,0x00000000,0x00030016,0x0000000e,0x00000020, + 0x00040017,0x0000000f,0x0000000e,0x00000002,0x0004002b,0x00000006,0x00000013,0x00000001, + 0x00020014,0x00000015,0x0004002b,0x0000000e,0x00000017,0xbf800000,0x0004002b,0x0000000e, + 0x00000018,0x3f800000,0x00040015,0x0000001a,0x00000020,0x00000000,0x0004002b,0x0000001a, + 0x0000001b,0x00000000,0x0004002b,0x00000006,0x0000001f,0x00000002,0x0004002b,0x0000001a, + 0x00000023,0x00000001,0x00040020,0x00000025,0x00000003,0x0000000f,0x0004003b,0x00000025, + 0x00000026,0x00000003,0x0004002b,0x0000000e,0x00000029,0x3f000000,0x00040020,0x0000002c, + 0x00000003,0x0000000e,0x0004002b,0x0000000e,0x00000030,0xbf000000,0x00040017,0x00000034, + 0x0000000e,0x00000004,0x0004002b,0x0000000e,0x00000038,0x00000000,0x0004001c,0x0000003c, + 0x0000000e,0x00000023,0x0006001e,0x0000003d,0x00000034,0x0000000e,0x0000003c,0x0000003c, + 0x00040020,0x0000003e,0x00000003,0x0000003d,0x0004003b,0x0000003e,0x0000003f,0x00000003, + 0x00040020,0x00000041,0x00000003,0x00000034,0x00040017,0x00000043,0x00000006,0x00000004, + 0x0017001e,0x00000044,0x0000000e,0x0000000e,0x0000000e,0x0000000e,0x0000001a,0x0000001a, + 0x0000001a,0x0000001a,0x00000043,0x0000000f,0x0000000f,0x0000001a,0x0000000e,0x0000001a, + 0x0000000e,0x0000000e,0x0000001a,0x0000000e,0x0000000e,0x0000000e,0x0000001a,0x00040020, + 0x00000045,0x00000002,0x00000044,0x0004003b,0x00000045,0x00000046,0x00000002,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000006, + 0x0000000b,0x0000000a,0x000500c7,0x00000006,0x00000014,0x0000000b,0x00000013,0x000500aa, + 0x00000015,0x00000016,0x00000014,0x0000000d,0x000600a9,0x0000000e,0x00000019,0x00000016, + 0x00000017,0x00000018,0x000500c7,0x00000006,0x00000020,0x0000000b,0x0000001f,0x000500aa, + 0x00000015,0x00000021,0x00000020,0x0000000d,0x000600a9,0x0000000e,0x00000022,0x00000021, + 0x00000017,0x00000018,0x00050085,0x0000000e,0x0000002a,0x00000019,0x00000029,0x00050081, + 0x0000000e,0x0000002b,0x0000002a,0x00000029,0x00050041,0x0000002c,0x0000002d,0x00000026, + 0x0000001b,0x0003003e,0x0000002d,0x0000002b,0x00050085,0x0000000e,0x00000031,0x00000022, + 0x00000030,0x00050081,0x0000000e,0x00000032,0x00000031,0x00000029,0x00050041,0x0000002c, + 0x00000033,0x00000026,0x00000023,0x0003003e,0x00000033,0x00000032,0x00070050,0x00000034, + 0x0000003b,0x00000019,0x00000022,0x00000038,0x00000018,0x00050041,0x00000041,0x00000042, + 0x0000003f,0x0000000d,0x0003003e,0x00000042,0x0000003b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..c42e1e06457f8ab9fb4528338683c910deadb9d0 GIT binary patch literal 2364 zcmZ9N*-jKe6ow0i!370T7PsIak;ILtD4HlB>tHg53Ao3k9cG%bv1!P3kK2`A_%Qks zUV7sLd1K=LO?S~1i=0&b|5@ssQ)lQx_rxJ%x=f!rY|18GgQi=I5!c(<%azT_RGc)X zZr{0qMZYO@46zxIAFD^QTMHu2M(uI=uJek=6j*h~D6NxS8H+wG{H1bb1eur_9SeZ5>+ z@#_2giuoz@y)cM;uMxBqFL>``r}`>hW*0>Du-$MCin4HPD5`eqXolW1zon}mMGgO> zF-6rwZBNw+Y-UrNs^3b@1jVL2XZct6;(&a`9_rZBw+35qs?iF5k>@`eg#lcL+)4RF-5#b%jpB}$*^63+Pelxc}CLB5T$Aw?s$@Trh>$h?| zAY5zY_=NB$C!ay#_tUxlr0@p^pAz13{D*{_x}V;z>ikYpR&U9hT(4x9nHZC>%CcoH z=Lrq+7=aj+k)x5Xbt!@g|ldHXMDn z96oUL&T_mv9R08yZx46c;dpbj$GlW$@(%E zaBB|7Y`|3I%tu1-uJ0x~E zQn-1p$DJqpgiscVS5jH`oKNZa7jBgk`Fb2Co|68cUf3# z9{X!LU{4-a&%9{;q^{dKpkrRGp4nlY7yCdvdU6<3=lC63A9M)!%xUKy^yCFjzg?+* zA=Bf_y-V782kspc!yIytE7a}^KGcoCV{7;S&lZ#0itOkocaR%+HRERVyGBPIENb{8 zrl@^ZEIIP~VNQOD1v8s)y#Ehzy#0s-p85GMEABrdfoC3=0qbAV8Gqi{`j6{elDPgC zh2gFLH{C^C{$CQCcmA4jS2G@NK^*UXT{0s<7mWR1(vx1C#l_Ip3Z$bLLE1YmYXZyXJbX>n`2OZo4(DILG{0bI+{@p7cNVcdL51 zySM)ox*odI&!5sNn=U54ocO9rYyZ7omOdRVXL()BXO+TQ%;fAW z>7S1f}a$Lr+y4ult3nN2mr zUtZydSNN;{cq`Op`fT;>o5+_md9>sb#U9=qwnZE z@O`0m&D&wLLyysCtZnMd-3D`)+v0aM<7fSz_-0twkL*dqAFSv<{!pCyo1Yqz+xU(! z`yu}G1{43N;oKp9^z3U-12euK*w1&S=bq3XsI$n!-Z9pGYo((ZEoY&|oX0qIjyd-l zbMDqSGyN2EdMf7hRm|zFnA1b>x7r=CI2)KahKXUA?>X;rQ;STP?@n|o;tVv{Gj~87 zI2zOE!o)WHP#8UTgdUE@^zhz3VfJYHb7Az{F?u)}^xQH1jvpVj zg`4lSFl+ee0XUeNQ4h<>dtl9S^5@CDS`FZ6OwXH%^$T(IRs%R1)AO!keJPIKY5+%L ndfr~Fuf@?@4d7_dQv=>7e$Gb!!OeFp%o;xW8vaMG=}_Y@K#YtG literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.h new file mode 100644 index 000000000..7f1ba1ee7 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.h @@ -0,0 +1,56 @@ +#pragma once + +const uint32_t clear_clockwise_atomic_clip_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000077,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000033, + 0x0000003b,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x00000033,0x00003065,0x00040005,0x00000036,0x61726170, + 0x0000006d,0x00040005,0x00000037,0x61726170,0x0000006d,0x00040005,0x00000038,0x61726170, + 0x0000006d,0x00040005,0x00000039,0x61726170,0x0000006d,0x00030005,0x0000003b,0x0000306a, + 0x00040005,0x0000003c,0x61726170,0x0000006d,0x00030047,0x00000033,0x00000000,0x00040047, + 0x00000033,0x0000001e,0x00000001,0x00030047,0x00000036,0x00000000,0x00030047,0x00000037, + 0x00000000,0x00030047,0x00000038,0x00000000,0x00030047,0x00000039,0x00000000,0x00030047, + 0x0000003b,0x00000000,0x00040047,0x0000003b,0x0000001e,0x00000000,0x00030047,0x0000003c, + 0x00000000,0x00030047,0x0000005f,0x00000000,0x00030047,0x00000060,0x00000000,0x00030047, + 0x00000062,0x00000000,0x00030047,0x00000064,0x00000000,0x00030047,0x00000066,0x00000000, + 0x00030047,0x00000068,0x00000000,0x00030047,0x0000006a,0x00000000,0x00030047,0x0000006b, + 0x00000000,0x00030047,0x0000006c,0x00000000,0x00030047,0x0000006e,0x00000000,0x00030047, + 0x00000070,0x00000000,0x00030047,0x00000072,0x00000000,0x00030047,0x00000074,0x00000000, + 0x00030047,0x00000076,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017, + 0x00000008,0x00000006,0x00000004,0x00040020,0x00000014,0x00000007,0x00000008,0x00040015, + 0x00000017,0x00000020,0x00000000,0x0004002b,0x00000017,0x00000018,0x00000000,0x0004002b, + 0x00000017,0x0000001b,0x00000001,0x0004002b,0x00000017,0x0000001e,0x00000002,0x0004002b, + 0x00000017,0x00000021,0x00000003,0x00040020,0x00000032,0x00000003,0x00000008,0x0004003b, + 0x00000032,0x00000033,0x00000003,0x0004002b,0x00000006,0x00000034,0x00000000,0x0004002b, + 0x00000006,0x00000035,0x3f800000,0x0004003b,0x00000032,0x0000003b,0x00000003,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000014, + 0x0000006b,0x00000007,0x0004003b,0x00000014,0x0000006c,0x00000007,0x0004003b,0x00000014, + 0x0000005f,0x00000007,0x0004003b,0x00000014,0x00000060,0x00000007,0x0004003b,0x00000007, + 0x00000036,0x00000007,0x0004003b,0x00000007,0x00000037,0x00000007,0x0004003b,0x00000007, + 0x00000038,0x00000007,0x0004003b,0x00000007,0x00000039,0x00000007,0x0004003b,0x00000007, + 0x0000003c,0x00000007,0x0003003e,0x00000036,0x00000034,0x0003003e,0x00000037,0x00000034, + 0x0003003e,0x00000038,0x00000034,0x0003003e,0x00000039,0x00000035,0x0004003d,0x00000006, + 0x00000062,0x00000036,0x00050041,0x00000007,0x00000063,0x0000005f,0x00000018,0x0003003e, + 0x00000063,0x00000062,0x0004003d,0x00000006,0x00000064,0x00000037,0x00050041,0x00000007, + 0x00000065,0x0000005f,0x0000001b,0x0003003e,0x00000065,0x00000064,0x0004003d,0x00000006, + 0x00000066,0x00000038,0x00050041,0x00000007,0x00000067,0x0000005f,0x0000001e,0x0003003e, + 0x00000067,0x00000066,0x0004003d,0x00000006,0x00000068,0x00000039,0x00050041,0x00000007, + 0x00000069,0x0000005f,0x00000021,0x0003003e,0x00000069,0x00000068,0x0004003d,0x00000008, + 0x0000006a,0x0000005f,0x0003003e,0x00000060,0x0000006a,0x0004003d,0x00000008,0x0000003a, + 0x00000060,0x0003003e,0x00000033,0x0000003a,0x0003003e,0x0000003c,0x00000034,0x0004003d, + 0x00000006,0x0000006e,0x0000003c,0x00050041,0x00000007,0x0000006f,0x0000006b,0x00000018, + 0x0003003e,0x0000006f,0x0000006e,0x0004003d,0x00000006,0x00000070,0x0000003c,0x00050041, + 0x00000007,0x00000071,0x0000006b,0x0000001b,0x0003003e,0x00000071,0x00000070,0x0004003d, + 0x00000006,0x00000072,0x0000003c,0x00050041,0x00000007,0x00000073,0x0000006b,0x0000001e, + 0x0003003e,0x00000073,0x00000072,0x0004003d,0x00000006,0x00000074,0x0000003c,0x00050041, + 0x00000007,0x00000075,0x0000006b,0x00000021,0x0003003e,0x00000075,0x00000074,0x0004003d, + 0x00000008,0x00000076,0x0000006b,0x0003003e,0x0000006c,0x00000076,0x0004003d,0x00000008, + 0x0000003d,0x0000006c,0x0003003e,0x0000003b,0x0000003d,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/clear_clockwise_atomic_clip.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..435254232f78d5a48f53eccc87bcc0c48b04773b GIT binary patch literal 1660 zcmZ9L-D?w35XG-e(gq8D;70{PT6__NBHGq!tx}=vOQ4`W__o<3n|9;o!`)5QH~&EY zAYTN}Z?hv~FWlU7W=>}AotbT|J>Cf6TG$NT@GY#??XV_G2%JxJZie-mN4<}|-Le|( z?(IKAc_XwqYTwPU5!%A+X_C#bztBF?z9k)YB@${WY6!oSpdGG;6vaE)-S7y4h#Ijl6`-sVw2&wul!AF|vH{mhAVCs*4EvZ(CQLSAA0$wg z#Z|o@ z{XzTMjhol;IPFTABR*#ohm@r|jiifxMLI2Al$P`}s_}0*m)%KMt4Fhs=A!;qqaF96 z{$RJ)*o>p*u+tITZEnY{f&9ktTUcL<`i-5vH14HwzaI_agTb&DN1b7}HAr^5eWkUW zwdLhneIaV??J4K0G>+1w8%OP=r+mrF7{BA>^nOXVl@8mXLq#6p9xB>9``ApQAL5=$ z-|x2L1LrE*4|{tsm)l>;{$BQ&qOp;cW`XI^MytT|;*r*4{&aFRz}XsZ74sF%?`#%$ zOt>2O>+sw{fH{rFUlsl*gtvqElfqAf^^6NY(S~e2r-ZwK|69TvH;ehx!pmP2_>6F) zUEsHcUj^$qEBsQ8vHb4{?+5sta5IR1S9nwP>9fkZ=Tgq13ZF(RaW6j(L9scH&D?H3 z;a-S6mig2Bj8D3Q)#SBSMNB@&IcRP^P4=ouf6(Z*;-fjvgt=jw9?h{H?lXeDp>b|L zw||oT(A$yh2c3Ms*hu?E?$?lA*IglATXx(_`hty^pTgZ^pKnX{zW2jM%x_!vvd@>w z{?6CMM$C^#x$g75kiB-txti*7zd8S_QZV;=Qi{~HM(#6xTGEQKk<0mT#L;88vef*D zf#WV3SMnV9%Q#~2OQjUxuG6mZyZWhu3I57g!i42QMZ3&I>WzMO;M z!nf>x5zm>^FYY1lD6d`4Y(Zyt!QL2sK=5y9WS-pE)FR$+SgR$TTKT&3cWJfS;t{K5 zIIN{7cT@|TTGkVASWBO^H}#e27XVN;9u!oI*^t>?n*%X-K+!D?Y6 zR?Bc$i*JV2!loAas0A)+l^ov`ggI<{?QFs3drr4+G@IwYg8VMNFN?fW(h0@$uEF?$ z$pfaR@98)1WlD;CD$LwOh7P|4Gk;z>BDHzegAo6*#wjWDQ^KEk8~$sL`7Sa~Jp5-; zg!O!`k(#WZ`0E<+g(n_7?K%AQr!vdI`X`lv?iGH5{<;c5eMG(9C5sLTQ_eROx%w5fg=vg+a=eB`n{_Wzdelz7(eg}2+1vdVeqF% zNJ;vSn2N@`V!8Ksq|?$_vD~4%Qtlmh4Ij?wUS=0QGs5_A|IBAr_KftQ@(?qWk{kKU zbNjO4$@iz{4rIemNGPcDYclp bD5V~I=6>IoE=u`U+*6mphthwQ{kHT!5j^#c literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.h new file mode 100644 index 000000000..3a8732220 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.h @@ -0,0 +1,52 @@ +#pragma once + +const uint32_t color_ramp_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000014,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000b,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000009,0x00006771, + 0x00030005,0x0000000b,0x00003652,0x00030005,0x00000011,0x0000424d,0x00040006,0x00000011, + 0x00000000,0x00006250,0x00040006,0x00000011,0x00000001,0x00006359,0x00040006,0x00000011, + 0x00000002,0x00006552,0x00040006,0x00000011,0x00000003,0x00006553,0x00040006,0x00000011, + 0x00000004,0x0000366d,0x00040006,0x00000011,0x00000005,0x0000676d,0x00040006,0x00000011, + 0x00000006,0x00006544,0x00040006,0x00000011,0x00000007,0x00006545,0x00040006,0x00000011, + 0x00000008,0x00003755,0x00040006,0x00000011,0x00000009,0x0000676a,0x00040006,0x00000011, + 0x0000000a,0x0000635a,0x00040006,0x00000011,0x0000000b,0x00003157,0x00040006,0x00000011, + 0x0000000c,0x0000676e,0x00040006,0x00000011,0x0000000d,0x00003559,0x00040006,0x00000011, + 0x0000000e,0x0000324f,0x00040006,0x00000011,0x0000000f,0x00006461,0x00040006,0x00000011, + 0x00000010,0x00006579,0x00040006,0x00000011,0x00000011,0x00003376,0x00040006,0x00000011, + 0x00000012,0x00003377,0x00040006,0x00000011,0x00000013,0x00006462,0x00040006,0x00000011, + 0x00000014,0x00006767,0x00030005,0x00000013,0x0000006b,0x00030047,0x00000009,0x00000000, + 0x00040047,0x00000009,0x0000001e,0x00000000,0x00030047,0x0000000b,0x00000000,0x00040047, + 0x0000000b,0x0000001e,0x00000000,0x00030047,0x0000000c,0x00000000,0x00030047,0x00000011, + 0x00000002,0x00050048,0x00000011,0x00000000,0x00000023,0x00000000,0x00050048,0x00000011, + 0x00000001,0x00000023,0x00000004,0x00050048,0x00000011,0x00000002,0x00000023,0x00000008, + 0x00050048,0x00000011,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000011,0x00000004, + 0x00000023,0x00000010,0x00050048,0x00000011,0x00000005,0x00000023,0x00000014,0x00050048, + 0x00000011,0x00000006,0x00000023,0x00000018,0x00050048,0x00000011,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x00000011,0x00000008,0x00000023,0x00000020,0x00050048,0x00000011, + 0x00000009,0x00000023,0x00000030,0x00050048,0x00000011,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x00000011,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000011,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x00000011,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x00000011,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000011,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x00000011,0x00000010,0x00000023,0x00000054,0x00050048,0x00000011, + 0x00000011,0x00000023,0x00000058,0x00050048,0x00000011,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x00000011,0x00000013,0x00000023,0x00000060,0x00050048,0x00000011,0x00000014, + 0x00000023,0x00000064,0x00040047,0x00000013,0x00000021,0x00000000,0x00040047,0x00000013, + 0x00000022,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008, + 0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040020,0x0000000a, + 0x00000001,0x00000007,0x0004003b,0x0000000a,0x0000000b,0x00000001,0x00040015,0x0000000d, + 0x00000020,0x00000000,0x00040015,0x0000000e,0x00000020,0x00000001,0x00040017,0x0000000f, + 0x0000000e,0x00000004,0x00040017,0x00000010,0x00000006,0x00000002,0x0017001e,0x00000011, + 0x00000006,0x00000006,0x00000006,0x00000006,0x0000000d,0x0000000d,0x0000000d,0x0000000d, + 0x0000000f,0x00000010,0x00000010,0x0000000d,0x00000006,0x0000000d,0x00000006,0x00000006, + 0x0000000d,0x00000006,0x00000006,0x00000006,0x0000000d,0x00040020,0x00000012,0x00000002, + 0x00000011,0x0004003b,0x00000012,0x00000013,0x00000002,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000007,0x0000000c,0x0000000b, + 0x0003003e,0x00000009,0x0000000c,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..98ee6d404cd948daf8c805e7a8a860a0cb11d11b GIT binary patch literal 1524 zcmZ9LTTc^F6h=3l7Ahzg?+=Cy@=m;gBu1kIGCYhaDH_F?jJ*uCSPHfU!+-P#`C{U? zhMvrhC)u6zt-a@*eVIm;^*OT{Td=y_wd=KF6%iAgEuKkwm~Myx8CwAKE4{_X(Ey$J?2iFDKMLN~&w_d8+yd`P&uDO$qzqh*iC>u}CMy+0+wJ(m3 zCC}O?d1n&hl13v*_p;9Ux#F${c{b<|^Q_w+DW-p!b6%bErg8mYXK>N=0X0SV{A$XD z9DnxA*pq8>>w3SU{reqLCk(6iFJ zE}mZPIbE0j__B;A?-Td_y!02B54C)HTE^d$9=iBj(np)6e^I*etkg@=t!}B8rLSB* z^yKn+>Ax-g%jrAPZTCLkR8RNQXM8_o$+Z94YF{m8v5L^bM-41|?7feASj3SF{omK= zVOHxnwE|;aFy;^#@4)D7V9}Iueqg*q96bn(`N60wFlGpQ=ooW^J#viuV6kJ&6UHAa zoX1RI+m6u(*jvZQ6}Iab^M&m@#*AU9W6T+L;23qnJ~&2SVV@mi=CH4hFEnzn z_|fzcc29nK70Xy?`V`CXb00l|aUYuga6h@NiqIRhH_r6N8N7$Vi4D*H_d%08J?0+n npf)u9f^F%0=Sf~H>ir|axA|I>dige}^^Lsr1pQZ)ZOi@vok3hw literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.h new file mode 100644 index 000000000..fa37032b2 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.h @@ -0,0 +1,131 @@ +#pragma once + +const uint32_t color_ramp_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000000fd,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0009000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000004c,0x0000005c,0x000000ac, + 0x000000ca,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168, + 0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000004c,0x565f6c67,0x65747265, + 0x646e4978,0x00007865,0x00030005,0x0000005c,0x00004341,0x00030005,0x00000071,0x0000424d, + 0x00040006,0x00000071,0x00000000,0x00006250,0x00040006,0x00000071,0x00000001,0x00006359, + 0x00040006,0x00000071,0x00000002,0x00006552,0x00040006,0x00000071,0x00000003,0x00006553, + 0x00040006,0x00000071,0x00000004,0x0000366d,0x00040006,0x00000071,0x00000005,0x0000676d, + 0x00040006,0x00000071,0x00000006,0x00006544,0x00040006,0x00000071,0x00000007,0x00006545, + 0x00040006,0x00000071,0x00000008,0x00003755,0x00040006,0x00000071,0x00000009,0x0000676a, + 0x00040006,0x00000071,0x0000000a,0x0000635a,0x00040006,0x00000071,0x0000000b,0x00003157, + 0x00040006,0x00000071,0x0000000c,0x0000676e,0x00040006,0x00000071,0x0000000d,0x00003559, + 0x00040006,0x00000071,0x0000000e,0x0000324f,0x00040006,0x00000071,0x0000000f,0x00006461, + 0x00040006,0x00000071,0x00000010,0x00006579,0x00040006,0x00000071,0x00000011,0x00003376, + 0x00040006,0x00000071,0x00000012,0x00003377,0x00040006,0x00000071,0x00000013,0x00006462, + 0x00040006,0x00000071,0x00000014,0x00006767,0x00030005,0x00000073,0x0000006b,0x00030005, + 0x000000ac,0x00003652,0x00060005,0x000000c8,0x505f6c67,0x65567265,0x78657472,0x00000000, + 0x00060006,0x000000c8,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000000c8, + 0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x000000c8,0x00000002, + 0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x000000c8,0x00000003,0x435f6c67, + 0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000000ca,0x00000000,0x00040047,0x0000004c, + 0x0000000b,0x0000002a,0x00040047,0x0000005c,0x0000001e,0x00000000,0x00030047,0x00000071, + 0x00000002,0x00050048,0x00000071,0x00000000,0x00000023,0x00000000,0x00050048,0x00000071, + 0x00000001,0x00000023,0x00000004,0x00050048,0x00000071,0x00000002,0x00000023,0x00000008, + 0x00050048,0x00000071,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000071,0x00000004, + 0x00000023,0x00000010,0x00050048,0x00000071,0x00000005,0x00000023,0x00000014,0x00050048, + 0x00000071,0x00000006,0x00000023,0x00000018,0x00050048,0x00000071,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x00000071,0x00000008,0x00000023,0x00000020,0x00050048,0x00000071, + 0x00000009,0x00000023,0x00000030,0x00050048,0x00000071,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x00000071,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000071,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x00000071,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x00000071,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000071,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x00000071,0x00000010,0x00000023,0x00000054,0x00050048,0x00000071, + 0x00000011,0x00000023,0x00000058,0x00050048,0x00000071,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x00000071,0x00000013,0x00000023,0x00000060,0x00050048,0x00000071,0x00000014, + 0x00000023,0x00000064,0x00040047,0x00000073,0x00000021,0x00000000,0x00040047,0x00000073, + 0x00000022,0x00000000,0x00030047,0x000000ac,0x00000000,0x00040047,0x000000ac,0x0000001e, + 0x00000000,0x00030047,0x000000c8,0x00000002,0x00050048,0x000000c8,0x00000000,0x0000000b, + 0x00000000,0x00050048,0x000000c8,0x00000001,0x0000000b,0x00000001,0x00050048,0x000000c8, + 0x00000002,0x0000000b,0x00000003,0x00050048,0x000000c8,0x00000003,0x0000000b,0x00000004, + 0x00030047,0x000000d7,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00040015,0x00000006,0x00000020,0x00000000,0x00040017,0x00000007,0x00000006,0x00000004, + 0x00030016,0x00000009,0x00000020,0x00040017,0x0000000a,0x00000009,0x00000004,0x00040017, + 0x0000000f,0x00000009,0x00000002,0x0004002b,0x00000006,0x00000024,0x00000000,0x0004002b, + 0x00000009,0x00000029,0x3f800000,0x0004002b,0x00000006,0x0000002b,0x00000001,0x0004002b, + 0x00000009,0x00000033,0x00000000,0x0004002b,0x00000006,0x00000039,0x00000010,0x0004002b, + 0x00000006,0x0000003a,0x00000008,0x0004002b,0x00000006,0x0000003b,0x00000018,0x0007002c, + 0x00000007,0x0000003c,0x00000039,0x0000003a,0x00000024,0x0000003b,0x0004002b,0x00000006, + 0x0000003e,0x000000ff,0x00040015,0x00000048,0x00000020,0x00000001,0x00040020,0x0000004b, + 0x00000001,0x00000048,0x0004003b,0x0000004b,0x0000004c,0x00000001,0x0004002b,0x00000048, + 0x0000004f,0x00000000,0x0004002b,0x00000048,0x00000052,0x00000001,0x00020014,0x00000056, + 0x00040020,0x0000005b,0x00000001,0x00000007,0x0004003b,0x0000005b,0x0000005c,0x00000001, + 0x00040020,0x0000005d,0x00000001,0x00000006,0x0004002b,0x00000006,0x00000060,0x0000ffff, + 0x0004002b,0x00000048,0x00000065,0x00000010,0x00040017,0x00000070,0x00000048,0x00000004, + 0x0017001e,0x00000071,0x00000009,0x00000009,0x00000009,0x00000009,0x00000006,0x00000006, + 0x00000006,0x00000006,0x00000070,0x0000000f,0x0000000f,0x00000006,0x00000009,0x00000006, + 0x00000009,0x00000009,0x00000006,0x00000009,0x00000009,0x00000009,0x00000006,0x00040020, + 0x00000072,0x00000002,0x00000071,0x0004003b,0x00000072,0x00000073,0x00000002,0x00040020, + 0x00000074,0x00000002,0x00000009,0x0004002b,0x00000006,0x00000081,0x1fffffff,0x0004002b, + 0x00000006,0x00000087,0x80000000,0x0004002b,0x00000006,0x00000090,0x20000000,0x0004002b, + 0x00000009,0x00000096,0x3b000000,0x0004002b,0x00000006,0x0000009a,0x40000000,0x0004002b, + 0x00000048,0x0000009e,0x00000003,0x00040020,0x000000ab,0x00000003,0x0000000a,0x0004003b, + 0x000000ab,0x000000ac,0x00000003,0x0004002b,0x00000006,0x000000b2,0x00000002,0x0004002b, + 0x00000006,0x000000b6,0x00000003,0x0004002b,0x00000009,0x000000c0,0x40000000,0x0004001c, + 0x000000c7,0x00000009,0x0000002b,0x0006001e,0x000000c8,0x0000000a,0x00000009,0x000000c7, + 0x000000c7,0x00040020,0x000000c9,0x00000003,0x000000c8,0x0004003b,0x000000c9,0x000000ca, + 0x00000003,0x0007002c,0x00000007,0x000000f8,0x0000003e,0x0000003e,0x0000003e,0x0000003e, + 0x0004002b,0x00000009,0x000000fa,0x37800000,0x0004002b,0x00000009,0x000000fb,0x3b808081, + 0x0007002c,0x0000000a,0x000000fc,0x000000fb,0x000000fb,0x000000fb,0x000000fb,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000048, + 0x0000004d,0x0000004c,0x000500c3,0x00000048,0x00000053,0x0000004d,0x00000052,0x000500b3, + 0x00000056,0x00000057,0x00000053,0x00000052,0x000300f7,0x0000005a,0x00000000,0x000400fa, + 0x00000057,0x00000059,0x00000062,0x000200f8,0x00000059,0x00050041,0x0000005d,0x0000005e, + 0x0000005c,0x00000024,0x0004003d,0x00000006,0x0000005f,0x0000005e,0x000500c7,0x00000006, + 0x00000061,0x0000005f,0x00000060,0x000200f9,0x0000005a,0x000200f8,0x00000062,0x00050041, + 0x0000005d,0x00000063,0x0000005c,0x00000024,0x0004003d,0x00000006,0x00000064,0x00000063, + 0x000500c2,0x00000006,0x00000066,0x00000064,0x00000065,0x000200f9,0x0000005a,0x000200f8, + 0x0000005a,0x000700f5,0x00000006,0x000000ef,0x00000061,0x00000059,0x00000066,0x00000062, + 0x00040070,0x00000009,0x00000068,0x000000ef,0x00050085,0x00000009,0x0000006a,0x00000068, + 0x000000fa,0x000500c7,0x00000048,0x0000006d,0x0000004d,0x00000052,0x000500aa,0x00000056, + 0x0000006e,0x0000006d,0x0000004f,0x000600a9,0x00000009,0x0000006f,0x0000006e,0x00000033, + 0x00000029,0x00050041,0x00000074,0x00000075,0x00000073,0x0000004f,0x0004003d,0x00000009, + 0x00000076,0x00000075,0x000500b8,0x00000056,0x00000077,0x00000076,0x00000033,0x000300f7, + 0x00000079,0x00000000,0x000400fa,0x00000077,0x00000078,0x00000079,0x000200f8,0x00000078, + 0x00050083,0x00000009,0x0000007b,0x00000029,0x0000006f,0x000200f9,0x00000079,0x000200f8, + 0x00000079,0x000700f5,0x00000009,0x000000f0,0x0000006f,0x0000005a,0x0000007b,0x00000078, + 0x00050041,0x0000005d,0x0000007d,0x0000005c,0x0000002b,0x0004003d,0x00000006,0x0000007e, + 0x0000007d,0x000500c7,0x00000006,0x00000082,0x0000007e,0x00000081,0x00040070,0x00000009, + 0x00000083,0x00000082,0x00050081,0x00000009,0x00000085,0x00000083,0x000000f0,0x000500c7, + 0x00000006,0x00000088,0x0000007e,0x00000087,0x000500ab,0x00000056,0x00000089,0x00000088, + 0x00000024,0x000500aa,0x00000056,0x0000008b,0x00000053,0x0000004f,0x000500a7,0x00000056, + 0x0000008c,0x00000089,0x0000008b,0x000300f7,0x0000008e,0x00000000,0x000400fa,0x0000008c, + 0x0000008d,0x0000008e,0x000200f8,0x0000008d,0x000500c7,0x00000006,0x00000091,0x0000007e, + 0x00000090,0x000500ab,0x00000056,0x00000092,0x00000091,0x00000024,0x000300f7,0x00000094, + 0x00000000,0x000400fa,0x00000092,0x00000093,0x00000095,0x000200f8,0x00000093,0x000200f9, + 0x00000094,0x000200f8,0x00000095,0x00050083,0x00000009,0x00000098,0x0000006a,0x00000096, + 0x000200f9,0x00000094,0x000200f8,0x00000094,0x000700f5,0x00000009,0x000000f3,0x00000033, + 0x00000093,0x00000098,0x00000095,0x000200f9,0x0000008e,0x000200f8,0x0000008e,0x000700f5, + 0x00000009,0x000000f2,0x0000006a,0x00000079,0x000000f3,0x00000094,0x000500c7,0x00000006, + 0x0000009b,0x0000007e,0x0000009a,0x000500ab,0x00000056,0x0000009c,0x0000009b,0x00000024, + 0x000500aa,0x00000056,0x0000009f,0x00000053,0x0000009e,0x000500a7,0x00000056,0x000000a0, + 0x0000009c,0x0000009f,0x000300f7,0x000000a2,0x00000000,0x000400fa,0x000000a0,0x000000a1, + 0x000000a2,0x000200f8,0x000000a1,0x000500c7,0x00000006,0x000000a4,0x0000007e,0x00000090, + 0x000500ab,0x00000056,0x000000a5,0x000000a4,0x00000024,0x000300f7,0x000000a7,0x00000000, + 0x000400fa,0x000000a5,0x000000a6,0x000000a8,0x000200f8,0x000000a6,0x000200f9,0x000000a7, + 0x000200f8,0x000000a8,0x00050081,0x00000009,0x000000aa,0x000000f2,0x00000096,0x000200f9, + 0x000000a7,0x000200f8,0x000000a7,0x000700f5,0x00000009,0x000000f7,0x00000029,0x000000a6, + 0x000000aa,0x000000a8,0x000200f9,0x000000a2,0x000200f8,0x000000a2,0x000700f5,0x00000009, + 0x000000f6,0x000000f2,0x0000008e,0x000000f7,0x000000a7,0x000300f7,0x000000b1,0x00000000, + 0x000400fa,0x00000057,0x000000b0,0x000000b5,0x000200f8,0x000000b0,0x00050041,0x0000005d, + 0x000000b3,0x0000005c,0x000000b2,0x0004003d,0x00000006,0x000000b4,0x000000b3,0x000200f9, + 0x000000b1,0x000200f8,0x000000b5,0x00050041,0x0000005d,0x000000b7,0x0000005c,0x000000b6, + 0x0004003d,0x00000006,0x000000b8,0x000000b7,0x000200f9,0x000000b1,0x000200f8,0x000000b1, + 0x000700f5,0x00000006,0x000000f4,0x000000b4,0x000000b0,0x000000b8,0x000000b5,0x00070050, + 0x00000007,0x000000d1,0x000000f4,0x000000f4,0x000000f4,0x000000f4,0x000500c2,0x00000007, + 0x000000d2,0x000000d1,0x0000003c,0x000500c7,0x00000007,0x000000d4,0x000000d2,0x000000f8, + 0x00040070,0x0000000a,0x000000dc,0x000000d4,0x00050085,0x0000000a,0x000000d7,0x000000dc, + 0x000000fc,0x0003003e,0x000000ac,0x000000d7,0x00050085,0x00000009,0x000000e3,0x000000f6, + 0x000000c0,0x00050083,0x00000009,0x000000e4,0x000000e3,0x00000029,0x00050085,0x00000009, + 0x000000e8,0x00000085,0x00000076,0x0006000c,0x00000009,0x000000ea,0x00000001,0x00000006, + 0x00000076,0x00050083,0x00000009,0x000000eb,0x000000e8,0x000000ea,0x00070050,0x0000000a, + 0x000000ec,0x000000e4,0x000000eb,0x00000033,0x00000029,0x00050041,0x000000ab,0x000000cc, + 0x000000ca,0x0000004f,0x0003003e,0x000000cc,0x000000ec,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/color_ramp.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d64bc6bf4e69fe4066ee0b37d7f803d0c95b2b16 GIT binary patch literal 4060 zcmZ9OOKg-?6vsdMwjhY$V?l5bH;5r><)KAvp`D=^^KlhyfdE9f)J@Y|% z+3M;bSP(1>YJ$r_w3Y^CVghkh;ojWZ*}AS!Os%_P{jGQ`4$4DEe3k@PgmQ)c9!z9% zD6PW7!ZBf5DA%7d?dKFw5!43Ft?|Z=t?|O{L@J$+7m7pqM1MNoJJQ!Db*OhBoh+JP zb6Z<;>-KnZcvybp*>pUc$))3|OkO^j(KPvL$mjerxny=E_GUccQ-jYbD*|Lzdv8hS?%m0f&iy)6kNMM~PEQYO*if=p z%0Ad%(yOF5dH#BoV7sT+NPl2s$)Bzdc=5H;cX{7Pf8HVFGr3}C<_T3uOl0FtWZRa_3^!#8#Y8Tdp0n{j z*haG1IUDsbudHUhJ99!GZ+1HKu~J|)%a^&}j22aIGqM_^mT}Yv$NL*c3>i1^9!HPhG=|}OGIy&47VnFG zW2i;%d2CLu2GwMO-cZ1#Hk4yIF?WAYtywieK!wSWpkr35RFQae0 z%`i5=xnFDNjI#pgqE9={=4?hf^W?+scu{;1Ol&m$KWUQ_6ZOP$-X#If#|Hhbxd-pe z;`|vge1q>6OK)}v%;Z;M(K{W-9G(!z40bsl?t-%H($2c59N4;rUV+@mjf!I?9~GEW zelwiMyu=0gGx9-CIIc(gzltX}dB|sZl9K1=Nr{91(&g!s49A@NdC2#-dc;}337kib z_;bdv>f-%&3)uH5ANqjf=sUI2n?Zqo(TAhr=nem2gl`i*)+xje3GjS()(G5#IUf<2 zeSGN$zM}&CDVJ}L zQFU@g8IH3o?m5ZC@jIS!_k3P5JhNfFd_gkv zM}LkuzZWIri;aG~ter(au)QR}(GO%h^Hs^5$+yDJd`&VuXOio6?JRO(+b_H!kPDeU z;)4!vy?#?N^Kn4%eektj|0%gnAP@e;<7>6Do9`cz$;Vp}M;^P!TavlQLBa0vwq$s} zckf8=6b=d2yTg+4#m0T#)6U|)hqb>ez;QohJM(?X^LzJ!IC$&b5y>oaVf#?{NFWz7 zcf|)C-sa<|WbSLdGaq*A#|6pEGI{VPo_tm-yZQbjnSAt0VjYYf&0$!Gurtb)@uLW@qE9~&pYmt_ATlM|Hi@D_w5JC^zO7^bN!=a zczSPsKZSDiom%9+Z$FD$AaJiy!Qy|Bj6ZhnMjgKj2QL2xK5D|}(JAdD|<}t?^8Qtx&=YRemYpwrUd+qP+ zy;qvH-gn!o+N$bOZC7pFv8o@RskRnVRh;|k+@GyI^r^Clm3*x~&#+^K5f zRM&N_x>n7?lo=DI&V+B1`T~`2s$8$~OO>@MU1hY3${s3xRd!Y!ohmg%s7bX})zfM~ zbJe*THoSGv=)tXX&zms0ZBFald9&tBn9|ld@xpV@l{jnSw6;m}WY-0|q2tH4&Ydu0 z_Vl(n)7$3GZJpP4@w^M?w6≷mk?%rp}rG<&vUUNXI{b^6qq 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 X$?zPG`#H&bs5mY%b{{KyN2&ZjOj07{ literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.h new file mode 100644 index 000000000..62e406d18 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.h @@ -0,0 +1,260 @@ +#pragma once + +const uint32_t draw_atlas_blit_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000029a,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000d000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000c9,0x000000d1,0x000000d4, + 0x0000010d,0x00000112,0x00000133,0x00000152,0x000001c5,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000a1,0x0000664a,0x00040006,0x000000a1, + 0x00000000,0x00003464,0x00030005,0x000000a3,0x0000424c,0x00030005,0x000000bb,0x0000424d, + 0x00040006,0x000000bb,0x00000000,0x00006250,0x00040006,0x000000bb,0x00000001,0x00006359, + 0x00040006,0x000000bb,0x00000002,0x00006552,0x00040006,0x000000bb,0x00000003,0x00006553, + 0x00040006,0x000000bb,0x00000004,0x0000366d,0x00040006,0x000000bb,0x00000005,0x0000676d, + 0x00040006,0x000000bb,0x00000006,0x00006544,0x00040006,0x000000bb,0x00000007,0x00006545, + 0x00040006,0x000000bb,0x00000008,0x00003755,0x00040006,0x000000bb,0x00000009,0x0000676a, + 0x00040006,0x000000bb,0x0000000a,0x0000635a,0x00040006,0x000000bb,0x0000000b,0x00003157, + 0x00040006,0x000000bb,0x0000000c,0x0000676e,0x00040006,0x000000bb,0x0000000d,0x00003559, + 0x00040006,0x000000bb,0x0000000e,0x0000324f,0x00040006,0x000000bb,0x0000000f,0x00006461, + 0x00040006,0x000000bb,0x00000010,0x00006579,0x00040006,0x000000bb,0x00000011,0x00003376, + 0x00040006,0x000000bb,0x00000012,0x00003377,0x00040006,0x000000bb,0x00000013,0x00006462, + 0x00040006,0x000000bb,0x00000014,0x00006767,0x00030005,0x000000bd,0x0000006b,0x00060005, + 0x000000c9,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x000000d1,0x0000424a, + 0x00030005,0x000000d4,0x00003243,0x00030005,0x000000e0,0x00006576,0x00040006,0x000000e0, + 0x00000000,0x00003464,0x00030005,0x000000e2,0x00004355,0x00030005,0x000000ec,0x00006747, + 0x00030005,0x0000010d,0x00003346,0x00030005,0x0000010f,0x00006749,0x00030005,0x00000112, + 0x00003159,0x00030005,0x0000011b,0x00006748,0x00030005,0x00000120,0x00006577,0x00040006, + 0x00000120,0x00000000,0x00003464,0x00030005,0x00000122,0x0000424f,0x00030005,0x00000133, + 0x0000304e,0x00030005,0x00000152,0x0000316b,0x00060005,0x000001c3,0x505f6c67,0x65567265, + 0x78657472,0x00000000,0x00060006,0x000001c3,0x00000000,0x505f6c67,0x7469736f,0x006e6f69, + 0x00070006,0x000001c3,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006, + 0x000001c3,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x000001c3, + 0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000001c5,0x00000000, + 0x00030005,0x000001d3,0x00004342,0x00030005,0x000001d6,0x00004351,0x00030005,0x000001d8, + 0x0000664b,0x00040006,0x000001d8,0x00000000,0x00003464,0x00030005,0x000001da,0x00004358, + 0x00030005,0x000001dd,0x00003954,0x00040047,0x000000a0,0x00000006,0x00000010,0x00030047, + 0x000000a1,0x00000003,0x00040048,0x000000a1,0x00000000,0x00000018,0x00050048,0x000000a1, + 0x00000000,0x00000023,0x00000000,0x00030047,0x000000a3,0x00000018,0x00040047,0x000000a3, + 0x00000021,0x00000003,0x00040047,0x000000a3,0x00000022,0x00000000,0x00030047,0x000000bb, + 0x00000002,0x00050048,0x000000bb,0x00000000,0x00000023,0x00000000,0x00050048,0x000000bb, + 0x00000001,0x00000023,0x00000004,0x00050048,0x000000bb,0x00000002,0x00000023,0x00000008, + 0x00050048,0x000000bb,0x00000003,0x00000023,0x0000000c,0x00050048,0x000000bb,0x00000004, + 0x00000023,0x00000010,0x00050048,0x000000bb,0x00000005,0x00000023,0x00000014,0x00050048, + 0x000000bb,0x00000006,0x00000023,0x00000018,0x00050048,0x000000bb,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x000000bb,0x00000008,0x00000023,0x00000020,0x00050048,0x000000bb, + 0x00000009,0x00000023,0x00000030,0x00050048,0x000000bb,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x000000bb,0x0000000b,0x00000023,0x00000040,0x00050048,0x000000bb,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x000000bb,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x000000bb,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000000bb,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x000000bb,0x00000010,0x00000023,0x00000054,0x00050048,0x000000bb, + 0x00000011,0x00000023,0x00000058,0x00050048,0x000000bb,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x000000bb,0x00000013,0x00000023,0x00000060,0x00050048,0x000000bb,0x00000014, + 0x00000023,0x00000064,0x00040047,0x000000bd,0x00000021,0x00000000,0x00040047,0x000000bd, + 0x00000022,0x00000000,0x00040047,0x000000c9,0x0000000b,0x0000002a,0x00040047,0x000000d1, + 0x0000001e,0x00000000,0x00040047,0x000000d4,0x0000001e,0x00000001,0x00040047,0x000000df, + 0x00000006,0x00000008,0x00030047,0x000000e0,0x00000003,0x00040048,0x000000e0,0x00000000, + 0x00000018,0x00050048,0x000000e0,0x00000000,0x00000023,0x00000000,0x00030047,0x000000e2, + 0x00000018,0x00040047,0x000000e2,0x00000021,0x00000004,0x00040047,0x000000e2,0x00000022, + 0x00000000,0x00040047,0x000000ec,0x00000001,0x00000000,0x00030047,0x0000010b,0x00000000, + 0x00030047,0x0000010d,0x00000000,0x00030047,0x0000010d,0x0000000e,0x00040047,0x0000010d, + 0x0000001e,0x00000004,0x00040047,0x0000010f,0x00000001,0x00000002,0x00030047,0x00000112, + 0x00000000,0x00030047,0x00000112,0x0000000e,0x00040047,0x00000112,0x0000001e,0x00000006, + 0x00040047,0x0000011b,0x00000001,0x00000001,0x00040047,0x0000011f,0x00000006,0x00000010, + 0x00030047,0x00000120,0x00000003,0x00040048,0x00000120,0x00000000,0x00000018,0x00050048, + 0x00000120,0x00000000,0x00000023,0x00000000,0x00030047,0x00000122,0x00000018,0x00040047, + 0x00000122,0x00000021,0x00000005,0x00040047,0x00000122,0x00000022,0x00000000,0x00040047, + 0x00000133,0x0000001e,0x00000005,0x00030047,0x00000148,0x00000000,0x00030047,0x0000014a, + 0x00000000,0x00030047,0x0000014b,0x00000000,0x00040047,0x00000152,0x0000001e,0x00000000, + 0x00030047,0x000001c3,0x00000002,0x00050048,0x000001c3,0x00000000,0x0000000b,0x00000000, + 0x00050048,0x000001c3,0x00000001,0x0000000b,0x00000001,0x00050048,0x000001c3,0x00000002, + 0x0000000b,0x00000003,0x00050048,0x000001c3,0x00000003,0x0000000b,0x00000004,0x00040047, + 0x000001d3,0x00000021,0x00000008,0x00040047,0x000001d3,0x00000022,0x00000000,0x00030047, + 0x000001d6,0x00000000,0x00040047,0x000001d6,0x00000021,0x0000000a,0x00040047,0x000001d6, + 0x00000022,0x00000000,0x00040047,0x000001d7,0x00000006,0x00000010,0x00030047,0x000001d8, + 0x00000003,0x00040048,0x000001d8,0x00000000,0x00000018,0x00050048,0x000001d8,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000001da,0x00000018,0x00040047,0x000001da,0x00000021, + 0x00000006,0x00040047,0x000001da,0x00000022,0x00000000,0x00030047,0x000001dd,0x00000000, + 0x00040047,0x000001dd,0x00000021,0x0000000a,0x00040047,0x000001dd,0x00000022,0x00000000, + 0x00030047,0x00000280,0x00000000,0x00030047,0x00000282,0x00000000,0x00030047,0x00000284, + 0x00000000,0x00030047,0x00000291,0x00000000,0x00030047,0x00000293,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000004,0x00040017,0x00000009,0x00000006,0x00000002,0x00040018, + 0x0000000a,0x00000009,0x00000002,0x00040015,0x0000000f,0x00000020,0x00000000,0x00040017, + 0x00000025,0x00000006,0x00000003,0x0004002b,0x00000006,0x00000031,0x3f800000,0x0004002b, + 0x00000006,0x00000032,0x00000000,0x0004002b,0x0000000f,0x0000003d,0x00000000,0x00020014, + 0x0000003e,0x0004002b,0x0000000f,0x00000045,0x000003ff,0x0004002b,0x0000000f,0x00000055, + 0x00000001,0x00040015,0x00000061,0x00000020,0x00000001,0x0004002b,0x00000061,0x00000062, + 0x00000000,0x0004002b,0x00000006,0x0000008e,0x3f000000,0x0004002b,0x0000000f,0x00000097, + 0x00000002,0x0004002b,0x0000000f,0x0000009b,0x0000ffff,0x00040017,0x0000009d,0x0000000f, + 0x00000004,0x0003001d,0x000000a0,0x0000009d,0x0003001e,0x000000a1,0x000000a0,0x00040020, + 0x000000a2,0x00000002,0x000000a1,0x0004003b,0x000000a2,0x000000a3,0x00000002,0x0004002b, + 0x0000000f,0x000000a5,0x00000004,0x00040020,0x000000a8,0x00000002,0x0000009d,0x00040017, + 0x000000af,0x0000000f,0x00000003,0x00040017,0x000000ba,0x00000061,0x00000004,0x0017001e, + 0x000000bb,0x00000006,0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f,0x0000000f, + 0x0000000f,0x000000ba,0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f,0x00000006, + 0x00000006,0x0000000f,0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020,0x000000bc, + 0x00000002,0x000000bb,0x0004003b,0x000000bc,0x000000bd,0x00000002,0x0004002b,0x00000061, + 0x000000be,0x00000009,0x00040020,0x000000bf,0x00000002,0x00000009,0x00040020,0x000000c8, + 0x00000001,0x00000061,0x0004003b,0x000000c8,0x000000c9,0x00000001,0x00040020,0x000000d0, + 0x00000001,0x00000025,0x0004003b,0x000000d0,0x000000d1,0x00000001,0x00040020,0x000000d3, + 0x00000003,0x00000009,0x0004003b,0x000000d3,0x000000d4,0x00000003,0x00040017,0x000000dc, + 0x0000000f,0x00000002,0x0003001d,0x000000df,0x000000dc,0x0003001e,0x000000e0,0x000000df, + 0x00040020,0x000000e1,0x00000002,0x000000e0,0x0004003b,0x000000e1,0x000000e2,0x00000002, + 0x00040020,0x000000e4,0x00000002,0x000000dc,0x0004002b,0x0000000f,0x000000ea,0x0000000f, + 0x00030030,0x0000003e,0x000000ec,0x0004002b,0x00000061,0x000000fb,0x00000010,0x0004002b, + 0x00000061,0x000000fe,0x0000000d,0x00040020,0x00000102,0x00000002,0x0000000f,0x00040020, + 0x0000010c,0x00000003,0x00000006,0x0004003b,0x0000010c,0x0000010d,0x00000003,0x00030030, + 0x0000003e,0x0000010f,0x0004003b,0x0000010c,0x00000112,0x00000003,0x0004002b,0x00000061, + 0x00000115,0x00000004,0x00030030,0x0000003e,0x0000011b,0x0003001d,0x0000011f,0x00000007, + 0x0003001e,0x00000120,0x0000011f,0x00040020,0x00000121,0x00000002,0x00000120,0x0004003b, + 0x00000121,0x00000122,0x00000002,0x00040020,0x00000127,0x00000002,0x00000007,0x0004002b, + 0x0000000f,0x0000012e,0x00000003,0x00040020,0x00000132,0x00000003,0x00000007,0x0004003b, + 0x00000132,0x00000133,0x00000003,0x00050034,0x0000003e,0x00000144,0x000000a8,0x0000010f, + 0x0004003b,0x00000132,0x00000152,0x00000003,0x0004002b,0x00000006,0x00000179,0x3f666666, + 0x0004002b,0x00000006,0x0000017d,0x40000000,0x0004002b,0x00000006,0x000001a2,0xc0000000, + 0x0004002b,0x00000061,0x000001ab,0x00000002,0x0004002b,0x00000061,0x000001ac,0x00000003, + 0x00040020,0x000001b0,0x00000002,0x00000006,0x0004001c,0x000001c2,0x00000006,0x00000055, + 0x0006001e,0x000001c3,0x00000007,0x00000006,0x000001c2,0x000001c2,0x00040020,0x000001c4, + 0x00000003,0x000001c3,0x0004003b,0x000001c4,0x000001c5,0x00000003,0x00090019,0x000001d1, + 0x0000000f,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x000001d2,0x00000000,0x000001d1,0x0004003b,0x000001d2,0x000001d3,0x00000000,0x00090019, + 0x000001d4,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x000001d5,0x00000000,0x000001d4,0x0004003b,0x000001d5,0x000001d6,0x00000000, + 0x0003001d,0x000001d7,0x0000009d,0x0003001e,0x000001d8,0x000001d7,0x00040020,0x000001d9, + 0x00000002,0x000001d8,0x0004003b,0x000001d9,0x000001da,0x00000002,0x0002001a,0x000001db, + 0x00040020,0x000001dc,0x00000000,0x000001db,0x0004003b,0x000001dc,0x000001dd,0x00000000, + 0x0005002c,0x00000009,0x00000296,0x00000031,0x00000031,0x0007002c,0x00000007,0x00000297, + 0x0000008e,0x0000008e,0x0000008e,0x0000008e,0x0003002e,0x00000009,0x00000299,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000025, + 0x000000d6,0x000000d1,0x00050051,0x00000006,0x000001ea,0x000000d6,0x00000002,0x0004007c, + 0x0000000f,0x000001eb,0x000001ea,0x000500c7,0x0000000f,0x000001ec,0x000001eb,0x0000009b, + 0x00050084,0x0000000f,0x000001ee,0x000001ec,0x000000a5,0x00050080,0x0000000f,0x000001ef, + 0x000001ee,0x00000097,0x00060041,0x000000a8,0x000001f0,0x000000a3,0x00000062,0x000001ef, + 0x0004003d,0x0000009d,0x000001f1,0x000001f0,0x0007004f,0x00000009,0x000001f3,0x000000d6, + 0x000000d6,0x00000000,0x00000001,0x0008004f,0x000000af,0x000001f5,0x000001f1,0x000001f1, + 0x00000001,0x00000002,0x00000003,0x0004007c,0x00000025,0x000001f6,0x000001f5,0x00050051, + 0x00000006,0x000001f9,0x000001f6,0x00000000,0x0005008e,0x00000009,0x000001fa,0x000001f3, + 0x000001f9,0x0007004f,0x00000009,0x000001fc,0x000001f6,0x000001f6,0x00000001,0x00000002, + 0x00050081,0x00000009,0x000001fd,0x000001fa,0x000001fc,0x00050041,0x000000bf,0x000001fe, + 0x000000bd,0x000000be,0x0004003d,0x00000009,0x000001ff,0x000001fe,0x00050085,0x00000009, + 0x00000200,0x000001fd,0x000001ff,0x0003003e,0x000000d4,0x00000200,0x00060041,0x000000e4, + 0x000000e5,0x000000e2,0x00000062,0x000001ec,0x0004003d,0x000000dc,0x000000e6,0x000000e5, + 0x00050051,0x0000000f,0x000000e9,0x000000e6,0x00000000,0x000500c7,0x0000000f,0x000000eb, + 0x000000e9,0x000000ea,0x000300f7,0x000000ee,0x00000000,0x000400fa,0x000000ec,0x000000ed, + 0x000000ee,0x000200f8,0x000000ed,0x000500aa,0x0000003e,0x000000f1,0x000000eb,0x0000003d, + 0x000300f7,0x000000f4,0x00000000,0x000400fa,0x000000f1,0x000000f3,0x000000f7,0x000200f8, + 0x000000f7,0x000200f9,0x000000f4,0x000200f8,0x000000f3,0x00050051,0x0000000f,0x000000f6, + 0x000000e6,0x00000001,0x000200f9,0x000000f4,0x000200f8,0x000000f4,0x000700f5,0x0000000f, + 0x0000028f,0x000000f6,0x000000f3,0x000000e9,0x000000f7,0x000500c2,0x0000000f,0x000000fc, + 0x0000028f,0x000000fb,0x00050041,0x00000102,0x00000103,0x000000bd,0x000000fe,0x0004003d, + 0x0000000f,0x00000104,0x00000103,0x000500aa,0x0000003e,0x00000207,0x000000fc,0x0000003d, + 0x000300f7,0x00000210,0x00000000,0x000400fa,0x00000207,0x00000208,0x00000209,0x000200f8, + 0x00000209,0x00050080,0x0000000f,0x0000020b,0x000000fc,0x00000045,0x00050084,0x0000000f, + 0x0000020d,0x0000020b,0x00000104,0x0006000c,0x00000009,0x0000020e,0x00000001,0x0000003e, + 0x0000020d,0x00050051,0x00000006,0x0000020f,0x0000020e,0x00000000,0x000200f9,0x00000210, + 0x000200f8,0x00000208,0x000200f9,0x00000210,0x000200f8,0x00000210,0x000700f5,0x00000006, + 0x00000290,0x00000032,0x00000208,0x0000020f,0x00000209,0x000300f7,0x00000109,0x00000000, + 0x000400fa,0x000000f1,0x00000108,0x00000109,0x000200f8,0x00000108,0x0004007f,0x00000006, + 0x0000010b,0x00000290,0x000200f9,0x00000109,0x000200f8,0x00000109,0x000700f5,0x00000006, + 0x00000291,0x00000290,0x00000210,0x0000010b,0x00000108,0x0003003e,0x0000010d,0x00000291, + 0x000200f9,0x000000ee,0x000200f8,0x000000ee,0x000300f7,0x00000111,0x00000000,0x000400fa, + 0x0000010f,0x00000110,0x00000111,0x000200f8,0x00000110,0x000500c2,0x0000000f,0x00000116, + 0x000000e9,0x00000115,0x000500c7,0x0000000f,0x00000117,0x00000116,0x000000ea,0x00040070, + 0x00000006,0x00000118,0x00000117,0x0003003e,0x00000112,0x00000118,0x000200f9,0x00000111, + 0x000200f8,0x00000111,0x000300f7,0x0000011d,0x00000000,0x000400fa,0x0000011b,0x0000011c, + 0x0000011d,0x000200f8,0x0000011c,0x00060041,0x00000127,0x00000128,0x00000122,0x00000062, + 0x000001ef,0x0004003d,0x00000007,0x00000129,0x00000128,0x00050051,0x00000006,0x00000219, + 0x00000129,0x00000000,0x00050051,0x00000006,0x0000021a,0x00000129,0x00000001,0x00050051, + 0x00000006,0x0000021b,0x00000129,0x00000002,0x00050051,0x00000006,0x0000021c,0x00000129, + 0x00000003,0x00050050,0x00000009,0x0000021d,0x00000219,0x0000021a,0x00050050,0x00000009, + 0x0000021e,0x0000021b,0x0000021c,0x00050050,0x0000000a,0x0000021f,0x0000021d,0x0000021e, + 0x00050080,0x0000000f,0x0000012f,0x000001ee,0x0000012e,0x00060041,0x00000127,0x00000130, + 0x00000122,0x00000062,0x0000012f,0x0004003d,0x00000007,0x00000131,0x00000130,0x0007004f, + 0x00000009,0x00000138,0x00000131,0x00000131,0x00000000,0x00000001,0x000300f7,0x00000255, + 0x00000000,0x000300fb,0x0000003d,0x00000227,0x000200f8,0x00000227,0x0006000c,0x00000009, + 0x0000022a,0x00000001,0x00000004,0x0000021d,0x0006000c,0x00000009,0x0000022d,0x00000001, + 0x00000004,0x0000021e,0x00050081,0x00000009,0x0000022e,0x0000022a,0x0000022d,0x00050051, + 0x00000006,0x00000230,0x0000022e,0x00000000,0x000500b7,0x0000003e,0x00000231,0x00000230, + 0x00000032,0x000300f7,0x00000236,0x00000000,0x000400fa,0x00000231,0x00000232,0x00000236, + 0x000200f8,0x00000232,0x00050051,0x00000006,0x00000234,0x0000022e,0x00000001,0x000500b7, + 0x0000003e,0x00000235,0x00000234,0x00000032,0x000200f9,0x00000236,0x000200f8,0x00000236, + 0x000700f5,0x0000003e,0x00000237,0x00000231,0x00000227,0x00000235,0x00000232,0x000300f7, + 0x00000254,0x00000000,0x000400fa,0x00000237,0x00000238,0x00000251,0x000200f8,0x00000251, + 0x0009004f,0x00000007,0x00000253,0x00000131,0x00000299,0x00000000,0x00000001,0x00000000, + 0x00000001,0x000200f9,0x00000255,0x000200f8,0x00000238,0x00050088,0x00000009,0x0000023b, + 0x00000296,0x0000022e,0x00050091,0x00000009,0x0000023e,0x0000021f,0x000001f3,0x00050081, + 0x00000009,0x00000240,0x0000023e,0x00000138,0x0004007f,0x00000009,0x00000243,0x00000240, + 0x00050051,0x00000006,0x00000244,0x00000240,0x00000000,0x00050051,0x00000006,0x00000245, + 0x00000240,0x00000001,0x00050051,0x00000006,0x00000246,0x00000243,0x00000000,0x00050051, + 0x00000006,0x00000247,0x00000243,0x00000001,0x00070050,0x00000007,0x00000248,0x00000244, + 0x00000245,0x00000246,0x00000247,0x0009004f,0x00000007,0x0000024a,0x0000023b,0x0000023b, + 0x00000000,0x00000001,0x00000000,0x00000001,0x00050085,0x00000007,0x0000024b,0x00000248, + 0x0000024a,0x00050081,0x00000007,0x0000024e,0x0000024b,0x0000024a,0x00050081,0x00000007, + 0x00000250,0x0000024e,0x00000297,0x000200f9,0x00000255,0x000200f8,0x00000254,0x000100ff, + 0x000200f8,0x00000255,0x000700f5,0x00000007,0x00000292,0x00000250,0x00000238,0x00000253, + 0x00000251,0x0003003e,0x00000133,0x00000292,0x000200f9,0x0000011d,0x000200f8,0x0000011d, + 0x000500aa,0x0000003e,0x0000013d,0x000000eb,0x00000055,0x000300f7,0x0000013f,0x00000000, + 0x000400fa,0x0000013d,0x0000013e,0x00000154,0x000200f8,0x00000154,0x00060041,0x00000127, + 0x00000159,0x00000122,0x00000062,0x000001ee,0x0004003d,0x00000007,0x0000015a,0x00000159, + 0x00050051,0x00000006,0x0000025d,0x0000015a,0x00000000,0x00050051,0x00000006,0x0000025e, + 0x0000015a,0x00000001,0x00050051,0x00000006,0x0000025f,0x0000015a,0x00000002,0x00050051, + 0x00000006,0x00000260,0x0000015a,0x00000003,0x00050050,0x00000009,0x00000261,0x0000025d, + 0x0000025e,0x00050050,0x00000009,0x00000262,0x0000025f,0x00000260,0x00050050,0x0000000a, + 0x00000263,0x00000261,0x00000262,0x00050080,0x0000000f,0x0000015f,0x000001ee,0x00000055, + 0x00060041,0x00000127,0x00000160,0x00000122,0x00000062,0x0000015f,0x0004003d,0x00000007, + 0x00000161,0x00000160,0x00050091,0x00000009,0x00000165,0x00000263,0x000001f3,0x0007004f, + 0x00000009,0x00000167,0x00000161,0x00000161,0x00000000,0x00000001,0x00050081,0x00000009, + 0x00000168,0x00000165,0x00000167,0x000500aa,0x0000003e,0x0000016a,0x000000eb,0x00000097, + 0x000500aa,0x0000003e,0x0000016c,0x000000eb,0x0000012e,0x000500a6,0x0000003e,0x0000016d, + 0x0000016a,0x0000016c,0x000300f7,0x0000016f,0x00000000,0x000400fa,0x0000016d,0x0000016e, + 0x00000195,0x000200f8,0x00000195,0x00050051,0x0000000f,0x00000198,0x000000e6,0x00000001, + 0x0004007c,0x00000006,0x00000199,0x00000198,0x00050051,0x00000006,0x0000019c,0x00000161, + 0x00000002,0x00050051,0x00000006,0x0000019e,0x00000168,0x00000000,0x00050051,0x00000006, + 0x000001a0,0x00000168,0x00000001,0x00050083,0x00000006,0x000001a4,0x000001a2,0x0000019c, + 0x00070050,0x00000007,0x000001a5,0x0000019e,0x000001a0,0x00000199,0x000001a4,0x0003003e, + 0x00000152,0x000001a5,0x000200f9,0x0000016f,0x000200f8,0x0000016e,0x00050051,0x0000000f, + 0x00000171,0x000000e6,0x00000001,0x0004007c,0x00000006,0x00000172,0x00000171,0x0004007f, + 0x00000006,0x00000173,0x00000172,0x00050041,0x0000010c,0x00000174,0x00000152,0x0000012e, + 0x0003003e,0x00000174,0x00000173,0x00050051,0x00000006,0x00000177,0x00000161,0x00000002, + 0x000500ba,0x0000003e,0x0000017a,0x00000177,0x00000179,0x000300f7,0x0000017c,0x00000000, + 0x000400fa,0x0000017a,0x0000017b,0x0000017f,0x000200f8,0x0000017f,0x00050051,0x00000006, + 0x00000181,0x00000161,0x00000003,0x00050041,0x0000010c,0x00000182,0x00000152,0x00000097, + 0x0003003e,0x00000182,0x00000181,0x000200f9,0x0000017c,0x000200f8,0x0000017b,0x00050041, + 0x0000010c,0x0000017e,0x00000152,0x00000097,0x0003003e,0x0000017e,0x0000017d,0x000200f9, + 0x0000017c,0x000200f8,0x0000017c,0x000300f7,0x00000186,0x00000000,0x000400fa,0x0000016a, + 0x00000185,0x0000018b,0x000200f8,0x0000018b,0x00050041,0x0000010c,0x0000018c,0x00000152, + 0x00000097,0x0004003d,0x00000006,0x0000018d,0x0000018c,0x0004007f,0x00000006,0x0000018e, + 0x0000018d,0x0003003e,0x0000018c,0x0000018e,0x00050041,0x0000010c,0x00000191,0x00000152, + 0x0000003d,0x00050051,0x00000006,0x00000192,0x00000168,0x00000000,0x0003003e,0x00000191, + 0x00000192,0x00050041,0x0000010c,0x00000193,0x00000152,0x00000055,0x00050051,0x00000006, + 0x00000194,0x00000168,0x00000001,0x0003003e,0x00000193,0x00000194,0x000200f9,0x00000186, + 0x000200f8,0x00000185,0x00050041,0x0000010c,0x00000187,0x00000152,0x00000055,0x0003003e, + 0x00000187,0x00000032,0x00050051,0x00000006,0x00000189,0x00000168,0x00000000,0x00050041, + 0x0000010c,0x0000018a,0x00000152,0x0000003d,0x0003003e,0x0000018a,0x00000189,0x000200f9, + 0x00000186,0x000200f8,0x00000186,0x000200f9,0x0000016f,0x000200f8,0x0000016f,0x000200f9, + 0x0000013f,0x000200f8,0x0000013e,0x00050051,0x0000000f,0x00000142,0x000000e6,0x00000001, + 0x0006000c,0x00000007,0x00000143,0x00000001,0x00000040,0x00000142,0x000300f7,0x00000146, + 0x00000000,0x000400fa,0x00000144,0x00000145,0x00000146,0x000200f8,0x00000145,0x00050051, + 0x00000006,0x00000148,0x00000143,0x00000003,0x0008004f,0x00000025,0x0000014a,0x00000143, + 0x00000143,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000025,0x0000014b,0x0000014a, + 0x00000148,0x00050051,0x00000006,0x0000014d,0x0000014b,0x00000000,0x00060052,0x00000007, + 0x00000280,0x0000014d,0x00000143,0x00000000,0x00050051,0x00000006,0x0000014f,0x0000014b, + 0x00000001,0x00060052,0x00000007,0x00000282,0x0000014f,0x00000280,0x00000001,0x00050051, + 0x00000006,0x00000151,0x0000014b,0x00000002,0x00060052,0x00000007,0x00000284,0x00000151, + 0x00000282,0x00000002,0x000200f9,0x00000146,0x000200f8,0x00000146,0x000700f5,0x00000007, + 0x00000293,0x00000143,0x0000013e,0x00000284,0x00000145,0x0003003e,0x00000152,0x00000293, + 0x000200f9,0x0000013f,0x000200f8,0x0000013f,0x00050041,0x000001b0,0x000001b1,0x000000bd, + 0x000001ab,0x0004003d,0x00000006,0x000001b2,0x000001b1,0x00050041,0x000001b0,0x000001b4, + 0x000000bd,0x000001ac,0x0004003d,0x00000006,0x000001b5,0x000001b4,0x00050051,0x00000006, + 0x00000267,0x000000d6,0x00000000,0x00050085,0x00000006,0x00000269,0x00000267,0x000001b2, + 0x00050083,0x00000006,0x0000026a,0x00000269,0x00000031,0x00050051,0x00000006,0x0000026c, + 0x000000d6,0x00000001,0x00050085,0x00000006,0x0000026e,0x0000026c,0x000001b5,0x0006000c, + 0x00000006,0x00000270,0x00000001,0x00000006,0x000001b5,0x00050083,0x00000006,0x00000271, + 0x0000026e,0x00000270,0x00070050,0x00000007,0x00000272,0x0000026a,0x00000271,0x00000032, + 0x00000031,0x00050041,0x00000132,0x000001c7,0x000001c5,0x00000062,0x0003003e,0x000001c7, + 0x00000272,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_atlas_blit.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..a1166bae1904e5a72e169fa2a757a2714ff01724 GIT binary patch literal 8172 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 HzasQsK~w)9 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.h new file mode 100644 index 000000000..a02d0b6b7 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.h @@ -0,0 +1,251 @@ +#pragma once + +const uint32_t draw_clockwise_atlas_blit_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000002e4,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x000c000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x00000131,0x00000137,0x00000143,0x00000150,0x00000160,0x000001a8,0x000001b4, + 0x00030010,0x00000004,0x00000007,0x00030010,0x00000004,0x000014f6,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x665f4252,0x6d676172,0x5f746e65,0x64616873,0x695f7265, + 0x7265746e,0x6b636f6c,0x00000000,0x00090004,0x415f4c47,0x735f4252,0x65646168,0x6d695f72, + 0x5f656761,0x64616f6c,0x6f74735f,0x00006572,0x000a0004,0x415f4c47,0x735f4252,0x65646168, + 0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47, + 0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69, + 0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c, + 0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63, + 0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005, + 0x00000088,0x0000674e,0x00030005,0x000000a4,0x00006749,0x00030005,0x000000e4,0x00004444, + 0x00030005,0x000000e8,0x00006277,0x00030005,0x0000010a,0x00004344,0x00030005,0x0000010c, + 0x00003552,0x00060005,0x00000131,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x00000137,0x0000316b,0x00030005,0x0000013d,0x00004356,0x00030005,0x0000013f,0x00003949, + 0x00030005,0x00000143,0x00003243,0x00030005,0x0000014c,0x00006748,0x00030005,0x00000150, + 0x0000304e,0x00030005,0x0000015c,0x00006747,0x00030005,0x00000160,0x00003346,0x00030005, + 0x00000169,0x00003065,0x00030005,0x0000018e,0x0000424d,0x00040006,0x0000018e,0x00000000, + 0x00006250,0x00040006,0x0000018e,0x00000001,0x00006359,0x00040006,0x0000018e,0x00000002, + 0x00006552,0x00040006,0x0000018e,0x00000003,0x00006553,0x00040006,0x0000018e,0x00000004, + 0x0000366d,0x00040006,0x0000018e,0x00000005,0x0000676d,0x00040006,0x0000018e,0x00000006, + 0x00006544,0x00040006,0x0000018e,0x00000007,0x00006545,0x00040006,0x0000018e,0x00000008, + 0x00003755,0x00040006,0x0000018e,0x00000009,0x0000676a,0x00040006,0x0000018e,0x0000000a, + 0x0000635a,0x00040006,0x0000018e,0x0000000b,0x00003157,0x00040006,0x0000018e,0x0000000c, + 0x0000676e,0x00040006,0x0000018e,0x0000000d,0x00003559,0x00040006,0x0000018e,0x0000000e, + 0x0000324f,0x00040006,0x0000018e,0x0000000f,0x00006461,0x00040006,0x0000018e,0x00000010, + 0x00006579,0x00040006,0x0000018e,0x00000011,0x00003376,0x00040006,0x0000018e,0x00000012, + 0x00003377,0x00040006,0x0000018e,0x00000013,0x00006462,0x00040006,0x0000018e,0x00000014, + 0x00006767,0x00030005,0x00000190,0x0000006b,0x00030005,0x000001a8,0x0000316d,0x00030005, + 0x000001b2,0x00003954,0x00030005,0x000001b3,0x00004351,0x00030005,0x000001b4,0x00003159, + 0x00030005,0x000001b5,0x00003053,0x00040047,0x00000088,0x00000001,0x00000007,0x00040047, + 0x000000a4,0x00000001,0x00000002,0x00030047,0x000000e4,0x00000000,0x00040047,0x000000e4, + 0x00000021,0x00000009,0x00040047,0x000000e4,0x00000022,0x00000000,0x00030047,0x000000e8, + 0x00000000,0x00040047,0x000000e8,0x00000021,0x00000009,0x00040047,0x000000e8,0x00000022, + 0x00000000,0x00030047,0x0000010a,0x00000000,0x00040047,0x0000010a,0x00000021,0x0000000c, + 0x00040047,0x0000010a,0x00000022,0x00000001,0x00030047,0x0000010c,0x00000000,0x00040047, + 0x0000010c,0x00000021,0x0000000c,0x00040047,0x0000010c,0x00000022,0x00000001,0x00040047, + 0x00000131,0x0000000b,0x0000000f,0x00040047,0x00000137,0x0000001e,0x00000000,0x00030047, + 0x0000013d,0x00000000,0x00040047,0x0000013d,0x00000021,0x0000000b,0x00040047,0x0000013d, + 0x00000022,0x00000000,0x00030047,0x0000013e,0x00000000,0x00030047,0x0000013f,0x00000000, + 0x00040047,0x0000013f,0x00000021,0x0000000b,0x00040047,0x0000013f,0x00000022,0x00000000, + 0x00030047,0x00000140,0x00000000,0x00040047,0x00000143,0x0000001e,0x00000001,0x00030047, + 0x00000145,0x00000000,0x00030047,0x00000146,0x00000000,0x00030047,0x0000014b,0x00000000, + 0x00040047,0x0000014c,0x00000001,0x00000001,0x00040047,0x00000150,0x0000001e,0x00000005, + 0x00030047,0x00000158,0x00000000,0x00030047,0x0000015b,0x00000000,0x00040047,0x0000015c, + 0x00000001,0x00000000,0x00030047,0x00000160,0x00000000,0x00030047,0x00000160,0x0000000e, + 0x00040047,0x00000160,0x0000001e,0x00000004,0x00030047,0x00000161,0x00000000,0x00030047, + 0x00000169,0x00000017,0x00040047,0x00000169,0x00000021,0x00000001,0x00040047,0x00000169, + 0x00000022,0x00000002,0x00030047,0x00000172,0x00000000,0x00030047,0x00000175,0x00000000, + 0x00030047,0x0000017b,0x00000000,0x00030047,0x00000182,0x00000000,0x00030047,0x00000186, + 0x00000000,0x00030047,0x00000189,0x00000000,0x00030047,0x0000018c,0x00000000,0x00030047, + 0x0000018e,0x00000002,0x00050048,0x0000018e,0x00000000,0x00000023,0x00000000,0x00050048, + 0x0000018e,0x00000001,0x00000023,0x00000004,0x00050048,0x0000018e,0x00000002,0x00000023, + 0x00000008,0x00050048,0x0000018e,0x00000003,0x00000023,0x0000000c,0x00050048,0x0000018e, + 0x00000004,0x00000023,0x00000010,0x00050048,0x0000018e,0x00000005,0x00000023,0x00000014, + 0x00050048,0x0000018e,0x00000006,0x00000023,0x00000018,0x00050048,0x0000018e,0x00000007, + 0x00000023,0x0000001c,0x00050048,0x0000018e,0x00000008,0x00000023,0x00000020,0x00050048, + 0x0000018e,0x00000009,0x00000023,0x00000030,0x00050048,0x0000018e,0x0000000a,0x00000023, + 0x00000038,0x00050048,0x0000018e,0x0000000b,0x00000023,0x00000040,0x00050048,0x0000018e, + 0x0000000c,0x00000023,0x00000044,0x00050048,0x0000018e,0x0000000d,0x00000023,0x00000048, + 0x00050048,0x0000018e,0x0000000e,0x00000023,0x0000004c,0x00050048,0x0000018e,0x0000000f, + 0x00000023,0x00000050,0x00050048,0x0000018e,0x00000010,0x00000023,0x00000054,0x00050048, + 0x0000018e,0x00000011,0x00000023,0x00000058,0x00050048,0x0000018e,0x00000012,0x00000023, + 0x0000005c,0x00050048,0x0000018e,0x00000013,0x00000023,0x00000060,0x00050048,0x0000018e, + 0x00000014,0x00000023,0x00000064,0x00040047,0x00000190,0x00000021,0x00000000,0x00040047, + 0x00000190,0x00000022,0x00000000,0x00030047,0x00000195,0x00000000,0x00030047,0x000001a8, + 0x00000000,0x00040047,0x000001a8,0x0000001e,0x00000000,0x00030047,0x000001b2,0x00000000, + 0x00040047,0x000001b2,0x00000021,0x0000000a,0x00040047,0x000001b2,0x00000022,0x00000000, + 0x00030047,0x000001b3,0x00000000,0x00040047,0x000001b3,0x00000021,0x0000000a,0x00040047, + 0x000001b3,0x00000022,0x00000000,0x00030047,0x000001b4,0x00000000,0x00030047,0x000001b4, + 0x0000000e,0x00040047,0x000001b4,0x0000001e,0x00000006,0x00030047,0x000001b5,0x00000017, + 0x00040047,0x000001b5,0x00000021,0x00000003,0x00040047,0x000001b5,0x00000022,0x00000002, + 0x00030047,0x000001d2,0x00000000,0x00030047,0x000001fc,0x00000000,0x00030047,0x000001fd, + 0x00000000,0x00030047,0x00000202,0x00000000,0x00030047,0x00000205,0x00000000,0x00030047, + 0x0000020a,0x00000000,0x00030047,0x0000020c,0x00000000,0x00030047,0x0000020d,0x00000000, + 0x00030047,0x0000021a,0x00000000,0x00030047,0x0000021b,0x00000000,0x00030047,0x00000220, + 0x00000000,0x00030047,0x00000228,0x00000000,0x00030047,0x0000022f,0x00000000,0x00030047, + 0x0000023e,0x00000000,0x00030047,0x00000240,0x00000000,0x00030047,0x00000245,0x00000000, + 0x00030047,0x00000249,0x00000000,0x00030047,0x00000267,0x00000000,0x00030047,0x00000269, + 0x00000000,0x00030047,0x0000026a,0x00000000,0x00030047,0x0000026c,0x00000000,0x00030047, + 0x0000026e,0x00000000,0x00030047,0x0000026f,0x00000000,0x00030047,0x00000289,0x00000000, + 0x00030047,0x0000028a,0x00000000,0x00030047,0x0000029c,0x00000000,0x00030047,0x0000029d, + 0x00000000,0x00030047,0x000002a0,0x00000000,0x00030047,0x000002a2,0x00000000,0x00030047, + 0x000002a6,0x00000000,0x00030047,0x000002ae,0x00000000,0x00030047,0x000002b1,0x00000000, + 0x00030047,0x000002b3,0x00000000,0x00030047,0x000002b5,0x00000000,0x00030047,0x000002bc, + 0x00000000,0x00030047,0x000002be,0x00000000,0x00030047,0x000002c0,0x00000000,0x00030047, + 0x000002c2,0x00000000,0x00030047,0x000002ca,0x00000000,0x00030047,0x000002cc,0x00000000, + 0x00030047,0x000002ce,0x00000000,0x00030047,0x000002cf,0x00000000,0x00030047,0x000002d6, + 0x00000000,0x00030047,0x000002d8,0x00000000,0x00030047,0x000002d9,0x00000000,0x00030047, + 0x000002d7,0x00000000,0x00030047,0x000002d5,0x00000000,0x00030047,0x000002da,0x00000000, + 0x00030047,0x000002dd,0x00000000,0x00030047,0x000002e2,0x00000000,0x00030047,0x000002e3, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, + 0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017,0x00000012,0x00000006, + 0x00000003,0x00040017,0x00000021,0x00000006,0x00000002,0x00040015,0x0000003f,0x00000020, + 0x00000000,0x0004002b,0x00000006,0x00000053,0x00000000,0x00020014,0x00000054,0x0004002b, + 0x00000006,0x00000059,0x3f800000,0x0004002b,0x00000006,0x00000072,0x3d897143,0x0004002b, + 0x00000006,0x00000076,0x3bbf4590,0x0004002b,0x00000006,0x0000007d,0x4253ee82,0x00030030, + 0x00000054,0x00000088,0x00030030,0x00000054,0x000000a4,0x00050034,0x00000054,0x000000a5, + 0x000000a8,0x000000a4,0x0004002b,0x00000006,0x000000b4,0xbf800000,0x0004002b,0x00000006, + 0x000000d2,0x3f7f8000,0x0004002b,0x00000006,0x000000d5,0x3a800000,0x0004002b,0x00000006, + 0x000000d8,0x3b000000,0x00090019,0x000000e2,0x00000006,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x000000e3,0x00000000,0x000000e2,0x0004003b, + 0x000000e3,0x000000e4,0x00000000,0x0002001a,0x000000e6,0x00040020,0x000000e7,0x00000000, + 0x000000e6,0x0004003b,0x000000e7,0x000000e8,0x00000000,0x0003001b,0x000000ea,0x000000e2, + 0x00050034,0x00000054,0x000000f5,0x000000a8,0x000000a4,0x0004002b,0x00000006,0x00000108, + 0x40000000,0x0004003b,0x000000e3,0x0000010a,0x00000000,0x0004003b,0x000000e7,0x0000010c, + 0x00000000,0x00050034,0x00000054,0x00000118,0x000000a8,0x000000a4,0x00040015,0x0000012c, + 0x00000020,0x00000001,0x00040017,0x0000012d,0x0000012c,0x00000002,0x00040020,0x00000130, + 0x00000001,0x00000007,0x0004003b,0x00000130,0x00000131,0x00000001,0x0004003b,0x00000130, + 0x00000137,0x00000001,0x0004003b,0x000000e3,0x0000013d,0x00000000,0x0004003b,0x000000e7, + 0x0000013f,0x00000000,0x00040020,0x00000142,0x00000001,0x00000021,0x0004003b,0x00000142, + 0x00000143,0x00000001,0x00030030,0x00000054,0x0000014c,0x0004003b,0x00000130,0x00000150, + 0x00000001,0x00030030,0x00000054,0x0000015c,0x00040020,0x0000015f,0x00000001,0x00000006, + 0x0004003b,0x0000015f,0x00000160,0x00000001,0x00090019,0x00000167,0x0000003f,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x00000168,0x00000000, + 0x00000167,0x0004003b,0x00000168,0x00000169,0x00000000,0x00040017,0x0000016c,0x0000003f, + 0x00000004,0x00040017,0x0000018d,0x0000012c,0x00000004,0x0017001e,0x0000018e,0x00000006, + 0x00000006,0x00000006,0x00000006,0x0000003f,0x0000003f,0x0000003f,0x0000003f,0x0000018d, + 0x00000021,0x00000021,0x0000003f,0x00000006,0x0000003f,0x00000006,0x00000006,0x0000003f, + 0x00000006,0x00000006,0x00000006,0x0000003f,0x00040020,0x0000018f,0x00000002,0x0000018e, + 0x0004003b,0x0000018f,0x00000190,0x00000002,0x0004002b,0x0000012c,0x00000191,0x00000011, + 0x0004002b,0x0000012c,0x00000192,0x00000012,0x00040020,0x0000019a,0x00000002,0x00000006, + 0x00040020,0x000001a7,0x00000003,0x00000007,0x0004003b,0x000001a7,0x000001a8,0x00000003, + 0x0004003b,0x000000e7,0x000001b2,0x00000000,0x0004003b,0x000000e3,0x000001b3,0x00000000, + 0x0004003b,0x0000015f,0x000001b4,0x00000001,0x0004003b,0x00000168,0x000001b5,0x00000000, + 0x00030001,0x00000007,0x000002d2,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003d,0x00000007,0x00000132,0x00000131,0x0007004f,0x00000021, + 0x00000133,0x00000132,0x00000132,0x00000000,0x00000001,0x0006000c,0x00000021,0x00000134, + 0x00000001,0x00000008,0x00000133,0x0004006e,0x0000012d,0x00000135,0x00000134,0x0004003d, + 0x00000007,0x00000139,0x00000137,0x00050051,0x00000006,0x000001c6,0x00000139,0x00000003, + 0x000500be,0x00000054,0x000001c7,0x000001c6,0x00000053,0x000300f7,0x00000233,0x00000000, + 0x000400fa,0x000001c7,0x000001c8,0x000001d6,0x000200f8,0x000001c8,0x000300f7,0x000001d5, + 0x00000000,0x000400fa,0x000000a5,0x000001cb,0x000001cf,0x000200f8,0x000001cb,0x0005008e, + 0x00000007,0x000001ce,0x00000139,0x00000059,0x000200f9,0x000001d5,0x000200f8,0x000001cf, + 0x00050051,0x00000006,0x000001d2,0x00000139,0x00000003,0x00050085,0x00000006,0x000001d3, + 0x000001d2,0x00000059,0x00060052,0x00000007,0x000002a6,0x000001d3,0x00000139,0x00000003, + 0x000200f9,0x000001d5,0x000200f8,0x000001d5,0x000700f5,0x00000007,0x000002d6,0x000001ce, + 0x000001cb,0x000002a6,0x000001cf,0x000200f9,0x00000233,0x000200f8,0x000001d6,0x000500ba, + 0x00000054,0x000001d9,0x000001c6,0x000000b4,0x000300f7,0x00000232,0x00000000,0x000400fa, + 0x000001d9,0x000001da,0x00000215,0x000200f8,0x000001da,0x00050051,0x00000006,0x000001dc, + 0x00000139,0x00000002,0x000500ba,0x00000054,0x000001dd,0x000001dc,0x00000053,0x000300f7, + 0x000001e5,0x00000000,0x000400fa,0x000001dd,0x000001de,0x000001e1,0x000200f8,0x000001de, + 0x00050051,0x00000006,0x000001e0,0x00000139,0x00000000,0x000200f9,0x000001e5,0x000200f8, + 0x000001e1,0x0007004f,0x00000021,0x000001e3,0x00000139,0x00000139,0x00000000,0x00000001, + 0x0006000c,0x00000006,0x000001e4,0x00000001,0x00000042,0x000001e3,0x000200f9,0x000001e5, + 0x000200f8,0x000001e5,0x000700f5,0x00000006,0x000002d3,0x000001e0,0x000001de,0x000001e4, + 0x000001e1,0x0008000c,0x00000006,0x000001e8,0x00000001,0x0000002b,0x000002d3,0x00000053, + 0x00000059,0x0006000c,0x00000006,0x000001eb,0x00000001,0x00000004,0x000001dc,0x000500ba, + 0x00000054,0x000001ed,0x000001eb,0x00000059,0x000300f7,0x000001f7,0x00000000,0x000400fa, + 0x000001ed,0x000001ee,0x000001f2,0x000200f8,0x000001ee,0x00050085,0x00000006,0x000001f0, + 0x000000d2,0x000001e8,0x00050081,0x00000006,0x000001f1,0x000001f0,0x000000d5,0x000200f9, + 0x000001f7,0x000200f8,0x000001f2,0x00050085,0x00000006,0x000001f4,0x000000d8,0x000001e8, + 0x00050081,0x00000006,0x000001f6,0x000001f4,0x000001eb,0x000200f9,0x000001f7,0x000200f8, + 0x000001f7,0x000700f5,0x00000006,0x000002d4,0x000001f1,0x000001ee,0x000001f6,0x000001f2, + 0x0004007f,0x00000006,0x000001fb,0x000001c6,0x0004003d,0x000000e2,0x000001fc,0x000000e4, + 0x0004003d,0x000000e6,0x000001fd,0x000000e8,0x00050056,0x000000ea,0x000001fe,0x000001fc, + 0x000001fd,0x00050050,0x00000021,0x00000201,0x000002d4,0x000001fb,0x00070058,0x00000007, + 0x00000202,0x000001fe,0x00000201,0x00000002,0x00000053,0x00050051,0x00000006,0x00000205, + 0x00000202,0x00000003,0x00050085,0x00000006,0x00000206,0x00000205,0x00000059,0x00060052, + 0x00000007,0x000002ae,0x00000206,0x00000202,0x00000003,0x000300f7,0x00000214,0x00000000, + 0x000400fa,0x000000f5,0x00000208,0x00000214,0x000200f8,0x00000208,0x00050051,0x00000006, + 0x0000020a,0x000002ae,0x00000003,0x0008004f,0x00000012,0x0000020c,0x000002ae,0x000002ae, + 0x00000000,0x00000001,0x00000002,0x0005008e,0x00000012,0x0000020d,0x0000020c,0x0000020a, + 0x00050051,0x00000006,0x0000020f,0x0000020d,0x00000000,0x00060052,0x00000007,0x000002b1, + 0x0000020f,0x000002ae,0x00000000,0x00050051,0x00000006,0x00000211,0x0000020d,0x00000001, + 0x00060052,0x00000007,0x000002b3,0x00000211,0x000002b1,0x00000001,0x00050051,0x00000006, + 0x00000213,0x0000020d,0x00000002,0x00060052,0x00000007,0x000002b5,0x00000213,0x000002b3, + 0x00000002,0x000200f9,0x00000214,0x000200f8,0x00000214,0x000700f5,0x00000007,0x000002d8, + 0x000002ae,0x000001f7,0x000002b5,0x00000208,0x000200f9,0x00000232,0x000200f8,0x00000215, + 0x0004007f,0x00000006,0x00000218,0x000001c6,0x00050083,0x00000006,0x00000219,0x00000218, + 0x00000108,0x0004003d,0x000000e2,0x0000021a,0x0000010a,0x0004003d,0x000000e6,0x0000021b, + 0x0000010c,0x00050056,0x000000ea,0x0000021c,0x0000021a,0x0000021b,0x0007004f,0x00000021, + 0x0000021e,0x00000139,0x00000139,0x00000000,0x00000001,0x00070058,0x00000007,0x00000220, + 0x0000021c,0x0000021e,0x00000002,0x00000219,0x00050051,0x00000006,0x00000222,0x00000139, + 0x00000002,0x00050085,0x00000006,0x00000224,0x00000222,0x00000059,0x000300f7,0x00000231, + 0x00000000,0x000400fa,0x00000118,0x00000225,0x00000229,0x000200f8,0x00000225,0x0005008e, + 0x00000007,0x00000228,0x00000220,0x00000224,0x000200f9,0x00000231,0x000200f8,0x00000229, + 0x0008004f,0x00000012,0x0000023e,0x00000220,0x00000220,0x00000000,0x00000001,0x00000002, + 0x00050051,0x00000006,0x00000240,0x00000220,0x00000003,0x000500b7,0x00000054,0x00000241, + 0x00000240,0x00000053,0x000300f7,0x00000247,0x00000000,0x000400fa,0x00000241,0x00000242, + 0x00000246,0x000200f8,0x00000242,0x00050088,0x00000006,0x00000245,0x00000059,0x00000240, + 0x000200f9,0x00000247,0x000200f8,0x00000246,0x000200f9,0x00000247,0x000200f8,0x00000247, + 0x000700f5,0x00000006,0x000002cf,0x00000245,0x00000242,0x00000053,0x00000246,0x0005008e, + 0x00000012,0x00000249,0x0000023e,0x000002cf,0x00050085,0x00000006,0x0000022f,0x00000240, + 0x00000224,0x00050051,0x00000006,0x0000024f,0x00000249,0x00000000,0x00060052,0x00000007, + 0x000002bc,0x0000024f,0x000002d2,0x00000000,0x00050051,0x00000006,0x00000251,0x00000249, + 0x00000001,0x00060052,0x00000007,0x000002be,0x00000251,0x000002bc,0x00000001,0x00050051, + 0x00000006,0x00000253,0x00000249,0x00000002,0x00060052,0x00000007,0x000002c0,0x00000253, + 0x000002be,0x00000002,0x00060052,0x00000007,0x000002c2,0x0000022f,0x000002c0,0x00000003, + 0x000200f9,0x00000231,0x000200f8,0x00000231,0x000700f5,0x00000007,0x000002d9,0x00000228, + 0x00000225,0x000002c2,0x00000247,0x000200f9,0x00000232,0x000200f8,0x00000232,0x000700f5, + 0x00000007,0x000002d7,0x000002d8,0x00000214,0x000002d9,0x00000231,0x000200f9,0x00000233, + 0x000200f8,0x00000233,0x000700f5,0x00000007,0x000002d5,0x000002d6,0x000001d5,0x000002d7, + 0x00000232,0x0004003d,0x000000e2,0x0000013e,0x0000013d,0x0004003d,0x000000e6,0x00000140, + 0x0000013f,0x00050056,0x000000ea,0x00000141,0x0000013e,0x00000140,0x0004003d,0x00000021, + 0x00000144,0x00000143,0x00070058,0x00000007,0x00000145,0x00000141,0x00000144,0x00000002, + 0x00000053,0x00050051,0x00000006,0x00000146,0x00000145,0x00000000,0x0008000c,0x00000006, + 0x0000014b,0x00000001,0x0000002b,0x00000146,0x00000053,0x00000059,0x000300f7,0x0000014e, + 0x00000000,0x000400fa,0x0000014c,0x0000014d,0x0000014e,0x000200f8,0x0000014d,0x0004003d, + 0x00000007,0x00000152,0x00000150,0x0007004f,0x00000021,0x00000267,0x00000152,0x00000152, + 0x00000000,0x00000001,0x0007004f,0x00000021,0x00000269,0x00000152,0x00000152,0x00000002, + 0x00000003,0x0007000c,0x00000021,0x0000026a,0x00000001,0x00000025,0x00000267,0x00000269, + 0x00050051,0x00000006,0x0000026c,0x0000026a,0x00000000,0x00050051,0x00000006,0x0000026e, + 0x0000026a,0x00000001,0x0007000c,0x00000006,0x0000026f,0x00000001,0x00000025,0x0000026c, + 0x0000026e,0x0007000c,0x00000006,0x00000158,0x00000001,0x00000028,0x0000026f,0x00000053, + 0x0007000c,0x00000006,0x0000015b,0x00000001,0x00000025,0x00000158,0x0000014b,0x000200f9, + 0x0000014e,0x000200f8,0x0000014e,0x000700f5,0x00000006,0x000002dd,0x0000014b,0x00000233, + 0x0000015b,0x0000014d,0x000114f4,0x000300f7,0x0000015e,0x00000000,0x000400fa,0x0000015c, + 0x0000015d,0x0000015e,0x000200f8,0x0000015d,0x0004003d,0x00000006,0x00000161,0x00000160, + 0x000500b7,0x00000054,0x00000162,0x00000161,0x00000053,0x000200f9,0x0000015e,0x000200f8, + 0x0000015e,0x000700f5,0x00000054,0x00000163,0x0000015c,0x0000014e,0x00000162,0x0000015d, + 0x000300f7,0x00000165,0x00000000,0x000400fa,0x00000163,0x00000164,0x00000165,0x000200f8, + 0x00000164,0x0004003d,0x00000167,0x0000016a,0x00000169,0x00050062,0x0000016c,0x0000016d, + 0x0000016a,0x00000135,0x00050051,0x0000003f,0x0000016e,0x0000016d,0x00000000,0x0006000c, + 0x00000021,0x0000016f,0x00000001,0x0000003e,0x0000016e,0x00050051,0x00000006,0x00000172, + 0x0000016f,0x00000001,0x0004003d,0x00000006,0x00000175,0x00000160,0x000500b4,0x00000054, + 0x00000176,0x00000172,0x00000175,0x000300f7,0x00000179,0x00000000,0x000400fa,0x00000176, + 0x00000178,0x0000017c,0x000200f8,0x00000178,0x00050051,0x00000006,0x0000017b,0x0000016f, + 0x00000000,0x000200f9,0x00000179,0x000200f8,0x0000017c,0x000200f9,0x00000179,0x000200f8, + 0x00000179,0x000700f5,0x00000006,0x000002da,0x0000017b,0x00000178,0x00000053,0x0000017c, + 0x0007000c,0x00000006,0x00000182,0x00000001,0x00000028,0x000002da,0x00000053,0x0007000c, + 0x00000006,0x00000186,0x00000001,0x00000028,0x00000182,0x00000053,0x0007000c,0x00000006, + 0x00000189,0x00000001,0x00000025,0x000002dd,0x00000186,0x000200f9,0x00000165,0x000200f8, + 0x00000165,0x000700f5,0x00000006,0x000002e2,0x000002dd,0x0000015e,0x00000189,0x00000179, + 0x000114f5,0x0005008e,0x00000007,0x0000018c,0x000002d5,0x000002e2,0x0008004f,0x00000012, + 0x00000195,0x0000018c,0x0000018c,0x00000000,0x00000001,0x00000002,0x00050041,0x0000019a, + 0x0000019b,0x00000190,0x00000191,0x0004003d,0x00000006,0x0000019c,0x0000019b,0x00050041, + 0x0000019a,0x0000019e,0x00000190,0x00000192,0x0004003d,0x00000006,0x0000019f,0x0000019e, + 0x000300f7,0x0000028d,0x00000000,0x000400fa,0x00000088,0x00000283,0x0000028b,0x000200f8, + 0x00000283,0x00050051,0x00000006,0x00000294,0x00000133,0x00000000,0x00050085,0x00000006, + 0x00000295,0x00000072,0x00000294,0x00050051,0x00000006,0x00000297,0x00000133,0x00000001, + 0x00050085,0x00000006,0x00000298,0x00000076,0x00000297,0x00050081,0x00000006,0x00000299, + 0x00000295,0x00000298,0x0006000c,0x00000006,0x0000029a,0x00000001,0x0000000a,0x00000299, + 0x00050085,0x00000006,0x0000029c,0x0000007d,0x0000029a,0x0006000c,0x00000006,0x0000029d, + 0x00000001,0x0000000a,0x0000029c,0x00050085,0x00000006,0x000002a0,0x0000029d,0x0000019c, + 0x00050081,0x00000006,0x000002a2,0x000002a0,0x0000019f,0x00060050,0x00000012,0x00000289, + 0x000002a2,0x000002a2,0x000002a2,0x00050081,0x00000012,0x0000028a,0x00000289,0x00000195, + 0x000200f9,0x0000028d,0x000200f8,0x0000028b,0x000200f9,0x0000028d,0x000200f8,0x0000028d, + 0x000700f5,0x00000012,0x000002e3,0x0000028a,0x00000283,0x00000195,0x0000028b,0x00050051, + 0x00000006,0x000001a2,0x000002e3,0x00000000,0x00060052,0x00000007,0x000002ca,0x000001a2, + 0x0000018c,0x00000000,0x00050051,0x00000006,0x000001a4,0x000002e3,0x00000001,0x00060052, + 0x00000007,0x000002cc,0x000001a4,0x000002ca,0x00000001,0x00050051,0x00000006,0x000001a6, + 0x000002e3,0x00000002,0x00060052,0x00000007,0x000002ce,0x000001a6,0x000002cc,0x00000002, + 0x0003003e,0x000001a8,0x000002ce,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..803833f7cbc15ad3b63c58723f953bfae83d08c0 GIT binary patch literal 7892 zcmaKwdyJe_8OBd%re$dtN@*+Ql4hq!f z`JVSV&-aG_ z1%8DpyGgl2xnFrm`KaJ*YLA04DXT-DX4W7@4t|{{fAgm9xqQot=?Ae&bB}Y;3i`^mAl)I{gK* zyPVx5`*SzV=r5E#=KSZ%{(@`IJlUVuSXumL*%hb1NcIkmx0PQkyHDe0_I%lSjl9{H z$lmMPvq1J9jhmHUD*H}nFO)s({IyL&QS~$ak7)4NqhR*dc%0Lp3U7_`_>AzDIKS+@ z9Z~bF@Sx_XNAtpZlbP&C>?6@;E_xJuT2B&X;H)y^X7(~+5?aS8NxHiYpR=7^ban8VPbR2UD*XuaeJY2uy=qKD($8qk!ZFd}J z58O`2asI#!IgT-c8&zgaa1LdKNoFsro3hj4Ad{s8=A5eIOoIKshJ-FA8`1P z!%sT=l*5M|e%j$5JNy%epKT6gjlOB%9m-~a~5H9o?)|pvC(5^qmA!k+3WRe zQ6^m{8|`3Xaqgv(^TGHX34iZ;vumJhg+RJqdIU`Iz;^VciGVsj7iWqbn=Cl`6<0xkAXch-e-KW;>hr5?fG$RHf{Ts{Aeq6&^Bz|dvL5v+VO2=-m7Lm zDw{ot{}aM!iHZFq+3ZvHF!8W?H^O1F_IT%!u$f1D=V3FxyuXlOGgiE_NV61$xTjR% zjoNqA%NUV}|8Ftech-qTw^Dwrp*~qz*{g)%$Rr-kYI#=A)iSV~l+jfbgEhKFnKFxc zi!keOi)y0JzZ8a}{^Rj1_?2vU&Y<^HvWkW(eV~|>{aX1IW!eiyb6QW+aF+Z=_DfL% zeps>T(@A0K;~aZm{`e6Gt+nY?)X=7H#CE#^QuL;w4&OZ9JQW_F{r|fm*#nBIJZT`J5?Lcm^-jEG%UENA`FN9*(7g(*YJ_`N4gqR*7QrTi~t`UAH4{f98`7wY|b zob!JQ!}Fe@55&R`fAf1=nD>tNdsiGh?eKp1Ti<`Hz7wA|peN=%Y9oFBk1%V1J#$9( zhr-i(V!x>;cS+tq+tg0pJ^z)B2EJchR@^Mbrw(FmkLxfc8!ct}Pu7LaIrmV?{hFU6 z8{V&Z?p^SvWsDceCNajm`kns4xGoRKsp0>xi^HDc*j1T=r z%l>5?*t0gjON5!<`{FvgTsB;jIGc0s`P>m~&bjM1%eFbcN;VpJ+mlO$*^hot+T6FO z3?DT557cS>UM7qWyshg`%7C|hw1Pq<=9s(5HL^dYOy9tEzVhusUHH>~{LrAaIp;eB z4Vk2HQp~icEtauPex@`IeBwKfUgTV9tC7E`MY_yDnX^+c>#|PfD zgR;@;zoC6z20T8Ve?bOqqnxqy^TE8>+T|OCd1D^&VJy(v+U03lzF}DFtbP25gLajk zj4Mymo)+fa$GZ?e;@J9b6}OHY&$KpS?w_{4HwdGFN0U|iJB7J}+M4F~GIa0?ecpN2 zEsk=My;E+L4aGZ!a(kz6hHZ{o)>E(WZOU-;2}~P!mk$VY*R?%YRK;*)5)UgYxiZ?v z95gFRR?jgJXs=Nw23nhAzNslE8CQuMKE&WXQ59z~@Ihl`{0>OjwNXc3t&HCV%?};p z!W>$EdD>p!dz5nK6+gz}?M1Vack7phNsQS};V&t}F=k-KjCSUQhm>tE4-3Q5Ch9dG zp47{J9}y-dZ9z{w=Bc13i8|4YD#KAHm^zDkjw$nvFsyT+tmk;-*67KYa<{KUo_KbT zt%}osXpQAI{xy+SX8oEHN5786Gir}8I(XW;S5FdcrR*-{uPW14u*JSxnAjx713xrq zy$x^k!fyun5r=U^YxBELSpUh~qw{lrzbixM%lO?DKh`Akj+Xjue0f^^XH<@cIm0h$ zo7RQB2Obp1{zqr${y}l@WD*Y*hYcD(zJtD}%(oNYOE$)bB5#`SN6n*7^8;ac#{3}y zDlz8!^}J8^Hvkecpsas19fncWq?D~vy7c1L|e z7(afiq}==u3G=%M<)(eoX(>1DQ^J%n4p!G;+3@tcUptI@(gE4o|6951J literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.h new file mode 100644 index 000000000..5a97135ab --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.h @@ -0,0 +1,715 @@ +#pragma once + +const uint32_t draw_clockwise_atlas_blit_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000def,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x000b000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x00000367,0x0000036d,0x00000379,0x00000386,0x00000396,0x000003ca,0x00030010, + 0x00000004,0x00000007,0x00030010,0x00000004,0x000014f6,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x665f4252,0x6d676172,0x5f746e65,0x64616873,0x695f7265,0x7265746e, + 0x6b636f6c,0x00000000,0x00090004,0x415f4c47,0x735f4252,0x65646168,0x6d695f72,0x5f656761, + 0x64616f6c,0x6f74735f,0x00006572,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x0000010f, + 0x0000674e,0x00030005,0x00000281,0x0000674d,0x00030005,0x000002dc,0x00006749,0x00030005, + 0x0000031c,0x00004444,0x00030005,0x00000320,0x00006277,0x00030005,0x00000341,0x00004344, + 0x00030005,0x00000343,0x00003552,0x00060005,0x00000367,0x465f6c67,0x43676172,0x64726f6f, + 0x00000000,0x00030005,0x0000036d,0x0000316b,0x00030005,0x00000373,0x00004356,0x00030005, + 0x00000375,0x00003949,0x00030005,0x00000379,0x00003243,0x00030005,0x00000382,0x00006748, + 0x00030005,0x00000386,0x0000304e,0x00030005,0x00000392,0x00006747,0x00030005,0x00000396, + 0x00003346,0x00030005,0x0000039f,0x00003065,0x00030005,0x000003c3,0x0000306a,0x00030005, + 0x000003ca,0x00003159,0x00030005,0x000003f5,0x0000424d,0x00040006,0x000003f5,0x00000000, + 0x00006250,0x00040006,0x000003f5,0x00000001,0x00006359,0x00040006,0x000003f5,0x00000002, + 0x00006552,0x00040006,0x000003f5,0x00000003,0x00006553,0x00040006,0x000003f5,0x00000004, + 0x0000366d,0x00040006,0x000003f5,0x00000005,0x0000676d,0x00040006,0x000003f5,0x00000006, + 0x00006544,0x00040006,0x000003f5,0x00000007,0x00006545,0x00040006,0x000003f5,0x00000008, + 0x00003755,0x00040006,0x000003f5,0x00000009,0x0000676a,0x00040006,0x000003f5,0x0000000a, + 0x0000635a,0x00040006,0x000003f5,0x0000000b,0x00003157,0x00040006,0x000003f5,0x0000000c, + 0x0000676e,0x00040006,0x000003f5,0x0000000d,0x00003559,0x00040006,0x000003f5,0x0000000e, + 0x0000324f,0x00040006,0x000003f5,0x0000000f,0x00006461,0x00040006,0x000003f5,0x00000010, + 0x00006579,0x00040006,0x000003f5,0x00000011,0x00003376,0x00040006,0x000003f5,0x00000012, + 0x00003377,0x00040006,0x000003f5,0x00000013,0x00006462,0x00040006,0x000003f5,0x00000014, + 0x00006767,0x00030005,0x000003f7,0x0000006b,0x00030005,0x0000041f,0x00003954,0x00030005, + 0x00000420,0x00004351,0x00030005,0x00000421,0x00003466,0x00030005,0x00000422,0x00003053, + 0x00040047,0x0000010f,0x00000001,0x00000007,0x00040047,0x00000281,0x00000001,0x00000006, + 0x00040047,0x000002dc,0x00000001,0x00000002,0x00030047,0x0000031c,0x00000000,0x00040047, + 0x0000031c,0x00000021,0x00000009,0x00040047,0x0000031c,0x00000022,0x00000000,0x00030047, + 0x00000320,0x00000000,0x00040047,0x00000320,0x00000021,0x00000009,0x00040047,0x00000320, + 0x00000022,0x00000000,0x00030047,0x00000341,0x00000000,0x00040047,0x00000341,0x00000021, + 0x0000000c,0x00040047,0x00000341,0x00000022,0x00000001,0x00030047,0x00000343,0x00000000, + 0x00040047,0x00000343,0x00000021,0x0000000c,0x00040047,0x00000343,0x00000022,0x00000001, + 0x00040047,0x00000367,0x0000000b,0x0000000f,0x00040047,0x0000036d,0x0000001e,0x00000000, + 0x00030047,0x00000373,0x00000000,0x00040047,0x00000373,0x00000021,0x0000000b,0x00040047, + 0x00000373,0x00000022,0x00000000,0x00030047,0x00000374,0x00000000,0x00030047,0x00000375, + 0x00000000,0x00040047,0x00000375,0x00000021,0x0000000b,0x00040047,0x00000375,0x00000022, + 0x00000000,0x00030047,0x00000376,0x00000000,0x00040047,0x00000379,0x0000001e,0x00000001, + 0x00030047,0x0000037b,0x00000000,0x00030047,0x0000037c,0x00000000,0x00030047,0x00000381, + 0x00000000,0x00040047,0x00000382,0x00000001,0x00000001,0x00040047,0x00000386,0x0000001e, + 0x00000005,0x00030047,0x0000038e,0x00000000,0x00030047,0x00000391,0x00000000,0x00040047, + 0x00000392,0x00000001,0x00000000,0x00030047,0x00000396,0x00000000,0x00030047,0x00000396, + 0x0000000e,0x00040047,0x00000396,0x0000001e,0x00000004,0x00030047,0x00000397,0x00000000, + 0x00030047,0x0000039f,0x00000017,0x00040047,0x0000039f,0x00000021,0x00000001,0x00040047, + 0x0000039f,0x00000022,0x00000002,0x00030047,0x000003a8,0x00000000,0x00030047,0x000003ab, + 0x00000000,0x00030047,0x000003b1,0x00000000,0x00030047,0x000003b8,0x00000000,0x00030047, + 0x000003bc,0x00000000,0x00030047,0x000003bf,0x00000000,0x00030047,0x000003c3,0x00000000, + 0x00030047,0x000003c3,0x00000017,0x00040047,0x000003c3,0x00000021,0x00000000,0x00040047, + 0x000003c3,0x00000022,0x00000002,0x00030047,0x000003c4,0x00000000,0x00030047,0x000003c6, + 0x00000000,0x00030047,0x000003ca,0x00000000,0x00030047,0x000003ca,0x0000000e,0x00040047, + 0x000003ca,0x0000001e,0x00000006,0x00030047,0x000003cc,0x00000000,0x00030047,0x000003d4, + 0x00000000,0x00030047,0x000003e2,0x00000000,0x00030047,0x000003e3,0x00000000,0x00030047, + 0x000003e6,0x00000000,0x00030047,0x000003e8,0x00000000,0x00030047,0x000003e9,0x00000000, + 0x00030047,0x000003f3,0x00000000,0x00030047,0x000003f5,0x00000002,0x00050048,0x000003f5, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000003f5,0x00000001,0x00000023,0x00000004, + 0x00050048,0x000003f5,0x00000002,0x00000023,0x00000008,0x00050048,0x000003f5,0x00000003, + 0x00000023,0x0000000c,0x00050048,0x000003f5,0x00000004,0x00000023,0x00000010,0x00050048, + 0x000003f5,0x00000005,0x00000023,0x00000014,0x00050048,0x000003f5,0x00000006,0x00000023, + 0x00000018,0x00050048,0x000003f5,0x00000007,0x00000023,0x0000001c,0x00050048,0x000003f5, + 0x00000008,0x00000023,0x00000020,0x00050048,0x000003f5,0x00000009,0x00000023,0x00000030, + 0x00050048,0x000003f5,0x0000000a,0x00000023,0x00000038,0x00050048,0x000003f5,0x0000000b, + 0x00000023,0x00000040,0x00050048,0x000003f5,0x0000000c,0x00000023,0x00000044,0x00050048, + 0x000003f5,0x0000000d,0x00000023,0x00000048,0x00050048,0x000003f5,0x0000000e,0x00000023, + 0x0000004c,0x00050048,0x000003f5,0x0000000f,0x00000023,0x00000050,0x00050048,0x000003f5, + 0x00000010,0x00000023,0x00000054,0x00050048,0x000003f5,0x00000011,0x00000023,0x00000058, + 0x00050048,0x000003f5,0x00000012,0x00000023,0x0000005c,0x00050048,0x000003f5,0x00000013, + 0x00000023,0x00000060,0x00050048,0x000003f5,0x00000014,0x00000023,0x00000064,0x00040047, + 0x000003f7,0x00000021,0x00000000,0x00040047,0x000003f7,0x00000022,0x00000000,0x00030047, + 0x000003fc,0x00000000,0x00030047,0x00000410,0x00000000,0x00030047,0x00000411,0x00000000, + 0x00030047,0x00000412,0x00000000,0x00030047,0x00000414,0x00000000,0x00030047,0x00000415, + 0x00000000,0x00030047,0x0000041f,0x00000000,0x00040047,0x0000041f,0x00000021,0x0000000a, + 0x00040047,0x0000041f,0x00000022,0x00000000,0x00030047,0x00000420,0x00000000,0x00040047, + 0x00000420,0x00000021,0x0000000a,0x00040047,0x00000420,0x00000022,0x00000000,0x00030047, + 0x00000421,0x00000000,0x00030047,0x00000421,0x00000017,0x00040047,0x00000421,0x00000021, + 0x00000002,0x00040047,0x00000421,0x00000022,0x00000002,0x00030047,0x00000422,0x00000017, + 0x00040047,0x00000422,0x00000021,0x00000003,0x00040047,0x00000422,0x00000022,0x00000002, + 0x00030047,0x0000043f,0x00000000,0x00030047,0x00000469,0x00000000,0x00030047,0x0000046a, + 0x00000000,0x00030047,0x0000046f,0x00000000,0x00030047,0x00000472,0x00000000,0x00030047, + 0x00000477,0x00000000,0x00030047,0x00000479,0x00000000,0x00030047,0x0000047a,0x00000000, + 0x00030047,0x00000487,0x00000000,0x00030047,0x00000488,0x00000000,0x00030047,0x0000048d, + 0x00000000,0x00030047,0x00000495,0x00000000,0x00030047,0x0000049c,0x00000000,0x00030047, + 0x000004ab,0x00000000,0x00030047,0x000004ad,0x00000000,0x00030047,0x000004b2,0x00000000, + 0x00030047,0x000004b6,0x00000000,0x00030047,0x000004d4,0x00000000,0x00030047,0x000004d6, + 0x00000000,0x00030047,0x000004d7,0x00000000,0x00030047,0x000004d9,0x00000000,0x00030047, + 0x000004db,0x00000000,0x00030047,0x000004dc,0x00000000,0x00030047,0x000004ed,0x00000000, + 0x00030047,0x000004ef,0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047,0x000004ff, + 0x00000000,0x00030047,0x00000501,0x00000000,0x00030047,0x0000052b,0x00000000,0x00030047, + 0x0000052d,0x00000000,0x00030047,0x0000052f,0x00000000,0x00030047,0x00000531,0x00000000, + 0x00030047,0x00000534,0x00000000,0x00030047,0x00000535,0x00000000,0x00030047,0x00000537, + 0x00000000,0x00030047,0x00000539,0x00000000,0x00030047,0x0000053d,0x00000000,0x00030047, + 0x0000053f,0x00000000,0x00030047,0x00000541,0x00000000,0x00030047,0x00000544,0x00000000, + 0x00030047,0x00000545,0x00000000,0x00030047,0x00000546,0x00000000,0x00030047,0x00000548, + 0x00000000,0x00030047,0x0000054a,0x00000000,0x00030047,0x0000054c,0x00000000,0x00030047, + 0x0000054e,0x00000000,0x00030047,0x00000554,0x00000000,0x00030047,0x00000555,0x00000000, + 0x00030047,0x0000055c,0x00000000,0x00030047,0x0000055e,0x00000000,0x00030047,0x00000561, + 0x00000000,0x00030047,0x00000563,0x00000000,0x00030047,0x00000564,0x00000000,0x00030047, + 0x00000567,0x00000000,0x00030047,0x00000569,0x00000000,0x00030047,0x0000056a,0x00000000, + 0x00030047,0x0000056d,0x00000000,0x00030047,0x00000570,0x00000000,0x00030047,0x00000571, + 0x00000000,0x00030047,0x00000573,0x00000000,0x00030047,0x00000576,0x00000000,0x00030047, + 0x0000057b,0x00000000,0x00030047,0x0000057c,0x00000000,0x00030047,0x00000584,0x00000000, + 0x00030047,0x0000058a,0x00000000,0x00030047,0x0000058c,0x00000000,0x00030047,0x0000058d, + 0x00000000,0x00030047,0x0000058e,0x00000000,0x00030047,0x00000591,0x00000000,0x00030047, + 0x00000594,0x00000000,0x00030047,0x00000595,0x00000000,0x00030047,0x00000596,0x00000000, + 0x00030047,0x00000598,0x00000000,0x00030047,0x0000059b,0x00000000,0x00030047,0x0000059c, + 0x00000000,0x00030047,0x0000059e,0x00000000,0x00030047,0x000005a0,0x00000000,0x00030047, + 0x000005a2,0x00000000,0x00030047,0x000005a6,0x00000000,0x00030047,0x000005a8,0x00000000, + 0x00030047,0x000005aa,0x00000000,0x00030047,0x000005ad,0x00000000,0x00030047,0x000005ae, + 0x00000000,0x00030047,0x000005af,0x00000000,0x00030047,0x000005b8,0x00000000,0x00030047, + 0x000005be,0x00000000,0x00030047,0x000005bf,0x00000000,0x00030047,0x000005c4,0x00000000, + 0x00030047,0x000005ca,0x00000000,0x00030047,0x000005cb,0x00000000,0x00030047,0x000005cc, + 0x00000000,0x00030047,0x000005cf,0x00000000,0x00030047,0x000005d0,0x00000000,0x00030047, + 0x000005d1,0x00000000,0x00030047,0x000005d7,0x00000000,0x00030047,0x000005d8,0x00000000, + 0x00030047,0x000005d9,0x00000000,0x00030047,0x000005e3,0x00000000,0x00030047,0x000005e4, + 0x00000000,0x00030047,0x000005e6,0x00000000,0x00030047,0x000005e7,0x00000000,0x00030047, + 0x000005e8,0x00000000,0x00030047,0x000005e9,0x00000000,0x00030047,0x000005ea,0x00000000, + 0x00030047,0x000005ed,0x00000000,0x00030047,0x000005ee,0x00000000,0x00030047,0x000005ef, + 0x00000000,0x00030047,0x000005f1,0x00000000,0x00030047,0x000005f3,0x00000000,0x00030047, + 0x000005f5,0x00000000,0x00030047,0x000005f7,0x00000000,0x00030047,0x000005f8,0x00000000, + 0x00030047,0x000005fb,0x00000000,0x00030047,0x000005fe,0x00000000,0x00030047,0x00000606, + 0x00000000,0x00030047,0x00000609,0x00000000,0x00030047,0x00000611,0x00000000,0x00030047, + 0x00000614,0x00000000,0x00030047,0x0000061b,0x00000000,0x00030047,0x0000061e,0x00000000, + 0x00030047,0x00000624,0x00000000,0x00030047,0x00000629,0x00000000,0x00030047,0x0000062b, + 0x00000000,0x00030047,0x00000630,0x00000000,0x00030047,0x00000634,0x00000000,0x00030047, + 0x000006d0,0x00000000,0x00030047,0x000006d4,0x00000000,0x00030047,0x000006d5,0x00000000, + 0x00030047,0x000006e5,0x00000000,0x00030047,0x000006e8,0x00000000,0x00030047,0x000006e9, + 0x00000000,0x00030047,0x000006ed,0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047, + 0x000006f0,0x00000000,0x00030047,0x000006f9,0x00000000,0x00030047,0x00000700,0x00000000, + 0x00030047,0x00000705,0x00000000,0x00030047,0x00000708,0x00000000,0x00030047,0x00000709, + 0x00000000,0x00030047,0x0000070d,0x00000000,0x00030047,0x0000070f,0x00000000,0x00030047, + 0x00000710,0x00000000,0x00030047,0x00000715,0x00000000,0x00030047,0x00000718,0x00000000, + 0x00030047,0x00000719,0x00000000,0x00030047,0x0000071d,0x00000000,0x00030047,0x0000071f, + 0x00000000,0x00030047,0x00000720,0x00000000,0x00030047,0x00000736,0x00000000,0x00030047, + 0x00000737,0x00000000,0x00030047,0x00000739,0x00000000,0x00030047,0x0000073f,0x00000000, + 0x00030047,0x00000743,0x00000000,0x00030047,0x00000744,0x00000000,0x00030047,0x00000747, + 0x00000000,0x00030047,0x00000749,0x00000000,0x00030047,0x0000074a,0x00000000,0x00030047, + 0x0000074b,0x00000000,0x00030047,0x0000074e,0x00000000,0x00030047,0x00000750,0x00000000, + 0x00030047,0x00000751,0x00000000,0x00030047,0x00000759,0x00000000,0x00030047,0x0000076b, + 0x00000000,0x00030047,0x0000078a,0x00000000,0x00030047,0x0000078d,0x00000000,0x00030047, + 0x0000078e,0x00000000,0x00030047,0x00000792,0x00000000,0x00030047,0x00000794,0x00000000, + 0x00030047,0x00000795,0x00000000,0x00030047,0x0000079e,0x00000000,0x00030047,0x000007a5, + 0x00000000,0x00030047,0x000007d4,0x00000000,0x00030047,0x000007d8,0x00000000,0x00030047, + 0x000007d9,0x00000000,0x00030047,0x000007e9,0x00000000,0x00030047,0x000007ec,0x00000000, + 0x00030047,0x000007ed,0x00000000,0x00030047,0x000007f1,0x00000000,0x00030047,0x000007f3, + 0x00000000,0x00030047,0x000007f4,0x00000000,0x00030047,0x000007fd,0x00000000,0x00030047, + 0x00000804,0x00000000,0x00030047,0x00000809,0x00000000,0x00030047,0x0000080c,0x00000000, + 0x00030047,0x0000080d,0x00000000,0x00030047,0x00000811,0x00000000,0x00030047,0x00000813, + 0x00000000,0x00030047,0x00000814,0x00000000,0x00030047,0x00000819,0x00000000,0x00030047, + 0x0000081c,0x00000000,0x00030047,0x0000081d,0x00000000,0x00030047,0x00000821,0x00000000, + 0x00030047,0x00000823,0x00000000,0x00030047,0x00000824,0x00000000,0x00030047,0x0000083a, + 0x00000000,0x00030047,0x0000083b,0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047, + 0x00000843,0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000848,0x00000000, + 0x00030047,0x0000084b,0x00000000,0x00030047,0x0000084d,0x00000000,0x00030047,0x0000084e, + 0x00000000,0x00030047,0x0000084f,0x00000000,0x00030047,0x00000852,0x00000000,0x00030047, + 0x00000854,0x00000000,0x00030047,0x00000855,0x00000000,0x00030047,0x0000085d,0x00000000, + 0x00030047,0x0000086f,0x00000000,0x00030047,0x0000088e,0x00000000,0x00030047,0x00000891, + 0x00000000,0x00030047,0x00000892,0x00000000,0x00030047,0x00000896,0x00000000,0x00030047, + 0x00000898,0x00000000,0x00030047,0x00000899,0x00000000,0x00030047,0x000008a2,0x00000000, + 0x00030047,0x000008a9,0x00000000,0x00030047,0x000008de,0x00000000,0x00030047,0x000008df, + 0x00000000,0x00030047,0x000008e1,0x00000000,0x00030047,0x000008e7,0x00000000,0x00030047, + 0x000008eb,0x00000000,0x00030047,0x000008ec,0x00000000,0x00030047,0x000008ef,0x00000000, + 0x00030047,0x000008f1,0x00000000,0x00030047,0x000008f2,0x00000000,0x00030047,0x000008f3, + 0x00000000,0x00030047,0x000008f6,0x00000000,0x00030047,0x000008f8,0x00000000,0x00030047, + 0x000008f9,0x00000000,0x00030047,0x00000901,0x00000000,0x00030047,0x00000913,0x00000000, + 0x00030047,0x00000932,0x00000000,0x00030047,0x00000935,0x00000000,0x00030047,0x00000936, + 0x00000000,0x00030047,0x0000093a,0x00000000,0x00030047,0x0000093c,0x00000000,0x00030047, + 0x0000093d,0x00000000,0x00030047,0x00000946,0x00000000,0x00030047,0x0000094d,0x00000000, + 0x00030047,0x00000982,0x00000000,0x00030047,0x00000983,0x00000000,0x00030047,0x00000985, + 0x00000000,0x00030047,0x0000098b,0x00000000,0x00030047,0x0000098f,0x00000000,0x00030047, + 0x00000990,0x00000000,0x00030047,0x00000993,0x00000000,0x00030047,0x00000995,0x00000000, + 0x00030047,0x00000996,0x00000000,0x00030047,0x00000997,0x00000000,0x00030047,0x0000099a, + 0x00000000,0x00030047,0x0000099c,0x00000000,0x00030047,0x0000099d,0x00000000,0x00030047, + 0x000009a5,0x00000000,0x00030047,0x000009b7,0x00000000,0x00030047,0x000009d6,0x00000000, + 0x00030047,0x000009d9,0x00000000,0x00030047,0x000009da,0x00000000,0x00030047,0x000009de, + 0x00000000,0x00030047,0x000009e0,0x00000000,0x00030047,0x000009e1,0x00000000,0x00030047, + 0x000009ea,0x00000000,0x00030047,0x000009f1,0x00000000,0x00030047,0x00000a13,0x00000000, + 0x00030047,0x00000a14,0x00000000,0x00030047,0x00000a26,0x00000000,0x00030047,0x00000a27, + 0x00000000,0x00030047,0x00000a2a,0x00000000,0x00030047,0x00000a2c,0x00000000,0x00030047, + 0x00000a30,0x00000000,0x00030047,0x00000a38,0x00000000,0x00030047,0x00000a3b,0x00000000, + 0x00030047,0x00000a3d,0x00000000,0x00030047,0x00000a3f,0x00000000,0x00030047,0x00000a46, + 0x00000000,0x00030047,0x00000a48,0x00000000,0x00030047,0x00000a4a,0x00000000,0x00030047, + 0x00000a4c,0x00000000,0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a56,0x00000000, + 0x00030047,0x00000a58,0x00000000,0x00030047,0x00000a5a,0x00000000,0x00030047,0x00000a5c, + 0x00000000,0x00030047,0x00000a5e,0x00000000,0x00030047,0x00000a60,0x00000000,0x00030047, + 0x00000a62,0x00000000,0x00030047,0x00000a64,0x00000000,0x00030047,0x00000a6c,0x00000000, + 0x00030047,0x00000a6e,0x00000000,0x00030047,0x00000a70,0x00000000,0x00030047,0x00000a7f, + 0x00000000,0x00030047,0x00000a81,0x00000000,0x00030047,0x00000a83,0x00000000,0x00030047, + 0x00000a85,0x00000000,0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a89,0x00000000, + 0x00030047,0x00000a91,0x00000000,0x00030047,0x00000a93,0x00000000,0x00030047,0x00000a95, + 0x00000000,0x00030047,0x00000a98,0x00000000,0x00030047,0x00000aa8,0x00000000,0x00030047, + 0x00000aaa,0x00000000,0x00030047,0x00000aac,0x00000000,0x00030047,0x00000aae,0x00000000, + 0x00030047,0x00000ab0,0x00000000,0x00030047,0x00000ab2,0x00000000,0x00030047,0x00000ab4, + 0x00000000,0x00030047,0x00000ab6,0x00000000,0x00030047,0x00000ab8,0x00000000,0x00030047, + 0x00000ac6,0x00000000,0x00030047,0x00000ac8,0x00000000,0x00030047,0x00000aca,0x00000000, + 0x00030047,0x00000ad2,0x00000000,0x00030047,0x00000ad4,0x00000000,0x00030047,0x00000ad6, + 0x00000000,0x00030047,0x00000ad8,0x00000000,0x00030047,0x00000ae0,0x00000000,0x00030047, + 0x00000ae2,0x00000000,0x00030047,0x00000ae6,0x00000000,0x00030047,0x00000ae8,0x00000000, + 0x00030047,0x00000aea,0x00000000,0x00030047,0x00000aec,0x00000000,0x00030047,0x00000aee, + 0x00000000,0x00030047,0x00000af0,0x00000000,0x00030047,0x00000afe,0x00000000,0x00030047, + 0x00000b00,0x00000000,0x00030047,0x00000b02,0x00000000,0x00030047,0x00000b0a,0x00000000, + 0x00030047,0x00000b0c,0x00000000,0x00030047,0x00000b0e,0x00000000,0x00030047,0x00000b10, + 0x00000000,0x00030047,0x00000b18,0x00000000,0x00030047,0x00000b1a,0x00000000,0x00030047, + 0x00000b1e,0x00000000,0x00030047,0x00000b20,0x00000000,0x00030047,0x00000b22,0x00000000, + 0x00030047,0x00000b24,0x00000000,0x00030047,0x00000b26,0x00000000,0x00030047,0x00000b28, + 0x00000000,0x00030047,0x00000b2a,0x00000000,0x00030047,0x00000b2c,0x00000000,0x00030047, + 0x00000b2e,0x00000000,0x00030047,0x00000b36,0x00000000,0x00030047,0x00000b38,0x00000000, + 0x00030047,0x00000b3a,0x00000000,0x00030047,0x00000b3c,0x00000000,0x00030047,0x00000b44, + 0x00000000,0x00030047,0x00000b46,0x00000000,0x00030047,0x00000b4a,0x00000000,0x00030047, + 0x00000b4c,0x00000000,0x00030047,0x00000b4e,0x00000000,0x00030047,0x00000b50,0x00000000, + 0x00030047,0x00000b52,0x00000000,0x00030047,0x00000b54,0x00000000,0x00030047,0x00000b56, + 0x00000000,0x00030047,0x00000b58,0x00000000,0x00030047,0x00000b5a,0x00000000,0x00030047, + 0x00000b62,0x00000000,0x00030047,0x00000b64,0x00000000,0x00030047,0x00000b66,0x00000000, + 0x00030047,0x00000b68,0x00000000,0x00030047,0x00000b70,0x00000000,0x00030047,0x00000b72, + 0x00000000,0x00030047,0x00000b77,0x00000000,0x00030047,0x00000b79,0x00000000,0x00030047, + 0x00000b7b,0x00000000,0x00030047,0x00000b7d,0x00000000,0x00030047,0x00000b7f,0x00000000, + 0x00030047,0x00000b81,0x00000000,0x00030047,0x00000b84,0x00000000,0x00030047,0x00000b87, + 0x00000000,0x00030047,0x00000b89,0x00000000,0x00030047,0x00000b8b,0x00000000,0x00030047, + 0x00000b8f,0x00000000,0x00030047,0x00000b91,0x00000000,0x00030047,0x00000b93,0x00000000, + 0x00030047,0x00000b95,0x00000000,0x00030047,0x00000b9c,0x00000000,0x00030047,0x00000b9e, + 0x00000000,0x00030047,0x00000b9f,0x00000000,0x00030047,0x00000b9d,0x00000000,0x00030047, + 0x00000b9b,0x00000000,0x00030047,0x00000ba0,0x00000000,0x00030047,0x00000ba3,0x00000000, + 0x00030047,0x00000ba4,0x00000000,0x00030047,0x00000ba9,0x00000000,0x00030047,0x00000d50, + 0x00000000,0x00030047,0x00000de6,0x00000000,0x00030047,0x00000de7,0x00000000,0x00030047, + 0x00000de8,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x0000000d, + 0x00000007,0x00000006,0x00040015,0x0000000e,0x00000020,0x00000000,0x00040017,0x00000017, + 0x00000006,0x00000002,0x00040017,0x00000021,0x00000006,0x00000003,0x00040020,0x0000002c, + 0x00000007,0x00000021,0x0004002b,0x0000000e,0x00000083,0x00000000,0x0004002b,0x00000006, + 0x000000ba,0x00000000,0x00020014,0x000000bb,0x0004002b,0x00000006,0x000000c0,0x3f800000, + 0x0004002b,0x00000006,0x000000f9,0x3d897143,0x0004002b,0x00000006,0x000000fd,0x3bbf4590, + 0x0004002b,0x00000006,0x00000104,0x4253ee82,0x00030030,0x000000bb,0x0000010f,0x0004002b, + 0x00000006,0x00000123,0x3e99999a,0x0004002b,0x00000006,0x00000124,0x3f170a3d,0x0004002b, + 0x00000006,0x00000125,0x3de147ae,0x0004002b,0x00000006,0x0000013f,0x388205ff,0x0004002b, + 0x00000006,0x000001a5,0x40000000,0x0004002b,0x00000006,0x000001ac,0x3f000000,0x00040017, + 0x000001b2,0x000000bb,0x00000003,0x00040015,0x0000022e,0x00000020,0x00000001,0x0004002b, + 0x0000022e,0x00000231,0x00000000,0x0004002b,0x0000022e,0x00000238,0x00000003,0x0004002b, + 0x00000006,0x0000024a,0x3e800000,0x0004002b,0x00000006,0x0000024f,0x41800000,0x0004002b, + 0x00000006,0x00000254,0x41400000,0x0004002b,0x00000006,0x0000025a,0x40400000,0x0004002b, + 0x0000022e,0x00000266,0x00000001,0x00030030,0x000000bb,0x00000281,0x00030030,0x000000bb, + 0x000002dc,0x00050034,0x000000bb,0x000002dd,0x000000a8,0x000002dc,0x0004002b,0x00000006, + 0x000002ec,0xbf800000,0x0004002b,0x00000006,0x0000030a,0x3f7f8000,0x0004002b,0x00000006, + 0x0000030d,0x3a800000,0x0004002b,0x00000006,0x00000310,0x3b000000,0x00090019,0x0000031a, + 0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x0000031b,0x00000000,0x0000031a,0x0004003b,0x0000031b,0x0000031c,0x00000000,0x0002001a, + 0x0000031e,0x00040020,0x0000031f,0x00000000,0x0000031e,0x0004003b,0x0000031f,0x00000320, + 0x00000000,0x0003001b,0x00000322,0x0000031a,0x00050034,0x000000bb,0x0000032d,0x000000a8, + 0x000002dc,0x0004003b,0x0000031b,0x00000341,0x00000000,0x0004003b,0x0000031f,0x00000343, + 0x00000000,0x00050034,0x000000bb,0x0000034f,0x000000a8,0x000002dc,0x00040017,0x00000363, + 0x0000022e,0x00000002,0x00040020,0x00000366,0x00000001,0x00000007,0x0004003b,0x00000366, + 0x00000367,0x00000001,0x0004003b,0x00000366,0x0000036d,0x00000001,0x0004003b,0x0000031b, + 0x00000373,0x00000000,0x0004003b,0x0000031f,0x00000375,0x00000000,0x00040020,0x00000378, + 0x00000001,0x00000017,0x0004003b,0x00000378,0x00000379,0x00000001,0x00030030,0x000000bb, + 0x00000382,0x0004003b,0x00000366,0x00000386,0x00000001,0x00030030,0x000000bb,0x00000392, + 0x00040020,0x00000395,0x00000001,0x00000006,0x0004003b,0x00000395,0x00000396,0x00000001, + 0x00090019,0x0000039d,0x0000000e,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000021,0x00040020,0x0000039e,0x00000000,0x0000039d,0x0004003b,0x0000039e,0x0000039f, + 0x00000000,0x00040017,0x000003a2,0x0000000e,0x00000004,0x00090019,0x000003c1,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000004,0x00040020,0x000003c2, + 0x00000000,0x000003c1,0x0004003b,0x000003c2,0x000003c3,0x00000000,0x0004003b,0x00000395, + 0x000003ca,0x00000001,0x00040017,0x000003f4,0x0000022e,0x00000004,0x0017001e,0x000003f5, + 0x00000006,0x00000006,0x00000006,0x00000006,0x0000000e,0x0000000e,0x0000000e,0x0000000e, + 0x000003f4,0x00000017,0x00000017,0x0000000e,0x00000006,0x0000000e,0x00000006,0x00000006, + 0x0000000e,0x00000006,0x00000006,0x00000006,0x0000000e,0x00040020,0x000003f6,0x00000002, + 0x000003f5,0x0004003b,0x000003f6,0x000003f7,0x00000002,0x0004002b,0x0000022e,0x000003f8, + 0x00000011,0x0004002b,0x0000022e,0x000003f9,0x00000012,0x00040020,0x00000401,0x00000002, + 0x00000006,0x0004003b,0x0000031f,0x0000041f,0x00000000,0x0004003b,0x0000031b,0x00000420, + 0x00000000,0x0004003b,0x000003c2,0x00000421,0x00000000,0x0004003b,0x0000039e,0x00000422, + 0x00000000,0x00030001,0x00000007,0x00000b98,0x00030001,0x00000021,0x00000bb0,0x0006002c, + 0x00000021,0x00000dea,0x000001ac,0x000001ac,0x000001ac,0x0006002c,0x00000021,0x00000deb, + 0x000000c0,0x000000c0,0x000000c0,0x00030001,0x00000017,0x00000ded,0x00030001,0x00000021, + 0x00000dee,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003b,0x0000002c,0x000004ff,0x00000007,0x0004003b,0x0000002c,0x00000501,0x00000007, + 0x0004003b,0x0000002c,0x000004ef,0x00000007,0x0004003d,0x00000007,0x00000368,0x00000367, + 0x0007004f,0x00000017,0x00000369,0x00000368,0x00000368,0x00000000,0x00000001,0x0006000c, + 0x00000017,0x0000036a,0x00000001,0x00000008,0x00000369,0x0004006e,0x00000363,0x0000036b, + 0x0000036a,0x0004003d,0x00000007,0x0000036f,0x0000036d,0x00050051,0x00000006,0x00000433, + 0x0000036f,0x00000003,0x000500be,0x000000bb,0x00000434,0x00000433,0x000000ba,0x000300f7, + 0x000004a0,0x00000000,0x000400fa,0x00000434,0x00000435,0x00000443,0x000200f8,0x00000435, + 0x000300f7,0x00000442,0x00000000,0x000400fa,0x000002dd,0x00000438,0x0000043c,0x000200f8, + 0x00000438,0x0005008e,0x00000007,0x0000043b,0x0000036f,0x000000c0,0x000200f9,0x00000442, + 0x000200f8,0x0000043c,0x00050051,0x00000006,0x0000043f,0x0000036f,0x00000003,0x00050085, + 0x00000006,0x00000440,0x0000043f,0x000000c0,0x00060052,0x00000007,0x00000a30,0x00000440, + 0x0000036f,0x00000003,0x000200f9,0x00000442,0x000200f8,0x00000442,0x000700f5,0x00000007, + 0x00000b9c,0x0000043b,0x00000438,0x00000a30,0x0000043c,0x000200f9,0x000004a0,0x000200f8, + 0x00000443,0x000500ba,0x000000bb,0x00000446,0x00000433,0x000002ec,0x000300f7,0x0000049f, + 0x00000000,0x000400fa,0x00000446,0x00000447,0x00000482,0x000200f8,0x00000447,0x00050051, + 0x00000006,0x00000449,0x0000036f,0x00000002,0x000500ba,0x000000bb,0x0000044a,0x00000449, + 0x000000ba,0x000300f7,0x00000452,0x00000000,0x000400fa,0x0000044a,0x0000044b,0x0000044e, + 0x000200f8,0x0000044b,0x00050051,0x00000006,0x0000044d,0x0000036f,0x00000000,0x000200f9, + 0x00000452,0x000200f8,0x0000044e,0x0007004f,0x00000017,0x00000450,0x0000036f,0x0000036f, + 0x00000000,0x00000001,0x0006000c,0x00000006,0x00000451,0x00000001,0x00000042,0x00000450, + 0x000200f9,0x00000452,0x000200f8,0x00000452,0x000700f5,0x00000006,0x00000b99,0x0000044d, + 0x0000044b,0x00000451,0x0000044e,0x0008000c,0x00000006,0x00000455,0x00000001,0x0000002b, + 0x00000b99,0x000000ba,0x000000c0,0x0006000c,0x00000006,0x00000458,0x00000001,0x00000004, + 0x00000449,0x000500ba,0x000000bb,0x0000045a,0x00000458,0x000000c0,0x000300f7,0x00000464, + 0x00000000,0x000400fa,0x0000045a,0x0000045b,0x0000045f,0x000200f8,0x0000045b,0x00050085, + 0x00000006,0x0000045d,0x0000030a,0x00000455,0x00050081,0x00000006,0x0000045e,0x0000045d, + 0x0000030d,0x000200f9,0x00000464,0x000200f8,0x0000045f,0x00050085,0x00000006,0x00000461, + 0x00000310,0x00000455,0x00050081,0x00000006,0x00000463,0x00000461,0x00000458,0x000200f9, + 0x00000464,0x000200f8,0x00000464,0x000700f5,0x00000006,0x00000b9a,0x0000045e,0x0000045b, + 0x00000463,0x0000045f,0x0004007f,0x00000006,0x00000468,0x00000433,0x0004003d,0x0000031a, + 0x00000469,0x0000031c,0x0004003d,0x0000031e,0x0000046a,0x00000320,0x00050056,0x00000322, + 0x0000046b,0x00000469,0x0000046a,0x00050050,0x00000017,0x0000046e,0x00000b9a,0x00000468, + 0x00070058,0x00000007,0x0000046f,0x0000046b,0x0000046e,0x00000002,0x000000ba,0x00050051, + 0x00000006,0x00000472,0x0000046f,0x00000003,0x00050085,0x00000006,0x00000473,0x00000472, + 0x000000c0,0x00060052,0x00000007,0x00000a38,0x00000473,0x0000046f,0x00000003,0x000300f7, + 0x00000481,0x00000000,0x000400fa,0x0000032d,0x00000475,0x00000481,0x000200f8,0x00000475, + 0x00050051,0x00000006,0x00000477,0x00000a38,0x00000003,0x0008004f,0x00000021,0x00000479, + 0x00000a38,0x00000a38,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000021,0x0000047a, + 0x00000479,0x00000477,0x00050051,0x00000006,0x0000047c,0x0000047a,0x00000000,0x00060052, + 0x00000007,0x00000a3b,0x0000047c,0x00000a38,0x00000000,0x00050051,0x00000006,0x0000047e, + 0x0000047a,0x00000001,0x00060052,0x00000007,0x00000a3d,0x0000047e,0x00000a3b,0x00000001, + 0x00050051,0x00000006,0x00000480,0x0000047a,0x00000002,0x00060052,0x00000007,0x00000a3f, + 0x00000480,0x00000a3d,0x00000002,0x000200f9,0x00000481,0x000200f8,0x00000481,0x000700f5, + 0x00000007,0x00000b9e,0x00000a38,0x00000464,0x00000a3f,0x00000475,0x000200f9,0x0000049f, + 0x000200f8,0x00000482,0x0004007f,0x00000006,0x00000485,0x00000433,0x00050083,0x00000006, + 0x00000486,0x00000485,0x000001a5,0x0004003d,0x0000031a,0x00000487,0x00000341,0x0004003d, + 0x0000031e,0x00000488,0x00000343,0x00050056,0x00000322,0x00000489,0x00000487,0x00000488, + 0x0007004f,0x00000017,0x0000048b,0x0000036f,0x0000036f,0x00000000,0x00000001,0x00070058, + 0x00000007,0x0000048d,0x00000489,0x0000048b,0x00000002,0x00000486,0x00050051,0x00000006, + 0x0000048f,0x0000036f,0x00000002,0x00050085,0x00000006,0x00000491,0x0000048f,0x000000c0, + 0x000300f7,0x0000049e,0x00000000,0x000400fa,0x0000034f,0x00000492,0x00000496,0x000200f8, + 0x00000492,0x0005008e,0x00000007,0x00000495,0x0000048d,0x00000491,0x000200f9,0x0000049e, + 0x000200f8,0x00000496,0x0008004f,0x00000021,0x000004ab,0x0000048d,0x0000048d,0x00000000, + 0x00000001,0x00000002,0x00050051,0x00000006,0x000004ad,0x0000048d,0x00000003,0x000500b7, + 0x000000bb,0x000004ae,0x000004ad,0x000000ba,0x000300f7,0x000004b4,0x00000000,0x000400fa, + 0x000004ae,0x000004af,0x000004b3,0x000200f8,0x000004af,0x00050088,0x00000006,0x000004b2, + 0x000000c0,0x000004ad,0x000200f9,0x000004b4,0x000200f8,0x000004b3,0x000200f9,0x000004b4, + 0x000200f8,0x000004b4,0x000700f5,0x00000006,0x00000b95,0x000004b2,0x000004af,0x000000ba, + 0x000004b3,0x0005008e,0x00000021,0x000004b6,0x000004ab,0x00000b95,0x00050085,0x00000006, + 0x0000049c,0x000004ad,0x00000491,0x00050051,0x00000006,0x000004bc,0x000004b6,0x00000000, + 0x00060052,0x00000007,0x00000a46,0x000004bc,0x00000b98,0x00000000,0x00050051,0x00000006, + 0x000004be,0x000004b6,0x00000001,0x00060052,0x00000007,0x00000a48,0x000004be,0x00000a46, + 0x00000001,0x00050051,0x00000006,0x000004c0,0x000004b6,0x00000002,0x00060052,0x00000007, + 0x00000a4a,0x000004c0,0x00000a48,0x00000002,0x00060052,0x00000007,0x00000a4c,0x0000049c, + 0x00000a4a,0x00000003,0x000200f9,0x0000049e,0x000200f8,0x0000049e,0x000700f5,0x00000007, + 0x00000b9f,0x00000495,0x00000492,0x00000a4c,0x000004b4,0x000200f9,0x0000049f,0x000200f8, + 0x0000049f,0x000700f5,0x00000007,0x00000b9d,0x00000b9e,0x00000481,0x00000b9f,0x0000049e, + 0x000200f9,0x000004a0,0x000200f8,0x000004a0,0x000700f5,0x00000007,0x00000b9b,0x00000b9c, + 0x00000442,0x00000b9d,0x0000049f,0x0004003d,0x0000031a,0x00000374,0x00000373,0x0004003d, + 0x0000031e,0x00000376,0x00000375,0x00050056,0x00000322,0x00000377,0x00000374,0x00000376, + 0x0004003d,0x00000017,0x0000037a,0x00000379,0x00070058,0x00000007,0x0000037b,0x00000377, + 0x0000037a,0x00000002,0x000000ba,0x00050051,0x00000006,0x0000037c,0x0000037b,0x00000000, + 0x0008000c,0x00000006,0x00000381,0x00000001,0x0000002b,0x0000037c,0x000000ba,0x000000c0, + 0x000300f7,0x00000384,0x00000000,0x000400fa,0x00000382,0x00000383,0x00000384,0x000200f8, + 0x00000383,0x0004003d,0x00000007,0x00000388,0x00000386,0x0007004f,0x00000017,0x000004d4, + 0x00000388,0x00000388,0x00000000,0x00000001,0x0007004f,0x00000017,0x000004d6,0x00000388, + 0x00000388,0x00000002,0x00000003,0x0007000c,0x00000017,0x000004d7,0x00000001,0x00000025, + 0x000004d4,0x000004d6,0x00050051,0x00000006,0x000004d9,0x000004d7,0x00000000,0x00050051, + 0x00000006,0x000004db,0x000004d7,0x00000001,0x0007000c,0x00000006,0x000004dc,0x00000001, + 0x00000025,0x000004d9,0x000004db,0x0007000c,0x00000006,0x0000038e,0x00000001,0x00000028, + 0x000004dc,0x000000ba,0x0007000c,0x00000006,0x00000391,0x00000001,0x00000025,0x0000038e, + 0x00000381,0x000200f9,0x00000384,0x000200f8,0x00000384,0x000700f5,0x00000006,0x00000ba3, + 0x00000381,0x000004a0,0x00000391,0x00000383,0x000114f4,0x000300f7,0x00000394,0x00000000, + 0x000400fa,0x00000392,0x00000393,0x00000394,0x000200f8,0x00000393,0x0004003d,0x00000006, + 0x00000397,0x00000396,0x000500b7,0x000000bb,0x00000398,0x00000397,0x000000ba,0x000200f9, + 0x00000394,0x000200f8,0x00000394,0x000700f5,0x000000bb,0x00000399,0x00000392,0x00000384, + 0x00000398,0x00000393,0x000300f7,0x0000039b,0x00000000,0x000400fa,0x00000399,0x0000039a, + 0x0000039b,0x000200f8,0x0000039a,0x0004003d,0x0000039d,0x000003a0,0x0000039f,0x00050062, + 0x000003a2,0x000003a3,0x000003a0,0x0000036b,0x00050051,0x0000000e,0x000003a4,0x000003a3, + 0x00000000,0x0006000c,0x00000017,0x000003a5,0x00000001,0x0000003e,0x000003a4,0x00050051, + 0x00000006,0x000003a8,0x000003a5,0x00000001,0x0004003d,0x00000006,0x000003ab,0x00000396, + 0x000500b4,0x000000bb,0x000003ac,0x000003a8,0x000003ab,0x000300f7,0x000003af,0x00000000, + 0x000400fa,0x000003ac,0x000003ae,0x000003b2,0x000200f8,0x000003ae,0x00050051,0x00000006, + 0x000003b1,0x000003a5,0x00000000,0x000200f9,0x000003af,0x000200f8,0x000003b2,0x000200f9, + 0x000003af,0x000200f8,0x000003af,0x000700f5,0x00000006,0x00000ba0,0x000003b1,0x000003ae, + 0x000000ba,0x000003b2,0x0007000c,0x00000006,0x000003b8,0x00000001,0x00000028,0x00000ba0, + 0x000000ba,0x0007000c,0x00000006,0x000003bc,0x00000001,0x00000028,0x000003b8,0x000000ba, + 0x0007000c,0x00000006,0x000003bf,0x00000001,0x00000025,0x00000ba3,0x000003bc,0x000200f9, + 0x0000039b,0x000200f8,0x0000039b,0x000700f5,0x00000006,0x00000ba4,0x00000ba3,0x00000394, + 0x000003bf,0x000003af,0x0004003d,0x000003c1,0x000003c4,0x000003c3,0x00050062,0x00000007, + 0x000003c6,0x000003c4,0x0000036b,0x000300f7,0x000003c8,0x00000000,0x000400fa,0x000002dc, + 0x000003c7,0x000003f0,0x000200f8,0x000003c7,0x0004003d,0x00000006,0x000003cc,0x000003ca, + 0x0004006d,0x0000000e,0x000004ed,0x000003cc,0x000500ab,0x000000bb,0x000003cf,0x000004ed, + 0x00000083,0x000300f7,0x000003d1,0x00000000,0x000400fa,0x000003cf,0x000003d0,0x000003d1, + 0x000200f8,0x000003d0,0x0008004f,0x00000021,0x000003d4,0x00000b9b,0x00000b9b,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x000004ef,0x000003d4,0x0008004f,0x00000021,0x00000629, + 0x000003c6,0x000003c6,0x00000000,0x00000001,0x00000002,0x00050051,0x00000006,0x0000062b, + 0x000003c6,0x00000003,0x000500b7,0x000000bb,0x0000062c,0x0000062b,0x000000ba,0x000300f7, + 0x00000632,0x00000000,0x000400fa,0x0000062c,0x0000062d,0x00000631,0x000200f8,0x0000062d, + 0x00050088,0x00000006,0x00000630,0x000000c0,0x0000062b,0x000200f9,0x00000632,0x000200f8, + 0x00000631,0x000200f9,0x00000632,0x000200f8,0x00000632,0x000700f5,0x00000006,0x00000ba9, + 0x00000630,0x0000062d,0x000000ba,0x00000631,0x0005008e,0x00000021,0x00000634,0x00000629, + 0x00000ba9,0x0003003e,0x000004ff,0x00000634,0x000300f7,0x00000623,0x00000000,0x002100fb, + 0x000004ed,0x00000623,0x0000000b,0x0000052a,0x00000001,0x0000052e,0x00000002,0x00000536, + 0x00000003,0x00000547,0x00000004,0x0000054b,0x00000005,0x0000054f,0x00000006,0x00000572, + 0x00000007,0x0000059f,0x00000008,0x000005b0,0x00000009,0x000005eb,0x0000000a,0x000005f0, + 0x0000000c,0x000005f9,0x0000000d,0x00000604,0x0000000e,0x0000060f,0x0000000f,0x00000619, + 0x000200f8,0x0000052a,0x0004003d,0x00000021,0x0000052b,0x000004ef,0x00050085,0x00000021, + 0x0000052d,0x0000052b,0x00000634,0x0003003e,0x00000501,0x0000052d,0x000200f9,0x00000623, + 0x000200f8,0x0000052e,0x0004003d,0x00000021,0x0000052f,0x000004ef,0x00050081,0x00000021, + 0x00000531,0x0000052f,0x00000634,0x00050085,0x00000021,0x00000534,0x0000052f,0x00000634, + 0x00050083,0x00000021,0x00000535,0x00000531,0x00000534,0x0003003e,0x00000501,0x00000535, + 0x000200f9,0x00000623,0x000200f8,0x00000536,0x0004003d,0x00000021,0x00000537,0x000004ef, + 0x00050085,0x00000021,0x00000539,0x00000537,0x00000634,0x00050081,0x00000021,0x0000053d, + 0x00000537,0x00000634,0x00050083,0x00000021,0x0000053f,0x0000053d,0x00000539,0x00050083, + 0x00000021,0x00000541,0x0000053f,0x00000dea,0x00060052,0x00000021,0x00000a54,0x000001ac, + 0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000a56,0x000001ac,0x00000a54,0x00000001, + 0x00060052,0x00000021,0x00000a58,0x000001ac,0x00000a56,0x00000002,0x000500ba,0x000001b2, + 0x00000544,0x00000634,0x00000a58,0x000600a9,0x00000021,0x00000545,0x00000544,0x00000541, + 0x00000539,0x0005008e,0x00000021,0x00000546,0x00000545,0x000001a5,0x0003003e,0x00000501, + 0x00000546,0x000200f9,0x00000623,0x000200f8,0x00000547,0x0004003d,0x00000021,0x00000548, + 0x000004ef,0x0007000c,0x00000021,0x0000054a,0x00000001,0x00000025,0x00000548,0x00000634, + 0x0003003e,0x00000501,0x0000054a,0x000200f9,0x00000623,0x000200f8,0x0000054b,0x0004003d, + 0x00000021,0x0000054c,0x000004ef,0x0007000c,0x00000021,0x0000054e,0x00000001,0x00000028, + 0x0000054c,0x00000634,0x0003003e,0x00000501,0x0000054e,0x000200f9,0x00000623,0x000200f8, + 0x0000054f,0x00060052,0x00000021,0x00000a5a,0x000000ba,0x00000bb0,0x00000000,0x00060052, + 0x00000021,0x00000a5c,0x000000ba,0x00000a5a,0x00000001,0x00060052,0x00000021,0x00000a5e, + 0x000000ba,0x00000a5c,0x00000002,0x0008004f,0x00000021,0x00000554,0x000003c6,0x000003c6, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x00000021,0x00000555,0x00000001,0x0000002b, + 0x00000629,0x00000a5e,0x00000554,0x00050051,0x00000006,0x00000557,0x00000555,0x00000000, + 0x00060052,0x00000007,0x00000a60,0x00000557,0x000003c6,0x00000000,0x00050051,0x00000006, + 0x00000559,0x00000555,0x00000001,0x00060052,0x00000007,0x00000a62,0x00000559,0x00000a60, + 0x00000001,0x00050051,0x00000006,0x0000055b,0x00000555,0x00000002,0x00060052,0x00000007, + 0x00000a64,0x0000055b,0x00000a62,0x00000002,0x0004003d,0x00000021,0x0000055c,0x000004ef, + 0x00050083,0x00000021,0x0000055e,0x00000deb,0x0000055c,0x00060052,0x00000021,0x00000a6c, + 0x000000c0,0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000a6e,0x000000c0,0x00000a6c, + 0x00000001,0x00060052,0x00000021,0x00000a70,0x000000c0,0x00000a6e,0x00000002,0x0008000c, + 0x00000021,0x00000561,0x00000001,0x0000002b,0x0000055e,0x00000a5e,0x00000a70,0x00050051, + 0x00000006,0x00000563,0x00000a64,0x00000003,0x0005008e,0x00000021,0x00000564,0x00000561, + 0x00000563,0x0008004f,0x00000021,0x00000567,0x00000a64,0x00000a64,0x00000000,0x00000001, + 0x00000002,0x00050088,0x00000021,0x00000569,0x00000567,0x00000564,0x0007000c,0x00000021, + 0x0000056a,0x00000001,0x00000025,0x00000a70,0x00000569,0x0006000c,0x00000021,0x0000056d, + 0x00000001,0x00000006,0x00000567,0x000500b4,0x000001b2,0x00000570,0x00000564,0x00000a5e, + 0x000600a9,0x00000021,0x00000571,0x00000570,0x0000056d,0x0000056a,0x0003003e,0x00000501, + 0x00000571,0x000200f9,0x00000623,0x000200f8,0x00000572,0x0004003d,0x00000021,0x00000573, + 0x000004ef,0x00060052,0x00000021,0x00000a7f,0x000000ba,0x00000bb0,0x00000000,0x00060052, + 0x00000021,0x00000a81,0x000000ba,0x00000a7f,0x00000001,0x00060052,0x00000021,0x00000a83, + 0x000000ba,0x00000a81,0x00000002,0x00060052,0x00000021,0x00000a85,0x000000c0,0x00000bb0, + 0x00000000,0x00060052,0x00000021,0x00000a87,0x000000c0,0x00000a85,0x00000001,0x00060052, + 0x00000021,0x00000a89,0x000000c0,0x00000a87,0x00000002,0x0008000c,0x00000021,0x00000576, + 0x00000001,0x0000002b,0x00000573,0x00000a83,0x00000a89,0x0003003e,0x000004ef,0x00000576, + 0x0008004f,0x00000021,0x0000057b,0x000003c6,0x000003c6,0x00000003,0x00000003,0x00000003, + 0x0008000c,0x00000021,0x0000057c,0x00000001,0x0000002b,0x00000629,0x00000a83,0x0000057b, + 0x00050051,0x00000006,0x0000057e,0x0000057c,0x00000000,0x00060052,0x00000007,0x00000a91, + 0x0000057e,0x000003c6,0x00000000,0x00050051,0x00000006,0x00000580,0x0000057c,0x00000001, + 0x00060052,0x00000007,0x00000a93,0x00000580,0x00000a91,0x00000001,0x00050051,0x00000006, + 0x00000582,0x0000057c,0x00000002,0x00060052,0x00000007,0x00000a95,0x00000582,0x00000a93, + 0x00000002,0x00050051,0x00000006,0x00000584,0x00000a95,0x00000003,0x000500b4,0x000000bb, + 0x00000585,0x00000584,0x000000ba,0x000300f7,0x00000588,0x00000000,0x000400fa,0x00000585, + 0x00000586,0x00000588,0x000200f8,0x00000586,0x00060052,0x00000007,0x00000a98,0x000000c0, + 0x00000a95,0x00000003,0x000200f9,0x00000588,0x000200f8,0x00000588,0x000700f5,0x00000007, + 0x00000d50,0x00000a95,0x00000572,0x00000a98,0x00000586,0x00050051,0x00000006,0x0000058a, + 0x00000d50,0x00000003,0x0008004f,0x00000021,0x0000058c,0x00000d50,0x00000d50,0x00000000, + 0x00000001,0x00000002,0x00060050,0x00000021,0x0000058d,0x0000058a,0x0000058a,0x0000058a, + 0x00050083,0x00000021,0x0000058e,0x0000058d,0x0000058c,0x0004003d,0x00000021,0x00000591, + 0x000004ef,0x0005008e,0x00000021,0x00000594,0x00000591,0x0000058a,0x00050088,0x00000021, + 0x00000595,0x0000058e,0x00000594,0x0007000c,0x00000021,0x00000596,0x00000001,0x00000025, + 0x00000a89,0x00000595,0x0006000c,0x00000021,0x00000598,0x00000001,0x00000006,0x0000058e, + 0x000500b4,0x000001b2,0x0000059b,0x00000591,0x00000a83,0x000600a9,0x00000021,0x0000059c, + 0x0000059b,0x00000598,0x00000596,0x00050083,0x00000021,0x0000059e,0x00000deb,0x0000059c, + 0x0003003e,0x00000501,0x0000059e,0x000200f9,0x00000623,0x000200f8,0x0000059f,0x0004003d, + 0x00000021,0x000005a0,0x000004ef,0x00050085,0x00000021,0x000005a2,0x000005a0,0x00000634, + 0x00050081,0x00000021,0x000005a6,0x000005a0,0x00000634,0x00050083,0x00000021,0x000005a8, + 0x000005a6,0x000005a2,0x00050083,0x00000021,0x000005aa,0x000005a8,0x00000dea,0x00060052, + 0x00000021,0x00000aa8,0x000001ac,0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000aaa, + 0x000001ac,0x00000aa8,0x00000001,0x00060052,0x00000021,0x00000aac,0x000001ac,0x00000aaa, + 0x00000002,0x000500ba,0x000001b2,0x000005ad,0x000005a0,0x00000aac,0x000600a9,0x00000021, + 0x000005ae,0x000005ad,0x000005aa,0x000005a2,0x0005008e,0x00000021,0x000005af,0x000005ae, + 0x000001a5,0x0003003e,0x00000501,0x000005af,0x000200f9,0x00000623,0x000200f8,0x000005b0, + 0x000200f9,0x000005b1,0x000200f8,0x000005b1,0x000700f5,0x0000022e,0x00000d18,0x00000231, + 0x000005b0,0x000005df,0x000005dd,0x000500b1,0x000000bb,0x000005b4,0x00000d18,0x00000238, + 0x000400f6,0x000005e0,0x000005dd,0x00000000,0x000400fa,0x000005b4,0x000005b5,0x000005e0, + 0x000200f8,0x000005b5,0x00050041,0x0000000d,0x000005b7,0x000004ef,0x00000d18,0x0004003d, + 0x00000006,0x000005b8,0x000005b7,0x000500bc,0x000000bb,0x000005b9,0x000005b8,0x000001ac, + 0x000300f7,0x000005dc,0x00000000,0x000400fa,0x000005b9,0x000005ba,0x000005c1,0x000200f8, + 0x000005ba,0x00050041,0x0000000d,0x000005bd,0x000004ff,0x00000d18,0x0004003d,0x00000006, + 0x000005be,0x000005bd,0x00050083,0x00000006,0x000005bf,0x000000c0,0x000005be,0x00050041, + 0x0000000d,0x000005c0,0x00000501,0x00000d18,0x0003003e,0x000005c0,0x000005bf,0x000200f9, + 0x000005dc,0x000200f8,0x000005c1,0x00050041,0x0000000d,0x000005c3,0x000004ff,0x00000d18, + 0x0004003d,0x00000006,0x000005c4,0x000005c3,0x000500bc,0x000000bb,0x000005c5,0x000005c4, + 0x0000024a,0x000300f7,0x000005db,0x00000000,0x000400fa,0x000005c5,0x000005c6,0x000005d3, + 0x000200f8,0x000005c6,0x0004003d,0x00000006,0x000005ca,0x000005c3,0x00050085,0x00000006, + 0x000005cb,0x0000024f,0x000005ca,0x00050083,0x00000006,0x000005cc,0x000005cb,0x00000254, + 0x0004003d,0x00000006,0x000005cf,0x000005c3,0x00050085,0x00000006,0x000005d0,0x000005cc, + 0x000005cf,0x00050081,0x00000006,0x000005d1,0x000005d0,0x0000025a,0x00050041,0x0000000d, + 0x000005d2,0x00000501,0x00000d18,0x0003003e,0x000005d2,0x000005d1,0x000200f9,0x000005db, + 0x000200f8,0x000005d3,0x0004003d,0x00000006,0x000005d7,0x000005c3,0x0006000c,0x00000006, + 0x000005d8,0x00000001,0x00000020,0x000005d7,0x00050083,0x00000006,0x000005d9,0x000005d8, + 0x000000c0,0x00050041,0x0000000d,0x000005da,0x00000501,0x00000d18,0x0003003e,0x000005da, + 0x000005d9,0x000200f9,0x000005db,0x000200f8,0x000005db,0x000200f9,0x000005dc,0x000200f8, + 0x000005dc,0x000200f9,0x000005dd,0x000200f8,0x000005dd,0x00050080,0x0000022e,0x000005df, + 0x00000d18,0x00000266,0x000200f9,0x000005b1,0x000200f8,0x000005e0,0x0004003d,0x00000021, + 0x000005e3,0x000004ef,0x0005008e,0x00000021,0x000005e4,0x000005e3,0x000001a5,0x00050083, + 0x00000021,0x000005e6,0x000005e4,0x00000deb,0x00050085,0x00000021,0x000005e7,0x00000634, + 0x000005e6,0x0004003d,0x00000021,0x000005e8,0x00000501,0x00050085,0x00000021,0x000005e9, + 0x000005e7,0x000005e8,0x00050081,0x00000021,0x000005ea,0x00000634,0x000005e9,0x0003003e, + 0x00000501,0x000005ea,0x000200f9,0x00000623,0x000200f8,0x000005eb,0x0004003d,0x00000021, + 0x000005ed,0x000004ef,0x00050083,0x00000021,0x000005ee,0x00000634,0x000005ed,0x0006000c, + 0x00000021,0x000005ef,0x00000001,0x00000004,0x000005ee,0x0003003e,0x00000501,0x000005ef, + 0x000200f9,0x00000623,0x000200f8,0x000005f0,0x0004003d,0x00000021,0x000005f1,0x000004ef, + 0x00050081,0x00000021,0x000005f3,0x000005f1,0x00000634,0x0005008e,0x00000021,0x000005f5, + 0x000005f1,0x000001a5,0x00050085,0x00000021,0x000005f7,0x000005f5,0x00000634,0x00050083, + 0x00000021,0x000005f8,0x000005f3,0x000005f7,0x0003003e,0x00000501,0x000005f8,0x000200f9, + 0x00000623,0x000200f8,0x000005f9,0x000300f7,0x00000603,0x00000000,0x000400fa,0x00000281, + 0x000005fa,0x00000603,0x000200f8,0x000005fa,0x0004003d,0x00000021,0x000005fb,0x000004ef, + 0x00060052,0x00000021,0x00000aae,0x000000ba,0x00000bb0,0x00000000,0x00060052,0x00000021, + 0x00000ab0,0x000000ba,0x00000aae,0x00000001,0x00060052,0x00000021,0x00000ab2,0x000000ba, + 0x00000ab0,0x00000002,0x00060052,0x00000021,0x00000ab4,0x000000c0,0x00000bb0,0x00000000, + 0x00060052,0x00000021,0x00000ab6,0x000000c0,0x00000ab4,0x00000001,0x00060052,0x00000021, + 0x00000ab8,0x000000c0,0x00000ab6,0x00000002,0x0008000c,0x00000021,0x000005fe,0x00000001, + 0x0000002b,0x000005fb,0x00000ab2,0x00000ab8,0x0003003e,0x000004ef,0x000005fe,0x0007004f, + 0x00000017,0x000006e5,0x00000634,0x00000634,0x00000000,0x00000001,0x00050051,0x00000006, + 0x000006ed,0x000006e5,0x00000000,0x00050051,0x00000006,0x000006ef,0x000006e5,0x00000001, + 0x0007000c,0x00000006,0x000006f0,0x00000001,0x00000028,0x000006ed,0x000006ef,0x00050051, + 0x00000006,0x000006e8,0x00000634,0x00000002,0x0007000c,0x00000006,0x000006e9,0x00000001, + 0x00000028,0x000006f0,0x000006e8,0x0007000c,0x00000006,0x00000700,0x00000001,0x00000025, + 0x000006ed,0x000006ef,0x0007000c,0x00000006,0x000006f9,0x00000001,0x00000025,0x00000700, + 0x000006e8,0x00050083,0x00000006,0x000006d0,0x000006e9,0x000006f9,0x0007004f,0x00000017, + 0x00000705,0x000005fe,0x000005fe,0x00000000,0x00000001,0x00050051,0x00000006,0x0000070d, + 0x00000705,0x00000000,0x00050051,0x00000006,0x0000070f,0x00000705,0x00000001,0x0007000c, + 0x00000006,0x00000710,0x00000001,0x00000025,0x0000070d,0x0000070f,0x00050051,0x00000006, + 0x00000708,0x000005fe,0x00000002,0x0007000c,0x00000006,0x00000709,0x00000001,0x00000025, + 0x00000710,0x00000708,0x00060050,0x00000021,0x000006d4,0x00000709,0x00000709,0x00000709, + 0x00050083,0x00000021,0x000006d5,0x000005fe,0x000006d4,0x0007004f,0x00000017,0x00000715, + 0x000006d5,0x000006d5,0x00000000,0x00000001,0x00050051,0x00000006,0x0000071d,0x00000715, + 0x00000000,0x00050051,0x00000006,0x0000071f,0x00000715,0x00000001,0x0007000c,0x00000006, + 0x00000720,0x00000001,0x00000028,0x0000071d,0x0000071f,0x00050051,0x00000006,0x00000718, + 0x000006d5,0x00000002,0x0007000c,0x00000006,0x00000719,0x00000001,0x00000028,0x00000720, + 0x00000718,0x0007000c,0x00000006,0x000006da,0x00000001,0x00000028,0x0000013f,0x00000719, + 0x00050088,0x00000006,0x000006db,0x000006d0,0x000006da,0x0005008e,0x00000021,0x000006de, + 0x000006d5,0x000006db,0x00060052,0x00000021,0x00000ac6,0x00000123,0x00000bb0,0x00000000, + 0x00060052,0x00000021,0x00000ac8,0x00000124,0x00000ac6,0x00000001,0x00060052,0x00000021, + 0x00000aca,0x00000125,0x00000ac8,0x00000002,0x00050094,0x00000006,0x00000759,0x00000634, + 0x00000aca,0x00050094,0x00000006,0x0000076b,0x000006de,0x00000aca,0x00060050,0x00000021, + 0x00000736,0x0000076b,0x0000076b,0x0000076b,0x00050083,0x00000021,0x00000737,0x000006de, + 0x00000736,0x00050083,0x00000006,0x00000739,0x000000c0,0x00000759,0x00060052,0x00000017, + 0x00000ad2,0x00000759,0x00000ded,0x00000000,0x00060052,0x00000017,0x00000ad4,0x00000739, + 0x00000ad2,0x00000001,0x00060052,0x00000017,0x00000ad6,0x0000013f,0x00000ded,0x00000000, + 0x00060052,0x00000017,0x00000ad8,0x0000013f,0x00000ad6,0x00000001,0x0007004f,0x00000017, + 0x0000078a,0x00000737,0x00000737,0x00000000,0x00000001,0x00050051,0x00000006,0x00000792, + 0x0000078a,0x00000000,0x00050051,0x00000006,0x00000794,0x0000078a,0x00000001,0x0007000c, + 0x00000006,0x00000795,0x00000001,0x00000025,0x00000792,0x00000794,0x00050051,0x00000006, + 0x0000078d,0x00000737,0x00000002,0x0007000c,0x00000006,0x0000078e,0x00000001,0x00000025, + 0x00000795,0x0000078d,0x0004007f,0x00000006,0x0000073f,0x0000078e,0x0007000c,0x00000006, + 0x000007a5,0x00000001,0x00000028,0x00000792,0x00000794,0x0007000c,0x00000006,0x0000079e, + 0x00000001,0x00000028,0x000007a5,0x0000078d,0x00060052,0x00000017,0x00000ae0,0x0000073f, + 0x00000ded,0x00000000,0x00060052,0x00000017,0x00000ae2,0x0000079e,0x00000ae0,0x00000001, + 0x0007000c,0x00000017,0x00000743,0x00000001,0x00000028,0x00000ad8,0x00000ae2,0x00050088, + 0x00000017,0x00000744,0x00000ad4,0x00000743,0x00050051,0x00000006,0x00000747,0x00000744, + 0x00000000,0x00050051,0x00000006,0x00000749,0x00000744,0x00000001,0x0007000c,0x00000006, + 0x0000074a,0x00000001,0x00000025,0x00000747,0x00000749,0x0007000c,0x00000006,0x0000074b, + 0x00000001,0x00000025,0x000000c0,0x0000074a,0x0005008e,0x00000021,0x0000074e,0x00000737, + 0x0000074b,0x00060050,0x00000021,0x00000750,0x00000759,0x00000759,0x00000759,0x00050081, + 0x00000021,0x00000751,0x0000074e,0x00000750,0x0003003e,0x00000501,0x00000751,0x000200f9, + 0x00000603,0x000200f8,0x00000603,0x000200f9,0x00000623,0x000200f8,0x00000604,0x000300f7, + 0x0000060e,0x00000000,0x000400fa,0x00000281,0x00000605,0x0000060e,0x000200f8,0x00000605, + 0x0004003d,0x00000021,0x00000606,0x000004ef,0x00060052,0x00000021,0x00000ae6,0x000000ba, + 0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000ae8,0x000000ba,0x00000ae6,0x00000001, + 0x00060052,0x00000021,0x00000aea,0x000000ba,0x00000ae8,0x00000002,0x00060052,0x00000021, + 0x00000aec,0x000000c0,0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000aee,0x000000c0, + 0x00000aec,0x00000001,0x00060052,0x00000021,0x00000af0,0x000000c0,0x00000aee,0x00000002, + 0x0008000c,0x00000021,0x00000609,0x00000001,0x0000002b,0x00000606,0x00000aea,0x00000af0, + 0x0003003e,0x000004ef,0x00000609,0x0007004f,0x00000017,0x000007e9,0x00000609,0x00000609, + 0x00000000,0x00000001,0x00050051,0x00000006,0x000007f1,0x000007e9,0x00000000,0x00050051, + 0x00000006,0x000007f3,0x000007e9,0x00000001,0x0007000c,0x00000006,0x000007f4,0x00000001, + 0x00000028,0x000007f1,0x000007f3,0x00050051,0x00000006,0x000007ec,0x00000609,0x00000002, + 0x0007000c,0x00000006,0x000007ed,0x00000001,0x00000028,0x000007f4,0x000007ec,0x0007000c, + 0x00000006,0x00000804,0x00000001,0x00000025,0x000007f1,0x000007f3,0x0007000c,0x00000006, + 0x000007fd,0x00000001,0x00000025,0x00000804,0x000007ec,0x00050083,0x00000006,0x000007d4, + 0x000007ed,0x000007fd,0x0007004f,0x00000017,0x00000809,0x00000634,0x00000634,0x00000000, + 0x00000001,0x00050051,0x00000006,0x00000811,0x00000809,0x00000000,0x00050051,0x00000006, + 0x00000813,0x00000809,0x00000001,0x0007000c,0x00000006,0x00000814,0x00000001,0x00000025, + 0x00000811,0x00000813,0x00050051,0x00000006,0x0000080c,0x00000634,0x00000002,0x0007000c, + 0x00000006,0x0000080d,0x00000001,0x00000025,0x00000814,0x0000080c,0x00060050,0x00000021, + 0x000007d8,0x0000080d,0x0000080d,0x0000080d,0x00050083,0x00000021,0x000007d9,0x00000634, + 0x000007d8,0x0007004f,0x00000017,0x00000819,0x000007d9,0x000007d9,0x00000000,0x00000001, + 0x00050051,0x00000006,0x00000821,0x00000819,0x00000000,0x00050051,0x00000006,0x00000823, + 0x00000819,0x00000001,0x0007000c,0x00000006,0x00000824,0x00000001,0x00000028,0x00000821, + 0x00000823,0x00050051,0x00000006,0x0000081c,0x000007d9,0x00000002,0x0007000c,0x00000006, + 0x0000081d,0x00000001,0x00000028,0x00000824,0x0000081c,0x0007000c,0x00000006,0x000007de, + 0x00000001,0x00000028,0x0000013f,0x0000081d,0x00050088,0x00000006,0x000007df,0x000007d4, + 0x000007de,0x0005008e,0x00000021,0x000007e2,0x000007d9,0x000007df,0x00060052,0x00000021, + 0x00000afe,0x00000123,0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000b00,0x00000124, + 0x00000afe,0x00000001,0x00060052,0x00000021,0x00000b02,0x00000125,0x00000b00,0x00000002, + 0x00050094,0x00000006,0x0000085d,0x00000634,0x00000b02,0x00050094,0x00000006,0x0000086f, + 0x000007e2,0x00000b02,0x00060050,0x00000021,0x0000083a,0x0000086f,0x0000086f,0x0000086f, + 0x00050083,0x00000021,0x0000083b,0x000007e2,0x0000083a,0x00050083,0x00000006,0x0000083d, + 0x000000c0,0x0000085d,0x00060052,0x00000017,0x00000b0a,0x0000085d,0x00000ded,0x00000000, + 0x00060052,0x00000017,0x00000b0c,0x0000083d,0x00000b0a,0x00000001,0x00060052,0x00000017, + 0x00000b0e,0x0000013f,0x00000ded,0x00000000,0x00060052,0x00000017,0x00000b10,0x0000013f, + 0x00000b0e,0x00000001,0x0007004f,0x00000017,0x0000088e,0x0000083b,0x0000083b,0x00000000, + 0x00000001,0x00050051,0x00000006,0x00000896,0x0000088e,0x00000000,0x00050051,0x00000006, + 0x00000898,0x0000088e,0x00000001,0x0007000c,0x00000006,0x00000899,0x00000001,0x00000025, + 0x00000896,0x00000898,0x00050051,0x00000006,0x00000891,0x0000083b,0x00000002,0x0007000c, + 0x00000006,0x00000892,0x00000001,0x00000025,0x00000899,0x00000891,0x0004007f,0x00000006, + 0x00000843,0x00000892,0x0007000c,0x00000006,0x000008a9,0x00000001,0x00000028,0x00000896, + 0x00000898,0x0007000c,0x00000006,0x000008a2,0x00000001,0x00000028,0x000008a9,0x00000891, + 0x00060052,0x00000017,0x00000b18,0x00000843,0x00000ded,0x00000000,0x00060052,0x00000017, + 0x00000b1a,0x000008a2,0x00000b18,0x00000001,0x0007000c,0x00000017,0x00000847,0x00000001, + 0x00000028,0x00000b10,0x00000b1a,0x00050088,0x00000017,0x00000848,0x00000b0c,0x00000847, + 0x00050051,0x00000006,0x0000084b,0x00000848,0x00000000,0x00050051,0x00000006,0x0000084d, + 0x00000848,0x00000001,0x0007000c,0x00000006,0x0000084e,0x00000001,0x00000025,0x0000084b, + 0x0000084d,0x0007000c,0x00000006,0x0000084f,0x00000001,0x00000025,0x000000c0,0x0000084e, + 0x0005008e,0x00000021,0x00000852,0x0000083b,0x0000084f,0x00060050,0x00000021,0x00000854, + 0x0000085d,0x0000085d,0x0000085d,0x00050081,0x00000021,0x00000855,0x00000852,0x00000854, + 0x0003003e,0x00000501,0x00000855,0x000200f9,0x0000060e,0x000200f8,0x0000060e,0x000200f9, + 0x00000623,0x000200f8,0x0000060f,0x000300f7,0x00000618,0x00000000,0x000400fa,0x00000281, + 0x00000610,0x00000618,0x000200f8,0x00000610,0x0004003d,0x00000021,0x00000611,0x000004ef, + 0x00060052,0x00000021,0x00000b1e,0x000000ba,0x00000bb0,0x00000000,0x00060052,0x00000021, + 0x00000b20,0x000000ba,0x00000b1e,0x00000001,0x00060052,0x00000021,0x00000b22,0x000000ba, + 0x00000b20,0x00000002,0x00060052,0x00000021,0x00000b24,0x000000c0,0x00000bb0,0x00000000, + 0x00060052,0x00000021,0x00000b26,0x000000c0,0x00000b24,0x00000001,0x00060052,0x00000021, + 0x00000b28,0x000000c0,0x00000b26,0x00000002,0x0008000c,0x00000021,0x00000614,0x00000001, + 0x0000002b,0x00000611,0x00000b22,0x00000b28,0x0003003e,0x000004ef,0x00000614,0x00060052, + 0x00000021,0x00000b2a,0x00000123,0x00000bb0,0x00000000,0x00060052,0x00000021,0x00000b2c, + 0x00000124,0x00000b2a,0x00000001,0x00060052,0x00000021,0x00000b2e,0x00000125,0x00000b2c, + 0x00000002,0x00050094,0x00000006,0x00000901,0x00000634,0x00000b2e,0x00050094,0x00000006, + 0x00000913,0x00000614,0x00000b2e,0x00060050,0x00000021,0x000008de,0x00000913,0x00000913, + 0x00000913,0x00050083,0x00000021,0x000008df,0x00000614,0x000008de,0x00050083,0x00000006, + 0x000008e1,0x000000c0,0x00000901,0x00060052,0x00000017,0x00000b36,0x00000901,0x00000ded, + 0x00000000,0x00060052,0x00000017,0x00000b38,0x000008e1,0x00000b36,0x00000001,0x00060052, + 0x00000017,0x00000b3a,0x0000013f,0x00000ded,0x00000000,0x00060052,0x00000017,0x00000b3c, + 0x0000013f,0x00000b3a,0x00000001,0x0007004f,0x00000017,0x00000932,0x000008df,0x000008df, + 0x00000000,0x00000001,0x00050051,0x00000006,0x0000093a,0x00000932,0x00000000,0x00050051, + 0x00000006,0x0000093c,0x00000932,0x00000001,0x0007000c,0x00000006,0x0000093d,0x00000001, + 0x00000025,0x0000093a,0x0000093c,0x00050051,0x00000006,0x00000935,0x000008df,0x00000002, + 0x0007000c,0x00000006,0x00000936,0x00000001,0x00000025,0x0000093d,0x00000935,0x0004007f, + 0x00000006,0x000008e7,0x00000936,0x0007000c,0x00000006,0x0000094d,0x00000001,0x00000028, + 0x0000093a,0x0000093c,0x0007000c,0x00000006,0x00000946,0x00000001,0x00000028,0x0000094d, + 0x00000935,0x00060052,0x00000017,0x00000b44,0x000008e7,0x00000ded,0x00000000,0x00060052, + 0x00000017,0x00000b46,0x00000946,0x00000b44,0x00000001,0x0007000c,0x00000017,0x000008eb, + 0x00000001,0x00000028,0x00000b3c,0x00000b46,0x00050088,0x00000017,0x000008ec,0x00000b38, + 0x000008eb,0x00050051,0x00000006,0x000008ef,0x000008ec,0x00000000,0x00050051,0x00000006, + 0x000008f1,0x000008ec,0x00000001,0x0007000c,0x00000006,0x000008f2,0x00000001,0x00000025, + 0x000008ef,0x000008f1,0x0007000c,0x00000006,0x000008f3,0x00000001,0x00000025,0x000000c0, + 0x000008f2,0x0005008e,0x00000021,0x000008f6,0x000008df,0x000008f3,0x00060050,0x00000021, + 0x000008f8,0x00000901,0x00000901,0x00000901,0x00050081,0x00000021,0x000008f9,0x000008f6, + 0x000008f8,0x0003003e,0x00000501,0x000008f9,0x000200f9,0x00000618,0x000200f8,0x00000618, + 0x000200f9,0x00000623,0x000200f8,0x00000619,0x000300f7,0x00000622,0x00000000,0x000400fa, + 0x00000281,0x0000061a,0x00000622,0x000200f8,0x0000061a,0x0004003d,0x00000021,0x0000061b, + 0x000004ef,0x00060052,0x00000021,0x00000b4a,0x000000ba,0x00000bb0,0x00000000,0x00060052, + 0x00000021,0x00000b4c,0x000000ba,0x00000b4a,0x00000001,0x00060052,0x00000021,0x00000b4e, + 0x000000ba,0x00000b4c,0x00000002,0x00060052,0x00000021,0x00000b50,0x000000c0,0x00000bb0, + 0x00000000,0x00060052,0x00000021,0x00000b52,0x000000c0,0x00000b50,0x00000001,0x00060052, + 0x00000021,0x00000b54,0x000000c0,0x00000b52,0x00000002,0x0008000c,0x00000021,0x0000061e, + 0x00000001,0x0000002b,0x0000061b,0x00000b4e,0x00000b54,0x0003003e,0x000004ef,0x0000061e, + 0x00060052,0x00000021,0x00000b56,0x00000123,0x00000bb0,0x00000000,0x00060052,0x00000021, + 0x00000b58,0x00000124,0x00000b56,0x00000001,0x00060052,0x00000021,0x00000b5a,0x00000125, + 0x00000b58,0x00000002,0x00050094,0x00000006,0x000009a5,0x0000061e,0x00000b5a,0x00050094, + 0x00000006,0x000009b7,0x00000634,0x00000b5a,0x00060050,0x00000021,0x00000982,0x000009b7, + 0x000009b7,0x000009b7,0x00050083,0x00000021,0x00000983,0x00000634,0x00000982,0x00050083, + 0x00000006,0x00000985,0x000000c0,0x000009a5,0x00060052,0x00000017,0x00000b62,0x000009a5, + 0x00000ded,0x00000000,0x00060052,0x00000017,0x00000b64,0x00000985,0x00000b62,0x00000001, + 0x00060052,0x00000017,0x00000b66,0x0000013f,0x00000ded,0x00000000,0x00060052,0x00000017, + 0x00000b68,0x0000013f,0x00000b66,0x00000001,0x0007004f,0x00000017,0x000009d6,0x00000983, + 0x00000983,0x00000000,0x00000001,0x00050051,0x00000006,0x000009de,0x000009d6,0x00000000, + 0x00050051,0x00000006,0x000009e0,0x000009d6,0x00000001,0x0007000c,0x00000006,0x000009e1, + 0x00000001,0x00000025,0x000009de,0x000009e0,0x00050051,0x00000006,0x000009d9,0x00000983, + 0x00000002,0x0007000c,0x00000006,0x000009da,0x00000001,0x00000025,0x000009e1,0x000009d9, + 0x0004007f,0x00000006,0x0000098b,0x000009da,0x0007000c,0x00000006,0x000009f1,0x00000001, + 0x00000028,0x000009de,0x000009e0,0x0007000c,0x00000006,0x000009ea,0x00000001,0x00000028, + 0x000009f1,0x000009d9,0x00060052,0x00000017,0x00000b70,0x0000098b,0x00000ded,0x00000000, + 0x00060052,0x00000017,0x00000b72,0x000009ea,0x00000b70,0x00000001,0x0007000c,0x00000017, + 0x0000098f,0x00000001,0x00000028,0x00000b68,0x00000b72,0x00050088,0x00000017,0x00000990, + 0x00000b64,0x0000098f,0x00050051,0x00000006,0x00000993,0x00000990,0x00000000,0x00050051, + 0x00000006,0x00000995,0x00000990,0x00000001,0x0007000c,0x00000006,0x00000996,0x00000001, + 0x00000025,0x00000993,0x00000995,0x0007000c,0x00000006,0x00000997,0x00000001,0x00000025, + 0x000000c0,0x00000996,0x0005008e,0x00000021,0x0000099a,0x00000983,0x00000997,0x00060050, + 0x00000021,0x0000099c,0x000009a5,0x000009a5,0x000009a5,0x00050081,0x00000021,0x0000099d, + 0x0000099a,0x0000099c,0x0003003e,0x00000501,0x0000099d,0x000200f9,0x00000622,0x000200f8, + 0x00000622,0x000200f9,0x00000623,0x000200f8,0x00000623,0x0004003d,0x00000021,0x00000624, + 0x00000501,0x00060052,0x00000021,0x00000b77,0x0000062b,0x00000dee,0x00000000,0x00060052, + 0x00000021,0x00000b79,0x0000062b,0x00000b77,0x00000001,0x00060052,0x00000021,0x00000b7b, + 0x0000062b,0x00000b79,0x00000002,0x0008000c,0x00000021,0x000004fe,0x00000001,0x0000002e, + 0x000003d4,0x00000624,0x00000b7b,0x00050051,0x00000006,0x000003db,0x000004fe,0x00000000, + 0x00060052,0x00000007,0x00000b7d,0x000003db,0x00000b9b,0x00000000,0x00050051,0x00000006, + 0x000003dd,0x000004fe,0x00000001,0x00060052,0x00000007,0x00000b7f,0x000003dd,0x00000b7d, + 0x00000001,0x00050051,0x00000006,0x000003df,0x000004fe,0x00000002,0x00060052,0x00000007, + 0x00000b81,0x000003df,0x00000b7f,0x00000002,0x000200f9,0x000003d1,0x000200f8,0x000003d1, + 0x000700f5,0x00000007,0x00000de6,0x00000b9b,0x000003c7,0x00000b81,0x00000623,0x00050051, + 0x00000006,0x000003e2,0x00000de6,0x00000003,0x00050085,0x00000006,0x000003e3,0x000003e2, + 0x00000ba4,0x00060052,0x00000007,0x00000b84,0x000003e3,0x00000de6,0x00000003,0x00050051, + 0x00000006,0x000003e6,0x00000b84,0x00000003,0x0008004f,0x00000021,0x000003e8,0x00000b84, + 0x00000b84,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000021,0x000003e9,0x000003e8, + 0x000003e6,0x00050051,0x00000006,0x000003eb,0x000003e9,0x00000000,0x00060052,0x00000007, + 0x00000b87,0x000003eb,0x00000b84,0x00000000,0x00050051,0x00000006,0x000003ed,0x000003e9, + 0x00000001,0x00060052,0x00000007,0x00000b89,0x000003ed,0x00000b87,0x00000001,0x00050051, + 0x00000006,0x000003ef,0x000003e9,0x00000002,0x00060052,0x00000007,0x00000b8b,0x000003ef, + 0x00000b89,0x00000002,0x000200f9,0x000003c8,0x000200f8,0x000003f0,0x0005008e,0x00000007, + 0x000003f3,0x00000b9b,0x00000ba4,0x000200f9,0x000003c8,0x000200f8,0x000003c8,0x000700f5, + 0x00000007,0x00000de7,0x00000b8b,0x000003d1,0x000003f3,0x000003f0,0x0008004f,0x00000021, + 0x000003fc,0x00000de7,0x00000de7,0x00000000,0x00000001,0x00000002,0x00050041,0x00000401, + 0x00000402,0x000003f7,0x000003f8,0x0004003d,0x00000006,0x00000403,0x00000402,0x00050041, + 0x00000401,0x00000405,0x000003f7,0x000003f9,0x0004003d,0x00000006,0x00000406,0x00000405, + 0x000300f7,0x00000a17,0x00000000,0x000400fa,0x0000010f,0x00000a0d,0x00000a15,0x000200f8, + 0x00000a0d,0x00050051,0x00000006,0x00000a1e,0x00000369,0x00000000,0x00050085,0x00000006, + 0x00000a1f,0x000000f9,0x00000a1e,0x00050051,0x00000006,0x00000a21,0x00000369,0x00000001, + 0x00050085,0x00000006,0x00000a22,0x000000fd,0x00000a21,0x00050081,0x00000006,0x00000a23, + 0x00000a1f,0x00000a22,0x0006000c,0x00000006,0x00000a24,0x00000001,0x0000000a,0x00000a23, + 0x00050085,0x00000006,0x00000a26,0x00000104,0x00000a24,0x0006000c,0x00000006,0x00000a27, + 0x00000001,0x0000000a,0x00000a26,0x00050085,0x00000006,0x00000a2a,0x00000a27,0x00000403, + 0x00050081,0x00000006,0x00000a2c,0x00000a2a,0x00000406,0x00060050,0x00000021,0x00000a13, + 0x00000a2c,0x00000a2c,0x00000a2c,0x00050081,0x00000021,0x00000a14,0x00000a13,0x000003fc, + 0x000200f9,0x00000a17,0x000200f8,0x00000a15,0x000200f9,0x00000a17,0x000200f8,0x00000a17, + 0x000700f5,0x00000021,0x00000de8,0x00000a14,0x00000a0d,0x000003fc,0x00000a15,0x00050051, + 0x00000006,0x00000409,0x00000de8,0x00000000,0x00060052,0x00000007,0x00000b8f,0x00000409, + 0x00000de7,0x00000000,0x00050051,0x00000006,0x0000040b,0x00000de8,0x00000001,0x00060052, + 0x00000007,0x00000b91,0x0000040b,0x00000b8f,0x00000001,0x00050051,0x00000006,0x0000040d, + 0x00000de8,0x00000002,0x00060052,0x00000007,0x00000b93,0x0000040d,0x00000b91,0x00000002, + 0x00050051,0x00000006,0x00000410,0x00000b93,0x00000003,0x00050083,0x00000006,0x00000411, + 0x000000c0,0x00000410,0x0005008e,0x00000007,0x00000412,0x000003c6,0x00000411,0x00050081, + 0x00000007,0x00000414,0x00000412,0x00000b93,0x0004003d,0x000003c1,0x00000415,0x000003c3, + 0x00040063,0x00000415,0x0000036b,0x00000414,0x000114f5,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..576942df9272a0b061d5d8b33e649fc29c2acd70 GIT binary patch literal 22748 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.h new file mode 100644 index 000000000..852946246 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.h @@ -0,0 +1,262 @@ +#pragma once + +const uint32_t draw_clockwise_atlas_blit_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000029c,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000e000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000c9,0x000000cc,0x000000d3, + 0x000000d6,0x0000010f,0x00000114,0x00000135,0x00000154,0x000001c7,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000a1,0x0000664a,0x00040006, + 0x000000a1,0x00000000,0x00003464,0x00030005,0x000000a3,0x0000424c,0x00030005,0x000000bb, + 0x0000424d,0x00040006,0x000000bb,0x00000000,0x00006250,0x00040006,0x000000bb,0x00000001, + 0x00006359,0x00040006,0x000000bb,0x00000002,0x00006552,0x00040006,0x000000bb,0x00000003, + 0x00006553,0x00040006,0x000000bb,0x00000004,0x0000366d,0x00040006,0x000000bb,0x00000005, + 0x0000676d,0x00040006,0x000000bb,0x00000006,0x00006544,0x00040006,0x000000bb,0x00000007, + 0x00006545,0x00040006,0x000000bb,0x00000008,0x00003755,0x00040006,0x000000bb,0x00000009, + 0x0000676a,0x00040006,0x000000bb,0x0000000a,0x0000635a,0x00040006,0x000000bb,0x0000000b, + 0x00003157,0x00040006,0x000000bb,0x0000000c,0x0000676e,0x00040006,0x000000bb,0x0000000d, + 0x00003559,0x00040006,0x000000bb,0x0000000e,0x0000324f,0x00040006,0x000000bb,0x0000000f, + 0x00006461,0x00040006,0x000000bb,0x00000010,0x00006579,0x00040006,0x000000bb,0x00000011, + 0x00003376,0x00040006,0x000000bb,0x00000012,0x00003377,0x00040006,0x000000bb,0x00000013, + 0x00006462,0x00040006,0x000000bb,0x00000014,0x00006767,0x00030005,0x000000bd,0x0000006b, + 0x00060005,0x000000c9,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005,0x000000cc, + 0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005,0x000000d3,0x0000424a, + 0x00030005,0x000000d6,0x00003243,0x00030005,0x000000e2,0x00006576,0x00040006,0x000000e2, + 0x00000000,0x00003464,0x00030005,0x000000e4,0x00004355,0x00030005,0x000000ee,0x00006747, + 0x00030005,0x0000010f,0x00003346,0x00030005,0x00000111,0x00006749,0x00030005,0x00000114, + 0x00003159,0x00030005,0x0000011d,0x00006748,0x00030005,0x00000122,0x00006577,0x00040006, + 0x00000122,0x00000000,0x00003464,0x00030005,0x00000124,0x0000424f,0x00030005,0x00000135, + 0x0000304e,0x00030005,0x00000154,0x0000316b,0x00060005,0x000001c5,0x505f6c67,0x65567265, + 0x78657472,0x00000000,0x00060006,0x000001c5,0x00000000,0x505f6c67,0x7469736f,0x006e6f69, + 0x00070006,0x000001c5,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006, + 0x000001c5,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x000001c5, + 0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000001c7,0x00000000, + 0x00030005,0x000001d5,0x00004342,0x00030005,0x000001d8,0x00004351,0x00030005,0x000001da, + 0x0000664b,0x00040006,0x000001da,0x00000000,0x00003464,0x00030005,0x000001dc,0x00004358, + 0x00030005,0x000001df,0x00003954,0x00040047,0x000000a0,0x00000006,0x00000010,0x00030047, + 0x000000a1,0x00000003,0x00040048,0x000000a1,0x00000000,0x00000018,0x00050048,0x000000a1, + 0x00000000,0x00000023,0x00000000,0x00030047,0x000000a3,0x00000018,0x00040047,0x000000a3, + 0x00000021,0x00000003,0x00040047,0x000000a3,0x00000022,0x00000000,0x00030047,0x000000bb, + 0x00000002,0x00050048,0x000000bb,0x00000000,0x00000023,0x00000000,0x00050048,0x000000bb, + 0x00000001,0x00000023,0x00000004,0x00050048,0x000000bb,0x00000002,0x00000023,0x00000008, + 0x00050048,0x000000bb,0x00000003,0x00000023,0x0000000c,0x00050048,0x000000bb,0x00000004, + 0x00000023,0x00000010,0x00050048,0x000000bb,0x00000005,0x00000023,0x00000014,0x00050048, + 0x000000bb,0x00000006,0x00000023,0x00000018,0x00050048,0x000000bb,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x000000bb,0x00000008,0x00000023,0x00000020,0x00050048,0x000000bb, + 0x00000009,0x00000023,0x00000030,0x00050048,0x000000bb,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x000000bb,0x0000000b,0x00000023,0x00000040,0x00050048,0x000000bb,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x000000bb,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x000000bb,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000000bb,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x000000bb,0x00000010,0x00000023,0x00000054,0x00050048,0x000000bb, + 0x00000011,0x00000023,0x00000058,0x00050048,0x000000bb,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x000000bb,0x00000013,0x00000023,0x00000060,0x00050048,0x000000bb,0x00000014, + 0x00000023,0x00000064,0x00040047,0x000000bd,0x00000021,0x00000000,0x00040047,0x000000bd, + 0x00000022,0x00000000,0x00040047,0x000000c9,0x0000000b,0x0000002a,0x00040047,0x000000cc, + 0x0000000b,0x0000002b,0x00040047,0x000000d3,0x0000001e,0x00000000,0x00040047,0x000000d6, + 0x0000001e,0x00000001,0x00040047,0x000000e1,0x00000006,0x00000008,0x00030047,0x000000e2, + 0x00000003,0x00040048,0x000000e2,0x00000000,0x00000018,0x00050048,0x000000e2,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000000e4,0x00000018,0x00040047,0x000000e4,0x00000021, + 0x00000004,0x00040047,0x000000e4,0x00000022,0x00000000,0x00040047,0x000000ee,0x00000001, + 0x00000000,0x00030047,0x0000010d,0x00000000,0x00030047,0x0000010f,0x00000000,0x00030047, + 0x0000010f,0x0000000e,0x00040047,0x0000010f,0x0000001e,0x00000004,0x00040047,0x00000111, + 0x00000001,0x00000002,0x00030047,0x00000114,0x00000000,0x00030047,0x00000114,0x0000000e, + 0x00040047,0x00000114,0x0000001e,0x00000006,0x00040047,0x0000011d,0x00000001,0x00000001, + 0x00040047,0x00000121,0x00000006,0x00000010,0x00030047,0x00000122,0x00000003,0x00040048, + 0x00000122,0x00000000,0x00000018,0x00050048,0x00000122,0x00000000,0x00000023,0x00000000, + 0x00030047,0x00000124,0x00000018,0x00040047,0x00000124,0x00000021,0x00000005,0x00040047, + 0x00000124,0x00000022,0x00000000,0x00040047,0x00000135,0x0000001e,0x00000005,0x00030047, + 0x0000014a,0x00000000,0x00030047,0x0000014c,0x00000000,0x00030047,0x0000014d,0x00000000, + 0x00040047,0x00000154,0x0000001e,0x00000000,0x00030047,0x000001c5,0x00000002,0x00050048, + 0x000001c5,0x00000000,0x0000000b,0x00000000,0x00050048,0x000001c5,0x00000001,0x0000000b, + 0x00000001,0x00050048,0x000001c5,0x00000002,0x0000000b,0x00000003,0x00050048,0x000001c5, + 0x00000003,0x0000000b,0x00000004,0x00040047,0x000001d5,0x00000021,0x00000008,0x00040047, + 0x000001d5,0x00000022,0x00000000,0x00030047,0x000001d8,0x00000000,0x00040047,0x000001d8, + 0x00000021,0x0000000a,0x00040047,0x000001d8,0x00000022,0x00000000,0x00040047,0x000001d9, + 0x00000006,0x00000010,0x00030047,0x000001da,0x00000003,0x00040048,0x000001da,0x00000000, + 0x00000018,0x00050048,0x000001da,0x00000000,0x00000023,0x00000000,0x00030047,0x000001dc, + 0x00000018,0x00040047,0x000001dc,0x00000021,0x00000006,0x00040047,0x000001dc,0x00000022, + 0x00000000,0x00030047,0x000001df,0x00000000,0x00040047,0x000001df,0x00000021,0x0000000a, + 0x00040047,0x000001df,0x00000022,0x00000000,0x00030047,0x00000282,0x00000000,0x00030047, + 0x00000284,0x00000000,0x00030047,0x00000286,0x00000000,0x00030047,0x00000293,0x00000000, + 0x00030047,0x00000295,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017, + 0x00000009,0x00000006,0x00000002,0x00040018,0x0000000a,0x00000009,0x00000002,0x00040015, + 0x0000000f,0x00000020,0x00000000,0x00040017,0x00000025,0x00000006,0x00000003,0x0004002b, + 0x00000006,0x00000031,0x3f800000,0x0004002b,0x00000006,0x00000032,0x00000000,0x0004002b, + 0x0000000f,0x0000003d,0x00000000,0x00020014,0x0000003e,0x0004002b,0x0000000f,0x00000045, + 0x000003ff,0x0004002b,0x0000000f,0x00000055,0x00000001,0x00040015,0x00000061,0x00000020, + 0x00000001,0x0004002b,0x00000061,0x00000062,0x00000000,0x0004002b,0x00000006,0x0000008e, + 0x3f000000,0x0004002b,0x0000000f,0x00000097,0x00000002,0x0004002b,0x0000000f,0x0000009b, + 0x0000ffff,0x00040017,0x0000009d,0x0000000f,0x00000004,0x0003001d,0x000000a0,0x0000009d, + 0x0003001e,0x000000a1,0x000000a0,0x00040020,0x000000a2,0x00000002,0x000000a1,0x0004003b, + 0x000000a2,0x000000a3,0x00000002,0x0004002b,0x0000000f,0x000000a5,0x00000004,0x00040020, + 0x000000a8,0x00000002,0x0000009d,0x00040017,0x000000af,0x0000000f,0x00000003,0x00040017, + 0x000000ba,0x00000061,0x00000004,0x0017001e,0x000000bb,0x00000006,0x00000006,0x00000006, + 0x00000006,0x0000000f,0x0000000f,0x0000000f,0x0000000f,0x000000ba,0x00000009,0x00000009, + 0x0000000f,0x00000006,0x0000000f,0x00000006,0x00000006,0x0000000f,0x00000006,0x00000006, + 0x00000006,0x0000000f,0x00040020,0x000000bc,0x00000002,0x000000bb,0x0004003b,0x000000bc, + 0x000000bd,0x00000002,0x0004002b,0x00000061,0x000000be,0x00000009,0x00040020,0x000000bf, + 0x00000002,0x00000009,0x00040020,0x000000c8,0x00000001,0x00000061,0x0004003b,0x000000c8, + 0x000000c9,0x00000001,0x0004003b,0x000000c8,0x000000cc,0x00000001,0x00040020,0x000000d2, + 0x00000001,0x00000025,0x0004003b,0x000000d2,0x000000d3,0x00000001,0x00040020,0x000000d5, + 0x00000003,0x00000009,0x0004003b,0x000000d5,0x000000d6,0x00000003,0x00040017,0x000000de, + 0x0000000f,0x00000002,0x0003001d,0x000000e1,0x000000de,0x0003001e,0x000000e2,0x000000e1, + 0x00040020,0x000000e3,0x00000002,0x000000e2,0x0004003b,0x000000e3,0x000000e4,0x00000002, + 0x00040020,0x000000e6,0x00000002,0x000000de,0x0004002b,0x0000000f,0x000000ec,0x0000000f, + 0x00030030,0x0000003e,0x000000ee,0x0004002b,0x00000061,0x000000fd,0x00000010,0x0004002b, + 0x00000061,0x00000100,0x0000000d,0x00040020,0x00000104,0x00000002,0x0000000f,0x00040020, + 0x0000010e,0x00000003,0x00000006,0x0004003b,0x0000010e,0x0000010f,0x00000003,0x00030030, + 0x0000003e,0x00000111,0x0004003b,0x0000010e,0x00000114,0x00000003,0x0004002b,0x00000061, + 0x00000117,0x00000004,0x00030030,0x0000003e,0x0000011d,0x0003001d,0x00000121,0x00000007, + 0x0003001e,0x00000122,0x00000121,0x00040020,0x00000123,0x00000002,0x00000122,0x0004003b, + 0x00000123,0x00000124,0x00000002,0x00040020,0x00000129,0x00000002,0x00000007,0x0004002b, + 0x0000000f,0x00000130,0x00000003,0x00040020,0x00000134,0x00000003,0x00000007,0x0004003b, + 0x00000134,0x00000135,0x00000003,0x00050034,0x0000003e,0x00000146,0x000000a8,0x00000111, + 0x0004003b,0x00000134,0x00000154,0x00000003,0x0004002b,0x00000006,0x0000017b,0x3f666666, + 0x0004002b,0x00000006,0x0000017f,0x40000000,0x0004002b,0x00000006,0x000001a4,0xc0000000, + 0x0004002b,0x00000061,0x000001ad,0x00000002,0x0004002b,0x00000061,0x000001ae,0x00000003, + 0x00040020,0x000001b2,0x00000002,0x00000006,0x0004001c,0x000001c4,0x00000006,0x00000055, + 0x0006001e,0x000001c5,0x00000007,0x00000006,0x000001c4,0x000001c4,0x00040020,0x000001c6, + 0x00000003,0x000001c5,0x0004003b,0x000001c6,0x000001c7,0x00000003,0x00090019,0x000001d3, + 0x0000000f,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x000001d4,0x00000000,0x000001d3,0x0004003b,0x000001d4,0x000001d5,0x00000000,0x00090019, + 0x000001d6,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x000001d7,0x00000000,0x000001d6,0x0004003b,0x000001d7,0x000001d8,0x00000000, + 0x0003001d,0x000001d9,0x0000009d,0x0003001e,0x000001da,0x000001d9,0x00040020,0x000001db, + 0x00000002,0x000001da,0x0004003b,0x000001db,0x000001dc,0x00000002,0x0002001a,0x000001dd, + 0x00040020,0x000001de,0x00000000,0x000001dd,0x0004003b,0x000001de,0x000001df,0x00000000, + 0x0005002c,0x00000009,0x00000298,0x00000031,0x00000031,0x0007002c,0x00000007,0x00000299, + 0x0000008e,0x0000008e,0x0000008e,0x0000008e,0x0003002e,0x00000009,0x0000029b,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000025, + 0x000000d8,0x000000d3,0x00050051,0x00000006,0x000001ec,0x000000d8,0x00000002,0x0004007c, + 0x0000000f,0x000001ed,0x000001ec,0x000500c7,0x0000000f,0x000001ee,0x000001ed,0x0000009b, + 0x00050084,0x0000000f,0x000001f0,0x000001ee,0x000000a5,0x00050080,0x0000000f,0x000001f1, + 0x000001f0,0x00000097,0x00060041,0x000000a8,0x000001f2,0x000000a3,0x00000062,0x000001f1, + 0x0004003d,0x0000009d,0x000001f3,0x000001f2,0x0007004f,0x00000009,0x000001f5,0x000000d8, + 0x000000d8,0x00000000,0x00000001,0x0008004f,0x000000af,0x000001f7,0x000001f3,0x000001f3, + 0x00000001,0x00000002,0x00000003,0x0004007c,0x00000025,0x000001f8,0x000001f7,0x00050051, + 0x00000006,0x000001fb,0x000001f8,0x00000000,0x0005008e,0x00000009,0x000001fc,0x000001f5, + 0x000001fb,0x0007004f,0x00000009,0x000001fe,0x000001f8,0x000001f8,0x00000001,0x00000002, + 0x00050081,0x00000009,0x000001ff,0x000001fc,0x000001fe,0x00050041,0x000000bf,0x00000200, + 0x000000bd,0x000000be,0x0004003d,0x00000009,0x00000201,0x00000200,0x00050085,0x00000009, + 0x00000202,0x000001ff,0x00000201,0x0003003e,0x000000d6,0x00000202,0x00060041,0x000000e6, + 0x000000e7,0x000000e4,0x00000062,0x000001ee,0x0004003d,0x000000de,0x000000e8,0x000000e7, + 0x00050051,0x0000000f,0x000000eb,0x000000e8,0x00000000,0x000500c7,0x0000000f,0x000000ed, + 0x000000eb,0x000000ec,0x000300f7,0x000000f0,0x00000000,0x000400fa,0x000000ee,0x000000ef, + 0x000000f0,0x000200f8,0x000000ef,0x000500aa,0x0000003e,0x000000f3,0x000000ed,0x0000003d, + 0x000300f7,0x000000f6,0x00000000,0x000400fa,0x000000f3,0x000000f5,0x000000f9,0x000200f8, + 0x000000f9,0x000200f9,0x000000f6,0x000200f8,0x000000f5,0x00050051,0x0000000f,0x000000f8, + 0x000000e8,0x00000001,0x000200f9,0x000000f6,0x000200f8,0x000000f6,0x000700f5,0x0000000f, + 0x00000291,0x000000f8,0x000000f5,0x000000eb,0x000000f9,0x000500c2,0x0000000f,0x000000fe, + 0x00000291,0x000000fd,0x00050041,0x00000104,0x00000105,0x000000bd,0x00000100,0x0004003d, + 0x0000000f,0x00000106,0x00000105,0x000500aa,0x0000003e,0x00000209,0x000000fe,0x0000003d, + 0x000300f7,0x00000212,0x00000000,0x000400fa,0x00000209,0x0000020a,0x0000020b,0x000200f8, + 0x0000020b,0x00050080,0x0000000f,0x0000020d,0x000000fe,0x00000045,0x00050084,0x0000000f, + 0x0000020f,0x0000020d,0x00000106,0x0006000c,0x00000009,0x00000210,0x00000001,0x0000003e, + 0x0000020f,0x00050051,0x00000006,0x00000211,0x00000210,0x00000000,0x000200f9,0x00000212, + 0x000200f8,0x0000020a,0x000200f9,0x00000212,0x000200f8,0x00000212,0x000700f5,0x00000006, + 0x00000292,0x00000032,0x0000020a,0x00000211,0x0000020b,0x000300f7,0x0000010b,0x00000000, + 0x000400fa,0x000000f3,0x0000010a,0x0000010b,0x000200f8,0x0000010a,0x0004007f,0x00000006, + 0x0000010d,0x00000292,0x000200f9,0x0000010b,0x000200f8,0x0000010b,0x000700f5,0x00000006, + 0x00000293,0x00000292,0x00000212,0x0000010d,0x0000010a,0x0003003e,0x0000010f,0x00000293, + 0x000200f9,0x000000f0,0x000200f8,0x000000f0,0x000300f7,0x00000113,0x00000000,0x000400fa, + 0x00000111,0x00000112,0x00000113,0x000200f8,0x00000112,0x000500c2,0x0000000f,0x00000118, + 0x000000eb,0x00000117,0x000500c7,0x0000000f,0x00000119,0x00000118,0x000000ec,0x00040070, + 0x00000006,0x0000011a,0x00000119,0x0003003e,0x00000114,0x0000011a,0x000200f9,0x00000113, + 0x000200f8,0x00000113,0x000300f7,0x0000011f,0x00000000,0x000400fa,0x0000011d,0x0000011e, + 0x0000011f,0x000200f8,0x0000011e,0x00060041,0x00000129,0x0000012a,0x00000124,0x00000062, + 0x000001f1,0x0004003d,0x00000007,0x0000012b,0x0000012a,0x00050051,0x00000006,0x0000021b, + 0x0000012b,0x00000000,0x00050051,0x00000006,0x0000021c,0x0000012b,0x00000001,0x00050051, + 0x00000006,0x0000021d,0x0000012b,0x00000002,0x00050051,0x00000006,0x0000021e,0x0000012b, + 0x00000003,0x00050050,0x00000009,0x0000021f,0x0000021b,0x0000021c,0x00050050,0x00000009, + 0x00000220,0x0000021d,0x0000021e,0x00050050,0x0000000a,0x00000221,0x0000021f,0x00000220, + 0x00050080,0x0000000f,0x00000131,0x000001f0,0x00000130,0x00060041,0x00000129,0x00000132, + 0x00000124,0x00000062,0x00000131,0x0004003d,0x00000007,0x00000133,0x00000132,0x0007004f, + 0x00000009,0x0000013a,0x00000133,0x00000133,0x00000000,0x00000001,0x000300f7,0x00000257, + 0x00000000,0x000300fb,0x0000003d,0x00000229,0x000200f8,0x00000229,0x0006000c,0x00000009, + 0x0000022c,0x00000001,0x00000004,0x0000021f,0x0006000c,0x00000009,0x0000022f,0x00000001, + 0x00000004,0x00000220,0x00050081,0x00000009,0x00000230,0x0000022c,0x0000022f,0x00050051, + 0x00000006,0x00000232,0x00000230,0x00000000,0x000500b7,0x0000003e,0x00000233,0x00000232, + 0x00000032,0x000300f7,0x00000238,0x00000000,0x000400fa,0x00000233,0x00000234,0x00000238, + 0x000200f8,0x00000234,0x00050051,0x00000006,0x00000236,0x00000230,0x00000001,0x000500b7, + 0x0000003e,0x00000237,0x00000236,0x00000032,0x000200f9,0x00000238,0x000200f8,0x00000238, + 0x000700f5,0x0000003e,0x00000239,0x00000233,0x00000229,0x00000237,0x00000234,0x000300f7, + 0x00000256,0x00000000,0x000400fa,0x00000239,0x0000023a,0x00000253,0x000200f8,0x00000253, + 0x0009004f,0x00000007,0x00000255,0x00000133,0x0000029b,0x00000000,0x00000001,0x00000000, + 0x00000001,0x000200f9,0x00000257,0x000200f8,0x0000023a,0x00050088,0x00000009,0x0000023d, + 0x00000298,0x00000230,0x00050091,0x00000009,0x00000240,0x00000221,0x000001f5,0x00050081, + 0x00000009,0x00000242,0x00000240,0x0000013a,0x0004007f,0x00000009,0x00000245,0x00000242, + 0x00050051,0x00000006,0x00000246,0x00000242,0x00000000,0x00050051,0x00000006,0x00000247, + 0x00000242,0x00000001,0x00050051,0x00000006,0x00000248,0x00000245,0x00000000,0x00050051, + 0x00000006,0x00000249,0x00000245,0x00000001,0x00070050,0x00000007,0x0000024a,0x00000246, + 0x00000247,0x00000248,0x00000249,0x0009004f,0x00000007,0x0000024c,0x0000023d,0x0000023d, + 0x00000000,0x00000001,0x00000000,0x00000001,0x00050085,0x00000007,0x0000024d,0x0000024a, + 0x0000024c,0x00050081,0x00000007,0x00000250,0x0000024d,0x0000024c,0x00050081,0x00000007, + 0x00000252,0x00000250,0x00000299,0x000200f9,0x00000257,0x000200f8,0x00000256,0x000100ff, + 0x000200f8,0x00000257,0x000700f5,0x00000007,0x00000294,0x00000252,0x0000023a,0x00000255, + 0x00000253,0x0003003e,0x00000135,0x00000294,0x000200f9,0x0000011f,0x000200f8,0x0000011f, + 0x000500aa,0x0000003e,0x0000013f,0x000000ed,0x00000055,0x000300f7,0x00000141,0x00000000, + 0x000400fa,0x0000013f,0x00000140,0x00000156,0x000200f8,0x00000156,0x00060041,0x00000129, + 0x0000015b,0x00000124,0x00000062,0x000001f0,0x0004003d,0x00000007,0x0000015c,0x0000015b, + 0x00050051,0x00000006,0x0000025f,0x0000015c,0x00000000,0x00050051,0x00000006,0x00000260, + 0x0000015c,0x00000001,0x00050051,0x00000006,0x00000261,0x0000015c,0x00000002,0x00050051, + 0x00000006,0x00000262,0x0000015c,0x00000003,0x00050050,0x00000009,0x00000263,0x0000025f, + 0x00000260,0x00050050,0x00000009,0x00000264,0x00000261,0x00000262,0x00050050,0x0000000a, + 0x00000265,0x00000263,0x00000264,0x00050080,0x0000000f,0x00000161,0x000001f0,0x00000055, + 0x00060041,0x00000129,0x00000162,0x00000124,0x00000062,0x00000161,0x0004003d,0x00000007, + 0x00000163,0x00000162,0x00050091,0x00000009,0x00000167,0x00000265,0x000001f5,0x0007004f, + 0x00000009,0x00000169,0x00000163,0x00000163,0x00000000,0x00000001,0x00050081,0x00000009, + 0x0000016a,0x00000167,0x00000169,0x000500aa,0x0000003e,0x0000016c,0x000000ed,0x00000097, + 0x000500aa,0x0000003e,0x0000016e,0x000000ed,0x00000130,0x000500a6,0x0000003e,0x0000016f, + 0x0000016c,0x0000016e,0x000300f7,0x00000171,0x00000000,0x000400fa,0x0000016f,0x00000170, + 0x00000197,0x000200f8,0x00000197,0x00050051,0x0000000f,0x0000019a,0x000000e8,0x00000001, + 0x0004007c,0x00000006,0x0000019b,0x0000019a,0x00050051,0x00000006,0x0000019e,0x00000163, + 0x00000002,0x00050051,0x00000006,0x000001a0,0x0000016a,0x00000000,0x00050051,0x00000006, + 0x000001a2,0x0000016a,0x00000001,0x00050083,0x00000006,0x000001a6,0x000001a4,0x0000019e, + 0x00070050,0x00000007,0x000001a7,0x000001a0,0x000001a2,0x0000019b,0x000001a6,0x0003003e, + 0x00000154,0x000001a7,0x000200f9,0x00000171,0x000200f8,0x00000170,0x00050051,0x0000000f, + 0x00000173,0x000000e8,0x00000001,0x0004007c,0x00000006,0x00000174,0x00000173,0x0004007f, + 0x00000006,0x00000175,0x00000174,0x00050041,0x0000010e,0x00000176,0x00000154,0x00000130, + 0x0003003e,0x00000176,0x00000175,0x00050051,0x00000006,0x00000179,0x00000163,0x00000002, + 0x000500ba,0x0000003e,0x0000017c,0x00000179,0x0000017b,0x000300f7,0x0000017e,0x00000000, + 0x000400fa,0x0000017c,0x0000017d,0x00000181,0x000200f8,0x00000181,0x00050051,0x00000006, + 0x00000183,0x00000163,0x00000003,0x00050041,0x0000010e,0x00000184,0x00000154,0x00000097, + 0x0003003e,0x00000184,0x00000183,0x000200f9,0x0000017e,0x000200f8,0x0000017d,0x00050041, + 0x0000010e,0x00000180,0x00000154,0x00000097,0x0003003e,0x00000180,0x0000017f,0x000200f9, + 0x0000017e,0x000200f8,0x0000017e,0x000300f7,0x00000188,0x00000000,0x000400fa,0x0000016c, + 0x00000187,0x0000018d,0x000200f8,0x0000018d,0x00050041,0x0000010e,0x0000018e,0x00000154, + 0x00000097,0x0004003d,0x00000006,0x0000018f,0x0000018e,0x0004007f,0x00000006,0x00000190, + 0x0000018f,0x0003003e,0x0000018e,0x00000190,0x00050041,0x0000010e,0x00000193,0x00000154, + 0x0000003d,0x00050051,0x00000006,0x00000194,0x0000016a,0x00000000,0x0003003e,0x00000193, + 0x00000194,0x00050041,0x0000010e,0x00000195,0x00000154,0x00000055,0x00050051,0x00000006, + 0x00000196,0x0000016a,0x00000001,0x0003003e,0x00000195,0x00000196,0x000200f9,0x00000188, + 0x000200f8,0x00000187,0x00050041,0x0000010e,0x00000189,0x00000154,0x00000055,0x0003003e, + 0x00000189,0x00000032,0x00050051,0x00000006,0x0000018b,0x0000016a,0x00000000,0x00050041, + 0x0000010e,0x0000018c,0x00000154,0x0000003d,0x0003003e,0x0000018c,0x0000018b,0x000200f9, + 0x00000188,0x000200f8,0x00000188,0x000200f9,0x00000171,0x000200f8,0x00000171,0x000200f9, + 0x00000141,0x000200f8,0x00000140,0x00050051,0x0000000f,0x00000144,0x000000e8,0x00000001, + 0x0006000c,0x00000007,0x00000145,0x00000001,0x00000040,0x00000144,0x000300f7,0x00000148, + 0x00000000,0x000400fa,0x00000146,0x00000147,0x00000148,0x000200f8,0x00000147,0x00050051, + 0x00000006,0x0000014a,0x00000145,0x00000003,0x0008004f,0x00000025,0x0000014c,0x00000145, + 0x00000145,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000025,0x0000014d,0x0000014c, + 0x0000014a,0x00050051,0x00000006,0x0000014f,0x0000014d,0x00000000,0x00060052,0x00000007, + 0x00000282,0x0000014f,0x00000145,0x00000000,0x00050051,0x00000006,0x00000151,0x0000014d, + 0x00000001,0x00060052,0x00000007,0x00000284,0x00000151,0x00000282,0x00000001,0x00050051, + 0x00000006,0x00000153,0x0000014d,0x00000002,0x00060052,0x00000007,0x00000286,0x00000153, + 0x00000284,0x00000002,0x000200f9,0x00000148,0x000200f8,0x00000148,0x000700f5,0x00000007, + 0x00000295,0x00000145,0x00000140,0x00000286,0x00000147,0x0003003e,0x00000154,0x00000295, + 0x000200f9,0x00000141,0x000200f8,0x00000141,0x00050041,0x000001b2,0x000001b3,0x000000bd, + 0x000001ad,0x0004003d,0x00000006,0x000001b4,0x000001b3,0x00050041,0x000001b2,0x000001b6, + 0x000000bd,0x000001ae,0x0004003d,0x00000006,0x000001b7,0x000001b6,0x00050051,0x00000006, + 0x00000269,0x000000d8,0x00000000,0x00050085,0x00000006,0x0000026b,0x00000269,0x000001b4, + 0x00050083,0x00000006,0x0000026c,0x0000026b,0x00000031,0x00050051,0x00000006,0x0000026e, + 0x000000d8,0x00000001,0x00050085,0x00000006,0x00000270,0x0000026e,0x000001b7,0x0006000c, + 0x00000006,0x00000272,0x00000001,0x00000006,0x000001b7,0x00050083,0x00000006,0x00000273, + 0x00000270,0x00000272,0x00070050,0x00000007,0x00000274,0x0000026c,0x00000273,0x00000032, + 0x00000031,0x00050041,0x00000134,0x000001c9,0x000001c7,0x00000062,0x0003003e,0x000001c9, + 0x00000274,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atlas_blit.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..bd8dc59b6daa7e74ce1a4f05713d5ff9ba23f45b GIT binary patch literal 8236 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 YSR literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h new file mode 100644 index 000000000..e3bde98d9 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h @@ -0,0 +1,348 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_atlas_blit_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000002a6,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000f000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000013e, + 0x0000014a,0x00000157,0x00000167,0x00000180,0x00000186,0x000001a1,0x000001ad,0x000001b0, + 0x000001b1,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x00000098,0x0000674e,0x00030005,0x000000b4,0x00006749, + 0x00030005,0x000000f4,0x00004444,0x00030005,0x000000f8,0x00006277,0x00030005,0x0000011a, + 0x00004344,0x00030005,0x0000011c,0x00003552,0x00030005,0x0000013c,0x0000006a,0x00030005, + 0x0000013e,0x0000316b,0x00040005,0x0000013f,0x61726170,0x0000006d,0x00040005,0x00000141, + 0x61726170,0x0000006d,0x00030005,0x00000143,0x0000006e,0x00030005,0x00000144,0x00004356, + 0x00030005,0x00000146,0x00003949,0x00030005,0x0000014a,0x00003243,0x00040005,0x0000014e, + 0x61726170,0x0000006d,0x00040005,0x00000150,0x61726170,0x0000006d,0x00030005,0x00000153, + 0x00006748,0x00030005,0x00000156,0x00003456,0x00030005,0x00000157,0x0000304e,0x00040005, + 0x00000158,0x61726170,0x0000006d,0x00040005,0x0000015b,0x61726170,0x0000006d,0x00040005, + 0x0000015d,0x61726170,0x0000006d,0x00030005,0x00000163,0x00006747,0x00030005,0x00000167, + 0x00003346,0x00030005,0x0000016d,0x0000336f,0x00040005,0x00000170,0x30653742,0x00000000, + 0x00040005,0x00000179,0x61726170,0x0000006d,0x00030005,0x00000180,0x00003065,0x00040005, + 0x00000181,0x61726170,0x0000006d,0x00060005,0x00000186,0x465f6c67,0x43676172,0x64726f6f, + 0x00000000,0x00030005,0x00000188,0x0000424d,0x00040006,0x00000188,0x00000000,0x00003376, + 0x00040006,0x00000188,0x00000001,0x00003377,0x00030005,0x0000018a,0x0000006b,0x00040005, + 0x0000018d,0x61726170,0x0000006d,0x00040005,0x00000190,0x61726170,0x0000006d,0x00040005, + 0x00000193,0x61726170,0x0000006d,0x00040005,0x00000197,0x61726170,0x0000006d,0x00030005, + 0x000001a1,0x0000316d,0x00030005,0x000001ad,0x00003159,0x00030005,0x000001b0,0x00003361, + 0x00030005,0x000001b1,0x00003469,0x00040047,0x00000098,0x00000001,0x00000007,0x00040047, + 0x000000b4,0x00000001,0x00000002,0x00030047,0x000000f4,0x00000000,0x00040047,0x000000f4, + 0x00000021,0x00000009,0x00040047,0x000000f4,0x00000022,0x00000000,0x00030047,0x000000f8, + 0x00000000,0x00040047,0x000000f8,0x00000021,0x00000009,0x00040047,0x000000f8,0x00000022, + 0x00000000,0x00030047,0x0000011a,0x00000000,0x00040047,0x0000011a,0x00000021,0x0000000c, + 0x00040047,0x0000011a,0x00000022,0x00000001,0x00030047,0x0000011c,0x00000000,0x00040047, + 0x0000011c,0x00000021,0x0000000c,0x00040047,0x0000011c,0x00000022,0x00000001,0x00030047, + 0x0000013c,0x00000000,0x00040047,0x0000013e,0x0000001e,0x00000000,0x00030047,0x00000143, + 0x00000000,0x00030047,0x00000144,0x00000000,0x00040047,0x00000144,0x00000021,0x0000000b, + 0x00040047,0x00000144,0x00000022,0x00000000,0x00030047,0x00000145,0x00000000,0x00030047, + 0x00000146,0x00000000,0x00040047,0x00000146,0x00000021,0x0000000b,0x00040047,0x00000146, + 0x00000022,0x00000000,0x00030047,0x00000147,0x00000000,0x00040047,0x0000014a,0x0000001e, + 0x00000001,0x00030047,0x0000014c,0x00000000,0x00030047,0x0000014d,0x00000000,0x00030047, + 0x0000014e,0x00000000,0x00030047,0x00000150,0x00000000,0x00030047,0x00000152,0x00000000, + 0x00040047,0x00000153,0x00000001,0x00000001,0x00030047,0x00000156,0x00000000,0x00040047, + 0x00000157,0x0000001e,0x00000005,0x00030047,0x0000015b,0x00000000,0x00030047,0x0000015d, + 0x00000000,0x00030047,0x0000015f,0x00000000,0x00030047,0x00000160,0x00000000,0x00030047, + 0x00000161,0x00000000,0x00030047,0x00000162,0x00000000,0x00040047,0x00000163,0x00000001, + 0x00000000,0x00030047,0x00000167,0x00000000,0x00030047,0x00000167,0x0000000e,0x00040047, + 0x00000167,0x0000001e,0x00000004,0x00030047,0x00000168,0x00000000,0x00030047,0x0000016d, + 0x00000000,0x00030047,0x00000170,0x00000000,0x00040047,0x00000170,0x00000021,0x00000001, + 0x00040047,0x00000170,0x00000022,0x00000002,0x00040047,0x00000170,0x0000002b,0x00000001, + 0x00030047,0x00000171,0x00000000,0x00030047,0x00000176,0x00000000,0x00030047,0x00000177, + 0x00000000,0x00030047,0x00000178,0x00000000,0x00030047,0x00000179,0x00000000,0x00030047, + 0x0000017b,0x00000000,0x00030047,0x0000017c,0x00000000,0x00030047,0x0000017d,0x00000000, + 0x00030047,0x0000017e,0x00000000,0x00030047,0x00000180,0x00000000,0x00040047,0x00000180, + 0x0000001e,0x00000001,0x00030047,0x00000181,0x00000000,0x00030047,0x00000183,0x00000000, + 0x00030047,0x00000184,0x00000000,0x00030047,0x00000185,0x00000000,0x00040047,0x00000186, + 0x0000000b,0x0000000f,0x00030047,0x00000188,0x00000002,0x00050048,0x00000188,0x00000000, + 0x00000023,0x00000058,0x00050048,0x00000188,0x00000001,0x00000023,0x0000005c,0x00040047, + 0x0000018a,0x00000021,0x00000000,0x00040047,0x0000018a,0x00000022,0x00000000,0x00030047, + 0x0000018d,0x00000000,0x00030047,0x0000018e,0x00000000,0x00030047,0x0000018f,0x00000000, + 0x00030047,0x00000193,0x00000000,0x00030047,0x00000197,0x00000000,0x00030047,0x000001a1, + 0x00000000,0x00040047,0x000001a1,0x0000001e,0x00000000,0x00030047,0x000001a2,0x00000000, + 0x00030047,0x000001ad,0x00000000,0x00030047,0x000001ad,0x0000000e,0x00040047,0x000001ad, + 0x0000001e,0x00000006,0x00030047,0x000001b0,0x0000000e,0x00040047,0x000001b0,0x0000001e, + 0x00000007,0x00040047,0x000001b1,0x0000001e,0x00000008,0x00030047,0x000001b3,0x00000000, + 0x00030047,0x000001bb,0x00000000,0x00030047,0x000001bc,0x00000000,0x00030047,0x000001bd, + 0x00000000,0x00030047,0x000001be,0x00000000,0x00030047,0x000001bf,0x00000000,0x00030047, + 0x000001c0,0x00000000,0x00030047,0x000001ca,0x00000000,0x00030047,0x000001cf,0x00000000, + 0x00030047,0x000001f9,0x00000000,0x00030047,0x000001fa,0x00000000,0x00030047,0x000001ff, + 0x00000000,0x00030047,0x00000202,0x00000000,0x00030047,0x00000207,0x00000000,0x00030047, + 0x00000208,0x00000000,0x00030047,0x00000209,0x00000000,0x00030047,0x0000020a,0x00000000, + 0x00030047,0x00000217,0x00000000,0x00030047,0x00000218,0x00000000,0x00030047,0x0000021c, + 0x00000000,0x00030047,0x0000021d,0x00000000,0x00030047,0x00000223,0x00000000,0x00030047, + 0x00000224,0x00000000,0x00030047,0x00000225,0x00000000,0x00030047,0x00000227,0x00000000, + 0x00030047,0x0000022a,0x00000000,0x00030047,0x0000022b,0x00000000,0x00030047,0x0000022c, + 0x00000000,0x00030047,0x00000231,0x00000000,0x00030047,0x00000232,0x00000000,0x00030047, + 0x00000233,0x00000000,0x00030047,0x00000236,0x00000000,0x00030047,0x00000237,0x00000000, + 0x00030047,0x00000238,0x00000000,0x00030047,0x0000023a,0x00000000,0x00030047,0x0000023b, + 0x00000000,0x00030047,0x0000023d,0x00000000,0x00030047,0x00000241,0x00000000,0x00030047, + 0x00000242,0x00000000,0x00030047,0x00000245,0x00000000,0x00030047,0x00000246,0x00000000, + 0x00030047,0x00000247,0x00000000,0x00030047,0x00000248,0x00000000,0x00030047,0x0000024a, + 0x00000000,0x00030047,0x00000251,0x00000000,0x00030047,0x00000253,0x00000000,0x00030047, + 0x00000254,0x00000000,0x00030047,0x00000256,0x00000000,0x00030047,0x00000257,0x00000000, + 0x00030047,0x00000259,0x00000000,0x00030047,0x0000025a,0x00000000,0x00030047,0x0000025b, + 0x00000000,0x00030047,0x0000025e,0x00000000,0x00030047,0x0000025f,0x00000000,0x00030047, + 0x00000260,0x00000000,0x00030047,0x00000261,0x00000000,0x00030047,0x00000263,0x00000000, + 0x00030047,0x00000264,0x00000000,0x00030047,0x00000265,0x00000000,0x00030047,0x00000266, + 0x00000000,0x00030047,0x00000267,0x00000000,0x00030047,0x00000269,0x00000000,0x00030047, + 0x0000026b,0x00000000,0x00030047,0x0000026c,0x00000000,0x00030047,0x0000026d,0x00000000, + 0x00030047,0x0000026e,0x00000000,0x00030047,0x00000270,0x00000000,0x00030047,0x00000271, + 0x00000000,0x00030047,0x00000273,0x00000000,0x00030047,0x00000274,0x00000000,0x00030047, + 0x00000275,0x00000000,0x00030047,0x00000277,0x00000000,0x00030047,0x00000279,0x00000000, + 0x00030047,0x0000027b,0x00000000,0x00030047,0x0000027d,0x00000000,0x00030047,0x0000027f, + 0x00000000,0x00030047,0x00000280,0x00000000,0x00030047,0x00000282,0x00000000,0x00030047, + 0x00000283,0x00000000,0x00030047,0x00000284,0x00000000,0x00030047,0x00000288,0x00000000, + 0x00030047,0x00000289,0x00000000,0x00030047,0x0000028b,0x00000000,0x00030047,0x0000028c, + 0x00000000,0x00030047,0x0000028d,0x00000000,0x00030047,0x0000028f,0x00000000,0x00030047, + 0x00000291,0x00000000,0x00030047,0x00000292,0x00000000,0x00030047,0x00000293,0x00000000, + 0x00030047,0x00000294,0x00000000,0x00030047,0x0000029e,0x00000000,0x00030047,0x0000029f, + 0x00000000,0x00030047,0x000002a0,0x00000000,0x00030047,0x000002a1,0x00000000,0x00030047, + 0x000002a2,0x00000000,0x00030047,0x000002a3,0x00000000,0x00030047,0x000002a4,0x00000000, + 0x00030047,0x000002a5,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020, + 0x00000008,0x00000007,0x00000007,0x00040020,0x0000000d,0x00000007,0x00000006,0x00040017, + 0x00000012,0x00000006,0x00000003,0x00040020,0x00000013,0x00000007,0x00000012,0x00040017, + 0x00000025,0x00000006,0x00000002,0x00040020,0x00000026,0x00000007,0x00000025,0x00040015, + 0x00000043,0x00000020,0x00000000,0x0004002b,0x00000043,0x00000044,0x00000000,0x0004002b, + 0x00000043,0x00000047,0x00000001,0x0004002b,0x00000043,0x0000004a,0x00000002,0x0004002b, + 0x00000043,0x0000004e,0x00000003,0x0004002b,0x00000006,0x00000063,0x00000000,0x00020014, + 0x00000064,0x0004002b,0x00000006,0x00000069,0x3f800000,0x0004002b,0x00000006,0x00000082, + 0x3d897143,0x0004002b,0x00000006,0x00000086,0x3bbf4590,0x0004002b,0x00000006,0x0000008d, + 0x4253ee82,0x00030030,0x00000064,0x00000098,0x00030030,0x00000064,0x000000b4,0x00050034, + 0x00000064,0x000000b5,0x000000a8,0x000000b4,0x0004002b,0x00000006,0x000000c4,0xbf800000, + 0x0004002b,0x00000006,0x000000e2,0x3f7f8000,0x0004002b,0x00000006,0x000000e5,0x3a800000, + 0x0004002b,0x00000006,0x000000e8,0x3b000000,0x00090019,0x000000f2,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000000f3,0x00000000, + 0x000000f2,0x0004003b,0x000000f3,0x000000f4,0x00000000,0x0002001a,0x000000f6,0x00040020, + 0x000000f7,0x00000000,0x000000f6,0x0004003b,0x000000f7,0x000000f8,0x00000000,0x0003001b, + 0x000000fa,0x000000f2,0x00050034,0x00000064,0x00000105,0x000000a8,0x000000b4,0x0004003b, + 0x000000f3,0x0000011a,0x00000000,0x0004003b,0x000000f7,0x0000011c,0x00000000,0x00050034, + 0x00000064,0x00000128,0x000000a8,0x000000b4,0x00040020,0x0000013d,0x00000001,0x00000007, + 0x0004003b,0x0000013d,0x0000013e,0x00000001,0x0004003b,0x000000f3,0x00000144,0x00000000, + 0x0004003b,0x000000f7,0x00000146,0x00000000,0x00040020,0x00000149,0x00000001,0x00000025, + 0x0004003b,0x00000149,0x0000014a,0x00000001,0x00030030,0x00000064,0x00000153,0x0004003b, + 0x0000013d,0x00000157,0x00000001,0x00030030,0x00000064,0x00000163,0x00040020,0x00000166, + 0x00000001,0x00000006,0x0004003b,0x00000166,0x00000167,0x00000001,0x00090019,0x0000016e, + 0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020, + 0x0000016f,0x00000000,0x0000016e,0x0004003b,0x0000016f,0x00000170,0x00000000,0x00040015, + 0x00000172,0x00000020,0x00000001,0x0004002b,0x00000172,0x00000173,0x00000000,0x00040017, + 0x00000174,0x00000172,0x00000002,0x0005002c,0x00000174,0x00000175,0x00000173,0x00000173, + 0x00040020,0x0000017f,0x00000003,0x00000007,0x0004003b,0x0000017f,0x00000180,0x00000003, + 0x0004003b,0x0000013d,0x00000186,0x00000001,0x0004001e,0x00000188,0x00000006,0x00000006, + 0x00040020,0x00000189,0x00000002,0x00000188,0x0004003b,0x00000189,0x0000018a,0x00000002, + 0x00040020,0x00000194,0x00000002,0x00000006,0x0004003b,0x0000017f,0x000001a1,0x00000003, + 0x0004003b,0x00000166,0x000001ad,0x00000001,0x00040017,0x000001ae,0x00000043,0x00000002, + 0x00040020,0x000001af,0x00000001,0x000001ae,0x0004003b,0x000001af,0x000001b0,0x00000001, + 0x0004003b,0x00000149,0x000001b1,0x00000001,0x0004002b,0x00000006,0x000001b2,0xc0000000, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b, + 0x0000000d,0x00000292,0x00000007,0x0004003b,0x0000000d,0x00000293,0x00000007,0x0004003b, + 0x0000000d,0x00000294,0x00000007,0x0004003b,0x00000013,0x00000280,0x00000007,0x0004003b, + 0x00000026,0x00000281,0x00000007,0x0004003b,0x0000000d,0x00000282,0x00000007,0x0004003b, + 0x0000000d,0x00000283,0x00000007,0x0004003b,0x00000013,0x00000284,0x00000007,0x0004003b, + 0x00000008,0x00000274,0x00000007,0x0004003b,0x00000008,0x00000275,0x00000007,0x0004003b, + 0x0000000d,0x00000271,0x00000007,0x0004003b,0x0000000d,0x0000026e,0x00000007,0x0004003b, + 0x00000026,0x0000025f,0x00000007,0x0004003b,0x0000000d,0x00000260,0x00000007,0x0004003b, + 0x0000000d,0x00000261,0x00000007,0x0004003b,0x00000008,0x0000025a,0x00000007,0x0004003b, + 0x00000008,0x0000025b,0x00000007,0x0004003b,0x0000000d,0x00000257,0x00000007,0x0004003b, + 0x0000000d,0x00000254,0x00000007,0x0004003b,0x00000008,0x00000247,0x00000007,0x0004003b, + 0x00000008,0x00000248,0x00000007,0x0004003b,0x0000000d,0x00000237,0x00000007,0x0004003b, + 0x00000013,0x00000238,0x00000007,0x0004003b,0x00000008,0x00000232,0x00000007,0x0004003b, + 0x00000008,0x00000233,0x00000007,0x0004003b,0x00000008,0x000001b3,0x00000007,0x0004003b, + 0x00000008,0x000001b4,0x00000007,0x0004003b,0x0000000d,0x000001b5,0x00000007,0x0004003b, + 0x0000000d,0x000001b6,0x00000007,0x0004003b,0x0000000d,0x000001b7,0x00000007,0x0004003b, + 0x0000000d,0x000001b8,0x00000007,0x0004003b,0x0000000d,0x000001b9,0x00000007,0x0004003b, + 0x0000000d,0x000001ba,0x00000007,0x0004003b,0x0000000d,0x000001bb,0x00000007,0x0004003b, + 0x0000000d,0x000001bc,0x00000007,0x0004003b,0x00000008,0x000001bd,0x00000007,0x0004003b, + 0x00000013,0x000001be,0x00000007,0x0004003b,0x0000000d,0x000001bf,0x00000007,0x0004003b, + 0x00000008,0x000001c0,0x00000007,0x0004003b,0x00000008,0x0000013c,0x00000007,0x0004003b, + 0x00000008,0x0000013f,0x00000007,0x0004003b,0x0000000d,0x00000141,0x00000007,0x0004003b, + 0x0000000d,0x00000143,0x00000007,0x0004003b,0x0000000d,0x0000014e,0x00000007,0x0004003b, + 0x0000000d,0x00000150,0x00000007,0x0004003b,0x0000000d,0x00000156,0x00000007,0x0004003b, + 0x00000008,0x00000158,0x00000007,0x0004003b,0x00000008,0x0000015b,0x00000007,0x0004003b, + 0x0000000d,0x0000015d,0x00000007,0x0004003b,0x0000000d,0x0000016d,0x00000007,0x0004003b, + 0x0000000d,0x00000179,0x00000007,0x0004003b,0x0000000d,0x00000181,0x00000007,0x0004003b, + 0x00000013,0x0000018d,0x00000007,0x0004003b,0x00000026,0x00000190,0x00000007,0x0004003b, + 0x0000000d,0x00000193,0x00000007,0x0004003b,0x0000000d,0x00000197,0x00000007,0x0004003d, + 0x00000007,0x00000140,0x0000013e,0x0003003e,0x0000013f,0x00000140,0x0003003e,0x00000141, + 0x00000069,0x00050041,0x0000000d,0x000001c2,0x0000013f,0x0000004e,0x0004003d,0x00000006, + 0x000001c3,0x000001c2,0x000500be,0x00000064,0x000001c4,0x000001c3,0x00000063,0x000300f7, + 0x00000230,0x00000000,0x000400fa,0x000001c4,0x000001c5,0x000001d3,0x000200f8,0x000001c5, + 0x0004003d,0x00000007,0x000001c6,0x0000013f,0x0003003e,0x000001b4,0x000001c6,0x0004003d, + 0x00000007,0x00000235,0x000001b4,0x0003003e,0x00000232,0x00000235,0x0004003d,0x00000007, + 0x00000236,0x00000232,0x0003003e,0x00000233,0x00000236,0x0004003d,0x00000007,0x000001c7, + 0x00000233,0x0003003e,0x000001b3,0x000001c7,0x000300f7,0x000001d2,0x00000000,0x000400fa, + 0x000000b5,0x000001c8,0x000001cc,0x000200f8,0x000001c8,0x0004003d,0x00000006,0x000001c9, + 0x00000141,0x0004003d,0x00000007,0x000001ca,0x000001b3,0x0005008e,0x00000007,0x000001cb, + 0x000001ca,0x000001c9,0x0003003e,0x000001b3,0x000001cb,0x000200f9,0x000001d2,0x000200f8, + 0x000001cc,0x0004003d,0x00000006,0x000001cd,0x00000141,0x00050041,0x0000000d,0x000001ce, + 0x000001b3,0x0000004e,0x0004003d,0x00000006,0x000001cf,0x000001ce,0x00050085,0x00000006, + 0x000001d0,0x000001cf,0x000001cd,0x0003003e,0x000001ce,0x000001d0,0x000200f9,0x000001d2, + 0x000200f8,0x000001d2,0x000200f9,0x00000230,0x000200f8,0x000001d3,0x0004003d,0x00000006, + 0x000001d5,0x000001c2,0x000500ba,0x00000064,0x000001d6,0x000001d5,0x000000c4,0x000300f7, + 0x0000022f,0x00000000,0x000400fa,0x000001d6,0x000001d7,0x00000212,0x000200f8,0x000001d7, + 0x00050041,0x0000000d,0x000001d8,0x0000013f,0x0000004a,0x0004003d,0x00000006,0x000001d9, + 0x000001d8,0x000500ba,0x00000064,0x000001da,0x000001d9,0x00000063,0x000300f7,0x000001e2, + 0x00000000,0x000400fa,0x000001da,0x000001db,0x000001de,0x000200f8,0x000001db,0x00050041, + 0x0000000d,0x000001dc,0x0000013f,0x00000044,0x0004003d,0x00000006,0x000001dd,0x000001dc, + 0x0003003e,0x000001b6,0x000001dd,0x000200f9,0x000001e2,0x000200f8,0x000001de,0x0004003d, + 0x00000007,0x000001df,0x0000013f,0x0007004f,0x00000025,0x000001e0,0x000001df,0x000001df, + 0x00000000,0x00000001,0x0006000c,0x00000006,0x000001e1,0x00000001,0x00000042,0x000001e0, + 0x0003003e,0x000001b6,0x000001e1,0x000200f9,0x000001e2,0x000200f8,0x000001e2,0x0004003d, + 0x00000006,0x000001e3,0x000001b6,0x0003003e,0x000001b5,0x000001e3,0x0004003d,0x00000006, + 0x000001e4,0x000001b5,0x0008000c,0x00000006,0x000001e5,0x00000001,0x0000002b,0x000001e4, + 0x00000063,0x00000069,0x0003003e,0x000001b5,0x000001e5,0x0004003d,0x00000006,0x000001e7, + 0x000001d8,0x0006000c,0x00000006,0x000001e8,0x00000001,0x00000004,0x000001e7,0x0003003e, + 0x000001b7,0x000001e8,0x0004003d,0x00000006,0x000001e9,0x000001b7,0x000500ba,0x00000064, + 0x000001ea,0x000001e9,0x00000069,0x000300f7,0x000001f4,0x00000000,0x000400fa,0x000001ea, + 0x000001eb,0x000001ef,0x000200f8,0x000001eb,0x0004003d,0x00000006,0x000001ec,0x000001b5, + 0x00050085,0x00000006,0x000001ed,0x000000e2,0x000001ec,0x00050081,0x00000006,0x000001ee, + 0x000001ed,0x000000e5,0x0003003e,0x000001b9,0x000001ee,0x000200f9,0x000001f4,0x000200f8, + 0x000001ef,0x0004003d,0x00000006,0x000001f0,0x000001b5,0x00050085,0x00000006,0x000001f1, + 0x000000e8,0x000001f0,0x0004003d,0x00000006,0x000001f2,0x000001b7,0x00050081,0x00000006, + 0x000001f3,0x000001f1,0x000001f2,0x0003003e,0x000001b9,0x000001f3,0x000200f9,0x000001f4, + 0x000200f8,0x000001f4,0x0004003d,0x00000006,0x000001f5,0x000001b9,0x0003003e,0x000001b8, + 0x000001f5,0x0004003d,0x00000006,0x000001f7,0x000001c2,0x0004007f,0x00000006,0x000001f8, + 0x000001f7,0x0003003e,0x000001ba,0x000001f8,0x0004003d,0x000000f2,0x000001f9,0x000000f4, + 0x0004003d,0x000000f6,0x000001fa,0x000000f8,0x00050056,0x000000fa,0x000001fb,0x000001f9, + 0x000001fa,0x0004003d,0x00000006,0x000001fc,0x000001b8,0x0004003d,0x00000006,0x000001fd, + 0x000001ba,0x00050050,0x00000025,0x000001fe,0x000001fc,0x000001fd,0x00070058,0x00000007, + 0x000001ff,0x000001fb,0x000001fe,0x00000002,0x00000063,0x0003003e,0x000001b3,0x000001ff, + 0x0004003d,0x00000006,0x00000200,0x00000141,0x00050041,0x0000000d,0x00000201,0x000001b3, + 0x0000004e,0x0004003d,0x00000006,0x00000202,0x00000201,0x00050085,0x00000006,0x00000203, + 0x00000202,0x00000200,0x0003003e,0x00000201,0x00000203,0x000300f7,0x00000211,0x00000000, + 0x000400fa,0x00000105,0x00000205,0x00000211,0x000200f8,0x00000205,0x0004003d,0x00000006, + 0x00000207,0x00000201,0x0004003d,0x00000007,0x00000208,0x000001b3,0x0008004f,0x00000012, + 0x00000209,0x00000208,0x00000208,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000012, + 0x0000020a,0x00000209,0x00000207,0x00050041,0x0000000d,0x0000020b,0x000001b3,0x00000044, + 0x00050051,0x00000006,0x0000020c,0x0000020a,0x00000000,0x0003003e,0x0000020b,0x0000020c, + 0x00050041,0x0000000d,0x0000020d,0x000001b3,0x00000047,0x00050051,0x00000006,0x0000020e, + 0x0000020a,0x00000001,0x0003003e,0x0000020d,0x0000020e,0x00050041,0x0000000d,0x0000020f, + 0x000001b3,0x0000004a,0x00050051,0x00000006,0x00000210,0x0000020a,0x00000002,0x0003003e, + 0x0000020f,0x00000210,0x000200f9,0x00000211,0x000200f8,0x00000211,0x000200f9,0x0000022f, + 0x000200f8,0x00000212,0x0004003d,0x00000006,0x00000214,0x000001c2,0x00050083,0x00000006, + 0x00000216,0x000001b2,0x00000214,0x0003003e,0x000001bb,0x00000216,0x0004003d,0x000000f2, + 0x00000217,0x0000011a,0x0004003d,0x000000f6,0x00000218,0x0000011c,0x00050056,0x000000fa, + 0x00000219,0x00000217,0x00000218,0x0004003d,0x00000007,0x0000021a,0x0000013f,0x0007004f, + 0x00000025,0x0000021b,0x0000021a,0x0000021a,0x00000000,0x00000001,0x0004003d,0x00000006, + 0x0000021c,0x000001bb,0x00070058,0x00000007,0x0000021d,0x00000219,0x0000021b,0x00000002, + 0x0000021c,0x0003003e,0x000001b3,0x0000021d,0x00050041,0x0000000d,0x0000021e,0x0000013f, + 0x0000004a,0x0004003d,0x00000006,0x0000021f,0x0000021e,0x0004003d,0x00000006,0x00000220, + 0x00000141,0x00050085,0x00000006,0x00000221,0x0000021f,0x00000220,0x0003003e,0x000001bc, + 0x00000221,0x000300f7,0x0000022e,0x00000000,0x000400fa,0x00000128,0x00000222,0x00000226, + 0x000200f8,0x00000222,0x0004003d,0x00000006,0x00000223,0x000001bc,0x0004003d,0x00000007, + 0x00000224,0x000001b3,0x0005008e,0x00000007,0x00000225,0x00000224,0x00000223,0x0003003e, + 0x000001b3,0x00000225,0x000200f9,0x0000022e,0x000200f8,0x00000226,0x0004003d,0x00000007, + 0x00000227,0x000001b3,0x0003003e,0x000001bd,0x00000227,0x0004003d,0x00000007,0x0000023a, + 0x000001bd,0x0008004f,0x00000012,0x0000023b,0x0000023a,0x0000023a,0x00000000,0x00000001, + 0x00000002,0x00050041,0x0000000d,0x0000023c,0x000001bd,0x0000004e,0x0004003d,0x00000006, + 0x0000023d,0x0000023c,0x000500b7,0x00000064,0x0000023e,0x0000023d,0x00000063,0x000300f7, + 0x00000244,0x00000000,0x000400fa,0x0000023e,0x0000023f,0x00000243,0x000200f8,0x0000023f, + 0x0004003d,0x00000006,0x00000241,0x0000023c,0x00050088,0x00000006,0x00000242,0x00000069, + 0x00000241,0x0003003e,0x00000237,0x00000242,0x000200f9,0x00000244,0x000200f8,0x00000243, + 0x0003003e,0x00000237,0x00000063,0x000200f9,0x00000244,0x000200f8,0x00000244,0x0004003d, + 0x00000006,0x00000245,0x00000237,0x0005008e,0x00000012,0x00000246,0x0000023b,0x00000245, + 0x0003003e,0x00000238,0x00000246,0x0004003d,0x00000012,0x00000228,0x00000238,0x00050041, + 0x0000000d,0x00000229,0x000001b3,0x0000004e,0x0004003d,0x00000006,0x0000022a,0x00000229, + 0x0004003d,0x00000006,0x0000022b,0x000001bc,0x00050085,0x00000006,0x0000022c,0x0000022a, + 0x0000022b,0x0003003e,0x000001be,0x00000228,0x0003003e,0x000001bf,0x0000022c,0x0004003d, + 0x00000012,0x0000024a,0x000001be,0x00050041,0x0000000d,0x0000024b,0x00000247,0x00000044, + 0x00050051,0x00000006,0x0000024c,0x0000024a,0x00000000,0x0003003e,0x0000024b,0x0000024c, + 0x00050041,0x0000000d,0x0000024d,0x00000247,0x00000047,0x00050051,0x00000006,0x0000024e, + 0x0000024a,0x00000001,0x0003003e,0x0000024d,0x0000024e,0x00050041,0x0000000d,0x0000024f, + 0x00000247,0x0000004a,0x00050051,0x00000006,0x00000250,0x0000024a,0x00000002,0x0003003e, + 0x0000024f,0x00000250,0x0004003d,0x00000006,0x00000251,0x000001bf,0x00050041,0x0000000d, + 0x00000252,0x00000247,0x0000004e,0x0003003e,0x00000252,0x00000251,0x0004003d,0x00000007, + 0x00000253,0x00000247,0x0003003e,0x00000248,0x00000253,0x0004003d,0x00000007,0x0000022d, + 0x00000248,0x0003003e,0x000001b3,0x0000022d,0x000200f9,0x0000022e,0x000200f8,0x0000022e, + 0x000200f9,0x0000022f,0x000200f8,0x0000022f,0x000200f9,0x00000230,0x000200f8,0x00000230, + 0x0004003d,0x00000007,0x00000231,0x000001b3,0x0003003e,0x000001c0,0x00000231,0x0004003d, + 0x00000007,0x00000142,0x000001c0,0x0003003e,0x0000013c,0x00000142,0x0004003d,0x000000f2, + 0x00000145,0x00000144,0x0004003d,0x000000f6,0x00000147,0x00000146,0x00050056,0x000000fa, + 0x00000148,0x00000145,0x00000147,0x0004003d,0x00000025,0x0000014b,0x0000014a,0x00070058, + 0x00000007,0x0000014c,0x00000148,0x0000014b,0x00000002,0x00000063,0x00050051,0x00000006, + 0x0000014d,0x0000014c,0x00000000,0x0003003e,0x0000014e,0x00000063,0x0004003d,0x00000006, + 0x00000256,0x0000014e,0x0003003e,0x00000254,0x00000256,0x0004003d,0x00000006,0x0000014f, + 0x00000254,0x0003003e,0x00000150,0x00000069,0x0004003d,0x00000006,0x00000259,0x00000150, + 0x0003003e,0x00000257,0x00000259,0x0004003d,0x00000006,0x00000151,0x00000257,0x0008000c, + 0x00000006,0x00000152,0x00000001,0x0000002b,0x0000014d,0x0000014f,0x00000151,0x0003003e, + 0x00000143,0x00000152,0x000300f7,0x00000155,0x00000000,0x000400fa,0x00000153,0x00000154, + 0x00000155,0x000200f8,0x00000154,0x0004003d,0x00000007,0x00000159,0x00000157,0x0003003e, + 0x00000158,0x00000159,0x0004003d,0x00000007,0x0000025d,0x00000158,0x0003003e,0x0000025a, + 0x0000025d,0x0004003d,0x00000007,0x0000025e,0x0000025a,0x0003003e,0x0000025b,0x0000025e, + 0x0004003d,0x00000007,0x0000015a,0x0000025b,0x0003003e,0x0000015b,0x0000015a,0x0004003d, + 0x00000007,0x00000263,0x0000015b,0x0007004f,0x00000025,0x00000264,0x00000263,0x00000263, + 0x00000000,0x00000001,0x0004003d,0x00000007,0x00000265,0x0000015b,0x0007004f,0x00000025, + 0x00000266,0x00000265,0x00000265,0x00000002,0x00000003,0x0007000c,0x00000025,0x00000267, + 0x00000001,0x00000025,0x00000264,0x00000266,0x0003003e,0x0000025f,0x00000267,0x00050041, + 0x0000000d,0x00000268,0x0000025f,0x00000044,0x0004003d,0x00000006,0x00000269,0x00000268, + 0x00050041,0x0000000d,0x0000026a,0x0000025f,0x00000047,0x0004003d,0x00000006,0x0000026b, + 0x0000026a,0x0007000c,0x00000006,0x0000026c,0x00000001,0x00000025,0x00000269,0x0000026b, + 0x0003003e,0x00000260,0x0000026c,0x0004003d,0x00000006,0x0000026d,0x00000260,0x0003003e, + 0x00000261,0x0000026d,0x0004003d,0x00000006,0x0000015c,0x00000261,0x0003003e,0x0000015d, + 0x00000063,0x0004003d,0x00000006,0x00000270,0x0000015d,0x0003003e,0x0000026e,0x00000270, + 0x0004003d,0x00000006,0x0000015e,0x0000026e,0x0007000c,0x00000006,0x0000015f,0x00000001, + 0x00000028,0x0000015c,0x0000015e,0x0003003e,0x00000156,0x0000015f,0x0004003d,0x00000006, + 0x00000160,0x00000156,0x0004003d,0x00000006,0x00000161,0x00000143,0x0007000c,0x00000006, + 0x00000162,0x00000001,0x00000025,0x00000160,0x00000161,0x0003003e,0x00000143,0x00000162, + 0x000200f9,0x00000155,0x000200f8,0x00000155,0x000300f7,0x00000165,0x00000000,0x000400fa, + 0x00000163,0x00000164,0x00000165,0x000200f8,0x00000164,0x0004003d,0x00000006,0x00000168, + 0x00000167,0x000500b7,0x00000064,0x00000169,0x00000168,0x00000063,0x000200f9,0x00000165, + 0x000200f8,0x00000165,0x000700f5,0x00000064,0x0000016a,0x00000163,0x00000155,0x00000169, + 0x00000164,0x000300f7,0x0000016c,0x00000000,0x000400fa,0x0000016a,0x0000016b,0x0000016c, + 0x000200f8,0x0000016b,0x0004003d,0x0000016e,0x00000171,0x00000170,0x00050062,0x00000007, + 0x00000176,0x00000171,0x00000175,0x00050051,0x00000006,0x00000177,0x00000176,0x00000000, + 0x0003003e,0x0000016d,0x00000177,0x0004003d,0x00000006,0x00000178,0x0000016d,0x0003003e, + 0x00000179,0x00000063,0x0004003d,0x00000006,0x00000273,0x00000179,0x0003003e,0x00000271, + 0x00000273,0x0004003d,0x00000006,0x0000017a,0x00000271,0x0007000c,0x00000006,0x0000017b, + 0x00000001,0x00000028,0x00000178,0x0000017a,0x0003003e,0x0000016d,0x0000017b,0x0004003d, + 0x00000006,0x0000017c,0x00000143,0x0004003d,0x00000006,0x0000017d,0x0000016d,0x0007000c, + 0x00000006,0x0000017e,0x00000001,0x00000025,0x0000017c,0x0000017d,0x0003003e,0x00000143, + 0x0000017e,0x000200f9,0x0000016c,0x000200f8,0x0000016c,0x0003003e,0x00000181,0x00000063, + 0x0004003d,0x00000006,0x00000277,0x00000181,0x00050041,0x0000000d,0x00000278,0x00000274, + 0x00000044,0x0003003e,0x00000278,0x00000277,0x0004003d,0x00000006,0x00000279,0x00000181, + 0x00050041,0x0000000d,0x0000027a,0x00000274,0x00000047,0x0003003e,0x0000027a,0x00000279, + 0x0004003d,0x00000006,0x0000027b,0x00000181,0x00050041,0x0000000d,0x0000027c,0x00000274, + 0x0000004a,0x0003003e,0x0000027c,0x0000027b,0x0004003d,0x00000006,0x0000027d,0x00000181, + 0x00050041,0x0000000d,0x0000027e,0x00000274,0x0000004e,0x0003003e,0x0000027e,0x0000027d, + 0x0004003d,0x00000007,0x0000027f,0x00000274,0x0003003e,0x00000275,0x0000027f,0x0004003d, + 0x00000007,0x00000182,0x00000275,0x0003003e,0x00000180,0x00000182,0x0004003d,0x00000007, + 0x00000183,0x0000013c,0x0004003d,0x00000006,0x00000184,0x00000143,0x0005008e,0x00000007, + 0x00000185,0x00000183,0x00000184,0x0003003e,0x0000013c,0x00000185,0x0004003d,0x00000007, + 0x0000018e,0x0000013c,0x0008004f,0x00000012,0x0000018f,0x0000018e,0x0000018e,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x0000018d,0x0000018f,0x0004003d,0x00000007,0x00000191, + 0x00000186,0x0007004f,0x00000025,0x00000192,0x00000191,0x00000191,0x00000000,0x00000001, + 0x0003003e,0x00000190,0x00000192,0x00050041,0x00000194,0x00000195,0x0000018a,0x00000044, + 0x0004003d,0x00000006,0x00000196,0x00000195,0x0003003e,0x00000193,0x00000196,0x00050041, + 0x00000194,0x00000198,0x0000018a,0x00000047,0x0004003d,0x00000006,0x00000199,0x00000198, + 0x0003003e,0x00000197,0x00000199,0x000300f7,0x00000290,0x00000000,0x000400fa,0x00000098, + 0x00000286,0x0000028e,0x000200f8,0x00000286,0x0004003d,0x00000025,0x00000287,0x00000190, + 0x0003003e,0x00000281,0x00000287,0x0004003d,0x00000006,0x00000288,0x00000193,0x0003003e, + 0x00000282,0x00000288,0x0004003d,0x00000006,0x00000289,0x00000197,0x0003003e,0x00000283, + 0x00000289,0x00050041,0x0000000d,0x00000296,0x00000281,0x00000044,0x0004003d,0x00000006, + 0x00000297,0x00000296,0x00050085,0x00000006,0x00000298,0x00000082,0x00000297,0x00050041, + 0x0000000d,0x00000299,0x00000281,0x00000047,0x0004003d,0x00000006,0x0000029a,0x00000299, + 0x00050085,0x00000006,0x0000029b,0x00000086,0x0000029a,0x00050081,0x00000006,0x0000029c, + 0x00000298,0x0000029b,0x0006000c,0x00000006,0x0000029d,0x00000001,0x0000000a,0x0000029c, + 0x0003003e,0x00000292,0x0000029d,0x0004003d,0x00000006,0x0000029e,0x00000292,0x00050085, + 0x00000006,0x0000029f,0x0000008d,0x0000029e,0x0006000c,0x00000006,0x000002a0,0x00000001, + 0x0000000a,0x0000029f,0x0003003e,0x00000293,0x000002a0,0x0004003d,0x00000006,0x000002a1, + 0x00000293,0x0004003d,0x00000006,0x000002a2,0x00000282,0x00050085,0x00000006,0x000002a3, + 0x000002a1,0x000002a2,0x0004003d,0x00000006,0x000002a4,0x00000283,0x00050081,0x00000006, + 0x000002a5,0x000002a3,0x000002a4,0x0003003e,0x00000294,0x000002a5,0x0004003d,0x00000006, + 0x0000028a,0x00000294,0x0004003d,0x00000012,0x0000028b,0x0000018d,0x00060050,0x00000012, + 0x0000028c,0x0000028a,0x0000028a,0x0000028a,0x00050081,0x00000012,0x0000028d,0x0000028c, + 0x0000028b,0x0003003e,0x00000280,0x0000028d,0x000200f9,0x00000290,0x000200f8,0x0000028e, + 0x0004003d,0x00000012,0x0000028f,0x0000018d,0x0003003e,0x00000280,0x0000028f,0x000200f9, + 0x00000290,0x000200f8,0x00000290,0x0004003d,0x00000012,0x00000291,0x00000280,0x0003003e, + 0x00000284,0x00000291,0x0004003d,0x00000012,0x0000019a,0x00000284,0x00050041,0x0000000d, + 0x0000019b,0x0000013c,0x00000044,0x00050051,0x00000006,0x0000019c,0x0000019a,0x00000000, + 0x0003003e,0x0000019b,0x0000019c,0x00050041,0x0000000d,0x0000019d,0x0000013c,0x00000047, + 0x00050051,0x00000006,0x0000019e,0x0000019a,0x00000001,0x0003003e,0x0000019d,0x0000019e, + 0x00050041,0x0000000d,0x0000019f,0x0000013c,0x0000004a,0x00050051,0x00000006,0x000001a0, + 0x0000019a,0x00000002,0x0003003e,0x0000019f,0x000001a0,0x0004003d,0x00000007,0x000001a2, + 0x0000013c,0x0003003e,0x000001a1,0x000001a2,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..1c6314cbe60fefeb3c09d643439cb0c1bd3dd1d0 GIT binary patch literal 11000 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h new file mode 100644 index 000000000..8de7f1134 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h @@ -0,0 +1,1552 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_atlas_blit_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000a21,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000f000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000375, + 0x00000381,0x0000038e,0x0000039e,0x000003bb,0x000003e5,0x00000401,0x00000403,0x00000411, + 0x00000412,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x0000011f,0x0000674e,0x00030005,0x00000291,0x0000674d, + 0x00030005,0x000002ec,0x00006749,0x00030005,0x0000032c,0x00004444,0x00030005,0x00000330, + 0x00006277,0x00030005,0x00000351,0x00004344,0x00030005,0x00000353,0x00003552,0x00030005, + 0x00000373,0x0000006a,0x00030005,0x00000375,0x0000316b,0x00040005,0x00000376,0x61726170, + 0x0000006d,0x00040005,0x00000378,0x61726170,0x0000006d,0x00030005,0x0000037a,0x0000006e, + 0x00030005,0x0000037b,0x00004356,0x00030005,0x0000037d,0x00003949,0x00030005,0x00000381, + 0x00003243,0x00040005,0x00000385,0x61726170,0x0000006d,0x00040005,0x00000387,0x61726170, + 0x0000006d,0x00030005,0x0000038a,0x00006748,0x00030005,0x0000038d,0x00003456,0x00030005, + 0x0000038e,0x0000304e,0x00040005,0x0000038f,0x61726170,0x0000006d,0x00040005,0x00000392, + 0x61726170,0x0000006d,0x00040005,0x00000394,0x61726170,0x0000006d,0x00030005,0x0000039a, + 0x00006747,0x00030005,0x0000039e,0x00003346,0x00030005,0x000003a4,0x0000336f,0x00040005, + 0x000003a7,0x30653742,0x00000000,0x00040005,0x000003ae,0x61726170,0x0000006d,0x00030005, + 0x000003b4,0x0000314d,0x00040005,0x000003b5,0x306a3742,0x00000000,0x00030005,0x000003ba, + 0x0000326e,0x00030005,0x000003bb,0x00003159,0x00040005,0x000003bc,0x61726170,0x0000006d, + 0x00040005,0x000003c3,0x61726170,0x0000006d,0x00040005,0x000003c6,0x61726170,0x0000006d, + 0x00040005,0x000003c8,0x61726170,0x0000006d,0x00060005,0x000003e5,0x465f6c67,0x43676172, + 0x64726f6f,0x00000000,0x00030005,0x000003e7,0x0000424d,0x00040006,0x000003e7,0x00000000, + 0x00003376,0x00040006,0x000003e7,0x00000001,0x00003377,0x00030005,0x000003e9,0x0000006b, + 0x00040005,0x000003ec,0x61726170,0x0000006d,0x00040005,0x000003ef,0x61726170,0x0000006d, + 0x00040005,0x000003f2,0x61726170,0x0000006d,0x00040005,0x000003f6,0x61726170,0x0000006d, + 0x00030005,0x00000401,0x0000306a,0x00030005,0x00000403,0x00003065,0x00040005,0x00000404, + 0x61726170,0x0000006d,0x00030005,0x00000411,0x00003361,0x00030005,0x00000412,0x00003469, + 0x00040047,0x0000011f,0x00000001,0x00000007,0x00040047,0x00000291,0x00000001,0x00000006, + 0x00040047,0x000002ec,0x00000001,0x00000002,0x00030047,0x0000032c,0x00000000,0x00040047, + 0x0000032c,0x00000021,0x00000009,0x00040047,0x0000032c,0x00000022,0x00000000,0x00030047, + 0x00000330,0x00000000,0x00040047,0x00000330,0x00000021,0x00000009,0x00040047,0x00000330, + 0x00000022,0x00000000,0x00030047,0x00000351,0x00000000,0x00040047,0x00000351,0x00000021, + 0x0000000c,0x00040047,0x00000351,0x00000022,0x00000001,0x00030047,0x00000353,0x00000000, + 0x00040047,0x00000353,0x00000021,0x0000000c,0x00040047,0x00000353,0x00000022,0x00000001, + 0x00030047,0x00000373,0x00000000,0x00040047,0x00000375,0x0000001e,0x00000000,0x00030047, + 0x0000037a,0x00000000,0x00030047,0x0000037b,0x00000000,0x00040047,0x0000037b,0x00000021, + 0x0000000b,0x00040047,0x0000037b,0x00000022,0x00000000,0x00030047,0x0000037c,0x00000000, + 0x00030047,0x0000037d,0x00000000,0x00040047,0x0000037d,0x00000021,0x0000000b,0x00040047, + 0x0000037d,0x00000022,0x00000000,0x00030047,0x0000037e,0x00000000,0x00040047,0x00000381, + 0x0000001e,0x00000001,0x00030047,0x00000383,0x00000000,0x00030047,0x00000384,0x00000000, + 0x00030047,0x00000385,0x00000000,0x00030047,0x00000387,0x00000000,0x00030047,0x00000389, + 0x00000000,0x00040047,0x0000038a,0x00000001,0x00000001,0x00030047,0x0000038d,0x00000000, + 0x00040047,0x0000038e,0x0000001e,0x00000005,0x00030047,0x00000392,0x00000000,0x00030047, + 0x00000394,0x00000000,0x00030047,0x00000396,0x00000000,0x00030047,0x00000397,0x00000000, + 0x00030047,0x00000398,0x00000000,0x00030047,0x00000399,0x00000000,0x00040047,0x0000039a, + 0x00000001,0x00000000,0x00030047,0x0000039e,0x00000000,0x00030047,0x0000039e,0x0000000e, + 0x00040047,0x0000039e,0x0000001e,0x00000004,0x00030047,0x0000039f,0x00000000,0x00030047, + 0x000003a4,0x00000000,0x00030047,0x000003a7,0x00000000,0x00040047,0x000003a7,0x00000021, + 0x00000001,0x00040047,0x000003a7,0x00000022,0x00000002,0x00040047,0x000003a7,0x0000002b, + 0x00000001,0x00030047,0x000003a8,0x00000000,0x00030047,0x000003ab,0x00000000,0x00030047, + 0x000003ac,0x00000000,0x00030047,0x000003ad,0x00000000,0x00030047,0x000003ae,0x00000000, + 0x00030047,0x000003b0,0x00000000,0x00030047,0x000003b1,0x00000000,0x00030047,0x000003b2, + 0x00000000,0x00030047,0x000003b3,0x00000000,0x00030047,0x000003b4,0x00000000,0x00030047, + 0x000003b5,0x00000000,0x00040047,0x000003b5,0x00000021,0x00000000,0x00040047,0x000003b5, + 0x00000022,0x00000002,0x00040047,0x000003b5,0x0000002b,0x00000000,0x00030047,0x000003b6, + 0x00000000,0x00030047,0x000003b7,0x00000000,0x00030047,0x000003ba,0x00000000,0x00030047, + 0x000003bb,0x00000000,0x00030047,0x000003bb,0x0000000e,0x00040047,0x000003bb,0x0000001e, + 0x00000006,0x00030047,0x000003bc,0x00000000,0x00030047,0x000003bd,0x00000000,0x00030047, + 0x000003bf,0x00000000,0x00030047,0x000003c3,0x00000000,0x00030047,0x000003c4,0x00000000, + 0x00030047,0x000003c5,0x00000000,0x00030047,0x000003c6,0x00000000,0x00030047,0x000003c7, + 0x00000000,0x00030047,0x000003c8,0x00000000,0x00030047,0x000003c9,0x00000000,0x00030047, + 0x000003d1,0x00000000,0x00030047,0x000003d3,0x00000000,0x00030047,0x000003d4,0x00000000, + 0x00030047,0x000003d7,0x00000000,0x00030047,0x000003d8,0x00000000,0x00030047,0x000003d9, + 0x00000000,0x00030047,0x000003da,0x00000000,0x00030047,0x000003e2,0x00000000,0x00030047, + 0x000003e3,0x00000000,0x00030047,0x000003e4,0x00000000,0x00040047,0x000003e5,0x0000000b, + 0x0000000f,0x00030047,0x000003e7,0x00000002,0x00050048,0x000003e7,0x00000000,0x00000023, + 0x00000058,0x00050048,0x000003e7,0x00000001,0x00000023,0x0000005c,0x00040047,0x000003e9, + 0x00000021,0x00000000,0x00040047,0x000003e9,0x00000022,0x00000000,0x00030047,0x000003ec, + 0x00000000,0x00030047,0x000003ed,0x00000000,0x00030047,0x000003ee,0x00000000,0x00030047, + 0x000003f2,0x00000000,0x00030047,0x000003f6,0x00000000,0x00030047,0x00000401,0x00000000, + 0x00040047,0x00000401,0x0000001e,0x00000000,0x00030047,0x00000402,0x00000000,0x00030047, + 0x00000403,0x00000000,0x00040047,0x00000403,0x0000001e,0x00000001,0x00030047,0x00000404, + 0x00000000,0x00030047,0x00000411,0x0000000e,0x00040047,0x00000411,0x0000001e,0x00000007, + 0x00040047,0x00000412,0x0000001e,0x00000008,0x00030047,0x00000416,0x00000000,0x00030047, + 0x0000041e,0x00000000,0x00030047,0x0000041f,0x00000000,0x00030047,0x00000420,0x00000000, + 0x00030047,0x00000421,0x00000000,0x00030047,0x00000422,0x00000000,0x00030047,0x00000423, + 0x00000000,0x00030047,0x0000042d,0x00000000,0x00030047,0x00000432,0x00000000,0x00030047, + 0x0000045c,0x00000000,0x00030047,0x0000045d,0x00000000,0x00030047,0x00000462,0x00000000, + 0x00030047,0x00000465,0x00000000,0x00030047,0x0000046a,0x00000000,0x00030047,0x0000046b, + 0x00000000,0x00030047,0x0000046c,0x00000000,0x00030047,0x0000046d,0x00000000,0x00030047, + 0x0000047a,0x00000000,0x00030047,0x0000047b,0x00000000,0x00030047,0x0000047f,0x00000000, + 0x00030047,0x00000480,0x00000000,0x00030047,0x00000486,0x00000000,0x00030047,0x00000487, + 0x00000000,0x00030047,0x00000488,0x00000000,0x00030047,0x0000048a,0x00000000,0x00030047, + 0x0000048d,0x00000000,0x00030047,0x0000048e,0x00000000,0x00030047,0x0000048f,0x00000000, + 0x00030047,0x00000494,0x00000000,0x00030047,0x00000495,0x00000000,0x00030047,0x00000496, + 0x00000000,0x00030047,0x00000499,0x00000000,0x00030047,0x0000049a,0x00000000,0x00030047, + 0x0000049b,0x00000000,0x00030047,0x0000049d,0x00000000,0x00030047,0x0000049e,0x00000000, + 0x00030047,0x000004a0,0x00000000,0x00030047,0x000004a4,0x00000000,0x00030047,0x000004a5, + 0x00000000,0x00030047,0x000004a8,0x00000000,0x00030047,0x000004a9,0x00000000,0x00030047, + 0x000004aa,0x00000000,0x00030047,0x000004ab,0x00000000,0x00030047,0x000004ad,0x00000000, + 0x00030047,0x000004b4,0x00000000,0x00030047,0x000004b6,0x00000000,0x00030047,0x000004b7, + 0x00000000,0x00030047,0x000004b9,0x00000000,0x00030047,0x000004ba,0x00000000,0x00030047, + 0x000004bc,0x00000000,0x00030047,0x000004bd,0x00000000,0x00030047,0x000004be,0x00000000, + 0x00030047,0x000004c1,0x00000000,0x00030047,0x000004c2,0x00000000,0x00030047,0x000004c3, + 0x00000000,0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047, + 0x000004c7,0x00000000,0x00030047,0x000004c8,0x00000000,0x00030047,0x000004c9,0x00000000, + 0x00030047,0x000004ca,0x00000000,0x00030047,0x000004cc,0x00000000,0x00030047,0x000004ce, + 0x00000000,0x00030047,0x000004cf,0x00000000,0x00030047,0x000004d0,0x00000000,0x00030047, + 0x000004d1,0x00000000,0x00030047,0x000004d3,0x00000000,0x00030047,0x000004d4,0x00000000, + 0x00030047,0x000004d6,0x00000000,0x00030047,0x000004d7,0x00000000,0x00030047,0x000004d9, + 0x00000000,0x00030047,0x000004da,0x00000000,0x00030047,0x000004db,0x00000000,0x00030047, + 0x000004dc,0x00000000,0x00030047,0x000004dd,0x00000000,0x00030047,0x000004de,0x00000000, + 0x00030047,0x000004df,0x00000000,0x00030047,0x000004e0,0x00000000,0x00030047,0x000004e2, + 0x00000000,0x00030047,0x000004e3,0x00000000,0x00030047,0x000004e4,0x00000000,0x00030047, + 0x000004e6,0x00000000,0x00030047,0x000004e7,0x00000000,0x00030047,0x000004e9,0x00000000, + 0x00030047,0x000004eb,0x00000000,0x00030047,0x000004ec,0x00000000,0x00030047,0x000004ed, + 0x00000000,0x00030047,0x000004ee,0x00000000,0x00030047,0x000004ef,0x00000000,0x00030047, + 0x000004f0,0x00000000,0x00030047,0x000004f1,0x00000000,0x00030047,0x000004f2,0x00000000, + 0x00030047,0x000004f3,0x00000000,0x00030047,0x000004f4,0x00000000,0x00030047,0x000004f5, + 0x00000000,0x00030047,0x000004f6,0x00000000,0x00030047,0x000004f7,0x00000000,0x00030047, + 0x000004f8,0x00000000,0x00030047,0x000004f9,0x00000000,0x00030047,0x000004fa,0x00000000, + 0x00030047,0x000004fb,0x00000000,0x00030047,0x000004fc,0x00000000,0x00030047,0x000004fd, + 0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047,0x00000500,0x00000000,0x00030047, + 0x00000501,0x00000000,0x00030047,0x00000502,0x00000000,0x00030047,0x00000503,0x00000000, + 0x00030047,0x00000504,0x00000000,0x00030047,0x00000505,0x00000000,0x00030047,0x00000506, + 0x00000000,0x00030047,0x00000507,0x00000000,0x00030047,0x00000508,0x00000000,0x00030047, + 0x00000509,0x00000000,0x00030047,0x0000050a,0x00000000,0x00030047,0x0000050b,0x00000000, + 0x00030047,0x0000050c,0x00000000,0x00030047,0x0000050d,0x00000000,0x00030047,0x0000050e, + 0x00000000,0x00030047,0x0000050f,0x00000000,0x00030047,0x00000510,0x00000000,0x00030047, + 0x00000511,0x00000000,0x00030047,0x00000512,0x00000000,0x00030047,0x00000514,0x00000000, + 0x00030047,0x00000516,0x00000000,0x00030047,0x00000518,0x00000000,0x00030047,0x00000519, + 0x00000000,0x00030047,0x0000051a,0x00000000,0x00030047,0x0000051c,0x00000000,0x00030047, + 0x0000051d,0x00000000,0x00030047,0x0000051e,0x00000000,0x00030047,0x0000051f,0x00000000, + 0x00030047,0x00000520,0x00000000,0x00030047,0x00000521,0x00000000,0x00030047,0x00000522, + 0x00000000,0x00030047,0x00000524,0x00000000,0x00030047,0x00000525,0x00000000,0x00030047, + 0x00000526,0x00000000,0x00030047,0x00000527,0x00000000,0x00030047,0x00000528,0x00000000, + 0x00030047,0x00000529,0x00000000,0x00030047,0x0000052a,0x00000000,0x00030047,0x0000052b, + 0x00000000,0x00030047,0x0000052c,0x00000000,0x00030047,0x0000052d,0x00000000,0x00030047, + 0x0000052e,0x00000000,0x00030047,0x00000530,0x00000000,0x00030047,0x00000531,0x00000000, + 0x00030047,0x00000532,0x00000000,0x00030047,0x00000534,0x00000000,0x00030047,0x00000535, + 0x00000000,0x00030047,0x00000536,0x00000000,0x00030047,0x00000538,0x00000000,0x00030047, + 0x00000539,0x00000000,0x00030047,0x0000053a,0x00000000,0x00030047,0x0000053c,0x00000000, + 0x00030047,0x0000053d,0x00000000,0x00030047,0x0000053f,0x00000000,0x00030047,0x00000540, + 0x00000000,0x00030047,0x00000541,0x00000000,0x00030047,0x00000548,0x00000000,0x00030047, + 0x00000549,0x00000000,0x00030047,0x0000054c,0x00000000,0x00030047,0x0000054e,0x00000000, + 0x00030047,0x0000054f,0x00000000,0x00030047,0x00000551,0x00000000,0x00030047,0x00000552, + 0x00000000,0x00030047,0x00000553,0x00000000,0x00030047,0x00000554,0x00000000,0x00030047, + 0x00000555,0x00000000,0x00030047,0x00000556,0x00000000,0x00030047,0x00000557,0x00000000, + 0x00030047,0x00000558,0x00000000,0x00030047,0x00000559,0x00000000,0x00030047,0x0000055b, + 0x00000000,0x00030047,0x0000055c,0x00000000,0x00030047,0x0000055e,0x00000000,0x00030047, + 0x00000561,0x00000000,0x00030047,0x00000562,0x00000000,0x00030047,0x00000563,0x00000000, + 0x00030047,0x00000565,0x00000000,0x00030047,0x00000566,0x00000000,0x00030047,0x00000567, + 0x00000000,0x00030047,0x0000056f,0x00000000,0x00030047,0x00000575,0x00000000,0x00030047, + 0x00000576,0x00000000,0x00030047,0x00000577,0x00000000,0x00030047,0x00000578,0x00000000, + 0x00030047,0x00000579,0x00000000,0x00030047,0x0000057b,0x00000000,0x00030047,0x0000057c, + 0x00000000,0x00030047,0x0000057e,0x00000000,0x00030047,0x0000057f,0x00000000,0x00030047, + 0x00000580,0x00000000,0x00030047,0x00000581,0x00000000,0x00030047,0x00000582,0x00000000, + 0x00030047,0x00000583,0x00000000,0x00030047,0x00000584,0x00000000,0x00030047,0x00000586, + 0x00000000,0x00030047,0x00000587,0x00000000,0x00030047,0x00000588,0x00000000,0x00030047, + 0x0000058a,0x00000000,0x00030047,0x0000058b,0x00000000,0x00030047,0x0000058c,0x00000000, + 0x00030047,0x0000058d,0x00000000,0x00030047,0x0000058e,0x00000000,0x00030047,0x0000058f, + 0x00000000,0x00030047,0x00000590,0x00000000,0x00030047,0x00000591,0x00000000,0x00030047, + 0x00000592,0x00000000,0x00030047,0x00000593,0x00000000,0x00030047,0x00000594,0x00000000, + 0x00030047,0x00000596,0x00000000,0x00030047,0x00000597,0x00000000,0x00030047,0x00000598, + 0x00000000,0x00030047,0x000005a1,0x00000000,0x00030047,0x000005a7,0x00000000,0x00030047, + 0x000005a8,0x00000000,0x00030047,0x000005ad,0x00000000,0x00030047,0x000005b3,0x00000000, + 0x00030047,0x000005b4,0x00000000,0x00030047,0x000005b5,0x00000000,0x00030047,0x000005b8, + 0x00000000,0x00030047,0x000005b9,0x00000000,0x00030047,0x000005ba,0x00000000,0x00030047, + 0x000005c0,0x00000000,0x00030047,0x000005c1,0x00000000,0x00030047,0x000005c2,0x00000000, + 0x00030047,0x000005ca,0x00000000,0x00030047,0x000005cb,0x00000000,0x00030047,0x000005cc, + 0x00000000,0x00030047,0x000005cd,0x00000000,0x00030047,0x000005ce,0x00000000,0x00030047, + 0x000005cf,0x00000000,0x00030047,0x000005d0,0x00000000,0x00030047,0x000005d1,0x00000000, + 0x00030047,0x000005d2,0x00000000,0x00030047,0x000005d4,0x00000000,0x00030047,0x000005d5, + 0x00000000,0x00030047,0x000005d6,0x00000000,0x00030047,0x000005d7,0x00000000,0x00030047, + 0x000005d9,0x00000000,0x00030047,0x000005da,0x00000000,0x00030047,0x000005db,0x00000000, + 0x00030047,0x000005dc,0x00000000,0x00030047,0x000005dd,0x00000000,0x00030047,0x000005de, + 0x00000000,0x00030047,0x000005df,0x00000000,0x00030047,0x000005e0,0x00000000,0x00030047, + 0x000005e3,0x00000000,0x00030047,0x000005e6,0x00000000,0x00030047,0x000005e7,0x00000000, + 0x00030047,0x000005e8,0x00000000,0x00030047,0x000005e9,0x00000000,0x00030047,0x000005ee, + 0x00000000,0x00030047,0x000005f1,0x00000000,0x00030047,0x000005f2,0x00000000,0x00030047, + 0x000005f3,0x00000000,0x00030047,0x000005f4,0x00000000,0x00030047,0x000005f9,0x00000000, + 0x00030047,0x000005fc,0x00000000,0x00030047,0x000005fd,0x00000000,0x00030047,0x000005fe, + 0x00000000,0x00030047,0x00000603,0x00000000,0x00030047,0x00000606,0x00000000,0x00030047, + 0x00000607,0x00000000,0x00030047,0x00000608,0x00000000,0x00030047,0x0000060c,0x00000000, + 0x00030047,0x0000060d,0x00000000,0x00030047,0x0000060e,0x00000000,0x00030047,0x00000610, + 0x00000000,0x00030047,0x00000611,0x00000000,0x00030047,0x00000613,0x00000000,0x00030047, + 0x00000617,0x00000000,0x00030047,0x00000618,0x00000000,0x00030047,0x0000061b,0x00000000, + 0x00030047,0x0000061c,0x00000000,0x00030047,0x0000061d,0x00000000,0x00030047,0x0000061e, + 0x00000000,0x00030047,0x00000620,0x00000000,0x00030047,0x00000622,0x00000000,0x00030047, + 0x00000624,0x00000000,0x00030047,0x00000626,0x00000000,0x00030047,0x00000627,0x00000000, + 0x00030047,0x00000628,0x00000000,0x00030047,0x0000062a,0x00000000,0x00030047,0x0000062c, + 0x00000000,0x00030047,0x0000062e,0x00000000,0x00030047,0x00000630,0x00000000,0x00030047, + 0x00000631,0x00000000,0x00030047,0x00000632,0x00000000,0x00030047,0x00000634,0x00000000, + 0x00030047,0x00000636,0x00000000,0x00030047,0x00000638,0x00000000,0x00030047,0x0000063a, + 0x00000000,0x00030047,0x0000063b,0x00000000,0x00030047,0x0000063c,0x00000000,0x00030047, + 0x0000063e,0x00000000,0x00030047,0x00000640,0x00000000,0x00030047,0x00000642,0x00000000, + 0x00030047,0x00000644,0x00000000,0x00030047,0x00000645,0x00000000,0x00030047,0x00000646, + 0x00000000,0x00030047,0x00000648,0x00000000,0x00030047,0x0000064a,0x00000000,0x00030047, + 0x0000064c,0x00000000,0x00030047,0x0000064e,0x00000000,0x00030047,0x0000064f,0x00000000, + 0x00030047,0x00000650,0x00000000,0x00030047,0x00000652,0x00000000,0x00030047,0x00000654, + 0x00000000,0x00030047,0x00000656,0x00000000,0x00030047,0x00000658,0x00000000,0x00030047, + 0x00000659,0x00000000,0x00030047,0x0000065a,0x00000000,0x00030047,0x0000065c,0x00000000, + 0x00030047,0x0000065e,0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000662, + 0x00000000,0x00030047,0x00000663,0x00000000,0x00030047,0x00000664,0x00000000,0x00030047, + 0x00000666,0x00000000,0x00030047,0x00000668,0x00000000,0x00030047,0x0000066a,0x00000000, + 0x00030047,0x0000066c,0x00000000,0x00030047,0x0000066d,0x00000000,0x00030047,0x0000066e, + 0x00000000,0x00030047,0x00000670,0x00000000,0x00030047,0x00000672,0x00000000,0x00030047, + 0x00000674,0x00000000,0x00030047,0x00000676,0x00000000,0x00030047,0x00000677,0x00000000, + 0x00030047,0x00000678,0x00000000,0x00030047,0x0000067a,0x00000000,0x00030047,0x0000067c, + 0x00000000,0x00030047,0x0000067e,0x00000000,0x00030047,0x00000680,0x00000000,0x00030047, + 0x00000681,0x00000000,0x00030047,0x00000682,0x00000000,0x00030047,0x00000684,0x00000000, + 0x00030047,0x00000686,0x00000000,0x00030047,0x00000688,0x00000000,0x00030047,0x0000068a, + 0x00000000,0x00030047,0x0000068b,0x00000000,0x00030047,0x0000068c,0x00000000,0x00030047, + 0x0000068e,0x00000000,0x00030047,0x00000690,0x00000000,0x00030047,0x00000692,0x00000000, + 0x00030047,0x00000694,0x00000000,0x00030047,0x00000695,0x00000000,0x00030047,0x00000696, + 0x00000000,0x00030047,0x00000698,0x00000000,0x00030047,0x0000069a,0x00000000,0x00030047, + 0x0000069c,0x00000000,0x00030047,0x0000069e,0x00000000,0x00030047,0x0000069f,0x00000000, + 0x00030047,0x000006a0,0x00000000,0x00030047,0x000006a2,0x00000000,0x00030047,0x000006a4, + 0x00000000,0x00030047,0x000006a6,0x00000000,0x00030047,0x000006a8,0x00000000,0x00030047, + 0x000006aa,0x00000000,0x00030047,0x000006ab,0x00000000,0x00030047,0x000006ac,0x00000000, + 0x00030047,0x000006ae,0x00000000,0x00030047,0x000006b0,0x00000000,0x00030047,0x000006b1, + 0x00000000,0x00030047,0x000006b2,0x00000000,0x00030047,0x000006b4,0x00000000,0x00030047, + 0x000006b6,0x00000000,0x00030047,0x000006b8,0x00000000,0x00030047,0x000006b9,0x00000000, + 0x00030047,0x000006bb,0x00000000,0x00030047,0x000006bc,0x00000000,0x00030047,0x000006bd, + 0x00000000,0x00030047,0x000006be,0x00000000,0x00030047,0x000006c4,0x00000000,0x00030047, + 0x000006c7,0x00000000,0x00030047,0x000006c9,0x00000000,0x00030047,0x000006ca,0x00000000, + 0x00030047,0x000006cc,0x00000000,0x00030047,0x000006cd,0x00000000,0x00030047,0x000006d0, + 0x00000000,0x00030047,0x000006d1,0x00000000,0x00030047,0x000006d2,0x00000000,0x00030047, + 0x000006d5,0x00000000,0x00030047,0x000006d7,0x00000000,0x00030047,0x000006d8,0x00000000, + 0x00030047,0x000006d9,0x00000000,0x00030047,0x000006da,0x00000000,0x00030047,0x000006dc, + 0x00000000,0x00030047,0x000006dd,0x00000000,0x00030047,0x000006e0,0x00000000,0x00030047, + 0x000006e1,0x00000000,0x00030047,0x000006e2,0x00000000,0x00030047,0x000006e5,0x00000000, + 0x00030047,0x000006e7,0x00000000,0x00030047,0x000006e8,0x00000000,0x00030047,0x000006e9, + 0x00000000,0x00030047,0x000006ea,0x00000000,0x00030047,0x000006ec,0x00000000,0x00030047, + 0x000006ed,0x00000000,0x00030047,0x000006f0,0x00000000,0x00030047,0x000006f1,0x00000000, + 0x00030047,0x000006f2,0x00000000,0x00030047,0x000006f5,0x00000000,0x00030047,0x000006f7, + 0x00000000,0x00030047,0x000006f8,0x00000000,0x00030047,0x000006f9,0x00000000,0x00030047, + 0x000006fa,0x00000000,0x00030047,0x000006fc,0x00000000,0x00030047,0x000006fd,0x00000000, + 0x00030047,0x00000700,0x00000000,0x00030047,0x00000701,0x00000000,0x00030047,0x00000702, + 0x00000000,0x00030047,0x00000705,0x00000000,0x00030047,0x00000707,0x00000000,0x00030047, + 0x00000708,0x00000000,0x00030047,0x00000709,0x00000000,0x00030047,0x0000070a,0x00000000, + 0x00030047,0x0000070b,0x00000000,0x00030047,0x0000070c,0x00000000,0x00030047,0x0000070d, + 0x00000000,0x00030047,0x0000070e,0x00000000,0x00030047,0x0000070f,0x00000000,0x00030047, + 0x00000710,0x00000000,0x00030047,0x00000711,0x00000000,0x00030047,0x00000712,0x00000000, + 0x00030047,0x00000713,0x00000000,0x00030047,0x00000714,0x00000000,0x00030047,0x00000715, + 0x00000000,0x00030047,0x00000716,0x00000000,0x00030047,0x00000717,0x00000000,0x00030047, + 0x00000719,0x00000000,0x00030047,0x0000071b,0x00000000,0x00030047,0x0000071c,0x00000000, + 0x00030047,0x0000071e,0x00000000,0x00030047,0x0000071f,0x00000000,0x00030047,0x00000720, + 0x00000000,0x00030047,0x00000721,0x00000000,0x00030047,0x00000722,0x00000000,0x00030047, + 0x00000725,0x00000000,0x00030047,0x00000727,0x00000000,0x00030047,0x00000728,0x00000000, + 0x00030047,0x0000072b,0x00000000,0x00030047,0x0000072c,0x00000000,0x00030047,0x0000072f, + 0x00000000,0x00030047,0x00000731,0x00000000,0x00030047,0x00000732,0x00000000,0x00030047, + 0x00000733,0x00000000,0x00030047,0x00000734,0x00000000,0x00030047,0x00000735,0x00000000, + 0x00030047,0x00000736,0x00000000,0x00030047,0x00000737,0x00000000,0x00030047,0x00000738, + 0x00000000,0x00030047,0x00000739,0x00000000,0x00030047,0x0000073a,0x00000000,0x00030047, + 0x0000073b,0x00000000,0x00030047,0x0000073c,0x00000000,0x00030047,0x0000073d,0x00000000, + 0x00030047,0x0000073f,0x00000000,0x00030047,0x00000741,0x00000000,0x00030047,0x00000742, + 0x00000000,0x00030047,0x00000743,0x00000000,0x00030047,0x00000745,0x00000000,0x00030047, + 0x00000747,0x00000000,0x00030047,0x00000749,0x00000000,0x00030047,0x0000074b,0x00000000, + 0x00030047,0x0000074c,0x00000000,0x00030047,0x0000074d,0x00000000,0x00030047,0x0000074e, + 0x00000000,0x00030047,0x0000074f,0x00000000,0x00030047,0x00000751,0x00000000,0x00030047, + 0x00000753,0x00000000,0x00030047,0x00000754,0x00000000,0x00030047,0x00000755,0x00000000, + 0x00030047,0x00000757,0x00000000,0x00030047,0x00000759,0x00000000,0x00030047,0x0000075b, + 0x00000000,0x00030047,0x0000075d,0x00000000,0x00030047,0x0000075e,0x00000000,0x00030047, + 0x0000075f,0x00000000,0x00030047,0x00000761,0x00000000,0x00030047,0x00000763,0x00000000, + 0x00030047,0x00000765,0x00000000,0x00030047,0x00000766,0x00000000,0x00030047,0x00000767, + 0x00000000,0x00030047,0x00000769,0x00000000,0x00030047,0x0000076b,0x00000000,0x00030047, + 0x0000076d,0x00000000,0x00030047,0x0000076e,0x00000000,0x00030047,0x0000076f,0x00000000, + 0x00030047,0x00000771,0x00000000,0x00030047,0x00000772,0x00000000,0x00030047,0x00000775, + 0x00000000,0x00030047,0x00000776,0x00000000,0x00030047,0x00000777,0x00000000,0x00030047, + 0x0000077a,0x00000000,0x00030047,0x0000077c,0x00000000,0x00030047,0x0000077d,0x00000000, + 0x00030047,0x0000077e,0x00000000,0x00030047,0x0000077f,0x00000000,0x00030047,0x00000781, + 0x00000000,0x00030047,0x00000782,0x00000000,0x00030047,0x00000785,0x00000000,0x00030047, + 0x00000786,0x00000000,0x00030047,0x00000787,0x00000000,0x00030047,0x0000078a,0x00000000, + 0x00030047,0x0000078c,0x00000000,0x00030047,0x0000078d,0x00000000,0x00030047,0x0000078e, + 0x00000000,0x00030047,0x0000078f,0x00000000,0x00030047,0x00000791,0x00000000,0x00030047, + 0x00000793,0x00000000,0x00030047,0x00000795,0x00000000,0x00030047,0x00000796,0x00000000, + 0x00030047,0x00000798,0x00000000,0x00030047,0x00000799,0x00000000,0x00030047,0x0000079a, + 0x00000000,0x00030047,0x0000079c,0x00000000,0x00030047,0x0000079e,0x00000000,0x00030047, + 0x000007a0,0x00000000,0x00030047,0x000007a2,0x00000000,0x00030047,0x000007a3,0x00000000, + 0x00030047,0x000007a4,0x00000000,0x00030047,0x000007a6,0x00000000,0x00030047,0x000007a8, + 0x00000000,0x00030047,0x000007aa,0x00000000,0x00030047,0x000007ac,0x00000000,0x00030047, + 0x000007ae,0x00000000,0x00030047,0x000007af,0x00000000,0x00030047,0x000007b0,0x00000000, + 0x00030047,0x000007b2,0x00000000,0x00030047,0x000007b4,0x00000000,0x00030047,0x000007b5, + 0x00000000,0x00030047,0x000007b6,0x00000000,0x00030047,0x000007b8,0x00000000,0x00030047, + 0x000007ba,0x00000000,0x00030047,0x000007bc,0x00000000,0x00030047,0x000007bd,0x00000000, + 0x00030047,0x000007bf,0x00000000,0x00030047,0x000007c0,0x00000000,0x00030047,0x000007c1, + 0x00000000,0x00030047,0x000007c2,0x00000000,0x00030047,0x000007c8,0x00000000,0x00030047, + 0x000007cb,0x00000000,0x00030047,0x000007cd,0x00000000,0x00030047,0x000007ce,0x00000000, + 0x00030047,0x000007d0,0x00000000,0x00030047,0x000007d1,0x00000000,0x00030047,0x000007d4, + 0x00000000,0x00030047,0x000007d5,0x00000000,0x00030047,0x000007d6,0x00000000,0x00030047, + 0x000007d9,0x00000000,0x00030047,0x000007db,0x00000000,0x00030047,0x000007dc,0x00000000, + 0x00030047,0x000007dd,0x00000000,0x00030047,0x000007de,0x00000000,0x00030047,0x000007e0, + 0x00000000,0x00030047,0x000007e1,0x00000000,0x00030047,0x000007e4,0x00000000,0x00030047, + 0x000007e5,0x00000000,0x00030047,0x000007e6,0x00000000,0x00030047,0x000007e9,0x00000000, + 0x00030047,0x000007eb,0x00000000,0x00030047,0x000007ec,0x00000000,0x00030047,0x000007ed, + 0x00000000,0x00030047,0x000007ee,0x00000000,0x00030047,0x000007f0,0x00000000,0x00030047, + 0x000007f1,0x00000000,0x00030047,0x000007f4,0x00000000,0x00030047,0x000007f5,0x00000000, + 0x00030047,0x000007f6,0x00000000,0x00030047,0x000007f9,0x00000000,0x00030047,0x000007fb, + 0x00000000,0x00030047,0x000007fc,0x00000000,0x00030047,0x000007fd,0x00000000,0x00030047, + 0x000007fe,0x00000000,0x00030047,0x00000800,0x00000000,0x00030047,0x00000801,0x00000000, + 0x00030047,0x00000804,0x00000000,0x00030047,0x00000805,0x00000000,0x00030047,0x00000806, + 0x00000000,0x00030047,0x00000809,0x00000000,0x00030047,0x0000080b,0x00000000,0x00030047, + 0x0000080c,0x00000000,0x00030047,0x0000080d,0x00000000,0x00030047,0x0000080e,0x00000000, + 0x00030047,0x0000080f,0x00000000,0x00030047,0x00000810,0x00000000,0x00030047,0x00000811, + 0x00000000,0x00030047,0x00000812,0x00000000,0x00030047,0x00000813,0x00000000,0x00030047, + 0x00000814,0x00000000,0x00030047,0x00000815,0x00000000,0x00030047,0x00000816,0x00000000, + 0x00030047,0x00000817,0x00000000,0x00030047,0x00000818,0x00000000,0x00030047,0x00000819, + 0x00000000,0x00030047,0x0000081a,0x00000000,0x00030047,0x0000081b,0x00000000,0x00030047, + 0x0000081d,0x00000000,0x00030047,0x0000081f,0x00000000,0x00030047,0x00000820,0x00000000, + 0x00030047,0x00000822,0x00000000,0x00030047,0x00000823,0x00000000,0x00030047,0x00000824, + 0x00000000,0x00030047,0x00000825,0x00000000,0x00030047,0x00000826,0x00000000,0x00030047, + 0x00000829,0x00000000,0x00030047,0x0000082b,0x00000000,0x00030047,0x0000082c,0x00000000, + 0x00030047,0x0000082f,0x00000000,0x00030047,0x00000830,0x00000000,0x00030047,0x00000833, + 0x00000000,0x00030047,0x00000835,0x00000000,0x00030047,0x00000836,0x00000000,0x00030047, + 0x00000837,0x00000000,0x00030047,0x00000838,0x00000000,0x00030047,0x00000839,0x00000000, + 0x00030047,0x0000083a,0x00000000,0x00030047,0x0000083b,0x00000000,0x00030047,0x0000083c, + 0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x0000083e,0x00000000,0x00030047, + 0x0000083f,0x00000000,0x00030047,0x00000840,0x00000000,0x00030047,0x00000841,0x00000000, + 0x00030047,0x00000843,0x00000000,0x00030047,0x00000845,0x00000000,0x00030047,0x00000846, + 0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000849,0x00000000,0x00030047, + 0x0000084b,0x00000000,0x00030047,0x0000084d,0x00000000,0x00030047,0x0000084f,0x00000000, + 0x00030047,0x00000850,0x00000000,0x00030047,0x00000851,0x00000000,0x00030047,0x00000852, + 0x00000000,0x00030047,0x00000853,0x00000000,0x00030047,0x00000855,0x00000000,0x00030047, + 0x00000857,0x00000000,0x00030047,0x00000858,0x00000000,0x00030047,0x00000859,0x00000000, + 0x00030047,0x0000085b,0x00000000,0x00030047,0x0000085d,0x00000000,0x00030047,0x0000085f, + 0x00000000,0x00030047,0x00000861,0x00000000,0x00030047,0x00000862,0x00000000,0x00030047, + 0x00000863,0x00000000,0x00030047,0x00000865,0x00000000,0x00030047,0x00000867,0x00000000, + 0x00030047,0x00000869,0x00000000,0x00030047,0x0000086a,0x00000000,0x00030047,0x0000086b, + 0x00000000,0x00030047,0x0000086d,0x00000000,0x00030047,0x0000086f,0x00000000,0x00030047, + 0x00000871,0x00000000,0x00030047,0x00000872,0x00000000,0x00030047,0x00000873,0x00000000, + 0x00030047,0x00000875,0x00000000,0x00030047,0x00000876,0x00000000,0x00030047,0x00000879, + 0x00000000,0x00030047,0x0000087a,0x00000000,0x00030047,0x0000087b,0x00000000,0x00030047, + 0x0000087e,0x00000000,0x00030047,0x00000880,0x00000000,0x00030047,0x00000881,0x00000000, + 0x00030047,0x00000882,0x00000000,0x00030047,0x00000883,0x00000000,0x00030047,0x00000885, + 0x00000000,0x00030047,0x00000886,0x00000000,0x00030047,0x00000889,0x00000000,0x00030047, + 0x0000088a,0x00000000,0x00030047,0x0000088b,0x00000000,0x00030047,0x0000088e,0x00000000, + 0x00030047,0x00000890,0x00000000,0x00030047,0x00000891,0x00000000,0x00030047,0x00000892, + 0x00000000,0x00030047,0x00000893,0x00000000,0x00030047,0x00000895,0x00000000,0x00030047, + 0x00000897,0x00000000,0x00030047,0x00000899,0x00000000,0x00030047,0x0000089a,0x00000000, + 0x00030047,0x0000089c,0x00000000,0x00030047,0x0000089d,0x00000000,0x00030047,0x0000089e, + 0x00000000,0x00030047,0x000008a0,0x00000000,0x00030047,0x000008a2,0x00000000,0x00030047, + 0x000008a4,0x00000000,0x00030047,0x000008a6,0x00000000,0x00030047,0x000008a7,0x00000000, + 0x00030047,0x000008a8,0x00000000,0x00030047,0x000008aa,0x00000000,0x00030047,0x000008ac, + 0x00000000,0x00030047,0x000008ae,0x00000000,0x00030047,0x000008b0,0x00000000,0x00030047, + 0x000008b1,0x00000000,0x00030047,0x000008b2,0x00000000,0x00030047,0x000008b3,0x00000000, + 0x00030047,0x000008b4,0x00000000,0x00030047,0x000008b5,0x00000000,0x00030047,0x000008b6, + 0x00000000,0x00030047,0x000008b7,0x00000000,0x00030047,0x000008b8,0x00000000,0x00030047, + 0x000008b9,0x00000000,0x00030047,0x000008ba,0x00000000,0x00030047,0x000008bb,0x00000000, + 0x00030047,0x000008bc,0x00000000,0x00030047,0x000008bd,0x00000000,0x00030047,0x000008be, + 0x00000000,0x00030047,0x000008bf,0x00000000,0x00030047,0x000008c1,0x00000000,0x00030047, + 0x000008c3,0x00000000,0x00030047,0x000008c4,0x00000000,0x00030047,0x000008c6,0x00000000, + 0x00030047,0x000008c7,0x00000000,0x00030047,0x000008c8,0x00000000,0x00030047,0x000008c9, + 0x00000000,0x00030047,0x000008ca,0x00000000,0x00030047,0x000008cd,0x00000000,0x00030047, + 0x000008cf,0x00000000,0x00030047,0x000008d0,0x00000000,0x00030047,0x000008d3,0x00000000, + 0x00030047,0x000008d4,0x00000000,0x00030047,0x000008d7,0x00000000,0x00030047,0x000008d9, + 0x00000000,0x00030047,0x000008da,0x00000000,0x00030047,0x000008db,0x00000000,0x00030047, + 0x000008dc,0x00000000,0x00030047,0x000008dd,0x00000000,0x00030047,0x000008de,0x00000000, + 0x00030047,0x000008df,0x00000000,0x00030047,0x000008e0,0x00000000,0x00030047,0x000008e1, + 0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008e3,0x00000000,0x00030047, + 0x000008e4,0x00000000,0x00030047,0x000008e5,0x00000000,0x00030047,0x000008e7,0x00000000, + 0x00030047,0x000008e9,0x00000000,0x00030047,0x000008ea,0x00000000,0x00030047,0x000008eb, + 0x00000000,0x00030047,0x000008ed,0x00000000,0x00030047,0x000008ef,0x00000000,0x00030047, + 0x000008f1,0x00000000,0x00030047,0x000008f3,0x00000000,0x00030047,0x000008f4,0x00000000, + 0x00030047,0x000008f5,0x00000000,0x00030047,0x000008f6,0x00000000,0x00030047,0x000008f7, + 0x00000000,0x00030047,0x000008f9,0x00000000,0x00030047,0x000008fb,0x00000000,0x00030047, + 0x000008fc,0x00000000,0x00030047,0x000008fd,0x00000000,0x00030047,0x000008ff,0x00000000, + 0x00030047,0x00000901,0x00000000,0x00030047,0x00000903,0x00000000,0x00030047,0x00000905, + 0x00000000,0x00030047,0x00000906,0x00000000,0x00030047,0x00000907,0x00000000,0x00030047, + 0x00000909,0x00000000,0x00030047,0x0000090b,0x00000000,0x00030047,0x0000090d,0x00000000, + 0x00030047,0x0000090e,0x00000000,0x00030047,0x0000090f,0x00000000,0x00030047,0x00000911, + 0x00000000,0x00030047,0x00000913,0x00000000,0x00030047,0x00000915,0x00000000,0x00030047, + 0x00000916,0x00000000,0x00030047,0x00000917,0x00000000,0x00030047,0x00000919,0x00000000, + 0x00030047,0x0000091a,0x00000000,0x00030047,0x0000091d,0x00000000,0x00030047,0x0000091e, + 0x00000000,0x00030047,0x0000091f,0x00000000,0x00030047,0x00000922,0x00000000,0x00030047, + 0x00000924,0x00000000,0x00030047,0x00000925,0x00000000,0x00030047,0x00000926,0x00000000, + 0x00030047,0x00000927,0x00000000,0x00030047,0x00000929,0x00000000,0x00030047,0x0000092a, + 0x00000000,0x00030047,0x0000092d,0x00000000,0x00030047,0x0000092e,0x00000000,0x00030047, + 0x0000092f,0x00000000,0x00030047,0x00000932,0x00000000,0x00030047,0x00000934,0x00000000, + 0x00030047,0x00000935,0x00000000,0x00030047,0x00000936,0x00000000,0x00030047,0x00000937, + 0x00000000,0x00030047,0x00000939,0x00000000,0x00030047,0x0000093b,0x00000000,0x00030047, + 0x0000093d,0x00000000,0x00030047,0x0000093e,0x00000000,0x00030047,0x00000940,0x00000000, + 0x00030047,0x00000941,0x00000000,0x00030047,0x00000942,0x00000000,0x00030047,0x00000944, + 0x00000000,0x00030047,0x00000946,0x00000000,0x00030047,0x00000948,0x00000000,0x00030047, + 0x0000094a,0x00000000,0x00030047,0x0000094b,0x00000000,0x00030047,0x0000094c,0x00000000, + 0x00030047,0x0000094e,0x00000000,0x00030047,0x00000950,0x00000000,0x00030047,0x00000952, + 0x00000000,0x00030047,0x00000954,0x00000000,0x00030047,0x00000955,0x00000000,0x00030047, + 0x00000956,0x00000000,0x00030047,0x00000957,0x00000000,0x00030047,0x00000958,0x00000000, + 0x00030047,0x00000959,0x00000000,0x00030047,0x0000095a,0x00000000,0x00030047,0x0000095b, + 0x00000000,0x00030047,0x0000095c,0x00000000,0x00030047,0x0000095d,0x00000000,0x00030047, + 0x0000095e,0x00000000,0x00030047,0x0000095f,0x00000000,0x00030047,0x00000960,0x00000000, + 0x00030047,0x00000961,0x00000000,0x00030047,0x00000962,0x00000000,0x00030047,0x00000963, + 0x00000000,0x00030047,0x00000965,0x00000000,0x00030047,0x00000967,0x00000000,0x00030047, + 0x00000968,0x00000000,0x00030047,0x0000096a,0x00000000,0x00030047,0x0000096b,0x00000000, + 0x00030047,0x0000096c,0x00000000,0x00030047,0x0000096d,0x00000000,0x00030047,0x0000096e, + 0x00000000,0x00030047,0x00000971,0x00000000,0x00030047,0x00000973,0x00000000,0x00030047, + 0x00000974,0x00000000,0x00030047,0x00000977,0x00000000,0x00030047,0x00000978,0x00000000, + 0x00030047,0x0000097b,0x00000000,0x00030047,0x0000097d,0x00000000,0x00030047,0x0000097e, + 0x00000000,0x00030047,0x0000097f,0x00000000,0x00030047,0x00000980,0x00000000,0x00030047, + 0x00000981,0x00000000,0x00030047,0x00000982,0x00000000,0x00030047,0x00000983,0x00000000, + 0x00030047,0x00000984,0x00000000,0x00030047,0x00000985,0x00000000,0x00030047,0x00000986, + 0x00000000,0x00030047,0x00000987,0x00000000,0x00030047,0x00000988,0x00000000,0x00030047, + 0x00000989,0x00000000,0x00030047,0x0000098b,0x00000000,0x00030047,0x0000098d,0x00000000, + 0x00030047,0x0000098e,0x00000000,0x00030047,0x0000098f,0x00000000,0x00030047,0x00000991, + 0x00000000,0x00030047,0x00000993,0x00000000,0x00030047,0x00000995,0x00000000,0x00030047, + 0x00000997,0x00000000,0x00030047,0x00000998,0x00000000,0x00030047,0x00000999,0x00000000, + 0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099b,0x00000000,0x00030047,0x0000099d, + 0x00000000,0x00030047,0x0000099f,0x00000000,0x00030047,0x000009a0,0x00000000,0x00030047, + 0x000009a1,0x00000000,0x00030047,0x000009a3,0x00000000,0x00030047,0x000009a5,0x00000000, + 0x00030047,0x000009a7,0x00000000,0x00030047,0x000009a9,0x00000000,0x00030047,0x000009aa, + 0x00000000,0x00030047,0x000009ab,0x00000000,0x00030047,0x000009ad,0x00000000,0x00030047, + 0x000009af,0x00000000,0x00030047,0x000009b1,0x00000000,0x00030047,0x000009b2,0x00000000, + 0x00030047,0x000009b3,0x00000000,0x00030047,0x000009b5,0x00000000,0x00030047,0x000009b7, + 0x00000000,0x00030047,0x000009b9,0x00000000,0x00030047,0x000009ba,0x00000000,0x00030047, + 0x000009bb,0x00000000,0x00030047,0x000009bd,0x00000000,0x00030047,0x000009be,0x00000000, + 0x00030047,0x000009c1,0x00000000,0x00030047,0x000009c2,0x00000000,0x00030047,0x000009c3, + 0x00000000,0x00030047,0x000009c6,0x00000000,0x00030047,0x000009c8,0x00000000,0x00030047, + 0x000009c9,0x00000000,0x00030047,0x000009ca,0x00000000,0x00030047,0x000009cb,0x00000000, + 0x00030047,0x000009cd,0x00000000,0x00030047,0x000009ce,0x00000000,0x00030047,0x000009d1, + 0x00000000,0x00030047,0x000009d2,0x00000000,0x00030047,0x000009d3,0x00000000,0x00030047, + 0x000009d6,0x00000000,0x00030047,0x000009d8,0x00000000,0x00030047,0x000009d9,0x00000000, + 0x00030047,0x000009da,0x00000000,0x00030047,0x000009db,0x00000000,0x00030047,0x000009dd, + 0x00000000,0x00030047,0x000009df,0x00000000,0x00030047,0x000009e1,0x00000000,0x00030047, + 0x000009e2,0x00000000,0x00030047,0x000009e4,0x00000000,0x00030047,0x000009e5,0x00000000, + 0x00030047,0x000009e6,0x00000000,0x00030047,0x000009e8,0x00000000,0x00030047,0x000009ea, + 0x00000000,0x00030047,0x000009ec,0x00000000,0x00030047,0x000009ee,0x00000000,0x00030047, + 0x000009ef,0x00000000,0x00030047,0x000009f1,0x00000000,0x00030047,0x000009f2,0x00000000, + 0x00030047,0x000009f3,0x00000000,0x00030047,0x000009f7,0x00000000,0x00030047,0x000009f8, + 0x00000000,0x00030047,0x000009fa,0x00000000,0x00030047,0x000009fb,0x00000000,0x00030047, + 0x000009fc,0x00000000,0x00030047,0x000009fe,0x00000000,0x00030047,0x00000a00,0x00000000, + 0x00030047,0x00000a01,0x00000000,0x00030047,0x00000a02,0x00000000,0x00030047,0x00000a03, + 0x00000000,0x00030047,0x00000a0d,0x00000000,0x00030047,0x00000a0e,0x00000000,0x00030047, + 0x00000a0f,0x00000000,0x00030047,0x00000a10,0x00000000,0x00030047,0x00000a11,0x00000000, + 0x00030047,0x00000a12,0x00000000,0x00030047,0x00000a13,0x00000000,0x00030047,0x00000a14, + 0x00000000,0x00030047,0x00000a15,0x00000000,0x00030047,0x00000a16,0x00000000,0x00030047, + 0x00000a18,0x00000000,0x00030047,0x00000a1a,0x00000000,0x00030047,0x00000a1c,0x00000000, + 0x00030047,0x00000a1e,0x00000000,0x00030047,0x00000a20,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040020,0x00000008,0x00000007,0x00000007,0x00040020,0x0000000d, + 0x00000007,0x00000006,0x00040015,0x0000000e,0x00000020,0x00000000,0x00040017,0x00000017, + 0x00000006,0x00000002,0x00040017,0x00000021,0x00000006,0x00000003,0x00040020,0x0000002c, + 0x00000007,0x00000021,0x00040020,0x0000003a,0x00000007,0x00000017,0x00040020,0x00000068, + 0x00000007,0x0000000e,0x0004002b,0x0000000e,0x00000087,0x00000000,0x0004002b,0x0000000e, + 0x0000008a,0x00000001,0x0004002b,0x0000000e,0x0000009d,0x00000002,0x0004002b,0x0000000e, + 0x000000b5,0x00000003,0x0004002b,0x00000006,0x000000ca,0x00000000,0x00020014,0x000000cb, + 0x0004002b,0x00000006,0x000000d0,0x3f800000,0x0004002b,0x00000006,0x00000109,0x3d897143, + 0x0004002b,0x00000006,0x0000010d,0x3bbf4590,0x0004002b,0x00000006,0x00000114,0x4253ee82, + 0x00030030,0x000000cb,0x0000011f,0x0004002b,0x00000006,0x00000133,0x3e99999a,0x0004002b, + 0x00000006,0x00000134,0x3f170a3d,0x0004002b,0x00000006,0x00000135,0x3de147ae,0x0004002b, + 0x00000006,0x0000014f,0x388205ff,0x0004002b,0x00000006,0x000001b5,0x40000000,0x0004002b, + 0x00000006,0x000001bc,0x3f000000,0x00040017,0x000001c2,0x000000cb,0x00000003,0x00040015, + 0x0000023e,0x00000020,0x00000001,0x00040020,0x0000023f,0x00000007,0x0000023e,0x0004002b, + 0x0000023e,0x00000241,0x00000000,0x0004002b,0x0000023e,0x00000248,0x00000003,0x0004002b, + 0x00000006,0x0000025a,0x3e800000,0x0004002b,0x00000006,0x0000025f,0x41800000,0x0004002b, + 0x00000006,0x00000264,0x41400000,0x0004002b,0x00000006,0x0000026a,0x40400000,0x0004002b, + 0x0000023e,0x00000276,0x00000001,0x00030030,0x000000cb,0x00000291,0x00030030,0x000000cb, + 0x000002ec,0x00050034,0x000000cb,0x000002ed,0x000000a8,0x000002ec,0x0004002b,0x00000006, + 0x000002fc,0xbf800000,0x0004002b,0x00000006,0x0000031a,0x3f7f8000,0x0004002b,0x00000006, + 0x0000031d,0x3a800000,0x0004002b,0x00000006,0x00000320,0x3b000000,0x00090019,0x0000032a, + 0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x0000032b,0x00000000,0x0000032a,0x0004003b,0x0000032b,0x0000032c,0x00000000,0x0002001a, + 0x0000032e,0x00040020,0x0000032f,0x00000000,0x0000032e,0x0004003b,0x0000032f,0x00000330, + 0x00000000,0x0003001b,0x00000332,0x0000032a,0x00050034,0x000000cb,0x0000033d,0x000000a8, + 0x000002ec,0x0004003b,0x0000032b,0x00000351,0x00000000,0x0004003b,0x0000032f,0x00000353, + 0x00000000,0x00050034,0x000000cb,0x0000035f,0x000000a8,0x000002ec,0x00040020,0x00000374, + 0x00000001,0x00000007,0x0004003b,0x00000374,0x00000375,0x00000001,0x0004003b,0x0000032b, + 0x0000037b,0x00000000,0x0004003b,0x0000032f,0x0000037d,0x00000000,0x00040020,0x00000380, + 0x00000001,0x00000017,0x0004003b,0x00000380,0x00000381,0x00000001,0x00030030,0x000000cb, + 0x0000038a,0x0004003b,0x00000374,0x0000038e,0x00000001,0x00030030,0x000000cb,0x0000039a, + 0x00040020,0x0000039d,0x00000001,0x00000006,0x0004003b,0x0000039d,0x0000039e,0x00000001, + 0x00090019,0x000003a5,0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000000,0x00040020,0x000003a6,0x00000000,0x000003a5,0x0004003b,0x000003a6,0x000003a7, + 0x00000000,0x00040017,0x000003a9,0x0000023e,0x00000002,0x0005002c,0x000003a9,0x000003aa, + 0x00000241,0x00000241,0x0004003b,0x000003a6,0x000003b5,0x00000000,0x0004003b,0x0000039d, + 0x000003bb,0x00000001,0x0004003b,0x00000374,0x000003e5,0x00000001,0x0004001e,0x000003e7, + 0x00000006,0x00000006,0x00040020,0x000003e8,0x00000002,0x000003e7,0x0004003b,0x000003e8, + 0x000003e9,0x00000002,0x00040020,0x000003f3,0x00000002,0x00000006,0x00040020,0x00000400, + 0x00000003,0x00000007,0x0004003b,0x00000400,0x00000401,0x00000003,0x0004003b,0x00000400, + 0x00000403,0x00000003,0x00040017,0x0000040f,0x0000000e,0x00000002,0x00040020,0x00000410, + 0x00000001,0x0000040f,0x0004003b,0x00000410,0x00000411,0x00000001,0x0004003b,0x00000380, + 0x00000412,0x00000001,0x0006002c,0x00000021,0x00000413,0x000000d0,0x000000d0,0x000000d0, + 0x0006002c,0x00000021,0x00000414,0x000001bc,0x000001bc,0x000001bc,0x0004002b,0x00000006, + 0x00000415,0xc0000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003b,0x00000008,0x00000a15,0x00000007,0x0004003b,0x00000008,0x00000a16, + 0x00000007,0x0004003b,0x0000000d,0x00000a01,0x00000007,0x0004003b,0x0000000d,0x00000a02, + 0x00000007,0x0004003b,0x0000000d,0x00000a03,0x00000007,0x0004003b,0x0000002c,0x000009ef, + 0x00000007,0x0004003b,0x0000003a,0x000009f0,0x00000007,0x0004003b,0x0000000d,0x000009f1, + 0x00000007,0x0004003b,0x0000000d,0x000009f2,0x00000007,0x0004003b,0x0000002c,0x000009f3, + 0x00000007,0x0004003b,0x0000002c,0x000009e5,0x00000007,0x0004003b,0x0000002c,0x000009e6, + 0x00000007,0x0004003b,0x0000000d,0x000009e2,0x00000007,0x0004003b,0x0000003a,0x000009da, + 0x00000007,0x0004003b,0x0000003a,0x000009db,0x00000007,0x0004003b,0x0000000d,0x000009d3, + 0x00000007,0x0004003b,0x0000003a,0x000009ca,0x00000007,0x0004003b,0x0000000d,0x000009cb, + 0x00000007,0x0004003b,0x0000000d,0x000009c3,0x00000007,0x0004003b,0x0000003a,0x000009ba, + 0x00000007,0x0004003b,0x0000000d,0x000009bb,0x00000007,0x0004003b,0x0000003a,0x000009b2, + 0x00000007,0x0004003b,0x0000003a,0x000009b3,0x00000007,0x0004003b,0x0000003a,0x000009aa, + 0x00000007,0x0004003b,0x0000003a,0x000009ab,0x00000007,0x0004003b,0x0000002c,0x000009a0, + 0x00000007,0x0004003b,0x0000002c,0x000009a1,0x00000007,0x0004003b,0x0000000d,0x00000998, + 0x00000007,0x0004003b,0x0000000d,0x00000999,0x00000007,0x0004003b,0x0000000d,0x0000099a, + 0x00000007,0x0004003b,0x0000000d,0x0000099b,0x00000007,0x0004003b,0x0000002c,0x0000098e, + 0x00000007,0x0004003b,0x0000002c,0x0000098f,0x00000007,0x0004003b,0x0000000d,0x00000986, + 0x00000007,0x0004003b,0x0000000d,0x00000987,0x00000007,0x0004003b,0x0000000d,0x00000988, + 0x00000007,0x0004003b,0x0000000d,0x00000989,0x00000007,0x0004003b,0x0000000d,0x00000955, + 0x00000007,0x0004003b,0x0000002c,0x00000956,0x00000007,0x0004003b,0x0000002c,0x00000957, + 0x00000007,0x0004003b,0x0000002c,0x00000958,0x00000007,0x0004003b,0x0000003a,0x00000959, + 0x00000007,0x0004003b,0x0000000d,0x0000095a,0x00000007,0x0004003b,0x0000000d,0x0000095b, + 0x00000007,0x0004003b,0x0000000d,0x0000095c,0x00000007,0x0004003b,0x0000002c,0x0000095d, + 0x00000007,0x0004003b,0x0000002c,0x0000095e,0x00000007,0x0004003b,0x0000000d,0x0000095f, + 0x00000007,0x0004003b,0x0000000d,0x00000960,0x00000007,0x0004003b,0x0000000d,0x00000961, + 0x00000007,0x0004003b,0x0000000d,0x00000962,0x00000007,0x0004003b,0x0000002c,0x00000963, + 0x00000007,0x0004003b,0x0000002c,0x0000094b,0x00000007,0x0004003b,0x0000002c,0x0000094c, + 0x00000007,0x0004003b,0x0000002c,0x00000941,0x00000007,0x0004003b,0x0000002c,0x00000942, + 0x00000007,0x0004003b,0x0000000d,0x0000093e,0x00000007,0x0004003b,0x0000003a,0x00000936, + 0x00000007,0x0004003b,0x0000003a,0x00000937,0x00000007,0x0004003b,0x0000000d,0x0000092f, + 0x00000007,0x0004003b,0x0000003a,0x00000926,0x00000007,0x0004003b,0x0000000d,0x00000927, + 0x00000007,0x0004003b,0x0000000d,0x0000091f,0x00000007,0x0004003b,0x0000003a,0x00000916, + 0x00000007,0x0004003b,0x0000000d,0x00000917,0x00000007,0x0004003b,0x0000003a,0x0000090e, + 0x00000007,0x0004003b,0x0000003a,0x0000090f,0x00000007,0x0004003b,0x0000003a,0x00000906, + 0x00000007,0x0004003b,0x0000003a,0x00000907,0x00000007,0x0004003b,0x0000002c,0x000008fc, + 0x00000007,0x0004003b,0x0000002c,0x000008fd,0x00000007,0x0004003b,0x0000000d,0x000008f4, + 0x00000007,0x0004003b,0x0000000d,0x000008f5,0x00000007,0x0004003b,0x0000000d,0x000008f6, + 0x00000007,0x0004003b,0x0000000d,0x000008f7,0x00000007,0x0004003b,0x0000002c,0x000008ea, + 0x00000007,0x0004003b,0x0000002c,0x000008eb,0x00000007,0x0004003b,0x0000000d,0x000008e2, + 0x00000007,0x0004003b,0x0000000d,0x000008e3,0x00000007,0x0004003b,0x0000000d,0x000008e4, + 0x00000007,0x0004003b,0x0000000d,0x000008e5,0x00000007,0x0004003b,0x0000000d,0x000008b1, + 0x00000007,0x0004003b,0x0000002c,0x000008b2,0x00000007,0x0004003b,0x0000002c,0x000008b3, + 0x00000007,0x0004003b,0x0000002c,0x000008b4,0x00000007,0x0004003b,0x0000003a,0x000008b5, + 0x00000007,0x0004003b,0x0000000d,0x000008b6,0x00000007,0x0004003b,0x0000000d,0x000008b7, + 0x00000007,0x0004003b,0x0000000d,0x000008b8,0x00000007,0x0004003b,0x0000002c,0x000008b9, + 0x00000007,0x0004003b,0x0000002c,0x000008ba,0x00000007,0x0004003b,0x0000000d,0x000008bb, + 0x00000007,0x0004003b,0x0000000d,0x000008bc,0x00000007,0x0004003b,0x0000000d,0x000008bd, + 0x00000007,0x0004003b,0x0000000d,0x000008be,0x00000007,0x0004003b,0x0000002c,0x000008bf, + 0x00000007,0x0004003b,0x0000002c,0x000008a7,0x00000007,0x0004003b,0x0000002c,0x000008a8, + 0x00000007,0x0004003b,0x0000002c,0x0000089d,0x00000007,0x0004003b,0x0000002c,0x0000089e, + 0x00000007,0x0004003b,0x0000000d,0x0000089a,0x00000007,0x0004003b,0x0000003a,0x00000892, + 0x00000007,0x0004003b,0x0000003a,0x00000893,0x00000007,0x0004003b,0x0000000d,0x0000088b, + 0x00000007,0x0004003b,0x0000003a,0x00000882,0x00000007,0x0004003b,0x0000000d,0x00000883, + 0x00000007,0x0004003b,0x0000000d,0x0000087b,0x00000007,0x0004003b,0x0000003a,0x00000872, + 0x00000007,0x0004003b,0x0000000d,0x00000873,0x00000007,0x0004003b,0x0000003a,0x0000086a, + 0x00000007,0x0004003b,0x0000003a,0x0000086b,0x00000007,0x0004003b,0x0000003a,0x00000862, + 0x00000007,0x0004003b,0x0000003a,0x00000863,0x00000007,0x0004003b,0x0000002c,0x00000858, + 0x00000007,0x0004003b,0x0000002c,0x00000859,0x00000007,0x0004003b,0x0000000d,0x00000850, + 0x00000007,0x0004003b,0x0000000d,0x00000851,0x00000007,0x0004003b,0x0000000d,0x00000852, + 0x00000007,0x0004003b,0x0000000d,0x00000853,0x00000007,0x0004003b,0x0000002c,0x00000846, + 0x00000007,0x0004003b,0x0000002c,0x00000847,0x00000007,0x0004003b,0x0000000d,0x0000083e, + 0x00000007,0x0004003b,0x0000000d,0x0000083f,0x00000007,0x0004003b,0x0000000d,0x00000840, + 0x00000007,0x0004003b,0x0000000d,0x00000841,0x00000007,0x0004003b,0x0000000d,0x0000080d, + 0x00000007,0x0004003b,0x0000002c,0x0000080e,0x00000007,0x0004003b,0x0000002c,0x0000080f, + 0x00000007,0x0004003b,0x0000002c,0x00000810,0x00000007,0x0004003b,0x0000003a,0x00000811, + 0x00000007,0x0004003b,0x0000000d,0x00000812,0x00000007,0x0004003b,0x0000000d,0x00000813, + 0x00000007,0x0004003b,0x0000000d,0x00000814,0x00000007,0x0004003b,0x0000002c,0x00000815, + 0x00000007,0x0004003b,0x0000002c,0x00000816,0x00000007,0x0004003b,0x0000000d,0x00000817, + 0x00000007,0x0004003b,0x0000000d,0x00000818,0x00000007,0x0004003b,0x0000000d,0x00000819, + 0x00000007,0x0004003b,0x0000000d,0x0000081a,0x00000007,0x0004003b,0x0000002c,0x0000081b, + 0x00000007,0x0004003b,0x0000000d,0x00000806,0x00000007,0x0004003b,0x0000003a,0x000007fd, + 0x00000007,0x0004003b,0x0000000d,0x000007fe,0x00000007,0x0004003b,0x0000000d,0x000007f6, + 0x00000007,0x0004003b,0x0000003a,0x000007ed,0x00000007,0x0004003b,0x0000000d,0x000007ee, + 0x00000007,0x0004003b,0x0000000d,0x000007e6,0x00000007,0x0004003b,0x0000003a,0x000007dd, + 0x00000007,0x0004003b,0x0000000d,0x000007de,0x00000007,0x0004003b,0x0000000d,0x000007d6, + 0x00000007,0x0004003b,0x0000003a,0x000007cd,0x00000007,0x0004003b,0x0000000d,0x000007ce, + 0x00000007,0x0004003b,0x0000000d,0x000007ad,0x00000007,0x0004003b,0x0000002c,0x000007ae, + 0x00000007,0x0004003b,0x0000002c,0x000007af,0x00000007,0x0004003b,0x0000002c,0x000007b0, + 0x00000007,0x0004003b,0x0000000d,0x000007b1,0x00000007,0x0004003b,0x0000002c,0x000007b2, + 0x00000007,0x0004003b,0x0000000d,0x000007b3,0x00000007,0x0004003b,0x0000002c,0x000007b4, + 0x00000007,0x0004003b,0x0000002c,0x000007b5,0x00000007,0x0004003b,0x0000002c,0x000007b6, + 0x00000007,0x0004003b,0x0000002c,0x000007a3,0x00000007,0x0004003b,0x0000002c,0x000007a4, + 0x00000007,0x0004003b,0x0000002c,0x00000799,0x00000007,0x0004003b,0x0000002c,0x0000079a, + 0x00000007,0x0004003b,0x0000000d,0x00000796,0x00000007,0x0004003b,0x0000003a,0x0000078e, + 0x00000007,0x0004003b,0x0000003a,0x0000078f,0x00000007,0x0004003b,0x0000000d,0x00000787, + 0x00000007,0x0004003b,0x0000003a,0x0000077e,0x00000007,0x0004003b,0x0000000d,0x0000077f, + 0x00000007,0x0004003b,0x0000000d,0x00000777,0x00000007,0x0004003b,0x0000003a,0x0000076e, + 0x00000007,0x0004003b,0x0000000d,0x0000076f,0x00000007,0x0004003b,0x0000003a,0x00000766, + 0x00000007,0x0004003b,0x0000003a,0x00000767,0x00000007,0x0004003b,0x0000003a,0x0000075e, + 0x00000007,0x0004003b,0x0000003a,0x0000075f,0x00000007,0x0004003b,0x0000002c,0x00000754, + 0x00000007,0x0004003b,0x0000002c,0x00000755,0x00000007,0x0004003b,0x0000000d,0x0000074c, + 0x00000007,0x0004003b,0x0000000d,0x0000074d,0x00000007,0x0004003b,0x0000000d,0x0000074e, + 0x00000007,0x0004003b,0x0000000d,0x0000074f,0x00000007,0x0004003b,0x0000002c,0x00000742, + 0x00000007,0x0004003b,0x0000002c,0x00000743,0x00000007,0x0004003b,0x0000000d,0x0000073a, + 0x00000007,0x0004003b,0x0000000d,0x0000073b,0x00000007,0x0004003b,0x0000000d,0x0000073c, + 0x00000007,0x0004003b,0x0000000d,0x0000073d,0x00000007,0x0004003b,0x0000000d,0x00000709, + 0x00000007,0x0004003b,0x0000002c,0x0000070a,0x00000007,0x0004003b,0x0000002c,0x0000070b, + 0x00000007,0x0004003b,0x0000002c,0x0000070c,0x00000007,0x0004003b,0x0000003a,0x0000070d, + 0x00000007,0x0004003b,0x0000000d,0x0000070e,0x00000007,0x0004003b,0x0000000d,0x0000070f, + 0x00000007,0x0004003b,0x0000000d,0x00000710,0x00000007,0x0004003b,0x0000002c,0x00000711, + 0x00000007,0x0004003b,0x0000002c,0x00000712,0x00000007,0x0004003b,0x0000000d,0x00000713, + 0x00000007,0x0004003b,0x0000000d,0x00000714,0x00000007,0x0004003b,0x0000000d,0x00000715, + 0x00000007,0x0004003b,0x0000000d,0x00000716,0x00000007,0x0004003b,0x0000002c,0x00000717, + 0x00000007,0x0004003b,0x0000000d,0x00000702,0x00000007,0x0004003b,0x0000003a,0x000006f9, + 0x00000007,0x0004003b,0x0000000d,0x000006fa,0x00000007,0x0004003b,0x0000000d,0x000006f2, + 0x00000007,0x0004003b,0x0000003a,0x000006e9,0x00000007,0x0004003b,0x0000000d,0x000006ea, + 0x00000007,0x0004003b,0x0000000d,0x000006e2,0x00000007,0x0004003b,0x0000003a,0x000006d9, + 0x00000007,0x0004003b,0x0000000d,0x000006da,0x00000007,0x0004003b,0x0000000d,0x000006d2, + 0x00000007,0x0004003b,0x0000003a,0x000006c9,0x00000007,0x0004003b,0x0000000d,0x000006ca, + 0x00000007,0x0004003b,0x0000000d,0x000006a9,0x00000007,0x0004003b,0x0000002c,0x000006aa, + 0x00000007,0x0004003b,0x0000002c,0x000006ab,0x00000007,0x0004003b,0x0000002c,0x000006ac, + 0x00000007,0x0004003b,0x0000000d,0x000006ad,0x00000007,0x0004003b,0x0000002c,0x000006ae, + 0x00000007,0x0004003b,0x0000000d,0x000006af,0x00000007,0x0004003b,0x0000002c,0x000006b0, + 0x00000007,0x0004003b,0x0000002c,0x000006b1,0x00000007,0x0004003b,0x0000002c,0x000006b2, + 0x00000007,0x0004003b,0x0000002c,0x0000069f,0x00000007,0x0004003b,0x0000002c,0x000006a0, + 0x00000007,0x0004003b,0x0000002c,0x00000695,0x00000007,0x0004003b,0x0000002c,0x00000696, + 0x00000007,0x0004003b,0x0000002c,0x0000068b,0x00000007,0x0004003b,0x0000002c,0x0000068c, + 0x00000007,0x0004003b,0x0000002c,0x00000681,0x00000007,0x0004003b,0x0000002c,0x00000682, + 0x00000007,0x0004003b,0x0000002c,0x00000677,0x00000007,0x0004003b,0x0000002c,0x00000678, + 0x00000007,0x0004003b,0x0000002c,0x0000066d,0x00000007,0x0004003b,0x0000002c,0x0000066e, + 0x00000007,0x0004003b,0x0000002c,0x00000663,0x00000007,0x0004003b,0x0000002c,0x00000664, + 0x00000007,0x0004003b,0x0000002c,0x00000659,0x00000007,0x0004003b,0x0000002c,0x0000065a, + 0x00000007,0x0004003b,0x0000002c,0x0000064f,0x00000007,0x0004003b,0x0000002c,0x00000650, + 0x00000007,0x0004003b,0x0000002c,0x00000645,0x00000007,0x0004003b,0x0000002c,0x00000646, + 0x00000007,0x0004003b,0x0000002c,0x0000063b,0x00000007,0x0004003b,0x0000002c,0x0000063c, + 0x00000007,0x0004003b,0x0000002c,0x00000631,0x00000007,0x0004003b,0x0000002c,0x00000632, + 0x00000007,0x0004003b,0x0000002c,0x00000627,0x00000007,0x0004003b,0x0000002c,0x00000628, + 0x00000007,0x0004003b,0x0000002c,0x0000061d,0x00000007,0x0004003b,0x0000002c,0x0000061e, + 0x00000007,0x0004003b,0x0000000d,0x0000060d,0x00000007,0x0004003b,0x0000002c,0x0000060e, + 0x00000007,0x0004003b,0x0000002c,0x000004ec,0x00000007,0x0004003b,0x00000008,0x000004ed, + 0x00000007,0x0004003b,0x0000002c,0x000004ee,0x00000007,0x0004003b,0x0000002c,0x000004ef, + 0x00000007,0x0004003b,0x0000000d,0x000004f0,0x00000007,0x0004003b,0x0000000d,0x000004f1, + 0x00000007,0x0004003b,0x0000002c,0x000004f2,0x00000007,0x0004003b,0x0000000d,0x000004f3, + 0x00000007,0x0004003b,0x0000000d,0x000004f4,0x00000007,0x0004003b,0x0000000d,0x000004f5, + 0x00000007,0x0004003b,0x0000000d,0x000004f6,0x00000007,0x0004003b,0x0000000d,0x000004f7, + 0x00000007,0x0004003b,0x0000000d,0x000004f8,0x00000007,0x0004003b,0x0000000d,0x000004f9, + 0x00000007,0x0004003b,0x0000002c,0x000004fa,0x00000007,0x0004003b,0x0000000d,0x000004fb, + 0x00000007,0x0004003b,0x0000000d,0x000004fc,0x00000007,0x0004003b,0x0000002c,0x000004fd, + 0x00000007,0x0004003b,0x0000000d,0x000004fe,0x00000007,0x0004003b,0x0000023f,0x000004ff, + 0x00000007,0x0004003b,0x0000000d,0x00000500,0x00000007,0x0004003b,0x0000000d,0x00000501, + 0x00000007,0x0004003b,0x0000002c,0x00000502,0x00000007,0x0004003b,0x0000002c,0x00000503, + 0x00000007,0x0004003b,0x0000002c,0x00000504,0x00000007,0x0004003b,0x0000000d,0x00000505, + 0x00000007,0x0004003b,0x0000000d,0x00000506,0x00000007,0x0004003b,0x0000002c,0x00000507, + 0x00000007,0x0004003b,0x0000002c,0x00000508,0x00000007,0x0004003b,0x0000002c,0x00000509, + 0x00000007,0x0004003b,0x0000000d,0x0000050a,0x00000007,0x0004003b,0x0000000d,0x0000050b, + 0x00000007,0x0004003b,0x0000002c,0x0000050c,0x00000007,0x0004003b,0x0000002c,0x0000050d, + 0x00000007,0x0004003b,0x0000000d,0x0000050e,0x00000007,0x0004003b,0x0000000d,0x0000050f, + 0x00000007,0x0004003b,0x0000002c,0x00000510,0x00000007,0x0004003b,0x0000002c,0x00000511, + 0x00000007,0x0004003b,0x0000002c,0x00000512,0x00000007,0x0004003b,0x0000002c,0x000004db, + 0x00000007,0x0004003b,0x0000002c,0x000004dc,0x00000007,0x0004003b,0x00000008,0x000004dd, + 0x00000007,0x0004003b,0x00000068,0x000004de,0x00000007,0x0004003b,0x0000000d,0x000004df, + 0x00000007,0x0004003b,0x0000002c,0x000004e0,0x00000007,0x0004003b,0x00000068,0x000004d7, + 0x00000007,0x0004003b,0x0000000d,0x000004d4,0x00000007,0x0004003b,0x0000000d,0x000004d1, + 0x00000007,0x0004003b,0x0000003a,0x000004c2,0x00000007,0x0004003b,0x0000000d,0x000004c3, + 0x00000007,0x0004003b,0x0000000d,0x000004c4,0x00000007,0x0004003b,0x00000008,0x000004bd, + 0x00000007,0x0004003b,0x00000008,0x000004be,0x00000007,0x0004003b,0x0000000d,0x000004ba, + 0x00000007,0x0004003b,0x0000000d,0x000004b7,0x00000007,0x0004003b,0x00000008,0x000004aa, + 0x00000007,0x0004003b,0x00000008,0x000004ab,0x00000007,0x0004003b,0x0000000d,0x0000049a, + 0x00000007,0x0004003b,0x0000002c,0x0000049b,0x00000007,0x0004003b,0x00000008,0x00000495, + 0x00000007,0x0004003b,0x00000008,0x00000496,0x00000007,0x0004003b,0x00000008,0x00000416, + 0x00000007,0x0004003b,0x00000008,0x00000417,0x00000007,0x0004003b,0x0000000d,0x00000418, + 0x00000007,0x0004003b,0x0000000d,0x00000419,0x00000007,0x0004003b,0x0000000d,0x0000041a, + 0x00000007,0x0004003b,0x0000000d,0x0000041b,0x00000007,0x0004003b,0x0000000d,0x0000041c, + 0x00000007,0x0004003b,0x0000000d,0x0000041d,0x00000007,0x0004003b,0x0000000d,0x0000041e, + 0x00000007,0x0004003b,0x0000000d,0x0000041f,0x00000007,0x0004003b,0x00000008,0x00000420, + 0x00000007,0x0004003b,0x0000002c,0x00000421,0x00000007,0x0004003b,0x0000000d,0x00000422, + 0x00000007,0x0004003b,0x00000008,0x00000423,0x00000007,0x0004003b,0x00000008,0x00000373, + 0x00000007,0x0004003b,0x00000008,0x00000376,0x00000007,0x0004003b,0x0000000d,0x00000378, + 0x00000007,0x0004003b,0x0000000d,0x0000037a,0x00000007,0x0004003b,0x0000000d,0x00000385, + 0x00000007,0x0004003b,0x0000000d,0x00000387,0x00000007,0x0004003b,0x0000000d,0x0000038d, + 0x00000007,0x0004003b,0x00000008,0x0000038f,0x00000007,0x0004003b,0x00000008,0x00000392, + 0x00000007,0x0004003b,0x0000000d,0x00000394,0x00000007,0x0004003b,0x0000000d,0x000003a4, + 0x00000007,0x0004003b,0x0000000d,0x000003ae,0x00000007,0x0004003b,0x00000008,0x000003b4, + 0x00000007,0x0004003b,0x00000068,0x000003ba,0x00000007,0x0004003b,0x0000000d,0x000003bc, + 0x00000007,0x0004003b,0x0000002c,0x000003c3,0x00000007,0x0004003b,0x00000008,0x000003c6, + 0x00000007,0x0004003b,0x00000068,0x000003c8,0x00000007,0x0004003b,0x0000002c,0x000003ec, + 0x00000007,0x0004003b,0x0000003a,0x000003ef,0x00000007,0x0004003b,0x0000000d,0x000003f2, + 0x00000007,0x0004003b,0x0000000d,0x000003f6,0x00000007,0x0004003b,0x0000000d,0x00000404, + 0x00000007,0x0004003d,0x00000007,0x00000377,0x00000375,0x0003003e,0x00000376,0x00000377, + 0x0003003e,0x00000378,0x000000d0,0x00050041,0x0000000d,0x00000425,0x00000376,0x000000b5, + 0x0004003d,0x00000006,0x00000426,0x00000425,0x000500be,0x000000cb,0x00000427,0x00000426, + 0x000000ca,0x000300f7,0x00000493,0x00000000,0x000400fa,0x00000427,0x00000428,0x00000436, + 0x000200f8,0x00000428,0x0004003d,0x00000007,0x00000429,0x00000376,0x0003003e,0x00000417, + 0x00000429,0x0004003d,0x00000007,0x00000498,0x00000417,0x0003003e,0x00000495,0x00000498, + 0x0004003d,0x00000007,0x00000499,0x00000495,0x0003003e,0x00000496,0x00000499,0x0004003d, + 0x00000007,0x0000042a,0x00000496,0x0003003e,0x00000416,0x0000042a,0x000300f7,0x00000435, + 0x00000000,0x000400fa,0x000002ed,0x0000042b,0x0000042f,0x000200f8,0x0000042b,0x0004003d, + 0x00000006,0x0000042c,0x00000378,0x0004003d,0x00000007,0x0000042d,0x00000416,0x0005008e, + 0x00000007,0x0000042e,0x0000042d,0x0000042c,0x0003003e,0x00000416,0x0000042e,0x000200f9, + 0x00000435,0x000200f8,0x0000042f,0x0004003d,0x00000006,0x00000430,0x00000378,0x00050041, + 0x0000000d,0x00000431,0x00000416,0x000000b5,0x0004003d,0x00000006,0x00000432,0x00000431, + 0x00050085,0x00000006,0x00000433,0x00000432,0x00000430,0x0003003e,0x00000431,0x00000433, + 0x000200f9,0x00000435,0x000200f8,0x00000435,0x000200f9,0x00000493,0x000200f8,0x00000436, + 0x0004003d,0x00000006,0x00000438,0x00000425,0x000500ba,0x000000cb,0x00000439,0x00000438, + 0x000002fc,0x000300f7,0x00000492,0x00000000,0x000400fa,0x00000439,0x0000043a,0x00000475, + 0x000200f8,0x0000043a,0x00050041,0x0000000d,0x0000043b,0x00000376,0x0000009d,0x0004003d, + 0x00000006,0x0000043c,0x0000043b,0x000500ba,0x000000cb,0x0000043d,0x0000043c,0x000000ca, + 0x000300f7,0x00000445,0x00000000,0x000400fa,0x0000043d,0x0000043e,0x00000441,0x000200f8, + 0x0000043e,0x00050041,0x0000000d,0x0000043f,0x00000376,0x00000087,0x0004003d,0x00000006, + 0x00000440,0x0000043f,0x0003003e,0x00000419,0x00000440,0x000200f9,0x00000445,0x000200f8, + 0x00000441,0x0004003d,0x00000007,0x00000442,0x00000376,0x0007004f,0x00000017,0x00000443, + 0x00000442,0x00000442,0x00000000,0x00000001,0x0006000c,0x00000006,0x00000444,0x00000001, + 0x00000042,0x00000443,0x0003003e,0x00000419,0x00000444,0x000200f9,0x00000445,0x000200f8, + 0x00000445,0x0004003d,0x00000006,0x00000446,0x00000419,0x0003003e,0x00000418,0x00000446, + 0x0004003d,0x00000006,0x00000447,0x00000418,0x0008000c,0x00000006,0x00000448,0x00000001, + 0x0000002b,0x00000447,0x000000ca,0x000000d0,0x0003003e,0x00000418,0x00000448,0x0004003d, + 0x00000006,0x0000044a,0x0000043b,0x0006000c,0x00000006,0x0000044b,0x00000001,0x00000004, + 0x0000044a,0x0003003e,0x0000041a,0x0000044b,0x0004003d,0x00000006,0x0000044c,0x0000041a, + 0x000500ba,0x000000cb,0x0000044d,0x0000044c,0x000000d0,0x000300f7,0x00000457,0x00000000, + 0x000400fa,0x0000044d,0x0000044e,0x00000452,0x000200f8,0x0000044e,0x0004003d,0x00000006, + 0x0000044f,0x00000418,0x00050085,0x00000006,0x00000450,0x0000031a,0x0000044f,0x00050081, + 0x00000006,0x00000451,0x00000450,0x0000031d,0x0003003e,0x0000041c,0x00000451,0x000200f9, + 0x00000457,0x000200f8,0x00000452,0x0004003d,0x00000006,0x00000453,0x00000418,0x00050085, + 0x00000006,0x00000454,0x00000320,0x00000453,0x0004003d,0x00000006,0x00000455,0x0000041a, + 0x00050081,0x00000006,0x00000456,0x00000454,0x00000455,0x0003003e,0x0000041c,0x00000456, + 0x000200f9,0x00000457,0x000200f8,0x00000457,0x0004003d,0x00000006,0x00000458,0x0000041c, + 0x0003003e,0x0000041b,0x00000458,0x0004003d,0x00000006,0x0000045a,0x00000425,0x0004007f, + 0x00000006,0x0000045b,0x0000045a,0x0003003e,0x0000041d,0x0000045b,0x0004003d,0x0000032a, + 0x0000045c,0x0000032c,0x0004003d,0x0000032e,0x0000045d,0x00000330,0x00050056,0x00000332, + 0x0000045e,0x0000045c,0x0000045d,0x0004003d,0x00000006,0x0000045f,0x0000041b,0x0004003d, + 0x00000006,0x00000460,0x0000041d,0x00050050,0x00000017,0x00000461,0x0000045f,0x00000460, + 0x00070058,0x00000007,0x00000462,0x0000045e,0x00000461,0x00000002,0x000000ca,0x0003003e, + 0x00000416,0x00000462,0x0004003d,0x00000006,0x00000463,0x00000378,0x00050041,0x0000000d, + 0x00000464,0x00000416,0x000000b5,0x0004003d,0x00000006,0x00000465,0x00000464,0x00050085, + 0x00000006,0x00000466,0x00000465,0x00000463,0x0003003e,0x00000464,0x00000466,0x000300f7, + 0x00000474,0x00000000,0x000400fa,0x0000033d,0x00000468,0x00000474,0x000200f8,0x00000468, + 0x0004003d,0x00000006,0x0000046a,0x00000464,0x0004003d,0x00000007,0x0000046b,0x00000416, + 0x0008004f,0x00000021,0x0000046c,0x0000046b,0x0000046b,0x00000000,0x00000001,0x00000002, + 0x0005008e,0x00000021,0x0000046d,0x0000046c,0x0000046a,0x00050041,0x0000000d,0x0000046e, + 0x00000416,0x00000087,0x00050051,0x00000006,0x0000046f,0x0000046d,0x00000000,0x0003003e, + 0x0000046e,0x0000046f,0x00050041,0x0000000d,0x00000470,0x00000416,0x0000008a,0x00050051, + 0x00000006,0x00000471,0x0000046d,0x00000001,0x0003003e,0x00000470,0x00000471,0x00050041, + 0x0000000d,0x00000472,0x00000416,0x0000009d,0x00050051,0x00000006,0x00000473,0x0000046d, + 0x00000002,0x0003003e,0x00000472,0x00000473,0x000200f9,0x00000474,0x000200f8,0x00000474, + 0x000200f9,0x00000492,0x000200f8,0x00000475,0x0004003d,0x00000006,0x00000477,0x00000425, + 0x00050083,0x00000006,0x00000479,0x00000415,0x00000477,0x0003003e,0x0000041e,0x00000479, + 0x0004003d,0x0000032a,0x0000047a,0x00000351,0x0004003d,0x0000032e,0x0000047b,0x00000353, + 0x00050056,0x00000332,0x0000047c,0x0000047a,0x0000047b,0x0004003d,0x00000007,0x0000047d, + 0x00000376,0x0007004f,0x00000017,0x0000047e,0x0000047d,0x0000047d,0x00000000,0x00000001, + 0x0004003d,0x00000006,0x0000047f,0x0000041e,0x00070058,0x00000007,0x00000480,0x0000047c, + 0x0000047e,0x00000002,0x0000047f,0x0003003e,0x00000416,0x00000480,0x00050041,0x0000000d, + 0x00000481,0x00000376,0x0000009d,0x0004003d,0x00000006,0x00000482,0x00000481,0x0004003d, + 0x00000006,0x00000483,0x00000378,0x00050085,0x00000006,0x00000484,0x00000482,0x00000483, + 0x0003003e,0x0000041f,0x00000484,0x000300f7,0x00000491,0x00000000,0x000400fa,0x0000035f, + 0x00000485,0x00000489,0x000200f8,0x00000485,0x0004003d,0x00000006,0x00000486,0x0000041f, + 0x0004003d,0x00000007,0x00000487,0x00000416,0x0005008e,0x00000007,0x00000488,0x00000487, + 0x00000486,0x0003003e,0x00000416,0x00000488,0x000200f9,0x00000491,0x000200f8,0x00000489, + 0x0004003d,0x00000007,0x0000048a,0x00000416,0x0003003e,0x00000420,0x0000048a,0x0004003d, + 0x00000007,0x0000049d,0x00000420,0x0008004f,0x00000021,0x0000049e,0x0000049d,0x0000049d, + 0x00000000,0x00000001,0x00000002,0x00050041,0x0000000d,0x0000049f,0x00000420,0x000000b5, + 0x0004003d,0x00000006,0x000004a0,0x0000049f,0x000500b7,0x000000cb,0x000004a1,0x000004a0, + 0x000000ca,0x000300f7,0x000004a7,0x00000000,0x000400fa,0x000004a1,0x000004a2,0x000004a6, + 0x000200f8,0x000004a2,0x0004003d,0x00000006,0x000004a4,0x0000049f,0x00050088,0x00000006, + 0x000004a5,0x000000d0,0x000004a4,0x0003003e,0x0000049a,0x000004a5,0x000200f9,0x000004a7, + 0x000200f8,0x000004a6,0x0003003e,0x0000049a,0x000000ca,0x000200f9,0x000004a7,0x000200f8, + 0x000004a7,0x0004003d,0x00000006,0x000004a8,0x0000049a,0x0005008e,0x00000021,0x000004a9, + 0x0000049e,0x000004a8,0x0003003e,0x0000049b,0x000004a9,0x0004003d,0x00000021,0x0000048b, + 0x0000049b,0x00050041,0x0000000d,0x0000048c,0x00000416,0x000000b5,0x0004003d,0x00000006, + 0x0000048d,0x0000048c,0x0004003d,0x00000006,0x0000048e,0x0000041f,0x00050085,0x00000006, + 0x0000048f,0x0000048d,0x0000048e,0x0003003e,0x00000421,0x0000048b,0x0003003e,0x00000422, + 0x0000048f,0x0004003d,0x00000021,0x000004ad,0x00000421,0x00050041,0x0000000d,0x000004ae, + 0x000004aa,0x00000087,0x00050051,0x00000006,0x000004af,0x000004ad,0x00000000,0x0003003e, + 0x000004ae,0x000004af,0x00050041,0x0000000d,0x000004b0,0x000004aa,0x0000008a,0x00050051, + 0x00000006,0x000004b1,0x000004ad,0x00000001,0x0003003e,0x000004b0,0x000004b1,0x00050041, + 0x0000000d,0x000004b2,0x000004aa,0x0000009d,0x00050051,0x00000006,0x000004b3,0x000004ad, + 0x00000002,0x0003003e,0x000004b2,0x000004b3,0x0004003d,0x00000006,0x000004b4,0x00000422, + 0x00050041,0x0000000d,0x000004b5,0x000004aa,0x000000b5,0x0003003e,0x000004b5,0x000004b4, + 0x0004003d,0x00000007,0x000004b6,0x000004aa,0x0003003e,0x000004ab,0x000004b6,0x0004003d, + 0x00000007,0x00000490,0x000004ab,0x0003003e,0x00000416,0x00000490,0x000200f9,0x00000491, + 0x000200f8,0x00000491,0x000200f9,0x00000492,0x000200f8,0x00000492,0x000200f9,0x00000493, + 0x000200f8,0x00000493,0x0004003d,0x00000007,0x00000494,0x00000416,0x0003003e,0x00000423, + 0x00000494,0x0004003d,0x00000007,0x00000379,0x00000423,0x0003003e,0x00000373,0x00000379, + 0x0004003d,0x0000032a,0x0000037c,0x0000037b,0x0004003d,0x0000032e,0x0000037e,0x0000037d, + 0x00050056,0x00000332,0x0000037f,0x0000037c,0x0000037e,0x0004003d,0x00000017,0x00000382, + 0x00000381,0x00070058,0x00000007,0x00000383,0x0000037f,0x00000382,0x00000002,0x000000ca, + 0x00050051,0x00000006,0x00000384,0x00000383,0x00000000,0x0003003e,0x00000385,0x000000ca, + 0x0004003d,0x00000006,0x000004b9,0x00000385,0x0003003e,0x000004b7,0x000004b9,0x0004003d, + 0x00000006,0x00000386,0x000004b7,0x0003003e,0x00000387,0x000000d0,0x0004003d,0x00000006, + 0x000004bc,0x00000387,0x0003003e,0x000004ba,0x000004bc,0x0004003d,0x00000006,0x00000388, + 0x000004ba,0x0008000c,0x00000006,0x00000389,0x00000001,0x0000002b,0x00000384,0x00000386, + 0x00000388,0x0003003e,0x0000037a,0x00000389,0x000300f7,0x0000038c,0x00000000,0x000400fa, + 0x0000038a,0x0000038b,0x0000038c,0x000200f8,0x0000038b,0x0004003d,0x00000007,0x00000390, + 0x0000038e,0x0003003e,0x0000038f,0x00000390,0x0004003d,0x00000007,0x000004c0,0x0000038f, + 0x0003003e,0x000004bd,0x000004c0,0x0004003d,0x00000007,0x000004c1,0x000004bd,0x0003003e, + 0x000004be,0x000004c1,0x0004003d,0x00000007,0x00000391,0x000004be,0x0003003e,0x00000392, + 0x00000391,0x0004003d,0x00000007,0x000004c6,0x00000392,0x0007004f,0x00000017,0x000004c7, + 0x000004c6,0x000004c6,0x00000000,0x00000001,0x0004003d,0x00000007,0x000004c8,0x00000392, + 0x0007004f,0x00000017,0x000004c9,0x000004c8,0x000004c8,0x00000002,0x00000003,0x0007000c, + 0x00000017,0x000004ca,0x00000001,0x00000025,0x000004c7,0x000004c9,0x0003003e,0x000004c2, + 0x000004ca,0x00050041,0x0000000d,0x000004cb,0x000004c2,0x00000087,0x0004003d,0x00000006, + 0x000004cc,0x000004cb,0x00050041,0x0000000d,0x000004cd,0x000004c2,0x0000008a,0x0004003d, + 0x00000006,0x000004ce,0x000004cd,0x0007000c,0x00000006,0x000004cf,0x00000001,0x00000025, + 0x000004cc,0x000004ce,0x0003003e,0x000004c3,0x000004cf,0x0004003d,0x00000006,0x000004d0, + 0x000004c3,0x0003003e,0x000004c4,0x000004d0,0x0004003d,0x00000006,0x00000393,0x000004c4, + 0x0003003e,0x00000394,0x000000ca,0x0004003d,0x00000006,0x000004d3,0x00000394,0x0003003e, + 0x000004d1,0x000004d3,0x0004003d,0x00000006,0x00000395,0x000004d1,0x0007000c,0x00000006, + 0x00000396,0x00000001,0x00000028,0x00000393,0x00000395,0x0003003e,0x0000038d,0x00000396, + 0x0004003d,0x00000006,0x00000397,0x0000038d,0x0004003d,0x00000006,0x00000398,0x0000037a, + 0x0007000c,0x00000006,0x00000399,0x00000001,0x00000025,0x00000397,0x00000398,0x0003003e, + 0x0000037a,0x00000399,0x000200f9,0x0000038c,0x000200f8,0x0000038c,0x000300f7,0x0000039c, + 0x00000000,0x000400fa,0x0000039a,0x0000039b,0x0000039c,0x000200f8,0x0000039b,0x0004003d, + 0x00000006,0x0000039f,0x0000039e,0x000500b7,0x000000cb,0x000003a0,0x0000039f,0x000000ca, + 0x000200f9,0x0000039c,0x000200f8,0x0000039c,0x000700f5,0x000000cb,0x000003a1,0x0000039a, + 0x0000038c,0x000003a0,0x0000039b,0x000300f7,0x000003a3,0x00000000,0x000400fa,0x000003a1, + 0x000003a2,0x000003a3,0x000200f8,0x000003a2,0x0004003d,0x000003a5,0x000003a8,0x000003a7, + 0x00050062,0x00000007,0x000003ab,0x000003a8,0x000003aa,0x00050051,0x00000006,0x000003ac, + 0x000003ab,0x00000000,0x0003003e,0x000003a4,0x000003ac,0x0004003d,0x00000006,0x000003ad, + 0x000003a4,0x0003003e,0x000003ae,0x000000ca,0x0004003d,0x00000006,0x000004d6,0x000003ae, + 0x0003003e,0x000004d4,0x000004d6,0x0004003d,0x00000006,0x000003af,0x000004d4,0x0007000c, + 0x00000006,0x000003b0,0x00000001,0x00000028,0x000003ad,0x000003af,0x0003003e,0x000003a4, + 0x000003b0,0x0004003d,0x00000006,0x000003b1,0x0000037a,0x0004003d,0x00000006,0x000003b2, + 0x000003a4,0x0007000c,0x00000006,0x000003b3,0x00000001,0x00000025,0x000003b1,0x000003b2, + 0x0003003e,0x0000037a,0x000003b3,0x000200f9,0x000003a3,0x000200f8,0x000003a3,0x0004003d, + 0x000003a5,0x000003b6,0x000003b5,0x00050062,0x00000007,0x000003b7,0x000003b6,0x000003aa, + 0x0003003e,0x000003b4,0x000003b7,0x000300f7,0x000003b9,0x00000000,0x000400fa,0x000002ec, + 0x000003b8,0x000003e1,0x000200f8,0x000003b8,0x0004003d,0x00000006,0x000003bd,0x000003bb, + 0x0003003e,0x000003bc,0x000003bd,0x0004003d,0x00000006,0x000004d9,0x000003bc,0x0004006d, + 0x0000000e,0x000004da,0x000004d9,0x0003003e,0x000004d7,0x000004da,0x0004003d,0x0000000e, + 0x000003be,0x000004d7,0x0003003e,0x000003ba,0x000003be,0x0004003d,0x0000000e,0x000003bf, + 0x000003ba,0x000500ab,0x000000cb,0x000003c0,0x000003bf,0x00000087,0x000300f7,0x000003c2, + 0x00000000,0x000400fa,0x000003c0,0x000003c1,0x000003c2,0x000200f8,0x000003c1,0x0004003d, + 0x00000007,0x000003c4,0x00000373,0x0008004f,0x00000021,0x000003c5,0x000003c4,0x000003c4, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x000003c3,0x000003c5,0x0004003d,0x00000007, + 0x000003c7,0x000003b4,0x0003003e,0x000003c6,0x000003c7,0x0004003d,0x0000000e,0x000003c9, + 0x000003ba,0x0003003e,0x000003c8,0x000003c9,0x0004003d,0x00000021,0x000004e2,0x000003c3, + 0x0003003e,0x000004dc,0x000004e2,0x0004003d,0x00000007,0x000004e3,0x000003c6,0x0003003e, + 0x000004dd,0x000004e3,0x0004003d,0x0000000e,0x000004e4,0x000003c8,0x0003003e,0x000004de, + 0x000004e4,0x0004003d,0x00000007,0x00000514,0x000004dd,0x0003003e,0x000004ed,0x00000514, + 0x0004003d,0x00000007,0x00000610,0x000004ed,0x0008004f,0x00000021,0x00000611,0x00000610, + 0x00000610,0x00000000,0x00000001,0x00000002,0x00050041,0x0000000d,0x00000612,0x000004ed, + 0x000000b5,0x0004003d,0x00000006,0x00000613,0x00000612,0x000500b7,0x000000cb,0x00000614, + 0x00000613,0x000000ca,0x000300f7,0x0000061a,0x00000000,0x000400fa,0x00000614,0x00000615, + 0x00000619,0x000200f8,0x00000615,0x0004003d,0x00000006,0x00000617,0x00000612,0x00050088, + 0x00000006,0x00000618,0x000000d0,0x00000617,0x0003003e,0x0000060d,0x00000618,0x000200f9, + 0x0000061a,0x000200f8,0x00000619,0x0003003e,0x0000060d,0x000000ca,0x000200f9,0x0000061a, + 0x000200f8,0x0000061a,0x0004003d,0x00000006,0x0000061b,0x0000060d,0x0005008e,0x00000021, + 0x0000061c,0x00000611,0x0000061b,0x0003003e,0x0000060e,0x0000061c,0x0004003d,0x00000021, + 0x00000515,0x0000060e,0x0003003e,0x000004ec,0x00000515,0x0004003d,0x0000000e,0x00000516, + 0x000004de,0x000300f7,0x0000060b,0x00000000,0x002100fb,0x00000516,0x0000060b,0x0000000b, + 0x00000517,0x00000001,0x0000051b,0x00000002,0x00000523,0x00000003,0x00000533,0x00000004, + 0x00000537,0x00000005,0x0000053b,0x00000006,0x0000055d,0x00000007,0x00000589,0x00000008, + 0x00000599,0x00000009,0x000005d3,0x0000000a,0x000005d8,0x0000000c,0x000005e1,0x0000000d, + 0x000005ec,0x0000000e,0x000005f7,0x0000000f,0x00000601,0x000200f8,0x00000517,0x0004003d, + 0x00000021,0x00000518,0x000004dc,0x0004003d,0x00000021,0x00000519,0x000004ec,0x00050085, + 0x00000021,0x0000051a,0x00000518,0x00000519,0x0003003e,0x000004ee,0x0000051a,0x000200f9, + 0x0000060b,0x000200f8,0x0000051b,0x0004003d,0x00000021,0x0000051c,0x000004dc,0x0004003d, + 0x00000021,0x0000051d,0x000004ec,0x00050081,0x00000021,0x0000051e,0x0000051c,0x0000051d, + 0x0004003d,0x00000021,0x0000051f,0x000004dc,0x0004003d,0x00000021,0x00000520,0x000004ec, + 0x00050085,0x00000021,0x00000521,0x0000051f,0x00000520,0x00050083,0x00000021,0x00000522, + 0x0000051e,0x00000521,0x0003003e,0x000004ee,0x00000522,0x000200f9,0x0000060b,0x000200f8, + 0x00000523,0x0004003d,0x00000021,0x00000524,0x000004dc,0x0004003d,0x00000021,0x00000525, + 0x000004ec,0x00050085,0x00000021,0x00000526,0x00000524,0x00000525,0x0003003e,0x000004ef, + 0x00000526,0x0004003d,0x00000021,0x00000527,0x000004ef,0x0004003d,0x00000021,0x00000528, + 0x000004dc,0x0004003d,0x00000021,0x00000529,0x000004ec,0x00050081,0x00000021,0x0000052a, + 0x00000528,0x00000529,0x0004003d,0x00000021,0x0000052b,0x000004ef,0x00050083,0x00000021, + 0x0000052c,0x0000052a,0x0000052b,0x00050083,0x00000021,0x0000052d,0x0000052c,0x00000414, + 0x0004003d,0x00000021,0x0000052e,0x000004ec,0x0003003e,0x000004f0,0x000001bc,0x0004003d, + 0x00000006,0x00000620,0x000004f0,0x00050041,0x0000000d,0x00000621,0x0000061d,0x00000087, + 0x0003003e,0x00000621,0x00000620,0x0004003d,0x00000006,0x00000622,0x000004f0,0x00050041, + 0x0000000d,0x00000623,0x0000061d,0x0000008a,0x0003003e,0x00000623,0x00000622,0x0004003d, + 0x00000006,0x00000624,0x000004f0,0x00050041,0x0000000d,0x00000625,0x0000061d,0x0000009d, + 0x0003003e,0x00000625,0x00000624,0x0004003d,0x00000021,0x00000626,0x0000061d,0x0003003e, + 0x0000061e,0x00000626,0x0004003d,0x00000021,0x0000052f,0x0000061e,0x000500ba,0x000001c2, + 0x00000530,0x0000052e,0x0000052f,0x000600a9,0x00000021,0x00000531,0x00000530,0x0000052d, + 0x00000527,0x0005008e,0x00000021,0x00000532,0x00000531,0x000001b5,0x0003003e,0x000004ee, + 0x00000532,0x000200f9,0x0000060b,0x000200f8,0x00000533,0x0004003d,0x00000021,0x00000534, + 0x000004dc,0x0004003d,0x00000021,0x00000535,0x000004ec,0x0007000c,0x00000021,0x00000536, + 0x00000001,0x00000025,0x00000534,0x00000535,0x0003003e,0x000004ee,0x00000536,0x000200f9, + 0x0000060b,0x000200f8,0x00000537,0x0004003d,0x00000021,0x00000538,0x000004dc,0x0004003d, + 0x00000021,0x00000539,0x000004ec,0x0007000c,0x00000021,0x0000053a,0x00000001,0x00000028, + 0x00000538,0x00000539,0x0003003e,0x000004ee,0x0000053a,0x000200f9,0x0000060b,0x000200f8, + 0x0000053b,0x0004003d,0x00000007,0x0000053c,0x000004dd,0x0008004f,0x00000021,0x0000053d, + 0x0000053c,0x0000053c,0x00000000,0x00000001,0x00000002,0x0003003e,0x000004f1,0x000000ca, + 0x0004003d,0x00000006,0x0000062a,0x000004f1,0x00050041,0x0000000d,0x0000062b,0x00000627, + 0x00000087,0x0003003e,0x0000062b,0x0000062a,0x0004003d,0x00000006,0x0000062c,0x000004f1, + 0x00050041,0x0000000d,0x0000062d,0x00000627,0x0000008a,0x0003003e,0x0000062d,0x0000062c, + 0x0004003d,0x00000006,0x0000062e,0x000004f1,0x00050041,0x0000000d,0x0000062f,0x00000627, + 0x0000009d,0x0003003e,0x0000062f,0x0000062e,0x0004003d,0x00000021,0x00000630,0x00000627, + 0x0003003e,0x00000628,0x00000630,0x0004003d,0x00000021,0x0000053e,0x00000628,0x0004003d, + 0x00000007,0x0000053f,0x000004dd,0x0008004f,0x00000021,0x00000540,0x0000053f,0x0000053f, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x00000021,0x00000541,0x00000001,0x0000002b, + 0x0000053d,0x0000053e,0x00000540,0x00050041,0x0000000d,0x00000542,0x000004dd,0x00000087, + 0x00050051,0x00000006,0x00000543,0x00000541,0x00000000,0x0003003e,0x00000542,0x00000543, + 0x00050041,0x0000000d,0x00000544,0x000004dd,0x0000008a,0x00050051,0x00000006,0x00000545, + 0x00000541,0x00000001,0x0003003e,0x00000544,0x00000545,0x00050041,0x0000000d,0x00000546, + 0x000004dd,0x0000009d,0x00050051,0x00000006,0x00000547,0x00000541,0x00000002,0x0003003e, + 0x00000546,0x00000547,0x0004003d,0x00000021,0x00000548,0x000004dc,0x00050083,0x00000021, + 0x00000549,0x00000413,0x00000548,0x0003003e,0x000004f3,0x000000ca,0x0004003d,0x00000006, + 0x00000634,0x000004f3,0x00050041,0x0000000d,0x00000635,0x00000631,0x00000087,0x0003003e, + 0x00000635,0x00000634,0x0004003d,0x00000006,0x00000636,0x000004f3,0x00050041,0x0000000d, + 0x00000637,0x00000631,0x0000008a,0x0003003e,0x00000637,0x00000636,0x0004003d,0x00000006, + 0x00000638,0x000004f3,0x00050041,0x0000000d,0x00000639,0x00000631,0x0000009d,0x0003003e, + 0x00000639,0x00000638,0x0004003d,0x00000021,0x0000063a,0x00000631,0x0003003e,0x00000632, + 0x0000063a,0x0004003d,0x00000021,0x0000054a,0x00000632,0x0003003e,0x000004f4,0x000000d0, + 0x0004003d,0x00000006,0x0000063e,0x000004f4,0x00050041,0x0000000d,0x0000063f,0x0000063b, + 0x00000087,0x0003003e,0x0000063f,0x0000063e,0x0004003d,0x00000006,0x00000640,0x000004f4, + 0x00050041,0x0000000d,0x00000641,0x0000063b,0x0000008a,0x0003003e,0x00000641,0x00000640, + 0x0004003d,0x00000006,0x00000642,0x000004f4,0x00050041,0x0000000d,0x00000643,0x0000063b, + 0x0000009d,0x0003003e,0x00000643,0x00000642,0x0004003d,0x00000021,0x00000644,0x0000063b, + 0x0003003e,0x0000063c,0x00000644,0x0004003d,0x00000021,0x0000054b,0x0000063c,0x0008000c, + 0x00000021,0x0000054c,0x00000001,0x0000002b,0x00000549,0x0000054a,0x0000054b,0x00050041, + 0x0000000d,0x0000054d,0x000004dd,0x000000b5,0x0004003d,0x00000006,0x0000054e,0x0000054d, + 0x0005008e,0x00000021,0x0000054f,0x0000054c,0x0000054e,0x0003003e,0x000004f2,0x0000054f, + 0x0003003e,0x000004f5,0x000000d0,0x0004003d,0x00000006,0x00000648,0x000004f5,0x00050041, + 0x0000000d,0x00000649,0x00000645,0x00000087,0x0003003e,0x00000649,0x00000648,0x0004003d, + 0x00000006,0x0000064a,0x000004f5,0x00050041,0x0000000d,0x0000064b,0x00000645,0x0000008a, + 0x0003003e,0x0000064b,0x0000064a,0x0004003d,0x00000006,0x0000064c,0x000004f5,0x00050041, + 0x0000000d,0x0000064d,0x00000645,0x0000009d,0x0003003e,0x0000064d,0x0000064c,0x0004003d, + 0x00000021,0x0000064e,0x00000645,0x0003003e,0x00000646,0x0000064e,0x0004003d,0x00000021, + 0x00000550,0x00000646,0x0004003d,0x00000007,0x00000551,0x000004dd,0x0008004f,0x00000021, + 0x00000552,0x00000551,0x00000551,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000021, + 0x00000553,0x000004f2,0x00050088,0x00000021,0x00000554,0x00000552,0x00000553,0x0007000c, + 0x00000021,0x00000555,0x00000001,0x00000025,0x00000550,0x00000554,0x0004003d,0x00000007, + 0x00000556,0x000004dd,0x0008004f,0x00000021,0x00000557,0x00000556,0x00000556,0x00000000, + 0x00000001,0x00000002,0x0006000c,0x00000021,0x00000558,0x00000001,0x00000006,0x00000557, + 0x0004003d,0x00000021,0x00000559,0x000004f2,0x0003003e,0x000004f6,0x000000ca,0x0004003d, + 0x00000006,0x00000652,0x000004f6,0x00050041,0x0000000d,0x00000653,0x0000064f,0x00000087, + 0x0003003e,0x00000653,0x00000652,0x0004003d,0x00000006,0x00000654,0x000004f6,0x00050041, + 0x0000000d,0x00000655,0x0000064f,0x0000008a,0x0003003e,0x00000655,0x00000654,0x0004003d, + 0x00000006,0x00000656,0x000004f6,0x00050041,0x0000000d,0x00000657,0x0000064f,0x0000009d, + 0x0003003e,0x00000657,0x00000656,0x0004003d,0x00000021,0x00000658,0x0000064f,0x0003003e, + 0x00000650,0x00000658,0x0004003d,0x00000021,0x0000055a,0x00000650,0x000500b4,0x000001c2, + 0x0000055b,0x00000559,0x0000055a,0x000600a9,0x00000021,0x0000055c,0x0000055b,0x00000558, + 0x00000555,0x0003003e,0x000004ee,0x0000055c,0x000200f9,0x0000060b,0x000200f8,0x0000055d, + 0x0004003d,0x00000021,0x0000055e,0x000004dc,0x0003003e,0x000004f7,0x000000ca,0x0004003d, + 0x00000006,0x0000065c,0x000004f7,0x00050041,0x0000000d,0x0000065d,0x00000659,0x00000087, + 0x0003003e,0x0000065d,0x0000065c,0x0004003d,0x00000006,0x0000065e,0x000004f7,0x00050041, + 0x0000000d,0x0000065f,0x00000659,0x0000008a,0x0003003e,0x0000065f,0x0000065e,0x0004003d, + 0x00000006,0x00000660,0x000004f7,0x00050041,0x0000000d,0x00000661,0x00000659,0x0000009d, + 0x0003003e,0x00000661,0x00000660,0x0004003d,0x00000021,0x00000662,0x00000659,0x0003003e, + 0x0000065a,0x00000662,0x0004003d,0x00000021,0x0000055f,0x0000065a,0x0003003e,0x000004f8, + 0x000000d0,0x0004003d,0x00000006,0x00000666,0x000004f8,0x00050041,0x0000000d,0x00000667, + 0x00000663,0x00000087,0x0003003e,0x00000667,0x00000666,0x0004003d,0x00000006,0x00000668, + 0x000004f8,0x00050041,0x0000000d,0x00000669,0x00000663,0x0000008a,0x0003003e,0x00000669, + 0x00000668,0x0004003d,0x00000006,0x0000066a,0x000004f8,0x00050041,0x0000000d,0x0000066b, + 0x00000663,0x0000009d,0x0003003e,0x0000066b,0x0000066a,0x0004003d,0x00000021,0x0000066c, + 0x00000663,0x0003003e,0x00000664,0x0000066c,0x0004003d,0x00000021,0x00000560,0x00000664, + 0x0008000c,0x00000021,0x00000561,0x00000001,0x0000002b,0x0000055e,0x0000055f,0x00000560, + 0x0003003e,0x000004dc,0x00000561,0x0004003d,0x00000007,0x00000562,0x000004dd,0x0008004f, + 0x00000021,0x00000563,0x00000562,0x00000562,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x000004f9,0x000000ca,0x0004003d,0x00000006,0x00000670,0x000004f9,0x00050041,0x0000000d, + 0x00000671,0x0000066d,0x00000087,0x0003003e,0x00000671,0x00000670,0x0004003d,0x00000006, + 0x00000672,0x000004f9,0x00050041,0x0000000d,0x00000673,0x0000066d,0x0000008a,0x0003003e, + 0x00000673,0x00000672,0x0004003d,0x00000006,0x00000674,0x000004f9,0x00050041,0x0000000d, + 0x00000675,0x0000066d,0x0000009d,0x0003003e,0x00000675,0x00000674,0x0004003d,0x00000021, + 0x00000676,0x0000066d,0x0003003e,0x0000066e,0x00000676,0x0004003d,0x00000021,0x00000564, + 0x0000066e,0x0004003d,0x00000007,0x00000565,0x000004dd,0x0008004f,0x00000021,0x00000566, + 0x00000565,0x00000565,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000021,0x00000567, + 0x00000001,0x0000002b,0x00000563,0x00000564,0x00000566,0x00050041,0x0000000d,0x00000568, + 0x000004dd,0x00000087,0x00050051,0x00000006,0x00000569,0x00000567,0x00000000,0x0003003e, + 0x00000568,0x00000569,0x00050041,0x0000000d,0x0000056a,0x000004dd,0x0000008a,0x00050051, + 0x00000006,0x0000056b,0x00000567,0x00000001,0x0003003e,0x0000056a,0x0000056b,0x00050041, + 0x0000000d,0x0000056c,0x000004dd,0x0000009d,0x00050051,0x00000006,0x0000056d,0x00000567, + 0x00000002,0x0003003e,0x0000056c,0x0000056d,0x00050041,0x0000000d,0x0000056e,0x000004dd, + 0x000000b5,0x0004003d,0x00000006,0x0000056f,0x0000056e,0x000500b4,0x000000cb,0x00000570, + 0x0000056f,0x000000ca,0x000300f7,0x00000573,0x00000000,0x000400fa,0x00000570,0x00000571, + 0x00000573,0x000200f8,0x00000571,0x0003003e,0x0000056e,0x000000d0,0x000200f9,0x00000573, + 0x000200f8,0x00000573,0x0004003d,0x00000006,0x00000575,0x0000056e,0x0004003d,0x00000007, + 0x00000576,0x000004dd,0x0008004f,0x00000021,0x00000577,0x00000576,0x00000576,0x00000000, + 0x00000001,0x00000002,0x00060050,0x00000021,0x00000578,0x00000575,0x00000575,0x00000575, + 0x00050083,0x00000021,0x00000579,0x00000578,0x00000577,0x0003003e,0x000004fa,0x00000579, + 0x0003003e,0x000004fb,0x000000d0,0x0004003d,0x00000006,0x0000067a,0x000004fb,0x00050041, + 0x0000000d,0x0000067b,0x00000677,0x00000087,0x0003003e,0x0000067b,0x0000067a,0x0004003d, + 0x00000006,0x0000067c,0x000004fb,0x00050041,0x0000000d,0x0000067d,0x00000677,0x0000008a, + 0x0003003e,0x0000067d,0x0000067c,0x0004003d,0x00000006,0x0000067e,0x000004fb,0x00050041, + 0x0000000d,0x0000067f,0x00000677,0x0000009d,0x0003003e,0x0000067f,0x0000067e,0x0004003d, + 0x00000021,0x00000680,0x00000677,0x0003003e,0x00000678,0x00000680,0x0004003d,0x00000021, + 0x0000057a,0x00000678,0x0004003d,0x00000021,0x0000057b,0x000004fa,0x0004003d,0x00000021, + 0x0000057c,0x000004dc,0x0004003d,0x00000006,0x0000057e,0x0000056e,0x0005008e,0x00000021, + 0x0000057f,0x0000057c,0x0000057e,0x00050088,0x00000021,0x00000580,0x0000057b,0x0000057f, + 0x0007000c,0x00000021,0x00000581,0x00000001,0x00000025,0x0000057a,0x00000580,0x0004003d, + 0x00000021,0x00000582,0x000004fa,0x0006000c,0x00000021,0x00000583,0x00000001,0x00000006, + 0x00000582,0x0004003d,0x00000021,0x00000584,0x000004dc,0x0003003e,0x000004fc,0x000000ca, + 0x0004003d,0x00000006,0x00000684,0x000004fc,0x00050041,0x0000000d,0x00000685,0x00000681, + 0x00000087,0x0003003e,0x00000685,0x00000684,0x0004003d,0x00000006,0x00000686,0x000004fc, + 0x00050041,0x0000000d,0x00000687,0x00000681,0x0000008a,0x0003003e,0x00000687,0x00000686, + 0x0004003d,0x00000006,0x00000688,0x000004fc,0x00050041,0x0000000d,0x00000689,0x00000681, + 0x0000009d,0x0003003e,0x00000689,0x00000688,0x0004003d,0x00000021,0x0000068a,0x00000681, + 0x0003003e,0x00000682,0x0000068a,0x0004003d,0x00000021,0x00000585,0x00000682,0x000500b4, + 0x000001c2,0x00000586,0x00000584,0x00000585,0x000600a9,0x00000021,0x00000587,0x00000586, + 0x00000583,0x00000581,0x00050083,0x00000021,0x00000588,0x00000413,0x00000587,0x0003003e, + 0x000004ee,0x00000588,0x000200f9,0x0000060b,0x000200f8,0x00000589,0x0004003d,0x00000021, + 0x0000058a,0x000004dc,0x0004003d,0x00000021,0x0000058b,0x000004ec,0x00050085,0x00000021, + 0x0000058c,0x0000058a,0x0000058b,0x0003003e,0x000004fd,0x0000058c,0x0004003d,0x00000021, + 0x0000058d,0x000004fd,0x0004003d,0x00000021,0x0000058e,0x000004dc,0x0004003d,0x00000021, + 0x0000058f,0x000004ec,0x00050081,0x00000021,0x00000590,0x0000058e,0x0000058f,0x0004003d, + 0x00000021,0x00000591,0x000004fd,0x00050083,0x00000021,0x00000592,0x00000590,0x00000591, + 0x00050083,0x00000021,0x00000593,0x00000592,0x00000414,0x0004003d,0x00000021,0x00000594, + 0x000004dc,0x0003003e,0x000004fe,0x000001bc,0x0004003d,0x00000006,0x0000068e,0x000004fe, + 0x00050041,0x0000000d,0x0000068f,0x0000068b,0x00000087,0x0003003e,0x0000068f,0x0000068e, + 0x0004003d,0x00000006,0x00000690,0x000004fe,0x00050041,0x0000000d,0x00000691,0x0000068b, + 0x0000008a,0x0003003e,0x00000691,0x00000690,0x0004003d,0x00000006,0x00000692,0x000004fe, + 0x00050041,0x0000000d,0x00000693,0x0000068b,0x0000009d,0x0003003e,0x00000693,0x00000692, + 0x0004003d,0x00000021,0x00000694,0x0000068b,0x0003003e,0x0000068c,0x00000694,0x0004003d, + 0x00000021,0x00000595,0x0000068c,0x000500ba,0x000001c2,0x00000596,0x00000594,0x00000595, + 0x000600a9,0x00000021,0x00000597,0x00000596,0x00000593,0x0000058d,0x0005008e,0x00000021, + 0x00000598,0x00000597,0x000001b5,0x0003003e,0x000004ee,0x00000598,0x000200f9,0x0000060b, + 0x000200f8,0x00000599,0x0003003e,0x000004ff,0x00000241,0x000200f9,0x0000059a,0x000200f8, + 0x0000059a,0x0004003d,0x0000023e,0x0000059c,0x000004ff,0x000500b1,0x000000cb,0x0000059d, + 0x0000059c,0x00000248,0x000400f6,0x000005c9,0x000005c6,0x00000000,0x000400fa,0x0000059d, + 0x0000059e,0x000005c9,0x000200f8,0x0000059e,0x0004003d,0x0000023e,0x0000059f,0x000004ff, + 0x00050041,0x0000000d,0x000005a0,0x000004dc,0x0000059f,0x0004003d,0x00000006,0x000005a1, + 0x000005a0,0x000500bc,0x000000cb,0x000005a2,0x000005a1,0x000001bc,0x000300f7,0x000005c5, + 0x00000000,0x000400fa,0x000005a2,0x000005a3,0x000005aa,0x000200f8,0x000005a3,0x0004003d, + 0x0000023e,0x000005a4,0x000004ff,0x0004003d,0x0000023e,0x000005a5,0x000004ff,0x00050041, + 0x0000000d,0x000005a6,0x000004ec,0x000005a5,0x0004003d,0x00000006,0x000005a7,0x000005a6, + 0x00050083,0x00000006,0x000005a8,0x000000d0,0x000005a7,0x00050041,0x0000000d,0x000005a9, + 0x000004ee,0x000005a4,0x0003003e,0x000005a9,0x000005a8,0x000200f9,0x000005c5,0x000200f8, + 0x000005aa,0x0004003d,0x0000023e,0x000005ab,0x000004ff,0x00050041,0x0000000d,0x000005ac, + 0x000004ec,0x000005ab,0x0004003d,0x00000006,0x000005ad,0x000005ac,0x000500bc,0x000000cb, + 0x000005ae,0x000005ad,0x0000025a,0x000300f7,0x000005c4,0x00000000,0x000400fa,0x000005ae, + 0x000005af,0x000005bc,0x000200f8,0x000005af,0x0004003d,0x0000023e,0x000005b0,0x000004ff, + 0x0004003d,0x0000023e,0x000005b1,0x000004ff,0x00050041,0x0000000d,0x000005b2,0x000004ec, + 0x000005b1,0x0004003d,0x00000006,0x000005b3,0x000005b2,0x00050085,0x00000006,0x000005b4, + 0x0000025f,0x000005b3,0x00050083,0x00000006,0x000005b5,0x000005b4,0x00000264,0x0004003d, + 0x0000023e,0x000005b6,0x000004ff,0x00050041,0x0000000d,0x000005b7,0x000004ec,0x000005b6, + 0x0004003d,0x00000006,0x000005b8,0x000005b7,0x00050085,0x00000006,0x000005b9,0x000005b5, + 0x000005b8,0x00050081,0x00000006,0x000005ba,0x000005b9,0x0000026a,0x00050041,0x0000000d, + 0x000005bb,0x000004ee,0x000005b0,0x0003003e,0x000005bb,0x000005ba,0x000200f9,0x000005c4, + 0x000200f8,0x000005bc,0x0004003d,0x0000023e,0x000005bd,0x000004ff,0x0004003d,0x0000023e, + 0x000005be,0x000004ff,0x00050041,0x0000000d,0x000005bf,0x000004ec,0x000005be,0x0004003d, + 0x00000006,0x000005c0,0x000005bf,0x0006000c,0x00000006,0x000005c1,0x00000001,0x00000020, + 0x000005c0,0x00050083,0x00000006,0x000005c2,0x000005c1,0x000000d0,0x00050041,0x0000000d, + 0x000005c3,0x000004ee,0x000005bd,0x0003003e,0x000005c3,0x000005c2,0x000200f9,0x000005c4, + 0x000200f8,0x000005c4,0x000200f9,0x000005c5,0x000200f8,0x000005c5,0x000200f9,0x000005c6, + 0x000200f8,0x000005c6,0x0004003d,0x0000023e,0x000005c7,0x000004ff,0x00050080,0x0000023e, + 0x000005c8,0x000005c7,0x00000276,0x0003003e,0x000004ff,0x000005c8,0x000200f9,0x0000059a, + 0x000200f8,0x000005c9,0x0004003d,0x00000021,0x000005ca,0x000004ec,0x0004003d,0x00000021, + 0x000005cb,0x000004ec,0x0004003d,0x00000021,0x000005cc,0x000004dc,0x0005008e,0x00000021, + 0x000005cd,0x000005cc,0x000001b5,0x00050083,0x00000021,0x000005ce,0x000005cd,0x00000413, + 0x00050085,0x00000021,0x000005cf,0x000005cb,0x000005ce,0x0004003d,0x00000021,0x000005d0, + 0x000004ee,0x00050085,0x00000021,0x000005d1,0x000005cf,0x000005d0,0x00050081,0x00000021, + 0x000005d2,0x000005ca,0x000005d1,0x0003003e,0x000004ee,0x000005d2,0x000200f9,0x0000060b, + 0x000200f8,0x000005d3,0x0004003d,0x00000021,0x000005d4,0x000004ec,0x0004003d,0x00000021, + 0x000005d5,0x000004dc,0x00050083,0x00000021,0x000005d6,0x000005d4,0x000005d5,0x0006000c, + 0x00000021,0x000005d7,0x00000001,0x00000004,0x000005d6,0x0003003e,0x000004ee,0x000005d7, + 0x000200f9,0x0000060b,0x000200f8,0x000005d8,0x0004003d,0x00000021,0x000005d9,0x000004dc, + 0x0004003d,0x00000021,0x000005da,0x000004ec,0x00050081,0x00000021,0x000005db,0x000005d9, + 0x000005da,0x0004003d,0x00000021,0x000005dc,0x000004dc,0x0005008e,0x00000021,0x000005dd, + 0x000005dc,0x000001b5,0x0004003d,0x00000021,0x000005de,0x000004ec,0x00050085,0x00000021, + 0x000005df,0x000005dd,0x000005de,0x00050083,0x00000021,0x000005e0,0x000005db,0x000005df, + 0x0003003e,0x000004ee,0x000005e0,0x000200f9,0x0000060b,0x000200f8,0x000005e1,0x000300f7, + 0x000005eb,0x00000000,0x000400fa,0x00000291,0x000005e2,0x000005eb,0x000200f8,0x000005e2, + 0x0004003d,0x00000021,0x000005e3,0x000004dc,0x0003003e,0x00000500,0x000000ca,0x0004003d, + 0x00000006,0x00000698,0x00000500,0x00050041,0x0000000d,0x00000699,0x00000695,0x00000087, + 0x0003003e,0x00000699,0x00000698,0x0004003d,0x00000006,0x0000069a,0x00000500,0x00050041, + 0x0000000d,0x0000069b,0x00000695,0x0000008a,0x0003003e,0x0000069b,0x0000069a,0x0004003d, + 0x00000006,0x0000069c,0x00000500,0x00050041,0x0000000d,0x0000069d,0x00000695,0x0000009d, + 0x0003003e,0x0000069d,0x0000069c,0x0004003d,0x00000021,0x0000069e,0x00000695,0x0003003e, + 0x00000696,0x0000069e,0x0004003d,0x00000021,0x000005e4,0x00000696,0x0003003e,0x00000501, + 0x000000d0,0x0004003d,0x00000006,0x000006a2,0x00000501,0x00050041,0x0000000d,0x000006a3, + 0x0000069f,0x00000087,0x0003003e,0x000006a3,0x000006a2,0x0004003d,0x00000006,0x000006a4, + 0x00000501,0x00050041,0x0000000d,0x000006a5,0x0000069f,0x0000008a,0x0003003e,0x000006a5, + 0x000006a4,0x0004003d,0x00000006,0x000006a6,0x00000501,0x00050041,0x0000000d,0x000006a7, + 0x0000069f,0x0000009d,0x0003003e,0x000006a7,0x000006a6,0x0004003d,0x00000021,0x000006a8, + 0x0000069f,0x0003003e,0x000006a0,0x000006a8,0x0004003d,0x00000021,0x000005e5,0x000006a0, + 0x0008000c,0x00000021,0x000005e6,0x00000001,0x0000002b,0x000005e3,0x000005e4,0x000005e5, + 0x0003003e,0x000004dc,0x000005e6,0x0004003d,0x00000021,0x000005e7,0x000004dc,0x0003003e, + 0x00000502,0x000005e7,0x0004003d,0x00000021,0x000005e8,0x000004ec,0x0003003e,0x00000503, + 0x000005e8,0x0004003d,0x00000021,0x000005e9,0x000004ec,0x0003003e,0x00000504,0x000005e9, + 0x0004003d,0x00000021,0x000006b4,0x00000503,0x0003003e,0x000006aa,0x000006b4,0x0004003d, + 0x00000021,0x000006cc,0x000006aa,0x0007004f,0x00000017,0x000006cd,0x000006cc,0x000006cc, + 0x00000000,0x00000001,0x0003003e,0x000006c9,0x000006cd,0x00050041,0x0000000d,0x000006d4, + 0x000006c9,0x00000087,0x0004003d,0x00000006,0x000006d5,0x000006d4,0x00050041,0x0000000d, + 0x000006d6,0x000006c9,0x0000008a,0x0004003d,0x00000006,0x000006d7,0x000006d6,0x0007000c, + 0x00000006,0x000006d8,0x00000001,0x00000028,0x000006d5,0x000006d7,0x0003003e,0x000006d2, + 0x000006d8,0x0004003d,0x00000006,0x000006ce,0x000006d2,0x00050041,0x0000000d,0x000006cf, + 0x000006aa,0x0000009d,0x0004003d,0x00000006,0x000006d0,0x000006cf,0x0007000c,0x00000006, + 0x000006d1,0x00000001,0x00000028,0x000006ce,0x000006d0,0x0003003e,0x000006ca,0x000006d1, + 0x0004003d,0x00000006,0x000006b5,0x000006ca,0x0004003d,0x00000021,0x000006b6,0x00000503, + 0x0003003e,0x000006ab,0x000006b6,0x0004003d,0x00000021,0x000006dc,0x000006ab,0x0007004f, + 0x00000017,0x000006dd,0x000006dc,0x000006dc,0x00000000,0x00000001,0x0003003e,0x000006d9, + 0x000006dd,0x00050041,0x0000000d,0x000006e4,0x000006d9,0x00000087,0x0004003d,0x00000006, + 0x000006e5,0x000006e4,0x00050041,0x0000000d,0x000006e6,0x000006d9,0x0000008a,0x0004003d, + 0x00000006,0x000006e7,0x000006e6,0x0007000c,0x00000006,0x000006e8,0x00000001,0x00000025, + 0x000006e5,0x000006e7,0x0003003e,0x000006e2,0x000006e8,0x0004003d,0x00000006,0x000006de, + 0x000006e2,0x00050041,0x0000000d,0x000006df,0x000006ab,0x0000009d,0x0004003d,0x00000006, + 0x000006e0,0x000006df,0x0007000c,0x00000006,0x000006e1,0x00000001,0x00000025,0x000006de, + 0x000006e0,0x0003003e,0x000006da,0x000006e1,0x0004003d,0x00000006,0x000006b7,0x000006da, + 0x00050083,0x00000006,0x000006b8,0x000006b5,0x000006b7,0x0003003e,0x000006a9,0x000006b8, + 0x0004003d,0x00000021,0x000006b9,0x00000502,0x0003003e,0x000006ac,0x000006b9,0x0004003d, + 0x00000021,0x000006ec,0x000006ac,0x0007004f,0x00000017,0x000006ed,0x000006ec,0x000006ec, + 0x00000000,0x00000001,0x0003003e,0x000006e9,0x000006ed,0x00050041,0x0000000d,0x000006f4, + 0x000006e9,0x00000087,0x0004003d,0x00000006,0x000006f5,0x000006f4,0x00050041,0x0000000d, + 0x000006f6,0x000006e9,0x0000008a,0x0004003d,0x00000006,0x000006f7,0x000006f6,0x0007000c, + 0x00000006,0x000006f8,0x00000001,0x00000025,0x000006f5,0x000006f7,0x0003003e,0x000006f2, + 0x000006f8,0x0004003d,0x00000006,0x000006ee,0x000006f2,0x00050041,0x0000000d,0x000006ef, + 0x000006ac,0x0000009d,0x0004003d,0x00000006,0x000006f0,0x000006ef,0x0007000c,0x00000006, + 0x000006f1,0x00000001,0x00000025,0x000006ee,0x000006f0,0x0003003e,0x000006ea,0x000006f1, + 0x0004003d,0x00000006,0x000006ba,0x000006ea,0x0004003d,0x00000021,0x000006bb,0x00000502, + 0x00060050,0x00000021,0x000006bc,0x000006ba,0x000006ba,0x000006ba,0x00050083,0x00000021, + 0x000006bd,0x000006bb,0x000006bc,0x0003003e,0x00000502,0x000006bd,0x0004003d,0x00000021, + 0x000006be,0x00000502,0x0003003e,0x000006ae,0x000006be,0x0004003d,0x00000021,0x000006fc, + 0x000006ae,0x0007004f,0x00000017,0x000006fd,0x000006fc,0x000006fc,0x00000000,0x00000001, + 0x0003003e,0x000006f9,0x000006fd,0x00050041,0x0000000d,0x00000704,0x000006f9,0x00000087, + 0x0004003d,0x00000006,0x00000705,0x00000704,0x00050041,0x0000000d,0x00000706,0x000006f9, + 0x0000008a,0x0004003d,0x00000006,0x00000707,0x00000706,0x0007000c,0x00000006,0x00000708, + 0x00000001,0x00000028,0x00000705,0x00000707,0x0003003e,0x00000702,0x00000708,0x0004003d, + 0x00000006,0x000006fe,0x00000702,0x00050041,0x0000000d,0x000006ff,0x000006ae,0x0000009d, + 0x0004003d,0x00000006,0x00000700,0x000006ff,0x0007000c,0x00000006,0x00000701,0x00000001, + 0x00000028,0x000006fe,0x00000700,0x0003003e,0x000006fa,0x00000701,0x0004003d,0x00000006, + 0x000006bf,0x000006fa,0x0003003e,0x000006ad,0x000006bf,0x0004003d,0x00000006,0x000006c0, + 0x000006a9,0x0004003d,0x00000006,0x000006c1,0x000006ad,0x0007000c,0x00000006,0x000006c2, + 0x00000001,0x00000028,0x0000014f,0x000006c1,0x00050088,0x00000006,0x000006c3,0x000006c0, + 0x000006c2,0x0003003e,0x000006af,0x000006c3,0x0004003d,0x00000021,0x000006c4,0x00000502, + 0x0004003d,0x00000006,0x000006c5,0x000006af,0x0005008e,0x00000021,0x000006c6,0x000006c4, + 0x000006c5,0x0003003e,0x000006b0,0x000006c6,0x0004003d,0x00000021,0x000006c7,0x00000504, + 0x0003003e,0x000006b1,0x000006c7,0x0004003d,0x00000021,0x00000719,0x000006b1,0x0003003e, + 0x0000070a,0x00000719,0x0004003d,0x00000021,0x0000073f,0x0000070a,0x0003003e,0x0000073a, + 0x00000133,0x0003003e,0x0000073b,0x00000134,0x0003003e,0x0000073c,0x00000135,0x0004003d, + 0x00000006,0x00000745,0x0000073a,0x00050041,0x0000000d,0x00000746,0x00000742,0x00000087, + 0x0003003e,0x00000746,0x00000745,0x0004003d,0x00000006,0x00000747,0x0000073b,0x00050041, + 0x0000000d,0x00000748,0x00000742,0x0000008a,0x0003003e,0x00000748,0x00000747,0x0004003d, + 0x00000006,0x00000749,0x0000073c,0x00050041,0x0000000d,0x0000074a,0x00000742,0x0000009d, + 0x0003003e,0x0000074a,0x00000749,0x0004003d,0x00000021,0x0000074b,0x00000742,0x0003003e, + 0x00000743,0x0000074b,0x0004003d,0x00000021,0x00000740,0x00000743,0x00050094,0x00000006, + 0x00000741,0x0000073f,0x00000740,0x0003003e,0x0000073d,0x00000741,0x0004003d,0x00000006, + 0x0000071a,0x0000073d,0x0003003e,0x00000709,0x0000071a,0x0004003d,0x00000021,0x0000071b, + 0x000006b0,0x0004003d,0x00000021,0x0000071c,0x000006b0,0x0003003e,0x0000070c,0x0000071c, + 0x0004003d,0x00000021,0x00000751,0x0000070c,0x0003003e,0x0000074c,0x00000133,0x0003003e, + 0x0000074d,0x00000134,0x0003003e,0x0000074e,0x00000135,0x0004003d,0x00000006,0x00000757, + 0x0000074c,0x00050041,0x0000000d,0x00000758,0x00000754,0x00000087,0x0003003e,0x00000758, + 0x00000757,0x0004003d,0x00000006,0x00000759,0x0000074d,0x00050041,0x0000000d,0x0000075a, + 0x00000754,0x0000008a,0x0003003e,0x0000075a,0x00000759,0x0004003d,0x00000006,0x0000075b, + 0x0000074e,0x00050041,0x0000000d,0x0000075c,0x00000754,0x0000009d,0x0003003e,0x0000075c, + 0x0000075b,0x0004003d,0x00000021,0x0000075d,0x00000754,0x0003003e,0x00000755,0x0000075d, + 0x0004003d,0x00000021,0x00000752,0x00000755,0x00050094,0x00000006,0x00000753,0x00000751, + 0x00000752,0x0003003e,0x0000074f,0x00000753,0x0004003d,0x00000006,0x0000071d,0x0000074f, + 0x00060050,0x00000021,0x0000071e,0x0000071d,0x0000071d,0x0000071d,0x00050083,0x00000021, + 0x0000071f,0x0000071b,0x0000071e,0x0003003e,0x0000070b,0x0000071f,0x0004003d,0x00000006, + 0x00000720,0x00000709,0x00050083,0x00000006,0x00000721,0x000000d0,0x00000720,0x0004003d, + 0x00000006,0x00000722,0x00000709,0x0003003e,0x0000070e,0x00000722,0x0003003e,0x0000070f, + 0x00000721,0x0004003d,0x00000006,0x00000761,0x0000070e,0x00050041,0x0000000d,0x00000762, + 0x0000075e,0x00000087,0x0003003e,0x00000762,0x00000761,0x0004003d,0x00000006,0x00000763, + 0x0000070f,0x00050041,0x0000000d,0x00000764,0x0000075e,0x0000008a,0x0003003e,0x00000764, + 0x00000763,0x0004003d,0x00000017,0x00000765,0x0000075e,0x0003003e,0x0000075f,0x00000765, + 0x0004003d,0x00000017,0x00000723,0x0000075f,0x0003003e,0x00000710,0x0000014f,0x0004003d, + 0x00000006,0x00000769,0x00000710,0x00050041,0x0000000d,0x0000076a,0x00000766,0x00000087, + 0x0003003e,0x0000076a,0x00000769,0x0004003d,0x00000006,0x0000076b,0x00000710,0x00050041, + 0x0000000d,0x0000076c,0x00000766,0x0000008a,0x0003003e,0x0000076c,0x0000076b,0x0004003d, + 0x00000017,0x0000076d,0x00000766,0x0003003e,0x00000767,0x0000076d,0x0004003d,0x00000017, + 0x00000724,0x00000767,0x0004003d,0x00000021,0x00000725,0x0000070b,0x0003003e,0x00000711, + 0x00000725,0x0004003d,0x00000021,0x00000771,0x00000711,0x0007004f,0x00000017,0x00000772, + 0x00000771,0x00000771,0x00000000,0x00000001,0x0003003e,0x0000076e,0x00000772,0x00050041, + 0x0000000d,0x00000779,0x0000076e,0x00000087,0x0004003d,0x00000006,0x0000077a,0x00000779, + 0x00050041,0x0000000d,0x0000077b,0x0000076e,0x0000008a,0x0004003d,0x00000006,0x0000077c, + 0x0000077b,0x0007000c,0x00000006,0x0000077d,0x00000001,0x00000025,0x0000077a,0x0000077c, + 0x0003003e,0x00000777,0x0000077d,0x0004003d,0x00000006,0x00000773,0x00000777,0x00050041, + 0x0000000d,0x00000774,0x00000711,0x0000009d,0x0004003d,0x00000006,0x00000775,0x00000774, + 0x0007000c,0x00000006,0x00000776,0x00000001,0x00000025,0x00000773,0x00000775,0x0003003e, + 0x0000076f,0x00000776,0x0004003d,0x00000006,0x00000726,0x0000076f,0x0004007f,0x00000006, + 0x00000727,0x00000726,0x0004003d,0x00000021,0x00000728,0x0000070b,0x0003003e,0x00000712, + 0x00000728,0x0004003d,0x00000021,0x00000781,0x00000712,0x0007004f,0x00000017,0x00000782, + 0x00000781,0x00000781,0x00000000,0x00000001,0x0003003e,0x0000077e,0x00000782,0x00050041, + 0x0000000d,0x00000789,0x0000077e,0x00000087,0x0004003d,0x00000006,0x0000078a,0x00000789, + 0x00050041,0x0000000d,0x0000078b,0x0000077e,0x0000008a,0x0004003d,0x00000006,0x0000078c, + 0x0000078b,0x0007000c,0x00000006,0x0000078d,0x00000001,0x00000028,0x0000078a,0x0000078c, + 0x0003003e,0x00000787,0x0000078d,0x0004003d,0x00000006,0x00000783,0x00000787,0x00050041, + 0x0000000d,0x00000784,0x00000712,0x0000009d,0x0004003d,0x00000006,0x00000785,0x00000784, + 0x0007000c,0x00000006,0x00000786,0x00000001,0x00000028,0x00000783,0x00000785,0x0003003e, + 0x0000077f,0x00000786,0x0004003d,0x00000006,0x00000729,0x0000077f,0x0003003e,0x00000713, + 0x00000727,0x0003003e,0x00000714,0x00000729,0x0004003d,0x00000006,0x00000791,0x00000713, + 0x00050041,0x0000000d,0x00000792,0x0000078e,0x00000087,0x0003003e,0x00000792,0x00000791, + 0x0004003d,0x00000006,0x00000793,0x00000714,0x00050041,0x0000000d,0x00000794,0x0000078e, + 0x0000008a,0x0003003e,0x00000794,0x00000793,0x0004003d,0x00000017,0x00000795,0x0000078e, + 0x0003003e,0x0000078f,0x00000795,0x0004003d,0x00000017,0x0000072a,0x0000078f,0x0007000c, + 0x00000017,0x0000072b,0x00000001,0x00000028,0x00000724,0x0000072a,0x00050088,0x00000017, + 0x0000072c,0x00000723,0x0000072b,0x0003003e,0x0000070d,0x0000072c,0x0003003e,0x00000716, + 0x000000d0,0x0004003d,0x00000006,0x00000798,0x00000716,0x0003003e,0x00000796,0x00000798, + 0x0004003d,0x00000006,0x0000072d,0x00000796,0x00050041,0x0000000d,0x0000072e,0x0000070d, + 0x00000087,0x0004003d,0x00000006,0x0000072f,0x0000072e,0x00050041,0x0000000d,0x00000730, + 0x0000070d,0x0000008a,0x0004003d,0x00000006,0x00000731,0x00000730,0x0007000c,0x00000006, + 0x00000732,0x00000001,0x00000025,0x0000072f,0x00000731,0x0007000c,0x00000006,0x00000733, + 0x00000001,0x00000025,0x0000072d,0x00000732,0x0003003e,0x00000715,0x00000733,0x0004003d, + 0x00000021,0x00000734,0x0000070b,0x0004003d,0x00000006,0x00000735,0x00000715,0x0005008e, + 0x00000021,0x00000736,0x00000734,0x00000735,0x0004003d,0x00000006,0x00000737,0x00000709, + 0x00060050,0x00000021,0x00000738,0x00000737,0x00000737,0x00000737,0x00050081,0x00000021, + 0x00000739,0x00000736,0x00000738,0x0003003e,0x00000717,0x00000739,0x0004003d,0x00000021, + 0x000006c8,0x00000717,0x0003003e,0x000006b2,0x000006c8,0x0004003d,0x00000021,0x000005ea, + 0x000006b2,0x0003003e,0x000004ee,0x000005ea,0x000200f9,0x000005eb,0x000200f8,0x000005eb, + 0x000200f9,0x0000060b,0x000200f8,0x000005ec,0x000300f7,0x000005f6,0x00000000,0x000400fa, + 0x00000291,0x000005ed,0x000005f6,0x000200f8,0x000005ed,0x0004003d,0x00000021,0x000005ee, + 0x000004dc,0x0003003e,0x00000505,0x000000ca,0x0004003d,0x00000006,0x0000079c,0x00000505, + 0x00050041,0x0000000d,0x0000079d,0x00000799,0x00000087,0x0003003e,0x0000079d,0x0000079c, + 0x0004003d,0x00000006,0x0000079e,0x00000505,0x00050041,0x0000000d,0x0000079f,0x00000799, + 0x0000008a,0x0003003e,0x0000079f,0x0000079e,0x0004003d,0x00000006,0x000007a0,0x00000505, + 0x00050041,0x0000000d,0x000007a1,0x00000799,0x0000009d,0x0003003e,0x000007a1,0x000007a0, + 0x0004003d,0x00000021,0x000007a2,0x00000799,0x0003003e,0x0000079a,0x000007a2,0x0004003d, + 0x00000021,0x000005ef,0x0000079a,0x0003003e,0x00000506,0x000000d0,0x0004003d,0x00000006, + 0x000007a6,0x00000506,0x00050041,0x0000000d,0x000007a7,0x000007a3,0x00000087,0x0003003e, + 0x000007a7,0x000007a6,0x0004003d,0x00000006,0x000007a8,0x00000506,0x00050041,0x0000000d, + 0x000007a9,0x000007a3,0x0000008a,0x0003003e,0x000007a9,0x000007a8,0x0004003d,0x00000006, + 0x000007aa,0x00000506,0x00050041,0x0000000d,0x000007ab,0x000007a3,0x0000009d,0x0003003e, + 0x000007ab,0x000007aa,0x0004003d,0x00000021,0x000007ac,0x000007a3,0x0003003e,0x000007a4, + 0x000007ac,0x0004003d,0x00000021,0x000005f0,0x000007a4,0x0008000c,0x00000021,0x000005f1, + 0x00000001,0x0000002b,0x000005ee,0x000005ef,0x000005f0,0x0003003e,0x000004dc,0x000005f1, + 0x0004003d,0x00000021,0x000005f2,0x000004ec,0x0003003e,0x00000507,0x000005f2,0x0004003d, + 0x00000021,0x000005f3,0x000004dc,0x0003003e,0x00000508,0x000005f3,0x0004003d,0x00000021, + 0x000005f4,0x000004ec,0x0003003e,0x00000509,0x000005f4,0x0004003d,0x00000021,0x000007b8, + 0x00000508,0x0003003e,0x000007ae,0x000007b8,0x0004003d,0x00000021,0x000007d0,0x000007ae, + 0x0007004f,0x00000017,0x000007d1,0x000007d0,0x000007d0,0x00000000,0x00000001,0x0003003e, + 0x000007cd,0x000007d1,0x00050041,0x0000000d,0x000007d8,0x000007cd,0x00000087,0x0004003d, + 0x00000006,0x000007d9,0x000007d8,0x00050041,0x0000000d,0x000007da,0x000007cd,0x0000008a, + 0x0004003d,0x00000006,0x000007db,0x000007da,0x0007000c,0x00000006,0x000007dc,0x00000001, + 0x00000028,0x000007d9,0x000007db,0x0003003e,0x000007d6,0x000007dc,0x0004003d,0x00000006, + 0x000007d2,0x000007d6,0x00050041,0x0000000d,0x000007d3,0x000007ae,0x0000009d,0x0004003d, + 0x00000006,0x000007d4,0x000007d3,0x0007000c,0x00000006,0x000007d5,0x00000001,0x00000028, + 0x000007d2,0x000007d4,0x0003003e,0x000007ce,0x000007d5,0x0004003d,0x00000006,0x000007b9, + 0x000007ce,0x0004003d,0x00000021,0x000007ba,0x00000508,0x0003003e,0x000007af,0x000007ba, + 0x0004003d,0x00000021,0x000007e0,0x000007af,0x0007004f,0x00000017,0x000007e1,0x000007e0, + 0x000007e0,0x00000000,0x00000001,0x0003003e,0x000007dd,0x000007e1,0x00050041,0x0000000d, + 0x000007e8,0x000007dd,0x00000087,0x0004003d,0x00000006,0x000007e9,0x000007e8,0x00050041, + 0x0000000d,0x000007ea,0x000007dd,0x0000008a,0x0004003d,0x00000006,0x000007eb,0x000007ea, + 0x0007000c,0x00000006,0x000007ec,0x00000001,0x00000025,0x000007e9,0x000007eb,0x0003003e, + 0x000007e6,0x000007ec,0x0004003d,0x00000006,0x000007e2,0x000007e6,0x00050041,0x0000000d, + 0x000007e3,0x000007af,0x0000009d,0x0004003d,0x00000006,0x000007e4,0x000007e3,0x0007000c, + 0x00000006,0x000007e5,0x00000001,0x00000025,0x000007e2,0x000007e4,0x0003003e,0x000007de, + 0x000007e5,0x0004003d,0x00000006,0x000007bb,0x000007de,0x00050083,0x00000006,0x000007bc, + 0x000007b9,0x000007bb,0x0003003e,0x000007ad,0x000007bc,0x0004003d,0x00000021,0x000007bd, + 0x00000507,0x0003003e,0x000007b0,0x000007bd,0x0004003d,0x00000021,0x000007f0,0x000007b0, + 0x0007004f,0x00000017,0x000007f1,0x000007f0,0x000007f0,0x00000000,0x00000001,0x0003003e, + 0x000007ed,0x000007f1,0x00050041,0x0000000d,0x000007f8,0x000007ed,0x00000087,0x0004003d, + 0x00000006,0x000007f9,0x000007f8,0x00050041,0x0000000d,0x000007fa,0x000007ed,0x0000008a, + 0x0004003d,0x00000006,0x000007fb,0x000007fa,0x0007000c,0x00000006,0x000007fc,0x00000001, + 0x00000025,0x000007f9,0x000007fb,0x0003003e,0x000007f6,0x000007fc,0x0004003d,0x00000006, + 0x000007f2,0x000007f6,0x00050041,0x0000000d,0x000007f3,0x000007b0,0x0000009d,0x0004003d, + 0x00000006,0x000007f4,0x000007f3,0x0007000c,0x00000006,0x000007f5,0x00000001,0x00000025, + 0x000007f2,0x000007f4,0x0003003e,0x000007ee,0x000007f5,0x0004003d,0x00000006,0x000007be, + 0x000007ee,0x0004003d,0x00000021,0x000007bf,0x00000507,0x00060050,0x00000021,0x000007c0, + 0x000007be,0x000007be,0x000007be,0x00050083,0x00000021,0x000007c1,0x000007bf,0x000007c0, + 0x0003003e,0x00000507,0x000007c1,0x0004003d,0x00000021,0x000007c2,0x00000507,0x0003003e, + 0x000007b2,0x000007c2,0x0004003d,0x00000021,0x00000800,0x000007b2,0x0007004f,0x00000017, + 0x00000801,0x00000800,0x00000800,0x00000000,0x00000001,0x0003003e,0x000007fd,0x00000801, + 0x00050041,0x0000000d,0x00000808,0x000007fd,0x00000087,0x0004003d,0x00000006,0x00000809, + 0x00000808,0x00050041,0x0000000d,0x0000080a,0x000007fd,0x0000008a,0x0004003d,0x00000006, + 0x0000080b,0x0000080a,0x0007000c,0x00000006,0x0000080c,0x00000001,0x00000028,0x00000809, + 0x0000080b,0x0003003e,0x00000806,0x0000080c,0x0004003d,0x00000006,0x00000802,0x00000806, + 0x00050041,0x0000000d,0x00000803,0x000007b2,0x0000009d,0x0004003d,0x00000006,0x00000804, + 0x00000803,0x0007000c,0x00000006,0x00000805,0x00000001,0x00000028,0x00000802,0x00000804, + 0x0003003e,0x000007fe,0x00000805,0x0004003d,0x00000006,0x000007c3,0x000007fe,0x0003003e, + 0x000007b1,0x000007c3,0x0004003d,0x00000006,0x000007c4,0x000007ad,0x0004003d,0x00000006, + 0x000007c5,0x000007b1,0x0007000c,0x00000006,0x000007c6,0x00000001,0x00000028,0x0000014f, + 0x000007c5,0x00050088,0x00000006,0x000007c7,0x000007c4,0x000007c6,0x0003003e,0x000007b3, + 0x000007c7,0x0004003d,0x00000021,0x000007c8,0x00000507,0x0004003d,0x00000006,0x000007c9, + 0x000007b3,0x0005008e,0x00000021,0x000007ca,0x000007c8,0x000007c9,0x0003003e,0x000007b4, + 0x000007ca,0x0004003d,0x00000021,0x000007cb,0x00000509,0x0003003e,0x000007b5,0x000007cb, + 0x0004003d,0x00000021,0x0000081d,0x000007b5,0x0003003e,0x0000080e,0x0000081d,0x0004003d, + 0x00000021,0x00000843,0x0000080e,0x0003003e,0x0000083e,0x00000133,0x0003003e,0x0000083f, + 0x00000134,0x0003003e,0x00000840,0x00000135,0x0004003d,0x00000006,0x00000849,0x0000083e, + 0x00050041,0x0000000d,0x0000084a,0x00000846,0x00000087,0x0003003e,0x0000084a,0x00000849, + 0x0004003d,0x00000006,0x0000084b,0x0000083f,0x00050041,0x0000000d,0x0000084c,0x00000846, + 0x0000008a,0x0003003e,0x0000084c,0x0000084b,0x0004003d,0x00000006,0x0000084d,0x00000840, + 0x00050041,0x0000000d,0x0000084e,0x00000846,0x0000009d,0x0003003e,0x0000084e,0x0000084d, + 0x0004003d,0x00000021,0x0000084f,0x00000846,0x0003003e,0x00000847,0x0000084f,0x0004003d, + 0x00000021,0x00000844,0x00000847,0x00050094,0x00000006,0x00000845,0x00000843,0x00000844, + 0x0003003e,0x00000841,0x00000845,0x0004003d,0x00000006,0x0000081e,0x00000841,0x0003003e, + 0x0000080d,0x0000081e,0x0004003d,0x00000021,0x0000081f,0x000007b4,0x0004003d,0x00000021, + 0x00000820,0x000007b4,0x0003003e,0x00000810,0x00000820,0x0004003d,0x00000021,0x00000855, + 0x00000810,0x0003003e,0x00000850,0x00000133,0x0003003e,0x00000851,0x00000134,0x0003003e, + 0x00000852,0x00000135,0x0004003d,0x00000006,0x0000085b,0x00000850,0x00050041,0x0000000d, + 0x0000085c,0x00000858,0x00000087,0x0003003e,0x0000085c,0x0000085b,0x0004003d,0x00000006, + 0x0000085d,0x00000851,0x00050041,0x0000000d,0x0000085e,0x00000858,0x0000008a,0x0003003e, + 0x0000085e,0x0000085d,0x0004003d,0x00000006,0x0000085f,0x00000852,0x00050041,0x0000000d, + 0x00000860,0x00000858,0x0000009d,0x0003003e,0x00000860,0x0000085f,0x0004003d,0x00000021, + 0x00000861,0x00000858,0x0003003e,0x00000859,0x00000861,0x0004003d,0x00000021,0x00000856, + 0x00000859,0x00050094,0x00000006,0x00000857,0x00000855,0x00000856,0x0003003e,0x00000853, + 0x00000857,0x0004003d,0x00000006,0x00000821,0x00000853,0x00060050,0x00000021,0x00000822, + 0x00000821,0x00000821,0x00000821,0x00050083,0x00000021,0x00000823,0x0000081f,0x00000822, + 0x0003003e,0x0000080f,0x00000823,0x0004003d,0x00000006,0x00000824,0x0000080d,0x00050083, + 0x00000006,0x00000825,0x000000d0,0x00000824,0x0004003d,0x00000006,0x00000826,0x0000080d, + 0x0003003e,0x00000812,0x00000826,0x0003003e,0x00000813,0x00000825,0x0004003d,0x00000006, + 0x00000865,0x00000812,0x00050041,0x0000000d,0x00000866,0x00000862,0x00000087,0x0003003e, + 0x00000866,0x00000865,0x0004003d,0x00000006,0x00000867,0x00000813,0x00050041,0x0000000d, + 0x00000868,0x00000862,0x0000008a,0x0003003e,0x00000868,0x00000867,0x0004003d,0x00000017, + 0x00000869,0x00000862,0x0003003e,0x00000863,0x00000869,0x0004003d,0x00000017,0x00000827, + 0x00000863,0x0003003e,0x00000814,0x0000014f,0x0004003d,0x00000006,0x0000086d,0x00000814, + 0x00050041,0x0000000d,0x0000086e,0x0000086a,0x00000087,0x0003003e,0x0000086e,0x0000086d, + 0x0004003d,0x00000006,0x0000086f,0x00000814,0x00050041,0x0000000d,0x00000870,0x0000086a, + 0x0000008a,0x0003003e,0x00000870,0x0000086f,0x0004003d,0x00000017,0x00000871,0x0000086a, + 0x0003003e,0x0000086b,0x00000871,0x0004003d,0x00000017,0x00000828,0x0000086b,0x0004003d, + 0x00000021,0x00000829,0x0000080f,0x0003003e,0x00000815,0x00000829,0x0004003d,0x00000021, + 0x00000875,0x00000815,0x0007004f,0x00000017,0x00000876,0x00000875,0x00000875,0x00000000, + 0x00000001,0x0003003e,0x00000872,0x00000876,0x00050041,0x0000000d,0x0000087d,0x00000872, + 0x00000087,0x0004003d,0x00000006,0x0000087e,0x0000087d,0x00050041,0x0000000d,0x0000087f, + 0x00000872,0x0000008a,0x0004003d,0x00000006,0x00000880,0x0000087f,0x0007000c,0x00000006, + 0x00000881,0x00000001,0x00000025,0x0000087e,0x00000880,0x0003003e,0x0000087b,0x00000881, + 0x0004003d,0x00000006,0x00000877,0x0000087b,0x00050041,0x0000000d,0x00000878,0x00000815, + 0x0000009d,0x0004003d,0x00000006,0x00000879,0x00000878,0x0007000c,0x00000006,0x0000087a, + 0x00000001,0x00000025,0x00000877,0x00000879,0x0003003e,0x00000873,0x0000087a,0x0004003d, + 0x00000006,0x0000082a,0x00000873,0x0004007f,0x00000006,0x0000082b,0x0000082a,0x0004003d, + 0x00000021,0x0000082c,0x0000080f,0x0003003e,0x00000816,0x0000082c,0x0004003d,0x00000021, + 0x00000885,0x00000816,0x0007004f,0x00000017,0x00000886,0x00000885,0x00000885,0x00000000, + 0x00000001,0x0003003e,0x00000882,0x00000886,0x00050041,0x0000000d,0x0000088d,0x00000882, + 0x00000087,0x0004003d,0x00000006,0x0000088e,0x0000088d,0x00050041,0x0000000d,0x0000088f, + 0x00000882,0x0000008a,0x0004003d,0x00000006,0x00000890,0x0000088f,0x0007000c,0x00000006, + 0x00000891,0x00000001,0x00000028,0x0000088e,0x00000890,0x0003003e,0x0000088b,0x00000891, + 0x0004003d,0x00000006,0x00000887,0x0000088b,0x00050041,0x0000000d,0x00000888,0x00000816, + 0x0000009d,0x0004003d,0x00000006,0x00000889,0x00000888,0x0007000c,0x00000006,0x0000088a, + 0x00000001,0x00000028,0x00000887,0x00000889,0x0003003e,0x00000883,0x0000088a,0x0004003d, + 0x00000006,0x0000082d,0x00000883,0x0003003e,0x00000817,0x0000082b,0x0003003e,0x00000818, + 0x0000082d,0x0004003d,0x00000006,0x00000895,0x00000817,0x00050041,0x0000000d,0x00000896, + 0x00000892,0x00000087,0x0003003e,0x00000896,0x00000895,0x0004003d,0x00000006,0x00000897, + 0x00000818,0x00050041,0x0000000d,0x00000898,0x00000892,0x0000008a,0x0003003e,0x00000898, + 0x00000897,0x0004003d,0x00000017,0x00000899,0x00000892,0x0003003e,0x00000893,0x00000899, + 0x0004003d,0x00000017,0x0000082e,0x00000893,0x0007000c,0x00000017,0x0000082f,0x00000001, + 0x00000028,0x00000828,0x0000082e,0x00050088,0x00000017,0x00000830,0x00000827,0x0000082f, + 0x0003003e,0x00000811,0x00000830,0x0003003e,0x0000081a,0x000000d0,0x0004003d,0x00000006, + 0x0000089c,0x0000081a,0x0003003e,0x0000089a,0x0000089c,0x0004003d,0x00000006,0x00000831, + 0x0000089a,0x00050041,0x0000000d,0x00000832,0x00000811,0x00000087,0x0004003d,0x00000006, + 0x00000833,0x00000832,0x00050041,0x0000000d,0x00000834,0x00000811,0x0000008a,0x0004003d, + 0x00000006,0x00000835,0x00000834,0x0007000c,0x00000006,0x00000836,0x00000001,0x00000025, + 0x00000833,0x00000835,0x0007000c,0x00000006,0x00000837,0x00000001,0x00000025,0x00000831, + 0x00000836,0x0003003e,0x00000819,0x00000837,0x0004003d,0x00000021,0x00000838,0x0000080f, + 0x0004003d,0x00000006,0x00000839,0x00000819,0x0005008e,0x00000021,0x0000083a,0x00000838, + 0x00000839,0x0004003d,0x00000006,0x0000083b,0x0000080d,0x00060050,0x00000021,0x0000083c, + 0x0000083b,0x0000083b,0x0000083b,0x00050081,0x00000021,0x0000083d,0x0000083a,0x0000083c, + 0x0003003e,0x0000081b,0x0000083d,0x0004003d,0x00000021,0x000007cc,0x0000081b,0x0003003e, + 0x000007b6,0x000007cc,0x0004003d,0x00000021,0x000005f5,0x000007b6,0x0003003e,0x000004ee, + 0x000005f5,0x000200f9,0x000005f6,0x000200f8,0x000005f6,0x000200f9,0x0000060b,0x000200f8, + 0x000005f7,0x000300f7,0x00000600,0x00000000,0x000400fa,0x00000291,0x000005f8,0x00000600, + 0x000200f8,0x000005f8,0x0004003d,0x00000021,0x000005f9,0x000004dc,0x0003003e,0x0000050a, + 0x000000ca,0x0004003d,0x00000006,0x000008a0,0x0000050a,0x00050041,0x0000000d,0x000008a1, + 0x0000089d,0x00000087,0x0003003e,0x000008a1,0x000008a0,0x0004003d,0x00000006,0x000008a2, + 0x0000050a,0x00050041,0x0000000d,0x000008a3,0x0000089d,0x0000008a,0x0003003e,0x000008a3, + 0x000008a2,0x0004003d,0x00000006,0x000008a4,0x0000050a,0x00050041,0x0000000d,0x000008a5, + 0x0000089d,0x0000009d,0x0003003e,0x000008a5,0x000008a4,0x0004003d,0x00000021,0x000008a6, + 0x0000089d,0x0003003e,0x0000089e,0x000008a6,0x0004003d,0x00000021,0x000005fa,0x0000089e, + 0x0003003e,0x0000050b,0x000000d0,0x0004003d,0x00000006,0x000008aa,0x0000050b,0x00050041, + 0x0000000d,0x000008ab,0x000008a7,0x00000087,0x0003003e,0x000008ab,0x000008aa,0x0004003d, + 0x00000006,0x000008ac,0x0000050b,0x00050041,0x0000000d,0x000008ad,0x000008a7,0x0000008a, + 0x0003003e,0x000008ad,0x000008ac,0x0004003d,0x00000006,0x000008ae,0x0000050b,0x00050041, + 0x0000000d,0x000008af,0x000008a7,0x0000009d,0x0003003e,0x000008af,0x000008ae,0x0004003d, + 0x00000021,0x000008b0,0x000008a7,0x0003003e,0x000008a8,0x000008b0,0x0004003d,0x00000021, + 0x000005fb,0x000008a8,0x0008000c,0x00000021,0x000005fc,0x00000001,0x0000002b,0x000005f9, + 0x000005fa,0x000005fb,0x0003003e,0x000004dc,0x000005fc,0x0004003d,0x00000021,0x000005fd, + 0x000004dc,0x0003003e,0x0000050c,0x000005fd,0x0004003d,0x00000021,0x000005fe,0x000004ec, + 0x0003003e,0x0000050d,0x000005fe,0x0004003d,0x00000021,0x000008c1,0x0000050d,0x0003003e, + 0x000008b2,0x000008c1,0x0004003d,0x00000021,0x000008e7,0x000008b2,0x0003003e,0x000008e2, + 0x00000133,0x0003003e,0x000008e3,0x00000134,0x0003003e,0x000008e4,0x00000135,0x0004003d, + 0x00000006,0x000008ed,0x000008e2,0x00050041,0x0000000d,0x000008ee,0x000008ea,0x00000087, + 0x0003003e,0x000008ee,0x000008ed,0x0004003d,0x00000006,0x000008ef,0x000008e3,0x00050041, + 0x0000000d,0x000008f0,0x000008ea,0x0000008a,0x0003003e,0x000008f0,0x000008ef,0x0004003d, + 0x00000006,0x000008f1,0x000008e4,0x00050041,0x0000000d,0x000008f2,0x000008ea,0x0000009d, + 0x0003003e,0x000008f2,0x000008f1,0x0004003d,0x00000021,0x000008f3,0x000008ea,0x0003003e, + 0x000008eb,0x000008f3,0x0004003d,0x00000021,0x000008e8,0x000008eb,0x00050094,0x00000006, + 0x000008e9,0x000008e7,0x000008e8,0x0003003e,0x000008e5,0x000008e9,0x0004003d,0x00000006, + 0x000008c2,0x000008e5,0x0003003e,0x000008b1,0x000008c2,0x0004003d,0x00000021,0x000008c3, + 0x0000050c,0x0004003d,0x00000021,0x000008c4,0x0000050c,0x0003003e,0x000008b4,0x000008c4, + 0x0004003d,0x00000021,0x000008f9,0x000008b4,0x0003003e,0x000008f4,0x00000133,0x0003003e, + 0x000008f5,0x00000134,0x0003003e,0x000008f6,0x00000135,0x0004003d,0x00000006,0x000008ff, + 0x000008f4,0x00050041,0x0000000d,0x00000900,0x000008fc,0x00000087,0x0003003e,0x00000900, + 0x000008ff,0x0004003d,0x00000006,0x00000901,0x000008f5,0x00050041,0x0000000d,0x00000902, + 0x000008fc,0x0000008a,0x0003003e,0x00000902,0x00000901,0x0004003d,0x00000006,0x00000903, + 0x000008f6,0x00050041,0x0000000d,0x00000904,0x000008fc,0x0000009d,0x0003003e,0x00000904, + 0x00000903,0x0004003d,0x00000021,0x00000905,0x000008fc,0x0003003e,0x000008fd,0x00000905, + 0x0004003d,0x00000021,0x000008fa,0x000008fd,0x00050094,0x00000006,0x000008fb,0x000008f9, + 0x000008fa,0x0003003e,0x000008f7,0x000008fb,0x0004003d,0x00000006,0x000008c5,0x000008f7, + 0x00060050,0x00000021,0x000008c6,0x000008c5,0x000008c5,0x000008c5,0x00050083,0x00000021, + 0x000008c7,0x000008c3,0x000008c6,0x0003003e,0x000008b3,0x000008c7,0x0004003d,0x00000006, + 0x000008c8,0x000008b1,0x00050083,0x00000006,0x000008c9,0x000000d0,0x000008c8,0x0004003d, + 0x00000006,0x000008ca,0x000008b1,0x0003003e,0x000008b6,0x000008ca,0x0003003e,0x000008b7, + 0x000008c9,0x0004003d,0x00000006,0x00000909,0x000008b6,0x00050041,0x0000000d,0x0000090a, + 0x00000906,0x00000087,0x0003003e,0x0000090a,0x00000909,0x0004003d,0x00000006,0x0000090b, + 0x000008b7,0x00050041,0x0000000d,0x0000090c,0x00000906,0x0000008a,0x0003003e,0x0000090c, + 0x0000090b,0x0004003d,0x00000017,0x0000090d,0x00000906,0x0003003e,0x00000907,0x0000090d, + 0x0004003d,0x00000017,0x000008cb,0x00000907,0x0003003e,0x000008b8,0x0000014f,0x0004003d, + 0x00000006,0x00000911,0x000008b8,0x00050041,0x0000000d,0x00000912,0x0000090e,0x00000087, + 0x0003003e,0x00000912,0x00000911,0x0004003d,0x00000006,0x00000913,0x000008b8,0x00050041, + 0x0000000d,0x00000914,0x0000090e,0x0000008a,0x0003003e,0x00000914,0x00000913,0x0004003d, + 0x00000017,0x00000915,0x0000090e,0x0003003e,0x0000090f,0x00000915,0x0004003d,0x00000017, + 0x000008cc,0x0000090f,0x0004003d,0x00000021,0x000008cd,0x000008b3,0x0003003e,0x000008b9, + 0x000008cd,0x0004003d,0x00000021,0x00000919,0x000008b9,0x0007004f,0x00000017,0x0000091a, + 0x00000919,0x00000919,0x00000000,0x00000001,0x0003003e,0x00000916,0x0000091a,0x00050041, + 0x0000000d,0x00000921,0x00000916,0x00000087,0x0004003d,0x00000006,0x00000922,0x00000921, + 0x00050041,0x0000000d,0x00000923,0x00000916,0x0000008a,0x0004003d,0x00000006,0x00000924, + 0x00000923,0x0007000c,0x00000006,0x00000925,0x00000001,0x00000025,0x00000922,0x00000924, + 0x0003003e,0x0000091f,0x00000925,0x0004003d,0x00000006,0x0000091b,0x0000091f,0x00050041, + 0x0000000d,0x0000091c,0x000008b9,0x0000009d,0x0004003d,0x00000006,0x0000091d,0x0000091c, + 0x0007000c,0x00000006,0x0000091e,0x00000001,0x00000025,0x0000091b,0x0000091d,0x0003003e, + 0x00000917,0x0000091e,0x0004003d,0x00000006,0x000008ce,0x00000917,0x0004007f,0x00000006, + 0x000008cf,0x000008ce,0x0004003d,0x00000021,0x000008d0,0x000008b3,0x0003003e,0x000008ba, + 0x000008d0,0x0004003d,0x00000021,0x00000929,0x000008ba,0x0007004f,0x00000017,0x0000092a, + 0x00000929,0x00000929,0x00000000,0x00000001,0x0003003e,0x00000926,0x0000092a,0x00050041, + 0x0000000d,0x00000931,0x00000926,0x00000087,0x0004003d,0x00000006,0x00000932,0x00000931, + 0x00050041,0x0000000d,0x00000933,0x00000926,0x0000008a,0x0004003d,0x00000006,0x00000934, + 0x00000933,0x0007000c,0x00000006,0x00000935,0x00000001,0x00000028,0x00000932,0x00000934, + 0x0003003e,0x0000092f,0x00000935,0x0004003d,0x00000006,0x0000092b,0x0000092f,0x00050041, + 0x0000000d,0x0000092c,0x000008ba,0x0000009d,0x0004003d,0x00000006,0x0000092d,0x0000092c, + 0x0007000c,0x00000006,0x0000092e,0x00000001,0x00000028,0x0000092b,0x0000092d,0x0003003e, + 0x00000927,0x0000092e,0x0004003d,0x00000006,0x000008d1,0x00000927,0x0003003e,0x000008bb, + 0x000008cf,0x0003003e,0x000008bc,0x000008d1,0x0004003d,0x00000006,0x00000939,0x000008bb, + 0x00050041,0x0000000d,0x0000093a,0x00000936,0x00000087,0x0003003e,0x0000093a,0x00000939, + 0x0004003d,0x00000006,0x0000093b,0x000008bc,0x00050041,0x0000000d,0x0000093c,0x00000936, + 0x0000008a,0x0003003e,0x0000093c,0x0000093b,0x0004003d,0x00000017,0x0000093d,0x00000936, + 0x0003003e,0x00000937,0x0000093d,0x0004003d,0x00000017,0x000008d2,0x00000937,0x0007000c, + 0x00000017,0x000008d3,0x00000001,0x00000028,0x000008cc,0x000008d2,0x00050088,0x00000017, + 0x000008d4,0x000008cb,0x000008d3,0x0003003e,0x000008b5,0x000008d4,0x0003003e,0x000008be, + 0x000000d0,0x0004003d,0x00000006,0x00000940,0x000008be,0x0003003e,0x0000093e,0x00000940, + 0x0004003d,0x00000006,0x000008d5,0x0000093e,0x00050041,0x0000000d,0x000008d6,0x000008b5, + 0x00000087,0x0004003d,0x00000006,0x000008d7,0x000008d6,0x00050041,0x0000000d,0x000008d8, + 0x000008b5,0x0000008a,0x0004003d,0x00000006,0x000008d9,0x000008d8,0x0007000c,0x00000006, + 0x000008da,0x00000001,0x00000025,0x000008d7,0x000008d9,0x0007000c,0x00000006,0x000008db, + 0x00000001,0x00000025,0x000008d5,0x000008da,0x0003003e,0x000008bd,0x000008db,0x0004003d, + 0x00000021,0x000008dc,0x000008b3,0x0004003d,0x00000006,0x000008dd,0x000008bd,0x0005008e, + 0x00000021,0x000008de,0x000008dc,0x000008dd,0x0004003d,0x00000006,0x000008df,0x000008b1, + 0x00060050,0x00000021,0x000008e0,0x000008df,0x000008df,0x000008df,0x00050081,0x00000021, + 0x000008e1,0x000008de,0x000008e0,0x0003003e,0x000008bf,0x000008e1,0x0004003d,0x00000021, + 0x000005ff,0x000008bf,0x0003003e,0x000004ee,0x000005ff,0x000200f9,0x00000600,0x000200f8, + 0x00000600,0x000200f9,0x0000060b,0x000200f8,0x00000601,0x000300f7,0x0000060a,0x00000000, + 0x000400fa,0x00000291,0x00000602,0x0000060a,0x000200f8,0x00000602,0x0004003d,0x00000021, + 0x00000603,0x000004dc,0x0003003e,0x0000050e,0x000000ca,0x0004003d,0x00000006,0x00000944, + 0x0000050e,0x00050041,0x0000000d,0x00000945,0x00000941,0x00000087,0x0003003e,0x00000945, + 0x00000944,0x0004003d,0x00000006,0x00000946,0x0000050e,0x00050041,0x0000000d,0x00000947, + 0x00000941,0x0000008a,0x0003003e,0x00000947,0x00000946,0x0004003d,0x00000006,0x00000948, + 0x0000050e,0x00050041,0x0000000d,0x00000949,0x00000941,0x0000009d,0x0003003e,0x00000949, + 0x00000948,0x0004003d,0x00000021,0x0000094a,0x00000941,0x0003003e,0x00000942,0x0000094a, + 0x0004003d,0x00000021,0x00000604,0x00000942,0x0003003e,0x0000050f,0x000000d0,0x0004003d, + 0x00000006,0x0000094e,0x0000050f,0x00050041,0x0000000d,0x0000094f,0x0000094b,0x00000087, + 0x0003003e,0x0000094f,0x0000094e,0x0004003d,0x00000006,0x00000950,0x0000050f,0x00050041, + 0x0000000d,0x00000951,0x0000094b,0x0000008a,0x0003003e,0x00000951,0x00000950,0x0004003d, + 0x00000006,0x00000952,0x0000050f,0x00050041,0x0000000d,0x00000953,0x0000094b,0x0000009d, + 0x0003003e,0x00000953,0x00000952,0x0004003d,0x00000021,0x00000954,0x0000094b,0x0003003e, + 0x0000094c,0x00000954,0x0004003d,0x00000021,0x00000605,0x0000094c,0x0008000c,0x00000021, + 0x00000606,0x00000001,0x0000002b,0x00000603,0x00000604,0x00000605,0x0003003e,0x000004dc, + 0x00000606,0x0004003d,0x00000021,0x00000607,0x000004ec,0x0003003e,0x00000510,0x00000607, + 0x0004003d,0x00000021,0x00000608,0x000004dc,0x0003003e,0x00000511,0x00000608,0x0004003d, + 0x00000021,0x00000965,0x00000511,0x0003003e,0x00000956,0x00000965,0x0004003d,0x00000021, + 0x0000098b,0x00000956,0x0003003e,0x00000986,0x00000133,0x0003003e,0x00000987,0x00000134, + 0x0003003e,0x00000988,0x00000135,0x0004003d,0x00000006,0x00000991,0x00000986,0x00050041, + 0x0000000d,0x00000992,0x0000098e,0x00000087,0x0003003e,0x00000992,0x00000991,0x0004003d, + 0x00000006,0x00000993,0x00000987,0x00050041,0x0000000d,0x00000994,0x0000098e,0x0000008a, + 0x0003003e,0x00000994,0x00000993,0x0004003d,0x00000006,0x00000995,0x00000988,0x00050041, + 0x0000000d,0x00000996,0x0000098e,0x0000009d,0x0003003e,0x00000996,0x00000995,0x0004003d, + 0x00000021,0x00000997,0x0000098e,0x0003003e,0x0000098f,0x00000997,0x0004003d,0x00000021, + 0x0000098c,0x0000098f,0x00050094,0x00000006,0x0000098d,0x0000098b,0x0000098c,0x0003003e, + 0x00000989,0x0000098d,0x0004003d,0x00000006,0x00000966,0x00000989,0x0003003e,0x00000955, + 0x00000966,0x0004003d,0x00000021,0x00000967,0x00000510,0x0004003d,0x00000021,0x00000968, + 0x00000510,0x0003003e,0x00000958,0x00000968,0x0004003d,0x00000021,0x0000099d,0x00000958, + 0x0003003e,0x00000998,0x00000133,0x0003003e,0x00000999,0x00000134,0x0003003e,0x0000099a, + 0x00000135,0x0004003d,0x00000006,0x000009a3,0x00000998,0x00050041,0x0000000d,0x000009a4, + 0x000009a0,0x00000087,0x0003003e,0x000009a4,0x000009a3,0x0004003d,0x00000006,0x000009a5, + 0x00000999,0x00050041,0x0000000d,0x000009a6,0x000009a0,0x0000008a,0x0003003e,0x000009a6, + 0x000009a5,0x0004003d,0x00000006,0x000009a7,0x0000099a,0x00050041,0x0000000d,0x000009a8, + 0x000009a0,0x0000009d,0x0003003e,0x000009a8,0x000009a7,0x0004003d,0x00000021,0x000009a9, + 0x000009a0,0x0003003e,0x000009a1,0x000009a9,0x0004003d,0x00000021,0x0000099e,0x000009a1, + 0x00050094,0x00000006,0x0000099f,0x0000099d,0x0000099e,0x0003003e,0x0000099b,0x0000099f, + 0x0004003d,0x00000006,0x00000969,0x0000099b,0x00060050,0x00000021,0x0000096a,0x00000969, + 0x00000969,0x00000969,0x00050083,0x00000021,0x0000096b,0x00000967,0x0000096a,0x0003003e, + 0x00000957,0x0000096b,0x0004003d,0x00000006,0x0000096c,0x00000955,0x00050083,0x00000006, + 0x0000096d,0x000000d0,0x0000096c,0x0004003d,0x00000006,0x0000096e,0x00000955,0x0003003e, + 0x0000095a,0x0000096e,0x0003003e,0x0000095b,0x0000096d,0x0004003d,0x00000006,0x000009ad, + 0x0000095a,0x00050041,0x0000000d,0x000009ae,0x000009aa,0x00000087,0x0003003e,0x000009ae, + 0x000009ad,0x0004003d,0x00000006,0x000009af,0x0000095b,0x00050041,0x0000000d,0x000009b0, + 0x000009aa,0x0000008a,0x0003003e,0x000009b0,0x000009af,0x0004003d,0x00000017,0x000009b1, + 0x000009aa,0x0003003e,0x000009ab,0x000009b1,0x0004003d,0x00000017,0x0000096f,0x000009ab, + 0x0003003e,0x0000095c,0x0000014f,0x0004003d,0x00000006,0x000009b5,0x0000095c,0x00050041, + 0x0000000d,0x000009b6,0x000009b2,0x00000087,0x0003003e,0x000009b6,0x000009b5,0x0004003d, + 0x00000006,0x000009b7,0x0000095c,0x00050041,0x0000000d,0x000009b8,0x000009b2,0x0000008a, + 0x0003003e,0x000009b8,0x000009b7,0x0004003d,0x00000017,0x000009b9,0x000009b2,0x0003003e, + 0x000009b3,0x000009b9,0x0004003d,0x00000017,0x00000970,0x000009b3,0x0004003d,0x00000021, + 0x00000971,0x00000957,0x0003003e,0x0000095d,0x00000971,0x0004003d,0x00000021,0x000009bd, + 0x0000095d,0x0007004f,0x00000017,0x000009be,0x000009bd,0x000009bd,0x00000000,0x00000001, + 0x0003003e,0x000009ba,0x000009be,0x00050041,0x0000000d,0x000009c5,0x000009ba,0x00000087, + 0x0004003d,0x00000006,0x000009c6,0x000009c5,0x00050041,0x0000000d,0x000009c7,0x000009ba, + 0x0000008a,0x0004003d,0x00000006,0x000009c8,0x000009c7,0x0007000c,0x00000006,0x000009c9, + 0x00000001,0x00000025,0x000009c6,0x000009c8,0x0003003e,0x000009c3,0x000009c9,0x0004003d, + 0x00000006,0x000009bf,0x000009c3,0x00050041,0x0000000d,0x000009c0,0x0000095d,0x0000009d, + 0x0004003d,0x00000006,0x000009c1,0x000009c0,0x0007000c,0x00000006,0x000009c2,0x00000001, + 0x00000025,0x000009bf,0x000009c1,0x0003003e,0x000009bb,0x000009c2,0x0004003d,0x00000006, + 0x00000972,0x000009bb,0x0004007f,0x00000006,0x00000973,0x00000972,0x0004003d,0x00000021, + 0x00000974,0x00000957,0x0003003e,0x0000095e,0x00000974,0x0004003d,0x00000021,0x000009cd, + 0x0000095e,0x0007004f,0x00000017,0x000009ce,0x000009cd,0x000009cd,0x00000000,0x00000001, + 0x0003003e,0x000009ca,0x000009ce,0x00050041,0x0000000d,0x000009d5,0x000009ca,0x00000087, + 0x0004003d,0x00000006,0x000009d6,0x000009d5,0x00050041,0x0000000d,0x000009d7,0x000009ca, + 0x0000008a,0x0004003d,0x00000006,0x000009d8,0x000009d7,0x0007000c,0x00000006,0x000009d9, + 0x00000001,0x00000028,0x000009d6,0x000009d8,0x0003003e,0x000009d3,0x000009d9,0x0004003d, + 0x00000006,0x000009cf,0x000009d3,0x00050041,0x0000000d,0x000009d0,0x0000095e,0x0000009d, + 0x0004003d,0x00000006,0x000009d1,0x000009d0,0x0007000c,0x00000006,0x000009d2,0x00000001, + 0x00000028,0x000009cf,0x000009d1,0x0003003e,0x000009cb,0x000009d2,0x0004003d,0x00000006, + 0x00000975,0x000009cb,0x0003003e,0x0000095f,0x00000973,0x0003003e,0x00000960,0x00000975, + 0x0004003d,0x00000006,0x000009dd,0x0000095f,0x00050041,0x0000000d,0x000009de,0x000009da, + 0x00000087,0x0003003e,0x000009de,0x000009dd,0x0004003d,0x00000006,0x000009df,0x00000960, + 0x00050041,0x0000000d,0x000009e0,0x000009da,0x0000008a,0x0003003e,0x000009e0,0x000009df, + 0x0004003d,0x00000017,0x000009e1,0x000009da,0x0003003e,0x000009db,0x000009e1,0x0004003d, + 0x00000017,0x00000976,0x000009db,0x0007000c,0x00000017,0x00000977,0x00000001,0x00000028, + 0x00000970,0x00000976,0x00050088,0x00000017,0x00000978,0x0000096f,0x00000977,0x0003003e, + 0x00000959,0x00000978,0x0003003e,0x00000962,0x000000d0,0x0004003d,0x00000006,0x000009e4, + 0x00000962,0x0003003e,0x000009e2,0x000009e4,0x0004003d,0x00000006,0x00000979,0x000009e2, + 0x00050041,0x0000000d,0x0000097a,0x00000959,0x00000087,0x0004003d,0x00000006,0x0000097b, + 0x0000097a,0x00050041,0x0000000d,0x0000097c,0x00000959,0x0000008a,0x0004003d,0x00000006, + 0x0000097d,0x0000097c,0x0007000c,0x00000006,0x0000097e,0x00000001,0x00000025,0x0000097b, + 0x0000097d,0x0007000c,0x00000006,0x0000097f,0x00000001,0x00000025,0x00000979,0x0000097e, + 0x0003003e,0x00000961,0x0000097f,0x0004003d,0x00000021,0x00000980,0x00000957,0x0004003d, + 0x00000006,0x00000981,0x00000961,0x0005008e,0x00000021,0x00000982,0x00000980,0x00000981, + 0x0004003d,0x00000006,0x00000983,0x00000955,0x00060050,0x00000021,0x00000984,0x00000983, + 0x00000983,0x00000983,0x00050081,0x00000021,0x00000985,0x00000982,0x00000984,0x0003003e, + 0x00000963,0x00000985,0x0004003d,0x00000021,0x00000609,0x00000963,0x0003003e,0x000004ee, + 0x00000609,0x000200f9,0x0000060a,0x000200f8,0x0000060a,0x000200f9,0x0000060b,0x000200f8, + 0x0000060b,0x0004003d,0x00000021,0x0000060c,0x000004ee,0x0003003e,0x00000512,0x0000060c, + 0x0004003d,0x00000021,0x000004e5,0x00000512,0x0003003e,0x000004db,0x000004e5,0x0004003d, + 0x00000021,0x000004e6,0x000003c3,0x0004003d,0x00000021,0x000004e7,0x000004db,0x00050041, + 0x0000000d,0x000004e8,0x000003c6,0x000000b5,0x0004003d,0x00000006,0x000004e9,0x000004e8, + 0x0003003e,0x000004df,0x000004e9,0x0004003d,0x00000006,0x000009e8,0x000004df,0x00050041, + 0x0000000d,0x000009e9,0x000009e5,0x00000087,0x0003003e,0x000009e9,0x000009e8,0x0004003d, + 0x00000006,0x000009ea,0x000004df,0x00050041,0x0000000d,0x000009eb,0x000009e5,0x0000008a, + 0x0003003e,0x000009eb,0x000009ea,0x0004003d,0x00000006,0x000009ec,0x000004df,0x00050041, + 0x0000000d,0x000009ed,0x000009e5,0x0000009d,0x0003003e,0x000009ed,0x000009ec,0x0004003d, + 0x00000021,0x000009ee,0x000009e5,0x0003003e,0x000009e6,0x000009ee,0x0004003d,0x00000021, + 0x000004ea,0x000009e6,0x0008000c,0x00000021,0x000004eb,0x00000001,0x0000002e,0x000004e6, + 0x000004e7,0x000004ea,0x0003003e,0x000004e0,0x000004eb,0x0004003d,0x00000021,0x000003ca, + 0x000004e0,0x00050041,0x0000000d,0x000003cb,0x00000373,0x00000087,0x00050051,0x00000006, + 0x000003cc,0x000003ca,0x00000000,0x0003003e,0x000003cb,0x000003cc,0x00050041,0x0000000d, + 0x000003cd,0x00000373,0x0000008a,0x00050051,0x00000006,0x000003ce,0x000003ca,0x00000001, + 0x0003003e,0x000003cd,0x000003ce,0x00050041,0x0000000d,0x000003cf,0x00000373,0x0000009d, + 0x00050051,0x00000006,0x000003d0,0x000003ca,0x00000002,0x0003003e,0x000003cf,0x000003d0, + 0x000200f9,0x000003c2,0x000200f8,0x000003c2,0x0004003d,0x00000006,0x000003d1,0x0000037a, + 0x00050041,0x0000000d,0x000003d2,0x00000373,0x000000b5,0x0004003d,0x00000006,0x000003d3, + 0x000003d2,0x00050085,0x00000006,0x000003d4,0x000003d3,0x000003d1,0x0003003e,0x000003d2, + 0x000003d4,0x0004003d,0x00000006,0x000003d7,0x000003d2,0x0004003d,0x00000007,0x000003d8, + 0x00000373,0x0008004f,0x00000021,0x000003d9,0x000003d8,0x000003d8,0x00000000,0x00000001, + 0x00000002,0x0005008e,0x00000021,0x000003da,0x000003d9,0x000003d7,0x00050041,0x0000000d, + 0x000003db,0x00000373,0x00000087,0x00050051,0x00000006,0x000003dc,0x000003da,0x00000000, + 0x0003003e,0x000003db,0x000003dc,0x00050041,0x0000000d,0x000003dd,0x00000373,0x0000008a, + 0x00050051,0x00000006,0x000003de,0x000003da,0x00000001,0x0003003e,0x000003dd,0x000003de, + 0x00050041,0x0000000d,0x000003df,0x00000373,0x0000009d,0x00050051,0x00000006,0x000003e0, + 0x000003da,0x00000002,0x0003003e,0x000003df,0x000003e0,0x000200f9,0x000003b9,0x000200f8, + 0x000003e1,0x0004003d,0x00000006,0x000003e2,0x0000037a,0x0004003d,0x00000007,0x000003e3, + 0x00000373,0x0005008e,0x00000007,0x000003e4,0x000003e3,0x000003e2,0x0003003e,0x00000373, + 0x000003e4,0x000200f9,0x000003b9,0x000200f8,0x000003b9,0x0004003d,0x00000007,0x000003ed, + 0x00000373,0x0008004f,0x00000021,0x000003ee,0x000003ed,0x000003ed,0x00000000,0x00000001, + 0x00000002,0x0003003e,0x000003ec,0x000003ee,0x0004003d,0x00000007,0x000003f0,0x000003e5, + 0x0007004f,0x00000017,0x000003f1,0x000003f0,0x000003f0,0x00000000,0x00000001,0x0003003e, + 0x000003ef,0x000003f1,0x00050041,0x000003f3,0x000003f4,0x000003e9,0x00000087,0x0004003d, + 0x00000006,0x000003f5,0x000003f4,0x0003003e,0x000003f2,0x000003f5,0x00050041,0x000003f3, + 0x000003f7,0x000003e9,0x0000008a,0x0004003d,0x00000006,0x000003f8,0x000003f7,0x0003003e, + 0x000003f6,0x000003f8,0x000300f7,0x000009ff,0x00000000,0x000400fa,0x0000011f,0x000009f5, + 0x000009fd,0x000200f8,0x000009f5,0x0004003d,0x00000017,0x000009f6,0x000003ef,0x0003003e, + 0x000009f0,0x000009f6,0x0004003d,0x00000006,0x000009f7,0x000003f2,0x0003003e,0x000009f1, + 0x000009f7,0x0004003d,0x00000006,0x000009f8,0x000003f6,0x0003003e,0x000009f2,0x000009f8, + 0x00050041,0x0000000d,0x00000a05,0x000009f0,0x00000087,0x0004003d,0x00000006,0x00000a06, + 0x00000a05,0x00050085,0x00000006,0x00000a07,0x00000109,0x00000a06,0x00050041,0x0000000d, + 0x00000a08,0x000009f0,0x0000008a,0x0004003d,0x00000006,0x00000a09,0x00000a08,0x00050085, + 0x00000006,0x00000a0a,0x0000010d,0x00000a09,0x00050081,0x00000006,0x00000a0b,0x00000a07, + 0x00000a0a,0x0006000c,0x00000006,0x00000a0c,0x00000001,0x0000000a,0x00000a0b,0x0003003e, + 0x00000a01,0x00000a0c,0x0004003d,0x00000006,0x00000a0d,0x00000a01,0x00050085,0x00000006, + 0x00000a0e,0x00000114,0x00000a0d,0x0006000c,0x00000006,0x00000a0f,0x00000001,0x0000000a, + 0x00000a0e,0x0003003e,0x00000a02,0x00000a0f,0x0004003d,0x00000006,0x00000a10,0x00000a02, + 0x0004003d,0x00000006,0x00000a11,0x000009f1,0x00050085,0x00000006,0x00000a12,0x00000a10, + 0x00000a11,0x0004003d,0x00000006,0x00000a13,0x000009f2,0x00050081,0x00000006,0x00000a14, + 0x00000a12,0x00000a13,0x0003003e,0x00000a03,0x00000a14,0x0004003d,0x00000006,0x000009f9, + 0x00000a03,0x0004003d,0x00000021,0x000009fa,0x000003ec,0x00060050,0x00000021,0x000009fb, + 0x000009f9,0x000009f9,0x000009f9,0x00050081,0x00000021,0x000009fc,0x000009fb,0x000009fa, + 0x0003003e,0x000009ef,0x000009fc,0x000200f9,0x000009ff,0x000200f8,0x000009fd,0x0004003d, + 0x00000021,0x000009fe,0x000003ec,0x0003003e,0x000009ef,0x000009fe,0x000200f9,0x000009ff, + 0x000200f8,0x000009ff,0x0004003d,0x00000021,0x00000a00,0x000009ef,0x0003003e,0x000009f3, + 0x00000a00,0x0004003d,0x00000021,0x000003f9,0x000009f3,0x00050041,0x0000000d,0x000003fa, + 0x00000373,0x00000087,0x00050051,0x00000006,0x000003fb,0x000003f9,0x00000000,0x0003003e, + 0x000003fa,0x000003fb,0x00050041,0x0000000d,0x000003fc,0x00000373,0x0000008a,0x00050051, + 0x00000006,0x000003fd,0x000003f9,0x00000001,0x0003003e,0x000003fc,0x000003fd,0x00050041, + 0x0000000d,0x000003fe,0x00000373,0x0000009d,0x00050051,0x00000006,0x000003ff,0x000003f9, + 0x00000002,0x0003003e,0x000003fe,0x000003ff,0x0004003d,0x00000007,0x00000402,0x00000373, + 0x0003003e,0x00000401,0x00000402,0x0003003e,0x00000404,0x000000ca,0x0004003d,0x00000006, + 0x00000a18,0x00000404,0x00050041,0x0000000d,0x00000a19,0x00000a15,0x00000087,0x0003003e, + 0x00000a19,0x00000a18,0x0004003d,0x00000006,0x00000a1a,0x00000404,0x00050041,0x0000000d, + 0x00000a1b,0x00000a15,0x0000008a,0x0003003e,0x00000a1b,0x00000a1a,0x0004003d,0x00000006, + 0x00000a1c,0x00000404,0x00050041,0x0000000d,0x00000a1d,0x00000a15,0x0000009d,0x0003003e, + 0x00000a1d,0x00000a1c,0x0004003d,0x00000006,0x00000a1e,0x00000404,0x00050041,0x0000000d, + 0x00000a1f,0x00000a15,0x000000b5,0x0003003e,0x00000a1f,0x00000a1e,0x0004003d,0x00000007, + 0x00000a20,0x00000a15,0x0003003e,0x00000a16,0x00000a20,0x0004003d,0x00000007,0x00000405, + 0x00000a16,0x0003003e,0x00000403,0x00000405,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..85eab8a55944a00f49ca9834707117447b636835 GIT binary patch literal 49528 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h new file mode 100644 index 000000000..064084f1c --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h @@ -0,0 +1,271 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_atlas_blit_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000002ac,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0010000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000c9,0x000000cc,0x000000d3, + 0x000000d6,0x0000010f,0x00000114,0x00000135,0x00000154,0x000001c0,0x000001c3,0x000001d7, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000a1, + 0x0000664a,0x00040006,0x000000a1,0x00000000,0x00003464,0x00030005,0x000000a3,0x0000424c, + 0x00030005,0x000000bb,0x0000424d,0x00040006,0x000000bb,0x00000000,0x00006250,0x00040006, + 0x000000bb,0x00000001,0x00006359,0x00040006,0x000000bb,0x00000002,0x00006552,0x00040006, + 0x000000bb,0x00000003,0x00006553,0x00040006,0x000000bb,0x00000004,0x0000366d,0x00040006, + 0x000000bb,0x00000005,0x0000676d,0x00040006,0x000000bb,0x00000006,0x00006544,0x00040006, + 0x000000bb,0x00000007,0x00006545,0x00040006,0x000000bb,0x00000008,0x00003755,0x00040006, + 0x000000bb,0x00000009,0x0000676a,0x00040006,0x000000bb,0x0000000a,0x0000635a,0x00040006, + 0x000000bb,0x0000000b,0x00003157,0x00040006,0x000000bb,0x0000000c,0x0000676e,0x00040006, + 0x000000bb,0x0000000d,0x00003559,0x00040006,0x000000bb,0x0000000e,0x0000324f,0x00040006, + 0x000000bb,0x0000000f,0x00006461,0x00040006,0x000000bb,0x00000010,0x00006579,0x00040006, + 0x000000bb,0x00000011,0x00003376,0x00040006,0x000000bb,0x00000012,0x00003377,0x00040006, + 0x000000bb,0x00000013,0x00006462,0x00040006,0x000000bb,0x00000014,0x00006767,0x00030005, + 0x000000bd,0x0000006b,0x00060005,0x000000c9,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00070005,0x000000cc,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005, + 0x000000d3,0x0000424a,0x00030005,0x000000d6,0x00003243,0x00030005,0x000000e2,0x00006576, + 0x00040006,0x000000e2,0x00000000,0x00003464,0x00030005,0x000000e4,0x00004355,0x00030005, + 0x000000ee,0x00006747,0x00030005,0x0000010f,0x00003346,0x00030005,0x00000111,0x00006749, + 0x00030005,0x00000114,0x00003159,0x00030005,0x0000011d,0x00006748,0x00030005,0x00000122, + 0x00006577,0x00040006,0x00000122,0x00000000,0x00003464,0x00030005,0x00000124,0x0000424f, + 0x00030005,0x00000135,0x0000304e,0x00030005,0x00000154,0x0000316b,0x00030005,0x000001c0, + 0x00003361,0x00030005,0x000001c3,0x00003469,0x00060005,0x000001d5,0x505f6c67,0x65567265, + 0x78657472,0x00000000,0x00060006,0x000001d5,0x00000000,0x505f6c67,0x7469736f,0x006e6f69, + 0x00070006,0x000001d5,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006, + 0x000001d5,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x000001d5, + 0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000001d7,0x00000000, + 0x00030005,0x000001e5,0x00004342,0x00030005,0x000001e8,0x00004351,0x00030005,0x000001ea, + 0x0000664b,0x00040006,0x000001ea,0x00000000,0x00003464,0x00030005,0x000001ec,0x00004358, + 0x00030005,0x000001ef,0x00003954,0x00040047,0x000000a0,0x00000006,0x00000010,0x00030047, + 0x000000a1,0x00000003,0x00040048,0x000000a1,0x00000000,0x00000018,0x00050048,0x000000a1, + 0x00000000,0x00000023,0x00000000,0x00030047,0x000000a3,0x00000018,0x00040047,0x000000a3, + 0x00000021,0x00000003,0x00040047,0x000000a3,0x00000022,0x00000000,0x00030047,0x000000bb, + 0x00000002,0x00050048,0x000000bb,0x00000000,0x00000023,0x00000000,0x00050048,0x000000bb, + 0x00000001,0x00000023,0x00000004,0x00050048,0x000000bb,0x00000002,0x00000023,0x00000008, + 0x00050048,0x000000bb,0x00000003,0x00000023,0x0000000c,0x00050048,0x000000bb,0x00000004, + 0x00000023,0x00000010,0x00050048,0x000000bb,0x00000005,0x00000023,0x00000014,0x00050048, + 0x000000bb,0x00000006,0x00000023,0x00000018,0x00050048,0x000000bb,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x000000bb,0x00000008,0x00000023,0x00000020,0x00050048,0x000000bb, + 0x00000009,0x00000023,0x00000030,0x00050048,0x000000bb,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x000000bb,0x0000000b,0x00000023,0x00000040,0x00050048,0x000000bb,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x000000bb,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x000000bb,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000000bb,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x000000bb,0x00000010,0x00000023,0x00000054,0x00050048,0x000000bb, + 0x00000011,0x00000023,0x00000058,0x00050048,0x000000bb,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x000000bb,0x00000013,0x00000023,0x00000060,0x00050048,0x000000bb,0x00000014, + 0x00000023,0x00000064,0x00040047,0x000000bd,0x00000021,0x00000000,0x00040047,0x000000bd, + 0x00000022,0x00000000,0x00040047,0x000000c9,0x0000000b,0x0000002a,0x00040047,0x000000cc, + 0x0000000b,0x0000002b,0x00040047,0x000000d3,0x0000001e,0x00000000,0x00040047,0x000000d6, + 0x0000001e,0x00000001,0x00040047,0x000000e1,0x00000006,0x00000008,0x00030047,0x000000e2, + 0x00000003,0x00040048,0x000000e2,0x00000000,0x00000018,0x00050048,0x000000e2,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000000e4,0x00000018,0x00040047,0x000000e4,0x00000021, + 0x00000004,0x00040047,0x000000e4,0x00000022,0x00000000,0x00040047,0x000000ee,0x00000001, + 0x00000000,0x00030047,0x0000010d,0x00000000,0x00030047,0x0000010f,0x00000000,0x00030047, + 0x0000010f,0x0000000e,0x00040047,0x0000010f,0x0000001e,0x00000004,0x00040047,0x00000111, + 0x00000001,0x00000002,0x00030047,0x00000114,0x00000000,0x00030047,0x00000114,0x0000000e, + 0x00040047,0x00000114,0x0000001e,0x00000006,0x00040047,0x0000011d,0x00000001,0x00000001, + 0x00040047,0x00000121,0x00000006,0x00000010,0x00030047,0x00000122,0x00000003,0x00040048, + 0x00000122,0x00000000,0x00000018,0x00050048,0x00000122,0x00000000,0x00000023,0x00000000, + 0x00030047,0x00000124,0x00000018,0x00040047,0x00000124,0x00000021,0x00000005,0x00040047, + 0x00000124,0x00000022,0x00000000,0x00040047,0x00000135,0x0000001e,0x00000005,0x00030047, + 0x0000014a,0x00000000,0x00030047,0x0000014c,0x00000000,0x00030047,0x0000014d,0x00000000, + 0x00040047,0x00000154,0x0000001e,0x00000000,0x00030047,0x000001c0,0x0000000e,0x00040047, + 0x000001c0,0x0000001e,0x00000007,0x00040047,0x000001c3,0x0000001e,0x00000008,0x00030047, + 0x000001d5,0x00000002,0x00050048,0x000001d5,0x00000000,0x0000000b,0x00000000,0x00050048, + 0x000001d5,0x00000001,0x0000000b,0x00000001,0x00050048,0x000001d5,0x00000002,0x0000000b, + 0x00000003,0x00050048,0x000001d5,0x00000003,0x0000000b,0x00000004,0x00040047,0x000001e5, + 0x00000021,0x00000008,0x00040047,0x000001e5,0x00000022,0x00000000,0x00030047,0x000001e8, + 0x00000000,0x00040047,0x000001e8,0x00000021,0x0000000a,0x00040047,0x000001e8,0x00000022, + 0x00000000,0x00040047,0x000001e9,0x00000006,0x00000010,0x00030047,0x000001ea,0x00000003, + 0x00040048,0x000001ea,0x00000000,0x00000018,0x00050048,0x000001ea,0x00000000,0x00000023, + 0x00000000,0x00030047,0x000001ec,0x00000018,0x00040047,0x000001ec,0x00000021,0x00000006, + 0x00040047,0x000001ec,0x00000022,0x00000000,0x00030047,0x000001ef,0x00000000,0x00040047, + 0x000001ef,0x00000021,0x0000000a,0x00040047,0x000001ef,0x00000022,0x00000000,0x00030047, + 0x00000292,0x00000000,0x00030047,0x00000294,0x00000000,0x00030047,0x00000296,0x00000000, + 0x00030047,0x000002a3,0x00000000,0x00030047,0x000002a5,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040017,0x00000009,0x00000006,0x00000002,0x00040018,0x0000000a, + 0x00000009,0x00000002,0x00040015,0x0000000f,0x00000020,0x00000000,0x00040017,0x00000025, + 0x00000006,0x00000003,0x0004002b,0x00000006,0x00000031,0x3f800000,0x0004002b,0x00000006, + 0x00000032,0x00000000,0x0004002b,0x0000000f,0x0000003d,0x00000000,0x00020014,0x0000003e, + 0x0004002b,0x0000000f,0x00000045,0x000003ff,0x0004002b,0x0000000f,0x00000055,0x00000001, + 0x00040015,0x00000061,0x00000020,0x00000001,0x0004002b,0x00000061,0x00000062,0x00000000, + 0x0004002b,0x00000006,0x0000008e,0x3f000000,0x0004002b,0x0000000f,0x00000097,0x00000002, + 0x0004002b,0x0000000f,0x0000009b,0x0000ffff,0x00040017,0x0000009d,0x0000000f,0x00000004, + 0x0003001d,0x000000a0,0x0000009d,0x0003001e,0x000000a1,0x000000a0,0x00040020,0x000000a2, + 0x00000002,0x000000a1,0x0004003b,0x000000a2,0x000000a3,0x00000002,0x0004002b,0x0000000f, + 0x000000a5,0x00000004,0x00040020,0x000000a8,0x00000002,0x0000009d,0x00040017,0x000000af, + 0x0000000f,0x00000003,0x00040017,0x000000ba,0x00000061,0x00000004,0x0017001e,0x000000bb, + 0x00000006,0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f,0x0000000f,0x0000000f, + 0x000000ba,0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f,0x00000006,0x00000006, + 0x0000000f,0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020,0x000000bc,0x00000002, + 0x000000bb,0x0004003b,0x000000bc,0x000000bd,0x00000002,0x0004002b,0x00000061,0x000000be, + 0x00000009,0x00040020,0x000000bf,0x00000002,0x00000009,0x00040020,0x000000c8,0x00000001, + 0x00000061,0x0004003b,0x000000c8,0x000000c9,0x00000001,0x0004003b,0x000000c8,0x000000cc, + 0x00000001,0x00040020,0x000000d2,0x00000001,0x00000025,0x0004003b,0x000000d2,0x000000d3, + 0x00000001,0x00040020,0x000000d5,0x00000003,0x00000009,0x0004003b,0x000000d5,0x000000d6, + 0x00000003,0x00040017,0x000000de,0x0000000f,0x00000002,0x0003001d,0x000000e1,0x000000de, + 0x0003001e,0x000000e2,0x000000e1,0x00040020,0x000000e3,0x00000002,0x000000e2,0x0004003b, + 0x000000e3,0x000000e4,0x00000002,0x00040020,0x000000e6,0x00000002,0x000000de,0x0004002b, + 0x0000000f,0x000000ec,0x0000000f,0x00030030,0x0000003e,0x000000ee,0x0004002b,0x00000061, + 0x000000fd,0x00000010,0x0004002b,0x00000061,0x00000100,0x0000000d,0x00040020,0x00000104, + 0x00000002,0x0000000f,0x00040020,0x0000010e,0x00000003,0x00000006,0x0004003b,0x0000010e, + 0x0000010f,0x00000003,0x00030030,0x0000003e,0x00000111,0x0004003b,0x0000010e,0x00000114, + 0x00000003,0x0004002b,0x00000061,0x00000117,0x00000004,0x00030030,0x0000003e,0x0000011d, + 0x0003001d,0x00000121,0x00000007,0x0003001e,0x00000122,0x00000121,0x00040020,0x00000123, + 0x00000002,0x00000122,0x0004003b,0x00000123,0x00000124,0x00000002,0x00040020,0x00000129, + 0x00000002,0x00000007,0x0004002b,0x0000000f,0x00000130,0x00000003,0x00040020,0x00000134, + 0x00000003,0x00000007,0x0004003b,0x00000134,0x00000135,0x00000003,0x00050034,0x0000003e, + 0x00000146,0x000000a8,0x00000111,0x0004003b,0x00000134,0x00000154,0x00000003,0x0004002b, + 0x00000006,0x0000017b,0x3f666666,0x0004002b,0x00000006,0x0000017f,0x40000000,0x0004002b, + 0x00000006,0x000001a4,0xc0000000,0x0004002b,0x00000061,0x000001ad,0x00000002,0x0004002b, + 0x00000061,0x000001ae,0x00000003,0x00040020,0x000001b2,0x00000002,0x00000006,0x00040020, + 0x000001bf,0x00000003,0x000000de,0x0004003b,0x000001bf,0x000001c0,0x00000003,0x0004003b, + 0x000000d5,0x000001c3,0x00000003,0x0004001c,0x000001d4,0x00000006,0x00000055,0x0006001e, + 0x000001d5,0x00000007,0x00000006,0x000001d4,0x000001d4,0x00040020,0x000001d6,0x00000003, + 0x000001d5,0x0004003b,0x000001d6,0x000001d7,0x00000003,0x00090019,0x000001e3,0x0000000f, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000001e4, + 0x00000000,0x000001e3,0x0004003b,0x000001e4,0x000001e5,0x00000000,0x00090019,0x000001e6, + 0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x000001e7,0x00000000,0x000001e6,0x0004003b,0x000001e7,0x000001e8,0x00000000,0x0003001d, + 0x000001e9,0x0000009d,0x0003001e,0x000001ea,0x000001e9,0x00040020,0x000001eb,0x00000002, + 0x000001ea,0x0004003b,0x000001eb,0x000001ec,0x00000002,0x0002001a,0x000001ed,0x00040020, + 0x000001ee,0x00000000,0x000001ed,0x0004003b,0x000001ee,0x000001ef,0x00000000,0x0005002c, + 0x00000009,0x000002a8,0x00000031,0x00000031,0x0007002c,0x00000007,0x000002a9,0x0000008e, + 0x0000008e,0x0000008e,0x0000008e,0x0003002e,0x00000009,0x000002ab,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000025,0x000000d8, + 0x000000d3,0x00050051,0x00000006,0x000001fc,0x000000d8,0x00000002,0x0004007c,0x0000000f, + 0x000001fd,0x000001fc,0x000500c7,0x0000000f,0x000001fe,0x000001fd,0x0000009b,0x00050084, + 0x0000000f,0x00000200,0x000001fe,0x000000a5,0x00050080,0x0000000f,0x00000201,0x00000200, + 0x00000097,0x00060041,0x000000a8,0x00000202,0x000000a3,0x00000062,0x00000201,0x0004003d, + 0x0000009d,0x00000203,0x00000202,0x0007004f,0x00000009,0x00000205,0x000000d8,0x000000d8, + 0x00000000,0x00000001,0x0008004f,0x000000af,0x00000207,0x00000203,0x00000203,0x00000001, + 0x00000002,0x00000003,0x0004007c,0x00000025,0x00000208,0x00000207,0x00050051,0x00000006, + 0x0000020b,0x00000208,0x00000000,0x0005008e,0x00000009,0x0000020c,0x00000205,0x0000020b, + 0x0007004f,0x00000009,0x0000020e,0x00000208,0x00000208,0x00000001,0x00000002,0x00050081, + 0x00000009,0x0000020f,0x0000020c,0x0000020e,0x00050041,0x000000bf,0x00000210,0x000000bd, + 0x000000be,0x0004003d,0x00000009,0x00000211,0x00000210,0x00050085,0x00000009,0x00000212, + 0x0000020f,0x00000211,0x0003003e,0x000000d6,0x00000212,0x00060041,0x000000e6,0x000000e7, + 0x000000e4,0x00000062,0x000001fe,0x0004003d,0x000000de,0x000000e8,0x000000e7,0x00050051, + 0x0000000f,0x000000eb,0x000000e8,0x00000000,0x000500c7,0x0000000f,0x000000ed,0x000000eb, + 0x000000ec,0x000300f7,0x000000f0,0x00000000,0x000400fa,0x000000ee,0x000000ef,0x000000f0, + 0x000200f8,0x000000ef,0x000500aa,0x0000003e,0x000000f3,0x000000ed,0x0000003d,0x000300f7, + 0x000000f6,0x00000000,0x000400fa,0x000000f3,0x000000f5,0x000000f9,0x000200f8,0x000000f9, + 0x000200f9,0x000000f6,0x000200f8,0x000000f5,0x00050051,0x0000000f,0x000000f8,0x000000e8, + 0x00000001,0x000200f9,0x000000f6,0x000200f8,0x000000f6,0x000700f5,0x0000000f,0x000002a1, + 0x000000f8,0x000000f5,0x000000eb,0x000000f9,0x000500c2,0x0000000f,0x000000fe,0x000002a1, + 0x000000fd,0x00050041,0x00000104,0x00000105,0x000000bd,0x00000100,0x0004003d,0x0000000f, + 0x00000106,0x00000105,0x000500aa,0x0000003e,0x00000219,0x000000fe,0x0000003d,0x000300f7, + 0x00000222,0x00000000,0x000400fa,0x00000219,0x0000021a,0x0000021b,0x000200f8,0x0000021b, + 0x00050080,0x0000000f,0x0000021d,0x000000fe,0x00000045,0x00050084,0x0000000f,0x0000021f, + 0x0000021d,0x00000106,0x0006000c,0x00000009,0x00000220,0x00000001,0x0000003e,0x0000021f, + 0x00050051,0x00000006,0x00000221,0x00000220,0x00000000,0x000200f9,0x00000222,0x000200f8, + 0x0000021a,0x000200f9,0x00000222,0x000200f8,0x00000222,0x000700f5,0x00000006,0x000002a2, + 0x00000032,0x0000021a,0x00000221,0x0000021b,0x000300f7,0x0000010b,0x00000000,0x000400fa, + 0x000000f3,0x0000010a,0x0000010b,0x000200f8,0x0000010a,0x0004007f,0x00000006,0x0000010d, + 0x000002a2,0x000200f9,0x0000010b,0x000200f8,0x0000010b,0x000700f5,0x00000006,0x000002a3, + 0x000002a2,0x00000222,0x0000010d,0x0000010a,0x0003003e,0x0000010f,0x000002a3,0x000200f9, + 0x000000f0,0x000200f8,0x000000f0,0x000300f7,0x00000113,0x00000000,0x000400fa,0x00000111, + 0x00000112,0x00000113,0x000200f8,0x00000112,0x000500c2,0x0000000f,0x00000118,0x000000eb, + 0x00000117,0x000500c7,0x0000000f,0x00000119,0x00000118,0x000000ec,0x00040070,0x00000006, + 0x0000011a,0x00000119,0x0003003e,0x00000114,0x0000011a,0x000200f9,0x00000113,0x000200f8, + 0x00000113,0x000300f7,0x0000011f,0x00000000,0x000400fa,0x0000011d,0x0000011e,0x0000011f, + 0x000200f8,0x0000011e,0x00060041,0x00000129,0x0000012a,0x00000124,0x00000062,0x00000201, + 0x0004003d,0x00000007,0x0000012b,0x0000012a,0x00050051,0x00000006,0x0000022b,0x0000012b, + 0x00000000,0x00050051,0x00000006,0x0000022c,0x0000012b,0x00000001,0x00050051,0x00000006, + 0x0000022d,0x0000012b,0x00000002,0x00050051,0x00000006,0x0000022e,0x0000012b,0x00000003, + 0x00050050,0x00000009,0x0000022f,0x0000022b,0x0000022c,0x00050050,0x00000009,0x00000230, + 0x0000022d,0x0000022e,0x00050050,0x0000000a,0x00000231,0x0000022f,0x00000230,0x00050080, + 0x0000000f,0x00000131,0x00000200,0x00000130,0x00060041,0x00000129,0x00000132,0x00000124, + 0x00000062,0x00000131,0x0004003d,0x00000007,0x00000133,0x00000132,0x0007004f,0x00000009, + 0x0000013a,0x00000133,0x00000133,0x00000000,0x00000001,0x000300f7,0x00000267,0x00000000, + 0x000300fb,0x0000003d,0x00000239,0x000200f8,0x00000239,0x0006000c,0x00000009,0x0000023c, + 0x00000001,0x00000004,0x0000022f,0x0006000c,0x00000009,0x0000023f,0x00000001,0x00000004, + 0x00000230,0x00050081,0x00000009,0x00000240,0x0000023c,0x0000023f,0x00050051,0x00000006, + 0x00000242,0x00000240,0x00000000,0x000500b7,0x0000003e,0x00000243,0x00000242,0x00000032, + 0x000300f7,0x00000248,0x00000000,0x000400fa,0x00000243,0x00000244,0x00000248,0x000200f8, + 0x00000244,0x00050051,0x00000006,0x00000246,0x00000240,0x00000001,0x000500b7,0x0000003e, + 0x00000247,0x00000246,0x00000032,0x000200f9,0x00000248,0x000200f8,0x00000248,0x000700f5, + 0x0000003e,0x00000249,0x00000243,0x00000239,0x00000247,0x00000244,0x000300f7,0x00000266, + 0x00000000,0x000400fa,0x00000249,0x0000024a,0x00000263,0x000200f8,0x00000263,0x0009004f, + 0x00000007,0x00000265,0x00000133,0x000002ab,0x00000000,0x00000001,0x00000000,0x00000001, + 0x000200f9,0x00000267,0x000200f8,0x0000024a,0x00050088,0x00000009,0x0000024d,0x000002a8, + 0x00000240,0x00050091,0x00000009,0x00000250,0x00000231,0x00000205,0x00050081,0x00000009, + 0x00000252,0x00000250,0x0000013a,0x0004007f,0x00000009,0x00000255,0x00000252,0x00050051, + 0x00000006,0x00000256,0x00000252,0x00000000,0x00050051,0x00000006,0x00000257,0x00000252, + 0x00000001,0x00050051,0x00000006,0x00000258,0x00000255,0x00000000,0x00050051,0x00000006, + 0x00000259,0x00000255,0x00000001,0x00070050,0x00000007,0x0000025a,0x00000256,0x00000257, + 0x00000258,0x00000259,0x0009004f,0x00000007,0x0000025c,0x0000024d,0x0000024d,0x00000000, + 0x00000001,0x00000000,0x00000001,0x00050085,0x00000007,0x0000025d,0x0000025a,0x0000025c, + 0x00050081,0x00000007,0x00000260,0x0000025d,0x0000025c,0x00050081,0x00000007,0x00000262, + 0x00000260,0x000002a9,0x000200f9,0x00000267,0x000200f8,0x00000266,0x000100ff,0x000200f8, + 0x00000267,0x000700f5,0x00000007,0x000002a4,0x00000262,0x0000024a,0x00000265,0x00000263, + 0x0003003e,0x00000135,0x000002a4,0x000200f9,0x0000011f,0x000200f8,0x0000011f,0x000500aa, + 0x0000003e,0x0000013f,0x000000ed,0x00000055,0x000300f7,0x00000141,0x00000000,0x000400fa, + 0x0000013f,0x00000140,0x00000156,0x000200f8,0x00000156,0x00060041,0x00000129,0x0000015b, + 0x00000124,0x00000062,0x00000200,0x0004003d,0x00000007,0x0000015c,0x0000015b,0x00050051, + 0x00000006,0x0000026f,0x0000015c,0x00000000,0x00050051,0x00000006,0x00000270,0x0000015c, + 0x00000001,0x00050051,0x00000006,0x00000271,0x0000015c,0x00000002,0x00050051,0x00000006, + 0x00000272,0x0000015c,0x00000003,0x00050050,0x00000009,0x00000273,0x0000026f,0x00000270, + 0x00050050,0x00000009,0x00000274,0x00000271,0x00000272,0x00050050,0x0000000a,0x00000275, + 0x00000273,0x00000274,0x00050080,0x0000000f,0x00000161,0x00000200,0x00000055,0x00060041, + 0x00000129,0x00000162,0x00000124,0x00000062,0x00000161,0x0004003d,0x00000007,0x00000163, + 0x00000162,0x00050091,0x00000009,0x00000167,0x00000275,0x00000205,0x0007004f,0x00000009, + 0x00000169,0x00000163,0x00000163,0x00000000,0x00000001,0x00050081,0x00000009,0x0000016a, + 0x00000167,0x00000169,0x000500aa,0x0000003e,0x0000016c,0x000000ed,0x00000097,0x000500aa, + 0x0000003e,0x0000016e,0x000000ed,0x00000130,0x000500a6,0x0000003e,0x0000016f,0x0000016c, + 0x0000016e,0x000300f7,0x00000171,0x00000000,0x000400fa,0x0000016f,0x00000170,0x00000197, + 0x000200f8,0x00000197,0x00050051,0x0000000f,0x0000019a,0x000000e8,0x00000001,0x0004007c, + 0x00000006,0x0000019b,0x0000019a,0x00050051,0x00000006,0x0000019e,0x00000163,0x00000002, + 0x00050051,0x00000006,0x000001a0,0x0000016a,0x00000000,0x00050051,0x00000006,0x000001a2, + 0x0000016a,0x00000001,0x00050083,0x00000006,0x000001a6,0x000001a4,0x0000019e,0x00070050, + 0x00000007,0x000001a7,0x000001a0,0x000001a2,0x0000019b,0x000001a6,0x0003003e,0x00000154, + 0x000001a7,0x000200f9,0x00000171,0x000200f8,0x00000170,0x00050051,0x0000000f,0x00000173, + 0x000000e8,0x00000001,0x0004007c,0x00000006,0x00000174,0x00000173,0x0004007f,0x00000006, + 0x00000175,0x00000174,0x00050041,0x0000010e,0x00000176,0x00000154,0x00000130,0x0003003e, + 0x00000176,0x00000175,0x00050051,0x00000006,0x00000179,0x00000163,0x00000002,0x000500ba, + 0x0000003e,0x0000017c,0x00000179,0x0000017b,0x000300f7,0x0000017e,0x00000000,0x000400fa, + 0x0000017c,0x0000017d,0x00000181,0x000200f8,0x00000181,0x00050051,0x00000006,0x00000183, + 0x00000163,0x00000003,0x00050041,0x0000010e,0x00000184,0x00000154,0x00000097,0x0003003e, + 0x00000184,0x00000183,0x000200f9,0x0000017e,0x000200f8,0x0000017d,0x00050041,0x0000010e, + 0x00000180,0x00000154,0x00000097,0x0003003e,0x00000180,0x0000017f,0x000200f9,0x0000017e, + 0x000200f8,0x0000017e,0x000300f7,0x00000188,0x00000000,0x000400fa,0x0000016c,0x00000187, + 0x0000018d,0x000200f8,0x0000018d,0x00050041,0x0000010e,0x0000018e,0x00000154,0x00000097, + 0x0004003d,0x00000006,0x0000018f,0x0000018e,0x0004007f,0x00000006,0x00000190,0x0000018f, + 0x0003003e,0x0000018e,0x00000190,0x00050041,0x0000010e,0x00000193,0x00000154,0x0000003d, + 0x00050051,0x00000006,0x00000194,0x0000016a,0x00000000,0x0003003e,0x00000193,0x00000194, + 0x00050041,0x0000010e,0x00000195,0x00000154,0x00000055,0x00050051,0x00000006,0x00000196, + 0x0000016a,0x00000001,0x0003003e,0x00000195,0x00000196,0x000200f9,0x00000188,0x000200f8, + 0x00000187,0x00050041,0x0000010e,0x00000189,0x00000154,0x00000055,0x0003003e,0x00000189, + 0x00000032,0x00050051,0x00000006,0x0000018b,0x0000016a,0x00000000,0x00050041,0x0000010e, + 0x0000018c,0x00000154,0x0000003d,0x0003003e,0x0000018c,0x0000018b,0x000200f9,0x00000188, + 0x000200f8,0x00000188,0x000200f9,0x00000171,0x000200f8,0x00000171,0x000200f9,0x00000141, + 0x000200f8,0x00000140,0x00050051,0x0000000f,0x00000144,0x000000e8,0x00000001,0x0006000c, + 0x00000007,0x00000145,0x00000001,0x00000040,0x00000144,0x000300f7,0x00000148,0x00000000, + 0x000400fa,0x00000146,0x00000147,0x00000148,0x000200f8,0x00000147,0x00050051,0x00000006, + 0x0000014a,0x00000145,0x00000003,0x0008004f,0x00000025,0x0000014c,0x00000145,0x00000145, + 0x00000000,0x00000001,0x00000002,0x0005008e,0x00000025,0x0000014d,0x0000014c,0x0000014a, + 0x00050051,0x00000006,0x0000014f,0x0000014d,0x00000000,0x00060052,0x00000007,0x00000292, + 0x0000014f,0x00000145,0x00000000,0x00050051,0x00000006,0x00000151,0x0000014d,0x00000001, + 0x00060052,0x00000007,0x00000294,0x00000151,0x00000292,0x00000001,0x00050051,0x00000006, + 0x00000153,0x0000014d,0x00000002,0x00060052,0x00000007,0x00000296,0x00000153,0x00000294, + 0x00000002,0x000200f9,0x00000148,0x000200f8,0x00000148,0x000700f5,0x00000007,0x000002a5, + 0x00000145,0x00000140,0x00000296,0x00000147,0x0003003e,0x00000154,0x000002a5,0x000200f9, + 0x00000141,0x000200f8,0x00000141,0x00050041,0x000001b2,0x000001b3,0x000000bd,0x000001ad, + 0x0004003d,0x00000006,0x000001b4,0x000001b3,0x00050041,0x000001b2,0x000001b6,0x000000bd, + 0x000001ae,0x0004003d,0x00000006,0x000001b7,0x000001b6,0x00050051,0x00000006,0x00000279, + 0x000000d8,0x00000000,0x00050085,0x00000006,0x0000027b,0x00000279,0x000001b4,0x00050083, + 0x00000006,0x0000027c,0x0000027b,0x00000031,0x00050051,0x00000006,0x0000027e,0x000000d8, + 0x00000001,0x00050085,0x00000006,0x00000280,0x0000027e,0x000001b7,0x0006000c,0x00000006, + 0x00000282,0x00000001,0x00000006,0x000001b7,0x00050083,0x00000006,0x00000283,0x00000280, + 0x00000282,0x00070050,0x00000007,0x00000284,0x0000027c,0x00000283,0x00000032,0x00000031, + 0x00050080,0x0000000f,0x000001bc,0x00000200,0x00000130,0x00060041,0x000000a8,0x000001bd, + 0x000000a3,0x00000062,0x000001bc,0x0004003d,0x0000009d,0x000001be,0x000001bd,0x0007004f, + 0x000000de,0x000001c2,0x000001be,0x000001be,0x00000000,0x00000001,0x0003003e,0x000001c0, + 0x000001c2,0x0007004f,0x000000de,0x000001c6,0x000001be,0x000001be,0x00000002,0x00000003, + 0x0004007c,0x00000009,0x000001c7,0x000001c6,0x00050081,0x00000009,0x000001c8,0x00000205, + 0x000001c7,0x0003003e,0x000001c3,0x000001c8,0x00050041,0x00000134,0x000001d9,0x000001d7, + 0x00000062,0x0003003e,0x000001d9,0x00000284,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ca015c60c428af851995c3962e253e70ad2caff9 GIT binary patch literal 8536 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.h new file mode 100644 index 000000000..3fca17a76 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.h @@ -0,0 +1,355 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_borrowed_coverage_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000032b,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000d000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000181,0x00000187,0x0000018d, + 0x000001d8,0x000001da,0x000001db,0x000001dc,0x000001dd,0x00030010,0x00000004,0x00000007, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000069, + 0x00004351,0x00030005,0x0000006d,0x00003954,0x00030005,0x00000146,0x0000674a,0x00030005, + 0x0000017f,0x00003071,0x00030005,0x00000181,0x00000049,0x00040005,0x00000182,0x61726170, + 0x0000006d,0x00030005,0x00000185,0x00003679,0x00030005,0x00000187,0x00003469,0x00030005, + 0x0000018b,0x0000374e,0x00030005,0x0000018d,0x00003361,0x00030005,0x00000191,0x00003154, + 0x00040005,0x00000194,0x61726170,0x0000006d,0x00040005,0x00000196,0x61726170,0x0000006d, + 0x00030005,0x0000019a,0x00006455,0x00040005,0x0000019d,0x61726170,0x0000006d,0x00030005, + 0x0000019f,0x0000374f,0x00030005,0x000001a2,0x0000424d,0x00040006,0x000001a2,0x00000000, + 0x00003157,0x00030005,0x000001a4,0x0000006b,0x00030005,0x000001ad,0x00003363,0x00030005, + 0x000001af,0x00006454,0x00040006,0x000001af,0x00000000,0x00003464,0x00030005,0x000001b1, + 0x00003053,0x00030005,0x000001bd,0x0000686f,0x00030005,0x000001d8,0x0000316b,0x00030005, + 0x000001da,0x0000307a,0x00030005,0x000001db,0x00003153,0x00030005,0x000001dc,0x0000304e, + 0x00030005,0x000001dd,0x00003159,0x00030047,0x00000069,0x00000000,0x00040047,0x00000069, + 0x00000021,0x0000000a,0x00040047,0x00000069,0x00000022,0x00000000,0x00030047,0x0000006d, + 0x00000000,0x00040047,0x0000006d,0x00000021,0x0000000a,0x00040047,0x0000006d,0x00000022, + 0x00000000,0x00040047,0x00000146,0x00000001,0x00000003,0x00030047,0x0000017f,0x00000000, + 0x00040047,0x00000181,0x0000001e,0x00000002,0x00040047,0x00000187,0x0000001e,0x00000008, + 0x00030047,0x0000018d,0x0000000e,0x00040047,0x0000018d,0x0000001e,0x00000007,0x00030047, + 0x0000019b,0x00000000,0x00030047,0x0000019c,0x00000000,0x00030047,0x0000019d,0x00000000, + 0x00030047,0x000001a2,0x00000002,0x00050048,0x000001a2,0x00000000,0x00000023,0x00000040, + 0x00040047,0x000001a4,0x00000021,0x00000000,0x00040047,0x000001a4,0x00000022,0x00000000, + 0x00040047,0x000001ae,0x00000006,0x00000004,0x00030047,0x000001af,0x00000003,0x00050048, + 0x000001af,0x00000000,0x00000023,0x00000000,0x00040047,0x000001b1,0x00000021,0x00000007, + 0x00040047,0x000001b1,0x00000022,0x00000000,0x00040047,0x000001d8,0x0000001e,0x00000000, + 0x00030047,0x000001da,0x00000000,0x00030047,0x000001da,0x0000000e,0x00040047,0x000001da, + 0x0000001e,0x00000003,0x00030047,0x000001db,0x00000000,0x00030047,0x000001db,0x0000000e, + 0x00040047,0x000001db,0x0000001e,0x00000004,0x00040047,0x000001dc,0x0000001e,0x00000005, + 0x00030047,0x000001dd,0x00000000,0x00030047,0x000001dd,0x0000000e,0x00040047,0x000001dd, + 0x0000001e,0x00000006,0x00030047,0x000001f2,0x00000000,0x00030047,0x000001f6,0x00000000, + 0x00030047,0x00000203,0x00000000,0x00030047,0x0000020a,0x00000000,0x00030047,0x0000020d, + 0x00000000,0x00030047,0x0000020e,0x00000000,0x00030047,0x0000021f,0x00000000,0x00030047, + 0x00000222,0x00000000,0x00030047,0x0000022b,0x00000000,0x00030047,0x0000022c,0x00000000, + 0x00030047,0x00000231,0x00000000,0x00030047,0x00000232,0x00000000,0x00030047,0x0000023d, + 0x00000000,0x00030047,0x0000023e,0x00000000,0x00030047,0x00000247,0x00000000,0x00030047, + 0x00000249,0x00000000,0x00030047,0x0000024c,0x00000000,0x00030047,0x0000024d,0x00000000, + 0x00030047,0x0000025b,0x00000000,0x00030047,0x0000025e,0x00000000,0x00030047,0x00000264, + 0x00000000,0x00030047,0x00000265,0x00000000,0x00030047,0x00000266,0x00000000,0x00030047, + 0x00000267,0x00000000,0x00030047,0x00000268,0x00000000,0x00030047,0x00000269,0x00000000, + 0x00030047,0x0000026a,0x00000000,0x00030047,0x0000026b,0x00000000,0x00030047,0x0000026c, + 0x00000000,0x00030047,0x0000026d,0x00000000,0x00030047,0x0000026e,0x00000000,0x00030047, + 0x0000026f,0x00000000,0x00030047,0x00000270,0x00000000,0x00030047,0x00000271,0x00000000, + 0x00030047,0x00000272,0x00000000,0x00030047,0x00000273,0x00000000,0x00030047,0x00000274, + 0x00000000,0x00030047,0x00000275,0x00000000,0x00030047,0x00000276,0x00000000,0x00030047, + 0x00000277,0x00000000,0x00030047,0x00000278,0x00000000,0x00030047,0x00000279,0x00000000, + 0x00030047,0x00000280,0x00000000,0x00030047,0x00000283,0x00000000,0x00030047,0x00000284, + 0x00000000,0x00030047,0x00000286,0x00000000,0x00030047,0x00000287,0x00000000,0x00030047, + 0x00000288,0x00000000,0x00030047,0x00000289,0x00000000,0x00030047,0x0000028c,0x00000000, + 0x00030047,0x0000028d,0x00000000,0x00030047,0x0000028e,0x00000000,0x00030047,0x00000299, + 0x00000000,0x00030047,0x0000029a,0x00000000,0x00030047,0x0000029b,0x00000000,0x00030047, + 0x0000029c,0x00000000,0x00030047,0x0000029d,0x00000000,0x00030047,0x0000029e,0x00000000, + 0x00030047,0x000002a0,0x00000000,0x00030047,0x000002a1,0x00000000,0x00030047,0x000002a2, + 0x00000000,0x00030047,0x000002a3,0x00000000,0x00030047,0x000002a4,0x00000000,0x00030047, + 0x000002a5,0x00000000,0x00030047,0x000002a6,0x00000000,0x00030047,0x000002a7,0x00000000, + 0x00030047,0x000002a8,0x00000000,0x00030047,0x000002a9,0x00000000,0x00030047,0x000002aa, + 0x00000000,0x00030047,0x000002ab,0x00000000,0x00030047,0x000002ac,0x00000000,0x00030047, + 0x000002ad,0x00000000,0x00030047,0x000002ae,0x00000000,0x00030047,0x000002af,0x00000000, + 0x00030047,0x000002b2,0x00000000,0x00030047,0x000002b3,0x00000000,0x00030047,0x000002b5, + 0x00000000,0x00030047,0x000002b6,0x00000000,0x00030047,0x000002b9,0x00000000,0x00030047, + 0x000002ba,0x00000000,0x00030047,0x000002bc,0x00000000,0x00030047,0x000002bd,0x00000000, + 0x00030047,0x000002c0,0x00000000,0x00030047,0x000002c1,0x00000000,0x00030047,0x000002c3, + 0x00000000,0x00030047,0x000002c4,0x00000000,0x00030047,0x000002c7,0x00000000,0x00030047, + 0x000002c8,0x00000000,0x00030047,0x000002cf,0x00000000,0x00030047,0x000002d0,0x00000000, + 0x00030047,0x000002d1,0x00000000,0x00030047,0x000002d2,0x00000000,0x00030047,0x000002d3, + 0x00000000,0x00030047,0x000002d4,0x00000000,0x00030047,0x000002d5,0x00000000,0x00030047, + 0x000002d6,0x00000000,0x00030047,0x000002d7,0x00000000,0x00030047,0x000002d8,0x00000000, + 0x00030047,0x000002d9,0x00000000,0x00030047,0x000002da,0x00000000,0x00030047,0x000002db, + 0x00000000,0x00030047,0x000002dc,0x00000000,0x00030047,0x000002dd,0x00000000,0x00030047, + 0x000002df,0x00000000,0x00030047,0x000002e4,0x00000000,0x00030047,0x000002e5,0x00000000, + 0x00030047,0x000002e6,0x00000000,0x00030047,0x000002e8,0x00000000,0x00030047,0x000002ea, + 0x00000000,0x00030047,0x000002ec,0x00000000,0x00030047,0x000002ee,0x00000000,0x00030047, + 0x000002f0,0x00000000,0x00030047,0x000002f1,0x00000000,0x00030047,0x000002f2,0x00000000, + 0x00030047,0x000002f4,0x00000000,0x00030047,0x000002f6,0x00000000,0x00030047,0x000002f8, + 0x00000000,0x00030047,0x000002fa,0x00000000,0x00030047,0x000002fc,0x00000000,0x00030047, + 0x00000326,0x00000000,0x00030047,0x00000327,0x00000000,0x00030047,0x00000328,0x00000000, + 0x00030047,0x00000329,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017, + 0x00000008,0x00000006,0x00000004,0x00040020,0x00000010,0x00000007,0x00000008,0x00020014, + 0x00000011,0x00040015,0x00000023,0x00000020,0x00000000,0x00040017,0x00000024,0x00000023, + 0x00000002,0x00040020,0x00000025,0x00000007,0x00000024,0x00040020,0x00000026,0x00000007, + 0x00000023,0x0004002b,0x00000023,0x0000003b,0x00000000,0x0004002b,0x00000023,0x0000003e, + 0x00000001,0x0004002b,0x00000023,0x00000041,0x00000002,0x0004002b,0x00000023,0x00000044, + 0x00000003,0x0004002b,0x00000006,0x0000004b,0x00000000,0x0004002b,0x00000006,0x00000051, + 0xbfc00000,0x00090019,0x00000067,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x00000068,0x00000000,0x00000067,0x0004003b,0x00000068, + 0x00000069,0x00000000,0x0002001a,0x0000006b,0x00040020,0x0000006c,0x00000000,0x0000006b, + 0x0004003b,0x0000006c,0x0000006d,0x00000000,0x0003001b,0x0000006f,0x00000067,0x00040017, + 0x00000072,0x00000006,0x00000002,0x0004002b,0x00000006,0x0000007a,0x447a0000,0x0004002b, + 0x00000006,0x00000082,0x3e800000,0x0004002b,0x00000006,0x00000088,0xc0000000,0x0004002b, + 0x00000006,0x0000008e,0x3f19319f,0x0004002b,0x00000006,0x00000093,0x3e55e621,0x0004002b, + 0x00000006,0x00000094,0x3f206c99,0x0004002b,0x00000006,0x00000095,0x3f85afd5,0x0004002b, + 0x00000006,0x00000096,0x3fbb295d,0x0004002b,0x00000006,0x000000d3,0x40a311dd,0x0004002b, + 0x00000006,0x000000d5,0xc02311dd,0x0004002b,0x00000006,0x000000ef,0x3f800000,0x0004002b, + 0x00000006,0x000000f1,0x40400000,0x0004002b,0x00000023,0x00000113,0x00000005,0x0004002b, + 0x00000023,0x0000011b,0x00000400,0x0004002b,0x00000023,0x00000120,0x0000001f,0x0004002b, + 0x00000023,0x00000123,0x00000080,0x0004002b,0x00000023,0x00000129,0x00000010,0x0004002b, + 0x00000023,0x00000131,0x00000004,0x0004002b,0x00000006,0x0000013d,0x44800000,0x0004002b, + 0x00000006,0x0000013f,0x3f000000,0x00030030,0x00000011,0x00000146,0x00040020,0x00000180, + 0x00000001,0x00000008,0x0004003b,0x00000180,0x00000181,0x00000001,0x00040020,0x00000186, + 0x00000001,0x00000072,0x0004003b,0x00000186,0x00000187,0x00000001,0x00040020,0x0000018c, + 0x00000001,0x00000024,0x0004003b,0x0000018c,0x0000018d,0x00000001,0x00040020,0x0000018e, + 0x00000001,0x00000023,0x00040015,0x000001a0,0x00000020,0x00000001,0x0003001e,0x000001a2, + 0x00000023,0x00040020,0x000001a3,0x00000002,0x000001a2,0x0004003b,0x000001a3,0x000001a4, + 0x00000002,0x00040020,0x000001a6,0x00000002,0x00000023,0x0004002b,0x00000023,0x000001a9, + 0x00040000,0x0003001d,0x000001ae,0x00000023,0x0003001e,0x000001af,0x000001ae,0x00040020, + 0x000001b0,0x00000002,0x000001af,0x0004003b,0x000001b0,0x000001b1,0x00000002,0x0004002b, + 0x000001a0,0x000001b2,0x00000000,0x0004003b,0x00000180,0x000001d8,0x00000001,0x00040020, + 0x000001d9,0x00000001,0x00000006,0x0004003b,0x000001d9,0x000001da,0x00000001,0x0004003b, + 0x00000186,0x000001db,0x00000001,0x0004003b,0x00000180,0x000001dc,0x00000001,0x0004003b, + 0x000001d9,0x000001dd,0x00000001,0x0007002c,0x00000008,0x000001de,0x000000d5,0x000000d5, + 0x000000d5,0x000000d5,0x00040020,0x000001e4,0x00000007,0x00000011,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000026,0x00000323, + 0x00000007,0x0004003b,0x00000026,0x00000324,0x00000007,0x0004003b,0x00000026,0x000002fd, + 0x00000007,0x0004003b,0x00000026,0x000002fe,0x00000007,0x0004003b,0x00000010,0x000002f1, + 0x00000007,0x0004003b,0x00000010,0x000002f2,0x00000007,0x0004003b,0x00000010,0x000002e5, + 0x00000007,0x0004003b,0x00000010,0x000002e6,0x00000007,0x0004003b,0x00000007,0x00000264, + 0x00000007,0x0004003b,0x00000007,0x00000265,0x00000007,0x0004003b,0x00000007,0x00000266, + 0x00000007,0x0004003b,0x00000007,0x00000267,0x00000007,0x0004003b,0x00000007,0x00000268, + 0x00000007,0x0004003b,0x00000007,0x00000269,0x00000007,0x0004003b,0x00000007,0x0000026a, + 0x00000007,0x0004003b,0x00000010,0x0000026b,0x00000007,0x0004003b,0x00000007,0x0000026c, + 0x00000007,0x0004003b,0x00000007,0x0000026d,0x00000007,0x0004003b,0x00000007,0x0000026e, + 0x00000007,0x0004003b,0x00000007,0x0000026f,0x00000007,0x0004003b,0x00000010,0x00000270, + 0x00000007,0x0004003b,0x00000010,0x00000271,0x00000007,0x0004003b,0x00000007,0x00000272, + 0x00000007,0x0004003b,0x00000007,0x00000273,0x00000007,0x0004003b,0x00000007,0x00000274, + 0x00000007,0x0004003b,0x00000007,0x00000275,0x00000007,0x0004003b,0x00000010,0x00000276, + 0x00000007,0x0004003b,0x00000010,0x00000277,0x00000007,0x0004003b,0x00000007,0x00000278, + 0x00000007,0x0004003b,0x00000007,0x00000279,0x00000007,0x0004003b,0x000001e4,0x0000025f, + 0x00000007,0x0004003b,0x00000007,0x00000249,0x00000007,0x0004003b,0x00000010,0x0000024a, + 0x00000007,0x0004003b,0x00000010,0x0000024b,0x00000007,0x0004003b,0x00000007,0x0000024c, + 0x00000007,0x0004003b,0x00000007,0x0000024d,0x00000007,0x0004003b,0x00000007,0x00000228, + 0x00000007,0x0004003b,0x00000007,0x00000229,0x00000007,0x0004003b,0x00000007,0x0000022a, + 0x00000007,0x0004003b,0x00000007,0x0000022b,0x00000007,0x0004003b,0x00000007,0x0000022c, + 0x00000007,0x0004003b,0x000001e4,0x00000223,0x00000007,0x0004003b,0x00000007,0x0000020a, + 0x00000007,0x0004003b,0x00000010,0x0000020b,0x00000007,0x0004003b,0x00000010,0x0000020c, + 0x00000007,0x0004003b,0x00000007,0x0000020d,0x00000007,0x0004003b,0x00000007,0x0000020e, + 0x00000007,0x0004003b,0x000001e4,0x00000204,0x00000007,0x0004003b,0x00000007,0x000001f2, + 0x00000007,0x0004003b,0x00000010,0x000001f3,0x00000007,0x0004003b,0x00000010,0x000001f4, + 0x00000007,0x0004003b,0x00000010,0x000001f5,0x00000007,0x0004003b,0x00000007,0x000001f6, + 0x00000007,0x0004003b,0x00000007,0x0000017f,0x00000007,0x0004003b,0x00000010,0x00000182, + 0x00000007,0x0004003b,0x00000025,0x00000185,0x00000007,0x0004003b,0x00000026,0x0000018b, + 0x00000007,0x0004003b,0x00000026,0x00000191,0x00000007,0x0004003b,0x00000025,0x00000194, + 0x00000007,0x0004003b,0x00000026,0x00000196,0x00000007,0x0004003b,0x00000026,0x0000019a, + 0x00000007,0x0004003b,0x00000007,0x0000019d,0x00000007,0x0004003b,0x00000026,0x0000019f, + 0x00000007,0x0004003b,0x00000026,0x000001ad,0x00000007,0x0004003b,0x00000026,0x000001bd, + 0x00000007,0x0004003d,0x00000008,0x00000183,0x00000181,0x0003003e,0x00000182,0x00000183, + 0x000300f7,0x00000202,0x00000000,0x000300fb,0x0000003b,0x000001f8,0x000200f8,0x000001f8, + 0x0004003d,0x00000008,0x000001f9,0x00000182,0x0003003e,0x000001f3,0x000001f9,0x00050041, + 0x00000007,0x00000206,0x000001f3,0x0000003e,0x0004003d,0x00000006,0x00000207,0x00000206, + 0x000500be,0x00000011,0x00000208,0x00000207,0x0000004b,0x0003003e,0x00000204,0x00000208, + 0x0004003d,0x00000011,0x000001fa,0x00000204,0x000300f7,0x00000201,0x00000000,0x000400fa, + 0x000001fa,0x000001fb,0x000001fe,0x000200f8,0x000001fb,0x0004003d,0x00000008,0x000001fc, + 0x00000182,0x0003003e,0x000001f4,0x000001fc,0x000300f7,0x00000221,0x00000000,0x000300fb, + 0x0000003b,0x00000210,0x000200f8,0x00000210,0x000300f7,0x00000214,0x00000000,0x000400fa, + 0x00000146,0x00000211,0x00000214,0x000200f8,0x00000211,0x0004003d,0x00000008,0x00000212, + 0x000001f4,0x0003003e,0x0000020b,0x00000212,0x00050041,0x00000007,0x00000225,0x0000020b, + 0x0000003b,0x0004003d,0x00000006,0x00000226,0x00000225,0x000500b8,0x00000011,0x00000227, + 0x00000226,0x00000051,0x0003003e,0x00000223,0x00000227,0x0004003d,0x00000011,0x00000213, + 0x00000223,0x000200f9,0x00000214,0x000200f8,0x00000214,0x000700f5,0x00000011,0x00000215, + 0x00000146,0x00000210,0x00000213,0x00000211,0x000300f7,0x00000220,0x00000000,0x000400fa, + 0x00000215,0x00000216,0x00000219,0x000200f8,0x00000216,0x0004003d,0x00000008,0x00000217, + 0x000001f4,0x0003003e,0x0000020c,0x00000217,0x0003003e,0x00000228,0x000000ef,0x00050041, + 0x00000007,0x0000022e,0x0000020c,0x0000003b,0x0004003d,0x00000006,0x0000022f,0x0000022e, + 0x00050081,0x00000006,0x00000230,0x000000f1,0x0000022f,0x0003003e,0x00000229,0x00000230, + 0x0004003d,0x00000067,0x00000231,0x00000069,0x0004003d,0x0000006b,0x00000232,0x0000006d, + 0x00050056,0x0000006f,0x00000233,0x00000231,0x00000232,0x0004003d,0x00000006,0x00000234, + 0x00000229,0x00050050,0x00000072,0x00000235,0x00000234,0x0000004b,0x00070058,0x00000008, + 0x00000236,0x00000233,0x00000235,0x00000002,0x0000004b,0x00050051,0x00000006,0x00000237, + 0x00000236,0x00000000,0x0004003d,0x00000006,0x00000238,0x00000228,0x00050083,0x00000006, + 0x00000239,0x00000238,0x00000237,0x0003003e,0x00000228,0x00000239,0x00050041,0x00000007, + 0x0000023a,0x0000020c,0x0000003e,0x0004003d,0x00000006,0x0000023b,0x0000023a,0x00050083, + 0x00000006,0x0000023c,0x000000ef,0x0000023b,0x0003003e,0x0000022a,0x0000023c,0x0004003d, + 0x00000067,0x0000023d,0x00000069,0x0004003d,0x0000006b,0x0000023e,0x0000006d,0x00050056, + 0x0000006f,0x0000023f,0x0000023d,0x0000023e,0x0004003d,0x00000006,0x00000240,0x0000022a, + 0x00050050,0x00000072,0x00000241,0x00000240,0x0000004b,0x00070058,0x00000008,0x00000242, + 0x0000023f,0x00000241,0x00000002,0x0000004b,0x00050051,0x00000006,0x00000243,0x00000242, + 0x00000000,0x0004003d,0x00000006,0x00000244,0x00000228,0x00050083,0x00000006,0x00000245, + 0x00000244,0x00000243,0x0003003e,0x00000228,0x00000245,0x0004003d,0x00000006,0x00000246, + 0x00000228,0x0003003e,0x0000022b,0x00000246,0x0004003d,0x00000006,0x00000247,0x0000022b, + 0x0003003e,0x0000022c,0x00000247,0x0004003d,0x00000006,0x00000218,0x0000022c,0x0003003e, + 0x0000020a,0x00000218,0x000200f9,0x00000221,0x000200f8,0x00000219,0x00050041,0x00000007, + 0x0000021a,0x000001f4,0x0000003b,0x0004003d,0x00000006,0x0000021b,0x0000021a,0x00050041, + 0x00000007,0x0000021c,0x000001f4,0x0000003e,0x0004003d,0x00000006,0x0000021d,0x0000021c, + 0x0007000c,0x00000006,0x0000021e,0x00000001,0x00000025,0x0000021b,0x0000021d,0x0003003e, + 0x0000020d,0x0000021e,0x0004003d,0x00000006,0x0000021f,0x0000020d,0x0003003e,0x0000020a, + 0x0000021f,0x000200f9,0x00000221,0x000200f8,0x00000220,0x000200f9,0x00000221,0x000200f8, + 0x00000221,0x0004003d,0x00000006,0x00000222,0x0000020a,0x0003003e,0x0000020e,0x00000222, + 0x0004003d,0x00000006,0x000001fd,0x0000020e,0x0003003e,0x000001f2,0x000001fd,0x000200f9, + 0x00000202,0x000200f8,0x000001fe,0x0004003d,0x00000008,0x000001ff,0x00000182,0x0003003e, + 0x000001f5,0x000001ff,0x000300f7,0x0000025d,0x00000000,0x000300fb,0x0000003b,0x0000024f, + 0x000200f8,0x0000024f,0x000300f7,0x00000253,0x00000000,0x000400fa,0x00000146,0x00000250, + 0x00000253,0x000200f8,0x00000250,0x0004003d,0x00000008,0x00000251,0x000001f5,0x0003003e, + 0x0000024a,0x00000251,0x00050041,0x00000007,0x00000261,0x0000024a,0x0000003e,0x0004003d, + 0x00000006,0x00000262,0x00000261,0x000500b8,0x00000011,0x00000263,0x00000262,0x00000051, + 0x0003003e,0x0000025f,0x00000263,0x0004003d,0x00000011,0x00000252,0x0000025f,0x000200f9, + 0x00000253,0x000200f8,0x00000253,0x000700f5,0x00000011,0x00000254,0x00000146,0x0000024f, + 0x00000252,0x00000250,0x000300f7,0x0000025c,0x00000000,0x000400fa,0x00000254,0x00000255, + 0x00000258,0x000200f8,0x00000255,0x0004003d,0x00000008,0x00000256,0x000001f5,0x0003003e, + 0x0000024b,0x00000256,0x00050041,0x00000007,0x0000027b,0x0000024b,0x00000041,0x0004003d, + 0x00000006,0x0000027c,0x0000027b,0x0003003e,0x00000264,0x0000027c,0x00050041,0x00000007, + 0x0000027d,0x0000024b,0x00000044,0x0004003d,0x00000006,0x0000027e,0x0000027d,0x0007000c, + 0x00000006,0x0000027f,0x00000001,0x00000028,0x0000027e,0x0000004b,0x0003003e,0x00000265, + 0x0000027f,0x0004003d,0x00000006,0x00000280,0x00000264,0x000500be,0x00000011,0x00000281, + 0x00000280,0x0000004b,0x000300f7,0x0000028b,0x00000000,0x000400fa,0x00000281,0x00000282, + 0x0000028a,0x000200f8,0x00000282,0x0004003d,0x00000067,0x00000283,0x00000069,0x0004003d, + 0x0000006b,0x00000284,0x0000006d,0x00050056,0x0000006f,0x00000285,0x00000283,0x00000284, + 0x0004003d,0x00000006,0x00000286,0x00000265,0x00050050,0x00000072,0x00000287,0x00000286, + 0x0000004b,0x00070058,0x00000008,0x00000288,0x00000285,0x00000287,0x00000002,0x0000004b, + 0x00050051,0x00000006,0x00000289,0x00000288,0x00000000,0x0003003e,0x00000267,0x00000289, + 0x000200f9,0x0000028b,0x000200f8,0x0000028a,0x0003003e,0x00000267,0x0000004b,0x000200f9, + 0x0000028b,0x000200f8,0x0000028b,0x0004003d,0x00000006,0x0000028c,0x00000267,0x0003003e, + 0x00000266,0x0000028c,0x0004003d,0x00000006,0x0000028d,0x00000264,0x0006000c,0x00000006, + 0x0000028e,0x00000001,0x00000004,0x0000028d,0x000500b8,0x00000011,0x0000028f,0x0000028e, + 0x0000007a,0x000300f7,0x000002de,0x00000000,0x000400fa,0x0000028f,0x00000290,0x000002de, + 0x000200f8,0x00000290,0x00050041,0x00000007,0x00000291,0x0000024b,0x0000003b,0x0004003d, + 0x00000006,0x00000292,0x00000291,0x0006000c,0x00000006,0x00000293,0x00000001,0x00000004, + 0x00000292,0x00050083,0x00000006,0x00000294,0x00000293,0x00000082,0x0003003e,0x00000268, + 0x00000294,0x00050041,0x00000007,0x00000295,0x0000024b,0x0000003e,0x0004003d,0x00000006, + 0x00000296,0x00000295,0x00050083,0x00000006,0x00000298,0x00000088,0x00000296,0x0003003e, + 0x00000269,0x00000298,0x0004003d,0x00000006,0x00000299,0x00000269,0x0004003d,0x00000006, + 0x0000029a,0x00000265,0x00050083,0x00000006,0x0000029b,0x00000299,0x0000029a,0x00050085, + 0x00000006,0x0000029c,0x0000029b,0x0000008e,0x0003003e,0x0000026a,0x0000029c,0x0004003d, + 0x00000006,0x0000029d,0x00000265,0x0004003d,0x00000006,0x0000029e,0x0000026a,0x0003003e, + 0x0000026c,0x00000093,0x0003003e,0x0000026d,0x00000094,0x0003003e,0x0000026e,0x00000095, + 0x0003003e,0x0000026f,0x00000096,0x0004003d,0x00000006,0x000002e8,0x0000026c,0x00050041, + 0x00000007,0x000002e9,0x000002e5,0x0000003b,0x0003003e,0x000002e9,0x000002e8,0x0004003d, + 0x00000006,0x000002ea,0x0000026d,0x00050041,0x00000007,0x000002eb,0x000002e5,0x0000003e, + 0x0003003e,0x000002eb,0x000002ea,0x0004003d,0x00000006,0x000002ec,0x0000026e,0x00050041, + 0x00000007,0x000002ed,0x000002e5,0x00000041,0x0003003e,0x000002ed,0x000002ec,0x0004003d, + 0x00000006,0x000002ee,0x0000026f,0x00050041,0x00000007,0x000002ef,0x000002e5,0x00000044, + 0x0003003e,0x000002ef,0x000002ee,0x0004003d,0x00000008,0x000002f0,0x000002e5,0x0003003e, + 0x000002e6,0x000002f0,0x0004003d,0x00000008,0x0000029f,0x000002e6,0x0005008e,0x00000008, + 0x000002a0,0x0000029f,0x0000029e,0x00070050,0x00000008,0x000002a1,0x0000029d,0x0000029d, + 0x0000029d,0x0000029d,0x00050081,0x00000008,0x000002a2,0x000002a1,0x000002a0,0x0003003e, + 0x0000026b,0x000002a2,0x0004003d,0x00000008,0x000002a3,0x0000026b,0x0004003d,0x00000006, + 0x000002a4,0x00000264,0x0004007f,0x00000006,0x000002a5,0x000002a4,0x0005008e,0x00000008, + 0x000002a6,0x000002a3,0x000002a5,0x0004003d,0x00000006,0x000002a7,0x00000269,0x0004003d, + 0x00000006,0x000002a8,0x00000264,0x00050085,0x00000006,0x000002a9,0x000002a7,0x000002a8, + 0x0004003d,0x00000006,0x000002aa,0x00000268,0x00050081,0x00000006,0x000002ab,0x000002a9, + 0x000002aa,0x00070050,0x00000008,0x000002ac,0x000002ab,0x000002ab,0x000002ab,0x000002ab, + 0x00050081,0x00000008,0x000002ad,0x000002a6,0x000002ac,0x0003003e,0x00000270,0x000002ad, + 0x0004003d,0x00000067,0x000002ae,0x00000069,0x0004003d,0x0000006b,0x000002af,0x0000006d, + 0x00050056,0x0000006f,0x000002b0,0x000002ae,0x000002af,0x00050041,0x00000007,0x000002b1, + 0x00000270,0x0000003b,0x0004003d,0x00000006,0x000002b2,0x000002b1,0x00050050,0x00000072, + 0x000002b3,0x000002b2,0x0000004b,0x00070058,0x00000008,0x000002b4,0x000002b0,0x000002b3, + 0x00000002,0x0000004b,0x0004003d,0x00000067,0x000002b5,0x00000069,0x0004003d,0x0000006b, + 0x000002b6,0x0000006d,0x00050056,0x0000006f,0x000002b7,0x000002b5,0x000002b6,0x00050041, + 0x00000007,0x000002b8,0x00000270,0x0000003e,0x0004003d,0x00000006,0x000002b9,0x000002b8, + 0x00050050,0x00000072,0x000002ba,0x000002b9,0x0000004b,0x00070058,0x00000008,0x000002bb, + 0x000002b7,0x000002ba,0x00000002,0x0000004b,0x0004003d,0x00000067,0x000002bc,0x00000069, + 0x0004003d,0x0000006b,0x000002bd,0x0000006d,0x00050056,0x0000006f,0x000002be,0x000002bc, + 0x000002bd,0x00050041,0x00000007,0x000002bf,0x00000270,0x00000041,0x0004003d,0x00000006, + 0x000002c0,0x000002bf,0x00050050,0x00000072,0x000002c1,0x000002c0,0x0000004b,0x00070058, + 0x00000008,0x000002c2,0x000002be,0x000002c1,0x00000002,0x0000004b,0x0004003d,0x00000067, + 0x000002c3,0x00000069,0x0004003d,0x0000006b,0x000002c4,0x0000006d,0x00050056,0x0000006f, + 0x000002c5,0x000002c3,0x000002c4,0x00050041,0x00000007,0x000002c6,0x00000270,0x00000044, + 0x0004003d,0x00000006,0x000002c7,0x000002c6,0x00050050,0x00000072,0x000002c8,0x000002c7, + 0x0000004b,0x00070058,0x00000008,0x000002c9,0x000002c5,0x000002c8,0x00000002,0x0000004b, + 0x00050051,0x00000006,0x000002ca,0x000002b4,0x00000000,0x0003003e,0x00000272,0x000002ca, + 0x00050051,0x00000006,0x000002cb,0x000002bb,0x00000000,0x0003003e,0x00000273,0x000002cb, + 0x00050051,0x00000006,0x000002cc,0x000002c2,0x00000000,0x0003003e,0x00000274,0x000002cc, + 0x00050051,0x00000006,0x000002cd,0x000002c9,0x00000000,0x0003003e,0x00000275,0x000002cd, + 0x0004003d,0x00000006,0x000002f4,0x00000272,0x00050041,0x00000007,0x000002f5,0x000002f1, + 0x0000003b,0x0003003e,0x000002f5,0x000002f4,0x0004003d,0x00000006,0x000002f6,0x00000273, + 0x00050041,0x00000007,0x000002f7,0x000002f1,0x0000003e,0x0003003e,0x000002f7,0x000002f6, + 0x0004003d,0x00000006,0x000002f8,0x00000274,0x00050041,0x00000007,0x000002f9,0x000002f1, + 0x00000041,0x0003003e,0x000002f9,0x000002f8,0x0004003d,0x00000006,0x000002fa,0x00000275, + 0x00050041,0x00000007,0x000002fb,0x000002f1,0x00000044,0x0003003e,0x000002fb,0x000002fa, + 0x0004003d,0x00000008,0x000002fc,0x000002f1,0x0003003e,0x000002f2,0x000002fc,0x0004003d, + 0x00000008,0x000002ce,0x000002f2,0x0003003e,0x00000271,0x000002ce,0x0004003d,0x00000008, + 0x000002cf,0x0000026b,0x0005008e,0x00000008,0x000002d0,0x000002cf,0x000000d3,0x00050081, + 0x00000008,0x000002d1,0x000002d0,0x000001de,0x0003003e,0x00000276,0x000002d1,0x0004003d, + 0x00000008,0x000002d2,0x00000276,0x0004007f,0x00000008,0x000002d3,0x000002d2,0x0004003d, + 0x00000008,0x000002d4,0x00000276,0x00050085,0x00000008,0x000002d5,0x000002d3,0x000002d4, + 0x0006000c,0x00000008,0x000002d6,0x00000001,0x0000001d,0x000002d5,0x0003003e,0x00000277, + 0x000002d6,0x0004003d,0x00000008,0x000002d7,0x00000271,0x0004003d,0x00000008,0x000002d8, + 0x00000277,0x00050094,0x00000006,0x000002d9,0x000002d7,0x000002d8,0x0004003d,0x00000006, + 0x000002da,0x0000026a,0x00050085,0x00000006,0x000002db,0x000002d9,0x000002da,0x0004003d, + 0x00000006,0x000002dc,0x00000266,0x00050081,0x00000006,0x000002dd,0x000002dc,0x000002db, + 0x0003003e,0x00000266,0x000002dd,0x000200f9,0x000002de,0x000200f8,0x000002de,0x0004003d, + 0x00000006,0x000002df,0x00000266,0x00050041,0x00000007,0x000002e0,0x0000024b,0x0000003b, + 0x0004003d,0x00000006,0x000002e1,0x000002e0,0x0006000c,0x00000006,0x000002e2,0x00000001, + 0x00000006,0x000002e1,0x00050085,0x00000006,0x000002e3,0x000002df,0x000002e2,0x0003003e, + 0x00000278,0x000002e3,0x0004003d,0x00000006,0x000002e4,0x00000278,0x0003003e,0x00000279, + 0x000002e4,0x0004003d,0x00000006,0x00000257,0x00000279,0x0003003e,0x00000249,0x00000257, + 0x000200f9,0x0000025d,0x000200f8,0x00000258,0x00050041,0x00000007,0x00000259,0x000001f5, + 0x0000003b,0x0004003d,0x00000006,0x0000025a,0x00000259,0x0003003e,0x0000024c,0x0000025a, + 0x0004003d,0x00000006,0x0000025b,0x0000024c,0x0003003e,0x00000249,0x0000025b,0x000200f9, + 0x0000025d,0x000200f8,0x0000025c,0x000200f9,0x0000025d,0x000200f8,0x0000025d,0x0004003d, + 0x00000006,0x0000025e,0x00000249,0x0003003e,0x0000024d,0x0000025e,0x0004003d,0x00000006, + 0x00000200,0x0000024d,0x0003003e,0x000001f2,0x00000200,0x000200f9,0x00000202,0x000200f8, + 0x00000201,0x000200f9,0x00000202,0x000200f8,0x00000202,0x0004003d,0x00000006,0x00000203, + 0x000001f2,0x0003003e,0x000001f6,0x00000203,0x0004003d,0x00000006,0x00000184,0x000001f6, + 0x0003003e,0x0000017f,0x00000184,0x0004003d,0x00000072,0x00000188,0x00000187,0x0006000c, + 0x00000072,0x00000189,0x00000001,0x00000008,0x00000188,0x0004006d,0x00000024,0x0000018a, + 0x00000189,0x0003003e,0x00000185,0x0000018a,0x00050041,0x0000018e,0x0000018f,0x0000018d, + 0x0000003e,0x0004003d,0x00000023,0x00000190,0x0000018f,0x0003003e,0x0000018b,0x00000190, + 0x00050041,0x0000018e,0x00000192,0x0000018d,0x0000003b,0x0004003d,0x00000023,0x00000193, + 0x00000192,0x0004003d,0x00000024,0x00000195,0x00000185,0x0003003e,0x00000194,0x00000195, + 0x0004003d,0x00000023,0x00000197,0x0000018b,0x0003003e,0x00000196,0x00000197,0x00050041, + 0x00000026,0x00000300,0x00000194,0x0000003e,0x0004003d,0x00000023,0x00000301,0x00000300, + 0x000500c2,0x00000023,0x00000302,0x00000301,0x00000113,0x0004003d,0x00000023,0x00000303, + 0x00000196,0x000500c4,0x00000023,0x00000304,0x00000303,0x00000113,0x00050084,0x00000023, + 0x00000305,0x00000302,0x00000304,0x00050041,0x00000026,0x00000306,0x00000194,0x0000003b, + 0x0004003d,0x00000023,0x00000307,0x00000306,0x000500c2,0x00000023,0x00000308,0x00000307, + 0x00000113,0x00050084,0x00000023,0x00000309,0x00000308,0x0000011b,0x00050080,0x00000023, + 0x0000030a,0x00000305,0x00000309,0x0003003e,0x000002fd,0x0000030a,0x0004003d,0x00000023, + 0x0000030c,0x00000306,0x000500c7,0x00000023,0x0000030d,0x0000030c,0x00000120,0x000500c2, + 0x00000023,0x0000030e,0x0000030d,0x00000041,0x00050084,0x00000023,0x0000030f,0x0000030e, + 0x00000123,0x0004003d,0x00000023,0x00000311,0x00000300,0x000500c7,0x00000023,0x00000312, + 0x00000311,0x00000120,0x000500c2,0x00000023,0x00000313,0x00000312,0x00000041,0x00050084, + 0x00000023,0x00000314,0x00000313,0x00000129,0x00050080,0x00000023,0x00000315,0x0000030f, + 0x00000314,0x0004003d,0x00000023,0x00000316,0x000002fd,0x00050080,0x00000023,0x00000317, + 0x00000316,0x00000315,0x0003003e,0x000002fd,0x00000317,0x0004003d,0x00000023,0x00000319, + 0x00000300,0x000500c7,0x00000023,0x0000031a,0x00000319,0x00000044,0x00050084,0x00000023, + 0x0000031b,0x0000031a,0x00000131,0x0004003d,0x00000023,0x0000031d,0x00000306,0x000500c7, + 0x00000023,0x0000031e,0x0000031d,0x00000044,0x00050080,0x00000023,0x0000031f,0x0000031b, + 0x0000031e,0x0004003d,0x00000023,0x00000320,0x000002fd,0x00050080,0x00000023,0x00000321, + 0x00000320,0x0000031f,0x0003003e,0x000002fd,0x00000321,0x0004003d,0x00000023,0x00000322, + 0x000002fd,0x0003003e,0x000002fe,0x00000322,0x0004003d,0x00000023,0x00000198,0x000002fe, + 0x00050080,0x00000023,0x00000199,0x00000193,0x00000198,0x0003003e,0x00000191,0x00000199, + 0x0004003d,0x00000006,0x0000019b,0x0000017f,0x0006000c,0x00000006,0x0000019c,0x00000001, + 0x00000004,0x0000019b,0x0003003e,0x0000019d,0x0000019c,0x0004003d,0x00000006,0x00000326, + 0x0000019d,0x00050085,0x00000006,0x00000327,0x00000326,0x0000013d,0x00050081,0x00000006, + 0x00000328,0x00000327,0x0000013f,0x0004006d,0x00000023,0x00000329,0x00000328,0x0003003e, + 0x00000323,0x00000329,0x0004003d,0x00000023,0x0000032a,0x00000323,0x0003003e,0x00000324, + 0x0000032a,0x0004003d,0x00000023,0x0000019e,0x00000324,0x0003003e,0x0000019a,0x0000019e, + 0x00050041,0x000001a6,0x000001a7,0x000001a4,0x0000003b,0x0004003d,0x00000023,0x000001a8, + 0x000001a7,0x0004003d,0x00000023,0x000001aa,0x0000019a,0x00050082,0x00000023,0x000001ab, + 0x000001a9,0x000001aa,0x000500c5,0x00000023,0x000001ac,0x000001a8,0x000001ab,0x0003003e, + 0x0000019f,0x000001ac,0x0004003d,0x00000023,0x000001b3,0x00000191,0x00060041,0x000001a6, + 0x000001b4,0x000001b1,0x000001b2,0x000001b3,0x0004003d,0x00000023,0x000001b5,0x0000019f, + 0x000700ef,0x00000023,0x000001b6,0x000001b4,0x0000003e,0x0000003b,0x000001b5,0x0003003e, + 0x000001ad,0x000001b6,0x0004003d,0x00000023,0x000001b7,0x000001ad,0x000500ae,0x00000011, + 0x000001ba,0x000001b7,0x000001a8,0x000300f7,0x000001bc,0x00000000,0x000400fa,0x000001ba, + 0x000001bb,0x000001bc,0x000200f8,0x000001bb,0x0004003d,0x00000023,0x000001be,0x000001ad, + 0x0004003d,0x00000023,0x000001bf,0x000001ad,0x0004003d,0x00000023,0x000001c0,0x0000019f, + 0x0007000c,0x00000023,0x000001c1,0x00000001,0x00000029,0x000001bf,0x000001c0,0x00050082, + 0x00000023,0x000001c2,0x000001be,0x000001c1,0x0003003e,0x000001bd,0x000001c2,0x0004003d, + 0x00000023,0x000001c3,0x00000191,0x00060041,0x000001a6,0x000001c4,0x000001b1,0x000001b2, + 0x000001c3,0x0004003d,0x00000023,0x000001c5,0x000001bd,0x0004003d,0x00000023,0x000001c6, + 0x0000019a,0x00050082,0x00000023,0x000001c7,0x000001c5,0x000001c6,0x000700ea,0x00000023, + 0x000001c8,0x000001c4,0x0000003e,0x0000003b,0x000001c7,0x000200f9,0x000001bc,0x000200f8, + 0x000001bc,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..07cf4eb8e5398f9ff5fbbe048f86954f67eef9d9 GIT binary patch literal 11212 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.h new file mode 100644 index 000000000..5c365acba --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.h @@ -0,0 +1,250 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_clip_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000001a8,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000f000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000007f,0x00000089,0x00000092, + 0x000000fd,0x00000101,0x0000011f,0x00000120,0x00000121,0x00000122,0x00000123,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x0000007d,0x00003071,0x00030005,0x0000007f,0x00000049,0x00030005,0x00000084, + 0x00006751,0x00030005,0x00000087,0x0000374e,0x00030005,0x00000089,0x00003361,0x00030005, + 0x0000008d,0x00003154,0x00030005,0x00000092,0x00003469,0x00040005,0x00000096,0x61726170, + 0x0000006d,0x00040005,0x00000097,0x61726170,0x0000006d,0x00030005,0x0000009b,0x00003170, + 0x00030005,0x0000009d,0x00006454,0x00040006,0x0000009d,0x00000000,0x00003464,0x00030005, + 0x0000009f,0x00003053,0x00030005,0x000000ac,0x0000424d,0x00040006,0x000000ac,0x00000000, + 0x00003157,0x00030005,0x000000ae,0x0000006b,0x00030005,0x000000bf,0x00006159,0x00030005, + 0x000000c2,0x00006456,0x00030005,0x000000c4,0x00003967,0x00030005,0x000000cc,0x0000374f, + 0x00040005,0x000000d1,0x61726170,0x0000006d,0x00030005,0x000000d5,0x00003363,0x00040005, + 0x000000e6,0x61726170,0x0000006d,0x00030005,0x000000ed,0x0000615a,0x00040005,0x000000f2, + 0x61726170,0x0000006d,0x00040005,0x000000f5,0x61726170,0x0000006d,0x00030005,0x000000fd, + 0x00003065,0x00040005,0x000000fe,0x61726170,0x0000006d,0x00030005,0x00000101,0x0000316d, + 0x00040005,0x00000102,0x61726170,0x0000006d,0x00040005,0x00000105,0x61726170,0x0000006d, + 0x00040005,0x00000108,0x61726170,0x0000006d,0x00030005,0x0000011f,0x0000316b,0x00030005, + 0x00000120,0x0000307a,0x00030005,0x00000121,0x00003153,0x00030005,0x00000122,0x0000304e, + 0x00030005,0x00000123,0x00003159,0x00030047,0x0000007d,0x00000000,0x00040047,0x0000007f, + 0x0000001e,0x00000002,0x00040047,0x00000084,0x00000001,0x0000000a,0x00030047,0x00000089, + 0x0000000e,0x00040047,0x00000089,0x0000001e,0x00000007,0x00040047,0x00000092,0x0000001e, + 0x00000008,0x00040047,0x0000009c,0x00000006,0x00000004,0x00030047,0x0000009d,0x00000003, + 0x00050048,0x0000009d,0x00000000,0x00000023,0x00000000,0x00040047,0x0000009f,0x00000021, + 0x00000007,0x00040047,0x0000009f,0x00000022,0x00000000,0x00030047,0x000000a5,0x00000000, + 0x00030047,0x000000ac,0x00000002,0x00050048,0x000000ac,0x00000000,0x00000023,0x00000040, + 0x00040047,0x000000ae,0x00000021,0x00000000,0x00040047,0x000000ae,0x00000022,0x00000000, + 0x00030047,0x000000bf,0x00000000,0x00030047,0x000000c2,0x00000000,0x00030047,0x000000c3, + 0x00000000,0x00030047,0x000000c4,0x00000000,0x00030047,0x000000c5,0x00000000,0x00030047, + 0x000000cf,0x00000000,0x00030047,0x000000d0,0x00000000,0x00030047,0x000000d1,0x00000000, + 0x00030047,0x000000e9,0x00000000,0x00030047,0x000000f0,0x00000000,0x00030047,0x000000f1, + 0x00000000,0x00030047,0x000000f2,0x00000000,0x00030047,0x000000f8,0x00000000,0x00030047, + 0x000000f9,0x00000000,0x00030047,0x000000fa,0x00000000,0x00030047,0x000000fb,0x00000000, + 0x00030047,0x000000fd,0x00000000,0x00040047,0x000000fd,0x0000001e,0x00000001,0x00030047, + 0x000000fe,0x00000000,0x00030047,0x000000ff,0x00000000,0x00030047,0x00000101,0x00000000, + 0x00040047,0x00000101,0x0000001e,0x00000000,0x00030047,0x00000102,0x00000000,0x00030047, + 0x00000105,0x00000000,0x00030047,0x00000106,0x00000000,0x00030047,0x00000108,0x00000000, + 0x00040047,0x0000011f,0x0000001e,0x00000000,0x00030047,0x00000120,0x00000000,0x00030047, + 0x00000120,0x0000000e,0x00040047,0x00000120,0x0000001e,0x00000003,0x00030047,0x00000121, + 0x00000000,0x00030047,0x00000121,0x0000000e,0x00040047,0x00000121,0x0000001e,0x00000004, + 0x00040047,0x00000122,0x0000001e,0x00000005,0x00030047,0x00000123,0x00000000,0x00030047, + 0x00000123,0x0000000e,0x00040047,0x00000123,0x0000001e,0x00000006,0x00030047,0x0000014d, + 0x00000000,0x00030047,0x0000014e,0x00000000,0x00030047,0x0000014f,0x00000000,0x00030047, + 0x00000150,0x00000000,0x00030047,0x00000153,0x00000000,0x00030047,0x0000015a,0x00000000, + 0x00030047,0x0000015b,0x00000000,0x00030047,0x0000015c,0x00000000,0x00030047,0x00000160, + 0x00000000,0x00030047,0x00000164,0x00000000,0x00030047,0x00000165,0x00000000,0x00030047, + 0x00000166,0x00000000,0x00030047,0x00000167,0x00000000,0x00030047,0x0000016a,0x00000000, + 0x00030047,0x00000171,0x00000000,0x00030047,0x00000172,0x00000000,0x00030047,0x00000173, + 0x00000000,0x00030047,0x00000177,0x00000000,0x00030047,0x00000178,0x00000000,0x00030047, + 0x00000179,0x00000000,0x00030047,0x0000017b,0x00000000,0x00030047,0x0000017d,0x00000000, + 0x00030047,0x0000017f,0x00000000,0x00030047,0x00000181,0x00000000,0x00030047,0x00000183, + 0x00000000,0x00030047,0x00000184,0x00000000,0x00030047,0x00000185,0x00000000,0x00030047, + 0x00000187,0x00000000,0x00030047,0x00000189,0x00000000,0x00030047,0x0000018b,0x00000000, + 0x00030047,0x0000018d,0x00000000,0x00030047,0x0000018f,0x00000000,0x00030047,0x00000190, + 0x00000000,0x00030047,0x00000191,0x00000000,0x00030047,0x00000193,0x00000000,0x00030047, + 0x00000195,0x00000000,0x00030047,0x00000197,0x00000000,0x00030047,0x00000199,0x00000000, + 0x00030047,0x0000019b,0x00000000,0x00030047,0x0000019c,0x00000000,0x00030047,0x0000019d, + 0x00000000,0x00030047,0x0000019f,0x00000000,0x00030047,0x000001a1,0x00000000,0x00030047, + 0x000001a3,0x00000000,0x00030047,0x000001a5,0x00000000,0x00030047,0x000001a7,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020, + 0x00000001,0x00040020,0x00000007,0x00000007,0x00000006,0x00030016,0x00000008,0x00000020, + 0x00040020,0x0000000d,0x00000007,0x00000008,0x00040017,0x0000000e,0x00000008,0x00000004, + 0x00040015,0x00000013,0x00000020,0x00000000,0x00040017,0x00000014,0x00000013,0x00000002, + 0x00040020,0x00000015,0x00000007,0x00000014,0x00040020,0x00000016,0x00000007,0x00000013, + 0x00040020,0x0000002a,0x00000007,0x0000000e,0x0004002b,0x00000013,0x0000002d,0x00000000, + 0x0004002b,0x00000013,0x00000030,0x00000001,0x0004002b,0x00000013,0x00000033,0x00000002, + 0x0004002b,0x00000013,0x00000036,0x00000003,0x0004002b,0x00000013,0x0000003e,0x00000005, + 0x0004002b,0x00000013,0x00000046,0x00000400,0x0004002b,0x00000013,0x0000004b,0x0000001f, + 0x0004002b,0x00000013,0x0000004e,0x00000080,0x0004002b,0x00000013,0x00000054,0x00000010, + 0x0004002b,0x00000013,0x0000005c,0x00000004,0x0004002b,0x00000013,0x00000068,0x0007ffff, + 0x0004002b,0x00000013,0x0000006a,0x00040000,0x0004002b,0x00000008,0x0000006f,0x3a800000, + 0x0004002b,0x00000008,0x00000074,0x44800000,0x0004002b,0x00000008,0x00000076,0x3f000000, + 0x00040020,0x0000007e,0x00000001,0x0000000e,0x0004003b,0x0000007e,0x0000007f,0x00000001, + 0x00040020,0x00000080,0x00000001,0x00000008,0x00020014,0x00000083,0x00030030,0x00000083, + 0x00000084,0x00040020,0x00000088,0x00000001,0x00000014,0x0004003b,0x00000088,0x00000089, + 0x00000001,0x00040020,0x0000008a,0x00000001,0x00000013,0x00040017,0x00000090,0x00000008, + 0x00000002,0x00040020,0x00000091,0x00000001,0x00000090,0x0004003b,0x00000091,0x00000092, + 0x00000001,0x0003001d,0x0000009c,0x00000013,0x0003001e,0x0000009d,0x0000009c,0x00040020, + 0x0000009e,0x00000002,0x0000009d,0x0004003b,0x0000009e,0x0000009f,0x00000002,0x0004002b, + 0x00000006,0x000000a0,0x00000000,0x00040020,0x000000a2,0x00000002,0x00000013,0x0004002b, + 0x00000008,0x000000a6,0x3f800000,0x0003001e,0x000000ac,0x00000013,0x00040020,0x000000ad, + 0x00000002,0x000000ac,0x0004003b,0x000000ad,0x000000ae,0x00000002,0x0004002b,0x00000008, + 0x000000c0,0x00000000,0x00040020,0x000000fc,0x00000003,0x0000000e,0x0004003b,0x000000fc, + 0x000000fd,0x00000003,0x0004003b,0x000000fc,0x00000101,0x00000003,0x0004003b,0x0000007e, + 0x0000011f,0x00000001,0x0004003b,0x00000080,0x00000120,0x00000001,0x0004003b,0x00000091, + 0x00000121,0x00000001,0x0004003b,0x0000007e,0x00000122,0x00000001,0x0004003b,0x00000080, + 0x00000123,0x00000001,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003b,0x0000002a,0x0000019c,0x00000007,0x0004003b,0x0000002a,0x0000019d, + 0x00000007,0x0004003b,0x0000002a,0x00000190,0x00000007,0x0004003b,0x0000002a,0x00000191, + 0x00000007,0x0004003b,0x0000002a,0x00000184,0x00000007,0x0004003b,0x0000002a,0x00000185, + 0x00000007,0x0004003b,0x0000002a,0x00000178,0x00000007,0x0004003b,0x0000002a,0x00000179, + 0x00000007,0x0004003b,0x0000000d,0x00000172,0x00000007,0x0004003b,0x0000000d,0x00000173, + 0x00000007,0x0004003b,0x00000007,0x00000169,0x00000007,0x0004003b,0x0000000d,0x0000016a, + 0x00000007,0x0004003b,0x00000016,0x00000161,0x00000007,0x0004003b,0x00000016,0x00000162, + 0x00000007,0x0004003b,0x0000000d,0x0000015b,0x00000007,0x0004003b,0x0000000d,0x0000015c, + 0x00000007,0x0004003b,0x00000007,0x00000152,0x00000007,0x0004003b,0x0000000d,0x00000153, + 0x00000007,0x0004003b,0x00000016,0x0000014a,0x00000007,0x0004003b,0x00000016,0x0000014b, + 0x00000007,0x0004003b,0x00000016,0x00000124,0x00000007,0x0004003b,0x00000016,0x00000125, + 0x00000007,0x0004003b,0x0000000d,0x0000007d,0x00000007,0x0004003b,0x00000016,0x00000087, + 0x00000007,0x0004003b,0x00000016,0x0000008d,0x00000007,0x0004003b,0x00000015,0x00000096, + 0x00000007,0x0004003b,0x00000016,0x00000097,0x00000007,0x0004003b,0x00000016,0x0000009b, + 0x00000007,0x0004003b,0x0000000d,0x000000bf,0x00000007,0x0004003b,0x0000000d,0x000000c2, + 0x00000007,0x0004003b,0x0000000d,0x000000c4,0x00000007,0x0004003b,0x00000016,0x000000cc, + 0x00000007,0x0004003b,0x0000000d,0x000000d1,0x00000007,0x0004003b,0x00000016,0x000000d5, + 0x00000007,0x0004003b,0x00000016,0x000000e6,0x00000007,0x0004003b,0x00000016,0x000000ed, + 0x00000007,0x0004003b,0x0000000d,0x000000f2,0x00000007,0x0004003b,0x00000016,0x000000f5, + 0x00000007,0x0004003b,0x0000000d,0x000000fe,0x00000007,0x0004003b,0x0000000d,0x00000102, + 0x00000007,0x0004003b,0x0000000d,0x00000105,0x00000007,0x0004003b,0x0000000d,0x00000108, + 0x00000007,0x00050041,0x00000080,0x00000081,0x0000007f,0x0000002d,0x0004003d,0x00000008, + 0x00000082,0x00000081,0x0003003e,0x0000007d,0x00000082,0x000300f7,0x00000086,0x00000000, + 0x000400fa,0x00000084,0x00000085,0x00000104,0x000200f8,0x00000085,0x00050041,0x0000008a, + 0x0000008b,0x00000089,0x00000030,0x0004003d,0x00000013,0x0000008c,0x0000008b,0x0003003e, + 0x00000087,0x0000008c,0x00050041,0x0000008a,0x0000008e,0x00000089,0x0000002d,0x0004003d, + 0x00000013,0x0000008f,0x0000008e,0x0004003d,0x00000090,0x00000093,0x00000092,0x0006000c, + 0x00000090,0x00000094,0x00000001,0x00000008,0x00000093,0x0004006d,0x00000014,0x00000095, + 0x00000094,0x0003003e,0x00000096,0x00000095,0x0004003d,0x00000013,0x00000098,0x00000087, + 0x0003003e,0x00000097,0x00000098,0x00050041,0x00000016,0x00000127,0x00000096,0x00000030, + 0x0004003d,0x00000013,0x00000128,0x00000127,0x000500c2,0x00000013,0x00000129,0x00000128, + 0x0000003e,0x0004003d,0x00000013,0x0000012a,0x00000097,0x000500c4,0x00000013,0x0000012b, + 0x0000012a,0x0000003e,0x00050084,0x00000013,0x0000012c,0x00000129,0x0000012b,0x00050041, + 0x00000016,0x0000012d,0x00000096,0x0000002d,0x0004003d,0x00000013,0x0000012e,0x0000012d, + 0x000500c2,0x00000013,0x0000012f,0x0000012e,0x0000003e,0x00050084,0x00000013,0x00000130, + 0x0000012f,0x00000046,0x00050080,0x00000013,0x00000131,0x0000012c,0x00000130,0x0003003e, + 0x00000124,0x00000131,0x0004003d,0x00000013,0x00000133,0x0000012d,0x000500c7,0x00000013, + 0x00000134,0x00000133,0x0000004b,0x000500c2,0x00000013,0x00000135,0x00000134,0x00000033, + 0x00050084,0x00000013,0x00000136,0x00000135,0x0000004e,0x0004003d,0x00000013,0x00000138, + 0x00000127,0x000500c7,0x00000013,0x00000139,0x00000138,0x0000004b,0x000500c2,0x00000013, + 0x0000013a,0x00000139,0x00000033,0x00050084,0x00000013,0x0000013b,0x0000013a,0x00000054, + 0x00050080,0x00000013,0x0000013c,0x00000136,0x0000013b,0x0004003d,0x00000013,0x0000013d, + 0x00000124,0x00050080,0x00000013,0x0000013e,0x0000013d,0x0000013c,0x0003003e,0x00000124, + 0x0000013e,0x0004003d,0x00000013,0x00000140,0x00000127,0x000500c7,0x00000013,0x00000141, + 0x00000140,0x00000036,0x00050084,0x00000013,0x00000142,0x00000141,0x0000005c,0x0004003d, + 0x00000013,0x00000144,0x0000012d,0x000500c7,0x00000013,0x00000145,0x00000144,0x00000036, + 0x00050080,0x00000013,0x00000146,0x00000142,0x00000145,0x0004003d,0x00000013,0x00000147, + 0x00000124,0x00050080,0x00000013,0x00000148,0x00000147,0x00000146,0x0003003e,0x00000124, + 0x00000148,0x0004003d,0x00000013,0x00000149,0x00000124,0x0003003e,0x00000125,0x00000149, + 0x0004003d,0x00000013,0x00000099,0x00000125,0x00050080,0x00000013,0x0000009a,0x0000008f, + 0x00000099,0x0003003e,0x0000008d,0x0000009a,0x0004003d,0x00000013,0x000000a1,0x0000008d, + 0x00060041,0x000000a2,0x000000a3,0x0000009f,0x000000a0,0x000000a1,0x0004003d,0x00000013, + 0x000000a4,0x000000a3,0x0003003e,0x0000009b,0x000000a4,0x0004003d,0x00000008,0x000000a5, + 0x0000007d,0x000500be,0x00000083,0x000000a7,0x000000a5,0x000000a6,0x000300f7,0x000000a9, + 0x00000000,0x000400fa,0x000000a7,0x000000a8,0x000000a9,0x000200f8,0x000000a8,0x0004003d, + 0x00000013,0x000000aa,0x0000009b,0x00050041,0x000000a2,0x000000b0,0x000000ae,0x0000002d, + 0x0004003d,0x00000013,0x000000b1,0x000000b0,0x000500b0,0x00000083,0x000000b2,0x000000aa, + 0x000000b1,0x000400a8,0x00000083,0x000000b3,0x000000b2,0x000300f7,0x000000b5,0x00000000, + 0x000400fa,0x000000b3,0x000000b4,0x000000b5,0x000200f8,0x000000b4,0x0004003d,0x00000013, + 0x000000b6,0x0000009b,0x000500c5,0x00000013,0x000000b9,0x000000b1,0x0000006a,0x000500ae, + 0x00000083,0x000000ba,0x000000b6,0x000000b9,0x000200f9,0x000000b5,0x000200f8,0x000000b5, + 0x000700f5,0x00000083,0x000000bb,0x000000b2,0x000000a8,0x000000ba,0x000000b4,0x000200f9, + 0x000000a9,0x000200f8,0x000000a9,0x000700f5,0x00000083,0x000000bc,0x000000a7,0x00000085, + 0x000000bb,0x000000b5,0x000300f7,0x000000be,0x00000000,0x000400fa,0x000000bc,0x000000bd, + 0x000000c1,0x000200f8,0x000000bd,0x0003003e,0x000000bf,0x000000c0,0x000200f9,0x000000be, + 0x000200f8,0x000000c1,0x0004003d,0x00000008,0x000000c3,0x0000007d,0x0003003e,0x000000c2, + 0x000000c3,0x0004003d,0x00000008,0x000000c5,0x0000007d,0x0003003e,0x000000c4,0x000000c5, + 0x0004003d,0x00000013,0x000000c6,0x0000009b,0x00050041,0x000000a2,0x000000c7,0x000000ae, + 0x0000002d,0x0004003d,0x00000013,0x000000c8,0x000000c7,0x000500b0,0x00000083,0x000000c9, + 0x000000c6,0x000000c8,0x000300f7,0x000000cb,0x00000000,0x000400fa,0x000000c9,0x000000ca, + 0x000000cb,0x000200f8,0x000000ca,0x0004003d,0x00000008,0x000000cf,0x0000007d,0x0006000c, + 0x00000008,0x000000d0,0x00000001,0x00000004,0x000000cf,0x0003003e,0x000000d1,0x000000d0, + 0x0004003d,0x00000008,0x0000014d,0x000000d1,0x00050085,0x00000008,0x0000014e,0x0000014d, + 0x00000074,0x00050081,0x00000008,0x0000014f,0x0000014e,0x00000076,0x0004006d,0x00000013, + 0x00000150,0x0000014f,0x0003003e,0x0000014a,0x00000150,0x0004003d,0x00000013,0x00000151, + 0x0000014a,0x0003003e,0x0000014b,0x00000151,0x0004003d,0x00000013,0x000000d2,0x0000014b, + 0x00050080,0x00000013,0x000000d3,0x0000006a,0x000000d2,0x000500c5,0x00000013,0x000000d4, + 0x000000c8,0x000000d3,0x0003003e,0x000000cc,0x000000d4,0x0004003d,0x00000013,0x000000d6, + 0x0000008d,0x00060041,0x000000a2,0x000000d7,0x0000009f,0x000000a0,0x000000d6,0x0004003d, + 0x00000013,0x000000d8,0x000000cc,0x000700ef,0x00000013,0x000000d9,0x000000d7,0x00000030, + 0x0000002d,0x000000d8,0x0003003e,0x000000d5,0x000000d9,0x0004003d,0x00000013,0x000000da, + 0x000000d5,0x000500b2,0x00000083,0x000000dd,0x000000da,0x000000c8,0x000300f7,0x000000df, + 0x00000000,0x000400fa,0x000000dd,0x000000de,0x000000e0,0x000200f8,0x000000de,0x0003003e, + 0x000000c4,0x000000c0,0x000200f9,0x000000df,0x000200f8,0x000000e0,0x0004003d,0x00000013, + 0x000000e1,0x000000d5,0x0004003d,0x00000013,0x000000e2,0x000000cc,0x000500b0,0x00000083, + 0x000000e3,0x000000e1,0x000000e2,0x000300f7,0x000000e5,0x00000000,0x000400fa,0x000000e3, + 0x000000e4,0x000000e5,0x000200f8,0x000000e4,0x0004003d,0x00000013,0x000000e7,0x000000d5, + 0x0003003e,0x000000e6,0x000000e7,0x0004003d,0x00000013,0x00000155,0x000000e6,0x000500c7, + 0x00000013,0x00000156,0x00000155,0x00000068,0x00050082,0x00000013,0x00000157,0x00000156, + 0x0000006a,0x0004007c,0x00000006,0x00000158,0x00000157,0x0003003e,0x00000152,0x00000158, + 0x0004003d,0x00000006,0x0000015e,0x00000152,0x0004006f,0x00000008,0x0000015f,0x0000015e, + 0x0003003e,0x0000015b,0x0000015f,0x0004003d,0x00000008,0x00000160,0x0000015b,0x0003003e, + 0x0000015c,0x00000160,0x0004003d,0x00000008,0x00000159,0x0000015c,0x00050085,0x00000008, + 0x0000015a,0x00000159,0x0000006f,0x0003003e,0x00000153,0x0000015a,0x0004003d,0x00000008, + 0x000000e8,0x00000153,0x0003003e,0x000000c4,0x000000e8,0x000200f9,0x000000e5,0x000200f8, + 0x000000e5,0x000200f9,0x000000df,0x000200f8,0x000000df,0x000200f9,0x000000cb,0x000200f8, + 0x000000cb,0x0004003d,0x00000008,0x000000e9,0x000000c4,0x000500ba,0x00000083,0x000000ea, + 0x000000e9,0x000000c0,0x000300f7,0x000000ec,0x00000000,0x000400fa,0x000000ea,0x000000eb, + 0x000000ec,0x000200f8,0x000000eb,0x0004003d,0x00000013,0x000000ee,0x0000008d,0x00060041, + 0x000000a2,0x000000ef,0x0000009f,0x000000a0,0x000000ee,0x0004003d,0x00000008,0x000000f0, + 0x000000c4,0x0006000c,0x00000008,0x000000f1,0x00000001,0x00000004,0x000000f0,0x0003003e, + 0x000000f2,0x000000f1,0x0004003d,0x00000008,0x00000164,0x000000f2,0x00050085,0x00000008, + 0x00000165,0x00000164,0x00000074,0x00050081,0x00000008,0x00000166,0x00000165,0x00000076, + 0x0004006d,0x00000013,0x00000167,0x00000166,0x0003003e,0x00000161,0x00000167,0x0004003d, + 0x00000013,0x00000168,0x00000161,0x0003003e,0x00000162,0x00000168,0x0004003d,0x00000013, + 0x000000f3,0x00000162,0x000700ea,0x00000013,0x000000f4,0x000000ef,0x00000030,0x0000002d, + 0x000000f3,0x0003003e,0x000000ed,0x000000f4,0x0004003d,0x00000013,0x000000f6,0x000000ed, + 0x0003003e,0x000000f5,0x000000f6,0x0004003d,0x00000013,0x0000016c,0x000000f5,0x000500c7, + 0x00000013,0x0000016d,0x0000016c,0x00000068,0x00050082,0x00000013,0x0000016e,0x0000016d, + 0x0000006a,0x0004007c,0x00000006,0x0000016f,0x0000016e,0x0003003e,0x00000169,0x0000016f, + 0x0004003d,0x00000006,0x00000175,0x00000169,0x0004006f,0x00000008,0x00000176,0x00000175, + 0x0003003e,0x00000172,0x00000176,0x0004003d,0x00000008,0x00000177,0x00000172,0x0003003e, + 0x00000173,0x00000177,0x0004003d,0x00000008,0x00000170,0x00000173,0x00050085,0x00000008, + 0x00000171,0x00000170,0x0000006f,0x0003003e,0x0000016a,0x00000171,0x0004003d,0x00000008, + 0x000000f7,0x0000016a,0x0004003d,0x00000008,0x000000f8,0x0000007d,0x00050081,0x00000008, + 0x000000f9,0x000000f7,0x000000f8,0x0003003e,0x000000c2,0x000000f9,0x000200f9,0x000000ec, + 0x000200f8,0x000000ec,0x0004003d,0x00000008,0x000000fa,0x000000c2,0x00050083,0x00000008, + 0x000000fb,0x000000a6,0x000000fa,0x0003003e,0x000000bf,0x000000fb,0x000200f9,0x000000be, + 0x000200f8,0x000000be,0x0004003d,0x00000008,0x000000ff,0x000000bf,0x0003003e,0x000000fe, + 0x000000ff,0x0004003d,0x00000008,0x0000017b,0x000000fe,0x00050041,0x0000000d,0x0000017c, + 0x00000178,0x0000002d,0x0003003e,0x0000017c,0x0000017b,0x0004003d,0x00000008,0x0000017d, + 0x000000fe,0x00050041,0x0000000d,0x0000017e,0x00000178,0x00000030,0x0003003e,0x0000017e, + 0x0000017d,0x0004003d,0x00000008,0x0000017f,0x000000fe,0x00050041,0x0000000d,0x00000180, + 0x00000178,0x00000033,0x0003003e,0x00000180,0x0000017f,0x0004003d,0x00000008,0x00000181, + 0x000000fe,0x00050041,0x0000000d,0x00000182,0x00000178,0x00000036,0x0003003e,0x00000182, + 0x00000181,0x0004003d,0x0000000e,0x00000183,0x00000178,0x0003003e,0x00000179,0x00000183, + 0x0004003d,0x0000000e,0x00000100,0x00000179,0x0003003e,0x000000fd,0x00000100,0x0003003e, + 0x00000102,0x000000a6,0x0004003d,0x00000008,0x00000187,0x00000102,0x00050041,0x0000000d, + 0x00000188,0x00000184,0x0000002d,0x0003003e,0x00000188,0x00000187,0x0004003d,0x00000008, + 0x00000189,0x00000102,0x00050041,0x0000000d,0x0000018a,0x00000184,0x00000030,0x0003003e, + 0x0000018a,0x00000189,0x0004003d,0x00000008,0x0000018b,0x00000102,0x00050041,0x0000000d, + 0x0000018c,0x00000184,0x00000033,0x0003003e,0x0000018c,0x0000018b,0x0004003d,0x00000008, + 0x0000018d,0x00000102,0x00050041,0x0000000d,0x0000018e,0x00000184,0x00000036,0x0003003e, + 0x0000018e,0x0000018d,0x0004003d,0x0000000e,0x0000018f,0x00000184,0x0003003e,0x00000185, + 0x0000018f,0x0004003d,0x0000000e,0x00000103,0x00000185,0x0003003e,0x00000101,0x00000103, + 0x000200f9,0x00000086,0x000200f8,0x00000104,0x0004003d,0x00000008,0x00000106,0x0000007d, + 0x0003003e,0x00000105,0x00000106,0x0004003d,0x00000008,0x00000193,0x00000105,0x00050041, + 0x0000000d,0x00000194,0x00000190,0x0000002d,0x0003003e,0x00000194,0x00000193,0x0004003d, + 0x00000008,0x00000195,0x00000105,0x00050041,0x0000000d,0x00000196,0x00000190,0x00000030, + 0x0003003e,0x00000196,0x00000195,0x0004003d,0x00000008,0x00000197,0x00000105,0x00050041, + 0x0000000d,0x00000198,0x00000190,0x00000033,0x0003003e,0x00000198,0x00000197,0x0004003d, + 0x00000008,0x00000199,0x00000105,0x00050041,0x0000000d,0x0000019a,0x00000190,0x00000036, + 0x0003003e,0x0000019a,0x00000199,0x0004003d,0x0000000e,0x0000019b,0x00000190,0x0003003e, + 0x00000191,0x0000019b,0x0004003d,0x0000000e,0x00000107,0x00000191,0x0003003e,0x000000fd, + 0x00000107,0x0003003e,0x00000108,0x000000c0,0x0004003d,0x00000008,0x0000019f,0x00000108, + 0x00050041,0x0000000d,0x000001a0,0x0000019c,0x0000002d,0x0003003e,0x000001a0,0x0000019f, + 0x0004003d,0x00000008,0x000001a1,0x00000108,0x00050041,0x0000000d,0x000001a2,0x0000019c, + 0x00000030,0x0003003e,0x000001a2,0x000001a1,0x0004003d,0x00000008,0x000001a3,0x00000108, + 0x00050041,0x0000000d,0x000001a4,0x0000019c,0x00000033,0x0003003e,0x000001a4,0x000001a3, + 0x0004003d,0x00000008,0x000001a5,0x00000108,0x00050041,0x0000000d,0x000001a6,0x0000019c, + 0x00000036,0x0003003e,0x000001a6,0x000001a5,0x0004003d,0x0000000e,0x000001a7,0x0000019c, + 0x0003003e,0x0000019d,0x000001a7,0x0004003d,0x0000000e,0x00000109,0x0000019d,0x0003003e, + 0x00000101,0x00000109,0x000200f9,0x00000086,0x000200f8,0x00000086,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d4fe376b1496e6aca875da926728ef2c28b12e9d GIT binary patch literal 7872 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 HIvM*vG%4{v literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.h new file mode 100644 index 000000000..a634d3a2a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.h @@ -0,0 +1,251 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_clip_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000001ab,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000f000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000007f, + 0x00000089,0x00000092,0x000000fd,0x00000101,0x0000011f,0x00000120,0x00000121,0x00000122, + 0x00000123,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x0000007d,0x00003071,0x00030005,0x0000007f,0x00000049, + 0x00030005,0x00000084,0x00006751,0x00030005,0x00000087,0x0000374e,0x00030005,0x00000089, + 0x00003361,0x00030005,0x0000008d,0x00003154,0x00030005,0x00000092,0x00003469,0x00040005, + 0x00000096,0x61726170,0x0000006d,0x00040005,0x00000097,0x61726170,0x0000006d,0x00030005, + 0x0000009b,0x00003170,0x00030005,0x0000009d,0x00006454,0x00040006,0x0000009d,0x00000000, + 0x00003464,0x00030005,0x0000009f,0x00003053,0x00030005,0x000000ac,0x0000424d,0x00040006, + 0x000000ac,0x00000000,0x00003157,0x00030005,0x000000ae,0x0000006b,0x00030005,0x000000bf, + 0x00006159,0x00030005,0x000000c2,0x00006456,0x00030005,0x000000c4,0x00003967,0x00030005, + 0x000000cc,0x0000374f,0x00040005,0x000000d1,0x61726170,0x0000006d,0x00030005,0x000000d5, + 0x00003363,0x00040005,0x000000e6,0x61726170,0x0000006d,0x00030005,0x000000ed,0x0000615a, + 0x00040005,0x000000f2,0x61726170,0x0000006d,0x00040005,0x000000f5,0x61726170,0x0000006d, + 0x00030005,0x000000fd,0x00003065,0x00040005,0x000000fe,0x61726170,0x0000006d,0x00030005, + 0x00000101,0x0000306a,0x00040005,0x00000102,0x61726170,0x0000006d,0x00040005,0x00000105, + 0x61726170,0x0000006d,0x00040005,0x00000108,0x61726170,0x0000006d,0x00030005,0x0000011f, + 0x0000316b,0x00030005,0x00000120,0x0000307a,0x00030005,0x00000121,0x00003153,0x00030005, + 0x00000122,0x0000304e,0x00030005,0x00000123,0x00003159,0x00030047,0x0000007d,0x00000000, + 0x00040047,0x0000007f,0x0000001e,0x00000002,0x00040047,0x00000084,0x00000001,0x0000000a, + 0x00030047,0x00000089,0x0000000e,0x00040047,0x00000089,0x0000001e,0x00000007,0x00040047, + 0x00000092,0x0000001e,0x00000008,0x00040047,0x0000009c,0x00000006,0x00000004,0x00030047, + 0x0000009d,0x00000003,0x00050048,0x0000009d,0x00000000,0x00000023,0x00000000,0x00040047, + 0x0000009f,0x00000021,0x00000007,0x00040047,0x0000009f,0x00000022,0x00000000,0x00030047, + 0x000000a5,0x00000000,0x00030047,0x000000ac,0x00000002,0x00050048,0x000000ac,0x00000000, + 0x00000023,0x00000040,0x00040047,0x000000ae,0x00000021,0x00000000,0x00040047,0x000000ae, + 0x00000022,0x00000000,0x00030047,0x000000bf,0x00000000,0x00030047,0x000000c2,0x00000000, + 0x00030047,0x000000c3,0x00000000,0x00030047,0x000000c4,0x00000000,0x00030047,0x000000c5, + 0x00000000,0x00030047,0x000000cf,0x00000000,0x00030047,0x000000d0,0x00000000,0x00030047, + 0x000000d1,0x00000000,0x00030047,0x000000e9,0x00000000,0x00030047,0x000000f0,0x00000000, + 0x00030047,0x000000f1,0x00000000,0x00030047,0x000000f2,0x00000000,0x00030047,0x000000f8, + 0x00000000,0x00030047,0x000000f9,0x00000000,0x00030047,0x000000fa,0x00000000,0x00030047, + 0x000000fb,0x00000000,0x00030047,0x000000fd,0x00000000,0x00040047,0x000000fd,0x0000001e, + 0x00000001,0x00030047,0x000000fe,0x00000000,0x00030047,0x000000ff,0x00000000,0x00030047, + 0x00000101,0x00000000,0x00040047,0x00000101,0x0000001e,0x00000000,0x00030047,0x00000102, + 0x00000000,0x00030047,0x00000105,0x00000000,0x00030047,0x00000106,0x00000000,0x00030047, + 0x00000108,0x00000000,0x00040047,0x0000011f,0x0000001e,0x00000000,0x00030047,0x00000120, + 0x00000000,0x00030047,0x00000120,0x0000000e,0x00040047,0x00000120,0x0000001e,0x00000003, + 0x00030047,0x00000121,0x00000000,0x00030047,0x00000121,0x0000000e,0x00040047,0x00000121, + 0x0000001e,0x00000004,0x00040047,0x00000122,0x0000001e,0x00000005,0x00030047,0x00000123, + 0x00000000,0x00030047,0x00000123,0x0000000e,0x00040047,0x00000123,0x0000001e,0x00000006, + 0x00030047,0x00000150,0x00000000,0x00030047,0x00000151,0x00000000,0x00030047,0x00000152, + 0x00000000,0x00030047,0x00000153,0x00000000,0x00030047,0x00000156,0x00000000,0x00030047, + 0x0000015d,0x00000000,0x00030047,0x0000015e,0x00000000,0x00030047,0x0000015f,0x00000000, + 0x00030047,0x00000163,0x00000000,0x00030047,0x00000167,0x00000000,0x00030047,0x00000168, + 0x00000000,0x00030047,0x00000169,0x00000000,0x00030047,0x0000016a,0x00000000,0x00030047, + 0x0000016d,0x00000000,0x00030047,0x00000174,0x00000000,0x00030047,0x00000175,0x00000000, + 0x00030047,0x00000176,0x00000000,0x00030047,0x0000017a,0x00000000,0x00030047,0x0000017b, + 0x00000000,0x00030047,0x0000017c,0x00000000,0x00030047,0x0000017e,0x00000000,0x00030047, + 0x00000180,0x00000000,0x00030047,0x00000182,0x00000000,0x00030047,0x00000184,0x00000000, + 0x00030047,0x00000186,0x00000000,0x00030047,0x00000187,0x00000000,0x00030047,0x00000188, + 0x00000000,0x00030047,0x0000018a,0x00000000,0x00030047,0x0000018c,0x00000000,0x00030047, + 0x0000018e,0x00000000,0x00030047,0x00000190,0x00000000,0x00030047,0x00000192,0x00000000, + 0x00030047,0x00000193,0x00000000,0x00030047,0x00000194,0x00000000,0x00030047,0x00000196, + 0x00000000,0x00030047,0x00000198,0x00000000,0x00030047,0x0000019a,0x00000000,0x00030047, + 0x0000019c,0x00000000,0x00030047,0x0000019e,0x00000000,0x00030047,0x0000019f,0x00000000, + 0x00030047,0x000001a0,0x00000000,0x00030047,0x000001a2,0x00000000,0x00030047,0x000001a4, + 0x00000000,0x00030047,0x000001a6,0x00000000,0x00030047,0x000001a8,0x00000000,0x00030047, + 0x000001aa,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015, + 0x00000006,0x00000020,0x00000001,0x00040020,0x00000007,0x00000007,0x00000006,0x00030016, + 0x00000008,0x00000020,0x00040020,0x0000000d,0x00000007,0x00000008,0x00040017,0x0000000e, + 0x00000008,0x00000004,0x00040015,0x00000013,0x00000020,0x00000000,0x00040017,0x00000014, + 0x00000013,0x00000002,0x00040020,0x00000015,0x00000007,0x00000014,0x00040020,0x00000016, + 0x00000007,0x00000013,0x00040020,0x0000002a,0x00000007,0x0000000e,0x0004002b,0x00000013, + 0x0000002d,0x00000000,0x0004002b,0x00000013,0x00000030,0x00000001,0x0004002b,0x00000013, + 0x00000033,0x00000002,0x0004002b,0x00000013,0x00000036,0x00000003,0x0004002b,0x00000013, + 0x0000003e,0x00000005,0x0004002b,0x00000013,0x00000046,0x00000400,0x0004002b,0x00000013, + 0x0000004b,0x0000001f,0x0004002b,0x00000013,0x0000004e,0x00000080,0x0004002b,0x00000013, + 0x00000054,0x00000010,0x0004002b,0x00000013,0x0000005c,0x00000004,0x0004002b,0x00000013, + 0x00000068,0x0007ffff,0x0004002b,0x00000013,0x0000006a,0x00040000,0x0004002b,0x00000008, + 0x0000006f,0x3a800000,0x0004002b,0x00000008,0x00000074,0x44800000,0x0004002b,0x00000008, + 0x00000076,0x3f000000,0x00040020,0x0000007e,0x00000001,0x0000000e,0x0004003b,0x0000007e, + 0x0000007f,0x00000001,0x00040020,0x00000080,0x00000001,0x00000008,0x00020014,0x00000083, + 0x00030030,0x00000083,0x00000084,0x00040020,0x00000088,0x00000001,0x00000014,0x0004003b, + 0x00000088,0x00000089,0x00000001,0x00040020,0x0000008a,0x00000001,0x00000013,0x00040017, + 0x00000090,0x00000008,0x00000002,0x00040020,0x00000091,0x00000001,0x00000090,0x0004003b, + 0x00000091,0x00000092,0x00000001,0x0003001d,0x0000009c,0x00000013,0x0003001e,0x0000009d, + 0x0000009c,0x00040020,0x0000009e,0x00000002,0x0000009d,0x0004003b,0x0000009e,0x0000009f, + 0x00000002,0x0004002b,0x00000006,0x000000a0,0x00000000,0x00040020,0x000000a2,0x00000002, + 0x00000013,0x0004002b,0x00000008,0x000000a6,0x3f800000,0x0003001e,0x000000ac,0x00000013, + 0x00040020,0x000000ad,0x00000002,0x000000ac,0x0004003b,0x000000ad,0x000000ae,0x00000002, + 0x0004002b,0x00000008,0x000000c0,0x00000000,0x00040020,0x000000fc,0x00000003,0x0000000e, + 0x0004003b,0x000000fc,0x000000fd,0x00000003,0x0004003b,0x000000fc,0x00000101,0x00000003, + 0x0004003b,0x0000007e,0x0000011f,0x00000001,0x0004003b,0x00000080,0x00000120,0x00000001, + 0x0004003b,0x00000091,0x00000121,0x00000001,0x0004003b,0x0000007e,0x00000122,0x00000001, + 0x0004003b,0x00000080,0x00000123,0x00000001,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000002a,0x0000019f,0x00000007,0x0004003b, + 0x0000002a,0x000001a0,0x00000007,0x0004003b,0x0000002a,0x00000193,0x00000007,0x0004003b, + 0x0000002a,0x00000194,0x00000007,0x0004003b,0x0000002a,0x00000187,0x00000007,0x0004003b, + 0x0000002a,0x00000188,0x00000007,0x0004003b,0x0000002a,0x0000017b,0x00000007,0x0004003b, + 0x0000002a,0x0000017c,0x00000007,0x0004003b,0x0000000d,0x00000175,0x00000007,0x0004003b, + 0x0000000d,0x00000176,0x00000007,0x0004003b,0x00000007,0x0000016c,0x00000007,0x0004003b, + 0x0000000d,0x0000016d,0x00000007,0x0004003b,0x00000016,0x00000164,0x00000007,0x0004003b, + 0x00000016,0x00000165,0x00000007,0x0004003b,0x0000000d,0x0000015e,0x00000007,0x0004003b, + 0x0000000d,0x0000015f,0x00000007,0x0004003b,0x00000007,0x00000155,0x00000007,0x0004003b, + 0x0000000d,0x00000156,0x00000007,0x0004003b,0x00000016,0x0000014d,0x00000007,0x0004003b, + 0x00000016,0x0000014e,0x00000007,0x0004003b,0x00000016,0x00000127,0x00000007,0x0004003b, + 0x00000016,0x00000128,0x00000007,0x0004003b,0x0000000d,0x0000007d,0x00000007,0x0004003b, + 0x00000016,0x00000087,0x00000007,0x0004003b,0x00000016,0x0000008d,0x00000007,0x0004003b, + 0x00000015,0x00000096,0x00000007,0x0004003b,0x00000016,0x00000097,0x00000007,0x0004003b, + 0x00000016,0x0000009b,0x00000007,0x0004003b,0x0000000d,0x000000bf,0x00000007,0x0004003b, + 0x0000000d,0x000000c2,0x00000007,0x0004003b,0x0000000d,0x000000c4,0x00000007,0x0004003b, + 0x00000016,0x000000cc,0x00000007,0x0004003b,0x0000000d,0x000000d1,0x00000007,0x0004003b, + 0x00000016,0x000000d5,0x00000007,0x0004003b,0x00000016,0x000000e6,0x00000007,0x0004003b, + 0x00000016,0x000000ed,0x00000007,0x0004003b,0x0000000d,0x000000f2,0x00000007,0x0004003b, + 0x00000016,0x000000f5,0x00000007,0x0004003b,0x0000000d,0x000000fe,0x00000007,0x0004003b, + 0x0000000d,0x00000102,0x00000007,0x0004003b,0x0000000d,0x00000105,0x00000007,0x0004003b, + 0x0000000d,0x00000108,0x00000007,0x00050041,0x00000080,0x00000081,0x0000007f,0x0000002d, + 0x0004003d,0x00000008,0x00000082,0x00000081,0x0003003e,0x0000007d,0x00000082,0x000300f7, + 0x00000086,0x00000000,0x000400fa,0x00000084,0x00000085,0x00000104,0x000200f8,0x00000085, + 0x00050041,0x0000008a,0x0000008b,0x00000089,0x00000030,0x0004003d,0x00000013,0x0000008c, + 0x0000008b,0x0003003e,0x00000087,0x0000008c,0x00050041,0x0000008a,0x0000008e,0x00000089, + 0x0000002d,0x0004003d,0x00000013,0x0000008f,0x0000008e,0x0004003d,0x00000090,0x00000093, + 0x00000092,0x0006000c,0x00000090,0x00000094,0x00000001,0x00000008,0x00000093,0x0004006d, + 0x00000014,0x00000095,0x00000094,0x0003003e,0x00000096,0x00000095,0x0004003d,0x00000013, + 0x00000098,0x00000087,0x0003003e,0x00000097,0x00000098,0x00050041,0x00000016,0x0000012a, + 0x00000096,0x00000030,0x0004003d,0x00000013,0x0000012b,0x0000012a,0x000500c2,0x00000013, + 0x0000012c,0x0000012b,0x0000003e,0x0004003d,0x00000013,0x0000012d,0x00000097,0x000500c4, + 0x00000013,0x0000012e,0x0000012d,0x0000003e,0x00050084,0x00000013,0x0000012f,0x0000012c, + 0x0000012e,0x00050041,0x00000016,0x00000130,0x00000096,0x0000002d,0x0004003d,0x00000013, + 0x00000131,0x00000130,0x000500c2,0x00000013,0x00000132,0x00000131,0x0000003e,0x00050084, + 0x00000013,0x00000133,0x00000132,0x00000046,0x00050080,0x00000013,0x00000134,0x0000012f, + 0x00000133,0x0003003e,0x00000127,0x00000134,0x0004003d,0x00000013,0x00000136,0x00000130, + 0x000500c7,0x00000013,0x00000137,0x00000136,0x0000004b,0x000500c2,0x00000013,0x00000138, + 0x00000137,0x00000033,0x00050084,0x00000013,0x00000139,0x00000138,0x0000004e,0x0004003d, + 0x00000013,0x0000013b,0x0000012a,0x000500c7,0x00000013,0x0000013c,0x0000013b,0x0000004b, + 0x000500c2,0x00000013,0x0000013d,0x0000013c,0x00000033,0x00050084,0x00000013,0x0000013e, + 0x0000013d,0x00000054,0x00050080,0x00000013,0x0000013f,0x00000139,0x0000013e,0x0004003d, + 0x00000013,0x00000140,0x00000127,0x00050080,0x00000013,0x00000141,0x00000140,0x0000013f, + 0x0003003e,0x00000127,0x00000141,0x0004003d,0x00000013,0x00000143,0x0000012a,0x000500c7, + 0x00000013,0x00000144,0x00000143,0x00000036,0x00050084,0x00000013,0x00000145,0x00000144, + 0x0000005c,0x0004003d,0x00000013,0x00000147,0x00000130,0x000500c7,0x00000013,0x00000148, + 0x00000147,0x00000036,0x00050080,0x00000013,0x00000149,0x00000145,0x00000148,0x0004003d, + 0x00000013,0x0000014a,0x00000127,0x00050080,0x00000013,0x0000014b,0x0000014a,0x00000149, + 0x0003003e,0x00000127,0x0000014b,0x0004003d,0x00000013,0x0000014c,0x00000127,0x0003003e, + 0x00000128,0x0000014c,0x0004003d,0x00000013,0x00000099,0x00000128,0x00050080,0x00000013, + 0x0000009a,0x0000008f,0x00000099,0x0003003e,0x0000008d,0x0000009a,0x0004003d,0x00000013, + 0x000000a1,0x0000008d,0x00060041,0x000000a2,0x000000a3,0x0000009f,0x000000a0,0x000000a1, + 0x0004003d,0x00000013,0x000000a4,0x000000a3,0x0003003e,0x0000009b,0x000000a4,0x0004003d, + 0x00000008,0x000000a5,0x0000007d,0x000500be,0x00000083,0x000000a7,0x000000a5,0x000000a6, + 0x000300f7,0x000000a9,0x00000000,0x000400fa,0x000000a7,0x000000a8,0x000000a9,0x000200f8, + 0x000000a8,0x0004003d,0x00000013,0x000000aa,0x0000009b,0x00050041,0x000000a2,0x000000b0, + 0x000000ae,0x0000002d,0x0004003d,0x00000013,0x000000b1,0x000000b0,0x000500b0,0x00000083, + 0x000000b2,0x000000aa,0x000000b1,0x000400a8,0x00000083,0x000000b3,0x000000b2,0x000300f7, + 0x000000b5,0x00000000,0x000400fa,0x000000b3,0x000000b4,0x000000b5,0x000200f8,0x000000b4, + 0x0004003d,0x00000013,0x000000b6,0x0000009b,0x000500c5,0x00000013,0x000000b9,0x000000b1, + 0x0000006a,0x000500ae,0x00000083,0x000000ba,0x000000b6,0x000000b9,0x000200f9,0x000000b5, + 0x000200f8,0x000000b5,0x000700f5,0x00000083,0x000000bb,0x000000b2,0x000000a8,0x000000ba, + 0x000000b4,0x000200f9,0x000000a9,0x000200f8,0x000000a9,0x000700f5,0x00000083,0x000000bc, + 0x000000a7,0x00000085,0x000000bb,0x000000b5,0x000300f7,0x000000be,0x00000000,0x000400fa, + 0x000000bc,0x000000bd,0x000000c1,0x000200f8,0x000000bd,0x0003003e,0x000000bf,0x000000c0, + 0x000200f9,0x000000be,0x000200f8,0x000000c1,0x0004003d,0x00000008,0x000000c3,0x0000007d, + 0x0003003e,0x000000c2,0x000000c3,0x0004003d,0x00000008,0x000000c5,0x0000007d,0x0003003e, + 0x000000c4,0x000000c5,0x0004003d,0x00000013,0x000000c6,0x0000009b,0x00050041,0x000000a2, + 0x000000c7,0x000000ae,0x0000002d,0x0004003d,0x00000013,0x000000c8,0x000000c7,0x000500b0, + 0x00000083,0x000000c9,0x000000c6,0x000000c8,0x000300f7,0x000000cb,0x00000000,0x000400fa, + 0x000000c9,0x000000ca,0x000000cb,0x000200f8,0x000000ca,0x0004003d,0x00000008,0x000000cf, + 0x0000007d,0x0006000c,0x00000008,0x000000d0,0x00000001,0x00000004,0x000000cf,0x0003003e, + 0x000000d1,0x000000d0,0x0004003d,0x00000008,0x00000150,0x000000d1,0x00050085,0x00000008, + 0x00000151,0x00000150,0x00000074,0x00050081,0x00000008,0x00000152,0x00000151,0x00000076, + 0x0004006d,0x00000013,0x00000153,0x00000152,0x0003003e,0x0000014d,0x00000153,0x0004003d, + 0x00000013,0x00000154,0x0000014d,0x0003003e,0x0000014e,0x00000154,0x0004003d,0x00000013, + 0x000000d2,0x0000014e,0x00050080,0x00000013,0x000000d3,0x0000006a,0x000000d2,0x000500c5, + 0x00000013,0x000000d4,0x000000c8,0x000000d3,0x0003003e,0x000000cc,0x000000d4,0x0004003d, + 0x00000013,0x000000d6,0x0000008d,0x00060041,0x000000a2,0x000000d7,0x0000009f,0x000000a0, + 0x000000d6,0x0004003d,0x00000013,0x000000d8,0x000000cc,0x000700ef,0x00000013,0x000000d9, + 0x000000d7,0x00000030,0x0000002d,0x000000d8,0x0003003e,0x000000d5,0x000000d9,0x0004003d, + 0x00000013,0x000000da,0x000000d5,0x000500b2,0x00000083,0x000000dd,0x000000da,0x000000c8, + 0x000300f7,0x000000df,0x00000000,0x000400fa,0x000000dd,0x000000de,0x000000e0,0x000200f8, + 0x000000de,0x0003003e,0x000000c4,0x000000c0,0x000200f9,0x000000df,0x000200f8,0x000000e0, + 0x0004003d,0x00000013,0x000000e1,0x000000d5,0x0004003d,0x00000013,0x000000e2,0x000000cc, + 0x000500b0,0x00000083,0x000000e3,0x000000e1,0x000000e2,0x000300f7,0x000000e5,0x00000000, + 0x000400fa,0x000000e3,0x000000e4,0x000000e5,0x000200f8,0x000000e4,0x0004003d,0x00000013, + 0x000000e7,0x000000d5,0x0003003e,0x000000e6,0x000000e7,0x0004003d,0x00000013,0x00000158, + 0x000000e6,0x000500c7,0x00000013,0x00000159,0x00000158,0x00000068,0x00050082,0x00000013, + 0x0000015a,0x00000159,0x0000006a,0x0004007c,0x00000006,0x0000015b,0x0000015a,0x0003003e, + 0x00000155,0x0000015b,0x0004003d,0x00000006,0x00000161,0x00000155,0x0004006f,0x00000008, + 0x00000162,0x00000161,0x0003003e,0x0000015e,0x00000162,0x0004003d,0x00000008,0x00000163, + 0x0000015e,0x0003003e,0x0000015f,0x00000163,0x0004003d,0x00000008,0x0000015c,0x0000015f, + 0x00050085,0x00000008,0x0000015d,0x0000015c,0x0000006f,0x0003003e,0x00000156,0x0000015d, + 0x0004003d,0x00000008,0x000000e8,0x00000156,0x0003003e,0x000000c4,0x000000e8,0x000200f9, + 0x000000e5,0x000200f8,0x000000e5,0x000200f9,0x000000df,0x000200f8,0x000000df,0x000200f9, + 0x000000cb,0x000200f8,0x000000cb,0x0004003d,0x00000008,0x000000e9,0x000000c4,0x000500ba, + 0x00000083,0x000000ea,0x000000e9,0x000000c0,0x000300f7,0x000000ec,0x00000000,0x000400fa, + 0x000000ea,0x000000eb,0x000000ec,0x000200f8,0x000000eb,0x0004003d,0x00000013,0x000000ee, + 0x0000008d,0x00060041,0x000000a2,0x000000ef,0x0000009f,0x000000a0,0x000000ee,0x0004003d, + 0x00000008,0x000000f0,0x000000c4,0x0006000c,0x00000008,0x000000f1,0x00000001,0x00000004, + 0x000000f0,0x0003003e,0x000000f2,0x000000f1,0x0004003d,0x00000008,0x00000167,0x000000f2, + 0x00050085,0x00000008,0x00000168,0x00000167,0x00000074,0x00050081,0x00000008,0x00000169, + 0x00000168,0x00000076,0x0004006d,0x00000013,0x0000016a,0x00000169,0x0003003e,0x00000164, + 0x0000016a,0x0004003d,0x00000013,0x0000016b,0x00000164,0x0003003e,0x00000165,0x0000016b, + 0x0004003d,0x00000013,0x000000f3,0x00000165,0x000700ea,0x00000013,0x000000f4,0x000000ef, + 0x00000030,0x0000002d,0x000000f3,0x0003003e,0x000000ed,0x000000f4,0x0004003d,0x00000013, + 0x000000f6,0x000000ed,0x0003003e,0x000000f5,0x000000f6,0x0004003d,0x00000013,0x0000016f, + 0x000000f5,0x000500c7,0x00000013,0x00000170,0x0000016f,0x00000068,0x00050082,0x00000013, + 0x00000171,0x00000170,0x0000006a,0x0004007c,0x00000006,0x00000172,0x00000171,0x0003003e, + 0x0000016c,0x00000172,0x0004003d,0x00000006,0x00000178,0x0000016c,0x0004006f,0x00000008, + 0x00000179,0x00000178,0x0003003e,0x00000175,0x00000179,0x0004003d,0x00000008,0x0000017a, + 0x00000175,0x0003003e,0x00000176,0x0000017a,0x0004003d,0x00000008,0x00000173,0x00000176, + 0x00050085,0x00000008,0x00000174,0x00000173,0x0000006f,0x0003003e,0x0000016d,0x00000174, + 0x0004003d,0x00000008,0x000000f7,0x0000016d,0x0004003d,0x00000008,0x000000f8,0x0000007d, + 0x00050081,0x00000008,0x000000f9,0x000000f7,0x000000f8,0x0003003e,0x000000c2,0x000000f9, + 0x000200f9,0x000000ec,0x000200f8,0x000000ec,0x0004003d,0x00000008,0x000000fa,0x000000c2, + 0x00050083,0x00000008,0x000000fb,0x000000a6,0x000000fa,0x0003003e,0x000000bf,0x000000fb, + 0x000200f9,0x000000be,0x000200f8,0x000000be,0x0004003d,0x00000008,0x000000ff,0x000000bf, + 0x0003003e,0x000000fe,0x000000ff,0x0004003d,0x00000008,0x0000017e,0x000000fe,0x00050041, + 0x0000000d,0x0000017f,0x0000017b,0x0000002d,0x0003003e,0x0000017f,0x0000017e,0x0004003d, + 0x00000008,0x00000180,0x000000fe,0x00050041,0x0000000d,0x00000181,0x0000017b,0x00000030, + 0x0003003e,0x00000181,0x00000180,0x0004003d,0x00000008,0x00000182,0x000000fe,0x00050041, + 0x0000000d,0x00000183,0x0000017b,0x00000033,0x0003003e,0x00000183,0x00000182,0x0004003d, + 0x00000008,0x00000184,0x000000fe,0x00050041,0x0000000d,0x00000185,0x0000017b,0x00000036, + 0x0003003e,0x00000185,0x00000184,0x0004003d,0x0000000e,0x00000186,0x0000017b,0x0003003e, + 0x0000017c,0x00000186,0x0004003d,0x0000000e,0x00000100,0x0000017c,0x0003003e,0x000000fd, + 0x00000100,0x0003003e,0x00000102,0x000000a6,0x0004003d,0x00000008,0x0000018a,0x00000102, + 0x00050041,0x0000000d,0x0000018b,0x00000187,0x0000002d,0x0003003e,0x0000018b,0x0000018a, + 0x0004003d,0x00000008,0x0000018c,0x00000102,0x00050041,0x0000000d,0x0000018d,0x00000187, + 0x00000030,0x0003003e,0x0000018d,0x0000018c,0x0004003d,0x00000008,0x0000018e,0x00000102, + 0x00050041,0x0000000d,0x0000018f,0x00000187,0x00000033,0x0003003e,0x0000018f,0x0000018e, + 0x0004003d,0x00000008,0x00000190,0x00000102,0x00050041,0x0000000d,0x00000191,0x00000187, + 0x00000036,0x0003003e,0x00000191,0x00000190,0x0004003d,0x0000000e,0x00000192,0x00000187, + 0x0003003e,0x00000188,0x00000192,0x0004003d,0x0000000e,0x00000103,0x00000188,0x0003003e, + 0x00000101,0x00000103,0x000200f9,0x00000086,0x000200f8,0x00000104,0x0004003d,0x00000008, + 0x00000106,0x0000007d,0x0003003e,0x00000105,0x00000106,0x0004003d,0x00000008,0x00000196, + 0x00000105,0x00050041,0x0000000d,0x00000197,0x00000193,0x0000002d,0x0003003e,0x00000197, + 0x00000196,0x0004003d,0x00000008,0x00000198,0x00000105,0x00050041,0x0000000d,0x00000199, + 0x00000193,0x00000030,0x0003003e,0x00000199,0x00000198,0x0004003d,0x00000008,0x0000019a, + 0x00000105,0x00050041,0x0000000d,0x0000019b,0x00000193,0x00000033,0x0003003e,0x0000019b, + 0x0000019a,0x0004003d,0x00000008,0x0000019c,0x00000105,0x00050041,0x0000000d,0x0000019d, + 0x00000193,0x00000036,0x0003003e,0x0000019d,0x0000019c,0x0004003d,0x0000000e,0x0000019e, + 0x00000193,0x0003003e,0x00000194,0x0000019e,0x0004003d,0x0000000e,0x00000107,0x00000194, + 0x0003003e,0x000000fd,0x00000107,0x0003003e,0x00000108,0x000000c0,0x0004003d,0x00000008, + 0x000001a2,0x00000108,0x00050041,0x0000000d,0x000001a3,0x0000019f,0x0000002d,0x0003003e, + 0x000001a3,0x000001a2,0x0004003d,0x00000008,0x000001a4,0x00000108,0x00050041,0x0000000d, + 0x000001a5,0x0000019f,0x00000030,0x0003003e,0x000001a5,0x000001a4,0x0004003d,0x00000008, + 0x000001a6,0x00000108,0x00050041,0x0000000d,0x000001a7,0x0000019f,0x00000033,0x0003003e, + 0x000001a7,0x000001a6,0x0004003d,0x00000008,0x000001a8,0x00000108,0x00050041,0x0000000d, + 0x000001a9,0x0000019f,0x00000036,0x0003003e,0x000001a9,0x000001a8,0x0004003d,0x0000000e, + 0x000001aa,0x0000019f,0x0003003e,0x000001a0,0x000001aa,0x0004003d,0x0000000e,0x00000109, + 0x000001a0,0x0003003e,0x00000101,0x00000109,0x000200f9,0x00000086,0x000200f8,0x00000086, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_clip.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..3cd3357c95dcfb5574c2bb89d27890ff78106539 GIT binary patch literal 7880 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h new file mode 100644 index 000000000..00cf03fc3 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h @@ -0,0 +1,158 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_image_mesh_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000172,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000d000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000092,0x00000095,0x000000a1, + 0x000000a9,0x000000aa,0x000000b0,0x000000c3,0x000000e1,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00060005,0x00000092,0x565f6c67,0x65747265,0x646e4978, + 0x00007865,0x00070005,0x00000095,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000, + 0x00030005,0x00000098,0x0000434c,0x00040006,0x00000098,0x00000000,0x00003972,0x00040006, + 0x00000098,0x00000001,0x00003261,0x00040006,0x00000098,0x00000002,0x00003479,0x00040006, + 0x00000098,0x00000003,0x00006969,0x00040006,0x00000098,0x00000004,0x0000326b,0x00040006, + 0x00000098,0x00000005,0x00003244,0x00040006,0x00000098,0x00000006,0x00003056,0x00040006, + 0x00000098,0x00000007,0x0000326e,0x00040006,0x00000098,0x00000008,0x0000365a,0x00030005, + 0x0000009a,0x00003041,0x00030005,0x000000a1,0x00004346,0x00030005,0x000000a9,0x00003055, + 0x00030005,0x000000aa,0x00004347,0x00030005,0x000000ac,0x00006747,0x00030005,0x000000b0, + 0x00003346,0x00030005,0x000000b3,0x0000424d,0x00040006,0x000000b3,0x00000000,0x00006250, + 0x00040006,0x000000b3,0x00000001,0x00006359,0x00040006,0x000000b3,0x00000002,0x00006552, + 0x00040006,0x000000b3,0x00000003,0x00006553,0x00040006,0x000000b3,0x00000004,0x0000366d, + 0x00040006,0x000000b3,0x00000005,0x0000676d,0x00040006,0x000000b3,0x00000006,0x00006544, + 0x00040006,0x000000b3,0x00000007,0x00006545,0x00040006,0x000000b3,0x00000008,0x00003755, + 0x00040006,0x000000b3,0x00000009,0x0000676a,0x00040006,0x000000b3,0x0000000a,0x0000635a, + 0x00040006,0x000000b3,0x0000000b,0x00003157,0x00040006,0x000000b3,0x0000000c,0x0000676e, + 0x00040006,0x000000b3,0x0000000d,0x00003559,0x00040006,0x000000b3,0x0000000e,0x0000324f, + 0x00040006,0x000000b3,0x0000000f,0x00006461,0x00040006,0x000000b3,0x00000010,0x00006579, + 0x00040006,0x000000b3,0x00000011,0x00003376,0x00040006,0x000000b3,0x00000012,0x00003377, + 0x00040006,0x000000b3,0x00000013,0x00006462,0x00040006,0x000000b3,0x00000014,0x00006767, + 0x00030005,0x000000b5,0x0000006b,0x00030005,0x000000bf,0x00006748,0x00030005,0x000000c3, + 0x0000304e,0x00060005,0x000000df,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006, + 0x000000df,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000000df,0x00000001, + 0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x000000df,0x00000002,0x435f6c67, + 0x4470696c,0x61747369,0x0065636e,0x00070006,0x000000df,0x00000003,0x435f6c67,0x446c6c75, + 0x61747369,0x0065636e,0x00030005,0x000000e1,0x00000000,0x00040047,0x00000092,0x0000000b, + 0x0000002a,0x00040047,0x00000095,0x0000000b,0x0000002b,0x00030047,0x00000098,0x00000002, + 0x00050048,0x00000098,0x00000000,0x00000023,0x00000000,0x00050048,0x00000098,0x00000001, + 0x00000023,0x00000010,0x00050048,0x00000098,0x00000002,0x00000023,0x00000018,0x00050048, + 0x00000098,0x00000003,0x00000023,0x0000001c,0x00050048,0x00000098,0x00000004,0x00000023, + 0x00000020,0x00050048,0x00000098,0x00000005,0x00000023,0x00000030,0x00050048,0x00000098, + 0x00000006,0x00000023,0x00000038,0x00050048,0x00000098,0x00000007,0x00000023,0x0000003c, + 0x00050048,0x00000098,0x00000008,0x00000023,0x00000040,0x00040047,0x0000009a,0x00000021, + 0x00000002,0x00040047,0x0000009a,0x00000022,0x00000000,0x00040047,0x000000a1,0x0000001e, + 0x00000000,0x00040047,0x000000a9,0x0000001e,0x00000000,0x00040047,0x000000aa,0x0000001e, + 0x00000001,0x00040047,0x000000ac,0x00000001,0x00000000,0x00030047,0x000000b0,0x00000000, + 0x00030047,0x000000b0,0x0000000e,0x00040047,0x000000b0,0x0000001e,0x00000001,0x00030047, + 0x000000b3,0x00000002,0x00050048,0x000000b3,0x00000000,0x00000023,0x00000000,0x00050048, + 0x000000b3,0x00000001,0x00000023,0x00000004,0x00050048,0x000000b3,0x00000002,0x00000023, + 0x00000008,0x00050048,0x000000b3,0x00000003,0x00000023,0x0000000c,0x00050048,0x000000b3, + 0x00000004,0x00000023,0x00000010,0x00050048,0x000000b3,0x00000005,0x00000023,0x00000014, + 0x00050048,0x000000b3,0x00000006,0x00000023,0x00000018,0x00050048,0x000000b3,0x00000007, + 0x00000023,0x0000001c,0x00050048,0x000000b3,0x00000008,0x00000023,0x00000020,0x00050048, + 0x000000b3,0x00000009,0x00000023,0x00000030,0x00050048,0x000000b3,0x0000000a,0x00000023, + 0x00000038,0x00050048,0x000000b3,0x0000000b,0x00000023,0x00000040,0x00050048,0x000000b3, + 0x0000000c,0x00000023,0x00000044,0x00050048,0x000000b3,0x0000000d,0x00000023,0x00000048, + 0x00050048,0x000000b3,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000000b3,0x0000000f, + 0x00000023,0x00000050,0x00050048,0x000000b3,0x00000010,0x00000023,0x00000054,0x00050048, + 0x000000b3,0x00000011,0x00000023,0x00000058,0x00050048,0x000000b3,0x00000012,0x00000023, + 0x0000005c,0x00050048,0x000000b3,0x00000013,0x00000023,0x00000060,0x00050048,0x000000b3, + 0x00000014,0x00000023,0x00000064,0x00040047,0x000000b5,0x00000021,0x00000000,0x00040047, + 0x000000b5,0x00000022,0x00000000,0x00040047,0x000000bf,0x00000001,0x00000001,0x00040047, + 0x000000c3,0x0000001e,0x00000002,0x00030047,0x000000df,0x00000002,0x00050048,0x000000df, + 0x00000000,0x0000000b,0x00000000,0x00050048,0x000000df,0x00000001,0x0000000b,0x00000001, + 0x00050048,0x000000df,0x00000002,0x0000000b,0x00000003,0x00050048,0x000000df,0x00000003, + 0x0000000b,0x00000004,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017,0x00000009, + 0x00000006,0x00000002,0x00040018,0x0000000a,0x00000009,0x00000002,0x00040015,0x0000000f, + 0x00000020,0x00000000,0x0004002b,0x00000006,0x00000029,0x3f800000,0x0004002b,0x00000006, + 0x0000002a,0x00000000,0x0004002b,0x0000000f,0x00000035,0x00000000,0x00020014,0x00000036, + 0x0004002b,0x0000000f,0x0000003d,0x000003ff,0x0004002b,0x0000000f,0x0000004d,0x00000001, + 0x00040015,0x00000059,0x00000020,0x00000001,0x0004002b,0x00000059,0x0000005a,0x00000000, + 0x0004002b,0x00000059,0x0000005e,0x00000001,0x0004002b,0x00000006,0x00000086,0x3f000000, + 0x00040020,0x00000091,0x00000001,0x00000059,0x0004003b,0x00000091,0x00000092,0x00000001, + 0x0004003b,0x00000091,0x00000095,0x00000001,0x000b001e,0x00000098,0x00000007,0x00000009, + 0x00000006,0x00000006,0x00000007,0x00000009,0x0000000f,0x0000000f,0x0000000f,0x00040020, + 0x00000099,0x00000002,0x00000098,0x0004003b,0x00000099,0x0000009a,0x00000002,0x00040020, + 0x0000009c,0x00000002,0x00000007,0x00040020,0x000000a0,0x00000001,0x00000009,0x0004003b, + 0x000000a0,0x000000a1,0x00000001,0x00040020,0x000000a4,0x00000002,0x00000009,0x00040020, + 0x000000a8,0x00000003,0x00000009,0x0004003b,0x000000a8,0x000000a9,0x00000003,0x0004003b, + 0x000000a0,0x000000aa,0x00000001,0x00030030,0x00000036,0x000000ac,0x00040020,0x000000af, + 0x00000003,0x00000006,0x0004003b,0x000000af,0x000000b0,0x00000003,0x0004002b,0x00000059, + 0x000000b1,0x00000006,0x00040017,0x000000b2,0x00000059,0x00000004,0x0017001e,0x000000b3, + 0x00000006,0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f,0x0000000f,0x0000000f, + 0x000000b2,0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f,0x00000006,0x00000006, + 0x0000000f,0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020,0x000000b4,0x00000002, + 0x000000b3,0x0004003b,0x000000b4,0x000000b5,0x00000002,0x0004002b,0x00000059,0x000000b6, + 0x0000000d,0x00040020,0x000000b8,0x00000002,0x0000000f,0x00030030,0x00000036,0x000000bf, + 0x00040020,0x000000c2,0x00000003,0x00000007,0x0004003b,0x000000c2,0x000000c3,0x00000003, + 0x0004002b,0x00000059,0x000000c4,0x00000004,0x0004002b,0x00000059,0x000000c9,0x00000005, + 0x0004002b,0x00000059,0x000000d2,0x00000002,0x0004002b,0x00000059,0x000000d3,0x00000003, + 0x00040020,0x000000d7,0x00000002,0x00000006,0x0004001c,0x000000de,0x00000006,0x0000004d, + 0x0006001e,0x000000df,0x00000007,0x00000006,0x000000de,0x000000de,0x00040020,0x000000e0, + 0x00000003,0x000000df,0x0004003b,0x000000e0,0x000000e1,0x00000003,0x0005002c,0x00000009, + 0x00000170,0x00000029,0x00000029,0x0007002c,0x00000007,0x00000171,0x00000086,0x00000086, + 0x00000086,0x00000086,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x00050041,0x0000009c,0x0000009d,0x0000009a,0x0000005a,0x0004003d,0x00000007, + 0x0000009e,0x0000009d,0x00050051,0x00000006,0x000000fc,0x0000009e,0x00000000,0x00050051, + 0x00000006,0x000000fd,0x0000009e,0x00000001,0x00050051,0x00000006,0x000000fe,0x0000009e, + 0x00000002,0x00050051,0x00000006,0x000000ff,0x0000009e,0x00000003,0x00050050,0x00000009, + 0x00000100,0x000000fc,0x000000fd,0x00050050,0x00000009,0x00000101,0x000000fe,0x000000ff, + 0x00050050,0x0000000a,0x00000102,0x00000100,0x00000101,0x0004003d,0x00000009,0x000000a2, + 0x000000a1,0x00050091,0x00000009,0x000000a3,0x00000102,0x000000a2,0x00050041,0x000000a4, + 0x000000a5,0x0000009a,0x0000005e,0x0004003d,0x00000009,0x000000a6,0x000000a5,0x00050081, + 0x00000009,0x000000a7,0x000000a3,0x000000a6,0x0004003d,0x00000009,0x000000ab,0x000000aa, + 0x0003003e,0x000000a9,0x000000ab,0x000300f7,0x000000ae,0x00000000,0x000400fa,0x000000ac, + 0x000000ad,0x000000ae,0x000200f8,0x000000ad,0x00050041,0x000000b8,0x000000b9,0x0000009a, + 0x000000b1,0x0004003d,0x0000000f,0x000000ba,0x000000b9,0x00050041,0x000000b8,0x000000bc, + 0x000000b5,0x000000b6,0x0004003d,0x0000000f,0x000000bd,0x000000bc,0x000500aa,0x00000036, + 0x00000108,0x000000ba,0x00000035,0x000300f7,0x00000111,0x00000000,0x000400fa,0x00000108, + 0x00000109,0x0000010a,0x000200f8,0x0000010a,0x00050080,0x0000000f,0x0000010c,0x000000ba, + 0x0000003d,0x00050084,0x0000000f,0x0000010e,0x0000010c,0x000000bd,0x0006000c,0x00000009, + 0x0000010f,0x00000001,0x0000003e,0x0000010e,0x00050051,0x00000006,0x00000110,0x0000010f, + 0x00000000,0x000200f9,0x00000111,0x000200f8,0x00000109,0x000200f9,0x00000111,0x000200f8, + 0x00000111,0x000700f5,0x00000006,0x0000016d,0x0000002a,0x00000109,0x00000110,0x0000010a, + 0x0003003e,0x000000b0,0x0000016d,0x000200f9,0x000000ae,0x000200f8,0x000000ae,0x000300f7, + 0x000000c1,0x00000000,0x000400fa,0x000000bf,0x000000c0,0x000000c1,0x000200f8,0x000000c0, + 0x00050041,0x0000009c,0x000000c6,0x0000009a,0x000000c4,0x0004003d,0x00000007,0x000000c7, + 0x000000c6,0x00050051,0x00000006,0x0000011a,0x000000c7,0x00000000,0x00050051,0x00000006, + 0x0000011b,0x000000c7,0x00000001,0x00050051,0x00000006,0x0000011c,0x000000c7,0x00000002, + 0x00050051,0x00000006,0x0000011d,0x000000c7,0x00000003,0x00050050,0x00000009,0x0000011e, + 0x0000011a,0x0000011b,0x00050050,0x00000009,0x0000011f,0x0000011c,0x0000011d,0x00050050, + 0x0000000a,0x00000120,0x0000011e,0x0000011f,0x00050041,0x000000a4,0x000000cc,0x0000009a, + 0x000000c9,0x0004003d,0x00000009,0x000000cd,0x000000cc,0x000300f7,0x00000156,0x00000000, + 0x000300fb,0x00000035,0x00000128,0x000200f8,0x00000128,0x0006000c,0x00000009,0x0000012b, + 0x00000001,0x00000004,0x0000011e,0x0006000c,0x00000009,0x0000012e,0x00000001,0x00000004, + 0x0000011f,0x00050081,0x00000009,0x0000012f,0x0000012b,0x0000012e,0x00050051,0x00000006, + 0x00000131,0x0000012f,0x00000000,0x000500b7,0x00000036,0x00000132,0x00000131,0x0000002a, + 0x000300f7,0x00000137,0x00000000,0x000400fa,0x00000132,0x00000133,0x00000137,0x000200f8, + 0x00000133,0x00050051,0x00000006,0x00000135,0x0000012f,0x00000001,0x000500b7,0x00000036, + 0x00000136,0x00000135,0x0000002a,0x000200f9,0x00000137,0x000200f8,0x00000137,0x000700f5, + 0x00000036,0x00000138,0x00000132,0x00000128,0x00000136,0x00000133,0x000300f7,0x00000155, + 0x00000000,0x000400fa,0x00000138,0x00000139,0x00000152,0x000200f8,0x00000152,0x0009004f, + 0x00000007,0x00000154,0x000000cd,0x000000cd,0x00000000,0x00000001,0x00000000,0x00000001, + 0x000200f9,0x00000156,0x000200f8,0x00000139,0x00050088,0x00000009,0x0000013c,0x00000170, + 0x0000012f,0x00050091,0x00000009,0x0000013f,0x00000120,0x000000a7,0x00050081,0x00000009, + 0x00000141,0x0000013f,0x000000cd,0x0004007f,0x00000009,0x00000144,0x00000141,0x00050051, + 0x00000006,0x00000145,0x00000141,0x00000000,0x00050051,0x00000006,0x00000146,0x00000141, + 0x00000001,0x00050051,0x00000006,0x00000147,0x00000144,0x00000000,0x00050051,0x00000006, + 0x00000148,0x00000144,0x00000001,0x00070050,0x00000007,0x00000149,0x00000145,0x00000146, + 0x00000147,0x00000148,0x0009004f,0x00000007,0x0000014b,0x0000013c,0x0000013c,0x00000000, + 0x00000001,0x00000000,0x00000001,0x00050085,0x00000007,0x0000014c,0x00000149,0x0000014b, + 0x00050081,0x00000007,0x0000014f,0x0000014c,0x0000014b,0x00050081,0x00000007,0x00000151, + 0x0000014f,0x00000171,0x000200f9,0x00000156,0x000200f8,0x00000155,0x000100ff,0x000200f8, + 0x00000156,0x000700f5,0x00000007,0x0000016e,0x00000151,0x00000139,0x00000154,0x00000152, + 0x0003003e,0x000000c3,0x0000016e,0x000200f9,0x000000c1,0x000200f8,0x000000c1,0x00050041, + 0x000000d7,0x000000d8,0x000000b5,0x000000d2,0x0004003d,0x00000006,0x000000d9,0x000000d8, + 0x00050041,0x000000d7,0x000000db,0x000000b5,0x000000d3,0x0004003d,0x00000006,0x000000dc, + 0x000000db,0x00050051,0x00000006,0x0000015b,0x000000a7,0x00000000,0x00050085,0x00000006, + 0x0000015d,0x0000015b,0x000000d9,0x00050083,0x00000006,0x0000015e,0x0000015d,0x00000029, + 0x00050051,0x00000006,0x00000160,0x000000a7,0x00000001,0x00050085,0x00000006,0x00000162, + 0x00000160,0x000000dc,0x0006000c,0x00000006,0x00000164,0x00000001,0x00000006,0x000000dc, + 0x00050083,0x00000006,0x00000165,0x00000162,0x00000164,0x00070050,0x00000007,0x00000166, + 0x0000015e,0x00000165,0x0000002a,0x00000029,0x00050041,0x000000c2,0x000000e3,0x000000e1, + 0x0000005a,0x0003003e,0x000000e3,0x00000166,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..b66877860ce899dd29d00a11e2ebe693b730596a GIT binary patch literal 4920 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h new file mode 100644 index 000000000..0842e302f --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h @@ -0,0 +1,287 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_interior_triangles_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000315,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0010000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000d7,0x000000df,0x000000e2, + 0x000000f4,0x0000012d,0x00000133,0x00000154,0x00000172,0x000001ef,0x000001f2,0x00000206, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000b5, + 0x0000664a,0x00040006,0x000000b5,0x00000000,0x00003464,0x00030005,0x000000b7,0x0000424c, + 0x00060005,0x000000d7,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x000000df, + 0x0000424a,0x00030005,0x000000e2,0x0000316c,0x00030005,0x000000ed,0x00006576,0x00040006, + 0x000000ed,0x00000000,0x00003464,0x00030005,0x000000ef,0x00004355,0x00030005,0x000000f4, + 0x0000307a,0x00030005,0x000000f6,0x0000424d,0x00040006,0x000000f6,0x00000000,0x00006250, + 0x00040006,0x000000f6,0x00000001,0x00006359,0x00040006,0x000000f6,0x00000002,0x00006552, + 0x00040006,0x000000f6,0x00000003,0x00006553,0x00040006,0x000000f6,0x00000004,0x0000366d, + 0x00040006,0x000000f6,0x00000005,0x0000676d,0x00040006,0x000000f6,0x00000006,0x00006544, + 0x00040006,0x000000f6,0x00000007,0x00006545,0x00040006,0x000000f6,0x00000008,0x00003755, + 0x00040006,0x000000f6,0x00000009,0x0000676a,0x00040006,0x000000f6,0x0000000a,0x0000635a, + 0x00040006,0x000000f6,0x0000000b,0x00003157,0x00040006,0x000000f6,0x0000000c,0x0000676e, + 0x00040006,0x000000f6,0x0000000d,0x00003559,0x00040006,0x000000f6,0x0000000e,0x0000324f, + 0x00040006,0x000000f6,0x0000000f,0x00006461,0x00040006,0x000000f6,0x00000010,0x00006579, + 0x00040006,0x000000f6,0x00000011,0x00003376,0x00040006,0x000000f6,0x00000012,0x00003377, + 0x00040006,0x000000f6,0x00000013,0x00006462,0x00040006,0x000000f6,0x00000014,0x00006767, + 0x00030005,0x000000f8,0x0000006b,0x00030005,0x0000010f,0x00006747,0x00030005,0x0000012d, + 0x00003153,0x00030005,0x00000130,0x00006749,0x00030005,0x00000133,0x00003159,0x00030005, + 0x0000013c,0x00006748,0x00030005,0x00000141,0x00006577,0x00040006,0x00000141,0x00000000, + 0x00003464,0x00030005,0x00000143,0x0000424f,0x00030005,0x00000154,0x0000304e,0x00030005, + 0x00000172,0x0000316b,0x00030005,0x000001ef,0x00003361,0x00030005,0x000001f2,0x00003469, + 0x00060005,0x00000204,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000204, + 0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000204,0x00000001,0x505f6c67, + 0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000204,0x00000002,0x435f6c67,0x4470696c, + 0x61747369,0x0065636e,0x00070006,0x00000204,0x00000003,0x435f6c67,0x446c6c75,0x61747369, + 0x0065636e,0x00030005,0x00000206,0x00000000,0x00030005,0x00000214,0x00004342,0x00030005, + 0x00000217,0x00004351,0x00030005,0x00000219,0x0000664b,0x00040006,0x00000219,0x00000000, + 0x00003464,0x00030005,0x0000021b,0x00004358,0x00030005,0x0000021e,0x00003954,0x00040047, + 0x000000b4,0x00000006,0x00000010,0x00030047,0x000000b5,0x00000003,0x00040048,0x000000b5, + 0x00000000,0x00000018,0x00050048,0x000000b5,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000b7,0x00000018,0x00040047,0x000000b7,0x00000021,0x00000003,0x00040047,0x000000b7, + 0x00000022,0x00000000,0x00040047,0x000000d7,0x0000000b,0x0000002a,0x00040047,0x000000df, + 0x0000001e,0x00000000,0x00030047,0x000000e2,0x00000000,0x00030047,0x000000e2,0x0000000e, + 0x00040047,0x000000e2,0x0000001e,0x00000001,0x00040047,0x000000ec,0x00000006,0x00000008, + 0x00030047,0x000000ed,0x00000003,0x00040048,0x000000ed,0x00000000,0x00000018,0x00050048, + 0x000000ed,0x00000000,0x00000023,0x00000000,0x00030047,0x000000ef,0x00000018,0x00040047, + 0x000000ef,0x00000021,0x00000004,0x00040047,0x000000ef,0x00000022,0x00000000,0x00030047, + 0x000000f4,0x00000000,0x00030047,0x000000f4,0x0000000e,0x00040047,0x000000f4,0x0000001e, + 0x00000003,0x00030047,0x000000f6,0x00000002,0x00050048,0x000000f6,0x00000000,0x00000023, + 0x00000000,0x00050048,0x000000f6,0x00000001,0x00000023,0x00000004,0x00050048,0x000000f6, + 0x00000002,0x00000023,0x00000008,0x00050048,0x000000f6,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x000000f6,0x00000004,0x00000023,0x00000010,0x00050048,0x000000f6,0x00000005, + 0x00000023,0x00000014,0x00050048,0x000000f6,0x00000006,0x00000023,0x00000018,0x00050048, + 0x000000f6,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000f6,0x00000008,0x00000023, + 0x00000020,0x00050048,0x000000f6,0x00000009,0x00000023,0x00000030,0x00050048,0x000000f6, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x000000f6,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x000000f6,0x0000000c,0x00000023,0x00000044,0x00050048,0x000000f6,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x000000f6,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x000000f6,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000f6,0x00000010,0x00000023, + 0x00000054,0x00050048,0x000000f6,0x00000011,0x00000023,0x00000058,0x00050048,0x000000f6, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x000000f6,0x00000013,0x00000023,0x00000060, + 0x00050048,0x000000f6,0x00000014,0x00000023,0x00000064,0x00040047,0x000000f8,0x00000021, + 0x00000000,0x00040047,0x000000f8,0x00000022,0x00000000,0x00030047,0x00000108,0x00000000, + 0x00030047,0x00000109,0x00000000,0x00040047,0x0000010f,0x00000001,0x00000000,0x00030047, + 0x0000012b,0x00000000,0x00030047,0x0000012d,0x00000000,0x00030047,0x0000012d,0x0000000e, + 0x00040047,0x0000012d,0x0000001e,0x00000004,0x00040047,0x00000130,0x00000001,0x00000002, + 0x00030047,0x00000133,0x00000000,0x00030047,0x00000133,0x0000000e,0x00040047,0x00000133, + 0x0000001e,0x00000006,0x00040047,0x0000013c,0x00000001,0x00000001,0x00040047,0x00000140, + 0x00000006,0x00000010,0x00030047,0x00000141,0x00000003,0x00040048,0x00000141,0x00000000, + 0x00000018,0x00050048,0x00000141,0x00000000,0x00000023,0x00000000,0x00030047,0x00000143, + 0x00000018,0x00040047,0x00000143,0x00000021,0x00000005,0x00040047,0x00000143,0x00000022, + 0x00000000,0x00040047,0x00000154,0x0000001e,0x00000005,0x00040047,0x00000172,0x0000001e, + 0x00000000,0x00030047,0x000001ef,0x0000000e,0x00040047,0x000001ef,0x0000001e,0x00000007, + 0x00040047,0x000001f2,0x0000001e,0x00000008,0x00030047,0x00000204,0x00000002,0x00050048, + 0x00000204,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000204,0x00000001,0x0000000b, + 0x00000001,0x00050048,0x00000204,0x00000002,0x0000000b,0x00000003,0x00050048,0x00000204, + 0x00000003,0x0000000b,0x00000004,0x00040047,0x00000214,0x00000021,0x00000008,0x00040047, + 0x00000214,0x00000022,0x00000000,0x00030047,0x00000217,0x00000000,0x00040047,0x00000217, + 0x00000021,0x0000000a,0x00040047,0x00000217,0x00000022,0x00000000,0x00040047,0x00000218, + 0x00000006,0x00000010,0x00030047,0x00000219,0x00000003,0x00040048,0x00000219,0x00000000, + 0x00000018,0x00050048,0x00000219,0x00000000,0x00000023,0x00000000,0x00030047,0x0000021b, + 0x00000018,0x00040047,0x0000021b,0x00000021,0x00000006,0x00040047,0x0000021b,0x00000022, + 0x00000000,0x00030047,0x0000021e,0x00000000,0x00040047,0x0000021e,0x00000021,0x0000000a, + 0x00040047,0x0000021e,0x00000022,0x00000000,0x00030047,0x0000030c,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000001, + 0x00030016,0x00000008,0x00000020,0x00040017,0x0000000d,0x00000008,0x00000004,0x00040017, + 0x0000000f,0x00000008,0x00000002,0x00040018,0x00000010,0x0000000f,0x00000002,0x00040015, + 0x00000015,0x00000020,0x00000000,0x00040017,0x0000002b,0x00000008,0x00000003,0x0004002b, + 0x00000008,0x0000003d,0x3f800000,0x0004002b,0x00000008,0x0000003e,0x00000000,0x0004002b, + 0x00000015,0x00000049,0x00000000,0x00020014,0x0000004a,0x0004002b,0x00000015,0x00000051, + 0x000003ff,0x0004002b,0x00000015,0x00000061,0x00000001,0x0004002b,0x00000006,0x0000006d, + 0x00000000,0x0004002b,0x00000008,0x00000099,0x3f000000,0x0004002b,0x00000015,0x000000a2, + 0x00000002,0x0004002b,0x00000015,0x000000a6,0x0000ffff,0x0004002b,0x00000006,0x000000ab, + 0x00000010,0x00040017,0x000000b3,0x00000015,0x00000004,0x0003001d,0x000000b4,0x000000b3, + 0x0003001e,0x000000b5,0x000000b4,0x00040020,0x000000b6,0x00000002,0x000000b5,0x0004003b, + 0x000000b6,0x000000b7,0x00000002,0x0004002b,0x00000015,0x000000b9,0x00000004,0x00040020, + 0x000000bb,0x00000002,0x000000b3,0x00040017,0x000000c9,0x00000015,0x00000002,0x00040020, + 0x000000d6,0x00000001,0x00000006,0x0004003b,0x000000d6,0x000000d7,0x00000001,0x00040020, + 0x000000de,0x00000001,0x0000002b,0x0004003b,0x000000de,0x000000df,0x00000001,0x00040020, + 0x000000e1,0x00000003,0x00000008,0x0004003b,0x000000e1,0x000000e2,0x00000003,0x0003001d, + 0x000000ec,0x000000c9,0x0003001e,0x000000ed,0x000000ec,0x00040020,0x000000ee,0x00000002, + 0x000000ed,0x0004003b,0x000000ee,0x000000ef,0x00000002,0x00040020,0x000000f1,0x00000002, + 0x000000c9,0x0004003b,0x000000e1,0x000000f4,0x00000003,0x00040017,0x000000f5,0x00000006, + 0x00000004,0x0017001e,0x000000f6,0x00000008,0x00000008,0x00000008,0x00000008,0x00000015, + 0x00000015,0x00000015,0x00000015,0x000000f5,0x0000000f,0x0000000f,0x00000015,0x00000008, + 0x00000015,0x00000008,0x00000008,0x00000015,0x00000008,0x00000008,0x00000008,0x00000015, + 0x00040020,0x000000f7,0x00000002,0x000000f6,0x0004003b,0x000000f7,0x000000f8,0x00000002, + 0x0004002b,0x00000006,0x000000f9,0x0000000d,0x00040020,0x000000fd,0x00000002,0x00000015, + 0x0004002b,0x00000015,0x00000103,0x00000200,0x0004002b,0x00000015,0x0000010d,0x0000000f, + 0x00030030,0x0000004a,0x0000010f,0x00040020,0x0000012c,0x00000003,0x0000000f,0x0004003b, + 0x0000012c,0x0000012d,0x00000003,0x00030030,0x0000004a,0x00000130,0x0004003b,0x000000e1, + 0x00000133,0x00000003,0x0004002b,0x00000006,0x00000136,0x00000004,0x00030030,0x0000004a, + 0x0000013c,0x0003001d,0x00000140,0x0000000d,0x0003001e,0x00000141,0x00000140,0x00040020, + 0x00000142,0x00000002,0x00000141,0x0004003b,0x00000142,0x00000143,0x00000002,0x00040020, + 0x00000148,0x00000002,0x0000000d,0x0004002b,0x00000015,0x0000014f,0x00000003,0x00040020, + 0x00000153,0x00000003,0x0000000d,0x0004003b,0x00000153,0x00000154,0x00000003,0x0004003b, + 0x00000153,0x00000172,0x00000003,0x0004002b,0x00000008,0x000001aa,0x3f666666,0x0004002b, + 0x00000008,0x000001ae,0x40000000,0x0004002b,0x00000008,0x000001d3,0xc0000000,0x0004002b, + 0x00000006,0x000001dc,0x00000002,0x0004002b,0x00000006,0x000001dd,0x00000003,0x00040020, + 0x000001e1,0x00000002,0x00000008,0x00040020,0x000001ee,0x00000003,0x000000c9,0x0004003b, + 0x000001ee,0x000001ef,0x00000003,0x0004003b,0x0000012c,0x000001f2,0x00000003,0x0004001c, + 0x00000203,0x00000008,0x00000061,0x0006001e,0x00000204,0x0000000d,0x00000008,0x00000203, + 0x00000203,0x00040020,0x00000205,0x00000003,0x00000204,0x0004003b,0x00000205,0x00000206, + 0x00000003,0x00090019,0x00000212,0x00000015,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x00000213,0x00000000,0x00000212,0x0004003b,0x00000213, + 0x00000214,0x00000000,0x00090019,0x00000215,0x00000008,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x00000216,0x00000000,0x00000215,0x0004003b, + 0x00000216,0x00000217,0x00000000,0x0003001d,0x00000218,0x000000b3,0x0003001e,0x00000219, + 0x00000218,0x00040020,0x0000021a,0x00000002,0x00000219,0x0004003b,0x0000021a,0x0000021b, + 0x00000002,0x0002001a,0x0000021c,0x00040020,0x0000021d,0x00000000,0x0000021c,0x0004003b, + 0x0000021d,0x0000021e,0x00000000,0x0005002c,0x0000000f,0x00000311,0x0000003d,0x0000003d, + 0x0007002c,0x0000000d,0x00000312,0x00000099,0x00000099,0x00000099,0x00000099,0x0003002e, + 0x0000000f,0x00000314,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x0000002b,0x000000e4,0x000000df,0x00050051,0x00000008,0x0000022e, + 0x000000e4,0x00000002,0x0004007c,0x00000015,0x0000022f,0x0000022e,0x000500c7,0x00000015, + 0x00000230,0x0000022f,0x000000a6,0x0004007c,0x00000006,0x00000233,0x0000022e,0x000500c3, + 0x00000006,0x00000234,0x00000233,0x000000ab,0x0004006f,0x00000008,0x00000250,0x00000234, + 0x0007004f,0x0000000f,0x00000237,0x000000e4,0x000000e4,0x00000000,0x00000001,0x00050084, + 0x00000015,0x00000239,0x00000230,0x000000b9,0x00060041,0x000000bb,0x0000023a,0x000000b7, + 0x0000006d,0x00000239,0x0004003d,0x000000b3,0x0000023b,0x0000023a,0x0004007c,0x0000000d, + 0x0000023c,0x0000023b,0x00050051,0x00000008,0x00000258,0x0000023c,0x00000000,0x00050051, + 0x00000008,0x00000259,0x0000023c,0x00000001,0x00050051,0x00000008,0x0000025a,0x0000023c, + 0x00000002,0x00050051,0x00000008,0x0000025b,0x0000023c,0x00000003,0x00050050,0x0000000f, + 0x0000025c,0x00000258,0x00000259,0x00050050,0x0000000f,0x0000025d,0x0000025a,0x0000025b, + 0x00050050,0x00000010,0x0000025e,0x0000025c,0x0000025d,0x00050080,0x00000015,0x00000240, + 0x00000239,0x00000061,0x00060041,0x000000bb,0x00000241,0x000000b7,0x0000006d,0x00000240, + 0x0004003d,0x000000b3,0x00000242,0x00000241,0x0007004f,0x000000c9,0x00000244,0x00000242, + 0x00000242,0x00000000,0x00000001,0x0004007c,0x0000000f,0x00000245,0x00000244,0x00050091, + 0x0000000f,0x00000248,0x0000025e,0x00000237,0x00050081,0x0000000f,0x0000024a,0x00000248, + 0x00000245,0x0003003e,0x000000e2,0x00000250,0x00060041,0x000000f1,0x000000f2,0x000000ef, + 0x0000006d,0x00000230,0x0004003d,0x000000c9,0x000000f3,0x000000f2,0x00050041,0x000000fd, + 0x000000fe,0x000000f8,0x000000f9,0x0004003d,0x00000015,0x000000ff,0x000000fe,0x000500aa, + 0x0000004a,0x00000264,0x00000230,0x00000049,0x000300f7,0x0000026d,0x00000000,0x000400fa, + 0x00000264,0x0000026c,0x00000265,0x000200f8,0x00000265,0x00050080,0x00000015,0x00000267, + 0x00000230,0x00000051,0x00050084,0x00000015,0x00000269,0x00000267,0x000000ff,0x0006000c, + 0x0000000f,0x0000026a,0x00000001,0x0000003e,0x00000269,0x00050051,0x00000008,0x0000026b, + 0x0000026a,0x00000000,0x000200f9,0x0000026d,0x000200f8,0x0000026c,0x000200f9,0x0000026d, + 0x000200f8,0x0000026d,0x000700f5,0x00000008,0x00000309,0x0000026b,0x00000265,0x0000003e, + 0x0000026c,0x0003003e,0x000000f4,0x00000309,0x00050051,0x00000015,0x00000102,0x000000f3, + 0x00000000,0x000500c7,0x00000015,0x00000104,0x00000102,0x00000103,0x000500ab,0x0000004a, + 0x00000105,0x00000104,0x00000049,0x000300f7,0x00000107,0x00000000,0x000400fa,0x00000105, + 0x00000106,0x00000107,0x000200f8,0x00000106,0x0004003d,0x00000008,0x00000108,0x000000f4, + 0x0004007f,0x00000008,0x00000109,0x00000108,0x0003003e,0x000000f4,0x00000109,0x000200f9, + 0x00000107,0x000200f8,0x00000107,0x000500c7,0x00000015,0x0000010e,0x00000102,0x0000010d, + 0x000300f7,0x00000111,0x00000000,0x000400fa,0x0000010f,0x00000110,0x00000111,0x000200f8, + 0x00000110,0x000500aa,0x0000004a,0x00000114,0x0000010e,0x00000049,0x000300f7,0x00000117, + 0x00000000,0x000400fa,0x00000114,0x00000116,0x0000011a,0x000200f8,0x0000011a,0x000200f9, + 0x00000117,0x000200f8,0x00000116,0x00050051,0x00000015,0x00000119,0x000000f3,0x00000001, + 0x000200f9,0x00000117,0x000200f8,0x00000117,0x000700f5,0x00000015,0x0000030a,0x00000102, + 0x0000011a,0x00000119,0x00000116,0x000500c2,0x00000015,0x0000011e,0x0000030a,0x000000ab, + 0x000500aa,0x0000004a,0x00000275,0x0000011e,0x00000049,0x000300f7,0x0000027e,0x00000000, + 0x000400fa,0x00000275,0x0000027d,0x00000276,0x000200f8,0x00000276,0x00050080,0x00000015, + 0x00000278,0x0000011e,0x00000051,0x00050084,0x00000015,0x0000027a,0x00000278,0x000000ff, + 0x0006000c,0x0000000f,0x0000027b,0x00000001,0x0000003e,0x0000027a,0x00050051,0x00000008, + 0x0000027c,0x0000027b,0x00000000,0x000200f9,0x0000027e,0x000200f8,0x0000027d,0x000200f9, + 0x0000027e,0x000200f8,0x0000027e,0x000700f5,0x00000008,0x0000030b,0x0000027c,0x00000276, + 0x0000003e,0x0000027d,0x000300f7,0x00000129,0x00000000,0x000400fa,0x00000114,0x00000128, + 0x00000129,0x000200f8,0x00000128,0x0004007f,0x00000008,0x0000012b,0x0000030b,0x000200f9, + 0x00000129,0x000200f8,0x00000129,0x000700f5,0x00000008,0x0000030c,0x0000030b,0x0000027e, + 0x0000012b,0x00000128,0x00050041,0x000000e1,0x0000012f,0x0000012d,0x00000049,0x0003003e, + 0x0000012f,0x0000030c,0x000200f9,0x00000111,0x000200f8,0x00000111,0x000300f7,0x00000132, + 0x00000000,0x000400fa,0x00000130,0x00000131,0x00000132,0x000200f8,0x00000131,0x000500c2, + 0x00000015,0x00000137,0x00000102,0x00000136,0x000500c7,0x00000015,0x00000138,0x00000137, + 0x0000010d,0x00040070,0x00000008,0x00000139,0x00000138,0x0003003e,0x00000133,0x00000139, + 0x000200f9,0x00000132,0x000200f8,0x00000132,0x000300f7,0x0000013e,0x00000000,0x000400fa, + 0x0000013c,0x0000013d,0x0000013e,0x000200f8,0x0000013d,0x00050080,0x00000015,0x00000146, + 0x00000239,0x000000a2,0x00060041,0x00000148,0x00000149,0x00000143,0x0000006d,0x00000146, + 0x0004003d,0x0000000d,0x0000014a,0x00000149,0x00050051,0x00000008,0x00000287,0x0000014a, + 0x00000000,0x00050051,0x00000008,0x00000288,0x0000014a,0x00000001,0x00050051,0x00000008, + 0x00000289,0x0000014a,0x00000002,0x00050051,0x00000008,0x0000028a,0x0000014a,0x00000003, + 0x00050050,0x0000000f,0x0000028b,0x00000287,0x00000288,0x00050050,0x0000000f,0x0000028c, + 0x00000289,0x0000028a,0x00050050,0x00000010,0x0000028d,0x0000028b,0x0000028c,0x00050080, + 0x00000015,0x00000150,0x00000239,0x0000014f,0x00060041,0x00000148,0x00000151,0x00000143, + 0x0000006d,0x00000150,0x0004003d,0x0000000d,0x00000152,0x00000151,0x0007004f,0x0000000f, + 0x00000159,0x00000152,0x00000152,0x00000000,0x00000001,0x000300f7,0x000002c3,0x00000000, + 0x000300fb,0x00000049,0x00000295,0x000200f8,0x00000295,0x0006000c,0x0000000f,0x00000298, + 0x00000001,0x00000004,0x0000028b,0x0006000c,0x0000000f,0x0000029b,0x00000001,0x00000004, + 0x0000028c,0x00050081,0x0000000f,0x0000029c,0x00000298,0x0000029b,0x00050051,0x00000008, + 0x0000029e,0x0000029c,0x00000000,0x000500b7,0x0000004a,0x0000029f,0x0000029e,0x0000003e, + 0x000300f7,0x000002a4,0x00000000,0x000400fa,0x0000029f,0x000002a0,0x000002a4,0x000200f8, + 0x000002a0,0x00050051,0x00000008,0x000002a2,0x0000029c,0x00000001,0x000500b7,0x0000004a, + 0x000002a3,0x000002a2,0x0000003e,0x000200f9,0x000002a4,0x000200f8,0x000002a4,0x000700f5, + 0x0000004a,0x000002a5,0x0000029f,0x00000295,0x000002a3,0x000002a0,0x000300f7,0x000002c2, + 0x00000000,0x000400fa,0x000002a5,0x000002a9,0x000002a6,0x000200f8,0x000002a6,0x0009004f, + 0x0000000d,0x000002a8,0x00000152,0x00000314,0x00000000,0x00000001,0x00000000,0x00000001, + 0x000200f9,0x000002c3,0x000200f8,0x000002a9,0x00050088,0x0000000f,0x000002ac,0x00000311, + 0x0000029c,0x00050091,0x0000000f,0x000002af,0x0000028d,0x0000024a,0x00050081,0x0000000f, + 0x000002b1,0x000002af,0x00000159,0x0004007f,0x0000000f,0x000002b4,0x000002b1,0x00050051, + 0x00000008,0x000002b5,0x000002b1,0x00000000,0x00050051,0x00000008,0x000002b6,0x000002b1, + 0x00000001,0x00050051,0x00000008,0x000002b7,0x000002b4,0x00000000,0x00050051,0x00000008, + 0x000002b8,0x000002b4,0x00000001,0x00070050,0x0000000d,0x000002b9,0x000002b5,0x000002b6, + 0x000002b7,0x000002b8,0x0009004f,0x0000000d,0x000002bb,0x000002ac,0x000002ac,0x00000000, + 0x00000001,0x00000000,0x00000001,0x00050085,0x0000000d,0x000002bc,0x000002b9,0x000002bb, + 0x00050081,0x0000000d,0x000002bf,0x000002bc,0x000002bb,0x00050081,0x0000000d,0x000002c1, + 0x000002bf,0x00000312,0x000200f9,0x000002c3,0x000200f8,0x000002c2,0x000100ff,0x000200f8, + 0x000002c3,0x000700f5,0x0000000d,0x0000030d,0x000002a8,0x000002a6,0x000002c1,0x000002a9, + 0x0003003e,0x00000154,0x0000030d,0x000200f9,0x0000013e,0x000200f8,0x0000013e,0x000500aa, + 0x0000004a,0x0000015e,0x0000010e,0x00000061,0x000300f7,0x00000160,0x00000000,0x000400fa, + 0x0000015e,0x0000015f,0x00000174,0x000200f8,0x00000174,0x000500aa,0x0000004a,0x00000176, + 0x0000010e,0x00000049,0x000500a7,0x0000004a,0x00000177,0x0000010f,0x00000176,0x000300f7, + 0x00000179,0x00000000,0x000400fa,0x00000177,0x00000178,0x00000185,0x000200f8,0x00000185, + 0x00060041,0x00000148,0x0000018a,0x00000143,0x0000006d,0x00000239,0x0004003d,0x0000000d, + 0x0000018b,0x0000018a,0x00050051,0x00000008,0x000002cb,0x0000018b,0x00000000,0x00050051, + 0x00000008,0x000002cc,0x0000018b,0x00000001,0x00050051,0x00000008,0x000002cd,0x0000018b, + 0x00000002,0x00050051,0x00000008,0x000002ce,0x0000018b,0x00000003,0x00050050,0x0000000f, + 0x000002cf,0x000002cb,0x000002cc,0x00050050,0x0000000f,0x000002d0,0x000002cd,0x000002ce, + 0x00050050,0x00000010,0x000002d1,0x000002cf,0x000002d0,0x00060041,0x00000148,0x00000191, + 0x00000143,0x0000006d,0x00000240,0x0004003d,0x0000000d,0x00000192,0x00000191,0x00050091, + 0x0000000f,0x00000196,0x000002d1,0x0000024a,0x0007004f,0x0000000f,0x00000198,0x00000192, + 0x00000192,0x00000000,0x00000001,0x00050081,0x0000000f,0x00000199,0x00000196,0x00000198, + 0x000500aa,0x0000004a,0x0000019b,0x0000010e,0x000000a2,0x000500aa,0x0000004a,0x0000019d, + 0x0000010e,0x0000014f,0x000500a6,0x0000004a,0x0000019e,0x0000019b,0x0000019d,0x000300f7, + 0x000001a0,0x00000000,0x000400fa,0x0000019e,0x0000019f,0x000001c6,0x000200f8,0x000001c6, + 0x00050051,0x00000015,0x000001c9,0x000000f3,0x00000001,0x0004007c,0x00000008,0x000001ca, + 0x000001c9,0x00050051,0x00000008,0x000001cd,0x00000192,0x00000002,0x00050051,0x00000008, + 0x000001cf,0x00000199,0x00000000,0x00050051,0x00000008,0x000001d1,0x00000199,0x00000001, + 0x00050083,0x00000008,0x000001d5,0x000001d3,0x000001cd,0x00070050,0x0000000d,0x000001d6, + 0x000001cf,0x000001d1,0x000001ca,0x000001d5,0x0003003e,0x00000172,0x000001d6,0x000200f9, + 0x000001a0,0x000200f8,0x0000019f,0x00050051,0x00000015,0x000001a2,0x000000f3,0x00000001, + 0x0004007c,0x00000008,0x000001a3,0x000001a2,0x0004007f,0x00000008,0x000001a4,0x000001a3, + 0x00050041,0x000000e1,0x000001a5,0x00000172,0x0000014f,0x0003003e,0x000001a5,0x000001a4, + 0x00050051,0x00000008,0x000001a8,0x00000192,0x00000002,0x000500ba,0x0000004a,0x000001ab, + 0x000001a8,0x000001aa,0x000300f7,0x000001ad,0x00000000,0x000400fa,0x000001ab,0x000001ac, + 0x000001b0,0x000200f8,0x000001b0,0x00050051,0x00000008,0x000001b2,0x00000192,0x00000003, + 0x00050041,0x000000e1,0x000001b3,0x00000172,0x000000a2,0x0003003e,0x000001b3,0x000001b2, + 0x000200f9,0x000001ad,0x000200f8,0x000001ac,0x00050041,0x000000e1,0x000001af,0x00000172, + 0x000000a2,0x0003003e,0x000001af,0x000001ae,0x000200f9,0x000001ad,0x000200f8,0x000001ad, + 0x000300f7,0x000001b7,0x00000000,0x000400fa,0x0000019b,0x000001b6,0x000001bc,0x000200f8, + 0x000001bc,0x00050041,0x000000e1,0x000001bd,0x00000172,0x000000a2,0x0004003d,0x00000008, + 0x000001be,0x000001bd,0x0004007f,0x00000008,0x000001bf,0x000001be,0x0003003e,0x000001bd, + 0x000001bf,0x00050041,0x000000e1,0x000001c2,0x00000172,0x00000049,0x00050051,0x00000008, + 0x000001c3,0x00000199,0x00000000,0x0003003e,0x000001c2,0x000001c3,0x00050041,0x000000e1, + 0x000001c4,0x00000172,0x00000061,0x00050051,0x00000008,0x000001c5,0x00000199,0x00000001, + 0x0003003e,0x000001c4,0x000001c5,0x000200f9,0x000001b7,0x000200f8,0x000001b6,0x00050041, + 0x000000e1,0x000001b8,0x00000172,0x00000061,0x0003003e,0x000001b8,0x0000003e,0x00050051, + 0x00000008,0x000001ba,0x00000199,0x00000000,0x00050041,0x000000e1,0x000001bb,0x00000172, + 0x00000049,0x0003003e,0x000001bb,0x000001ba,0x000200f9,0x000001b7,0x000200f8,0x000001b7, + 0x000200f9,0x000001a0,0x000200f8,0x000001a0,0x000200f9,0x00000179,0x000200f8,0x00000178, + 0x000500c2,0x00000015,0x0000017d,0x00000102,0x000000ab,0x000500aa,0x0000004a,0x000002d7, + 0x0000017d,0x00000049,0x000300f7,0x000002e0,0x00000000,0x000400fa,0x000002d7,0x000002df, + 0x000002d8,0x000200f8,0x000002d8,0x00050080,0x00000015,0x000002da,0x0000017d,0x00000051, + 0x00050084,0x00000015,0x000002dc,0x000002da,0x000000ff,0x0006000c,0x0000000f,0x000002dd, + 0x00000001,0x0000003e,0x000002dc,0x00050051,0x00000008,0x000002de,0x000002dd,0x00000000, + 0x000200f9,0x000002e0,0x000200f8,0x000002df,0x000200f9,0x000002e0,0x000200f8,0x000002e0, + 0x000700f5,0x00000008,0x0000030e,0x000002de,0x000002d8,0x0000003e,0x000002df,0x00050041, + 0x000000e1,0x00000184,0x0000012d,0x00000061,0x0003003e,0x00000184,0x0000030e,0x000200f9, + 0x00000179,0x000200f8,0x00000179,0x000200f9,0x00000160,0x000200f8,0x0000015f,0x00050051, + 0x00000015,0x00000163,0x000000f3,0x00000001,0x0006000c,0x0000000d,0x00000164,0x00000001, + 0x00000040,0x00000163,0x0003003e,0x00000172,0x00000164,0x000200f9,0x00000160,0x000200f8, + 0x00000160,0x00050041,0x000001e1,0x000001e2,0x000000f8,0x000001dc,0x0004003d,0x00000008, + 0x000001e3,0x000001e2,0x00050041,0x000001e1,0x000001e5,0x000000f8,0x000001dd,0x0004003d, + 0x00000008,0x000001e6,0x000001e5,0x00050051,0x00000008,0x000002e6,0x0000024a,0x00000000, + 0x00050085,0x00000008,0x000002e8,0x000002e6,0x000001e3,0x00050083,0x00000008,0x000002e9, + 0x000002e8,0x0000003d,0x00050051,0x00000008,0x000002eb,0x0000024a,0x00000001,0x00050085, + 0x00000008,0x000002ed,0x000002eb,0x000001e6,0x0006000c,0x00000008,0x000002ef,0x00000001, + 0x00000006,0x000001e6,0x00050083,0x00000008,0x000002f0,0x000002ed,0x000002ef,0x00070050, + 0x0000000d,0x000002f1,0x000002e9,0x000002f0,0x0000003e,0x0000003d,0x00050080,0x00000015, + 0x000001eb,0x00000239,0x0000014f,0x00060041,0x000000bb,0x000001ec,0x000000b7,0x0000006d, + 0x000001eb,0x0004003d,0x000000b3,0x000001ed,0x000001ec,0x0007004f,0x000000c9,0x000001f1, + 0x000001ed,0x000001ed,0x00000000,0x00000001,0x0003003e,0x000001ef,0x000001f1,0x0007004f, + 0x000000c9,0x000001f5,0x000001ed,0x000001ed,0x00000002,0x00000003,0x0004007c,0x0000000f, + 0x000001f6,0x000001f5,0x00050081,0x0000000f,0x000001f7,0x0000024a,0x000001f6,0x0003003e, + 0x000001f2,0x000001f7,0x00050041,0x00000153,0x00000208,0x00000206,0x0000006d,0x0003003e, + 0x00000208,0x000002f1,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..2563f8ef1fe02da7d648c070928fcab4ba0faa71 GIT binary patch literal 9040 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 TG_oa`+gmKW{rx@B&&m8JoLqyU literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.h new file mode 100644 index 000000000..abb97fa59 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.h @@ -0,0 +1,807 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_path_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000074b,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0010000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000038c, + 0x00000392,0x00000398,0x0000039e,0x000003b1,0x000003bd,0x000003fd,0x00000424,0x00000427, + 0x00000431,0x00000432,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000f5,0x0000674e,0x00030005,0x00000123, + 0x00004351,0x00030005,0x00000127,0x00003954,0x00030005,0x0000025b,0x00004444,0x00030005, + 0x0000025d,0x00006277,0x00030005,0x0000027d,0x00004344,0x00030005,0x0000027f,0x00003552, + 0x00030005,0x0000029e,0x0000674a,0x00030005,0x000002e4,0x00006454,0x00040006,0x000002e4, + 0x00000000,0x00003464,0x00030005,0x000002e6,0x00003053,0x00030005,0x000002ec,0x0000424d, + 0x00040006,0x000002ec,0x00000000,0x00003157,0x00040006,0x000002ec,0x00000001,0x00003376, + 0x00040006,0x000002ec,0x00000002,0x00003377,0x00030005,0x000002ee,0x0000006b,0x00030005, + 0x0000038a,0x00003046,0x00030005,0x0000038c,0x0000316b,0x00040005,0x0000038d,0x61726170, + 0x0000006d,0x00040005,0x0000038f,0x61726170,0x0000006d,0x00030005,0x00000391,0x00003071, + 0x00030005,0x00000392,0x00000049,0x00040005,0x00000393,0x61726170,0x0000006d,0x00030005, + 0x00000396,0x00003679,0x00030005,0x00000398,0x00003469,0x00030005,0x0000039c,0x0000374e, + 0x00030005,0x0000039e,0x00003361,0x00030005,0x000003a2,0x00003154,0x00040005,0x000003a7, + 0x61726170,0x0000006d,0x00040005,0x000003a8,0x61726170,0x0000006d,0x00030005,0x000003ac, + 0x00003149,0x00030005,0x000003ad,0x00006748,0x00030005,0x000003b0,0x00006263,0x00030005, + 0x000003b1,0x0000304e,0x00040005,0x000003b2,0x61726170,0x0000006d,0x00040005,0x000003b5, + 0x61726170,0x0000006d,0x00030005,0x000003ba,0x00006747,0x00030005,0x000003bd,0x00003153, + 0x00030005,0x000003c5,0x00006264,0x00040005,0x000003c8,0x30653742,0x00000000,0x00040005, + 0x000003d6,0x61726170,0x0000006d,0x00040005,0x000003dd,0x61726170,0x0000006d,0x00040005, + 0x000003e0,0x61726170,0x0000006d,0x00040005,0x000003e2,0x61726170,0x0000006d,0x00040005, + 0x000003e4,0x61726170,0x0000006d,0x00040005,0x000003ec,0x61726170,0x0000006d,0x00040005, + 0x000003ef,0x61726170,0x0000006d,0x00040005,0x000003f1,0x61726170,0x0000006d,0x00040005, + 0x000003f3,0x61726170,0x0000006d,0x00030005,0x000003fc,0x00003545,0x00060005,0x000003fd, + 0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00040005,0x00000400,0x61726170,0x0000006d, + 0x00040005,0x00000403,0x61726170,0x0000006d,0x00040005,0x00000407,0x61726170,0x0000006d, + 0x00030005,0x00000424,0x00003065,0x00040005,0x00000425,0x61726170,0x0000006d,0x00030005, + 0x00000427,0x0000316d,0x00030005,0x00000431,0x0000307a,0x00030005,0x00000432,0x00003159, + 0x00040047,0x000000f5,0x00000001,0x00000007,0x00030047,0x00000123,0x00000000,0x00040047, + 0x00000123,0x00000021,0x0000000a,0x00040047,0x00000123,0x00000022,0x00000000,0x00030047, + 0x00000127,0x00000000,0x00040047,0x00000127,0x00000021,0x0000000a,0x00040047,0x00000127, + 0x00000022,0x00000000,0x00030047,0x0000025b,0x00000000,0x00040047,0x0000025b,0x00000021, + 0x00000009,0x00040047,0x0000025b,0x00000022,0x00000000,0x00030047,0x0000025d,0x00000000, + 0x00040047,0x0000025d,0x00000021,0x00000009,0x00040047,0x0000025d,0x00000022,0x00000000, + 0x00030047,0x0000027d,0x00000000,0x00040047,0x0000027d,0x00000021,0x0000000c,0x00040047, + 0x0000027d,0x00000022,0x00000001,0x00030047,0x0000027f,0x00000000,0x00040047,0x0000027f, + 0x00000021,0x0000000c,0x00040047,0x0000027f,0x00000022,0x00000001,0x00040047,0x0000029e, + 0x00000001,0x00000003,0x00040047,0x000002e3,0x00000006,0x00000004,0x00030047,0x000002e4, + 0x00000003,0x00050048,0x000002e4,0x00000000,0x00000023,0x00000000,0x00040047,0x000002e6, + 0x00000021,0x00000007,0x00040047,0x000002e6,0x00000022,0x00000000,0x00030047,0x000002ec, + 0x00000002,0x00050048,0x000002ec,0x00000000,0x00000023,0x00000040,0x00050048,0x000002ec, + 0x00000001,0x00000023,0x00000058,0x00050048,0x000002ec,0x00000002,0x00000023,0x0000005c, + 0x00040047,0x000002ee,0x00000021,0x00000000,0x00040047,0x000002ee,0x00000022,0x00000000, + 0x00030047,0x0000038a,0x00000000,0x00040047,0x0000038c,0x0000001e,0x00000000,0x00030047, + 0x00000391,0x00000000,0x00040047,0x00000392,0x0000001e,0x00000002,0x00040047,0x00000398, + 0x0000001e,0x00000008,0x00030047,0x0000039e,0x0000000e,0x00040047,0x0000039e,0x0000001e, + 0x00000007,0x00030047,0x000003ac,0x00000000,0x00040047,0x000003ad,0x00000001,0x00000001, + 0x00030047,0x000003b0,0x00000000,0x00040047,0x000003b1,0x0000001e,0x00000005,0x00030047, + 0x000003b5,0x00000000,0x00030047,0x000003b7,0x00000000,0x00030047,0x000003b8,0x00000000, + 0x00030047,0x000003b9,0x00000000,0x00040047,0x000003ba,0x00000001,0x00000000,0x00030047, + 0x000003bd,0x00000000,0x00030047,0x000003bd,0x0000000e,0x00040047,0x000003bd,0x0000001e, + 0x00000004,0x00030047,0x000003c0,0x00000000,0x00030047,0x000003c5,0x00000000,0x00030047, + 0x000003c8,0x00000000,0x00040047,0x000003c8,0x00000021,0x00000001,0x00040047,0x000003c8, + 0x00000022,0x00000002,0x00040047,0x000003c8,0x0000002b,0x00000001,0x00030047,0x000003c9, + 0x00000000,0x00030047,0x000003cc,0x00000000,0x00030047,0x000003cd,0x00000000,0x00030047, + 0x000003ce,0x00000000,0x00030047,0x000003cf,0x00000000,0x00030047,0x000003d0,0x00000000, + 0x00030047,0x000003d1,0x00000000,0x00030047,0x000003d2,0x00000000,0x00030047,0x000003d3, + 0x00000000,0x00030047,0x000003d4,0x00000000,0x00030047,0x000003d5,0x00000000,0x00030047, + 0x000003df,0x00000000,0x00030047,0x000003e0,0x00000000,0x00030047,0x000003e1,0x00000000, + 0x00030047,0x000003ee,0x00000000,0x00030047,0x000003ef,0x00000000,0x00030047,0x000003f0, + 0x00000000,0x00030047,0x000003fc,0x00000000,0x00040047,0x000003fd,0x0000000b,0x0000000f, + 0x00030047,0x00000403,0x00000000,0x00030047,0x00000407,0x00000000,0x00030047,0x0000040c, + 0x00000000,0x00030047,0x0000040d,0x00000000,0x00030047,0x0000040e,0x00000000,0x00030047, + 0x0000040f,0x00000000,0x00030047,0x00000418,0x00000000,0x00030047,0x00000419,0x00000000, + 0x00030047,0x0000041a,0x00000000,0x00030047,0x0000041b,0x00000000,0x00030047,0x0000041c, + 0x00000000,0x00030047,0x00000424,0x00000000,0x00040047,0x00000424,0x0000001e,0x00000001, + 0x00030047,0x00000425,0x00000000,0x00030047,0x00000427,0x00000000,0x00040047,0x00000427, + 0x0000001e,0x00000000,0x00030047,0x00000428,0x00000000,0x00030047,0x00000431,0x00000000, + 0x00030047,0x00000431,0x0000000e,0x00040047,0x00000431,0x0000001e,0x00000003,0x00030047, + 0x00000432,0x00000000,0x00030047,0x00000432,0x0000000e,0x00040047,0x00000432,0x0000001e, + 0x00000006,0x00030047,0x0000044b,0x00000000,0x00030047,0x00000453,0x00000000,0x00030047, + 0x00000454,0x00000000,0x00030047,0x00000455,0x00000000,0x00030047,0x00000456,0x00000000, + 0x00030047,0x00000457,0x00000000,0x00030047,0x00000458,0x00000000,0x00030047,0x00000466, + 0x00000000,0x00030047,0x00000467,0x00000000,0x00030047,0x0000046b,0x00000000,0x00030047, + 0x0000046c,0x00000000,0x00030047,0x00000472,0x00000000,0x00030047,0x00000475,0x00000000, + 0x00030047,0x00000476,0x00000000,0x00030047,0x00000477,0x00000000,0x00030047,0x0000049c, + 0x00000000,0x00030047,0x0000049d,0x00000000,0x00030047,0x000004a2,0x00000000,0x00030047, + 0x000004a5,0x00000000,0x00030047,0x000004b0,0x00000000,0x00030047,0x000004b5,0x00000000, + 0x00030047,0x000004b6,0x00000000,0x00030047,0x000004b7,0x00000000,0x00030047,0x000004b9, + 0x00000000,0x00030047,0x000004ba,0x00000000,0x00030047,0x000004bc,0x00000000,0x00030047, + 0x000004c1,0x00000000,0x00030047,0x000004c2,0x00000000,0x00030047,0x000004c4,0x00000000, + 0x00030047,0x000004c5,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c7, + 0x00000000,0x00030047,0x000004c9,0x00000000,0x00030047,0x000004d0,0x00000000,0x00030047, + 0x000004d2,0x00000000,0x00030047,0x000004d3,0x00000000,0x00030047,0x000004d4,0x00000000, + 0x00030047,0x000004d7,0x00000000,0x00030047,0x000004d9,0x00000000,0x00030047,0x000004dd, + 0x00000000,0x00030047,0x000004ea,0x00000000,0x00030047,0x000004f1,0x00000000,0x00030047, + 0x000004f4,0x00000000,0x00030047,0x000004f5,0x00000000,0x00030047,0x00000500,0x00000000, + 0x00030047,0x00000506,0x00000000,0x00030047,0x0000050c,0x00000000,0x00030047,0x0000050d, + 0x00000000,0x00030047,0x0000050e,0x00000000,0x00030047,0x0000050f,0x00000000,0x00030047, + 0x00000510,0x00000000,0x00030047,0x00000511,0x00000000,0x00030047,0x00000512,0x00000000, + 0x00030047,0x00000513,0x00000000,0x00030047,0x00000514,0x00000000,0x00030047,0x00000515, + 0x00000000,0x00030047,0x00000516,0x00000000,0x00030047,0x00000517,0x00000000,0x00030047, + 0x00000518,0x00000000,0x00030047,0x00000519,0x00000000,0x00030047,0x0000051a,0x00000000, + 0x00030047,0x0000051b,0x00000000,0x00030047,0x0000051c,0x00000000,0x00030047,0x0000051d, + 0x00000000,0x00030047,0x0000051e,0x00000000,0x00030047,0x0000051f,0x00000000,0x00030047, + 0x00000520,0x00000000,0x00030047,0x00000521,0x00000000,0x00030047,0x00000528,0x00000000, + 0x00030047,0x0000052c,0x00000000,0x00030047,0x0000052d,0x00000000,0x00030047,0x0000052f, + 0x00000000,0x00030047,0x00000530,0x00000000,0x00030047,0x00000531,0x00000000,0x00030047, + 0x00000532,0x00000000,0x00030047,0x00000534,0x00000000,0x00030047,0x00000535,0x00000000, + 0x00030047,0x00000536,0x00000000,0x00030047,0x00000541,0x00000000,0x00030047,0x00000542, + 0x00000000,0x00030047,0x00000543,0x00000000,0x00030047,0x00000544,0x00000000,0x00030047, + 0x00000545,0x00000000,0x00030047,0x00000546,0x00000000,0x00030047,0x00000548,0x00000000, + 0x00030047,0x00000549,0x00000000,0x00030047,0x0000054a,0x00000000,0x00030047,0x0000054b, + 0x00000000,0x00030047,0x0000054c,0x00000000,0x00030047,0x0000054d,0x00000000,0x00030047, + 0x0000054e,0x00000000,0x00030047,0x0000054f,0x00000000,0x00030047,0x00000550,0x00000000, + 0x00030047,0x00000551,0x00000000,0x00030047,0x00000552,0x00000000,0x00030047,0x00000553, + 0x00000000,0x00030047,0x00000554,0x00000000,0x00030047,0x00000555,0x00000000,0x00030047, + 0x00000556,0x00000000,0x00030047,0x00000557,0x00000000,0x00030047,0x0000055a,0x00000000, + 0x00030047,0x0000055b,0x00000000,0x00030047,0x0000055d,0x00000000,0x00030047,0x0000055e, + 0x00000000,0x00030047,0x00000561,0x00000000,0x00030047,0x00000562,0x00000000,0x00030047, + 0x00000564,0x00000000,0x00030047,0x00000565,0x00000000,0x00030047,0x00000568,0x00000000, + 0x00030047,0x00000569,0x00000000,0x00030047,0x0000056b,0x00000000,0x00030047,0x0000056c, + 0x00000000,0x00030047,0x0000056f,0x00000000,0x00030047,0x00000570,0x00000000,0x00030047, + 0x00000577,0x00000000,0x00030047,0x00000578,0x00000000,0x00030047,0x00000579,0x00000000, + 0x00030047,0x0000057a,0x00000000,0x00030047,0x0000057b,0x00000000,0x00030047,0x0000057c, + 0x00000000,0x00030047,0x0000057d,0x00000000,0x00030047,0x0000057e,0x00000000,0x00030047, + 0x0000057f,0x00000000,0x00030047,0x00000580,0x00000000,0x00030047,0x00000581,0x00000000, + 0x00030047,0x00000582,0x00000000,0x00030047,0x00000583,0x00000000,0x00030047,0x00000584, + 0x00000000,0x00030047,0x00000585,0x00000000,0x00030047,0x00000587,0x00000000,0x00030047, + 0x0000058c,0x00000000,0x00030047,0x0000058d,0x00000000,0x00030047,0x0000058e,0x00000000, + 0x00030047,0x00000590,0x00000000,0x00030047,0x00000592,0x00000000,0x00030047,0x00000594, + 0x00000000,0x00030047,0x00000596,0x00000000,0x00030047,0x00000598,0x00000000,0x00030047, + 0x00000599,0x00000000,0x00030047,0x0000059a,0x00000000,0x00030047,0x0000059c,0x00000000, + 0x00030047,0x0000059e,0x00000000,0x00030047,0x000005a0,0x00000000,0x00030047,0x000005a2, + 0x00000000,0x00030047,0x000005a4,0x00000000,0x00030047,0x000005a6,0x00000000,0x00030047, + 0x000005a9,0x00000000,0x00030047,0x000005aa,0x00000000,0x00030047,0x000005b8,0x00000000, + 0x00030047,0x000005be,0x00000000,0x00030047,0x000005c7,0x00000000,0x00030047,0x000005c8, + 0x00000000,0x00030047,0x000005cd,0x00000000,0x00030047,0x000005ce,0x00000000,0x00030047, + 0x000005d9,0x00000000,0x00030047,0x000005da,0x00000000,0x00030047,0x000005e3,0x00000000, + 0x00030047,0x0000060a,0x00000000,0x00030047,0x0000060b,0x00000000,0x00030047,0x0000060e, + 0x00000000,0x00030047,0x0000060f,0x00000000,0x00030047,0x00000610,0x00000000,0x00030047, + 0x00000611,0x00000000,0x00030047,0x00000613,0x00000000,0x00030047,0x00000614,0x00000000, + 0x00030047,0x00000615,0x00000000,0x00030047,0x00000616,0x00000000,0x00030047,0x00000617, + 0x00000000,0x00030047,0x00000619,0x00000000,0x00030047,0x0000061b,0x00000000,0x00030047, + 0x0000061c,0x00000000,0x00030047,0x0000061d,0x00000000,0x00030047,0x00000624,0x00000000, + 0x00030047,0x00000626,0x00000000,0x00030047,0x0000062a,0x00000000,0x00030047,0x0000062c, + 0x00000000,0x00030047,0x0000062d,0x00000000,0x00030047,0x0000062e,0x00000000,0x00030047, + 0x0000062f,0x00000000,0x00030047,0x00000631,0x00000000,0x00030047,0x00000633,0x00000000, + 0x00030047,0x00000634,0x00000000,0x00030047,0x00000635,0x00000000,0x00030047,0x00000636, + 0x00000000,0x00030047,0x00000639,0x00000000,0x00030047,0x0000063a,0x00000000,0x00030047, + 0x00000640,0x00000000,0x00030047,0x00000671,0x00000000,0x00030047,0x00000672,0x00000000, + 0x00030047,0x00000673,0x00000000,0x00030047,0x00000674,0x00000000,0x00030047,0x00000678, + 0x00000000,0x00030047,0x0000067b,0x00000000,0x00030047,0x0000067e,0x00000000,0x00030047, + 0x00000687,0x00000000,0x00030047,0x00000688,0x00000000,0x00030047,0x00000689,0x00000000, + 0x00030047,0x0000068a,0x00000000,0x00030047,0x0000068b,0x00000000,0x00030047,0x0000068c, + 0x00000000,0x00030047,0x0000068d,0x00000000,0x00030047,0x0000068e,0x00000000,0x00030047, + 0x00000692,0x00000000,0x00030047,0x00000693,0x00000000,0x00030047,0x00000697,0x00000000, + 0x00030047,0x0000069a,0x00000000,0x00030047,0x000006a1,0x00000000,0x00030047,0x000006a2, + 0x00000000,0x00030047,0x000006a3,0x00000000,0x00030047,0x000006a4,0x00000000,0x00030047, + 0x000006a6,0x00000000,0x00030047,0x000006a7,0x00000000,0x00030047,0x000006ab,0x00000000, + 0x00030047,0x000006ac,0x00000000,0x00030047,0x000006ae,0x00000000,0x00030047,0x000006af, + 0x00000000,0x00030047,0x000006b0,0x00000000,0x00030047,0x000006b1,0x00000000,0x00030047, + 0x000006b2,0x00000000,0x00030047,0x000006b3,0x00000000,0x00030047,0x000006b4,0x00000000, + 0x00030047,0x000006b5,0x00000000,0x00030047,0x000006b6,0x00000000,0x00030047,0x000006b8, + 0x00000000,0x00030047,0x000006bf,0x00000000,0x00030047,0x000006c0,0x00000000,0x00030047, + 0x000006c1,0x00000000,0x00030047,0x000006c5,0x00000000,0x00030047,0x000006c6,0x00000000, + 0x00030047,0x000006c8,0x00000000,0x00030047,0x000006c9,0x00000000,0x00030047,0x000006ca, + 0x00000000,0x00030047,0x000006cb,0x00000000,0x00030047,0x000006cc,0x00000000,0x00030047, + 0x000006cd,0x00000000,0x00030047,0x000006ce,0x00000000,0x00030047,0x000006cf,0x00000000, + 0x00030047,0x000006d0,0x00000000,0x00030047,0x000006d3,0x00000000,0x00030047,0x000006d4, + 0x00000000,0x00030047,0x000006d5,0x00000000,0x00030047,0x000006d7,0x00000000,0x00030047, + 0x000006d8,0x00000000,0x00030047,0x000006d9,0x00000000,0x00030047,0x000006da,0x00000000, + 0x00030047,0x000006de,0x00000000,0x00030047,0x000006e3,0x00000000,0x00030047,0x000006e4, + 0x00000000,0x00030047,0x000006f5,0x00000000,0x00030047,0x000006f6,0x00000000,0x00030047, + 0x000006f7,0x00000000,0x00030047,0x000006f8,0x00000000,0x00030047,0x000006f9,0x00000000, + 0x00030047,0x000006fa,0x00000000,0x00030047,0x000006fe,0x00000000,0x00030047,0x00000700, + 0x00000000,0x00030047,0x00000707,0x00000000,0x00030047,0x00000708,0x00000000,0x00030047, + 0x00000709,0x00000000,0x00030047,0x0000070a,0x00000000,0x00030047,0x0000070c,0x00000000, + 0x00030047,0x0000070d,0x00000000,0x00030047,0x00000711,0x00000000,0x00030047,0x00000712, + 0x00000000,0x00030047,0x00000714,0x00000000,0x00030047,0x00000715,0x00000000,0x00030047, + 0x00000716,0x00000000,0x00030047,0x00000717,0x00000000,0x00030047,0x00000718,0x00000000, + 0x00030047,0x00000719,0x00000000,0x00030047,0x0000071a,0x00000000,0x00030047,0x0000071b, + 0x00000000,0x00030047,0x0000071c,0x00000000,0x00030047,0x0000071d,0x00000000,0x00030047, + 0x0000071f,0x00000000,0x00030047,0x00000720,0x00000000,0x00030047,0x00000721,0x00000000, + 0x00030047,0x00000726,0x00000000,0x00030047,0x00000727,0x00000000,0x00030047,0x0000072a, + 0x00000000,0x00030047,0x0000072b,0x00000000,0x00030047,0x0000072c,0x00000000,0x00030047, + 0x0000072d,0x00000000,0x00030047,0x00000737,0x00000000,0x00030047,0x00000738,0x00000000, + 0x00030047,0x00000739,0x00000000,0x00030047,0x0000073a,0x00000000,0x00030047,0x0000073b, + 0x00000000,0x00030047,0x0000073c,0x00000000,0x00030047,0x0000073d,0x00000000,0x00030047, + 0x0000073e,0x00000000,0x00030047,0x0000073f,0x00000000,0x00030047,0x00000740,0x00000000, + 0x00030047,0x00000742,0x00000000,0x00030047,0x00000744,0x00000000,0x00030047,0x00000746, + 0x00000000,0x00030047,0x00000748,0x00000000,0x00030047,0x0000074a,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000, + 0x00040020,0x00000007,0x00000007,0x00000006,0x00030016,0x00000008,0x00000020,0x00040015, + 0x0000000d,0x00000020,0x00000001,0x00040020,0x0000000e,0x00000007,0x0000000d,0x00040017, + 0x00000013,0x00000008,0x00000004,0x00040020,0x00000014,0x00000007,0x00000013,0x00040020, + 0x00000019,0x00000007,0x00000008,0x00040017,0x00000021,0x00000008,0x00000003,0x00040020, + 0x00000022,0x00000007,0x00000021,0x00040017,0x00000034,0x00000008,0x00000002,0x00040020, + 0x00000035,0x00000007,0x00000034,0x00020014,0x00000041,0x00040017,0x00000058,0x00000006, + 0x00000002,0x00040020,0x00000059,0x00000007,0x00000058,0x0004002b,0x00000006,0x00000096, + 0x00000000,0x0004002b,0x00000006,0x00000099,0x00000001,0x0004002b,0x00000006,0x0000009c, + 0x00000002,0x0004002b,0x00000006,0x0000009f,0x00000003,0x0004002b,0x00000008,0x000000c1, + 0x00000000,0x0004002b,0x00000008,0x000000c6,0x3f800000,0x0004002b,0x00000008,0x000000df, + 0x3d897143,0x0004002b,0x00000008,0x000000e3,0x3bbf4590,0x0004002b,0x00000008,0x000000ea, + 0x4253ee82,0x00030030,0x00000041,0x000000f5,0x0004002b,0x00000008,0x0000010b,0xbfc00000, + 0x00090019,0x00000121,0x00000008,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x00000122,0x00000000,0x00000121,0x0004003b,0x00000122,0x00000123, + 0x00000000,0x0002001a,0x00000125,0x00040020,0x00000126,0x00000000,0x00000125,0x0004003b, + 0x00000126,0x00000127,0x00000000,0x0003001b,0x00000129,0x00000121,0x0004002b,0x00000008, + 0x00000133,0x447a0000,0x0004002b,0x00000008,0x0000013b,0x3e800000,0x0004002b,0x00000008, + 0x00000141,0xc0000000,0x0004002b,0x00000008,0x00000147,0x3f19319f,0x0004002b,0x00000008, + 0x0000014c,0x3e55e621,0x0004002b,0x00000008,0x0000014d,0x3f206c99,0x0004002b,0x00000008, + 0x0000014e,0x3f85afd5,0x0004002b,0x00000008,0x0000014f,0x3fbb295d,0x0004002b,0x00000008, + 0x0000018c,0x40a311dd,0x0004002b,0x00000008,0x0000018e,0xc02311dd,0x0004002b,0x00000008, + 0x000001a9,0x40400000,0x0004002b,0x00000008,0x000001cf,0x388205ff,0x0004002b,0x00000006, + 0x000001d7,0x00000005,0x0004002b,0x00000006,0x000001df,0x00000400,0x0004002b,0x00000006, + 0x000001e4,0x0000001f,0x0004002b,0x00000006,0x000001e7,0x00000080,0x0004002b,0x00000006, + 0x000001ed,0x00000010,0x0004002b,0x00000006,0x000001f5,0x00000004,0x0004002b,0x00000006, + 0x00000201,0x0007ffff,0x0004002b,0x00000006,0x00000203,0x00040000,0x0004002b,0x00000008, + 0x00000208,0x3a800000,0x0004002b,0x00000008,0x0000020d,0x44800000,0x0004002b,0x00000008, + 0x0000020f,0x3f000000,0x0004002b,0x00000008,0x0000022e,0xbf800000,0x0004002b,0x00000008, + 0x0000024c,0x3f7f8000,0x0004002b,0x00000008,0x00000251,0x3b000000,0x0004003b,0x00000122, + 0x0000025b,0x00000000,0x0004003b,0x00000126,0x0000025d,0x00000000,0x0004003b,0x00000122, + 0x0000027d,0x00000000,0x0004003b,0x00000126,0x0000027f,0x00000000,0x00030030,0x00000041, + 0x0000029e,0x0003001d,0x000002e3,0x00000006,0x0003001e,0x000002e4,0x000002e3,0x00040020, + 0x000002e5,0x00000002,0x000002e4,0x0004003b,0x000002e5,0x000002e6,0x00000002,0x0004002b, + 0x0000000d,0x000002e7,0x00000000,0x00040020,0x000002e9,0x00000002,0x00000006,0x0005001e, + 0x000002ec,0x00000006,0x00000008,0x00000008,0x00040020,0x000002ed,0x00000002,0x000002ec, + 0x0004003b,0x000002ed,0x000002ee,0x00000002,0x00040020,0x0000038b,0x00000001,0x00000013, + 0x0004003b,0x0000038b,0x0000038c,0x00000001,0x0004003b,0x0000038b,0x00000392,0x00000001, + 0x00040020,0x00000397,0x00000001,0x00000034,0x0004003b,0x00000397,0x00000398,0x00000001, + 0x00040020,0x0000039d,0x00000001,0x00000058,0x0004003b,0x0000039d,0x0000039e,0x00000001, + 0x00040020,0x0000039f,0x00000001,0x00000006,0x00030030,0x00000041,0x000003ad,0x0004003b, + 0x0000038b,0x000003b1,0x00000001,0x00030030,0x00000041,0x000003ba,0x0004003b,0x00000397, + 0x000003bd,0x00000001,0x00040020,0x000003be,0x00000001,0x00000008,0x00090019,0x000003c6, + 0x00000008,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020, + 0x000003c7,0x00000000,0x000003c6,0x0004003b,0x000003c7,0x000003c8,0x00000000,0x00040017, + 0x000003ca,0x0000000d,0x00000002,0x0005002c,0x000003ca,0x000003cb,0x000002e7,0x000002e7, + 0x0004003b,0x0000038b,0x000003fd,0x00000001,0x00040020,0x00000404,0x00000002,0x00000008, + 0x00040020,0x00000423,0x00000003,0x00000013,0x0004003b,0x00000423,0x00000424,0x00000003, + 0x0004003b,0x00000423,0x00000427,0x00000003,0x0004003b,0x000003be,0x00000431,0x00000001, + 0x0004003b,0x000003be,0x00000432,0x00000001,0x0007002c,0x00000013,0x00000433,0x0000018e, + 0x0000018e,0x0000018e,0x0000018e,0x00040020,0x00000438,0x00000007,0x00000041,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000014, + 0x0000073f,0x00000007,0x0004003b,0x00000014,0x00000740,0x00000007,0x0004003b,0x00000019, + 0x0000072b,0x00000007,0x0004003b,0x00000019,0x0000072c,0x00000007,0x0004003b,0x00000019, + 0x0000072d,0x00000007,0x0004003b,0x00000019,0x0000071d,0x00000007,0x0004003b,0x00000035, + 0x0000071e,0x00000007,0x0004003b,0x00000019,0x0000071f,0x00000007,0x0004003b,0x00000019, + 0x00000720,0x00000007,0x0004003b,0x00000019,0x00000721,0x00000007,0x0004003b,0x00000019, + 0x00000712,0x00000007,0x0004003b,0x00000019,0x0000070c,0x00000007,0x0004003b,0x00000019, + 0x0000070d,0x00000007,0x0004003b,0x00000007,0x00000704,0x00000007,0x0004003b,0x00000007, + 0x00000705,0x00000007,0x0004003b,0x00000007,0x000006d2,0x00000007,0x0004003b,0x00000019, + 0x000006d3,0x00000007,0x0004003b,0x00000019,0x000006d4,0x00000007,0x0004003b,0x00000019, + 0x000006d5,0x00000007,0x0004003b,0x00000007,0x000006d6,0x00000007,0x0004003b,0x00000019, + 0x000006d7,0x00000007,0x0004003b,0x00000019,0x000006d8,0x00000007,0x0004003b,0x00000019, + 0x000006d9,0x00000007,0x0004003b,0x00000019,0x000006da,0x00000007,0x0004003b,0x00000019, + 0x000006c6,0x00000007,0x0004003b,0x00000019,0x000006c0,0x00000007,0x0004003b,0x00000019, + 0x000006c1,0x00000007,0x0004003b,0x0000000e,0x000006b7,0x00000007,0x0004003b,0x00000019, + 0x000006b8,0x00000007,0x0004003b,0x00000019,0x000006ac,0x00000007,0x0004003b,0x00000019, + 0x000006a6,0x00000007,0x0004003b,0x00000019,0x000006a7,0x00000007,0x0004003b,0x00000007, + 0x0000069e,0x00000007,0x0004003b,0x00000007,0x0000069f,0x00000007,0x0004003b,0x00000019, + 0x00000624,0x00000007,0x0004003b,0x00000007,0x00000625,0x00000007,0x0004003b,0x00000019, + 0x00000626,0x00000007,0x0004003b,0x00000007,0x00000627,0x00000007,0x0004003b,0x00000007, + 0x00000628,0x00000007,0x0004003b,0x00000007,0x00000629,0x00000007,0x0004003b,0x00000019, + 0x0000062a,0x00000007,0x0004003b,0x00000007,0x0000062b,0x00000007,0x0004003b,0x00000019, + 0x0000062c,0x00000007,0x0004003b,0x00000019,0x0000062d,0x00000007,0x0004003b,0x00000019, + 0x0000062e,0x00000007,0x0004003b,0x00000019,0x0000062f,0x00000007,0x0004003b,0x00000007, + 0x00000630,0x00000007,0x0004003b,0x00000019,0x00000631,0x00000007,0x0004003b,0x00000007, + 0x00000632,0x00000007,0x0004003b,0x00000019,0x00000633,0x00000007,0x0004003b,0x00000019, + 0x00000634,0x00000007,0x0004003b,0x00000019,0x00000635,0x00000007,0x0004003b,0x00000019, + 0x00000636,0x00000007,0x0004003b,0x00000438,0x0000061e,0x00000007,0x0004003b,0x00000035, + 0x0000060f,0x00000007,0x0004003b,0x00000019,0x00000610,0x00000007,0x0004003b,0x00000019, + 0x00000611,0x00000007,0x0004003b,0x00000014,0x0000060a,0x00000007,0x0004003b,0x00000014, + 0x0000060b,0x00000007,0x0004003b,0x00000007,0x000005e4,0x00000007,0x0004003b,0x00000007, + 0x000005e5,0x00000007,0x0004003b,0x00000019,0x000005c4,0x00000007,0x0004003b,0x00000019, + 0x000005c5,0x00000007,0x0004003b,0x00000019,0x000005c6,0x00000007,0x0004003b,0x00000019, + 0x000005c7,0x00000007,0x0004003b,0x00000019,0x000005c8,0x00000007,0x0004003b,0x00000438, + 0x000005bf,0x00000007,0x0004003b,0x00000019,0x000005a6,0x00000007,0x0004003b,0x00000014, + 0x000005a7,0x00000007,0x0004003b,0x00000014,0x000005a8,0x00000007,0x0004003b,0x00000019, + 0x000005a9,0x00000007,0x0004003b,0x00000019,0x000005aa,0x00000007,0x0004003b,0x00000014, + 0x00000599,0x00000007,0x0004003b,0x00000014,0x0000059a,0x00000007,0x0004003b,0x00000014, + 0x0000058d,0x00000007,0x0004003b,0x00000014,0x0000058e,0x00000007,0x0004003b,0x00000019, + 0x0000050c,0x00000007,0x0004003b,0x00000019,0x0000050d,0x00000007,0x0004003b,0x00000019, + 0x0000050e,0x00000007,0x0004003b,0x00000019,0x0000050f,0x00000007,0x0004003b,0x00000019, + 0x00000510,0x00000007,0x0004003b,0x00000019,0x00000511,0x00000007,0x0004003b,0x00000019, + 0x00000512,0x00000007,0x0004003b,0x00000014,0x00000513,0x00000007,0x0004003b,0x00000019, + 0x00000514,0x00000007,0x0004003b,0x00000019,0x00000515,0x00000007,0x0004003b,0x00000019, + 0x00000516,0x00000007,0x0004003b,0x00000019,0x00000517,0x00000007,0x0004003b,0x00000014, + 0x00000518,0x00000007,0x0004003b,0x00000014,0x00000519,0x00000007,0x0004003b,0x00000019, + 0x0000051a,0x00000007,0x0004003b,0x00000019,0x0000051b,0x00000007,0x0004003b,0x00000019, + 0x0000051c,0x00000007,0x0004003b,0x00000019,0x0000051d,0x00000007,0x0004003b,0x00000014, + 0x0000051e,0x00000007,0x0004003b,0x00000014,0x0000051f,0x00000007,0x0004003b,0x00000019, + 0x00000520,0x00000007,0x0004003b,0x00000019,0x00000521,0x00000007,0x0004003b,0x00000438, + 0x00000507,0x00000007,0x0004003b,0x00000019,0x000004f1,0x00000007,0x0004003b,0x00000014, + 0x000004f2,0x00000007,0x0004003b,0x00000014,0x000004f3,0x00000007,0x0004003b,0x00000019, + 0x000004f4,0x00000007,0x0004003b,0x00000019,0x000004f5,0x00000007,0x0004003b,0x00000438, + 0x000004eb,0x00000007,0x0004003b,0x00000019,0x000004d9,0x00000007,0x0004003b,0x00000014, + 0x000004da,0x00000007,0x0004003b,0x00000014,0x000004db,0x00000007,0x0004003b,0x00000014, + 0x000004dc,0x00000007,0x0004003b,0x00000019,0x000004dd,0x00000007,0x0004003b,0x00000014, + 0x000004d3,0x00000007,0x0004003b,0x00000014,0x000004d4,0x00000007,0x0004003b,0x00000014, + 0x000004c6,0x00000007,0x0004003b,0x00000014,0x000004c7,0x00000007,0x0004003b,0x00000019, + 0x000004b6,0x00000007,0x0004003b,0x00000022,0x000004b7,0x00000007,0x0004003b,0x00000014, + 0x0000044b,0x00000007,0x0004003b,0x00000014,0x0000044c,0x00000007,0x0004003b,0x00000019, + 0x0000044d,0x00000007,0x0004003b,0x00000019,0x0000044e,0x00000007,0x0004003b,0x00000019, + 0x0000044f,0x00000007,0x0004003b,0x00000019,0x00000450,0x00000007,0x0004003b,0x00000019, + 0x00000451,0x00000007,0x0004003b,0x00000019,0x00000452,0x00000007,0x0004003b,0x00000019, + 0x00000453,0x00000007,0x0004003b,0x00000019,0x00000454,0x00000007,0x0004003b,0x00000014, + 0x00000455,0x00000007,0x0004003b,0x00000022,0x00000456,0x00000007,0x0004003b,0x00000019, + 0x00000457,0x00000007,0x0004003b,0x00000014,0x00000458,0x00000007,0x0004003b,0x00000014, + 0x0000038a,0x00000007,0x0004003b,0x00000014,0x0000038d,0x00000007,0x0004003b,0x00000019, + 0x0000038f,0x00000007,0x0004003b,0x00000019,0x00000391,0x00000007,0x0004003b,0x00000014, + 0x00000393,0x00000007,0x0004003b,0x00000035,0x00000396,0x00000007,0x0004003b,0x00000007, + 0x0000039c,0x00000007,0x0004003b,0x00000007,0x000003a2,0x00000007,0x0004003b,0x00000059, + 0x000003a7,0x00000007,0x0004003b,0x00000007,0x000003a8,0x00000007,0x0004003b,0x00000019, + 0x000003ac,0x00000007,0x0004003b,0x00000019,0x000003b0,0x00000007,0x0004003b,0x00000014, + 0x000003b2,0x00000007,0x0004003b,0x00000014,0x000003b5,0x00000007,0x0004003b,0x00000019, + 0x000003c5,0x00000007,0x0004003b,0x00000014,0x000003d6,0x00000007,0x0004003b,0x00000019, + 0x000003dd,0x00000007,0x0004003b,0x00000019,0x000003e0,0x00000007,0x0004003b,0x00000007, + 0x000003e2,0x00000007,0x0004003b,0x00000007,0x000003e4,0x00000007,0x0004003b,0x00000019, + 0x000003ec,0x00000007,0x0004003b,0x00000019,0x000003ef,0x00000007,0x0004003b,0x00000007, + 0x000003f1,0x00000007,0x0004003b,0x00000007,0x000003f3,0x00000007,0x0004003b,0x00000019, + 0x000003fc,0x00000007,0x0004003b,0x00000035,0x00000400,0x00000007,0x0004003b,0x00000019, + 0x00000403,0x00000007,0x0004003b,0x00000019,0x00000407,0x00000007,0x0004003b,0x00000019, + 0x00000425,0x00000007,0x0004003d,0x00000013,0x0000038e,0x0000038c,0x0003003e,0x0000038d, + 0x0000038e,0x0003003e,0x0000038f,0x000000c6,0x00050041,0x00000019,0x0000045a,0x0000038d, + 0x0000009f,0x0004003d,0x00000008,0x0000045b,0x0000045a,0x000500be,0x00000041,0x0000045c, + 0x0000045b,0x000000c1,0x000300f7,0x000004b4,0x00000000,0x000400fa,0x0000045c,0x000004aa, + 0x0000045d,0x000200f8,0x0000045d,0x0004003d,0x00000008,0x0000045f,0x0000045a,0x000500ba, + 0x00000041,0x00000460,0x0000045f,0x0000022e,0x000300f7,0x000004a9,0x00000000,0x000400fa, + 0x00000460,0x0000047a,0x00000461,0x000200f8,0x00000461,0x0004003d,0x00000008,0x00000463, + 0x0000045a,0x00050083,0x00000008,0x00000465,0x00000141,0x00000463,0x0003003e,0x00000453, + 0x00000465,0x0004003d,0x00000121,0x00000466,0x0000027d,0x0004003d,0x00000125,0x00000467, + 0x0000027f,0x00050056,0x00000129,0x00000468,0x00000466,0x00000467,0x0004003d,0x00000013, + 0x00000469,0x0000038d,0x0007004f,0x00000034,0x0000046a,0x00000469,0x00000469,0x00000000, + 0x00000001,0x0004003d,0x00000008,0x0000046b,0x00000453,0x00070058,0x00000013,0x0000046c, + 0x00000468,0x0000046a,0x00000002,0x0000046b,0x0003003e,0x0000044b,0x0000046c,0x00050041, + 0x00000019,0x0000046d,0x0000038d,0x0000009c,0x0004003d,0x00000008,0x0000046e,0x0000046d, + 0x0004003d,0x00000008,0x0000046f,0x0000038f,0x00050085,0x00000008,0x00000470,0x0000046e, + 0x0000046f,0x0003003e,0x00000454,0x00000470,0x0004003d,0x00000013,0x00000472,0x0000044b, + 0x0003003e,0x00000455,0x00000472,0x0004003d,0x00000013,0x000004b9,0x00000455,0x0008004f, + 0x00000021,0x000004ba,0x000004b9,0x000004b9,0x00000000,0x00000001,0x00000002,0x00050041, + 0x00000019,0x000004bb,0x00000455,0x0000009f,0x0004003d,0x00000008,0x000004bc,0x000004bb, + 0x000500b7,0x00000041,0x000004bd,0x000004bc,0x000000c1,0x000300f7,0x000004c3,0x00000000, + 0x000400fa,0x000004bd,0x000004bf,0x000004be,0x000200f8,0x000004be,0x0003003e,0x000004b6, + 0x000000c1,0x000200f9,0x000004c3,0x000200f8,0x000004bf,0x0004003d,0x00000008,0x000004c1, + 0x000004bb,0x00050088,0x00000008,0x000004c2,0x000000c6,0x000004c1,0x0003003e,0x000004b6, + 0x000004c2,0x000200f9,0x000004c3,0x000200f8,0x000004c3,0x0004003d,0x00000008,0x000004c4, + 0x000004b6,0x0005008e,0x00000021,0x000004c5,0x000004ba,0x000004c4,0x0003003e,0x000004b7, + 0x000004c5,0x0004003d,0x00000021,0x00000473,0x000004b7,0x00050041,0x00000019,0x00000474, + 0x0000044b,0x0000009f,0x0004003d,0x00000008,0x00000475,0x00000474,0x0004003d,0x00000008, + 0x00000476,0x00000454,0x00050085,0x00000008,0x00000477,0x00000475,0x00000476,0x0003003e, + 0x00000456,0x00000473,0x0003003e,0x00000457,0x00000477,0x0004003d,0x00000021,0x000004c9, + 0x00000456,0x00050041,0x00000019,0x000004ca,0x000004c6,0x00000096,0x00050051,0x00000008, + 0x000004cb,0x000004c9,0x00000000,0x0003003e,0x000004ca,0x000004cb,0x00050041,0x00000019, + 0x000004cc,0x000004c6,0x00000099,0x00050051,0x00000008,0x000004cd,0x000004c9,0x00000001, + 0x0003003e,0x000004cc,0x000004cd,0x00050041,0x00000019,0x000004ce,0x000004c6,0x0000009c, + 0x00050051,0x00000008,0x000004cf,0x000004c9,0x00000002,0x0003003e,0x000004ce,0x000004cf, + 0x0004003d,0x00000008,0x000004d0,0x00000457,0x00050041,0x00000019,0x000004d1,0x000004c6, + 0x0000009f,0x0003003e,0x000004d1,0x000004d0,0x0004003d,0x00000013,0x000004d2,0x000004c6, + 0x0003003e,0x000004c7,0x000004d2,0x0004003d,0x00000013,0x00000478,0x000004c7,0x0003003e, + 0x0000044b,0x00000478,0x000200f9,0x000004a9,0x000200f8,0x0000047a,0x00050041,0x00000019, + 0x0000047b,0x0000038d,0x0000009c,0x0004003d,0x00000008,0x0000047c,0x0000047b,0x000500ba, + 0x00000041,0x0000047d,0x0000047c,0x000000c1,0x000300f7,0x00000485,0x00000000,0x000400fa, + 0x0000047d,0x00000482,0x0000047e,0x000200f8,0x0000047e,0x0004003d,0x00000013,0x0000047f, + 0x0000038d,0x0007004f,0x00000034,0x00000480,0x0000047f,0x0000047f,0x00000000,0x00000001, + 0x0006000c,0x00000008,0x00000481,0x00000001,0x00000042,0x00000480,0x0003003e,0x0000044e, + 0x00000481,0x000200f9,0x00000485,0x000200f8,0x00000482,0x00050041,0x00000019,0x00000483, + 0x0000038d,0x00000096,0x0004003d,0x00000008,0x00000484,0x00000483,0x0003003e,0x0000044e, + 0x00000484,0x000200f9,0x00000485,0x000200f8,0x00000485,0x0004003d,0x00000008,0x00000486, + 0x0000044e,0x0003003e,0x0000044d,0x00000486,0x0004003d,0x00000008,0x00000487,0x0000044d, + 0x0008000c,0x00000008,0x00000488,0x00000001,0x0000002b,0x00000487,0x000000c1,0x000000c6, + 0x0003003e,0x0000044d,0x00000488,0x0004003d,0x00000008,0x0000048a,0x0000047b,0x0006000c, + 0x00000008,0x0000048b,0x00000001,0x00000004,0x0000048a,0x0003003e,0x0000044f,0x0000048b, + 0x0004003d,0x00000008,0x0000048c,0x0000044f,0x000500ba,0x00000041,0x0000048d,0x0000048c, + 0x000000c6,0x000300f7,0x00000497,0x00000000,0x000400fa,0x0000048d,0x00000493,0x0000048e, + 0x000200f8,0x0000048e,0x0004003d,0x00000008,0x0000048f,0x0000044d,0x00050085,0x00000008, + 0x00000490,0x00000251,0x0000048f,0x0004003d,0x00000008,0x00000491,0x0000044f,0x00050081, + 0x00000008,0x00000492,0x00000490,0x00000491,0x0003003e,0x00000451,0x00000492,0x000200f9, + 0x00000497,0x000200f8,0x00000493,0x0004003d,0x00000008,0x00000494,0x0000044d,0x00050085, + 0x00000008,0x00000495,0x0000024c,0x00000494,0x00050081,0x00000008,0x00000496,0x00000495, + 0x00000208,0x0003003e,0x00000451,0x00000496,0x000200f9,0x00000497,0x000200f8,0x00000497, + 0x0004003d,0x00000008,0x00000498,0x00000451,0x0003003e,0x00000450,0x00000498,0x0004003d, + 0x00000008,0x0000049a,0x0000045a,0x0004007f,0x00000008,0x0000049b,0x0000049a,0x0003003e, + 0x00000452,0x0000049b,0x0004003d,0x00000121,0x0000049c,0x0000025b,0x0004003d,0x00000125, + 0x0000049d,0x0000025d,0x00050056,0x00000129,0x0000049e,0x0000049c,0x0000049d,0x0004003d, + 0x00000008,0x0000049f,0x00000450,0x0004003d,0x00000008,0x000004a0,0x00000452,0x00050050, + 0x00000034,0x000004a1,0x0000049f,0x000004a0,0x00070058,0x00000013,0x000004a2,0x0000049e, + 0x000004a1,0x00000002,0x000000c1,0x0003003e,0x0000044b,0x000004a2,0x0004003d,0x00000008, + 0x000004a3,0x0000038f,0x00050041,0x00000019,0x000004a4,0x0000044b,0x0000009f,0x0004003d, + 0x00000008,0x000004a5,0x000004a4,0x00050085,0x00000008,0x000004a6,0x000004a5,0x000004a3, + 0x0003003e,0x000004a4,0x000004a6,0x000200f9,0x000004a9,0x000200f8,0x000004a9,0x000200f9, + 0x000004b4,0x000200f8,0x000004aa,0x0004003d,0x00000013,0x000004ab,0x0000038d,0x0003003e, + 0x0000044c,0x000004ab,0x0004003d,0x00000013,0x000004d6,0x0000044c,0x0003003e,0x000004d3, + 0x000004d6,0x0004003d,0x00000013,0x000004d7,0x000004d3,0x0003003e,0x000004d4,0x000004d7, + 0x0004003d,0x00000013,0x000004ac,0x000004d4,0x0003003e,0x0000044b,0x000004ac,0x0004003d, + 0x00000008,0x000004ae,0x0000038f,0x00050041,0x00000019,0x000004af,0x0000044b,0x0000009f, + 0x0004003d,0x00000008,0x000004b0,0x000004af,0x00050085,0x00000008,0x000004b1,0x000004b0, + 0x000004ae,0x0003003e,0x000004af,0x000004b1,0x000200f9,0x000004b4,0x000200f8,0x000004b4, + 0x0004003d,0x00000013,0x000004b5,0x0000044b,0x0003003e,0x00000458,0x000004b5,0x0004003d, + 0x00000013,0x00000390,0x00000458,0x0003003e,0x0000038a,0x00000390,0x0004003d,0x00000013, + 0x00000394,0x00000392,0x0003003e,0x00000393,0x00000394,0x000300f7,0x000004e9,0x00000000, + 0x000300fb,0x00000096,0x000004df,0x000200f8,0x000004df,0x0004003d,0x00000013,0x000004e0, + 0x00000393,0x0003003e,0x000004da,0x000004e0,0x00050041,0x00000019,0x000004ed,0x000004da, + 0x00000099,0x0004003d,0x00000008,0x000004ee,0x000004ed,0x000500be,0x00000041,0x000004ef, + 0x000004ee,0x000000c1,0x0003003e,0x000004eb,0x000004ef,0x0004003d,0x00000041,0x000004e1, + 0x000004eb,0x000300f7,0x000004e8,0x00000000,0x000400fa,0x000004e1,0x000004e5,0x000004e2, + 0x000200f8,0x000004e2,0x0004003d,0x00000013,0x000004e3,0x00000393,0x0003003e,0x000004dc, + 0x000004e3,0x000300f7,0x00000505,0x00000000,0x000300fb,0x00000096,0x000004f7,0x000200f8, + 0x000004f7,0x000300f7,0x000004fb,0x00000000,0x000400fa,0x0000029e,0x000004f8,0x000004fb, + 0x000200f8,0x000004f8,0x0004003d,0x00000013,0x000004f9,0x000004dc,0x0003003e,0x000004f2, + 0x000004f9,0x00050041,0x00000019,0x00000509,0x000004f2,0x00000099,0x0004003d,0x00000008, + 0x0000050a,0x00000509,0x000500b8,0x00000041,0x0000050b,0x0000050a,0x0000010b,0x0003003e, + 0x00000507,0x0000050b,0x0004003d,0x00000041,0x000004fa,0x00000507,0x000200f9,0x000004fb, + 0x000200f8,0x000004fb,0x000700f5,0x00000041,0x000004fc,0x0000029e,0x000004f7,0x000004fa, + 0x000004f8,0x000300f7,0x00000504,0x00000000,0x000400fa,0x000004fc,0x00000501,0x000004fd, + 0x000200f8,0x000004fd,0x00050041,0x00000019,0x000004fe,0x000004dc,0x00000096,0x0004003d, + 0x00000008,0x000004ff,0x000004fe,0x0003003e,0x000004f4,0x000004ff,0x0004003d,0x00000008, + 0x00000500,0x000004f4,0x0003003e,0x000004f1,0x00000500,0x000200f9,0x00000505,0x000200f8, + 0x00000501,0x0004003d,0x00000013,0x00000502,0x000004dc,0x0003003e,0x000004f3,0x00000502, + 0x00050041,0x00000019,0x00000523,0x000004f3,0x0000009c,0x0004003d,0x00000008,0x00000524, + 0x00000523,0x0003003e,0x0000050c,0x00000524,0x00050041,0x00000019,0x00000525,0x000004f3, + 0x0000009f,0x0004003d,0x00000008,0x00000526,0x00000525,0x0007000c,0x00000008,0x00000527, + 0x00000001,0x00000028,0x00000526,0x000000c1,0x0003003e,0x0000050d,0x00000527,0x0004003d, + 0x00000008,0x00000528,0x0000050c,0x000500be,0x00000041,0x00000529,0x00000528,0x000000c1, + 0x000300f7,0x00000533,0x00000000,0x000400fa,0x00000529,0x0000052b,0x0000052a,0x000200f8, + 0x0000052a,0x0003003e,0x0000050f,0x000000c1,0x000200f9,0x00000533,0x000200f8,0x0000052b, + 0x0004003d,0x00000121,0x0000052c,0x00000123,0x0004003d,0x00000125,0x0000052d,0x00000127, + 0x00050056,0x00000129,0x0000052e,0x0000052c,0x0000052d,0x0004003d,0x00000008,0x0000052f, + 0x0000050d,0x00050050,0x00000034,0x00000530,0x0000052f,0x000000c1,0x00070058,0x00000013, + 0x00000531,0x0000052e,0x00000530,0x00000002,0x000000c1,0x00050051,0x00000008,0x00000532, + 0x00000531,0x00000000,0x0003003e,0x0000050f,0x00000532,0x000200f9,0x00000533,0x000200f8, + 0x00000533,0x0004003d,0x00000008,0x00000534,0x0000050f,0x0003003e,0x0000050e,0x00000534, + 0x0004003d,0x00000008,0x00000535,0x0000050c,0x0006000c,0x00000008,0x00000536,0x00000001, + 0x00000004,0x00000535,0x000500b8,0x00000041,0x00000537,0x00000536,0x00000133,0x000300f7, + 0x00000586,0x00000000,0x000400fa,0x00000537,0x00000538,0x00000586,0x000200f8,0x00000538, + 0x00050041,0x00000019,0x00000539,0x000004f3,0x00000096,0x0004003d,0x00000008,0x0000053a, + 0x00000539,0x0006000c,0x00000008,0x0000053b,0x00000001,0x00000004,0x0000053a,0x00050083, + 0x00000008,0x0000053c,0x0000053b,0x0000013b,0x0003003e,0x00000510,0x0000053c,0x00050041, + 0x00000019,0x0000053d,0x000004f3,0x00000099,0x0004003d,0x00000008,0x0000053e,0x0000053d, + 0x00050083,0x00000008,0x00000540,0x00000141,0x0000053e,0x0003003e,0x00000511,0x00000540, + 0x0004003d,0x00000008,0x00000541,0x00000511,0x0004003d,0x00000008,0x00000542,0x0000050d, + 0x00050083,0x00000008,0x00000543,0x00000541,0x00000542,0x00050085,0x00000008,0x00000544, + 0x00000543,0x00000147,0x0003003e,0x00000512,0x00000544,0x0004003d,0x00000008,0x00000545, + 0x0000050d,0x0004003d,0x00000008,0x00000546,0x00000512,0x0003003e,0x00000514,0x0000014c, + 0x0003003e,0x00000515,0x0000014d,0x0003003e,0x00000516,0x0000014e,0x0003003e,0x00000517, + 0x0000014f,0x0004003d,0x00000008,0x00000590,0x00000514,0x00050041,0x00000019,0x00000591, + 0x0000058d,0x00000096,0x0003003e,0x00000591,0x00000590,0x0004003d,0x00000008,0x00000592, + 0x00000515,0x00050041,0x00000019,0x00000593,0x0000058d,0x00000099,0x0003003e,0x00000593, + 0x00000592,0x0004003d,0x00000008,0x00000594,0x00000516,0x00050041,0x00000019,0x00000595, + 0x0000058d,0x0000009c,0x0003003e,0x00000595,0x00000594,0x0004003d,0x00000008,0x00000596, + 0x00000517,0x00050041,0x00000019,0x00000597,0x0000058d,0x0000009f,0x0003003e,0x00000597, + 0x00000596,0x0004003d,0x00000013,0x00000598,0x0000058d,0x0003003e,0x0000058e,0x00000598, + 0x0004003d,0x00000013,0x00000547,0x0000058e,0x0005008e,0x00000013,0x00000548,0x00000547, + 0x00000546,0x00070050,0x00000013,0x00000549,0x00000545,0x00000545,0x00000545,0x00000545, + 0x00050081,0x00000013,0x0000054a,0x00000549,0x00000548,0x0003003e,0x00000513,0x0000054a, + 0x0004003d,0x00000013,0x0000054b,0x00000513,0x0004003d,0x00000008,0x0000054c,0x0000050c, + 0x0004007f,0x00000008,0x0000054d,0x0000054c,0x0005008e,0x00000013,0x0000054e,0x0000054b, + 0x0000054d,0x0004003d,0x00000008,0x0000054f,0x00000511,0x0004003d,0x00000008,0x00000550, + 0x0000050c,0x00050085,0x00000008,0x00000551,0x0000054f,0x00000550,0x0004003d,0x00000008, + 0x00000552,0x00000510,0x00050081,0x00000008,0x00000553,0x00000551,0x00000552,0x00070050, + 0x00000013,0x00000554,0x00000553,0x00000553,0x00000553,0x00000553,0x00050081,0x00000013, + 0x00000555,0x0000054e,0x00000554,0x0003003e,0x00000518,0x00000555,0x0004003d,0x00000121, + 0x00000556,0x00000123,0x0004003d,0x00000125,0x00000557,0x00000127,0x00050056,0x00000129, + 0x00000558,0x00000556,0x00000557,0x00050041,0x00000019,0x00000559,0x00000518,0x00000096, + 0x0004003d,0x00000008,0x0000055a,0x00000559,0x00050050,0x00000034,0x0000055b,0x0000055a, + 0x000000c1,0x00070058,0x00000013,0x0000055c,0x00000558,0x0000055b,0x00000002,0x000000c1, + 0x0004003d,0x00000121,0x0000055d,0x00000123,0x0004003d,0x00000125,0x0000055e,0x00000127, + 0x00050056,0x00000129,0x0000055f,0x0000055d,0x0000055e,0x00050041,0x00000019,0x00000560, + 0x00000518,0x00000099,0x0004003d,0x00000008,0x00000561,0x00000560,0x00050050,0x00000034, + 0x00000562,0x00000561,0x000000c1,0x00070058,0x00000013,0x00000563,0x0000055f,0x00000562, + 0x00000002,0x000000c1,0x0004003d,0x00000121,0x00000564,0x00000123,0x0004003d,0x00000125, + 0x00000565,0x00000127,0x00050056,0x00000129,0x00000566,0x00000564,0x00000565,0x00050041, + 0x00000019,0x00000567,0x00000518,0x0000009c,0x0004003d,0x00000008,0x00000568,0x00000567, + 0x00050050,0x00000034,0x00000569,0x00000568,0x000000c1,0x00070058,0x00000013,0x0000056a, + 0x00000566,0x00000569,0x00000002,0x000000c1,0x0004003d,0x00000121,0x0000056b,0x00000123, + 0x0004003d,0x00000125,0x0000056c,0x00000127,0x00050056,0x00000129,0x0000056d,0x0000056b, + 0x0000056c,0x00050041,0x00000019,0x0000056e,0x00000518,0x0000009f,0x0004003d,0x00000008, + 0x0000056f,0x0000056e,0x00050050,0x00000034,0x00000570,0x0000056f,0x000000c1,0x00070058, + 0x00000013,0x00000571,0x0000056d,0x00000570,0x00000002,0x000000c1,0x00050051,0x00000008, + 0x00000572,0x0000055c,0x00000000,0x0003003e,0x0000051a,0x00000572,0x00050051,0x00000008, + 0x00000573,0x00000563,0x00000000,0x0003003e,0x0000051b,0x00000573,0x00050051,0x00000008, + 0x00000574,0x0000056a,0x00000000,0x0003003e,0x0000051c,0x00000574,0x00050051,0x00000008, + 0x00000575,0x00000571,0x00000000,0x0003003e,0x0000051d,0x00000575,0x0004003d,0x00000008, + 0x0000059c,0x0000051a,0x00050041,0x00000019,0x0000059d,0x00000599,0x00000096,0x0003003e, + 0x0000059d,0x0000059c,0x0004003d,0x00000008,0x0000059e,0x0000051b,0x00050041,0x00000019, + 0x0000059f,0x00000599,0x00000099,0x0003003e,0x0000059f,0x0000059e,0x0004003d,0x00000008, + 0x000005a0,0x0000051c,0x00050041,0x00000019,0x000005a1,0x00000599,0x0000009c,0x0003003e, + 0x000005a1,0x000005a0,0x0004003d,0x00000008,0x000005a2,0x0000051d,0x00050041,0x00000019, + 0x000005a3,0x00000599,0x0000009f,0x0003003e,0x000005a3,0x000005a2,0x0004003d,0x00000013, + 0x000005a4,0x00000599,0x0003003e,0x0000059a,0x000005a4,0x0004003d,0x00000013,0x00000576, + 0x0000059a,0x0003003e,0x00000519,0x00000576,0x0004003d,0x00000013,0x00000577,0x00000513, + 0x0005008e,0x00000013,0x00000578,0x00000577,0x0000018c,0x00050081,0x00000013,0x00000579, + 0x00000578,0x00000433,0x0003003e,0x0000051e,0x00000579,0x0004003d,0x00000013,0x0000057a, + 0x0000051e,0x0004007f,0x00000013,0x0000057b,0x0000057a,0x0004003d,0x00000013,0x0000057c, + 0x0000051e,0x00050085,0x00000013,0x0000057d,0x0000057b,0x0000057c,0x0006000c,0x00000013, + 0x0000057e,0x00000001,0x0000001d,0x0000057d,0x0003003e,0x0000051f,0x0000057e,0x0004003d, + 0x00000013,0x0000057f,0x00000519,0x0004003d,0x00000013,0x00000580,0x0000051f,0x00050094, + 0x00000008,0x00000581,0x0000057f,0x00000580,0x0004003d,0x00000008,0x00000582,0x00000512, + 0x00050085,0x00000008,0x00000583,0x00000581,0x00000582,0x0004003d,0x00000008,0x00000584, + 0x0000050e,0x00050081,0x00000008,0x00000585,0x00000584,0x00000583,0x0003003e,0x0000050e, + 0x00000585,0x000200f9,0x00000586,0x000200f8,0x00000586,0x0004003d,0x00000008,0x00000587, + 0x0000050e,0x00050041,0x00000019,0x00000588,0x000004f3,0x00000096,0x0004003d,0x00000008, + 0x00000589,0x00000588,0x0006000c,0x00000008,0x0000058a,0x00000001,0x00000006,0x00000589, + 0x00050085,0x00000008,0x0000058b,0x00000587,0x0000058a,0x0003003e,0x00000520,0x0000058b, + 0x0004003d,0x00000008,0x0000058c,0x00000520,0x0003003e,0x00000521,0x0000058c,0x0004003d, + 0x00000008,0x00000503,0x00000521,0x0003003e,0x000004f1,0x00000503,0x000200f9,0x00000505, + 0x000200f8,0x00000504,0x000200f9,0x00000505,0x000200f8,0x00000505,0x0004003d,0x00000008, + 0x00000506,0x000004f1,0x0003003e,0x000004f5,0x00000506,0x0004003d,0x00000008,0x000004e4, + 0x000004f5,0x0003003e,0x000004d9,0x000004e4,0x000200f9,0x000004e9,0x000200f8,0x000004e5, + 0x0004003d,0x00000013,0x000004e6,0x00000393,0x0003003e,0x000004db,0x000004e6,0x000300f7, + 0x000005bd,0x00000000,0x000300fb,0x00000096,0x000005ac,0x000200f8,0x000005ac,0x000300f7, + 0x000005b0,0x00000000,0x000400fa,0x0000029e,0x000005ad,0x000005b0,0x000200f8,0x000005ad, + 0x0004003d,0x00000013,0x000005ae,0x000004db,0x0003003e,0x000005a7,0x000005ae,0x00050041, + 0x00000019,0x000005c1,0x000005a7,0x00000096,0x0004003d,0x00000008,0x000005c2,0x000005c1, + 0x000500b8,0x00000041,0x000005c3,0x000005c2,0x0000010b,0x0003003e,0x000005bf,0x000005c3, + 0x0004003d,0x00000041,0x000005af,0x000005bf,0x000200f9,0x000005b0,0x000200f8,0x000005b0, + 0x000700f5,0x00000041,0x000005b1,0x0000029e,0x000005ac,0x000005af,0x000005ad,0x000300f7, + 0x000005bc,0x00000000,0x000400fa,0x000005b1,0x000005b9,0x000005b2,0x000200f8,0x000005b2, + 0x00050041,0x00000019,0x000005b3,0x000004db,0x00000096,0x0004003d,0x00000008,0x000005b4, + 0x000005b3,0x00050041,0x00000019,0x000005b5,0x000004db,0x00000099,0x0004003d,0x00000008, + 0x000005b6,0x000005b5,0x0007000c,0x00000008,0x000005b7,0x00000001,0x00000025,0x000005b4, + 0x000005b6,0x0003003e,0x000005a9,0x000005b7,0x0004003d,0x00000008,0x000005b8,0x000005a9, + 0x0003003e,0x000005a6,0x000005b8,0x000200f9,0x000005bd,0x000200f8,0x000005b9,0x0004003d, + 0x00000013,0x000005ba,0x000004db,0x0003003e,0x000005a8,0x000005ba,0x0003003e,0x000005c4, + 0x000000c6,0x00050041,0x00000019,0x000005ca,0x000005a8,0x00000096,0x0004003d,0x00000008, + 0x000005cb,0x000005ca,0x00050081,0x00000008,0x000005cc,0x000001a9,0x000005cb,0x0003003e, + 0x000005c5,0x000005cc,0x0004003d,0x00000121,0x000005cd,0x00000123,0x0004003d,0x00000125, + 0x000005ce,0x00000127,0x00050056,0x00000129,0x000005cf,0x000005cd,0x000005ce,0x0004003d, + 0x00000008,0x000005d0,0x000005c5,0x00050050,0x00000034,0x000005d1,0x000005d0,0x000000c1, + 0x00070058,0x00000013,0x000005d2,0x000005cf,0x000005d1,0x00000002,0x000000c1,0x00050051, + 0x00000008,0x000005d3,0x000005d2,0x00000000,0x0004003d,0x00000008,0x000005d4,0x000005c4, + 0x00050083,0x00000008,0x000005d5,0x000005d4,0x000005d3,0x0003003e,0x000005c4,0x000005d5, + 0x00050041,0x00000019,0x000005d6,0x000005a8,0x00000099,0x0004003d,0x00000008,0x000005d7, + 0x000005d6,0x00050083,0x00000008,0x000005d8,0x000000c6,0x000005d7,0x0003003e,0x000005c6, + 0x000005d8,0x0004003d,0x00000121,0x000005d9,0x00000123,0x0004003d,0x00000125,0x000005da, + 0x00000127,0x00050056,0x00000129,0x000005db,0x000005d9,0x000005da,0x0004003d,0x00000008, + 0x000005dc,0x000005c6,0x00050050,0x00000034,0x000005dd,0x000005dc,0x000000c1,0x00070058, + 0x00000013,0x000005de,0x000005db,0x000005dd,0x00000002,0x000000c1,0x00050051,0x00000008, + 0x000005df,0x000005de,0x00000000,0x0004003d,0x00000008,0x000005e0,0x000005c4,0x00050083, + 0x00000008,0x000005e1,0x000005e0,0x000005df,0x0003003e,0x000005c4,0x000005e1,0x0004003d, + 0x00000008,0x000005e2,0x000005c4,0x0003003e,0x000005c7,0x000005e2,0x0004003d,0x00000008, + 0x000005e3,0x000005c7,0x0003003e,0x000005c8,0x000005e3,0x0004003d,0x00000008,0x000005bb, + 0x000005c8,0x0003003e,0x000005a6,0x000005bb,0x000200f9,0x000005bd,0x000200f8,0x000005bc, + 0x000200f9,0x000005bd,0x000200f8,0x000005bd,0x0004003d,0x00000008,0x000005be,0x000005a6, + 0x0003003e,0x000005aa,0x000005be,0x0004003d,0x00000008,0x000004e7,0x000005aa,0x0003003e, + 0x000004d9,0x000004e7,0x000200f9,0x000004e9,0x000200f8,0x000004e8,0x000200f9,0x000004e9, + 0x000200f8,0x000004e9,0x0004003d,0x00000008,0x000004ea,0x000004d9,0x0003003e,0x000004dd, + 0x000004ea,0x0004003d,0x00000008,0x00000395,0x000004dd,0x0003003e,0x00000391,0x00000395, + 0x0004003d,0x00000034,0x00000399,0x00000398,0x0003003e,0x00000396,0x00000399,0x0004003d, + 0x00000034,0x0000039a,0x00000396,0x0006000c,0x00000034,0x0000039b,0x00000001,0x00000008, + 0x0000039a,0x0003003e,0x00000396,0x0000039b,0x00050041,0x0000039f,0x000003a0,0x0000039e, + 0x00000099,0x0004003d,0x00000006,0x000003a1,0x000003a0,0x0003003e,0x0000039c,0x000003a1, + 0x00050041,0x0000039f,0x000003a3,0x0000039e,0x00000096,0x0004003d,0x00000006,0x000003a4, + 0x000003a3,0x0004003d,0x00000034,0x000003a5,0x00000396,0x0004006d,0x00000058,0x000003a6, + 0x000003a5,0x0003003e,0x000003a7,0x000003a6,0x0004003d,0x00000006,0x000003a9,0x0000039c, + 0x0003003e,0x000003a8,0x000003a9,0x00050041,0x00000007,0x000005e7,0x000003a7,0x00000099, + 0x0004003d,0x00000006,0x000005e8,0x000005e7,0x000500c2,0x00000006,0x000005e9,0x000005e8, + 0x000001d7,0x0004003d,0x00000006,0x000005ea,0x000003a8,0x000500c4,0x00000006,0x000005eb, + 0x000005ea,0x000001d7,0x00050084,0x00000006,0x000005ec,0x000005e9,0x000005eb,0x00050041, + 0x00000007,0x000005ed,0x000003a7,0x00000096,0x0004003d,0x00000006,0x000005ee,0x000005ed, + 0x000500c2,0x00000006,0x000005ef,0x000005ee,0x000001d7,0x00050084,0x00000006,0x000005f0, + 0x000005ef,0x000001df,0x00050080,0x00000006,0x000005f1,0x000005ec,0x000005f0,0x0003003e, + 0x000005e4,0x000005f1,0x0004003d,0x00000006,0x000005f3,0x000005ed,0x000500c7,0x00000006, + 0x000005f4,0x000005f3,0x000001e4,0x000500c2,0x00000006,0x000005f5,0x000005f4,0x0000009c, + 0x00050084,0x00000006,0x000005f6,0x000005f5,0x000001e7,0x0004003d,0x00000006,0x000005f8, + 0x000005e7,0x000500c7,0x00000006,0x000005f9,0x000005f8,0x000001e4,0x000500c2,0x00000006, + 0x000005fa,0x000005f9,0x0000009c,0x00050084,0x00000006,0x000005fb,0x000005fa,0x000001ed, + 0x00050080,0x00000006,0x000005fc,0x000005f6,0x000005fb,0x0004003d,0x00000006,0x000005fd, + 0x000005e4,0x00050080,0x00000006,0x000005fe,0x000005fd,0x000005fc,0x0003003e,0x000005e4, + 0x000005fe,0x0004003d,0x00000006,0x00000600,0x000005e7,0x000500c7,0x00000006,0x00000601, + 0x00000600,0x0000009f,0x00050084,0x00000006,0x00000602,0x00000601,0x000001f5,0x0004003d, + 0x00000006,0x00000604,0x000005ed,0x000500c7,0x00000006,0x00000605,0x00000604,0x0000009f, + 0x00050080,0x00000006,0x00000606,0x00000602,0x00000605,0x0004003d,0x00000006,0x00000607, + 0x000005e4,0x00050080,0x00000006,0x00000608,0x00000607,0x00000606,0x0003003e,0x000005e4, + 0x00000608,0x0004003d,0x00000006,0x00000609,0x000005e4,0x0003003e,0x000005e5,0x00000609, + 0x0004003d,0x00000006,0x000003aa,0x000005e5,0x00050080,0x00000006,0x000003ab,0x000003a4, + 0x000003aa,0x0003003e,0x000003a2,0x000003ab,0x0003003e,0x000003ac,0x000000c6,0x000300f7, + 0x000003af,0x00000000,0x000400fa,0x000003ad,0x000003ae,0x000003af,0x000200f8,0x000003ae, + 0x0004003d,0x00000013,0x000003b3,0x000003b1,0x0003003e,0x000003b2,0x000003b3,0x0004003d, + 0x00000013,0x0000060d,0x000003b2,0x0003003e,0x0000060a,0x0000060d,0x0004003d,0x00000013, + 0x0000060e,0x0000060a,0x0003003e,0x0000060b,0x0000060e,0x0004003d,0x00000013,0x000003b4, + 0x0000060b,0x0003003e,0x000003b5,0x000003b4,0x0004003d,0x00000013,0x00000613,0x000003b5, + 0x0007004f,0x00000034,0x00000614,0x00000613,0x00000613,0x00000000,0x00000001,0x0004003d, + 0x00000013,0x00000615,0x000003b5,0x0007004f,0x00000034,0x00000616,0x00000615,0x00000615, + 0x00000002,0x00000003,0x0007000c,0x00000034,0x00000617,0x00000001,0x00000025,0x00000614, + 0x00000616,0x0003003e,0x0000060f,0x00000617,0x00050041,0x00000019,0x00000618,0x0000060f, + 0x00000096,0x0004003d,0x00000008,0x00000619,0x00000618,0x00050041,0x00000019,0x0000061a, + 0x0000060f,0x00000099,0x0004003d,0x00000008,0x0000061b,0x0000061a,0x0007000c,0x00000008, + 0x0000061c,0x00000001,0x00000025,0x00000619,0x0000061b,0x0003003e,0x00000610,0x0000061c, + 0x0004003d,0x00000008,0x0000061d,0x00000610,0x0003003e,0x00000611,0x0000061d,0x0004003d, + 0x00000008,0x000003b6,0x00000611,0x0003003e,0x000003b0,0x000003b6,0x0004003d,0x00000008, + 0x000003b7,0x000003b0,0x0004003d,0x00000008,0x000003b8,0x000003ac,0x0007000c,0x00000008, + 0x000003b9,0x00000001,0x00000025,0x000003b7,0x000003b8,0x0003003e,0x000003ac,0x000003b9, + 0x000200f9,0x000003af,0x000200f8,0x000003af,0x000300f7,0x000003bc,0x00000000,0x000400fa, + 0x000003ba,0x000003bb,0x000003bc,0x000200f8,0x000003bb,0x00050041,0x000003be,0x000003bf, + 0x000003bd,0x00000096,0x0004003d,0x00000008,0x000003c0,0x000003bf,0x000500b7,0x00000041, + 0x000003c1,0x000003c0,0x000000c1,0x000200f9,0x000003bc,0x000200f8,0x000003bc,0x000700f5, + 0x00000041,0x000003c2,0x000003ba,0x000003af,0x000003c1,0x000003bb,0x000300f7,0x000003c4, + 0x00000000,0x000400fa,0x000003c2,0x000003c3,0x000003c4,0x000200f8,0x000003c3,0x0004003d, + 0x000003c6,0x000003c9,0x000003c8,0x00050062,0x00000013,0x000003cc,0x000003c9,0x000003cb, + 0x00050051,0x00000008,0x000003cd,0x000003cc,0x00000000,0x0003003e,0x000003c5,0x000003cd, + 0x0004003d,0x00000008,0x000003ce,0x000003c5,0x0004003d,0x00000008,0x000003cf,0x000003ac, + 0x0007000c,0x00000008,0x000003d0,0x00000001,0x00000025,0x000003ce,0x000003cf,0x0003003e, + 0x000003ac,0x000003d0,0x000200f9,0x000003c4,0x000200f8,0x000003c4,0x0004003d,0x00000008, + 0x000003d1,0x000003ac,0x0007000c,0x00000008,0x000003d2,0x00000001,0x00000028,0x000003d1, + 0x000000c1,0x0003003e,0x000003ac,0x000003d2,0x0004003d,0x00000008,0x000003d3,0x00000391, + 0x0004003d,0x00000008,0x000003d4,0x000003ac,0x0008000c,0x00000008,0x000003d5,0x00000001, + 0x0000002b,0x000003d3,0x000000c1,0x000003d4,0x0003003e,0x00000391,0x000003d5,0x0003003e, + 0x000003d6,0x00000394,0x00050041,0x00000019,0x00000620,0x000003d6,0x00000099,0x0004003d, + 0x00000008,0x00000621,0x00000620,0x000500be,0x00000041,0x00000622,0x00000621,0x000000c1, + 0x0003003e,0x0000061e,0x00000622,0x0004003d,0x00000041,0x000003d8,0x0000061e,0x000300f7, + 0x000003da,0x00000000,0x000400fa,0x000003d8,0x000003d9,0x000003eb,0x000200f8,0x000003eb, + 0x00050041,0x00000019,0x000003ed,0x0000038a,0x0000009f,0x0004003d,0x00000008,0x000003ee, + 0x000003ed,0x0003003e,0x000003ec,0x000003ee,0x0004003d,0x00000008,0x000003f0,0x00000391, + 0x0003003e,0x000003ef,0x000003f0,0x0004003d,0x00000006,0x000003f2,0x000003a2,0x0003003e, + 0x000003f1,0x000003f2,0x000300f7,0x0000069d,0x00000000,0x000300fb,0x00000096,0x00000638, + 0x000200f8,0x00000638,0x0003003e,0x00000624,0x000000c1,0x0004003d,0x00000008,0x00000639, + 0x000003ef,0x0006000c,0x00000008,0x0000063a,0x00000001,0x00000004,0x00000639,0x0003003e, + 0x00000626,0x0000063a,0x0004003d,0x00000008,0x000006a1,0x00000626,0x00050085,0x00000008, + 0x000006a2,0x000006a1,0x0000020d,0x00050081,0x00000008,0x000006a3,0x000006a2,0x0000020f, + 0x0004006d,0x00000006,0x000006a4,0x000006a3,0x0003003e,0x0000069e,0x000006a4,0x0004003d, + 0x00000006,0x000006a5,0x0000069e,0x0003003e,0x0000069f,0x000006a5,0x0004003d,0x00000006, + 0x0000063b,0x0000069f,0x0003003e,0x00000625,0x0000063b,0x0004003d,0x00000006,0x0000063c, + 0x000003f1,0x00060041,0x000002e9,0x0000063d,0x000002e6,0x000002e7,0x0000063c,0x0004003d, + 0x00000006,0x0000063e,0x0000063d,0x0003003e,0x000003f3,0x0000063e,0x0004003d,0x00000008, + 0x0000063f,0x000003ec,0x0004003d,0x00000008,0x00000640,0x000003ef,0x0007000c,0x00000008, + 0x00000641,0x00000001,0x00000025,0x0000063f,0x00000640,0x000500be,0x00000041,0x00000642, + 0x00000641,0x000000c6,0x000300f7,0x00000651,0x00000000,0x000400fa,0x00000642,0x00000643, + 0x00000651,0x000200f8,0x00000643,0x0004003d,0x00000006,0x00000644,0x000003f3,0x00050041, + 0x000002e9,0x00000645,0x000002ee,0x00000096,0x0004003d,0x00000006,0x00000646,0x00000645, + 0x000500b0,0x00000041,0x00000647,0x00000644,0x00000646,0x000400a8,0x00000041,0x00000648, + 0x00000647,0x000300f7,0x0000064f,0x00000000,0x000400fa,0x00000648,0x00000649,0x0000064f, + 0x000200f8,0x00000649,0x0004003d,0x00000006,0x0000064a,0x000003f3,0x000500c5,0x00000006, + 0x0000064d,0x00000646,0x00000203,0x000500ae,0x00000041,0x0000064e,0x0000064a,0x0000064d, + 0x000200f9,0x0000064f,0x000200f8,0x0000064f,0x000700f5,0x00000041,0x00000650,0x00000647, + 0x00000643,0x0000064e,0x00000649,0x000200f9,0x00000651,0x000200f8,0x00000651,0x000700f5, + 0x00000041,0x00000652,0x00000642,0x00000638,0x00000650,0x0000064f,0x000300f7,0x00000654, + 0x00000000,0x000400fa,0x00000652,0x00000653,0x00000654,0x000200f8,0x00000653,0x000200f9, + 0x0000069d,0x000200f8,0x00000654,0x0004003d,0x00000006,0x00000655,0x000003f3,0x00050041, + 0x000002e9,0x00000656,0x000002ee,0x00000096,0x0004003d,0x00000006,0x00000657,0x00000656, + 0x000500b0,0x00000041,0x00000658,0x00000655,0x00000657,0x000300f7,0x0000067d,0x00000000, + 0x000400fa,0x00000658,0x00000659,0x0000067d,0x000200f8,0x00000659,0x0004003d,0x00000006, + 0x0000065c,0x00000625,0x00050080,0x00000006,0x0000065d,0x00000203,0x0000065c,0x000500c5, + 0x00000006,0x0000065e,0x00000657,0x0000065d,0x0003003e,0x00000627,0x0000065e,0x0004003d, + 0x00000006,0x0000065f,0x000003f1,0x00060041,0x000002e9,0x00000660,0x000002e6,0x000002e7, + 0x0000065f,0x0004003d,0x00000006,0x00000661,0x00000627,0x000700ef,0x00000006,0x00000662, + 0x00000660,0x00000099,0x00000096,0x00000661,0x0003003e,0x00000628,0x00000662,0x0004003d, + 0x00000006,0x00000663,0x00000628,0x000500b2,0x00000041,0x00000666,0x00000663,0x00000657, + 0x000300f7,0x0000067c,0x00000000,0x000400fa,0x00000666,0x0000067a,0x00000667,0x000200f8, + 0x00000667,0x0004003d,0x00000006,0x00000668,0x00000628,0x0004003d,0x00000006,0x00000669, + 0x00000627,0x000500b0,0x00000041,0x0000066a,0x00000668,0x00000669,0x000300f7,0x00000679, + 0x00000000,0x000400fa,0x0000066a,0x0000066b,0x00000679,0x000200f8,0x0000066b,0x0004003d, + 0x00000006,0x0000066c,0x00000628,0x000500c7,0x00000006,0x0000066d,0x0000066c,0x00000201, + 0x00050082,0x00000006,0x0000066e,0x0000066d,0x00000203,0x0003003e,0x00000629,0x0000066e, + 0x0004003d,0x00000006,0x0000066f,0x00000629,0x0003003e,0x0000062b,0x0000066f,0x0004003d, + 0x00000006,0x000006a9,0x0000062b,0x00040070,0x00000008,0x000006aa,0x000006a9,0x0003003e, + 0x000006a6,0x000006aa,0x0004003d,0x00000008,0x000006ab,0x000006a6,0x0003003e,0x000006a7, + 0x000006ab,0x0004003d,0x00000008,0x00000670,0x000006a7,0x00050085,0x00000008,0x00000671, + 0x00000670,0x00000208,0x0003003e,0x0000062a,0x00000671,0x0004003d,0x00000008,0x00000672, + 0x000003ef,0x0003003e,0x0000062c,0x00000672,0x0004003d,0x00000008,0x00000673,0x0000062a, + 0x0003003e,0x0000062d,0x00000673,0x0004003d,0x00000008,0x00000674,0x0000062c,0x0003003e, + 0x0000062e,0x00000674,0x0004003d,0x00000008,0x00000675,0x000003ec,0x0003003e,0x0000062f, + 0x00000675,0x0004003d,0x00000008,0x000006ae,0x0000062e,0x0004003d,0x00000008,0x000006af, + 0x0000062d,0x00050083,0x00000008,0x000006b0,0x000006ae,0x000006af,0x0004003d,0x00000008, + 0x000006b1,0x0000062d,0x0004003d,0x00000008,0x000006b2,0x0000062f,0x00050085,0x00000008, + 0x000006b3,0x000006b1,0x000006b2,0x00050083,0x00000008,0x000006b4,0x000000c6,0x000006b3, + 0x0007000c,0x00000008,0x000006b5,0x00000001,0x00000028,0x000006b4,0x000001cf,0x00050088, + 0x00000008,0x000006b6,0x000006b0,0x000006b5,0x0003003e,0x000006ac,0x000006b6,0x0004003d, + 0x00000008,0x00000676,0x000006ac,0x0003003e,0x00000624,0x00000676,0x0004003d,0x00000006, + 0x00000677,0x00000629,0x0003003e,0x00000625,0x00000677,0x0004003d,0x00000008,0x00000678, + 0x0000062a,0x0003003e,0x000003ef,0x00000678,0x000200f9,0x00000679,0x000200f8,0x00000679, + 0x000200f9,0x0000067c,0x000200f8,0x0000067a,0x0004003d,0x00000008,0x0000067b,0x000003ef, + 0x0003003e,0x00000624,0x0000067b,0x0003003e,0x000003ef,0x000000c1,0x000200f9,0x0000067c, + 0x000200f8,0x0000067c,0x000200f9,0x0000067d,0x000200f8,0x0000067d,0x0004003d,0x00000008, + 0x0000067e,0x000003ef,0x000500ba,0x00000041,0x0000067f,0x0000067e,0x000000c1,0x000300f7, + 0x00000699,0x00000000,0x000400fa,0x0000067f,0x00000680,0x00000699,0x000200f8,0x00000680, + 0x0004003d,0x00000006,0x00000681,0x000003f1,0x00060041,0x000002e9,0x00000682,0x000002e6, + 0x000002e7,0x00000681,0x0004003d,0x00000006,0x00000683,0x00000625,0x000700ea,0x00000006, + 0x00000684,0x00000682,0x00000099,0x00000096,0x00000683,0x0003003e,0x00000630,0x00000684, + 0x0004003d,0x00000006,0x00000685,0x00000630,0x0003003e,0x00000632,0x00000685,0x0004003d, + 0x00000006,0x000006ba,0x00000632,0x000500c7,0x00000006,0x000006bb,0x000006ba,0x00000201, + 0x00050082,0x00000006,0x000006bc,0x000006bb,0x00000203,0x0004007c,0x0000000d,0x000006bd, + 0x000006bc,0x0003003e,0x000006b7,0x000006bd,0x0004003d,0x0000000d,0x000006c3,0x000006b7, + 0x0004006f,0x00000008,0x000006c4,0x000006c3,0x0003003e,0x000006c0,0x000006c4,0x0004003d, + 0x00000008,0x000006c5,0x000006c0,0x0003003e,0x000006c1,0x000006c5,0x0004003d,0x00000008, + 0x000006be,0x000006c1,0x00050085,0x00000008,0x000006bf,0x000006be,0x00000208,0x0003003e, + 0x000006b8,0x000006bf,0x0004003d,0x00000008,0x00000686,0x000006b8,0x0003003e,0x00000631, + 0x00000686,0x0004003d,0x00000008,0x00000687,0x00000631,0x0004003d,0x00000008,0x00000688, + 0x000003ef,0x00050081,0x00000008,0x00000689,0x00000687,0x00000688,0x0003003e,0x00000633, + 0x00000689,0x0004003d,0x00000008,0x0000068a,0x00000631,0x0008000c,0x00000008,0x0000068b, + 0x00000001,0x0000002b,0x0000068a,0x000000c1,0x000000c6,0x0003003e,0x00000631,0x0000068b, + 0x0004003d,0x00000008,0x0000068c,0x00000633,0x0008000c,0x00000008,0x0000068d,0x00000001, + 0x0000002b,0x0000068c,0x000000c1,0x000000c6,0x0003003e,0x00000633,0x0000068d,0x0004003d, + 0x00000008,0x0000068e,0x00000624,0x0004003d,0x00000008,0x0000068f,0x000003ec,0x00050085, + 0x00000008,0x00000690,0x0000068e,0x0000068f,0x00050083,0x00000008,0x00000691,0x000000c6, + 0x00000690,0x0004003d,0x00000008,0x00000692,0x00000631,0x0003003e,0x00000634,0x00000692, + 0x0004003d,0x00000008,0x00000693,0x00000633,0x0003003e,0x00000635,0x00000693,0x0004003d, + 0x00000008,0x00000694,0x000003ec,0x0003003e,0x00000636,0x00000694,0x0004003d,0x00000008, + 0x000006c8,0x00000635,0x0004003d,0x00000008,0x000006c9,0x00000634,0x00050083,0x00000008, + 0x000006ca,0x000006c8,0x000006c9,0x0004003d,0x00000008,0x000006cb,0x00000634,0x0004003d, + 0x00000008,0x000006cc,0x00000636,0x00050085,0x00000008,0x000006cd,0x000006cb,0x000006cc, + 0x00050083,0x00000008,0x000006ce,0x000000c6,0x000006cd,0x0007000c,0x00000008,0x000006cf, + 0x00000001,0x00000028,0x000006ce,0x000001cf,0x00050088,0x00000008,0x000006d0,0x000006ca, + 0x000006cf,0x0003003e,0x000006c6,0x000006d0,0x0004003d,0x00000008,0x00000695,0x000006c6, + 0x00050085,0x00000008,0x00000696,0x00000691,0x00000695,0x0004003d,0x00000008,0x00000697, + 0x00000624,0x00050081,0x00000008,0x00000698,0x00000697,0x00000696,0x0003003e,0x00000624, + 0x00000698,0x000200f9,0x00000699,0x000200f8,0x00000699,0x0004003d,0x00000008,0x0000069a, + 0x00000624,0x0004003d,0x00000008,0x0000069b,0x000003ec,0x00050085,0x00000008,0x0000069c, + 0x0000069b,0x0000069a,0x0003003e,0x000003ec,0x0000069c,0x000200f9,0x0000069d,0x000200f8, + 0x0000069d,0x0004003d,0x00000008,0x000003f6,0x000003ec,0x0003003e,0x000003ed,0x000003f6, + 0x000200f9,0x000003da,0x000200f8,0x000003d9,0x00050041,0x00000019,0x000003de,0x0000038a, + 0x0000009f,0x0004003d,0x00000008,0x000003df,0x000003de,0x0003003e,0x000003dd,0x000003df, + 0x0004003d,0x00000008,0x000003e1,0x00000391,0x0003003e,0x000003e0,0x000003e1,0x0004003d, + 0x00000006,0x000003e3,0x000003a2,0x0003003e,0x000003e2,0x000003e3,0x000300f7,0x00000703, + 0x00000000,0x000300fb,0x00000096,0x000006dc,0x000200f8,0x000006dc,0x0004003d,0x00000008, + 0x000006dd,0x000003dd,0x0004003d,0x00000008,0x000006de,0x000003e0,0x0007000c,0x00000008, + 0x000006df,0x00000001,0x00000025,0x000006dd,0x000006de,0x000500be,0x00000041,0x000006e0, + 0x000006df,0x000000c6,0x000300f7,0x000006e2,0x00000000,0x000400fa,0x000006e0,0x000006e1, + 0x000006e2,0x000200f8,0x000006e1,0x000200f9,0x00000703,0x000200f8,0x000006e2,0x0004003d, + 0x00000008,0x000006e3,0x000003e0,0x0006000c,0x00000008,0x000006e4,0x00000001,0x00000004, + 0x000006e3,0x0003003e,0x000006d3,0x000006e4,0x0004003d,0x00000008,0x00000707,0x000006d3, + 0x00050085,0x00000008,0x00000708,0x00000707,0x0000020d,0x00050081,0x00000008,0x00000709, + 0x00000708,0x0000020f,0x0004006d,0x00000006,0x0000070a,0x00000709,0x0003003e,0x00000704, + 0x0000070a,0x0004003d,0x00000006,0x0000070b,0x00000704,0x0003003e,0x00000705,0x0000070b, + 0x0004003d,0x00000006,0x000006e5,0x00000705,0x0003003e,0x000006d2,0x000006e5,0x0004003d, + 0x00000006,0x000006e6,0x000003e2,0x00060041,0x000002e9,0x000006e7,0x000002e6,0x000002e7, + 0x000006e6,0x00050041,0x000002e9,0x000006e8,0x000002ee,0x00000096,0x0004003d,0x00000006, + 0x000006e9,0x000006e8,0x0004003d,0x00000006,0x000006ea,0x000006d2,0x000500c5,0x00000006, + 0x000006eb,0x000006e9,0x000006ea,0x000700ef,0x00000006,0x000006ec,0x000006e7,0x00000099, + 0x00000096,0x000006eb,0x0003003e,0x000003e4,0x000006ec,0x0004003d,0x00000006,0x000006ed, + 0x000003e4,0x000500b0,0x00000041,0x000006f0,0x000006ed,0x000006e9,0x000300f7,0x000006ff, + 0x00000000,0x000400fa,0x000006f0,0x000006fd,0x000006f1,0x000200f8,0x000006f1,0x0004003d, + 0x00000006,0x000006f2,0x000003e4,0x000500c7,0x00000006,0x000006f3,0x000006f2,0x00000201, + 0x0003003e,0x000006d6,0x000006f3,0x0004003d,0x00000006,0x0000070f,0x000006d6,0x00040070, + 0x00000008,0x00000710,0x0000070f,0x0003003e,0x0000070c,0x00000710,0x0004003d,0x00000008, + 0x00000711,0x0000070c,0x0003003e,0x0000070d,0x00000711,0x0004003d,0x00000008,0x000006f4, + 0x0000070d,0x00050085,0x00000008,0x000006f5,0x000006f4,0x00000208,0x0003003e,0x000006d5, + 0x000006f5,0x0004003d,0x00000008,0x000006f6,0x000006d5,0x0004003d,0x00000008,0x000006f7, + 0x000003e0,0x0007000c,0x00000008,0x000006f8,0x00000001,0x00000028,0x000006f6,0x000006f7, + 0x0003003e,0x000006d7,0x000006f8,0x0004003d,0x00000008,0x000006f9,0x000006d5,0x0003003e, + 0x000006d8,0x000006f9,0x0004003d,0x00000008,0x000006fa,0x000006d7,0x0003003e,0x000006d9, + 0x000006fa,0x0004003d,0x00000008,0x000006fb,0x000003dd,0x0003003e,0x000006da,0x000006fb, + 0x0004003d,0x00000008,0x00000714,0x000006d9,0x0004003d,0x00000008,0x00000715,0x000006d8, + 0x00050083,0x00000008,0x00000716,0x00000714,0x00000715,0x0004003d,0x00000008,0x00000717, + 0x000006d8,0x0004003d,0x00000008,0x00000718,0x000006da,0x00050085,0x00000008,0x00000719, + 0x00000717,0x00000718,0x00050083,0x00000008,0x0000071a,0x000000c6,0x00000719,0x0007000c, + 0x00000008,0x0000071b,0x00000001,0x00000028,0x0000071a,0x000001cf,0x00050088,0x00000008, + 0x0000071c,0x00000716,0x0000071b,0x0003003e,0x00000712,0x0000071c,0x0004003d,0x00000008, + 0x000006fc,0x00000712,0x0003003e,0x000006d4,0x000006fc,0x000200f9,0x000006ff,0x000200f8, + 0x000006fd,0x0004003d,0x00000008,0x000006fe,0x000003e0,0x0003003e,0x000006d4,0x000006fe, + 0x000200f9,0x000006ff,0x000200f8,0x000006ff,0x0004003d,0x00000008,0x00000700,0x000006d4, + 0x0004003d,0x00000008,0x00000701,0x000003dd,0x00050085,0x00000008,0x00000702,0x00000701, + 0x00000700,0x0003003e,0x000003dd,0x00000702,0x000200f9,0x00000703,0x000200f8,0x00000703, + 0x0004003d,0x00000008,0x000003e7,0x000003dd,0x0003003e,0x000003de,0x000003e7,0x000200f9, + 0x000003da,0x000200f8,0x000003da,0x000300f7,0x000003fb,0x00000000,0x000400fa,0x000000f5, + 0x000003fa,0x000003fb,0x000200f8,0x000003fa,0x0004003d,0x00000013,0x00000401,0x000003fd, + 0x0007004f,0x00000034,0x00000402,0x00000401,0x00000401,0x00000000,0x00000001,0x0003003e, + 0x00000400,0x00000402,0x00050041,0x00000404,0x00000405,0x000002ee,0x00000099,0x0004003d, + 0x00000008,0x00000406,0x00000405,0x0003003e,0x00000403,0x00000406,0x00050041,0x00000404, + 0x00000408,0x000002ee,0x0000009c,0x0004003d,0x00000008,0x00000409,0x00000408,0x0003003e, + 0x00000407,0x00000409,0x000300f7,0x00000729,0x00000000,0x000400fa,0x000000f5,0x00000724, + 0x00000723,0x000200f8,0x00000723,0x0003003e,0x0000071d,0x000000c1,0x000200f9,0x00000729, + 0x000200f8,0x00000724,0x0004003d,0x00000034,0x00000725,0x00000400,0x0003003e,0x0000071e, + 0x00000725,0x0004003d,0x00000008,0x00000726,0x00000403,0x0003003e,0x0000071f,0x00000726, + 0x0004003d,0x00000008,0x00000727,0x00000407,0x0003003e,0x00000720,0x00000727,0x00050041, + 0x00000019,0x0000072f,0x0000071e,0x00000096,0x0004003d,0x00000008,0x00000730,0x0000072f, + 0x00050085,0x00000008,0x00000731,0x000000df,0x00000730,0x00050041,0x00000019,0x00000732, + 0x0000071e,0x00000099,0x0004003d,0x00000008,0x00000733,0x00000732,0x00050085,0x00000008, + 0x00000734,0x000000e3,0x00000733,0x00050081,0x00000008,0x00000735,0x00000731,0x00000734, + 0x0006000c,0x00000008,0x00000736,0x00000001,0x0000000a,0x00000735,0x0003003e,0x0000072b, + 0x00000736,0x0004003d,0x00000008,0x00000737,0x0000072b,0x00050085,0x00000008,0x00000738, + 0x000000ea,0x00000737,0x0006000c,0x00000008,0x00000739,0x00000001,0x0000000a,0x00000738, + 0x0003003e,0x0000072c,0x00000739,0x0004003d,0x00000008,0x0000073a,0x0000072c,0x0004003d, + 0x00000008,0x0000073b,0x0000071f,0x00050085,0x00000008,0x0000073c,0x0000073a,0x0000073b, + 0x0004003d,0x00000008,0x0000073d,0x00000720,0x00050081,0x00000008,0x0000073e,0x0000073c, + 0x0000073d,0x0003003e,0x0000072d,0x0000073e,0x0004003d,0x00000008,0x00000728,0x0000072d, + 0x0003003e,0x0000071d,0x00000728,0x000200f9,0x00000729,0x000200f8,0x00000729,0x0004003d, + 0x00000008,0x0000072a,0x0000071d,0x0003003e,0x00000721,0x0000072a,0x0004003d,0x00000008, + 0x0000040a,0x00000721,0x0003003e,0x000003fc,0x0000040a,0x000200f9,0x000003fb,0x000200f8, + 0x000003fb,0x00050041,0x00000019,0x0000040b,0x0000038a,0x0000009f,0x0004003d,0x00000008, + 0x0000040c,0x0000040b,0x0004003d,0x00000013,0x0000040d,0x0000038a,0x0008004f,0x00000021, + 0x0000040e,0x0000040d,0x0000040d,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000021, + 0x0000040f,0x0000040e,0x0000040c,0x00050041,0x00000019,0x00000410,0x0000038a,0x00000096, + 0x00050051,0x00000008,0x00000411,0x0000040f,0x00000000,0x0003003e,0x00000410,0x00000411, + 0x00050041,0x00000019,0x00000412,0x0000038a,0x00000099,0x00050051,0x00000008,0x00000413, + 0x0000040f,0x00000001,0x0003003e,0x00000412,0x00000413,0x00050041,0x00000019,0x00000414, + 0x0000038a,0x0000009c,0x00050051,0x00000008,0x00000415,0x0000040f,0x00000002,0x0003003e, + 0x00000414,0x00000415,0x000300f7,0x00000417,0x00000000,0x000400fa,0x000000f5,0x00000416, + 0x00000417,0x000200f8,0x00000416,0x0004003d,0x00000008,0x00000418,0x000003fc,0x0004003d, + 0x00000013,0x00000419,0x0000038a,0x0008004f,0x00000021,0x0000041a,0x00000419,0x00000419, + 0x00000000,0x00000001,0x00000002,0x00060050,0x00000021,0x0000041b,0x00000418,0x00000418, + 0x00000418,0x00050081,0x00000021,0x0000041c,0x0000041a,0x0000041b,0x00050051,0x00000008, + 0x0000041e,0x0000041c,0x00000000,0x0003003e,0x00000410,0x0000041e,0x00050051,0x00000008, + 0x00000420,0x0000041c,0x00000001,0x0003003e,0x00000412,0x00000420,0x00050051,0x00000008, + 0x00000422,0x0000041c,0x00000002,0x0003003e,0x00000414,0x00000422,0x000200f9,0x00000417, + 0x000200f8,0x00000417,0x0003003e,0x00000425,0x000000c1,0x0004003d,0x00000008,0x00000742, + 0x00000425,0x00050041,0x00000019,0x00000743,0x0000073f,0x00000096,0x0003003e,0x00000743, + 0x00000742,0x0004003d,0x00000008,0x00000744,0x00000425,0x00050041,0x00000019,0x00000745, + 0x0000073f,0x00000099,0x0003003e,0x00000745,0x00000744,0x0004003d,0x00000008,0x00000746, + 0x00000425,0x00050041,0x00000019,0x00000747,0x0000073f,0x0000009c,0x0003003e,0x00000747, + 0x00000746,0x0004003d,0x00000008,0x00000748,0x00000425,0x00050041,0x00000019,0x00000749, + 0x0000073f,0x0000009f,0x0003003e,0x00000749,0x00000748,0x0004003d,0x00000013,0x0000074a, + 0x0000073f,0x0003003e,0x00000740,0x0000074a,0x0004003d,0x00000013,0x00000426,0x00000740, + 0x0003003e,0x00000424,0x00000426,0x0004003d,0x00000013,0x00000428,0x0000038a,0x0003003e, + 0x00000427,0x00000428,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..443ebd5e6bfc0e660065a808209fab6c27c33db2 GIT binary patch literal 25680 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.h new file mode 100644 index 000000000..174e7c082 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.h @@ -0,0 +1,2063 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_path_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000ee9,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x00020011,0x00000031,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x0010000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x000005b9,0x000005bf,0x000005cc,0x000005d2,0x000005e4,0x000005f7,0x00000603, + 0x00000660,0x000006b3,0x000006b6,0x000006bf,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000181,0x0000674e, + 0x00030005,0x000001af,0x00004351,0x00030005,0x000001b3,0x00003954,0x00030005,0x000003fb, + 0x0000674d,0x00030005,0x00000492,0x00004444,0x00030005,0x00000494,0x00006277,0x00030005, + 0x000004b3,0x00004344,0x00030005,0x000004b5,0x00003552,0x00030005,0x000004d4,0x0000674a, + 0x00030005,0x00000513,0x00006454,0x00040006,0x00000513,0x00000000,0x00003464,0x00030005, + 0x00000515,0x00003053,0x00030005,0x0000051a,0x0000424d,0x00040006,0x0000051a,0x00000000, + 0x00003157,0x00040006,0x0000051a,0x00000001,0x0000676e,0x00040006,0x0000051a,0x00000002, + 0x00003376,0x00040006,0x0000051a,0x00000003,0x00003377,0x00040006,0x0000051a,0x00000004, + 0x00006462,0x00030005,0x0000051c,0x0000006b,0x00030005,0x000005b7,0x00000045,0x00060005, + 0x000005b9,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x000005be,0x00003046, + 0x00030005,0x000005bf,0x0000316b,0x00040005,0x000005c0,0x61726170,0x0000006d,0x00040005, + 0x000005c2,0x61726170,0x0000006d,0x00030005,0x000005c4,0x00006262,0x00040005,0x000005c7, + 0x306a3742,0x00000000,0x00030005,0x000005cb,0x00003071,0x00030005,0x000005cc,0x00000049, + 0x00040005,0x000005cd,0x61726170,0x0000006d,0x00030005,0x000005d0,0x00003679,0x00030005, + 0x000005d2,0x00003469,0x00030005,0x000005e2,0x0000374e,0x00030005,0x000005e4,0x00003361, + 0x00030005,0x000005e8,0x00003154,0x00040005,0x000005ed,0x61726170,0x0000006d,0x00040005, + 0x000005ee,0x61726170,0x0000006d,0x00030005,0x000005f2,0x00003149,0x00030005,0x000005f3, + 0x00006748,0x00030005,0x000005f6,0x00006263,0x00030005,0x000005f7,0x0000304e,0x00040005, + 0x000005f8,0x61726170,0x0000006d,0x00040005,0x000005fb,0x61726170,0x0000006d,0x00030005, + 0x00000600,0x00006747,0x00030005,0x00000603,0x00003153,0x00030005,0x0000060b,0x00006264, + 0x00040005,0x0000060c,0x30653742,0x00000000,0x00040005,0x00000618,0x61726170,0x0000006d, + 0x00030005,0x0000061d,0x00003170,0x00030005,0x0000061e,0x00003347,0x00040005,0x0000061f, + 0x61726170,0x0000006d,0x00040005,0x00000622,0x61726170,0x0000006d,0x00040005,0x00000624, + 0x61726170,0x0000006d,0x00040005,0x00000626,0x61726170,0x0000006d,0x00040005,0x00000627, + 0x61726170,0x0000006d,0x00040005,0x0000062e,0x61726170,0x0000006d,0x00040005,0x00000631, + 0x61726170,0x0000006d,0x00040005,0x00000633,0x61726170,0x0000006d,0x00040005,0x00000635, + 0x61726170,0x0000006d,0x00040005,0x00000636,0x61726170,0x0000006d,0x00030005,0x0000063e, + 0x00003545,0x00040005,0x00000641,0x61726170,0x0000006d,0x00040005,0x00000644,0x61726170, + 0x0000006d,0x00040005,0x00000647,0x61726170,0x0000006d,0x00030005,0x00000651,0x00006872, + 0x00030005,0x00000660,0x00003159,0x00040005,0x00000661,0x61726170,0x0000006d,0x00040005, + 0x00000664,0x61726170,0x0000006d,0x00040005,0x00000667,0x61726170,0x0000006d,0x00040005, + 0x00000669,0x61726170,0x0000006d,0x00030005,0x00000675,0x00003750,0x00030005,0x00000684, + 0x0000367a,0x00040005,0x00000687,0x61726170,0x0000006d,0x00040005,0x00000689,0x61726170, + 0x0000006d,0x00030005,0x000006b3,0x00003065,0x00040005,0x000006b4,0x61726170,0x0000006d, + 0x00030005,0x000006b6,0x0000306a,0x00030005,0x000006bf,0x0000307a,0x00040047,0x00000181, + 0x00000001,0x00000007,0x00030047,0x000001af,0x00000000,0x00040047,0x000001af,0x00000021, + 0x0000000a,0x00040047,0x000001af,0x00000022,0x00000000,0x00030047,0x000001b3,0x00000000, + 0x00040047,0x000001b3,0x00000021,0x0000000a,0x00040047,0x000001b3,0x00000022,0x00000000, + 0x00040047,0x000003fb,0x00000001,0x00000006,0x00030047,0x00000492,0x00000000,0x00040047, + 0x00000492,0x00000021,0x00000009,0x00040047,0x00000492,0x00000022,0x00000000,0x00030047, + 0x00000494,0x00000000,0x00040047,0x00000494,0x00000021,0x00000009,0x00040047,0x00000494, + 0x00000022,0x00000000,0x00030047,0x000004b3,0x00000000,0x00040047,0x000004b3,0x00000021, + 0x0000000c,0x00040047,0x000004b3,0x00000022,0x00000001,0x00030047,0x000004b5,0x00000000, + 0x00040047,0x000004b5,0x00000021,0x0000000c,0x00040047,0x000004b5,0x00000022,0x00000001, + 0x00040047,0x000004d4,0x00000001,0x00000003,0x00040047,0x00000512,0x00000006,0x00000004, + 0x00030047,0x00000513,0x00000003,0x00050048,0x00000513,0x00000000,0x00000023,0x00000000, + 0x00040047,0x00000515,0x00000021,0x00000007,0x00040047,0x00000515,0x00000022,0x00000000, + 0x00030047,0x0000051a,0x00000002,0x00050048,0x0000051a,0x00000000,0x00000023,0x00000040, + 0x00050048,0x0000051a,0x00000001,0x00000023,0x00000044,0x00050048,0x0000051a,0x00000002, + 0x00000023,0x00000058,0x00050048,0x0000051a,0x00000003,0x00000023,0x0000005c,0x00050048, + 0x0000051a,0x00000004,0x00000023,0x00000060,0x00040047,0x0000051c,0x00000021,0x00000000, + 0x00040047,0x0000051c,0x00000022,0x00000000,0x00040047,0x000005b9,0x0000000b,0x0000000f, + 0x00030047,0x000005be,0x00000000,0x00040047,0x000005bf,0x0000001e,0x00000000,0x00030047, + 0x000005c4,0x00000000,0x00030047,0x000005c7,0x00000000,0x00040047,0x000005c7,0x00000021, + 0x00000000,0x00040047,0x000005c7,0x00000022,0x00000002,0x00040047,0x000005c7,0x0000002b, + 0x00000000,0x00030047,0x000005c8,0x00000000,0x00030047,0x000005ca,0x00000000,0x00030047, + 0x000005cb,0x00000000,0x00040047,0x000005cc,0x0000001e,0x00000002,0x00040047,0x000005d2, + 0x0000001e,0x00000008,0x00030047,0x000005d4,0x00000000,0x00030047,0x000005d5,0x00000000, + 0x00030047,0x000005d6,0x00000000,0x00030047,0x000005d7,0x00000000,0x00030047,0x000005d8, + 0x00000000,0x00030047,0x000005e4,0x0000000e,0x00040047,0x000005e4,0x0000001e,0x00000007, + 0x00030047,0x000005f2,0x00000000,0x00040047,0x000005f3,0x00000001,0x00000001,0x00030047, + 0x000005f6,0x00000000,0x00040047,0x000005f7,0x0000001e,0x00000005,0x00030047,0x000005fb, + 0x00000000,0x00030047,0x000005fd,0x00000000,0x00030047,0x000005fe,0x00000000,0x00030047, + 0x000005ff,0x00000000,0x00040047,0x00000600,0x00000001,0x00000000,0x00030047,0x00000603, + 0x00000000,0x00030047,0x00000603,0x0000000e,0x00040047,0x00000603,0x0000001e,0x00000004, + 0x00030047,0x00000606,0x00000000,0x00030047,0x0000060b,0x00000000,0x00030047,0x0000060c, + 0x00000000,0x00040047,0x0000060c,0x00000021,0x00000001,0x00040047,0x0000060c,0x00000022, + 0x00000002,0x00040047,0x0000060c,0x0000002b,0x00000001,0x00030047,0x0000060d,0x00000000, + 0x00030047,0x0000060e,0x00000000,0x00030047,0x0000060f,0x00000000,0x00030047,0x00000610, + 0x00000000,0x00030047,0x00000611,0x00000000,0x00030047,0x00000612,0x00000000,0x00030047, + 0x00000613,0x00000000,0x00030047,0x00000614,0x00000000,0x00030047,0x00000615,0x00000000, + 0x00030047,0x00000616,0x00000000,0x00030047,0x00000617,0x00000000,0x00030047,0x00000621, + 0x00000000,0x00030047,0x00000622,0x00000000,0x00030047,0x00000623,0x00000000,0x00030047, + 0x00000627,0x00000000,0x00030047,0x00000630,0x00000000,0x00030047,0x00000631,0x00000000, + 0x00030047,0x00000632,0x00000000,0x00030047,0x00000636,0x00000000,0x00030047,0x0000063e, + 0x00000000,0x00030047,0x00000644,0x00000000,0x00030047,0x00000647,0x00000000,0x00030047, + 0x0000064c,0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000660,0x0000000e, + 0x00040047,0x00000660,0x0000001e,0x00000006,0x00030047,0x00000661,0x00000000,0x00030047, + 0x00000662,0x00000000,0x00030047,0x00000664,0x00000000,0x00030047,0x00000665,0x00000000, + 0x00030047,0x00000666,0x00000000,0x00030047,0x00000667,0x00000000,0x00030047,0x00000668, + 0x00000000,0x00030047,0x00000669,0x00000000,0x00030047,0x00000675,0x00000000,0x00030047, + 0x00000676,0x00000000,0x00030047,0x00000677,0x00000000,0x00030047,0x0000067a,0x00000000, + 0x00030047,0x0000067f,0x00000000,0x00030047,0x00000684,0x00000000,0x00030047,0x00000684, + 0x00000017,0x00040047,0x00000684,0x00000021,0x00000002,0x00040047,0x00000684,0x00000022, + 0x00000002,0x00030047,0x00000685,0x00000000,0x00030047,0x00000687,0x00000000,0x00030047, + 0x00000688,0x00000000,0x00030047,0x00000689,0x00000000,0x00030047,0x00000690,0x00000000, + 0x00030047,0x00000692,0x00000000,0x00030047,0x0000069b,0x00000000,0x00030047,0x0000069c, + 0x00000000,0x00030047,0x0000069d,0x00000000,0x00030047,0x0000069e,0x00000000,0x00030047, + 0x000006a7,0x00000000,0x00030047,0x000006a8,0x00000000,0x00030047,0x000006a9,0x00000000, + 0x00030047,0x000006aa,0x00000000,0x00030047,0x000006ab,0x00000000,0x00030047,0x000006b3, + 0x00000000,0x00040047,0x000006b3,0x0000001e,0x00000001,0x00030047,0x000006b4,0x00000000, + 0x00030047,0x000006b6,0x00000000,0x00040047,0x000006b6,0x0000001e,0x00000000,0x00030047, + 0x000006b7,0x00000000,0x00030047,0x000006bf,0x00000000,0x00030047,0x000006bf,0x0000000e, + 0x00040047,0x000006bf,0x0000001e,0x00000003,0x00030047,0x000006d3,0x00000000,0x00030047, + 0x000006db,0x00000000,0x00030047,0x000006dc,0x00000000,0x00030047,0x000006dd,0x00000000, + 0x00030047,0x000006de,0x00000000,0x00030047,0x000006df,0x00000000,0x00030047,0x000006e0, + 0x00000000,0x00030047,0x000006ee,0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047, + 0x000006f3,0x00000000,0x00030047,0x000006f4,0x00000000,0x00030047,0x000006fa,0x00000000, + 0x00030047,0x000006fd,0x00000000,0x00030047,0x000006fe,0x00000000,0x00030047,0x000006ff, + 0x00000000,0x00030047,0x00000724,0x00000000,0x00030047,0x00000725,0x00000000,0x00030047, + 0x0000072a,0x00000000,0x00030047,0x0000072d,0x00000000,0x00030047,0x00000738,0x00000000, + 0x00030047,0x0000073d,0x00000000,0x00030047,0x0000073e,0x00000000,0x00030047,0x0000073f, + 0x00000000,0x00030047,0x00000741,0x00000000,0x00030047,0x00000742,0x00000000,0x00030047, + 0x00000744,0x00000000,0x00030047,0x00000749,0x00000000,0x00030047,0x0000074a,0x00000000, + 0x00030047,0x0000074c,0x00000000,0x00030047,0x0000074d,0x00000000,0x00030047,0x0000074e, + 0x00000000,0x00030047,0x0000074f,0x00000000,0x00030047,0x00000751,0x00000000,0x00030047, + 0x00000758,0x00000000,0x00030047,0x0000075a,0x00000000,0x00030047,0x0000075b,0x00000000, + 0x00030047,0x0000075c,0x00000000,0x00030047,0x0000075f,0x00000000,0x00030047,0x00000761, + 0x00000000,0x00030047,0x00000765,0x00000000,0x00030047,0x00000772,0x00000000,0x00030047, + 0x00000779,0x00000000,0x00030047,0x0000077c,0x00000000,0x00030047,0x0000077d,0x00000000, + 0x00030047,0x00000788,0x00000000,0x00030047,0x0000078e,0x00000000,0x00030047,0x00000794, + 0x00000000,0x00030047,0x00000795,0x00000000,0x00030047,0x00000796,0x00000000,0x00030047, + 0x00000797,0x00000000,0x00030047,0x00000798,0x00000000,0x00030047,0x00000799,0x00000000, + 0x00030047,0x0000079a,0x00000000,0x00030047,0x0000079b,0x00000000,0x00030047,0x0000079c, + 0x00000000,0x00030047,0x0000079d,0x00000000,0x00030047,0x0000079e,0x00000000,0x00030047, + 0x0000079f,0x00000000,0x00030047,0x000007a0,0x00000000,0x00030047,0x000007a1,0x00000000, + 0x00030047,0x000007a2,0x00000000,0x00030047,0x000007a3,0x00000000,0x00030047,0x000007a4, + 0x00000000,0x00030047,0x000007a5,0x00000000,0x00030047,0x000007a6,0x00000000,0x00030047, + 0x000007a7,0x00000000,0x00030047,0x000007a8,0x00000000,0x00030047,0x000007a9,0x00000000, + 0x00030047,0x000007b0,0x00000000,0x00030047,0x000007b4,0x00000000,0x00030047,0x000007b5, + 0x00000000,0x00030047,0x000007b7,0x00000000,0x00030047,0x000007b8,0x00000000,0x00030047, + 0x000007b9,0x00000000,0x00030047,0x000007ba,0x00000000,0x00030047,0x000007bc,0x00000000, + 0x00030047,0x000007bd,0x00000000,0x00030047,0x000007be,0x00000000,0x00030047,0x000007c9, + 0x00000000,0x00030047,0x000007ca,0x00000000,0x00030047,0x000007cb,0x00000000,0x00030047, + 0x000007cc,0x00000000,0x00030047,0x000007cd,0x00000000,0x00030047,0x000007ce,0x00000000, + 0x00030047,0x000007d0,0x00000000,0x00030047,0x000007d1,0x00000000,0x00030047,0x000007d2, + 0x00000000,0x00030047,0x000007d3,0x00000000,0x00030047,0x000007d4,0x00000000,0x00030047, + 0x000007d5,0x00000000,0x00030047,0x000007d6,0x00000000,0x00030047,0x000007d7,0x00000000, + 0x00030047,0x000007d8,0x00000000,0x00030047,0x000007d9,0x00000000,0x00030047,0x000007da, + 0x00000000,0x00030047,0x000007db,0x00000000,0x00030047,0x000007dc,0x00000000,0x00030047, + 0x000007dd,0x00000000,0x00030047,0x000007de,0x00000000,0x00030047,0x000007df,0x00000000, + 0x00030047,0x000007e2,0x00000000,0x00030047,0x000007e3,0x00000000,0x00030047,0x000007e5, + 0x00000000,0x00030047,0x000007e6,0x00000000,0x00030047,0x000007e9,0x00000000,0x00030047, + 0x000007ea,0x00000000,0x00030047,0x000007ec,0x00000000,0x00030047,0x000007ed,0x00000000, + 0x00030047,0x000007f0,0x00000000,0x00030047,0x000007f1,0x00000000,0x00030047,0x000007f3, + 0x00000000,0x00030047,0x000007f4,0x00000000,0x00030047,0x000007f7,0x00000000,0x00030047, + 0x000007f8,0x00000000,0x00030047,0x000007ff,0x00000000,0x00030047,0x00000800,0x00000000, + 0x00030047,0x00000801,0x00000000,0x00030047,0x00000802,0x00000000,0x00030047,0x00000803, + 0x00000000,0x00030047,0x00000804,0x00000000,0x00030047,0x00000805,0x00000000,0x00030047, + 0x00000806,0x00000000,0x00030047,0x00000807,0x00000000,0x00030047,0x00000808,0x00000000, + 0x00030047,0x00000809,0x00000000,0x00030047,0x0000080a,0x00000000,0x00030047,0x0000080b, + 0x00000000,0x00030047,0x0000080c,0x00000000,0x00030047,0x0000080d,0x00000000,0x00030047, + 0x0000080f,0x00000000,0x00030047,0x00000814,0x00000000,0x00030047,0x00000815,0x00000000, + 0x00030047,0x00000816,0x00000000,0x00030047,0x00000818,0x00000000,0x00030047,0x0000081a, + 0x00000000,0x00030047,0x0000081c,0x00000000,0x00030047,0x0000081e,0x00000000,0x00030047, + 0x00000820,0x00000000,0x00030047,0x00000821,0x00000000,0x00030047,0x00000822,0x00000000, + 0x00030047,0x00000824,0x00000000,0x00030047,0x00000826,0x00000000,0x00030047,0x00000828, + 0x00000000,0x00030047,0x0000082a,0x00000000,0x00030047,0x0000082c,0x00000000,0x00030047, + 0x0000082e,0x00000000,0x00030047,0x00000831,0x00000000,0x00030047,0x00000832,0x00000000, + 0x00030047,0x00000840,0x00000000,0x00030047,0x00000846,0x00000000,0x00030047,0x0000084f, + 0x00000000,0x00030047,0x00000850,0x00000000,0x00030047,0x00000855,0x00000000,0x00030047, + 0x00000856,0x00000000,0x00030047,0x00000861,0x00000000,0x00030047,0x00000862,0x00000000, + 0x00030047,0x0000086b,0x00000000,0x00030047,0x00000892,0x00000000,0x00030047,0x00000893, + 0x00000000,0x00030047,0x00000896,0x00000000,0x00030047,0x00000897,0x00000000,0x00030047, + 0x00000898,0x00000000,0x00030047,0x00000899,0x00000000,0x00030047,0x0000089b,0x00000000, + 0x00030047,0x0000089c,0x00000000,0x00030047,0x0000089d,0x00000000,0x00030047,0x0000089e, + 0x00000000,0x00030047,0x0000089f,0x00000000,0x00030047,0x000008a1,0x00000000,0x00030047, + 0x000008a3,0x00000000,0x00030047,0x000008a4,0x00000000,0x00030047,0x000008a5,0x00000000, + 0x00030047,0x000008ab,0x00000000,0x00030047,0x000008ad,0x00000000,0x00030047,0x000008b1, + 0x00000000,0x00030047,0x000008b3,0x00000000,0x00030047,0x000008b4,0x00000000,0x00030047, + 0x000008b5,0x00000000,0x00030047,0x000008b6,0x00000000,0x00030047,0x000008b8,0x00000000, + 0x00030047,0x000008ba,0x00000000,0x00030047,0x000008bb,0x00000000,0x00030047,0x000008bc, + 0x00000000,0x00030047,0x000008bd,0x00000000,0x00030047,0x000008bf,0x00000000,0x00030047, + 0x000008c0,0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008e3,0x00000000, + 0x00030047,0x000008e4,0x00000000,0x00030047,0x000008e5,0x00000000,0x00030047,0x000008e6, + 0x00000000,0x00030047,0x000008ea,0x00000000,0x00030047,0x000008ed,0x00000000,0x00030047, + 0x000008ee,0x00000000,0x00030047,0x000008f1,0x00000000,0x00030047,0x000008fa,0x00000000, + 0x00030047,0x000008fb,0x00000000,0x00030047,0x000008fc,0x00000000,0x00030047,0x000008fd, + 0x00000000,0x00030047,0x000008fe,0x00000000,0x00030047,0x000008ff,0x00000000,0x00030047, + 0x00000900,0x00000000,0x00030047,0x00000901,0x00000000,0x00030047,0x00000902,0x00000000, + 0x00030047,0x00000906,0x00000000,0x00030047,0x00000907,0x00000000,0x00030047,0x0000090b, + 0x00000000,0x00030047,0x0000090e,0x00000000,0x00030047,0x00000914,0x00000000,0x00030047, + 0x00000915,0x00000000,0x00030047,0x00000916,0x00000000,0x00030047,0x00000917,0x00000000, + 0x00030047,0x00000919,0x00000000,0x00030047,0x0000091a,0x00000000,0x00030047,0x0000091e, + 0x00000000,0x00030047,0x0000091f,0x00000000,0x00030047,0x00000921,0x00000000,0x00030047, + 0x00000922,0x00000000,0x00030047,0x00000923,0x00000000,0x00030047,0x00000924,0x00000000, + 0x00030047,0x00000925,0x00000000,0x00030047,0x00000926,0x00000000,0x00030047,0x00000927, + 0x00000000,0x00030047,0x00000928,0x00000000,0x00030047,0x00000929,0x00000000,0x00030047, + 0x0000092b,0x00000000,0x00030047,0x00000932,0x00000000,0x00030047,0x00000933,0x00000000, + 0x00030047,0x00000934,0x00000000,0x00030047,0x00000938,0x00000000,0x00030047,0x00000939, + 0x00000000,0x00030047,0x0000093b,0x00000000,0x00030047,0x0000093c,0x00000000,0x00030047, + 0x0000093d,0x00000000,0x00030047,0x0000093e,0x00000000,0x00030047,0x0000093f,0x00000000, + 0x00030047,0x00000940,0x00000000,0x00030047,0x00000941,0x00000000,0x00030047,0x00000942, + 0x00000000,0x00030047,0x00000943,0x00000000,0x00030047,0x00000945,0x00000000,0x00030047, + 0x00000946,0x00000000,0x00030047,0x00000947,0x00000000,0x00030047,0x00000949,0x00000000, + 0x00030047,0x0000094a,0x00000000,0x00030047,0x0000094b,0x00000000,0x00030047,0x0000094c, + 0x00000000,0x00030047,0x0000094e,0x00000000,0x00030047,0x0000094f,0x00000000,0x00030047, + 0x0000096d,0x00000000,0x00030047,0x0000096e,0x00000000,0x00030047,0x0000096f,0x00000000, + 0x00030047,0x00000970,0x00000000,0x00030047,0x00000971,0x00000000,0x00030047,0x00000972, + 0x00000000,0x00030047,0x00000975,0x00000000,0x00030047,0x00000977,0x00000000,0x00030047, + 0x00000978,0x00000000,0x00030047,0x0000097a,0x00000000,0x00030047,0x00000980,0x00000000, + 0x00030047,0x00000981,0x00000000,0x00030047,0x00000982,0x00000000,0x00030047,0x00000983, + 0x00000000,0x00030047,0x00000985,0x00000000,0x00030047,0x00000986,0x00000000,0x00030047, + 0x0000098a,0x00000000,0x00030047,0x0000098b,0x00000000,0x00030047,0x0000098d,0x00000000, + 0x00030047,0x0000098e,0x00000000,0x00030047,0x0000098f,0x00000000,0x00030047,0x00000990, + 0x00000000,0x00030047,0x00000991,0x00000000,0x00030047,0x00000992,0x00000000,0x00030047, + 0x00000993,0x00000000,0x00030047,0x00000994,0x00000000,0x00030047,0x00000995,0x00000000, + 0x00030047,0x00000996,0x00000000,0x00030047,0x00000998,0x00000000,0x00030047,0x00000999, + 0x00000000,0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099f,0x00000000,0x00030047, + 0x000009a0,0x00000000,0x00030047,0x000009a3,0x00000000,0x00030047,0x000009a4,0x00000000, + 0x00030047,0x000009a5,0x00000000,0x00030047,0x000009a6,0x00000000,0x00030047,0x000009b0, + 0x00000000,0x00030047,0x000009b1,0x00000000,0x00030047,0x000009b2,0x00000000,0x00030047, + 0x000009b3,0x00000000,0x00030047,0x000009b4,0x00000000,0x00030047,0x000009b5,0x00000000, + 0x00030047,0x000009b6,0x00000000,0x00030047,0x000009b7,0x00000000,0x00030047,0x000009b8, + 0x00000000,0x00030047,0x000009ba,0x00000000,0x00030047,0x000009bb,0x00000000,0x00030047, + 0x000009bc,0x00000000,0x00030047,0x000009bd,0x00000000,0x00030047,0x000009be,0x00000000, + 0x00030047,0x000009bf,0x00000000,0x00030047,0x000009c0,0x00000000,0x00030047,0x000009c1, + 0x00000000,0x00030047,0x000009c3,0x00000000,0x00030047,0x000009c4,0x00000000,0x00030047, + 0x000009c5,0x00000000,0x00030047,0x000009c7,0x00000000,0x00030047,0x000009c8,0x00000000, + 0x00030047,0x000009ca,0x00000000,0x00030047,0x000009cc,0x00000000,0x00030047,0x000009cd, + 0x00000000,0x00030047,0x000009ce,0x00000000,0x00030047,0x000009cf,0x00000000,0x00030047, + 0x000009d0,0x00000000,0x00030047,0x000009d1,0x00000000,0x00030047,0x000009d2,0x00000000, + 0x00030047,0x000009d3,0x00000000,0x00030047,0x000009d4,0x00000000,0x00030047,0x000009d5, + 0x00000000,0x00030047,0x000009d6,0x00000000,0x00030047,0x000009d7,0x00000000,0x00030047, + 0x000009d8,0x00000000,0x00030047,0x000009d9,0x00000000,0x00030047,0x000009da,0x00000000, + 0x00030047,0x000009db,0x00000000,0x00030047,0x000009dc,0x00000000,0x00030047,0x000009dd, + 0x00000000,0x00030047,0x000009de,0x00000000,0x00030047,0x000009df,0x00000000,0x00030047, + 0x000009e1,0x00000000,0x00030047,0x000009e2,0x00000000,0x00030047,0x000009e3,0x00000000, + 0x00030047,0x000009e4,0x00000000,0x00030047,0x000009e5,0x00000000,0x00030047,0x000009e6, + 0x00000000,0x00030047,0x000009e7,0x00000000,0x00030047,0x000009e8,0x00000000,0x00030047, + 0x000009e9,0x00000000,0x00030047,0x000009ea,0x00000000,0x00030047,0x000009eb,0x00000000, + 0x00030047,0x000009ec,0x00000000,0x00030047,0x000009ed,0x00000000,0x00030047,0x000009ee, + 0x00000000,0x00030047,0x000009ef,0x00000000,0x00030047,0x000009f0,0x00000000,0x00030047, + 0x000009f1,0x00000000,0x00030047,0x000009f2,0x00000000,0x00030047,0x000009f3,0x00000000, + 0x00030047,0x000009f5,0x00000000,0x00030047,0x000009f7,0x00000000,0x00030047,0x000009fa, + 0x00000000,0x00030047,0x000009fd,0x00000000,0x00030047,0x000009fe,0x00000000,0x00030047, + 0x000009ff,0x00000000,0x00030047,0x00000a04,0x00000000,0x00030047,0x00000a07,0x00000000, + 0x00030047,0x00000a08,0x00000000,0x00030047,0x00000a09,0x00000000,0x00030047,0x00000a0e, + 0x00000000,0x00030047,0x00000a11,0x00000000,0x00030047,0x00000a12,0x00000000,0x00030047, + 0x00000a13,0x00000000,0x00030047,0x00000a14,0x00000000,0x00030047,0x00000a19,0x00000000, + 0x00030047,0x00000a1c,0x00000000,0x00030047,0x00000a1d,0x00000000,0x00030047,0x00000a1e, + 0x00000000,0x00030047,0x00000a1f,0x00000000,0x00030047,0x00000a23,0x00000000,0x00030047, + 0x00000a24,0x00000000,0x00030047,0x00000a25,0x00000000,0x00030047,0x00000a26,0x00000000, + 0x00030047,0x00000a27,0x00000000,0x00030047,0x00000a28,0x00000000,0x00030047,0x00000a29, + 0x00000000,0x00030047,0x00000a2a,0x00000000,0x00030047,0x00000a2c,0x00000000,0x00030047, + 0x00000a2d,0x00000000,0x00030047,0x00000a2e,0x00000000,0x00030047,0x00000a2f,0x00000000, + 0x00030047,0x00000a38,0x00000000,0x00030047,0x00000a3d,0x00000000,0x00030047,0x00000a43, + 0x00000000,0x00030047,0x00000a44,0x00000000,0x00030047,0x00000a45,0x00000000,0x00030047, + 0x00000a4b,0x00000000,0x00030047,0x00000a4c,0x00000000,0x00030047,0x00000a4d,0x00000000, + 0x00030047,0x00000a50,0x00000000,0x00030047,0x00000a51,0x00000000,0x00030047,0x00000a52, + 0x00000000,0x00030047,0x00000a59,0x00000000,0x00030047,0x00000a5a,0x00000000,0x00030047, + 0x00000a61,0x00000000,0x00030047,0x00000a62,0x00000000,0x00030047,0x00000a63,0x00000000, + 0x00030047,0x00000a64,0x00000000,0x00030047,0x00000a65,0x00000000,0x00030047,0x00000a66, + 0x00000000,0x00030047,0x00000a67,0x00000000,0x00030047,0x00000a68,0x00000000,0x00030047, + 0x00000a69,0x00000000,0x00030047,0x00000a6b,0x00000000,0x00030047,0x00000a6c,0x00000000, + 0x00030047,0x00000a6d,0x00000000,0x00030047,0x00000a6e,0x00000000,0x00030047,0x00000a6f, + 0x00000000,0x00030047,0x00000a70,0x00000000,0x00030047,0x00000a71,0x00000000,0x00030047, + 0x00000a72,0x00000000,0x00030047,0x00000a73,0x00000000,0x00030047,0x00000a74,0x00000000, + 0x00030047,0x00000a75,0x00000000,0x00030047,0x00000a77,0x00000000,0x00030047,0x00000a78, + 0x00000000,0x00030047,0x00000a79,0x00000000,0x00030047,0x00000a7b,0x00000000,0x00030047, + 0x00000a7e,0x00000000,0x00030047,0x00000a7f,0x00000000,0x00030047,0x00000a80,0x00000000, + 0x00030047,0x00000a82,0x00000000,0x00030047,0x00000a83,0x00000000,0x00030047,0x00000a84, + 0x00000000,0x00030047,0x00000a8c,0x00000000,0x00030047,0x00000a92,0x00000000,0x00030047, + 0x00000a93,0x00000000,0x00030047,0x00000a94,0x00000000,0x00030047,0x00000a95,0x00000000, + 0x00030047,0x00000a96,0x00000000,0x00030047,0x00000a98,0x00000000,0x00030047,0x00000a99, + 0x00000000,0x00030047,0x00000a9b,0x00000000,0x00030047,0x00000a9c,0x00000000,0x00030047, + 0x00000a9d,0x00000000,0x00030047,0x00000a9e,0x00000000,0x00030047,0x00000a9f,0x00000000, + 0x00030047,0x00000aa0,0x00000000,0x00030047,0x00000aa1,0x00000000,0x00030047,0x00000aa3, + 0x00000000,0x00030047,0x00000aa4,0x00000000,0x00030047,0x00000aa5,0x00000000,0x00030047, + 0x00000aa7,0x00000000,0x00030047,0x00000aa8,0x00000000,0x00030047,0x00000aaa,0x00000000, + 0x00030047,0x00000aab,0x00000000,0x00030047,0x00000aac,0x00000000,0x00030047,0x00000ab3, + 0x00000000,0x00030047,0x00000ab4,0x00000000,0x00030047,0x00000ab7,0x00000000,0x00030047, + 0x00000ab9,0x00000000,0x00030047,0x00000aba,0x00000000,0x00030047,0x00000abc,0x00000000, + 0x00030047,0x00000abd,0x00000000,0x00030047,0x00000abe,0x00000000,0x00030047,0x00000abf, + 0x00000000,0x00030047,0x00000ac0,0x00000000,0x00030047,0x00000ac1,0x00000000,0x00030047, + 0x00000ac2,0x00000000,0x00030047,0x00000ac3,0x00000000,0x00030047,0x00000ac4,0x00000000, + 0x00030047,0x00000ac6,0x00000000,0x00030047,0x00000ac7,0x00000000,0x00030047,0x00000ac9, + 0x00000000,0x00030047,0x00000aca,0x00000000,0x00030047,0x00000acb,0x00000000,0x00030047, + 0x00000acd,0x00000000,0x00030047,0x00000ace,0x00000000,0x00030047,0x00000acf,0x00000000, + 0x00030047,0x00000ad1,0x00000000,0x00030047,0x00000ad2,0x00000000,0x00030047,0x00000ad3, + 0x00000000,0x00030047,0x00000ad4,0x00000000,0x00030047,0x00000ad5,0x00000000,0x00030047, + 0x00000ad6,0x00000000,0x00030047,0x00000ad7,0x00000000,0x00030047,0x00000ad8,0x00000000, + 0x00030047,0x00000ad9,0x00000000,0x00030047,0x00000ada,0x00000000,0x00030047,0x00000adb, + 0x00000000,0x00030047,0x00000add,0x00000000,0x00030047,0x00000ade,0x00000000,0x00030047, + 0x00000adf,0x00000000,0x00030047,0x00000ae1,0x00000000,0x00030047,0x00000ae2,0x00000000, + 0x00030047,0x00000ae3,0x00000000,0x00030047,0x00000ae4,0x00000000,0x00030047,0x00000ae5, + 0x00000000,0x00030047,0x00000ae6,0x00000000,0x00030047,0x00000ae7,0x00000000,0x00030047, + 0x00000ae9,0x00000000,0x00030047,0x00000aea,0x00000000,0x00030047,0x00000aeb,0x00000000, + 0x00030047,0x00000aed,0x00000000,0x00030047,0x00000aee,0x00000000,0x00030047,0x00000aef, + 0x00000000,0x00030047,0x00000af1,0x00000000,0x00030047,0x00000af2,0x00000000,0x00030047, + 0x00000af4,0x00000000,0x00030047,0x00000af9,0x00000000,0x00030047,0x00000afa,0x00000000, + 0x00030047,0x00000afc,0x00000000,0x00030047,0x00000afd,0x00000000,0x00030047,0x00000afe, + 0x00000000,0x00030047,0x00000aff,0x00000000,0x00030047,0x00000b01,0x00000000,0x00030047, + 0x00000b03,0x00000000,0x00030047,0x00000b05,0x00000000,0x00030047,0x00000b07,0x00000000, + 0x00030047,0x00000b08,0x00000000,0x00030047,0x00000b09,0x00000000,0x00030047,0x00000b0b, + 0x00000000,0x00030047,0x00000b0d,0x00000000,0x00030047,0x00000b0f,0x00000000,0x00030047, + 0x00000b11,0x00000000,0x00030047,0x00000b12,0x00000000,0x00030047,0x00000b13,0x00000000, + 0x00030047,0x00000b14,0x00000000,0x00030047,0x00000b15,0x00000000,0x00030047,0x00000b16, + 0x00000000,0x00030047,0x00000b17,0x00000000,0x00030047,0x00000b18,0x00000000,0x00030047, + 0x00000b19,0x00000000,0x00030047,0x00000b1a,0x00000000,0x00030047,0x00000b1b,0x00000000, + 0x00030047,0x00000b1c,0x00000000,0x00030047,0x00000b1d,0x00000000,0x00030047,0x00000b1e, + 0x00000000,0x00030047,0x00000b1f,0x00000000,0x00030047,0x00000b20,0x00000000,0x00030047, + 0x00000b22,0x00000000,0x00030047,0x00000b24,0x00000000,0x00030047,0x00000b25,0x00000000, + 0x00030047,0x00000b27,0x00000000,0x00030047,0x00000b28,0x00000000,0x00030047,0x00000b29, + 0x00000000,0x00030047,0x00000b2a,0x00000000,0x00030047,0x00000b2b,0x00000000,0x00030047, + 0x00000b2e,0x00000000,0x00030047,0x00000b30,0x00000000,0x00030047,0x00000b31,0x00000000, + 0x00030047,0x00000b34,0x00000000,0x00030047,0x00000b35,0x00000000,0x00030047,0x00000b38, + 0x00000000,0x00030047,0x00000b3a,0x00000000,0x00030047,0x00000b3b,0x00000000,0x00030047, + 0x00000b3c,0x00000000,0x00030047,0x00000b3d,0x00000000,0x00030047,0x00000b3e,0x00000000, + 0x00030047,0x00000b3f,0x00000000,0x00030047,0x00000b40,0x00000000,0x00030047,0x00000b41, + 0x00000000,0x00030047,0x00000b42,0x00000000,0x00030047,0x00000b43,0x00000000,0x00030047, + 0x00000b44,0x00000000,0x00030047,0x00000b45,0x00000000,0x00030047,0x00000b46,0x00000000, + 0x00030047,0x00000b48,0x00000000,0x00030047,0x00000b4a,0x00000000,0x00030047,0x00000b4b, + 0x00000000,0x00030047,0x00000b4c,0x00000000,0x00030047,0x00000b4e,0x00000000,0x00030047, + 0x00000b50,0x00000000,0x00030047,0x00000b52,0x00000000,0x00030047,0x00000b54,0x00000000, + 0x00030047,0x00000b55,0x00000000,0x00030047,0x00000b56,0x00000000,0x00030047,0x00000b57, + 0x00000000,0x00030047,0x00000b58,0x00000000,0x00030047,0x00000b5a,0x00000000,0x00030047, + 0x00000b5c,0x00000000,0x00030047,0x00000b5d,0x00000000,0x00030047,0x00000b5e,0x00000000, + 0x00030047,0x00000b60,0x00000000,0x00030047,0x00000b62,0x00000000,0x00030047,0x00000b64, + 0x00000000,0x00030047,0x00000b66,0x00000000,0x00030047,0x00000b67,0x00000000,0x00030047, + 0x00000b68,0x00000000,0x00030047,0x00000b6a,0x00000000,0x00030047,0x00000b6c,0x00000000, + 0x00030047,0x00000b6e,0x00000000,0x00030047,0x00000b6f,0x00000000,0x00030047,0x00000b70, + 0x00000000,0x00030047,0x00000b72,0x00000000,0x00030047,0x00000b74,0x00000000,0x00030047, + 0x00000b76,0x00000000,0x00030047,0x00000b77,0x00000000,0x00030047,0x00000b78,0x00000000, + 0x00030047,0x00000b7a,0x00000000,0x00030047,0x00000b7b,0x00000000,0x00030047,0x00000b7e, + 0x00000000,0x00030047,0x00000b7f,0x00000000,0x00030047,0x00000b80,0x00000000,0x00030047, + 0x00000b83,0x00000000,0x00030047,0x00000b85,0x00000000,0x00030047,0x00000b86,0x00000000, + 0x00030047,0x00000b87,0x00000000,0x00030047,0x00000b88,0x00000000,0x00030047,0x00000b8a, + 0x00000000,0x00030047,0x00000b8b,0x00000000,0x00030047,0x00000b8e,0x00000000,0x00030047, + 0x00000b8f,0x00000000,0x00030047,0x00000b90,0x00000000,0x00030047,0x00000b93,0x00000000, + 0x00030047,0x00000b95,0x00000000,0x00030047,0x00000b96,0x00000000,0x00030047,0x00000b97, + 0x00000000,0x00030047,0x00000b98,0x00000000,0x00030047,0x00000b9a,0x00000000,0x00030047, + 0x00000b9c,0x00000000,0x00030047,0x00000b9e,0x00000000,0x00030047,0x00000b9f,0x00000000, + 0x00030047,0x00000ba1,0x00000000,0x00030047,0x00000ba2,0x00000000,0x00030047,0x00000ba3, + 0x00000000,0x00030047,0x00000ba5,0x00000000,0x00030047,0x00000ba7,0x00000000,0x00030047, + 0x00000ba9,0x00000000,0x00030047,0x00000bab,0x00000000,0x00030047,0x00000bac,0x00000000, + 0x00030047,0x00000bad,0x00000000,0x00030047,0x00000baf,0x00000000,0x00030047,0x00000bb1, + 0x00000000,0x00030047,0x00000bb3,0x00000000,0x00030047,0x00000bb5,0x00000000,0x00030047, + 0x00000bb6,0x00000000,0x00030047,0x00000bb7,0x00000000,0x00030047,0x00000bb8,0x00000000, + 0x00030047,0x00000bb9,0x00000000,0x00030047,0x00000bba,0x00000000,0x00030047,0x00000bbb, + 0x00000000,0x00030047,0x00000bbc,0x00000000,0x00030047,0x00000bbd,0x00000000,0x00030047, + 0x00000bbe,0x00000000,0x00030047,0x00000bbf,0x00000000,0x00030047,0x00000bc0,0x00000000, + 0x00030047,0x00000bc1,0x00000000,0x00030047,0x00000bc2,0x00000000,0x00030047,0x00000bc3, + 0x00000000,0x00030047,0x00000bc4,0x00000000,0x00030047,0x00000bc6,0x00000000,0x00030047, + 0x00000bc8,0x00000000,0x00030047,0x00000bc9,0x00000000,0x00030047,0x00000bcb,0x00000000, + 0x00030047,0x00000bcc,0x00000000,0x00030047,0x00000bcd,0x00000000,0x00030047,0x00000bce, + 0x00000000,0x00030047,0x00000bcf,0x00000000,0x00030047,0x00000bd2,0x00000000,0x00030047, + 0x00000bd4,0x00000000,0x00030047,0x00000bd5,0x00000000,0x00030047,0x00000bd8,0x00000000, + 0x00030047,0x00000bd9,0x00000000,0x00030047,0x00000bdc,0x00000000,0x00030047,0x00000bde, + 0x00000000,0x00030047,0x00000bdf,0x00000000,0x00030047,0x00000be0,0x00000000,0x00030047, + 0x00000be1,0x00000000,0x00030047,0x00000be2,0x00000000,0x00030047,0x00000be3,0x00000000, + 0x00030047,0x00000be4,0x00000000,0x00030047,0x00000be5,0x00000000,0x00030047,0x00000be6, + 0x00000000,0x00030047,0x00000be7,0x00000000,0x00030047,0x00000be8,0x00000000,0x00030047, + 0x00000be9,0x00000000,0x00030047,0x00000bea,0x00000000,0x00030047,0x00000bec,0x00000000, + 0x00030047,0x00000bee,0x00000000,0x00030047,0x00000bef,0x00000000,0x00030047,0x00000bf0, + 0x00000000,0x00030047,0x00000bf2,0x00000000,0x00030047,0x00000bf4,0x00000000,0x00030047, + 0x00000bf6,0x00000000,0x00030047,0x00000bf8,0x00000000,0x00030047,0x00000bf9,0x00000000, + 0x00030047,0x00000bfa,0x00000000,0x00030047,0x00000bfb,0x00000000,0x00030047,0x00000bfc, + 0x00000000,0x00030047,0x00000bfe,0x00000000,0x00030047,0x00000c00,0x00000000,0x00030047, + 0x00000c01,0x00000000,0x00030047,0x00000c02,0x00000000,0x00030047,0x00000c04,0x00000000, + 0x00030047,0x00000c06,0x00000000,0x00030047,0x00000c08,0x00000000,0x00030047,0x00000c0a, + 0x00000000,0x00030047,0x00000c0b,0x00000000,0x00030047,0x00000c0c,0x00000000,0x00030047, + 0x00000c0e,0x00000000,0x00030047,0x00000c10,0x00000000,0x00030047,0x00000c12,0x00000000, + 0x00030047,0x00000c13,0x00000000,0x00030047,0x00000c14,0x00000000,0x00030047,0x00000c16, + 0x00000000,0x00030047,0x00000c18,0x00000000,0x00030047,0x00000c1a,0x00000000,0x00030047, + 0x00000c1b,0x00000000,0x00030047,0x00000c1c,0x00000000,0x00030047,0x00000c1e,0x00000000, + 0x00030047,0x00000c1f,0x00000000,0x00030047,0x00000c22,0x00000000,0x00030047,0x00000c23, + 0x00000000,0x00030047,0x00000c24,0x00000000,0x00030047,0x00000c27,0x00000000,0x00030047, + 0x00000c29,0x00000000,0x00030047,0x00000c2a,0x00000000,0x00030047,0x00000c2b,0x00000000, + 0x00030047,0x00000c2c,0x00000000,0x00030047,0x00000c2e,0x00000000,0x00030047,0x00000c2f, + 0x00000000,0x00030047,0x00000c32,0x00000000,0x00030047,0x00000c33,0x00000000,0x00030047, + 0x00000c34,0x00000000,0x00030047,0x00000c37,0x00000000,0x00030047,0x00000c39,0x00000000, + 0x00030047,0x00000c3a,0x00000000,0x00030047,0x00000c3b,0x00000000,0x00030047,0x00000c3c, + 0x00000000,0x00030047,0x00000c3e,0x00000000,0x00030047,0x00000c40,0x00000000,0x00030047, + 0x00000c42,0x00000000,0x00030047,0x00000c43,0x00000000,0x00030047,0x00000c45,0x00000000, + 0x00030047,0x00000c46,0x00000000,0x00030047,0x00000c47,0x00000000,0x00030047,0x00000c49, + 0x00000000,0x00030047,0x00000c4b,0x00000000,0x00030047,0x00000c4d,0x00000000,0x00030047, + 0x00000c4f,0x00000000,0x00030047,0x00000c50,0x00000000,0x00030047,0x00000c51,0x00000000, + 0x00030047,0x00000c53,0x00000000,0x00030047,0x00000c55,0x00000000,0x00030047,0x00000c57, + 0x00000000,0x00030047,0x00000c59,0x00000000,0x00030047,0x00000c5b,0x00000000,0x00030047, + 0x00000c5c,0x00000000,0x00030047,0x00000c5d,0x00000000,0x00030047,0x00000c5f,0x00000000, + 0x00030047,0x00000c61,0x00000000,0x00030047,0x00000c62,0x00000000,0x00030047,0x00000c63, + 0x00000000,0x00030047,0x00000c65,0x00000000,0x00030047,0x00000c67,0x00000000,0x00030047, + 0x00000c69,0x00000000,0x00030047,0x00000c6a,0x00000000,0x00030047,0x00000c6c,0x00000000, + 0x00030047,0x00000c6d,0x00000000,0x00030047,0x00000c6e,0x00000000,0x00030047,0x00000c6f, + 0x00000000,0x00030047,0x00000c75,0x00000000,0x00030047,0x00000c78,0x00000000,0x00030047, + 0x00000c7a,0x00000000,0x00030047,0x00000c7b,0x00000000,0x00030047,0x00000c7d,0x00000000, + 0x00030047,0x00000c7e,0x00000000,0x00030047,0x00000c81,0x00000000,0x00030047,0x00000c82, + 0x00000000,0x00030047,0x00000c83,0x00000000,0x00030047,0x00000c86,0x00000000,0x00030047, + 0x00000c88,0x00000000,0x00030047,0x00000c89,0x00000000,0x00030047,0x00000c8a,0x00000000, + 0x00030047,0x00000c8b,0x00000000,0x00030047,0x00000c8d,0x00000000,0x00030047,0x00000c8e, + 0x00000000,0x00030047,0x00000c91,0x00000000,0x00030047,0x00000c92,0x00000000,0x00030047, + 0x00000c93,0x00000000,0x00030047,0x00000c96,0x00000000,0x00030047,0x00000c98,0x00000000, + 0x00030047,0x00000c99,0x00000000,0x00030047,0x00000c9a,0x00000000,0x00030047,0x00000c9b, + 0x00000000,0x00030047,0x00000c9d,0x00000000,0x00030047,0x00000c9e,0x00000000,0x00030047, + 0x00000ca1,0x00000000,0x00030047,0x00000ca2,0x00000000,0x00030047,0x00000ca3,0x00000000, + 0x00030047,0x00000ca6,0x00000000,0x00030047,0x00000ca8,0x00000000,0x00030047,0x00000ca9, + 0x00000000,0x00030047,0x00000caa,0x00000000,0x00030047,0x00000cab,0x00000000,0x00030047, + 0x00000cad,0x00000000,0x00030047,0x00000cae,0x00000000,0x00030047,0x00000cb1,0x00000000, + 0x00030047,0x00000cb2,0x00000000,0x00030047,0x00000cb3,0x00000000,0x00030047,0x00000cb6, + 0x00000000,0x00030047,0x00000cb8,0x00000000,0x00030047,0x00000cb9,0x00000000,0x00030047, + 0x00000cba,0x00000000,0x00030047,0x00000cbb,0x00000000,0x00030047,0x00000cbc,0x00000000, + 0x00030047,0x00000cbd,0x00000000,0x00030047,0x00000cbe,0x00000000,0x00030047,0x00000cbf, + 0x00000000,0x00030047,0x00000cc0,0x00000000,0x00030047,0x00000cc1,0x00000000,0x00030047, + 0x00000cc2,0x00000000,0x00030047,0x00000cc3,0x00000000,0x00030047,0x00000cc4,0x00000000, + 0x00030047,0x00000cc5,0x00000000,0x00030047,0x00000cc6,0x00000000,0x00030047,0x00000cc7, + 0x00000000,0x00030047,0x00000cc8,0x00000000,0x00030047,0x00000cca,0x00000000,0x00030047, + 0x00000ccc,0x00000000,0x00030047,0x00000ccd,0x00000000,0x00030047,0x00000ccf,0x00000000, + 0x00030047,0x00000cd0,0x00000000,0x00030047,0x00000cd1,0x00000000,0x00030047,0x00000cd2, + 0x00000000,0x00030047,0x00000cd3,0x00000000,0x00030047,0x00000cd6,0x00000000,0x00030047, + 0x00000cd8,0x00000000,0x00030047,0x00000cd9,0x00000000,0x00030047,0x00000cdc,0x00000000, + 0x00030047,0x00000cdd,0x00000000,0x00030047,0x00000ce0,0x00000000,0x00030047,0x00000ce2, + 0x00000000,0x00030047,0x00000ce3,0x00000000,0x00030047,0x00000ce4,0x00000000,0x00030047, + 0x00000ce5,0x00000000,0x00030047,0x00000ce6,0x00000000,0x00030047,0x00000ce7,0x00000000, + 0x00030047,0x00000ce8,0x00000000,0x00030047,0x00000ce9,0x00000000,0x00030047,0x00000cea, + 0x00000000,0x00030047,0x00000ceb,0x00000000,0x00030047,0x00000cec,0x00000000,0x00030047, + 0x00000ced,0x00000000,0x00030047,0x00000cee,0x00000000,0x00030047,0x00000cf0,0x00000000, + 0x00030047,0x00000cf2,0x00000000,0x00030047,0x00000cf3,0x00000000,0x00030047,0x00000cf4, + 0x00000000,0x00030047,0x00000cf6,0x00000000,0x00030047,0x00000cf8,0x00000000,0x00030047, + 0x00000cfa,0x00000000,0x00030047,0x00000cfc,0x00000000,0x00030047,0x00000cfd,0x00000000, + 0x00030047,0x00000cfe,0x00000000,0x00030047,0x00000cff,0x00000000,0x00030047,0x00000d00, + 0x00000000,0x00030047,0x00000d02,0x00000000,0x00030047,0x00000d04,0x00000000,0x00030047, + 0x00000d05,0x00000000,0x00030047,0x00000d06,0x00000000,0x00030047,0x00000d08,0x00000000, + 0x00030047,0x00000d0a,0x00000000,0x00030047,0x00000d0c,0x00000000,0x00030047,0x00000d0e, + 0x00000000,0x00030047,0x00000d0f,0x00000000,0x00030047,0x00000d10,0x00000000,0x00030047, + 0x00000d12,0x00000000,0x00030047,0x00000d14,0x00000000,0x00030047,0x00000d16,0x00000000, + 0x00030047,0x00000d17,0x00000000,0x00030047,0x00000d18,0x00000000,0x00030047,0x00000d1a, + 0x00000000,0x00030047,0x00000d1c,0x00000000,0x00030047,0x00000d1e,0x00000000,0x00030047, + 0x00000d1f,0x00000000,0x00030047,0x00000d20,0x00000000,0x00030047,0x00000d22,0x00000000, + 0x00030047,0x00000d23,0x00000000,0x00030047,0x00000d26,0x00000000,0x00030047,0x00000d27, + 0x00000000,0x00030047,0x00000d28,0x00000000,0x00030047,0x00000d2b,0x00000000,0x00030047, + 0x00000d2d,0x00000000,0x00030047,0x00000d2e,0x00000000,0x00030047,0x00000d2f,0x00000000, + 0x00030047,0x00000d30,0x00000000,0x00030047,0x00000d32,0x00000000,0x00030047,0x00000d33, + 0x00000000,0x00030047,0x00000d36,0x00000000,0x00030047,0x00000d37,0x00000000,0x00030047, + 0x00000d38,0x00000000,0x00030047,0x00000d3b,0x00000000,0x00030047,0x00000d3d,0x00000000, + 0x00030047,0x00000d3e,0x00000000,0x00030047,0x00000d3f,0x00000000,0x00030047,0x00000d40, + 0x00000000,0x00030047,0x00000d42,0x00000000,0x00030047,0x00000d44,0x00000000,0x00030047, + 0x00000d46,0x00000000,0x00030047,0x00000d47,0x00000000,0x00030047,0x00000d49,0x00000000, + 0x00030047,0x00000d4a,0x00000000,0x00030047,0x00000d4b,0x00000000,0x00030047,0x00000d4d, + 0x00000000,0x00030047,0x00000d4f,0x00000000,0x00030047,0x00000d51,0x00000000,0x00030047, + 0x00000d53,0x00000000,0x00030047,0x00000d54,0x00000000,0x00030047,0x00000d55,0x00000000, + 0x00030047,0x00000d57,0x00000000,0x00030047,0x00000d59,0x00000000,0x00030047,0x00000d5b, + 0x00000000,0x00030047,0x00000d5d,0x00000000,0x00030047,0x00000d5f,0x00000000,0x00030047, + 0x00000d60,0x00000000,0x00030047,0x00000d61,0x00000000,0x00030047,0x00000d63,0x00000000, + 0x00030047,0x00000d65,0x00000000,0x00030047,0x00000d66,0x00000000,0x00030047,0x00000d67, + 0x00000000,0x00030047,0x00000d69,0x00000000,0x00030047,0x00000d6b,0x00000000,0x00030047, + 0x00000d6d,0x00000000,0x00030047,0x00000d6e,0x00000000,0x00030047,0x00000d70,0x00000000, + 0x00030047,0x00000d71,0x00000000,0x00030047,0x00000d72,0x00000000,0x00030047,0x00000d73, + 0x00000000,0x00030047,0x00000d79,0x00000000,0x00030047,0x00000d7c,0x00000000,0x00030047, + 0x00000d7e,0x00000000,0x00030047,0x00000d7f,0x00000000,0x00030047,0x00000d81,0x00000000, + 0x00030047,0x00000d82,0x00000000,0x00030047,0x00000d85,0x00000000,0x00030047,0x00000d86, + 0x00000000,0x00030047,0x00000d87,0x00000000,0x00030047,0x00000d8a,0x00000000,0x00030047, + 0x00000d8c,0x00000000,0x00030047,0x00000d8d,0x00000000,0x00030047,0x00000d8e,0x00000000, + 0x00030047,0x00000d8f,0x00000000,0x00030047,0x00000d91,0x00000000,0x00030047,0x00000d92, + 0x00000000,0x00030047,0x00000d95,0x00000000,0x00030047,0x00000d96,0x00000000,0x00030047, + 0x00000d97,0x00000000,0x00030047,0x00000d9a,0x00000000,0x00030047,0x00000d9c,0x00000000, + 0x00030047,0x00000d9d,0x00000000,0x00030047,0x00000d9e,0x00000000,0x00030047,0x00000d9f, + 0x00000000,0x00030047,0x00000da1,0x00000000,0x00030047,0x00000da2,0x00000000,0x00030047, + 0x00000da5,0x00000000,0x00030047,0x00000da6,0x00000000,0x00030047,0x00000da7,0x00000000, + 0x00030047,0x00000daa,0x00000000,0x00030047,0x00000dac,0x00000000,0x00030047,0x00000dad, + 0x00000000,0x00030047,0x00000dae,0x00000000,0x00030047,0x00000daf,0x00000000,0x00030047, + 0x00000db1,0x00000000,0x00030047,0x00000db2,0x00000000,0x00030047,0x00000db5,0x00000000, + 0x00030047,0x00000db6,0x00000000,0x00030047,0x00000db7,0x00000000,0x00030047,0x00000dba, + 0x00000000,0x00030047,0x00000dbc,0x00000000,0x00030047,0x00000dbd,0x00000000,0x00030047, + 0x00000dbe,0x00000000,0x00030047,0x00000dbf,0x00000000,0x00030047,0x00000dc0,0x00000000, + 0x00030047,0x00000dc1,0x00000000,0x00030047,0x00000dc2,0x00000000,0x00030047,0x00000dc3, + 0x00000000,0x00030047,0x00000dc4,0x00000000,0x00030047,0x00000dc5,0x00000000,0x00030047, + 0x00000dc6,0x00000000,0x00030047,0x00000dc7,0x00000000,0x00030047,0x00000dc8,0x00000000, + 0x00030047,0x00000dc9,0x00000000,0x00030047,0x00000dca,0x00000000,0x00030047,0x00000dcb, + 0x00000000,0x00030047,0x00000dcc,0x00000000,0x00030047,0x00000dce,0x00000000,0x00030047, + 0x00000dd0,0x00000000,0x00030047,0x00000dd1,0x00000000,0x00030047,0x00000dd3,0x00000000, + 0x00030047,0x00000dd4,0x00000000,0x00030047,0x00000dd5,0x00000000,0x00030047,0x00000dd6, + 0x00000000,0x00030047,0x00000dd7,0x00000000,0x00030047,0x00000dda,0x00000000,0x00030047, + 0x00000ddc,0x00000000,0x00030047,0x00000ddd,0x00000000,0x00030047,0x00000de0,0x00000000, + 0x00030047,0x00000de1,0x00000000,0x00030047,0x00000de4,0x00000000,0x00030047,0x00000de6, + 0x00000000,0x00030047,0x00000de7,0x00000000,0x00030047,0x00000de8,0x00000000,0x00030047, + 0x00000de9,0x00000000,0x00030047,0x00000dea,0x00000000,0x00030047,0x00000deb,0x00000000, + 0x00030047,0x00000dec,0x00000000,0x00030047,0x00000ded,0x00000000,0x00030047,0x00000dee, + 0x00000000,0x00030047,0x00000def,0x00000000,0x00030047,0x00000df0,0x00000000,0x00030047, + 0x00000df1,0x00000000,0x00030047,0x00000df2,0x00000000,0x00030047,0x00000df4,0x00000000, + 0x00030047,0x00000df6,0x00000000,0x00030047,0x00000df7,0x00000000,0x00030047,0x00000df8, + 0x00000000,0x00030047,0x00000dfa,0x00000000,0x00030047,0x00000dfc,0x00000000,0x00030047, + 0x00000dfe,0x00000000,0x00030047,0x00000e00,0x00000000,0x00030047,0x00000e01,0x00000000, + 0x00030047,0x00000e02,0x00000000,0x00030047,0x00000e03,0x00000000,0x00030047,0x00000e04, + 0x00000000,0x00030047,0x00000e06,0x00000000,0x00030047,0x00000e08,0x00000000,0x00030047, + 0x00000e09,0x00000000,0x00030047,0x00000e0a,0x00000000,0x00030047,0x00000e0c,0x00000000, + 0x00030047,0x00000e0e,0x00000000,0x00030047,0x00000e10,0x00000000,0x00030047,0x00000e12, + 0x00000000,0x00030047,0x00000e13,0x00000000,0x00030047,0x00000e14,0x00000000,0x00030047, + 0x00000e16,0x00000000,0x00030047,0x00000e18,0x00000000,0x00030047,0x00000e1a,0x00000000, + 0x00030047,0x00000e1b,0x00000000,0x00030047,0x00000e1c,0x00000000,0x00030047,0x00000e1e, + 0x00000000,0x00030047,0x00000e20,0x00000000,0x00030047,0x00000e22,0x00000000,0x00030047, + 0x00000e23,0x00000000,0x00030047,0x00000e24,0x00000000,0x00030047,0x00000e26,0x00000000, + 0x00030047,0x00000e27,0x00000000,0x00030047,0x00000e2a,0x00000000,0x00030047,0x00000e2b, + 0x00000000,0x00030047,0x00000e2c,0x00000000,0x00030047,0x00000e2f,0x00000000,0x00030047, + 0x00000e31,0x00000000,0x00030047,0x00000e32,0x00000000,0x00030047,0x00000e33,0x00000000, + 0x00030047,0x00000e34,0x00000000,0x00030047,0x00000e36,0x00000000,0x00030047,0x00000e37, + 0x00000000,0x00030047,0x00000e3a,0x00000000,0x00030047,0x00000e3b,0x00000000,0x00030047, + 0x00000e3c,0x00000000,0x00030047,0x00000e3f,0x00000000,0x00030047,0x00000e41,0x00000000, + 0x00030047,0x00000e42,0x00000000,0x00030047,0x00000e43,0x00000000,0x00030047,0x00000e44, + 0x00000000,0x00030047,0x00000e46,0x00000000,0x00030047,0x00000e48,0x00000000,0x00030047, + 0x00000e4a,0x00000000,0x00030047,0x00000e4b,0x00000000,0x00030047,0x00000e4d,0x00000000, + 0x00030047,0x00000e4e,0x00000000,0x00030047,0x00000e4f,0x00000000,0x00030047,0x00000e51, + 0x00000000,0x00030047,0x00000e53,0x00000000,0x00030047,0x00000e55,0x00000000,0x00030047, + 0x00000e57,0x00000000,0x00030047,0x00000e58,0x00000000,0x00030047,0x00000e59,0x00000000, + 0x00030047,0x00000e5b,0x00000000,0x00030047,0x00000e5d,0x00000000,0x00030047,0x00000e5f, + 0x00000000,0x00030047,0x00000e61,0x00000000,0x00030047,0x00000e62,0x00000000,0x00030047, + 0x00000e63,0x00000000,0x00030047,0x00000e65,0x00000000,0x00030047,0x00000e67,0x00000000, + 0x00030047,0x00000e69,0x00000000,0x00030047,0x00000e6b,0x00000000,0x00030047,0x00000e6c, + 0x00000000,0x00030047,0x00000e6d,0x00000000,0x00030047,0x00000e6f,0x00000000,0x00030047, + 0x00000e71,0x00000000,0x00030047,0x00000e73,0x00000000,0x00030047,0x00000e75,0x00000000, + 0x00030047,0x00000e76,0x00000000,0x00030047,0x00000e77,0x00000000,0x00030047,0x00000e79, + 0x00000000,0x00030047,0x00000e7b,0x00000000,0x00030047,0x00000e7d,0x00000000,0x00030047, + 0x00000e7f,0x00000000,0x00030047,0x00000e80,0x00000000,0x00030047,0x00000e81,0x00000000, + 0x00030047,0x00000e83,0x00000000,0x00030047,0x00000e85,0x00000000,0x00030047,0x00000e87, + 0x00000000,0x00030047,0x00000e89,0x00000000,0x00030047,0x00000e8a,0x00000000,0x00030047, + 0x00000e8b,0x00000000,0x00030047,0x00000e8d,0x00000000,0x00030047,0x00000e8f,0x00000000, + 0x00030047,0x00000e91,0x00000000,0x00030047,0x00000e93,0x00000000,0x00030047,0x00000e94, + 0x00000000,0x00030047,0x00000e95,0x00000000,0x00030047,0x00000e97,0x00000000,0x00030047, + 0x00000e99,0x00000000,0x00030047,0x00000e9b,0x00000000,0x00030047,0x00000e9d,0x00000000, + 0x00030047,0x00000e9e,0x00000000,0x00030047,0x00000e9f,0x00000000,0x00030047,0x00000ea1, + 0x00000000,0x00030047,0x00000ea3,0x00000000,0x00030047,0x00000ea5,0x00000000,0x00030047, + 0x00000ea7,0x00000000,0x00030047,0x00000ea8,0x00000000,0x00030047,0x00000ea9,0x00000000, + 0x00030047,0x00000eab,0x00000000,0x00030047,0x00000ead,0x00000000,0x00030047,0x00000eaf, + 0x00000000,0x00030047,0x00000eb1,0x00000000,0x00030047,0x00000eb2,0x00000000,0x00030047, + 0x00000eb3,0x00000000,0x00030047,0x00000eb5,0x00000000,0x00030047,0x00000eb7,0x00000000, + 0x00030047,0x00000eb9,0x00000000,0x00030047,0x00000ebb,0x00000000,0x00030047,0x00000ebc, + 0x00000000,0x00030047,0x00000ebd,0x00000000,0x00030047,0x00000ebf,0x00000000,0x00030047, + 0x00000ec1,0x00000000,0x00030047,0x00000ec3,0x00000000,0x00030047,0x00000ec5,0x00000000, + 0x00030047,0x00000ec6,0x00000000,0x00030047,0x00000ec7,0x00000000,0x00030047,0x00000ec9, + 0x00000000,0x00030047,0x00000ecb,0x00000000,0x00030047,0x00000ecd,0x00000000,0x00030047, + 0x00000ecf,0x00000000,0x00030047,0x00000ed0,0x00000000,0x00030047,0x00000ed1,0x00000000, + 0x00030047,0x00000ed3,0x00000000,0x00030047,0x00000eda,0x00000000,0x00030047,0x00000edc, + 0x00000000,0x00030047,0x00000edd,0x00000000,0x00030047,0x00000ede,0x00000000,0x00030047, + 0x00000ee0,0x00000000,0x00030047,0x00000ee2,0x00000000,0x00030047,0x00000ee4,0x00000000, + 0x00030047,0x00000ee6,0x00000000,0x00030047,0x00000ee8,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00040020, + 0x00000007,0x00000007,0x00000006,0x00030016,0x00000008,0x00000020,0x00040015,0x0000000d, + 0x00000020,0x00000001,0x00040020,0x0000000e,0x00000007,0x0000000d,0x00040017,0x00000013, + 0x00000008,0x00000004,0x00040020,0x00000014,0x00000007,0x00000013,0x00040020,0x00000019, + 0x00000007,0x00000008,0x00040017,0x00000022,0x00000008,0x00000002,0x00040017,0x0000002c, + 0x00000008,0x00000003,0x00040020,0x0000003e,0x00000007,0x0000002c,0x00040020,0x0000004c, + 0x00000007,0x00000022,0x00020014,0x0000006a,0x00040017,0x00000081,0x00000006,0x00000002, + 0x00040020,0x00000082,0x00000007,0x00000081,0x0004002b,0x00000006,0x000000de,0x00000000, + 0x0004002b,0x00000006,0x000000e1,0x00000001,0x0004002b,0x00000006,0x000000f4,0x00000002, + 0x0004002b,0x00000006,0x0000010b,0x00000003,0x0004002b,0x00000008,0x0000012d,0x00000000, + 0x0004002b,0x00000008,0x00000132,0x3f800000,0x0004002b,0x00000008,0x0000016b,0x3d897143, + 0x0004002b,0x00000008,0x0000016f,0x3bbf4590,0x0004002b,0x00000008,0x00000176,0x4253ee82, + 0x00030030,0x0000006a,0x00000181,0x0004002b,0x00000008,0x00000197,0xbfc00000,0x00090019, + 0x000001ad,0x00000008,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x000001ae,0x00000000,0x000001ad,0x0004003b,0x000001ae,0x000001af,0x00000000, + 0x0002001a,0x000001b1,0x00040020,0x000001b2,0x00000000,0x000001b1,0x0004003b,0x000001b2, + 0x000001b3,0x00000000,0x0003001b,0x000001b5,0x000001ad,0x0004002b,0x00000008,0x000001bf, + 0x447a0000,0x0004002b,0x00000008,0x000001c7,0x3e800000,0x0004002b,0x00000008,0x000001cd, + 0xc0000000,0x0004002b,0x00000008,0x000001d3,0x3f19319f,0x0004002b,0x00000008,0x000001d8, + 0x3e55e621,0x0004002b,0x00000008,0x000001d9,0x3f206c99,0x0004002b,0x00000008,0x000001da, + 0x3f85afd5,0x0004002b,0x00000008,0x000001db,0x3fbb295d,0x0004002b,0x00000008,0x00000218, + 0x40a311dd,0x0004002b,0x00000008,0x0000021a,0xc02311dd,0x0004002b,0x00000008,0x00000235, + 0x40400000,0x0004002b,0x00000008,0x0000025b,0x388205ff,0x0004002b,0x00000006,0x00000263, + 0x00000005,0x0004002b,0x00000006,0x0000026b,0x00000400,0x0004002b,0x00000006,0x00000270, + 0x0000001f,0x0004002b,0x00000006,0x00000273,0x00000080,0x0004002b,0x00000006,0x00000279, + 0x00000010,0x0004002b,0x00000006,0x00000281,0x00000004,0x0004002b,0x00000006,0x0000028d, + 0x0007ffff,0x0004002b,0x00000006,0x0000028f,0x00040000,0x0004002b,0x00000008,0x00000294, + 0x3a800000,0x0004002b,0x00000008,0x00000299,0x44800000,0x0004002b,0x00000008,0x0000029b, + 0x3f000000,0x0004002b,0x00000008,0x000002a3,0x3e99999a,0x0004002b,0x00000008,0x000002a4, + 0x3f170a3d,0x0004002b,0x00000008,0x000002a5,0x3de147ae,0x0004002b,0x00000008,0x00000324, + 0x40000000,0x00040017,0x00000330,0x0000006a,0x00000003,0x0004002b,0x0000000d,0x000003ad, + 0x00000000,0x0004002b,0x0000000d,0x000003b4,0x00000003,0x0004002b,0x00000008,0x000003ca, + 0x41800000,0x0004002b,0x00000008,0x000003cf,0x41400000,0x0004002b,0x0000000d,0x000003e0, + 0x00000001,0x00030030,0x0000006a,0x000003fb,0x0004002b,0x00000008,0x00000465,0xbf800000, + 0x0004002b,0x00000008,0x00000483,0x3f7f8000,0x0004002b,0x00000008,0x00000488,0x3b000000, + 0x0004003b,0x000001ae,0x00000492,0x00000000,0x0004003b,0x000001b2,0x00000494,0x00000000, + 0x0004003b,0x000001ae,0x000004b3,0x00000000,0x0004003b,0x000001b2,0x000004b5,0x00000000, + 0x00030030,0x0000006a,0x000004d4,0x0003001d,0x00000512,0x00000006,0x0003001e,0x00000513, + 0x00000512,0x00040020,0x00000514,0x00000002,0x00000513,0x0004003b,0x00000514,0x00000515, + 0x00000002,0x00040020,0x00000517,0x00000002,0x00000006,0x0007001e,0x0000051a,0x00000006, + 0x00000008,0x00000008,0x00000008,0x00000008,0x00040020,0x0000051b,0x00000002,0x0000051a, + 0x0004003b,0x0000051b,0x0000051c,0x00000002,0x0004002b,0x00000006,0x0000052e,0x00080000, + 0x00040017,0x000005b5,0x0000000d,0x00000002,0x00040020,0x000005b6,0x00000007,0x000005b5, + 0x00040020,0x000005b8,0x00000001,0x00000013,0x0004003b,0x000005b8,0x000005b9,0x00000001, + 0x0004003b,0x000005b8,0x000005bf,0x00000001,0x00090019,0x000005c5,0x00000008,0x00000006, + 0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020,0x000005c6,0x00000000, + 0x000005c5,0x0004003b,0x000005c6,0x000005c7,0x00000000,0x0005002c,0x000005b5,0x000005c9, + 0x000003ad,0x000003ad,0x0004003b,0x000005b8,0x000005cc,0x00000001,0x00040020,0x000005d1, + 0x00000001,0x00000022,0x0004003b,0x000005d1,0x000005d2,0x00000001,0x00040020,0x000005da, + 0x00000002,0x00000008,0x00040020,0x000005e3,0x00000001,0x00000081,0x0004003b,0x000005e3, + 0x000005e4,0x00000001,0x00040020,0x000005e5,0x00000001,0x00000006,0x00030030,0x0000006a, + 0x000005f3,0x0004003b,0x000005b8,0x000005f7,0x00000001,0x00030030,0x0000006a,0x00000600, + 0x0004003b,0x000005d1,0x00000603,0x00000001,0x00040020,0x00000604,0x00000001,0x00000008, + 0x0004003b,0x000005c6,0x0000060c,0x00000000,0x00040020,0x00000650,0x00000007,0x0000006a, + 0x0004003b,0x00000604,0x00000660,0x00000001,0x00090019,0x00000682,0x00000008,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000002,0x0000000b,0x00040020,0x00000683,0x00000000, + 0x00000682,0x0004003b,0x00000683,0x00000684,0x00000000,0x0004002b,0x00000006,0x0000068b, + 0x00000d48,0x00040020,0x000006b2,0x00000003,0x00000013,0x0004003b,0x000006b2,0x000006b3, + 0x00000003,0x0004003b,0x000006b2,0x000006b6,0x00000003,0x0004003b,0x00000604,0x000006bf, + 0x00000001,0x0007002c,0x00000013,0x000006c0,0x0000021a,0x0000021a,0x0000021a,0x0000021a, + 0x0006002c,0x0000002c,0x000006c1,0x00000132,0x00000132,0x00000132,0x0006002c,0x0000002c, + 0x000006c2,0x0000029b,0x0000029b,0x0000029b,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000014,0x00000edd,0x00000007,0x0004003b, + 0x00000014,0x00000ede,0x00000007,0x0004003b,0x00000014,0x00000ed0,0x00000007,0x0004003b, + 0x00000014,0x00000ed1,0x00000007,0x0004003b,0x0000003e,0x00000ec6,0x00000007,0x0004003b, + 0x0000003e,0x00000ec7,0x00000007,0x0004003b,0x0000003e,0x00000ebc,0x00000007,0x0004003b, + 0x0000003e,0x00000ebd,0x00000007,0x0004003b,0x0000003e,0x00000eb2,0x00000007,0x0004003b, + 0x0000003e,0x00000eb3,0x00000007,0x0004003b,0x0000003e,0x00000ea8,0x00000007,0x0004003b, + 0x0000003e,0x00000ea9,0x00000007,0x0004003b,0x0000003e,0x00000e9e,0x00000007,0x0004003b, + 0x0000003e,0x00000e9f,0x00000007,0x0004003b,0x0000003e,0x00000e94,0x00000007,0x0004003b, + 0x0000003e,0x00000e95,0x00000007,0x0004003b,0x0000003e,0x00000e8a,0x00000007,0x0004003b, + 0x0000003e,0x00000e8b,0x00000007,0x0004003b,0x0000003e,0x00000e80,0x00000007,0x0004003b, + 0x0000003e,0x00000e81,0x00000007,0x0004003b,0x0000003e,0x00000e76,0x00000007,0x0004003b, + 0x0000003e,0x00000e77,0x00000007,0x0004003b,0x0000003e,0x00000e6c,0x00000007,0x0004003b, + 0x0000003e,0x00000e6d,0x00000007,0x0004003b,0x0000003e,0x00000e62,0x00000007,0x0004003b, + 0x0000003e,0x00000e63,0x00000007,0x0004003b,0x0000003e,0x00000e58,0x00000007,0x0004003b, + 0x0000003e,0x00000e59,0x00000007,0x0004003b,0x0000003e,0x00000e4e,0x00000007,0x0004003b, + 0x0000003e,0x00000e4f,0x00000007,0x0004003b,0x00000019,0x00000e4b,0x00000007,0x0004003b, + 0x0000004c,0x00000e43,0x00000007,0x0004003b,0x0000004c,0x00000e44,0x00000007,0x0004003b, + 0x00000019,0x00000e3c,0x00000007,0x0004003b,0x0000004c,0x00000e33,0x00000007,0x0004003b, + 0x00000019,0x00000e34,0x00000007,0x0004003b,0x00000019,0x00000e2c,0x00000007,0x0004003b, + 0x0000004c,0x00000e23,0x00000007,0x0004003b,0x00000019,0x00000e24,0x00000007,0x0004003b, + 0x0000004c,0x00000e1b,0x00000007,0x0004003b,0x0000004c,0x00000e1c,0x00000007,0x0004003b, + 0x0000004c,0x00000e13,0x00000007,0x0004003b,0x0000004c,0x00000e14,0x00000007,0x0004003b, + 0x0000003e,0x00000e09,0x00000007,0x0004003b,0x0000003e,0x00000e0a,0x00000007,0x0004003b, + 0x00000019,0x00000e01,0x00000007,0x0004003b,0x00000019,0x00000e02,0x00000007,0x0004003b, + 0x00000019,0x00000e03,0x00000007,0x0004003b,0x00000019,0x00000e04,0x00000007,0x0004003b, + 0x0000003e,0x00000df7,0x00000007,0x0004003b,0x0000003e,0x00000df8,0x00000007,0x0004003b, + 0x00000019,0x00000def,0x00000007,0x0004003b,0x00000019,0x00000df0,0x00000007,0x0004003b, + 0x00000019,0x00000df1,0x00000007,0x0004003b,0x00000019,0x00000df2,0x00000007,0x0004003b, + 0x00000019,0x00000dbe,0x00000007,0x0004003b,0x0000003e,0x00000dbf,0x00000007,0x0004003b, + 0x0000003e,0x00000dc0,0x00000007,0x0004003b,0x0000003e,0x00000dc1,0x00000007,0x0004003b, + 0x0000004c,0x00000dc2,0x00000007,0x0004003b,0x00000019,0x00000dc3,0x00000007,0x0004003b, + 0x00000019,0x00000dc4,0x00000007,0x0004003b,0x00000019,0x00000dc5,0x00000007,0x0004003b, + 0x0000003e,0x00000dc6,0x00000007,0x0004003b,0x0000003e,0x00000dc7,0x00000007,0x0004003b, + 0x00000019,0x00000dc8,0x00000007,0x0004003b,0x00000019,0x00000dc9,0x00000007,0x0004003b, + 0x00000019,0x00000dca,0x00000007,0x0004003b,0x00000019,0x00000dcb,0x00000007,0x0004003b, + 0x0000003e,0x00000dcc,0x00000007,0x0004003b,0x00000019,0x00000db7,0x00000007,0x0004003b, + 0x0000004c,0x00000dae,0x00000007,0x0004003b,0x00000019,0x00000daf,0x00000007,0x0004003b, + 0x00000019,0x00000da7,0x00000007,0x0004003b,0x0000004c,0x00000d9e,0x00000007,0x0004003b, + 0x00000019,0x00000d9f,0x00000007,0x0004003b,0x00000019,0x00000d97,0x00000007,0x0004003b, + 0x0000004c,0x00000d8e,0x00000007,0x0004003b,0x00000019,0x00000d8f,0x00000007,0x0004003b, + 0x00000019,0x00000d87,0x00000007,0x0004003b,0x0000004c,0x00000d7e,0x00000007,0x0004003b, + 0x00000019,0x00000d7f,0x00000007,0x0004003b,0x00000019,0x00000d5e,0x00000007,0x0004003b, + 0x0000003e,0x00000d5f,0x00000007,0x0004003b,0x0000003e,0x00000d60,0x00000007,0x0004003b, + 0x0000003e,0x00000d61,0x00000007,0x0004003b,0x00000019,0x00000d62,0x00000007,0x0004003b, + 0x0000003e,0x00000d63,0x00000007,0x0004003b,0x00000019,0x00000d64,0x00000007,0x0004003b, + 0x0000003e,0x00000d65,0x00000007,0x0004003b,0x0000003e,0x00000d66,0x00000007,0x0004003b, + 0x0000003e,0x00000d67,0x00000007,0x0004003b,0x0000003e,0x00000d54,0x00000007,0x0004003b, + 0x0000003e,0x00000d55,0x00000007,0x0004003b,0x0000003e,0x00000d4a,0x00000007,0x0004003b, + 0x0000003e,0x00000d4b,0x00000007,0x0004003b,0x00000019,0x00000d47,0x00000007,0x0004003b, + 0x0000004c,0x00000d3f,0x00000007,0x0004003b,0x0000004c,0x00000d40,0x00000007,0x0004003b, + 0x00000019,0x00000d38,0x00000007,0x0004003b,0x0000004c,0x00000d2f,0x00000007,0x0004003b, + 0x00000019,0x00000d30,0x00000007,0x0004003b,0x00000019,0x00000d28,0x00000007,0x0004003b, + 0x0000004c,0x00000d1f,0x00000007,0x0004003b,0x00000019,0x00000d20,0x00000007,0x0004003b, + 0x0000004c,0x00000d17,0x00000007,0x0004003b,0x0000004c,0x00000d18,0x00000007,0x0004003b, + 0x0000004c,0x00000d0f,0x00000007,0x0004003b,0x0000004c,0x00000d10,0x00000007,0x0004003b, + 0x0000003e,0x00000d05,0x00000007,0x0004003b,0x0000003e,0x00000d06,0x00000007,0x0004003b, + 0x00000019,0x00000cfd,0x00000007,0x0004003b,0x00000019,0x00000cfe,0x00000007,0x0004003b, + 0x00000019,0x00000cff,0x00000007,0x0004003b,0x00000019,0x00000d00,0x00000007,0x0004003b, + 0x0000003e,0x00000cf3,0x00000007,0x0004003b,0x0000003e,0x00000cf4,0x00000007,0x0004003b, + 0x00000019,0x00000ceb,0x00000007,0x0004003b,0x00000019,0x00000cec,0x00000007,0x0004003b, + 0x00000019,0x00000ced,0x00000007,0x0004003b,0x00000019,0x00000cee,0x00000007,0x0004003b, + 0x00000019,0x00000cba,0x00000007,0x0004003b,0x0000003e,0x00000cbb,0x00000007,0x0004003b, + 0x0000003e,0x00000cbc,0x00000007,0x0004003b,0x0000003e,0x00000cbd,0x00000007,0x0004003b, + 0x0000004c,0x00000cbe,0x00000007,0x0004003b,0x00000019,0x00000cbf,0x00000007,0x0004003b, + 0x00000019,0x00000cc0,0x00000007,0x0004003b,0x00000019,0x00000cc1,0x00000007,0x0004003b, + 0x0000003e,0x00000cc2,0x00000007,0x0004003b,0x0000003e,0x00000cc3,0x00000007,0x0004003b, + 0x00000019,0x00000cc4,0x00000007,0x0004003b,0x00000019,0x00000cc5,0x00000007,0x0004003b, + 0x00000019,0x00000cc6,0x00000007,0x0004003b,0x00000019,0x00000cc7,0x00000007,0x0004003b, + 0x0000003e,0x00000cc8,0x00000007,0x0004003b,0x00000019,0x00000cb3,0x00000007,0x0004003b, + 0x0000004c,0x00000caa,0x00000007,0x0004003b,0x00000019,0x00000cab,0x00000007,0x0004003b, + 0x00000019,0x00000ca3,0x00000007,0x0004003b,0x0000004c,0x00000c9a,0x00000007,0x0004003b, + 0x00000019,0x00000c9b,0x00000007,0x0004003b,0x00000019,0x00000c93,0x00000007,0x0004003b, + 0x0000004c,0x00000c8a,0x00000007,0x0004003b,0x00000019,0x00000c8b,0x00000007,0x0004003b, + 0x00000019,0x00000c83,0x00000007,0x0004003b,0x0000004c,0x00000c7a,0x00000007,0x0004003b, + 0x00000019,0x00000c7b,0x00000007,0x0004003b,0x00000019,0x00000c5a,0x00000007,0x0004003b, + 0x0000003e,0x00000c5b,0x00000007,0x0004003b,0x0000003e,0x00000c5c,0x00000007,0x0004003b, + 0x0000003e,0x00000c5d,0x00000007,0x0004003b,0x00000019,0x00000c5e,0x00000007,0x0004003b, + 0x0000003e,0x00000c5f,0x00000007,0x0004003b,0x00000019,0x00000c60,0x00000007,0x0004003b, + 0x0000003e,0x00000c61,0x00000007,0x0004003b,0x0000003e,0x00000c62,0x00000007,0x0004003b, + 0x0000003e,0x00000c63,0x00000007,0x0004003b,0x0000003e,0x00000c50,0x00000007,0x0004003b, + 0x0000003e,0x00000c51,0x00000007,0x0004003b,0x0000003e,0x00000c46,0x00000007,0x0004003b, + 0x0000003e,0x00000c47,0x00000007,0x0004003b,0x00000019,0x00000c43,0x00000007,0x0004003b, + 0x0000004c,0x00000c3b,0x00000007,0x0004003b,0x0000004c,0x00000c3c,0x00000007,0x0004003b, + 0x00000019,0x00000c34,0x00000007,0x0004003b,0x0000004c,0x00000c2b,0x00000007,0x0004003b, + 0x00000019,0x00000c2c,0x00000007,0x0004003b,0x00000019,0x00000c24,0x00000007,0x0004003b, + 0x0000004c,0x00000c1b,0x00000007,0x0004003b,0x00000019,0x00000c1c,0x00000007,0x0004003b, + 0x0000004c,0x00000c13,0x00000007,0x0004003b,0x0000004c,0x00000c14,0x00000007,0x0004003b, + 0x0000004c,0x00000c0b,0x00000007,0x0004003b,0x0000004c,0x00000c0c,0x00000007,0x0004003b, + 0x0000003e,0x00000c01,0x00000007,0x0004003b,0x0000003e,0x00000c02,0x00000007,0x0004003b, + 0x00000019,0x00000bf9,0x00000007,0x0004003b,0x00000019,0x00000bfa,0x00000007,0x0004003b, + 0x00000019,0x00000bfb,0x00000007,0x0004003b,0x00000019,0x00000bfc,0x00000007,0x0004003b, + 0x0000003e,0x00000bef,0x00000007,0x0004003b,0x0000003e,0x00000bf0,0x00000007,0x0004003b, + 0x00000019,0x00000be7,0x00000007,0x0004003b,0x00000019,0x00000be8,0x00000007,0x0004003b, + 0x00000019,0x00000be9,0x00000007,0x0004003b,0x00000019,0x00000bea,0x00000007,0x0004003b, + 0x00000019,0x00000bb6,0x00000007,0x0004003b,0x0000003e,0x00000bb7,0x00000007,0x0004003b, + 0x0000003e,0x00000bb8,0x00000007,0x0004003b,0x0000003e,0x00000bb9,0x00000007,0x0004003b, + 0x0000004c,0x00000bba,0x00000007,0x0004003b,0x00000019,0x00000bbb,0x00000007,0x0004003b, + 0x00000019,0x00000bbc,0x00000007,0x0004003b,0x00000019,0x00000bbd,0x00000007,0x0004003b, + 0x0000003e,0x00000bbe,0x00000007,0x0004003b,0x0000003e,0x00000bbf,0x00000007,0x0004003b, + 0x00000019,0x00000bc0,0x00000007,0x0004003b,0x00000019,0x00000bc1,0x00000007,0x0004003b, + 0x00000019,0x00000bc2,0x00000007,0x0004003b,0x00000019,0x00000bc3,0x00000007,0x0004003b, + 0x0000003e,0x00000bc4,0x00000007,0x0004003b,0x0000003e,0x00000bac,0x00000007,0x0004003b, + 0x0000003e,0x00000bad,0x00000007,0x0004003b,0x0000003e,0x00000ba2,0x00000007,0x0004003b, + 0x0000003e,0x00000ba3,0x00000007,0x0004003b,0x00000019,0x00000b9f,0x00000007,0x0004003b, + 0x0000004c,0x00000b97,0x00000007,0x0004003b,0x0000004c,0x00000b98,0x00000007,0x0004003b, + 0x00000019,0x00000b90,0x00000007,0x0004003b,0x0000004c,0x00000b87,0x00000007,0x0004003b, + 0x00000019,0x00000b88,0x00000007,0x0004003b,0x00000019,0x00000b80,0x00000007,0x0004003b, + 0x0000004c,0x00000b77,0x00000007,0x0004003b,0x00000019,0x00000b78,0x00000007,0x0004003b, + 0x0000004c,0x00000b6f,0x00000007,0x0004003b,0x0000004c,0x00000b70,0x00000007,0x0004003b, + 0x0000004c,0x00000b67,0x00000007,0x0004003b,0x0000004c,0x00000b68,0x00000007,0x0004003b, + 0x0000003e,0x00000b5d,0x00000007,0x0004003b,0x0000003e,0x00000b5e,0x00000007,0x0004003b, + 0x00000019,0x00000b55,0x00000007,0x0004003b,0x00000019,0x00000b56,0x00000007,0x0004003b, + 0x00000019,0x00000b57,0x00000007,0x0004003b,0x00000019,0x00000b58,0x00000007,0x0004003b, + 0x0000003e,0x00000b4b,0x00000007,0x0004003b,0x0000003e,0x00000b4c,0x00000007,0x0004003b, + 0x00000019,0x00000b43,0x00000007,0x0004003b,0x00000019,0x00000b44,0x00000007,0x0004003b, + 0x00000019,0x00000b45,0x00000007,0x0004003b,0x00000019,0x00000b46,0x00000007,0x0004003b, + 0x00000019,0x00000b12,0x00000007,0x0004003b,0x0000003e,0x00000b13,0x00000007,0x0004003b, + 0x0000003e,0x00000b14,0x00000007,0x0004003b,0x0000003e,0x00000b15,0x00000007,0x0004003b, + 0x0000004c,0x00000b16,0x00000007,0x0004003b,0x00000019,0x00000b17,0x00000007,0x0004003b, + 0x00000019,0x00000b18,0x00000007,0x0004003b,0x00000019,0x00000b19,0x00000007,0x0004003b, + 0x0000003e,0x00000b1a,0x00000007,0x0004003b,0x0000003e,0x00000b1b,0x00000007,0x0004003b, + 0x00000019,0x00000b1c,0x00000007,0x0004003b,0x00000019,0x00000b1d,0x00000007,0x0004003b, + 0x00000019,0x00000b1e,0x00000007,0x0004003b,0x00000019,0x00000b1f,0x00000007,0x0004003b, + 0x0000003e,0x00000b20,0x00000007,0x0004003b,0x0000003e,0x00000b08,0x00000007,0x0004003b, + 0x0000003e,0x00000b09,0x00000007,0x0004003b,0x0000003e,0x00000afe,0x00000007,0x0004003b, + 0x0000003e,0x00000aff,0x00000007,0x0004003b,0x00000019,0x00000aee,0x00000007,0x0004003b, + 0x0000003e,0x00000aef,0x00000007,0x0004003b,0x0000003e,0x000009cd,0x00000007,0x0004003b, + 0x00000014,0x000009ce,0x00000007,0x0004003b,0x0000003e,0x000009cf,0x00000007,0x0004003b, + 0x0000003e,0x000009d0,0x00000007,0x0004003b,0x00000019,0x000009d1,0x00000007,0x0004003b, + 0x00000019,0x000009d2,0x00000007,0x0004003b,0x0000003e,0x000009d3,0x00000007,0x0004003b, + 0x00000019,0x000009d4,0x00000007,0x0004003b,0x00000019,0x000009d5,0x00000007,0x0004003b, + 0x00000019,0x000009d6,0x00000007,0x0004003b,0x00000019,0x000009d7,0x00000007,0x0004003b, + 0x00000019,0x000009d8,0x00000007,0x0004003b,0x00000019,0x000009d9,0x00000007,0x0004003b, + 0x00000019,0x000009da,0x00000007,0x0004003b,0x0000003e,0x000009db,0x00000007,0x0004003b, + 0x00000019,0x000009dc,0x00000007,0x0004003b,0x00000019,0x000009dd,0x00000007,0x0004003b, + 0x0000003e,0x000009de,0x00000007,0x0004003b,0x00000019,0x000009df,0x00000007,0x0004003b, + 0x0000000e,0x000009e0,0x00000007,0x0004003b,0x00000019,0x000009e1,0x00000007,0x0004003b, + 0x00000019,0x000009e2,0x00000007,0x0004003b,0x0000003e,0x000009e3,0x00000007,0x0004003b, + 0x0000003e,0x000009e4,0x00000007,0x0004003b,0x0000003e,0x000009e5,0x00000007,0x0004003b, + 0x00000019,0x000009e6,0x00000007,0x0004003b,0x00000019,0x000009e7,0x00000007,0x0004003b, + 0x0000003e,0x000009e8,0x00000007,0x0004003b,0x0000003e,0x000009e9,0x00000007,0x0004003b, + 0x0000003e,0x000009ea,0x00000007,0x0004003b,0x00000019,0x000009eb,0x00000007,0x0004003b, + 0x00000019,0x000009ec,0x00000007,0x0004003b,0x0000003e,0x000009ed,0x00000007,0x0004003b, + 0x0000003e,0x000009ee,0x00000007,0x0004003b,0x00000019,0x000009ef,0x00000007,0x0004003b, + 0x00000019,0x000009f0,0x00000007,0x0004003b,0x0000003e,0x000009f1,0x00000007,0x0004003b, + 0x0000003e,0x000009f2,0x00000007,0x0004003b,0x0000003e,0x000009f3,0x00000007,0x0004003b, + 0x0000003e,0x000009bc,0x00000007,0x0004003b,0x0000003e,0x000009bd,0x00000007,0x0004003b, + 0x00000014,0x000009be,0x00000007,0x0004003b,0x00000007,0x000009bf,0x00000007,0x0004003b, + 0x00000019,0x000009c0,0x00000007,0x0004003b,0x0000003e,0x000009c1,0x00000007,0x0004003b, + 0x00000007,0x000009b8,0x00000007,0x0004003b,0x00000019,0x000009a4,0x00000007,0x0004003b, + 0x00000019,0x000009a5,0x00000007,0x0004003b,0x00000019,0x000009a6,0x00000007,0x0004003b, + 0x00000019,0x00000996,0x00000007,0x0004003b,0x0000004c,0x00000997,0x00000007,0x0004003b, + 0x00000019,0x00000998,0x00000007,0x0004003b,0x00000019,0x00000999,0x00000007,0x0004003b, + 0x00000019,0x0000099a,0x00000007,0x0004003b,0x00000019,0x0000098b,0x00000007,0x0004003b, + 0x00000019,0x00000985,0x00000007,0x0004003b,0x00000019,0x00000986,0x00000007,0x0004003b, + 0x00000007,0x0000097d,0x00000007,0x0004003b,0x00000007,0x0000097e,0x00000007,0x0004003b, + 0x00000007,0x00000944,0x00000007,0x0004003b,0x00000019,0x00000945,0x00000007,0x0004003b, + 0x00000019,0x00000946,0x00000007,0x0004003b,0x00000019,0x00000947,0x00000007,0x0004003b, + 0x00000007,0x00000948,0x00000007,0x0004003b,0x00000019,0x00000949,0x00000007,0x0004003b, + 0x00000019,0x0000094a,0x00000007,0x0004003b,0x00000019,0x0000094b,0x00000007,0x0004003b, + 0x00000019,0x0000094c,0x00000007,0x0004003b,0x00000019,0x00000939,0x00000007,0x0004003b, + 0x00000019,0x00000933,0x00000007,0x0004003b,0x00000019,0x00000934,0x00000007,0x0004003b, + 0x0000000e,0x0000092a,0x00000007,0x0004003b,0x00000019,0x0000092b,0x00000007,0x0004003b, + 0x00000019,0x0000091f,0x00000007,0x0004003b,0x00000019,0x00000919,0x00000007,0x0004003b, + 0x00000019,0x0000091a,0x00000007,0x0004003b,0x00000007,0x00000911,0x00000007,0x0004003b, + 0x00000007,0x00000912,0x00000007,0x0004003b,0x00000019,0x000008ab,0x00000007,0x0004003b, + 0x00000007,0x000008ac,0x00000007,0x0004003b,0x00000019,0x000008ad,0x00000007,0x0004003b, + 0x00000007,0x000008ae,0x00000007,0x0004003b,0x00000007,0x000008af,0x00000007,0x0004003b, + 0x00000007,0x000008b0,0x00000007,0x0004003b,0x00000019,0x000008b1,0x00000007,0x0004003b, + 0x00000007,0x000008b2,0x00000007,0x0004003b,0x00000019,0x000008b3,0x00000007,0x0004003b, + 0x00000019,0x000008b4,0x00000007,0x0004003b,0x00000019,0x000008b5,0x00000007,0x0004003b, + 0x00000019,0x000008b6,0x00000007,0x0004003b,0x00000007,0x000008b7,0x00000007,0x0004003b, + 0x00000019,0x000008b8,0x00000007,0x0004003b,0x00000007,0x000008b9,0x00000007,0x0004003b, + 0x00000019,0x000008ba,0x00000007,0x0004003b,0x00000019,0x000008bb,0x00000007,0x0004003b, + 0x00000019,0x000008bc,0x00000007,0x0004003b,0x00000019,0x000008bd,0x00000007,0x0004003b, + 0x00000650,0x000008a6,0x00000007,0x0004003b,0x0000004c,0x00000897,0x00000007,0x0004003b, + 0x00000019,0x00000898,0x00000007,0x0004003b,0x00000019,0x00000899,0x00000007,0x0004003b, + 0x00000014,0x00000892,0x00000007,0x0004003b,0x00000014,0x00000893,0x00000007,0x0004003b, + 0x00000007,0x0000086c,0x00000007,0x0004003b,0x00000007,0x0000086d,0x00000007,0x0004003b, + 0x00000019,0x0000084c,0x00000007,0x0004003b,0x00000019,0x0000084d,0x00000007,0x0004003b, + 0x00000019,0x0000084e,0x00000007,0x0004003b,0x00000019,0x0000084f,0x00000007,0x0004003b, + 0x00000019,0x00000850,0x00000007,0x0004003b,0x00000650,0x00000847,0x00000007,0x0004003b, + 0x00000019,0x0000082e,0x00000007,0x0004003b,0x00000014,0x0000082f,0x00000007,0x0004003b, + 0x00000014,0x00000830,0x00000007,0x0004003b,0x00000019,0x00000831,0x00000007,0x0004003b, + 0x00000019,0x00000832,0x00000007,0x0004003b,0x00000014,0x00000821,0x00000007,0x0004003b, + 0x00000014,0x00000822,0x00000007,0x0004003b,0x00000014,0x00000815,0x00000007,0x0004003b, + 0x00000014,0x00000816,0x00000007,0x0004003b,0x00000019,0x00000794,0x00000007,0x0004003b, + 0x00000019,0x00000795,0x00000007,0x0004003b,0x00000019,0x00000796,0x00000007,0x0004003b, + 0x00000019,0x00000797,0x00000007,0x0004003b,0x00000019,0x00000798,0x00000007,0x0004003b, + 0x00000019,0x00000799,0x00000007,0x0004003b,0x00000019,0x0000079a,0x00000007,0x0004003b, + 0x00000014,0x0000079b,0x00000007,0x0004003b,0x00000019,0x0000079c,0x00000007,0x0004003b, + 0x00000019,0x0000079d,0x00000007,0x0004003b,0x00000019,0x0000079e,0x00000007,0x0004003b, + 0x00000019,0x0000079f,0x00000007,0x0004003b,0x00000014,0x000007a0,0x00000007,0x0004003b, + 0x00000014,0x000007a1,0x00000007,0x0004003b,0x00000019,0x000007a2,0x00000007,0x0004003b, + 0x00000019,0x000007a3,0x00000007,0x0004003b,0x00000019,0x000007a4,0x00000007,0x0004003b, + 0x00000019,0x000007a5,0x00000007,0x0004003b,0x00000014,0x000007a6,0x00000007,0x0004003b, + 0x00000014,0x000007a7,0x00000007,0x0004003b,0x00000019,0x000007a8,0x00000007,0x0004003b, + 0x00000019,0x000007a9,0x00000007,0x0004003b,0x00000650,0x0000078f,0x00000007,0x0004003b, + 0x00000019,0x00000779,0x00000007,0x0004003b,0x00000014,0x0000077a,0x00000007,0x0004003b, + 0x00000014,0x0000077b,0x00000007,0x0004003b,0x00000019,0x0000077c,0x00000007,0x0004003b, + 0x00000019,0x0000077d,0x00000007,0x0004003b,0x00000650,0x00000773,0x00000007,0x0004003b, + 0x00000019,0x00000761,0x00000007,0x0004003b,0x00000014,0x00000762,0x00000007,0x0004003b, + 0x00000014,0x00000763,0x00000007,0x0004003b,0x00000014,0x00000764,0x00000007,0x0004003b, + 0x00000019,0x00000765,0x00000007,0x0004003b,0x00000014,0x0000075b,0x00000007,0x0004003b, + 0x00000014,0x0000075c,0x00000007,0x0004003b,0x00000014,0x0000074e,0x00000007,0x0004003b, + 0x00000014,0x0000074f,0x00000007,0x0004003b,0x00000019,0x0000073e,0x00000007,0x0004003b, + 0x0000003e,0x0000073f,0x00000007,0x0004003b,0x00000014,0x000006d3,0x00000007,0x0004003b, + 0x00000014,0x000006d4,0x00000007,0x0004003b,0x00000019,0x000006d5,0x00000007,0x0004003b, + 0x00000019,0x000006d6,0x00000007,0x0004003b,0x00000019,0x000006d7,0x00000007,0x0004003b, + 0x00000019,0x000006d8,0x00000007,0x0004003b,0x00000019,0x000006d9,0x00000007,0x0004003b, + 0x00000019,0x000006da,0x00000007,0x0004003b,0x00000019,0x000006db,0x00000007,0x0004003b, + 0x00000019,0x000006dc,0x00000007,0x0004003b,0x00000014,0x000006dd,0x00000007,0x0004003b, + 0x0000003e,0x000006de,0x00000007,0x0004003b,0x00000019,0x000006df,0x00000007,0x0004003b, + 0x00000014,0x000006e0,0x00000007,0x0004003b,0x000005b6,0x000005b7,0x00000007,0x0004003b, + 0x00000014,0x000005be,0x00000007,0x0004003b,0x00000014,0x000005c0,0x00000007,0x0004003b, + 0x00000019,0x000005c2,0x00000007,0x0004003b,0x00000014,0x000005c4,0x00000007,0x0004003b, + 0x00000019,0x000005cb,0x00000007,0x0004003b,0x00000014,0x000005cd,0x00000007,0x0004003b, + 0x0000004c,0x000005d0,0x00000007,0x0004003b,0x00000007,0x000005e2,0x00000007,0x0004003b, + 0x00000007,0x000005e8,0x00000007,0x0004003b,0x00000082,0x000005ed,0x00000007,0x0004003b, + 0x00000007,0x000005ee,0x00000007,0x0004003b,0x00000019,0x000005f2,0x00000007,0x0004003b, + 0x00000019,0x000005f6,0x00000007,0x0004003b,0x00000014,0x000005f8,0x00000007,0x0004003b, + 0x00000014,0x000005fb,0x00000007,0x0004003b,0x00000019,0x0000060b,0x00000007,0x0004003b, + 0x00000014,0x00000618,0x00000007,0x0004003b,0x00000007,0x0000061d,0x00000007,0x0004003b, + 0x00000019,0x0000061e,0x00000007,0x0004003b,0x00000019,0x0000061f,0x00000007,0x0004003b, + 0x00000019,0x00000622,0x00000007,0x0004003b,0x00000007,0x00000624,0x00000007,0x0004003b, + 0x00000007,0x00000626,0x00000007,0x0004003b,0x00000019,0x00000627,0x00000007,0x0004003b, + 0x00000019,0x0000062e,0x00000007,0x0004003b,0x00000019,0x00000631,0x00000007,0x0004003b, + 0x00000007,0x00000633,0x00000007,0x0004003b,0x00000007,0x00000635,0x00000007,0x0004003b, + 0x00000019,0x00000636,0x00000007,0x0004003b,0x00000019,0x0000063e,0x00000007,0x0004003b, + 0x0000004c,0x00000641,0x00000007,0x0004003b,0x00000019,0x00000644,0x00000007,0x0004003b, + 0x00000019,0x00000647,0x00000007,0x0004003b,0x00000650,0x00000651,0x00000007,0x0004003b, + 0x00000019,0x00000661,0x00000007,0x0004003b,0x0000003e,0x00000664,0x00000007,0x0004003b, + 0x00000014,0x00000667,0x00000007,0x0004003b,0x00000007,0x00000669,0x00000007,0x0004003b, + 0x0000003e,0x00000675,0x00000007,0x0004003b,0x0000003e,0x00000687,0x00000007,0x0004003b, + 0x00000019,0x00000689,0x00000007,0x0004003b,0x00000019,0x000006b4,0x00000007,0x0004003d, + 0x00000013,0x000005ba,0x000005b9,0x0007004f,0x00000022,0x000005bb,0x000005ba,0x000005ba, + 0x00000000,0x00000001,0x0006000c,0x00000022,0x000005bc,0x00000001,0x00000008,0x000005bb, + 0x0004006e,0x000005b5,0x000005bd,0x000005bc,0x0003003e,0x000005b7,0x000005bd,0x0004003d, + 0x00000013,0x000005c1,0x000005bf,0x0003003e,0x000005c0,0x000005c1,0x0003003e,0x000005c2, + 0x00000132,0x00050041,0x00000019,0x000006e2,0x000005c0,0x0000010b,0x0004003d,0x00000008, + 0x000006e3,0x000006e2,0x000500be,0x0000006a,0x000006e4,0x000006e3,0x0000012d,0x000300f7, + 0x0000073c,0x00000000,0x000400fa,0x000006e4,0x00000732,0x000006e5,0x000200f8,0x000006e5, + 0x0004003d,0x00000008,0x000006e7,0x000006e2,0x000500ba,0x0000006a,0x000006e8,0x000006e7, + 0x00000465,0x000300f7,0x00000731,0x00000000,0x000400fa,0x000006e8,0x00000702,0x000006e9, + 0x000200f8,0x000006e9,0x0004003d,0x00000008,0x000006eb,0x000006e2,0x00050083,0x00000008, + 0x000006ed,0x000001cd,0x000006eb,0x0003003e,0x000006db,0x000006ed,0x0004003d,0x000001ad, + 0x000006ee,0x000004b3,0x0004003d,0x000001b1,0x000006ef,0x000004b5,0x00050056,0x000001b5, + 0x000006f0,0x000006ee,0x000006ef,0x0004003d,0x00000013,0x000006f1,0x000005c0,0x0007004f, + 0x00000022,0x000006f2,0x000006f1,0x000006f1,0x00000000,0x00000001,0x0004003d,0x00000008, + 0x000006f3,0x000006db,0x00070058,0x00000013,0x000006f4,0x000006f0,0x000006f2,0x00000002, + 0x000006f3,0x0003003e,0x000006d3,0x000006f4,0x00050041,0x00000019,0x000006f5,0x000005c0, + 0x000000f4,0x0004003d,0x00000008,0x000006f6,0x000006f5,0x0004003d,0x00000008,0x000006f7, + 0x000005c2,0x00050085,0x00000008,0x000006f8,0x000006f6,0x000006f7,0x0003003e,0x000006dc, + 0x000006f8,0x0004003d,0x00000013,0x000006fa,0x000006d3,0x0003003e,0x000006dd,0x000006fa, + 0x0004003d,0x00000013,0x00000741,0x000006dd,0x0008004f,0x0000002c,0x00000742,0x00000741, + 0x00000741,0x00000000,0x00000001,0x00000002,0x00050041,0x00000019,0x00000743,0x000006dd, + 0x0000010b,0x0004003d,0x00000008,0x00000744,0x00000743,0x000500b7,0x0000006a,0x00000745, + 0x00000744,0x0000012d,0x000300f7,0x0000074b,0x00000000,0x000400fa,0x00000745,0x00000747, + 0x00000746,0x000200f8,0x00000746,0x0003003e,0x0000073e,0x0000012d,0x000200f9,0x0000074b, + 0x000200f8,0x00000747,0x0004003d,0x00000008,0x00000749,0x00000743,0x00050088,0x00000008, + 0x0000074a,0x00000132,0x00000749,0x0003003e,0x0000073e,0x0000074a,0x000200f9,0x0000074b, + 0x000200f8,0x0000074b,0x0004003d,0x00000008,0x0000074c,0x0000073e,0x0005008e,0x0000002c, + 0x0000074d,0x00000742,0x0000074c,0x0003003e,0x0000073f,0x0000074d,0x0004003d,0x0000002c, + 0x000006fb,0x0000073f,0x00050041,0x00000019,0x000006fc,0x000006d3,0x0000010b,0x0004003d, + 0x00000008,0x000006fd,0x000006fc,0x0004003d,0x00000008,0x000006fe,0x000006dc,0x00050085, + 0x00000008,0x000006ff,0x000006fd,0x000006fe,0x0003003e,0x000006de,0x000006fb,0x0003003e, + 0x000006df,0x000006ff,0x0004003d,0x0000002c,0x00000751,0x000006de,0x00050041,0x00000019, + 0x00000752,0x0000074e,0x000000de,0x00050051,0x00000008,0x00000753,0x00000751,0x00000000, + 0x0003003e,0x00000752,0x00000753,0x00050041,0x00000019,0x00000754,0x0000074e,0x000000e1, + 0x00050051,0x00000008,0x00000755,0x00000751,0x00000001,0x0003003e,0x00000754,0x00000755, + 0x00050041,0x00000019,0x00000756,0x0000074e,0x000000f4,0x00050051,0x00000008,0x00000757, + 0x00000751,0x00000002,0x0003003e,0x00000756,0x00000757,0x0004003d,0x00000008,0x00000758, + 0x000006df,0x00050041,0x00000019,0x00000759,0x0000074e,0x0000010b,0x0003003e,0x00000759, + 0x00000758,0x0004003d,0x00000013,0x0000075a,0x0000074e,0x0003003e,0x0000074f,0x0000075a, + 0x0004003d,0x00000013,0x00000700,0x0000074f,0x0003003e,0x000006d3,0x00000700,0x000200f9, + 0x00000731,0x000200f8,0x00000702,0x00050041,0x00000019,0x00000703,0x000005c0,0x000000f4, + 0x0004003d,0x00000008,0x00000704,0x00000703,0x000500ba,0x0000006a,0x00000705,0x00000704, + 0x0000012d,0x000300f7,0x0000070d,0x00000000,0x000400fa,0x00000705,0x0000070a,0x00000706, + 0x000200f8,0x00000706,0x0004003d,0x00000013,0x00000707,0x000005c0,0x0007004f,0x00000022, + 0x00000708,0x00000707,0x00000707,0x00000000,0x00000001,0x0006000c,0x00000008,0x00000709, + 0x00000001,0x00000042,0x00000708,0x0003003e,0x000006d6,0x00000709,0x000200f9,0x0000070d, + 0x000200f8,0x0000070a,0x00050041,0x00000019,0x0000070b,0x000005c0,0x000000de,0x0004003d, + 0x00000008,0x0000070c,0x0000070b,0x0003003e,0x000006d6,0x0000070c,0x000200f9,0x0000070d, + 0x000200f8,0x0000070d,0x0004003d,0x00000008,0x0000070e,0x000006d6,0x0003003e,0x000006d5, + 0x0000070e,0x0004003d,0x00000008,0x0000070f,0x000006d5,0x0008000c,0x00000008,0x00000710, + 0x00000001,0x0000002b,0x0000070f,0x0000012d,0x00000132,0x0003003e,0x000006d5,0x00000710, + 0x0004003d,0x00000008,0x00000712,0x00000703,0x0006000c,0x00000008,0x00000713,0x00000001, + 0x00000004,0x00000712,0x0003003e,0x000006d7,0x00000713,0x0004003d,0x00000008,0x00000714, + 0x000006d7,0x000500ba,0x0000006a,0x00000715,0x00000714,0x00000132,0x000300f7,0x0000071f, + 0x00000000,0x000400fa,0x00000715,0x0000071b,0x00000716,0x000200f8,0x00000716,0x0004003d, + 0x00000008,0x00000717,0x000006d5,0x00050085,0x00000008,0x00000718,0x00000488,0x00000717, + 0x0004003d,0x00000008,0x00000719,0x000006d7,0x00050081,0x00000008,0x0000071a,0x00000718, + 0x00000719,0x0003003e,0x000006d9,0x0000071a,0x000200f9,0x0000071f,0x000200f8,0x0000071b, + 0x0004003d,0x00000008,0x0000071c,0x000006d5,0x00050085,0x00000008,0x0000071d,0x00000483, + 0x0000071c,0x00050081,0x00000008,0x0000071e,0x0000071d,0x00000294,0x0003003e,0x000006d9, + 0x0000071e,0x000200f9,0x0000071f,0x000200f8,0x0000071f,0x0004003d,0x00000008,0x00000720, + 0x000006d9,0x0003003e,0x000006d8,0x00000720,0x0004003d,0x00000008,0x00000722,0x000006e2, + 0x0004007f,0x00000008,0x00000723,0x00000722,0x0003003e,0x000006da,0x00000723,0x0004003d, + 0x000001ad,0x00000724,0x00000492,0x0004003d,0x000001b1,0x00000725,0x00000494,0x00050056, + 0x000001b5,0x00000726,0x00000724,0x00000725,0x0004003d,0x00000008,0x00000727,0x000006d8, + 0x0004003d,0x00000008,0x00000728,0x000006da,0x00050050,0x00000022,0x00000729,0x00000727, + 0x00000728,0x00070058,0x00000013,0x0000072a,0x00000726,0x00000729,0x00000002,0x0000012d, + 0x0003003e,0x000006d3,0x0000072a,0x0004003d,0x00000008,0x0000072b,0x000005c2,0x00050041, + 0x00000019,0x0000072c,0x000006d3,0x0000010b,0x0004003d,0x00000008,0x0000072d,0x0000072c, + 0x00050085,0x00000008,0x0000072e,0x0000072d,0x0000072b,0x0003003e,0x0000072c,0x0000072e, + 0x000200f9,0x00000731,0x000200f8,0x00000731,0x000200f9,0x0000073c,0x000200f8,0x00000732, + 0x0004003d,0x00000013,0x00000733,0x000005c0,0x0003003e,0x000006d4,0x00000733,0x0004003d, + 0x00000013,0x0000075e,0x000006d4,0x0003003e,0x0000075b,0x0000075e,0x0004003d,0x00000013, + 0x0000075f,0x0000075b,0x0003003e,0x0000075c,0x0000075f,0x0004003d,0x00000013,0x00000734, + 0x0000075c,0x0003003e,0x000006d3,0x00000734,0x0004003d,0x00000008,0x00000736,0x000005c2, + 0x00050041,0x00000019,0x00000737,0x000006d3,0x0000010b,0x0004003d,0x00000008,0x00000738, + 0x00000737,0x00050085,0x00000008,0x00000739,0x00000738,0x00000736,0x0003003e,0x00000737, + 0x00000739,0x000200f9,0x0000073c,0x000200f8,0x0000073c,0x0004003d,0x00000013,0x0000073d, + 0x000006d3,0x0003003e,0x000006e0,0x0000073d,0x0004003d,0x00000013,0x000005c3,0x000006e0, + 0x0003003e,0x000005be,0x000005c3,0x0004003d,0x000005c5,0x000005c8,0x000005c7,0x00050062, + 0x00000013,0x000005ca,0x000005c8,0x000005c9,0x0003003e,0x000005c4,0x000005ca,0x0004003d, + 0x00000013,0x000005ce,0x000005cc,0x0003003e,0x000005cd,0x000005ce,0x000300f7,0x00000771, + 0x00000000,0x000300fb,0x000000de,0x00000767,0x000200f8,0x00000767,0x0004003d,0x00000013, + 0x00000768,0x000005cd,0x0003003e,0x00000762,0x00000768,0x00050041,0x00000019,0x00000775, + 0x00000762,0x000000e1,0x0004003d,0x00000008,0x00000776,0x00000775,0x000500be,0x0000006a, + 0x00000777,0x00000776,0x0000012d,0x0003003e,0x00000773,0x00000777,0x0004003d,0x0000006a, + 0x00000769,0x00000773,0x000300f7,0x00000770,0x00000000,0x000400fa,0x00000769,0x0000076d, + 0x0000076a,0x000200f8,0x0000076a,0x0004003d,0x00000013,0x0000076b,0x000005cd,0x0003003e, + 0x00000764,0x0000076b,0x000300f7,0x0000078d,0x00000000,0x000300fb,0x000000de,0x0000077f, + 0x000200f8,0x0000077f,0x000300f7,0x00000783,0x00000000,0x000400fa,0x000004d4,0x00000780, + 0x00000783,0x000200f8,0x00000780,0x0004003d,0x00000013,0x00000781,0x00000764,0x0003003e, + 0x0000077a,0x00000781,0x00050041,0x00000019,0x00000791,0x0000077a,0x000000e1,0x0004003d, + 0x00000008,0x00000792,0x00000791,0x000500b8,0x0000006a,0x00000793,0x00000792,0x00000197, + 0x0003003e,0x0000078f,0x00000793,0x0004003d,0x0000006a,0x00000782,0x0000078f,0x000200f9, + 0x00000783,0x000200f8,0x00000783,0x000700f5,0x0000006a,0x00000784,0x000004d4,0x0000077f, + 0x00000782,0x00000780,0x000300f7,0x0000078c,0x00000000,0x000400fa,0x00000784,0x00000789, + 0x00000785,0x000200f8,0x00000785,0x00050041,0x00000019,0x00000786,0x00000764,0x000000de, + 0x0004003d,0x00000008,0x00000787,0x00000786,0x0003003e,0x0000077c,0x00000787,0x0004003d, + 0x00000008,0x00000788,0x0000077c,0x0003003e,0x00000779,0x00000788,0x000200f9,0x0000078d, + 0x000200f8,0x00000789,0x0004003d,0x00000013,0x0000078a,0x00000764,0x0003003e,0x0000077b, + 0x0000078a,0x00050041,0x00000019,0x000007ab,0x0000077b,0x000000f4,0x0004003d,0x00000008, + 0x000007ac,0x000007ab,0x0003003e,0x00000794,0x000007ac,0x00050041,0x00000019,0x000007ad, + 0x0000077b,0x0000010b,0x0004003d,0x00000008,0x000007ae,0x000007ad,0x0007000c,0x00000008, + 0x000007af,0x00000001,0x00000028,0x000007ae,0x0000012d,0x0003003e,0x00000795,0x000007af, + 0x0004003d,0x00000008,0x000007b0,0x00000794,0x000500be,0x0000006a,0x000007b1,0x000007b0, + 0x0000012d,0x000300f7,0x000007bb,0x00000000,0x000400fa,0x000007b1,0x000007b3,0x000007b2, + 0x000200f8,0x000007b2,0x0003003e,0x00000797,0x0000012d,0x000200f9,0x000007bb,0x000200f8, + 0x000007b3,0x0004003d,0x000001ad,0x000007b4,0x000001af,0x0004003d,0x000001b1,0x000007b5, + 0x000001b3,0x00050056,0x000001b5,0x000007b6,0x000007b4,0x000007b5,0x0004003d,0x00000008, + 0x000007b7,0x00000795,0x00050050,0x00000022,0x000007b8,0x000007b7,0x0000012d,0x00070058, + 0x00000013,0x000007b9,0x000007b6,0x000007b8,0x00000002,0x0000012d,0x00050051,0x00000008, + 0x000007ba,0x000007b9,0x00000000,0x0003003e,0x00000797,0x000007ba,0x000200f9,0x000007bb, + 0x000200f8,0x000007bb,0x0004003d,0x00000008,0x000007bc,0x00000797,0x0003003e,0x00000796, + 0x000007bc,0x0004003d,0x00000008,0x000007bd,0x00000794,0x0006000c,0x00000008,0x000007be, + 0x00000001,0x00000004,0x000007bd,0x000500b8,0x0000006a,0x000007bf,0x000007be,0x000001bf, + 0x000300f7,0x0000080e,0x00000000,0x000400fa,0x000007bf,0x000007c0,0x0000080e,0x000200f8, + 0x000007c0,0x00050041,0x00000019,0x000007c1,0x0000077b,0x000000de,0x0004003d,0x00000008, + 0x000007c2,0x000007c1,0x0006000c,0x00000008,0x000007c3,0x00000001,0x00000004,0x000007c2, + 0x00050083,0x00000008,0x000007c4,0x000007c3,0x000001c7,0x0003003e,0x00000798,0x000007c4, + 0x00050041,0x00000019,0x000007c5,0x0000077b,0x000000e1,0x0004003d,0x00000008,0x000007c6, + 0x000007c5,0x00050083,0x00000008,0x000007c8,0x000001cd,0x000007c6,0x0003003e,0x00000799, + 0x000007c8,0x0004003d,0x00000008,0x000007c9,0x00000799,0x0004003d,0x00000008,0x000007ca, + 0x00000795,0x00050083,0x00000008,0x000007cb,0x000007c9,0x000007ca,0x00050085,0x00000008, + 0x000007cc,0x000007cb,0x000001d3,0x0003003e,0x0000079a,0x000007cc,0x0004003d,0x00000008, + 0x000007cd,0x00000795,0x0004003d,0x00000008,0x000007ce,0x0000079a,0x0003003e,0x0000079c, + 0x000001d8,0x0003003e,0x0000079d,0x000001d9,0x0003003e,0x0000079e,0x000001da,0x0003003e, + 0x0000079f,0x000001db,0x0004003d,0x00000008,0x00000818,0x0000079c,0x00050041,0x00000019, + 0x00000819,0x00000815,0x000000de,0x0003003e,0x00000819,0x00000818,0x0004003d,0x00000008, + 0x0000081a,0x0000079d,0x00050041,0x00000019,0x0000081b,0x00000815,0x000000e1,0x0003003e, + 0x0000081b,0x0000081a,0x0004003d,0x00000008,0x0000081c,0x0000079e,0x00050041,0x00000019, + 0x0000081d,0x00000815,0x000000f4,0x0003003e,0x0000081d,0x0000081c,0x0004003d,0x00000008, + 0x0000081e,0x0000079f,0x00050041,0x00000019,0x0000081f,0x00000815,0x0000010b,0x0003003e, + 0x0000081f,0x0000081e,0x0004003d,0x00000013,0x00000820,0x00000815,0x0003003e,0x00000816, + 0x00000820,0x0004003d,0x00000013,0x000007cf,0x00000816,0x0005008e,0x00000013,0x000007d0, + 0x000007cf,0x000007ce,0x00070050,0x00000013,0x000007d1,0x000007cd,0x000007cd,0x000007cd, + 0x000007cd,0x00050081,0x00000013,0x000007d2,0x000007d1,0x000007d0,0x0003003e,0x0000079b, + 0x000007d2,0x0004003d,0x00000013,0x000007d3,0x0000079b,0x0004003d,0x00000008,0x000007d4, + 0x00000794,0x0004007f,0x00000008,0x000007d5,0x000007d4,0x0005008e,0x00000013,0x000007d6, + 0x000007d3,0x000007d5,0x0004003d,0x00000008,0x000007d7,0x00000799,0x0004003d,0x00000008, + 0x000007d8,0x00000794,0x00050085,0x00000008,0x000007d9,0x000007d7,0x000007d8,0x0004003d, + 0x00000008,0x000007da,0x00000798,0x00050081,0x00000008,0x000007db,0x000007d9,0x000007da, + 0x00070050,0x00000013,0x000007dc,0x000007db,0x000007db,0x000007db,0x000007db,0x00050081, + 0x00000013,0x000007dd,0x000007d6,0x000007dc,0x0003003e,0x000007a0,0x000007dd,0x0004003d, + 0x000001ad,0x000007de,0x000001af,0x0004003d,0x000001b1,0x000007df,0x000001b3,0x00050056, + 0x000001b5,0x000007e0,0x000007de,0x000007df,0x00050041,0x00000019,0x000007e1,0x000007a0, + 0x000000de,0x0004003d,0x00000008,0x000007e2,0x000007e1,0x00050050,0x00000022,0x000007e3, + 0x000007e2,0x0000012d,0x00070058,0x00000013,0x000007e4,0x000007e0,0x000007e3,0x00000002, + 0x0000012d,0x0004003d,0x000001ad,0x000007e5,0x000001af,0x0004003d,0x000001b1,0x000007e6, + 0x000001b3,0x00050056,0x000001b5,0x000007e7,0x000007e5,0x000007e6,0x00050041,0x00000019, + 0x000007e8,0x000007a0,0x000000e1,0x0004003d,0x00000008,0x000007e9,0x000007e8,0x00050050, + 0x00000022,0x000007ea,0x000007e9,0x0000012d,0x00070058,0x00000013,0x000007eb,0x000007e7, + 0x000007ea,0x00000002,0x0000012d,0x0004003d,0x000001ad,0x000007ec,0x000001af,0x0004003d, + 0x000001b1,0x000007ed,0x000001b3,0x00050056,0x000001b5,0x000007ee,0x000007ec,0x000007ed, + 0x00050041,0x00000019,0x000007ef,0x000007a0,0x000000f4,0x0004003d,0x00000008,0x000007f0, + 0x000007ef,0x00050050,0x00000022,0x000007f1,0x000007f0,0x0000012d,0x00070058,0x00000013, + 0x000007f2,0x000007ee,0x000007f1,0x00000002,0x0000012d,0x0004003d,0x000001ad,0x000007f3, + 0x000001af,0x0004003d,0x000001b1,0x000007f4,0x000001b3,0x00050056,0x000001b5,0x000007f5, + 0x000007f3,0x000007f4,0x00050041,0x00000019,0x000007f6,0x000007a0,0x0000010b,0x0004003d, + 0x00000008,0x000007f7,0x000007f6,0x00050050,0x00000022,0x000007f8,0x000007f7,0x0000012d, + 0x00070058,0x00000013,0x000007f9,0x000007f5,0x000007f8,0x00000002,0x0000012d,0x00050051, + 0x00000008,0x000007fa,0x000007e4,0x00000000,0x0003003e,0x000007a2,0x000007fa,0x00050051, + 0x00000008,0x000007fb,0x000007eb,0x00000000,0x0003003e,0x000007a3,0x000007fb,0x00050051, + 0x00000008,0x000007fc,0x000007f2,0x00000000,0x0003003e,0x000007a4,0x000007fc,0x00050051, + 0x00000008,0x000007fd,0x000007f9,0x00000000,0x0003003e,0x000007a5,0x000007fd,0x0004003d, + 0x00000008,0x00000824,0x000007a2,0x00050041,0x00000019,0x00000825,0x00000821,0x000000de, + 0x0003003e,0x00000825,0x00000824,0x0004003d,0x00000008,0x00000826,0x000007a3,0x00050041, + 0x00000019,0x00000827,0x00000821,0x000000e1,0x0003003e,0x00000827,0x00000826,0x0004003d, + 0x00000008,0x00000828,0x000007a4,0x00050041,0x00000019,0x00000829,0x00000821,0x000000f4, + 0x0003003e,0x00000829,0x00000828,0x0004003d,0x00000008,0x0000082a,0x000007a5,0x00050041, + 0x00000019,0x0000082b,0x00000821,0x0000010b,0x0003003e,0x0000082b,0x0000082a,0x0004003d, + 0x00000013,0x0000082c,0x00000821,0x0003003e,0x00000822,0x0000082c,0x0004003d,0x00000013, + 0x000007fe,0x00000822,0x0003003e,0x000007a1,0x000007fe,0x0004003d,0x00000013,0x000007ff, + 0x0000079b,0x0005008e,0x00000013,0x00000800,0x000007ff,0x00000218,0x00050081,0x00000013, + 0x00000801,0x00000800,0x000006c0,0x0003003e,0x000007a6,0x00000801,0x0004003d,0x00000013, + 0x00000802,0x000007a6,0x0004007f,0x00000013,0x00000803,0x00000802,0x0004003d,0x00000013, + 0x00000804,0x000007a6,0x00050085,0x00000013,0x00000805,0x00000803,0x00000804,0x0006000c, + 0x00000013,0x00000806,0x00000001,0x0000001d,0x00000805,0x0003003e,0x000007a7,0x00000806, + 0x0004003d,0x00000013,0x00000807,0x000007a1,0x0004003d,0x00000013,0x00000808,0x000007a7, + 0x00050094,0x00000008,0x00000809,0x00000807,0x00000808,0x0004003d,0x00000008,0x0000080a, + 0x0000079a,0x00050085,0x00000008,0x0000080b,0x00000809,0x0000080a,0x0004003d,0x00000008, + 0x0000080c,0x00000796,0x00050081,0x00000008,0x0000080d,0x0000080c,0x0000080b,0x0003003e, + 0x00000796,0x0000080d,0x000200f9,0x0000080e,0x000200f8,0x0000080e,0x0004003d,0x00000008, + 0x0000080f,0x00000796,0x00050041,0x00000019,0x00000810,0x0000077b,0x000000de,0x0004003d, + 0x00000008,0x00000811,0x00000810,0x0006000c,0x00000008,0x00000812,0x00000001,0x00000006, + 0x00000811,0x00050085,0x00000008,0x00000813,0x0000080f,0x00000812,0x0003003e,0x000007a8, + 0x00000813,0x0004003d,0x00000008,0x00000814,0x000007a8,0x0003003e,0x000007a9,0x00000814, + 0x0004003d,0x00000008,0x0000078b,0x000007a9,0x0003003e,0x00000779,0x0000078b,0x000200f9, + 0x0000078d,0x000200f8,0x0000078c,0x000200f9,0x0000078d,0x000200f8,0x0000078d,0x0004003d, + 0x00000008,0x0000078e,0x00000779,0x0003003e,0x0000077d,0x0000078e,0x0004003d,0x00000008, + 0x0000076c,0x0000077d,0x0003003e,0x00000761,0x0000076c,0x000200f9,0x00000771,0x000200f8, + 0x0000076d,0x0004003d,0x00000013,0x0000076e,0x000005cd,0x0003003e,0x00000763,0x0000076e, + 0x000300f7,0x00000845,0x00000000,0x000300fb,0x000000de,0x00000834,0x000200f8,0x00000834, + 0x000300f7,0x00000838,0x00000000,0x000400fa,0x000004d4,0x00000835,0x00000838,0x000200f8, + 0x00000835,0x0004003d,0x00000013,0x00000836,0x00000763,0x0003003e,0x0000082f,0x00000836, + 0x00050041,0x00000019,0x00000849,0x0000082f,0x000000de,0x0004003d,0x00000008,0x0000084a, + 0x00000849,0x000500b8,0x0000006a,0x0000084b,0x0000084a,0x00000197,0x0003003e,0x00000847, + 0x0000084b,0x0004003d,0x0000006a,0x00000837,0x00000847,0x000200f9,0x00000838,0x000200f8, + 0x00000838,0x000700f5,0x0000006a,0x00000839,0x000004d4,0x00000834,0x00000837,0x00000835, + 0x000300f7,0x00000844,0x00000000,0x000400fa,0x00000839,0x00000841,0x0000083a,0x000200f8, + 0x0000083a,0x00050041,0x00000019,0x0000083b,0x00000763,0x000000de,0x0004003d,0x00000008, + 0x0000083c,0x0000083b,0x00050041,0x00000019,0x0000083d,0x00000763,0x000000e1,0x0004003d, + 0x00000008,0x0000083e,0x0000083d,0x0007000c,0x00000008,0x0000083f,0x00000001,0x00000025, + 0x0000083c,0x0000083e,0x0003003e,0x00000831,0x0000083f,0x0004003d,0x00000008,0x00000840, + 0x00000831,0x0003003e,0x0000082e,0x00000840,0x000200f9,0x00000845,0x000200f8,0x00000841, + 0x0004003d,0x00000013,0x00000842,0x00000763,0x0003003e,0x00000830,0x00000842,0x0003003e, + 0x0000084c,0x00000132,0x00050041,0x00000019,0x00000852,0x00000830,0x000000de,0x0004003d, + 0x00000008,0x00000853,0x00000852,0x00050081,0x00000008,0x00000854,0x00000235,0x00000853, + 0x0003003e,0x0000084d,0x00000854,0x0004003d,0x000001ad,0x00000855,0x000001af,0x0004003d, + 0x000001b1,0x00000856,0x000001b3,0x00050056,0x000001b5,0x00000857,0x00000855,0x00000856, + 0x0004003d,0x00000008,0x00000858,0x0000084d,0x00050050,0x00000022,0x00000859,0x00000858, + 0x0000012d,0x00070058,0x00000013,0x0000085a,0x00000857,0x00000859,0x00000002,0x0000012d, + 0x00050051,0x00000008,0x0000085b,0x0000085a,0x00000000,0x0004003d,0x00000008,0x0000085c, + 0x0000084c,0x00050083,0x00000008,0x0000085d,0x0000085c,0x0000085b,0x0003003e,0x0000084c, + 0x0000085d,0x00050041,0x00000019,0x0000085e,0x00000830,0x000000e1,0x0004003d,0x00000008, + 0x0000085f,0x0000085e,0x00050083,0x00000008,0x00000860,0x00000132,0x0000085f,0x0003003e, + 0x0000084e,0x00000860,0x0004003d,0x000001ad,0x00000861,0x000001af,0x0004003d,0x000001b1, + 0x00000862,0x000001b3,0x00050056,0x000001b5,0x00000863,0x00000861,0x00000862,0x0004003d, + 0x00000008,0x00000864,0x0000084e,0x00050050,0x00000022,0x00000865,0x00000864,0x0000012d, + 0x00070058,0x00000013,0x00000866,0x00000863,0x00000865,0x00000002,0x0000012d,0x00050051, + 0x00000008,0x00000867,0x00000866,0x00000000,0x0004003d,0x00000008,0x00000868,0x0000084c, + 0x00050083,0x00000008,0x00000869,0x00000868,0x00000867,0x0003003e,0x0000084c,0x00000869, + 0x0004003d,0x00000008,0x0000086a,0x0000084c,0x0003003e,0x0000084f,0x0000086a,0x0004003d, + 0x00000008,0x0000086b,0x0000084f,0x0003003e,0x00000850,0x0000086b,0x0004003d,0x00000008, + 0x00000843,0x00000850,0x0003003e,0x0000082e,0x00000843,0x000200f9,0x00000845,0x000200f8, + 0x00000844,0x000200f9,0x00000845,0x000200f8,0x00000845,0x0004003d,0x00000008,0x00000846, + 0x0000082e,0x0003003e,0x00000832,0x00000846,0x0004003d,0x00000008,0x0000076f,0x00000832, + 0x0003003e,0x00000761,0x0000076f,0x000200f9,0x00000771,0x000200f8,0x00000770,0x000200f9, + 0x00000771,0x000200f8,0x00000771,0x0004003d,0x00000008,0x00000772,0x00000761,0x0003003e, + 0x00000765,0x00000772,0x0004003d,0x00000008,0x000005cf,0x00000765,0x0003003e,0x000005cb, + 0x000005cf,0x0004003d,0x00000022,0x000005d3,0x000005d2,0x0003003e,0x000005d0,0x000005d3, + 0x0004003d,0x00000013,0x000005d4,0x000005c4,0x0007004f,0x00000022,0x000005d5,0x000005d4, + 0x000005d4,0x00000000,0x00000001,0x0004003d,0x00000013,0x000005d6,0x000005c4,0x0007004f, + 0x00000022,0x000005d7,0x000005d6,0x000005d6,0x00000002,0x00000003,0x00050081,0x00000022, + 0x000005d8,0x000005d5,0x000005d7,0x00050041,0x000005da,0x000005db,0x0000051c,0x000000e1, + 0x0004003d,0x00000008,0x000005dc,0x000005db,0x0005008e,0x00000022,0x000005dd,0x000005d8, + 0x000005dc,0x0004003d,0x00000022,0x000005de,0x000005d0,0x00050081,0x00000022,0x000005df, + 0x000005de,0x000005dd,0x0003003e,0x000005d0,0x000005df,0x0004003d,0x00000022,0x000005e0, + 0x000005d0,0x0006000c,0x00000022,0x000005e1,0x00000001,0x00000008,0x000005e0,0x0003003e, + 0x000005d0,0x000005e1,0x00050041,0x000005e5,0x000005e6,0x000005e4,0x000000e1,0x0004003d, + 0x00000006,0x000005e7,0x000005e6,0x0003003e,0x000005e2,0x000005e7,0x00050041,0x000005e5, + 0x000005e9,0x000005e4,0x000000de,0x0004003d,0x00000006,0x000005ea,0x000005e9,0x0004003d, + 0x00000022,0x000005eb,0x000005d0,0x0004006d,0x00000081,0x000005ec,0x000005eb,0x0003003e, + 0x000005ed,0x000005ec,0x0004003d,0x00000006,0x000005ef,0x000005e2,0x0003003e,0x000005ee, + 0x000005ef,0x00050041,0x00000007,0x0000086f,0x000005ed,0x000000e1,0x0004003d,0x00000006, + 0x00000870,0x0000086f,0x000500c2,0x00000006,0x00000871,0x00000870,0x00000263,0x0004003d, + 0x00000006,0x00000872,0x000005ee,0x000500c4,0x00000006,0x00000873,0x00000872,0x00000263, + 0x00050084,0x00000006,0x00000874,0x00000871,0x00000873,0x00050041,0x00000007,0x00000875, + 0x000005ed,0x000000de,0x0004003d,0x00000006,0x00000876,0x00000875,0x000500c2,0x00000006, + 0x00000877,0x00000876,0x00000263,0x00050084,0x00000006,0x00000878,0x00000877,0x0000026b, + 0x00050080,0x00000006,0x00000879,0x00000874,0x00000878,0x0003003e,0x0000086c,0x00000879, + 0x0004003d,0x00000006,0x0000087b,0x00000875,0x000500c7,0x00000006,0x0000087c,0x0000087b, + 0x00000270,0x000500c2,0x00000006,0x0000087d,0x0000087c,0x000000f4,0x00050084,0x00000006, + 0x0000087e,0x0000087d,0x00000273,0x0004003d,0x00000006,0x00000880,0x0000086f,0x000500c7, + 0x00000006,0x00000881,0x00000880,0x00000270,0x000500c2,0x00000006,0x00000882,0x00000881, + 0x000000f4,0x00050084,0x00000006,0x00000883,0x00000882,0x00000279,0x00050080,0x00000006, + 0x00000884,0x0000087e,0x00000883,0x0004003d,0x00000006,0x00000885,0x0000086c,0x00050080, + 0x00000006,0x00000886,0x00000885,0x00000884,0x0003003e,0x0000086c,0x00000886,0x0004003d, + 0x00000006,0x00000888,0x0000086f,0x000500c7,0x00000006,0x00000889,0x00000888,0x0000010b, + 0x00050084,0x00000006,0x0000088a,0x00000889,0x00000281,0x0004003d,0x00000006,0x0000088c, + 0x00000875,0x000500c7,0x00000006,0x0000088d,0x0000088c,0x0000010b,0x00050080,0x00000006, + 0x0000088e,0x0000088a,0x0000088d,0x0004003d,0x00000006,0x0000088f,0x0000086c,0x00050080, + 0x00000006,0x00000890,0x0000088f,0x0000088e,0x0003003e,0x0000086c,0x00000890,0x0004003d, + 0x00000006,0x00000891,0x0000086c,0x0003003e,0x0000086d,0x00000891,0x0004003d,0x00000006, + 0x000005f0,0x0000086d,0x00050080,0x00000006,0x000005f1,0x000005ea,0x000005f0,0x0003003e, + 0x000005e8,0x000005f1,0x0003003e,0x000005f2,0x00000132,0x000300f7,0x000005f5,0x00000000, + 0x000400fa,0x000005f3,0x000005f4,0x000005f5,0x000200f8,0x000005f4,0x0004003d,0x00000013, + 0x000005f9,0x000005f7,0x0003003e,0x000005f8,0x000005f9,0x0004003d,0x00000013,0x00000895, + 0x000005f8,0x0003003e,0x00000892,0x00000895,0x0004003d,0x00000013,0x00000896,0x00000892, + 0x0003003e,0x00000893,0x00000896,0x0004003d,0x00000013,0x000005fa,0x00000893,0x0003003e, + 0x000005fb,0x000005fa,0x0004003d,0x00000013,0x0000089b,0x000005fb,0x0007004f,0x00000022, + 0x0000089c,0x0000089b,0x0000089b,0x00000000,0x00000001,0x0004003d,0x00000013,0x0000089d, + 0x000005fb,0x0007004f,0x00000022,0x0000089e,0x0000089d,0x0000089d,0x00000002,0x00000003, + 0x0007000c,0x00000022,0x0000089f,0x00000001,0x00000025,0x0000089c,0x0000089e,0x0003003e, + 0x00000897,0x0000089f,0x00050041,0x00000019,0x000008a0,0x00000897,0x000000de,0x0004003d, + 0x00000008,0x000008a1,0x000008a0,0x00050041,0x00000019,0x000008a2,0x00000897,0x000000e1, + 0x0004003d,0x00000008,0x000008a3,0x000008a2,0x0007000c,0x00000008,0x000008a4,0x00000001, + 0x00000025,0x000008a1,0x000008a3,0x0003003e,0x00000898,0x000008a4,0x0004003d,0x00000008, + 0x000008a5,0x00000898,0x0003003e,0x00000899,0x000008a5,0x0004003d,0x00000008,0x000005fc, + 0x00000899,0x0003003e,0x000005f6,0x000005fc,0x0004003d,0x00000008,0x000005fd,0x000005f6, + 0x0004003d,0x00000008,0x000005fe,0x000005f2,0x0007000c,0x00000008,0x000005ff,0x00000001, + 0x00000025,0x000005fd,0x000005fe,0x0003003e,0x000005f2,0x000005ff,0x000200f9,0x000005f5, + 0x000200f8,0x000005f5,0x000300f7,0x00000602,0x00000000,0x000400fa,0x00000600,0x00000601, + 0x00000602,0x000200f8,0x00000601,0x00050041,0x00000604,0x00000605,0x00000603,0x000000de, + 0x0004003d,0x00000008,0x00000606,0x00000605,0x000500b7,0x0000006a,0x00000607,0x00000606, + 0x0000012d,0x000200f9,0x00000602,0x000200f8,0x00000602,0x000700f5,0x0000006a,0x00000608, + 0x00000600,0x000005f5,0x00000607,0x00000601,0x000300f7,0x0000060a,0x00000000,0x000400fa, + 0x00000608,0x00000609,0x0000060a,0x000200f8,0x00000609,0x0004003d,0x000005c5,0x0000060d, + 0x0000060c,0x00050062,0x00000013,0x0000060e,0x0000060d,0x000005c9,0x00050051,0x00000008, + 0x0000060f,0x0000060e,0x00000000,0x0003003e,0x0000060b,0x0000060f,0x0004003d,0x00000008, + 0x00000610,0x0000060b,0x0004003d,0x00000008,0x00000611,0x000005f2,0x0007000c,0x00000008, + 0x00000612,0x00000001,0x00000025,0x00000610,0x00000611,0x0003003e,0x000005f2,0x00000612, + 0x000200f9,0x0000060a,0x000200f8,0x0000060a,0x0004003d,0x00000008,0x00000613,0x000005f2, + 0x0007000c,0x00000008,0x00000614,0x00000001,0x00000028,0x00000613,0x0000012d,0x0003003e, + 0x000005f2,0x00000614,0x0004003d,0x00000008,0x00000615,0x000005cb,0x0004003d,0x00000008, + 0x00000616,0x000005f2,0x0008000c,0x00000008,0x00000617,0x00000001,0x0000002b,0x00000615, + 0x0000012d,0x00000616,0x0003003e,0x000005cb,0x00000617,0x0003003e,0x00000618,0x000005ce, + 0x00050041,0x00000019,0x000008a8,0x00000618,0x000000e1,0x0004003d,0x00000008,0x000008a9, + 0x000008a8,0x000500be,0x0000006a,0x000008aa,0x000008a9,0x0000012d,0x0003003e,0x000008a6, + 0x000008aa,0x0004003d,0x0000006a,0x0000061a,0x000008a6,0x000300f7,0x0000061c,0x00000000, + 0x000400fa,0x0000061a,0x0000061b,0x0000062d,0x000200f8,0x0000062d,0x00050041,0x00000019, + 0x0000062f,0x000005be,0x0000010b,0x0004003d,0x00000008,0x00000630,0x0000062f,0x0003003e, + 0x0000062e,0x00000630,0x0004003d,0x00000008,0x00000632,0x000005cb,0x0003003e,0x00000631, + 0x00000632,0x0004003d,0x00000006,0x00000634,0x000005e8,0x0003003e,0x00000633,0x00000634, + 0x0003003e,0x000008ab,0x0000012d,0x0004003d,0x00000008,0x000008bf,0x00000631,0x0006000c, + 0x00000008,0x000008c0,0x00000001,0x00000004,0x000008bf,0x0003003e,0x000008ad,0x000008c0, + 0x0004003d,0x00000008,0x00000914,0x000008ad,0x00050085,0x00000008,0x00000915,0x00000914, + 0x00000299,0x00050081,0x00000008,0x00000916,0x00000915,0x0000029b,0x0004006d,0x00000006, + 0x00000917,0x00000916,0x0003003e,0x00000911,0x00000917,0x0004003d,0x00000006,0x00000918, + 0x00000911,0x0003003e,0x00000912,0x00000918,0x0004003d,0x00000006,0x000008c1,0x00000912, + 0x0003003e,0x000008ac,0x000008c1,0x0004003d,0x00000006,0x000008c2,0x00000633,0x00060041, + 0x00000517,0x000008c3,0x00000515,0x000003ad,0x000008c2,0x0004003d,0x00000006,0x000008c4, + 0x000008c3,0x0003003e,0x00000635,0x000008c4,0x0004003d,0x00000006,0x000008c5,0x00000635, + 0x00050041,0x00000517,0x000008c6,0x0000051c,0x000000de,0x0004003d,0x00000006,0x000008c7, + 0x000008c6,0x000500b0,0x0000006a,0x000008c8,0x000008c5,0x000008c7,0x000300f7,0x000008f0, + 0x00000000,0x000400fa,0x000008c8,0x000008c9,0x000008f0,0x000200f8,0x000008c9,0x0004003d, + 0x00000006,0x000008cc,0x000008ac,0x00050080,0x00000006,0x000008cd,0x0000028f,0x000008cc, + 0x000500c5,0x00000006,0x000008ce,0x000008c7,0x000008cd,0x0003003e,0x000008ae,0x000008ce, + 0x0004003d,0x00000006,0x000008cf,0x00000633,0x00060041,0x00000517,0x000008d0,0x00000515, + 0x000003ad,0x000008cf,0x0004003d,0x00000006,0x000008d1,0x000008ae,0x000700ef,0x00000006, + 0x000008d2,0x000008d0,0x000000e1,0x000000de,0x000008d1,0x0003003e,0x000008af,0x000008d2, + 0x0004003d,0x00000006,0x000008d3,0x000008af,0x0003003e,0x00000635,0x000008d3,0x0004003d, + 0x00000006,0x000008d4,0x000008af,0x000500b2,0x0000006a,0x000008d7,0x000008d4,0x000008c7, + 0x000300f7,0x000008ef,0x00000000,0x000400fa,0x000008d7,0x000008ec,0x000008d8,0x000200f8, + 0x000008d8,0x0004003d,0x00000006,0x000008d9,0x000008af,0x0004003d,0x00000006,0x000008da, + 0x000008ae,0x000500b0,0x0000006a,0x000008db,0x000008d9,0x000008da,0x000300f7,0x000008eb, + 0x00000000,0x000400fa,0x000008db,0x000008dc,0x000008eb,0x000200f8,0x000008dc,0x0004003d, + 0x00000006,0x000008dd,0x000008af,0x000500c7,0x00000006,0x000008de,0x000008dd,0x0000028d, + 0x00050082,0x00000006,0x000008df,0x000008de,0x0000028f,0x0003003e,0x000008b0,0x000008df, + 0x0004003d,0x00000006,0x000008e0,0x000008b0,0x0003003e,0x000008b2,0x000008e0,0x0004003d, + 0x00000006,0x0000091c,0x000008b2,0x00040070,0x00000008,0x0000091d,0x0000091c,0x0003003e, + 0x00000919,0x0000091d,0x0004003d,0x00000008,0x0000091e,0x00000919,0x0003003e,0x0000091a, + 0x0000091e,0x0004003d,0x00000008,0x000008e1,0x0000091a,0x00050085,0x00000008,0x000008e2, + 0x000008e1,0x00000294,0x0003003e,0x000008b1,0x000008e2,0x0004003d,0x00000008,0x000008e3, + 0x00000631,0x0003003e,0x000008b3,0x000008e3,0x0004003d,0x00000008,0x000008e4,0x000008b3, + 0x0003003e,0x00000636,0x000008e4,0x0004003d,0x00000008,0x000008e5,0x000008b1,0x0003003e, + 0x000008b4,0x000008e5,0x0004003d,0x00000008,0x000008e6,0x000008b3,0x0003003e,0x000008b5, + 0x000008e6,0x0004003d,0x00000008,0x000008e7,0x0000062e,0x0003003e,0x000008b6,0x000008e7, + 0x0004003d,0x00000008,0x00000921,0x000008b5,0x0004003d,0x00000008,0x00000922,0x000008b4, + 0x00050083,0x00000008,0x00000923,0x00000921,0x00000922,0x0004003d,0x00000008,0x00000924, + 0x000008b4,0x0004003d,0x00000008,0x00000925,0x000008b6,0x00050085,0x00000008,0x00000926, + 0x00000924,0x00000925,0x00050083,0x00000008,0x00000927,0x00000132,0x00000926,0x0007000c, + 0x00000008,0x00000928,0x00000001,0x00000028,0x00000927,0x0000025b,0x00050088,0x00000008, + 0x00000929,0x00000923,0x00000928,0x0003003e,0x0000091f,0x00000929,0x0004003d,0x00000008, + 0x000008e8,0x0000091f,0x0003003e,0x000008ab,0x000008e8,0x0004003d,0x00000006,0x000008e9, + 0x000008b0,0x0003003e,0x000008ac,0x000008e9,0x0004003d,0x00000008,0x000008ea,0x000008b1, + 0x0003003e,0x00000631,0x000008ea,0x000200f9,0x000008eb,0x000200f8,0x000008eb,0x000200f9, + 0x000008ef,0x000200f8,0x000008ec,0x0004003d,0x00000008,0x000008ed,0x00000631,0x0003003e, + 0x000008ab,0x000008ed,0x0004003d,0x00000008,0x000008ee,0x000008ab,0x0003003e,0x00000636, + 0x000008ee,0x0003003e,0x00000631,0x0000012d,0x000200f9,0x000008ef,0x000200f8,0x000008ef, + 0x000200f9,0x000008f0,0x000200f8,0x000008f0,0x0004003d,0x00000008,0x000008f1,0x00000631, + 0x000500ba,0x0000006a,0x000008f2,0x000008f1,0x0000012d,0x000300f7,0x0000090d,0x00000000, + 0x000400fa,0x000008f2,0x000008f3,0x0000090d,0x000200f8,0x000008f3,0x0004003d,0x00000006, + 0x000008f4,0x00000633,0x00060041,0x00000517,0x000008f5,0x00000515,0x000003ad,0x000008f4, + 0x0004003d,0x00000006,0x000008f6,0x000008ac,0x000700ea,0x00000006,0x000008f7,0x000008f5, + 0x000000e1,0x000000de,0x000008f6,0x0003003e,0x000008b7,0x000008f7,0x0004003d,0x00000006, + 0x000008f8,0x000008b7,0x0003003e,0x000008b9,0x000008f8,0x0004003d,0x00000006,0x0000092d, + 0x000008b9,0x000500c7,0x00000006,0x0000092e,0x0000092d,0x0000028d,0x00050082,0x00000006, + 0x0000092f,0x0000092e,0x0000028f,0x0004007c,0x0000000d,0x00000930,0x0000092f,0x0003003e, + 0x0000092a,0x00000930,0x0004003d,0x0000000d,0x00000936,0x0000092a,0x0004006f,0x00000008, + 0x00000937,0x00000936,0x0003003e,0x00000933,0x00000937,0x0004003d,0x00000008,0x00000938, + 0x00000933,0x0003003e,0x00000934,0x00000938,0x0004003d,0x00000008,0x00000931,0x00000934, + 0x00050085,0x00000008,0x00000932,0x00000931,0x00000294,0x0003003e,0x0000092b,0x00000932, + 0x0004003d,0x00000008,0x000008f9,0x0000092b,0x0003003e,0x000008b8,0x000008f9,0x0004003d, + 0x00000008,0x000008fa,0x000008b8,0x0004003d,0x00000008,0x000008fb,0x00000631,0x00050081, + 0x00000008,0x000008fc,0x000008fa,0x000008fb,0x0003003e,0x000008ba,0x000008fc,0x0004003d, + 0x00000008,0x000008fd,0x000008b8,0x0008000c,0x00000008,0x000008fe,0x00000001,0x0000002b, + 0x000008fd,0x0000012d,0x00000132,0x0003003e,0x000008b8,0x000008fe,0x0004003d,0x00000008, + 0x000008ff,0x000008ba,0x0008000c,0x00000008,0x00000900,0x00000001,0x0000002b,0x000008ff, + 0x0000012d,0x00000132,0x0003003e,0x000008ba,0x00000900,0x0004003d,0x00000008,0x00000901, + 0x000008ba,0x0003003e,0x00000636,0x00000901,0x0004003d,0x00000008,0x00000902,0x000008ab, + 0x0004003d,0x00000008,0x00000903,0x0000062e,0x00050085,0x00000008,0x00000904,0x00000902, + 0x00000903,0x00050083,0x00000008,0x00000905,0x00000132,0x00000904,0x0004003d,0x00000008, + 0x00000906,0x000008b8,0x0003003e,0x000008bb,0x00000906,0x0004003d,0x00000008,0x00000907, + 0x000008ba,0x0003003e,0x000008bc,0x00000907,0x0004003d,0x00000008,0x00000908,0x0000062e, + 0x0003003e,0x000008bd,0x00000908,0x0004003d,0x00000008,0x0000093b,0x000008bc,0x0004003d, + 0x00000008,0x0000093c,0x000008bb,0x00050083,0x00000008,0x0000093d,0x0000093b,0x0000093c, + 0x0004003d,0x00000008,0x0000093e,0x000008bb,0x0004003d,0x00000008,0x0000093f,0x000008bd, + 0x00050085,0x00000008,0x00000940,0x0000093e,0x0000093f,0x00050083,0x00000008,0x00000941, + 0x00000132,0x00000940,0x0007000c,0x00000008,0x00000942,0x00000001,0x00000028,0x00000941, + 0x0000025b,0x00050088,0x00000008,0x00000943,0x0000093d,0x00000942,0x0003003e,0x00000939, + 0x00000943,0x0004003d,0x00000008,0x00000909,0x00000939,0x00050085,0x00000008,0x0000090a, + 0x00000905,0x00000909,0x0004003d,0x00000008,0x0000090b,0x000008ab,0x00050081,0x00000008, + 0x0000090c,0x0000090b,0x0000090a,0x0003003e,0x000008ab,0x0000090c,0x000200f9,0x0000090d, + 0x000200f8,0x0000090d,0x0004003d,0x00000008,0x0000090e,0x000008ab,0x0004003d,0x00000008, + 0x0000090f,0x0000062e,0x00050085,0x00000008,0x00000910,0x0000090f,0x0000090e,0x0003003e, + 0x0000062e,0x00000910,0x0004003d,0x00000008,0x00000638,0x0000062e,0x0003003e,0x0000062f, + 0x00000638,0x0004003d,0x00000006,0x0000063a,0x00000635,0x0003003e,0x0000061d,0x0000063a, + 0x0004003d,0x00000008,0x0000063b,0x00000636,0x0003003e,0x0000061e,0x0000063b,0x000200f9, + 0x0000061c,0x000200f8,0x0000061b,0x00050041,0x00000019,0x00000620,0x000005be,0x0000010b, + 0x0004003d,0x00000008,0x00000621,0x00000620,0x0003003e,0x0000061f,0x00000621,0x0004003d, + 0x00000008,0x00000623,0x000005cb,0x0003003e,0x00000622,0x00000623,0x0004003d,0x00000006, + 0x00000625,0x000005e8,0x0003003e,0x00000624,0x00000625,0x0004003d,0x00000008,0x0000094e, + 0x00000622,0x0006000c,0x00000008,0x0000094f,0x00000001,0x00000004,0x0000094e,0x0003003e, + 0x00000945,0x0000094f,0x0004003d,0x00000008,0x00000980,0x00000945,0x00050085,0x00000008, + 0x00000981,0x00000980,0x00000299,0x00050081,0x00000008,0x00000982,0x00000981,0x0000029b, + 0x0004006d,0x00000006,0x00000983,0x00000982,0x0003003e,0x0000097d,0x00000983,0x0004003d, + 0x00000006,0x00000984,0x0000097d,0x0003003e,0x0000097e,0x00000984,0x0004003d,0x00000006, + 0x00000950,0x0000097e,0x0003003e,0x00000944,0x00000950,0x0004003d,0x00000006,0x00000951, + 0x00000624,0x00060041,0x00000517,0x00000952,0x00000515,0x000003ad,0x00000951,0x00050041, + 0x00000517,0x00000953,0x0000051c,0x000000de,0x0004003d,0x00000006,0x00000954,0x00000953, + 0x0004003d,0x00000006,0x00000955,0x00000944,0x000500c5,0x00000006,0x00000956,0x00000954, + 0x00000955,0x000700ef,0x00000006,0x00000957,0x00000952,0x000000e1,0x000000de,0x00000956, + 0x0003003e,0x00000626,0x00000957,0x0004003d,0x00000006,0x00000958,0x00000626,0x000500b0, + 0x0000006a,0x0000095b,0x00000958,0x00000954,0x000300f7,0x00000979,0x00000000,0x000400fa, + 0x0000095b,0x00000976,0x0000095c,0x000200f8,0x0000095c,0x0004003d,0x00000006,0x0000095d, + 0x00000626,0x000500c7,0x00000006,0x0000095e,0x0000095d,0x0000052e,0x000500ab,0x0000006a, + 0x0000095f,0x0000095e,0x000000de,0x000300f7,0x00000969,0x00000000,0x000400fa,0x0000095f, + 0x00000960,0x00000969,0x000200f8,0x00000960,0x0004003d,0x00000006,0x00000961,0x00000624, + 0x00060041,0x00000517,0x00000962,0x00000515,0x000003ad,0x00000961,0x000500c5,0x00000006, + 0x00000965,0x00000954,0x0000052e,0x0004003d,0x00000006,0x00000966,0x00000944,0x000500c5, + 0x00000006,0x00000967,0x00000965,0x00000966,0x000700ef,0x00000006,0x00000968,0x00000962, + 0x000000e1,0x000000de,0x00000967,0x0003003e,0x00000626,0x00000968,0x000200f9,0x00000969, + 0x000200f8,0x00000969,0x0004003d,0x00000006,0x0000096a,0x00000626,0x000500c7,0x00000006, + 0x0000096b,0x0000096a,0x0000028d,0x0003003e,0x00000948,0x0000096b,0x0004003d,0x00000006, + 0x00000988,0x00000948,0x00040070,0x00000008,0x00000989,0x00000988,0x0003003e,0x00000985, + 0x00000989,0x0004003d,0x00000008,0x0000098a,0x00000985,0x0003003e,0x00000986,0x0000098a, + 0x0004003d,0x00000008,0x0000096c,0x00000986,0x00050085,0x00000008,0x0000096d,0x0000096c, + 0x00000294,0x0003003e,0x00000947,0x0000096d,0x0004003d,0x00000008,0x0000096e,0x00000947, + 0x0004003d,0x00000008,0x0000096f,0x00000622,0x0007000c,0x00000008,0x00000970,0x00000001, + 0x00000028,0x0000096e,0x0000096f,0x0003003e,0x00000949,0x00000970,0x0004003d,0x00000008, + 0x00000971,0x00000947,0x0003003e,0x0000094a,0x00000971,0x0004003d,0x00000008,0x00000972, + 0x00000949,0x0003003e,0x0000094b,0x00000972,0x0004003d,0x00000008,0x00000973,0x0000061f, + 0x0003003e,0x0000094c,0x00000973,0x0004003d,0x00000008,0x0000098d,0x0000094b,0x0004003d, + 0x00000008,0x0000098e,0x0000094a,0x00050083,0x00000008,0x0000098f,0x0000098d,0x0000098e, + 0x0004003d,0x00000008,0x00000990,0x0000094a,0x0004003d,0x00000008,0x00000991,0x0000094c, + 0x00050085,0x00000008,0x00000992,0x00000990,0x00000991,0x00050083,0x00000008,0x00000993, + 0x00000132,0x00000992,0x0007000c,0x00000008,0x00000994,0x00000001,0x00000028,0x00000993, + 0x0000025b,0x00050088,0x00000008,0x00000995,0x0000098f,0x00000994,0x0003003e,0x0000098b, + 0x00000995,0x0004003d,0x00000008,0x00000974,0x0000098b,0x0003003e,0x00000946,0x00000974, + 0x0004003d,0x00000008,0x00000975,0x00000949,0x0003003e,0x00000627,0x00000975,0x000200f9, + 0x00000979,0x000200f8,0x00000976,0x0004003d,0x00000008,0x00000977,0x00000622,0x0003003e, + 0x00000946,0x00000977,0x0004003d,0x00000008,0x00000978,0x00000622,0x0003003e,0x00000627, + 0x00000978,0x000200f9,0x00000979,0x000200f8,0x00000979,0x0004003d,0x00000008,0x0000097a, + 0x00000946,0x0004003d,0x00000008,0x0000097b,0x0000061f,0x00050085,0x00000008,0x0000097c, + 0x0000097b,0x0000097a,0x0003003e,0x0000061f,0x0000097c,0x0004003d,0x00000008,0x00000629, + 0x0000061f,0x0003003e,0x00000620,0x00000629,0x0004003d,0x00000006,0x0000062b,0x00000626, + 0x0003003e,0x0000061d,0x0000062b,0x0004003d,0x00000008,0x0000062c,0x00000627,0x0003003e, + 0x0000061e,0x0000062c,0x000200f9,0x0000061c,0x000200f8,0x0000061c,0x000300f7,0x0000063d, + 0x00000000,0x000400fa,0x00000181,0x0000063c,0x0000063d,0x000200f8,0x0000063c,0x0003003e, + 0x00000641,0x000005bb,0x00050041,0x000005da,0x00000645,0x0000051c,0x000000f4,0x0004003d, + 0x00000008,0x00000646,0x00000645,0x0003003e,0x00000644,0x00000646,0x00050041,0x000005da, + 0x00000648,0x0000051c,0x0000010b,0x0004003d,0x00000008,0x00000649,0x00000648,0x0003003e, + 0x00000647,0x00000649,0x000300f7,0x000009a2,0x00000000,0x000400fa,0x00000181,0x0000099d, + 0x0000099c,0x000200f8,0x0000099c,0x0003003e,0x00000996,0x0000012d,0x000200f9,0x000009a2, + 0x000200f8,0x0000099d,0x0004003d,0x00000022,0x0000099e,0x00000641,0x0003003e,0x00000997, + 0x0000099e,0x0004003d,0x00000008,0x0000099f,0x00000644,0x0003003e,0x00000998,0x0000099f, + 0x0004003d,0x00000008,0x000009a0,0x00000647,0x0003003e,0x00000999,0x000009a0,0x00050041, + 0x00000019,0x000009a8,0x00000997,0x000000de,0x0004003d,0x00000008,0x000009a9,0x000009a8, + 0x00050085,0x00000008,0x000009aa,0x0000016b,0x000009a9,0x00050041,0x00000019,0x000009ab, + 0x00000997,0x000000e1,0x0004003d,0x00000008,0x000009ac,0x000009ab,0x00050085,0x00000008, + 0x000009ad,0x0000016f,0x000009ac,0x00050081,0x00000008,0x000009ae,0x000009aa,0x000009ad, + 0x0006000c,0x00000008,0x000009af,0x00000001,0x0000000a,0x000009ae,0x0003003e,0x000009a4, + 0x000009af,0x0004003d,0x00000008,0x000009b0,0x000009a4,0x00050085,0x00000008,0x000009b1, + 0x00000176,0x000009b0,0x0006000c,0x00000008,0x000009b2,0x00000001,0x0000000a,0x000009b1, + 0x0003003e,0x000009a5,0x000009b2,0x0004003d,0x00000008,0x000009b3,0x000009a5,0x0004003d, + 0x00000008,0x000009b4,0x00000998,0x00050085,0x00000008,0x000009b5,0x000009b3,0x000009b4, + 0x0004003d,0x00000008,0x000009b6,0x00000999,0x00050081,0x00000008,0x000009b7,0x000009b5, + 0x000009b6,0x0003003e,0x000009a6,0x000009b7,0x0004003d,0x00000008,0x000009a1,0x000009a6, + 0x0003003e,0x00000996,0x000009a1,0x000200f9,0x000009a2,0x000200f8,0x000009a2,0x0004003d, + 0x00000008,0x000009a3,0x00000996,0x0003003e,0x0000099a,0x000009a3,0x0004003d,0x00000008, + 0x0000064a,0x0000099a,0x0003003e,0x0000063e,0x0000064a,0x000200f9,0x0000063d,0x000200f8, + 0x0000063d,0x00050041,0x00000019,0x0000064b,0x000005be,0x0000010b,0x0004003d,0x00000008, + 0x0000064c,0x0000064b,0x000500ba,0x0000006a,0x0000064d,0x0000064c,0x0000012d,0x000300f7, + 0x0000064f,0x00000000,0x000400fa,0x0000064d,0x0000064e,0x0000064f,0x000200f8,0x0000064e, + 0x0004003d,0x00000006,0x00000652,0x0000061d,0x00050041,0x00000517,0x00000653,0x0000051c, + 0x000000de,0x0004003d,0x00000006,0x00000654,0x00000653,0x000500ae,0x0000006a,0x00000655, + 0x00000652,0x00000654,0x000300f7,0x00000657,0x00000000,0x000400fa,0x00000655,0x00000656, + 0x00000657,0x000200f8,0x00000656,0x0004003d,0x00000006,0x00000658,0x0000061d,0x000500c7, + 0x00000006,0x00000659,0x00000658,0x0000052e,0x000500ab,0x0000006a,0x0000065a,0x00000659, + 0x000000de,0x000200f9,0x00000657,0x000200f8,0x00000657,0x000700f5,0x0000006a,0x0000065b, + 0x00000655,0x0000064e,0x0000065a,0x00000656,0x0003003e,0x00000651,0x0000065b,0x0004003d, + 0x0000006a,0x0000065c,0x00000651,0x000400a8,0x0000006a,0x0000065d,0x0000065c,0x000300f7, + 0x0000065f,0x00000000,0x000400fa,0x0000065d,0x0000065e,0x0000068f,0x000200f8,0x0000068f, + 0x0004003d,0x00000682,0x00000690,0x00000684,0x0004003d,0x000005b5,0x00000691,0x000005b7, + 0x00050062,0x00000013,0x00000692,0x00000690,0x00000691,0x00050041,0x00000019,0x00000694, + 0x000005be,0x000000de,0x00050051,0x00000008,0x00000695,0x00000692,0x00000000,0x0003003e, + 0x00000694,0x00000695,0x00050041,0x00000019,0x00000696,0x000005be,0x000000e1,0x00050051, + 0x00000008,0x00000697,0x00000692,0x00000001,0x0003003e,0x00000696,0x00000697,0x00050041, + 0x00000019,0x00000698,0x000005be,0x000000f4,0x00050051,0x00000008,0x00000699,0x00000692, + 0x00000002,0x0003003e,0x00000698,0x00000699,0x000200f9,0x0000065f,0x000200f8,0x0000065e, + 0x0004003d,0x00000008,0x00000662,0x00000660,0x0003003e,0x00000661,0x00000662,0x0004003d, + 0x00000008,0x000009ba,0x00000661,0x0004006d,0x00000006,0x000009bb,0x000009ba,0x0003003e, + 0x000009b8,0x000009bb,0x0004003d,0x00000006,0x00000663,0x000009b8,0x0004003d,0x00000013, + 0x00000665,0x000005be,0x0008004f,0x0000002c,0x00000666,0x00000665,0x00000665,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x00000664,0x00000666,0x0004003d,0x00000013,0x00000668, + 0x000005c4,0x0003003e,0x00000667,0x00000668,0x0003003e,0x00000669,0x00000663,0x0004003d, + 0x0000002c,0x000009c3,0x00000664,0x0003003e,0x000009bd,0x000009c3,0x0004003d,0x00000013, + 0x000009c4,0x00000667,0x0003003e,0x000009be,0x000009c4,0x0004003d,0x00000006,0x000009c5, + 0x00000669,0x0003003e,0x000009bf,0x000009c5,0x0004003d,0x00000013,0x000009f5,0x000009be, + 0x0003003e,0x000009ce,0x000009f5,0x0004003d,0x00000013,0x00000af1,0x000009ce,0x0008004f, + 0x0000002c,0x00000af2,0x00000af1,0x00000af1,0x00000000,0x00000001,0x00000002,0x00050041, + 0x00000019,0x00000af3,0x000009ce,0x0000010b,0x0004003d,0x00000008,0x00000af4,0x00000af3, + 0x000500b7,0x0000006a,0x00000af5,0x00000af4,0x0000012d,0x000300f7,0x00000afb,0x00000000, + 0x000400fa,0x00000af5,0x00000af7,0x00000af6,0x000200f8,0x00000af6,0x0003003e,0x00000aee, + 0x0000012d,0x000200f9,0x00000afb,0x000200f8,0x00000af7,0x0004003d,0x00000008,0x00000af9, + 0x00000af3,0x00050088,0x00000008,0x00000afa,0x00000132,0x00000af9,0x0003003e,0x00000aee, + 0x00000afa,0x000200f9,0x00000afb,0x000200f8,0x00000afb,0x0004003d,0x00000008,0x00000afc, + 0x00000aee,0x0005008e,0x0000002c,0x00000afd,0x00000af2,0x00000afc,0x0003003e,0x00000aef, + 0x00000afd,0x0004003d,0x0000002c,0x000009f6,0x00000aef,0x0003003e,0x000009cd,0x000009f6, + 0x0004003d,0x00000006,0x000009f7,0x000009bf,0x000300f7,0x00000aec,0x00000000,0x002100fb, + 0x000009f7,0x00000aec,0x0000000b,0x00000ae8,0x00000001,0x00000ae0,0x00000002,0x00000ad0, + 0x00000003,0x00000acc,0x00000004,0x00000ac8,0x00000005,0x00000aa6,0x00000006,0x00000a7a, + 0x00000007,0x00000a6a,0x00000008,0x00000a30,0x00000009,0x00000a2b,0x0000000a,0x00000a22, + 0x0000000c,0x00000a17,0x0000000d,0x00000a0c,0x0000000e,0x00000a02,0x0000000f,0x000009f8, + 0x000200f8,0x000009f8,0x000300f7,0x00000a01,0x00000000,0x000400fa,0x000003fb,0x000009f9, + 0x00000a01,0x000200f8,0x000009f9,0x0004003d,0x0000002c,0x000009fa,0x000009bd,0x0003003e, + 0x000009ef,0x0000012d,0x0004003d,0x00000008,0x00000b01,0x000009ef,0x00050041,0x00000019, + 0x00000b02,0x00000afe,0x000000de,0x0003003e,0x00000b02,0x00000b01,0x0004003d,0x00000008, + 0x00000b03,0x000009ef,0x00050041,0x00000019,0x00000b04,0x00000afe,0x000000e1,0x0003003e, + 0x00000b04,0x00000b03,0x0004003d,0x00000008,0x00000b05,0x000009ef,0x00050041,0x00000019, + 0x00000b06,0x00000afe,0x000000f4,0x0003003e,0x00000b06,0x00000b05,0x0004003d,0x0000002c, + 0x00000b07,0x00000afe,0x0003003e,0x00000aff,0x00000b07,0x0004003d,0x0000002c,0x000009fb, + 0x00000aff,0x0003003e,0x000009f0,0x00000132,0x0004003d,0x00000008,0x00000b0b,0x000009f0, + 0x00050041,0x00000019,0x00000b0c,0x00000b08,0x000000de,0x0003003e,0x00000b0c,0x00000b0b, + 0x0004003d,0x00000008,0x00000b0d,0x000009f0,0x00050041,0x00000019,0x00000b0e,0x00000b08, + 0x000000e1,0x0003003e,0x00000b0e,0x00000b0d,0x0004003d,0x00000008,0x00000b0f,0x000009f0, + 0x00050041,0x00000019,0x00000b10,0x00000b08,0x000000f4,0x0003003e,0x00000b10,0x00000b0f, + 0x0004003d,0x0000002c,0x00000b11,0x00000b08,0x0003003e,0x00000b09,0x00000b11,0x0004003d, + 0x0000002c,0x000009fc,0x00000b09,0x0008000c,0x0000002c,0x000009fd,0x00000001,0x0000002b, + 0x000009fa,0x000009fb,0x000009fc,0x0003003e,0x000009bd,0x000009fd,0x0004003d,0x0000002c, + 0x000009fe,0x000009cd,0x0003003e,0x000009f1,0x000009fe,0x0004003d,0x0000002c,0x000009ff, + 0x000009bd,0x0003003e,0x000009f2,0x000009ff,0x0004003d,0x0000002c,0x00000b22,0x000009f2, + 0x0003003e,0x00000b13,0x00000b22,0x0004003d,0x0000002c,0x00000b48,0x00000b13,0x0003003e, + 0x00000b43,0x000002a3,0x0003003e,0x00000b44,0x000002a4,0x0003003e,0x00000b45,0x000002a5, + 0x0004003d,0x00000008,0x00000b4e,0x00000b43,0x00050041,0x00000019,0x00000b4f,0x00000b4b, + 0x000000de,0x0003003e,0x00000b4f,0x00000b4e,0x0004003d,0x00000008,0x00000b50,0x00000b44, + 0x00050041,0x00000019,0x00000b51,0x00000b4b,0x000000e1,0x0003003e,0x00000b51,0x00000b50, + 0x0004003d,0x00000008,0x00000b52,0x00000b45,0x00050041,0x00000019,0x00000b53,0x00000b4b, + 0x000000f4,0x0003003e,0x00000b53,0x00000b52,0x0004003d,0x0000002c,0x00000b54,0x00000b4b, + 0x0003003e,0x00000b4c,0x00000b54,0x0004003d,0x0000002c,0x00000b49,0x00000b4c,0x00050094, + 0x00000008,0x00000b4a,0x00000b48,0x00000b49,0x0003003e,0x00000b46,0x00000b4a,0x0004003d, + 0x00000008,0x00000b23,0x00000b46,0x0003003e,0x00000b12,0x00000b23,0x0004003d,0x0000002c, + 0x00000b24,0x000009f1,0x0004003d,0x0000002c,0x00000b25,0x000009f1,0x0003003e,0x00000b15, + 0x00000b25,0x0004003d,0x0000002c,0x00000b5a,0x00000b15,0x0003003e,0x00000b55,0x000002a3, + 0x0003003e,0x00000b56,0x000002a4,0x0003003e,0x00000b57,0x000002a5,0x0004003d,0x00000008, + 0x00000b60,0x00000b55,0x00050041,0x00000019,0x00000b61,0x00000b5d,0x000000de,0x0003003e, + 0x00000b61,0x00000b60,0x0004003d,0x00000008,0x00000b62,0x00000b56,0x00050041,0x00000019, + 0x00000b63,0x00000b5d,0x000000e1,0x0003003e,0x00000b63,0x00000b62,0x0004003d,0x00000008, + 0x00000b64,0x00000b57,0x00050041,0x00000019,0x00000b65,0x00000b5d,0x000000f4,0x0003003e, + 0x00000b65,0x00000b64,0x0004003d,0x0000002c,0x00000b66,0x00000b5d,0x0003003e,0x00000b5e, + 0x00000b66,0x0004003d,0x0000002c,0x00000b5b,0x00000b5e,0x00050094,0x00000008,0x00000b5c, + 0x00000b5a,0x00000b5b,0x0003003e,0x00000b58,0x00000b5c,0x0004003d,0x00000008,0x00000b26, + 0x00000b58,0x00060050,0x0000002c,0x00000b27,0x00000b26,0x00000b26,0x00000b26,0x00050083, + 0x0000002c,0x00000b28,0x00000b24,0x00000b27,0x0003003e,0x00000b14,0x00000b28,0x0004003d, + 0x00000008,0x00000b29,0x00000b12,0x00050083,0x00000008,0x00000b2a,0x00000132,0x00000b29, + 0x0004003d,0x00000008,0x00000b2b,0x00000b12,0x0003003e,0x00000b17,0x00000b2b,0x0003003e, + 0x00000b18,0x00000b2a,0x0004003d,0x00000008,0x00000b6a,0x00000b17,0x00050041,0x00000019, + 0x00000b6b,0x00000b67,0x000000de,0x0003003e,0x00000b6b,0x00000b6a,0x0004003d,0x00000008, + 0x00000b6c,0x00000b18,0x00050041,0x00000019,0x00000b6d,0x00000b67,0x000000e1,0x0003003e, + 0x00000b6d,0x00000b6c,0x0004003d,0x00000022,0x00000b6e,0x00000b67,0x0003003e,0x00000b68, + 0x00000b6e,0x0004003d,0x00000022,0x00000b2c,0x00000b68,0x0003003e,0x00000b19,0x0000025b, + 0x0004003d,0x00000008,0x00000b72,0x00000b19,0x00050041,0x00000019,0x00000b73,0x00000b6f, + 0x000000de,0x0003003e,0x00000b73,0x00000b72,0x0004003d,0x00000008,0x00000b74,0x00000b19, + 0x00050041,0x00000019,0x00000b75,0x00000b6f,0x000000e1,0x0003003e,0x00000b75,0x00000b74, + 0x0004003d,0x00000022,0x00000b76,0x00000b6f,0x0003003e,0x00000b70,0x00000b76,0x0004003d, + 0x00000022,0x00000b2d,0x00000b70,0x0004003d,0x0000002c,0x00000b2e,0x00000b14,0x0003003e, + 0x00000b1a,0x00000b2e,0x0004003d,0x0000002c,0x00000b7a,0x00000b1a,0x0007004f,0x00000022, + 0x00000b7b,0x00000b7a,0x00000b7a,0x00000000,0x00000001,0x0003003e,0x00000b77,0x00000b7b, + 0x00050041,0x00000019,0x00000b82,0x00000b77,0x000000de,0x0004003d,0x00000008,0x00000b83, + 0x00000b82,0x00050041,0x00000019,0x00000b84,0x00000b77,0x000000e1,0x0004003d,0x00000008, + 0x00000b85,0x00000b84,0x0007000c,0x00000008,0x00000b86,0x00000001,0x00000025,0x00000b83, + 0x00000b85,0x0003003e,0x00000b80,0x00000b86,0x0004003d,0x00000008,0x00000b7c,0x00000b80, + 0x00050041,0x00000019,0x00000b7d,0x00000b1a,0x000000f4,0x0004003d,0x00000008,0x00000b7e, + 0x00000b7d,0x0007000c,0x00000008,0x00000b7f,0x00000001,0x00000025,0x00000b7c,0x00000b7e, + 0x0003003e,0x00000b78,0x00000b7f,0x0004003d,0x00000008,0x00000b2f,0x00000b78,0x0004007f, + 0x00000008,0x00000b30,0x00000b2f,0x0004003d,0x0000002c,0x00000b31,0x00000b14,0x0003003e, + 0x00000b1b,0x00000b31,0x0004003d,0x0000002c,0x00000b8a,0x00000b1b,0x0007004f,0x00000022, + 0x00000b8b,0x00000b8a,0x00000b8a,0x00000000,0x00000001,0x0003003e,0x00000b87,0x00000b8b, + 0x00050041,0x00000019,0x00000b92,0x00000b87,0x000000de,0x0004003d,0x00000008,0x00000b93, + 0x00000b92,0x00050041,0x00000019,0x00000b94,0x00000b87,0x000000e1,0x0004003d,0x00000008, + 0x00000b95,0x00000b94,0x0007000c,0x00000008,0x00000b96,0x00000001,0x00000028,0x00000b93, + 0x00000b95,0x0003003e,0x00000b90,0x00000b96,0x0004003d,0x00000008,0x00000b8c,0x00000b90, + 0x00050041,0x00000019,0x00000b8d,0x00000b1b,0x000000f4,0x0004003d,0x00000008,0x00000b8e, + 0x00000b8d,0x0007000c,0x00000008,0x00000b8f,0x00000001,0x00000028,0x00000b8c,0x00000b8e, + 0x0003003e,0x00000b88,0x00000b8f,0x0004003d,0x00000008,0x00000b32,0x00000b88,0x0003003e, + 0x00000b1c,0x00000b30,0x0003003e,0x00000b1d,0x00000b32,0x0004003d,0x00000008,0x00000b9a, + 0x00000b1c,0x00050041,0x00000019,0x00000b9b,0x00000b97,0x000000de,0x0003003e,0x00000b9b, + 0x00000b9a,0x0004003d,0x00000008,0x00000b9c,0x00000b1d,0x00050041,0x00000019,0x00000b9d, + 0x00000b97,0x000000e1,0x0003003e,0x00000b9d,0x00000b9c,0x0004003d,0x00000022,0x00000b9e, + 0x00000b97,0x0003003e,0x00000b98,0x00000b9e,0x0004003d,0x00000022,0x00000b33,0x00000b98, + 0x0007000c,0x00000022,0x00000b34,0x00000001,0x00000028,0x00000b2d,0x00000b33,0x00050088, + 0x00000022,0x00000b35,0x00000b2c,0x00000b34,0x0003003e,0x00000b16,0x00000b35,0x0003003e, + 0x00000b1f,0x00000132,0x0004003d,0x00000008,0x00000ba1,0x00000b1f,0x0003003e,0x00000b9f, + 0x00000ba1,0x0004003d,0x00000008,0x00000b36,0x00000b9f,0x00050041,0x00000019,0x00000b37, + 0x00000b16,0x000000de,0x0004003d,0x00000008,0x00000b38,0x00000b37,0x00050041,0x00000019, + 0x00000b39,0x00000b16,0x000000e1,0x0004003d,0x00000008,0x00000b3a,0x00000b39,0x0007000c, + 0x00000008,0x00000b3b,0x00000001,0x00000025,0x00000b38,0x00000b3a,0x0007000c,0x00000008, + 0x00000b3c,0x00000001,0x00000025,0x00000b36,0x00000b3b,0x0003003e,0x00000b1e,0x00000b3c, + 0x0004003d,0x0000002c,0x00000b3d,0x00000b14,0x0004003d,0x00000008,0x00000b3e,0x00000b1e, + 0x0005008e,0x0000002c,0x00000b3f,0x00000b3d,0x00000b3e,0x0004003d,0x00000008,0x00000b40, + 0x00000b12,0x00060050,0x0000002c,0x00000b41,0x00000b40,0x00000b40,0x00000b40,0x00050081, + 0x0000002c,0x00000b42,0x00000b3f,0x00000b41,0x0003003e,0x00000b20,0x00000b42,0x0004003d, + 0x0000002c,0x00000a00,0x00000b20,0x0003003e,0x000009cf,0x00000a00,0x000200f9,0x00000a01, + 0x000200f8,0x00000a01,0x000200f9,0x00000aec,0x000200f8,0x00000a02,0x000300f7,0x00000a0b, + 0x00000000,0x000400fa,0x000003fb,0x00000a03,0x00000a0b,0x000200f8,0x00000a03,0x0004003d, + 0x0000002c,0x00000a04,0x000009bd,0x0003003e,0x000009eb,0x0000012d,0x0004003d,0x00000008, + 0x00000ba5,0x000009eb,0x00050041,0x00000019,0x00000ba6,0x00000ba2,0x000000de,0x0003003e, + 0x00000ba6,0x00000ba5,0x0004003d,0x00000008,0x00000ba7,0x000009eb,0x00050041,0x00000019, + 0x00000ba8,0x00000ba2,0x000000e1,0x0003003e,0x00000ba8,0x00000ba7,0x0004003d,0x00000008, + 0x00000ba9,0x000009eb,0x00050041,0x00000019,0x00000baa,0x00000ba2,0x000000f4,0x0003003e, + 0x00000baa,0x00000ba9,0x0004003d,0x0000002c,0x00000bab,0x00000ba2,0x0003003e,0x00000ba3, + 0x00000bab,0x0004003d,0x0000002c,0x00000a05,0x00000ba3,0x0003003e,0x000009ec,0x00000132, + 0x0004003d,0x00000008,0x00000baf,0x000009ec,0x00050041,0x00000019,0x00000bb0,0x00000bac, + 0x000000de,0x0003003e,0x00000bb0,0x00000baf,0x0004003d,0x00000008,0x00000bb1,0x000009ec, + 0x00050041,0x00000019,0x00000bb2,0x00000bac,0x000000e1,0x0003003e,0x00000bb2,0x00000bb1, + 0x0004003d,0x00000008,0x00000bb3,0x000009ec,0x00050041,0x00000019,0x00000bb4,0x00000bac, + 0x000000f4,0x0003003e,0x00000bb4,0x00000bb3,0x0004003d,0x0000002c,0x00000bb5,0x00000bac, + 0x0003003e,0x00000bad,0x00000bb5,0x0004003d,0x0000002c,0x00000a06,0x00000bad,0x0008000c, + 0x0000002c,0x00000a07,0x00000001,0x0000002b,0x00000a04,0x00000a05,0x00000a06,0x0003003e, + 0x000009bd,0x00000a07,0x0004003d,0x0000002c,0x00000a08,0x000009bd,0x0003003e,0x000009ed, + 0x00000a08,0x0004003d,0x0000002c,0x00000a09,0x000009cd,0x0003003e,0x000009ee,0x00000a09, + 0x0004003d,0x0000002c,0x00000bc6,0x000009ee,0x0003003e,0x00000bb7,0x00000bc6,0x0004003d, + 0x0000002c,0x00000bec,0x00000bb7,0x0003003e,0x00000be7,0x000002a3,0x0003003e,0x00000be8, + 0x000002a4,0x0003003e,0x00000be9,0x000002a5,0x0004003d,0x00000008,0x00000bf2,0x00000be7, + 0x00050041,0x00000019,0x00000bf3,0x00000bef,0x000000de,0x0003003e,0x00000bf3,0x00000bf2, + 0x0004003d,0x00000008,0x00000bf4,0x00000be8,0x00050041,0x00000019,0x00000bf5,0x00000bef, + 0x000000e1,0x0003003e,0x00000bf5,0x00000bf4,0x0004003d,0x00000008,0x00000bf6,0x00000be9, + 0x00050041,0x00000019,0x00000bf7,0x00000bef,0x000000f4,0x0003003e,0x00000bf7,0x00000bf6, + 0x0004003d,0x0000002c,0x00000bf8,0x00000bef,0x0003003e,0x00000bf0,0x00000bf8,0x0004003d, + 0x0000002c,0x00000bed,0x00000bf0,0x00050094,0x00000008,0x00000bee,0x00000bec,0x00000bed, + 0x0003003e,0x00000bea,0x00000bee,0x0004003d,0x00000008,0x00000bc7,0x00000bea,0x0003003e, + 0x00000bb6,0x00000bc7,0x0004003d,0x0000002c,0x00000bc8,0x000009ed,0x0004003d,0x0000002c, + 0x00000bc9,0x000009ed,0x0003003e,0x00000bb9,0x00000bc9,0x0004003d,0x0000002c,0x00000bfe, + 0x00000bb9,0x0003003e,0x00000bf9,0x000002a3,0x0003003e,0x00000bfa,0x000002a4,0x0003003e, + 0x00000bfb,0x000002a5,0x0004003d,0x00000008,0x00000c04,0x00000bf9,0x00050041,0x00000019, + 0x00000c05,0x00000c01,0x000000de,0x0003003e,0x00000c05,0x00000c04,0x0004003d,0x00000008, + 0x00000c06,0x00000bfa,0x00050041,0x00000019,0x00000c07,0x00000c01,0x000000e1,0x0003003e, + 0x00000c07,0x00000c06,0x0004003d,0x00000008,0x00000c08,0x00000bfb,0x00050041,0x00000019, + 0x00000c09,0x00000c01,0x000000f4,0x0003003e,0x00000c09,0x00000c08,0x0004003d,0x0000002c, + 0x00000c0a,0x00000c01,0x0003003e,0x00000c02,0x00000c0a,0x0004003d,0x0000002c,0x00000bff, + 0x00000c02,0x00050094,0x00000008,0x00000c00,0x00000bfe,0x00000bff,0x0003003e,0x00000bfc, + 0x00000c00,0x0004003d,0x00000008,0x00000bca,0x00000bfc,0x00060050,0x0000002c,0x00000bcb, + 0x00000bca,0x00000bca,0x00000bca,0x00050083,0x0000002c,0x00000bcc,0x00000bc8,0x00000bcb, + 0x0003003e,0x00000bb8,0x00000bcc,0x0004003d,0x00000008,0x00000bcd,0x00000bb6,0x00050083, + 0x00000008,0x00000bce,0x00000132,0x00000bcd,0x0004003d,0x00000008,0x00000bcf,0x00000bb6, + 0x0003003e,0x00000bbb,0x00000bcf,0x0003003e,0x00000bbc,0x00000bce,0x0004003d,0x00000008, + 0x00000c0e,0x00000bbb,0x00050041,0x00000019,0x00000c0f,0x00000c0b,0x000000de,0x0003003e, + 0x00000c0f,0x00000c0e,0x0004003d,0x00000008,0x00000c10,0x00000bbc,0x00050041,0x00000019, + 0x00000c11,0x00000c0b,0x000000e1,0x0003003e,0x00000c11,0x00000c10,0x0004003d,0x00000022, + 0x00000c12,0x00000c0b,0x0003003e,0x00000c0c,0x00000c12,0x0004003d,0x00000022,0x00000bd0, + 0x00000c0c,0x0003003e,0x00000bbd,0x0000025b,0x0004003d,0x00000008,0x00000c16,0x00000bbd, + 0x00050041,0x00000019,0x00000c17,0x00000c13,0x000000de,0x0003003e,0x00000c17,0x00000c16, + 0x0004003d,0x00000008,0x00000c18,0x00000bbd,0x00050041,0x00000019,0x00000c19,0x00000c13, + 0x000000e1,0x0003003e,0x00000c19,0x00000c18,0x0004003d,0x00000022,0x00000c1a,0x00000c13, + 0x0003003e,0x00000c14,0x00000c1a,0x0004003d,0x00000022,0x00000bd1,0x00000c14,0x0004003d, + 0x0000002c,0x00000bd2,0x00000bb8,0x0003003e,0x00000bbe,0x00000bd2,0x0004003d,0x0000002c, + 0x00000c1e,0x00000bbe,0x0007004f,0x00000022,0x00000c1f,0x00000c1e,0x00000c1e,0x00000000, + 0x00000001,0x0003003e,0x00000c1b,0x00000c1f,0x00050041,0x00000019,0x00000c26,0x00000c1b, + 0x000000de,0x0004003d,0x00000008,0x00000c27,0x00000c26,0x00050041,0x00000019,0x00000c28, + 0x00000c1b,0x000000e1,0x0004003d,0x00000008,0x00000c29,0x00000c28,0x0007000c,0x00000008, + 0x00000c2a,0x00000001,0x00000025,0x00000c27,0x00000c29,0x0003003e,0x00000c24,0x00000c2a, + 0x0004003d,0x00000008,0x00000c20,0x00000c24,0x00050041,0x00000019,0x00000c21,0x00000bbe, + 0x000000f4,0x0004003d,0x00000008,0x00000c22,0x00000c21,0x0007000c,0x00000008,0x00000c23, + 0x00000001,0x00000025,0x00000c20,0x00000c22,0x0003003e,0x00000c1c,0x00000c23,0x0004003d, + 0x00000008,0x00000bd3,0x00000c1c,0x0004007f,0x00000008,0x00000bd4,0x00000bd3,0x0004003d, + 0x0000002c,0x00000bd5,0x00000bb8,0x0003003e,0x00000bbf,0x00000bd5,0x0004003d,0x0000002c, + 0x00000c2e,0x00000bbf,0x0007004f,0x00000022,0x00000c2f,0x00000c2e,0x00000c2e,0x00000000, + 0x00000001,0x0003003e,0x00000c2b,0x00000c2f,0x00050041,0x00000019,0x00000c36,0x00000c2b, + 0x000000de,0x0004003d,0x00000008,0x00000c37,0x00000c36,0x00050041,0x00000019,0x00000c38, + 0x00000c2b,0x000000e1,0x0004003d,0x00000008,0x00000c39,0x00000c38,0x0007000c,0x00000008, + 0x00000c3a,0x00000001,0x00000028,0x00000c37,0x00000c39,0x0003003e,0x00000c34,0x00000c3a, + 0x0004003d,0x00000008,0x00000c30,0x00000c34,0x00050041,0x00000019,0x00000c31,0x00000bbf, + 0x000000f4,0x0004003d,0x00000008,0x00000c32,0x00000c31,0x0007000c,0x00000008,0x00000c33, + 0x00000001,0x00000028,0x00000c30,0x00000c32,0x0003003e,0x00000c2c,0x00000c33,0x0004003d, + 0x00000008,0x00000bd6,0x00000c2c,0x0003003e,0x00000bc0,0x00000bd4,0x0003003e,0x00000bc1, + 0x00000bd6,0x0004003d,0x00000008,0x00000c3e,0x00000bc0,0x00050041,0x00000019,0x00000c3f, + 0x00000c3b,0x000000de,0x0003003e,0x00000c3f,0x00000c3e,0x0004003d,0x00000008,0x00000c40, + 0x00000bc1,0x00050041,0x00000019,0x00000c41,0x00000c3b,0x000000e1,0x0003003e,0x00000c41, + 0x00000c40,0x0004003d,0x00000022,0x00000c42,0x00000c3b,0x0003003e,0x00000c3c,0x00000c42, + 0x0004003d,0x00000022,0x00000bd7,0x00000c3c,0x0007000c,0x00000022,0x00000bd8,0x00000001, + 0x00000028,0x00000bd1,0x00000bd7,0x00050088,0x00000022,0x00000bd9,0x00000bd0,0x00000bd8, + 0x0003003e,0x00000bba,0x00000bd9,0x0003003e,0x00000bc3,0x00000132,0x0004003d,0x00000008, + 0x00000c45,0x00000bc3,0x0003003e,0x00000c43,0x00000c45,0x0004003d,0x00000008,0x00000bda, + 0x00000c43,0x00050041,0x00000019,0x00000bdb,0x00000bba,0x000000de,0x0004003d,0x00000008, + 0x00000bdc,0x00000bdb,0x00050041,0x00000019,0x00000bdd,0x00000bba,0x000000e1,0x0004003d, + 0x00000008,0x00000bde,0x00000bdd,0x0007000c,0x00000008,0x00000bdf,0x00000001,0x00000025, + 0x00000bdc,0x00000bde,0x0007000c,0x00000008,0x00000be0,0x00000001,0x00000025,0x00000bda, + 0x00000bdf,0x0003003e,0x00000bc2,0x00000be0,0x0004003d,0x0000002c,0x00000be1,0x00000bb8, + 0x0004003d,0x00000008,0x00000be2,0x00000bc2,0x0005008e,0x0000002c,0x00000be3,0x00000be1, + 0x00000be2,0x0004003d,0x00000008,0x00000be4,0x00000bb6,0x00060050,0x0000002c,0x00000be5, + 0x00000be4,0x00000be4,0x00000be4,0x00050081,0x0000002c,0x00000be6,0x00000be3,0x00000be5, + 0x0003003e,0x00000bc4,0x00000be6,0x0004003d,0x0000002c,0x00000a0a,0x00000bc4,0x0003003e, + 0x000009cf,0x00000a0a,0x000200f9,0x00000a0b,0x000200f8,0x00000a0b,0x000200f9,0x00000aec, + 0x000200f8,0x00000a0c,0x000300f7,0x00000a16,0x00000000,0x000400fa,0x000003fb,0x00000a0d, + 0x00000a16,0x000200f8,0x00000a0d,0x0004003d,0x0000002c,0x00000a0e,0x000009bd,0x0003003e, + 0x000009e6,0x0000012d,0x0004003d,0x00000008,0x00000c49,0x000009e6,0x00050041,0x00000019, + 0x00000c4a,0x00000c46,0x000000de,0x0003003e,0x00000c4a,0x00000c49,0x0004003d,0x00000008, + 0x00000c4b,0x000009e6,0x00050041,0x00000019,0x00000c4c,0x00000c46,0x000000e1,0x0003003e, + 0x00000c4c,0x00000c4b,0x0004003d,0x00000008,0x00000c4d,0x000009e6,0x00050041,0x00000019, + 0x00000c4e,0x00000c46,0x000000f4,0x0003003e,0x00000c4e,0x00000c4d,0x0004003d,0x0000002c, + 0x00000c4f,0x00000c46,0x0003003e,0x00000c47,0x00000c4f,0x0004003d,0x0000002c,0x00000a0f, + 0x00000c47,0x0003003e,0x000009e7,0x00000132,0x0004003d,0x00000008,0x00000c53,0x000009e7, + 0x00050041,0x00000019,0x00000c54,0x00000c50,0x000000de,0x0003003e,0x00000c54,0x00000c53, + 0x0004003d,0x00000008,0x00000c55,0x000009e7,0x00050041,0x00000019,0x00000c56,0x00000c50, + 0x000000e1,0x0003003e,0x00000c56,0x00000c55,0x0004003d,0x00000008,0x00000c57,0x000009e7, + 0x00050041,0x00000019,0x00000c58,0x00000c50,0x000000f4,0x0003003e,0x00000c58,0x00000c57, + 0x0004003d,0x0000002c,0x00000c59,0x00000c50,0x0003003e,0x00000c51,0x00000c59,0x0004003d, + 0x0000002c,0x00000a10,0x00000c51,0x0008000c,0x0000002c,0x00000a11,0x00000001,0x0000002b, + 0x00000a0e,0x00000a0f,0x00000a10,0x0003003e,0x000009bd,0x00000a11,0x0004003d,0x0000002c, + 0x00000a12,0x000009cd,0x0003003e,0x000009e8,0x00000a12,0x0004003d,0x0000002c,0x00000a13, + 0x000009bd,0x0003003e,0x000009e9,0x00000a13,0x0004003d,0x0000002c,0x00000a14,0x000009cd, + 0x0003003e,0x000009ea,0x00000a14,0x0004003d,0x0000002c,0x00000c65,0x000009e9,0x0003003e, + 0x00000c5b,0x00000c65,0x0004003d,0x0000002c,0x00000c7d,0x00000c5b,0x0007004f,0x00000022, + 0x00000c7e,0x00000c7d,0x00000c7d,0x00000000,0x00000001,0x0003003e,0x00000c7a,0x00000c7e, + 0x00050041,0x00000019,0x00000c85,0x00000c7a,0x000000de,0x0004003d,0x00000008,0x00000c86, + 0x00000c85,0x00050041,0x00000019,0x00000c87,0x00000c7a,0x000000e1,0x0004003d,0x00000008, + 0x00000c88,0x00000c87,0x0007000c,0x00000008,0x00000c89,0x00000001,0x00000028,0x00000c86, + 0x00000c88,0x0003003e,0x00000c83,0x00000c89,0x0004003d,0x00000008,0x00000c7f,0x00000c83, + 0x00050041,0x00000019,0x00000c80,0x00000c5b,0x000000f4,0x0004003d,0x00000008,0x00000c81, + 0x00000c80,0x0007000c,0x00000008,0x00000c82,0x00000001,0x00000028,0x00000c7f,0x00000c81, + 0x0003003e,0x00000c7b,0x00000c82,0x0004003d,0x00000008,0x00000c66,0x00000c7b,0x0004003d, + 0x0000002c,0x00000c67,0x000009e9,0x0003003e,0x00000c5c,0x00000c67,0x0004003d,0x0000002c, + 0x00000c8d,0x00000c5c,0x0007004f,0x00000022,0x00000c8e,0x00000c8d,0x00000c8d,0x00000000, + 0x00000001,0x0003003e,0x00000c8a,0x00000c8e,0x00050041,0x00000019,0x00000c95,0x00000c8a, + 0x000000de,0x0004003d,0x00000008,0x00000c96,0x00000c95,0x00050041,0x00000019,0x00000c97, + 0x00000c8a,0x000000e1,0x0004003d,0x00000008,0x00000c98,0x00000c97,0x0007000c,0x00000008, + 0x00000c99,0x00000001,0x00000025,0x00000c96,0x00000c98,0x0003003e,0x00000c93,0x00000c99, + 0x0004003d,0x00000008,0x00000c8f,0x00000c93,0x00050041,0x00000019,0x00000c90,0x00000c5c, + 0x000000f4,0x0004003d,0x00000008,0x00000c91,0x00000c90,0x0007000c,0x00000008,0x00000c92, + 0x00000001,0x00000025,0x00000c8f,0x00000c91,0x0003003e,0x00000c8b,0x00000c92,0x0004003d, + 0x00000008,0x00000c68,0x00000c8b,0x00050083,0x00000008,0x00000c69,0x00000c66,0x00000c68, + 0x0003003e,0x00000c5a,0x00000c69,0x0004003d,0x0000002c,0x00000c6a,0x000009e8,0x0003003e, + 0x00000c5d,0x00000c6a,0x0004003d,0x0000002c,0x00000c9d,0x00000c5d,0x0007004f,0x00000022, + 0x00000c9e,0x00000c9d,0x00000c9d,0x00000000,0x00000001,0x0003003e,0x00000c9a,0x00000c9e, + 0x00050041,0x00000019,0x00000ca5,0x00000c9a,0x000000de,0x0004003d,0x00000008,0x00000ca6, + 0x00000ca5,0x00050041,0x00000019,0x00000ca7,0x00000c9a,0x000000e1,0x0004003d,0x00000008, + 0x00000ca8,0x00000ca7,0x0007000c,0x00000008,0x00000ca9,0x00000001,0x00000025,0x00000ca6, + 0x00000ca8,0x0003003e,0x00000ca3,0x00000ca9,0x0004003d,0x00000008,0x00000c9f,0x00000ca3, + 0x00050041,0x00000019,0x00000ca0,0x00000c5d,0x000000f4,0x0004003d,0x00000008,0x00000ca1, + 0x00000ca0,0x0007000c,0x00000008,0x00000ca2,0x00000001,0x00000025,0x00000c9f,0x00000ca1, + 0x0003003e,0x00000c9b,0x00000ca2,0x0004003d,0x00000008,0x00000c6b,0x00000c9b,0x0004003d, + 0x0000002c,0x00000c6c,0x000009e8,0x00060050,0x0000002c,0x00000c6d,0x00000c6b,0x00000c6b, + 0x00000c6b,0x00050083,0x0000002c,0x00000c6e,0x00000c6c,0x00000c6d,0x0003003e,0x000009e8, + 0x00000c6e,0x0004003d,0x0000002c,0x00000c6f,0x000009e8,0x0003003e,0x00000c5f,0x00000c6f, + 0x0004003d,0x0000002c,0x00000cad,0x00000c5f,0x0007004f,0x00000022,0x00000cae,0x00000cad, + 0x00000cad,0x00000000,0x00000001,0x0003003e,0x00000caa,0x00000cae,0x00050041,0x00000019, + 0x00000cb5,0x00000caa,0x000000de,0x0004003d,0x00000008,0x00000cb6,0x00000cb5,0x00050041, + 0x00000019,0x00000cb7,0x00000caa,0x000000e1,0x0004003d,0x00000008,0x00000cb8,0x00000cb7, + 0x0007000c,0x00000008,0x00000cb9,0x00000001,0x00000028,0x00000cb6,0x00000cb8,0x0003003e, + 0x00000cb3,0x00000cb9,0x0004003d,0x00000008,0x00000caf,0x00000cb3,0x00050041,0x00000019, + 0x00000cb0,0x00000c5f,0x000000f4,0x0004003d,0x00000008,0x00000cb1,0x00000cb0,0x0007000c, + 0x00000008,0x00000cb2,0x00000001,0x00000028,0x00000caf,0x00000cb1,0x0003003e,0x00000cab, + 0x00000cb2,0x0004003d,0x00000008,0x00000c70,0x00000cab,0x0003003e,0x00000c5e,0x00000c70, + 0x0004003d,0x00000008,0x00000c71,0x00000c5a,0x0004003d,0x00000008,0x00000c72,0x00000c5e, + 0x0007000c,0x00000008,0x00000c73,0x00000001,0x00000028,0x0000025b,0x00000c72,0x00050088, + 0x00000008,0x00000c74,0x00000c71,0x00000c73,0x0003003e,0x00000c60,0x00000c74,0x0004003d, + 0x0000002c,0x00000c75,0x000009e8,0x0004003d,0x00000008,0x00000c76,0x00000c60,0x0005008e, + 0x0000002c,0x00000c77,0x00000c75,0x00000c76,0x0003003e,0x00000c61,0x00000c77,0x0004003d, + 0x0000002c,0x00000c78,0x000009ea,0x0003003e,0x00000c62,0x00000c78,0x0004003d,0x0000002c, + 0x00000cca,0x00000c62,0x0003003e,0x00000cbb,0x00000cca,0x0004003d,0x0000002c,0x00000cf0, + 0x00000cbb,0x0003003e,0x00000ceb,0x000002a3,0x0003003e,0x00000cec,0x000002a4,0x0003003e, + 0x00000ced,0x000002a5,0x0004003d,0x00000008,0x00000cf6,0x00000ceb,0x00050041,0x00000019, + 0x00000cf7,0x00000cf3,0x000000de,0x0003003e,0x00000cf7,0x00000cf6,0x0004003d,0x00000008, + 0x00000cf8,0x00000cec,0x00050041,0x00000019,0x00000cf9,0x00000cf3,0x000000e1,0x0003003e, + 0x00000cf9,0x00000cf8,0x0004003d,0x00000008,0x00000cfa,0x00000ced,0x00050041,0x00000019, + 0x00000cfb,0x00000cf3,0x000000f4,0x0003003e,0x00000cfb,0x00000cfa,0x0004003d,0x0000002c, + 0x00000cfc,0x00000cf3,0x0003003e,0x00000cf4,0x00000cfc,0x0004003d,0x0000002c,0x00000cf1, + 0x00000cf4,0x00050094,0x00000008,0x00000cf2,0x00000cf0,0x00000cf1,0x0003003e,0x00000cee, + 0x00000cf2,0x0004003d,0x00000008,0x00000ccb,0x00000cee,0x0003003e,0x00000cba,0x00000ccb, + 0x0004003d,0x0000002c,0x00000ccc,0x00000c61,0x0004003d,0x0000002c,0x00000ccd,0x00000c61, + 0x0003003e,0x00000cbd,0x00000ccd,0x0004003d,0x0000002c,0x00000d02,0x00000cbd,0x0003003e, + 0x00000cfd,0x000002a3,0x0003003e,0x00000cfe,0x000002a4,0x0003003e,0x00000cff,0x000002a5, + 0x0004003d,0x00000008,0x00000d08,0x00000cfd,0x00050041,0x00000019,0x00000d09,0x00000d05, + 0x000000de,0x0003003e,0x00000d09,0x00000d08,0x0004003d,0x00000008,0x00000d0a,0x00000cfe, + 0x00050041,0x00000019,0x00000d0b,0x00000d05,0x000000e1,0x0003003e,0x00000d0b,0x00000d0a, + 0x0004003d,0x00000008,0x00000d0c,0x00000cff,0x00050041,0x00000019,0x00000d0d,0x00000d05, + 0x000000f4,0x0003003e,0x00000d0d,0x00000d0c,0x0004003d,0x0000002c,0x00000d0e,0x00000d05, + 0x0003003e,0x00000d06,0x00000d0e,0x0004003d,0x0000002c,0x00000d03,0x00000d06,0x00050094, + 0x00000008,0x00000d04,0x00000d02,0x00000d03,0x0003003e,0x00000d00,0x00000d04,0x0004003d, + 0x00000008,0x00000cce,0x00000d00,0x00060050,0x0000002c,0x00000ccf,0x00000cce,0x00000cce, + 0x00000cce,0x00050083,0x0000002c,0x00000cd0,0x00000ccc,0x00000ccf,0x0003003e,0x00000cbc, + 0x00000cd0,0x0004003d,0x00000008,0x00000cd1,0x00000cba,0x00050083,0x00000008,0x00000cd2, + 0x00000132,0x00000cd1,0x0004003d,0x00000008,0x00000cd3,0x00000cba,0x0003003e,0x00000cbf, + 0x00000cd3,0x0003003e,0x00000cc0,0x00000cd2,0x0004003d,0x00000008,0x00000d12,0x00000cbf, + 0x00050041,0x00000019,0x00000d13,0x00000d0f,0x000000de,0x0003003e,0x00000d13,0x00000d12, + 0x0004003d,0x00000008,0x00000d14,0x00000cc0,0x00050041,0x00000019,0x00000d15,0x00000d0f, + 0x000000e1,0x0003003e,0x00000d15,0x00000d14,0x0004003d,0x00000022,0x00000d16,0x00000d0f, + 0x0003003e,0x00000d10,0x00000d16,0x0004003d,0x00000022,0x00000cd4,0x00000d10,0x0003003e, + 0x00000cc1,0x0000025b,0x0004003d,0x00000008,0x00000d1a,0x00000cc1,0x00050041,0x00000019, + 0x00000d1b,0x00000d17,0x000000de,0x0003003e,0x00000d1b,0x00000d1a,0x0004003d,0x00000008, + 0x00000d1c,0x00000cc1,0x00050041,0x00000019,0x00000d1d,0x00000d17,0x000000e1,0x0003003e, + 0x00000d1d,0x00000d1c,0x0004003d,0x00000022,0x00000d1e,0x00000d17,0x0003003e,0x00000d18, + 0x00000d1e,0x0004003d,0x00000022,0x00000cd5,0x00000d18,0x0004003d,0x0000002c,0x00000cd6, + 0x00000cbc,0x0003003e,0x00000cc2,0x00000cd6,0x0004003d,0x0000002c,0x00000d22,0x00000cc2, + 0x0007004f,0x00000022,0x00000d23,0x00000d22,0x00000d22,0x00000000,0x00000001,0x0003003e, + 0x00000d1f,0x00000d23,0x00050041,0x00000019,0x00000d2a,0x00000d1f,0x000000de,0x0004003d, + 0x00000008,0x00000d2b,0x00000d2a,0x00050041,0x00000019,0x00000d2c,0x00000d1f,0x000000e1, + 0x0004003d,0x00000008,0x00000d2d,0x00000d2c,0x0007000c,0x00000008,0x00000d2e,0x00000001, + 0x00000025,0x00000d2b,0x00000d2d,0x0003003e,0x00000d28,0x00000d2e,0x0004003d,0x00000008, + 0x00000d24,0x00000d28,0x00050041,0x00000019,0x00000d25,0x00000cc2,0x000000f4,0x0004003d, + 0x00000008,0x00000d26,0x00000d25,0x0007000c,0x00000008,0x00000d27,0x00000001,0x00000025, + 0x00000d24,0x00000d26,0x0003003e,0x00000d20,0x00000d27,0x0004003d,0x00000008,0x00000cd7, + 0x00000d20,0x0004007f,0x00000008,0x00000cd8,0x00000cd7,0x0004003d,0x0000002c,0x00000cd9, + 0x00000cbc,0x0003003e,0x00000cc3,0x00000cd9,0x0004003d,0x0000002c,0x00000d32,0x00000cc3, + 0x0007004f,0x00000022,0x00000d33,0x00000d32,0x00000d32,0x00000000,0x00000001,0x0003003e, + 0x00000d2f,0x00000d33,0x00050041,0x00000019,0x00000d3a,0x00000d2f,0x000000de,0x0004003d, + 0x00000008,0x00000d3b,0x00000d3a,0x00050041,0x00000019,0x00000d3c,0x00000d2f,0x000000e1, + 0x0004003d,0x00000008,0x00000d3d,0x00000d3c,0x0007000c,0x00000008,0x00000d3e,0x00000001, + 0x00000028,0x00000d3b,0x00000d3d,0x0003003e,0x00000d38,0x00000d3e,0x0004003d,0x00000008, + 0x00000d34,0x00000d38,0x00050041,0x00000019,0x00000d35,0x00000cc3,0x000000f4,0x0004003d, + 0x00000008,0x00000d36,0x00000d35,0x0007000c,0x00000008,0x00000d37,0x00000001,0x00000028, + 0x00000d34,0x00000d36,0x0003003e,0x00000d30,0x00000d37,0x0004003d,0x00000008,0x00000cda, + 0x00000d30,0x0003003e,0x00000cc4,0x00000cd8,0x0003003e,0x00000cc5,0x00000cda,0x0004003d, + 0x00000008,0x00000d42,0x00000cc4,0x00050041,0x00000019,0x00000d43,0x00000d3f,0x000000de, + 0x0003003e,0x00000d43,0x00000d42,0x0004003d,0x00000008,0x00000d44,0x00000cc5,0x00050041, + 0x00000019,0x00000d45,0x00000d3f,0x000000e1,0x0003003e,0x00000d45,0x00000d44,0x0004003d, + 0x00000022,0x00000d46,0x00000d3f,0x0003003e,0x00000d40,0x00000d46,0x0004003d,0x00000022, + 0x00000cdb,0x00000d40,0x0007000c,0x00000022,0x00000cdc,0x00000001,0x00000028,0x00000cd5, + 0x00000cdb,0x00050088,0x00000022,0x00000cdd,0x00000cd4,0x00000cdc,0x0003003e,0x00000cbe, + 0x00000cdd,0x0003003e,0x00000cc7,0x00000132,0x0004003d,0x00000008,0x00000d49,0x00000cc7, + 0x0003003e,0x00000d47,0x00000d49,0x0004003d,0x00000008,0x00000cde,0x00000d47,0x00050041, + 0x00000019,0x00000cdf,0x00000cbe,0x000000de,0x0004003d,0x00000008,0x00000ce0,0x00000cdf, + 0x00050041,0x00000019,0x00000ce1,0x00000cbe,0x000000e1,0x0004003d,0x00000008,0x00000ce2, + 0x00000ce1,0x0007000c,0x00000008,0x00000ce3,0x00000001,0x00000025,0x00000ce0,0x00000ce2, + 0x0007000c,0x00000008,0x00000ce4,0x00000001,0x00000025,0x00000cde,0x00000ce3,0x0003003e, + 0x00000cc6,0x00000ce4,0x0004003d,0x0000002c,0x00000ce5,0x00000cbc,0x0004003d,0x00000008, + 0x00000ce6,0x00000cc6,0x0005008e,0x0000002c,0x00000ce7,0x00000ce5,0x00000ce6,0x0004003d, + 0x00000008,0x00000ce8,0x00000cba,0x00060050,0x0000002c,0x00000ce9,0x00000ce8,0x00000ce8, + 0x00000ce8,0x00050081,0x0000002c,0x00000cea,0x00000ce7,0x00000ce9,0x0003003e,0x00000cc8, + 0x00000cea,0x0004003d,0x0000002c,0x00000c79,0x00000cc8,0x0003003e,0x00000c63,0x00000c79, + 0x0004003d,0x0000002c,0x00000a15,0x00000c63,0x0003003e,0x000009cf,0x00000a15,0x000200f9, + 0x00000a16,0x000200f8,0x00000a16,0x000200f9,0x00000aec,0x000200f8,0x00000a17,0x000300f7, + 0x00000a21,0x00000000,0x000400fa,0x000003fb,0x00000a18,0x00000a21,0x000200f8,0x00000a18, + 0x0004003d,0x0000002c,0x00000a19,0x000009bd,0x0003003e,0x000009e1,0x0000012d,0x0004003d, + 0x00000008,0x00000d4d,0x000009e1,0x00050041,0x00000019,0x00000d4e,0x00000d4a,0x000000de, + 0x0003003e,0x00000d4e,0x00000d4d,0x0004003d,0x00000008,0x00000d4f,0x000009e1,0x00050041, + 0x00000019,0x00000d50,0x00000d4a,0x000000e1,0x0003003e,0x00000d50,0x00000d4f,0x0004003d, + 0x00000008,0x00000d51,0x000009e1,0x00050041,0x00000019,0x00000d52,0x00000d4a,0x000000f4, + 0x0003003e,0x00000d52,0x00000d51,0x0004003d,0x0000002c,0x00000d53,0x00000d4a,0x0003003e, + 0x00000d4b,0x00000d53,0x0004003d,0x0000002c,0x00000a1a,0x00000d4b,0x0003003e,0x000009e2, + 0x00000132,0x0004003d,0x00000008,0x00000d57,0x000009e2,0x00050041,0x00000019,0x00000d58, + 0x00000d54,0x000000de,0x0003003e,0x00000d58,0x00000d57,0x0004003d,0x00000008,0x00000d59, + 0x000009e2,0x00050041,0x00000019,0x00000d5a,0x00000d54,0x000000e1,0x0003003e,0x00000d5a, + 0x00000d59,0x0004003d,0x00000008,0x00000d5b,0x000009e2,0x00050041,0x00000019,0x00000d5c, + 0x00000d54,0x000000f4,0x0003003e,0x00000d5c,0x00000d5b,0x0004003d,0x0000002c,0x00000d5d, + 0x00000d54,0x0003003e,0x00000d55,0x00000d5d,0x0004003d,0x0000002c,0x00000a1b,0x00000d55, + 0x0008000c,0x0000002c,0x00000a1c,0x00000001,0x0000002b,0x00000a19,0x00000a1a,0x00000a1b, + 0x0003003e,0x000009bd,0x00000a1c,0x0004003d,0x0000002c,0x00000a1d,0x000009bd,0x0003003e, + 0x000009e3,0x00000a1d,0x0004003d,0x0000002c,0x00000a1e,0x000009cd,0x0003003e,0x000009e4, + 0x00000a1e,0x0004003d,0x0000002c,0x00000a1f,0x000009cd,0x0003003e,0x000009e5,0x00000a1f, + 0x0004003d,0x0000002c,0x00000d69,0x000009e4,0x0003003e,0x00000d5f,0x00000d69,0x0004003d, + 0x0000002c,0x00000d81,0x00000d5f,0x0007004f,0x00000022,0x00000d82,0x00000d81,0x00000d81, + 0x00000000,0x00000001,0x0003003e,0x00000d7e,0x00000d82,0x00050041,0x00000019,0x00000d89, + 0x00000d7e,0x000000de,0x0004003d,0x00000008,0x00000d8a,0x00000d89,0x00050041,0x00000019, + 0x00000d8b,0x00000d7e,0x000000e1,0x0004003d,0x00000008,0x00000d8c,0x00000d8b,0x0007000c, + 0x00000008,0x00000d8d,0x00000001,0x00000028,0x00000d8a,0x00000d8c,0x0003003e,0x00000d87, + 0x00000d8d,0x0004003d,0x00000008,0x00000d83,0x00000d87,0x00050041,0x00000019,0x00000d84, + 0x00000d5f,0x000000f4,0x0004003d,0x00000008,0x00000d85,0x00000d84,0x0007000c,0x00000008, + 0x00000d86,0x00000001,0x00000028,0x00000d83,0x00000d85,0x0003003e,0x00000d7f,0x00000d86, + 0x0004003d,0x00000008,0x00000d6a,0x00000d7f,0x0004003d,0x0000002c,0x00000d6b,0x000009e4, + 0x0003003e,0x00000d60,0x00000d6b,0x0004003d,0x0000002c,0x00000d91,0x00000d60,0x0007004f, + 0x00000022,0x00000d92,0x00000d91,0x00000d91,0x00000000,0x00000001,0x0003003e,0x00000d8e, + 0x00000d92,0x00050041,0x00000019,0x00000d99,0x00000d8e,0x000000de,0x0004003d,0x00000008, + 0x00000d9a,0x00000d99,0x00050041,0x00000019,0x00000d9b,0x00000d8e,0x000000e1,0x0004003d, + 0x00000008,0x00000d9c,0x00000d9b,0x0007000c,0x00000008,0x00000d9d,0x00000001,0x00000025, + 0x00000d9a,0x00000d9c,0x0003003e,0x00000d97,0x00000d9d,0x0004003d,0x00000008,0x00000d93, + 0x00000d97,0x00050041,0x00000019,0x00000d94,0x00000d60,0x000000f4,0x0004003d,0x00000008, + 0x00000d95,0x00000d94,0x0007000c,0x00000008,0x00000d96,0x00000001,0x00000025,0x00000d93, + 0x00000d95,0x0003003e,0x00000d8f,0x00000d96,0x0004003d,0x00000008,0x00000d6c,0x00000d8f, + 0x00050083,0x00000008,0x00000d6d,0x00000d6a,0x00000d6c,0x0003003e,0x00000d5e,0x00000d6d, + 0x0004003d,0x0000002c,0x00000d6e,0x000009e3,0x0003003e,0x00000d61,0x00000d6e,0x0004003d, + 0x0000002c,0x00000da1,0x00000d61,0x0007004f,0x00000022,0x00000da2,0x00000da1,0x00000da1, + 0x00000000,0x00000001,0x0003003e,0x00000d9e,0x00000da2,0x00050041,0x00000019,0x00000da9, + 0x00000d9e,0x000000de,0x0004003d,0x00000008,0x00000daa,0x00000da9,0x00050041,0x00000019, + 0x00000dab,0x00000d9e,0x000000e1,0x0004003d,0x00000008,0x00000dac,0x00000dab,0x0007000c, + 0x00000008,0x00000dad,0x00000001,0x00000025,0x00000daa,0x00000dac,0x0003003e,0x00000da7, + 0x00000dad,0x0004003d,0x00000008,0x00000da3,0x00000da7,0x00050041,0x00000019,0x00000da4, + 0x00000d61,0x000000f4,0x0004003d,0x00000008,0x00000da5,0x00000da4,0x0007000c,0x00000008, + 0x00000da6,0x00000001,0x00000025,0x00000da3,0x00000da5,0x0003003e,0x00000d9f,0x00000da6, + 0x0004003d,0x00000008,0x00000d6f,0x00000d9f,0x0004003d,0x0000002c,0x00000d70,0x000009e3, + 0x00060050,0x0000002c,0x00000d71,0x00000d6f,0x00000d6f,0x00000d6f,0x00050083,0x0000002c, + 0x00000d72,0x00000d70,0x00000d71,0x0003003e,0x000009e3,0x00000d72,0x0004003d,0x0000002c, + 0x00000d73,0x000009e3,0x0003003e,0x00000d63,0x00000d73,0x0004003d,0x0000002c,0x00000db1, + 0x00000d63,0x0007004f,0x00000022,0x00000db2,0x00000db1,0x00000db1,0x00000000,0x00000001, + 0x0003003e,0x00000dae,0x00000db2,0x00050041,0x00000019,0x00000db9,0x00000dae,0x000000de, + 0x0004003d,0x00000008,0x00000dba,0x00000db9,0x00050041,0x00000019,0x00000dbb,0x00000dae, + 0x000000e1,0x0004003d,0x00000008,0x00000dbc,0x00000dbb,0x0007000c,0x00000008,0x00000dbd, + 0x00000001,0x00000028,0x00000dba,0x00000dbc,0x0003003e,0x00000db7,0x00000dbd,0x0004003d, + 0x00000008,0x00000db3,0x00000db7,0x00050041,0x00000019,0x00000db4,0x00000d63,0x000000f4, + 0x0004003d,0x00000008,0x00000db5,0x00000db4,0x0007000c,0x00000008,0x00000db6,0x00000001, + 0x00000028,0x00000db3,0x00000db5,0x0003003e,0x00000daf,0x00000db6,0x0004003d,0x00000008, + 0x00000d74,0x00000daf,0x0003003e,0x00000d62,0x00000d74,0x0004003d,0x00000008,0x00000d75, + 0x00000d5e,0x0004003d,0x00000008,0x00000d76,0x00000d62,0x0007000c,0x00000008,0x00000d77, + 0x00000001,0x00000028,0x0000025b,0x00000d76,0x00050088,0x00000008,0x00000d78,0x00000d75, + 0x00000d77,0x0003003e,0x00000d64,0x00000d78,0x0004003d,0x0000002c,0x00000d79,0x000009e3, + 0x0004003d,0x00000008,0x00000d7a,0x00000d64,0x0005008e,0x0000002c,0x00000d7b,0x00000d79, + 0x00000d7a,0x0003003e,0x00000d65,0x00000d7b,0x0004003d,0x0000002c,0x00000d7c,0x000009e5, + 0x0003003e,0x00000d66,0x00000d7c,0x0004003d,0x0000002c,0x00000dce,0x00000d66,0x0003003e, + 0x00000dbf,0x00000dce,0x0004003d,0x0000002c,0x00000df4,0x00000dbf,0x0003003e,0x00000def, + 0x000002a3,0x0003003e,0x00000df0,0x000002a4,0x0003003e,0x00000df1,0x000002a5,0x0004003d, + 0x00000008,0x00000dfa,0x00000def,0x00050041,0x00000019,0x00000dfb,0x00000df7,0x000000de, + 0x0003003e,0x00000dfb,0x00000dfa,0x0004003d,0x00000008,0x00000dfc,0x00000df0,0x00050041, + 0x00000019,0x00000dfd,0x00000df7,0x000000e1,0x0003003e,0x00000dfd,0x00000dfc,0x0004003d, + 0x00000008,0x00000dfe,0x00000df1,0x00050041,0x00000019,0x00000dff,0x00000df7,0x000000f4, + 0x0003003e,0x00000dff,0x00000dfe,0x0004003d,0x0000002c,0x00000e00,0x00000df7,0x0003003e, + 0x00000df8,0x00000e00,0x0004003d,0x0000002c,0x00000df5,0x00000df8,0x00050094,0x00000008, + 0x00000df6,0x00000df4,0x00000df5,0x0003003e,0x00000df2,0x00000df6,0x0004003d,0x00000008, + 0x00000dcf,0x00000df2,0x0003003e,0x00000dbe,0x00000dcf,0x0004003d,0x0000002c,0x00000dd0, + 0x00000d65,0x0004003d,0x0000002c,0x00000dd1,0x00000d65,0x0003003e,0x00000dc1,0x00000dd1, + 0x0004003d,0x0000002c,0x00000e06,0x00000dc1,0x0003003e,0x00000e01,0x000002a3,0x0003003e, + 0x00000e02,0x000002a4,0x0003003e,0x00000e03,0x000002a5,0x0004003d,0x00000008,0x00000e0c, + 0x00000e01,0x00050041,0x00000019,0x00000e0d,0x00000e09,0x000000de,0x0003003e,0x00000e0d, + 0x00000e0c,0x0004003d,0x00000008,0x00000e0e,0x00000e02,0x00050041,0x00000019,0x00000e0f, + 0x00000e09,0x000000e1,0x0003003e,0x00000e0f,0x00000e0e,0x0004003d,0x00000008,0x00000e10, + 0x00000e03,0x00050041,0x00000019,0x00000e11,0x00000e09,0x000000f4,0x0003003e,0x00000e11, + 0x00000e10,0x0004003d,0x0000002c,0x00000e12,0x00000e09,0x0003003e,0x00000e0a,0x00000e12, + 0x0004003d,0x0000002c,0x00000e07,0x00000e0a,0x00050094,0x00000008,0x00000e08,0x00000e06, + 0x00000e07,0x0003003e,0x00000e04,0x00000e08,0x0004003d,0x00000008,0x00000dd2,0x00000e04, + 0x00060050,0x0000002c,0x00000dd3,0x00000dd2,0x00000dd2,0x00000dd2,0x00050083,0x0000002c, + 0x00000dd4,0x00000dd0,0x00000dd3,0x0003003e,0x00000dc0,0x00000dd4,0x0004003d,0x00000008, + 0x00000dd5,0x00000dbe,0x00050083,0x00000008,0x00000dd6,0x00000132,0x00000dd5,0x0004003d, + 0x00000008,0x00000dd7,0x00000dbe,0x0003003e,0x00000dc3,0x00000dd7,0x0003003e,0x00000dc4, + 0x00000dd6,0x0004003d,0x00000008,0x00000e16,0x00000dc3,0x00050041,0x00000019,0x00000e17, + 0x00000e13,0x000000de,0x0003003e,0x00000e17,0x00000e16,0x0004003d,0x00000008,0x00000e18, + 0x00000dc4,0x00050041,0x00000019,0x00000e19,0x00000e13,0x000000e1,0x0003003e,0x00000e19, + 0x00000e18,0x0004003d,0x00000022,0x00000e1a,0x00000e13,0x0003003e,0x00000e14,0x00000e1a, + 0x0004003d,0x00000022,0x00000dd8,0x00000e14,0x0003003e,0x00000dc5,0x0000025b,0x0004003d, + 0x00000008,0x00000e1e,0x00000dc5,0x00050041,0x00000019,0x00000e1f,0x00000e1b,0x000000de, + 0x0003003e,0x00000e1f,0x00000e1e,0x0004003d,0x00000008,0x00000e20,0x00000dc5,0x00050041, + 0x00000019,0x00000e21,0x00000e1b,0x000000e1,0x0003003e,0x00000e21,0x00000e20,0x0004003d, + 0x00000022,0x00000e22,0x00000e1b,0x0003003e,0x00000e1c,0x00000e22,0x0004003d,0x00000022, + 0x00000dd9,0x00000e1c,0x0004003d,0x0000002c,0x00000dda,0x00000dc0,0x0003003e,0x00000dc6, + 0x00000dda,0x0004003d,0x0000002c,0x00000e26,0x00000dc6,0x0007004f,0x00000022,0x00000e27, + 0x00000e26,0x00000e26,0x00000000,0x00000001,0x0003003e,0x00000e23,0x00000e27,0x00050041, + 0x00000019,0x00000e2e,0x00000e23,0x000000de,0x0004003d,0x00000008,0x00000e2f,0x00000e2e, + 0x00050041,0x00000019,0x00000e30,0x00000e23,0x000000e1,0x0004003d,0x00000008,0x00000e31, + 0x00000e30,0x0007000c,0x00000008,0x00000e32,0x00000001,0x00000025,0x00000e2f,0x00000e31, + 0x0003003e,0x00000e2c,0x00000e32,0x0004003d,0x00000008,0x00000e28,0x00000e2c,0x00050041, + 0x00000019,0x00000e29,0x00000dc6,0x000000f4,0x0004003d,0x00000008,0x00000e2a,0x00000e29, + 0x0007000c,0x00000008,0x00000e2b,0x00000001,0x00000025,0x00000e28,0x00000e2a,0x0003003e, + 0x00000e24,0x00000e2b,0x0004003d,0x00000008,0x00000ddb,0x00000e24,0x0004007f,0x00000008, + 0x00000ddc,0x00000ddb,0x0004003d,0x0000002c,0x00000ddd,0x00000dc0,0x0003003e,0x00000dc7, + 0x00000ddd,0x0004003d,0x0000002c,0x00000e36,0x00000dc7,0x0007004f,0x00000022,0x00000e37, + 0x00000e36,0x00000e36,0x00000000,0x00000001,0x0003003e,0x00000e33,0x00000e37,0x00050041, + 0x00000019,0x00000e3e,0x00000e33,0x000000de,0x0004003d,0x00000008,0x00000e3f,0x00000e3e, + 0x00050041,0x00000019,0x00000e40,0x00000e33,0x000000e1,0x0004003d,0x00000008,0x00000e41, + 0x00000e40,0x0007000c,0x00000008,0x00000e42,0x00000001,0x00000028,0x00000e3f,0x00000e41, + 0x0003003e,0x00000e3c,0x00000e42,0x0004003d,0x00000008,0x00000e38,0x00000e3c,0x00050041, + 0x00000019,0x00000e39,0x00000dc7,0x000000f4,0x0004003d,0x00000008,0x00000e3a,0x00000e39, + 0x0007000c,0x00000008,0x00000e3b,0x00000001,0x00000028,0x00000e38,0x00000e3a,0x0003003e, + 0x00000e34,0x00000e3b,0x0004003d,0x00000008,0x00000dde,0x00000e34,0x0003003e,0x00000dc8, + 0x00000ddc,0x0003003e,0x00000dc9,0x00000dde,0x0004003d,0x00000008,0x00000e46,0x00000dc8, + 0x00050041,0x00000019,0x00000e47,0x00000e43,0x000000de,0x0003003e,0x00000e47,0x00000e46, + 0x0004003d,0x00000008,0x00000e48,0x00000dc9,0x00050041,0x00000019,0x00000e49,0x00000e43, + 0x000000e1,0x0003003e,0x00000e49,0x00000e48,0x0004003d,0x00000022,0x00000e4a,0x00000e43, + 0x0003003e,0x00000e44,0x00000e4a,0x0004003d,0x00000022,0x00000ddf,0x00000e44,0x0007000c, + 0x00000022,0x00000de0,0x00000001,0x00000028,0x00000dd9,0x00000ddf,0x00050088,0x00000022, + 0x00000de1,0x00000dd8,0x00000de0,0x0003003e,0x00000dc2,0x00000de1,0x0003003e,0x00000dcb, + 0x00000132,0x0004003d,0x00000008,0x00000e4d,0x00000dcb,0x0003003e,0x00000e4b,0x00000e4d, + 0x0004003d,0x00000008,0x00000de2,0x00000e4b,0x00050041,0x00000019,0x00000de3,0x00000dc2, + 0x000000de,0x0004003d,0x00000008,0x00000de4,0x00000de3,0x00050041,0x00000019,0x00000de5, + 0x00000dc2,0x000000e1,0x0004003d,0x00000008,0x00000de6,0x00000de5,0x0007000c,0x00000008, + 0x00000de7,0x00000001,0x00000025,0x00000de4,0x00000de6,0x0007000c,0x00000008,0x00000de8, + 0x00000001,0x00000025,0x00000de2,0x00000de7,0x0003003e,0x00000dca,0x00000de8,0x0004003d, + 0x0000002c,0x00000de9,0x00000dc0,0x0004003d,0x00000008,0x00000dea,0x00000dca,0x0005008e, + 0x0000002c,0x00000deb,0x00000de9,0x00000dea,0x0004003d,0x00000008,0x00000dec,0x00000dbe, + 0x00060050,0x0000002c,0x00000ded,0x00000dec,0x00000dec,0x00000dec,0x00050081,0x0000002c, + 0x00000dee,0x00000deb,0x00000ded,0x0003003e,0x00000dcc,0x00000dee,0x0004003d,0x0000002c, + 0x00000d7d,0x00000dcc,0x0003003e,0x00000d67,0x00000d7d,0x0004003d,0x0000002c,0x00000a20, + 0x00000d67,0x0003003e,0x000009cf,0x00000a20,0x000200f9,0x00000a21,0x000200f8,0x00000a21, + 0x000200f9,0x00000aec,0x000200f8,0x00000a22,0x0004003d,0x0000002c,0x00000a23,0x000009bd, + 0x0004003d,0x0000002c,0x00000a24,0x000009cd,0x00050081,0x0000002c,0x00000a25,0x00000a23, + 0x00000a24,0x0004003d,0x0000002c,0x00000a26,0x000009bd,0x0005008e,0x0000002c,0x00000a27, + 0x00000a26,0x00000324,0x0004003d,0x0000002c,0x00000a28,0x000009cd,0x00050085,0x0000002c, + 0x00000a29,0x00000a27,0x00000a28,0x00050083,0x0000002c,0x00000a2a,0x00000a25,0x00000a29, + 0x0003003e,0x000009cf,0x00000a2a,0x000200f9,0x00000aec,0x000200f8,0x00000a2b,0x0004003d, + 0x0000002c,0x00000a2c,0x000009cd,0x0004003d,0x0000002c,0x00000a2d,0x000009bd,0x00050083, + 0x0000002c,0x00000a2e,0x00000a2c,0x00000a2d,0x0006000c,0x0000002c,0x00000a2f,0x00000001, + 0x00000004,0x00000a2e,0x0003003e,0x000009cf,0x00000a2f,0x000200f9,0x00000aec,0x000200f8, + 0x00000a30,0x0003003e,0x000009e0,0x000003ad,0x000200f9,0x00000a31,0x000200f8,0x00000a31, + 0x0004003d,0x0000000d,0x00000a33,0x000009e0,0x000500b1,0x0000006a,0x00000a34,0x00000a33, + 0x000003b4,0x000400f6,0x00000a60,0x00000a5d,0x00000000,0x000400fa,0x00000a34,0x00000a35, + 0x00000a60,0x000200f8,0x00000a35,0x0004003d,0x0000000d,0x00000a36,0x000009e0,0x00050041, + 0x00000019,0x00000a37,0x000009bd,0x00000a36,0x0004003d,0x00000008,0x00000a38,0x00000a37, + 0x000500bc,0x0000006a,0x00000a39,0x00000a38,0x0000029b,0x000300f7,0x00000a5c,0x00000000, + 0x000400fa,0x00000a39,0x00000a55,0x00000a3a,0x000200f8,0x00000a3a,0x0004003d,0x0000000d, + 0x00000a3b,0x000009e0,0x00050041,0x00000019,0x00000a3c,0x000009cd,0x00000a3b,0x0004003d, + 0x00000008,0x00000a3d,0x00000a3c,0x000500bc,0x0000006a,0x00000a3e,0x00000a3d,0x000001c7, + 0x000300f7,0x00000a54,0x00000000,0x000400fa,0x00000a3e,0x00000a47,0x00000a3f,0x000200f8, + 0x00000a3f,0x0004003d,0x0000000d,0x00000a40,0x000009e0,0x0004003d,0x0000000d,0x00000a41, + 0x000009e0,0x00050041,0x00000019,0x00000a42,0x000009cd,0x00000a41,0x0004003d,0x00000008, + 0x00000a43,0x00000a42,0x0006000c,0x00000008,0x00000a44,0x00000001,0x00000020,0x00000a43, + 0x00050083,0x00000008,0x00000a45,0x00000a44,0x00000132,0x00050041,0x00000019,0x00000a46, + 0x000009cf,0x00000a40,0x0003003e,0x00000a46,0x00000a45,0x000200f9,0x00000a54,0x000200f8, + 0x00000a47,0x0004003d,0x0000000d,0x00000a48,0x000009e0,0x0004003d,0x0000000d,0x00000a49, + 0x000009e0,0x00050041,0x00000019,0x00000a4a,0x000009cd,0x00000a49,0x0004003d,0x00000008, + 0x00000a4b,0x00000a4a,0x00050085,0x00000008,0x00000a4c,0x000003ca,0x00000a4b,0x00050083, + 0x00000008,0x00000a4d,0x00000a4c,0x000003cf,0x0004003d,0x0000000d,0x00000a4e,0x000009e0, + 0x00050041,0x00000019,0x00000a4f,0x000009cd,0x00000a4e,0x0004003d,0x00000008,0x00000a50, + 0x00000a4f,0x00050085,0x00000008,0x00000a51,0x00000a4d,0x00000a50,0x00050081,0x00000008, + 0x00000a52,0x00000a51,0x00000235,0x00050041,0x00000019,0x00000a53,0x000009cf,0x00000a48, + 0x0003003e,0x00000a53,0x00000a52,0x000200f9,0x00000a54,0x000200f8,0x00000a54,0x000200f9, + 0x00000a5c,0x000200f8,0x00000a55,0x0004003d,0x0000000d,0x00000a56,0x000009e0,0x0004003d, + 0x0000000d,0x00000a57,0x000009e0,0x00050041,0x00000019,0x00000a58,0x000009cd,0x00000a57, + 0x0004003d,0x00000008,0x00000a59,0x00000a58,0x00050083,0x00000008,0x00000a5a,0x00000132, + 0x00000a59,0x00050041,0x00000019,0x00000a5b,0x000009cf,0x00000a56,0x0003003e,0x00000a5b, + 0x00000a5a,0x000200f9,0x00000a5c,0x000200f8,0x00000a5c,0x000200f9,0x00000a5d,0x000200f8, + 0x00000a5d,0x0004003d,0x0000000d,0x00000a5e,0x000009e0,0x00050080,0x0000000d,0x00000a5f, + 0x00000a5e,0x000003e0,0x0003003e,0x000009e0,0x00000a5f,0x000200f9,0x00000a31,0x000200f8, + 0x00000a60,0x0004003d,0x0000002c,0x00000a61,0x000009cd,0x0004003d,0x0000002c,0x00000a62, + 0x000009cd,0x0004003d,0x0000002c,0x00000a63,0x000009bd,0x0005008e,0x0000002c,0x00000a64, + 0x00000a63,0x00000324,0x00050083,0x0000002c,0x00000a65,0x00000a64,0x000006c1,0x00050085, + 0x0000002c,0x00000a66,0x00000a62,0x00000a65,0x0004003d,0x0000002c,0x00000a67,0x000009cf, + 0x00050085,0x0000002c,0x00000a68,0x00000a66,0x00000a67,0x00050081,0x0000002c,0x00000a69, + 0x00000a61,0x00000a68,0x0003003e,0x000009cf,0x00000a69,0x000200f9,0x00000aec,0x000200f8, + 0x00000a6a,0x0004003d,0x0000002c,0x00000a6b,0x000009bd,0x0004003d,0x0000002c,0x00000a6c, + 0x000009cd,0x00050085,0x0000002c,0x00000a6d,0x00000a6b,0x00000a6c,0x0003003e,0x000009de, + 0x00000a6d,0x0004003d,0x0000002c,0x00000a6e,0x000009de,0x0004003d,0x0000002c,0x00000a6f, + 0x000009bd,0x0004003d,0x0000002c,0x00000a70,0x000009cd,0x00050081,0x0000002c,0x00000a71, + 0x00000a6f,0x00000a70,0x0004003d,0x0000002c,0x00000a72,0x000009de,0x00050083,0x0000002c, + 0x00000a73,0x00000a71,0x00000a72,0x00050083,0x0000002c,0x00000a74,0x00000a73,0x000006c2, + 0x0004003d,0x0000002c,0x00000a75,0x000009bd,0x0003003e,0x000009df,0x0000029b,0x0004003d, + 0x00000008,0x00000e51,0x000009df,0x00050041,0x00000019,0x00000e52,0x00000e4e,0x000000de, + 0x0003003e,0x00000e52,0x00000e51,0x0004003d,0x00000008,0x00000e53,0x000009df,0x00050041, + 0x00000019,0x00000e54,0x00000e4e,0x000000e1,0x0003003e,0x00000e54,0x00000e53,0x0004003d, + 0x00000008,0x00000e55,0x000009df,0x00050041,0x00000019,0x00000e56,0x00000e4e,0x000000f4, + 0x0003003e,0x00000e56,0x00000e55,0x0004003d,0x0000002c,0x00000e57,0x00000e4e,0x0003003e, + 0x00000e4f,0x00000e57,0x0004003d,0x0000002c,0x00000a76,0x00000e4f,0x000500ba,0x00000330, + 0x00000a77,0x00000a75,0x00000a76,0x000600a9,0x0000002c,0x00000a78,0x00000a77,0x00000a74, + 0x00000a6e,0x0005008e,0x0000002c,0x00000a79,0x00000a78,0x00000324,0x0003003e,0x000009cf, + 0x00000a79,0x000200f9,0x00000aec,0x000200f8,0x00000a7a,0x0004003d,0x0000002c,0x00000a7b, + 0x000009bd,0x0003003e,0x000009d8,0x0000012d,0x0004003d,0x00000008,0x00000e5b,0x000009d8, + 0x00050041,0x00000019,0x00000e5c,0x00000e58,0x000000de,0x0003003e,0x00000e5c,0x00000e5b, + 0x0004003d,0x00000008,0x00000e5d,0x000009d8,0x00050041,0x00000019,0x00000e5e,0x00000e58, + 0x000000e1,0x0003003e,0x00000e5e,0x00000e5d,0x0004003d,0x00000008,0x00000e5f,0x000009d8, + 0x00050041,0x00000019,0x00000e60,0x00000e58,0x000000f4,0x0003003e,0x00000e60,0x00000e5f, + 0x0004003d,0x0000002c,0x00000e61,0x00000e58,0x0003003e,0x00000e59,0x00000e61,0x0004003d, + 0x0000002c,0x00000a7c,0x00000e59,0x0003003e,0x000009d9,0x00000132,0x0004003d,0x00000008, + 0x00000e65,0x000009d9,0x00050041,0x00000019,0x00000e66,0x00000e62,0x000000de,0x0003003e, + 0x00000e66,0x00000e65,0x0004003d,0x00000008,0x00000e67,0x000009d9,0x00050041,0x00000019, + 0x00000e68,0x00000e62,0x000000e1,0x0003003e,0x00000e68,0x00000e67,0x0004003d,0x00000008, + 0x00000e69,0x000009d9,0x00050041,0x00000019,0x00000e6a,0x00000e62,0x000000f4,0x0003003e, + 0x00000e6a,0x00000e69,0x0004003d,0x0000002c,0x00000e6b,0x00000e62,0x0003003e,0x00000e63, + 0x00000e6b,0x0004003d,0x0000002c,0x00000a7d,0x00000e63,0x0008000c,0x0000002c,0x00000a7e, + 0x00000001,0x0000002b,0x00000a7b,0x00000a7c,0x00000a7d,0x0003003e,0x000009bd,0x00000a7e, + 0x0004003d,0x00000013,0x00000a7f,0x000009be,0x0008004f,0x0000002c,0x00000a80,0x00000a7f, + 0x00000a7f,0x00000000,0x00000001,0x00000002,0x0003003e,0x000009da,0x0000012d,0x0004003d, + 0x00000008,0x00000e6f,0x000009da,0x00050041,0x00000019,0x00000e70,0x00000e6c,0x000000de, + 0x0003003e,0x00000e70,0x00000e6f,0x0004003d,0x00000008,0x00000e71,0x000009da,0x00050041, + 0x00000019,0x00000e72,0x00000e6c,0x000000e1,0x0003003e,0x00000e72,0x00000e71,0x0004003d, + 0x00000008,0x00000e73,0x000009da,0x00050041,0x00000019,0x00000e74,0x00000e6c,0x000000f4, + 0x0003003e,0x00000e74,0x00000e73,0x0004003d,0x0000002c,0x00000e75,0x00000e6c,0x0003003e, + 0x00000e6d,0x00000e75,0x0004003d,0x0000002c,0x00000a81,0x00000e6d,0x0004003d,0x00000013, + 0x00000a82,0x000009be,0x0008004f,0x0000002c,0x00000a83,0x00000a82,0x00000a82,0x00000003, + 0x00000003,0x00000003,0x0008000c,0x0000002c,0x00000a84,0x00000001,0x0000002b,0x00000a80, + 0x00000a81,0x00000a83,0x00050041,0x00000019,0x00000a85,0x000009be,0x000000de,0x00050051, + 0x00000008,0x00000a86,0x00000a84,0x00000000,0x0003003e,0x00000a85,0x00000a86,0x00050041, + 0x00000019,0x00000a87,0x000009be,0x000000e1,0x00050051,0x00000008,0x00000a88,0x00000a84, + 0x00000001,0x0003003e,0x00000a87,0x00000a88,0x00050041,0x00000019,0x00000a89,0x000009be, + 0x000000f4,0x00050051,0x00000008,0x00000a8a,0x00000a84,0x00000002,0x0003003e,0x00000a89, + 0x00000a8a,0x00050041,0x00000019,0x00000a8b,0x000009be,0x0000010b,0x0004003d,0x00000008, + 0x00000a8c,0x00000a8b,0x000500b4,0x0000006a,0x00000a8d,0x00000a8c,0x0000012d,0x000300f7, + 0x00000a90,0x00000000,0x000400fa,0x00000a8d,0x00000a8e,0x00000a90,0x000200f8,0x00000a8e, + 0x0003003e,0x00000a8b,0x00000132,0x000200f9,0x00000a90,0x000200f8,0x00000a90,0x0004003d, + 0x00000008,0x00000a92,0x00000a8b,0x0004003d,0x00000013,0x00000a93,0x000009be,0x0008004f, + 0x0000002c,0x00000a94,0x00000a93,0x00000a93,0x00000000,0x00000001,0x00000002,0x00060050, + 0x0000002c,0x00000a95,0x00000a92,0x00000a92,0x00000a92,0x00050083,0x0000002c,0x00000a96, + 0x00000a95,0x00000a94,0x0003003e,0x000009db,0x00000a96,0x0003003e,0x000009dc,0x00000132, + 0x0004003d,0x00000008,0x00000e79,0x000009dc,0x00050041,0x00000019,0x00000e7a,0x00000e76, + 0x000000de,0x0003003e,0x00000e7a,0x00000e79,0x0004003d,0x00000008,0x00000e7b,0x000009dc, + 0x00050041,0x00000019,0x00000e7c,0x00000e76,0x000000e1,0x0003003e,0x00000e7c,0x00000e7b, + 0x0004003d,0x00000008,0x00000e7d,0x000009dc,0x00050041,0x00000019,0x00000e7e,0x00000e76, + 0x000000f4,0x0003003e,0x00000e7e,0x00000e7d,0x0004003d,0x0000002c,0x00000e7f,0x00000e76, + 0x0003003e,0x00000e77,0x00000e7f,0x0004003d,0x0000002c,0x00000a97,0x00000e77,0x0004003d, + 0x0000002c,0x00000a98,0x000009db,0x0004003d,0x0000002c,0x00000a99,0x000009bd,0x0004003d, + 0x00000008,0x00000a9b,0x00000a8b,0x0005008e,0x0000002c,0x00000a9c,0x00000a99,0x00000a9b, + 0x00050088,0x0000002c,0x00000a9d,0x00000a98,0x00000a9c,0x0007000c,0x0000002c,0x00000a9e, + 0x00000001,0x00000025,0x00000a97,0x00000a9d,0x0004003d,0x0000002c,0x00000a9f,0x000009db, + 0x0006000c,0x0000002c,0x00000aa0,0x00000001,0x00000006,0x00000a9f,0x0004003d,0x0000002c, + 0x00000aa1,0x000009bd,0x0003003e,0x000009dd,0x0000012d,0x0004003d,0x00000008,0x00000e83, + 0x000009dd,0x00050041,0x00000019,0x00000e84,0x00000e80,0x000000de,0x0003003e,0x00000e84, + 0x00000e83,0x0004003d,0x00000008,0x00000e85,0x000009dd,0x00050041,0x00000019,0x00000e86, + 0x00000e80,0x000000e1,0x0003003e,0x00000e86,0x00000e85,0x0004003d,0x00000008,0x00000e87, + 0x000009dd,0x00050041,0x00000019,0x00000e88,0x00000e80,0x000000f4,0x0003003e,0x00000e88, + 0x00000e87,0x0004003d,0x0000002c,0x00000e89,0x00000e80,0x0003003e,0x00000e81,0x00000e89, + 0x0004003d,0x0000002c,0x00000aa2,0x00000e81,0x000500b4,0x00000330,0x00000aa3,0x00000aa1, + 0x00000aa2,0x000600a9,0x0000002c,0x00000aa4,0x00000aa3,0x00000aa0,0x00000a9e,0x00050083, + 0x0000002c,0x00000aa5,0x000006c1,0x00000aa4,0x0003003e,0x000009cf,0x00000aa5,0x000200f9, + 0x00000aec,0x000200f8,0x00000aa6,0x0004003d,0x00000013,0x00000aa7,0x000009be,0x0008004f, + 0x0000002c,0x00000aa8,0x00000aa7,0x00000aa7,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x000009d2,0x0000012d,0x0004003d,0x00000008,0x00000e8d,0x000009d2,0x00050041,0x00000019, + 0x00000e8e,0x00000e8a,0x000000de,0x0003003e,0x00000e8e,0x00000e8d,0x0004003d,0x00000008, + 0x00000e8f,0x000009d2,0x00050041,0x00000019,0x00000e90,0x00000e8a,0x000000e1,0x0003003e, + 0x00000e90,0x00000e8f,0x0004003d,0x00000008,0x00000e91,0x000009d2,0x00050041,0x00000019, + 0x00000e92,0x00000e8a,0x000000f4,0x0003003e,0x00000e92,0x00000e91,0x0004003d,0x0000002c, + 0x00000e93,0x00000e8a,0x0003003e,0x00000e8b,0x00000e93,0x0004003d,0x0000002c,0x00000aa9, + 0x00000e8b,0x0004003d,0x00000013,0x00000aaa,0x000009be,0x0008004f,0x0000002c,0x00000aab, + 0x00000aaa,0x00000aaa,0x00000003,0x00000003,0x00000003,0x0008000c,0x0000002c,0x00000aac, + 0x00000001,0x0000002b,0x00000aa8,0x00000aa9,0x00000aab,0x00050041,0x00000019,0x00000aad, + 0x000009be,0x000000de,0x00050051,0x00000008,0x00000aae,0x00000aac,0x00000000,0x0003003e, + 0x00000aad,0x00000aae,0x00050041,0x00000019,0x00000aaf,0x000009be,0x000000e1,0x00050051, + 0x00000008,0x00000ab0,0x00000aac,0x00000001,0x0003003e,0x00000aaf,0x00000ab0,0x00050041, + 0x00000019,0x00000ab1,0x000009be,0x000000f4,0x00050051,0x00000008,0x00000ab2,0x00000aac, + 0x00000002,0x0003003e,0x00000ab1,0x00000ab2,0x0004003d,0x0000002c,0x00000ab3,0x000009bd, + 0x00050083,0x0000002c,0x00000ab4,0x000006c1,0x00000ab3,0x0003003e,0x000009d4,0x0000012d, + 0x0004003d,0x00000008,0x00000e97,0x000009d4,0x00050041,0x00000019,0x00000e98,0x00000e94, + 0x000000de,0x0003003e,0x00000e98,0x00000e97,0x0004003d,0x00000008,0x00000e99,0x000009d4, + 0x00050041,0x00000019,0x00000e9a,0x00000e94,0x000000e1,0x0003003e,0x00000e9a,0x00000e99, + 0x0004003d,0x00000008,0x00000e9b,0x000009d4,0x00050041,0x00000019,0x00000e9c,0x00000e94, + 0x000000f4,0x0003003e,0x00000e9c,0x00000e9b,0x0004003d,0x0000002c,0x00000e9d,0x00000e94, + 0x0003003e,0x00000e95,0x00000e9d,0x0004003d,0x0000002c,0x00000ab5,0x00000e95,0x0003003e, + 0x000009d5,0x00000132,0x0004003d,0x00000008,0x00000ea1,0x000009d5,0x00050041,0x00000019, + 0x00000ea2,0x00000e9e,0x000000de,0x0003003e,0x00000ea2,0x00000ea1,0x0004003d,0x00000008, + 0x00000ea3,0x000009d5,0x00050041,0x00000019,0x00000ea4,0x00000e9e,0x000000e1,0x0003003e, + 0x00000ea4,0x00000ea3,0x0004003d,0x00000008,0x00000ea5,0x000009d5,0x00050041,0x00000019, + 0x00000ea6,0x00000e9e,0x000000f4,0x0003003e,0x00000ea6,0x00000ea5,0x0004003d,0x0000002c, + 0x00000ea7,0x00000e9e,0x0003003e,0x00000e9f,0x00000ea7,0x0004003d,0x0000002c,0x00000ab6, + 0x00000e9f,0x0008000c,0x0000002c,0x00000ab7,0x00000001,0x0000002b,0x00000ab4,0x00000ab5, + 0x00000ab6,0x00050041,0x00000019,0x00000ab8,0x000009be,0x0000010b,0x0004003d,0x00000008, + 0x00000ab9,0x00000ab8,0x0005008e,0x0000002c,0x00000aba,0x00000ab7,0x00000ab9,0x0003003e, + 0x000009d3,0x00000aba,0x0003003e,0x000009d6,0x00000132,0x0004003d,0x00000008,0x00000eab, + 0x000009d6,0x00050041,0x00000019,0x00000eac,0x00000ea8,0x000000de,0x0003003e,0x00000eac, + 0x00000eab,0x0004003d,0x00000008,0x00000ead,0x000009d6,0x00050041,0x00000019,0x00000eae, + 0x00000ea8,0x000000e1,0x0003003e,0x00000eae,0x00000ead,0x0004003d,0x00000008,0x00000eaf, + 0x000009d6,0x00050041,0x00000019,0x00000eb0,0x00000ea8,0x000000f4,0x0003003e,0x00000eb0, + 0x00000eaf,0x0004003d,0x0000002c,0x00000eb1,0x00000ea8,0x0003003e,0x00000ea9,0x00000eb1, + 0x0004003d,0x0000002c,0x00000abb,0x00000ea9,0x0004003d,0x00000013,0x00000abc,0x000009be, + 0x0008004f,0x0000002c,0x00000abd,0x00000abc,0x00000abc,0x00000000,0x00000001,0x00000002, + 0x0004003d,0x0000002c,0x00000abe,0x000009d3,0x00050088,0x0000002c,0x00000abf,0x00000abd, + 0x00000abe,0x0007000c,0x0000002c,0x00000ac0,0x00000001,0x00000025,0x00000abb,0x00000abf, + 0x0004003d,0x00000013,0x00000ac1,0x000009be,0x0008004f,0x0000002c,0x00000ac2,0x00000ac1, + 0x00000ac1,0x00000000,0x00000001,0x00000002,0x0006000c,0x0000002c,0x00000ac3,0x00000001, + 0x00000006,0x00000ac2,0x0004003d,0x0000002c,0x00000ac4,0x000009d3,0x0003003e,0x000009d7, + 0x0000012d,0x0004003d,0x00000008,0x00000eb5,0x000009d7,0x00050041,0x00000019,0x00000eb6, + 0x00000eb2,0x000000de,0x0003003e,0x00000eb6,0x00000eb5,0x0004003d,0x00000008,0x00000eb7, + 0x000009d7,0x00050041,0x00000019,0x00000eb8,0x00000eb2,0x000000e1,0x0003003e,0x00000eb8, + 0x00000eb7,0x0004003d,0x00000008,0x00000eb9,0x000009d7,0x00050041,0x00000019,0x00000eba, + 0x00000eb2,0x000000f4,0x0003003e,0x00000eba,0x00000eb9,0x0004003d,0x0000002c,0x00000ebb, + 0x00000eb2,0x0003003e,0x00000eb3,0x00000ebb,0x0004003d,0x0000002c,0x00000ac5,0x00000eb3, + 0x000500b4,0x00000330,0x00000ac6,0x00000ac4,0x00000ac5,0x000600a9,0x0000002c,0x00000ac7, + 0x00000ac6,0x00000ac3,0x00000ac0,0x0003003e,0x000009cf,0x00000ac7,0x000200f9,0x00000aec, + 0x000200f8,0x00000ac8,0x0004003d,0x0000002c,0x00000ac9,0x000009bd,0x0004003d,0x0000002c, + 0x00000aca,0x000009cd,0x0007000c,0x0000002c,0x00000acb,0x00000001,0x00000028,0x00000ac9, + 0x00000aca,0x0003003e,0x000009cf,0x00000acb,0x000200f9,0x00000aec,0x000200f8,0x00000acc, + 0x0004003d,0x0000002c,0x00000acd,0x000009bd,0x0004003d,0x0000002c,0x00000ace,0x000009cd, + 0x0007000c,0x0000002c,0x00000acf,0x00000001,0x00000025,0x00000acd,0x00000ace,0x0003003e, + 0x000009cf,0x00000acf,0x000200f9,0x00000aec,0x000200f8,0x00000ad0,0x0004003d,0x0000002c, + 0x00000ad1,0x000009bd,0x0004003d,0x0000002c,0x00000ad2,0x000009cd,0x00050085,0x0000002c, + 0x00000ad3,0x00000ad1,0x00000ad2,0x0003003e,0x000009d0,0x00000ad3,0x0004003d,0x0000002c, + 0x00000ad4,0x000009d0,0x0004003d,0x0000002c,0x00000ad5,0x000009bd,0x0004003d,0x0000002c, + 0x00000ad6,0x000009cd,0x00050081,0x0000002c,0x00000ad7,0x00000ad5,0x00000ad6,0x0004003d, + 0x0000002c,0x00000ad8,0x000009d0,0x00050083,0x0000002c,0x00000ad9,0x00000ad7,0x00000ad8, + 0x00050083,0x0000002c,0x00000ada,0x00000ad9,0x000006c2,0x0004003d,0x0000002c,0x00000adb, + 0x000009cd,0x0003003e,0x000009d1,0x0000029b,0x0004003d,0x00000008,0x00000ebf,0x000009d1, + 0x00050041,0x00000019,0x00000ec0,0x00000ebc,0x000000de,0x0003003e,0x00000ec0,0x00000ebf, + 0x0004003d,0x00000008,0x00000ec1,0x000009d1,0x00050041,0x00000019,0x00000ec2,0x00000ebc, + 0x000000e1,0x0003003e,0x00000ec2,0x00000ec1,0x0004003d,0x00000008,0x00000ec3,0x000009d1, + 0x00050041,0x00000019,0x00000ec4,0x00000ebc,0x000000f4,0x0003003e,0x00000ec4,0x00000ec3, + 0x0004003d,0x0000002c,0x00000ec5,0x00000ebc,0x0003003e,0x00000ebd,0x00000ec5,0x0004003d, + 0x0000002c,0x00000adc,0x00000ebd,0x000500ba,0x00000330,0x00000add,0x00000adb,0x00000adc, + 0x000600a9,0x0000002c,0x00000ade,0x00000add,0x00000ada,0x00000ad4,0x0005008e,0x0000002c, + 0x00000adf,0x00000ade,0x00000324,0x0003003e,0x000009cf,0x00000adf,0x000200f9,0x00000aec, + 0x000200f8,0x00000ae0,0x0004003d,0x0000002c,0x00000ae1,0x000009bd,0x0004003d,0x0000002c, + 0x00000ae2,0x000009cd,0x00050081,0x0000002c,0x00000ae3,0x00000ae1,0x00000ae2,0x0004003d, + 0x0000002c,0x00000ae4,0x000009bd,0x0004003d,0x0000002c,0x00000ae5,0x000009cd,0x00050085, + 0x0000002c,0x00000ae6,0x00000ae4,0x00000ae5,0x00050083,0x0000002c,0x00000ae7,0x00000ae3, + 0x00000ae6,0x0003003e,0x000009cf,0x00000ae7,0x000200f9,0x00000aec,0x000200f8,0x00000ae8, + 0x0004003d,0x0000002c,0x00000ae9,0x000009bd,0x0004003d,0x0000002c,0x00000aea,0x000009cd, + 0x00050085,0x0000002c,0x00000aeb,0x00000ae9,0x00000aea,0x0003003e,0x000009cf,0x00000aeb, + 0x000200f9,0x00000aec,0x000200f8,0x00000aec,0x0004003d,0x0000002c,0x00000aed,0x000009cf, + 0x0003003e,0x000009f3,0x00000aed,0x0004003d,0x0000002c,0x000009c6,0x000009f3,0x0003003e, + 0x000009bc,0x000009c6,0x0004003d,0x0000002c,0x000009c7,0x00000664,0x0004003d,0x0000002c, + 0x000009c8,0x000009bc,0x00050041,0x00000019,0x000009c9,0x00000667,0x0000010b,0x0004003d, + 0x00000008,0x000009ca,0x000009c9,0x0003003e,0x000009c0,0x000009ca,0x0004003d,0x00000008, + 0x00000ec9,0x000009c0,0x00050041,0x00000019,0x00000eca,0x00000ec6,0x000000de,0x0003003e, + 0x00000eca,0x00000ec9,0x0004003d,0x00000008,0x00000ecb,0x000009c0,0x00050041,0x00000019, + 0x00000ecc,0x00000ec6,0x000000e1,0x0003003e,0x00000ecc,0x00000ecb,0x0004003d,0x00000008, + 0x00000ecd,0x000009c0,0x00050041,0x00000019,0x00000ece,0x00000ec6,0x000000f4,0x0003003e, + 0x00000ece,0x00000ecd,0x0004003d,0x0000002c,0x00000ecf,0x00000ec6,0x0003003e,0x00000ec7, + 0x00000ecf,0x0004003d,0x0000002c,0x000009cb,0x00000ec7,0x0008000c,0x0000002c,0x000009cc, + 0x00000001,0x0000002e,0x000009c7,0x000009c8,0x000009cb,0x0003003e,0x000009c1,0x000009cc, + 0x0004003d,0x0000002c,0x0000066a,0x000009c1,0x00050041,0x00000019,0x0000066b,0x000005be, + 0x000000de,0x00050051,0x00000008,0x0000066c,0x0000066a,0x00000000,0x0003003e,0x0000066b, + 0x0000066c,0x00050041,0x00000019,0x0000066d,0x000005be,0x000000e1,0x00050051,0x00000008, + 0x0000066e,0x0000066a,0x00000001,0x0003003e,0x0000066d,0x0000066e,0x00050041,0x00000019, + 0x0000066f,0x000005be,0x000000f4,0x00050051,0x00000008,0x00000670,0x0000066a,0x00000002, + 0x0003003e,0x0000066f,0x00000670,0x0004003d,0x00000008,0x00000671,0x0000061e,0x000500b8, + 0x0000006a,0x00000672,0x00000671,0x00000132,0x000300f7,0x00000674,0x00000000,0x000400fa, + 0x00000672,0x00000673,0x00000674,0x000200f8,0x00000673,0x0004003d,0x00000013,0x00000676, + 0x000005be,0x0008004f,0x0000002c,0x00000677,0x00000676,0x00000676,0x00000000,0x00000001, + 0x00000002,0x0003003e,0x00000675,0x00000677,0x000300f7,0x00000679,0x00000000,0x000400fa, + 0x00000181,0x00000678,0x00000679,0x000200f8,0x00000678,0x0004003d,0x00000008,0x0000067a, + 0x0000063e,0x00050041,0x000005da,0x0000067c,0x0000051c,0x00000281,0x0004003d,0x00000008, + 0x0000067d,0x0000067c,0x00050085,0x00000008,0x0000067e,0x0000067a,0x0000067d,0x0004003d, + 0x0000002c,0x0000067f,0x00000675,0x00060050,0x0000002c,0x00000680,0x0000067e,0x0000067e, + 0x0000067e,0x00050081,0x0000002c,0x00000681,0x0000067f,0x00000680,0x0003003e,0x00000675, + 0x00000681,0x000200f9,0x00000679,0x000200f8,0x00000679,0x0004003d,0x00000682,0x00000685, + 0x00000684,0x0004003d,0x000005b5,0x00000686,0x000005b7,0x0004003d,0x0000002c,0x00000688, + 0x00000675,0x0003003e,0x00000687,0x00000688,0x0003003e,0x00000689,0x0000012d,0x0004003d, + 0x0000002c,0x00000ed3,0x00000687,0x00050041,0x00000019,0x00000ed4,0x00000ed0,0x000000de, + 0x00050051,0x00000008,0x00000ed5,0x00000ed3,0x00000000,0x0003003e,0x00000ed4,0x00000ed5, + 0x00050041,0x00000019,0x00000ed6,0x00000ed0,0x000000e1,0x00050051,0x00000008,0x00000ed7, + 0x00000ed3,0x00000001,0x0003003e,0x00000ed6,0x00000ed7,0x00050041,0x00000019,0x00000ed8, + 0x00000ed0,0x000000f4,0x00050051,0x00000008,0x00000ed9,0x00000ed3,0x00000002,0x0003003e, + 0x00000ed8,0x00000ed9,0x0004003d,0x00000008,0x00000eda,0x00000689,0x00050041,0x00000019, + 0x00000edb,0x00000ed0,0x0000010b,0x0003003e,0x00000edb,0x00000eda,0x0004003d,0x00000013, + 0x00000edc,0x00000ed0,0x0003003e,0x00000ed1,0x00000edc,0x0004003d,0x00000013,0x0000068a, + 0x00000ed1,0x00040063,0x00000685,0x00000686,0x0000068a,0x000300e1,0x000000e1,0x0000068b, + 0x0004003d,0x00000006,0x0000068c,0x000005e8,0x00060041,0x00000517,0x0000068d,0x00000515, + 0x000003ad,0x0000068c,0x000700f1,0x00000006,0x0000068e,0x0000068d,0x000000e1,0x000000de, + 0x0000052e,0x000200f9,0x00000674,0x000200f8,0x00000674,0x000200f9,0x0000065f,0x000200f8, + 0x0000065f,0x000200f9,0x0000064f,0x000200f8,0x0000064f,0x0004003d,0x00000008,0x0000069b, + 0x0000064b,0x0004003d,0x00000013,0x0000069c,0x000005be,0x0008004f,0x0000002c,0x0000069d, + 0x0000069c,0x0000069c,0x00000000,0x00000001,0x00000002,0x0005008e,0x0000002c,0x0000069e, + 0x0000069d,0x0000069b,0x00050041,0x00000019,0x0000069f,0x000005be,0x000000de,0x00050051, + 0x00000008,0x000006a0,0x0000069e,0x00000000,0x0003003e,0x0000069f,0x000006a0,0x00050041, + 0x00000019,0x000006a1,0x000005be,0x000000e1,0x00050051,0x00000008,0x000006a2,0x0000069e, + 0x00000001,0x0003003e,0x000006a1,0x000006a2,0x00050041,0x00000019,0x000006a3,0x000005be, + 0x000000f4,0x00050051,0x00000008,0x000006a4,0x0000069e,0x00000002,0x0003003e,0x000006a3, + 0x000006a4,0x000300f7,0x000006a6,0x00000000,0x000400fa,0x00000181,0x000006a5,0x000006a6, + 0x000200f8,0x000006a5,0x0004003d,0x00000008,0x000006a7,0x0000063e,0x0004003d,0x00000013, + 0x000006a8,0x000005be,0x0008004f,0x0000002c,0x000006a9,0x000006a8,0x000006a8,0x00000000, + 0x00000001,0x00000002,0x00060050,0x0000002c,0x000006aa,0x000006a7,0x000006a7,0x000006a7, + 0x00050081,0x0000002c,0x000006ab,0x000006a9,0x000006aa,0x00050051,0x00000008,0x000006ad, + 0x000006ab,0x00000000,0x0003003e,0x0000069f,0x000006ad,0x00050051,0x00000008,0x000006af, + 0x000006ab,0x00000001,0x0003003e,0x000006a1,0x000006af,0x00050051,0x00000008,0x000006b1, + 0x000006ab,0x00000002,0x0003003e,0x000006a3,0x000006b1,0x000200f9,0x000006a6,0x000200f8, + 0x000006a6,0x0003003e,0x000006b4,0x0000012d,0x0004003d,0x00000008,0x00000ee0,0x000006b4, + 0x00050041,0x00000019,0x00000ee1,0x00000edd,0x000000de,0x0003003e,0x00000ee1,0x00000ee0, + 0x0004003d,0x00000008,0x00000ee2,0x000006b4,0x00050041,0x00000019,0x00000ee3,0x00000edd, + 0x000000e1,0x0003003e,0x00000ee3,0x00000ee2,0x0004003d,0x00000008,0x00000ee4,0x000006b4, + 0x00050041,0x00000019,0x00000ee5,0x00000edd,0x000000f4,0x0003003e,0x00000ee5,0x00000ee4, + 0x0004003d,0x00000008,0x00000ee6,0x000006b4,0x00050041,0x00000019,0x00000ee7,0x00000edd, + 0x0000010b,0x0003003e,0x00000ee7,0x00000ee6,0x0004003d,0x00000013,0x00000ee8,0x00000edd, + 0x0003003e,0x00000ede,0x00000ee8,0x0004003d,0x00000013,0x000006b5,0x00000ede,0x0003003e, + 0x000006b3,0x000006b5,0x0004003d,0x00000013,0x000006b7,0x000005be,0x0003003e,0x000006b6, + 0x000006b7,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ac168a655b371942a7247745ab6c99e27733b043 GIT binary patch literal 65868 zcmZvl2i%qO|NoD=B}zy_QmGIndlPLG*_*Vaosw*o&DS1D6tW3PBBdgGOLnOwd++^w zJ@5N^<>mbU*Q2Y?^YwneKkv`D<~jE{*Qs8u*(#;dN~Kz*nx)U`lq#3CO4Vd3l_*;j z<<=@|m1!2R}24jD0>(oU$j=QQ7Rp$b*k1!w9eMLrgBkNof1`74^&T`sVJ>h>fE(^+XLHmAAUlQ-hGC3 zAAZu1VLkfx>E3h1@yAOJ>Dj+euagv4i@1)5AKZO-k3mBR_8B&?&+y^hPwI2ZNh5~! z>3;l(!M#rEH)QZ|rFG8E-MV$|+Od1Dp+lAP)Pa4v59~L%Pxs#ahACgallu@?lbl6d zzrno*j_92MD=Q+$yR!N{T7BNHZ>a=7AU>dd6;Bl(ymJ-*p=sNY>%O(qQGZX6{ek_Fv6b9vNC)DD_mk@g)hxQoOV^C#WMd``^=<20;(mgBZrlRz$xZRHZEB8U#eNp{Uy1+CRZ;r- zKe~G9d+EI^W2={b5bsrNqo2jSifziizh7lPD@wnLGv6Qo(VB4`6P=4394`kIxoe4g z7xPeC+-}D{#XMA$)|37>XZ6yC=%QXDap%f$Rg@b4C$6H@v`jZI)0>p(P0MuaGQD+~ z-nL9{U#55XkFH*7Bi*rbf3GOD{g1Dr)S*mw{*SI+IzW2Z302$gIPnq1_UrMVxQbHm zGTpaK_xq2oUK%02f3c68D?Y7qKdLBQ@SnJf(nbH#)ho|&Y$5jXhs%7N``C-w*Ek2B zChn{_&LJF=t7z>kALkJkeDFr%)j~JLsfAe1GgVws$r+39-`I*0=OMz?bY)%6MJ%)f zQ+L(S|JJQu;#|c-ES$0EjGY>>FtN3Zx@cnQ2mR+<$3k8>W6}S{R+KmwQjhZ!@pW|! zF&0vgi*q8ry)?rs|jjE({)%mi@SH1Fl={U}v z*#??6=reiHEeX~_p68^^F9dVWt+H2CUf*fkIXJhXYicFOn=4|gmlg!S75sMaJHecf zxjmt8FnN7kaL#4H$2pg6!AhH)cUkap-lZNUe4J}p;J-tdw5){uc%wSR3~_i;5CES3a%Txc5uDm zb%N^$uN%BkFxL(i=A~IM*9hCU3g+5i`!>N`18nE~Z{~b&=3H;?8q9g#cG%kkW_#eK ze_R7t;GV%;3vBNbe0(t12gjTc%yq(ct`X*wgGUCR7JPOv*A&-<*Og%3h1oxRY@z?% zKdP6`i+Ws(SQy`h!CaGUzasdm;PJsX2HzAsA^6VVyMpfyz9;zJVD9^?`lD-m1uX^QcgDS45Wa6r{?lmKhYp3n7w?9lB&b`dZ{D^x$_=Dhu!Ha@F3|<`kb?`UA zKLr06{Cn_U!G8z;6WpAWUD5xIgEtS}B6z3Z-Gkc%?-ATKxLt6E;Jt(Q3GN!aZ}5J> z-GUDYK0Nry;G=?%4(=Y@Be+lSu;5dJ&j>y<_`=}Jg0Bg_Hu$>WvBB2|j|;vbczp1U z!8Zj@2%Z>xbMP&}w+2rNzAgCn;5&lv48AM)?%)T59}b=tJU#f);Kzbz1kVhf75qf- z^T96!zZm>d@XNuk1iu#idhi>;^Ml_EUJ(3N@Y})f1iu^nUhw~@OQyK1pgTPOYpD3{{&aw^cCl;mAC;cxLR=a;ELdtgKGq@ z5?nKQ)!@~FYX#R1UOjk?;CjL91lJE| zb?`R9dj@w3?iRd%@FBs62KNZ=89X5Ps^F`GuL~Xjc*iUN?CC;0D2s zf*S{K6x=kpS#a~oq~4`-Zgl);N64U1n&{NXK>r# zcERm~I|g?O?i{>#@IJv^g1ZLq7u+p)Q1Ia3A;Cj~PYfOwJR*2x@F~Hk1&<0I9XuxZ zoZ$0<&kw#h_>$mDgD(rdJot*>D}%2JzB>4t;A?}g3%)*hT<{IS6N7IKo)mmr@a@5O z1V0!&CHSG>slg8iPYZq|czW=o!83v%51tu3EBJ}v*}-#y=LSC&JTLg^;AexM3w|N^ zrQnx?UkQFS__g5IgWm|AAN*$Ug5bA;-wu8!_}$?5g5MARAb4T$qTmmMmjo{j{wR1^ z@W;W+gFgxWH2AaN&x5}R{xbNh;ID(f3H~&}SA$;y^4gM&2S@6ff%Y#1&{w(r)gWCk}5xi$`+u(M=?Snf6cMR?nyjSo(!Civ82JaWVfAE392L~S# zd}#1t!G{MQ8GLl`F~P?M9~ay+xOedJ!F_{I2<{&|FnDnAkl>-g!-7u=J~?<~@F~Hk z1)m;#R`A)uqk_)~J}>zE;0uB;48Az{lHkjNFAu&V`0C(mgRcu78+?864Z$}CPY9kE zd`s}H!IOe-556<_?%;ca?+czB{6O%O;HkmWf*%Q<9{gzVW5F|m9}k`xJS+H#;Mu`* zg69T58T?f6yx?bop9_9I_{HFtf?p1PCHU3gH-g^`UJ(3F@Vmhu1TPByFnDqBlHjGm z9|bQ9{y2Df@F&5a27ea(dGMFPUk85^{B7{}!9NE79Qp-!FvX`3vM6WF}PE3=it4A zy9DnW+%0(j-~)mW3O*$Gu;3$tj|x6I_?Y1C!99X|2KNf?6WlkrUvU56fx&}<2L}%c z9ua&>@M*!P2cH>yR`BTHF~R2qpC5c-@I}EF2VW9=Y4ByiR|a1de0A`3!Pf_m3%((E zeDF=d6M}CEzBPDK@EyT-1>YTfPw>6LlY{RMo)Y{}@YLW(f*%cjEO0Tt9f-;PrwV1UC$B6x=wtNpREP zX2F{TZyMYpxMlDb!L5V04Bjeuo8WDOcL?4wc&Ff9gLe;Z6TC<8p26*cI|O$M?i{># z@IJv^g7*#X7JNYPLBR(H9};|6@DagB1s@aKJ@~lb9>KkW`ve~!+&8#i@POb!!GnW` z2A>!_EO>bEsljIipA~#|@aW(%!RG~^AACXZ#limzzBKr<;LC%r48AJ(+TiPg#|GaJ zd}HuU!4rZf2Hz5VYw+#CcLd)Vd{6Lw!IOjU4}KtcO7KI$(}Eufo*q0ScxLdd;3tA- z2hRzf8~kMOQ^E6spALQ|_}Sp+f}an5A^64Mmx5mjel7U*;Q7IC1}_MHEBNi;_kuqN zUKqSMcuDZG;N`)e1b-U*S@7q@~DtL78Il<=zUl4pz@WsKG1Ya6_dGM9N zR|j7cd~NX9;Bmp@gKr9+5IiyXmf%Ujw+G)Dd{^+@!S@DF4t^kbO7KI$Q-h}kPY-@9 z`0?PG!Lx#A2hRA^C%xc-^H%8hrH|R{@fCVKZGeSqP1@7>8&v9ME85$h4OH55 zh5sn&e^wr|6Y*^0UebI$*?Iu++8M2fN;eMwaOqK@PnBLX^k`}JW!Jw{`X7C%$NF+< zBG7EJYby1qU987d=@s)izEYP~jCYds4dceGn6KNUcVBJY75>|$@9(^1#Xi-X9a0m( zKEIWi{mA<$$Kd2De`SBr4@=um|6Zu{k811wy;`aFtklFWmewXIc^~CD2#)Q;M3hF& zwmt_v>g*MLy|B_>+SU7`pPAtO&d)`#-_Jg<-_JL2+dRWyL-pRzE@&j?Sp{hJ?RqMi zPHf~r^V|Y#_}49%{i2c120W(#W*%}Sc7r087;>R`<^Z`EFZEhWQ@JrM;fEpV!Jh z!0L8*?hEaZY3Z`BBjLpvipdb6o&-}8#<0t;Oq7L&nMoeAu<-%C_GblOEQ49;Qm!Ps+}D!s`y&wv40d@TzL>S6MVgmHprv%e?~gL%-16FQn!^BsKRU)?8z`-$~6q zPipR~Qgd&Wn)|oZ+{2~jJ~1`-imACDP0c-NYVLbebMKp)`|H%)W2fdmJ~j99sd>GS zn%4}ed0mp4*CwfX{gay4K&g41m73RDsd+t@x?5=OnYx7L9;khp=5?j(6VGc@YvQ*J zji1-Q_M>?%ZB2Z$(D-?sp8gHWbi*>ecA2ghn*D9nGQC=8+FPkiS1Z%i%XCF(^7EdJ z`-|p%8*B3O-cV}ZA4<)8M5%e7C^hd9T9cpm2~*E0)4X43Kl96bhSv0l_YG6?-eGFq zKeVPj-a|~y`-s-$CT~PzkTSg(z}-F-9i)3XVjdZ_?DsZw<^LOo3tiBpV>^!=Qgd$$7e%R z^ZC%!d`2`ipA${ZXN0Y3kIxCG=Ci`79}C@8@qA|3e)_}bhEvZh(|mr|e%gDYOwSHY zzBy%jZkgsY#m+}OpDVT|Kc6j5&1b7q^ZDx3e1_;D3rVlIA zhleH~-_vk?bl1@2YhR{2lK318=CxlHz?bySEknq&HU95O@G!c)9aP#^+VHM zgEGBAX!12I(;JrQMrFEjX!18H(>2TVs%4t*ZRPm+?v^$E;X7p32srlZ!HLu_K z?z=VdeE&T)-+{L#Ki`8-&3ECgsn7S}t%>J5@u~S!n_4acKN}r`~=v->bJKAK$G{&G+k5^BsF@ z>hnGO)O^?8ntXiUJ~iLDPtEu4t;xrC?^E;rdu#IX9sJaM58s;ld>218-^aJ6KHtet z&G+(C^WFT^JOd&%&w;RJ|KnK@)|5OC!kYff2~GPv7s7r@o$PwhbAA-wX`42vn^Bee9P24<1#hRxlGNoE>rWoOKbYeGcT=akLO;d=Gm92 zdH!W;o`GpizMIQ5&%(5y{5%gcHP6IM&2uqR^K49O^7DMm)I1~8n*2N`Gd0i3v}XHX z9-8=5LzDlsGJSez;?F44XND&K@X*Bb98~>V@%NCPWx7|H?j4%?JUdnYR@6VLOdnmQ zd9G{5^K4gZ^0f)g^>UBUjGyQ4Iv)LIXzDL0({GjOx6AZ9W%}JR{a%^onZItI_IU2E zHT~h)zt;4h=l@z0&oh9niC-L=zl~1Untq7N%GKhIcCKfh;T&H0kw zv#_S*cPvu#`xVw>hp|qYvTDm3Tw&@ zLlfVqOgApmO+!<^d70*SDV(2to0e&Qmm>Wt|Fgl7KRhQ{Ba zOm_~=@yl;hWImopZq5GIJ2dmxH#BiPYdqt5-gxQ@Len3f`)xm(XKSN(*WXY1yX_2Z zKmK0dP1dH;kBhOfvhX+F+WI>#zL~P2bxEm=8>}4sEq<0(d~Ng>V)lQu^UoFY_kVos z`)HW`p1%jT)n9k%*HZNhKc7XSE^T}y8}=s@(_ea-7~2+#`9(Q)V<1|7S3JILq(4^4 z-;61p=Myn`W)yio6=UOb9^~0N^5Cl`{h3PgP&&^SV)C4$JoN7?F`pB{&X_p2U?ZN- z8u46kKKp^@b4ffKoX>t7s``8$>04=HuoJ`f_)a`W^Wg3Ay)-sf7FAo(AD%Bxn}=)L zQI}_olao699UVXY;+%`mbN!Q;Hhzp;Kg)*QWBo#x$pU?(T%O>FKr&orkU ze4Ink_O;b~V(X?^Yo#{ZNn>MWVNCSb{cB&u=f1$R$gxjXf7ll~im`cL=ptreU%=N{ zYbUL2LrVI^wTbxOWFsCQaUS#DV%oT{7&Ff~XCKAx`q;8Qd0d}oq0`1?s?Rui9y(*K zw5xrth1iJ4|A*!To5%g9G;^5a{!1FW+u#}T%)Pe@&xt1nJAGWFlDsh2D*SGbXRqUT zdk0E$Jzu2098iq;AZg-Q$UzJ?*Ev{Boh90TdQOr;COdC)x~ql zj*SZ0u>1V6vKX89z177m?0fiD(^^9-xhdU`Rm9}>v0YOd8!HR*$GMhs%c`=W+i4|^ zzH={xoxam1`Dx32uO%iw+tc${TQ=;jkIwq!acmtiZ4kRaCEC6<#Mo-9cl2*fY5Lbv zD?a9eW5spxyKY@E^XIXxEv7D?^T9_Q?(49-PCYR;&-psi*l2@uc4ILMbB=EVt@X7s zCzQ^!u9$xNcv(-H&+lP(%=%*58eJR%4Wx;~PT#nv#KyeQE^W}B>o*i<8yiaVnL+H% z*+`6?&rLcfw#-Rx=WHUTU1GV%Mcda@%ysB&jh$`LOd1=p-0z}^ovgWPF6Q%zXs$sU zOY`|eUxPN0CI-9nZz`ru>lV`F-Cy(5RPAjhO$>Hldo~x73m?Zc`vd*qc*EyhEyY|{ zywA3hERIK$LA^eEhj!p*;Ct+x#9Pmui?MmkW5n3lFWf%mPo-5V>z^y8 zfApJJ`bPi%r;>&K6LXQ)^R&``O84=6G5ybL$OY2a>CYJ|(e#IHcA*#>zEf4A=^OJ& zZrbtOTrBq7oGwPY-FwB@@}BfQY3$^_MkU(ulf}g6z0&>C*lTMp=-UHgO=GErR(#%% zt`+0+7#W%pJa|S|8HN_$cY$Se3*xcH;37M;nu6e^|`-7SNoB zr%Chu1fPc=ktPPa`!!umUwz(vRE&*weBOObn!5OW-t|4!4B7CrxR2PfkMz~;%@i{Z zVy{z)wr`f0Ir26939-7N(dhM_*!%BnF+RRu!Q9nhLug^{@XgVRjroDSJ?Dzqp1I#W zDUIE2J|%XW`20F-o){nB;h^u=i?KQP(_(TjQ9nGMXQZ(^$8+MBRUbP!#;L^S_~*sg ztX~kbZCw9FF)`SEPJc;^o$rp2^9C_C=XhC64(nIM#1MO-z|YB ziuqoN>#wJIrJl#VzBKO#GpEF(iE%u?VM1=lZy-(lk|G{WjN==MY2Wc1N)yj9OMWyl zj_0>f=%eEsOB3&Vcr-D@b1iC8_{qil)@b`)RUT}-wj%a5X>82d{yN^Vy)I@>a~)m8 zzacw*>XCoEN^H(QUyRLte^bo0jO%8V*vQX$XOTG1J0D8td1tXSG1$GGmWaud z$Kq0H>^>KLB*vEKqGi(L!{>96`|+`C*^lMY*^f`8iNWrEd@80N?2n$W&!n-tAD@e{ zWk0@6Yp~tni$9PTTArO@hzo^_c;qq4Dp9+gtSCn&00d<{IS{miP@WVz3i~Z8iOOgJOK{ zt0hewcE{8fU#A$xD=e+9|F98DKk#AWe#Q3;l&-&qm>6%XHKk9N&hyq&4bCyQU#Y$r`!O8h$&e!s5SUK$%Q zu=DRACNF*AZ`f$h``%(~Iq&;OWA}Yw7cn-!uIVhsMt)xR>?p>@_}o6FU)Ss`=5-DI zCYHX@{|+iy=sz)SweF&o{!_Y-yNc<5_Hj4ausde=A||glZDhml*A#n**?%_HN`3sy z34gc8=WVyA7#qIUD$$IM?Lpt@r{}hv*mKM00npUzsxtpZa-cN+9K%7<*hd$~(7|H9 zJB*zie4YUtZB16k4-w~e=TPaq?i?mf40ey@a4~s&jX6S$Ew3?0N>dkK`8DP!+3>SC z=h4!P&-c&Ah_Mmtv19YLIabWrbK7*6#_k-)iJ33#oI>+8ini%Zv zXKyiiJoY|fY&rJhrKyXreC&N?!=Gb6K|06YPZ}Gs9y>Pop}&}TeBD%{?HeG*hHrnB zX#3iWvEgGMMCU%pv6Gs8({($EsYBguRHE%0qT>h~KF&*M^7yg(fBy`@!R6_wEBJZ1!8QhEF7}G5vP#55?Gs^_Z|Z zezBN%u3O|>B4!+#_7XnV!A{@!e)4jy%e1<0T;o0|?8Gk>qaFX5n0TL0i2qy~yZiBl zn0^e>T#uIjOEEU`eWemjEOoyT(*{01SAeE1ZPL;Zb)5L@+fdoCKdBh%pD4!0vkjbc zm^8WO6*0r5u@Q4_VLM5hy7=7Q2r=#D*iM!WyW1Nn#+JEGk;cyR6h;;KPnD((e2i_N zN^I`q>0O)k+}4@W*tzd?zt57!&a)YuYm_u|;#{M}*fQ4`Y3!Nn9BJ%4 z*TMZhSDH5PIsbWL`tO+Y#n_1T*swYNLUH!zB57>g4|^OJOJg4$TXNTCs86hRM%)=Qr^$TB*aFyd{?VP+xNTbV8h2} zYtZ(MmmQnWb2mz3V`b6Qu86&;d!{jn_6bf_D`~~XJ^?fS z3Y9Bst*$las77J;XBSqH#>PDaZ8;C6?{{m8X@~ZSrw#hC8g?!8gP2vdVxu20W9IKX ztBZNAg#XS{M~scX^Z2#-8q(NV7(bug!sdBfQ;f}eEpg6cU1`rFvG_fY_!yh}M(I3j zi!)C>Y4WttijR459(=C1j+pxb>-y4Fd8+;3VivX$_6@Xdp_Oe!>2|jiKcRl) z`#D?5hMj)4R*80>wh=Q9d|Qjr_*9g((|?@L@NFwb!}k__c8=N7)b;D(InvCT_UaNo z>P%LN-F52eGw#^@T6rC5Y&`R4wDx2A|{RiSdzRd&Q&eds>W*?Ldxaq#LUA zF-zZ{l@0rYiedXcC#D{Dw(++rS=h$-p4WVBg;F7m!1CYJr0vEe8G11j;k-h44O&lTFfHw)iG z#XP(%jm`7$jhKab!1txrceFAOl+N?6m^Q566Vq4E@B3n6urt43sB~U@A85r!Uf6jS ziplHyrA1 zSbUAd*zoba5wv|v6oAdg&{An^{yfMOF*e74B<46J*HkguzGY%;_;yeX+P;s)P20rKZ@$Ze&24_F_ORjOJc!1}vGJMM+nnPQ z?RuY!J%?-qG}kikf0StUefCH8dDs0)?CnOIX#2hvW1~N8H#AJV?**Kbk~Y3oNgI^T z^PQMF{%q9u(%8tsv9r3y%)&8=?+2~e$ODr{)k{B$^Stttw9hN}9QU)BIr_Xfulyn= z*5?)cjAOb=e6IJa7#qIFRHE(MLjA$!UlwmfdPl*Z0+dxrX~M_ZJ(lEzL>zT1T+ zC%zrT*oH_eb!kU2He&gn7@AmoJBhL3<2z$$`?eNi^S-)`7@Ln(zC(u1@xLh{HgY{G zM%(wh7@PGUVz!;Hn}13ZgPr;_RAO`dUt;R}b9aA>IUcyj!N)e|m~q?qUH2a``CM0z z4_i?eU)CiKzw53f#ztQDRkVH8#O%k`)ulOic)lv6iNWq;du1{G#OHc7#EgwL9#@IB zZxylIpD7>OzM5j6t7gfEwr^K4@z%RZliU5+U78r|j%icGSnnZCUXN!_X=1QDPg^nL z!RK>TJF!fa=PLYpu4*q$+r%(lzQ5>w`(S*u)lnsO*BK?o=4~`uj4khj$4Fz(``~k=v6J&mm1y_zTroC$XQ@Qn zx4#%0z78tU_8lN*Oui33P}=8ie7?6mNL+qzd$4TSo$C-W`JXQCmkt#ZgWdO%hly!p ziROoUNn+?1-@n18=<+H|T)7OqYBPS$#~R`vr*=Q&199$z1hmB!Xu z_v!Z*_oCgUvC|)N_Y<>_8{ctSv5^~g?jGWtyPndXJA9spK4SV!o34Ajbk0>@Y2vVZ zu1*k>({n|P=L#SDzWYV#-2KHl<^j^!xF%A6FEKX9Uns`rd((@=*oZw(C7M{B7D^Y3 zvEe&kCEC7$Vr<^82Z^!yde>Qu&GCc9*sO<$tB$3r&)p4`_IZ$4{It8bN_?(&qL@7R z_ECwpZnHaHjDEsfpV@*eR3%^`Nz zyH`xTC5m@D_eo=Sy~*Mss)v2F=9t{~i^+%2*VYHb3M;Kv`03|uvSD}b2gTT&dy1In zh+}u2hs4fy-X5Ku8>0;ur)5aYtu{r)0F*bZ` zQ#AXiw<)D#Cy9w6_6C(``}WZ`!-lVo7)>7U$CTb4UBu=0MO|gX?$?3)im~~1U^g)f z#|Xatv|?kwgXxEg(t-MKL#?#M`(X!(|DSsX*|6WQ7~T&%L`=PdwX**orjmuW@ExiZ z8*RaE>u@n``MQ3D7+YS~kCevFKFfSK52fE9KT1qHjDvXEU>*-piI4W^=h0$pcNO{= zF*f?#T_p>B#(u2U%eB&HN^*=*d4<+<3q4KqbESB?O24;$RS|>T+v^%J+lw*y{q}2R zBbJ4}5`)ckt`k#diTtiJRyOLe-&2PeY_4;?m^z%(TxXnY)X{B2WgTL$F_(;)@iA7$ z$1&See4JMD_fUzpZ-(|yY<^GoacOMCKB^K;tU^k?^dB}fe;?~3P2c>z&*P=Bv9d5G z_p!HZ_+9q|@jTU~oxWl;+)pL#5XW~YpHh3&#Wzcgc8+;s>f(DsjK(KZ>1i>!@XZ#Z zUGFC`@%Ua*iMH=Moy4$tOy5gmV`cG}ynTKs;`18vqiopy_n@D|*nHgnA!cE}#P^HV zpS7~xDCrl^+48l7czndsPqyiAV%qR~WxtELU%~GB*w`mrpVIaJ6w?NuX<(lJ5;Iop z)aSWg*oepfv*rXFzL&*le9ZMPV&<4*?n}k6{Gngxz>d}<#!8>6WbPKLWS@9VC4ZxQ zNhPnzo>Qsap>&5za-OD=&lU7n$#}O?sdS~5D)q0_RR7ghxvomy8>+36=K)nyxrWML z70jGb(yx_dXJO9yEr8!-$3_h7asDo5KdYPrm23mg*-9G7H?n!#SCi&>X`BOyM-$`t z>Sgg2Mf{Q?9!-qnS1yaMQN(lXlOIit`?^Zu$5;8Bw($L-eqzJ-t(bko?bK2nHjksW zG|z?eIMBp6esyui*O4aP<3JPR_%*~Czos)lY1^$5pwX zN^2;U?~k#q7$-5*WxM^Q)ph?Cv#;X&P9@sDf5hI--;2@qHC21qsK@gF(e~{n#)gk) z4^Gm~4D;MUe)9t6nS=b^1$EeW_md{p^W9C%a}7P;Xkr|{znFZEKR`^p=NnCo;|~3KyHiI?!p(B!qZ+ZiT}&Fu^q z57Fv=p^0()N#cwjAx*sdg(k*rpIrE9d#D&~-xgwQXtqadG24Jxp6!XY?=&$sf4=8* zF*a5fZI;S z7@Ozs5-~Pb7SG=W()ir}tHjuH{;rnB?wD(en4G_BWy9_h%ZsDVSV(D8WmH5cXKE1oRUZFX5+lYzrz4spYv|@KZ_7vCE>hphFF*dKGi}Qaw z*{F}7wwtKL=C-+6#)j`zU5nAYCh)y4C7Szm?uEI3=6<=BN*3QQSC_^{4D9?BV&6x7 zq5OHje7oAk=J~!u`c|#p2hqfM%y)`2{w`_ay$_;^as1uljK4>kcwe8<#JI2b7JlYp zk{E5@${GhYd|#^1x!*k?J2sEwLFxOndK_qC+^;F(jDJX)c#i{3jN_+@GyY*|;yn&D zG4AWM!cSi(i_!Mg&^WO9et8vX_TQFT*;b5`80xa!@VjnJvA5+{@}ccpRqT7|ujNDA z_l(-ZM$YMCw0&QSvElnfrSI!L75l#KGjZP6eJ@R{=lcioH(EX4XkuuCigxFWMiK3ljl*D*qrBOG26xW%ddzz7hreHt3?d;9~YzHnJS5Q zTpjffzvp8OX?_pF^Nl9P@oS37;rO+riT8Y?i6NeAXWhb2+x)Hs+P>G62OGXw;=Et3 zFFQ83v#vD1W8r?GiE+Qy6KDMT(!{%8Xky%UgThbS{2m6{zSq?*HgqeE;SFiF0kKc0 zMBCR$aoBvn*H{`GD~mQuWj%hQ1E0sUi5MH>As6R}O{K9rrbQ9M7#y>iY}kE$-&{-^ zT>GhypMLTiA^2Rci5Q!6ZzQJQ?DvjoDjRm^ZYFka>fWQs=G37cGHnL%N?rp`+O?~|2=J#CiIrm%2gALytG4lt{ zRf*4WZ4`sweb_^q- zmWerU`~3g07@OD8#r^Vf*{F}7w&$tD=C)VUeGN8z+%KcKKlZ&ZW!^9IzBBjB^;NR? zetC6iY}_xy&R<9Dd#vTkpZCjqYkOexeD5RONvrokG%+4?7jedSl_uW%AetD*?<>yu z{iKQa^%+f!``WGWGZ&r3X#3XCII!XSM19Wv?jYH*c^n5z@2}P4KojGB9U{*7L#2uL zIMBp6{xEUIA1+P2$AKoseLbS^)7JyUX#3XGII#JCc`a%7-ayMNyKY^v z?}I?C-ca#`y-UD*zo~bcG(OM& zd17pNY@aWU-7yywG0Zvbam~C?HtarrFA~!R=X2`gr@eDj;&Z*T#n_yCl$d_!`FylA zcIO@=c5dq9C->L2fhP=e|NrzjMB>l*aDdSBagQ`uNFx ziAsFVeS#R9?`QjonM3TvAE^?X=d8b&eHkCW4TrYxCNVb8=L9h}Ru<3a4bu2Lp4-LP zaz5{n#_pIqid?b5kEb zxyP%-=iCFt*gPi##mtwlJAnO?-?ygw=%cF)aYV&;b9p8EJ1!&H^{JU0)Bu{rmHV)~u) zK1CY4b3Y_@ZtCMF_q{6dIrmU8HhjmbMB8_wnElv#n3x#1FXo#OnqX= zeVj^ci1BI&Gkh9`~x!{I09#6-|u$x|*1Lj;|$6yyq27 zjN@yIY18qmOB3&TMHAyO)G7Rof!~uw+gDwT>9zX3W@$=fe`%-1aMK7n{#tuS#R{ z>hsrYvN6y2$umX)m4A+dp_2d=67~I z-)LeSUr$U9$FCzzyyqKD4Dr0as$ckNo8Rk2+xMpOV8b_8obQ`7kR6-b*+81#2X?>E z#JFD##Tmb$H1X~ini#j;sPNM^zcY-sZ-LsyhHj-Xyd}*xAofX>X#1Kf4x6tR&7`rh zvS_nZ*5kL2@p(L(i?J~ta&ZsXQX0EsS`{&j!7*FNhTZ4e)?(V=zK8nw=_kLvjL-F& zi?KQP#$x)N*NaVL!|vRhik+MK_{rTwB|hhVTY0egeUo>jvEgr}e!VO9{5>T`+qaGC zVe|ZLD~*kn#q-B+P2+R_cM)UD`P)?*yJL1MVsid=mkqne*hWknTyLq5pE2@V*Z4ff z?ZnuedwVhc&iUIxHtf#5qu9BrkDuK9PBuR0eouL@;hQIB{@|xo;&WU(#o%`z+Dr4B z-99GJ#5lf#m>iDpC`~-`L4Gtb#B;26D*X8N6r=5XUwN=GHex@J_SiUH@cVs}g<_6v zV#xJ`N^J16D)aU0-pYv$AHPSAcK;X2j?Ml5P?}u1%@<2!cg&I^hA}$NQrWP3yL=?3 z?;JDK$8X=V@Xf@*F=Tu^I+oy`L;p?RmZQnY2eTxkr@2Q}955@0~Q099oe5Q~0R5nt{;`db6 zlg7q-DzNjfFZOHgCCZ=gsqCw5h0WVyKk0q6djCWd;F+P;433-PqqU5vJGv>2Pu^<%`?SXt;d_0E#U=lQ=# zj4hA*i>0wU=8__YIj23Yr~i`;yN~Tl#k9e>p8EJ{?*f(hT<;t)Hs?N9OuzG7f1WgU z=RRNT+|J3w8!TpD#@9oPw(k}(HqYm+Vr;A|p3e!=_&lDw#n^H_ z?~%stn0t$uoX`7Y!|pLp7JJOp$4@`+REf`Ho+QTR+_#D8ch2YS(%7B*4zY7nA3wP# zs>J8qL&VrTCqu=|m#;}DN)zMNuStfSOedx_EZO%Y@Bygwwy#+vhf zzcfCN`!O-Loc9^h*d6nD5tH*iQ#S0Ln^|J!hU1?4_!+}=mH0e2Q^nYv`(ZKt&Uv3E zjorB)5j!{a@ss-jmH3?dBr!I8JyoLZ8zE*twmw-*jN2F~b{o7#!teJ~P7za|7;^Vk ziH%&XG~QFiY!~M~O_~_rr<^V(20QipsKn;_XNWn+<2zoAw(k`&Hhi;HqV4-pj1Av6 zD*f93Td`mJe<#k@{=Z8T>-qmf{EJq$KY7r^cr1U4$>;dL#Kf~N5RWFt@qdeH)A9d^ ziD&x~k0!=r;7bnp@%^e2ZQoDQ*!(>iS z>|8P0z8dNSHhe3IJ+IZop4aN)oY&gY#CqJTi&xd^c|{ZBzSa?w&+%)BiTAvsiE;dz zV%l{4T4LfouV`XChPs8HF{~y=+qa4so9DHrm@#7~zCtB7xBZ6Z0-MiY^QEzQ_4(^f z*_dbiQb)mMM;dp_2cUR$f@8%>Pk z*AtV&@#{+y@A*a(Lp-m&8Weuot|vy@_m1*l!}qi}-&1KMJ2tn|Sb77k?iZRE_p6CG z<2RBf-u*%o<)@zc*%D)G5q3o$n5-b_rt z^LnwlY}lQGv_}u?CVr)5odq`t<%$`L|&R<*EuzQT{#I(WnmiqV^<8CVPd5k-Wu{rn7V)~u) zw~K7poqJcYb5kEbxwlh^&$$;V4>o+yiJ3q6d6oDa*GVz>-G|Q7?X~)tKojHmy~N~j z{NB>UGauwf6GJ@5>OO@ZUk5STz7LfL8)GAOv9!m=@q*v)sVot5Y!gGSCsksDUsRc| zU-wl`Z1}o}(eD3J*|E9*A4!udxA`(@?2h@kh+&M*vs^ap-Y%br={v^^_3_*HY4~WL zSo-#YN_^yGpZ-kDKJ7L>7Zc-ql`q7^V0X-yV$Rz>|9>UM=5=)Op32vGG5PVi@7S`hEv22am6)8?TS(In=W8uZ z40fI)K)YLt+3tL=6u;ZSp6&3RQhbY*kLOF`+gdi>U!tTt>kF)>p#uKv>7Nn?9h zb$(XNapGgNvhZFN{_VA5Cl~BoJBZ2U{dh-d#)F+0t`9qjvCk~p+gXflyzaAkU+icx z3vJ;$MC&eEX^YZr?JCZ;c9UiE@JF{wnSI)3)<$`-M4+k*k3J<1NN8wq;uZ8Ns}A9bMG(4 z?%W56$%TEiwmbX5fnx0Z-h=yjkTm0FJd7JnT#lRZquEcG2lfxo!=d7whrVfAyBe)?E30F6kqUeXhQM?sM4j(&WPD+=@UNsPdqmI|D{UC-(RJ34iM8n>w(gY$88LfCI&nC7RiUr@q@+KtcOTv zzM<0ObN^11CI-9f3=@;X^D$hSIPA8aB*y-v=E(I%NYfVm`cNh3DSYh12k5$v&HKrL z()(%ky$qTd#~&ol_=Ba1U!q*(M-$`tL&O<>s5J3@orfmIeLbx3ldGE;ZQscn2R5F! zvX%CWkH{{< z+0oL6YxSI=iSZm9BhL6^rHS{Pp^0&PcX7raCr!NP3{8yt+N1C@t|P=~`_9lfu;F`G zea?HnKC)x;IF6U@snz2^6XSmM6=(bj(!_flXkr}SPn_}nrHS`A(8Rc}0}4NV?IlLr zcc#XH&405vOIoM6%D-8#tr#aU)MdNjr!LPyIa~aMY<_0QC~0i0EacH4QCasr#pSjh zqBgO4j)qDP)ap4x6XP+TD9-p{(!_g?(8M@?xH#iak|y4BgeJ!GFrx4?&Ou_deWNuV zY-q+kMmooRjx;t_9R@2_&*{0cdrp}n@=?cQKTk|P#_ng`oG%;oSm+Zm*j(oVF?ATf z>s%Uu?uY3c^*LrZPuNH4?RS-!7|;3D;+*qqq_MHGFu#n!uRX4nog7|$9=}dD zeAK5O?`saR!5@h8I6hU|9GmCjH0hJIdLKm-<367*&iFH=iDw&;A5Dzo&lG3;S<=LN zA4L;GJlEE<3qQF=iqZCs)fli@UoXwrtj9_Fy2$luyfpLc^Z1QoVzBc%m-cQFlLsHK zAF)jkGuOPfq)lSn#zZk~`t``oMJ&&?!RNSJ#J&bBRD7Nn&e0gKdCt$39;MZDjwXg& zjN?3U#-A@uyyqNEjN>m5XZ(fI#Cy)s#JH~)6@KP?v>0vQtr`b5jsvcnlcX6Nc3(Gd z6JuvCm^<%>w~M*o!cT6lo7nQYd51J@an89@ocsS>(%4v8y#JHyjj}ntRDHzeIlWB! zVy&K2G%=o|%f%Ugg*5S=Q#3J-zfzp>S4k7^IYkrWdAqvs)7MMHX#4Kgc(9=v_dU`% z?t7)NvHt(gwfD)+T<|w{=7@aM@z^Je$(QHa`(>jZ3w$O}w`&ni%*0rovBOuN9;1o2D^f!?!?v&hzXovSaf& zZk3*()#E@D<9Gy>zP3-7 z_Ws89Vw}WyERTxWck=rAm~7a6?wuhf4|dv|uXt?mTV-=~uiD1u{P#)UrPXtVCdOl* zEYA4*rHS`kp^0()1LBN-P?~tp6`B~&$CScPU+)&9?R#8fz=q~no++Kj@+@g=tSrnU z$A;@aAv<&7>(Oj!>R|WvXpWeAT#smv7`Hc9ob5d+jg6JX?fH83lhl%oEcO z#`w0%JO-y}eAv7_9+7@XtG5T57;3q*&zBDn| z$@iMZg3a~c6l1eqAf5T%lFs)W-j*f?yX(9oCWp`U?@AMg-M06{*z-My_oc~Azg}0F z?>WrYw#DXsagOv%t=<>W#Lx%!#kt~)e^Q!w?~7<+9RHL!& z#Ay3I&^WO9J%@$Tj19Z@#YJN5%mZ`o^W}$Pe9hxM2W+{$7fZXXCF0yZOQm!Bd?ZZ_ zcGp=Z&N?4U=RUGrni%ZfUZ04`h0psTw(QrZ(r)83aklZfbhhz@G%?tn4_oH@Qrh{x z5_7B)`-4ifea}c^!#7hU+P-JSJZseYIcZ|NA3ZPTd82s^dqFnr#69;|`ULI=;6g2Ak*XL^01D_wQB@6Jz5(jMwZZiCK8fj&HbDY`kWN$-_1L zWN|+GcBC{mRu=l~K8%nJKlx8B{N(4k=BG$wBR}kZo+jp*(TtU6o1Y=(na!h>)G=qu zhTVTdI7>`D?8H>QRus8OJ4JVpWv>r~mk!6aN;-rPBUA3w+<{JqhA2(|`D=&;0Ss zZML8HUrMx}5lxBirjq@S(qkPj=Go)!?~UTz-*1w}#>&DxGjF~&O^}@!@_4=`ipi1N z_Ga0LWnrF(!R9)*h^fPvyq#{9jXJbR9b&M#&LlB)a@*b}8+E*GiNVG(d520CACtFB zV`ENW&&i$QHic&U-X+dCxmy|=D~spE$KE}%lf&!i;@G=aHtOQ{7$=Ldvv^*x+5bS{ z&pE(m|CGX?paGxDQ} zar`oI#(ykLysukmVjRC*objJX6Yt{=O$_mDmrn~nZ7&j|?VF}?VZ%37jJ9vOnC*%0 N5i$BNZN;6m{vSOqzNP>G literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.h new file mode 100644 index 000000000..4a226076b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.h @@ -0,0 +1,666 @@ +#pragma once + +const uint32_t draw_clockwise_atomic_path_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000c04,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0012000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000046a,0x0000046d,0x00000471, + 0x00000472,0x00000485,0x00000492,0x000004c6,0x000004cc,0x000004eb,0x0000050a,0x00000583, + 0x00000586,0x0000059a,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x0000014f,0x00004342,0x00030005,0x0000015f,0x0000664b,0x00040006,0x0000015f, + 0x00000000,0x00003464,0x00030005,0x00000161,0x00004358,0x00030005,0x00000174,0x0000664a, + 0x00040006,0x00000174,0x00000000,0x00003464,0x00030005,0x00000176,0x0000424c,0x00030005, + 0x00000456,0x0000424d,0x00040006,0x00000456,0x00000000,0x00006250,0x00040006,0x00000456, + 0x00000001,0x00006359,0x00040006,0x00000456,0x00000002,0x00006552,0x00040006,0x00000456, + 0x00000003,0x00006553,0x00040006,0x00000456,0x00000004,0x0000366d,0x00040006,0x00000456, + 0x00000005,0x0000676d,0x00040006,0x00000456,0x00000006,0x00006544,0x00040006,0x00000456, + 0x00000007,0x00006545,0x00040006,0x00000456,0x00000008,0x00003755,0x00040006,0x00000456, + 0x00000009,0x0000676a,0x00040006,0x00000456,0x0000000a,0x0000635a,0x00040006,0x00000456, + 0x0000000b,0x00003157,0x00040006,0x00000456,0x0000000c,0x0000676e,0x00040006,0x00000456, + 0x0000000d,0x00003559,0x00040006,0x00000456,0x0000000e,0x0000324f,0x00040006,0x00000456, + 0x0000000f,0x00006461,0x00040006,0x00000456,0x00000010,0x00006579,0x00040006,0x00000456, + 0x00000011,0x00003376,0x00040006,0x00000456,0x00000012,0x00003377,0x00040006,0x00000456, + 0x00000013,0x00006462,0x00040006,0x00000456,0x00000014,0x00006767,0x00030005,0x00000458, + 0x0000006b,0x00060005,0x0000046a,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005, + 0x0000046d,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005,0x00000471, + 0x00004254,0x00030005,0x00000472,0x00004255,0x00030005,0x00000485,0x00000049,0x00030005, + 0x0000048a,0x00006576,0x00040006,0x0000048a,0x00000000,0x00003464,0x00030005,0x0000048c, + 0x00004355,0x00030005,0x00000492,0x0000307a,0x00030005,0x000004a8,0x00006747,0x00030005, + 0x000004c6,0x00003153,0x00030005,0x000004c9,0x00006749,0x00030005,0x000004cc,0x00003159, + 0x00030005,0x000004d5,0x00006748,0x00030005,0x000004da,0x00006577,0x00040006,0x000004da, + 0x00000000,0x00003464,0x00030005,0x000004dc,0x0000424f,0x00030005,0x000004eb,0x0000304e, + 0x00030005,0x0000050a,0x0000316b,0x00030005,0x00000583,0x00003361,0x00030005,0x00000586, + 0x00003469,0x00060005,0x00000598,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006, + 0x00000598,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000598,0x00000001, + 0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000598,0x00000002,0x435f6c67, + 0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000598,0x00000003,0x435f6c67,0x446c6c75, + 0x61747369,0x0065636e,0x00030005,0x0000059a,0x00000000,0x00030005,0x000005a8,0x00004351, + 0x00030005,0x000005ab,0x00003954,0x00040047,0x0000014f,0x00000021,0x00000008,0x00040047, + 0x0000014f,0x00000022,0x00000000,0x00040047,0x0000015e,0x00000006,0x00000010,0x00030047, + 0x0000015f,0x00000003,0x00040048,0x0000015f,0x00000000,0x00000018,0x00050048,0x0000015f, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000161,0x00000018,0x00040047,0x00000161, + 0x00000021,0x00000006,0x00040047,0x00000161,0x00000022,0x00000000,0x00040047,0x00000173, + 0x00000006,0x00000010,0x00030047,0x00000174,0x00000003,0x00040048,0x00000174,0x00000000, + 0x00000018,0x00050048,0x00000174,0x00000000,0x00000023,0x00000000,0x00030047,0x00000176, + 0x00000018,0x00040047,0x00000176,0x00000021,0x00000003,0x00040047,0x00000176,0x00000022, + 0x00000000,0x00030047,0x00000456,0x00000002,0x00050048,0x00000456,0x00000000,0x00000023, + 0x00000000,0x00050048,0x00000456,0x00000001,0x00000023,0x00000004,0x00050048,0x00000456, + 0x00000002,0x00000023,0x00000008,0x00050048,0x00000456,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x00000456,0x00000004,0x00000023,0x00000010,0x00050048,0x00000456,0x00000005, + 0x00000023,0x00000014,0x00050048,0x00000456,0x00000006,0x00000023,0x00000018,0x00050048, + 0x00000456,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000456,0x00000008,0x00000023, + 0x00000020,0x00050048,0x00000456,0x00000009,0x00000023,0x00000030,0x00050048,0x00000456, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x00000456,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x00000456,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000456,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x00000456,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x00000456,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000456,0x00000010,0x00000023, + 0x00000054,0x00050048,0x00000456,0x00000011,0x00000023,0x00000058,0x00050048,0x00000456, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x00000456,0x00000013,0x00000023,0x00000060, + 0x00050048,0x00000456,0x00000014,0x00000023,0x00000064,0x00040047,0x00000458,0x00000021, + 0x00000000,0x00040047,0x00000458,0x00000022,0x00000000,0x00040047,0x0000046a,0x0000000b, + 0x0000002a,0x00040047,0x0000046d,0x0000000b,0x0000002b,0x00040047,0x00000471,0x0000001e, + 0x00000000,0x00040047,0x00000472,0x0000001e,0x00000001,0x00040047,0x00000485,0x0000001e, + 0x00000002,0x00040047,0x00000489,0x00000006,0x00000008,0x00030047,0x0000048a,0x00000003, + 0x00040048,0x0000048a,0x00000000,0x00000018,0x00050048,0x0000048a,0x00000000,0x00000023, + 0x00000000,0x00030047,0x0000048c,0x00000018,0x00040047,0x0000048c,0x00000021,0x00000004, + 0x00040047,0x0000048c,0x00000022,0x00000000,0x00030047,0x00000492,0x00000000,0x00030047, + 0x00000492,0x0000000e,0x00040047,0x00000492,0x0000001e,0x00000003,0x00030047,0x000004a1, + 0x00000000,0x00030047,0x000004a2,0x00000000,0x00040047,0x000004a8,0x00000001,0x00000000, + 0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c6, + 0x0000000e,0x00040047,0x000004c6,0x0000001e,0x00000004,0x00040047,0x000004c9,0x00000001, + 0x00000002,0x00030047,0x000004cc,0x00000000,0x00030047,0x000004cc,0x0000000e,0x00040047, + 0x000004cc,0x0000001e,0x00000006,0x00040047,0x000004d5,0x00000001,0x00000001,0x00040047, + 0x000004d9,0x00000006,0x00000010,0x00030047,0x000004da,0x00000003,0x00040048,0x000004da, + 0x00000000,0x00000018,0x00050048,0x000004da,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000004dc,0x00000018,0x00040047,0x000004dc,0x00000021,0x00000005,0x00040047,0x000004dc, + 0x00000022,0x00000000,0x00040047,0x000004eb,0x0000001e,0x00000005,0x00040047,0x0000050a, + 0x0000001e,0x00000000,0x00030047,0x00000583,0x0000000e,0x00040047,0x00000583,0x0000001e, + 0x00000007,0x00040047,0x00000586,0x0000001e,0x00000008,0x00030047,0x00000598,0x00000002, + 0x00050048,0x00000598,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000598,0x00000001, + 0x0000000b,0x00000001,0x00050048,0x00000598,0x00000002,0x0000000b,0x00000003,0x00050048, + 0x00000598,0x00000003,0x0000000b,0x00000004,0x00030047,0x000005a8,0x00000000,0x00040047, + 0x000005a8,0x00000021,0x0000000a,0x00040047,0x000005a8,0x00000022,0x00000000,0x00030047, + 0x000005ab,0x00000000,0x00040047,0x000005ab,0x00000021,0x0000000a,0x00040047,0x000005ab, + 0x00000022,0x00000000,0x00030047,0x000007c0,0x00000000,0x00030047,0x00000b79,0x00000000, + 0x00030047,0x00000bdf,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006,0x00000002,0x00020014, + 0x00000011,0x00040017,0x00000013,0x00000011,0x00000002,0x00040017,0x00000018,0x00000006, + 0x00000004,0x00040018,0x0000001a,0x0000000c,0x00000002,0x00040015,0x0000001f,0x00000020, + 0x00000000,0x00040015,0x0000003a,0x00000020,0x00000001,0x00040017,0x0000003c,0x0000003a, + 0x00000002,0x0004002b,0x00000006,0x00000060,0x3f800000,0x0004002b,0x00000006,0x00000061, + 0x00000000,0x0004002b,0x0000001f,0x0000006c,0x00000000,0x0004002b,0x0000001f,0x00000073, + 0x000003ff,0x0004002b,0x0000001f,0x00000083,0x00000001,0x0004002b,0x0000003a,0x0000008f, + 0x00000000,0x0004002b,0x0000003a,0x00000093,0x00000001,0x0004002b,0x00000006,0x000000bb, + 0x3f000000,0x0004002b,0x00000006,0x000000cd,0x3fc90fdb,0x0004002b,0x00000006,0x000000d0, + 0x3a83126f,0x0004002b,0x00000006,0x000000df,0x358637bd,0x0004002b,0x00000006,0x000000fc, + 0x3e800000,0x0004002b,0x00000006,0x00000102,0xc0000000,0x0004002b,0x0000001f,0x00000106, + 0x00000002,0x0004002b,0x0000001f,0x00000109,0x00000003,0x0004002b,0x0000003a,0x0000010f, + 0x000007ff,0x0004002b,0x0000003a,0x00000112,0x0000000b,0x0004002b,0x0000003a,0x00000137, + 0x00000002,0x0004002b,0x0000003a,0x0000013d,0x00000003,0x00040017,0x0000014a,0x0000001f, + 0x00000004,0x00090019,0x0000014d,0x0000001f,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x0000014e,0x00000000,0x0000014d,0x0004003b,0x0000014e, + 0x0000014f,0x00000000,0x0004002b,0x0000001f,0x0000015a,0x0000ffff,0x0003001d,0x0000015e, + 0x0000014a,0x0003001e,0x0000015f,0x0000015e,0x00040020,0x00000160,0x00000002,0x0000015f, + 0x0004003b,0x00000160,0x00000161,0x00000002,0x00040020,0x00000164,0x00000002,0x0000014a, + 0x00040017,0x00000168,0x0000001f,0x00000002,0x0003001d,0x00000173,0x0000014a,0x0003001e, + 0x00000174,0x00000173,0x00040020,0x00000175,0x00000002,0x00000174,0x0004003b,0x00000175, + 0x00000176,0x00000002,0x0004002b,0x0000001f,0x00000178,0x00000004,0x0004002b,0x0000001f, + 0x00000193,0x00800000,0x0004002b,0x0000001f,0x000001b3,0x0080ffff,0x0004002b,0x0000001f, + 0x000001d3,0xff7fffff,0x0004002b,0x0000001f,0x000001d8,0x1c000000,0x0004002b,0x0000001f, + 0x000001da,0x04000000,0x0004002b,0x0000003a,0x000001ea,0x00000010,0x0004002b,0x00000006, + 0x0000022f,0x40490fdb,0x0004002b,0x00000006,0x00000233,0x40c90fdb,0x0004002b,0x00000006, + 0x00000268,0x40000000,0x0004002b,0x0000001f,0x000002a2,0x00100000,0x0004002b,0x0000001f, + 0x000002aa,0x00080000,0x0004002b,0x0000001f,0x000002f8,0x08000000,0x0004002b,0x0000001f, + 0x000002fe,0x00400000,0x0004002b,0x00000006,0x00000332,0xbf000000,0x0004002b,0x0000001f, + 0x00000349,0x14000000,0x0004002b,0x0000001f,0x0000034f,0x10000000,0x0004002b,0x0000001f, + 0x00000359,0x02000000,0x0004002b,0x0000001f,0x00000371,0x00200000,0x0004002b,0x00000006, + 0x0000037c,0x3e000000,0x0004002b,0x00000006,0x000003ca,0x38d1b717,0x0003002a,0x00000011, + 0x000003de,0x0004002b,0x00000006,0x000003e2,0xbf800000,0x0004002b,0x00000006,0x000003e9, + 0x49742400,0x0004002b,0x0000001f,0x00000433,0x01000000,0x0007002c,0x00000018,0x00000439, + 0x000003e2,0x00000060,0x00000060,0x00000060,0x0004002b,0x0000001f,0x00000442,0x80000000, + 0x0005002c,0x0000000c,0x00000454,0x00000060,0x000003e2,0x00040017,0x00000455,0x0000003a, + 0x00000004,0x0017001e,0x00000456,0x00000006,0x00000006,0x00000006,0x00000006,0x0000001f, + 0x0000001f,0x0000001f,0x0000001f,0x00000455,0x0000000c,0x0000000c,0x0000001f,0x00000006, + 0x0000001f,0x00000006,0x00000006,0x0000001f,0x00000006,0x00000006,0x00000006,0x0000001f, + 0x00040020,0x00000457,0x00000002,0x00000456,0x0004003b,0x00000457,0x00000458,0x00000002, + 0x0004002b,0x0000003a,0x00000459,0x00000014,0x00040020,0x0000045a,0x00000002,0x0000001f, + 0x00030029,0x00000011,0x00000465,0x00040020,0x00000469,0x00000001,0x0000003a,0x0004003b, + 0x00000469,0x0000046a,0x00000001,0x0004003b,0x00000469,0x0000046d,0x00000001,0x00040020, + 0x00000470,0x00000001,0x00000018,0x0004003b,0x00000470,0x00000471,0x00000001,0x0004003b, + 0x00000470,0x00000472,0x00000001,0x00040020,0x00000484,0x00000003,0x00000018,0x0004003b, + 0x00000484,0x00000485,0x00000003,0x0003001d,0x00000489,0x00000168,0x0003001e,0x0000048a, + 0x00000489,0x00040020,0x0000048b,0x00000002,0x0000048a,0x0004003b,0x0000048b,0x0000048c, + 0x00000002,0x00040020,0x0000048e,0x00000002,0x00000168,0x00040020,0x00000491,0x00000003, + 0x00000006,0x0004003b,0x00000491,0x00000492,0x00000003,0x0004002b,0x0000003a,0x00000493, + 0x0000000d,0x0004002b,0x0000001f,0x0000049c,0x00000200,0x0004002b,0x0000001f,0x000004a6, + 0x0000000f,0x00030030,0x00000011,0x000004a8,0x00040020,0x000004c5,0x00000003,0x0000000c, + 0x0004003b,0x000004c5,0x000004c6,0x00000003,0x00030030,0x00000011,0x000004c9,0x0004003b, + 0x00000491,0x000004cc,0x00000003,0x0004002b,0x0000003a,0x000004cf,0x00000004,0x00030030, + 0x00000011,0x000004d5,0x0003001d,0x000004d9,0x00000018,0x0003001e,0x000004da,0x000004d9, + 0x00040020,0x000004db,0x00000002,0x000004da,0x0004003b,0x000004db,0x000004dc,0x00000002, + 0x00040020,0x000004e1,0x00000002,0x00000018,0x0004003b,0x00000484,0x000004eb,0x00000003, + 0x0004003b,0x00000484,0x0000050a,0x00000003,0x0004002b,0x00000006,0x00000542,0x3f666666, + 0x00040020,0x00000575,0x00000002,0x00000006,0x00040020,0x00000582,0x00000003,0x00000168, + 0x0004003b,0x00000582,0x00000583,0x00000003,0x0004003b,0x000004c5,0x00000586,0x00000003, + 0x0004002b,0x0000003a,0x0000058d,0x0000000e,0x0004001c,0x00000597,0x00000006,0x00000083, + 0x0006001e,0x00000598,0x00000018,0x00000006,0x00000597,0x00000597,0x00040020,0x00000599, + 0x00000003,0x00000598,0x0004003b,0x00000599,0x0000059a,0x00000003,0x00090019,0x000005a6, + 0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x000005a7,0x00000000,0x000005a6,0x0004003b,0x000005a7,0x000005a8,0x00000000,0x0002001a, + 0x000005a9,0x00040020,0x000005aa,0x00000000,0x000005a9,0x0004003b,0x000005aa,0x000005ab, + 0x00000000,0x00030001,0x00000006,0x00000ade,0x00030001,0x0000000c,0x00000bbd,0x0005002c, + 0x0000000c,0x00000bf4,0x00000060,0x00000060,0x0005002c,0x0000000c,0x00000bf5,0x000000bb, + 0x000000bb,0x0004002b,0x0000003a,0x00000bf7,0xfffffffe,0x0007002c,0x00000018,0x00000bf8, + 0x000000bb,0x000000bb,0x000000bb,0x000000bb,0x0004002b,0x00000006,0x00000bf9,0x3ea2f983, + 0x0004002b,0x00000006,0x00000bfa,0xc0400000,0x0003002e,0x0000000c,0x00000bfd,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000003a, + 0x0000046e,0x0000046d,0x0004003d,0x00000018,0x00000477,0x00000471,0x0004003d,0x00000018, + 0x00000479,0x00000472,0x000300f7,0x000008be,0x00000000,0x000300fb,0x0000006c,0x00000610, + 0x000200f8,0x00000610,0x00050051,0x00000006,0x00000612,0x00000477,0x00000000,0x0004006e, + 0x0000003a,0x00000613,0x00000612,0x00050051,0x00000006,0x00000615,0x00000477,0x00000001, + 0x00050051,0x00000006,0x00000617,0x00000477,0x00000002,0x00050051,0x00000006,0x00000619, + 0x00000477,0x00000003,0x0004007c,0x0000003a,0x0000061a,0x00000619,0x000500c3,0x0000003a, + 0x0000061b,0x0000061a,0x00000137,0x000500c7,0x0000003a,0x0000061f,0x0000061a,0x0000013d, + 0x00050082,0x0000003a,0x00000622,0x0000061b,0x00000093,0x0007000c,0x0000003a,0x00000623, + 0x00000001,0x00000027,0x00000613,0x00000622,0x00050084,0x0000003a,0x00000626,0x0000046e, + 0x0000061b,0x00050080,0x0000003a,0x00000628,0x00000626,0x00000623,0x0004003d,0x0000014d, + 0x00000629,0x0000014f,0x000500c7,0x0000003a,0x000008c3,0x00000628,0x0000010f,0x000500c3, + 0x0000003a,0x000008c5,0x00000628,0x00000112,0x00050050,0x0000003c,0x000008c6,0x000008c3, + 0x000008c5,0x0007005f,0x0000014a,0x0000062c,0x00000629,0x000008c6,0x00000002,0x0000008f, + 0x00050051,0x0000001f,0x0000062e,0x0000062c,0x00000003,0x000500c7,0x0000001f,0x00000630, + 0x0000062e,0x0000015a,0x0007000c,0x0000001f,0x00000631,0x00000001,0x00000029,0x00000630, + 0x00000083,0x00050082,0x0000001f,0x00000633,0x00000631,0x00000083,0x00060041,0x00000164, + 0x00000634,0x00000161,0x0000008f,0x00000633,0x0004003d,0x0000014a,0x00000635,0x00000634, + 0x0007004f,0x00000168,0x00000637,0x00000635,0x00000635,0x00000000,0x00000001,0x0004007c, + 0x0000000c,0x00000638,0x00000637,0x00050051,0x0000001f,0x0000063a,0x00000635,0x00000002, + 0x000500c7,0x0000001f,0x0000063b,0x0000063a,0x0000015a,0x00050051,0x0000001f,0x0000063d, + 0x00000635,0x00000003,0x00050084,0x0000001f,0x0000063f,0x0000063b,0x00000178,0x00060041, + 0x00000164,0x00000640,0x00000176,0x0000008f,0x0000063f,0x0004003d,0x0000014a,0x00000641, + 0x00000640,0x0004007c,0x00000018,0x00000642,0x00000641,0x00050051,0x00000006,0x000008cd, + 0x00000642,0x00000000,0x00050051,0x00000006,0x000008ce,0x00000642,0x00000001,0x00050051, + 0x00000006,0x000008cf,0x00000642,0x00000002,0x00050051,0x00000006,0x000008d0,0x00000642, + 0x00000003,0x00050050,0x0000000c,0x000008d1,0x000008cd,0x000008ce,0x00050050,0x0000000c, + 0x000008d2,0x000008cf,0x000008d0,0x00050050,0x0000001a,0x000008d3,0x000008d1,0x000008d2, + 0x00050080,0x0000001f,0x00000646,0x0000063f,0x00000083,0x00060041,0x00000164,0x00000647, + 0x00000176,0x0000008f,0x00000646,0x0004003d,0x0000014a,0x00000648,0x00000647,0x0007004f, + 0x00000168,0x0000064a,0x00000648,0x00000648,0x00000000,0x00000001,0x0004007c,0x0000000c, + 0x0000064b,0x0000064a,0x00050051,0x0000001f,0x0000064d,0x00000648,0x00000002,0x0004007c, + 0x00000006,0x0000064e,0x0000064d,0x00050051,0x0000001f,0x00000650,0x00000648,0x00000003, + 0x0004007c,0x00000006,0x00000651,0x00000650,0x000500c7,0x0000001f,0x00000653,0x0000062e, + 0x00000193,0x000500ab,0x00000011,0x00000655,0x00000653,0x0000006c,0x000300f7,0x0000065e, + 0x00000000,0x000400fa,0x00000655,0x00000656,0x0000065e,0x000200f8,0x00000656,0x00050051, + 0x00000006,0x00000658,0x00000479,0x00000000,0x0004006e,0x0000003a,0x00000659,0x00000658, + 0x00050051,0x00000006,0x0000065b,0x00000479,0x00000001,0x00050051,0x00000006,0x0000065d, + 0x00000479,0x00000002,0x000200f9,0x0000065e,0x000200f8,0x0000065e,0x000700f5,0x00000006, + 0x00000abf,0x00000617,0x00000610,0x0000065d,0x00000656,0x000700f5,0x00000006,0x00000a87, + 0x00000615,0x00000610,0x0000065b,0x00000656,0x000700f5,0x0000003a,0x00000a6b,0x00000613, + 0x00000610,0x00000659,0x00000656,0x000500ab,0x00000011,0x00000661,0x00000a6b,0x00000623, + 0x000300f7,0x0000068e,0x00000000,0x000400fa,0x00000661,0x00000662,0x0000068e,0x000200f8, + 0x00000662,0x00050080,0x0000003a,0x00000665,0x00000628,0x00000a6b,0x00050082,0x0000003a, + 0x00000667,0x00000665,0x00000623,0x0004003d,0x0000014d,0x00000668,0x0000014f,0x000500c7, + 0x0000003a,0x000008d7,0x00000667,0x0000010f,0x000500c3,0x0000003a,0x000008d9,0x00000667, + 0x00000112,0x00050050,0x0000003c,0x000008da,0x000008d7,0x000008d9,0x0007005f,0x0000014a, + 0x0000066b,0x00000668,0x000008da,0x00000002,0x0000008f,0x00050051,0x0000001f,0x0000066d, + 0x0000066b,0x00000003,0x000500c7,0x0000001f,0x0000066e,0x0000066d,0x000001b3,0x000500c7, + 0x0000001f,0x00000670,0x0000062e,0x000001b3,0x000500ab,0x00000011,0x00000671,0x0000066e, + 0x00000670,0x000300f7,0x00000688,0x00000000,0x000400fa,0x00000671,0x00000675,0x00000672, + 0x000200f8,0x00000672,0x000200f9,0x00000688,0x000200f8,0x00000675,0x000500b4,0x00000011, + 0x00000677,0x0000064e,0x00000061,0x000400a8,0x00000011,0x00000678,0x00000677,0x000300f7, + 0x0000067d,0x00000000,0x000400fa,0x00000678,0x00000679,0x0000067d,0x000200f8,0x00000679, + 0x00050051,0x00000006,0x0000067b,0x00000638,0x00000000,0x000500b7,0x00000011,0x0000067c, + 0x0000067b,0x00000061,0x000200f9,0x0000067d,0x000200f8,0x0000067d,0x000700f5,0x00000011, + 0x0000067e,0x00000677,0x00000675,0x0000067c,0x00000679,0x000300f7,0x00000687,0x00000000, + 0x000400fa,0x0000067e,0x00000680,0x00000687,0x000200f8,0x00000680,0x0004007c,0x0000003a, + 0x00000682,0x0000063d,0x0004003d,0x0000014d,0x00000683,0x0000014f,0x000500c7,0x0000003a, + 0x000008de,0x00000682,0x0000010f,0x000500c3,0x0000003a,0x000008e0,0x00000682,0x00000112, + 0x00050050,0x0000003c,0x000008e1,0x000008de,0x000008e0,0x0007005f,0x0000014a,0x00000686, + 0x00000683,0x000008e1,0x00000002,0x0000008f,0x000200f9,0x00000687,0x000200f8,0x00000687, + 0x000700f5,0x0000003a,0x00000a78,0x00000628,0x0000067d,0x00000682,0x00000680,0x000700f5, + 0x0000014a,0x00000a70,0x0000062c,0x0000067d,0x00000686,0x00000680,0x000200f9,0x00000688, + 0x000200f8,0x00000688,0x000700f5,0x0000003a,0x00000a77,0x00000667,0x00000672,0x00000a78, + 0x00000687,0x000700f5,0x0000014a,0x00000a6f,0x0000066b,0x00000672,0x00000a70,0x00000687, + 0x00050051,0x0000001f,0x0000068a,0x00000a6f,0x00000003,0x000500c7,0x0000001f,0x0000068b, + 0x0000068a,0x000001d3,0x000500c5,0x0000001f,0x0000068d,0x0000068b,0x00000653,0x000200f9, + 0x0000068e,0x000200f8,0x0000068e,0x000700f5,0x0000003a,0x00000a76,0x00000628,0x0000065e, + 0x00000a77,0x00000688,0x000700f5,0x0000014a,0x00000a74,0x0000062c,0x0000065e,0x00000a6f, + 0x00000688,0x000700f5,0x0000001f,0x00000a73,0x0000062e,0x0000065e,0x0000068d,0x00000688, + 0x000500c7,0x0000001f,0x00000690,0x00000a73,0x000001d8,0x000500aa,0x00000011,0x00000691, + 0x00000690,0x000001da,0x000500aa,0x00000011,0x00000693,0x0000061f,0x0000008f,0x000500a7, + 0x00000011,0x00000694,0x00000691,0x00000693,0x000300f7,0x0000071f,0x00000000,0x000400fa, + 0x00000694,0x00000699,0x00000695,0x000200f8,0x00000695,0x00050051,0x0000001f,0x00000697, + 0x00000a74,0x00000002,0x0004007c,0x00000006,0x00000698,0x00000697,0x000200f9,0x0000071f, + 0x000200f8,0x00000699,0x00050051,0x0000001f,0x0000069b,0x00000a74,0x00000002,0x000500c7, + 0x0000001f,0x0000069d,0x0000069b,0x0000015a,0x00040070,0x00000006,0x0000069e,0x0000069d, + 0x000500c2,0x0000001f,0x000006a0,0x0000069b,0x000001ea,0x00040070,0x00000006,0x000006a1, + 0x000006a0,0x00050083,0x00000006,0x000006a4,0x000003e2,0x0000069e,0x0004006e,0x0000003a, + 0x000006a5,0x000006a4,0x00050083,0x00000006,0x000006a8,0x000006a1,0x0000069e,0x00050081, + 0x00000006,0x000006a9,0x000006a8,0x00000060,0x0004006e,0x0000003a,0x000006aa,0x000006a9, + 0x00050050,0x0000003c,0x000006ab,0x000006a5,0x000006aa,0x000500c7,0x0000001f,0x000006ad, + 0x00000a73,0x00000193,0x000500ab,0x00000011,0x000006ae,0x000006ad,0x0000006c,0x000300f7, + 0x000006b2,0x00000000,0x000400fa,0x000006ae,0x000006af,0x000006b2,0x000200f8,0x000006af, + 0x0004007e,0x0000003c,0x000006b1,0x000006ab,0x000200f9,0x000006b2,0x000200f8,0x000006b2, + 0x000700f5,0x0000003c,0x00000a7a,0x000006ab,0x00000699,0x000006b1,0x000006af,0x0004003d, + 0x0000014d,0x000006b3,0x0000014f,0x00050051,0x0000003a,0x000006b6,0x00000a7a,0x00000000, + 0x00050080,0x0000003a,0x000006b7,0x00000a76,0x000006b6,0x000500c7,0x0000003a,0x000008e5, + 0x000006b7,0x0000010f,0x000500c3,0x0000003a,0x000008e7,0x000006b7,0x00000112,0x00050050, + 0x0000003c,0x000008e8,0x000008e5,0x000008e7,0x0007005f,0x0000014a,0x000006b9,0x000006b3, + 0x000008e8,0x00000002,0x0000008f,0x0004003d,0x0000014d,0x000006ba,0x0000014f,0x00050051, + 0x0000003a,0x000006bd,0x00000a7a,0x00000001,0x00050080,0x0000003a,0x000006be,0x00000a76, + 0x000006bd,0x000500c7,0x0000003a,0x000008ec,0x000006be,0x0000010f,0x000500c3,0x0000003a, + 0x000008ee,0x000006be,0x00000112,0x00050050,0x0000003c,0x000008ef,0x000008ec,0x000008ee, + 0x0007005f,0x0000014a,0x000006c0,0x000006ba,0x000008ef,0x00000002,0x0000008f,0x00050051, + 0x0000001f,0x000006c2,0x000006c0,0x00000003,0x000500c7,0x0000001f,0x000006c3,0x000006c2, + 0x000001b3,0x00050051,0x0000001f,0x000006c5,0x000006b9,0x00000003,0x000500c7,0x0000001f, + 0x000006c6,0x000006c5,0x000001b3,0x000500ab,0x00000011,0x000006c7,0x000006c3,0x000006c6, + 0x000300f7,0x000006ce,0x00000000,0x000400fa,0x000006c7,0x000006c8,0x000006ce,0x000200f8, + 0x000006c8,0x0004003d,0x0000014d,0x000006c9,0x0000014f,0x0004007c,0x0000003a,0x000006cb, + 0x0000063d,0x000500c7,0x0000003a,0x000008f3,0x000006cb,0x0000010f,0x000500c3,0x0000003a, + 0x000008f5,0x000006cb,0x00000112,0x00050050,0x0000003c,0x000008f6,0x000008f3,0x000008f5, + 0x0007005f,0x0000014a,0x000006cd,0x000006c9,0x000008f6,0x00000002,0x0000008f,0x000200f9, + 0x000006ce,0x000200f8,0x000006ce,0x000700f5,0x0000014a,0x00000a7b,0x000006c0,0x000006b2, + 0x000006cd,0x000006c8,0x00050051,0x0000001f,0x000006d0,0x000006b9,0x00000002,0x0004007c, + 0x00000006,0x000006d1,0x000006d0,0x00050051,0x0000001f,0x000006d3,0x00000a7b,0x00000002, + 0x0004007c,0x00000006,0x000006d4,0x000006d3,0x00050083,0x00000006,0x000006d7,0x000006d4, + 0x000006d1,0x0006000c,0x00000006,0x000006d9,0x00000001,0x00000004,0x000006d7,0x000500ba, + 0x00000011,0x000006da,0x000006d9,0x0000022f,0x000300f7,0x000006e1,0x00000000,0x000400fa, + 0x000006da,0x000006db,0x000006e1,0x000200f8,0x000006db,0x0006000c,0x00000006,0x000006dd, + 0x00000001,0x00000006,0x000006d7,0x00050085,0x00000006,0x000006de,0x00000233,0x000006dd, + 0x00050083,0x00000006,0x000006e0,0x000006d7,0x000006de,0x000200f9,0x000006e1,0x000200f8, + 0x000006e1,0x000700f5,0x00000006,0x00000a7f,0x000006d7,0x000006ce,0x000006e0,0x000006db, + 0x00050081,0x00000006,0x000006e4,0x000006a1,0x00000102,0x0006000c,0x00000006,0x000006e6, + 0x00000001,0x00000004,0x00000a7f,0x00050085,0x00000006,0x000006e7,0x000006e6,0x00000bf9, + 0x00050085,0x00000006,0x000006e9,0x000006e7,0x000006e4,0x0006000c,0x00000006,0x000006ea, + 0x00000001,0x00000001,0x000006e9,0x00050081,0x00000006,0x000006ec,0x000006a1,0x00000bfa, + 0x0008000c,0x00000006,0x000006ed,0x00000001,0x0000002b,0x000006ea,0x00000060,0x000006ec, + 0x00050083,0x00000006,0x000006f0,0x000006e4,0x000006ed,0x000500bc,0x00000011,0x000006f3, + 0x0000069e,0x000006f0,0x000300f7,0x00000710,0x00000000,0x000400fa,0x000006f3,0x00000701, + 0x000006f4,0x000200f8,0x000006f4,0x00050081,0x00000006,0x000006f7,0x000006f0,0x00000060, + 0x000500b4,0x00000011,0x000006f8,0x0000069e,0x000006f7,0x000300f7,0x00000700,0x00000000, + 0x000400fa,0x000006f8,0x000006ff,0x000006f9,0x000200f8,0x000006f9,0x00050081,0x00000006, + 0x000006fb,0x000006f0,0x00000268,0x00050083,0x00000006,0x000006fd,0x0000069e,0x000006fb, + 0x000200f9,0x00000700,0x000200f8,0x000006ff,0x000200f9,0x00000700,0x000200f8,0x00000700, + 0x000700f5,0x00000006,0x00000a8c,0x000006fd,0x000006f9,0x00000061,0x000006ff,0x000600a9, + 0x00000006,0x00000bfe,0x000006f8,0x00000061,0x00000a87,0x000600a9,0x00000006,0x00000bff, + 0x000006f8,0x00000061,0x000006ed,0x000200f9,0x00000710,0x000200f8,0x00000701,0x0006000c, + 0x00000006,0x00000703,0x00000001,0x00000006,0x00000a7f,0x00050085,0x00000006,0x00000704, + 0x0000022f,0x00000703,0x00050083,0x00000006,0x00000706,0x00000704,0x00000a7f,0x0004007f, + 0x00000006,0x00000707,0x00000706,0x000500b4,0x00000011,0x0000070b,0x0000069e,0x000006f0, + 0x000300f7,0x0000070f,0x00000000,0x000400fa,0x0000070b,0x0000070c,0x0000070f,0x000200f8, + 0x0000070c,0x0004007f,0x00000006,0x0000070e,0x00000a87,0x000200f9,0x0000070f,0x000200f8, + 0x0000070f,0x000700f5,0x00000006,0x00000ad0,0x00000a87,0x00000701,0x0000070e,0x0000070c, + 0x000200f9,0x00000710,0x000200f8,0x00000710,0x000700f5,0x00000006,0x00000ace,0x00000bfe, + 0x00000700,0x00000ad0,0x0000070f,0x000700f5,0x00000006,0x00000a95,0x00000a7f,0x00000700, + 0x00000707,0x0000070f,0x000700f5,0x00000006,0x00000a8e,0x00000bff,0x00000700,0x000006f0, + 0x0000070f,0x000700f5,0x00000006,0x00000a8b,0x00000a8c,0x00000700,0x0000069e,0x0000070f, + 0x000500b4,0x00000011,0x00000713,0x00000a8b,0x00000a8e,0x000300f7,0x0000071e,0x00000000, + 0x000400fa,0x00000713,0x0000071c,0x00000714,0x000200f8,0x00000714,0x00050088,0x00000006, + 0x00000719,0x00000a8b,0x00000a8e,0x00050085,0x00000006,0x0000071a,0x00000a95,0x00000719, + 0x00050081,0x00000006,0x0000071b,0x000006d1,0x0000071a,0x000200f9,0x0000071e,0x000200f8, + 0x0000071c,0x000200f9,0x0000071e,0x000200f8,0x0000071e,0x000700f5,0x00000006,0x00000a99, + 0x0000071b,0x00000714,0x000006d4,0x0000071c,0x000200f9,0x0000071f,0x000200f8,0x0000071f, + 0x000700f5,0x00000006,0x00000ae4,0x00000ade,0x00000695,0x000006d1,0x0000071e,0x000700f5, + 0x00000006,0x00000adb,0x00000ade,0x00000695,0x00000a95,0x0000071e,0x000700f5,0x00000006, + 0x00000acc,0x00000a87,0x00000695,0x00000ace,0x0000071e,0x000700f5,0x00000006,0x00000a98, + 0x00000698,0x00000695,0x00000a99,0x0000071e,0x0006000c,0x00000006,0x00000721,0x00000001, + 0x0000000d,0x00000a98,0x0006000c,0x00000006,0x00000723,0x00000001,0x0000000e,0x00000a98, + 0x0004007f,0x00000006,0x00000724,0x00000723,0x00050050,0x0000000c,0x00000725,0x00000721, + 0x00000724,0x0007004f,0x00000168,0x00000727,0x00000a74,0x00000a74,0x00000000,0x00000001, + 0x0004007c,0x0000000c,0x00000728,0x00000727,0x000500b7,0x00000011,0x0000072a,0x00000651, + 0x00000061,0x000300f7,0x00000733,0x00000000,0x000400fa,0x0000072a,0x0000072b,0x00000733, + 0x000200f8,0x0000072b,0x00050091,0x0000000c,0x0000072f,0x000008d3,0x00000725,0x0006000c, + 0x00000006,0x00000730,0x00000001,0x00000042,0x0000072f,0x00050088,0x00000006,0x00000731, + 0x00000060,0x00000730,0x0007000c,0x00000006,0x00000732,0x00000001,0x00000028,0x00000651, + 0x00000731,0x000200f9,0x00000733,0x000200f8,0x00000733,0x000700f5,0x00000006,0x00000aca, + 0x00000651,0x0000071f,0x00000732,0x0000072b,0x000500b7,0x00000011,0x00000735,0x0000064e, + 0x00000061,0x000300f7,0x000008ab,0x00000000,0x000400fa,0x00000735,0x00000796,0x00000736, + 0x000200f8,0x00000736,0x00070050,0x00000018,0x00000738,0x00000abf,0x000003e2,0x00000061, + 0x00000061,0x000500b7,0x00000011,0x0000073a,0x00000aca,0x00000061,0x000300f7,0x0000077d, + 0x00000000,0x000400fa,0x0000073a,0x00000744,0x0000073b,0x000200f8,0x0000073b,0x0005008e, + 0x0000000c,0x0000073e,0x00000725,0x00000acc,0x0006000c,0x0000001a,0x00000740,0x00000001, + 0x00000022,0x000008d3,0x00050090,0x0000000c,0x00000741,0x0000073e,0x00000740,0x0006000c, + 0x0000000c,0x00000742,0x00000001,0x00000006,0x00000741,0x0005008e,0x0000000c,0x00000743, + 0x00000742,0x000000bb,0x000200f9,0x0000077d,0x000200f8,0x00000744,0x00060052,0x00000018, + 0x00000a24,0x00000102,0x00000738,0x00000001,0x00060052,0x00000018,0x00000a26,0x000003e9, + 0x00000a24,0x00000002,0x00060052,0x00000018,0x00000a28,0x00000abf,0x00000a26,0x00000003, + 0x000300f7,0x00000775,0x00000000,0x000400fa,0x00000694,0x0000074f,0x00000775,0x000200f8, + 0x0000074f,0x000500b8,0x00000011,0x00000751,0x00000adb,0x00000061,0x000300f7,0x00000758, + 0x00000000,0x000400fa,0x00000751,0x00000752,0x00000758,0x000200f8,0x00000752,0x00050081, + 0x00000006,0x00000755,0x00000ae4,0x00000adb,0x0004007f,0x00000006,0x00000757,0x00000adb, + 0x000200f9,0x00000758,0x000200f8,0x00000758,0x000700f5,0x00000006,0x00000aee,0x00000adb, + 0x0000074f,0x00000757,0x00000752,0x000700f5,0x00000006,0x00000aed,0x00000ae4,0x0000074f, + 0x00000755,0x00000752,0x00050083,0x00000006,0x0000075b,0x00000a98,0x00000aed,0x00050081, + 0x00000006,0x0000075d,0x0000075b,0x000000cd,0x0005008d,0x00000006,0x0000075e,0x0000075d, + 0x00000233,0x00050083,0x00000006,0x0000075f,0x0000075e,0x000000cd,0x0008000c,0x00000006, + 0x00000762,0x00000001,0x0000002b,0x0000075f,0x00000061,0x00000aee,0x00050085,0x00000006, + 0x00000765,0x00000aee,0x000000bb,0x000500ba,0x00000011,0x00000766,0x00000762,0x00000765, + 0x000300f7,0x0000076b,0x00000000,0x000400fa,0x00000766,0x00000767,0x0000076b,0x000200f8, + 0x00000767,0x00050083,0x00000006,0x0000076a,0x00000aee,0x00000762,0x000200f9,0x0000076b, + 0x000200f8,0x0000076b,0x000700f5,0x00000006,0x00000aef,0x00000762,0x00000758,0x0000076a, + 0x00000767,0x0006000c,0x00000006,0x0000076d,0x00000001,0x0000000d,0x00000aef,0x0006000c, + 0x00000006,0x0000076f,0x00000001,0x0000000e,0x00000aef,0x00050050,0x0000000c,0x00000770, + 0x0000076d,0x0000076f,0x0006000c,0x00000006,0x00000901,0x00000001,0x00000004,0x00000acc, + 0x0005008e,0x0000000c,0x00000902,0x00000770,0x00000901,0x00050083,0x0000000c,0x00000904, + 0x00000bf4,0x00000902,0x0005008e,0x0000000c,0x00000905,0x00000904,0x000000bb,0x00050083, + 0x00000006,0x00000907,0x00000aee,0x000000cd,0x0006000c,0x00000006,0x00000908,0x00000001, + 0x00000004,0x00000907,0x000500b8,0x00000011,0x00000909,0x00000908,0x000000d0,0x000300f7, + 0x0000092a,0x00000000,0x000400fa,0x00000909,0x00000929,0x0000090a,0x000200f8,0x0000090a, + 0x0006000c,0x00000006,0x0000090c,0x00000001,0x0000000f,0x00000aee,0x00050083,0x00000006, + 0x0000090e,0x000000cd,0x00000aee,0x0006000c,0x00000006,0x0000090f,0x00000001,0x00000006, + 0x0000090e,0x0006000c,0x00000006,0x00000911,0x00000001,0x00000004,0x0000090c,0x0007000c, + 0x00000006,0x00000912,0x00000001,0x00000028,0x00000911,0x000000df,0x00050088,0x00000006, + 0x00000913,0x0000090f,0x00000912,0x000500be,0x00000011,0x00000915,0x00000913,0x00000061, + 0x000300f7,0x00000927,0x00000000,0x000400fa,0x00000915,0x0000091e,0x00000916,0x000200f8, + 0x00000916,0x00050051,0x00000006,0x00000918,0x00000905,0x00000001,0x00050051,0x00000006, + 0x0000091a,0x00000905,0x00000000,0x00050085,0x00000006,0x0000091c,0x0000091a,0x0000090c, + 0x00050081,0x00000006,0x0000091d,0x00000918,0x0000091c,0x000200f9,0x00000927,0x000200f8, + 0x0000091e,0x00050051,0x00000006,0x00000920,0x00000905,0x00000001,0x00050051,0x00000006, + 0x00000922,0x00000905,0x00000000,0x00050083,0x00000006,0x00000923,0x00000060,0x00000922, + 0x00050085,0x00000006,0x00000925,0x00000923,0x0000090c,0x00050083,0x00000006,0x00000926, + 0x00000920,0x00000925,0x000200f9,0x00000927,0x000200f8,0x00000927,0x000700f5,0x00000006, + 0x00000af3,0x0000091d,0x00000916,0x00000926,0x0000091e,0x000200f9,0x0000092a,0x000200f8, + 0x00000929,0x000200f9,0x0000092a,0x000200f8,0x0000092a,0x000700f5,0x00000006,0x00000b09, + 0x00000af3,0x00000927,0x00000061,0x00000929,0x000700f5,0x00000006,0x00000b07,0x00000913, + 0x00000927,0x00000061,0x00000929,0x00050051,0x00000006,0x0000092c,0x00000905,0x00000000, + 0x0007000c,0x00000006,0x0000092d,0x00000001,0x00000028,0x0000092c,0x00000061,0x00050081, + 0x00000006,0x0000092e,0x0000092d,0x000000fc,0x00050051,0x00000006,0x00000931,0x00000905, + 0x00000001,0x00050083,0x00000006,0x00000933,0x00000102,0x00000931,0x00070050,0x00000018, + 0x00000bfb,0x0000092e,0x00000933,0x00000b07,0x00000b09,0x000200f9,0x00000775,0x000200f8, + 0x00000775,0x000700f5,0x00000018,0x00000b19,0x00000a28,0x00000744,0x00000bfb,0x0000092a, + 0x00050085,0x00000006,0x00000779,0x00000acc,0x00000aca,0x0005008e,0x0000000c,0x0000077b, + 0x00000725,0x00000779,0x00050091,0x0000000c,0x0000077c,0x000008d3,0x0000077b,0x000200f9, + 0x0000077d,0x000200f8,0x0000077d,0x000700f5,0x0000000c,0x00000baf,0x00000743,0x0000073b, + 0x0000077c,0x00000775,0x000700f5,0x00000018,0x00000b18,0x00000738,0x0000073b,0x00000b19, + 0x00000775,0x000500c7,0x0000001f,0x0000077f,0x00000a73,0x00000193,0x000500ab,0x00000011, + 0x00000780,0x0000077f,0x0000006c,0x000500c7,0x0000001f,0x00000782,0x00000a73,0x00000433, + 0x000500ab,0x00000011,0x00000783,0x00000782,0x0000006c,0x000500a5,0x00000011,0x00000784, + 0x00000780,0x00000783,0x000300f7,0x00000788,0x00000000,0x000400fa,0x00000784,0x00000785, + 0x00000788,0x000200f8,0x00000785,0x00050085,0x00000018,0x00000787,0x00000b18,0x00000439, + 0x000200f9,0x00000788,0x000200f8,0x00000788,0x000700f5,0x00000018,0x00000bb2,0x00000b18, + 0x0000077d,0x00000787,0x00000785,0x000500aa,0x00000011,0x0000078a,0x0000061f,0x00000137, + 0x00050050,0x00000013,0x00000c00,0x0000078a,0x0000078a,0x000600a9,0x0000000c,0x00000c01, + 0x00000c00,0x00000638,0x00000728,0x000500c7,0x0000001f,0x0000078f,0x00000a73,0x00000442, + 0x000500ab,0x00000011,0x00000790,0x0000078f,0x0000006c,0x000500ab,0x00000011,0x00000792, + 0x0000061f,0x00000093,0x000500a7,0x00000011,0x00000793,0x00000790,0x00000792,0x000300f7, + 0x00000795,0x00000000,0x000400fa,0x00000793,0x00000794,0x00000795,0x000200f8,0x00000794, + 0x000200f9,0x000008be,0x000200f8,0x00000795,0x000200f9,0x000008ab,0x000200f8,0x00000796, + 0x0006000c,0x00000006,0x00000798,0x00000001,0x00000021,0x000008d3,0x0006000c,0x00000006, + 0x00000799,0x00000001,0x00000006,0x00000798,0x00050085,0x00000006,0x0000079b,0x00000acc, + 0x00000799,0x000500c7,0x0000001f,0x0000079d,0x00000a73,0x000002a2,0x000500ab,0x00000011, + 0x0000079e,0x0000079d,0x0000006c,0x000300f7,0x000007a2,0x00000000,0x000400fa,0x0000079e, + 0x0000079f,0x000007a2,0x000200f8,0x0000079f,0x0007000c,0x00000006,0x000007a1,0x00000001, + 0x00000025,0x0000079b,0x00000061,0x000200f9,0x000007a2,0x000200f8,0x000007a2,0x000700f5, + 0x00000006,0x00000b1d,0x0000079b,0x00000796,0x000007a1,0x0000079f,0x000500c7,0x0000001f, + 0x000007a4,0x00000a73,0x000002aa,0x000500ab,0x00000011,0x000007a5,0x000007a4,0x0000006c, + 0x000300f7,0x000007a9,0x00000000,0x000400fa,0x000007a5,0x000007a6,0x000007a9,0x000200f8, + 0x000007a6,0x0007000c,0x00000006,0x000007a8,0x00000001,0x00000028,0x00000b1d,0x00000061, + 0x000200f9,0x000007a9,0x000200f8,0x000007a9,0x000700f5,0x00000006,0x00000b28,0x00000b1d, + 0x000007a2,0x000007a8,0x000007a6,0x000500b7,0x00000011,0x000007ab,0x00000aca,0x00000061, + 0x000300f7,0x000007b3,0x00000000,0x000400fa,0x000007ab,0x000007b1,0x000007ac,0x000200f8, + 0x000007ac,0x00050091,0x0000000c,0x0000093f,0x000008d3,0x00000725,0x00050051,0x00000006, + 0x00000941,0x0000093f,0x00000000,0x0006000c,0x00000006,0x00000942,0x00000001,0x00000004, + 0x00000941,0x00050051,0x00000006,0x00000944,0x0000093f,0x00000001,0x0006000c,0x00000006, + 0x00000945,0x00000001,0x00000004,0x00000944,0x00050081,0x00000006,0x00000946,0x00000942, + 0x00000945,0x00050094,0x00000006,0x00000949,0x0000093f,0x0000093f,0x00050088,0x00000006, + 0x0000094a,0x00000060,0x00000949,0x00050085,0x00000006,0x0000094b,0x00000946,0x0000094a, + 0x00050085,0x00000006,0x000007b0,0x0000094b,0x000000bb,0x000200f9,0x000007b3,0x000200f8, + 0x000007b1,0x000200f9,0x000007b3,0x000200f8,0x000007b3,0x000700f5,0x00000006,0x00000b20, + 0x000007b0,0x000007ac,0x00000aca,0x000007b1,0x000500ba,0x00000011,0x000007b7,0x00000b20, + 0x0000064e,0x000500b4,0x00000011,0x000007b9,0x00000aca,0x00000061,0x000500a7,0x00000011, + 0x000007ba,0x000007b7,0x000007b9,0x000300f7,0x000007c2,0x00000000,0x000400fa,0x000007ba, + 0x000007bb,0x000007c2,0x000200f8,0x000007bb,0x00050088,0x00000006,0x000007c0,0x0000064e, + 0x00000b20,0x000200f9,0x000007c2,0x000200f8,0x000007c2,0x000700f5,0x00000006,0x00000b79, + 0x00000060,0x000007b3,0x000007c0,0x000007bb,0x000600a9,0x00000006,0x00000c02,0x000007ba, + 0x00000b20,0x0000064e,0x00050081,0x00000006,0x000007c6,0x00000c02,0x00000b20,0x0005008e, + 0x0000000c,0x000007c7,0x00000725,0x000007c6,0x00050085,0x00000006,0x000007cc,0x00000b28, + 0x000007c6,0x00050088,0x00000006,0x000007cf,0x000000bb,0x00000b20,0x0004007f,0x00000006, + 0x000007d2,0x000007cc,0x00050050,0x0000000c,0x000007d3,0x000007cc,0x000007d2,0x00050050, + 0x0000000c,0x000007d5,0x00000c02,0x00000c02,0x00050081,0x0000000c,0x000007d6,0x000007d3, + 0x000007d5,0x0005008e,0x0000000c,0x000007d7,0x000007d6,0x000007cf,0x00050081,0x0000000c, + 0x000007d9,0x000007d7,0x00000bf5,0x00050051,0x00000006,0x000007db,0x000007d9,0x00000000, + 0x00050051,0x00000006,0x000007dd,0x000007d9,0x00000001,0x00070050,0x00000018,0x00000bfc, + 0x000007db,0x000007dd,0x00000061,0x00000061,0x000500ac,0x00000011,0x000007e6,0x00000690, + 0x000002f8,0x000300f7,0x0000088d,0x00000000,0x000400fa,0x000007e6,0x000007e7,0x0000088d, + 0x000200f8,0x000007e7,0x000500c7,0x0000001f,0x000007e9,0x00000a73,0x000002fe,0x000500aa, + 0x00000011,0x000007ea,0x000007e9,0x0000006c,0x000600a9,0x0000003a,0x00000c03,0x000007ea, + 0x00000bf7,0x00000137,0x000500c7,0x0000001f,0x000007f0,0x00000a73,0x00000193,0x000500ab, + 0x00000011,0x000007f1,0x000007f0,0x0000006c,0x000300f7,0x000007f5,0x00000000,0x000400fa, + 0x000007f1,0x000007f2,0x000007f5,0x000200f8,0x000007f2,0x0004007e,0x0000003a,0x000007f4, + 0x00000c03,0x000200f9,0x000007f5,0x000200f8,0x000007f5,0x000700f5,0x0000003a,0x00000b4e, + 0x00000c03,0x000007e7,0x000007f4,0x000007f2,0x00050080,0x0000003a,0x000007f8,0x00000a76, + 0x00000b4e,0x000500c7,0x0000003a,0x0000095d,0x000007f8,0x0000010f,0x000500c3,0x0000003a, + 0x0000095f,0x000007f8,0x00000112,0x00050050,0x0000003c,0x00000960,0x0000095d,0x0000095f, + 0x0004003d,0x0000014d,0x000007fa,0x0000014f,0x0007005f,0x0000014a,0x000007fc,0x000007fa, + 0x00000960,0x00000002,0x0000008f,0x00050051,0x0000001f,0x000007fe,0x000007fc,0x00000002, + 0x0004007c,0x00000006,0x000007ff,0x000007fe,0x00050083,0x00000006,0x00000802,0x000007ff, + 0x00000a98,0x0006000c,0x00000006,0x00000803,0x00000001,0x00000004,0x00000802,0x000500ba, + 0x00000011,0x00000805,0x00000803,0x0000022f,0x000300f7,0x00000809,0x00000000,0x000400fa, + 0x00000805,0x00000806,0x00000809,0x000200f8,0x00000806,0x00050083,0x00000006,0x00000808, + 0x00000233,0x00000803,0x000200f9,0x00000809,0x000200f8,0x00000809,0x000700f5,0x00000006, + 0x00000b57,0x00000803,0x000007f5,0x00000808,0x00000806,0x000500ab,0x00000011,0x0000080c, + 0x000007e9,0x0000006c,0x000500a4,0x00000011,0x00000813,0x0000080c,0x0000079e,0x000600a9, + 0x00000006,0x00000814,0x00000813,0x00000332,0x000000bb,0x00050085,0x00000006,0x00000815, + 0x00000b57,0x00000814,0x00050081,0x00000006,0x00000817,0x00000815,0x00000a98,0x0006000c, + 0x00000006,0x00000819,0x00000001,0x0000000d,0x00000817,0x0006000c,0x00000006,0x0000081b, + 0x00000001,0x0000000e,0x00000817,0x0004007f,0x00000006,0x0000081c,0x0000081b,0x00050050, + 0x0000000c,0x0000081d,0x00000819,0x0000081c,0x00050091,0x0000000c,0x00000966,0x000008d3, + 0x0000081d,0x00050051,0x00000006,0x00000968,0x00000966,0x00000000,0x0006000c,0x00000006, + 0x00000969,0x00000001,0x00000004,0x00000968,0x00050051,0x00000006,0x0000096b,0x00000966, + 0x00000001,0x0006000c,0x00000006,0x0000096c,0x00000001,0x00000004,0x0000096b,0x00050081, + 0x00000006,0x0000096d,0x00000969,0x0000096c,0x00050094,0x00000006,0x00000970,0x00000966, + 0x00000966,0x00050088,0x00000006,0x00000971,0x00000060,0x00000970,0x00050085,0x00000006, + 0x00000972,0x0000096d,0x00000971,0x00050085,0x00000006,0x00000822,0x00000b57,0x000000bb, + 0x0006000c,0x00000006,0x00000823,0x00000001,0x0000000e,0x00000822,0x000500aa,0x00000011, + 0x00000825,0x00000690,0x00000349,0x000400a8,0x00000011,0x00000826,0x00000825,0x000300f7, + 0x0000082d,0x00000000,0x000400fa,0x00000826,0x00000827,0x0000082d,0x000200f8,0x00000827, + 0x000500aa,0x00000011,0x00000829,0x00000690,0x0000034f,0x000500be,0x00000011,0x0000082b, + 0x00000823,0x000000fc,0x000500a7,0x00000011,0x0000082c,0x00000829,0x0000082b,0x000200f9, + 0x0000082d,0x000200f8,0x0000082d,0x000700f5,0x00000011,0x0000082e,0x00000825,0x00000809, + 0x0000082c,0x00000827,0x000300f7,0x00000841,0x00000000,0x000400fa,0x0000082e,0x00000836, + 0x0000082f,0x000200f8,0x0000082f,0x00050085,0x00000006,0x00000832,0x00000c02,0x00000823, + 0x00050085,0x00000006,0x00000834,0x00000972,0x000000bb,0x00050081,0x00000006,0x00000835, + 0x00000832,0x00000834,0x000200f9,0x00000841,0x000200f8,0x00000836,0x000500c7,0x0000001f, + 0x00000838,0x00000a73,0x00000359,0x000500ab,0x00000011,0x00000839,0x00000838,0x0000006c, + 0x000600a9,0x00000006,0x0000083a,0x00000839,0x00000060,0x000000fc,0x0007000c,0x00000006, + 0x0000083e,0x00000001,0x00000028,0x00000823,0x0000083a,0x00050088,0x00000006,0x0000083f, + 0x00000060,0x0000083e,0x00050085,0x00000006,0x00000840,0x00000c02,0x0000083f,0x000200f9, + 0x00000841,0x000200f8,0x00000841,0x000700f5,0x00000006,0x00000b5e,0x00000835,0x0000082f, + 0x00000840,0x00000836,0x00050085,0x00000006,0x00000844,0x00000972,0x000000bb,0x00050081, + 0x00000006,0x00000845,0x00000b5e,0x00000844,0x000500c7,0x0000001f,0x00000847,0x00000a73, + 0x00000371,0x000500ab,0x00000011,0x00000848,0x00000847,0x0000006c,0x000300f7,0x00000876, + 0x00000000,0x000400fa,0x00000848,0x00000849,0x00000876,0x000200f8,0x00000849,0x00050085, + 0x00000006,0x0000084e,0x00000b20,0x0000037c,0x00050085,0x00000006,0x00000852,0x00000845, + 0x00000823,0x00050081,0x00000006,0x00000854,0x00000852,0x0000084e,0x000500bc,0x00000011, + 0x00000855,0x000007c6,0x00000854,0x000300f7,0x00000875,0x00000000,0x000400fa,0x00000855, + 0x0000086d,0x00000856,0x000200f8,0x00000856,0x0005008e,0x0000000c,0x00000859,0x0000081d, + 0x00000845,0x00050094,0x00000006,0x0000085c,0x000007c7,0x000007c7,0x00050094,0x00000006, + 0x0000085f,0x00000859,0x00000859,0x00050050,0x0000000c,0x00000860,0x0000085c,0x0000085f, + 0x00050050,0x0000001a,0x0000086a,0x000007c7,0x00000859,0x0006000c,0x0000001a,0x0000086b, + 0x00000001,0x00000022,0x0000086a,0x00050090,0x0000000c,0x0000086c,0x00000860,0x0000086b, + 0x000200f9,0x00000875,0x000200f8,0x0000086d,0x00050088,0x00000006,0x00000870,0x00000060, + 0x00000823,0x00050085,0x00000006,0x00000871,0x000007c6,0x00000870,0x0005008e,0x0000000c, + 0x00000874,0x0000081d,0x00000871,0x000200f9,0x00000875,0x000200f8,0x00000875,0x000700f5, + 0x0000000c,0x00000b6e,0x0000086c,0x00000856,0x00000874,0x0000086d,0x000200f9,0x00000876, + 0x000200f8,0x00000876,0x000700f5,0x0000000c,0x00000b6d,0x000007c7,0x00000841,0x00000b6e, + 0x00000875,0x0006000c,0x00000006,0x00000878,0x00000001,0x00000004,0x00000b28,0x0005008e, + 0x0000000c,0x0000087a,0x00000b6d,0x00000878,0x00050094,0x00000006,0x0000087e,0x0000087a, + 0x0000081d,0x00050083,0x00000006,0x0000087f,0x00000845,0x0000087e,0x00050088,0x00000006, + 0x00000882,0x0000087f,0x00000972,0x000300f7,0x0000088c,0x00000000,0x000400fa,0x0000079e, + 0x00000889,0x00000886,0x000200f8,0x00000886,0x00060052,0x00000018,0x00000a45,0x00000882, + 0x00000bfc,0x00000000,0x000200f9,0x0000088c,0x000200f8,0x00000889,0x00060052,0x00000018, + 0x00000a47,0x00000882,0x00000bfc,0x00000001,0x000200f9,0x0000088c,0x000200f8,0x0000088c, + 0x000700f5,0x00000018,0x00000b83,0x00000a45,0x00000886,0x00000a47,0x00000889,0x000200f9, + 0x0000088d,0x000200f8,0x0000088d,0x000700f5,0x0000000c,0x00000b92,0x000007c7,0x000007c2, + 0x00000b6d,0x0000088c,0x000700f5,0x00000018,0x00000b82,0x00000bfc,0x000007c2,0x00000b83, + 0x0000088c,0x0007004f,0x0000000c,0x00000890,0x00000b82,0x00000b82,0x00000000,0x00000001, + 0x0005008e,0x0000000c,0x00000891,0x00000890,0x00000b79,0x00050051,0x00000006,0x00000893, + 0x00000891,0x00000000,0x00060052,0x00000018,0x00000a49,0x00000893,0x00000b82,0x00000000, + 0x00050051,0x00000006,0x00000895,0x00000891,0x00000001,0x0007000c,0x00000006,0x00000898, + 0x00000001,0x00000028,0x00000895,0x000003ca,0x00060052,0x00000018,0x00000a4e,0x00000898, + 0x00000a49,0x00000001,0x000300f7,0x000008a1,0x00000000,0x000400fa,0x000007ab,0x0000089c, + 0x000008a1,0x000200f8,0x0000089c,0x00050083,0x00000006,0x0000089f,0x00000102,0x00000893, + 0x00060052,0x00000018,0x00000a51,0x0000089f,0x00000a4e,0x00000000,0x000200f9,0x000008a1, + 0x000200f8,0x000008a1,0x000700f5,0x00000018,0x00000bb3,0x00000a4e,0x0000088d,0x00000a51, + 0x0000089c,0x0005008e,0x0000000c,0x000008a5,0x00000b92,0x00000b28,0x00050091,0x0000000c, + 0x000008a6,0x000008d3,0x000008a5,0x000500ab,0x00000011,0x000008a8,0x0000061f,0x0000008f, + 0x000300f7,0x000008aa,0x00000000,0x000400fa,0x000008a8,0x000008a9,0x000008aa,0x000200f8, + 0x000008a9,0x000200f9,0x000008be,0x000200f8,0x000008aa,0x000200f9,0x000008ab,0x000200f8, + 0x000008ab,0x000700f5,0x00000018,0x00000bb0,0x00000bb2,0x00000795,0x00000bb3,0x000008aa, + 0x000700f5,0x0000000c,0x00000bac,0x00000baf,0x00000795,0x000008a6,0x000008aa,0x000700f5, + 0x0000000c,0x00000b94,0x00000c01,0x00000795,0x00000728,0x000008aa,0x00050091,0x0000000c, + 0x000008ae,0x000008d3,0x00000b94,0x00050081,0x0000000c,0x000008b0,0x000008ae,0x00000bac, + 0x00050081,0x0000000c,0x000008b2,0x000008b0,0x0000064b,0x0007004f,0x0000000c,0x000008b4, + 0x00000bb0,0x00000bb0,0x00000000,0x00000001,0x00050041,0x0000045a,0x000008b5,0x00000458, + 0x00000459,0x0004003d,0x0000001f,0x000008b6,0x000008b5,0x000500ab,0x00000011,0x000008b7, + 0x000008b6,0x0000006c,0x00050050,0x00000013,0x00000977,0x000008b7,0x000008b7,0x000600a9, + 0x0000000c,0x000008b9,0x00000977,0x00000454,0x000008b4,0x00050051,0x00000006,0x000008bb, + 0x000008b9,0x00000000,0x00060052,0x00000018,0x00000a53,0x000008bb,0x00000bb0,0x00000000, + 0x00050051,0x00000006,0x000008bd,0x000008b9,0x00000001,0x00060052,0x00000018,0x00000a55, + 0x000008bd,0x00000a53,0x00000001,0x000200f9,0x000008be,0x000200f8,0x000008be,0x000900f5, + 0x00000018,0x00000bdb,0x00000bb2,0x00000794,0x00000bb3,0x000008a9,0x00000a55,0x000008ab, + 0x000900f5,0x0000000c,0x00000bb5,0x00000bbd,0x00000794,0x00000bbd,0x000008a9,0x000008b2, + 0x000008ab,0x000900f5,0x00000011,0x00000bb4,0x000003de,0x00000794,0x000003de,0x000008a9, + 0x00000465,0x000008ab,0x0003003e,0x00000485,0x00000bdb,0x00060041,0x0000048e,0x0000048f, + 0x0000048c,0x0000008f,0x0000063b,0x0004003d,0x00000168,0x00000490,0x0000048f,0x00050041, + 0x0000045a,0x00000497,0x00000458,0x00000493,0x0004003d,0x0000001f,0x00000498,0x00000497, + 0x000500aa,0x00000011,0x0000097d,0x0000063b,0x0000006c,0x000300f7,0x00000986,0x00000000, + 0x000400fa,0x0000097d,0x00000985,0x0000097e,0x000200f8,0x0000097e,0x00050080,0x0000001f, + 0x00000980,0x0000063b,0x00000073,0x00050084,0x0000001f,0x00000982,0x00000980,0x00000498, + 0x0006000c,0x0000000c,0x00000983,0x00000001,0x0000003e,0x00000982,0x00050051,0x00000006, + 0x00000984,0x00000983,0x00000000,0x000200f9,0x00000986,0x000200f8,0x00000985,0x000200f9, + 0x00000986,0x000200f8,0x00000986,0x000700f5,0x00000006,0x00000bdc,0x00000984,0x0000097e, + 0x00000061,0x00000985,0x0003003e,0x00000492,0x00000bdc,0x00050051,0x0000001f,0x0000049b, + 0x00000490,0x00000000,0x000500c7,0x0000001f,0x0000049d,0x0000049b,0x0000049c,0x000500ab, + 0x00000011,0x0000049e,0x0000049d,0x0000006c,0x000300f7,0x000004a0,0x00000000,0x000400fa, + 0x0000049e,0x0000049f,0x000004a0,0x000200f8,0x0000049f,0x0004003d,0x00000006,0x000004a1, + 0x00000492,0x0004007f,0x00000006,0x000004a2,0x000004a1,0x0003003e,0x00000492,0x000004a2, + 0x000200f9,0x000004a0,0x000200f8,0x000004a0,0x000500c7,0x0000001f,0x000004a7,0x0000049b, + 0x000004a6,0x000300f7,0x000004aa,0x00000000,0x000400fa,0x000004a8,0x000004a9,0x000004aa, + 0x000200f8,0x000004a9,0x000500aa,0x00000011,0x000004ad,0x000004a7,0x0000006c,0x000300f7, + 0x000004b0,0x00000000,0x000400fa,0x000004ad,0x000004af,0x000004b3,0x000200f8,0x000004b3, + 0x000200f9,0x000004b0,0x000200f8,0x000004af,0x00050051,0x0000001f,0x000004b2,0x00000490, + 0x00000001,0x000200f9,0x000004b0,0x000200f8,0x000004b0,0x000700f5,0x0000001f,0x00000bdd, + 0x0000049b,0x000004b3,0x000004b2,0x000004af,0x000500c2,0x0000001f,0x000004b7,0x00000bdd, + 0x000001ea,0x000500aa,0x00000011,0x0000098e,0x000004b7,0x0000006c,0x000300f7,0x00000997, + 0x00000000,0x000400fa,0x0000098e,0x00000996,0x0000098f,0x000200f8,0x0000098f,0x00050080, + 0x0000001f,0x00000991,0x000004b7,0x00000073,0x00050084,0x0000001f,0x00000993,0x00000991, + 0x00000498,0x0006000c,0x0000000c,0x00000994,0x00000001,0x0000003e,0x00000993,0x00050051, + 0x00000006,0x00000995,0x00000994,0x00000000,0x000200f9,0x00000997,0x000200f8,0x00000996, + 0x000200f9,0x00000997,0x000200f8,0x00000997,0x000700f5,0x00000006,0x00000bde,0x00000995, + 0x0000098f,0x00000061,0x00000996,0x000300f7,0x000004c2,0x00000000,0x000400fa,0x000004ad, + 0x000004c1,0x000004c2,0x000200f8,0x000004c1,0x0004007f,0x00000006,0x000004c4,0x00000bde, + 0x000200f9,0x000004c2,0x000200f8,0x000004c2,0x000700f5,0x00000006,0x00000bdf,0x00000bde, + 0x00000997,0x000004c4,0x000004c1,0x00050041,0x00000491,0x000004c8,0x000004c6,0x0000006c, + 0x0003003e,0x000004c8,0x00000bdf,0x000200f9,0x000004aa,0x000200f8,0x000004aa,0x000300f7, + 0x000004cb,0x00000000,0x000400fa,0x000004c9,0x000004ca,0x000004cb,0x000200f8,0x000004ca, + 0x000500c2,0x0000001f,0x000004d0,0x0000049b,0x000004cf,0x000500c7,0x0000001f,0x000004d1, + 0x000004d0,0x000004a6,0x00040070,0x00000006,0x000004d2,0x000004d1,0x0003003e,0x000004cc, + 0x000004d2,0x000200f9,0x000004cb,0x000200f8,0x000004cb,0x000300f7,0x000004d7,0x00000000, + 0x000400fa,0x000004d5,0x000004d6,0x000004d7,0x000200f8,0x000004d6,0x00050080,0x0000001f, + 0x000004df,0x0000063f,0x00000106,0x00060041,0x000004e1,0x000004e2,0x000004dc,0x0000008f, + 0x000004df,0x0004003d,0x00000018,0x000004e3,0x000004e2,0x00050051,0x00000006,0x000009a0, + 0x000004e3,0x00000000,0x00050051,0x00000006,0x000009a1,0x000004e3,0x00000001,0x00050051, + 0x00000006,0x000009a2,0x000004e3,0x00000002,0x00050051,0x00000006,0x000009a3,0x000004e3, + 0x00000003,0x00050050,0x0000000c,0x000009a4,0x000009a0,0x000009a1,0x00050050,0x0000000c, + 0x000009a5,0x000009a2,0x000009a3,0x00050050,0x0000001a,0x000009a6,0x000009a4,0x000009a5, + 0x00050080,0x0000001f,0x000004e8,0x0000063f,0x00000109,0x00060041,0x000004e1,0x000004e9, + 0x000004dc,0x0000008f,0x000004e8,0x0004003d,0x00000018,0x000004ea,0x000004e9,0x0007004f, + 0x0000000c,0x000004f0,0x000004ea,0x000004ea,0x00000000,0x00000001,0x000300f7,0x000009dc, + 0x00000000,0x000300fb,0x0000006c,0x000009ae,0x000200f8,0x000009ae,0x0006000c,0x0000000c, + 0x000009b1,0x00000001,0x00000004,0x000009a4,0x0006000c,0x0000000c,0x000009b4,0x00000001, + 0x00000004,0x000009a5,0x00050081,0x0000000c,0x000009b5,0x000009b1,0x000009b4,0x00050051, + 0x00000006,0x000009b7,0x000009b5,0x00000000,0x000500b7,0x00000011,0x000009b8,0x000009b7, + 0x00000061,0x000300f7,0x000009bd,0x00000000,0x000400fa,0x000009b8,0x000009b9,0x000009bd, + 0x000200f8,0x000009b9,0x00050051,0x00000006,0x000009bb,0x000009b5,0x00000001,0x000500b7, + 0x00000011,0x000009bc,0x000009bb,0x00000061,0x000200f9,0x000009bd,0x000200f8,0x000009bd, + 0x000700f5,0x00000011,0x000009be,0x000009b8,0x000009ae,0x000009bc,0x000009b9,0x000300f7, + 0x000009db,0x00000000,0x000400fa,0x000009be,0x000009c2,0x000009bf,0x000200f8,0x000009bf, + 0x0009004f,0x00000018,0x000009c1,0x000004ea,0x00000bfd,0x00000000,0x00000001,0x00000000, + 0x00000001,0x000200f9,0x000009dc,0x000200f8,0x000009c2,0x00050088,0x0000000c,0x000009c5, + 0x00000bf4,0x000009b5,0x00050091,0x0000000c,0x000009c8,0x000009a6,0x00000bb5,0x00050081, + 0x0000000c,0x000009ca,0x000009c8,0x000004f0,0x0004007f,0x0000000c,0x000009cd,0x000009ca, + 0x00050051,0x00000006,0x000009ce,0x000009ca,0x00000000,0x00050051,0x00000006,0x000009cf, + 0x000009ca,0x00000001,0x00050051,0x00000006,0x000009d0,0x000009cd,0x00000000,0x00050051, + 0x00000006,0x000009d1,0x000009cd,0x00000001,0x00070050,0x00000018,0x000009d2,0x000009ce, + 0x000009cf,0x000009d0,0x000009d1,0x0009004f,0x00000018,0x000009d4,0x000009c5,0x000009c5, + 0x00000000,0x00000001,0x00000000,0x00000001,0x00050085,0x00000018,0x000009d5,0x000009d2, + 0x000009d4,0x00050081,0x00000018,0x000009d8,0x000009d5,0x000009d4,0x00050081,0x00000018, + 0x000009da,0x000009d8,0x00000bf8,0x000200f9,0x000009dc,0x000200f8,0x000009db,0x000100ff, + 0x000200f8,0x000009dc,0x000700f5,0x00000018,0x00000be0,0x000009c1,0x000009bf,0x000009da, + 0x000009c2,0x0003003e,0x000004eb,0x00000be0,0x000200f9,0x000004d7,0x000200f8,0x000004d7, + 0x000500aa,0x00000011,0x000004f5,0x000004a7,0x00000083,0x000300f7,0x000004f7,0x00000000, + 0x000400fa,0x000004f5,0x000004f6,0x0000050c,0x000200f8,0x0000050c,0x000500aa,0x00000011, + 0x0000050e,0x000004a7,0x0000006c,0x000500a7,0x00000011,0x0000050f,0x000004a8,0x0000050e, + 0x000300f7,0x00000511,0x00000000,0x000400fa,0x0000050f,0x00000510,0x0000051d,0x000200f8, + 0x0000051d,0x00060041,0x000004e1,0x00000522,0x000004dc,0x0000008f,0x0000063f,0x0004003d, + 0x00000018,0x00000523,0x00000522,0x00050051,0x00000006,0x000009e4,0x00000523,0x00000000, + 0x00050051,0x00000006,0x000009e5,0x00000523,0x00000001,0x00050051,0x00000006,0x000009e6, + 0x00000523,0x00000002,0x00050051,0x00000006,0x000009e7,0x00000523,0x00000003,0x00050050, + 0x0000000c,0x000009e8,0x000009e4,0x000009e5,0x00050050,0x0000000c,0x000009e9,0x000009e6, + 0x000009e7,0x00050050,0x0000001a,0x000009ea,0x000009e8,0x000009e9,0x00060041,0x000004e1, + 0x00000529,0x000004dc,0x0000008f,0x00000646,0x0004003d,0x00000018,0x0000052a,0x00000529, + 0x00050091,0x0000000c,0x0000052e,0x000009ea,0x00000bb5,0x0007004f,0x0000000c,0x00000530, + 0x0000052a,0x0000052a,0x00000000,0x00000001,0x00050081,0x0000000c,0x00000531,0x0000052e, + 0x00000530,0x000500aa,0x00000011,0x00000533,0x000004a7,0x00000106,0x000500aa,0x00000011, + 0x00000535,0x000004a7,0x00000109,0x000500a6,0x00000011,0x00000536,0x00000533,0x00000535, + 0x000300f7,0x00000538,0x00000000,0x000400fa,0x00000536,0x00000537,0x0000055d,0x000200f8, + 0x0000055d,0x00050051,0x0000001f,0x00000560,0x00000490,0x00000001,0x0004007c,0x00000006, + 0x00000561,0x00000560,0x00050051,0x00000006,0x00000564,0x0000052a,0x00000002,0x00050051, + 0x00000006,0x00000566,0x00000531,0x00000000,0x00050051,0x00000006,0x00000568,0x00000531, + 0x00000001,0x00050083,0x00000006,0x0000056b,0x00000102,0x00000564,0x00070050,0x00000018, + 0x0000056c,0x00000566,0x00000568,0x00000561,0x0000056b,0x0003003e,0x0000050a,0x0000056c, + 0x000200f9,0x00000538,0x000200f8,0x00000537,0x00050051,0x0000001f,0x0000053a,0x00000490, + 0x00000001,0x0004007c,0x00000006,0x0000053b,0x0000053a,0x0004007f,0x00000006,0x0000053c, + 0x0000053b,0x00050041,0x00000491,0x0000053d,0x0000050a,0x00000109,0x0003003e,0x0000053d, + 0x0000053c,0x00050051,0x00000006,0x00000540,0x0000052a,0x00000002,0x000500ba,0x00000011, + 0x00000543,0x00000540,0x00000542,0x000300f7,0x00000545,0x00000000,0x000400fa,0x00000543, + 0x00000544,0x00000547,0x000200f8,0x00000547,0x00050051,0x00000006,0x00000549,0x0000052a, + 0x00000003,0x00050041,0x00000491,0x0000054a,0x0000050a,0x00000106,0x0003003e,0x0000054a, + 0x00000549,0x000200f9,0x00000545,0x000200f8,0x00000544,0x00050041,0x00000491,0x00000546, + 0x0000050a,0x00000106,0x0003003e,0x00000546,0x00000268,0x000200f9,0x00000545,0x000200f8, + 0x00000545,0x000300f7,0x0000054e,0x00000000,0x000400fa,0x00000533,0x0000054d,0x00000553, + 0x000200f8,0x00000553,0x00050041,0x00000491,0x00000554,0x0000050a,0x00000106,0x0004003d, + 0x00000006,0x00000555,0x00000554,0x0004007f,0x00000006,0x00000556,0x00000555,0x0003003e, + 0x00000554,0x00000556,0x00050041,0x00000491,0x00000559,0x0000050a,0x0000006c,0x00050051, + 0x00000006,0x0000055a,0x00000531,0x00000000,0x0003003e,0x00000559,0x0000055a,0x00050041, + 0x00000491,0x0000055b,0x0000050a,0x00000083,0x00050051,0x00000006,0x0000055c,0x00000531, + 0x00000001,0x0003003e,0x0000055b,0x0000055c,0x000200f9,0x0000054e,0x000200f8,0x0000054d, + 0x00050041,0x00000491,0x0000054f,0x0000050a,0x00000083,0x0003003e,0x0000054f,0x00000061, + 0x00050051,0x00000006,0x00000551,0x00000531,0x00000000,0x00050041,0x00000491,0x00000552, + 0x0000050a,0x0000006c,0x0003003e,0x00000552,0x00000551,0x000200f9,0x0000054e,0x000200f8, + 0x0000054e,0x000200f9,0x00000538,0x000200f8,0x00000538,0x000200f9,0x00000511,0x000200f8, + 0x00000510,0x000500c2,0x0000001f,0x00000515,0x0000049b,0x000001ea,0x000500aa,0x00000011, + 0x000009f0,0x00000515,0x0000006c,0x000300f7,0x000009f9,0x00000000,0x000400fa,0x000009f0, + 0x000009f8,0x000009f1,0x000200f8,0x000009f1,0x00050080,0x0000001f,0x000009f3,0x00000515, + 0x00000073,0x00050084,0x0000001f,0x000009f5,0x000009f3,0x00000498,0x0006000c,0x0000000c, + 0x000009f6,0x00000001,0x0000003e,0x000009f5,0x00050051,0x00000006,0x000009f7,0x000009f6, + 0x00000000,0x000200f9,0x000009f9,0x000200f8,0x000009f8,0x000200f9,0x000009f9,0x000200f8, + 0x000009f9,0x000700f5,0x00000006,0x00000be1,0x000009f7,0x000009f1,0x00000061,0x000009f8, + 0x00050041,0x00000491,0x0000051c,0x000004c6,0x00000083,0x0003003e,0x0000051c,0x00000be1, + 0x000200f9,0x00000511,0x000200f8,0x00000511,0x000200f9,0x000004f7,0x000200f8,0x000004f6, + 0x00050051,0x0000001f,0x000004fa,0x00000490,0x00000001,0x0006000c,0x00000018,0x000004fb, + 0x00000001,0x00000040,0x000004fa,0x0003003e,0x0000050a,0x000004fb,0x000200f9,0x000004f7, + 0x000200f8,0x000004f7,0x000300f7,0x00000570,0x00000000,0x000400fa,0x00000bb4,0x0000056f, + 0x0000058c,0x000200f8,0x0000058c,0x00050041,0x00000575,0x0000058e,0x00000458,0x0000058d, + 0x0004003d,0x00000006,0x0000058f,0x0000058e,0x00070050,0x00000018,0x00000596,0x0000058f, + 0x0000058f,0x0000058f,0x0000058f,0x000200f9,0x00000570,0x000200f8,0x0000056f,0x00050041, + 0x00000575,0x00000576,0x00000458,0x00000137,0x0004003d,0x00000006,0x00000577,0x00000576, + 0x00050041,0x00000575,0x00000579,0x00000458,0x0000013d,0x0004003d,0x00000006,0x0000057a, + 0x00000579,0x00050051,0x00000006,0x000009ff,0x00000bb5,0x00000000,0x00050085,0x00000006, + 0x00000a01,0x000009ff,0x00000577,0x00050083,0x00000006,0x00000a02,0x00000a01,0x00000060, + 0x00050051,0x00000006,0x00000a04,0x00000bb5,0x00000001,0x00050085,0x00000006,0x00000a06, + 0x00000a04,0x0000057a,0x0006000c,0x00000006,0x00000a08,0x00000001,0x00000006,0x0000057a, + 0x00050083,0x00000006,0x00000a09,0x00000a06,0x00000a08,0x00070050,0x00000018,0x00000a0a, + 0x00000a02,0x00000a09,0x00000061,0x00000060,0x00050080,0x0000001f,0x0000057f,0x0000063f, + 0x00000109,0x00060041,0x00000164,0x00000580,0x00000176,0x0000008f,0x0000057f,0x0004003d, + 0x0000014a,0x00000581,0x00000580,0x0007004f,0x00000168,0x00000585,0x00000581,0x00000581, + 0x00000000,0x00000001,0x0003003e,0x00000583,0x00000585,0x0007004f,0x00000168,0x00000589, + 0x00000581,0x00000581,0x00000002,0x00000003,0x0004007c,0x0000000c,0x0000058a,0x00000589, + 0x00050081,0x0000000c,0x0000058b,0x00000bb5,0x0000058a,0x0003003e,0x00000586,0x0000058b, + 0x000200f9,0x00000570,0x000200f8,0x00000570,0x000700f5,0x00000018,0x00000bf2,0x00000596, + 0x0000058c,0x00000a0a,0x0000056f,0x00050041,0x00000484,0x0000059c,0x0000059a,0x0000008f, + 0x0003003e,0x0000059c,0x00000bf2,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_atomic_path.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ca313a8fd4fe8a1b40eec04acfaca051b06e8c06 GIT binary patch literal 21172 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.h new file mode 100644 index 000000000..80ae6e5c0 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.h @@ -0,0 +1,147 @@ +#pragma once + +const uint32_t draw_clockwise_clip_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000000d6,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000031,0x00020011,0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d, + 0x6168735f,0x5f726564,0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47, + 0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,0x000c000f,0x00000004, + 0x00000004,0x6e69616d,0x00000000,0x00000027,0x0000002e,0x00000034,0x000000a5,0x000000a6, + 0x000000a7,0x000000a8,0x00030010,0x00000004,0x00000007,0x00030010,0x00000004,0x000014f6, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x665f4252,0x6d676172,0x5f746e65, + 0x64616873,0x695f7265,0x7265746e,0x6b636f6c,0x00000000,0x00090004,0x415f4c47,0x735f4252, + 0x65646168,0x6d695f72,0x5f656761,0x64616f6c,0x6f74735f,0x00006572,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00060005,0x00000027,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x0000002e,0x00003153,0x00030005,0x00000034,0x00000049,0x00030005,0x0000003a,0x00003065, + 0x00030005,0x0000005a,0x0000674c,0x00030005,0x00000070,0x00003053,0x00030005,0x00000098, + 0x0000424d,0x00040006,0x00000098,0x00000000,0x00006250,0x00040006,0x00000098,0x00000001, + 0x00006359,0x00040006,0x00000098,0x00000002,0x00006552,0x00040006,0x00000098,0x00000003, + 0x00006553,0x00040006,0x00000098,0x00000004,0x0000366d,0x00040006,0x00000098,0x00000005, + 0x0000676d,0x00040006,0x00000098,0x00000006,0x00006544,0x00040006,0x00000098,0x00000007, + 0x00006545,0x00040006,0x00000098,0x00000008,0x00003755,0x00040006,0x00000098,0x00000009, + 0x0000676a,0x00040006,0x00000098,0x0000000a,0x0000635a,0x00040006,0x00000098,0x0000000b, + 0x00003157,0x00040006,0x00000098,0x0000000c,0x0000676e,0x00040006,0x00000098,0x0000000d, + 0x00003559,0x00040006,0x00000098,0x0000000e,0x0000324f,0x00040006,0x00000098,0x0000000f, + 0x00006461,0x00040006,0x00000098,0x00000010,0x00006579,0x00040006,0x00000098,0x00000011, + 0x00003376,0x00040006,0x00000098,0x00000012,0x00003377,0x00040006,0x00000098,0x00000013, + 0x00006462,0x00040006,0x00000098,0x00000014,0x00006767,0x00030005,0x0000009a,0x0000006b, + 0x00030005,0x0000009d,0x00003954,0x00030005,0x000000a0,0x00004444,0x00030005,0x000000a1, + 0x00004351,0x00030005,0x000000a2,0x00004344,0x00030005,0x000000a3,0x00006277,0x00030005, + 0x000000a4,0x00003552,0x00030005,0x000000a5,0x0000316b,0x00030005,0x000000a6,0x0000307a, + 0x00030005,0x000000a7,0x0000304e,0x00030005,0x000000a8,0x00003159,0x00030005,0x000000ab, + 0x0000306a,0x00030005,0x000000ae,0x00003466,0x00040047,0x00000027,0x0000000b,0x0000000f, + 0x00030047,0x0000002e,0x00000000,0x00030047,0x0000002e,0x0000000e,0x00040047,0x0000002e, + 0x0000001e,0x00000004,0x00030047,0x00000031,0x00000000,0x00030047,0x00000032,0x00000000, + 0x00040047,0x00000034,0x0000001e,0x00000002,0x00030047,0x0000003a,0x00000017,0x00040047, + 0x0000003a,0x00000021,0x00000001,0x00040047,0x0000003a,0x00000022,0x00000002,0x00030047, + 0x00000043,0x00000000,0x00030047,0x0000004d,0x00000000,0x00030047,0x00000056,0x00000000, + 0x00030047,0x00000059,0x00000000,0x00040047,0x0000005a,0x00000001,0x00000005,0x00030047, + 0x0000006d,0x00000000,0x00030047,0x00000070,0x00000017,0x00040047,0x00000070,0x00000021, + 0x00000003,0x00040047,0x00000070,0x00000022,0x00000002,0x00030047,0x00000077,0x00000000, + 0x00030047,0x00000082,0x00000000,0x00030047,0x0000008a,0x00000000,0x00030047,0x00000098, + 0x00000002,0x00050048,0x00000098,0x00000000,0x00000023,0x00000000,0x00050048,0x00000098, + 0x00000001,0x00000023,0x00000004,0x00050048,0x00000098,0x00000002,0x00000023,0x00000008, + 0x00050048,0x00000098,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000098,0x00000004, + 0x00000023,0x00000010,0x00050048,0x00000098,0x00000005,0x00000023,0x00000014,0x00050048, + 0x00000098,0x00000006,0x00000023,0x00000018,0x00050048,0x00000098,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x00000098,0x00000008,0x00000023,0x00000020,0x00050048,0x00000098, + 0x00000009,0x00000023,0x00000030,0x00050048,0x00000098,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x00000098,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000098,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x00000098,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x00000098,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000098,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x00000098,0x00000010,0x00000023,0x00000054,0x00050048,0x00000098, + 0x00000011,0x00000023,0x00000058,0x00050048,0x00000098,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x00000098,0x00000013,0x00000023,0x00000060,0x00050048,0x00000098,0x00000014, + 0x00000023,0x00000064,0x00040047,0x0000009a,0x00000021,0x00000000,0x00040047,0x0000009a, + 0x00000022,0x00000000,0x00030047,0x0000009d,0x00000000,0x00040047,0x0000009d,0x00000021, + 0x0000000a,0x00040047,0x0000009d,0x00000022,0x00000000,0x00030047,0x000000a0,0x00000000, + 0x00040047,0x000000a0,0x00000021,0x00000009,0x00040047,0x000000a0,0x00000022,0x00000000, + 0x00030047,0x000000a1,0x00000000,0x00040047,0x000000a1,0x00000021,0x0000000a,0x00040047, + 0x000000a1,0x00000022,0x00000000,0x00030047,0x000000a2,0x00000000,0x00040047,0x000000a2, + 0x00000021,0x0000000c,0x00040047,0x000000a2,0x00000022,0x00000001,0x00030047,0x000000a3, + 0x00000000,0x00040047,0x000000a3,0x00000021,0x00000009,0x00040047,0x000000a3,0x00000022, + 0x00000000,0x00030047,0x000000a4,0x00000000,0x00040047,0x000000a4,0x00000021,0x0000000c, + 0x00040047,0x000000a4,0x00000022,0x00000001,0x00040047,0x000000a5,0x0000001e,0x00000000, + 0x00030047,0x000000a6,0x00000000,0x00030047,0x000000a6,0x0000000e,0x00040047,0x000000a6, + 0x0000001e,0x00000003,0x00040047,0x000000a7,0x0000001e,0x00000005,0x00030047,0x000000a8, + 0x00000000,0x00030047,0x000000a8,0x0000000e,0x00040047,0x000000a8,0x0000001e,0x00000006, + 0x00030047,0x000000ab,0x00000000,0x00030047,0x000000ab,0x00000017,0x00040047,0x000000ab, + 0x00000021,0x00000000,0x00040047,0x000000ab,0x00000022,0x00000002,0x00030047,0x000000ae, + 0x00000000,0x00030047,0x000000ae,0x00000017,0x00040047,0x000000ae,0x00000021,0x00000002, + 0x00040047,0x000000ae,0x00000022,0x00000002,0x00030047,0x000000c6,0x00000000,0x00030047, + 0x000000c8,0x00000000,0x00030047,0x000000ca,0x00000000,0x00030047,0x000000cc,0x00000000, + 0x00030047,0x000000cd,0x00000000,0x00030047,0x000000ce,0x00000000,0x00030047,0x000000d4, + 0x00000000,0x00030047,0x000000d5,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006,0x00000002, + 0x00040015,0x00000018,0x00000020,0x00000000,0x0004002b,0x00000018,0x00000019,0x00000000, + 0x0004002b,0x00000018,0x0000001c,0x00000001,0x00040015,0x00000021,0x00000020,0x00000001, + 0x00040017,0x00000022,0x00000021,0x00000002,0x00040017,0x00000025,0x00000006,0x00000004, + 0x00040020,0x00000026,0x00000001,0x00000025,0x0004003b,0x00000026,0x00000027,0x00000001, + 0x00040020,0x0000002d,0x00000001,0x0000000c,0x0004003b,0x0000002d,0x0000002e,0x00000001, + 0x00040020,0x0000002f,0x00000001,0x00000006,0x0004003b,0x00000026,0x00000034,0x00000001, + 0x00090019,0x00000038,0x00000018,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000021,0x00040020,0x00000039,0x00000000,0x00000038,0x0004003b,0x00000039,0x0000003a, + 0x00000000,0x00040017,0x0000003d,0x00000018,0x00000004,0x00020014,0x00000047,0x0004002b, + 0x00000006,0x0000004f,0x00000000,0x00030030,0x00000047,0x0000005a,0x0004003b,0x00000039, + 0x00000070,0x00000000,0x00040017,0x00000097,0x00000021,0x00000004,0x0017001e,0x00000098, + 0x00000006,0x00000006,0x00000006,0x00000006,0x00000018,0x00000018,0x00000018,0x00000018, + 0x00000097,0x0000000c,0x0000000c,0x00000018,0x00000006,0x00000018,0x00000006,0x00000006, + 0x00000018,0x00000006,0x00000006,0x00000006,0x00000018,0x00040020,0x00000099,0x00000002, + 0x00000098,0x0004003b,0x00000099,0x0000009a,0x00000002,0x0002001a,0x0000009b,0x00040020, + 0x0000009c,0x00000000,0x0000009b,0x0004003b,0x0000009c,0x0000009d,0x00000000,0x00090019, + 0x0000009e,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x0000009f,0x00000000,0x0000009e,0x0004003b,0x0000009f,0x000000a0,0x00000000, + 0x0004003b,0x0000009f,0x000000a1,0x00000000,0x0004003b,0x0000009f,0x000000a2,0x00000000, + 0x0004003b,0x0000009c,0x000000a3,0x00000000,0x0004003b,0x0000009c,0x000000a4,0x00000000, + 0x0004003b,0x00000026,0x000000a5,0x00000001,0x0004003b,0x0000002f,0x000000a6,0x00000001, + 0x0004003b,0x00000026,0x000000a7,0x00000001,0x0004003b,0x0000002f,0x000000a8,0x00000001, + 0x00090019,0x000000a9,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000004,0x00040020,0x000000aa,0x00000000,0x000000a9,0x0004003b,0x000000aa,0x000000ab, + 0x00000000,0x00090019,0x000000ac,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000002,0x0000000b,0x00040020,0x000000ad,0x00000000,0x000000ac,0x0004003b,0x000000ad, + 0x000000ae,0x00000000,0x00030001,0x0000000c,0x000000d1,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000025,0x00000028,0x00000027, + 0x0007004f,0x0000000c,0x00000029,0x00000028,0x00000028,0x00000000,0x00000001,0x0006000c, + 0x0000000c,0x0000002a,0x00000001,0x00000008,0x00000029,0x0004006e,0x00000022,0x0000002b, + 0x0000002a,0x00050041,0x0000002f,0x00000030,0x0000002e,0x00000019,0x0004003d,0x00000006, + 0x00000031,0x00000030,0x0004007f,0x00000006,0x00000032,0x00000031,0x00050041,0x0000002f, + 0x00000035,0x00000034,0x00000019,0x0004003d,0x00000006,0x00000036,0x00000035,0x000114f4, + 0x0004003d,0x00000038,0x0000003b,0x0000003a,0x00050062,0x0000003d,0x0000003e,0x0000003b, + 0x0000002b,0x00050051,0x00000018,0x0000003f,0x0000003e,0x00000000,0x0006000c,0x0000000c, + 0x00000040,0x00000001,0x0000003e,0x0000003f,0x00050051,0x00000006,0x00000043,0x00000040, + 0x00000001,0x000500b4,0x00000047,0x00000048,0x00000043,0x00000032,0x000300f7,0x0000004b, + 0x00000000,0x000400fa,0x00000048,0x0000004a,0x0000004e,0x000200f8,0x0000004a,0x00050051, + 0x00000006,0x0000004d,0x00000040,0x00000000,0x000200f9,0x0000004b,0x000200f8,0x0000004e, + 0x000200f9,0x0000004b,0x000200f8,0x0000004b,0x000700f5,0x00000006,0x000000cd,0x0000004d, + 0x0000004a,0x0000004f,0x0000004e,0x00050081,0x00000006,0x00000056,0x000000cd,0x00000036, + 0x00050041,0x0000002f,0x00000058,0x0000002e,0x0000001c,0x0004003d,0x00000006,0x00000059, + 0x00000058,0x000500b7,0x00000047,0x0000005c,0x00000059,0x0000004f,0x000500a7,0x00000047, + 0x0000005d,0x0000005a,0x0000005c,0x000300f7,0x0000005f,0x00000000,0x000400fa,0x0000005d, + 0x0000005e,0x0000005f,0x000200f8,0x0000005e,0x000500b7,0x00000047,0x00000063,0x00000043, + 0x00000032,0x000300f7,0x00000065,0x00000000,0x000400fa,0x00000063,0x00000064,0x00000079, + 0x000200f8,0x00000064,0x000500b4,0x00000047,0x00000068,0x00000043,0x00000059,0x000300f7, + 0x0000006b,0x00000000,0x000400fa,0x00000068,0x0000006a,0x0000006e,0x000200f8,0x0000006a, + 0x00050051,0x00000006,0x0000006d,0x00000040,0x00000000,0x000200f9,0x0000006b,0x000200f8, + 0x0000006e,0x000200f9,0x0000006b,0x000200f8,0x0000006b,0x000700f5,0x00000006,0x000000ce, + 0x0000006d,0x0000006a,0x0000004f,0x0000006e,0x0004003d,0x00000038,0x00000071,0x00000070, + 0x00060052,0x0000000c,0x000000c6,0x000000ce,0x000000d1,0x00000000,0x00060052,0x0000000c, + 0x000000c8,0x0000004f,0x000000c6,0x00000001,0x0006000c,0x00000018,0x00000077,0x00000001, + 0x0000003a,0x000000c8,0x00070050,0x0000003d,0x00000078,0x00000077,0x00000077,0x00000077, + 0x00000077,0x00040063,0x00000071,0x0000002b,0x00000078,0x000200f9,0x00000065,0x000200f8, + 0x00000079,0x0004003d,0x00000038,0x0000007a,0x00000070,0x00050062,0x0000003d,0x0000007c, + 0x0000007a,0x0000002b,0x00050051,0x00000018,0x0000007d,0x0000007c,0x00000000,0x0006000c, + 0x0000000c,0x0000007e,0x00000001,0x0000003e,0x0000007d,0x00050051,0x00000006,0x0000007f, + 0x0000007e,0x00000000,0x000200f9,0x00000065,0x000200f8,0x00000065,0x000700f5,0x00000006, + 0x000000d4,0x000000ce,0x0000006b,0x0000007f,0x00000079,0x0007000c,0x00000006,0x00000082, + 0x00000001,0x00000025,0x00000056,0x000000d4,0x000200f9,0x0000005f,0x000200f8,0x0000005f, + 0x000700f5,0x00000006,0x000000d5,0x00000056,0x0000004b,0x00000082,0x00000065,0x0004003d, + 0x00000038,0x00000083,0x0000003a,0x00060052,0x0000000c,0x000000ca,0x000000d5,0x000000d1, + 0x00000000,0x00060052,0x0000000c,0x000000cc,0x00000032,0x000000ca,0x00000001,0x0006000c, + 0x00000018,0x0000008a,0x00000001,0x0000003a,0x000000cc,0x00070050,0x0000003d,0x0000008b, + 0x0000008a,0x0000008a,0x0000008a,0x0000008a,0x00040063,0x00000083,0x0000002b,0x0000008b, + 0x000114f5,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..2447f3606063d48fbdd5b4f7a09b3678bc4df1a0 GIT binary patch literal 4556 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.h new file mode 100644 index 000000000..fe4b793f6 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.h @@ -0,0 +1,154 @@ +#pragma once + +const uint32_t draw_clockwise_clip_interior_triangles_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000000e8,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x000c000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x00000027,0x0000002e,0x00000034,0x000000b1,0x000000b2,0x000000b3,0x000000b4, + 0x00030010,0x00000004,0x00000007,0x00030010,0x00000004,0x000014f6,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x665f4252,0x6d676172,0x5f746e65,0x64616873,0x695f7265, + 0x7265746e,0x6b636f6c,0x00000000,0x00090004,0x415f4c47,0x735f4252,0x65646168,0x6d695f72, + 0x5f656761,0x64616f6c,0x6f74735f,0x00006572,0x000a0004,0x415f4c47,0x735f4252,0x65646168, + 0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47, + 0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69, + 0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c, + 0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63, + 0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005, + 0x00000027,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x0000002e,0x00003153, + 0x00030005,0x00000034,0x0000316c,0x00030005,0x00000037,0x00006750,0x00030005,0x00000040, + 0x00003065,0x00030005,0x0000005e,0x0000674c,0x00030005,0x0000007d,0x00003053,0x00030005, + 0x000000a4,0x0000424d,0x00040006,0x000000a4,0x00000000,0x00006250,0x00040006,0x000000a4, + 0x00000001,0x00006359,0x00040006,0x000000a4,0x00000002,0x00006552,0x00040006,0x000000a4, + 0x00000003,0x00006553,0x00040006,0x000000a4,0x00000004,0x0000366d,0x00040006,0x000000a4, + 0x00000005,0x0000676d,0x00040006,0x000000a4,0x00000006,0x00006544,0x00040006,0x000000a4, + 0x00000007,0x00006545,0x00040006,0x000000a4,0x00000008,0x00003755,0x00040006,0x000000a4, + 0x00000009,0x0000676a,0x00040006,0x000000a4,0x0000000a,0x0000635a,0x00040006,0x000000a4, + 0x0000000b,0x00003157,0x00040006,0x000000a4,0x0000000c,0x0000676e,0x00040006,0x000000a4, + 0x0000000d,0x00003559,0x00040006,0x000000a4,0x0000000e,0x0000324f,0x00040006,0x000000a4, + 0x0000000f,0x00006461,0x00040006,0x000000a4,0x00000010,0x00006579,0x00040006,0x000000a4, + 0x00000011,0x00003376,0x00040006,0x000000a4,0x00000012,0x00003377,0x00040006,0x000000a4, + 0x00000013,0x00006462,0x00040006,0x000000a4,0x00000014,0x00006767,0x00030005,0x000000a6, + 0x0000006b,0x00030005,0x000000a9,0x00003954,0x00030005,0x000000ac,0x00004444,0x00030005, + 0x000000ad,0x00004351,0x00030005,0x000000ae,0x00004344,0x00030005,0x000000af,0x00006277, + 0x00030005,0x000000b0,0x00003552,0x00030005,0x000000b1,0x0000316b,0x00030005,0x000000b2, + 0x0000307a,0x00030005,0x000000b3,0x0000304e,0x00030005,0x000000b4,0x00003159,0x00040047, + 0x00000027,0x0000000b,0x0000000f,0x00030047,0x0000002e,0x00000000,0x00030047,0x0000002e, + 0x0000000e,0x00040047,0x0000002e,0x0000001e,0x00000004,0x00030047,0x00000031,0x00000000, + 0x00030047,0x00000032,0x00000000,0x00030047,0x00000034,0x00000000,0x00030047,0x00000034, + 0x0000000e,0x00040047,0x00000034,0x0000001e,0x00000001,0x00030047,0x00000035,0x00000000, + 0x00040047,0x00000037,0x00000001,0x00000009,0x00030047,0x00000040,0x00000017,0x00040047, + 0x00000040,0x00000021,0x00000001,0x00040047,0x00000040,0x00000022,0x00000002,0x00030047, + 0x00000049,0x00000000,0x00030047,0x00000052,0x00000000,0x00030047,0x0000005a,0x00000000, + 0x00030047,0x0000005d,0x00000000,0x00040047,0x0000005e,0x00000001,0x00000005,0x00030047, + 0x0000006d,0x00000000,0x00030047,0x0000007a,0x00000000,0x00030047,0x0000007d,0x00000017, + 0x00040047,0x0000007d,0x00000021,0x00000003,0x00040047,0x0000007d,0x00000022,0x00000002, + 0x00030047,0x00000084,0x00000000,0x00030047,0x0000008f,0x00000000,0x00030047,0x00000097, + 0x00000000,0x00030047,0x000000a4,0x00000002,0x00050048,0x000000a4,0x00000000,0x00000023, + 0x00000000,0x00050048,0x000000a4,0x00000001,0x00000023,0x00000004,0x00050048,0x000000a4, + 0x00000002,0x00000023,0x00000008,0x00050048,0x000000a4,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x000000a4,0x00000004,0x00000023,0x00000010,0x00050048,0x000000a4,0x00000005, + 0x00000023,0x00000014,0x00050048,0x000000a4,0x00000006,0x00000023,0x00000018,0x00050048, + 0x000000a4,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000a4,0x00000008,0x00000023, + 0x00000020,0x00050048,0x000000a4,0x00000009,0x00000023,0x00000030,0x00050048,0x000000a4, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x000000a4,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x000000a4,0x0000000c,0x00000023,0x00000044,0x00050048,0x000000a4,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x000000a4,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x000000a4,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000a4,0x00000010,0x00000023, + 0x00000054,0x00050048,0x000000a4,0x00000011,0x00000023,0x00000058,0x00050048,0x000000a4, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x000000a4,0x00000013,0x00000023,0x00000060, + 0x00050048,0x000000a4,0x00000014,0x00000023,0x00000064,0x00040047,0x000000a6,0x00000021, + 0x00000000,0x00040047,0x000000a6,0x00000022,0x00000000,0x00030047,0x000000a9,0x00000000, + 0x00040047,0x000000a9,0x00000021,0x0000000a,0x00040047,0x000000a9,0x00000022,0x00000000, + 0x00030047,0x000000ac,0x00000000,0x00040047,0x000000ac,0x00000021,0x00000009,0x00040047, + 0x000000ac,0x00000022,0x00000000,0x00030047,0x000000ad,0x00000000,0x00040047,0x000000ad, + 0x00000021,0x0000000a,0x00040047,0x000000ad,0x00000022,0x00000000,0x00030047,0x000000ae, + 0x00000000,0x00040047,0x000000ae,0x00000021,0x0000000c,0x00040047,0x000000ae,0x00000022, + 0x00000001,0x00030047,0x000000af,0x00000000,0x00040047,0x000000af,0x00000021,0x00000009, + 0x00040047,0x000000af,0x00000022,0x00000000,0x00030047,0x000000b0,0x00000000,0x00040047, + 0x000000b0,0x00000021,0x0000000c,0x00040047,0x000000b0,0x00000022,0x00000001,0x00040047, + 0x000000b1,0x0000001e,0x00000000,0x00030047,0x000000b2,0x00000000,0x00030047,0x000000b2, + 0x0000000e,0x00040047,0x000000b2,0x0000001e,0x00000003,0x00040047,0x000000b3,0x0000001e, + 0x00000005,0x00030047,0x000000b4,0x00000000,0x00030047,0x000000b4,0x0000000e,0x00040047, + 0x000000b4,0x0000001e,0x00000006,0x00030047,0x000000cd,0x00000000,0x00030047,0x000000cf, + 0x00000000,0x00030047,0x000000d1,0x00000000,0x00030047,0x000000d3,0x00000000,0x00030047, + 0x000000d4,0x00000000,0x00030047,0x000000d6,0x00000000,0x00030047,0x000000d5,0x00000000, + 0x00030047,0x000000da,0x00000000,0x00030047,0x000000d9,0x00000000,0x00030047,0x000000dd, + 0x00000000,0x00030047,0x000000e5,0x00000000,0x00030047,0x000000e6,0x00000000,0x00030047, + 0x000000e7,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006,0x00000002,0x00040015,0x00000018, + 0x00000020,0x00000000,0x0004002b,0x00000018,0x00000019,0x00000000,0x0004002b,0x00000018, + 0x0000001c,0x00000001,0x00040015,0x00000021,0x00000020,0x00000001,0x00040017,0x00000022, + 0x00000021,0x00000002,0x00040017,0x00000025,0x00000006,0x00000004,0x00040020,0x00000026, + 0x00000001,0x00000025,0x0004003b,0x00000026,0x00000027,0x00000001,0x00040020,0x0000002d, + 0x00000001,0x0000000c,0x0004003b,0x0000002d,0x0000002e,0x00000001,0x00040020,0x0000002f, + 0x00000001,0x00000006,0x0004003b,0x0000002f,0x00000034,0x00000001,0x00020014,0x00000036, + 0x00030030,0x00000036,0x00000037,0x00090019,0x0000003e,0x00000018,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x0000003f,0x00000000,0x0000003e, + 0x0004003b,0x0000003f,0x00000040,0x00000000,0x00040017,0x00000043,0x00000018,0x00000004, + 0x0004002b,0x00000006,0x00000054,0x00000000,0x00030030,0x00000036,0x0000005e,0x0004003b, + 0x0000003f,0x0000007d,0x00000000,0x00040017,0x000000a3,0x00000021,0x00000004,0x0017001e, + 0x000000a4,0x00000006,0x00000006,0x00000006,0x00000006,0x00000018,0x00000018,0x00000018, + 0x00000018,0x000000a3,0x0000000c,0x0000000c,0x00000018,0x00000006,0x00000018,0x00000006, + 0x00000006,0x00000018,0x00000006,0x00000006,0x00000006,0x00000018,0x00040020,0x000000a5, + 0x00000002,0x000000a4,0x0004003b,0x000000a5,0x000000a6,0x00000002,0x0002001a,0x000000a7, + 0x00040020,0x000000a8,0x00000000,0x000000a7,0x0004003b,0x000000a8,0x000000a9,0x00000000, + 0x00090019,0x000000aa,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x000000ab,0x00000000,0x000000aa,0x0004003b,0x000000ab,0x000000ac, + 0x00000000,0x0004003b,0x000000ab,0x000000ad,0x00000000,0x0004003b,0x000000ab,0x000000ae, + 0x00000000,0x0004003b,0x000000a8,0x000000af,0x00000000,0x0004003b,0x000000a8,0x000000b0, + 0x00000000,0x0004003b,0x00000026,0x000000b1,0x00000001,0x0004003b,0x0000002f,0x000000b2, + 0x00000001,0x0004003b,0x00000026,0x000000b3,0x00000001,0x0004003b,0x0000002f,0x000000b4, + 0x00000001,0x00030001,0x00000006,0x000000d7,0x00030001,0x0000000c,0x000000db,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000025, + 0x00000028,0x00000027,0x0007004f,0x0000000c,0x00000029,0x00000028,0x00000028,0x00000000, + 0x00000001,0x0006000c,0x0000000c,0x0000002a,0x00000001,0x00000008,0x00000029,0x0004006e, + 0x00000022,0x0000002b,0x0000002a,0x00050041,0x0000002f,0x00000030,0x0000002e,0x00000019, + 0x0004003d,0x00000006,0x00000031,0x00000030,0x0004007f,0x00000006,0x00000032,0x00000031, + 0x0004003d,0x00000006,0x00000035,0x00000034,0x000114f4,0x000300f7,0x00000039,0x00000000, + 0x000400fa,0x00000037,0x00000038,0x0000003c,0x000200f8,0x00000038,0x000200f9,0x00000039, + 0x000200f8,0x0000003c,0x0004003d,0x0000003e,0x00000041,0x00000040,0x00050062,0x00000043, + 0x00000044,0x00000041,0x0000002b,0x00050051,0x00000018,0x00000045,0x00000044,0x00000000, + 0x0006000c,0x0000000c,0x00000046,0x00000001,0x0000003e,0x00000045,0x00050051,0x00000006, + 0x00000049,0x00000046,0x00000001,0x000500b4,0x00000036,0x0000004d,0x00000049,0x00000032, + 0x000300f7,0x00000050,0x00000000,0x000400fa,0x0000004d,0x0000004f,0x00000053,0x000200f8, + 0x0000004f,0x00050051,0x00000006,0x00000052,0x00000046,0x00000000,0x000200f9,0x00000050, + 0x000200f8,0x00000053,0x000200f9,0x00000050,0x000200f8,0x00000050,0x000700f5,0x00000006, + 0x000000d4,0x00000052,0x0000004f,0x00000054,0x00000053,0x00050081,0x00000006,0x0000005a, + 0x000000d4,0x00000035,0x000200f9,0x00000039,0x000200f8,0x00000039,0x000700f5,0x00000006, + 0x000000e5,0x00000035,0x00000038,0x0000005a,0x00000050,0x000700f5,0x0000000c,0x000000da, + 0x000000db,0x00000038,0x00000046,0x00000050,0x000700f5,0x00000006,0x000000d6,0x000000d7, + 0x00000038,0x00000049,0x00000050,0x00050041,0x0000002f,0x0000005c,0x0000002e,0x0000001c, + 0x0004003d,0x00000006,0x0000005d,0x0000005c,0x000500b7,0x00000036,0x00000060,0x0000005d, + 0x00000054,0x000500a7,0x00000036,0x00000061,0x0000005e,0x00000060,0x000300f7,0x00000063, + 0x00000000,0x000400fa,0x00000061,0x00000062,0x00000063,0x000200f8,0x00000062,0x000300f7, + 0x00000066,0x00000000,0x000400fa,0x00000037,0x00000065,0x00000066,0x000200f8,0x00000065, + 0x0004003d,0x0000003e,0x00000067,0x00000040,0x00050062,0x00000043,0x00000069,0x00000067, + 0x0000002b,0x00050051,0x00000018,0x0000006a,0x00000069,0x00000000,0x0006000c,0x0000000c, + 0x0000006b,0x00000001,0x0000003e,0x0000006a,0x00050051,0x00000006,0x0000006d,0x0000006b, + 0x00000001,0x000200f9,0x00000066,0x000200f8,0x00000066,0x000700f5,0x0000000c,0x000000d9, + 0x000000da,0x00000062,0x0000006b,0x00000065,0x000700f5,0x00000006,0x000000d5,0x000000d6, + 0x00000062,0x0000006d,0x00000065,0x000500b7,0x00000036,0x00000070,0x000000d5,0x00000032, + 0x000300f7,0x00000072,0x00000000,0x000400fa,0x00000070,0x00000071,0x00000086,0x000200f8, + 0x00000071,0x000500b4,0x00000036,0x00000075,0x000000d5,0x0000005d,0x000300f7,0x00000078, + 0x00000000,0x000400fa,0x00000075,0x00000077,0x0000007b,0x000200f8,0x00000077,0x00050051, + 0x00000006,0x0000007a,0x000000d9,0x00000000,0x000200f9,0x00000078,0x000200f8,0x0000007b, + 0x000200f9,0x00000078,0x000200f8,0x00000078,0x000700f5,0x00000006,0x000000dd,0x0000007a, + 0x00000077,0x00000054,0x0000007b,0x0004003d,0x0000003e,0x0000007e,0x0000007d,0x00060052, + 0x0000000c,0x000000cd,0x000000dd,0x000000db,0x00000000,0x00060052,0x0000000c,0x000000cf, + 0x00000054,0x000000cd,0x00000001,0x0006000c,0x00000018,0x00000084,0x00000001,0x0000003a, + 0x000000cf,0x00070050,0x00000043,0x00000085,0x00000084,0x00000084,0x00000084,0x00000084, + 0x00040063,0x0000007e,0x0000002b,0x00000085,0x000200f9,0x00000072,0x000200f8,0x00000086, + 0x0004003d,0x0000003e,0x00000087,0x0000007d,0x00050062,0x00000043,0x00000089,0x00000087, + 0x0000002b,0x00050051,0x00000018,0x0000008a,0x00000089,0x00000000,0x0006000c,0x0000000c, + 0x0000008b,0x00000001,0x0000003e,0x0000008a,0x00050051,0x00000006,0x0000008c,0x0000008b, + 0x00000000,0x000200f9,0x00000072,0x000200f8,0x00000072,0x000700f5,0x00000006,0x000000e6, + 0x000000dd,0x00000078,0x0000008c,0x00000086,0x0007000c,0x00000006,0x0000008f,0x00000001, + 0x00000025,0x000000e5,0x000000e6,0x000200f9,0x00000063,0x000200f8,0x00000063,0x000700f5, + 0x00000006,0x000000e7,0x000000e5,0x00000039,0x0000008f,0x00000072,0x0004003d,0x0000003e, + 0x00000090,0x00000040,0x00060052,0x0000000c,0x000000d1,0x000000e7,0x000000db,0x00000000, + 0x00060052,0x0000000c,0x000000d3,0x00000032,0x000000d1,0x00000001,0x0006000c,0x00000018, + 0x00000097,0x00000001,0x0000003a,0x000000d3,0x00070050,0x00000043,0x00000098,0x00000097, + 0x00000097,0x00000097,0x00000097,0x00040063,0x00000090,0x0000002b,0x00000098,0x000114f5, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..40f851cc1977b44e002fa1c69019560760862149 GIT binary patch literal 4776 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.h new file mode 100644 index 000000000..11abb9863 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.h @@ -0,0 +1,168 @@ +#pragma once + +const uint32_t draw_clockwise_image_mesh_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000158,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x00000071,0x00000082,0x00000093,0x000000a4,0x000000f0,0x00030010,0x00000004, + 0x00000007,0x00030010,0x00000004,0x000014f6,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x665f4252,0x6d676172,0x5f746e65,0x64616873,0x695f7265,0x7265746e,0x6b636f6c, + 0x00000000,0x00090004,0x415f4c47,0x735f4252,0x65646168,0x6d695f72,0x5f656761,0x64616f6c, + 0x6f74735f,0x00006572,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000059,0x0000674e, + 0x00060005,0x00000071,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x00000079, + 0x00004344,0x00030005,0x0000007d,0x00003552,0x00030005,0x00000082,0x00003055,0x00030005, + 0x00000085,0x0000424d,0x00040006,0x00000085,0x00000000,0x00006250,0x00040006,0x00000085, + 0x00000001,0x00006359,0x00040006,0x00000085,0x00000002,0x00006552,0x00040006,0x00000085, + 0x00000003,0x00006553,0x00040006,0x00000085,0x00000004,0x0000366d,0x00040006,0x00000085, + 0x00000005,0x0000676d,0x00040006,0x00000085,0x00000006,0x00006544,0x00040006,0x00000085, + 0x00000007,0x00006545,0x00040006,0x00000085,0x00000008,0x00003755,0x00040006,0x00000085, + 0x00000009,0x0000676a,0x00040006,0x00000085,0x0000000a,0x0000635a,0x00040006,0x00000085, + 0x0000000b,0x00003157,0x00040006,0x00000085,0x0000000c,0x0000676e,0x00040006,0x00000085, + 0x0000000d,0x00003559,0x00040006,0x00000085,0x0000000e,0x0000324f,0x00040006,0x00000085, + 0x0000000f,0x00006461,0x00040006,0x00000085,0x00000010,0x00006579,0x00040006,0x00000085, + 0x00000011,0x00003376,0x00040006,0x00000085,0x00000012,0x00003377,0x00040006,0x00000085, + 0x00000013,0x00006462,0x00040006,0x00000085,0x00000014,0x00006767,0x00030005,0x00000087, + 0x0000006b,0x00030005,0x0000008f,0x00006748,0x00030005,0x00000093,0x0000304e,0x00030005, + 0x000000a0,0x00006747,0x00030005,0x000000a4,0x00003346,0x00030005,0x000000ad,0x00003065, + 0x00030005,0x000000ce,0x0000434c,0x00040006,0x000000ce,0x00000000,0x00003972,0x00040006, + 0x000000ce,0x00000001,0x00003261,0x00040006,0x000000ce,0x00000002,0x00003479,0x00040006, + 0x000000ce,0x00000003,0x00006969,0x00040006,0x000000ce,0x00000004,0x0000326b,0x00040006, + 0x000000ce,0x00000005,0x00003244,0x00040006,0x000000ce,0x00000006,0x00003056,0x00040006, + 0x000000ce,0x00000007,0x0000326e,0x00040006,0x000000ce,0x00000008,0x0000365a,0x00030005, + 0x000000d0,0x00003041,0x00030005,0x000000f0,0x0000316d,0x00030005,0x000000fb,0x00003053, + 0x00040047,0x00000059,0x00000001,0x00000007,0x00040047,0x00000071,0x0000000b,0x0000000f, + 0x00030047,0x00000079,0x00000000,0x00040047,0x00000079,0x00000021,0x0000000c,0x00040047, + 0x00000079,0x00000022,0x00000001,0x00030047,0x0000007a,0x00000000,0x00030047,0x0000007d, + 0x00000000,0x00040047,0x0000007d,0x00000021,0x0000000c,0x00040047,0x0000007d,0x00000022, + 0x00000001,0x00030047,0x0000007e,0x00000000,0x00040047,0x00000082,0x0000001e,0x00000000, + 0x00030047,0x00000085,0x00000002,0x00050048,0x00000085,0x00000000,0x00000023,0x00000000, + 0x00050048,0x00000085,0x00000001,0x00000023,0x00000004,0x00050048,0x00000085,0x00000002, + 0x00000023,0x00000008,0x00050048,0x00000085,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x00000085,0x00000004,0x00000023,0x00000010,0x00050048,0x00000085,0x00000005,0x00000023, + 0x00000014,0x00050048,0x00000085,0x00000006,0x00000023,0x00000018,0x00050048,0x00000085, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x00000085,0x00000008,0x00000023,0x00000020, + 0x00050048,0x00000085,0x00000009,0x00000023,0x00000030,0x00050048,0x00000085,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x00000085,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x00000085,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000085,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x00000085,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000085, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x00000085,0x00000010,0x00000023,0x00000054, + 0x00050048,0x00000085,0x00000011,0x00000023,0x00000058,0x00050048,0x00000085,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x00000085,0x00000013,0x00000023,0x00000060,0x00050048, + 0x00000085,0x00000014,0x00000023,0x00000064,0x00040047,0x00000087,0x00000021,0x00000000, + 0x00040047,0x00000087,0x00000022,0x00000000,0x00030047,0x0000008c,0x00000000,0x00040047, + 0x0000008f,0x00000001,0x00000001,0x00040047,0x00000093,0x0000001e,0x00000002,0x00030047, + 0x0000009c,0x00000000,0x00030047,0x0000009f,0x00000000,0x00040047,0x000000a0,0x00000001, + 0x00000000,0x00030047,0x000000a4,0x00000000,0x00030047,0x000000a4,0x0000000e,0x00040047, + 0x000000a4,0x0000001e,0x00000001,0x00030047,0x000000a5,0x00000000,0x00030047,0x000000ad, + 0x00000017,0x00040047,0x000000ad,0x00000021,0x00000001,0x00040047,0x000000ad,0x00000022, + 0x00000002,0x00030047,0x000000b6,0x00000000,0x00030047,0x000000b9,0x00000000,0x00030047, + 0x000000bf,0x00000000,0x00030047,0x000000c6,0x00000000,0x00030047,0x000000ca,0x00000000, + 0x00030047,0x000000cd,0x00000000,0x00030047,0x000000ce,0x00000002,0x00050048,0x000000ce, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000000ce,0x00000001,0x00000023,0x00000010, + 0x00050048,0x000000ce,0x00000002,0x00000023,0x00000018,0x00050048,0x000000ce,0x00000003, + 0x00000023,0x0000001c,0x00050048,0x000000ce,0x00000004,0x00000023,0x00000020,0x00050048, + 0x000000ce,0x00000005,0x00000023,0x00000030,0x00050048,0x000000ce,0x00000006,0x00000023, + 0x00000038,0x00050048,0x000000ce,0x00000007,0x00000023,0x0000003c,0x00050048,0x000000ce, + 0x00000008,0x00000023,0x00000040,0x00040047,0x000000d0,0x00000021,0x00000002,0x00040047, + 0x000000d0,0x00000022,0x00000000,0x00030047,0x000000d8,0x00000000,0x00030047,0x000000dd, + 0x00000000,0x00030047,0x000000f0,0x00000000,0x00040047,0x000000f0,0x0000001e,0x00000000, + 0x00030047,0x000000fb,0x00000017,0x00040047,0x000000fb,0x00000021,0x00000003,0x00040047, + 0x000000fb,0x00000022,0x00000002,0x00030047,0x00000106,0x00000000,0x00030047,0x00000108, + 0x00000000,0x00030047,0x00000109,0x00000000,0x00030047,0x0000010b,0x00000000,0x00030047, + 0x0000010d,0x00000000,0x00030047,0x0000010e,0x00000000,0x00030047,0x00000128,0x00000000, + 0x00030047,0x00000129,0x00000000,0x00030047,0x0000013b,0x00000000,0x00030047,0x0000013c, + 0x00000000,0x00030047,0x0000013f,0x00000000,0x00030047,0x00000141,0x00000000,0x00030047, + 0x00000149,0x00000000,0x00030047,0x0000014b,0x00000000,0x00030047,0x0000014d,0x00000000, + 0x00030047,0x0000014e,0x00000000,0x00030047,0x00000151,0x00000000,0x00030047,0x00000152, + 0x00000000,0x00030047,0x00000157,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004, + 0x00040017,0x00000016,0x00000006,0x00000002,0x00040017,0x0000001e,0x00000006,0x00000003, + 0x00040015,0x00000036,0x00000020,0x00000000,0x0004002b,0x00000006,0x00000042,0x3d897143, + 0x0004002b,0x00000006,0x00000046,0x3bbf4590,0x0004002b,0x00000006,0x0000004d,0x4253ee82, + 0x00020014,0x00000058,0x00030030,0x00000058,0x00000059,0x00040015,0x0000006c,0x00000020, + 0x00000001,0x00040017,0x0000006d,0x0000006c,0x00000002,0x00040020,0x00000070,0x00000001, + 0x00000007,0x0004003b,0x00000070,0x00000071,0x00000001,0x00090019,0x00000077,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000078, + 0x00000000,0x00000077,0x0004003b,0x00000078,0x00000079,0x00000000,0x0002001a,0x0000007b, + 0x00040020,0x0000007c,0x00000000,0x0000007b,0x0004003b,0x0000007c,0x0000007d,0x00000000, + 0x0003001b,0x0000007f,0x00000077,0x00040020,0x00000081,0x00000001,0x00000016,0x0004003b, + 0x00000081,0x00000082,0x00000001,0x00040017,0x00000084,0x0000006c,0x00000004,0x0017001e, + 0x00000085,0x00000006,0x00000006,0x00000006,0x00000006,0x00000036,0x00000036,0x00000036, + 0x00000036,0x00000084,0x00000016,0x00000016,0x00000036,0x00000006,0x00000036,0x00000006, + 0x00000006,0x00000036,0x00000006,0x00000006,0x00000006,0x00000036,0x00040020,0x00000086, + 0x00000002,0x00000085,0x0004003b,0x00000086,0x00000087,0x00000002,0x0004002b,0x0000006c, + 0x00000088,0x0000000f,0x00040020,0x00000089,0x00000002,0x00000006,0x0004002b,0x00000006, + 0x0000008e,0x3f800000,0x00030030,0x00000058,0x0000008f,0x0004003b,0x00000070,0x00000093, + 0x00000001,0x0004002b,0x00000006,0x00000099,0x00000000,0x00030030,0x00000058,0x000000a0, + 0x00040020,0x000000a3,0x00000001,0x00000006,0x0004003b,0x000000a3,0x000000a4,0x00000001, + 0x00090019,0x000000ab,0x00000036,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000021,0x00040020,0x000000ac,0x00000000,0x000000ab,0x0004003b,0x000000ac,0x000000ad, + 0x00000000,0x00040017,0x000000b0,0x00000036,0x00000004,0x000b001e,0x000000ce,0x00000007, + 0x00000016,0x00000006,0x00000006,0x00000007,0x00000016,0x00000036,0x00000036,0x00000036, + 0x00040020,0x000000cf,0x00000002,0x000000ce,0x0004003b,0x000000cf,0x000000d0,0x00000002, + 0x0004002b,0x0000006c,0x000000d1,0x00000002,0x0004002b,0x0000006c,0x000000d9,0x00000011, + 0x0004002b,0x0000006c,0x000000da,0x00000012,0x00040020,0x000000ef,0x00000003,0x00000007, + 0x0004003b,0x000000ef,0x000000f0,0x00000003,0x0004003b,0x000000ac,0x000000fb,0x00000000, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d, + 0x00000007,0x00000072,0x00000071,0x0007004f,0x00000016,0x00000073,0x00000072,0x00000072, + 0x00000000,0x00000001,0x0006000c,0x00000016,0x00000074,0x00000001,0x00000008,0x00000073, + 0x0004006e,0x0000006d,0x00000075,0x00000074,0x0004003d,0x00000077,0x0000007a,0x00000079, + 0x0004003d,0x0000007b,0x0000007e,0x0000007d,0x00050056,0x0000007f,0x00000080,0x0000007a, + 0x0000007e,0x0004003d,0x00000016,0x00000083,0x00000082,0x00050041,0x00000089,0x0000008a, + 0x00000087,0x00000088,0x0004003d,0x00000006,0x0000008b,0x0000008a,0x00070057,0x00000007, + 0x0000008c,0x00000080,0x00000083,0x00000001,0x0000008b,0x000300f7,0x00000091,0x00000000, + 0x000400fa,0x0000008f,0x00000090,0x00000091,0x000200f8,0x00000090,0x0004003d,0x00000007, + 0x00000095,0x00000093,0x0007004f,0x00000016,0x00000106,0x00000095,0x00000095,0x00000000, + 0x00000001,0x0007004f,0x00000016,0x00000108,0x00000095,0x00000095,0x00000002,0x00000003, + 0x0007000c,0x00000016,0x00000109,0x00000001,0x00000025,0x00000106,0x00000108,0x00050051, + 0x00000006,0x0000010b,0x00000109,0x00000000,0x00050051,0x00000006,0x0000010d,0x00000109, + 0x00000001,0x0007000c,0x00000006,0x0000010e,0x00000001,0x00000025,0x0000010b,0x0000010d, + 0x0007000c,0x00000006,0x0000009c,0x00000001,0x00000028,0x0000010e,0x00000099,0x0007000c, + 0x00000006,0x0000009f,0x00000001,0x00000025,0x0000009c,0x0000008e,0x000200f9,0x00000091, + 0x000200f8,0x00000091,0x000700f5,0x00000006,0x00000151,0x0000008e,0x00000005,0x0000009f, + 0x00000090,0x000114f4,0x000300f7,0x000000a2,0x00000000,0x000400fa,0x000000a0,0x000000a1, + 0x000000a2,0x000200f8,0x000000a1,0x0004003d,0x00000006,0x000000a5,0x000000a4,0x000500b7, + 0x00000058,0x000000a6,0x000000a5,0x00000099,0x000200f9,0x000000a2,0x000200f8,0x000000a2, + 0x000700f5,0x00000058,0x000000a7,0x000000a0,0x00000091,0x000000a6,0x000000a1,0x000300f7, + 0x000000a9,0x00000000,0x000400fa,0x000000a7,0x000000a8,0x000000a9,0x000200f8,0x000000a8, + 0x0004003d,0x000000ab,0x000000ae,0x000000ad,0x00050062,0x000000b0,0x000000b1,0x000000ae, + 0x00000075,0x00050051,0x00000036,0x000000b2,0x000000b1,0x00000000,0x0006000c,0x00000016, + 0x000000b3,0x00000001,0x0000003e,0x000000b2,0x00050051,0x00000006,0x000000b6,0x000000b3, + 0x00000001,0x0004003d,0x00000006,0x000000b9,0x000000a4,0x000500b4,0x00000058,0x000000ba, + 0x000000b6,0x000000b9,0x000300f7,0x000000bd,0x00000000,0x000400fa,0x000000ba,0x000000bc, + 0x000000c0,0x000200f8,0x000000bc,0x00050051,0x00000006,0x000000bf,0x000000b3,0x00000000, + 0x000200f9,0x000000bd,0x000200f8,0x000000c0,0x000200f9,0x000000bd,0x000200f8,0x000000bd, + 0x000700f5,0x00000006,0x0000014e,0x000000bf,0x000000bc,0x00000099,0x000000c0,0x0007000c, + 0x00000006,0x000000c6,0x00000001,0x00000028,0x0000014e,0x00000099,0x0007000c,0x00000006, + 0x000000ca,0x00000001,0x00000028,0x000000c6,0x00000099,0x0007000c,0x00000006,0x000000cd, + 0x00000001,0x00000025,0x00000151,0x000000ca,0x000200f9,0x000000a9,0x000200f8,0x000000a9, + 0x000700f5,0x00000006,0x00000152,0x00000151,0x000000a2,0x000000cd,0x000000bd,0x00050041, + 0x00000089,0x000000d2,0x000000d0,0x000000d1,0x0004003d,0x00000006,0x000000d3,0x000000d2, + 0x00050085,0x00000006,0x000000d5,0x00000152,0x000000d3,0x000114f5,0x0005008e,0x00000007, + 0x000000d8,0x0000008c,0x000000d5,0x0008004f,0x0000001e,0x000000dd,0x000000d8,0x000000d8, + 0x00000000,0x00000001,0x00000002,0x00050041,0x00000089,0x000000e2,0x00000087,0x000000d9, + 0x0004003d,0x00000006,0x000000e3,0x000000e2,0x00050041,0x00000089,0x000000e5,0x00000087, + 0x000000da,0x0004003d,0x00000006,0x000000e6,0x000000e5,0x000300f7,0x0000012c,0x00000000, + 0x000400fa,0x00000059,0x00000122,0x0000012a,0x000200f8,0x00000122,0x00050051,0x00000006, + 0x00000133,0x00000073,0x00000000,0x00050085,0x00000006,0x00000134,0x00000042,0x00000133, + 0x00050051,0x00000006,0x00000136,0x00000073,0x00000001,0x00050085,0x00000006,0x00000137, + 0x00000046,0x00000136,0x00050081,0x00000006,0x00000138,0x00000134,0x00000137,0x0006000c, + 0x00000006,0x00000139,0x00000001,0x0000000a,0x00000138,0x00050085,0x00000006,0x0000013b, + 0x0000004d,0x00000139,0x0006000c,0x00000006,0x0000013c,0x00000001,0x0000000a,0x0000013b, + 0x00050085,0x00000006,0x0000013f,0x0000013c,0x000000e3,0x00050081,0x00000006,0x00000141, + 0x0000013f,0x000000e6,0x00060050,0x0000001e,0x00000128,0x00000141,0x00000141,0x00000141, + 0x00050081,0x0000001e,0x00000129,0x00000128,0x000000dd,0x000200f9,0x0000012c,0x000200f8, + 0x0000012a,0x000200f9,0x0000012c,0x000200f8,0x0000012c,0x000700f5,0x0000001e,0x00000157, + 0x00000129,0x00000122,0x000000dd,0x0000012a,0x00050051,0x00000006,0x000000e9,0x00000157, + 0x00000000,0x00060052,0x00000007,0x00000149,0x000000e9,0x000000d8,0x00000000,0x00050051, + 0x00000006,0x000000eb,0x00000157,0x00000001,0x00060052,0x00000007,0x0000014b,0x000000eb, + 0x00000149,0x00000001,0x00050051,0x00000006,0x000000ee,0x00000157,0x00000002,0x00060052, + 0x00000007,0x0000014d,0x000000ee,0x0000014b,0x00000002,0x0003003e,0x000000f0,0x0000014d, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..894ab652b76df601a7fa4e589aa0a8c26fce30b7 GIT binary patch literal 5224 zcmaKwS!|S56vsd4LZR%dTSyBb0W}0=4{J*oh%GHGTZzdyZKri$IxRC(pe_hitP24Q z@xg?|s>LNP!6g`s2A+5@qD5l@B)n)eF(%jtagB-p-#7QnTzT-?llwpabMCq4o^!u% zJ}ekLcT5nB3QB{LVCSeH98-ePVuFBq^o$@Fr~jH8w@0dXZjE%LqMco_WG0e+INBad zMdHa!ES2bP+av$dpg3GtTi0B-Fr8^%xMb-f0!|DHm_pkm#VQm=x}xzU{9Z}Fmn6RmH(TT{KlG}W!)9+j71XN(e_9>)18X_ zCzkWUfLCj8M~4pD-MTy0mQk!yVo{28w5unf!^hI;NG5h5)0>J#I(n0BnRs_HtrRW4 z+J=VOy6Q+2B!mPPMZ)K7E?2He~VR!c9xFm|AaBXYe^9TwfU|N@0kl292$GoqN#I zme;9$lX5nHI@|2&VV=wK_9EH4l&AR@ORw_$>2I~Cmq_2XJnuhN`fhLiIO)5*d`hM7 zxG(QNUV75=pCG+O=eGSPN^iJ7uTPR5RmIFcS$dzB&lKtV7U%6#rSJFjY0_K0^}3=# zr}n3|1HwEP;NzM%I{u{aW>^0~;abNJ3D+n#{_hIMoX?lSb?PHIf*Glmd7U0b-I=h{ zqrN41J3WfW^Ey4+|J+qJjtH%5BWv(uwp>M?l^3s<;2M})i73;4ffV=5X8>^P}!?w|N{jgS*S) z*blDE<9JTsRPtOro)x$i9!K5b)_WYe!c}=3&kfv0kK@^atMfQ|2-oOwoD*)V$MGD& z?ew^*j(gDKc%JZk$m6IHT)Tw+4QQs<4AbXiRp|x6(Ht%epF4Vo;LEc|@97=Br!+Ib zFK1!sHz>>+2DYIr%wcLlJb2<|;}-;{JwKk|SrYuf;Os81 z_SV{6UN4S14Qr-O*}7zP>cpTnSF$j~*F8Lv!-e7Zga3TC58dxWF~!kf zuM!WB^>C?&CwO?Ghv$2EfrnRlc(sSudAP#En>_r0hwDAO*~42r+~naM4o_2MscpH= zM-9L;h3HqAWR_||pU~+w`b?+ei%xB^vwntj{S<_2H3j!b$5tuXu=m+Drq@V6QGI@u z>Gjh4Z!}jBPYIux9q4X85A_JC1WaCCoXf z?QETl-y8Dug?jqJ8sZ`F_}Y9cHl19amLK(E4{|~0-3dn@$m1Ca?{NH|)r^f8)~92_ zL2ziD^@r~mVo`tIrJU7#UlL}R@1QVoU(<{qaaoH#$wQZaaTdL`J1$zA0;io1@^y*?=6PH)%F+~-3QeBkjR_LGu+Nrim4E6+&=B-|l< zsPXd>_#MiX+>c5QNmxss*nih4U(n3>OY4qnJ|ThQ>|o-t{zVD*%+AjH84h6((`>x2 z%|=bB<#<;!-rxAnlMn;nEjkA|^FFutyK%hNZ4EK-D!KSw}5?ojxk8*{i|~YBs3(6$u%Y}KA;G{5h-Ud_~$ z=j{W>Ys%f%4~2E)V66nZ)&H!p+3Z~B#Br{V+_^px#t)ucKhw-0S8Sh3E=b4~Y_ZP^ z6PrOjSclJrTXcBq3%{|fBMx=EAhG^l6y^-{9zX16<2%i4`1!U=&NfdoeaDx4tiH^) zKfmSp&@~kL3lB>!ORQGk2*V#yt%@~&DrekTN&i+7u$u9$R`2ZQ z%Qu_(VmDvD->^{!+l%iwc+TCZov1C}h43c$!Y>eqjoNbus1LQECcX~OonQ^$bgZLZ zti#vp@sqP_3YxSxz1}1{y!F+5e-=k9{pEc5)`Vvby!qa6zT5|k%eN>zYv9+azayIA K|Iz9dl79grIq@w3 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.h new file mode 100644 index 000000000..9296643e1 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.h @@ -0,0 +1,648 @@ +#pragma once + +const uint32_t draw_clockwise_image_mesh_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000b83,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x0009000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x000002c1,0x000002d2,0x000002e2,0x000002f2,0x00030010,0x00000004,0x00000007, + 0x00030010,0x00000004,0x000014f6,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x665f4252,0x6d676172,0x5f746e65,0x64616873,0x695f7265,0x7265746e,0x6b636f6c,0x00000000, + 0x00090004,0x415f4c47,0x735f4252,0x65646168,0x6d695f72,0x5f656761,0x64616f6c,0x6f74735f, + 0x00006572,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000f9,0x0000674e,0x00030005, + 0x0000026b,0x0000674d,0x00060005,0x000002c1,0x465f6c67,0x43676172,0x64726f6f,0x00000000, + 0x00030005,0x000002c9,0x00004344,0x00030005,0x000002cd,0x00003552,0x00030005,0x000002d2, + 0x00003055,0x00030005,0x000002d5,0x0000424d,0x00040006,0x000002d5,0x00000000,0x00006250, + 0x00040006,0x000002d5,0x00000001,0x00006359,0x00040006,0x000002d5,0x00000002,0x00006552, + 0x00040006,0x000002d5,0x00000003,0x00006553,0x00040006,0x000002d5,0x00000004,0x0000366d, + 0x00040006,0x000002d5,0x00000005,0x0000676d,0x00040006,0x000002d5,0x00000006,0x00006544, + 0x00040006,0x000002d5,0x00000007,0x00006545,0x00040006,0x000002d5,0x00000008,0x00003755, + 0x00040006,0x000002d5,0x00000009,0x0000676a,0x00040006,0x000002d5,0x0000000a,0x0000635a, + 0x00040006,0x000002d5,0x0000000b,0x00003157,0x00040006,0x000002d5,0x0000000c,0x0000676e, + 0x00040006,0x000002d5,0x0000000d,0x00003559,0x00040006,0x000002d5,0x0000000e,0x0000324f, + 0x00040006,0x000002d5,0x0000000f,0x00006461,0x00040006,0x000002d5,0x00000010,0x00006579, + 0x00040006,0x000002d5,0x00000011,0x00003376,0x00040006,0x000002d5,0x00000012,0x00003377, + 0x00040006,0x000002d5,0x00000013,0x00006462,0x00040006,0x000002d5,0x00000014,0x00006767, + 0x00030005,0x000002d7,0x0000006b,0x00030005,0x000002de,0x00006748,0x00030005,0x000002e2, + 0x0000304e,0x00030005,0x000002ee,0x00006747,0x00030005,0x000002f2,0x00003346,0x00030005, + 0x000002fb,0x00003065,0x00030005,0x0000031c,0x0000434c,0x00040006,0x0000031c,0x00000000, + 0x00003972,0x00040006,0x0000031c,0x00000001,0x00003261,0x00040006,0x0000031c,0x00000002, + 0x00003479,0x00040006,0x0000031c,0x00000003,0x00006969,0x00040006,0x0000031c,0x00000004, + 0x0000326b,0x00040006,0x0000031c,0x00000005,0x00003244,0x00040006,0x0000031c,0x00000006, + 0x00003056,0x00040006,0x0000031c,0x00000007,0x0000326e,0x00040006,0x0000031c,0x00000008, + 0x0000365a,0x00030005,0x0000031e,0x00003041,0x00030005,0x00000327,0x0000306a,0x00030005, + 0x0000032b,0x00006749,0x00030005,0x0000038a,0x00003466,0x00030005,0x0000038b,0x00003053, + 0x00040047,0x000000f9,0x00000001,0x00000007,0x00040047,0x0000026b,0x00000001,0x00000006, + 0x00040047,0x000002c1,0x0000000b,0x0000000f,0x00030047,0x000002c9,0x00000000,0x00040047, + 0x000002c9,0x00000021,0x0000000c,0x00040047,0x000002c9,0x00000022,0x00000001,0x00030047, + 0x000002ca,0x00000000,0x00030047,0x000002cd,0x00000000,0x00040047,0x000002cd,0x00000021, + 0x0000000c,0x00040047,0x000002cd,0x00000022,0x00000001,0x00030047,0x000002ce,0x00000000, + 0x00040047,0x000002d2,0x0000001e,0x00000000,0x00030047,0x000002d5,0x00000002,0x00050048, + 0x000002d5,0x00000000,0x00000023,0x00000000,0x00050048,0x000002d5,0x00000001,0x00000023, + 0x00000004,0x00050048,0x000002d5,0x00000002,0x00000023,0x00000008,0x00050048,0x000002d5, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x000002d5,0x00000004,0x00000023,0x00000010, + 0x00050048,0x000002d5,0x00000005,0x00000023,0x00000014,0x00050048,0x000002d5,0x00000006, + 0x00000023,0x00000018,0x00050048,0x000002d5,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x000002d5,0x00000008,0x00000023,0x00000020,0x00050048,0x000002d5,0x00000009,0x00000023, + 0x00000030,0x00050048,0x000002d5,0x0000000a,0x00000023,0x00000038,0x00050048,0x000002d5, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x000002d5,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x000002d5,0x0000000d,0x00000023,0x00000048,0x00050048,0x000002d5,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x000002d5,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x000002d5,0x00000010,0x00000023,0x00000054,0x00050048,0x000002d5,0x00000011,0x00000023, + 0x00000058,0x00050048,0x000002d5,0x00000012,0x00000023,0x0000005c,0x00050048,0x000002d5, + 0x00000013,0x00000023,0x00000060,0x00050048,0x000002d5,0x00000014,0x00000023,0x00000064, + 0x00040047,0x000002d7,0x00000021,0x00000000,0x00040047,0x000002d7,0x00000022,0x00000000, + 0x00030047,0x000002dc,0x00000000,0x00040047,0x000002de,0x00000001,0x00000001,0x00040047, + 0x000002e2,0x0000001e,0x00000002,0x00030047,0x000002ea,0x00000000,0x00030047,0x000002ed, + 0x00000000,0x00040047,0x000002ee,0x00000001,0x00000000,0x00030047,0x000002f2,0x00000000, + 0x00030047,0x000002f2,0x0000000e,0x00040047,0x000002f2,0x0000001e,0x00000001,0x00030047, + 0x000002f3,0x00000000,0x00030047,0x000002fb,0x00000017,0x00040047,0x000002fb,0x00000021, + 0x00000001,0x00040047,0x000002fb,0x00000022,0x00000002,0x00030047,0x00000304,0x00000000, + 0x00030047,0x00000307,0x00000000,0x00030047,0x0000030d,0x00000000,0x00030047,0x00000314, + 0x00000000,0x00030047,0x00000318,0x00000000,0x00030047,0x0000031b,0x00000000,0x00030047, + 0x0000031c,0x00000002,0x00050048,0x0000031c,0x00000000,0x00000023,0x00000000,0x00050048, + 0x0000031c,0x00000001,0x00000023,0x00000010,0x00050048,0x0000031c,0x00000002,0x00000023, + 0x00000018,0x00050048,0x0000031c,0x00000003,0x00000023,0x0000001c,0x00050048,0x0000031c, + 0x00000004,0x00000023,0x00000020,0x00050048,0x0000031c,0x00000005,0x00000023,0x00000030, + 0x00050048,0x0000031c,0x00000006,0x00000023,0x00000038,0x00050048,0x0000031c,0x00000007, + 0x00000023,0x0000003c,0x00050048,0x0000031c,0x00000008,0x00000023,0x00000040,0x00040047, + 0x0000031e,0x00000021,0x00000002,0x00040047,0x0000031e,0x00000022,0x00000000,0x00030047, + 0x00000327,0x00000000,0x00030047,0x00000327,0x00000017,0x00040047,0x00000327,0x00000021, + 0x00000000,0x00040047,0x00000327,0x00000022,0x00000002,0x00030047,0x00000328,0x00000000, + 0x00030047,0x0000032a,0x00000000,0x00040047,0x0000032b,0x00000001,0x00000002,0x00030047, + 0x00000344,0x00000000,0x00030047,0x00000352,0x00000000,0x00030047,0x00000353,0x00000000, + 0x00030047,0x00000356,0x00000000,0x00030047,0x00000358,0x00000000,0x00030047,0x00000359, + 0x00000000,0x00030047,0x00000363,0x00000000,0x00030047,0x00000368,0x00000000,0x00030047, + 0x0000037b,0x00000000,0x00030047,0x0000037c,0x00000000,0x00030047,0x0000037d,0x00000000, + 0x00030047,0x0000037f,0x00000000,0x00030047,0x00000380,0x00000000,0x00030047,0x0000038a, + 0x00000000,0x00030047,0x0000038a,0x00000017,0x00040047,0x0000038a,0x00000021,0x00000002, + 0x00040047,0x0000038a,0x00000022,0x00000002,0x00030047,0x0000038b,0x00000017,0x00040047, + 0x0000038b,0x00000021,0x00000003,0x00040047,0x0000038b,0x00000022,0x00000002,0x00030047, + 0x00000396,0x00000000,0x00030047,0x00000398,0x00000000,0x00030047,0x00000399,0x00000000, + 0x00030047,0x0000039b,0x00000000,0x00030047,0x0000039d,0x00000000,0x00030047,0x0000039e, + 0x00000000,0x00030047,0x000003b0,0x00000000,0x00030047,0x000003b2,0x00000000,0x00030047, + 0x000003b7,0x00000000,0x00030047,0x000003bb,0x00000000,0x00030047,0x000003c2,0x00000000, + 0x00030047,0x000003d1,0x00000000,0x00030047,0x000003d2,0x00000000,0x00030047,0x000003d4, + 0x00000000,0x00030047,0x000003fe,0x00000000,0x00030047,0x00000400,0x00000000,0x00030047, + 0x00000402,0x00000000,0x00030047,0x00000404,0x00000000,0x00030047,0x00000407,0x00000000, + 0x00030047,0x00000408,0x00000000,0x00030047,0x0000040a,0x00000000,0x00030047,0x0000040c, + 0x00000000,0x00030047,0x00000410,0x00000000,0x00030047,0x00000412,0x00000000,0x00030047, + 0x00000414,0x00000000,0x00030047,0x00000417,0x00000000,0x00030047,0x00000418,0x00000000, + 0x00030047,0x00000419,0x00000000,0x00030047,0x0000041b,0x00000000,0x00030047,0x0000041d, + 0x00000000,0x00030047,0x0000041f,0x00000000,0x00030047,0x00000421,0x00000000,0x00030047, + 0x00000427,0x00000000,0x00030047,0x00000428,0x00000000,0x00030047,0x0000042f,0x00000000, + 0x00030047,0x00000431,0x00000000,0x00030047,0x00000434,0x00000000,0x00030047,0x00000436, + 0x00000000,0x00030047,0x00000437,0x00000000,0x00030047,0x0000043a,0x00000000,0x00030047, + 0x0000043c,0x00000000,0x00030047,0x0000043d,0x00000000,0x00030047,0x00000440,0x00000000, + 0x00030047,0x00000443,0x00000000,0x00030047,0x00000444,0x00000000,0x00030047,0x00000446, + 0x00000000,0x00030047,0x00000449,0x00000000,0x00030047,0x0000044e,0x00000000,0x00030047, + 0x0000044f,0x00000000,0x00030047,0x00000457,0x00000000,0x00030047,0x0000045d,0x00000000, + 0x00030047,0x0000045f,0x00000000,0x00030047,0x00000460,0x00000000,0x00030047,0x00000461, + 0x00000000,0x00030047,0x00000464,0x00000000,0x00030047,0x00000467,0x00000000,0x00030047, + 0x00000468,0x00000000,0x00030047,0x00000469,0x00000000,0x00030047,0x0000046b,0x00000000, + 0x00030047,0x0000046e,0x00000000,0x00030047,0x0000046f,0x00000000,0x00030047,0x00000471, + 0x00000000,0x00030047,0x00000473,0x00000000,0x00030047,0x00000475,0x00000000,0x00030047, + 0x00000479,0x00000000,0x00030047,0x0000047b,0x00000000,0x00030047,0x0000047d,0x00000000, + 0x00030047,0x00000480,0x00000000,0x00030047,0x00000481,0x00000000,0x00030047,0x00000482, + 0x00000000,0x00030047,0x0000048b,0x00000000,0x00030047,0x00000491,0x00000000,0x00030047, + 0x00000492,0x00000000,0x00030047,0x00000497,0x00000000,0x00030047,0x0000049d,0x00000000, + 0x00030047,0x0000049e,0x00000000,0x00030047,0x0000049f,0x00000000,0x00030047,0x000004a2, + 0x00000000,0x00030047,0x000004a3,0x00000000,0x00030047,0x000004a4,0x00000000,0x00030047, + 0x000004aa,0x00000000,0x00030047,0x000004ab,0x00000000,0x00030047,0x000004ac,0x00000000, + 0x00030047,0x000004b6,0x00000000,0x00030047,0x000004b7,0x00000000,0x00030047,0x000004b9, + 0x00000000,0x00030047,0x000004ba,0x00000000,0x00030047,0x000004bb,0x00000000,0x00030047, + 0x000004bc,0x00000000,0x00030047,0x000004bd,0x00000000,0x00030047,0x000004c0,0x00000000, + 0x00030047,0x000004c1,0x00000000,0x00030047,0x000004c2,0x00000000,0x00030047,0x000004c4, + 0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c8,0x00000000,0x00030047, + 0x000004ca,0x00000000,0x00030047,0x000004cb,0x00000000,0x00030047,0x000004ce,0x00000000, + 0x00030047,0x000004d1,0x00000000,0x00030047,0x000004d9,0x00000000,0x00030047,0x000004dc, + 0x00000000,0x00030047,0x000004e4,0x00000000,0x00030047,0x000004e7,0x00000000,0x00030047, + 0x000004ee,0x00000000,0x00030047,0x000004f1,0x00000000,0x00030047,0x000004f7,0x00000000, + 0x00030047,0x000004fc,0x00000000,0x00030047,0x000004fe,0x00000000,0x00030047,0x00000503, + 0x00000000,0x00030047,0x00000507,0x00000000,0x00030047,0x000005a3,0x00000000,0x00030047, + 0x000005a7,0x00000000,0x00030047,0x000005a8,0x00000000,0x00030047,0x000005b8,0x00000000, + 0x00030047,0x000005bb,0x00000000,0x00030047,0x000005bc,0x00000000,0x00030047,0x000005c0, + 0x00000000,0x00030047,0x000005c2,0x00000000,0x00030047,0x000005c3,0x00000000,0x00030047, + 0x000005cc,0x00000000,0x00030047,0x000005d3,0x00000000,0x00030047,0x000005d8,0x00000000, + 0x00030047,0x000005db,0x00000000,0x00030047,0x000005dc,0x00000000,0x00030047,0x000005e0, + 0x00000000,0x00030047,0x000005e2,0x00000000,0x00030047,0x000005e3,0x00000000,0x00030047, + 0x000005e8,0x00000000,0x00030047,0x000005eb,0x00000000,0x00030047,0x000005ec,0x00000000, + 0x00030047,0x000005f0,0x00000000,0x00030047,0x000005f2,0x00000000,0x00030047,0x000005f3, + 0x00000000,0x00030047,0x00000609,0x00000000,0x00030047,0x0000060a,0x00000000,0x00030047, + 0x0000060c,0x00000000,0x00030047,0x00000612,0x00000000,0x00030047,0x00000616,0x00000000, + 0x00030047,0x00000617,0x00000000,0x00030047,0x0000061a,0x00000000,0x00030047,0x0000061c, + 0x00000000,0x00030047,0x0000061d,0x00000000,0x00030047,0x0000061e,0x00000000,0x00030047, + 0x00000621,0x00000000,0x00030047,0x00000623,0x00000000,0x00030047,0x00000624,0x00000000, + 0x00030047,0x0000062c,0x00000000,0x00030047,0x0000063e,0x00000000,0x00030047,0x0000065d, + 0x00000000,0x00030047,0x00000660,0x00000000,0x00030047,0x00000661,0x00000000,0x00030047, + 0x00000665,0x00000000,0x00030047,0x00000667,0x00000000,0x00030047,0x00000668,0x00000000, + 0x00030047,0x00000671,0x00000000,0x00030047,0x00000678,0x00000000,0x00030047,0x000006a7, + 0x00000000,0x00030047,0x000006ab,0x00000000,0x00030047,0x000006ac,0x00000000,0x00030047, + 0x000006bc,0x00000000,0x00030047,0x000006bf,0x00000000,0x00030047,0x000006c0,0x00000000, + 0x00030047,0x000006c4,0x00000000,0x00030047,0x000006c6,0x00000000,0x00030047,0x000006c7, + 0x00000000,0x00030047,0x000006d0,0x00000000,0x00030047,0x000006d7,0x00000000,0x00030047, + 0x000006dc,0x00000000,0x00030047,0x000006df,0x00000000,0x00030047,0x000006e0,0x00000000, + 0x00030047,0x000006e4,0x00000000,0x00030047,0x000006e6,0x00000000,0x00030047,0x000006e7, + 0x00000000,0x00030047,0x000006ec,0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047, + 0x000006f0,0x00000000,0x00030047,0x000006f4,0x00000000,0x00030047,0x000006f6,0x00000000, + 0x00030047,0x000006f7,0x00000000,0x00030047,0x0000070d,0x00000000,0x00030047,0x0000070e, + 0x00000000,0x00030047,0x00000710,0x00000000,0x00030047,0x00000716,0x00000000,0x00030047, + 0x0000071a,0x00000000,0x00030047,0x0000071b,0x00000000,0x00030047,0x0000071e,0x00000000, + 0x00030047,0x00000720,0x00000000,0x00030047,0x00000721,0x00000000,0x00030047,0x00000722, + 0x00000000,0x00030047,0x00000725,0x00000000,0x00030047,0x00000727,0x00000000,0x00030047, + 0x00000728,0x00000000,0x00030047,0x00000730,0x00000000,0x00030047,0x00000742,0x00000000, + 0x00030047,0x00000761,0x00000000,0x00030047,0x00000764,0x00000000,0x00030047,0x00000765, + 0x00000000,0x00030047,0x00000769,0x00000000,0x00030047,0x0000076b,0x00000000,0x00030047, + 0x0000076c,0x00000000,0x00030047,0x00000775,0x00000000,0x00030047,0x0000077c,0x00000000, + 0x00030047,0x000007b1,0x00000000,0x00030047,0x000007b2,0x00000000,0x00030047,0x000007b4, + 0x00000000,0x00030047,0x000007ba,0x00000000,0x00030047,0x000007be,0x00000000,0x00030047, + 0x000007bf,0x00000000,0x00030047,0x000007c2,0x00000000,0x00030047,0x000007c4,0x00000000, + 0x00030047,0x000007c5,0x00000000,0x00030047,0x000007c6,0x00000000,0x00030047,0x000007c9, + 0x00000000,0x00030047,0x000007cb,0x00000000,0x00030047,0x000007cc,0x00000000,0x00030047, + 0x000007d4,0x00000000,0x00030047,0x000007e6,0x00000000,0x00030047,0x00000805,0x00000000, + 0x00030047,0x00000808,0x00000000,0x00030047,0x00000809,0x00000000,0x00030047,0x0000080d, + 0x00000000,0x00030047,0x0000080f,0x00000000,0x00030047,0x00000810,0x00000000,0x00030047, + 0x00000819,0x00000000,0x00030047,0x00000820,0x00000000,0x00030047,0x00000855,0x00000000, + 0x00030047,0x00000856,0x00000000,0x00030047,0x00000858,0x00000000,0x00030047,0x0000085e, + 0x00000000,0x00030047,0x00000862,0x00000000,0x00030047,0x00000863,0x00000000,0x00030047, + 0x00000866,0x00000000,0x00030047,0x00000868,0x00000000,0x00030047,0x00000869,0x00000000, + 0x00030047,0x0000086a,0x00000000,0x00030047,0x0000086d,0x00000000,0x00030047,0x0000086f, + 0x00000000,0x00030047,0x00000870,0x00000000,0x00030047,0x00000878,0x00000000,0x00030047, + 0x0000088a,0x00000000,0x00030047,0x000008a9,0x00000000,0x00030047,0x000008ac,0x00000000, + 0x00030047,0x000008ad,0x00000000,0x00030047,0x000008b1,0x00000000,0x00030047,0x000008b3, + 0x00000000,0x00030047,0x000008b4,0x00000000,0x00030047,0x000008bd,0x00000000,0x00030047, + 0x000008c4,0x00000000,0x00030047,0x000008e6,0x00000000,0x00030047,0x000008e7,0x00000000, + 0x00030047,0x000008f9,0x00000000,0x00030047,0x000008fa,0x00000000,0x00030047,0x000008fd, + 0x00000000,0x00030047,0x000008ff,0x00000000,0x00030047,0x00000907,0x00000000,0x00030047, + 0x00000909,0x00000000,0x00030047,0x0000090b,0x00000000,0x00030047,0x0000090f,0x00000000, + 0x00030047,0x00000911,0x00000000,0x00030047,0x00000913,0x00000000,0x00030047,0x00000915, + 0x00000000,0x00030047,0x00000917,0x00000000,0x00030047,0x00000919,0x00000000,0x00030047, + 0x0000091b,0x00000000,0x00030047,0x0000091d,0x00000000,0x00030047,0x0000091f,0x00000000, + 0x00030047,0x00000927,0x00000000,0x00030047,0x00000929,0x00000000,0x00030047,0x0000092b, + 0x00000000,0x00030047,0x0000093a,0x00000000,0x00030047,0x0000093c,0x00000000,0x00030047, + 0x0000093e,0x00000000,0x00030047,0x00000940,0x00000000,0x00030047,0x00000942,0x00000000, + 0x00030047,0x00000944,0x00000000,0x00030047,0x0000094c,0x00000000,0x00030047,0x0000094e, + 0x00000000,0x00030047,0x00000950,0x00000000,0x00030047,0x00000953,0x00000000,0x00030047, + 0x00000963,0x00000000,0x00030047,0x00000965,0x00000000,0x00030047,0x00000967,0x00000000, + 0x00030047,0x00000969,0x00000000,0x00030047,0x0000096b,0x00000000,0x00030047,0x0000096d, + 0x00000000,0x00030047,0x0000096f,0x00000000,0x00030047,0x00000971,0x00000000,0x00030047, + 0x00000973,0x00000000,0x00030047,0x00000981,0x00000000,0x00030047,0x00000983,0x00000000, + 0x00030047,0x00000985,0x00000000,0x00030047,0x0000098d,0x00000000,0x00030047,0x0000098f, + 0x00000000,0x00030047,0x00000991,0x00000000,0x00030047,0x00000993,0x00000000,0x00030047, + 0x0000099b,0x00000000,0x00030047,0x0000099d,0x00000000,0x00030047,0x000009a1,0x00000000, + 0x00030047,0x000009a3,0x00000000,0x00030047,0x000009a5,0x00000000,0x00030047,0x000009a7, + 0x00000000,0x00030047,0x000009a9,0x00000000,0x00030047,0x000009ab,0x00000000,0x00030047, + 0x000009b9,0x00000000,0x00030047,0x000009bb,0x00000000,0x00030047,0x000009bd,0x00000000, + 0x00030047,0x000009c5,0x00000000,0x00030047,0x000009c7,0x00000000,0x00030047,0x000009c9, + 0x00000000,0x00030047,0x000009cb,0x00000000,0x00030047,0x000009d3,0x00000000,0x00030047, + 0x000009d5,0x00000000,0x00030047,0x000009d9,0x00000000,0x00030047,0x000009db,0x00000000, + 0x00030047,0x000009dd,0x00000000,0x00030047,0x000009df,0x00000000,0x00030047,0x000009e1, + 0x00000000,0x00030047,0x000009e3,0x00000000,0x00030047,0x000009e5,0x00000000,0x00030047, + 0x000009e7,0x00000000,0x00030047,0x000009e9,0x00000000,0x00030047,0x000009f1,0x00000000, + 0x00030047,0x000009f3,0x00000000,0x00030047,0x000009f5,0x00000000,0x00030047,0x000009f7, + 0x00000000,0x00030047,0x000009ff,0x00000000,0x00030047,0x00000a01,0x00000000,0x00030047, + 0x00000a05,0x00000000,0x00030047,0x00000a07,0x00000000,0x00030047,0x00000a09,0x00000000, + 0x00030047,0x00000a0b,0x00000000,0x00030047,0x00000a0d,0x00000000,0x00030047,0x00000a0f, + 0x00000000,0x00030047,0x00000a11,0x00000000,0x00030047,0x00000a13,0x00000000,0x00030047, + 0x00000a15,0x00000000,0x00030047,0x00000a1d,0x00000000,0x00030047,0x00000a1f,0x00000000, + 0x00030047,0x00000a21,0x00000000,0x00030047,0x00000a23,0x00000000,0x00030047,0x00000a2b, + 0x00000000,0x00030047,0x00000a2d,0x00000000,0x00030047,0x00000a32,0x00000000,0x00030047, + 0x00000a34,0x00000000,0x00030047,0x00000a36,0x00000000,0x00030047,0x00000a38,0x00000000, + 0x00030047,0x00000a3a,0x00000000,0x00030047,0x00000a3c,0x00000000,0x00030047,0x00000a3f, + 0x00000000,0x00030047,0x00000a42,0x00000000,0x00030047,0x00000a44,0x00000000,0x00030047, + 0x00000a46,0x00000000,0x00030047,0x00000a4a,0x00000000,0x00030047,0x00000a4c,0x00000000, + 0x00030047,0x00000a4e,0x00000000,0x00030047,0x00000a50,0x00000000,0x00030047,0x00000a53, + 0x00000000,0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a59,0x00000000,0x00030047, + 0x00000a5b,0x00000000,0x00030047,0x00000b22,0x00000000,0x00030047,0x00000b7a,0x00000000, + 0x00030047,0x00000b7b,0x00000000,0x00030047,0x00000b7c,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040015,0x0000000d,0x00000020,0x00000000,0x00040020,0x00000013, + 0x00000007,0x00000006,0x00040017,0x00000018,0x00000006,0x00000002,0x00040017,0x00000022, + 0x00000006,0x00000003,0x00040020,0x00000036,0x00000007,0x00000022,0x0004002b,0x0000000d, + 0x0000007a,0x00000000,0x0004002b,0x00000006,0x000000a4,0x00000000,0x00020014,0x000000a5, + 0x0004002b,0x00000006,0x000000aa,0x3f800000,0x0004002b,0x00000006,0x000000e3,0x3d897143, + 0x0004002b,0x00000006,0x000000e7,0x3bbf4590,0x0004002b,0x00000006,0x000000ee,0x4253ee82, + 0x00030030,0x000000a5,0x000000f9,0x0004002b,0x00000006,0x0000010d,0x3e99999a,0x0004002b, + 0x00000006,0x0000010e,0x3f170a3d,0x0004002b,0x00000006,0x0000010f,0x3de147ae,0x0004002b, + 0x00000006,0x00000129,0x388205ff,0x0004002b,0x00000006,0x0000018f,0x40000000,0x0004002b, + 0x00000006,0x00000196,0x3f000000,0x00040017,0x0000019c,0x000000a5,0x00000003,0x00040015, + 0x00000218,0x00000020,0x00000001,0x0004002b,0x00000218,0x0000021b,0x00000000,0x0004002b, + 0x00000218,0x00000222,0x00000003,0x0004002b,0x00000006,0x00000234,0x3e800000,0x0004002b, + 0x00000006,0x00000239,0x41800000,0x0004002b,0x00000006,0x0000023e,0x41400000,0x0004002b, + 0x00000006,0x00000244,0x40400000,0x0004002b,0x00000218,0x00000250,0x00000001,0x00030030, + 0x000000a5,0x0000026b,0x00040017,0x000002bd,0x00000218,0x00000002,0x00040020,0x000002c0, + 0x00000001,0x00000007,0x0004003b,0x000002c0,0x000002c1,0x00000001,0x00090019,0x000002c7, + 0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x000002c8,0x00000000,0x000002c7,0x0004003b,0x000002c8,0x000002c9,0x00000000,0x0002001a, + 0x000002cb,0x00040020,0x000002cc,0x00000000,0x000002cb,0x0004003b,0x000002cc,0x000002cd, + 0x00000000,0x0003001b,0x000002cf,0x000002c7,0x00040020,0x000002d1,0x00000001,0x00000018, + 0x0004003b,0x000002d1,0x000002d2,0x00000001,0x00040017,0x000002d4,0x00000218,0x00000004, + 0x0017001e,0x000002d5,0x00000006,0x00000006,0x00000006,0x00000006,0x0000000d,0x0000000d, + 0x0000000d,0x0000000d,0x000002d4,0x00000018,0x00000018,0x0000000d,0x00000006,0x0000000d, + 0x00000006,0x00000006,0x0000000d,0x00000006,0x00000006,0x00000006,0x0000000d,0x00040020, + 0x000002d6,0x00000002,0x000002d5,0x0004003b,0x000002d6,0x000002d7,0x00000002,0x0004002b, + 0x00000218,0x000002d8,0x0000000f,0x00040020,0x000002d9,0x00000002,0x00000006,0x00030030, + 0x000000a5,0x000002de,0x0004003b,0x000002c0,0x000002e2,0x00000001,0x00030030,0x000000a5, + 0x000002ee,0x00040020,0x000002f1,0x00000001,0x00000006,0x0004003b,0x000002f1,0x000002f2, + 0x00000001,0x00090019,0x000002f9,0x0000000d,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000002,0x00000021,0x00040020,0x000002fa,0x00000000,0x000002f9,0x0004003b,0x000002fa, + 0x000002fb,0x00000000,0x00040017,0x000002fe,0x0000000d,0x00000004,0x000b001e,0x0000031c, + 0x00000007,0x00000018,0x00000006,0x00000006,0x00000007,0x00000018,0x0000000d,0x0000000d, + 0x0000000d,0x00040020,0x0000031d,0x00000002,0x0000031c,0x0004003b,0x0000031d,0x0000031e, + 0x00000002,0x0004002b,0x00000218,0x0000031f,0x00000002,0x00090019,0x00000325,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000004,0x00040020,0x00000326, + 0x00000000,0x00000325,0x0004003b,0x00000326,0x00000327,0x00000000,0x00030030,0x000000a5, + 0x0000032b,0x0004002b,0x00000218,0x00000338,0x00000007,0x00040020,0x0000033a,0x00000002, + 0x0000000d,0x0004002b,0x00000218,0x00000364,0x00000011,0x0004002b,0x00000218,0x00000365, + 0x00000012,0x0004003b,0x00000326,0x0000038a,0x00000000,0x0004003b,0x000002fa,0x0000038b, + 0x00000000,0x00030001,0x00000022,0x00000a61,0x0006002c,0x00000022,0x00000b7e,0x00000196, + 0x00000196,0x00000196,0x0006002c,0x00000022,0x00000b7f,0x000000aa,0x000000aa,0x000000aa, + 0x00030001,0x00000018,0x00000b81,0x00030001,0x00000022,0x00000b82,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000036,0x000003d2, + 0x00000007,0x0004003b,0x00000036,0x000003d4,0x00000007,0x0004003b,0x00000036,0x000003c2, + 0x00000007,0x0004003d,0x00000007,0x000002c2,0x000002c1,0x0007004f,0x00000018,0x000002c3, + 0x000002c2,0x000002c2,0x00000000,0x00000001,0x0006000c,0x00000018,0x000002c4,0x00000001, + 0x00000008,0x000002c3,0x0004006e,0x000002bd,0x000002c5,0x000002c4,0x0004003d,0x000002c7, + 0x000002ca,0x000002c9,0x0004003d,0x000002cb,0x000002ce,0x000002cd,0x00050056,0x000002cf, + 0x000002d0,0x000002ca,0x000002ce,0x0004003d,0x00000018,0x000002d3,0x000002d2,0x00050041, + 0x000002d9,0x000002da,0x000002d7,0x000002d8,0x0004003d,0x00000006,0x000002db,0x000002da, + 0x00070057,0x00000007,0x000002dc,0x000002d0,0x000002d3,0x00000001,0x000002db,0x000300f7, + 0x000002e0,0x00000000,0x000400fa,0x000002de,0x000002df,0x000002e0,0x000200f8,0x000002df, + 0x0004003d,0x00000007,0x000002e4,0x000002e2,0x0007004f,0x00000018,0x00000396,0x000002e4, + 0x000002e4,0x00000000,0x00000001,0x0007004f,0x00000018,0x00000398,0x000002e4,0x000002e4, + 0x00000002,0x00000003,0x0007000c,0x00000018,0x00000399,0x00000001,0x00000025,0x00000396, + 0x00000398,0x00050051,0x00000006,0x0000039b,0x00000399,0x00000000,0x00050051,0x00000006, + 0x0000039d,0x00000399,0x00000001,0x0007000c,0x00000006,0x0000039e,0x00000001,0x00000025, + 0x0000039b,0x0000039d,0x0007000c,0x00000006,0x000002ea,0x00000001,0x00000028,0x0000039e, + 0x000000a4,0x0007000c,0x00000006,0x000002ed,0x00000001,0x00000025,0x000002ea,0x000000aa, + 0x000200f9,0x000002e0,0x000200f8,0x000002e0,0x000700f5,0x00000006,0x00000a53,0x000000aa, + 0x00000005,0x000002ed,0x000002df,0x000114f4,0x000300f7,0x000002f0,0x00000000,0x000400fa, + 0x000002ee,0x000002ef,0x000002f0,0x000200f8,0x000002ef,0x0004003d,0x00000006,0x000002f3, + 0x000002f2,0x000500b7,0x000000a5,0x000002f4,0x000002f3,0x000000a4,0x000200f9,0x000002f0, + 0x000200f8,0x000002f0,0x000700f5,0x000000a5,0x000002f5,0x000002ee,0x000002e0,0x000002f4, + 0x000002ef,0x000300f7,0x000002f7,0x00000000,0x000400fa,0x000002f5,0x000002f6,0x000002f7, + 0x000200f8,0x000002f6,0x0004003d,0x000002f9,0x000002fc,0x000002fb,0x00050062,0x000002fe, + 0x000002ff,0x000002fc,0x000002c5,0x00050051,0x0000000d,0x00000300,0x000002ff,0x00000000, + 0x0006000c,0x00000018,0x00000301,0x00000001,0x0000003e,0x00000300,0x00050051,0x00000006, + 0x00000304,0x00000301,0x00000001,0x0004003d,0x00000006,0x00000307,0x000002f2,0x000500b4, + 0x000000a5,0x00000308,0x00000304,0x00000307,0x000300f7,0x0000030b,0x00000000,0x000400fa, + 0x00000308,0x0000030a,0x0000030e,0x000200f8,0x0000030a,0x00050051,0x00000006,0x0000030d, + 0x00000301,0x00000000,0x000200f9,0x0000030b,0x000200f8,0x0000030e,0x000200f9,0x0000030b, + 0x000200f8,0x0000030b,0x000700f5,0x00000006,0x00000a50,0x0000030d,0x0000030a,0x000000a4, + 0x0000030e,0x0007000c,0x00000006,0x00000314,0x00000001,0x00000028,0x00000a50,0x000000a4, + 0x0007000c,0x00000006,0x00000318,0x00000001,0x00000028,0x00000314,0x000000a4,0x0007000c, + 0x00000006,0x0000031b,0x00000001,0x00000025,0x00000a53,0x00000318,0x000200f9,0x000002f7, + 0x000200f8,0x000002f7,0x000700f5,0x00000006,0x00000a54,0x00000a53,0x000002f0,0x0000031b, + 0x0000030b,0x00050041,0x000002d9,0x00000320,0x0000031e,0x0000031f,0x0004003d,0x00000006, + 0x00000321,0x00000320,0x00050085,0x00000006,0x00000323,0x00000a54,0x00000321,0x0004003d, + 0x00000325,0x00000328,0x00000327,0x00050062,0x00000007,0x0000032a,0x00000328,0x000002c5, + 0x000300f7,0x0000032d,0x00000000,0x000400fa,0x0000032b,0x0000032c,0x00000360,0x000200f8, + 0x0000032c,0x0008004f,0x00000022,0x000003b0,0x000002dc,0x000002dc,0x00000000,0x00000001, + 0x00000002,0x00050051,0x00000006,0x000003b2,0x000002dc,0x00000003,0x000500b7,0x000000a5, + 0x000003b3,0x000003b2,0x000000a4,0x000300f7,0x000003b9,0x00000000,0x000400fa,0x000003b3, + 0x000003b4,0x000003b8,0x000200f8,0x000003b4,0x00050088,0x00000006,0x000003b7,0x000000aa, + 0x000003b2,0x000200f9,0x000003b9,0x000200f8,0x000003b8,0x000200f9,0x000003b9,0x000200f8, + 0x000003b9,0x000700f5,0x00000006,0x00000a59,0x000003b7,0x000003b4,0x000000a4,0x000003b8, + 0x0005008e,0x00000022,0x000003bb,0x000003b0,0x00000a59,0x00050051,0x00000006,0x00000332, + 0x000003bb,0x00000000,0x00060052,0x00000007,0x00000907,0x00000332,0x000002dc,0x00000000, + 0x00050051,0x00000006,0x00000334,0x000003bb,0x00000001,0x00060052,0x00000007,0x00000909, + 0x00000334,0x00000907,0x00000001,0x00050051,0x00000006,0x00000336,0x000003bb,0x00000002, + 0x00060052,0x00000007,0x0000090b,0x00000336,0x00000909,0x00000002,0x00050041,0x0000033a, + 0x0000033b,0x0000031e,0x00000338,0x0004003d,0x0000000d,0x0000033c,0x0000033b,0x000500ab, + 0x000000a5,0x0000033f,0x0000033c,0x0000007a,0x000300f7,0x00000341,0x00000000,0x000400fa, + 0x0000033f,0x00000340,0x00000341,0x000200f8,0x00000340,0x0008004f,0x00000022,0x00000344, + 0x0000090b,0x0000090b,0x00000000,0x00000001,0x00000002,0x0003003e,0x000003c2,0x00000344, + 0x0008004f,0x00000022,0x000004fc,0x0000032a,0x0000032a,0x00000000,0x00000001,0x00000002, + 0x00050051,0x00000006,0x000004fe,0x0000032a,0x00000003,0x000500b7,0x000000a5,0x000004ff, + 0x000004fe,0x000000a4,0x000300f7,0x00000505,0x00000000,0x000400fa,0x000004ff,0x00000500, + 0x00000504,0x000200f8,0x00000500,0x00050088,0x00000006,0x00000503,0x000000aa,0x000004fe, + 0x000200f9,0x00000505,0x000200f8,0x00000504,0x000200f9,0x00000505,0x000200f8,0x00000505, + 0x000700f5,0x00000006,0x00000a5b,0x00000503,0x00000500,0x000000a4,0x00000504,0x0005008e, + 0x00000022,0x00000507,0x000004fc,0x00000a5b,0x0003003e,0x000003d2,0x00000507,0x000300f7, + 0x000004f6,0x00000000,0x002100fb,0x0000033c,0x000004f6,0x0000000b,0x000003fd,0x00000001, + 0x00000401,0x00000002,0x00000409,0x00000003,0x0000041a,0x00000004,0x0000041e,0x00000005, + 0x00000422,0x00000006,0x00000445,0x00000007,0x00000472,0x00000008,0x00000483,0x00000009, + 0x000004be,0x0000000a,0x000004c3,0x0000000c,0x000004cc,0x0000000d,0x000004d7,0x0000000e, + 0x000004e2,0x0000000f,0x000004ec,0x000200f8,0x000003fd,0x0004003d,0x00000022,0x000003fe, + 0x000003c2,0x00050085,0x00000022,0x00000400,0x000003fe,0x00000507,0x0003003e,0x000003d4, + 0x00000400,0x000200f9,0x000004f6,0x000200f8,0x00000401,0x0004003d,0x00000022,0x00000402, + 0x000003c2,0x00050081,0x00000022,0x00000404,0x00000402,0x00000507,0x00050085,0x00000022, + 0x00000407,0x00000402,0x00000507,0x00050083,0x00000022,0x00000408,0x00000404,0x00000407, + 0x0003003e,0x000003d4,0x00000408,0x000200f9,0x000004f6,0x000200f8,0x00000409,0x0004003d, + 0x00000022,0x0000040a,0x000003c2,0x00050085,0x00000022,0x0000040c,0x0000040a,0x00000507, + 0x00050081,0x00000022,0x00000410,0x0000040a,0x00000507,0x00050083,0x00000022,0x00000412, + 0x00000410,0x0000040c,0x00050083,0x00000022,0x00000414,0x00000412,0x00000b7e,0x00060052, + 0x00000022,0x0000090f,0x00000196,0x00000a61,0x00000000,0x00060052,0x00000022,0x00000911, + 0x00000196,0x0000090f,0x00000001,0x00060052,0x00000022,0x00000913,0x00000196,0x00000911, + 0x00000002,0x000500ba,0x0000019c,0x00000417,0x00000507,0x00000913,0x000600a9,0x00000022, + 0x00000418,0x00000417,0x00000414,0x0000040c,0x0005008e,0x00000022,0x00000419,0x00000418, + 0x0000018f,0x0003003e,0x000003d4,0x00000419,0x000200f9,0x000004f6,0x000200f8,0x0000041a, + 0x0004003d,0x00000022,0x0000041b,0x000003c2,0x0007000c,0x00000022,0x0000041d,0x00000001, + 0x00000025,0x0000041b,0x00000507,0x0003003e,0x000003d4,0x0000041d,0x000200f9,0x000004f6, + 0x000200f8,0x0000041e,0x0004003d,0x00000022,0x0000041f,0x000003c2,0x0007000c,0x00000022, + 0x00000421,0x00000001,0x00000028,0x0000041f,0x00000507,0x0003003e,0x000003d4,0x00000421, + 0x000200f9,0x000004f6,0x000200f8,0x00000422,0x00060052,0x00000022,0x00000915,0x000000a4, + 0x00000a61,0x00000000,0x00060052,0x00000022,0x00000917,0x000000a4,0x00000915,0x00000001, + 0x00060052,0x00000022,0x00000919,0x000000a4,0x00000917,0x00000002,0x0008004f,0x00000022, + 0x00000427,0x0000032a,0x0000032a,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000022, + 0x00000428,0x00000001,0x0000002b,0x000004fc,0x00000919,0x00000427,0x00050051,0x00000006, + 0x0000042a,0x00000428,0x00000000,0x00060052,0x00000007,0x0000091b,0x0000042a,0x0000032a, + 0x00000000,0x00050051,0x00000006,0x0000042c,0x00000428,0x00000001,0x00060052,0x00000007, + 0x0000091d,0x0000042c,0x0000091b,0x00000001,0x00050051,0x00000006,0x0000042e,0x00000428, + 0x00000002,0x00060052,0x00000007,0x0000091f,0x0000042e,0x0000091d,0x00000002,0x0004003d, + 0x00000022,0x0000042f,0x000003c2,0x00050083,0x00000022,0x00000431,0x00000b7f,0x0000042f, + 0x00060052,0x00000022,0x00000927,0x000000aa,0x00000a61,0x00000000,0x00060052,0x00000022, + 0x00000929,0x000000aa,0x00000927,0x00000001,0x00060052,0x00000022,0x0000092b,0x000000aa, + 0x00000929,0x00000002,0x0008000c,0x00000022,0x00000434,0x00000001,0x0000002b,0x00000431, + 0x00000919,0x0000092b,0x00050051,0x00000006,0x00000436,0x0000091f,0x00000003,0x0005008e, + 0x00000022,0x00000437,0x00000434,0x00000436,0x0008004f,0x00000022,0x0000043a,0x0000091f, + 0x0000091f,0x00000000,0x00000001,0x00000002,0x00050088,0x00000022,0x0000043c,0x0000043a, + 0x00000437,0x0007000c,0x00000022,0x0000043d,0x00000001,0x00000025,0x0000092b,0x0000043c, + 0x0006000c,0x00000022,0x00000440,0x00000001,0x00000006,0x0000043a,0x000500b4,0x0000019c, + 0x00000443,0x00000437,0x00000919,0x000600a9,0x00000022,0x00000444,0x00000443,0x00000440, + 0x0000043d,0x0003003e,0x000003d4,0x00000444,0x000200f9,0x000004f6,0x000200f8,0x00000445, + 0x0004003d,0x00000022,0x00000446,0x000003c2,0x00060052,0x00000022,0x0000093a,0x000000a4, + 0x00000a61,0x00000000,0x00060052,0x00000022,0x0000093c,0x000000a4,0x0000093a,0x00000001, + 0x00060052,0x00000022,0x0000093e,0x000000a4,0x0000093c,0x00000002,0x00060052,0x00000022, + 0x00000940,0x000000aa,0x00000a61,0x00000000,0x00060052,0x00000022,0x00000942,0x000000aa, + 0x00000940,0x00000001,0x00060052,0x00000022,0x00000944,0x000000aa,0x00000942,0x00000002, + 0x0008000c,0x00000022,0x00000449,0x00000001,0x0000002b,0x00000446,0x0000093e,0x00000944, + 0x0003003e,0x000003c2,0x00000449,0x0008004f,0x00000022,0x0000044e,0x0000032a,0x0000032a, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x00000022,0x0000044f,0x00000001,0x0000002b, + 0x000004fc,0x0000093e,0x0000044e,0x00050051,0x00000006,0x00000451,0x0000044f,0x00000000, + 0x00060052,0x00000007,0x0000094c,0x00000451,0x0000032a,0x00000000,0x00050051,0x00000006, + 0x00000453,0x0000044f,0x00000001,0x00060052,0x00000007,0x0000094e,0x00000453,0x0000094c, + 0x00000001,0x00050051,0x00000006,0x00000455,0x0000044f,0x00000002,0x00060052,0x00000007, + 0x00000950,0x00000455,0x0000094e,0x00000002,0x00050051,0x00000006,0x00000457,0x00000950, + 0x00000003,0x000500b4,0x000000a5,0x00000458,0x00000457,0x000000a4,0x000300f7,0x0000045b, + 0x00000000,0x000400fa,0x00000458,0x00000459,0x0000045b,0x000200f8,0x00000459,0x00060052, + 0x00000007,0x00000953,0x000000aa,0x00000950,0x00000003,0x000200f9,0x0000045b,0x000200f8, + 0x0000045b,0x000700f5,0x00000007,0x00000b22,0x00000950,0x00000445,0x00000953,0x00000459, + 0x00050051,0x00000006,0x0000045d,0x00000b22,0x00000003,0x0008004f,0x00000022,0x0000045f, + 0x00000b22,0x00000b22,0x00000000,0x00000001,0x00000002,0x00060050,0x00000022,0x00000460, + 0x0000045d,0x0000045d,0x0000045d,0x00050083,0x00000022,0x00000461,0x00000460,0x0000045f, + 0x0004003d,0x00000022,0x00000464,0x000003c2,0x0005008e,0x00000022,0x00000467,0x00000464, + 0x0000045d,0x00050088,0x00000022,0x00000468,0x00000461,0x00000467,0x0007000c,0x00000022, + 0x00000469,0x00000001,0x00000025,0x00000944,0x00000468,0x0006000c,0x00000022,0x0000046b, + 0x00000001,0x00000006,0x00000461,0x000500b4,0x0000019c,0x0000046e,0x00000464,0x0000093e, + 0x000600a9,0x00000022,0x0000046f,0x0000046e,0x0000046b,0x00000469,0x00050083,0x00000022, + 0x00000471,0x00000b7f,0x0000046f,0x0003003e,0x000003d4,0x00000471,0x000200f9,0x000004f6, + 0x000200f8,0x00000472,0x0004003d,0x00000022,0x00000473,0x000003c2,0x00050085,0x00000022, + 0x00000475,0x00000473,0x00000507,0x00050081,0x00000022,0x00000479,0x00000473,0x00000507, + 0x00050083,0x00000022,0x0000047b,0x00000479,0x00000475,0x00050083,0x00000022,0x0000047d, + 0x0000047b,0x00000b7e,0x00060052,0x00000022,0x00000963,0x00000196,0x00000a61,0x00000000, + 0x00060052,0x00000022,0x00000965,0x00000196,0x00000963,0x00000001,0x00060052,0x00000022, + 0x00000967,0x00000196,0x00000965,0x00000002,0x000500ba,0x0000019c,0x00000480,0x00000473, + 0x00000967,0x000600a9,0x00000022,0x00000481,0x00000480,0x0000047d,0x00000475,0x0005008e, + 0x00000022,0x00000482,0x00000481,0x0000018f,0x0003003e,0x000003d4,0x00000482,0x000200f9, + 0x000004f6,0x000200f8,0x00000483,0x000200f9,0x00000484,0x000200f8,0x00000484,0x000700f5, + 0x00000218,0x00000b06,0x0000021b,0x00000483,0x000004b2,0x000004b0,0x000500b1,0x000000a5, + 0x00000487,0x00000b06,0x00000222,0x000400f6,0x000004b3,0x000004b0,0x00000000,0x000400fa, + 0x00000487,0x00000488,0x000004b3,0x000200f8,0x00000488,0x00050041,0x00000013,0x0000048a, + 0x000003c2,0x00000b06,0x0004003d,0x00000006,0x0000048b,0x0000048a,0x000500bc,0x000000a5, + 0x0000048c,0x0000048b,0x00000196,0x000300f7,0x000004af,0x00000000,0x000400fa,0x0000048c, + 0x0000048d,0x00000494,0x000200f8,0x0000048d,0x00050041,0x00000013,0x00000490,0x000003d2, + 0x00000b06,0x0004003d,0x00000006,0x00000491,0x00000490,0x00050083,0x00000006,0x00000492, + 0x000000aa,0x00000491,0x00050041,0x00000013,0x00000493,0x000003d4,0x00000b06,0x0003003e, + 0x00000493,0x00000492,0x000200f9,0x000004af,0x000200f8,0x00000494,0x00050041,0x00000013, + 0x00000496,0x000003d2,0x00000b06,0x0004003d,0x00000006,0x00000497,0x00000496,0x000500bc, + 0x000000a5,0x00000498,0x00000497,0x00000234,0x000300f7,0x000004ae,0x00000000,0x000400fa, + 0x00000498,0x00000499,0x000004a6,0x000200f8,0x00000499,0x0004003d,0x00000006,0x0000049d, + 0x00000496,0x00050085,0x00000006,0x0000049e,0x00000239,0x0000049d,0x00050083,0x00000006, + 0x0000049f,0x0000049e,0x0000023e,0x0004003d,0x00000006,0x000004a2,0x00000496,0x00050085, + 0x00000006,0x000004a3,0x0000049f,0x000004a2,0x00050081,0x00000006,0x000004a4,0x000004a3, + 0x00000244,0x00050041,0x00000013,0x000004a5,0x000003d4,0x00000b06,0x0003003e,0x000004a5, + 0x000004a4,0x000200f9,0x000004ae,0x000200f8,0x000004a6,0x0004003d,0x00000006,0x000004aa, + 0x00000496,0x0006000c,0x00000006,0x000004ab,0x00000001,0x00000020,0x000004aa,0x00050083, + 0x00000006,0x000004ac,0x000004ab,0x000000aa,0x00050041,0x00000013,0x000004ad,0x000003d4, + 0x00000b06,0x0003003e,0x000004ad,0x000004ac,0x000200f9,0x000004ae,0x000200f8,0x000004ae, + 0x000200f9,0x000004af,0x000200f8,0x000004af,0x000200f9,0x000004b0,0x000200f8,0x000004b0, + 0x00050080,0x00000218,0x000004b2,0x00000b06,0x00000250,0x000200f9,0x00000484,0x000200f8, + 0x000004b3,0x0004003d,0x00000022,0x000004b6,0x000003c2,0x0005008e,0x00000022,0x000004b7, + 0x000004b6,0x0000018f,0x00050083,0x00000022,0x000004b9,0x000004b7,0x00000b7f,0x00050085, + 0x00000022,0x000004ba,0x00000507,0x000004b9,0x0004003d,0x00000022,0x000004bb,0x000003d4, + 0x00050085,0x00000022,0x000004bc,0x000004ba,0x000004bb,0x00050081,0x00000022,0x000004bd, + 0x00000507,0x000004bc,0x0003003e,0x000003d4,0x000004bd,0x000200f9,0x000004f6,0x000200f8, + 0x000004be,0x0004003d,0x00000022,0x000004c0,0x000003c2,0x00050083,0x00000022,0x000004c1, + 0x00000507,0x000004c0,0x0006000c,0x00000022,0x000004c2,0x00000001,0x00000004,0x000004c1, + 0x0003003e,0x000003d4,0x000004c2,0x000200f9,0x000004f6,0x000200f8,0x000004c3,0x0004003d, + 0x00000022,0x000004c4,0x000003c2,0x00050081,0x00000022,0x000004c6,0x000004c4,0x00000507, + 0x0005008e,0x00000022,0x000004c8,0x000004c4,0x0000018f,0x00050085,0x00000022,0x000004ca, + 0x000004c8,0x00000507,0x00050083,0x00000022,0x000004cb,0x000004c6,0x000004ca,0x0003003e, + 0x000003d4,0x000004cb,0x000200f9,0x000004f6,0x000200f8,0x000004cc,0x000300f7,0x000004d6, + 0x00000000,0x000400fa,0x0000026b,0x000004cd,0x000004d6,0x000200f8,0x000004cd,0x0004003d, + 0x00000022,0x000004ce,0x000003c2,0x00060052,0x00000022,0x00000969,0x000000a4,0x00000a61, + 0x00000000,0x00060052,0x00000022,0x0000096b,0x000000a4,0x00000969,0x00000001,0x00060052, + 0x00000022,0x0000096d,0x000000a4,0x0000096b,0x00000002,0x00060052,0x00000022,0x0000096f, + 0x000000aa,0x00000a61,0x00000000,0x00060052,0x00000022,0x00000971,0x000000aa,0x0000096f, + 0x00000001,0x00060052,0x00000022,0x00000973,0x000000aa,0x00000971,0x00000002,0x0008000c, + 0x00000022,0x000004d1,0x00000001,0x0000002b,0x000004ce,0x0000096d,0x00000973,0x0003003e, + 0x000003c2,0x000004d1,0x0007004f,0x00000018,0x000005b8,0x00000507,0x00000507,0x00000000, + 0x00000001,0x00050051,0x00000006,0x000005c0,0x000005b8,0x00000000,0x00050051,0x00000006, + 0x000005c2,0x000005b8,0x00000001,0x0007000c,0x00000006,0x000005c3,0x00000001,0x00000028, + 0x000005c0,0x000005c2,0x00050051,0x00000006,0x000005bb,0x00000507,0x00000002,0x0007000c, + 0x00000006,0x000005bc,0x00000001,0x00000028,0x000005c3,0x000005bb,0x0007000c,0x00000006, + 0x000005d3,0x00000001,0x00000025,0x000005c0,0x000005c2,0x0007000c,0x00000006,0x000005cc, + 0x00000001,0x00000025,0x000005d3,0x000005bb,0x00050083,0x00000006,0x000005a3,0x000005bc, + 0x000005cc,0x0007004f,0x00000018,0x000005d8,0x000004d1,0x000004d1,0x00000000,0x00000001, + 0x00050051,0x00000006,0x000005e0,0x000005d8,0x00000000,0x00050051,0x00000006,0x000005e2, + 0x000005d8,0x00000001,0x0007000c,0x00000006,0x000005e3,0x00000001,0x00000025,0x000005e0, + 0x000005e2,0x00050051,0x00000006,0x000005db,0x000004d1,0x00000002,0x0007000c,0x00000006, + 0x000005dc,0x00000001,0x00000025,0x000005e3,0x000005db,0x00060050,0x00000022,0x000005a7, + 0x000005dc,0x000005dc,0x000005dc,0x00050083,0x00000022,0x000005a8,0x000004d1,0x000005a7, + 0x0007004f,0x00000018,0x000005e8,0x000005a8,0x000005a8,0x00000000,0x00000001,0x00050051, + 0x00000006,0x000005f0,0x000005e8,0x00000000,0x00050051,0x00000006,0x000005f2,0x000005e8, + 0x00000001,0x0007000c,0x00000006,0x000005f3,0x00000001,0x00000028,0x000005f0,0x000005f2, + 0x00050051,0x00000006,0x000005eb,0x000005a8,0x00000002,0x0007000c,0x00000006,0x000005ec, + 0x00000001,0x00000028,0x000005f3,0x000005eb,0x0007000c,0x00000006,0x000005ad,0x00000001, + 0x00000028,0x00000129,0x000005ec,0x00050088,0x00000006,0x000005ae,0x000005a3,0x000005ad, + 0x0005008e,0x00000022,0x000005b1,0x000005a8,0x000005ae,0x00060052,0x00000022,0x00000981, + 0x0000010d,0x00000a61,0x00000000,0x00060052,0x00000022,0x00000983,0x0000010e,0x00000981, + 0x00000001,0x00060052,0x00000022,0x00000985,0x0000010f,0x00000983,0x00000002,0x00050094, + 0x00000006,0x0000062c,0x00000507,0x00000985,0x00050094,0x00000006,0x0000063e,0x000005b1, + 0x00000985,0x00060050,0x00000022,0x00000609,0x0000063e,0x0000063e,0x0000063e,0x00050083, + 0x00000022,0x0000060a,0x000005b1,0x00000609,0x00050083,0x00000006,0x0000060c,0x000000aa, + 0x0000062c,0x00060052,0x00000018,0x0000098d,0x0000062c,0x00000b81,0x00000000,0x00060052, + 0x00000018,0x0000098f,0x0000060c,0x0000098d,0x00000001,0x00060052,0x00000018,0x00000991, + 0x00000129,0x00000b81,0x00000000,0x00060052,0x00000018,0x00000993,0x00000129,0x00000991, + 0x00000001,0x0007004f,0x00000018,0x0000065d,0x0000060a,0x0000060a,0x00000000,0x00000001, + 0x00050051,0x00000006,0x00000665,0x0000065d,0x00000000,0x00050051,0x00000006,0x00000667, + 0x0000065d,0x00000001,0x0007000c,0x00000006,0x00000668,0x00000001,0x00000025,0x00000665, + 0x00000667,0x00050051,0x00000006,0x00000660,0x0000060a,0x00000002,0x0007000c,0x00000006, + 0x00000661,0x00000001,0x00000025,0x00000668,0x00000660,0x0004007f,0x00000006,0x00000612, + 0x00000661,0x0007000c,0x00000006,0x00000678,0x00000001,0x00000028,0x00000665,0x00000667, + 0x0007000c,0x00000006,0x00000671,0x00000001,0x00000028,0x00000678,0x00000660,0x00060052, + 0x00000018,0x0000099b,0x00000612,0x00000b81,0x00000000,0x00060052,0x00000018,0x0000099d, + 0x00000671,0x0000099b,0x00000001,0x0007000c,0x00000018,0x00000616,0x00000001,0x00000028, + 0x00000993,0x0000099d,0x00050088,0x00000018,0x00000617,0x0000098f,0x00000616,0x00050051, + 0x00000006,0x0000061a,0x00000617,0x00000000,0x00050051,0x00000006,0x0000061c,0x00000617, + 0x00000001,0x0007000c,0x00000006,0x0000061d,0x00000001,0x00000025,0x0000061a,0x0000061c, + 0x0007000c,0x00000006,0x0000061e,0x00000001,0x00000025,0x000000aa,0x0000061d,0x0005008e, + 0x00000022,0x00000621,0x0000060a,0x0000061e,0x00060050,0x00000022,0x00000623,0x0000062c, + 0x0000062c,0x0000062c,0x00050081,0x00000022,0x00000624,0x00000621,0x00000623,0x0003003e, + 0x000003d4,0x00000624,0x000200f9,0x000004d6,0x000200f8,0x000004d6,0x000200f9,0x000004f6, + 0x000200f8,0x000004d7,0x000300f7,0x000004e1,0x00000000,0x000400fa,0x0000026b,0x000004d8, + 0x000004e1,0x000200f8,0x000004d8,0x0004003d,0x00000022,0x000004d9,0x000003c2,0x00060052, + 0x00000022,0x000009a1,0x000000a4,0x00000a61,0x00000000,0x00060052,0x00000022,0x000009a3, + 0x000000a4,0x000009a1,0x00000001,0x00060052,0x00000022,0x000009a5,0x000000a4,0x000009a3, + 0x00000002,0x00060052,0x00000022,0x000009a7,0x000000aa,0x00000a61,0x00000000,0x00060052, + 0x00000022,0x000009a9,0x000000aa,0x000009a7,0x00000001,0x00060052,0x00000022,0x000009ab, + 0x000000aa,0x000009a9,0x00000002,0x0008000c,0x00000022,0x000004dc,0x00000001,0x0000002b, + 0x000004d9,0x000009a5,0x000009ab,0x0003003e,0x000003c2,0x000004dc,0x0007004f,0x00000018, + 0x000006bc,0x000004dc,0x000004dc,0x00000000,0x00000001,0x00050051,0x00000006,0x000006c4, + 0x000006bc,0x00000000,0x00050051,0x00000006,0x000006c6,0x000006bc,0x00000001,0x0007000c, + 0x00000006,0x000006c7,0x00000001,0x00000028,0x000006c4,0x000006c6,0x00050051,0x00000006, + 0x000006bf,0x000004dc,0x00000002,0x0007000c,0x00000006,0x000006c0,0x00000001,0x00000028, + 0x000006c7,0x000006bf,0x0007000c,0x00000006,0x000006d7,0x00000001,0x00000025,0x000006c4, + 0x000006c6,0x0007000c,0x00000006,0x000006d0,0x00000001,0x00000025,0x000006d7,0x000006bf, + 0x00050083,0x00000006,0x000006a7,0x000006c0,0x000006d0,0x0007004f,0x00000018,0x000006dc, + 0x00000507,0x00000507,0x00000000,0x00000001,0x00050051,0x00000006,0x000006e4,0x000006dc, + 0x00000000,0x00050051,0x00000006,0x000006e6,0x000006dc,0x00000001,0x0007000c,0x00000006, + 0x000006e7,0x00000001,0x00000025,0x000006e4,0x000006e6,0x00050051,0x00000006,0x000006df, + 0x00000507,0x00000002,0x0007000c,0x00000006,0x000006e0,0x00000001,0x00000025,0x000006e7, + 0x000006df,0x00060050,0x00000022,0x000006ab,0x000006e0,0x000006e0,0x000006e0,0x00050083, + 0x00000022,0x000006ac,0x00000507,0x000006ab,0x0007004f,0x00000018,0x000006ec,0x000006ac, + 0x000006ac,0x00000000,0x00000001,0x00050051,0x00000006,0x000006f4,0x000006ec,0x00000000, + 0x00050051,0x00000006,0x000006f6,0x000006ec,0x00000001,0x0007000c,0x00000006,0x000006f7, + 0x00000001,0x00000028,0x000006f4,0x000006f6,0x00050051,0x00000006,0x000006ef,0x000006ac, + 0x00000002,0x0007000c,0x00000006,0x000006f0,0x00000001,0x00000028,0x000006f7,0x000006ef, + 0x0007000c,0x00000006,0x000006b1,0x00000001,0x00000028,0x00000129,0x000006f0,0x00050088, + 0x00000006,0x000006b2,0x000006a7,0x000006b1,0x0005008e,0x00000022,0x000006b5,0x000006ac, + 0x000006b2,0x00060052,0x00000022,0x000009b9,0x0000010d,0x00000a61,0x00000000,0x00060052, + 0x00000022,0x000009bb,0x0000010e,0x000009b9,0x00000001,0x00060052,0x00000022,0x000009bd, + 0x0000010f,0x000009bb,0x00000002,0x00050094,0x00000006,0x00000730,0x00000507,0x000009bd, + 0x00050094,0x00000006,0x00000742,0x000006b5,0x000009bd,0x00060050,0x00000022,0x0000070d, + 0x00000742,0x00000742,0x00000742,0x00050083,0x00000022,0x0000070e,0x000006b5,0x0000070d, + 0x00050083,0x00000006,0x00000710,0x000000aa,0x00000730,0x00060052,0x00000018,0x000009c5, + 0x00000730,0x00000b81,0x00000000,0x00060052,0x00000018,0x000009c7,0x00000710,0x000009c5, + 0x00000001,0x00060052,0x00000018,0x000009c9,0x00000129,0x00000b81,0x00000000,0x00060052, + 0x00000018,0x000009cb,0x00000129,0x000009c9,0x00000001,0x0007004f,0x00000018,0x00000761, + 0x0000070e,0x0000070e,0x00000000,0x00000001,0x00050051,0x00000006,0x00000769,0x00000761, + 0x00000000,0x00050051,0x00000006,0x0000076b,0x00000761,0x00000001,0x0007000c,0x00000006, + 0x0000076c,0x00000001,0x00000025,0x00000769,0x0000076b,0x00050051,0x00000006,0x00000764, + 0x0000070e,0x00000002,0x0007000c,0x00000006,0x00000765,0x00000001,0x00000025,0x0000076c, + 0x00000764,0x0004007f,0x00000006,0x00000716,0x00000765,0x0007000c,0x00000006,0x0000077c, + 0x00000001,0x00000028,0x00000769,0x0000076b,0x0007000c,0x00000006,0x00000775,0x00000001, + 0x00000028,0x0000077c,0x00000764,0x00060052,0x00000018,0x000009d3,0x00000716,0x00000b81, + 0x00000000,0x00060052,0x00000018,0x000009d5,0x00000775,0x000009d3,0x00000001,0x0007000c, + 0x00000018,0x0000071a,0x00000001,0x00000028,0x000009cb,0x000009d5,0x00050088,0x00000018, + 0x0000071b,0x000009c7,0x0000071a,0x00050051,0x00000006,0x0000071e,0x0000071b,0x00000000, + 0x00050051,0x00000006,0x00000720,0x0000071b,0x00000001,0x0007000c,0x00000006,0x00000721, + 0x00000001,0x00000025,0x0000071e,0x00000720,0x0007000c,0x00000006,0x00000722,0x00000001, + 0x00000025,0x000000aa,0x00000721,0x0005008e,0x00000022,0x00000725,0x0000070e,0x00000722, + 0x00060050,0x00000022,0x00000727,0x00000730,0x00000730,0x00000730,0x00050081,0x00000022, + 0x00000728,0x00000725,0x00000727,0x0003003e,0x000003d4,0x00000728,0x000200f9,0x000004e1, + 0x000200f8,0x000004e1,0x000200f9,0x000004f6,0x000200f8,0x000004e2,0x000300f7,0x000004eb, + 0x00000000,0x000400fa,0x0000026b,0x000004e3,0x000004eb,0x000200f8,0x000004e3,0x0004003d, + 0x00000022,0x000004e4,0x000003c2,0x00060052,0x00000022,0x000009d9,0x000000a4,0x00000a61, + 0x00000000,0x00060052,0x00000022,0x000009db,0x000000a4,0x000009d9,0x00000001,0x00060052, + 0x00000022,0x000009dd,0x000000a4,0x000009db,0x00000002,0x00060052,0x00000022,0x000009df, + 0x000000aa,0x00000a61,0x00000000,0x00060052,0x00000022,0x000009e1,0x000000aa,0x000009df, + 0x00000001,0x00060052,0x00000022,0x000009e3,0x000000aa,0x000009e1,0x00000002,0x0008000c, + 0x00000022,0x000004e7,0x00000001,0x0000002b,0x000004e4,0x000009dd,0x000009e3,0x0003003e, + 0x000003c2,0x000004e7,0x00060052,0x00000022,0x000009e5,0x0000010d,0x00000a61,0x00000000, + 0x00060052,0x00000022,0x000009e7,0x0000010e,0x000009e5,0x00000001,0x00060052,0x00000022, + 0x000009e9,0x0000010f,0x000009e7,0x00000002,0x00050094,0x00000006,0x000007d4,0x00000507, + 0x000009e9,0x00050094,0x00000006,0x000007e6,0x000004e7,0x000009e9,0x00060050,0x00000022, + 0x000007b1,0x000007e6,0x000007e6,0x000007e6,0x00050083,0x00000022,0x000007b2,0x000004e7, + 0x000007b1,0x00050083,0x00000006,0x000007b4,0x000000aa,0x000007d4,0x00060052,0x00000018, + 0x000009f1,0x000007d4,0x00000b81,0x00000000,0x00060052,0x00000018,0x000009f3,0x000007b4, + 0x000009f1,0x00000001,0x00060052,0x00000018,0x000009f5,0x00000129,0x00000b81,0x00000000, + 0x00060052,0x00000018,0x000009f7,0x00000129,0x000009f5,0x00000001,0x0007004f,0x00000018, + 0x00000805,0x000007b2,0x000007b2,0x00000000,0x00000001,0x00050051,0x00000006,0x0000080d, + 0x00000805,0x00000000,0x00050051,0x00000006,0x0000080f,0x00000805,0x00000001,0x0007000c, + 0x00000006,0x00000810,0x00000001,0x00000025,0x0000080d,0x0000080f,0x00050051,0x00000006, + 0x00000808,0x000007b2,0x00000002,0x0007000c,0x00000006,0x00000809,0x00000001,0x00000025, + 0x00000810,0x00000808,0x0004007f,0x00000006,0x000007ba,0x00000809,0x0007000c,0x00000006, + 0x00000820,0x00000001,0x00000028,0x0000080d,0x0000080f,0x0007000c,0x00000006,0x00000819, + 0x00000001,0x00000028,0x00000820,0x00000808,0x00060052,0x00000018,0x000009ff,0x000007ba, + 0x00000b81,0x00000000,0x00060052,0x00000018,0x00000a01,0x00000819,0x000009ff,0x00000001, + 0x0007000c,0x00000018,0x000007be,0x00000001,0x00000028,0x000009f7,0x00000a01,0x00050088, + 0x00000018,0x000007bf,0x000009f3,0x000007be,0x00050051,0x00000006,0x000007c2,0x000007bf, + 0x00000000,0x00050051,0x00000006,0x000007c4,0x000007bf,0x00000001,0x0007000c,0x00000006, + 0x000007c5,0x00000001,0x00000025,0x000007c2,0x000007c4,0x0007000c,0x00000006,0x000007c6, + 0x00000001,0x00000025,0x000000aa,0x000007c5,0x0005008e,0x00000022,0x000007c9,0x000007b2, + 0x000007c6,0x00060050,0x00000022,0x000007cb,0x000007d4,0x000007d4,0x000007d4,0x00050081, + 0x00000022,0x000007cc,0x000007c9,0x000007cb,0x0003003e,0x000003d4,0x000007cc,0x000200f9, + 0x000004eb,0x000200f8,0x000004eb,0x000200f9,0x000004f6,0x000200f8,0x000004ec,0x000300f7, + 0x000004f5,0x00000000,0x000400fa,0x0000026b,0x000004ed,0x000004f5,0x000200f8,0x000004ed, + 0x0004003d,0x00000022,0x000004ee,0x000003c2,0x00060052,0x00000022,0x00000a05,0x000000a4, + 0x00000a61,0x00000000,0x00060052,0x00000022,0x00000a07,0x000000a4,0x00000a05,0x00000001, + 0x00060052,0x00000022,0x00000a09,0x000000a4,0x00000a07,0x00000002,0x00060052,0x00000022, + 0x00000a0b,0x000000aa,0x00000a61,0x00000000,0x00060052,0x00000022,0x00000a0d,0x000000aa, + 0x00000a0b,0x00000001,0x00060052,0x00000022,0x00000a0f,0x000000aa,0x00000a0d,0x00000002, + 0x0008000c,0x00000022,0x000004f1,0x00000001,0x0000002b,0x000004ee,0x00000a09,0x00000a0f, + 0x0003003e,0x000003c2,0x000004f1,0x00060052,0x00000022,0x00000a11,0x0000010d,0x00000a61, + 0x00000000,0x00060052,0x00000022,0x00000a13,0x0000010e,0x00000a11,0x00000001,0x00060052, + 0x00000022,0x00000a15,0x0000010f,0x00000a13,0x00000002,0x00050094,0x00000006,0x00000878, + 0x000004f1,0x00000a15,0x00050094,0x00000006,0x0000088a,0x00000507,0x00000a15,0x00060050, + 0x00000022,0x00000855,0x0000088a,0x0000088a,0x0000088a,0x00050083,0x00000022,0x00000856, + 0x00000507,0x00000855,0x00050083,0x00000006,0x00000858,0x000000aa,0x00000878,0x00060052, + 0x00000018,0x00000a1d,0x00000878,0x00000b81,0x00000000,0x00060052,0x00000018,0x00000a1f, + 0x00000858,0x00000a1d,0x00000001,0x00060052,0x00000018,0x00000a21,0x00000129,0x00000b81, + 0x00000000,0x00060052,0x00000018,0x00000a23,0x00000129,0x00000a21,0x00000001,0x0007004f, + 0x00000018,0x000008a9,0x00000856,0x00000856,0x00000000,0x00000001,0x00050051,0x00000006, + 0x000008b1,0x000008a9,0x00000000,0x00050051,0x00000006,0x000008b3,0x000008a9,0x00000001, + 0x0007000c,0x00000006,0x000008b4,0x00000001,0x00000025,0x000008b1,0x000008b3,0x00050051, + 0x00000006,0x000008ac,0x00000856,0x00000002,0x0007000c,0x00000006,0x000008ad,0x00000001, + 0x00000025,0x000008b4,0x000008ac,0x0004007f,0x00000006,0x0000085e,0x000008ad,0x0007000c, + 0x00000006,0x000008c4,0x00000001,0x00000028,0x000008b1,0x000008b3,0x0007000c,0x00000006, + 0x000008bd,0x00000001,0x00000028,0x000008c4,0x000008ac,0x00060052,0x00000018,0x00000a2b, + 0x0000085e,0x00000b81,0x00000000,0x00060052,0x00000018,0x00000a2d,0x000008bd,0x00000a2b, + 0x00000001,0x0007000c,0x00000018,0x00000862,0x00000001,0x00000028,0x00000a23,0x00000a2d, + 0x00050088,0x00000018,0x00000863,0x00000a1f,0x00000862,0x00050051,0x00000006,0x00000866, + 0x00000863,0x00000000,0x00050051,0x00000006,0x00000868,0x00000863,0x00000001,0x0007000c, + 0x00000006,0x00000869,0x00000001,0x00000025,0x00000866,0x00000868,0x0007000c,0x00000006, + 0x0000086a,0x00000001,0x00000025,0x000000aa,0x00000869,0x0005008e,0x00000022,0x0000086d, + 0x00000856,0x0000086a,0x00060050,0x00000022,0x0000086f,0x00000878,0x00000878,0x00000878, + 0x00050081,0x00000022,0x00000870,0x0000086d,0x0000086f,0x0003003e,0x000003d4,0x00000870, + 0x000200f9,0x000004f5,0x000200f8,0x000004f5,0x000200f9,0x000004f6,0x000200f8,0x000004f6, + 0x0004003d,0x00000022,0x000004f7,0x000003d4,0x00060052,0x00000022,0x00000a32,0x000004fe, + 0x00000b82,0x00000000,0x00060052,0x00000022,0x00000a34,0x000004fe,0x00000a32,0x00000001, + 0x00060052,0x00000022,0x00000a36,0x000004fe,0x00000a34,0x00000002,0x0008000c,0x00000022, + 0x000003d1,0x00000001,0x0000002e,0x00000344,0x000004f7,0x00000a36,0x00050051,0x00000006, + 0x0000034b,0x000003d1,0x00000000,0x00060052,0x00000007,0x00000a38,0x0000034b,0x0000090b, + 0x00000000,0x00050051,0x00000006,0x0000034d,0x000003d1,0x00000001,0x00060052,0x00000007, + 0x00000a3a,0x0000034d,0x00000a38,0x00000001,0x00050051,0x00000006,0x0000034f,0x000003d1, + 0x00000002,0x00060052,0x00000007,0x00000a3c,0x0000034f,0x00000a3a,0x00000002,0x000200f9, + 0x00000341,0x000200f8,0x00000341,0x000700f5,0x00000007,0x00000b7a,0x0000090b,0x000003b9, + 0x00000a3c,0x000004f6,0x00050051,0x00000006,0x00000352,0x00000b7a,0x00000003,0x00050085, + 0x00000006,0x00000353,0x00000352,0x00000323,0x00060052,0x00000007,0x00000a3f,0x00000353, + 0x00000b7a,0x00000003,0x00050051,0x00000006,0x00000356,0x00000a3f,0x00000003,0x0008004f, + 0x00000022,0x00000358,0x00000a3f,0x00000a3f,0x00000000,0x00000001,0x00000002,0x0005008e, + 0x00000022,0x00000359,0x00000358,0x00000356,0x00050051,0x00000006,0x0000035b,0x00000359, + 0x00000000,0x00060052,0x00000007,0x00000a42,0x0000035b,0x00000a3f,0x00000000,0x00050051, + 0x00000006,0x0000035d,0x00000359,0x00000001,0x00060052,0x00000007,0x00000a44,0x0000035d, + 0x00000a42,0x00000001,0x00050051,0x00000006,0x0000035f,0x00000359,0x00000002,0x00060052, + 0x00000007,0x00000a46,0x0000035f,0x00000a44,0x00000002,0x000200f9,0x0000032d,0x000200f8, + 0x00000360,0x0005008e,0x00000007,0x00000363,0x000002dc,0x00000323,0x000200f9,0x0000032d, + 0x000200f8,0x0000032d,0x000700f5,0x00000007,0x00000b7b,0x00000a46,0x00000341,0x00000363, + 0x00000360,0x0008004f,0x00000022,0x00000368,0x00000b7b,0x00000b7b,0x00000000,0x00000001, + 0x00000002,0x00050041,0x000002d9,0x0000036d,0x000002d7,0x00000364,0x0004003d,0x00000006, + 0x0000036e,0x0000036d,0x00050041,0x000002d9,0x00000370,0x000002d7,0x00000365,0x0004003d, + 0x00000006,0x00000371,0x00000370,0x000300f7,0x000008ea,0x00000000,0x000400fa,0x000000f9, + 0x000008e0,0x000008e8,0x000200f8,0x000008e0,0x00050051,0x00000006,0x000008f1,0x000002c3, + 0x00000000,0x00050085,0x00000006,0x000008f2,0x000000e3,0x000008f1,0x00050051,0x00000006, + 0x000008f4,0x000002c3,0x00000001,0x00050085,0x00000006,0x000008f5,0x000000e7,0x000008f4, + 0x00050081,0x00000006,0x000008f6,0x000008f2,0x000008f5,0x0006000c,0x00000006,0x000008f7, + 0x00000001,0x0000000a,0x000008f6,0x00050085,0x00000006,0x000008f9,0x000000ee,0x000008f7, + 0x0006000c,0x00000006,0x000008fa,0x00000001,0x0000000a,0x000008f9,0x00050085,0x00000006, + 0x000008fd,0x000008fa,0x0000036e,0x00050081,0x00000006,0x000008ff,0x000008fd,0x00000371, + 0x00060050,0x00000022,0x000008e6,0x000008ff,0x000008ff,0x000008ff,0x00050081,0x00000022, + 0x000008e7,0x000008e6,0x00000368,0x000200f9,0x000008ea,0x000200f8,0x000008e8,0x000200f9, + 0x000008ea,0x000200f8,0x000008ea,0x000700f5,0x00000022,0x00000b7c,0x000008e7,0x000008e0, + 0x00000368,0x000008e8,0x00050051,0x00000006,0x00000374,0x00000b7c,0x00000000,0x00060052, + 0x00000007,0x00000a4a,0x00000374,0x00000b7b,0x00000000,0x00050051,0x00000006,0x00000376, + 0x00000b7c,0x00000001,0x00060052,0x00000007,0x00000a4c,0x00000376,0x00000a4a,0x00000001, + 0x00050051,0x00000006,0x00000378,0x00000b7c,0x00000002,0x00060052,0x00000007,0x00000a4e, + 0x00000378,0x00000a4c,0x00000002,0x00050051,0x00000006,0x0000037b,0x00000a4e,0x00000003, + 0x00050083,0x00000006,0x0000037c,0x000000aa,0x0000037b,0x0005008e,0x00000007,0x0000037d, + 0x0000032a,0x0000037c,0x00050081,0x00000007,0x0000037f,0x0000037d,0x00000a4e,0x0004003d, + 0x00000325,0x00000380,0x00000327,0x00040063,0x00000380,0x000002c5,0x0000037f,0x000114f5, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..0233bd507cd866580df0c9bd77378c461cbadb5d GIT binary patch literal 20584 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 W-#SY&n0>9-?a_YfKd6?&l>Q%ep)4-| literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.h new file mode 100644 index 000000000..0f19d92e8 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.h @@ -0,0 +1,156 @@ +#pragma once + +const uint32_t draw_clockwise_image_mesh_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000170,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000092,0x0000009f,0x000000a7, + 0x000000a8,0x000000ae,0x000000c1,0x000000df,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00060005,0x00000092,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00030005,0x00000096,0x0000434c,0x00040006,0x00000096,0x00000000,0x00003972,0x00040006, + 0x00000096,0x00000001,0x00003261,0x00040006,0x00000096,0x00000002,0x00003479,0x00040006, + 0x00000096,0x00000003,0x00006969,0x00040006,0x00000096,0x00000004,0x0000326b,0x00040006, + 0x00000096,0x00000005,0x00003244,0x00040006,0x00000096,0x00000006,0x00003056,0x00040006, + 0x00000096,0x00000007,0x0000326e,0x00040006,0x00000096,0x00000008,0x0000365a,0x00030005, + 0x00000098,0x00003041,0x00030005,0x0000009f,0x00004346,0x00030005,0x000000a7,0x00003055, + 0x00030005,0x000000a8,0x00004347,0x00030005,0x000000aa,0x00006747,0x00030005,0x000000ae, + 0x00003346,0x00030005,0x000000b1,0x0000424d,0x00040006,0x000000b1,0x00000000,0x00006250, + 0x00040006,0x000000b1,0x00000001,0x00006359,0x00040006,0x000000b1,0x00000002,0x00006552, + 0x00040006,0x000000b1,0x00000003,0x00006553,0x00040006,0x000000b1,0x00000004,0x0000366d, + 0x00040006,0x000000b1,0x00000005,0x0000676d,0x00040006,0x000000b1,0x00000006,0x00006544, + 0x00040006,0x000000b1,0x00000007,0x00006545,0x00040006,0x000000b1,0x00000008,0x00003755, + 0x00040006,0x000000b1,0x00000009,0x0000676a,0x00040006,0x000000b1,0x0000000a,0x0000635a, + 0x00040006,0x000000b1,0x0000000b,0x00003157,0x00040006,0x000000b1,0x0000000c,0x0000676e, + 0x00040006,0x000000b1,0x0000000d,0x00003559,0x00040006,0x000000b1,0x0000000e,0x0000324f, + 0x00040006,0x000000b1,0x0000000f,0x00006461,0x00040006,0x000000b1,0x00000010,0x00006579, + 0x00040006,0x000000b1,0x00000011,0x00003376,0x00040006,0x000000b1,0x00000012,0x00003377, + 0x00040006,0x000000b1,0x00000013,0x00006462,0x00040006,0x000000b1,0x00000014,0x00006767, + 0x00030005,0x000000b3,0x0000006b,0x00030005,0x000000bd,0x00006748,0x00030005,0x000000c1, + 0x0000304e,0x00060005,0x000000dd,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006, + 0x000000dd,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000000dd,0x00000001, + 0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x000000dd,0x00000002,0x435f6c67, + 0x4470696c,0x61747369,0x0065636e,0x00070006,0x000000dd,0x00000003,0x435f6c67,0x446c6c75, + 0x61747369,0x0065636e,0x00030005,0x000000df,0x00000000,0x00040047,0x00000092,0x0000000b, + 0x0000002a,0x00030047,0x00000096,0x00000002,0x00050048,0x00000096,0x00000000,0x00000023, + 0x00000000,0x00050048,0x00000096,0x00000001,0x00000023,0x00000010,0x00050048,0x00000096, + 0x00000002,0x00000023,0x00000018,0x00050048,0x00000096,0x00000003,0x00000023,0x0000001c, + 0x00050048,0x00000096,0x00000004,0x00000023,0x00000020,0x00050048,0x00000096,0x00000005, + 0x00000023,0x00000030,0x00050048,0x00000096,0x00000006,0x00000023,0x00000038,0x00050048, + 0x00000096,0x00000007,0x00000023,0x0000003c,0x00050048,0x00000096,0x00000008,0x00000023, + 0x00000040,0x00040047,0x00000098,0x00000021,0x00000002,0x00040047,0x00000098,0x00000022, + 0x00000000,0x00040047,0x0000009f,0x0000001e,0x00000000,0x00040047,0x000000a7,0x0000001e, + 0x00000000,0x00040047,0x000000a8,0x0000001e,0x00000001,0x00040047,0x000000aa,0x00000001, + 0x00000000,0x00030047,0x000000ae,0x00000000,0x00030047,0x000000ae,0x0000000e,0x00040047, + 0x000000ae,0x0000001e,0x00000001,0x00030047,0x000000b1,0x00000002,0x00050048,0x000000b1, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000000b1,0x00000001,0x00000023,0x00000004, + 0x00050048,0x000000b1,0x00000002,0x00000023,0x00000008,0x00050048,0x000000b1,0x00000003, + 0x00000023,0x0000000c,0x00050048,0x000000b1,0x00000004,0x00000023,0x00000010,0x00050048, + 0x000000b1,0x00000005,0x00000023,0x00000014,0x00050048,0x000000b1,0x00000006,0x00000023, + 0x00000018,0x00050048,0x000000b1,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000b1, + 0x00000008,0x00000023,0x00000020,0x00050048,0x000000b1,0x00000009,0x00000023,0x00000030, + 0x00050048,0x000000b1,0x0000000a,0x00000023,0x00000038,0x00050048,0x000000b1,0x0000000b, + 0x00000023,0x00000040,0x00050048,0x000000b1,0x0000000c,0x00000023,0x00000044,0x00050048, + 0x000000b1,0x0000000d,0x00000023,0x00000048,0x00050048,0x000000b1,0x0000000e,0x00000023, + 0x0000004c,0x00050048,0x000000b1,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000b1, + 0x00000010,0x00000023,0x00000054,0x00050048,0x000000b1,0x00000011,0x00000023,0x00000058, + 0x00050048,0x000000b1,0x00000012,0x00000023,0x0000005c,0x00050048,0x000000b1,0x00000013, + 0x00000023,0x00000060,0x00050048,0x000000b1,0x00000014,0x00000023,0x00000064,0x00040047, + 0x000000b3,0x00000021,0x00000000,0x00040047,0x000000b3,0x00000022,0x00000000,0x00040047, + 0x000000bd,0x00000001,0x00000001,0x00040047,0x000000c1,0x0000001e,0x00000002,0x00030047, + 0x000000dd,0x00000002,0x00050048,0x000000dd,0x00000000,0x0000000b,0x00000000,0x00050048, + 0x000000dd,0x00000001,0x0000000b,0x00000001,0x00050048,0x000000dd,0x00000002,0x0000000b, + 0x00000003,0x00050048,0x000000dd,0x00000003,0x0000000b,0x00000004,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040017,0x00000009,0x00000006,0x00000002,0x00040018,0x0000000a, + 0x00000009,0x00000002,0x00040015,0x0000000f,0x00000020,0x00000000,0x0004002b,0x00000006, + 0x00000029,0x3f800000,0x0004002b,0x00000006,0x0000002a,0x00000000,0x0004002b,0x0000000f, + 0x00000035,0x00000000,0x00020014,0x00000036,0x0004002b,0x0000000f,0x0000003d,0x000003ff, + 0x0004002b,0x0000000f,0x0000004d,0x00000001,0x00040015,0x00000059,0x00000020,0x00000001, + 0x0004002b,0x00000059,0x0000005a,0x00000000,0x0004002b,0x00000059,0x0000005e,0x00000001, + 0x0004002b,0x00000006,0x00000086,0x3f000000,0x00040020,0x00000091,0x00000001,0x00000059, + 0x0004003b,0x00000091,0x00000092,0x00000001,0x000b001e,0x00000096,0x00000007,0x00000009, + 0x00000006,0x00000006,0x00000007,0x00000009,0x0000000f,0x0000000f,0x0000000f,0x00040020, + 0x00000097,0x00000002,0x00000096,0x0004003b,0x00000097,0x00000098,0x00000002,0x00040020, + 0x0000009a,0x00000002,0x00000007,0x00040020,0x0000009e,0x00000001,0x00000009,0x0004003b, + 0x0000009e,0x0000009f,0x00000001,0x00040020,0x000000a2,0x00000002,0x00000009,0x00040020, + 0x000000a6,0x00000003,0x00000009,0x0004003b,0x000000a6,0x000000a7,0x00000003,0x0004003b, + 0x0000009e,0x000000a8,0x00000001,0x00030030,0x00000036,0x000000aa,0x00040020,0x000000ad, + 0x00000003,0x00000006,0x0004003b,0x000000ad,0x000000ae,0x00000003,0x0004002b,0x00000059, + 0x000000af,0x00000006,0x00040017,0x000000b0,0x00000059,0x00000004,0x0017001e,0x000000b1, + 0x00000006,0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f,0x0000000f,0x0000000f, + 0x000000b0,0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f,0x00000006,0x00000006, + 0x0000000f,0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020,0x000000b2,0x00000002, + 0x000000b1,0x0004003b,0x000000b2,0x000000b3,0x00000002,0x0004002b,0x00000059,0x000000b4, + 0x0000000d,0x00040020,0x000000b6,0x00000002,0x0000000f,0x00030030,0x00000036,0x000000bd, + 0x00040020,0x000000c0,0x00000003,0x00000007,0x0004003b,0x000000c0,0x000000c1,0x00000003, + 0x0004002b,0x00000059,0x000000c2,0x00000004,0x0004002b,0x00000059,0x000000c7,0x00000005, + 0x0004002b,0x00000059,0x000000d0,0x00000002,0x0004002b,0x00000059,0x000000d1,0x00000003, + 0x00040020,0x000000d5,0x00000002,0x00000006,0x0004001c,0x000000dc,0x00000006,0x0000004d, + 0x0006001e,0x000000dd,0x00000007,0x00000006,0x000000dc,0x000000dc,0x00040020,0x000000de, + 0x00000003,0x000000dd,0x0004003b,0x000000de,0x000000df,0x00000003,0x0005002c,0x00000009, + 0x0000016e,0x00000029,0x00000029,0x0007002c,0x00000007,0x0000016f,0x00000086,0x00000086, + 0x00000086,0x00000086,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x00050041,0x0000009a,0x0000009b,0x00000098,0x0000005a,0x0004003d,0x00000007, + 0x0000009c,0x0000009b,0x00050051,0x00000006,0x000000fa,0x0000009c,0x00000000,0x00050051, + 0x00000006,0x000000fb,0x0000009c,0x00000001,0x00050051,0x00000006,0x000000fc,0x0000009c, + 0x00000002,0x00050051,0x00000006,0x000000fd,0x0000009c,0x00000003,0x00050050,0x00000009, + 0x000000fe,0x000000fa,0x000000fb,0x00050050,0x00000009,0x000000ff,0x000000fc,0x000000fd, + 0x00050050,0x0000000a,0x00000100,0x000000fe,0x000000ff,0x0004003d,0x00000009,0x000000a0, + 0x0000009f,0x00050091,0x00000009,0x000000a1,0x00000100,0x000000a0,0x00050041,0x000000a2, + 0x000000a3,0x00000098,0x0000005e,0x0004003d,0x00000009,0x000000a4,0x000000a3,0x00050081, + 0x00000009,0x000000a5,0x000000a1,0x000000a4,0x0004003d,0x00000009,0x000000a9,0x000000a8, + 0x0003003e,0x000000a7,0x000000a9,0x000300f7,0x000000ac,0x00000000,0x000400fa,0x000000aa, + 0x000000ab,0x000000ac,0x000200f8,0x000000ab,0x00050041,0x000000b6,0x000000b7,0x00000098, + 0x000000af,0x0004003d,0x0000000f,0x000000b8,0x000000b7,0x00050041,0x000000b6,0x000000ba, + 0x000000b3,0x000000b4,0x0004003d,0x0000000f,0x000000bb,0x000000ba,0x000500aa,0x00000036, + 0x00000106,0x000000b8,0x00000035,0x000300f7,0x0000010f,0x00000000,0x000400fa,0x00000106, + 0x00000107,0x00000108,0x000200f8,0x00000108,0x00050080,0x0000000f,0x0000010a,0x000000b8, + 0x0000003d,0x00050084,0x0000000f,0x0000010c,0x0000010a,0x000000bb,0x0006000c,0x00000009, + 0x0000010d,0x00000001,0x0000003e,0x0000010c,0x00050051,0x00000006,0x0000010e,0x0000010d, + 0x00000000,0x000200f9,0x0000010f,0x000200f8,0x00000107,0x000200f9,0x0000010f,0x000200f8, + 0x0000010f,0x000700f5,0x00000006,0x0000016b,0x0000002a,0x00000107,0x0000010e,0x00000108, + 0x0003003e,0x000000ae,0x0000016b,0x000200f9,0x000000ac,0x000200f8,0x000000ac,0x000300f7, + 0x000000bf,0x00000000,0x000400fa,0x000000bd,0x000000be,0x000000bf,0x000200f8,0x000000be, + 0x00050041,0x0000009a,0x000000c4,0x00000098,0x000000c2,0x0004003d,0x00000007,0x000000c5, + 0x000000c4,0x00050051,0x00000006,0x00000118,0x000000c5,0x00000000,0x00050051,0x00000006, + 0x00000119,0x000000c5,0x00000001,0x00050051,0x00000006,0x0000011a,0x000000c5,0x00000002, + 0x00050051,0x00000006,0x0000011b,0x000000c5,0x00000003,0x00050050,0x00000009,0x0000011c, + 0x00000118,0x00000119,0x00050050,0x00000009,0x0000011d,0x0000011a,0x0000011b,0x00050050, + 0x0000000a,0x0000011e,0x0000011c,0x0000011d,0x00050041,0x000000a2,0x000000ca,0x00000098, + 0x000000c7,0x0004003d,0x00000009,0x000000cb,0x000000ca,0x000300f7,0x00000154,0x00000000, + 0x000300fb,0x00000035,0x00000126,0x000200f8,0x00000126,0x0006000c,0x00000009,0x00000129, + 0x00000001,0x00000004,0x0000011c,0x0006000c,0x00000009,0x0000012c,0x00000001,0x00000004, + 0x0000011d,0x00050081,0x00000009,0x0000012d,0x00000129,0x0000012c,0x00050051,0x00000006, + 0x0000012f,0x0000012d,0x00000000,0x000500b7,0x00000036,0x00000130,0x0000012f,0x0000002a, + 0x000300f7,0x00000135,0x00000000,0x000400fa,0x00000130,0x00000131,0x00000135,0x000200f8, + 0x00000131,0x00050051,0x00000006,0x00000133,0x0000012d,0x00000001,0x000500b7,0x00000036, + 0x00000134,0x00000133,0x0000002a,0x000200f9,0x00000135,0x000200f8,0x00000135,0x000700f5, + 0x00000036,0x00000136,0x00000130,0x00000126,0x00000134,0x00000131,0x000300f7,0x00000153, + 0x00000000,0x000400fa,0x00000136,0x00000137,0x00000150,0x000200f8,0x00000150,0x0009004f, + 0x00000007,0x00000152,0x000000cb,0x000000cb,0x00000000,0x00000001,0x00000000,0x00000001, + 0x000200f9,0x00000154,0x000200f8,0x00000137,0x00050088,0x00000009,0x0000013a,0x0000016e, + 0x0000012d,0x00050091,0x00000009,0x0000013d,0x0000011e,0x000000a5,0x00050081,0x00000009, + 0x0000013f,0x0000013d,0x000000cb,0x0004007f,0x00000009,0x00000142,0x0000013f,0x00050051, + 0x00000006,0x00000143,0x0000013f,0x00000000,0x00050051,0x00000006,0x00000144,0x0000013f, + 0x00000001,0x00050051,0x00000006,0x00000145,0x00000142,0x00000000,0x00050051,0x00000006, + 0x00000146,0x00000142,0x00000001,0x00070050,0x00000007,0x00000147,0x00000143,0x00000144, + 0x00000145,0x00000146,0x0009004f,0x00000007,0x00000149,0x0000013a,0x0000013a,0x00000000, + 0x00000001,0x00000000,0x00000001,0x00050085,0x00000007,0x0000014a,0x00000147,0x00000149, + 0x00050081,0x00000007,0x0000014d,0x0000014a,0x00000149,0x00050081,0x00000007,0x0000014f, + 0x0000014d,0x0000016f,0x000200f9,0x00000154,0x000200f8,0x00000153,0x000100ff,0x000200f8, + 0x00000154,0x000700f5,0x00000007,0x0000016c,0x0000014f,0x00000137,0x00000152,0x00000150, + 0x0003003e,0x000000c1,0x0000016c,0x000200f9,0x000000bf,0x000200f8,0x000000bf,0x00050041, + 0x000000d5,0x000000d6,0x000000b3,0x000000d0,0x0004003d,0x00000006,0x000000d7,0x000000d6, + 0x00050041,0x000000d5,0x000000d9,0x000000b3,0x000000d1,0x0004003d,0x00000006,0x000000da, + 0x000000d9,0x00050051,0x00000006,0x00000159,0x000000a5,0x00000000,0x00050085,0x00000006, + 0x0000015b,0x00000159,0x000000d7,0x00050083,0x00000006,0x0000015c,0x0000015b,0x00000029, + 0x00050051,0x00000006,0x0000015e,0x000000a5,0x00000001,0x00050085,0x00000006,0x00000160, + 0x0000015e,0x000000da,0x0006000c,0x00000006,0x00000162,0x00000001,0x00000006,0x000000da, + 0x00050083,0x00000006,0x00000163,0x00000160,0x00000162,0x00070050,0x00000007,0x00000164, + 0x0000015c,0x00000163,0x0000002a,0x00000029,0x00050041,0x000000c0,0x000000e1,0x000000df, + 0x0000005a,0x0003003e,0x000000e1,0x00000164,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_image_mesh.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..282707f4dbd0c9885abb9d7043d0287000c930e1 GIT binary patch literal 4856 zcmZ9N>yMSy6^CCKhCx6mUTI4wLrI#@T8rhPRS|)K!Di@80WBcmFqZ=!IGmZxnW5m9 zYP_Uh@k49WwA5Z`>BU=9jg3}}hNSvIKUkyDn*I@{Er|F$@7e2|9X71l>-XDht-aS; zd%ve^_KKdOm{lw&<`t8(igGL|X2TS4bIW;PaOdES&FS$Q*Q{No!J?w8w9{sBv9Q$V z@b~CQts!^}`6Y51`91O%oWH!@zGsx+r3rbZ4` zE2A?94+1Af4_C*gv0I?smfgE5&5@&%_3Bi;+H6*)tH-BjrmB^LGmWw7+C-yC*oZkW zG&C@{r7|`-Nz4=VYNcLlR4e1PDdN?RRkfRE%w$(pAVoR?ewzZ|+XKJsL>-8TCUg8~e6(bxVH^efy@? zp6ZU_(GE7pJ!2hgjytHcXVl&tcV@V(EoY2%b3Dqvfz7c$vp2^r88*keZ|>M%0Y04h z&j;_#&a(jgqnkSR-r7cHeO*Cu11K6I@ z-ky|vtuei`c0Z@pr?qB(Sle8$P4?HC(<6kSxl8(H`s94lH=oAW$!)-LSykz1N^?k~42v zgZ1&=IXtH$IOED$li>7`Gq2#f66akHF6tOPaF3{?cQWjvj?owGqK?rQxu|1b=IdMZ zEYTP3e2;R`7dh{b+?`15>sjUcGtRduw=LtWpWI-^`9|f2GtNBac4gd>#O=;F->Y`} zGR`+EcOc`ek=!_9|9rdN8%N;$-uRyFm*V-?1zX=f#PKb#wku2Yz=ptn z4;*6c`J|TP8lv#IZ}aQXFLAK2+YUBA_u0eTm$2*Ny@(_5est}{p5sx3v7rxq62&$B zZcEtjm0T|s^7~}&k+1%NJ#&b$ehxN&eT*gcTOsHA6G_)!{0nCHF}C(%za4U}Kh3PK z>*C)r+n=x(pH5u(`)$#G6_(b}Z;QTvX4cp9Yb*A9A{TXf2Hkc0`z*6HvERKgzCqV= ziQHq>$FnJN+Qxjj9@w)zkDYnChi4P}R^;Mre?|9gYyY>jX6(q*x8vGt%;sc`jU_&d z-I_IKwcg0elItnsOu#(~&Sf3;p3fW{#`qtMIc(&w_v}f;yXRY2kELgN3X%UI zHlFW%;+Wdpg~YLKoBJ$r?is!p6X)K;#Pj^0BgQmFaF@{a*Iv%=L_u(EUGr@Eo8LsIUwQ@F}e=s}D=N0Bx5jpo#w^mOuzkyiK*AZ*w-Fy>~k25c2 z4>?D0UrroToBK-Q^1J!f#N~H$8JsbV5qI-z==y6Pce58=Th~0V_wJvF=RJqSoq8+r z=DiDB#|3nI`wg%;J4bI;qH8t>F@EqjWW0Mm$e#A{+vxhZ9{GOTnw$29Op7&(p)}z}i-+R<-16bbJKj9qKaT8cR z^4^>gW5nBZ_OAQe_AkWmn7@JE zb-xAgBl2PM0lGH+E{4sA=<-pkJ?v+19Oi1Ad*S4b_fX>Yf#p}ih3|f_zD#Z30|0sV w@$DFI6s(Q9e8e1s)ZX>z(>S_&x#s)6iM78-^jnZG0Jp)+I{*Lx literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.h new file mode 100644 index 000000000..5885f7e6a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.h @@ -0,0 +1,308 @@ +#pragma once + +const uint32_t draw_clockwise_interior_triangles_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000003c8,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x000d000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x0000016c,0x00000173,0x0000017a,0x00000184,0x00000194,0x000001bc,0x0000021a, + 0x00000224,0x00030010,0x00000004,0x00000007,0x00030010,0x00000004,0x000014f6,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x665f4252,0x6d676172,0x5f746e65,0x64616873, + 0x695f7265,0x7265746e,0x6b636f6c,0x00000000,0x00090004,0x415f4c47,0x735f4252,0x65646168, + 0x6d695f72,0x5f656761,0x64616f6c,0x6f74735f,0x00006572,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x00000087,0x00006752,0x00030005,0x000000bb,0x0000674e,0x00030005,0x000000df, + 0x00006749,0x00030005,0x0000011f,0x00004444,0x00030005,0x00000123,0x00006277,0x00030005, + 0x00000145,0x00004344,0x00030005,0x00000147,0x00003552,0x00060005,0x0000016c,0x465f6c67, + 0x43676172,0x64726f6f,0x00000000,0x00030005,0x00000173,0x0000316c,0x00030005,0x00000175, + 0x00006750,0x00030005,0x0000017a,0x0000316b,0x00030005,0x00000180,0x00006748,0x00030005, + 0x00000184,0x0000304e,0x00030005,0x00000191,0x00003053,0x00030005,0x00000194,0x0000307a, + 0x00030005,0x000001b8,0x00006747,0x00030005,0x000001bc,0x00003153,0x00030005,0x000001c4, + 0x00003065,0x00030005,0x000001f2,0x0000424d,0x00040006,0x000001f2,0x00000000,0x00006250, + 0x00040006,0x000001f2,0x00000001,0x00006359,0x00040006,0x000001f2,0x00000002,0x00006552, + 0x00040006,0x000001f2,0x00000003,0x00006553,0x00040006,0x000001f2,0x00000004,0x0000366d, + 0x00040006,0x000001f2,0x00000005,0x0000676d,0x00040006,0x000001f2,0x00000006,0x00006544, + 0x00040006,0x000001f2,0x00000007,0x00006545,0x00040006,0x000001f2,0x00000008,0x00003755, + 0x00040006,0x000001f2,0x00000009,0x0000676a,0x00040006,0x000001f2,0x0000000a,0x0000635a, + 0x00040006,0x000001f2,0x0000000b,0x00003157,0x00040006,0x000001f2,0x0000000c,0x0000676e, + 0x00040006,0x000001f2,0x0000000d,0x00003559,0x00040006,0x000001f2,0x0000000e,0x0000324f, + 0x00040006,0x000001f2,0x0000000f,0x00006461,0x00040006,0x000001f2,0x00000010,0x00006579, + 0x00040006,0x000001f2,0x00000011,0x00003376,0x00040006,0x000001f2,0x00000012,0x00003377, + 0x00040006,0x000001f2,0x00000013,0x00006462,0x00040006,0x000001f2,0x00000014,0x00006767, + 0x00030005,0x000001f4,0x0000006b,0x00030005,0x0000021a,0x0000316d,0x00030005,0x00000222, + 0x00003954,0x00030005,0x00000223,0x00004351,0x00030005,0x00000224,0x00003159,0x00040047, + 0x00000087,0x00000001,0x0000000b,0x00040047,0x000000bb,0x00000001,0x00000007,0x00040047, + 0x000000df,0x00000001,0x00000002,0x00030047,0x0000011f,0x00000000,0x00040047,0x0000011f, + 0x00000021,0x00000009,0x00040047,0x0000011f,0x00000022,0x00000000,0x00030047,0x00000123, + 0x00000000,0x00040047,0x00000123,0x00000021,0x00000009,0x00040047,0x00000123,0x00000022, + 0x00000000,0x00030047,0x00000145,0x00000000,0x00040047,0x00000145,0x00000021,0x0000000c, + 0x00040047,0x00000145,0x00000022,0x00000001,0x00030047,0x00000147,0x00000000,0x00040047, + 0x00000147,0x00000021,0x0000000c,0x00040047,0x00000147,0x00000022,0x00000001,0x00040047, + 0x0000016c,0x0000000b,0x0000000f,0x00030047,0x00000173,0x00000000,0x00030047,0x00000173, + 0x0000000e,0x00040047,0x00000173,0x0000001e,0x00000001,0x00030047,0x00000174,0x00000000, + 0x00040047,0x00000175,0x00000001,0x00000009,0x00040047,0x0000017a,0x0000001e,0x00000000, + 0x00040047,0x00000180,0x00000001,0x00000001,0x00040047,0x00000184,0x0000001e,0x00000005, + 0x00030047,0x0000018c,0x00000000,0x00030047,0x00000191,0x00000017,0x00040047,0x00000191, + 0x00000021,0x00000003,0x00040047,0x00000191,0x00000022,0x00000002,0x00030047,0x00000194, + 0x00000000,0x00030047,0x00000194,0x0000000e,0x00040047,0x00000194,0x0000001e,0x00000003, + 0x00030047,0x00000198,0x00000000,0x00030047,0x0000019a,0x00000000,0x00030047,0x000001a6, + 0x00000000,0x00030047,0x000001a9,0x00000000,0x00030047,0x000001af,0x00000000,0x00030047, + 0x000001b7,0x00000000,0x00040047,0x000001b8,0x00000001,0x00000000,0x00030047,0x000001bc, + 0x00000000,0x00030047,0x000001bc,0x0000000e,0x00040047,0x000001bc,0x0000001e,0x00000004, + 0x00030047,0x000001be,0x00000000,0x00030047,0x000001c4,0x00000017,0x00040047,0x000001c4, + 0x00000021,0x00000001,0x00040047,0x000001c4,0x00000022,0x00000002,0x00030047,0x000001cc, + 0x00000000,0x00030047,0x000001d0,0x00000000,0x00030047,0x000001d6,0x00000000,0x00030047, + 0x000001dd,0x00000000,0x00030047,0x000001df,0x00000000,0x00030047,0x000001f2,0x00000002, + 0x00050048,0x000001f2,0x00000000,0x00000023,0x00000000,0x00050048,0x000001f2,0x00000001, + 0x00000023,0x00000004,0x00050048,0x000001f2,0x00000002,0x00000023,0x00000008,0x00050048, + 0x000001f2,0x00000003,0x00000023,0x0000000c,0x00050048,0x000001f2,0x00000004,0x00000023, + 0x00000010,0x00050048,0x000001f2,0x00000005,0x00000023,0x00000014,0x00050048,0x000001f2, + 0x00000006,0x00000023,0x00000018,0x00050048,0x000001f2,0x00000007,0x00000023,0x0000001c, + 0x00050048,0x000001f2,0x00000008,0x00000023,0x00000020,0x00050048,0x000001f2,0x00000009, + 0x00000023,0x00000030,0x00050048,0x000001f2,0x0000000a,0x00000023,0x00000038,0x00050048, + 0x000001f2,0x0000000b,0x00000023,0x00000040,0x00050048,0x000001f2,0x0000000c,0x00000023, + 0x00000044,0x00050048,0x000001f2,0x0000000d,0x00000023,0x00000048,0x00050048,0x000001f2, + 0x0000000e,0x00000023,0x0000004c,0x00050048,0x000001f2,0x0000000f,0x00000023,0x00000050, + 0x00050048,0x000001f2,0x00000010,0x00000023,0x00000054,0x00050048,0x000001f2,0x00000011, + 0x00000023,0x00000058,0x00050048,0x000001f2,0x00000012,0x00000023,0x0000005c,0x00050048, + 0x000001f2,0x00000013,0x00000023,0x00000060,0x00050048,0x000001f2,0x00000014,0x00000023, + 0x00000064,0x00040047,0x000001f4,0x00000021,0x00000000,0x00040047,0x000001f4,0x00000022, + 0x00000000,0x00030047,0x00000208,0x00000000,0x00030047,0x0000020b,0x00000000,0x00030047, + 0x00000210,0x00000000,0x00030047,0x00000211,0x00000000,0x00030047,0x00000212,0x00000000, + 0x00030047,0x0000021a,0x00000000,0x00040047,0x0000021a,0x0000001e,0x00000000,0x00030047, + 0x00000222,0x00000000,0x00040047,0x00000222,0x00000021,0x0000000a,0x00040047,0x00000222, + 0x00000022,0x00000000,0x00030047,0x00000223,0x00000000,0x00040047,0x00000223,0x00000021, + 0x0000000a,0x00040047,0x00000223,0x00000022,0x00000000,0x00030047,0x00000224,0x00000000, + 0x00030047,0x00000224,0x0000000e,0x00040047,0x00000224,0x0000001e,0x00000006,0x00030047, + 0x00000249,0x00000000,0x00030047,0x00000273,0x00000000,0x00030047,0x00000274,0x00000000, + 0x00030047,0x00000279,0x00000000,0x00030047,0x0000027c,0x00000000,0x00030047,0x00000281, + 0x00000000,0x00030047,0x00000283,0x00000000,0x00030047,0x00000284,0x00000000,0x00030047, + 0x00000291,0x00000000,0x00030047,0x00000292,0x00000000,0x00030047,0x00000297,0x00000000, + 0x00030047,0x0000029f,0x00000000,0x00030047,0x000002a6,0x00000000,0x00030047,0x000002b5, + 0x00000000,0x00030047,0x000002b7,0x00000000,0x00030047,0x000002bc,0x00000000,0x00030047, + 0x000002c0,0x00000000,0x00030047,0x000002d8,0x00000000,0x00030047,0x000002da,0x00000000, + 0x00030047,0x000002db,0x00000000,0x00030047,0x000002dd,0x00000000,0x00030047,0x000002df, + 0x00000000,0x00030047,0x000002e0,0x00000000,0x00030047,0x00000309,0x00000000,0x00030047, + 0x00000325,0x00000000,0x00030047,0x00000343,0x00000000,0x00030047,0x00000344,0x00000000, + 0x00030047,0x00000347,0x00000000,0x00030047,0x00000349,0x00000000,0x00030047,0x0000034e, + 0x00000000,0x00030047,0x00000351,0x00000000,0x00030047,0x00000352,0x00000000,0x00030047, + 0x00000353,0x00000000,0x00030047,0x00000354,0x00000000,0x00030047,0x00000358,0x00000000, + 0x00030047,0x00000360,0x00000000,0x00030047,0x00000363,0x00000000,0x00030047,0x00000365, + 0x00000000,0x00030047,0x00000367,0x00000000,0x00030047,0x0000036e,0x00000000,0x00030047, + 0x00000370,0x00000000,0x00030047,0x00000372,0x00000000,0x00030047,0x00000374,0x00000000, + 0x00030047,0x00000378,0x00000000,0x00030047,0x0000037a,0x00000000,0x00030047,0x00000383, + 0x00000000,0x00030047,0x00000385,0x00000000,0x00030047,0x00000387,0x00000000,0x00030047, + 0x00000388,0x00000000,0x00030047,0x0000038f,0x00000000,0x00030047,0x00000391,0x00000000, + 0x00030047,0x00000392,0x00000000,0x00030047,0x00000390,0x00000000,0x00030047,0x0000038e, + 0x00000000,0x00030047,0x00000393,0x00000000,0x00030047,0x00000394,0x00000000,0x00030047, + 0x0000039a,0x00000000,0x00030047,0x00000398,0x00000000,0x00030047,0x0000039b,0x00000000, + 0x00030047,0x0000039f,0x00000000,0x00030047,0x000003a6,0x00000000,0x00030047,0x000003aa, + 0x00000000,0x00030047,0x000003c7,0x00000000,0x00030047,0x000003c6,0x00000000,0x00030047, + 0x0000039c,0x00000000,0x00030047,0x0000039e,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006, + 0x00000004,0x00040017,0x00000012,0x00000006,0x00000002,0x00040017,0x00000018,0x00000006, + 0x00000003,0x00040015,0x0000004d,0x00000020,0x00000000,0x0004002b,0x0000004d,0x0000004e, + 0x00000000,0x0004002b,0x00000006,0x00000069,0x00000000,0x00020014,0x0000006a,0x0004002b, + 0x00000006,0x0000006f,0x3f800000,0x00040032,0x0000004d,0x00000087,0x00000000,0x0004002b, + 0x0000004d,0x00000088,0x000013b5,0x00060034,0x0000006a,0x00000089,0x000000aa,0x00000087, + 0x00000088,0x0004002b,0x00000006,0x000000a5,0x3d897143,0x0004002b,0x00000006,0x000000a9, + 0x3bbf4590,0x0004002b,0x00000006,0x000000b0,0x4253ee82,0x00030030,0x0000006a,0x000000bb, + 0x0004002b,0x00000006,0x000000d1,0x388205ff,0x00030030,0x0000006a,0x000000df,0x00050034, + 0x0000006a,0x000000e0,0x000000a8,0x000000df,0x0004002b,0x00000006,0x000000ef,0xbf800000, + 0x0004002b,0x00000006,0x0000010d,0x3f7f8000,0x0004002b,0x00000006,0x00000110,0x3a800000, + 0x0004002b,0x00000006,0x00000113,0x3b000000,0x00090019,0x0000011d,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x0000011e,0x00000000, + 0x0000011d,0x0004003b,0x0000011e,0x0000011f,0x00000000,0x0002001a,0x00000121,0x00040020, + 0x00000122,0x00000000,0x00000121,0x0004003b,0x00000122,0x00000123,0x00000000,0x0003001b, + 0x00000125,0x0000011d,0x00050034,0x0000006a,0x00000130,0x000000a8,0x000000df,0x0004002b, + 0x00000006,0x00000143,0x40000000,0x0004003b,0x0000011e,0x00000145,0x00000000,0x0004003b, + 0x00000122,0x00000147,0x00000000,0x00050034,0x0000006a,0x00000153,0x000000a8,0x000000df, + 0x00040015,0x00000167,0x00000020,0x00000001,0x00040017,0x00000168,0x00000167,0x00000002, + 0x00040020,0x0000016b,0x00000001,0x00000007,0x0004003b,0x0000016b,0x0000016c,0x00000001, + 0x00040020,0x00000172,0x00000001,0x00000006,0x0004003b,0x00000172,0x00000173,0x00000001, + 0x00030030,0x0000006a,0x00000175,0x00050034,0x0000006a,0x00000176,0x000000a8,0x00000175, + 0x0004003b,0x0000016b,0x0000017a,0x00000001,0x00030030,0x0000006a,0x00000180,0x0004003b, + 0x0000016b,0x00000184,0x00000001,0x00090019,0x0000018f,0x0000004d,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000002,0x00000021,0x00040020,0x00000190,0x00000000,0x0000018f, + 0x0004003b,0x00000190,0x00000191,0x00000000,0x0004003b,0x00000172,0x00000194,0x00000001, + 0x00040017,0x0000019b,0x0000004d,0x00000004,0x00030030,0x0000006a,0x000001b8,0x00040020, + 0x000001bb,0x00000001,0x00000012,0x0004003b,0x000001bb,0x000001bc,0x00000001,0x0004003b, + 0x00000190,0x000001c4,0x00000000,0x00040017,0x000001f1,0x00000167,0x00000004,0x0017001e, + 0x000001f2,0x00000006,0x00000006,0x00000006,0x00000006,0x0000004d,0x0000004d,0x0000004d, + 0x0000004d,0x000001f1,0x00000012,0x00000012,0x0000004d,0x00000006,0x0000004d,0x00000006, + 0x00000006,0x0000004d,0x00000006,0x00000006,0x00000006,0x0000004d,0x00040020,0x000001f3, + 0x00000002,0x000001f2,0x0004003b,0x000001f3,0x000001f4,0x00000002,0x0004002b,0x00000167, + 0x000001f5,0x00000011,0x0004002b,0x00000167,0x000001f6,0x00000012,0x00040020,0x000001fb, + 0x00000002,0x00000006,0x00040020,0x00000219,0x00000003,0x00000007,0x0004003b,0x00000219, + 0x0000021a,0x00000003,0x0004003b,0x00000122,0x00000222,0x00000000,0x0004003b,0x0000011e, + 0x00000223,0x00000000,0x0004003b,0x00000172,0x00000224,0x00000001,0x00030001,0x00000007, + 0x0000038b,0x00030001,0x00000006,0x00000399,0x00030001,0x00000012,0x000003bc,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000007, + 0x0000016d,0x0000016c,0x0007004f,0x00000012,0x0000016e,0x0000016d,0x0000016d,0x00000000, + 0x00000001,0x0006000c,0x00000012,0x0000016f,0x00000001,0x00000008,0x0000016e,0x0004006e, + 0x00000168,0x00000170,0x0000016f,0x0004003d,0x00000006,0x00000174,0x00000173,0x000300f7, + 0x00000178,0x00000000,0x000400fa,0x00000176,0x00000177,0x00000178,0x000200f8,0x00000177, + 0x0004003d,0x00000007,0x0000017c,0x0000017a,0x00050051,0x00000006,0x0000023d,0x0000017c, + 0x00000003,0x000500be,0x0000006a,0x0000023e,0x0000023d,0x00000069,0x000300f7,0x000002aa, + 0x00000000,0x000400fa,0x0000023e,0x0000023f,0x0000024d,0x000200f8,0x0000024d,0x000500ba, + 0x0000006a,0x00000250,0x0000023d,0x000000ef,0x000300f7,0x000002a9,0x00000000,0x000400fa, + 0x00000250,0x00000251,0x0000028c,0x000200f8,0x0000028c,0x0004007f,0x00000006,0x0000028f, + 0x0000023d,0x00050083,0x00000006,0x00000290,0x0000028f,0x00000143,0x0004003d,0x0000011d, + 0x00000291,0x00000145,0x0004003d,0x00000121,0x00000292,0x00000147,0x00050056,0x00000125, + 0x00000293,0x00000291,0x00000292,0x0007004f,0x00000012,0x00000295,0x0000017c,0x0000017c, + 0x00000000,0x00000001,0x00070058,0x00000007,0x00000297,0x00000293,0x00000295,0x00000002, + 0x00000290,0x00050051,0x00000006,0x00000299,0x0000017c,0x00000002,0x00050085,0x00000006, + 0x0000029b,0x00000299,0x0000006f,0x000300f7,0x000002a8,0x00000000,0x000400fa,0x00000153, + 0x0000029c,0x000002a0,0x000200f8,0x000002a0,0x0008004f,0x00000018,0x000002b5,0x00000297, + 0x00000297,0x00000000,0x00000001,0x00000002,0x00050051,0x00000006,0x000002b7,0x00000297, + 0x00000003,0x000500b7,0x0000006a,0x000002b8,0x000002b7,0x00000069,0x000300f7,0x000002be, + 0x00000000,0x000400fa,0x000002b8,0x000002b9,0x000002bd,0x000200f8,0x000002bd,0x000200f9, + 0x000002be,0x000200f8,0x000002b9,0x00050088,0x00000006,0x000002bc,0x0000006f,0x000002b7, + 0x000200f9,0x000002be,0x000200f8,0x000002be,0x000700f5,0x00000006,0x00000388,0x000002bc, + 0x000002b9,0x00000069,0x000002bd,0x0005008e,0x00000018,0x000002c0,0x000002b5,0x00000388, + 0x00050085,0x00000006,0x000002a6,0x000002b7,0x0000029b,0x00050051,0x00000006,0x000002c6, + 0x000002c0,0x00000000,0x00060052,0x00000007,0x0000036e,0x000002c6,0x0000038b,0x00000000, + 0x00050051,0x00000006,0x000002c8,0x000002c0,0x00000001,0x00060052,0x00000007,0x00000370, + 0x000002c8,0x0000036e,0x00000001,0x00050051,0x00000006,0x000002ca,0x000002c0,0x00000002, + 0x00060052,0x00000007,0x00000372,0x000002ca,0x00000370,0x00000002,0x00060052,0x00000007, + 0x00000374,0x000002a6,0x00000372,0x00000003,0x000200f9,0x000002a8,0x000200f8,0x0000029c, + 0x0005008e,0x00000007,0x0000029f,0x00000297,0x0000029b,0x000200f9,0x000002a8,0x000200f8, + 0x000002a8,0x000700f5,0x00000007,0x00000392,0x0000029f,0x0000029c,0x00000374,0x000002be, + 0x000200f9,0x000002a9,0x000200f8,0x00000251,0x00050051,0x00000006,0x00000253,0x0000017c, + 0x00000002,0x000500ba,0x0000006a,0x00000254,0x00000253,0x00000069,0x000300f7,0x0000025c, + 0x00000000,0x000400fa,0x00000254,0x00000255,0x00000258,0x000200f8,0x00000258,0x0007004f, + 0x00000012,0x0000025a,0x0000017c,0x0000017c,0x00000000,0x00000001,0x0006000c,0x00000006, + 0x0000025b,0x00000001,0x00000042,0x0000025a,0x000200f9,0x0000025c,0x000200f8,0x00000255, + 0x00050051,0x00000006,0x00000257,0x0000017c,0x00000000,0x000200f9,0x0000025c,0x000200f8, + 0x0000025c,0x000700f5,0x00000006,0x0000038c,0x00000257,0x00000255,0x0000025b,0x00000258, + 0x0008000c,0x00000006,0x0000025f,0x00000001,0x0000002b,0x0000038c,0x00000069,0x0000006f, + 0x0006000c,0x00000006,0x00000262,0x00000001,0x00000004,0x00000253,0x000500ba,0x0000006a, + 0x00000264,0x00000262,0x0000006f,0x000300f7,0x0000026e,0x00000000,0x000400fa,0x00000264, + 0x00000265,0x00000269,0x000200f8,0x00000269,0x00050085,0x00000006,0x0000026b,0x00000113, + 0x0000025f,0x00050081,0x00000006,0x0000026d,0x0000026b,0x00000262,0x000200f9,0x0000026e, + 0x000200f8,0x00000265,0x00050085,0x00000006,0x00000267,0x0000010d,0x0000025f,0x00050081, + 0x00000006,0x00000268,0x00000267,0x00000110,0x000200f9,0x0000026e,0x000200f8,0x0000026e, + 0x000700f5,0x00000006,0x0000038d,0x00000268,0x00000265,0x0000026d,0x00000269,0x0004007f, + 0x00000006,0x00000272,0x0000023d,0x0004003d,0x0000011d,0x00000273,0x0000011f,0x0004003d, + 0x00000121,0x00000274,0x00000123,0x00050056,0x00000125,0x00000275,0x00000273,0x00000274, + 0x00050050,0x00000012,0x00000278,0x0000038d,0x00000272,0x00070058,0x00000007,0x00000279, + 0x00000275,0x00000278,0x00000002,0x00000069,0x00050051,0x00000006,0x0000027c,0x00000279, + 0x00000003,0x00050085,0x00000006,0x0000027d,0x0000027c,0x0000006f,0x00060052,0x00000007, + 0x00000360,0x0000027d,0x00000279,0x00000003,0x000300f7,0x0000028b,0x00000000,0x000400fa, + 0x00000130,0x0000027f,0x0000028b,0x000200f8,0x0000027f,0x00050051,0x00000006,0x00000281, + 0x00000360,0x00000003,0x0008004f,0x00000018,0x00000283,0x00000360,0x00000360,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x00000018,0x00000284,0x00000283,0x00000281,0x00050051, + 0x00000006,0x00000286,0x00000284,0x00000000,0x00060052,0x00000007,0x00000363,0x00000286, + 0x00000360,0x00000000,0x00050051,0x00000006,0x00000288,0x00000284,0x00000001,0x00060052, + 0x00000007,0x00000365,0x00000288,0x00000363,0x00000001,0x00050051,0x00000006,0x0000028a, + 0x00000284,0x00000002,0x00060052,0x00000007,0x00000367,0x0000028a,0x00000365,0x00000002, + 0x000200f9,0x0000028b,0x000200f8,0x0000028b,0x000700f5,0x00000007,0x00000391,0x00000360, + 0x0000026e,0x00000367,0x0000027f,0x000200f9,0x000002a9,0x000200f8,0x000002a9,0x000700f5, + 0x00000007,0x00000390,0x00000391,0x0000028b,0x00000392,0x000002a8,0x000200f9,0x000002aa, + 0x000200f8,0x0000023f,0x000300f7,0x0000024c,0x00000000,0x000400fa,0x000000e0,0x00000242, + 0x00000246,0x000200f8,0x00000246,0x00050051,0x00000006,0x00000249,0x0000017c,0x00000003, + 0x00050085,0x00000006,0x0000024a,0x00000249,0x0000006f,0x00060052,0x00000007,0x00000358, + 0x0000024a,0x0000017c,0x00000003,0x000200f9,0x0000024c,0x000200f8,0x00000242,0x0005008e, + 0x00000007,0x00000245,0x0000017c,0x0000006f,0x000200f9,0x0000024c,0x000200f8,0x0000024c, + 0x000700f5,0x00000007,0x0000038f,0x00000245,0x00000242,0x00000358,0x00000246,0x000200f9, + 0x000002aa,0x000200f8,0x000002aa,0x000700f5,0x00000007,0x0000038e,0x0000038f,0x0000024c, + 0x00000390,0x000002a9,0x000300f7,0x00000182,0x00000000,0x000400fa,0x00000180,0x00000181, + 0x00000182,0x000200f8,0x00000181,0x0004003d,0x00000007,0x00000186,0x00000184,0x0007004f, + 0x00000012,0x000002d8,0x00000186,0x00000186,0x00000000,0x00000001,0x0007004f,0x00000012, + 0x000002da,0x00000186,0x00000186,0x00000002,0x00000003,0x0007000c,0x00000012,0x000002db, + 0x00000001,0x00000025,0x000002d8,0x000002da,0x00050051,0x00000006,0x000002dd,0x000002db, + 0x00000000,0x00050051,0x00000006,0x000002df,0x000002db,0x00000001,0x0007000c,0x00000006, + 0x000002e0,0x00000001,0x00000025,0x000002dd,0x000002df,0x0007000c,0x00000006,0x0000018c, + 0x00000001,0x00000025,0x000002e0,0x0000006f,0x000200f9,0x00000182,0x000200f8,0x00000182, + 0x000700f5,0x00000006,0x0000039a,0x0000006f,0x000002aa,0x0000018c,0x00000181,0x000200f9, + 0x00000178,0x000200f8,0x00000178,0x000700f5,0x00000007,0x000003a6,0x0000038b,0x00000005, + 0x0000038e,0x00000182,0x000700f5,0x00000006,0x00000398,0x00000399,0x00000005,0x0000039a, + 0x00000182,0x000114f4,0x000300f7,0x0000018e,0x00000000,0x000400fa,0x00000175,0x0000018d, + 0x0000019d,0x000200f8,0x0000019d,0x0004003d,0x0000018f,0x0000019f,0x00000191,0x00050062, + 0x0000019b,0x000001a1,0x0000019f,0x00000170,0x00050051,0x0000004d,0x000001a2,0x000001a1, + 0x00000000,0x0006000c,0x00000012,0x000001a3,0x00000001,0x0000003e,0x000001a2,0x00050051, + 0x00000006,0x000001a6,0x000001a3,0x00000001,0x0004003d,0x00000006,0x000001a9,0x00000194, + 0x000500b4,0x0000006a,0x000001aa,0x000001a6,0x000001a9,0x000300f7,0x000001ad,0x00000000, + 0x000400fa,0x000001aa,0x000001ac,0x000001b0,0x000200f8,0x000001b0,0x000200f9,0x000001ad, + 0x000200f8,0x000001ac,0x00050051,0x00000006,0x000001af,0x000001a3,0x00000000,0x000200f9, + 0x000001ad,0x000200f8,0x000001ad,0x000700f5,0x00000006,0x00000393,0x000001af,0x000001ac, + 0x00000069,0x000001b0,0x00050081,0x00000006,0x000001b7,0x00000393,0x00000174,0x000300f7, + 0x000001ba,0x00000000,0x000400fa,0x000001b8,0x000001b9,0x000001ba,0x000200f8,0x000001b9, + 0x00050041,0x00000172,0x000001bd,0x000001bc,0x0000004e,0x0004003d,0x00000006,0x000001be, + 0x000001bd,0x000500b7,0x0000006a,0x000001bf,0x000001be,0x00000069,0x000200f9,0x000001ba, + 0x000200f8,0x000001ba,0x000700f5,0x0000006a,0x000001c0,0x000001b8,0x000001ad,0x000001bf, + 0x000001b9,0x000300f7,0x000001c2,0x00000000,0x000400fa,0x000001c0,0x000001c1,0x000001c2, + 0x000200f8,0x000001c1,0x0004003d,0x0000018f,0x000001c5,0x000001c4,0x00050062,0x0000019b, + 0x000001c7,0x000001c5,0x00000170,0x00050051,0x0000004d,0x000001c8,0x000001c7,0x00000000, + 0x0006000c,0x00000012,0x000001c9,0x00000001,0x0000003e,0x000001c8,0x00050051,0x00000006, + 0x000001cc,0x000001c9,0x00000001,0x00050041,0x00000172,0x000001cf,0x000001bc,0x0000004e, + 0x0004003d,0x00000006,0x000001d0,0x000001cf,0x000500b4,0x0000006a,0x000001d1,0x000001cc, + 0x000001d0,0x000300f7,0x000001d4,0x00000000,0x000400fa,0x000001d1,0x000001d3,0x000001d7, + 0x000200f8,0x000001d7,0x000200f9,0x000001d4,0x000200f8,0x000001d3,0x00050051,0x00000006, + 0x000001d6,0x000001c9,0x00000000,0x000200f9,0x000001d4,0x000200f8,0x000001d4,0x000700f5, + 0x00000006,0x00000394,0x000001d6,0x000001d3,0x00000069,0x000001d7,0x0007000c,0x00000006, + 0x000001dd,0x00000001,0x00000025,0x00000394,0x00000398,0x000200f9,0x000001c2,0x000200f8, + 0x000001c2,0x000700f5,0x00000006,0x0000039b,0x00000398,0x000001ba,0x000001dd,0x000001d4, + 0x0007000c,0x00000006,0x000001df,0x00000001,0x00000028,0x0000039b,0x00000069,0x000300f7, + 0x0000030a,0x00000000,0x000300fb,0x0000004e,0x000002f4,0x000200f8,0x000002f4,0x000300f7, + 0x00000305,0x00000000,0x000400fa,0x00000089,0x000002f5,0x00000305,0x000200f8,0x000002f5, + 0x000500b8,0x0000006a,0x000002f8,0x00000393,0x000001df,0x000300f7,0x00000304,0x00000000, + 0x000400fa,0x000002f8,0x000002f9,0x00000302,0x000200f8,0x00000302,0x000200f9,0x0000030a, + 0x000200f8,0x000002f9,0x000500ba,0x0000006a,0x000002fc,0x00000393,0x00000069,0x000300f7, + 0x00000301,0x00000000,0x000400fa,0x000002fc,0x000002fd,0x000002ff,0x000200f8,0x000002ff, + 0x000200f9,0x0000030a,0x000200f8,0x000002fd,0x000200f9,0x0000030a,0x000200f8,0x00000301, + 0x000100ff,0x000200f8,0x00000304,0x000100ff,0x000200f8,0x00000305,0x0008000c,0x00000006, + 0x00000309,0x00000001,0x0000002b,0x00000393,0x00000069,0x000001df,0x000200f9,0x0000030a, + 0x000200f8,0x0000030a,0x000b00f5,0x00000006,0x0000039c,0x00000393,0x000002fd,0x00000069, + 0x000002ff,0x000001df,0x00000302,0x00000309,0x00000305,0x000300f7,0x00000326,0x00000000, + 0x000300fb,0x0000004e,0x00000310,0x000200f8,0x00000310,0x000300f7,0x00000321,0x00000000, + 0x000400fa,0x00000089,0x00000311,0x00000321,0x000200f8,0x00000311,0x000500b8,0x0000006a, + 0x00000314,0x000001b7,0x000001df,0x000300f7,0x00000320,0x00000000,0x000400fa,0x00000314, + 0x00000315,0x0000031e,0x000200f8,0x0000031e,0x000200f9,0x00000326,0x000200f8,0x00000315, + 0x000500ba,0x0000006a,0x00000318,0x000001b7,0x00000069,0x000300f7,0x0000031d,0x00000000, + 0x000400fa,0x00000318,0x00000319,0x0000031b,0x000200f8,0x0000031b,0x000200f9,0x00000326, + 0x000200f8,0x00000319,0x000200f9,0x00000326,0x000200f8,0x0000031d,0x000100ff,0x000200f8, + 0x00000320,0x000100ff,0x000200f8,0x00000321,0x0008000c,0x00000006,0x00000325,0x00000001, + 0x0000002b,0x000001b7,0x00000069,0x000001df,0x000200f9,0x00000326,0x000200f8,0x00000326, + 0x000b00f5,0x00000006,0x0000039e,0x000001b7,0x00000319,0x00000069,0x0000031b,0x000001df, + 0x0000031e,0x00000325,0x00000321,0x000300f7,0x000001ef,0x00000000,0x000400fa,0x000000bb, + 0x000001ee,0x000001ef,0x000200f8,0x000001ee,0x00050041,0x000001fb,0x000001fc,0x000001f4, + 0x000001f5,0x0004003d,0x00000006,0x000001fd,0x000001fc,0x00050041,0x000001fb,0x000001ff, + 0x000001f4,0x000001f6,0x0004003d,0x00000006,0x00000200,0x000001ff,0x000300f7,0x00000334, + 0x00000000,0x000400fa,0x000000bb,0x0000032e,0x00000333,0x000200f8,0x00000333,0x000200f9, + 0x00000334,0x000200f8,0x0000032e,0x00050051,0x00000006,0x0000033b,0x0000016e,0x00000000, + 0x00050085,0x00000006,0x0000033c,0x000000a5,0x0000033b,0x00050051,0x00000006,0x0000033e, + 0x0000016e,0x00000001,0x00050085,0x00000006,0x0000033f,0x000000a9,0x0000033e,0x00050081, + 0x00000006,0x00000340,0x0000033c,0x0000033f,0x0006000c,0x00000006,0x00000341,0x00000001, + 0x0000000a,0x00000340,0x00050085,0x00000006,0x00000343,0x000000b0,0x00000341,0x0006000c, + 0x00000006,0x00000344,0x00000001,0x0000000a,0x00000343,0x00050085,0x00000006,0x00000347, + 0x00000344,0x000001fd,0x00050081,0x00000006,0x00000349,0x00000347,0x00000200,0x000200f9, + 0x00000334,0x000200f8,0x00000334,0x000700f5,0x00000006,0x0000039f,0x00000349,0x0000032e, + 0x00000069,0x00000333,0x000200f9,0x000001ef,0x000200f8,0x000001ef,0x000700f5,0x00000006, + 0x000003aa,0x00000399,0x00000326,0x0000039f,0x00000334,0x00050051,0x00000006,0x00000208, + 0x000003a6,0x00000003,0x00050083,0x00000006,0x0000034e,0x0000039e,0x0000039c,0x00050085, + 0x00000006,0x00000351,0x0000039c,0x00000208,0x00050083,0x00000006,0x00000352,0x0000006f, + 0x00000351,0x0007000c,0x00000006,0x00000353,0x00000001,0x00000028,0x00000352,0x000000d1, + 0x00050088,0x00000006,0x00000354,0x0000034e,0x00000353,0x0005008e,0x00000007,0x0000020b, + 0x000003a6,0x00000354,0x000300f7,0x0000020d,0x00000000,0x000400fa,0x000000bb,0x0000020c, + 0x0000020d,0x000200f8,0x0000020c,0x0008004f,0x00000018,0x00000210,0x0000020b,0x0000020b, + 0x00000000,0x00000001,0x00000002,0x00060050,0x00000018,0x00000211,0x000003aa,0x000003aa, + 0x000003aa,0x00050081,0x00000018,0x00000212,0x00000210,0x00000211,0x00050051,0x00000006, + 0x00000214,0x00000212,0x00000000,0x00060052,0x00000007,0x00000383,0x00000214,0x0000020b, + 0x00000000,0x00050051,0x00000006,0x00000216,0x00000212,0x00000001,0x00060052,0x00000007, + 0x00000385,0x00000216,0x00000383,0x00000001,0x00050051,0x00000006,0x00000218,0x00000212, + 0x00000002,0x00060052,0x00000007,0x00000387,0x00000218,0x00000385,0x00000002,0x000200f9, + 0x0000020d,0x000200f8,0x0000020d,0x000700f5,0x00000007,0x000003c7,0x0000020b,0x000001ef, + 0x00000387,0x0000020c,0x000200f9,0x0000018e,0x000200f8,0x0000018d,0x0004003d,0x0000018f, + 0x00000192,0x00000191,0x0004003d,0x00000006,0x00000198,0x00000194,0x00060052,0x00000012, + 0x00000378,0x00000174,0x000003bc,0x00000000,0x00060052,0x00000012,0x0000037a,0x00000198, + 0x00000378,0x00000001,0x0006000c,0x0000004d,0x0000019a,0x00000001,0x0000003a,0x0000037a, + 0x00070050,0x0000019b,0x0000019c,0x0000019a,0x0000019a,0x0000019a,0x0000019a,0x00040063, + 0x00000192,0x00000170,0x0000019c,0x000200f9,0x0000018e,0x000200f8,0x0000018e,0x000700f5, + 0x00000007,0x000003c6,0x000003a6,0x0000018d,0x000003c7,0x0000020d,0x000114f5,0x0003003e, + 0x0000021a,0x000003c6,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..be0d1ca24d794918c2d4b4033173a12ecd0e4728 GIT binary patch literal 9712 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 z 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.h new file mode 100644 index 000000000..22c6b686a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.h @@ -0,0 +1,431 @@ +#pragma once + +const uint32_t draw_clockwise_path_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000684,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00001502,0x000a000a,0x5f565053,0x5f545845,0x67617266,0x746e656d,0x6168735f,0x5f726564, + 0x65746e69,0x636f6c72,0x0000006b,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e, + 0x00000000,0x0003000e,0x00000000,0x00000001,0x000d000f,0x00000004,0x00000004,0x6e69616d, + 0x00000000,0x0000029b,0x000002a1,0x000002a6,0x000002b0,0x000002c9,0x000002e8,0x00000349, + 0x00000362,0x00030010,0x00000004,0x00000007,0x00030010,0x00000004,0x000014f6,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x665f4252,0x6d676172,0x5f746e65,0x64616873, + 0x695f7265,0x7265746e,0x6b636f6c,0x00000000,0x00090004,0x415f4c47,0x735f4252,0x65646168, + 0x6d695f72,0x5f656761,0x64616f6c,0x6f74735f,0x00006572,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x000000be,0x00006752,0x00030005,0x000000f2,0x0000674e,0x00030005,0x00000120, + 0x00004351,0x00030005,0x00000124,0x00003954,0x00030005,0x000001da,0x00006749,0x00030005, + 0x00000218,0x00004444,0x00030005,0x0000021a,0x00006277,0x00030005,0x0000023b,0x00004344, + 0x00030005,0x0000023d,0x00003552,0x00030005,0x0000025d,0x0000674a,0x00060005,0x0000029b, + 0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x000002a1,0x00000049,0x00030005, + 0x000002a6,0x0000316b,0x00030005,0x000002ac,0x00006748,0x00030005,0x000002b0,0x0000304e, + 0x00030005,0x000002bc,0x00003053,0x00030005,0x000002c9,0x0000307a,0x00030005,0x000002e4, + 0x00006747,0x00030005,0x000002e8,0x00003153,0x00030005,0x000002f0,0x00003065,0x00030005, + 0x0000031e,0x0000424d,0x00040006,0x0000031e,0x00000000,0x00006250,0x00040006,0x0000031e, + 0x00000001,0x00006359,0x00040006,0x0000031e,0x00000002,0x00006552,0x00040006,0x0000031e, + 0x00000003,0x00006553,0x00040006,0x0000031e,0x00000004,0x0000366d,0x00040006,0x0000031e, + 0x00000005,0x0000676d,0x00040006,0x0000031e,0x00000006,0x00006544,0x00040006,0x0000031e, + 0x00000007,0x00006545,0x00040006,0x0000031e,0x00000008,0x00003755,0x00040006,0x0000031e, + 0x00000009,0x0000676a,0x00040006,0x0000031e,0x0000000a,0x0000635a,0x00040006,0x0000031e, + 0x0000000b,0x00003157,0x00040006,0x0000031e,0x0000000c,0x0000676e,0x00040006,0x0000031e, + 0x0000000d,0x00003559,0x00040006,0x0000031e,0x0000000e,0x0000324f,0x00040006,0x0000031e, + 0x0000000f,0x00006461,0x00040006,0x0000031e,0x00000010,0x00006579,0x00040006,0x0000031e, + 0x00000011,0x00003376,0x00040006,0x0000031e,0x00000012,0x00003377,0x00040006,0x0000031e, + 0x00000013,0x00006462,0x00040006,0x0000031e,0x00000014,0x00006767,0x00030005,0x00000320, + 0x0000006b,0x00030005,0x00000349,0x00003159,0x00030005,0x00000362,0x0000316d,0x00040047, + 0x000000be,0x00000001,0x0000000b,0x00040047,0x000000f2,0x00000001,0x00000007,0x00030047, + 0x00000120,0x00000000,0x00040047,0x00000120,0x00000021,0x0000000a,0x00040047,0x00000120, + 0x00000022,0x00000000,0x00030047,0x00000124,0x00000000,0x00040047,0x00000124,0x00000021, + 0x0000000a,0x00040047,0x00000124,0x00000022,0x00000000,0x00040047,0x000001da,0x00000001, + 0x00000002,0x00030047,0x00000218,0x00000000,0x00040047,0x00000218,0x00000021,0x00000009, + 0x00040047,0x00000218,0x00000022,0x00000000,0x00030047,0x0000021a,0x00000000,0x00040047, + 0x0000021a,0x00000021,0x00000009,0x00040047,0x0000021a,0x00000022,0x00000000,0x00030047, + 0x0000023b,0x00000000,0x00040047,0x0000023b,0x00000021,0x0000000c,0x00040047,0x0000023b, + 0x00000022,0x00000001,0x00030047,0x0000023d,0x00000000,0x00040047,0x0000023d,0x00000021, + 0x0000000c,0x00040047,0x0000023d,0x00000022,0x00000001,0x00040047,0x0000025d,0x00000001, + 0x00000003,0x00040047,0x0000029b,0x0000000b,0x0000000f,0x00040047,0x000002a1,0x0000001e, + 0x00000002,0x00040047,0x000002a6,0x0000001e,0x00000000,0x00040047,0x000002ac,0x00000001, + 0x00000001,0x00040047,0x000002b0,0x0000001e,0x00000005,0x00030047,0x000002b8,0x00000000, + 0x00030047,0x000002bc,0x00000017,0x00040047,0x000002bc,0x00000021,0x00000003,0x00040047, + 0x000002bc,0x00000022,0x00000002,0x00030047,0x000002c5,0x00000000,0x00030047,0x000002c9, + 0x00000000,0x00030047,0x000002c9,0x0000000e,0x00040047,0x000002c9,0x0000001e,0x00000003, + 0x00030047,0x000002ca,0x00000000,0x00030047,0x000002d0,0x00000000,0x00030047,0x000002de, + 0x00000000,0x00030047,0x000002e2,0x00000000,0x00040047,0x000002e4,0x00000001,0x00000000, + 0x00030047,0x000002e8,0x00000000,0x00030047,0x000002e8,0x0000000e,0x00040047,0x000002e8, + 0x0000001e,0x00000004,0x00030047,0x000002ea,0x00000000,0x00030047,0x000002f0,0x00000017, + 0x00040047,0x000002f0,0x00000021,0x00000001,0x00040047,0x000002f0,0x00000022,0x00000002, + 0x00030047,0x000002f8,0x00000000,0x00030047,0x000002fc,0x00000000,0x00030047,0x00000302, + 0x00000000,0x00030047,0x00000309,0x00000000,0x00030047,0x0000030b,0x00000000,0x00030047, + 0x0000031e,0x00000002,0x00050048,0x0000031e,0x00000000,0x00000023,0x00000000,0x00050048, + 0x0000031e,0x00000001,0x00000023,0x00000004,0x00050048,0x0000031e,0x00000002,0x00000023, + 0x00000008,0x00050048,0x0000031e,0x00000003,0x00000023,0x0000000c,0x00050048,0x0000031e, + 0x00000004,0x00000023,0x00000010,0x00050048,0x0000031e,0x00000005,0x00000023,0x00000014, + 0x00050048,0x0000031e,0x00000006,0x00000023,0x00000018,0x00050048,0x0000031e,0x00000007, + 0x00000023,0x0000001c,0x00050048,0x0000031e,0x00000008,0x00000023,0x00000020,0x00050048, + 0x0000031e,0x00000009,0x00000023,0x00000030,0x00050048,0x0000031e,0x0000000a,0x00000023, + 0x00000038,0x00050048,0x0000031e,0x0000000b,0x00000023,0x00000040,0x00050048,0x0000031e, + 0x0000000c,0x00000023,0x00000044,0x00050048,0x0000031e,0x0000000d,0x00000023,0x00000048, + 0x00050048,0x0000031e,0x0000000e,0x00000023,0x0000004c,0x00050048,0x0000031e,0x0000000f, + 0x00000023,0x00000050,0x00050048,0x0000031e,0x00000010,0x00000023,0x00000054,0x00050048, + 0x0000031e,0x00000011,0x00000023,0x00000058,0x00050048,0x0000031e,0x00000012,0x00000023, + 0x0000005c,0x00050048,0x0000031e,0x00000013,0x00000023,0x00000060,0x00050048,0x0000031e, + 0x00000014,0x00000023,0x00000064,0x00040047,0x00000320,0x00000021,0x00000000,0x00040047, + 0x00000320,0x00000022,0x00000000,0x00030047,0x00000334,0x00000000,0x00030047,0x00000337, + 0x00000000,0x00030047,0x0000033c,0x00000000,0x00030047,0x0000033d,0x00000000,0x00030047, + 0x0000033e,0x00000000,0x00030047,0x00000349,0x00000000,0x00030047,0x00000349,0x0000000e, + 0x00040047,0x00000349,0x0000001e,0x00000006,0x00030047,0x0000034a,0x00000000,0x00030047, + 0x00000352,0x00000000,0x00030047,0x0000035f,0x00000000,0x00030047,0x00000362,0x00000000, + 0x00040047,0x00000362,0x0000001e,0x00000000,0x00030047,0x000003c1,0x00000000,0x00030047, + 0x000003c2,0x00000000,0x00030047,0x000003cd,0x00000000,0x00030047,0x000003ce,0x00000000, + 0x00030047,0x00000413,0x00000000,0x00030047,0x00000414,0x00000000,0x00030047,0x00000417, + 0x00000000,0x00030047,0x00000418,0x00000000,0x00030047,0x00000419,0x00000000,0x00030047, + 0x0000041e,0x00000000,0x00030047,0x0000042b,0x00000000,0x00030047,0x0000042c,0x00000000, + 0x00030047,0x00000430,0x00000000,0x00030047,0x00000431,0x00000000,0x00030047,0x00000432, + 0x00000000,0x00030047,0x00000435,0x00000000,0x00030047,0x00000436,0x00000000,0x00030047, + 0x00000439,0x00000000,0x00030047,0x0000043b,0x00000000,0x00030047,0x0000043c,0x00000000, + 0x00030047,0x0000043d,0x00000000,0x00030047,0x0000043e,0x00000000,0x00030047,0x0000043f, + 0x00000000,0x00030047,0x00000442,0x00000000,0x00030047,0x00000443,0x00000000,0x00030047, + 0x00000445,0x00000000,0x00030047,0x00000446,0x00000000,0x00030047,0x00000449,0x00000000, + 0x00030047,0x0000044a,0x00000000,0x00030047,0x0000044c,0x00000000,0x00030047,0x0000044d, + 0x00000000,0x00030047,0x00000450,0x00000000,0x00030047,0x00000451,0x00000000,0x00030047, + 0x00000453,0x00000000,0x00030047,0x00000454,0x00000000,0x00030047,0x00000457,0x00000000, + 0x00030047,0x00000458,0x00000000,0x00030047,0x00000460,0x00000000,0x00030047,0x00000462, + 0x00000000,0x00030047,0x00000464,0x00000000,0x00030047,0x00000466,0x00000000,0x00030047, + 0x00000467,0x00000000,0x00030047,0x0000046a,0x00000000,0x00030047,0x0000046c,0x00000000, + 0x00030047,0x0000046e,0x00000000,0x00030047,0x000004aa,0x00000000,0x00030047,0x000004d4, + 0x00000000,0x00030047,0x000004d5,0x00000000,0x00030047,0x000004da,0x00000000,0x00030047, + 0x000004dd,0x00000000,0x00030047,0x000004e2,0x00000000,0x00030047,0x000004e4,0x00000000, + 0x00030047,0x000004e5,0x00000000,0x00030047,0x000004f2,0x00000000,0x00030047,0x000004f3, + 0x00000000,0x00030047,0x000004f8,0x00000000,0x00030047,0x00000500,0x00000000,0x00030047, + 0x00000507,0x00000000,0x00030047,0x00000516,0x00000000,0x00030047,0x00000518,0x00000000, + 0x00030047,0x0000051d,0x00000000,0x00030047,0x00000521,0x00000000,0x00030047,0x00000539, + 0x00000000,0x00030047,0x0000053b,0x00000000,0x00030047,0x0000053c,0x00000000,0x00030047, + 0x0000053e,0x00000000,0x00030047,0x00000540,0x00000000,0x00030047,0x00000541,0x00000000, + 0x00030047,0x00000567,0x00000000,0x00030047,0x00000583,0x00000000,0x00030047,0x000005a1, + 0x00000000,0x00030047,0x000005a2,0x00000000,0x00030047,0x000005a5,0x00000000,0x00030047, + 0x000005a7,0x00000000,0x00030047,0x000005ac,0x00000000,0x00030047,0x000005af,0x00000000, + 0x00030047,0x000005b0,0x00000000,0x00030047,0x000005b1,0x00000000,0x00030047,0x000005b2, + 0x00000000,0x00030047,0x000005cd,0x00000000,0x00030047,0x000005cf,0x00000000,0x00030047, + 0x000005d1,0x00000000,0x00030047,0x000005d3,0x00000000,0x00030047,0x000005d9,0x00000000, + 0x00030047,0x000005db,0x00000000,0x00030047,0x000005dd,0x00000000,0x00030047,0x000005df, + 0x00000000,0x00030047,0x000005e5,0x00000000,0x00030047,0x000005ed,0x00000000,0x00030047, + 0x000005f0,0x00000000,0x00030047,0x000005f2,0x00000000,0x00030047,0x000005f4,0x00000000, + 0x00030047,0x000005fb,0x00000000,0x00030047,0x000005fd,0x00000000,0x00030047,0x000005ff, + 0x00000000,0x00030047,0x00000601,0x00000000,0x00030047,0x0000060d,0x00000000,0x00030047, + 0x0000060f,0x00000000,0x00030047,0x00000611,0x00000000,0x00030047,0x00000614,0x00000000, + 0x00030047,0x00000616,0x00000000,0x00030047,0x00000617,0x00000000,0x00030047,0x0000061d, + 0x00000000,0x00030047,0x00000621,0x00000000,0x00030047,0x0000062e,0x00000000,0x00030047, + 0x00000630,0x00000000,0x00030047,0x00000631,0x00000000,0x00030047,0x0000062f,0x00000000, + 0x00030047,0x0000062d,0x00000000,0x00030047,0x00000632,0x00000000,0x00030047,0x00000633, + 0x00000000,0x00030047,0x00000634,0x00000000,0x00030047,0x00000639,0x00000000,0x00030047, + 0x0000063a,0x00000000,0x00030047,0x0000063e,0x00000000,0x00030047,0x00000649,0x00000000, + 0x00030047,0x00000663,0x00000000,0x00030047,0x0000061e,0x00000000,0x00030047,0x0000061f, + 0x00000000,0x00030047,0x00000620,0x00000000,0x00030047,0x0000063b,0x00000000,0x00030047, + 0x0000063d,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015, + 0x00000006,0x00000020,0x00000000,0x00030016,0x00000008,0x00000020,0x00040017,0x0000000d, + 0x00000008,0x00000004,0x00040017,0x00000018,0x00000008,0x00000002,0x00040017,0x00000025, + 0x00000008,0x00000003,0x00020014,0x00000046,0x0004002b,0x00000006,0x0000007a,0x00000000, + 0x0004002b,0x00000008,0x000000a1,0x00000000,0x0004002b,0x00000008,0x000000a6,0x3f800000, + 0x00040032,0x00000006,0x000000be,0x00000000,0x0004002b,0x00000006,0x000000bf,0x000013b5, + 0x00060034,0x00000046,0x000000c0,0x000000aa,0x000000be,0x000000bf,0x0004002b,0x00000008, + 0x000000dc,0x3d897143,0x0004002b,0x00000008,0x000000e0,0x3bbf4590,0x0004002b,0x00000008, + 0x000000e7,0x4253ee82,0x00030030,0x00000046,0x000000f2,0x0004002b,0x00000008,0x00000108, + 0xbfc00000,0x00090019,0x0000011e,0x00000008,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x0000011f,0x00000000,0x0000011e,0x0004003b,0x0000011f, + 0x00000120,0x00000000,0x0002001a,0x00000122,0x00040020,0x00000123,0x00000000,0x00000122, + 0x0004003b,0x00000123,0x00000124,0x00000000,0x0003001b,0x00000126,0x0000011e,0x0004002b, + 0x00000008,0x00000130,0x447a0000,0x0004002b,0x00000008,0x00000138,0x3e800000,0x0004002b, + 0x00000008,0x0000013e,0xc0000000,0x0004002b,0x00000008,0x00000144,0x3f19319f,0x0004002b, + 0x00000008,0x00000149,0x3e55e621,0x0004002b,0x00000008,0x0000014a,0x3f206c99,0x0004002b, + 0x00000008,0x0000014b,0x3f85afd5,0x0004002b,0x00000008,0x0000014c,0x3fbb295d,0x0004002b, + 0x00000008,0x00000189,0x40a311dd,0x0004002b,0x00000008,0x0000018b,0xc02311dd,0x0004002b, + 0x00000008,0x000001a6,0x40400000,0x0004002b,0x00000008,0x000001cc,0x388205ff,0x00030030, + 0x00000046,0x000001da,0x00050034,0x00000046,0x000001db,0x000000a8,0x000001da,0x0004002b, + 0x00000008,0x000001ea,0xbf800000,0x0004002b,0x00000008,0x00000208,0x3f7f8000,0x0004002b, + 0x00000008,0x0000020b,0x3a800000,0x0004002b,0x00000008,0x0000020e,0x3b000000,0x0004003b, + 0x0000011f,0x00000218,0x00000000,0x0004003b,0x00000123,0x0000021a,0x00000000,0x00050034, + 0x00000046,0x00000226,0x000000a8,0x000001da,0x0004002b,0x00000008,0x00000239,0x40000000, + 0x0004003b,0x0000011f,0x0000023b,0x00000000,0x0004003b,0x00000123,0x0000023d,0x00000000, + 0x00050034,0x00000046,0x00000249,0x000000a8,0x000001da,0x00030030,0x00000046,0x0000025d, + 0x00040015,0x00000296,0x00000020,0x00000001,0x00040017,0x00000297,0x00000296,0x00000002, + 0x00040020,0x0000029a,0x00000001,0x0000000d,0x0004003b,0x0000029a,0x0000029b,0x00000001, + 0x0004003b,0x0000029a,0x000002a1,0x00000001,0x0004003b,0x0000029a,0x000002a6,0x00000001, + 0x00030030,0x00000046,0x000002ac,0x0004003b,0x0000029a,0x000002b0,0x00000001,0x00090019, + 0x000002ba,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000002,0x00000021, + 0x00040020,0x000002bb,0x00000000,0x000002ba,0x0004003b,0x000002bb,0x000002bc,0x00000000, + 0x00040017,0x000002bf,0x00000006,0x00000004,0x00040020,0x000002c8,0x00000001,0x00000008, + 0x0004003b,0x000002c8,0x000002c9,0x00000001,0x00030030,0x00000046,0x000002e4,0x00040020, + 0x000002e7,0x00000001,0x00000018,0x0004003b,0x000002e7,0x000002e8,0x00000001,0x0004003b, + 0x000002bb,0x000002f0,0x00000000,0x00040017,0x0000031d,0x00000296,0x00000004,0x0017001e, + 0x0000031e,0x00000008,0x00000008,0x00000008,0x00000008,0x00000006,0x00000006,0x00000006, + 0x00000006,0x0000031d,0x00000018,0x00000018,0x00000006,0x00000008,0x00000006,0x00000008, + 0x00000008,0x00000006,0x00000008,0x00000008,0x00000008,0x00000006,0x00040020,0x0000031f, + 0x00000002,0x0000031e,0x0004003b,0x0000031f,0x00000320,0x00000002,0x0004002b,0x00000296, + 0x00000321,0x00000011,0x0004002b,0x00000296,0x00000322,0x00000012,0x00040020,0x00000327, + 0x00000002,0x00000008,0x00050034,0x00000046,0x00000345,0x000000a8,0x000001da,0x0004003b, + 0x000002c8,0x00000349,0x00000001,0x00040020,0x00000361,0x00000003,0x0000000d,0x0004003b, + 0x00000361,0x00000362,0x00000003,0x00030001,0x0000000d,0x0000061a,0x00030001,0x00000008, + 0x00000656,0x00030001,0x00000018,0x00000674,0x0007002c,0x0000000d,0x00000683,0x0000018b, + 0x0000018b,0x0000018b,0x0000018b,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003d,0x0000000d,0x0000029c,0x0000029b,0x0007004f,0x00000018, + 0x0000029d,0x0000029c,0x0000029c,0x00000000,0x00000001,0x0006000c,0x00000018,0x0000029e, + 0x00000001,0x00000008,0x0000029d,0x0004006e,0x00000297,0x0000029f,0x0000029e,0x0004003d, + 0x0000000d,0x000002a3,0x000002a1,0x000300f7,0x00000392,0x00000000,0x000300fb,0x0000007a, + 0x00000388,0x000200f8,0x00000388,0x00050051,0x00000008,0x00000397,0x000002a3,0x00000001, + 0x000500be,0x00000046,0x00000398,0x00000397,0x000000a1,0x000300f7,0x00000391,0x00000000, + 0x000400fa,0x00000398,0x0000038b,0x0000038e,0x000200f8,0x0000038e,0x000300f7,0x000003ed, + 0x00000000,0x000300fb,0x0000007a,0x000003df,0x000200f8,0x000003df,0x000300f7,0x000003e3, + 0x00000000,0x000400fa,0x0000025d,0x000003e0,0x000003e3,0x000200f8,0x000003e0,0x000500b8, + 0x00000046,0x000003f3,0x00000397,0x00000108,0x000200f9,0x000003e3,0x000200f8,0x000003e3, + 0x000700f5,0x00000046,0x000003e4,0x0000025d,0x000003df,0x000003f3,0x000003e0,0x000300f7, + 0x000003ec,0x00000000,0x000400fa,0x000003e4,0x000003e5,0x000003e8,0x000200f8,0x000003e8, + 0x00050051,0x00000008,0x000003ea,0x000002a3,0x00000000,0x000200f9,0x000003ed,0x000200f8, + 0x000003e5,0x00050051,0x00000008,0x0000040c,0x000002a3,0x00000002,0x00050051,0x00000008, + 0x0000040e,0x000002a3,0x00000003,0x0007000c,0x00000008,0x0000040f,0x00000001,0x00000028, + 0x0000040e,0x000000a1,0x000500be,0x00000046,0x00000411,0x0000040c,0x000000a1,0x000300f7, + 0x0000041b,0x00000000,0x000400fa,0x00000411,0x00000412,0x0000041a,0x000200f8,0x0000041a, + 0x000200f9,0x0000041b,0x000200f8,0x00000412,0x0004003d,0x0000011e,0x00000413,0x00000120, + 0x0004003d,0x00000122,0x00000414,0x00000124,0x00050056,0x00000126,0x00000415,0x00000413, + 0x00000414,0x00050050,0x00000018,0x00000417,0x0000040f,0x000000a1,0x00070058,0x0000000d, + 0x00000418,0x00000415,0x00000417,0x00000002,0x000000a1,0x00050051,0x00000008,0x00000419, + 0x00000418,0x00000000,0x000200f9,0x0000041b,0x000200f8,0x0000041b,0x000700f5,0x00000008, + 0x00000617,0x00000419,0x00000412,0x000000a1,0x0000041a,0x0006000c,0x00000008,0x0000041e, + 0x00000001,0x00000004,0x0000040c,0x000500b8,0x00000046,0x0000041f,0x0000041e,0x00000130, + 0x000300f7,0x0000046f,0x00000000,0x000400fa,0x0000041f,0x00000420,0x0000046f,0x000200f8, + 0x00000420,0x00050051,0x00000008,0x00000422,0x000002a3,0x00000000,0x0006000c,0x00000008, + 0x00000423,0x00000001,0x00000004,0x00000422,0x00050083,0x00000008,0x00000424,0x00000423, + 0x00000138,0x0004007f,0x00000008,0x00000427,0x00000397,0x00050081,0x00000008,0x00000428, + 0x00000427,0x0000013e,0x00050083,0x00000008,0x0000042b,0x00000428,0x0000040f,0x00050085, + 0x00000008,0x0000042c,0x0000042b,0x00000144,0x00060052,0x0000000d,0x000005cd,0x00000149, + 0x0000061a,0x00000000,0x00060052,0x0000000d,0x000005cf,0x0000014a,0x000005cd,0x00000001, + 0x00060052,0x0000000d,0x000005d1,0x0000014b,0x000005cf,0x00000002,0x00060052,0x0000000d, + 0x000005d3,0x0000014c,0x000005d1,0x00000003,0x0005008e,0x0000000d,0x00000430,0x000005d3, + 0x0000042c,0x00070050,0x0000000d,0x00000431,0x0000040f,0x0000040f,0x0000040f,0x0000040f, + 0x00050081,0x0000000d,0x00000432,0x00000431,0x00000430,0x0004007f,0x00000008,0x00000435, + 0x0000040c,0x0005008e,0x0000000d,0x00000436,0x00000432,0x00000435,0x00050085,0x00000008, + 0x00000439,0x00000428,0x0000040c,0x00050081,0x00000008,0x0000043b,0x00000439,0x00000424, + 0x00070050,0x0000000d,0x0000043c,0x0000043b,0x0000043b,0x0000043b,0x0000043b,0x00050081, + 0x0000000d,0x0000043d,0x00000436,0x0000043c,0x0004003d,0x0000011e,0x0000043e,0x00000120, + 0x0004003d,0x00000122,0x0000043f,0x00000124,0x00050056,0x00000126,0x00000440,0x0000043e, + 0x0000043f,0x00050051,0x00000008,0x00000442,0x0000043d,0x00000000,0x00050050,0x00000018, + 0x00000443,0x00000442,0x000000a1,0x00070058,0x0000000d,0x00000444,0x00000440,0x00000443, + 0x00000002,0x000000a1,0x0004003d,0x0000011e,0x00000445,0x00000120,0x0004003d,0x00000122, + 0x00000446,0x00000124,0x00050056,0x00000126,0x00000447,0x00000445,0x00000446,0x00050051, + 0x00000008,0x00000449,0x0000043d,0x00000001,0x00050050,0x00000018,0x0000044a,0x00000449, + 0x000000a1,0x00070058,0x0000000d,0x0000044b,0x00000447,0x0000044a,0x00000002,0x000000a1, + 0x0004003d,0x0000011e,0x0000044c,0x00000120,0x0004003d,0x00000122,0x0000044d,0x00000124, + 0x00050056,0x00000126,0x0000044e,0x0000044c,0x0000044d,0x00050051,0x00000008,0x00000450, + 0x0000043d,0x00000002,0x00050050,0x00000018,0x00000451,0x00000450,0x000000a1,0x00070058, + 0x0000000d,0x00000452,0x0000044e,0x00000451,0x00000002,0x000000a1,0x0004003d,0x0000011e, + 0x00000453,0x00000120,0x0004003d,0x00000122,0x00000454,0x00000124,0x00050056,0x00000126, + 0x00000455,0x00000453,0x00000454,0x00050051,0x00000008,0x00000457,0x0000043d,0x00000003, + 0x00050050,0x00000018,0x00000458,0x00000457,0x000000a1,0x00070058,0x0000000d,0x00000459, + 0x00000455,0x00000458,0x00000002,0x000000a1,0x00050051,0x00000008,0x0000045a,0x00000444, + 0x00000000,0x00050051,0x00000008,0x0000045b,0x0000044b,0x00000000,0x00050051,0x00000008, + 0x0000045c,0x00000452,0x00000000,0x00050051,0x00000008,0x0000045d,0x00000459,0x00000000, + 0x00060052,0x0000000d,0x000005d9,0x0000045a,0x0000061a,0x00000000,0x00060052,0x0000000d, + 0x000005db,0x0000045b,0x000005d9,0x00000001,0x00060052,0x0000000d,0x000005dd,0x0000045c, + 0x000005db,0x00000002,0x00060052,0x0000000d,0x000005df,0x0000045d,0x000005dd,0x00000003, + 0x0005008e,0x0000000d,0x00000460,0x00000432,0x00000189,0x00050081,0x0000000d,0x00000462, + 0x00000460,0x00000683,0x0004007f,0x0000000d,0x00000464,0x00000462,0x00050085,0x0000000d, + 0x00000466,0x00000464,0x00000462,0x0006000c,0x0000000d,0x00000467,0x00000001,0x0000001d, + 0x00000466,0x00050094,0x00000008,0x0000046a,0x000005df,0x00000467,0x00050085,0x00000008, + 0x0000046c,0x0000046a,0x0000042c,0x00050081,0x00000008,0x0000046e,0x00000617,0x0000046c, + 0x000200f9,0x0000046f,0x000200f8,0x0000046f,0x000700f5,0x00000008,0x0000061d,0x00000617, + 0x0000041b,0x0000046e,0x00000420,0x00050051,0x00000008,0x00000472,0x000002a3,0x00000000, + 0x0006000c,0x00000008,0x00000473,0x00000001,0x00000006,0x00000472,0x00050085,0x00000008, + 0x00000474,0x0000061d,0x00000473,0x000200f9,0x000003ed,0x000200f8,0x000003ec,0x000100ff, + 0x000200f8,0x000003ed,0x000700f5,0x00000008,0x0000061e,0x00000474,0x0000046f,0x000003ea, + 0x000003e8,0x000200f9,0x00000392,0x000200f8,0x0000038b,0x000300f7,0x000003b1,0x00000000, + 0x000300fb,0x0000007a,0x000003a0,0x000200f8,0x000003a0,0x000300f7,0x000003a4,0x00000000, + 0x000400fa,0x0000025d,0x000003a1,0x000003a4,0x000200f8,0x000003a1,0x00050051,0x00000008, + 0x000003b6,0x000002a3,0x00000000,0x000500b8,0x00000046,0x000003b7,0x000003b6,0x00000108, + 0x000200f9,0x000003a4,0x000200f8,0x000003a4,0x000700f5,0x00000046,0x000003a5,0x0000025d, + 0x000003a0,0x000003b7,0x000003a1,0x000300f7,0x000003b0,0x00000000,0x000400fa,0x000003a5, + 0x000003a6,0x000003a9,0x000200f8,0x000003a9,0x00050051,0x00000008,0x000003ab,0x000002a3, + 0x00000000,0x0007000c,0x00000008,0x000003ae,0x00000001,0x00000025,0x000003ab,0x00000397, + 0x000200f9,0x000003b1,0x000200f8,0x000003a6,0x00050051,0x00000008,0x000003bf,0x000002a3, + 0x00000000,0x00050081,0x00000008,0x000003c0,0x000001a6,0x000003bf,0x0004003d,0x0000011e, + 0x000003c1,0x00000120,0x0004003d,0x00000122,0x000003c2,0x00000124,0x00050056,0x00000126, + 0x000003c3,0x000003c1,0x000003c2,0x00050050,0x00000018,0x000003c5,0x000003c0,0x000000a1, + 0x00070058,0x0000000d,0x000003c6,0x000003c3,0x000003c5,0x00000002,0x000000a1,0x00050051, + 0x00000008,0x000003c7,0x000003c6,0x00000000,0x00050083,0x00000008,0x000003c9,0x000000a6, + 0x000003c7,0x00050083,0x00000008,0x000003cc,0x000000a6,0x00000397,0x0004003d,0x0000011e, + 0x000003cd,0x00000120,0x0004003d,0x00000122,0x000003ce,0x00000124,0x00050056,0x00000126, + 0x000003cf,0x000003cd,0x000003ce,0x00050050,0x00000018,0x000003d1,0x000003cc,0x000000a1, + 0x00070058,0x0000000d,0x000003d2,0x000003cf,0x000003d1,0x00000002,0x000000a1,0x00050051, + 0x00000008,0x000003d3,0x000003d2,0x00000000,0x00050083,0x00000008,0x000003d5,0x000003c9, + 0x000003d3,0x000200f9,0x000003b1,0x000200f8,0x000003b0,0x000100ff,0x000200f8,0x000003b1, + 0x000700f5,0x00000008,0x0000061f,0x000003d5,0x000003a6,0x000003ae,0x000003a9,0x000200f9, + 0x00000392,0x000200f8,0x00000391,0x000100ff,0x000200f8,0x00000392,0x000700f5,0x00000008, + 0x00000620,0x0000061f,0x000003b1,0x0000061e,0x000003ed,0x0004003d,0x0000000d,0x000002a8, + 0x000002a6,0x00050051,0x00000008,0x0000049e,0x000002a8,0x00000003,0x000500be,0x00000046, + 0x0000049f,0x0000049e,0x000000a1,0x000300f7,0x0000050b,0x00000000,0x000400fa,0x0000049f, + 0x000004a0,0x000004ae,0x000200f8,0x000004ae,0x000500ba,0x00000046,0x000004b1,0x0000049e, + 0x000001ea,0x000300f7,0x0000050a,0x00000000,0x000400fa,0x000004b1,0x000004b2,0x000004ed, + 0x000200f8,0x000004ed,0x0004007f,0x00000008,0x000004f0,0x0000049e,0x00050083,0x00000008, + 0x000004f1,0x000004f0,0x00000239,0x0004003d,0x0000011e,0x000004f2,0x0000023b,0x0004003d, + 0x00000122,0x000004f3,0x0000023d,0x00050056,0x00000126,0x000004f4,0x000004f2,0x000004f3, + 0x0007004f,0x00000018,0x000004f6,0x000002a8,0x000002a8,0x00000000,0x00000001,0x00070058, + 0x0000000d,0x000004f8,0x000004f4,0x000004f6,0x00000002,0x000004f1,0x00050051,0x00000008, + 0x000004fa,0x000002a8,0x00000002,0x00050085,0x00000008,0x000004fc,0x000004fa,0x000000a6, + 0x000300f7,0x00000509,0x00000000,0x000400fa,0x00000249,0x000004fd,0x00000501,0x000200f8, + 0x00000501,0x0008004f,0x00000025,0x00000516,0x000004f8,0x000004f8,0x00000000,0x00000001, + 0x00000002,0x00050051,0x00000008,0x00000518,0x000004f8,0x00000003,0x000500b7,0x00000046, + 0x00000519,0x00000518,0x000000a1,0x000300f7,0x0000051f,0x00000000,0x000400fa,0x00000519, + 0x0000051a,0x0000051e,0x000200f8,0x0000051e,0x000200f9,0x0000051f,0x000200f8,0x0000051a, + 0x00050088,0x00000008,0x0000051d,0x000000a6,0x00000518,0x000200f9,0x0000051f,0x000200f8, + 0x0000051f,0x000700f5,0x00000008,0x00000621,0x0000051d,0x0000051a,0x000000a1,0x0000051e, + 0x0005008e,0x00000025,0x00000521,0x00000516,0x00000621,0x00050085,0x00000008,0x00000507, + 0x00000518,0x000004fc,0x00050051,0x00000008,0x00000527,0x00000521,0x00000000,0x00060052, + 0x0000000d,0x000005fb,0x00000527,0x0000061a,0x00000000,0x00050051,0x00000008,0x00000529, + 0x00000521,0x00000001,0x00060052,0x0000000d,0x000005fd,0x00000529,0x000005fb,0x00000001, + 0x00050051,0x00000008,0x0000052b,0x00000521,0x00000002,0x00060052,0x0000000d,0x000005ff, + 0x0000052b,0x000005fd,0x00000002,0x00060052,0x0000000d,0x00000601,0x00000507,0x000005ff, + 0x00000003,0x000200f9,0x00000509,0x000200f8,0x000004fd,0x0005008e,0x0000000d,0x00000500, + 0x000004f8,0x000004fc,0x000200f9,0x00000509,0x000200f8,0x00000509,0x000700f5,0x0000000d, + 0x00000631,0x00000500,0x000004fd,0x00000601,0x0000051f,0x000200f9,0x0000050a,0x000200f8, + 0x000004b2,0x00050051,0x00000008,0x000004b4,0x000002a8,0x00000002,0x000500ba,0x00000046, + 0x000004b5,0x000004b4,0x000000a1,0x000300f7,0x000004bd,0x00000000,0x000400fa,0x000004b5, + 0x000004b6,0x000004b9,0x000200f8,0x000004b9,0x0007004f,0x00000018,0x000004bb,0x000002a8, + 0x000002a8,0x00000000,0x00000001,0x0006000c,0x00000008,0x000004bc,0x00000001,0x00000042, + 0x000004bb,0x000200f9,0x000004bd,0x000200f8,0x000004b6,0x00050051,0x00000008,0x000004b8, + 0x000002a8,0x00000000,0x000200f9,0x000004bd,0x000200f8,0x000004bd,0x000700f5,0x00000008, + 0x0000062b,0x000004b8,0x000004b6,0x000004bc,0x000004b9,0x0008000c,0x00000008,0x000004c0, + 0x00000001,0x0000002b,0x0000062b,0x000000a1,0x000000a6,0x0006000c,0x00000008,0x000004c3, + 0x00000001,0x00000004,0x000004b4,0x000500ba,0x00000046,0x000004c5,0x000004c3,0x000000a6, + 0x000300f7,0x000004cf,0x00000000,0x000400fa,0x000004c5,0x000004c6,0x000004ca,0x000200f8, + 0x000004ca,0x00050085,0x00000008,0x000004cc,0x0000020e,0x000004c0,0x00050081,0x00000008, + 0x000004ce,0x000004cc,0x000004c3,0x000200f9,0x000004cf,0x000200f8,0x000004c6,0x00050085, + 0x00000008,0x000004c8,0x00000208,0x000004c0,0x00050081,0x00000008,0x000004c9,0x000004c8, + 0x0000020b,0x000200f9,0x000004cf,0x000200f8,0x000004cf,0x000700f5,0x00000008,0x0000062c, + 0x000004c9,0x000004c6,0x000004ce,0x000004ca,0x0004007f,0x00000008,0x000004d3,0x0000049e, + 0x0004003d,0x0000011e,0x000004d4,0x00000218,0x0004003d,0x00000122,0x000004d5,0x0000021a, + 0x00050056,0x00000126,0x000004d6,0x000004d4,0x000004d5,0x00050050,0x00000018,0x000004d9, + 0x0000062c,0x000004d3,0x00070058,0x0000000d,0x000004da,0x000004d6,0x000004d9,0x00000002, + 0x000000a1,0x00050051,0x00000008,0x000004dd,0x000004da,0x00000003,0x00050085,0x00000008, + 0x000004de,0x000004dd,0x000000a6,0x00060052,0x0000000d,0x000005ed,0x000004de,0x000004da, + 0x00000003,0x000300f7,0x000004ec,0x00000000,0x000400fa,0x00000226,0x000004e0,0x000004ec, + 0x000200f8,0x000004e0,0x00050051,0x00000008,0x000004e2,0x000005ed,0x00000003,0x0008004f, + 0x00000025,0x000004e4,0x000005ed,0x000005ed,0x00000000,0x00000001,0x00000002,0x0005008e, + 0x00000025,0x000004e5,0x000004e4,0x000004e2,0x00050051,0x00000008,0x000004e7,0x000004e5, + 0x00000000,0x00060052,0x0000000d,0x000005f0,0x000004e7,0x000005ed,0x00000000,0x00050051, + 0x00000008,0x000004e9,0x000004e5,0x00000001,0x00060052,0x0000000d,0x000005f2,0x000004e9, + 0x000005f0,0x00000001,0x00050051,0x00000008,0x000004eb,0x000004e5,0x00000002,0x00060052, + 0x0000000d,0x000005f4,0x000004eb,0x000005f2,0x00000002,0x000200f9,0x000004ec,0x000200f8, + 0x000004ec,0x000700f5,0x0000000d,0x00000630,0x000005ed,0x000004cf,0x000005f4,0x000004e0, + 0x000200f9,0x0000050a,0x000200f8,0x0000050a,0x000700f5,0x0000000d,0x0000062f,0x00000630, + 0x000004ec,0x00000631,0x00000509,0x000200f9,0x0000050b,0x000200f8,0x000004a0,0x000300f7, + 0x000004ad,0x00000000,0x000400fa,0x000001db,0x000004a3,0x000004a7,0x000200f8,0x000004a7, + 0x00050051,0x00000008,0x000004aa,0x000002a8,0x00000003,0x00050085,0x00000008,0x000004ab, + 0x000004aa,0x000000a6,0x00060052,0x0000000d,0x000005e5,0x000004ab,0x000002a8,0x00000003, + 0x000200f9,0x000004ad,0x000200f8,0x000004a3,0x0005008e,0x0000000d,0x000004a6,0x000002a8, + 0x000000a6,0x000200f9,0x000004ad,0x000200f8,0x000004ad,0x000700f5,0x0000000d,0x0000062e, + 0x000004a6,0x000004a3,0x000005e5,0x000004a7,0x000200f9,0x0000050b,0x000200f8,0x0000050b, + 0x000700f5,0x0000000d,0x0000062d,0x0000062e,0x000004ad,0x0000062f,0x0000050a,0x000300f7, + 0x000002ae,0x00000000,0x000400fa,0x000002ac,0x000002ad,0x000002ae,0x000200f8,0x000002ad, + 0x0004003d,0x0000000d,0x000002b2,0x000002b0,0x0007004f,0x00000018,0x00000539,0x000002b2, + 0x000002b2,0x00000000,0x00000001,0x0007004f,0x00000018,0x0000053b,0x000002b2,0x000002b2, + 0x00000002,0x00000003,0x0007000c,0x00000018,0x0000053c,0x00000001,0x00000025,0x00000539, + 0x0000053b,0x00050051,0x00000008,0x0000053e,0x0000053c,0x00000000,0x00050051,0x00000008, + 0x00000540,0x0000053c,0x00000001,0x0007000c,0x00000008,0x00000541,0x00000001,0x00000025, + 0x0000053e,0x00000540,0x0007000c,0x00000008,0x000002b8,0x00000001,0x00000025,0x00000541, + 0x000000a6,0x000200f9,0x000002ae,0x000200f8,0x000002ae,0x000700f5,0x00000008,0x00000639, + 0x000000a6,0x0000050b,0x000002b8,0x000002ad,0x000114f4,0x0004003d,0x000002ba,0x000002bd, + 0x000002bc,0x00050062,0x000002bf,0x000002c0,0x000002bd,0x0000029f,0x00050051,0x00000006, + 0x000002c1,0x000002c0,0x00000000,0x0006000c,0x00000018,0x000002c2,0x00000001,0x0000003e, + 0x000002c1,0x00050051,0x00000008,0x000002c5,0x000002c2,0x00000001,0x0004003d,0x00000008, + 0x000002ca,0x000002c9,0x000500b4,0x00000046,0x000002cb,0x000002c5,0x000002ca,0x000300f7, + 0x000002ce,0x00000000,0x000400fa,0x000002cb,0x000002cd,0x000002d1,0x000200f8,0x000002d1, + 0x000200f9,0x000002ce,0x000200f8,0x000002cd,0x00050051,0x00000008,0x000002d0,0x000002c2, + 0x00000000,0x000200f9,0x000002ce,0x000200f8,0x000002ce,0x000700f5,0x00000008,0x00000632, + 0x000002d0,0x000002cd,0x000000a1,0x000002d1,0x000300f7,0x000002db,0x00000000,0x000400fa, + 0x00000398,0x000002da,0x000002df,0x000200f8,0x000002df,0x00050081,0x00000008,0x000002e2, + 0x00000632,0x00000620,0x000200f9,0x000002db,0x000200f8,0x000002da,0x0007000c,0x00000008, + 0x000002de,0x00000001,0x00000028,0x00000632,0x00000620,0x000200f9,0x000002db,0x000200f8, + 0x000002db,0x000700f5,0x00000008,0x00000633,0x000002de,0x000002da,0x000002e2,0x000002df, + 0x000300f7,0x000002e6,0x00000000,0x000400fa,0x000002e4,0x000002e5,0x000002e6,0x000200f8, + 0x000002e5,0x00050041,0x000002c8,0x000002e9,0x000002e8,0x0000007a,0x0004003d,0x00000008, + 0x000002ea,0x000002e9,0x000500b7,0x00000046,0x000002eb,0x000002ea,0x000000a1,0x000200f9, + 0x000002e6,0x000200f8,0x000002e6,0x000700f5,0x00000046,0x000002ec,0x000002e4,0x000002db, + 0x000002eb,0x000002e5,0x000300f7,0x000002ee,0x00000000,0x000400fa,0x000002ec,0x000002ed, + 0x000002ee,0x000200f8,0x000002ed,0x0004003d,0x000002ba,0x000002f1,0x000002f0,0x00050062, + 0x000002bf,0x000002f3,0x000002f1,0x0000029f,0x00050051,0x00000006,0x000002f4,0x000002f3, + 0x00000000,0x0006000c,0x00000018,0x000002f5,0x00000001,0x0000003e,0x000002f4,0x00050051, + 0x00000008,0x000002f8,0x000002f5,0x00000001,0x00050041,0x000002c8,0x000002fb,0x000002e8, + 0x0000007a,0x0004003d,0x00000008,0x000002fc,0x000002fb,0x000500b4,0x00000046,0x000002fd, + 0x000002f8,0x000002fc,0x000300f7,0x00000300,0x00000000,0x000400fa,0x000002fd,0x000002ff, + 0x00000303,0x000200f8,0x00000303,0x000200f9,0x00000300,0x000200f8,0x000002ff,0x00050051, + 0x00000008,0x00000302,0x000002f5,0x00000000,0x000200f9,0x00000300,0x000200f8,0x00000300, + 0x000700f5,0x00000008,0x00000634,0x00000302,0x000002ff,0x000000a1,0x00000303,0x0007000c, + 0x00000008,0x00000309,0x00000001,0x00000025,0x00000634,0x00000639,0x000200f9,0x000002ee, + 0x000200f8,0x000002ee,0x000700f5,0x00000008,0x0000063a,0x00000639,0x000002e6,0x00000309, + 0x00000300,0x0007000c,0x00000008,0x0000030b,0x00000001,0x00000028,0x0000063a,0x000000a1, + 0x000300f7,0x00000568,0x00000000,0x000300fb,0x0000007a,0x00000552,0x000200f8,0x00000552, + 0x000300f7,0x00000563,0x00000000,0x000400fa,0x000000c0,0x00000553,0x00000563,0x000200f8, + 0x00000553,0x000500b8,0x00000046,0x00000556,0x00000632,0x0000030b,0x000300f7,0x00000562, + 0x00000000,0x000400fa,0x00000556,0x00000557,0x00000560,0x000200f8,0x00000560,0x000200f9, + 0x00000568,0x000200f8,0x00000557,0x000500ba,0x00000046,0x0000055a,0x00000632,0x000000a1, + 0x000300f7,0x0000055f,0x00000000,0x000400fa,0x0000055a,0x0000055b,0x0000055d,0x000200f8, + 0x0000055d,0x000200f9,0x00000568,0x000200f8,0x0000055b,0x000200f9,0x00000568,0x000200f8, + 0x0000055f,0x000100ff,0x000200f8,0x00000562,0x000100ff,0x000200f8,0x00000563,0x0008000c, + 0x00000008,0x00000567,0x00000001,0x0000002b,0x00000632,0x000000a1,0x0000030b,0x000200f9, + 0x00000568,0x000200f8,0x00000568,0x000b00f5,0x00000008,0x0000063b,0x00000632,0x0000055b, + 0x000000a1,0x0000055d,0x0000030b,0x00000560,0x00000567,0x00000563,0x000300f7,0x00000584, + 0x00000000,0x000300fb,0x0000007a,0x0000056e,0x000200f8,0x0000056e,0x000300f7,0x0000057f, + 0x00000000,0x000400fa,0x000000c0,0x0000056f,0x0000057f,0x000200f8,0x0000056f,0x000500b8, + 0x00000046,0x00000572,0x00000633,0x0000030b,0x000300f7,0x0000057e,0x00000000,0x000400fa, + 0x00000572,0x00000573,0x0000057c,0x000200f8,0x0000057c,0x000200f9,0x00000584,0x000200f8, + 0x00000573,0x000500ba,0x00000046,0x00000576,0x00000633,0x000000a1,0x000300f7,0x0000057b, + 0x00000000,0x000400fa,0x00000576,0x00000577,0x00000579,0x000200f8,0x00000579,0x000200f9, + 0x00000584,0x000200f8,0x00000577,0x000200f9,0x00000584,0x000200f8,0x0000057b,0x000100ff, + 0x000200f8,0x0000057e,0x000100ff,0x000200f8,0x0000057f,0x0008000c,0x00000008,0x00000583, + 0x00000001,0x0000002b,0x00000633,0x000000a1,0x0000030b,0x000200f9,0x00000584,0x000200f8, + 0x00000584,0x000b00f5,0x00000008,0x0000063d,0x00000633,0x00000577,0x000000a1,0x00000579, + 0x0000030b,0x0000057c,0x00000583,0x0000057f,0x000300f7,0x0000031b,0x00000000,0x000400fa, + 0x000000f2,0x0000031a,0x0000031b,0x000200f8,0x0000031a,0x00050041,0x00000327,0x00000328, + 0x00000320,0x00000321,0x0004003d,0x00000008,0x00000329,0x00000328,0x00050041,0x00000327, + 0x0000032b,0x00000320,0x00000322,0x0004003d,0x00000008,0x0000032c,0x0000032b,0x000300f7, + 0x00000592,0x00000000,0x000400fa,0x000000f2,0x0000058c,0x00000591,0x000200f8,0x00000591, + 0x000200f9,0x00000592,0x000200f8,0x0000058c,0x00050051,0x00000008,0x00000599,0x0000029d, + 0x00000000,0x00050085,0x00000008,0x0000059a,0x000000dc,0x00000599,0x00050051,0x00000008, + 0x0000059c,0x0000029d,0x00000001,0x00050085,0x00000008,0x0000059d,0x000000e0,0x0000059c, + 0x00050081,0x00000008,0x0000059e,0x0000059a,0x0000059d,0x0006000c,0x00000008,0x0000059f, + 0x00000001,0x0000000a,0x0000059e,0x00050085,0x00000008,0x000005a1,0x000000e7,0x0000059f, + 0x0006000c,0x00000008,0x000005a2,0x00000001,0x0000000a,0x000005a1,0x00050085,0x00000008, + 0x000005a5,0x000005a2,0x00000329,0x00050081,0x00000008,0x000005a7,0x000005a5,0x0000032c, + 0x000200f9,0x00000592,0x000200f8,0x00000592,0x000700f5,0x00000008,0x0000063e,0x000005a7, + 0x0000058c,0x000000a1,0x00000591,0x000200f9,0x0000031b,0x000200f8,0x0000031b,0x000700f5, + 0x00000008,0x00000649,0x00000656,0x00000584,0x0000063e,0x00000592,0x00050051,0x00000008, + 0x00000334,0x0000062d,0x00000003,0x00050083,0x00000008,0x000005ac,0x0000063d,0x0000063b, + 0x00050085,0x00000008,0x000005af,0x0000063b,0x00000334,0x00050083,0x00000008,0x000005b0, + 0x000000a6,0x000005af,0x0007000c,0x00000008,0x000005b1,0x00000001,0x00000028,0x000005b0, + 0x000001cc,0x00050088,0x00000008,0x000005b2,0x000005ac,0x000005b1,0x0005008e,0x0000000d, + 0x00000337,0x0000062d,0x000005b2,0x000300f7,0x00000339,0x00000000,0x000400fa,0x000000f2, + 0x00000338,0x00000339,0x000200f8,0x00000338,0x0008004f,0x00000025,0x0000033c,0x00000337, + 0x00000337,0x00000000,0x00000001,0x00000002,0x00060050,0x00000025,0x0000033d,0x00000649, + 0x00000649,0x00000649,0x00050081,0x00000025,0x0000033e,0x0000033c,0x0000033d,0x00050051, + 0x00000008,0x00000340,0x0000033e,0x00000000,0x00060052,0x0000000d,0x0000060d,0x00000340, + 0x00000337,0x00000000,0x00050051,0x00000008,0x00000342,0x0000033e,0x00000001,0x00060052, + 0x0000000d,0x0000060f,0x00000342,0x0000060d,0x00000001,0x00050051,0x00000008,0x00000344, + 0x0000033e,0x00000002,0x00060052,0x0000000d,0x00000611,0x00000344,0x0000060f,0x00000002, + 0x000200f9,0x00000339,0x000200f8,0x00000339,0x000700f5,0x0000000d,0x00000663,0x00000337, + 0x0000031b,0x00000611,0x00000338,0x000400a8,0x00000046,0x00000346,0x00000345,0x000300f7, + 0x00000348,0x00000000,0x000400fa,0x00000346,0x00000347,0x00000348,0x000200f8,0x00000347, + 0x0004003d,0x00000008,0x0000034a,0x00000349,0x000500b4,0x00000046,0x0000034d,0x0000034a, + 0x000000a1,0x000200f9,0x00000348,0x000200f8,0x00000348,0x000700f5,0x00000046,0x0000034e, + 0x00000345,0x00000339,0x0000034d,0x00000347,0x000300f7,0x00000350,0x00000000,0x000400fa, + 0x0000034e,0x0000034f,0x00000350,0x000200f8,0x0000034f,0x00050051,0x00000008,0x00000352, + 0x00000663,0x00000003,0x000500be,0x00000046,0x00000353,0x00000352,0x000000a6,0x000200f9, + 0x00000350,0x000200f8,0x00000350,0x000700f5,0x00000046,0x00000354,0x0000034e,0x00000348, + 0x00000353,0x0000034f,0x000400a8,0x00000046,0x00000355,0x00000354,0x000300f7,0x00000357, + 0x00000000,0x000400fa,0x00000355,0x00000356,0x00000357,0x000200f8,0x00000356,0x0004003d, + 0x000002ba,0x00000358,0x000002bc,0x00060052,0x00000018,0x00000614,0x00000633,0x00000674, + 0x00000000,0x00060052,0x00000018,0x00000616,0x000002ca,0x00000614,0x00000001,0x0006000c, + 0x00000006,0x0000035f,0x00000001,0x0000003a,0x00000616,0x00070050,0x000002bf,0x00000360, + 0x0000035f,0x0000035f,0x0000035f,0x0000035f,0x00040063,0x00000358,0x0000029f,0x00000360, + 0x000200f9,0x00000357,0x000200f8,0x00000357,0x000114f5,0x0003003e,0x00000362,0x00000663, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..bf1176b62283797cc4f8671580aea80acc5ddd24 GIT binary patch literal 13640 zcmaLd3D90uc?a+p5;lV%iUOg8FTp4d)B>UsA~A$41S5omRb@W15u+ioNziIL6-8%s zbe!sRYF#n4M(PTTTip_Mv}#?ebVe-7P;kdl7E4uz{(o=o^W|x#)06My{Ga_f+r9VP z_f9+Tq(erd14c7OhmKxz@Mv6)8XXwUXrw*x@uShB@^AIZ%O;mxamnO0+tzHncEgq( zliOdoX8ne3lbg2e*syK$)^#tA{*2MVW4mQ5RlG|gCcA~u?Yc_4cf5(BN(azLesW+#7E%j%q%VV}S^)a!hpG2qd?~WdYJ1rTGM&C%X)05+} z6_e+#TJ-;>7`?+vuX=FpnvEMKH*a0DescSct=l&IFJFTW0j;&yU2{!3y>;!2Hmutb zUo-eJEZf&y`;yHWhz;AfPwv?87dx)owqf#`>$a@hv1#j;?MbonTXxY!%T_FzT=$Zf zB-qP0C+?;#8z$Fp+7^GCUOJ9_D4&DgrY-9>U$?$1928G|><-Epd_MkHZ5)l@`+_eV z@I=Pt;`8?MpBQ|}yuJAL;N^qPu^GU{i}&(p2ET0WUOXRvustVu)zkO#uL{0kY-AF(=5qOf&FPCz-^>3{@cBbr^L$}e2mQ|muO6_uf5m|B4qi6s zTMw%TKfejyFzC$6`grc5QC8mc5v;6SyN^y+M^~=fN5^!uD&t)GOjb8~Jhso+CqF3i zYm-Ci+aimb{vn~4H2Tocmp*f!{$ZhC)a)M>`gtv%8KEyvzsmpNp|>>sM~A*LV_)(k zLSJ;oKKjVeYcldBe@y6?w|tHY{nDrHlRq}}%NqT-&}*B0w$*53;+vO=432#b+lyBY z<8M!18@w!IZtWRk{XkoPXydYs55yQxALH4<#(*x_9Ksa3*63b5eT=&<**@LrBWswt z`DAMyEBwN2jeXJkY^RN^bA=4=T6y?z-rGy3xNn z&hE>=fbGSOtv#{v#oFs*+UV;|?>i0usNuV&@br;=EpJ6kd%NR`gD;LfN$(d;&o!X> z1nX0c1$s{CG-JDmfC2xp;RAJG;2+lTjD}rPn4F)Ht?SE4W2=2Uaq;9?dTj7q4~iF8 zW1jU>JT~;~+v1r+JbSTtt~+?gHl96(_a}`f9^ORb*#~&JWKQ|B2l38oJnIi{VdKda zZ*k+fCgGjmc;*amMdMk^cqkT$y!ENp=EStU zYa!$mJqM9u4V@Wz;b%7dtcK5NctOLifn^KVI)$xMb0o$EO>b4hlMTCuDsqO|E9}28 zC7U+-V#D8T_*)G>&LSFYk8b#whL3IdxQ1snd`iQoHhfycr#E~?!%uJc84b^Ccz(mr zYWSRn7c~6rh8Hz_Uc*ZoUfS^ThA(J%MZ?c+cxA&EH@v#xOB%ks;VT-xy5Y4AuW$I8 zhBr3+qJ}p&yrtm}H2nRBZ)^DWhVN+ju7>Y!_@0LEYxw?#A8L4flNr|AAud(}enP{? zHhebITh97SDk%kW#&VH^xk8b$LhL39a z=!T!r@G%Xa(D3YrpW5(g4WHidpEdla4WH5Q(;7ar;du?8-SC2jmp8nw;aLrz*ziQd z^BX>Az>mvQf_wh#jGs$0{PH(Cq&}@Jdt`#WbUJATMO;pj%JIVJJ9?c9q!V! zr-aYvD^e9So1J57AH8c#U;peg2K~=BIs4tIAI}Z-%y{E>PwEF!>5-M+{|G+s&tHE| z(RYUan~2{CNH^*`Wu781318T%N>d1Xk0*uZqw+W{I3u>W=(EQ3^$Ut#Fs4U)ie4Q0#?y~` zcG1g2&;H4!Q~DQ#e%t1WDfx3k-}cehPSGnuU-gvFOwq3oeaBJnU0D9!Fs4tMinlBD zXtZ!j?tR812fg~N8dGPTGjq{3zCR4UDJ@?4`$h0*bp7t454C`+vfB%^C_WD>@KI)uQKI$w~K9)Bh)h}ltd*tuZP9#I!uQ_sg4i0)4ZzP(Qu?c77RVmZ$!Vx5qSfw2*5RyfWi z;`Az)UfJ-k;?u2me_XWOPK=$(0F{npBiG{A1t=(`F}@NI@$*_PD>Nx?qELnrq5oCU!_&VpmR^^ z&r-$ER-b@YH;~o!fdI@-gn#isvnQa$_rJ>yymcE~zBLy?w6vJTVM1_eFEGl|qU! zAe%_V(`UHynG;-dR54BpuVRqjkiLrj#9%V_+E>Oe-jhRHN3R-mP7aOd{#$m=p!mk= zwS(TN!T9dWtI{{)=6TzF*|k6^zGrXuXYw>te9z(T)8xjv^gWZiUz1xyZ%R!5oq5T` zUOCK_v#-2*)ff6_gip?{`s++=t(8ybVtV-1H|JyhrB~zPoQ!V_E4K48eyKeJ%`52fyZbQE;8bYt1@qEKsfXLWIt?$lm!X2_a<*WL8acKM=cU5Ti zWc$bUexS$oj-bcAG&CLjitF8hxYk?6^$r2Q$GtK%d$NjKKAsnzc~FY?{Lsdz^Ii~I z{+)MKXug%&2hO8>?!TX$P5C7^Kc(-S$~U>(ito(IKY8CzSBGcqdls&ByEZhwd$m1d zAFU6KZ-1b@D=D694&KJ_uO!=v~^u| zcBONCc=RVyYn-wVyiu=Lfid*;XkA!Co=cbaoSLnOGvgfPpcL$e!&Fh} zdh~_hiSX(==zVJ6pI-`12fy~>mxKA*nLO&6_m$9e$@bri{}LX#Qund1h29mKta#rT zc=}cOd8ga+^Io^-_wCSh@GHOX2J_YP`?t_^$@b6hd*P8QmCJ3RvE|F!w$}CCKE5f5I;Yi~zB_9kFDg^dYd406udmkE zjO=g4`XYNz>PJ$o5ACOOEm#`)Ey3)ZjoCe_*^%9vdT%N_ZQZkf6U?s0>9@gn&bu{d z_l2H6(4PJ74}DJPdiHxDG#&gpNBk~W-&7@LQ)}y?$k@;!7PH3W_rYxN>zeY%@bGtq zr*DU~zBy+<9N7Wk>6`YVJblfLuJ^NIsfrxO5>vnZ9GeE8*qzsl!R!L{DI4&9pbQ_?4T?D&<#;aM@(%${Iz zPEn($54%z;k1q}KG~+&2pT8Ui8C`4k+Z0mtnd~d6Ur&{Q}ef9m+^obr{;>e}0L*EN_9ja^2_k+EsL%ZhO7J6pr zy5{_QXgc_HpZGzr7<|=z?Dk-~WHBF)Y0cLi;gMUj)wdso#y6I=?*0CNU%JNlSD_VS z?0w;#q4A6rTrutnW-mrvm+l^T_=-7~TkZXOBB#T){QNW+U#YzO7J^@XO84i3F2AMg zw-S6d_@(>HL0A0J^;-%)8+`Lwebd%n^;?G6=9rCs)2+R#EnUBF&}VOt+w*kY-;CLN z!Z)rTPOBJK?|$DK`u(YNw3YV0QFMdbDFI_Rk;E(URHtia8*mfPd z)d#=h&|}B1e0m@BrF8vsWhyhK}KksNioQfwOxSkbm4ffu)u21t~kEbf; zuw?U_jM$iX#`F%xZ;N#2rt(3z#?Wt#_1k0d77jc%^_+Tcc;$l)os#+PreySX#m<;i zpR~rr_08{8W+^~JY6B{Qya@a>Lw(;th!rJ?^dm>$0Q`BqxR{E&S!^}DI&N2_mi&}0?sJHcWp zU59S<-*0*J*zJrSe`5YHtsFx;Ebx%*RBk80_fKuleu|lCd~B_5adk zQ~CHkkv@CA#gflY(kk-t-u|9cJh9+&Gj?B1`}5SFrFyShUJH~M18*oG}*VoMh;o&Rpr`FAbp=;fc z*IYgnT(auxAHv(euYU{=zt+;j!EEv6?@y6G*(0gb!jr$&c+f$URr~|P6JO~%bZhSX z{!5RYvE{GUz+u7qH8+)>eaBCYowod(J;==mJ2A@7jKPn!L{A+3dSUjjQfKj1q4hya zzHX4~_nzpj4vj|#u5*pXeHdUYy0tv-m2CadS4=LPdq`Avo{KV;8O zy(*QRw)-LLG}}7Y$)~XV>p5*>u<`YrR&n*A`;q5^`NGjP$M5I##FC>N=<5?-eCz*f z(keBsTSCiOOa971UgNqoG#(we#&uh;y(5s#scM zLI+J&d;V>~?;7@eJ&V3QJl`XbmEJoCJ>yh*?+WkE&}6SlU#z)z2eT)u^TUn7?0gGJ zUiLeKeb+!UULRi|>0(w&XPi z3xn%B&3exD4HJI(FWp6hu6U*E8z+1=_@%pe(3Mx|`UVQ04ZiuU{%OsbbGvVf#5Rv? z^!=uc$GIUNw>~!*Z)a@fP&QgQh;w1EIP#*; zpO`DtDq_;PC>2jkxca{;SU=KCy^mWR0)JO{;+CDZ;$9NWuUzQ!S$)4Wm|Py0r&Z*E ze_1M?Jm7ksxgyweusQIYa&&TXo%4IYQheW`d2S^)kM=H=$=IXMPNm~FwcXLXI()KT f*CiM6ZXD$LSUG7Q%=7tza9#O@qtWX5?~rMS&)DzCLubrAb>{J>%$c`v z#)1=O&YpAXj1%WAoO9~Q^JkqD{WV6bj+LJ>^^mDsFIYHx>+N^ghT-RoCb*2r)*7uj zniwpfGV{cF_)9|EntVs{UCECn|HCSy(J{%-P1%s6IJ+D_6@Mq>zm>!LK^&eK|E5fx zvDX{+{x98&-fE>+-k&n__&GC9oUFvGBB0=ggRU+Pql{PnCKg5Wa}uPKSYF)7~Kgf=eGVl*W-j7^CQ-Y{4^ihem^ z5?y0=8J;+XyDr%?x)VpnHg$c&)=KF_w7zD`7?;Rkw)9KU&)AwU+Ny(VaLl$CNWR=`RT_rurIfeytz8@<5woXo=iBQ+`?96UWw8 z@^n??6Grz&F2PHKUp$5xQ>!*m@&2 z`zNxs_G}bdDxP}r_*pz<@T?WZ6E8gDr+CWXnbXBnJ)U`5JmVhkC5>m!;k~T!)Q2~z z@yr9fOzq|N%t^e-jc5Gf?b&#I#oM>>tXFvZH=aJjo7#BBGTyYt(@wlY8_)WMcVy#P z!|;x2JnIvzQKH3=F7w}S@-S2R_>C9FKu{n!=GySGYwzW@Ru6? zYQtY|_!|v>v*BAC{!zofZ1}#0A8hz{4L{QGqYdvbs7c~2l(!?!kkd&A#v_y-ODu;HIH z{L_Z-Z1`Ur{&~Z9H~fo+f7$ST4d37J!wo;u@S_d?q2b3G{UYN zAJg#6hG#c?V#6mjd~(C5H+)9JXEprZhA(LN6AfR{@Kp_8)9{jpZ)*7FhHq*3wuZmg z@M8_H?glZ$XY+=)Xn3oJw{CcH!#g*8K*O(VcxuCMYxo@vpV9EU8a}Jxvl~9A;d2{4 zzv1^c{K1AVZ1_VBf4Jd~G<|mhSzHNg$=)`;TJdj(uUV<_+<^hyy1-+ z-nikd8-7*8+cvyi!>?|5`-XRDcyhx#HN11fyEeRg!+SQocfOX!ziU4{i9E zhG#T9x8V~Tp5O4ohTqokI~zW$;dMRy4t>2r!;>1`rr}pNynVxy8{WC$T^ioE;eTv+ zTEmAld}zZ*HhfgWM>l+I!?PNm-S7zwzq#R)8eY`!ISrrN@cSFSpy3M}zNq1kHhgiz zmo&V%;maHTc*9pU{I!PfYWVJk?`innhVO6qfrcMx`0<7}@CVT_PBv20B zAAg3iG_m1T8(yv9bsAo`;q@Bcpy3T0-l*YC8s4noEgIgj z;hh@ZrQv-V-ml>)4Ij|(!3`hM@DUA9Z}{kj-`MbshG#ZBzu~twyrAKCHhgBoXEnU2 z;rBKCfrc+^_`?lv*EiM{&~aqG`zIo2OIuf!@qC%e>ePC!;d%or-q+s_^F2f z((uy_|9iv#+3?s4mtoFM@PqY$S84cJ4X@ttnhigv;k6rne#0+n_+<@GYWS56zpCMF z8s56$ts368;q4lJb;FYz-l^f;8s5L*3;hs3#N?BHfFJOU4gaR$hZ_D}!+&gey=H&? zhBs(<=Z1G3@bmKvxZl7x%*CP%vBvIBp+A=^J+iWUSnxh?ecx_HPY?Z}{chZ)=wm~l^VlJKZ+pSy1SxFR$g<;S(b zd5gSn(O(*)&)&W0>&NKPlA^yI`igDW*`w&2LT~un!Cu7X`JuF~Sa9keIM;}Sp=oz80%HC;X z^0W6U`iwDp&oNs04BBJ@k@+SG4!*bc*(Vy~oS@^^*CHh0GkfKX}z(bWiHuFj@T%L`R~_272kh z6a^j#4zM#F2#WPm;@!HVd_ZB@Rv|EhwQwLo(#rn|Du(tKY zp7tnnSac-1>O|K&UbI+x7t2P~d0uGu0d;&Z`2SajKk?P^-=ibZWfNWRYHNJn6y7z_ zF^^WtOf~k_$$bmnH28=Ci|LX9tM~J9WUJg^=&zTT+190=w@T!dUq3QyNaf;h5Wf3N zW%a3J!|!Z(eMex8F@BE1Ta7HaGuIJY2`1OZr=|d+l1G`RsadJZEeD zU}f0;mtjrYAUu5cV|HE=EIpk%$)1<|!eq8w=`74us=DS5a#!*<4{|oFJI9B{V*|cn zsQZjyb-VBWHL}uieKK*Hn>tPkW`k||%By2Ru97O{Pyh z19<=L83OHj!8>@*3Wq0Vo)bPEnhyT7@QjyF2J=nbN5)s<%{zL!WZFemZM!l&a;f{l zA8|KUJb%;Uo3ea1KFPf2k1O$TS(~drKN~)o=NEnSRInrlWLGESX)|2@TpL_{RCRnV zysCrz-D#`3KOaoyndq$8#rs0&v2ir$d@(eh=cFp>I@wD{((&0(}upfA(&r1FBU1>1CLeEO!MkI!2} z_wjjKXgc`SzrMGq?=ou4em^|?K4$L-tvp$c*{avK8NFWLXY_i16q*ix)$6+r_3E#x z*Y_Lvz22XNR-SBpy?2J!>-C*SulKIdbnvTQ-+!o=t*ZC#(D=RHdqOKuHoo3pgxBl! zy-2V3SE1?PSH1TItJip|dhZX7-|KxKwDM$CZ`oKHo_>&u_v_GN)Oinv=6~ls6q;?R z=7HZ<*&IKg{LacQd7n>yb7h;HZ)L~tuk4fe`Sfsj#=gHSA zA86mr6wjK2_gHv*S#OYkbeK23rBOe5&96TP<9{W&=GT+K)=e_&YOQsywXXUtgU+Y% zlCMs#IR7>jDyI=Rw) zUar>c$+=2(Z{KW?yOM7?$m`y|d1yQ~;A+cm!PSb>H40JTcrPnSA|ZZP!-i*{brd4X*OluT#SFH!oSO zN4~4;^YehveSW?!G#&h!i&KNy>T~hH&~(Yh&&Ah=M=sTUY+7i~uVlqLWZ-F6`FCh= z_wTUK-M_;_)4?zQjtpk2`!_u_U9$219TgtARK6S&nvY~X#`>?urMTC)^qZD4`anPF z%RVk&61vJ6t5weLU&^v&Y#Zy^ZXW+IhacB?Mm?~#fB^+O!542@s$|7@_NF0xN0 z|5LKMT#X4jXtMK%wb}Q8{AH`_(5de?`q41Vc;dC(QF()BJ7UzyJLUXX9(VyV6QNKEuiJrDY( zQoQ-!b?AyoijVw8PER>@#fz@-%${*vKJF4+W2NT7uHoTV|Lq$r=|8gFlJ`tz%eBVq z-ofL?Yd!Pt6PeiTEeG?5T{hS&fA$Ej@!oalR-eBj?W3n0yL?zP|sZ<#jHV@o}Jsdeb6VCzt=IY$TY5nHw9`1W_N(6#2gF*F_g zx=$P%tPZwnt(h52m&}+I)9SC;;gK7&)wVgI@x`*ny?5#OrE3jZ5Ly!B1LN26q4C5D zt~z{=th_pEUGiNro-FBezSZ3Ktuh^D%g(&u`i8mu@?Iam?3C_X23>Yb*L#0_W$;V) z)Iqn;XWs?jD}%2;t8K0|SH0U(w?0-zyXn?kbuC@*yXY%#j(=#-y(m{P+bmac-9A@I zT>Y;7iqKmRI0?F@cb_S)!6gg^ms5meEsw1TqXTO_NU~hlJ$?P{-%Q_tGb>HR+rRu=vMo^ z+oh+Rb%;H6#+9+8&JEJYzlT3DJaxF%+HC(F8=f)Mp&T9h)gKeW6N}B0SEQ><`Q!aE zedXC!7k}2sRpO6#7ON-YsSDmKM*fg8&k6S4!tc5jU;F#;>v`(A!Fbxs=d$C<4}Gw9 zuzL7LUmg5-K3)<(=sYhOj~}o)jhhz*dtXxH<|V;+ecY@Q8eeihHEv!Sy2cH8^`*Ur zC9Aeh3U7Q{Hw+KI#?s4!mBr`(Cb>%dC)+rA^JML@$*P}W$YrylM4W9F|^e~aG}S{q!+e?Q2z zd#4!qMQA)aaQ)qVZ?G|{9_1bhEh$HKU-HAr%DHNTy3u6y{IfKeo$~Luq00{0uah52 zR?fBCA?viV^>-bA3iH37(;f>J7td)`uQqf${CqOIfvq{dgP^A_KJtOSHnGLF_OC%X zsp9%%_&ndz z*?%T$pmMI=4q2y_tyuD>F#jvA_BB;p`LEuJYx(C|arI3JJ$2FL1AT2`i*0e+GdxM$ zd{?nYXgq$y=D7Ek2PW^A?EPk~XRjalr88~NnbLF)4#rp4I;peQ_59E;NmiGun9xC! z)tsLc?46oa&!QWK=erTI(%Wdz6Q|PKIK1g$kS$7Eav5!sf0QSyzaKUYR?g?~pdq;A9&V!@jp7Wq_0;B@2Jpt;tf~7+RN*ma^0tn4aVbJ@s0~^jNx6K z`rNB#g-4f6eRFb^)JHZu8Bcw1-5ZV%whpkR+=-zj<;YG*zBpMqSAKd|eM#~K$<6Tyi50QBe zuD*PGc=#3nGlM1ZCwoWoyOR0o%5OSovie=eek9MZY;_&FHGX}2M^8ERu~&cF*~7$t zI@;!aJ)SW!FIVYr`3gmR(7sDyZ0jgj{{eP`?YF>-a*I~w~G*d;HX{R;XVZ`u$m zdoA!Q`#qM=_Fd2=uit3xztBFm`RiHMx4mfJj7Y`zoiBaz@|V7EetjP|Uf=h>_~i8K zZ%q3t_)_~o$ZEcA5n1iKDBhL>k6t}b+Fya*Bv~0crN417+hSMx_H2~CvUKYABKuCr zOV=I^x|=uKC9{{KWc1jn`1r<|t?_a2y|Z%U%CaSH_PCTSv7%>fAhYL1yy;ZC?0u=d zFvWXd;FVo-)Lt00*eFA%{I@rzWcrbZQN-ACJ6r?Omg54Jg|sv&XGu^w_DmU6*#UH9l_Fhp!yDvTTW)y?^9J1qYRz$fA=QS?{sSo*eh7v=+s!Um(WM-N(Fr$EB|YNc?)u{}f(zn-{?cO$fo=aa@IyGkP&nB;2>z}>a z?2wo5_Cn*!Quo~+XmY81u@@Sz`)*G(TE8emr}XWwX1n`-Lg><0mQKZCizc&n(yhN4 zUJ)$*bZXANGMIg`8sGNHt>}JZ-<pm<(k+OFY@BqORY}4ino2> z_?0W(_Jq?Vukmw!u(`*!`mKZSj4kx|b@R;d>64eg^v?>tqWjIFflp4q`q-XtzSJId zvg)6u;n$w<;@R_!N3Z(jp@BAEl%Z4lzY1ns>`LE$a^>kOOQ-HP_QaEy?i0auji0hz zGW*O+Mvt9}+xyZ^w#LWp1K}%2UTqLJ`|rz^SkbHdjs5uIO{dyrUw-Y=FW#jCuk5D-|QC}&;16j`;Bu-`u%2u#A8MGn+*p(xpvn)+GyaD8wv;!SC&rMa^4AR(50^|or=RIO=eA{TlbqygTBCA9kuIX~;(a#d^^Q{=^S#)~@fD&Eeg!LMBLc2*5t@)|$q z2Ag|qtKT}fPi&#bubcaYPoKQ}r9UO~itaZD4199>)yK}F;Y*#JLstFc44OKtrg+Yx z!J}9G^1whFpUTiF{kwzN7Q51S&W-Z)m8Dbn8)x;9m+s@ibd8^~T{7q2l#Cub6}N-a zPPWF!?U3-5Bd<1yn{$E6mRQlN`;Bvg#G6jF%XvX{eo*l~I`GP_`_0ASp|w>RI_3W* zO{U-J*4TBvkhsyQv2=N`u~510H_jZQPhR&MJolHncewWZjo(A-Ub1Vjdr8@IW)`0D zUHi~jdq-7j7JK5hTrM%k=qZz`Qvq}=AoUrIaX#^&F{Bez%esnoLNAdhJ5 zK1}Y%WPEnvy;9a*yp@Cbue>%)C0GF=||jsXfqiY8)GPVqz|A9c;YSynIz?JoB>V(6*uR?Xj%6>YP3EimYroZ;!vF zvwdiK_~NTRXYVOTR`U*zfAezH2Jc+T=A*& zk@JS|>s@B)-ZAJ_8|Y4qF1|AOrTfD{x8g(Bc}4ij;FqrRLCN_3)nQHkNqG4B#kzTC zuw+dp`)M+s@eP;ntHq9(mOb;J^jzI<_~QH#I>v=EY?MED1(Wlq;_R$aygIi;TeYF? z{dY&MT;-Z0_k>5Le2qV6n(D_Izs@zqQ`R$$dHq1JvSgk|@RkOv*RzVTL#OV+4-T?b zBU4Ts&74W#sIb55_P%%2a=SI+%`BkS_~Xa$RfBH%6}6EwzVMa7FT0-| zbop9#odJfg41V?L)#2&WisiMzVu@eza%R|y)(7W@;ggqNWBonw$<R41JpgEtH^V^Fyo zgU%6VgP%19zZDu^88&OY;rH?8JA#U_vy#QQd|4dKm(7#O+{4NaS-0c6gtGII;BM#Q z(A6fgZilSfSroeLoD#>V@@!>3=o4+i7+d#Us6R&+0QwjDk> zziWKmKJdx)qi^P{0T;$DpU5lz&Z)*%FF$IWd^nh_-%Ig&3{DSSF*qYw4C>k8UBP(j ztGJxic-7vs!=p=9eTLWTIW2V6vx34>wSgS%X|K*^7DhIMqaUUUfA2hbB2Xf zd}oK@llRyZR+P zGJIw5OZW6amoH`4IcE6E;Mcd8?+VX1W4=RlFa2-1O75j(XC~vhm%_C^EDC0`&PP)} zyKKBWGKme}FP;+`j}6!}x9=CaIs*=W{9d)`gKqC1XT;$v z)BES>LAUphGvx4<>3rwOxi6AivuDLue)^t{OgpQ8T+#LYnrl7NI4@0KjrDK(+c$f3 z>)Suq(siDi@#p(P<=Cm1d@7i{KmUAY;MF;7H5O{!xGHiw%9fqa2IET=TW8_nmz~nR zX3*`ibygm}GCj7R8+3aNou!Ab48C^PH6hN|;kk#C)$d2nT;=!X$>e_btKUOU49zwjG0bJ;{|`m|Waik{LQ6Hr zt_zK4j=?ogzaFftELGpsT>3`%=2zvKOWzD%S@Md(w}bJe>N95(;+Or>y>Za(eYR$F z@s;U)_MJhu_nET|@s+7QtM<88pE=`C-TF}(ZNDaSWNv)CIryez@wz2fNxbmCn~W!3 zaIHVL2K&yo{?@oX7|$FuZmNtcAJp^xVD<2eK6~o?L9UWI>D-Zwr%t$H^`l_zFt%!6 z^^e2DH*VBh3j7h$x`v1FKPb~xqkGF=eh2eDUaScnU1qj9*W+t!YAw5I;KAB7`Zl}DrqnN(qugCg|+w4Tpvt6Jh|rS?}Ejf?V5Lw1W!*UGdIk| cM}zVCr5)^O2flVxU9L}Nzu12yDwC7{FH5gK1^@s6 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.h new file mode 100644 index 000000000..fd676addc --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.h @@ -0,0 +1,669 @@ +#pragma once + +const uint32_t draw_clockwise_path_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000bfe,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0010000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000046a,0x0000046d,0x00000471, + 0x00000472,0x00000485,0x00000492,0x000004c6,0x000004cc,0x000004eb,0x0000050b,0x0000058b, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x0000014f, + 0x00004342,0x00030005,0x0000015f,0x0000664b,0x00040006,0x0000015f,0x00000000,0x00003464, + 0x00030005,0x00000161,0x00004358,0x00030005,0x00000174,0x0000664a,0x00040006,0x00000174, + 0x00000000,0x00003464,0x00030005,0x00000176,0x0000424c,0x00030005,0x00000456,0x0000424d, + 0x00040006,0x00000456,0x00000000,0x00006250,0x00040006,0x00000456,0x00000001,0x00006359, + 0x00040006,0x00000456,0x00000002,0x00006552,0x00040006,0x00000456,0x00000003,0x00006553, + 0x00040006,0x00000456,0x00000004,0x0000366d,0x00040006,0x00000456,0x00000005,0x0000676d, + 0x00040006,0x00000456,0x00000006,0x00006544,0x00040006,0x00000456,0x00000007,0x00006545, + 0x00040006,0x00000456,0x00000008,0x00003755,0x00040006,0x00000456,0x00000009,0x0000676a, + 0x00040006,0x00000456,0x0000000a,0x0000635a,0x00040006,0x00000456,0x0000000b,0x00003157, + 0x00040006,0x00000456,0x0000000c,0x0000676e,0x00040006,0x00000456,0x0000000d,0x00003559, + 0x00040006,0x00000456,0x0000000e,0x0000324f,0x00040006,0x00000456,0x0000000f,0x00006461, + 0x00040006,0x00000456,0x00000010,0x00006579,0x00040006,0x00000456,0x00000011,0x00003376, + 0x00040006,0x00000456,0x00000012,0x00003377,0x00040006,0x00000456,0x00000013,0x00006462, + 0x00040006,0x00000456,0x00000014,0x00006767,0x00030005,0x00000458,0x0000006b,0x00060005, + 0x0000046a,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005,0x0000046d,0x495f6c67, + 0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005,0x00000471,0x00004254,0x00030005, + 0x00000472,0x00004255,0x00030005,0x00000485,0x00000049,0x00030005,0x0000048a,0x00006576, + 0x00040006,0x0000048a,0x00000000,0x00003464,0x00030005,0x0000048c,0x00004355,0x00030005, + 0x00000492,0x0000307a,0x00030005,0x000004a8,0x00006747,0x00030005,0x000004c6,0x00003153, + 0x00030005,0x000004c9,0x00006749,0x00030005,0x000004cc,0x00003159,0x00030005,0x000004d5, + 0x00006748,0x00030005,0x000004da,0x00006577,0x00040006,0x000004da,0x00000000,0x00003464, + 0x00030005,0x000004dc,0x0000424f,0x00030005,0x000004eb,0x0000304e,0x00030005,0x0000050b, + 0x0000316b,0x00060005,0x00000589,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006, + 0x00000589,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000589,0x00000001, + 0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000589,0x00000002,0x435f6c67, + 0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000589,0x00000003,0x435f6c67,0x446c6c75, + 0x61747369,0x0065636e,0x00030005,0x0000058b,0x00000000,0x00030005,0x00000599,0x00004351, + 0x00030005,0x0000059c,0x00003954,0x00040047,0x0000014f,0x00000021,0x00000008,0x00040047, + 0x0000014f,0x00000022,0x00000000,0x00040047,0x0000015e,0x00000006,0x00000010,0x00030047, + 0x0000015f,0x00000003,0x00040048,0x0000015f,0x00000000,0x00000018,0x00050048,0x0000015f, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000161,0x00000018,0x00040047,0x00000161, + 0x00000021,0x00000006,0x00040047,0x00000161,0x00000022,0x00000000,0x00040047,0x00000173, + 0x00000006,0x00000010,0x00030047,0x00000174,0x00000003,0x00040048,0x00000174,0x00000000, + 0x00000018,0x00050048,0x00000174,0x00000000,0x00000023,0x00000000,0x00030047,0x00000176, + 0x00000018,0x00040047,0x00000176,0x00000021,0x00000003,0x00040047,0x00000176,0x00000022, + 0x00000000,0x00030047,0x00000456,0x00000002,0x00050048,0x00000456,0x00000000,0x00000023, + 0x00000000,0x00050048,0x00000456,0x00000001,0x00000023,0x00000004,0x00050048,0x00000456, + 0x00000002,0x00000023,0x00000008,0x00050048,0x00000456,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x00000456,0x00000004,0x00000023,0x00000010,0x00050048,0x00000456,0x00000005, + 0x00000023,0x00000014,0x00050048,0x00000456,0x00000006,0x00000023,0x00000018,0x00050048, + 0x00000456,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000456,0x00000008,0x00000023, + 0x00000020,0x00050048,0x00000456,0x00000009,0x00000023,0x00000030,0x00050048,0x00000456, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x00000456,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x00000456,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000456,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x00000456,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x00000456,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000456,0x00000010,0x00000023, + 0x00000054,0x00050048,0x00000456,0x00000011,0x00000023,0x00000058,0x00050048,0x00000456, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x00000456,0x00000013,0x00000023,0x00000060, + 0x00050048,0x00000456,0x00000014,0x00000023,0x00000064,0x00040047,0x00000458,0x00000021, + 0x00000000,0x00040047,0x00000458,0x00000022,0x00000000,0x00040047,0x0000046a,0x0000000b, + 0x0000002a,0x00040047,0x0000046d,0x0000000b,0x0000002b,0x00040047,0x00000471,0x0000001e, + 0x00000000,0x00040047,0x00000472,0x0000001e,0x00000001,0x00040047,0x00000485,0x0000001e, + 0x00000002,0x00040047,0x00000489,0x00000006,0x00000008,0x00030047,0x0000048a,0x00000003, + 0x00040048,0x0000048a,0x00000000,0x00000018,0x00050048,0x0000048a,0x00000000,0x00000023, + 0x00000000,0x00030047,0x0000048c,0x00000018,0x00040047,0x0000048c,0x00000021,0x00000004, + 0x00040047,0x0000048c,0x00000022,0x00000000,0x00030047,0x00000492,0x00000000,0x00030047, + 0x00000492,0x0000000e,0x00040047,0x00000492,0x0000001e,0x00000003,0x00030047,0x000004a1, + 0x00000000,0x00030047,0x000004a2,0x00000000,0x00040047,0x000004a8,0x00000001,0x00000000, + 0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c6, + 0x0000000e,0x00040047,0x000004c6,0x0000001e,0x00000004,0x00040047,0x000004c9,0x00000001, + 0x00000002,0x00030047,0x000004cc,0x00000000,0x00030047,0x000004cc,0x0000000e,0x00040047, + 0x000004cc,0x0000001e,0x00000006,0x00040047,0x000004d5,0x00000001,0x00000001,0x00040047, + 0x000004d9,0x00000006,0x00000010,0x00030047,0x000004da,0x00000003,0x00040048,0x000004da, + 0x00000000,0x00000018,0x00050048,0x000004da,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000004dc,0x00000018,0x00040047,0x000004dc,0x00000021,0x00000005,0x00040047,0x000004dc, + 0x00000022,0x00000000,0x00040047,0x000004eb,0x0000001e,0x00000005,0x00030047,0x00000500, + 0x00000000,0x00030047,0x00000503,0x00000000,0x00030047,0x00000504,0x00000000,0x00040047, + 0x0000050b,0x0000001e,0x00000000,0x00030047,0x00000589,0x00000002,0x00050048,0x00000589, + 0x00000000,0x0000000b,0x00000000,0x00050048,0x00000589,0x00000001,0x0000000b,0x00000001, + 0x00050048,0x00000589,0x00000002,0x0000000b,0x00000003,0x00050048,0x00000589,0x00000003, + 0x0000000b,0x00000004,0x00030047,0x00000599,0x00000000,0x00040047,0x00000599,0x00000021, + 0x0000000a,0x00040047,0x00000599,0x00000022,0x00000000,0x00030047,0x0000059c,0x00000000, + 0x00040047,0x0000059c,0x00000021,0x0000000a,0x00040047,0x0000059c,0x00000022,0x00000000, + 0x00030047,0x00000751,0x00000000,0x00030047,0x00000a53,0x00000000,0x00030047,0x00000a55, + 0x00000000,0x00030047,0x00000a57,0x00000000,0x00030047,0x00000b71,0x00000000,0x00030047, + 0x00000bd7,0x00000000,0x00030047,0x00000bda,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006, + 0x00000002,0x00020014,0x00000011,0x00040017,0x00000013,0x00000011,0x00000002,0x00040017, + 0x00000018,0x00000006,0x00000004,0x00040018,0x0000001a,0x0000000c,0x00000002,0x00040015, + 0x0000001f,0x00000020,0x00000000,0x00040015,0x0000003a,0x00000020,0x00000001,0x00040017, + 0x0000003c,0x0000003a,0x00000002,0x0004002b,0x00000006,0x00000060,0x3f800000,0x0004002b, + 0x00000006,0x00000061,0x00000000,0x0004002b,0x0000001f,0x0000006c,0x00000000,0x0004002b, + 0x0000001f,0x00000073,0x000003ff,0x0004002b,0x0000001f,0x00000083,0x00000001,0x0004002b, + 0x0000003a,0x0000008f,0x00000000,0x0004002b,0x0000003a,0x00000093,0x00000001,0x0004002b, + 0x00000006,0x000000bb,0x3f000000,0x0004002b,0x00000006,0x000000cd,0x3fc90fdb,0x0004002b, + 0x00000006,0x000000d0,0x3a83126f,0x0004002b,0x00000006,0x000000df,0x358637bd,0x0004002b, + 0x00000006,0x000000fc,0x3e800000,0x0004002b,0x00000006,0x00000102,0xc0000000,0x0004002b, + 0x0000001f,0x00000106,0x00000002,0x0004002b,0x0000001f,0x00000109,0x00000003,0x0004002b, + 0x0000003a,0x0000010f,0x000007ff,0x0004002b,0x0000003a,0x00000112,0x0000000b,0x0004002b, + 0x0000003a,0x00000137,0x00000002,0x0004002b,0x0000003a,0x0000013d,0x00000003,0x00040017, + 0x0000014a,0x0000001f,0x00000004,0x00090019,0x0000014d,0x0000001f,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x0000014e,0x00000000,0x0000014d, + 0x0004003b,0x0000014e,0x0000014f,0x00000000,0x0004002b,0x0000001f,0x0000015a,0x0000ffff, + 0x0003001d,0x0000015e,0x0000014a,0x0003001e,0x0000015f,0x0000015e,0x00040020,0x00000160, + 0x00000002,0x0000015f,0x0004003b,0x00000160,0x00000161,0x00000002,0x00040020,0x00000164, + 0x00000002,0x0000014a,0x00040017,0x00000168,0x0000001f,0x00000002,0x0003001d,0x00000173, + 0x0000014a,0x0003001e,0x00000174,0x00000173,0x00040020,0x00000175,0x00000002,0x00000174, + 0x0004003b,0x00000175,0x00000176,0x00000002,0x0004002b,0x0000001f,0x00000178,0x00000004, + 0x0004002b,0x0000001f,0x00000193,0x00800000,0x0004002b,0x0000001f,0x000001b3,0x0080ffff, + 0x0004002b,0x0000001f,0x000001d3,0xff7fffff,0x0004002b,0x0000001f,0x000001d8,0x1c000000, + 0x0004002b,0x0000001f,0x000001da,0x04000000,0x0004002b,0x0000003a,0x000001ea,0x00000010, + 0x0004002b,0x00000006,0x0000022f,0x40490fdb,0x0004002b,0x00000006,0x00000233,0x40c90fdb, + 0x0004002b,0x00000006,0x00000268,0x40000000,0x0004002b,0x0000001f,0x000002a2,0x00100000, + 0x0004002b,0x0000001f,0x000002aa,0x00080000,0x0004002b,0x0000001f,0x000002f8,0x08000000, + 0x0004002b,0x0000001f,0x000002fe,0x00400000,0x0004002b,0x00000006,0x00000332,0xbf000000, + 0x0004002b,0x0000001f,0x00000349,0x14000000,0x0004002b,0x0000001f,0x0000034f,0x10000000, + 0x0004002b,0x0000001f,0x00000359,0x02000000,0x0004002b,0x0000001f,0x00000371,0x00200000, + 0x0004002b,0x00000006,0x0000037c,0x3e000000,0x0004002b,0x00000006,0x000003ca,0x38d1b717, + 0x0003002a,0x00000011,0x000003de,0x0004002b,0x00000006,0x000003e2,0xbf800000,0x0004002b, + 0x00000006,0x000003e9,0x49742400,0x0004002b,0x0000001f,0x00000433,0x01000000,0x0007002c, + 0x00000018,0x00000439,0x000003e2,0x00000060,0x00000060,0x00000060,0x0004002b,0x0000001f, + 0x00000442,0x80000000,0x0005002c,0x0000000c,0x00000454,0x00000060,0x000003e2,0x00040017, + 0x00000455,0x0000003a,0x00000004,0x0017001e,0x00000456,0x00000006,0x00000006,0x00000006, + 0x00000006,0x0000001f,0x0000001f,0x0000001f,0x0000001f,0x00000455,0x0000000c,0x0000000c, + 0x0000001f,0x00000006,0x0000001f,0x00000006,0x00000006,0x0000001f,0x00000006,0x00000006, + 0x00000006,0x0000001f,0x00040020,0x00000457,0x00000002,0x00000456,0x0004003b,0x00000457, + 0x00000458,0x00000002,0x0004002b,0x0000003a,0x00000459,0x00000014,0x00040020,0x0000045a, + 0x00000002,0x0000001f,0x00030029,0x00000011,0x00000465,0x00040020,0x00000469,0x00000001, + 0x0000003a,0x0004003b,0x00000469,0x0000046a,0x00000001,0x0004003b,0x00000469,0x0000046d, + 0x00000001,0x00040020,0x00000470,0x00000001,0x00000018,0x0004003b,0x00000470,0x00000471, + 0x00000001,0x0004003b,0x00000470,0x00000472,0x00000001,0x00040020,0x00000484,0x00000003, + 0x00000018,0x0004003b,0x00000484,0x00000485,0x00000003,0x0003001d,0x00000489,0x00000168, + 0x0003001e,0x0000048a,0x00000489,0x00040020,0x0000048b,0x00000002,0x0000048a,0x0004003b, + 0x0000048b,0x0000048c,0x00000002,0x00040020,0x0000048e,0x00000002,0x00000168,0x00040020, + 0x00000491,0x00000003,0x00000006,0x0004003b,0x00000491,0x00000492,0x00000003,0x0004002b, + 0x0000003a,0x00000493,0x0000000d,0x0004002b,0x0000001f,0x0000049c,0x00000200,0x0004002b, + 0x0000001f,0x000004a6,0x0000000f,0x00030030,0x00000011,0x000004a8,0x00040020,0x000004c5, + 0x00000003,0x0000000c,0x0004003b,0x000004c5,0x000004c6,0x00000003,0x00030030,0x00000011, + 0x000004c9,0x0004003b,0x00000491,0x000004cc,0x00000003,0x0004002b,0x0000003a,0x000004cf, + 0x00000004,0x00030030,0x00000011,0x000004d5,0x0003001d,0x000004d9,0x00000018,0x0003001e, + 0x000004da,0x000004d9,0x00040020,0x000004db,0x00000002,0x000004da,0x0004003b,0x000004db, + 0x000004dc,0x00000002,0x00040020,0x000004e1,0x00000002,0x00000018,0x0004003b,0x00000484, + 0x000004eb,0x00000003,0x00050034,0x00000011,0x000004fc,0x000000a8,0x000004c9,0x00040017, + 0x00000501,0x00000006,0x00000003,0x0004003b,0x00000484,0x0000050b,0x00000003,0x0004002b, + 0x00000006,0x00000543,0x3f666666,0x00040020,0x00000576,0x00000002,0x00000006,0x0004002b, + 0x0000003a,0x0000057e,0x0000000e,0x0004001c,0x00000588,0x00000006,0x00000083,0x0006001e, + 0x00000589,0x00000018,0x00000006,0x00000588,0x00000588,0x00040020,0x0000058a,0x00000003, + 0x00000589,0x0004003b,0x0000058a,0x0000058b,0x00000003,0x00090019,0x00000597,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000598, + 0x00000000,0x00000597,0x0004003b,0x00000598,0x00000599,0x00000000,0x0002001a,0x0000059a, + 0x00040020,0x0000059b,0x00000000,0x0000059a,0x0004003b,0x0000059b,0x0000059c,0x00000000, + 0x00030001,0x00000006,0x00000ad7,0x00030001,0x0000000c,0x00000bbe,0x0005002c,0x0000000c, + 0x00000bee,0x00000060,0x00000060,0x0005002c,0x0000000c,0x00000bef,0x000000bb,0x000000bb, + 0x0004002b,0x0000003a,0x00000bf1,0xfffffffe,0x0007002c,0x00000018,0x00000bf2,0x000000bb, + 0x000000bb,0x000000bb,0x000000bb,0x0004002b,0x00000006,0x00000bf3,0x3ea2f983,0x0004002b, + 0x00000006,0x00000bf4,0xc0400000,0x0003002e,0x0000000c,0x00000bf7,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000003a,0x0000046e, + 0x0000046d,0x0004003d,0x00000018,0x00000477,0x00000471,0x0004003d,0x00000018,0x00000479, + 0x00000472,0x000300f7,0x000008af,0x00000000,0x000300fb,0x0000006c,0x00000601,0x000200f8, + 0x00000601,0x00050051,0x00000006,0x00000603,0x00000477,0x00000000,0x0004006e,0x0000003a, + 0x00000604,0x00000603,0x00050051,0x00000006,0x00000606,0x00000477,0x00000001,0x00050051, + 0x00000006,0x00000608,0x00000477,0x00000002,0x00050051,0x00000006,0x0000060a,0x00000477, + 0x00000003,0x0004007c,0x0000003a,0x0000060b,0x0000060a,0x000500c3,0x0000003a,0x0000060c, + 0x0000060b,0x00000137,0x000500c7,0x0000003a,0x00000610,0x0000060b,0x0000013d,0x00050082, + 0x0000003a,0x00000613,0x0000060c,0x00000093,0x0007000c,0x0000003a,0x00000614,0x00000001, + 0x00000027,0x00000604,0x00000613,0x00050084,0x0000003a,0x00000617,0x0000046e,0x0000060c, + 0x00050080,0x0000003a,0x00000619,0x00000617,0x00000614,0x0004003d,0x0000014d,0x0000061a, + 0x0000014f,0x000500c7,0x0000003a,0x000008b4,0x00000619,0x0000010f,0x000500c3,0x0000003a, + 0x000008b6,0x00000619,0x00000112,0x00050050,0x0000003c,0x000008b7,0x000008b4,0x000008b6, + 0x0007005f,0x0000014a,0x0000061d,0x0000061a,0x000008b7,0x00000002,0x0000008f,0x00050051, + 0x0000001f,0x0000061f,0x0000061d,0x00000003,0x000500c7,0x0000001f,0x00000621,0x0000061f, + 0x0000015a,0x0007000c,0x0000001f,0x00000622,0x00000001,0x00000029,0x00000621,0x00000083, + 0x00050082,0x0000001f,0x00000624,0x00000622,0x00000083,0x00060041,0x00000164,0x00000625, + 0x00000161,0x0000008f,0x00000624,0x0004003d,0x0000014a,0x00000626,0x00000625,0x0007004f, + 0x00000168,0x00000628,0x00000626,0x00000626,0x00000000,0x00000001,0x0004007c,0x0000000c, + 0x00000629,0x00000628,0x00050051,0x0000001f,0x0000062b,0x00000626,0x00000002,0x000500c7, + 0x0000001f,0x0000062c,0x0000062b,0x0000015a,0x00050051,0x0000001f,0x0000062e,0x00000626, + 0x00000003,0x00050084,0x0000001f,0x00000630,0x0000062c,0x00000178,0x00060041,0x00000164, + 0x00000631,0x00000176,0x0000008f,0x00000630,0x0004003d,0x0000014a,0x00000632,0x00000631, + 0x0004007c,0x00000018,0x00000633,0x00000632,0x00050051,0x00000006,0x000008be,0x00000633, + 0x00000000,0x00050051,0x00000006,0x000008bf,0x00000633,0x00000001,0x00050051,0x00000006, + 0x000008c0,0x00000633,0x00000002,0x00050051,0x00000006,0x000008c1,0x00000633,0x00000003, + 0x00050050,0x0000000c,0x000008c2,0x000008be,0x000008bf,0x00050050,0x0000000c,0x000008c3, + 0x000008c0,0x000008c1,0x00050050,0x0000001a,0x000008c4,0x000008c2,0x000008c3,0x00050080, + 0x0000001f,0x00000637,0x00000630,0x00000083,0x00060041,0x00000164,0x00000638,0x00000176, + 0x0000008f,0x00000637,0x0004003d,0x0000014a,0x00000639,0x00000638,0x0007004f,0x00000168, + 0x0000063b,0x00000639,0x00000639,0x00000000,0x00000001,0x0004007c,0x0000000c,0x0000063c, + 0x0000063b,0x00050051,0x0000001f,0x0000063e,0x00000639,0x00000002,0x0004007c,0x00000006, + 0x0000063f,0x0000063e,0x00050051,0x0000001f,0x00000641,0x00000639,0x00000003,0x0004007c, + 0x00000006,0x00000642,0x00000641,0x000500c7,0x0000001f,0x00000644,0x0000061f,0x00000193, + 0x000500ab,0x00000011,0x00000646,0x00000644,0x0000006c,0x000300f7,0x0000064f,0x00000000, + 0x000400fa,0x00000646,0x00000647,0x0000064f,0x000200f8,0x00000647,0x00050051,0x00000006, + 0x00000649,0x00000479,0x00000000,0x0004006e,0x0000003a,0x0000064a,0x00000649,0x00050051, + 0x00000006,0x0000064c,0x00000479,0x00000001,0x00050051,0x00000006,0x0000064e,0x00000479, + 0x00000002,0x000200f9,0x0000064f,0x000200f8,0x0000064f,0x000700f5,0x00000006,0x00000abd, + 0x00000608,0x00000601,0x0000064e,0x00000647,0x000700f5,0x00000006,0x00000a7f,0x00000606, + 0x00000601,0x0000064c,0x00000647,0x000700f5,0x0000003a,0x00000a63,0x00000604,0x00000601, + 0x0000064a,0x00000647,0x000500ab,0x00000011,0x00000652,0x00000a63,0x00000614,0x000300f7, + 0x0000067f,0x00000000,0x000400fa,0x00000652,0x00000653,0x0000067f,0x000200f8,0x00000653, + 0x00050080,0x0000003a,0x00000656,0x00000619,0x00000a63,0x00050082,0x0000003a,0x00000658, + 0x00000656,0x00000614,0x0004003d,0x0000014d,0x00000659,0x0000014f,0x000500c7,0x0000003a, + 0x000008c8,0x00000658,0x0000010f,0x000500c3,0x0000003a,0x000008ca,0x00000658,0x00000112, + 0x00050050,0x0000003c,0x000008cb,0x000008c8,0x000008ca,0x0007005f,0x0000014a,0x0000065c, + 0x00000659,0x000008cb,0x00000002,0x0000008f,0x00050051,0x0000001f,0x0000065e,0x0000065c, + 0x00000003,0x000500c7,0x0000001f,0x0000065f,0x0000065e,0x000001b3,0x000500c7,0x0000001f, + 0x00000661,0x0000061f,0x000001b3,0x000500ab,0x00000011,0x00000662,0x0000065f,0x00000661, + 0x000300f7,0x00000679,0x00000000,0x000400fa,0x00000662,0x00000663,0x00000676,0x000200f8, + 0x00000676,0x000200f9,0x00000679,0x000200f8,0x00000663,0x000500b4,0x00000011,0x00000665, + 0x0000063f,0x00000061,0x000400a8,0x00000011,0x00000666,0x00000665,0x000300f7,0x0000066b, + 0x00000000,0x000400fa,0x00000666,0x00000667,0x0000066b,0x000200f8,0x00000667,0x00050051, + 0x00000006,0x00000669,0x00000629,0x00000000,0x000500b7,0x00000011,0x0000066a,0x00000669, + 0x00000061,0x000200f9,0x0000066b,0x000200f8,0x0000066b,0x000700f5,0x00000011,0x0000066c, + 0x00000665,0x00000663,0x0000066a,0x00000667,0x000300f7,0x00000675,0x00000000,0x000400fa, + 0x0000066c,0x0000066e,0x00000675,0x000200f8,0x0000066e,0x0004007c,0x0000003a,0x00000670, + 0x0000062e,0x0004003d,0x0000014d,0x00000671,0x0000014f,0x000500c7,0x0000003a,0x000008cf, + 0x00000670,0x0000010f,0x000500c3,0x0000003a,0x000008d1,0x00000670,0x00000112,0x00050050, + 0x0000003c,0x000008d2,0x000008cf,0x000008d1,0x0007005f,0x0000014a,0x00000674,0x00000671, + 0x000008d2,0x00000002,0x0000008f,0x000200f9,0x00000675,0x000200f8,0x00000675,0x000700f5, + 0x0000003a,0x00000a70,0x00000619,0x0000066b,0x00000670,0x0000066e,0x000700f5,0x0000014a, + 0x00000a68,0x0000061d,0x0000066b,0x00000674,0x0000066e,0x000200f9,0x00000679,0x000200f8, + 0x00000679,0x000700f5,0x0000003a,0x00000a6f,0x00000a70,0x00000675,0x00000658,0x00000676, + 0x000700f5,0x0000014a,0x00000a67,0x00000a68,0x00000675,0x0000065c,0x00000676,0x00050051, + 0x0000001f,0x0000067b,0x00000a67,0x00000003,0x000500c7,0x0000001f,0x0000067c,0x0000067b, + 0x000001d3,0x000500c5,0x0000001f,0x0000067e,0x0000067c,0x00000644,0x000200f9,0x0000067f, + 0x000200f8,0x0000067f,0x000700f5,0x0000003a,0x00000a6e,0x00000619,0x0000064f,0x00000a6f, + 0x00000679,0x000700f5,0x0000014a,0x00000a6c,0x0000061d,0x0000064f,0x00000a67,0x00000679, + 0x000700f5,0x0000001f,0x00000a6b,0x0000061f,0x0000064f,0x0000067e,0x00000679,0x000500c7, + 0x0000001f,0x00000681,0x00000a6b,0x000001d8,0x000500aa,0x00000011,0x00000682,0x00000681, + 0x000001da,0x000500aa,0x00000011,0x00000684,0x00000610,0x0000008f,0x000500a7,0x00000011, + 0x00000685,0x00000682,0x00000684,0x000300f7,0x00000710,0x00000000,0x000400fa,0x00000685, + 0x00000686,0x0000070c,0x000200f8,0x0000070c,0x00050051,0x0000001f,0x0000070e,0x00000a6c, + 0x00000002,0x0004007c,0x00000006,0x0000070f,0x0000070e,0x000200f9,0x00000710,0x000200f8, + 0x00000686,0x00050051,0x0000001f,0x00000688,0x00000a6c,0x00000002,0x000500c7,0x0000001f, + 0x0000068a,0x00000688,0x0000015a,0x00040070,0x00000006,0x0000068b,0x0000068a,0x000500c2, + 0x0000001f,0x0000068d,0x00000688,0x000001ea,0x00040070,0x00000006,0x0000068e,0x0000068d, + 0x00050083,0x00000006,0x00000691,0x000003e2,0x0000068b,0x0004006e,0x0000003a,0x00000692, + 0x00000691,0x00050083,0x00000006,0x00000695,0x0000068e,0x0000068b,0x00050081,0x00000006, + 0x00000696,0x00000695,0x00000060,0x0004006e,0x0000003a,0x00000697,0x00000696,0x00050050, + 0x0000003c,0x00000698,0x00000692,0x00000697,0x000500c7,0x0000001f,0x0000069a,0x00000a6b, + 0x00000193,0x000500ab,0x00000011,0x0000069b,0x0000069a,0x0000006c,0x000300f7,0x0000069f, + 0x00000000,0x000400fa,0x0000069b,0x0000069c,0x0000069f,0x000200f8,0x0000069c,0x0004007e, + 0x0000003c,0x0000069e,0x00000698,0x000200f9,0x0000069f,0x000200f8,0x0000069f,0x000700f5, + 0x0000003c,0x00000a72,0x00000698,0x00000686,0x0000069e,0x0000069c,0x0004003d,0x0000014d, + 0x000006a0,0x0000014f,0x00050051,0x0000003a,0x000006a3,0x00000a72,0x00000000,0x00050080, + 0x0000003a,0x000006a4,0x00000a6e,0x000006a3,0x000500c7,0x0000003a,0x000008d6,0x000006a4, + 0x0000010f,0x000500c3,0x0000003a,0x000008d8,0x000006a4,0x00000112,0x00050050,0x0000003c, + 0x000008d9,0x000008d6,0x000008d8,0x0007005f,0x0000014a,0x000006a6,0x000006a0,0x000008d9, + 0x00000002,0x0000008f,0x0004003d,0x0000014d,0x000006a7,0x0000014f,0x00050051,0x0000003a, + 0x000006aa,0x00000a72,0x00000001,0x00050080,0x0000003a,0x000006ab,0x00000a6e,0x000006aa, + 0x000500c7,0x0000003a,0x000008dd,0x000006ab,0x0000010f,0x000500c3,0x0000003a,0x000008df, + 0x000006ab,0x00000112,0x00050050,0x0000003c,0x000008e0,0x000008dd,0x000008df,0x0007005f, + 0x0000014a,0x000006ad,0x000006a7,0x000008e0,0x00000002,0x0000008f,0x00050051,0x0000001f, + 0x000006af,0x000006ad,0x00000003,0x000500c7,0x0000001f,0x000006b0,0x000006af,0x000001b3, + 0x00050051,0x0000001f,0x000006b2,0x000006a6,0x00000003,0x000500c7,0x0000001f,0x000006b3, + 0x000006b2,0x000001b3,0x000500ab,0x00000011,0x000006b4,0x000006b0,0x000006b3,0x000300f7, + 0x000006bb,0x00000000,0x000400fa,0x000006b4,0x000006b5,0x000006bb,0x000200f8,0x000006b5, + 0x0004003d,0x0000014d,0x000006b6,0x0000014f,0x0004007c,0x0000003a,0x000006b8,0x0000062e, + 0x000500c7,0x0000003a,0x000008e4,0x000006b8,0x0000010f,0x000500c3,0x0000003a,0x000008e6, + 0x000006b8,0x00000112,0x00050050,0x0000003c,0x000008e7,0x000008e4,0x000008e6,0x0007005f, + 0x0000014a,0x000006ba,0x000006b6,0x000008e7,0x00000002,0x0000008f,0x000200f9,0x000006bb, + 0x000200f8,0x000006bb,0x000700f5,0x0000014a,0x00000a73,0x000006ad,0x0000069f,0x000006ba, + 0x000006b5,0x00050051,0x0000001f,0x000006bd,0x000006a6,0x00000002,0x0004007c,0x00000006, + 0x000006be,0x000006bd,0x00050051,0x0000001f,0x000006c0,0x00000a73,0x00000002,0x0004007c, + 0x00000006,0x000006c1,0x000006c0,0x00050083,0x00000006,0x000006c4,0x000006c1,0x000006be, + 0x0006000c,0x00000006,0x000006c6,0x00000001,0x00000004,0x000006c4,0x000500ba,0x00000011, + 0x000006c7,0x000006c6,0x0000022f,0x000300f7,0x000006ce,0x00000000,0x000400fa,0x000006c7, + 0x000006c8,0x000006ce,0x000200f8,0x000006c8,0x0006000c,0x00000006,0x000006ca,0x00000001, + 0x00000006,0x000006c4,0x00050085,0x00000006,0x000006cb,0x00000233,0x000006ca,0x00050083, + 0x00000006,0x000006cd,0x000006c4,0x000006cb,0x000200f9,0x000006ce,0x000200f8,0x000006ce, + 0x000700f5,0x00000006,0x00000a77,0x000006c4,0x000006bb,0x000006cd,0x000006c8,0x00050081, + 0x00000006,0x000006d1,0x0000068e,0x00000102,0x0006000c,0x00000006,0x000006d3,0x00000001, + 0x00000004,0x00000a77,0x00050085,0x00000006,0x000006d4,0x000006d3,0x00000bf3,0x00050085, + 0x00000006,0x000006d6,0x000006d4,0x000006d1,0x0006000c,0x00000006,0x000006d7,0x00000001, + 0x00000001,0x000006d6,0x00050081,0x00000006,0x000006d9,0x0000068e,0x00000bf4,0x0008000c, + 0x00000006,0x000006da,0x00000001,0x0000002b,0x000006d7,0x00000060,0x000006d9,0x00050083, + 0x00000006,0x000006dd,0x000006d1,0x000006da,0x000500bc,0x00000011,0x000006e0,0x0000068b, + 0x000006dd,0x000300f7,0x000006fd,0x00000000,0x000400fa,0x000006e0,0x000006e1,0x000006f0, + 0x000200f8,0x000006f0,0x00050081,0x00000006,0x000006f3,0x000006dd,0x00000060,0x000500b4, + 0x00000011,0x000006f4,0x0000068b,0x000006f3,0x000300f7,0x000006fc,0x00000000,0x000400fa, + 0x000006f4,0x000006f5,0x000006f6,0x000200f8,0x000006f6,0x00050081,0x00000006,0x000006f8, + 0x000006dd,0x00000268,0x00050083,0x00000006,0x000006fa,0x0000068b,0x000006f8,0x000200f9, + 0x000006fc,0x000200f8,0x000006f5,0x000200f9,0x000006fc,0x000200f8,0x000006fc,0x000700f5, + 0x00000006,0x00000a85,0x00000061,0x000006f5,0x000006fa,0x000006f6,0x000600a9,0x00000006, + 0x00000bf8,0x000006f4,0x00000061,0x00000a7f,0x000600a9,0x00000006,0x00000bf9,0x000006f4, + 0x00000061,0x000006da,0x000200f9,0x000006fd,0x000200f8,0x000006e1,0x0006000c,0x00000006, + 0x000006e3,0x00000001,0x00000006,0x00000a77,0x00050085,0x00000006,0x000006e4,0x0000022f, + 0x000006e3,0x00050083,0x00000006,0x000006e6,0x000006e4,0x00000a77,0x0004007f,0x00000006, + 0x000006e7,0x000006e6,0x000500b4,0x00000011,0x000006eb,0x0000068b,0x000006dd,0x000300f7, + 0x000006ef,0x00000000,0x000400fa,0x000006eb,0x000006ec,0x000006ef,0x000200f8,0x000006ec, + 0x0004007f,0x00000006,0x000006ee,0x00000a7f,0x000200f9,0x000006ef,0x000200f8,0x000006ef, + 0x000700f5,0x00000006,0x00000ac7,0x00000a7f,0x000006e1,0x000006ee,0x000006ec,0x000200f9, + 0x000006fd,0x000200f8,0x000006fd,0x000700f5,0x00000006,0x00000ac6,0x00000ac7,0x000006ef, + 0x00000bf8,0x000006fc,0x000700f5,0x00000006,0x00000a8d,0x000006e7,0x000006ef,0x00000a77, + 0x000006fc,0x000700f5,0x00000006,0x00000a86,0x000006dd,0x000006ef,0x00000bf9,0x000006fc, + 0x000700f5,0x00000006,0x00000a83,0x0000068b,0x000006ef,0x00000a85,0x000006fc,0x000500b4, + 0x00000011,0x00000700,0x00000a83,0x00000a86,0x000300f7,0x0000070b,0x00000000,0x000400fa, + 0x00000700,0x00000701,0x00000703,0x000200f8,0x00000703,0x00050088,0x00000006,0x00000708, + 0x00000a83,0x00000a86,0x00050085,0x00000006,0x00000709,0x00000a8d,0x00000708,0x00050081, + 0x00000006,0x0000070a,0x000006be,0x00000709,0x000200f9,0x0000070b,0x000200f8,0x00000701, + 0x000200f9,0x0000070b,0x000200f8,0x0000070b,0x000700f5,0x00000006,0x00000a91,0x000006c1, + 0x00000701,0x0000070a,0x00000703,0x000200f9,0x00000710,0x000200f8,0x00000710,0x000700f5, + 0x00000006,0x00000adc,0x000006be,0x0000070b,0x00000ad7,0x0000070c,0x000700f5,0x00000006, + 0x00000ad3,0x00000a8d,0x0000070b,0x00000ad7,0x0000070c,0x000700f5,0x00000006,0x00000ac4, + 0x00000ac6,0x0000070b,0x00000a7f,0x0000070c,0x000700f5,0x00000006,0x00000a90,0x00000a91, + 0x0000070b,0x0000070f,0x0000070c,0x0006000c,0x00000006,0x00000712,0x00000001,0x0000000d, + 0x00000a90,0x0006000c,0x00000006,0x00000714,0x00000001,0x0000000e,0x00000a90,0x0004007f, + 0x00000006,0x00000715,0x00000714,0x00050050,0x0000000c,0x00000716,0x00000712,0x00000715, + 0x0007004f,0x00000168,0x00000718,0x00000a6c,0x00000a6c,0x00000000,0x00000001,0x0004007c, + 0x0000000c,0x00000719,0x00000718,0x000500b7,0x00000011,0x0000071b,0x00000642,0x00000061, + 0x000300f7,0x00000724,0x00000000,0x000400fa,0x0000071b,0x0000071c,0x00000724,0x000200f8, + 0x0000071c,0x00050091,0x0000000c,0x00000720,0x000008c4,0x00000716,0x0006000c,0x00000006, + 0x00000721,0x00000001,0x00000042,0x00000720,0x00050088,0x00000006,0x00000722,0x00000060, + 0x00000721,0x0007000c,0x00000006,0x00000723,0x00000001,0x00000028,0x00000642,0x00000722, + 0x000200f9,0x00000724,0x000200f8,0x00000724,0x000700f5,0x00000006,0x00000ac2,0x00000642, + 0x00000710,0x00000723,0x0000071c,0x000500b7,0x00000011,0x00000726,0x0000063f,0x00000061, + 0x000300f7,0x0000089c,0x00000000,0x000400fa,0x00000726,0x00000727,0x0000083c,0x000200f8, + 0x0000083c,0x00070050,0x00000018,0x0000083e,0x00000abd,0x000003e2,0x00000061,0x00000061, + 0x000500b7,0x00000011,0x00000840,0x00000ac2,0x00000061,0x000300f7,0x00000883,0x00000000, + 0x000400fa,0x00000840,0x00000841,0x0000087a,0x000200f8,0x0000087a,0x0005008e,0x0000000c, + 0x0000087d,0x00000716,0x00000ac4,0x0006000c,0x0000001a,0x0000087f,0x00000001,0x00000022, + 0x000008c4,0x00050090,0x0000000c,0x00000880,0x0000087d,0x0000087f,0x0006000c,0x0000000c, + 0x00000881,0x00000001,0x00000006,0x00000880,0x0005008e,0x0000000c,0x00000882,0x00000881, + 0x000000bb,0x000200f9,0x00000883,0x000200f8,0x00000841,0x00060052,0x00000018,0x00000a30, + 0x00000102,0x0000083e,0x00000001,0x00060052,0x00000018,0x00000a32,0x000003e9,0x00000a30, + 0x00000002,0x00060052,0x00000018,0x00000a34,0x00000abd,0x00000a32,0x00000003,0x000300f7, + 0x00000872,0x00000000,0x000400fa,0x00000685,0x0000084c,0x00000872,0x000200f8,0x0000084c, + 0x000500b8,0x00000011,0x0000084e,0x00000ad3,0x00000061,0x000300f7,0x00000855,0x00000000, + 0x000400fa,0x0000084e,0x0000084f,0x00000855,0x000200f8,0x0000084f,0x00050081,0x00000006, + 0x00000852,0x00000adc,0x00000ad3,0x0004007f,0x00000006,0x00000854,0x00000ad3,0x000200f9, + 0x00000855,0x000200f8,0x00000855,0x000700f5,0x00000006,0x00000ae6,0x00000ad3,0x0000084c, + 0x00000854,0x0000084f,0x000700f5,0x00000006,0x00000ae5,0x00000adc,0x0000084c,0x00000852, + 0x0000084f,0x00050083,0x00000006,0x00000858,0x00000a90,0x00000ae5,0x00050081,0x00000006, + 0x0000085a,0x00000858,0x000000cd,0x0005008d,0x00000006,0x0000085b,0x0000085a,0x00000233, + 0x00050083,0x00000006,0x0000085c,0x0000085b,0x000000cd,0x0008000c,0x00000006,0x0000085f, + 0x00000001,0x0000002b,0x0000085c,0x00000061,0x00000ae6,0x00050085,0x00000006,0x00000862, + 0x00000ae6,0x000000bb,0x000500ba,0x00000011,0x00000863,0x0000085f,0x00000862,0x000300f7, + 0x00000868,0x00000000,0x000400fa,0x00000863,0x00000864,0x00000868,0x000200f8,0x00000864, + 0x00050083,0x00000006,0x00000867,0x00000ae6,0x0000085f,0x000200f9,0x00000868,0x000200f8, + 0x00000868,0x000700f5,0x00000006,0x00000ae7,0x0000085f,0x00000855,0x00000867,0x00000864, + 0x0006000c,0x00000006,0x0000086a,0x00000001,0x0000000d,0x00000ae7,0x0006000c,0x00000006, + 0x0000086c,0x00000001,0x0000000e,0x00000ae7,0x00050050,0x0000000c,0x0000086d,0x0000086a, + 0x0000086c,0x0006000c,0x00000006,0x0000092b,0x00000001,0x00000004,0x00000ac4,0x0005008e, + 0x0000000c,0x0000092c,0x0000086d,0x0000092b,0x00050083,0x0000000c,0x0000092e,0x00000bee, + 0x0000092c,0x0005008e,0x0000000c,0x0000092f,0x0000092e,0x000000bb,0x00050083,0x00000006, + 0x00000931,0x00000ae6,0x000000cd,0x0006000c,0x00000006,0x00000932,0x00000001,0x00000004, + 0x00000931,0x000500b8,0x00000011,0x00000933,0x00000932,0x000000d0,0x000300f7,0x00000954, + 0x00000000,0x000400fa,0x00000933,0x00000934,0x00000935,0x000200f8,0x00000935,0x0006000c, + 0x00000006,0x00000937,0x00000001,0x0000000f,0x00000ae6,0x00050083,0x00000006,0x00000939, + 0x000000cd,0x00000ae6,0x0006000c,0x00000006,0x0000093a,0x00000001,0x00000006,0x00000939, + 0x0006000c,0x00000006,0x0000093c,0x00000001,0x00000004,0x00000937,0x0007000c,0x00000006, + 0x0000093d,0x00000001,0x00000028,0x0000093c,0x000000df,0x00050088,0x00000006,0x0000093e, + 0x0000093a,0x0000093d,0x000500be,0x00000011,0x00000940,0x0000093e,0x00000061,0x000300f7, + 0x00000952,0x00000000,0x000400fa,0x00000940,0x00000941,0x0000094a,0x000200f8,0x0000094a, + 0x00050051,0x00000006,0x0000094c,0x0000092f,0x00000001,0x00050051,0x00000006,0x0000094e, + 0x0000092f,0x00000000,0x00050085,0x00000006,0x00000950,0x0000094e,0x00000937,0x00050081, + 0x00000006,0x00000951,0x0000094c,0x00000950,0x000200f9,0x00000952,0x000200f8,0x00000941, + 0x00050051,0x00000006,0x00000943,0x0000092f,0x00000001,0x00050051,0x00000006,0x00000945, + 0x0000092f,0x00000000,0x00050083,0x00000006,0x00000946,0x00000060,0x00000945,0x00050085, + 0x00000006,0x00000948,0x00000946,0x00000937,0x00050083,0x00000006,0x00000949,0x00000943, + 0x00000948,0x000200f9,0x00000952,0x000200f8,0x00000952,0x000700f5,0x00000006,0x00000aeb, + 0x00000949,0x00000941,0x00000951,0x0000094a,0x000200f9,0x00000954,0x000200f8,0x00000934, + 0x000200f9,0x00000954,0x000200f8,0x00000954,0x000700f5,0x00000006,0x00000b01,0x00000061, + 0x00000934,0x00000aeb,0x00000952,0x000700f5,0x00000006,0x00000aff,0x00000061,0x00000934, + 0x0000093e,0x00000952,0x00050051,0x00000006,0x00000956,0x0000092f,0x00000000,0x0007000c, + 0x00000006,0x00000957,0x00000001,0x00000028,0x00000956,0x00000061,0x00050081,0x00000006, + 0x00000958,0x00000957,0x000000fc,0x00050051,0x00000006,0x0000095b,0x0000092f,0x00000001, + 0x00050083,0x00000006,0x0000095d,0x00000102,0x0000095b,0x00070050,0x00000018,0x00000bf5, + 0x00000958,0x0000095d,0x00000aff,0x00000b01,0x000200f9,0x00000872,0x000200f8,0x00000872, + 0x000700f5,0x00000018,0x00000b11,0x00000a34,0x00000841,0x00000bf5,0x00000954,0x00050085, + 0x00000006,0x00000876,0x00000ac4,0x00000ac2,0x0005008e,0x0000000c,0x00000878,0x00000716, + 0x00000876,0x00050091,0x0000000c,0x00000879,0x000008c4,0x00000878,0x000200f9,0x00000883, + 0x000200f8,0x00000883,0x000700f5,0x0000000c,0x00000ba7,0x00000879,0x00000872,0x00000882, + 0x0000087a,0x000700f5,0x00000018,0x00000b10,0x00000b11,0x00000872,0x0000083e,0x0000087a, + 0x000500c7,0x0000001f,0x00000885,0x00000a6b,0x00000193,0x000500ab,0x00000011,0x00000886, + 0x00000885,0x0000006c,0x000500c7,0x0000001f,0x00000888,0x00000a6b,0x00000433,0x000500ab, + 0x00000011,0x00000889,0x00000888,0x0000006c,0x000500a5,0x00000011,0x0000088a,0x00000886, + 0x00000889,0x000300f7,0x0000088e,0x00000000,0x000400fa,0x0000088a,0x0000088b,0x0000088e, + 0x000200f8,0x0000088b,0x00050085,0x00000018,0x0000088d,0x00000b10,0x00000439,0x000200f9, + 0x0000088e,0x000200f8,0x0000088e,0x000700f5,0x00000018,0x00000bab,0x00000b10,0x00000883, + 0x0000088d,0x0000088b,0x000500aa,0x00000011,0x00000890,0x00000610,0x00000137,0x00050050, + 0x00000013,0x00000bfa,0x00000890,0x00000890,0x000600a9,0x0000000c,0x00000bfb,0x00000bfa, + 0x00000629,0x00000719,0x000500c7,0x0000001f,0x00000895,0x00000a6b,0x00000442,0x000500ab, + 0x00000011,0x00000896,0x00000895,0x0000006c,0x000500ab,0x00000011,0x00000898,0x00000610, + 0x00000093,0x000500a7,0x00000011,0x00000899,0x00000896,0x00000898,0x000300f7,0x0000089b, + 0x00000000,0x000400fa,0x00000899,0x0000089a,0x0000089b,0x000200f8,0x0000089a,0x000200f9, + 0x000008af,0x000200f8,0x0000089b,0x000200f9,0x0000089c,0x000200f8,0x00000727,0x0006000c, + 0x00000006,0x00000729,0x00000001,0x00000021,0x000008c4,0x0006000c,0x00000006,0x0000072a, + 0x00000001,0x00000006,0x00000729,0x00050085,0x00000006,0x0000072c,0x00000ac4,0x0000072a, + 0x000500c7,0x0000001f,0x0000072e,0x00000a6b,0x000002a2,0x000500ab,0x00000011,0x0000072f, + 0x0000072e,0x0000006c,0x000300f7,0x00000733,0x00000000,0x000400fa,0x0000072f,0x00000730, + 0x00000733,0x000200f8,0x00000730,0x0007000c,0x00000006,0x00000732,0x00000001,0x00000025, + 0x0000072c,0x00000061,0x000200f9,0x00000733,0x000200f8,0x00000733,0x000700f5,0x00000006, + 0x00000b15,0x0000072c,0x00000727,0x00000732,0x00000730,0x000500c7,0x0000001f,0x00000735, + 0x00000a6b,0x000002aa,0x000500ab,0x00000011,0x00000736,0x00000735,0x0000006c,0x000300f7, + 0x0000073a,0x00000000,0x000400fa,0x00000736,0x00000737,0x0000073a,0x000200f8,0x00000737, + 0x0007000c,0x00000006,0x00000739,0x00000001,0x00000028,0x00000b15,0x00000061,0x000200f9, + 0x0000073a,0x000200f8,0x0000073a,0x000700f5,0x00000006,0x00000b20,0x00000b15,0x00000733, + 0x00000739,0x00000737,0x000500b7,0x00000011,0x0000073c,0x00000ac2,0x00000061,0x000300f7, + 0x00000744,0x00000000,0x000400fa,0x0000073c,0x0000073d,0x0000073f,0x000200f8,0x0000073f, + 0x00050091,0x0000000c,0x000008ed,0x000008c4,0x00000716,0x00050051,0x00000006,0x000008ef, + 0x000008ed,0x00000000,0x0006000c,0x00000006,0x000008f0,0x00000001,0x00000004,0x000008ef, + 0x00050051,0x00000006,0x000008f2,0x000008ed,0x00000001,0x0006000c,0x00000006,0x000008f3, + 0x00000001,0x00000004,0x000008f2,0x00050081,0x00000006,0x000008f4,0x000008f0,0x000008f3, + 0x00050094,0x00000006,0x000008f7,0x000008ed,0x000008ed,0x00050088,0x00000006,0x000008f8, + 0x00000060,0x000008f7,0x00050085,0x00000006,0x000008f9,0x000008f4,0x000008f8,0x00050085, + 0x00000006,0x00000743,0x000008f9,0x000000bb,0x000200f9,0x00000744,0x000200f8,0x0000073d, + 0x000200f9,0x00000744,0x000200f8,0x00000744,0x000700f5,0x00000006,0x00000b18,0x00000ac2, + 0x0000073d,0x00000743,0x0000073f,0x000500ba,0x00000011,0x00000748,0x00000b18,0x0000063f, + 0x000500b4,0x00000011,0x0000074a,0x00000ac2,0x00000061,0x000500a7,0x00000011,0x0000074b, + 0x00000748,0x0000074a,0x000300f7,0x00000753,0x00000000,0x000400fa,0x0000074b,0x0000074c, + 0x00000753,0x000200f8,0x0000074c,0x00050088,0x00000006,0x00000751,0x0000063f,0x00000b18, + 0x000200f9,0x00000753,0x000200f8,0x00000753,0x000700f5,0x00000006,0x00000b71,0x00000060, + 0x00000744,0x00000751,0x0000074c,0x000600a9,0x00000006,0x00000bfc,0x0000074b,0x00000b18, + 0x0000063f,0x00050081,0x00000006,0x00000757,0x00000bfc,0x00000b18,0x0005008e,0x0000000c, + 0x00000758,0x00000716,0x00000757,0x00050085,0x00000006,0x0000075d,0x00000b20,0x00000757, + 0x00050088,0x00000006,0x00000760,0x000000bb,0x00000b18,0x0004007f,0x00000006,0x00000763, + 0x0000075d,0x00050050,0x0000000c,0x00000764,0x0000075d,0x00000763,0x00050050,0x0000000c, + 0x00000766,0x00000bfc,0x00000bfc,0x00050081,0x0000000c,0x00000767,0x00000764,0x00000766, + 0x0005008e,0x0000000c,0x00000768,0x00000767,0x00000760,0x00050081,0x0000000c,0x0000076a, + 0x00000768,0x00000bef,0x00050051,0x00000006,0x0000076c,0x0000076a,0x00000000,0x00050051, + 0x00000006,0x0000076e,0x0000076a,0x00000001,0x00070050,0x00000018,0x00000bf6,0x0000076c, + 0x0000076e,0x00000061,0x00000061,0x000500ac,0x00000011,0x00000777,0x00000681,0x000002f8, + 0x000300f7,0x0000081e,0x00000000,0x000400fa,0x00000777,0x00000778,0x0000081e,0x000200f8, + 0x00000778,0x000500c7,0x0000001f,0x0000077a,0x00000a6b,0x000002fe,0x000500aa,0x00000011, + 0x0000077b,0x0000077a,0x0000006c,0x000600a9,0x0000003a,0x00000bfd,0x0000077b,0x00000bf1, + 0x00000137,0x000500c7,0x0000001f,0x00000781,0x00000a6b,0x00000193,0x000500ab,0x00000011, + 0x00000782,0x00000781,0x0000006c,0x000300f7,0x00000786,0x00000000,0x000400fa,0x00000782, + 0x00000783,0x00000786,0x000200f8,0x00000783,0x0004007e,0x0000003a,0x00000785,0x00000bfd, + 0x000200f9,0x00000786,0x000200f8,0x00000786,0x000700f5,0x0000003a,0x00000b46,0x00000bfd, + 0x00000778,0x00000785,0x00000783,0x00050080,0x0000003a,0x00000789,0x00000a6e,0x00000b46, + 0x000500c7,0x0000003a,0x0000090b,0x00000789,0x0000010f,0x000500c3,0x0000003a,0x0000090d, + 0x00000789,0x00000112,0x00050050,0x0000003c,0x0000090e,0x0000090b,0x0000090d,0x0004003d, + 0x0000014d,0x0000078b,0x0000014f,0x0007005f,0x0000014a,0x0000078d,0x0000078b,0x0000090e, + 0x00000002,0x0000008f,0x00050051,0x0000001f,0x0000078f,0x0000078d,0x00000002,0x0004007c, + 0x00000006,0x00000790,0x0000078f,0x00050083,0x00000006,0x00000793,0x00000790,0x00000a90, + 0x0006000c,0x00000006,0x00000794,0x00000001,0x00000004,0x00000793,0x000500ba,0x00000011, + 0x00000796,0x00000794,0x0000022f,0x000300f7,0x0000079a,0x00000000,0x000400fa,0x00000796, + 0x00000797,0x0000079a,0x000200f8,0x00000797,0x00050083,0x00000006,0x00000799,0x00000233, + 0x00000794,0x000200f9,0x0000079a,0x000200f8,0x0000079a,0x000700f5,0x00000006,0x00000b4f, + 0x00000794,0x00000786,0x00000799,0x00000797,0x000500ab,0x00000011,0x0000079d,0x0000077a, + 0x0000006c,0x000500a4,0x00000011,0x000007a4,0x0000079d,0x0000072f,0x000600a9,0x00000006, + 0x000007a5,0x000007a4,0x00000332,0x000000bb,0x00050085,0x00000006,0x000007a6,0x00000b4f, + 0x000007a5,0x00050081,0x00000006,0x000007a8,0x000007a6,0x00000a90,0x0006000c,0x00000006, + 0x000007aa,0x00000001,0x0000000d,0x000007a8,0x0006000c,0x00000006,0x000007ac,0x00000001, + 0x0000000e,0x000007a8,0x0004007f,0x00000006,0x000007ad,0x000007ac,0x00050050,0x0000000c, + 0x000007ae,0x000007aa,0x000007ad,0x00050091,0x0000000c,0x00000914,0x000008c4,0x000007ae, + 0x00050051,0x00000006,0x00000916,0x00000914,0x00000000,0x0006000c,0x00000006,0x00000917, + 0x00000001,0x00000004,0x00000916,0x00050051,0x00000006,0x00000919,0x00000914,0x00000001, + 0x0006000c,0x00000006,0x0000091a,0x00000001,0x00000004,0x00000919,0x00050081,0x00000006, + 0x0000091b,0x00000917,0x0000091a,0x00050094,0x00000006,0x0000091e,0x00000914,0x00000914, + 0x00050088,0x00000006,0x0000091f,0x00000060,0x0000091e,0x00050085,0x00000006,0x00000920, + 0x0000091b,0x0000091f,0x00050085,0x00000006,0x000007b3,0x00000b4f,0x000000bb,0x0006000c, + 0x00000006,0x000007b4,0x00000001,0x0000000e,0x000007b3,0x000500aa,0x00000011,0x000007b6, + 0x00000681,0x00000349,0x000400a8,0x00000011,0x000007b7,0x000007b6,0x000300f7,0x000007be, + 0x00000000,0x000400fa,0x000007b7,0x000007b8,0x000007be,0x000200f8,0x000007b8,0x000500aa, + 0x00000011,0x000007ba,0x00000681,0x0000034f,0x000500be,0x00000011,0x000007bc,0x000007b4, + 0x000000fc,0x000500a7,0x00000011,0x000007bd,0x000007ba,0x000007bc,0x000200f9,0x000007be, + 0x000200f8,0x000007be,0x000700f5,0x00000011,0x000007bf,0x000007b6,0x0000079a,0x000007bd, + 0x000007b8,0x000300f7,0x000007d2,0x00000000,0x000400fa,0x000007bf,0x000007c0,0x000007cb, + 0x000200f8,0x000007cb,0x00050085,0x00000006,0x000007ce,0x00000bfc,0x000007b4,0x00050085, + 0x00000006,0x000007d0,0x00000920,0x000000bb,0x00050081,0x00000006,0x000007d1,0x000007ce, + 0x000007d0,0x000200f9,0x000007d2,0x000200f8,0x000007c0,0x000500c7,0x0000001f,0x000007c2, + 0x00000a6b,0x00000359,0x000500ab,0x00000011,0x000007c3,0x000007c2,0x0000006c,0x000600a9, + 0x00000006,0x000007c4,0x000007c3,0x00000060,0x000000fc,0x0007000c,0x00000006,0x000007c8, + 0x00000001,0x00000028,0x000007b4,0x000007c4,0x00050088,0x00000006,0x000007c9,0x00000060, + 0x000007c8,0x00050085,0x00000006,0x000007ca,0x00000bfc,0x000007c9,0x000200f9,0x000007d2, + 0x000200f8,0x000007d2,0x000700f5,0x00000006,0x00000b56,0x000007ca,0x000007c0,0x000007d1, + 0x000007cb,0x00050085,0x00000006,0x000007d5,0x00000920,0x000000bb,0x00050081,0x00000006, + 0x000007d6,0x00000b56,0x000007d5,0x000500c7,0x0000001f,0x000007d8,0x00000a6b,0x00000371, + 0x000500ab,0x00000011,0x000007d9,0x000007d8,0x0000006c,0x000300f7,0x00000807,0x00000000, + 0x000400fa,0x000007d9,0x000007da,0x00000807,0x000200f8,0x000007da,0x00050085,0x00000006, + 0x000007df,0x00000b18,0x0000037c,0x00050085,0x00000006,0x000007e3,0x000007d6,0x000007b4, + 0x00050081,0x00000006,0x000007e5,0x000007e3,0x000007df,0x000500bc,0x00000011,0x000007e6, + 0x00000757,0x000007e5,0x000300f7,0x00000806,0x00000000,0x000400fa,0x000007e6,0x000007e7, + 0x000007ef,0x000200f8,0x000007ef,0x0005008e,0x0000000c,0x000007f2,0x000007ae,0x000007d6, + 0x00050094,0x00000006,0x000007f5,0x00000758,0x00000758,0x00050094,0x00000006,0x000007f8, + 0x000007f2,0x000007f2,0x00050050,0x0000000c,0x000007f9,0x000007f5,0x000007f8,0x00050050, + 0x0000001a,0x00000803,0x00000758,0x000007f2,0x0006000c,0x0000001a,0x00000804,0x00000001, + 0x00000022,0x00000803,0x00050090,0x0000000c,0x00000805,0x000007f9,0x00000804,0x000200f9, + 0x00000806,0x000200f8,0x000007e7,0x00050088,0x00000006,0x000007ea,0x00000060,0x000007b4, + 0x00050085,0x00000006,0x000007eb,0x00000757,0x000007ea,0x0005008e,0x0000000c,0x000007ee, + 0x000007ae,0x000007eb,0x000200f9,0x00000806,0x000200f8,0x00000806,0x000700f5,0x0000000c, + 0x00000b66,0x000007ee,0x000007e7,0x00000805,0x000007ef,0x000200f9,0x00000807,0x000200f8, + 0x00000807,0x000700f5,0x0000000c,0x00000b65,0x00000758,0x000007d2,0x00000b66,0x00000806, + 0x0006000c,0x00000006,0x00000809,0x00000001,0x00000004,0x00000b20,0x0005008e,0x0000000c, + 0x0000080b,0x00000b65,0x00000809,0x00050094,0x00000006,0x0000080f,0x0000080b,0x000007ae, + 0x00050083,0x00000006,0x00000810,0x000007d6,0x0000080f,0x00050088,0x00000006,0x00000813, + 0x00000810,0x00000920,0x000300f7,0x0000081d,0x00000000,0x000400fa,0x0000072f,0x00000817, + 0x0000081a,0x000200f8,0x0000081a,0x00060052,0x00000018,0x00000a24,0x00000813,0x00000bf6, + 0x00000000,0x000200f9,0x0000081d,0x000200f8,0x00000817,0x00060052,0x00000018,0x00000a22, + 0x00000813,0x00000bf6,0x00000001,0x000200f9,0x0000081d,0x000200f8,0x0000081d,0x000700f5, + 0x00000018,0x00000b7b,0x00000a22,0x00000817,0x00000a24,0x0000081a,0x000200f9,0x0000081e, + 0x000200f8,0x0000081e,0x000700f5,0x0000000c,0x00000b8a,0x00000758,0x00000753,0x00000b65, + 0x0000081d,0x000700f5,0x00000018,0x00000b7a,0x00000bf6,0x00000753,0x00000b7b,0x0000081d, + 0x0007004f,0x0000000c,0x00000821,0x00000b7a,0x00000b7a,0x00000000,0x00000001,0x0005008e, + 0x0000000c,0x00000822,0x00000821,0x00000b71,0x00050051,0x00000006,0x00000824,0x00000822, + 0x00000000,0x00060052,0x00000018,0x00000a26,0x00000824,0x00000b7a,0x00000000,0x00050051, + 0x00000006,0x00000826,0x00000822,0x00000001,0x0007000c,0x00000006,0x00000829,0x00000001, + 0x00000028,0x00000826,0x000003ca,0x00060052,0x00000018,0x00000a2b,0x00000829,0x00000a26, + 0x00000001,0x000300f7,0x00000832,0x00000000,0x000400fa,0x0000073c,0x0000082d,0x00000832, + 0x000200f8,0x0000082d,0x00050083,0x00000006,0x00000830,0x00000102,0x00000824,0x00060052, + 0x00000018,0x00000a2e,0x00000830,0x00000a2b,0x00000000,0x000200f9,0x00000832,0x000200f8, + 0x00000832,0x000700f5,0x00000018,0x00000ba9,0x00000a2b,0x0000081e,0x00000a2e,0x0000082d, + 0x0005008e,0x0000000c,0x00000836,0x00000b8a,0x00000b20,0x00050091,0x0000000c,0x00000837, + 0x000008c4,0x00000836,0x000500ab,0x00000011,0x00000839,0x00000610,0x0000008f,0x000300f7, + 0x0000083b,0x00000000,0x000400fa,0x00000839,0x0000083a,0x0000083b,0x000200f8,0x0000083a, + 0x000200f9,0x000008af,0x000200f8,0x0000083b,0x000200f9,0x0000089c,0x000200f8,0x0000089c, + 0x000700f5,0x00000018,0x00000ba8,0x00000ba9,0x0000083b,0x00000bab,0x0000089b,0x000700f5, + 0x0000000c,0x00000ba4,0x00000837,0x0000083b,0x00000ba7,0x0000089b,0x000700f5,0x0000000c, + 0x00000b8c,0x00000719,0x0000083b,0x00000bfb,0x0000089b,0x00050091,0x0000000c,0x0000089f, + 0x000008c4,0x00000b8c,0x00050081,0x0000000c,0x000008a1,0x0000089f,0x00000ba4,0x00050081, + 0x0000000c,0x000008a3,0x000008a1,0x0000063c,0x0007004f,0x0000000c,0x000008a5,0x00000ba8, + 0x00000ba8,0x00000000,0x00000001,0x00050041,0x0000045a,0x000008a6,0x00000458,0x00000459, + 0x0004003d,0x0000001f,0x000008a7,0x000008a6,0x000500ab,0x00000011,0x000008a8,0x000008a7, + 0x0000006c,0x00050050,0x00000013,0x00000968,0x000008a8,0x000008a8,0x000600a9,0x0000000c, + 0x000008aa,0x00000968,0x00000454,0x000008a5,0x00050051,0x00000006,0x000008ac,0x000008aa, + 0x00000000,0x00060052,0x00000018,0x00000a44,0x000008ac,0x00000ba8,0x00000000,0x00050051, + 0x00000006,0x000008ae,0x000008aa,0x00000001,0x00060052,0x00000018,0x00000a46,0x000008ae, + 0x00000a44,0x00000001,0x000200f9,0x000008af,0x000200f8,0x000008af,0x000900f5,0x00000018, + 0x00000bd3,0x00000ba9,0x0000083a,0x00000bab,0x0000089a,0x00000a46,0x0000089c,0x000900f5, + 0x0000000c,0x00000bad,0x00000bbe,0x0000083a,0x00000bbe,0x0000089a,0x000008a3,0x0000089c, + 0x000900f5,0x00000011,0x00000bac,0x000003de,0x0000083a,0x000003de,0x0000089a,0x00000465, + 0x0000089c,0x0003003e,0x00000485,0x00000bd3,0x00060041,0x0000048e,0x0000048f,0x0000048c, + 0x0000008f,0x0000062c,0x0004003d,0x00000168,0x00000490,0x0000048f,0x00050041,0x0000045a, + 0x00000497,0x00000458,0x00000493,0x0004003d,0x0000001f,0x00000498,0x00000497,0x000500aa, + 0x00000011,0x0000096e,0x0000062c,0x0000006c,0x000300f7,0x00000977,0x00000000,0x000400fa, + 0x0000096e,0x0000096f,0x00000970,0x000200f8,0x00000970,0x00050080,0x0000001f,0x00000972, + 0x0000062c,0x00000073,0x00050084,0x0000001f,0x00000974,0x00000972,0x00000498,0x0006000c, + 0x0000000c,0x00000975,0x00000001,0x0000003e,0x00000974,0x00050051,0x00000006,0x00000976, + 0x00000975,0x00000000,0x000200f9,0x00000977,0x000200f8,0x0000096f,0x000200f9,0x00000977, + 0x000200f8,0x00000977,0x000700f5,0x00000006,0x00000bd4,0x00000061,0x0000096f,0x00000976, + 0x00000970,0x0003003e,0x00000492,0x00000bd4,0x00050051,0x0000001f,0x0000049b,0x00000490, + 0x00000000,0x000500c7,0x0000001f,0x0000049d,0x0000049b,0x0000049c,0x000500ab,0x00000011, + 0x0000049e,0x0000049d,0x0000006c,0x000300f7,0x000004a0,0x00000000,0x000400fa,0x0000049e, + 0x0000049f,0x000004a0,0x000200f8,0x0000049f,0x0004003d,0x00000006,0x000004a1,0x00000492, + 0x0004007f,0x00000006,0x000004a2,0x000004a1,0x0003003e,0x00000492,0x000004a2,0x000200f9, + 0x000004a0,0x000200f8,0x000004a0,0x000500c7,0x0000001f,0x000004a7,0x0000049b,0x000004a6, + 0x000300f7,0x000004aa,0x00000000,0x000400fa,0x000004a8,0x000004a9,0x000004aa,0x000200f8, + 0x000004a9,0x000500aa,0x00000011,0x000004ad,0x000004a7,0x0000006c,0x000300f7,0x000004b0, + 0x00000000,0x000400fa,0x000004ad,0x000004af,0x000004b3,0x000200f8,0x000004b3,0x000200f9, + 0x000004b0,0x000200f8,0x000004af,0x00050051,0x0000001f,0x000004b2,0x00000490,0x00000001, + 0x000200f9,0x000004b0,0x000200f8,0x000004b0,0x000700f5,0x0000001f,0x00000bd5,0x000004b2, + 0x000004af,0x0000049b,0x000004b3,0x000500c2,0x0000001f,0x000004b7,0x00000bd5,0x000001ea, + 0x000500aa,0x00000011,0x0000097f,0x000004b7,0x0000006c,0x000300f7,0x00000988,0x00000000, + 0x000400fa,0x0000097f,0x00000980,0x00000981,0x000200f8,0x00000981,0x00050080,0x0000001f, + 0x00000983,0x000004b7,0x00000073,0x00050084,0x0000001f,0x00000985,0x00000983,0x00000498, + 0x0006000c,0x0000000c,0x00000986,0x00000001,0x0000003e,0x00000985,0x00050051,0x00000006, + 0x00000987,0x00000986,0x00000000,0x000200f9,0x00000988,0x000200f8,0x00000980,0x000200f9, + 0x00000988,0x000200f8,0x00000988,0x000700f5,0x00000006,0x00000bd6,0x00000061,0x00000980, + 0x00000987,0x00000981,0x000300f7,0x000004c2,0x00000000,0x000400fa,0x000004ad,0x000004c1, + 0x000004c2,0x000200f8,0x000004c1,0x0004007f,0x00000006,0x000004c4,0x00000bd6,0x000200f9, + 0x000004c2,0x000200f8,0x000004c2,0x000700f5,0x00000006,0x00000bd7,0x00000bd6,0x00000988, + 0x000004c4,0x000004c1,0x00050041,0x00000491,0x000004c8,0x000004c6,0x0000006c,0x0003003e, + 0x000004c8,0x00000bd7,0x000200f9,0x000004aa,0x000200f8,0x000004aa,0x000300f7,0x000004cb, + 0x00000000,0x000400fa,0x000004c9,0x000004ca,0x000004cb,0x000200f8,0x000004ca,0x000500c2, + 0x0000001f,0x000004d0,0x0000049b,0x000004cf,0x000500c7,0x0000001f,0x000004d1,0x000004d0, + 0x000004a6,0x00040070,0x00000006,0x000004d2,0x000004d1,0x0003003e,0x000004cc,0x000004d2, + 0x000200f9,0x000004cb,0x000200f8,0x000004cb,0x000300f7,0x000004d7,0x00000000,0x000400fa, + 0x000004d5,0x000004d6,0x000004d7,0x000200f8,0x000004d6,0x00050080,0x0000001f,0x000004df, + 0x00000630,0x00000106,0x00060041,0x000004e1,0x000004e2,0x000004dc,0x0000008f,0x000004df, + 0x0004003d,0x00000018,0x000004e3,0x000004e2,0x00050051,0x00000006,0x00000991,0x000004e3, + 0x00000000,0x00050051,0x00000006,0x00000992,0x000004e3,0x00000001,0x00050051,0x00000006, + 0x00000993,0x000004e3,0x00000002,0x00050051,0x00000006,0x00000994,0x000004e3,0x00000003, + 0x00050050,0x0000000c,0x00000995,0x00000991,0x00000992,0x00050050,0x0000000c,0x00000996, + 0x00000993,0x00000994,0x00050050,0x0000001a,0x00000997,0x00000995,0x00000996,0x00050080, + 0x0000001f,0x000004e8,0x00000630,0x00000109,0x00060041,0x000004e1,0x000004e9,0x000004dc, + 0x0000008f,0x000004e8,0x0004003d,0x00000018,0x000004ea,0x000004e9,0x0007004f,0x0000000c, + 0x000004f0,0x000004ea,0x000004ea,0x00000000,0x00000001,0x000300f7,0x000009cd,0x00000000, + 0x000300fb,0x0000006c,0x0000099f,0x000200f8,0x0000099f,0x0006000c,0x0000000c,0x000009a2, + 0x00000001,0x00000004,0x00000995,0x0006000c,0x0000000c,0x000009a5,0x00000001,0x00000004, + 0x00000996,0x00050081,0x0000000c,0x000009a6,0x000009a2,0x000009a5,0x00050051,0x00000006, + 0x000009a8,0x000009a6,0x00000000,0x000500b7,0x00000011,0x000009a9,0x000009a8,0x00000061, + 0x000300f7,0x000009ae,0x00000000,0x000400fa,0x000009a9,0x000009aa,0x000009ae,0x000200f8, + 0x000009aa,0x00050051,0x00000006,0x000009ac,0x000009a6,0x00000001,0x000500b7,0x00000011, + 0x000009ad,0x000009ac,0x00000061,0x000200f9,0x000009ae,0x000200f8,0x000009ae,0x000700f5, + 0x00000011,0x000009af,0x000009a9,0x0000099f,0x000009ad,0x000009aa,0x000300f7,0x000009cc, + 0x00000000,0x000400fa,0x000009af,0x000009b0,0x000009c9,0x000200f8,0x000009c9,0x0009004f, + 0x00000018,0x000009cb,0x000004ea,0x00000bf7,0x00000000,0x00000001,0x00000000,0x00000001, + 0x000200f9,0x000009cd,0x000200f8,0x000009b0,0x00050088,0x0000000c,0x000009b3,0x00000bee, + 0x000009a6,0x00050091,0x0000000c,0x000009b6,0x00000997,0x00000bad,0x00050081,0x0000000c, + 0x000009b8,0x000009b6,0x000004f0,0x0004007f,0x0000000c,0x000009bb,0x000009b8,0x00050051, + 0x00000006,0x000009bc,0x000009b8,0x00000000,0x00050051,0x00000006,0x000009bd,0x000009b8, + 0x00000001,0x00050051,0x00000006,0x000009be,0x000009bb,0x00000000,0x00050051,0x00000006, + 0x000009bf,0x000009bb,0x00000001,0x00070050,0x00000018,0x000009c0,0x000009bc,0x000009bd, + 0x000009be,0x000009bf,0x0009004f,0x00000018,0x000009c2,0x000009b3,0x000009b3,0x00000000, + 0x00000001,0x00000000,0x00000001,0x00050085,0x00000018,0x000009c3,0x000009c0,0x000009c2, + 0x00050081,0x00000018,0x000009c6,0x000009c3,0x000009c2,0x00050081,0x00000018,0x000009c8, + 0x000009c6,0x00000bf2,0x000200f9,0x000009cd,0x000200f8,0x000009cc,0x000100ff,0x000200f8, + 0x000009cd,0x000700f5,0x00000018,0x00000bd8,0x000009c8,0x000009b0,0x000009cb,0x000009c9, + 0x0003003e,0x000004eb,0x00000bd8,0x000200f9,0x000004d7,0x000200f8,0x000004d7,0x000500aa, + 0x00000011,0x000004f5,0x000004a7,0x00000083,0x000300f7,0x000004f7,0x00000000,0x000400fa, + 0x000004f5,0x000004f6,0x0000050d,0x000200f8,0x0000050d,0x000500aa,0x00000011,0x0000050f, + 0x000004a7,0x0000006c,0x000500a7,0x00000011,0x00000510,0x000004a8,0x0000050f,0x000300f7, + 0x00000512,0x00000000,0x000400fa,0x00000510,0x00000511,0x0000051e,0x000200f8,0x0000051e, + 0x00060041,0x000004e1,0x00000523,0x000004dc,0x0000008f,0x00000630,0x0004003d,0x00000018, + 0x00000524,0x00000523,0x00050051,0x00000006,0x000009e6,0x00000524,0x00000000,0x00050051, + 0x00000006,0x000009e7,0x00000524,0x00000001,0x00050051,0x00000006,0x000009e8,0x00000524, + 0x00000002,0x00050051,0x00000006,0x000009e9,0x00000524,0x00000003,0x00050050,0x0000000c, + 0x000009ea,0x000009e6,0x000009e7,0x00050050,0x0000000c,0x000009eb,0x000009e8,0x000009e9, + 0x00050050,0x0000001a,0x000009ec,0x000009ea,0x000009eb,0x00060041,0x000004e1,0x0000052a, + 0x000004dc,0x0000008f,0x00000637,0x0004003d,0x00000018,0x0000052b,0x0000052a,0x00050091, + 0x0000000c,0x0000052f,0x000009ec,0x00000bad,0x0007004f,0x0000000c,0x00000531,0x0000052b, + 0x0000052b,0x00000000,0x00000001,0x00050081,0x0000000c,0x00000532,0x0000052f,0x00000531, + 0x000500aa,0x00000011,0x00000534,0x000004a7,0x00000106,0x000500aa,0x00000011,0x00000536, + 0x000004a7,0x00000109,0x000500a6,0x00000011,0x00000537,0x00000534,0x00000536,0x000300f7, + 0x00000539,0x00000000,0x000400fa,0x00000537,0x00000538,0x0000055e,0x000200f8,0x0000055e, + 0x00050051,0x0000001f,0x00000561,0x00000490,0x00000001,0x0004007c,0x00000006,0x00000562, + 0x00000561,0x00050051,0x00000006,0x00000565,0x0000052b,0x00000002,0x00050051,0x00000006, + 0x00000567,0x00000532,0x00000000,0x00050051,0x00000006,0x00000569,0x00000532,0x00000001, + 0x00050083,0x00000006,0x0000056c,0x00000102,0x00000565,0x00070050,0x00000018,0x0000056d, + 0x00000567,0x00000569,0x00000562,0x0000056c,0x0003003e,0x0000050b,0x0000056d,0x000200f9, + 0x00000539,0x000200f8,0x00000538,0x00050051,0x0000001f,0x0000053b,0x00000490,0x00000001, + 0x0004007c,0x00000006,0x0000053c,0x0000053b,0x0004007f,0x00000006,0x0000053d,0x0000053c, + 0x00050041,0x00000491,0x0000053e,0x0000050b,0x00000109,0x0003003e,0x0000053e,0x0000053d, + 0x00050051,0x00000006,0x00000541,0x0000052b,0x00000002,0x000500ba,0x00000011,0x00000544, + 0x00000541,0x00000543,0x000300f7,0x00000546,0x00000000,0x000400fa,0x00000544,0x00000545, + 0x00000548,0x000200f8,0x00000548,0x00050051,0x00000006,0x0000054a,0x0000052b,0x00000003, + 0x00050041,0x00000491,0x0000054b,0x0000050b,0x00000106,0x0003003e,0x0000054b,0x0000054a, + 0x000200f9,0x00000546,0x000200f8,0x00000545,0x00050041,0x00000491,0x00000547,0x0000050b, + 0x00000106,0x0003003e,0x00000547,0x00000268,0x000200f9,0x00000546,0x000200f8,0x00000546, + 0x000300f7,0x0000054f,0x00000000,0x000400fa,0x00000534,0x0000054e,0x00000554,0x000200f8, + 0x00000554,0x00050041,0x00000491,0x00000555,0x0000050b,0x00000106,0x0004003d,0x00000006, + 0x00000556,0x00000555,0x0004007f,0x00000006,0x00000557,0x00000556,0x0003003e,0x00000555, + 0x00000557,0x00050041,0x00000491,0x0000055a,0x0000050b,0x0000006c,0x00050051,0x00000006, + 0x0000055b,0x00000532,0x00000000,0x0003003e,0x0000055a,0x0000055b,0x00050041,0x00000491, + 0x0000055c,0x0000050b,0x00000083,0x00050051,0x00000006,0x0000055d,0x00000532,0x00000001, + 0x0003003e,0x0000055c,0x0000055d,0x000200f9,0x0000054f,0x000200f8,0x0000054e,0x00050041, + 0x00000491,0x00000550,0x0000050b,0x00000083,0x0003003e,0x00000550,0x00000061,0x00050051, + 0x00000006,0x00000552,0x00000532,0x00000000,0x00050041,0x00000491,0x00000553,0x0000050b, + 0x0000006c,0x0003003e,0x00000553,0x00000552,0x000200f9,0x0000054f,0x000200f8,0x0000054f, + 0x000200f9,0x00000539,0x000200f8,0x00000539,0x000200f9,0x00000512,0x000200f8,0x00000511, + 0x000500c2,0x0000001f,0x00000516,0x0000049b,0x000001ea,0x000500aa,0x00000011,0x000009d4, + 0x00000516,0x0000006c,0x000300f7,0x000009dd,0x00000000,0x000400fa,0x000009d4,0x000009d5, + 0x000009d6,0x000200f8,0x000009d6,0x00050080,0x0000001f,0x000009d8,0x00000516,0x00000073, + 0x00050084,0x0000001f,0x000009da,0x000009d8,0x00000498,0x0006000c,0x0000000c,0x000009db, + 0x00000001,0x0000003e,0x000009da,0x00050051,0x00000006,0x000009dc,0x000009db,0x00000000, + 0x000200f9,0x000009dd,0x000200f8,0x000009d5,0x000200f9,0x000009dd,0x000200f8,0x000009dd, + 0x000700f5,0x00000006,0x00000bd9,0x00000061,0x000009d5,0x000009dc,0x000009d6,0x00050041, + 0x00000491,0x0000051d,0x000004c6,0x00000083,0x0003003e,0x0000051d,0x00000bd9,0x000200f9, + 0x00000512,0x000200f8,0x00000512,0x000200f9,0x000004f7,0x000200f8,0x000004f6,0x00050051, + 0x0000001f,0x000004fa,0x00000490,0x00000001,0x0006000c,0x00000018,0x000004fb,0x00000001, + 0x00000040,0x000004fa,0x000300f7,0x000004fe,0x00000000,0x000400fa,0x000004fc,0x000004fd, + 0x000004fe,0x000200f8,0x000004fd,0x00050051,0x00000006,0x00000500,0x000004fb,0x00000003, + 0x0008004f,0x00000501,0x00000503,0x000004fb,0x000004fb,0x00000000,0x00000001,0x00000002, + 0x0005008e,0x00000501,0x00000504,0x00000503,0x00000500,0x00050051,0x00000006,0x00000506, + 0x00000504,0x00000000,0x00060052,0x00000018,0x00000a53,0x00000506,0x000004fb,0x00000000, + 0x00050051,0x00000006,0x00000508,0x00000504,0x00000001,0x00060052,0x00000018,0x00000a55, + 0x00000508,0x00000a53,0x00000001,0x00050051,0x00000006,0x0000050a,0x00000504,0x00000002, + 0x00060052,0x00000018,0x00000a57,0x0000050a,0x00000a55,0x00000002,0x000200f9,0x000004fe, + 0x000200f8,0x000004fe,0x000700f5,0x00000018,0x00000bda,0x000004fb,0x000004f6,0x00000a57, + 0x000004fd,0x0003003e,0x0000050b,0x00000bda,0x000200f9,0x000004f7,0x000200f8,0x000004f7, + 0x000300f7,0x00000571,0x00000000,0x000400fa,0x00000bac,0x00000570,0x0000057d,0x000200f8, + 0x0000057d,0x00050041,0x00000576,0x0000057f,0x00000458,0x0000057e,0x0004003d,0x00000006, + 0x00000580,0x0000057f,0x00070050,0x00000018,0x00000587,0x00000580,0x00000580,0x00000580, + 0x00000580,0x000200f9,0x00000571,0x000200f8,0x00000570,0x00050041,0x00000576,0x00000577, + 0x00000458,0x00000137,0x0004003d,0x00000006,0x00000578,0x00000577,0x00050041,0x00000576, + 0x0000057a,0x00000458,0x0000013d,0x0004003d,0x00000006,0x0000057b,0x0000057a,0x00050051, + 0x00000006,0x000009f0,0x00000bad,0x00000000,0x00050085,0x00000006,0x000009f2,0x000009f0, + 0x00000578,0x00050083,0x00000006,0x000009f3,0x000009f2,0x00000060,0x00050051,0x00000006, + 0x000009f5,0x00000bad,0x00000001,0x00050085,0x00000006,0x000009f7,0x000009f5,0x0000057b, + 0x0006000c,0x00000006,0x000009f9,0x00000001,0x00000006,0x0000057b,0x00050083,0x00000006, + 0x000009fa,0x000009f7,0x000009f9,0x00070050,0x00000018,0x000009fb,0x000009f3,0x000009fa, + 0x00000061,0x00000060,0x000200f9,0x00000571,0x000200f8,0x00000571,0x000700f5,0x00000018, + 0x00000bec,0x000009fb,0x00000570,0x00000587,0x0000057d,0x00050041,0x00000484,0x0000058d, + 0x0000058b,0x0000008f,0x0003003e,0x0000058d,0x00000bec,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_clockwise_path.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..b87874d8daf6ad901ec3d5218b8e7f5fc1fc110b GIT binary patch literal 21276 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.h new file mode 100644 index 000000000..7d6e49805 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.h @@ -0,0 +1,73 @@ +#pragma once + +const uint32_t draw_fullscreen_quad_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000002d,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000d,0x00000011,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00060005,0x0000000b,0x505f6c67,0x65567265,0x78657472,0x00000000, + 0x00060006,0x0000000b,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x0000000b, + 0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000000b,0x00000002, + 0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000000b,0x00000003,0x435f6c67, + 0x446c6c75,0x61747369,0x0065636e,0x00030005,0x0000000d,0x00000000,0x00060005,0x00000011, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x0000002a,0x0000424d,0x00040006, + 0x0000002a,0x00000000,0x00006250,0x00040006,0x0000002a,0x00000001,0x00006359,0x00040006, + 0x0000002a,0x00000002,0x00006552,0x00040006,0x0000002a,0x00000003,0x00006553,0x00040006, + 0x0000002a,0x00000004,0x0000366d,0x00040006,0x0000002a,0x00000005,0x0000676d,0x00040006, + 0x0000002a,0x00000006,0x00006544,0x00040006,0x0000002a,0x00000007,0x00006545,0x00040006, + 0x0000002a,0x00000008,0x00003755,0x00040006,0x0000002a,0x00000009,0x0000676a,0x00040006, + 0x0000002a,0x0000000a,0x0000635a,0x00040006,0x0000002a,0x0000000b,0x00003157,0x00040006, + 0x0000002a,0x0000000c,0x0000676e,0x00040006,0x0000002a,0x0000000d,0x00003559,0x00040006, + 0x0000002a,0x0000000e,0x0000324f,0x00040006,0x0000002a,0x0000000f,0x00006461,0x00040006, + 0x0000002a,0x00000010,0x00006579,0x00040006,0x0000002a,0x00000011,0x00003376,0x00040006, + 0x0000002a,0x00000012,0x00003377,0x00040006,0x0000002a,0x00000013,0x00006462,0x00040006, + 0x0000002a,0x00000014,0x00006767,0x00030005,0x0000002c,0x0000006b,0x00030047,0x0000000b, + 0x00000002,0x00050048,0x0000000b,0x00000000,0x0000000b,0x00000000,0x00050048,0x0000000b, + 0x00000001,0x0000000b,0x00000001,0x00050048,0x0000000b,0x00000002,0x0000000b,0x00000003, + 0x00050048,0x0000000b,0x00000003,0x0000000b,0x00000004,0x00040047,0x00000011,0x0000000b, + 0x0000002a,0x00030047,0x0000002a,0x00000002,0x00050048,0x0000002a,0x00000000,0x00000023, + 0x00000000,0x00050048,0x0000002a,0x00000001,0x00000023,0x00000004,0x00050048,0x0000002a, + 0x00000002,0x00000023,0x00000008,0x00050048,0x0000002a,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x0000002a,0x00000004,0x00000023,0x00000010,0x00050048,0x0000002a,0x00000005, + 0x00000023,0x00000014,0x00050048,0x0000002a,0x00000006,0x00000023,0x00000018,0x00050048, + 0x0000002a,0x00000007,0x00000023,0x0000001c,0x00050048,0x0000002a,0x00000008,0x00000023, + 0x00000020,0x00050048,0x0000002a,0x00000009,0x00000023,0x00000030,0x00050048,0x0000002a, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x0000002a,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x0000002a,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000002a,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x0000002a,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x0000002a,0x0000000f,0x00000023,0x00000050,0x00050048,0x0000002a,0x00000010,0x00000023, + 0x00000054,0x00050048,0x0000002a,0x00000011,0x00000023,0x00000058,0x00050048,0x0000002a, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x0000002a,0x00000013,0x00000023,0x00000060, + 0x00050048,0x0000002a,0x00000014,0x00000023,0x00000064,0x00040047,0x0000002c,0x00000021, + 0x00000000,0x00040047,0x0000002c,0x00000022,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006, + 0x00000004,0x00040015,0x00000008,0x00000020,0x00000000,0x0004002b,0x00000008,0x00000009, + 0x00000001,0x0004001c,0x0000000a,0x00000006,0x00000009,0x0006001e,0x0000000b,0x00000007, + 0x00000006,0x0000000a,0x0000000a,0x00040020,0x0000000c,0x00000003,0x0000000b,0x0004003b, + 0x0000000c,0x0000000d,0x00000003,0x00040015,0x0000000e,0x00000020,0x00000001,0x0004002b, + 0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,0x00000001,0x0000000e,0x0004003b, + 0x00000010,0x00000011,0x00000001,0x0004002b,0x0000000e,0x00000013,0x00000001,0x00020014, + 0x00000015,0x0004002b,0x00000006,0x00000017,0xbf800000,0x0004002b,0x00000006,0x00000018, + 0x3f800000,0x0004002b,0x00000008,0x0000001a,0x00000000,0x00040020,0x0000001b,0x00000003, + 0x00000006,0x0004002b,0x0000000e,0x0000001e,0x00000002,0x0004002b,0x00000006,0x00000023, + 0x00000000,0x0004002b,0x00000008,0x00000024,0x00000002,0x0004002b,0x00000008,0x00000026, + 0x00000003,0x00040017,0x00000028,0x0000000e,0x00000004,0x00040017,0x00000029,0x00000006, + 0x00000002,0x0017001e,0x0000002a,0x00000006,0x00000006,0x00000006,0x00000006,0x00000008, + 0x00000008,0x00000008,0x00000008,0x00000028,0x00000029,0x00000029,0x00000008,0x00000006, + 0x00000008,0x00000006,0x00000006,0x00000008,0x00000006,0x00000006,0x00000006,0x00000008, + 0x00040020,0x0000002b,0x00000002,0x0000002a,0x0004003b,0x0000002b,0x0000002c,0x00000002, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d, + 0x0000000e,0x00000012,0x00000011,0x000500c7,0x0000000e,0x00000014,0x00000012,0x00000013, + 0x000500aa,0x00000015,0x00000016,0x00000014,0x0000000f,0x000600a9,0x00000006,0x00000019, + 0x00000016,0x00000017,0x00000018,0x00060041,0x0000001b,0x0000001c,0x0000000d,0x0000000f, + 0x0000001a,0x0003003e,0x0000001c,0x00000019,0x000500c7,0x0000000e,0x0000001f,0x00000012, + 0x0000001e,0x000500aa,0x00000015,0x00000020,0x0000001f,0x0000000f,0x000600a9,0x00000006, + 0x00000021,0x00000020,0x00000017,0x00000018,0x00060041,0x0000001b,0x00000022,0x0000000d, + 0x0000000f,0x00000009,0x0003003e,0x00000022,0x00000021,0x00060041,0x0000001b,0x00000025, + 0x0000000d,0x0000000f,0x00000024,0x0003003e,0x00000025,0x00000023,0x00060041,0x0000001b, + 0x00000027,0x0000000d,0x0000000f,0x00000026,0x0003003e,0x00000027,0x00000018,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_fullscreen_quad.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..824a01eae75287fde440ffd99a91507a45b8af31 GIT binary patch literal 2180 zcmZ9MTTc@~7={N*0YO3JP4ah3O zttqQ-=~XS2s<#=`-vsq$@KsVY;mld9HNs|Ci$uHPc)l^_Vbt6XzbP|&k~O|fYcHzd z!AjU@7Nc@-vW7#f9agI+Ygze$H#F+OBgG`etVcc-5i=wHa+y3G@tpY0QmUzGr<`i) z*ivOSp4{7xj(u22*RxvRucW$Ddc}$7Mpqr(E&cjY8h=K5&)MH2{obhupWog~>rY@C_mob*8H=2UUTZi zyEUyar`gdmyoNDa#vT|xTgDuQ*LnS=Ml^RxE=HS+Ic+K#;xl06fN=)r+C4Dtz%p{d z@YOQ*!0^g4?it4STgF|(E;@|+hK)Ile6XCuxOW);3E1;`T5Qo_d^d5=9Y(FN6^HQ- zU~3NJEx-y6<2}GO9maRUUO5cUVecHq+kky=81Do2(P4N5^VPXO-pPbI&FaZSnnB$p zcR8VZ&1hskq8Z-i)JL@+Ptn}Vu>Rs_PMtQ}()ih?J|>Ni#KXol!$W%pYxJDr@R6LX zKW=G!gpmjTa_XE*9yI>Z*pF|l!P$?-H#Z)C&_nvNVU3(aZKLYOeE(%NZ%F!?{hrIQ zPV!vQoSN8Y>loJ@uk8LQ&1rW3HO=iheod=$27cbuNX__(zNL|~i60l4X=#}4oZ)uP zU>_Y$oE=Zkt;Vxi#gT^`c!uVEz!vm7Wuz_|_5Ky%xA#Ppnt6kG{96>wTZ7^APcb|m zQHOI^KU5j{FR8=v9j})}@s-~xcTOyxKUG#3@ixa*&B=l1Hb+i#xSL}_8h$#*q?paY jnW*abSnnN_x#f)q&Ucpk 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.h new file mode 100644 index 000000000..a6df4ecbe --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.h @@ -0,0 +1,57 @@ +#pragma once + +const uint32_t draw_input_attachment_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000019,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0006000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009, + 0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000009, + 0x00006265,0x00030005,0x0000000c,0x00006873,0x00030005,0x00000016,0x0000424d,0x00040006, + 0x00000016,0x00000000,0x00006250,0x00040006,0x00000016,0x00000001,0x00006359,0x00040006, + 0x00000016,0x00000002,0x00006552,0x00040006,0x00000016,0x00000003,0x00006553,0x00040006, + 0x00000016,0x00000004,0x0000366d,0x00040006,0x00000016,0x00000005,0x0000676d,0x00040006, + 0x00000016,0x00000006,0x00006544,0x00040006,0x00000016,0x00000007,0x00006545,0x00040006, + 0x00000016,0x00000008,0x00003755,0x00040006,0x00000016,0x00000009,0x0000676a,0x00040006, + 0x00000016,0x0000000a,0x0000635a,0x00040006,0x00000016,0x0000000b,0x00003157,0x00040006, + 0x00000016,0x0000000c,0x0000676e,0x00040006,0x00000016,0x0000000d,0x00003559,0x00040006, + 0x00000016,0x0000000e,0x0000324f,0x00040006,0x00000016,0x0000000f,0x00006461,0x00040006, + 0x00000016,0x00000010,0x00006579,0x00040006,0x00000016,0x00000011,0x00003376,0x00040006, + 0x00000016,0x00000012,0x00003377,0x00040006,0x00000016,0x00000013,0x00006462,0x00040006, + 0x00000016,0x00000014,0x00006767,0x00030005,0x00000018,0x0000006b,0x00030047,0x00000009, + 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00030047,0x0000000c,0x00000000, + 0x00040047,0x0000000c,0x00000021,0x00000000,0x00040047,0x0000000c,0x00000022,0x00000002, + 0x00040047,0x0000000c,0x0000002b,0x00000000,0x00030047,0x0000000d,0x00000000,0x00030047, + 0x00000012,0x00000000,0x00030047,0x00000016,0x00000002,0x00050048,0x00000016,0x00000000, + 0x00000023,0x00000000,0x00050048,0x00000016,0x00000001,0x00000023,0x00000004,0x00050048, + 0x00000016,0x00000002,0x00000023,0x00000008,0x00050048,0x00000016,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x00000016,0x00000004,0x00000023,0x00000010,0x00050048,0x00000016, + 0x00000005,0x00000023,0x00000014,0x00050048,0x00000016,0x00000006,0x00000023,0x00000018, + 0x00050048,0x00000016,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000016,0x00000008, + 0x00000023,0x00000020,0x00050048,0x00000016,0x00000009,0x00000023,0x00000030,0x00050048, + 0x00000016,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000016,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x00000016,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000016, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x00000016,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x00000016,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000016,0x00000010, + 0x00000023,0x00000054,0x00050048,0x00000016,0x00000011,0x00000023,0x00000058,0x00050048, + 0x00000016,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000016,0x00000013,0x00000023, + 0x00000060,0x00050048,0x00000016,0x00000014,0x00000023,0x00000064,0x00040047,0x00000018, + 0x00000021,0x00000000,0x00040047,0x00000018,0x00000022,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008, + 0x00000009,0x00000003,0x00090019,0x0000000a,0x00000006,0x00000006,0x00000000,0x00000000, + 0x00000000,0x00000002,0x00000000,0x00040020,0x0000000b,0x00000000,0x0000000a,0x0004003b, + 0x0000000b,0x0000000c,0x00000000,0x00040015,0x0000000e,0x00000020,0x00000001,0x0004002b, + 0x0000000e,0x0000000f,0x00000000,0x00040017,0x00000010,0x0000000e,0x00000002,0x0005002c, + 0x00000010,0x00000011,0x0000000f,0x0000000f,0x00040015,0x00000013,0x00000020,0x00000000, + 0x00040017,0x00000014,0x0000000e,0x00000004,0x00040017,0x00000015,0x00000006,0x00000002, + 0x0017001e,0x00000016,0x00000006,0x00000006,0x00000006,0x00000006,0x00000013,0x00000013, + 0x00000013,0x00000013,0x00000014,0x00000015,0x00000015,0x00000013,0x00000006,0x00000013, + 0x00000006,0x00000006,0x00000013,0x00000006,0x00000006,0x00000006,0x00000013,0x00040020, + 0x00000017,0x00000002,0x00000016,0x0004003b,0x00000017,0x00000018,0x00000002,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000000a, + 0x0000000d,0x0000000c,0x00050062,0x00000007,0x00000012,0x0000000d,0x00000011,0x0003003e, + 0x00000009,0x00000012,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_input_attachment.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..104b50ba5f0fed448b2134f8ec80597a8095a5ca GIT binary patch literal 1680 zcmZ9LZBJ7{5QP_RicvAL5#_@xA#(trI5B@_>cY| zznFNQ+partlIhMlJ3Dvw%r+WdyW`xLE4z|gazmSS<6@j+eWJDOCURV@9o07agLLE7 z<})&=-e+AFStopt;HV>cjEq8Bh7koe{k7r zw6Zw4K0Ot@OwP0Bz~@!#^=fS|ZeCp}@3xc0opv{i({@ie?VF5xCF+gx+TCX7I<*N! zW!T<|>V^KY#5v-7iu-57ctP>U9hcvT7&}lNHw2^2Ni$&Xbf_NuKB^oUoPT#K>=(6v z(F%A%c-Q2k)taAM9s6mIGJ==@0W4|#Q@ze2@@d=|?98GH1Mu}8d;qkvb1 z(cSN_|J#oo_rs_|Zx}JN0;JIkT(VOQuLmqm0j#?P)@dxy0nLpgN;dldZ?+r(E4Y2b@gCr6hT~1Z z9T<*#!hJFvZv*a&;g|v3H^cEp;JzCUjo|cj^0}gqojZ6{j?HP3%wwc zd{GlbQ!sO>=odZ7g?}@`=n1!^7l@AJ9Y#-R zMh-Qf>K%g7j2xUAXj746oIw}Pa1ZdjR(hnyvKZd7@7u4`uucum;qc`7_5avo?z^bG xp|->Of|&!{milLEhsAooVSVdc-|MlN> zZToFoskEtdsjo6RN1MrO_d%u;php2R;-*iXvoknp}0e(j-o2- zTKb~>m~l7^4-cWEBBIcH{~OgrzxMPe5vvVeOV0#OApxrPm3)vD2qEt(d)J z+2ZEqi zo>;~8m3~z{sG96h(c?>7jQ^3P4)b79X_xshql&kw&Wi<$n-0}bk2&e2<@0Rkd(xRW zx}q6bUjdUQD`uvdw=?E`Ml0-Yfx089oA`L#uXdzzaWely&FRB zw!o}y5;|bl2UFkuxij>B+=AM(z?`Cp;S9)V0lU6noEBCD%B6ZqM{ z&jtQX;O7Is(1PnL>^-zWqJ8$C#O@z_{I)NzhTdy|UvI(n74|P|vzD>_PRQ8L`ihU7 z_(SIyLNkUnd0plITk6(Tw!;Y}Y_bp5aBWY-rsn~&v#OHxj&bi6S#8g?AMC&A)#$qF9$dq<{TLsUP9NE?@v$batLz?a^bgz^cv#?(fk(CA z`U?9#v8=_jzIyiKqsQi$(B&*h|L3;I>MHXB&kwvHFy{w}@d0}dfw5cLhw3VeLhsbT zs{?-{@cDr+3Vd(xA_ zCOq~w^QZ%lbHO}f4UfIvJYoTF=isq#!~1;jXb)bW;IT);<8Ze<&N+Dd2akTkJ2-gw z3h$8Mapu7rA3Vkm-h|*0LwJ*eM?c|B4IXD8yy?N?9E5jV@Hh+M%?chdf;Uf@{ed&F zuQ16p>xRU5UQNIY=FF_&`s(>fJ>o(=WLb|hm4pnOy3nc1nQL7zbGfZD?Z4V0tE;qO zpbNh)aDCuy0=Ey`A@H7orv^SI@XWx+2c8pnUf|}y%LA_nd|KdDfiDPrS>P)IUlaKH zz#9T@4E%WDCjvhi_`Sd%1pX-SCxN#Fu5LDEEZVZz3a$^_K5)mt+Xe0%xJ%$219uC& zQ{bL~dj;+txKH2#f%gdf#lV9C?;Uubz(WEL4ZMHg;eihfd{E#~fe#HlF7Twl#{`}h zczWO&fsYH^6nIwP*@5QOCV**bPJR|V&ftv!)3cN7zvcT5{zA^Ak zf!7DVKk$aY4+VZC@S}l$5%{UV&jtQ%;O7Is5ctKwn*whR{FlIg4g5ynw*tQ%xE&u@ z%RJd8aQnbJ1nwHRTi_mncMjYu@GgOO4ct3$pTGkH9}sv(;Nt=xA9!})xq;^eUJ`g^ z;B|p-5B!6`cL%;N@cn@|27V~;!+{?O{L{dX1^!v!Cj-A2_|w4E57uQ&+wdW~;C6wx z4ctEPj)8X$JTdT*fhPw(Ht@{AUkUuxz_S9+4m>AtbKnJmPYAp$@an+V2fiur&4Jei zz9aAt0^b|>p};Q&-W2$q!2cKc-N5e${xtBGz}xaiVi~*6fx8Co9=J!~T?6+H+&6H) zzykvB5x6n%UV--xJUH;afrkbj7I5N( z8TjnL=L9}C@OgpH4}3x3HGwY-yf*Mvfv*XCbKqM8uM2!f;Clk!8~B014+efX@S}l$ z8u+omPX~TB@NWYDG4Q6qF9&`#@auu!4E#>uzXyId@cV&34E%B6PXliW+=ee)%KGXM zxKrTm19uMGGjOlKy9VwZxNqQof%^v@5O|Nkje++HJT&mIz+VnLJn)#nV*?)^ctYSK z15XY-CGgb1(*n;3{FT770?!FNFK~0<1%XctyeROJz>5Pf4SZ7IRe@IrJ}>aOfzJti ze&Bx#ynT5-%=b>e4ZJzg2B6G~g%^z9bkZ}n9>bt=I->3cH%9O|P? z>LCdq@%kwDl#K5Xq4_$jkN)SoJ^oaHhn(*;!PtUsC^Yub*CV;AKKw?}v~{U6$@FEy zZ3>O8CzMIuW%ZXT(S!eMn3Yu{_bGOGPDZkw4x;asgG1B`^*V~aT_t+RY^OnZ%*ks; znBG(LC1W2QZhElj)o&d=`b&xhc6k0~*<|4>*RDOt^iiTmbnH3O^c2x|j(fSq_F~an z+O6K-@@GUV9c=n{HF_km+ayeT#ExyxEgInkeYIM~f>|d%(d+s~W8jX3*I7HvCS7R%DoAlt>b}t;Mta{Y+Fz8k1w8Z9s zn*0FEM^x#`@Lqa4IZl`{rtM6onM>nq`c>WGh4!<~T{KsYkQ}`UMGqQ1Xr5(~KBs6+ z5~e-(Wu~zEV!M9U>H2=2={jdc9sK{cXy!IKQ#HI|;MaGgLqZq3&^+rTG5+5ZW(=tF zMV@1bzD$`hC!=$@Xxi|4yiPPRB6iq>zP|8G^DGk`e7H+k|EhM7LvyDA9`gGNrVWof z_Z*CQhH1>RM(Vtz68r20*o1z$@T|+TLuB-sXMrT*)K?9=zPK(l_bT8~7kXOI*U2c)!BWn%DQL#) zyTXjA3O!%wS$#G|e>2nf%+w*4WcZGc>zJ1`zF($#%pIP8;Vbmzg~yu1k1Is;9LMxp z(LBSU{`Ex{yVPgh_}L3I>yKwBBxvHwa}(m)M*kDD({$E=8-%}IF#UK%_>1Zd{10?C zvF|yX|DpKo@y^(x?#JTW<|o4YX>HKY;!3ss55(ay0e*4j@a%ze$~4a(lIEEO^a$y* z9>1&1TAU**tg$N!kM(zyc*J~d;S1{7;5Jp?t`v{4KB&miC4Ssdu#7g~aR-65xn4T# zp*ISn2mgKb;ue*pkED<6X61Ft^o{aEmFPetb6d9w(-tXp(0y0Eq-{PIp+`N=SM1p@ z?l!PToLhY7egpdO9iMxIGd}A@!^`;GD;hp&lx(q=+^@|3!kK@N`Us64{oSaNM1R?1 z9#HK;ji*$SXak*JDZ`@;@cAWPPYdHC^VvQ>BO0GODkHb6!#{)j+r|bVl z*nLKRUTKSaAFL1L^vC{CdaU`}i$C-ceSF=n%meOJf@oa6Z~acWd{yN;FpqkLDl z5YXo{HhQ#$kNAK-eZm&DGtR`@| zbKWveUeny?f$wqHEDX=tJJm zXn5#=?dzVxt$pS03;g@bSnnka&ttu}ux%q7qzn(+VDC|bh52mZJ$xV0@N$pZS2TQ* z_wXU28Ef`%Kr` zrE$ve=ogqV;QXH`%;%*^+HW|!xjO-mOrn35ahJj}&T|c2H5SyXm&~!i2D*+NcP)^U z%;V05>o}g=y|4}HpyTz;{U~ItZ}f;EeJ3vN7p3FE_W{TUibvh-^9<3`l2!B&wi3o z2OY+fHXV~QgsB7HXW?1m!6&x#ZH+LAnDF=2*`m)?rf-y!)H6Oma#w{rEo2ftVApM3 zQDidFvZt&S55D7nZK+FJ$gWiWzA|l5G7r#!M)pm`gt&4ahJ77dse`WP3f~u@M?KoZ z-bJd9@7D|CKRS*B_i(UBJluy{h0!HV(dQuIyKARP1wNm#N!DFgbcus?drKESb>Lg~ zj-pGvtlL*Q@TrshexmUWIkBX_j1e(mZ0Hkytr9*>8UIrUU1EX`-;be3J?s)MbeYfC zV;eGhzrFn(t=WUER zzIp9)R}UTP+Rg%D_$2$qGdlRTW8H;C7rWNw86JGzP z+9bcPk>mWmNuOu4pi7^T%~Ebw#z#ul0N-iNSMI9J=T`R01%=1wR{X$Db^fVzow>q% zhvho+gyFTWLtXpM^9S_sgEsI1KNqSbF*Y64<_V(V(I%KSIr|m~^IezwyHpsS_vB^5 zB`Tx*%cTE&2S_r%ci|(aU*`8MeB|Dh_Bf8irfJ3I$PA31h7 zgR#SXLG&7x@s;+_^&CTPUwD4XbDq|1@+_6-J;<|7o~!cQ2RUtiS0h5~xm$u=@(QMclZTWLv}v zJ@y7<+*2an=(u0pSMvQO^SHMJ&vqHp*@Y%H)IrDo&j}ghj;{BUW?|xnj^`5hoR|yF zeEwrDapwtr)LbLa*xDYzoelWN(+>AH;3LmHV3YhquTdFaX%AiR0m$tO z_dd3^2W%0aJpg&O*+yf}9)LXe0PftehLL*@;O<@37x6r9+#7`N>^*=xgy85f z`iE`LW$vIrx1P(L#77^w{bjyxFM4Zx0QXejBS+tR0CxoO#djK!c}};}Jn|hv^SC1j z4?WLi?g~OPls^*NldoqIr=(5Egs-UGNpiQKliZ-{O70Nb{Vdx@4+?^x%)uexUXqj#0ov{0o>mt-srer+~f4UPV>0W3D0)f10F6kv7rt+_WzNP zG4AMk58&P>aYM&*iTj_-1!wO8+yzA+x%U8gta-0z%G?9^e83*?JC!8w0lyXvk39hF zJ%Bs?xd%L;_3(u1wcZ0BEPUj|!Rzkf!bhHaz@wt+duuyCEqvr@hkIw}BhNj6_YBZ$ zRK{1@L)Uu%a?g40b3>C!)N2_-$$a12JnnPDL(gN!y>94%%G~`%$NJn6$9B$n?uuKV zy6D&zcfpY{M{LV7?u=W89`(FmTq}%Sblf-YlCv+7Nz}Dp+#yF!GLO6D@X&Lc+$ndP z)IrDk+)u}L_Kkb$)~7Byp0nJkNAB$X?yt&7ZE^^Nw?(?&juGkFo{b zdf(h6KKjV*FZ<@pqPKS5yju9k(f1g0Paj|WUI8+X5BKwZkKa7*>BB?MU95?Q(VykuBxVuU{3RyBgj~uR;?W>Y!u)cL^Eej;`nKuEN9( z9nU4+!C)>p`@HER9{R|A-oWF0@!3I{=M8_Ca^Cz(CCTT_&qc%IyaD^X;oY)4Z_ZUb zwszi}SNO<@gVz!FuF*%%Tri(I*jqbqxQ`7VdD^+K@R8T%RPFE1$K@Y-jmr2+d+7SS zLGC%vduFU%GKqQ~L*6g*duZnIo*6v!Ja)Wq2F<*r4m#H7-8F3IoaY@j>r)pU+u|KH zWXuuUvW$1xEJKfa-Y>2a#x6SU8}GQ$S2BsZ_KSDhkdw^g9XELBxlP`6bDPvb$NIcC zhwbbe@6TDEy6AY$@~$6pXYYU4iH9BJ_WdPc_+(Q0&ii!8N%n>J>fojCyk7^+xKIZj z>+`POb;{}cX3^HCE;^3G%^_n?Mc3!eEyBbf9k1DS!q`XV`Mp+iaBJtyRpN8rAg6un zUn83H204EEY}s9#33Cd$dAyfLoA4a(HsZl|cD#AN5MAV+KlQ?_F>KR5`ylT!K)2pE zZxtVXhMBS+t3%=?4*;`beqd3<~;k=r)!BBDDmY+J@Vi9mnk+^%GmI<94t3)I&~PY!Nr! z<+Lqgg`Urw&XN&tblflA@q|w@uY2LyE@IyKgeErBLC6002pQv!uIDcAgc3J&JePPk zl)2#S^XBv7p^x0>4Lr^lpB&yt6PIZJGh_nhG|zwOUY3hx%(ZDik8{=PD{DedD8!r1Y%*c*k3aUW%5-ji+;M#lWKUpI^9do=uFETGY2 zENGv$XxDA=I{~!i=dG6sb3Y%x+u=6@;B!yk^{y11^{x_)9(?91vA$XuKKJ?U-!-Ds zKWOyQKm3GdEbx~xaQ$xzw~qT7@!;EEeiMP1z<0e1g|l5~^s*h=gJ%BGF6Aoqg*nQ+ zB&NKJfR5)e^NyG_sJ%OdnQvZ~KN1a(b?G&9muUFhEB0FDw-H!Z$ZU(>NWfp~tQULK&GgNJ`_siY4ls`N=ku#62e@@{eS6Hie40zwKU#H{LIW zk4=(wk0`qC1G@923!gghtvj*kIzH&~eky$Gz_;!s@sQ#B`m!fa77spgX5Tzon8cop z>?mb;%x|!LUnD!k)b^MI)}!<@XWnf?hj~FAY}lV;gpuQq<2O|a$@J$ z_Lj|mHHZ61j-5tj<}h}sXoq;9YrhAH zho8(}?~!|pM?GYY`#wbvT@p5F$8&Iqb8x6IddxxEM8|V*{~}XSt>-y7TnudB zr{~~-qTy2qo1Sm*bKmYE+A;1aOpNVIFVXliP#M`4W!piPcDjnToo>QuXD89_6SA~} zEbX)rZ98p+vE#F}UNk)F`z&oAJkO1e;=xDXyzPYH=UF;H@!Hy1x<}z7$8XQC#==L= zIC5W)J)pDf;uCVmzl&)2w2L2}Cp!uw%d-?-#(+B?j=@L5#K8UiL>M0JIWAj*=l)hC zM;DpL3|_Xw9TT_no^Zzc1JUqutl(vR_AJ+bTbR#Mj@98h+up+mtx=Ns6AB-B#`eg< zN1ki(aoI#~kTUmyXa`-d#k0giheR9fH@tTa-}j2F`}LyhcG2a%bokVPZ{1Zz7hi0b z_txQ42R^azJts<^eZ0#}+uWg|4so*G)#4$~v+o;)=Xb#I1N)vc{9YzH)U}-pgyECy z-!!!a-*&9Krs!tBXGj-5b+X?V7TxSO@8ZL!j{EILc^twr>klPeoPk`uyh1 zUW0#BWAhX5ZQQQ0`9cX0k8^3`~-`tjUC|MWy!|#5eM?J>E_Usp>b@^Qo^r=rj=)1pf-C3CU z_E+XzFLd$CV@PQ`{H6#x%o*y@2D+Y0l-A`pN6=;7QV%<kNCN6pwacX?k?O<+2h(@7#`#5^$U+ac%4yxs@C^c{wFF& Bm@xnV literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.h new file mode 100644 index 000000000..bb8a8ce03 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.h @@ -0,0 +1,290 @@ +#pragma once + +const uint32_t draw_interior_triangles_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000030e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000e000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000d7,0x000000df,0x000000e2, + 0x000000f4,0x0000012d,0x00000133,0x00000154,0x00000173,0x000001f7,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000b5,0x0000664a,0x00040006, + 0x000000b5,0x00000000,0x00003464,0x00030005,0x000000b7,0x0000424c,0x00060005,0x000000d7, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x000000df,0x0000424a,0x00030005, + 0x000000e2,0x0000316c,0x00030005,0x000000ed,0x00006576,0x00040006,0x000000ed,0x00000000, + 0x00003464,0x00030005,0x000000ef,0x00004355,0x00030005,0x000000f4,0x0000307a,0x00030005, + 0x000000f6,0x0000424d,0x00040006,0x000000f6,0x00000000,0x00006250,0x00040006,0x000000f6, + 0x00000001,0x00006359,0x00040006,0x000000f6,0x00000002,0x00006552,0x00040006,0x000000f6, + 0x00000003,0x00006553,0x00040006,0x000000f6,0x00000004,0x0000366d,0x00040006,0x000000f6, + 0x00000005,0x0000676d,0x00040006,0x000000f6,0x00000006,0x00006544,0x00040006,0x000000f6, + 0x00000007,0x00006545,0x00040006,0x000000f6,0x00000008,0x00003755,0x00040006,0x000000f6, + 0x00000009,0x0000676a,0x00040006,0x000000f6,0x0000000a,0x0000635a,0x00040006,0x000000f6, + 0x0000000b,0x00003157,0x00040006,0x000000f6,0x0000000c,0x0000676e,0x00040006,0x000000f6, + 0x0000000d,0x00003559,0x00040006,0x000000f6,0x0000000e,0x0000324f,0x00040006,0x000000f6, + 0x0000000f,0x00006461,0x00040006,0x000000f6,0x00000010,0x00006579,0x00040006,0x000000f6, + 0x00000011,0x00003376,0x00040006,0x000000f6,0x00000012,0x00003377,0x00040006,0x000000f6, + 0x00000013,0x00006462,0x00040006,0x000000f6,0x00000014,0x00006767,0x00030005,0x000000f8, + 0x0000006b,0x00030005,0x0000010f,0x00006747,0x00030005,0x0000012d,0x00003153,0x00030005, + 0x00000130,0x00006749,0x00030005,0x00000133,0x00003159,0x00030005,0x0000013c,0x00006748, + 0x00030005,0x00000141,0x00006577,0x00040006,0x00000141,0x00000000,0x00003464,0x00030005, + 0x00000143,0x0000424f,0x00030005,0x00000154,0x0000304e,0x00030005,0x00000173,0x0000316b, + 0x00060005,0x000001f5,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x000001f5, + 0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000001f5,0x00000001,0x505f6c67, + 0x746e696f,0x657a6953,0x00000000,0x00070006,0x000001f5,0x00000002,0x435f6c67,0x4470696c, + 0x61747369,0x0065636e,0x00070006,0x000001f5,0x00000003,0x435f6c67,0x446c6c75,0x61747369, + 0x0065636e,0x00030005,0x000001f7,0x00000000,0x00030005,0x00000205,0x00004342,0x00030005, + 0x00000208,0x00004351,0x00030005,0x0000020a,0x0000664b,0x00040006,0x0000020a,0x00000000, + 0x00003464,0x00030005,0x0000020c,0x00004358,0x00030005,0x0000020f,0x00003954,0x00040047, + 0x000000b4,0x00000006,0x00000010,0x00030047,0x000000b5,0x00000003,0x00040048,0x000000b5, + 0x00000000,0x00000018,0x00050048,0x000000b5,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000b7,0x00000018,0x00040047,0x000000b7,0x00000021,0x00000003,0x00040047,0x000000b7, + 0x00000022,0x00000000,0x00040047,0x000000d7,0x0000000b,0x0000002a,0x00040047,0x000000df, + 0x0000001e,0x00000000,0x00030047,0x000000e2,0x00000000,0x00030047,0x000000e2,0x0000000e, + 0x00040047,0x000000e2,0x0000001e,0x00000001,0x00040047,0x000000ec,0x00000006,0x00000008, + 0x00030047,0x000000ed,0x00000003,0x00040048,0x000000ed,0x00000000,0x00000018,0x00050048, + 0x000000ed,0x00000000,0x00000023,0x00000000,0x00030047,0x000000ef,0x00000018,0x00040047, + 0x000000ef,0x00000021,0x00000004,0x00040047,0x000000ef,0x00000022,0x00000000,0x00030047, + 0x000000f4,0x00000000,0x00030047,0x000000f4,0x0000000e,0x00040047,0x000000f4,0x0000001e, + 0x00000003,0x00030047,0x000000f6,0x00000002,0x00050048,0x000000f6,0x00000000,0x00000023, + 0x00000000,0x00050048,0x000000f6,0x00000001,0x00000023,0x00000004,0x00050048,0x000000f6, + 0x00000002,0x00000023,0x00000008,0x00050048,0x000000f6,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x000000f6,0x00000004,0x00000023,0x00000010,0x00050048,0x000000f6,0x00000005, + 0x00000023,0x00000014,0x00050048,0x000000f6,0x00000006,0x00000023,0x00000018,0x00050048, + 0x000000f6,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000f6,0x00000008,0x00000023, + 0x00000020,0x00050048,0x000000f6,0x00000009,0x00000023,0x00000030,0x00050048,0x000000f6, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x000000f6,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x000000f6,0x0000000c,0x00000023,0x00000044,0x00050048,0x000000f6,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x000000f6,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x000000f6,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000f6,0x00000010,0x00000023, + 0x00000054,0x00050048,0x000000f6,0x00000011,0x00000023,0x00000058,0x00050048,0x000000f6, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x000000f6,0x00000013,0x00000023,0x00000060, + 0x00050048,0x000000f6,0x00000014,0x00000023,0x00000064,0x00040047,0x000000f8,0x00000021, + 0x00000000,0x00040047,0x000000f8,0x00000022,0x00000000,0x00030047,0x00000108,0x00000000, + 0x00030047,0x00000109,0x00000000,0x00040047,0x0000010f,0x00000001,0x00000000,0x00030047, + 0x0000012b,0x00000000,0x00030047,0x0000012d,0x00000000,0x00030047,0x0000012d,0x0000000e, + 0x00040047,0x0000012d,0x0000001e,0x00000004,0x00040047,0x00000130,0x00000001,0x00000002, + 0x00030047,0x00000133,0x00000000,0x00030047,0x00000133,0x0000000e,0x00040047,0x00000133, + 0x0000001e,0x00000006,0x00040047,0x0000013c,0x00000001,0x00000001,0x00040047,0x00000140, + 0x00000006,0x00000010,0x00030047,0x00000141,0x00000003,0x00040048,0x00000141,0x00000000, + 0x00000018,0x00050048,0x00000141,0x00000000,0x00000023,0x00000000,0x00030047,0x00000143, + 0x00000018,0x00040047,0x00000143,0x00000021,0x00000005,0x00040047,0x00000143,0x00000022, + 0x00000000,0x00040047,0x00000154,0x0000001e,0x00000005,0x00030047,0x00000169,0x00000000, + 0x00030047,0x0000016b,0x00000000,0x00030047,0x0000016c,0x00000000,0x00040047,0x00000173, + 0x0000001e,0x00000000,0x00030047,0x000001f5,0x00000002,0x00050048,0x000001f5,0x00000000, + 0x0000000b,0x00000000,0x00050048,0x000001f5,0x00000001,0x0000000b,0x00000001,0x00050048, + 0x000001f5,0x00000002,0x0000000b,0x00000003,0x00050048,0x000001f5,0x00000003,0x0000000b, + 0x00000004,0x00040047,0x00000205,0x00000021,0x00000008,0x00040047,0x00000205,0x00000022, + 0x00000000,0x00030047,0x00000208,0x00000000,0x00040047,0x00000208,0x00000021,0x0000000a, + 0x00040047,0x00000208,0x00000022,0x00000000,0x00040047,0x00000209,0x00000006,0x00000010, + 0x00030047,0x0000020a,0x00000003,0x00040048,0x0000020a,0x00000000,0x00000018,0x00050048, + 0x0000020a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000020c,0x00000018,0x00040047, + 0x0000020c,0x00000021,0x00000006,0x00040047,0x0000020c,0x00000022,0x00000000,0x00030047, + 0x0000020f,0x00000000,0x00040047,0x0000020f,0x00000021,0x0000000a,0x00040047,0x0000020f, + 0x00000022,0x00000000,0x00030047,0x000002f1,0x00000000,0x00030047,0x000002f3,0x00000000, + 0x00030047,0x000002f5,0x00000000,0x00030047,0x00000304,0x00000000,0x00030047,0x00000307, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006, + 0x00000020,0x00000001,0x00030016,0x00000008,0x00000020,0x00040017,0x0000000d,0x00000008, + 0x00000004,0x00040017,0x0000000f,0x00000008,0x00000002,0x00040018,0x00000010,0x0000000f, + 0x00000002,0x00040015,0x00000015,0x00000020,0x00000000,0x00040017,0x0000002b,0x00000008, + 0x00000003,0x0004002b,0x00000008,0x0000003d,0x3f800000,0x0004002b,0x00000008,0x0000003e, + 0x00000000,0x0004002b,0x00000015,0x00000049,0x00000000,0x00020014,0x0000004a,0x0004002b, + 0x00000015,0x00000051,0x000003ff,0x0004002b,0x00000015,0x00000061,0x00000001,0x0004002b, + 0x00000006,0x0000006d,0x00000000,0x0004002b,0x00000008,0x00000099,0x3f000000,0x0004002b, + 0x00000015,0x000000a2,0x00000002,0x0004002b,0x00000015,0x000000a6,0x0000ffff,0x0004002b, + 0x00000006,0x000000ab,0x00000010,0x00040017,0x000000b3,0x00000015,0x00000004,0x0003001d, + 0x000000b4,0x000000b3,0x0003001e,0x000000b5,0x000000b4,0x00040020,0x000000b6,0x00000002, + 0x000000b5,0x0004003b,0x000000b6,0x000000b7,0x00000002,0x0004002b,0x00000015,0x000000b9, + 0x00000004,0x00040020,0x000000bb,0x00000002,0x000000b3,0x00040017,0x000000c9,0x00000015, + 0x00000002,0x00040020,0x000000d6,0x00000001,0x00000006,0x0004003b,0x000000d6,0x000000d7, + 0x00000001,0x00040020,0x000000de,0x00000001,0x0000002b,0x0004003b,0x000000de,0x000000df, + 0x00000001,0x00040020,0x000000e1,0x00000003,0x00000008,0x0004003b,0x000000e1,0x000000e2, + 0x00000003,0x0003001d,0x000000ec,0x000000c9,0x0003001e,0x000000ed,0x000000ec,0x00040020, + 0x000000ee,0x00000002,0x000000ed,0x0004003b,0x000000ee,0x000000ef,0x00000002,0x00040020, + 0x000000f1,0x00000002,0x000000c9,0x0004003b,0x000000e1,0x000000f4,0x00000003,0x00040017, + 0x000000f5,0x00000006,0x00000004,0x0017001e,0x000000f6,0x00000008,0x00000008,0x00000008, + 0x00000008,0x00000015,0x00000015,0x00000015,0x00000015,0x000000f5,0x0000000f,0x0000000f, + 0x00000015,0x00000008,0x00000015,0x00000008,0x00000008,0x00000015,0x00000008,0x00000008, + 0x00000008,0x00000015,0x00040020,0x000000f7,0x00000002,0x000000f6,0x0004003b,0x000000f7, + 0x000000f8,0x00000002,0x0004002b,0x00000006,0x000000f9,0x0000000d,0x00040020,0x000000fd, + 0x00000002,0x00000015,0x0004002b,0x00000015,0x00000103,0x00000200,0x0004002b,0x00000015, + 0x0000010d,0x0000000f,0x00030030,0x0000004a,0x0000010f,0x00040020,0x0000012c,0x00000003, + 0x0000000f,0x0004003b,0x0000012c,0x0000012d,0x00000003,0x00030030,0x0000004a,0x00000130, + 0x0004003b,0x000000e1,0x00000133,0x00000003,0x0004002b,0x00000006,0x00000136,0x00000004, + 0x00030030,0x0000004a,0x0000013c,0x0003001d,0x00000140,0x0000000d,0x0003001e,0x00000141, + 0x00000140,0x00040020,0x00000142,0x00000002,0x00000141,0x0004003b,0x00000142,0x00000143, + 0x00000002,0x00040020,0x00000148,0x00000002,0x0000000d,0x0004002b,0x00000015,0x0000014f, + 0x00000003,0x00040020,0x00000153,0x00000003,0x0000000d,0x0004003b,0x00000153,0x00000154, + 0x00000003,0x00050034,0x0000004a,0x00000165,0x000000a8,0x00000130,0x0004003b,0x00000153, + 0x00000173,0x00000003,0x0004002b,0x00000008,0x000001ab,0x3f666666,0x0004002b,0x00000008, + 0x000001af,0x40000000,0x0004002b,0x00000008,0x000001d4,0xc0000000,0x0004002b,0x00000006, + 0x000001dd,0x00000002,0x0004002b,0x00000006,0x000001de,0x00000003,0x00040020,0x000001e2, + 0x00000002,0x00000008,0x0004001c,0x000001f4,0x00000008,0x00000061,0x0006001e,0x000001f5, + 0x0000000d,0x00000008,0x000001f4,0x000001f4,0x00040020,0x000001f6,0x00000003,0x000001f5, + 0x0004003b,0x000001f6,0x000001f7,0x00000003,0x00090019,0x00000203,0x00000015,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000204,0x00000000, + 0x00000203,0x0004003b,0x00000204,0x00000205,0x00000000,0x00090019,0x00000206,0x00000008, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000207, + 0x00000000,0x00000206,0x0004003b,0x00000207,0x00000208,0x00000000,0x0003001d,0x00000209, + 0x000000b3,0x0003001e,0x0000020a,0x00000209,0x00040020,0x0000020b,0x00000002,0x0000020a, + 0x0004003b,0x0000020b,0x0000020c,0x00000002,0x0002001a,0x0000020d,0x00040020,0x0000020e, + 0x00000000,0x0000020d,0x0004003b,0x0000020e,0x0000020f,0x00000000,0x0005002c,0x0000000f, + 0x0000030a,0x0000003d,0x0000003d,0x0007002c,0x0000000d,0x0000030b,0x00000099,0x00000099, + 0x00000099,0x00000099,0x0003002e,0x0000000f,0x0000030d,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000002b,0x000000e4,0x000000df, + 0x00050051,0x00000008,0x0000021f,0x000000e4,0x00000002,0x0004007c,0x00000015,0x00000220, + 0x0000021f,0x000500c7,0x00000015,0x00000221,0x00000220,0x000000a6,0x0004007c,0x00000006, + 0x00000224,0x0000021f,0x000500c3,0x00000006,0x00000225,0x00000224,0x000000ab,0x0004006f, + 0x00000008,0x00000241,0x00000225,0x0007004f,0x0000000f,0x00000228,0x000000e4,0x000000e4, + 0x00000000,0x00000001,0x00050084,0x00000015,0x0000022a,0x00000221,0x000000b9,0x00060041, + 0x000000bb,0x0000022b,0x000000b7,0x0000006d,0x0000022a,0x0004003d,0x000000b3,0x0000022c, + 0x0000022b,0x0004007c,0x0000000d,0x0000022d,0x0000022c,0x00050051,0x00000008,0x00000249, + 0x0000022d,0x00000000,0x00050051,0x00000008,0x0000024a,0x0000022d,0x00000001,0x00050051, + 0x00000008,0x0000024b,0x0000022d,0x00000002,0x00050051,0x00000008,0x0000024c,0x0000022d, + 0x00000003,0x00050050,0x0000000f,0x0000024d,0x00000249,0x0000024a,0x00050050,0x0000000f, + 0x0000024e,0x0000024b,0x0000024c,0x00050050,0x00000010,0x0000024f,0x0000024d,0x0000024e, + 0x00050080,0x00000015,0x00000231,0x0000022a,0x00000061,0x00060041,0x000000bb,0x00000232, + 0x000000b7,0x0000006d,0x00000231,0x0004003d,0x000000b3,0x00000233,0x00000232,0x0007004f, + 0x000000c9,0x00000235,0x00000233,0x00000233,0x00000000,0x00000001,0x0004007c,0x0000000f, + 0x00000236,0x00000235,0x00050091,0x0000000f,0x00000239,0x0000024f,0x00000228,0x00050081, + 0x0000000f,0x0000023b,0x00000239,0x00000236,0x0003003e,0x000000e2,0x00000241,0x00060041, + 0x000000f1,0x000000f2,0x000000ef,0x0000006d,0x00000221,0x0004003d,0x000000c9,0x000000f3, + 0x000000f2,0x00050041,0x000000fd,0x000000fe,0x000000f8,0x000000f9,0x0004003d,0x00000015, + 0x000000ff,0x000000fe,0x000500aa,0x0000004a,0x00000255,0x00000221,0x00000049,0x000300f7, + 0x0000025e,0x00000000,0x000400fa,0x00000255,0x00000256,0x00000257,0x000200f8,0x00000257, + 0x00050080,0x00000015,0x00000259,0x00000221,0x00000051,0x00050084,0x00000015,0x0000025b, + 0x00000259,0x000000ff,0x0006000c,0x0000000f,0x0000025c,0x00000001,0x0000003e,0x0000025b, + 0x00050051,0x00000008,0x0000025d,0x0000025c,0x00000000,0x000200f9,0x0000025e,0x000200f8, + 0x00000256,0x000200f9,0x0000025e,0x000200f8,0x0000025e,0x000700f5,0x00000008,0x00000301, + 0x0000003e,0x00000256,0x0000025d,0x00000257,0x0003003e,0x000000f4,0x00000301,0x00050051, + 0x00000015,0x00000102,0x000000f3,0x00000000,0x000500c7,0x00000015,0x00000104,0x00000102, + 0x00000103,0x000500ab,0x0000004a,0x00000105,0x00000104,0x00000049,0x000300f7,0x00000107, + 0x00000000,0x000400fa,0x00000105,0x00000106,0x00000107,0x000200f8,0x00000106,0x0004003d, + 0x00000008,0x00000108,0x000000f4,0x0004007f,0x00000008,0x00000109,0x00000108,0x0003003e, + 0x000000f4,0x00000109,0x000200f9,0x00000107,0x000200f8,0x00000107,0x000500c7,0x00000015, + 0x0000010e,0x00000102,0x0000010d,0x000300f7,0x00000111,0x00000000,0x000400fa,0x0000010f, + 0x00000110,0x00000111,0x000200f8,0x00000110,0x000500aa,0x0000004a,0x00000114,0x0000010e, + 0x00000049,0x000300f7,0x00000117,0x00000000,0x000400fa,0x00000114,0x00000116,0x0000011a, + 0x000200f8,0x0000011a,0x000200f9,0x00000117,0x000200f8,0x00000116,0x00050051,0x00000015, + 0x00000119,0x000000f3,0x00000001,0x000200f9,0x00000117,0x000200f8,0x00000117,0x000700f5, + 0x00000015,0x00000302,0x00000119,0x00000116,0x00000102,0x0000011a,0x000500c2,0x00000015, + 0x0000011e,0x00000302,0x000000ab,0x000500aa,0x0000004a,0x00000266,0x0000011e,0x00000049, + 0x000300f7,0x0000026f,0x00000000,0x000400fa,0x00000266,0x00000267,0x00000268,0x000200f8, + 0x00000268,0x00050080,0x00000015,0x0000026a,0x0000011e,0x00000051,0x00050084,0x00000015, + 0x0000026c,0x0000026a,0x000000ff,0x0006000c,0x0000000f,0x0000026d,0x00000001,0x0000003e, + 0x0000026c,0x00050051,0x00000008,0x0000026e,0x0000026d,0x00000000,0x000200f9,0x0000026f, + 0x000200f8,0x00000267,0x000200f9,0x0000026f,0x000200f8,0x0000026f,0x000700f5,0x00000008, + 0x00000303,0x0000003e,0x00000267,0x0000026e,0x00000268,0x000300f7,0x00000129,0x00000000, + 0x000400fa,0x00000114,0x00000128,0x00000129,0x000200f8,0x00000128,0x0004007f,0x00000008, + 0x0000012b,0x00000303,0x000200f9,0x00000129,0x000200f8,0x00000129,0x000700f5,0x00000008, + 0x00000304,0x00000303,0x0000026f,0x0000012b,0x00000128,0x00050041,0x000000e1,0x0000012f, + 0x0000012d,0x00000049,0x0003003e,0x0000012f,0x00000304,0x000200f9,0x00000111,0x000200f8, + 0x00000111,0x000300f7,0x00000132,0x00000000,0x000400fa,0x00000130,0x00000131,0x00000132, + 0x000200f8,0x00000131,0x000500c2,0x00000015,0x00000137,0x00000102,0x00000136,0x000500c7, + 0x00000015,0x00000138,0x00000137,0x0000010d,0x00040070,0x00000008,0x00000139,0x00000138, + 0x0003003e,0x00000133,0x00000139,0x000200f9,0x00000132,0x000200f8,0x00000132,0x000300f7, + 0x0000013e,0x00000000,0x000400fa,0x0000013c,0x0000013d,0x0000013e,0x000200f8,0x0000013d, + 0x00050080,0x00000015,0x00000146,0x0000022a,0x000000a2,0x00060041,0x00000148,0x00000149, + 0x00000143,0x0000006d,0x00000146,0x0004003d,0x0000000d,0x0000014a,0x00000149,0x00050051, + 0x00000008,0x00000278,0x0000014a,0x00000000,0x00050051,0x00000008,0x00000279,0x0000014a, + 0x00000001,0x00050051,0x00000008,0x0000027a,0x0000014a,0x00000002,0x00050051,0x00000008, + 0x0000027b,0x0000014a,0x00000003,0x00050050,0x0000000f,0x0000027c,0x00000278,0x00000279, + 0x00050050,0x0000000f,0x0000027d,0x0000027a,0x0000027b,0x00050050,0x00000010,0x0000027e, + 0x0000027c,0x0000027d,0x00050080,0x00000015,0x00000150,0x0000022a,0x0000014f,0x00060041, + 0x00000148,0x00000151,0x00000143,0x0000006d,0x00000150,0x0004003d,0x0000000d,0x00000152, + 0x00000151,0x0007004f,0x0000000f,0x00000159,0x00000152,0x00000152,0x00000000,0x00000001, + 0x000300f7,0x000002b4,0x00000000,0x000300fb,0x00000049,0x00000286,0x000200f8,0x00000286, + 0x0006000c,0x0000000f,0x00000289,0x00000001,0x00000004,0x0000027c,0x0006000c,0x0000000f, + 0x0000028c,0x00000001,0x00000004,0x0000027d,0x00050081,0x0000000f,0x0000028d,0x00000289, + 0x0000028c,0x00050051,0x00000008,0x0000028f,0x0000028d,0x00000000,0x000500b7,0x0000004a, + 0x00000290,0x0000028f,0x0000003e,0x000300f7,0x00000295,0x00000000,0x000400fa,0x00000290, + 0x00000291,0x00000295,0x000200f8,0x00000291,0x00050051,0x00000008,0x00000293,0x0000028d, + 0x00000001,0x000500b7,0x0000004a,0x00000294,0x00000293,0x0000003e,0x000200f9,0x00000295, + 0x000200f8,0x00000295,0x000700f5,0x0000004a,0x00000296,0x00000290,0x00000286,0x00000294, + 0x00000291,0x000300f7,0x000002b3,0x00000000,0x000400fa,0x00000296,0x00000297,0x000002b0, + 0x000200f8,0x000002b0,0x0009004f,0x0000000d,0x000002b2,0x00000152,0x0000030d,0x00000000, + 0x00000001,0x00000000,0x00000001,0x000200f9,0x000002b4,0x000200f8,0x00000297,0x00050088, + 0x0000000f,0x0000029a,0x0000030a,0x0000028d,0x00050091,0x0000000f,0x0000029d,0x0000027e, + 0x0000023b,0x00050081,0x0000000f,0x0000029f,0x0000029d,0x00000159,0x0004007f,0x0000000f, + 0x000002a2,0x0000029f,0x00050051,0x00000008,0x000002a3,0x0000029f,0x00000000,0x00050051, + 0x00000008,0x000002a4,0x0000029f,0x00000001,0x00050051,0x00000008,0x000002a5,0x000002a2, + 0x00000000,0x00050051,0x00000008,0x000002a6,0x000002a2,0x00000001,0x00070050,0x0000000d, + 0x000002a7,0x000002a3,0x000002a4,0x000002a5,0x000002a6,0x0009004f,0x0000000d,0x000002a9, + 0x0000029a,0x0000029a,0x00000000,0x00000001,0x00000000,0x00000001,0x00050085,0x0000000d, + 0x000002aa,0x000002a7,0x000002a9,0x00050081,0x0000000d,0x000002ad,0x000002aa,0x000002a9, + 0x00050081,0x0000000d,0x000002af,0x000002ad,0x0000030b,0x000200f9,0x000002b4,0x000200f8, + 0x000002b3,0x000100ff,0x000200f8,0x000002b4,0x000700f5,0x0000000d,0x00000305,0x000002af, + 0x00000297,0x000002b2,0x000002b0,0x0003003e,0x00000154,0x00000305,0x000200f9,0x0000013e, + 0x000200f8,0x0000013e,0x000500aa,0x0000004a,0x0000015e,0x0000010e,0x00000061,0x000300f7, + 0x00000160,0x00000000,0x000400fa,0x0000015e,0x0000015f,0x00000175,0x000200f8,0x00000175, + 0x000500aa,0x0000004a,0x00000177,0x0000010e,0x00000049,0x000500a7,0x0000004a,0x00000178, + 0x0000010f,0x00000177,0x000300f7,0x0000017a,0x00000000,0x000400fa,0x00000178,0x00000179, + 0x00000186,0x000200f8,0x00000186,0x00060041,0x00000148,0x0000018b,0x00000143,0x0000006d, + 0x0000022a,0x0004003d,0x0000000d,0x0000018c,0x0000018b,0x00050051,0x00000008,0x000002cd, + 0x0000018c,0x00000000,0x00050051,0x00000008,0x000002ce,0x0000018c,0x00000001,0x00050051, + 0x00000008,0x000002cf,0x0000018c,0x00000002,0x00050051,0x00000008,0x000002d0,0x0000018c, + 0x00000003,0x00050050,0x0000000f,0x000002d1,0x000002cd,0x000002ce,0x00050050,0x0000000f, + 0x000002d2,0x000002cf,0x000002d0,0x00050050,0x00000010,0x000002d3,0x000002d1,0x000002d2, + 0x00060041,0x00000148,0x00000192,0x00000143,0x0000006d,0x00000231,0x0004003d,0x0000000d, + 0x00000193,0x00000192,0x00050091,0x0000000f,0x00000197,0x000002d3,0x0000023b,0x0007004f, + 0x0000000f,0x00000199,0x00000193,0x00000193,0x00000000,0x00000001,0x00050081,0x0000000f, + 0x0000019a,0x00000197,0x00000199,0x000500aa,0x0000004a,0x0000019c,0x0000010e,0x000000a2, + 0x000500aa,0x0000004a,0x0000019e,0x0000010e,0x0000014f,0x000500a6,0x0000004a,0x0000019f, + 0x0000019c,0x0000019e,0x000300f7,0x000001a1,0x00000000,0x000400fa,0x0000019f,0x000001a0, + 0x000001c7,0x000200f8,0x000001c7,0x00050051,0x00000015,0x000001ca,0x000000f3,0x00000001, + 0x0004007c,0x00000008,0x000001cb,0x000001ca,0x00050051,0x00000008,0x000001ce,0x00000193, + 0x00000002,0x00050051,0x00000008,0x000001d0,0x0000019a,0x00000000,0x00050051,0x00000008, + 0x000001d2,0x0000019a,0x00000001,0x00050083,0x00000008,0x000001d6,0x000001d4,0x000001ce, + 0x00070050,0x0000000d,0x000001d7,0x000001d0,0x000001d2,0x000001cb,0x000001d6,0x0003003e, + 0x00000173,0x000001d7,0x000200f9,0x000001a1,0x000200f8,0x000001a0,0x00050051,0x00000015, + 0x000001a3,0x000000f3,0x00000001,0x0004007c,0x00000008,0x000001a4,0x000001a3,0x0004007f, + 0x00000008,0x000001a5,0x000001a4,0x00050041,0x000000e1,0x000001a6,0x00000173,0x0000014f, + 0x0003003e,0x000001a6,0x000001a5,0x00050051,0x00000008,0x000001a9,0x00000193,0x00000002, + 0x000500ba,0x0000004a,0x000001ac,0x000001a9,0x000001ab,0x000300f7,0x000001ae,0x00000000, + 0x000400fa,0x000001ac,0x000001ad,0x000001b1,0x000200f8,0x000001b1,0x00050051,0x00000008, + 0x000001b3,0x00000193,0x00000003,0x00050041,0x000000e1,0x000001b4,0x00000173,0x000000a2, + 0x0003003e,0x000001b4,0x000001b3,0x000200f9,0x000001ae,0x000200f8,0x000001ad,0x00050041, + 0x000000e1,0x000001b0,0x00000173,0x000000a2,0x0003003e,0x000001b0,0x000001af,0x000200f9, + 0x000001ae,0x000200f8,0x000001ae,0x000300f7,0x000001b8,0x00000000,0x000400fa,0x0000019c, + 0x000001b7,0x000001bd,0x000200f8,0x000001bd,0x00050041,0x000000e1,0x000001be,0x00000173, + 0x000000a2,0x0004003d,0x00000008,0x000001bf,0x000001be,0x0004007f,0x00000008,0x000001c0, + 0x000001bf,0x0003003e,0x000001be,0x000001c0,0x00050041,0x000000e1,0x000001c3,0x00000173, + 0x00000049,0x00050051,0x00000008,0x000001c4,0x0000019a,0x00000000,0x0003003e,0x000001c3, + 0x000001c4,0x00050041,0x000000e1,0x000001c5,0x00000173,0x00000061,0x00050051,0x00000008, + 0x000001c6,0x0000019a,0x00000001,0x0003003e,0x000001c5,0x000001c6,0x000200f9,0x000001b8, + 0x000200f8,0x000001b7,0x00050041,0x000000e1,0x000001b9,0x00000173,0x00000061,0x0003003e, + 0x000001b9,0x0000003e,0x00050051,0x00000008,0x000001bb,0x0000019a,0x00000000,0x00050041, + 0x000000e1,0x000001bc,0x00000173,0x00000049,0x0003003e,0x000001bc,0x000001bb,0x000200f9, + 0x000001b8,0x000200f8,0x000001b8,0x000200f9,0x000001a1,0x000200f8,0x000001a1,0x000200f9, + 0x0000017a,0x000200f8,0x00000179,0x000500c2,0x00000015,0x0000017e,0x00000102,0x000000ab, + 0x000500aa,0x0000004a,0x000002bb,0x0000017e,0x00000049,0x000300f7,0x000002c4,0x00000000, + 0x000400fa,0x000002bb,0x000002bc,0x000002bd,0x000200f8,0x000002bd,0x00050080,0x00000015, + 0x000002bf,0x0000017e,0x00000051,0x00050084,0x00000015,0x000002c1,0x000002bf,0x000000ff, + 0x0006000c,0x0000000f,0x000002c2,0x00000001,0x0000003e,0x000002c1,0x00050051,0x00000008, + 0x000002c3,0x000002c2,0x00000000,0x000200f9,0x000002c4,0x000200f8,0x000002bc,0x000200f9, + 0x000002c4,0x000200f8,0x000002c4,0x000700f5,0x00000008,0x00000306,0x0000003e,0x000002bc, + 0x000002c3,0x000002bd,0x00050041,0x000000e1,0x00000185,0x0000012d,0x00000061,0x0003003e, + 0x00000185,0x00000306,0x000200f9,0x0000017a,0x000200f8,0x0000017a,0x000200f9,0x00000160, + 0x000200f8,0x0000015f,0x00050051,0x00000015,0x00000163,0x000000f3,0x00000001,0x0006000c, + 0x0000000d,0x00000164,0x00000001,0x00000040,0x00000163,0x000300f7,0x00000167,0x00000000, + 0x000400fa,0x00000165,0x00000166,0x00000167,0x000200f8,0x00000166,0x00050051,0x00000008, + 0x00000169,0x00000164,0x00000003,0x0008004f,0x0000002b,0x0000016b,0x00000164,0x00000164, + 0x00000000,0x00000001,0x00000002,0x0005008e,0x0000002b,0x0000016c,0x0000016b,0x00000169, + 0x00050051,0x00000008,0x0000016e,0x0000016c,0x00000000,0x00060052,0x0000000d,0x000002f1, + 0x0000016e,0x00000164,0x00000000,0x00050051,0x00000008,0x00000170,0x0000016c,0x00000001, + 0x00060052,0x0000000d,0x000002f3,0x00000170,0x000002f1,0x00000001,0x00050051,0x00000008, + 0x00000172,0x0000016c,0x00000002,0x00060052,0x0000000d,0x000002f5,0x00000172,0x000002f3, + 0x00000002,0x000200f9,0x00000167,0x000200f8,0x00000167,0x000700f5,0x0000000d,0x00000307, + 0x00000164,0x0000015f,0x000002f5,0x00000166,0x0003003e,0x00000173,0x00000307,0x000200f9, + 0x00000160,0x000200f8,0x00000160,0x00050041,0x000001e2,0x000001e3,0x000000f8,0x000001dd, + 0x0004003d,0x00000008,0x000001e4,0x000001e3,0x00050041,0x000001e2,0x000001e6,0x000000f8, + 0x000001de,0x0004003d,0x00000008,0x000001e7,0x000001e6,0x00050051,0x00000008,0x000002d7, + 0x0000023b,0x00000000,0x00050085,0x00000008,0x000002d9,0x000002d7,0x000001e4,0x00050083, + 0x00000008,0x000002da,0x000002d9,0x0000003d,0x00050051,0x00000008,0x000002dc,0x0000023b, + 0x00000001,0x00050085,0x00000008,0x000002de,0x000002dc,0x000001e7,0x0006000c,0x00000008, + 0x000002e0,0x00000001,0x00000006,0x000001e7,0x00050083,0x00000008,0x000002e1,0x000002de, + 0x000002e0,0x00070050,0x0000000d,0x000002e2,0x000002da,0x000002e1,0x0000003e,0x0000003d, + 0x00050041,0x00000153,0x000001f9,0x000001f7,0x0000006d,0x0003003e,0x000001f9,0x000002e2, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_interior_triangles.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..337c34b3035709759bca3d37890225efbe2577f9 GIT binary patch literal 9128 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.h new file mode 100644 index 000000000..e49520277 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.h @@ -0,0 +1,201 @@ +#pragma once + +const uint32_t draw_msaa_atlas_blit_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000260,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000120,0x0000012b,0x00000131, + 0x0000014e,0x0000015d,0x0000015e,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00070004,0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000075,0x0000674e,0x00030005,0x00000091, + 0x00006749,0x00030005,0x000000d1,0x00004444,0x00030005,0x000000d5,0x00006277,0x00030005, + 0x000000f7,0x00004344,0x00030005,0x000000f9,0x00003552,0x00030005,0x0000011a,0x00004356, + 0x00030005,0x0000011c,0x00003949,0x00030005,0x00000120,0x00003243,0x00030005,0x0000012b, + 0x0000316b,0x00060005,0x00000131,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x00000134,0x0000424d,0x00040006,0x00000134,0x00000000,0x00006250,0x00040006,0x00000134, + 0x00000001,0x00006359,0x00040006,0x00000134,0x00000002,0x00006552,0x00040006,0x00000134, + 0x00000003,0x00006553,0x00040006,0x00000134,0x00000004,0x0000366d,0x00040006,0x00000134, + 0x00000005,0x0000676d,0x00040006,0x00000134,0x00000006,0x00006544,0x00040006,0x00000134, + 0x00000007,0x00006545,0x00040006,0x00000134,0x00000008,0x00003755,0x00040006,0x00000134, + 0x00000009,0x0000676a,0x00040006,0x00000134,0x0000000a,0x0000635a,0x00040006,0x00000134, + 0x0000000b,0x00003157,0x00040006,0x00000134,0x0000000c,0x0000676e,0x00040006,0x00000134, + 0x0000000d,0x00003559,0x00040006,0x00000134,0x0000000e,0x0000324f,0x00040006,0x00000134, + 0x0000000f,0x00006461,0x00040006,0x00000134,0x00000010,0x00006579,0x00040006,0x00000134, + 0x00000011,0x00003376,0x00040006,0x00000134,0x00000012,0x00003377,0x00040006,0x00000134, + 0x00000013,0x00006462,0x00040006,0x00000134,0x00000014,0x00006767,0x00030005,0x00000136, + 0x0000006b,0x00030005,0x0000014e,0x00006771,0x00030005,0x0000015a,0x00003954,0x00030005, + 0x0000015b,0x00004351,0x00030005,0x0000015d,0x00003346,0x00030005,0x0000015e,0x00003159, + 0x00040047,0x00000075,0x00000001,0x00000007,0x00040047,0x00000091,0x00000001,0x00000002, + 0x00030047,0x000000d1,0x00000000,0x00040047,0x000000d1,0x00000021,0x00000009,0x00040047, + 0x000000d1,0x00000022,0x00000000,0x00030047,0x000000d5,0x00000000,0x00040047,0x000000d5, + 0x00000021,0x00000009,0x00040047,0x000000d5,0x00000022,0x00000000,0x00030047,0x000000f7, + 0x00000000,0x00040047,0x000000f7,0x00000021,0x0000000c,0x00040047,0x000000f7,0x00000022, + 0x00000001,0x00030047,0x000000f9,0x00000000,0x00040047,0x000000f9,0x00000021,0x0000000c, + 0x00040047,0x000000f9,0x00000022,0x00000001,0x00030047,0x0000011a,0x00000000,0x00040047, + 0x0000011a,0x00000021,0x0000000b,0x00040047,0x0000011a,0x00000022,0x00000000,0x00030047, + 0x0000011b,0x00000000,0x00030047,0x0000011c,0x00000000,0x00040047,0x0000011c,0x00000021, + 0x0000000b,0x00040047,0x0000011c,0x00000022,0x00000000,0x00030047,0x0000011d,0x00000000, + 0x00040047,0x00000120,0x0000001e,0x00000001,0x00030047,0x00000122,0x00000000,0x00030047, + 0x00000123,0x00000000,0x00030047,0x00000128,0x00000000,0x00040047,0x0000012b,0x0000001e, + 0x00000000,0x00040047,0x00000131,0x0000000b,0x0000000f,0x00030047,0x00000134,0x00000002, + 0x00050048,0x00000134,0x00000000,0x00000023,0x00000000,0x00050048,0x00000134,0x00000001, + 0x00000023,0x00000004,0x00050048,0x00000134,0x00000002,0x00000023,0x00000008,0x00050048, + 0x00000134,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000134,0x00000004,0x00000023, + 0x00000010,0x00050048,0x00000134,0x00000005,0x00000023,0x00000014,0x00050048,0x00000134, + 0x00000006,0x00000023,0x00000018,0x00050048,0x00000134,0x00000007,0x00000023,0x0000001c, + 0x00050048,0x00000134,0x00000008,0x00000023,0x00000020,0x00050048,0x00000134,0x00000009, + 0x00000023,0x00000030,0x00050048,0x00000134,0x0000000a,0x00000023,0x00000038,0x00050048, + 0x00000134,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000134,0x0000000c,0x00000023, + 0x00000044,0x00050048,0x00000134,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000134, + 0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000134,0x0000000f,0x00000023,0x00000050, + 0x00050048,0x00000134,0x00000010,0x00000023,0x00000054,0x00050048,0x00000134,0x00000011, + 0x00000023,0x00000058,0x00050048,0x00000134,0x00000012,0x00000023,0x0000005c,0x00050048, + 0x00000134,0x00000013,0x00000023,0x00000060,0x00050048,0x00000134,0x00000014,0x00000023, + 0x00000064,0x00040047,0x00000136,0x00000021,0x00000000,0x00040047,0x00000136,0x00000022, + 0x00000000,0x00030047,0x0000013b,0x00000000,0x00030047,0x0000014e,0x00000000,0x00040047, + 0x0000014e,0x0000001e,0x00000000,0x00030047,0x0000015a,0x00000000,0x00040047,0x0000015a, + 0x00000021,0x0000000a,0x00040047,0x0000015a,0x00000022,0x00000000,0x00030047,0x0000015b, + 0x00000000,0x00040047,0x0000015b,0x00000021,0x0000000a,0x00040047,0x0000015b,0x00000022, + 0x00000000,0x00030047,0x0000015d,0x00000000,0x00030047,0x0000015d,0x0000000e,0x00040047, + 0x0000015d,0x0000001e,0x00000004,0x00030047,0x0000015e,0x00000000,0x00030047,0x0000015e, + 0x0000000e,0x00040047,0x0000015e,0x0000001e,0x00000006,0x00030047,0x00000181,0x00000000, + 0x00030047,0x000001ab,0x00000000,0x00030047,0x000001ac,0x00000000,0x00030047,0x000001b1, + 0x00000000,0x00030047,0x000001b4,0x00000000,0x00030047,0x000001b9,0x00000000,0x00030047, + 0x000001bb,0x00000000,0x00030047,0x000001bc,0x00000000,0x00030047,0x000001c9,0x00000000, + 0x00030047,0x000001ca,0x00000000,0x00030047,0x000001cf,0x00000000,0x00030047,0x000001d7, + 0x00000000,0x00030047,0x000001de,0x00000000,0x00030047,0x000001ed,0x00000000,0x00030047, + 0x000001ef,0x00000000,0x00030047,0x000001f4,0x00000000,0x00030047,0x000001f8,0x00000000, + 0x00030047,0x00000212,0x00000000,0x00030047,0x00000213,0x00000000,0x00030047,0x00000225, + 0x00000000,0x00030047,0x00000226,0x00000000,0x00030047,0x00000229,0x00000000,0x00030047, + 0x0000022b,0x00000000,0x00030047,0x0000022f,0x00000000,0x00030047,0x00000237,0x00000000, + 0x00030047,0x0000023a,0x00000000,0x00030047,0x0000023c,0x00000000,0x00030047,0x0000023e, + 0x00000000,0x00030047,0x00000245,0x00000000,0x00030047,0x00000247,0x00000000,0x00030047, + 0x00000249,0x00000000,0x00030047,0x0000024b,0x00000000,0x00030047,0x0000024f,0x00000000, + 0x00030047,0x00000251,0x00000000,0x00030047,0x00000253,0x00000000,0x00030047,0x00000254, + 0x00000000,0x00030047,0x0000025b,0x00000000,0x00030047,0x0000025d,0x00000000,0x00030047, + 0x0000025e,0x00000000,0x00030047,0x0000025c,0x00000000,0x00030047,0x0000025a,0x00000000, + 0x00030047,0x0000025f,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017, + 0x00000012,0x00000006,0x00000003,0x00040017,0x0000001d,0x00000006,0x00000002,0x00040015, + 0x0000003b,0x00000020,0x00000000,0x0004002b,0x00000006,0x0000004f,0x00000000,0x00020014, + 0x00000050,0x0004002b,0x00000006,0x00000055,0x3f800000,0x0004002b,0x00000006,0x0000005f, + 0x3d897143,0x0004002b,0x00000006,0x00000063,0x3bbf4590,0x0004002b,0x00000006,0x0000006a, + 0x4253ee82,0x00030030,0x00000050,0x00000075,0x00030030,0x00000050,0x00000091,0x00050034, + 0x00000050,0x00000092,0x000000a8,0x00000091,0x0004002b,0x00000006,0x000000a1,0xbf800000, + 0x0004002b,0x00000006,0x000000bf,0x3f7f8000,0x0004002b,0x00000006,0x000000c2,0x3a800000, + 0x0004002b,0x00000006,0x000000c5,0x3b000000,0x00090019,0x000000cf,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000000d0,0x00000000, + 0x000000cf,0x0004003b,0x000000d0,0x000000d1,0x00000000,0x0002001a,0x000000d3,0x00040020, + 0x000000d4,0x00000000,0x000000d3,0x0004003b,0x000000d4,0x000000d5,0x00000000,0x0003001b, + 0x000000d7,0x000000cf,0x00050034,0x00000050,0x000000e2,0x000000a8,0x00000091,0x0004002b, + 0x00000006,0x000000f5,0x40000000,0x0004003b,0x000000d0,0x000000f7,0x00000000,0x0004003b, + 0x000000d4,0x000000f9,0x00000000,0x00050034,0x00000050,0x00000105,0x000000a8,0x00000091, + 0x0004003b,0x000000d0,0x0000011a,0x00000000,0x0004003b,0x000000d4,0x0000011c,0x00000000, + 0x00040020,0x0000011f,0x00000001,0x0000001d,0x0004003b,0x0000011f,0x00000120,0x00000001, + 0x00040020,0x0000012a,0x00000001,0x00000007,0x0004003b,0x0000012a,0x0000012b,0x00000001, + 0x0004003b,0x0000012a,0x00000131,0x00000001,0x00040015,0x00000132,0x00000020,0x00000001, + 0x00040017,0x00000133,0x00000132,0x00000004,0x0017001e,0x00000134,0x00000006,0x00000006, + 0x00000006,0x00000006,0x0000003b,0x0000003b,0x0000003b,0x0000003b,0x00000133,0x0000001d, + 0x0000001d,0x0000003b,0x00000006,0x0000003b,0x00000006,0x00000006,0x0000003b,0x00000006, + 0x00000006,0x00000006,0x0000003b,0x00040020,0x00000135,0x00000002,0x00000134,0x0004003b, + 0x00000135,0x00000136,0x00000002,0x0004002b,0x00000132,0x00000137,0x00000011,0x0004002b, + 0x00000132,0x00000138,0x00000012,0x00040020,0x00000140,0x00000002,0x00000006,0x00040020, + 0x0000014d,0x00000003,0x00000007,0x0004003b,0x0000014d,0x0000014e,0x00000003,0x0004003b, + 0x000000d4,0x0000015a,0x00000000,0x0004003b,0x000000d0,0x0000015b,0x00000000,0x00040020, + 0x0000015c,0x00000001,0x00000006,0x0004003b,0x0000015c,0x0000015d,0x00000001,0x0004003b, + 0x0000015c,0x0000015e,0x00000001,0x00030001,0x00000007,0x00000257,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x000000cf,0x0000011b, + 0x0000011a,0x0004003d,0x000000d3,0x0000011d,0x0000011c,0x00050056,0x000000d7,0x0000011e, + 0x0000011b,0x0000011d,0x0004003d,0x0000001d,0x00000121,0x00000120,0x00070058,0x00000007, + 0x00000122,0x0000011e,0x00000121,0x00000002,0x0000004f,0x00050051,0x00000006,0x00000123, + 0x00000122,0x00000000,0x0008000c,0x00000006,0x00000128,0x00000001,0x0000002b,0x00000123, + 0x0000004f,0x00000055,0x0004003d,0x00000007,0x0000012d,0x0000012b,0x00050051,0x00000006, + 0x00000175,0x0000012d,0x00000003,0x000500be,0x00000050,0x00000176,0x00000175,0x0000004f, + 0x000300f7,0x000001e2,0x00000000,0x000400fa,0x00000176,0x00000177,0x00000185,0x000200f8, + 0x00000177,0x000300f7,0x00000184,0x00000000,0x000400fa,0x00000092,0x0000017a,0x0000017e, + 0x000200f8,0x0000017a,0x0005008e,0x00000007,0x0000017d,0x0000012d,0x00000128,0x000200f9, + 0x00000184,0x000200f8,0x0000017e,0x00050051,0x00000006,0x00000181,0x0000012d,0x00000003, + 0x00050085,0x00000006,0x00000182,0x00000181,0x00000128,0x00060052,0x00000007,0x0000022f, + 0x00000182,0x0000012d,0x00000003,0x000200f9,0x00000184,0x000200f8,0x00000184,0x000700f5, + 0x00000007,0x0000025b,0x0000017d,0x0000017a,0x0000022f,0x0000017e,0x000200f9,0x000001e2, + 0x000200f8,0x00000185,0x000500ba,0x00000050,0x00000188,0x00000175,0x000000a1,0x000300f7, + 0x000001e1,0x00000000,0x000400fa,0x00000188,0x00000189,0x000001c4,0x000200f8,0x00000189, + 0x00050051,0x00000006,0x0000018b,0x0000012d,0x00000002,0x000500ba,0x00000050,0x0000018c, + 0x0000018b,0x0000004f,0x000300f7,0x00000194,0x00000000,0x000400fa,0x0000018c,0x0000018d, + 0x00000190,0x000200f8,0x0000018d,0x00050051,0x00000006,0x0000018f,0x0000012d,0x00000000, + 0x000200f9,0x00000194,0x000200f8,0x00000190,0x0007004f,0x0000001d,0x00000192,0x0000012d, + 0x0000012d,0x00000000,0x00000001,0x0006000c,0x00000006,0x00000193,0x00000001,0x00000042, + 0x00000192,0x000200f9,0x00000194,0x000200f8,0x00000194,0x000700f5,0x00000006,0x00000258, + 0x0000018f,0x0000018d,0x00000193,0x00000190,0x0008000c,0x00000006,0x00000197,0x00000001, + 0x0000002b,0x00000258,0x0000004f,0x00000055,0x0006000c,0x00000006,0x0000019a,0x00000001, + 0x00000004,0x0000018b,0x000500ba,0x00000050,0x0000019c,0x0000019a,0x00000055,0x000300f7, + 0x000001a6,0x00000000,0x000400fa,0x0000019c,0x0000019d,0x000001a1,0x000200f8,0x0000019d, + 0x00050085,0x00000006,0x0000019f,0x000000bf,0x00000197,0x00050081,0x00000006,0x000001a0, + 0x0000019f,0x000000c2,0x000200f9,0x000001a6,0x000200f8,0x000001a1,0x00050085,0x00000006, + 0x000001a3,0x000000c5,0x00000197,0x00050081,0x00000006,0x000001a5,0x000001a3,0x0000019a, + 0x000200f9,0x000001a6,0x000200f8,0x000001a6,0x000700f5,0x00000006,0x00000259,0x000001a0, + 0x0000019d,0x000001a5,0x000001a1,0x0004007f,0x00000006,0x000001aa,0x00000175,0x0004003d, + 0x000000cf,0x000001ab,0x000000d1,0x0004003d,0x000000d3,0x000001ac,0x000000d5,0x00050056, + 0x000000d7,0x000001ad,0x000001ab,0x000001ac,0x00050050,0x0000001d,0x000001b0,0x00000259, + 0x000001aa,0x00070058,0x00000007,0x000001b1,0x000001ad,0x000001b0,0x00000002,0x0000004f, + 0x00050051,0x00000006,0x000001b4,0x000001b1,0x00000003,0x00050085,0x00000006,0x000001b5, + 0x000001b4,0x00000128,0x00060052,0x00000007,0x00000237,0x000001b5,0x000001b1,0x00000003, + 0x000300f7,0x000001c3,0x00000000,0x000400fa,0x000000e2,0x000001b7,0x000001c3,0x000200f8, + 0x000001b7,0x00050051,0x00000006,0x000001b9,0x00000237,0x00000003,0x0008004f,0x00000012, + 0x000001bb,0x00000237,0x00000237,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000012, + 0x000001bc,0x000001bb,0x000001b9,0x00050051,0x00000006,0x000001be,0x000001bc,0x00000000, + 0x00060052,0x00000007,0x0000023a,0x000001be,0x00000237,0x00000000,0x00050051,0x00000006, + 0x000001c0,0x000001bc,0x00000001,0x00060052,0x00000007,0x0000023c,0x000001c0,0x0000023a, + 0x00000001,0x00050051,0x00000006,0x000001c2,0x000001bc,0x00000002,0x00060052,0x00000007, + 0x0000023e,0x000001c2,0x0000023c,0x00000002,0x000200f9,0x000001c3,0x000200f8,0x000001c3, + 0x000700f5,0x00000007,0x0000025d,0x00000237,0x000001a6,0x0000023e,0x000001b7,0x000200f9, + 0x000001e1,0x000200f8,0x000001c4,0x0004007f,0x00000006,0x000001c7,0x00000175,0x00050083, + 0x00000006,0x000001c8,0x000001c7,0x000000f5,0x0004003d,0x000000cf,0x000001c9,0x000000f7, + 0x0004003d,0x000000d3,0x000001ca,0x000000f9,0x00050056,0x000000d7,0x000001cb,0x000001c9, + 0x000001ca,0x0007004f,0x0000001d,0x000001cd,0x0000012d,0x0000012d,0x00000000,0x00000001, + 0x00070058,0x00000007,0x000001cf,0x000001cb,0x000001cd,0x00000002,0x000001c8,0x00050051, + 0x00000006,0x000001d1,0x0000012d,0x00000002,0x00050085,0x00000006,0x000001d3,0x000001d1, + 0x00000128,0x000300f7,0x000001e0,0x00000000,0x000400fa,0x00000105,0x000001d4,0x000001d8, + 0x000200f8,0x000001d4,0x0005008e,0x00000007,0x000001d7,0x000001cf,0x000001d3,0x000200f9, + 0x000001e0,0x000200f8,0x000001d8,0x0008004f,0x00000012,0x000001ed,0x000001cf,0x000001cf, + 0x00000000,0x00000001,0x00000002,0x00050051,0x00000006,0x000001ef,0x000001cf,0x00000003, + 0x000500b7,0x00000050,0x000001f0,0x000001ef,0x0000004f,0x000300f7,0x000001f6,0x00000000, + 0x000400fa,0x000001f0,0x000001f1,0x000001f5,0x000200f8,0x000001f1,0x00050088,0x00000006, + 0x000001f4,0x00000055,0x000001ef,0x000200f9,0x000001f6,0x000200f8,0x000001f5,0x000200f9, + 0x000001f6,0x000200f8,0x000001f6,0x000700f5,0x00000006,0x00000254,0x000001f4,0x000001f1, + 0x0000004f,0x000001f5,0x0005008e,0x00000012,0x000001f8,0x000001ed,0x00000254,0x00050085, + 0x00000006,0x000001de,0x000001ef,0x000001d3,0x00050051,0x00000006,0x000001fe,0x000001f8, + 0x00000000,0x00060052,0x00000007,0x00000245,0x000001fe,0x00000257,0x00000000,0x00050051, + 0x00000006,0x00000200,0x000001f8,0x00000001,0x00060052,0x00000007,0x00000247,0x00000200, + 0x00000245,0x00000001,0x00050051,0x00000006,0x00000202,0x000001f8,0x00000002,0x00060052, + 0x00000007,0x00000249,0x00000202,0x00000247,0x00000002,0x00060052,0x00000007,0x0000024b, + 0x000001de,0x00000249,0x00000003,0x000200f9,0x000001e0,0x000200f8,0x000001e0,0x000700f5, + 0x00000007,0x0000025e,0x000001d7,0x000001d4,0x0000024b,0x000001f6,0x000200f9,0x000001e1, + 0x000200f8,0x000001e1,0x000700f5,0x00000007,0x0000025c,0x0000025d,0x000001c3,0x0000025e, + 0x000001e0,0x000200f9,0x000001e2,0x000200f8,0x000001e2,0x000700f5,0x00000007,0x0000025a, + 0x0000025b,0x00000184,0x0000025c,0x000001e1,0x0008004f,0x00000012,0x0000013b,0x0000025a, + 0x0000025a,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,0x0000013d,0x00000131, + 0x0007004f,0x0000001d,0x0000013e,0x0000013d,0x0000013d,0x00000000,0x00000001,0x00050041, + 0x00000140,0x00000141,0x00000136,0x00000137,0x0004003d,0x00000006,0x00000142,0x00000141, + 0x00050041,0x00000140,0x00000144,0x00000136,0x00000138,0x0004003d,0x00000006,0x00000145, + 0x00000144,0x000300f7,0x00000216,0x00000000,0x000400fa,0x00000075,0x0000020c,0x00000214, + 0x000200f8,0x0000020c,0x00050051,0x00000006,0x0000021d,0x0000013e,0x00000000,0x00050085, + 0x00000006,0x0000021e,0x0000005f,0x0000021d,0x00050051,0x00000006,0x00000220,0x0000013e, + 0x00000001,0x00050085,0x00000006,0x00000221,0x00000063,0x00000220,0x00050081,0x00000006, + 0x00000222,0x0000021e,0x00000221,0x0006000c,0x00000006,0x00000223,0x00000001,0x0000000a, + 0x00000222,0x00050085,0x00000006,0x00000225,0x0000006a,0x00000223,0x0006000c,0x00000006, + 0x00000226,0x00000001,0x0000000a,0x00000225,0x00050085,0x00000006,0x00000229,0x00000226, + 0x00000142,0x00050081,0x00000006,0x0000022b,0x00000229,0x00000145,0x00060050,0x00000012, + 0x00000212,0x0000022b,0x0000022b,0x0000022b,0x00050081,0x00000012,0x00000213,0x00000212, + 0x0000013b,0x000200f9,0x00000216,0x000200f8,0x00000214,0x000200f9,0x00000216,0x000200f8, + 0x00000216,0x000700f5,0x00000012,0x0000025f,0x00000213,0x0000020c,0x0000013b,0x00000214, + 0x00050051,0x00000006,0x00000148,0x0000025f,0x00000000,0x00060052,0x00000007,0x0000024f, + 0x00000148,0x0000025a,0x00000000,0x00050051,0x00000006,0x0000014a,0x0000025f,0x00000001, + 0x00060052,0x00000007,0x00000251,0x0000014a,0x0000024f,0x00000001,0x00050051,0x00000006, + 0x0000014c,0x0000025f,0x00000002,0x00060052,0x00000007,0x00000253,0x0000014c,0x00000251, + 0x00000002,0x0003003e,0x0000014e,0x00000253,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..cfe16c97787dccd4ce30a1907e5aab68abb63624 GIT binary patch literal 6296 zcmZ9QX>3(h6ooH+Eg)1GMP>4p2BQ*?nMwtr0|hO-LYb#WhX)o*3!M-XWl$1`6QGHS z(I_z*BbsP}Au0ib8WlB2z~C>U{6{na0TYeuyZ7vN$CIACwbx$zjQiYkZ&P{2eWIvW z)IaJQZODt_GAPOu6N&2`|5jDkR!?Z}Xq+&0+C&7mMX6YaW`I=r`lW8EYihxfmSddi zB-KT#>r~gP4pbaEbtsflFH!V^`246}R8^gwyQD1J{#adOt}WZ%(b`tGDVMG9+_+I@ zYyIY2Lx*(z(N(Tonr*M!vb8za)|_i^&vxXV=;&pzwl#&k9#mB>d09+v^j29lkulH-(o>OYm^5%ksdF6khOP z!n3yJlM~DuKRyZEJ6`Ke&DnWcw({22wnjA-k724b3(F!Y@*^;%Mtz$NwW^`VW>1!A zUChr;*E&0%@AMvjf&5!EN7MI~UE%cXb)~cW%3e03M}Ld#%`U#5?A2~O{bjGv9IgFA z*)2|gtL#-;GxOgjJEQe6dw}dZt%lhHW$$p~86>-FN{@fA?Cs7TBD>zj50$-1{jv}g58!3Qo< zW!=mkBTPX{Zc*@oy%yVR$vp~MFk05vY_yDvcF9c&KCstfdo8(3K?_F9KAP>vFrr(V zipX;cIbBDsZf=am1h_AC2QI!I5Leah~ArbX=dnjdUFSp-VfC9D(DZ zZS8Ts;7T0Fyy50JjR9lpom`y3wU@B>&B;Yx?A z9A4n?qYh^rUhHtK!%H1rMT}mtCsgv?^tsY_yr!;yIKTpJC&d#r&>^&Cbd$-?o32*$uJ}RGus~ zd$a64zt@&cRPQ_sI#msG$4%9<75>Fn zOE=>gVdfE1Eb%xyt$F?wShS_V=5D17*Syc^7v1@oiDDZaHuorHgywZYzqDa$?i{T!nSd873jPY*yaI?4gvD1OWe}BN_27YYb9rf33 zbN^wJ6O#qf!r0`@6ahGLYP1;cL)O<<^2k?W7*8^$M2p{IJch$&tkV=nZqf&1#pYQK z$6hmz8LHeJW|zn&&xxNSjFvXB7s@90ZSL5-tHIe?+A|-Uys+mw@oS~kU)&ykY@XS0 zX7g;u?xj}gXN3kZUAfITSThR!-4MeaKT9k*GeSY^D>nJYI}Q7~Tq^Qvv@jZYG^}Nj za9VYxdZI7hb{0LVK~Nr zLhW*1yJW)?dtIJO!j!+&2EOg8dsUe)7|pZ#H4W$eN!d>a4fsX1P5(~`(;wr!sd(aO z2d#~XyU)h7H_Ua9IC$cgXr{EqeE@G--yZE=lL{TrX8L6u#LyR7=0)Gk<+CvNeZtKB zu;Q54Z^9Jjj&Hx}SE|H;ZOqRJGYs5tzbLz~+tvf+Ks^WFn*TGseW*%a3Jl75fLhGVV3 z)(7u}#M4Jc&kLTZydT0*DKg`+abEEs7lDRYYv+V8JjKo;?_luOj%mLLTI8nX9Sxos zc+;K=T83g;-r?YhfoDH$Zv5IA=bekb*<)guH(Jgw>%f_{{ryIm{e33n*|)-Q+~cibT9xZay#@`6yiGeq5UeM~NTgx{DJTac?1L(1zO8peof0a1i4P`6GuB}?Jncjw0vW5_i+~zM?01SrNa2B6q)hZ z$#?F|St2II`sBWuEeuDc@H1C?JV#)z>U7l^s>JgQEepJ9DuSlOX)1-`$?sud9OP4{ z;tORDRV7!zw*I4p84Jbsf3!HhRq&ZE9dt-dS0t`MHa@#!#t0LS&+fKjVdD6|0Dg-f zE6g_!e$(>ZYFhlJtKEHEep@QYqUx{U->qMw~7{??__-J6Z^~huokR|x8d1u zV)%|Ej`boAt*ys=+4h}jInFmOyybvt9|>ChbmutV!0^Pto3=V=MR#lYMusN_ezx|P McXIfD6kVeFAA_zqhyVZp literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.h new file mode 100644 index 000000000..969ab050b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.h @@ -0,0 +1,717 @@ +#pragma once + +const uint32_t draw_msaa_atlas_blit_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000d73,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000c000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000399, + 0x000003a4,0x000003ac,0x000003d5,0x000003f5,0x00000410,0x0000041d,0x00030010,0x00000004, + 0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168, + 0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47, + 0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69, + 0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c, + 0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63, + 0x69645f65,0x74636572,0x00657669,0x00070004,0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65, + 0x62616972,0x0073656c,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000105, + 0x0000674e,0x00030005,0x000002b0,0x0000674d,0x00030005,0x0000030b,0x00006749,0x00030005, + 0x0000034b,0x00004444,0x00030005,0x0000034f,0x00006277,0x00030005,0x00000370,0x00004344, + 0x00030005,0x00000372,0x00003552,0x00030005,0x00000393,0x00004356,0x00030005,0x00000395, + 0x00003949,0x00030005,0x00000399,0x00003243,0x00030005,0x000003a4,0x0000316b,0x00030005, + 0x000003ac,0x00003159,0x00030005,0x000003b3,0x0000444a,0x00060005,0x000003d5,0x535f6c67, + 0x6c706d61,0x73614d65,0x006e496b,0x00060005,0x000003f5,0x465f6c67,0x43676172,0x64726f6f, + 0x00000000,0x00030005,0x000003f6,0x0000424d,0x00040006,0x000003f6,0x00000000,0x00006250, + 0x00040006,0x000003f6,0x00000001,0x00006359,0x00040006,0x000003f6,0x00000002,0x00006552, + 0x00040006,0x000003f6,0x00000003,0x00006553,0x00040006,0x000003f6,0x00000004,0x0000366d, + 0x00040006,0x000003f6,0x00000005,0x0000676d,0x00040006,0x000003f6,0x00000006,0x00006544, + 0x00040006,0x000003f6,0x00000007,0x00006545,0x00040006,0x000003f6,0x00000008,0x00003755, + 0x00040006,0x000003f6,0x00000009,0x0000676a,0x00040006,0x000003f6,0x0000000a,0x0000635a, + 0x00040006,0x000003f6,0x0000000b,0x00003157,0x00040006,0x000003f6,0x0000000c,0x0000676e, + 0x00040006,0x000003f6,0x0000000d,0x00003559,0x00040006,0x000003f6,0x0000000e,0x0000324f, + 0x00040006,0x000003f6,0x0000000f,0x00006461,0x00040006,0x000003f6,0x00000010,0x00006579, + 0x00040006,0x000003f6,0x00000011,0x00003376,0x00040006,0x000003f6,0x00000012,0x00003377, + 0x00040006,0x000003f6,0x00000013,0x00006462,0x00040006,0x000003f6,0x00000014,0x00006767, + 0x00030005,0x000003f8,0x0000006b,0x00030005,0x00000410,0x00006771,0x00030005,0x0000041b, + 0x00003954,0x00030005,0x0000041c,0x00004351,0x00030005,0x0000041d,0x00003346,0x00040047, + 0x00000105,0x00000001,0x00000007,0x00040047,0x000002b0,0x00000001,0x00000006,0x00040047, + 0x0000030b,0x00000001,0x00000002,0x00030047,0x0000034b,0x00000000,0x00040047,0x0000034b, + 0x00000021,0x00000009,0x00040047,0x0000034b,0x00000022,0x00000000,0x00030047,0x0000034f, + 0x00000000,0x00040047,0x0000034f,0x00000021,0x00000009,0x00040047,0x0000034f,0x00000022, + 0x00000000,0x00030047,0x00000370,0x00000000,0x00040047,0x00000370,0x00000021,0x0000000c, + 0x00040047,0x00000370,0x00000022,0x00000001,0x00030047,0x00000372,0x00000000,0x00040047, + 0x00000372,0x00000021,0x0000000c,0x00040047,0x00000372,0x00000022,0x00000001,0x00030047, + 0x00000393,0x00000000,0x00040047,0x00000393,0x00000021,0x0000000b,0x00040047,0x00000393, + 0x00000022,0x00000000,0x00030047,0x00000394,0x00000000,0x00030047,0x00000395,0x00000000, + 0x00040047,0x00000395,0x00000021,0x0000000b,0x00040047,0x00000395,0x00000022,0x00000000, + 0x00030047,0x00000396,0x00000000,0x00040047,0x00000399,0x0000001e,0x00000001,0x00030047, + 0x0000039b,0x00000000,0x00030047,0x0000039c,0x00000000,0x00030047,0x000003a1,0x00000000, + 0x00040047,0x000003a4,0x0000001e,0x00000000,0x00030047,0x000003ac,0x00000000,0x00030047, + 0x000003ac,0x0000000e,0x00040047,0x000003ac,0x0000001e,0x00000006,0x00030047,0x000003ae, + 0x00000000,0x00030047,0x000003b3,0x00000000,0x00040047,0x000003b3,0x00000021,0x00000000, + 0x00040047,0x000003b3,0x00000022,0x00000002,0x00040047,0x000003b3,0x0000002b,0x00000000, + 0x00030047,0x000003b4,0x00000000,0x00030047,0x000003b7,0x00000000,0x00030047,0x000003b8, + 0x00000000,0x00030047,0x000003b9,0x00000000,0x00030047,0x000003ba,0x00000000,0x00030047, + 0x000003bb,0x00000000,0x00030047,0x000003bc,0x00000000,0x00030047,0x000003bd,0x00000000, + 0x00030047,0x000003be,0x00000000,0x00030047,0x000003bf,0x00000000,0x00030047,0x000003c0, + 0x00000000,0x00030047,0x000003c1,0x00000000,0x00030047,0x000003c2,0x00000000,0x00030047, + 0x000003c3,0x00000000,0x00030047,0x000003c4,0x00000000,0x00030047,0x000003c5,0x00000000, + 0x00030047,0x000003c6,0x00000000,0x00030047,0x000003c7,0x00000000,0x00030047,0x000003c8, + 0x00000000,0x00030047,0x000003c9,0x00000000,0x00030047,0x000003ca,0x00000000,0x00030047, + 0x000003cb,0x00000000,0x00030047,0x000003cc,0x00000000,0x00030047,0x000003cd,0x00000000, + 0x00030047,0x000003ce,0x00000000,0x00030047,0x000003cf,0x00000000,0x00030047,0x000003d0, + 0x00000000,0x00030047,0x000003d1,0x00000000,0x00030047,0x000003d2,0x00000000,0x00040047, + 0x000003d5,0x0000000b,0x00000014,0x00030047,0x000003d5,0x0000000e,0x00030047,0x000003de, + 0x00000000,0x00030047,0x000003eb,0x00000000,0x00030047,0x000003ed,0x00000000,0x00030047, + 0x000003ee,0x00000000,0x00040047,0x000003f5,0x0000000b,0x0000000f,0x00030047,0x000003f6, + 0x00000002,0x00050048,0x000003f6,0x00000000,0x00000023,0x00000000,0x00050048,0x000003f6, + 0x00000001,0x00000023,0x00000004,0x00050048,0x000003f6,0x00000002,0x00000023,0x00000008, + 0x00050048,0x000003f6,0x00000003,0x00000023,0x0000000c,0x00050048,0x000003f6,0x00000004, + 0x00000023,0x00000010,0x00050048,0x000003f6,0x00000005,0x00000023,0x00000014,0x00050048, + 0x000003f6,0x00000006,0x00000023,0x00000018,0x00050048,0x000003f6,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x000003f6,0x00000008,0x00000023,0x00000020,0x00050048,0x000003f6, + 0x00000009,0x00000023,0x00000030,0x00050048,0x000003f6,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x000003f6,0x0000000b,0x00000023,0x00000040,0x00050048,0x000003f6,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x000003f6,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x000003f6,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000003f6,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x000003f6,0x00000010,0x00000023,0x00000054,0x00050048,0x000003f6, + 0x00000011,0x00000023,0x00000058,0x00050048,0x000003f6,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x000003f6,0x00000013,0x00000023,0x00000060,0x00050048,0x000003f6,0x00000014, + 0x00000023,0x00000064,0x00040047,0x000003f8,0x00000021,0x00000000,0x00040047,0x000003f8, + 0x00000022,0x00000000,0x00030047,0x000003fd,0x00000000,0x00030047,0x00000410,0x00000000, + 0x00040047,0x00000410,0x0000001e,0x00000000,0x00030047,0x0000041b,0x00000000,0x00040047, + 0x0000041b,0x00000021,0x0000000a,0x00040047,0x0000041b,0x00000022,0x00000000,0x00030047, + 0x0000041c,0x00000000,0x00040047,0x0000041c,0x00000021,0x0000000a,0x00040047,0x0000041c, + 0x00000022,0x00000000,0x00030047,0x0000041d,0x00000000,0x00030047,0x0000041d,0x0000000e, + 0x00040047,0x0000041d,0x0000001e,0x00000004,0x00030047,0x00000448,0x00000000,0x00030047, + 0x00000472,0x00000000,0x00030047,0x00000473,0x00000000,0x00030047,0x00000478,0x00000000, + 0x00030047,0x0000047b,0x00000000,0x00030047,0x00000480,0x00000000,0x00030047,0x00000482, + 0x00000000,0x00030047,0x00000483,0x00000000,0x00030047,0x00000490,0x00000000,0x00030047, + 0x00000491,0x00000000,0x00030047,0x00000496,0x00000000,0x00030047,0x0000049e,0x00000000, + 0x00030047,0x000004a5,0x00000000,0x00030047,0x000004b4,0x00000000,0x00030047,0x000004b6, + 0x00000000,0x00030047,0x000004bb,0x00000000,0x00030047,0x000004bf,0x00000000,0x00030047, + 0x000004d0,0x00000000,0x00030047,0x000004dd,0x00000000,0x00030047,0x000004df,0x00000000, + 0x00030047,0x000004e0,0x00000000,0x00030047,0x000004e2,0x00000000,0x00030047,0x000004e3, + 0x00000000,0x00030047,0x000004e5,0x00000000,0x00030047,0x000004e6,0x00000000,0x00030047, + 0x000004e7,0x00000000,0x00030047,0x000004ed,0x00000000,0x00030047,0x000004f0,0x00000000, + 0x00030047,0x00000506,0x00000000,0x00030047,0x00000515,0x00000000,0x00030047,0x00000516, + 0x00000000,0x00030047,0x00000518,0x00000000,0x00030047,0x00000542,0x00000000,0x00030047, + 0x00000544,0x00000000,0x00030047,0x00000546,0x00000000,0x00030047,0x00000548,0x00000000, + 0x00030047,0x0000054b,0x00000000,0x00030047,0x0000054c,0x00000000,0x00030047,0x0000054e, + 0x00000000,0x00030047,0x00000550,0x00000000,0x00030047,0x00000554,0x00000000,0x00030047, + 0x00000556,0x00000000,0x00030047,0x00000558,0x00000000,0x00030047,0x0000055b,0x00000000, + 0x00030047,0x0000055c,0x00000000,0x00030047,0x0000055d,0x00000000,0x00030047,0x0000055f, + 0x00000000,0x00030047,0x00000561,0x00000000,0x00030047,0x00000563,0x00000000,0x00030047, + 0x00000565,0x00000000,0x00030047,0x0000056b,0x00000000,0x00030047,0x0000056c,0x00000000, + 0x00030047,0x00000573,0x00000000,0x00030047,0x00000575,0x00000000,0x00030047,0x00000578, + 0x00000000,0x00030047,0x0000057a,0x00000000,0x00030047,0x0000057b,0x00000000,0x00030047, + 0x0000057e,0x00000000,0x00030047,0x00000580,0x00000000,0x00030047,0x00000581,0x00000000, + 0x00030047,0x00000584,0x00000000,0x00030047,0x00000587,0x00000000,0x00030047,0x00000588, + 0x00000000,0x00030047,0x0000058a,0x00000000,0x00030047,0x0000058d,0x00000000,0x00030047, + 0x00000592,0x00000000,0x00030047,0x00000593,0x00000000,0x00030047,0x0000059b,0x00000000, + 0x00030047,0x000005a1,0x00000000,0x00030047,0x000005a3,0x00000000,0x00030047,0x000005a4, + 0x00000000,0x00030047,0x000005a5,0x00000000,0x00030047,0x000005a8,0x00000000,0x00030047, + 0x000005ab,0x00000000,0x00030047,0x000005ac,0x00000000,0x00030047,0x000005ad,0x00000000, + 0x00030047,0x000005af,0x00000000,0x00030047,0x000005b2,0x00000000,0x00030047,0x000005b3, + 0x00000000,0x00030047,0x000005b5,0x00000000,0x00030047,0x000005b7,0x00000000,0x00030047, + 0x000005b9,0x00000000,0x00030047,0x000005bd,0x00000000,0x00030047,0x000005bf,0x00000000, + 0x00030047,0x000005c1,0x00000000,0x00030047,0x000005c4,0x00000000,0x00030047,0x000005c5, + 0x00000000,0x00030047,0x000005c6,0x00000000,0x00030047,0x000005cf,0x00000000,0x00030047, + 0x000005d5,0x00000000,0x00030047,0x000005d6,0x00000000,0x00030047,0x000005db,0x00000000, + 0x00030047,0x000005e1,0x00000000,0x00030047,0x000005e2,0x00000000,0x00030047,0x000005e3, + 0x00000000,0x00030047,0x000005e6,0x00000000,0x00030047,0x000005e7,0x00000000,0x00030047, + 0x000005e8,0x00000000,0x00030047,0x000005ee,0x00000000,0x00030047,0x000005ef,0x00000000, + 0x00030047,0x000005f0,0x00000000,0x00030047,0x000005fa,0x00000000,0x00030047,0x000005fb, + 0x00000000,0x00030047,0x000005fd,0x00000000,0x00030047,0x000005fe,0x00000000,0x00030047, + 0x000005ff,0x00000000,0x00030047,0x00000600,0x00000000,0x00030047,0x00000601,0x00000000, + 0x00030047,0x00000604,0x00000000,0x00030047,0x00000605,0x00000000,0x00030047,0x00000606, + 0x00000000,0x00030047,0x00000608,0x00000000,0x00030047,0x0000060a,0x00000000,0x00030047, + 0x0000060c,0x00000000,0x00030047,0x0000060e,0x00000000,0x00030047,0x0000060f,0x00000000, + 0x00030047,0x00000612,0x00000000,0x00030047,0x00000615,0x00000000,0x00030047,0x0000061d, + 0x00000000,0x00030047,0x00000620,0x00000000,0x00030047,0x00000628,0x00000000,0x00030047, + 0x0000062b,0x00000000,0x00030047,0x00000632,0x00000000,0x00030047,0x00000635,0x00000000, + 0x00030047,0x0000063b,0x00000000,0x00030047,0x00000640,0x00000000,0x00030047,0x00000642, + 0x00000000,0x00030047,0x00000647,0x00000000,0x00030047,0x0000064b,0x00000000,0x00030047, + 0x000006e7,0x00000000,0x00030047,0x000006eb,0x00000000,0x00030047,0x000006ec,0x00000000, + 0x00030047,0x000006fc,0x00000000,0x00030047,0x000006ff,0x00000000,0x00030047,0x00000700, + 0x00000000,0x00030047,0x00000704,0x00000000,0x00030047,0x00000706,0x00000000,0x00030047, + 0x00000707,0x00000000,0x00030047,0x00000710,0x00000000,0x00030047,0x00000717,0x00000000, + 0x00030047,0x0000071c,0x00000000,0x00030047,0x0000071f,0x00000000,0x00030047,0x00000720, + 0x00000000,0x00030047,0x00000724,0x00000000,0x00030047,0x00000726,0x00000000,0x00030047, + 0x00000727,0x00000000,0x00030047,0x0000072c,0x00000000,0x00030047,0x0000072f,0x00000000, + 0x00030047,0x00000730,0x00000000,0x00030047,0x00000734,0x00000000,0x00030047,0x00000736, + 0x00000000,0x00030047,0x00000737,0x00000000,0x00030047,0x0000074d,0x00000000,0x00030047, + 0x0000074e,0x00000000,0x00030047,0x00000750,0x00000000,0x00030047,0x00000756,0x00000000, + 0x00030047,0x0000075a,0x00000000,0x00030047,0x0000075b,0x00000000,0x00030047,0x0000075e, + 0x00000000,0x00030047,0x00000760,0x00000000,0x00030047,0x00000761,0x00000000,0x00030047, + 0x00000762,0x00000000,0x00030047,0x00000765,0x00000000,0x00030047,0x00000767,0x00000000, + 0x00030047,0x00000768,0x00000000,0x00030047,0x00000770,0x00000000,0x00030047,0x00000782, + 0x00000000,0x00030047,0x000007a1,0x00000000,0x00030047,0x000007a4,0x00000000,0x00030047, + 0x000007a5,0x00000000,0x00030047,0x000007a9,0x00000000,0x00030047,0x000007ab,0x00000000, + 0x00030047,0x000007ac,0x00000000,0x00030047,0x000007b5,0x00000000,0x00030047,0x000007bc, + 0x00000000,0x00030047,0x000007eb,0x00000000,0x00030047,0x000007ef,0x00000000,0x00030047, + 0x000007f0,0x00000000,0x00030047,0x00000800,0x00000000,0x00030047,0x00000803,0x00000000, + 0x00030047,0x00000804,0x00000000,0x00030047,0x00000808,0x00000000,0x00030047,0x0000080a, + 0x00000000,0x00030047,0x0000080b,0x00000000,0x00030047,0x00000814,0x00000000,0x00030047, + 0x0000081b,0x00000000,0x00030047,0x00000820,0x00000000,0x00030047,0x00000823,0x00000000, + 0x00030047,0x00000824,0x00000000,0x00030047,0x00000828,0x00000000,0x00030047,0x0000082a, + 0x00000000,0x00030047,0x0000082b,0x00000000,0x00030047,0x00000830,0x00000000,0x00030047, + 0x00000833,0x00000000,0x00030047,0x00000834,0x00000000,0x00030047,0x00000838,0x00000000, + 0x00030047,0x0000083a,0x00000000,0x00030047,0x0000083b,0x00000000,0x00030047,0x00000851, + 0x00000000,0x00030047,0x00000852,0x00000000,0x00030047,0x00000854,0x00000000,0x00030047, + 0x0000085a,0x00000000,0x00030047,0x0000085e,0x00000000,0x00030047,0x0000085f,0x00000000, + 0x00030047,0x00000862,0x00000000,0x00030047,0x00000864,0x00000000,0x00030047,0x00000865, + 0x00000000,0x00030047,0x00000866,0x00000000,0x00030047,0x00000869,0x00000000,0x00030047, + 0x0000086b,0x00000000,0x00030047,0x0000086c,0x00000000,0x00030047,0x00000874,0x00000000, + 0x00030047,0x00000886,0x00000000,0x00030047,0x000008a5,0x00000000,0x00030047,0x000008a8, + 0x00000000,0x00030047,0x000008a9,0x00000000,0x00030047,0x000008ad,0x00000000,0x00030047, + 0x000008af,0x00000000,0x00030047,0x000008b0,0x00000000,0x00030047,0x000008b9,0x00000000, + 0x00030047,0x000008c0,0x00000000,0x00030047,0x000008f5,0x00000000,0x00030047,0x000008f6, + 0x00000000,0x00030047,0x000008f8,0x00000000,0x00030047,0x000008fe,0x00000000,0x00030047, + 0x00000902,0x00000000,0x00030047,0x00000903,0x00000000,0x00030047,0x00000906,0x00000000, + 0x00030047,0x00000908,0x00000000,0x00030047,0x00000909,0x00000000,0x00030047,0x0000090a, + 0x00000000,0x00030047,0x0000090d,0x00000000,0x00030047,0x0000090f,0x00000000,0x00030047, + 0x00000910,0x00000000,0x00030047,0x00000918,0x00000000,0x00030047,0x0000092a,0x00000000, + 0x00030047,0x00000949,0x00000000,0x00030047,0x0000094c,0x00000000,0x00030047,0x0000094d, + 0x00000000,0x00030047,0x00000951,0x00000000,0x00030047,0x00000953,0x00000000,0x00030047, + 0x00000954,0x00000000,0x00030047,0x0000095d,0x00000000,0x00030047,0x00000964,0x00000000, + 0x00030047,0x00000999,0x00000000,0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099c, + 0x00000000,0x00030047,0x000009a2,0x00000000,0x00030047,0x000009a6,0x00000000,0x00030047, + 0x000009a7,0x00000000,0x00030047,0x000009aa,0x00000000,0x00030047,0x000009ac,0x00000000, + 0x00030047,0x000009ad,0x00000000,0x00030047,0x000009ae,0x00000000,0x00030047,0x000009b1, + 0x00000000,0x00030047,0x000009b3,0x00000000,0x00030047,0x000009b4,0x00000000,0x00030047, + 0x000009bc,0x00000000,0x00030047,0x000009ce,0x00000000,0x00030047,0x000009ed,0x00000000, + 0x00030047,0x000009f0,0x00000000,0x00030047,0x000009f1,0x00000000,0x00030047,0x000009f5, + 0x00000000,0x00030047,0x000009f7,0x00000000,0x00030047,0x000009f8,0x00000000,0x00030047, + 0x00000a01,0x00000000,0x00030047,0x00000a08,0x00000000,0x00030047,0x00000a2a,0x00000000, + 0x00030047,0x00000a2b,0x00000000,0x00030047,0x00000a3d,0x00000000,0x00030047,0x00000a3e, + 0x00000000,0x00030047,0x00000a41,0x00000000,0x00030047,0x00000a43,0x00000000,0x00030047, + 0x00000a47,0x00000000,0x00030047,0x00000a4f,0x00000000,0x00030047,0x00000a52,0x00000000, + 0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a56,0x00000000,0x00030047,0x00000a5d, + 0x00000000,0x00030047,0x00000a5f,0x00000000,0x00030047,0x00000a61,0x00000000,0x00030047, + 0x00000a63,0x00000000,0x00030047,0x00000a6b,0x00000000,0x00030047,0x00000a6d,0x00000000, + 0x00030047,0x00000a6f,0x00000000,0x00030047,0x00000a71,0x00000000,0x00030047,0x00000a73, + 0x00000000,0x00030047,0x00000a75,0x00000000,0x00030047,0x00000a77,0x00000000,0x00030047, + 0x00000a79,0x00000000,0x00030047,0x00000a7b,0x00000000,0x00030047,0x00000a83,0x00000000, + 0x00030047,0x00000a85,0x00000000,0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a96, + 0x00000000,0x00030047,0x00000a98,0x00000000,0x00030047,0x00000a9a,0x00000000,0x00030047, + 0x00000a9c,0x00000000,0x00030047,0x00000a9e,0x00000000,0x00030047,0x00000aa0,0x00000000, + 0x00030047,0x00000aa8,0x00000000,0x00030047,0x00000aaa,0x00000000,0x00030047,0x00000aac, + 0x00000000,0x00030047,0x00000aaf,0x00000000,0x00030047,0x00000abf,0x00000000,0x00030047, + 0x00000ac1,0x00000000,0x00030047,0x00000ac3,0x00000000,0x00030047,0x00000ac5,0x00000000, + 0x00030047,0x00000ac7,0x00000000,0x00030047,0x00000ac9,0x00000000,0x00030047,0x00000acb, + 0x00000000,0x00030047,0x00000acd,0x00000000,0x00030047,0x00000acf,0x00000000,0x00030047, + 0x00000add,0x00000000,0x00030047,0x00000adf,0x00000000,0x00030047,0x00000ae1,0x00000000, + 0x00030047,0x00000ae9,0x00000000,0x00030047,0x00000aeb,0x00000000,0x00030047,0x00000aed, + 0x00000000,0x00030047,0x00000aef,0x00000000,0x00030047,0x00000af7,0x00000000,0x00030047, + 0x00000af9,0x00000000,0x00030047,0x00000afd,0x00000000,0x00030047,0x00000aff,0x00000000, + 0x00030047,0x00000b01,0x00000000,0x00030047,0x00000b03,0x00000000,0x00030047,0x00000b05, + 0x00000000,0x00030047,0x00000b07,0x00000000,0x00030047,0x00000b15,0x00000000,0x00030047, + 0x00000b17,0x00000000,0x00030047,0x00000b19,0x00000000,0x00030047,0x00000b21,0x00000000, + 0x00030047,0x00000b23,0x00000000,0x00030047,0x00000b25,0x00000000,0x00030047,0x00000b27, + 0x00000000,0x00030047,0x00000b2f,0x00000000,0x00030047,0x00000b31,0x00000000,0x00030047, + 0x00000b35,0x00000000,0x00030047,0x00000b37,0x00000000,0x00030047,0x00000b39,0x00000000, + 0x00030047,0x00000b3b,0x00000000,0x00030047,0x00000b3d,0x00000000,0x00030047,0x00000b3f, + 0x00000000,0x00030047,0x00000b41,0x00000000,0x00030047,0x00000b43,0x00000000,0x00030047, + 0x00000b45,0x00000000,0x00030047,0x00000b4d,0x00000000,0x00030047,0x00000b4f,0x00000000, + 0x00030047,0x00000b51,0x00000000,0x00030047,0x00000b53,0x00000000,0x00030047,0x00000b5b, + 0x00000000,0x00030047,0x00000b5d,0x00000000,0x00030047,0x00000b61,0x00000000,0x00030047, + 0x00000b63,0x00000000,0x00030047,0x00000b65,0x00000000,0x00030047,0x00000b67,0x00000000, + 0x00030047,0x00000b69,0x00000000,0x00030047,0x00000b6b,0x00000000,0x00030047,0x00000b6d, + 0x00000000,0x00030047,0x00000b6f,0x00000000,0x00030047,0x00000b71,0x00000000,0x00030047, + 0x00000b79,0x00000000,0x00030047,0x00000b7b,0x00000000,0x00030047,0x00000b7d,0x00000000, + 0x00030047,0x00000b7f,0x00000000,0x00030047,0x00000b87,0x00000000,0x00030047,0x00000b89, + 0x00000000,0x00030047,0x00000b8e,0x00000000,0x00030047,0x00000b90,0x00000000,0x00030047, + 0x00000b92,0x00000000,0x00030047,0x00000b94,0x00000000,0x00030047,0x00000b96,0x00000000, + 0x00030047,0x00000b98,0x00000000,0x00030047,0x00000b9b,0x00000000,0x00030047,0x00000b9d, + 0x00000000,0x00030047,0x00000b9f,0x00000000,0x00030047,0x00000ba3,0x00000000,0x00030047, + 0x00000ba5,0x00000000,0x00030047,0x00000ba7,0x00000000,0x00030047,0x00000ba8,0x00000000, + 0x00030047,0x00000baf,0x00000000,0x00030047,0x00000bb1,0x00000000,0x00030047,0x00000bb2, + 0x00000000,0x00030047,0x00000bb0,0x00000000,0x00030047,0x00000bae,0x00000000,0x00030047, + 0x00000bb5,0x00000000,0x00030047,0x00000cfc,0x00000000,0x00030047,0x00000d6c,0x00000000, + 0x00030047,0x00000bb3,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002, + 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020, + 0x0000000d,0x00000007,0x00000006,0x00040015,0x0000000e,0x00000020,0x00000000,0x00040017, + 0x00000017,0x00000006,0x00000002,0x00040017,0x00000021,0x00000006,0x00000003,0x00040020, + 0x0000002c,0x00000007,0x00000021,0x00040018,0x00000052,0x00000007,0x00000004,0x00040015, + 0x00000054,0x00000020,0x00000001,0x0004002b,0x0000000e,0x00000088,0x00000000,0x0004002b, + 0x0000000e,0x0000008b,0x00000001,0x0004002b,0x00000006,0x000000bf,0x00000000,0x00020014, + 0x000000c0,0x0004002b,0x00000006,0x000000c5,0x3f800000,0x0004002b,0x00000006,0x000000ef, + 0x3d897143,0x0004002b,0x00000006,0x000000f3,0x3bbf4590,0x0004002b,0x00000006,0x000000fa, + 0x4253ee82,0x00030030,0x000000c0,0x00000105,0x0004002b,0x00000054,0x00000119,0x0000000f, + 0x0004002b,0x00000054,0x0000011d,0x00000000,0x0004002b,0x00000054,0x00000120,0x00000001, + 0x0004002b,0x00000054,0x00000124,0x00000002,0x0004002b,0x00000054,0x00000128,0x00000003, + 0x0004002b,0x00000006,0x0000012c,0x3e800000,0x00040017,0x00000132,0x00000054,0x00000004, + 0x0004002b,0x00000054,0x00000133,0x00000004,0x0004002b,0x00000054,0x00000134,0x00000008, + 0x0007002c,0x00000132,0x00000135,0x00000120,0x00000124,0x00000133,0x00000134,0x0007002c, + 0x00000132,0x00000138,0x0000011d,0x0000011d,0x0000011d,0x0000011d,0x00040017,0x00000139, + 0x000000c0,0x00000004,0x0007002c,0x00000007,0x0000013b,0x000000bf,0x000000bf,0x000000bf, + 0x000000bf,0x0007002c,0x00000007,0x0000013c,0x000000c5,0x000000c5,0x000000c5,0x000000c5, + 0x0004002b,0x00000054,0x00000144,0x00000005,0x0004002b,0x00000006,0x00000158,0x3e99999a, + 0x0004002b,0x00000006,0x00000159,0x3f170a3d,0x0004002b,0x00000006,0x0000015a,0x3de147ae, + 0x0004002b,0x00000006,0x00000174,0x388205ff,0x0004002b,0x00000006,0x000001da,0x40000000, + 0x0004002b,0x00000006,0x000001e1,0x3f000000,0x00040017,0x000001e7,0x000000c0,0x00000003, + 0x0004002b,0x00000006,0x0000027f,0x41800000,0x0004002b,0x00000006,0x00000284,0x41400000, + 0x0004002b,0x00000006,0x0000028a,0x40400000,0x00030030,0x000000c0,0x000002b0,0x00030030, + 0x000000c0,0x0000030b,0x00050034,0x000000c0,0x0000030c,0x000000a8,0x0000030b,0x0004002b, + 0x00000006,0x0000031b,0xbf800000,0x0004002b,0x00000006,0x00000339,0x3f7f8000,0x0004002b, + 0x00000006,0x0000033c,0x3a800000,0x0004002b,0x00000006,0x0000033f,0x3b000000,0x00090019, + 0x00000349,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x0000034a,0x00000000,0x00000349,0x0004003b,0x0000034a,0x0000034b,0x00000000, + 0x0002001a,0x0000034d,0x00040020,0x0000034e,0x00000000,0x0000034d,0x0004003b,0x0000034e, + 0x0000034f,0x00000000,0x0003001b,0x00000351,0x00000349,0x00050034,0x000000c0,0x0000035c, + 0x000000a8,0x0000030b,0x0004003b,0x0000034a,0x00000370,0x00000000,0x0004003b,0x0000034e, + 0x00000372,0x00000000,0x00050034,0x000000c0,0x0000037e,0x000000a8,0x0000030b,0x0004003b, + 0x0000034a,0x00000393,0x00000000,0x0004003b,0x0000034e,0x00000395,0x00000000,0x00040020, + 0x00000398,0x00000001,0x00000017,0x0004003b,0x00000398,0x00000399,0x00000001,0x00040020, + 0x000003a3,0x00000001,0x00000007,0x0004003b,0x000003a3,0x000003a4,0x00000001,0x00040020, + 0x000003ab,0x00000001,0x00000006,0x0004003b,0x000003ab,0x000003ac,0x00000001,0x00090019, + 0x000003b1,0x00000006,0x00000006,0x00000000,0x00000000,0x00000001,0x00000002,0x00000000, + 0x00040020,0x000003b2,0x00000000,0x000003b1,0x0004003b,0x000003b2,0x000003b3,0x00000000, + 0x00040017,0x000003b5,0x00000054,0x00000002,0x0005002c,0x000003b5,0x000003b6,0x0000011d, + 0x0000011d,0x0004001c,0x000003d3,0x00000054,0x0000008b,0x00040020,0x000003d4,0x00000001, + 0x000003d3,0x0004003b,0x000003d4,0x000003d5,0x00000001,0x00040020,0x000003d8,0x00000001, + 0x00000054,0x0004003b,0x000003a3,0x000003f5,0x00000001,0x0017001e,0x000003f6,0x00000006, + 0x00000006,0x00000006,0x00000006,0x0000000e,0x0000000e,0x0000000e,0x0000000e,0x00000132, + 0x00000017,0x00000017,0x0000000e,0x00000006,0x0000000e,0x00000006,0x00000006,0x0000000e, + 0x00000006,0x00000006,0x00000006,0x0000000e,0x00040020,0x000003f7,0x00000002,0x000003f6, + 0x0004003b,0x000003f7,0x000003f8,0x00000002,0x0004002b,0x00000054,0x000003f9,0x00000011, + 0x0004002b,0x00000054,0x000003fa,0x00000012,0x00040020,0x00000402,0x00000002,0x00000006, + 0x00040020,0x0000040f,0x00000003,0x00000007,0x0004003b,0x0000040f,0x00000410,0x00000003, + 0x0004003b,0x0000034e,0x0000041b,0x00000000,0x0004003b,0x0000034a,0x0000041c,0x00000000, + 0x0004003b,0x000003ab,0x0000041d,0x00000001,0x00030001,0x00000007,0x00000bab,0x00030001, + 0x00000021,0x00000bba,0x0006002c,0x00000021,0x00000d6e,0x000001e1,0x000001e1,0x000001e1, + 0x0006002c,0x00000021,0x00000d6f,0x000000c5,0x000000c5,0x000000c5,0x00030001,0x00000017, + 0x00000d71,0x00030001,0x00000021,0x00000d72,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000002c,0x00000516,0x00000007,0x0004003b, + 0x0000002c,0x00000518,0x00000007,0x0004003b,0x0000002c,0x00000506,0x00000007,0x0004003d, + 0x00000349,0x00000394,0x00000393,0x0004003d,0x0000034d,0x00000396,0x00000395,0x00050056, + 0x00000351,0x00000397,0x00000394,0x00000396,0x0004003d,0x00000017,0x0000039a,0x00000399, + 0x00070058,0x00000007,0x0000039b,0x00000397,0x0000039a,0x00000002,0x000000bf,0x00050051, + 0x00000006,0x0000039c,0x0000039b,0x00000000,0x0008000c,0x00000006,0x000003a1,0x00000001, + 0x0000002b,0x0000039c,0x000000bf,0x000000c5,0x0004003d,0x00000007,0x000003a6,0x000003a4, + 0x00050051,0x00000006,0x0000043c,0x000003a6,0x00000003,0x000500be,0x000000c0,0x0000043d, + 0x0000043c,0x000000bf,0x000300f7,0x000004a9,0x00000000,0x000400fa,0x0000043d,0x0000043e, + 0x0000044c,0x000200f8,0x0000044c,0x000500ba,0x000000c0,0x0000044f,0x0000043c,0x0000031b, + 0x000300f7,0x000004a8,0x00000000,0x000400fa,0x0000044f,0x00000450,0x0000048b,0x000200f8, + 0x0000048b,0x0004007f,0x00000006,0x0000048e,0x0000043c,0x00050083,0x00000006,0x0000048f, + 0x0000048e,0x000001da,0x0004003d,0x00000349,0x00000490,0x00000370,0x0004003d,0x0000034d, + 0x00000491,0x00000372,0x00050056,0x00000351,0x00000492,0x00000490,0x00000491,0x0007004f, + 0x00000017,0x00000494,0x000003a6,0x000003a6,0x00000000,0x00000001,0x00070058,0x00000007, + 0x00000496,0x00000492,0x00000494,0x00000002,0x0000048f,0x00050051,0x00000006,0x00000498, + 0x000003a6,0x00000002,0x00050085,0x00000006,0x0000049a,0x00000498,0x000003a1,0x000300f7, + 0x000004a7,0x00000000,0x000400fa,0x0000037e,0x0000049b,0x0000049f,0x000200f8,0x0000049f, + 0x0008004f,0x00000021,0x000004b4,0x00000496,0x00000496,0x00000000,0x00000001,0x00000002, + 0x00050051,0x00000006,0x000004b6,0x00000496,0x00000003,0x000500b7,0x000000c0,0x000004b7, + 0x000004b6,0x000000bf,0x000300f7,0x000004bd,0x00000000,0x000400fa,0x000004b7,0x000004b8, + 0x000004bc,0x000200f8,0x000004bc,0x000200f9,0x000004bd,0x000200f8,0x000004b8,0x00050088, + 0x00000006,0x000004bb,0x000000c5,0x000004b6,0x000200f9,0x000004bd,0x000200f8,0x000004bd, + 0x000700f5,0x00000006,0x00000ba8,0x000004bb,0x000004b8,0x000000bf,0x000004bc,0x0005008e, + 0x00000021,0x000004bf,0x000004b4,0x00000ba8,0x00050085,0x00000006,0x000004a5,0x000004b6, + 0x0000049a,0x00050051,0x00000006,0x000004c5,0x000004bf,0x00000000,0x00060052,0x00000007, + 0x00000a5d,0x000004c5,0x00000bab,0x00000000,0x00050051,0x00000006,0x000004c7,0x000004bf, + 0x00000001,0x00060052,0x00000007,0x00000a5f,0x000004c7,0x00000a5d,0x00000001,0x00050051, + 0x00000006,0x000004c9,0x000004bf,0x00000002,0x00060052,0x00000007,0x00000a61,0x000004c9, + 0x00000a5f,0x00000002,0x00060052,0x00000007,0x00000a63,0x000004a5,0x00000a61,0x00000003, + 0x000200f9,0x000004a7,0x000200f8,0x0000049b,0x0005008e,0x00000007,0x0000049e,0x00000496, + 0x0000049a,0x000200f9,0x000004a7,0x000200f8,0x000004a7,0x000700f5,0x00000007,0x00000bb2, + 0x0000049e,0x0000049b,0x00000a63,0x000004bd,0x000200f9,0x000004a8,0x000200f8,0x00000450, + 0x00050051,0x00000006,0x00000452,0x000003a6,0x00000002,0x000500ba,0x000000c0,0x00000453, + 0x00000452,0x000000bf,0x000300f7,0x0000045b,0x00000000,0x000400fa,0x00000453,0x00000454, + 0x00000457,0x000200f8,0x00000457,0x0007004f,0x00000017,0x00000459,0x000003a6,0x000003a6, + 0x00000000,0x00000001,0x0006000c,0x00000006,0x0000045a,0x00000001,0x00000042,0x00000459, + 0x000200f9,0x0000045b,0x000200f8,0x00000454,0x00050051,0x00000006,0x00000456,0x000003a6, + 0x00000000,0x000200f9,0x0000045b,0x000200f8,0x0000045b,0x000700f5,0x00000006,0x00000bac, + 0x00000456,0x00000454,0x0000045a,0x00000457,0x0008000c,0x00000006,0x0000045e,0x00000001, + 0x0000002b,0x00000bac,0x000000bf,0x000000c5,0x0006000c,0x00000006,0x00000461,0x00000001, + 0x00000004,0x00000452,0x000500ba,0x000000c0,0x00000463,0x00000461,0x000000c5,0x000300f7, + 0x0000046d,0x00000000,0x000400fa,0x00000463,0x00000464,0x00000468,0x000200f8,0x00000468, + 0x00050085,0x00000006,0x0000046a,0x0000033f,0x0000045e,0x00050081,0x00000006,0x0000046c, + 0x0000046a,0x00000461,0x000200f9,0x0000046d,0x000200f8,0x00000464,0x00050085,0x00000006, + 0x00000466,0x00000339,0x0000045e,0x00050081,0x00000006,0x00000467,0x00000466,0x0000033c, + 0x000200f9,0x0000046d,0x000200f8,0x0000046d,0x000700f5,0x00000006,0x00000bad,0x00000467, + 0x00000464,0x0000046c,0x00000468,0x0004007f,0x00000006,0x00000471,0x0000043c,0x0004003d, + 0x00000349,0x00000472,0x0000034b,0x0004003d,0x0000034d,0x00000473,0x0000034f,0x00050056, + 0x00000351,0x00000474,0x00000472,0x00000473,0x00050050,0x00000017,0x00000477,0x00000bad, + 0x00000471,0x00070058,0x00000007,0x00000478,0x00000474,0x00000477,0x00000002,0x000000bf, + 0x00050051,0x00000006,0x0000047b,0x00000478,0x00000003,0x00050085,0x00000006,0x0000047c, + 0x0000047b,0x000003a1,0x00060052,0x00000007,0x00000a4f,0x0000047c,0x00000478,0x00000003, + 0x000300f7,0x0000048a,0x00000000,0x000400fa,0x0000035c,0x0000047e,0x0000048a,0x000200f8, + 0x0000047e,0x00050051,0x00000006,0x00000480,0x00000a4f,0x00000003,0x0008004f,0x00000021, + 0x00000482,0x00000a4f,0x00000a4f,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000021, + 0x00000483,0x00000482,0x00000480,0x00050051,0x00000006,0x00000485,0x00000483,0x00000000, + 0x00060052,0x00000007,0x00000a52,0x00000485,0x00000a4f,0x00000000,0x00050051,0x00000006, + 0x00000487,0x00000483,0x00000001,0x00060052,0x00000007,0x00000a54,0x00000487,0x00000a52, + 0x00000001,0x00050051,0x00000006,0x00000489,0x00000483,0x00000002,0x00060052,0x00000007, + 0x00000a56,0x00000489,0x00000a54,0x00000002,0x000200f9,0x0000048a,0x000200f8,0x0000048a, + 0x000700f5,0x00000007,0x00000bb1,0x00000a4f,0x0000046d,0x00000a56,0x0000047e,0x000200f9, + 0x000004a8,0x000200f8,0x000004a8,0x000700f5,0x00000007,0x00000bb0,0x00000bb1,0x0000048a, + 0x00000bb2,0x000004a7,0x000200f9,0x000004a9,0x000200f8,0x0000043e,0x000300f7,0x0000044b, + 0x00000000,0x000400fa,0x0000030c,0x00000441,0x00000445,0x000200f8,0x00000445,0x00050051, + 0x00000006,0x00000448,0x000003a6,0x00000003,0x00050085,0x00000006,0x00000449,0x00000448, + 0x000003a1,0x00060052,0x00000007,0x00000a47,0x00000449,0x000003a6,0x00000003,0x000200f9, + 0x0000044b,0x000200f8,0x00000441,0x0005008e,0x00000007,0x00000444,0x000003a6,0x000003a1, + 0x000200f9,0x0000044b,0x000200f8,0x0000044b,0x000700f5,0x00000007,0x00000baf,0x00000444, + 0x00000441,0x00000a47,0x00000445,0x000200f9,0x000004a9,0x000200f8,0x000004a9,0x000700f5, + 0x00000007,0x00000bae,0x00000baf,0x0000044b,0x00000bb0,0x000004a8,0x0004003d,0x00000006, + 0x000003ae,0x000003ac,0x0004006d,0x0000000e,0x000004d0,0x000003ae,0x0004003d,0x000003b1, + 0x000003b4,0x000003b3,0x00070062,0x00000007,0x000003b7,0x000003b4,0x000003b6,0x00000040, + 0x0000011d,0x0004003d,0x000003b1,0x000003b8,0x000003b3,0x00070062,0x00000007,0x000003b9, + 0x000003b8,0x000003b6,0x00000040,0x00000120,0x0004003d,0x000003b1,0x000003ba,0x000003b3, + 0x00070062,0x00000007,0x000003bb,0x000003ba,0x000003b6,0x00000040,0x00000124,0x0004003d, + 0x000003b1,0x000003bc,0x000003b3,0x00070062,0x00000007,0x000003bd,0x000003bc,0x000003b6, + 0x00000040,0x00000128,0x00050051,0x00000006,0x000003be,0x000003b7,0x00000000,0x00050051, + 0x00000006,0x000003bf,0x000003b7,0x00000001,0x00050051,0x00000006,0x000003c0,0x000003b7, + 0x00000002,0x00050051,0x00000006,0x000003c1,0x000003b7,0x00000003,0x00050051,0x00000006, + 0x000003c2,0x000003b9,0x00000000,0x00050051,0x00000006,0x000003c3,0x000003b9,0x00000001, + 0x00050051,0x00000006,0x000003c4,0x000003b9,0x00000002,0x00050051,0x00000006,0x000003c5, + 0x000003b9,0x00000003,0x00050051,0x00000006,0x000003c6,0x000003bb,0x00000000,0x00050051, + 0x00000006,0x000003c7,0x000003bb,0x00000001,0x00050051,0x00000006,0x000003c8,0x000003bb, + 0x00000002,0x00050051,0x00000006,0x000003c9,0x000003bb,0x00000003,0x00050051,0x00000006, + 0x000003ca,0x000003bd,0x00000000,0x00050051,0x00000006,0x000003cb,0x000003bd,0x00000001, + 0x00050051,0x00000006,0x000003cc,0x000003bd,0x00000002,0x00050051,0x00000006,0x000003cd, + 0x000003bd,0x00000003,0x00070050,0x00000007,0x000003ce,0x000003be,0x000003bf,0x000003c0, + 0x000003c1,0x00070050,0x00000007,0x000003cf,0x000003c2,0x000003c3,0x000003c4,0x000003c5, + 0x00070050,0x00000007,0x000003d0,0x000003c6,0x000003c7,0x000003c8,0x000003c9,0x00070050, + 0x00000007,0x000003d1,0x000003ca,0x000003cb,0x000003cc,0x000003cd,0x00070050,0x00000052, + 0x000003d2,0x000003ce,0x000003cf,0x000003d0,0x000003d1,0x00050041,0x000003d8,0x000003d9, + 0x000003d5,0x0000011d,0x0004003d,0x00000054,0x000003da,0x000003d9,0x000300f7,0x00000503, + 0x00000000,0x000300fb,0x00000088,0x000004d8,0x000200f8,0x000004d8,0x000500aa,0x000000c0, + 0x000004da,0x000003da,0x00000119,0x000300f7,0x00000502,0x00000000,0x000400fa,0x000004da, + 0x000004db,0x000004e8,0x000200f8,0x000004e8,0x00070050,0x00000132,0x000004ea,0x000003da, + 0x000003da,0x000003da,0x000003da,0x000500c7,0x00000132,0x000004eb,0x000004ea,0x00000135, + 0x000500ab,0x00000139,0x000004ec,0x000004eb,0x00000138,0x000600a9,0x00000007,0x000004ed, + 0x000004ec,0x0000013c,0x0000013b,0x00050091,0x00000007,0x000004f0,0x000003d2,0x000004ed, + 0x000500c7,0x00000054,0x000004f2,0x000003da,0x00000144,0x000500c3,0x00000054,0x000004f4, + 0x000003da,0x00000120,0x000500c7,0x00000054,0x000004f5,0x000004f4,0x00000144,0x00050080, + 0x00000054,0x000004f6,0x000004f2,0x000004f5,0x000500c7,0x00000054,0x000004f8,0x000004f6, + 0x00000128,0x000500c3,0x00000054,0x000004fa,0x000004f6,0x00000124,0x00050080,0x00000054, + 0x000004fb,0x000004f8,0x000004fa,0x0004006f,0x00000006,0x000004fd,0x000004fb,0x00050088, + 0x00000006,0x000004fe,0x000000c5,0x000004fd,0x0005008e,0x00000007,0x00000500,0x000004f0, + 0x000004fe,0x000200f9,0x00000503,0x000200f8,0x000004db,0x00050051,0x00000007,0x000004dd, + 0x000003d2,0x00000000,0x00050051,0x00000007,0x000004df,0x000003d2,0x00000001,0x00050081, + 0x00000007,0x000004e0,0x000004dd,0x000004df,0x00050051,0x00000007,0x000004e2,0x000003d2, + 0x00000002,0x00050081,0x00000007,0x000004e3,0x000004e0,0x000004e2,0x00050051,0x00000007, + 0x000004e5,0x000003d2,0x00000003,0x00050081,0x00000007,0x000004e6,0x000004e3,0x000004e5, + 0x0005008e,0x00000007,0x000004e7,0x000004e6,0x0000012c,0x000200f9,0x00000503,0x000200f8, + 0x00000502,0x000100ff,0x000200f8,0x00000503,0x000700f5,0x00000007,0x00000bb3,0x000004e7, + 0x000004db,0x00000500,0x000004e8,0x0008004f,0x00000021,0x000003de,0x00000bae,0x00000bae, + 0x00000000,0x00000001,0x00000002,0x0003003e,0x00000506,0x000003de,0x0008004f,0x00000021, + 0x00000640,0x00000bb3,0x00000bb3,0x00000000,0x00000001,0x00000002,0x00050051,0x00000006, + 0x00000642,0x00000bb3,0x00000003,0x000500b7,0x000000c0,0x00000643,0x00000642,0x000000bf, + 0x000300f7,0x00000649,0x00000000,0x000400fa,0x00000643,0x00000644,0x00000648,0x000200f8, + 0x00000648,0x000200f9,0x00000649,0x000200f8,0x00000644,0x00050088,0x00000006,0x00000647, + 0x000000c5,0x00000642,0x000200f9,0x00000649,0x000200f8,0x00000649,0x000700f5,0x00000006, + 0x00000bb5,0x00000647,0x00000644,0x000000bf,0x00000648,0x0005008e,0x00000021,0x0000064b, + 0x00000640,0x00000bb5,0x0003003e,0x00000516,0x0000064b,0x000300f7,0x0000063a,0x00000000, + 0x002100fb,0x000004d0,0x0000063a,0x0000000b,0x00000541,0x00000001,0x00000545,0x00000002, + 0x0000054d,0x00000003,0x0000055e,0x00000004,0x00000562,0x00000005,0x00000566,0x00000006, + 0x00000589,0x00000007,0x000005b6,0x00000008,0x000005c7,0x00000009,0x00000602,0x0000000a, + 0x00000607,0x0000000c,0x00000610,0x0000000d,0x0000061b,0x0000000e,0x00000626,0x0000000f, + 0x00000630,0x000200f8,0x00000630,0x000300f7,0x00000639,0x00000000,0x000400fa,0x000002b0, + 0x00000631,0x00000639,0x000200f8,0x00000631,0x0004003d,0x00000021,0x00000632,0x00000506, + 0x00060052,0x00000021,0x00000b61,0x000000bf,0x00000bba,0x00000000,0x00060052,0x00000021, + 0x00000b63,0x000000bf,0x00000b61,0x00000001,0x00060052,0x00000021,0x00000b65,0x000000bf, + 0x00000b63,0x00000002,0x00060052,0x00000021,0x00000b67,0x000000c5,0x00000bba,0x00000000, + 0x00060052,0x00000021,0x00000b69,0x000000c5,0x00000b67,0x00000001,0x00060052,0x00000021, + 0x00000b6b,0x000000c5,0x00000b69,0x00000002,0x0008000c,0x00000021,0x00000635,0x00000001, + 0x0000002b,0x00000632,0x00000b65,0x00000b6b,0x0003003e,0x00000506,0x00000635,0x00060052, + 0x00000021,0x00000b6d,0x00000158,0x00000bba,0x00000000,0x00060052,0x00000021,0x00000b6f, + 0x00000159,0x00000b6d,0x00000001,0x00060052,0x00000021,0x00000b71,0x0000015a,0x00000b6f, + 0x00000002,0x00050094,0x00000006,0x000009bc,0x00000635,0x00000b71,0x00050094,0x00000006, + 0x000009ce,0x0000064b,0x00000b71,0x00060050,0x00000021,0x00000999,0x000009ce,0x000009ce, + 0x000009ce,0x00050083,0x00000021,0x0000099a,0x0000064b,0x00000999,0x00050083,0x00000006, + 0x0000099c,0x000000c5,0x000009bc,0x00060052,0x00000017,0x00000b79,0x000009bc,0x00000d71, + 0x00000000,0x00060052,0x00000017,0x00000b7b,0x0000099c,0x00000b79,0x00000001,0x00060052, + 0x00000017,0x00000b7d,0x00000174,0x00000d71,0x00000000,0x00060052,0x00000017,0x00000b7f, + 0x00000174,0x00000b7d,0x00000001,0x0007004f,0x00000017,0x000009ed,0x0000099a,0x0000099a, + 0x00000000,0x00000001,0x00050051,0x00000006,0x000009f5,0x000009ed,0x00000000,0x00050051, + 0x00000006,0x000009f7,0x000009ed,0x00000001,0x0007000c,0x00000006,0x000009f8,0x00000001, + 0x00000025,0x000009f5,0x000009f7,0x00050051,0x00000006,0x000009f0,0x0000099a,0x00000002, + 0x0007000c,0x00000006,0x000009f1,0x00000001,0x00000025,0x000009f8,0x000009f0,0x0004007f, + 0x00000006,0x000009a2,0x000009f1,0x0007000c,0x00000006,0x00000a08,0x00000001,0x00000028, + 0x000009f5,0x000009f7,0x0007000c,0x00000006,0x00000a01,0x00000001,0x00000028,0x00000a08, + 0x000009f0,0x00060052,0x00000017,0x00000b87,0x000009a2,0x00000d71,0x00000000,0x00060052, + 0x00000017,0x00000b89,0x00000a01,0x00000b87,0x00000001,0x0007000c,0x00000017,0x000009a6, + 0x00000001,0x00000028,0x00000b7f,0x00000b89,0x00050088,0x00000017,0x000009a7,0x00000b7b, + 0x000009a6,0x00050051,0x00000006,0x000009aa,0x000009a7,0x00000000,0x00050051,0x00000006, + 0x000009ac,0x000009a7,0x00000001,0x0007000c,0x00000006,0x000009ad,0x00000001,0x00000025, + 0x000009aa,0x000009ac,0x0007000c,0x00000006,0x000009ae,0x00000001,0x00000025,0x000000c5, + 0x000009ad,0x0005008e,0x00000021,0x000009b1,0x0000099a,0x000009ae,0x00060050,0x00000021, + 0x000009b3,0x000009bc,0x000009bc,0x000009bc,0x00050081,0x00000021,0x000009b4,0x000009b1, + 0x000009b3,0x0003003e,0x00000518,0x000009b4,0x000200f9,0x00000639,0x000200f8,0x00000639, + 0x000200f9,0x0000063a,0x000200f8,0x00000626,0x000300f7,0x0000062f,0x00000000,0x000400fa, + 0x000002b0,0x00000627,0x0000062f,0x000200f8,0x00000627,0x0004003d,0x00000021,0x00000628, + 0x00000506,0x00060052,0x00000021,0x00000b35,0x000000bf,0x00000bba,0x00000000,0x00060052, + 0x00000021,0x00000b37,0x000000bf,0x00000b35,0x00000001,0x00060052,0x00000021,0x00000b39, + 0x000000bf,0x00000b37,0x00000002,0x00060052,0x00000021,0x00000b3b,0x000000c5,0x00000bba, + 0x00000000,0x00060052,0x00000021,0x00000b3d,0x000000c5,0x00000b3b,0x00000001,0x00060052, + 0x00000021,0x00000b3f,0x000000c5,0x00000b3d,0x00000002,0x0008000c,0x00000021,0x0000062b, + 0x00000001,0x0000002b,0x00000628,0x00000b39,0x00000b3f,0x0003003e,0x00000506,0x0000062b, + 0x00060052,0x00000021,0x00000b41,0x00000158,0x00000bba,0x00000000,0x00060052,0x00000021, + 0x00000b43,0x00000159,0x00000b41,0x00000001,0x00060052,0x00000021,0x00000b45,0x0000015a, + 0x00000b43,0x00000002,0x00050094,0x00000006,0x00000918,0x0000064b,0x00000b45,0x00050094, + 0x00000006,0x0000092a,0x0000062b,0x00000b45,0x00060050,0x00000021,0x000008f5,0x0000092a, + 0x0000092a,0x0000092a,0x00050083,0x00000021,0x000008f6,0x0000062b,0x000008f5,0x00050083, + 0x00000006,0x000008f8,0x000000c5,0x00000918,0x00060052,0x00000017,0x00000b4d,0x00000918, + 0x00000d71,0x00000000,0x00060052,0x00000017,0x00000b4f,0x000008f8,0x00000b4d,0x00000001, + 0x00060052,0x00000017,0x00000b51,0x00000174,0x00000d71,0x00000000,0x00060052,0x00000017, + 0x00000b53,0x00000174,0x00000b51,0x00000001,0x0007004f,0x00000017,0x00000949,0x000008f6, + 0x000008f6,0x00000000,0x00000001,0x00050051,0x00000006,0x00000951,0x00000949,0x00000000, + 0x00050051,0x00000006,0x00000953,0x00000949,0x00000001,0x0007000c,0x00000006,0x00000954, + 0x00000001,0x00000025,0x00000951,0x00000953,0x00050051,0x00000006,0x0000094c,0x000008f6, + 0x00000002,0x0007000c,0x00000006,0x0000094d,0x00000001,0x00000025,0x00000954,0x0000094c, + 0x0004007f,0x00000006,0x000008fe,0x0000094d,0x0007000c,0x00000006,0x00000964,0x00000001, + 0x00000028,0x00000951,0x00000953,0x0007000c,0x00000006,0x0000095d,0x00000001,0x00000028, + 0x00000964,0x0000094c,0x00060052,0x00000017,0x00000b5b,0x000008fe,0x00000d71,0x00000000, + 0x00060052,0x00000017,0x00000b5d,0x0000095d,0x00000b5b,0x00000001,0x0007000c,0x00000017, + 0x00000902,0x00000001,0x00000028,0x00000b53,0x00000b5d,0x00050088,0x00000017,0x00000903, + 0x00000b4f,0x00000902,0x00050051,0x00000006,0x00000906,0x00000903,0x00000000,0x00050051, + 0x00000006,0x00000908,0x00000903,0x00000001,0x0007000c,0x00000006,0x00000909,0x00000001, + 0x00000025,0x00000906,0x00000908,0x0007000c,0x00000006,0x0000090a,0x00000001,0x00000025, + 0x000000c5,0x00000909,0x0005008e,0x00000021,0x0000090d,0x000008f6,0x0000090a,0x00060050, + 0x00000021,0x0000090f,0x00000918,0x00000918,0x00000918,0x00050081,0x00000021,0x00000910, + 0x0000090d,0x0000090f,0x0003003e,0x00000518,0x00000910,0x000200f9,0x0000062f,0x000200f8, + 0x0000062f,0x000200f9,0x0000063a,0x000200f8,0x0000061b,0x000300f7,0x00000625,0x00000000, + 0x000400fa,0x000002b0,0x0000061c,0x00000625,0x000200f8,0x0000061c,0x0004003d,0x00000021, + 0x0000061d,0x00000506,0x00060052,0x00000021,0x00000afd,0x000000bf,0x00000bba,0x00000000, + 0x00060052,0x00000021,0x00000aff,0x000000bf,0x00000afd,0x00000001,0x00060052,0x00000021, + 0x00000b01,0x000000bf,0x00000aff,0x00000002,0x00060052,0x00000021,0x00000b03,0x000000c5, + 0x00000bba,0x00000000,0x00060052,0x00000021,0x00000b05,0x000000c5,0x00000b03,0x00000001, + 0x00060052,0x00000021,0x00000b07,0x000000c5,0x00000b05,0x00000002,0x0008000c,0x00000021, + 0x00000620,0x00000001,0x0000002b,0x0000061d,0x00000b01,0x00000b07,0x0003003e,0x00000506, + 0x00000620,0x0007004f,0x00000017,0x00000800,0x00000620,0x00000620,0x00000000,0x00000001, + 0x00050051,0x00000006,0x00000808,0x00000800,0x00000000,0x00050051,0x00000006,0x0000080a, + 0x00000800,0x00000001,0x0007000c,0x00000006,0x0000080b,0x00000001,0x00000028,0x00000808, + 0x0000080a,0x00050051,0x00000006,0x00000803,0x00000620,0x00000002,0x0007000c,0x00000006, + 0x00000804,0x00000001,0x00000028,0x0000080b,0x00000803,0x0007000c,0x00000006,0x0000081b, + 0x00000001,0x00000025,0x00000808,0x0000080a,0x0007000c,0x00000006,0x00000814,0x00000001, + 0x00000025,0x0000081b,0x00000803,0x00050083,0x00000006,0x000007eb,0x00000804,0x00000814, + 0x0007004f,0x00000017,0x00000820,0x0000064b,0x0000064b,0x00000000,0x00000001,0x00050051, + 0x00000006,0x00000828,0x00000820,0x00000000,0x00050051,0x00000006,0x0000082a,0x00000820, + 0x00000001,0x0007000c,0x00000006,0x0000082b,0x00000001,0x00000025,0x00000828,0x0000082a, + 0x00050051,0x00000006,0x00000823,0x0000064b,0x00000002,0x0007000c,0x00000006,0x00000824, + 0x00000001,0x00000025,0x0000082b,0x00000823,0x00060050,0x00000021,0x000007ef,0x00000824, + 0x00000824,0x00000824,0x00050083,0x00000021,0x000007f0,0x0000064b,0x000007ef,0x0007004f, + 0x00000017,0x00000830,0x000007f0,0x000007f0,0x00000000,0x00000001,0x00050051,0x00000006, + 0x00000838,0x00000830,0x00000000,0x00050051,0x00000006,0x0000083a,0x00000830,0x00000001, + 0x0007000c,0x00000006,0x0000083b,0x00000001,0x00000028,0x00000838,0x0000083a,0x00050051, + 0x00000006,0x00000833,0x000007f0,0x00000002,0x0007000c,0x00000006,0x00000834,0x00000001, + 0x00000028,0x0000083b,0x00000833,0x0007000c,0x00000006,0x000007f5,0x00000001,0x00000028, + 0x00000174,0x00000834,0x00050088,0x00000006,0x000007f6,0x000007eb,0x000007f5,0x0005008e, + 0x00000021,0x000007f9,0x000007f0,0x000007f6,0x00060052,0x00000021,0x00000b15,0x00000158, + 0x00000bba,0x00000000,0x00060052,0x00000021,0x00000b17,0x00000159,0x00000b15,0x00000001, + 0x00060052,0x00000021,0x00000b19,0x0000015a,0x00000b17,0x00000002,0x00050094,0x00000006, + 0x00000874,0x0000064b,0x00000b19,0x00050094,0x00000006,0x00000886,0x000007f9,0x00000b19, + 0x00060050,0x00000021,0x00000851,0x00000886,0x00000886,0x00000886,0x00050083,0x00000021, + 0x00000852,0x000007f9,0x00000851,0x00050083,0x00000006,0x00000854,0x000000c5,0x00000874, + 0x00060052,0x00000017,0x00000b21,0x00000874,0x00000d71,0x00000000,0x00060052,0x00000017, + 0x00000b23,0x00000854,0x00000b21,0x00000001,0x00060052,0x00000017,0x00000b25,0x00000174, + 0x00000d71,0x00000000,0x00060052,0x00000017,0x00000b27,0x00000174,0x00000b25,0x00000001, + 0x0007004f,0x00000017,0x000008a5,0x00000852,0x00000852,0x00000000,0x00000001,0x00050051, + 0x00000006,0x000008ad,0x000008a5,0x00000000,0x00050051,0x00000006,0x000008af,0x000008a5, + 0x00000001,0x0007000c,0x00000006,0x000008b0,0x00000001,0x00000025,0x000008ad,0x000008af, + 0x00050051,0x00000006,0x000008a8,0x00000852,0x00000002,0x0007000c,0x00000006,0x000008a9, + 0x00000001,0x00000025,0x000008b0,0x000008a8,0x0004007f,0x00000006,0x0000085a,0x000008a9, + 0x0007000c,0x00000006,0x000008c0,0x00000001,0x00000028,0x000008ad,0x000008af,0x0007000c, + 0x00000006,0x000008b9,0x00000001,0x00000028,0x000008c0,0x000008a8,0x00060052,0x00000017, + 0x00000b2f,0x0000085a,0x00000d71,0x00000000,0x00060052,0x00000017,0x00000b31,0x000008b9, + 0x00000b2f,0x00000001,0x0007000c,0x00000017,0x0000085e,0x00000001,0x00000028,0x00000b27, + 0x00000b31,0x00050088,0x00000017,0x0000085f,0x00000b23,0x0000085e,0x00050051,0x00000006, + 0x00000862,0x0000085f,0x00000000,0x00050051,0x00000006,0x00000864,0x0000085f,0x00000001, + 0x0007000c,0x00000006,0x00000865,0x00000001,0x00000025,0x00000862,0x00000864,0x0007000c, + 0x00000006,0x00000866,0x00000001,0x00000025,0x000000c5,0x00000865,0x0005008e,0x00000021, + 0x00000869,0x00000852,0x00000866,0x00060050,0x00000021,0x0000086b,0x00000874,0x00000874, + 0x00000874,0x00050081,0x00000021,0x0000086c,0x00000869,0x0000086b,0x0003003e,0x00000518, + 0x0000086c,0x000200f9,0x00000625,0x000200f8,0x00000625,0x000200f9,0x0000063a,0x000200f8, + 0x00000610,0x000300f7,0x0000061a,0x00000000,0x000400fa,0x000002b0,0x00000611,0x0000061a, + 0x000200f8,0x00000611,0x0004003d,0x00000021,0x00000612,0x00000506,0x00060052,0x00000021, + 0x00000ac5,0x000000bf,0x00000bba,0x00000000,0x00060052,0x00000021,0x00000ac7,0x000000bf, + 0x00000ac5,0x00000001,0x00060052,0x00000021,0x00000ac9,0x000000bf,0x00000ac7,0x00000002, + 0x00060052,0x00000021,0x00000acb,0x000000c5,0x00000bba,0x00000000,0x00060052,0x00000021, + 0x00000acd,0x000000c5,0x00000acb,0x00000001,0x00060052,0x00000021,0x00000acf,0x000000c5, + 0x00000acd,0x00000002,0x0008000c,0x00000021,0x00000615,0x00000001,0x0000002b,0x00000612, + 0x00000ac9,0x00000acf,0x0003003e,0x00000506,0x00000615,0x0007004f,0x00000017,0x000006fc, + 0x0000064b,0x0000064b,0x00000000,0x00000001,0x00050051,0x00000006,0x00000704,0x000006fc, + 0x00000000,0x00050051,0x00000006,0x00000706,0x000006fc,0x00000001,0x0007000c,0x00000006, + 0x00000707,0x00000001,0x00000028,0x00000704,0x00000706,0x00050051,0x00000006,0x000006ff, + 0x0000064b,0x00000002,0x0007000c,0x00000006,0x00000700,0x00000001,0x00000028,0x00000707, + 0x000006ff,0x0007000c,0x00000006,0x00000717,0x00000001,0x00000025,0x00000704,0x00000706, + 0x0007000c,0x00000006,0x00000710,0x00000001,0x00000025,0x00000717,0x000006ff,0x00050083, + 0x00000006,0x000006e7,0x00000700,0x00000710,0x0007004f,0x00000017,0x0000071c,0x00000615, + 0x00000615,0x00000000,0x00000001,0x00050051,0x00000006,0x00000724,0x0000071c,0x00000000, + 0x00050051,0x00000006,0x00000726,0x0000071c,0x00000001,0x0007000c,0x00000006,0x00000727, + 0x00000001,0x00000025,0x00000724,0x00000726,0x00050051,0x00000006,0x0000071f,0x00000615, + 0x00000002,0x0007000c,0x00000006,0x00000720,0x00000001,0x00000025,0x00000727,0x0000071f, + 0x00060050,0x00000021,0x000006eb,0x00000720,0x00000720,0x00000720,0x00050083,0x00000021, + 0x000006ec,0x00000615,0x000006eb,0x0007004f,0x00000017,0x0000072c,0x000006ec,0x000006ec, + 0x00000000,0x00000001,0x00050051,0x00000006,0x00000734,0x0000072c,0x00000000,0x00050051, + 0x00000006,0x00000736,0x0000072c,0x00000001,0x0007000c,0x00000006,0x00000737,0x00000001, + 0x00000028,0x00000734,0x00000736,0x00050051,0x00000006,0x0000072f,0x000006ec,0x00000002, + 0x0007000c,0x00000006,0x00000730,0x00000001,0x00000028,0x00000737,0x0000072f,0x0007000c, + 0x00000006,0x000006f1,0x00000001,0x00000028,0x00000174,0x00000730,0x00050088,0x00000006, + 0x000006f2,0x000006e7,0x000006f1,0x0005008e,0x00000021,0x000006f5,0x000006ec,0x000006f2, + 0x00060052,0x00000021,0x00000add,0x00000158,0x00000bba,0x00000000,0x00060052,0x00000021, + 0x00000adf,0x00000159,0x00000add,0x00000001,0x00060052,0x00000021,0x00000ae1,0x0000015a, + 0x00000adf,0x00000002,0x00050094,0x00000006,0x00000770,0x0000064b,0x00000ae1,0x00050094, + 0x00000006,0x00000782,0x000006f5,0x00000ae1,0x00060050,0x00000021,0x0000074d,0x00000782, + 0x00000782,0x00000782,0x00050083,0x00000021,0x0000074e,0x000006f5,0x0000074d,0x00050083, + 0x00000006,0x00000750,0x000000c5,0x00000770,0x00060052,0x00000017,0x00000ae9,0x00000770, + 0x00000d71,0x00000000,0x00060052,0x00000017,0x00000aeb,0x00000750,0x00000ae9,0x00000001, + 0x00060052,0x00000017,0x00000aed,0x00000174,0x00000d71,0x00000000,0x00060052,0x00000017, + 0x00000aef,0x00000174,0x00000aed,0x00000001,0x0007004f,0x00000017,0x000007a1,0x0000074e, + 0x0000074e,0x00000000,0x00000001,0x00050051,0x00000006,0x000007a9,0x000007a1,0x00000000, + 0x00050051,0x00000006,0x000007ab,0x000007a1,0x00000001,0x0007000c,0x00000006,0x000007ac, + 0x00000001,0x00000025,0x000007a9,0x000007ab,0x00050051,0x00000006,0x000007a4,0x0000074e, + 0x00000002,0x0007000c,0x00000006,0x000007a5,0x00000001,0x00000025,0x000007ac,0x000007a4, + 0x0004007f,0x00000006,0x00000756,0x000007a5,0x0007000c,0x00000006,0x000007bc,0x00000001, + 0x00000028,0x000007a9,0x000007ab,0x0007000c,0x00000006,0x000007b5,0x00000001,0x00000028, + 0x000007bc,0x000007a4,0x00060052,0x00000017,0x00000af7,0x00000756,0x00000d71,0x00000000, + 0x00060052,0x00000017,0x00000af9,0x000007b5,0x00000af7,0x00000001,0x0007000c,0x00000017, + 0x0000075a,0x00000001,0x00000028,0x00000aef,0x00000af9,0x00050088,0x00000017,0x0000075b, + 0x00000aeb,0x0000075a,0x00050051,0x00000006,0x0000075e,0x0000075b,0x00000000,0x00050051, + 0x00000006,0x00000760,0x0000075b,0x00000001,0x0007000c,0x00000006,0x00000761,0x00000001, + 0x00000025,0x0000075e,0x00000760,0x0007000c,0x00000006,0x00000762,0x00000001,0x00000025, + 0x000000c5,0x00000761,0x0005008e,0x00000021,0x00000765,0x0000074e,0x00000762,0x00060050, + 0x00000021,0x00000767,0x00000770,0x00000770,0x00000770,0x00050081,0x00000021,0x00000768, + 0x00000765,0x00000767,0x0003003e,0x00000518,0x00000768,0x000200f9,0x0000061a,0x000200f8, + 0x0000061a,0x000200f9,0x0000063a,0x000200f8,0x00000607,0x0004003d,0x00000021,0x00000608, + 0x00000506,0x00050081,0x00000021,0x0000060a,0x00000608,0x0000064b,0x0005008e,0x00000021, + 0x0000060c,0x00000608,0x000001da,0x00050085,0x00000021,0x0000060e,0x0000060c,0x0000064b, + 0x00050083,0x00000021,0x0000060f,0x0000060a,0x0000060e,0x0003003e,0x00000518,0x0000060f, + 0x000200f9,0x0000063a,0x000200f8,0x00000602,0x0004003d,0x00000021,0x00000604,0x00000506, + 0x00050083,0x00000021,0x00000605,0x0000064b,0x00000604,0x0006000c,0x00000021,0x00000606, + 0x00000001,0x00000004,0x00000605,0x0003003e,0x00000518,0x00000606,0x000200f9,0x0000063a, + 0x000200f8,0x000005c7,0x000200f9,0x000005c8,0x000200f8,0x000005c8,0x000700f5,0x00000054, + 0x00000cd0,0x0000011d,0x000005c7,0x000005f6,0x000005f4,0x000500b1,0x000000c0,0x000005cb, + 0x00000cd0,0x00000128,0x000400f6,0x000005f7,0x000005f4,0x00000000,0x000400fa,0x000005cb, + 0x000005cc,0x000005f7,0x000200f8,0x000005cc,0x00050041,0x0000000d,0x000005ce,0x00000506, + 0x00000cd0,0x0004003d,0x00000006,0x000005cf,0x000005ce,0x000500bc,0x000000c0,0x000005d0, + 0x000005cf,0x000001e1,0x000300f7,0x000005f3,0x00000000,0x000400fa,0x000005d0,0x000005d1, + 0x000005d8,0x000200f8,0x000005d8,0x00050041,0x0000000d,0x000005da,0x00000516,0x00000cd0, + 0x0004003d,0x00000006,0x000005db,0x000005da,0x000500bc,0x000000c0,0x000005dc,0x000005db, + 0x0000012c,0x000300f7,0x000005f2,0x00000000,0x000400fa,0x000005dc,0x000005dd,0x000005ea, + 0x000200f8,0x000005ea,0x0004003d,0x00000006,0x000005ee,0x000005da,0x0006000c,0x00000006, + 0x000005ef,0x00000001,0x00000020,0x000005ee,0x00050083,0x00000006,0x000005f0,0x000005ef, + 0x000000c5,0x00050041,0x0000000d,0x000005f1,0x00000518,0x00000cd0,0x0003003e,0x000005f1, + 0x000005f0,0x000200f9,0x000005f2,0x000200f8,0x000005dd,0x0004003d,0x00000006,0x000005e1, + 0x000005da,0x00050085,0x00000006,0x000005e2,0x0000027f,0x000005e1,0x00050083,0x00000006, + 0x000005e3,0x000005e2,0x00000284,0x0004003d,0x00000006,0x000005e6,0x000005da,0x00050085, + 0x00000006,0x000005e7,0x000005e3,0x000005e6,0x00050081,0x00000006,0x000005e8,0x000005e7, + 0x0000028a,0x00050041,0x0000000d,0x000005e9,0x00000518,0x00000cd0,0x0003003e,0x000005e9, + 0x000005e8,0x000200f9,0x000005f2,0x000200f8,0x000005f2,0x000200f9,0x000005f3,0x000200f8, + 0x000005d1,0x00050041,0x0000000d,0x000005d4,0x00000516,0x00000cd0,0x0004003d,0x00000006, + 0x000005d5,0x000005d4,0x00050083,0x00000006,0x000005d6,0x000000c5,0x000005d5,0x00050041, + 0x0000000d,0x000005d7,0x00000518,0x00000cd0,0x0003003e,0x000005d7,0x000005d6,0x000200f9, + 0x000005f3,0x000200f8,0x000005f3,0x000200f9,0x000005f4,0x000200f8,0x000005f4,0x00050080, + 0x00000054,0x000005f6,0x00000cd0,0x00000120,0x000200f9,0x000005c8,0x000200f8,0x000005f7, + 0x0004003d,0x00000021,0x000005fa,0x00000506,0x0005008e,0x00000021,0x000005fb,0x000005fa, + 0x000001da,0x00050083,0x00000021,0x000005fd,0x000005fb,0x00000d6f,0x00050085,0x00000021, + 0x000005fe,0x0000064b,0x000005fd,0x0004003d,0x00000021,0x000005ff,0x00000518,0x00050085, + 0x00000021,0x00000600,0x000005fe,0x000005ff,0x00050081,0x00000021,0x00000601,0x0000064b, + 0x00000600,0x0003003e,0x00000518,0x00000601,0x000200f9,0x0000063a,0x000200f8,0x000005b6, + 0x0004003d,0x00000021,0x000005b7,0x00000506,0x00050085,0x00000021,0x000005b9,0x000005b7, + 0x0000064b,0x00050081,0x00000021,0x000005bd,0x000005b7,0x0000064b,0x00050083,0x00000021, + 0x000005bf,0x000005bd,0x000005b9,0x00050083,0x00000021,0x000005c1,0x000005bf,0x00000d6e, + 0x00060052,0x00000021,0x00000abf,0x000001e1,0x00000bba,0x00000000,0x00060052,0x00000021, + 0x00000ac1,0x000001e1,0x00000abf,0x00000001,0x00060052,0x00000021,0x00000ac3,0x000001e1, + 0x00000ac1,0x00000002,0x000500ba,0x000001e7,0x000005c4,0x000005b7,0x00000ac3,0x000600a9, + 0x00000021,0x000005c5,0x000005c4,0x000005c1,0x000005b9,0x0005008e,0x00000021,0x000005c6, + 0x000005c5,0x000001da,0x0003003e,0x00000518,0x000005c6,0x000200f9,0x0000063a,0x000200f8, + 0x00000589,0x0004003d,0x00000021,0x0000058a,0x00000506,0x00060052,0x00000021,0x00000a96, + 0x000000bf,0x00000bba,0x00000000,0x00060052,0x00000021,0x00000a98,0x000000bf,0x00000a96, + 0x00000001,0x00060052,0x00000021,0x00000a9a,0x000000bf,0x00000a98,0x00000002,0x00060052, + 0x00000021,0x00000a9c,0x000000c5,0x00000bba,0x00000000,0x00060052,0x00000021,0x00000a9e, + 0x000000c5,0x00000a9c,0x00000001,0x00060052,0x00000021,0x00000aa0,0x000000c5,0x00000a9e, + 0x00000002,0x0008000c,0x00000021,0x0000058d,0x00000001,0x0000002b,0x0000058a,0x00000a9a, + 0x00000aa0,0x0003003e,0x00000506,0x0000058d,0x0008004f,0x00000021,0x00000592,0x00000bb3, + 0x00000bb3,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000021,0x00000593,0x00000001, + 0x0000002b,0x00000640,0x00000a9a,0x00000592,0x00050051,0x00000006,0x00000595,0x00000593, + 0x00000000,0x00060052,0x00000007,0x00000aa8,0x00000595,0x00000bb3,0x00000000,0x00050051, + 0x00000006,0x00000597,0x00000593,0x00000001,0x00060052,0x00000007,0x00000aaa,0x00000597, + 0x00000aa8,0x00000001,0x00050051,0x00000006,0x00000599,0x00000593,0x00000002,0x00060052, + 0x00000007,0x00000aac,0x00000599,0x00000aaa,0x00000002,0x00050051,0x00000006,0x0000059b, + 0x00000aac,0x00000003,0x000500b4,0x000000c0,0x0000059c,0x0000059b,0x000000bf,0x000300f7, + 0x0000059f,0x00000000,0x000400fa,0x0000059c,0x0000059d,0x0000059f,0x000200f8,0x0000059d, + 0x00060052,0x00000007,0x00000aaf,0x000000c5,0x00000aac,0x00000003,0x000200f9,0x0000059f, + 0x000200f8,0x0000059f,0x000700f5,0x00000007,0x00000cfc,0x00000aac,0x00000589,0x00000aaf, + 0x0000059d,0x00050051,0x00000006,0x000005a1,0x00000cfc,0x00000003,0x0008004f,0x00000021, + 0x000005a3,0x00000cfc,0x00000cfc,0x00000000,0x00000001,0x00000002,0x00060050,0x00000021, + 0x000005a4,0x000005a1,0x000005a1,0x000005a1,0x00050083,0x00000021,0x000005a5,0x000005a4, + 0x000005a3,0x0004003d,0x00000021,0x000005a8,0x00000506,0x0005008e,0x00000021,0x000005ab, + 0x000005a8,0x000005a1,0x00050088,0x00000021,0x000005ac,0x000005a5,0x000005ab,0x0007000c, + 0x00000021,0x000005ad,0x00000001,0x00000025,0x00000aa0,0x000005ac,0x0006000c,0x00000021, + 0x000005af,0x00000001,0x00000006,0x000005a5,0x000500b4,0x000001e7,0x000005b2,0x000005a8, + 0x00000a9a,0x000600a9,0x00000021,0x000005b3,0x000005b2,0x000005af,0x000005ad,0x00050083, + 0x00000021,0x000005b5,0x00000d6f,0x000005b3,0x0003003e,0x00000518,0x000005b5,0x000200f9, + 0x0000063a,0x000200f8,0x00000566,0x00060052,0x00000021,0x00000a71,0x000000bf,0x00000bba, + 0x00000000,0x00060052,0x00000021,0x00000a73,0x000000bf,0x00000a71,0x00000001,0x00060052, + 0x00000021,0x00000a75,0x000000bf,0x00000a73,0x00000002,0x0008004f,0x00000021,0x0000056b, + 0x00000bb3,0x00000bb3,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000021,0x0000056c, + 0x00000001,0x0000002b,0x00000640,0x00000a75,0x0000056b,0x00050051,0x00000006,0x0000056e, + 0x0000056c,0x00000000,0x00060052,0x00000007,0x00000a77,0x0000056e,0x00000bb3,0x00000000, + 0x00050051,0x00000006,0x00000570,0x0000056c,0x00000001,0x00060052,0x00000007,0x00000a79, + 0x00000570,0x00000a77,0x00000001,0x00050051,0x00000006,0x00000572,0x0000056c,0x00000002, + 0x00060052,0x00000007,0x00000a7b,0x00000572,0x00000a79,0x00000002,0x0004003d,0x00000021, + 0x00000573,0x00000506,0x00050083,0x00000021,0x00000575,0x00000d6f,0x00000573,0x00060052, + 0x00000021,0x00000a83,0x000000c5,0x00000bba,0x00000000,0x00060052,0x00000021,0x00000a85, + 0x000000c5,0x00000a83,0x00000001,0x00060052,0x00000021,0x00000a87,0x000000c5,0x00000a85, + 0x00000002,0x0008000c,0x00000021,0x00000578,0x00000001,0x0000002b,0x00000575,0x00000a75, + 0x00000a87,0x00050051,0x00000006,0x0000057a,0x00000a7b,0x00000003,0x0005008e,0x00000021, + 0x0000057b,0x00000578,0x0000057a,0x0008004f,0x00000021,0x0000057e,0x00000a7b,0x00000a7b, + 0x00000000,0x00000001,0x00000002,0x00050088,0x00000021,0x00000580,0x0000057e,0x0000057b, + 0x0007000c,0x00000021,0x00000581,0x00000001,0x00000025,0x00000a87,0x00000580,0x0006000c, + 0x00000021,0x00000584,0x00000001,0x00000006,0x0000057e,0x000500b4,0x000001e7,0x00000587, + 0x0000057b,0x00000a75,0x000600a9,0x00000021,0x00000588,0x00000587,0x00000584,0x00000581, + 0x0003003e,0x00000518,0x00000588,0x000200f9,0x0000063a,0x000200f8,0x00000562,0x0004003d, + 0x00000021,0x00000563,0x00000506,0x0007000c,0x00000021,0x00000565,0x00000001,0x00000028, + 0x00000563,0x0000064b,0x0003003e,0x00000518,0x00000565,0x000200f9,0x0000063a,0x000200f8, + 0x0000055e,0x0004003d,0x00000021,0x0000055f,0x00000506,0x0007000c,0x00000021,0x00000561, + 0x00000001,0x00000025,0x0000055f,0x0000064b,0x0003003e,0x00000518,0x00000561,0x000200f9, + 0x0000063a,0x000200f8,0x0000054d,0x0004003d,0x00000021,0x0000054e,0x00000506,0x00050085, + 0x00000021,0x00000550,0x0000054e,0x0000064b,0x00050081,0x00000021,0x00000554,0x0000054e, + 0x0000064b,0x00050083,0x00000021,0x00000556,0x00000554,0x00000550,0x00050083,0x00000021, + 0x00000558,0x00000556,0x00000d6e,0x00060052,0x00000021,0x00000a6b,0x000001e1,0x00000bba, + 0x00000000,0x00060052,0x00000021,0x00000a6d,0x000001e1,0x00000a6b,0x00000001,0x00060052, + 0x00000021,0x00000a6f,0x000001e1,0x00000a6d,0x00000002,0x000500ba,0x000001e7,0x0000055b, + 0x0000064b,0x00000a6f,0x000600a9,0x00000021,0x0000055c,0x0000055b,0x00000558,0x00000550, + 0x0005008e,0x00000021,0x0000055d,0x0000055c,0x000001da,0x0003003e,0x00000518,0x0000055d, + 0x000200f9,0x0000063a,0x000200f8,0x00000545,0x0004003d,0x00000021,0x00000546,0x00000506, + 0x00050081,0x00000021,0x00000548,0x00000546,0x0000064b,0x00050085,0x00000021,0x0000054b, + 0x00000546,0x0000064b,0x00050083,0x00000021,0x0000054c,0x00000548,0x0000054b,0x0003003e, + 0x00000518,0x0000054c,0x000200f9,0x0000063a,0x000200f8,0x00000541,0x0004003d,0x00000021, + 0x00000542,0x00000506,0x00050085,0x00000021,0x00000544,0x00000542,0x0000064b,0x0003003e, + 0x00000518,0x00000544,0x000200f9,0x0000063a,0x000200f8,0x0000063a,0x0004003d,0x00000021, + 0x0000063b,0x00000518,0x00060052,0x00000021,0x00000b8e,0x00000642,0x00000d72,0x00000000, + 0x00060052,0x00000021,0x00000b90,0x00000642,0x00000b8e,0x00000001,0x00060052,0x00000021, + 0x00000b92,0x00000642,0x00000b90,0x00000002,0x0008000c,0x00000021,0x00000515,0x00000001, + 0x0000002e,0x000003de,0x0000063b,0x00000b92,0x00050051,0x00000006,0x000003e5,0x00000515, + 0x00000000,0x00060052,0x00000007,0x00000b94,0x000003e5,0x00000bae,0x00000000,0x00050051, + 0x00000006,0x000003e7,0x00000515,0x00000001,0x00060052,0x00000007,0x00000b96,0x000003e7, + 0x00000b94,0x00000001,0x00050051,0x00000006,0x000003e9,0x00000515,0x00000002,0x00060052, + 0x00000007,0x00000b98,0x000003e9,0x00000b96,0x00000002,0x00050051,0x00000006,0x000003eb, + 0x00000b98,0x00000003,0x0008004f,0x00000021,0x000003ed,0x00000b98,0x00000b98,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x00000021,0x000003ee,0x000003ed,0x000003eb,0x00050051, + 0x00000006,0x000003f0,0x000003ee,0x00000000,0x00060052,0x00000007,0x00000b9b,0x000003f0, + 0x00000b98,0x00000000,0x00050051,0x00000006,0x000003f2,0x000003ee,0x00000001,0x00060052, + 0x00000007,0x00000b9d,0x000003f2,0x00000b9b,0x00000001,0x00050051,0x00000006,0x000003f4, + 0x000003ee,0x00000002,0x00060052,0x00000007,0x00000b9f,0x000003f4,0x00000b9d,0x00000002, + 0x0008004f,0x00000021,0x000003fd,0x00000b9f,0x00000b9f,0x00000000,0x00000001,0x00000002, + 0x0004003d,0x00000007,0x000003ff,0x000003f5,0x0007004f,0x00000017,0x00000400,0x000003ff, + 0x000003ff,0x00000000,0x00000001,0x00050041,0x00000402,0x00000403,0x000003f8,0x000003f9, + 0x0004003d,0x00000006,0x00000404,0x00000403,0x00050041,0x00000402,0x00000406,0x000003f8, + 0x000003fa,0x0004003d,0x00000006,0x00000407,0x00000406,0x000300f7,0x00000a2e,0x00000000, + 0x000400fa,0x00000105,0x00000a24,0x00000a2c,0x000200f8,0x00000a2c,0x000200f9,0x00000a2e, + 0x000200f8,0x00000a24,0x00050051,0x00000006,0x00000a35,0x00000400,0x00000000,0x00050085, + 0x00000006,0x00000a36,0x000000ef,0x00000a35,0x00050051,0x00000006,0x00000a38,0x00000400, + 0x00000001,0x00050085,0x00000006,0x00000a39,0x000000f3,0x00000a38,0x00050081,0x00000006, + 0x00000a3a,0x00000a36,0x00000a39,0x0006000c,0x00000006,0x00000a3b,0x00000001,0x0000000a, + 0x00000a3a,0x00050085,0x00000006,0x00000a3d,0x000000fa,0x00000a3b,0x0006000c,0x00000006, + 0x00000a3e,0x00000001,0x0000000a,0x00000a3d,0x00050085,0x00000006,0x00000a41,0x00000a3e, + 0x00000404,0x00050081,0x00000006,0x00000a43,0x00000a41,0x00000407,0x00060050,0x00000021, + 0x00000a2a,0x00000a43,0x00000a43,0x00000a43,0x00050081,0x00000021,0x00000a2b,0x00000a2a, + 0x000003fd,0x000200f9,0x00000a2e,0x000200f8,0x00000a2e,0x000700f5,0x00000021,0x00000d6c, + 0x00000a2b,0x00000a24,0x000003fd,0x00000a2c,0x00050051,0x00000006,0x0000040a,0x00000d6c, + 0x00000000,0x00060052,0x00000007,0x00000ba3,0x0000040a,0x00000b9f,0x00000000,0x00050051, + 0x00000006,0x0000040c,0x00000d6c,0x00000001,0x00060052,0x00000007,0x00000ba5,0x0000040c, + 0x00000ba3,0x00000001,0x00050051,0x00000006,0x0000040e,0x00000d6c,0x00000002,0x00060052, + 0x00000007,0x00000ba7,0x0000040e,0x00000ba5,0x00000002,0x0003003e,0x00000410,0x00000ba7, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..5a7bb184682a9c51ff58962dd4f490a3933169de GIT binary patch literal 22792 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 bZFefR+2?MQ4Lo_^8J7l0hJR1F4_Ep>R2dUu literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.h new file mode 100644 index 000000000..081f4b800 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.h @@ -0,0 +1,227 @@ +#pragma once + +const uint32_t draw_msaa_atlas_blit_noclipdistance_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000024f,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000ad,0x000000b5,0x000000b9, + 0x000000f4,0x000000f9,0x00000138,0x000001af,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x0000007f,0x0000664a,0x00040006,0x0000007f,0x00000000, + 0x00003464,0x00030005,0x00000081,0x0000424c,0x00030005,0x0000009f,0x0000424d,0x00040006, + 0x0000009f,0x00000000,0x00006250,0x00040006,0x0000009f,0x00000001,0x00006359,0x00040006, + 0x0000009f,0x00000002,0x00006552,0x00040006,0x0000009f,0x00000003,0x00006553,0x00040006, + 0x0000009f,0x00000004,0x0000366d,0x00040006,0x0000009f,0x00000005,0x0000676d,0x00040006, + 0x0000009f,0x00000006,0x00006544,0x00040006,0x0000009f,0x00000007,0x00006545,0x00040006, + 0x0000009f,0x00000008,0x00003755,0x00040006,0x0000009f,0x00000009,0x0000676a,0x00040006, + 0x0000009f,0x0000000a,0x0000635a,0x00040006,0x0000009f,0x0000000b,0x00003157,0x00040006, + 0x0000009f,0x0000000c,0x0000676e,0x00040006,0x0000009f,0x0000000d,0x00003559,0x00040006, + 0x0000009f,0x0000000e,0x0000324f,0x00040006,0x0000009f,0x0000000f,0x00006461,0x00040006, + 0x0000009f,0x00000010,0x00006579,0x00040006,0x0000009f,0x00000011,0x00003376,0x00040006, + 0x0000009f,0x00000012,0x00003377,0x00040006,0x0000009f,0x00000013,0x00006462,0x00040006, + 0x0000009f,0x00000014,0x00006767,0x00030005,0x000000a1,0x0000006b,0x00060005,0x000000ad, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x000000b5,0x0000424a,0x00030005, + 0x000000b9,0x00003243,0x00030005,0x000000c7,0x00006576,0x00040006,0x000000c7,0x00000000, + 0x00003464,0x00030005,0x000000c9,0x00004355,0x00030005,0x000000d3,0x00006747,0x00030005, + 0x000000f4,0x00003346,0x00030005,0x000000f6,0x00006749,0x00030005,0x000000f9,0x00003159, + 0x00030005,0x00000107,0x00006577,0x00040006,0x00000107,0x00000000,0x00003464,0x00030005, + 0x00000109,0x0000424f,0x00030005,0x00000138,0x0000316b,0x00060005,0x000001ad,0x505f6c67, + 0x65567265,0x78657472,0x00000000,0x00060006,0x000001ad,0x00000000,0x505f6c67,0x7469736f, + 0x006e6f69,0x00070006,0x000001ad,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000, + 0x00070006,0x000001ad,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006, + 0x000001ad,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000001af, + 0x00000000,0x00030005,0x000001bd,0x00004342,0x00030005,0x000001c0,0x00004351,0x00030005, + 0x000001c2,0x0000664b,0x00040006,0x000001c2,0x00000000,0x00003464,0x00030005,0x000001c4, + 0x00004358,0x00030005,0x000001c7,0x00003954,0x00040047,0x0000007e,0x00000006,0x00000010, + 0x00030047,0x0000007f,0x00000003,0x00040048,0x0000007f,0x00000000,0x00000018,0x00050048, + 0x0000007f,0x00000000,0x00000023,0x00000000,0x00030047,0x00000081,0x00000018,0x00040047, + 0x00000081,0x00000021,0x00000003,0x00040047,0x00000081,0x00000022,0x00000000,0x00030047, + 0x0000009f,0x00000002,0x00050048,0x0000009f,0x00000000,0x00000023,0x00000000,0x00050048, + 0x0000009f,0x00000001,0x00000023,0x00000004,0x00050048,0x0000009f,0x00000002,0x00000023, + 0x00000008,0x00050048,0x0000009f,0x00000003,0x00000023,0x0000000c,0x00050048,0x0000009f, + 0x00000004,0x00000023,0x00000010,0x00050048,0x0000009f,0x00000005,0x00000023,0x00000014, + 0x00050048,0x0000009f,0x00000006,0x00000023,0x00000018,0x00050048,0x0000009f,0x00000007, + 0x00000023,0x0000001c,0x00050048,0x0000009f,0x00000008,0x00000023,0x00000020,0x00050048, + 0x0000009f,0x00000009,0x00000023,0x00000030,0x00050048,0x0000009f,0x0000000a,0x00000023, + 0x00000038,0x00050048,0x0000009f,0x0000000b,0x00000023,0x00000040,0x00050048,0x0000009f, + 0x0000000c,0x00000023,0x00000044,0x00050048,0x0000009f,0x0000000d,0x00000023,0x00000048, + 0x00050048,0x0000009f,0x0000000e,0x00000023,0x0000004c,0x00050048,0x0000009f,0x0000000f, + 0x00000023,0x00000050,0x00050048,0x0000009f,0x00000010,0x00000023,0x00000054,0x00050048, + 0x0000009f,0x00000011,0x00000023,0x00000058,0x00050048,0x0000009f,0x00000012,0x00000023, + 0x0000005c,0x00050048,0x0000009f,0x00000013,0x00000023,0x00000060,0x00050048,0x0000009f, + 0x00000014,0x00000023,0x00000064,0x00040047,0x000000a1,0x00000021,0x00000000,0x00040047, + 0x000000a1,0x00000022,0x00000000,0x00040047,0x000000ad,0x0000000b,0x0000002a,0x00040047, + 0x000000b5,0x0000001e,0x00000000,0x00040047,0x000000b9,0x0000001e,0x00000001,0x00040047, + 0x000000c6,0x00000006,0x00000008,0x00030047,0x000000c7,0x00000003,0x00040048,0x000000c7, + 0x00000000,0x00000018,0x00050048,0x000000c7,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000c9,0x00000018,0x00040047,0x000000c9,0x00000021,0x00000004,0x00040047,0x000000c9, + 0x00000022,0x00000000,0x00040047,0x000000d3,0x00000001,0x00000000,0x00030047,0x000000f2, + 0x00000000,0x00030047,0x000000f4,0x00000000,0x00030047,0x000000f4,0x0000000e,0x00040047, + 0x000000f4,0x0000001e,0x00000004,0x00040047,0x000000f6,0x00000001,0x00000002,0x00030047, + 0x000000f9,0x00000000,0x00030047,0x000000f9,0x0000000e,0x00040047,0x000000f9,0x0000001e, + 0x00000006,0x00040047,0x00000106,0x00000006,0x00000010,0x00030047,0x00000107,0x00000003, + 0x00040048,0x00000107,0x00000000,0x00000018,0x00050048,0x00000107,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000109,0x00000018,0x00040047,0x00000109,0x00000021,0x00000005, + 0x00040047,0x00000109,0x00000022,0x00000000,0x00030047,0x0000012d,0x00000000,0x00030047, + 0x0000012f,0x00000000,0x00030047,0x00000130,0x00000000,0x00040047,0x00000138,0x0000001e, + 0x00000000,0x00030047,0x000001ad,0x00000002,0x00050048,0x000001ad,0x00000000,0x0000000b, + 0x00000000,0x00050048,0x000001ad,0x00000001,0x0000000b,0x00000001,0x00050048,0x000001ad, + 0x00000002,0x0000000b,0x00000003,0x00050048,0x000001ad,0x00000003,0x0000000b,0x00000004, + 0x00040047,0x000001bd,0x00000021,0x00000008,0x00040047,0x000001bd,0x00000022,0x00000000, + 0x00030047,0x000001c0,0x00000000,0x00040047,0x000001c0,0x00000021,0x0000000a,0x00040047, + 0x000001c0,0x00000022,0x00000000,0x00040047,0x000001c1,0x00000006,0x00000010,0x00030047, + 0x000001c2,0x00000003,0x00040048,0x000001c2,0x00000000,0x00000018,0x00050048,0x000001c2, + 0x00000000,0x00000023,0x00000000,0x00030047,0x000001c4,0x00000018,0x00040047,0x000001c4, + 0x00000021,0x00000006,0x00040047,0x000001c4,0x00000022,0x00000000,0x00030047,0x000001c7, + 0x00000000,0x00040047,0x000001c7,0x00000021,0x0000000a,0x00040047,0x000001c7,0x00000022, + 0x00000000,0x00030047,0x0000023a,0x00000000,0x00030047,0x0000023c,0x00000000,0x00030047, + 0x0000023e,0x00000000,0x00030047,0x0000024d,0x00000000,0x00030047,0x0000024e,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020, + 0x00000000,0x00030016,0x0000000c,0x00000020,0x00040017,0x0000000d,0x0000000c,0x00000004, + 0x00040017,0x0000000f,0x0000000c,0x00000002,0x00040018,0x00000010,0x0000000f,0x00000002, + 0x00040017,0x0000002d,0x0000000c,0x00000003,0x0004002b,0x0000000c,0x0000003f,0x3f800000, + 0x0004002b,0x0000000c,0x00000040,0x00000000,0x0004002b,0x00000006,0x0000004b,0x00000000, + 0x00020014,0x0000004c,0x0004002b,0x00000006,0x00000053,0x000003ff,0x0004002b,0x00000006, + 0x00000063,0x00000001,0x0004002b,0x0000000c,0x00000070,0x38800000,0x0004002b,0x00000006, + 0x00000075,0x00000002,0x0004002b,0x00000006,0x00000079,0x0000ffff,0x00040017,0x0000007b, + 0x00000006,0x00000004,0x0003001d,0x0000007e,0x0000007b,0x0003001e,0x0000007f,0x0000007e, + 0x00040020,0x00000080,0x00000002,0x0000007f,0x0004003b,0x00000080,0x00000081,0x00000002, + 0x00040015,0x00000082,0x00000020,0x00000001,0x0004002b,0x00000082,0x00000083,0x00000000, + 0x0004002b,0x00000006,0x00000085,0x00000004,0x00040020,0x00000088,0x00000002,0x0000007b, + 0x00040017,0x00000093,0x00000006,0x00000003,0x00040017,0x0000009e,0x00000082,0x00000004, + 0x0017001e,0x0000009f,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x00000006,0x00000006, + 0x00000006,0x00000006,0x0000009e,0x0000000f,0x0000000f,0x00000006,0x0000000c,0x00000006, + 0x0000000c,0x0000000c,0x00000006,0x0000000c,0x0000000c,0x0000000c,0x00000006,0x00040020, + 0x000000a0,0x00000002,0x0000009f,0x0004003b,0x000000a0,0x000000a1,0x00000002,0x0004002b, + 0x00000082,0x000000a2,0x00000009,0x00040020,0x000000a3,0x00000002,0x0000000f,0x00040020, + 0x000000ac,0x00000001,0x00000082,0x0004003b,0x000000ac,0x000000ad,0x00000001,0x00040020, + 0x000000b4,0x00000001,0x0000002d,0x0004003b,0x000000b4,0x000000b5,0x00000001,0x00040020, + 0x000000b8,0x00000003,0x0000000f,0x0004003b,0x000000b8,0x000000b9,0x00000003,0x00040017, + 0x000000c3,0x00000006,0x00000002,0x0003001d,0x000000c6,0x000000c3,0x0003001e,0x000000c7, + 0x000000c6,0x00040020,0x000000c8,0x00000002,0x000000c7,0x0004003b,0x000000c8,0x000000c9, + 0x00000002,0x00040020,0x000000cb,0x00000002,0x000000c3,0x0004002b,0x00000006,0x000000d1, + 0x0000000f,0x00030030,0x0000004c,0x000000d3,0x0004002b,0x00000082,0x000000e2,0x00000010, + 0x0004002b,0x00000082,0x000000e5,0x0000000d,0x00040020,0x000000e9,0x00000002,0x00000006, + 0x00040020,0x000000f3,0x00000003,0x0000000c,0x0004003b,0x000000f3,0x000000f4,0x00000003, + 0x00030030,0x0000004c,0x000000f6,0x0004003b,0x000000f3,0x000000f9,0x00000003,0x0004002b, + 0x00000082,0x000000fc,0x00000004,0x0003001d,0x00000106,0x0000000d,0x0003001e,0x00000107, + 0x00000106,0x00040020,0x00000108,0x00000002,0x00000107,0x0004003b,0x00000108,0x00000109, + 0x00000002,0x00040020,0x0000010e,0x00000002,0x0000000d,0x0004002b,0x00000006,0x00000115, + 0x00000003,0x00050034,0x0000004c,0x00000129,0x000000a8,0x000000f6,0x00040020,0x00000137, + 0x00000003,0x0000000d,0x0004003b,0x00000137,0x00000138,0x00000003,0x0004002b,0x0000000c, + 0x0000015f,0x3f666666,0x0004002b,0x0000000c,0x00000163,0x40000000,0x0004002b,0x0000000c, + 0x00000188,0xc0000000,0x0004002b,0x00000082,0x00000191,0x00000002,0x0004002b,0x00000082, + 0x00000192,0x00000003,0x00040020,0x00000196,0x00000002,0x0000000c,0x0004001c,0x000001ac, + 0x0000000c,0x00000063,0x0006001e,0x000001ad,0x0000000d,0x0000000c,0x000001ac,0x000001ac, + 0x00040020,0x000001ae,0x00000003,0x000001ad,0x0004003b,0x000001ae,0x000001af,0x00000003, + 0x00090019,0x000001bb,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x000001bc,0x00000000,0x000001bb,0x0004003b,0x000001bc,0x000001bd, + 0x00000000,0x00090019,0x000001be,0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x000001bf,0x00000000,0x000001be,0x0004003b,0x000001bf, + 0x000001c0,0x00000000,0x0003001d,0x000001c1,0x0000007b,0x0003001e,0x000001c2,0x000001c1, + 0x00040020,0x000001c3,0x00000002,0x000001c2,0x0004003b,0x000001c3,0x000001c4,0x00000002, + 0x0002001a,0x000001c5,0x00040020,0x000001c6,0x00000000,0x000001c5,0x0004003b,0x000001c6, + 0x000001c7,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x0000002d,0x000000bb,0x000000b5,0x00050051,0x0000000c,0x000001cf, + 0x000000bb,0x00000002,0x0004007c,0x00000006,0x000001d0,0x000001cf,0x000500c7,0x00000006, + 0x000001d1,0x000001d0,0x00000079,0x00050084,0x00000006,0x000001d3,0x000001d1,0x00000085, + 0x00050080,0x00000006,0x000001d4,0x000001d3,0x00000075,0x00060041,0x00000088,0x000001d5, + 0x00000081,0x00000083,0x000001d4,0x0004003d,0x0000007b,0x000001d6,0x000001d5,0x00050051, + 0x00000006,0x000001d8,0x000001d6,0x00000000,0x0007004f,0x0000000f,0x000001db,0x000000bb, + 0x000000bb,0x00000000,0x00000001,0x0008004f,0x00000093,0x000001dd,0x000001d6,0x000001d6, + 0x00000001,0x00000002,0x00000003,0x0004007c,0x0000002d,0x000001de,0x000001dd,0x00050051, + 0x0000000c,0x000001e1,0x000001de,0x00000000,0x0005008e,0x0000000f,0x000001e2,0x000001db, + 0x000001e1,0x0007004f,0x0000000f,0x000001e4,0x000001de,0x000001de,0x00000001,0x00000002, + 0x00050081,0x0000000f,0x000001e5,0x000001e2,0x000001e4,0x00050041,0x000000a3,0x000001e6, + 0x000000a1,0x000000a2,0x0004003d,0x0000000f,0x000001e7,0x000001e6,0x00050085,0x0000000f, + 0x000001e8,0x000001e5,0x000001e7,0x0003003e,0x000000b9,0x000001e8,0x00060041,0x000000cb, + 0x000000cc,0x000000c9,0x00000083,0x000001d1,0x0004003d,0x000000c3,0x000000cd,0x000000cc, + 0x00050051,0x00000006,0x000000d0,0x000000cd,0x00000000,0x000500c7,0x00000006,0x000000d2, + 0x000000d0,0x000000d1,0x000300f7,0x000000d5,0x00000000,0x000400fa,0x000000d3,0x000000d4, + 0x000000d5,0x000200f8,0x000000d4,0x000500aa,0x0000004c,0x000000d8,0x000000d2,0x0000004b, + 0x000300f7,0x000000db,0x00000000,0x000400fa,0x000000d8,0x000000da,0x000000de,0x000200f8, + 0x000000de,0x000200f9,0x000000db,0x000200f8,0x000000da,0x00050051,0x00000006,0x000000dd, + 0x000000cd,0x00000001,0x000200f9,0x000000db,0x000200f8,0x000000db,0x000700f5,0x00000006, + 0x0000024b,0x000000dd,0x000000da,0x000000d0,0x000000de,0x000500c2,0x00000006,0x000000e3, + 0x0000024b,0x000000e2,0x00050041,0x000000e9,0x000000ea,0x000000a1,0x000000e5,0x0004003d, + 0x00000006,0x000000eb,0x000000ea,0x000500aa,0x0000004c,0x000001f4,0x000000e3,0x0000004b, + 0x000300f7,0x000001fd,0x00000000,0x000400fa,0x000001f4,0x000001f5,0x000001f6,0x000200f8, + 0x000001f6,0x00050080,0x00000006,0x000001f8,0x000000e3,0x00000053,0x00050084,0x00000006, + 0x000001fa,0x000001f8,0x000000eb,0x0006000c,0x0000000f,0x000001fb,0x00000001,0x0000003e, + 0x000001fa,0x00050051,0x0000000c,0x000001fc,0x000001fb,0x00000000,0x000200f9,0x000001fd, + 0x000200f8,0x000001f5,0x000200f9,0x000001fd,0x000200f8,0x000001fd,0x000700f5,0x0000000c, + 0x0000024c,0x00000040,0x000001f5,0x000001fc,0x000001f6,0x000300f7,0x000000f0,0x00000000, + 0x000400fa,0x000000d8,0x000000ef,0x000000f0,0x000200f8,0x000000ef,0x0004007f,0x0000000c, + 0x000000f2,0x0000024c,0x000200f9,0x000000f0,0x000200f8,0x000000f0,0x000700f5,0x0000000c, + 0x0000024d,0x0000024c,0x000001fd,0x000000f2,0x000000ef,0x0003003e,0x000000f4,0x0000024d, + 0x000200f9,0x000000d5,0x000200f8,0x000000d5,0x000300f7,0x000000f8,0x00000000,0x000400fa, + 0x000000f6,0x000000f7,0x000000f8,0x000200f8,0x000000f7,0x000500c2,0x00000006,0x000000fd, + 0x000000d0,0x000000fc,0x000500c7,0x00000006,0x000000fe,0x000000fd,0x000000d1,0x00040070, + 0x0000000c,0x000000ff,0x000000fe,0x0003003e,0x000000f9,0x000000ff,0x000200f9,0x000000f8, + 0x000200f8,0x000000f8,0x000500aa,0x0000004c,0x00000122,0x000000d2,0x00000063,0x000300f7, + 0x00000124,0x00000000,0x000400fa,0x00000122,0x00000123,0x0000013a,0x000200f8,0x0000013a, + 0x00060041,0x0000010e,0x0000013f,0x00000109,0x00000083,0x000001d3,0x0004003d,0x0000000d, + 0x00000140,0x0000013f,0x00050051,0x0000000c,0x00000214,0x00000140,0x00000000,0x00050051, + 0x0000000c,0x00000215,0x00000140,0x00000001,0x00050051,0x0000000c,0x00000216,0x00000140, + 0x00000002,0x00050051,0x0000000c,0x00000217,0x00000140,0x00000003,0x00050050,0x0000000f, + 0x00000218,0x00000214,0x00000215,0x00050050,0x0000000f,0x00000219,0x00000216,0x00000217, + 0x00050050,0x00000010,0x0000021a,0x00000218,0x00000219,0x00050080,0x00000006,0x00000145, + 0x000001d3,0x00000063,0x00060041,0x0000010e,0x00000146,0x00000109,0x00000083,0x00000145, + 0x0004003d,0x0000000d,0x00000147,0x00000146,0x00050091,0x0000000f,0x0000014b,0x0000021a, + 0x000001db,0x0007004f,0x0000000f,0x0000014d,0x00000147,0x00000147,0x00000000,0x00000001, + 0x00050081,0x0000000f,0x0000014e,0x0000014b,0x0000014d,0x000500aa,0x0000004c,0x00000150, + 0x000000d2,0x00000075,0x000500aa,0x0000004c,0x00000152,0x000000d2,0x00000115,0x000500a6, + 0x0000004c,0x00000153,0x00000150,0x00000152,0x000300f7,0x00000155,0x00000000,0x000400fa, + 0x00000153,0x00000154,0x0000017b,0x000200f8,0x0000017b,0x00050051,0x00000006,0x0000017e, + 0x000000cd,0x00000001,0x0004007c,0x0000000c,0x0000017f,0x0000017e,0x00050051,0x0000000c, + 0x00000182,0x00000147,0x00000002,0x00050051,0x0000000c,0x00000184,0x0000014e,0x00000000, + 0x00050051,0x0000000c,0x00000186,0x0000014e,0x00000001,0x00050083,0x0000000c,0x0000018a, + 0x00000188,0x00000182,0x00070050,0x0000000d,0x0000018b,0x00000184,0x00000186,0x0000017f, + 0x0000018a,0x0003003e,0x00000138,0x0000018b,0x000200f9,0x00000155,0x000200f8,0x00000154, + 0x00050051,0x00000006,0x00000157,0x000000cd,0x00000001,0x0004007c,0x0000000c,0x00000158, + 0x00000157,0x0004007f,0x0000000c,0x00000159,0x00000158,0x00050041,0x000000f3,0x0000015a, + 0x00000138,0x00000115,0x0003003e,0x0000015a,0x00000159,0x00050051,0x0000000c,0x0000015d, + 0x00000147,0x00000002,0x000500ba,0x0000004c,0x00000160,0x0000015d,0x0000015f,0x000300f7, + 0x00000162,0x00000000,0x000400fa,0x00000160,0x00000161,0x00000165,0x000200f8,0x00000165, + 0x00050051,0x0000000c,0x00000167,0x00000147,0x00000003,0x00050041,0x000000f3,0x00000168, + 0x00000138,0x00000075,0x0003003e,0x00000168,0x00000167,0x000200f9,0x00000162,0x000200f8, + 0x00000161,0x00050041,0x000000f3,0x00000164,0x00000138,0x00000075,0x0003003e,0x00000164, + 0x00000163,0x000200f9,0x00000162,0x000200f8,0x00000162,0x000300f7,0x0000016c,0x00000000, + 0x000400fa,0x00000150,0x0000016b,0x00000171,0x000200f8,0x00000171,0x00050041,0x000000f3, + 0x00000172,0x00000138,0x00000075,0x0004003d,0x0000000c,0x00000173,0x00000172,0x0004007f, + 0x0000000c,0x00000174,0x00000173,0x0003003e,0x00000172,0x00000174,0x00050041,0x000000f3, + 0x00000177,0x00000138,0x0000004b,0x00050051,0x0000000c,0x00000178,0x0000014e,0x00000000, + 0x0003003e,0x00000177,0x00000178,0x00050041,0x000000f3,0x00000179,0x00000138,0x00000063, + 0x00050051,0x0000000c,0x0000017a,0x0000014e,0x00000001,0x0003003e,0x00000179,0x0000017a, + 0x000200f9,0x0000016c,0x000200f8,0x0000016b,0x00050041,0x000000f3,0x0000016d,0x00000138, + 0x00000063,0x0003003e,0x0000016d,0x00000040,0x00050051,0x0000000c,0x0000016f,0x0000014e, + 0x00000000,0x00050041,0x000000f3,0x00000170,0x00000138,0x0000004b,0x0003003e,0x00000170, + 0x0000016f,0x000200f9,0x0000016c,0x000200f8,0x0000016c,0x000200f9,0x00000155,0x000200f8, + 0x00000155,0x000200f9,0x00000124,0x000200f8,0x00000123,0x00050051,0x00000006,0x00000127, + 0x000000cd,0x00000001,0x0006000c,0x0000000d,0x00000128,0x00000001,0x00000040,0x00000127, + 0x000300f7,0x0000012b,0x00000000,0x000400fa,0x00000129,0x0000012a,0x0000012b,0x000200f8, + 0x0000012a,0x00050051,0x0000000c,0x0000012d,0x00000128,0x00000003,0x0008004f,0x0000002d, + 0x0000012f,0x00000128,0x00000128,0x00000000,0x00000001,0x00000002,0x0005008e,0x0000002d, + 0x00000130,0x0000012f,0x0000012d,0x00050051,0x0000000c,0x00000132,0x00000130,0x00000000, + 0x00060052,0x0000000d,0x0000023a,0x00000132,0x00000128,0x00000000,0x00050051,0x0000000c, + 0x00000134,0x00000130,0x00000001,0x00060052,0x0000000d,0x0000023c,0x00000134,0x0000023a, + 0x00000001,0x00050051,0x0000000c,0x00000136,0x00000130,0x00000002,0x00060052,0x0000000d, + 0x0000023e,0x00000136,0x0000023c,0x00000002,0x000200f9,0x0000012b,0x000200f8,0x0000012b, + 0x000700f5,0x0000000d,0x0000024e,0x00000128,0x00000123,0x0000023e,0x0000012a,0x0003003e, + 0x00000138,0x0000024e,0x000200f9,0x00000124,0x000200f8,0x00000124,0x00050041,0x00000196, + 0x00000197,0x000000a1,0x00000191,0x0004003d,0x0000000c,0x00000198,0x00000197,0x00050041, + 0x00000196,0x0000019a,0x000000a1,0x00000192,0x0004003d,0x0000000c,0x0000019b,0x0000019a, + 0x00050051,0x0000000c,0x0000021e,0x000000bb,0x00000000,0x00050085,0x0000000c,0x00000220, + 0x0000021e,0x00000198,0x00050083,0x0000000c,0x00000221,0x00000220,0x0000003f,0x00050051, + 0x0000000c,0x00000223,0x000000bb,0x00000001,0x00050085,0x0000000c,0x00000225,0x00000223, + 0x0000019b,0x0006000c,0x0000000c,0x00000227,0x00000001,0x00000006,0x0000019b,0x00050083, + 0x0000000c,0x00000228,0x00000225,0x00000227,0x00070050,0x0000000d,0x00000229,0x00000221, + 0x00000228,0x00000040,0x0000003f,0x00040070,0x0000000c,0x0000022d,0x000001d8,0x00050085, + 0x0000000c,0x0000022e,0x0000022d,0x00000070,0x00050083,0x0000000c,0x0000022f,0x0000003f, + 0x0000022e,0x00060052,0x0000000d,0x0000024a,0x0000022f,0x00000229,0x00000002,0x00050041, + 0x00000137,0x000001b1,0x000001af,0x00000083,0x0003003e,0x000001b1,0x0000024a,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..c777931cd011b154cee673a8a8bcfc59ea330f8b GIT binary patch literal 7108 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 QhvDP*h`hQN$#x<0e@lY;82|tP literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.h new file mode 100644 index 000000000..de60c550b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.h @@ -0,0 +1,177 @@ +#pragma once + +const uint32_t draw_msaa_atlas_blit_webgpu_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000246,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000011d,0x00000128,0x00000139, + 0x00000156,0x0000015b,0x0000015c,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00070004,0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000d0,0x00004444,0x00030005,0x000000d4, + 0x00006277,0x00030005,0x000000f5,0x00004344,0x00030005,0x000000f7,0x00003552,0x00030005, + 0x00000117,0x00004356,0x00030005,0x00000119,0x00003949,0x00030005,0x0000011d,0x00003243, + 0x00030005,0x00000128,0x0000316b,0x00060005,0x00000139,0x465f6c67,0x43676172,0x64726f6f, + 0x00000000,0x00030005,0x0000013c,0x0000424d,0x00040006,0x0000013c,0x00000000,0x00006250, + 0x00040006,0x0000013c,0x00000001,0x00006359,0x00040006,0x0000013c,0x00000002,0x00006552, + 0x00040006,0x0000013c,0x00000003,0x00006553,0x00040006,0x0000013c,0x00000004,0x0000366d, + 0x00040006,0x0000013c,0x00000005,0x0000676d,0x00040006,0x0000013c,0x00000006,0x00006544, + 0x00040006,0x0000013c,0x00000007,0x00006545,0x00040006,0x0000013c,0x00000008,0x00003755, + 0x00040006,0x0000013c,0x00000009,0x0000676a,0x00040006,0x0000013c,0x0000000a,0x0000635a, + 0x00040006,0x0000013c,0x0000000b,0x00003157,0x00040006,0x0000013c,0x0000000c,0x0000676e, + 0x00040006,0x0000013c,0x0000000d,0x00003559,0x00040006,0x0000013c,0x0000000e,0x0000324f, + 0x00040006,0x0000013c,0x0000000f,0x00006461,0x00040006,0x0000013c,0x00000010,0x00006579, + 0x00040006,0x0000013c,0x00000011,0x00003376,0x00040006,0x0000013c,0x00000012,0x00003377, + 0x00040006,0x0000013c,0x00000013,0x00006462,0x00040006,0x0000013c,0x00000014,0x00006767, + 0x00030005,0x0000013e,0x0000006b,0x00030005,0x00000156,0x00006771,0x00030005,0x00000158, + 0x00003954,0x00030005,0x00000159,0x00004351,0x00030005,0x0000015b,0x00003346,0x00030005, + 0x0000015c,0x00003159,0x00030047,0x000000d0,0x00000000,0x00040047,0x000000d0,0x00000021, + 0x00000009,0x00040047,0x000000d0,0x00000022,0x00000000,0x00030047,0x000000d4,0x00000000, + 0x00040047,0x000000d4,0x00000021,0x00000009,0x00040047,0x000000d4,0x00000022,0x00000003, + 0x00030047,0x000000f5,0x00000000,0x00040047,0x000000f5,0x00000021,0x0000000c,0x00040047, + 0x000000f5,0x00000022,0x00000001,0x00030047,0x000000f7,0x00000000,0x00040047,0x000000f7, + 0x00000021,0x0000000e,0x00040047,0x000000f7,0x00000022,0x00000001,0x00030047,0x00000117, + 0x00000000,0x00040047,0x00000117,0x00000021,0x0000000b,0x00040047,0x00000117,0x00000022, + 0x00000000,0x00030047,0x00000118,0x00000000,0x00030047,0x00000119,0x00000000,0x00040047, + 0x00000119,0x00000021,0x0000000b,0x00040047,0x00000119,0x00000022,0x00000003,0x00030047, + 0x0000011a,0x00000000,0x00040047,0x0000011d,0x0000001e,0x00000001,0x00030047,0x0000011f, + 0x00000000,0x00030047,0x00000120,0x00000000,0x00030047,0x00000125,0x00000000,0x00040047, + 0x00000128,0x0000001e,0x00000000,0x00030047,0x0000012f,0x00000000,0x00030047,0x00000131, + 0x00000000,0x00030047,0x00000132,0x00000000,0x00040047,0x00000139,0x0000000b,0x0000000f, + 0x00030047,0x0000013c,0x00000002,0x00050048,0x0000013c,0x00000000,0x00000023,0x00000000, + 0x00050048,0x0000013c,0x00000001,0x00000023,0x00000004,0x00050048,0x0000013c,0x00000002, + 0x00000023,0x00000008,0x00050048,0x0000013c,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x0000013c,0x00000004,0x00000023,0x00000010,0x00050048,0x0000013c,0x00000005,0x00000023, + 0x00000014,0x00050048,0x0000013c,0x00000006,0x00000023,0x00000018,0x00050048,0x0000013c, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x0000013c,0x00000008,0x00000023,0x00000020, + 0x00050048,0x0000013c,0x00000009,0x00000023,0x00000030,0x00050048,0x0000013c,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x0000013c,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x0000013c,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000013c,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x0000013c,0x0000000e,0x00000023,0x0000004c,0x00050048,0x0000013c, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x0000013c,0x00000010,0x00000023,0x00000054, + 0x00050048,0x0000013c,0x00000011,0x00000023,0x00000058,0x00050048,0x0000013c,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x0000013c,0x00000013,0x00000023,0x00000060,0x00050048, + 0x0000013c,0x00000014,0x00000023,0x00000064,0x00040047,0x0000013e,0x00000021,0x00000000, + 0x00040047,0x0000013e,0x00000022,0x00000000,0x00030047,0x00000143,0x00000000,0x00030047, + 0x00000156,0x00000000,0x00040047,0x00000156,0x0000001e,0x00000000,0x00030047,0x00000158, + 0x00000000,0x00040047,0x00000158,0x00000021,0x0000000a,0x00040047,0x00000158,0x00000022, + 0x00000003,0x00030047,0x00000159,0x00000000,0x00040047,0x00000159,0x00000021,0x0000000a, + 0x00040047,0x00000159,0x00000022,0x00000000,0x00030047,0x0000015b,0x00000000,0x00030047, + 0x0000015b,0x0000000e,0x00040047,0x0000015b,0x0000001e,0x00000004,0x00030047,0x0000015c, + 0x00000000,0x00030047,0x0000015c,0x0000000e,0x00040047,0x0000015c,0x0000001e,0x00000006, + 0x00030047,0x0000017e,0x00000000,0x00030047,0x0000017f,0x00000000,0x00030047,0x00000184, + 0x00000000,0x00030047,0x0000018f,0x00000000,0x00030047,0x000001b4,0x00000000,0x00030047, + 0x000001b5,0x00000000,0x00030047,0x000001ba,0x00000000,0x00030047,0x000001bd,0x00000000, + 0x00030047,0x000001c8,0x00000000,0x00030047,0x000001d2,0x00000000,0x00030047,0x000001d4, + 0x00000000,0x00030047,0x000001da,0x00000000,0x00030047,0x000001dd,0x00000000,0x00030047, + 0x000001fc,0x00000000,0x00030047,0x000001fd,0x00000000,0x00030047,0x0000020d,0x00000000, + 0x00030047,0x0000020e,0x00000000,0x00030047,0x00000211,0x00000000,0x00030047,0x00000213, + 0x00000000,0x00030047,0x00000229,0x00000000,0x00030047,0x0000022c,0x00000000,0x00030047, + 0x0000022f,0x00000000,0x00030047,0x00000231,0x00000000,0x00030047,0x00000233,0x00000000, + 0x00030047,0x00000237,0x00000000,0x00030047,0x00000239,0x00000000,0x00030047,0x0000023b, + 0x00000000,0x00030047,0x0000023c,0x00000000,0x00030047,0x00000243,0x00000000,0x00030047, + 0x00000242,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017,0x00000012, + 0x00000006,0x00000003,0x00040017,0x0000001d,0x00000006,0x00000002,0x00040015,0x0000003b, + 0x00000020,0x00000000,0x0004002b,0x00000006,0x0000004f,0x00000000,0x00020014,0x00000050, + 0x0004002b,0x00000006,0x00000055,0x3f800000,0x0004002b,0x00000006,0x0000005f,0x3d897143, + 0x0004002b,0x00000006,0x00000063,0x3bbf4590,0x0004002b,0x00000006,0x0000006a,0x4253ee82, + 0x0004002b,0x00000006,0x000000a0,0xbf800000,0x0004002b,0x00000006,0x000000be,0x3f7f8000, + 0x0004002b,0x00000006,0x000000c1,0x3a800000,0x0004002b,0x00000006,0x000000c4,0x3b000000, + 0x00090019,0x000000ce,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x000000cf,0x00000000,0x000000ce,0x0004003b,0x000000cf,0x000000d0, + 0x00000000,0x0002001a,0x000000d2,0x00040020,0x000000d3,0x00000000,0x000000d2,0x0004003b, + 0x000000d3,0x000000d4,0x00000000,0x0003001b,0x000000d6,0x000000ce,0x0004003b,0x000000cf, + 0x000000f5,0x00000000,0x0004003b,0x000000d3,0x000000f7,0x00000000,0x0004003b,0x000000cf, + 0x00000117,0x00000000,0x0004003b,0x000000d3,0x00000119,0x00000000,0x00040020,0x0000011c, + 0x00000001,0x0000001d,0x0004003b,0x0000011c,0x0000011d,0x00000001,0x00040020,0x00000127, + 0x00000001,0x00000007,0x0004003b,0x00000127,0x00000128,0x00000001,0x0004003b,0x00000127, + 0x00000139,0x00000001,0x00040015,0x0000013a,0x00000020,0x00000001,0x00040017,0x0000013b, + 0x0000013a,0x00000004,0x0017001e,0x0000013c,0x00000006,0x00000006,0x00000006,0x00000006, + 0x0000003b,0x0000003b,0x0000003b,0x0000003b,0x0000013b,0x0000001d,0x0000001d,0x0000003b, + 0x00000006,0x0000003b,0x00000006,0x00000006,0x0000003b,0x00000006,0x00000006,0x00000006, + 0x0000003b,0x00040020,0x0000013d,0x00000002,0x0000013c,0x0004003b,0x0000013d,0x0000013e, + 0x00000002,0x0004002b,0x0000013a,0x0000013f,0x00000011,0x0004002b,0x0000013a,0x00000140, + 0x00000012,0x00040020,0x00000148,0x00000002,0x00000006,0x00040020,0x00000155,0x00000003, + 0x00000007,0x0004003b,0x00000155,0x00000156,0x00000003,0x0004003b,0x000000d3,0x00000158, + 0x00000000,0x0004003b,0x000000cf,0x00000159,0x00000000,0x00040020,0x0000015a,0x00000001, + 0x00000006,0x0004003b,0x0000015a,0x0000015b,0x00000001,0x0004003b,0x0000015a,0x0000015c, + 0x00000001,0x0004002b,0x00000006,0x00000244,0xc0000000,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x000000ce,0x00000118,0x00000117, + 0x0004003d,0x000000d2,0x0000011a,0x00000119,0x00050056,0x000000d6,0x0000011b,0x00000118, + 0x0000011a,0x0004003d,0x0000001d,0x0000011e,0x0000011d,0x00070058,0x00000007,0x0000011f, + 0x0000011b,0x0000011e,0x00000002,0x0000004f,0x00050051,0x00000006,0x00000120,0x0000011f, + 0x00000000,0x0008000c,0x00000006,0x00000125,0x00000001,0x0000002b,0x00000120,0x0000004f, + 0x00000055,0x0004003d,0x00000007,0x0000012a,0x00000128,0x00050051,0x00000006,0x00000173, + 0x0000012a,0x00000003,0x000500be,0x00000050,0x00000174,0x00000173,0x0000004f,0x000300f7, + 0x000001cc,0x00000000,0x000400fa,0x00000174,0x000001c2,0x00000175,0x000200f8,0x00000175, + 0x000500ba,0x00000050,0x00000178,0x00000173,0x000000a0,0x000300f7,0x000001c1,0x00000000, + 0x000400fa,0x00000178,0x00000192,0x00000179,0x000200f8,0x00000179,0x00050083,0x00000006, + 0x0000017d,0x00000244,0x00000173,0x0004003d,0x000000ce,0x0000017e,0x000000f5,0x0004003d, + 0x000000d2,0x0000017f,0x000000f7,0x00050056,0x000000d6,0x00000180,0x0000017e,0x0000017f, + 0x0007004f,0x0000001d,0x00000182,0x0000012a,0x0000012a,0x00000000,0x00000001,0x00070058, + 0x00000007,0x00000184,0x00000180,0x00000182,0x00000002,0x0000017d,0x00050051,0x00000006, + 0x00000186,0x0000012a,0x00000002,0x00050085,0x00000006,0x00000188,0x00000186,0x00000125, + 0x0008004f,0x00000012,0x000001d2,0x00000184,0x00000184,0x00000000,0x00000001,0x00000002, + 0x00050051,0x00000006,0x000001d4,0x00000184,0x00000003,0x000500b7,0x00000050,0x000001d5, + 0x000001d4,0x0000004f,0x000300f7,0x000001db,0x00000000,0x000400fa,0x000001d5,0x000001d7, + 0x000001d6,0x000200f8,0x000001d6,0x000200f9,0x000001db,0x000200f8,0x000001d7,0x00050088, + 0x00000006,0x000001da,0x00000055,0x000001d4,0x000200f9,0x000001db,0x000200f8,0x000001db, + 0x000700f5,0x00000006,0x0000023c,0x0000004f,0x000001d6,0x000001da,0x000001d7,0x0005008e, + 0x00000012,0x000001dd,0x000001d2,0x0000023c,0x00050085,0x00000006,0x0000018f,0x000001d4, + 0x00000188,0x00050051,0x00000006,0x000001e3,0x000001dd,0x00000000,0x00050051,0x00000006, + 0x000001e5,0x000001dd,0x00000001,0x00050051,0x00000006,0x000001e7,0x000001dd,0x00000002, + 0x00070050,0x00000007,0x00000245,0x000001e3,0x000001e5,0x000001e7,0x0000018f,0x000200f9, + 0x000001c1,0x000200f8,0x00000192,0x00050051,0x00000006,0x00000194,0x0000012a,0x00000002, + 0x000500ba,0x00000050,0x00000195,0x00000194,0x0000004f,0x000300f7,0x0000019d,0x00000000, + 0x000400fa,0x00000195,0x0000019a,0x00000196,0x000200f8,0x00000196,0x0007004f,0x0000001d, + 0x00000198,0x0000012a,0x0000012a,0x00000000,0x00000001,0x0006000c,0x00000006,0x00000199, + 0x00000001,0x00000042,0x00000198,0x000200f9,0x0000019d,0x000200f8,0x0000019a,0x00050051, + 0x00000006,0x0000019c,0x0000012a,0x00000000,0x000200f9,0x0000019d,0x000200f8,0x0000019d, + 0x000700f5,0x00000006,0x00000240,0x00000199,0x00000196,0x0000019c,0x0000019a,0x0008000c, + 0x00000006,0x000001a0,0x00000001,0x0000002b,0x00000240,0x0000004f,0x00000055,0x0006000c, + 0x00000006,0x000001a3,0x00000001,0x00000004,0x00000194,0x000500ba,0x00000050,0x000001a5, + 0x000001a3,0x00000055,0x000300f7,0x000001af,0x00000000,0x000400fa,0x000001a5,0x000001ab, + 0x000001a6,0x000200f8,0x000001a6,0x00050085,0x00000006,0x000001a8,0x000000c4,0x000001a0, + 0x00050081,0x00000006,0x000001aa,0x000001a8,0x000001a3,0x000200f9,0x000001af,0x000200f8, + 0x000001ab,0x00050085,0x00000006,0x000001ad,0x000000be,0x000001a0,0x00050081,0x00000006, + 0x000001ae,0x000001ad,0x000000c1,0x000200f9,0x000001af,0x000200f8,0x000001af,0x000700f5, + 0x00000006,0x00000241,0x000001aa,0x000001a6,0x000001ae,0x000001ab,0x0004007f,0x00000006, + 0x000001b3,0x00000173,0x0004003d,0x000000ce,0x000001b4,0x000000d0,0x0004003d,0x000000d2, + 0x000001b5,0x000000d4,0x00050056,0x000000d6,0x000001b6,0x000001b4,0x000001b5,0x00050050, + 0x0000001d,0x000001b9,0x00000241,0x000001b3,0x00070058,0x00000007,0x000001ba,0x000001b6, + 0x000001b9,0x00000002,0x0000004f,0x00050051,0x00000006,0x000001bd,0x000001ba,0x00000003, + 0x00050085,0x00000006,0x000001be,0x000001bd,0x00000125,0x00060052,0x00000007,0x00000229, + 0x000001be,0x000001ba,0x00000003,0x000200f9,0x000001c1,0x000200f8,0x000001c1,0x000700f5, + 0x00000007,0x00000243,0x00000245,0x000001db,0x00000229,0x000001af,0x000200f9,0x000001cc, + 0x000200f8,0x000001c2,0x00050051,0x00000006,0x000001c8,0x0000012a,0x00000003,0x00050085, + 0x00000006,0x000001c9,0x000001c8,0x00000125,0x00060052,0x00000007,0x0000022c,0x000001c9, + 0x0000012a,0x00000003,0x000200f9,0x000001cc,0x000200f8,0x000001cc,0x000700f5,0x00000007, + 0x00000242,0x00000243,0x000001c1,0x0000022c,0x000001c2,0x00050051,0x00000006,0x0000012f, + 0x00000242,0x00000003,0x0008004f,0x00000012,0x00000131,0x00000242,0x00000242,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x00000012,0x00000132,0x00000131,0x0000012f,0x00050051, + 0x00000006,0x00000134,0x00000132,0x00000000,0x00060052,0x00000007,0x0000022f,0x00000134, + 0x00000242,0x00000000,0x00050051,0x00000006,0x00000136,0x00000132,0x00000001,0x00060052, + 0x00000007,0x00000231,0x00000136,0x0000022f,0x00000001,0x00050051,0x00000006,0x00000138, + 0x00000132,0x00000002,0x00060052,0x00000007,0x00000233,0x00000138,0x00000231,0x00000002, + 0x0008004f,0x00000012,0x00000143,0x00000233,0x00000233,0x00000000,0x00000001,0x00000002, + 0x0004003d,0x00000007,0x00000145,0x00000139,0x00050041,0x00000148,0x00000149,0x0000013e, + 0x0000013f,0x0004003d,0x00000006,0x0000014a,0x00000149,0x00050041,0x00000148,0x0000014c, + 0x0000013e,0x00000140,0x0004003d,0x00000006,0x0000014d,0x0000014c,0x00050051,0x00000006, + 0x00000205,0x00000145,0x00000000,0x00050085,0x00000006,0x00000206,0x0000005f,0x00000205, + 0x00050051,0x00000006,0x00000208,0x00000145,0x00000001,0x00050085,0x00000006,0x00000209, + 0x00000063,0x00000208,0x00050081,0x00000006,0x0000020a,0x00000206,0x00000209,0x0006000c, + 0x00000006,0x0000020b,0x00000001,0x0000000a,0x0000020a,0x00050085,0x00000006,0x0000020d, + 0x0000006a,0x0000020b,0x0006000c,0x00000006,0x0000020e,0x00000001,0x0000000a,0x0000020d, + 0x00050085,0x00000006,0x00000211,0x0000020e,0x0000014a,0x00050081,0x00000006,0x00000213, + 0x00000211,0x0000014d,0x00060050,0x00000012,0x000001fc,0x00000213,0x00000213,0x00000213, + 0x00050081,0x00000012,0x000001fd,0x000001fc,0x00000143,0x00050051,0x00000006,0x00000150, + 0x000001fd,0x00000000,0x00060052,0x00000007,0x00000237,0x00000150,0x00000233,0x00000000, + 0x00050051,0x00000006,0x00000152,0x000001fd,0x00000001,0x00060052,0x00000007,0x00000239, + 0x00000152,0x00000237,0x00000001,0x00050051,0x00000006,0x00000154,0x000001fd,0x00000002, + 0x00060052,0x00000007,0x0000023b,0x00000154,0x00000239,0x00000002,0x0003003e,0x00000156, + 0x0000023b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d43dd51c3d3aef8cac1a5141fa1335e30ccd9c37 GIT binary patch literal 5516 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.h new file mode 100644 index 000000000..2f80fb766 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.h @@ -0,0 +1,209 @@ +#pragma once + +const uint32_t draw_msaa_atlas_blit_webgpu_noclipdistance_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000023b,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000ad,0x000000b5,0x000000b9, + 0x000000f4,0x000000f8,0x00000135,0x000001ac,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x0000007f,0x0000664a,0x00040006,0x0000007f,0x00000000, + 0x00003464,0x00030005,0x00000081,0x0000424c,0x00030005,0x0000009f,0x0000424d,0x00040006, + 0x0000009f,0x00000000,0x00006250,0x00040006,0x0000009f,0x00000001,0x00006359,0x00040006, + 0x0000009f,0x00000002,0x00006552,0x00040006,0x0000009f,0x00000003,0x00006553,0x00040006, + 0x0000009f,0x00000004,0x0000366d,0x00040006,0x0000009f,0x00000005,0x0000676d,0x00040006, + 0x0000009f,0x00000006,0x00006544,0x00040006,0x0000009f,0x00000007,0x00006545,0x00040006, + 0x0000009f,0x00000008,0x00003755,0x00040006,0x0000009f,0x00000009,0x0000676a,0x00040006, + 0x0000009f,0x0000000a,0x0000635a,0x00040006,0x0000009f,0x0000000b,0x00003157,0x00040006, + 0x0000009f,0x0000000c,0x0000676e,0x00040006,0x0000009f,0x0000000d,0x00003559,0x00040006, + 0x0000009f,0x0000000e,0x0000324f,0x00040006,0x0000009f,0x0000000f,0x00006461,0x00040006, + 0x0000009f,0x00000010,0x00006579,0x00040006,0x0000009f,0x00000011,0x00003376,0x00040006, + 0x0000009f,0x00000012,0x00003377,0x00040006,0x0000009f,0x00000013,0x00006462,0x00040006, + 0x0000009f,0x00000014,0x00006767,0x00030005,0x000000a1,0x0000006b,0x00060005,0x000000ad, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x000000b5,0x0000424a,0x00030005, + 0x000000b9,0x00003243,0x00030005,0x000000c7,0x00006576,0x00040006,0x000000c7,0x00000000, + 0x00003464,0x00030005,0x000000c9,0x00004355,0x00030005,0x000000f4,0x00003346,0x00030005, + 0x000000f8,0x00003159,0x00030005,0x00000105,0x00006577,0x00040006,0x00000105,0x00000000, + 0x00003464,0x00030005,0x00000107,0x0000424f,0x00030005,0x00000135,0x0000316b,0x00060005, + 0x000001aa,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x000001aa,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000001aa,0x00000001,0x505f6c67,0x746e696f, + 0x657a6953,0x00000000,0x00070006,0x000001aa,0x00000002,0x435f6c67,0x4470696c,0x61747369, + 0x0065636e,0x00070006,0x000001aa,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e, + 0x00030005,0x000001ac,0x00000000,0x00030005,0x000001b1,0x00004342,0x00030005,0x000001b4, + 0x00004351,0x00030005,0x000001b6,0x0000664b,0x00040006,0x000001b6,0x00000000,0x00003464, + 0x00030005,0x000001b8,0x00004358,0x00030005,0x000001bb,0x00003954,0x00040047,0x0000007e, + 0x00000006,0x00000010,0x00030047,0x0000007f,0x00000003,0x00040048,0x0000007f,0x00000000, + 0x00000018,0x00050048,0x0000007f,0x00000000,0x00000023,0x00000000,0x00030047,0x00000081, + 0x00000018,0x00040047,0x00000081,0x00000021,0x00000003,0x00040047,0x00000081,0x00000022, + 0x00000000,0x00030047,0x0000009f,0x00000002,0x00050048,0x0000009f,0x00000000,0x00000023, + 0x00000000,0x00050048,0x0000009f,0x00000001,0x00000023,0x00000004,0x00050048,0x0000009f, + 0x00000002,0x00000023,0x00000008,0x00050048,0x0000009f,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x0000009f,0x00000004,0x00000023,0x00000010,0x00050048,0x0000009f,0x00000005, + 0x00000023,0x00000014,0x00050048,0x0000009f,0x00000006,0x00000023,0x00000018,0x00050048, + 0x0000009f,0x00000007,0x00000023,0x0000001c,0x00050048,0x0000009f,0x00000008,0x00000023, + 0x00000020,0x00050048,0x0000009f,0x00000009,0x00000023,0x00000030,0x00050048,0x0000009f, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x0000009f,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x0000009f,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000009f,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x0000009f,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x0000009f,0x0000000f,0x00000023,0x00000050,0x00050048,0x0000009f,0x00000010,0x00000023, + 0x00000054,0x00050048,0x0000009f,0x00000011,0x00000023,0x00000058,0x00050048,0x0000009f, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x0000009f,0x00000013,0x00000023,0x00000060, + 0x00050048,0x0000009f,0x00000014,0x00000023,0x00000064,0x00040047,0x000000a1,0x00000021, + 0x00000000,0x00040047,0x000000a1,0x00000022,0x00000000,0x00040047,0x000000ad,0x0000000b, + 0x0000002a,0x00040047,0x000000b5,0x0000001e,0x00000000,0x00040047,0x000000b9,0x0000001e, + 0x00000001,0x00040047,0x000000c6,0x00000006,0x00000008,0x00030047,0x000000c7,0x00000003, + 0x00040048,0x000000c7,0x00000000,0x00000018,0x00050048,0x000000c7,0x00000000,0x00000023, + 0x00000000,0x00030047,0x000000c9,0x00000018,0x00040047,0x000000c9,0x00000021,0x00000004, + 0x00040047,0x000000c9,0x00000022,0x00000000,0x00030047,0x000000f2,0x00000000,0x00030047, + 0x000000f4,0x00000000,0x00030047,0x000000f4,0x0000000e,0x00040047,0x000000f4,0x0000001e, + 0x00000004,0x00030047,0x000000f8,0x00000000,0x00030047,0x000000f8,0x0000000e,0x00040047, + 0x000000f8,0x0000001e,0x00000006,0x00040047,0x00000104,0x00000006,0x00000010,0x00030047, + 0x00000105,0x00000003,0x00040048,0x00000105,0x00000000,0x00000018,0x00050048,0x00000105, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000107,0x00000018,0x00040047,0x00000107, + 0x00000021,0x00000005,0x00040047,0x00000107,0x00000022,0x00000000,0x00040047,0x00000135, + 0x0000001e,0x00000000,0x00030047,0x000001aa,0x00000002,0x00050048,0x000001aa,0x00000000, + 0x0000000b,0x00000000,0x00050048,0x000001aa,0x00000001,0x0000000b,0x00000001,0x00050048, + 0x000001aa,0x00000002,0x0000000b,0x00000003,0x00050048,0x000001aa,0x00000003,0x0000000b, + 0x00000004,0x00040047,0x000001b1,0x00000021,0x00000008,0x00040047,0x000001b1,0x00000022, + 0x00000000,0x00030047,0x000001b4,0x00000000,0x00040047,0x000001b4,0x00000021,0x0000000a, + 0x00040047,0x000001b4,0x00000022,0x00000000,0x00040047,0x000001b5,0x00000006,0x00000010, + 0x00030047,0x000001b6,0x00000003,0x00040048,0x000001b6,0x00000000,0x00000018,0x00050048, + 0x000001b6,0x00000000,0x00000023,0x00000000,0x00030047,0x000001b8,0x00000018,0x00040047, + 0x000001b8,0x00000021,0x00000006,0x00040047,0x000001b8,0x00000022,0x00000000,0x00030047, + 0x000001bb,0x00000000,0x00040047,0x000001bb,0x00000021,0x0000000a,0x00040047,0x000001bb, + 0x00000022,0x00000003,0x00030047,0x0000023a,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00030016,0x0000000c, + 0x00000020,0x00040017,0x0000000d,0x0000000c,0x00000004,0x00040017,0x0000000f,0x0000000c, + 0x00000002,0x00040018,0x00000010,0x0000000f,0x00000002,0x00040017,0x0000002d,0x0000000c, + 0x00000003,0x0004002b,0x0000000c,0x0000003f,0x3f800000,0x0004002b,0x0000000c,0x00000040, + 0x00000000,0x0004002b,0x00000006,0x0000004b,0x00000000,0x00020014,0x0000004c,0x0004002b, + 0x00000006,0x00000053,0x000003ff,0x0004002b,0x00000006,0x00000063,0x00000001,0x0004002b, + 0x0000000c,0x00000070,0x38800000,0x0004002b,0x00000006,0x00000075,0x00000002,0x0004002b, + 0x00000006,0x00000079,0x0000ffff,0x00040017,0x0000007b,0x00000006,0x00000004,0x0003001d, + 0x0000007e,0x0000007b,0x0003001e,0x0000007f,0x0000007e,0x00040020,0x00000080,0x00000002, + 0x0000007f,0x0004003b,0x00000080,0x00000081,0x00000002,0x00040015,0x00000082,0x00000020, + 0x00000001,0x0004002b,0x00000082,0x00000083,0x00000000,0x0004002b,0x00000006,0x00000085, + 0x00000004,0x00040020,0x00000088,0x00000002,0x0000007b,0x00040017,0x00000093,0x00000006, + 0x00000003,0x00040017,0x0000009e,0x00000082,0x00000004,0x0017001e,0x0000009f,0x0000000c, + 0x0000000c,0x0000000c,0x0000000c,0x00000006,0x00000006,0x00000006,0x00000006,0x0000009e, + 0x0000000f,0x0000000f,0x00000006,0x0000000c,0x00000006,0x0000000c,0x0000000c,0x00000006, + 0x0000000c,0x0000000c,0x0000000c,0x00000006,0x00040020,0x000000a0,0x00000002,0x0000009f, + 0x0004003b,0x000000a0,0x000000a1,0x00000002,0x0004002b,0x00000082,0x000000a2,0x00000009, + 0x00040020,0x000000a3,0x00000002,0x0000000f,0x00040020,0x000000ac,0x00000001,0x00000082, + 0x0004003b,0x000000ac,0x000000ad,0x00000001,0x00040020,0x000000b4,0x00000001,0x0000002d, + 0x0004003b,0x000000b4,0x000000b5,0x00000001,0x00040020,0x000000b8,0x00000003,0x0000000f, + 0x0004003b,0x000000b8,0x000000b9,0x00000003,0x00040017,0x000000c3,0x00000006,0x00000002, + 0x0003001d,0x000000c6,0x000000c3,0x0003001e,0x000000c7,0x000000c6,0x00040020,0x000000c8, + 0x00000002,0x000000c7,0x0004003b,0x000000c8,0x000000c9,0x00000002,0x00040020,0x000000cb, + 0x00000002,0x000000c3,0x0004002b,0x00000006,0x000000d1,0x0000000f,0x0004002b,0x00000082, + 0x000000e2,0x00000010,0x0004002b,0x00000082,0x000000e5,0x0000000d,0x00040020,0x000000e9, + 0x00000002,0x00000006,0x00040020,0x000000f3,0x00000003,0x0000000c,0x0004003b,0x000000f3, + 0x000000f4,0x00000003,0x0004003b,0x000000f3,0x000000f8,0x00000003,0x0004002b,0x00000082, + 0x000000fb,0x00000004,0x0003001d,0x00000104,0x0000000d,0x0003001e,0x00000105,0x00000104, + 0x00040020,0x00000106,0x00000002,0x00000105,0x0004003b,0x00000106,0x00000107,0x00000002, + 0x00040020,0x0000010c,0x00000002,0x0000000d,0x0004002b,0x00000006,0x00000113,0x00000003, + 0x00040020,0x00000134,0x00000003,0x0000000d,0x0004003b,0x00000134,0x00000135,0x00000003, + 0x0004002b,0x0000000c,0x0000015c,0x3f666666,0x0004002b,0x0000000c,0x00000160,0x40000000, + 0x0004002b,0x0000000c,0x00000185,0xc0000000,0x0004002b,0x00000082,0x0000018e,0x00000002, + 0x0004002b,0x00000082,0x0000018f,0x00000003,0x00040020,0x00000193,0x00000002,0x0000000c, + 0x0004001c,0x000001a9,0x0000000c,0x00000063,0x0006001e,0x000001aa,0x0000000d,0x0000000c, + 0x000001a9,0x000001a9,0x00040020,0x000001ab,0x00000003,0x000001aa,0x0004003b,0x000001ab, + 0x000001ac,0x00000003,0x00090019,0x000001af,0x00000006,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x000001b0,0x00000000,0x000001af,0x0004003b, + 0x000001b0,0x000001b1,0x00000000,0x00090019,0x000001b2,0x0000000c,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000001b3,0x00000000,0x000001b2, + 0x0004003b,0x000001b3,0x000001b4,0x00000000,0x0003001d,0x000001b5,0x0000007b,0x0003001e, + 0x000001b6,0x000001b5,0x00040020,0x000001b7,0x00000002,0x000001b6,0x0004003b,0x000001b7, + 0x000001b8,0x00000002,0x0002001a,0x000001b9,0x00040020,0x000001ba,0x00000000,0x000001b9, + 0x0004003b,0x000001ba,0x000001bb,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000002d,0x000000bb,0x000000b5,0x00050051, + 0x0000000c,0x000001c3,0x000000bb,0x00000002,0x0004007c,0x00000006,0x000001c4,0x000001c3, + 0x000500c7,0x00000006,0x000001c5,0x000001c4,0x00000079,0x00050084,0x00000006,0x000001c7, + 0x000001c5,0x00000085,0x00050080,0x00000006,0x000001c8,0x000001c7,0x00000075,0x00060041, + 0x00000088,0x000001c9,0x00000081,0x00000083,0x000001c8,0x0004003d,0x0000007b,0x000001ca, + 0x000001c9,0x00050051,0x00000006,0x000001cc,0x000001ca,0x00000000,0x0007004f,0x0000000f, + 0x000001cf,0x000000bb,0x000000bb,0x00000000,0x00000001,0x0008004f,0x00000093,0x000001d1, + 0x000001ca,0x000001ca,0x00000001,0x00000002,0x00000003,0x0004007c,0x0000002d,0x000001d2, + 0x000001d1,0x00050051,0x0000000c,0x000001d5,0x000001d2,0x00000000,0x0005008e,0x0000000f, + 0x000001d6,0x000001cf,0x000001d5,0x0007004f,0x0000000f,0x000001d8,0x000001d2,0x000001d2, + 0x00000001,0x00000002,0x00050081,0x0000000f,0x000001d9,0x000001d6,0x000001d8,0x00050041, + 0x000000a3,0x000001da,0x000000a1,0x000000a2,0x0004003d,0x0000000f,0x000001db,0x000001da, + 0x00050085,0x0000000f,0x000001dc,0x000001d9,0x000001db,0x0003003e,0x000000b9,0x000001dc, + 0x00060041,0x000000cb,0x000000cc,0x000000c9,0x00000083,0x000001c5,0x0004003d,0x000000c3, + 0x000000cd,0x000000cc,0x00050051,0x00000006,0x000000d0,0x000000cd,0x00000000,0x000500c7, + 0x00000006,0x000000d2,0x000000d0,0x000000d1,0x000500aa,0x0000004c,0x000000d8,0x000000d2, + 0x0000004b,0x000300f7,0x000000db,0x00000000,0x000400fa,0x000000d8,0x000000da,0x000000de, + 0x000200f8,0x000000de,0x000200f9,0x000000db,0x000200f8,0x000000da,0x00050051,0x00000006, + 0x000000dd,0x000000cd,0x00000001,0x000200f9,0x000000db,0x000200f8,0x000000db,0x000700f5, + 0x00000006,0x00000238,0x000000d0,0x000000de,0x000000dd,0x000000da,0x000500c2,0x00000006, + 0x000000e3,0x00000238,0x000000e2,0x00050041,0x000000e9,0x000000ea,0x000000a1,0x000000e5, + 0x0004003d,0x00000006,0x000000eb,0x000000ea,0x000500aa,0x0000004c,0x000001e8,0x000000e3, + 0x0000004b,0x000300f7,0x000001f1,0x00000000,0x000400fa,0x000001e8,0x000001f0,0x000001e9, + 0x000200f8,0x000001e9,0x00050080,0x00000006,0x000001eb,0x000000e3,0x00000053,0x00050084, + 0x00000006,0x000001ed,0x000001eb,0x000000eb,0x0006000c,0x0000000f,0x000001ee,0x00000001, + 0x0000003e,0x000001ed,0x00050051,0x0000000c,0x000001ef,0x000001ee,0x00000000,0x000200f9, + 0x000001f1,0x000200f8,0x000001f0,0x000200f9,0x000001f1,0x000200f8,0x000001f1,0x000700f5, + 0x0000000c,0x00000239,0x000001ef,0x000001e9,0x00000040,0x000001f0,0x000300f7,0x000000f0, + 0x00000000,0x000400fa,0x000000d8,0x000000ef,0x000000f0,0x000200f8,0x000000ef,0x0004007f, + 0x0000000c,0x000000f2,0x00000239,0x000200f9,0x000000f0,0x000200f8,0x000000f0,0x000700f5, + 0x0000000c,0x0000023a,0x00000239,0x000001f1,0x000000f2,0x000000ef,0x0003003e,0x000000f4, + 0x0000023a,0x000500c2,0x00000006,0x000000fc,0x000000d0,0x000000fb,0x000500c7,0x00000006, + 0x000000fd,0x000000fc,0x000000d1,0x00040070,0x0000000c,0x000000fe,0x000000fd,0x0003003e, + 0x000000f8,0x000000fe,0x000500aa,0x0000004c,0x00000120,0x000000d2,0x00000063,0x000300f7, + 0x00000122,0x00000000,0x000400fa,0x00000120,0x00000121,0x00000137,0x000200f8,0x00000137, + 0x00060041,0x0000010c,0x0000013c,0x00000107,0x00000083,0x000001c7,0x0004003d,0x0000000d, + 0x0000013d,0x0000013c,0x00050051,0x0000000c,0x00000208,0x0000013d,0x00000000,0x00050051, + 0x0000000c,0x00000209,0x0000013d,0x00000001,0x00050051,0x0000000c,0x0000020a,0x0000013d, + 0x00000002,0x00050051,0x0000000c,0x0000020b,0x0000013d,0x00000003,0x00050050,0x0000000f, + 0x0000020c,0x00000208,0x00000209,0x00050050,0x0000000f,0x0000020d,0x0000020a,0x0000020b, + 0x00050050,0x00000010,0x0000020e,0x0000020c,0x0000020d,0x00050080,0x00000006,0x00000142, + 0x000001c7,0x00000063,0x00060041,0x0000010c,0x00000143,0x00000107,0x00000083,0x00000142, + 0x0004003d,0x0000000d,0x00000144,0x00000143,0x00050091,0x0000000f,0x00000148,0x0000020e, + 0x000001cf,0x0007004f,0x0000000f,0x0000014a,0x00000144,0x00000144,0x00000000,0x00000001, + 0x00050081,0x0000000f,0x0000014b,0x00000148,0x0000014a,0x000500aa,0x0000004c,0x0000014d, + 0x000000d2,0x00000075,0x000500aa,0x0000004c,0x0000014f,0x000000d2,0x00000113,0x000500a6, + 0x0000004c,0x00000150,0x0000014d,0x0000014f,0x000300f7,0x00000152,0x00000000,0x000400fa, + 0x00000150,0x00000151,0x00000178,0x000200f8,0x00000178,0x00050051,0x00000006,0x0000017b, + 0x000000cd,0x00000001,0x0004007c,0x0000000c,0x0000017c,0x0000017b,0x00050051,0x0000000c, + 0x0000017f,0x00000144,0x00000002,0x00050051,0x0000000c,0x00000181,0x0000014b,0x00000000, + 0x00050051,0x0000000c,0x00000183,0x0000014b,0x00000001,0x00050083,0x0000000c,0x00000187, + 0x00000185,0x0000017f,0x00070050,0x0000000d,0x00000188,0x00000181,0x00000183,0x0000017c, + 0x00000187,0x0003003e,0x00000135,0x00000188,0x000200f9,0x00000152,0x000200f8,0x00000151, + 0x00050051,0x00000006,0x00000154,0x000000cd,0x00000001,0x0004007c,0x0000000c,0x00000155, + 0x00000154,0x0004007f,0x0000000c,0x00000156,0x00000155,0x00050041,0x000000f3,0x00000157, + 0x00000135,0x00000113,0x0003003e,0x00000157,0x00000156,0x00050051,0x0000000c,0x0000015a, + 0x00000144,0x00000002,0x000500ba,0x0000004c,0x0000015d,0x0000015a,0x0000015c,0x000300f7, + 0x0000015f,0x00000000,0x000400fa,0x0000015d,0x0000015e,0x00000162,0x000200f8,0x00000162, + 0x00050051,0x0000000c,0x00000164,0x00000144,0x00000003,0x00050041,0x000000f3,0x00000165, + 0x00000135,0x00000075,0x0003003e,0x00000165,0x00000164,0x000200f9,0x0000015f,0x000200f8, + 0x0000015e,0x00050041,0x000000f3,0x00000161,0x00000135,0x00000075,0x0003003e,0x00000161, + 0x00000160,0x000200f9,0x0000015f,0x000200f8,0x0000015f,0x000300f7,0x00000169,0x00000000, + 0x000400fa,0x0000014d,0x00000168,0x0000016e,0x000200f8,0x0000016e,0x00050041,0x000000f3, + 0x0000016f,0x00000135,0x00000075,0x0004003d,0x0000000c,0x00000170,0x0000016f,0x0004007f, + 0x0000000c,0x00000171,0x00000170,0x0003003e,0x0000016f,0x00000171,0x00050041,0x000000f3, + 0x00000174,0x00000135,0x0000004b,0x00050051,0x0000000c,0x00000175,0x0000014b,0x00000000, + 0x0003003e,0x00000174,0x00000175,0x00050041,0x000000f3,0x00000176,0x00000135,0x00000063, + 0x00050051,0x0000000c,0x00000177,0x0000014b,0x00000001,0x0003003e,0x00000176,0x00000177, + 0x000200f9,0x00000169,0x000200f8,0x00000168,0x00050041,0x000000f3,0x0000016a,0x00000135, + 0x00000063,0x0003003e,0x0000016a,0x00000040,0x00050051,0x0000000c,0x0000016c,0x0000014b, + 0x00000000,0x00050041,0x000000f3,0x0000016d,0x00000135,0x0000004b,0x0003003e,0x0000016d, + 0x0000016c,0x000200f9,0x00000169,0x000200f8,0x00000169,0x000200f9,0x00000152,0x000200f8, + 0x00000152,0x000200f9,0x00000122,0x000200f8,0x00000121,0x00050051,0x00000006,0x00000125, + 0x000000cd,0x00000001,0x0006000c,0x0000000d,0x00000126,0x00000001,0x00000040,0x00000125, + 0x0003003e,0x00000135,0x00000126,0x000200f9,0x00000122,0x000200f8,0x00000122,0x00050041, + 0x00000193,0x00000194,0x000000a1,0x0000018e,0x0004003d,0x0000000c,0x00000195,0x00000194, + 0x00050041,0x00000193,0x00000197,0x000000a1,0x0000018f,0x0004003d,0x0000000c,0x00000198, + 0x00000197,0x00050051,0x0000000c,0x00000212,0x000000bb,0x00000000,0x00050085,0x0000000c, + 0x00000214,0x00000212,0x00000195,0x00050083,0x0000000c,0x00000215,0x00000214,0x0000003f, + 0x00050051,0x0000000c,0x00000217,0x000000bb,0x00000001,0x00050085,0x0000000c,0x00000219, + 0x00000217,0x00000198,0x0006000c,0x0000000c,0x0000021b,0x00000001,0x00000006,0x00000198, + 0x00050083,0x0000000c,0x0000021c,0x00000219,0x0000021b,0x00070050,0x0000000d,0x0000021d, + 0x00000215,0x0000021c,0x00000040,0x0000003f,0x00040070,0x0000000c,0x00000221,0x000001cc, + 0x00050085,0x0000000c,0x00000222,0x00000221,0x00000070,0x00050083,0x0000000c,0x00000223, + 0x0000003f,0x00000222,0x00060052,0x0000000d,0x00000237,0x00000223,0x0000021d,0x00000002, + 0x00050041,0x00000134,0x000001ae,0x000001ac,0x00000083,0x0003003e,0x000001ae,0x00000237, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d15e550db77c843904b9a79cb8b6041b993a26ba GIT binary patch literal 6536 zcmZ9PX^fp^702Js*3yloML##Iy&i(YcG+UhO zE&M&)U#SVcfjo*lj{F0;fUL#&4ARU$hj|9QC0m$vb(c2o+Eg09qkpJ8RvMoe8S6h- zE)7f$4+BRA4wVNd@LQzc*1fw+?IaV$WPu2z}DkHUV(nij% zo}RAmt);=yQF0!ymP^%2ty~(ajFGQ$q^#cpb0)t^ZLm5yRCH*?qd2El>OMjK?ZX+X z(vs_rH?$_pv`wLRZ>sALpx=V7pSrDgpn;iswr{Y3U5{PV6#lMmUjgTJ+|aPMVn2Ma zf!n}a3jS)zP(V-BJgb=X!yIswSxZ=@V>PT`%-Yv2OIcO zaQ{#PUj{y2sONIpst*n;k>|nKYYk7>L@bTJE z`B>e@v$s9%g=cUxwHbRJ-Mx36)ornVPowYIT=(_b)N4{cJJ&;#HPRZRy;4^C+S^#*VXgj z{cT1(YjKxjPXb$yO@HsVc5|y+n|mI(QCoBNH+Y+Iz6G|>U0-A5t*@S={!RdMzYFx? zr>>v18`r{w)Lnmb`i{gr;!TNp1TN0QcP8ec-a#JEskz0Cd9>u;xs5e#&fk_Md_8;d z{1C_v*tsAa#d=+Lp_|irTuXKL(95kv zKS3{U$9j_99C9}$Je4@t>NDu=NYo*oMr<+e47%f(?_PTIIhN~ln%+8GAMuyz&7uEF zmwI?mapJvEso*b#IuN;wOhx7i0{4r57BFL9Pt_Yd5C_- zi~TJlr~Q$ndj_^3 z^sb4Vabn+Nxp(sSadiEjptp(j6URG!1K(ZxdnRnI#|4;H`kP^|qd$vyUv|PemvhF` z8+SK8uF;R-Rr(&uxkkPt z&mg`nu90hMo^$9wN3_KnJ)1bXxxINFUEa6nVaDsGe*uyAJMUkN_Y%GBKjhW+BJw-L zvtj>ldVR#&V!Yp?TLUG%#Yf+NvPbUQdKTXC&7;5ZKcWt8zelvcOz(R6=KTqoMSKgL zr+%*@@=^aE8PM3M|F0H6vwm%_Bd;LVYai$DRdnO}kT|D*hLd-U#f;|u`~}R1y~r}{ zaYkN4*Jg7~9M>@%uZZQHzxU@x=4YIBbb|GD&0j~i#hSl{E@wXV6U@bUe@~mk{9(6` z{Qj=e?wI-->lyO9L0hc#f5FcpZy<4R-$a-9Y>cMy{)aAa4!=*tvF`1R;kg+^oWm-x z%{gf6K-MA7!QS)h_s2&Nzf-31_5QoBOVDplwpiZ<)GKET?vlhw2e&YBbaULI#5Ke9 zrhBy*&Yb25ZV9^a`paF0|59{)wZ&Q4#DLc7Tw@-a!7&f*F^?_i+U`%|ZbLVxZ%4cv z+tKw?Y;M>}PptJV=&rSIWpF)-^ZWO!jOAVKMb}rGd$Nn(=ALNVi5x@R6MNUt zJ9QU&++E*9&)VH^^0Ce*(5;uL%yCm->$Qd7bmF9^$#1UD0cH?$^l}&6?|adW*Wa=9 z@tm!t*X9|wervVvsC75`+iTqeCm;9ZR&+Vv5q}%qhHhTh$}z~L zRp@Qj<=)?c)DUypN6r!S$mv;iUq<2NW8FT5E@zGM;)tI>H{N$P<~k`xY{uv#7cocB zjq%<@%u%p0eDWB5*^5GiEPd zMQ;rq^w#YCcsF{SIlmV?zwd$Llh>l%aja9mn8$q9b(;S3$Sg6Z=wlDQkofTVV)D7K z;PWMP`B=j%xP)iPWAk@|d$}A=-h6TIt^~_(z#g$zfsMs&F7_HYdB<^n=6e@dALlP0 zIak2zuRZSawdjtetrLI8i|>#QIDfB2ovXldqxeM5)nH?^?Mmyr4qe{deDXD1L!NIU RXYzXLYcAIJO{!gw{2%MVgAM=y literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.h new file mode 100644 index 000000000..60a3f2c9c --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.h @@ -0,0 +1,239 @@ +#pragma once + +const uint32_t draw_msaa_atlas_blit_webgpu_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000295,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000020,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000c000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000008c, + 0x000000e1,0x000000e9,0x000000ed,0x00000127,0x0000012b,0x00000168,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000008a,0x505f6c67,0x65567265, + 0x78657472,0x00000000,0x00060006,0x0000008a,0x00000000,0x505f6c67,0x7469736f,0x006e6f69, + 0x00070006,0x0000008a,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006, + 0x0000008a,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000008a, + 0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x0000008c,0x00000000, + 0x00030005,0x000000b6,0x0000664a,0x00040006,0x000000b6,0x00000000,0x00003464,0x00030005, + 0x000000b8,0x0000424c,0x00030005,0x000000d3,0x0000424d,0x00040006,0x000000d3,0x00000000, + 0x00006250,0x00040006,0x000000d3,0x00000001,0x00006359,0x00040006,0x000000d3,0x00000002, + 0x00006552,0x00040006,0x000000d3,0x00000003,0x00006553,0x00040006,0x000000d3,0x00000004, + 0x0000366d,0x00040006,0x000000d3,0x00000005,0x0000676d,0x00040006,0x000000d3,0x00000006, + 0x00006544,0x00040006,0x000000d3,0x00000007,0x00006545,0x00040006,0x000000d3,0x00000008, + 0x00003755,0x00040006,0x000000d3,0x00000009,0x0000676a,0x00040006,0x000000d3,0x0000000a, + 0x0000635a,0x00040006,0x000000d3,0x0000000b,0x00003157,0x00040006,0x000000d3,0x0000000c, + 0x0000676e,0x00040006,0x000000d3,0x0000000d,0x00003559,0x00040006,0x000000d3,0x0000000e, + 0x0000324f,0x00040006,0x000000d3,0x0000000f,0x00006461,0x00040006,0x000000d3,0x00000010, + 0x00006579,0x00040006,0x000000d3,0x00000011,0x00003376,0x00040006,0x000000d3,0x00000012, + 0x00003377,0x00040006,0x000000d3,0x00000013,0x00006462,0x00040006,0x000000d3,0x00000014, + 0x00006767,0x00030005,0x000000d5,0x0000006b,0x00060005,0x000000e1,0x565f6c67,0x65747265, + 0x646e4978,0x00007865,0x00030005,0x000000e9,0x0000424a,0x00030005,0x000000ed,0x00003243, + 0x00030005,0x000000fb,0x00006576,0x00040006,0x000000fb,0x00000000,0x00003464,0x00030005, + 0x000000fd,0x00004355,0x00030005,0x00000127,0x00003346,0x00030005,0x0000012b,0x00003159, + 0x00030005,0x00000138,0x00006577,0x00040006,0x00000138,0x00000000,0x00003464,0x00030005, + 0x0000013a,0x0000424f,0x00030005,0x00000168,0x0000316b,0x00030005,0x000001de,0x00004342, + 0x00030005,0x000001e1,0x00004351,0x00030005,0x000001e3,0x0000664b,0x00040006,0x000001e3, + 0x00000000,0x00003464,0x00030005,0x000001e5,0x00004358,0x00030005,0x000001e8,0x00003954, + 0x00030047,0x0000008a,0x00000002,0x00050048,0x0000008a,0x00000000,0x0000000b,0x00000000, + 0x00050048,0x0000008a,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000008a,0x00000002, + 0x0000000b,0x00000003,0x00050048,0x0000008a,0x00000003,0x0000000b,0x00000004,0x00040047, + 0x000000b5,0x00000006,0x00000010,0x00030047,0x000000b6,0x00000003,0x00040048,0x000000b6, + 0x00000000,0x00000018,0x00050048,0x000000b6,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000b8,0x00000018,0x00040047,0x000000b8,0x00000021,0x00000003,0x00040047,0x000000b8, + 0x00000022,0x00000000,0x00030047,0x000000d3,0x00000002,0x00050048,0x000000d3,0x00000000, + 0x00000023,0x00000000,0x00050048,0x000000d3,0x00000001,0x00000023,0x00000004,0x00050048, + 0x000000d3,0x00000002,0x00000023,0x00000008,0x00050048,0x000000d3,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x000000d3,0x00000004,0x00000023,0x00000010,0x00050048,0x000000d3, + 0x00000005,0x00000023,0x00000014,0x00050048,0x000000d3,0x00000006,0x00000023,0x00000018, + 0x00050048,0x000000d3,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000d3,0x00000008, + 0x00000023,0x00000020,0x00050048,0x000000d3,0x00000009,0x00000023,0x00000030,0x00050048, + 0x000000d3,0x0000000a,0x00000023,0x00000038,0x00050048,0x000000d3,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x000000d3,0x0000000c,0x00000023,0x00000044,0x00050048,0x000000d3, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x000000d3,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x000000d3,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000d3,0x00000010, + 0x00000023,0x00000054,0x00050048,0x000000d3,0x00000011,0x00000023,0x00000058,0x00050048, + 0x000000d3,0x00000012,0x00000023,0x0000005c,0x00050048,0x000000d3,0x00000013,0x00000023, + 0x00000060,0x00050048,0x000000d3,0x00000014,0x00000023,0x00000064,0x00040047,0x000000d5, + 0x00000021,0x00000000,0x00040047,0x000000d5,0x00000022,0x00000000,0x00040047,0x000000e1, + 0x0000000b,0x0000002a,0x00040047,0x000000e9,0x0000001e,0x00000000,0x00040047,0x000000ed, + 0x0000001e,0x00000001,0x00040047,0x000000fa,0x00000006,0x00000008,0x00030047,0x000000fb, + 0x00000003,0x00040048,0x000000fb,0x00000000,0x00000018,0x00050048,0x000000fb,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000000fd,0x00000018,0x00040047,0x000000fd,0x00000021, + 0x00000004,0x00040047,0x000000fd,0x00000022,0x00000000,0x00030047,0x00000126,0x00000000, + 0x00030047,0x00000127,0x00000000,0x00030047,0x00000127,0x0000000e,0x00040047,0x00000127, + 0x0000001e,0x00000004,0x00030047,0x0000012b,0x00000000,0x00030047,0x0000012b,0x0000000e, + 0x00040047,0x0000012b,0x0000001e,0x00000006,0x00040047,0x00000137,0x00000006,0x00000010, + 0x00030047,0x00000138,0x00000003,0x00040048,0x00000138,0x00000000,0x00000018,0x00050048, + 0x00000138,0x00000000,0x00000023,0x00000000,0x00030047,0x0000013a,0x00000018,0x00040047, + 0x0000013a,0x00000021,0x00000005,0x00040047,0x0000013a,0x00000022,0x00000000,0x00040047, + 0x00000168,0x0000001e,0x00000000,0x00040047,0x000001de,0x00000021,0x00000008,0x00040047, + 0x000001de,0x00000022,0x00000000,0x00030047,0x000001e1,0x00000000,0x00040047,0x000001e1, + 0x00000021,0x0000000a,0x00040047,0x000001e1,0x00000022,0x00000000,0x00040047,0x000001e2, + 0x00000006,0x00000010,0x00030047,0x000001e3,0x00000003,0x00040048,0x000001e3,0x00000000, + 0x00000018,0x00050048,0x000001e3,0x00000000,0x00000023,0x00000000,0x00030047,0x000001e5, + 0x00000018,0x00040047,0x000001e5,0x00000021,0x00000006,0x00040047,0x000001e5,0x00000022, + 0x00000000,0x00030047,0x000001e8,0x00000000,0x00040047,0x000001e8,0x00000021,0x0000000a, + 0x00040047,0x000001e8,0x00000022,0x00000003,0x00030047,0x00000294,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000, + 0x00030016,0x0000000c,0x00000020,0x00040017,0x0000000d,0x0000000c,0x00000004,0x00040017, + 0x0000000f,0x0000000c,0x00000002,0x00040018,0x00000010,0x0000000f,0x00000002,0x00040017, + 0x0000002d,0x0000000c,0x00000003,0x0004002b,0x0000000c,0x0000003f,0x3f800000,0x0004002b, + 0x0000000c,0x00000040,0x00000000,0x0004002b,0x00000006,0x0000004b,0x00000000,0x00020014, + 0x0000004c,0x0004002b,0x00000006,0x00000053,0x000003ff,0x0004002b,0x00000006,0x00000063, + 0x00000001,0x0004002b,0x0000000c,0x00000070,0x38800000,0x0007002c,0x0000000d,0x0000007b, + 0x00000040,0x00000040,0x00000040,0x00000040,0x00040017,0x0000007c,0x0000004c,0x00000004, + 0x0004002b,0x00000006,0x00000087,0x00000004,0x0004001c,0x00000088,0x0000000c,0x00000087, + 0x0004001c,0x00000089,0x0000000c,0x00000063,0x0006001e,0x0000008a,0x0000000d,0x0000000c, + 0x00000088,0x00000089,0x00040020,0x0000008b,0x00000003,0x0000008a,0x0004003b,0x0000008b, + 0x0000008c,0x00000003,0x00040015,0x0000008d,0x00000020,0x00000001,0x0004002b,0x0000008d, + 0x0000008e,0x00000002,0x0004002b,0x0000008d,0x0000008f,0x00000000,0x00040020,0x00000093, + 0x00000003,0x0000000c,0x0004002b,0x0000008d,0x00000095,0x00000001,0x0004002b,0x0000008d, + 0x0000009e,0x00000003,0x0004002b,0x0000000c,0x000000a6,0x3f000000,0x0004002b,0x00000006, + 0x000000ac,0x00000002,0x0004002b,0x00000006,0x000000b0,0x0000ffff,0x00040017,0x000000b2, + 0x00000006,0x00000004,0x0003001d,0x000000b5,0x000000b2,0x0003001e,0x000000b6,0x000000b5, + 0x00040020,0x000000b7,0x00000002,0x000000b6,0x0004003b,0x000000b7,0x000000b8,0x00000002, + 0x00040020,0x000000bc,0x00000002,0x000000b2,0x00040017,0x000000c7,0x00000006,0x00000003, + 0x00040017,0x000000d2,0x0000008d,0x00000004,0x0017001e,0x000000d3,0x0000000c,0x0000000c, + 0x0000000c,0x0000000c,0x00000006,0x00000006,0x00000006,0x00000006,0x000000d2,0x0000000f, + 0x0000000f,0x00000006,0x0000000c,0x00000006,0x0000000c,0x0000000c,0x00000006,0x0000000c, + 0x0000000c,0x0000000c,0x00000006,0x00040020,0x000000d4,0x00000002,0x000000d3,0x0004003b, + 0x000000d4,0x000000d5,0x00000002,0x0004002b,0x0000008d,0x000000d6,0x00000009,0x00040020, + 0x000000d7,0x00000002,0x0000000f,0x00040020,0x000000e0,0x00000001,0x0000008d,0x0004003b, + 0x000000e0,0x000000e1,0x00000001,0x00040020,0x000000e8,0x00000001,0x0000002d,0x0004003b, + 0x000000e8,0x000000e9,0x00000001,0x00040020,0x000000ec,0x00000003,0x0000000f,0x0004003b, + 0x000000ec,0x000000ed,0x00000003,0x00040017,0x000000f7,0x00000006,0x00000002,0x0003001d, + 0x000000fa,0x000000f7,0x0003001e,0x000000fb,0x000000fa,0x00040020,0x000000fc,0x00000002, + 0x000000fb,0x0004003b,0x000000fc,0x000000fd,0x00000002,0x00040020,0x000000ff,0x00000002, + 0x000000f7,0x0004002b,0x00000006,0x00000105,0x0000000f,0x0004002b,0x0000008d,0x00000116, + 0x00000010,0x0004002b,0x0000008d,0x00000119,0x0000000d,0x00040020,0x0000011d,0x00000002, + 0x00000006,0x0004003b,0x00000093,0x00000127,0x00000003,0x0004003b,0x00000093,0x0000012b, + 0x00000003,0x0004002b,0x0000008d,0x0000012e,0x00000004,0x0003001d,0x00000137,0x0000000d, + 0x0003001e,0x00000138,0x00000137,0x00040020,0x00000139,0x00000002,0x00000138,0x0004003b, + 0x00000139,0x0000013a,0x00000002,0x00040020,0x0000013f,0x00000002,0x0000000d,0x0004002b, + 0x00000006,0x00000146,0x00000003,0x00040020,0x00000167,0x00000003,0x0000000d,0x0004003b, + 0x00000167,0x00000168,0x00000003,0x0004002b,0x0000000c,0x0000018f,0x3f666666,0x0004002b, + 0x0000000c,0x00000193,0x40000000,0x0004002b,0x0000000c,0x000001b8,0xc0000000,0x00040020, + 0x000001c4,0x00000002,0x0000000c,0x00090019,0x000001dc,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000001dd,0x00000000,0x000001dc, + 0x0004003b,0x000001dd,0x000001de,0x00000000,0x00090019,0x000001df,0x0000000c,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000001e0,0x00000000, + 0x000001df,0x0004003b,0x000001e0,0x000001e1,0x00000000,0x0003001d,0x000001e2,0x000000b2, + 0x0003001e,0x000001e3,0x000001e2,0x00040020,0x000001e4,0x00000002,0x000001e3,0x0004003b, + 0x000001e4,0x000001e5,0x00000002,0x0002001a,0x000001e6,0x00040020,0x000001e7,0x00000000, + 0x000001e6,0x0004003b,0x000001e7,0x000001e8,0x00000000,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000002d,0x000000ef,0x000000e9, + 0x00050051,0x0000000c,0x000001f0,0x000000ef,0x00000002,0x0004007c,0x00000006,0x000001f1, + 0x000001f0,0x000500c7,0x00000006,0x000001f2,0x000001f1,0x000000b0,0x00050084,0x00000006, + 0x000001f4,0x000001f2,0x00000087,0x00050080,0x00000006,0x000001f5,0x000001f4,0x000000ac, + 0x00060041,0x000000bc,0x000001f6,0x000000b8,0x0000008f,0x000001f5,0x0004003d,0x000000b2, + 0x000001f7,0x000001f6,0x00050051,0x00000006,0x000001f9,0x000001f7,0x00000000,0x0007004f, + 0x0000000f,0x000001fc,0x000000ef,0x000000ef,0x00000000,0x00000001,0x0008004f,0x000000c7, + 0x000001fe,0x000001f7,0x000001f7,0x00000001,0x00000002,0x00000003,0x0004007c,0x0000002d, + 0x000001ff,0x000001fe,0x00050051,0x0000000c,0x00000202,0x000001ff,0x00000000,0x0005008e, + 0x0000000f,0x00000203,0x000001fc,0x00000202,0x0007004f,0x0000000f,0x00000205,0x000001ff, + 0x000001ff,0x00000001,0x00000002,0x00050081,0x0000000f,0x00000206,0x00000203,0x00000205, + 0x00050041,0x000000d7,0x00000207,0x000000d5,0x000000d6,0x0004003d,0x0000000f,0x00000208, + 0x00000207,0x00050085,0x0000000f,0x00000209,0x00000206,0x00000208,0x0003003e,0x000000ed, + 0x00000209,0x00060041,0x000000ff,0x00000100,0x000000fd,0x0000008f,0x000001f2,0x0004003d, + 0x000000f7,0x00000101,0x00000100,0x00050051,0x00000006,0x00000104,0x00000101,0x00000000, + 0x000500c7,0x00000006,0x00000106,0x00000104,0x00000105,0x000500aa,0x0000004c,0x0000010c, + 0x00000106,0x0000004b,0x000300f7,0x0000010f,0x00000000,0x000400fa,0x0000010c,0x0000010e, + 0x00000112,0x000200f8,0x00000112,0x000200f9,0x0000010f,0x000200f8,0x0000010e,0x00050051, + 0x00000006,0x00000111,0x00000101,0x00000001,0x000200f9,0x0000010f,0x000200f8,0x0000010f, + 0x000700f5,0x00000006,0x00000292,0x00000104,0x00000112,0x00000111,0x0000010e,0x000500c2, + 0x00000006,0x00000117,0x00000292,0x00000116,0x00050041,0x0000011d,0x0000011e,0x000000d5, + 0x00000119,0x0004003d,0x00000006,0x0000011f,0x0000011e,0x000500aa,0x0000004c,0x00000215, + 0x00000117,0x0000004b,0x000300f7,0x0000021e,0x00000000,0x000400fa,0x00000215,0x0000021d, + 0x00000216,0x000200f8,0x00000216,0x00050080,0x00000006,0x00000218,0x00000117,0x00000053, + 0x00050084,0x00000006,0x0000021a,0x00000218,0x0000011f,0x0006000c,0x0000000f,0x0000021b, + 0x00000001,0x0000003e,0x0000021a,0x00050051,0x0000000c,0x0000021c,0x0000021b,0x00000000, + 0x000200f9,0x0000021e,0x000200f8,0x0000021d,0x000200f9,0x0000021e,0x000200f8,0x0000021e, + 0x000700f5,0x0000000c,0x00000293,0x0000021c,0x00000216,0x00000040,0x0000021d,0x000300f7, + 0x00000124,0x00000000,0x000400fa,0x0000010c,0x00000123,0x00000124,0x000200f8,0x00000123, + 0x0004007f,0x0000000c,0x00000126,0x00000293,0x000200f9,0x00000124,0x000200f8,0x00000124, + 0x000700f5,0x0000000c,0x00000294,0x00000293,0x0000021e,0x00000126,0x00000123,0x0003003e, + 0x00000127,0x00000294,0x000500c2,0x00000006,0x0000012f,0x00000104,0x0000012e,0x000500c7, + 0x00000006,0x00000130,0x0000012f,0x00000105,0x00040070,0x0000000c,0x00000131,0x00000130, + 0x0003003e,0x0000012b,0x00000131,0x00060041,0x0000013f,0x00000140,0x0000013a,0x0000008f, + 0x000001f5,0x0004003d,0x0000000d,0x00000141,0x00000140,0x00050051,0x0000000c,0x00000227, + 0x00000141,0x00000000,0x00050051,0x0000000c,0x00000228,0x00000141,0x00000001,0x00050051, + 0x0000000c,0x00000229,0x00000141,0x00000002,0x00050051,0x0000000c,0x0000022a,0x00000141, + 0x00000003,0x00050050,0x0000000f,0x0000022b,0x00000227,0x00000228,0x00050050,0x0000000f, + 0x0000022c,0x00000229,0x0000022a,0x00050050,0x00000010,0x0000022d,0x0000022b,0x0000022c, + 0x00050080,0x00000006,0x00000147,0x000001f4,0x00000146,0x00060041,0x0000013f,0x00000148, + 0x0000013a,0x0000008f,0x00000147,0x0004003d,0x0000000d,0x00000149,0x00000148,0x0007004f, + 0x0000000f,0x0000014e,0x00000149,0x00000149,0x00000000,0x00000001,0x000500b7,0x0000007c, + 0x00000236,0x00000141,0x0000007b,0x0004009a,0x0000004c,0x00000237,0x00000236,0x000300f7, + 0x00000256,0x00000000,0x000400fa,0x00000237,0x00000240,0x00000238,0x000200f8,0x00000238, + 0x00050051,0x0000000c,0x0000023a,0x00000149,0x00000000,0x00050083,0x0000000c,0x0000023b, + 0x0000023a,0x000000a6,0x00060041,0x00000093,0x0000023c,0x0000008c,0x0000008e,0x0000009e, + 0x0003003e,0x0000023c,0x0000023b,0x00060041,0x00000093,0x0000023d,0x0000008c,0x0000008e, + 0x0000008e,0x0003003e,0x0000023d,0x0000023b,0x00060041,0x00000093,0x0000023e,0x0000008c, + 0x0000008e,0x00000095,0x0003003e,0x0000023e,0x0000023b,0x00060041,0x00000093,0x0000023f, + 0x0000008c,0x0000008e,0x0000008f,0x0003003e,0x0000023f,0x0000023b,0x000200f9,0x00000256, + 0x000200f8,0x00000240,0x00050091,0x0000000f,0x00000243,0x0000022d,0x000001fc,0x00050081, + 0x0000000f,0x00000245,0x00000243,0x0000014e,0x00050051,0x0000000c,0x00000247,0x00000245, + 0x00000000,0x00050081,0x0000000c,0x00000248,0x00000247,0x0000003f,0x00060041,0x00000093, + 0x00000249,0x0000008c,0x0000008e,0x0000008f,0x0003003e,0x00000249,0x00000248,0x00050051, + 0x0000000c,0x0000024b,0x00000245,0x00000001,0x00050081,0x0000000c,0x0000024c,0x0000024b, + 0x0000003f,0x00060041,0x00000093,0x0000024d,0x0000008c,0x0000008e,0x00000095,0x0003003e, + 0x0000024d,0x0000024c,0x00050083,0x0000000c,0x00000250,0x0000003f,0x00000247,0x00060041, + 0x00000093,0x00000251,0x0000008c,0x0000008e,0x0000008e,0x0003003e,0x00000251,0x00000250, + 0x00050083,0x0000000c,0x00000254,0x0000003f,0x0000024b,0x00060041,0x00000093,0x00000255, + 0x0000008c,0x0000008e,0x0000009e,0x0003003e,0x00000255,0x00000254,0x000200f9,0x00000256, + 0x000200f8,0x00000256,0x000500aa,0x0000004c,0x00000153,0x00000106,0x00000063,0x000300f7, + 0x00000155,0x00000000,0x000400fa,0x00000153,0x00000154,0x0000016a,0x000200f8,0x0000016a, + 0x00060041,0x0000013f,0x0000016f,0x0000013a,0x0000008f,0x000001f4,0x0004003d,0x0000000d, + 0x00000170,0x0000016f,0x00050051,0x0000000c,0x0000025d,0x00000170,0x00000000,0x00050051, + 0x0000000c,0x0000025e,0x00000170,0x00000001,0x00050051,0x0000000c,0x0000025f,0x00000170, + 0x00000002,0x00050051,0x0000000c,0x00000260,0x00000170,0x00000003,0x00050050,0x0000000f, + 0x00000261,0x0000025d,0x0000025e,0x00050050,0x0000000f,0x00000262,0x0000025f,0x00000260, + 0x00050050,0x00000010,0x00000263,0x00000261,0x00000262,0x00050080,0x00000006,0x00000175, + 0x000001f4,0x00000063,0x00060041,0x0000013f,0x00000176,0x0000013a,0x0000008f,0x00000175, + 0x0004003d,0x0000000d,0x00000177,0x00000176,0x00050091,0x0000000f,0x0000017b,0x00000263, + 0x000001fc,0x0007004f,0x0000000f,0x0000017d,0x00000177,0x00000177,0x00000000,0x00000001, + 0x00050081,0x0000000f,0x0000017e,0x0000017b,0x0000017d,0x000500aa,0x0000004c,0x00000180, + 0x00000106,0x000000ac,0x000500aa,0x0000004c,0x00000182,0x00000106,0x00000146,0x000500a6, + 0x0000004c,0x00000183,0x00000180,0x00000182,0x000300f7,0x00000185,0x00000000,0x000400fa, + 0x00000183,0x00000184,0x000001ab,0x000200f8,0x000001ab,0x00050051,0x00000006,0x000001ae, + 0x00000101,0x00000001,0x0004007c,0x0000000c,0x000001af,0x000001ae,0x00050051,0x0000000c, + 0x000001b2,0x00000177,0x00000002,0x00050051,0x0000000c,0x000001b4,0x0000017e,0x00000000, + 0x00050051,0x0000000c,0x000001b6,0x0000017e,0x00000001,0x00050083,0x0000000c,0x000001ba, + 0x000001b8,0x000001b2,0x00070050,0x0000000d,0x000001bb,0x000001b4,0x000001b6,0x000001af, + 0x000001ba,0x0003003e,0x00000168,0x000001bb,0x000200f9,0x00000185,0x000200f8,0x00000184, + 0x00050051,0x00000006,0x00000187,0x00000101,0x00000001,0x0004007c,0x0000000c,0x00000188, + 0x00000187,0x0004007f,0x0000000c,0x00000189,0x00000188,0x00050041,0x00000093,0x0000018a, + 0x00000168,0x00000146,0x0003003e,0x0000018a,0x00000189,0x00050051,0x0000000c,0x0000018d, + 0x00000177,0x00000002,0x000500ba,0x0000004c,0x00000190,0x0000018d,0x0000018f,0x000300f7, + 0x00000192,0x00000000,0x000400fa,0x00000190,0x00000191,0x00000195,0x000200f8,0x00000195, + 0x00050051,0x0000000c,0x00000197,0x00000177,0x00000003,0x00050041,0x00000093,0x00000198, + 0x00000168,0x000000ac,0x0003003e,0x00000198,0x00000197,0x000200f9,0x00000192,0x000200f8, + 0x00000191,0x00050041,0x00000093,0x00000194,0x00000168,0x000000ac,0x0003003e,0x00000194, + 0x00000193,0x000200f9,0x00000192,0x000200f8,0x00000192,0x000300f7,0x0000019c,0x00000000, + 0x000400fa,0x00000180,0x0000019b,0x000001a1,0x000200f8,0x000001a1,0x00050041,0x00000093, + 0x000001a2,0x00000168,0x000000ac,0x0004003d,0x0000000c,0x000001a3,0x000001a2,0x0004007f, + 0x0000000c,0x000001a4,0x000001a3,0x0003003e,0x000001a2,0x000001a4,0x00050041,0x00000093, + 0x000001a7,0x00000168,0x0000004b,0x00050051,0x0000000c,0x000001a8,0x0000017e,0x00000000, + 0x0003003e,0x000001a7,0x000001a8,0x00050041,0x00000093,0x000001a9,0x00000168,0x00000063, + 0x00050051,0x0000000c,0x000001aa,0x0000017e,0x00000001,0x0003003e,0x000001a9,0x000001aa, + 0x000200f9,0x0000019c,0x000200f8,0x0000019b,0x00050041,0x00000093,0x0000019d,0x00000168, + 0x00000063,0x0003003e,0x0000019d,0x00000040,0x00050051,0x0000000c,0x0000019f,0x0000017e, + 0x00000000,0x00050041,0x00000093,0x000001a0,0x00000168,0x0000004b,0x0003003e,0x000001a0, + 0x0000019f,0x000200f9,0x0000019c,0x000200f8,0x0000019c,0x000200f9,0x00000185,0x000200f8, + 0x00000185,0x000200f9,0x00000155,0x000200f8,0x00000154,0x00050051,0x00000006,0x00000158, + 0x00000101,0x00000001,0x0006000c,0x0000000d,0x00000159,0x00000001,0x00000040,0x00000158, + 0x0003003e,0x00000168,0x00000159,0x000200f9,0x00000155,0x000200f8,0x00000155,0x00050041, + 0x000001c4,0x000001c5,0x000000d5,0x0000008e,0x0004003d,0x0000000c,0x000001c6,0x000001c5, + 0x00050041,0x000001c4,0x000001c8,0x000000d5,0x0000009e,0x0004003d,0x0000000c,0x000001c9, + 0x000001c8,0x00050051,0x0000000c,0x00000267,0x000000ef,0x00000000,0x00050085,0x0000000c, + 0x00000269,0x00000267,0x000001c6,0x00050083,0x0000000c,0x0000026a,0x00000269,0x0000003f, + 0x00050051,0x0000000c,0x0000026c,0x000000ef,0x00000001,0x00050085,0x0000000c,0x0000026e, + 0x0000026c,0x000001c9,0x0006000c,0x0000000c,0x00000270,0x00000001,0x00000006,0x000001c9, + 0x00050083,0x0000000c,0x00000271,0x0000026e,0x00000270,0x00070050,0x0000000d,0x00000272, + 0x0000026a,0x00000271,0x00000040,0x0000003f,0x00040070,0x0000000c,0x00000276,0x000001f9, + 0x00050085,0x0000000c,0x00000277,0x00000276,0x00000070,0x00050083,0x0000000c,0x00000278, + 0x0000003f,0x00000277,0x00060052,0x0000000d,0x00000291,0x00000278,0x00000272,0x00000002, + 0x00050041,0x00000167,0x000001db,0x0000008c,0x0000008f,0x0003003e,0x000001db,0x00000291, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..9171fef67f0db284ab9f57fd19351fdd44b914ff GIT binary patch literal 7496 zcmZ9Pdyv&-8OMLJyMTfa;sp)1B^oIa(o#T8S*{DRwhOx$G}Uq0J-ZxSmTh+dO)5+s zl~6)tYP#Qs%9v`LQpWnDX)J4|zp~38-Q2D=6Js?QX&QY#=e*CJH(q#opYQj%zSrNO zVbX#rMR86st(aOIn^aWWtYQ*OQ8>0RPAeu?aa(&=`;yVIz9rXOdzFSWiUxttyjqd2_E02^$$99kO z43taT_w@GzcW>WW?j6H!ns#fqc9%wbb`1}fM+VEIqouL(9bK)wEmm4%;k<$Yw1iq@L4@r8D3Kv9qSqD zEl=oNVRd^32Pbq*tetCXQ+|T+=6>TfR%Q9VYihca$nC3Y^0UadAZw>=>)c+)*0`;= zj;(7mm4>~wbY-}@E=%kBCiJ@o>Uc7EO=izQE7oRsDtODXy8XG}otgi6;CE*AOas5; z>bkurZYZ-qAH40_x_$<@<1KYO6Wr5R$FBk3nbk83y!Wkj{RQBC8J-Q^p7~!09w5Ja z@H6Dw>7I{q`N2}{aBLXr^Mq*QJ-9jTh4*1KwaNbn*|X?6E8AlKUPa!rx@PD7Sw}tk zc#pQR7Rt+!_a%R2TlilO?npVkcef{>-yp9_amSH2CHeQr8`D`*&SU)%yfxW9kKBD- zQM8fY``}qwPc_Om_sSNWq2wHc(?_l$+Qq!g>)nx?OAkBq$+cvhcSz0$I_$hha?3N$HI{45IBS(#lX2cDx%C<6y^?Fs zIPaERXT~{Cx$cbfj>&D!IPaO`0*GRiQy8Gvyb3bi?>-*VQy@$^8ilq1c zHPda{dk4ktsrY3^*WPvYJa`uy=)lm4J*{nlZ+o(&dt-0OjM<*fBX7gGo&WBT{d=dWUXrbFKM&rF|pDu5GZgj zn5j*~9Y!YZ@+*05tn)5<>sj5J_QM(1IYg}c6P^qE0J3$;i62bZe9csHkTKRlTlFp2 zeVEaCs=p!OLy2=;A3|=SN6q4g>8_P^h!4|k#yiSrJZlO4G34C;)5%7?cE{e{+y zC+HDh{0;hE8V6A!AKJWT?j_mT<#(1_I*jj#yowb_7TE)Jzu?E)hbGqLd?SGMU<`F-~ z==y4>zj&N3r~dgQFJ@FP_FWGBUy+@+@zje?CC;@tjqE(E$2IrOmUGR0lf~wFg;5(h zoN>gyxl#9uBuY)s>{sT!?ufKRl;w_fft{{0iOc7JBHiM12QH()7WJMG;on``@T7{7rx z!Y*cff$q881nXS>hQFMC`>}D2{thSq3^w9_Aj|oN+?%+6g5`ZH41+Qm3aC- z{0r=xahR^&I-LJ$WOdeIj+c<-Y#qGgp66G<)@HYAOavHw@&K&9@XH&A%R&!u+ce0-h&_|nr-}syu~_oNMHLHj#JyFx@pZj`#Z<3!ujuH6m9z=-8XdaPqzZkCCq(-E?Gmzo)0k zHxt?RGI7<-pkF}uY&gEesEt@%D3*3UXx!P>g!Z!iHZ)_eh2&UnfnbT80f zj%*C$hu$&b`Np!$A!oyJ1_Peu3&7X z`(}F%Op0||0F^v&-ayzpA+Q*&jMb=hb+{ry8 zv{vUD^VkcHd8m(h>_b*}B%QOnkd5g%i+lQhWbN!Whd6^D0O+Gltn~q8*ZKr@!F?!k zz7xmE)sF5SWNp>CC-*Vh+!J;8(!WY~PaIuCzgJ&Fj_;zsH>SgV9Zo*h`Eg|HWhxWg zH^J6x3%e&0Cmm<*DS*FajnSF@Py20T{k1ojHr`u*Bdhb=S--Vfchq`6^4YaM04E>c zpa+rVRx&@|qJzlBb*;=H)+TCx2s!5VR9efAz{ww`yOxhI+FVO@N9f1s*5??pK8kEC z&tByJ7})&opZUewIY;9f!+2r;C~|Hu_WuUCy?)m9Nk*G>x%Z!-e~xZU$B6lPhMA8Rv@FJ=?ILvZruael@d25aN|w5%Q-q`%DuHgW2en~$Bj&H13+gGV}IsJc6>CSQh literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.h new file mode 100644 index 000000000..c911c569f --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.h @@ -0,0 +1,57 @@ +#pragma once + +const uint32_t draw_msaa_color_seed_attachment_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000019,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0006000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009, + 0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000009, + 0x00006265,0x00030005,0x0000000c,0x00006873,0x00030005,0x00000016,0x0000424d,0x00040006, + 0x00000016,0x00000000,0x00006250,0x00040006,0x00000016,0x00000001,0x00006359,0x00040006, + 0x00000016,0x00000002,0x00006552,0x00040006,0x00000016,0x00000003,0x00006553,0x00040006, + 0x00000016,0x00000004,0x0000366d,0x00040006,0x00000016,0x00000005,0x0000676d,0x00040006, + 0x00000016,0x00000006,0x00006544,0x00040006,0x00000016,0x00000007,0x00006545,0x00040006, + 0x00000016,0x00000008,0x00003755,0x00040006,0x00000016,0x00000009,0x0000676a,0x00040006, + 0x00000016,0x0000000a,0x0000635a,0x00040006,0x00000016,0x0000000b,0x00003157,0x00040006, + 0x00000016,0x0000000c,0x0000676e,0x00040006,0x00000016,0x0000000d,0x00003559,0x00040006, + 0x00000016,0x0000000e,0x0000324f,0x00040006,0x00000016,0x0000000f,0x00006461,0x00040006, + 0x00000016,0x00000010,0x00006579,0x00040006,0x00000016,0x00000011,0x00003376,0x00040006, + 0x00000016,0x00000012,0x00003377,0x00040006,0x00000016,0x00000013,0x00006462,0x00040006, + 0x00000016,0x00000014,0x00006767,0x00030005,0x00000018,0x0000006b,0x00030047,0x00000009, + 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00030047,0x0000000c,0x00000000, + 0x00040047,0x0000000c,0x00000021,0x00000003,0x00040047,0x0000000c,0x00000022,0x00000002, + 0x00040047,0x0000000c,0x0000002b,0x00000000,0x00030047,0x0000000d,0x00000000,0x00030047, + 0x00000012,0x00000000,0x00030047,0x00000016,0x00000002,0x00050048,0x00000016,0x00000000, + 0x00000023,0x00000000,0x00050048,0x00000016,0x00000001,0x00000023,0x00000004,0x00050048, + 0x00000016,0x00000002,0x00000023,0x00000008,0x00050048,0x00000016,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x00000016,0x00000004,0x00000023,0x00000010,0x00050048,0x00000016, + 0x00000005,0x00000023,0x00000014,0x00050048,0x00000016,0x00000006,0x00000023,0x00000018, + 0x00050048,0x00000016,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000016,0x00000008, + 0x00000023,0x00000020,0x00050048,0x00000016,0x00000009,0x00000023,0x00000030,0x00050048, + 0x00000016,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000016,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x00000016,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000016, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x00000016,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x00000016,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000016,0x00000010, + 0x00000023,0x00000054,0x00050048,0x00000016,0x00000011,0x00000023,0x00000058,0x00050048, + 0x00000016,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000016,0x00000013,0x00000023, + 0x00000060,0x00050048,0x00000016,0x00000014,0x00000023,0x00000064,0x00040047,0x00000018, + 0x00000021,0x00000000,0x00040047,0x00000018,0x00000022,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040020,0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008, + 0x00000009,0x00000003,0x00090019,0x0000000a,0x00000006,0x00000006,0x00000000,0x00000000, + 0x00000000,0x00000002,0x00000000,0x00040020,0x0000000b,0x00000000,0x0000000a,0x0004003b, + 0x0000000b,0x0000000c,0x00000000,0x00040015,0x0000000e,0x00000020,0x00000001,0x0004002b, + 0x0000000e,0x0000000f,0x00000000,0x00040017,0x00000010,0x0000000e,0x00000002,0x0005002c, + 0x00000010,0x00000011,0x0000000f,0x0000000f,0x00040015,0x00000013,0x00000020,0x00000000, + 0x00040017,0x00000014,0x0000000e,0x00000004,0x00040017,0x00000015,0x00000006,0x00000002, + 0x0017001e,0x00000016,0x00000006,0x00000006,0x00000006,0x00000006,0x00000013,0x00000013, + 0x00000013,0x00000013,0x00000014,0x00000015,0x00000015,0x00000013,0x00000006,0x00000013, + 0x00000006,0x00000006,0x00000013,0x00000006,0x00000006,0x00000006,0x00000013,0x00040020, + 0x00000017,0x00000002,0x00000016,0x0004003b,0x00000017,0x00000018,0x00000002,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000000a, + 0x0000000d,0x0000000c,0x00050062,0x00000007,0x00000012,0x0000000d,0x00000011,0x0003003e, + 0x00000009,0x00000012,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d99fcf9a472020c3fb5b7b053680e5a018f87e25 GIT binary patch literal 1680 zcmZ9LZBG+X5QQ(ag-Vqd5s<`?0$)rZ#5a({Xp}&f4{J(5qZpI5+g-|HDWokJ{-Zz0 zFD9O6+nb#@$@I=SckbP}XQrj`^-1T(T+LP8vK!i*8yDjo>r<^YH<9BYJPEh@gJkQ~ z_A@f4U5O>%n^8_#F@D+1y72epv&wcHTt@aNY>K6PK1^Haj#Og%N>FVBm7-qtnw4}?#*i~VWg#)|^a2se`g z&kEm}dgg?0Ul#ihg?|}5FC3fmkA&O$J~}^E{8Ju`^jE03ocCe{AY+f3G4_a8<>>11 znqqYKctbJ9S>A^cQyWH1?>KX)N_=0}*_3&X-onu{&v6EhK6s8=;Hb@WoPk3x&(Ui* zH1Hh#hC>U_(Q~*bhU0s1b;HqnIR1eCEd7VuH5@Yl_ug>S3b$`Kw1PV{9P18hq8o6Ud472R(_A7T-=MK){@Z|aR|JY;R zyQI9Kw!`;==>y!3>Sv`c3?2W7Vdme8MI+`5ePXfb&Md(3=65=Q{&0V#*slB^ETCat literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.h new file mode 100644 index 000000000..b7c2625b5 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.h @@ -0,0 +1,121 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000000c2,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0009000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000055, + 0x00000069,0x00000081,0x0000008f,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002, + 0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65, + 0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265, + 0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47, + 0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576, + 0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669, + 0x00070004,0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000034,0x0000674e,0x00030005,0x0000004c, + 0x00004344,0x00030005,0x00000050,0x00003552,0x00030005,0x00000055,0x00003055,0x00030005, + 0x00000059,0x0000424d,0x00040006,0x00000059,0x00000000,0x00006250,0x00040006,0x00000059, + 0x00000001,0x00006359,0x00040006,0x00000059,0x00000002,0x00006552,0x00040006,0x00000059, + 0x00000003,0x00006553,0x00040006,0x00000059,0x00000004,0x0000366d,0x00040006,0x00000059, + 0x00000005,0x0000676d,0x00040006,0x00000059,0x00000006,0x00006544,0x00040006,0x00000059, + 0x00000007,0x00006545,0x00040006,0x00000059,0x00000008,0x00003755,0x00040006,0x00000059, + 0x00000009,0x0000676a,0x00040006,0x00000059,0x0000000a,0x0000635a,0x00040006,0x00000059, + 0x0000000b,0x00003157,0x00040006,0x00000059,0x0000000c,0x0000676e,0x00040006,0x00000059, + 0x0000000d,0x00003559,0x00040006,0x00000059,0x0000000e,0x0000324f,0x00040006,0x00000059, + 0x0000000f,0x00006461,0x00040006,0x00000059,0x00000010,0x00006579,0x00040006,0x00000059, + 0x00000011,0x00003376,0x00040006,0x00000059,0x00000012,0x00003377,0x00040006,0x00000059, + 0x00000013,0x00006462,0x00040006,0x00000059,0x00000014,0x00006767,0x00030005,0x0000005b, + 0x0000006b,0x00030005,0x00000061,0x0000434c,0x00040006,0x00000061,0x00000000,0x00003972, + 0x00040006,0x00000061,0x00000001,0x00003261,0x00040006,0x00000061,0x00000002,0x00003479, + 0x00040006,0x00000061,0x00000003,0x00006969,0x00040006,0x00000061,0x00000004,0x0000326b, + 0x00040006,0x00000061,0x00000005,0x00003244,0x00040006,0x00000061,0x00000006,0x00003056, + 0x00040006,0x00000061,0x00000007,0x0000326e,0x00040006,0x00000061,0x00000008,0x0000365a, + 0x00030005,0x00000063,0x00003041,0x00060005,0x00000069,0x465f6c67,0x43676172,0x64726f6f, + 0x00000000,0x00030005,0x00000081,0x00006771,0x00030005,0x0000008f,0x00003346,0x00030005, + 0x00000092,0x0000444a,0x00040047,0x00000034,0x00000001,0x00000007,0x00030047,0x0000004c, + 0x00000000,0x00040047,0x0000004c,0x00000021,0x0000000c,0x00040047,0x0000004c,0x00000022, + 0x00000001,0x00030047,0x0000004d,0x00000000,0x00030047,0x00000050,0x00000000,0x00040047, + 0x00000050,0x00000021,0x0000000c,0x00040047,0x00000050,0x00000022,0x00000001,0x00030047, + 0x00000051,0x00000000,0x00040047,0x00000055,0x0000001e,0x00000000,0x00030047,0x00000059, + 0x00000002,0x00050048,0x00000059,0x00000000,0x00000023,0x00000000,0x00050048,0x00000059, + 0x00000001,0x00000023,0x00000004,0x00050048,0x00000059,0x00000002,0x00000023,0x00000008, + 0x00050048,0x00000059,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000059,0x00000004, + 0x00000023,0x00000010,0x00050048,0x00000059,0x00000005,0x00000023,0x00000014,0x00050048, + 0x00000059,0x00000006,0x00000023,0x00000018,0x00050048,0x00000059,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x00000059,0x00000008,0x00000023,0x00000020,0x00050048,0x00000059, + 0x00000009,0x00000023,0x00000030,0x00050048,0x00000059,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x00000059,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000059,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x00000059,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x00000059,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000059,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x00000059,0x00000010,0x00000023,0x00000054,0x00050048,0x00000059, + 0x00000011,0x00000023,0x00000058,0x00050048,0x00000059,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x00000059,0x00000013,0x00000023,0x00000060,0x00050048,0x00000059,0x00000014, + 0x00000023,0x00000064,0x00040047,0x0000005b,0x00000021,0x00000000,0x00040047,0x0000005b, + 0x00000022,0x00000000,0x00030047,0x00000061,0x00000002,0x00050048,0x00000061,0x00000000, + 0x00000023,0x00000000,0x00050048,0x00000061,0x00000001,0x00000023,0x00000010,0x00050048, + 0x00000061,0x00000002,0x00000023,0x00000018,0x00050048,0x00000061,0x00000003,0x00000023, + 0x0000001c,0x00050048,0x00000061,0x00000004,0x00000023,0x00000020,0x00050048,0x00000061, + 0x00000005,0x00000023,0x00000030,0x00050048,0x00000061,0x00000006,0x00000023,0x00000038, + 0x00050048,0x00000061,0x00000007,0x00000023,0x0000003c,0x00050048,0x00000061,0x00000008, + 0x00000023,0x00000040,0x00040047,0x00000063,0x00000021,0x00000002,0x00040047,0x00000063, + 0x00000022,0x00000000,0x00040047,0x00000069,0x0000000b,0x0000000f,0x00030047,0x0000006e, + 0x00000000,0x00030047,0x00000081,0x00000000,0x00040047,0x00000081,0x0000001e,0x00000000, + 0x00030047,0x0000008f,0x00000000,0x00030047,0x0000008f,0x0000000e,0x00040047,0x0000008f, + 0x0000001e,0x00000001,0x00030047,0x00000092,0x00000000,0x00040047,0x00000092,0x00000021, + 0x00000000,0x00040047,0x00000092,0x00000022,0x00000002,0x00040047,0x00000092,0x0000002b, + 0x00000000,0x00030047,0x0000009f,0x00000000,0x00030047,0x000000a0,0x00000000,0x00030047, + 0x000000b2,0x00000000,0x00030047,0x000000b3,0x00000000,0x00030047,0x000000b6,0x00000000, + 0x00030047,0x000000b8,0x00000000,0x00030047,0x000000bc,0x00000000,0x00030047,0x000000be, + 0x00000000,0x00030047,0x000000c0,0x00000000,0x00030047,0x000000c1,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000002,0x00040017,0x00000010,0x00000006,0x00000003,0x0004002b, + 0x00000006,0x0000001a,0x3d897143,0x00040015,0x0000001b,0x00000020,0x00000000,0x0004002b, + 0x00000006,0x00000020,0x3bbf4590,0x0004002b,0x00000006,0x00000028,0x4253ee82,0x00020014, + 0x00000033,0x00030030,0x00000033,0x00000034,0x00040017,0x00000047,0x00000006,0x00000004, + 0x00090019,0x0000004a,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x0000004b,0x00000000,0x0000004a,0x0004003b,0x0000004b,0x0000004c, + 0x00000000,0x0002001a,0x0000004e,0x00040020,0x0000004f,0x00000000,0x0000004e,0x0004003b, + 0x0000004f,0x00000050,0x00000000,0x0003001b,0x00000052,0x0000004a,0x00040020,0x00000054, + 0x00000001,0x00000007,0x0004003b,0x00000054,0x00000055,0x00000001,0x00040015,0x00000057, + 0x00000020,0x00000001,0x00040017,0x00000058,0x00000057,0x00000004,0x0017001e,0x00000059, + 0x00000006,0x00000006,0x00000006,0x00000006,0x0000001b,0x0000001b,0x0000001b,0x0000001b, + 0x00000058,0x00000007,0x00000007,0x0000001b,0x00000006,0x0000001b,0x00000006,0x00000006, + 0x0000001b,0x00000006,0x00000006,0x00000006,0x0000001b,0x00040020,0x0000005a,0x00000002, + 0x00000059,0x0004003b,0x0000005a,0x0000005b,0x00000002,0x0004002b,0x00000057,0x0000005c, + 0x0000000f,0x00040020,0x0000005d,0x00000002,0x00000006,0x000b001e,0x00000061,0x00000047, + 0x00000007,0x00000006,0x00000006,0x00000047,0x00000007,0x0000001b,0x0000001b,0x0000001b, + 0x00040020,0x00000062,0x00000002,0x00000061,0x0004003b,0x00000062,0x00000063,0x00000002, + 0x0004002b,0x00000057,0x00000064,0x00000002,0x00040020,0x00000068,0x00000001,0x00000047, + 0x0004003b,0x00000068,0x00000069,0x00000001,0x0004002b,0x00000057,0x0000006a,0x00000011, + 0x0004002b,0x00000057,0x0000006b,0x00000012,0x00040020,0x00000080,0x00000003,0x00000047, + 0x0004003b,0x00000080,0x00000081,0x00000003,0x00040020,0x0000008e,0x00000001,0x00000006, + 0x0004003b,0x0000008e,0x0000008f,0x00000001,0x00090019,0x00000090,0x00000006,0x00000006, + 0x00000000,0x00000000,0x00000001,0x00000002,0x00000000,0x00040020,0x00000091,0x00000000, + 0x00000090,0x0004003b,0x00000091,0x00000092,0x00000000,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000004a,0x0000004d,0x0000004c, + 0x0004003d,0x0000004e,0x00000051,0x00000050,0x00050056,0x00000052,0x00000053,0x0000004d, + 0x00000051,0x0004003d,0x00000007,0x00000056,0x00000055,0x00050041,0x0000005d,0x0000005e, + 0x0000005b,0x0000005c,0x0004003d,0x00000006,0x0000005f,0x0000005e,0x00070057,0x00000047, + 0x00000060,0x00000053,0x00000056,0x00000001,0x0000005f,0x00050041,0x0000005d,0x00000065, + 0x00000063,0x00000064,0x0004003d,0x00000006,0x00000066,0x00000065,0x0005008e,0x00000047, + 0x00000067,0x00000060,0x00000066,0x0008004f,0x00000010,0x0000006e,0x00000067,0x00000067, + 0x00000000,0x00000001,0x00000002,0x0004003d,0x00000047,0x00000070,0x00000069,0x0007004f, + 0x00000007,0x00000071,0x00000070,0x00000070,0x00000000,0x00000001,0x00050041,0x0000005d, + 0x00000073,0x0000005b,0x0000006a,0x0004003d,0x00000006,0x00000074,0x00000073,0x00050041, + 0x0000005d,0x00000076,0x0000005b,0x0000006b,0x0004003d,0x00000006,0x00000077,0x00000076, + 0x000300f7,0x000000a3,0x00000000,0x000400fa,0x00000034,0x00000099,0x000000a1,0x000200f8, + 0x00000099,0x00050051,0x00000006,0x000000aa,0x00000071,0x00000000,0x00050085,0x00000006, + 0x000000ab,0x0000001a,0x000000aa,0x00050051,0x00000006,0x000000ad,0x00000071,0x00000001, + 0x00050085,0x00000006,0x000000ae,0x00000020,0x000000ad,0x00050081,0x00000006,0x000000af, + 0x000000ab,0x000000ae,0x0006000c,0x00000006,0x000000b0,0x00000001,0x0000000a,0x000000af, + 0x00050085,0x00000006,0x000000b2,0x00000028,0x000000b0,0x0006000c,0x00000006,0x000000b3, + 0x00000001,0x0000000a,0x000000b2,0x00050085,0x00000006,0x000000b6,0x000000b3,0x00000074, + 0x00050081,0x00000006,0x000000b8,0x000000b6,0x00000077,0x00060050,0x00000010,0x0000009f, + 0x000000b8,0x000000b8,0x000000b8,0x00050081,0x00000010,0x000000a0,0x0000009f,0x0000006e, + 0x000200f9,0x000000a3,0x000200f8,0x000000a1,0x000200f9,0x000000a3,0x000200f8,0x000000a3, + 0x000700f5,0x00000010,0x000000c1,0x000000a0,0x00000099,0x0000006e,0x000000a1,0x00050051, + 0x00000006,0x0000007a,0x000000c1,0x00000000,0x00060052,0x00000047,0x000000bc,0x0000007a, + 0x00000067,0x00000000,0x00050051,0x00000006,0x0000007c,0x000000c1,0x00000001,0x00060052, + 0x00000047,0x000000be,0x0000007c,0x000000bc,0x00000001,0x00050051,0x00000006,0x0000007f, + 0x000000c1,0x00000002,0x00060052,0x00000047,0x000000c0,0x0000007f,0x000000be,0x00000002, + 0x0003003e,0x00000081,0x000000c0,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..663f4a6a6ccd9800535337d1f7e5c97f662a8e82 GIT binary patch literal 3732 zcmZ9O+iz4=6vp>3Z7D6%Qt$?*nZgSR2|)$KAco!;f&65k|V0tw;4Xz|&<#W&+6G4cDIIjgh7PFD7}zWwdJ*IsMyGn3qNe6Mo} z*X=spZ?4%6x;j7-_$gUQ z){uQ6>y@5yZ77t~>dyVHjoMt7OJ{L1Ar8Yi^appj@hi zL9tZTdZo<}T_BW3-YEKlHbtxP?C4~?XRw*8mU4OR?AkTkKX1FvbVhq$UvwHv zx{UD1a1)OSPn>OH@-n3iqL~%GHsqAywg}60WBHa(9cBwHpPWr7ZqrkNNzaesIoBF* z*Z7L!F@1;p5l>GoMm@h%{?r>S{XY3i-uy24b6z~%@@HOc>G#X8c>3q$&+6Q^{{i{g z*IIs${9Li+_sZY$;yEaP^YzwvpZq(Xe@K4bn}1mTqV^}Zw}h8v;GFu5YC#-eTJ_DA zPo8seT#S?FEfv%BA?Oxe1G1!r{!Mv@A}QVO&+f(QtmnJc(dE(*dLC3nvOYe+U?yX0}i3a9ey#=?7m zyW(-Y2{>wGG4n3q$hUEv6Yhq`@jl>gdR$-3z3Xwj6Lj+)M~>i%GVTQLg<8|hr`9y? zMNYld6HH@1jTqq)GB~S=&4IK0!zE*#7l)g3%c7mRM+L z@rlJ^!#^pbvFNI>NULXE?#s*i-*Gke6YBkDeoD%B;sLZ5VxRX$JEDEAt4EiO82yH;M~6Qab4L}& zgfMHMHj5GwOtfm;)L7jAn5Dc^PXlmoqSK^Fv|kK<;h+f-wAD?ZNy-*}M!s zt6yB+Z$$==(JVKt!JIW2^~x%Sz3SIv4xWbIVyFpo2I^@s)P>hF#KQ2 z?zie`|7w4}0bk4R%g8x+TxTIS-^qxD_F2q55a#>CnCZS3Mn{~c`$0G*W2_O+{ZW|t zjP2JB?D3O~d0jHbZT>@HzFUl&_K~n@88_`?VaCXV?Zr15o^y|Br(X4Z^Wn|V!f(qM zqfY-Q2jqub+<(T0|5FuW&Qsa8jC?TxoGVa90_+M62lI{|NZz_cHULz|G9mfsP0 g=D?fwV_~$s71Qnr!!rl|ZPmA-enOV literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.h new file mode 100644 index 000000000..7c9cf54cd --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.h @@ -0,0 +1,646 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000af9,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x000002ef, + 0x00000333,0x00000354,0x0000036b,0x00000378,0x00030010,0x00000004,0x00000007,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00070004,0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c, + 0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000e6,0x0000674e,0x00030005, + 0x00000291,0x0000674d,0x00030005,0x000002e6,0x00004344,0x00030005,0x000002ea,0x00003552, + 0x00030005,0x000002ef,0x00003055,0x00030005,0x000002f1,0x0000424d,0x00040006,0x000002f1, + 0x00000000,0x00006250,0x00040006,0x000002f1,0x00000001,0x00006359,0x00040006,0x000002f1, + 0x00000002,0x00006552,0x00040006,0x000002f1,0x00000003,0x00006553,0x00040006,0x000002f1, + 0x00000004,0x0000366d,0x00040006,0x000002f1,0x00000005,0x0000676d,0x00040006,0x000002f1, + 0x00000006,0x00006544,0x00040006,0x000002f1,0x00000007,0x00006545,0x00040006,0x000002f1, + 0x00000008,0x00003755,0x00040006,0x000002f1,0x00000009,0x0000676a,0x00040006,0x000002f1, + 0x0000000a,0x0000635a,0x00040006,0x000002f1,0x0000000b,0x00003157,0x00040006,0x000002f1, + 0x0000000c,0x0000676e,0x00040006,0x000002f1,0x0000000d,0x00003559,0x00040006,0x000002f1, + 0x0000000e,0x0000324f,0x00040006,0x000002f1,0x0000000f,0x00006461,0x00040006,0x000002f1, + 0x00000010,0x00006579,0x00040006,0x000002f1,0x00000011,0x00003376,0x00040006,0x000002f1, + 0x00000012,0x00003377,0x00040006,0x000002f1,0x00000013,0x00006462,0x00040006,0x000002f1, + 0x00000014,0x00006767,0x00030005,0x000002f3,0x0000006b,0x00030005,0x000002f8,0x0000434c, + 0x00040006,0x000002f8,0x00000000,0x00003972,0x00040006,0x000002f8,0x00000001,0x00003261, + 0x00040006,0x000002f8,0x00000002,0x00003479,0x00040006,0x000002f8,0x00000003,0x00006969, + 0x00040006,0x000002f8,0x00000004,0x0000326b,0x00040006,0x000002f8,0x00000005,0x00003244, + 0x00040006,0x000002f8,0x00000006,0x00003056,0x00040006,0x000002f8,0x00000007,0x0000326e, + 0x00040006,0x000002f8,0x00000008,0x0000365a,0x00030005,0x000002fa,0x00003041,0x00030005, + 0x00000311,0x0000444a,0x00060005,0x00000333,0x535f6c67,0x6c706d61,0x73614d65,0x006e496b, + 0x00060005,0x00000354,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x0000036b, + 0x00006771,0x00030005,0x00000378,0x00003346,0x00040047,0x000000e6,0x00000001,0x00000007, + 0x00040047,0x00000291,0x00000001,0x00000006,0x00030047,0x000002e6,0x00000000,0x00040047, + 0x000002e6,0x00000021,0x0000000c,0x00040047,0x000002e6,0x00000022,0x00000001,0x00030047, + 0x000002e7,0x00000000,0x00030047,0x000002ea,0x00000000,0x00040047,0x000002ea,0x00000021, + 0x0000000c,0x00040047,0x000002ea,0x00000022,0x00000001,0x00030047,0x000002eb,0x00000000, + 0x00040047,0x000002ef,0x0000001e,0x00000000,0x00030047,0x000002f1,0x00000002,0x00050048, + 0x000002f1,0x00000000,0x00000023,0x00000000,0x00050048,0x000002f1,0x00000001,0x00000023, + 0x00000004,0x00050048,0x000002f1,0x00000002,0x00000023,0x00000008,0x00050048,0x000002f1, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x000002f1,0x00000004,0x00000023,0x00000010, + 0x00050048,0x000002f1,0x00000005,0x00000023,0x00000014,0x00050048,0x000002f1,0x00000006, + 0x00000023,0x00000018,0x00050048,0x000002f1,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x000002f1,0x00000008,0x00000023,0x00000020,0x00050048,0x000002f1,0x00000009,0x00000023, + 0x00000030,0x00050048,0x000002f1,0x0000000a,0x00000023,0x00000038,0x00050048,0x000002f1, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x000002f1,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x000002f1,0x0000000d,0x00000023,0x00000048,0x00050048,0x000002f1,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x000002f1,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x000002f1,0x00000010,0x00000023,0x00000054,0x00050048,0x000002f1,0x00000011,0x00000023, + 0x00000058,0x00050048,0x000002f1,0x00000012,0x00000023,0x0000005c,0x00050048,0x000002f1, + 0x00000013,0x00000023,0x00000060,0x00050048,0x000002f1,0x00000014,0x00000023,0x00000064, + 0x00040047,0x000002f3,0x00000021,0x00000000,0x00040047,0x000002f3,0x00000022,0x00000000, + 0x00030047,0x000002f8,0x00000002,0x00050048,0x000002f8,0x00000000,0x00000023,0x00000000, + 0x00050048,0x000002f8,0x00000001,0x00000023,0x00000010,0x00050048,0x000002f8,0x00000002, + 0x00000023,0x00000018,0x00050048,0x000002f8,0x00000003,0x00000023,0x0000001c,0x00050048, + 0x000002f8,0x00000004,0x00000023,0x00000020,0x00050048,0x000002f8,0x00000005,0x00000023, + 0x00000030,0x00050048,0x000002f8,0x00000006,0x00000023,0x00000038,0x00050048,0x000002f8, + 0x00000007,0x00000023,0x0000003c,0x00050048,0x000002f8,0x00000008,0x00000023,0x00000040, + 0x00040047,0x000002fa,0x00000021,0x00000002,0x00040047,0x000002fa,0x00000022,0x00000000, + 0x00030047,0x00000311,0x00000000,0x00040047,0x00000311,0x00000021,0x00000000,0x00040047, + 0x00000311,0x00000022,0x00000002,0x00040047,0x00000311,0x0000002b,0x00000000,0x00030047, + 0x00000312,0x00000000,0x00030047,0x00000315,0x00000000,0x00030047,0x00000316,0x00000000, + 0x00030047,0x00000317,0x00000000,0x00030047,0x00000318,0x00000000,0x00030047,0x00000319, + 0x00000000,0x00030047,0x0000031a,0x00000000,0x00030047,0x0000031b,0x00000000,0x00030047, + 0x0000031c,0x00000000,0x00030047,0x0000031d,0x00000000,0x00030047,0x0000031e,0x00000000, + 0x00030047,0x0000031f,0x00000000,0x00030047,0x00000320,0x00000000,0x00030047,0x00000321, + 0x00000000,0x00030047,0x00000322,0x00000000,0x00030047,0x00000323,0x00000000,0x00030047, + 0x00000324,0x00000000,0x00030047,0x00000325,0x00000000,0x00030047,0x00000326,0x00000000, + 0x00030047,0x00000327,0x00000000,0x00030047,0x00000328,0x00000000,0x00030047,0x00000329, + 0x00000000,0x00030047,0x0000032a,0x00000000,0x00030047,0x0000032b,0x00000000,0x00030047, + 0x0000032c,0x00000000,0x00030047,0x0000032d,0x00000000,0x00030047,0x0000032e,0x00000000, + 0x00030047,0x0000032f,0x00000000,0x00030047,0x00000330,0x00000000,0x00040047,0x00000333, + 0x0000000b,0x00000014,0x00030047,0x00000333,0x0000000e,0x00030047,0x0000033c,0x00000000, + 0x00030047,0x00000349,0x00000000,0x00030047,0x0000034b,0x00000000,0x00030047,0x0000034c, + 0x00000000,0x00040047,0x00000354,0x0000000b,0x0000000f,0x00030047,0x00000359,0x00000000, + 0x00030047,0x0000036b,0x00000000,0x00040047,0x0000036b,0x0000001e,0x00000000,0x00030047, + 0x00000378,0x00000000,0x00030047,0x00000378,0x0000000e,0x00040047,0x00000378,0x0000001e, + 0x00000001,0x00030047,0x00000385,0x00000000,0x00030047,0x00000387,0x00000000,0x00030047, + 0x0000038c,0x00000000,0x00030047,0x00000390,0x00000000,0x00030047,0x000003a2,0x00000000, + 0x00030047,0x000003a4,0x00000000,0x00030047,0x000003a5,0x00000000,0x00030047,0x000003a7, + 0x00000000,0x00030047,0x000003a8,0x00000000,0x00030047,0x000003aa,0x00000000,0x00030047, + 0x000003ab,0x00000000,0x00030047,0x000003ac,0x00000000,0x00030047,0x000003b2,0x00000000, + 0x00030047,0x000003b5,0x00000000,0x00030047,0x000003cb,0x00000000,0x00030047,0x000003da, + 0x00000000,0x00030047,0x000003db,0x00000000,0x00030047,0x000003dd,0x00000000,0x00030047, + 0x00000407,0x00000000,0x00030047,0x00000409,0x00000000,0x00030047,0x0000040b,0x00000000, + 0x00030047,0x0000040d,0x00000000,0x00030047,0x00000410,0x00000000,0x00030047,0x00000411, + 0x00000000,0x00030047,0x00000413,0x00000000,0x00030047,0x00000415,0x00000000,0x00030047, + 0x00000419,0x00000000,0x00030047,0x0000041b,0x00000000,0x00030047,0x0000041d,0x00000000, + 0x00030047,0x00000420,0x00000000,0x00030047,0x00000421,0x00000000,0x00030047,0x00000422, + 0x00000000,0x00030047,0x00000424,0x00000000,0x00030047,0x00000426,0x00000000,0x00030047, + 0x00000428,0x00000000,0x00030047,0x0000042a,0x00000000,0x00030047,0x00000430,0x00000000, + 0x00030047,0x00000431,0x00000000,0x00030047,0x00000438,0x00000000,0x00030047,0x0000043a, + 0x00000000,0x00030047,0x0000043d,0x00000000,0x00030047,0x0000043f,0x00000000,0x00030047, + 0x00000440,0x00000000,0x00030047,0x00000443,0x00000000,0x00030047,0x00000445,0x00000000, + 0x00030047,0x00000446,0x00000000,0x00030047,0x00000449,0x00000000,0x00030047,0x0000044c, + 0x00000000,0x00030047,0x0000044d,0x00000000,0x00030047,0x0000044f,0x00000000,0x00030047, + 0x00000452,0x00000000,0x00030047,0x00000457,0x00000000,0x00030047,0x00000458,0x00000000, + 0x00030047,0x00000460,0x00000000,0x00030047,0x00000466,0x00000000,0x00030047,0x00000468, + 0x00000000,0x00030047,0x00000469,0x00000000,0x00030047,0x0000046a,0x00000000,0x00030047, + 0x0000046d,0x00000000,0x00030047,0x00000470,0x00000000,0x00030047,0x00000471,0x00000000, + 0x00030047,0x00000472,0x00000000,0x00030047,0x00000474,0x00000000,0x00030047,0x00000477, + 0x00000000,0x00030047,0x00000478,0x00000000,0x00030047,0x0000047a,0x00000000,0x00030047, + 0x0000047c,0x00000000,0x00030047,0x0000047e,0x00000000,0x00030047,0x00000482,0x00000000, + 0x00030047,0x00000484,0x00000000,0x00030047,0x00000486,0x00000000,0x00030047,0x00000489, + 0x00000000,0x00030047,0x0000048a,0x00000000,0x00030047,0x0000048b,0x00000000,0x00030047, + 0x00000494,0x00000000,0x00030047,0x0000049a,0x00000000,0x00030047,0x0000049b,0x00000000, + 0x00030047,0x000004a0,0x00000000,0x00030047,0x000004a6,0x00000000,0x00030047,0x000004a7, + 0x00000000,0x00030047,0x000004a8,0x00000000,0x00030047,0x000004ab,0x00000000,0x00030047, + 0x000004ac,0x00000000,0x00030047,0x000004ad,0x00000000,0x00030047,0x000004b3,0x00000000, + 0x00030047,0x000004b4,0x00000000,0x00030047,0x000004b5,0x00000000,0x00030047,0x000004bf, + 0x00000000,0x00030047,0x000004c0,0x00000000,0x00030047,0x000004c2,0x00000000,0x00030047, + 0x000004c3,0x00000000,0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c5,0x00000000, + 0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c9,0x00000000,0x00030047,0x000004ca, + 0x00000000,0x00030047,0x000004cb,0x00000000,0x00030047,0x000004cd,0x00000000,0x00030047, + 0x000004cf,0x00000000,0x00030047,0x000004d1,0x00000000,0x00030047,0x000004d3,0x00000000, + 0x00030047,0x000004d4,0x00000000,0x00030047,0x000004d7,0x00000000,0x00030047,0x000004da, + 0x00000000,0x00030047,0x000004e2,0x00000000,0x00030047,0x000004e5,0x00000000,0x00030047, + 0x000004ed,0x00000000,0x00030047,0x000004f0,0x00000000,0x00030047,0x000004f7,0x00000000, + 0x00030047,0x000004fa,0x00000000,0x00030047,0x00000500,0x00000000,0x00030047,0x00000505, + 0x00000000,0x00030047,0x00000507,0x00000000,0x00030047,0x0000050c,0x00000000,0x00030047, + 0x00000510,0x00000000,0x00030047,0x000005ac,0x00000000,0x00030047,0x000005b0,0x00000000, + 0x00030047,0x000005b1,0x00000000,0x00030047,0x000005c1,0x00000000,0x00030047,0x000005c4, + 0x00000000,0x00030047,0x000005c5,0x00000000,0x00030047,0x000005c9,0x00000000,0x00030047, + 0x000005cb,0x00000000,0x00030047,0x000005cc,0x00000000,0x00030047,0x000005d5,0x00000000, + 0x00030047,0x000005dc,0x00000000,0x00030047,0x000005e1,0x00000000,0x00030047,0x000005e4, + 0x00000000,0x00030047,0x000005e5,0x00000000,0x00030047,0x000005e9,0x00000000,0x00030047, + 0x000005eb,0x00000000,0x00030047,0x000005ec,0x00000000,0x00030047,0x000005f1,0x00000000, + 0x00030047,0x000005f4,0x00000000,0x00030047,0x000005f5,0x00000000,0x00030047,0x000005f9, + 0x00000000,0x00030047,0x000005fb,0x00000000,0x00030047,0x000005fc,0x00000000,0x00030047, + 0x00000612,0x00000000,0x00030047,0x00000613,0x00000000,0x00030047,0x00000615,0x00000000, + 0x00030047,0x0000061b,0x00000000,0x00030047,0x0000061f,0x00000000,0x00030047,0x00000620, + 0x00000000,0x00030047,0x00000623,0x00000000,0x00030047,0x00000625,0x00000000,0x00030047, + 0x00000626,0x00000000,0x00030047,0x00000627,0x00000000,0x00030047,0x0000062a,0x00000000, + 0x00030047,0x0000062c,0x00000000,0x00030047,0x0000062d,0x00000000,0x00030047,0x00000635, + 0x00000000,0x00030047,0x00000647,0x00000000,0x00030047,0x00000666,0x00000000,0x00030047, + 0x00000669,0x00000000,0x00030047,0x0000066a,0x00000000,0x00030047,0x0000066e,0x00000000, + 0x00030047,0x00000670,0x00000000,0x00030047,0x00000671,0x00000000,0x00030047,0x0000067a, + 0x00000000,0x00030047,0x00000681,0x00000000,0x00030047,0x000006b0,0x00000000,0x00030047, + 0x000006b4,0x00000000,0x00030047,0x000006b5,0x00000000,0x00030047,0x000006c5,0x00000000, + 0x00030047,0x000006c8,0x00000000,0x00030047,0x000006c9,0x00000000,0x00030047,0x000006cd, + 0x00000000,0x00030047,0x000006cf,0x00000000,0x00030047,0x000006d0,0x00000000,0x00030047, + 0x000006d9,0x00000000,0x00030047,0x000006e0,0x00000000,0x00030047,0x000006e5,0x00000000, + 0x00030047,0x000006e8,0x00000000,0x00030047,0x000006e9,0x00000000,0x00030047,0x000006ed, + 0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047,0x000006f0,0x00000000,0x00030047, + 0x000006f5,0x00000000,0x00030047,0x000006f8,0x00000000,0x00030047,0x000006f9,0x00000000, + 0x00030047,0x000006fd,0x00000000,0x00030047,0x000006ff,0x00000000,0x00030047,0x00000700, + 0x00000000,0x00030047,0x00000716,0x00000000,0x00030047,0x00000717,0x00000000,0x00030047, + 0x00000719,0x00000000,0x00030047,0x0000071f,0x00000000,0x00030047,0x00000723,0x00000000, + 0x00030047,0x00000724,0x00000000,0x00030047,0x00000727,0x00000000,0x00030047,0x00000729, + 0x00000000,0x00030047,0x0000072a,0x00000000,0x00030047,0x0000072b,0x00000000,0x00030047, + 0x0000072e,0x00000000,0x00030047,0x00000730,0x00000000,0x00030047,0x00000731,0x00000000, + 0x00030047,0x00000739,0x00000000,0x00030047,0x0000074b,0x00000000,0x00030047,0x0000076a, + 0x00000000,0x00030047,0x0000076d,0x00000000,0x00030047,0x0000076e,0x00000000,0x00030047, + 0x00000772,0x00000000,0x00030047,0x00000774,0x00000000,0x00030047,0x00000775,0x00000000, + 0x00030047,0x0000077e,0x00000000,0x00030047,0x00000785,0x00000000,0x00030047,0x000007ba, + 0x00000000,0x00030047,0x000007bb,0x00000000,0x00030047,0x000007bd,0x00000000,0x00030047, + 0x000007c3,0x00000000,0x00030047,0x000007c7,0x00000000,0x00030047,0x000007c8,0x00000000, + 0x00030047,0x000007cb,0x00000000,0x00030047,0x000007cd,0x00000000,0x00030047,0x000007ce, + 0x00000000,0x00030047,0x000007cf,0x00000000,0x00030047,0x000007d2,0x00000000,0x00030047, + 0x000007d4,0x00000000,0x00030047,0x000007d5,0x00000000,0x00030047,0x000007dd,0x00000000, + 0x00030047,0x000007ef,0x00000000,0x00030047,0x0000080e,0x00000000,0x00030047,0x00000811, + 0x00000000,0x00030047,0x00000812,0x00000000,0x00030047,0x00000816,0x00000000,0x00030047, + 0x00000818,0x00000000,0x00030047,0x00000819,0x00000000,0x00030047,0x00000822,0x00000000, + 0x00030047,0x00000829,0x00000000,0x00030047,0x0000085e,0x00000000,0x00030047,0x0000085f, + 0x00000000,0x00030047,0x00000861,0x00000000,0x00030047,0x00000867,0x00000000,0x00030047, + 0x0000086b,0x00000000,0x00030047,0x0000086c,0x00000000,0x00030047,0x0000086f,0x00000000, + 0x00030047,0x00000871,0x00000000,0x00030047,0x00000872,0x00000000,0x00030047,0x00000873, + 0x00000000,0x00030047,0x00000876,0x00000000,0x00030047,0x00000878,0x00000000,0x00030047, + 0x00000879,0x00000000,0x00030047,0x00000881,0x00000000,0x00030047,0x00000893,0x00000000, + 0x00030047,0x000008b2,0x00000000,0x00030047,0x000008b5,0x00000000,0x00030047,0x000008b6, + 0x00000000,0x00030047,0x000008ba,0x00000000,0x00030047,0x000008bc,0x00000000,0x00030047, + 0x000008bd,0x00000000,0x00030047,0x000008c6,0x00000000,0x00030047,0x000008cd,0x00000000, + 0x00030047,0x000008ef,0x00000000,0x00030047,0x000008f0,0x00000000,0x00030047,0x00000902, + 0x00000000,0x00030047,0x00000903,0x00000000,0x00030047,0x00000906,0x00000000,0x00030047, + 0x00000908,0x00000000,0x00030047,0x0000090c,0x00000000,0x00030047,0x0000090e,0x00000000, + 0x00030047,0x00000910,0x00000000,0x00030047,0x00000918,0x00000000,0x00030047,0x0000091a, + 0x00000000,0x00030047,0x0000091c,0x00000000,0x00030047,0x0000091e,0x00000000,0x00030047, + 0x00000920,0x00000000,0x00030047,0x00000922,0x00000000,0x00030047,0x00000924,0x00000000, + 0x00030047,0x00000926,0x00000000,0x00030047,0x00000928,0x00000000,0x00030047,0x00000930, + 0x00000000,0x00030047,0x00000932,0x00000000,0x00030047,0x00000934,0x00000000,0x00030047, + 0x00000943,0x00000000,0x00030047,0x00000945,0x00000000,0x00030047,0x00000947,0x00000000, + 0x00030047,0x00000949,0x00000000,0x00030047,0x0000094b,0x00000000,0x00030047,0x0000094d, + 0x00000000,0x00030047,0x00000955,0x00000000,0x00030047,0x00000957,0x00000000,0x00030047, + 0x00000959,0x00000000,0x00030047,0x0000095c,0x00000000,0x00030047,0x0000096c,0x00000000, + 0x00030047,0x0000096e,0x00000000,0x00030047,0x00000970,0x00000000,0x00030047,0x00000972, + 0x00000000,0x00030047,0x00000974,0x00000000,0x00030047,0x00000976,0x00000000,0x00030047, + 0x00000978,0x00000000,0x00030047,0x0000097a,0x00000000,0x00030047,0x0000097c,0x00000000, + 0x00030047,0x0000098a,0x00000000,0x00030047,0x0000098c,0x00000000,0x00030047,0x0000098e, + 0x00000000,0x00030047,0x00000996,0x00000000,0x00030047,0x00000998,0x00000000,0x00030047, + 0x0000099a,0x00000000,0x00030047,0x0000099c,0x00000000,0x00030047,0x000009a4,0x00000000, + 0x00030047,0x000009a6,0x00000000,0x00030047,0x000009aa,0x00000000,0x00030047,0x000009ac, + 0x00000000,0x00030047,0x000009ae,0x00000000,0x00030047,0x000009b0,0x00000000,0x00030047, + 0x000009b2,0x00000000,0x00030047,0x000009b4,0x00000000,0x00030047,0x000009c2,0x00000000, + 0x00030047,0x000009c4,0x00000000,0x00030047,0x000009c6,0x00000000,0x00030047,0x000009ce, + 0x00000000,0x00030047,0x000009d0,0x00000000,0x00030047,0x000009d2,0x00000000,0x00030047, + 0x000009d4,0x00000000,0x00030047,0x000009dc,0x00000000,0x00030047,0x000009de,0x00000000, + 0x00030047,0x000009e2,0x00000000,0x00030047,0x000009e4,0x00000000,0x00030047,0x000009e6, + 0x00000000,0x00030047,0x000009e8,0x00000000,0x00030047,0x000009ea,0x00000000,0x00030047, + 0x000009ec,0x00000000,0x00030047,0x000009ee,0x00000000,0x00030047,0x000009f0,0x00000000, + 0x00030047,0x000009f2,0x00000000,0x00030047,0x000009fa,0x00000000,0x00030047,0x000009fc, + 0x00000000,0x00030047,0x000009fe,0x00000000,0x00030047,0x00000a00,0x00000000,0x00030047, + 0x00000a08,0x00000000,0x00030047,0x00000a0a,0x00000000,0x00030047,0x00000a0e,0x00000000, + 0x00030047,0x00000a10,0x00000000,0x00030047,0x00000a12,0x00000000,0x00030047,0x00000a14, + 0x00000000,0x00030047,0x00000a16,0x00000000,0x00030047,0x00000a18,0x00000000,0x00030047, + 0x00000a1a,0x00000000,0x00030047,0x00000a1c,0x00000000,0x00030047,0x00000a1e,0x00000000, + 0x00030047,0x00000a26,0x00000000,0x00030047,0x00000a28,0x00000000,0x00030047,0x00000a2a, + 0x00000000,0x00030047,0x00000a2c,0x00000000,0x00030047,0x00000a34,0x00000000,0x00030047, + 0x00000a36,0x00000000,0x00030047,0x00000a3b,0x00000000,0x00030047,0x00000a3d,0x00000000, + 0x00030047,0x00000a3f,0x00000000,0x00030047,0x00000a41,0x00000000,0x00030047,0x00000a43, + 0x00000000,0x00030047,0x00000a45,0x00000000,0x00030047,0x00000a48,0x00000000,0x00030047, + 0x00000a4a,0x00000000,0x00030047,0x00000a4c,0x00000000,0x00030047,0x00000a50,0x00000000, + 0x00030047,0x00000a52,0x00000000,0x00030047,0x00000a54,0x00000000,0x00030047,0x00000a55, + 0x00000000,0x00030047,0x00000a59,0x00000000,0x00030047,0x00000ac0,0x00000000,0x00030047, + 0x00000af1,0x00000000,0x00030047,0x00000a57,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00030016,0x0000000c, + 0x00000020,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00040017,0x00000012,0x0000000c, + 0x00000002,0x00040017,0x0000001c,0x0000000c,0x00000003,0x00040017,0x00000027,0x0000000c, + 0x00000004,0x00040020,0x00000032,0x00000007,0x0000001c,0x00040018,0x0000004a,0x00000027, + 0x00000004,0x00040015,0x0000004c,0x00000020,0x00000001,0x0004002b,0x00000006,0x00000076, + 0x00000000,0x0004002b,0x00000006,0x00000079,0x00000001,0x0004002b,0x0000000c,0x000000a0, + 0x00000000,0x00020014,0x000000a1,0x0004002b,0x0000000c,0x000000a6,0x3f800000,0x0004002b, + 0x0000000c,0x000000d0,0x3d897143,0x0004002b,0x0000000c,0x000000d4,0x3bbf4590,0x0004002b, + 0x0000000c,0x000000db,0x4253ee82,0x00030030,0x000000a1,0x000000e6,0x0004002b,0x0000004c, + 0x000000fa,0x0000000f,0x0004002b,0x0000004c,0x000000fe,0x00000000,0x0004002b,0x0000004c, + 0x00000101,0x00000001,0x0004002b,0x0000004c,0x00000105,0x00000002,0x0004002b,0x0000004c, + 0x00000109,0x00000003,0x0004002b,0x0000000c,0x0000010d,0x3e800000,0x00040017,0x00000113, + 0x0000004c,0x00000004,0x0004002b,0x0000004c,0x00000114,0x00000004,0x0004002b,0x0000004c, + 0x00000115,0x00000008,0x0007002c,0x00000113,0x00000116,0x00000101,0x00000105,0x00000114, + 0x00000115,0x0007002c,0x00000113,0x00000119,0x000000fe,0x000000fe,0x000000fe,0x000000fe, + 0x00040017,0x0000011a,0x000000a1,0x00000004,0x0007002c,0x00000027,0x0000011c,0x000000a0, + 0x000000a0,0x000000a0,0x000000a0,0x0007002c,0x00000027,0x0000011d,0x000000a6,0x000000a6, + 0x000000a6,0x000000a6,0x0004002b,0x0000004c,0x00000125,0x00000005,0x0004002b,0x0000000c, + 0x00000139,0x3e99999a,0x0004002b,0x0000000c,0x0000013a,0x3f170a3d,0x0004002b,0x0000000c, + 0x0000013b,0x3de147ae,0x0004002b,0x0000000c,0x00000155,0x388205ff,0x0004002b,0x0000000c, + 0x000001bb,0x40000000,0x0004002b,0x0000000c,0x000001c2,0x3f000000,0x00040017,0x000001c8, + 0x000000a1,0x00000003,0x0004002b,0x0000000c,0x00000260,0x41800000,0x0004002b,0x0000000c, + 0x00000265,0x41400000,0x0004002b,0x0000000c,0x0000026b,0x40400000,0x00030030,0x000000a1, + 0x00000291,0x00090019,0x000002e4,0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x000002e5,0x00000000,0x000002e4,0x0004003b,0x000002e5, + 0x000002e6,0x00000000,0x0002001a,0x000002e8,0x00040020,0x000002e9,0x00000000,0x000002e8, + 0x0004003b,0x000002e9,0x000002ea,0x00000000,0x0003001b,0x000002ec,0x000002e4,0x00040020, + 0x000002ee,0x00000001,0x00000012,0x0004003b,0x000002ee,0x000002ef,0x00000001,0x0017001e, + 0x000002f1,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x00000006,0x00000006,0x00000006, + 0x00000006,0x00000113,0x00000012,0x00000012,0x00000006,0x0000000c,0x00000006,0x0000000c, + 0x0000000c,0x00000006,0x0000000c,0x0000000c,0x0000000c,0x00000006,0x00040020,0x000002f2, + 0x00000002,0x000002f1,0x0004003b,0x000002f2,0x000002f3,0x00000002,0x00040020,0x000002f4, + 0x00000002,0x0000000c,0x000b001e,0x000002f8,0x00000027,0x00000012,0x0000000c,0x0000000c, + 0x00000027,0x00000012,0x00000006,0x00000006,0x00000006,0x00040020,0x000002f9,0x00000002, + 0x000002f8,0x0004003b,0x000002f9,0x000002fa,0x00000002,0x0004002b,0x0000004c,0x00000308, + 0x00000007,0x00040020,0x0000030a,0x00000002,0x00000006,0x00090019,0x0000030f,0x0000000c, + 0x00000006,0x00000000,0x00000000,0x00000001,0x00000002,0x00000000,0x00040020,0x00000310, + 0x00000000,0x0000030f,0x0004003b,0x00000310,0x00000311,0x00000000,0x00040017,0x00000313, + 0x0000004c,0x00000002,0x0005002c,0x00000313,0x00000314,0x000000fe,0x000000fe,0x0004001c, + 0x00000331,0x0000004c,0x00000079,0x00040020,0x00000332,0x00000001,0x00000331,0x0004003b, + 0x00000332,0x00000333,0x00000001,0x00040020,0x00000336,0x00000001,0x0000004c,0x00040020, + 0x00000353,0x00000001,0x00000027,0x0004003b,0x00000353,0x00000354,0x00000001,0x0004002b, + 0x0000004c,0x00000355,0x00000011,0x0004002b,0x0000004c,0x00000356,0x00000012,0x00040020, + 0x0000036a,0x00000003,0x00000027,0x0004003b,0x0000036a,0x0000036b,0x00000003,0x00040020, + 0x00000377,0x00000001,0x0000000c,0x0004003b,0x00000377,0x00000378,0x00000001,0x00030001, + 0x0000001c,0x00000a5d,0x0006002c,0x0000001c,0x00000af4,0x000001c2,0x000001c2,0x000001c2, + 0x0006002c,0x0000001c,0x00000af5,0x000000a6,0x000000a6,0x000000a6,0x00030001,0x00000012, + 0x00000af7,0x00030001,0x0000001c,0x00000af8,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000032,0x000003db,0x00000007,0x0004003b, + 0x00000032,0x000003dd,0x00000007,0x0004003b,0x00000032,0x000003cb,0x00000007,0x0004003d, + 0x000002e4,0x000002e7,0x000002e6,0x0004003d,0x000002e8,0x000002eb,0x000002ea,0x00050056, + 0x000002ec,0x000002ed,0x000002e7,0x000002eb,0x0004003d,0x00000012,0x000002f0,0x000002ef, + 0x00050041,0x000002f4,0x000002f5,0x000002f3,0x000000fa,0x0004003d,0x0000000c,0x000002f6, + 0x000002f5,0x00070057,0x00000027,0x000002f7,0x000002ed,0x000002f0,0x00000001,0x000002f6, + 0x00050041,0x000002f4,0x000002fb,0x000002fa,0x00000105,0x0004003d,0x0000000c,0x000002fc, + 0x000002fb,0x0005008e,0x00000027,0x000002fd,0x000002f7,0x000002fc,0x0008004f,0x0000001c, + 0x00000385,0x000002fd,0x000002fd,0x00000000,0x00000001,0x00000002,0x00050051,0x0000000c, + 0x00000387,0x000002fd,0x00000003,0x000500b7,0x000000a1,0x00000388,0x00000387,0x000000a0, + 0x000300f7,0x0000038e,0x00000000,0x000400fa,0x00000388,0x00000389,0x0000038d,0x000200f8, + 0x0000038d,0x000200f9,0x0000038e,0x000200f8,0x00000389,0x00050088,0x0000000c,0x0000038c, + 0x000000a6,0x00000387,0x000200f9,0x0000038e,0x000200f8,0x0000038e,0x000700f5,0x0000000c, + 0x00000a55,0x0000038c,0x00000389,0x000000a0,0x0000038d,0x0005008e,0x0000001c,0x00000390, + 0x00000385,0x00000a55,0x00050051,0x0000000c,0x00000302,0x00000390,0x00000000,0x00060052, + 0x00000027,0x0000090c,0x00000302,0x000002fd,0x00000000,0x00050051,0x0000000c,0x00000304, + 0x00000390,0x00000001,0x00060052,0x00000027,0x0000090e,0x00000304,0x0000090c,0x00000001, + 0x00050051,0x0000000c,0x00000306,0x00000390,0x00000002,0x00060052,0x00000027,0x00000910, + 0x00000306,0x0000090e,0x00000002,0x00050041,0x0000030a,0x0000030b,0x000002fa,0x00000308, + 0x0004003d,0x00000006,0x0000030c,0x0000030b,0x0004003d,0x0000030f,0x00000312,0x00000311, + 0x00070062,0x00000027,0x00000315,0x00000312,0x00000314,0x00000040,0x000000fe,0x0004003d, + 0x0000030f,0x00000316,0x00000311,0x00070062,0x00000027,0x00000317,0x00000316,0x00000314, + 0x00000040,0x00000101,0x0004003d,0x0000030f,0x00000318,0x00000311,0x00070062,0x00000027, + 0x00000319,0x00000318,0x00000314,0x00000040,0x00000105,0x0004003d,0x0000030f,0x0000031a, + 0x00000311,0x00070062,0x00000027,0x0000031b,0x0000031a,0x00000314,0x00000040,0x00000109, + 0x00050051,0x0000000c,0x0000031c,0x00000315,0x00000000,0x00050051,0x0000000c,0x0000031d, + 0x00000315,0x00000001,0x00050051,0x0000000c,0x0000031e,0x00000315,0x00000002,0x00050051, + 0x0000000c,0x0000031f,0x00000315,0x00000003,0x00050051,0x0000000c,0x00000320,0x00000317, + 0x00000000,0x00050051,0x0000000c,0x00000321,0x00000317,0x00000001,0x00050051,0x0000000c, + 0x00000322,0x00000317,0x00000002,0x00050051,0x0000000c,0x00000323,0x00000317,0x00000003, + 0x00050051,0x0000000c,0x00000324,0x00000319,0x00000000,0x00050051,0x0000000c,0x00000325, + 0x00000319,0x00000001,0x00050051,0x0000000c,0x00000326,0x00000319,0x00000002,0x00050051, + 0x0000000c,0x00000327,0x00000319,0x00000003,0x00050051,0x0000000c,0x00000328,0x0000031b, + 0x00000000,0x00050051,0x0000000c,0x00000329,0x0000031b,0x00000001,0x00050051,0x0000000c, + 0x0000032a,0x0000031b,0x00000002,0x00050051,0x0000000c,0x0000032b,0x0000031b,0x00000003, + 0x00070050,0x00000027,0x0000032c,0x0000031c,0x0000031d,0x0000031e,0x0000031f,0x00070050, + 0x00000027,0x0000032d,0x00000320,0x00000321,0x00000322,0x00000323,0x00070050,0x00000027, + 0x0000032e,0x00000324,0x00000325,0x00000326,0x00000327,0x00070050,0x00000027,0x0000032f, + 0x00000328,0x00000329,0x0000032a,0x0000032b,0x00070050,0x0000004a,0x00000330,0x0000032c, + 0x0000032d,0x0000032e,0x0000032f,0x00050041,0x00000336,0x00000337,0x00000333,0x000000fe, + 0x0004003d,0x0000004c,0x00000338,0x00000337,0x000300f7,0x000003c8,0x00000000,0x000300fb, + 0x00000076,0x0000039d,0x000200f8,0x0000039d,0x000500aa,0x000000a1,0x0000039f,0x00000338, + 0x000000fa,0x000300f7,0x000003c7,0x00000000,0x000400fa,0x0000039f,0x000003a0,0x000003ad, + 0x000200f8,0x000003ad,0x00070050,0x00000113,0x000003af,0x00000338,0x00000338,0x00000338, + 0x00000338,0x000500c7,0x00000113,0x000003b0,0x000003af,0x00000116,0x000500ab,0x0000011a, + 0x000003b1,0x000003b0,0x00000119,0x000600a9,0x00000027,0x000003b2,0x000003b1,0x0000011d, + 0x0000011c,0x00050091,0x00000027,0x000003b5,0x00000330,0x000003b2,0x000500c7,0x0000004c, + 0x000003b7,0x00000338,0x00000125,0x000500c3,0x0000004c,0x000003b9,0x00000338,0x00000101, + 0x000500c7,0x0000004c,0x000003ba,0x000003b9,0x00000125,0x00050080,0x0000004c,0x000003bb, + 0x000003b7,0x000003ba,0x000500c7,0x0000004c,0x000003bd,0x000003bb,0x00000109,0x000500c3, + 0x0000004c,0x000003bf,0x000003bb,0x00000105,0x00050080,0x0000004c,0x000003c0,0x000003bd, + 0x000003bf,0x0004006f,0x0000000c,0x000003c2,0x000003c0,0x00050088,0x0000000c,0x000003c3, + 0x000000a6,0x000003c2,0x0005008e,0x00000027,0x000003c5,0x000003b5,0x000003c3,0x000200f9, + 0x000003c8,0x000200f8,0x000003a0,0x00050051,0x00000027,0x000003a2,0x00000330,0x00000000, + 0x00050051,0x00000027,0x000003a4,0x00000330,0x00000001,0x00050081,0x00000027,0x000003a5, + 0x000003a2,0x000003a4,0x00050051,0x00000027,0x000003a7,0x00000330,0x00000002,0x00050081, + 0x00000027,0x000003a8,0x000003a5,0x000003a7,0x00050051,0x00000027,0x000003aa,0x00000330, + 0x00000003,0x00050081,0x00000027,0x000003ab,0x000003a8,0x000003aa,0x0005008e,0x00000027, + 0x000003ac,0x000003ab,0x0000010d,0x000200f9,0x000003c8,0x000200f8,0x000003c7,0x000100ff, + 0x000200f8,0x000003c8,0x000700f5,0x00000027,0x00000a57,0x000003ac,0x000003a0,0x000003c5, + 0x000003ad,0x0008004f,0x0000001c,0x0000033c,0x00000910,0x00000910,0x00000000,0x00000001, + 0x00000002,0x0003003e,0x000003cb,0x0000033c,0x0008004f,0x0000001c,0x00000505,0x00000a57, + 0x00000a57,0x00000000,0x00000001,0x00000002,0x00050051,0x0000000c,0x00000507,0x00000a57, + 0x00000003,0x000500b7,0x000000a1,0x00000508,0x00000507,0x000000a0,0x000300f7,0x0000050e, + 0x00000000,0x000400fa,0x00000508,0x00000509,0x0000050d,0x000200f8,0x0000050d,0x000200f9, + 0x0000050e,0x000200f8,0x00000509,0x00050088,0x0000000c,0x0000050c,0x000000a6,0x00000507, + 0x000200f9,0x0000050e,0x000200f8,0x0000050e,0x000700f5,0x0000000c,0x00000a59,0x0000050c, + 0x00000509,0x000000a0,0x0000050d,0x0005008e,0x0000001c,0x00000510,0x00000505,0x00000a59, + 0x0003003e,0x000003db,0x00000510,0x000300f7,0x000004ff,0x00000000,0x002100fb,0x0000030c, + 0x000004ff,0x0000000b,0x00000406,0x00000001,0x0000040a,0x00000002,0x00000412,0x00000003, + 0x00000423,0x00000004,0x00000427,0x00000005,0x0000042b,0x00000006,0x0000044e,0x00000007, + 0x0000047b,0x00000008,0x0000048c,0x00000009,0x000004c7,0x0000000a,0x000004cc,0x0000000c, + 0x000004d5,0x0000000d,0x000004e0,0x0000000e,0x000004eb,0x0000000f,0x000004f5,0x000200f8, + 0x000004f5,0x000300f7,0x000004fe,0x00000000,0x000400fa,0x00000291,0x000004f6,0x000004fe, + 0x000200f8,0x000004f6,0x0004003d,0x0000001c,0x000004f7,0x000003cb,0x00060052,0x0000001c, + 0x00000a0e,0x000000a0,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x00000a10,0x000000a0, + 0x00000a0e,0x00000001,0x00060052,0x0000001c,0x00000a12,0x000000a0,0x00000a10,0x00000002, + 0x00060052,0x0000001c,0x00000a14,0x000000a6,0x00000a5d,0x00000000,0x00060052,0x0000001c, + 0x00000a16,0x000000a6,0x00000a14,0x00000001,0x00060052,0x0000001c,0x00000a18,0x000000a6, + 0x00000a16,0x00000002,0x0008000c,0x0000001c,0x000004fa,0x00000001,0x0000002b,0x000004f7, + 0x00000a12,0x00000a18,0x0003003e,0x000003cb,0x000004fa,0x00060052,0x0000001c,0x00000a1a, + 0x00000139,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x00000a1c,0x0000013a,0x00000a1a, + 0x00000001,0x00060052,0x0000001c,0x00000a1e,0x0000013b,0x00000a1c,0x00000002,0x00050094, + 0x0000000c,0x00000881,0x000004fa,0x00000a1e,0x00050094,0x0000000c,0x00000893,0x00000510, + 0x00000a1e,0x00060050,0x0000001c,0x0000085e,0x00000893,0x00000893,0x00000893,0x00050083, + 0x0000001c,0x0000085f,0x00000510,0x0000085e,0x00050083,0x0000000c,0x00000861,0x000000a6, + 0x00000881,0x00060052,0x00000012,0x00000a26,0x00000881,0x00000af7,0x00000000,0x00060052, + 0x00000012,0x00000a28,0x00000861,0x00000a26,0x00000001,0x00060052,0x00000012,0x00000a2a, + 0x00000155,0x00000af7,0x00000000,0x00060052,0x00000012,0x00000a2c,0x00000155,0x00000a2a, + 0x00000001,0x0007004f,0x00000012,0x000008b2,0x0000085f,0x0000085f,0x00000000,0x00000001, + 0x00050051,0x0000000c,0x000008ba,0x000008b2,0x00000000,0x00050051,0x0000000c,0x000008bc, + 0x000008b2,0x00000001,0x0007000c,0x0000000c,0x000008bd,0x00000001,0x00000025,0x000008ba, + 0x000008bc,0x00050051,0x0000000c,0x000008b5,0x0000085f,0x00000002,0x0007000c,0x0000000c, + 0x000008b6,0x00000001,0x00000025,0x000008bd,0x000008b5,0x0004007f,0x0000000c,0x00000867, + 0x000008b6,0x0007000c,0x0000000c,0x000008cd,0x00000001,0x00000028,0x000008ba,0x000008bc, + 0x0007000c,0x0000000c,0x000008c6,0x00000001,0x00000028,0x000008cd,0x000008b5,0x00060052, + 0x00000012,0x00000a34,0x00000867,0x00000af7,0x00000000,0x00060052,0x00000012,0x00000a36, + 0x000008c6,0x00000a34,0x00000001,0x0007000c,0x00000012,0x0000086b,0x00000001,0x00000028, + 0x00000a2c,0x00000a36,0x00050088,0x00000012,0x0000086c,0x00000a28,0x0000086b,0x00050051, + 0x0000000c,0x0000086f,0x0000086c,0x00000000,0x00050051,0x0000000c,0x00000871,0x0000086c, + 0x00000001,0x0007000c,0x0000000c,0x00000872,0x00000001,0x00000025,0x0000086f,0x00000871, + 0x0007000c,0x0000000c,0x00000873,0x00000001,0x00000025,0x000000a6,0x00000872,0x0005008e, + 0x0000001c,0x00000876,0x0000085f,0x00000873,0x00060050,0x0000001c,0x00000878,0x00000881, + 0x00000881,0x00000881,0x00050081,0x0000001c,0x00000879,0x00000876,0x00000878,0x0003003e, + 0x000003dd,0x00000879,0x000200f9,0x000004fe,0x000200f8,0x000004fe,0x000200f9,0x000004ff, + 0x000200f8,0x000004eb,0x000300f7,0x000004f4,0x00000000,0x000400fa,0x00000291,0x000004ec, + 0x000004f4,0x000200f8,0x000004ec,0x0004003d,0x0000001c,0x000004ed,0x000003cb,0x00060052, + 0x0000001c,0x000009e2,0x000000a0,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x000009e4, + 0x000000a0,0x000009e2,0x00000001,0x00060052,0x0000001c,0x000009e6,0x000000a0,0x000009e4, + 0x00000002,0x00060052,0x0000001c,0x000009e8,0x000000a6,0x00000a5d,0x00000000,0x00060052, + 0x0000001c,0x000009ea,0x000000a6,0x000009e8,0x00000001,0x00060052,0x0000001c,0x000009ec, + 0x000000a6,0x000009ea,0x00000002,0x0008000c,0x0000001c,0x000004f0,0x00000001,0x0000002b, + 0x000004ed,0x000009e6,0x000009ec,0x0003003e,0x000003cb,0x000004f0,0x00060052,0x0000001c, + 0x000009ee,0x00000139,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x000009f0,0x0000013a, + 0x000009ee,0x00000001,0x00060052,0x0000001c,0x000009f2,0x0000013b,0x000009f0,0x00000002, + 0x00050094,0x0000000c,0x000007dd,0x00000510,0x000009f2,0x00050094,0x0000000c,0x000007ef, + 0x000004f0,0x000009f2,0x00060050,0x0000001c,0x000007ba,0x000007ef,0x000007ef,0x000007ef, + 0x00050083,0x0000001c,0x000007bb,0x000004f0,0x000007ba,0x00050083,0x0000000c,0x000007bd, + 0x000000a6,0x000007dd,0x00060052,0x00000012,0x000009fa,0x000007dd,0x00000af7,0x00000000, + 0x00060052,0x00000012,0x000009fc,0x000007bd,0x000009fa,0x00000001,0x00060052,0x00000012, + 0x000009fe,0x00000155,0x00000af7,0x00000000,0x00060052,0x00000012,0x00000a00,0x00000155, + 0x000009fe,0x00000001,0x0007004f,0x00000012,0x0000080e,0x000007bb,0x000007bb,0x00000000, + 0x00000001,0x00050051,0x0000000c,0x00000816,0x0000080e,0x00000000,0x00050051,0x0000000c, + 0x00000818,0x0000080e,0x00000001,0x0007000c,0x0000000c,0x00000819,0x00000001,0x00000025, + 0x00000816,0x00000818,0x00050051,0x0000000c,0x00000811,0x000007bb,0x00000002,0x0007000c, + 0x0000000c,0x00000812,0x00000001,0x00000025,0x00000819,0x00000811,0x0004007f,0x0000000c, + 0x000007c3,0x00000812,0x0007000c,0x0000000c,0x00000829,0x00000001,0x00000028,0x00000816, + 0x00000818,0x0007000c,0x0000000c,0x00000822,0x00000001,0x00000028,0x00000829,0x00000811, + 0x00060052,0x00000012,0x00000a08,0x000007c3,0x00000af7,0x00000000,0x00060052,0x00000012, + 0x00000a0a,0x00000822,0x00000a08,0x00000001,0x0007000c,0x00000012,0x000007c7,0x00000001, + 0x00000028,0x00000a00,0x00000a0a,0x00050088,0x00000012,0x000007c8,0x000009fc,0x000007c7, + 0x00050051,0x0000000c,0x000007cb,0x000007c8,0x00000000,0x00050051,0x0000000c,0x000007cd, + 0x000007c8,0x00000001,0x0007000c,0x0000000c,0x000007ce,0x00000001,0x00000025,0x000007cb, + 0x000007cd,0x0007000c,0x0000000c,0x000007cf,0x00000001,0x00000025,0x000000a6,0x000007ce, + 0x0005008e,0x0000001c,0x000007d2,0x000007bb,0x000007cf,0x00060050,0x0000001c,0x000007d4, + 0x000007dd,0x000007dd,0x000007dd,0x00050081,0x0000001c,0x000007d5,0x000007d2,0x000007d4, + 0x0003003e,0x000003dd,0x000007d5,0x000200f9,0x000004f4,0x000200f8,0x000004f4,0x000200f9, + 0x000004ff,0x000200f8,0x000004e0,0x000300f7,0x000004ea,0x00000000,0x000400fa,0x00000291, + 0x000004e1,0x000004ea,0x000200f8,0x000004e1,0x0004003d,0x0000001c,0x000004e2,0x000003cb, + 0x00060052,0x0000001c,0x000009aa,0x000000a0,0x00000a5d,0x00000000,0x00060052,0x0000001c, + 0x000009ac,0x000000a0,0x000009aa,0x00000001,0x00060052,0x0000001c,0x000009ae,0x000000a0, + 0x000009ac,0x00000002,0x00060052,0x0000001c,0x000009b0,0x000000a6,0x00000a5d,0x00000000, + 0x00060052,0x0000001c,0x000009b2,0x000000a6,0x000009b0,0x00000001,0x00060052,0x0000001c, + 0x000009b4,0x000000a6,0x000009b2,0x00000002,0x0008000c,0x0000001c,0x000004e5,0x00000001, + 0x0000002b,0x000004e2,0x000009ae,0x000009b4,0x0003003e,0x000003cb,0x000004e5,0x0007004f, + 0x00000012,0x000006c5,0x000004e5,0x000004e5,0x00000000,0x00000001,0x00050051,0x0000000c, + 0x000006cd,0x000006c5,0x00000000,0x00050051,0x0000000c,0x000006cf,0x000006c5,0x00000001, + 0x0007000c,0x0000000c,0x000006d0,0x00000001,0x00000028,0x000006cd,0x000006cf,0x00050051, + 0x0000000c,0x000006c8,0x000004e5,0x00000002,0x0007000c,0x0000000c,0x000006c9,0x00000001, + 0x00000028,0x000006d0,0x000006c8,0x0007000c,0x0000000c,0x000006e0,0x00000001,0x00000025, + 0x000006cd,0x000006cf,0x0007000c,0x0000000c,0x000006d9,0x00000001,0x00000025,0x000006e0, + 0x000006c8,0x00050083,0x0000000c,0x000006b0,0x000006c9,0x000006d9,0x0007004f,0x00000012, + 0x000006e5,0x00000510,0x00000510,0x00000000,0x00000001,0x00050051,0x0000000c,0x000006ed, + 0x000006e5,0x00000000,0x00050051,0x0000000c,0x000006ef,0x000006e5,0x00000001,0x0007000c, + 0x0000000c,0x000006f0,0x00000001,0x00000025,0x000006ed,0x000006ef,0x00050051,0x0000000c, + 0x000006e8,0x00000510,0x00000002,0x0007000c,0x0000000c,0x000006e9,0x00000001,0x00000025, + 0x000006f0,0x000006e8,0x00060050,0x0000001c,0x000006b4,0x000006e9,0x000006e9,0x000006e9, + 0x00050083,0x0000001c,0x000006b5,0x00000510,0x000006b4,0x0007004f,0x00000012,0x000006f5, + 0x000006b5,0x000006b5,0x00000000,0x00000001,0x00050051,0x0000000c,0x000006fd,0x000006f5, + 0x00000000,0x00050051,0x0000000c,0x000006ff,0x000006f5,0x00000001,0x0007000c,0x0000000c, + 0x00000700,0x00000001,0x00000028,0x000006fd,0x000006ff,0x00050051,0x0000000c,0x000006f8, + 0x000006b5,0x00000002,0x0007000c,0x0000000c,0x000006f9,0x00000001,0x00000028,0x00000700, + 0x000006f8,0x0007000c,0x0000000c,0x000006ba,0x00000001,0x00000028,0x00000155,0x000006f9, + 0x00050088,0x0000000c,0x000006bb,0x000006b0,0x000006ba,0x0005008e,0x0000001c,0x000006be, + 0x000006b5,0x000006bb,0x00060052,0x0000001c,0x000009c2,0x00000139,0x00000a5d,0x00000000, + 0x00060052,0x0000001c,0x000009c4,0x0000013a,0x000009c2,0x00000001,0x00060052,0x0000001c, + 0x000009c6,0x0000013b,0x000009c4,0x00000002,0x00050094,0x0000000c,0x00000739,0x00000510, + 0x000009c6,0x00050094,0x0000000c,0x0000074b,0x000006be,0x000009c6,0x00060050,0x0000001c, + 0x00000716,0x0000074b,0x0000074b,0x0000074b,0x00050083,0x0000001c,0x00000717,0x000006be, + 0x00000716,0x00050083,0x0000000c,0x00000719,0x000000a6,0x00000739,0x00060052,0x00000012, + 0x000009ce,0x00000739,0x00000af7,0x00000000,0x00060052,0x00000012,0x000009d0,0x00000719, + 0x000009ce,0x00000001,0x00060052,0x00000012,0x000009d2,0x00000155,0x00000af7,0x00000000, + 0x00060052,0x00000012,0x000009d4,0x00000155,0x000009d2,0x00000001,0x0007004f,0x00000012, + 0x0000076a,0x00000717,0x00000717,0x00000000,0x00000001,0x00050051,0x0000000c,0x00000772, + 0x0000076a,0x00000000,0x00050051,0x0000000c,0x00000774,0x0000076a,0x00000001,0x0007000c, + 0x0000000c,0x00000775,0x00000001,0x00000025,0x00000772,0x00000774,0x00050051,0x0000000c, + 0x0000076d,0x00000717,0x00000002,0x0007000c,0x0000000c,0x0000076e,0x00000001,0x00000025, + 0x00000775,0x0000076d,0x0004007f,0x0000000c,0x0000071f,0x0000076e,0x0007000c,0x0000000c, + 0x00000785,0x00000001,0x00000028,0x00000772,0x00000774,0x0007000c,0x0000000c,0x0000077e, + 0x00000001,0x00000028,0x00000785,0x0000076d,0x00060052,0x00000012,0x000009dc,0x0000071f, + 0x00000af7,0x00000000,0x00060052,0x00000012,0x000009de,0x0000077e,0x000009dc,0x00000001, + 0x0007000c,0x00000012,0x00000723,0x00000001,0x00000028,0x000009d4,0x000009de,0x00050088, + 0x00000012,0x00000724,0x000009d0,0x00000723,0x00050051,0x0000000c,0x00000727,0x00000724, + 0x00000000,0x00050051,0x0000000c,0x00000729,0x00000724,0x00000001,0x0007000c,0x0000000c, + 0x0000072a,0x00000001,0x00000025,0x00000727,0x00000729,0x0007000c,0x0000000c,0x0000072b, + 0x00000001,0x00000025,0x000000a6,0x0000072a,0x0005008e,0x0000001c,0x0000072e,0x00000717, + 0x0000072b,0x00060050,0x0000001c,0x00000730,0x00000739,0x00000739,0x00000739,0x00050081, + 0x0000001c,0x00000731,0x0000072e,0x00000730,0x0003003e,0x000003dd,0x00000731,0x000200f9, + 0x000004ea,0x000200f8,0x000004ea,0x000200f9,0x000004ff,0x000200f8,0x000004d5,0x000300f7, + 0x000004df,0x00000000,0x000400fa,0x00000291,0x000004d6,0x000004df,0x000200f8,0x000004d6, + 0x0004003d,0x0000001c,0x000004d7,0x000003cb,0x00060052,0x0000001c,0x00000972,0x000000a0, + 0x00000a5d,0x00000000,0x00060052,0x0000001c,0x00000974,0x000000a0,0x00000972,0x00000001, + 0x00060052,0x0000001c,0x00000976,0x000000a0,0x00000974,0x00000002,0x00060052,0x0000001c, + 0x00000978,0x000000a6,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x0000097a,0x000000a6, + 0x00000978,0x00000001,0x00060052,0x0000001c,0x0000097c,0x000000a6,0x0000097a,0x00000002, + 0x0008000c,0x0000001c,0x000004da,0x00000001,0x0000002b,0x000004d7,0x00000976,0x0000097c, + 0x0003003e,0x000003cb,0x000004da,0x0007004f,0x00000012,0x000005c1,0x00000510,0x00000510, + 0x00000000,0x00000001,0x00050051,0x0000000c,0x000005c9,0x000005c1,0x00000000,0x00050051, + 0x0000000c,0x000005cb,0x000005c1,0x00000001,0x0007000c,0x0000000c,0x000005cc,0x00000001, + 0x00000028,0x000005c9,0x000005cb,0x00050051,0x0000000c,0x000005c4,0x00000510,0x00000002, + 0x0007000c,0x0000000c,0x000005c5,0x00000001,0x00000028,0x000005cc,0x000005c4,0x0007000c, + 0x0000000c,0x000005dc,0x00000001,0x00000025,0x000005c9,0x000005cb,0x0007000c,0x0000000c, + 0x000005d5,0x00000001,0x00000025,0x000005dc,0x000005c4,0x00050083,0x0000000c,0x000005ac, + 0x000005c5,0x000005d5,0x0007004f,0x00000012,0x000005e1,0x000004da,0x000004da,0x00000000, + 0x00000001,0x00050051,0x0000000c,0x000005e9,0x000005e1,0x00000000,0x00050051,0x0000000c, + 0x000005eb,0x000005e1,0x00000001,0x0007000c,0x0000000c,0x000005ec,0x00000001,0x00000025, + 0x000005e9,0x000005eb,0x00050051,0x0000000c,0x000005e4,0x000004da,0x00000002,0x0007000c, + 0x0000000c,0x000005e5,0x00000001,0x00000025,0x000005ec,0x000005e4,0x00060050,0x0000001c, + 0x000005b0,0x000005e5,0x000005e5,0x000005e5,0x00050083,0x0000001c,0x000005b1,0x000004da, + 0x000005b0,0x0007004f,0x00000012,0x000005f1,0x000005b1,0x000005b1,0x00000000,0x00000001, + 0x00050051,0x0000000c,0x000005f9,0x000005f1,0x00000000,0x00050051,0x0000000c,0x000005fb, + 0x000005f1,0x00000001,0x0007000c,0x0000000c,0x000005fc,0x00000001,0x00000028,0x000005f9, + 0x000005fb,0x00050051,0x0000000c,0x000005f4,0x000005b1,0x00000002,0x0007000c,0x0000000c, + 0x000005f5,0x00000001,0x00000028,0x000005fc,0x000005f4,0x0007000c,0x0000000c,0x000005b6, + 0x00000001,0x00000028,0x00000155,0x000005f5,0x00050088,0x0000000c,0x000005b7,0x000005ac, + 0x000005b6,0x0005008e,0x0000001c,0x000005ba,0x000005b1,0x000005b7,0x00060052,0x0000001c, + 0x0000098a,0x00000139,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x0000098c,0x0000013a, + 0x0000098a,0x00000001,0x00060052,0x0000001c,0x0000098e,0x0000013b,0x0000098c,0x00000002, + 0x00050094,0x0000000c,0x00000635,0x00000510,0x0000098e,0x00050094,0x0000000c,0x00000647, + 0x000005ba,0x0000098e,0x00060050,0x0000001c,0x00000612,0x00000647,0x00000647,0x00000647, + 0x00050083,0x0000001c,0x00000613,0x000005ba,0x00000612,0x00050083,0x0000000c,0x00000615, + 0x000000a6,0x00000635,0x00060052,0x00000012,0x00000996,0x00000635,0x00000af7,0x00000000, + 0x00060052,0x00000012,0x00000998,0x00000615,0x00000996,0x00000001,0x00060052,0x00000012, + 0x0000099a,0x00000155,0x00000af7,0x00000000,0x00060052,0x00000012,0x0000099c,0x00000155, + 0x0000099a,0x00000001,0x0007004f,0x00000012,0x00000666,0x00000613,0x00000613,0x00000000, + 0x00000001,0x00050051,0x0000000c,0x0000066e,0x00000666,0x00000000,0x00050051,0x0000000c, + 0x00000670,0x00000666,0x00000001,0x0007000c,0x0000000c,0x00000671,0x00000001,0x00000025, + 0x0000066e,0x00000670,0x00050051,0x0000000c,0x00000669,0x00000613,0x00000002,0x0007000c, + 0x0000000c,0x0000066a,0x00000001,0x00000025,0x00000671,0x00000669,0x0004007f,0x0000000c, + 0x0000061b,0x0000066a,0x0007000c,0x0000000c,0x00000681,0x00000001,0x00000028,0x0000066e, + 0x00000670,0x0007000c,0x0000000c,0x0000067a,0x00000001,0x00000028,0x00000681,0x00000669, + 0x00060052,0x00000012,0x000009a4,0x0000061b,0x00000af7,0x00000000,0x00060052,0x00000012, + 0x000009a6,0x0000067a,0x000009a4,0x00000001,0x0007000c,0x00000012,0x0000061f,0x00000001, + 0x00000028,0x0000099c,0x000009a6,0x00050088,0x00000012,0x00000620,0x00000998,0x0000061f, + 0x00050051,0x0000000c,0x00000623,0x00000620,0x00000000,0x00050051,0x0000000c,0x00000625, + 0x00000620,0x00000001,0x0007000c,0x0000000c,0x00000626,0x00000001,0x00000025,0x00000623, + 0x00000625,0x0007000c,0x0000000c,0x00000627,0x00000001,0x00000025,0x000000a6,0x00000626, + 0x0005008e,0x0000001c,0x0000062a,0x00000613,0x00000627,0x00060050,0x0000001c,0x0000062c, + 0x00000635,0x00000635,0x00000635,0x00050081,0x0000001c,0x0000062d,0x0000062a,0x0000062c, + 0x0003003e,0x000003dd,0x0000062d,0x000200f9,0x000004df,0x000200f8,0x000004df,0x000200f9, + 0x000004ff,0x000200f8,0x000004cc,0x0004003d,0x0000001c,0x000004cd,0x000003cb,0x00050081, + 0x0000001c,0x000004cf,0x000004cd,0x00000510,0x0005008e,0x0000001c,0x000004d1,0x000004cd, + 0x000001bb,0x00050085,0x0000001c,0x000004d3,0x000004d1,0x00000510,0x00050083,0x0000001c, + 0x000004d4,0x000004cf,0x000004d3,0x0003003e,0x000003dd,0x000004d4,0x000200f9,0x000004ff, + 0x000200f8,0x000004c7,0x0004003d,0x0000001c,0x000004c9,0x000003cb,0x00050083,0x0000001c, + 0x000004ca,0x00000510,0x000004c9,0x0006000c,0x0000001c,0x000004cb,0x00000001,0x00000004, + 0x000004ca,0x0003003e,0x000003dd,0x000004cb,0x000200f9,0x000004ff,0x000200f8,0x0000048c, + 0x000200f9,0x0000048d,0x000200f8,0x0000048d,0x000700f5,0x0000004c,0x00000ab0,0x000000fe, + 0x0000048c,0x000004bb,0x000004b9,0x000500b1,0x000000a1,0x00000490,0x00000ab0,0x00000109, + 0x000400f6,0x000004bc,0x000004b9,0x00000000,0x000400fa,0x00000490,0x00000491,0x000004bc, + 0x000200f8,0x00000491,0x00050041,0x0000000d,0x00000493,0x000003cb,0x00000ab0,0x0004003d, + 0x0000000c,0x00000494,0x00000493,0x000500bc,0x000000a1,0x00000495,0x00000494,0x000001c2, + 0x000300f7,0x000004b8,0x00000000,0x000400fa,0x00000495,0x00000496,0x0000049d,0x000200f8, + 0x0000049d,0x00050041,0x0000000d,0x0000049f,0x000003db,0x00000ab0,0x0004003d,0x0000000c, + 0x000004a0,0x0000049f,0x000500bc,0x000000a1,0x000004a1,0x000004a0,0x0000010d,0x000300f7, + 0x000004b7,0x00000000,0x000400fa,0x000004a1,0x000004a2,0x000004af,0x000200f8,0x000004af, + 0x0004003d,0x0000000c,0x000004b3,0x0000049f,0x0006000c,0x0000000c,0x000004b4,0x00000001, + 0x00000020,0x000004b3,0x00050083,0x0000000c,0x000004b5,0x000004b4,0x000000a6,0x00050041, + 0x0000000d,0x000004b6,0x000003dd,0x00000ab0,0x0003003e,0x000004b6,0x000004b5,0x000200f9, + 0x000004b7,0x000200f8,0x000004a2,0x0004003d,0x0000000c,0x000004a6,0x0000049f,0x00050085, + 0x0000000c,0x000004a7,0x00000260,0x000004a6,0x00050083,0x0000000c,0x000004a8,0x000004a7, + 0x00000265,0x0004003d,0x0000000c,0x000004ab,0x0000049f,0x00050085,0x0000000c,0x000004ac, + 0x000004a8,0x000004ab,0x00050081,0x0000000c,0x000004ad,0x000004ac,0x0000026b,0x00050041, + 0x0000000d,0x000004ae,0x000003dd,0x00000ab0,0x0003003e,0x000004ae,0x000004ad,0x000200f9, + 0x000004b7,0x000200f8,0x000004b7,0x000200f9,0x000004b8,0x000200f8,0x00000496,0x00050041, + 0x0000000d,0x00000499,0x000003db,0x00000ab0,0x0004003d,0x0000000c,0x0000049a,0x00000499, + 0x00050083,0x0000000c,0x0000049b,0x000000a6,0x0000049a,0x00050041,0x0000000d,0x0000049c, + 0x000003dd,0x00000ab0,0x0003003e,0x0000049c,0x0000049b,0x000200f9,0x000004b8,0x000200f8, + 0x000004b8,0x000200f9,0x000004b9,0x000200f8,0x000004b9,0x00050080,0x0000004c,0x000004bb, + 0x00000ab0,0x00000101,0x000200f9,0x0000048d,0x000200f8,0x000004bc,0x0004003d,0x0000001c, + 0x000004bf,0x000003cb,0x0005008e,0x0000001c,0x000004c0,0x000004bf,0x000001bb,0x00050083, + 0x0000001c,0x000004c2,0x000004c0,0x00000af5,0x00050085,0x0000001c,0x000004c3,0x00000510, + 0x000004c2,0x0004003d,0x0000001c,0x000004c4,0x000003dd,0x00050085,0x0000001c,0x000004c5, + 0x000004c3,0x000004c4,0x00050081,0x0000001c,0x000004c6,0x00000510,0x000004c5,0x0003003e, + 0x000003dd,0x000004c6,0x000200f9,0x000004ff,0x000200f8,0x0000047b,0x0004003d,0x0000001c, + 0x0000047c,0x000003cb,0x00050085,0x0000001c,0x0000047e,0x0000047c,0x00000510,0x00050081, + 0x0000001c,0x00000482,0x0000047c,0x00000510,0x00050083,0x0000001c,0x00000484,0x00000482, + 0x0000047e,0x00050083,0x0000001c,0x00000486,0x00000484,0x00000af4,0x00060052,0x0000001c, + 0x0000096c,0x000001c2,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x0000096e,0x000001c2, + 0x0000096c,0x00000001,0x00060052,0x0000001c,0x00000970,0x000001c2,0x0000096e,0x00000002, + 0x000500ba,0x000001c8,0x00000489,0x0000047c,0x00000970,0x000600a9,0x0000001c,0x0000048a, + 0x00000489,0x00000486,0x0000047e,0x0005008e,0x0000001c,0x0000048b,0x0000048a,0x000001bb, + 0x0003003e,0x000003dd,0x0000048b,0x000200f9,0x000004ff,0x000200f8,0x0000044e,0x0004003d, + 0x0000001c,0x0000044f,0x000003cb,0x00060052,0x0000001c,0x00000943,0x000000a0,0x00000a5d, + 0x00000000,0x00060052,0x0000001c,0x00000945,0x000000a0,0x00000943,0x00000001,0x00060052, + 0x0000001c,0x00000947,0x000000a0,0x00000945,0x00000002,0x00060052,0x0000001c,0x00000949, + 0x000000a6,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x0000094b,0x000000a6,0x00000949, + 0x00000001,0x00060052,0x0000001c,0x0000094d,0x000000a6,0x0000094b,0x00000002,0x0008000c, + 0x0000001c,0x00000452,0x00000001,0x0000002b,0x0000044f,0x00000947,0x0000094d,0x0003003e, + 0x000003cb,0x00000452,0x0008004f,0x0000001c,0x00000457,0x00000a57,0x00000a57,0x00000003, + 0x00000003,0x00000003,0x0008000c,0x0000001c,0x00000458,0x00000001,0x0000002b,0x00000505, + 0x00000947,0x00000457,0x00050051,0x0000000c,0x0000045a,0x00000458,0x00000000,0x00060052, + 0x00000027,0x00000955,0x0000045a,0x00000a57,0x00000000,0x00050051,0x0000000c,0x0000045c, + 0x00000458,0x00000001,0x00060052,0x00000027,0x00000957,0x0000045c,0x00000955,0x00000001, + 0x00050051,0x0000000c,0x0000045e,0x00000458,0x00000002,0x00060052,0x00000027,0x00000959, + 0x0000045e,0x00000957,0x00000002,0x00050051,0x0000000c,0x00000460,0x00000959,0x00000003, + 0x000500b4,0x000000a1,0x00000461,0x00000460,0x000000a0,0x000300f7,0x00000464,0x00000000, + 0x000400fa,0x00000461,0x00000462,0x00000464,0x000200f8,0x00000462,0x00060052,0x00000027, + 0x0000095c,0x000000a6,0x00000959,0x00000003,0x000200f9,0x00000464,0x000200f8,0x00000464, + 0x000700f5,0x00000027,0x00000ac0,0x00000959,0x0000044e,0x0000095c,0x00000462,0x00050051, + 0x0000000c,0x00000466,0x00000ac0,0x00000003,0x0008004f,0x0000001c,0x00000468,0x00000ac0, + 0x00000ac0,0x00000000,0x00000001,0x00000002,0x00060050,0x0000001c,0x00000469,0x00000466, + 0x00000466,0x00000466,0x00050083,0x0000001c,0x0000046a,0x00000469,0x00000468,0x0004003d, + 0x0000001c,0x0000046d,0x000003cb,0x0005008e,0x0000001c,0x00000470,0x0000046d,0x00000466, + 0x00050088,0x0000001c,0x00000471,0x0000046a,0x00000470,0x0007000c,0x0000001c,0x00000472, + 0x00000001,0x00000025,0x0000094d,0x00000471,0x0006000c,0x0000001c,0x00000474,0x00000001, + 0x00000006,0x0000046a,0x000500b4,0x000001c8,0x00000477,0x0000046d,0x00000947,0x000600a9, + 0x0000001c,0x00000478,0x00000477,0x00000474,0x00000472,0x00050083,0x0000001c,0x0000047a, + 0x00000af5,0x00000478,0x0003003e,0x000003dd,0x0000047a,0x000200f9,0x000004ff,0x000200f8, + 0x0000042b,0x00060052,0x0000001c,0x0000091e,0x000000a0,0x00000a5d,0x00000000,0x00060052, + 0x0000001c,0x00000920,0x000000a0,0x0000091e,0x00000001,0x00060052,0x0000001c,0x00000922, + 0x000000a0,0x00000920,0x00000002,0x0008004f,0x0000001c,0x00000430,0x00000a57,0x00000a57, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x0000001c,0x00000431,0x00000001,0x0000002b, + 0x00000505,0x00000922,0x00000430,0x00050051,0x0000000c,0x00000433,0x00000431,0x00000000, + 0x00060052,0x00000027,0x00000924,0x00000433,0x00000a57,0x00000000,0x00050051,0x0000000c, + 0x00000435,0x00000431,0x00000001,0x00060052,0x00000027,0x00000926,0x00000435,0x00000924, + 0x00000001,0x00050051,0x0000000c,0x00000437,0x00000431,0x00000002,0x00060052,0x00000027, + 0x00000928,0x00000437,0x00000926,0x00000002,0x0004003d,0x0000001c,0x00000438,0x000003cb, + 0x00050083,0x0000001c,0x0000043a,0x00000af5,0x00000438,0x00060052,0x0000001c,0x00000930, + 0x000000a6,0x00000a5d,0x00000000,0x00060052,0x0000001c,0x00000932,0x000000a6,0x00000930, + 0x00000001,0x00060052,0x0000001c,0x00000934,0x000000a6,0x00000932,0x00000002,0x0008000c, + 0x0000001c,0x0000043d,0x00000001,0x0000002b,0x0000043a,0x00000922,0x00000934,0x00050051, + 0x0000000c,0x0000043f,0x00000928,0x00000003,0x0005008e,0x0000001c,0x00000440,0x0000043d, + 0x0000043f,0x0008004f,0x0000001c,0x00000443,0x00000928,0x00000928,0x00000000,0x00000001, + 0x00000002,0x00050088,0x0000001c,0x00000445,0x00000443,0x00000440,0x0007000c,0x0000001c, + 0x00000446,0x00000001,0x00000025,0x00000934,0x00000445,0x0006000c,0x0000001c,0x00000449, + 0x00000001,0x00000006,0x00000443,0x000500b4,0x000001c8,0x0000044c,0x00000440,0x00000922, + 0x000600a9,0x0000001c,0x0000044d,0x0000044c,0x00000449,0x00000446,0x0003003e,0x000003dd, + 0x0000044d,0x000200f9,0x000004ff,0x000200f8,0x00000427,0x0004003d,0x0000001c,0x00000428, + 0x000003cb,0x0007000c,0x0000001c,0x0000042a,0x00000001,0x00000028,0x00000428,0x00000510, + 0x0003003e,0x000003dd,0x0000042a,0x000200f9,0x000004ff,0x000200f8,0x00000423,0x0004003d, + 0x0000001c,0x00000424,0x000003cb,0x0007000c,0x0000001c,0x00000426,0x00000001,0x00000025, + 0x00000424,0x00000510,0x0003003e,0x000003dd,0x00000426,0x000200f9,0x000004ff,0x000200f8, + 0x00000412,0x0004003d,0x0000001c,0x00000413,0x000003cb,0x00050085,0x0000001c,0x00000415, + 0x00000413,0x00000510,0x00050081,0x0000001c,0x00000419,0x00000413,0x00000510,0x00050083, + 0x0000001c,0x0000041b,0x00000419,0x00000415,0x00050083,0x0000001c,0x0000041d,0x0000041b, + 0x00000af4,0x00060052,0x0000001c,0x00000918,0x000001c2,0x00000a5d,0x00000000,0x00060052, + 0x0000001c,0x0000091a,0x000001c2,0x00000918,0x00000001,0x00060052,0x0000001c,0x0000091c, + 0x000001c2,0x0000091a,0x00000002,0x000500ba,0x000001c8,0x00000420,0x00000510,0x0000091c, + 0x000600a9,0x0000001c,0x00000421,0x00000420,0x0000041d,0x00000415,0x0005008e,0x0000001c, + 0x00000422,0x00000421,0x000001bb,0x0003003e,0x000003dd,0x00000422,0x000200f9,0x000004ff, + 0x000200f8,0x0000040a,0x0004003d,0x0000001c,0x0000040b,0x000003cb,0x00050081,0x0000001c, + 0x0000040d,0x0000040b,0x00000510,0x00050085,0x0000001c,0x00000410,0x0000040b,0x00000510, + 0x00050083,0x0000001c,0x00000411,0x0000040d,0x00000410,0x0003003e,0x000003dd,0x00000411, + 0x000200f9,0x000004ff,0x000200f8,0x00000406,0x0004003d,0x0000001c,0x00000407,0x000003cb, + 0x00050085,0x0000001c,0x00000409,0x00000407,0x00000510,0x0003003e,0x000003dd,0x00000409, + 0x000200f9,0x000004ff,0x000200f8,0x000004ff,0x0004003d,0x0000001c,0x00000500,0x000003dd, + 0x00060052,0x0000001c,0x00000a3b,0x00000507,0x00000af8,0x00000000,0x00060052,0x0000001c, + 0x00000a3d,0x00000507,0x00000a3b,0x00000001,0x00060052,0x0000001c,0x00000a3f,0x00000507, + 0x00000a3d,0x00000002,0x0008000c,0x0000001c,0x000003da,0x00000001,0x0000002e,0x0000033c, + 0x00000500,0x00000a3f,0x00050051,0x0000000c,0x00000343,0x000003da,0x00000000,0x00060052, + 0x00000027,0x00000a41,0x00000343,0x00000910,0x00000000,0x00050051,0x0000000c,0x00000345, + 0x000003da,0x00000001,0x00060052,0x00000027,0x00000a43,0x00000345,0x00000a41,0x00000001, + 0x00050051,0x0000000c,0x00000347,0x000003da,0x00000002,0x00060052,0x00000027,0x00000a45, + 0x00000347,0x00000a43,0x00000002,0x00050051,0x0000000c,0x00000349,0x00000a45,0x00000003, + 0x0008004f,0x0000001c,0x0000034b,0x00000a45,0x00000a45,0x00000000,0x00000001,0x00000002, + 0x0005008e,0x0000001c,0x0000034c,0x0000034b,0x00000349,0x00050051,0x0000000c,0x0000034e, + 0x0000034c,0x00000000,0x00060052,0x00000027,0x00000a48,0x0000034e,0x00000a45,0x00000000, + 0x00050051,0x0000000c,0x00000350,0x0000034c,0x00000001,0x00060052,0x00000027,0x00000a4a, + 0x00000350,0x00000a48,0x00000001,0x00050051,0x0000000c,0x00000352,0x0000034c,0x00000002, + 0x00060052,0x00000027,0x00000a4c,0x00000352,0x00000a4a,0x00000002,0x0008004f,0x0000001c, + 0x00000359,0x00000a4c,0x00000a4c,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000027, + 0x0000035b,0x00000354,0x0007004f,0x00000012,0x0000035c,0x0000035b,0x0000035b,0x00000000, + 0x00000001,0x00050041,0x000002f4,0x0000035e,0x000002f3,0x00000355,0x0004003d,0x0000000c, + 0x0000035f,0x0000035e,0x00050041,0x000002f4,0x00000361,0x000002f3,0x00000356,0x0004003d, + 0x0000000c,0x00000362,0x00000361,0x000300f7,0x000008f3,0x00000000,0x000400fa,0x000000e6, + 0x000008e9,0x000008f1,0x000200f8,0x000008f1,0x000200f9,0x000008f3,0x000200f8,0x000008e9, + 0x00050051,0x0000000c,0x000008fa,0x0000035c,0x00000000,0x00050085,0x0000000c,0x000008fb, + 0x000000d0,0x000008fa,0x00050051,0x0000000c,0x000008fd,0x0000035c,0x00000001,0x00050085, + 0x0000000c,0x000008fe,0x000000d4,0x000008fd,0x00050081,0x0000000c,0x000008ff,0x000008fb, + 0x000008fe,0x0006000c,0x0000000c,0x00000900,0x00000001,0x0000000a,0x000008ff,0x00050085, + 0x0000000c,0x00000902,0x000000db,0x00000900,0x0006000c,0x0000000c,0x00000903,0x00000001, + 0x0000000a,0x00000902,0x00050085,0x0000000c,0x00000906,0x00000903,0x0000035f,0x00050081, + 0x0000000c,0x00000908,0x00000906,0x00000362,0x00060050,0x0000001c,0x000008ef,0x00000908, + 0x00000908,0x00000908,0x00050081,0x0000001c,0x000008f0,0x000008ef,0x00000359,0x000200f9, + 0x000008f3,0x000200f8,0x000008f3,0x000700f5,0x0000001c,0x00000af1,0x000008f0,0x000008e9, + 0x00000359,0x000008f1,0x00050051,0x0000000c,0x00000365,0x00000af1,0x00000000,0x00060052, + 0x00000027,0x00000a50,0x00000365,0x00000a4c,0x00000000,0x00050051,0x0000000c,0x00000367, + 0x00000af1,0x00000001,0x00060052,0x00000027,0x00000a52,0x00000367,0x00000a50,0x00000001, + 0x00050051,0x0000000c,0x00000369,0x00000af1,0x00000002,0x00060052,0x00000027,0x00000a54, + 0x00000369,0x00000a52,0x00000002,0x0003003e,0x0000036b,0x00000a54,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..509a41fec73833bd08064d824b64490375b4fdcb GIT binary patch literal 20544 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.h new file mode 100644 index 000000000..8f9f1db16 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.h @@ -0,0 +1,125 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_noclipdistance_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000010f,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000067,0x00000075,0x0000007e, + 0x0000007f,0x00000085,0x000000bb,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00060005,0x00000067,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005, + 0x0000006c,0x0000434c,0x00040006,0x0000006c,0x00000000,0x00003972,0x00040006,0x0000006c, + 0x00000001,0x00003261,0x00040006,0x0000006c,0x00000002,0x00003479,0x00040006,0x0000006c, + 0x00000003,0x00006969,0x00040006,0x0000006c,0x00000004,0x0000326b,0x00040006,0x0000006c, + 0x00000005,0x00003244,0x00040006,0x0000006c,0x00000006,0x00003056,0x00040006,0x0000006c, + 0x00000007,0x0000326e,0x00040006,0x0000006c,0x00000008,0x0000365a,0x00030005,0x0000006e, + 0x00003041,0x00030005,0x00000075,0x00004346,0x00030005,0x0000007e,0x00003055,0x00030005, + 0x0000007f,0x00004347,0x00030005,0x00000081,0x00006747,0x00030005,0x00000085,0x00003346, + 0x00030005,0x00000088,0x0000424d,0x00040006,0x00000088,0x00000000,0x00006250,0x00040006, + 0x00000088,0x00000001,0x00006359,0x00040006,0x00000088,0x00000002,0x00006552,0x00040006, + 0x00000088,0x00000003,0x00006553,0x00040006,0x00000088,0x00000004,0x0000366d,0x00040006, + 0x00000088,0x00000005,0x0000676d,0x00040006,0x00000088,0x00000006,0x00006544,0x00040006, + 0x00000088,0x00000007,0x00006545,0x00040006,0x00000088,0x00000008,0x00003755,0x00040006, + 0x00000088,0x00000009,0x0000676a,0x00040006,0x00000088,0x0000000a,0x0000635a,0x00040006, + 0x00000088,0x0000000b,0x00003157,0x00040006,0x00000088,0x0000000c,0x0000676e,0x00040006, + 0x00000088,0x0000000d,0x00003559,0x00040006,0x00000088,0x0000000e,0x0000324f,0x00040006, + 0x00000088,0x0000000f,0x00006461,0x00040006,0x00000088,0x00000010,0x00006579,0x00040006, + 0x00000088,0x00000011,0x00003376,0x00040006,0x00000088,0x00000012,0x00003377,0x00040006, + 0x00000088,0x00000013,0x00006462,0x00040006,0x00000088,0x00000014,0x00006767,0x00030005, + 0x0000008a,0x0000006b,0x00060005,0x000000b9,0x505f6c67,0x65567265,0x78657472,0x00000000, + 0x00060006,0x000000b9,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000000b9, + 0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x000000b9,0x00000002, + 0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x000000b9,0x00000003,0x435f6c67, + 0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000000bb,0x00000000,0x00040047,0x00000067, + 0x0000000b,0x0000002a,0x00030047,0x0000006c,0x00000002,0x00050048,0x0000006c,0x00000000, + 0x00000023,0x00000000,0x00050048,0x0000006c,0x00000001,0x00000023,0x00000010,0x00050048, + 0x0000006c,0x00000002,0x00000023,0x00000018,0x00050048,0x0000006c,0x00000003,0x00000023, + 0x0000001c,0x00050048,0x0000006c,0x00000004,0x00000023,0x00000020,0x00050048,0x0000006c, + 0x00000005,0x00000023,0x00000030,0x00050048,0x0000006c,0x00000006,0x00000023,0x00000038, + 0x00050048,0x0000006c,0x00000007,0x00000023,0x0000003c,0x00050048,0x0000006c,0x00000008, + 0x00000023,0x00000040,0x00040047,0x0000006e,0x00000021,0x00000002,0x00040047,0x0000006e, + 0x00000022,0x00000000,0x00040047,0x00000075,0x0000001e,0x00000000,0x00040047,0x0000007e, + 0x0000001e,0x00000000,0x00040047,0x0000007f,0x0000001e,0x00000001,0x00040047,0x00000081, + 0x00000001,0x00000000,0x00030047,0x00000085,0x00000000,0x00030047,0x00000085,0x0000000e, + 0x00040047,0x00000085,0x0000001e,0x00000001,0x00030047,0x00000088,0x00000002,0x00050048, + 0x00000088,0x00000000,0x00000023,0x00000000,0x00050048,0x00000088,0x00000001,0x00000023, + 0x00000004,0x00050048,0x00000088,0x00000002,0x00000023,0x00000008,0x00050048,0x00000088, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x00000088,0x00000004,0x00000023,0x00000010, + 0x00050048,0x00000088,0x00000005,0x00000023,0x00000014,0x00050048,0x00000088,0x00000006, + 0x00000023,0x00000018,0x00050048,0x00000088,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x00000088,0x00000008,0x00000023,0x00000020,0x00050048,0x00000088,0x00000009,0x00000023, + 0x00000030,0x00050048,0x00000088,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000088, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x00000088,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x00000088,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000088,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x00000088,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x00000088,0x00000010,0x00000023,0x00000054,0x00050048,0x00000088,0x00000011,0x00000023, + 0x00000058,0x00050048,0x00000088,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000088, + 0x00000013,0x00000023,0x00000060,0x00050048,0x00000088,0x00000014,0x00000023,0x00000064, + 0x00040047,0x0000008a,0x00000021,0x00000000,0x00040047,0x0000008a,0x00000022,0x00000000, + 0x00030047,0x000000b9,0x00000002,0x00050048,0x000000b9,0x00000000,0x0000000b,0x00000000, + 0x00050048,0x000000b9,0x00000001,0x0000000b,0x00000001,0x00050048,0x000000b9,0x00000002, + 0x0000000b,0x00000003,0x00050048,0x000000b9,0x00000003,0x0000000b,0x00000004,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000004,0x00040017,0x00000009,0x00000006,0x00000002,0x00040018, + 0x0000000a,0x00000009,0x00000002,0x00040015,0x0000000f,0x00000020,0x00000000,0x0004002b, + 0x00000006,0x0000002d,0x3f800000,0x0004002b,0x00000006,0x0000002e,0x00000000,0x0004002b, + 0x0000000f,0x00000039,0x00000000,0x00020014,0x0000003a,0x0004002b,0x0000000f,0x00000041, + 0x000003ff,0x0004002b,0x0000000f,0x00000051,0x00000001,0x0004002b,0x00000006,0x0000005e, + 0x38800000,0x00040015,0x00000063,0x00000020,0x00000001,0x00040020,0x00000066,0x00000001, + 0x00000063,0x0004003b,0x00000066,0x00000067,0x00000001,0x0004002b,0x00000063,0x0000006a, + 0x00000000,0x000b001e,0x0000006c,0x00000007,0x00000009,0x00000006,0x00000006,0x00000007, + 0x00000009,0x0000000f,0x0000000f,0x0000000f,0x00040020,0x0000006d,0x00000002,0x0000006c, + 0x0004003b,0x0000006d,0x0000006e,0x00000002,0x00040020,0x00000070,0x00000002,0x00000007, + 0x00040020,0x00000074,0x00000001,0x00000009,0x0004003b,0x00000074,0x00000075,0x00000001, + 0x0004002b,0x00000063,0x00000078,0x00000001,0x00040020,0x00000079,0x00000002,0x00000009, + 0x00040020,0x0000007d,0x00000003,0x00000009,0x0004003b,0x0000007d,0x0000007e,0x00000003, + 0x0004003b,0x00000074,0x0000007f,0x00000001,0x00030030,0x0000003a,0x00000081,0x00040020, + 0x00000084,0x00000003,0x00000006,0x0004003b,0x00000084,0x00000085,0x00000003,0x0004002b, + 0x00000063,0x00000086,0x00000006,0x00040017,0x00000087,0x00000063,0x00000004,0x0017001e, + 0x00000088,0x00000006,0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f,0x0000000f, + 0x0000000f,0x00000087,0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f,0x00000006, + 0x00000006,0x0000000f,0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020,0x00000089, + 0x00000002,0x00000088,0x0004003b,0x00000089,0x0000008a,0x00000002,0x0004002b,0x00000063, + 0x0000008b,0x0000000d,0x00040020,0x0000008d,0x00000002,0x0000000f,0x0004002b,0x00000063, + 0x000000a5,0x00000002,0x0004002b,0x00000063,0x000000a6,0x00000003,0x00040020,0x000000aa, + 0x00000002,0x00000006,0x0004002b,0x00000063,0x000000b1,0x00000008,0x0004001c,0x000000b8, + 0x00000006,0x00000051,0x0006001e,0x000000b9,0x00000007,0x00000006,0x000000b8,0x000000b8, + 0x00040020,0x000000ba,0x00000003,0x000000b9,0x0004003b,0x000000ba,0x000000bb,0x00000003, + 0x00040020,0x000000bd,0x00000003,0x00000007,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x00050041,0x00000070,0x00000071,0x0000006e,0x0000006a, + 0x0004003d,0x00000007,0x00000072,0x00000071,0x00050051,0x00000006,0x000000cf,0x00000072, + 0x00000000,0x00050051,0x00000006,0x000000d0,0x00000072,0x00000001,0x00050051,0x00000006, + 0x000000d1,0x00000072,0x00000002,0x00050051,0x00000006,0x000000d2,0x00000072,0x00000003, + 0x00050050,0x00000009,0x000000d3,0x000000cf,0x000000d0,0x00050050,0x00000009,0x000000d4, + 0x000000d1,0x000000d2,0x00050050,0x0000000a,0x000000d5,0x000000d3,0x000000d4,0x0004003d, + 0x00000009,0x00000076,0x00000075,0x00050091,0x00000009,0x00000077,0x000000d5,0x00000076, + 0x00050041,0x00000079,0x0000007a,0x0000006e,0x00000078,0x0004003d,0x00000009,0x0000007b, + 0x0000007a,0x00050081,0x00000009,0x0000007c,0x00000077,0x0000007b,0x0004003d,0x00000009, + 0x00000080,0x0000007f,0x0003003e,0x0000007e,0x00000080,0x000300f7,0x00000083,0x00000000, + 0x000400fa,0x00000081,0x00000082,0x00000083,0x000200f8,0x00000082,0x00050041,0x0000008d, + 0x0000008e,0x0000006e,0x00000086,0x0004003d,0x0000000f,0x0000008f,0x0000008e,0x00050041, + 0x0000008d,0x00000091,0x0000008a,0x0000008b,0x0004003d,0x0000000f,0x00000092,0x00000091, + 0x000500aa,0x0000003a,0x000000db,0x0000008f,0x00000039,0x000300f7,0x000000e4,0x00000000, + 0x000400fa,0x000000db,0x000000dc,0x000000dd,0x000200f8,0x000000dc,0x000200f9,0x000000e4, + 0x000200f8,0x000000dd,0x00050080,0x0000000f,0x000000df,0x0000008f,0x00000041,0x00050084, + 0x0000000f,0x000000e1,0x000000df,0x00000092,0x0006000c,0x00000009,0x000000e2,0x00000001, + 0x0000003e,0x000000e1,0x00050051,0x00000006,0x000000e3,0x000000e2,0x00000000,0x000200f9, + 0x000000e4,0x000200f8,0x000000e4,0x000700f5,0x00000006,0x0000010e,0x0000002e,0x000000dc, + 0x000000e3,0x000000dd,0x0003003e,0x00000085,0x0000010e,0x000200f9,0x00000083,0x000200f8, + 0x00000083,0x00050041,0x000000aa,0x000000ab,0x0000008a,0x000000a5,0x0004003d,0x00000006, + 0x000000ac,0x000000ab,0x00050041,0x000000aa,0x000000ae,0x0000008a,0x000000a6,0x0004003d, + 0x00000006,0x000000af,0x000000ae,0x00050051,0x00000006,0x000000f8,0x0000007c,0x00000000, + 0x00050085,0x00000006,0x000000fa,0x000000f8,0x000000ac,0x00050083,0x00000006,0x000000fb, + 0x000000fa,0x0000002d,0x00050051,0x00000006,0x000000fd,0x0000007c,0x00000001,0x00050085, + 0x00000006,0x000000ff,0x000000fd,0x000000af,0x0006000c,0x00000006,0x00000101,0x00000001, + 0x00000006,0x000000af,0x00050083,0x00000006,0x00000102,0x000000ff,0x00000101,0x00070050, + 0x00000007,0x00000103,0x000000fb,0x00000102,0x0000002e,0x0000002d,0x00050041,0x0000008d, + 0x000000b3,0x0000006e,0x000000b1,0x0004003d,0x0000000f,0x000000b4,0x000000b3,0x00040070, + 0x00000006,0x00000107,0x000000b4,0x00050085,0x00000006,0x00000108,0x00000107,0x0000005e, + 0x00050083,0x00000006,0x00000109,0x0000002d,0x00000108,0x00060052,0x00000007,0x0000010d, + 0x00000109,0x00000103,0x00000002,0x00050041,0x000000bd,0x000000be,0x000000bb,0x0000006a, + 0x0003003e,0x000000be,0x0000010d,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..dac01e54a6a52ecc0936f8e617ce022bee5cfd04 GIT binary patch literal 3860 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.h new file mode 100644 index 000000000..f5726998b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.h @@ -0,0 +1,113 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_webgpu_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000000b2,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0009000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000055,0x00000069,0x00000081, + 0x00000084,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00070004,0x4f5f4c47, + 0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x0000004c,0x00004344,0x00030005,0x00000050,0x00003552,0x00030005, + 0x00000055,0x00003055,0x00030005,0x00000059,0x0000424d,0x00040006,0x00000059,0x00000000, + 0x00006250,0x00040006,0x00000059,0x00000001,0x00006359,0x00040006,0x00000059,0x00000002, + 0x00006552,0x00040006,0x00000059,0x00000003,0x00006553,0x00040006,0x00000059,0x00000004, + 0x0000366d,0x00040006,0x00000059,0x00000005,0x0000676d,0x00040006,0x00000059,0x00000006, + 0x00006544,0x00040006,0x00000059,0x00000007,0x00006545,0x00040006,0x00000059,0x00000008, + 0x00003755,0x00040006,0x00000059,0x00000009,0x0000676a,0x00040006,0x00000059,0x0000000a, + 0x0000635a,0x00040006,0x00000059,0x0000000b,0x00003157,0x00040006,0x00000059,0x0000000c, + 0x0000676e,0x00040006,0x00000059,0x0000000d,0x00003559,0x00040006,0x00000059,0x0000000e, + 0x0000324f,0x00040006,0x00000059,0x0000000f,0x00006461,0x00040006,0x00000059,0x00000010, + 0x00006579,0x00040006,0x00000059,0x00000011,0x00003376,0x00040006,0x00000059,0x00000012, + 0x00003377,0x00040006,0x00000059,0x00000013,0x00006462,0x00040006,0x00000059,0x00000014, + 0x00006767,0x00030005,0x0000005b,0x0000006b,0x00030005,0x00000061,0x0000434c,0x00040006, + 0x00000061,0x00000000,0x00003972,0x00040006,0x00000061,0x00000001,0x00003261,0x00040006, + 0x00000061,0x00000002,0x00003479,0x00040006,0x00000061,0x00000003,0x00006969,0x00040006, + 0x00000061,0x00000004,0x0000326b,0x00040006,0x00000061,0x00000005,0x00003244,0x00040006, + 0x00000061,0x00000006,0x00003056,0x00040006,0x00000061,0x00000007,0x0000326e,0x00040006, + 0x00000061,0x00000008,0x0000365a,0x00030005,0x00000063,0x00003041,0x00060005,0x00000069, + 0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x00000081,0x00006771,0x00030005, + 0x00000084,0x00003346,0x00030005,0x00000085,0x0000444a,0x00030047,0x0000004c,0x00000000, + 0x00040047,0x0000004c,0x00000021,0x0000000c,0x00040047,0x0000004c,0x00000022,0x00000001, + 0x00030047,0x0000004d,0x00000000,0x00030047,0x00000050,0x00000000,0x00040047,0x00000050, + 0x00000021,0x0000000e,0x00040047,0x00000050,0x00000022,0x00000001,0x00030047,0x00000051, + 0x00000000,0x00040047,0x00000055,0x0000001e,0x00000000,0x00030047,0x00000059,0x00000002, + 0x00050048,0x00000059,0x00000000,0x00000023,0x00000000,0x00050048,0x00000059,0x00000001, + 0x00000023,0x00000004,0x00050048,0x00000059,0x00000002,0x00000023,0x00000008,0x00050048, + 0x00000059,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000059,0x00000004,0x00000023, + 0x00000010,0x00050048,0x00000059,0x00000005,0x00000023,0x00000014,0x00050048,0x00000059, + 0x00000006,0x00000023,0x00000018,0x00050048,0x00000059,0x00000007,0x00000023,0x0000001c, + 0x00050048,0x00000059,0x00000008,0x00000023,0x00000020,0x00050048,0x00000059,0x00000009, + 0x00000023,0x00000030,0x00050048,0x00000059,0x0000000a,0x00000023,0x00000038,0x00050048, + 0x00000059,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000059,0x0000000c,0x00000023, + 0x00000044,0x00050048,0x00000059,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000059, + 0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000059,0x0000000f,0x00000023,0x00000050, + 0x00050048,0x00000059,0x00000010,0x00000023,0x00000054,0x00050048,0x00000059,0x00000011, + 0x00000023,0x00000058,0x00050048,0x00000059,0x00000012,0x00000023,0x0000005c,0x00050048, + 0x00000059,0x00000013,0x00000023,0x00000060,0x00050048,0x00000059,0x00000014,0x00000023, + 0x00000064,0x00040047,0x0000005b,0x00000021,0x00000000,0x00040047,0x0000005b,0x00000022, + 0x00000000,0x00030047,0x00000061,0x00000002,0x00050048,0x00000061,0x00000000,0x00000023, + 0x00000000,0x00050048,0x00000061,0x00000001,0x00000023,0x00000010,0x00050048,0x00000061, + 0x00000002,0x00000023,0x00000018,0x00050048,0x00000061,0x00000003,0x00000023,0x0000001c, + 0x00050048,0x00000061,0x00000004,0x00000023,0x00000020,0x00050048,0x00000061,0x00000005, + 0x00000023,0x00000030,0x00050048,0x00000061,0x00000006,0x00000023,0x00000038,0x00050048, + 0x00000061,0x00000007,0x00000023,0x0000003c,0x00050048,0x00000061,0x00000008,0x00000023, + 0x00000040,0x00040047,0x00000063,0x00000021,0x00000002,0x00040047,0x00000063,0x00000022, + 0x00000000,0x00040047,0x00000069,0x0000000b,0x0000000f,0x00030047,0x0000006e,0x00000000, + 0x00030047,0x00000081,0x00000000,0x00040047,0x00000081,0x0000001e,0x00000000,0x00030047, + 0x00000084,0x00000000,0x00030047,0x00000084,0x0000000e,0x00040047,0x00000084,0x0000001e, + 0x00000001,0x00030047,0x00000085,0x00000000,0x00040047,0x00000085,0x00000021,0x0000000d, + 0x00040047,0x00000085,0x00000022,0x00000000,0x00030047,0x00000092,0x00000000,0x00030047, + 0x00000093,0x00000000,0x00030047,0x000000a3,0x00000000,0x00030047,0x000000a4,0x00000000, + 0x00030047,0x000000a7,0x00000000,0x00030047,0x000000a9,0x00000000,0x00030047,0x000000ad, + 0x00000000,0x00030047,0x000000af,0x00000000,0x00030047,0x000000b1,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000002,0x00040017,0x00000010,0x00000006,0x00000003,0x0004002b, + 0x00000006,0x0000001a,0x3d897143,0x00040015,0x0000001b,0x00000020,0x00000000,0x0004002b, + 0x00000006,0x00000020,0x3bbf4590,0x0004002b,0x00000006,0x00000028,0x4253ee82,0x00040017, + 0x00000047,0x00000006,0x00000004,0x00090019,0x0000004a,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x0000004b,0x00000000,0x0000004a, + 0x0004003b,0x0000004b,0x0000004c,0x00000000,0x0002001a,0x0000004e,0x00040020,0x0000004f, + 0x00000000,0x0000004e,0x0004003b,0x0000004f,0x00000050,0x00000000,0x0003001b,0x00000052, + 0x0000004a,0x00040020,0x00000054,0x00000001,0x00000007,0x0004003b,0x00000054,0x00000055, + 0x00000001,0x00040015,0x00000057,0x00000020,0x00000001,0x00040017,0x00000058,0x00000057, + 0x00000004,0x0017001e,0x00000059,0x00000006,0x00000006,0x00000006,0x00000006,0x0000001b, + 0x0000001b,0x0000001b,0x0000001b,0x00000058,0x00000007,0x00000007,0x0000001b,0x00000006, + 0x0000001b,0x00000006,0x00000006,0x0000001b,0x00000006,0x00000006,0x00000006,0x0000001b, + 0x00040020,0x0000005a,0x00000002,0x00000059,0x0004003b,0x0000005a,0x0000005b,0x00000002, + 0x0004002b,0x00000057,0x0000005c,0x0000000f,0x00040020,0x0000005d,0x00000002,0x00000006, + 0x000b001e,0x00000061,0x00000047,0x00000007,0x00000006,0x00000006,0x00000047,0x00000007, + 0x0000001b,0x0000001b,0x0000001b,0x00040020,0x00000062,0x00000002,0x00000061,0x0004003b, + 0x00000062,0x00000063,0x00000002,0x0004002b,0x00000057,0x00000064,0x00000002,0x00040020, + 0x00000068,0x00000001,0x00000047,0x0004003b,0x00000068,0x00000069,0x00000001,0x0004002b, + 0x00000057,0x0000006a,0x00000011,0x0004002b,0x00000057,0x0000006b,0x00000012,0x00040020, + 0x00000080,0x00000003,0x00000047,0x0004003b,0x00000080,0x00000081,0x00000003,0x00040020, + 0x00000083,0x00000001,0x00000006,0x0004003b,0x00000083,0x00000084,0x00000001,0x0004003b, + 0x0000004b,0x00000085,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003d,0x0000004a,0x0000004d,0x0000004c,0x0004003d,0x0000004e, + 0x00000051,0x00000050,0x00050056,0x00000052,0x00000053,0x0000004d,0x00000051,0x0004003d, + 0x00000007,0x00000056,0x00000055,0x00050041,0x0000005d,0x0000005e,0x0000005b,0x0000005c, + 0x0004003d,0x00000006,0x0000005f,0x0000005e,0x00070057,0x00000047,0x00000060,0x00000053, + 0x00000056,0x00000001,0x0000005f,0x00050041,0x0000005d,0x00000065,0x00000063,0x00000064, + 0x0004003d,0x00000006,0x00000066,0x00000065,0x0005008e,0x00000047,0x00000067,0x00000060, + 0x00000066,0x0008004f,0x00000010,0x0000006e,0x00000067,0x00000067,0x00000000,0x00000001, + 0x00000002,0x0004003d,0x00000047,0x00000070,0x00000069,0x00050041,0x0000005d,0x00000073, + 0x0000005b,0x0000006a,0x0004003d,0x00000006,0x00000074,0x00000073,0x00050041,0x0000005d, + 0x00000076,0x0000005b,0x0000006b,0x0004003d,0x00000006,0x00000077,0x00000076,0x00050051, + 0x00000006,0x0000009b,0x00000070,0x00000000,0x00050085,0x00000006,0x0000009c,0x0000001a, + 0x0000009b,0x00050051,0x00000006,0x0000009e,0x00000070,0x00000001,0x00050085,0x00000006, + 0x0000009f,0x00000020,0x0000009e,0x00050081,0x00000006,0x000000a0,0x0000009c,0x0000009f, + 0x0006000c,0x00000006,0x000000a1,0x00000001,0x0000000a,0x000000a0,0x00050085,0x00000006, + 0x000000a3,0x00000028,0x000000a1,0x0006000c,0x00000006,0x000000a4,0x00000001,0x0000000a, + 0x000000a3,0x00050085,0x00000006,0x000000a7,0x000000a4,0x00000074,0x00050081,0x00000006, + 0x000000a9,0x000000a7,0x00000077,0x00060050,0x00000010,0x00000092,0x000000a9,0x000000a9, + 0x000000a9,0x00050081,0x00000010,0x00000093,0x00000092,0x0000006e,0x00050051,0x00000006, + 0x0000007a,0x00000093,0x00000000,0x00060052,0x00000047,0x000000ad,0x0000007a,0x00000067, + 0x00000000,0x00050051,0x00000006,0x0000007c,0x00000093,0x00000001,0x00060052,0x00000047, + 0x000000af,0x0000007c,0x000000ad,0x00000001,0x00050051,0x00000006,0x0000007f,0x00000093, + 0x00000002,0x00060052,0x00000047,0x000000b1,0x0000007f,0x000000af,0x00000002,0x0003003e, + 0x00000081,0x000000b1,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..535c822f7f2c49061cf374ba560e7a841e8e87f8 GIT binary patch literal 3472 zcmZ9OUvHE}6vn6Qww4y5fPcX>Te&eYA*g^D#L#~%!Nn~tZD~>8zPtOjY}szh?zUKC zqO0Y?8)M{BqZmkt7slup;0y3sy!OV#=lAX$-iec(%z2)9&dixJGw*J0--+j(>vO|y z(Ea6l?XcS?#)%t9`(kOXbh6#4ojiT!6pDi`mkQAwa{FCgJ+=|on+(j$>awnEPc|Yw z<61~wPP04rRKa;SHVD{6N(Tk%>FRkl}G1ve|}Nwp*0FuLg**Q0j4 zvDHXgjilX~39?N$=4Za1r)`ew7OX>HD8xm+wwN7bz@&AHo1qDH-$M74TL^VN3} zbc4+4b@gVov0V!Vd1b5d^7NcvGunw;^|+#yUB9Bk{q}25C9OR*=`@yeGxBH8^n7YD zud2Z>$-g?`RMmXy3%Z#~hNb!e88>h~7U0{o+ z&bI?Sb)E_^bzaaJo1Qv1gK_G-taBnamD7!<_hBG?BWsQ5lCJ#Z=4MMf>uI{`@A!S~ z$-kr;5PMJll_}?n^0{xcqV|YCCgVH|zb>DBqP?n~hCkDDQyo5WoD*^2Fz%W#jWO== zXo`CCaF?muWo3p>JJIW&ajXwV{Y*y;95pd6=Q;8>ju>4t3RBb=lemdo##by?5C=JOvWAzXZy>iZ;f-L_Ut$P zq4IuLJ&id0@Sg9bBfS`Wdn@?p`ee+<+oUlEKDlro3}?CI+z;Yu#NF??ssAwW9|iv7 z!2d1qe-HdW0{>6%A5}G|$C%dPOz>ZlM~w@zmz68E1v3WbY{BT?6vjU$o4oVwg%^d7 z%P+`iHeQhb{q&RbhTjnW`tP|3<}1o)j=bzu{a3i+F?9=@;ewPO`T?}(J?8z;jw#cR z)T1k>j7u>(@QmkJs8z#49>8L+zkQ?}>=cp-p@ZPz*=s)pe%rUC}MzMP8%(`%x;V?g9D;i@h zVpt2z+kvySY96D%CBIL`eCWaYX-qlOuM6|7GR*HV-znn1QqNtocyQNqjDI7a`N^62 z!F!$qa~JGwoz-`UJUJ5@^Zp}-@5lwQoHf67+!ZkQgx@gk#DY}ZhdCJCs)zqq(dT6U0kqT+-~a#s literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.h new file mode 100644 index 000000000..b98a87f15 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.h @@ -0,0 +1,471 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_webgpu_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000a36,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0009000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x000002ac,0x000002d2,0x00000308, + 0x0000030b,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865, + 0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45, + 0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47, + 0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00070004,0x4f5f4c47, + 0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x000002a3,0x00004344,0x00030005,0x000002a7,0x00003552,0x00030005, + 0x000002ac,0x00003055,0x00030005,0x000002af,0x0000424d,0x00040006,0x000002af,0x00000000, + 0x00006250,0x00040006,0x000002af,0x00000001,0x00006359,0x00040006,0x000002af,0x00000002, + 0x00006552,0x00040006,0x000002af,0x00000003,0x00006553,0x00040006,0x000002af,0x00000004, + 0x0000366d,0x00040006,0x000002af,0x00000005,0x0000676d,0x00040006,0x000002af,0x00000006, + 0x00006544,0x00040006,0x000002af,0x00000007,0x00006545,0x00040006,0x000002af,0x00000008, + 0x00003755,0x00040006,0x000002af,0x00000009,0x0000676a,0x00040006,0x000002af,0x0000000a, + 0x0000635a,0x00040006,0x000002af,0x0000000b,0x00003157,0x00040006,0x000002af,0x0000000c, + 0x0000676e,0x00040006,0x000002af,0x0000000d,0x00003559,0x00040006,0x000002af,0x0000000e, + 0x0000324f,0x00040006,0x000002af,0x0000000f,0x00006461,0x00040006,0x000002af,0x00000010, + 0x00006579,0x00040006,0x000002af,0x00000011,0x00003376,0x00040006,0x000002af,0x00000012, + 0x00003377,0x00040006,0x000002af,0x00000013,0x00006462,0x00040006,0x000002af,0x00000014, + 0x00006767,0x00030005,0x000002b1,0x0000006b,0x00030005,0x000002b7,0x0000434c,0x00040006, + 0x000002b7,0x00000000,0x00003972,0x00040006,0x000002b7,0x00000001,0x00003261,0x00040006, + 0x000002b7,0x00000002,0x00003479,0x00040006,0x000002b7,0x00000003,0x00006969,0x00040006, + 0x000002b7,0x00000004,0x0000326b,0x00040006,0x000002b7,0x00000005,0x00003244,0x00040006, + 0x000002b7,0x00000006,0x00003056,0x00040006,0x000002b7,0x00000007,0x0000326e,0x00040006, + 0x000002b7,0x00000008,0x0000365a,0x00030005,0x000002b9,0x00003041,0x00030005,0x000002cf, + 0x0000444a,0x00060005,0x000002d2,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x00000308,0x00006771,0x00030005,0x0000030b,0x00003346,0x00030047,0x000002a3,0x00000000, + 0x00040047,0x000002a3,0x00000021,0x0000000c,0x00040047,0x000002a3,0x00000022,0x00000001, + 0x00030047,0x000002a4,0x00000000,0x00030047,0x000002a7,0x00000000,0x00040047,0x000002a7, + 0x00000021,0x0000000e,0x00040047,0x000002a7,0x00000022,0x00000001,0x00030047,0x000002a8, + 0x00000000,0x00040047,0x000002ac,0x0000001e,0x00000000,0x00030047,0x000002af,0x00000002, + 0x00050048,0x000002af,0x00000000,0x00000023,0x00000000,0x00050048,0x000002af,0x00000001, + 0x00000023,0x00000004,0x00050048,0x000002af,0x00000002,0x00000023,0x00000008,0x00050048, + 0x000002af,0x00000003,0x00000023,0x0000000c,0x00050048,0x000002af,0x00000004,0x00000023, + 0x00000010,0x00050048,0x000002af,0x00000005,0x00000023,0x00000014,0x00050048,0x000002af, + 0x00000006,0x00000023,0x00000018,0x00050048,0x000002af,0x00000007,0x00000023,0x0000001c, + 0x00050048,0x000002af,0x00000008,0x00000023,0x00000020,0x00050048,0x000002af,0x00000009, + 0x00000023,0x00000030,0x00050048,0x000002af,0x0000000a,0x00000023,0x00000038,0x00050048, + 0x000002af,0x0000000b,0x00000023,0x00000040,0x00050048,0x000002af,0x0000000c,0x00000023, + 0x00000044,0x00050048,0x000002af,0x0000000d,0x00000023,0x00000048,0x00050048,0x000002af, + 0x0000000e,0x00000023,0x0000004c,0x00050048,0x000002af,0x0000000f,0x00000023,0x00000050, + 0x00050048,0x000002af,0x00000010,0x00000023,0x00000054,0x00050048,0x000002af,0x00000011, + 0x00000023,0x00000058,0x00050048,0x000002af,0x00000012,0x00000023,0x0000005c,0x00050048, + 0x000002af,0x00000013,0x00000023,0x00000060,0x00050048,0x000002af,0x00000014,0x00000023, + 0x00000064,0x00040047,0x000002b1,0x00000021,0x00000000,0x00040047,0x000002b1,0x00000022, + 0x00000000,0x00030047,0x000002b7,0x00000002,0x00050048,0x000002b7,0x00000000,0x00000023, + 0x00000000,0x00050048,0x000002b7,0x00000001,0x00000023,0x00000010,0x00050048,0x000002b7, + 0x00000002,0x00000023,0x00000018,0x00050048,0x000002b7,0x00000003,0x00000023,0x0000001c, + 0x00050048,0x000002b7,0x00000004,0x00000023,0x00000020,0x00050048,0x000002b7,0x00000005, + 0x00000023,0x00000030,0x00050048,0x000002b7,0x00000006,0x00000023,0x00000038,0x00050048, + 0x000002b7,0x00000007,0x00000023,0x0000003c,0x00050048,0x000002b7,0x00000008,0x00000023, + 0x00000040,0x00040047,0x000002b9,0x00000021,0x00000002,0x00040047,0x000002b9,0x00000022, + 0x00000000,0x00030047,0x000002cf,0x00000000,0x00040047,0x000002cf,0x00000021,0x0000000d, + 0x00040047,0x000002cf,0x00000022,0x00000000,0x00030047,0x000002d0,0x00000000,0x00030047, + 0x000002d2,0x00000000,0x00040047,0x000002d2,0x0000000b,0x0000000f,0x00030047,0x000002d3, + 0x00000000,0x00030047,0x000002d4,0x00000000,0x00030047,0x000002d5,0x00000000,0x00030047, + 0x000002d7,0x00000000,0x00030047,0x000002d8,0x00000000,0x00030047,0x000002db,0x00000000, + 0x00030047,0x000002ea,0x00000000,0x00030047,0x000002eb,0x00000000,0x00030047,0x000002f6, + 0x00000000,0x00030047,0x00000308,0x00000000,0x00040047,0x00000308,0x0000001e,0x00000000, + 0x00030047,0x0000030b,0x00000000,0x00030047,0x0000030b,0x0000000e,0x00040047,0x0000030b, + 0x0000001e,0x00000001,0x00030047,0x00000310,0x00000000,0x00030047,0x00000312,0x00000000, + 0x00030047,0x00000318,0x00000000,0x00030047,0x0000031b,0x00000000,0x00030047,0x00000322, + 0x00000000,0x00030047,0x00000331,0x00000000,0x00030047,0x00000332,0x00000000,0x00030047, + 0x00000334,0x00000000,0x00030047,0x0000035f,0x00000000,0x00030047,0x00000362,0x00000000, + 0x00030047,0x00000369,0x00000000,0x00030047,0x0000036c,0x00000000,0x00030047,0x00000373, + 0x00000000,0x00030047,0x00000376,0x00000000,0x00030047,0x0000037e,0x00000000,0x00030047, + 0x00000381,0x00000000,0x00030047,0x00000388,0x00000000,0x00030047,0x0000038a,0x00000000, + 0x00030047,0x0000038c,0x00000000,0x00030047,0x0000038e,0x00000000,0x00030047,0x0000038f, + 0x00000000,0x00030047,0x00000392,0x00000000,0x00030047,0x00000393,0x00000000,0x00030047, + 0x00000394,0x00000000,0x00030047,0x0000039d,0x00000000,0x00030047,0x000003a2,0x00000000, + 0x00030047,0x000003a8,0x00000000,0x00030047,0x000003a9,0x00000000,0x00030047,0x000003aa, + 0x00000000,0x00030047,0x000003b0,0x00000000,0x00030047,0x000003b1,0x00000000,0x00030047, + 0x000003b2,0x00000000,0x00030047,0x000003b5,0x00000000,0x00030047,0x000003b6,0x00000000, + 0x00030047,0x000003b7,0x00000000,0x00030047,0x000003be,0x00000000,0x00030047,0x000003bf, + 0x00000000,0x00030047,0x000003c8,0x00000000,0x00030047,0x000003c9,0x00000000,0x00030047, + 0x000003cb,0x00000000,0x00030047,0x000003cc,0x00000000,0x00030047,0x000003cd,0x00000000, + 0x00030047,0x000003ce,0x00000000,0x00030047,0x000003cf,0x00000000,0x00030047,0x000003d1, + 0x00000000,0x00030047,0x000003d3,0x00000000,0x00030047,0x000003d7,0x00000000,0x00030047, + 0x000003d9,0x00000000,0x00030047,0x000003db,0x00000000,0x00030047,0x000003de,0x00000000, + 0x00030047,0x000003df,0x00000000,0x00030047,0x000003e0,0x00000000,0x00030047,0x000003e2, + 0x00000000,0x00030047,0x000003e5,0x00000000,0x00030047,0x000003ea,0x00000000,0x00030047, + 0x000003eb,0x00000000,0x00030047,0x000003f9,0x00000000,0x00030047,0x000003fb,0x00000000, + 0x00030047,0x000003fc,0x00000000,0x00030047,0x000003fd,0x00000000,0x00030047,0x00000400, + 0x00000000,0x00030047,0x00000403,0x00000000,0x00030047,0x00000404,0x00000000,0x00030047, + 0x00000405,0x00000000,0x00030047,0x00000407,0x00000000,0x00030047,0x0000040a,0x00000000, + 0x00030047,0x0000040b,0x00000000,0x00030047,0x0000040d,0x00000000,0x00030047,0x00000413, + 0x00000000,0x00030047,0x00000414,0x00000000,0x00030047,0x0000041b,0x00000000,0x00030047, + 0x0000041d,0x00000000,0x00030047,0x00000420,0x00000000,0x00030047,0x00000423,0x00000000, + 0x00030047,0x00000426,0x00000000,0x00030047,0x00000428,0x00000000,0x00030047,0x00000429, + 0x00000000,0x00030047,0x0000042c,0x00000000,0x00030047,0x0000042f,0x00000000,0x00030047, + 0x00000430,0x00000000,0x00030047,0x00000432,0x00000000,0x00030047,0x00000434,0x00000000, + 0x00030047,0x00000436,0x00000000,0x00030047,0x00000438,0x00000000,0x00030047,0x0000043a, + 0x00000000,0x00030047,0x0000043c,0x00000000,0x00030047,0x00000440,0x00000000,0x00030047, + 0x00000442,0x00000000,0x00030047,0x00000444,0x00000000,0x00030047,0x00000447,0x00000000, + 0x00030047,0x00000448,0x00000000,0x00030047,0x00000449,0x00000000,0x00030047,0x0000044b, + 0x00000000,0x00030047,0x0000044d,0x00000000,0x00030047,0x00000450,0x00000000,0x00030047, + 0x00000451,0x00000000,0x00030047,0x00000453,0x00000000,0x00030047,0x00000455,0x00000000, + 0x00030047,0x00000457,0x00000000,0x00030047,0x0000045c,0x00000000,0x00030047,0x0000045e, + 0x00000000,0x00030047,0x00000464,0x00000000,0x00030047,0x00000467,0x00000000,0x00030047, + 0x00000491,0x00000000,0x00030047,0x00000492,0x00000000,0x00030047,0x00000494,0x00000000, + 0x00030047,0x0000049a,0x00000000,0x00030047,0x0000049e,0x00000000,0x00030047,0x0000049f, + 0x00000000,0x00030047,0x000004a2,0x00000000,0x00030047,0x000004a4,0x00000000,0x00030047, + 0x000004a5,0x00000000,0x00030047,0x000004a6,0x00000000,0x00030047,0x000004a9,0x00000000, + 0x00030047,0x000004ab,0x00000000,0x00030047,0x000004ac,0x00000000,0x00030047,0x000004b4, + 0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004e8,0x00000000,0x00030047, + 0x000004e9,0x00000000,0x00030047,0x000004ed,0x00000000,0x00030047,0x000004ef,0x00000000, + 0x00030047,0x000004f0,0x00000000,0x00030047,0x000004f9,0x00000000,0x00030047,0x00000500, + 0x00000000,0x00030047,0x00000535,0x00000000,0x00030047,0x00000536,0x00000000,0x00030047, + 0x00000538,0x00000000,0x00030047,0x0000053e,0x00000000,0x00030047,0x00000542,0x00000000, + 0x00030047,0x00000543,0x00000000,0x00030047,0x00000546,0x00000000,0x00030047,0x00000548, + 0x00000000,0x00030047,0x00000549,0x00000000,0x00030047,0x0000054a,0x00000000,0x00030047, + 0x0000054d,0x00000000,0x00030047,0x0000054f,0x00000000,0x00030047,0x00000550,0x00000000, + 0x00030047,0x00000558,0x00000000,0x00030047,0x0000056a,0x00000000,0x00030047,0x0000058c, + 0x00000000,0x00030047,0x0000058d,0x00000000,0x00030047,0x00000591,0x00000000,0x00030047, + 0x00000593,0x00000000,0x00030047,0x00000594,0x00000000,0x00030047,0x0000059d,0x00000000, + 0x00030047,0x000005a4,0x00000000,0x00030047,0x000005d3,0x00000000,0x00030047,0x000005d7, + 0x00000000,0x00030047,0x000005d8,0x00000000,0x00030047,0x000005eb,0x00000000,0x00030047, + 0x000005ec,0x00000000,0x00030047,0x000005f0,0x00000000,0x00030047,0x000005f2,0x00000000, + 0x00030047,0x000005f3,0x00000000,0x00030047,0x000005fc,0x00000000,0x00030047,0x00000603, + 0x00000000,0x00030047,0x0000060b,0x00000000,0x00030047,0x0000060c,0x00000000,0x00030047, + 0x00000610,0x00000000,0x00030047,0x00000612,0x00000000,0x00030047,0x00000613,0x00000000, + 0x00030047,0x0000061b,0x00000000,0x00030047,0x0000061c,0x00000000,0x00030047,0x00000620, + 0x00000000,0x00030047,0x00000622,0x00000000,0x00030047,0x00000623,0x00000000,0x00030047, + 0x00000639,0x00000000,0x00030047,0x0000063a,0x00000000,0x00030047,0x0000063c,0x00000000, + 0x00030047,0x00000642,0x00000000,0x00030047,0x00000646,0x00000000,0x00030047,0x00000647, + 0x00000000,0x00030047,0x0000064a,0x00000000,0x00030047,0x0000064c,0x00000000,0x00030047, + 0x0000064d,0x00000000,0x00030047,0x0000064e,0x00000000,0x00030047,0x00000651,0x00000000, + 0x00030047,0x00000653,0x00000000,0x00030047,0x00000654,0x00000000,0x00030047,0x0000065c, + 0x00000000,0x00030047,0x0000066e,0x00000000,0x00030047,0x00000690,0x00000000,0x00030047, + 0x00000691,0x00000000,0x00030047,0x00000695,0x00000000,0x00030047,0x00000697,0x00000000, + 0x00030047,0x00000698,0x00000000,0x00030047,0x000006a1,0x00000000,0x00030047,0x000006a8, + 0x00000000,0x00030047,0x000006d7,0x00000000,0x00030047,0x000006db,0x00000000,0x00030047, + 0x000006dc,0x00000000,0x00030047,0x000006ef,0x00000000,0x00030047,0x000006f0,0x00000000, + 0x00030047,0x000006f4,0x00000000,0x00030047,0x000006f6,0x00000000,0x00030047,0x000006f7, + 0x00000000,0x00030047,0x00000700,0x00000000,0x00030047,0x00000707,0x00000000,0x00030047, + 0x0000070f,0x00000000,0x00030047,0x00000710,0x00000000,0x00030047,0x00000714,0x00000000, + 0x00030047,0x00000716,0x00000000,0x00030047,0x00000717,0x00000000,0x00030047,0x0000071f, + 0x00000000,0x00030047,0x00000720,0x00000000,0x00030047,0x00000724,0x00000000,0x00030047, + 0x00000726,0x00000000,0x00030047,0x00000727,0x00000000,0x00030047,0x0000073d,0x00000000, + 0x00030047,0x0000073e,0x00000000,0x00030047,0x00000740,0x00000000,0x00030047,0x00000746, + 0x00000000,0x00030047,0x0000074a,0x00000000,0x00030047,0x0000074b,0x00000000,0x00030047, + 0x0000074e,0x00000000,0x00030047,0x00000750,0x00000000,0x00030047,0x00000751,0x00000000, + 0x00030047,0x00000752,0x00000000,0x00030047,0x00000755,0x00000000,0x00030047,0x00000757, + 0x00000000,0x00030047,0x00000758,0x00000000,0x00030047,0x00000760,0x00000000,0x00030047, + 0x00000772,0x00000000,0x00030047,0x00000794,0x00000000,0x00030047,0x00000795,0x00000000, + 0x00030047,0x00000799,0x00000000,0x00030047,0x0000079b,0x00000000,0x00030047,0x0000079c, + 0x00000000,0x00030047,0x000007a5,0x00000000,0x00030047,0x000007ac,0x00000000,0x00030047, + 0x00000846,0x00000000,0x00030047,0x00000847,0x00000000,0x00030047,0x00000857,0x00000000, + 0x00030047,0x00000858,0x00000000,0x00030047,0x0000085b,0x00000000,0x00030047,0x0000085d, + 0x00000000,0x00030047,0x00000861,0x00000000,0x00030047,0x00000863,0x00000000,0x00030047, + 0x00000865,0x00000000,0x00030047,0x00000949,0x00000000,0x00030047,0x0000094b,0x00000000, + 0x00030047,0x0000094d,0x00000000,0x00030047,0x00000966,0x00000000,0x00030047,0x00000968, + 0x00000000,0x00030047,0x0000096a,0x00000000,0x00030047,0x00000992,0x00000000,0x00030047, + 0x00000994,0x00000000,0x00030047,0x00000996,0x00000000,0x00030047,0x00000999,0x00000000, + 0x00030047,0x0000099b,0x00000000,0x00030047,0x0000099d,0x00000000,0x00030047,0x000009a1, + 0x00000000,0x00030047,0x000009a3,0x00000000,0x00030047,0x000009a5,0x00000000,0x00030047, + 0x000009a6,0x00000000,0x00030047,0x000009a8,0x00000000,0x00030047,0x000009ef,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020, + 0x00000000,0x00030016,0x0000000c,0x00000020,0x00040020,0x0000000d,0x00000007,0x0000000c, + 0x00040017,0x00000012,0x0000000c,0x00000002,0x00040017,0x0000001c,0x0000000c,0x00000003, + 0x00040017,0x00000027,0x0000000c,0x00000004,0x00040020,0x00000032,0x00000007,0x0000001c, + 0x0004002b,0x0000000c,0x00000097,0x00000000,0x00020014,0x00000098,0x0004002b,0x0000000c, + 0x0000009d,0x3f800000,0x0004002b,0x0000000c,0x000000c7,0x3d897143,0x0004002b,0x0000000c, + 0x000000cb,0x3bbf4590,0x0004002b,0x0000000c,0x000000d2,0x4253ee82,0x0004002b,0x0000000c, + 0x000000f1,0x3e99999a,0x0004002b,0x0000000c,0x000000f2,0x3f170a3d,0x0004002b,0x0000000c, + 0x000000f3,0x3de147ae,0x0004002b,0x0000000c,0x0000010d,0x388205ff,0x0004002b,0x0000000c, + 0x00000173,0x40000000,0x0004002b,0x0000000c,0x0000017a,0x3f000000,0x00040017,0x00000180, + 0x00000098,0x00000003,0x00040015,0x000001fc,0x00000020,0x00000001,0x0004002b,0x000001fc, + 0x000001ff,0x00000000,0x0004002b,0x000001fc,0x00000206,0x00000003,0x0004002b,0x0000000c, + 0x00000218,0x3e800000,0x0004002b,0x0000000c,0x0000021d,0x41800000,0x0004002b,0x0000000c, + 0x00000222,0x41400000,0x0004002b,0x0000000c,0x00000228,0x40400000,0x0004002b,0x000001fc, + 0x00000234,0x00000001,0x00090019,0x000002a1,0x0000000c,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x00040020,0x000002a2,0x00000000,0x000002a1,0x0004003b, + 0x000002a2,0x000002a3,0x00000000,0x0002001a,0x000002a5,0x00040020,0x000002a6,0x00000000, + 0x000002a5,0x0004003b,0x000002a6,0x000002a7,0x00000000,0x0003001b,0x000002a9,0x000002a1, + 0x00040020,0x000002ab,0x00000001,0x00000012,0x0004003b,0x000002ab,0x000002ac,0x00000001, + 0x00040017,0x000002ae,0x000001fc,0x00000004,0x0017001e,0x000002af,0x0000000c,0x0000000c, + 0x0000000c,0x0000000c,0x00000006,0x00000006,0x00000006,0x00000006,0x000002ae,0x00000012, + 0x00000012,0x00000006,0x0000000c,0x00000006,0x0000000c,0x0000000c,0x00000006,0x0000000c, + 0x0000000c,0x0000000c,0x00000006,0x00040020,0x000002b0,0x00000002,0x000002af,0x0004003b, + 0x000002b0,0x000002b1,0x00000002,0x0004002b,0x000001fc,0x000002b2,0x0000000f,0x00040020, + 0x000002b3,0x00000002,0x0000000c,0x000b001e,0x000002b7,0x00000027,0x00000012,0x0000000c, + 0x0000000c,0x00000027,0x00000012,0x00000006,0x00000006,0x00000006,0x00040020,0x000002b8, + 0x00000002,0x000002b7,0x0004003b,0x000002b8,0x000002b9,0x00000002,0x0004002b,0x000001fc, + 0x000002ba,0x00000002,0x0004002b,0x000001fc,0x000002c8,0x00000007,0x00040020,0x000002ca, + 0x00000002,0x00000006,0x0004003b,0x000002a2,0x000002cf,0x00000000,0x00040020,0x000002d1, + 0x00000001,0x00000027,0x0004003b,0x000002d1,0x000002d2,0x00000001,0x00040017,0x000002d6, + 0x000001fc,0x00000002,0x0004002b,0x000001fc,0x000002f2,0x00000011,0x0004002b,0x000001fc, + 0x000002f3,0x00000012,0x00040020,0x00000307,0x00000003,0x00000027,0x0004003b,0x00000307, + 0x00000308,0x00000003,0x00040020,0x0000030a,0x00000001,0x0000000c,0x0004003b,0x0000030a, + 0x0000030b,0x00000001,0x0006002c,0x0000001c,0x00000a0f,0x0000017a,0x0000017a,0x0000017a, + 0x0006002c,0x0000001c,0x00000a10,0x0000009d,0x0000009d,0x0000009d,0x0006002c,0x0000001c, + 0x00000a32,0x00000097,0x00000097,0x00000097,0x0006002c,0x0000001c,0x00000a33,0x000000f1, + 0x000000f2,0x000000f3,0x0005002c,0x00000012,0x00000a34,0x0000010d,0x0000010d,0x00030001, + 0x00000027,0x00000a35,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003b,0x00000032,0x00000332,0x00000007,0x0004003b,0x00000032,0x00000334, + 0x00000007,0x0004003b,0x00000032,0x00000322,0x00000007,0x0004003d,0x000002a1,0x000002a4, + 0x000002a3,0x0004003d,0x000002a5,0x000002a8,0x000002a7,0x00050056,0x000002a9,0x000002aa, + 0x000002a4,0x000002a8,0x0004003d,0x00000012,0x000002ad,0x000002ac,0x00050041,0x000002b3, + 0x000002b4,0x000002b1,0x000002b2,0x0004003d,0x0000000c,0x000002b5,0x000002b4,0x00070057, + 0x00000027,0x000002b6,0x000002aa,0x000002ad,0x00000001,0x000002b5,0x00050041,0x000002b3, + 0x000002bb,0x000002b9,0x000002ba,0x0004003d,0x0000000c,0x000002bc,0x000002bb,0x0005008e, + 0x00000027,0x000002bd,0x000002b6,0x000002bc,0x0008004f,0x0000001c,0x00000310,0x000002bd, + 0x000002bd,0x00000000,0x00000001,0x00000002,0x00050051,0x0000000c,0x00000312,0x000002bd, + 0x00000003,0x000500b7,0x00000098,0x00000313,0x00000312,0x00000097,0x000300f7,0x00000319, + 0x00000000,0x000400fa,0x00000313,0x00000315,0x00000314,0x000200f8,0x00000314,0x000200f9, + 0x00000319,0x000200f8,0x00000315,0x00050088,0x0000000c,0x00000318,0x0000009d,0x00000312, + 0x000200f9,0x00000319,0x000200f8,0x00000319,0x000700f5,0x0000000c,0x000009a6,0x00000097, + 0x00000314,0x00000318,0x00000315,0x0005008e,0x0000001c,0x0000031b,0x00000310,0x000009a6, + 0x00050051,0x0000000c,0x000002c2,0x0000031b,0x00000000,0x00060052,0x00000027,0x00000861, + 0x000002c2,0x000002bd,0x00000000,0x00050051,0x0000000c,0x000002c4,0x0000031b,0x00000001, + 0x00060052,0x00000027,0x00000863,0x000002c4,0x00000861,0x00000001,0x00050051,0x0000000c, + 0x000002c6,0x0000031b,0x00000002,0x00060052,0x00000027,0x00000865,0x000002c6,0x00000863, + 0x00000002,0x00050041,0x000002ca,0x000002cb,0x000002b9,0x000002c8,0x0004003d,0x00000006, + 0x000002cc,0x000002cb,0x0004003d,0x000002a1,0x000002d0,0x000002cf,0x0004003d,0x00000027, + 0x000002d3,0x000002d2,0x0007004f,0x00000012,0x000002d4,0x000002d3,0x000002d3,0x00000000, + 0x00000001,0x0006000c,0x00000012,0x000002d5,0x00000001,0x00000008,0x000002d4,0x0004006e, + 0x000002d6,0x000002d7,0x000002d5,0x0007005f,0x00000027,0x000002d8,0x000002d0,0x000002d7, + 0x00000002,0x000001ff,0x0008004f,0x0000001c,0x000002db,0x00000865,0x00000865,0x00000000, + 0x00000001,0x00000002,0x0003003e,0x00000322,0x000002db,0x0008004f,0x0000001c,0x0000045c, + 0x000002d8,0x000002d8,0x00000000,0x00000001,0x00000002,0x00050051,0x0000000c,0x0000045e, + 0x000002d8,0x00000003,0x000500b7,0x00000098,0x0000045f,0x0000045e,0x00000097,0x000300f7, + 0x00000465,0x00000000,0x000400fa,0x0000045f,0x00000461,0x00000460,0x000200f8,0x00000460, + 0x000200f9,0x00000465,0x000200f8,0x00000461,0x00050088,0x0000000c,0x00000464,0x0000009d, + 0x0000045e,0x000200f9,0x00000465,0x000200f8,0x00000465,0x000700f5,0x0000000c,0x000009a8, + 0x00000097,0x00000460,0x00000464,0x00000461,0x0005008e,0x0000001c,0x00000467,0x0000045c, + 0x000009a8,0x0003003e,0x00000332,0x00000467,0x000300f7,0x00000456,0x00000000,0x002100fb, + 0x000002cc,0x00000456,0x0000000b,0x00000452,0x00000001,0x0000044a,0x00000002,0x00000439, + 0x00000003,0x00000435,0x00000004,0x00000431,0x00000005,0x0000040e,0x00000006,0x000003e1, + 0x00000007,0x000003d0,0x00000008,0x00000395,0x00000009,0x00000390,0x0000000a,0x00000387, + 0x0000000c,0x0000037c,0x0000000d,0x00000371,0x0000000e,0x00000367,0x0000000f,0x0000035d, + 0x000200f8,0x0000035d,0x0004003d,0x0000001c,0x0000035f,0x00000322,0x0008000c,0x0000001c, + 0x00000362,0x00000001,0x0000002b,0x0000035f,0x00000a32,0x00000a10,0x0003003e,0x00000322, + 0x00000362,0x00050094,0x0000000c,0x000004b4,0x00000362,0x00000a33,0x00050094,0x0000000c, + 0x000004c6,0x00000467,0x00000a33,0x00060050,0x0000001c,0x00000491,0x000004c6,0x000004c6, + 0x000004c6,0x00050083,0x0000001c,0x00000492,0x00000467,0x00000491,0x00050083,0x0000000c, + 0x00000494,0x0000009d,0x000004b4,0x00050050,0x00000012,0x00000a15,0x000004b4,0x00000494, + 0x00050051,0x0000000c,0x000004ed,0x00000492,0x00000000,0x00050051,0x0000000c,0x000004ef, + 0x00000492,0x00000001,0x0007000c,0x0000000c,0x000004f0,0x00000001,0x00000025,0x000004ed, + 0x000004ef,0x00050051,0x0000000c,0x000004e8,0x00000492,0x00000002,0x0007000c,0x0000000c, + 0x000004e9,0x00000001,0x00000025,0x000004f0,0x000004e8,0x0004007f,0x0000000c,0x0000049a, + 0x000004e9,0x0007000c,0x0000000c,0x00000500,0x00000001,0x00000028,0x000004ed,0x000004ef, + 0x0007000c,0x0000000c,0x000004f9,0x00000001,0x00000028,0x00000500,0x000004e8,0x00050050, + 0x00000012,0x00000a17,0x0000049a,0x000004f9,0x0007000c,0x00000012,0x0000049e,0x00000001, + 0x00000028,0x00000a34,0x00000a17,0x00050088,0x00000012,0x0000049f,0x00000a15,0x0000049e, + 0x00050051,0x0000000c,0x000004a2,0x0000049f,0x00000000,0x00050051,0x0000000c,0x000004a4, + 0x0000049f,0x00000001,0x0007000c,0x0000000c,0x000004a5,0x00000001,0x00000025,0x000004a2, + 0x000004a4,0x0007000c,0x0000000c,0x000004a6,0x00000001,0x00000025,0x0000009d,0x000004a5, + 0x0005008e,0x0000001c,0x000004a9,0x00000492,0x000004a6,0x00060050,0x0000001c,0x000004ab, + 0x000004b4,0x000004b4,0x000004b4,0x00050081,0x0000001c,0x000004ac,0x000004a9,0x000004ab, + 0x0003003e,0x00000334,0x000004ac,0x000200f9,0x00000456,0x000200f8,0x00000367,0x0004003d, + 0x0000001c,0x00000369,0x00000322,0x0008000c,0x0000001c,0x0000036c,0x00000001,0x0000002b, + 0x00000369,0x00000a32,0x00000a10,0x0003003e,0x00000322,0x0000036c,0x00050094,0x0000000c, + 0x00000558,0x00000467,0x00000a33,0x00050094,0x0000000c,0x0000056a,0x0000036c,0x00000a33, + 0x00060050,0x0000001c,0x00000535,0x0000056a,0x0000056a,0x0000056a,0x00050083,0x0000001c, + 0x00000536,0x0000036c,0x00000535,0x00050083,0x0000000c,0x00000538,0x0000009d,0x00000558, + 0x00050050,0x00000012,0x00000a1b,0x00000558,0x00000538,0x00050051,0x0000000c,0x00000591, + 0x00000536,0x00000000,0x00050051,0x0000000c,0x00000593,0x00000536,0x00000001,0x0007000c, + 0x0000000c,0x00000594,0x00000001,0x00000025,0x00000591,0x00000593,0x00050051,0x0000000c, + 0x0000058c,0x00000536,0x00000002,0x0007000c,0x0000000c,0x0000058d,0x00000001,0x00000025, + 0x00000594,0x0000058c,0x0004007f,0x0000000c,0x0000053e,0x0000058d,0x0007000c,0x0000000c, + 0x000005a4,0x00000001,0x00000028,0x00000591,0x00000593,0x0007000c,0x0000000c,0x0000059d, + 0x00000001,0x00000028,0x000005a4,0x0000058c,0x00050050,0x00000012,0x00000a1d,0x0000053e, + 0x0000059d,0x0007000c,0x00000012,0x00000542,0x00000001,0x00000028,0x00000a34,0x00000a1d, + 0x00050088,0x00000012,0x00000543,0x00000a1b,0x00000542,0x00050051,0x0000000c,0x00000546, + 0x00000543,0x00000000,0x00050051,0x0000000c,0x00000548,0x00000543,0x00000001,0x0007000c, + 0x0000000c,0x00000549,0x00000001,0x00000025,0x00000546,0x00000548,0x0007000c,0x0000000c, + 0x0000054a,0x00000001,0x00000025,0x0000009d,0x00000549,0x0005008e,0x0000001c,0x0000054d, + 0x00000536,0x0000054a,0x00060050,0x0000001c,0x0000054f,0x00000558,0x00000558,0x00000558, + 0x00050081,0x0000001c,0x00000550,0x0000054d,0x0000054f,0x0003003e,0x00000334,0x00000550, + 0x000200f9,0x00000456,0x000200f8,0x00000371,0x0004003d,0x0000001c,0x00000373,0x00000322, + 0x0008000c,0x0000001c,0x00000376,0x00000001,0x0000002b,0x00000373,0x00000a32,0x00000a10, + 0x0003003e,0x00000322,0x00000376,0x00050051,0x0000000c,0x000005f0,0x00000376,0x00000000, + 0x00050051,0x0000000c,0x000005f2,0x00000376,0x00000001,0x0007000c,0x0000000c,0x000005f3, + 0x00000001,0x00000028,0x000005f0,0x000005f2,0x00050051,0x0000000c,0x000005eb,0x00000376, + 0x00000002,0x0007000c,0x0000000c,0x000005ec,0x00000001,0x00000028,0x000005f3,0x000005eb, + 0x0007000c,0x0000000c,0x00000603,0x00000001,0x00000025,0x000005f0,0x000005f2,0x0007000c, + 0x0000000c,0x000005fc,0x00000001,0x00000025,0x00000603,0x000005eb,0x00050083,0x0000000c, + 0x000005d3,0x000005ec,0x000005fc,0x00050051,0x0000000c,0x00000610,0x00000467,0x00000000, + 0x00050051,0x0000000c,0x00000612,0x00000467,0x00000001,0x0007000c,0x0000000c,0x00000613, + 0x00000001,0x00000025,0x00000610,0x00000612,0x00050051,0x0000000c,0x0000060b,0x00000467, + 0x00000002,0x0007000c,0x0000000c,0x0000060c,0x00000001,0x00000025,0x00000613,0x0000060b, + 0x00060050,0x0000001c,0x000005d7,0x0000060c,0x0000060c,0x0000060c,0x00050083,0x0000001c, + 0x000005d8,0x00000467,0x000005d7,0x00050051,0x0000000c,0x00000620,0x000005d8,0x00000000, + 0x00050051,0x0000000c,0x00000622,0x000005d8,0x00000001,0x0007000c,0x0000000c,0x00000623, + 0x00000001,0x00000028,0x00000620,0x00000622,0x00050051,0x0000000c,0x0000061b,0x000005d8, + 0x00000002,0x0007000c,0x0000000c,0x0000061c,0x00000001,0x00000028,0x00000623,0x0000061b, + 0x0007000c,0x0000000c,0x000005dd,0x00000001,0x00000028,0x0000010d,0x0000061c,0x00050088, + 0x0000000c,0x000005de,0x000005d3,0x000005dd,0x0005008e,0x0000001c,0x000005e1,0x000005d8, + 0x000005de,0x00050094,0x0000000c,0x0000065c,0x00000467,0x00000a33,0x00050094,0x0000000c, + 0x0000066e,0x000005e1,0x00000a33,0x00060050,0x0000001c,0x00000639,0x0000066e,0x0000066e, + 0x0000066e,0x00050083,0x0000001c,0x0000063a,0x000005e1,0x00000639,0x00050083,0x0000000c, + 0x0000063c,0x0000009d,0x0000065c,0x00050050,0x00000012,0x00000a21,0x0000065c,0x0000063c, + 0x00050051,0x0000000c,0x00000695,0x0000063a,0x00000000,0x00050051,0x0000000c,0x00000697, + 0x0000063a,0x00000001,0x0007000c,0x0000000c,0x00000698,0x00000001,0x00000025,0x00000695, + 0x00000697,0x00050051,0x0000000c,0x00000690,0x0000063a,0x00000002,0x0007000c,0x0000000c, + 0x00000691,0x00000001,0x00000025,0x00000698,0x00000690,0x0004007f,0x0000000c,0x00000642, + 0x00000691,0x0007000c,0x0000000c,0x000006a8,0x00000001,0x00000028,0x00000695,0x00000697, + 0x0007000c,0x0000000c,0x000006a1,0x00000001,0x00000028,0x000006a8,0x00000690,0x00050050, + 0x00000012,0x00000a23,0x00000642,0x000006a1,0x0007000c,0x00000012,0x00000646,0x00000001, + 0x00000028,0x00000a34,0x00000a23,0x00050088,0x00000012,0x00000647,0x00000a21,0x00000646, + 0x00050051,0x0000000c,0x0000064a,0x00000647,0x00000000,0x00050051,0x0000000c,0x0000064c, + 0x00000647,0x00000001,0x0007000c,0x0000000c,0x0000064d,0x00000001,0x00000025,0x0000064a, + 0x0000064c,0x0007000c,0x0000000c,0x0000064e,0x00000001,0x00000025,0x0000009d,0x0000064d, + 0x0005008e,0x0000001c,0x00000651,0x0000063a,0x0000064e,0x00060050,0x0000001c,0x00000653, + 0x0000065c,0x0000065c,0x0000065c,0x00050081,0x0000001c,0x00000654,0x00000651,0x00000653, + 0x0003003e,0x00000334,0x00000654,0x000200f9,0x00000456,0x000200f8,0x0000037c,0x0004003d, + 0x0000001c,0x0000037e,0x00000322,0x0008000c,0x0000001c,0x00000381,0x00000001,0x0000002b, + 0x0000037e,0x00000a32,0x00000a10,0x0003003e,0x00000322,0x00000381,0x00050051,0x0000000c, + 0x000006f4,0x00000467,0x00000000,0x00050051,0x0000000c,0x000006f6,0x00000467,0x00000001, + 0x0007000c,0x0000000c,0x000006f7,0x00000001,0x00000028,0x000006f4,0x000006f6,0x00050051, + 0x0000000c,0x000006ef,0x00000467,0x00000002,0x0007000c,0x0000000c,0x000006f0,0x00000001, + 0x00000028,0x000006f7,0x000006ef,0x0007000c,0x0000000c,0x00000707,0x00000001,0x00000025, + 0x000006f4,0x000006f6,0x0007000c,0x0000000c,0x00000700,0x00000001,0x00000025,0x00000707, + 0x000006ef,0x00050083,0x0000000c,0x000006d7,0x000006f0,0x00000700,0x00050051,0x0000000c, + 0x00000714,0x00000381,0x00000000,0x00050051,0x0000000c,0x00000716,0x00000381,0x00000001, + 0x0007000c,0x0000000c,0x00000717,0x00000001,0x00000025,0x00000714,0x00000716,0x00050051, + 0x0000000c,0x0000070f,0x00000381,0x00000002,0x0007000c,0x0000000c,0x00000710,0x00000001, + 0x00000025,0x00000717,0x0000070f,0x00060050,0x0000001c,0x000006db,0x00000710,0x00000710, + 0x00000710,0x00050083,0x0000001c,0x000006dc,0x00000381,0x000006db,0x00050051,0x0000000c, + 0x00000724,0x000006dc,0x00000000,0x00050051,0x0000000c,0x00000726,0x000006dc,0x00000001, + 0x0007000c,0x0000000c,0x00000727,0x00000001,0x00000028,0x00000724,0x00000726,0x00050051, + 0x0000000c,0x0000071f,0x000006dc,0x00000002,0x0007000c,0x0000000c,0x00000720,0x00000001, + 0x00000028,0x00000727,0x0000071f,0x0007000c,0x0000000c,0x000006e1,0x00000001,0x00000028, + 0x0000010d,0x00000720,0x00050088,0x0000000c,0x000006e2,0x000006d7,0x000006e1,0x0005008e, + 0x0000001c,0x000006e5,0x000006dc,0x000006e2,0x00050094,0x0000000c,0x00000760,0x00000467, + 0x00000a33,0x00050094,0x0000000c,0x00000772,0x000006e5,0x00000a33,0x00060050,0x0000001c, + 0x0000073d,0x00000772,0x00000772,0x00000772,0x00050083,0x0000001c,0x0000073e,0x000006e5, + 0x0000073d,0x00050083,0x0000000c,0x00000740,0x0000009d,0x00000760,0x00050050,0x00000012, + 0x00000a27,0x00000760,0x00000740,0x00050051,0x0000000c,0x00000799,0x0000073e,0x00000000, + 0x00050051,0x0000000c,0x0000079b,0x0000073e,0x00000001,0x0007000c,0x0000000c,0x0000079c, + 0x00000001,0x00000025,0x00000799,0x0000079b,0x00050051,0x0000000c,0x00000794,0x0000073e, + 0x00000002,0x0007000c,0x0000000c,0x00000795,0x00000001,0x00000025,0x0000079c,0x00000794, + 0x0004007f,0x0000000c,0x00000746,0x00000795,0x0007000c,0x0000000c,0x000007ac,0x00000001, + 0x00000028,0x00000799,0x0000079b,0x0007000c,0x0000000c,0x000007a5,0x00000001,0x00000028, + 0x000007ac,0x00000794,0x00050050,0x00000012,0x00000a29,0x00000746,0x000007a5,0x0007000c, + 0x00000012,0x0000074a,0x00000001,0x00000028,0x00000a34,0x00000a29,0x00050088,0x00000012, + 0x0000074b,0x00000a27,0x0000074a,0x00050051,0x0000000c,0x0000074e,0x0000074b,0x00000000, + 0x00050051,0x0000000c,0x00000750,0x0000074b,0x00000001,0x0007000c,0x0000000c,0x00000751, + 0x00000001,0x00000025,0x0000074e,0x00000750,0x0007000c,0x0000000c,0x00000752,0x00000001, + 0x00000025,0x0000009d,0x00000751,0x0005008e,0x0000001c,0x00000755,0x0000073e,0x00000752, + 0x00060050,0x0000001c,0x00000757,0x00000760,0x00000760,0x00000760,0x00050081,0x0000001c, + 0x00000758,0x00000755,0x00000757,0x0003003e,0x00000334,0x00000758,0x000200f9,0x00000456, + 0x000200f8,0x00000387,0x0004003d,0x0000001c,0x00000388,0x00000322,0x00050081,0x0000001c, + 0x0000038a,0x00000388,0x00000467,0x0005008e,0x0000001c,0x0000038c,0x00000388,0x00000173, + 0x00050085,0x0000001c,0x0000038e,0x0000038c,0x00000467,0x00050083,0x0000001c,0x0000038f, + 0x0000038a,0x0000038e,0x0003003e,0x00000334,0x0000038f,0x000200f9,0x00000456,0x000200f8, + 0x00000390,0x0004003d,0x0000001c,0x00000392,0x00000322,0x00050083,0x0000001c,0x00000393, + 0x00000467,0x00000392,0x0006000c,0x0000001c,0x00000394,0x00000001,0x00000004,0x00000393, + 0x0003003e,0x00000334,0x00000394,0x000200f9,0x00000456,0x000200f8,0x00000395,0x000200f9, + 0x00000396,0x000200f8,0x00000396,0x000700f5,0x000001fc,0x000009e3,0x000001ff,0x00000395, + 0x000003c4,0x000003c2,0x000500b1,0x00000098,0x00000399,0x000009e3,0x00000206,0x000400f6, + 0x000003c5,0x000003c2,0x00000000,0x000400fa,0x00000399,0x0000039a,0x000003c5,0x000200f8, + 0x0000039a,0x00050041,0x0000000d,0x0000039c,0x00000322,0x000009e3,0x0004003d,0x0000000c, + 0x0000039d,0x0000039c,0x000500bc,0x00000098,0x0000039e,0x0000039d,0x0000017a,0x000300f7, + 0x000003c1,0x00000000,0x000400fa,0x0000039e,0x000003ba,0x0000039f,0x000200f8,0x0000039f, + 0x00050041,0x0000000d,0x000003a1,0x00000332,0x000009e3,0x0004003d,0x0000000c,0x000003a2, + 0x000003a1,0x000500bc,0x00000098,0x000003a3,0x000003a2,0x00000218,0x000300f7,0x000003b9, + 0x00000000,0x000400fa,0x000003a3,0x000003ac,0x000003a4,0x000200f8,0x000003a4,0x0004003d, + 0x0000000c,0x000003a8,0x000003a1,0x0006000c,0x0000000c,0x000003a9,0x00000001,0x00000020, + 0x000003a8,0x00050083,0x0000000c,0x000003aa,0x000003a9,0x0000009d,0x00050041,0x0000000d, + 0x000003ab,0x00000334,0x000009e3,0x0003003e,0x000003ab,0x000003aa,0x000200f9,0x000003b9, + 0x000200f8,0x000003ac,0x0004003d,0x0000000c,0x000003b0,0x000003a1,0x00050085,0x0000000c, + 0x000003b1,0x0000021d,0x000003b0,0x00050083,0x0000000c,0x000003b2,0x000003b1,0x00000222, + 0x0004003d,0x0000000c,0x000003b5,0x000003a1,0x00050085,0x0000000c,0x000003b6,0x000003b2, + 0x000003b5,0x00050081,0x0000000c,0x000003b7,0x000003b6,0x00000228,0x00050041,0x0000000d, + 0x000003b8,0x00000334,0x000009e3,0x0003003e,0x000003b8,0x000003b7,0x000200f9,0x000003b9, + 0x000200f8,0x000003b9,0x000200f9,0x000003c1,0x000200f8,0x000003ba,0x00050041,0x0000000d, + 0x000003bd,0x00000332,0x000009e3,0x0004003d,0x0000000c,0x000003be,0x000003bd,0x00050083, + 0x0000000c,0x000003bf,0x0000009d,0x000003be,0x00050041,0x0000000d,0x000003c0,0x00000334, + 0x000009e3,0x0003003e,0x000003c0,0x000003bf,0x000200f9,0x000003c1,0x000200f8,0x000003c1, + 0x000200f9,0x000003c2,0x000200f8,0x000003c2,0x00050080,0x000001fc,0x000003c4,0x000009e3, + 0x00000234,0x000200f9,0x00000396,0x000200f8,0x000003c5,0x0004003d,0x0000001c,0x000003c8, + 0x00000322,0x0005008e,0x0000001c,0x000003c9,0x000003c8,0x00000173,0x00050083,0x0000001c, + 0x000003cb,0x000003c9,0x00000a10,0x00050085,0x0000001c,0x000003cc,0x00000467,0x000003cb, + 0x0004003d,0x0000001c,0x000003cd,0x00000334,0x00050085,0x0000001c,0x000003ce,0x000003cc, + 0x000003cd,0x00050081,0x0000001c,0x000003cf,0x00000467,0x000003ce,0x0003003e,0x00000334, + 0x000003cf,0x000200f9,0x00000456,0x000200f8,0x000003d0,0x0004003d,0x0000001c,0x000003d1, + 0x00000322,0x00050085,0x0000001c,0x000003d3,0x000003d1,0x00000467,0x00050081,0x0000001c, + 0x000003d7,0x000003d1,0x00000467,0x00050083,0x0000001c,0x000003d9,0x000003d7,0x000003d3, + 0x00050083,0x0000001c,0x000003db,0x000003d9,0x00000a0f,0x000500ba,0x00000180,0x000003de, + 0x000003d1,0x00000a0f,0x000600a9,0x0000001c,0x000003df,0x000003de,0x000003db,0x000003d3, + 0x0005008e,0x0000001c,0x000003e0,0x000003df,0x00000173,0x0003003e,0x00000334,0x000003e0, + 0x000200f9,0x00000456,0x000200f8,0x000003e1,0x0004003d,0x0000001c,0x000003e2,0x00000322, + 0x0008000c,0x0000001c,0x000003e5,0x00000001,0x0000002b,0x000003e2,0x00000a32,0x00000a10, + 0x0003003e,0x00000322,0x000003e5,0x0008004f,0x0000001c,0x000003ea,0x000002d8,0x000002d8, + 0x00000003,0x00000003,0x00000003,0x0008000c,0x0000001c,0x000003eb,0x00000001,0x0000002b, + 0x0000045c,0x00000a32,0x000003ea,0x00050051,0x0000000c,0x000003ed,0x000003eb,0x00000000, + 0x00060052,0x00000027,0x00000949,0x000003ed,0x000002d8,0x00000000,0x00050051,0x0000000c, + 0x000003ef,0x000003eb,0x00000001,0x00060052,0x00000027,0x0000094b,0x000003ef,0x00000949, + 0x00000001,0x00050051,0x0000000c,0x000003f1,0x000003eb,0x00000002,0x00060052,0x00000027, + 0x0000094d,0x000003f1,0x0000094b,0x00000002,0x000500b4,0x00000098,0x000003f4,0x0000045e, + 0x00000097,0x000300f7,0x000003f7,0x00000000,0x000400fa,0x000003f4,0x000003f5,0x000003f7, + 0x000200f8,0x000003f5,0x00070050,0x00000027,0x00000a2d,0x000003ed,0x000003ef,0x000003f1, + 0x0000009d,0x000200f9,0x000003f7,0x000200f8,0x000003f7,0x000700f5,0x00000027,0x000009ef, + 0x0000094d,0x000003e1,0x00000a2d,0x000003f5,0x00050051,0x0000000c,0x000003f9,0x000009ef, + 0x00000003,0x0008004f,0x0000001c,0x000003fb,0x000009ef,0x000009ef,0x00000000,0x00000001, + 0x00000002,0x00060050,0x0000001c,0x000003fc,0x000003f9,0x000003f9,0x000003f9,0x00050083, + 0x0000001c,0x000003fd,0x000003fc,0x000003fb,0x0004003d,0x0000001c,0x00000400,0x00000322, + 0x0005008e,0x0000001c,0x00000403,0x00000400,0x000003f9,0x00050088,0x0000001c,0x00000404, + 0x000003fd,0x00000403,0x0007000c,0x0000001c,0x00000405,0x00000001,0x00000025,0x00000a10, + 0x00000404,0x0006000c,0x0000001c,0x00000407,0x00000001,0x00000006,0x000003fd,0x000500b4, + 0x00000180,0x0000040a,0x00000400,0x00000a32,0x000600a9,0x0000001c,0x0000040b,0x0000040a, + 0x00000407,0x00000405,0x00050083,0x0000001c,0x0000040d,0x00000a10,0x0000040b,0x0003003e, + 0x00000334,0x0000040d,0x000200f9,0x00000456,0x000200f8,0x0000040e,0x0008004f,0x0000001c, + 0x00000413,0x000002d8,0x000002d8,0x00000003,0x00000003,0x00000003,0x0008000c,0x0000001c, + 0x00000414,0x00000001,0x0000002b,0x0000045c,0x00000a32,0x00000413,0x00050051,0x0000000c, + 0x00000416,0x00000414,0x00000000,0x00060052,0x00000027,0x00000966,0x00000416,0x00000a35, + 0x00000000,0x00050051,0x0000000c,0x00000418,0x00000414,0x00000001,0x00060052,0x00000027, + 0x00000968,0x00000418,0x00000966,0x00000001,0x00050051,0x0000000c,0x0000041a,0x00000414, + 0x00000002,0x00060052,0x00000027,0x0000096a,0x0000041a,0x00000968,0x00000002,0x0004003d, + 0x0000001c,0x0000041b,0x00000322,0x00050083,0x0000001c,0x0000041d,0x00000a10,0x0000041b, + 0x0008000c,0x0000001c,0x00000420,0x00000001,0x0000002b,0x0000041d,0x00000a32,0x00000a10, + 0x0005008e,0x0000001c,0x00000423,0x00000420,0x0000045e,0x0008004f,0x0000001c,0x00000426, + 0x0000096a,0x0000096a,0x00000000,0x00000001,0x00000002,0x00050088,0x0000001c,0x00000428, + 0x00000426,0x00000423,0x0007000c,0x0000001c,0x00000429,0x00000001,0x00000025,0x00000a10, + 0x00000428,0x0006000c,0x0000001c,0x0000042c,0x00000001,0x00000006,0x00000426,0x000500b4, + 0x00000180,0x0000042f,0x00000423,0x00000a32,0x000600a9,0x0000001c,0x00000430,0x0000042f, + 0x0000042c,0x00000429,0x0003003e,0x00000334,0x00000430,0x000200f9,0x00000456,0x000200f8, + 0x00000431,0x0004003d,0x0000001c,0x00000432,0x00000322,0x0007000c,0x0000001c,0x00000434, + 0x00000001,0x00000028,0x00000432,0x00000467,0x0003003e,0x00000334,0x00000434,0x000200f9, + 0x00000456,0x000200f8,0x00000435,0x0004003d,0x0000001c,0x00000436,0x00000322,0x0007000c, + 0x0000001c,0x00000438,0x00000001,0x00000025,0x00000436,0x00000467,0x0003003e,0x00000334, + 0x00000438,0x000200f9,0x00000456,0x000200f8,0x00000439,0x0004003d,0x0000001c,0x0000043a, + 0x00000322,0x00050085,0x0000001c,0x0000043c,0x0000043a,0x00000467,0x00050081,0x0000001c, + 0x00000440,0x0000043a,0x00000467,0x00050083,0x0000001c,0x00000442,0x00000440,0x0000043c, + 0x00050083,0x0000001c,0x00000444,0x00000442,0x00000a0f,0x000500ba,0x00000180,0x00000447, + 0x00000467,0x00000a0f,0x000600a9,0x0000001c,0x00000448,0x00000447,0x00000444,0x0000043c, + 0x0005008e,0x0000001c,0x00000449,0x00000448,0x00000173,0x0003003e,0x00000334,0x00000449, + 0x000200f9,0x00000456,0x000200f8,0x0000044a,0x0004003d,0x0000001c,0x0000044b,0x00000322, + 0x00050081,0x0000001c,0x0000044d,0x0000044b,0x00000467,0x00050085,0x0000001c,0x00000450, + 0x0000044b,0x00000467,0x00050083,0x0000001c,0x00000451,0x0000044d,0x00000450,0x0003003e, + 0x00000334,0x00000451,0x000200f9,0x00000456,0x000200f8,0x00000452,0x0004003d,0x0000001c, + 0x00000453,0x00000322,0x00050085,0x0000001c,0x00000455,0x00000453,0x00000467,0x0003003e, + 0x00000334,0x00000455,0x000200f9,0x00000456,0x000200f8,0x00000456,0x0004003d,0x0000001c, + 0x00000457,0x00000334,0x00060050,0x0000001c,0x00000a31,0x0000045e,0x0000045e,0x0000045e, + 0x0008000c,0x0000001c,0x00000331,0x00000001,0x0000002e,0x000002db,0x00000457,0x00000a31, + 0x00050051,0x0000000c,0x000002e2,0x00000331,0x00000000,0x00060052,0x00000027,0x00000992, + 0x000002e2,0x00000865,0x00000000,0x00050051,0x0000000c,0x000002e4,0x00000331,0x00000001, + 0x00060052,0x00000027,0x00000994,0x000002e4,0x00000992,0x00000001,0x00050051,0x0000000c, + 0x000002e6,0x00000331,0x00000002,0x00060052,0x00000027,0x00000996,0x000002e6,0x00000994, + 0x00000002,0x0008004f,0x0000001c,0x000002ea,0x00000996,0x00000996,0x00000000,0x00000001, + 0x00000002,0x0005008e,0x0000001c,0x000002eb,0x000002ea,0x00000312,0x00050051,0x0000000c, + 0x000002ed,0x000002eb,0x00000000,0x00060052,0x00000027,0x00000999,0x000002ed,0x00000996, + 0x00000000,0x00050051,0x0000000c,0x000002ef,0x000002eb,0x00000001,0x00060052,0x00000027, + 0x0000099b,0x000002ef,0x00000999,0x00000001,0x00050051,0x0000000c,0x000002f1,0x000002eb, + 0x00000002,0x00060052,0x00000027,0x0000099d,0x000002f1,0x0000099b,0x00000002,0x0008004f, + 0x0000001c,0x000002f6,0x0000099d,0x0000099d,0x00000000,0x00000001,0x00000002,0x0004003d, + 0x00000027,0x000002f8,0x000002d2,0x00050041,0x000002b3,0x000002fb,0x000002b1,0x000002f2, + 0x0004003d,0x0000000c,0x000002fc,0x000002fb,0x00050041,0x000002b3,0x000002fe,0x000002b1, + 0x000002f3,0x0004003d,0x0000000c,0x000002ff,0x000002fe,0x00050051,0x0000000c,0x0000084f, + 0x000002f8,0x00000000,0x00050085,0x0000000c,0x00000850,0x000000c7,0x0000084f,0x00050051, + 0x0000000c,0x00000852,0x000002f8,0x00000001,0x00050085,0x0000000c,0x00000853,0x000000cb, + 0x00000852,0x00050081,0x0000000c,0x00000854,0x00000850,0x00000853,0x0006000c,0x0000000c, + 0x00000855,0x00000001,0x0000000a,0x00000854,0x00050085,0x0000000c,0x00000857,0x000000d2, + 0x00000855,0x0006000c,0x0000000c,0x00000858,0x00000001,0x0000000a,0x00000857,0x00050085, + 0x0000000c,0x0000085b,0x00000858,0x000002fc,0x00050081,0x0000000c,0x0000085d,0x0000085b, + 0x000002ff,0x00060050,0x0000001c,0x00000846,0x0000085d,0x0000085d,0x0000085d,0x00050081, + 0x0000001c,0x00000847,0x00000846,0x000002f6,0x00050051,0x0000000c,0x00000302,0x00000847, + 0x00000000,0x00060052,0x00000027,0x000009a1,0x00000302,0x0000099d,0x00000000,0x00050051, + 0x0000000c,0x00000304,0x00000847,0x00000001,0x00060052,0x00000027,0x000009a3,0x00000304, + 0x000009a1,0x00000001,0x00050051,0x0000000c,0x00000306,0x00000847,0x00000002,0x00060052, + 0x00000027,0x000009a5,0x00000306,0x000009a3,0x00000002,0x0003003e,0x00000308,0x000009a5, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d1c122468190d00449622d09eb2bc3ba9d26ffe3 GIT binary patch literal 14920 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 EFUG47>;M1& literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.h new file mode 100644 index 000000000..58ada707e --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.h @@ -0,0 +1,122 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_webgpu_noclipdistance_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000104,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000067,0x00000075,0x0000007e, + 0x0000007f,0x00000085,0x000000ba,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00060005,0x00000067,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005, + 0x0000006c,0x0000434c,0x00040006,0x0000006c,0x00000000,0x00003972,0x00040006,0x0000006c, + 0x00000001,0x00003261,0x00040006,0x0000006c,0x00000002,0x00003479,0x00040006,0x0000006c, + 0x00000003,0x00006969,0x00040006,0x0000006c,0x00000004,0x0000326b,0x00040006,0x0000006c, + 0x00000005,0x00003244,0x00040006,0x0000006c,0x00000006,0x00003056,0x00040006,0x0000006c, + 0x00000007,0x0000326e,0x00040006,0x0000006c,0x00000008,0x0000365a,0x00030005,0x0000006e, + 0x00003041,0x00030005,0x00000075,0x00004346,0x00030005,0x0000007e,0x00003055,0x00030005, + 0x0000007f,0x00004347,0x00030005,0x00000085,0x00003346,0x00030005,0x00000088,0x0000424d, + 0x00040006,0x00000088,0x00000000,0x00006250,0x00040006,0x00000088,0x00000001,0x00006359, + 0x00040006,0x00000088,0x00000002,0x00006552,0x00040006,0x00000088,0x00000003,0x00006553, + 0x00040006,0x00000088,0x00000004,0x0000366d,0x00040006,0x00000088,0x00000005,0x0000676d, + 0x00040006,0x00000088,0x00000006,0x00006544,0x00040006,0x00000088,0x00000007,0x00006545, + 0x00040006,0x00000088,0x00000008,0x00003755,0x00040006,0x00000088,0x00000009,0x0000676a, + 0x00040006,0x00000088,0x0000000a,0x0000635a,0x00040006,0x00000088,0x0000000b,0x00003157, + 0x00040006,0x00000088,0x0000000c,0x0000676e,0x00040006,0x00000088,0x0000000d,0x00003559, + 0x00040006,0x00000088,0x0000000e,0x0000324f,0x00040006,0x00000088,0x0000000f,0x00006461, + 0x00040006,0x00000088,0x00000010,0x00006579,0x00040006,0x00000088,0x00000011,0x00003376, + 0x00040006,0x00000088,0x00000012,0x00003377,0x00040006,0x00000088,0x00000013,0x00006462, + 0x00040006,0x00000088,0x00000014,0x00006767,0x00030005,0x0000008a,0x0000006b,0x00060005, + 0x000000b8,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x000000b8,0x00000000, + 0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x000000b8,0x00000001,0x505f6c67,0x746e696f, + 0x657a6953,0x00000000,0x00070006,0x000000b8,0x00000002,0x435f6c67,0x4470696c,0x61747369, + 0x0065636e,0x00070006,0x000000b8,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e, + 0x00030005,0x000000ba,0x00000000,0x00040047,0x00000067,0x0000000b,0x0000002a,0x00030047, + 0x0000006c,0x00000002,0x00050048,0x0000006c,0x00000000,0x00000023,0x00000000,0x00050048, + 0x0000006c,0x00000001,0x00000023,0x00000010,0x00050048,0x0000006c,0x00000002,0x00000023, + 0x00000018,0x00050048,0x0000006c,0x00000003,0x00000023,0x0000001c,0x00050048,0x0000006c, + 0x00000004,0x00000023,0x00000020,0x00050048,0x0000006c,0x00000005,0x00000023,0x00000030, + 0x00050048,0x0000006c,0x00000006,0x00000023,0x00000038,0x00050048,0x0000006c,0x00000007, + 0x00000023,0x0000003c,0x00050048,0x0000006c,0x00000008,0x00000023,0x00000040,0x00040047, + 0x0000006e,0x00000021,0x00000002,0x00040047,0x0000006e,0x00000022,0x00000000,0x00040047, + 0x00000075,0x0000001e,0x00000000,0x00040047,0x0000007e,0x0000001e,0x00000000,0x00040047, + 0x0000007f,0x0000001e,0x00000001,0x00030047,0x00000085,0x00000000,0x00030047,0x00000085, + 0x0000000e,0x00040047,0x00000085,0x0000001e,0x00000001,0x00030047,0x00000088,0x00000002, + 0x00050048,0x00000088,0x00000000,0x00000023,0x00000000,0x00050048,0x00000088,0x00000001, + 0x00000023,0x00000004,0x00050048,0x00000088,0x00000002,0x00000023,0x00000008,0x00050048, + 0x00000088,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000088,0x00000004,0x00000023, + 0x00000010,0x00050048,0x00000088,0x00000005,0x00000023,0x00000014,0x00050048,0x00000088, + 0x00000006,0x00000023,0x00000018,0x00050048,0x00000088,0x00000007,0x00000023,0x0000001c, + 0x00050048,0x00000088,0x00000008,0x00000023,0x00000020,0x00050048,0x00000088,0x00000009, + 0x00000023,0x00000030,0x00050048,0x00000088,0x0000000a,0x00000023,0x00000038,0x00050048, + 0x00000088,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000088,0x0000000c,0x00000023, + 0x00000044,0x00050048,0x00000088,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000088, + 0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000088,0x0000000f,0x00000023,0x00000050, + 0x00050048,0x00000088,0x00000010,0x00000023,0x00000054,0x00050048,0x00000088,0x00000011, + 0x00000023,0x00000058,0x00050048,0x00000088,0x00000012,0x00000023,0x0000005c,0x00050048, + 0x00000088,0x00000013,0x00000023,0x00000060,0x00050048,0x00000088,0x00000014,0x00000023, + 0x00000064,0x00040047,0x0000008a,0x00000021,0x00000000,0x00040047,0x0000008a,0x00000022, + 0x00000000,0x00030047,0x000000b8,0x00000002,0x00050048,0x000000b8,0x00000000,0x0000000b, + 0x00000000,0x00050048,0x000000b8,0x00000001,0x0000000b,0x00000001,0x00050048,0x000000b8, + 0x00000002,0x0000000b,0x00000003,0x00050048,0x000000b8,0x00000003,0x0000000b,0x00000004, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020, + 0x00040017,0x00000007,0x00000006,0x00000004,0x00040017,0x00000009,0x00000006,0x00000002, + 0x00040018,0x0000000a,0x00000009,0x00000002,0x00040015,0x0000000f,0x00000020,0x00000000, + 0x0004002b,0x00000006,0x0000002d,0x3f800000,0x0004002b,0x00000006,0x0000002e,0x00000000, + 0x0004002b,0x0000000f,0x00000039,0x00000000,0x00020014,0x0000003a,0x0004002b,0x0000000f, + 0x00000041,0x000003ff,0x0004002b,0x0000000f,0x00000051,0x00000001,0x0004002b,0x00000006, + 0x0000005e,0x38800000,0x00040015,0x00000063,0x00000020,0x00000001,0x00040020,0x00000066, + 0x00000001,0x00000063,0x0004003b,0x00000066,0x00000067,0x00000001,0x0004002b,0x00000063, + 0x0000006a,0x00000000,0x000b001e,0x0000006c,0x00000007,0x00000009,0x00000006,0x00000006, + 0x00000007,0x00000009,0x0000000f,0x0000000f,0x0000000f,0x00040020,0x0000006d,0x00000002, + 0x0000006c,0x0004003b,0x0000006d,0x0000006e,0x00000002,0x00040020,0x00000070,0x00000002, + 0x00000007,0x00040020,0x00000074,0x00000001,0x00000009,0x0004003b,0x00000074,0x00000075, + 0x00000001,0x0004002b,0x00000063,0x00000078,0x00000001,0x00040020,0x00000079,0x00000002, + 0x00000009,0x00040020,0x0000007d,0x00000003,0x00000009,0x0004003b,0x0000007d,0x0000007e, + 0x00000003,0x0004003b,0x00000074,0x0000007f,0x00000001,0x00040020,0x00000084,0x00000003, + 0x00000006,0x0004003b,0x00000084,0x00000085,0x00000003,0x0004002b,0x00000063,0x00000086, + 0x00000006,0x00040017,0x00000087,0x00000063,0x00000004,0x0017001e,0x00000088,0x00000006, + 0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f,0x0000000f,0x0000000f,0x00000087, + 0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f,0x00000006,0x00000006,0x0000000f, + 0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020,0x00000089,0x00000002,0x00000088, + 0x0004003b,0x00000089,0x0000008a,0x00000002,0x0004002b,0x00000063,0x0000008b,0x0000000d, + 0x00040020,0x0000008d,0x00000002,0x0000000f,0x0004002b,0x00000063,0x000000a4,0x00000002, + 0x0004002b,0x00000063,0x000000a5,0x00000003,0x00040020,0x000000a9,0x00000002,0x00000006, + 0x0004002b,0x00000063,0x000000b0,0x00000008,0x0004001c,0x000000b7,0x00000006,0x00000051, + 0x0006001e,0x000000b8,0x00000007,0x00000006,0x000000b7,0x000000b7,0x00040020,0x000000b9, + 0x00000003,0x000000b8,0x0004003b,0x000000b9,0x000000ba,0x00000003,0x00040020,0x000000bc, + 0x00000003,0x00000007,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x00050041,0x00000070,0x00000071,0x0000006e,0x0000006a,0x0004003d,0x00000007, + 0x00000072,0x00000071,0x00050051,0x00000006,0x000000c4,0x00000072,0x00000000,0x00050051, + 0x00000006,0x000000c5,0x00000072,0x00000001,0x00050051,0x00000006,0x000000c6,0x00000072, + 0x00000002,0x00050051,0x00000006,0x000000c7,0x00000072,0x00000003,0x00050050,0x00000009, + 0x000000c8,0x000000c4,0x000000c5,0x00050050,0x00000009,0x000000c9,0x000000c6,0x000000c7, + 0x00050050,0x0000000a,0x000000ca,0x000000c8,0x000000c9,0x0004003d,0x00000009,0x00000076, + 0x00000075,0x00050091,0x00000009,0x00000077,0x000000ca,0x00000076,0x00050041,0x00000079, + 0x0000007a,0x0000006e,0x00000078,0x0004003d,0x00000009,0x0000007b,0x0000007a,0x00050081, + 0x00000009,0x0000007c,0x00000077,0x0000007b,0x0004003d,0x00000009,0x00000080,0x0000007f, + 0x0003003e,0x0000007e,0x00000080,0x00050041,0x0000008d,0x0000008e,0x0000006e,0x00000086, + 0x0004003d,0x0000000f,0x0000008f,0x0000008e,0x00050041,0x0000008d,0x00000091,0x0000008a, + 0x0000008b,0x0004003d,0x0000000f,0x00000092,0x00000091,0x000500aa,0x0000003a,0x000000d0, + 0x0000008f,0x00000039,0x000300f7,0x000000d9,0x00000000,0x000400fa,0x000000d0,0x000000d8, + 0x000000d1,0x000200f8,0x000000d1,0x00050080,0x0000000f,0x000000d3,0x0000008f,0x00000041, + 0x00050084,0x0000000f,0x000000d5,0x000000d3,0x00000092,0x0006000c,0x00000009,0x000000d6, + 0x00000001,0x0000003e,0x000000d5,0x00050051,0x00000006,0x000000d7,0x000000d6,0x00000000, + 0x000200f9,0x000000d9,0x000200f8,0x000000d8,0x000200f9,0x000000d9,0x000200f8,0x000000d9, + 0x000700f5,0x00000006,0x00000103,0x000000d7,0x000000d1,0x0000002e,0x000000d8,0x0003003e, + 0x00000085,0x00000103,0x00050041,0x000000a9,0x000000aa,0x0000008a,0x000000a4,0x0004003d, + 0x00000006,0x000000ab,0x000000aa,0x00050041,0x000000a9,0x000000ad,0x0000008a,0x000000a5, + 0x0004003d,0x00000006,0x000000ae,0x000000ad,0x00050051,0x00000006,0x000000ed,0x0000007c, + 0x00000000,0x00050085,0x00000006,0x000000ef,0x000000ed,0x000000ab,0x00050083,0x00000006, + 0x000000f0,0x000000ef,0x0000002d,0x00050051,0x00000006,0x000000f2,0x0000007c,0x00000001, + 0x00050085,0x00000006,0x000000f4,0x000000f2,0x000000ae,0x0006000c,0x00000006,0x000000f6, + 0x00000001,0x00000006,0x000000ae,0x00050083,0x00000006,0x000000f7,0x000000f4,0x000000f6, + 0x00070050,0x00000007,0x000000f8,0x000000f0,0x000000f7,0x0000002e,0x0000002d,0x00050041, + 0x0000008d,0x000000b2,0x0000006e,0x000000b0,0x0004003d,0x0000000f,0x000000b3,0x000000b2, + 0x00040070,0x00000006,0x000000fc,0x000000b3,0x00050085,0x00000006,0x000000fd,0x000000fc, + 0x0000005e,0x00050083,0x00000006,0x000000fe,0x0000002d,0x000000fd,0x00060052,0x00000007, + 0x00000102,0x000000fe,0x000000f8,0x00000002,0x00050041,0x000000bc,0x000000bd,0x000000ba, + 0x0000006a,0x0003003e,0x000000bd,0x00000102,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..0cb1ea7db21047d067f32e67037e2dd6122eaa56 GIT binary patch literal 3768 zcmZ9O+iz4=6vj_GEvk1Y$f+XHM%W)9E;u(xPIG z6cwWe{|0yfq9OVq8hrB}A2i0>A7L~`1&yfR@0`76c06XW*Y~Zp*It*sr)D}g^#nmj zup;OUx;ld7TN8AO3B)Z+)?9u(-(PQ(`nPPo3x`!fCh@~(wY>PcBr}D$f<7f_N=`_g zmn=y>kYw~_;OxY7RBXs^1%AVa z_J{StOtl=<%2B-@Hlq1PvlfMu%}TKm&sORRYcX>pBf0!=SgckRbDH{@RmBWKkO-DacDMj-^(5-sP;`6%$d2}T@dDOPI zF+D2W)5g@lu%(UZWE{6K=N|R^yM>25yiE9@reNo3ctORp_X;1`mgdGV2IWhh%wv!8 zL}xAs9M61mj%QAL?oEAOmj39j^c-})(TO&uuEWJPrmivdmb~z%u5k}1{Zw9Nr>+?_ z)i8ApdH&Qj>|yFUa9`X12H|OM|8n6YUOwE)$L?&Zt zLaA-PNqE7_XN~ZjdS&_FEPTwvYlSDg{p*CMbUyt*E&Zs3dvzJU9F9h{^lAx;O?h-| zv-OxeF19D}r}qgTR~qB-ab?Ax)W#fS+g*;ULvg)Ps1&1?jhSF;mdh<0`S3RRa+;k| zOkVUI2~O`fG50E4?mFM5bZK$q14oa{k3DefJ&yC?Hh3KO0xs)u-Hy{0ZN=k$;5XoL zJ&t?OzR?5Y*n=N+7?*Jzci1@VoAsPCtZ&>k^RvF$9PqQg*&N_Fk8`sU+shk+ zvpL|$JA<=1!131Lc1mn7xxx*39B&S8ugB3pxV*>l_TWZ6jymD?dmL{N?vTgv4&fg6 zINl=MlO9Kp;7Sta$D8Dy@ELC3lT7mNY@U}>H}{t>tr?Da(hFAl0LLD<2fraxSs)2lMv*T;?6de?dC2@CQGqRc&bP z2cK}9#pAbvc=(@mHfq2Q<~M>E^p4t3Nw721m$bq$<32IGD{Q`4{kF1){17;NZT-J) znA~2GAGL7?xq-R=aF*Mv(s{4=zvgVjHv3t}89paWZTO#eHqJErCF#AA4YI$d6&rV{ zPa5xpIl*B=i1WTyVqzyxaQgp|sr`zxvv-@`8~M{eKK5M`!*AlC{^dSAE#Z!E=N^(L z`)U&See&V_j~u6^#eM9!4v+i9ahz#;KXn{uk18H>`AkAgVi@r+a*_Z&W~F8{!&bAKS;ioFelbU?c=O( zBF}IGe~9;o1Rr#Gi+NQ#{@6!VKkwk0gtM?wKj+!3-;rLCT$0$V z-<1wubv^i7I-KQmT{;|pAMD(Jq!Sn0n6l#BP9+G>`Mf30yrT6(32%K`!W_W(UROl} GlK%kwlV%qH literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.h new file mode 100644 index 000000000..49629f51d --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.h @@ -0,0 +1,151 @@ +#pragma once + +const uint32_t draw_msaa_image_mesh_webgpu_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x0000015e,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000020,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000007a, + 0x0000009d,0x000000aa,0x000000b2,0x000000b3,0x000000b8,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00060005,0x00000078,0x505f6c67,0x65567265,0x78657472, + 0x00000000,0x00060006,0x00000078,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006, + 0x00000078,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000078, + 0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000078,0x00000003, + 0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x0000007a,0x00000000,0x00060005, + 0x0000009d,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x000000a1,0x0000434c, + 0x00040006,0x000000a1,0x00000000,0x00003972,0x00040006,0x000000a1,0x00000001,0x00003261, + 0x00040006,0x000000a1,0x00000002,0x00003479,0x00040006,0x000000a1,0x00000003,0x00006969, + 0x00040006,0x000000a1,0x00000004,0x0000326b,0x00040006,0x000000a1,0x00000005,0x00003244, + 0x00040006,0x000000a1,0x00000006,0x00003056,0x00040006,0x000000a1,0x00000007,0x0000326e, + 0x00040006,0x000000a1,0x00000008,0x0000365a,0x00030005,0x000000a3,0x00003041,0x00030005, + 0x000000aa,0x00004346,0x00030005,0x000000b2,0x00003055,0x00030005,0x000000b3,0x00004347, + 0x00030005,0x000000b8,0x00003346,0x00030005,0x000000bb,0x0000424d,0x00040006,0x000000bb, + 0x00000000,0x00006250,0x00040006,0x000000bb,0x00000001,0x00006359,0x00040006,0x000000bb, + 0x00000002,0x00006552,0x00040006,0x000000bb,0x00000003,0x00006553,0x00040006,0x000000bb, + 0x00000004,0x0000366d,0x00040006,0x000000bb,0x00000005,0x0000676d,0x00040006,0x000000bb, + 0x00000006,0x00006544,0x00040006,0x000000bb,0x00000007,0x00006545,0x00040006,0x000000bb, + 0x00000008,0x00003755,0x00040006,0x000000bb,0x00000009,0x0000676a,0x00040006,0x000000bb, + 0x0000000a,0x0000635a,0x00040006,0x000000bb,0x0000000b,0x00003157,0x00040006,0x000000bb, + 0x0000000c,0x0000676e,0x00040006,0x000000bb,0x0000000d,0x00003559,0x00040006,0x000000bb, + 0x0000000e,0x0000324f,0x00040006,0x000000bb,0x0000000f,0x00006461,0x00040006,0x000000bb, + 0x00000010,0x00006579,0x00040006,0x000000bb,0x00000011,0x00003376,0x00040006,0x000000bb, + 0x00000012,0x00003377,0x00040006,0x000000bb,0x00000013,0x00006462,0x00040006,0x000000bb, + 0x00000014,0x00006767,0x00030005,0x000000bd,0x0000006b,0x00030047,0x00000078,0x00000002, + 0x00050048,0x00000078,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000078,0x00000001, + 0x0000000b,0x00000001,0x00050048,0x00000078,0x00000002,0x0000000b,0x00000003,0x00050048, + 0x00000078,0x00000003,0x0000000b,0x00000004,0x00040047,0x0000009d,0x0000000b,0x0000002a, + 0x00030047,0x000000a1,0x00000002,0x00050048,0x000000a1,0x00000000,0x00000023,0x00000000, + 0x00050048,0x000000a1,0x00000001,0x00000023,0x00000010,0x00050048,0x000000a1,0x00000002, + 0x00000023,0x00000018,0x00050048,0x000000a1,0x00000003,0x00000023,0x0000001c,0x00050048, + 0x000000a1,0x00000004,0x00000023,0x00000020,0x00050048,0x000000a1,0x00000005,0x00000023, + 0x00000030,0x00050048,0x000000a1,0x00000006,0x00000023,0x00000038,0x00050048,0x000000a1, + 0x00000007,0x00000023,0x0000003c,0x00050048,0x000000a1,0x00000008,0x00000023,0x00000040, + 0x00040047,0x000000a3,0x00000021,0x00000002,0x00040047,0x000000a3,0x00000022,0x00000000, + 0x00040047,0x000000aa,0x0000001e,0x00000000,0x00040047,0x000000b2,0x0000001e,0x00000000, + 0x00040047,0x000000b3,0x0000001e,0x00000001,0x00030047,0x000000b8,0x00000000,0x00030047, + 0x000000b8,0x0000000e,0x00040047,0x000000b8,0x0000001e,0x00000001,0x00030047,0x000000bb, + 0x00000002,0x00050048,0x000000bb,0x00000000,0x00000023,0x00000000,0x00050048,0x000000bb, + 0x00000001,0x00000023,0x00000004,0x00050048,0x000000bb,0x00000002,0x00000023,0x00000008, + 0x00050048,0x000000bb,0x00000003,0x00000023,0x0000000c,0x00050048,0x000000bb,0x00000004, + 0x00000023,0x00000010,0x00050048,0x000000bb,0x00000005,0x00000023,0x00000014,0x00050048, + 0x000000bb,0x00000006,0x00000023,0x00000018,0x00050048,0x000000bb,0x00000007,0x00000023, + 0x0000001c,0x00050048,0x000000bb,0x00000008,0x00000023,0x00000020,0x00050048,0x000000bb, + 0x00000009,0x00000023,0x00000030,0x00050048,0x000000bb,0x0000000a,0x00000023,0x00000038, + 0x00050048,0x000000bb,0x0000000b,0x00000023,0x00000040,0x00050048,0x000000bb,0x0000000c, + 0x00000023,0x00000044,0x00050048,0x000000bb,0x0000000d,0x00000023,0x00000048,0x00050048, + 0x000000bb,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000000bb,0x0000000f,0x00000023, + 0x00000050,0x00050048,0x000000bb,0x00000010,0x00000023,0x00000054,0x00050048,0x000000bb, + 0x00000011,0x00000023,0x00000058,0x00050048,0x000000bb,0x00000012,0x00000023,0x0000005c, + 0x00050048,0x000000bb,0x00000013,0x00000023,0x00000060,0x00050048,0x000000bb,0x00000014, + 0x00000023,0x00000064,0x00040047,0x000000bd,0x00000021,0x00000000,0x00040047,0x000000bd, + 0x00000022,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040017,0x00000009, + 0x00000006,0x00000002,0x00040018,0x0000000a,0x00000009,0x00000002,0x00040015,0x0000000f, + 0x00000020,0x00000000,0x0004002b,0x00000006,0x0000002d,0x3f800000,0x0004002b,0x00000006, + 0x0000002e,0x00000000,0x0004002b,0x0000000f,0x00000039,0x00000000,0x00020014,0x0000003a, + 0x0004002b,0x0000000f,0x00000041,0x000003ff,0x0004002b,0x0000000f,0x00000051,0x00000001, + 0x0004002b,0x00000006,0x0000005e,0x38800000,0x0007002c,0x00000007,0x00000069,0x0000002e, + 0x0000002e,0x0000002e,0x0000002e,0x00040017,0x0000006a,0x0000003a,0x00000004,0x0004002b, + 0x0000000f,0x00000075,0x00000004,0x0004001c,0x00000076,0x00000006,0x00000075,0x0004001c, + 0x00000077,0x00000006,0x00000051,0x0006001e,0x00000078,0x00000007,0x00000006,0x00000076, + 0x00000077,0x00040020,0x00000079,0x00000003,0x00000078,0x0004003b,0x00000079,0x0000007a, + 0x00000003,0x00040015,0x0000007b,0x00000020,0x00000001,0x0004002b,0x0000007b,0x0000007c, + 0x00000002,0x0004002b,0x0000007b,0x0000007d,0x00000000,0x00040020,0x00000081,0x00000003, + 0x00000006,0x0004002b,0x0000007b,0x00000083,0x00000001,0x0004002b,0x0000007b,0x0000008c, + 0x00000003,0x0004002b,0x00000006,0x00000094,0x3f000000,0x00040020,0x0000009c,0x00000001, + 0x0000007b,0x0004003b,0x0000009c,0x0000009d,0x00000001,0x000b001e,0x000000a1,0x00000007, + 0x00000009,0x00000006,0x00000006,0x00000007,0x00000009,0x0000000f,0x0000000f,0x0000000f, + 0x00040020,0x000000a2,0x00000002,0x000000a1,0x0004003b,0x000000a2,0x000000a3,0x00000002, + 0x00040020,0x000000a5,0x00000002,0x00000007,0x00040020,0x000000a9,0x00000001,0x00000009, + 0x0004003b,0x000000a9,0x000000aa,0x00000001,0x00040020,0x000000ad,0x00000002,0x00000009, + 0x00040020,0x000000b1,0x00000003,0x00000009,0x0004003b,0x000000b1,0x000000b2,0x00000003, + 0x0004003b,0x000000a9,0x000000b3,0x00000001,0x0004003b,0x00000081,0x000000b8,0x00000003, + 0x0004002b,0x0000007b,0x000000b9,0x00000006,0x00040017,0x000000ba,0x0000007b,0x00000004, + 0x0017001e,0x000000bb,0x00000006,0x00000006,0x00000006,0x00000006,0x0000000f,0x0000000f, + 0x0000000f,0x0000000f,0x000000ba,0x00000009,0x00000009,0x0000000f,0x00000006,0x0000000f, + 0x00000006,0x00000006,0x0000000f,0x00000006,0x00000006,0x00000006,0x0000000f,0x00040020, + 0x000000bc,0x00000002,0x000000bb,0x0004003b,0x000000bc,0x000000bd,0x00000002,0x0004002b, + 0x0000007b,0x000000be,0x0000000d,0x00040020,0x000000c0,0x00000002,0x0000000f,0x0004002b, + 0x0000007b,0x000000c9,0x00000004,0x0004002b,0x0000007b,0x000000ce,0x00000005,0x00040020, + 0x000000da,0x00000002,0x00000006,0x0004002b,0x0000007b,0x000000e1,0x00000008,0x00040020, + 0x000000e9,0x00000003,0x00000007,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x00050041,0x000000a5,0x000000a6,0x000000a3,0x0000007d,0x0004003d, + 0x00000007,0x000000a7,0x000000a6,0x00050051,0x00000006,0x000000f1,0x000000a7,0x00000000, + 0x00050051,0x00000006,0x000000f2,0x000000a7,0x00000001,0x00050051,0x00000006,0x000000f3, + 0x000000a7,0x00000002,0x00050051,0x00000006,0x000000f4,0x000000a7,0x00000003,0x00050050, + 0x00000009,0x000000f5,0x000000f1,0x000000f2,0x00050050,0x00000009,0x000000f6,0x000000f3, + 0x000000f4,0x00050050,0x0000000a,0x000000f7,0x000000f5,0x000000f6,0x0004003d,0x00000009, + 0x000000ab,0x000000aa,0x00050091,0x00000009,0x000000ac,0x000000f7,0x000000ab,0x00050041, + 0x000000ad,0x000000ae,0x000000a3,0x00000083,0x0004003d,0x00000009,0x000000af,0x000000ae, + 0x00050081,0x00000009,0x000000b0,0x000000ac,0x000000af,0x0004003d,0x00000009,0x000000b4, + 0x000000b3,0x0003003e,0x000000b2,0x000000b4,0x00050041,0x000000c0,0x000000c1,0x000000a3, + 0x000000b9,0x0004003d,0x0000000f,0x000000c2,0x000000c1,0x00050041,0x000000c0,0x000000c4, + 0x000000bd,0x000000be,0x0004003d,0x0000000f,0x000000c5,0x000000c4,0x000500aa,0x0000003a, + 0x000000fd,0x000000c2,0x00000039,0x000300f7,0x00000106,0x00000000,0x000400fa,0x000000fd, + 0x00000105,0x000000fe,0x000200f8,0x000000fe,0x00050080,0x0000000f,0x00000100,0x000000c2, + 0x00000041,0x00050084,0x0000000f,0x00000102,0x00000100,0x000000c5,0x0006000c,0x00000009, + 0x00000103,0x00000001,0x0000003e,0x00000102,0x00050051,0x00000006,0x00000104,0x00000103, + 0x00000000,0x000200f9,0x00000106,0x000200f8,0x00000105,0x000200f9,0x00000106,0x000200f8, + 0x00000106,0x000700f5,0x00000006,0x0000015d,0x00000104,0x000000fe,0x0000002e,0x00000105, + 0x0003003e,0x000000b8,0x0000015d,0x00050041,0x000000a5,0x000000cb,0x000000a3,0x000000c9, + 0x0004003d,0x00000007,0x000000cc,0x000000cb,0x00050051,0x00000006,0x0000010f,0x000000cc, + 0x00000000,0x00050051,0x00000006,0x00000110,0x000000cc,0x00000001,0x00050051,0x00000006, + 0x00000111,0x000000cc,0x00000002,0x00050051,0x00000006,0x00000112,0x000000cc,0x00000003, + 0x00050050,0x00000009,0x00000113,0x0000010f,0x00000110,0x00050050,0x00000009,0x00000114, + 0x00000111,0x00000112,0x00050050,0x0000000a,0x00000115,0x00000113,0x00000114,0x00050041, + 0x000000ad,0x000000d1,0x000000a3,0x000000ce,0x0004003d,0x00000009,0x000000d2,0x000000d1, + 0x000500b7,0x0000006a,0x0000011e,0x000000cc,0x00000069,0x0004009a,0x0000003a,0x0000011f, + 0x0000011e,0x000300f7,0x0000013e,0x00000000,0x000400fa,0x0000011f,0x00000128,0x00000120, + 0x000200f8,0x00000120,0x00050051,0x00000006,0x00000122,0x000000d2,0x00000000,0x00050083, + 0x00000006,0x00000123,0x00000122,0x00000094,0x00060041,0x00000081,0x00000124,0x0000007a, + 0x0000007c,0x0000008c,0x0003003e,0x00000124,0x00000123,0x00060041,0x00000081,0x00000125, + 0x0000007a,0x0000007c,0x0000007c,0x0003003e,0x00000125,0x00000123,0x00060041,0x00000081, + 0x00000126,0x0000007a,0x0000007c,0x00000083,0x0003003e,0x00000126,0x00000123,0x00060041, + 0x00000081,0x00000127,0x0000007a,0x0000007c,0x0000007d,0x0003003e,0x00000127,0x00000123, + 0x000200f9,0x0000013e,0x000200f8,0x00000128,0x00050091,0x00000009,0x0000012b,0x00000115, + 0x000000b0,0x00050081,0x00000009,0x0000012d,0x0000012b,0x000000d2,0x00050051,0x00000006, + 0x0000012f,0x0000012d,0x00000000,0x00050081,0x00000006,0x00000130,0x0000012f,0x0000002d, + 0x00060041,0x00000081,0x00000131,0x0000007a,0x0000007c,0x0000007d,0x0003003e,0x00000131, + 0x00000130,0x00050051,0x00000006,0x00000133,0x0000012d,0x00000001,0x00050081,0x00000006, + 0x00000134,0x00000133,0x0000002d,0x00060041,0x00000081,0x00000135,0x0000007a,0x0000007c, + 0x00000083,0x0003003e,0x00000135,0x00000134,0x00050083,0x00000006,0x00000138,0x0000002d, + 0x0000012f,0x00060041,0x00000081,0x00000139,0x0000007a,0x0000007c,0x0000007c,0x0003003e, + 0x00000139,0x00000138,0x00050083,0x00000006,0x0000013c,0x0000002d,0x00000133,0x00060041, + 0x00000081,0x0000013d,0x0000007a,0x0000007c,0x0000008c,0x0003003e,0x0000013d,0x0000013c, + 0x000200f9,0x0000013e,0x000200f8,0x0000013e,0x00050041,0x000000da,0x000000db,0x000000bd, + 0x0000007c,0x0004003d,0x00000006,0x000000dc,0x000000db,0x00050041,0x000000da,0x000000de, + 0x000000bd,0x0000008c,0x0004003d,0x00000006,0x000000df,0x000000de,0x00050051,0x00000006, + 0x00000142,0x000000b0,0x00000000,0x00050085,0x00000006,0x00000144,0x00000142,0x000000dc, + 0x00050083,0x00000006,0x00000145,0x00000144,0x0000002d,0x00050051,0x00000006,0x00000147, + 0x000000b0,0x00000001,0x00050085,0x00000006,0x00000149,0x00000147,0x000000df,0x0006000c, + 0x00000006,0x0000014b,0x00000001,0x00000006,0x000000df,0x00050083,0x00000006,0x0000014c, + 0x00000149,0x0000014b,0x00070050,0x00000007,0x0000014d,0x00000145,0x0000014c,0x0000002e, + 0x0000002d,0x00050041,0x000000c0,0x000000e3,0x000000a3,0x000000e1,0x0004003d,0x0000000f, + 0x000000e4,0x000000e3,0x00040070,0x00000006,0x00000151,0x000000e4,0x00050085,0x00000006, + 0x00000152,0x00000151,0x0000005e,0x00050083,0x00000006,0x00000153,0x0000002d,0x00000152, + 0x00060052,0x00000007,0x0000015c,0x00000153,0x0000014d,0x00000002,0x00050041,0x000000e9, + 0x000000ea,0x0000007a,0x0000007d,0x0003003e,0x000000ea,0x0000015c,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..d78525b4599548ab6de3a5b19f7e0693a768388c GIT binary patch literal 4704 zcmZ9NTWnNS6oyYbZ9zb81?7R%0lY;7K`s{LR%jWBLntjE5M-Qo4)wq=ZDyuG5fhr~ z8!se08F|1)jd%wWtB66P4@6?3k7zVRU+~Qfq9&;ScV@4d9S^MTwf_CDwbxpEoimC0 zdEX3$DLXb*l+Pcleq#Vx7Y+O>|T$H|LedQc>kg5 zhU`9_Pya7TKPX8_XRztrChf#SF1_-G*D!hw#%er#!05AK=wS3ZrN7K9_Cv8UM ztT3K=l_ib=#u;GLOI$E~z-DQk`eye4W_?R~zPvBwV)p=#cLvPv0gQP8 zTPLw|$rY^K!+3wdHhCER150}t?-5w1hfyckb`Rry0^8+byi;I%J&gAX>}e09M_@S# z_s9FiobZ@!bJDDvWCf&H9>hj_zU@g*1AACd0+pL87d;hmP~S&RQmQs5Goe6acMfwgFw&uXO(yF>iV zrr##SdRaDk;zKO#QHQbriqrAOeqAf)5F0)=-yksd-_lAv_Oaj7O0CAn<{JfO{(PhG z#~#)?CSl)t^PzNV;Eq4iO5NOXi;#<2+4IHfvlSoCN5J6P`hVSQa{pL7YT*oW!{$8$ zv)n$B&UXR+Wv%QH+xD+Ww|OM*uOxiu;9t`UpEHerT{_<~_HSsV5A=Syyx!#Te=OiLB})nRoW_M5{v(|mt-7-x4X9{s#2Ato^l z`$IbZ@WJ?Y+>*d$kKFKmL&EHwa0#H*8{F*7~W0n9LP??&~uNxN$z0&RuiA#`!`z_&LQ{sr9x5KfY_XbWRfu)bqDu zvezj4AFbRI>k0XB7Q>ETo8)jS*^yo(uvJ8qS*9xo-pv!(%Xa#YrR+YF|EfXCnfY546bqR z^EmL}fcc#JJZfccyUJPz+Yalqg(3)Ds()O1QYGgtGa(@Wl)VTUb{4NiSl?<2Co zdEim+BH1x6-D+7Z%<8oqz~EY}CDMtd|J7JaWyH7_Ynd>MWi^ArwVt<1UmzdyupCxM zH$Uqq7+mvPB^^J`G{4o-&Cl)%46ffl`pC>(lmEApOA^ju=IG0J5^&>uFC7jsjq`(a zaO=r>#pDinUU2rz&n cyH`3m=ku-L%o|#NmT)&VQ`m5CtD;uPf6pkoYXATM literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.h new file mode 100644 index 000000000..a14c7ed14 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.h @@ -0,0 +1,189 @@ +#pragma once + +const uint32_t draw_msaa_path_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000245,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000115,0x0000011b,0x00000138, + 0x00000147,0x00000149,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00070004, + 0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x0000006e,0x0000674e,0x00030005,0x0000008a,0x00006749, + 0x00030005,0x000000ca,0x00004444,0x00030005,0x000000ce,0x00006277,0x00030005,0x000000f0, + 0x00004344,0x00030005,0x000000f2,0x00003552,0x00030005,0x00000115,0x0000316b,0x00060005, + 0x0000011b,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x0000011e,0x0000424d, + 0x00040006,0x0000011e,0x00000000,0x00006250,0x00040006,0x0000011e,0x00000001,0x00006359, + 0x00040006,0x0000011e,0x00000002,0x00006552,0x00040006,0x0000011e,0x00000003,0x00006553, + 0x00040006,0x0000011e,0x00000004,0x0000366d,0x00040006,0x0000011e,0x00000005,0x0000676d, + 0x00040006,0x0000011e,0x00000006,0x00006544,0x00040006,0x0000011e,0x00000007,0x00006545, + 0x00040006,0x0000011e,0x00000008,0x00003755,0x00040006,0x0000011e,0x00000009,0x0000676a, + 0x00040006,0x0000011e,0x0000000a,0x0000635a,0x00040006,0x0000011e,0x0000000b,0x00003157, + 0x00040006,0x0000011e,0x0000000c,0x0000676e,0x00040006,0x0000011e,0x0000000d,0x00003559, + 0x00040006,0x0000011e,0x0000000e,0x0000324f,0x00040006,0x0000011e,0x0000000f,0x00006461, + 0x00040006,0x0000011e,0x00000010,0x00006579,0x00040006,0x0000011e,0x00000011,0x00003376, + 0x00040006,0x0000011e,0x00000012,0x00003377,0x00040006,0x0000011e,0x00000013,0x00006462, + 0x00040006,0x0000011e,0x00000014,0x00006767,0x00030005,0x00000120,0x0000006b,0x00030005, + 0x00000138,0x00006771,0x00030005,0x00000144,0x00003954,0x00030005,0x00000145,0x00004351, + 0x00030005,0x00000147,0x00003153,0x00030005,0x00000149,0x00003159,0x00040047,0x0000006e, + 0x00000001,0x00000007,0x00040047,0x0000008a,0x00000001,0x00000002,0x00030047,0x000000ca, + 0x00000000,0x00040047,0x000000ca,0x00000021,0x00000009,0x00040047,0x000000ca,0x00000022, + 0x00000000,0x00030047,0x000000ce,0x00000000,0x00040047,0x000000ce,0x00000021,0x00000009, + 0x00040047,0x000000ce,0x00000022,0x00000000,0x00030047,0x000000f0,0x00000000,0x00040047, + 0x000000f0,0x00000021,0x0000000c,0x00040047,0x000000f0,0x00000022,0x00000001,0x00030047, + 0x000000f2,0x00000000,0x00040047,0x000000f2,0x00000021,0x0000000c,0x00040047,0x000000f2, + 0x00000022,0x00000001,0x00040047,0x00000115,0x0000001e,0x00000000,0x00040047,0x0000011b, + 0x0000000b,0x0000000f,0x00030047,0x0000011e,0x00000002,0x00050048,0x0000011e,0x00000000, + 0x00000023,0x00000000,0x00050048,0x0000011e,0x00000001,0x00000023,0x00000004,0x00050048, + 0x0000011e,0x00000002,0x00000023,0x00000008,0x00050048,0x0000011e,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x0000011e,0x00000004,0x00000023,0x00000010,0x00050048,0x0000011e, + 0x00000005,0x00000023,0x00000014,0x00050048,0x0000011e,0x00000006,0x00000023,0x00000018, + 0x00050048,0x0000011e,0x00000007,0x00000023,0x0000001c,0x00050048,0x0000011e,0x00000008, + 0x00000023,0x00000020,0x00050048,0x0000011e,0x00000009,0x00000023,0x00000030,0x00050048, + 0x0000011e,0x0000000a,0x00000023,0x00000038,0x00050048,0x0000011e,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x0000011e,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000011e, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x0000011e,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x0000011e,0x0000000f,0x00000023,0x00000050,0x00050048,0x0000011e,0x00000010, + 0x00000023,0x00000054,0x00050048,0x0000011e,0x00000011,0x00000023,0x00000058,0x00050048, + 0x0000011e,0x00000012,0x00000023,0x0000005c,0x00050048,0x0000011e,0x00000013,0x00000023, + 0x00000060,0x00050048,0x0000011e,0x00000014,0x00000023,0x00000064,0x00040047,0x00000120, + 0x00000021,0x00000000,0x00040047,0x00000120,0x00000022,0x00000000,0x00030047,0x00000125, + 0x00000000,0x00030047,0x00000138,0x00000000,0x00040047,0x00000138,0x0000001e,0x00000000, + 0x00030047,0x00000144,0x00000000,0x00040047,0x00000144,0x00000021,0x0000000a,0x00040047, + 0x00000144,0x00000022,0x00000000,0x00030047,0x00000145,0x00000000,0x00040047,0x00000145, + 0x00000021,0x0000000a,0x00040047,0x00000145,0x00000022,0x00000000,0x00030047,0x00000147, + 0x00000000,0x00030047,0x00000147,0x0000000e,0x00040047,0x00000147,0x0000001e,0x00000004, + 0x00030047,0x00000149,0x00000000,0x00030047,0x00000149,0x0000000e,0x00040047,0x00000149, + 0x0000001e,0x00000006,0x00030047,0x00000166,0x00000000,0x00030047,0x00000190,0x00000000, + 0x00030047,0x00000191,0x00000000,0x00030047,0x00000196,0x00000000,0x00030047,0x00000199, + 0x00000000,0x00030047,0x0000019e,0x00000000,0x00030047,0x000001a0,0x00000000,0x00030047, + 0x000001a1,0x00000000,0x00030047,0x000001ae,0x00000000,0x00030047,0x000001af,0x00000000, + 0x00030047,0x000001b4,0x00000000,0x00030047,0x000001bc,0x00000000,0x00030047,0x000001c3, + 0x00000000,0x00030047,0x000001d2,0x00000000,0x00030047,0x000001d4,0x00000000,0x00030047, + 0x000001d9,0x00000000,0x00030047,0x000001dd,0x00000000,0x00030047,0x000001f7,0x00000000, + 0x00030047,0x000001f8,0x00000000,0x00030047,0x0000020a,0x00000000,0x00030047,0x0000020b, + 0x00000000,0x00030047,0x0000020e,0x00000000,0x00030047,0x00000210,0x00000000,0x00030047, + 0x00000214,0x00000000,0x00030047,0x0000021c,0x00000000,0x00030047,0x0000021f,0x00000000, + 0x00030047,0x00000221,0x00000000,0x00030047,0x00000223,0x00000000,0x00030047,0x0000022a, + 0x00000000,0x00030047,0x0000022c,0x00000000,0x00030047,0x0000022e,0x00000000,0x00030047, + 0x00000230,0x00000000,0x00030047,0x00000234,0x00000000,0x00030047,0x00000236,0x00000000, + 0x00030047,0x00000238,0x00000000,0x00030047,0x00000239,0x00000000,0x00030047,0x00000240, + 0x00000000,0x00030047,0x00000242,0x00000000,0x00030047,0x00000243,0x00000000,0x00030047, + 0x00000241,0x00000000,0x00030047,0x0000023f,0x00000000,0x00030047,0x00000244,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020, + 0x00040017,0x00000007,0x00000006,0x00000004,0x00040017,0x0000000d,0x00000006,0x00000003, + 0x00040017,0x00000019,0x00000006,0x00000002,0x00040015,0x00000034,0x00000020,0x00000000, + 0x0004002b,0x00000006,0x00000048,0x00000000,0x00020014,0x00000049,0x0004002b,0x00000006, + 0x0000004e,0x3f800000,0x0004002b,0x00000006,0x00000058,0x3d897143,0x0004002b,0x00000006, + 0x0000005c,0x3bbf4590,0x0004002b,0x00000006,0x00000063,0x4253ee82,0x00030030,0x00000049, + 0x0000006e,0x00030030,0x00000049,0x0000008a,0x00050034,0x00000049,0x0000008b,0x000000a8, + 0x0000008a,0x0004002b,0x00000006,0x0000009a,0xbf800000,0x0004002b,0x00000006,0x000000b8, + 0x3f7f8000,0x0004002b,0x00000006,0x000000bb,0x3a800000,0x0004002b,0x00000006,0x000000be, + 0x3b000000,0x00090019,0x000000c8,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x000000c9,0x00000000,0x000000c8,0x0004003b,0x000000c9, + 0x000000ca,0x00000000,0x0002001a,0x000000cc,0x00040020,0x000000cd,0x00000000,0x000000cc, + 0x0004003b,0x000000cd,0x000000ce,0x00000000,0x0003001b,0x000000d0,0x000000c8,0x00050034, + 0x00000049,0x000000db,0x000000a8,0x0000008a,0x0004002b,0x00000006,0x000000ee,0x40000000, + 0x0004003b,0x000000c9,0x000000f0,0x00000000,0x0004003b,0x000000cd,0x000000f2,0x00000000, + 0x00050034,0x00000049,0x000000fe,0x000000a8,0x0000008a,0x00040020,0x00000114,0x00000001, + 0x00000007,0x0004003b,0x00000114,0x00000115,0x00000001,0x0004003b,0x00000114,0x0000011b, + 0x00000001,0x00040015,0x0000011c,0x00000020,0x00000001,0x00040017,0x0000011d,0x0000011c, + 0x00000004,0x0017001e,0x0000011e,0x00000006,0x00000006,0x00000006,0x00000006,0x00000034, + 0x00000034,0x00000034,0x00000034,0x0000011d,0x00000019,0x00000019,0x00000034,0x00000006, + 0x00000034,0x00000006,0x00000006,0x00000034,0x00000006,0x00000006,0x00000006,0x00000034, + 0x00040020,0x0000011f,0x00000002,0x0000011e,0x0004003b,0x0000011f,0x00000120,0x00000002, + 0x0004002b,0x0000011c,0x00000121,0x00000011,0x0004002b,0x0000011c,0x00000122,0x00000012, + 0x00040020,0x0000012a,0x00000002,0x00000006,0x00040020,0x00000137,0x00000003,0x00000007, + 0x0004003b,0x00000137,0x00000138,0x00000003,0x0004003b,0x000000cd,0x00000144,0x00000000, + 0x0004003b,0x000000c9,0x00000145,0x00000000,0x00040020,0x00000146,0x00000001,0x00000019, + 0x0004003b,0x00000146,0x00000147,0x00000001,0x00040020,0x00000148,0x00000001,0x00000006, + 0x0004003b,0x00000148,0x00000149,0x00000001,0x00030001,0x00000007,0x0000023c,0x00050036, + 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000007, + 0x00000117,0x00000115,0x00050051,0x00000006,0x0000015a,0x00000117,0x00000003,0x000500be, + 0x00000049,0x0000015b,0x0000015a,0x00000048,0x000300f7,0x000001c7,0x00000000,0x000400fa, + 0x0000015b,0x0000015c,0x0000016a,0x000200f8,0x0000015c,0x000300f7,0x00000169,0x00000000, + 0x000400fa,0x0000008b,0x0000015f,0x00000163,0x000200f8,0x0000015f,0x0005008e,0x00000007, + 0x00000162,0x00000117,0x0000004e,0x000200f9,0x00000169,0x000200f8,0x00000163,0x00050051, + 0x00000006,0x00000166,0x00000117,0x00000003,0x00050085,0x00000006,0x00000167,0x00000166, + 0x0000004e,0x00060052,0x00000007,0x00000214,0x00000167,0x00000117,0x00000003,0x000200f9, + 0x00000169,0x000200f8,0x00000169,0x000700f5,0x00000007,0x00000240,0x00000162,0x0000015f, + 0x00000214,0x00000163,0x000200f9,0x000001c7,0x000200f8,0x0000016a,0x000500ba,0x00000049, + 0x0000016d,0x0000015a,0x0000009a,0x000300f7,0x000001c6,0x00000000,0x000400fa,0x0000016d, + 0x0000016e,0x000001a9,0x000200f8,0x0000016e,0x00050051,0x00000006,0x00000170,0x00000117, + 0x00000002,0x000500ba,0x00000049,0x00000171,0x00000170,0x00000048,0x000300f7,0x00000179, + 0x00000000,0x000400fa,0x00000171,0x00000172,0x00000175,0x000200f8,0x00000172,0x00050051, + 0x00000006,0x00000174,0x00000117,0x00000000,0x000200f9,0x00000179,0x000200f8,0x00000175, + 0x0007004f,0x00000019,0x00000177,0x00000117,0x00000117,0x00000000,0x00000001,0x0006000c, + 0x00000006,0x00000178,0x00000001,0x00000042,0x00000177,0x000200f9,0x00000179,0x000200f8, + 0x00000179,0x000700f5,0x00000006,0x0000023d,0x00000174,0x00000172,0x00000178,0x00000175, + 0x0008000c,0x00000006,0x0000017c,0x00000001,0x0000002b,0x0000023d,0x00000048,0x0000004e, + 0x0006000c,0x00000006,0x0000017f,0x00000001,0x00000004,0x00000170,0x000500ba,0x00000049, + 0x00000181,0x0000017f,0x0000004e,0x000300f7,0x0000018b,0x00000000,0x000400fa,0x00000181, + 0x00000182,0x00000186,0x000200f8,0x00000182,0x00050085,0x00000006,0x00000184,0x000000b8, + 0x0000017c,0x00050081,0x00000006,0x00000185,0x00000184,0x000000bb,0x000200f9,0x0000018b, + 0x000200f8,0x00000186,0x00050085,0x00000006,0x00000188,0x000000be,0x0000017c,0x00050081, + 0x00000006,0x0000018a,0x00000188,0x0000017f,0x000200f9,0x0000018b,0x000200f8,0x0000018b, + 0x000700f5,0x00000006,0x0000023e,0x00000185,0x00000182,0x0000018a,0x00000186,0x0004007f, + 0x00000006,0x0000018f,0x0000015a,0x0004003d,0x000000c8,0x00000190,0x000000ca,0x0004003d, + 0x000000cc,0x00000191,0x000000ce,0x00050056,0x000000d0,0x00000192,0x00000190,0x00000191, + 0x00050050,0x00000019,0x00000195,0x0000023e,0x0000018f,0x00070058,0x00000007,0x00000196, + 0x00000192,0x00000195,0x00000002,0x00000048,0x00050051,0x00000006,0x00000199,0x00000196, + 0x00000003,0x00050085,0x00000006,0x0000019a,0x00000199,0x0000004e,0x00060052,0x00000007, + 0x0000021c,0x0000019a,0x00000196,0x00000003,0x000300f7,0x000001a8,0x00000000,0x000400fa, + 0x000000db,0x0000019c,0x000001a8,0x000200f8,0x0000019c,0x00050051,0x00000006,0x0000019e, + 0x0000021c,0x00000003,0x0008004f,0x0000000d,0x000001a0,0x0000021c,0x0000021c,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x0000000d,0x000001a1,0x000001a0,0x0000019e,0x00050051, + 0x00000006,0x000001a3,0x000001a1,0x00000000,0x00060052,0x00000007,0x0000021f,0x000001a3, + 0x0000021c,0x00000000,0x00050051,0x00000006,0x000001a5,0x000001a1,0x00000001,0x00060052, + 0x00000007,0x00000221,0x000001a5,0x0000021f,0x00000001,0x00050051,0x00000006,0x000001a7, + 0x000001a1,0x00000002,0x00060052,0x00000007,0x00000223,0x000001a7,0x00000221,0x00000002, + 0x000200f9,0x000001a8,0x000200f8,0x000001a8,0x000700f5,0x00000007,0x00000242,0x0000021c, + 0x0000018b,0x00000223,0x0000019c,0x000200f9,0x000001c6,0x000200f8,0x000001a9,0x0004007f, + 0x00000006,0x000001ac,0x0000015a,0x00050083,0x00000006,0x000001ad,0x000001ac,0x000000ee, + 0x0004003d,0x000000c8,0x000001ae,0x000000f0,0x0004003d,0x000000cc,0x000001af,0x000000f2, + 0x00050056,0x000000d0,0x000001b0,0x000001ae,0x000001af,0x0007004f,0x00000019,0x000001b2, + 0x00000117,0x00000117,0x00000000,0x00000001,0x00070058,0x00000007,0x000001b4,0x000001b0, + 0x000001b2,0x00000002,0x000001ad,0x00050051,0x00000006,0x000001b6,0x00000117,0x00000002, + 0x00050085,0x00000006,0x000001b8,0x000001b6,0x0000004e,0x000300f7,0x000001c5,0x00000000, + 0x000400fa,0x000000fe,0x000001b9,0x000001bd,0x000200f8,0x000001b9,0x0005008e,0x00000007, + 0x000001bc,0x000001b4,0x000001b8,0x000200f9,0x000001c5,0x000200f8,0x000001bd,0x0008004f, + 0x0000000d,0x000001d2,0x000001b4,0x000001b4,0x00000000,0x00000001,0x00000002,0x00050051, + 0x00000006,0x000001d4,0x000001b4,0x00000003,0x000500b7,0x00000049,0x000001d5,0x000001d4, + 0x00000048,0x000300f7,0x000001db,0x00000000,0x000400fa,0x000001d5,0x000001d6,0x000001da, + 0x000200f8,0x000001d6,0x00050088,0x00000006,0x000001d9,0x0000004e,0x000001d4,0x000200f9, + 0x000001db,0x000200f8,0x000001da,0x000200f9,0x000001db,0x000200f8,0x000001db,0x000700f5, + 0x00000006,0x00000239,0x000001d9,0x000001d6,0x00000048,0x000001da,0x0005008e,0x0000000d, + 0x000001dd,0x000001d2,0x00000239,0x00050085,0x00000006,0x000001c3,0x000001d4,0x000001b8, + 0x00050051,0x00000006,0x000001e3,0x000001dd,0x00000000,0x00060052,0x00000007,0x0000022a, + 0x000001e3,0x0000023c,0x00000000,0x00050051,0x00000006,0x000001e5,0x000001dd,0x00000001, + 0x00060052,0x00000007,0x0000022c,0x000001e5,0x0000022a,0x00000001,0x00050051,0x00000006, + 0x000001e7,0x000001dd,0x00000002,0x00060052,0x00000007,0x0000022e,0x000001e7,0x0000022c, + 0x00000002,0x00060052,0x00000007,0x00000230,0x000001c3,0x0000022e,0x00000003,0x000200f9, + 0x000001c5,0x000200f8,0x000001c5,0x000700f5,0x00000007,0x00000243,0x000001bc,0x000001b9, + 0x00000230,0x000001db,0x000200f9,0x000001c6,0x000200f8,0x000001c6,0x000700f5,0x00000007, + 0x00000241,0x00000242,0x000001a8,0x00000243,0x000001c5,0x000200f9,0x000001c7,0x000200f8, + 0x000001c7,0x000700f5,0x00000007,0x0000023f,0x00000240,0x00000169,0x00000241,0x000001c6, + 0x0008004f,0x0000000d,0x00000125,0x0000023f,0x0000023f,0x00000000,0x00000001,0x00000002, + 0x0004003d,0x00000007,0x00000127,0x0000011b,0x0007004f,0x00000019,0x00000128,0x00000127, + 0x00000127,0x00000000,0x00000001,0x00050041,0x0000012a,0x0000012b,0x00000120,0x00000121, + 0x0004003d,0x00000006,0x0000012c,0x0000012b,0x00050041,0x0000012a,0x0000012e,0x00000120, + 0x00000122,0x0004003d,0x00000006,0x0000012f,0x0000012e,0x000300f7,0x000001fb,0x00000000, + 0x000400fa,0x0000006e,0x000001f1,0x000001f9,0x000200f8,0x000001f1,0x00050051,0x00000006, + 0x00000202,0x00000128,0x00000000,0x00050085,0x00000006,0x00000203,0x00000058,0x00000202, + 0x00050051,0x00000006,0x00000205,0x00000128,0x00000001,0x00050085,0x00000006,0x00000206, + 0x0000005c,0x00000205,0x00050081,0x00000006,0x00000207,0x00000203,0x00000206,0x0006000c, + 0x00000006,0x00000208,0x00000001,0x0000000a,0x00000207,0x00050085,0x00000006,0x0000020a, + 0x00000063,0x00000208,0x0006000c,0x00000006,0x0000020b,0x00000001,0x0000000a,0x0000020a, + 0x00050085,0x00000006,0x0000020e,0x0000020b,0x0000012c,0x00050081,0x00000006,0x00000210, + 0x0000020e,0x0000012f,0x00060050,0x0000000d,0x000001f7,0x00000210,0x00000210,0x00000210, + 0x00050081,0x0000000d,0x000001f8,0x000001f7,0x00000125,0x000200f9,0x000001fb,0x000200f8, + 0x000001f9,0x000200f9,0x000001fb,0x000200f8,0x000001fb,0x000700f5,0x0000000d,0x00000244, + 0x000001f8,0x000001f1,0x00000125,0x000001f9,0x00050051,0x00000006,0x00000132,0x00000244, + 0x00000000,0x00060052,0x00000007,0x00000234,0x00000132,0x0000023f,0x00000000,0x00050051, + 0x00000006,0x00000134,0x00000244,0x00000001,0x00060052,0x00000007,0x00000236,0x00000134, + 0x00000234,0x00000001,0x00050051,0x00000006,0x00000136,0x00000244,0x00000002,0x00060052, + 0x00000007,0x00000238,0x00000136,0x00000236,0x00000002,0x0003003e,0x00000138,0x00000238, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..e751998c45d8013e7cafb1b28886c6d57a386b98 GIT binary patch literal 5896 zcmZ9PeQ1?s7{=dr<}|gbshMedrbwY;%jTT=Y5}( zD401sitdU=MI)lxf+#NIq5?6IxT5%3*U-{1udly-UfF_D1jSJz)}a{_jf@KQr1rFS zWoekGhAFBQs&%TXRL9B(jRq4+XoM)bAihxkbq%Q%%~h$s=UUq{xl~_&Z?3g7lWH62 z=#bglwkebDmu?ig+I4GFeXTv4yED1&OkZEBKeN4mAeTvX3}n;&UA@^pb!&arH8$2Y z)TYv#H>=Mb-I-K(S2mMs@5-sauB{n#Bj_{ey0Yo+fp#w_)NIw>SlbfDOl@t=b+xu> z`txJmQ?rl=GrBT`=2Jw6IGEEg%Oz2q<+nYTAv=W+3#kp+1iOT^mohN`cE>>X}C<797rY^eQS+1s2wUUr-FpCG$a;}g3i`!5?z4sQv3jqutLk#$io8RdhML$FQ?GDkLA&NpR(Mp&h%@vCEY*K)Htx7Ax-S!yeb`#A3g5Yw>v?^pjdLS!5B6u@ zE$iby*9UW$poOp&VoM*`+^gWs=KFXA9#`pV$j!le@NdY~J5+^iMqO zosCUg?Y)fuN@?|r*Fifr?_4jP#y+Oc`p>Zh8B$6cZcl`B`77kfxy{99u9W-k@X z{3gkXxU3ONe;b71(4Gpp{)}w+dT}?^a#on~xB8%Mqv|GA`Ua!v($h4Ym6Yss(12f6 z-;CcT%y^vB+w#Yce$d*S_-@#o_J(|E-lg!S_5IQBUs9o~l#X$k2R@92 zmUS^UYxydyy+@d}bGBL6cfu6bPFq&>16BOMHs{U4%!B>6zP8AQw|(3pOrbB@a;gKW z^aZxQ`i1F>!aVUqgSJsCBHyk&*1iza?J}^dg3k9rU+fFIrJ5{bF*ZK*KU%j! z+FlUWPx+tMu?F_u#@HF!$u-t!Yu+tP8(Q}7fG~wM)3!(TWmVP#w)nmz%=?pZcZZno z6^7?M${OekKm5&apD^!L@3&tZJoE5=_}ki-Y3=mS9MIF}PR)_Eza~r$aAwZQ=I+9K z7n^r1_m_)$KBal`Zhb>G8u%u0#OF<6#-OitArHChpruVsab8%=4~e6lb7*TjEF0eE zJa-0o)3V3MWK-B<-tBM8hGVb5HU@Vp{28NBapt>wBye^Ykr~g8^Gf?s5oqwWe%=*^ zr`TEK{sM3PnD)J(MQ&Q|H}LqtoA&*n6+Nis{sWH>Jn^)(@w79}eTA`!F+QvtE$5eg z;LKWlKNKduFKUg%`y*kv>%tau?v{K5E#}-W`373dKb4IJ-p=G_!kkBcCN1{I#p8p9 zbugx_`*UG@;4StiWW(Dz`c{}ijQRF{Df=5$)&{os>q%k8!k_iyhX$?1{E{#lDuoAQ z+k7sEHuB^P?Gg8%pTxo2yX-1XD$IwrpH+WRWi0T%u(wx)Sp&Yz2R}4uy$x??lRGJX z^uu^)Eg!E5Gk-L;S7&6?KWnx%{3?u=VtL2?8GZ?iRWa>vL5tk9+^^yBfj8~%K}#2= z<^BzikLS6IGdJ4VOCJy7V!6xxnz#{1eAo-Lmb*Mn%l(^NC-?EAAGBxnWM6rjmiu|7 zD&Io<=*MzkmN4y9icERu^PO+zLn5Zc`uz9iVPQBbg~tlTc(%YC)ud{PD(8hWH8=34 znHMxOoaPZ>c-~?E=t&`;vU>g@`?e};0^9x4pUzQqvWQD?+eQfEH&T^$^XI=_S{&`Bsd+mHFe_8-mimj8$FmIJ0O3tBw}bDaN= f@c6)+wmfJ>4{G^;36Br_GR3z-HvGTxu2B6S_*x1= literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.h new file mode 100644 index 000000000..19a373357 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.h @@ -0,0 +1,704 @@ +#pragma once + +const uint32_t draw_msaa_path_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000d5f,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000b000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000395, + 0x0000039d,0x000003c6,0x000003e6,0x00000401,0x0000040f,0x00030010,0x00000004,0x00000007, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00070004,0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972, + 0x0073656c,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000105,0x0000674e, + 0x00030005,0x000002b0,0x0000674d,0x00030005,0x0000030b,0x00006749,0x00030005,0x0000034b, + 0x00004444,0x00030005,0x0000034f,0x00006277,0x00030005,0x00000370,0x00004344,0x00030005, + 0x00000372,0x00003552,0x00030005,0x00000395,0x0000316b,0x00030005,0x0000039d,0x00003159, + 0x00030005,0x000003a4,0x0000444a,0x00060005,0x000003c6,0x535f6c67,0x6c706d61,0x73614d65, + 0x006e496b,0x00060005,0x000003e6,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x000003e7,0x0000424d,0x00040006,0x000003e7,0x00000000,0x00006250,0x00040006,0x000003e7, + 0x00000001,0x00006359,0x00040006,0x000003e7,0x00000002,0x00006552,0x00040006,0x000003e7, + 0x00000003,0x00006553,0x00040006,0x000003e7,0x00000004,0x0000366d,0x00040006,0x000003e7, + 0x00000005,0x0000676d,0x00040006,0x000003e7,0x00000006,0x00006544,0x00040006,0x000003e7, + 0x00000007,0x00006545,0x00040006,0x000003e7,0x00000008,0x00003755,0x00040006,0x000003e7, + 0x00000009,0x0000676a,0x00040006,0x000003e7,0x0000000a,0x0000635a,0x00040006,0x000003e7, + 0x0000000b,0x00003157,0x00040006,0x000003e7,0x0000000c,0x0000676e,0x00040006,0x000003e7, + 0x0000000d,0x00003559,0x00040006,0x000003e7,0x0000000e,0x0000324f,0x00040006,0x000003e7, + 0x0000000f,0x00006461,0x00040006,0x000003e7,0x00000010,0x00006579,0x00040006,0x000003e7, + 0x00000011,0x00003376,0x00040006,0x000003e7,0x00000012,0x00003377,0x00040006,0x000003e7, + 0x00000013,0x00006462,0x00040006,0x000003e7,0x00000014,0x00006767,0x00030005,0x000003e9, + 0x0000006b,0x00030005,0x00000401,0x00006771,0x00030005,0x0000040c,0x00003954,0x00030005, + 0x0000040d,0x00004351,0x00030005,0x0000040f,0x00003153,0x00040047,0x00000105,0x00000001, + 0x00000007,0x00040047,0x000002b0,0x00000001,0x00000006,0x00040047,0x0000030b,0x00000001, + 0x00000002,0x00030047,0x0000034b,0x00000000,0x00040047,0x0000034b,0x00000021,0x00000009, + 0x00040047,0x0000034b,0x00000022,0x00000000,0x00030047,0x0000034f,0x00000000,0x00040047, + 0x0000034f,0x00000021,0x00000009,0x00040047,0x0000034f,0x00000022,0x00000000,0x00030047, + 0x00000370,0x00000000,0x00040047,0x00000370,0x00000021,0x0000000c,0x00040047,0x00000370, + 0x00000022,0x00000001,0x00030047,0x00000372,0x00000000,0x00040047,0x00000372,0x00000021, + 0x0000000c,0x00040047,0x00000372,0x00000022,0x00000001,0x00040047,0x00000395,0x0000001e, + 0x00000000,0x00030047,0x0000039d,0x00000000,0x00030047,0x0000039d,0x0000000e,0x00040047, + 0x0000039d,0x0000001e,0x00000006,0x00030047,0x0000039f,0x00000000,0x00030047,0x000003a4, + 0x00000000,0x00040047,0x000003a4,0x00000021,0x00000000,0x00040047,0x000003a4,0x00000022, + 0x00000002,0x00040047,0x000003a4,0x0000002b,0x00000000,0x00030047,0x000003a5,0x00000000, + 0x00030047,0x000003a8,0x00000000,0x00030047,0x000003a9,0x00000000,0x00030047,0x000003aa, + 0x00000000,0x00030047,0x000003ab,0x00000000,0x00030047,0x000003ac,0x00000000,0x00030047, + 0x000003ad,0x00000000,0x00030047,0x000003ae,0x00000000,0x00030047,0x000003af,0x00000000, + 0x00030047,0x000003b0,0x00000000,0x00030047,0x000003b1,0x00000000,0x00030047,0x000003b2, + 0x00000000,0x00030047,0x000003b3,0x00000000,0x00030047,0x000003b4,0x00000000,0x00030047, + 0x000003b5,0x00000000,0x00030047,0x000003b6,0x00000000,0x00030047,0x000003b7,0x00000000, + 0x00030047,0x000003b8,0x00000000,0x00030047,0x000003b9,0x00000000,0x00030047,0x000003ba, + 0x00000000,0x00030047,0x000003bb,0x00000000,0x00030047,0x000003bc,0x00000000,0x00030047, + 0x000003bd,0x00000000,0x00030047,0x000003be,0x00000000,0x00030047,0x000003bf,0x00000000, + 0x00030047,0x000003c0,0x00000000,0x00030047,0x000003c1,0x00000000,0x00030047,0x000003c2, + 0x00000000,0x00030047,0x000003c3,0x00000000,0x00040047,0x000003c6,0x0000000b,0x00000014, + 0x00030047,0x000003c6,0x0000000e,0x00030047,0x000003cf,0x00000000,0x00030047,0x000003dc, + 0x00000000,0x00030047,0x000003de,0x00000000,0x00030047,0x000003df,0x00000000,0x00040047, + 0x000003e6,0x0000000b,0x0000000f,0x00030047,0x000003e7,0x00000002,0x00050048,0x000003e7, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000003e7,0x00000001,0x00000023,0x00000004, + 0x00050048,0x000003e7,0x00000002,0x00000023,0x00000008,0x00050048,0x000003e7,0x00000003, + 0x00000023,0x0000000c,0x00050048,0x000003e7,0x00000004,0x00000023,0x00000010,0x00050048, + 0x000003e7,0x00000005,0x00000023,0x00000014,0x00050048,0x000003e7,0x00000006,0x00000023, + 0x00000018,0x00050048,0x000003e7,0x00000007,0x00000023,0x0000001c,0x00050048,0x000003e7, + 0x00000008,0x00000023,0x00000020,0x00050048,0x000003e7,0x00000009,0x00000023,0x00000030, + 0x00050048,0x000003e7,0x0000000a,0x00000023,0x00000038,0x00050048,0x000003e7,0x0000000b, + 0x00000023,0x00000040,0x00050048,0x000003e7,0x0000000c,0x00000023,0x00000044,0x00050048, + 0x000003e7,0x0000000d,0x00000023,0x00000048,0x00050048,0x000003e7,0x0000000e,0x00000023, + 0x0000004c,0x00050048,0x000003e7,0x0000000f,0x00000023,0x00000050,0x00050048,0x000003e7, + 0x00000010,0x00000023,0x00000054,0x00050048,0x000003e7,0x00000011,0x00000023,0x00000058, + 0x00050048,0x000003e7,0x00000012,0x00000023,0x0000005c,0x00050048,0x000003e7,0x00000013, + 0x00000023,0x00000060,0x00050048,0x000003e7,0x00000014,0x00000023,0x00000064,0x00040047, + 0x000003e9,0x00000021,0x00000000,0x00040047,0x000003e9,0x00000022,0x00000000,0x00030047, + 0x000003ee,0x00000000,0x00030047,0x00000401,0x00000000,0x00040047,0x00000401,0x0000001e, + 0x00000000,0x00030047,0x0000040c,0x00000000,0x00040047,0x0000040c,0x00000021,0x0000000a, + 0x00040047,0x0000040c,0x00000022,0x00000000,0x00030047,0x0000040d,0x00000000,0x00040047, + 0x0000040d,0x00000021,0x0000000a,0x00040047,0x0000040d,0x00000022,0x00000000,0x00030047, + 0x0000040f,0x00000000,0x00030047,0x0000040f,0x0000000e,0x00040047,0x0000040f,0x0000001e, + 0x00000004,0x00030047,0x00000434,0x00000000,0x00030047,0x0000045e,0x00000000,0x00030047, + 0x0000045f,0x00000000,0x00030047,0x00000464,0x00000000,0x00030047,0x00000467,0x00000000, + 0x00030047,0x0000046c,0x00000000,0x00030047,0x0000046e,0x00000000,0x00030047,0x0000046f, + 0x00000000,0x00030047,0x0000047c,0x00000000,0x00030047,0x0000047d,0x00000000,0x00030047, + 0x00000482,0x00000000,0x00030047,0x0000048a,0x00000000,0x00030047,0x00000491,0x00000000, + 0x00030047,0x000004a0,0x00000000,0x00030047,0x000004a2,0x00000000,0x00030047,0x000004a7, + 0x00000000,0x00030047,0x000004ab,0x00000000,0x00030047,0x000004bc,0x00000000,0x00030047, + 0x000004c9,0x00000000,0x00030047,0x000004cb,0x00000000,0x00030047,0x000004cc,0x00000000, + 0x00030047,0x000004ce,0x00000000,0x00030047,0x000004cf,0x00000000,0x00030047,0x000004d1, + 0x00000000,0x00030047,0x000004d2,0x00000000,0x00030047,0x000004d3,0x00000000,0x00030047, + 0x000004d9,0x00000000,0x00030047,0x000004dc,0x00000000,0x00030047,0x000004f2,0x00000000, + 0x00030047,0x00000501,0x00000000,0x00030047,0x00000502,0x00000000,0x00030047,0x00000504, + 0x00000000,0x00030047,0x0000052e,0x00000000,0x00030047,0x00000530,0x00000000,0x00030047, + 0x00000532,0x00000000,0x00030047,0x00000534,0x00000000,0x00030047,0x00000537,0x00000000, + 0x00030047,0x00000538,0x00000000,0x00030047,0x0000053a,0x00000000,0x00030047,0x0000053c, + 0x00000000,0x00030047,0x00000540,0x00000000,0x00030047,0x00000542,0x00000000,0x00030047, + 0x00000544,0x00000000,0x00030047,0x00000547,0x00000000,0x00030047,0x00000548,0x00000000, + 0x00030047,0x00000549,0x00000000,0x00030047,0x0000054b,0x00000000,0x00030047,0x0000054d, + 0x00000000,0x00030047,0x0000054f,0x00000000,0x00030047,0x00000551,0x00000000,0x00030047, + 0x00000557,0x00000000,0x00030047,0x00000558,0x00000000,0x00030047,0x0000055f,0x00000000, + 0x00030047,0x00000561,0x00000000,0x00030047,0x00000564,0x00000000,0x00030047,0x00000566, + 0x00000000,0x00030047,0x00000567,0x00000000,0x00030047,0x0000056a,0x00000000,0x00030047, + 0x0000056c,0x00000000,0x00030047,0x0000056d,0x00000000,0x00030047,0x00000570,0x00000000, + 0x00030047,0x00000573,0x00000000,0x00030047,0x00000574,0x00000000,0x00030047,0x00000576, + 0x00000000,0x00030047,0x00000579,0x00000000,0x00030047,0x0000057e,0x00000000,0x00030047, + 0x0000057f,0x00000000,0x00030047,0x00000587,0x00000000,0x00030047,0x0000058d,0x00000000, + 0x00030047,0x0000058f,0x00000000,0x00030047,0x00000590,0x00000000,0x00030047,0x00000591, + 0x00000000,0x00030047,0x00000594,0x00000000,0x00030047,0x00000597,0x00000000,0x00030047, + 0x00000598,0x00000000,0x00030047,0x00000599,0x00000000,0x00030047,0x0000059b,0x00000000, + 0x00030047,0x0000059e,0x00000000,0x00030047,0x0000059f,0x00000000,0x00030047,0x000005a1, + 0x00000000,0x00030047,0x000005a3,0x00000000,0x00030047,0x000005a5,0x00000000,0x00030047, + 0x000005a9,0x00000000,0x00030047,0x000005ab,0x00000000,0x00030047,0x000005ad,0x00000000, + 0x00030047,0x000005b0,0x00000000,0x00030047,0x000005b1,0x00000000,0x00030047,0x000005b2, + 0x00000000,0x00030047,0x000005bb,0x00000000,0x00030047,0x000005c1,0x00000000,0x00030047, + 0x000005c2,0x00000000,0x00030047,0x000005c7,0x00000000,0x00030047,0x000005cd,0x00000000, + 0x00030047,0x000005ce,0x00000000,0x00030047,0x000005cf,0x00000000,0x00030047,0x000005d2, + 0x00000000,0x00030047,0x000005d3,0x00000000,0x00030047,0x000005d4,0x00000000,0x00030047, + 0x000005da,0x00000000,0x00030047,0x000005db,0x00000000,0x00030047,0x000005dc,0x00000000, + 0x00030047,0x000005e6,0x00000000,0x00030047,0x000005e7,0x00000000,0x00030047,0x000005e9, + 0x00000000,0x00030047,0x000005ea,0x00000000,0x00030047,0x000005eb,0x00000000,0x00030047, + 0x000005ec,0x00000000,0x00030047,0x000005ed,0x00000000,0x00030047,0x000005f0,0x00000000, + 0x00030047,0x000005f1,0x00000000,0x00030047,0x000005f2,0x00000000,0x00030047,0x000005f4, + 0x00000000,0x00030047,0x000005f6,0x00000000,0x00030047,0x000005f8,0x00000000,0x00030047, + 0x000005fa,0x00000000,0x00030047,0x000005fb,0x00000000,0x00030047,0x000005fe,0x00000000, + 0x00030047,0x00000601,0x00000000,0x00030047,0x00000609,0x00000000,0x00030047,0x0000060c, + 0x00000000,0x00030047,0x00000614,0x00000000,0x00030047,0x00000617,0x00000000,0x00030047, + 0x0000061e,0x00000000,0x00030047,0x00000621,0x00000000,0x00030047,0x00000627,0x00000000, + 0x00030047,0x0000062c,0x00000000,0x00030047,0x0000062e,0x00000000,0x00030047,0x00000633, + 0x00000000,0x00030047,0x00000637,0x00000000,0x00030047,0x000006d3,0x00000000,0x00030047, + 0x000006d7,0x00000000,0x00030047,0x000006d8,0x00000000,0x00030047,0x000006e8,0x00000000, + 0x00030047,0x000006eb,0x00000000,0x00030047,0x000006ec,0x00000000,0x00030047,0x000006f0, + 0x00000000,0x00030047,0x000006f2,0x00000000,0x00030047,0x000006f3,0x00000000,0x00030047, + 0x000006fc,0x00000000,0x00030047,0x00000703,0x00000000,0x00030047,0x00000708,0x00000000, + 0x00030047,0x0000070b,0x00000000,0x00030047,0x0000070c,0x00000000,0x00030047,0x00000710, + 0x00000000,0x00030047,0x00000712,0x00000000,0x00030047,0x00000713,0x00000000,0x00030047, + 0x00000718,0x00000000,0x00030047,0x0000071b,0x00000000,0x00030047,0x0000071c,0x00000000, + 0x00030047,0x00000720,0x00000000,0x00030047,0x00000722,0x00000000,0x00030047,0x00000723, + 0x00000000,0x00030047,0x00000739,0x00000000,0x00030047,0x0000073a,0x00000000,0x00030047, + 0x0000073c,0x00000000,0x00030047,0x00000742,0x00000000,0x00030047,0x00000746,0x00000000, + 0x00030047,0x00000747,0x00000000,0x00030047,0x0000074a,0x00000000,0x00030047,0x0000074c, + 0x00000000,0x00030047,0x0000074d,0x00000000,0x00030047,0x0000074e,0x00000000,0x00030047, + 0x00000751,0x00000000,0x00030047,0x00000753,0x00000000,0x00030047,0x00000754,0x00000000, + 0x00030047,0x0000075c,0x00000000,0x00030047,0x0000076e,0x00000000,0x00030047,0x0000078d, + 0x00000000,0x00030047,0x00000790,0x00000000,0x00030047,0x00000791,0x00000000,0x00030047, + 0x00000795,0x00000000,0x00030047,0x00000797,0x00000000,0x00030047,0x00000798,0x00000000, + 0x00030047,0x000007a1,0x00000000,0x00030047,0x000007a8,0x00000000,0x00030047,0x000007d7, + 0x00000000,0x00030047,0x000007db,0x00000000,0x00030047,0x000007dc,0x00000000,0x00030047, + 0x000007ec,0x00000000,0x00030047,0x000007ef,0x00000000,0x00030047,0x000007f0,0x00000000, + 0x00030047,0x000007f4,0x00000000,0x00030047,0x000007f6,0x00000000,0x00030047,0x000007f7, + 0x00000000,0x00030047,0x00000800,0x00000000,0x00030047,0x00000807,0x00000000,0x00030047, + 0x0000080c,0x00000000,0x00030047,0x0000080f,0x00000000,0x00030047,0x00000810,0x00000000, + 0x00030047,0x00000814,0x00000000,0x00030047,0x00000816,0x00000000,0x00030047,0x00000817, + 0x00000000,0x00030047,0x0000081c,0x00000000,0x00030047,0x0000081f,0x00000000,0x00030047, + 0x00000820,0x00000000,0x00030047,0x00000824,0x00000000,0x00030047,0x00000826,0x00000000, + 0x00030047,0x00000827,0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x0000083e, + 0x00000000,0x00030047,0x00000840,0x00000000,0x00030047,0x00000846,0x00000000,0x00030047, + 0x0000084a,0x00000000,0x00030047,0x0000084b,0x00000000,0x00030047,0x0000084e,0x00000000, + 0x00030047,0x00000850,0x00000000,0x00030047,0x00000851,0x00000000,0x00030047,0x00000852, + 0x00000000,0x00030047,0x00000855,0x00000000,0x00030047,0x00000857,0x00000000,0x00030047, + 0x00000858,0x00000000,0x00030047,0x00000860,0x00000000,0x00030047,0x00000872,0x00000000, + 0x00030047,0x00000891,0x00000000,0x00030047,0x00000894,0x00000000,0x00030047,0x00000895, + 0x00000000,0x00030047,0x00000899,0x00000000,0x00030047,0x0000089b,0x00000000,0x00030047, + 0x0000089c,0x00000000,0x00030047,0x000008a5,0x00000000,0x00030047,0x000008ac,0x00000000, + 0x00030047,0x000008e1,0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008e4, + 0x00000000,0x00030047,0x000008ea,0x00000000,0x00030047,0x000008ee,0x00000000,0x00030047, + 0x000008ef,0x00000000,0x00030047,0x000008f2,0x00000000,0x00030047,0x000008f4,0x00000000, + 0x00030047,0x000008f5,0x00000000,0x00030047,0x000008f6,0x00000000,0x00030047,0x000008f9, + 0x00000000,0x00030047,0x000008fb,0x00000000,0x00030047,0x000008fc,0x00000000,0x00030047, + 0x00000904,0x00000000,0x00030047,0x00000916,0x00000000,0x00030047,0x00000935,0x00000000, + 0x00030047,0x00000938,0x00000000,0x00030047,0x00000939,0x00000000,0x00030047,0x0000093d, + 0x00000000,0x00030047,0x0000093f,0x00000000,0x00030047,0x00000940,0x00000000,0x00030047, + 0x00000949,0x00000000,0x00030047,0x00000950,0x00000000,0x00030047,0x00000985,0x00000000, + 0x00030047,0x00000986,0x00000000,0x00030047,0x00000988,0x00000000,0x00030047,0x0000098e, + 0x00000000,0x00030047,0x00000992,0x00000000,0x00030047,0x00000993,0x00000000,0x00030047, + 0x00000996,0x00000000,0x00030047,0x00000998,0x00000000,0x00030047,0x00000999,0x00000000, + 0x00030047,0x0000099a,0x00000000,0x00030047,0x0000099d,0x00000000,0x00030047,0x0000099f, + 0x00000000,0x00030047,0x000009a0,0x00000000,0x00030047,0x000009a8,0x00000000,0x00030047, + 0x000009ba,0x00000000,0x00030047,0x000009d9,0x00000000,0x00030047,0x000009dc,0x00000000, + 0x00030047,0x000009dd,0x00000000,0x00030047,0x000009e1,0x00000000,0x00030047,0x000009e3, + 0x00000000,0x00030047,0x000009e4,0x00000000,0x00030047,0x000009ed,0x00000000,0x00030047, + 0x000009f4,0x00000000,0x00030047,0x00000a16,0x00000000,0x00030047,0x00000a17,0x00000000, + 0x00030047,0x00000a29,0x00000000,0x00030047,0x00000a2a,0x00000000,0x00030047,0x00000a2d, + 0x00000000,0x00030047,0x00000a2f,0x00000000,0x00030047,0x00000a33,0x00000000,0x00030047, + 0x00000a3b,0x00000000,0x00030047,0x00000a3e,0x00000000,0x00030047,0x00000a40,0x00000000, + 0x00030047,0x00000a42,0x00000000,0x00030047,0x00000a49,0x00000000,0x00030047,0x00000a4b, + 0x00000000,0x00030047,0x00000a4d,0x00000000,0x00030047,0x00000a4f,0x00000000,0x00030047, + 0x00000a57,0x00000000,0x00030047,0x00000a59,0x00000000,0x00030047,0x00000a5b,0x00000000, + 0x00030047,0x00000a5d,0x00000000,0x00030047,0x00000a5f,0x00000000,0x00030047,0x00000a61, + 0x00000000,0x00030047,0x00000a63,0x00000000,0x00030047,0x00000a65,0x00000000,0x00030047, + 0x00000a67,0x00000000,0x00030047,0x00000a6f,0x00000000,0x00030047,0x00000a71,0x00000000, + 0x00030047,0x00000a73,0x00000000,0x00030047,0x00000a82,0x00000000,0x00030047,0x00000a84, + 0x00000000,0x00030047,0x00000a86,0x00000000,0x00030047,0x00000a88,0x00000000,0x00030047, + 0x00000a8a,0x00000000,0x00030047,0x00000a8c,0x00000000,0x00030047,0x00000a94,0x00000000, + 0x00030047,0x00000a96,0x00000000,0x00030047,0x00000a98,0x00000000,0x00030047,0x00000a9b, + 0x00000000,0x00030047,0x00000aab,0x00000000,0x00030047,0x00000aad,0x00000000,0x00030047, + 0x00000aaf,0x00000000,0x00030047,0x00000ab1,0x00000000,0x00030047,0x00000ab3,0x00000000, + 0x00030047,0x00000ab5,0x00000000,0x00030047,0x00000ab7,0x00000000,0x00030047,0x00000ab9, + 0x00000000,0x00030047,0x00000abb,0x00000000,0x00030047,0x00000ac9,0x00000000,0x00030047, + 0x00000acb,0x00000000,0x00030047,0x00000acd,0x00000000,0x00030047,0x00000ad5,0x00000000, + 0x00030047,0x00000ad7,0x00000000,0x00030047,0x00000ad9,0x00000000,0x00030047,0x00000adb, + 0x00000000,0x00030047,0x00000ae3,0x00000000,0x00030047,0x00000ae5,0x00000000,0x00030047, + 0x00000ae9,0x00000000,0x00030047,0x00000aeb,0x00000000,0x00030047,0x00000aed,0x00000000, + 0x00030047,0x00000aef,0x00000000,0x00030047,0x00000af1,0x00000000,0x00030047,0x00000af3, + 0x00000000,0x00030047,0x00000b01,0x00000000,0x00030047,0x00000b03,0x00000000,0x00030047, + 0x00000b05,0x00000000,0x00030047,0x00000b0d,0x00000000,0x00030047,0x00000b0f,0x00000000, + 0x00030047,0x00000b11,0x00000000,0x00030047,0x00000b13,0x00000000,0x00030047,0x00000b1b, + 0x00000000,0x00030047,0x00000b1d,0x00000000,0x00030047,0x00000b21,0x00000000,0x00030047, + 0x00000b23,0x00000000,0x00030047,0x00000b25,0x00000000,0x00030047,0x00000b27,0x00000000, + 0x00030047,0x00000b29,0x00000000,0x00030047,0x00000b2b,0x00000000,0x00030047,0x00000b2d, + 0x00000000,0x00030047,0x00000b2f,0x00000000,0x00030047,0x00000b31,0x00000000,0x00030047, + 0x00000b39,0x00000000,0x00030047,0x00000b3b,0x00000000,0x00030047,0x00000b3d,0x00000000, + 0x00030047,0x00000b3f,0x00000000,0x00030047,0x00000b47,0x00000000,0x00030047,0x00000b49, + 0x00000000,0x00030047,0x00000b4d,0x00000000,0x00030047,0x00000b4f,0x00000000,0x00030047, + 0x00000b51,0x00000000,0x00030047,0x00000b53,0x00000000,0x00030047,0x00000b55,0x00000000, + 0x00030047,0x00000b57,0x00000000,0x00030047,0x00000b59,0x00000000,0x00030047,0x00000b5b, + 0x00000000,0x00030047,0x00000b5d,0x00000000,0x00030047,0x00000b65,0x00000000,0x00030047, + 0x00000b67,0x00000000,0x00030047,0x00000b69,0x00000000,0x00030047,0x00000b6b,0x00000000, + 0x00030047,0x00000b73,0x00000000,0x00030047,0x00000b75,0x00000000,0x00030047,0x00000b7a, + 0x00000000,0x00030047,0x00000b7c,0x00000000,0x00030047,0x00000b7e,0x00000000,0x00030047, + 0x00000b80,0x00000000,0x00030047,0x00000b82,0x00000000,0x00030047,0x00000b84,0x00000000, + 0x00030047,0x00000b87,0x00000000,0x00030047,0x00000b89,0x00000000,0x00030047,0x00000b8b, + 0x00000000,0x00030047,0x00000b8f,0x00000000,0x00030047,0x00000b91,0x00000000,0x00030047, + 0x00000b93,0x00000000,0x00030047,0x00000b94,0x00000000,0x00030047,0x00000b9b,0x00000000, + 0x00030047,0x00000b9d,0x00000000,0x00030047,0x00000b9e,0x00000000,0x00030047,0x00000b9c, + 0x00000000,0x00030047,0x00000b9a,0x00000000,0x00030047,0x00000ba1,0x00000000,0x00030047, + 0x00000ce8,0x00000000,0x00030047,0x00000d58,0x00000000,0x00030047,0x00000b9f,0x00000000, + 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020, + 0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x0000000d,0x00000007,0x00000006, + 0x00040015,0x0000000e,0x00000020,0x00000000,0x00040017,0x00000017,0x00000006,0x00000002, + 0x00040017,0x00000021,0x00000006,0x00000003,0x00040020,0x0000002c,0x00000007,0x00000021, + 0x00040018,0x00000052,0x00000007,0x00000004,0x00040015,0x00000054,0x00000020,0x00000001, + 0x0004002b,0x0000000e,0x00000088,0x00000000,0x0004002b,0x0000000e,0x0000008b,0x00000001, + 0x0004002b,0x00000006,0x000000bf,0x00000000,0x00020014,0x000000c0,0x0004002b,0x00000006, + 0x000000c5,0x3f800000,0x0004002b,0x00000006,0x000000ef,0x3d897143,0x0004002b,0x00000006, + 0x000000f3,0x3bbf4590,0x0004002b,0x00000006,0x000000fa,0x4253ee82,0x00030030,0x000000c0, + 0x00000105,0x0004002b,0x00000054,0x00000119,0x0000000f,0x0004002b,0x00000054,0x0000011d, + 0x00000000,0x0004002b,0x00000054,0x00000120,0x00000001,0x0004002b,0x00000054,0x00000124, + 0x00000002,0x0004002b,0x00000054,0x00000128,0x00000003,0x0004002b,0x00000006,0x0000012c, + 0x3e800000,0x00040017,0x00000132,0x00000054,0x00000004,0x0004002b,0x00000054,0x00000133, + 0x00000004,0x0004002b,0x00000054,0x00000134,0x00000008,0x0007002c,0x00000132,0x00000135, + 0x00000120,0x00000124,0x00000133,0x00000134,0x0007002c,0x00000132,0x00000138,0x0000011d, + 0x0000011d,0x0000011d,0x0000011d,0x00040017,0x00000139,0x000000c0,0x00000004,0x0007002c, + 0x00000007,0x0000013b,0x000000bf,0x000000bf,0x000000bf,0x000000bf,0x0007002c,0x00000007, + 0x0000013c,0x000000c5,0x000000c5,0x000000c5,0x000000c5,0x0004002b,0x00000054,0x00000144, + 0x00000005,0x0004002b,0x00000006,0x00000158,0x3e99999a,0x0004002b,0x00000006,0x00000159, + 0x3f170a3d,0x0004002b,0x00000006,0x0000015a,0x3de147ae,0x0004002b,0x00000006,0x00000174, + 0x388205ff,0x0004002b,0x00000006,0x000001da,0x40000000,0x0004002b,0x00000006,0x000001e1, + 0x3f000000,0x00040017,0x000001e7,0x000000c0,0x00000003,0x0004002b,0x00000006,0x0000027f, + 0x41800000,0x0004002b,0x00000006,0x00000284,0x41400000,0x0004002b,0x00000006,0x0000028a, + 0x40400000,0x00030030,0x000000c0,0x000002b0,0x00030030,0x000000c0,0x0000030b,0x00050034, + 0x000000c0,0x0000030c,0x000000a8,0x0000030b,0x0004002b,0x00000006,0x0000031b,0xbf800000, + 0x0004002b,0x00000006,0x00000339,0x3f7f8000,0x0004002b,0x00000006,0x0000033c,0x3a800000, + 0x0004002b,0x00000006,0x0000033f,0x3b000000,0x00090019,0x00000349,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x0000034a,0x00000000, + 0x00000349,0x0004003b,0x0000034a,0x0000034b,0x00000000,0x0002001a,0x0000034d,0x00040020, + 0x0000034e,0x00000000,0x0000034d,0x0004003b,0x0000034e,0x0000034f,0x00000000,0x0003001b, + 0x00000351,0x00000349,0x00050034,0x000000c0,0x0000035c,0x000000a8,0x0000030b,0x0004003b, + 0x0000034a,0x00000370,0x00000000,0x0004003b,0x0000034e,0x00000372,0x00000000,0x00050034, + 0x000000c0,0x0000037e,0x000000a8,0x0000030b,0x00040020,0x00000394,0x00000001,0x00000007, + 0x0004003b,0x00000394,0x00000395,0x00000001,0x00040020,0x0000039c,0x00000001,0x00000006, + 0x0004003b,0x0000039c,0x0000039d,0x00000001,0x00090019,0x000003a2,0x00000006,0x00000006, + 0x00000000,0x00000000,0x00000001,0x00000002,0x00000000,0x00040020,0x000003a3,0x00000000, + 0x000003a2,0x0004003b,0x000003a3,0x000003a4,0x00000000,0x00040017,0x000003a6,0x00000054, + 0x00000002,0x0005002c,0x000003a6,0x000003a7,0x0000011d,0x0000011d,0x0004001c,0x000003c4, + 0x00000054,0x0000008b,0x00040020,0x000003c5,0x00000001,0x000003c4,0x0004003b,0x000003c5, + 0x000003c6,0x00000001,0x00040020,0x000003c9,0x00000001,0x00000054,0x0004003b,0x00000394, + 0x000003e6,0x00000001,0x0017001e,0x000003e7,0x00000006,0x00000006,0x00000006,0x00000006, + 0x0000000e,0x0000000e,0x0000000e,0x0000000e,0x00000132,0x00000017,0x00000017,0x0000000e, + 0x00000006,0x0000000e,0x00000006,0x00000006,0x0000000e,0x00000006,0x00000006,0x00000006, + 0x0000000e,0x00040020,0x000003e8,0x00000002,0x000003e7,0x0004003b,0x000003e8,0x000003e9, + 0x00000002,0x0004002b,0x00000054,0x000003ea,0x00000011,0x0004002b,0x00000054,0x000003eb, + 0x00000012,0x00040020,0x000003f3,0x00000002,0x00000006,0x00040020,0x00000400,0x00000003, + 0x00000007,0x0004003b,0x00000400,0x00000401,0x00000003,0x0004003b,0x0000034e,0x0000040c, + 0x00000000,0x0004003b,0x0000034a,0x0000040d,0x00000000,0x00040020,0x0000040e,0x00000001, + 0x00000017,0x0004003b,0x0000040e,0x0000040f,0x00000001,0x00030001,0x00000007,0x00000b97, + 0x00030001,0x00000021,0x00000ba6,0x0006002c,0x00000021,0x00000d5a,0x000001e1,0x000001e1, + 0x000001e1,0x0006002c,0x00000021,0x00000d5b,0x000000c5,0x000000c5,0x000000c5,0x00030001, + 0x00000017,0x00000d5d,0x00030001,0x00000021,0x00000d5e,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000002c,0x00000502,0x00000007, + 0x0004003b,0x0000002c,0x00000504,0x00000007,0x0004003b,0x0000002c,0x000004f2,0x00000007, + 0x0004003d,0x00000007,0x00000397,0x00000395,0x00050051,0x00000006,0x00000428,0x00000397, + 0x00000003,0x000500be,0x000000c0,0x00000429,0x00000428,0x000000bf,0x000300f7,0x00000495, + 0x00000000,0x000400fa,0x00000429,0x0000042a,0x00000438,0x000200f8,0x00000438,0x000500ba, + 0x000000c0,0x0000043b,0x00000428,0x0000031b,0x000300f7,0x00000494,0x00000000,0x000400fa, + 0x0000043b,0x0000043c,0x00000477,0x000200f8,0x00000477,0x0004007f,0x00000006,0x0000047a, + 0x00000428,0x00050083,0x00000006,0x0000047b,0x0000047a,0x000001da,0x0004003d,0x00000349, + 0x0000047c,0x00000370,0x0004003d,0x0000034d,0x0000047d,0x00000372,0x00050056,0x00000351, + 0x0000047e,0x0000047c,0x0000047d,0x0007004f,0x00000017,0x00000480,0x00000397,0x00000397, + 0x00000000,0x00000001,0x00070058,0x00000007,0x00000482,0x0000047e,0x00000480,0x00000002, + 0x0000047b,0x00050051,0x00000006,0x00000484,0x00000397,0x00000002,0x00050085,0x00000006, + 0x00000486,0x00000484,0x000000c5,0x000300f7,0x00000493,0x00000000,0x000400fa,0x0000037e, + 0x00000487,0x0000048b,0x000200f8,0x0000048b,0x0008004f,0x00000021,0x000004a0,0x00000482, + 0x00000482,0x00000000,0x00000001,0x00000002,0x00050051,0x00000006,0x000004a2,0x00000482, + 0x00000003,0x000500b7,0x000000c0,0x000004a3,0x000004a2,0x000000bf,0x000300f7,0x000004a9, + 0x00000000,0x000400fa,0x000004a3,0x000004a4,0x000004a8,0x000200f8,0x000004a8,0x000200f9, + 0x000004a9,0x000200f8,0x000004a4,0x00050088,0x00000006,0x000004a7,0x000000c5,0x000004a2, + 0x000200f9,0x000004a9,0x000200f8,0x000004a9,0x000700f5,0x00000006,0x00000b94,0x000004a7, + 0x000004a4,0x000000bf,0x000004a8,0x0005008e,0x00000021,0x000004ab,0x000004a0,0x00000b94, + 0x00050085,0x00000006,0x00000491,0x000004a2,0x00000486,0x00050051,0x00000006,0x000004b1, + 0x000004ab,0x00000000,0x00060052,0x00000007,0x00000a49,0x000004b1,0x00000b97,0x00000000, + 0x00050051,0x00000006,0x000004b3,0x000004ab,0x00000001,0x00060052,0x00000007,0x00000a4b, + 0x000004b3,0x00000a49,0x00000001,0x00050051,0x00000006,0x000004b5,0x000004ab,0x00000002, + 0x00060052,0x00000007,0x00000a4d,0x000004b5,0x00000a4b,0x00000002,0x00060052,0x00000007, + 0x00000a4f,0x00000491,0x00000a4d,0x00000003,0x000200f9,0x00000493,0x000200f8,0x00000487, + 0x0005008e,0x00000007,0x0000048a,0x00000482,0x00000486,0x000200f9,0x00000493,0x000200f8, + 0x00000493,0x000700f5,0x00000007,0x00000b9e,0x0000048a,0x00000487,0x00000a4f,0x000004a9, + 0x000200f9,0x00000494,0x000200f8,0x0000043c,0x00050051,0x00000006,0x0000043e,0x00000397, + 0x00000002,0x000500ba,0x000000c0,0x0000043f,0x0000043e,0x000000bf,0x000300f7,0x00000447, + 0x00000000,0x000400fa,0x0000043f,0x00000440,0x00000443,0x000200f8,0x00000443,0x0007004f, + 0x00000017,0x00000445,0x00000397,0x00000397,0x00000000,0x00000001,0x0006000c,0x00000006, + 0x00000446,0x00000001,0x00000042,0x00000445,0x000200f9,0x00000447,0x000200f8,0x00000440, + 0x00050051,0x00000006,0x00000442,0x00000397,0x00000000,0x000200f9,0x00000447,0x000200f8, + 0x00000447,0x000700f5,0x00000006,0x00000b98,0x00000442,0x00000440,0x00000446,0x00000443, + 0x0008000c,0x00000006,0x0000044a,0x00000001,0x0000002b,0x00000b98,0x000000bf,0x000000c5, + 0x0006000c,0x00000006,0x0000044d,0x00000001,0x00000004,0x0000043e,0x000500ba,0x000000c0, + 0x0000044f,0x0000044d,0x000000c5,0x000300f7,0x00000459,0x00000000,0x000400fa,0x0000044f, + 0x00000450,0x00000454,0x000200f8,0x00000454,0x00050085,0x00000006,0x00000456,0x0000033f, + 0x0000044a,0x00050081,0x00000006,0x00000458,0x00000456,0x0000044d,0x000200f9,0x00000459, + 0x000200f8,0x00000450,0x00050085,0x00000006,0x00000452,0x00000339,0x0000044a,0x00050081, + 0x00000006,0x00000453,0x00000452,0x0000033c,0x000200f9,0x00000459,0x000200f8,0x00000459, + 0x000700f5,0x00000006,0x00000b99,0x00000453,0x00000450,0x00000458,0x00000454,0x0004007f, + 0x00000006,0x0000045d,0x00000428,0x0004003d,0x00000349,0x0000045e,0x0000034b,0x0004003d, + 0x0000034d,0x0000045f,0x0000034f,0x00050056,0x00000351,0x00000460,0x0000045e,0x0000045f, + 0x00050050,0x00000017,0x00000463,0x00000b99,0x0000045d,0x00070058,0x00000007,0x00000464, + 0x00000460,0x00000463,0x00000002,0x000000bf,0x00050051,0x00000006,0x00000467,0x00000464, + 0x00000003,0x00050085,0x00000006,0x00000468,0x00000467,0x000000c5,0x00060052,0x00000007, + 0x00000a3b,0x00000468,0x00000464,0x00000003,0x000300f7,0x00000476,0x00000000,0x000400fa, + 0x0000035c,0x0000046a,0x00000476,0x000200f8,0x0000046a,0x00050051,0x00000006,0x0000046c, + 0x00000a3b,0x00000003,0x0008004f,0x00000021,0x0000046e,0x00000a3b,0x00000a3b,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x00000021,0x0000046f,0x0000046e,0x0000046c,0x00050051, + 0x00000006,0x00000471,0x0000046f,0x00000000,0x00060052,0x00000007,0x00000a3e,0x00000471, + 0x00000a3b,0x00000000,0x00050051,0x00000006,0x00000473,0x0000046f,0x00000001,0x00060052, + 0x00000007,0x00000a40,0x00000473,0x00000a3e,0x00000001,0x00050051,0x00000006,0x00000475, + 0x0000046f,0x00000002,0x00060052,0x00000007,0x00000a42,0x00000475,0x00000a40,0x00000002, + 0x000200f9,0x00000476,0x000200f8,0x00000476,0x000700f5,0x00000007,0x00000b9d,0x00000a3b, + 0x00000459,0x00000a42,0x0000046a,0x000200f9,0x00000494,0x000200f8,0x00000494,0x000700f5, + 0x00000007,0x00000b9c,0x00000b9d,0x00000476,0x00000b9e,0x00000493,0x000200f9,0x00000495, + 0x000200f8,0x0000042a,0x000300f7,0x00000437,0x00000000,0x000400fa,0x0000030c,0x0000042d, + 0x00000431,0x000200f8,0x00000431,0x00050051,0x00000006,0x00000434,0x00000397,0x00000003, + 0x00050085,0x00000006,0x00000435,0x00000434,0x000000c5,0x00060052,0x00000007,0x00000a33, + 0x00000435,0x00000397,0x00000003,0x000200f9,0x00000437,0x000200f8,0x0000042d,0x0005008e, + 0x00000007,0x00000430,0x00000397,0x000000c5,0x000200f9,0x00000437,0x000200f8,0x00000437, + 0x000700f5,0x00000007,0x00000b9b,0x00000430,0x0000042d,0x00000a33,0x00000431,0x000200f9, + 0x00000495,0x000200f8,0x00000495,0x000700f5,0x00000007,0x00000b9a,0x00000b9b,0x00000437, + 0x00000b9c,0x00000494,0x0004003d,0x00000006,0x0000039f,0x0000039d,0x0004006d,0x0000000e, + 0x000004bc,0x0000039f,0x0004003d,0x000003a2,0x000003a5,0x000003a4,0x00070062,0x00000007, + 0x000003a8,0x000003a5,0x000003a7,0x00000040,0x0000011d,0x0004003d,0x000003a2,0x000003a9, + 0x000003a4,0x00070062,0x00000007,0x000003aa,0x000003a9,0x000003a7,0x00000040,0x00000120, + 0x0004003d,0x000003a2,0x000003ab,0x000003a4,0x00070062,0x00000007,0x000003ac,0x000003ab, + 0x000003a7,0x00000040,0x00000124,0x0004003d,0x000003a2,0x000003ad,0x000003a4,0x00070062, + 0x00000007,0x000003ae,0x000003ad,0x000003a7,0x00000040,0x00000128,0x00050051,0x00000006, + 0x000003af,0x000003a8,0x00000000,0x00050051,0x00000006,0x000003b0,0x000003a8,0x00000001, + 0x00050051,0x00000006,0x000003b1,0x000003a8,0x00000002,0x00050051,0x00000006,0x000003b2, + 0x000003a8,0x00000003,0x00050051,0x00000006,0x000003b3,0x000003aa,0x00000000,0x00050051, + 0x00000006,0x000003b4,0x000003aa,0x00000001,0x00050051,0x00000006,0x000003b5,0x000003aa, + 0x00000002,0x00050051,0x00000006,0x000003b6,0x000003aa,0x00000003,0x00050051,0x00000006, + 0x000003b7,0x000003ac,0x00000000,0x00050051,0x00000006,0x000003b8,0x000003ac,0x00000001, + 0x00050051,0x00000006,0x000003b9,0x000003ac,0x00000002,0x00050051,0x00000006,0x000003ba, + 0x000003ac,0x00000003,0x00050051,0x00000006,0x000003bb,0x000003ae,0x00000000,0x00050051, + 0x00000006,0x000003bc,0x000003ae,0x00000001,0x00050051,0x00000006,0x000003bd,0x000003ae, + 0x00000002,0x00050051,0x00000006,0x000003be,0x000003ae,0x00000003,0x00070050,0x00000007, + 0x000003bf,0x000003af,0x000003b0,0x000003b1,0x000003b2,0x00070050,0x00000007,0x000003c0, + 0x000003b3,0x000003b4,0x000003b5,0x000003b6,0x00070050,0x00000007,0x000003c1,0x000003b7, + 0x000003b8,0x000003b9,0x000003ba,0x00070050,0x00000007,0x000003c2,0x000003bb,0x000003bc, + 0x000003bd,0x000003be,0x00070050,0x00000052,0x000003c3,0x000003bf,0x000003c0,0x000003c1, + 0x000003c2,0x00050041,0x000003c9,0x000003ca,0x000003c6,0x0000011d,0x0004003d,0x00000054, + 0x000003cb,0x000003ca,0x000300f7,0x000004ef,0x00000000,0x000300fb,0x00000088,0x000004c4, + 0x000200f8,0x000004c4,0x000500aa,0x000000c0,0x000004c6,0x000003cb,0x00000119,0x000300f7, + 0x000004ee,0x00000000,0x000400fa,0x000004c6,0x000004c7,0x000004d4,0x000200f8,0x000004d4, + 0x00070050,0x00000132,0x000004d6,0x000003cb,0x000003cb,0x000003cb,0x000003cb,0x000500c7, + 0x00000132,0x000004d7,0x000004d6,0x00000135,0x000500ab,0x00000139,0x000004d8,0x000004d7, + 0x00000138,0x000600a9,0x00000007,0x000004d9,0x000004d8,0x0000013c,0x0000013b,0x00050091, + 0x00000007,0x000004dc,0x000003c3,0x000004d9,0x000500c7,0x00000054,0x000004de,0x000003cb, + 0x00000144,0x000500c3,0x00000054,0x000004e0,0x000003cb,0x00000120,0x000500c7,0x00000054, + 0x000004e1,0x000004e0,0x00000144,0x00050080,0x00000054,0x000004e2,0x000004de,0x000004e1, + 0x000500c7,0x00000054,0x000004e4,0x000004e2,0x00000128,0x000500c3,0x00000054,0x000004e6, + 0x000004e2,0x00000124,0x00050080,0x00000054,0x000004e7,0x000004e4,0x000004e6,0x0004006f, + 0x00000006,0x000004e9,0x000004e7,0x00050088,0x00000006,0x000004ea,0x000000c5,0x000004e9, + 0x0005008e,0x00000007,0x000004ec,0x000004dc,0x000004ea,0x000200f9,0x000004ef,0x000200f8, + 0x000004c7,0x00050051,0x00000007,0x000004c9,0x000003c3,0x00000000,0x00050051,0x00000007, + 0x000004cb,0x000003c3,0x00000001,0x00050081,0x00000007,0x000004cc,0x000004c9,0x000004cb, + 0x00050051,0x00000007,0x000004ce,0x000003c3,0x00000002,0x00050081,0x00000007,0x000004cf, + 0x000004cc,0x000004ce,0x00050051,0x00000007,0x000004d1,0x000003c3,0x00000003,0x00050081, + 0x00000007,0x000004d2,0x000004cf,0x000004d1,0x0005008e,0x00000007,0x000004d3,0x000004d2, + 0x0000012c,0x000200f9,0x000004ef,0x000200f8,0x000004ee,0x000100ff,0x000200f8,0x000004ef, + 0x000700f5,0x00000007,0x00000b9f,0x000004d3,0x000004c7,0x000004ec,0x000004d4,0x0008004f, + 0x00000021,0x000003cf,0x00000b9a,0x00000b9a,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x000004f2,0x000003cf,0x0008004f,0x00000021,0x0000062c,0x00000b9f,0x00000b9f,0x00000000, + 0x00000001,0x00000002,0x00050051,0x00000006,0x0000062e,0x00000b9f,0x00000003,0x000500b7, + 0x000000c0,0x0000062f,0x0000062e,0x000000bf,0x000300f7,0x00000635,0x00000000,0x000400fa, + 0x0000062f,0x00000630,0x00000634,0x000200f8,0x00000634,0x000200f9,0x00000635,0x000200f8, + 0x00000630,0x00050088,0x00000006,0x00000633,0x000000c5,0x0000062e,0x000200f9,0x00000635, + 0x000200f8,0x00000635,0x000700f5,0x00000006,0x00000ba1,0x00000633,0x00000630,0x000000bf, + 0x00000634,0x0005008e,0x00000021,0x00000637,0x0000062c,0x00000ba1,0x0003003e,0x00000502, + 0x00000637,0x000300f7,0x00000626,0x00000000,0x002100fb,0x000004bc,0x00000626,0x0000000b, + 0x0000052d,0x00000001,0x00000531,0x00000002,0x00000539,0x00000003,0x0000054a,0x00000004, + 0x0000054e,0x00000005,0x00000552,0x00000006,0x00000575,0x00000007,0x000005a2,0x00000008, + 0x000005b3,0x00000009,0x000005ee,0x0000000a,0x000005f3,0x0000000c,0x000005fc,0x0000000d, + 0x00000607,0x0000000e,0x00000612,0x0000000f,0x0000061c,0x000200f8,0x0000061c,0x000300f7, + 0x00000625,0x00000000,0x000400fa,0x000002b0,0x0000061d,0x00000625,0x000200f8,0x0000061d, + 0x0004003d,0x00000021,0x0000061e,0x000004f2,0x00060052,0x00000021,0x00000b4d,0x000000bf, + 0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000b4f,0x000000bf,0x00000b4d,0x00000001, + 0x00060052,0x00000021,0x00000b51,0x000000bf,0x00000b4f,0x00000002,0x00060052,0x00000021, + 0x00000b53,0x000000c5,0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000b55,0x000000c5, + 0x00000b53,0x00000001,0x00060052,0x00000021,0x00000b57,0x000000c5,0x00000b55,0x00000002, + 0x0008000c,0x00000021,0x00000621,0x00000001,0x0000002b,0x0000061e,0x00000b51,0x00000b57, + 0x0003003e,0x000004f2,0x00000621,0x00060052,0x00000021,0x00000b59,0x00000158,0x00000ba6, + 0x00000000,0x00060052,0x00000021,0x00000b5b,0x00000159,0x00000b59,0x00000001,0x00060052, + 0x00000021,0x00000b5d,0x0000015a,0x00000b5b,0x00000002,0x00050094,0x00000006,0x000009a8, + 0x00000621,0x00000b5d,0x00050094,0x00000006,0x000009ba,0x00000637,0x00000b5d,0x00060050, + 0x00000021,0x00000985,0x000009ba,0x000009ba,0x000009ba,0x00050083,0x00000021,0x00000986, + 0x00000637,0x00000985,0x00050083,0x00000006,0x00000988,0x000000c5,0x000009a8,0x00060052, + 0x00000017,0x00000b65,0x000009a8,0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000b67, + 0x00000988,0x00000b65,0x00000001,0x00060052,0x00000017,0x00000b69,0x00000174,0x00000d5d, + 0x00000000,0x00060052,0x00000017,0x00000b6b,0x00000174,0x00000b69,0x00000001,0x0007004f, + 0x00000017,0x000009d9,0x00000986,0x00000986,0x00000000,0x00000001,0x00050051,0x00000006, + 0x000009e1,0x000009d9,0x00000000,0x00050051,0x00000006,0x000009e3,0x000009d9,0x00000001, + 0x0007000c,0x00000006,0x000009e4,0x00000001,0x00000025,0x000009e1,0x000009e3,0x00050051, + 0x00000006,0x000009dc,0x00000986,0x00000002,0x0007000c,0x00000006,0x000009dd,0x00000001, + 0x00000025,0x000009e4,0x000009dc,0x0004007f,0x00000006,0x0000098e,0x000009dd,0x0007000c, + 0x00000006,0x000009f4,0x00000001,0x00000028,0x000009e1,0x000009e3,0x0007000c,0x00000006, + 0x000009ed,0x00000001,0x00000028,0x000009f4,0x000009dc,0x00060052,0x00000017,0x00000b73, + 0x0000098e,0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000b75,0x000009ed,0x00000b73, + 0x00000001,0x0007000c,0x00000017,0x00000992,0x00000001,0x00000028,0x00000b6b,0x00000b75, + 0x00050088,0x00000017,0x00000993,0x00000b67,0x00000992,0x00050051,0x00000006,0x00000996, + 0x00000993,0x00000000,0x00050051,0x00000006,0x00000998,0x00000993,0x00000001,0x0007000c, + 0x00000006,0x00000999,0x00000001,0x00000025,0x00000996,0x00000998,0x0007000c,0x00000006, + 0x0000099a,0x00000001,0x00000025,0x000000c5,0x00000999,0x0005008e,0x00000021,0x0000099d, + 0x00000986,0x0000099a,0x00060050,0x00000021,0x0000099f,0x000009a8,0x000009a8,0x000009a8, + 0x00050081,0x00000021,0x000009a0,0x0000099d,0x0000099f,0x0003003e,0x00000504,0x000009a0, + 0x000200f9,0x00000625,0x000200f8,0x00000625,0x000200f9,0x00000626,0x000200f8,0x00000612, + 0x000300f7,0x0000061b,0x00000000,0x000400fa,0x000002b0,0x00000613,0x0000061b,0x000200f8, + 0x00000613,0x0004003d,0x00000021,0x00000614,0x000004f2,0x00060052,0x00000021,0x00000b21, + 0x000000bf,0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000b23,0x000000bf,0x00000b21, + 0x00000001,0x00060052,0x00000021,0x00000b25,0x000000bf,0x00000b23,0x00000002,0x00060052, + 0x00000021,0x00000b27,0x000000c5,0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000b29, + 0x000000c5,0x00000b27,0x00000001,0x00060052,0x00000021,0x00000b2b,0x000000c5,0x00000b29, + 0x00000002,0x0008000c,0x00000021,0x00000617,0x00000001,0x0000002b,0x00000614,0x00000b25, + 0x00000b2b,0x0003003e,0x000004f2,0x00000617,0x00060052,0x00000021,0x00000b2d,0x00000158, + 0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000b2f,0x00000159,0x00000b2d,0x00000001, + 0x00060052,0x00000021,0x00000b31,0x0000015a,0x00000b2f,0x00000002,0x00050094,0x00000006, + 0x00000904,0x00000637,0x00000b31,0x00050094,0x00000006,0x00000916,0x00000617,0x00000b31, + 0x00060050,0x00000021,0x000008e1,0x00000916,0x00000916,0x00000916,0x00050083,0x00000021, + 0x000008e2,0x00000617,0x000008e1,0x00050083,0x00000006,0x000008e4,0x000000c5,0x00000904, + 0x00060052,0x00000017,0x00000b39,0x00000904,0x00000d5d,0x00000000,0x00060052,0x00000017, + 0x00000b3b,0x000008e4,0x00000b39,0x00000001,0x00060052,0x00000017,0x00000b3d,0x00000174, + 0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000b3f,0x00000174,0x00000b3d,0x00000001, + 0x0007004f,0x00000017,0x00000935,0x000008e2,0x000008e2,0x00000000,0x00000001,0x00050051, + 0x00000006,0x0000093d,0x00000935,0x00000000,0x00050051,0x00000006,0x0000093f,0x00000935, + 0x00000001,0x0007000c,0x00000006,0x00000940,0x00000001,0x00000025,0x0000093d,0x0000093f, + 0x00050051,0x00000006,0x00000938,0x000008e2,0x00000002,0x0007000c,0x00000006,0x00000939, + 0x00000001,0x00000025,0x00000940,0x00000938,0x0004007f,0x00000006,0x000008ea,0x00000939, + 0x0007000c,0x00000006,0x00000950,0x00000001,0x00000028,0x0000093d,0x0000093f,0x0007000c, + 0x00000006,0x00000949,0x00000001,0x00000028,0x00000950,0x00000938,0x00060052,0x00000017, + 0x00000b47,0x000008ea,0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000b49,0x00000949, + 0x00000b47,0x00000001,0x0007000c,0x00000017,0x000008ee,0x00000001,0x00000028,0x00000b3f, + 0x00000b49,0x00050088,0x00000017,0x000008ef,0x00000b3b,0x000008ee,0x00050051,0x00000006, + 0x000008f2,0x000008ef,0x00000000,0x00050051,0x00000006,0x000008f4,0x000008ef,0x00000001, + 0x0007000c,0x00000006,0x000008f5,0x00000001,0x00000025,0x000008f2,0x000008f4,0x0007000c, + 0x00000006,0x000008f6,0x00000001,0x00000025,0x000000c5,0x000008f5,0x0005008e,0x00000021, + 0x000008f9,0x000008e2,0x000008f6,0x00060050,0x00000021,0x000008fb,0x00000904,0x00000904, + 0x00000904,0x00050081,0x00000021,0x000008fc,0x000008f9,0x000008fb,0x0003003e,0x00000504, + 0x000008fc,0x000200f9,0x0000061b,0x000200f8,0x0000061b,0x000200f9,0x00000626,0x000200f8, + 0x00000607,0x000300f7,0x00000611,0x00000000,0x000400fa,0x000002b0,0x00000608,0x00000611, + 0x000200f8,0x00000608,0x0004003d,0x00000021,0x00000609,0x000004f2,0x00060052,0x00000021, + 0x00000ae9,0x000000bf,0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000aeb,0x000000bf, + 0x00000ae9,0x00000001,0x00060052,0x00000021,0x00000aed,0x000000bf,0x00000aeb,0x00000002, + 0x00060052,0x00000021,0x00000aef,0x000000c5,0x00000ba6,0x00000000,0x00060052,0x00000021, + 0x00000af1,0x000000c5,0x00000aef,0x00000001,0x00060052,0x00000021,0x00000af3,0x000000c5, + 0x00000af1,0x00000002,0x0008000c,0x00000021,0x0000060c,0x00000001,0x0000002b,0x00000609, + 0x00000aed,0x00000af3,0x0003003e,0x000004f2,0x0000060c,0x0007004f,0x00000017,0x000007ec, + 0x0000060c,0x0000060c,0x00000000,0x00000001,0x00050051,0x00000006,0x000007f4,0x000007ec, + 0x00000000,0x00050051,0x00000006,0x000007f6,0x000007ec,0x00000001,0x0007000c,0x00000006, + 0x000007f7,0x00000001,0x00000028,0x000007f4,0x000007f6,0x00050051,0x00000006,0x000007ef, + 0x0000060c,0x00000002,0x0007000c,0x00000006,0x000007f0,0x00000001,0x00000028,0x000007f7, + 0x000007ef,0x0007000c,0x00000006,0x00000807,0x00000001,0x00000025,0x000007f4,0x000007f6, + 0x0007000c,0x00000006,0x00000800,0x00000001,0x00000025,0x00000807,0x000007ef,0x00050083, + 0x00000006,0x000007d7,0x000007f0,0x00000800,0x0007004f,0x00000017,0x0000080c,0x00000637, + 0x00000637,0x00000000,0x00000001,0x00050051,0x00000006,0x00000814,0x0000080c,0x00000000, + 0x00050051,0x00000006,0x00000816,0x0000080c,0x00000001,0x0007000c,0x00000006,0x00000817, + 0x00000001,0x00000025,0x00000814,0x00000816,0x00050051,0x00000006,0x0000080f,0x00000637, + 0x00000002,0x0007000c,0x00000006,0x00000810,0x00000001,0x00000025,0x00000817,0x0000080f, + 0x00060050,0x00000021,0x000007db,0x00000810,0x00000810,0x00000810,0x00050083,0x00000021, + 0x000007dc,0x00000637,0x000007db,0x0007004f,0x00000017,0x0000081c,0x000007dc,0x000007dc, + 0x00000000,0x00000001,0x00050051,0x00000006,0x00000824,0x0000081c,0x00000000,0x00050051, + 0x00000006,0x00000826,0x0000081c,0x00000001,0x0007000c,0x00000006,0x00000827,0x00000001, + 0x00000028,0x00000824,0x00000826,0x00050051,0x00000006,0x0000081f,0x000007dc,0x00000002, + 0x0007000c,0x00000006,0x00000820,0x00000001,0x00000028,0x00000827,0x0000081f,0x0007000c, + 0x00000006,0x000007e1,0x00000001,0x00000028,0x00000174,0x00000820,0x00050088,0x00000006, + 0x000007e2,0x000007d7,0x000007e1,0x0005008e,0x00000021,0x000007e5,0x000007dc,0x000007e2, + 0x00060052,0x00000021,0x00000b01,0x00000158,0x00000ba6,0x00000000,0x00060052,0x00000021, + 0x00000b03,0x00000159,0x00000b01,0x00000001,0x00060052,0x00000021,0x00000b05,0x0000015a, + 0x00000b03,0x00000002,0x00050094,0x00000006,0x00000860,0x00000637,0x00000b05,0x00050094, + 0x00000006,0x00000872,0x000007e5,0x00000b05,0x00060050,0x00000021,0x0000083d,0x00000872, + 0x00000872,0x00000872,0x00050083,0x00000021,0x0000083e,0x000007e5,0x0000083d,0x00050083, + 0x00000006,0x00000840,0x000000c5,0x00000860,0x00060052,0x00000017,0x00000b0d,0x00000860, + 0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000b0f,0x00000840,0x00000b0d,0x00000001, + 0x00060052,0x00000017,0x00000b11,0x00000174,0x00000d5d,0x00000000,0x00060052,0x00000017, + 0x00000b13,0x00000174,0x00000b11,0x00000001,0x0007004f,0x00000017,0x00000891,0x0000083e, + 0x0000083e,0x00000000,0x00000001,0x00050051,0x00000006,0x00000899,0x00000891,0x00000000, + 0x00050051,0x00000006,0x0000089b,0x00000891,0x00000001,0x0007000c,0x00000006,0x0000089c, + 0x00000001,0x00000025,0x00000899,0x0000089b,0x00050051,0x00000006,0x00000894,0x0000083e, + 0x00000002,0x0007000c,0x00000006,0x00000895,0x00000001,0x00000025,0x0000089c,0x00000894, + 0x0004007f,0x00000006,0x00000846,0x00000895,0x0007000c,0x00000006,0x000008ac,0x00000001, + 0x00000028,0x00000899,0x0000089b,0x0007000c,0x00000006,0x000008a5,0x00000001,0x00000028, + 0x000008ac,0x00000894,0x00060052,0x00000017,0x00000b1b,0x00000846,0x00000d5d,0x00000000, + 0x00060052,0x00000017,0x00000b1d,0x000008a5,0x00000b1b,0x00000001,0x0007000c,0x00000017, + 0x0000084a,0x00000001,0x00000028,0x00000b13,0x00000b1d,0x00050088,0x00000017,0x0000084b, + 0x00000b0f,0x0000084a,0x00050051,0x00000006,0x0000084e,0x0000084b,0x00000000,0x00050051, + 0x00000006,0x00000850,0x0000084b,0x00000001,0x0007000c,0x00000006,0x00000851,0x00000001, + 0x00000025,0x0000084e,0x00000850,0x0007000c,0x00000006,0x00000852,0x00000001,0x00000025, + 0x000000c5,0x00000851,0x0005008e,0x00000021,0x00000855,0x0000083e,0x00000852,0x00060050, + 0x00000021,0x00000857,0x00000860,0x00000860,0x00000860,0x00050081,0x00000021,0x00000858, + 0x00000855,0x00000857,0x0003003e,0x00000504,0x00000858,0x000200f9,0x00000611,0x000200f8, + 0x00000611,0x000200f9,0x00000626,0x000200f8,0x000005fc,0x000300f7,0x00000606,0x00000000, + 0x000400fa,0x000002b0,0x000005fd,0x00000606,0x000200f8,0x000005fd,0x0004003d,0x00000021, + 0x000005fe,0x000004f2,0x00060052,0x00000021,0x00000ab1,0x000000bf,0x00000ba6,0x00000000, + 0x00060052,0x00000021,0x00000ab3,0x000000bf,0x00000ab1,0x00000001,0x00060052,0x00000021, + 0x00000ab5,0x000000bf,0x00000ab3,0x00000002,0x00060052,0x00000021,0x00000ab7,0x000000c5, + 0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000ab9,0x000000c5,0x00000ab7,0x00000001, + 0x00060052,0x00000021,0x00000abb,0x000000c5,0x00000ab9,0x00000002,0x0008000c,0x00000021, + 0x00000601,0x00000001,0x0000002b,0x000005fe,0x00000ab5,0x00000abb,0x0003003e,0x000004f2, + 0x00000601,0x0007004f,0x00000017,0x000006e8,0x00000637,0x00000637,0x00000000,0x00000001, + 0x00050051,0x00000006,0x000006f0,0x000006e8,0x00000000,0x00050051,0x00000006,0x000006f2, + 0x000006e8,0x00000001,0x0007000c,0x00000006,0x000006f3,0x00000001,0x00000028,0x000006f0, + 0x000006f2,0x00050051,0x00000006,0x000006eb,0x00000637,0x00000002,0x0007000c,0x00000006, + 0x000006ec,0x00000001,0x00000028,0x000006f3,0x000006eb,0x0007000c,0x00000006,0x00000703, + 0x00000001,0x00000025,0x000006f0,0x000006f2,0x0007000c,0x00000006,0x000006fc,0x00000001, + 0x00000025,0x00000703,0x000006eb,0x00050083,0x00000006,0x000006d3,0x000006ec,0x000006fc, + 0x0007004f,0x00000017,0x00000708,0x00000601,0x00000601,0x00000000,0x00000001,0x00050051, + 0x00000006,0x00000710,0x00000708,0x00000000,0x00050051,0x00000006,0x00000712,0x00000708, + 0x00000001,0x0007000c,0x00000006,0x00000713,0x00000001,0x00000025,0x00000710,0x00000712, + 0x00050051,0x00000006,0x0000070b,0x00000601,0x00000002,0x0007000c,0x00000006,0x0000070c, + 0x00000001,0x00000025,0x00000713,0x0000070b,0x00060050,0x00000021,0x000006d7,0x0000070c, + 0x0000070c,0x0000070c,0x00050083,0x00000021,0x000006d8,0x00000601,0x000006d7,0x0007004f, + 0x00000017,0x00000718,0x000006d8,0x000006d8,0x00000000,0x00000001,0x00050051,0x00000006, + 0x00000720,0x00000718,0x00000000,0x00050051,0x00000006,0x00000722,0x00000718,0x00000001, + 0x0007000c,0x00000006,0x00000723,0x00000001,0x00000028,0x00000720,0x00000722,0x00050051, + 0x00000006,0x0000071b,0x000006d8,0x00000002,0x0007000c,0x00000006,0x0000071c,0x00000001, + 0x00000028,0x00000723,0x0000071b,0x0007000c,0x00000006,0x000006dd,0x00000001,0x00000028, + 0x00000174,0x0000071c,0x00050088,0x00000006,0x000006de,0x000006d3,0x000006dd,0x0005008e, + 0x00000021,0x000006e1,0x000006d8,0x000006de,0x00060052,0x00000021,0x00000ac9,0x00000158, + 0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000acb,0x00000159,0x00000ac9,0x00000001, + 0x00060052,0x00000021,0x00000acd,0x0000015a,0x00000acb,0x00000002,0x00050094,0x00000006, + 0x0000075c,0x00000637,0x00000acd,0x00050094,0x00000006,0x0000076e,0x000006e1,0x00000acd, + 0x00060050,0x00000021,0x00000739,0x0000076e,0x0000076e,0x0000076e,0x00050083,0x00000021, + 0x0000073a,0x000006e1,0x00000739,0x00050083,0x00000006,0x0000073c,0x000000c5,0x0000075c, + 0x00060052,0x00000017,0x00000ad5,0x0000075c,0x00000d5d,0x00000000,0x00060052,0x00000017, + 0x00000ad7,0x0000073c,0x00000ad5,0x00000001,0x00060052,0x00000017,0x00000ad9,0x00000174, + 0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000adb,0x00000174,0x00000ad9,0x00000001, + 0x0007004f,0x00000017,0x0000078d,0x0000073a,0x0000073a,0x00000000,0x00000001,0x00050051, + 0x00000006,0x00000795,0x0000078d,0x00000000,0x00050051,0x00000006,0x00000797,0x0000078d, + 0x00000001,0x0007000c,0x00000006,0x00000798,0x00000001,0x00000025,0x00000795,0x00000797, + 0x00050051,0x00000006,0x00000790,0x0000073a,0x00000002,0x0007000c,0x00000006,0x00000791, + 0x00000001,0x00000025,0x00000798,0x00000790,0x0004007f,0x00000006,0x00000742,0x00000791, + 0x0007000c,0x00000006,0x000007a8,0x00000001,0x00000028,0x00000795,0x00000797,0x0007000c, + 0x00000006,0x000007a1,0x00000001,0x00000028,0x000007a8,0x00000790,0x00060052,0x00000017, + 0x00000ae3,0x00000742,0x00000d5d,0x00000000,0x00060052,0x00000017,0x00000ae5,0x000007a1, + 0x00000ae3,0x00000001,0x0007000c,0x00000017,0x00000746,0x00000001,0x00000028,0x00000adb, + 0x00000ae5,0x00050088,0x00000017,0x00000747,0x00000ad7,0x00000746,0x00050051,0x00000006, + 0x0000074a,0x00000747,0x00000000,0x00050051,0x00000006,0x0000074c,0x00000747,0x00000001, + 0x0007000c,0x00000006,0x0000074d,0x00000001,0x00000025,0x0000074a,0x0000074c,0x0007000c, + 0x00000006,0x0000074e,0x00000001,0x00000025,0x000000c5,0x0000074d,0x0005008e,0x00000021, + 0x00000751,0x0000073a,0x0000074e,0x00060050,0x00000021,0x00000753,0x0000075c,0x0000075c, + 0x0000075c,0x00050081,0x00000021,0x00000754,0x00000751,0x00000753,0x0003003e,0x00000504, + 0x00000754,0x000200f9,0x00000606,0x000200f8,0x00000606,0x000200f9,0x00000626,0x000200f8, + 0x000005f3,0x0004003d,0x00000021,0x000005f4,0x000004f2,0x00050081,0x00000021,0x000005f6, + 0x000005f4,0x00000637,0x0005008e,0x00000021,0x000005f8,0x000005f4,0x000001da,0x00050085, + 0x00000021,0x000005fa,0x000005f8,0x00000637,0x00050083,0x00000021,0x000005fb,0x000005f6, + 0x000005fa,0x0003003e,0x00000504,0x000005fb,0x000200f9,0x00000626,0x000200f8,0x000005ee, + 0x0004003d,0x00000021,0x000005f0,0x000004f2,0x00050083,0x00000021,0x000005f1,0x00000637, + 0x000005f0,0x0006000c,0x00000021,0x000005f2,0x00000001,0x00000004,0x000005f1,0x0003003e, + 0x00000504,0x000005f2,0x000200f9,0x00000626,0x000200f8,0x000005b3,0x000200f9,0x000005b4, + 0x000200f8,0x000005b4,0x000700f5,0x00000054,0x00000cbc,0x0000011d,0x000005b3,0x000005e2, + 0x000005e0,0x000500b1,0x000000c0,0x000005b7,0x00000cbc,0x00000128,0x000400f6,0x000005e3, + 0x000005e0,0x00000000,0x000400fa,0x000005b7,0x000005b8,0x000005e3,0x000200f8,0x000005b8, + 0x00050041,0x0000000d,0x000005ba,0x000004f2,0x00000cbc,0x0004003d,0x00000006,0x000005bb, + 0x000005ba,0x000500bc,0x000000c0,0x000005bc,0x000005bb,0x000001e1,0x000300f7,0x000005df, + 0x00000000,0x000400fa,0x000005bc,0x000005bd,0x000005c4,0x000200f8,0x000005c4,0x00050041, + 0x0000000d,0x000005c6,0x00000502,0x00000cbc,0x0004003d,0x00000006,0x000005c7,0x000005c6, + 0x000500bc,0x000000c0,0x000005c8,0x000005c7,0x0000012c,0x000300f7,0x000005de,0x00000000, + 0x000400fa,0x000005c8,0x000005c9,0x000005d6,0x000200f8,0x000005d6,0x0004003d,0x00000006, + 0x000005da,0x000005c6,0x0006000c,0x00000006,0x000005db,0x00000001,0x00000020,0x000005da, + 0x00050083,0x00000006,0x000005dc,0x000005db,0x000000c5,0x00050041,0x0000000d,0x000005dd, + 0x00000504,0x00000cbc,0x0003003e,0x000005dd,0x000005dc,0x000200f9,0x000005de,0x000200f8, + 0x000005c9,0x0004003d,0x00000006,0x000005cd,0x000005c6,0x00050085,0x00000006,0x000005ce, + 0x0000027f,0x000005cd,0x00050083,0x00000006,0x000005cf,0x000005ce,0x00000284,0x0004003d, + 0x00000006,0x000005d2,0x000005c6,0x00050085,0x00000006,0x000005d3,0x000005cf,0x000005d2, + 0x00050081,0x00000006,0x000005d4,0x000005d3,0x0000028a,0x00050041,0x0000000d,0x000005d5, + 0x00000504,0x00000cbc,0x0003003e,0x000005d5,0x000005d4,0x000200f9,0x000005de,0x000200f8, + 0x000005de,0x000200f9,0x000005df,0x000200f8,0x000005bd,0x00050041,0x0000000d,0x000005c0, + 0x00000502,0x00000cbc,0x0004003d,0x00000006,0x000005c1,0x000005c0,0x00050083,0x00000006, + 0x000005c2,0x000000c5,0x000005c1,0x00050041,0x0000000d,0x000005c3,0x00000504,0x00000cbc, + 0x0003003e,0x000005c3,0x000005c2,0x000200f9,0x000005df,0x000200f8,0x000005df,0x000200f9, + 0x000005e0,0x000200f8,0x000005e0,0x00050080,0x00000054,0x000005e2,0x00000cbc,0x00000120, + 0x000200f9,0x000005b4,0x000200f8,0x000005e3,0x0004003d,0x00000021,0x000005e6,0x000004f2, + 0x0005008e,0x00000021,0x000005e7,0x000005e6,0x000001da,0x00050083,0x00000021,0x000005e9, + 0x000005e7,0x00000d5b,0x00050085,0x00000021,0x000005ea,0x00000637,0x000005e9,0x0004003d, + 0x00000021,0x000005eb,0x00000504,0x00050085,0x00000021,0x000005ec,0x000005ea,0x000005eb, + 0x00050081,0x00000021,0x000005ed,0x00000637,0x000005ec,0x0003003e,0x00000504,0x000005ed, + 0x000200f9,0x00000626,0x000200f8,0x000005a2,0x0004003d,0x00000021,0x000005a3,0x000004f2, + 0x00050085,0x00000021,0x000005a5,0x000005a3,0x00000637,0x00050081,0x00000021,0x000005a9, + 0x000005a3,0x00000637,0x00050083,0x00000021,0x000005ab,0x000005a9,0x000005a5,0x00050083, + 0x00000021,0x000005ad,0x000005ab,0x00000d5a,0x00060052,0x00000021,0x00000aab,0x000001e1, + 0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000aad,0x000001e1,0x00000aab,0x00000001, + 0x00060052,0x00000021,0x00000aaf,0x000001e1,0x00000aad,0x00000002,0x000500ba,0x000001e7, + 0x000005b0,0x000005a3,0x00000aaf,0x000600a9,0x00000021,0x000005b1,0x000005b0,0x000005ad, + 0x000005a5,0x0005008e,0x00000021,0x000005b2,0x000005b1,0x000001da,0x0003003e,0x00000504, + 0x000005b2,0x000200f9,0x00000626,0x000200f8,0x00000575,0x0004003d,0x00000021,0x00000576, + 0x000004f2,0x00060052,0x00000021,0x00000a82,0x000000bf,0x00000ba6,0x00000000,0x00060052, + 0x00000021,0x00000a84,0x000000bf,0x00000a82,0x00000001,0x00060052,0x00000021,0x00000a86, + 0x000000bf,0x00000a84,0x00000002,0x00060052,0x00000021,0x00000a88,0x000000c5,0x00000ba6, + 0x00000000,0x00060052,0x00000021,0x00000a8a,0x000000c5,0x00000a88,0x00000001,0x00060052, + 0x00000021,0x00000a8c,0x000000c5,0x00000a8a,0x00000002,0x0008000c,0x00000021,0x00000579, + 0x00000001,0x0000002b,0x00000576,0x00000a86,0x00000a8c,0x0003003e,0x000004f2,0x00000579, + 0x0008004f,0x00000021,0x0000057e,0x00000b9f,0x00000b9f,0x00000003,0x00000003,0x00000003, + 0x0008000c,0x00000021,0x0000057f,0x00000001,0x0000002b,0x0000062c,0x00000a86,0x0000057e, + 0x00050051,0x00000006,0x00000581,0x0000057f,0x00000000,0x00060052,0x00000007,0x00000a94, + 0x00000581,0x00000b9f,0x00000000,0x00050051,0x00000006,0x00000583,0x0000057f,0x00000001, + 0x00060052,0x00000007,0x00000a96,0x00000583,0x00000a94,0x00000001,0x00050051,0x00000006, + 0x00000585,0x0000057f,0x00000002,0x00060052,0x00000007,0x00000a98,0x00000585,0x00000a96, + 0x00000002,0x00050051,0x00000006,0x00000587,0x00000a98,0x00000003,0x000500b4,0x000000c0, + 0x00000588,0x00000587,0x000000bf,0x000300f7,0x0000058b,0x00000000,0x000400fa,0x00000588, + 0x00000589,0x0000058b,0x000200f8,0x00000589,0x00060052,0x00000007,0x00000a9b,0x000000c5, + 0x00000a98,0x00000003,0x000200f9,0x0000058b,0x000200f8,0x0000058b,0x000700f5,0x00000007, + 0x00000ce8,0x00000a98,0x00000575,0x00000a9b,0x00000589,0x00050051,0x00000006,0x0000058d, + 0x00000ce8,0x00000003,0x0008004f,0x00000021,0x0000058f,0x00000ce8,0x00000ce8,0x00000000, + 0x00000001,0x00000002,0x00060050,0x00000021,0x00000590,0x0000058d,0x0000058d,0x0000058d, + 0x00050083,0x00000021,0x00000591,0x00000590,0x0000058f,0x0004003d,0x00000021,0x00000594, + 0x000004f2,0x0005008e,0x00000021,0x00000597,0x00000594,0x0000058d,0x00050088,0x00000021, + 0x00000598,0x00000591,0x00000597,0x0007000c,0x00000021,0x00000599,0x00000001,0x00000025, + 0x00000a8c,0x00000598,0x0006000c,0x00000021,0x0000059b,0x00000001,0x00000006,0x00000591, + 0x000500b4,0x000001e7,0x0000059e,0x00000594,0x00000a86,0x000600a9,0x00000021,0x0000059f, + 0x0000059e,0x0000059b,0x00000599,0x00050083,0x00000021,0x000005a1,0x00000d5b,0x0000059f, + 0x0003003e,0x00000504,0x000005a1,0x000200f9,0x00000626,0x000200f8,0x00000552,0x00060052, + 0x00000021,0x00000a5d,0x000000bf,0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000a5f, + 0x000000bf,0x00000a5d,0x00000001,0x00060052,0x00000021,0x00000a61,0x000000bf,0x00000a5f, + 0x00000002,0x0008004f,0x00000021,0x00000557,0x00000b9f,0x00000b9f,0x00000003,0x00000003, + 0x00000003,0x0008000c,0x00000021,0x00000558,0x00000001,0x0000002b,0x0000062c,0x00000a61, + 0x00000557,0x00050051,0x00000006,0x0000055a,0x00000558,0x00000000,0x00060052,0x00000007, + 0x00000a63,0x0000055a,0x00000b9f,0x00000000,0x00050051,0x00000006,0x0000055c,0x00000558, + 0x00000001,0x00060052,0x00000007,0x00000a65,0x0000055c,0x00000a63,0x00000001,0x00050051, + 0x00000006,0x0000055e,0x00000558,0x00000002,0x00060052,0x00000007,0x00000a67,0x0000055e, + 0x00000a65,0x00000002,0x0004003d,0x00000021,0x0000055f,0x000004f2,0x00050083,0x00000021, + 0x00000561,0x00000d5b,0x0000055f,0x00060052,0x00000021,0x00000a6f,0x000000c5,0x00000ba6, + 0x00000000,0x00060052,0x00000021,0x00000a71,0x000000c5,0x00000a6f,0x00000001,0x00060052, + 0x00000021,0x00000a73,0x000000c5,0x00000a71,0x00000002,0x0008000c,0x00000021,0x00000564, + 0x00000001,0x0000002b,0x00000561,0x00000a61,0x00000a73,0x00050051,0x00000006,0x00000566, + 0x00000a67,0x00000003,0x0005008e,0x00000021,0x00000567,0x00000564,0x00000566,0x0008004f, + 0x00000021,0x0000056a,0x00000a67,0x00000a67,0x00000000,0x00000001,0x00000002,0x00050088, + 0x00000021,0x0000056c,0x0000056a,0x00000567,0x0007000c,0x00000021,0x0000056d,0x00000001, + 0x00000025,0x00000a73,0x0000056c,0x0006000c,0x00000021,0x00000570,0x00000001,0x00000006, + 0x0000056a,0x000500b4,0x000001e7,0x00000573,0x00000567,0x00000a61,0x000600a9,0x00000021, + 0x00000574,0x00000573,0x00000570,0x0000056d,0x0003003e,0x00000504,0x00000574,0x000200f9, + 0x00000626,0x000200f8,0x0000054e,0x0004003d,0x00000021,0x0000054f,0x000004f2,0x0007000c, + 0x00000021,0x00000551,0x00000001,0x00000028,0x0000054f,0x00000637,0x0003003e,0x00000504, + 0x00000551,0x000200f9,0x00000626,0x000200f8,0x0000054a,0x0004003d,0x00000021,0x0000054b, + 0x000004f2,0x0007000c,0x00000021,0x0000054d,0x00000001,0x00000025,0x0000054b,0x00000637, + 0x0003003e,0x00000504,0x0000054d,0x000200f9,0x00000626,0x000200f8,0x00000539,0x0004003d, + 0x00000021,0x0000053a,0x000004f2,0x00050085,0x00000021,0x0000053c,0x0000053a,0x00000637, + 0x00050081,0x00000021,0x00000540,0x0000053a,0x00000637,0x00050083,0x00000021,0x00000542, + 0x00000540,0x0000053c,0x00050083,0x00000021,0x00000544,0x00000542,0x00000d5a,0x00060052, + 0x00000021,0x00000a57,0x000001e1,0x00000ba6,0x00000000,0x00060052,0x00000021,0x00000a59, + 0x000001e1,0x00000a57,0x00000001,0x00060052,0x00000021,0x00000a5b,0x000001e1,0x00000a59, + 0x00000002,0x000500ba,0x000001e7,0x00000547,0x00000637,0x00000a5b,0x000600a9,0x00000021, + 0x00000548,0x00000547,0x00000544,0x0000053c,0x0005008e,0x00000021,0x00000549,0x00000548, + 0x000001da,0x0003003e,0x00000504,0x00000549,0x000200f9,0x00000626,0x000200f8,0x00000531, + 0x0004003d,0x00000021,0x00000532,0x000004f2,0x00050081,0x00000021,0x00000534,0x00000532, + 0x00000637,0x00050085,0x00000021,0x00000537,0x00000532,0x00000637,0x00050083,0x00000021, + 0x00000538,0x00000534,0x00000537,0x0003003e,0x00000504,0x00000538,0x000200f9,0x00000626, + 0x000200f8,0x0000052d,0x0004003d,0x00000021,0x0000052e,0x000004f2,0x00050085,0x00000021, + 0x00000530,0x0000052e,0x00000637,0x0003003e,0x00000504,0x00000530,0x000200f9,0x00000626, + 0x000200f8,0x00000626,0x0004003d,0x00000021,0x00000627,0x00000504,0x00060052,0x00000021, + 0x00000b7a,0x0000062e,0x00000d5e,0x00000000,0x00060052,0x00000021,0x00000b7c,0x0000062e, + 0x00000b7a,0x00000001,0x00060052,0x00000021,0x00000b7e,0x0000062e,0x00000b7c,0x00000002, + 0x0008000c,0x00000021,0x00000501,0x00000001,0x0000002e,0x000003cf,0x00000627,0x00000b7e, + 0x00050051,0x00000006,0x000003d6,0x00000501,0x00000000,0x00060052,0x00000007,0x00000b80, + 0x000003d6,0x00000b9a,0x00000000,0x00050051,0x00000006,0x000003d8,0x00000501,0x00000001, + 0x00060052,0x00000007,0x00000b82,0x000003d8,0x00000b80,0x00000001,0x00050051,0x00000006, + 0x000003da,0x00000501,0x00000002,0x00060052,0x00000007,0x00000b84,0x000003da,0x00000b82, + 0x00000002,0x00050051,0x00000006,0x000003dc,0x00000b84,0x00000003,0x0008004f,0x00000021, + 0x000003de,0x00000b84,0x00000b84,0x00000000,0x00000001,0x00000002,0x0005008e,0x00000021, + 0x000003df,0x000003de,0x000003dc,0x00050051,0x00000006,0x000003e1,0x000003df,0x00000000, + 0x00060052,0x00000007,0x00000b87,0x000003e1,0x00000b84,0x00000000,0x00050051,0x00000006, + 0x000003e3,0x000003df,0x00000001,0x00060052,0x00000007,0x00000b89,0x000003e3,0x00000b87, + 0x00000001,0x00050051,0x00000006,0x000003e5,0x000003df,0x00000002,0x00060052,0x00000007, + 0x00000b8b,0x000003e5,0x00000b89,0x00000002,0x0008004f,0x00000021,0x000003ee,0x00000b8b, + 0x00000b8b,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,0x000003f0,0x000003e6, + 0x0007004f,0x00000017,0x000003f1,0x000003f0,0x000003f0,0x00000000,0x00000001,0x00050041, + 0x000003f3,0x000003f4,0x000003e9,0x000003ea,0x0004003d,0x00000006,0x000003f5,0x000003f4, + 0x00050041,0x000003f3,0x000003f7,0x000003e9,0x000003eb,0x0004003d,0x00000006,0x000003f8, + 0x000003f7,0x000300f7,0x00000a1a,0x00000000,0x000400fa,0x00000105,0x00000a10,0x00000a18, + 0x000200f8,0x00000a18,0x000200f9,0x00000a1a,0x000200f8,0x00000a10,0x00050051,0x00000006, + 0x00000a21,0x000003f1,0x00000000,0x00050085,0x00000006,0x00000a22,0x000000ef,0x00000a21, + 0x00050051,0x00000006,0x00000a24,0x000003f1,0x00000001,0x00050085,0x00000006,0x00000a25, + 0x000000f3,0x00000a24,0x00050081,0x00000006,0x00000a26,0x00000a22,0x00000a25,0x0006000c, + 0x00000006,0x00000a27,0x00000001,0x0000000a,0x00000a26,0x00050085,0x00000006,0x00000a29, + 0x000000fa,0x00000a27,0x0006000c,0x00000006,0x00000a2a,0x00000001,0x0000000a,0x00000a29, + 0x00050085,0x00000006,0x00000a2d,0x00000a2a,0x000003f5,0x00050081,0x00000006,0x00000a2f, + 0x00000a2d,0x000003f8,0x00060050,0x00000021,0x00000a16,0x00000a2f,0x00000a2f,0x00000a2f, + 0x00050081,0x00000021,0x00000a17,0x00000a16,0x000003ee,0x000200f9,0x00000a1a,0x000200f8, + 0x00000a1a,0x000700f5,0x00000021,0x00000d58,0x00000a17,0x00000a10,0x000003ee,0x00000a18, + 0x00050051,0x00000006,0x000003fb,0x00000d58,0x00000000,0x00060052,0x00000007,0x00000b8f, + 0x000003fb,0x00000b8b,0x00000000,0x00050051,0x00000006,0x000003fd,0x00000d58,0x00000001, + 0x00060052,0x00000007,0x00000b91,0x000003fd,0x00000b8f,0x00000001,0x00050051,0x00000006, + 0x000003ff,0x00000d58,0x00000002,0x00060052,0x00000007,0x00000b93,0x000003ff,0x00000b91, + 0x00000002,0x0003003e,0x00000401,0x00000b93,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..9ad5acfb7bb698888eda6e365877ae95c6dbf604 GIT binary patch literal 22392 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≪@Bpd|t0%j`bMTG}1Xw z)@3+P(x9=PH6Fyzx^)gcY0T z=d!aF1eM8d$-V&7L8-QD6L~LrlR%z<|X-Pe>A>kR|pdypZoVx^}$u$ zZypiP{RTgISpS%8?l<@;r|&HXD{uM~esioLAx}8BH|t;Ey}P|x3xgKF`%iyit}$Yh zKjR?tak1Nvo6OBckKg4*&ph2#-EUqfJbv^($EhxAvpM*`@kOqy*KO%gbceL)i ztY4zt(6}$Lj)}hD-S->TG@-}u`wblT7vDQL=KY5Ep}v=}9*=v8^sE^q9z1gd$cMFqv?1?(@jEVj z#^s$a_8mHMzvRgKX}*gr(#v1I|DbtQ`zzXSRXrBVcb71JzHxl1TwW`FxvKYJ{D0C8 zPh9YxO3Q18X>7Ub#mc{Gt+nkucl}#pfRXvM?L>czl1+{-AbZb9C&7gn3t< zu~{n$@7Vt%49E8fV!tHp*!Y%ee_A`SIl7F`3lqolFkTQ=h)TV7d>)gQ3*%cN-sO5x zHt*3W7v};S9c@qkao$g85nQobEbnx_5+WIMB zc;=kCe1Dgn<-K9$Gjmpmzg!z@aWCm zC=AcMN8gVZY8>V|YX5wCW8v}3-KM{}@c6k0F~5j8&8*#~T=@CUN?mW24Ntz5!)<(< zFh1JYZ2*^T!1pJ&!EwU0fy>O=qE$Vcv(5+}f0mgwNAUP5v*WP-Xo>9hb!ROSJpPQs zx+Hk~#PK&F*6gF>*_^VHA6n{0x$*nER zc4pi>SD1}48Qqe+6b@09a0{Kbj-Pg!marj8@{x?rJ#|Zx41US<2Ow&O5g-MH#=Mgym9|iL5uATmX z#`oX_#ivtTO-DO&9bF-w*qnD?M_0;*Ck-)O)~kgXlkodGg3Ie@jBNLJ*8i>Qx?wFK zJbub+J?jGD@zZv0+i{Bd|MlVV@)L*afj&$e()fHGD2#^9{eX3c@a_BX!A0wG(Jx!1 zg(nTX;~rYH*@s!T2u~V#pVMY>oKv^uMA@_@yz4(hX_hEW`|;t}!sB zH9c7|(a|2{LwlfgxsMP>IqAP1Bd3TX9X_}FkwxdVn8YL>_d)&-lBz~W_raru(RJ5O zo@m?$k10O-AnDu(TZPG=a=H)Bk_}H9V!FSx3`k;LA9DWjoI9!o=~tw7+b)yq7ix=e{vW96Wk+gN5PqUOG&e-0oio6&^q5(f86O#idO6-TwQEgC}3g;eIki7+>B?;j#^OlI=FwS(rBP zvqNv$aOCH9*)2HNw~siq_QP)u~&YiB+X`JnZ+__R1QY~;as!`exB&nvR_*`js6 zXjxkcPa1e@pD$X<;<&86geMKWwadlf)1mF!f2nX@uSsmuxF5VMKN`|H&I)08Hs^V! z;=((QwXYRz*5zzz;YpKqd825vF6T-EPa1fSSs#kS$Ij+*bDn9hkL73WlHZ?vA`HjQ zhMwO8tQ-1V`#aj-)lPbyy2=-Yx8|#&c`r0y3&ZnV@>5+?Y&@5+CURZb8*Asegd_bC z4K_ZvPlGUJW8*p@@6E-r4ilesTNWMVwywK4)@S15x+CpY!lcLN-;7%elTL@K-|4pz z!Fo>o*7E-kSc~7W3pMUs24&c3`ZBQOv#o^<;Wn0iDJd2@W{Vh7$ z2OaI^`hP3i>vP@b&eyqzcOS6!`=X^D*3Oj{o;2{*{!p~p=Pr~6o;2``OROD(|6Zy4 GX#XeUL;!vO literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.h new file mode 100644 index 000000000..3ce5c56f9 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.h @@ -0,0 +1,505 @@ +#pragma once + +const uint32_t draw_msaa_path_noclipdistance_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000008f7,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000d000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000034d,0x00000350,0x00000354, + 0x00000355,0x0000039a,0x000003a1,0x000003e0,0x00000465,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000ce,0x00004342,0x00030005,0x000000df, + 0x0000664b,0x00040006,0x000000df,0x00000000,0x00003464,0x00030005,0x000000e1,0x00004358, + 0x00030005,0x000000f4,0x0000664a,0x00040006,0x000000f4,0x00000000,0x00003464,0x00030005, + 0x000000f6,0x0000424c,0x00060005,0x0000034d,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00070005,0x00000350,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005, + 0x00000354,0x00004254,0x00030005,0x00000355,0x00004255,0x00030005,0x0000036a,0x00006576, + 0x00040006,0x0000036a,0x00000000,0x00003464,0x00030005,0x0000036c,0x00004355,0x00030005, + 0x00000376,0x00006747,0x00030005,0x00000388,0x0000424d,0x00040006,0x00000388,0x00000000, + 0x00006250,0x00040006,0x00000388,0x00000001,0x00006359,0x00040006,0x00000388,0x00000002, + 0x00006552,0x00040006,0x00000388,0x00000003,0x00006553,0x00040006,0x00000388,0x00000004, + 0x0000366d,0x00040006,0x00000388,0x00000005,0x0000676d,0x00040006,0x00000388,0x00000006, + 0x00006544,0x00040006,0x00000388,0x00000007,0x00006545,0x00040006,0x00000388,0x00000008, + 0x00003755,0x00040006,0x00000388,0x00000009,0x0000676a,0x00040006,0x00000388,0x0000000a, + 0x0000635a,0x00040006,0x00000388,0x0000000b,0x00003157,0x00040006,0x00000388,0x0000000c, + 0x0000676e,0x00040006,0x00000388,0x0000000d,0x00003559,0x00040006,0x00000388,0x0000000e, + 0x0000324f,0x00040006,0x00000388,0x0000000f,0x00006461,0x00040006,0x00000388,0x00000010, + 0x00006579,0x00040006,0x00000388,0x00000011,0x00003376,0x00040006,0x00000388,0x00000012, + 0x00003377,0x00040006,0x00000388,0x00000013,0x00006462,0x00040006,0x00000388,0x00000014, + 0x00006767,0x00030005,0x0000038a,0x0000006b,0x00030005,0x0000039a,0x00003153,0x00030005, + 0x0000039e,0x00006749,0x00030005,0x000003a1,0x00003159,0x00030005,0x000003af,0x00006577, + 0x00040006,0x000003af,0x00000000,0x00003464,0x00030005,0x000003b1,0x0000424f,0x00030005, + 0x000003e0,0x0000316b,0x00060005,0x00000463,0x505f6c67,0x65567265,0x78657472,0x00000000, + 0x00060006,0x00000463,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000463, + 0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000463,0x00000002, + 0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000463,0x00000003,0x435f6c67, + 0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000465,0x00000000,0x00030005,0x00000473, + 0x00004351,0x00030005,0x00000476,0x00003954,0x00040047,0x000000ce,0x00000021,0x00000008, + 0x00040047,0x000000ce,0x00000022,0x00000000,0x00040047,0x000000de,0x00000006,0x00000010, + 0x00030047,0x000000df,0x00000003,0x00040048,0x000000df,0x00000000,0x00000018,0x00050048, + 0x000000df,0x00000000,0x00000023,0x00000000,0x00030047,0x000000e1,0x00000018,0x00040047, + 0x000000e1,0x00000021,0x00000006,0x00040047,0x000000e1,0x00000022,0x00000000,0x00040047, + 0x000000f3,0x00000006,0x00000010,0x00030047,0x000000f4,0x00000003,0x00040048,0x000000f4, + 0x00000000,0x00000018,0x00050048,0x000000f4,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000000f6,0x00000018,0x00040047,0x000000f6,0x00000021,0x00000003,0x00040047,0x000000f6, + 0x00000022,0x00000000,0x00040047,0x0000034d,0x0000000b,0x0000002a,0x00040047,0x00000350, + 0x0000000b,0x0000002b,0x00040047,0x00000354,0x0000001e,0x00000000,0x00040047,0x00000355, + 0x0000001e,0x00000001,0x00040047,0x00000369,0x00000006,0x00000008,0x00030047,0x0000036a, + 0x00000003,0x00040048,0x0000036a,0x00000000,0x00000018,0x00050048,0x0000036a,0x00000000, + 0x00000023,0x00000000,0x00030047,0x0000036c,0x00000018,0x00040047,0x0000036c,0x00000021, + 0x00000004,0x00040047,0x0000036c,0x00000022,0x00000000,0x00040047,0x00000376,0x00000001, + 0x00000000,0x00030047,0x00000388,0x00000002,0x00050048,0x00000388,0x00000000,0x00000023, + 0x00000000,0x00050048,0x00000388,0x00000001,0x00000023,0x00000004,0x00050048,0x00000388, + 0x00000002,0x00000023,0x00000008,0x00050048,0x00000388,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x00000388,0x00000004,0x00000023,0x00000010,0x00050048,0x00000388,0x00000005, + 0x00000023,0x00000014,0x00050048,0x00000388,0x00000006,0x00000023,0x00000018,0x00050048, + 0x00000388,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000388,0x00000008,0x00000023, + 0x00000020,0x00050048,0x00000388,0x00000009,0x00000023,0x00000030,0x00050048,0x00000388, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x00000388,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x00000388,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000388,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x00000388,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x00000388,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000388,0x00000010,0x00000023, + 0x00000054,0x00050048,0x00000388,0x00000011,0x00000023,0x00000058,0x00050048,0x00000388, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x00000388,0x00000013,0x00000023,0x00000060, + 0x00050048,0x00000388,0x00000014,0x00000023,0x00000064,0x00040047,0x0000038a,0x00000021, + 0x00000000,0x00040047,0x0000038a,0x00000022,0x00000000,0x00030047,0x00000398,0x00000000, + 0x00030047,0x0000039a,0x00000000,0x00030047,0x0000039a,0x0000000e,0x00040047,0x0000039a, + 0x0000001e,0x00000004,0x00040047,0x0000039e,0x00000001,0x00000002,0x00030047,0x000003a1, + 0x00000000,0x00030047,0x000003a1,0x0000000e,0x00040047,0x000003a1,0x0000001e,0x00000006, + 0x00040047,0x000003ae,0x00000006,0x00000010,0x00030047,0x000003af,0x00000003,0x00040048, + 0x000003af,0x00000000,0x00000018,0x00050048,0x000003af,0x00000000,0x00000023,0x00000000, + 0x00030047,0x000003b1,0x00000018,0x00040047,0x000003b1,0x00000021,0x00000005,0x00040047, + 0x000003b1,0x00000022,0x00000000,0x00030047,0x000003d4,0x00000000,0x00030047,0x000003d7, + 0x00000000,0x00030047,0x000003d8,0x00000000,0x00040047,0x000003e0,0x0000001e,0x00000000, + 0x00030047,0x00000463,0x00000002,0x00050048,0x00000463,0x00000000,0x0000000b,0x00000000, + 0x00050048,0x00000463,0x00000001,0x0000000b,0x00000001,0x00050048,0x00000463,0x00000002, + 0x0000000b,0x00000003,0x00050048,0x00000463,0x00000003,0x0000000b,0x00000004,0x00030047, + 0x00000473,0x00000000,0x00040047,0x00000473,0x00000021,0x0000000a,0x00040047,0x00000473, + 0x00000022,0x00000000,0x00030047,0x00000476,0x00000000,0x00040047,0x00000476,0x00000021, + 0x0000000a,0x00040047,0x00000476,0x00000022,0x00000000,0x00030047,0x000007d8,0x00000000, + 0x00030047,0x000007da,0x00000000,0x00030047,0x000007dc,0x00000000,0x00030047,0x000008bc, + 0x00000000,0x00030047,0x000008db,0x00000000,0x00030047,0x000008dd,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040015, + 0x0000000c,0x00000020,0x00000000,0x00040017,0x00000012,0x00000006,0x00000004,0x00040017, + 0x00000014,0x00000006,0x00000002,0x00040018,0x00000015,0x00000014,0x00000002,0x00040015, + 0x00000031,0x00000020,0x00000001,0x00040017,0x00000033,0x00000031,0x00000002,0x00020014, + 0x0000003d,0x0004002b,0x00000006,0x00000055,0x3f800000,0x0004002b,0x00000006,0x00000056, + 0x00000000,0x0004002b,0x0000000c,0x00000061,0x00000000,0x0004002b,0x0000000c,0x00000068, + 0x000003ff,0x0004002b,0x0000000c,0x00000078,0x00000001,0x0004002b,0x00000006,0x00000085, + 0x38800000,0x0004002b,0x00000031,0x0000008b,0x000007ff,0x0004002b,0x00000031,0x0000008e, + 0x0000000b,0x0004002b,0x0000000c,0x000000ad,0x00000002,0x0004002b,0x0000000c,0x000000b1, + 0x00000003,0x0004002b,0x00000031,0x000000b5,0x00000002,0x0004002b,0x00000031,0x000000bb, + 0x00000003,0x0004002b,0x00000031,0x000000c0,0x00000001,0x00040017,0x000000c9,0x0000000c, + 0x00000004,0x00090019,0x000000cc,0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x000000cd,0x00000000,0x000000cc,0x0004003b,0x000000cd, + 0x000000ce,0x00000000,0x0004002b,0x00000031,0x000000d3,0x00000000,0x0004002b,0x0000000c, + 0x000000da,0x0000ffff,0x0003001d,0x000000de,0x000000c9,0x0003001e,0x000000df,0x000000de, + 0x00040020,0x000000e0,0x00000002,0x000000df,0x0004003b,0x000000e0,0x000000e1,0x00000002, + 0x00040020,0x000000e4,0x00000002,0x000000c9,0x00040017,0x000000e8,0x0000000c,0x00000002, + 0x0003001d,0x000000f3,0x000000c9,0x0003001e,0x000000f4,0x000000f3,0x00040020,0x000000f5, + 0x00000002,0x000000f4,0x0004003b,0x000000f5,0x000000f6,0x00000002,0x0004002b,0x0000000c, + 0x000000f8,0x00000004,0x0004002b,0x0000000c,0x00000113,0x00800000,0x0004002b,0x0000000c, + 0x00000133,0x0080ffff,0x0004002b,0x0000000c,0x00000154,0xff7fffff,0x0004002b,0x0000000c, + 0x00000159,0x1c000000,0x0004002b,0x0000000c,0x0000015b,0x04000000,0x0004002b,0x00000031, + 0x0000016b,0x00000010,0x0004002b,0x00000006,0x000001b0,0x40490fdb,0x0004002b,0x00000006, + 0x000001b4,0x40c90fdb,0x0004002b,0x00000006,0x000001e9,0x40000000,0x0005002c,0x00000014, + 0x0000020d,0x00000056,0x00000056,0x0004002b,0x0000000c,0x00000223,0x00100000,0x0004002b, + 0x0000000c,0x0000022b,0x00080000,0x0004002b,0x0000000c,0x0000025c,0x08000000,0x0004002b, + 0x0000000c,0x00000262,0x00400000,0x0004002b,0x00000006,0x00000296,0xbf000000,0x0004002b, + 0x00000006,0x00000297,0x3f000000,0x0004002b,0x0000000c,0x000002ae,0x14000000,0x0004002b, + 0x0000000c,0x000002b4,0x10000000,0x0004002b,0x00000006,0x000002b7,0x3e800000,0x0004002b, + 0x0000000c,0x000002bf,0x02000000,0x0004002b,0x0000000c,0x000002d7,0x00200000,0x0004002b, + 0x00000006,0x000002e2,0x3e000000,0x0003002a,0x0000003d,0x00000325,0x0004002b,0x0000000c, + 0x0000032e,0x80000000,0x00030029,0x0000003d,0x00000348,0x00040020,0x0000034c,0x00000001, + 0x00000031,0x0004003b,0x0000034c,0x0000034d,0x00000001,0x0004003b,0x0000034c,0x00000350, + 0x00000001,0x00040020,0x00000353,0x00000001,0x00000012,0x0004003b,0x00000353,0x00000354, + 0x00000001,0x0004003b,0x00000353,0x00000355,0x00000001,0x0003001d,0x00000369,0x000000e8, + 0x0003001e,0x0000036a,0x00000369,0x00040020,0x0000036b,0x00000002,0x0000036a,0x0004003b, + 0x0000036b,0x0000036c,0x00000002,0x00040020,0x0000036e,0x00000002,0x000000e8,0x0004002b, + 0x0000000c,0x00000374,0x0000000f,0x00030030,0x0000003d,0x00000376,0x00040017,0x00000387, + 0x00000031,0x00000004,0x0017001e,0x00000388,0x00000006,0x00000006,0x00000006,0x00000006, + 0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x00000387,0x00000014,0x00000014,0x0000000c, + 0x00000006,0x0000000c,0x00000006,0x00000006,0x0000000c,0x00000006,0x00000006,0x00000006, + 0x0000000c,0x00040020,0x00000389,0x00000002,0x00000388,0x0004003b,0x00000389,0x0000038a, + 0x00000002,0x0004002b,0x00000031,0x0000038b,0x0000000d,0x00040020,0x0000038f,0x00000002, + 0x0000000c,0x00040020,0x00000399,0x00000003,0x00000014,0x0004003b,0x00000399,0x0000039a, + 0x00000003,0x00040020,0x0000039c,0x00000003,0x00000006,0x00030030,0x0000003d,0x0000039e, + 0x0004003b,0x0000039c,0x000003a1,0x00000003,0x0004002b,0x00000031,0x000003a4,0x00000004, + 0x0003001d,0x000003ae,0x00000012,0x0003001e,0x000003af,0x000003ae,0x00040020,0x000003b0, + 0x00000002,0x000003af,0x0004003b,0x000003b0,0x000003b1,0x00000002,0x00040020,0x000003b6, + 0x00000002,0x00000012,0x00050034,0x0000003d,0x000003d0,0x000000a8,0x0000039e,0x00040017, + 0x000003d5,0x00000006,0x00000003,0x00040020,0x000003df,0x00000003,0x00000012,0x0004003b, + 0x000003df,0x000003e0,0x00000003,0x0004002b,0x00000006,0x00000418,0x3f666666,0x0004002b, + 0x00000006,0x00000440,0xc0000000,0x00040020,0x0000044c,0x00000002,0x00000006,0x0004002b, + 0x00000031,0x00000458,0x0000000e,0x0004001c,0x00000462,0x00000006,0x00000078,0x0006001e, + 0x00000463,0x00000012,0x00000006,0x00000462,0x00000462,0x00040020,0x00000464,0x00000003, + 0x00000463,0x0004003b,0x00000464,0x00000465,0x00000003,0x00090019,0x00000471,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000472, + 0x00000000,0x00000471,0x0004003b,0x00000472,0x00000473,0x00000000,0x0002001a,0x00000474, + 0x00040020,0x00000475,0x00000000,0x00000474,0x0004003b,0x00000475,0x00000476,0x00000000, + 0x00030001,0x00000014,0x000008af,0x00030001,0x0000000c,0x000008cc,0x0004002b,0x00000031, + 0x000008eb,0xfffffffe,0x0004002b,0x00000006,0x000008ec,0xbf800000,0x0004002b,0x00000006, + 0x000008ed,0x3ea2f983,0x0004002b,0x00000006,0x000008ee,0xc0400000,0x00040017,0x000008f4, + 0x0000003d,0x00000002,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000031,0x00000351,0x00000350,0x0004003d,0x00000012,0x0000035a, + 0x00000354,0x0004003d,0x00000012,0x0000035c,0x00000355,0x000300f7,0x000006f0,0x00000000, + 0x000300fb,0x00000061,0x000004d0,0x000200f8,0x000004d0,0x00050051,0x00000006,0x000004d2, + 0x0000035a,0x00000000,0x0004006e,0x00000031,0x000004d3,0x000004d2,0x00050051,0x00000006, + 0x000004d5,0x0000035a,0x00000001,0x00050051,0x00000006,0x000004d9,0x0000035a,0x00000003, + 0x0004007c,0x00000031,0x000004da,0x000004d9,0x000500c3,0x00000031,0x000004db,0x000004da, + 0x000000b5,0x000500c7,0x00000031,0x000004df,0x000004da,0x000000bb,0x00050082,0x00000031, + 0x000004e2,0x000004db,0x000000c0,0x0007000c,0x00000031,0x000004e3,0x00000001,0x00000027, + 0x000004d3,0x000004e2,0x00050084,0x00000031,0x000004e6,0x00000351,0x000004db,0x00050080, + 0x00000031,0x000004e8,0x000004e6,0x000004e3,0x0004003d,0x000000cc,0x000004e9,0x000000ce, + 0x000500c7,0x00000031,0x000006f5,0x000004e8,0x0000008b,0x000500c3,0x00000031,0x000006f7, + 0x000004e8,0x0000008e,0x00050050,0x00000033,0x000006f8,0x000006f5,0x000006f7,0x0007005f, + 0x000000c9,0x000004ec,0x000004e9,0x000006f8,0x00000002,0x000000d3,0x00050051,0x0000000c, + 0x000004ee,0x000004ec,0x00000003,0x000500c7,0x0000000c,0x000004f0,0x000004ee,0x000000da, + 0x0007000c,0x0000000c,0x000004f1,0x00000001,0x00000029,0x000004f0,0x00000078,0x00050082, + 0x0000000c,0x000004f3,0x000004f1,0x00000078,0x00060041,0x000000e4,0x000004f4,0x000000e1, + 0x000000d3,0x000004f3,0x0004003d,0x000000c9,0x000004f5,0x000004f4,0x0007004f,0x000000e8, + 0x000004f7,0x000004f5,0x000004f5,0x00000000,0x00000001,0x0004007c,0x00000014,0x000004f8, + 0x000004f7,0x00050051,0x0000000c,0x000004fa,0x000004f5,0x00000002,0x000500c7,0x0000000c, + 0x000004fb,0x000004fa,0x000000da,0x00050051,0x0000000c,0x000004fd,0x000004f5,0x00000003, + 0x00050084,0x0000000c,0x000004ff,0x000004fb,0x000000f8,0x00060041,0x000000e4,0x00000500, + 0x000000f6,0x000000d3,0x000004ff,0x0004003d,0x000000c9,0x00000501,0x00000500,0x0004007c, + 0x00000012,0x00000502,0x00000501,0x00050051,0x00000006,0x000006ff,0x00000502,0x00000000, + 0x00050051,0x00000006,0x00000700,0x00000502,0x00000001,0x00050051,0x00000006,0x00000701, + 0x00000502,0x00000002,0x00050051,0x00000006,0x00000702,0x00000502,0x00000003,0x00050050, + 0x00000014,0x00000703,0x000006ff,0x00000700,0x00050050,0x00000014,0x00000704,0x00000701, + 0x00000702,0x00050050,0x00000015,0x00000705,0x00000703,0x00000704,0x00050080,0x0000000c, + 0x00000506,0x000004ff,0x00000078,0x00060041,0x000000e4,0x00000507,0x000000f6,0x000000d3, + 0x00000506,0x0004003d,0x000000c9,0x00000508,0x00000507,0x0007004f,0x000000e8,0x0000050a, + 0x00000508,0x00000508,0x00000000,0x00000001,0x0004007c,0x00000014,0x0000050b,0x0000050a, + 0x00050051,0x0000000c,0x0000050d,0x00000508,0x00000002,0x0004007c,0x00000006,0x0000050e, + 0x0000050d,0x00050051,0x0000000c,0x00000510,0x00000508,0x00000003,0x0004007c,0x00000006, + 0x00000511,0x00000510,0x000500c7,0x0000000c,0x00000513,0x000004ee,0x00000113,0x000500ab, + 0x0000003d,0x00000515,0x00000513,0x00000061,0x000300f7,0x0000051e,0x00000000,0x000400fa, + 0x00000515,0x00000516,0x0000051e,0x000200f8,0x00000516,0x00050051,0x00000006,0x00000518, + 0x0000035c,0x00000000,0x0004006e,0x00000031,0x00000519,0x00000518,0x00050051,0x00000006, + 0x0000051b,0x0000035c,0x00000001,0x000200f9,0x0000051e,0x000200f8,0x0000051e,0x000700f5, + 0x00000006,0x00000806,0x000004d5,0x000004d0,0x0000051b,0x00000516,0x000700f5,0x00000031, + 0x000007ea,0x000004d3,0x000004d0,0x00000519,0x00000516,0x000500ab,0x0000003d,0x00000521, + 0x000007ea,0x000004e3,0x000300f7,0x0000054e,0x00000000,0x000400fa,0x00000521,0x00000522, + 0x0000054e,0x000200f8,0x00000522,0x00050080,0x00000031,0x00000525,0x000004e8,0x000007ea, + 0x00050082,0x00000031,0x00000527,0x00000525,0x000004e3,0x0004003d,0x000000cc,0x00000528, + 0x000000ce,0x000500c7,0x00000031,0x00000709,0x00000527,0x0000008b,0x000500c3,0x00000031, + 0x0000070b,0x00000527,0x0000008e,0x00050050,0x00000033,0x0000070c,0x00000709,0x0000070b, + 0x0007005f,0x000000c9,0x0000052b,0x00000528,0x0000070c,0x00000002,0x000000d3,0x00050051, + 0x0000000c,0x0000052d,0x0000052b,0x00000003,0x000500c7,0x0000000c,0x0000052e,0x0000052d, + 0x00000133,0x000500c7,0x0000000c,0x00000530,0x000004ee,0x00000133,0x000500ab,0x0000003d, + 0x00000531,0x0000052e,0x00000530,0x000300f7,0x00000548,0x00000000,0x000400fa,0x00000531, + 0x00000532,0x00000545,0x000200f8,0x00000532,0x000500b4,0x0000003d,0x00000534,0x0000050e, + 0x00000056,0x000400a8,0x0000003d,0x00000535,0x00000534,0x000300f7,0x0000053a,0x00000000, + 0x000400fa,0x00000535,0x00000536,0x0000053a,0x000200f8,0x00000536,0x00050051,0x00000006, + 0x00000538,0x000004f8,0x00000000,0x000500b7,0x0000003d,0x00000539,0x00000538,0x00000056, + 0x000200f9,0x0000053a,0x000200f8,0x0000053a,0x000700f5,0x0000003d,0x0000053b,0x00000534, + 0x00000532,0x00000539,0x00000536,0x000300f7,0x00000544,0x00000000,0x000400fa,0x0000053b, + 0x0000053d,0x00000544,0x000200f8,0x0000053d,0x0004007c,0x00000031,0x0000053f,0x000004fd, + 0x0004003d,0x000000cc,0x00000540,0x000000ce,0x000500c7,0x00000031,0x00000710,0x0000053f, + 0x0000008b,0x000500c3,0x00000031,0x00000712,0x0000053f,0x0000008e,0x00050050,0x00000033, + 0x00000713,0x00000710,0x00000712,0x0007005f,0x000000c9,0x00000543,0x00000540,0x00000713, + 0x00000002,0x000000d3,0x000200f9,0x00000544,0x000200f8,0x00000544,0x000700f5,0x00000031, + 0x000007f7,0x000004e8,0x0000053a,0x0000053f,0x0000053d,0x000700f5,0x000000c9,0x000007ef, + 0x000004ec,0x0000053a,0x00000543,0x0000053d,0x000200f9,0x00000548,0x000200f8,0x00000545, + 0x000200f9,0x00000548,0x000200f8,0x00000548,0x000700f5,0x00000031,0x000007f6,0x000007f7, + 0x00000544,0x00000527,0x00000545,0x000700f5,0x000000c9,0x000007ee,0x000007ef,0x00000544, + 0x0000052b,0x00000545,0x00050051,0x0000000c,0x0000054a,0x000007ee,0x00000003,0x000500c7, + 0x0000000c,0x0000054b,0x0000054a,0x00000154,0x000500c5,0x0000000c,0x0000054d,0x0000054b, + 0x00000513,0x000200f9,0x0000054e,0x000200f8,0x0000054e,0x000700f5,0x00000031,0x000007f5, + 0x000004e8,0x0000051e,0x000007f6,0x00000548,0x000700f5,0x000000c9,0x000007f3,0x000004ec, + 0x0000051e,0x000007ee,0x00000548,0x000700f5,0x0000000c,0x000007f2,0x000004ee,0x0000051e, + 0x0000054d,0x00000548,0x000500c7,0x0000000c,0x00000550,0x000007f2,0x00000159,0x000500aa, + 0x0000003d,0x00000551,0x00000550,0x0000015b,0x000500aa,0x0000003d,0x00000553,0x000004df, + 0x000000d3,0x000500a7,0x0000003d,0x00000554,0x00000551,0x00000553,0x000300f7,0x000005df, + 0x00000000,0x000400fa,0x00000554,0x00000555,0x000005db,0x000200f8,0x00000555,0x00050051, + 0x0000000c,0x00000557,0x000007f3,0x00000002,0x000500c7,0x0000000c,0x00000559,0x00000557, + 0x000000da,0x00040070,0x00000006,0x0000055a,0x00000559,0x000500c2,0x0000000c,0x0000055c, + 0x00000557,0x0000016b,0x00040070,0x00000006,0x0000055d,0x0000055c,0x00050083,0x00000006, + 0x00000560,0x000008ec,0x0000055a,0x0004006e,0x00000031,0x00000561,0x00000560,0x00050083, + 0x00000006,0x00000564,0x0000055d,0x0000055a,0x00050081,0x00000006,0x00000565,0x00000564, + 0x00000055,0x0004006e,0x00000031,0x00000566,0x00000565,0x00050050,0x00000033,0x00000567, + 0x00000561,0x00000566,0x000500c7,0x0000000c,0x00000569,0x000007f2,0x00000113,0x000500ab, + 0x0000003d,0x0000056a,0x00000569,0x00000061,0x000300f7,0x0000056e,0x00000000,0x000400fa, + 0x0000056a,0x0000056b,0x0000056e,0x000200f8,0x0000056b,0x0004007e,0x00000033,0x0000056d, + 0x00000567,0x000200f9,0x0000056e,0x000200f8,0x0000056e,0x000700f5,0x00000033,0x000007f9, + 0x00000567,0x00000555,0x0000056d,0x0000056b,0x0004003d,0x000000cc,0x0000056f,0x000000ce, + 0x00050051,0x00000031,0x00000572,0x000007f9,0x00000000,0x00050080,0x00000031,0x00000573, + 0x000007f5,0x00000572,0x000500c7,0x00000031,0x00000717,0x00000573,0x0000008b,0x000500c3, + 0x00000031,0x00000719,0x00000573,0x0000008e,0x00050050,0x00000033,0x0000071a,0x00000717, + 0x00000719,0x0007005f,0x000000c9,0x00000575,0x0000056f,0x0000071a,0x00000002,0x000000d3, + 0x0004003d,0x000000cc,0x00000576,0x000000ce,0x00050051,0x00000031,0x00000579,0x000007f9, + 0x00000001,0x00050080,0x00000031,0x0000057a,0x000007f5,0x00000579,0x000500c7,0x00000031, + 0x0000071e,0x0000057a,0x0000008b,0x000500c3,0x00000031,0x00000720,0x0000057a,0x0000008e, + 0x00050050,0x00000033,0x00000721,0x0000071e,0x00000720,0x0007005f,0x000000c9,0x0000057c, + 0x00000576,0x00000721,0x00000002,0x000000d3,0x00050051,0x0000000c,0x0000057e,0x0000057c, + 0x00000003,0x000500c7,0x0000000c,0x0000057f,0x0000057e,0x00000133,0x00050051,0x0000000c, + 0x00000581,0x00000575,0x00000003,0x000500c7,0x0000000c,0x00000582,0x00000581,0x00000133, + 0x000500ab,0x0000003d,0x00000583,0x0000057f,0x00000582,0x000300f7,0x0000058a,0x00000000, + 0x000400fa,0x00000583,0x00000584,0x0000058a,0x000200f8,0x00000584,0x0004003d,0x000000cc, + 0x00000585,0x000000ce,0x0004007c,0x00000031,0x00000587,0x000004fd,0x000500c7,0x00000031, + 0x00000725,0x00000587,0x0000008b,0x000500c3,0x00000031,0x00000727,0x00000587,0x0000008e, + 0x00050050,0x00000033,0x00000728,0x00000725,0x00000727,0x0007005f,0x000000c9,0x00000589, + 0x00000585,0x00000728,0x00000002,0x000000d3,0x000200f9,0x0000058a,0x000200f8,0x0000058a, + 0x000700f5,0x000000c9,0x000007fa,0x0000057c,0x0000056e,0x00000589,0x00000584,0x00050051, + 0x0000000c,0x0000058c,0x00000575,0x00000002,0x0004007c,0x00000006,0x0000058d,0x0000058c, + 0x00050051,0x0000000c,0x0000058f,0x000007fa,0x00000002,0x0004007c,0x00000006,0x00000590, + 0x0000058f,0x00050083,0x00000006,0x00000593,0x00000590,0x0000058d,0x0006000c,0x00000006, + 0x00000595,0x00000001,0x00000004,0x00000593,0x000500ba,0x0000003d,0x00000596,0x00000595, + 0x000001b0,0x000300f7,0x0000059d,0x00000000,0x000400fa,0x00000596,0x00000597,0x0000059d, + 0x000200f8,0x00000597,0x0006000c,0x00000006,0x00000599,0x00000001,0x00000006,0x00000593, + 0x00050085,0x00000006,0x0000059a,0x000001b4,0x00000599,0x00050083,0x00000006,0x0000059c, + 0x00000593,0x0000059a,0x000200f9,0x0000059d,0x000200f8,0x0000059d,0x000700f5,0x00000006, + 0x000007fe,0x00000593,0x0000058a,0x0000059c,0x00000597,0x00050081,0x00000006,0x000005a0, + 0x0000055d,0x00000440,0x0006000c,0x00000006,0x000005a2,0x00000001,0x00000004,0x000007fe, + 0x00050085,0x00000006,0x000005a3,0x000005a2,0x000008ed,0x00050085,0x00000006,0x000005a5, + 0x000005a3,0x000005a0,0x0006000c,0x00000006,0x000005a6,0x00000001,0x00000001,0x000005a5, + 0x00050081,0x00000006,0x000005a8,0x0000055d,0x000008ee,0x0008000c,0x00000006,0x000005a9, + 0x00000001,0x0000002b,0x000005a6,0x00000055,0x000005a8,0x00050083,0x00000006,0x000005ac, + 0x000005a0,0x000005a9,0x000500bc,0x0000003d,0x000005af,0x0000055a,0x000005ac,0x000300f7, + 0x000005cc,0x00000000,0x000400fa,0x000005af,0x000005b0,0x000005bf,0x000200f8,0x000005b0, + 0x0006000c,0x00000006,0x000005b2,0x00000001,0x00000006,0x000007fe,0x00050085,0x00000006, + 0x000005b3,0x000001b0,0x000005b2,0x00050083,0x00000006,0x000005b5,0x000005b3,0x000007fe, + 0x0004007f,0x00000006,0x000005b6,0x000005b5,0x000500b4,0x0000003d,0x000005ba,0x0000055a, + 0x000005ac,0x000300f7,0x000005be,0x00000000,0x000400fa,0x000005ba,0x000005bb,0x000005be, + 0x000200f8,0x000005bb,0x0004007f,0x00000006,0x000005bd,0x00000806,0x000200f9,0x000005be, + 0x000200f8,0x000005be,0x000700f5,0x00000006,0x00000845,0x00000806,0x000005b0,0x000005bd, + 0x000005bb,0x000200f9,0x000005cc,0x000200f8,0x000005bf,0x00050081,0x00000006,0x000005c2, + 0x000005ac,0x00000055,0x000500b4,0x0000003d,0x000005c3,0x0000055a,0x000005c2,0x000300f7, + 0x000005cb,0x00000000,0x000400fa,0x000005c3,0x000005c4,0x000005c5,0x000200f8,0x000005c4, + 0x000200f9,0x000005cb,0x000200f8,0x000005c5,0x00050081,0x00000006,0x000005c7,0x000005ac, + 0x000001e9,0x00050083,0x00000006,0x000005c9,0x0000055a,0x000005c7,0x000200f9,0x000005cb, + 0x000200f8,0x000005cb,0x000700f5,0x00000006,0x0000080c,0x00000056,0x000005c4,0x000005c9, + 0x000005c5,0x000600a9,0x00000006,0x000008ef,0x000005c3,0x00000056,0x00000806,0x000600a9, + 0x00000006,0x000008f0,0x000005c3,0x00000056,0x000005a9,0x000200f9,0x000005cc,0x000200f8, + 0x000005cc,0x000700f5,0x00000006,0x00000844,0x00000845,0x000005be,0x000008ef,0x000005cb, + 0x000700f5,0x00000006,0x00000810,0x000005b6,0x000005be,0x000007fe,0x000005cb,0x000700f5, + 0x00000006,0x0000080d,0x000005ac,0x000005be,0x000008f0,0x000005cb,0x000700f5,0x00000006, + 0x0000080a,0x0000055a,0x000005be,0x0000080c,0x000005cb,0x000500b4,0x0000003d,0x000005cf, + 0x0000080a,0x0000080d,0x000300f7,0x000005da,0x00000000,0x000400fa,0x000005cf,0x000005d0, + 0x000005d2,0x000200f8,0x000005d0,0x000200f9,0x000005da,0x000200f8,0x000005d2,0x00050088, + 0x00000006,0x000005d7,0x0000080a,0x0000080d,0x00050085,0x00000006,0x000005d8,0x00000810, + 0x000005d7,0x00050081,0x00000006,0x000005d9,0x0000058d,0x000005d8,0x000200f9,0x000005da, + 0x000200f8,0x000005da,0x000700f5,0x00000006,0x00000814,0x00000590,0x000005d0,0x000005d9, + 0x000005d2,0x000200f9,0x000005df,0x000200f8,0x000005db,0x00050051,0x0000000c,0x000005dd, + 0x000007f3,0x00000002,0x0004007c,0x00000006,0x000005de,0x000005dd,0x000200f9,0x000005df, + 0x000200f8,0x000005df,0x000700f5,0x00000006,0x00000842,0x00000844,0x000005da,0x00000806, + 0x000005db,0x000700f5,0x00000006,0x00000813,0x00000814,0x000005da,0x000005de,0x000005db, + 0x0006000c,0x00000006,0x000005e1,0x00000001,0x0000000d,0x00000813,0x0006000c,0x00000006, + 0x000005e3,0x00000001,0x0000000e,0x00000813,0x0004007f,0x00000006,0x000005e4,0x000005e3, + 0x00050050,0x00000014,0x000005e5,0x000005e1,0x000005e4,0x0007004f,0x000000e8,0x000005e7, + 0x000007f3,0x000007f3,0x00000000,0x00000001,0x0004007c,0x00000014,0x000005e8,0x000005e7, + 0x000500b7,0x0000003d,0x000005ea,0x00000511,0x00000056,0x000300f7,0x000005f3,0x00000000, + 0x000400fa,0x000005ea,0x000005eb,0x000005f3,0x000200f8,0x000005eb,0x00050091,0x00000014, + 0x000005ef,0x00000705,0x000005e5,0x0006000c,0x00000006,0x000005f0,0x00000001,0x00000042, + 0x000005ef,0x00050088,0x00000006,0x000005f1,0x00000055,0x000005f0,0x0007000c,0x00000006, + 0x000005f2,0x00000001,0x00000028,0x00000511,0x000005f1,0x000200f9,0x000005f3,0x000200f8, + 0x000005f3,0x000700f5,0x00000006,0x0000084b,0x00000511,0x000005df,0x000005f2,0x000005eb, + 0x000500b7,0x0000003d,0x000005f5,0x0000050e,0x00000056,0x000300f7,0x000006e0,0x00000000, + 0x000400fa,0x000005f5,0x000005f6,0x000006d2,0x000200f8,0x000005f6,0x0006000c,0x00000006, + 0x000005f8,0x00000001,0x00000021,0x00000705,0x0006000c,0x00000006,0x000005f9,0x00000001, + 0x00000006,0x000005f8,0x00050085,0x00000006,0x000005fb,0x00000842,0x000005f9,0x000500c7, + 0x0000000c,0x000005fd,0x000007f2,0x00000223,0x000500ab,0x0000003d,0x000005fe,0x000005fd, + 0x00000061,0x000300f7,0x00000602,0x00000000,0x000400fa,0x000005fe,0x000005ff,0x00000602, + 0x000200f8,0x000005ff,0x0007000c,0x00000006,0x00000601,0x00000001,0x00000025,0x000005fb, + 0x00000056,0x000200f9,0x00000602,0x000200f8,0x00000602,0x000700f5,0x00000006,0x00000848, + 0x000005fb,0x000005f6,0x00000601,0x000005ff,0x000500c7,0x0000000c,0x00000604,0x000007f2, + 0x0000022b,0x000500ab,0x0000003d,0x00000605,0x00000604,0x00000061,0x000300f7,0x00000609, + 0x00000000,0x000400fa,0x00000605,0x00000606,0x00000609,0x000200f8,0x00000606,0x0007000c, + 0x00000006,0x00000608,0x00000001,0x00000028,0x00000848,0x00000056,0x000200f9,0x00000609, + 0x000200f8,0x00000609,0x000700f5,0x00000006,0x00000881,0x00000848,0x00000602,0x00000608, + 0x00000606,0x000500b7,0x0000003d,0x0000060b,0x0000084b,0x00000056,0x000600a9,0x00000006, + 0x000008f1,0x0000060b,0x0000084b,0x00000056,0x000500ba,0x0000003d,0x00000617,0x000008f1, + 0x0000050e,0x000500b4,0x0000003d,0x00000619,0x0000084b,0x00000056,0x000500a7,0x0000003d, + 0x0000061a,0x00000617,0x00000619,0x000600a9,0x00000006,0x000008f2,0x0000061a,0x000008f1, + 0x0000050e,0x00050081,0x00000006,0x00000626,0x000008f2,0x000008f1,0x0005008e,0x00000014, + 0x00000627,0x000005e5,0x00000626,0x000500ac,0x0000003d,0x0000062b,0x00000550,0x0000025c, + 0x000300f7,0x000006c8,0x00000000,0x000400fa,0x0000062b,0x0000062c,0x000006c8,0x000200f8, + 0x0000062c,0x000500c7,0x0000000c,0x0000062e,0x000007f2,0x00000262,0x000500aa,0x0000003d, + 0x0000062f,0x0000062e,0x00000061,0x000600a9,0x00000031,0x000008f3,0x0000062f,0x000008eb, + 0x000000b5,0x000500c7,0x0000000c,0x00000635,0x000007f2,0x00000113,0x000500ab,0x0000003d, + 0x00000636,0x00000635,0x00000061,0x000300f7,0x0000063a,0x00000000,0x000400fa,0x00000636, + 0x00000637,0x0000063a,0x000200f8,0x00000637,0x0004007e,0x00000031,0x00000639,0x000008f3, + 0x000200f9,0x0000063a,0x000200f8,0x0000063a,0x000700f5,0x00000031,0x00000865,0x000008f3, + 0x0000062c,0x00000639,0x00000637,0x00050080,0x00000031,0x0000063d,0x000007f5,0x00000865, + 0x000500c7,0x00000031,0x00000748,0x0000063d,0x0000008b,0x000500c3,0x00000031,0x0000074a, + 0x0000063d,0x0000008e,0x00050050,0x00000033,0x0000074b,0x00000748,0x0000074a,0x0004003d, + 0x000000cc,0x0000063f,0x000000ce,0x0007005f,0x000000c9,0x00000641,0x0000063f,0x0000074b, + 0x00000002,0x000000d3,0x00050051,0x0000000c,0x00000643,0x00000641,0x00000002,0x0004007c, + 0x00000006,0x00000644,0x00000643,0x00050083,0x00000006,0x00000647,0x00000644,0x00000813, + 0x0006000c,0x00000006,0x00000648,0x00000001,0x00000004,0x00000647,0x000500ba,0x0000003d, + 0x0000064a,0x00000648,0x000001b0,0x000300f7,0x0000064e,0x00000000,0x000400fa,0x0000064a, + 0x0000064b,0x0000064e,0x000200f8,0x0000064b,0x00050083,0x00000006,0x0000064d,0x000001b4, + 0x00000648,0x000200f9,0x0000064e,0x000200f8,0x0000064e,0x000700f5,0x00000006,0x0000086f, + 0x00000648,0x0000063a,0x0000064d,0x0000064b,0x000500ab,0x0000003d,0x00000651,0x0000062e, + 0x00000061,0x000500a4,0x0000003d,0x00000658,0x00000651,0x000005fe,0x000600a9,0x00000006, + 0x00000659,0x00000658,0x00000296,0x00000297,0x00050085,0x00000006,0x0000065a,0x0000086f, + 0x00000659,0x00050081,0x00000006,0x0000065c,0x0000065a,0x00000813,0x0006000c,0x00000006, + 0x0000065e,0x00000001,0x0000000d,0x0000065c,0x0006000c,0x00000006,0x00000660,0x00000001, + 0x0000000e,0x0000065c,0x0004007f,0x00000006,0x00000661,0x00000660,0x00050050,0x00000014, + 0x00000662,0x0000065e,0x00000661,0x00050091,0x00000014,0x00000751,0x00000705,0x00000662, + 0x00050051,0x00000006,0x00000753,0x00000751,0x00000000,0x0006000c,0x00000006,0x00000754, + 0x00000001,0x00000004,0x00000753,0x00050051,0x00000006,0x00000756,0x00000751,0x00000001, + 0x0006000c,0x00000006,0x00000757,0x00000001,0x00000004,0x00000756,0x00050081,0x00000006, + 0x00000758,0x00000754,0x00000757,0x00050094,0x00000006,0x0000075b,0x00000751,0x00000751, + 0x00050088,0x00000006,0x0000075c,0x00000055,0x0000075b,0x00050085,0x00000006,0x0000075d, + 0x00000758,0x0000075c,0x00050085,0x00000006,0x00000667,0x0000086f,0x00000297,0x0006000c, + 0x00000006,0x00000668,0x00000001,0x0000000e,0x00000667,0x000500aa,0x0000003d,0x0000066a, + 0x00000550,0x000002ae,0x000400a8,0x0000003d,0x0000066b,0x0000066a,0x000300f7,0x00000672, + 0x00000000,0x000400fa,0x0000066b,0x0000066c,0x00000672,0x000200f8,0x0000066c,0x000500aa, + 0x0000003d,0x0000066e,0x00000550,0x000002b4,0x000500be,0x0000003d,0x00000670,0x00000668, + 0x000002b7,0x000500a7,0x0000003d,0x00000671,0x0000066e,0x00000670,0x000200f9,0x00000672, + 0x000200f8,0x00000672,0x000700f5,0x0000003d,0x00000673,0x0000066a,0x0000064e,0x00000671, + 0x0000066c,0x000300f7,0x00000686,0x00000000,0x000400fa,0x00000673,0x00000674,0x0000067f, + 0x000200f8,0x00000674,0x000500c7,0x0000000c,0x00000676,0x000007f2,0x000002bf,0x000500ab, + 0x0000003d,0x00000677,0x00000676,0x00000061,0x000600a9,0x00000006,0x00000678,0x00000677, + 0x00000055,0x000002b7,0x0007000c,0x00000006,0x0000067c,0x00000001,0x00000028,0x00000668, + 0x00000678,0x00050088,0x00000006,0x0000067d,0x00000055,0x0000067c,0x00050085,0x00000006, + 0x0000067e,0x000008f2,0x0000067d,0x000200f9,0x00000686,0x000200f8,0x0000067f,0x00050085, + 0x00000006,0x00000682,0x000008f2,0x00000668,0x00050085,0x00000006,0x00000684,0x0000075d, + 0x00000297,0x00050081,0x00000006,0x00000685,0x00000682,0x00000684,0x000200f9,0x00000686, + 0x000200f8,0x00000686,0x000700f5,0x00000006,0x00000876,0x0000067e,0x00000674,0x00000685, + 0x0000067f,0x000500c7,0x0000000c,0x0000068c,0x000007f2,0x000002d7,0x000500ab,0x0000003d, + 0x0000068d,0x0000068c,0x00000061,0x000300f7,0x000006bb,0x00000000,0x000400fa,0x0000068d, + 0x0000068e,0x000006bb,0x000200f8,0x0000068e,0x00050085,0x00000006,0x00000693,0x000008f1, + 0x000002e2,0x00050085,0x00000006,0x00000697,0x00000876,0x00000668,0x00050081,0x00000006, + 0x00000699,0x00000697,0x00000693,0x000500bc,0x0000003d,0x0000069a,0x00000626,0x00000699, + 0x000300f7,0x000006ba,0x00000000,0x000400fa,0x0000069a,0x0000069b,0x000006a3,0x000200f8, + 0x0000069b,0x00050088,0x00000006,0x0000069e,0x00000055,0x00000668,0x00050085,0x00000006, + 0x0000069f,0x00000626,0x0000069e,0x0005008e,0x00000014,0x000006a2,0x00000662,0x0000069f, + 0x000200f9,0x000006ba,0x000200f8,0x000006a3,0x0005008e,0x00000014,0x000006a6,0x00000662, + 0x00000876,0x00050094,0x00000006,0x000006a9,0x00000627,0x00000627,0x00050094,0x00000006, + 0x000006ac,0x000006a6,0x000006a6,0x00050050,0x00000014,0x000006ad,0x000006a9,0x000006ac, + 0x00050050,0x00000015,0x000006b7,0x00000627,0x000006a6,0x0006000c,0x00000015,0x000006b8, + 0x00000001,0x00000022,0x000006b7,0x00050090,0x00000014,0x000006b9,0x000006ad,0x000006b8, + 0x000200f9,0x000006ba,0x000200f8,0x000006ba,0x000700f5,0x00000014,0x0000088b,0x000006a2, + 0x0000069b,0x000006b9,0x000006a3,0x000200f9,0x000006bb,0x000200f8,0x000006bb,0x000700f5, + 0x00000014,0x0000088a,0x00000627,0x00000686,0x0000088b,0x000006ba,0x000200f9,0x000006c8, + 0x000200f8,0x000006c8,0x000700f5,0x00000014,0x00000889,0x00000627,0x00000609,0x0000088a, + 0x000006bb,0x0005008e,0x00000014,0x000006cc,0x00000889,0x00000881,0x00050091,0x00000014, + 0x000006cd,0x00000705,0x000006cc,0x000500ab,0x0000003d,0x000006cf,0x000004df,0x000000d3, + 0x000300f7,0x000006d1,0x00000000,0x000400fa,0x000006cf,0x000006d0,0x000006d1,0x000200f8, + 0x000006d0,0x000200f9,0x000006f0,0x000200f8,0x000006d1,0x000200f9,0x000006e0,0x000200f8, + 0x000006d2,0x000500aa,0x0000003d,0x000006d4,0x000004df,0x000000b5,0x00050050,0x000008f4, + 0x000008f5,0x000006d4,0x000006d4,0x000600a9,0x00000014,0x000008f6,0x000008f5,0x000004f8, + 0x000005e8,0x000500c7,0x0000000c,0x000006d9,0x000007f2,0x0000032e,0x000500ab,0x0000003d, + 0x000006da,0x000006d9,0x00000061,0x000500ab,0x0000003d,0x000006dc,0x000004df,0x000000c0, + 0x000500a7,0x0000003d,0x000006dd,0x000006da,0x000006dc,0x000300f7,0x000006df,0x00000000, + 0x000400fa,0x000006dd,0x000006de,0x000006df,0x000200f8,0x000006de,0x000200f9,0x000006f0, + 0x000200f8,0x000006df,0x000200f9,0x000006e0,0x000200f8,0x000006e0,0x000700f5,0x00000014, + 0x0000089b,0x000006cd,0x000006d1,0x0000020d,0x000006df,0x000700f5,0x00000014,0x0000088c, + 0x000005e8,0x000006d1,0x000008f6,0x000006df,0x00050091,0x00000014,0x000006e3,0x00000705, + 0x0000088c,0x00050081,0x00000014,0x000006e5,0x000006e3,0x0000089b,0x00050081,0x00000014, + 0x000006e7,0x000006e5,0x0000050b,0x00050080,0x0000000c,0x000006ea,0x000004ff,0x000000ad, + 0x00060041,0x000000e4,0x000006eb,0x000000f6,0x000000d3,0x000006ea,0x0004003d,0x000000c9, + 0x000006ec,0x000006eb,0x00050051,0x0000000c,0x000006ee,0x000006ec,0x00000000,0x000200f9, + 0x000006f0,0x000200f8,0x000006f0,0x000900f5,0x0000000c,0x000008bc,0x000008cc,0x000006d0, + 0x000008cc,0x000006de,0x000006ee,0x000006e0,0x000900f5,0x00000014,0x0000089f,0x000008af, + 0x000006d0,0x000008af,0x000006de,0x000006e7,0x000006e0,0x000900f5,0x0000003d,0x0000089e, + 0x00000325,0x000006d0,0x00000325,0x000006de,0x00000348,0x000006e0,0x00060041,0x0000036e, + 0x0000036f,0x0000036c,0x000000d3,0x000004fb,0x0004003d,0x000000e8,0x00000370,0x0000036f, + 0x00050051,0x0000000c,0x00000373,0x00000370,0x00000000,0x000500c7,0x0000000c,0x00000375, + 0x00000373,0x00000374,0x000300f7,0x00000378,0x00000000,0x000400fa,0x00000376,0x00000377, + 0x00000378,0x000200f8,0x00000377,0x000500aa,0x0000003d,0x0000037b,0x00000375,0x00000061, + 0x000300f7,0x0000037e,0x00000000,0x000400fa,0x0000037b,0x0000037d,0x00000381,0x000200f8, + 0x0000037d,0x00050051,0x0000000c,0x00000380,0x00000370,0x00000001,0x000200f9,0x0000037e, + 0x000200f8,0x00000381,0x000200f9,0x0000037e,0x000200f8,0x0000037e,0x000700f5,0x0000000c, + 0x000008d9,0x00000380,0x0000037d,0x00000373,0x00000381,0x000500c2,0x0000000c,0x00000385, + 0x000008d9,0x0000016b,0x00050041,0x0000038f,0x00000390,0x0000038a,0x0000038b,0x0004003d, + 0x0000000c,0x00000391,0x00000390,0x000500aa,0x0000003d,0x00000768,0x00000385,0x00000061, + 0x000300f7,0x00000771,0x00000000,0x000400fa,0x00000768,0x00000769,0x0000076a,0x000200f8, + 0x00000769,0x000200f9,0x00000771,0x000200f8,0x0000076a,0x00050080,0x0000000c,0x0000076c, + 0x00000385,0x00000068,0x00050084,0x0000000c,0x0000076e,0x0000076c,0x00000391,0x0006000c, + 0x00000014,0x0000076f,0x00000001,0x0000003e,0x0000076e,0x00050051,0x00000006,0x00000770, + 0x0000076f,0x00000000,0x000200f9,0x00000771,0x000200f8,0x00000771,0x000700f5,0x00000006, + 0x000008da,0x00000056,0x00000769,0x00000770,0x0000076a,0x000300f7,0x00000396,0x00000000, + 0x000400fa,0x0000037b,0x00000395,0x00000396,0x000200f8,0x00000395,0x0004007f,0x00000006, + 0x00000398,0x000008da,0x000200f9,0x00000396,0x000200f8,0x00000396,0x000700f5,0x00000006, + 0x000008db,0x000008da,0x00000771,0x00000398,0x00000395,0x00050041,0x0000039c,0x0000039d, + 0x0000039a,0x00000061,0x0003003e,0x0000039d,0x000008db,0x000200f9,0x00000378,0x000200f8, + 0x00000378,0x000300f7,0x000003a0,0x00000000,0x000400fa,0x0000039e,0x0000039f,0x000003a0, + 0x000200f8,0x0000039f,0x000500c2,0x0000000c,0x000003a5,0x00000373,0x000003a4,0x000500c7, + 0x0000000c,0x000003a6,0x000003a5,0x00000374,0x00040070,0x00000006,0x000003a7,0x000003a6, + 0x0003003e,0x000003a1,0x000003a7,0x000200f9,0x000003a0,0x000200f8,0x000003a0,0x000500aa, + 0x0000003d,0x000003c9,0x00000375,0x00000078,0x000300f7,0x000003cb,0x00000000,0x000400fa, + 0x000003c9,0x000003ca,0x000003e2,0x000200f8,0x000003ca,0x00050051,0x0000000c,0x000003ce, + 0x00000370,0x00000001,0x0006000c,0x00000012,0x000003cf,0x00000001,0x00000040,0x000003ce, + 0x000300f7,0x000003d2,0x00000000,0x000400fa,0x000003d0,0x000003d1,0x000003d2,0x000200f8, + 0x000003d1,0x00050051,0x00000006,0x000003d4,0x000003cf,0x00000003,0x0008004f,0x000003d5, + 0x000003d7,0x000003cf,0x000003cf,0x00000000,0x00000001,0x00000002,0x0005008e,0x000003d5, + 0x000003d8,0x000003d7,0x000003d4,0x00050051,0x00000006,0x000003da,0x000003d8,0x00000000, + 0x00060052,0x00000012,0x000007d8,0x000003da,0x000003cf,0x00000000,0x00050051,0x00000006, + 0x000003dc,0x000003d8,0x00000001,0x00060052,0x00000012,0x000007da,0x000003dc,0x000007d8, + 0x00000001,0x00050051,0x00000006,0x000003de,0x000003d8,0x00000002,0x00060052,0x00000012, + 0x000007dc,0x000003de,0x000007da,0x00000002,0x000200f9,0x000003d2,0x000200f8,0x000003d2, + 0x000700f5,0x00000012,0x000008dd,0x000003cf,0x000003ca,0x000007dc,0x000003d1,0x0003003e, + 0x000003e0,0x000008dd,0x000200f9,0x000003cb,0x000200f8,0x000003e2,0x000500aa,0x0000003d, + 0x000003e4,0x00000375,0x00000061,0x000500a7,0x0000003d,0x000003e5,0x00000376,0x000003e4, + 0x000300f7,0x000003e7,0x00000000,0x000400fa,0x000003e5,0x000003e6,0x000003f3,0x000200f8, + 0x000003e6,0x000500c2,0x0000000c,0x000003eb,0x00000373,0x0000016b,0x00050041,0x0000038f, + 0x000003ee,0x0000038a,0x0000038b,0x0004003d,0x0000000c,0x000003ef,0x000003ee,0x000500aa, + 0x0000003d,0x00000787,0x000003eb,0x00000061,0x000300f7,0x00000790,0x00000000,0x000400fa, + 0x00000787,0x00000788,0x00000789,0x000200f8,0x00000788,0x000200f9,0x00000790,0x000200f8, + 0x00000789,0x00050080,0x0000000c,0x0000078b,0x000003eb,0x00000068,0x00050084,0x0000000c, + 0x0000078d,0x0000078b,0x000003ef,0x0006000c,0x00000014,0x0000078e,0x00000001,0x0000003e, + 0x0000078d,0x00050051,0x00000006,0x0000078f,0x0000078e,0x00000000,0x000200f9,0x00000790, + 0x000200f8,0x00000790,0x000700f5,0x00000006,0x000008dc,0x00000056,0x00000788,0x0000078f, + 0x00000789,0x00050041,0x0000039c,0x000003f2,0x0000039a,0x00000078,0x0003003e,0x000003f2, + 0x000008dc,0x000200f9,0x000003e7,0x000200f8,0x000003f3,0x00060041,0x000003b6,0x000003f8, + 0x000003b1,0x000000d3,0x000004ff,0x0004003d,0x00000012,0x000003f9,0x000003f8,0x00050051, + 0x00000006,0x00000799,0x000003f9,0x00000000,0x00050051,0x00000006,0x0000079a,0x000003f9, + 0x00000001,0x00050051,0x00000006,0x0000079b,0x000003f9,0x00000002,0x00050051,0x00000006, + 0x0000079c,0x000003f9,0x00000003,0x00050050,0x00000014,0x0000079d,0x00000799,0x0000079a, + 0x00050050,0x00000014,0x0000079e,0x0000079b,0x0000079c,0x00050050,0x00000015,0x0000079f, + 0x0000079d,0x0000079e,0x00060041,0x000003b6,0x000003ff,0x000003b1,0x000000d3,0x00000506, + 0x0004003d,0x00000012,0x00000400,0x000003ff,0x00050091,0x00000014,0x00000404,0x0000079f, + 0x0000089f,0x0007004f,0x00000014,0x00000406,0x00000400,0x00000400,0x00000000,0x00000001, + 0x00050081,0x00000014,0x00000407,0x00000404,0x00000406,0x000500aa,0x0000003d,0x00000409, + 0x00000375,0x000000ad,0x000500aa,0x0000003d,0x0000040b,0x00000375,0x000000b1,0x000500a6, + 0x0000003d,0x0000040c,0x00000409,0x0000040b,0x000300f7,0x0000040e,0x00000000,0x000400fa, + 0x0000040c,0x0000040d,0x00000433,0x000200f8,0x0000040d,0x00050051,0x0000000c,0x00000410, + 0x00000370,0x00000001,0x0004007c,0x00000006,0x00000411,0x00000410,0x0004007f,0x00000006, + 0x00000412,0x00000411,0x00050041,0x0000039c,0x00000413,0x000003e0,0x000000b1,0x0003003e, + 0x00000413,0x00000412,0x00050051,0x00000006,0x00000416,0x00000400,0x00000002,0x000500ba, + 0x0000003d,0x00000419,0x00000416,0x00000418,0x000300f7,0x0000041b,0x00000000,0x000400fa, + 0x00000419,0x0000041a,0x0000041d,0x000200f8,0x0000041a,0x00050041,0x0000039c,0x0000041c, + 0x000003e0,0x000000ad,0x0003003e,0x0000041c,0x000001e9,0x000200f9,0x0000041b,0x000200f8, + 0x0000041d,0x00050051,0x00000006,0x0000041f,0x00000400,0x00000003,0x00050041,0x0000039c, + 0x00000420,0x000003e0,0x000000ad,0x0003003e,0x00000420,0x0000041f,0x000200f9,0x0000041b, + 0x000200f8,0x0000041b,0x000300f7,0x00000424,0x00000000,0x000400fa,0x00000409,0x00000423, + 0x00000429,0x000200f8,0x00000423,0x00050041,0x0000039c,0x00000425,0x000003e0,0x00000078, + 0x0003003e,0x00000425,0x00000056,0x00050051,0x00000006,0x00000427,0x00000407,0x00000000, + 0x00050041,0x0000039c,0x00000428,0x000003e0,0x00000061,0x0003003e,0x00000428,0x00000427, + 0x000200f9,0x00000424,0x000200f8,0x00000429,0x00050041,0x0000039c,0x0000042a,0x000003e0, + 0x000000ad,0x0004003d,0x00000006,0x0000042b,0x0000042a,0x0004007f,0x00000006,0x0000042c, + 0x0000042b,0x0003003e,0x0000042a,0x0000042c,0x00050041,0x0000039c,0x0000042f,0x000003e0, + 0x00000061,0x00050051,0x00000006,0x00000430,0x00000407,0x00000000,0x0003003e,0x0000042f, + 0x00000430,0x00050041,0x0000039c,0x00000431,0x000003e0,0x00000078,0x00050051,0x00000006, + 0x00000432,0x00000407,0x00000001,0x0003003e,0x00000431,0x00000432,0x000200f9,0x00000424, + 0x000200f8,0x00000424,0x000200f9,0x0000040e,0x000200f8,0x00000433,0x00050051,0x0000000c, + 0x00000436,0x00000370,0x00000001,0x0004007c,0x00000006,0x00000437,0x00000436,0x00050051, + 0x00000006,0x0000043a,0x00000400,0x00000002,0x00050051,0x00000006,0x0000043c,0x00000407, + 0x00000000,0x00050051,0x00000006,0x0000043e,0x00000407,0x00000001,0x00050083,0x00000006, + 0x00000442,0x00000440,0x0000043a,0x00070050,0x00000012,0x00000443,0x0000043c,0x0000043e, + 0x00000437,0x00000442,0x0003003e,0x000003e0,0x00000443,0x000200f9,0x0000040e,0x000200f8, + 0x0000040e,0x000200f9,0x000003e7,0x000200f8,0x000003e7,0x000200f9,0x000003cb,0x000200f8, + 0x000003cb,0x000300f7,0x00000447,0x00000000,0x000400fa,0x0000089e,0x00000446,0x00000457, + 0x000200f8,0x00000446,0x00050041,0x0000044c,0x0000044d,0x0000038a,0x000000b5,0x0004003d, + 0x00000006,0x0000044e,0x0000044d,0x00050041,0x0000044c,0x00000450,0x0000038a,0x000000bb, + 0x0004003d,0x00000006,0x00000451,0x00000450,0x00050051,0x00000006,0x000007a3,0x0000089f, + 0x00000000,0x00050085,0x00000006,0x000007a5,0x000007a3,0x0000044e,0x00050083,0x00000006, + 0x000007a6,0x000007a5,0x00000055,0x00050051,0x00000006,0x000007a8,0x0000089f,0x00000001, + 0x00050085,0x00000006,0x000007aa,0x000007a8,0x00000451,0x0006000c,0x00000006,0x000007ac, + 0x00000001,0x00000006,0x00000451,0x00050083,0x00000006,0x000007ad,0x000007aa,0x000007ac, + 0x00070050,0x00000012,0x000007ae,0x000007a6,0x000007ad,0x00000056,0x00000055,0x00040070, + 0x00000006,0x000007b2,0x000008bc,0x00050085,0x00000006,0x000007b3,0x000007b2,0x00000085, + 0x00050083,0x00000006,0x000007b4,0x00000055,0x000007b3,0x00060052,0x00000012,0x000007e9, + 0x000007b4,0x000007ae,0x00000002,0x000200f9,0x00000447,0x000200f8,0x00000457,0x00050041, + 0x0000044c,0x00000459,0x0000038a,0x00000458,0x0004003d,0x00000006,0x0000045a,0x00000459, + 0x00070050,0x00000012,0x00000461,0x0000045a,0x0000045a,0x0000045a,0x0000045a,0x000200f9, + 0x00000447,0x000200f8,0x00000447,0x000700f5,0x00000012,0x000008ea,0x000007e9,0x00000446, + 0x00000461,0x00000457,0x00050041,0x000003df,0x00000467,0x00000465,0x000000d3,0x0003003e, + 0x00000467,0x000008ea,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..69e12dead12919d844aa8794eff0c28b1666a7e7 GIT binary patch literal 16016 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.h new file mode 100644 index 000000000..dce722b88 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.h @@ -0,0 +1,162 @@ +#pragma once + +const uint32_t draw_msaa_path_webgpu_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000022b,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000112,0x00000123,0x00000140, + 0x00000145,0x00000147,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00070004, + 0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x000000c9,0x00004444,0x00030005,0x000000cd,0x00006277, + 0x00030005,0x000000ee,0x00004344,0x00030005,0x000000f0,0x00003552,0x00030005,0x00000112, + 0x0000316b,0x00060005,0x00000123,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x00000126,0x0000424d,0x00040006,0x00000126,0x00000000,0x00006250,0x00040006,0x00000126, + 0x00000001,0x00006359,0x00040006,0x00000126,0x00000002,0x00006552,0x00040006,0x00000126, + 0x00000003,0x00006553,0x00040006,0x00000126,0x00000004,0x0000366d,0x00040006,0x00000126, + 0x00000005,0x0000676d,0x00040006,0x00000126,0x00000006,0x00006544,0x00040006,0x00000126, + 0x00000007,0x00006545,0x00040006,0x00000126,0x00000008,0x00003755,0x00040006,0x00000126, + 0x00000009,0x0000676a,0x00040006,0x00000126,0x0000000a,0x0000635a,0x00040006,0x00000126, + 0x0000000b,0x00003157,0x00040006,0x00000126,0x0000000c,0x0000676e,0x00040006,0x00000126, + 0x0000000d,0x00003559,0x00040006,0x00000126,0x0000000e,0x0000324f,0x00040006,0x00000126, + 0x0000000f,0x00006461,0x00040006,0x00000126,0x00000010,0x00006579,0x00040006,0x00000126, + 0x00000011,0x00003376,0x00040006,0x00000126,0x00000012,0x00003377,0x00040006,0x00000126, + 0x00000013,0x00006462,0x00040006,0x00000126,0x00000014,0x00006767,0x00030005,0x00000128, + 0x0000006b,0x00030005,0x00000140,0x00006771,0x00030005,0x00000142,0x00003954,0x00030005, + 0x00000143,0x00004351,0x00030005,0x00000145,0x00003153,0x00030005,0x00000147,0x00003159, + 0x00030047,0x000000c9,0x00000000,0x00040047,0x000000c9,0x00000021,0x00000009,0x00040047, + 0x000000c9,0x00000022,0x00000000,0x00030047,0x000000cd,0x00000000,0x00040047,0x000000cd, + 0x00000021,0x00000009,0x00040047,0x000000cd,0x00000022,0x00000003,0x00030047,0x000000ee, + 0x00000000,0x00040047,0x000000ee,0x00000021,0x0000000c,0x00040047,0x000000ee,0x00000022, + 0x00000001,0x00030047,0x000000f0,0x00000000,0x00040047,0x000000f0,0x00000021,0x0000000e, + 0x00040047,0x000000f0,0x00000022,0x00000001,0x00040047,0x00000112,0x0000001e,0x00000000, + 0x00030047,0x00000119,0x00000000,0x00030047,0x0000011b,0x00000000,0x00030047,0x0000011c, + 0x00000000,0x00040047,0x00000123,0x0000000b,0x0000000f,0x00030047,0x00000126,0x00000002, + 0x00050048,0x00000126,0x00000000,0x00000023,0x00000000,0x00050048,0x00000126,0x00000001, + 0x00000023,0x00000004,0x00050048,0x00000126,0x00000002,0x00000023,0x00000008,0x00050048, + 0x00000126,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000126,0x00000004,0x00000023, + 0x00000010,0x00050048,0x00000126,0x00000005,0x00000023,0x00000014,0x00050048,0x00000126, + 0x00000006,0x00000023,0x00000018,0x00050048,0x00000126,0x00000007,0x00000023,0x0000001c, + 0x00050048,0x00000126,0x00000008,0x00000023,0x00000020,0x00050048,0x00000126,0x00000009, + 0x00000023,0x00000030,0x00050048,0x00000126,0x0000000a,0x00000023,0x00000038,0x00050048, + 0x00000126,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000126,0x0000000c,0x00000023, + 0x00000044,0x00050048,0x00000126,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000126, + 0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000126,0x0000000f,0x00000023,0x00000050, + 0x00050048,0x00000126,0x00000010,0x00000023,0x00000054,0x00050048,0x00000126,0x00000011, + 0x00000023,0x00000058,0x00050048,0x00000126,0x00000012,0x00000023,0x0000005c,0x00050048, + 0x00000126,0x00000013,0x00000023,0x00000060,0x00050048,0x00000126,0x00000014,0x00000023, + 0x00000064,0x00040047,0x00000128,0x00000021,0x00000000,0x00040047,0x00000128,0x00000022, + 0x00000000,0x00030047,0x0000012d,0x00000000,0x00030047,0x00000140,0x00000000,0x00040047, + 0x00000140,0x0000001e,0x00000000,0x00030047,0x00000142,0x00000000,0x00040047,0x00000142, + 0x00000021,0x0000000a,0x00040047,0x00000142,0x00000022,0x00000003,0x00030047,0x00000143, + 0x00000000,0x00040047,0x00000143,0x00000021,0x0000000a,0x00040047,0x00000143,0x00000022, + 0x00000000,0x00030047,0x00000145,0x00000000,0x00030047,0x00000145,0x0000000e,0x00040047, + 0x00000145,0x0000001e,0x00000004,0x00030047,0x00000147,0x00000000,0x00030047,0x00000147, + 0x0000000e,0x00040047,0x00000147,0x0000001e,0x00000006,0x00030047,0x00000163,0x00000000, + 0x00030047,0x00000164,0x00000000,0x00030047,0x00000169,0x00000000,0x00030047,0x00000174, + 0x00000000,0x00030047,0x00000199,0x00000000,0x00030047,0x0000019a,0x00000000,0x00030047, + 0x0000019f,0x00000000,0x00030047,0x000001a2,0x00000000,0x00030047,0x000001ad,0x00000000, + 0x00030047,0x000001b7,0x00000000,0x00030047,0x000001b9,0x00000000,0x00030047,0x000001bf, + 0x00000000,0x00030047,0x000001c2,0x00000000,0x00030047,0x000001e1,0x00000000,0x00030047, + 0x000001e2,0x00000000,0x00030047,0x000001f2,0x00000000,0x00030047,0x000001f3,0x00000000, + 0x00030047,0x000001f6,0x00000000,0x00030047,0x000001f8,0x00000000,0x00030047,0x0000020e, + 0x00000000,0x00030047,0x00000211,0x00000000,0x00030047,0x00000214,0x00000000,0x00030047, + 0x00000216,0x00000000,0x00030047,0x00000218,0x00000000,0x00030047,0x0000021c,0x00000000, + 0x00030047,0x0000021e,0x00000000,0x00030047,0x00000220,0x00000000,0x00030047,0x00000221, + 0x00000000,0x00030047,0x00000228,0x00000000,0x00030047,0x00000227,0x00000000,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000004,0x00040017,0x0000000d,0x00000006,0x00000003,0x00040017, + 0x00000019,0x00000006,0x00000002,0x00040015,0x00000034,0x00000020,0x00000000,0x0004002b, + 0x00000006,0x00000048,0x00000000,0x00020014,0x00000049,0x0004002b,0x00000006,0x0000004e, + 0x3f800000,0x0004002b,0x00000006,0x00000058,0x3d897143,0x0004002b,0x00000006,0x0000005c, + 0x3bbf4590,0x0004002b,0x00000006,0x00000063,0x4253ee82,0x0004002b,0x00000006,0x00000099, + 0xbf800000,0x0004002b,0x00000006,0x000000b7,0x3f7f8000,0x0004002b,0x00000006,0x000000ba, + 0x3a800000,0x0004002b,0x00000006,0x000000bd,0x3b000000,0x00090019,0x000000c7,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x000000c8, + 0x00000000,0x000000c7,0x0004003b,0x000000c8,0x000000c9,0x00000000,0x0002001a,0x000000cb, + 0x00040020,0x000000cc,0x00000000,0x000000cb,0x0004003b,0x000000cc,0x000000cd,0x00000000, + 0x0003001b,0x000000cf,0x000000c7,0x0004003b,0x000000c8,0x000000ee,0x00000000,0x0004003b, + 0x000000cc,0x000000f0,0x00000000,0x00040020,0x00000111,0x00000001,0x00000007,0x0004003b, + 0x00000111,0x00000112,0x00000001,0x0004003b,0x00000111,0x00000123,0x00000001,0x00040015, + 0x00000124,0x00000020,0x00000001,0x00040017,0x00000125,0x00000124,0x00000004,0x0017001e, + 0x00000126,0x00000006,0x00000006,0x00000006,0x00000006,0x00000034,0x00000034,0x00000034, + 0x00000034,0x00000125,0x00000019,0x00000019,0x00000034,0x00000006,0x00000034,0x00000006, + 0x00000006,0x00000034,0x00000006,0x00000006,0x00000006,0x00000034,0x00040020,0x00000127, + 0x00000002,0x00000126,0x0004003b,0x00000127,0x00000128,0x00000002,0x0004002b,0x00000124, + 0x00000129,0x00000011,0x0004002b,0x00000124,0x0000012a,0x00000012,0x00040020,0x00000132, + 0x00000002,0x00000006,0x00040020,0x0000013f,0x00000003,0x00000007,0x0004003b,0x0000013f, + 0x00000140,0x00000003,0x0004003b,0x000000cc,0x00000142,0x00000000,0x0004003b,0x000000c8, + 0x00000143,0x00000000,0x00040020,0x00000144,0x00000001,0x00000019,0x0004003b,0x00000144, + 0x00000145,0x00000001,0x00040020,0x00000146,0x00000001,0x00000006,0x0004003b,0x00000146, + 0x00000147,0x00000001,0x0004002b,0x00000006,0x00000229,0xc0000000,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000007,0x00000114, + 0x00000112,0x00050051,0x00000006,0x00000158,0x00000114,0x00000003,0x000500be,0x00000049, + 0x00000159,0x00000158,0x00000048,0x000300f7,0x000001b1,0x00000000,0x000400fa,0x00000159, + 0x000001a7,0x0000015a,0x000200f8,0x0000015a,0x000500ba,0x00000049,0x0000015d,0x00000158, + 0x00000099,0x000300f7,0x000001a6,0x00000000,0x000400fa,0x0000015d,0x00000177,0x0000015e, + 0x000200f8,0x0000015e,0x00050083,0x00000006,0x00000162,0x00000229,0x00000158,0x0004003d, + 0x000000c7,0x00000163,0x000000ee,0x0004003d,0x000000cb,0x00000164,0x000000f0,0x00050056, + 0x000000cf,0x00000165,0x00000163,0x00000164,0x0007004f,0x00000019,0x00000167,0x00000114, + 0x00000114,0x00000000,0x00000001,0x00070058,0x00000007,0x00000169,0x00000165,0x00000167, + 0x00000002,0x00000162,0x00050051,0x00000006,0x0000016b,0x00000114,0x00000002,0x0008004f, + 0x0000000d,0x000001b7,0x00000169,0x00000169,0x00000000,0x00000001,0x00000002,0x00050051, + 0x00000006,0x000001b9,0x00000169,0x00000003,0x000500b7,0x00000049,0x000001ba,0x000001b9, + 0x00000048,0x000300f7,0x000001c0,0x00000000,0x000400fa,0x000001ba,0x000001bc,0x000001bb, + 0x000200f8,0x000001bb,0x000200f9,0x000001c0,0x000200f8,0x000001bc,0x00050088,0x00000006, + 0x000001bf,0x0000004e,0x000001b9,0x000200f9,0x000001c0,0x000200f8,0x000001c0,0x000700f5, + 0x00000006,0x00000221,0x00000048,0x000001bb,0x000001bf,0x000001bc,0x0005008e,0x0000000d, + 0x000001c2,0x000001b7,0x00000221,0x00050085,0x00000006,0x00000174,0x000001b9,0x0000016b, + 0x00050051,0x00000006,0x000001c8,0x000001c2,0x00000000,0x00050051,0x00000006,0x000001ca, + 0x000001c2,0x00000001,0x00050051,0x00000006,0x000001cc,0x000001c2,0x00000002,0x00070050, + 0x00000007,0x0000022a,0x000001c8,0x000001ca,0x000001cc,0x00000174,0x000200f9,0x000001a6, + 0x000200f8,0x00000177,0x00050051,0x00000006,0x00000179,0x00000114,0x00000002,0x000500ba, + 0x00000049,0x0000017a,0x00000179,0x00000048,0x000300f7,0x00000182,0x00000000,0x000400fa, + 0x0000017a,0x0000017f,0x0000017b,0x000200f8,0x0000017b,0x0007004f,0x00000019,0x0000017d, + 0x00000114,0x00000114,0x00000000,0x00000001,0x0006000c,0x00000006,0x0000017e,0x00000001, + 0x00000042,0x0000017d,0x000200f9,0x00000182,0x000200f8,0x0000017f,0x00050051,0x00000006, + 0x00000181,0x00000114,0x00000000,0x000200f9,0x00000182,0x000200f8,0x00000182,0x000700f5, + 0x00000006,0x00000225,0x0000017e,0x0000017b,0x00000181,0x0000017f,0x0008000c,0x00000006, + 0x00000185,0x00000001,0x0000002b,0x00000225,0x00000048,0x0000004e,0x0006000c,0x00000006, + 0x00000188,0x00000001,0x00000004,0x00000179,0x000500ba,0x00000049,0x0000018a,0x00000188, + 0x0000004e,0x000300f7,0x00000194,0x00000000,0x000400fa,0x0000018a,0x00000190,0x0000018b, + 0x000200f8,0x0000018b,0x00050085,0x00000006,0x0000018d,0x000000bd,0x00000185,0x00050081, + 0x00000006,0x0000018f,0x0000018d,0x00000188,0x000200f9,0x00000194,0x000200f8,0x00000190, + 0x00050085,0x00000006,0x00000192,0x000000b7,0x00000185,0x00050081,0x00000006,0x00000193, + 0x00000192,0x000000ba,0x000200f9,0x00000194,0x000200f8,0x00000194,0x000700f5,0x00000006, + 0x00000226,0x0000018f,0x0000018b,0x00000193,0x00000190,0x0004007f,0x00000006,0x00000198, + 0x00000158,0x0004003d,0x000000c7,0x00000199,0x000000c9,0x0004003d,0x000000cb,0x0000019a, + 0x000000cd,0x00050056,0x000000cf,0x0000019b,0x00000199,0x0000019a,0x00050050,0x00000019, + 0x0000019e,0x00000226,0x00000198,0x00070058,0x00000007,0x0000019f,0x0000019b,0x0000019e, + 0x00000002,0x00000048,0x00050051,0x00000006,0x000001a2,0x0000019f,0x00000003,0x00060052, + 0x00000007,0x0000020e,0x000001a2,0x0000019f,0x00000003,0x000200f9,0x000001a6,0x000200f8, + 0x000001a6,0x000700f5,0x00000007,0x00000228,0x0000022a,0x000001c0,0x0000020e,0x00000194, + 0x000200f9,0x000001b1,0x000200f8,0x000001a7,0x00050051,0x00000006,0x000001ad,0x00000114, + 0x00000003,0x00060052,0x00000007,0x00000211,0x000001ad,0x00000114,0x00000003,0x000200f9, + 0x000001b1,0x000200f8,0x000001b1,0x000700f5,0x00000007,0x00000227,0x00000228,0x000001a6, + 0x00000211,0x000001a7,0x00050051,0x00000006,0x00000119,0x00000227,0x00000003,0x0008004f, + 0x0000000d,0x0000011b,0x00000227,0x00000227,0x00000000,0x00000001,0x00000002,0x0005008e, + 0x0000000d,0x0000011c,0x0000011b,0x00000119,0x00050051,0x00000006,0x0000011e,0x0000011c, + 0x00000000,0x00060052,0x00000007,0x00000214,0x0000011e,0x00000227,0x00000000,0x00050051, + 0x00000006,0x00000120,0x0000011c,0x00000001,0x00060052,0x00000007,0x00000216,0x00000120, + 0x00000214,0x00000001,0x00050051,0x00000006,0x00000122,0x0000011c,0x00000002,0x00060052, + 0x00000007,0x00000218,0x00000122,0x00000216,0x00000002,0x0008004f,0x0000000d,0x0000012d, + 0x00000218,0x00000218,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,0x0000012f, + 0x00000123,0x00050041,0x00000132,0x00000133,0x00000128,0x00000129,0x0004003d,0x00000006, + 0x00000134,0x00000133,0x00050041,0x00000132,0x00000136,0x00000128,0x0000012a,0x0004003d, + 0x00000006,0x00000137,0x00000136,0x00050051,0x00000006,0x000001ea,0x0000012f,0x00000000, + 0x00050085,0x00000006,0x000001eb,0x00000058,0x000001ea,0x00050051,0x00000006,0x000001ed, + 0x0000012f,0x00000001,0x00050085,0x00000006,0x000001ee,0x0000005c,0x000001ed,0x00050081, + 0x00000006,0x000001ef,0x000001eb,0x000001ee,0x0006000c,0x00000006,0x000001f0,0x00000001, + 0x0000000a,0x000001ef,0x00050085,0x00000006,0x000001f2,0x00000063,0x000001f0,0x0006000c, + 0x00000006,0x000001f3,0x00000001,0x0000000a,0x000001f2,0x00050085,0x00000006,0x000001f6, + 0x000001f3,0x00000134,0x00050081,0x00000006,0x000001f8,0x000001f6,0x00000137,0x00060050, + 0x0000000d,0x000001e1,0x000001f8,0x000001f8,0x000001f8,0x00050081,0x0000000d,0x000001e2, + 0x000001e1,0x0000012d,0x00050051,0x00000006,0x0000013a,0x000001e2,0x00000000,0x00060052, + 0x00000007,0x0000021c,0x0000013a,0x00000218,0x00000000,0x00050051,0x00000006,0x0000013c, + 0x000001e2,0x00000001,0x00060052,0x00000007,0x0000021e,0x0000013c,0x0000021c,0x00000001, + 0x00050051,0x00000006,0x0000013e,0x000001e2,0x00000002,0x00060052,0x00000007,0x00000220, + 0x0000013e,0x0000021e,0x00000002,0x0003003e,0x00000140,0x00000220,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..b4fbbbb648242b2768f2c9ce1d06eb304bf2964d GIT binary patch literal 5056 zcmZ9P+iz4=6vmI8;UXYVs7Qr0Q!1B2K;$k6lwK$%)s_~uCF(ex8R|f3VP*=VQ7(oA zH7Zdb1QSVk&?g^!BH{(Yi=Y_)26@z22}VT|6Tjb?y*exI%+C4Nx4yNnYwvR=QPVUf zitdS~M^mE}HBnq@qZ%=hxXJOev#YObRjHg?wQl`t1T&*VtV1&^nieJXq#n!^MsUoL zqe-`L$GZB3V6%;fULbg4XA%naqzgJb*l$s8Tr zpU;-1n~tude^0uUIe2I|UmVVtO6hX`rSe!YpWZh%k}VfTM@nke+U)G^?(FJFXAd1x zo5zOp>EXgiKAkHR)n4I99^F*h47$Qdc6co31xbxo{_c*x&}aHcrdY@fs^@5uqWzpF zX-+rPcYAvzUn2TJ_~>8-kHfcB@NMDV^%cxI9e4yhIbN@!;q*>Ty=`=~n3F7SXNfdV zv_?`SBQT{$?V1fWkgeLRYp>>Jes-$Q+3}b+RQ;3WKR8siC(CYkdiJZs*;8ddwXv$d zSN47vKTY;tH=gOTpV1s`JTqjEIQ@OH2ecmMpDDY0P1T+yJEPSw|7_XE+<0nbA6Z-V z&yju9*>hzNy7)TTL+YPBTE_az29v9Y1K%pV=g|t^CcHcB9l6{W?^hzu=>g%+u-lf&Eylj$9F^+IJa?Utn;K(E6m@gc2GmaQI z_S-me6^=bLj(mli@3<*}Tj)6YLzi+Kdjz-IapW)DCdV;vxE9ATR=9S@k;`zq9LFBO zbvceTgzIq}^Mu>uIC2}V-*MzO+_R1&$KhUZ9BTxp)Q@w3TyGSnkQ3PC1cm)vDcdk- zp@Ng~x$wEd*)SitQ3h*9o7l9Oi0wqg*`eSAdo8x_pR-lbCgOL7EO|k5BRc9mvgw_aM|H=4xe}Ug2NXb{>_JNP0qq)R5u5$P z=8RyY$F2`HvG>bfr)Nr)vO+dm&J(3hJv^?b@lVF=iS1@{PTCH?vDIwO$k~o7Tg=YN zJ~iIgYWBHG{1vk=VV^iY(ca~Xf3x|&j_qhmy>9n!g&AAej*7?GDUJPlV9{;~_KmxuYo9><{-4h4^-1Oy+?foBIb2|IUEv4?i~dj(!t4 z+01~V=;{W&7lEuJg>l^#!#ixNSjJeVK=x+0Sla9thC};}IC6bJHautGFL^!}ru?He z@O`SfSCzJTUJh~32@^+-6ZeTQg*bdiRi9TSj_2!P41>bVfmp^#-f@?bbJ*l)PBuCB zv|`B3ylgb^-I^KeHzdqls1zRk@-c7jU}Dg)M)YZGa6p(C_-=hAa9?o05@UC_VC=UT z?p%DV+odr7%d+8Z-L48#m_NR+RKHYZ{yhKI6Ad=LGhscr!?|Z@%WKg7q1mu++>`V} zJLrjjNAZmPnlR%>b2_wHmQ8!i)#h+r7%j!P?*a#H9RHcnu|7RvJ(tTM9zA~AXRPcw z^I@+o{+O_>ujR_i;^1wqP6<<3D}2XQUs0tkp0>xY3ey&q!efS3gf)3h26n3|I>tl0 zv_X3|o|D2B?=@&`eHUwfv`63QiJzg|pr6yi`sw^d5jy6;e%UzA1V87HIoh1x6vl^^ z^YMW&g*oFptNNBIm`16!z!zoNV4Nc23XB<~?HP^ds45;CnQ7&gsX(^bxle^67#& zwD{zT*VOjwqB#7VwO);a^UQaM=b4M;9#7_ij&BHZm9s+(^F+&?#(Hs=SwDPV)v5Y^ z_{QgC_>ww2OjP^n{l0Hh5y-ZQLux;j`~L+QDz{mxo30uHT`(=3Ti~b(w0j zDjITVUEoc#A!wF6%|>B(8{^Nyv`w-6{zW$5U-(S-YtSJz-M9?C%kbIx`AwL3e0FYc z3+osEx4>`lcZ9Rz@tc-!W&L6;e$(>ZjE^~5Uw4J!nNyEefIFJ+ad@j};ctn<$2!}b zHVea3Y%lqihPQn%?PEcU+_Zda!xIB<+HFD0{+Tu<1D+W8ZOYmf+3^1=dXwsZm$a{R literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.h new file mode 100644 index 000000000..04915df19 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.h @@ -0,0 +1,500 @@ +#pragma once + +const uint32_t draw_msaa_path_webgpu_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000c02,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000a000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000034f,0x00000357,0x0000035e, + 0x00000399,0x0000039e,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00070004, + 0x4f5f4c47,0x735f5345,0x6c706d61,0x61765f65,0x62616972,0x0073656c,0x00040005,0x00000004, + 0x6e69616d,0x00000000,0x00030005,0x00000307,0x00004444,0x00030005,0x0000030b,0x00006277, + 0x00030005,0x0000032b,0x00004344,0x00030005,0x0000032d,0x00003552,0x00030005,0x0000034f, + 0x0000316b,0x00030005,0x00000357,0x00003159,0x00030005,0x0000035c,0x0000444a,0x00060005, + 0x0000035e,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005,0x0000037f,0x0000424d, + 0x00040006,0x0000037f,0x00000000,0x00006250,0x00040006,0x0000037f,0x00000001,0x00006359, + 0x00040006,0x0000037f,0x00000002,0x00006552,0x00040006,0x0000037f,0x00000003,0x00006553, + 0x00040006,0x0000037f,0x00000004,0x0000366d,0x00040006,0x0000037f,0x00000005,0x0000676d, + 0x00040006,0x0000037f,0x00000006,0x00006544,0x00040006,0x0000037f,0x00000007,0x00006545, + 0x00040006,0x0000037f,0x00000008,0x00003755,0x00040006,0x0000037f,0x00000009,0x0000676a, + 0x00040006,0x0000037f,0x0000000a,0x0000635a,0x00040006,0x0000037f,0x0000000b,0x00003157, + 0x00040006,0x0000037f,0x0000000c,0x0000676e,0x00040006,0x0000037f,0x0000000d,0x00003559, + 0x00040006,0x0000037f,0x0000000e,0x0000324f,0x00040006,0x0000037f,0x0000000f,0x00006461, + 0x00040006,0x0000037f,0x00000010,0x00006579,0x00040006,0x0000037f,0x00000011,0x00003376, + 0x00040006,0x0000037f,0x00000012,0x00003377,0x00040006,0x0000037f,0x00000013,0x00006462, + 0x00040006,0x0000037f,0x00000014,0x00006767,0x00030005,0x00000381,0x0000006b,0x00030005, + 0x00000399,0x00006771,0x00030005,0x0000039b,0x00003954,0x00030005,0x0000039c,0x00004351, + 0x00030005,0x0000039e,0x00003153,0x00030047,0x00000307,0x00000000,0x00040047,0x00000307, + 0x00000021,0x00000009,0x00040047,0x00000307,0x00000022,0x00000000,0x00030047,0x0000030b, + 0x00000000,0x00040047,0x0000030b,0x00000021,0x00000009,0x00040047,0x0000030b,0x00000022, + 0x00000003,0x00030047,0x0000032b,0x00000000,0x00040047,0x0000032b,0x00000021,0x0000000c, + 0x00040047,0x0000032b,0x00000022,0x00000001,0x00030047,0x0000032d,0x00000000,0x00040047, + 0x0000032d,0x00000021,0x0000000e,0x00040047,0x0000032d,0x00000022,0x00000001,0x00040047, + 0x0000034f,0x0000001e,0x00000000,0x00030047,0x00000357,0x00000000,0x00030047,0x00000357, + 0x0000000e,0x00040047,0x00000357,0x0000001e,0x00000006,0x00030047,0x00000359,0x00000000, + 0x00030047,0x0000035c,0x00000000,0x00040047,0x0000035c,0x00000021,0x0000000d,0x00040047, + 0x0000035c,0x00000022,0x00000000,0x00030047,0x0000035d,0x00000000,0x00030047,0x0000035e, + 0x00000000,0x00040047,0x0000035e,0x0000000b,0x0000000f,0x00030047,0x0000035f,0x00000000, + 0x00030047,0x00000360,0x00000000,0x00030047,0x00000361,0x00000000,0x00030047,0x00000363, + 0x00000000,0x00030047,0x00000364,0x00000000,0x00030047,0x00000367,0x00000000,0x00030047, + 0x00000374,0x00000000,0x00030047,0x00000376,0x00000000,0x00030047,0x00000377,0x00000000, + 0x00030047,0x0000037f,0x00000002,0x00050048,0x0000037f,0x00000000,0x00000023,0x00000000, + 0x00050048,0x0000037f,0x00000001,0x00000023,0x00000004,0x00050048,0x0000037f,0x00000002, + 0x00000023,0x00000008,0x00050048,0x0000037f,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x0000037f,0x00000004,0x00000023,0x00000010,0x00050048,0x0000037f,0x00000005,0x00000023, + 0x00000014,0x00050048,0x0000037f,0x00000006,0x00000023,0x00000018,0x00050048,0x0000037f, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x0000037f,0x00000008,0x00000023,0x00000020, + 0x00050048,0x0000037f,0x00000009,0x00000023,0x00000030,0x00050048,0x0000037f,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x0000037f,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x0000037f,0x0000000c,0x00000023,0x00000044,0x00050048,0x0000037f,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x0000037f,0x0000000e,0x00000023,0x0000004c,0x00050048,0x0000037f, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x0000037f,0x00000010,0x00000023,0x00000054, + 0x00050048,0x0000037f,0x00000011,0x00000023,0x00000058,0x00050048,0x0000037f,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x0000037f,0x00000013,0x00000023,0x00000060,0x00050048, + 0x0000037f,0x00000014,0x00000023,0x00000064,0x00040047,0x00000381,0x00000021,0x00000000, + 0x00040047,0x00000381,0x00000022,0x00000000,0x00030047,0x00000386,0x00000000,0x00030047, + 0x00000399,0x00000000,0x00040047,0x00000399,0x0000001e,0x00000000,0x00030047,0x0000039b, + 0x00000000,0x00040047,0x0000039b,0x00000021,0x0000000a,0x00040047,0x0000039b,0x00000022, + 0x00000003,0x00030047,0x0000039c,0x00000000,0x00040047,0x0000039c,0x00000021,0x0000000a, + 0x00040047,0x0000039c,0x00000022,0x00000000,0x00030047,0x0000039e,0x00000000,0x00030047, + 0x0000039e,0x0000000e,0x00040047,0x0000039e,0x0000001e,0x00000004,0x00030047,0x000003ba, + 0x00000000,0x00030047,0x000003bb,0x00000000,0x00030047,0x000003c0,0x00000000,0x00030047, + 0x000003cb,0x00000000,0x00030047,0x000003f0,0x00000000,0x00030047,0x000003f1,0x00000000, + 0x00030047,0x000003f6,0x00000000,0x00030047,0x000003f9,0x00000000,0x00030047,0x00000404, + 0x00000000,0x00030047,0x0000040e,0x00000000,0x00030047,0x00000410,0x00000000,0x00030047, + 0x00000416,0x00000000,0x00030047,0x00000419,0x00000000,0x00030047,0x0000042f,0x00000000, + 0x00030047,0x00000431,0x00000000,0x00030047,0x00000440,0x00000000,0x00030047,0x00000441, + 0x00000000,0x00030047,0x00000443,0x00000000,0x00030047,0x0000046e,0x00000000,0x00030047, + 0x00000471,0x00000000,0x00030047,0x00000478,0x00000000,0x00030047,0x0000047b,0x00000000, + 0x00030047,0x00000482,0x00000000,0x00030047,0x00000485,0x00000000,0x00030047,0x0000048d, + 0x00000000,0x00030047,0x00000490,0x00000000,0x00030047,0x00000497,0x00000000,0x00030047, + 0x00000499,0x00000000,0x00030047,0x0000049b,0x00000000,0x00030047,0x0000049d,0x00000000, + 0x00030047,0x0000049e,0x00000000,0x00030047,0x000004a1,0x00000000,0x00030047,0x000004a2, + 0x00000000,0x00030047,0x000004a3,0x00000000,0x00030047,0x000004ac,0x00000000,0x00030047, + 0x000004b1,0x00000000,0x00030047,0x000004b7,0x00000000,0x00030047,0x000004b8,0x00000000, + 0x00030047,0x000004b9,0x00000000,0x00030047,0x000004bf,0x00000000,0x00030047,0x000004c0, + 0x00000000,0x00030047,0x000004c1,0x00000000,0x00030047,0x000004c4,0x00000000,0x00030047, + 0x000004c5,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004cd,0x00000000, + 0x00030047,0x000004ce,0x00000000,0x00030047,0x000004d7,0x00000000,0x00030047,0x000004d8, + 0x00000000,0x00030047,0x000004da,0x00000000,0x00030047,0x000004db,0x00000000,0x00030047, + 0x000004dc,0x00000000,0x00030047,0x000004dd,0x00000000,0x00030047,0x000004de,0x00000000, + 0x00030047,0x000004e0,0x00000000,0x00030047,0x000004e2,0x00000000,0x00030047,0x000004e6, + 0x00000000,0x00030047,0x000004e8,0x00000000,0x00030047,0x000004ea,0x00000000,0x00030047, + 0x000004ed,0x00000000,0x00030047,0x000004ee,0x00000000,0x00030047,0x000004ef,0x00000000, + 0x00030047,0x000004f1,0x00000000,0x00030047,0x000004f4,0x00000000,0x00030047,0x000004f9, + 0x00000000,0x00030047,0x000004fa,0x00000000,0x00030047,0x00000508,0x00000000,0x00030047, + 0x0000050a,0x00000000,0x00030047,0x0000050b,0x00000000,0x00030047,0x0000050c,0x00000000, + 0x00030047,0x0000050f,0x00000000,0x00030047,0x00000512,0x00000000,0x00030047,0x00000513, + 0x00000000,0x00030047,0x00000514,0x00000000,0x00030047,0x00000516,0x00000000,0x00030047, + 0x00000519,0x00000000,0x00030047,0x0000051a,0x00000000,0x00030047,0x0000051c,0x00000000, + 0x00030047,0x00000522,0x00000000,0x00030047,0x00000523,0x00000000,0x00030047,0x0000052a, + 0x00000000,0x00030047,0x0000052c,0x00000000,0x00030047,0x0000052f,0x00000000,0x00030047, + 0x00000532,0x00000000,0x00030047,0x00000535,0x00000000,0x00030047,0x00000537,0x00000000, + 0x00030047,0x00000538,0x00000000,0x00030047,0x0000053b,0x00000000,0x00030047,0x0000053e, + 0x00000000,0x00030047,0x0000053f,0x00000000,0x00030047,0x00000541,0x00000000,0x00030047, + 0x00000543,0x00000000,0x00030047,0x00000545,0x00000000,0x00030047,0x00000547,0x00000000, + 0x00030047,0x00000549,0x00000000,0x00030047,0x0000054b,0x00000000,0x00030047,0x0000054f, + 0x00000000,0x00030047,0x00000551,0x00000000,0x00030047,0x00000553,0x00000000,0x00030047, + 0x00000556,0x00000000,0x00030047,0x00000557,0x00000000,0x00030047,0x00000558,0x00000000, + 0x00030047,0x0000055a,0x00000000,0x00030047,0x0000055c,0x00000000,0x00030047,0x0000055f, + 0x00000000,0x00030047,0x00000560,0x00000000,0x00030047,0x00000562,0x00000000,0x00030047, + 0x00000564,0x00000000,0x00030047,0x00000566,0x00000000,0x00030047,0x0000056b,0x00000000, + 0x00030047,0x0000056d,0x00000000,0x00030047,0x00000573,0x00000000,0x00030047,0x00000576, + 0x00000000,0x00030047,0x000005a0,0x00000000,0x00030047,0x000005a1,0x00000000,0x00030047, + 0x000005a3,0x00000000,0x00030047,0x000005a9,0x00000000,0x00030047,0x000005ad,0x00000000, + 0x00030047,0x000005ae,0x00000000,0x00030047,0x000005b1,0x00000000,0x00030047,0x000005b3, + 0x00000000,0x00030047,0x000005b4,0x00000000,0x00030047,0x000005b5,0x00000000,0x00030047, + 0x000005b8,0x00000000,0x00030047,0x000005ba,0x00000000,0x00030047,0x000005bb,0x00000000, + 0x00030047,0x000005c3,0x00000000,0x00030047,0x000005d5,0x00000000,0x00030047,0x000005f7, + 0x00000000,0x00030047,0x000005f8,0x00000000,0x00030047,0x000005fc,0x00000000,0x00030047, + 0x000005fe,0x00000000,0x00030047,0x000005ff,0x00000000,0x00030047,0x00000608,0x00000000, + 0x00030047,0x0000060f,0x00000000,0x00030047,0x00000644,0x00000000,0x00030047,0x00000645, + 0x00000000,0x00030047,0x00000647,0x00000000,0x00030047,0x0000064d,0x00000000,0x00030047, + 0x00000651,0x00000000,0x00030047,0x00000652,0x00000000,0x00030047,0x00000655,0x00000000, + 0x00030047,0x00000657,0x00000000,0x00030047,0x00000658,0x00000000,0x00030047,0x00000659, + 0x00000000,0x00030047,0x0000065c,0x00000000,0x00030047,0x0000065e,0x00000000,0x00030047, + 0x0000065f,0x00000000,0x00030047,0x00000667,0x00000000,0x00030047,0x00000679,0x00000000, + 0x00030047,0x0000069b,0x00000000,0x00030047,0x0000069c,0x00000000,0x00030047,0x000006a0, + 0x00000000,0x00030047,0x000006a2,0x00000000,0x00030047,0x000006a3,0x00000000,0x00030047, + 0x000006ac,0x00000000,0x00030047,0x000006b3,0x00000000,0x00030047,0x000006e2,0x00000000, + 0x00030047,0x000006e6,0x00000000,0x00030047,0x000006e7,0x00000000,0x00030047,0x000006fa, + 0x00000000,0x00030047,0x000006fb,0x00000000,0x00030047,0x000006ff,0x00000000,0x00030047, + 0x00000701,0x00000000,0x00030047,0x00000702,0x00000000,0x00030047,0x0000070b,0x00000000, + 0x00030047,0x00000712,0x00000000,0x00030047,0x0000071a,0x00000000,0x00030047,0x0000071b, + 0x00000000,0x00030047,0x0000071f,0x00000000,0x00030047,0x00000721,0x00000000,0x00030047, + 0x00000722,0x00000000,0x00030047,0x0000072a,0x00000000,0x00030047,0x0000072b,0x00000000, + 0x00030047,0x0000072f,0x00000000,0x00030047,0x00000731,0x00000000,0x00030047,0x00000732, + 0x00000000,0x00030047,0x00000748,0x00000000,0x00030047,0x00000749,0x00000000,0x00030047, + 0x0000074b,0x00000000,0x00030047,0x00000751,0x00000000,0x00030047,0x00000755,0x00000000, + 0x00030047,0x00000756,0x00000000,0x00030047,0x00000759,0x00000000,0x00030047,0x0000075b, + 0x00000000,0x00030047,0x0000075c,0x00000000,0x00030047,0x0000075d,0x00000000,0x00030047, + 0x00000760,0x00000000,0x00030047,0x00000762,0x00000000,0x00030047,0x00000763,0x00000000, + 0x00030047,0x0000076b,0x00000000,0x00030047,0x0000077d,0x00000000,0x00030047,0x0000079f, + 0x00000000,0x00030047,0x000007a0,0x00000000,0x00030047,0x000007a4,0x00000000,0x00030047, + 0x000007a6,0x00000000,0x00030047,0x000007a7,0x00000000,0x00030047,0x000007b0,0x00000000, + 0x00030047,0x000007b7,0x00000000,0x00030047,0x000007e6,0x00000000,0x00030047,0x000007ea, + 0x00000000,0x00030047,0x000007eb,0x00000000,0x00030047,0x000007fe,0x00000000,0x00030047, + 0x000007ff,0x00000000,0x00030047,0x00000803,0x00000000,0x00030047,0x00000805,0x00000000, + 0x00030047,0x00000806,0x00000000,0x00030047,0x0000080f,0x00000000,0x00030047,0x00000816, + 0x00000000,0x00030047,0x0000081e,0x00000000,0x00030047,0x0000081f,0x00000000,0x00030047, + 0x00000823,0x00000000,0x00030047,0x00000825,0x00000000,0x00030047,0x00000826,0x00000000, + 0x00030047,0x0000082e,0x00000000,0x00030047,0x0000082f,0x00000000,0x00030047,0x00000833, + 0x00000000,0x00030047,0x00000835,0x00000000,0x00030047,0x00000836,0x00000000,0x00030047, + 0x0000084c,0x00000000,0x00030047,0x0000084d,0x00000000,0x00030047,0x0000084f,0x00000000, + 0x00030047,0x00000855,0x00000000,0x00030047,0x00000859,0x00000000,0x00030047,0x0000085a, + 0x00000000,0x00030047,0x0000085d,0x00000000,0x00030047,0x0000085f,0x00000000,0x00030047, + 0x00000860,0x00000000,0x00030047,0x00000861,0x00000000,0x00030047,0x00000864,0x00000000, + 0x00030047,0x00000866,0x00000000,0x00030047,0x00000867,0x00000000,0x00030047,0x0000086f, + 0x00000000,0x00030047,0x00000881,0x00000000,0x00030047,0x000008a3,0x00000000,0x00030047, + 0x000008a4,0x00000000,0x00030047,0x000008a8,0x00000000,0x00030047,0x000008aa,0x00000000, + 0x00030047,0x000008ab,0x00000000,0x00030047,0x000008b4,0x00000000,0x00030047,0x000008bb, + 0x00000000,0x00030047,0x00000955,0x00000000,0x00030047,0x00000956,0x00000000,0x00030047, + 0x00000966,0x00000000,0x00030047,0x00000967,0x00000000,0x00030047,0x0000096a,0x00000000, + 0x00030047,0x0000096c,0x00000000,0x00030047,0x00000982,0x00000000,0x00030047,0x00000985, + 0x00000000,0x00030047,0x00000a69,0x00000000,0x00030047,0x00000a6b,0x00000000,0x00030047, + 0x00000a6d,0x00000000,0x00030047,0x00000a86,0x00000000,0x00030047,0x00000a88,0x00000000, + 0x00030047,0x00000a8a,0x00000000,0x00030047,0x00000ab2,0x00000000,0x00030047,0x00000ab4, + 0x00000000,0x00030047,0x00000ab6,0x00000000,0x00030047,0x00000ab9,0x00000000,0x00030047, + 0x00000abb,0x00000000,0x00030047,0x00000abd,0x00000000,0x00030047,0x00000ac1,0x00000000, + 0x00030047,0x00000ac3,0x00000000,0x00030047,0x00000ac5,0x00000000,0x00030047,0x00000ac6, + 0x00000000,0x00030047,0x00000acd,0x00000000,0x00030047,0x00000acc,0x00000000,0x00030047, + 0x00000ace,0x00000000,0x00030047,0x00000b95,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006, + 0x00000004,0x00040020,0x0000000d,0x00000007,0x00000006,0x00040015,0x0000000e,0x00000020, + 0x00000000,0x00040017,0x00000017,0x00000006,0x00000002,0x00040017,0x00000021,0x00000006, + 0x00000003,0x00040020,0x0000002c,0x00000007,0x00000021,0x0004002b,0x00000006,0x000000b6, + 0x00000000,0x00020014,0x000000b7,0x0004002b,0x00000006,0x000000bc,0x3f800000,0x0004002b, + 0x00000006,0x000000e6,0x3d897143,0x0004002b,0x00000006,0x000000ea,0x3bbf4590,0x0004002b, + 0x00000006,0x000000f1,0x4253ee82,0x0004002b,0x00000006,0x00000110,0x3e99999a,0x0004002b, + 0x00000006,0x00000111,0x3f170a3d,0x0004002b,0x00000006,0x00000112,0x3de147ae,0x0004002b, + 0x00000006,0x0000012c,0x388205ff,0x0004002b,0x00000006,0x00000192,0x40000000,0x0004002b, + 0x00000006,0x00000199,0x3f000000,0x00040017,0x0000019f,0x000000b7,0x00000003,0x00040015, + 0x0000021b,0x00000020,0x00000001,0x0004002b,0x0000021b,0x0000021e,0x00000000,0x0004002b, + 0x0000021b,0x00000225,0x00000003,0x0004002b,0x00000006,0x00000237,0x3e800000,0x0004002b, + 0x00000006,0x0000023c,0x41800000,0x0004002b,0x00000006,0x00000241,0x41400000,0x0004002b, + 0x00000006,0x00000247,0x40400000,0x0004002b,0x0000021b,0x00000253,0x00000001,0x0004002b, + 0x00000006,0x000002d7,0xbf800000,0x0004002b,0x00000006,0x000002f5,0x3f7f8000,0x0004002b, + 0x00000006,0x000002f8,0x3a800000,0x0004002b,0x00000006,0x000002fb,0x3b000000,0x00090019, + 0x00000305,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x00000306,0x00000000,0x00000305,0x0004003b,0x00000306,0x00000307,0x00000000, + 0x0002001a,0x00000309,0x00040020,0x0000030a,0x00000000,0x00000309,0x0004003b,0x0000030a, + 0x0000030b,0x00000000,0x0003001b,0x0000030d,0x00000305,0x0004003b,0x00000306,0x0000032b, + 0x00000000,0x0004003b,0x0000030a,0x0000032d,0x00000000,0x00040020,0x0000034e,0x00000001, + 0x00000007,0x0004003b,0x0000034e,0x0000034f,0x00000001,0x00040020,0x00000356,0x00000001, + 0x00000006,0x0004003b,0x00000356,0x00000357,0x00000001,0x0004003b,0x00000306,0x0000035c, + 0x00000000,0x0004003b,0x0000034e,0x0000035e,0x00000001,0x00040017,0x00000362,0x0000021b, + 0x00000002,0x00040017,0x0000037e,0x0000021b,0x00000004,0x0017001e,0x0000037f,0x00000006, + 0x00000006,0x00000006,0x00000006,0x0000000e,0x0000000e,0x0000000e,0x0000000e,0x0000037e, + 0x00000017,0x00000017,0x0000000e,0x00000006,0x0000000e,0x00000006,0x00000006,0x0000000e, + 0x00000006,0x00000006,0x00000006,0x0000000e,0x00040020,0x00000380,0x00000002,0x0000037f, + 0x0004003b,0x00000380,0x00000381,0x00000002,0x0004002b,0x0000021b,0x00000382,0x00000011, + 0x0004002b,0x0000021b,0x00000383,0x00000012,0x00040020,0x0000038b,0x00000002,0x00000006, + 0x00040020,0x00000398,0x00000003,0x00000007,0x0004003b,0x00000398,0x00000399,0x00000003, + 0x0004003b,0x0000030a,0x0000039b,0x00000000,0x0004003b,0x00000306,0x0000039c,0x00000000, + 0x00040020,0x0000039d,0x00000001,0x00000017,0x0004003b,0x0000039d,0x0000039e,0x00000001, + 0x0006002c,0x00000021,0x00000bd9,0x00000199,0x00000199,0x00000199,0x0006002c,0x00000021, + 0x00000bda,0x000000bc,0x000000bc,0x000000bc,0x0004002b,0x00000006,0x00000bdc,0xc0000000, + 0x0006002c,0x00000021,0x00000bfe,0x000000b6,0x000000b6,0x000000b6,0x0006002c,0x00000021, + 0x00000bff,0x00000110,0x00000111,0x00000112,0x0005002c,0x00000017,0x00000c00,0x0000012c, + 0x0000012c,0x00030001,0x00000007,0x00000c01,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000002c,0x00000441,0x00000007,0x0004003b, + 0x0000002c,0x00000443,0x00000007,0x0004003b,0x0000002c,0x00000431,0x00000007,0x0004003d, + 0x00000007,0x00000351,0x0000034f,0x00050051,0x00000006,0x000003af,0x00000351,0x00000003, + 0x000500be,0x000000b7,0x000003b0,0x000003af,0x000000b6,0x000300f7,0x00000408,0x00000000, + 0x000400fa,0x000003b0,0x000003fe,0x000003b1,0x000200f8,0x000003b1,0x000500ba,0x000000b7, + 0x000003b4,0x000003af,0x000002d7,0x000300f7,0x000003fd,0x00000000,0x000400fa,0x000003b4, + 0x000003ce,0x000003b5,0x000200f8,0x000003b5,0x00050083,0x00000006,0x000003b9,0x00000bdc, + 0x000003af,0x0004003d,0x00000305,0x000003ba,0x0000032b,0x0004003d,0x00000309,0x000003bb, + 0x0000032d,0x00050056,0x0000030d,0x000003bc,0x000003ba,0x000003bb,0x0007004f,0x00000017, + 0x000003be,0x00000351,0x00000351,0x00000000,0x00000001,0x00070058,0x00000007,0x000003c0, + 0x000003bc,0x000003be,0x00000002,0x000003b9,0x00050051,0x00000006,0x000003c2,0x00000351, + 0x00000002,0x0008004f,0x00000021,0x0000040e,0x000003c0,0x000003c0,0x00000000,0x00000001, + 0x00000002,0x00050051,0x00000006,0x00000410,0x000003c0,0x00000003,0x000500b7,0x000000b7, + 0x00000411,0x00000410,0x000000b6,0x000300f7,0x00000417,0x00000000,0x000400fa,0x00000411, + 0x00000413,0x00000412,0x000200f8,0x00000412,0x000200f9,0x00000417,0x000200f8,0x00000413, + 0x00050088,0x00000006,0x00000416,0x000000bc,0x00000410,0x000200f9,0x00000417,0x000200f8, + 0x00000417,0x000700f5,0x00000006,0x00000ac6,0x000000b6,0x00000412,0x00000416,0x00000413, + 0x0005008e,0x00000021,0x00000419,0x0000040e,0x00000ac6,0x00050085,0x00000006,0x000003cb, + 0x00000410,0x000003c2,0x00050051,0x00000006,0x0000041f,0x00000419,0x00000000,0x00050051, + 0x00000006,0x00000421,0x00000419,0x00000001,0x00050051,0x00000006,0x00000423,0x00000419, + 0x00000002,0x00070050,0x00000007,0x00000bdd,0x0000041f,0x00000421,0x00000423,0x000003cb, + 0x000200f9,0x000003fd,0x000200f8,0x000003ce,0x00050051,0x00000006,0x000003d0,0x00000351, + 0x00000002,0x000500ba,0x000000b7,0x000003d1,0x000003d0,0x000000b6,0x000300f7,0x000003d9, + 0x00000000,0x000400fa,0x000003d1,0x000003d6,0x000003d2,0x000200f8,0x000003d2,0x0007004f, + 0x00000017,0x000003d4,0x00000351,0x00000351,0x00000000,0x00000001,0x0006000c,0x00000006, + 0x000003d5,0x00000001,0x00000042,0x000003d4,0x000200f9,0x000003d9,0x000200f8,0x000003d6, + 0x00050051,0x00000006,0x000003d8,0x00000351,0x00000000,0x000200f9,0x000003d9,0x000200f8, + 0x000003d9,0x000700f5,0x00000006,0x00000aca,0x000003d5,0x000003d2,0x000003d8,0x000003d6, + 0x0008000c,0x00000006,0x000003dc,0x00000001,0x0000002b,0x00000aca,0x000000b6,0x000000bc, + 0x0006000c,0x00000006,0x000003df,0x00000001,0x00000004,0x000003d0,0x000500ba,0x000000b7, + 0x000003e1,0x000003df,0x000000bc,0x000300f7,0x000003eb,0x00000000,0x000400fa,0x000003e1, + 0x000003e7,0x000003e2,0x000200f8,0x000003e2,0x00050085,0x00000006,0x000003e4,0x000002fb, + 0x000003dc,0x00050081,0x00000006,0x000003e6,0x000003e4,0x000003df,0x000200f9,0x000003eb, + 0x000200f8,0x000003e7,0x00050085,0x00000006,0x000003e9,0x000002f5,0x000003dc,0x00050081, + 0x00000006,0x000003ea,0x000003e9,0x000002f8,0x000200f9,0x000003eb,0x000200f8,0x000003eb, + 0x000700f5,0x00000006,0x00000acb,0x000003e6,0x000003e2,0x000003ea,0x000003e7,0x0004007f, + 0x00000006,0x000003ef,0x000003af,0x0004003d,0x00000305,0x000003f0,0x00000307,0x0004003d, + 0x00000309,0x000003f1,0x0000030b,0x00050056,0x0000030d,0x000003f2,0x000003f0,0x000003f1, + 0x00050050,0x00000017,0x000003f5,0x00000acb,0x000003ef,0x00070058,0x00000007,0x000003f6, + 0x000003f2,0x000003f5,0x00000002,0x000000b6,0x00050051,0x00000006,0x000003f9,0x000003f6, + 0x00000003,0x00060052,0x00000007,0x00000982,0x000003f9,0x000003f6,0x00000003,0x000200f9, + 0x000003fd,0x000200f8,0x000003fd,0x000700f5,0x00000007,0x00000acd,0x00000bdd,0x00000417, + 0x00000982,0x000003eb,0x000200f9,0x00000408,0x000200f8,0x000003fe,0x00050051,0x00000006, + 0x00000404,0x00000351,0x00000003,0x00060052,0x00000007,0x00000985,0x00000404,0x00000351, + 0x00000003,0x000200f9,0x00000408,0x000200f8,0x00000408,0x000700f5,0x00000007,0x00000acc, + 0x00000acd,0x000003fd,0x00000985,0x000003fe,0x0004003d,0x00000006,0x00000359,0x00000357, + 0x0004006d,0x0000000e,0x0000042f,0x00000359,0x0004003d,0x00000305,0x0000035d,0x0000035c, + 0x0004003d,0x00000007,0x0000035f,0x0000035e,0x0007004f,0x00000017,0x00000360,0x0000035f, + 0x0000035f,0x00000000,0x00000001,0x0006000c,0x00000017,0x00000361,0x00000001,0x00000008, + 0x00000360,0x0004006e,0x00000362,0x00000363,0x00000361,0x0007005f,0x00000007,0x00000364, + 0x0000035d,0x00000363,0x00000002,0x0000021e,0x0008004f,0x00000021,0x00000367,0x00000acc, + 0x00000acc,0x00000000,0x00000001,0x00000002,0x0003003e,0x00000431,0x00000367,0x0008004f, + 0x00000021,0x0000056b,0x00000364,0x00000364,0x00000000,0x00000001,0x00000002,0x00050051, + 0x00000006,0x0000056d,0x00000364,0x00000003,0x000500b7,0x000000b7,0x0000056e,0x0000056d, + 0x000000b6,0x000300f7,0x00000574,0x00000000,0x000400fa,0x0000056e,0x00000570,0x0000056f, + 0x000200f8,0x0000056f,0x000200f9,0x00000574,0x000200f8,0x00000570,0x00050088,0x00000006, + 0x00000573,0x000000bc,0x0000056d,0x000200f9,0x00000574,0x000200f8,0x00000574,0x000700f5, + 0x00000006,0x00000ace,0x000000b6,0x0000056f,0x00000573,0x00000570,0x0005008e,0x00000021, + 0x00000576,0x0000056b,0x00000ace,0x0003003e,0x00000441,0x00000576,0x000300f7,0x00000565, + 0x00000000,0x002100fb,0x0000042f,0x00000565,0x0000000b,0x00000561,0x00000001,0x00000559, + 0x00000002,0x00000548,0x00000003,0x00000544,0x00000004,0x00000540,0x00000005,0x0000051d, + 0x00000006,0x000004f0,0x00000007,0x000004df,0x00000008,0x000004a4,0x00000009,0x0000049f, + 0x0000000a,0x00000496,0x0000000c,0x0000048b,0x0000000d,0x00000480,0x0000000e,0x00000476, + 0x0000000f,0x0000046c,0x000200f8,0x0000046c,0x0004003d,0x00000021,0x0000046e,0x00000431, + 0x0008000c,0x00000021,0x00000471,0x00000001,0x0000002b,0x0000046e,0x00000bfe,0x00000bda, + 0x0003003e,0x00000431,0x00000471,0x00050094,0x00000006,0x000005c3,0x00000471,0x00000bff, + 0x00050094,0x00000006,0x000005d5,0x00000576,0x00000bff,0x00060050,0x00000021,0x000005a0, + 0x000005d5,0x000005d5,0x000005d5,0x00050083,0x00000021,0x000005a1,0x00000576,0x000005a0, + 0x00050083,0x00000006,0x000005a3,0x000000bc,0x000005c3,0x00050050,0x00000017,0x00000be1, + 0x000005c3,0x000005a3,0x00050051,0x00000006,0x000005fc,0x000005a1,0x00000000,0x00050051, + 0x00000006,0x000005fe,0x000005a1,0x00000001,0x0007000c,0x00000006,0x000005ff,0x00000001, + 0x00000025,0x000005fc,0x000005fe,0x00050051,0x00000006,0x000005f7,0x000005a1,0x00000002, + 0x0007000c,0x00000006,0x000005f8,0x00000001,0x00000025,0x000005ff,0x000005f7,0x0004007f, + 0x00000006,0x000005a9,0x000005f8,0x0007000c,0x00000006,0x0000060f,0x00000001,0x00000028, + 0x000005fc,0x000005fe,0x0007000c,0x00000006,0x00000608,0x00000001,0x00000028,0x0000060f, + 0x000005f7,0x00050050,0x00000017,0x00000be3,0x000005a9,0x00000608,0x0007000c,0x00000017, + 0x000005ad,0x00000001,0x00000028,0x00000c00,0x00000be3,0x00050088,0x00000017,0x000005ae, + 0x00000be1,0x000005ad,0x00050051,0x00000006,0x000005b1,0x000005ae,0x00000000,0x00050051, + 0x00000006,0x000005b3,0x000005ae,0x00000001,0x0007000c,0x00000006,0x000005b4,0x00000001, + 0x00000025,0x000005b1,0x000005b3,0x0007000c,0x00000006,0x000005b5,0x00000001,0x00000025, + 0x000000bc,0x000005b4,0x0005008e,0x00000021,0x000005b8,0x000005a1,0x000005b5,0x00060050, + 0x00000021,0x000005ba,0x000005c3,0x000005c3,0x000005c3,0x00050081,0x00000021,0x000005bb, + 0x000005b8,0x000005ba,0x0003003e,0x00000443,0x000005bb,0x000200f9,0x00000565,0x000200f8, + 0x00000476,0x0004003d,0x00000021,0x00000478,0x00000431,0x0008000c,0x00000021,0x0000047b, + 0x00000001,0x0000002b,0x00000478,0x00000bfe,0x00000bda,0x0003003e,0x00000431,0x0000047b, + 0x00050094,0x00000006,0x00000667,0x00000576,0x00000bff,0x00050094,0x00000006,0x00000679, + 0x0000047b,0x00000bff,0x00060050,0x00000021,0x00000644,0x00000679,0x00000679,0x00000679, + 0x00050083,0x00000021,0x00000645,0x0000047b,0x00000644,0x00050083,0x00000006,0x00000647, + 0x000000bc,0x00000667,0x00050050,0x00000017,0x00000be7,0x00000667,0x00000647,0x00050051, + 0x00000006,0x000006a0,0x00000645,0x00000000,0x00050051,0x00000006,0x000006a2,0x00000645, + 0x00000001,0x0007000c,0x00000006,0x000006a3,0x00000001,0x00000025,0x000006a0,0x000006a2, + 0x00050051,0x00000006,0x0000069b,0x00000645,0x00000002,0x0007000c,0x00000006,0x0000069c, + 0x00000001,0x00000025,0x000006a3,0x0000069b,0x0004007f,0x00000006,0x0000064d,0x0000069c, + 0x0007000c,0x00000006,0x000006b3,0x00000001,0x00000028,0x000006a0,0x000006a2,0x0007000c, + 0x00000006,0x000006ac,0x00000001,0x00000028,0x000006b3,0x0000069b,0x00050050,0x00000017, + 0x00000be9,0x0000064d,0x000006ac,0x0007000c,0x00000017,0x00000651,0x00000001,0x00000028, + 0x00000c00,0x00000be9,0x00050088,0x00000017,0x00000652,0x00000be7,0x00000651,0x00050051, + 0x00000006,0x00000655,0x00000652,0x00000000,0x00050051,0x00000006,0x00000657,0x00000652, + 0x00000001,0x0007000c,0x00000006,0x00000658,0x00000001,0x00000025,0x00000655,0x00000657, + 0x0007000c,0x00000006,0x00000659,0x00000001,0x00000025,0x000000bc,0x00000658,0x0005008e, + 0x00000021,0x0000065c,0x00000645,0x00000659,0x00060050,0x00000021,0x0000065e,0x00000667, + 0x00000667,0x00000667,0x00050081,0x00000021,0x0000065f,0x0000065c,0x0000065e,0x0003003e, + 0x00000443,0x0000065f,0x000200f9,0x00000565,0x000200f8,0x00000480,0x0004003d,0x00000021, + 0x00000482,0x00000431,0x0008000c,0x00000021,0x00000485,0x00000001,0x0000002b,0x00000482, + 0x00000bfe,0x00000bda,0x0003003e,0x00000431,0x00000485,0x00050051,0x00000006,0x000006ff, + 0x00000485,0x00000000,0x00050051,0x00000006,0x00000701,0x00000485,0x00000001,0x0007000c, + 0x00000006,0x00000702,0x00000001,0x00000028,0x000006ff,0x00000701,0x00050051,0x00000006, + 0x000006fa,0x00000485,0x00000002,0x0007000c,0x00000006,0x000006fb,0x00000001,0x00000028, + 0x00000702,0x000006fa,0x0007000c,0x00000006,0x00000712,0x00000001,0x00000025,0x000006ff, + 0x00000701,0x0007000c,0x00000006,0x0000070b,0x00000001,0x00000025,0x00000712,0x000006fa, + 0x00050083,0x00000006,0x000006e2,0x000006fb,0x0000070b,0x00050051,0x00000006,0x0000071f, + 0x00000576,0x00000000,0x00050051,0x00000006,0x00000721,0x00000576,0x00000001,0x0007000c, + 0x00000006,0x00000722,0x00000001,0x00000025,0x0000071f,0x00000721,0x00050051,0x00000006, + 0x0000071a,0x00000576,0x00000002,0x0007000c,0x00000006,0x0000071b,0x00000001,0x00000025, + 0x00000722,0x0000071a,0x00060050,0x00000021,0x000006e6,0x0000071b,0x0000071b,0x0000071b, + 0x00050083,0x00000021,0x000006e7,0x00000576,0x000006e6,0x00050051,0x00000006,0x0000072f, + 0x000006e7,0x00000000,0x00050051,0x00000006,0x00000731,0x000006e7,0x00000001,0x0007000c, + 0x00000006,0x00000732,0x00000001,0x00000028,0x0000072f,0x00000731,0x00050051,0x00000006, + 0x0000072a,0x000006e7,0x00000002,0x0007000c,0x00000006,0x0000072b,0x00000001,0x00000028, + 0x00000732,0x0000072a,0x0007000c,0x00000006,0x000006ec,0x00000001,0x00000028,0x0000012c, + 0x0000072b,0x00050088,0x00000006,0x000006ed,0x000006e2,0x000006ec,0x0005008e,0x00000021, + 0x000006f0,0x000006e7,0x000006ed,0x00050094,0x00000006,0x0000076b,0x00000576,0x00000bff, + 0x00050094,0x00000006,0x0000077d,0x000006f0,0x00000bff,0x00060050,0x00000021,0x00000748, + 0x0000077d,0x0000077d,0x0000077d,0x00050083,0x00000021,0x00000749,0x000006f0,0x00000748, + 0x00050083,0x00000006,0x0000074b,0x000000bc,0x0000076b,0x00050050,0x00000017,0x00000bed, + 0x0000076b,0x0000074b,0x00050051,0x00000006,0x000007a4,0x00000749,0x00000000,0x00050051, + 0x00000006,0x000007a6,0x00000749,0x00000001,0x0007000c,0x00000006,0x000007a7,0x00000001, + 0x00000025,0x000007a4,0x000007a6,0x00050051,0x00000006,0x0000079f,0x00000749,0x00000002, + 0x0007000c,0x00000006,0x000007a0,0x00000001,0x00000025,0x000007a7,0x0000079f,0x0004007f, + 0x00000006,0x00000751,0x000007a0,0x0007000c,0x00000006,0x000007b7,0x00000001,0x00000028, + 0x000007a4,0x000007a6,0x0007000c,0x00000006,0x000007b0,0x00000001,0x00000028,0x000007b7, + 0x0000079f,0x00050050,0x00000017,0x00000bef,0x00000751,0x000007b0,0x0007000c,0x00000017, + 0x00000755,0x00000001,0x00000028,0x00000c00,0x00000bef,0x00050088,0x00000017,0x00000756, + 0x00000bed,0x00000755,0x00050051,0x00000006,0x00000759,0x00000756,0x00000000,0x00050051, + 0x00000006,0x0000075b,0x00000756,0x00000001,0x0007000c,0x00000006,0x0000075c,0x00000001, + 0x00000025,0x00000759,0x0000075b,0x0007000c,0x00000006,0x0000075d,0x00000001,0x00000025, + 0x000000bc,0x0000075c,0x0005008e,0x00000021,0x00000760,0x00000749,0x0000075d,0x00060050, + 0x00000021,0x00000762,0x0000076b,0x0000076b,0x0000076b,0x00050081,0x00000021,0x00000763, + 0x00000760,0x00000762,0x0003003e,0x00000443,0x00000763,0x000200f9,0x00000565,0x000200f8, + 0x0000048b,0x0004003d,0x00000021,0x0000048d,0x00000431,0x0008000c,0x00000021,0x00000490, + 0x00000001,0x0000002b,0x0000048d,0x00000bfe,0x00000bda,0x0003003e,0x00000431,0x00000490, + 0x00050051,0x00000006,0x00000803,0x00000576,0x00000000,0x00050051,0x00000006,0x00000805, + 0x00000576,0x00000001,0x0007000c,0x00000006,0x00000806,0x00000001,0x00000028,0x00000803, + 0x00000805,0x00050051,0x00000006,0x000007fe,0x00000576,0x00000002,0x0007000c,0x00000006, + 0x000007ff,0x00000001,0x00000028,0x00000806,0x000007fe,0x0007000c,0x00000006,0x00000816, + 0x00000001,0x00000025,0x00000803,0x00000805,0x0007000c,0x00000006,0x0000080f,0x00000001, + 0x00000025,0x00000816,0x000007fe,0x00050083,0x00000006,0x000007e6,0x000007ff,0x0000080f, + 0x00050051,0x00000006,0x00000823,0x00000490,0x00000000,0x00050051,0x00000006,0x00000825, + 0x00000490,0x00000001,0x0007000c,0x00000006,0x00000826,0x00000001,0x00000025,0x00000823, + 0x00000825,0x00050051,0x00000006,0x0000081e,0x00000490,0x00000002,0x0007000c,0x00000006, + 0x0000081f,0x00000001,0x00000025,0x00000826,0x0000081e,0x00060050,0x00000021,0x000007ea, + 0x0000081f,0x0000081f,0x0000081f,0x00050083,0x00000021,0x000007eb,0x00000490,0x000007ea, + 0x00050051,0x00000006,0x00000833,0x000007eb,0x00000000,0x00050051,0x00000006,0x00000835, + 0x000007eb,0x00000001,0x0007000c,0x00000006,0x00000836,0x00000001,0x00000028,0x00000833, + 0x00000835,0x00050051,0x00000006,0x0000082e,0x000007eb,0x00000002,0x0007000c,0x00000006, + 0x0000082f,0x00000001,0x00000028,0x00000836,0x0000082e,0x0007000c,0x00000006,0x000007f0, + 0x00000001,0x00000028,0x0000012c,0x0000082f,0x00050088,0x00000006,0x000007f1,0x000007e6, + 0x000007f0,0x0005008e,0x00000021,0x000007f4,0x000007eb,0x000007f1,0x00050094,0x00000006, + 0x0000086f,0x00000576,0x00000bff,0x00050094,0x00000006,0x00000881,0x000007f4,0x00000bff, + 0x00060050,0x00000021,0x0000084c,0x00000881,0x00000881,0x00000881,0x00050083,0x00000021, + 0x0000084d,0x000007f4,0x0000084c,0x00050083,0x00000006,0x0000084f,0x000000bc,0x0000086f, + 0x00050050,0x00000017,0x00000bf3,0x0000086f,0x0000084f,0x00050051,0x00000006,0x000008a8, + 0x0000084d,0x00000000,0x00050051,0x00000006,0x000008aa,0x0000084d,0x00000001,0x0007000c, + 0x00000006,0x000008ab,0x00000001,0x00000025,0x000008a8,0x000008aa,0x00050051,0x00000006, + 0x000008a3,0x0000084d,0x00000002,0x0007000c,0x00000006,0x000008a4,0x00000001,0x00000025, + 0x000008ab,0x000008a3,0x0004007f,0x00000006,0x00000855,0x000008a4,0x0007000c,0x00000006, + 0x000008bb,0x00000001,0x00000028,0x000008a8,0x000008aa,0x0007000c,0x00000006,0x000008b4, + 0x00000001,0x00000028,0x000008bb,0x000008a3,0x00050050,0x00000017,0x00000bf5,0x00000855, + 0x000008b4,0x0007000c,0x00000017,0x00000859,0x00000001,0x00000028,0x00000c00,0x00000bf5, + 0x00050088,0x00000017,0x0000085a,0x00000bf3,0x00000859,0x00050051,0x00000006,0x0000085d, + 0x0000085a,0x00000000,0x00050051,0x00000006,0x0000085f,0x0000085a,0x00000001,0x0007000c, + 0x00000006,0x00000860,0x00000001,0x00000025,0x0000085d,0x0000085f,0x0007000c,0x00000006, + 0x00000861,0x00000001,0x00000025,0x000000bc,0x00000860,0x0005008e,0x00000021,0x00000864, + 0x0000084d,0x00000861,0x00060050,0x00000021,0x00000866,0x0000086f,0x0000086f,0x0000086f, + 0x00050081,0x00000021,0x00000867,0x00000864,0x00000866,0x0003003e,0x00000443,0x00000867, + 0x000200f9,0x00000565,0x000200f8,0x00000496,0x0004003d,0x00000021,0x00000497,0x00000431, + 0x00050081,0x00000021,0x00000499,0x00000497,0x00000576,0x0005008e,0x00000021,0x0000049b, + 0x00000497,0x00000192,0x00050085,0x00000021,0x0000049d,0x0000049b,0x00000576,0x00050083, + 0x00000021,0x0000049e,0x00000499,0x0000049d,0x0003003e,0x00000443,0x0000049e,0x000200f9, + 0x00000565,0x000200f8,0x0000049f,0x0004003d,0x00000021,0x000004a1,0x00000431,0x00050083, + 0x00000021,0x000004a2,0x00000576,0x000004a1,0x0006000c,0x00000021,0x000004a3,0x00000001, + 0x00000004,0x000004a2,0x0003003e,0x00000443,0x000004a3,0x000200f9,0x00000565,0x000200f8, + 0x000004a4,0x000200f9,0x000004a5,0x000200f8,0x000004a5,0x000700f5,0x0000021b,0x00000b79, + 0x0000021e,0x000004a4,0x000004d3,0x000004d1,0x000500b1,0x000000b7,0x000004a8,0x00000b79, + 0x00000225,0x000400f6,0x000004d4,0x000004d1,0x00000000,0x000400fa,0x000004a8,0x000004a9, + 0x000004d4,0x000200f8,0x000004a9,0x00050041,0x0000000d,0x000004ab,0x00000431,0x00000b79, + 0x0004003d,0x00000006,0x000004ac,0x000004ab,0x000500bc,0x000000b7,0x000004ad,0x000004ac, + 0x00000199,0x000300f7,0x000004d0,0x00000000,0x000400fa,0x000004ad,0x000004c9,0x000004ae, + 0x000200f8,0x000004ae,0x00050041,0x0000000d,0x000004b0,0x00000441,0x00000b79,0x0004003d, + 0x00000006,0x000004b1,0x000004b0,0x000500bc,0x000000b7,0x000004b2,0x000004b1,0x00000237, + 0x000300f7,0x000004c8,0x00000000,0x000400fa,0x000004b2,0x000004bb,0x000004b3,0x000200f8, + 0x000004b3,0x0004003d,0x00000006,0x000004b7,0x000004b0,0x0006000c,0x00000006,0x000004b8, + 0x00000001,0x00000020,0x000004b7,0x00050083,0x00000006,0x000004b9,0x000004b8,0x000000bc, + 0x00050041,0x0000000d,0x000004ba,0x00000443,0x00000b79,0x0003003e,0x000004ba,0x000004b9, + 0x000200f9,0x000004c8,0x000200f8,0x000004bb,0x0004003d,0x00000006,0x000004bf,0x000004b0, + 0x00050085,0x00000006,0x000004c0,0x0000023c,0x000004bf,0x00050083,0x00000006,0x000004c1, + 0x000004c0,0x00000241,0x0004003d,0x00000006,0x000004c4,0x000004b0,0x00050085,0x00000006, + 0x000004c5,0x000004c1,0x000004c4,0x00050081,0x00000006,0x000004c6,0x000004c5,0x00000247, + 0x00050041,0x0000000d,0x000004c7,0x00000443,0x00000b79,0x0003003e,0x000004c7,0x000004c6, + 0x000200f9,0x000004c8,0x000200f8,0x000004c8,0x000200f9,0x000004d0,0x000200f8,0x000004c9, + 0x00050041,0x0000000d,0x000004cc,0x00000441,0x00000b79,0x0004003d,0x00000006,0x000004cd, + 0x000004cc,0x00050083,0x00000006,0x000004ce,0x000000bc,0x000004cd,0x00050041,0x0000000d, + 0x000004cf,0x00000443,0x00000b79,0x0003003e,0x000004cf,0x000004ce,0x000200f9,0x000004d0, + 0x000200f8,0x000004d0,0x000200f9,0x000004d1,0x000200f8,0x000004d1,0x00050080,0x0000021b, + 0x000004d3,0x00000b79,0x00000253,0x000200f9,0x000004a5,0x000200f8,0x000004d4,0x0004003d, + 0x00000021,0x000004d7,0x00000431,0x0005008e,0x00000021,0x000004d8,0x000004d7,0x00000192, + 0x00050083,0x00000021,0x000004da,0x000004d8,0x00000bda,0x00050085,0x00000021,0x000004db, + 0x00000576,0x000004da,0x0004003d,0x00000021,0x000004dc,0x00000443,0x00050085,0x00000021, + 0x000004dd,0x000004db,0x000004dc,0x00050081,0x00000021,0x000004de,0x00000576,0x000004dd, + 0x0003003e,0x00000443,0x000004de,0x000200f9,0x00000565,0x000200f8,0x000004df,0x0004003d, + 0x00000021,0x000004e0,0x00000431,0x00050085,0x00000021,0x000004e2,0x000004e0,0x00000576, + 0x00050081,0x00000021,0x000004e6,0x000004e0,0x00000576,0x00050083,0x00000021,0x000004e8, + 0x000004e6,0x000004e2,0x00050083,0x00000021,0x000004ea,0x000004e8,0x00000bd9,0x000500ba, + 0x0000019f,0x000004ed,0x000004e0,0x00000bd9,0x000600a9,0x00000021,0x000004ee,0x000004ed, + 0x000004ea,0x000004e2,0x0005008e,0x00000021,0x000004ef,0x000004ee,0x00000192,0x0003003e, + 0x00000443,0x000004ef,0x000200f9,0x00000565,0x000200f8,0x000004f0,0x0004003d,0x00000021, + 0x000004f1,0x00000431,0x0008000c,0x00000021,0x000004f4,0x00000001,0x0000002b,0x000004f1, + 0x00000bfe,0x00000bda,0x0003003e,0x00000431,0x000004f4,0x0008004f,0x00000021,0x000004f9, + 0x00000364,0x00000364,0x00000003,0x00000003,0x00000003,0x0008000c,0x00000021,0x000004fa, + 0x00000001,0x0000002b,0x0000056b,0x00000bfe,0x000004f9,0x00050051,0x00000006,0x000004fc, + 0x000004fa,0x00000000,0x00060052,0x00000007,0x00000a69,0x000004fc,0x00000364,0x00000000, + 0x00050051,0x00000006,0x000004fe,0x000004fa,0x00000001,0x00060052,0x00000007,0x00000a6b, + 0x000004fe,0x00000a69,0x00000001,0x00050051,0x00000006,0x00000500,0x000004fa,0x00000002, + 0x00060052,0x00000007,0x00000a6d,0x00000500,0x00000a6b,0x00000002,0x000500b4,0x000000b7, + 0x00000503,0x0000056d,0x000000b6,0x000300f7,0x00000506,0x00000000,0x000400fa,0x00000503, + 0x00000504,0x00000506,0x000200f8,0x00000504,0x00070050,0x00000007,0x00000bf9,0x000004fc, + 0x000004fe,0x00000500,0x000000bc,0x000200f9,0x00000506,0x000200f8,0x00000506,0x000700f5, + 0x00000007,0x00000b95,0x00000a6d,0x000004f0,0x00000bf9,0x00000504,0x00050051,0x00000006, + 0x00000508,0x00000b95,0x00000003,0x0008004f,0x00000021,0x0000050a,0x00000b95,0x00000b95, + 0x00000000,0x00000001,0x00000002,0x00060050,0x00000021,0x0000050b,0x00000508,0x00000508, + 0x00000508,0x00050083,0x00000021,0x0000050c,0x0000050b,0x0000050a,0x0004003d,0x00000021, + 0x0000050f,0x00000431,0x0005008e,0x00000021,0x00000512,0x0000050f,0x00000508,0x00050088, + 0x00000021,0x00000513,0x0000050c,0x00000512,0x0007000c,0x00000021,0x00000514,0x00000001, + 0x00000025,0x00000bda,0x00000513,0x0006000c,0x00000021,0x00000516,0x00000001,0x00000006, + 0x0000050c,0x000500b4,0x0000019f,0x00000519,0x0000050f,0x00000bfe,0x000600a9,0x00000021, + 0x0000051a,0x00000519,0x00000516,0x00000514,0x00050083,0x00000021,0x0000051c,0x00000bda, + 0x0000051a,0x0003003e,0x00000443,0x0000051c,0x000200f9,0x00000565,0x000200f8,0x0000051d, + 0x0008004f,0x00000021,0x00000522,0x00000364,0x00000364,0x00000003,0x00000003,0x00000003, + 0x0008000c,0x00000021,0x00000523,0x00000001,0x0000002b,0x0000056b,0x00000bfe,0x00000522, + 0x00050051,0x00000006,0x00000525,0x00000523,0x00000000,0x00060052,0x00000007,0x00000a86, + 0x00000525,0x00000c01,0x00000000,0x00050051,0x00000006,0x00000527,0x00000523,0x00000001, + 0x00060052,0x00000007,0x00000a88,0x00000527,0x00000a86,0x00000001,0x00050051,0x00000006, + 0x00000529,0x00000523,0x00000002,0x00060052,0x00000007,0x00000a8a,0x00000529,0x00000a88, + 0x00000002,0x0004003d,0x00000021,0x0000052a,0x00000431,0x00050083,0x00000021,0x0000052c, + 0x00000bda,0x0000052a,0x0008000c,0x00000021,0x0000052f,0x00000001,0x0000002b,0x0000052c, + 0x00000bfe,0x00000bda,0x0005008e,0x00000021,0x00000532,0x0000052f,0x0000056d,0x0008004f, + 0x00000021,0x00000535,0x00000a8a,0x00000a8a,0x00000000,0x00000001,0x00000002,0x00050088, + 0x00000021,0x00000537,0x00000535,0x00000532,0x0007000c,0x00000021,0x00000538,0x00000001, + 0x00000025,0x00000bda,0x00000537,0x0006000c,0x00000021,0x0000053b,0x00000001,0x00000006, + 0x00000535,0x000500b4,0x0000019f,0x0000053e,0x00000532,0x00000bfe,0x000600a9,0x00000021, + 0x0000053f,0x0000053e,0x0000053b,0x00000538,0x0003003e,0x00000443,0x0000053f,0x000200f9, + 0x00000565,0x000200f8,0x00000540,0x0004003d,0x00000021,0x00000541,0x00000431,0x0007000c, + 0x00000021,0x00000543,0x00000001,0x00000028,0x00000541,0x00000576,0x0003003e,0x00000443, + 0x00000543,0x000200f9,0x00000565,0x000200f8,0x00000544,0x0004003d,0x00000021,0x00000545, + 0x00000431,0x0007000c,0x00000021,0x00000547,0x00000001,0x00000025,0x00000545,0x00000576, + 0x0003003e,0x00000443,0x00000547,0x000200f9,0x00000565,0x000200f8,0x00000548,0x0004003d, + 0x00000021,0x00000549,0x00000431,0x00050085,0x00000021,0x0000054b,0x00000549,0x00000576, + 0x00050081,0x00000021,0x0000054f,0x00000549,0x00000576,0x00050083,0x00000021,0x00000551, + 0x0000054f,0x0000054b,0x00050083,0x00000021,0x00000553,0x00000551,0x00000bd9,0x000500ba, + 0x0000019f,0x00000556,0x00000576,0x00000bd9,0x000600a9,0x00000021,0x00000557,0x00000556, + 0x00000553,0x0000054b,0x0005008e,0x00000021,0x00000558,0x00000557,0x00000192,0x0003003e, + 0x00000443,0x00000558,0x000200f9,0x00000565,0x000200f8,0x00000559,0x0004003d,0x00000021, + 0x0000055a,0x00000431,0x00050081,0x00000021,0x0000055c,0x0000055a,0x00000576,0x00050085, + 0x00000021,0x0000055f,0x0000055a,0x00000576,0x00050083,0x00000021,0x00000560,0x0000055c, + 0x0000055f,0x0003003e,0x00000443,0x00000560,0x000200f9,0x00000565,0x000200f8,0x00000561, + 0x0004003d,0x00000021,0x00000562,0x00000431,0x00050085,0x00000021,0x00000564,0x00000562, + 0x00000576,0x0003003e,0x00000443,0x00000564,0x000200f9,0x00000565,0x000200f8,0x00000565, + 0x0004003d,0x00000021,0x00000566,0x00000443,0x00060050,0x00000021,0x00000bfd,0x0000056d, + 0x0000056d,0x0000056d,0x0008000c,0x00000021,0x00000440,0x00000001,0x0000002e,0x00000367, + 0x00000566,0x00000bfd,0x00050051,0x00000006,0x0000036e,0x00000440,0x00000000,0x00060052, + 0x00000007,0x00000ab2,0x0000036e,0x00000acc,0x00000000,0x00050051,0x00000006,0x00000370, + 0x00000440,0x00000001,0x00060052,0x00000007,0x00000ab4,0x00000370,0x00000ab2,0x00000001, + 0x00050051,0x00000006,0x00000372,0x00000440,0x00000002,0x00060052,0x00000007,0x00000ab6, + 0x00000372,0x00000ab4,0x00000002,0x00050051,0x00000006,0x00000374,0x00000acc,0x00000003, + 0x0008004f,0x00000021,0x00000376,0x00000ab6,0x00000ab6,0x00000000,0x00000001,0x00000002, + 0x0005008e,0x00000021,0x00000377,0x00000376,0x00000374,0x00050051,0x00000006,0x00000379, + 0x00000377,0x00000000,0x00060052,0x00000007,0x00000ab9,0x00000379,0x00000ab6,0x00000000, + 0x00050051,0x00000006,0x0000037b,0x00000377,0x00000001,0x00060052,0x00000007,0x00000abb, + 0x0000037b,0x00000ab9,0x00000001,0x00050051,0x00000006,0x0000037d,0x00000377,0x00000002, + 0x00060052,0x00000007,0x00000abd,0x0000037d,0x00000abb,0x00000002,0x0008004f,0x00000021, + 0x00000386,0x00000abd,0x00000abd,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007, + 0x00000388,0x0000035e,0x00050041,0x0000038b,0x0000038c,0x00000381,0x00000382,0x0004003d, + 0x00000006,0x0000038d,0x0000038c,0x00050041,0x0000038b,0x0000038f,0x00000381,0x00000383, + 0x0004003d,0x00000006,0x00000390,0x0000038f,0x00050051,0x00000006,0x0000095e,0x00000388, + 0x00000000,0x00050085,0x00000006,0x0000095f,0x000000e6,0x0000095e,0x00050051,0x00000006, + 0x00000961,0x00000388,0x00000001,0x00050085,0x00000006,0x00000962,0x000000ea,0x00000961, + 0x00050081,0x00000006,0x00000963,0x0000095f,0x00000962,0x0006000c,0x00000006,0x00000964, + 0x00000001,0x0000000a,0x00000963,0x00050085,0x00000006,0x00000966,0x000000f1,0x00000964, + 0x0006000c,0x00000006,0x00000967,0x00000001,0x0000000a,0x00000966,0x00050085,0x00000006, + 0x0000096a,0x00000967,0x0000038d,0x00050081,0x00000006,0x0000096c,0x0000096a,0x00000390, + 0x00060050,0x00000021,0x00000955,0x0000096c,0x0000096c,0x0000096c,0x00050081,0x00000021, + 0x00000956,0x00000955,0x00000386,0x00050051,0x00000006,0x00000393,0x00000956,0x00000000, + 0x00060052,0x00000007,0x00000ac1,0x00000393,0x00000abd,0x00000000,0x00050051,0x00000006, + 0x00000395,0x00000956,0x00000001,0x00060052,0x00000007,0x00000ac3,0x00000395,0x00000ac1, + 0x00000001,0x00050051,0x00000006,0x00000397,0x00000956,0x00000002,0x00060052,0x00000007, + 0x00000ac5,0x00000397,0x00000ac3,0x00000002,0x0003003e,0x00000399,0x00000ac5,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..5e1f754047a8e48d44065e0c1ea97a51d902dca6 GIT binary patch literal 15844 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 A*8l(j literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.h new file mode 100644 index 000000000..8b3c26577 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.h @@ -0,0 +1,484 @@ +#pragma once + +const uint32_t draw_msaa_path_webgpu_noclipdistance_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000008df,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000d000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000034d,0x00000350,0x00000354, + 0x00000355,0x00000399,0x0000039f,0x000003dc,0x00000461,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x000000ce,0x00004342,0x00030005,0x000000df, + 0x0000664b,0x00040006,0x000000df,0x00000000,0x00003464,0x00030005,0x000000e1,0x00004358, + 0x00030005,0x000000f4,0x0000664a,0x00040006,0x000000f4,0x00000000,0x00003464,0x00030005, + 0x000000f6,0x0000424c,0x00060005,0x0000034d,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00070005,0x00000350,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005, + 0x00000354,0x00004254,0x00030005,0x00000355,0x00004255,0x00030005,0x0000036a,0x00006576, + 0x00040006,0x0000036a,0x00000000,0x00003464,0x00030005,0x0000036c,0x00004355,0x00030005, + 0x00000387,0x0000424d,0x00040006,0x00000387,0x00000000,0x00006250,0x00040006,0x00000387, + 0x00000001,0x00006359,0x00040006,0x00000387,0x00000002,0x00006552,0x00040006,0x00000387, + 0x00000003,0x00006553,0x00040006,0x00000387,0x00000004,0x0000366d,0x00040006,0x00000387, + 0x00000005,0x0000676d,0x00040006,0x00000387,0x00000006,0x00006544,0x00040006,0x00000387, + 0x00000007,0x00006545,0x00040006,0x00000387,0x00000008,0x00003755,0x00040006,0x00000387, + 0x00000009,0x0000676a,0x00040006,0x00000387,0x0000000a,0x0000635a,0x00040006,0x00000387, + 0x0000000b,0x00003157,0x00040006,0x00000387,0x0000000c,0x0000676e,0x00040006,0x00000387, + 0x0000000d,0x00003559,0x00040006,0x00000387,0x0000000e,0x0000324f,0x00040006,0x00000387, + 0x0000000f,0x00006461,0x00040006,0x00000387,0x00000010,0x00006579,0x00040006,0x00000387, + 0x00000011,0x00003376,0x00040006,0x00000387,0x00000012,0x00003377,0x00040006,0x00000387, + 0x00000013,0x00006462,0x00040006,0x00000387,0x00000014,0x00006767,0x00030005,0x00000389, + 0x0000006b,0x00030005,0x00000399,0x00003153,0x00030005,0x0000039f,0x00003159,0x00030005, + 0x000003ac,0x00006577,0x00040006,0x000003ac,0x00000000,0x00003464,0x00030005,0x000003ae, + 0x0000424f,0x00030005,0x000003dc,0x0000316b,0x00060005,0x0000045f,0x505f6c67,0x65567265, + 0x78657472,0x00000000,0x00060006,0x0000045f,0x00000000,0x505f6c67,0x7469736f,0x006e6f69, + 0x00070006,0x0000045f,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006, + 0x0000045f,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000045f, + 0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000461,0x00000000, + 0x00030005,0x00000466,0x00004351,0x00030005,0x00000469,0x00003954,0x00040047,0x000000ce, + 0x00000021,0x00000008,0x00040047,0x000000ce,0x00000022,0x00000000,0x00040047,0x000000de, + 0x00000006,0x00000010,0x00030047,0x000000df,0x00000003,0x00040048,0x000000df,0x00000000, + 0x00000018,0x00050048,0x000000df,0x00000000,0x00000023,0x00000000,0x00030047,0x000000e1, + 0x00000018,0x00040047,0x000000e1,0x00000021,0x00000006,0x00040047,0x000000e1,0x00000022, + 0x00000000,0x00040047,0x000000f3,0x00000006,0x00000010,0x00030047,0x000000f4,0x00000003, + 0x00040048,0x000000f4,0x00000000,0x00000018,0x00050048,0x000000f4,0x00000000,0x00000023, + 0x00000000,0x00030047,0x000000f6,0x00000018,0x00040047,0x000000f6,0x00000021,0x00000003, + 0x00040047,0x000000f6,0x00000022,0x00000000,0x00040047,0x0000034d,0x0000000b,0x0000002a, + 0x00040047,0x00000350,0x0000000b,0x0000002b,0x00040047,0x00000354,0x0000001e,0x00000000, + 0x00040047,0x00000355,0x0000001e,0x00000001,0x00040047,0x00000369,0x00000006,0x00000008, + 0x00030047,0x0000036a,0x00000003,0x00040048,0x0000036a,0x00000000,0x00000018,0x00050048, + 0x0000036a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000036c,0x00000018,0x00040047, + 0x0000036c,0x00000021,0x00000004,0x00040047,0x0000036c,0x00000022,0x00000000,0x00030047, + 0x00000387,0x00000002,0x00050048,0x00000387,0x00000000,0x00000023,0x00000000,0x00050048, + 0x00000387,0x00000001,0x00000023,0x00000004,0x00050048,0x00000387,0x00000002,0x00000023, + 0x00000008,0x00050048,0x00000387,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000387, + 0x00000004,0x00000023,0x00000010,0x00050048,0x00000387,0x00000005,0x00000023,0x00000014, + 0x00050048,0x00000387,0x00000006,0x00000023,0x00000018,0x00050048,0x00000387,0x00000007, + 0x00000023,0x0000001c,0x00050048,0x00000387,0x00000008,0x00000023,0x00000020,0x00050048, + 0x00000387,0x00000009,0x00000023,0x00000030,0x00050048,0x00000387,0x0000000a,0x00000023, + 0x00000038,0x00050048,0x00000387,0x0000000b,0x00000023,0x00000040,0x00050048,0x00000387, + 0x0000000c,0x00000023,0x00000044,0x00050048,0x00000387,0x0000000d,0x00000023,0x00000048, + 0x00050048,0x00000387,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000387,0x0000000f, + 0x00000023,0x00000050,0x00050048,0x00000387,0x00000010,0x00000023,0x00000054,0x00050048, + 0x00000387,0x00000011,0x00000023,0x00000058,0x00050048,0x00000387,0x00000012,0x00000023, + 0x0000005c,0x00050048,0x00000387,0x00000013,0x00000023,0x00000060,0x00050048,0x00000387, + 0x00000014,0x00000023,0x00000064,0x00040047,0x00000389,0x00000021,0x00000000,0x00040047, + 0x00000389,0x00000022,0x00000000,0x00030047,0x00000397,0x00000000,0x00030047,0x00000399, + 0x00000000,0x00030047,0x00000399,0x0000000e,0x00040047,0x00000399,0x0000001e,0x00000004, + 0x00030047,0x0000039f,0x00000000,0x00030047,0x0000039f,0x0000000e,0x00040047,0x0000039f, + 0x0000001e,0x00000006,0x00040047,0x000003ab,0x00000006,0x00000010,0x00030047,0x000003ac, + 0x00000003,0x00040048,0x000003ac,0x00000000,0x00000018,0x00050048,0x000003ac,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000003ae,0x00000018,0x00040047,0x000003ae,0x00000021, + 0x00000005,0x00040047,0x000003ae,0x00000022,0x00000000,0x00040047,0x000003dc,0x0000001e, + 0x00000000,0x00030047,0x0000045f,0x00000002,0x00050048,0x0000045f,0x00000000,0x0000000b, + 0x00000000,0x00050048,0x0000045f,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000045f, + 0x00000002,0x0000000b,0x00000003,0x00050048,0x0000045f,0x00000003,0x0000000b,0x00000004, + 0x00030047,0x00000466,0x00000000,0x00040047,0x00000466,0x00000021,0x0000000a,0x00040047, + 0x00000466,0x00000022,0x00000000,0x00030047,0x00000469,0x00000000,0x00040047,0x00000469, + 0x00000021,0x0000000a,0x00040047,0x00000469,0x00000022,0x00000003,0x00030047,0x000008a8, + 0x00000000,0x00030047,0x000008c7,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040015,0x0000000c,0x00000020,0x00000000, + 0x00040017,0x00000012,0x00000006,0x00000004,0x00040017,0x00000014,0x00000006,0x00000002, + 0x00040018,0x00000015,0x00000014,0x00000002,0x00040015,0x00000031,0x00000020,0x00000001, + 0x00040017,0x00000033,0x00000031,0x00000002,0x00020014,0x0000003d,0x0004002b,0x00000006, + 0x00000055,0x3f800000,0x0004002b,0x00000006,0x00000056,0x00000000,0x0004002b,0x0000000c, + 0x00000061,0x00000000,0x0004002b,0x0000000c,0x00000068,0x000003ff,0x0004002b,0x0000000c, + 0x00000078,0x00000001,0x0004002b,0x00000006,0x00000085,0x38800000,0x0004002b,0x00000031, + 0x0000008b,0x000007ff,0x0004002b,0x00000031,0x0000008e,0x0000000b,0x0004002b,0x0000000c, + 0x000000ad,0x00000002,0x0004002b,0x0000000c,0x000000b1,0x00000003,0x0004002b,0x00000031, + 0x000000b5,0x00000002,0x0004002b,0x00000031,0x000000bb,0x00000003,0x0004002b,0x00000031, + 0x000000c0,0x00000001,0x00040017,0x000000c9,0x0000000c,0x00000004,0x00090019,0x000000cc, + 0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020, + 0x000000cd,0x00000000,0x000000cc,0x0004003b,0x000000cd,0x000000ce,0x00000000,0x0004002b, + 0x00000031,0x000000d3,0x00000000,0x0004002b,0x0000000c,0x000000da,0x0000ffff,0x0003001d, + 0x000000de,0x000000c9,0x0003001e,0x000000df,0x000000de,0x00040020,0x000000e0,0x00000002, + 0x000000df,0x0004003b,0x000000e0,0x000000e1,0x00000002,0x00040020,0x000000e4,0x00000002, + 0x000000c9,0x00040017,0x000000e8,0x0000000c,0x00000002,0x0003001d,0x000000f3,0x000000c9, + 0x0003001e,0x000000f4,0x000000f3,0x00040020,0x000000f5,0x00000002,0x000000f4,0x0004003b, + 0x000000f5,0x000000f6,0x00000002,0x0004002b,0x0000000c,0x000000f8,0x00000004,0x0004002b, + 0x0000000c,0x00000113,0x00800000,0x0004002b,0x0000000c,0x00000133,0x0080ffff,0x0004002b, + 0x0000000c,0x00000154,0xff7fffff,0x0004002b,0x0000000c,0x00000159,0x1c000000,0x0004002b, + 0x0000000c,0x0000015b,0x04000000,0x0004002b,0x00000031,0x0000016b,0x00000010,0x0004002b, + 0x00000006,0x000001b0,0x40490fdb,0x0004002b,0x00000006,0x000001b4,0x40c90fdb,0x0004002b, + 0x00000006,0x000001e9,0x40000000,0x0005002c,0x00000014,0x0000020d,0x00000056,0x00000056, + 0x0004002b,0x0000000c,0x00000223,0x00100000,0x0004002b,0x0000000c,0x0000022b,0x00080000, + 0x0004002b,0x0000000c,0x0000025c,0x08000000,0x0004002b,0x0000000c,0x00000262,0x00400000, + 0x0004002b,0x00000006,0x00000296,0xbf000000,0x0004002b,0x00000006,0x00000297,0x3f000000, + 0x0004002b,0x0000000c,0x000002ae,0x14000000,0x0004002b,0x0000000c,0x000002b4,0x10000000, + 0x0004002b,0x00000006,0x000002b7,0x3e800000,0x0004002b,0x0000000c,0x000002bf,0x02000000, + 0x0004002b,0x0000000c,0x000002d7,0x00200000,0x0004002b,0x00000006,0x000002e2,0x3e000000, + 0x0003002a,0x0000003d,0x00000325,0x0004002b,0x0000000c,0x0000032e,0x80000000,0x00030029, + 0x0000003d,0x00000348,0x00040020,0x0000034c,0x00000001,0x00000031,0x0004003b,0x0000034c, + 0x0000034d,0x00000001,0x0004003b,0x0000034c,0x00000350,0x00000001,0x00040020,0x00000353, + 0x00000001,0x00000012,0x0004003b,0x00000353,0x00000354,0x00000001,0x0004003b,0x00000353, + 0x00000355,0x00000001,0x0003001d,0x00000369,0x000000e8,0x0003001e,0x0000036a,0x00000369, + 0x00040020,0x0000036b,0x00000002,0x0000036a,0x0004003b,0x0000036b,0x0000036c,0x00000002, + 0x00040020,0x0000036e,0x00000002,0x000000e8,0x0004002b,0x0000000c,0x00000374,0x0000000f, + 0x00040017,0x00000386,0x00000031,0x00000004,0x0017001e,0x00000387,0x00000006,0x00000006, + 0x00000006,0x00000006,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x00000386,0x00000014, + 0x00000014,0x0000000c,0x00000006,0x0000000c,0x00000006,0x00000006,0x0000000c,0x00000006, + 0x00000006,0x00000006,0x0000000c,0x00040020,0x00000388,0x00000002,0x00000387,0x0004003b, + 0x00000388,0x00000389,0x00000002,0x0004002b,0x00000031,0x0000038a,0x0000000d,0x00040020, + 0x0000038e,0x00000002,0x0000000c,0x00040020,0x00000398,0x00000003,0x00000014,0x0004003b, + 0x00000398,0x00000399,0x00000003,0x00040020,0x0000039b,0x00000003,0x00000006,0x0004003b, + 0x0000039b,0x0000039f,0x00000003,0x0004002b,0x00000031,0x000003a2,0x00000004,0x0003001d, + 0x000003ab,0x00000012,0x0003001e,0x000003ac,0x000003ab,0x00040020,0x000003ad,0x00000002, + 0x000003ac,0x0004003b,0x000003ad,0x000003ae,0x00000002,0x00040020,0x000003b3,0x00000002, + 0x00000012,0x00040020,0x000003db,0x00000003,0x00000012,0x0004003b,0x000003db,0x000003dc, + 0x00000003,0x0004002b,0x00000006,0x00000414,0x3f666666,0x0004002b,0x00000006,0x0000043c, + 0xc0000000,0x00040020,0x00000448,0x00000002,0x00000006,0x0004002b,0x00000031,0x00000454, + 0x0000000e,0x0004001c,0x0000045e,0x00000006,0x00000078,0x0006001e,0x0000045f,0x00000012, + 0x00000006,0x0000045e,0x0000045e,0x00040020,0x00000460,0x00000003,0x0000045f,0x0004003b, + 0x00000460,0x00000461,0x00000003,0x00090019,0x00000464,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000465,0x00000000,0x00000464, + 0x0004003b,0x00000465,0x00000466,0x00000000,0x0002001a,0x00000467,0x00040020,0x00000468, + 0x00000000,0x00000467,0x0004003b,0x00000468,0x00000469,0x00000000,0x00030001,0x00000014, + 0x00000891,0x00030001,0x0000000c,0x000008ae,0x0004002b,0x00000031,0x000008d3,0xfffffffe, + 0x0004002b,0x00000006,0x000008d4,0xbf800000,0x0004002b,0x00000006,0x000008d5,0x3ea2f983, + 0x0004002b,0x00000006,0x000008d6,0xc0400000,0x00040017,0x000008d9,0x0000003d,0x00000002, + 0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d, + 0x00000031,0x00000351,0x00000350,0x0004003d,0x00000012,0x0000035a,0x00000354,0x0004003d, + 0x00000012,0x0000035c,0x00000355,0x000300f7,0x000006e3,0x00000000,0x000300fb,0x00000061, + 0x000004c3,0x000200f8,0x000004c3,0x00050051,0x00000006,0x000004c5,0x0000035a,0x00000000, + 0x0004006e,0x00000031,0x000004c6,0x000004c5,0x00050051,0x00000006,0x000004c8,0x0000035a, + 0x00000001,0x00050051,0x00000006,0x000004cc,0x0000035a,0x00000003,0x0004007c,0x00000031, + 0x000004cd,0x000004cc,0x000500c3,0x00000031,0x000004ce,0x000004cd,0x000000b5,0x000500c7, + 0x00000031,0x000004d2,0x000004cd,0x000000bb,0x00050082,0x00000031,0x000004d5,0x000004ce, + 0x000000c0,0x0007000c,0x00000031,0x000004d6,0x00000001,0x00000027,0x000004c6,0x000004d5, + 0x00050084,0x00000031,0x000004d9,0x00000351,0x000004ce,0x00050080,0x00000031,0x000004db, + 0x000004d9,0x000004d6,0x0004003d,0x000000cc,0x000004dc,0x000000ce,0x000500c7,0x00000031, + 0x000006e8,0x000004db,0x0000008b,0x000500c3,0x00000031,0x000006ea,0x000004db,0x0000008e, + 0x00050050,0x00000033,0x000006eb,0x000006e8,0x000006ea,0x0007005f,0x000000c9,0x000004df, + 0x000004dc,0x000006eb,0x00000002,0x000000d3,0x00050051,0x0000000c,0x000004e1,0x000004df, + 0x00000003,0x000500c7,0x0000000c,0x000004e3,0x000004e1,0x000000da,0x0007000c,0x0000000c, + 0x000004e4,0x00000001,0x00000029,0x000004e3,0x00000078,0x00050082,0x0000000c,0x000004e6, + 0x000004e4,0x00000078,0x00060041,0x000000e4,0x000004e7,0x000000e1,0x000000d3,0x000004e6, + 0x0004003d,0x000000c9,0x000004e8,0x000004e7,0x0007004f,0x000000e8,0x000004ea,0x000004e8, + 0x000004e8,0x00000000,0x00000001,0x0004007c,0x00000014,0x000004eb,0x000004ea,0x00050051, + 0x0000000c,0x000004ed,0x000004e8,0x00000002,0x000500c7,0x0000000c,0x000004ee,0x000004ed, + 0x000000da,0x00050051,0x0000000c,0x000004f0,0x000004e8,0x00000003,0x00050084,0x0000000c, + 0x000004f2,0x000004ee,0x000000f8,0x00060041,0x000000e4,0x000004f3,0x000000f6,0x000000d3, + 0x000004f2,0x0004003d,0x000000c9,0x000004f4,0x000004f3,0x0004007c,0x00000012,0x000004f5, + 0x000004f4,0x00050051,0x00000006,0x000006f2,0x000004f5,0x00000000,0x00050051,0x00000006, + 0x000006f3,0x000004f5,0x00000001,0x00050051,0x00000006,0x000006f4,0x000004f5,0x00000002, + 0x00050051,0x00000006,0x000006f5,0x000004f5,0x00000003,0x00050050,0x00000014,0x000006f6, + 0x000006f2,0x000006f3,0x00050050,0x00000014,0x000006f7,0x000006f4,0x000006f5,0x00050050, + 0x00000015,0x000006f8,0x000006f6,0x000006f7,0x00050080,0x0000000c,0x000004f9,0x000004f2, + 0x00000078,0x00060041,0x000000e4,0x000004fa,0x000000f6,0x000000d3,0x000004f9,0x0004003d, + 0x000000c9,0x000004fb,0x000004fa,0x0007004f,0x000000e8,0x000004fd,0x000004fb,0x000004fb, + 0x00000000,0x00000001,0x0004007c,0x00000014,0x000004fe,0x000004fd,0x00050051,0x0000000c, + 0x00000500,0x000004fb,0x00000002,0x0004007c,0x00000006,0x00000501,0x00000500,0x00050051, + 0x0000000c,0x00000503,0x000004fb,0x00000003,0x0004007c,0x00000006,0x00000504,0x00000503, + 0x000500c7,0x0000000c,0x00000506,0x000004e1,0x00000113,0x000500ab,0x0000003d,0x00000508, + 0x00000506,0x00000061,0x000300f7,0x00000511,0x00000000,0x000400fa,0x00000508,0x00000509, + 0x00000511,0x000200f8,0x00000509,0x00050051,0x00000006,0x0000050b,0x0000035c,0x00000000, + 0x0004006e,0x00000031,0x0000050c,0x0000050b,0x00050051,0x00000006,0x0000050e,0x0000035c, + 0x00000001,0x000200f9,0x00000511,0x000200f8,0x00000511,0x000700f5,0x00000006,0x000007f2, + 0x000004c8,0x000004c3,0x0000050e,0x00000509,0x000700f5,0x00000031,0x000007d6,0x000004c6, + 0x000004c3,0x0000050c,0x00000509,0x000500ab,0x0000003d,0x00000514,0x000007d6,0x000004d6, + 0x000300f7,0x00000541,0x00000000,0x000400fa,0x00000514,0x00000515,0x00000541,0x000200f8, + 0x00000515,0x00050080,0x00000031,0x00000518,0x000004db,0x000007d6,0x00050082,0x00000031, + 0x0000051a,0x00000518,0x000004d6,0x0004003d,0x000000cc,0x0000051b,0x000000ce,0x000500c7, + 0x00000031,0x000006fc,0x0000051a,0x0000008b,0x000500c3,0x00000031,0x000006fe,0x0000051a, + 0x0000008e,0x00050050,0x00000033,0x000006ff,0x000006fc,0x000006fe,0x0007005f,0x000000c9, + 0x0000051e,0x0000051b,0x000006ff,0x00000002,0x000000d3,0x00050051,0x0000000c,0x00000520, + 0x0000051e,0x00000003,0x000500c7,0x0000000c,0x00000521,0x00000520,0x00000133,0x000500c7, + 0x0000000c,0x00000523,0x000004e1,0x00000133,0x000500ab,0x0000003d,0x00000524,0x00000521, + 0x00000523,0x000300f7,0x0000053b,0x00000000,0x000400fa,0x00000524,0x00000528,0x00000525, + 0x000200f8,0x00000525,0x000200f9,0x0000053b,0x000200f8,0x00000528,0x000500b4,0x0000003d, + 0x0000052a,0x00000501,0x00000056,0x000400a8,0x0000003d,0x0000052b,0x0000052a,0x000300f7, + 0x00000530,0x00000000,0x000400fa,0x0000052b,0x0000052c,0x00000530,0x000200f8,0x0000052c, + 0x00050051,0x00000006,0x0000052e,0x000004eb,0x00000000,0x000500b7,0x0000003d,0x0000052f, + 0x0000052e,0x00000056,0x000200f9,0x00000530,0x000200f8,0x00000530,0x000700f5,0x0000003d, + 0x00000531,0x0000052a,0x00000528,0x0000052f,0x0000052c,0x000300f7,0x0000053a,0x00000000, + 0x000400fa,0x00000531,0x00000533,0x0000053a,0x000200f8,0x00000533,0x0004007c,0x00000031, + 0x00000535,0x000004f0,0x0004003d,0x000000cc,0x00000536,0x000000ce,0x000500c7,0x00000031, + 0x00000703,0x00000535,0x0000008b,0x000500c3,0x00000031,0x00000705,0x00000535,0x0000008e, + 0x00050050,0x00000033,0x00000706,0x00000703,0x00000705,0x0007005f,0x000000c9,0x00000539, + 0x00000536,0x00000706,0x00000002,0x000000d3,0x000200f9,0x0000053a,0x000200f8,0x0000053a, + 0x000700f5,0x00000031,0x000007e3,0x000004db,0x00000530,0x00000535,0x00000533,0x000700f5, + 0x000000c9,0x000007db,0x000004df,0x00000530,0x00000539,0x00000533,0x000200f9,0x0000053b, + 0x000200f8,0x0000053b,0x000700f5,0x00000031,0x000007e2,0x0000051a,0x00000525,0x000007e3, + 0x0000053a,0x000700f5,0x000000c9,0x000007da,0x0000051e,0x00000525,0x000007db,0x0000053a, + 0x00050051,0x0000000c,0x0000053d,0x000007da,0x00000003,0x000500c7,0x0000000c,0x0000053e, + 0x0000053d,0x00000154,0x000500c5,0x0000000c,0x00000540,0x0000053e,0x00000506,0x000200f9, + 0x00000541,0x000200f8,0x00000541,0x000700f5,0x00000031,0x000007e1,0x000004db,0x00000511, + 0x000007e2,0x0000053b,0x000700f5,0x000000c9,0x000007df,0x000004df,0x00000511,0x000007da, + 0x0000053b,0x000700f5,0x0000000c,0x000007de,0x000004e1,0x00000511,0x00000540,0x0000053b, + 0x000500c7,0x0000000c,0x00000543,0x000007de,0x00000159,0x000500aa,0x0000003d,0x00000544, + 0x00000543,0x0000015b,0x000500aa,0x0000003d,0x00000546,0x000004d2,0x000000d3,0x000500a7, + 0x0000003d,0x00000547,0x00000544,0x00000546,0x000300f7,0x000005d2,0x00000000,0x000400fa, + 0x00000547,0x0000054c,0x00000548,0x000200f8,0x00000548,0x00050051,0x0000000c,0x0000054a, + 0x000007df,0x00000002,0x0004007c,0x00000006,0x0000054b,0x0000054a,0x000200f9,0x000005d2, + 0x000200f8,0x0000054c,0x00050051,0x0000000c,0x0000054e,0x000007df,0x00000002,0x000500c7, + 0x0000000c,0x00000550,0x0000054e,0x000000da,0x00040070,0x00000006,0x00000551,0x00000550, + 0x000500c2,0x0000000c,0x00000553,0x0000054e,0x0000016b,0x00040070,0x00000006,0x00000554, + 0x00000553,0x00050083,0x00000006,0x00000557,0x000008d4,0x00000551,0x0004006e,0x00000031, + 0x00000558,0x00000557,0x00050083,0x00000006,0x0000055b,0x00000554,0x00000551,0x00050081, + 0x00000006,0x0000055c,0x0000055b,0x00000055,0x0004006e,0x00000031,0x0000055d,0x0000055c, + 0x00050050,0x00000033,0x0000055e,0x00000558,0x0000055d,0x000500c7,0x0000000c,0x00000560, + 0x000007de,0x00000113,0x000500ab,0x0000003d,0x00000561,0x00000560,0x00000061,0x000300f7, + 0x00000565,0x00000000,0x000400fa,0x00000561,0x00000562,0x00000565,0x000200f8,0x00000562, + 0x0004007e,0x00000033,0x00000564,0x0000055e,0x000200f9,0x00000565,0x000200f8,0x00000565, + 0x000700f5,0x00000033,0x000007e5,0x0000055e,0x0000054c,0x00000564,0x00000562,0x0004003d, + 0x000000cc,0x00000566,0x000000ce,0x00050051,0x00000031,0x00000569,0x000007e5,0x00000000, + 0x00050080,0x00000031,0x0000056a,0x000007e1,0x00000569,0x000500c7,0x00000031,0x0000070a, + 0x0000056a,0x0000008b,0x000500c3,0x00000031,0x0000070c,0x0000056a,0x0000008e,0x00050050, + 0x00000033,0x0000070d,0x0000070a,0x0000070c,0x0007005f,0x000000c9,0x0000056c,0x00000566, + 0x0000070d,0x00000002,0x000000d3,0x0004003d,0x000000cc,0x0000056d,0x000000ce,0x00050051, + 0x00000031,0x00000570,0x000007e5,0x00000001,0x00050080,0x00000031,0x00000571,0x000007e1, + 0x00000570,0x000500c7,0x00000031,0x00000711,0x00000571,0x0000008b,0x000500c3,0x00000031, + 0x00000713,0x00000571,0x0000008e,0x00050050,0x00000033,0x00000714,0x00000711,0x00000713, + 0x0007005f,0x000000c9,0x00000573,0x0000056d,0x00000714,0x00000002,0x000000d3,0x00050051, + 0x0000000c,0x00000575,0x00000573,0x00000003,0x000500c7,0x0000000c,0x00000576,0x00000575, + 0x00000133,0x00050051,0x0000000c,0x00000578,0x0000056c,0x00000003,0x000500c7,0x0000000c, + 0x00000579,0x00000578,0x00000133,0x000500ab,0x0000003d,0x0000057a,0x00000576,0x00000579, + 0x000300f7,0x00000581,0x00000000,0x000400fa,0x0000057a,0x0000057b,0x00000581,0x000200f8, + 0x0000057b,0x0004003d,0x000000cc,0x0000057c,0x000000ce,0x0004007c,0x00000031,0x0000057e, + 0x000004f0,0x000500c7,0x00000031,0x00000718,0x0000057e,0x0000008b,0x000500c3,0x00000031, + 0x0000071a,0x0000057e,0x0000008e,0x00050050,0x00000033,0x0000071b,0x00000718,0x0000071a, + 0x0007005f,0x000000c9,0x00000580,0x0000057c,0x0000071b,0x00000002,0x000000d3,0x000200f9, + 0x00000581,0x000200f8,0x00000581,0x000700f5,0x000000c9,0x000007e6,0x00000573,0x00000565, + 0x00000580,0x0000057b,0x00050051,0x0000000c,0x00000583,0x0000056c,0x00000002,0x0004007c, + 0x00000006,0x00000584,0x00000583,0x00050051,0x0000000c,0x00000586,0x000007e6,0x00000002, + 0x0004007c,0x00000006,0x00000587,0x00000586,0x00050083,0x00000006,0x0000058a,0x00000587, + 0x00000584,0x0006000c,0x00000006,0x0000058c,0x00000001,0x00000004,0x0000058a,0x000500ba, + 0x0000003d,0x0000058d,0x0000058c,0x000001b0,0x000300f7,0x00000594,0x00000000,0x000400fa, + 0x0000058d,0x0000058e,0x00000594,0x000200f8,0x0000058e,0x0006000c,0x00000006,0x00000590, + 0x00000001,0x00000006,0x0000058a,0x00050085,0x00000006,0x00000591,0x000001b4,0x00000590, + 0x00050083,0x00000006,0x00000593,0x0000058a,0x00000591,0x000200f9,0x00000594,0x000200f8, + 0x00000594,0x000700f5,0x00000006,0x000007ea,0x0000058a,0x00000581,0x00000593,0x0000058e, + 0x00050081,0x00000006,0x00000597,0x00000554,0x0000043c,0x0006000c,0x00000006,0x00000599, + 0x00000001,0x00000004,0x000007ea,0x00050085,0x00000006,0x0000059a,0x00000599,0x000008d5, + 0x00050085,0x00000006,0x0000059c,0x0000059a,0x00000597,0x0006000c,0x00000006,0x0000059d, + 0x00000001,0x00000001,0x0000059c,0x00050081,0x00000006,0x0000059f,0x00000554,0x000008d6, + 0x0008000c,0x00000006,0x000005a0,0x00000001,0x0000002b,0x0000059d,0x00000055,0x0000059f, + 0x00050083,0x00000006,0x000005a3,0x00000597,0x000005a0,0x000500bc,0x0000003d,0x000005a6, + 0x00000551,0x000005a3,0x000300f7,0x000005c3,0x00000000,0x000400fa,0x000005a6,0x000005b4, + 0x000005a7,0x000200f8,0x000005a7,0x00050081,0x00000006,0x000005aa,0x000005a3,0x00000055, + 0x000500b4,0x0000003d,0x000005ab,0x00000551,0x000005aa,0x000300f7,0x000005b3,0x00000000, + 0x000400fa,0x000005ab,0x000005b2,0x000005ac,0x000200f8,0x000005ac,0x00050081,0x00000006, + 0x000005ae,0x000005a3,0x000001e9,0x00050083,0x00000006,0x000005b0,0x00000551,0x000005ae, + 0x000200f9,0x000005b3,0x000200f8,0x000005b2,0x000200f9,0x000005b3,0x000200f8,0x000005b3, + 0x000700f5,0x00000006,0x000007f7,0x000005b0,0x000005ac,0x00000056,0x000005b2,0x000600a9, + 0x00000006,0x000008d7,0x000005ab,0x00000056,0x000007f2,0x000600a9,0x00000006,0x000008d8, + 0x000005ab,0x00000056,0x000005a0,0x000200f9,0x000005c3,0x000200f8,0x000005b4,0x0006000c, + 0x00000006,0x000005b6,0x00000001,0x00000006,0x000007ea,0x00050085,0x00000006,0x000005b7, + 0x000001b0,0x000005b6,0x00050083,0x00000006,0x000005b9,0x000005b7,0x000007ea,0x0004007f, + 0x00000006,0x000005ba,0x000005b9,0x000500b4,0x0000003d,0x000005be,0x00000551,0x000005a3, + 0x000300f7,0x000005c2,0x00000000,0x000400fa,0x000005be,0x000005bf,0x000005c2,0x000200f8, + 0x000005bf,0x0004007f,0x00000006,0x000005c1,0x000007f2,0x000200f9,0x000005c2,0x000200f8, + 0x000005c2,0x000700f5,0x00000006,0x00000832,0x000007f2,0x000005b4,0x000005c1,0x000005bf, + 0x000200f9,0x000005c3,0x000200f8,0x000005c3,0x000700f5,0x00000006,0x00000830,0x000008d7, + 0x000005b3,0x00000832,0x000005c2,0x000700f5,0x00000006,0x000007fc,0x000007ea,0x000005b3, + 0x000005ba,0x000005c2,0x000700f5,0x00000006,0x000007f9,0x000008d8,0x000005b3,0x000005a3, + 0x000005c2,0x000700f5,0x00000006,0x000007f6,0x000007f7,0x000005b3,0x00000551,0x000005c2, + 0x000500b4,0x0000003d,0x000005c6,0x000007f6,0x000007f9,0x000300f7,0x000005d1,0x00000000, + 0x000400fa,0x000005c6,0x000005cf,0x000005c7,0x000200f8,0x000005c7,0x00050088,0x00000006, + 0x000005cc,0x000007f6,0x000007f9,0x00050085,0x00000006,0x000005cd,0x000007fc,0x000005cc, + 0x00050081,0x00000006,0x000005ce,0x00000584,0x000005cd,0x000200f9,0x000005d1,0x000200f8, + 0x000005cf,0x000200f9,0x000005d1,0x000200f8,0x000005d1,0x000700f5,0x00000006,0x00000800, + 0x000005ce,0x000005c7,0x00000587,0x000005cf,0x000200f9,0x000005d2,0x000200f8,0x000005d2, + 0x000700f5,0x00000006,0x0000082e,0x000007f2,0x00000548,0x00000830,0x000005d1,0x000700f5, + 0x00000006,0x000007ff,0x0000054b,0x00000548,0x00000800,0x000005d1,0x0006000c,0x00000006, + 0x000005d4,0x00000001,0x0000000d,0x000007ff,0x0006000c,0x00000006,0x000005d6,0x00000001, + 0x0000000e,0x000007ff,0x0004007f,0x00000006,0x000005d7,0x000005d6,0x00050050,0x00000014, + 0x000005d8,0x000005d4,0x000005d7,0x0007004f,0x000000e8,0x000005da,0x000007df,0x000007df, + 0x00000000,0x00000001,0x0004007c,0x00000014,0x000005db,0x000005da,0x000500b7,0x0000003d, + 0x000005dd,0x00000504,0x00000056,0x000300f7,0x000005e6,0x00000000,0x000400fa,0x000005dd, + 0x000005de,0x000005e6,0x000200f8,0x000005de,0x00050091,0x00000014,0x000005e2,0x000006f8, + 0x000005d8,0x0006000c,0x00000006,0x000005e3,0x00000001,0x00000042,0x000005e2,0x00050088, + 0x00000006,0x000005e4,0x00000055,0x000005e3,0x0007000c,0x00000006,0x000005e5,0x00000001, + 0x00000028,0x00000504,0x000005e4,0x000200f9,0x000005e6,0x000200f8,0x000005e6,0x000700f5, + 0x00000006,0x00000837,0x00000504,0x000005d2,0x000005e5,0x000005de,0x000500b7,0x0000003d, + 0x000005e8,0x00000501,0x00000056,0x000300f7,0x000006d3,0x00000000,0x000400fa,0x000005e8, + 0x000005f7,0x000005e9,0x000200f8,0x000005e9,0x000500aa,0x0000003d,0x000005eb,0x000004d2, + 0x000000b5,0x00050050,0x000008d9,0x000008da,0x000005eb,0x000005eb,0x000600a9,0x00000014, + 0x000008db,0x000008da,0x000004eb,0x000005db,0x000500c7,0x0000000c,0x000005f0,0x000007de, + 0x0000032e,0x000500ab,0x0000003d,0x000005f1,0x000005f0,0x00000061,0x000500ab,0x0000003d, + 0x000005f3,0x000004d2,0x000000c0,0x000500a7,0x0000003d,0x000005f4,0x000005f1,0x000005f3, + 0x000300f7,0x000005f6,0x00000000,0x000400fa,0x000005f4,0x000005f5,0x000005f6,0x000200f8, + 0x000005f5,0x000200f9,0x000006e3,0x000200f8,0x000005f6,0x000200f9,0x000006d3,0x000200f8, + 0x000005f7,0x0006000c,0x00000006,0x000005f9,0x00000001,0x00000021,0x000006f8,0x0006000c, + 0x00000006,0x000005fa,0x00000001,0x00000006,0x000005f9,0x00050085,0x00000006,0x000005fc, + 0x0000082e,0x000005fa,0x000500c7,0x0000000c,0x000005fe,0x000007de,0x00000223,0x000500ab, + 0x0000003d,0x000005ff,0x000005fe,0x00000061,0x000300f7,0x00000603,0x00000000,0x000400fa, + 0x000005ff,0x00000600,0x00000603,0x000200f8,0x00000600,0x0007000c,0x00000006,0x00000602, + 0x00000001,0x00000025,0x000005fc,0x00000056,0x000200f9,0x00000603,0x000200f8,0x00000603, + 0x000700f5,0x00000006,0x00000834,0x000005fc,0x000005f7,0x00000602,0x00000600,0x000500c7, + 0x0000000c,0x00000605,0x000007de,0x0000022b,0x000500ab,0x0000003d,0x00000606,0x00000605, + 0x00000061,0x000300f7,0x0000060a,0x00000000,0x000400fa,0x00000606,0x00000607,0x0000060a, + 0x000200f8,0x00000607,0x0007000c,0x00000006,0x00000609,0x00000001,0x00000028,0x00000834, + 0x00000056,0x000200f9,0x0000060a,0x000200f8,0x0000060a,0x000700f5,0x00000006,0x0000086d, + 0x00000834,0x00000603,0x00000609,0x00000607,0x000500b7,0x0000003d,0x0000060c,0x00000837, + 0x00000056,0x000600a9,0x00000006,0x000008dc,0x0000060c,0x00000837,0x00000056,0x000500ba, + 0x0000003d,0x00000618,0x000008dc,0x00000501,0x000500b4,0x0000003d,0x0000061a,0x00000837, + 0x00000056,0x000500a7,0x0000003d,0x0000061b,0x00000618,0x0000061a,0x000600a9,0x00000006, + 0x000008dd,0x0000061b,0x000008dc,0x00000501,0x00050081,0x00000006,0x00000627,0x000008dd, + 0x000008dc,0x0005008e,0x00000014,0x00000628,0x000005d8,0x00000627,0x000500ac,0x0000003d, + 0x0000062c,0x00000543,0x0000025c,0x000300f7,0x000006c9,0x00000000,0x000400fa,0x0000062c, + 0x0000062d,0x000006c9,0x000200f8,0x0000062d,0x000500c7,0x0000000c,0x0000062f,0x000007de, + 0x00000262,0x000500aa,0x0000003d,0x00000630,0x0000062f,0x00000061,0x000600a9,0x00000031, + 0x000008de,0x00000630,0x000008d3,0x000000b5,0x000500c7,0x0000000c,0x00000636,0x000007de, + 0x00000113,0x000500ab,0x0000003d,0x00000637,0x00000636,0x00000061,0x000300f7,0x0000063b, + 0x00000000,0x000400fa,0x00000637,0x00000638,0x0000063b,0x000200f8,0x00000638,0x0004007e, + 0x00000031,0x0000063a,0x000008de,0x000200f9,0x0000063b,0x000200f8,0x0000063b,0x000700f5, + 0x00000031,0x00000851,0x000008de,0x0000062d,0x0000063a,0x00000638,0x00050080,0x00000031, + 0x0000063e,0x000007e1,0x00000851,0x000500c7,0x00000031,0x0000073b,0x0000063e,0x0000008b, + 0x000500c3,0x00000031,0x0000073d,0x0000063e,0x0000008e,0x00050050,0x00000033,0x0000073e, + 0x0000073b,0x0000073d,0x0004003d,0x000000cc,0x00000640,0x000000ce,0x0007005f,0x000000c9, + 0x00000642,0x00000640,0x0000073e,0x00000002,0x000000d3,0x00050051,0x0000000c,0x00000644, + 0x00000642,0x00000002,0x0004007c,0x00000006,0x00000645,0x00000644,0x00050083,0x00000006, + 0x00000648,0x00000645,0x000007ff,0x0006000c,0x00000006,0x00000649,0x00000001,0x00000004, + 0x00000648,0x000500ba,0x0000003d,0x0000064b,0x00000649,0x000001b0,0x000300f7,0x0000064f, + 0x00000000,0x000400fa,0x0000064b,0x0000064c,0x0000064f,0x000200f8,0x0000064c,0x00050083, + 0x00000006,0x0000064e,0x000001b4,0x00000649,0x000200f9,0x0000064f,0x000200f8,0x0000064f, + 0x000700f5,0x00000006,0x0000085b,0x00000649,0x0000063b,0x0000064e,0x0000064c,0x000500ab, + 0x0000003d,0x00000652,0x0000062f,0x00000061,0x000500a4,0x0000003d,0x00000659,0x00000652, + 0x000005ff,0x000600a9,0x00000006,0x0000065a,0x00000659,0x00000296,0x00000297,0x00050085, + 0x00000006,0x0000065b,0x0000085b,0x0000065a,0x00050081,0x00000006,0x0000065d,0x0000065b, + 0x000007ff,0x0006000c,0x00000006,0x0000065f,0x00000001,0x0000000d,0x0000065d,0x0006000c, + 0x00000006,0x00000661,0x00000001,0x0000000e,0x0000065d,0x0004007f,0x00000006,0x00000662, + 0x00000661,0x00050050,0x00000014,0x00000663,0x0000065f,0x00000662,0x00050091,0x00000014, + 0x00000744,0x000006f8,0x00000663,0x00050051,0x00000006,0x00000746,0x00000744,0x00000000, + 0x0006000c,0x00000006,0x00000747,0x00000001,0x00000004,0x00000746,0x00050051,0x00000006, + 0x00000749,0x00000744,0x00000001,0x0006000c,0x00000006,0x0000074a,0x00000001,0x00000004, + 0x00000749,0x00050081,0x00000006,0x0000074b,0x00000747,0x0000074a,0x00050094,0x00000006, + 0x0000074e,0x00000744,0x00000744,0x00050088,0x00000006,0x0000074f,0x00000055,0x0000074e, + 0x00050085,0x00000006,0x00000750,0x0000074b,0x0000074f,0x00050085,0x00000006,0x00000668, + 0x0000085b,0x00000297,0x0006000c,0x00000006,0x00000669,0x00000001,0x0000000e,0x00000668, + 0x000500aa,0x0000003d,0x0000066b,0x00000543,0x000002ae,0x000400a8,0x0000003d,0x0000066c, + 0x0000066b,0x000300f7,0x00000673,0x00000000,0x000400fa,0x0000066c,0x0000066d,0x00000673, + 0x000200f8,0x0000066d,0x000500aa,0x0000003d,0x0000066f,0x00000543,0x000002b4,0x000500be, + 0x0000003d,0x00000671,0x00000669,0x000002b7,0x000500a7,0x0000003d,0x00000672,0x0000066f, + 0x00000671,0x000200f9,0x00000673,0x000200f8,0x00000673,0x000700f5,0x0000003d,0x00000674, + 0x0000066b,0x0000064f,0x00000672,0x0000066d,0x000300f7,0x00000687,0x00000000,0x000400fa, + 0x00000674,0x0000067c,0x00000675,0x000200f8,0x00000675,0x00050085,0x00000006,0x00000678, + 0x000008dd,0x00000669,0x00050085,0x00000006,0x0000067a,0x00000750,0x00000297,0x00050081, + 0x00000006,0x0000067b,0x00000678,0x0000067a,0x000200f9,0x00000687,0x000200f8,0x0000067c, + 0x000500c7,0x0000000c,0x0000067e,0x000007de,0x000002bf,0x000500ab,0x0000003d,0x0000067f, + 0x0000067e,0x00000061,0x000600a9,0x00000006,0x00000680,0x0000067f,0x00000055,0x000002b7, + 0x0007000c,0x00000006,0x00000684,0x00000001,0x00000028,0x00000669,0x00000680,0x00050088, + 0x00000006,0x00000685,0x00000055,0x00000684,0x00050085,0x00000006,0x00000686,0x000008dd, + 0x00000685,0x000200f9,0x00000687,0x000200f8,0x00000687,0x000700f5,0x00000006,0x00000862, + 0x0000067b,0x00000675,0x00000686,0x0000067c,0x000500c7,0x0000000c,0x0000068d,0x000007de, + 0x000002d7,0x000500ab,0x0000003d,0x0000068e,0x0000068d,0x00000061,0x000300f7,0x000006bc, + 0x00000000,0x000400fa,0x0000068e,0x0000068f,0x000006bc,0x000200f8,0x0000068f,0x00050085, + 0x00000006,0x00000694,0x000008dc,0x000002e2,0x00050085,0x00000006,0x00000698,0x00000862, + 0x00000669,0x00050081,0x00000006,0x0000069a,0x00000698,0x00000694,0x000500bc,0x0000003d, + 0x0000069b,0x00000627,0x0000069a,0x000300f7,0x000006bb,0x00000000,0x000400fa,0x0000069b, + 0x000006b3,0x0000069c,0x000200f8,0x0000069c,0x0005008e,0x00000014,0x0000069f,0x00000663, + 0x00000862,0x00050094,0x00000006,0x000006a2,0x00000628,0x00000628,0x00050094,0x00000006, + 0x000006a5,0x0000069f,0x0000069f,0x00050050,0x00000014,0x000006a6,0x000006a2,0x000006a5, + 0x00050050,0x00000015,0x000006b0,0x00000628,0x0000069f,0x0006000c,0x00000015,0x000006b1, + 0x00000001,0x00000022,0x000006b0,0x00050090,0x00000014,0x000006b2,0x000006a6,0x000006b1, + 0x000200f9,0x000006bb,0x000200f8,0x000006b3,0x00050088,0x00000006,0x000006b6,0x00000055, + 0x00000669,0x00050085,0x00000006,0x000006b7,0x00000627,0x000006b6,0x0005008e,0x00000014, + 0x000006ba,0x00000663,0x000006b7,0x000200f9,0x000006bb,0x000200f8,0x000006bb,0x000700f5, + 0x00000014,0x00000877,0x000006b2,0x0000069c,0x000006ba,0x000006b3,0x000200f9,0x000006bc, + 0x000200f8,0x000006bc,0x000700f5,0x00000014,0x00000876,0x00000628,0x00000687,0x00000877, + 0x000006bb,0x000200f9,0x000006c9,0x000200f8,0x000006c9,0x000700f5,0x00000014,0x00000875, + 0x00000628,0x0000060a,0x00000876,0x000006bc,0x0005008e,0x00000014,0x000006cd,0x00000875, + 0x0000086d,0x00050091,0x00000014,0x000006ce,0x000006f8,0x000006cd,0x000500ab,0x0000003d, + 0x000006d0,0x000004d2,0x000000d3,0x000300f7,0x000006d2,0x00000000,0x000400fa,0x000006d0, + 0x000006d1,0x000006d2,0x000200f8,0x000006d1,0x000200f9,0x000006e3,0x000200f8,0x000006d2, + 0x000200f9,0x000006d3,0x000200f8,0x000006d3,0x000700f5,0x00000014,0x00000887,0x0000020d, + 0x000005f6,0x000006ce,0x000006d2,0x000700f5,0x00000014,0x00000878,0x000008db,0x000005f6, + 0x000005db,0x000006d2,0x00050091,0x00000014,0x000006d6,0x000006f8,0x00000878,0x00050081, + 0x00000014,0x000006d8,0x000006d6,0x00000887,0x00050081,0x00000014,0x000006da,0x000006d8, + 0x000004fe,0x00050080,0x0000000c,0x000006dd,0x000004f2,0x000000ad,0x00060041,0x000000e4, + 0x000006de,0x000000f6,0x000000d3,0x000006dd,0x0004003d,0x000000c9,0x000006df,0x000006de, + 0x00050051,0x0000000c,0x000006e1,0x000006df,0x00000000,0x000200f9,0x000006e3,0x000200f8, + 0x000006e3,0x000900f5,0x0000000c,0x000008a8,0x000008ae,0x000005f5,0x000008ae,0x000006d1, + 0x000006e1,0x000006d3,0x000900f5,0x00000014,0x0000088b,0x00000891,0x000005f5,0x00000891, + 0x000006d1,0x000006da,0x000006d3,0x000900f5,0x0000003d,0x0000088a,0x00000325,0x000005f5, + 0x00000325,0x000006d1,0x00000348,0x000006d3,0x00060041,0x0000036e,0x0000036f,0x0000036c, + 0x000000d3,0x000004ee,0x0004003d,0x000000e8,0x00000370,0x0000036f,0x00050051,0x0000000c, + 0x00000373,0x00000370,0x00000000,0x000500c7,0x0000000c,0x00000375,0x00000373,0x00000374, + 0x000500aa,0x0000003d,0x0000037a,0x00000375,0x00000061,0x000300f7,0x0000037d,0x00000000, + 0x000400fa,0x0000037a,0x0000037c,0x00000380,0x000200f8,0x00000380,0x000200f9,0x0000037d, + 0x000200f8,0x0000037c,0x00050051,0x0000000c,0x0000037f,0x00000370,0x00000001,0x000200f9, + 0x0000037d,0x000200f8,0x0000037d,0x000700f5,0x0000000c,0x000008c5,0x00000373,0x00000380, + 0x0000037f,0x0000037c,0x000500c2,0x0000000c,0x00000384,0x000008c5,0x0000016b,0x00050041, + 0x0000038e,0x0000038f,0x00000389,0x0000038a,0x0004003d,0x0000000c,0x00000390,0x0000038f, + 0x000500aa,0x0000003d,0x0000075b,0x00000384,0x00000061,0x000300f7,0x00000764,0x00000000, + 0x000400fa,0x0000075b,0x00000763,0x0000075c,0x000200f8,0x0000075c,0x00050080,0x0000000c, + 0x0000075e,0x00000384,0x00000068,0x00050084,0x0000000c,0x00000760,0x0000075e,0x00000390, + 0x0006000c,0x00000014,0x00000761,0x00000001,0x0000003e,0x00000760,0x00050051,0x00000006, + 0x00000762,0x00000761,0x00000000,0x000200f9,0x00000764,0x000200f8,0x00000763,0x000200f9, + 0x00000764,0x000200f8,0x00000764,0x000700f5,0x00000006,0x000008c6,0x00000762,0x0000075c, + 0x00000056,0x00000763,0x000300f7,0x00000395,0x00000000,0x000400fa,0x0000037a,0x00000394, + 0x00000395,0x000200f8,0x00000394,0x0004007f,0x00000006,0x00000397,0x000008c6,0x000200f9, + 0x00000395,0x000200f8,0x00000395,0x000700f5,0x00000006,0x000008c7,0x000008c6,0x00000764, + 0x00000397,0x00000394,0x00050041,0x0000039b,0x0000039c,0x00000399,0x00000061,0x0003003e, + 0x0000039c,0x000008c7,0x000500c2,0x0000000c,0x000003a3,0x00000373,0x000003a2,0x000500c7, + 0x0000000c,0x000003a4,0x000003a3,0x00000374,0x00040070,0x00000006,0x000003a5,0x000003a4, + 0x0003003e,0x0000039f,0x000003a5,0x000500aa,0x0000003d,0x000003c6,0x00000375,0x00000078, + 0x000300f7,0x000003c8,0x00000000,0x000400fa,0x000003c6,0x000003c7,0x000003de,0x000200f8, + 0x000003de,0x000300f7,0x000003e3,0x00000000,0x000400fa,0x0000037a,0x000003e2,0x000003ef, + 0x000200f8,0x000003ef,0x00060041,0x000003b3,0x000003f4,0x000003ae,0x000000d3,0x000004f2, + 0x0004003d,0x00000012,0x000003f5,0x000003f4,0x00050051,0x00000006,0x0000077b,0x000003f5, + 0x00000000,0x00050051,0x00000006,0x0000077c,0x000003f5,0x00000001,0x00050051,0x00000006, + 0x0000077d,0x000003f5,0x00000002,0x00050051,0x00000006,0x0000077e,0x000003f5,0x00000003, + 0x00050050,0x00000014,0x0000077f,0x0000077b,0x0000077c,0x00050050,0x00000014,0x00000780, + 0x0000077d,0x0000077e,0x00050050,0x00000015,0x00000781,0x0000077f,0x00000780,0x00060041, + 0x000003b3,0x000003fb,0x000003ae,0x000000d3,0x000004f9,0x0004003d,0x00000012,0x000003fc, + 0x000003fb,0x00050091,0x00000014,0x00000400,0x00000781,0x0000088b,0x0007004f,0x00000014, + 0x00000402,0x000003fc,0x000003fc,0x00000000,0x00000001,0x00050081,0x00000014,0x00000403, + 0x00000400,0x00000402,0x000500aa,0x0000003d,0x00000405,0x00000375,0x000000ad,0x000500aa, + 0x0000003d,0x00000407,0x00000375,0x000000b1,0x000500a6,0x0000003d,0x00000408,0x00000405, + 0x00000407,0x000300f7,0x0000040a,0x00000000,0x000400fa,0x00000408,0x00000409,0x0000042f, + 0x000200f8,0x0000042f,0x00050051,0x0000000c,0x00000432,0x00000370,0x00000001,0x0004007c, + 0x00000006,0x00000433,0x00000432,0x00050051,0x00000006,0x00000436,0x000003fc,0x00000002, + 0x00050051,0x00000006,0x00000438,0x00000403,0x00000000,0x00050051,0x00000006,0x0000043a, + 0x00000403,0x00000001,0x00050083,0x00000006,0x0000043e,0x0000043c,0x00000436,0x00070050, + 0x00000012,0x0000043f,0x00000438,0x0000043a,0x00000433,0x0000043e,0x0003003e,0x000003dc, + 0x0000043f,0x000200f9,0x0000040a,0x000200f8,0x00000409,0x00050051,0x0000000c,0x0000040c, + 0x00000370,0x00000001,0x0004007c,0x00000006,0x0000040d,0x0000040c,0x0004007f,0x00000006, + 0x0000040e,0x0000040d,0x00050041,0x0000039b,0x0000040f,0x000003dc,0x000000b1,0x0003003e, + 0x0000040f,0x0000040e,0x00050051,0x00000006,0x00000412,0x000003fc,0x00000002,0x000500ba, + 0x0000003d,0x00000415,0x00000412,0x00000414,0x000300f7,0x00000417,0x00000000,0x000400fa, + 0x00000415,0x00000416,0x00000419,0x000200f8,0x00000419,0x00050051,0x00000006,0x0000041b, + 0x000003fc,0x00000003,0x00050041,0x0000039b,0x0000041c,0x000003dc,0x000000ad,0x0003003e, + 0x0000041c,0x0000041b,0x000200f9,0x00000417,0x000200f8,0x00000416,0x00050041,0x0000039b, + 0x00000418,0x000003dc,0x000000ad,0x0003003e,0x00000418,0x000001e9,0x000200f9,0x00000417, + 0x000200f8,0x00000417,0x000300f7,0x00000420,0x00000000,0x000400fa,0x00000405,0x0000041f, + 0x00000425,0x000200f8,0x00000425,0x00050041,0x0000039b,0x00000426,0x000003dc,0x000000ad, + 0x0004003d,0x00000006,0x00000427,0x00000426,0x0004007f,0x00000006,0x00000428,0x00000427, + 0x0003003e,0x00000426,0x00000428,0x00050041,0x0000039b,0x0000042b,0x000003dc,0x00000061, + 0x00050051,0x00000006,0x0000042c,0x00000403,0x00000000,0x0003003e,0x0000042b,0x0000042c, + 0x00050041,0x0000039b,0x0000042d,0x000003dc,0x00000078,0x00050051,0x00000006,0x0000042e, + 0x00000403,0x00000001,0x0003003e,0x0000042d,0x0000042e,0x000200f9,0x00000420,0x000200f8, + 0x0000041f,0x00050041,0x0000039b,0x00000421,0x000003dc,0x00000078,0x0003003e,0x00000421, + 0x00000056,0x00050051,0x00000006,0x00000423,0x00000403,0x00000000,0x00050041,0x0000039b, + 0x00000424,0x000003dc,0x00000061,0x0003003e,0x00000424,0x00000423,0x000200f9,0x00000420, + 0x000200f8,0x00000420,0x000200f9,0x0000040a,0x000200f8,0x0000040a,0x000200f9,0x000003e3, + 0x000200f8,0x000003e2,0x000500c2,0x0000000c,0x000003e7,0x00000373,0x0000016b,0x000500aa, + 0x0000003d,0x00000787,0x000003e7,0x00000061,0x000300f7,0x00000790,0x00000000,0x000400fa, + 0x00000787,0x0000078f,0x00000788,0x000200f8,0x00000788,0x00050080,0x0000000c,0x0000078a, + 0x000003e7,0x00000068,0x00050084,0x0000000c,0x0000078c,0x0000078a,0x00000390,0x0006000c, + 0x00000014,0x0000078d,0x00000001,0x0000003e,0x0000078c,0x00050051,0x00000006,0x0000078e, + 0x0000078d,0x00000000,0x000200f9,0x00000790,0x000200f8,0x0000078f,0x000200f9,0x00000790, + 0x000200f8,0x00000790,0x000700f5,0x00000006,0x000008c8,0x0000078e,0x00000788,0x00000056, + 0x0000078f,0x00050041,0x0000039b,0x000003ee,0x00000399,0x00000078,0x0003003e,0x000003ee, + 0x000008c8,0x000200f9,0x000003e3,0x000200f8,0x000003e3,0x000200f9,0x000003c8,0x000200f8, + 0x000003c7,0x00050051,0x0000000c,0x000003cb,0x00000370,0x00000001,0x0006000c,0x00000012, + 0x000003cc,0x00000001,0x00000040,0x000003cb,0x0003003e,0x000003dc,0x000003cc,0x000200f9, + 0x000003c8,0x000200f8,0x000003c8,0x000300f7,0x00000443,0x00000000,0x000400fa,0x0000088a, + 0x00000442,0x00000453,0x000200f8,0x00000453,0x00050041,0x00000448,0x00000455,0x00000389, + 0x00000454,0x0004003d,0x00000006,0x00000456,0x00000455,0x00070050,0x00000012,0x0000045d, + 0x00000456,0x00000456,0x00000456,0x00000456,0x000200f9,0x00000443,0x000200f8,0x00000442, + 0x00050041,0x00000448,0x00000449,0x00000389,0x000000b5,0x0004003d,0x00000006,0x0000044a, + 0x00000449,0x00050041,0x00000448,0x0000044c,0x00000389,0x000000bb,0x0004003d,0x00000006, + 0x0000044d,0x0000044c,0x00050051,0x00000006,0x00000796,0x0000088b,0x00000000,0x00050085, + 0x00000006,0x00000798,0x00000796,0x0000044a,0x00050083,0x00000006,0x00000799,0x00000798, + 0x00000055,0x00050051,0x00000006,0x0000079b,0x0000088b,0x00000001,0x00050085,0x00000006, + 0x0000079d,0x0000079b,0x0000044d,0x0006000c,0x00000006,0x0000079f,0x00000001,0x00000006, + 0x0000044d,0x00050083,0x00000006,0x000007a0,0x0000079d,0x0000079f,0x00070050,0x00000012, + 0x000007a1,0x00000799,0x000007a0,0x00000056,0x00000055,0x00040070,0x00000006,0x000007a5, + 0x000008a8,0x00050085,0x00000006,0x000007a6,0x000007a5,0x00000085,0x00050083,0x00000006, + 0x000007a7,0x00000055,0x000007a6,0x00060052,0x00000012,0x000007d5,0x000007a7,0x000007a1, + 0x00000002,0x000200f9,0x00000443,0x000200f8,0x00000443,0x000700f5,0x00000012,0x000008d2, + 0x0000045d,0x00000453,0x000007d5,0x00000442,0x00050041,0x000003db,0x00000463,0x00000461, + 0x000000d3,0x0003003e,0x00000463,0x000008d2,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..33889bc7a42796bb9031dd99e3952c9121e46bd8 GIT binary patch literal 15352 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.h new file mode 100644 index 000000000..17c0f1318 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.h @@ -0,0 +1,514 @@ +#pragma once + +const uint32_t draw_msaa_path_webgpu_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000938,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000020,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x000d000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x000000a1, + 0x0000037d,0x00000380,0x00000384,0x00000385,0x000003c9,0x000003ce,0x0000040b,0x00030003, + 0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f, + 0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61, + 0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004, + 0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365, + 0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572, + 0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000009f,0x505f6c67, + 0x65567265,0x78657472,0x00000000,0x00060006,0x0000009f,0x00000000,0x505f6c67,0x7469736f, + 0x006e6f69,0x00070006,0x0000009f,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000, + 0x00070006,0x0000009f,0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006, + 0x0000009f,0x00000003,0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x000000a1, + 0x00000000,0x00030005,0x00000101,0x00004342,0x00030005,0x00000111,0x0000664b,0x00040006, + 0x00000111,0x00000000,0x00003464,0x00030005,0x00000113,0x00004358,0x00030005,0x00000126, + 0x0000664a,0x00040006,0x00000126,0x00000000,0x00003464,0x00030005,0x00000128,0x0000424c, + 0x00060005,0x0000037d,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005,0x00000380, + 0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005,0x00000384,0x00004254, + 0x00030005,0x00000385,0x00004255,0x00030005,0x0000039a,0x00006576,0x00040006,0x0000039a, + 0x00000000,0x00003464,0x00030005,0x0000039c,0x00004355,0x00030005,0x000003b7,0x0000424d, + 0x00040006,0x000003b7,0x00000000,0x00006250,0x00040006,0x000003b7,0x00000001,0x00006359, + 0x00040006,0x000003b7,0x00000002,0x00006552,0x00040006,0x000003b7,0x00000003,0x00006553, + 0x00040006,0x000003b7,0x00000004,0x0000366d,0x00040006,0x000003b7,0x00000005,0x0000676d, + 0x00040006,0x000003b7,0x00000006,0x00006544,0x00040006,0x000003b7,0x00000007,0x00006545, + 0x00040006,0x000003b7,0x00000008,0x00003755,0x00040006,0x000003b7,0x00000009,0x0000676a, + 0x00040006,0x000003b7,0x0000000a,0x0000635a,0x00040006,0x000003b7,0x0000000b,0x00003157, + 0x00040006,0x000003b7,0x0000000c,0x0000676e,0x00040006,0x000003b7,0x0000000d,0x00003559, + 0x00040006,0x000003b7,0x0000000e,0x0000324f,0x00040006,0x000003b7,0x0000000f,0x00006461, + 0x00040006,0x000003b7,0x00000010,0x00006579,0x00040006,0x000003b7,0x00000011,0x00003376, + 0x00040006,0x000003b7,0x00000012,0x00003377,0x00040006,0x000003b7,0x00000013,0x00006462, + 0x00040006,0x000003b7,0x00000014,0x00006767,0x00030005,0x000003b9,0x0000006b,0x00030005, + 0x000003c9,0x00003153,0x00030005,0x000003ce,0x00003159,0x00030005,0x000003db,0x00006577, + 0x00040006,0x000003db,0x00000000,0x00003464,0x00030005,0x000003dd,0x0000424f,0x00030005, + 0x0000040b,0x0000316b,0x00030005,0x00000491,0x00004351,0x00030005,0x00000494,0x00003954, + 0x00030047,0x0000009f,0x00000002,0x00050048,0x0000009f,0x00000000,0x0000000b,0x00000000, + 0x00050048,0x0000009f,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000009f,0x00000002, + 0x0000000b,0x00000003,0x00050048,0x0000009f,0x00000003,0x0000000b,0x00000004,0x00040047, + 0x00000101,0x00000021,0x00000008,0x00040047,0x00000101,0x00000022,0x00000000,0x00040047, + 0x00000110,0x00000006,0x00000010,0x00030047,0x00000111,0x00000003,0x00040048,0x00000111, + 0x00000000,0x00000018,0x00050048,0x00000111,0x00000000,0x00000023,0x00000000,0x00030047, + 0x00000113,0x00000018,0x00040047,0x00000113,0x00000021,0x00000006,0x00040047,0x00000113, + 0x00000022,0x00000000,0x00040047,0x00000125,0x00000006,0x00000010,0x00030047,0x00000126, + 0x00000003,0x00040048,0x00000126,0x00000000,0x00000018,0x00050048,0x00000126,0x00000000, + 0x00000023,0x00000000,0x00030047,0x00000128,0x00000018,0x00040047,0x00000128,0x00000021, + 0x00000003,0x00040047,0x00000128,0x00000022,0x00000000,0x00040047,0x0000037d,0x0000000b, + 0x0000002a,0x00040047,0x00000380,0x0000000b,0x0000002b,0x00040047,0x00000384,0x0000001e, + 0x00000000,0x00040047,0x00000385,0x0000001e,0x00000001,0x00040047,0x00000399,0x00000006, + 0x00000008,0x00030047,0x0000039a,0x00000003,0x00040048,0x0000039a,0x00000000,0x00000018, + 0x00050048,0x0000039a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000039c,0x00000018, + 0x00040047,0x0000039c,0x00000021,0x00000004,0x00040047,0x0000039c,0x00000022,0x00000000, + 0x00030047,0x000003b7,0x00000002,0x00050048,0x000003b7,0x00000000,0x00000023,0x00000000, + 0x00050048,0x000003b7,0x00000001,0x00000023,0x00000004,0x00050048,0x000003b7,0x00000002, + 0x00000023,0x00000008,0x00050048,0x000003b7,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x000003b7,0x00000004,0x00000023,0x00000010,0x00050048,0x000003b7,0x00000005,0x00000023, + 0x00000014,0x00050048,0x000003b7,0x00000006,0x00000023,0x00000018,0x00050048,0x000003b7, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x000003b7,0x00000008,0x00000023,0x00000020, + 0x00050048,0x000003b7,0x00000009,0x00000023,0x00000030,0x00050048,0x000003b7,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x000003b7,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x000003b7,0x0000000c,0x00000023,0x00000044,0x00050048,0x000003b7,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x000003b7,0x0000000e,0x00000023,0x0000004c,0x00050048,0x000003b7, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x000003b7,0x00000010,0x00000023,0x00000054, + 0x00050048,0x000003b7,0x00000011,0x00000023,0x00000058,0x00050048,0x000003b7,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x000003b7,0x00000013,0x00000023,0x00000060,0x00050048, + 0x000003b7,0x00000014,0x00000023,0x00000064,0x00040047,0x000003b9,0x00000021,0x00000000, + 0x00040047,0x000003b9,0x00000022,0x00000000,0x00030047,0x000003c7,0x00000000,0x00030047, + 0x000003c9,0x00000000,0x00030047,0x000003c9,0x0000000e,0x00040047,0x000003c9,0x0000001e, + 0x00000004,0x00030047,0x000003ce,0x00000000,0x00030047,0x000003ce,0x0000000e,0x00040047, + 0x000003ce,0x0000001e,0x00000006,0x00040047,0x000003da,0x00000006,0x00000010,0x00030047, + 0x000003db,0x00000003,0x00040048,0x000003db,0x00000000,0x00000018,0x00050048,0x000003db, + 0x00000000,0x00000023,0x00000000,0x00030047,0x000003dd,0x00000018,0x00040047,0x000003dd, + 0x00000021,0x00000005,0x00040047,0x000003dd,0x00000022,0x00000000,0x00040047,0x0000040b, + 0x0000001e,0x00000000,0x00030047,0x00000491,0x00000000,0x00040047,0x00000491,0x00000021, + 0x0000000a,0x00040047,0x00000491,0x00000022,0x00000000,0x00030047,0x00000494,0x00000000, + 0x00040047,0x00000494,0x00000021,0x0000000a,0x00040047,0x00000494,0x00000022,0x00000003, + 0x00030047,0x00000900,0x00000000,0x00030047,0x0000091f,0x00000000,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040015,0x0000000c, + 0x00000020,0x00000000,0x00040017,0x00000012,0x00000006,0x00000004,0x00040017,0x00000014, + 0x00000006,0x00000002,0x00040018,0x00000015,0x00000014,0x00000002,0x00040015,0x00000031, + 0x00000020,0x00000001,0x00040017,0x00000033,0x00000031,0x00000002,0x00020014,0x0000003d, + 0x0004002b,0x00000006,0x00000055,0x3f800000,0x0004002b,0x00000006,0x00000056,0x00000000, + 0x0004002b,0x0000000c,0x00000061,0x00000000,0x0004002b,0x0000000c,0x00000068,0x000003ff, + 0x0004002b,0x0000000c,0x00000078,0x00000001,0x0004002b,0x00000006,0x00000085,0x38800000, + 0x0007002c,0x00000012,0x00000090,0x00000056,0x00000056,0x00000056,0x00000056,0x00040017, + 0x00000091,0x0000003d,0x00000004,0x0004002b,0x0000000c,0x0000009c,0x00000004,0x0004001c, + 0x0000009d,0x00000006,0x0000009c,0x0004001c,0x0000009e,0x00000006,0x00000078,0x0006001e, + 0x0000009f,0x00000012,0x00000006,0x0000009d,0x0000009e,0x00040020,0x000000a0,0x00000003, + 0x0000009f,0x0004003b,0x000000a0,0x000000a1,0x00000003,0x0004002b,0x00000031,0x000000a2, + 0x00000002,0x0004002b,0x00000031,0x000000a3,0x00000000,0x00040020,0x000000a7,0x00000003, + 0x00000006,0x0004002b,0x00000031,0x000000a9,0x00000001,0x0004002b,0x00000031,0x000000b2, + 0x00000003,0x0004002b,0x00000006,0x000000ba,0x3f000000,0x0004002b,0x00000031,0x000000c1, + 0x000007ff,0x0004002b,0x00000031,0x000000c4,0x0000000b,0x0004002b,0x0000000c,0x000000e3, + 0x00000002,0x0004002b,0x0000000c,0x000000e7,0x00000003,0x00040017,0x000000fc,0x0000000c, + 0x00000004,0x00090019,0x000000ff,0x0000000c,0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000001,0x00000000,0x00040020,0x00000100,0x00000000,0x000000ff,0x0004003b,0x00000100, + 0x00000101,0x00000000,0x0004002b,0x0000000c,0x0000010c,0x0000ffff,0x0003001d,0x00000110, + 0x000000fc,0x0003001e,0x00000111,0x00000110,0x00040020,0x00000112,0x00000002,0x00000111, + 0x0004003b,0x00000112,0x00000113,0x00000002,0x00040020,0x00000116,0x00000002,0x000000fc, + 0x00040017,0x0000011a,0x0000000c,0x00000002,0x0003001d,0x00000125,0x000000fc,0x0003001e, + 0x00000126,0x00000125,0x00040020,0x00000127,0x00000002,0x00000126,0x0004003b,0x00000127, + 0x00000128,0x00000002,0x0004002b,0x0000000c,0x00000144,0x00800000,0x0004002b,0x0000000c, + 0x00000164,0x0080ffff,0x0004002b,0x0000000c,0x00000185,0xff7fffff,0x0004002b,0x0000000c, + 0x0000018a,0x1c000000,0x0004002b,0x0000000c,0x0000018c,0x04000000,0x0004002b,0x00000031, + 0x0000019c,0x00000010,0x0004002b,0x00000006,0x000001e1,0x40490fdb,0x0004002b,0x00000006, + 0x000001e5,0x40c90fdb,0x0004002b,0x00000006,0x0000021a,0x40000000,0x0005002c,0x00000014, + 0x0000023e,0x00000056,0x00000056,0x0004002b,0x0000000c,0x00000254,0x00100000,0x0004002b, + 0x0000000c,0x0000025c,0x00080000,0x0004002b,0x0000000c,0x0000028d,0x08000000,0x0004002b, + 0x0000000c,0x00000293,0x00400000,0x0004002b,0x00000006,0x000002c7,0xbf000000,0x0004002b, + 0x0000000c,0x000002de,0x14000000,0x0004002b,0x0000000c,0x000002e4,0x10000000,0x0004002b, + 0x00000006,0x000002e7,0x3e800000,0x0004002b,0x0000000c,0x000002ef,0x02000000,0x0004002b, + 0x0000000c,0x00000307,0x00200000,0x0004002b,0x00000006,0x00000312,0x3e000000,0x0003002a, + 0x0000003d,0x00000355,0x0004002b,0x0000000c,0x0000035e,0x80000000,0x00030029,0x0000003d, + 0x00000378,0x00040020,0x0000037c,0x00000001,0x00000031,0x0004003b,0x0000037c,0x0000037d, + 0x00000001,0x0004003b,0x0000037c,0x00000380,0x00000001,0x00040020,0x00000383,0x00000001, + 0x00000012,0x0004003b,0x00000383,0x00000384,0x00000001,0x0004003b,0x00000383,0x00000385, + 0x00000001,0x0003001d,0x00000399,0x0000011a,0x0003001e,0x0000039a,0x00000399,0x00040020, + 0x0000039b,0x00000002,0x0000039a,0x0004003b,0x0000039b,0x0000039c,0x00000002,0x00040020, + 0x0000039e,0x00000002,0x0000011a,0x0004002b,0x0000000c,0x000003a4,0x0000000f,0x00040017, + 0x000003b6,0x00000031,0x00000004,0x0017001e,0x000003b7,0x00000006,0x00000006,0x00000006, + 0x00000006,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x000003b6,0x00000014,0x00000014, + 0x0000000c,0x00000006,0x0000000c,0x00000006,0x00000006,0x0000000c,0x00000006,0x00000006, + 0x00000006,0x0000000c,0x00040020,0x000003b8,0x00000002,0x000003b7,0x0004003b,0x000003b8, + 0x000003b9,0x00000002,0x0004002b,0x00000031,0x000003ba,0x0000000d,0x00040020,0x000003be, + 0x00000002,0x0000000c,0x00040020,0x000003c8,0x00000003,0x00000014,0x0004003b,0x000003c8, + 0x000003c9,0x00000003,0x0004003b,0x000000a7,0x000003ce,0x00000003,0x0004002b,0x00000031, + 0x000003d1,0x00000004,0x0003001d,0x000003da,0x00000012,0x0003001e,0x000003db,0x000003da, + 0x00040020,0x000003dc,0x00000002,0x000003db,0x0004003b,0x000003dc,0x000003dd,0x00000002, + 0x00040020,0x000003e2,0x00000002,0x00000012,0x00040020,0x0000040a,0x00000003,0x00000012, + 0x0004003b,0x0000040a,0x0000040b,0x00000003,0x0004002b,0x00000006,0x00000443,0x3f666666, + 0x0004002b,0x00000006,0x0000046b,0xc0000000,0x00040020,0x00000477,0x00000002,0x00000006, + 0x0004002b,0x00000031,0x00000483,0x0000000e,0x00090019,0x0000048f,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000490,0x00000000, + 0x0000048f,0x0004003b,0x00000490,0x00000491,0x00000000,0x0002001a,0x00000492,0x00040020, + 0x00000493,0x00000000,0x00000492,0x0004003b,0x00000493,0x00000494,0x00000000,0x00030001, + 0x00000014,0x000008e9,0x00030001,0x0000000c,0x00000906,0x0004002b,0x00000031,0x0000092c, + 0xfffffffe,0x0004002b,0x00000006,0x0000092d,0xbf800000,0x0004002b,0x00000006,0x0000092e, + 0x3ea2f983,0x0004002b,0x00000006,0x0000092f,0xc0400000,0x00040017,0x00000932,0x0000003d, + 0x00000002,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003d,0x00000031,0x00000381,0x00000380,0x0004003d,0x00000012,0x0000038a,0x00000384, + 0x0004003d,0x00000012,0x0000038c,0x00000385,0x000300f7,0x0000070e,0x00000000,0x000300fb, + 0x00000061,0x000004ee,0x000200f8,0x000004ee,0x00050051,0x00000006,0x000004f0,0x0000038a, + 0x00000000,0x0004006e,0x00000031,0x000004f1,0x000004f0,0x00050051,0x00000006,0x000004f3, + 0x0000038a,0x00000001,0x00050051,0x00000006,0x000004f7,0x0000038a,0x00000003,0x0004007c, + 0x00000031,0x000004f8,0x000004f7,0x000500c3,0x00000031,0x000004f9,0x000004f8,0x000000a2, + 0x000500c7,0x00000031,0x000004fd,0x000004f8,0x000000b2,0x00050082,0x00000031,0x00000500, + 0x000004f9,0x000000a9,0x0007000c,0x00000031,0x00000501,0x00000001,0x00000027,0x000004f1, + 0x00000500,0x00050084,0x00000031,0x00000504,0x00000381,0x000004f9,0x00050080,0x00000031, + 0x00000506,0x00000504,0x00000501,0x0004003d,0x000000ff,0x00000507,0x00000101,0x000500c7, + 0x00000031,0x00000713,0x00000506,0x000000c1,0x000500c3,0x00000031,0x00000715,0x00000506, + 0x000000c4,0x00050050,0x00000033,0x00000716,0x00000713,0x00000715,0x0007005f,0x000000fc, + 0x0000050a,0x00000507,0x00000716,0x00000002,0x000000a3,0x00050051,0x0000000c,0x0000050c, + 0x0000050a,0x00000003,0x000500c7,0x0000000c,0x0000050e,0x0000050c,0x0000010c,0x0007000c, + 0x0000000c,0x0000050f,0x00000001,0x00000029,0x0000050e,0x00000078,0x00050082,0x0000000c, + 0x00000511,0x0000050f,0x00000078,0x00060041,0x00000116,0x00000512,0x00000113,0x000000a3, + 0x00000511,0x0004003d,0x000000fc,0x00000513,0x00000512,0x0007004f,0x0000011a,0x00000515, + 0x00000513,0x00000513,0x00000000,0x00000001,0x0004007c,0x00000014,0x00000516,0x00000515, + 0x00050051,0x0000000c,0x00000518,0x00000513,0x00000002,0x000500c7,0x0000000c,0x00000519, + 0x00000518,0x0000010c,0x00050051,0x0000000c,0x0000051b,0x00000513,0x00000003,0x00050084, + 0x0000000c,0x0000051d,0x00000519,0x0000009c,0x00060041,0x00000116,0x0000051e,0x00000128, + 0x000000a3,0x0000051d,0x0004003d,0x000000fc,0x0000051f,0x0000051e,0x0004007c,0x00000012, + 0x00000520,0x0000051f,0x00050051,0x00000006,0x0000071d,0x00000520,0x00000000,0x00050051, + 0x00000006,0x0000071e,0x00000520,0x00000001,0x00050051,0x00000006,0x0000071f,0x00000520, + 0x00000002,0x00050051,0x00000006,0x00000720,0x00000520,0x00000003,0x00050050,0x00000014, + 0x00000721,0x0000071d,0x0000071e,0x00050050,0x00000014,0x00000722,0x0000071f,0x00000720, + 0x00050050,0x00000015,0x00000723,0x00000721,0x00000722,0x00050080,0x0000000c,0x00000524, + 0x0000051d,0x00000078,0x00060041,0x00000116,0x00000525,0x00000128,0x000000a3,0x00000524, + 0x0004003d,0x000000fc,0x00000526,0x00000525,0x0007004f,0x0000011a,0x00000528,0x00000526, + 0x00000526,0x00000000,0x00000001,0x0004007c,0x00000014,0x00000529,0x00000528,0x00050051, + 0x0000000c,0x0000052b,0x00000526,0x00000002,0x0004007c,0x00000006,0x0000052c,0x0000052b, + 0x00050051,0x0000000c,0x0000052e,0x00000526,0x00000003,0x0004007c,0x00000006,0x0000052f, + 0x0000052e,0x000500c7,0x0000000c,0x00000531,0x0000050c,0x00000144,0x000500ab,0x0000003d, + 0x00000533,0x00000531,0x00000061,0x000300f7,0x0000053c,0x00000000,0x000400fa,0x00000533, + 0x00000534,0x0000053c,0x000200f8,0x00000534,0x00050051,0x00000006,0x00000536,0x0000038c, + 0x00000000,0x0004006e,0x00000031,0x00000537,0x00000536,0x00050051,0x00000006,0x00000539, + 0x0000038c,0x00000001,0x000200f9,0x0000053c,0x000200f8,0x0000053c,0x000700f5,0x00000006, + 0x0000084a,0x000004f3,0x000004ee,0x00000539,0x00000534,0x000700f5,0x00000031,0x0000082e, + 0x000004f1,0x000004ee,0x00000537,0x00000534,0x000500ab,0x0000003d,0x0000053f,0x0000082e, + 0x00000501,0x000300f7,0x0000056c,0x00000000,0x000400fa,0x0000053f,0x00000540,0x0000056c, + 0x000200f8,0x00000540,0x00050080,0x00000031,0x00000543,0x00000506,0x0000082e,0x00050082, + 0x00000031,0x00000545,0x00000543,0x00000501,0x0004003d,0x000000ff,0x00000546,0x00000101, + 0x000500c7,0x00000031,0x00000727,0x00000545,0x000000c1,0x000500c3,0x00000031,0x00000729, + 0x00000545,0x000000c4,0x00050050,0x00000033,0x0000072a,0x00000727,0x00000729,0x0007005f, + 0x000000fc,0x00000549,0x00000546,0x0000072a,0x00000002,0x000000a3,0x00050051,0x0000000c, + 0x0000054b,0x00000549,0x00000003,0x000500c7,0x0000000c,0x0000054c,0x0000054b,0x00000164, + 0x000500c7,0x0000000c,0x0000054e,0x0000050c,0x00000164,0x000500ab,0x0000003d,0x0000054f, + 0x0000054c,0x0000054e,0x000300f7,0x00000566,0x00000000,0x000400fa,0x0000054f,0x00000553, + 0x00000550,0x000200f8,0x00000550,0x000200f9,0x00000566,0x000200f8,0x00000553,0x000500b4, + 0x0000003d,0x00000555,0x0000052c,0x00000056,0x000400a8,0x0000003d,0x00000556,0x00000555, + 0x000300f7,0x0000055b,0x00000000,0x000400fa,0x00000556,0x00000557,0x0000055b,0x000200f8, + 0x00000557,0x00050051,0x00000006,0x00000559,0x00000516,0x00000000,0x000500b7,0x0000003d, + 0x0000055a,0x00000559,0x00000056,0x000200f9,0x0000055b,0x000200f8,0x0000055b,0x000700f5, + 0x0000003d,0x0000055c,0x00000555,0x00000553,0x0000055a,0x00000557,0x000300f7,0x00000565, + 0x00000000,0x000400fa,0x0000055c,0x0000055e,0x00000565,0x000200f8,0x0000055e,0x0004007c, + 0x00000031,0x00000560,0x0000051b,0x0004003d,0x000000ff,0x00000561,0x00000101,0x000500c7, + 0x00000031,0x0000072e,0x00000560,0x000000c1,0x000500c3,0x00000031,0x00000730,0x00000560, + 0x000000c4,0x00050050,0x00000033,0x00000731,0x0000072e,0x00000730,0x0007005f,0x000000fc, + 0x00000564,0x00000561,0x00000731,0x00000002,0x000000a3,0x000200f9,0x00000565,0x000200f8, + 0x00000565,0x000700f5,0x00000031,0x0000083b,0x00000506,0x0000055b,0x00000560,0x0000055e, + 0x000700f5,0x000000fc,0x00000833,0x0000050a,0x0000055b,0x00000564,0x0000055e,0x000200f9, + 0x00000566,0x000200f8,0x00000566,0x000700f5,0x00000031,0x0000083a,0x00000545,0x00000550, + 0x0000083b,0x00000565,0x000700f5,0x000000fc,0x00000832,0x00000549,0x00000550,0x00000833, + 0x00000565,0x00050051,0x0000000c,0x00000568,0x00000832,0x00000003,0x000500c7,0x0000000c, + 0x00000569,0x00000568,0x00000185,0x000500c5,0x0000000c,0x0000056b,0x00000569,0x00000531, + 0x000200f9,0x0000056c,0x000200f8,0x0000056c,0x000700f5,0x00000031,0x00000839,0x00000506, + 0x0000053c,0x0000083a,0x00000566,0x000700f5,0x000000fc,0x00000837,0x0000050a,0x0000053c, + 0x00000832,0x00000566,0x000700f5,0x0000000c,0x00000836,0x0000050c,0x0000053c,0x0000056b, + 0x00000566,0x000500c7,0x0000000c,0x0000056e,0x00000836,0x0000018a,0x000500aa,0x0000003d, + 0x0000056f,0x0000056e,0x0000018c,0x000500aa,0x0000003d,0x00000571,0x000004fd,0x000000a3, + 0x000500a7,0x0000003d,0x00000572,0x0000056f,0x00000571,0x000300f7,0x000005fd,0x00000000, + 0x000400fa,0x00000572,0x00000577,0x00000573,0x000200f8,0x00000573,0x00050051,0x0000000c, + 0x00000575,0x00000837,0x00000002,0x0004007c,0x00000006,0x00000576,0x00000575,0x000200f9, + 0x000005fd,0x000200f8,0x00000577,0x00050051,0x0000000c,0x00000579,0x00000837,0x00000002, + 0x000500c7,0x0000000c,0x0000057b,0x00000579,0x0000010c,0x00040070,0x00000006,0x0000057c, + 0x0000057b,0x000500c2,0x0000000c,0x0000057e,0x00000579,0x0000019c,0x00040070,0x00000006, + 0x0000057f,0x0000057e,0x00050083,0x00000006,0x00000582,0x0000092d,0x0000057c,0x0004006e, + 0x00000031,0x00000583,0x00000582,0x00050083,0x00000006,0x00000586,0x0000057f,0x0000057c, + 0x00050081,0x00000006,0x00000587,0x00000586,0x00000055,0x0004006e,0x00000031,0x00000588, + 0x00000587,0x00050050,0x00000033,0x00000589,0x00000583,0x00000588,0x000500c7,0x0000000c, + 0x0000058b,0x00000836,0x00000144,0x000500ab,0x0000003d,0x0000058c,0x0000058b,0x00000061, + 0x000300f7,0x00000590,0x00000000,0x000400fa,0x0000058c,0x0000058d,0x00000590,0x000200f8, + 0x0000058d,0x0004007e,0x00000033,0x0000058f,0x00000589,0x000200f9,0x00000590,0x000200f8, + 0x00000590,0x000700f5,0x00000033,0x0000083d,0x00000589,0x00000577,0x0000058f,0x0000058d, + 0x0004003d,0x000000ff,0x00000591,0x00000101,0x00050051,0x00000031,0x00000594,0x0000083d, + 0x00000000,0x00050080,0x00000031,0x00000595,0x00000839,0x00000594,0x000500c7,0x00000031, + 0x00000735,0x00000595,0x000000c1,0x000500c3,0x00000031,0x00000737,0x00000595,0x000000c4, + 0x00050050,0x00000033,0x00000738,0x00000735,0x00000737,0x0007005f,0x000000fc,0x00000597, + 0x00000591,0x00000738,0x00000002,0x000000a3,0x0004003d,0x000000ff,0x00000598,0x00000101, + 0x00050051,0x00000031,0x0000059b,0x0000083d,0x00000001,0x00050080,0x00000031,0x0000059c, + 0x00000839,0x0000059b,0x000500c7,0x00000031,0x0000073c,0x0000059c,0x000000c1,0x000500c3, + 0x00000031,0x0000073e,0x0000059c,0x000000c4,0x00050050,0x00000033,0x0000073f,0x0000073c, + 0x0000073e,0x0007005f,0x000000fc,0x0000059e,0x00000598,0x0000073f,0x00000002,0x000000a3, + 0x00050051,0x0000000c,0x000005a0,0x0000059e,0x00000003,0x000500c7,0x0000000c,0x000005a1, + 0x000005a0,0x00000164,0x00050051,0x0000000c,0x000005a3,0x00000597,0x00000003,0x000500c7, + 0x0000000c,0x000005a4,0x000005a3,0x00000164,0x000500ab,0x0000003d,0x000005a5,0x000005a1, + 0x000005a4,0x000300f7,0x000005ac,0x00000000,0x000400fa,0x000005a5,0x000005a6,0x000005ac, + 0x000200f8,0x000005a6,0x0004003d,0x000000ff,0x000005a7,0x00000101,0x0004007c,0x00000031, + 0x000005a9,0x0000051b,0x000500c7,0x00000031,0x00000743,0x000005a9,0x000000c1,0x000500c3, + 0x00000031,0x00000745,0x000005a9,0x000000c4,0x00050050,0x00000033,0x00000746,0x00000743, + 0x00000745,0x0007005f,0x000000fc,0x000005ab,0x000005a7,0x00000746,0x00000002,0x000000a3, + 0x000200f9,0x000005ac,0x000200f8,0x000005ac,0x000700f5,0x000000fc,0x0000083e,0x0000059e, + 0x00000590,0x000005ab,0x000005a6,0x00050051,0x0000000c,0x000005ae,0x00000597,0x00000002, + 0x0004007c,0x00000006,0x000005af,0x000005ae,0x00050051,0x0000000c,0x000005b1,0x0000083e, + 0x00000002,0x0004007c,0x00000006,0x000005b2,0x000005b1,0x00050083,0x00000006,0x000005b5, + 0x000005b2,0x000005af,0x0006000c,0x00000006,0x000005b7,0x00000001,0x00000004,0x000005b5, + 0x000500ba,0x0000003d,0x000005b8,0x000005b7,0x000001e1,0x000300f7,0x000005bf,0x00000000, + 0x000400fa,0x000005b8,0x000005b9,0x000005bf,0x000200f8,0x000005b9,0x0006000c,0x00000006, + 0x000005bb,0x00000001,0x00000006,0x000005b5,0x00050085,0x00000006,0x000005bc,0x000001e5, + 0x000005bb,0x00050083,0x00000006,0x000005be,0x000005b5,0x000005bc,0x000200f9,0x000005bf, + 0x000200f8,0x000005bf,0x000700f5,0x00000006,0x00000842,0x000005b5,0x000005ac,0x000005be, + 0x000005b9,0x00050081,0x00000006,0x000005c2,0x0000057f,0x0000046b,0x0006000c,0x00000006, + 0x000005c4,0x00000001,0x00000004,0x00000842,0x00050085,0x00000006,0x000005c5,0x000005c4, + 0x0000092e,0x00050085,0x00000006,0x000005c7,0x000005c5,0x000005c2,0x0006000c,0x00000006, + 0x000005c8,0x00000001,0x00000001,0x000005c7,0x00050081,0x00000006,0x000005ca,0x0000057f, + 0x0000092f,0x0008000c,0x00000006,0x000005cb,0x00000001,0x0000002b,0x000005c8,0x00000055, + 0x000005ca,0x00050083,0x00000006,0x000005ce,0x000005c2,0x000005cb,0x000500bc,0x0000003d, + 0x000005d1,0x0000057c,0x000005ce,0x000300f7,0x000005ee,0x00000000,0x000400fa,0x000005d1, + 0x000005df,0x000005d2,0x000200f8,0x000005d2,0x00050081,0x00000006,0x000005d5,0x000005ce, + 0x00000055,0x000500b4,0x0000003d,0x000005d6,0x0000057c,0x000005d5,0x000300f7,0x000005de, + 0x00000000,0x000400fa,0x000005d6,0x000005dd,0x000005d7,0x000200f8,0x000005d7,0x00050081, + 0x00000006,0x000005d9,0x000005ce,0x0000021a,0x00050083,0x00000006,0x000005db,0x0000057c, + 0x000005d9,0x000200f9,0x000005de,0x000200f8,0x000005dd,0x000200f9,0x000005de,0x000200f8, + 0x000005de,0x000700f5,0x00000006,0x0000084f,0x000005db,0x000005d7,0x00000056,0x000005dd, + 0x000600a9,0x00000006,0x00000930,0x000005d6,0x00000056,0x0000084a,0x000600a9,0x00000006, + 0x00000931,0x000005d6,0x00000056,0x000005cb,0x000200f9,0x000005ee,0x000200f8,0x000005df, + 0x0006000c,0x00000006,0x000005e1,0x00000001,0x00000006,0x00000842,0x00050085,0x00000006, + 0x000005e2,0x000001e1,0x000005e1,0x00050083,0x00000006,0x000005e4,0x000005e2,0x00000842, + 0x0004007f,0x00000006,0x000005e5,0x000005e4,0x000500b4,0x0000003d,0x000005e9,0x0000057c, + 0x000005ce,0x000300f7,0x000005ed,0x00000000,0x000400fa,0x000005e9,0x000005ea,0x000005ed, + 0x000200f8,0x000005ea,0x0004007f,0x00000006,0x000005ec,0x0000084a,0x000200f9,0x000005ed, + 0x000200f8,0x000005ed,0x000700f5,0x00000006,0x0000088a,0x0000084a,0x000005df,0x000005ec, + 0x000005ea,0x000200f9,0x000005ee,0x000200f8,0x000005ee,0x000700f5,0x00000006,0x00000888, + 0x00000930,0x000005de,0x0000088a,0x000005ed,0x000700f5,0x00000006,0x00000854,0x00000842, + 0x000005de,0x000005e5,0x000005ed,0x000700f5,0x00000006,0x00000851,0x00000931,0x000005de, + 0x000005ce,0x000005ed,0x000700f5,0x00000006,0x0000084e,0x0000084f,0x000005de,0x0000057c, + 0x000005ed,0x000500b4,0x0000003d,0x000005f1,0x0000084e,0x00000851,0x000300f7,0x000005fc, + 0x00000000,0x000400fa,0x000005f1,0x000005fa,0x000005f2,0x000200f8,0x000005f2,0x00050088, + 0x00000006,0x000005f7,0x0000084e,0x00000851,0x00050085,0x00000006,0x000005f8,0x00000854, + 0x000005f7,0x00050081,0x00000006,0x000005f9,0x000005af,0x000005f8,0x000200f9,0x000005fc, + 0x000200f8,0x000005fa,0x000200f9,0x000005fc,0x000200f8,0x000005fc,0x000700f5,0x00000006, + 0x00000858,0x000005f9,0x000005f2,0x000005b2,0x000005fa,0x000200f9,0x000005fd,0x000200f8, + 0x000005fd,0x000700f5,0x00000006,0x00000886,0x0000084a,0x00000573,0x00000888,0x000005fc, + 0x000700f5,0x00000006,0x00000857,0x00000576,0x00000573,0x00000858,0x000005fc,0x0006000c, + 0x00000006,0x000005ff,0x00000001,0x0000000d,0x00000857,0x0006000c,0x00000006,0x00000601, + 0x00000001,0x0000000e,0x00000857,0x0004007f,0x00000006,0x00000602,0x00000601,0x00050050, + 0x00000014,0x00000603,0x000005ff,0x00000602,0x0007004f,0x0000011a,0x00000605,0x00000837, + 0x00000837,0x00000000,0x00000001,0x0004007c,0x00000014,0x00000606,0x00000605,0x000500b7, + 0x0000003d,0x00000608,0x0000052f,0x00000056,0x000300f7,0x00000611,0x00000000,0x000400fa, + 0x00000608,0x00000609,0x00000611,0x000200f8,0x00000609,0x00050091,0x00000014,0x0000060d, + 0x00000723,0x00000603,0x0006000c,0x00000006,0x0000060e,0x00000001,0x00000042,0x0000060d, + 0x00050088,0x00000006,0x0000060f,0x00000055,0x0000060e,0x0007000c,0x00000006,0x00000610, + 0x00000001,0x00000028,0x0000052f,0x0000060f,0x000200f9,0x00000611,0x000200f8,0x00000611, + 0x000700f5,0x00000006,0x0000088f,0x0000052f,0x000005fd,0x00000610,0x00000609,0x000500b7, + 0x0000003d,0x00000613,0x0000052c,0x00000056,0x000300f7,0x000006fe,0x00000000,0x000400fa, + 0x00000613,0x00000622,0x00000614,0x000200f8,0x00000614,0x000500aa,0x0000003d,0x00000616, + 0x000004fd,0x000000a2,0x00050050,0x00000932,0x00000933,0x00000616,0x00000616,0x000600a9, + 0x00000014,0x00000934,0x00000933,0x00000516,0x00000606,0x000500c7,0x0000000c,0x0000061b, + 0x00000836,0x0000035e,0x000500ab,0x0000003d,0x0000061c,0x0000061b,0x00000061,0x000500ab, + 0x0000003d,0x0000061e,0x000004fd,0x000000a9,0x000500a7,0x0000003d,0x0000061f,0x0000061c, + 0x0000061e,0x000300f7,0x00000621,0x00000000,0x000400fa,0x0000061f,0x00000620,0x00000621, + 0x000200f8,0x00000620,0x000200f9,0x0000070e,0x000200f8,0x00000621,0x000200f9,0x000006fe, + 0x000200f8,0x00000622,0x0006000c,0x00000006,0x00000624,0x00000001,0x00000021,0x00000723, + 0x0006000c,0x00000006,0x00000625,0x00000001,0x00000006,0x00000624,0x00050085,0x00000006, + 0x00000627,0x00000886,0x00000625,0x000500c7,0x0000000c,0x00000629,0x00000836,0x00000254, + 0x000500ab,0x0000003d,0x0000062a,0x00000629,0x00000061,0x000300f7,0x0000062e,0x00000000, + 0x000400fa,0x0000062a,0x0000062b,0x0000062e,0x000200f8,0x0000062b,0x0007000c,0x00000006, + 0x0000062d,0x00000001,0x00000025,0x00000627,0x00000056,0x000200f9,0x0000062e,0x000200f8, + 0x0000062e,0x000700f5,0x00000006,0x0000088c,0x00000627,0x00000622,0x0000062d,0x0000062b, + 0x000500c7,0x0000000c,0x00000630,0x00000836,0x0000025c,0x000500ab,0x0000003d,0x00000631, + 0x00000630,0x00000061,0x000300f7,0x00000635,0x00000000,0x000400fa,0x00000631,0x00000632, + 0x00000635,0x000200f8,0x00000632,0x0007000c,0x00000006,0x00000634,0x00000001,0x00000028, + 0x0000088c,0x00000056,0x000200f9,0x00000635,0x000200f8,0x00000635,0x000700f5,0x00000006, + 0x000008c5,0x0000088c,0x0000062e,0x00000634,0x00000632,0x000500b7,0x0000003d,0x00000637, + 0x0000088f,0x00000056,0x000600a9,0x00000006,0x00000935,0x00000637,0x0000088f,0x00000056, + 0x000500ba,0x0000003d,0x00000643,0x00000935,0x0000052c,0x000500b4,0x0000003d,0x00000645, + 0x0000088f,0x00000056,0x000500a7,0x0000003d,0x00000646,0x00000643,0x00000645,0x000600a9, + 0x00000006,0x00000936,0x00000646,0x00000935,0x0000052c,0x00050081,0x00000006,0x00000652, + 0x00000936,0x00000935,0x0005008e,0x00000014,0x00000653,0x00000603,0x00000652,0x000500ac, + 0x0000003d,0x00000657,0x0000056e,0x0000028d,0x000300f7,0x000006f4,0x00000000,0x000400fa, + 0x00000657,0x00000658,0x000006f4,0x000200f8,0x00000658,0x000500c7,0x0000000c,0x0000065a, + 0x00000836,0x00000293,0x000500aa,0x0000003d,0x0000065b,0x0000065a,0x00000061,0x000600a9, + 0x00000031,0x00000937,0x0000065b,0x0000092c,0x000000a2,0x000500c7,0x0000000c,0x00000661, + 0x00000836,0x00000144,0x000500ab,0x0000003d,0x00000662,0x00000661,0x00000061,0x000300f7, + 0x00000666,0x00000000,0x000400fa,0x00000662,0x00000663,0x00000666,0x000200f8,0x00000663, + 0x0004007e,0x00000031,0x00000665,0x00000937,0x000200f9,0x00000666,0x000200f8,0x00000666, + 0x000700f5,0x00000031,0x000008a9,0x00000937,0x00000658,0x00000665,0x00000663,0x00050080, + 0x00000031,0x00000669,0x00000839,0x000008a9,0x000500c7,0x00000031,0x00000766,0x00000669, + 0x000000c1,0x000500c3,0x00000031,0x00000768,0x00000669,0x000000c4,0x00050050,0x00000033, + 0x00000769,0x00000766,0x00000768,0x0004003d,0x000000ff,0x0000066b,0x00000101,0x0007005f, + 0x000000fc,0x0000066d,0x0000066b,0x00000769,0x00000002,0x000000a3,0x00050051,0x0000000c, + 0x0000066f,0x0000066d,0x00000002,0x0004007c,0x00000006,0x00000670,0x0000066f,0x00050083, + 0x00000006,0x00000673,0x00000670,0x00000857,0x0006000c,0x00000006,0x00000674,0x00000001, + 0x00000004,0x00000673,0x000500ba,0x0000003d,0x00000676,0x00000674,0x000001e1,0x000300f7, + 0x0000067a,0x00000000,0x000400fa,0x00000676,0x00000677,0x0000067a,0x000200f8,0x00000677, + 0x00050083,0x00000006,0x00000679,0x000001e5,0x00000674,0x000200f9,0x0000067a,0x000200f8, + 0x0000067a,0x000700f5,0x00000006,0x000008b3,0x00000674,0x00000666,0x00000679,0x00000677, + 0x000500ab,0x0000003d,0x0000067d,0x0000065a,0x00000061,0x000500a4,0x0000003d,0x00000684, + 0x0000067d,0x0000062a,0x000600a9,0x00000006,0x00000685,0x00000684,0x000002c7,0x000000ba, + 0x00050085,0x00000006,0x00000686,0x000008b3,0x00000685,0x00050081,0x00000006,0x00000688, + 0x00000686,0x00000857,0x0006000c,0x00000006,0x0000068a,0x00000001,0x0000000d,0x00000688, + 0x0006000c,0x00000006,0x0000068c,0x00000001,0x0000000e,0x00000688,0x0004007f,0x00000006, + 0x0000068d,0x0000068c,0x00050050,0x00000014,0x0000068e,0x0000068a,0x0000068d,0x00050091, + 0x00000014,0x0000076f,0x00000723,0x0000068e,0x00050051,0x00000006,0x00000771,0x0000076f, + 0x00000000,0x0006000c,0x00000006,0x00000772,0x00000001,0x00000004,0x00000771,0x00050051, + 0x00000006,0x00000774,0x0000076f,0x00000001,0x0006000c,0x00000006,0x00000775,0x00000001, + 0x00000004,0x00000774,0x00050081,0x00000006,0x00000776,0x00000772,0x00000775,0x00050094, + 0x00000006,0x00000779,0x0000076f,0x0000076f,0x00050088,0x00000006,0x0000077a,0x00000055, + 0x00000779,0x00050085,0x00000006,0x0000077b,0x00000776,0x0000077a,0x00050085,0x00000006, + 0x00000693,0x000008b3,0x000000ba,0x0006000c,0x00000006,0x00000694,0x00000001,0x0000000e, + 0x00000693,0x000500aa,0x0000003d,0x00000696,0x0000056e,0x000002de,0x000400a8,0x0000003d, + 0x00000697,0x00000696,0x000300f7,0x0000069e,0x00000000,0x000400fa,0x00000697,0x00000698, + 0x0000069e,0x000200f8,0x00000698,0x000500aa,0x0000003d,0x0000069a,0x0000056e,0x000002e4, + 0x000500be,0x0000003d,0x0000069c,0x00000694,0x000002e7,0x000500a7,0x0000003d,0x0000069d, + 0x0000069a,0x0000069c,0x000200f9,0x0000069e,0x000200f8,0x0000069e,0x000700f5,0x0000003d, + 0x0000069f,0x00000696,0x0000067a,0x0000069d,0x00000698,0x000300f7,0x000006b2,0x00000000, + 0x000400fa,0x0000069f,0x000006a7,0x000006a0,0x000200f8,0x000006a0,0x00050085,0x00000006, + 0x000006a3,0x00000936,0x00000694,0x00050085,0x00000006,0x000006a5,0x0000077b,0x000000ba, + 0x00050081,0x00000006,0x000006a6,0x000006a3,0x000006a5,0x000200f9,0x000006b2,0x000200f8, + 0x000006a7,0x000500c7,0x0000000c,0x000006a9,0x00000836,0x000002ef,0x000500ab,0x0000003d, + 0x000006aa,0x000006a9,0x00000061,0x000600a9,0x00000006,0x000006ab,0x000006aa,0x00000055, + 0x000002e7,0x0007000c,0x00000006,0x000006af,0x00000001,0x00000028,0x00000694,0x000006ab, + 0x00050088,0x00000006,0x000006b0,0x00000055,0x000006af,0x00050085,0x00000006,0x000006b1, + 0x00000936,0x000006b0,0x000200f9,0x000006b2,0x000200f8,0x000006b2,0x000700f5,0x00000006, + 0x000008ba,0x000006a6,0x000006a0,0x000006b1,0x000006a7,0x000500c7,0x0000000c,0x000006b8, + 0x00000836,0x00000307,0x000500ab,0x0000003d,0x000006b9,0x000006b8,0x00000061,0x000300f7, + 0x000006e7,0x00000000,0x000400fa,0x000006b9,0x000006ba,0x000006e7,0x000200f8,0x000006ba, + 0x00050085,0x00000006,0x000006bf,0x00000935,0x00000312,0x00050085,0x00000006,0x000006c3, + 0x000008ba,0x00000694,0x00050081,0x00000006,0x000006c5,0x000006c3,0x000006bf,0x000500bc, + 0x0000003d,0x000006c6,0x00000652,0x000006c5,0x000300f7,0x000006e6,0x00000000,0x000400fa, + 0x000006c6,0x000006de,0x000006c7,0x000200f8,0x000006c7,0x0005008e,0x00000014,0x000006ca, + 0x0000068e,0x000008ba,0x00050094,0x00000006,0x000006cd,0x00000653,0x00000653,0x00050094, + 0x00000006,0x000006d0,0x000006ca,0x000006ca,0x00050050,0x00000014,0x000006d1,0x000006cd, + 0x000006d0,0x00050050,0x00000015,0x000006db,0x00000653,0x000006ca,0x0006000c,0x00000015, + 0x000006dc,0x00000001,0x00000022,0x000006db,0x00050090,0x00000014,0x000006dd,0x000006d1, + 0x000006dc,0x000200f9,0x000006e6,0x000200f8,0x000006de,0x00050088,0x00000006,0x000006e1, + 0x00000055,0x00000694,0x00050085,0x00000006,0x000006e2,0x00000652,0x000006e1,0x0005008e, + 0x00000014,0x000006e5,0x0000068e,0x000006e2,0x000200f9,0x000006e6,0x000200f8,0x000006e6, + 0x000700f5,0x00000014,0x000008cf,0x000006dd,0x000006c7,0x000006e5,0x000006de,0x000200f9, + 0x000006e7,0x000200f8,0x000006e7,0x000700f5,0x00000014,0x000008ce,0x00000653,0x000006b2, + 0x000008cf,0x000006e6,0x000200f9,0x000006f4,0x000200f8,0x000006f4,0x000700f5,0x00000014, + 0x000008cd,0x00000653,0x00000635,0x000008ce,0x000006e7,0x0005008e,0x00000014,0x000006f8, + 0x000008cd,0x000008c5,0x00050091,0x00000014,0x000006f9,0x00000723,0x000006f8,0x000500ab, + 0x0000003d,0x000006fb,0x000004fd,0x000000a3,0x000300f7,0x000006fd,0x00000000,0x000400fa, + 0x000006fb,0x000006fc,0x000006fd,0x000200f8,0x000006fc,0x000200f9,0x0000070e,0x000200f8, + 0x000006fd,0x000200f9,0x000006fe,0x000200f8,0x000006fe,0x000700f5,0x00000014,0x000008df, + 0x0000023e,0x00000621,0x000006f9,0x000006fd,0x000700f5,0x00000014,0x000008d0,0x00000934, + 0x00000621,0x00000606,0x000006fd,0x00050091,0x00000014,0x00000701,0x00000723,0x000008d0, + 0x00050081,0x00000014,0x00000703,0x00000701,0x000008df,0x00050081,0x00000014,0x00000705, + 0x00000703,0x00000529,0x00050080,0x0000000c,0x00000708,0x0000051d,0x000000e3,0x00060041, + 0x00000116,0x00000709,0x00000128,0x000000a3,0x00000708,0x0004003d,0x000000fc,0x0000070a, + 0x00000709,0x00050051,0x0000000c,0x0000070c,0x0000070a,0x00000000,0x000200f9,0x0000070e, + 0x000200f8,0x0000070e,0x000900f5,0x0000000c,0x00000900,0x00000906,0x00000620,0x00000906, + 0x000006fc,0x0000070c,0x000006fe,0x000900f5,0x00000014,0x000008e3,0x000008e9,0x00000620, + 0x000008e9,0x000006fc,0x00000705,0x000006fe,0x000900f5,0x0000003d,0x000008e2,0x00000355, + 0x00000620,0x00000355,0x000006fc,0x00000378,0x000006fe,0x00060041,0x0000039e,0x0000039f, + 0x0000039c,0x000000a3,0x00000519,0x0004003d,0x0000011a,0x000003a0,0x0000039f,0x00050051, + 0x0000000c,0x000003a3,0x000003a0,0x00000000,0x000500c7,0x0000000c,0x000003a5,0x000003a3, + 0x000003a4,0x000500aa,0x0000003d,0x000003aa,0x000003a5,0x00000061,0x000300f7,0x000003ad, + 0x00000000,0x000400fa,0x000003aa,0x000003ac,0x000003b0,0x000200f8,0x000003b0,0x000200f9, + 0x000003ad,0x000200f8,0x000003ac,0x00050051,0x0000000c,0x000003af,0x000003a0,0x00000001, + 0x000200f9,0x000003ad,0x000200f8,0x000003ad,0x000700f5,0x0000000c,0x0000091d,0x000003a3, + 0x000003b0,0x000003af,0x000003ac,0x000500c2,0x0000000c,0x000003b4,0x0000091d,0x0000019c, + 0x00050041,0x000003be,0x000003bf,0x000003b9,0x000003ba,0x0004003d,0x0000000c,0x000003c0, + 0x000003bf,0x000500aa,0x0000003d,0x00000786,0x000003b4,0x00000061,0x000300f7,0x0000078f, + 0x00000000,0x000400fa,0x00000786,0x0000078e,0x00000787,0x000200f8,0x00000787,0x00050080, + 0x0000000c,0x00000789,0x000003b4,0x00000068,0x00050084,0x0000000c,0x0000078b,0x00000789, + 0x000003c0,0x0006000c,0x00000014,0x0000078c,0x00000001,0x0000003e,0x0000078b,0x00050051, + 0x00000006,0x0000078d,0x0000078c,0x00000000,0x000200f9,0x0000078f,0x000200f8,0x0000078e, + 0x000200f9,0x0000078f,0x000200f8,0x0000078f,0x000700f5,0x00000006,0x0000091e,0x0000078d, + 0x00000787,0x00000056,0x0000078e,0x000300f7,0x000003c5,0x00000000,0x000400fa,0x000003aa, + 0x000003c4,0x000003c5,0x000200f8,0x000003c4,0x0004007f,0x00000006,0x000003c7,0x0000091e, + 0x000200f9,0x000003c5,0x000200f8,0x000003c5,0x000700f5,0x00000006,0x0000091f,0x0000091e, + 0x0000078f,0x000003c7,0x000003c4,0x00050041,0x000000a7,0x000003cb,0x000003c9,0x00000061, + 0x0003003e,0x000003cb,0x0000091f,0x000500c2,0x0000000c,0x000003d2,0x000003a3,0x000003d1, + 0x000500c7,0x0000000c,0x000003d3,0x000003d2,0x000003a4,0x00040070,0x00000006,0x000003d4, + 0x000003d3,0x0003003e,0x000003ce,0x000003d4,0x00050080,0x0000000c,0x000003e0,0x0000051d, + 0x000000e3,0x00060041,0x000003e2,0x000003e3,0x000003dd,0x000000a3,0x000003e0,0x0004003d, + 0x00000012,0x000003e4,0x000003e3,0x00050051,0x00000006,0x00000798,0x000003e4,0x00000000, + 0x00050051,0x00000006,0x00000799,0x000003e4,0x00000001,0x00050051,0x00000006,0x0000079a, + 0x000003e4,0x00000002,0x00050051,0x00000006,0x0000079b,0x000003e4,0x00000003,0x00050050, + 0x00000014,0x0000079c,0x00000798,0x00000799,0x00050050,0x00000014,0x0000079d,0x0000079a, + 0x0000079b,0x00050050,0x00000015,0x0000079e,0x0000079c,0x0000079d,0x00050080,0x0000000c, + 0x000003e9,0x0000051d,0x000000e7,0x00060041,0x000003e2,0x000003ea,0x000003dd,0x000000a3, + 0x000003e9,0x0004003d,0x00000012,0x000003eb,0x000003ea,0x0007004f,0x00000014,0x000003f0, + 0x000003eb,0x000003eb,0x00000000,0x00000001,0x000500b7,0x00000091,0x000007a7,0x000003e4, + 0x00000090,0x0004009a,0x0000003d,0x000007a8,0x000007a7,0x000300f7,0x000007c7,0x00000000, + 0x000400fa,0x000007a8,0x000007b1,0x000007a9,0x000200f8,0x000007a9,0x00050051,0x00000006, + 0x000007ab,0x000003eb,0x00000000,0x00050083,0x00000006,0x000007ac,0x000007ab,0x000000ba, + 0x00060041,0x000000a7,0x000007ad,0x000000a1,0x000000a2,0x000000b2,0x0003003e,0x000007ad, + 0x000007ac,0x00060041,0x000000a7,0x000007ae,0x000000a1,0x000000a2,0x000000a2,0x0003003e, + 0x000007ae,0x000007ac,0x00060041,0x000000a7,0x000007af,0x000000a1,0x000000a2,0x000000a9, + 0x0003003e,0x000007af,0x000007ac,0x00060041,0x000000a7,0x000007b0,0x000000a1,0x000000a2, + 0x000000a3,0x0003003e,0x000007b0,0x000007ac,0x000200f9,0x000007c7,0x000200f8,0x000007b1, + 0x00050091,0x00000014,0x000007b4,0x0000079e,0x000008e3,0x00050081,0x00000014,0x000007b6, + 0x000007b4,0x000003f0,0x00050051,0x00000006,0x000007b8,0x000007b6,0x00000000,0x00050081, + 0x00000006,0x000007b9,0x000007b8,0x00000055,0x00060041,0x000000a7,0x000007ba,0x000000a1, + 0x000000a2,0x000000a3,0x0003003e,0x000007ba,0x000007b9,0x00050051,0x00000006,0x000007bc, + 0x000007b6,0x00000001,0x00050081,0x00000006,0x000007bd,0x000007bc,0x00000055,0x00060041, + 0x000000a7,0x000007be,0x000000a1,0x000000a2,0x000000a9,0x0003003e,0x000007be,0x000007bd, + 0x00050083,0x00000006,0x000007c1,0x00000055,0x000007b8,0x00060041,0x000000a7,0x000007c2, + 0x000000a1,0x000000a2,0x000000a2,0x0003003e,0x000007c2,0x000007c1,0x00050083,0x00000006, + 0x000007c5,0x00000055,0x000007bc,0x00060041,0x000000a7,0x000007c6,0x000000a1,0x000000a2, + 0x000000b2,0x0003003e,0x000007c6,0x000007c5,0x000200f9,0x000007c7,0x000200f8,0x000007c7, + 0x000500aa,0x0000003d,0x000003f5,0x000003a5,0x00000078,0x000300f7,0x000003f7,0x00000000, + 0x000400fa,0x000003f5,0x000003f6,0x0000040d,0x000200f8,0x0000040d,0x000300f7,0x00000412, + 0x00000000,0x000400fa,0x000003aa,0x00000411,0x0000041e,0x000200f8,0x0000041e,0x00060041, + 0x000003e2,0x00000423,0x000003dd,0x000000a3,0x0000051d,0x0004003d,0x00000012,0x00000424, + 0x00000423,0x00050051,0x00000006,0x000007ce,0x00000424,0x00000000,0x00050051,0x00000006, + 0x000007cf,0x00000424,0x00000001,0x00050051,0x00000006,0x000007d0,0x00000424,0x00000002, + 0x00050051,0x00000006,0x000007d1,0x00000424,0x00000003,0x00050050,0x00000014,0x000007d2, + 0x000007ce,0x000007cf,0x00050050,0x00000014,0x000007d3,0x000007d0,0x000007d1,0x00050050, + 0x00000015,0x000007d4,0x000007d2,0x000007d3,0x00060041,0x000003e2,0x0000042a,0x000003dd, + 0x000000a3,0x00000524,0x0004003d,0x00000012,0x0000042b,0x0000042a,0x00050091,0x00000014, + 0x0000042f,0x000007d4,0x000008e3,0x0007004f,0x00000014,0x00000431,0x0000042b,0x0000042b, + 0x00000000,0x00000001,0x00050081,0x00000014,0x00000432,0x0000042f,0x00000431,0x000500aa, + 0x0000003d,0x00000434,0x000003a5,0x000000e3,0x000500aa,0x0000003d,0x00000436,0x000003a5, + 0x000000e7,0x000500a6,0x0000003d,0x00000437,0x00000434,0x00000436,0x000300f7,0x00000439, + 0x00000000,0x000400fa,0x00000437,0x00000438,0x0000045e,0x000200f8,0x0000045e,0x00050051, + 0x0000000c,0x00000461,0x000003a0,0x00000001,0x0004007c,0x00000006,0x00000462,0x00000461, + 0x00050051,0x00000006,0x00000465,0x0000042b,0x00000002,0x00050051,0x00000006,0x00000467, + 0x00000432,0x00000000,0x00050051,0x00000006,0x00000469,0x00000432,0x00000001,0x00050083, + 0x00000006,0x0000046d,0x0000046b,0x00000465,0x00070050,0x00000012,0x0000046e,0x00000467, + 0x00000469,0x00000462,0x0000046d,0x0003003e,0x0000040b,0x0000046e,0x000200f9,0x00000439, + 0x000200f8,0x00000438,0x00050051,0x0000000c,0x0000043b,0x000003a0,0x00000001,0x0004007c, + 0x00000006,0x0000043c,0x0000043b,0x0004007f,0x00000006,0x0000043d,0x0000043c,0x00050041, + 0x000000a7,0x0000043e,0x0000040b,0x000000e7,0x0003003e,0x0000043e,0x0000043d,0x00050051, + 0x00000006,0x00000441,0x0000042b,0x00000002,0x000500ba,0x0000003d,0x00000444,0x00000441, + 0x00000443,0x000300f7,0x00000446,0x00000000,0x000400fa,0x00000444,0x00000445,0x00000448, + 0x000200f8,0x00000448,0x00050051,0x00000006,0x0000044a,0x0000042b,0x00000003,0x00050041, + 0x000000a7,0x0000044b,0x0000040b,0x000000e3,0x0003003e,0x0000044b,0x0000044a,0x000200f9, + 0x00000446,0x000200f8,0x00000445,0x00050041,0x000000a7,0x00000447,0x0000040b,0x000000e3, + 0x0003003e,0x00000447,0x0000021a,0x000200f9,0x00000446,0x000200f8,0x00000446,0x000300f7, + 0x0000044f,0x00000000,0x000400fa,0x00000434,0x0000044e,0x00000454,0x000200f8,0x00000454, + 0x00050041,0x000000a7,0x00000455,0x0000040b,0x000000e3,0x0004003d,0x00000006,0x00000456, + 0x00000455,0x0004007f,0x00000006,0x00000457,0x00000456,0x0003003e,0x00000455,0x00000457, + 0x00050041,0x000000a7,0x0000045a,0x0000040b,0x00000061,0x00050051,0x00000006,0x0000045b, + 0x00000432,0x00000000,0x0003003e,0x0000045a,0x0000045b,0x00050041,0x000000a7,0x0000045c, + 0x0000040b,0x00000078,0x00050051,0x00000006,0x0000045d,0x00000432,0x00000001,0x0003003e, + 0x0000045c,0x0000045d,0x000200f9,0x0000044f,0x000200f8,0x0000044e,0x00050041,0x000000a7, + 0x00000450,0x0000040b,0x00000078,0x0003003e,0x00000450,0x00000056,0x00050051,0x00000006, + 0x00000452,0x00000432,0x00000000,0x00050041,0x000000a7,0x00000453,0x0000040b,0x00000061, + 0x0003003e,0x00000453,0x00000452,0x000200f9,0x0000044f,0x000200f8,0x0000044f,0x000200f9, + 0x00000439,0x000200f8,0x00000439,0x000200f9,0x00000412,0x000200f8,0x00000411,0x000500c2, + 0x0000000c,0x00000416,0x000003a3,0x0000019c,0x000500aa,0x0000003d,0x000007da,0x00000416, + 0x00000061,0x000300f7,0x000007e3,0x00000000,0x000400fa,0x000007da,0x000007e2,0x000007db, + 0x000200f8,0x000007db,0x00050080,0x0000000c,0x000007dd,0x00000416,0x00000068,0x00050084, + 0x0000000c,0x000007df,0x000007dd,0x000003c0,0x0006000c,0x00000014,0x000007e0,0x00000001, + 0x0000003e,0x000007df,0x00050051,0x00000006,0x000007e1,0x000007e0,0x00000000,0x000200f9, + 0x000007e3,0x000200f8,0x000007e2,0x000200f9,0x000007e3,0x000200f8,0x000007e3,0x000700f5, + 0x00000006,0x00000920,0x000007e1,0x000007db,0x00000056,0x000007e2,0x00050041,0x000000a7, + 0x0000041d,0x000003c9,0x00000078,0x0003003e,0x0000041d,0x00000920,0x000200f9,0x00000412, + 0x000200f8,0x00000412,0x000200f9,0x000003f7,0x000200f8,0x000003f6,0x00050051,0x0000000c, + 0x000003fa,0x000003a0,0x00000001,0x0006000c,0x00000012,0x000003fb,0x00000001,0x00000040, + 0x000003fa,0x0003003e,0x0000040b,0x000003fb,0x000200f9,0x000003f7,0x000200f8,0x000003f7, + 0x000300f7,0x00000472,0x00000000,0x000400fa,0x000008e2,0x00000471,0x00000482,0x000200f8, + 0x00000482,0x00050041,0x00000477,0x00000484,0x000003b9,0x00000483,0x0004003d,0x00000006, + 0x00000485,0x00000484,0x00070050,0x00000012,0x0000048c,0x00000485,0x00000485,0x00000485, + 0x00000485,0x000200f9,0x00000472,0x000200f8,0x00000471,0x00050041,0x00000477,0x00000478, + 0x000003b9,0x000000a2,0x0004003d,0x00000006,0x00000479,0x00000478,0x00050041,0x00000477, + 0x0000047b,0x000003b9,0x000000b2,0x0004003d,0x00000006,0x0000047c,0x0000047b,0x00050051, + 0x00000006,0x000007e9,0x000008e3,0x00000000,0x00050085,0x00000006,0x000007eb,0x000007e9, + 0x00000479,0x00050083,0x00000006,0x000007ec,0x000007eb,0x00000055,0x00050051,0x00000006, + 0x000007ee,0x000008e3,0x00000001,0x00050085,0x00000006,0x000007f0,0x000007ee,0x0000047c, + 0x0006000c,0x00000006,0x000007f2,0x00000001,0x00000006,0x0000047c,0x00050083,0x00000006, + 0x000007f3,0x000007f0,0x000007f2,0x00070050,0x00000012,0x000007f4,0x000007ec,0x000007f3, + 0x00000056,0x00000055,0x00040070,0x00000006,0x000007f8,0x00000900,0x00050085,0x00000006, + 0x000007f9,0x000007f8,0x00000085,0x00050083,0x00000006,0x000007fa,0x00000055,0x000007f9, + 0x00060052,0x00000012,0x0000082d,0x000007fa,0x000007f4,0x00000002,0x000200f9,0x00000472, + 0x000200f8,0x00000472,0x000700f5,0x00000012,0x0000092b,0x0000048c,0x00000482,0x0000082d, + 0x00000471,0x00050041,0x0000040a,0x0000048e,0x000000a1,0x000000a3,0x0003003e,0x0000048e, + 0x0000092b,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_path.webgpu_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..7edb9611b859601cc2e481778ad6a2f6c9e294d6 GIT binary patch literal 16300 zcmZA73AmkAbq3&*goFT*8L9#yVUW=Gz(ySMFan?CiC^HSV>C|3BxRF{5`} zzt`igw-WWq)wn^_5 zeR{q8d)C0vBFxR{?}^H?^h?v1r+*{;(e#a?I41v%j?TX(*m}JUdq>ZlclfbK%v*BC z!2H3*^Oh_>++BxUM=Y#J!W zA6m3@&d|FOna!|F9U_~)aOj*Phn6fISajOpI$6rqmz}$C;X2va)J}ah^r$#LV)`(> zS?D({;CsCuTARQBuxyL)CpNv;gnnbwLwEId4L|b;HskthnB0aZdd#BvW;-@{FH2&< zk6ARFZ<7qivEFn0_G9|%eq5t(2(IRGLw94Y2!Gu4Vf!zK{+rm)Lu<279pR;W(rF|7 z=G1vaJ8(pQY~*L1KEjU+e`H5LhoU#5!;cSt+(9Gyj>dweJYON%(>JBmAb}FYM&AS@`qz8vtXQ8nBnnznAFVL!2{RVP1}1!AXjt6G_j>((KRLAZDSn608h+C_w6^Le z7w2Kv-^kf`Wn}!o%r;76YXYBj>Vmt#i6#j=3VMlf_=O6Zl4(1Mk&FowVDr=M759Vn)Qaz}=bFfeWyAMJmo^7B?iKsZ z+So7d7Om*ggVU=s^~3PpGvw}JYG2kpRO?s#jvS})?QSBM1KK?7h2lr%kvEAXH*!YC z^xR(>T{K&3T>Oabn4bGhBSUv}@pR=ar(S!nLT}&bEpj7{j(l=3dg!e~nfs*lt>V|d zL2G{%-g=S?jkj)iwyzAoRYn+|eXixc{iuxe^LXfE2>l%M^!^BaWThi5{_?4kG_Ny|o7rW%EL)RSH-<3{> zoZh|ZY5f|KKbXEY7fjhd9NztaSF@+nD?a|2bpF)k&lzFr@~Uj0wT&0Q+lrTSKe-6$ znlpY>Q>d5|!mo|Oc8TQKD9*&to_%ay=Ck8`Qg{D9pRVv`HR<<{uO=w-nPYGIn1wzw+1W1yD#z9 z=*jSpZ*t7E;(y-fzp;*gwPbp|X?y0@aF(WquRU8a=Js_qU6GZ;Ge?OrKviwdDUZEFWF``Zi5((mMZ}_xaw`-Ln?X z)^XuW_ie+nWxF-m1>vpDMHy3ye$A{6-a7`Y_+^c!e@UaAJ#xHvj?%|_=fK+&-Z$(M zd(Harh-bQ*b-TUU?QE>A4yRk= z%jx3fa(C?HC5Bw_o|Q1U$>ZMep6&GSYcjs^Uk{)E`*GRhJttv!caG;FzWhBF#@y7< zvr)a((6bNE?~gLd0mcvBv#)CSRHNC_-!KjX^?lLD4}TsXj%&`-gDqIFVBPcJOiA>5 z53oN!G~e_p&r5=Nrn{@I2~9RCz1xcC-qcYc>lZb^gi75@bvKY>>ZU^ zSi@)Y!iMgzVVkqGPLvXT&y?FGeP@P=z)yCj${6e zZ;4mA{3bLX+M*WYx5410^ZTZwu7y3oZK6EZ^`s;;O2mY5eY+NunJGJm^S|1-L6?==+gWiLYRgPOV z?BQUuF&oB?KQe2yGF>g~g$cpQ)j}-T#^K?fgXRR=B)mE8*5uwT z)PQWW$jD)bXJtJ5HV^N4C>FVS$z_YsWV7PeeYF+6)+6r6uqO8G*1^du*H<<@bEsTj z6$~!d(%Yu#nUlK9al2r2SA?z{Cx-WIl_PoOxP53cdGzmt(6HJ++og_^!fS<1Y*^f_ z!?tgjd`oXq!{lbo%yV)uKKUqYhtPfdhIw!GEhJqsd&j(XN*;3W)_&*kH81j-*K0zP zRqb~T4bwHbSM7HTMqV}Dqv@Fo9p`V)VDQqJ(sazNboL4cul3p|w7umW=Jw3N{jpzo z_&{i9|Mj7@7ZZnU|8$u1kFHuC7}}ko)%iat7`${2X*%ZiLhQ?r@sHVq=JCedjqV9| z3w<%joaHHzIm2XplU3e_g(i1y<-IVYCU3H7=`eYt>%317?JTpcdt^p7{`3yWxr09#`k{s$)UfW^ zJvbO$vO2pTiJiD)b#^PCj|T7N^YQTVNs8<8SrJS=WR=hB;|t!+XKKT``5YFEE?MPs zW9-Bwt9)wD-4vX>dvf_o_EP0xtow3m>aHI47dtst z4L%oI4Z3Ig&hYTk`9f$ux;l3SgV#Cxr_eCA6LLD8&o770^i!o?kNn>3Irr4vp~;?% zP(AMtt*Iy3J?Sv@M3=vR4$U9m{4I|^^jAXrZil?`xi2&wGIc3`Ms;C#MCL?Ct>}wY zcf?miU!3l>X?<=jYkA=P{olISSol#R)vY(`XFI`=Y760Etvk{}-WBxrnUu1m! zIHSfF*%RsikJiOLsR_e=+Z|^&FSEn*+vv=ww z2e^0M!uRRm>cY1gh-L1z4o`-*2DJxj&7KNwPm)*eKMM`F-WO-?YB1K^>ada?=@t6lGWZ>8`|FS zy&t{8M`dHceJ=*DH69I5ug}9{Lh}Ky&#z-cdq>hWempaLrXCj=d3^>LA9}CY+xzOi zS$NG}BikSyrdH_dQg?n{5!&Z&@hj(zLyL7plh+z;65L%t?t7CAy-l0$uA#-JV;w4% zv1)rw=0Qij*~z2w-y-y$o&5h2UXwrB4(VH_%imb@2V2$d)$N1PB~$as88tbRO-hH!8Lck9 z_rt^S=7~4Is{c-*)qirjwJCh(hG*!}sdKVRX#1AD=CxaB^YV9!n#1nF;N~UYDWNs_ zlI@WWlMlMq__d+svvayw^*OV2jkU&CCMF&8VaHG9w0CGZ`CCclv`;X2<#a%3O-^L{ zro-ffuAKG{EvH@6#jKo4*H}3{5;+}tvg4=r-9e%4OZN4=I3Rnai`VV&SEpB!4v{r#!V%v*!O)m(l)100n2aNn2T629yQn*EU}cCFc|Y@5AY7KGO1LUvj@ zOfG1jZNwN1EslL(a-(%3U!6S3q1lra_TeO}ZfaSvuMZ{{wIHvv`46F;bAJ!6?+HH=4DPJmm{GG= z;2%wg*(>Psb3|xiR*94bys~NJY6z-s(cykDWA(e8Crb%jJ`N>xhtb4 z7dorbZ%UVovF5)rv^!4h!fp$#R%%jp|5Px#WOCu3FMjJjS{>Sb=I`INuRjwEJ`i8E zhi?xLw?5`u&y72Ssr#zy-$bYPW3;pI?eKG2uk-QU@O1S$$B%`kO9tC20Ur;|mY%Z!`%!3X zvO|+!8(r^gPXyclXv)!OWGc=J9iMI$75jpVm>l@1%}mnm>JU z=+;^oOZU;}numSBjvu;z$S6l+>3+NEdM9DWPv!M|Xmal;b=SQR%w0!Td*)A}>-$>k z_fmMxo+0})dAitWxzxKR9RHUlH&$*xNnF2gnM^00ZppqInfGS0aZOe^j!J%Vq+{Qy z-;dyV+&-Ll#=r;p&jCAB$I_|xvg8SVJ9U~pTm7ybVzf1XK zy5Fj-jQ*=KCwcq3?@disd9Mr))9Nm}Ej;|z^t!h{6B=H3!)HTl)|u>%^v|bTXQLX> z!IM?IJ41`-Ty=HmT3>bAF0~P#ANuU;d-gAeCigx2;igX;t%w!^8MP*L%yF(0uS;a%1`TJ5O>k>9SSJ zRq_3;(0=!$PE!*TPrvH_z3|q?Z+~jPd_OeYeyP8G{2(-(55F72S51E!x_i$22I%Q@ zzYAKKxa8K+ZvcK4nyl*i(c}!%3j0{Y)W5JB8kQ?$9rp2tF|TLAieP;5QP?L!v!`Fr zhZ{rFC98Qn8%O5xO#C@_=JAX4ng@B!9xuFJS8G0f5LQg28d zocT`&gWCsdGHUh#{0r%;)9nLe)!_Ef<-gw5?+6C>ek12q89y8T=8U(b`;Cn?gV8OW z&vkU@(Sdb!?(FESZaT28&gVNiE1M3Cj{RzG=3!3Pr5KiF*KQ8|1y zblFusVRXyxkiKB$foX+(r(tSb*moP&J-3fFEaBFj z(eDN0laD&L-w(~6ex2JNgr-YYIq%-dd8ba!dju!DuI;fG)VjGnH^z4qk3 z!PwBL+V3A)?VpZbVFxzsnP8tvEa&^6V06jU|B#HDH6lAW{cY*ahEcsd=LSOG6#w$5 z?*L8>2Cte9hL&%)rl*IOuU2|P4dbi!;90@WOy^^E?k;!oqR{N=i$%wMuu(=b`%wOJ zm3QU(y3jAr_4UEv_3Sz{H06s(HeDGKLM~Cj}2+g>g|9tk#BZKa4(_UY zU)ege_Z9Dpb^d;sGYuERIy@a-vkqiWr9Ym|m$9DrPlRUIeHZ*mF!%$BQSX934L@9? zeC7yU^L;WjnI>Ox#SpK{!|PpbQr^AT$wTevR;{*6F5cCwky_#DcWa?0cz3>7?t1yS zJ6;TZQ@UK`?ri_5@za`|Uuy{O`r%LQ7DuM3ozErj4FCRgv5ay(KjWq8-qHOQyY}$% zhS$AvWq4S(izxE|)YJX0)pr-a314MP|Llt9R<>gZT_u zv0exdTOPQ4z8Ibj*|BX+Uz;4^e0v6TYpS;Pnzi2}zO8|EV^j6sF#Of&H%Dh>x;=rX L|59dlaQgoN$$jaO literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.h new file mode 100644 index 000000000..681424e0e --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.h @@ -0,0 +1,70 @@ +#pragma once + +const uint32_t draw_msaa_resolve_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000027,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0006000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009, + 0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000009, + 0x00006265,0x00030005,0x0000000c,0x00003969,0x00030005,0x00000024,0x0000424d,0x00040006, + 0x00000024,0x00000000,0x00006250,0x00040006,0x00000024,0x00000001,0x00006359,0x00040006, + 0x00000024,0x00000002,0x00006552,0x00040006,0x00000024,0x00000003,0x00006553,0x00040006, + 0x00000024,0x00000004,0x0000366d,0x00040006,0x00000024,0x00000005,0x0000676d,0x00040006, + 0x00000024,0x00000006,0x00006544,0x00040006,0x00000024,0x00000007,0x00006545,0x00040006, + 0x00000024,0x00000008,0x00003755,0x00040006,0x00000024,0x00000009,0x0000676a,0x00040006, + 0x00000024,0x0000000a,0x0000635a,0x00040006,0x00000024,0x0000000b,0x00003157,0x00040006, + 0x00000024,0x0000000c,0x0000676e,0x00040006,0x00000024,0x0000000d,0x00003559,0x00040006, + 0x00000024,0x0000000e,0x0000324f,0x00040006,0x00000024,0x0000000f,0x00006461,0x00040006, + 0x00000024,0x00000010,0x00006579,0x00040006,0x00000024,0x00000011,0x00003376,0x00040006, + 0x00000024,0x00000012,0x00003377,0x00040006,0x00000024,0x00000013,0x00006462,0x00040006, + 0x00000024,0x00000014,0x00006767,0x00030005,0x00000026,0x0000006b,0x00030047,0x00000009, + 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00030047,0x0000000c,0x00000000, + 0x00040047,0x0000000c,0x00000021,0x00000000,0x00040047,0x0000000c,0x00000022,0x00000002, + 0x00040047,0x0000000c,0x0000002b,0x00000000,0x00030047,0x0000000d,0x00000000,0x00030047, + 0x00000012,0x00000000,0x00030047,0x00000013,0x00000000,0x00030047,0x00000015,0x00000000, + 0x00030047,0x00000016,0x00000000,0x00030047,0x00000017,0x00000000,0x00030047,0x00000019, + 0x00000000,0x00030047,0x0000001a,0x00000000,0x00030047,0x0000001b,0x00000000,0x00030047, + 0x0000001d,0x00000000,0x00030047,0x0000001e,0x00000000,0x00030047,0x00000020,0x00000000, + 0x00030047,0x00000024,0x00000002,0x00050048,0x00000024,0x00000000,0x00000023,0x00000000, + 0x00050048,0x00000024,0x00000001,0x00000023,0x00000004,0x00050048,0x00000024,0x00000002, + 0x00000023,0x00000008,0x00050048,0x00000024,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x00000024,0x00000004,0x00000023,0x00000010,0x00050048,0x00000024,0x00000005,0x00000023, + 0x00000014,0x00050048,0x00000024,0x00000006,0x00000023,0x00000018,0x00050048,0x00000024, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x00000024,0x00000008,0x00000023,0x00000020, + 0x00050048,0x00000024,0x00000009,0x00000023,0x00000030,0x00050048,0x00000024,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x00000024,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x00000024,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000024,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x00000024,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000024, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x00000024,0x00000010,0x00000023,0x00000054, + 0x00050048,0x00000024,0x00000011,0x00000023,0x00000058,0x00050048,0x00000024,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x00000024,0x00000013,0x00000023,0x00000060,0x00050048, + 0x00000024,0x00000014,0x00000023,0x00000064,0x00040047,0x00000026,0x00000021,0x00000000, + 0x00040047,0x00000026,0x00000022,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004, + 0x00040020,0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003, + 0x00090019,0x0000000a,0x00000006,0x00000006,0x00000000,0x00000000,0x00000001,0x00000002, + 0x00000000,0x00040020,0x0000000b,0x00000000,0x0000000a,0x0004003b,0x0000000b,0x0000000c, + 0x00000000,0x00040015,0x0000000e,0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f, + 0x00000000,0x00040017,0x00000010,0x0000000e,0x00000002,0x0005002c,0x00000010,0x00000011, + 0x0000000f,0x0000000f,0x0004002b,0x0000000e,0x00000014,0x00000001,0x0004002b,0x0000000e, + 0x00000018,0x00000002,0x0004002b,0x0000000e,0x0000001c,0x00000003,0x0004002b,0x00000006, + 0x0000001f,0x3e800000,0x00040015,0x00000021,0x00000020,0x00000000,0x00040017,0x00000022, + 0x0000000e,0x00000004,0x00040017,0x00000023,0x00000006,0x00000002,0x0017001e,0x00000024, + 0x00000006,0x00000006,0x00000006,0x00000006,0x00000021,0x00000021,0x00000021,0x00000021, + 0x00000022,0x00000023,0x00000023,0x00000021,0x00000006,0x00000021,0x00000006,0x00000006, + 0x00000021,0x00000006,0x00000006,0x00000006,0x00000021,0x00040020,0x00000025,0x00000002, + 0x00000024,0x0004003b,0x00000025,0x00000026,0x00000002,0x00050036,0x00000002,0x00000004, + 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000000a,0x0000000d,0x0000000c, + 0x00070062,0x00000007,0x00000012,0x0000000d,0x00000011,0x00000040,0x0000000f,0x0004003d, + 0x0000000a,0x00000013,0x0000000c,0x00070062,0x00000007,0x00000015,0x00000013,0x00000011, + 0x00000040,0x00000014,0x00050081,0x00000007,0x00000016,0x00000012,0x00000015,0x0004003d, + 0x0000000a,0x00000017,0x0000000c,0x00070062,0x00000007,0x00000019,0x00000017,0x00000011, + 0x00000040,0x00000018,0x00050081,0x00000007,0x0000001a,0x00000016,0x00000019,0x0004003d, + 0x0000000a,0x0000001b,0x0000000c,0x00070062,0x00000007,0x0000001d,0x0000001b,0x00000011, + 0x00000040,0x0000001c,0x00050081,0x00000007,0x0000001e,0x0000001a,0x0000001d,0x0005008e, + 0x00000007,0x00000020,0x0000001e,0x0000001f,0x0003003e,0x00000009,0x00000020,0x000100fd, + 0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_msaa_resolve.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..80dbf94fdaeadef0b828ee5d92f3249e08fa8500 GIT binary patch literal 2084 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.h new file mode 100644 index 000000000..576623ddb --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.h @@ -0,0 +1,931 @@ +#pragma once + +const uint32_t draw_path_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000013ea,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0010000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x000004cd, + 0x000004da,0x000004e1,0x00000513,0x00000542,0x00000555,0x0000055d,0x00000585,0x00000591, + 0x000005a7,0x000005d0,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc, + 0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666, + 0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373, + 0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f, + 0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004, + 0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005, + 0x00000004,0x6e69616d,0x00000000,0x00030005,0x00000136,0x00006752,0x00030005,0x0000016a, + 0x0000674e,0x00030005,0x0000019c,0x00004351,0x00030005,0x000001a0,0x00003954,0x00030005, + 0x0000039e,0x0000674d,0x00030005,0x000003f9,0x00006749,0x00030005,0x00000437,0x00004444, + 0x00030005,0x00000439,0x00006277,0x00030005,0x00000459,0x00004344,0x00030005,0x0000045b, + 0x00003552,0x00030005,0x0000047b,0x0000674a,0x00040005,0x000004bf,0x37483742,0x00000000, + 0x00030005,0x000004cd,0x0000307a,0x00030005,0x000004da,0x00000049,0x00030005,0x000004e1, + 0x00003748,0x00030005,0x000004ea,0x0000674f,0x00030005,0x000004fa,0x0000674b,0x00030005, + 0x0000050f,0x00006747,0x00030005,0x00000513,0x00003153,0x00030005,0x0000051e,0x0000674c, + 0x00040005,0x00000529,0x30653742,0x00000000,0x00030005,0x00000542,0x00003466,0x00040005, + 0x0000054c,0x34663742,0x00000000,0x00030005,0x00000555,0x00003065,0x00030005,0x0000055d, + 0x0000306a,0x00040005,0x0000055e,0x306a3742,0x00000000,0x00030005,0x00000581,0x00006748, + 0x00030005,0x00000585,0x0000304e,0x00030005,0x00000591,0x0000316b,0x00030005,0x000005a7, + 0x00003159,0x00060005,0x000005d0,0x465f6c67,0x43676172,0x64726f6f,0x00000000,0x00030005, + 0x000005d2,0x0000424d,0x00040006,0x000005d2,0x00000000,0x00006250,0x00040006,0x000005d2, + 0x00000001,0x00006359,0x00040006,0x000005d2,0x00000002,0x00006552,0x00040006,0x000005d2, + 0x00000003,0x00006553,0x00040006,0x000005d2,0x00000004,0x0000366d,0x00040006,0x000005d2, + 0x00000005,0x0000676d,0x00040006,0x000005d2,0x00000006,0x00006544,0x00040006,0x000005d2, + 0x00000007,0x00006545,0x00040006,0x000005d2,0x00000008,0x00003755,0x00040006,0x000005d2, + 0x00000009,0x0000676a,0x00040006,0x000005d2,0x0000000a,0x0000635a,0x00040006,0x000005d2, + 0x0000000b,0x00003157,0x00040006,0x000005d2,0x0000000c,0x0000676e,0x00040006,0x000005d2, + 0x0000000d,0x00003559,0x00040006,0x000005d2,0x0000000e,0x0000324f,0x00040006,0x000005d2, + 0x0000000f,0x00006461,0x00040006,0x000005d2,0x00000010,0x00006579,0x00040006,0x000005d2, + 0x00000011,0x00003376,0x00040006,0x000005d2,0x00000012,0x00003377,0x00040006,0x000005d2, + 0x00000013,0x00006462,0x00040006,0x000005d2,0x00000014,0x00006767,0x00030005,0x000005d4, + 0x0000006b,0x00040047,0x00000136,0x00000001,0x0000000b,0x00040047,0x0000016a,0x00000001, + 0x00000007,0x00030047,0x0000019c,0x00000000,0x00040047,0x0000019c,0x00000021,0x0000000a, + 0x00040047,0x0000019c,0x00000022,0x00000000,0x00030047,0x000001a0,0x00000000,0x00040047, + 0x000001a0,0x00000021,0x0000000a,0x00040047,0x000001a0,0x00000022,0x00000000,0x00040047, + 0x0000039e,0x00000001,0x00000006,0x00040047,0x000003f9,0x00000001,0x00000002,0x00030047, + 0x00000437,0x00000000,0x00040047,0x00000437,0x00000021,0x00000009,0x00040047,0x00000437, + 0x00000022,0x00000000,0x00030047,0x00000439,0x00000000,0x00040047,0x00000439,0x00000021, + 0x00000009,0x00040047,0x00000439,0x00000022,0x00000000,0x00030047,0x00000459,0x00000000, + 0x00040047,0x00000459,0x00000021,0x0000000c,0x00040047,0x00000459,0x00000022,0x00000001, + 0x00030047,0x0000045b,0x00000000,0x00040047,0x0000045b,0x00000021,0x0000000c,0x00040047, + 0x0000045b,0x00000022,0x00000001,0x00040047,0x0000047b,0x00000001,0x00000003,0x00040047, + 0x000004bf,0x00000021,0x00000003,0x00040047,0x000004bf,0x00000022,0x00000002,0x00040047, + 0x000004bf,0x0000002b,0x00000003,0x00030047,0x000004c9,0x00000000,0x00030047,0x000004cd, + 0x00000000,0x00030047,0x000004cd,0x0000000e,0x00040047,0x000004cd,0x0000001e,0x00000003, + 0x00030047,0x000004ce,0x00000000,0x00030047,0x000004d4,0x00000000,0x00040047,0x000004da, + 0x0000001e,0x00000002,0x00040047,0x000004e1,0x0000001e,0x00000003,0x00030047,0x000004e7, + 0x00000000,0x00040047,0x000004ea,0x00000001,0x00000008,0x00030047,0x000004f9,0x00000000, + 0x00040047,0x000004fa,0x00000001,0x00000004,0x00030047,0x00000503,0x00000000,0x00030047, + 0x00000504,0x00000000,0x00030047,0x00000505,0x00000000,0x00030047,0x00000506,0x00000000, + 0x00030047,0x00000507,0x00000000,0x00030047,0x0000050a,0x00000000,0x00030047,0x0000050e, + 0x00000000,0x00040047,0x0000050f,0x00000001,0x00000000,0x00030047,0x00000513,0x00000000, + 0x00030047,0x00000513,0x0000000e,0x00040047,0x00000513,0x0000001e,0x00000004,0x00030047, + 0x00000515,0x00000000,0x00030047,0x0000051c,0x00000000,0x00030047,0x0000051d,0x00000000, + 0x00040047,0x0000051e,0x00000001,0x00000005,0x00030047,0x00000523,0x00000000,0x00040047, + 0x00000529,0x00000021,0x00000001,0x00040047,0x00000529,0x00000022,0x00000002,0x00040047, + 0x00000529,0x0000002b,0x00000001,0x00030047,0x00000530,0x00000000,0x00030047,0x0000053e, + 0x00000000,0x00030047,0x00000542,0x00000000,0x00040047,0x00000542,0x0000001e,0x00000002, + 0x00030047,0x0000054c,0x00000000,0x00040047,0x0000054c,0x00000021,0x00000002,0x00040047, + 0x0000054c,0x00000022,0x00000002,0x00040047,0x0000054c,0x0000002b,0x00000002,0x00030047, + 0x0000054d,0x00000000,0x00030047,0x0000054e,0x00000000,0x00030047,0x0000054f,0x00000000, + 0x00030047,0x00000550,0x00000000,0x00030047,0x00000551,0x00000000,0x00030047,0x00000554, + 0x00000000,0x00040047,0x00000555,0x0000001e,0x00000001,0x00030047,0x0000055b,0x00000000, + 0x00030047,0x0000055d,0x00000000,0x00040047,0x0000055d,0x0000001e,0x00000000,0x00030047, + 0x0000055e,0x00000000,0x00040047,0x0000055e,0x00000021,0x00000000,0x00040047,0x0000055e, + 0x00000022,0x00000002,0x00040047,0x0000055e,0x0000002b,0x00000000,0x00030047,0x0000055f, + 0x00000000,0x00030047,0x00000560,0x00000000,0x00030047,0x00000566,0x00000000,0x00030047, + 0x00000572,0x00000000,0x00030047,0x0000057a,0x00000000,0x00030047,0x0000057c,0x00000000, + 0x00040047,0x00000581,0x00000001,0x00000001,0x00040047,0x00000585,0x0000001e,0x00000005, + 0x00030047,0x0000058f,0x00000000,0x00040047,0x00000591,0x0000001e,0x00000000,0x00030047, + 0x0000059d,0x00000000,0x00030047,0x0000059e,0x00000000,0x00030047,0x000005a1,0x00000000, + 0x00030047,0x000005a2,0x00000000,0x00030047,0x000005a3,0x00000000,0x00030047,0x000005a4, + 0x00000000,0x00030047,0x000005a7,0x00000000,0x00030047,0x000005a7,0x0000000e,0x00040047, + 0x000005a7,0x0000001e,0x00000006,0x00030047,0x000005a8,0x00000000,0x00030047,0x000005b3, + 0x00000000,0x00030047,0x000005bf,0x00000000,0x00030047,0x000005c1,0x00000000,0x00030047, + 0x000005c2,0x00000000,0x00030047,0x000005cb,0x00000000,0x00030047,0x000005cc,0x00000000, + 0x00030047,0x000005cd,0x00000000,0x00030047,0x000005cf,0x00000000,0x00040047,0x000005d0, + 0x0000000b,0x0000000f,0x00030047,0x000005d2,0x00000002,0x00050048,0x000005d2,0x00000000, + 0x00000023,0x00000000,0x00050048,0x000005d2,0x00000001,0x00000023,0x00000004,0x00050048, + 0x000005d2,0x00000002,0x00000023,0x00000008,0x00050048,0x000005d2,0x00000003,0x00000023, + 0x0000000c,0x00050048,0x000005d2,0x00000004,0x00000023,0x00000010,0x00050048,0x000005d2, + 0x00000005,0x00000023,0x00000014,0x00050048,0x000005d2,0x00000006,0x00000023,0x00000018, + 0x00050048,0x000005d2,0x00000007,0x00000023,0x0000001c,0x00050048,0x000005d2,0x00000008, + 0x00000023,0x00000020,0x00050048,0x000005d2,0x00000009,0x00000023,0x00000030,0x00050048, + 0x000005d2,0x0000000a,0x00000023,0x00000038,0x00050048,0x000005d2,0x0000000b,0x00000023, + 0x00000040,0x00050048,0x000005d2,0x0000000c,0x00000023,0x00000044,0x00050048,0x000005d2, + 0x0000000d,0x00000023,0x00000048,0x00050048,0x000005d2,0x0000000e,0x00000023,0x0000004c, + 0x00050048,0x000005d2,0x0000000f,0x00000023,0x00000050,0x00050048,0x000005d2,0x00000010, + 0x00000023,0x00000054,0x00050048,0x000005d2,0x00000011,0x00000023,0x00000058,0x00050048, + 0x000005d2,0x00000012,0x00000023,0x0000005c,0x00050048,0x000005d2,0x00000013,0x00000023, + 0x00000060,0x00050048,0x000005d2,0x00000014,0x00000023,0x00000064,0x00040047,0x000005d4, + 0x00000021,0x00000000,0x00040047,0x000005d4,0x00000022,0x00000000,0x00030047,0x000005d9, + 0x00000000,0x00030047,0x0000061d,0x00000000,0x00030047,0x00000623,0x00000000,0x00030047, + 0x00000654,0x00000000,0x00030047,0x00000655,0x00000000,0x00030047,0x00000660,0x00000000, + 0x00030047,0x00000661,0x00000000,0x00030047,0x000006a6,0x00000000,0x00030047,0x000006a7, + 0x00000000,0x00030047,0x000006aa,0x00000000,0x00030047,0x000006ab,0x00000000,0x00030047, + 0x000006ac,0x00000000,0x00030047,0x000006b1,0x00000000,0x00030047,0x000006be,0x00000000, + 0x00030047,0x000006bf,0x00000000,0x00030047,0x000006c3,0x00000000,0x00030047,0x000006c4, + 0x00000000,0x00030047,0x000006c5,0x00000000,0x00030047,0x000006c8,0x00000000,0x00030047, + 0x000006c9,0x00000000,0x00030047,0x000006cc,0x00000000,0x00030047,0x000006ce,0x00000000, + 0x00030047,0x000006cf,0x00000000,0x00030047,0x000006d0,0x00000000,0x00030047,0x000006d1, + 0x00000000,0x00030047,0x000006d2,0x00000000,0x00030047,0x000006d5,0x00000000,0x00030047, + 0x000006d6,0x00000000,0x00030047,0x000006d8,0x00000000,0x00030047,0x000006d9,0x00000000, + 0x00030047,0x000006dc,0x00000000,0x00030047,0x000006dd,0x00000000,0x00030047,0x000006df, + 0x00000000,0x00030047,0x000006e0,0x00000000,0x00030047,0x000006e3,0x00000000,0x00030047, + 0x000006e4,0x00000000,0x00030047,0x000006e6,0x00000000,0x00030047,0x000006e7,0x00000000, + 0x00030047,0x000006ea,0x00000000,0x00030047,0x000006eb,0x00000000,0x00030047,0x000006f3, + 0x00000000,0x00030047,0x000006f5,0x00000000,0x00030047,0x000006f7,0x00000000,0x00030047, + 0x000006f9,0x00000000,0x00030047,0x000006fa,0x00000000,0x00030047,0x000006fd,0x00000000, + 0x00030047,0x000006ff,0x00000000,0x00030047,0x00000701,0x00000000,0x00030047,0x00000748, + 0x00000000,0x00030047,0x00000772,0x00000000,0x00030047,0x00000774,0x00000000,0x00030047, + 0x00000775,0x00000000,0x00030047,0x00000777,0x00000000,0x00030047,0x00000779,0x00000000, + 0x00030047,0x0000077a,0x00000000,0x00030047,0x0000079b,0x00000000,0x00030047,0x000007c5, + 0x00000000,0x00030047,0x000007c6,0x00000000,0x00030047,0x000007cb,0x00000000,0x00030047, + 0x000007ce,0x00000000,0x00030047,0x000007d3,0x00000000,0x00030047,0x000007d5,0x00000000, + 0x00030047,0x000007d6,0x00000000,0x00030047,0x000007e3,0x00000000,0x00030047,0x000007e4, + 0x00000000,0x00030047,0x000007e9,0x00000000,0x00030047,0x000007f1,0x00000000,0x00030047, + 0x000007f8,0x00000000,0x00030047,0x00000807,0x00000000,0x00030047,0x00000809,0x00000000, + 0x00030047,0x0000080e,0x00000000,0x00030047,0x00000812,0x00000000,0x00030047,0x00000829, + 0x00000000,0x00030047,0x0000082b,0x00000000,0x00030047,0x0000083a,0x00000000,0x00030047, + 0x0000083b,0x00000000,0x00030047,0x0000083d,0x00000000,0x00030047,0x00000867,0x00000000, + 0x00030047,0x00000869,0x00000000,0x00030047,0x0000086b,0x00000000,0x00030047,0x0000086d, + 0x00000000,0x00030047,0x00000870,0x00000000,0x00030047,0x00000871,0x00000000,0x00030047, + 0x00000873,0x00000000,0x00030047,0x00000875,0x00000000,0x00030047,0x00000879,0x00000000, + 0x00030047,0x0000087b,0x00000000,0x00030047,0x0000087d,0x00000000,0x00030047,0x00000880, + 0x00000000,0x00030047,0x00000881,0x00000000,0x00030047,0x00000882,0x00000000,0x00030047, + 0x00000884,0x00000000,0x00030047,0x00000886,0x00000000,0x00030047,0x00000888,0x00000000, + 0x00030047,0x0000088a,0x00000000,0x00030047,0x00000890,0x00000000,0x00030047,0x00000891, + 0x00000000,0x00030047,0x00000898,0x00000000,0x00030047,0x0000089a,0x00000000,0x00030047, + 0x0000089d,0x00000000,0x00030047,0x0000089f,0x00000000,0x00030047,0x000008a0,0x00000000, + 0x00030047,0x000008a3,0x00000000,0x00030047,0x000008a5,0x00000000,0x00030047,0x000008a6, + 0x00000000,0x00030047,0x000008a9,0x00000000,0x00030047,0x000008ac,0x00000000,0x00030047, + 0x000008ad,0x00000000,0x00030047,0x000008af,0x00000000,0x00030047,0x000008b2,0x00000000, + 0x00030047,0x000008b7,0x00000000,0x00030047,0x000008b8,0x00000000,0x00030047,0x000008c0, + 0x00000000,0x00030047,0x000008c6,0x00000000,0x00030047,0x000008c8,0x00000000,0x00030047, + 0x000008c9,0x00000000,0x00030047,0x000008ca,0x00000000,0x00030047,0x000008cd,0x00000000, + 0x00030047,0x000008d0,0x00000000,0x00030047,0x000008d1,0x00000000,0x00030047,0x000008d2, + 0x00000000,0x00030047,0x000008d4,0x00000000,0x00030047,0x000008d7,0x00000000,0x00030047, + 0x000008d8,0x00000000,0x00030047,0x000008da,0x00000000,0x00030047,0x000008dc,0x00000000, + 0x00030047,0x000008de,0x00000000,0x00030047,0x000008e2,0x00000000,0x00030047,0x000008e4, + 0x00000000,0x00030047,0x000008e6,0x00000000,0x00030047,0x000008e9,0x00000000,0x00030047, + 0x000008ea,0x00000000,0x00030047,0x000008eb,0x00000000,0x00030047,0x000008f4,0x00000000, + 0x00030047,0x000008fa,0x00000000,0x00030047,0x000008fb,0x00000000,0x00030047,0x00000900, + 0x00000000,0x00030047,0x00000906,0x00000000,0x00030047,0x00000907,0x00000000,0x00030047, + 0x00000908,0x00000000,0x00030047,0x0000090b,0x00000000,0x00030047,0x0000090c,0x00000000, + 0x00030047,0x0000090d,0x00000000,0x00030047,0x00000913,0x00000000,0x00030047,0x00000914, + 0x00000000,0x00030047,0x00000915,0x00000000,0x00030047,0x0000091f,0x00000000,0x00030047, + 0x00000920,0x00000000,0x00030047,0x00000922,0x00000000,0x00030047,0x00000923,0x00000000, + 0x00030047,0x00000924,0x00000000,0x00030047,0x00000925,0x00000000,0x00030047,0x00000926, + 0x00000000,0x00030047,0x00000929,0x00000000,0x00030047,0x0000092a,0x00000000,0x00030047, + 0x0000092b,0x00000000,0x00030047,0x0000092d,0x00000000,0x00030047,0x0000092f,0x00000000, + 0x00030047,0x00000931,0x00000000,0x00030047,0x00000933,0x00000000,0x00030047,0x00000934, + 0x00000000,0x00030047,0x00000937,0x00000000,0x00030047,0x0000093a,0x00000000,0x00030047, + 0x00000942,0x00000000,0x00030047,0x00000945,0x00000000,0x00030047,0x0000094d,0x00000000, + 0x00030047,0x00000950,0x00000000,0x00030047,0x00000957,0x00000000,0x00030047,0x0000095a, + 0x00000000,0x00030047,0x00000960,0x00000000,0x00030047,0x00000965,0x00000000,0x00030047, + 0x00000967,0x00000000,0x00030047,0x0000096c,0x00000000,0x00030047,0x00000970,0x00000000, + 0x00030047,0x00000a0c,0x00000000,0x00030047,0x00000a10,0x00000000,0x00030047,0x00000a11, + 0x00000000,0x00030047,0x00000a21,0x00000000,0x00030047,0x00000a24,0x00000000,0x00030047, + 0x00000a25,0x00000000,0x00030047,0x00000a29,0x00000000,0x00030047,0x00000a2b,0x00000000, + 0x00030047,0x00000a2c,0x00000000,0x00030047,0x00000a35,0x00000000,0x00030047,0x00000a3c, + 0x00000000,0x00030047,0x00000a41,0x00000000,0x00030047,0x00000a44,0x00000000,0x00030047, + 0x00000a45,0x00000000,0x00030047,0x00000a49,0x00000000,0x00030047,0x00000a4b,0x00000000, + 0x00030047,0x00000a4c,0x00000000,0x00030047,0x00000a51,0x00000000,0x00030047,0x00000a54, + 0x00000000,0x00030047,0x00000a55,0x00000000,0x00030047,0x00000a59,0x00000000,0x00030047, + 0x00000a5b,0x00000000,0x00030047,0x00000a5c,0x00000000,0x00030047,0x00000a72,0x00000000, + 0x00030047,0x00000a73,0x00000000,0x00030047,0x00000a75,0x00000000,0x00030047,0x00000a7b, + 0x00000000,0x00030047,0x00000a7f,0x00000000,0x00030047,0x00000a80,0x00000000,0x00030047, + 0x00000a83,0x00000000,0x00030047,0x00000a85,0x00000000,0x00030047,0x00000a86,0x00000000, + 0x00030047,0x00000a87,0x00000000,0x00030047,0x00000a8a,0x00000000,0x00030047,0x00000a8c, + 0x00000000,0x00030047,0x00000a8d,0x00000000,0x00030047,0x00000a95,0x00000000,0x00030047, + 0x00000aa7,0x00000000,0x00030047,0x00000ac6,0x00000000,0x00030047,0x00000ac9,0x00000000, + 0x00030047,0x00000aca,0x00000000,0x00030047,0x00000ace,0x00000000,0x00030047,0x00000ad0, + 0x00000000,0x00030047,0x00000ad1,0x00000000,0x00030047,0x00000ada,0x00000000,0x00030047, + 0x00000ae1,0x00000000,0x00030047,0x00000b10,0x00000000,0x00030047,0x00000b14,0x00000000, + 0x00030047,0x00000b15,0x00000000,0x00030047,0x00000b25,0x00000000,0x00030047,0x00000b28, + 0x00000000,0x00030047,0x00000b29,0x00000000,0x00030047,0x00000b2d,0x00000000,0x00030047, + 0x00000b2f,0x00000000,0x00030047,0x00000b30,0x00000000,0x00030047,0x00000b39,0x00000000, + 0x00030047,0x00000b40,0x00000000,0x00030047,0x00000b45,0x00000000,0x00030047,0x00000b48, + 0x00000000,0x00030047,0x00000b49,0x00000000,0x00030047,0x00000b4d,0x00000000,0x00030047, + 0x00000b4f,0x00000000,0x00030047,0x00000b50,0x00000000,0x00030047,0x00000b55,0x00000000, + 0x00030047,0x00000b58,0x00000000,0x00030047,0x00000b59,0x00000000,0x00030047,0x00000b5d, + 0x00000000,0x00030047,0x00000b5f,0x00000000,0x00030047,0x00000b60,0x00000000,0x00030047, + 0x00000b76,0x00000000,0x00030047,0x00000b77,0x00000000,0x00030047,0x00000b79,0x00000000, + 0x00030047,0x00000b7f,0x00000000,0x00030047,0x00000b83,0x00000000,0x00030047,0x00000b84, + 0x00000000,0x00030047,0x00000b87,0x00000000,0x00030047,0x00000b89,0x00000000,0x00030047, + 0x00000b8a,0x00000000,0x00030047,0x00000b8b,0x00000000,0x00030047,0x00000b8e,0x00000000, + 0x00030047,0x00000b90,0x00000000,0x00030047,0x00000b91,0x00000000,0x00030047,0x00000b99, + 0x00000000,0x00030047,0x00000bab,0x00000000,0x00030047,0x00000bca,0x00000000,0x00030047, + 0x00000bcd,0x00000000,0x00030047,0x00000bce,0x00000000,0x00030047,0x00000bd2,0x00000000, + 0x00030047,0x00000bd4,0x00000000,0x00030047,0x00000bd5,0x00000000,0x00030047,0x00000bde, + 0x00000000,0x00030047,0x00000be5,0x00000000,0x00030047,0x00000c1a,0x00000000,0x00030047, + 0x00000c1b,0x00000000,0x00030047,0x00000c1d,0x00000000,0x00030047,0x00000c23,0x00000000, + 0x00030047,0x00000c27,0x00000000,0x00030047,0x00000c28,0x00000000,0x00030047,0x00000c2b, + 0x00000000,0x00030047,0x00000c2d,0x00000000,0x00030047,0x00000c2e,0x00000000,0x00030047, + 0x00000c2f,0x00000000,0x00030047,0x00000c32,0x00000000,0x00030047,0x00000c34,0x00000000, + 0x00030047,0x00000c35,0x00000000,0x00030047,0x00000c3d,0x00000000,0x00030047,0x00000c4f, + 0x00000000,0x00030047,0x00000c6e,0x00000000,0x00030047,0x00000c71,0x00000000,0x00030047, + 0x00000c72,0x00000000,0x00030047,0x00000c76,0x00000000,0x00030047,0x00000c78,0x00000000, + 0x00030047,0x00000c79,0x00000000,0x00030047,0x00000c82,0x00000000,0x00030047,0x00000c89, + 0x00000000,0x00030047,0x00000cbe,0x00000000,0x00030047,0x00000cbf,0x00000000,0x00030047, + 0x00000cc1,0x00000000,0x00030047,0x00000cc7,0x00000000,0x00030047,0x00000ccb,0x00000000, + 0x00030047,0x00000ccc,0x00000000,0x00030047,0x00000ccf,0x00000000,0x00030047,0x00000cd1, + 0x00000000,0x00030047,0x00000cd2,0x00000000,0x00030047,0x00000cd3,0x00000000,0x00030047, + 0x00000cd6,0x00000000,0x00030047,0x00000cd8,0x00000000,0x00030047,0x00000cd9,0x00000000, + 0x00030047,0x00000ce1,0x00000000,0x00030047,0x00000cf3,0x00000000,0x00030047,0x00000d12, + 0x00000000,0x00030047,0x00000d15,0x00000000,0x00030047,0x00000d16,0x00000000,0x00030047, + 0x00000d1a,0x00000000,0x00030047,0x00000d1c,0x00000000,0x00030047,0x00000d1d,0x00000000, + 0x00030047,0x00000d26,0x00000000,0x00030047,0x00000d2d,0x00000000,0x00030047,0x00000d4f, + 0x00000000,0x00030047,0x00000d50,0x00000000,0x00030047,0x00000d62,0x00000000,0x00030047, + 0x00000d63,0x00000000,0x00030047,0x00000d66,0x00000000,0x00030047,0x00000d68,0x00000000, + 0x00030047,0x00000d77,0x00000000,0x00030047,0x00000d79,0x00000000,0x00030047,0x00000d7b, + 0x00000000,0x00030047,0x00000d7d,0x00000000,0x00030047,0x00000d83,0x00000000,0x00030047, + 0x00000d85,0x00000000,0x00030047,0x00000d87,0x00000000,0x00030047,0x00000d89,0x00000000, + 0x00030047,0x00000d8d,0x00000000,0x00030047,0x00000d8f,0x00000000,0x00030047,0x00000d93, + 0x00000000,0x00030047,0x00000d95,0x00000000,0x00030047,0x00000d97,0x00000000,0x00030047, + 0x00000d99,0x00000000,0x00030047,0x00000d9b,0x00000000,0x00030047,0x00000d9d,0x00000000, + 0x00030047,0x00000da5,0x00000000,0x00030047,0x00000dad,0x00000000,0x00030047,0x00000db0, + 0x00000000,0x00030047,0x00000db2,0x00000000,0x00030047,0x00000db4,0x00000000,0x00030047, + 0x00000dbb,0x00000000,0x00030047,0x00000dbd,0x00000000,0x00030047,0x00000dbf,0x00000000, + 0x00030047,0x00000dc1,0x00000000,0x00030047,0x00000dc5,0x00000000,0x00030047,0x00000dc7, + 0x00000000,0x00030047,0x00000dc9,0x00000000,0x00030047,0x00000dcb,0x00000000,0x00030047, + 0x00000dcd,0x00000000,0x00030047,0x00000dcf,0x00000000,0x00030047,0x00000dd1,0x00000000, + 0x00030047,0x00000dd3,0x00000000,0x00030047,0x00000dd5,0x00000000,0x00030047,0x00000ddd, + 0x00000000,0x00030047,0x00000ddf,0x00000000,0x00030047,0x00000de1,0x00000000,0x00030047, + 0x00000df0,0x00000000,0x00030047,0x00000df2,0x00000000,0x00030047,0x00000df4,0x00000000, + 0x00030047,0x00000df6,0x00000000,0x00030047,0x00000df8,0x00000000,0x00030047,0x00000dfa, + 0x00000000,0x00030047,0x00000e02,0x00000000,0x00030047,0x00000e04,0x00000000,0x00030047, + 0x00000e06,0x00000000,0x00030047,0x00000e09,0x00000000,0x00030047,0x00000e19,0x00000000, + 0x00030047,0x00000e1b,0x00000000,0x00030047,0x00000e1d,0x00000000,0x00030047,0x00000e1f, + 0x00000000,0x00030047,0x00000e21,0x00000000,0x00030047,0x00000e23,0x00000000,0x00030047, + 0x00000e25,0x00000000,0x00030047,0x00000e27,0x00000000,0x00030047,0x00000e29,0x00000000, + 0x00030047,0x00000e37,0x00000000,0x00030047,0x00000e39,0x00000000,0x00030047,0x00000e3b, + 0x00000000,0x00030047,0x00000e43,0x00000000,0x00030047,0x00000e45,0x00000000,0x00030047, + 0x00000e47,0x00000000,0x00030047,0x00000e49,0x00000000,0x00030047,0x00000e51,0x00000000, + 0x00030047,0x00000e53,0x00000000,0x00030047,0x00000e57,0x00000000,0x00030047,0x00000e59, + 0x00000000,0x00030047,0x00000e5b,0x00000000,0x00030047,0x00000e5d,0x00000000,0x00030047, + 0x00000e5f,0x00000000,0x00030047,0x00000e61,0x00000000,0x00030047,0x00000e6f,0x00000000, + 0x00030047,0x00000e71,0x00000000,0x00030047,0x00000e73,0x00000000,0x00030047,0x00000e7b, + 0x00000000,0x00030047,0x00000e7d,0x00000000,0x00030047,0x00000e7f,0x00000000,0x00030047, + 0x00000e81,0x00000000,0x00030047,0x00000e89,0x00000000,0x00030047,0x00000e8b,0x00000000, + 0x00030047,0x00000e8f,0x00000000,0x00030047,0x00000e91,0x00000000,0x00030047,0x00000e93, + 0x00000000,0x00030047,0x00000e95,0x00000000,0x00030047,0x00000e97,0x00000000,0x00030047, + 0x00000e99,0x00000000,0x00030047,0x00000e9b,0x00000000,0x00030047,0x00000e9d,0x00000000, + 0x00030047,0x00000e9f,0x00000000,0x00030047,0x00000ea7,0x00000000,0x00030047,0x00000ea9, + 0x00000000,0x00030047,0x00000eab,0x00000000,0x00030047,0x00000ead,0x00000000,0x00030047, + 0x00000eb5,0x00000000,0x00030047,0x00000eb7,0x00000000,0x00030047,0x00000ebb,0x00000000, + 0x00030047,0x00000ebd,0x00000000,0x00030047,0x00000ebf,0x00000000,0x00030047,0x00000ec1, + 0x00000000,0x00030047,0x00000ec3,0x00000000,0x00030047,0x00000ec5,0x00000000,0x00030047, + 0x00000ec7,0x00000000,0x00030047,0x00000ec9,0x00000000,0x00030047,0x00000ecb,0x00000000, + 0x00030047,0x00000ed3,0x00000000,0x00030047,0x00000ed5,0x00000000,0x00030047,0x00000ed7, + 0x00000000,0x00030047,0x00000ed9,0x00000000,0x00030047,0x00000ee1,0x00000000,0x00030047, + 0x00000ee3,0x00000000,0x00030047,0x00000ee8,0x00000000,0x00030047,0x00000eea,0x00000000, + 0x00030047,0x00000eec,0x00000000,0x00030047,0x00000eee,0x00000000,0x00030047,0x00000ef0, + 0x00000000,0x00030047,0x00000ef2,0x00000000,0x00030047,0x00000ef5,0x00000000,0x00030047, + 0x00000ef7,0x00000000,0x00030047,0x00000ef9,0x00000000,0x00030047,0x00000efe,0x00000000, + 0x00030047,0x00000f00,0x00000000,0x00030047,0x00000f02,0x00000000,0x00030047,0x00000f03, + 0x00000000,0x00030047,0x00000f04,0x00000000,0x00030047,0x00000f0c,0x00000000,0x00030047, + 0x00000f1a,0x00000000,0x00030047,0x00000f1d,0x00000000,0x00030047,0x00000f1e,0x00000000, + 0x00030047,0x00000f20,0x00000000,0x00030047,0x00000f1f,0x00000000,0x00030047,0x00000f21, + 0x00000000,0x00030047,0x00000f22,0x00000000,0x00030047,0x00000f39,0x00000000,0x00030047, + 0x00000f3b,0x00000000,0x00030047,0x00000f3c,0x00000000,0x00030047,0x00000f3a,0x00000000, + 0x00030047,0x00000f38,0x00000000,0x00030047,0x00000f3e,0x00000000,0x00030047,0x00000f3f, + 0x00000000,0x00030047,0x000012a5,0x00000000,0x00030047,0x000013ae,0x00000000,0x00030047, + 0x000013bb,0x00000000,0x00030047,0x000013bc,0x00000000,0x00030047,0x000013be,0x00000000, + 0x00030047,0x000013cf,0x00000000,0x00030047,0x000013d1,0x00000000,0x00030047,0x000013d0, + 0x00000000,0x00030047,0x00000f0d,0x00000000,0x00030047,0x00000f0e,0x00000000,0x00030047, + 0x00000f0f,0x00000000,0x00030047,0x00000f1b,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00030016,0x00000008, + 0x00000020,0x00040017,0x0000000d,0x00000008,0x00000004,0x00040020,0x00000013,0x00000007, + 0x00000008,0x00040017,0x0000001c,0x00000008,0x00000002,0x00040017,0x00000026,0x00000008, + 0x00000003,0x00040020,0x00000038,0x00000007,0x00000026,0x00020014,0x00000068,0x0004002b, + 0x00000006,0x000000b6,0x00000000,0x0004002b,0x00000006,0x000000b9,0x00000001,0x0004002b, + 0x00000008,0x000000f9,0x00000000,0x0004002b,0x00000008,0x000000fe,0x3f800000,0x00040032, + 0x00000006,0x00000136,0x00000000,0x0004002b,0x00000006,0x00000137,0x000013b5,0x00060034, + 0x00000068,0x00000138,0x000000aa,0x00000136,0x00000137,0x0004002b,0x00000008,0x00000154, + 0x3d897143,0x0004002b,0x00000008,0x00000158,0x3bbf4590,0x0004002b,0x00000008,0x0000015f, + 0x4253ee82,0x00030030,0x00000068,0x0000016a,0x0004002b,0x00000008,0x00000184,0xbfc00000, + 0x00090019,0x0000019a,0x00000008,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x0000019b,0x00000000,0x0000019a,0x0004003b,0x0000019b,0x0000019c, + 0x00000000,0x0002001a,0x0000019e,0x00040020,0x0000019f,0x00000000,0x0000019e,0x0004003b, + 0x0000019f,0x000001a0,0x00000000,0x0003001b,0x000001a2,0x0000019a,0x0004002b,0x00000008, + 0x000001ac,0x447a0000,0x0004002b,0x00000008,0x000001b4,0x3e800000,0x0004002b,0x00000008, + 0x000001ba,0xc0000000,0x0004002b,0x00000008,0x000001c0,0x3f19319f,0x0004002b,0x00000008, + 0x000001c5,0x3e55e621,0x0004002b,0x00000008,0x000001c6,0x3f206c99,0x0004002b,0x00000008, + 0x000001c7,0x3f85afd5,0x0004002b,0x00000008,0x000001c8,0x3fbb295d,0x0004002b,0x00000008, + 0x00000205,0x40a311dd,0x0004002b,0x00000008,0x00000207,0xc02311dd,0x0004002b,0x00000008, + 0x00000222,0x40400000,0x0004002b,0x00000008,0x00000242,0x3e99999a,0x0004002b,0x00000008, + 0x00000243,0x3f170a3d,0x0004002b,0x00000008,0x00000244,0x3de147ae,0x0004002b,0x00000008, + 0x0000025e,0x388205ff,0x0004002b,0x00000008,0x000002c4,0x40000000,0x0004002b,0x00000008, + 0x000002cb,0x3f000000,0x00040017,0x000002d1,0x00000068,0x00000003,0x00040015,0x0000034d, + 0x00000020,0x00000001,0x0004002b,0x0000034d,0x00000350,0x00000000,0x0004002b,0x0000034d, + 0x00000357,0x00000003,0x0004002b,0x00000008,0x0000036d,0x41800000,0x0004002b,0x00000008, + 0x00000372,0x41400000,0x0004002b,0x0000034d,0x00000383,0x00000001,0x00030030,0x00000068, + 0x0000039e,0x00030030,0x00000068,0x000003f9,0x00050034,0x00000068,0x000003fa,0x000000a8, + 0x000003f9,0x0004002b,0x00000008,0x00000409,0xbf800000,0x0004002b,0x00000008,0x00000427, + 0x3f7f8000,0x0004002b,0x00000008,0x0000042a,0x3a800000,0x0004002b,0x00000008,0x0000042d, + 0x3b000000,0x0004003b,0x0000019b,0x00000437,0x00000000,0x0004003b,0x0000019f,0x00000439, + 0x00000000,0x00050034,0x00000068,0x00000445,0x000000a8,0x000003f9,0x0004003b,0x0000019b, + 0x00000459,0x00000000,0x0004003b,0x0000019f,0x0000045b,0x00000000,0x00050034,0x00000068, + 0x00000467,0x000000a8,0x000003f9,0x00030030,0x00000068,0x0000047b,0x00090019,0x000004bd, + 0x00000006,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020, + 0x000004be,0x00000000,0x000004bd,0x0004003b,0x000004be,0x000004bf,0x00000000,0x00040017, + 0x000004c1,0x0000034d,0x00000002,0x0005002c,0x000004c1,0x000004c2,0x00000350,0x00000350, + 0x00040017,0x000004c3,0x00000006,0x00000004,0x00040020,0x000004cc,0x00000001,0x00000008, + 0x0004003b,0x000004cc,0x000004cd,0x00000001,0x00040020,0x000004d9,0x00000001,0x0000000d, + 0x0004003b,0x000004d9,0x000004da,0x00000001,0x00040020,0x000004e0,0x00000003,0x000004c3, + 0x0004003b,0x000004e0,0x000004e1,0x00000003,0x00040020,0x000004e8,0x00000003,0x00000006, + 0x00030030,0x00000068,0x000004ea,0x00030030,0x00000068,0x000004fa,0x00030030,0x00000068, + 0x0000050f,0x00040020,0x00000512,0x00000001,0x0000001c,0x0004003b,0x00000512,0x00000513, + 0x00000001,0x00030030,0x00000068,0x0000051e,0x0004003b,0x000004be,0x00000529,0x00000000, + 0x00040020,0x00000541,0x00000003,0x0000000d,0x0004003b,0x00000541,0x00000542,0x00000003, + 0x00090019,0x0000054a,0x00000008,0x00000006,0x00000000,0x00000000,0x00000000,0x00000002, + 0x00000000,0x00040020,0x0000054b,0x00000000,0x0000054a,0x0004003b,0x0000054b,0x0000054c, + 0x00000000,0x0004003b,0x000004e0,0x00000555,0x00000003,0x0004003b,0x00000541,0x0000055d, + 0x00000003,0x0004003b,0x0000054b,0x0000055e,0x00000000,0x00030030,0x00000068,0x00000581, + 0x0004003b,0x000004d9,0x00000585,0x00000001,0x0004003b,0x000004d9,0x00000591,0x00000001, + 0x0004003b,0x000004cc,0x000005a7,0x00000001,0x0004003b,0x000004d9,0x000005d0,0x00000001, + 0x00040017,0x000005d1,0x0000034d,0x00000004,0x0017001e,0x000005d2,0x00000008,0x00000008, + 0x00000008,0x00000008,0x00000006,0x00000006,0x00000006,0x00000006,0x000005d1,0x0000001c, + 0x0000001c,0x00000006,0x00000008,0x00000006,0x00000008,0x00000008,0x00000006,0x00000008, + 0x00000008,0x00000008,0x00000006,0x00040020,0x000005d3,0x00000002,0x000005d2,0x0004003b, + 0x000005d3,0x000005d4,0x00000002,0x0004002b,0x0000034d,0x000005d5,0x00000011,0x0004002b, + 0x0000034d,0x000005d6,0x00000012,0x00040020,0x000005de,0x00000002,0x00000008,0x00030001, + 0x0000000d,0x00000f08,0x00030001,0x0000001c,0x00000f14,0x00030001,0x00000026,0x00000f4d, + 0x0007002c,0x0000000d,0x000013e4,0x00000207,0x00000207,0x00000207,0x00000207,0x0006002c, + 0x00000026,0x000013e5,0x000002cb,0x000002cb,0x000002cb,0x0006002c,0x00000026,0x000013e6, + 0x000000fe,0x000000fe,0x000000fe,0x00030001,0x0000001c,0x000013e8,0x00030001,0x00000026, + 0x000013e9,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003b,0x00000038,0x0000083b,0x00000007,0x0004003b,0x00000038,0x0000083d,0x00000007, + 0x0004003b,0x00000038,0x0000082b,0x00000007,0x0004003d,0x000004bd,0x000004c0,0x000004bf, + 0x00050062,0x000004c3,0x000004c4,0x000004c0,0x000004c2,0x00050051,0x00000006,0x000004c5, + 0x000004c4,0x00000000,0x0006000c,0x0000001c,0x000004c6,0x00000001,0x0000003e,0x000004c5, + 0x00050051,0x00000008,0x000004c9,0x000004c6,0x00000001,0x0004003d,0x00000008,0x000004ce, + 0x000004cd,0x000500b4,0x00000068,0x000004cf,0x000004c9,0x000004ce,0x000300f7,0x000004d2, + 0x00000000,0x000400fa,0x000004cf,0x000004d1,0x000004d5,0x000200f8,0x000004d5,0x000200f9, + 0x000004d2,0x000200f8,0x000004d1,0x00050051,0x00000008,0x000004d4,0x000004c6,0x00000000, + 0x000200f9,0x000004d2,0x000200f8,0x000004d2,0x000700f5,0x00000008,0x00000f03,0x000004d4, + 0x000004d1,0x000000f9,0x000004d5,0x0004003d,0x0000000d,0x000004de,0x000004da,0x000300f7, + 0x00000625,0x00000000,0x000300fb,0x000000b6,0x00000615,0x000200f8,0x00000615,0x00050051, + 0x00000008,0x0000062a,0x000004de,0x00000001,0x000500be,0x00000068,0x0000062b,0x0000062a, + 0x000000f9,0x000300f7,0x00000624,0x00000000,0x000400fa,0x0000062b,0x00000618,0x0000061e, + 0x000200f8,0x0000061e,0x000300f7,0x00000680,0x00000000,0x000300fb,0x000000b6,0x00000672, + 0x000200f8,0x00000672,0x000300f7,0x00000676,0x00000000,0x000400fa,0x0000047b,0x00000673, + 0x00000676,0x000200f8,0x00000673,0x000500b8,0x00000068,0x00000686,0x0000062a,0x00000184, + 0x000200f9,0x00000676,0x000200f8,0x00000676,0x000700f5,0x00000068,0x00000677,0x0000047b, + 0x00000672,0x00000686,0x00000673,0x000300f7,0x0000067f,0x00000000,0x000400fa,0x00000677, + 0x00000678,0x0000067b,0x000200f8,0x0000067b,0x00050051,0x00000008,0x0000067d,0x000004de, + 0x00000000,0x000200f9,0x00000680,0x000200f8,0x00000678,0x00050051,0x00000008,0x0000069f, + 0x000004de,0x00000002,0x00050051,0x00000008,0x000006a1,0x000004de,0x00000003,0x0007000c, + 0x00000008,0x000006a2,0x00000001,0x00000028,0x000006a1,0x000000f9,0x000500be,0x00000068, + 0x000006a4,0x0000069f,0x000000f9,0x000300f7,0x000006ae,0x00000000,0x000400fa,0x000006a4, + 0x000006a5,0x000006ad,0x000200f8,0x000006ad,0x000200f9,0x000006ae,0x000200f8,0x000006a5, + 0x0004003d,0x0000019a,0x000006a6,0x0000019c,0x0004003d,0x0000019e,0x000006a7,0x000001a0, + 0x00050056,0x000001a2,0x000006a8,0x000006a6,0x000006a7,0x00050050,0x0000001c,0x000006aa, + 0x000006a2,0x000000f9,0x00070058,0x0000000d,0x000006ab,0x000006a8,0x000006aa,0x00000002, + 0x000000f9,0x00050051,0x00000008,0x000006ac,0x000006ab,0x00000000,0x000200f9,0x000006ae, + 0x000200f8,0x000006ae,0x000700f5,0x00000008,0x00000f04,0x000006ac,0x000006a5,0x000000f9, + 0x000006ad,0x0006000c,0x00000008,0x000006b1,0x00000001,0x00000004,0x0000069f,0x000500b8, + 0x00000068,0x000006b2,0x000006b1,0x000001ac,0x000300f7,0x00000702,0x00000000,0x000400fa, + 0x000006b2,0x000006b3,0x00000702,0x000200f8,0x000006b3,0x00050051,0x00000008,0x000006b5, + 0x000004de,0x00000000,0x0006000c,0x00000008,0x000006b6,0x00000001,0x00000004,0x000006b5, + 0x00050083,0x00000008,0x000006b7,0x000006b6,0x000001b4,0x0004007f,0x00000008,0x000006ba, + 0x0000062a,0x00050081,0x00000008,0x000006bb,0x000006ba,0x000001ba,0x00050083,0x00000008, + 0x000006be,0x000006bb,0x000006a2,0x00050085,0x00000008,0x000006bf,0x000006be,0x000001c0, + 0x00060052,0x0000000d,0x00000d77,0x000001c5,0x00000f08,0x00000000,0x00060052,0x0000000d, + 0x00000d79,0x000001c6,0x00000d77,0x00000001,0x00060052,0x0000000d,0x00000d7b,0x000001c7, + 0x00000d79,0x00000002,0x00060052,0x0000000d,0x00000d7d,0x000001c8,0x00000d7b,0x00000003, + 0x0005008e,0x0000000d,0x000006c3,0x00000d7d,0x000006bf,0x00070050,0x0000000d,0x000006c4, + 0x000006a2,0x000006a2,0x000006a2,0x000006a2,0x00050081,0x0000000d,0x000006c5,0x000006c4, + 0x000006c3,0x0004007f,0x00000008,0x000006c8,0x0000069f,0x0005008e,0x0000000d,0x000006c9, + 0x000006c5,0x000006c8,0x00050085,0x00000008,0x000006cc,0x000006bb,0x0000069f,0x00050081, + 0x00000008,0x000006ce,0x000006cc,0x000006b7,0x00070050,0x0000000d,0x000006cf,0x000006ce, + 0x000006ce,0x000006ce,0x000006ce,0x00050081,0x0000000d,0x000006d0,0x000006c9,0x000006cf, + 0x0004003d,0x0000019a,0x000006d1,0x0000019c,0x0004003d,0x0000019e,0x000006d2,0x000001a0, + 0x00050056,0x000001a2,0x000006d3,0x000006d1,0x000006d2,0x00050051,0x00000008,0x000006d5, + 0x000006d0,0x00000000,0x00050050,0x0000001c,0x000006d6,0x000006d5,0x000000f9,0x00070058, + 0x0000000d,0x000006d7,0x000006d3,0x000006d6,0x00000002,0x000000f9,0x0004003d,0x0000019a, + 0x000006d8,0x0000019c,0x0004003d,0x0000019e,0x000006d9,0x000001a0,0x00050056,0x000001a2, + 0x000006da,0x000006d8,0x000006d9,0x00050051,0x00000008,0x000006dc,0x000006d0,0x00000001, + 0x00050050,0x0000001c,0x000006dd,0x000006dc,0x000000f9,0x00070058,0x0000000d,0x000006de, + 0x000006da,0x000006dd,0x00000002,0x000000f9,0x0004003d,0x0000019a,0x000006df,0x0000019c, + 0x0004003d,0x0000019e,0x000006e0,0x000001a0,0x00050056,0x000001a2,0x000006e1,0x000006df, + 0x000006e0,0x00050051,0x00000008,0x000006e3,0x000006d0,0x00000002,0x00050050,0x0000001c, + 0x000006e4,0x000006e3,0x000000f9,0x00070058,0x0000000d,0x000006e5,0x000006e1,0x000006e4, + 0x00000002,0x000000f9,0x0004003d,0x0000019a,0x000006e6,0x0000019c,0x0004003d,0x0000019e, + 0x000006e7,0x000001a0,0x00050056,0x000001a2,0x000006e8,0x000006e6,0x000006e7,0x00050051, + 0x00000008,0x000006ea,0x000006d0,0x00000003,0x00050050,0x0000001c,0x000006eb,0x000006ea, + 0x000000f9,0x00070058,0x0000000d,0x000006ec,0x000006e8,0x000006eb,0x00000002,0x000000f9, + 0x00050051,0x00000008,0x000006ed,0x000006d7,0x00000000,0x00050051,0x00000008,0x000006ee, + 0x000006de,0x00000000,0x00050051,0x00000008,0x000006ef,0x000006e5,0x00000000,0x00050051, + 0x00000008,0x000006f0,0x000006ec,0x00000000,0x00060052,0x0000000d,0x00000d83,0x000006ed, + 0x00000f08,0x00000000,0x00060052,0x0000000d,0x00000d85,0x000006ee,0x00000d83,0x00000001, + 0x00060052,0x0000000d,0x00000d87,0x000006ef,0x00000d85,0x00000002,0x00060052,0x0000000d, + 0x00000d89,0x000006f0,0x00000d87,0x00000003,0x0005008e,0x0000000d,0x000006f3,0x000006c5, + 0x00000205,0x00050081,0x0000000d,0x000006f5,0x000006f3,0x000013e4,0x0004007f,0x0000000d, + 0x000006f7,0x000006f5,0x00050085,0x0000000d,0x000006f9,0x000006f7,0x000006f5,0x0006000c, + 0x0000000d,0x000006fa,0x00000001,0x0000001d,0x000006f9,0x00050094,0x00000008,0x000006fd, + 0x00000d89,0x000006fa,0x00050085,0x00000008,0x000006ff,0x000006fd,0x000006bf,0x00050081, + 0x00000008,0x00000701,0x00000f04,0x000006ff,0x000200f9,0x00000702,0x000200f8,0x00000702, + 0x000700f5,0x00000008,0x00000f0c,0x00000f04,0x000006ae,0x00000701,0x000006b3,0x00050051, + 0x00000008,0x00000705,0x000004de,0x00000000,0x0006000c,0x00000008,0x00000706,0x00000001, + 0x00000006,0x00000705,0x00050085,0x00000008,0x00000707,0x00000f0c,0x00000706,0x000200f9, + 0x00000680,0x000200f8,0x0000067f,0x000100ff,0x000200f8,0x00000680,0x000700f5,0x00000008, + 0x00000f0d,0x00000707,0x00000702,0x0000067d,0x0000067b,0x00050081,0x00000008,0x00000623, + 0x00000f03,0x00000f0d,0x000200f9,0x00000625,0x000200f8,0x00000618,0x000300f7,0x00000644, + 0x00000000,0x000300fb,0x000000b6,0x00000633,0x000200f8,0x00000633,0x000300f7,0x00000637, + 0x00000000,0x000400fa,0x0000047b,0x00000634,0x00000637,0x000200f8,0x00000634,0x00050051, + 0x00000008,0x00000649,0x000004de,0x00000000,0x000500b8,0x00000068,0x0000064a,0x00000649, + 0x00000184,0x000200f9,0x00000637,0x000200f8,0x00000637,0x000700f5,0x00000068,0x00000638, + 0x0000047b,0x00000633,0x0000064a,0x00000634,0x000300f7,0x00000643,0x00000000,0x000400fa, + 0x00000638,0x00000639,0x0000063c,0x000200f8,0x0000063c,0x00050051,0x00000008,0x0000063e, + 0x000004de,0x00000000,0x0007000c,0x00000008,0x00000641,0x00000001,0x00000025,0x0000063e, + 0x0000062a,0x000200f9,0x00000644,0x000200f8,0x00000639,0x00050051,0x00000008,0x00000652, + 0x000004de,0x00000000,0x00050081,0x00000008,0x00000653,0x00000222,0x00000652,0x0004003d, + 0x0000019a,0x00000654,0x0000019c,0x0004003d,0x0000019e,0x00000655,0x000001a0,0x00050056, + 0x000001a2,0x00000656,0x00000654,0x00000655,0x00050050,0x0000001c,0x00000658,0x00000653, + 0x000000f9,0x00070058,0x0000000d,0x00000659,0x00000656,0x00000658,0x00000002,0x000000f9, + 0x00050051,0x00000008,0x0000065a,0x00000659,0x00000000,0x00050083,0x00000008,0x0000065c, + 0x000000fe,0x0000065a,0x00050083,0x00000008,0x0000065f,0x000000fe,0x0000062a,0x0004003d, + 0x0000019a,0x00000660,0x0000019c,0x0004003d,0x0000019e,0x00000661,0x000001a0,0x00050056, + 0x000001a2,0x00000662,0x00000660,0x00000661,0x00050050,0x0000001c,0x00000664,0x0000065f, + 0x000000f9,0x00070058,0x0000000d,0x00000665,0x00000662,0x00000664,0x00000002,0x000000f9, + 0x00050051,0x00000008,0x00000666,0x00000665,0x00000000,0x00050083,0x00000008,0x00000668, + 0x0000065c,0x00000666,0x000200f9,0x00000644,0x000200f8,0x00000643,0x000100ff,0x000200f8, + 0x00000644,0x000700f5,0x00000008,0x00000f0e,0x00000668,0x00000639,0x00000641,0x0000063c, + 0x0007000c,0x00000008,0x0000061d,0x00000001,0x00000028,0x00000f0e,0x00000f03,0x000200f9, + 0x00000625,0x000200f8,0x00000624,0x000100ff,0x000200f8,0x00000625,0x000700f5,0x00000008, + 0x00000f0f,0x0000061d,0x00000644,0x00000623,0x00000680,0x00060052,0x0000001c,0x00000d8d, + 0x00000f0f,0x00000f14,0x00000000,0x00060052,0x0000001c,0x00000d8f,0x000004ce,0x00000d8d, + 0x00000001,0x0006000c,0x00000006,0x000004e7,0x00000001,0x0000003a,0x00000d8f,0x00050041, + 0x000004e8,0x000004e9,0x000004e1,0x000000b6,0x0003003e,0x000004e9,0x000004e7,0x000300f7, + 0x000004ec,0x00000000,0x000400fa,0x000004ea,0x000004eb,0x000004f7,0x000200f8,0x000004f7, + 0x0006000c,0x00000008,0x000004f9,0x00000001,0x00000004,0x00000f0f,0x000300f7,0x000004fc, + 0x00000000,0x000400fa,0x000004fa,0x000004fb,0x000004fc,0x000200f8,0x000004fb,0x000500b8, + 0x00000068,0x000004fe,0x000004ce,0x000000f9,0x000200f9,0x000004fc,0x000200f8,0x000004fc, + 0x000700f5,0x00000068,0x000004ff,0x000004fa,0x000004f7,0x000004fe,0x000004fb,0x000300f7, + 0x00000501,0x00000000,0x000400fa,0x000004ff,0x00000500,0x00000501,0x000200f8,0x00000500, + 0x00050085,0x00000008,0x00000503,0x000004f9,0x000002cb,0x0006000c,0x00000008,0x00000504, + 0x00000001,0x0000000a,0x00000503,0x00050085,0x00000008,0x00000505,0x00000504,0x000002c4, + 0x00050081,0x00000008,0x00000506,0x00000505,0x00000409,0x0006000c,0x00000008,0x00000507, + 0x00000001,0x00000004,0x00000506,0x00050083,0x00000008,0x0000050a,0x000000fe,0x00000507, + 0x000200f9,0x00000501,0x000200f8,0x00000501,0x000700f5,0x00000008,0x00000f1a,0x000004f9, + 0x000004fc,0x0000050a,0x00000500,0x0007000c,0x00000008,0x0000050e,0x00000001,0x00000025, + 0x00000f1a,0x000000fe,0x000200f9,0x000004ec,0x000200f8,0x000004eb,0x000300f7,0x00000749, + 0x00000000,0x000300fb,0x000000b6,0x00000733,0x000200f8,0x00000733,0x000300f7,0x00000744, + 0x00000000,0x000400fa,0x00000138,0x00000734,0x00000744,0x000200f8,0x00000734,0x000500b8, + 0x00000068,0x00000737,0x00000f0f,0x000000fe,0x000300f7,0x00000743,0x00000000,0x000400fa, + 0x00000737,0x00000738,0x00000741,0x000200f8,0x00000741,0x000200f9,0x00000749,0x000200f8, + 0x00000738,0x000500ba,0x00000068,0x0000073b,0x00000f0f,0x000000f9,0x000300f7,0x00000740, + 0x00000000,0x000400fa,0x0000073b,0x0000073c,0x0000073e,0x000200f8,0x0000073e,0x000200f9, + 0x00000749,0x000200f8,0x0000073c,0x000200f9,0x00000749,0x000200f8,0x00000740,0x000100ff, + 0x000200f8,0x00000743,0x000100ff,0x000200f8,0x00000744,0x0008000c,0x00000008,0x00000748, + 0x00000001,0x0000002b,0x00000f0f,0x000000f9,0x000000fe,0x000200f9,0x00000749,0x000200f8, + 0x00000749,0x000b00f5,0x00000008,0x00000f1b,0x00000f0f,0x0000073c,0x000000f9,0x0000073e, + 0x000000fe,0x00000741,0x00000748,0x00000744,0x000200f9,0x000004ec,0x000200f8,0x000004ec, + 0x000700f5,0x00000008,0x00000f1d,0x00000f1b,0x00000749,0x0000050e,0x00000501,0x000300f7, + 0x00000511,0x00000000,0x000400fa,0x0000050f,0x00000510,0x00000511,0x000200f8,0x00000510, + 0x00050041,0x000004cc,0x00000514,0x00000513,0x000000b6,0x0004003d,0x00000008,0x00000515, + 0x00000514,0x000500b8,0x00000068,0x00000516,0x00000515,0x000000f9,0x000200f9,0x00000511, + 0x000200f8,0x00000511,0x000700f5,0x00000068,0x00000517,0x0000050f,0x000004ec,0x00000516, + 0x00000510,0x000300f7,0x00000519,0x00000000,0x000400fa,0x00000517,0x00000518,0x00000561, + 0x000200f8,0x00000561,0x000300f7,0x00000563,0x00000000,0x000400fa,0x0000050f,0x00000562, + 0x00000563,0x000200f8,0x00000562,0x00050041,0x000004cc,0x00000565,0x00000513,0x000000b6, + 0x0004003d,0x00000008,0x00000566,0x00000565,0x000500b7,0x00000068,0x00000568,0x00000566, + 0x000000f9,0x000300f7,0x0000056a,0x00000000,0x000400fa,0x00000568,0x00000569,0x0000056a, + 0x000200f8,0x00000569,0x0004003d,0x000004bd,0x0000056c,0x00000529,0x00050062,0x000004c3, + 0x0000056d,0x0000056c,0x000004c2,0x00050051,0x00000006,0x0000056e,0x0000056d,0x00000000, + 0x0006000c,0x0000001c,0x0000056f,0x00000001,0x0000003e,0x0000056e,0x00050051,0x00000008, + 0x00000572,0x0000056f,0x00000001,0x000500b4,0x00000068,0x00000575,0x00000572,0x00000566, + 0x000300f7,0x00000578,0x00000000,0x000400fa,0x00000575,0x00000577,0x0000057d,0x000200f8, + 0x0000057d,0x000200f9,0x00000578,0x000200f8,0x00000577,0x00050051,0x00000008,0x0000057a, + 0x0000056f,0x00000000,0x0007000c,0x00000008,0x0000057c,0x00000001,0x00000025,0x0000057a, + 0x00000f1d,0x000200f9,0x00000578,0x000200f8,0x00000578,0x000700f5,0x00000008,0x00000f1e, + 0x0000057c,0x00000577,0x000000f9,0x0000057d,0x000200f9,0x0000056a,0x000200f8,0x0000056a, + 0x000700f5,0x00000008,0x00000f20,0x00000f1d,0x00000562,0x00000f1e,0x00000578,0x000200f9, + 0x00000563,0x000200f8,0x00000563,0x000700f5,0x00000008,0x00000f1f,0x00000f1d,0x00000561, + 0x00000f20,0x0000056a,0x000300f7,0x00000583,0x00000000,0x000400fa,0x00000581,0x00000582, + 0x00000583,0x000200f8,0x00000582,0x0004003d,0x0000000d,0x00000587,0x00000585,0x0007004f, + 0x0000001c,0x00000772,0x00000587,0x00000587,0x00000000,0x00000001,0x0007004f,0x0000001c, + 0x00000774,0x00000587,0x00000587,0x00000002,0x00000003,0x0007000c,0x0000001c,0x00000775, + 0x00000001,0x00000025,0x00000772,0x00000774,0x00050051,0x00000008,0x00000777,0x00000775, + 0x00000000,0x00050051,0x00000008,0x00000779,0x00000775,0x00000001,0x0007000c,0x00000008, + 0x0000077a,0x00000001,0x00000025,0x00000777,0x00000779,0x0008000c,0x00000008,0x0000058f, + 0x00000001,0x0000002b,0x0000077a,0x000000f9,0x00000f1f,0x000200f9,0x00000583,0x000200f8, + 0x00000583,0x000700f5,0x00000008,0x00000f21,0x00000f1f,0x00000563,0x0000058f,0x00000582, + 0x0004003d,0x0000000d,0x00000593,0x00000591,0x00050051,0x00000008,0x0000078f,0x00000593, + 0x00000003,0x000500be,0x00000068,0x00000790,0x0000078f,0x000000f9,0x000300f7,0x000007fc, + 0x00000000,0x000400fa,0x00000790,0x00000791,0x0000079f,0x000200f8,0x0000079f,0x000500ba, + 0x00000068,0x000007a2,0x0000078f,0x00000409,0x000300f7,0x000007fb,0x00000000,0x000400fa, + 0x000007a2,0x000007a3,0x000007de,0x000200f8,0x000007de,0x0004007f,0x00000008,0x000007e1, + 0x0000078f,0x00050083,0x00000008,0x000007e2,0x000007e1,0x000002c4,0x0004003d,0x0000019a, + 0x000007e3,0x00000459,0x0004003d,0x0000019e,0x000007e4,0x0000045b,0x00050056,0x000001a2, + 0x000007e5,0x000007e3,0x000007e4,0x0007004f,0x0000001c,0x000007e7,0x00000593,0x00000593, + 0x00000000,0x00000001,0x00070058,0x0000000d,0x000007e9,0x000007e5,0x000007e7,0x00000002, + 0x000007e2,0x00050051,0x00000008,0x000007eb,0x00000593,0x00000002,0x00050085,0x00000008, + 0x000007ed,0x000007eb,0x00000f21,0x000300f7,0x000007fa,0x00000000,0x000400fa,0x00000467, + 0x000007ee,0x000007f2,0x000200f8,0x000007f2,0x0008004f,0x00000026,0x00000807,0x000007e9, + 0x000007e9,0x00000000,0x00000001,0x00000002,0x00050051,0x00000008,0x00000809,0x000007e9, + 0x00000003,0x000500b7,0x00000068,0x0000080a,0x00000809,0x000000f9,0x000300f7,0x00000810, + 0x00000000,0x000400fa,0x0000080a,0x0000080b,0x0000080f,0x000200f8,0x0000080f,0x000200f9, + 0x00000810,0x000200f8,0x0000080b,0x00050088,0x00000008,0x0000080e,0x000000fe,0x00000809, + 0x000200f9,0x00000810,0x000200f8,0x00000810,0x000700f5,0x00000008,0x00000f22,0x0000080e, + 0x0000080b,0x000000f9,0x0000080f,0x0005008e,0x00000026,0x00000812,0x00000807,0x00000f22, + 0x00050085,0x00000008,0x000007f8,0x00000809,0x000007ed,0x00050051,0x00000008,0x00000818, + 0x00000812,0x00000000,0x00060052,0x0000000d,0x00000dbb,0x00000818,0x00000f08,0x00000000, + 0x00050051,0x00000008,0x0000081a,0x00000812,0x00000001,0x00060052,0x0000000d,0x00000dbd, + 0x0000081a,0x00000dbb,0x00000001,0x00050051,0x00000008,0x0000081c,0x00000812,0x00000002, + 0x00060052,0x0000000d,0x00000dbf,0x0000081c,0x00000dbd,0x00000002,0x00060052,0x0000000d, + 0x00000dc1,0x000007f8,0x00000dbf,0x00000003,0x000200f9,0x000007fa,0x000200f8,0x000007ee, + 0x0005008e,0x0000000d,0x000007f1,0x000007e9,0x000007ed,0x000200f9,0x000007fa,0x000200f8, + 0x000007fa,0x000700f5,0x0000000d,0x00000f3c,0x000007f1,0x000007ee,0x00000dc1,0x00000810, + 0x000200f9,0x000007fb,0x000200f8,0x000007a3,0x00050051,0x00000008,0x000007a5,0x00000593, + 0x00000002,0x000500ba,0x00000068,0x000007a6,0x000007a5,0x000000f9,0x000300f7,0x000007ae, + 0x00000000,0x000400fa,0x000007a6,0x000007a7,0x000007aa,0x000200f8,0x000007aa,0x0007004f, + 0x0000001c,0x000007ac,0x00000593,0x00000593,0x00000000,0x00000001,0x0006000c,0x00000008, + 0x000007ad,0x00000001,0x00000042,0x000007ac,0x000200f9,0x000007ae,0x000200f8,0x000007a7, + 0x00050051,0x00000008,0x000007a9,0x00000593,0x00000000,0x000200f9,0x000007ae,0x000200f8, + 0x000007ae,0x000700f5,0x00000008,0x00000f36,0x000007a9,0x000007a7,0x000007ad,0x000007aa, + 0x0008000c,0x00000008,0x000007b1,0x00000001,0x0000002b,0x00000f36,0x000000f9,0x000000fe, + 0x0006000c,0x00000008,0x000007b4,0x00000001,0x00000004,0x000007a5,0x000500ba,0x00000068, + 0x000007b6,0x000007b4,0x000000fe,0x000300f7,0x000007c0,0x00000000,0x000400fa,0x000007b6, + 0x000007b7,0x000007bb,0x000200f8,0x000007bb,0x00050085,0x00000008,0x000007bd,0x0000042d, + 0x000007b1,0x00050081,0x00000008,0x000007bf,0x000007bd,0x000007b4,0x000200f9,0x000007c0, + 0x000200f8,0x000007b7,0x00050085,0x00000008,0x000007b9,0x00000427,0x000007b1,0x00050081, + 0x00000008,0x000007ba,0x000007b9,0x0000042a,0x000200f9,0x000007c0,0x000200f8,0x000007c0, + 0x000700f5,0x00000008,0x00000f37,0x000007ba,0x000007b7,0x000007bf,0x000007bb,0x0004007f, + 0x00000008,0x000007c4,0x0000078f,0x0004003d,0x0000019a,0x000007c5,0x00000437,0x0004003d, + 0x0000019e,0x000007c6,0x00000439,0x00050056,0x000001a2,0x000007c7,0x000007c5,0x000007c6, + 0x00050050,0x0000001c,0x000007ca,0x00000f37,0x000007c4,0x00070058,0x0000000d,0x000007cb, + 0x000007c7,0x000007ca,0x00000002,0x000000f9,0x00050051,0x00000008,0x000007ce,0x000007cb, + 0x00000003,0x00050085,0x00000008,0x000007cf,0x000007ce,0x00000f21,0x00060052,0x0000000d, + 0x00000dad,0x000007cf,0x000007cb,0x00000003,0x000300f7,0x000007dd,0x00000000,0x000400fa, + 0x00000445,0x000007d1,0x000007dd,0x000200f8,0x000007d1,0x00050051,0x00000008,0x000007d3, + 0x00000dad,0x00000003,0x0008004f,0x00000026,0x000007d5,0x00000dad,0x00000dad,0x00000000, + 0x00000001,0x00000002,0x0005008e,0x00000026,0x000007d6,0x000007d5,0x000007d3,0x00050051, + 0x00000008,0x000007d8,0x000007d6,0x00000000,0x00060052,0x0000000d,0x00000db0,0x000007d8, + 0x00000dad,0x00000000,0x00050051,0x00000008,0x000007da,0x000007d6,0x00000001,0x00060052, + 0x0000000d,0x00000db2,0x000007da,0x00000db0,0x00000001,0x00050051,0x00000008,0x000007dc, + 0x000007d6,0x00000002,0x00060052,0x0000000d,0x00000db4,0x000007dc,0x00000db2,0x00000002, + 0x000200f9,0x000007dd,0x000200f8,0x000007dd,0x000700f5,0x0000000d,0x00000f3b,0x00000dad, + 0x000007c0,0x00000db4,0x000007d1,0x000200f9,0x000007fb,0x000200f8,0x000007fb,0x000700f5, + 0x0000000d,0x00000f3a,0x00000f3b,0x000007dd,0x00000f3c,0x000007fa,0x000200f9,0x000007fc, + 0x000200f8,0x00000791,0x000300f7,0x0000079e,0x00000000,0x000400fa,0x000003fa,0x00000794, + 0x00000798,0x000200f8,0x00000798,0x00050051,0x00000008,0x0000079b,0x00000593,0x00000003, + 0x00050085,0x00000008,0x0000079c,0x0000079b,0x00000f21,0x00060052,0x0000000d,0x00000da5, + 0x0000079c,0x00000593,0x00000003,0x000200f9,0x0000079e,0x000200f8,0x00000794,0x0005008e, + 0x0000000d,0x00000797,0x00000593,0x00000f21,0x000200f9,0x0000079e,0x000200f8,0x0000079e, + 0x000700f5,0x0000000d,0x00000f39,0x00000797,0x00000794,0x00000da5,0x00000798,0x000200f9, + 0x000007fc,0x000200f8,0x000007fc,0x000700f5,0x0000000d,0x00000f38,0x00000f39,0x0000079e, + 0x00000f3a,0x000007fb,0x000500b7,0x00000068,0x00000599,0x000004c9,0x000004ce,0x000300f7, + 0x0000059b,0x00000000,0x000400fa,0x00000599,0x0000059a,0x000005a0,0x000200f8,0x000005a0, + 0x0004003d,0x0000054a,0x000005a1,0x0000054c,0x00050062,0x0000000d,0x000005a2,0x000005a1, + 0x000004c2,0x0004003d,0x0000054a,0x000005a3,0x0000054c,0x00050062,0x0000000d,0x000005a4, + 0x000005a3,0x000004c2,0x0003003e,0x00000542,0x000005a4,0x000200f9,0x0000059b,0x000200f8, + 0x0000059a,0x0004003d,0x0000054a,0x0000059d,0x0000055e,0x00050062,0x0000000d,0x0000059e, + 0x0000059d,0x000004c2,0x0003003e,0x00000542,0x0000059e,0x000200f9,0x0000059b,0x000200f8, + 0x0000059b,0x000700f5,0x0000000d,0x00000f3e,0x0000059e,0x0000059a,0x000005a2,0x000005a0, + 0x000300f7,0x000005a6,0x00000000,0x000400fa,0x000003f9,0x000005a5,0x000005a6,0x000200f8, + 0x000005a5,0x0004003d,0x00000008,0x000005a8,0x000005a7,0x000500b7,0x00000068,0x000005ab, + 0x000005a8,0x000000f9,0x000300f7,0x000005ad,0x00000000,0x000400fa,0x000005ab,0x000005ac, + 0x000005ad,0x000200f8,0x000005ac,0x0004006d,0x00000006,0x00000829,0x000005a8,0x0008004f, + 0x00000026,0x000005b3,0x00000f38,0x00000f38,0x00000000,0x00000001,0x00000002,0x0003003e, + 0x0000082b,0x000005b3,0x0008004f,0x00000026,0x00000965,0x00000f3e,0x00000f3e,0x00000000, + 0x00000001,0x00000002,0x00050051,0x00000008,0x00000967,0x00000f3e,0x00000003,0x000500b7, + 0x00000068,0x00000968,0x00000967,0x000000f9,0x000300f7,0x0000096e,0x00000000,0x000400fa, + 0x00000968,0x00000969,0x0000096d,0x000200f8,0x0000096d,0x000200f9,0x0000096e,0x000200f8, + 0x00000969,0x00050088,0x00000008,0x0000096c,0x000000fe,0x00000967,0x000200f9,0x0000096e, + 0x000200f8,0x0000096e,0x000700f5,0x00000008,0x00000f3f,0x0000096c,0x00000969,0x000000f9, + 0x0000096d,0x0005008e,0x00000026,0x00000970,0x00000965,0x00000f3f,0x0003003e,0x0000083b, + 0x00000970,0x000300f7,0x0000095f,0x00000000,0x002100fb,0x00000829,0x0000095f,0x0000000b, + 0x00000866,0x00000001,0x0000086a,0x00000002,0x00000872,0x00000003,0x00000883,0x00000004, + 0x00000887,0x00000005,0x0000088b,0x00000006,0x000008ae,0x00000007,0x000008db,0x00000008, + 0x000008ec,0x00000009,0x00000927,0x0000000a,0x0000092c,0x0000000c,0x00000935,0x0000000d, + 0x00000940,0x0000000e,0x0000094b,0x0000000f,0x00000955,0x000200f8,0x00000955,0x000300f7, + 0x0000095e,0x00000000,0x000400fa,0x0000039e,0x00000956,0x0000095e,0x000200f8,0x00000956, + 0x0004003d,0x00000026,0x00000957,0x0000082b,0x00060052,0x00000026,0x00000ebb,0x000000f9, + 0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000ebd,0x000000f9,0x00000ebb,0x00000001, + 0x00060052,0x00000026,0x00000ebf,0x000000f9,0x00000ebd,0x00000002,0x00060052,0x00000026, + 0x00000ec1,0x000000fe,0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000ec3,0x000000fe, + 0x00000ec1,0x00000001,0x00060052,0x00000026,0x00000ec5,0x000000fe,0x00000ec3,0x00000002, + 0x0008000c,0x00000026,0x0000095a,0x00000001,0x0000002b,0x00000957,0x00000ebf,0x00000ec5, + 0x0003003e,0x0000082b,0x0000095a,0x00060052,0x00000026,0x00000ec7,0x00000242,0x00000f4d, + 0x00000000,0x00060052,0x00000026,0x00000ec9,0x00000243,0x00000ec7,0x00000001,0x00060052, + 0x00000026,0x00000ecb,0x00000244,0x00000ec9,0x00000002,0x00050094,0x00000008,0x00000ce1, + 0x0000095a,0x00000ecb,0x00050094,0x00000008,0x00000cf3,0x00000970,0x00000ecb,0x00060050, + 0x00000026,0x00000cbe,0x00000cf3,0x00000cf3,0x00000cf3,0x00050083,0x00000026,0x00000cbf, + 0x00000970,0x00000cbe,0x00050083,0x00000008,0x00000cc1,0x000000fe,0x00000ce1,0x00060052, + 0x0000001c,0x00000ed3,0x00000ce1,0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000ed5, + 0x00000cc1,0x00000ed3,0x00000001,0x00060052,0x0000001c,0x00000ed7,0x0000025e,0x000013e8, + 0x00000000,0x00060052,0x0000001c,0x00000ed9,0x0000025e,0x00000ed7,0x00000001,0x0007004f, + 0x0000001c,0x00000d12,0x00000cbf,0x00000cbf,0x00000000,0x00000001,0x00050051,0x00000008, + 0x00000d1a,0x00000d12,0x00000000,0x00050051,0x00000008,0x00000d1c,0x00000d12,0x00000001, + 0x0007000c,0x00000008,0x00000d1d,0x00000001,0x00000025,0x00000d1a,0x00000d1c,0x00050051, + 0x00000008,0x00000d15,0x00000cbf,0x00000002,0x0007000c,0x00000008,0x00000d16,0x00000001, + 0x00000025,0x00000d1d,0x00000d15,0x0004007f,0x00000008,0x00000cc7,0x00000d16,0x0007000c, + 0x00000008,0x00000d2d,0x00000001,0x00000028,0x00000d1a,0x00000d1c,0x0007000c,0x00000008, + 0x00000d26,0x00000001,0x00000028,0x00000d2d,0x00000d15,0x00060052,0x0000001c,0x00000ee1, + 0x00000cc7,0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000ee3,0x00000d26,0x00000ee1, + 0x00000001,0x0007000c,0x0000001c,0x00000ccb,0x00000001,0x00000028,0x00000ed9,0x00000ee3, + 0x00050088,0x0000001c,0x00000ccc,0x00000ed5,0x00000ccb,0x00050051,0x00000008,0x00000ccf, + 0x00000ccc,0x00000000,0x00050051,0x00000008,0x00000cd1,0x00000ccc,0x00000001,0x0007000c, + 0x00000008,0x00000cd2,0x00000001,0x00000025,0x00000ccf,0x00000cd1,0x0007000c,0x00000008, + 0x00000cd3,0x00000001,0x00000025,0x000000fe,0x00000cd2,0x0005008e,0x00000026,0x00000cd6, + 0x00000cbf,0x00000cd3,0x00060050,0x00000026,0x00000cd8,0x00000ce1,0x00000ce1,0x00000ce1, + 0x00050081,0x00000026,0x00000cd9,0x00000cd6,0x00000cd8,0x0003003e,0x0000083d,0x00000cd9, + 0x000200f9,0x0000095e,0x000200f8,0x0000095e,0x000200f9,0x0000095f,0x000200f8,0x0000094b, + 0x000300f7,0x00000954,0x00000000,0x000400fa,0x0000039e,0x0000094c,0x00000954,0x000200f8, + 0x0000094c,0x0004003d,0x00000026,0x0000094d,0x0000082b,0x00060052,0x00000026,0x00000e8f, + 0x000000f9,0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e91,0x000000f9,0x00000e8f, + 0x00000001,0x00060052,0x00000026,0x00000e93,0x000000f9,0x00000e91,0x00000002,0x00060052, + 0x00000026,0x00000e95,0x000000fe,0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e97, + 0x000000fe,0x00000e95,0x00000001,0x00060052,0x00000026,0x00000e99,0x000000fe,0x00000e97, + 0x00000002,0x0008000c,0x00000026,0x00000950,0x00000001,0x0000002b,0x0000094d,0x00000e93, + 0x00000e99,0x0003003e,0x0000082b,0x00000950,0x00060052,0x00000026,0x00000e9b,0x00000242, + 0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e9d,0x00000243,0x00000e9b,0x00000001, + 0x00060052,0x00000026,0x00000e9f,0x00000244,0x00000e9d,0x00000002,0x00050094,0x00000008, + 0x00000c3d,0x00000970,0x00000e9f,0x00050094,0x00000008,0x00000c4f,0x00000950,0x00000e9f, + 0x00060050,0x00000026,0x00000c1a,0x00000c4f,0x00000c4f,0x00000c4f,0x00050083,0x00000026, + 0x00000c1b,0x00000950,0x00000c1a,0x00050083,0x00000008,0x00000c1d,0x000000fe,0x00000c3d, + 0x00060052,0x0000001c,0x00000ea7,0x00000c3d,0x000013e8,0x00000000,0x00060052,0x0000001c, + 0x00000ea9,0x00000c1d,0x00000ea7,0x00000001,0x00060052,0x0000001c,0x00000eab,0x0000025e, + 0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000ead,0x0000025e,0x00000eab,0x00000001, + 0x0007004f,0x0000001c,0x00000c6e,0x00000c1b,0x00000c1b,0x00000000,0x00000001,0x00050051, + 0x00000008,0x00000c76,0x00000c6e,0x00000000,0x00050051,0x00000008,0x00000c78,0x00000c6e, + 0x00000001,0x0007000c,0x00000008,0x00000c79,0x00000001,0x00000025,0x00000c76,0x00000c78, + 0x00050051,0x00000008,0x00000c71,0x00000c1b,0x00000002,0x0007000c,0x00000008,0x00000c72, + 0x00000001,0x00000025,0x00000c79,0x00000c71,0x0004007f,0x00000008,0x00000c23,0x00000c72, + 0x0007000c,0x00000008,0x00000c89,0x00000001,0x00000028,0x00000c76,0x00000c78,0x0007000c, + 0x00000008,0x00000c82,0x00000001,0x00000028,0x00000c89,0x00000c71,0x00060052,0x0000001c, + 0x00000eb5,0x00000c23,0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000eb7,0x00000c82, + 0x00000eb5,0x00000001,0x0007000c,0x0000001c,0x00000c27,0x00000001,0x00000028,0x00000ead, + 0x00000eb7,0x00050088,0x0000001c,0x00000c28,0x00000ea9,0x00000c27,0x00050051,0x00000008, + 0x00000c2b,0x00000c28,0x00000000,0x00050051,0x00000008,0x00000c2d,0x00000c28,0x00000001, + 0x0007000c,0x00000008,0x00000c2e,0x00000001,0x00000025,0x00000c2b,0x00000c2d,0x0007000c, + 0x00000008,0x00000c2f,0x00000001,0x00000025,0x000000fe,0x00000c2e,0x0005008e,0x00000026, + 0x00000c32,0x00000c1b,0x00000c2f,0x00060050,0x00000026,0x00000c34,0x00000c3d,0x00000c3d, + 0x00000c3d,0x00050081,0x00000026,0x00000c35,0x00000c32,0x00000c34,0x0003003e,0x0000083d, + 0x00000c35,0x000200f9,0x00000954,0x000200f8,0x00000954,0x000200f9,0x0000095f,0x000200f8, + 0x00000940,0x000300f7,0x0000094a,0x00000000,0x000400fa,0x0000039e,0x00000941,0x0000094a, + 0x000200f8,0x00000941,0x0004003d,0x00000026,0x00000942,0x0000082b,0x00060052,0x00000026, + 0x00000e57,0x000000f9,0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e59,0x000000f9, + 0x00000e57,0x00000001,0x00060052,0x00000026,0x00000e5b,0x000000f9,0x00000e59,0x00000002, + 0x00060052,0x00000026,0x00000e5d,0x000000fe,0x00000f4d,0x00000000,0x00060052,0x00000026, + 0x00000e5f,0x000000fe,0x00000e5d,0x00000001,0x00060052,0x00000026,0x00000e61,0x000000fe, + 0x00000e5f,0x00000002,0x0008000c,0x00000026,0x00000945,0x00000001,0x0000002b,0x00000942, + 0x00000e5b,0x00000e61,0x0003003e,0x0000082b,0x00000945,0x0007004f,0x0000001c,0x00000b25, + 0x00000945,0x00000945,0x00000000,0x00000001,0x00050051,0x00000008,0x00000b2d,0x00000b25, + 0x00000000,0x00050051,0x00000008,0x00000b2f,0x00000b25,0x00000001,0x0007000c,0x00000008, + 0x00000b30,0x00000001,0x00000028,0x00000b2d,0x00000b2f,0x00050051,0x00000008,0x00000b28, + 0x00000945,0x00000002,0x0007000c,0x00000008,0x00000b29,0x00000001,0x00000028,0x00000b30, + 0x00000b28,0x0007000c,0x00000008,0x00000b40,0x00000001,0x00000025,0x00000b2d,0x00000b2f, + 0x0007000c,0x00000008,0x00000b39,0x00000001,0x00000025,0x00000b40,0x00000b28,0x00050083, + 0x00000008,0x00000b10,0x00000b29,0x00000b39,0x0007004f,0x0000001c,0x00000b45,0x00000970, + 0x00000970,0x00000000,0x00000001,0x00050051,0x00000008,0x00000b4d,0x00000b45,0x00000000, + 0x00050051,0x00000008,0x00000b4f,0x00000b45,0x00000001,0x0007000c,0x00000008,0x00000b50, + 0x00000001,0x00000025,0x00000b4d,0x00000b4f,0x00050051,0x00000008,0x00000b48,0x00000970, + 0x00000002,0x0007000c,0x00000008,0x00000b49,0x00000001,0x00000025,0x00000b50,0x00000b48, + 0x00060050,0x00000026,0x00000b14,0x00000b49,0x00000b49,0x00000b49,0x00050083,0x00000026, + 0x00000b15,0x00000970,0x00000b14,0x0007004f,0x0000001c,0x00000b55,0x00000b15,0x00000b15, + 0x00000000,0x00000001,0x00050051,0x00000008,0x00000b5d,0x00000b55,0x00000000,0x00050051, + 0x00000008,0x00000b5f,0x00000b55,0x00000001,0x0007000c,0x00000008,0x00000b60,0x00000001, + 0x00000028,0x00000b5d,0x00000b5f,0x00050051,0x00000008,0x00000b58,0x00000b15,0x00000002, + 0x0007000c,0x00000008,0x00000b59,0x00000001,0x00000028,0x00000b60,0x00000b58,0x0007000c, + 0x00000008,0x00000b1a,0x00000001,0x00000028,0x0000025e,0x00000b59,0x00050088,0x00000008, + 0x00000b1b,0x00000b10,0x00000b1a,0x0005008e,0x00000026,0x00000b1e,0x00000b15,0x00000b1b, + 0x00060052,0x00000026,0x00000e6f,0x00000242,0x00000f4d,0x00000000,0x00060052,0x00000026, + 0x00000e71,0x00000243,0x00000e6f,0x00000001,0x00060052,0x00000026,0x00000e73,0x00000244, + 0x00000e71,0x00000002,0x00050094,0x00000008,0x00000b99,0x00000970,0x00000e73,0x00050094, + 0x00000008,0x00000bab,0x00000b1e,0x00000e73,0x00060050,0x00000026,0x00000b76,0x00000bab, + 0x00000bab,0x00000bab,0x00050083,0x00000026,0x00000b77,0x00000b1e,0x00000b76,0x00050083, + 0x00000008,0x00000b79,0x000000fe,0x00000b99,0x00060052,0x0000001c,0x00000e7b,0x00000b99, + 0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000e7d,0x00000b79,0x00000e7b,0x00000001, + 0x00060052,0x0000001c,0x00000e7f,0x0000025e,0x000013e8,0x00000000,0x00060052,0x0000001c, + 0x00000e81,0x0000025e,0x00000e7f,0x00000001,0x0007004f,0x0000001c,0x00000bca,0x00000b77, + 0x00000b77,0x00000000,0x00000001,0x00050051,0x00000008,0x00000bd2,0x00000bca,0x00000000, + 0x00050051,0x00000008,0x00000bd4,0x00000bca,0x00000001,0x0007000c,0x00000008,0x00000bd5, + 0x00000001,0x00000025,0x00000bd2,0x00000bd4,0x00050051,0x00000008,0x00000bcd,0x00000b77, + 0x00000002,0x0007000c,0x00000008,0x00000bce,0x00000001,0x00000025,0x00000bd5,0x00000bcd, + 0x0004007f,0x00000008,0x00000b7f,0x00000bce,0x0007000c,0x00000008,0x00000be5,0x00000001, + 0x00000028,0x00000bd2,0x00000bd4,0x0007000c,0x00000008,0x00000bde,0x00000001,0x00000028, + 0x00000be5,0x00000bcd,0x00060052,0x0000001c,0x00000e89,0x00000b7f,0x000013e8,0x00000000, + 0x00060052,0x0000001c,0x00000e8b,0x00000bde,0x00000e89,0x00000001,0x0007000c,0x0000001c, + 0x00000b83,0x00000001,0x00000028,0x00000e81,0x00000e8b,0x00050088,0x0000001c,0x00000b84, + 0x00000e7d,0x00000b83,0x00050051,0x00000008,0x00000b87,0x00000b84,0x00000000,0x00050051, + 0x00000008,0x00000b89,0x00000b84,0x00000001,0x0007000c,0x00000008,0x00000b8a,0x00000001, + 0x00000025,0x00000b87,0x00000b89,0x0007000c,0x00000008,0x00000b8b,0x00000001,0x00000025, + 0x000000fe,0x00000b8a,0x0005008e,0x00000026,0x00000b8e,0x00000b77,0x00000b8b,0x00060050, + 0x00000026,0x00000b90,0x00000b99,0x00000b99,0x00000b99,0x00050081,0x00000026,0x00000b91, + 0x00000b8e,0x00000b90,0x0003003e,0x0000083d,0x00000b91,0x000200f9,0x0000094a,0x000200f8, + 0x0000094a,0x000200f9,0x0000095f,0x000200f8,0x00000935,0x000300f7,0x0000093f,0x00000000, + 0x000400fa,0x0000039e,0x00000936,0x0000093f,0x000200f8,0x00000936,0x0004003d,0x00000026, + 0x00000937,0x0000082b,0x00060052,0x00000026,0x00000e1f,0x000000f9,0x00000f4d,0x00000000, + 0x00060052,0x00000026,0x00000e21,0x000000f9,0x00000e1f,0x00000001,0x00060052,0x00000026, + 0x00000e23,0x000000f9,0x00000e21,0x00000002,0x00060052,0x00000026,0x00000e25,0x000000fe, + 0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e27,0x000000fe,0x00000e25,0x00000001, + 0x00060052,0x00000026,0x00000e29,0x000000fe,0x00000e27,0x00000002,0x0008000c,0x00000026, + 0x0000093a,0x00000001,0x0000002b,0x00000937,0x00000e23,0x00000e29,0x0003003e,0x0000082b, + 0x0000093a,0x0007004f,0x0000001c,0x00000a21,0x00000970,0x00000970,0x00000000,0x00000001, + 0x00050051,0x00000008,0x00000a29,0x00000a21,0x00000000,0x00050051,0x00000008,0x00000a2b, + 0x00000a21,0x00000001,0x0007000c,0x00000008,0x00000a2c,0x00000001,0x00000028,0x00000a29, + 0x00000a2b,0x00050051,0x00000008,0x00000a24,0x00000970,0x00000002,0x0007000c,0x00000008, + 0x00000a25,0x00000001,0x00000028,0x00000a2c,0x00000a24,0x0007000c,0x00000008,0x00000a3c, + 0x00000001,0x00000025,0x00000a29,0x00000a2b,0x0007000c,0x00000008,0x00000a35,0x00000001, + 0x00000025,0x00000a3c,0x00000a24,0x00050083,0x00000008,0x00000a0c,0x00000a25,0x00000a35, + 0x0007004f,0x0000001c,0x00000a41,0x0000093a,0x0000093a,0x00000000,0x00000001,0x00050051, + 0x00000008,0x00000a49,0x00000a41,0x00000000,0x00050051,0x00000008,0x00000a4b,0x00000a41, + 0x00000001,0x0007000c,0x00000008,0x00000a4c,0x00000001,0x00000025,0x00000a49,0x00000a4b, + 0x00050051,0x00000008,0x00000a44,0x0000093a,0x00000002,0x0007000c,0x00000008,0x00000a45, + 0x00000001,0x00000025,0x00000a4c,0x00000a44,0x00060050,0x00000026,0x00000a10,0x00000a45, + 0x00000a45,0x00000a45,0x00050083,0x00000026,0x00000a11,0x0000093a,0x00000a10,0x0007004f, + 0x0000001c,0x00000a51,0x00000a11,0x00000a11,0x00000000,0x00000001,0x00050051,0x00000008, + 0x00000a59,0x00000a51,0x00000000,0x00050051,0x00000008,0x00000a5b,0x00000a51,0x00000001, + 0x0007000c,0x00000008,0x00000a5c,0x00000001,0x00000028,0x00000a59,0x00000a5b,0x00050051, + 0x00000008,0x00000a54,0x00000a11,0x00000002,0x0007000c,0x00000008,0x00000a55,0x00000001, + 0x00000028,0x00000a5c,0x00000a54,0x0007000c,0x00000008,0x00000a16,0x00000001,0x00000028, + 0x0000025e,0x00000a55,0x00050088,0x00000008,0x00000a17,0x00000a0c,0x00000a16,0x0005008e, + 0x00000026,0x00000a1a,0x00000a11,0x00000a17,0x00060052,0x00000026,0x00000e37,0x00000242, + 0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e39,0x00000243,0x00000e37,0x00000001, + 0x00060052,0x00000026,0x00000e3b,0x00000244,0x00000e39,0x00000002,0x00050094,0x00000008, + 0x00000a95,0x00000970,0x00000e3b,0x00050094,0x00000008,0x00000aa7,0x00000a1a,0x00000e3b, + 0x00060050,0x00000026,0x00000a72,0x00000aa7,0x00000aa7,0x00000aa7,0x00050083,0x00000026, + 0x00000a73,0x00000a1a,0x00000a72,0x00050083,0x00000008,0x00000a75,0x000000fe,0x00000a95, + 0x00060052,0x0000001c,0x00000e43,0x00000a95,0x000013e8,0x00000000,0x00060052,0x0000001c, + 0x00000e45,0x00000a75,0x00000e43,0x00000001,0x00060052,0x0000001c,0x00000e47,0x0000025e, + 0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000e49,0x0000025e,0x00000e47,0x00000001, + 0x0007004f,0x0000001c,0x00000ac6,0x00000a73,0x00000a73,0x00000000,0x00000001,0x00050051, + 0x00000008,0x00000ace,0x00000ac6,0x00000000,0x00050051,0x00000008,0x00000ad0,0x00000ac6, + 0x00000001,0x0007000c,0x00000008,0x00000ad1,0x00000001,0x00000025,0x00000ace,0x00000ad0, + 0x00050051,0x00000008,0x00000ac9,0x00000a73,0x00000002,0x0007000c,0x00000008,0x00000aca, + 0x00000001,0x00000025,0x00000ad1,0x00000ac9,0x0004007f,0x00000008,0x00000a7b,0x00000aca, + 0x0007000c,0x00000008,0x00000ae1,0x00000001,0x00000028,0x00000ace,0x00000ad0,0x0007000c, + 0x00000008,0x00000ada,0x00000001,0x00000028,0x00000ae1,0x00000ac9,0x00060052,0x0000001c, + 0x00000e51,0x00000a7b,0x000013e8,0x00000000,0x00060052,0x0000001c,0x00000e53,0x00000ada, + 0x00000e51,0x00000001,0x0007000c,0x0000001c,0x00000a7f,0x00000001,0x00000028,0x00000e49, + 0x00000e53,0x00050088,0x0000001c,0x00000a80,0x00000e45,0x00000a7f,0x00050051,0x00000008, + 0x00000a83,0x00000a80,0x00000000,0x00050051,0x00000008,0x00000a85,0x00000a80,0x00000001, + 0x0007000c,0x00000008,0x00000a86,0x00000001,0x00000025,0x00000a83,0x00000a85,0x0007000c, + 0x00000008,0x00000a87,0x00000001,0x00000025,0x000000fe,0x00000a86,0x0005008e,0x00000026, + 0x00000a8a,0x00000a73,0x00000a87,0x00060050,0x00000026,0x00000a8c,0x00000a95,0x00000a95, + 0x00000a95,0x00050081,0x00000026,0x00000a8d,0x00000a8a,0x00000a8c,0x0003003e,0x0000083d, + 0x00000a8d,0x000200f9,0x0000093f,0x000200f8,0x0000093f,0x000200f9,0x0000095f,0x000200f8, + 0x0000092c,0x0004003d,0x00000026,0x0000092d,0x0000082b,0x00050081,0x00000026,0x0000092f, + 0x0000092d,0x00000970,0x0005008e,0x00000026,0x00000931,0x0000092d,0x000002c4,0x00050085, + 0x00000026,0x00000933,0x00000931,0x00000970,0x00050083,0x00000026,0x00000934,0x0000092f, + 0x00000933,0x0003003e,0x0000083d,0x00000934,0x000200f9,0x0000095f,0x000200f8,0x00000927, + 0x0004003d,0x00000026,0x00000929,0x0000082b,0x00050083,0x00000026,0x0000092a,0x00000970, + 0x00000929,0x0006000c,0x00000026,0x0000092b,0x00000001,0x00000004,0x0000092a,0x0003003e, + 0x0000083d,0x0000092b,0x000200f9,0x0000095f,0x000200f8,0x000008ec,0x000200f9,0x000008ed, + 0x000200f8,0x000008ed,0x000700f5,0x0000034d,0x00001235,0x00000350,0x000008ec,0x0000091b, + 0x00000919,0x000500b1,0x00000068,0x000008f0,0x00001235,0x00000357,0x000400f6,0x0000091c, + 0x00000919,0x00000000,0x000400fa,0x000008f0,0x000008f1,0x0000091c,0x000200f8,0x000008f1, + 0x00050041,0x00000013,0x000008f3,0x0000082b,0x00001235,0x0004003d,0x00000008,0x000008f4, + 0x000008f3,0x000500bc,0x00000068,0x000008f5,0x000008f4,0x000002cb,0x000300f7,0x00000918, + 0x00000000,0x000400fa,0x000008f5,0x000008f6,0x000008fd,0x000200f8,0x000008fd,0x00050041, + 0x00000013,0x000008ff,0x0000083b,0x00001235,0x0004003d,0x00000008,0x00000900,0x000008ff, + 0x000500bc,0x00000068,0x00000901,0x00000900,0x000001b4,0x000300f7,0x00000917,0x00000000, + 0x000400fa,0x00000901,0x00000902,0x0000090f,0x000200f8,0x0000090f,0x0004003d,0x00000008, + 0x00000913,0x000008ff,0x0006000c,0x00000008,0x00000914,0x00000001,0x00000020,0x00000913, + 0x00050083,0x00000008,0x00000915,0x00000914,0x000000fe,0x00050041,0x00000013,0x00000916, + 0x0000083d,0x00001235,0x0003003e,0x00000916,0x00000915,0x000200f9,0x00000917,0x000200f8, + 0x00000902,0x0004003d,0x00000008,0x00000906,0x000008ff,0x00050085,0x00000008,0x00000907, + 0x0000036d,0x00000906,0x00050083,0x00000008,0x00000908,0x00000907,0x00000372,0x0004003d, + 0x00000008,0x0000090b,0x000008ff,0x00050085,0x00000008,0x0000090c,0x00000908,0x0000090b, + 0x00050081,0x00000008,0x0000090d,0x0000090c,0x00000222,0x00050041,0x00000013,0x0000090e, + 0x0000083d,0x00001235,0x0003003e,0x0000090e,0x0000090d,0x000200f9,0x00000917,0x000200f8, + 0x00000917,0x000200f9,0x00000918,0x000200f8,0x000008f6,0x00050041,0x00000013,0x000008f9, + 0x0000083b,0x00001235,0x0004003d,0x00000008,0x000008fa,0x000008f9,0x00050083,0x00000008, + 0x000008fb,0x000000fe,0x000008fa,0x00050041,0x00000013,0x000008fc,0x0000083d,0x00001235, + 0x0003003e,0x000008fc,0x000008fb,0x000200f9,0x00000918,0x000200f8,0x00000918,0x000200f9, + 0x00000919,0x000200f8,0x00000919,0x00050080,0x0000034d,0x0000091b,0x00001235,0x00000383, + 0x000200f9,0x000008ed,0x000200f8,0x0000091c,0x0004003d,0x00000026,0x0000091f,0x0000082b, + 0x0005008e,0x00000026,0x00000920,0x0000091f,0x000002c4,0x00050083,0x00000026,0x00000922, + 0x00000920,0x000013e6,0x00050085,0x00000026,0x00000923,0x00000970,0x00000922,0x0004003d, + 0x00000026,0x00000924,0x0000083d,0x00050085,0x00000026,0x00000925,0x00000923,0x00000924, + 0x00050081,0x00000026,0x00000926,0x00000970,0x00000925,0x0003003e,0x0000083d,0x00000926, + 0x000200f9,0x0000095f,0x000200f8,0x000008db,0x0004003d,0x00000026,0x000008dc,0x0000082b, + 0x00050085,0x00000026,0x000008de,0x000008dc,0x00000970,0x00050081,0x00000026,0x000008e2, + 0x000008dc,0x00000970,0x00050083,0x00000026,0x000008e4,0x000008e2,0x000008de,0x00050083, + 0x00000026,0x000008e6,0x000008e4,0x000013e5,0x00060052,0x00000026,0x00000e19,0x000002cb, + 0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000e1b,0x000002cb,0x00000e19,0x00000001, + 0x00060052,0x00000026,0x00000e1d,0x000002cb,0x00000e1b,0x00000002,0x000500ba,0x000002d1, + 0x000008e9,0x000008dc,0x00000e1d,0x000600a9,0x00000026,0x000008ea,0x000008e9,0x000008e6, + 0x000008de,0x0005008e,0x00000026,0x000008eb,0x000008ea,0x000002c4,0x0003003e,0x0000083d, + 0x000008eb,0x000200f9,0x0000095f,0x000200f8,0x000008ae,0x0004003d,0x00000026,0x000008af, + 0x0000082b,0x00060052,0x00000026,0x00000df0,0x000000f9,0x00000f4d,0x00000000,0x00060052, + 0x00000026,0x00000df2,0x000000f9,0x00000df0,0x00000001,0x00060052,0x00000026,0x00000df4, + 0x000000f9,0x00000df2,0x00000002,0x00060052,0x00000026,0x00000df6,0x000000fe,0x00000f4d, + 0x00000000,0x00060052,0x00000026,0x00000df8,0x000000fe,0x00000df6,0x00000001,0x00060052, + 0x00000026,0x00000dfa,0x000000fe,0x00000df8,0x00000002,0x0008000c,0x00000026,0x000008b2, + 0x00000001,0x0000002b,0x000008af,0x00000df4,0x00000dfa,0x0003003e,0x0000082b,0x000008b2, + 0x0008004f,0x00000026,0x000008b7,0x00000f3e,0x00000f3e,0x00000003,0x00000003,0x00000003, + 0x0008000c,0x00000026,0x000008b8,0x00000001,0x0000002b,0x00000965,0x00000df4,0x000008b7, + 0x00050051,0x00000008,0x000008ba,0x000008b8,0x00000000,0x00060052,0x0000000d,0x00000e02, + 0x000008ba,0x00000f3e,0x00000000,0x00050051,0x00000008,0x000008bc,0x000008b8,0x00000001, + 0x00060052,0x0000000d,0x00000e04,0x000008bc,0x00000e02,0x00000001,0x00050051,0x00000008, + 0x000008be,0x000008b8,0x00000002,0x00060052,0x0000000d,0x00000e06,0x000008be,0x00000e04, + 0x00000002,0x00050051,0x00000008,0x000008c0,0x00000e06,0x00000003,0x000500b4,0x00000068, + 0x000008c1,0x000008c0,0x000000f9,0x000300f7,0x000008c4,0x00000000,0x000400fa,0x000008c1, + 0x000008c2,0x000008c4,0x000200f8,0x000008c2,0x00060052,0x0000000d,0x00000e09,0x000000fe, + 0x00000e06,0x00000003,0x000200f9,0x000008c4,0x000200f8,0x000008c4,0x000700f5,0x0000000d, + 0x000012a5,0x00000e06,0x000008ae,0x00000e09,0x000008c2,0x00050051,0x00000008,0x000008c6, + 0x000012a5,0x00000003,0x0008004f,0x00000026,0x000008c8,0x000012a5,0x000012a5,0x00000000, + 0x00000001,0x00000002,0x00060050,0x00000026,0x000008c9,0x000008c6,0x000008c6,0x000008c6, + 0x00050083,0x00000026,0x000008ca,0x000008c9,0x000008c8,0x0004003d,0x00000026,0x000008cd, + 0x0000082b,0x0005008e,0x00000026,0x000008d0,0x000008cd,0x000008c6,0x00050088,0x00000026, + 0x000008d1,0x000008ca,0x000008d0,0x0007000c,0x00000026,0x000008d2,0x00000001,0x00000025, + 0x00000dfa,0x000008d1,0x0006000c,0x00000026,0x000008d4,0x00000001,0x00000006,0x000008ca, + 0x000500b4,0x000002d1,0x000008d7,0x000008cd,0x00000df4,0x000600a9,0x00000026,0x000008d8, + 0x000008d7,0x000008d4,0x000008d2,0x00050083,0x00000026,0x000008da,0x000013e6,0x000008d8, + 0x0003003e,0x0000083d,0x000008da,0x000200f9,0x0000095f,0x000200f8,0x0000088b,0x00060052, + 0x00000026,0x00000dcb,0x000000f9,0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000dcd, + 0x000000f9,0x00000dcb,0x00000001,0x00060052,0x00000026,0x00000dcf,0x000000f9,0x00000dcd, + 0x00000002,0x0008004f,0x00000026,0x00000890,0x00000f3e,0x00000f3e,0x00000003,0x00000003, + 0x00000003,0x0008000c,0x00000026,0x00000891,0x00000001,0x0000002b,0x00000965,0x00000dcf, + 0x00000890,0x00050051,0x00000008,0x00000893,0x00000891,0x00000000,0x00060052,0x0000000d, + 0x00000dd1,0x00000893,0x00000f3e,0x00000000,0x00050051,0x00000008,0x00000895,0x00000891, + 0x00000001,0x00060052,0x0000000d,0x00000dd3,0x00000895,0x00000dd1,0x00000001,0x00050051, + 0x00000008,0x00000897,0x00000891,0x00000002,0x00060052,0x0000000d,0x00000dd5,0x00000897, + 0x00000dd3,0x00000002,0x0004003d,0x00000026,0x00000898,0x0000082b,0x00050083,0x00000026, + 0x0000089a,0x000013e6,0x00000898,0x00060052,0x00000026,0x00000ddd,0x000000fe,0x00000f4d, + 0x00000000,0x00060052,0x00000026,0x00000ddf,0x000000fe,0x00000ddd,0x00000001,0x00060052, + 0x00000026,0x00000de1,0x000000fe,0x00000ddf,0x00000002,0x0008000c,0x00000026,0x0000089d, + 0x00000001,0x0000002b,0x0000089a,0x00000dcf,0x00000de1,0x00050051,0x00000008,0x0000089f, + 0x00000dd5,0x00000003,0x0005008e,0x00000026,0x000008a0,0x0000089d,0x0000089f,0x0008004f, + 0x00000026,0x000008a3,0x00000dd5,0x00000dd5,0x00000000,0x00000001,0x00000002,0x00050088, + 0x00000026,0x000008a5,0x000008a3,0x000008a0,0x0007000c,0x00000026,0x000008a6,0x00000001, + 0x00000025,0x00000de1,0x000008a5,0x0006000c,0x00000026,0x000008a9,0x00000001,0x00000006, + 0x000008a3,0x000500b4,0x000002d1,0x000008ac,0x000008a0,0x00000dcf,0x000600a9,0x00000026, + 0x000008ad,0x000008ac,0x000008a9,0x000008a6,0x0003003e,0x0000083d,0x000008ad,0x000200f9, + 0x0000095f,0x000200f8,0x00000887,0x0004003d,0x00000026,0x00000888,0x0000082b,0x0007000c, + 0x00000026,0x0000088a,0x00000001,0x00000028,0x00000888,0x00000970,0x0003003e,0x0000083d, + 0x0000088a,0x000200f9,0x0000095f,0x000200f8,0x00000883,0x0004003d,0x00000026,0x00000884, + 0x0000082b,0x0007000c,0x00000026,0x00000886,0x00000001,0x00000025,0x00000884,0x00000970, + 0x0003003e,0x0000083d,0x00000886,0x000200f9,0x0000095f,0x000200f8,0x00000872,0x0004003d, + 0x00000026,0x00000873,0x0000082b,0x00050085,0x00000026,0x00000875,0x00000873,0x00000970, + 0x00050081,0x00000026,0x00000879,0x00000873,0x00000970,0x00050083,0x00000026,0x0000087b, + 0x00000879,0x00000875,0x00050083,0x00000026,0x0000087d,0x0000087b,0x000013e5,0x00060052, + 0x00000026,0x00000dc5,0x000002cb,0x00000f4d,0x00000000,0x00060052,0x00000026,0x00000dc7, + 0x000002cb,0x00000dc5,0x00000001,0x00060052,0x00000026,0x00000dc9,0x000002cb,0x00000dc7, + 0x00000002,0x000500ba,0x000002d1,0x00000880,0x00000970,0x00000dc9,0x000600a9,0x00000026, + 0x00000881,0x00000880,0x0000087d,0x00000875,0x0005008e,0x00000026,0x00000882,0x00000881, + 0x000002c4,0x0003003e,0x0000083d,0x00000882,0x000200f9,0x0000095f,0x000200f8,0x0000086a, + 0x0004003d,0x00000026,0x0000086b,0x0000082b,0x00050081,0x00000026,0x0000086d,0x0000086b, + 0x00000970,0x00050085,0x00000026,0x00000870,0x0000086b,0x00000970,0x00050083,0x00000026, + 0x00000871,0x0000086d,0x00000870,0x0003003e,0x0000083d,0x00000871,0x000200f9,0x0000095f, + 0x000200f8,0x00000866,0x0004003d,0x00000026,0x00000867,0x0000082b,0x00050085,0x00000026, + 0x00000869,0x00000867,0x00000970,0x0003003e,0x0000083d,0x00000869,0x000200f9,0x0000095f, + 0x000200f8,0x0000095f,0x0004003d,0x00000026,0x00000960,0x0000083d,0x00060052,0x00000026, + 0x00000ee8,0x00000967,0x000013e9,0x00000000,0x00060052,0x00000026,0x00000eea,0x00000967, + 0x00000ee8,0x00000001,0x00060052,0x00000026,0x00000eec,0x00000967,0x00000eea,0x00000002, + 0x0008000c,0x00000026,0x0000083a,0x00000001,0x0000002e,0x000005b3,0x00000960,0x00000eec, + 0x00050051,0x00000008,0x000005b9,0x0000083a,0x00000000,0x00060052,0x0000000d,0x00000eee, + 0x000005b9,0x00000f38,0x00000000,0x00050051,0x00000008,0x000005bb,0x0000083a,0x00000001, + 0x00060052,0x0000000d,0x00000ef0,0x000005bb,0x00000eee,0x00000001,0x00050051,0x00000008, + 0x000005bd,0x0000083a,0x00000002,0x00060052,0x0000000d,0x00000ef2,0x000005bd,0x00000ef0, + 0x00000002,0x000200f9,0x000005ad,0x000200f8,0x000005ad,0x000700f5,0x0000000d,0x000013ae, + 0x00000f38,0x000005a5,0x00000ef2,0x0000095f,0x00050051,0x00000008,0x000005bf,0x000013ae, + 0x00000003,0x0008004f,0x00000026,0x000005c1,0x000013ae,0x000013ae,0x00000000,0x00000001, + 0x00000002,0x0005008e,0x00000026,0x000005c2,0x000005c1,0x000005bf,0x00050051,0x00000008, + 0x000005c4,0x000005c2,0x00000000,0x00060052,0x0000000d,0x00000ef5,0x000005c4,0x000013ae, + 0x00000000,0x00050051,0x00000008,0x000005c6,0x000005c2,0x00000001,0x00060052,0x0000000d, + 0x00000ef7,0x000005c6,0x00000ef5,0x00000001,0x00050051,0x00000008,0x000005c8,0x000005c2, + 0x00000002,0x00060052,0x0000000d,0x00000ef9,0x000005c8,0x00000ef7,0x00000002,0x000200f9, + 0x000005a6,0x000200f8,0x000005a6,0x000700f5,0x0000000d,0x000013bb,0x00000f38,0x0000059b, + 0x00000ef9,0x000005ad,0x00050051,0x00000008,0x000005cb,0x000013bb,0x00000003,0x00050083, + 0x00000008,0x000005cc,0x000000fe,0x000005cb,0x0005008e,0x0000000d,0x000005cd,0x00000f3e, + 0x000005cc,0x00050081,0x0000000d,0x000005cf,0x000013bb,0x000005cd,0x0008004f,0x00000026, + 0x000005d9,0x000005cf,0x000005cf,0x00000000,0x00000001,0x00000002,0x0004003d,0x0000000d, + 0x000005db,0x000005d0,0x0007004f,0x0000001c,0x000005dc,0x000005db,0x000005db,0x00000000, + 0x00000001,0x00050041,0x000005de,0x000005df,0x000005d4,0x000005d5,0x0004003d,0x00000008, + 0x000005e0,0x000005df,0x00050041,0x000005de,0x000005e2,0x000005d4,0x000005d6,0x0004003d, + 0x00000008,0x000005e3,0x000005e2,0x000300f7,0x00000d53,0x00000000,0x000400fa,0x0000016a, + 0x00000d49,0x00000d51,0x000200f8,0x00000d51,0x000200f9,0x00000d53,0x000200f8,0x00000d49, + 0x00050051,0x00000008,0x00000d5a,0x000005dc,0x00000000,0x00050085,0x00000008,0x00000d5b, + 0x00000154,0x00000d5a,0x00050051,0x00000008,0x00000d5d,0x000005dc,0x00000001,0x00050085, + 0x00000008,0x00000d5e,0x00000158,0x00000d5d,0x00050081,0x00000008,0x00000d5f,0x00000d5b, + 0x00000d5e,0x0006000c,0x00000008,0x00000d60,0x00000001,0x0000000a,0x00000d5f,0x00050085, + 0x00000008,0x00000d62,0x0000015f,0x00000d60,0x0006000c,0x00000008,0x00000d63,0x00000001, + 0x0000000a,0x00000d62,0x00050085,0x00000008,0x00000d66,0x00000d63,0x000005e0,0x00050081, + 0x00000008,0x00000d68,0x00000d66,0x000005e3,0x00060050,0x00000026,0x00000d4f,0x00000d68, + 0x00000d68,0x00000d68,0x00050081,0x00000026,0x00000d50,0x00000d4f,0x000005d9,0x000200f9, + 0x00000d53,0x000200f8,0x00000d53,0x000700f5,0x00000026,0x000013bc,0x00000d50,0x00000d49, + 0x000005d9,0x00000d51,0x00050051,0x00000008,0x000005e6,0x000013bc,0x00000000,0x00060052, + 0x0000000d,0x00000efe,0x000005e6,0x000005cf,0x00000000,0x00050051,0x00000008,0x000005e8, + 0x000013bc,0x00000001,0x00060052,0x0000000d,0x00000f00,0x000005e8,0x00000efe,0x00000001, + 0x00050051,0x00000008,0x000005ea,0x000013bc,0x00000002,0x00060052,0x0000000d,0x00000f02, + 0x000005ea,0x00000f00,0x00000002,0x0003003e,0x0000055d,0x00000f02,0x0004003d,0x000004bd, + 0x000005ec,0x00000529,0x00050062,0x000004c3,0x000005ed,0x000005ec,0x000004c2,0x00050051, + 0x00000006,0x000005ee,0x000005ed,0x00000000,0x00050041,0x000004e8,0x000005ef,0x00000555, + 0x000000b6,0x0003003e,0x000005ef,0x000005ee,0x000200f9,0x00000519,0x000200f8,0x00000518, + 0x00050041,0x000004cc,0x0000051b,0x00000513,0x000000b6,0x0004003d,0x00000008,0x0000051c, + 0x0000051b,0x0004007f,0x00000008,0x0000051d,0x0000051c,0x000300f7,0x00000520,0x00000000, + 0x000400fa,0x0000051e,0x0000051f,0x00000520,0x000200f8,0x0000051f,0x00050041,0x000004cc, + 0x00000522,0x00000513,0x000000b9,0x0004003d,0x00000008,0x00000523,0x00000522,0x000500b7, + 0x00000068,0x00000525,0x00000523,0x000000f9,0x000300f7,0x00000527,0x00000000,0x000400fa, + 0x00000525,0x00000526,0x00000527,0x000200f8,0x00000526,0x0004003d,0x000004bd,0x0000052a, + 0x00000529,0x00050062,0x000004c3,0x0000052b,0x0000052a,0x000004c2,0x00050051,0x00000006, + 0x0000052c,0x0000052b,0x00000000,0x0006000c,0x0000001c,0x0000052d,0x00000001,0x0000003e, + 0x0000052c,0x00050051,0x00000008,0x00000530,0x0000052d,0x00000001,0x000500b7,0x00000068, + 0x00000533,0x00000530,0x0000051d,0x000300f7,0x00000535,0x00000000,0x000400fa,0x00000533, + 0x00000534,0x00000549,0x000200f8,0x00000549,0x0004003d,0x0000054a,0x0000054d,0x0000054c, + 0x00050062,0x0000000d,0x0000054e,0x0000054d,0x000004c2,0x00050051,0x00000008,0x0000054f, + 0x0000054e,0x00000000,0x0004003d,0x0000054a,0x00000550,0x0000054c,0x00050062,0x0000000d, + 0x00000551,0x00000550,0x000004c2,0x0003003e,0x00000542,0x00000551,0x000200f9,0x00000535, + 0x000200f8,0x00000534,0x000500b4,0x00000068,0x00000539,0x00000530,0x00000523,0x000300f7, + 0x0000053c,0x00000000,0x000400fa,0x00000539,0x0000053b,0x0000053f,0x000200f8,0x0000053f, + 0x000200f9,0x0000053c,0x000200f8,0x0000053b,0x00050051,0x00000008,0x0000053e,0x0000052d, + 0x00000000,0x000200f9,0x0000053c,0x000200f8,0x0000053c,0x000700f5,0x00000008,0x000013be, + 0x0000053e,0x0000053b,0x000000f9,0x0000053f,0x00060052,0x0000000d,0x00000d93,0x000013be, + 0x00000f08,0x00000000,0x00060052,0x0000000d,0x00000d95,0x000000f9,0x00000d93,0x00000001, + 0x00060052,0x0000000d,0x00000d97,0x000000f9,0x00000d95,0x00000002,0x00060052,0x0000000d, + 0x00000d99,0x000000f9,0x00000d97,0x00000003,0x0003003e,0x00000542,0x00000d99,0x000200f9, + 0x00000535,0x000200f8,0x00000535,0x000700f5,0x00000008,0x000013cf,0x000013be,0x0000053c, + 0x0000054f,0x00000549,0x0007000c,0x00000008,0x00000554,0x00000001,0x00000025,0x00000f1d, + 0x000013cf,0x000200f9,0x00000527,0x000200f8,0x00000527,0x000700f5,0x00000008,0x000013d1, + 0x00000f1d,0x0000051f,0x00000554,0x00000535,0x000200f9,0x00000520,0x000200f8,0x00000520, + 0x000700f5,0x00000008,0x000013d0,0x00000f1d,0x00000518,0x000013d1,0x00000527,0x00060052, + 0x0000001c,0x00000d9b,0x000013d0,0x00000f14,0x00000000,0x00060052,0x0000001c,0x00000d9d, + 0x0000051d,0x00000d9b,0x00000001,0x0006000c,0x00000006,0x0000055b,0x00000001,0x0000003a, + 0x00000d9d,0x00050041,0x000004e8,0x0000055c,0x00000555,0x000000b6,0x0003003e,0x0000055c, + 0x0000055b,0x0004003d,0x0000054a,0x0000055f,0x0000055e,0x00050062,0x0000000d,0x00000560, + 0x0000055f,0x000004c2,0x0003003e,0x0000055d,0x00000560,0x000200f9,0x00000519,0x000200f8, + 0x00000519,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..f2929693ab78f632a5400e2040e74c1e1e995f26 GIT binary patch literal 29644 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.h new file mode 100644 index 000000000..d6946b626 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.h @@ -0,0 +1,669 @@ +#pragma once + +const uint32_t draw_path_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000bfe,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0010000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000046a,0x0000046d,0x00000471, + 0x00000472,0x00000485,0x00000492,0x000004c6,0x000004cc,0x000004eb,0x0000050b,0x0000058b, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,0x0000014f, + 0x00004342,0x00030005,0x0000015f,0x0000664b,0x00040006,0x0000015f,0x00000000,0x00003464, + 0x00030005,0x00000161,0x00004358,0x00030005,0x00000174,0x0000664a,0x00040006,0x00000174, + 0x00000000,0x00003464,0x00030005,0x00000176,0x0000424c,0x00030005,0x00000456,0x0000424d, + 0x00040006,0x00000456,0x00000000,0x00006250,0x00040006,0x00000456,0x00000001,0x00006359, + 0x00040006,0x00000456,0x00000002,0x00006552,0x00040006,0x00000456,0x00000003,0x00006553, + 0x00040006,0x00000456,0x00000004,0x0000366d,0x00040006,0x00000456,0x00000005,0x0000676d, + 0x00040006,0x00000456,0x00000006,0x00006544,0x00040006,0x00000456,0x00000007,0x00006545, + 0x00040006,0x00000456,0x00000008,0x00003755,0x00040006,0x00000456,0x00000009,0x0000676a, + 0x00040006,0x00000456,0x0000000a,0x0000635a,0x00040006,0x00000456,0x0000000b,0x00003157, + 0x00040006,0x00000456,0x0000000c,0x0000676e,0x00040006,0x00000456,0x0000000d,0x00003559, + 0x00040006,0x00000456,0x0000000e,0x0000324f,0x00040006,0x00000456,0x0000000f,0x00006461, + 0x00040006,0x00000456,0x00000010,0x00006579,0x00040006,0x00000456,0x00000011,0x00003376, + 0x00040006,0x00000456,0x00000012,0x00003377,0x00040006,0x00000456,0x00000013,0x00006462, + 0x00040006,0x00000456,0x00000014,0x00006767,0x00030005,0x00000458,0x0000006b,0x00060005, + 0x0000046a,0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00070005,0x0000046d,0x495f6c67, + 0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005,0x00000471,0x00004254,0x00030005, + 0x00000472,0x00004255,0x00030005,0x00000485,0x00000049,0x00030005,0x0000048a,0x00006576, + 0x00040006,0x0000048a,0x00000000,0x00003464,0x00030005,0x0000048c,0x00004355,0x00030005, + 0x00000492,0x0000307a,0x00030005,0x000004a8,0x00006747,0x00030005,0x000004c6,0x00003153, + 0x00030005,0x000004c9,0x00006749,0x00030005,0x000004cc,0x00003159,0x00030005,0x000004d5, + 0x00006748,0x00030005,0x000004da,0x00006577,0x00040006,0x000004da,0x00000000,0x00003464, + 0x00030005,0x000004dc,0x0000424f,0x00030005,0x000004eb,0x0000304e,0x00030005,0x0000050b, + 0x0000316b,0x00060005,0x00000589,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006, + 0x00000589,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000589,0x00000001, + 0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000589,0x00000002,0x435f6c67, + 0x4470696c,0x61747369,0x0065636e,0x00070006,0x00000589,0x00000003,0x435f6c67,0x446c6c75, + 0x61747369,0x0065636e,0x00030005,0x0000058b,0x00000000,0x00030005,0x00000599,0x00004351, + 0x00030005,0x0000059c,0x00003954,0x00040047,0x0000014f,0x00000021,0x00000008,0x00040047, + 0x0000014f,0x00000022,0x00000000,0x00040047,0x0000015e,0x00000006,0x00000010,0x00030047, + 0x0000015f,0x00000003,0x00040048,0x0000015f,0x00000000,0x00000018,0x00050048,0x0000015f, + 0x00000000,0x00000023,0x00000000,0x00030047,0x00000161,0x00000018,0x00040047,0x00000161, + 0x00000021,0x00000006,0x00040047,0x00000161,0x00000022,0x00000000,0x00040047,0x00000173, + 0x00000006,0x00000010,0x00030047,0x00000174,0x00000003,0x00040048,0x00000174,0x00000000, + 0x00000018,0x00050048,0x00000174,0x00000000,0x00000023,0x00000000,0x00030047,0x00000176, + 0x00000018,0x00040047,0x00000176,0x00000021,0x00000003,0x00040047,0x00000176,0x00000022, + 0x00000000,0x00030047,0x00000456,0x00000002,0x00050048,0x00000456,0x00000000,0x00000023, + 0x00000000,0x00050048,0x00000456,0x00000001,0x00000023,0x00000004,0x00050048,0x00000456, + 0x00000002,0x00000023,0x00000008,0x00050048,0x00000456,0x00000003,0x00000023,0x0000000c, + 0x00050048,0x00000456,0x00000004,0x00000023,0x00000010,0x00050048,0x00000456,0x00000005, + 0x00000023,0x00000014,0x00050048,0x00000456,0x00000006,0x00000023,0x00000018,0x00050048, + 0x00000456,0x00000007,0x00000023,0x0000001c,0x00050048,0x00000456,0x00000008,0x00000023, + 0x00000020,0x00050048,0x00000456,0x00000009,0x00000023,0x00000030,0x00050048,0x00000456, + 0x0000000a,0x00000023,0x00000038,0x00050048,0x00000456,0x0000000b,0x00000023,0x00000040, + 0x00050048,0x00000456,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000456,0x0000000d, + 0x00000023,0x00000048,0x00050048,0x00000456,0x0000000e,0x00000023,0x0000004c,0x00050048, + 0x00000456,0x0000000f,0x00000023,0x00000050,0x00050048,0x00000456,0x00000010,0x00000023, + 0x00000054,0x00050048,0x00000456,0x00000011,0x00000023,0x00000058,0x00050048,0x00000456, + 0x00000012,0x00000023,0x0000005c,0x00050048,0x00000456,0x00000013,0x00000023,0x00000060, + 0x00050048,0x00000456,0x00000014,0x00000023,0x00000064,0x00040047,0x00000458,0x00000021, + 0x00000000,0x00040047,0x00000458,0x00000022,0x00000000,0x00040047,0x0000046a,0x0000000b, + 0x0000002a,0x00040047,0x0000046d,0x0000000b,0x0000002b,0x00040047,0x00000471,0x0000001e, + 0x00000000,0x00040047,0x00000472,0x0000001e,0x00000001,0x00040047,0x00000485,0x0000001e, + 0x00000002,0x00040047,0x00000489,0x00000006,0x00000008,0x00030047,0x0000048a,0x00000003, + 0x00040048,0x0000048a,0x00000000,0x00000018,0x00050048,0x0000048a,0x00000000,0x00000023, + 0x00000000,0x00030047,0x0000048c,0x00000018,0x00040047,0x0000048c,0x00000021,0x00000004, + 0x00040047,0x0000048c,0x00000022,0x00000000,0x00030047,0x00000492,0x00000000,0x00030047, + 0x00000492,0x0000000e,0x00040047,0x00000492,0x0000001e,0x00000003,0x00030047,0x000004a1, + 0x00000000,0x00030047,0x000004a2,0x00000000,0x00040047,0x000004a8,0x00000001,0x00000000, + 0x00030047,0x000004c4,0x00000000,0x00030047,0x000004c6,0x00000000,0x00030047,0x000004c6, + 0x0000000e,0x00040047,0x000004c6,0x0000001e,0x00000004,0x00040047,0x000004c9,0x00000001, + 0x00000002,0x00030047,0x000004cc,0x00000000,0x00030047,0x000004cc,0x0000000e,0x00040047, + 0x000004cc,0x0000001e,0x00000006,0x00040047,0x000004d5,0x00000001,0x00000001,0x00040047, + 0x000004d9,0x00000006,0x00000010,0x00030047,0x000004da,0x00000003,0x00040048,0x000004da, + 0x00000000,0x00000018,0x00050048,0x000004da,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000004dc,0x00000018,0x00040047,0x000004dc,0x00000021,0x00000005,0x00040047,0x000004dc, + 0x00000022,0x00000000,0x00040047,0x000004eb,0x0000001e,0x00000005,0x00030047,0x00000500, + 0x00000000,0x00030047,0x00000503,0x00000000,0x00030047,0x00000504,0x00000000,0x00040047, + 0x0000050b,0x0000001e,0x00000000,0x00030047,0x00000589,0x00000002,0x00050048,0x00000589, + 0x00000000,0x0000000b,0x00000000,0x00050048,0x00000589,0x00000001,0x0000000b,0x00000001, + 0x00050048,0x00000589,0x00000002,0x0000000b,0x00000003,0x00050048,0x00000589,0x00000003, + 0x0000000b,0x00000004,0x00030047,0x00000599,0x00000000,0x00040047,0x00000599,0x00000021, + 0x0000000a,0x00040047,0x00000599,0x00000022,0x00000000,0x00030047,0x0000059c,0x00000000, + 0x00040047,0x0000059c,0x00000021,0x0000000a,0x00040047,0x0000059c,0x00000022,0x00000000, + 0x00030047,0x00000751,0x00000000,0x00030047,0x00000a53,0x00000000,0x00030047,0x00000a55, + 0x00000000,0x00030047,0x00000a57,0x00000000,0x00030047,0x00000b71,0x00000000,0x00030047, + 0x00000bd7,0x00000000,0x00030047,0x00000bda,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006, + 0x00000002,0x00020014,0x00000011,0x00040017,0x00000013,0x00000011,0x00000002,0x00040017, + 0x00000018,0x00000006,0x00000004,0x00040018,0x0000001a,0x0000000c,0x00000002,0x00040015, + 0x0000001f,0x00000020,0x00000000,0x00040015,0x0000003a,0x00000020,0x00000001,0x00040017, + 0x0000003c,0x0000003a,0x00000002,0x0004002b,0x00000006,0x00000060,0x3f800000,0x0004002b, + 0x00000006,0x00000061,0x00000000,0x0004002b,0x0000001f,0x0000006c,0x00000000,0x0004002b, + 0x0000001f,0x00000073,0x000003ff,0x0004002b,0x0000001f,0x00000083,0x00000001,0x0004002b, + 0x0000003a,0x0000008f,0x00000000,0x0004002b,0x0000003a,0x00000093,0x00000001,0x0004002b, + 0x00000006,0x000000bb,0x3f000000,0x0004002b,0x00000006,0x000000cd,0x3fc90fdb,0x0004002b, + 0x00000006,0x000000d0,0x3a83126f,0x0004002b,0x00000006,0x000000df,0x358637bd,0x0004002b, + 0x00000006,0x000000fc,0x3e800000,0x0004002b,0x00000006,0x00000102,0xc0000000,0x0004002b, + 0x0000001f,0x00000106,0x00000002,0x0004002b,0x0000001f,0x00000109,0x00000003,0x0004002b, + 0x0000003a,0x0000010f,0x000007ff,0x0004002b,0x0000003a,0x00000112,0x0000000b,0x0004002b, + 0x0000003a,0x00000137,0x00000002,0x0004002b,0x0000003a,0x0000013d,0x00000003,0x00040017, + 0x0000014a,0x0000001f,0x00000004,0x00090019,0x0000014d,0x0000001f,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x0000014e,0x00000000,0x0000014d, + 0x0004003b,0x0000014e,0x0000014f,0x00000000,0x0004002b,0x0000001f,0x0000015a,0x0000ffff, + 0x0003001d,0x0000015e,0x0000014a,0x0003001e,0x0000015f,0x0000015e,0x00040020,0x00000160, + 0x00000002,0x0000015f,0x0004003b,0x00000160,0x00000161,0x00000002,0x00040020,0x00000164, + 0x00000002,0x0000014a,0x00040017,0x00000168,0x0000001f,0x00000002,0x0003001d,0x00000173, + 0x0000014a,0x0003001e,0x00000174,0x00000173,0x00040020,0x00000175,0x00000002,0x00000174, + 0x0004003b,0x00000175,0x00000176,0x00000002,0x0004002b,0x0000001f,0x00000178,0x00000004, + 0x0004002b,0x0000001f,0x00000193,0x00800000,0x0004002b,0x0000001f,0x000001b3,0x0080ffff, + 0x0004002b,0x0000001f,0x000001d3,0xff7fffff,0x0004002b,0x0000001f,0x000001d8,0x1c000000, + 0x0004002b,0x0000001f,0x000001da,0x04000000,0x0004002b,0x0000003a,0x000001ea,0x00000010, + 0x0004002b,0x00000006,0x0000022f,0x40490fdb,0x0004002b,0x00000006,0x00000233,0x40c90fdb, + 0x0004002b,0x00000006,0x00000268,0x40000000,0x0004002b,0x0000001f,0x000002a2,0x00100000, + 0x0004002b,0x0000001f,0x000002aa,0x00080000,0x0004002b,0x0000001f,0x000002f8,0x08000000, + 0x0004002b,0x0000001f,0x000002fe,0x00400000,0x0004002b,0x00000006,0x00000332,0xbf000000, + 0x0004002b,0x0000001f,0x00000349,0x14000000,0x0004002b,0x0000001f,0x0000034f,0x10000000, + 0x0004002b,0x0000001f,0x00000359,0x02000000,0x0004002b,0x0000001f,0x00000371,0x00200000, + 0x0004002b,0x00000006,0x0000037c,0x3e000000,0x0004002b,0x00000006,0x000003ca,0x38d1b717, + 0x0003002a,0x00000011,0x000003de,0x0004002b,0x00000006,0x000003e2,0xbf800000,0x0004002b, + 0x00000006,0x000003e9,0x49742400,0x0004002b,0x0000001f,0x00000433,0x01000000,0x0007002c, + 0x00000018,0x00000439,0x000003e2,0x00000060,0x00000060,0x00000060,0x0004002b,0x0000001f, + 0x00000442,0x80000000,0x0005002c,0x0000000c,0x00000454,0x00000060,0x000003e2,0x00040017, + 0x00000455,0x0000003a,0x00000004,0x0017001e,0x00000456,0x00000006,0x00000006,0x00000006, + 0x00000006,0x0000001f,0x0000001f,0x0000001f,0x0000001f,0x00000455,0x0000000c,0x0000000c, + 0x0000001f,0x00000006,0x0000001f,0x00000006,0x00000006,0x0000001f,0x00000006,0x00000006, + 0x00000006,0x0000001f,0x00040020,0x00000457,0x00000002,0x00000456,0x0004003b,0x00000457, + 0x00000458,0x00000002,0x0004002b,0x0000003a,0x00000459,0x00000014,0x00040020,0x0000045a, + 0x00000002,0x0000001f,0x00030029,0x00000011,0x00000465,0x00040020,0x00000469,0x00000001, + 0x0000003a,0x0004003b,0x00000469,0x0000046a,0x00000001,0x0004003b,0x00000469,0x0000046d, + 0x00000001,0x00040020,0x00000470,0x00000001,0x00000018,0x0004003b,0x00000470,0x00000471, + 0x00000001,0x0004003b,0x00000470,0x00000472,0x00000001,0x00040020,0x00000484,0x00000003, + 0x00000018,0x0004003b,0x00000484,0x00000485,0x00000003,0x0003001d,0x00000489,0x00000168, + 0x0003001e,0x0000048a,0x00000489,0x00040020,0x0000048b,0x00000002,0x0000048a,0x0004003b, + 0x0000048b,0x0000048c,0x00000002,0x00040020,0x0000048e,0x00000002,0x00000168,0x00040020, + 0x00000491,0x00000003,0x00000006,0x0004003b,0x00000491,0x00000492,0x00000003,0x0004002b, + 0x0000003a,0x00000493,0x0000000d,0x0004002b,0x0000001f,0x0000049c,0x00000200,0x0004002b, + 0x0000001f,0x000004a6,0x0000000f,0x00030030,0x00000011,0x000004a8,0x00040020,0x000004c5, + 0x00000003,0x0000000c,0x0004003b,0x000004c5,0x000004c6,0x00000003,0x00030030,0x00000011, + 0x000004c9,0x0004003b,0x00000491,0x000004cc,0x00000003,0x0004002b,0x0000003a,0x000004cf, + 0x00000004,0x00030030,0x00000011,0x000004d5,0x0003001d,0x000004d9,0x00000018,0x0003001e, + 0x000004da,0x000004d9,0x00040020,0x000004db,0x00000002,0x000004da,0x0004003b,0x000004db, + 0x000004dc,0x00000002,0x00040020,0x000004e1,0x00000002,0x00000018,0x0004003b,0x00000484, + 0x000004eb,0x00000003,0x00050034,0x00000011,0x000004fc,0x000000a8,0x000004c9,0x00040017, + 0x00000501,0x00000006,0x00000003,0x0004003b,0x00000484,0x0000050b,0x00000003,0x0004002b, + 0x00000006,0x00000543,0x3f666666,0x00040020,0x00000576,0x00000002,0x00000006,0x0004002b, + 0x0000003a,0x0000057e,0x0000000e,0x0004001c,0x00000588,0x00000006,0x00000083,0x0006001e, + 0x00000589,0x00000018,0x00000006,0x00000588,0x00000588,0x00040020,0x0000058a,0x00000003, + 0x00000589,0x0004003b,0x0000058a,0x0000058b,0x00000003,0x00090019,0x00000597,0x00000006, + 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000598, + 0x00000000,0x00000597,0x0004003b,0x00000598,0x00000599,0x00000000,0x0002001a,0x0000059a, + 0x00040020,0x0000059b,0x00000000,0x0000059a,0x0004003b,0x0000059b,0x0000059c,0x00000000, + 0x00030001,0x00000006,0x00000ad7,0x00030001,0x0000000c,0x00000bbe,0x0005002c,0x0000000c, + 0x00000bee,0x00000060,0x00000060,0x0005002c,0x0000000c,0x00000bef,0x000000bb,0x000000bb, + 0x0004002b,0x0000003a,0x00000bf1,0xfffffffe,0x0007002c,0x00000018,0x00000bf2,0x000000bb, + 0x000000bb,0x000000bb,0x000000bb,0x0004002b,0x00000006,0x00000bf3,0x3ea2f983,0x0004002b, + 0x00000006,0x00000bf4,0xc0400000,0x0003002e,0x0000000c,0x00000bf7,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000003a,0x0000046e, + 0x0000046d,0x0004003d,0x00000018,0x00000477,0x00000471,0x0004003d,0x00000018,0x00000479, + 0x00000472,0x000300f7,0x000008af,0x00000000,0x000300fb,0x0000006c,0x00000601,0x000200f8, + 0x00000601,0x00050051,0x00000006,0x00000603,0x00000477,0x00000000,0x0004006e,0x0000003a, + 0x00000604,0x00000603,0x00050051,0x00000006,0x00000606,0x00000477,0x00000001,0x00050051, + 0x00000006,0x00000608,0x00000477,0x00000002,0x00050051,0x00000006,0x0000060a,0x00000477, + 0x00000003,0x0004007c,0x0000003a,0x0000060b,0x0000060a,0x000500c3,0x0000003a,0x0000060c, + 0x0000060b,0x00000137,0x000500c7,0x0000003a,0x00000610,0x0000060b,0x0000013d,0x00050082, + 0x0000003a,0x00000613,0x0000060c,0x00000093,0x0007000c,0x0000003a,0x00000614,0x00000001, + 0x00000027,0x00000604,0x00000613,0x00050084,0x0000003a,0x00000617,0x0000046e,0x0000060c, + 0x00050080,0x0000003a,0x00000619,0x00000617,0x00000614,0x0004003d,0x0000014d,0x0000061a, + 0x0000014f,0x000500c7,0x0000003a,0x000008b4,0x00000619,0x0000010f,0x000500c3,0x0000003a, + 0x000008b6,0x00000619,0x00000112,0x00050050,0x0000003c,0x000008b7,0x000008b4,0x000008b6, + 0x0007005f,0x0000014a,0x0000061d,0x0000061a,0x000008b7,0x00000002,0x0000008f,0x00050051, + 0x0000001f,0x0000061f,0x0000061d,0x00000003,0x000500c7,0x0000001f,0x00000621,0x0000061f, + 0x0000015a,0x0007000c,0x0000001f,0x00000622,0x00000001,0x00000029,0x00000621,0x00000083, + 0x00050082,0x0000001f,0x00000624,0x00000622,0x00000083,0x00060041,0x00000164,0x00000625, + 0x00000161,0x0000008f,0x00000624,0x0004003d,0x0000014a,0x00000626,0x00000625,0x0007004f, + 0x00000168,0x00000628,0x00000626,0x00000626,0x00000000,0x00000001,0x0004007c,0x0000000c, + 0x00000629,0x00000628,0x00050051,0x0000001f,0x0000062b,0x00000626,0x00000002,0x000500c7, + 0x0000001f,0x0000062c,0x0000062b,0x0000015a,0x00050051,0x0000001f,0x0000062e,0x00000626, + 0x00000003,0x00050084,0x0000001f,0x00000630,0x0000062c,0x00000178,0x00060041,0x00000164, + 0x00000631,0x00000176,0x0000008f,0x00000630,0x0004003d,0x0000014a,0x00000632,0x00000631, + 0x0004007c,0x00000018,0x00000633,0x00000632,0x00050051,0x00000006,0x000008be,0x00000633, + 0x00000000,0x00050051,0x00000006,0x000008bf,0x00000633,0x00000001,0x00050051,0x00000006, + 0x000008c0,0x00000633,0x00000002,0x00050051,0x00000006,0x000008c1,0x00000633,0x00000003, + 0x00050050,0x0000000c,0x000008c2,0x000008be,0x000008bf,0x00050050,0x0000000c,0x000008c3, + 0x000008c0,0x000008c1,0x00050050,0x0000001a,0x000008c4,0x000008c2,0x000008c3,0x00050080, + 0x0000001f,0x00000637,0x00000630,0x00000083,0x00060041,0x00000164,0x00000638,0x00000176, + 0x0000008f,0x00000637,0x0004003d,0x0000014a,0x00000639,0x00000638,0x0007004f,0x00000168, + 0x0000063b,0x00000639,0x00000639,0x00000000,0x00000001,0x0004007c,0x0000000c,0x0000063c, + 0x0000063b,0x00050051,0x0000001f,0x0000063e,0x00000639,0x00000002,0x0004007c,0x00000006, + 0x0000063f,0x0000063e,0x00050051,0x0000001f,0x00000641,0x00000639,0x00000003,0x0004007c, + 0x00000006,0x00000642,0x00000641,0x000500c7,0x0000001f,0x00000644,0x0000061f,0x00000193, + 0x000500ab,0x00000011,0x00000646,0x00000644,0x0000006c,0x000300f7,0x0000064f,0x00000000, + 0x000400fa,0x00000646,0x00000647,0x0000064f,0x000200f8,0x00000647,0x00050051,0x00000006, + 0x00000649,0x00000479,0x00000000,0x0004006e,0x0000003a,0x0000064a,0x00000649,0x00050051, + 0x00000006,0x0000064c,0x00000479,0x00000001,0x00050051,0x00000006,0x0000064e,0x00000479, + 0x00000002,0x000200f9,0x0000064f,0x000200f8,0x0000064f,0x000700f5,0x00000006,0x00000abd, + 0x00000608,0x00000601,0x0000064e,0x00000647,0x000700f5,0x00000006,0x00000a7f,0x00000606, + 0x00000601,0x0000064c,0x00000647,0x000700f5,0x0000003a,0x00000a63,0x00000604,0x00000601, + 0x0000064a,0x00000647,0x000500ab,0x00000011,0x00000652,0x00000a63,0x00000614,0x000300f7, + 0x0000067f,0x00000000,0x000400fa,0x00000652,0x00000653,0x0000067f,0x000200f8,0x00000653, + 0x00050080,0x0000003a,0x00000656,0x00000619,0x00000a63,0x00050082,0x0000003a,0x00000658, + 0x00000656,0x00000614,0x0004003d,0x0000014d,0x00000659,0x0000014f,0x000500c7,0x0000003a, + 0x000008c8,0x00000658,0x0000010f,0x000500c3,0x0000003a,0x000008ca,0x00000658,0x00000112, + 0x00050050,0x0000003c,0x000008cb,0x000008c8,0x000008ca,0x0007005f,0x0000014a,0x0000065c, + 0x00000659,0x000008cb,0x00000002,0x0000008f,0x00050051,0x0000001f,0x0000065e,0x0000065c, + 0x00000003,0x000500c7,0x0000001f,0x0000065f,0x0000065e,0x000001b3,0x000500c7,0x0000001f, + 0x00000661,0x0000061f,0x000001b3,0x000500ab,0x00000011,0x00000662,0x0000065f,0x00000661, + 0x000300f7,0x00000679,0x00000000,0x000400fa,0x00000662,0x00000663,0x00000676,0x000200f8, + 0x00000676,0x000200f9,0x00000679,0x000200f8,0x00000663,0x000500b4,0x00000011,0x00000665, + 0x0000063f,0x00000061,0x000400a8,0x00000011,0x00000666,0x00000665,0x000300f7,0x0000066b, + 0x00000000,0x000400fa,0x00000666,0x00000667,0x0000066b,0x000200f8,0x00000667,0x00050051, + 0x00000006,0x00000669,0x00000629,0x00000000,0x000500b7,0x00000011,0x0000066a,0x00000669, + 0x00000061,0x000200f9,0x0000066b,0x000200f8,0x0000066b,0x000700f5,0x00000011,0x0000066c, + 0x00000665,0x00000663,0x0000066a,0x00000667,0x000300f7,0x00000675,0x00000000,0x000400fa, + 0x0000066c,0x0000066e,0x00000675,0x000200f8,0x0000066e,0x0004007c,0x0000003a,0x00000670, + 0x0000062e,0x0004003d,0x0000014d,0x00000671,0x0000014f,0x000500c7,0x0000003a,0x000008cf, + 0x00000670,0x0000010f,0x000500c3,0x0000003a,0x000008d1,0x00000670,0x00000112,0x00050050, + 0x0000003c,0x000008d2,0x000008cf,0x000008d1,0x0007005f,0x0000014a,0x00000674,0x00000671, + 0x000008d2,0x00000002,0x0000008f,0x000200f9,0x00000675,0x000200f8,0x00000675,0x000700f5, + 0x0000003a,0x00000a70,0x00000619,0x0000066b,0x00000670,0x0000066e,0x000700f5,0x0000014a, + 0x00000a68,0x0000061d,0x0000066b,0x00000674,0x0000066e,0x000200f9,0x00000679,0x000200f8, + 0x00000679,0x000700f5,0x0000003a,0x00000a6f,0x00000a70,0x00000675,0x00000658,0x00000676, + 0x000700f5,0x0000014a,0x00000a67,0x00000a68,0x00000675,0x0000065c,0x00000676,0x00050051, + 0x0000001f,0x0000067b,0x00000a67,0x00000003,0x000500c7,0x0000001f,0x0000067c,0x0000067b, + 0x000001d3,0x000500c5,0x0000001f,0x0000067e,0x0000067c,0x00000644,0x000200f9,0x0000067f, + 0x000200f8,0x0000067f,0x000700f5,0x0000003a,0x00000a6e,0x00000619,0x0000064f,0x00000a6f, + 0x00000679,0x000700f5,0x0000014a,0x00000a6c,0x0000061d,0x0000064f,0x00000a67,0x00000679, + 0x000700f5,0x0000001f,0x00000a6b,0x0000061f,0x0000064f,0x0000067e,0x00000679,0x000500c7, + 0x0000001f,0x00000681,0x00000a6b,0x000001d8,0x000500aa,0x00000011,0x00000682,0x00000681, + 0x000001da,0x000500aa,0x00000011,0x00000684,0x00000610,0x0000008f,0x000500a7,0x00000011, + 0x00000685,0x00000682,0x00000684,0x000300f7,0x00000710,0x00000000,0x000400fa,0x00000685, + 0x00000686,0x0000070c,0x000200f8,0x0000070c,0x00050051,0x0000001f,0x0000070e,0x00000a6c, + 0x00000002,0x0004007c,0x00000006,0x0000070f,0x0000070e,0x000200f9,0x00000710,0x000200f8, + 0x00000686,0x00050051,0x0000001f,0x00000688,0x00000a6c,0x00000002,0x000500c7,0x0000001f, + 0x0000068a,0x00000688,0x0000015a,0x00040070,0x00000006,0x0000068b,0x0000068a,0x000500c2, + 0x0000001f,0x0000068d,0x00000688,0x000001ea,0x00040070,0x00000006,0x0000068e,0x0000068d, + 0x00050083,0x00000006,0x00000691,0x000003e2,0x0000068b,0x0004006e,0x0000003a,0x00000692, + 0x00000691,0x00050083,0x00000006,0x00000695,0x0000068e,0x0000068b,0x00050081,0x00000006, + 0x00000696,0x00000695,0x00000060,0x0004006e,0x0000003a,0x00000697,0x00000696,0x00050050, + 0x0000003c,0x00000698,0x00000692,0x00000697,0x000500c7,0x0000001f,0x0000069a,0x00000a6b, + 0x00000193,0x000500ab,0x00000011,0x0000069b,0x0000069a,0x0000006c,0x000300f7,0x0000069f, + 0x00000000,0x000400fa,0x0000069b,0x0000069c,0x0000069f,0x000200f8,0x0000069c,0x0004007e, + 0x0000003c,0x0000069e,0x00000698,0x000200f9,0x0000069f,0x000200f8,0x0000069f,0x000700f5, + 0x0000003c,0x00000a72,0x00000698,0x00000686,0x0000069e,0x0000069c,0x0004003d,0x0000014d, + 0x000006a0,0x0000014f,0x00050051,0x0000003a,0x000006a3,0x00000a72,0x00000000,0x00050080, + 0x0000003a,0x000006a4,0x00000a6e,0x000006a3,0x000500c7,0x0000003a,0x000008d6,0x000006a4, + 0x0000010f,0x000500c3,0x0000003a,0x000008d8,0x000006a4,0x00000112,0x00050050,0x0000003c, + 0x000008d9,0x000008d6,0x000008d8,0x0007005f,0x0000014a,0x000006a6,0x000006a0,0x000008d9, + 0x00000002,0x0000008f,0x0004003d,0x0000014d,0x000006a7,0x0000014f,0x00050051,0x0000003a, + 0x000006aa,0x00000a72,0x00000001,0x00050080,0x0000003a,0x000006ab,0x00000a6e,0x000006aa, + 0x000500c7,0x0000003a,0x000008dd,0x000006ab,0x0000010f,0x000500c3,0x0000003a,0x000008df, + 0x000006ab,0x00000112,0x00050050,0x0000003c,0x000008e0,0x000008dd,0x000008df,0x0007005f, + 0x0000014a,0x000006ad,0x000006a7,0x000008e0,0x00000002,0x0000008f,0x00050051,0x0000001f, + 0x000006af,0x000006ad,0x00000003,0x000500c7,0x0000001f,0x000006b0,0x000006af,0x000001b3, + 0x00050051,0x0000001f,0x000006b2,0x000006a6,0x00000003,0x000500c7,0x0000001f,0x000006b3, + 0x000006b2,0x000001b3,0x000500ab,0x00000011,0x000006b4,0x000006b0,0x000006b3,0x000300f7, + 0x000006bb,0x00000000,0x000400fa,0x000006b4,0x000006b5,0x000006bb,0x000200f8,0x000006b5, + 0x0004003d,0x0000014d,0x000006b6,0x0000014f,0x0004007c,0x0000003a,0x000006b8,0x0000062e, + 0x000500c7,0x0000003a,0x000008e4,0x000006b8,0x0000010f,0x000500c3,0x0000003a,0x000008e6, + 0x000006b8,0x00000112,0x00050050,0x0000003c,0x000008e7,0x000008e4,0x000008e6,0x0007005f, + 0x0000014a,0x000006ba,0x000006b6,0x000008e7,0x00000002,0x0000008f,0x000200f9,0x000006bb, + 0x000200f8,0x000006bb,0x000700f5,0x0000014a,0x00000a73,0x000006ad,0x0000069f,0x000006ba, + 0x000006b5,0x00050051,0x0000001f,0x000006bd,0x000006a6,0x00000002,0x0004007c,0x00000006, + 0x000006be,0x000006bd,0x00050051,0x0000001f,0x000006c0,0x00000a73,0x00000002,0x0004007c, + 0x00000006,0x000006c1,0x000006c0,0x00050083,0x00000006,0x000006c4,0x000006c1,0x000006be, + 0x0006000c,0x00000006,0x000006c6,0x00000001,0x00000004,0x000006c4,0x000500ba,0x00000011, + 0x000006c7,0x000006c6,0x0000022f,0x000300f7,0x000006ce,0x00000000,0x000400fa,0x000006c7, + 0x000006c8,0x000006ce,0x000200f8,0x000006c8,0x0006000c,0x00000006,0x000006ca,0x00000001, + 0x00000006,0x000006c4,0x00050085,0x00000006,0x000006cb,0x00000233,0x000006ca,0x00050083, + 0x00000006,0x000006cd,0x000006c4,0x000006cb,0x000200f9,0x000006ce,0x000200f8,0x000006ce, + 0x000700f5,0x00000006,0x00000a77,0x000006c4,0x000006bb,0x000006cd,0x000006c8,0x00050081, + 0x00000006,0x000006d1,0x0000068e,0x00000102,0x0006000c,0x00000006,0x000006d3,0x00000001, + 0x00000004,0x00000a77,0x00050085,0x00000006,0x000006d4,0x000006d3,0x00000bf3,0x00050085, + 0x00000006,0x000006d6,0x000006d4,0x000006d1,0x0006000c,0x00000006,0x000006d7,0x00000001, + 0x00000001,0x000006d6,0x00050081,0x00000006,0x000006d9,0x0000068e,0x00000bf4,0x0008000c, + 0x00000006,0x000006da,0x00000001,0x0000002b,0x000006d7,0x00000060,0x000006d9,0x00050083, + 0x00000006,0x000006dd,0x000006d1,0x000006da,0x000500bc,0x00000011,0x000006e0,0x0000068b, + 0x000006dd,0x000300f7,0x000006fd,0x00000000,0x000400fa,0x000006e0,0x000006e1,0x000006f0, + 0x000200f8,0x000006f0,0x00050081,0x00000006,0x000006f3,0x000006dd,0x00000060,0x000500b4, + 0x00000011,0x000006f4,0x0000068b,0x000006f3,0x000300f7,0x000006fc,0x00000000,0x000400fa, + 0x000006f4,0x000006f5,0x000006f6,0x000200f8,0x000006f6,0x00050081,0x00000006,0x000006f8, + 0x000006dd,0x00000268,0x00050083,0x00000006,0x000006fa,0x0000068b,0x000006f8,0x000200f9, + 0x000006fc,0x000200f8,0x000006f5,0x000200f9,0x000006fc,0x000200f8,0x000006fc,0x000700f5, + 0x00000006,0x00000a85,0x00000061,0x000006f5,0x000006fa,0x000006f6,0x000600a9,0x00000006, + 0x00000bf8,0x000006f4,0x00000061,0x00000a7f,0x000600a9,0x00000006,0x00000bf9,0x000006f4, + 0x00000061,0x000006da,0x000200f9,0x000006fd,0x000200f8,0x000006e1,0x0006000c,0x00000006, + 0x000006e3,0x00000001,0x00000006,0x00000a77,0x00050085,0x00000006,0x000006e4,0x0000022f, + 0x000006e3,0x00050083,0x00000006,0x000006e6,0x000006e4,0x00000a77,0x0004007f,0x00000006, + 0x000006e7,0x000006e6,0x000500b4,0x00000011,0x000006eb,0x0000068b,0x000006dd,0x000300f7, + 0x000006ef,0x00000000,0x000400fa,0x000006eb,0x000006ec,0x000006ef,0x000200f8,0x000006ec, + 0x0004007f,0x00000006,0x000006ee,0x00000a7f,0x000200f9,0x000006ef,0x000200f8,0x000006ef, + 0x000700f5,0x00000006,0x00000ac7,0x00000a7f,0x000006e1,0x000006ee,0x000006ec,0x000200f9, + 0x000006fd,0x000200f8,0x000006fd,0x000700f5,0x00000006,0x00000ac6,0x00000ac7,0x000006ef, + 0x00000bf8,0x000006fc,0x000700f5,0x00000006,0x00000a8d,0x000006e7,0x000006ef,0x00000a77, + 0x000006fc,0x000700f5,0x00000006,0x00000a86,0x000006dd,0x000006ef,0x00000bf9,0x000006fc, + 0x000700f5,0x00000006,0x00000a83,0x0000068b,0x000006ef,0x00000a85,0x000006fc,0x000500b4, + 0x00000011,0x00000700,0x00000a83,0x00000a86,0x000300f7,0x0000070b,0x00000000,0x000400fa, + 0x00000700,0x00000701,0x00000703,0x000200f8,0x00000703,0x00050088,0x00000006,0x00000708, + 0x00000a83,0x00000a86,0x00050085,0x00000006,0x00000709,0x00000a8d,0x00000708,0x00050081, + 0x00000006,0x0000070a,0x000006be,0x00000709,0x000200f9,0x0000070b,0x000200f8,0x00000701, + 0x000200f9,0x0000070b,0x000200f8,0x0000070b,0x000700f5,0x00000006,0x00000a91,0x000006c1, + 0x00000701,0x0000070a,0x00000703,0x000200f9,0x00000710,0x000200f8,0x00000710,0x000700f5, + 0x00000006,0x00000adc,0x000006be,0x0000070b,0x00000ad7,0x0000070c,0x000700f5,0x00000006, + 0x00000ad3,0x00000a8d,0x0000070b,0x00000ad7,0x0000070c,0x000700f5,0x00000006,0x00000ac4, + 0x00000ac6,0x0000070b,0x00000a7f,0x0000070c,0x000700f5,0x00000006,0x00000a90,0x00000a91, + 0x0000070b,0x0000070f,0x0000070c,0x0006000c,0x00000006,0x00000712,0x00000001,0x0000000d, + 0x00000a90,0x0006000c,0x00000006,0x00000714,0x00000001,0x0000000e,0x00000a90,0x0004007f, + 0x00000006,0x00000715,0x00000714,0x00050050,0x0000000c,0x00000716,0x00000712,0x00000715, + 0x0007004f,0x00000168,0x00000718,0x00000a6c,0x00000a6c,0x00000000,0x00000001,0x0004007c, + 0x0000000c,0x00000719,0x00000718,0x000500b7,0x00000011,0x0000071b,0x00000642,0x00000061, + 0x000300f7,0x00000724,0x00000000,0x000400fa,0x0000071b,0x0000071c,0x00000724,0x000200f8, + 0x0000071c,0x00050091,0x0000000c,0x00000720,0x000008c4,0x00000716,0x0006000c,0x00000006, + 0x00000721,0x00000001,0x00000042,0x00000720,0x00050088,0x00000006,0x00000722,0x00000060, + 0x00000721,0x0007000c,0x00000006,0x00000723,0x00000001,0x00000028,0x00000642,0x00000722, + 0x000200f9,0x00000724,0x000200f8,0x00000724,0x000700f5,0x00000006,0x00000ac2,0x00000642, + 0x00000710,0x00000723,0x0000071c,0x000500b7,0x00000011,0x00000726,0x0000063f,0x00000061, + 0x000300f7,0x0000089c,0x00000000,0x000400fa,0x00000726,0x00000727,0x0000083c,0x000200f8, + 0x0000083c,0x00070050,0x00000018,0x0000083e,0x00000abd,0x000003e2,0x00000061,0x00000061, + 0x000500b7,0x00000011,0x00000840,0x00000ac2,0x00000061,0x000300f7,0x00000883,0x00000000, + 0x000400fa,0x00000840,0x00000841,0x0000087a,0x000200f8,0x0000087a,0x0005008e,0x0000000c, + 0x0000087d,0x00000716,0x00000ac4,0x0006000c,0x0000001a,0x0000087f,0x00000001,0x00000022, + 0x000008c4,0x00050090,0x0000000c,0x00000880,0x0000087d,0x0000087f,0x0006000c,0x0000000c, + 0x00000881,0x00000001,0x00000006,0x00000880,0x0005008e,0x0000000c,0x00000882,0x00000881, + 0x000000bb,0x000200f9,0x00000883,0x000200f8,0x00000841,0x00060052,0x00000018,0x00000a30, + 0x00000102,0x0000083e,0x00000001,0x00060052,0x00000018,0x00000a32,0x000003e9,0x00000a30, + 0x00000002,0x00060052,0x00000018,0x00000a34,0x00000abd,0x00000a32,0x00000003,0x000300f7, + 0x00000872,0x00000000,0x000400fa,0x00000685,0x0000084c,0x00000872,0x000200f8,0x0000084c, + 0x000500b8,0x00000011,0x0000084e,0x00000ad3,0x00000061,0x000300f7,0x00000855,0x00000000, + 0x000400fa,0x0000084e,0x0000084f,0x00000855,0x000200f8,0x0000084f,0x00050081,0x00000006, + 0x00000852,0x00000adc,0x00000ad3,0x0004007f,0x00000006,0x00000854,0x00000ad3,0x000200f9, + 0x00000855,0x000200f8,0x00000855,0x000700f5,0x00000006,0x00000ae6,0x00000ad3,0x0000084c, + 0x00000854,0x0000084f,0x000700f5,0x00000006,0x00000ae5,0x00000adc,0x0000084c,0x00000852, + 0x0000084f,0x00050083,0x00000006,0x00000858,0x00000a90,0x00000ae5,0x00050081,0x00000006, + 0x0000085a,0x00000858,0x000000cd,0x0005008d,0x00000006,0x0000085b,0x0000085a,0x00000233, + 0x00050083,0x00000006,0x0000085c,0x0000085b,0x000000cd,0x0008000c,0x00000006,0x0000085f, + 0x00000001,0x0000002b,0x0000085c,0x00000061,0x00000ae6,0x00050085,0x00000006,0x00000862, + 0x00000ae6,0x000000bb,0x000500ba,0x00000011,0x00000863,0x0000085f,0x00000862,0x000300f7, + 0x00000868,0x00000000,0x000400fa,0x00000863,0x00000864,0x00000868,0x000200f8,0x00000864, + 0x00050083,0x00000006,0x00000867,0x00000ae6,0x0000085f,0x000200f9,0x00000868,0x000200f8, + 0x00000868,0x000700f5,0x00000006,0x00000ae7,0x0000085f,0x00000855,0x00000867,0x00000864, + 0x0006000c,0x00000006,0x0000086a,0x00000001,0x0000000d,0x00000ae7,0x0006000c,0x00000006, + 0x0000086c,0x00000001,0x0000000e,0x00000ae7,0x00050050,0x0000000c,0x0000086d,0x0000086a, + 0x0000086c,0x0006000c,0x00000006,0x0000092b,0x00000001,0x00000004,0x00000ac4,0x0005008e, + 0x0000000c,0x0000092c,0x0000086d,0x0000092b,0x00050083,0x0000000c,0x0000092e,0x00000bee, + 0x0000092c,0x0005008e,0x0000000c,0x0000092f,0x0000092e,0x000000bb,0x00050083,0x00000006, + 0x00000931,0x00000ae6,0x000000cd,0x0006000c,0x00000006,0x00000932,0x00000001,0x00000004, + 0x00000931,0x000500b8,0x00000011,0x00000933,0x00000932,0x000000d0,0x000300f7,0x00000954, + 0x00000000,0x000400fa,0x00000933,0x00000934,0x00000935,0x000200f8,0x00000935,0x0006000c, + 0x00000006,0x00000937,0x00000001,0x0000000f,0x00000ae6,0x00050083,0x00000006,0x00000939, + 0x000000cd,0x00000ae6,0x0006000c,0x00000006,0x0000093a,0x00000001,0x00000006,0x00000939, + 0x0006000c,0x00000006,0x0000093c,0x00000001,0x00000004,0x00000937,0x0007000c,0x00000006, + 0x0000093d,0x00000001,0x00000028,0x0000093c,0x000000df,0x00050088,0x00000006,0x0000093e, + 0x0000093a,0x0000093d,0x000500be,0x00000011,0x00000940,0x0000093e,0x00000061,0x000300f7, + 0x00000952,0x00000000,0x000400fa,0x00000940,0x00000941,0x0000094a,0x000200f8,0x0000094a, + 0x00050051,0x00000006,0x0000094c,0x0000092f,0x00000001,0x00050051,0x00000006,0x0000094e, + 0x0000092f,0x00000000,0x00050085,0x00000006,0x00000950,0x0000094e,0x00000937,0x00050081, + 0x00000006,0x00000951,0x0000094c,0x00000950,0x000200f9,0x00000952,0x000200f8,0x00000941, + 0x00050051,0x00000006,0x00000943,0x0000092f,0x00000001,0x00050051,0x00000006,0x00000945, + 0x0000092f,0x00000000,0x00050083,0x00000006,0x00000946,0x00000060,0x00000945,0x00050085, + 0x00000006,0x00000948,0x00000946,0x00000937,0x00050083,0x00000006,0x00000949,0x00000943, + 0x00000948,0x000200f9,0x00000952,0x000200f8,0x00000952,0x000700f5,0x00000006,0x00000aeb, + 0x00000949,0x00000941,0x00000951,0x0000094a,0x000200f9,0x00000954,0x000200f8,0x00000934, + 0x000200f9,0x00000954,0x000200f8,0x00000954,0x000700f5,0x00000006,0x00000b01,0x00000061, + 0x00000934,0x00000aeb,0x00000952,0x000700f5,0x00000006,0x00000aff,0x00000061,0x00000934, + 0x0000093e,0x00000952,0x00050051,0x00000006,0x00000956,0x0000092f,0x00000000,0x0007000c, + 0x00000006,0x00000957,0x00000001,0x00000028,0x00000956,0x00000061,0x00050081,0x00000006, + 0x00000958,0x00000957,0x000000fc,0x00050051,0x00000006,0x0000095b,0x0000092f,0x00000001, + 0x00050083,0x00000006,0x0000095d,0x00000102,0x0000095b,0x00070050,0x00000018,0x00000bf5, + 0x00000958,0x0000095d,0x00000aff,0x00000b01,0x000200f9,0x00000872,0x000200f8,0x00000872, + 0x000700f5,0x00000018,0x00000b11,0x00000a34,0x00000841,0x00000bf5,0x00000954,0x00050085, + 0x00000006,0x00000876,0x00000ac4,0x00000ac2,0x0005008e,0x0000000c,0x00000878,0x00000716, + 0x00000876,0x00050091,0x0000000c,0x00000879,0x000008c4,0x00000878,0x000200f9,0x00000883, + 0x000200f8,0x00000883,0x000700f5,0x0000000c,0x00000ba7,0x00000879,0x00000872,0x00000882, + 0x0000087a,0x000700f5,0x00000018,0x00000b10,0x00000b11,0x00000872,0x0000083e,0x0000087a, + 0x000500c7,0x0000001f,0x00000885,0x00000a6b,0x00000193,0x000500ab,0x00000011,0x00000886, + 0x00000885,0x0000006c,0x000500c7,0x0000001f,0x00000888,0x00000a6b,0x00000433,0x000500ab, + 0x00000011,0x00000889,0x00000888,0x0000006c,0x000500a5,0x00000011,0x0000088a,0x00000886, + 0x00000889,0x000300f7,0x0000088e,0x00000000,0x000400fa,0x0000088a,0x0000088b,0x0000088e, + 0x000200f8,0x0000088b,0x00050085,0x00000018,0x0000088d,0x00000b10,0x00000439,0x000200f9, + 0x0000088e,0x000200f8,0x0000088e,0x000700f5,0x00000018,0x00000bab,0x00000b10,0x00000883, + 0x0000088d,0x0000088b,0x000500aa,0x00000011,0x00000890,0x00000610,0x00000137,0x00050050, + 0x00000013,0x00000bfa,0x00000890,0x00000890,0x000600a9,0x0000000c,0x00000bfb,0x00000bfa, + 0x00000629,0x00000719,0x000500c7,0x0000001f,0x00000895,0x00000a6b,0x00000442,0x000500ab, + 0x00000011,0x00000896,0x00000895,0x0000006c,0x000500ab,0x00000011,0x00000898,0x00000610, + 0x00000093,0x000500a7,0x00000011,0x00000899,0x00000896,0x00000898,0x000300f7,0x0000089b, + 0x00000000,0x000400fa,0x00000899,0x0000089a,0x0000089b,0x000200f8,0x0000089a,0x000200f9, + 0x000008af,0x000200f8,0x0000089b,0x000200f9,0x0000089c,0x000200f8,0x00000727,0x0006000c, + 0x00000006,0x00000729,0x00000001,0x00000021,0x000008c4,0x0006000c,0x00000006,0x0000072a, + 0x00000001,0x00000006,0x00000729,0x00050085,0x00000006,0x0000072c,0x00000ac4,0x0000072a, + 0x000500c7,0x0000001f,0x0000072e,0x00000a6b,0x000002a2,0x000500ab,0x00000011,0x0000072f, + 0x0000072e,0x0000006c,0x000300f7,0x00000733,0x00000000,0x000400fa,0x0000072f,0x00000730, + 0x00000733,0x000200f8,0x00000730,0x0007000c,0x00000006,0x00000732,0x00000001,0x00000025, + 0x0000072c,0x00000061,0x000200f9,0x00000733,0x000200f8,0x00000733,0x000700f5,0x00000006, + 0x00000b15,0x0000072c,0x00000727,0x00000732,0x00000730,0x000500c7,0x0000001f,0x00000735, + 0x00000a6b,0x000002aa,0x000500ab,0x00000011,0x00000736,0x00000735,0x0000006c,0x000300f7, + 0x0000073a,0x00000000,0x000400fa,0x00000736,0x00000737,0x0000073a,0x000200f8,0x00000737, + 0x0007000c,0x00000006,0x00000739,0x00000001,0x00000028,0x00000b15,0x00000061,0x000200f9, + 0x0000073a,0x000200f8,0x0000073a,0x000700f5,0x00000006,0x00000b20,0x00000b15,0x00000733, + 0x00000739,0x00000737,0x000500b7,0x00000011,0x0000073c,0x00000ac2,0x00000061,0x000300f7, + 0x00000744,0x00000000,0x000400fa,0x0000073c,0x0000073d,0x0000073f,0x000200f8,0x0000073f, + 0x00050091,0x0000000c,0x000008ed,0x000008c4,0x00000716,0x00050051,0x00000006,0x000008ef, + 0x000008ed,0x00000000,0x0006000c,0x00000006,0x000008f0,0x00000001,0x00000004,0x000008ef, + 0x00050051,0x00000006,0x000008f2,0x000008ed,0x00000001,0x0006000c,0x00000006,0x000008f3, + 0x00000001,0x00000004,0x000008f2,0x00050081,0x00000006,0x000008f4,0x000008f0,0x000008f3, + 0x00050094,0x00000006,0x000008f7,0x000008ed,0x000008ed,0x00050088,0x00000006,0x000008f8, + 0x00000060,0x000008f7,0x00050085,0x00000006,0x000008f9,0x000008f4,0x000008f8,0x00050085, + 0x00000006,0x00000743,0x000008f9,0x000000bb,0x000200f9,0x00000744,0x000200f8,0x0000073d, + 0x000200f9,0x00000744,0x000200f8,0x00000744,0x000700f5,0x00000006,0x00000b18,0x00000ac2, + 0x0000073d,0x00000743,0x0000073f,0x000500ba,0x00000011,0x00000748,0x00000b18,0x0000063f, + 0x000500b4,0x00000011,0x0000074a,0x00000ac2,0x00000061,0x000500a7,0x00000011,0x0000074b, + 0x00000748,0x0000074a,0x000300f7,0x00000753,0x00000000,0x000400fa,0x0000074b,0x0000074c, + 0x00000753,0x000200f8,0x0000074c,0x00050088,0x00000006,0x00000751,0x0000063f,0x00000b18, + 0x000200f9,0x00000753,0x000200f8,0x00000753,0x000700f5,0x00000006,0x00000b71,0x00000060, + 0x00000744,0x00000751,0x0000074c,0x000600a9,0x00000006,0x00000bfc,0x0000074b,0x00000b18, + 0x0000063f,0x00050081,0x00000006,0x00000757,0x00000bfc,0x00000b18,0x0005008e,0x0000000c, + 0x00000758,0x00000716,0x00000757,0x00050085,0x00000006,0x0000075d,0x00000b20,0x00000757, + 0x00050088,0x00000006,0x00000760,0x000000bb,0x00000b18,0x0004007f,0x00000006,0x00000763, + 0x0000075d,0x00050050,0x0000000c,0x00000764,0x0000075d,0x00000763,0x00050050,0x0000000c, + 0x00000766,0x00000bfc,0x00000bfc,0x00050081,0x0000000c,0x00000767,0x00000764,0x00000766, + 0x0005008e,0x0000000c,0x00000768,0x00000767,0x00000760,0x00050081,0x0000000c,0x0000076a, + 0x00000768,0x00000bef,0x00050051,0x00000006,0x0000076c,0x0000076a,0x00000000,0x00050051, + 0x00000006,0x0000076e,0x0000076a,0x00000001,0x00070050,0x00000018,0x00000bf6,0x0000076c, + 0x0000076e,0x00000061,0x00000061,0x000500ac,0x00000011,0x00000777,0x00000681,0x000002f8, + 0x000300f7,0x0000081e,0x00000000,0x000400fa,0x00000777,0x00000778,0x0000081e,0x000200f8, + 0x00000778,0x000500c7,0x0000001f,0x0000077a,0x00000a6b,0x000002fe,0x000500aa,0x00000011, + 0x0000077b,0x0000077a,0x0000006c,0x000600a9,0x0000003a,0x00000bfd,0x0000077b,0x00000bf1, + 0x00000137,0x000500c7,0x0000001f,0x00000781,0x00000a6b,0x00000193,0x000500ab,0x00000011, + 0x00000782,0x00000781,0x0000006c,0x000300f7,0x00000786,0x00000000,0x000400fa,0x00000782, + 0x00000783,0x00000786,0x000200f8,0x00000783,0x0004007e,0x0000003a,0x00000785,0x00000bfd, + 0x000200f9,0x00000786,0x000200f8,0x00000786,0x000700f5,0x0000003a,0x00000b46,0x00000bfd, + 0x00000778,0x00000785,0x00000783,0x00050080,0x0000003a,0x00000789,0x00000a6e,0x00000b46, + 0x000500c7,0x0000003a,0x0000090b,0x00000789,0x0000010f,0x000500c3,0x0000003a,0x0000090d, + 0x00000789,0x00000112,0x00050050,0x0000003c,0x0000090e,0x0000090b,0x0000090d,0x0004003d, + 0x0000014d,0x0000078b,0x0000014f,0x0007005f,0x0000014a,0x0000078d,0x0000078b,0x0000090e, + 0x00000002,0x0000008f,0x00050051,0x0000001f,0x0000078f,0x0000078d,0x00000002,0x0004007c, + 0x00000006,0x00000790,0x0000078f,0x00050083,0x00000006,0x00000793,0x00000790,0x00000a90, + 0x0006000c,0x00000006,0x00000794,0x00000001,0x00000004,0x00000793,0x000500ba,0x00000011, + 0x00000796,0x00000794,0x0000022f,0x000300f7,0x0000079a,0x00000000,0x000400fa,0x00000796, + 0x00000797,0x0000079a,0x000200f8,0x00000797,0x00050083,0x00000006,0x00000799,0x00000233, + 0x00000794,0x000200f9,0x0000079a,0x000200f8,0x0000079a,0x000700f5,0x00000006,0x00000b4f, + 0x00000794,0x00000786,0x00000799,0x00000797,0x000500ab,0x00000011,0x0000079d,0x0000077a, + 0x0000006c,0x000500a4,0x00000011,0x000007a4,0x0000079d,0x0000072f,0x000600a9,0x00000006, + 0x000007a5,0x000007a4,0x00000332,0x000000bb,0x00050085,0x00000006,0x000007a6,0x00000b4f, + 0x000007a5,0x00050081,0x00000006,0x000007a8,0x000007a6,0x00000a90,0x0006000c,0x00000006, + 0x000007aa,0x00000001,0x0000000d,0x000007a8,0x0006000c,0x00000006,0x000007ac,0x00000001, + 0x0000000e,0x000007a8,0x0004007f,0x00000006,0x000007ad,0x000007ac,0x00050050,0x0000000c, + 0x000007ae,0x000007aa,0x000007ad,0x00050091,0x0000000c,0x00000914,0x000008c4,0x000007ae, + 0x00050051,0x00000006,0x00000916,0x00000914,0x00000000,0x0006000c,0x00000006,0x00000917, + 0x00000001,0x00000004,0x00000916,0x00050051,0x00000006,0x00000919,0x00000914,0x00000001, + 0x0006000c,0x00000006,0x0000091a,0x00000001,0x00000004,0x00000919,0x00050081,0x00000006, + 0x0000091b,0x00000917,0x0000091a,0x00050094,0x00000006,0x0000091e,0x00000914,0x00000914, + 0x00050088,0x00000006,0x0000091f,0x00000060,0x0000091e,0x00050085,0x00000006,0x00000920, + 0x0000091b,0x0000091f,0x00050085,0x00000006,0x000007b3,0x00000b4f,0x000000bb,0x0006000c, + 0x00000006,0x000007b4,0x00000001,0x0000000e,0x000007b3,0x000500aa,0x00000011,0x000007b6, + 0x00000681,0x00000349,0x000400a8,0x00000011,0x000007b7,0x000007b6,0x000300f7,0x000007be, + 0x00000000,0x000400fa,0x000007b7,0x000007b8,0x000007be,0x000200f8,0x000007b8,0x000500aa, + 0x00000011,0x000007ba,0x00000681,0x0000034f,0x000500be,0x00000011,0x000007bc,0x000007b4, + 0x000000fc,0x000500a7,0x00000011,0x000007bd,0x000007ba,0x000007bc,0x000200f9,0x000007be, + 0x000200f8,0x000007be,0x000700f5,0x00000011,0x000007bf,0x000007b6,0x0000079a,0x000007bd, + 0x000007b8,0x000300f7,0x000007d2,0x00000000,0x000400fa,0x000007bf,0x000007c0,0x000007cb, + 0x000200f8,0x000007cb,0x00050085,0x00000006,0x000007ce,0x00000bfc,0x000007b4,0x00050085, + 0x00000006,0x000007d0,0x00000920,0x000000bb,0x00050081,0x00000006,0x000007d1,0x000007ce, + 0x000007d0,0x000200f9,0x000007d2,0x000200f8,0x000007c0,0x000500c7,0x0000001f,0x000007c2, + 0x00000a6b,0x00000359,0x000500ab,0x00000011,0x000007c3,0x000007c2,0x0000006c,0x000600a9, + 0x00000006,0x000007c4,0x000007c3,0x00000060,0x000000fc,0x0007000c,0x00000006,0x000007c8, + 0x00000001,0x00000028,0x000007b4,0x000007c4,0x00050088,0x00000006,0x000007c9,0x00000060, + 0x000007c8,0x00050085,0x00000006,0x000007ca,0x00000bfc,0x000007c9,0x000200f9,0x000007d2, + 0x000200f8,0x000007d2,0x000700f5,0x00000006,0x00000b56,0x000007ca,0x000007c0,0x000007d1, + 0x000007cb,0x00050085,0x00000006,0x000007d5,0x00000920,0x000000bb,0x00050081,0x00000006, + 0x000007d6,0x00000b56,0x000007d5,0x000500c7,0x0000001f,0x000007d8,0x00000a6b,0x00000371, + 0x000500ab,0x00000011,0x000007d9,0x000007d8,0x0000006c,0x000300f7,0x00000807,0x00000000, + 0x000400fa,0x000007d9,0x000007da,0x00000807,0x000200f8,0x000007da,0x00050085,0x00000006, + 0x000007df,0x00000b18,0x0000037c,0x00050085,0x00000006,0x000007e3,0x000007d6,0x000007b4, + 0x00050081,0x00000006,0x000007e5,0x000007e3,0x000007df,0x000500bc,0x00000011,0x000007e6, + 0x00000757,0x000007e5,0x000300f7,0x00000806,0x00000000,0x000400fa,0x000007e6,0x000007e7, + 0x000007ef,0x000200f8,0x000007ef,0x0005008e,0x0000000c,0x000007f2,0x000007ae,0x000007d6, + 0x00050094,0x00000006,0x000007f5,0x00000758,0x00000758,0x00050094,0x00000006,0x000007f8, + 0x000007f2,0x000007f2,0x00050050,0x0000000c,0x000007f9,0x000007f5,0x000007f8,0x00050050, + 0x0000001a,0x00000803,0x00000758,0x000007f2,0x0006000c,0x0000001a,0x00000804,0x00000001, + 0x00000022,0x00000803,0x00050090,0x0000000c,0x00000805,0x000007f9,0x00000804,0x000200f9, + 0x00000806,0x000200f8,0x000007e7,0x00050088,0x00000006,0x000007ea,0x00000060,0x000007b4, + 0x00050085,0x00000006,0x000007eb,0x00000757,0x000007ea,0x0005008e,0x0000000c,0x000007ee, + 0x000007ae,0x000007eb,0x000200f9,0x00000806,0x000200f8,0x00000806,0x000700f5,0x0000000c, + 0x00000b66,0x000007ee,0x000007e7,0x00000805,0x000007ef,0x000200f9,0x00000807,0x000200f8, + 0x00000807,0x000700f5,0x0000000c,0x00000b65,0x00000758,0x000007d2,0x00000b66,0x00000806, + 0x0006000c,0x00000006,0x00000809,0x00000001,0x00000004,0x00000b20,0x0005008e,0x0000000c, + 0x0000080b,0x00000b65,0x00000809,0x00050094,0x00000006,0x0000080f,0x0000080b,0x000007ae, + 0x00050083,0x00000006,0x00000810,0x000007d6,0x0000080f,0x00050088,0x00000006,0x00000813, + 0x00000810,0x00000920,0x000300f7,0x0000081d,0x00000000,0x000400fa,0x0000072f,0x00000817, + 0x0000081a,0x000200f8,0x0000081a,0x00060052,0x00000018,0x00000a24,0x00000813,0x00000bf6, + 0x00000000,0x000200f9,0x0000081d,0x000200f8,0x00000817,0x00060052,0x00000018,0x00000a22, + 0x00000813,0x00000bf6,0x00000001,0x000200f9,0x0000081d,0x000200f8,0x0000081d,0x000700f5, + 0x00000018,0x00000b7b,0x00000a22,0x00000817,0x00000a24,0x0000081a,0x000200f9,0x0000081e, + 0x000200f8,0x0000081e,0x000700f5,0x0000000c,0x00000b8a,0x00000758,0x00000753,0x00000b65, + 0x0000081d,0x000700f5,0x00000018,0x00000b7a,0x00000bf6,0x00000753,0x00000b7b,0x0000081d, + 0x0007004f,0x0000000c,0x00000821,0x00000b7a,0x00000b7a,0x00000000,0x00000001,0x0005008e, + 0x0000000c,0x00000822,0x00000821,0x00000b71,0x00050051,0x00000006,0x00000824,0x00000822, + 0x00000000,0x00060052,0x00000018,0x00000a26,0x00000824,0x00000b7a,0x00000000,0x00050051, + 0x00000006,0x00000826,0x00000822,0x00000001,0x0007000c,0x00000006,0x00000829,0x00000001, + 0x00000028,0x00000826,0x000003ca,0x00060052,0x00000018,0x00000a2b,0x00000829,0x00000a26, + 0x00000001,0x000300f7,0x00000832,0x00000000,0x000400fa,0x0000073c,0x0000082d,0x00000832, + 0x000200f8,0x0000082d,0x00050083,0x00000006,0x00000830,0x00000102,0x00000824,0x00060052, + 0x00000018,0x00000a2e,0x00000830,0x00000a2b,0x00000000,0x000200f9,0x00000832,0x000200f8, + 0x00000832,0x000700f5,0x00000018,0x00000ba9,0x00000a2b,0x0000081e,0x00000a2e,0x0000082d, + 0x0005008e,0x0000000c,0x00000836,0x00000b8a,0x00000b20,0x00050091,0x0000000c,0x00000837, + 0x000008c4,0x00000836,0x000500ab,0x00000011,0x00000839,0x00000610,0x0000008f,0x000300f7, + 0x0000083b,0x00000000,0x000400fa,0x00000839,0x0000083a,0x0000083b,0x000200f8,0x0000083a, + 0x000200f9,0x000008af,0x000200f8,0x0000083b,0x000200f9,0x0000089c,0x000200f8,0x0000089c, + 0x000700f5,0x00000018,0x00000ba8,0x00000ba9,0x0000083b,0x00000bab,0x0000089b,0x000700f5, + 0x0000000c,0x00000ba4,0x00000837,0x0000083b,0x00000ba7,0x0000089b,0x000700f5,0x0000000c, + 0x00000b8c,0x00000719,0x0000083b,0x00000bfb,0x0000089b,0x00050091,0x0000000c,0x0000089f, + 0x000008c4,0x00000b8c,0x00050081,0x0000000c,0x000008a1,0x0000089f,0x00000ba4,0x00050081, + 0x0000000c,0x000008a3,0x000008a1,0x0000063c,0x0007004f,0x0000000c,0x000008a5,0x00000ba8, + 0x00000ba8,0x00000000,0x00000001,0x00050041,0x0000045a,0x000008a6,0x00000458,0x00000459, + 0x0004003d,0x0000001f,0x000008a7,0x000008a6,0x000500ab,0x00000011,0x000008a8,0x000008a7, + 0x0000006c,0x00050050,0x00000013,0x00000968,0x000008a8,0x000008a8,0x000600a9,0x0000000c, + 0x000008aa,0x00000968,0x00000454,0x000008a5,0x00050051,0x00000006,0x000008ac,0x000008aa, + 0x00000000,0x00060052,0x00000018,0x00000a44,0x000008ac,0x00000ba8,0x00000000,0x00050051, + 0x00000006,0x000008ae,0x000008aa,0x00000001,0x00060052,0x00000018,0x00000a46,0x000008ae, + 0x00000a44,0x00000001,0x000200f9,0x000008af,0x000200f8,0x000008af,0x000900f5,0x00000018, + 0x00000bd3,0x00000ba9,0x0000083a,0x00000bab,0x0000089a,0x00000a46,0x0000089c,0x000900f5, + 0x0000000c,0x00000bad,0x00000bbe,0x0000083a,0x00000bbe,0x0000089a,0x000008a3,0x0000089c, + 0x000900f5,0x00000011,0x00000bac,0x000003de,0x0000083a,0x000003de,0x0000089a,0x00000465, + 0x0000089c,0x0003003e,0x00000485,0x00000bd3,0x00060041,0x0000048e,0x0000048f,0x0000048c, + 0x0000008f,0x0000062c,0x0004003d,0x00000168,0x00000490,0x0000048f,0x00050041,0x0000045a, + 0x00000497,0x00000458,0x00000493,0x0004003d,0x0000001f,0x00000498,0x00000497,0x000500aa, + 0x00000011,0x0000096e,0x0000062c,0x0000006c,0x000300f7,0x00000977,0x00000000,0x000400fa, + 0x0000096e,0x0000096f,0x00000970,0x000200f8,0x00000970,0x00050080,0x0000001f,0x00000972, + 0x0000062c,0x00000073,0x00050084,0x0000001f,0x00000974,0x00000972,0x00000498,0x0006000c, + 0x0000000c,0x00000975,0x00000001,0x0000003e,0x00000974,0x00050051,0x00000006,0x00000976, + 0x00000975,0x00000000,0x000200f9,0x00000977,0x000200f8,0x0000096f,0x000200f9,0x00000977, + 0x000200f8,0x00000977,0x000700f5,0x00000006,0x00000bd4,0x00000061,0x0000096f,0x00000976, + 0x00000970,0x0003003e,0x00000492,0x00000bd4,0x00050051,0x0000001f,0x0000049b,0x00000490, + 0x00000000,0x000500c7,0x0000001f,0x0000049d,0x0000049b,0x0000049c,0x000500ab,0x00000011, + 0x0000049e,0x0000049d,0x0000006c,0x000300f7,0x000004a0,0x00000000,0x000400fa,0x0000049e, + 0x0000049f,0x000004a0,0x000200f8,0x0000049f,0x0004003d,0x00000006,0x000004a1,0x00000492, + 0x0004007f,0x00000006,0x000004a2,0x000004a1,0x0003003e,0x00000492,0x000004a2,0x000200f9, + 0x000004a0,0x000200f8,0x000004a0,0x000500c7,0x0000001f,0x000004a7,0x0000049b,0x000004a6, + 0x000300f7,0x000004aa,0x00000000,0x000400fa,0x000004a8,0x000004a9,0x000004aa,0x000200f8, + 0x000004a9,0x000500aa,0x00000011,0x000004ad,0x000004a7,0x0000006c,0x000300f7,0x000004b0, + 0x00000000,0x000400fa,0x000004ad,0x000004af,0x000004b3,0x000200f8,0x000004b3,0x000200f9, + 0x000004b0,0x000200f8,0x000004af,0x00050051,0x0000001f,0x000004b2,0x00000490,0x00000001, + 0x000200f9,0x000004b0,0x000200f8,0x000004b0,0x000700f5,0x0000001f,0x00000bd5,0x000004b2, + 0x000004af,0x0000049b,0x000004b3,0x000500c2,0x0000001f,0x000004b7,0x00000bd5,0x000001ea, + 0x000500aa,0x00000011,0x0000097f,0x000004b7,0x0000006c,0x000300f7,0x00000988,0x00000000, + 0x000400fa,0x0000097f,0x00000980,0x00000981,0x000200f8,0x00000981,0x00050080,0x0000001f, + 0x00000983,0x000004b7,0x00000073,0x00050084,0x0000001f,0x00000985,0x00000983,0x00000498, + 0x0006000c,0x0000000c,0x00000986,0x00000001,0x0000003e,0x00000985,0x00050051,0x00000006, + 0x00000987,0x00000986,0x00000000,0x000200f9,0x00000988,0x000200f8,0x00000980,0x000200f9, + 0x00000988,0x000200f8,0x00000988,0x000700f5,0x00000006,0x00000bd6,0x00000061,0x00000980, + 0x00000987,0x00000981,0x000300f7,0x000004c2,0x00000000,0x000400fa,0x000004ad,0x000004c1, + 0x000004c2,0x000200f8,0x000004c1,0x0004007f,0x00000006,0x000004c4,0x00000bd6,0x000200f9, + 0x000004c2,0x000200f8,0x000004c2,0x000700f5,0x00000006,0x00000bd7,0x00000bd6,0x00000988, + 0x000004c4,0x000004c1,0x00050041,0x00000491,0x000004c8,0x000004c6,0x0000006c,0x0003003e, + 0x000004c8,0x00000bd7,0x000200f9,0x000004aa,0x000200f8,0x000004aa,0x000300f7,0x000004cb, + 0x00000000,0x000400fa,0x000004c9,0x000004ca,0x000004cb,0x000200f8,0x000004ca,0x000500c2, + 0x0000001f,0x000004d0,0x0000049b,0x000004cf,0x000500c7,0x0000001f,0x000004d1,0x000004d0, + 0x000004a6,0x00040070,0x00000006,0x000004d2,0x000004d1,0x0003003e,0x000004cc,0x000004d2, + 0x000200f9,0x000004cb,0x000200f8,0x000004cb,0x000300f7,0x000004d7,0x00000000,0x000400fa, + 0x000004d5,0x000004d6,0x000004d7,0x000200f8,0x000004d6,0x00050080,0x0000001f,0x000004df, + 0x00000630,0x00000106,0x00060041,0x000004e1,0x000004e2,0x000004dc,0x0000008f,0x000004df, + 0x0004003d,0x00000018,0x000004e3,0x000004e2,0x00050051,0x00000006,0x00000991,0x000004e3, + 0x00000000,0x00050051,0x00000006,0x00000992,0x000004e3,0x00000001,0x00050051,0x00000006, + 0x00000993,0x000004e3,0x00000002,0x00050051,0x00000006,0x00000994,0x000004e3,0x00000003, + 0x00050050,0x0000000c,0x00000995,0x00000991,0x00000992,0x00050050,0x0000000c,0x00000996, + 0x00000993,0x00000994,0x00050050,0x0000001a,0x00000997,0x00000995,0x00000996,0x00050080, + 0x0000001f,0x000004e8,0x00000630,0x00000109,0x00060041,0x000004e1,0x000004e9,0x000004dc, + 0x0000008f,0x000004e8,0x0004003d,0x00000018,0x000004ea,0x000004e9,0x0007004f,0x0000000c, + 0x000004f0,0x000004ea,0x000004ea,0x00000000,0x00000001,0x000300f7,0x000009cd,0x00000000, + 0x000300fb,0x0000006c,0x0000099f,0x000200f8,0x0000099f,0x0006000c,0x0000000c,0x000009a2, + 0x00000001,0x00000004,0x00000995,0x0006000c,0x0000000c,0x000009a5,0x00000001,0x00000004, + 0x00000996,0x00050081,0x0000000c,0x000009a6,0x000009a2,0x000009a5,0x00050051,0x00000006, + 0x000009a8,0x000009a6,0x00000000,0x000500b7,0x00000011,0x000009a9,0x000009a8,0x00000061, + 0x000300f7,0x000009ae,0x00000000,0x000400fa,0x000009a9,0x000009aa,0x000009ae,0x000200f8, + 0x000009aa,0x00050051,0x00000006,0x000009ac,0x000009a6,0x00000001,0x000500b7,0x00000011, + 0x000009ad,0x000009ac,0x00000061,0x000200f9,0x000009ae,0x000200f8,0x000009ae,0x000700f5, + 0x00000011,0x000009af,0x000009a9,0x0000099f,0x000009ad,0x000009aa,0x000300f7,0x000009cc, + 0x00000000,0x000400fa,0x000009af,0x000009b0,0x000009c9,0x000200f8,0x000009c9,0x0009004f, + 0x00000018,0x000009cb,0x000004ea,0x00000bf7,0x00000000,0x00000001,0x00000000,0x00000001, + 0x000200f9,0x000009cd,0x000200f8,0x000009b0,0x00050088,0x0000000c,0x000009b3,0x00000bee, + 0x000009a6,0x00050091,0x0000000c,0x000009b6,0x00000997,0x00000bad,0x00050081,0x0000000c, + 0x000009b8,0x000009b6,0x000004f0,0x0004007f,0x0000000c,0x000009bb,0x000009b8,0x00050051, + 0x00000006,0x000009bc,0x000009b8,0x00000000,0x00050051,0x00000006,0x000009bd,0x000009b8, + 0x00000001,0x00050051,0x00000006,0x000009be,0x000009bb,0x00000000,0x00050051,0x00000006, + 0x000009bf,0x000009bb,0x00000001,0x00070050,0x00000018,0x000009c0,0x000009bc,0x000009bd, + 0x000009be,0x000009bf,0x0009004f,0x00000018,0x000009c2,0x000009b3,0x000009b3,0x00000000, + 0x00000001,0x00000000,0x00000001,0x00050085,0x00000018,0x000009c3,0x000009c0,0x000009c2, + 0x00050081,0x00000018,0x000009c6,0x000009c3,0x000009c2,0x00050081,0x00000018,0x000009c8, + 0x000009c6,0x00000bf2,0x000200f9,0x000009cd,0x000200f8,0x000009cc,0x000100ff,0x000200f8, + 0x000009cd,0x000700f5,0x00000018,0x00000bd8,0x000009c8,0x000009b0,0x000009cb,0x000009c9, + 0x0003003e,0x000004eb,0x00000bd8,0x000200f9,0x000004d7,0x000200f8,0x000004d7,0x000500aa, + 0x00000011,0x000004f5,0x000004a7,0x00000083,0x000300f7,0x000004f7,0x00000000,0x000400fa, + 0x000004f5,0x000004f6,0x0000050d,0x000200f8,0x0000050d,0x000500aa,0x00000011,0x0000050f, + 0x000004a7,0x0000006c,0x000500a7,0x00000011,0x00000510,0x000004a8,0x0000050f,0x000300f7, + 0x00000512,0x00000000,0x000400fa,0x00000510,0x00000511,0x0000051e,0x000200f8,0x0000051e, + 0x00060041,0x000004e1,0x00000523,0x000004dc,0x0000008f,0x00000630,0x0004003d,0x00000018, + 0x00000524,0x00000523,0x00050051,0x00000006,0x000009e6,0x00000524,0x00000000,0x00050051, + 0x00000006,0x000009e7,0x00000524,0x00000001,0x00050051,0x00000006,0x000009e8,0x00000524, + 0x00000002,0x00050051,0x00000006,0x000009e9,0x00000524,0x00000003,0x00050050,0x0000000c, + 0x000009ea,0x000009e6,0x000009e7,0x00050050,0x0000000c,0x000009eb,0x000009e8,0x000009e9, + 0x00050050,0x0000001a,0x000009ec,0x000009ea,0x000009eb,0x00060041,0x000004e1,0x0000052a, + 0x000004dc,0x0000008f,0x00000637,0x0004003d,0x00000018,0x0000052b,0x0000052a,0x00050091, + 0x0000000c,0x0000052f,0x000009ec,0x00000bad,0x0007004f,0x0000000c,0x00000531,0x0000052b, + 0x0000052b,0x00000000,0x00000001,0x00050081,0x0000000c,0x00000532,0x0000052f,0x00000531, + 0x000500aa,0x00000011,0x00000534,0x000004a7,0x00000106,0x000500aa,0x00000011,0x00000536, + 0x000004a7,0x00000109,0x000500a6,0x00000011,0x00000537,0x00000534,0x00000536,0x000300f7, + 0x00000539,0x00000000,0x000400fa,0x00000537,0x00000538,0x0000055e,0x000200f8,0x0000055e, + 0x00050051,0x0000001f,0x00000561,0x00000490,0x00000001,0x0004007c,0x00000006,0x00000562, + 0x00000561,0x00050051,0x00000006,0x00000565,0x0000052b,0x00000002,0x00050051,0x00000006, + 0x00000567,0x00000532,0x00000000,0x00050051,0x00000006,0x00000569,0x00000532,0x00000001, + 0x00050083,0x00000006,0x0000056c,0x00000102,0x00000565,0x00070050,0x00000018,0x0000056d, + 0x00000567,0x00000569,0x00000562,0x0000056c,0x0003003e,0x0000050b,0x0000056d,0x000200f9, + 0x00000539,0x000200f8,0x00000538,0x00050051,0x0000001f,0x0000053b,0x00000490,0x00000001, + 0x0004007c,0x00000006,0x0000053c,0x0000053b,0x0004007f,0x00000006,0x0000053d,0x0000053c, + 0x00050041,0x00000491,0x0000053e,0x0000050b,0x00000109,0x0003003e,0x0000053e,0x0000053d, + 0x00050051,0x00000006,0x00000541,0x0000052b,0x00000002,0x000500ba,0x00000011,0x00000544, + 0x00000541,0x00000543,0x000300f7,0x00000546,0x00000000,0x000400fa,0x00000544,0x00000545, + 0x00000548,0x000200f8,0x00000548,0x00050051,0x00000006,0x0000054a,0x0000052b,0x00000003, + 0x00050041,0x00000491,0x0000054b,0x0000050b,0x00000106,0x0003003e,0x0000054b,0x0000054a, + 0x000200f9,0x00000546,0x000200f8,0x00000545,0x00050041,0x00000491,0x00000547,0x0000050b, + 0x00000106,0x0003003e,0x00000547,0x00000268,0x000200f9,0x00000546,0x000200f8,0x00000546, + 0x000300f7,0x0000054f,0x00000000,0x000400fa,0x00000534,0x0000054e,0x00000554,0x000200f8, + 0x00000554,0x00050041,0x00000491,0x00000555,0x0000050b,0x00000106,0x0004003d,0x00000006, + 0x00000556,0x00000555,0x0004007f,0x00000006,0x00000557,0x00000556,0x0003003e,0x00000555, + 0x00000557,0x00050041,0x00000491,0x0000055a,0x0000050b,0x0000006c,0x00050051,0x00000006, + 0x0000055b,0x00000532,0x00000000,0x0003003e,0x0000055a,0x0000055b,0x00050041,0x00000491, + 0x0000055c,0x0000050b,0x00000083,0x00050051,0x00000006,0x0000055d,0x00000532,0x00000001, + 0x0003003e,0x0000055c,0x0000055d,0x000200f9,0x0000054f,0x000200f8,0x0000054e,0x00050041, + 0x00000491,0x00000550,0x0000050b,0x00000083,0x0003003e,0x00000550,0x00000061,0x00050051, + 0x00000006,0x00000552,0x00000532,0x00000000,0x00050041,0x00000491,0x00000553,0x0000050b, + 0x0000006c,0x0003003e,0x00000553,0x00000552,0x000200f9,0x0000054f,0x000200f8,0x0000054f, + 0x000200f9,0x00000539,0x000200f8,0x00000539,0x000200f9,0x00000512,0x000200f8,0x00000511, + 0x000500c2,0x0000001f,0x00000516,0x0000049b,0x000001ea,0x000500aa,0x00000011,0x000009d4, + 0x00000516,0x0000006c,0x000300f7,0x000009dd,0x00000000,0x000400fa,0x000009d4,0x000009d5, + 0x000009d6,0x000200f8,0x000009d6,0x00050080,0x0000001f,0x000009d8,0x00000516,0x00000073, + 0x00050084,0x0000001f,0x000009da,0x000009d8,0x00000498,0x0006000c,0x0000000c,0x000009db, + 0x00000001,0x0000003e,0x000009da,0x00050051,0x00000006,0x000009dc,0x000009db,0x00000000, + 0x000200f9,0x000009dd,0x000200f8,0x000009d5,0x000200f9,0x000009dd,0x000200f8,0x000009dd, + 0x000700f5,0x00000006,0x00000bd9,0x00000061,0x000009d5,0x000009dc,0x000009d6,0x00050041, + 0x00000491,0x0000051d,0x000004c6,0x00000083,0x0003003e,0x0000051d,0x00000bd9,0x000200f9, + 0x00000512,0x000200f8,0x00000512,0x000200f9,0x000004f7,0x000200f8,0x000004f6,0x00050051, + 0x0000001f,0x000004fa,0x00000490,0x00000001,0x0006000c,0x00000018,0x000004fb,0x00000001, + 0x00000040,0x000004fa,0x000300f7,0x000004fe,0x00000000,0x000400fa,0x000004fc,0x000004fd, + 0x000004fe,0x000200f8,0x000004fd,0x00050051,0x00000006,0x00000500,0x000004fb,0x00000003, + 0x0008004f,0x00000501,0x00000503,0x000004fb,0x000004fb,0x00000000,0x00000001,0x00000002, + 0x0005008e,0x00000501,0x00000504,0x00000503,0x00000500,0x00050051,0x00000006,0x00000506, + 0x00000504,0x00000000,0x00060052,0x00000018,0x00000a53,0x00000506,0x000004fb,0x00000000, + 0x00050051,0x00000006,0x00000508,0x00000504,0x00000001,0x00060052,0x00000018,0x00000a55, + 0x00000508,0x00000a53,0x00000001,0x00050051,0x00000006,0x0000050a,0x00000504,0x00000002, + 0x00060052,0x00000018,0x00000a57,0x0000050a,0x00000a55,0x00000002,0x000200f9,0x000004fe, + 0x000200f8,0x000004fe,0x000700f5,0x00000018,0x00000bda,0x000004fb,0x000004f6,0x00000a57, + 0x000004fd,0x0003003e,0x0000050b,0x00000bda,0x000200f9,0x000004f7,0x000200f8,0x000004f7, + 0x000300f7,0x00000571,0x00000000,0x000400fa,0x00000bac,0x00000570,0x0000057d,0x000200f8, + 0x0000057d,0x00050041,0x00000576,0x0000057f,0x00000458,0x0000057e,0x0004003d,0x00000006, + 0x00000580,0x0000057f,0x00070050,0x00000018,0x00000587,0x00000580,0x00000580,0x00000580, + 0x00000580,0x000200f9,0x00000571,0x000200f8,0x00000570,0x00050041,0x00000576,0x00000577, + 0x00000458,0x00000137,0x0004003d,0x00000006,0x00000578,0x00000577,0x00050041,0x00000576, + 0x0000057a,0x00000458,0x0000013d,0x0004003d,0x00000006,0x0000057b,0x0000057a,0x00050051, + 0x00000006,0x000009f0,0x00000bad,0x00000000,0x00050085,0x00000006,0x000009f2,0x000009f0, + 0x00000578,0x00050083,0x00000006,0x000009f3,0x000009f2,0x00000060,0x00050051,0x00000006, + 0x000009f5,0x00000bad,0x00000001,0x00050085,0x00000006,0x000009f7,0x000009f5,0x0000057b, + 0x0006000c,0x00000006,0x000009f9,0x00000001,0x00000006,0x0000057b,0x00050083,0x00000006, + 0x000009fa,0x000009f7,0x000009f9,0x00070050,0x00000018,0x000009fb,0x000009f3,0x000009fa, + 0x00000061,0x00000060,0x000200f9,0x00000571,0x000200f8,0x00000571,0x000700f5,0x00000018, + 0x00000bec,0x000009fb,0x00000570,0x00000587,0x0000057d,0x00050041,0x00000484,0x0000058d, + 0x0000058b,0x0000008f,0x0003003e,0x0000058d,0x00000bec,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/draw_path.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..b87874d8daf6ad901ec3d5218b8e7f5fc1fc110b GIT binary patch literal 21276 zcmZwP3Amj_kp|!s5<(zoBBBT)CWwf_L}Uvf`yPx02}{5w_mbR%;3b44tU9tp5J8ZL ziUNu&AcFXaBR(pKh|1!I3!6H)f`TKCiY%g;?>)Ec=9gz0J6-ivbyaos^7r}gIgVZ9 zWoz|%V|o*N6MFxe*z1?)_0|Z|3pT#r?mu((%xTM(&!4v4_FGeUZf|T~kItmt-6@YId{)P z_L{rwn8Eo&OXn_Ie*DtGg+p_XK5@ZAPeB%7B!kW=Y*rQ`yGjY#K%zN$K>!Ig{e%*pzGB&PH^F4pN5!qm5 zbDG}r&<8d>bXV`B@H6)s>2r9Ty*@O1XyxFeSM$0aId3&DhlgYwrEi92cldtnJFJ!` z^}XX3uI9&w->0LWMbX>0!%ql**!0!FZ{_J{`ujL?(|5(T_4)!$@)I5(boBlzTL6C z^Fmu!<^!$NdU%gMZ9Ui*r)5`(>*~<^w;1h}*~uULj?gn2ZvPzF@Slc0py3aMKDqfr zcm4f5{HzwEy?0RaXAi!$Z)<$--JvtygNK%mq(cAk`46s;9lvameHC=AK5h;6@kNW5 z&t7y|yz4U}vmPVcdw9{3eHM-6a8zb(lASm_JSsCz=YfL$aOgL*99YFuJjt6>{=^!TGUrGq&$U|D{n_M98A9Xpt_1GYy86Dw?=4(1Gj z9nis?Be0nr%vl0ExPuud?9dM8Oo7emV9piTn>v`Y1vb#ZiHbk zKX;7tRZZ@BiQlsE&X`R?EBZTU@a7ortihXK{JX=On~{Ana{i1BZ{64VQ*&0lcoqA^ znMBSOTI^{?`PH$H?LW&S>i2Vg$+>=LG4adh#~En!Cr0UU{d3MZ6neLf%EtEZ2!%TX z%Ql*As(d*U*%%rB*#5nu`Z*)3A6mcK!_G|oRCewU-`&H`&dOVzqm{SfyLofAR^HH4 zW7oc68^1bl|S?Q93uB(E2F!oX5s&Ki1i7-6(|_8%$f6KCqFo zjr2vs5@z4FGglEi+F0z*;#ZGlY|ojjkfFP}_^$3791wlovAx+0Hu|s*eME;op$*7* z@9oeJH2V3;fbmR~x3uUNhBA*+Qa4CU&I>%*`uW%1hTFSnINsdRlYNu=%s{A?21Gat{+Kw9I1v4bCM82S80>nqk{(u!3d zc0K>guID>mzZ28afw7DCJn!c4l<>w}@m?Ih*E?gBzajjpRjc_Q_xaOTmHvHw{ocmK zKQO|N!^`m_;XUK<*2t^l{AZJ9>{0x-eg2M7{usgadVSs)KhftW_xt0o>GKmt`6oy8 zCzStx_4z&ea{jilKzhBemwd(uzkczvM)=9aA34IWQTz#ge#)r5w~xq2*XW($H@NZc z9bc7su%G`syuN(@y03di-#7jb_|2BjDBIgge74Y5xw+W?JB8P0AavEz-D^bmjIDCs zIu{NNPlvuWaaefyrnX5C_aQ#JRsOnFAGTCD-D;mr7jIo1k$%$5hjoQ_&wzTGWxKEKel1TyOYqNzogOfMUHnzAurw?rS#t!Iw|VsmmKfT z0<(AASL`Qy(tQNa&-rPM2c{q1eFR2+VWaiMuME$oJkiIyhrlW)7l(IOtU0|rJcGqw z8QvXn>-4ggd=6v#TWQ%bPi*7eLtv$QNBHvVuF>`TgYfy^sII$*vAc7~qp`bF;Q9Mm zTH}PViFb#nvHz;kH3xF)^BkYsWqpeMnebPq6_@onCeLEIp~I#=?i3X#+1}w7ELgC+ z7)}b!AH4GSj$rOn8%KU_XtEWln}l))5f6+^W#_!Ke30{t_xTRyoWCTrK4Vh5rFb?z z6di>w8~D1TY?LT34Nvc~riZ78ulvcEc;x5a+%M4P^5#68YCr!e^guARu*ZUVrmB^L z{|)x9RjXFjnems7PFI(&zecv=sZWfaReuZL>+NyNwC4Yb@H=F_|XEUpYo5;!)eDP5cafhh*fco%|C1?i<^&e!QiDc zzUi2U!X`9KyoIgPFmb=V*_s#({>}Ik|GJ@Jp8wxz*yM(}1Dw^c=Le(fUbAk_WPR5U zFNRm7ijmGcoBjr&~k_k!~M#pH;d`%1<5rG~k)92{Hjb2kQ~ zOEx$0c*egZ{n#Uu2X`{L=%4Gs$>oAC*wpYZO?3}3CfKIo!{#g=k*`QA2V|Q?Mh@FE zv*qsb^6>5>e32WMST+w$HY;|WgIk1#sY;;!oLK9x3`SnDZrSvVp<>-C7+kESH?8Rz zle~*@>tJ-^2+IMP0v{9=(2nMftSvnO~=?uXRl!Jny-CATU+jopUoJY`}>85+xyOgS)rAu z8U%-)|D*|;VX3t5fxkkI7zxpAJJRxwVp*{Lw&MA!LncxZcH-#T~Zgok&} zj3dK$&y3r%PUv;dj5{0FJu~hKMwhJ4j5nnpdt~y|Ju}`CoZLLuyv_{|clR%BFub{j zRSu30PnS#%PED)G0olCNlTzhCYkuh9$-dau%uwjvQwP)c>h!ga7KDeh`_{AyyYPjn zFm}+jJ{E;`&L}rF+sB57v(10?(^><34Tt7SO!V30_r$aczjPL-!uUno7uLy=(9=@u zygwmyckX_WywmB<-Q5lA&fSlK(Iu<7Tb_RGk=5K8N5!Evj(!|jQyYdiHvYs&=Bz#@ zGS3DwHp#m4VP4A4@zGt9%C;B1juH)M5Yye%|&cP+g=7~JQ^Z?$vo9pT~5 z2{D|WR!+4Q!{XR67W-H{6`!#Thc^~7{z~QyeQWraHW@!;wT90OP3|-6HEn&I6%6ik zYhmvUKRMMtxvJ@%9iA?kwK2K9OR_e|&PiQ2m~m(;C(jKn-tJjDDHzT_=B z>Qk|w7Yy#%xFkM9_Rh~g@LOA6F9=QNk&e!V;o&Qylcu*a|M<+PZ=JL63k@%w4}{i_ z&Y7*>2SdXLVx#(95*}Xnl@Enx3tn+w8d}b~&xp%{!Rr}uMQBAX$u3WY$qV`&!QF>G z8k!GzE4kL1AzvCl(Y;3vWlnH-1Wi9yL{$%#cSJNuynC!n&VdfZJ zdHGUkd8xDY%i*V`*7$#$*kRrAKh&`9_#X~Nm#oJBmGonutj2FGRUFzn=awb!@?m}H zC&tRbO`+wWyQgms4=^`B`Kc_sT*>Yr2PRa^f58d{%$=+-^v zZ{gV@W9yl;3R`54r~W;aEp6F)GBjJ>eO9bbhi8k-T(G4d8(kh=b8~j`I~ad-^ylL< z$xNEwlgX19$lZAhf2xDa3)^zQm$BD8{3f(HNYh^fHD|vKU`>)&><@*8oA1*z_K>}Y z^AEgo^=RmB-XEisB3ER8OofR9U3UJ2j$Ltk#wOvYBa-;N&rzMbTu zo68G=i&jL{W?W?EgRI7!Ez~2|-};yszQ#;8CUtD8F>B9ldv!wS z>Q{MRJD3>BY8|Z;+F3$o%L}ORW<{pvpSvgq|USX4L&(zaW+0{G;gW-*<`eBxSM>F-eRynWu{u-e6+YZ>X9~Q|kmG{uLteUD<_kn@^zUfV zt+lvSaQfupwQi?{_HLi7^j;krE*~|n*Mv8&k-UyPv$qLWe#mQ$Z5x`*-_zyp(9nw9 zk!_c{eX87PEAHu`*_)KgSNYy4IKQyc-MQ&n2jqqC(r{yEugY7b$#+(>-Ev(onAkVw8l%< zyo%3!c6oU99h0>shjiHK+FcdCWO7Yb<2*dHaVj;3M}(JGb4adl zxvKHLIheDStez*2Cr16r#3W|psq<57JkILpMdti@JwrUJDu&6CiG$2DgRI_XoE`ev?=#K`1|N>y(mS{5 z`5S+|FMW3~IK5A|eQ;iQ{mJZu3)3q00onPfFzWy<7xHvLXmRco`^H#0+8W1aBd25B z^!2ZITo;9&oDJn~V$M3>M|wKCaMkAndHP2%xc92=M>W0=L`NQcFQLZw!C-LXE9^tz z`SCZktJ;`99E>iRF<+KeF=nz$Q(?x8Hoof{5655Lcz2jOn_d~(`kk6;{tJIq!<`>= zYCUZg+Ik|daZL+tT)uZwV|aBixN(Vh+t7-5$+k{~i5Fe_X`9gEd3h>dgK5QHx>|E3 zt`{W7bc{zob}FXrLyO6GUn-^@g25}MokJ^PBAcEH6BD{(+9|Y{wn*i(Vk%v2#WW>y zI^xuiow^6^61sa2+$X%kKiRISyQlK6t-bj_nHO_o&(=BeSa`TnbN1)(;`E#$FWtX1 zU9!^sYe$#7&aA(MW{3R!S$p#QL}<#oa6l39PV(<*XJHZv6_7Iclv_Z`{h zLwu#9t@uueY#_G8Oke+cH}Fhk>{pDH*CT?F!Rs8J6U>~FRleRF+8TmYOar0iPv5%d z&I?Aj?p*U54=-#%Xg*bOIGYv*qf1tC91|MOPw5>S8t(fPwT_0v!4; zhc21DqF&q1v6F+Hnf&?=nt9nIYeO+FWT&LU%nQ2q^J$^&XWvz;^Z0GS;P$ipd-wd$ z_=fw=M}2p}-#E@}{k!kf&k6>w^WdD&ide{2q{764_D-FTvqSS^eUw~leUR@L8M*lB z>Ra#2-yPcfX*$M6e`223@b3HB=QOPQe)hS+=#tgD-}BSYyWe_WdqH>@-K6T@{%-l+ z;NojNPtAKv^rSIBEGelRpyy)`T6h``iPsJ$YSdvf6*23(W?6W!r!2XI`A;WVMH07!0nIj}5|C z&dE!6!=_7Cx*K(L$!kn64$TgEo#mT^=1Z;f<)xtqVvnqHG$pkDWQE<3nB`3_%l8+9 ziA65RYj1ujw0-WoqxJXc8-u~^`E3vFD!16<>}KN!5u*|j=nKG_4Q zFgZe3%nye4%=7)>!hREsUt_L(|1LC~e*KN&q0mR9l9}W29iLP7H?QB>xI2+{VNX+6B zYt8K=p$F2hy9OT(W~^j2jz5Jq4zjK-HqH0Cv9TbzrN=(s@<6xdLR-2+(KU`ArRv8{ zodIiyHXhFhcbAG`VsQP)D{qrR!^Kw5gUR9Lo2;2?rS$q1rgDA$MFFk!qZ_|#R*t>f4joW9&x5W-!ec9%VZrxF|m80{bD@U_ajk{~- zwD4jgW0TDLb@MPaG`XsXr*gPyWaRFg^$gf7JY1>qY@XQQWutUAZ@O&O+40I?_$^Y& zeILKdp+ z$FKP4ct3DilbO3ug%=B%_aj}|d%|y+e35x4KvwZz5nB9ooMUW#JUpDu!af-uzKdsI zTQ8puFD6wnPkY9O-wa$Cnco#0nd*+{?t4`*c;)Hp(6HgioKxOo9Fu(pSL;2-HKE~t zH^FDEscS=%DK*dgWX|9fQ|W%L>58#*_lquEA9!~j%*W%swflST#~Gizn=5(0G_AfP zbF+3oXV(Syop3r@I&xMzp8MAZ_Zt&BS~^1+6P?|%PRJ6(%mU9E!tlPx-8Swcnq@Di*vkR9|hy zaaCw>_+5y6Uz1kh({DpQlM3UrPiIWl$aTT=tyn)FTG5Z}`qUdz_0#fC2TxYH`9f&9 zsdZgCT6vbgpC*^|^b;$4^?kG(LzDYHTCJheGY{~J?cDH+*vQUEJu_7-+FC;^LhILE zLuUtrch}H4;cE?%*BW|PXfnlk`Q?MZE)TCYbWdADbo3XGdAK!kD3#A|gom+*uDQM~ zG#l)fTwC`2rj(pdy87CWemit~s^9p?leL1U&sNR3Ry=p5Rm9`>Hg~4N#DlK+_+e;s z^n=t|V|Ry!TVwUT!XJf(^Xs=ncz(;Kmfw5RmS4Xqx+fLJFS_RL!O&Z0Gx+_cbLm&% zf1T<#Mb0I1`^6pQH%(UawlcYaDTTeSVdlB8iyP*BKwE55a02qd{9f!U^?R8s!ponw z&c#oJrmw4*3jcHm7iT?ZuMDjZdFA5j&~T;R;eIAOd@z_;KG)>d5!p4VF!7+v*0rJ8 z5>wf_EWt#{|r^`Y4{Hu`Mx``xq(zjQvIdPge1+F9)xdRJ)q^SdR5e?`lu zT-&;*SNpd_=rZan;IsD(z`jB zzDi+VZy3FLw|Gl1HrddJPL1`}&|+7W?pS?(v{$|v85?ws1NQCE@Gf?Hc(~t+b@L?e zt72Ks?abNWGkw-Z<2hM^=lN&NNYM*QCY=1no=gx}QFt1O9R?I8e-&3EHAC~c_ zt$ve2*YoPCjKf-)9PH}old-j4T7@mL=cR6v%9ghFKW-MBtmfmPj0vU` z_He_xbNTy*bsiMo(45UTb=rVEWLhTyGazuARk&?a(mi+LbN;(}U3^lmDI4D)LXZW9nN{ zZgTX7$L!rgn&FRAM;#Ep-QN!4(&t=2<1z@B0(Q%>mr_UE1 z>vdvUGV4|RVikAA`r6RXj&+w{@Op;t8XC4|#^<@bTWEIWiVr-Uih0k_HMV-UyiYK= z-?z%;erXlCB-=OjfK>5m%hrLR*|N^c|Lel@Z~pkl(=$eP*-yjeUu#T@ zUoWi~oKTB*O~jS@UU*>lMnXTE_)}3X3yU+%ibx$;H7g~)A4)k(s^4jc;)NQS! zOE5Tl^^Evyc=$l{s_*0B^_BnX`$RA}Kh|3wy}hTx(?P?_=F`FHlUEM@5t=Wu!RQa9 nc5@&XHD7;>Z~F2gca`sVCNCF+KR?xHA#;eQ|Ib9SW9t6_hVA)F literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.h new file mode 100644 index 000000000..afe3c5286 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.h @@ -0,0 +1,64 @@ +#pragma once + +const uint32_t init_clockwise_atomic_workaround_fixedcolor_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x00000068,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000033, + 0x00000045,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c, + 0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63, + 0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005, + 0x00000033,0x00003065,0x00040005,0x00000036,0x30653742,0x00000000,0x00040005,0x0000003f, + 0x61726170,0x0000006d,0x00040005,0x00000041,0x61726170,0x0000006d,0x00040005,0x00000042, + 0x61726170,0x0000006d,0x00040005,0x00000043,0x61726170,0x0000006d,0x00030005,0x00000045, + 0x0000316d,0x00040005,0x00000046,0x61726170,0x0000006d,0x00030047,0x00000033,0x00000000, + 0x00040047,0x00000033,0x0000001e,0x00000001,0x00030047,0x00000036,0x00000000,0x00040047, + 0x00000036,0x00000021,0x00000001,0x00040047,0x00000036,0x00000022,0x00000002,0x00040047, + 0x00000036,0x0000002b,0x00000001,0x00030047,0x00000037,0x00000000,0x00030047,0x0000003c, + 0x00000000,0x00030047,0x0000003f,0x00000000,0x00030047,0x00000040,0x00000000,0x00030047, + 0x00000041,0x00000000,0x00030047,0x00000042,0x00000000,0x00030047,0x00000043,0x00000000, + 0x00030047,0x00000045,0x00000000,0x00040047,0x00000045,0x0000001e,0x00000000,0x00030047, + 0x00000046,0x00000000,0x00030047,0x00000050,0x00000000,0x00030047,0x00000051,0x00000000, + 0x00030047,0x00000053,0x00000000,0x00030047,0x00000055,0x00000000,0x00030047,0x00000057, + 0x00000000,0x00030047,0x00000059,0x00000000,0x00030047,0x0000005b,0x00000000,0x00030047, + 0x0000005c,0x00000000,0x00030047,0x0000005d,0x00000000,0x00030047,0x0000005f,0x00000000, + 0x00030047,0x00000061,0x00000000,0x00030047,0x00000063,0x00000000,0x00030047,0x00000065, + 0x00000000,0x00030047,0x00000067,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040020,0x00000007,0x00000007,0x00000006, + 0x00040017,0x00000008,0x00000006,0x00000004,0x00040020,0x00000014,0x00000007,0x00000008, + 0x00040015,0x00000017,0x00000020,0x00000000,0x0004002b,0x00000017,0x00000018,0x00000000, + 0x0004002b,0x00000017,0x0000001b,0x00000001,0x0004002b,0x00000017,0x0000001e,0x00000002, + 0x0004002b,0x00000017,0x00000021,0x00000003,0x00040020,0x00000032,0x00000003,0x00000008, + 0x0004003b,0x00000032,0x00000033,0x00000003,0x00090019,0x00000034,0x00000006,0x00000006, + 0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00040020,0x00000035,0x00000000, + 0x00000034,0x0004003b,0x00000035,0x00000036,0x00000000,0x00040015,0x00000038,0x00000020, + 0x00000001,0x0004002b,0x00000038,0x00000039,0x00000000,0x00040017,0x0000003a,0x00000038, + 0x00000002,0x0005002c,0x0000003a,0x0000003b,0x00000039,0x00000039,0x0004002b,0x00000006, + 0x0000003d,0x00000000,0x0004002b,0x00000006,0x0000003e,0x3f800000,0x0004003b,0x00000032, + 0x00000045,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003b,0x00000014,0x0000005c,0x00000007,0x0004003b,0x00000014,0x0000005d, + 0x00000007,0x0004003b,0x00000014,0x00000050,0x00000007,0x0004003b,0x00000014,0x00000051, + 0x00000007,0x0004003b,0x00000007,0x0000003f,0x00000007,0x0004003b,0x00000007,0x00000041, + 0x00000007,0x0004003b,0x00000007,0x00000042,0x00000007,0x0004003b,0x00000007,0x00000043, + 0x00000007,0x0004003b,0x00000007,0x00000046,0x00000007,0x0004003d,0x00000034,0x00000037, + 0x00000036,0x00050062,0x00000008,0x0000003c,0x00000037,0x0000003b,0x00050051,0x00000006, + 0x00000040,0x0000003c,0x00000000,0x0003003e,0x0000003f,0x00000040,0x0003003e,0x00000041, + 0x0000003d,0x0003003e,0x00000042,0x0000003d,0x0003003e,0x00000043,0x0000003e,0x0004003d, + 0x00000006,0x00000053,0x0000003f,0x00050041,0x00000007,0x00000054,0x00000050,0x00000018, + 0x0003003e,0x00000054,0x00000053,0x0004003d,0x00000006,0x00000055,0x00000041,0x00050041, + 0x00000007,0x00000056,0x00000050,0x0000001b,0x0003003e,0x00000056,0x00000055,0x0004003d, + 0x00000006,0x00000057,0x00000042,0x00050041,0x00000007,0x00000058,0x00000050,0x0000001e, + 0x0003003e,0x00000058,0x00000057,0x0004003d,0x00000006,0x00000059,0x00000043,0x00050041, + 0x00000007,0x0000005a,0x00000050,0x00000021,0x0003003e,0x0000005a,0x00000059,0x0004003d, + 0x00000008,0x0000005b,0x00000050,0x0003003e,0x00000051,0x0000005b,0x0004003d,0x00000008, + 0x00000044,0x00000051,0x0003003e,0x00000033,0x00000044,0x0003003e,0x00000046,0x0000003d, + 0x0004003d,0x00000006,0x0000005f,0x00000046,0x00050041,0x00000007,0x00000060,0x0000005c, + 0x00000018,0x0003003e,0x00000060,0x0000005f,0x0004003d,0x00000006,0x00000061,0x00000046, + 0x00050041,0x00000007,0x00000062,0x0000005c,0x0000001b,0x0003003e,0x00000062,0x00000061, + 0x0004003d,0x00000006,0x00000063,0x00000046,0x00050041,0x00000007,0x00000064,0x0000005c, + 0x0000001e,0x0003003e,0x00000064,0x00000063,0x0004003d,0x00000006,0x00000065,0x00000046, + 0x00050041,0x00000007,0x00000066,0x0000005c,0x00000021,0x0003003e,0x00000066,0x00000065, + 0x0004003d,0x00000008,0x00000067,0x0000005c,0x0003003e,0x0000005d,0x00000067,0x0004003d, + 0x00000008,0x00000047,0x0000005d,0x0003003e,0x00000045,0x00000047,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..53ea720d793a627555903e9965b34fe86690078a GIT binary patch literal 1920 zcmZ9M+fP$L5XKkULY2fzyr3~LR9{Rm#0xh?E-k`&X@ZD%G{@8SwA2)6+G66Hf1rPm zFD8D!J!f$3Cc}Q;%-7l3IkOZd?@v27;bvUf9l2~>b(8Wq$NoV3jGOX2svp!BhNITP z;?g6Omt29($1b~RR}{vMlkN%rr?MT{73uKnAfbY?I`>Nl6x~G^)#K{xT0A^TTInDj zj!p+jCyg6t?Y8J?<6GJsnJ(Jfi|RXZv)`BQM=yHxep7>U07hg zA&c|C)XE~py;$H^8T5ERzy|?-8{qc={utoH0DlhfmjK5BP6FHvutvf!YU||qnmR}C zD)KSC;G05I+UL9#{hTtZ_-1wIa*mmuIq~b-iQ~T^KI{GZqcxxNTNyp)cf==xI6dTS z(^rJ4hx|`+O#Zc;Gb6-ry9;hnJGEiqA|Hz!OBwW9a=>k_sCm`v{?!D3mj8x3KNrSF z&WCy(@HH74jJi30UB)uL;n~kktDAYD?q%g57d>R*`z=pNJ6d|mx2CVg`Q9OCzCzB7 z8E0q4LtY)@wK2Xu#&>hRu6pP(Z;75YR3+bn_k@o=?90dfw`BItHgqd$zz61h`UB={ z!<IENg(4}MowPU?Rn48Rwh+gD`q#5Ir1? z>3NIPX!=jW=qobxa5U)Y%b|=oF}?}hVlRd95o3noV0ukI>`dM>K0EWPF!NwNfTJ;e zA{^=);^?gha5ScG3WxfZIC|>=9F6Ju-x2ED;^?gha5U)YK}SZMyD_(Li$%iti18la KfArsARrVLD--p=% literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.h new file mode 100644 index 000000000..f93f8172c --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.h @@ -0,0 +1,56 @@ +#pragma once + +const uint32_t init_clockwise_atomic_workaround_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000004d,0x00000000,0x00020011,0x00000001,0x00020011, + 0x00000028,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e, + 0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000023, + 0x00000035,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004, + 0x415f4c47,0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f, + 0x00746365,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c, + 0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63, + 0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005, + 0x00000023,0x00003065,0x00040005,0x00000026,0x30653742,0x00000000,0x00040005,0x0000002f, + 0x61726170,0x0000006d,0x00040005,0x00000031,0x61726170,0x0000006d,0x00040005,0x00000032, + 0x61726170,0x0000006d,0x00040005,0x00000033,0x61726170,0x0000006d,0x00030005,0x00000035, + 0x0000306a,0x00040005,0x00000036,0x306a3742,0x00000000,0x00030047,0x00000023,0x00000000, + 0x00040047,0x00000023,0x0000001e,0x00000001,0x00030047,0x00000026,0x00000000,0x00040047, + 0x00000026,0x00000021,0x00000001,0x00040047,0x00000026,0x00000022,0x00000002,0x00040047, + 0x00000026,0x0000002b,0x00000001,0x00030047,0x00000027,0x00000000,0x00030047,0x0000002c, + 0x00000000,0x00030047,0x0000002f,0x00000000,0x00030047,0x00000030,0x00000000,0x00030047, + 0x00000031,0x00000000,0x00030047,0x00000032,0x00000000,0x00030047,0x00000033,0x00000000, + 0x00030047,0x00000035,0x00000000,0x00040047,0x00000035,0x0000001e,0x00000000,0x00030047, + 0x00000036,0x00000000,0x00040047,0x00000036,0x00000021,0x00000000,0x00040047,0x00000036, + 0x00000022,0x00000002,0x00040047,0x00000036,0x0000002b,0x00000000,0x00030047,0x00000037, + 0x00000000,0x00030047,0x00000038,0x00000000,0x00030047,0x00000041,0x00000000,0x00030047, + 0x00000042,0x00000000,0x00030047,0x00000044,0x00000000,0x00030047,0x00000046,0x00000000, + 0x00030047,0x00000048,0x00000000,0x00030047,0x0000004a,0x00000000,0x00030047,0x0000004c, + 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, + 0x00000020,0x00040020,0x00000007,0x00000007,0x00000006,0x00040017,0x00000008,0x00000006, + 0x00000004,0x00040020,0x00000010,0x00000007,0x00000008,0x00040015,0x00000013,0x00000020, + 0x00000000,0x0004002b,0x00000013,0x00000014,0x00000000,0x0004002b,0x00000013,0x00000017, + 0x00000001,0x0004002b,0x00000013,0x0000001a,0x00000002,0x0004002b,0x00000013,0x0000001d, + 0x00000003,0x00040020,0x00000022,0x00000003,0x00000008,0x0004003b,0x00000022,0x00000023, + 0x00000003,0x00090019,0x00000024,0x00000006,0x00000006,0x00000000,0x00000000,0x00000000, + 0x00000002,0x00000000,0x00040020,0x00000025,0x00000000,0x00000024,0x0004003b,0x00000025, + 0x00000026,0x00000000,0x00040015,0x00000028,0x00000020,0x00000001,0x0004002b,0x00000028, + 0x00000029,0x00000000,0x00040017,0x0000002a,0x00000028,0x00000002,0x0005002c,0x0000002a, + 0x0000002b,0x00000029,0x00000029,0x0004002b,0x00000006,0x0000002d,0x00000000,0x0004002b, + 0x00000006,0x0000002e,0x3f800000,0x0004003b,0x00000022,0x00000035,0x00000003,0x0004003b, + 0x00000025,0x00000036,0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003b,0x00000010,0x00000041,0x00000007,0x0004003b,0x00000010, + 0x00000042,0x00000007,0x0004003b,0x00000007,0x0000002f,0x00000007,0x0004003b,0x00000007, + 0x00000031,0x00000007,0x0004003b,0x00000007,0x00000032,0x00000007,0x0004003b,0x00000007, + 0x00000033,0x00000007,0x0004003d,0x00000024,0x00000027,0x00000026,0x00050062,0x00000008, + 0x0000002c,0x00000027,0x0000002b,0x00050051,0x00000006,0x00000030,0x0000002c,0x00000000, + 0x0003003e,0x0000002f,0x00000030,0x0003003e,0x00000031,0x0000002d,0x0003003e,0x00000032, + 0x0000002d,0x0003003e,0x00000033,0x0000002e,0x0004003d,0x00000006,0x00000044,0x0000002f, + 0x00050041,0x00000007,0x00000045,0x00000041,0x00000014,0x0003003e,0x00000045,0x00000044, + 0x0004003d,0x00000006,0x00000046,0x00000031,0x00050041,0x00000007,0x00000047,0x00000041, + 0x00000017,0x0003003e,0x00000047,0x00000046,0x0004003d,0x00000006,0x00000048,0x00000032, + 0x00050041,0x00000007,0x00000049,0x00000041,0x0000001a,0x0003003e,0x00000049,0x00000048, + 0x0004003d,0x00000006,0x0000004a,0x00000033,0x00050041,0x00000007,0x0000004b,0x00000041, + 0x0000001d,0x0003003e,0x0000004b,0x0000004a,0x0004003d,0x00000008,0x0000004c,0x00000041, + 0x0003003e,0x00000042,0x0000004c,0x0004003d,0x00000008,0x00000034,0x00000042,0x0003003e, + 0x00000023,0x00000034,0x0004003d,0x00000024,0x00000037,0x00000036,0x00050062,0x00000008, + 0x00000038,0x00000037,0x0000002b,0x0003003e,0x00000035,0x00000038,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/init_clockwise_atomic_workaround.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..ff0e53c65d140b575d611d987387cec3ea3b327b GIT binary patch literal 1664 zcmZ9LZBJ7{5QPWYLX|`@s6-PDFA6AF-++=BHEn>4T0?{%aMPEImXy-8#l&y^K!1>5 zOgzutU0j)DyXVZD&dlzeEle&?n@!k^mF=_TcFQK^F=JoTK4VjkCynDqWi;+oHn(1& zykP}47rSZGRupEPHM@QM%UWAnv(n*LA)$h@n*CCNqFuM7k=Bmt>F8UtlMU0+_ znx(CalM~VN)@jxr2VHV_m^Aj%_Fy30k6xDcy8SHebcfP(zh~qtlh5nA{dVu76AMaG z#Ql}j3q58!4Y3vBdKH%Q=h_F&Ve`!Mmsj|!EBy6;yx`7$>T_=^REAePD_2X;C2f@W%)@Jf72SabJt7$;5*1 z3QcKWaI5HMlljCqud|drW?mM=XSEZ@e@A@I`Sl}P_xyHFFZsOqL=?X-Ozoh5AWT2x zU-FpzZ#-uPkORF%8tjo{;)U*zL_ypQm9-lG>X2hs zi~rS>llprOn=vE&7mgIeM?hs~HV^25;tJ@0}ZgZ`7l zX3QXZI2!ca3vY*SL5yzz53x;Qe8iYhI5F;*H_i7B_shG+$Ni#bHt_w?%h=KS3nl7q AL;wH) literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.h new file mode 100644 index 000000000..0b09c441b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.h @@ -0,0 +1,523 @@ +#pragma once + +const uint32_t render_atlas_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000a18,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000041a,0x0000041d,0x00000420, + 0x00000421,0x00000425,0x00000463,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x000000fe,0x00004342,0x00030005,0x0000010f,0x0000664b,0x00040006, + 0x0000010f,0x00000000,0x00003464,0x00030005,0x00000111,0x00004358,0x00030005,0x00000124, + 0x0000664a,0x00040006,0x00000124,0x00000000,0x00003464,0x00030005,0x00000126,0x0000424c, + 0x00030005,0x00000406,0x0000424d,0x00040006,0x00000406,0x00000000,0x00006250,0x00040006, + 0x00000406,0x00000001,0x00006359,0x00040006,0x00000406,0x00000002,0x00006552,0x00040006, + 0x00000406,0x00000003,0x00006553,0x00040006,0x00000406,0x00000004,0x0000366d,0x00040006, + 0x00000406,0x00000005,0x0000676d,0x00040006,0x00000406,0x00000006,0x00006544,0x00040006, + 0x00000406,0x00000007,0x00006545,0x00040006,0x00000406,0x00000008,0x00003755,0x00040006, + 0x00000406,0x00000009,0x0000676a,0x00040006,0x00000406,0x0000000a,0x0000635a,0x00040006, + 0x00000406,0x0000000b,0x00003157,0x00040006,0x00000406,0x0000000c,0x0000676e,0x00040006, + 0x00000406,0x0000000d,0x00003559,0x00040006,0x00000406,0x0000000e,0x0000324f,0x00040006, + 0x00000406,0x0000000f,0x00006461,0x00040006,0x00000406,0x00000010,0x00006579,0x00040006, + 0x00000406,0x00000011,0x00003376,0x00040006,0x00000406,0x00000012,0x00003377,0x00040006, + 0x00000406,0x00000013,0x00006462,0x00040006,0x00000406,0x00000014,0x00006767,0x00030005, + 0x00000408,0x0000006b,0x00060005,0x0000041a,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00070005,0x0000041d,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005, + 0x00000420,0x00004254,0x00030005,0x00000421,0x00004255,0x00030005,0x00000425,0x00000049, + 0x00060005,0x00000461,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000461, + 0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000461,0x00000001,0x505f6c67, + 0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000461,0x00000002,0x435f6c67,0x4470696c, + 0x61747369,0x0065636e,0x00070006,0x00000461,0x00000003,0x435f6c67,0x446c6c75,0x61747369, + 0x0065636e,0x00030005,0x00000463,0x00000000,0x00030005,0x00000468,0x00004351,0x00030005, + 0x0000046a,0x00006576,0x00040006,0x0000046a,0x00000000,0x00003464,0x00030005,0x0000046c, + 0x00004355,0x00030005,0x0000046e,0x00006577,0x00040006,0x0000046e,0x00000000,0x00003464, + 0x00030005,0x00000470,0x0000424f,0x00030005,0x00000473,0x00003954,0x00040047,0x000000fe, + 0x00000021,0x00000008,0x00040047,0x000000fe,0x00000022,0x00000000,0x00040047,0x0000010e, + 0x00000006,0x00000010,0x00030047,0x0000010f,0x00000003,0x00040048,0x0000010f,0x00000000, + 0x00000018,0x00050048,0x0000010f,0x00000000,0x00000023,0x00000000,0x00030047,0x00000111, + 0x00000018,0x00040047,0x00000111,0x00000021,0x00000006,0x00040047,0x00000111,0x00000022, + 0x00000000,0x00040047,0x00000123,0x00000006,0x00000010,0x00030047,0x00000124,0x00000003, + 0x00040048,0x00000124,0x00000000,0x00000018,0x00050048,0x00000124,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000126,0x00000018,0x00040047,0x00000126,0x00000021,0x00000003, + 0x00040047,0x00000126,0x00000022,0x00000000,0x00030047,0x00000406,0x00000002,0x00050048, + 0x00000406,0x00000000,0x00000023,0x00000000,0x00050048,0x00000406,0x00000001,0x00000023, + 0x00000004,0x00050048,0x00000406,0x00000002,0x00000023,0x00000008,0x00050048,0x00000406, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x00000406,0x00000004,0x00000023,0x00000010, + 0x00050048,0x00000406,0x00000005,0x00000023,0x00000014,0x00050048,0x00000406,0x00000006, + 0x00000023,0x00000018,0x00050048,0x00000406,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x00000406,0x00000008,0x00000023,0x00000020,0x00050048,0x00000406,0x00000009,0x00000023, + 0x00000030,0x00050048,0x00000406,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000406, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x00000406,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x00000406,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000406,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x00000406,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x00000406,0x00000010,0x00000023,0x00000054,0x00050048,0x00000406,0x00000011,0x00000023, + 0x00000058,0x00050048,0x00000406,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000406, + 0x00000013,0x00000023,0x00000060,0x00050048,0x00000406,0x00000014,0x00000023,0x00000064, + 0x00040047,0x00000408,0x00000021,0x00000000,0x00040047,0x00000408,0x00000022,0x00000000, + 0x00040047,0x0000041a,0x0000000b,0x0000002a,0x00040047,0x0000041d,0x0000000b,0x0000002b, + 0x00040047,0x00000420,0x0000001e,0x00000000,0x00040047,0x00000421,0x0000001e,0x00000001, + 0x00040047,0x00000425,0x0000001e,0x00000000,0x00030047,0x00000461,0x00000002,0x00050048, + 0x00000461,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000461,0x00000001,0x0000000b, + 0x00000001,0x00050048,0x00000461,0x00000002,0x0000000b,0x00000003,0x00050048,0x00000461, + 0x00000003,0x0000000b,0x00000004,0x00030047,0x00000468,0x00000000,0x00040047,0x00000468, + 0x00000021,0x0000000a,0x00040047,0x00000468,0x00000022,0x00000000,0x00040047,0x00000469, + 0x00000006,0x00000008,0x00030047,0x0000046a,0x00000003,0x00040048,0x0000046a,0x00000000, + 0x00000018,0x00050048,0x0000046a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000046c, + 0x00000018,0x00040047,0x0000046c,0x00000021,0x00000004,0x00040047,0x0000046c,0x00000022, + 0x00000000,0x00040047,0x0000046d,0x00000006,0x00000010,0x00030047,0x0000046e,0x00000003, + 0x00040048,0x0000046e,0x00000000,0x00000018,0x00050048,0x0000046e,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000470,0x00000018,0x00040047,0x00000470,0x00000021,0x00000005, + 0x00040047,0x00000470,0x00000022,0x00000000,0x00030047,0x00000473,0x00000000,0x00040047, + 0x00000473,0x00000021,0x0000000a,0x00040047,0x00000473,0x00000022,0x00000000,0x00030047, + 0x00000623,0x00000000,0x00030047,0x000009a6,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006, + 0x00000002,0x00020014,0x00000011,0x00040017,0x00000013,0x00000011,0x00000002,0x00040017, + 0x00000018,0x00000006,0x00000004,0x00040018,0x0000001a,0x0000000c,0x00000002,0x00040015, + 0x0000002c,0x00000020,0x00000001,0x00040017,0x0000002e,0x0000002c,0x00000002,0x00040015, + 0x00000039,0x00000020,0x00000000,0x0004002b,0x00000006,0x00000055,0x3f800000,0x0004002b, + 0x00000006,0x00000056,0x00000000,0x0004002b,0x00000039,0x00000060,0x00000000,0x0004002b, + 0x00000039,0x00000066,0x00000001,0x0004002b,0x00000006,0x00000078,0x3f000000,0x0004002b, + 0x00000006,0x0000007b,0x3fc90fdb,0x0004002b,0x00000006,0x0000007e,0x3a83126f,0x0004002b, + 0x00000006,0x0000008d,0x358637bd,0x0004002b,0x00000006,0x000000aa,0x3e800000,0x0004002b, + 0x00000006,0x000000b0,0xc0000000,0x0004002b,0x00000039,0x000000b4,0x00000002,0x0004002b, + 0x0000002c,0x000000bd,0x000007ff,0x0004002b,0x0000002c,0x000000c0,0x0000000b,0x0004002b, + 0x0000002c,0x000000e5,0x00000002,0x0004002b,0x0000002c,0x000000eb,0x00000003,0x0004002b, + 0x0000002c,0x000000f0,0x00000001,0x00040017,0x000000f9,0x00000039,0x00000004,0x00090019, + 0x000000fc,0x00000039,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x000000fd,0x00000000,0x000000fc,0x0004003b,0x000000fd,0x000000fe,0x00000000, + 0x0004002b,0x0000002c,0x00000103,0x00000000,0x0004002b,0x00000039,0x0000010a,0x0000ffff, + 0x0003001d,0x0000010e,0x000000f9,0x0003001e,0x0000010f,0x0000010e,0x00040020,0x00000110, + 0x00000002,0x0000010f,0x0004003b,0x00000110,0x00000111,0x00000002,0x00040020,0x00000114, + 0x00000002,0x000000f9,0x00040017,0x00000118,0x00000039,0x00000002,0x0003001d,0x00000123, + 0x000000f9,0x0003001e,0x00000124,0x00000123,0x00040020,0x00000125,0x00000002,0x00000124, + 0x0004003b,0x00000125,0x00000126,0x00000002,0x0004002b,0x00000039,0x00000128,0x00000004, + 0x0004002b,0x00000039,0x00000143,0x00800000,0x0004002b,0x00000039,0x00000163,0x0080ffff, + 0x0004002b,0x00000039,0x00000183,0xff7fffff,0x0004002b,0x00000039,0x00000188,0x1c000000, + 0x0004002b,0x00000039,0x0000018a,0x04000000,0x0004002b,0x0000002c,0x0000019a,0x00000010, + 0x0004002b,0x00000006,0x000001df,0x40490fdb,0x0004002b,0x00000006,0x000001e3,0x40c90fdb, + 0x0004002b,0x00000006,0x00000218,0x40000000,0x0004002b,0x00000039,0x00000252,0x00100000, + 0x0004002b,0x00000039,0x0000025a,0x00080000,0x0004002b,0x00000039,0x000002a8,0x08000000, + 0x0004002b,0x00000039,0x000002ae,0x00400000,0x0004002b,0x00000006,0x000002e2,0xbf000000, + 0x0004002b,0x00000039,0x000002f9,0x14000000,0x0004002b,0x00000039,0x000002ff,0x10000000, + 0x0004002b,0x00000039,0x00000309,0x02000000,0x0004002b,0x00000039,0x00000321,0x00200000, + 0x0004002b,0x00000006,0x0000032c,0x3e000000,0x0004002b,0x00000006,0x0000037a,0x38d1b717, + 0x0003002a,0x00000011,0x0000038e,0x0004002b,0x00000006,0x00000392,0xbf800000,0x0004002b, + 0x00000006,0x00000399,0x49742400,0x0004002b,0x00000039,0x000003e3,0x01000000,0x0007002c, + 0x00000018,0x000003e9,0x00000392,0x00000055,0x00000055,0x00000055,0x0004002b,0x00000039, + 0x000003f2,0x80000000,0x0005002c,0x0000000c,0x00000404,0x00000055,0x00000392,0x00040017, + 0x00000405,0x0000002c,0x00000004,0x0017001e,0x00000406,0x00000006,0x00000006,0x00000006, + 0x00000006,0x00000039,0x00000039,0x00000039,0x00000039,0x00000405,0x0000000c,0x0000000c, + 0x00000039,0x00000006,0x00000039,0x00000006,0x00000006,0x00000039,0x00000006,0x00000006, + 0x00000006,0x00000039,0x00040020,0x00000407,0x00000002,0x00000406,0x0004003b,0x00000407, + 0x00000408,0x00000002,0x0004002b,0x0000002c,0x00000409,0x00000014,0x00040020,0x0000040a, + 0x00000002,0x00000039,0x00030029,0x00000011,0x00000415,0x00040020,0x00000419,0x00000001, + 0x0000002c,0x0004003b,0x00000419,0x0000041a,0x00000001,0x0004003b,0x00000419,0x0000041d, + 0x00000001,0x00040020,0x0000041f,0x00000001,0x00000018,0x0004003b,0x0000041f,0x00000420, + 0x00000001,0x0004003b,0x0000041f,0x00000421,0x00000001,0x00040020,0x00000424,0x00000003, + 0x00000018,0x0004003b,0x00000424,0x00000425,0x00000003,0x00040017,0x0000043b,0x00000006, + 0x00000003,0x00040017,0x0000043e,0x00000039,0x00000003,0x0004002b,0x0000002c,0x0000044a, + 0x0000000a,0x00040020,0x0000044e,0x00000002,0x00000006,0x0004002b,0x0000002c,0x00000456, + 0x0000000e,0x0004001c,0x00000460,0x00000006,0x00000066,0x0006001e,0x00000461,0x00000018, + 0x00000006,0x00000460,0x00000460,0x00040020,0x00000462,0x00000003,0x00000461,0x0004003b, + 0x00000462,0x00000463,0x00000003,0x00090019,0x00000466,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000467,0x00000000,0x00000466, + 0x0004003b,0x00000467,0x00000468,0x00000000,0x0003001d,0x00000469,0x00000118,0x0003001e, + 0x0000046a,0x00000469,0x00040020,0x0000046b,0x00000002,0x0000046a,0x0004003b,0x0000046b, + 0x0000046c,0x00000002,0x0003001d,0x0000046d,0x00000018,0x0003001e,0x0000046e,0x0000046d, + 0x00040020,0x0000046f,0x00000002,0x0000046e,0x0004003b,0x0000046f,0x00000470,0x00000002, + 0x0002001a,0x00000471,0x00040020,0x00000472,0x00000000,0x00000471,0x0004003b,0x00000472, + 0x00000473,0x00000000,0x00030001,0x00000006,0x0000090c,0x00030001,0x0000000c,0x000009f3, + 0x0005002c,0x0000000c,0x00000a0a,0x00000055,0x00000055,0x0005002c,0x0000000c,0x00000a0b, + 0x00000078,0x00000078,0x0004002b,0x0000002c,0x00000a0d,0xfffffffe,0x0004002b,0x00000006, + 0x00000a0e,0x3ea2f983,0x0004002b,0x00000006,0x00000a0f,0xc0400000,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000002c,0x0000041e, + 0x0000041d,0x0004003d,0x00000018,0x00000427,0x00000420,0x0004003d,0x00000018,0x00000429, + 0x00000421,0x000300f7,0x00000781,0x00000000,0x000300fb,0x00000060,0x000004d3,0x000200f8, + 0x000004d3,0x00050051,0x00000006,0x000004d5,0x00000427,0x00000000,0x0004006e,0x0000002c, + 0x000004d6,0x000004d5,0x00050051,0x00000006,0x000004d8,0x00000427,0x00000001,0x00050051, + 0x00000006,0x000004da,0x00000427,0x00000002,0x00050051,0x00000006,0x000004dc,0x00000427, + 0x00000003,0x0004007c,0x0000002c,0x000004dd,0x000004dc,0x000500c3,0x0000002c,0x000004de, + 0x000004dd,0x000000e5,0x000500c7,0x0000002c,0x000004e2,0x000004dd,0x000000eb,0x00050082, + 0x0000002c,0x000004e5,0x000004de,0x000000f0,0x0007000c,0x0000002c,0x000004e6,0x00000001, + 0x00000027,0x000004d6,0x000004e5,0x00050084,0x0000002c,0x000004e9,0x0000041e,0x000004de, + 0x00050080,0x0000002c,0x000004eb,0x000004e9,0x000004e6,0x0004003d,0x000000fc,0x000004ec, + 0x000000fe,0x000500c7,0x0000002c,0x00000786,0x000004eb,0x000000bd,0x000500c3,0x0000002c, + 0x00000788,0x000004eb,0x000000c0,0x00050050,0x0000002e,0x00000789,0x00000786,0x00000788, + 0x0007005f,0x000000f9,0x000004ef,0x000004ec,0x00000789,0x00000002,0x00000103,0x00050051, + 0x00000039,0x000004f1,0x000004ef,0x00000003,0x000500c7,0x00000039,0x000004f3,0x000004f1, + 0x0000010a,0x0007000c,0x00000039,0x000004f4,0x00000001,0x00000029,0x000004f3,0x00000066, + 0x00050082,0x00000039,0x000004f6,0x000004f4,0x00000066,0x00060041,0x00000114,0x000004f7, + 0x00000111,0x00000103,0x000004f6,0x0004003d,0x000000f9,0x000004f8,0x000004f7,0x0007004f, + 0x00000118,0x000004fa,0x000004f8,0x000004f8,0x00000000,0x00000001,0x0004007c,0x0000000c, + 0x000004fb,0x000004fa,0x00050051,0x00000039,0x000004fd,0x000004f8,0x00000002,0x000500c7, + 0x00000039,0x000004fe,0x000004fd,0x0000010a,0x00050051,0x00000039,0x00000500,0x000004f8, + 0x00000003,0x00050084,0x00000039,0x00000502,0x000004fe,0x00000128,0x00060041,0x00000114, + 0x00000503,0x00000126,0x00000103,0x00000502,0x0004003d,0x000000f9,0x00000504,0x00000503, + 0x0004007c,0x00000018,0x00000505,0x00000504,0x00050051,0x00000006,0x00000790,0x00000505, + 0x00000000,0x00050051,0x00000006,0x00000791,0x00000505,0x00000001,0x00050051,0x00000006, + 0x00000792,0x00000505,0x00000002,0x00050051,0x00000006,0x00000793,0x00000505,0x00000003, + 0x00050050,0x0000000c,0x00000794,0x00000790,0x00000791,0x00050050,0x0000000c,0x00000795, + 0x00000792,0x00000793,0x00050050,0x0000001a,0x00000796,0x00000794,0x00000795,0x00050080, + 0x00000039,0x00000509,0x00000502,0x00000066,0x00060041,0x00000114,0x0000050a,0x00000126, + 0x00000103,0x00000509,0x0004003d,0x000000f9,0x0000050b,0x0000050a,0x0007004f,0x00000118, + 0x0000050d,0x0000050b,0x0000050b,0x00000000,0x00000001,0x0004007c,0x0000000c,0x0000050e, + 0x0000050d,0x00050051,0x00000039,0x00000510,0x0000050b,0x00000002,0x0004007c,0x00000006, + 0x00000511,0x00000510,0x00050051,0x00000039,0x00000513,0x0000050b,0x00000003,0x0004007c, + 0x00000006,0x00000514,0x00000513,0x000500c7,0x00000039,0x00000516,0x000004f1,0x00000143, + 0x000500ab,0x00000011,0x00000518,0x00000516,0x00000060,0x000300f7,0x00000521,0x00000000, + 0x000400fa,0x00000518,0x00000519,0x00000521,0x000200f8,0x00000519,0x00050051,0x00000006, + 0x0000051b,0x00000429,0x00000000,0x0004006e,0x0000002c,0x0000051c,0x0000051b,0x00050051, + 0x00000006,0x0000051e,0x00000429,0x00000001,0x00050051,0x00000006,0x00000520,0x00000429, + 0x00000002,0x000200f9,0x00000521,0x000200f8,0x00000521,0x000700f5,0x00000006,0x000008f2, + 0x000004da,0x000004d3,0x00000520,0x00000519,0x000700f5,0x00000006,0x000008b4,0x000004d8, + 0x000004d3,0x0000051e,0x00000519,0x000700f5,0x0000002c,0x00000898,0x000004d6,0x000004d3, + 0x0000051c,0x00000519,0x000500ab,0x00000011,0x00000524,0x00000898,0x000004e6,0x000300f7, + 0x00000551,0x00000000,0x000400fa,0x00000524,0x00000525,0x00000551,0x000200f8,0x00000525, + 0x00050080,0x0000002c,0x00000528,0x000004eb,0x00000898,0x00050082,0x0000002c,0x0000052a, + 0x00000528,0x000004e6,0x0004003d,0x000000fc,0x0000052b,0x000000fe,0x000500c7,0x0000002c, + 0x0000079a,0x0000052a,0x000000bd,0x000500c3,0x0000002c,0x0000079c,0x0000052a,0x000000c0, + 0x00050050,0x0000002e,0x0000079d,0x0000079a,0x0000079c,0x0007005f,0x000000f9,0x0000052e, + 0x0000052b,0x0000079d,0x00000002,0x00000103,0x00050051,0x00000039,0x00000530,0x0000052e, + 0x00000003,0x000500c7,0x00000039,0x00000531,0x00000530,0x00000163,0x000500c7,0x00000039, + 0x00000533,0x000004f1,0x00000163,0x000500ab,0x00000011,0x00000534,0x00000531,0x00000533, + 0x000300f7,0x0000054b,0x00000000,0x000400fa,0x00000534,0x00000535,0x00000548,0x000200f8, + 0x00000535,0x000500b4,0x00000011,0x00000537,0x00000511,0x00000056,0x000400a8,0x00000011, + 0x00000538,0x00000537,0x000300f7,0x0000053d,0x00000000,0x000400fa,0x00000538,0x00000539, + 0x0000053d,0x000200f8,0x00000539,0x00050051,0x00000006,0x0000053b,0x000004fb,0x00000000, + 0x000500b7,0x00000011,0x0000053c,0x0000053b,0x00000056,0x000200f9,0x0000053d,0x000200f8, + 0x0000053d,0x000700f5,0x00000011,0x0000053e,0x00000537,0x00000535,0x0000053c,0x00000539, + 0x000300f7,0x00000547,0x00000000,0x000400fa,0x0000053e,0x00000540,0x00000547,0x000200f8, + 0x00000540,0x0004007c,0x0000002c,0x00000542,0x00000500,0x0004003d,0x000000fc,0x00000543, + 0x000000fe,0x000500c7,0x0000002c,0x000007a1,0x00000542,0x000000bd,0x000500c3,0x0000002c, + 0x000007a3,0x00000542,0x000000c0,0x00050050,0x0000002e,0x000007a4,0x000007a1,0x000007a3, + 0x0007005f,0x000000f9,0x00000546,0x00000543,0x000007a4,0x00000002,0x00000103,0x000200f9, + 0x00000547,0x000200f8,0x00000547,0x000700f5,0x0000002c,0x000008a5,0x000004eb,0x0000053d, + 0x00000542,0x00000540,0x000700f5,0x000000f9,0x0000089d,0x000004ef,0x0000053d,0x00000546, + 0x00000540,0x000200f9,0x0000054b,0x000200f8,0x00000548,0x000200f9,0x0000054b,0x000200f8, + 0x0000054b,0x000700f5,0x0000002c,0x000008a4,0x000008a5,0x00000547,0x0000052a,0x00000548, + 0x000700f5,0x000000f9,0x0000089c,0x0000089d,0x00000547,0x0000052e,0x00000548,0x00050051, + 0x00000039,0x0000054d,0x0000089c,0x00000003,0x000500c7,0x00000039,0x0000054e,0x0000054d, + 0x00000183,0x000500c5,0x00000039,0x00000550,0x0000054e,0x00000516,0x000200f9,0x00000551, + 0x000200f8,0x00000551,0x000700f5,0x0000002c,0x000008a3,0x000004eb,0x00000521,0x000008a4, + 0x0000054b,0x000700f5,0x000000f9,0x000008a1,0x000004ef,0x00000521,0x0000089c,0x0000054b, + 0x000700f5,0x00000039,0x000008a0,0x000004f1,0x00000521,0x00000550,0x0000054b,0x000500c7, + 0x00000039,0x00000553,0x000008a0,0x00000188,0x000500aa,0x00000011,0x00000554,0x00000553, + 0x0000018a,0x000500aa,0x00000011,0x00000556,0x000004e2,0x00000103,0x000500a7,0x00000011, + 0x00000557,0x00000554,0x00000556,0x000300f7,0x000005e2,0x00000000,0x000400fa,0x00000557, + 0x00000558,0x000005de,0x000200f8,0x00000558,0x00050051,0x00000039,0x0000055a,0x000008a1, + 0x00000002,0x000500c7,0x00000039,0x0000055c,0x0000055a,0x0000010a,0x00040070,0x00000006, + 0x0000055d,0x0000055c,0x000500c2,0x00000039,0x0000055f,0x0000055a,0x0000019a,0x00040070, + 0x00000006,0x00000560,0x0000055f,0x00050083,0x00000006,0x00000563,0x00000392,0x0000055d, + 0x0004006e,0x0000002c,0x00000564,0x00000563,0x00050083,0x00000006,0x00000567,0x00000560, + 0x0000055d,0x00050081,0x00000006,0x00000568,0x00000567,0x00000055,0x0004006e,0x0000002c, + 0x00000569,0x00000568,0x00050050,0x0000002e,0x0000056a,0x00000564,0x00000569,0x000500c7, + 0x00000039,0x0000056c,0x000008a0,0x00000143,0x000500ab,0x00000011,0x0000056d,0x0000056c, + 0x00000060,0x000300f7,0x00000571,0x00000000,0x000400fa,0x0000056d,0x0000056e,0x00000571, + 0x000200f8,0x0000056e,0x0004007e,0x0000002e,0x00000570,0x0000056a,0x000200f9,0x00000571, + 0x000200f8,0x00000571,0x000700f5,0x0000002e,0x000008a7,0x0000056a,0x00000558,0x00000570, + 0x0000056e,0x0004003d,0x000000fc,0x00000572,0x000000fe,0x00050051,0x0000002c,0x00000575, + 0x000008a7,0x00000000,0x00050080,0x0000002c,0x00000576,0x000008a3,0x00000575,0x000500c7, + 0x0000002c,0x000007a8,0x00000576,0x000000bd,0x000500c3,0x0000002c,0x000007aa,0x00000576, + 0x000000c0,0x00050050,0x0000002e,0x000007ab,0x000007a8,0x000007aa,0x0007005f,0x000000f9, + 0x00000578,0x00000572,0x000007ab,0x00000002,0x00000103,0x0004003d,0x000000fc,0x00000579, + 0x000000fe,0x00050051,0x0000002c,0x0000057c,0x000008a7,0x00000001,0x00050080,0x0000002c, + 0x0000057d,0x000008a3,0x0000057c,0x000500c7,0x0000002c,0x000007af,0x0000057d,0x000000bd, + 0x000500c3,0x0000002c,0x000007b1,0x0000057d,0x000000c0,0x00050050,0x0000002e,0x000007b2, + 0x000007af,0x000007b1,0x0007005f,0x000000f9,0x0000057f,0x00000579,0x000007b2,0x00000002, + 0x00000103,0x00050051,0x00000039,0x00000581,0x0000057f,0x00000003,0x000500c7,0x00000039, + 0x00000582,0x00000581,0x00000163,0x00050051,0x00000039,0x00000584,0x00000578,0x00000003, + 0x000500c7,0x00000039,0x00000585,0x00000584,0x00000163,0x000500ab,0x00000011,0x00000586, + 0x00000582,0x00000585,0x000300f7,0x0000058d,0x00000000,0x000400fa,0x00000586,0x00000587, + 0x0000058d,0x000200f8,0x00000587,0x0004003d,0x000000fc,0x00000588,0x000000fe,0x0004007c, + 0x0000002c,0x0000058a,0x00000500,0x000500c7,0x0000002c,0x000007b6,0x0000058a,0x000000bd, + 0x000500c3,0x0000002c,0x000007b8,0x0000058a,0x000000c0,0x00050050,0x0000002e,0x000007b9, + 0x000007b6,0x000007b8,0x0007005f,0x000000f9,0x0000058c,0x00000588,0x000007b9,0x00000002, + 0x00000103,0x000200f9,0x0000058d,0x000200f8,0x0000058d,0x000700f5,0x000000f9,0x000008a8, + 0x0000057f,0x00000571,0x0000058c,0x00000587,0x00050051,0x00000039,0x0000058f,0x00000578, + 0x00000002,0x0004007c,0x00000006,0x00000590,0x0000058f,0x00050051,0x00000039,0x00000592, + 0x000008a8,0x00000002,0x0004007c,0x00000006,0x00000593,0x00000592,0x00050083,0x00000006, + 0x00000596,0x00000593,0x00000590,0x0006000c,0x00000006,0x00000598,0x00000001,0x00000004, + 0x00000596,0x000500ba,0x00000011,0x00000599,0x00000598,0x000001df,0x000300f7,0x000005a0, + 0x00000000,0x000400fa,0x00000599,0x0000059a,0x000005a0,0x000200f8,0x0000059a,0x0006000c, + 0x00000006,0x0000059c,0x00000001,0x00000006,0x00000596,0x00050085,0x00000006,0x0000059d, + 0x000001e3,0x0000059c,0x00050083,0x00000006,0x0000059f,0x00000596,0x0000059d,0x000200f9, + 0x000005a0,0x000200f8,0x000005a0,0x000700f5,0x00000006,0x000008ac,0x00000596,0x0000058d, + 0x0000059f,0x0000059a,0x00050081,0x00000006,0x000005a3,0x00000560,0x000000b0,0x0006000c, + 0x00000006,0x000005a5,0x00000001,0x00000004,0x000008ac,0x00050085,0x00000006,0x000005a6, + 0x000005a5,0x00000a0e,0x00050085,0x00000006,0x000005a8,0x000005a6,0x000005a3,0x0006000c, + 0x00000006,0x000005a9,0x00000001,0x00000001,0x000005a8,0x00050081,0x00000006,0x000005ab, + 0x00000560,0x00000a0f,0x0008000c,0x00000006,0x000005ac,0x00000001,0x0000002b,0x000005a9, + 0x00000055,0x000005ab,0x00050083,0x00000006,0x000005af,0x000005a3,0x000005ac,0x000500bc, + 0x00000011,0x000005b2,0x0000055d,0x000005af,0x000300f7,0x000005cf,0x00000000,0x000400fa, + 0x000005b2,0x000005b3,0x000005c2,0x000200f8,0x000005b3,0x0006000c,0x00000006,0x000005b5, + 0x00000001,0x00000006,0x000008ac,0x00050085,0x00000006,0x000005b6,0x000001df,0x000005b5, + 0x00050083,0x00000006,0x000005b8,0x000005b6,0x000008ac,0x0004007f,0x00000006,0x000005b9, + 0x000005b8,0x000500b4,0x00000011,0x000005bd,0x0000055d,0x000005af,0x000300f7,0x000005c1, + 0x00000000,0x000400fa,0x000005bd,0x000005be,0x000005c1,0x000200f8,0x000005be,0x0004007f, + 0x00000006,0x000005c0,0x000008b4,0x000200f9,0x000005c1,0x000200f8,0x000005c1,0x000700f5, + 0x00000006,0x000008fc,0x000008b4,0x000005b3,0x000005c0,0x000005be,0x000200f9,0x000005cf, + 0x000200f8,0x000005c2,0x00050081,0x00000006,0x000005c5,0x000005af,0x00000055,0x000500b4, + 0x00000011,0x000005c6,0x0000055d,0x000005c5,0x000300f7,0x000005ce,0x00000000,0x000400fa, + 0x000005c6,0x000005c7,0x000005c8,0x000200f8,0x000005c7,0x000200f9,0x000005ce,0x000200f8, + 0x000005c8,0x00050081,0x00000006,0x000005ca,0x000005af,0x00000218,0x00050083,0x00000006, + 0x000005cc,0x0000055d,0x000005ca,0x000200f9,0x000005ce,0x000200f8,0x000005ce,0x000700f5, + 0x00000006,0x000008ba,0x00000056,0x000005c7,0x000005cc,0x000005c8,0x000600a9,0x00000006, + 0x00000a12,0x000005c6,0x00000056,0x000008b4,0x000600a9,0x00000006,0x00000a13,0x000005c6, + 0x00000056,0x000005ac,0x000200f9,0x000005cf,0x000200f8,0x000005cf,0x000700f5,0x00000006, + 0x000008fb,0x000008fc,0x000005c1,0x00000a12,0x000005ce,0x000700f5,0x00000006,0x000008c2, + 0x000005b9,0x000005c1,0x000008ac,0x000005ce,0x000700f5,0x00000006,0x000008bb,0x000005af, + 0x000005c1,0x00000a13,0x000005ce,0x000700f5,0x00000006,0x000008b8,0x0000055d,0x000005c1, + 0x000008ba,0x000005ce,0x000500b4,0x00000011,0x000005d2,0x000008b8,0x000008bb,0x000300f7, + 0x000005dd,0x00000000,0x000400fa,0x000005d2,0x000005d3,0x000005d5,0x000200f8,0x000005d3, + 0x000200f9,0x000005dd,0x000200f8,0x000005d5,0x00050088,0x00000006,0x000005da,0x000008b8, + 0x000008bb,0x00050085,0x00000006,0x000005db,0x000008c2,0x000005da,0x00050081,0x00000006, + 0x000005dc,0x00000590,0x000005db,0x000200f9,0x000005dd,0x000200f8,0x000005dd,0x000700f5, + 0x00000006,0x000008c6,0x00000593,0x000005d3,0x000005dc,0x000005d5,0x000200f9,0x000005e2, + 0x000200f8,0x000005de,0x00050051,0x00000039,0x000005e0,0x000008a1,0x00000002,0x0004007c, + 0x00000006,0x000005e1,0x000005e0,0x000200f9,0x000005e2,0x000200f8,0x000005e2,0x000700f5, + 0x00000006,0x00000911,0x00000590,0x000005dd,0x0000090c,0x000005de,0x000700f5,0x00000006, + 0x00000908,0x000008c2,0x000005dd,0x0000090c,0x000005de,0x000700f5,0x00000006,0x000008f9, + 0x000008fb,0x000005dd,0x000008b4,0x000005de,0x000700f5,0x00000006,0x000008c5,0x000008c6, + 0x000005dd,0x000005e1,0x000005de,0x0006000c,0x00000006,0x000005e4,0x00000001,0x0000000d, + 0x000008c5,0x0006000c,0x00000006,0x000005e6,0x00000001,0x0000000e,0x000008c5,0x0004007f, + 0x00000006,0x000005e7,0x000005e6,0x00050050,0x0000000c,0x000005e8,0x000005e4,0x000005e7, + 0x0007004f,0x00000118,0x000005ea,0x000008a1,0x000008a1,0x00000000,0x00000001,0x0004007c, + 0x0000000c,0x000005eb,0x000005ea,0x000500b7,0x00000011,0x000005ed,0x00000514,0x00000056, + 0x000300f7,0x000005f6,0x00000000,0x000400fa,0x000005ed,0x000005ee,0x000005f6,0x000200f8, + 0x000005ee,0x00050091,0x0000000c,0x000005f2,0x00000796,0x000005e8,0x0006000c,0x00000006, + 0x000005f3,0x00000001,0x00000042,0x000005f2,0x00050088,0x00000006,0x000005f4,0x00000055, + 0x000005f3,0x0007000c,0x00000006,0x000005f5,0x00000001,0x00000028,0x00000514,0x000005f4, + 0x000200f9,0x000005f6,0x000200f8,0x000005f6,0x000700f5,0x00000006,0x000008f7,0x00000514, + 0x000005e2,0x000005f5,0x000005ee,0x000500b7,0x00000011,0x000005f8,0x00000511,0x00000056, + 0x000300f7,0x0000076e,0x00000000,0x000400fa,0x000005f8,0x000005f9,0x0000070e,0x000200f8, + 0x000005f9,0x0006000c,0x00000006,0x000005fb,0x00000001,0x00000021,0x00000796,0x0006000c, + 0x00000006,0x000005fc,0x00000001,0x00000006,0x000005fb,0x00050085,0x00000006,0x000005fe, + 0x000008f9,0x000005fc,0x000500c7,0x00000039,0x00000600,0x000008a0,0x00000252,0x000500ab, + 0x00000011,0x00000601,0x00000600,0x00000060,0x000300f7,0x00000605,0x00000000,0x000400fa, + 0x00000601,0x00000602,0x00000605,0x000200f8,0x00000602,0x0007000c,0x00000006,0x00000604, + 0x00000001,0x00000025,0x000005fe,0x00000056,0x000200f9,0x00000605,0x000200f8,0x00000605, + 0x000700f5,0x00000006,0x0000094a,0x000005fe,0x000005f9,0x00000604,0x00000602,0x000500c7, + 0x00000039,0x00000607,0x000008a0,0x0000025a,0x000500ab,0x00000011,0x00000608,0x00000607, + 0x00000060,0x000300f7,0x0000060c,0x00000000,0x000400fa,0x00000608,0x00000609,0x0000060c, + 0x000200f8,0x00000609,0x0007000c,0x00000006,0x0000060b,0x00000001,0x00000028,0x0000094a, + 0x00000056,0x000200f9,0x0000060c,0x000200f8,0x0000060c,0x000700f5,0x00000006,0x00000955, + 0x0000094a,0x00000605,0x0000060b,0x00000609,0x000500b7,0x00000011,0x0000060e,0x000008f7, + 0x00000056,0x000300f7,0x00000616,0x00000000,0x000400fa,0x0000060e,0x0000060f,0x00000611, + 0x000200f8,0x0000060f,0x000200f9,0x00000616,0x000200f8,0x00000611,0x00050091,0x0000000c, + 0x000007bf,0x00000796,0x000005e8,0x00050051,0x00000006,0x000007c1,0x000007bf,0x00000000, + 0x0006000c,0x00000006,0x000007c2,0x00000001,0x00000004,0x000007c1,0x00050051,0x00000006, + 0x000007c4,0x000007bf,0x00000001,0x0006000c,0x00000006,0x000007c5,0x00000001,0x00000004, + 0x000007c4,0x00050081,0x00000006,0x000007c6,0x000007c2,0x000007c5,0x00050094,0x00000006, + 0x000007c9,0x000007bf,0x000007bf,0x00050088,0x00000006,0x000007ca,0x00000055,0x000007c9, + 0x00050085,0x00000006,0x000007cb,0x000007c6,0x000007ca,0x00050085,0x00000006,0x00000615, + 0x000007cb,0x00000078,0x000200f9,0x00000616,0x000200f8,0x00000616,0x000700f5,0x00000006, + 0x0000094d,0x000008f7,0x0000060f,0x00000615,0x00000611,0x000500ba,0x00000011,0x0000061a, + 0x0000094d,0x00000511,0x000500b4,0x00000011,0x0000061c,0x000008f7,0x00000056,0x000500a7, + 0x00000011,0x0000061d,0x0000061a,0x0000061c,0x000300f7,0x00000625,0x00000000,0x000400fa, + 0x0000061d,0x0000061e,0x00000625,0x000200f8,0x0000061e,0x00050088,0x00000006,0x00000623, + 0x00000511,0x0000094d,0x000200f9,0x00000625,0x000200f8,0x00000625,0x000700f5,0x00000006, + 0x000009a6,0x00000055,0x00000616,0x00000623,0x0000061e,0x000600a9,0x00000006,0x00000a14, + 0x0000061d,0x0000094d,0x00000511,0x00050081,0x00000006,0x00000629,0x00000a14,0x0000094d, + 0x0005008e,0x0000000c,0x0000062a,0x000005e8,0x00000629,0x00050085,0x00000006,0x0000062f, + 0x00000955,0x00000629,0x00050088,0x00000006,0x00000632,0x00000078,0x0000094d,0x0004007f, + 0x00000006,0x00000635,0x0000062f,0x00050050,0x0000000c,0x00000636,0x0000062f,0x00000635, + 0x00050050,0x0000000c,0x00000638,0x00000a14,0x00000a14,0x00050081,0x0000000c,0x00000639, + 0x00000636,0x00000638,0x0005008e,0x0000000c,0x0000063a,0x00000639,0x00000632,0x00050081, + 0x0000000c,0x0000063c,0x0000063a,0x00000a0b,0x00050051,0x00000006,0x0000063e,0x0000063c, + 0x00000000,0x00050051,0x00000006,0x00000640,0x0000063c,0x00000001,0x00070050,0x00000018, + 0x00000a11,0x0000063e,0x00000640,0x00000056,0x00000056,0x000500ac,0x00000011,0x00000649, + 0x00000553,0x000002a8,0x000300f7,0x000006f0,0x00000000,0x000400fa,0x00000649,0x0000064a, + 0x000006f0,0x000200f8,0x0000064a,0x000500c7,0x00000039,0x0000064c,0x000008a0,0x000002ae, + 0x000500aa,0x00000011,0x0000064d,0x0000064c,0x00000060,0x000600a9,0x0000002c,0x00000a15, + 0x0000064d,0x00000a0d,0x000000e5,0x000500c7,0x00000039,0x00000653,0x000008a0,0x00000143, + 0x000500ab,0x00000011,0x00000654,0x00000653,0x00000060,0x000300f7,0x00000658,0x00000000, + 0x000400fa,0x00000654,0x00000655,0x00000658,0x000200f8,0x00000655,0x0004007e,0x0000002c, + 0x00000657,0x00000a15,0x000200f9,0x00000658,0x000200f8,0x00000658,0x000700f5,0x0000002c, + 0x0000097b,0x00000a15,0x0000064a,0x00000657,0x00000655,0x00050080,0x0000002c,0x0000065b, + 0x000008a3,0x0000097b,0x000500c7,0x0000002c,0x000007dd,0x0000065b,0x000000bd,0x000500c3, + 0x0000002c,0x000007df,0x0000065b,0x000000c0,0x00050050,0x0000002e,0x000007e0,0x000007dd, + 0x000007df,0x0004003d,0x000000fc,0x0000065d,0x000000fe,0x0007005f,0x000000f9,0x0000065f, + 0x0000065d,0x000007e0,0x00000002,0x00000103,0x00050051,0x00000039,0x00000661,0x0000065f, + 0x00000002,0x0004007c,0x00000006,0x00000662,0x00000661,0x00050083,0x00000006,0x00000665, + 0x00000662,0x000008c5,0x0006000c,0x00000006,0x00000666,0x00000001,0x00000004,0x00000665, + 0x000500ba,0x00000011,0x00000668,0x00000666,0x000001df,0x000300f7,0x0000066c,0x00000000, + 0x000400fa,0x00000668,0x00000669,0x0000066c,0x000200f8,0x00000669,0x00050083,0x00000006, + 0x0000066b,0x000001e3,0x00000666,0x000200f9,0x0000066c,0x000200f8,0x0000066c,0x000700f5, + 0x00000006,0x00000984,0x00000666,0x00000658,0x0000066b,0x00000669,0x000500ab,0x00000011, + 0x0000066f,0x0000064c,0x00000060,0x000500a4,0x00000011,0x00000676,0x0000066f,0x00000601, + 0x000600a9,0x00000006,0x00000677,0x00000676,0x000002e2,0x00000078,0x00050085,0x00000006, + 0x00000678,0x00000984,0x00000677,0x00050081,0x00000006,0x0000067a,0x00000678,0x000008c5, + 0x0006000c,0x00000006,0x0000067c,0x00000001,0x0000000d,0x0000067a,0x0006000c,0x00000006, + 0x0000067e,0x00000001,0x0000000e,0x0000067a,0x0004007f,0x00000006,0x0000067f,0x0000067e, + 0x00050050,0x0000000c,0x00000680,0x0000067c,0x0000067f,0x00050091,0x0000000c,0x000007e6, + 0x00000796,0x00000680,0x00050051,0x00000006,0x000007e8,0x000007e6,0x00000000,0x0006000c, + 0x00000006,0x000007e9,0x00000001,0x00000004,0x000007e8,0x00050051,0x00000006,0x000007eb, + 0x000007e6,0x00000001,0x0006000c,0x00000006,0x000007ec,0x00000001,0x00000004,0x000007eb, + 0x00050081,0x00000006,0x000007ed,0x000007e9,0x000007ec,0x00050094,0x00000006,0x000007f0, + 0x000007e6,0x000007e6,0x00050088,0x00000006,0x000007f1,0x00000055,0x000007f0,0x00050085, + 0x00000006,0x000007f2,0x000007ed,0x000007f1,0x00050085,0x00000006,0x00000685,0x00000984, + 0x00000078,0x0006000c,0x00000006,0x00000686,0x00000001,0x0000000e,0x00000685,0x000500aa, + 0x00000011,0x00000688,0x00000553,0x000002f9,0x000400a8,0x00000011,0x00000689,0x00000688, + 0x000300f7,0x00000690,0x00000000,0x000400fa,0x00000689,0x0000068a,0x00000690,0x000200f8, + 0x0000068a,0x000500aa,0x00000011,0x0000068c,0x00000553,0x000002ff,0x000500be,0x00000011, + 0x0000068e,0x00000686,0x000000aa,0x000500a7,0x00000011,0x0000068f,0x0000068c,0x0000068e, + 0x000200f9,0x00000690,0x000200f8,0x00000690,0x000700f5,0x00000011,0x00000691,0x00000688, + 0x0000066c,0x0000068f,0x0000068a,0x000300f7,0x000006a4,0x00000000,0x000400fa,0x00000691, + 0x00000692,0x0000069d,0x000200f8,0x00000692,0x000500c7,0x00000039,0x00000694,0x000008a0, + 0x00000309,0x000500ab,0x00000011,0x00000695,0x00000694,0x00000060,0x000600a9,0x00000006, + 0x00000696,0x00000695,0x00000055,0x000000aa,0x0007000c,0x00000006,0x0000069a,0x00000001, + 0x00000028,0x00000686,0x00000696,0x00050088,0x00000006,0x0000069b,0x00000055,0x0000069a, + 0x00050085,0x00000006,0x0000069c,0x00000a14,0x0000069b,0x000200f9,0x000006a4,0x000200f8, + 0x0000069d,0x00050085,0x00000006,0x000006a0,0x00000a14,0x00000686,0x00050085,0x00000006, + 0x000006a2,0x000007f2,0x00000078,0x00050081,0x00000006,0x000006a3,0x000006a0,0x000006a2, + 0x000200f9,0x000006a4,0x000200f8,0x000006a4,0x000700f5,0x00000006,0x0000098b,0x0000069c, + 0x00000692,0x000006a3,0x0000069d,0x00050085,0x00000006,0x000006a7,0x000007f2,0x00000078, + 0x00050081,0x00000006,0x000006a8,0x0000098b,0x000006a7,0x000500c7,0x00000039,0x000006aa, + 0x000008a0,0x00000321,0x000500ab,0x00000011,0x000006ab,0x000006aa,0x00000060,0x000300f7, + 0x000006d9,0x00000000,0x000400fa,0x000006ab,0x000006ac,0x000006d9,0x000200f8,0x000006ac, + 0x00050085,0x00000006,0x000006b1,0x0000094d,0x0000032c,0x00050085,0x00000006,0x000006b5, + 0x000006a8,0x00000686,0x00050081,0x00000006,0x000006b7,0x000006b5,0x000006b1,0x000500bc, + 0x00000011,0x000006b8,0x00000629,0x000006b7,0x000300f7,0x000006d8,0x00000000,0x000400fa, + 0x000006b8,0x000006b9,0x000006c1,0x000200f8,0x000006b9,0x00050088,0x00000006,0x000006bc, + 0x00000055,0x00000686,0x00050085,0x00000006,0x000006bd,0x00000629,0x000006bc,0x0005008e, + 0x0000000c,0x000006c0,0x00000680,0x000006bd,0x000200f9,0x000006d8,0x000200f8,0x000006c1, + 0x0005008e,0x0000000c,0x000006c4,0x00000680,0x000006a8,0x00050094,0x00000006,0x000006c7, + 0x0000062a,0x0000062a,0x00050094,0x00000006,0x000006ca,0x000006c4,0x000006c4,0x00050050, + 0x0000000c,0x000006cb,0x000006c7,0x000006ca,0x00050050,0x0000001a,0x000006d5,0x0000062a, + 0x000006c4,0x0006000c,0x0000001a,0x000006d6,0x00000001,0x00000022,0x000006d5,0x00050090, + 0x0000000c,0x000006d7,0x000006cb,0x000006d6,0x000200f9,0x000006d8,0x000200f8,0x000006d8, + 0x000700f5,0x0000000c,0x0000099b,0x000006c0,0x000006b9,0x000006d7,0x000006c1,0x000200f9, + 0x000006d9,0x000200f8,0x000006d9,0x000700f5,0x0000000c,0x0000099a,0x0000062a,0x000006a4, + 0x0000099b,0x000006d8,0x0006000c,0x00000006,0x000006db,0x00000001,0x00000004,0x00000955, + 0x0005008e,0x0000000c,0x000006dd,0x0000099a,0x000006db,0x00050094,0x00000006,0x000006e1, + 0x000006dd,0x00000680,0x00050083,0x00000006,0x000006e2,0x000006a8,0x000006e1,0x00050088, + 0x00000006,0x000006e5,0x000006e2,0x000007f2,0x000300f7,0x000006ef,0x00000000,0x000400fa, + 0x00000601,0x000006e9,0x000006ec,0x000200f8,0x000006e9,0x00060052,0x00000018,0x00000870, + 0x000006e5,0x00000a11,0x00000001,0x000200f9,0x000006ef,0x000200f8,0x000006ec,0x00060052, + 0x00000018,0x00000872,0x000006e5,0x00000a11,0x00000000,0x000200f9,0x000006ef,0x000200f8, + 0x000006ef,0x000700f5,0x00000018,0x000009b0,0x00000870,0x000006e9,0x00000872,0x000006ec, + 0x000200f9,0x000006f0,0x000200f8,0x000006f0,0x000700f5,0x0000000c,0x000009bf,0x0000062a, + 0x00000625,0x0000099a,0x000006ef,0x000700f5,0x00000018,0x000009af,0x00000a11,0x00000625, + 0x000009b0,0x000006ef,0x0007004f,0x0000000c,0x000006f3,0x000009af,0x000009af,0x00000000, + 0x00000001,0x0005008e,0x0000000c,0x000006f4,0x000006f3,0x000009a6,0x00050051,0x00000006, + 0x000006f6,0x000006f4,0x00000000,0x00060052,0x00000018,0x00000874,0x000006f6,0x000009af, + 0x00000000,0x00050051,0x00000006,0x000006f8,0x000006f4,0x00000001,0x0007000c,0x00000006, + 0x000006fb,0x00000001,0x00000028,0x000006f8,0x0000037a,0x00060052,0x00000018,0x00000879, + 0x000006fb,0x00000874,0x00000001,0x000300f7,0x00000704,0x00000000,0x000400fa,0x0000060e, + 0x000006ff,0x00000704,0x000200f8,0x000006ff,0x00050083,0x00000006,0x00000702,0x000000b0, + 0x000006f6,0x00060052,0x00000018,0x0000087c,0x00000702,0x00000879,0x00000000,0x000200f9, + 0x00000704,0x000200f8,0x00000704,0x000700f5,0x00000018,0x000009de,0x00000879,0x000006f0, + 0x0000087c,0x000006ff,0x0005008e,0x0000000c,0x00000708,0x000009bf,0x00000955,0x00050091, + 0x0000000c,0x00000709,0x00000796,0x00000708,0x000500ab,0x00000011,0x0000070b,0x000004e2, + 0x00000103,0x000300f7,0x0000070d,0x00000000,0x000400fa,0x0000070b,0x0000070c,0x0000070d, + 0x000200f8,0x0000070c,0x000200f9,0x00000781,0x000200f8,0x0000070d,0x000200f9,0x0000076e, + 0x000200f8,0x0000070e,0x00070050,0x00000018,0x00000710,0x000008f2,0x00000392,0x00000056, + 0x00000056,0x000500b7,0x00000011,0x00000712,0x000008f7,0x00000056,0x000300f7,0x00000755, + 0x00000000,0x000400fa,0x00000712,0x00000713,0x0000074c,0x000200f8,0x00000713,0x00060052, + 0x00000018,0x0000087e,0x000000b0,0x00000710,0x00000001,0x00060052,0x00000018,0x00000880, + 0x00000399,0x0000087e,0x00000002,0x00060052,0x00000018,0x00000882,0x000008f2,0x00000880, + 0x00000003,0x000300f7,0x00000744,0x00000000,0x000400fa,0x00000557,0x0000071e,0x00000744, + 0x000200f8,0x0000071e,0x000500b8,0x00000011,0x00000720,0x00000908,0x00000056,0x000300f7, + 0x00000727,0x00000000,0x000400fa,0x00000720,0x00000721,0x00000727,0x000200f8,0x00000721, + 0x00050081,0x00000006,0x00000724,0x00000911,0x00000908,0x0004007f,0x00000006,0x00000726, + 0x00000908,0x000200f9,0x00000727,0x000200f8,0x00000727,0x000700f5,0x00000006,0x0000091b, + 0x00000908,0x0000071e,0x00000726,0x00000721,0x000700f5,0x00000006,0x0000091a,0x00000911, + 0x0000071e,0x00000724,0x00000721,0x00050083,0x00000006,0x0000072a,0x000008c5,0x0000091a, + 0x00050081,0x00000006,0x0000072c,0x0000072a,0x0000007b,0x0005008d,0x00000006,0x0000072d, + 0x0000072c,0x000001e3,0x00050083,0x00000006,0x0000072e,0x0000072d,0x0000007b,0x0008000c, + 0x00000006,0x00000731,0x00000001,0x0000002b,0x0000072e,0x00000056,0x0000091b,0x00050085, + 0x00000006,0x00000734,0x0000091b,0x00000078,0x000500ba,0x00000011,0x00000735,0x00000731, + 0x00000734,0x000300f7,0x0000073a,0x00000000,0x000400fa,0x00000735,0x00000736,0x0000073a, + 0x000200f8,0x00000736,0x00050083,0x00000006,0x00000739,0x0000091b,0x00000731,0x000200f9, + 0x0000073a,0x000200f8,0x0000073a,0x000700f5,0x00000006,0x0000091c,0x00000731,0x00000727, + 0x00000739,0x00000736,0x0006000c,0x00000006,0x0000073c,0x00000001,0x0000000d,0x0000091c, + 0x0006000c,0x00000006,0x0000073e,0x00000001,0x0000000e,0x0000091c,0x00050050,0x0000000c, + 0x0000073f,0x0000073c,0x0000073e,0x0006000c,0x00000006,0x000007fd,0x00000001,0x00000004, + 0x000008f9,0x0005008e,0x0000000c,0x000007fe,0x0000073f,0x000007fd,0x00050083,0x0000000c, + 0x00000800,0x00000a0a,0x000007fe,0x0005008e,0x0000000c,0x00000801,0x00000800,0x00000078, + 0x00050083,0x00000006,0x00000803,0x0000091b,0x0000007b,0x0006000c,0x00000006,0x00000804, + 0x00000001,0x00000004,0x00000803,0x000500b8,0x00000011,0x00000805,0x00000804,0x0000007e, + 0x000300f7,0x00000826,0x00000000,0x000400fa,0x00000805,0x00000806,0x00000807,0x000200f8, + 0x00000806,0x000200f9,0x00000826,0x000200f8,0x00000807,0x0006000c,0x00000006,0x00000809, + 0x00000001,0x0000000f,0x0000091b,0x00050083,0x00000006,0x0000080b,0x0000007b,0x0000091b, + 0x0006000c,0x00000006,0x0000080c,0x00000001,0x00000006,0x0000080b,0x0006000c,0x00000006, + 0x0000080e,0x00000001,0x00000004,0x00000809,0x0007000c,0x00000006,0x0000080f,0x00000001, + 0x00000028,0x0000080e,0x0000008d,0x00050088,0x00000006,0x00000810,0x0000080c,0x0000080f, + 0x000500be,0x00000011,0x00000812,0x00000810,0x00000056,0x000300f7,0x00000824,0x00000000, + 0x000400fa,0x00000812,0x00000813,0x0000081c,0x000200f8,0x00000813,0x00050051,0x00000006, + 0x00000815,0x00000801,0x00000001,0x00050051,0x00000006,0x00000817,0x00000801,0x00000000, + 0x00050083,0x00000006,0x00000818,0x00000055,0x00000817,0x00050085,0x00000006,0x0000081a, + 0x00000818,0x00000809,0x00050083,0x00000006,0x0000081b,0x00000815,0x0000081a,0x000200f9, + 0x00000824,0x000200f8,0x0000081c,0x00050051,0x00000006,0x0000081e,0x00000801,0x00000001, + 0x00050051,0x00000006,0x00000820,0x00000801,0x00000000,0x00050085,0x00000006,0x00000822, + 0x00000820,0x00000809,0x00050081,0x00000006,0x00000823,0x0000081e,0x00000822,0x000200f9, + 0x00000824,0x000200f8,0x00000824,0x000700f5,0x00000006,0x00000920,0x0000081b,0x00000813, + 0x00000823,0x0000081c,0x000200f9,0x00000826,0x000200f8,0x00000826,0x000700f5,0x00000006, + 0x00000936,0x00000056,0x00000806,0x00000920,0x00000824,0x000700f5,0x00000006,0x00000934, + 0x00000056,0x00000806,0x00000810,0x00000824,0x00050051,0x00000006,0x00000828,0x00000801, + 0x00000000,0x0007000c,0x00000006,0x00000829,0x00000001,0x00000028,0x00000828,0x00000056, + 0x00050081,0x00000006,0x0000082a,0x00000829,0x000000aa,0x00050051,0x00000006,0x0000082d, + 0x00000801,0x00000001,0x00050083,0x00000006,0x0000082f,0x000000b0,0x0000082d,0x00070050, + 0x00000018,0x00000a10,0x0000082a,0x0000082f,0x00000934,0x00000936,0x000200f9,0x00000744, + 0x000200f8,0x00000744,0x000700f5,0x00000018,0x00000946,0x00000882,0x00000713,0x00000a10, + 0x00000826,0x00050085,0x00000006,0x00000748,0x000008f9,0x000008f7,0x0005008e,0x0000000c, + 0x0000074a,0x000005e8,0x00000748,0x00050091,0x0000000c,0x0000074b,0x00000796,0x0000074a, + 0x000200f9,0x00000755,0x000200f8,0x0000074c,0x0005008e,0x0000000c,0x0000074f,0x000005e8, + 0x000008f9,0x0006000c,0x0000001a,0x00000751,0x00000001,0x00000022,0x00000796,0x00050090, + 0x0000000c,0x00000752,0x0000074f,0x00000751,0x0006000c,0x0000000c,0x00000753,0x00000001, + 0x00000006,0x00000752,0x0005008e,0x0000000c,0x00000754,0x00000753,0x00000078,0x000200f9, + 0x00000755,0x000200f8,0x00000755,0x000700f5,0x0000000c,0x000009dc,0x0000074b,0x00000744, + 0x00000754,0x0000074c,0x000700f5,0x00000018,0x00000945,0x00000946,0x00000744,0x00000710, + 0x0000074c,0x000500c7,0x00000039,0x00000757,0x000008a0,0x00000143,0x000500ab,0x00000011, + 0x00000758,0x00000757,0x00000060,0x000500c7,0x00000039,0x0000075a,0x000008a0,0x000003e3, + 0x000500ab,0x00000011,0x0000075b,0x0000075a,0x00000060,0x000500a5,0x00000011,0x0000075c, + 0x00000758,0x0000075b,0x000300f7,0x00000760,0x00000000,0x000400fa,0x0000075c,0x0000075d, + 0x00000760,0x000200f8,0x0000075d,0x00050085,0x00000018,0x0000075f,0x00000945,0x000003e9, + 0x000200f9,0x00000760,0x000200f8,0x00000760,0x000700f5,0x00000018,0x000009e0,0x00000945, + 0x00000755,0x0000075f,0x0000075d,0x000500aa,0x00000011,0x00000762,0x000004e2,0x000000e5, + 0x00050050,0x00000013,0x00000a16,0x00000762,0x00000762,0x000600a9,0x0000000c,0x00000a17, + 0x00000a16,0x000004fb,0x000005eb,0x000500c7,0x00000039,0x00000767,0x000008a0,0x000003f2, + 0x000500ab,0x00000011,0x00000768,0x00000767,0x00000060,0x000500ab,0x00000011,0x0000076a, + 0x000004e2,0x000000f0,0x000500a7,0x00000011,0x0000076b,0x00000768,0x0000076a,0x000300f7, + 0x0000076d,0x00000000,0x000400fa,0x0000076b,0x0000076c,0x0000076d,0x000200f8,0x0000076c, + 0x000200f9,0x00000781,0x000200f8,0x0000076d,0x000200f9,0x0000076e,0x000200f8,0x0000076e, + 0x000700f5,0x00000018,0x000009dd,0x000009de,0x0000070d,0x000009e0,0x0000076d,0x000700f5, + 0x0000000c,0x000009d9,0x00000709,0x0000070d,0x000009dc,0x0000076d,0x000700f5,0x0000000c, + 0x000009c1,0x000005eb,0x0000070d,0x00000a17,0x0000076d,0x00050091,0x0000000c,0x00000771, + 0x00000796,0x000009c1,0x00050081,0x0000000c,0x00000773,0x00000771,0x000009d9,0x00050081, + 0x0000000c,0x00000775,0x00000773,0x0000050e,0x0007004f,0x0000000c,0x00000777,0x000009dd, + 0x000009dd,0x00000000,0x00000001,0x00050041,0x0000040a,0x00000778,0x00000408,0x00000409, + 0x0004003d,0x00000039,0x00000779,0x00000778,0x000500ab,0x00000011,0x0000077a,0x00000779, + 0x00000060,0x00050050,0x00000013,0x0000083a,0x0000077a,0x0000077a,0x000600a9,0x0000000c, + 0x0000077c,0x0000083a,0x00000404,0x00000777,0x00050051,0x00000006,0x0000077e,0x0000077c, + 0x00000000,0x00060052,0x00000018,0x00000892,0x0000077e,0x000009dd,0x00000000,0x00050051, + 0x00000006,0x00000780,0x0000077c,0x00000001,0x00060052,0x00000018,0x00000894,0x00000780, + 0x00000892,0x00000001,0x000200f9,0x00000781,0x000200f8,0x00000781,0x000900f5,0x00000018, + 0x00000a08,0x000009de,0x0000070c,0x000009e0,0x0000076c,0x00000894,0x0000076e,0x000900f5, + 0x0000000c,0x000009e2,0x000009f3,0x0000070c,0x000009f3,0x0000076c,0x00000775,0x0000076e, + 0x000900f5,0x00000011,0x000009e1,0x0000038e,0x0000070c,0x0000038e,0x0000076c,0x00000415, + 0x0000076e,0x0003003e,0x00000425,0x00000a08,0x000300f7,0x00000434,0x00000000,0x000400fa, + 0x000009e1,0x00000433,0x00000455,0x000200f8,0x00000433,0x00050080,0x00000039,0x00000438, + 0x00000502,0x000000b4,0x00060041,0x00000114,0x00000439,0x00000126,0x00000103,0x00000438, + 0x0004003d,0x000000f9,0x0000043a,0x00000439,0x0008004f,0x0000043e,0x00000440,0x0000043a, + 0x0000043a,0x00000001,0x00000002,0x00000003,0x0004007c,0x0000043b,0x00000441,0x00000440, + 0x00050051,0x00000006,0x00000444,0x00000441,0x00000000,0x0005008e,0x0000000c,0x00000445, + 0x000009e2,0x00000444,0x0007004f,0x0000000c,0x00000447,0x00000441,0x00000441,0x00000001, + 0x00000002,0x00050081,0x0000000c,0x00000448,0x00000445,0x00000447,0x00060041,0x0000044e, + 0x0000044f,0x00000408,0x0000044a,0x00000060,0x0004003d,0x00000006,0x00000450,0x0000044f, + 0x00060041,0x0000044e,0x00000452,0x00000408,0x0000044a,0x00000066,0x0004003d,0x00000006, + 0x00000453,0x00000452,0x00050051,0x00000006,0x0000083e,0x00000448,0x00000000,0x00050085, + 0x00000006,0x00000840,0x0000083e,0x00000450,0x00050083,0x00000006,0x00000841,0x00000840, + 0x00000055,0x00050051,0x00000006,0x00000843,0x00000448,0x00000001,0x00050085,0x00000006, + 0x00000845,0x00000843,0x00000453,0x0006000c,0x00000006,0x00000847,0x00000001,0x00000006, + 0x00000453,0x00050083,0x00000006,0x00000848,0x00000845,0x00000847,0x00070050,0x00000018, + 0x00000849,0x00000841,0x00000848,0x00000056,0x00000055,0x000200f9,0x00000434,0x000200f8, + 0x00000455,0x00050041,0x0000044e,0x00000457,0x00000408,0x00000456,0x0004003d,0x00000006, + 0x00000458,0x00000457,0x00070050,0x00000018,0x0000045f,0x00000458,0x00000458,0x00000458, + 0x00000458,0x000200f9,0x00000434,0x000200f8,0x00000434,0x000700f5,0x00000018,0x00000a09, + 0x00000849,0x00000433,0x0000045f,0x00000455,0x00050041,0x00000424,0x00000465,0x00000463, + 0x00000103,0x0003003e,0x00000465,0x00000a09,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..980773b996f23b0e72b17174f2205b91a3cc9b16 GIT binary patch literal 16600 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 AW&i*H literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.h new file mode 100644 index 000000000..e3e29a7fc --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.h @@ -0,0 +1,523 @@ +#pragma once + +const uint32_t render_atlas_webgpu_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x00000a18,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x000b000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000041a,0x0000041d,0x00000420, + 0x00000421,0x00000425,0x00000463,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x000000fe,0x00004342,0x00030005,0x0000010f,0x0000664b,0x00040006, + 0x0000010f,0x00000000,0x00003464,0x00030005,0x00000111,0x00004358,0x00030005,0x00000124, + 0x0000664a,0x00040006,0x00000124,0x00000000,0x00003464,0x00030005,0x00000126,0x0000424c, + 0x00030005,0x00000406,0x0000424d,0x00040006,0x00000406,0x00000000,0x00006250,0x00040006, + 0x00000406,0x00000001,0x00006359,0x00040006,0x00000406,0x00000002,0x00006552,0x00040006, + 0x00000406,0x00000003,0x00006553,0x00040006,0x00000406,0x00000004,0x0000366d,0x00040006, + 0x00000406,0x00000005,0x0000676d,0x00040006,0x00000406,0x00000006,0x00006544,0x00040006, + 0x00000406,0x00000007,0x00006545,0x00040006,0x00000406,0x00000008,0x00003755,0x00040006, + 0x00000406,0x00000009,0x0000676a,0x00040006,0x00000406,0x0000000a,0x0000635a,0x00040006, + 0x00000406,0x0000000b,0x00003157,0x00040006,0x00000406,0x0000000c,0x0000676e,0x00040006, + 0x00000406,0x0000000d,0x00003559,0x00040006,0x00000406,0x0000000e,0x0000324f,0x00040006, + 0x00000406,0x0000000f,0x00006461,0x00040006,0x00000406,0x00000010,0x00006579,0x00040006, + 0x00000406,0x00000011,0x00003376,0x00040006,0x00000406,0x00000012,0x00003377,0x00040006, + 0x00000406,0x00000013,0x00006462,0x00040006,0x00000406,0x00000014,0x00006767,0x00030005, + 0x00000408,0x0000006b,0x00060005,0x0000041a,0x565f6c67,0x65747265,0x646e4978,0x00007865, + 0x00070005,0x0000041d,0x495f6c67,0x6174736e,0x4965636e,0x7865646e,0x00000000,0x00030005, + 0x00000420,0x00004254,0x00030005,0x00000421,0x00004255,0x00030005,0x00000425,0x00000049, + 0x00060005,0x00000461,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000461, + 0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x00000461,0x00000001,0x505f6c67, + 0x746e696f,0x657a6953,0x00000000,0x00070006,0x00000461,0x00000002,0x435f6c67,0x4470696c, + 0x61747369,0x0065636e,0x00070006,0x00000461,0x00000003,0x435f6c67,0x446c6c75,0x61747369, + 0x0065636e,0x00030005,0x00000463,0x00000000,0x00030005,0x00000468,0x00004351,0x00030005, + 0x0000046a,0x00006576,0x00040006,0x0000046a,0x00000000,0x00003464,0x00030005,0x0000046c, + 0x00004355,0x00030005,0x0000046e,0x00006577,0x00040006,0x0000046e,0x00000000,0x00003464, + 0x00030005,0x00000470,0x0000424f,0x00030005,0x00000473,0x00003954,0x00040047,0x000000fe, + 0x00000021,0x00000008,0x00040047,0x000000fe,0x00000022,0x00000000,0x00040047,0x0000010e, + 0x00000006,0x00000010,0x00030047,0x0000010f,0x00000003,0x00040048,0x0000010f,0x00000000, + 0x00000018,0x00050048,0x0000010f,0x00000000,0x00000023,0x00000000,0x00030047,0x00000111, + 0x00000018,0x00040047,0x00000111,0x00000021,0x00000006,0x00040047,0x00000111,0x00000022, + 0x00000000,0x00040047,0x00000123,0x00000006,0x00000010,0x00030047,0x00000124,0x00000003, + 0x00040048,0x00000124,0x00000000,0x00000018,0x00050048,0x00000124,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000126,0x00000018,0x00040047,0x00000126,0x00000021,0x00000003, + 0x00040047,0x00000126,0x00000022,0x00000000,0x00030047,0x00000406,0x00000002,0x00050048, + 0x00000406,0x00000000,0x00000023,0x00000000,0x00050048,0x00000406,0x00000001,0x00000023, + 0x00000004,0x00050048,0x00000406,0x00000002,0x00000023,0x00000008,0x00050048,0x00000406, + 0x00000003,0x00000023,0x0000000c,0x00050048,0x00000406,0x00000004,0x00000023,0x00000010, + 0x00050048,0x00000406,0x00000005,0x00000023,0x00000014,0x00050048,0x00000406,0x00000006, + 0x00000023,0x00000018,0x00050048,0x00000406,0x00000007,0x00000023,0x0000001c,0x00050048, + 0x00000406,0x00000008,0x00000023,0x00000020,0x00050048,0x00000406,0x00000009,0x00000023, + 0x00000030,0x00050048,0x00000406,0x0000000a,0x00000023,0x00000038,0x00050048,0x00000406, + 0x0000000b,0x00000023,0x00000040,0x00050048,0x00000406,0x0000000c,0x00000023,0x00000044, + 0x00050048,0x00000406,0x0000000d,0x00000023,0x00000048,0x00050048,0x00000406,0x0000000e, + 0x00000023,0x0000004c,0x00050048,0x00000406,0x0000000f,0x00000023,0x00000050,0x00050048, + 0x00000406,0x00000010,0x00000023,0x00000054,0x00050048,0x00000406,0x00000011,0x00000023, + 0x00000058,0x00050048,0x00000406,0x00000012,0x00000023,0x0000005c,0x00050048,0x00000406, + 0x00000013,0x00000023,0x00000060,0x00050048,0x00000406,0x00000014,0x00000023,0x00000064, + 0x00040047,0x00000408,0x00000021,0x00000000,0x00040047,0x00000408,0x00000022,0x00000000, + 0x00040047,0x0000041a,0x0000000b,0x0000002a,0x00040047,0x0000041d,0x0000000b,0x0000002b, + 0x00040047,0x00000420,0x0000001e,0x00000000,0x00040047,0x00000421,0x0000001e,0x00000001, + 0x00040047,0x00000425,0x0000001e,0x00000000,0x00030047,0x00000461,0x00000002,0x00050048, + 0x00000461,0x00000000,0x0000000b,0x00000000,0x00050048,0x00000461,0x00000001,0x0000000b, + 0x00000001,0x00050048,0x00000461,0x00000002,0x0000000b,0x00000003,0x00050048,0x00000461, + 0x00000003,0x0000000b,0x00000004,0x00030047,0x00000468,0x00000000,0x00040047,0x00000468, + 0x00000021,0x0000000a,0x00040047,0x00000468,0x00000022,0x00000000,0x00040047,0x00000469, + 0x00000006,0x00000008,0x00030047,0x0000046a,0x00000003,0x00040048,0x0000046a,0x00000000, + 0x00000018,0x00050048,0x0000046a,0x00000000,0x00000023,0x00000000,0x00030047,0x0000046c, + 0x00000018,0x00040047,0x0000046c,0x00000021,0x00000004,0x00040047,0x0000046c,0x00000022, + 0x00000000,0x00040047,0x0000046d,0x00000006,0x00000010,0x00030047,0x0000046e,0x00000003, + 0x00040048,0x0000046e,0x00000000,0x00000018,0x00050048,0x0000046e,0x00000000,0x00000023, + 0x00000000,0x00030047,0x00000470,0x00000018,0x00040047,0x00000470,0x00000021,0x00000005, + 0x00040047,0x00000470,0x00000022,0x00000000,0x00030047,0x00000473,0x00000000,0x00040047, + 0x00000473,0x00000021,0x0000000a,0x00040047,0x00000473,0x00000022,0x00000003,0x00030047, + 0x00000623,0x00000000,0x00030047,0x000009a6,0x00000000,0x00020013,0x00000002,0x00030021, + 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x0000000c,0x00000006, + 0x00000002,0x00020014,0x00000011,0x00040017,0x00000013,0x00000011,0x00000002,0x00040017, + 0x00000018,0x00000006,0x00000004,0x00040018,0x0000001a,0x0000000c,0x00000002,0x00040015, + 0x0000002c,0x00000020,0x00000001,0x00040017,0x0000002e,0x0000002c,0x00000002,0x00040015, + 0x00000039,0x00000020,0x00000000,0x0004002b,0x00000006,0x00000055,0x3f800000,0x0004002b, + 0x00000006,0x00000056,0x00000000,0x0004002b,0x00000039,0x00000060,0x00000000,0x0004002b, + 0x00000039,0x00000066,0x00000001,0x0004002b,0x00000006,0x00000078,0x3f000000,0x0004002b, + 0x00000006,0x0000007b,0x3fc90fdb,0x0004002b,0x00000006,0x0000007e,0x3a83126f,0x0004002b, + 0x00000006,0x0000008d,0x358637bd,0x0004002b,0x00000006,0x000000aa,0x3e800000,0x0004002b, + 0x00000006,0x000000b0,0xc0000000,0x0004002b,0x00000039,0x000000b4,0x00000002,0x0004002b, + 0x0000002c,0x000000bd,0x000007ff,0x0004002b,0x0000002c,0x000000c0,0x0000000b,0x0004002b, + 0x0000002c,0x000000e5,0x00000002,0x0004002b,0x0000002c,0x000000eb,0x00000003,0x0004002b, + 0x0000002c,0x000000f0,0x00000001,0x00040017,0x000000f9,0x00000039,0x00000004,0x00090019, + 0x000000fc,0x00000039,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x000000fd,0x00000000,0x000000fc,0x0004003b,0x000000fd,0x000000fe,0x00000000, + 0x0004002b,0x0000002c,0x00000103,0x00000000,0x0004002b,0x00000039,0x0000010a,0x0000ffff, + 0x0003001d,0x0000010e,0x000000f9,0x0003001e,0x0000010f,0x0000010e,0x00040020,0x00000110, + 0x00000002,0x0000010f,0x0004003b,0x00000110,0x00000111,0x00000002,0x00040020,0x00000114, + 0x00000002,0x000000f9,0x00040017,0x00000118,0x00000039,0x00000002,0x0003001d,0x00000123, + 0x000000f9,0x0003001e,0x00000124,0x00000123,0x00040020,0x00000125,0x00000002,0x00000124, + 0x0004003b,0x00000125,0x00000126,0x00000002,0x0004002b,0x00000039,0x00000128,0x00000004, + 0x0004002b,0x00000039,0x00000143,0x00800000,0x0004002b,0x00000039,0x00000163,0x0080ffff, + 0x0004002b,0x00000039,0x00000183,0xff7fffff,0x0004002b,0x00000039,0x00000188,0x1c000000, + 0x0004002b,0x00000039,0x0000018a,0x04000000,0x0004002b,0x0000002c,0x0000019a,0x00000010, + 0x0004002b,0x00000006,0x000001df,0x40490fdb,0x0004002b,0x00000006,0x000001e3,0x40c90fdb, + 0x0004002b,0x00000006,0x00000218,0x40000000,0x0004002b,0x00000039,0x00000252,0x00100000, + 0x0004002b,0x00000039,0x0000025a,0x00080000,0x0004002b,0x00000039,0x000002a8,0x08000000, + 0x0004002b,0x00000039,0x000002ae,0x00400000,0x0004002b,0x00000006,0x000002e2,0xbf000000, + 0x0004002b,0x00000039,0x000002f9,0x14000000,0x0004002b,0x00000039,0x000002ff,0x10000000, + 0x0004002b,0x00000039,0x00000309,0x02000000,0x0004002b,0x00000039,0x00000321,0x00200000, + 0x0004002b,0x00000006,0x0000032c,0x3e000000,0x0004002b,0x00000006,0x0000037a,0x38d1b717, + 0x0003002a,0x00000011,0x0000038e,0x0004002b,0x00000006,0x00000392,0xbf800000,0x0004002b, + 0x00000006,0x00000399,0x49742400,0x0004002b,0x00000039,0x000003e3,0x01000000,0x0007002c, + 0x00000018,0x000003e9,0x00000392,0x00000055,0x00000055,0x00000055,0x0004002b,0x00000039, + 0x000003f2,0x80000000,0x0005002c,0x0000000c,0x00000404,0x00000055,0x00000392,0x00040017, + 0x00000405,0x0000002c,0x00000004,0x0017001e,0x00000406,0x00000006,0x00000006,0x00000006, + 0x00000006,0x00000039,0x00000039,0x00000039,0x00000039,0x00000405,0x0000000c,0x0000000c, + 0x00000039,0x00000006,0x00000039,0x00000006,0x00000006,0x00000039,0x00000006,0x00000006, + 0x00000006,0x00000039,0x00040020,0x00000407,0x00000002,0x00000406,0x0004003b,0x00000407, + 0x00000408,0x00000002,0x0004002b,0x0000002c,0x00000409,0x00000014,0x00040020,0x0000040a, + 0x00000002,0x00000039,0x00030029,0x00000011,0x00000415,0x00040020,0x00000419,0x00000001, + 0x0000002c,0x0004003b,0x00000419,0x0000041a,0x00000001,0x0004003b,0x00000419,0x0000041d, + 0x00000001,0x00040020,0x0000041f,0x00000001,0x00000018,0x0004003b,0x0000041f,0x00000420, + 0x00000001,0x0004003b,0x0000041f,0x00000421,0x00000001,0x00040020,0x00000424,0x00000003, + 0x00000018,0x0004003b,0x00000424,0x00000425,0x00000003,0x00040017,0x0000043b,0x00000006, + 0x00000003,0x00040017,0x0000043e,0x00000039,0x00000003,0x0004002b,0x0000002c,0x0000044a, + 0x0000000a,0x00040020,0x0000044e,0x00000002,0x00000006,0x0004002b,0x0000002c,0x00000456, + 0x0000000e,0x0004001c,0x00000460,0x00000006,0x00000066,0x0006001e,0x00000461,0x00000018, + 0x00000006,0x00000460,0x00000460,0x00040020,0x00000462,0x00000003,0x00000461,0x0004003b, + 0x00000462,0x00000463,0x00000003,0x00090019,0x00000466,0x00000006,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000467,0x00000000,0x00000466, + 0x0004003b,0x00000467,0x00000468,0x00000000,0x0003001d,0x00000469,0x00000118,0x0003001e, + 0x0000046a,0x00000469,0x00040020,0x0000046b,0x00000002,0x0000046a,0x0004003b,0x0000046b, + 0x0000046c,0x00000002,0x0003001d,0x0000046d,0x00000018,0x0003001e,0x0000046e,0x0000046d, + 0x00040020,0x0000046f,0x00000002,0x0000046e,0x0004003b,0x0000046f,0x00000470,0x00000002, + 0x0002001a,0x00000471,0x00040020,0x00000472,0x00000000,0x00000471,0x0004003b,0x00000472, + 0x00000473,0x00000000,0x00030001,0x00000006,0x0000090c,0x00030001,0x0000000c,0x000009f3, + 0x0005002c,0x0000000c,0x00000a0a,0x00000055,0x00000055,0x0005002c,0x0000000c,0x00000a0b, + 0x00000078,0x00000078,0x0004002b,0x0000002c,0x00000a0d,0xfffffffe,0x0004002b,0x00000006, + 0x00000a0e,0x3ea2f983,0x0004002b,0x00000006,0x00000a0f,0xc0400000,0x00050036,0x00000002, + 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000002c,0x0000041e, + 0x0000041d,0x0004003d,0x00000018,0x00000427,0x00000420,0x0004003d,0x00000018,0x00000429, + 0x00000421,0x000300f7,0x00000781,0x00000000,0x000300fb,0x00000060,0x000004d3,0x000200f8, + 0x000004d3,0x00050051,0x00000006,0x000004d5,0x00000427,0x00000000,0x0004006e,0x0000002c, + 0x000004d6,0x000004d5,0x00050051,0x00000006,0x000004d8,0x00000427,0x00000001,0x00050051, + 0x00000006,0x000004da,0x00000427,0x00000002,0x00050051,0x00000006,0x000004dc,0x00000427, + 0x00000003,0x0004007c,0x0000002c,0x000004dd,0x000004dc,0x000500c3,0x0000002c,0x000004de, + 0x000004dd,0x000000e5,0x000500c7,0x0000002c,0x000004e2,0x000004dd,0x000000eb,0x00050082, + 0x0000002c,0x000004e5,0x000004de,0x000000f0,0x0007000c,0x0000002c,0x000004e6,0x00000001, + 0x00000027,0x000004d6,0x000004e5,0x00050084,0x0000002c,0x000004e9,0x0000041e,0x000004de, + 0x00050080,0x0000002c,0x000004eb,0x000004e9,0x000004e6,0x0004003d,0x000000fc,0x000004ec, + 0x000000fe,0x000500c7,0x0000002c,0x00000786,0x000004eb,0x000000bd,0x000500c3,0x0000002c, + 0x00000788,0x000004eb,0x000000c0,0x00050050,0x0000002e,0x00000789,0x00000786,0x00000788, + 0x0007005f,0x000000f9,0x000004ef,0x000004ec,0x00000789,0x00000002,0x00000103,0x00050051, + 0x00000039,0x000004f1,0x000004ef,0x00000003,0x000500c7,0x00000039,0x000004f3,0x000004f1, + 0x0000010a,0x0007000c,0x00000039,0x000004f4,0x00000001,0x00000029,0x000004f3,0x00000066, + 0x00050082,0x00000039,0x000004f6,0x000004f4,0x00000066,0x00060041,0x00000114,0x000004f7, + 0x00000111,0x00000103,0x000004f6,0x0004003d,0x000000f9,0x000004f8,0x000004f7,0x0007004f, + 0x00000118,0x000004fa,0x000004f8,0x000004f8,0x00000000,0x00000001,0x0004007c,0x0000000c, + 0x000004fb,0x000004fa,0x00050051,0x00000039,0x000004fd,0x000004f8,0x00000002,0x000500c7, + 0x00000039,0x000004fe,0x000004fd,0x0000010a,0x00050051,0x00000039,0x00000500,0x000004f8, + 0x00000003,0x00050084,0x00000039,0x00000502,0x000004fe,0x00000128,0x00060041,0x00000114, + 0x00000503,0x00000126,0x00000103,0x00000502,0x0004003d,0x000000f9,0x00000504,0x00000503, + 0x0004007c,0x00000018,0x00000505,0x00000504,0x00050051,0x00000006,0x00000790,0x00000505, + 0x00000000,0x00050051,0x00000006,0x00000791,0x00000505,0x00000001,0x00050051,0x00000006, + 0x00000792,0x00000505,0x00000002,0x00050051,0x00000006,0x00000793,0x00000505,0x00000003, + 0x00050050,0x0000000c,0x00000794,0x00000790,0x00000791,0x00050050,0x0000000c,0x00000795, + 0x00000792,0x00000793,0x00050050,0x0000001a,0x00000796,0x00000794,0x00000795,0x00050080, + 0x00000039,0x00000509,0x00000502,0x00000066,0x00060041,0x00000114,0x0000050a,0x00000126, + 0x00000103,0x00000509,0x0004003d,0x000000f9,0x0000050b,0x0000050a,0x0007004f,0x00000118, + 0x0000050d,0x0000050b,0x0000050b,0x00000000,0x00000001,0x0004007c,0x0000000c,0x0000050e, + 0x0000050d,0x00050051,0x00000039,0x00000510,0x0000050b,0x00000002,0x0004007c,0x00000006, + 0x00000511,0x00000510,0x00050051,0x00000039,0x00000513,0x0000050b,0x00000003,0x0004007c, + 0x00000006,0x00000514,0x00000513,0x000500c7,0x00000039,0x00000516,0x000004f1,0x00000143, + 0x000500ab,0x00000011,0x00000518,0x00000516,0x00000060,0x000300f7,0x00000521,0x00000000, + 0x000400fa,0x00000518,0x00000519,0x00000521,0x000200f8,0x00000519,0x00050051,0x00000006, + 0x0000051b,0x00000429,0x00000000,0x0004006e,0x0000002c,0x0000051c,0x0000051b,0x00050051, + 0x00000006,0x0000051e,0x00000429,0x00000001,0x00050051,0x00000006,0x00000520,0x00000429, + 0x00000002,0x000200f9,0x00000521,0x000200f8,0x00000521,0x000700f5,0x00000006,0x000008f2, + 0x000004da,0x000004d3,0x00000520,0x00000519,0x000700f5,0x00000006,0x000008b4,0x000004d8, + 0x000004d3,0x0000051e,0x00000519,0x000700f5,0x0000002c,0x00000898,0x000004d6,0x000004d3, + 0x0000051c,0x00000519,0x000500ab,0x00000011,0x00000524,0x00000898,0x000004e6,0x000300f7, + 0x00000551,0x00000000,0x000400fa,0x00000524,0x00000525,0x00000551,0x000200f8,0x00000525, + 0x00050080,0x0000002c,0x00000528,0x000004eb,0x00000898,0x00050082,0x0000002c,0x0000052a, + 0x00000528,0x000004e6,0x0004003d,0x000000fc,0x0000052b,0x000000fe,0x000500c7,0x0000002c, + 0x0000079a,0x0000052a,0x000000bd,0x000500c3,0x0000002c,0x0000079c,0x0000052a,0x000000c0, + 0x00050050,0x0000002e,0x0000079d,0x0000079a,0x0000079c,0x0007005f,0x000000f9,0x0000052e, + 0x0000052b,0x0000079d,0x00000002,0x00000103,0x00050051,0x00000039,0x00000530,0x0000052e, + 0x00000003,0x000500c7,0x00000039,0x00000531,0x00000530,0x00000163,0x000500c7,0x00000039, + 0x00000533,0x000004f1,0x00000163,0x000500ab,0x00000011,0x00000534,0x00000531,0x00000533, + 0x000300f7,0x0000054b,0x00000000,0x000400fa,0x00000534,0x00000535,0x00000548,0x000200f8, + 0x00000535,0x000500b4,0x00000011,0x00000537,0x00000511,0x00000056,0x000400a8,0x00000011, + 0x00000538,0x00000537,0x000300f7,0x0000053d,0x00000000,0x000400fa,0x00000538,0x00000539, + 0x0000053d,0x000200f8,0x00000539,0x00050051,0x00000006,0x0000053b,0x000004fb,0x00000000, + 0x000500b7,0x00000011,0x0000053c,0x0000053b,0x00000056,0x000200f9,0x0000053d,0x000200f8, + 0x0000053d,0x000700f5,0x00000011,0x0000053e,0x00000537,0x00000535,0x0000053c,0x00000539, + 0x000300f7,0x00000547,0x00000000,0x000400fa,0x0000053e,0x00000540,0x00000547,0x000200f8, + 0x00000540,0x0004007c,0x0000002c,0x00000542,0x00000500,0x0004003d,0x000000fc,0x00000543, + 0x000000fe,0x000500c7,0x0000002c,0x000007a1,0x00000542,0x000000bd,0x000500c3,0x0000002c, + 0x000007a3,0x00000542,0x000000c0,0x00050050,0x0000002e,0x000007a4,0x000007a1,0x000007a3, + 0x0007005f,0x000000f9,0x00000546,0x00000543,0x000007a4,0x00000002,0x00000103,0x000200f9, + 0x00000547,0x000200f8,0x00000547,0x000700f5,0x0000002c,0x000008a5,0x000004eb,0x0000053d, + 0x00000542,0x00000540,0x000700f5,0x000000f9,0x0000089d,0x000004ef,0x0000053d,0x00000546, + 0x00000540,0x000200f9,0x0000054b,0x000200f8,0x00000548,0x000200f9,0x0000054b,0x000200f8, + 0x0000054b,0x000700f5,0x0000002c,0x000008a4,0x000008a5,0x00000547,0x0000052a,0x00000548, + 0x000700f5,0x000000f9,0x0000089c,0x0000089d,0x00000547,0x0000052e,0x00000548,0x00050051, + 0x00000039,0x0000054d,0x0000089c,0x00000003,0x000500c7,0x00000039,0x0000054e,0x0000054d, + 0x00000183,0x000500c5,0x00000039,0x00000550,0x0000054e,0x00000516,0x000200f9,0x00000551, + 0x000200f8,0x00000551,0x000700f5,0x0000002c,0x000008a3,0x000004eb,0x00000521,0x000008a4, + 0x0000054b,0x000700f5,0x000000f9,0x000008a1,0x000004ef,0x00000521,0x0000089c,0x0000054b, + 0x000700f5,0x00000039,0x000008a0,0x000004f1,0x00000521,0x00000550,0x0000054b,0x000500c7, + 0x00000039,0x00000553,0x000008a0,0x00000188,0x000500aa,0x00000011,0x00000554,0x00000553, + 0x0000018a,0x000500aa,0x00000011,0x00000556,0x000004e2,0x00000103,0x000500a7,0x00000011, + 0x00000557,0x00000554,0x00000556,0x000300f7,0x000005e2,0x00000000,0x000400fa,0x00000557, + 0x00000558,0x000005de,0x000200f8,0x00000558,0x00050051,0x00000039,0x0000055a,0x000008a1, + 0x00000002,0x000500c7,0x00000039,0x0000055c,0x0000055a,0x0000010a,0x00040070,0x00000006, + 0x0000055d,0x0000055c,0x000500c2,0x00000039,0x0000055f,0x0000055a,0x0000019a,0x00040070, + 0x00000006,0x00000560,0x0000055f,0x00050083,0x00000006,0x00000563,0x00000392,0x0000055d, + 0x0004006e,0x0000002c,0x00000564,0x00000563,0x00050083,0x00000006,0x00000567,0x00000560, + 0x0000055d,0x00050081,0x00000006,0x00000568,0x00000567,0x00000055,0x0004006e,0x0000002c, + 0x00000569,0x00000568,0x00050050,0x0000002e,0x0000056a,0x00000564,0x00000569,0x000500c7, + 0x00000039,0x0000056c,0x000008a0,0x00000143,0x000500ab,0x00000011,0x0000056d,0x0000056c, + 0x00000060,0x000300f7,0x00000571,0x00000000,0x000400fa,0x0000056d,0x0000056e,0x00000571, + 0x000200f8,0x0000056e,0x0004007e,0x0000002e,0x00000570,0x0000056a,0x000200f9,0x00000571, + 0x000200f8,0x00000571,0x000700f5,0x0000002e,0x000008a7,0x0000056a,0x00000558,0x00000570, + 0x0000056e,0x0004003d,0x000000fc,0x00000572,0x000000fe,0x00050051,0x0000002c,0x00000575, + 0x000008a7,0x00000000,0x00050080,0x0000002c,0x00000576,0x000008a3,0x00000575,0x000500c7, + 0x0000002c,0x000007a8,0x00000576,0x000000bd,0x000500c3,0x0000002c,0x000007aa,0x00000576, + 0x000000c0,0x00050050,0x0000002e,0x000007ab,0x000007a8,0x000007aa,0x0007005f,0x000000f9, + 0x00000578,0x00000572,0x000007ab,0x00000002,0x00000103,0x0004003d,0x000000fc,0x00000579, + 0x000000fe,0x00050051,0x0000002c,0x0000057c,0x000008a7,0x00000001,0x00050080,0x0000002c, + 0x0000057d,0x000008a3,0x0000057c,0x000500c7,0x0000002c,0x000007af,0x0000057d,0x000000bd, + 0x000500c3,0x0000002c,0x000007b1,0x0000057d,0x000000c0,0x00050050,0x0000002e,0x000007b2, + 0x000007af,0x000007b1,0x0007005f,0x000000f9,0x0000057f,0x00000579,0x000007b2,0x00000002, + 0x00000103,0x00050051,0x00000039,0x00000581,0x0000057f,0x00000003,0x000500c7,0x00000039, + 0x00000582,0x00000581,0x00000163,0x00050051,0x00000039,0x00000584,0x00000578,0x00000003, + 0x000500c7,0x00000039,0x00000585,0x00000584,0x00000163,0x000500ab,0x00000011,0x00000586, + 0x00000582,0x00000585,0x000300f7,0x0000058d,0x00000000,0x000400fa,0x00000586,0x00000587, + 0x0000058d,0x000200f8,0x00000587,0x0004003d,0x000000fc,0x00000588,0x000000fe,0x0004007c, + 0x0000002c,0x0000058a,0x00000500,0x000500c7,0x0000002c,0x000007b6,0x0000058a,0x000000bd, + 0x000500c3,0x0000002c,0x000007b8,0x0000058a,0x000000c0,0x00050050,0x0000002e,0x000007b9, + 0x000007b6,0x000007b8,0x0007005f,0x000000f9,0x0000058c,0x00000588,0x000007b9,0x00000002, + 0x00000103,0x000200f9,0x0000058d,0x000200f8,0x0000058d,0x000700f5,0x000000f9,0x000008a8, + 0x0000057f,0x00000571,0x0000058c,0x00000587,0x00050051,0x00000039,0x0000058f,0x00000578, + 0x00000002,0x0004007c,0x00000006,0x00000590,0x0000058f,0x00050051,0x00000039,0x00000592, + 0x000008a8,0x00000002,0x0004007c,0x00000006,0x00000593,0x00000592,0x00050083,0x00000006, + 0x00000596,0x00000593,0x00000590,0x0006000c,0x00000006,0x00000598,0x00000001,0x00000004, + 0x00000596,0x000500ba,0x00000011,0x00000599,0x00000598,0x000001df,0x000300f7,0x000005a0, + 0x00000000,0x000400fa,0x00000599,0x0000059a,0x000005a0,0x000200f8,0x0000059a,0x0006000c, + 0x00000006,0x0000059c,0x00000001,0x00000006,0x00000596,0x00050085,0x00000006,0x0000059d, + 0x000001e3,0x0000059c,0x00050083,0x00000006,0x0000059f,0x00000596,0x0000059d,0x000200f9, + 0x000005a0,0x000200f8,0x000005a0,0x000700f5,0x00000006,0x000008ac,0x00000596,0x0000058d, + 0x0000059f,0x0000059a,0x00050081,0x00000006,0x000005a3,0x00000560,0x000000b0,0x0006000c, + 0x00000006,0x000005a5,0x00000001,0x00000004,0x000008ac,0x00050085,0x00000006,0x000005a6, + 0x000005a5,0x00000a0e,0x00050085,0x00000006,0x000005a8,0x000005a6,0x000005a3,0x0006000c, + 0x00000006,0x000005a9,0x00000001,0x00000001,0x000005a8,0x00050081,0x00000006,0x000005ab, + 0x00000560,0x00000a0f,0x0008000c,0x00000006,0x000005ac,0x00000001,0x0000002b,0x000005a9, + 0x00000055,0x000005ab,0x00050083,0x00000006,0x000005af,0x000005a3,0x000005ac,0x000500bc, + 0x00000011,0x000005b2,0x0000055d,0x000005af,0x000300f7,0x000005cf,0x00000000,0x000400fa, + 0x000005b2,0x000005b3,0x000005c2,0x000200f8,0x000005b3,0x0006000c,0x00000006,0x000005b5, + 0x00000001,0x00000006,0x000008ac,0x00050085,0x00000006,0x000005b6,0x000001df,0x000005b5, + 0x00050083,0x00000006,0x000005b8,0x000005b6,0x000008ac,0x0004007f,0x00000006,0x000005b9, + 0x000005b8,0x000500b4,0x00000011,0x000005bd,0x0000055d,0x000005af,0x000300f7,0x000005c1, + 0x00000000,0x000400fa,0x000005bd,0x000005be,0x000005c1,0x000200f8,0x000005be,0x0004007f, + 0x00000006,0x000005c0,0x000008b4,0x000200f9,0x000005c1,0x000200f8,0x000005c1,0x000700f5, + 0x00000006,0x000008fc,0x000008b4,0x000005b3,0x000005c0,0x000005be,0x000200f9,0x000005cf, + 0x000200f8,0x000005c2,0x00050081,0x00000006,0x000005c5,0x000005af,0x00000055,0x000500b4, + 0x00000011,0x000005c6,0x0000055d,0x000005c5,0x000300f7,0x000005ce,0x00000000,0x000400fa, + 0x000005c6,0x000005c7,0x000005c8,0x000200f8,0x000005c7,0x000200f9,0x000005ce,0x000200f8, + 0x000005c8,0x00050081,0x00000006,0x000005ca,0x000005af,0x00000218,0x00050083,0x00000006, + 0x000005cc,0x0000055d,0x000005ca,0x000200f9,0x000005ce,0x000200f8,0x000005ce,0x000700f5, + 0x00000006,0x000008ba,0x00000056,0x000005c7,0x000005cc,0x000005c8,0x000600a9,0x00000006, + 0x00000a12,0x000005c6,0x00000056,0x000008b4,0x000600a9,0x00000006,0x00000a13,0x000005c6, + 0x00000056,0x000005ac,0x000200f9,0x000005cf,0x000200f8,0x000005cf,0x000700f5,0x00000006, + 0x000008fb,0x000008fc,0x000005c1,0x00000a12,0x000005ce,0x000700f5,0x00000006,0x000008c2, + 0x000005b9,0x000005c1,0x000008ac,0x000005ce,0x000700f5,0x00000006,0x000008bb,0x000005af, + 0x000005c1,0x00000a13,0x000005ce,0x000700f5,0x00000006,0x000008b8,0x0000055d,0x000005c1, + 0x000008ba,0x000005ce,0x000500b4,0x00000011,0x000005d2,0x000008b8,0x000008bb,0x000300f7, + 0x000005dd,0x00000000,0x000400fa,0x000005d2,0x000005d3,0x000005d5,0x000200f8,0x000005d3, + 0x000200f9,0x000005dd,0x000200f8,0x000005d5,0x00050088,0x00000006,0x000005da,0x000008b8, + 0x000008bb,0x00050085,0x00000006,0x000005db,0x000008c2,0x000005da,0x00050081,0x00000006, + 0x000005dc,0x00000590,0x000005db,0x000200f9,0x000005dd,0x000200f8,0x000005dd,0x000700f5, + 0x00000006,0x000008c6,0x00000593,0x000005d3,0x000005dc,0x000005d5,0x000200f9,0x000005e2, + 0x000200f8,0x000005de,0x00050051,0x00000039,0x000005e0,0x000008a1,0x00000002,0x0004007c, + 0x00000006,0x000005e1,0x000005e0,0x000200f9,0x000005e2,0x000200f8,0x000005e2,0x000700f5, + 0x00000006,0x00000911,0x00000590,0x000005dd,0x0000090c,0x000005de,0x000700f5,0x00000006, + 0x00000908,0x000008c2,0x000005dd,0x0000090c,0x000005de,0x000700f5,0x00000006,0x000008f9, + 0x000008fb,0x000005dd,0x000008b4,0x000005de,0x000700f5,0x00000006,0x000008c5,0x000008c6, + 0x000005dd,0x000005e1,0x000005de,0x0006000c,0x00000006,0x000005e4,0x00000001,0x0000000d, + 0x000008c5,0x0006000c,0x00000006,0x000005e6,0x00000001,0x0000000e,0x000008c5,0x0004007f, + 0x00000006,0x000005e7,0x000005e6,0x00050050,0x0000000c,0x000005e8,0x000005e4,0x000005e7, + 0x0007004f,0x00000118,0x000005ea,0x000008a1,0x000008a1,0x00000000,0x00000001,0x0004007c, + 0x0000000c,0x000005eb,0x000005ea,0x000500b7,0x00000011,0x000005ed,0x00000514,0x00000056, + 0x000300f7,0x000005f6,0x00000000,0x000400fa,0x000005ed,0x000005ee,0x000005f6,0x000200f8, + 0x000005ee,0x00050091,0x0000000c,0x000005f2,0x00000796,0x000005e8,0x0006000c,0x00000006, + 0x000005f3,0x00000001,0x00000042,0x000005f2,0x00050088,0x00000006,0x000005f4,0x00000055, + 0x000005f3,0x0007000c,0x00000006,0x000005f5,0x00000001,0x00000028,0x00000514,0x000005f4, + 0x000200f9,0x000005f6,0x000200f8,0x000005f6,0x000700f5,0x00000006,0x000008f7,0x00000514, + 0x000005e2,0x000005f5,0x000005ee,0x000500b7,0x00000011,0x000005f8,0x00000511,0x00000056, + 0x000300f7,0x0000076e,0x00000000,0x000400fa,0x000005f8,0x000005f9,0x0000070e,0x000200f8, + 0x000005f9,0x0006000c,0x00000006,0x000005fb,0x00000001,0x00000021,0x00000796,0x0006000c, + 0x00000006,0x000005fc,0x00000001,0x00000006,0x000005fb,0x00050085,0x00000006,0x000005fe, + 0x000008f9,0x000005fc,0x000500c7,0x00000039,0x00000600,0x000008a0,0x00000252,0x000500ab, + 0x00000011,0x00000601,0x00000600,0x00000060,0x000300f7,0x00000605,0x00000000,0x000400fa, + 0x00000601,0x00000602,0x00000605,0x000200f8,0x00000602,0x0007000c,0x00000006,0x00000604, + 0x00000001,0x00000025,0x000005fe,0x00000056,0x000200f9,0x00000605,0x000200f8,0x00000605, + 0x000700f5,0x00000006,0x0000094a,0x000005fe,0x000005f9,0x00000604,0x00000602,0x000500c7, + 0x00000039,0x00000607,0x000008a0,0x0000025a,0x000500ab,0x00000011,0x00000608,0x00000607, + 0x00000060,0x000300f7,0x0000060c,0x00000000,0x000400fa,0x00000608,0x00000609,0x0000060c, + 0x000200f8,0x00000609,0x0007000c,0x00000006,0x0000060b,0x00000001,0x00000028,0x0000094a, + 0x00000056,0x000200f9,0x0000060c,0x000200f8,0x0000060c,0x000700f5,0x00000006,0x00000955, + 0x0000094a,0x00000605,0x0000060b,0x00000609,0x000500b7,0x00000011,0x0000060e,0x000008f7, + 0x00000056,0x000300f7,0x00000616,0x00000000,0x000400fa,0x0000060e,0x0000060f,0x00000611, + 0x000200f8,0x0000060f,0x000200f9,0x00000616,0x000200f8,0x00000611,0x00050091,0x0000000c, + 0x000007bf,0x00000796,0x000005e8,0x00050051,0x00000006,0x000007c1,0x000007bf,0x00000000, + 0x0006000c,0x00000006,0x000007c2,0x00000001,0x00000004,0x000007c1,0x00050051,0x00000006, + 0x000007c4,0x000007bf,0x00000001,0x0006000c,0x00000006,0x000007c5,0x00000001,0x00000004, + 0x000007c4,0x00050081,0x00000006,0x000007c6,0x000007c2,0x000007c5,0x00050094,0x00000006, + 0x000007c9,0x000007bf,0x000007bf,0x00050088,0x00000006,0x000007ca,0x00000055,0x000007c9, + 0x00050085,0x00000006,0x000007cb,0x000007c6,0x000007ca,0x00050085,0x00000006,0x00000615, + 0x000007cb,0x00000078,0x000200f9,0x00000616,0x000200f8,0x00000616,0x000700f5,0x00000006, + 0x0000094d,0x000008f7,0x0000060f,0x00000615,0x00000611,0x000500ba,0x00000011,0x0000061a, + 0x0000094d,0x00000511,0x000500b4,0x00000011,0x0000061c,0x000008f7,0x00000056,0x000500a7, + 0x00000011,0x0000061d,0x0000061a,0x0000061c,0x000300f7,0x00000625,0x00000000,0x000400fa, + 0x0000061d,0x0000061e,0x00000625,0x000200f8,0x0000061e,0x00050088,0x00000006,0x00000623, + 0x00000511,0x0000094d,0x000200f9,0x00000625,0x000200f8,0x00000625,0x000700f5,0x00000006, + 0x000009a6,0x00000055,0x00000616,0x00000623,0x0000061e,0x000600a9,0x00000006,0x00000a14, + 0x0000061d,0x0000094d,0x00000511,0x00050081,0x00000006,0x00000629,0x00000a14,0x0000094d, + 0x0005008e,0x0000000c,0x0000062a,0x000005e8,0x00000629,0x00050085,0x00000006,0x0000062f, + 0x00000955,0x00000629,0x00050088,0x00000006,0x00000632,0x00000078,0x0000094d,0x0004007f, + 0x00000006,0x00000635,0x0000062f,0x00050050,0x0000000c,0x00000636,0x0000062f,0x00000635, + 0x00050050,0x0000000c,0x00000638,0x00000a14,0x00000a14,0x00050081,0x0000000c,0x00000639, + 0x00000636,0x00000638,0x0005008e,0x0000000c,0x0000063a,0x00000639,0x00000632,0x00050081, + 0x0000000c,0x0000063c,0x0000063a,0x00000a0b,0x00050051,0x00000006,0x0000063e,0x0000063c, + 0x00000000,0x00050051,0x00000006,0x00000640,0x0000063c,0x00000001,0x00070050,0x00000018, + 0x00000a11,0x0000063e,0x00000640,0x00000056,0x00000056,0x000500ac,0x00000011,0x00000649, + 0x00000553,0x000002a8,0x000300f7,0x000006f0,0x00000000,0x000400fa,0x00000649,0x0000064a, + 0x000006f0,0x000200f8,0x0000064a,0x000500c7,0x00000039,0x0000064c,0x000008a0,0x000002ae, + 0x000500aa,0x00000011,0x0000064d,0x0000064c,0x00000060,0x000600a9,0x0000002c,0x00000a15, + 0x0000064d,0x00000a0d,0x000000e5,0x000500c7,0x00000039,0x00000653,0x000008a0,0x00000143, + 0x000500ab,0x00000011,0x00000654,0x00000653,0x00000060,0x000300f7,0x00000658,0x00000000, + 0x000400fa,0x00000654,0x00000655,0x00000658,0x000200f8,0x00000655,0x0004007e,0x0000002c, + 0x00000657,0x00000a15,0x000200f9,0x00000658,0x000200f8,0x00000658,0x000700f5,0x0000002c, + 0x0000097b,0x00000a15,0x0000064a,0x00000657,0x00000655,0x00050080,0x0000002c,0x0000065b, + 0x000008a3,0x0000097b,0x000500c7,0x0000002c,0x000007dd,0x0000065b,0x000000bd,0x000500c3, + 0x0000002c,0x000007df,0x0000065b,0x000000c0,0x00050050,0x0000002e,0x000007e0,0x000007dd, + 0x000007df,0x0004003d,0x000000fc,0x0000065d,0x000000fe,0x0007005f,0x000000f9,0x0000065f, + 0x0000065d,0x000007e0,0x00000002,0x00000103,0x00050051,0x00000039,0x00000661,0x0000065f, + 0x00000002,0x0004007c,0x00000006,0x00000662,0x00000661,0x00050083,0x00000006,0x00000665, + 0x00000662,0x000008c5,0x0006000c,0x00000006,0x00000666,0x00000001,0x00000004,0x00000665, + 0x000500ba,0x00000011,0x00000668,0x00000666,0x000001df,0x000300f7,0x0000066c,0x00000000, + 0x000400fa,0x00000668,0x00000669,0x0000066c,0x000200f8,0x00000669,0x00050083,0x00000006, + 0x0000066b,0x000001e3,0x00000666,0x000200f9,0x0000066c,0x000200f8,0x0000066c,0x000700f5, + 0x00000006,0x00000984,0x00000666,0x00000658,0x0000066b,0x00000669,0x000500ab,0x00000011, + 0x0000066f,0x0000064c,0x00000060,0x000500a4,0x00000011,0x00000676,0x0000066f,0x00000601, + 0x000600a9,0x00000006,0x00000677,0x00000676,0x000002e2,0x00000078,0x00050085,0x00000006, + 0x00000678,0x00000984,0x00000677,0x00050081,0x00000006,0x0000067a,0x00000678,0x000008c5, + 0x0006000c,0x00000006,0x0000067c,0x00000001,0x0000000d,0x0000067a,0x0006000c,0x00000006, + 0x0000067e,0x00000001,0x0000000e,0x0000067a,0x0004007f,0x00000006,0x0000067f,0x0000067e, + 0x00050050,0x0000000c,0x00000680,0x0000067c,0x0000067f,0x00050091,0x0000000c,0x000007e6, + 0x00000796,0x00000680,0x00050051,0x00000006,0x000007e8,0x000007e6,0x00000000,0x0006000c, + 0x00000006,0x000007e9,0x00000001,0x00000004,0x000007e8,0x00050051,0x00000006,0x000007eb, + 0x000007e6,0x00000001,0x0006000c,0x00000006,0x000007ec,0x00000001,0x00000004,0x000007eb, + 0x00050081,0x00000006,0x000007ed,0x000007e9,0x000007ec,0x00050094,0x00000006,0x000007f0, + 0x000007e6,0x000007e6,0x00050088,0x00000006,0x000007f1,0x00000055,0x000007f0,0x00050085, + 0x00000006,0x000007f2,0x000007ed,0x000007f1,0x00050085,0x00000006,0x00000685,0x00000984, + 0x00000078,0x0006000c,0x00000006,0x00000686,0x00000001,0x0000000e,0x00000685,0x000500aa, + 0x00000011,0x00000688,0x00000553,0x000002f9,0x000400a8,0x00000011,0x00000689,0x00000688, + 0x000300f7,0x00000690,0x00000000,0x000400fa,0x00000689,0x0000068a,0x00000690,0x000200f8, + 0x0000068a,0x000500aa,0x00000011,0x0000068c,0x00000553,0x000002ff,0x000500be,0x00000011, + 0x0000068e,0x00000686,0x000000aa,0x000500a7,0x00000011,0x0000068f,0x0000068c,0x0000068e, + 0x000200f9,0x00000690,0x000200f8,0x00000690,0x000700f5,0x00000011,0x00000691,0x00000688, + 0x0000066c,0x0000068f,0x0000068a,0x000300f7,0x000006a4,0x00000000,0x000400fa,0x00000691, + 0x00000692,0x0000069d,0x000200f8,0x00000692,0x000500c7,0x00000039,0x00000694,0x000008a0, + 0x00000309,0x000500ab,0x00000011,0x00000695,0x00000694,0x00000060,0x000600a9,0x00000006, + 0x00000696,0x00000695,0x00000055,0x000000aa,0x0007000c,0x00000006,0x0000069a,0x00000001, + 0x00000028,0x00000686,0x00000696,0x00050088,0x00000006,0x0000069b,0x00000055,0x0000069a, + 0x00050085,0x00000006,0x0000069c,0x00000a14,0x0000069b,0x000200f9,0x000006a4,0x000200f8, + 0x0000069d,0x00050085,0x00000006,0x000006a0,0x00000a14,0x00000686,0x00050085,0x00000006, + 0x000006a2,0x000007f2,0x00000078,0x00050081,0x00000006,0x000006a3,0x000006a0,0x000006a2, + 0x000200f9,0x000006a4,0x000200f8,0x000006a4,0x000700f5,0x00000006,0x0000098b,0x0000069c, + 0x00000692,0x000006a3,0x0000069d,0x00050085,0x00000006,0x000006a7,0x000007f2,0x00000078, + 0x00050081,0x00000006,0x000006a8,0x0000098b,0x000006a7,0x000500c7,0x00000039,0x000006aa, + 0x000008a0,0x00000321,0x000500ab,0x00000011,0x000006ab,0x000006aa,0x00000060,0x000300f7, + 0x000006d9,0x00000000,0x000400fa,0x000006ab,0x000006ac,0x000006d9,0x000200f8,0x000006ac, + 0x00050085,0x00000006,0x000006b1,0x0000094d,0x0000032c,0x00050085,0x00000006,0x000006b5, + 0x000006a8,0x00000686,0x00050081,0x00000006,0x000006b7,0x000006b5,0x000006b1,0x000500bc, + 0x00000011,0x000006b8,0x00000629,0x000006b7,0x000300f7,0x000006d8,0x00000000,0x000400fa, + 0x000006b8,0x000006b9,0x000006c1,0x000200f8,0x000006b9,0x00050088,0x00000006,0x000006bc, + 0x00000055,0x00000686,0x00050085,0x00000006,0x000006bd,0x00000629,0x000006bc,0x0005008e, + 0x0000000c,0x000006c0,0x00000680,0x000006bd,0x000200f9,0x000006d8,0x000200f8,0x000006c1, + 0x0005008e,0x0000000c,0x000006c4,0x00000680,0x000006a8,0x00050094,0x00000006,0x000006c7, + 0x0000062a,0x0000062a,0x00050094,0x00000006,0x000006ca,0x000006c4,0x000006c4,0x00050050, + 0x0000000c,0x000006cb,0x000006c7,0x000006ca,0x00050050,0x0000001a,0x000006d5,0x0000062a, + 0x000006c4,0x0006000c,0x0000001a,0x000006d6,0x00000001,0x00000022,0x000006d5,0x00050090, + 0x0000000c,0x000006d7,0x000006cb,0x000006d6,0x000200f9,0x000006d8,0x000200f8,0x000006d8, + 0x000700f5,0x0000000c,0x0000099b,0x000006c0,0x000006b9,0x000006d7,0x000006c1,0x000200f9, + 0x000006d9,0x000200f8,0x000006d9,0x000700f5,0x0000000c,0x0000099a,0x0000062a,0x000006a4, + 0x0000099b,0x000006d8,0x0006000c,0x00000006,0x000006db,0x00000001,0x00000004,0x00000955, + 0x0005008e,0x0000000c,0x000006dd,0x0000099a,0x000006db,0x00050094,0x00000006,0x000006e1, + 0x000006dd,0x00000680,0x00050083,0x00000006,0x000006e2,0x000006a8,0x000006e1,0x00050088, + 0x00000006,0x000006e5,0x000006e2,0x000007f2,0x000300f7,0x000006ef,0x00000000,0x000400fa, + 0x00000601,0x000006e9,0x000006ec,0x000200f8,0x000006e9,0x00060052,0x00000018,0x00000870, + 0x000006e5,0x00000a11,0x00000001,0x000200f9,0x000006ef,0x000200f8,0x000006ec,0x00060052, + 0x00000018,0x00000872,0x000006e5,0x00000a11,0x00000000,0x000200f9,0x000006ef,0x000200f8, + 0x000006ef,0x000700f5,0x00000018,0x000009b0,0x00000870,0x000006e9,0x00000872,0x000006ec, + 0x000200f9,0x000006f0,0x000200f8,0x000006f0,0x000700f5,0x0000000c,0x000009bf,0x0000062a, + 0x00000625,0x0000099a,0x000006ef,0x000700f5,0x00000018,0x000009af,0x00000a11,0x00000625, + 0x000009b0,0x000006ef,0x0007004f,0x0000000c,0x000006f3,0x000009af,0x000009af,0x00000000, + 0x00000001,0x0005008e,0x0000000c,0x000006f4,0x000006f3,0x000009a6,0x00050051,0x00000006, + 0x000006f6,0x000006f4,0x00000000,0x00060052,0x00000018,0x00000874,0x000006f6,0x000009af, + 0x00000000,0x00050051,0x00000006,0x000006f8,0x000006f4,0x00000001,0x0007000c,0x00000006, + 0x000006fb,0x00000001,0x00000028,0x000006f8,0x0000037a,0x00060052,0x00000018,0x00000879, + 0x000006fb,0x00000874,0x00000001,0x000300f7,0x00000704,0x00000000,0x000400fa,0x0000060e, + 0x000006ff,0x00000704,0x000200f8,0x000006ff,0x00050083,0x00000006,0x00000702,0x000000b0, + 0x000006f6,0x00060052,0x00000018,0x0000087c,0x00000702,0x00000879,0x00000000,0x000200f9, + 0x00000704,0x000200f8,0x00000704,0x000700f5,0x00000018,0x000009de,0x00000879,0x000006f0, + 0x0000087c,0x000006ff,0x0005008e,0x0000000c,0x00000708,0x000009bf,0x00000955,0x00050091, + 0x0000000c,0x00000709,0x00000796,0x00000708,0x000500ab,0x00000011,0x0000070b,0x000004e2, + 0x00000103,0x000300f7,0x0000070d,0x00000000,0x000400fa,0x0000070b,0x0000070c,0x0000070d, + 0x000200f8,0x0000070c,0x000200f9,0x00000781,0x000200f8,0x0000070d,0x000200f9,0x0000076e, + 0x000200f8,0x0000070e,0x00070050,0x00000018,0x00000710,0x000008f2,0x00000392,0x00000056, + 0x00000056,0x000500b7,0x00000011,0x00000712,0x000008f7,0x00000056,0x000300f7,0x00000755, + 0x00000000,0x000400fa,0x00000712,0x00000713,0x0000074c,0x000200f8,0x00000713,0x00060052, + 0x00000018,0x0000087e,0x000000b0,0x00000710,0x00000001,0x00060052,0x00000018,0x00000880, + 0x00000399,0x0000087e,0x00000002,0x00060052,0x00000018,0x00000882,0x000008f2,0x00000880, + 0x00000003,0x000300f7,0x00000744,0x00000000,0x000400fa,0x00000557,0x0000071e,0x00000744, + 0x000200f8,0x0000071e,0x000500b8,0x00000011,0x00000720,0x00000908,0x00000056,0x000300f7, + 0x00000727,0x00000000,0x000400fa,0x00000720,0x00000721,0x00000727,0x000200f8,0x00000721, + 0x00050081,0x00000006,0x00000724,0x00000911,0x00000908,0x0004007f,0x00000006,0x00000726, + 0x00000908,0x000200f9,0x00000727,0x000200f8,0x00000727,0x000700f5,0x00000006,0x0000091b, + 0x00000908,0x0000071e,0x00000726,0x00000721,0x000700f5,0x00000006,0x0000091a,0x00000911, + 0x0000071e,0x00000724,0x00000721,0x00050083,0x00000006,0x0000072a,0x000008c5,0x0000091a, + 0x00050081,0x00000006,0x0000072c,0x0000072a,0x0000007b,0x0005008d,0x00000006,0x0000072d, + 0x0000072c,0x000001e3,0x00050083,0x00000006,0x0000072e,0x0000072d,0x0000007b,0x0008000c, + 0x00000006,0x00000731,0x00000001,0x0000002b,0x0000072e,0x00000056,0x0000091b,0x00050085, + 0x00000006,0x00000734,0x0000091b,0x00000078,0x000500ba,0x00000011,0x00000735,0x00000731, + 0x00000734,0x000300f7,0x0000073a,0x00000000,0x000400fa,0x00000735,0x00000736,0x0000073a, + 0x000200f8,0x00000736,0x00050083,0x00000006,0x00000739,0x0000091b,0x00000731,0x000200f9, + 0x0000073a,0x000200f8,0x0000073a,0x000700f5,0x00000006,0x0000091c,0x00000731,0x00000727, + 0x00000739,0x00000736,0x0006000c,0x00000006,0x0000073c,0x00000001,0x0000000d,0x0000091c, + 0x0006000c,0x00000006,0x0000073e,0x00000001,0x0000000e,0x0000091c,0x00050050,0x0000000c, + 0x0000073f,0x0000073c,0x0000073e,0x0006000c,0x00000006,0x000007fd,0x00000001,0x00000004, + 0x000008f9,0x0005008e,0x0000000c,0x000007fe,0x0000073f,0x000007fd,0x00050083,0x0000000c, + 0x00000800,0x00000a0a,0x000007fe,0x0005008e,0x0000000c,0x00000801,0x00000800,0x00000078, + 0x00050083,0x00000006,0x00000803,0x0000091b,0x0000007b,0x0006000c,0x00000006,0x00000804, + 0x00000001,0x00000004,0x00000803,0x000500b8,0x00000011,0x00000805,0x00000804,0x0000007e, + 0x000300f7,0x00000826,0x00000000,0x000400fa,0x00000805,0x00000806,0x00000807,0x000200f8, + 0x00000806,0x000200f9,0x00000826,0x000200f8,0x00000807,0x0006000c,0x00000006,0x00000809, + 0x00000001,0x0000000f,0x0000091b,0x00050083,0x00000006,0x0000080b,0x0000007b,0x0000091b, + 0x0006000c,0x00000006,0x0000080c,0x00000001,0x00000006,0x0000080b,0x0006000c,0x00000006, + 0x0000080e,0x00000001,0x00000004,0x00000809,0x0007000c,0x00000006,0x0000080f,0x00000001, + 0x00000028,0x0000080e,0x0000008d,0x00050088,0x00000006,0x00000810,0x0000080c,0x0000080f, + 0x000500be,0x00000011,0x00000812,0x00000810,0x00000056,0x000300f7,0x00000824,0x00000000, + 0x000400fa,0x00000812,0x00000813,0x0000081c,0x000200f8,0x00000813,0x00050051,0x00000006, + 0x00000815,0x00000801,0x00000001,0x00050051,0x00000006,0x00000817,0x00000801,0x00000000, + 0x00050083,0x00000006,0x00000818,0x00000055,0x00000817,0x00050085,0x00000006,0x0000081a, + 0x00000818,0x00000809,0x00050083,0x00000006,0x0000081b,0x00000815,0x0000081a,0x000200f9, + 0x00000824,0x000200f8,0x0000081c,0x00050051,0x00000006,0x0000081e,0x00000801,0x00000001, + 0x00050051,0x00000006,0x00000820,0x00000801,0x00000000,0x00050085,0x00000006,0x00000822, + 0x00000820,0x00000809,0x00050081,0x00000006,0x00000823,0x0000081e,0x00000822,0x000200f9, + 0x00000824,0x000200f8,0x00000824,0x000700f5,0x00000006,0x00000920,0x0000081b,0x00000813, + 0x00000823,0x0000081c,0x000200f9,0x00000826,0x000200f8,0x00000826,0x000700f5,0x00000006, + 0x00000936,0x00000056,0x00000806,0x00000920,0x00000824,0x000700f5,0x00000006,0x00000934, + 0x00000056,0x00000806,0x00000810,0x00000824,0x00050051,0x00000006,0x00000828,0x00000801, + 0x00000000,0x0007000c,0x00000006,0x00000829,0x00000001,0x00000028,0x00000828,0x00000056, + 0x00050081,0x00000006,0x0000082a,0x00000829,0x000000aa,0x00050051,0x00000006,0x0000082d, + 0x00000801,0x00000001,0x00050083,0x00000006,0x0000082f,0x000000b0,0x0000082d,0x00070050, + 0x00000018,0x00000a10,0x0000082a,0x0000082f,0x00000934,0x00000936,0x000200f9,0x00000744, + 0x000200f8,0x00000744,0x000700f5,0x00000018,0x00000946,0x00000882,0x00000713,0x00000a10, + 0x00000826,0x00050085,0x00000006,0x00000748,0x000008f9,0x000008f7,0x0005008e,0x0000000c, + 0x0000074a,0x000005e8,0x00000748,0x00050091,0x0000000c,0x0000074b,0x00000796,0x0000074a, + 0x000200f9,0x00000755,0x000200f8,0x0000074c,0x0005008e,0x0000000c,0x0000074f,0x000005e8, + 0x000008f9,0x0006000c,0x0000001a,0x00000751,0x00000001,0x00000022,0x00000796,0x00050090, + 0x0000000c,0x00000752,0x0000074f,0x00000751,0x0006000c,0x0000000c,0x00000753,0x00000001, + 0x00000006,0x00000752,0x0005008e,0x0000000c,0x00000754,0x00000753,0x00000078,0x000200f9, + 0x00000755,0x000200f8,0x00000755,0x000700f5,0x0000000c,0x000009dc,0x0000074b,0x00000744, + 0x00000754,0x0000074c,0x000700f5,0x00000018,0x00000945,0x00000946,0x00000744,0x00000710, + 0x0000074c,0x000500c7,0x00000039,0x00000757,0x000008a0,0x00000143,0x000500ab,0x00000011, + 0x00000758,0x00000757,0x00000060,0x000500c7,0x00000039,0x0000075a,0x000008a0,0x000003e3, + 0x000500ab,0x00000011,0x0000075b,0x0000075a,0x00000060,0x000500a5,0x00000011,0x0000075c, + 0x00000758,0x0000075b,0x000300f7,0x00000760,0x00000000,0x000400fa,0x0000075c,0x0000075d, + 0x00000760,0x000200f8,0x0000075d,0x00050085,0x00000018,0x0000075f,0x00000945,0x000003e9, + 0x000200f9,0x00000760,0x000200f8,0x00000760,0x000700f5,0x00000018,0x000009e0,0x00000945, + 0x00000755,0x0000075f,0x0000075d,0x000500aa,0x00000011,0x00000762,0x000004e2,0x000000e5, + 0x00050050,0x00000013,0x00000a16,0x00000762,0x00000762,0x000600a9,0x0000000c,0x00000a17, + 0x00000a16,0x000004fb,0x000005eb,0x000500c7,0x00000039,0x00000767,0x000008a0,0x000003f2, + 0x000500ab,0x00000011,0x00000768,0x00000767,0x00000060,0x000500ab,0x00000011,0x0000076a, + 0x000004e2,0x000000f0,0x000500a7,0x00000011,0x0000076b,0x00000768,0x0000076a,0x000300f7, + 0x0000076d,0x00000000,0x000400fa,0x0000076b,0x0000076c,0x0000076d,0x000200f8,0x0000076c, + 0x000200f9,0x00000781,0x000200f8,0x0000076d,0x000200f9,0x0000076e,0x000200f8,0x0000076e, + 0x000700f5,0x00000018,0x000009dd,0x000009de,0x0000070d,0x000009e0,0x0000076d,0x000700f5, + 0x0000000c,0x000009d9,0x00000709,0x0000070d,0x000009dc,0x0000076d,0x000700f5,0x0000000c, + 0x000009c1,0x000005eb,0x0000070d,0x00000a17,0x0000076d,0x00050091,0x0000000c,0x00000771, + 0x00000796,0x000009c1,0x00050081,0x0000000c,0x00000773,0x00000771,0x000009d9,0x00050081, + 0x0000000c,0x00000775,0x00000773,0x0000050e,0x0007004f,0x0000000c,0x00000777,0x000009dd, + 0x000009dd,0x00000000,0x00000001,0x00050041,0x0000040a,0x00000778,0x00000408,0x00000409, + 0x0004003d,0x00000039,0x00000779,0x00000778,0x000500ab,0x00000011,0x0000077a,0x00000779, + 0x00000060,0x00050050,0x00000013,0x0000083a,0x0000077a,0x0000077a,0x000600a9,0x0000000c, + 0x0000077c,0x0000083a,0x00000404,0x00000777,0x00050051,0x00000006,0x0000077e,0x0000077c, + 0x00000000,0x00060052,0x00000018,0x00000892,0x0000077e,0x000009dd,0x00000000,0x00050051, + 0x00000006,0x00000780,0x0000077c,0x00000001,0x00060052,0x00000018,0x00000894,0x00000780, + 0x00000892,0x00000001,0x000200f9,0x00000781,0x000200f8,0x00000781,0x000900f5,0x00000018, + 0x00000a08,0x000009de,0x0000070c,0x000009e0,0x0000076c,0x00000894,0x0000076e,0x000900f5, + 0x0000000c,0x000009e2,0x000009f3,0x0000070c,0x000009f3,0x0000076c,0x00000775,0x0000076e, + 0x000900f5,0x00000011,0x000009e1,0x0000038e,0x0000070c,0x0000038e,0x0000076c,0x00000415, + 0x0000076e,0x0003003e,0x00000425,0x00000a08,0x000300f7,0x00000434,0x00000000,0x000400fa, + 0x000009e1,0x00000433,0x00000455,0x000200f8,0x00000433,0x00050080,0x00000039,0x00000438, + 0x00000502,0x000000b4,0x00060041,0x00000114,0x00000439,0x00000126,0x00000103,0x00000438, + 0x0004003d,0x000000f9,0x0000043a,0x00000439,0x0008004f,0x0000043e,0x00000440,0x0000043a, + 0x0000043a,0x00000001,0x00000002,0x00000003,0x0004007c,0x0000043b,0x00000441,0x00000440, + 0x00050051,0x00000006,0x00000444,0x00000441,0x00000000,0x0005008e,0x0000000c,0x00000445, + 0x000009e2,0x00000444,0x0007004f,0x0000000c,0x00000447,0x00000441,0x00000441,0x00000001, + 0x00000002,0x00050081,0x0000000c,0x00000448,0x00000445,0x00000447,0x00060041,0x0000044e, + 0x0000044f,0x00000408,0x0000044a,0x00000060,0x0004003d,0x00000006,0x00000450,0x0000044f, + 0x00060041,0x0000044e,0x00000452,0x00000408,0x0000044a,0x00000066,0x0004003d,0x00000006, + 0x00000453,0x00000452,0x00050051,0x00000006,0x0000083e,0x00000448,0x00000000,0x00050085, + 0x00000006,0x00000840,0x0000083e,0x00000450,0x00050083,0x00000006,0x00000841,0x00000840, + 0x00000055,0x00050051,0x00000006,0x00000843,0x00000448,0x00000001,0x00050085,0x00000006, + 0x00000845,0x00000843,0x00000453,0x0006000c,0x00000006,0x00000847,0x00000001,0x00000006, + 0x00000453,0x00050083,0x00000006,0x00000848,0x00000845,0x00000847,0x00070050,0x00000018, + 0x00000849,0x00000841,0x00000848,0x00000056,0x00000055,0x000200f9,0x00000434,0x000200f8, + 0x00000455,0x00050041,0x0000044e,0x00000457,0x00000408,0x00000456,0x0004003d,0x00000006, + 0x00000458,0x00000457,0x00070050,0x00000018,0x0000045f,0x00000458,0x00000458,0x00000458, + 0x00000458,0x000200f9,0x00000434,0x000200f8,0x00000434,0x000700f5,0x00000018,0x00000a09, + 0x00000849,0x00000433,0x0000045f,0x00000455,0x00050041,0x00000424,0x00000465,0x00000463, + 0x00000103,0x0003003e,0x00000465,0x00000a09,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas.webgpu_vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..7ef77100b89783d8b0a838c456ab78d75d6c2a83 GIT binary patch literal 16600 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 literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.h new file mode 100644 index 000000000..edbedbd29 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.h @@ -0,0 +1,157 @@ +#pragma once + +const uint32_t render_atlas_fill_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000001aa,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0008000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x000000d0,0x000000d2,0x000000d4, + 0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x0000003d,0x00004351,0x00030005,0x00000041,0x00003954,0x00030005, + 0x000000d0,0x00006771,0x00030005,0x000000d2,0x00000049,0x00060005,0x000000d4,0x465f6c67, + 0x746e6f72,0x69636146,0x0000676e,0x00030005,0x000000dc,0x0000424d,0x00040006,0x000000dc, + 0x00000000,0x00006250,0x00040006,0x000000dc,0x00000001,0x00006359,0x00040006,0x000000dc, + 0x00000002,0x00006552,0x00040006,0x000000dc,0x00000003,0x00006553,0x00040006,0x000000dc, + 0x00000004,0x0000366d,0x00040006,0x000000dc,0x00000005,0x0000676d,0x00040006,0x000000dc, + 0x00000006,0x00006544,0x00040006,0x000000dc,0x00000007,0x00006545,0x00040006,0x000000dc, + 0x00000008,0x00003755,0x00040006,0x000000dc,0x00000009,0x0000676a,0x00040006,0x000000dc, + 0x0000000a,0x0000635a,0x00040006,0x000000dc,0x0000000b,0x00003157,0x00040006,0x000000dc, + 0x0000000c,0x0000676e,0x00040006,0x000000dc,0x0000000d,0x00003559,0x00040006,0x000000dc, + 0x0000000e,0x0000324f,0x00040006,0x000000dc,0x0000000f,0x00006461,0x00040006,0x000000dc, + 0x00000010,0x00006579,0x00040006,0x000000dc,0x00000011,0x00003376,0x00040006,0x000000dc, + 0x00000012,0x00003377,0x00040006,0x000000dc,0x00000013,0x00006462,0x00040006,0x000000dc, + 0x00000014,0x00006767,0x00030005,0x000000de,0x0000006b,0x00030005,0x000000df,0x00004444, + 0x00030005,0x000000e0,0x00004344,0x00030005,0x000000e1,0x00006277,0x00030005,0x000000e2, + 0x00003552,0x00030047,0x0000003d,0x00000000,0x00040047,0x0000003d,0x00000021,0x0000000a, + 0x00040047,0x0000003d,0x00000022,0x00000000,0x00030047,0x00000041,0x00000000,0x00040047, + 0x00000041,0x00000021,0x0000000a,0x00040047,0x00000041,0x00000022,0x00000000,0x00040047, + 0x000000d0,0x0000001e,0x00000000,0x00040047,0x000000d2,0x0000001e,0x00000000,0x00040047, + 0x000000d4,0x0000000b,0x00000011,0x00030047,0x000000dc,0x00000002,0x00050048,0x000000dc, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000000dc,0x00000001,0x00000023,0x00000004, + 0x00050048,0x000000dc,0x00000002,0x00000023,0x00000008,0x00050048,0x000000dc,0x00000003, + 0x00000023,0x0000000c,0x00050048,0x000000dc,0x00000004,0x00000023,0x00000010,0x00050048, + 0x000000dc,0x00000005,0x00000023,0x00000014,0x00050048,0x000000dc,0x00000006,0x00000023, + 0x00000018,0x00050048,0x000000dc,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000dc, + 0x00000008,0x00000023,0x00000020,0x00050048,0x000000dc,0x00000009,0x00000023,0x00000030, + 0x00050048,0x000000dc,0x0000000a,0x00000023,0x00000038,0x00050048,0x000000dc,0x0000000b, + 0x00000023,0x00000040,0x00050048,0x000000dc,0x0000000c,0x00000023,0x00000044,0x00050048, + 0x000000dc,0x0000000d,0x00000023,0x00000048,0x00050048,0x000000dc,0x0000000e,0x00000023, + 0x0000004c,0x00050048,0x000000dc,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000dc, + 0x00000010,0x00000023,0x00000054,0x00050048,0x000000dc,0x00000011,0x00000023,0x00000058, + 0x00050048,0x000000dc,0x00000012,0x00000023,0x0000005c,0x00050048,0x000000dc,0x00000013, + 0x00000023,0x00000060,0x00050048,0x000000dc,0x00000014,0x00000023,0x00000064,0x00040047, + 0x000000de,0x00000021,0x00000000,0x00040047,0x000000de,0x00000022,0x00000000,0x00030047, + 0x000000df,0x00000000,0x00040047,0x000000df,0x00000021,0x00000009,0x00040047,0x000000df, + 0x00000022,0x00000000,0x00030047,0x000000e0,0x00000000,0x00040047,0x000000e0,0x00000021, + 0x0000000c,0x00040047,0x000000e0,0x00000022,0x00000001,0x00030047,0x000000e1,0x00000000, + 0x00040047,0x000000e1,0x00000021,0x00000009,0x00040047,0x000000e1,0x00000022,0x00000000, + 0x00030047,0x000000e2,0x00000000,0x00040047,0x000000e2,0x00000021,0x0000000c,0x00040047, + 0x000000e2,0x00000022,0x00000001,0x00030047,0x000000ed,0x00000000,0x00030047,0x0000010f, + 0x00000000,0x00030047,0x00000110,0x00000000,0x00030047,0x00000113,0x00000000,0x00030047, + 0x00000114,0x00000000,0x00030047,0x00000115,0x00000000,0x00030047,0x0000011a,0x00000000, + 0x00030047,0x00000127,0x00000000,0x00030047,0x00000128,0x00000000,0x00030047,0x0000012c, + 0x00000000,0x00030047,0x0000012d,0x00000000,0x00030047,0x0000012e,0x00000000,0x00030047, + 0x00000131,0x00000000,0x00030047,0x00000132,0x00000000,0x00030047,0x00000135,0x00000000, + 0x00030047,0x00000137,0x00000000,0x00030047,0x00000138,0x00000000,0x00030047,0x00000139, + 0x00000000,0x00030047,0x0000013a,0x00000000,0x00030047,0x0000013b,0x00000000,0x00030047, + 0x0000013e,0x00000000,0x00030047,0x0000013f,0x00000000,0x00030047,0x00000141,0x00000000, + 0x00030047,0x00000142,0x00000000,0x00030047,0x00000145,0x00000000,0x00030047,0x00000146, + 0x00000000,0x00030047,0x00000148,0x00000000,0x00030047,0x00000149,0x00000000,0x00030047, + 0x0000014c,0x00000000,0x00030047,0x0000014d,0x00000000,0x00030047,0x0000014f,0x00000000, + 0x00030047,0x00000150,0x00000000,0x00030047,0x00000153,0x00000000,0x00030047,0x00000154, + 0x00000000,0x00030047,0x0000015c,0x00000000,0x00030047,0x0000015e,0x00000000,0x00030047, + 0x00000160,0x00000000,0x00030047,0x00000162,0x00000000,0x00030047,0x00000163,0x00000000, + 0x00030047,0x00000166,0x00000000,0x00030047,0x00000168,0x00000000,0x00030047,0x0000016a, + 0x00000000,0x00030047,0x0000018f,0x00000000,0x00030047,0x00000191,0x00000000,0x00030047, + 0x00000193,0x00000000,0x00030047,0x00000195,0x00000000,0x00030047,0x0000019b,0x00000000, + 0x00030047,0x0000019d,0x00000000,0x00030047,0x0000019f,0x00000000,0x00030047,0x000001a1, + 0x00000000,0x00030047,0x000001a3,0x00000000,0x00030047,0x000001a7,0x00000000,0x00030047, + 0x000001a8,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000008,0x00000006,0x00000004,0x00020014,0x00000015, + 0x00040015,0x0000001e,0x00000020,0x00000000,0x0004002b,0x00000006,0x00000033,0x00000000, + 0x00090019,0x0000003b,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x0000003c,0x00000000,0x0000003b,0x0004003b,0x0000003c,0x0000003d, + 0x00000000,0x0002001a,0x0000003f,0x00040020,0x00000040,0x00000000,0x0000003f,0x0004003b, + 0x00000040,0x00000041,0x00000000,0x0003001b,0x00000043,0x0000003b,0x00040017,0x00000046, + 0x00000006,0x00000002,0x0004002b,0x00000006,0x0000004e,0x447a0000,0x0004002b,0x00000006, + 0x00000056,0x3e800000,0x0004002b,0x00000006,0x0000005c,0xc0000000,0x0004002b,0x00000006, + 0x00000062,0x3f19319f,0x0004002b,0x00000006,0x00000067,0x3e55e621,0x0004002b,0x00000006, + 0x00000068,0x3f206c99,0x0004002b,0x00000006,0x00000069,0x3f85afd5,0x0004002b,0x00000006, + 0x0000006a,0x3fbb295d,0x0004002b,0x00000006,0x000000a7,0x40a311dd,0x0004002b,0x00000006, + 0x000000a9,0xc02311dd,0x00040020,0x000000cf,0x00000003,0x00000006,0x0004003b,0x000000cf, + 0x000000d0,0x00000003,0x00040020,0x000000d1,0x00000001,0x00000008,0x0004003b,0x000000d1, + 0x000000d2,0x00000001,0x00040020,0x000000d3,0x00000001,0x00000015,0x0004003b,0x000000d3, + 0x000000d4,0x00000001,0x00040015,0x000000da,0x00000020,0x00000001,0x00040017,0x000000db, + 0x000000da,0x00000004,0x0017001e,0x000000dc,0x00000006,0x00000006,0x00000006,0x00000006, + 0x0000001e,0x0000001e,0x0000001e,0x0000001e,0x000000db,0x00000046,0x00000046,0x0000001e, + 0x00000006,0x0000001e,0x00000006,0x00000006,0x0000001e,0x00000006,0x00000006,0x00000006, + 0x0000001e,0x00040020,0x000000dd,0x00000002,0x000000dc,0x0004003b,0x000000dd,0x000000de, + 0x00000002,0x0004003b,0x0000003c,0x000000df,0x00000000,0x0004003b,0x0000003c,0x000000e0, + 0x00000000,0x0004003b,0x00000040,0x000000e1,0x00000000,0x0004003b,0x00000040,0x000000e2, + 0x00000000,0x00030001,0x00000008,0x000001a5,0x0007002c,0x00000008,0x000001a9,0x000000a9, + 0x000000a9,0x000000a9,0x000000a9,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003, + 0x000200f8,0x00000005,0x0004003d,0x00000008,0x000000d6,0x000000d2,0x0004003d,0x00000015, + 0x000000d8,0x000000d4,0x00050051,0x00000006,0x00000108,0x000000d6,0x00000002,0x00050051, + 0x00000006,0x0000010a,0x000000d6,0x00000003,0x0007000c,0x00000006,0x0000010b,0x00000001, + 0x00000028,0x0000010a,0x00000033,0x000500be,0x00000015,0x0000010d,0x00000108,0x00000033, + 0x000300f7,0x00000117,0x00000000,0x000400fa,0x0000010d,0x0000010e,0x00000116,0x000200f8, + 0x0000010e,0x0004003d,0x0000003b,0x0000010f,0x0000003d,0x0004003d,0x0000003f,0x00000110, + 0x00000041,0x00050056,0x00000043,0x00000111,0x0000010f,0x00000110,0x00050050,0x00000046, + 0x00000113,0x0000010b,0x00000033,0x00070058,0x00000008,0x00000114,0x00000111,0x00000113, + 0x00000002,0x00000033,0x00050051,0x00000006,0x00000115,0x00000114,0x00000000,0x000200f9, + 0x00000117,0x000200f8,0x00000116,0x000200f9,0x00000117,0x000200f8,0x00000117,0x000700f5, + 0x00000006,0x000001a3,0x00000115,0x0000010e,0x00000033,0x00000116,0x0006000c,0x00000006, + 0x0000011a,0x00000001,0x00000004,0x00000108,0x000500b8,0x00000015,0x0000011b,0x0000011a, + 0x0000004e,0x000300f7,0x0000016b,0x00000000,0x000400fa,0x0000011b,0x0000011c,0x0000016b, + 0x000200f8,0x0000011c,0x00050051,0x00000006,0x0000011e,0x000000d6,0x00000000,0x0006000c, + 0x00000006,0x0000011f,0x00000001,0x00000004,0x0000011e,0x00050083,0x00000006,0x00000120, + 0x0000011f,0x00000056,0x00050051,0x00000006,0x00000122,0x000000d6,0x00000001,0x0004007f, + 0x00000006,0x00000123,0x00000122,0x00050081,0x00000006,0x00000124,0x00000123,0x0000005c, + 0x00050083,0x00000006,0x00000127,0x00000124,0x0000010b,0x00050085,0x00000006,0x00000128, + 0x00000127,0x00000062,0x00060052,0x00000008,0x0000018f,0x00000067,0x000001a5,0x00000000, + 0x00060052,0x00000008,0x00000191,0x00000068,0x0000018f,0x00000001,0x00060052,0x00000008, + 0x00000193,0x00000069,0x00000191,0x00000002,0x00060052,0x00000008,0x00000195,0x0000006a, + 0x00000193,0x00000003,0x0005008e,0x00000008,0x0000012c,0x00000195,0x00000128,0x00070050, + 0x00000008,0x0000012d,0x0000010b,0x0000010b,0x0000010b,0x0000010b,0x00050081,0x00000008, + 0x0000012e,0x0000012d,0x0000012c,0x0004007f,0x00000006,0x00000131,0x00000108,0x0005008e, + 0x00000008,0x00000132,0x0000012e,0x00000131,0x00050085,0x00000006,0x00000135,0x00000124, + 0x00000108,0x00050081,0x00000006,0x00000137,0x00000135,0x00000120,0x00070050,0x00000008, + 0x00000138,0x00000137,0x00000137,0x00000137,0x00000137,0x00050081,0x00000008,0x00000139, + 0x00000132,0x00000138,0x0004003d,0x0000003b,0x0000013a,0x0000003d,0x0004003d,0x0000003f, + 0x0000013b,0x00000041,0x00050056,0x00000043,0x0000013c,0x0000013a,0x0000013b,0x00050051, + 0x00000006,0x0000013e,0x00000139,0x00000000,0x00050050,0x00000046,0x0000013f,0x0000013e, + 0x00000033,0x00070058,0x00000008,0x00000140,0x0000013c,0x0000013f,0x00000002,0x00000033, + 0x0004003d,0x0000003b,0x00000141,0x0000003d,0x0004003d,0x0000003f,0x00000142,0x00000041, + 0x00050056,0x00000043,0x00000143,0x00000141,0x00000142,0x00050051,0x00000006,0x00000145, + 0x00000139,0x00000001,0x00050050,0x00000046,0x00000146,0x00000145,0x00000033,0x00070058, + 0x00000008,0x00000147,0x00000143,0x00000146,0x00000002,0x00000033,0x0004003d,0x0000003b, + 0x00000148,0x0000003d,0x0004003d,0x0000003f,0x00000149,0x00000041,0x00050056,0x00000043, + 0x0000014a,0x00000148,0x00000149,0x00050051,0x00000006,0x0000014c,0x00000139,0x00000002, + 0x00050050,0x00000046,0x0000014d,0x0000014c,0x00000033,0x00070058,0x00000008,0x0000014e, + 0x0000014a,0x0000014d,0x00000002,0x00000033,0x0004003d,0x0000003b,0x0000014f,0x0000003d, + 0x0004003d,0x0000003f,0x00000150,0x00000041,0x00050056,0x00000043,0x00000151,0x0000014f, + 0x00000150,0x00050051,0x00000006,0x00000153,0x00000139,0x00000003,0x00050050,0x00000046, + 0x00000154,0x00000153,0x00000033,0x00070058,0x00000008,0x00000155,0x00000151,0x00000154, + 0x00000002,0x00000033,0x00050051,0x00000006,0x00000156,0x00000140,0x00000000,0x00050051, + 0x00000006,0x00000157,0x00000147,0x00000000,0x00050051,0x00000006,0x00000158,0x0000014e, + 0x00000000,0x00050051,0x00000006,0x00000159,0x00000155,0x00000000,0x00060052,0x00000008, + 0x0000019b,0x00000156,0x000001a5,0x00000000,0x00060052,0x00000008,0x0000019d,0x00000157, + 0x0000019b,0x00000001,0x00060052,0x00000008,0x0000019f,0x00000158,0x0000019d,0x00000002, + 0x00060052,0x00000008,0x000001a1,0x00000159,0x0000019f,0x00000003,0x0005008e,0x00000008, + 0x0000015c,0x0000012e,0x000000a7,0x00050081,0x00000008,0x0000015e,0x0000015c,0x000001a9, + 0x0004007f,0x00000008,0x00000160,0x0000015e,0x00050085,0x00000008,0x00000162,0x00000160, + 0x0000015e,0x0006000c,0x00000008,0x00000163,0x00000001,0x0000001d,0x00000162,0x00050094, + 0x00000006,0x00000166,0x000001a1,0x00000163,0x00050085,0x00000006,0x00000168,0x00000166, + 0x00000128,0x00050081,0x00000006,0x0000016a,0x000001a3,0x00000168,0x000200f9,0x0000016b, + 0x000200f8,0x0000016b,0x000700f5,0x00000006,0x000001a7,0x000001a3,0x00000117,0x0000016a, + 0x0000011c,0x00050051,0x00000006,0x0000016e,0x000000d6,0x00000000,0x0006000c,0x00000006, + 0x0000016f,0x00000001,0x00000006,0x0000016e,0x00050085,0x00000006,0x00000170,0x000001a7, + 0x0000016f,0x000400a8,0x00000015,0x000000ea,0x000000d8,0x000300f7,0x000000ee,0x00000000, + 0x000400fa,0x000000ea,0x000000eb,0x000000ee,0x000200f8,0x000000eb,0x0004007f,0x00000006, + 0x000000ed,0x00000170,0x000200f9,0x000000ee,0x000200f8,0x000000ee,0x000700f5,0x00000006, + 0x000001a8,0x00000170,0x0000016b,0x000000ed,0x000000eb,0x0003003e,0x000000d0,0x000001a8, + 0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..98355dc5254c0edd43b53e23ce081f93b3d2c2ff GIT binary patch literal 4872 zcmZ9P+iz4=6vj_)S}C{6O)la4YX7-v{>CWt&@B7x;Ywg?F`%GPJ z%Y#u=6E#JR(Z@AWsWeBmQX**&l%9#cp}wt!;@H+_+qdDcG^#84;j>Kb>h+|a8_ni1 z+*18o^;^~D^2MekLUoE9MPI04eY7Y_^d;kioyo%F=vZbpStw4=j!tBfsk!lS(dpDw zCS8UJY{T~vaa_tw1zu@}QBz~f;>c3c=v01();wRgy ze5rW<_9|Z{J~~$A%f&Cc{xpl9f2L}GSp0(HE5uW-{Yvo()3ZGR4|EyiB8n1V0sPr(NEzVNDVed%4;h_ed*>=Dn| zC(J41CN_JbR<&0>wEfW{PBE=U7>%_zjW%ekr)hOTV~tFs4SvkKY3vy^=F&9w4ca44 zWAC7Ca2om0VoqZZp>1;-bBVUgX^b1K!)f#tO-onl3wsK!*J@~DAPGgSH##C8P_8jX^FhdlFyf2Vc1NofoHIo7WRx z=EFF?H6>mb-P4nT4UDhFh5NYo#VPoL@wK>cd}~zMf4}QV0WU)gc)7zX9A4@0Du>rO z{Di};4sUVzX@|Eu+~)9hhuaF_RxcRT!?!+RXw@9+VK;|_N^-0g6W!@Uk4a=6do z!w&a5JmBzsw;@Mp_u9#?Oo0qIA_>Od92cNl^Ew~OqKGKI6k^EN@cCy ziakPTAywJncuZ~f1{L2uf!m$1PPq<9$FC#!!SRE~gSKA%Jy_Dq{p}GZFJrNO9TASA zSGtTJFY(v*8|VB{xoJEla;0tU0pq&rqD{XXtN2ffzn_a$>{;>eKDkukQ{pc^`B{Zu z6Tj1ZwZr1wDDjq?jO|Nd=AJ$?Hu$ZeVgE{)Ibw+E5{f3=&`ccnV z;H>9Q!f34LMy>E|J<07WYwIg*dO}6V*PaWpar$;geyjsI=o|cQ(BP~;=P||je2JBL zhw!}x{C?mynlT>mYF`*)vI+I_FeoWhyMA5@vc zqw-=rjf#s8aZFnjG~z8*e*BuG=@+%CV&{GMTrr5bM4UKif2kL1a8&tMIk7EOU9C#r z!1RUpg8P7X0?z*DPKfJyTyfd=&Eoi=4@m2g#$7>Q$Tbq?hC2gaY>We&jfFeJ?v#II zrEm0u{&%a^J=-d@6mm=+}!`f z#>e(B-vNFP^DPipKWz{16~_nN){Jii`%^sv%D7LxHQ&*V%iCD=E!R! z;`HBZC&h_PvG?GzI58K#Pki$b7rTBH|0^QI#!lZX4&Oq=$L`;!Q{wD>?q%Dzr^V5^ zLwIL+kIo3A^M1fn!lrQ!p{1qi7d;y6?}l@N??3WmxA$vO7`;{1-mfX)tE$*IYwi5w zX=m-V;Il?g{5PoDJm-ZMo{iJe^edfn*e(BzFtM;-*BH5%epThZ<2?RDPYUNT`fsXe moX220OZdM+Ec$D9p4Q*%vSDWo_|kU2;`3dD?LYNym+Jo?aF=NS literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.h new file mode 100644 index 000000000..dca93db36 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.h @@ -0,0 +1,150 @@ +#pragma once + +const uint32_t render_atlas_fill_webgpu_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x000001af,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0008000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x000000d0,0x000000d2,0x000000d4, + 0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47, + 0x735f4252,0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365, + 0x000b0004,0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572, + 0x74636e75,0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70, + 0x5f656c79,0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f, + 0x6e695f45,0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00030005,0x0000003d,0x00004351,0x00030005,0x00000041,0x00003954,0x00030005, + 0x000000d0,0x00006771,0x00030005,0x000000d2,0x00000049,0x00060005,0x000000d4,0x465f6c67, + 0x746e6f72,0x69636146,0x0000676e,0x00030005,0x000000dc,0x0000424d,0x00040006,0x000000dc, + 0x00000000,0x00006250,0x00040006,0x000000dc,0x00000001,0x00006359,0x00040006,0x000000dc, + 0x00000002,0x00006552,0x00040006,0x000000dc,0x00000003,0x00006553,0x00040006,0x000000dc, + 0x00000004,0x0000366d,0x00040006,0x000000dc,0x00000005,0x0000676d,0x00040006,0x000000dc, + 0x00000006,0x00006544,0x00040006,0x000000dc,0x00000007,0x00006545,0x00040006,0x000000dc, + 0x00000008,0x00003755,0x00040006,0x000000dc,0x00000009,0x0000676a,0x00040006,0x000000dc, + 0x0000000a,0x0000635a,0x00040006,0x000000dc,0x0000000b,0x00003157,0x00040006,0x000000dc, + 0x0000000c,0x0000676e,0x00040006,0x000000dc,0x0000000d,0x00003559,0x00040006,0x000000dc, + 0x0000000e,0x0000324f,0x00040006,0x000000dc,0x0000000f,0x00006461,0x00040006,0x000000dc, + 0x00000010,0x00006579,0x00040006,0x000000dc,0x00000011,0x00003376,0x00040006,0x000000dc, + 0x00000012,0x00003377,0x00040006,0x000000dc,0x00000013,0x00006462,0x00040006,0x000000dc, + 0x00000014,0x00006767,0x00030005,0x000000de,0x0000006b,0x00030005,0x000000df,0x00004444, + 0x00030005,0x000000e0,0x00004344,0x00030005,0x000000e1,0x00006277,0x00030005,0x000000e2, + 0x00003552,0x00030047,0x0000003d,0x00000000,0x00040047,0x0000003d,0x00000021,0x0000000a, + 0x00040047,0x0000003d,0x00000022,0x00000000,0x00030047,0x00000041,0x00000000,0x00040047, + 0x00000041,0x00000021,0x0000000a,0x00040047,0x00000041,0x00000022,0x00000003,0x00040047, + 0x000000d0,0x0000001e,0x00000000,0x00040047,0x000000d2,0x0000001e,0x00000000,0x00040047, + 0x000000d4,0x0000000b,0x00000011,0x00030047,0x000000dc,0x00000002,0x00050048,0x000000dc, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000000dc,0x00000001,0x00000023,0x00000004, + 0x00050048,0x000000dc,0x00000002,0x00000023,0x00000008,0x00050048,0x000000dc,0x00000003, + 0x00000023,0x0000000c,0x00050048,0x000000dc,0x00000004,0x00000023,0x00000010,0x00050048, + 0x000000dc,0x00000005,0x00000023,0x00000014,0x00050048,0x000000dc,0x00000006,0x00000023, + 0x00000018,0x00050048,0x000000dc,0x00000007,0x00000023,0x0000001c,0x00050048,0x000000dc, + 0x00000008,0x00000023,0x00000020,0x00050048,0x000000dc,0x00000009,0x00000023,0x00000030, + 0x00050048,0x000000dc,0x0000000a,0x00000023,0x00000038,0x00050048,0x000000dc,0x0000000b, + 0x00000023,0x00000040,0x00050048,0x000000dc,0x0000000c,0x00000023,0x00000044,0x00050048, + 0x000000dc,0x0000000d,0x00000023,0x00000048,0x00050048,0x000000dc,0x0000000e,0x00000023, + 0x0000004c,0x00050048,0x000000dc,0x0000000f,0x00000023,0x00000050,0x00050048,0x000000dc, + 0x00000010,0x00000023,0x00000054,0x00050048,0x000000dc,0x00000011,0x00000023,0x00000058, + 0x00050048,0x000000dc,0x00000012,0x00000023,0x0000005c,0x00050048,0x000000dc,0x00000013, + 0x00000023,0x00000060,0x00050048,0x000000dc,0x00000014,0x00000023,0x00000064,0x00040047, + 0x000000de,0x00000021,0x00000000,0x00040047,0x000000de,0x00000022,0x00000000,0x00030047, + 0x000000df,0x00000000,0x00040047,0x000000df,0x00000021,0x00000009,0x00040047,0x000000df, + 0x00000022,0x00000000,0x00030047,0x000000e0,0x00000000,0x00040047,0x000000e0,0x00000021, + 0x0000000c,0x00040047,0x000000e0,0x00000022,0x00000001,0x00030047,0x000000e1,0x00000000, + 0x00040047,0x000000e1,0x00000021,0x00000009,0x00040047,0x000000e1,0x00000022,0x00000003, + 0x00030047,0x000000e2,0x00000000,0x00040047,0x000000e2,0x00000021,0x0000000e,0x00040047, + 0x000000e2,0x00000022,0x00000001,0x00030047,0x000000ed,0x00000000,0x00030047,0x0000010f, + 0x00000000,0x00030047,0x00000110,0x00000000,0x00030047,0x00000113,0x00000000,0x00030047, + 0x00000114,0x00000000,0x00030047,0x00000115,0x00000000,0x00030047,0x0000011a,0x00000000, + 0x00030047,0x00000127,0x00000000,0x00030047,0x00000128,0x00000000,0x00030047,0x0000012c, + 0x00000000,0x00030047,0x0000012d,0x00000000,0x00030047,0x0000012e,0x00000000,0x00030047, + 0x00000131,0x00000000,0x00030047,0x00000132,0x00000000,0x00030047,0x00000135,0x00000000, + 0x00030047,0x00000137,0x00000000,0x00030047,0x00000138,0x00000000,0x00030047,0x00000139, + 0x00000000,0x00030047,0x0000013a,0x00000000,0x00030047,0x0000013b,0x00000000,0x00030047, + 0x0000013e,0x00000000,0x00030047,0x0000013f,0x00000000,0x00030047,0x00000141,0x00000000, + 0x00030047,0x00000142,0x00000000,0x00030047,0x00000145,0x00000000,0x00030047,0x00000146, + 0x00000000,0x00030047,0x00000148,0x00000000,0x00030047,0x00000149,0x00000000,0x00030047, + 0x0000014c,0x00000000,0x00030047,0x0000014d,0x00000000,0x00030047,0x0000014f,0x00000000, + 0x00030047,0x00000150,0x00000000,0x00030047,0x00000153,0x00000000,0x00030047,0x00000154, + 0x00000000,0x00030047,0x0000015c,0x00000000,0x00030047,0x0000015e,0x00000000,0x00030047, + 0x00000160,0x00000000,0x00030047,0x00000162,0x00000000,0x00030047,0x00000163,0x00000000, + 0x00030047,0x00000166,0x00000000,0x00030047,0x00000168,0x00000000,0x00030047,0x0000016a, + 0x00000000,0x00030047,0x000001a3,0x00000000,0x00030047,0x000001a7,0x00000000,0x00030047, + 0x000001a8,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000008,0x00000006,0x00000004,0x00020014,0x00000015, + 0x00040015,0x0000001e,0x00000020,0x00000000,0x0004002b,0x00000006,0x00000033,0x00000000, + 0x00090019,0x0000003b,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001, + 0x00000000,0x00040020,0x0000003c,0x00000000,0x0000003b,0x0004003b,0x0000003c,0x0000003d, + 0x00000000,0x0002001a,0x0000003f,0x00040020,0x00000040,0x00000000,0x0000003f,0x0004003b, + 0x00000040,0x00000041,0x00000000,0x0003001b,0x00000043,0x0000003b,0x00040017,0x00000046, + 0x00000006,0x00000002,0x0004002b,0x00000006,0x0000004e,0x447a0000,0x0004002b,0x00000006, + 0x00000056,0x3e800000,0x0004002b,0x00000006,0x0000005c,0xc0000000,0x0004002b,0x00000006, + 0x00000062,0x3f19319f,0x0004002b,0x00000006,0x00000067,0x3e55e621,0x0004002b,0x00000006, + 0x00000068,0x3f206c99,0x0004002b,0x00000006,0x00000069,0x3f85afd5,0x0004002b,0x00000006, + 0x0000006a,0x3fbb295d,0x0004002b,0x00000006,0x000000a7,0x40a311dd,0x0004002b,0x00000006, + 0x000000a9,0xc02311dd,0x00040020,0x000000cf,0x00000003,0x00000006,0x0004003b,0x000000cf, + 0x000000d0,0x00000003,0x00040020,0x000000d1,0x00000001,0x00000008,0x0004003b,0x000000d1, + 0x000000d2,0x00000001,0x00040020,0x000000d3,0x00000001,0x00000015,0x0004003b,0x000000d3, + 0x000000d4,0x00000001,0x00040015,0x000000da,0x00000020,0x00000001,0x00040017,0x000000db, + 0x000000da,0x00000004,0x0017001e,0x000000dc,0x00000006,0x00000006,0x00000006,0x00000006, + 0x0000001e,0x0000001e,0x0000001e,0x0000001e,0x000000db,0x00000046,0x00000046,0x0000001e, + 0x00000006,0x0000001e,0x00000006,0x00000006,0x0000001e,0x00000006,0x00000006,0x00000006, + 0x0000001e,0x00040020,0x000000dd,0x00000002,0x000000dc,0x0004003b,0x000000dd,0x000000de, + 0x00000002,0x0004003b,0x0000003c,0x000000df,0x00000000,0x0004003b,0x0000003c,0x000000e0, + 0x00000000,0x0004003b,0x00000040,0x000000e1,0x00000000,0x0004003b,0x00000040,0x000000e2, + 0x00000000,0x0007002c,0x00000008,0x000001a9,0x000000a9,0x000000a9,0x000000a9,0x000000a9, + 0x0004002b,0x00000006,0x000001ac,0x402311dd,0x0007002c,0x00000008,0x000001ad,0x000001ac, + 0x000001ac,0x000001ac,0x000001ac,0x0007002c,0x00000008,0x000001ae,0x00000067,0x00000068, + 0x00000069,0x0000006a,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8, + 0x00000005,0x0004003d,0x00000008,0x000000d6,0x000000d2,0x0004003d,0x00000015,0x000000d8, + 0x000000d4,0x00050051,0x00000006,0x00000108,0x000000d6,0x00000002,0x00050051,0x00000006, + 0x0000010a,0x000000d6,0x00000003,0x0007000c,0x00000006,0x0000010b,0x00000001,0x00000028, + 0x0000010a,0x00000033,0x000500be,0x00000015,0x0000010d,0x00000108,0x00000033,0x000300f7, + 0x00000117,0x00000000,0x000400fa,0x0000010d,0x0000010e,0x00000116,0x000200f8,0x0000010e, + 0x0004003d,0x0000003b,0x0000010f,0x0000003d,0x0004003d,0x0000003f,0x00000110,0x00000041, + 0x00050056,0x00000043,0x00000111,0x0000010f,0x00000110,0x00050050,0x00000046,0x00000113, + 0x0000010b,0x00000033,0x00070058,0x00000008,0x00000114,0x00000111,0x00000113,0x00000002, + 0x00000033,0x00050051,0x00000006,0x00000115,0x00000114,0x00000000,0x000200f9,0x00000117, + 0x000200f8,0x00000116,0x000200f9,0x00000117,0x000200f8,0x00000117,0x000700f5,0x00000006, + 0x000001a3,0x00000115,0x0000010e,0x00000033,0x00000116,0x0006000c,0x00000006,0x0000011a, + 0x00000001,0x00000004,0x00000108,0x000500b8,0x00000015,0x0000011b,0x0000011a,0x0000004e, + 0x000300f7,0x0000016b,0x00000000,0x000400fa,0x0000011b,0x0000011c,0x0000016b,0x000200f8, + 0x0000011c,0x00050051,0x00000006,0x0000011e,0x000000d6,0x00000000,0x0006000c,0x00000006, + 0x0000011f,0x00000001,0x00000004,0x0000011e,0x00050083,0x00000006,0x00000120,0x0000011f, + 0x00000056,0x00050051,0x00000006,0x00000122,0x000000d6,0x00000001,0x00050083,0x00000006, + 0x00000124,0x0000005c,0x00000122,0x00050083,0x00000006,0x00000127,0x00000124,0x0000010b, + 0x00050085,0x00000006,0x00000128,0x00000127,0x00000062,0x0005008e,0x00000008,0x0000012c, + 0x000001ae,0x00000128,0x00070050,0x00000008,0x0000012d,0x0000010b,0x0000010b,0x0000010b, + 0x0000010b,0x00050081,0x00000008,0x0000012e,0x0000012d,0x0000012c,0x0004007f,0x00000006, + 0x00000131,0x00000108,0x0005008e,0x00000008,0x00000132,0x0000012e,0x00000131,0x00050085, + 0x00000006,0x00000135,0x00000124,0x00000108,0x00050081,0x00000006,0x00000137,0x00000135, + 0x00000120,0x00070050,0x00000008,0x00000138,0x00000137,0x00000137,0x00000137,0x00000137, + 0x00050081,0x00000008,0x00000139,0x00000132,0x00000138,0x0004003d,0x0000003b,0x0000013a, + 0x0000003d,0x0004003d,0x0000003f,0x0000013b,0x00000041,0x00050056,0x00000043,0x0000013c, + 0x0000013a,0x0000013b,0x00050051,0x00000006,0x0000013e,0x00000139,0x00000000,0x00050050, + 0x00000046,0x0000013f,0x0000013e,0x00000033,0x00070058,0x00000008,0x00000140,0x0000013c, + 0x0000013f,0x00000002,0x00000033,0x0004003d,0x0000003b,0x00000141,0x0000003d,0x0004003d, + 0x0000003f,0x00000142,0x00000041,0x00050056,0x00000043,0x00000143,0x00000141,0x00000142, + 0x00050051,0x00000006,0x00000145,0x00000139,0x00000001,0x00050050,0x00000046,0x00000146, + 0x00000145,0x00000033,0x00070058,0x00000008,0x00000147,0x00000143,0x00000146,0x00000002, + 0x00000033,0x0004003d,0x0000003b,0x00000148,0x0000003d,0x0004003d,0x0000003f,0x00000149, + 0x00000041,0x00050056,0x00000043,0x0000014a,0x00000148,0x00000149,0x00050051,0x00000006, + 0x0000014c,0x00000139,0x00000002,0x00050050,0x00000046,0x0000014d,0x0000014c,0x00000033, + 0x00070058,0x00000008,0x0000014e,0x0000014a,0x0000014d,0x00000002,0x00000033,0x0004003d, + 0x0000003b,0x0000014f,0x0000003d,0x0004003d,0x0000003f,0x00000150,0x00000041,0x00050056, + 0x00000043,0x00000151,0x0000014f,0x00000150,0x00050051,0x00000006,0x00000153,0x00000139, + 0x00000003,0x00050050,0x00000046,0x00000154,0x00000153,0x00000033,0x00070058,0x00000008, + 0x00000155,0x00000151,0x00000154,0x00000002,0x00000033,0x00050051,0x00000006,0x00000156, + 0x00000140,0x00000000,0x00050051,0x00000006,0x00000157,0x00000147,0x00000000,0x00050051, + 0x00000006,0x00000158,0x0000014e,0x00000000,0x00050051,0x00000006,0x00000159,0x00000155, + 0x00000000,0x00070050,0x00000008,0x000001ab,0x00000156,0x00000157,0x00000158,0x00000159, + 0x0005008e,0x00000008,0x0000015c,0x0000012e,0x000000a7,0x00050081,0x00000008,0x0000015e, + 0x0000015c,0x000001a9,0x00050083,0x00000008,0x00000160,0x000001ad,0x0000015c,0x00050085, + 0x00000008,0x00000162,0x00000160,0x0000015e,0x0006000c,0x00000008,0x00000163,0x00000001, + 0x0000001d,0x00000162,0x00050094,0x00000006,0x00000166,0x000001ab,0x00000163,0x00050085, + 0x00000006,0x00000168,0x00000166,0x00000128,0x00050081,0x00000006,0x0000016a,0x000001a3, + 0x00000168,0x000200f9,0x0000016b,0x000200f8,0x0000016b,0x000700f5,0x00000006,0x000001a7, + 0x000001a3,0x00000117,0x0000016a,0x0000011c,0x00050051,0x00000006,0x0000016e,0x000000d6, + 0x00000000,0x0006000c,0x00000006,0x0000016f,0x00000001,0x00000006,0x0000016e,0x00050085, + 0x00000006,0x00000170,0x000001a7,0x0000016f,0x000400a8,0x00000015,0x000000ea,0x000000d8, + 0x000300f7,0x000000ee,0x00000000,0x000400fa,0x000000ea,0x000000eb,0x000000ee,0x000200f8, + 0x000000eb,0x0004007f,0x00000006,0x000000ed,0x00000170,0x000200f9,0x000000ee,0x000200f8, + 0x000000ee,0x000700f5,0x00000006,0x000001a8,0x00000170,0x0000016b,0x000000ed,0x000000eb, + 0x0003003e,0x000000d0,0x000001a8,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_fill.webgpu_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..0f4e535876c3cbefd27e9e7323276cbbdc17f190 GIT binary patch literal 4660 zcmZ9O&2N-d6vp4S6e|TvrGP-iftpxjX#fR^KS1wopL1b%UV)z40#LpO|SXj8w=+5|&nE3o=-ZOL3o4L8q^PF?czeDu(f;!OJvginYKngNG^pPywba@1Ob)|+ z)vr~*Rox(8YziV&qmhH)3w2x-tO;WAMD$d5B0oJokzPpT3v&zOQ|Ux(7VQtLV;9xA?mq^XeYs{M}(^~dM;Jr?AIyH+5Fl0(~cMC zd7xsim3>yR%zw3buk+^|`W&wlKXb6+|D^bg>%T_)H8-Dn@w0m?{%gfqo5fover|t- zuNNQOSK$rf;}aFWLHw$lPowzdmn!zB#IHEMQ9SATH;GRvKIigK_>wC4XSKb(CARTaF!;f)SAIlRf?Z4N*0 zaI3>@4)1oj-Qm3s?{j#+!v`JiaQKkJuQ+_z;ZBE-IUIGk+u=Tk`yC!|__)Jyhfg>> z=Ojw6vszbda-O()*co@3qzF*jz`qzNT}j_IOKL`Z&R#e z((&sG{owe)qoKB4^X)0>rTO*?6PLBvyiN)S!CSq?M~nQOPUGAUD))>hMLycQ^_X!z zMZwNr&XoP9#XrnO%Jz)-cXzLq`HcAMFML+!H^i43uXovaw~D;w9&7tjn7wDttPOrY z)Ubag%pP(M*x|f4XxP6AG3SCE&ijL%bNW$jB;=guPr_)N=MJ6l1GU8Vm9zDgKK)@u z$Jg4G*f?`rk{{2qHs=sOW|!jDwX)(t8yN2&fo`C_J3Gj z>_wf%#fNcBTN7%Gw^r-GuU?vdL8~fuzNODK24k)hXB@P@G>a`bs{E^%*w(9VR%LEr z=E66{UC;Lf=iA}FkE$KjxO_8>;`pEsN$Z!!JHT9sH5TqM?*YEpSO+#+3-5!y7yro0 z+?WUR@f`inaIM@+^kc4!h3{JJ0{g%lqn~D6TJxvj9&DG0jc=JfxP+4mdw{K36^+cunmR#yIYukzP=m!w@b%Pzqd7G=E?g>KG>MNq4=R&Y~E7lgCAqjk2e*a zby{rRR&-x2Hg7Fs<6}9+o9lCmcQ>lBEvJr%w&fY`GP=*RE^+!}vplo7 zyxl%-w|LaW?SZSJTU_3C;_6qRI6mkWm;V{W#UOOkw*c8jJ+v1GL81%u%^7gzidCU7~Id?%EoqL^ci*M$l@SRX6 zztNK7==k$pqosuP3!Vw>AB1_&e!u^K+n<^Uf0oz@` he|yGazGkPj`QDTbJ8Qs~zMUGM{}|Z*)9gA_{|BJ2ipBr{ literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.h new file mode 100644 index 000000000..2dcd7a806 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.h @@ -0,0 +1,83 @@ +#pragma once + +const uint32_t render_atlas_stroke_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000006a,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000003d,0x0000003f,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x00000019,0x00004351,0x00030005,0x0000001d,0x00003954,0x00030005,0x0000003d, + 0x00006771,0x00030005,0x0000003f,0x00000049,0x00030005,0x00000045,0x0000424d,0x00040006, + 0x00000045,0x00000000,0x00006250,0x00040006,0x00000045,0x00000001,0x00006359,0x00040006, + 0x00000045,0x00000002,0x00006552,0x00040006,0x00000045,0x00000003,0x00006553,0x00040006, + 0x00000045,0x00000004,0x0000366d,0x00040006,0x00000045,0x00000005,0x0000676d,0x00040006, + 0x00000045,0x00000006,0x00006544,0x00040006,0x00000045,0x00000007,0x00006545,0x00040006, + 0x00000045,0x00000008,0x00003755,0x00040006,0x00000045,0x00000009,0x0000676a,0x00040006, + 0x00000045,0x0000000a,0x0000635a,0x00040006,0x00000045,0x0000000b,0x00003157,0x00040006, + 0x00000045,0x0000000c,0x0000676e,0x00040006,0x00000045,0x0000000d,0x00003559,0x00040006, + 0x00000045,0x0000000e,0x0000324f,0x00040006,0x00000045,0x0000000f,0x00006461,0x00040006, + 0x00000045,0x00000010,0x00006579,0x00040006,0x00000045,0x00000011,0x00003376,0x00040006, + 0x00000045,0x00000012,0x00003377,0x00040006,0x00000045,0x00000013,0x00006462,0x00040006, + 0x00000045,0x00000014,0x00006767,0x00030005,0x00000047,0x0000006b,0x00030005,0x00000048, + 0x00004444,0x00030005,0x00000049,0x00004344,0x00030005,0x0000004a,0x00006277,0x00030005, + 0x0000004b,0x00003552,0x00030047,0x00000019,0x00000000,0x00040047,0x00000019,0x00000021, + 0x0000000a,0x00040047,0x00000019,0x00000022,0x00000000,0x00030047,0x0000001d,0x00000000, + 0x00040047,0x0000001d,0x00000021,0x0000000a,0x00040047,0x0000001d,0x00000022,0x00000000, + 0x00040047,0x0000003d,0x0000001e,0x00000000,0x00040047,0x0000003f,0x0000001e,0x00000000, + 0x00030047,0x00000045,0x00000002,0x00050048,0x00000045,0x00000000,0x00000023,0x00000000, + 0x00050048,0x00000045,0x00000001,0x00000023,0x00000004,0x00050048,0x00000045,0x00000002, + 0x00000023,0x00000008,0x00050048,0x00000045,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x00000045,0x00000004,0x00000023,0x00000010,0x00050048,0x00000045,0x00000005,0x00000023, + 0x00000014,0x00050048,0x00000045,0x00000006,0x00000023,0x00000018,0x00050048,0x00000045, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x00000045,0x00000008,0x00000023,0x00000020, + 0x00050048,0x00000045,0x00000009,0x00000023,0x00000030,0x00050048,0x00000045,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x00000045,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x00000045,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000045,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x00000045,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000045, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x00000045,0x00000010,0x00000023,0x00000054, + 0x00050048,0x00000045,0x00000011,0x00000023,0x00000058,0x00050048,0x00000045,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x00000045,0x00000013,0x00000023,0x00000060,0x00050048, + 0x00000045,0x00000014,0x00000023,0x00000064,0x00040047,0x00000047,0x00000021,0x00000000, + 0x00040047,0x00000047,0x00000022,0x00000000,0x00030047,0x00000048,0x00000000,0x00040047, + 0x00000048,0x00000021,0x00000009,0x00040047,0x00000048,0x00000022,0x00000000,0x00030047, + 0x00000049,0x00000000,0x00040047,0x00000049,0x00000021,0x0000000c,0x00040047,0x00000049, + 0x00000022,0x00000001,0x00030047,0x0000004a,0x00000000,0x00040047,0x0000004a,0x00000021, + 0x00000009,0x00040047,0x0000004a,0x00000022,0x00000000,0x00030047,0x0000004b,0x00000000, + 0x00040047,0x0000004b,0x00000021,0x0000000c,0x00040047,0x0000004b,0x00000022,0x00000001, + 0x00030047,0x00000055,0x00000000,0x00030047,0x00000056,0x00000000,0x00030047,0x00000061, + 0x00000000,0x00030047,0x00000062,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004, + 0x0004002b,0x00000006,0x0000000f,0x3f800000,0x0004002b,0x00000006,0x00000011,0x40400000, + 0x00040015,0x00000012,0x00000020,0x00000000,0x00090019,0x00000017,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000018,0x00000000, + 0x00000017,0x0004003b,0x00000018,0x00000019,0x00000000,0x0002001a,0x0000001b,0x00040020, + 0x0000001c,0x00000000,0x0000001b,0x0004003b,0x0000001c,0x0000001d,0x00000000,0x0003001b, + 0x0000001f,0x00000017,0x0004002b,0x00000006,0x00000022,0x00000000,0x00040017,0x00000023, + 0x00000006,0x00000002,0x00040020,0x0000003c,0x00000003,0x00000006,0x0004003b,0x0000003c, + 0x0000003d,0x00000003,0x00040020,0x0000003e,0x00000001,0x00000007,0x0004003b,0x0000003e, + 0x0000003f,0x00000001,0x00040015,0x00000043,0x00000020,0x00000001,0x00040017,0x00000044, + 0x00000043,0x00000004,0x0017001e,0x00000045,0x00000006,0x00000006,0x00000006,0x00000006, + 0x00000012,0x00000012,0x00000012,0x00000012,0x00000044,0x00000023,0x00000023,0x00000012, + 0x00000006,0x00000012,0x00000006,0x00000006,0x00000012,0x00000006,0x00000006,0x00000006, + 0x00000012,0x00040020,0x00000046,0x00000002,0x00000045,0x0004003b,0x00000046,0x00000047, + 0x00000002,0x0004003b,0x00000018,0x00000048,0x00000000,0x0004003b,0x00000018,0x00000049, + 0x00000000,0x0004003b,0x0000001c,0x0000004a,0x00000000,0x0004003b,0x0000001c,0x0000004b, + 0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003d,0x00000007,0x00000041,0x0000003f,0x00050051,0x00000006,0x00000053,0x00000041, + 0x00000000,0x00050081,0x00000006,0x00000054,0x00000011,0x00000053,0x0004003d,0x00000017, + 0x00000055,0x00000019,0x0004003d,0x0000001b,0x00000056,0x0000001d,0x00050056,0x0000001f, + 0x00000057,0x00000055,0x00000056,0x00050050,0x00000023,0x00000059,0x00000054,0x00000022, + 0x00070058,0x00000007,0x0000005a,0x00000057,0x00000059,0x00000002,0x00000022,0x00050051, + 0x00000006,0x0000005b,0x0000005a,0x00000000,0x00050083,0x00000006,0x0000005d,0x0000000f, + 0x0000005b,0x00050051,0x00000006,0x0000005f,0x00000041,0x00000001,0x00050083,0x00000006, + 0x00000060,0x0000000f,0x0000005f,0x0004003d,0x00000017,0x00000061,0x00000019,0x0004003d, + 0x0000001b,0x00000062,0x0000001d,0x00050056,0x0000001f,0x00000063,0x00000061,0x00000062, + 0x00050050,0x00000023,0x00000065,0x00000060,0x00000022,0x00070058,0x00000007,0x00000066, + 0x00000063,0x00000065,0x00000002,0x00000022,0x00050051,0x00000006,0x00000067,0x00000066, + 0x00000000,0x00050083,0x00000006,0x00000069,0x0000005d,0x00000067,0x0003003e,0x0000003d, + 0x00000069,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..7ebe2eb76c91ad06ad2b1b08e2a2841004af4460 GIT binary patch literal 2508 zcmZ9MSyNL%5QPU41VzDpUjjZ_MY%7fxIqkRELH_v>XPMx!4NPBE^k`?J%5ldR(ZbM z+uSavYBGIJpPA|D?wefy<-rj8!f+T0n;{uTLcf?GZeMRLl^4qsoo;>N=B=wJMnbM9 zL^B!&LtZO$tI}xUnACivd00AlT_7u`Q$zTzP5E#jl*-YQg{M*HW2GLqqfU3bUD=4E z>hAiw;C6L0u63mwMps-}iaM38oo3u_#+^>ojlXqw+i|qM+p2XN+pUg{wKGezv!!w| zs_pFP%S<8+@;zHH%vCc?-d1ZFCNB$$&Gck<(cxY^w=@5M{9C%$^!tRT zot}Ib9Uc;XeJ9iJ7v6OH4+y_?@eB(uU(56dgq47Aw(T(Cd) zH9`&g`b}c??25CiseMfU(*3f>q|Ir?J}HadDQKS3ee?{NzPqAdZ0Z!kk4J{7hq~bL z3Hhl*0jP0CnL4GFJ$(>v7%pfJJ<33PKgIU_o>f%m#G|8c8DMl^`*zPM?n}a)VR4Zc z2JfKe#K9Xm>w#9@498jE$&|zYP&P60e*9p*bvWKRrL~Y^&Zpnu$kRpL$hXhgev%tM z*+X1Rc(k_uZyP4IXVUQw?jSZWeGCUqzIg$MtvB(LH|syc)?>Hzzr{JcgOStxBZmK& zNwMVPi6*(27fW1=DW@g;OgX++`T`&Os0+PGUBT3l{-l0yw1?U)YodXl6GvWFH92cs zb49mv|65J8_=pvs#qv%ze#WmfmJhP&S$w98Wb+Q{X}UGp=X#CJ9S0aFsGPXGV_ literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.h new file mode 100644 index 000000000..8e647ec0e --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.h @@ -0,0 +1,83 @@ +#pragma once + +const uint32_t render_atlas_stroke_webgpu_frag[] = { + 0x07230203,0x00010000,0x0008000b,0x0000006a,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000003d,0x0000003f,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252, + 0x65646168,0x74735f72,0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004, + 0x455f4c47,0x735f5458,0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75, + 0x736e6f69,0x00000000,0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79, + 0x656e696c,0x7269645f,0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45, + 0x64756c63,0x69645f65,0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000, + 0x00030005,0x00000019,0x00004351,0x00030005,0x0000001d,0x00003954,0x00030005,0x0000003d, + 0x00006771,0x00030005,0x0000003f,0x00000049,0x00030005,0x00000045,0x0000424d,0x00040006, + 0x00000045,0x00000000,0x00006250,0x00040006,0x00000045,0x00000001,0x00006359,0x00040006, + 0x00000045,0x00000002,0x00006552,0x00040006,0x00000045,0x00000003,0x00006553,0x00040006, + 0x00000045,0x00000004,0x0000366d,0x00040006,0x00000045,0x00000005,0x0000676d,0x00040006, + 0x00000045,0x00000006,0x00006544,0x00040006,0x00000045,0x00000007,0x00006545,0x00040006, + 0x00000045,0x00000008,0x00003755,0x00040006,0x00000045,0x00000009,0x0000676a,0x00040006, + 0x00000045,0x0000000a,0x0000635a,0x00040006,0x00000045,0x0000000b,0x00003157,0x00040006, + 0x00000045,0x0000000c,0x0000676e,0x00040006,0x00000045,0x0000000d,0x00003559,0x00040006, + 0x00000045,0x0000000e,0x0000324f,0x00040006,0x00000045,0x0000000f,0x00006461,0x00040006, + 0x00000045,0x00000010,0x00006579,0x00040006,0x00000045,0x00000011,0x00003376,0x00040006, + 0x00000045,0x00000012,0x00003377,0x00040006,0x00000045,0x00000013,0x00006462,0x00040006, + 0x00000045,0x00000014,0x00006767,0x00030005,0x00000047,0x0000006b,0x00030005,0x00000048, + 0x00004444,0x00030005,0x00000049,0x00004344,0x00030005,0x0000004a,0x00006277,0x00030005, + 0x0000004b,0x00003552,0x00030047,0x00000019,0x00000000,0x00040047,0x00000019,0x00000021, + 0x0000000a,0x00040047,0x00000019,0x00000022,0x00000000,0x00030047,0x0000001d,0x00000000, + 0x00040047,0x0000001d,0x00000021,0x0000000a,0x00040047,0x0000001d,0x00000022,0x00000003, + 0x00040047,0x0000003d,0x0000001e,0x00000000,0x00040047,0x0000003f,0x0000001e,0x00000000, + 0x00030047,0x00000045,0x00000002,0x00050048,0x00000045,0x00000000,0x00000023,0x00000000, + 0x00050048,0x00000045,0x00000001,0x00000023,0x00000004,0x00050048,0x00000045,0x00000002, + 0x00000023,0x00000008,0x00050048,0x00000045,0x00000003,0x00000023,0x0000000c,0x00050048, + 0x00000045,0x00000004,0x00000023,0x00000010,0x00050048,0x00000045,0x00000005,0x00000023, + 0x00000014,0x00050048,0x00000045,0x00000006,0x00000023,0x00000018,0x00050048,0x00000045, + 0x00000007,0x00000023,0x0000001c,0x00050048,0x00000045,0x00000008,0x00000023,0x00000020, + 0x00050048,0x00000045,0x00000009,0x00000023,0x00000030,0x00050048,0x00000045,0x0000000a, + 0x00000023,0x00000038,0x00050048,0x00000045,0x0000000b,0x00000023,0x00000040,0x00050048, + 0x00000045,0x0000000c,0x00000023,0x00000044,0x00050048,0x00000045,0x0000000d,0x00000023, + 0x00000048,0x00050048,0x00000045,0x0000000e,0x00000023,0x0000004c,0x00050048,0x00000045, + 0x0000000f,0x00000023,0x00000050,0x00050048,0x00000045,0x00000010,0x00000023,0x00000054, + 0x00050048,0x00000045,0x00000011,0x00000023,0x00000058,0x00050048,0x00000045,0x00000012, + 0x00000023,0x0000005c,0x00050048,0x00000045,0x00000013,0x00000023,0x00000060,0x00050048, + 0x00000045,0x00000014,0x00000023,0x00000064,0x00040047,0x00000047,0x00000021,0x00000000, + 0x00040047,0x00000047,0x00000022,0x00000000,0x00030047,0x00000048,0x00000000,0x00040047, + 0x00000048,0x00000021,0x00000009,0x00040047,0x00000048,0x00000022,0x00000000,0x00030047, + 0x00000049,0x00000000,0x00040047,0x00000049,0x00000021,0x0000000c,0x00040047,0x00000049, + 0x00000022,0x00000001,0x00030047,0x0000004a,0x00000000,0x00040047,0x0000004a,0x00000021, + 0x00000009,0x00040047,0x0000004a,0x00000022,0x00000003,0x00030047,0x0000004b,0x00000000, + 0x00040047,0x0000004b,0x00000021,0x0000000e,0x00040047,0x0000004b,0x00000022,0x00000001, + 0x00030047,0x00000055,0x00000000,0x00030047,0x00000056,0x00000000,0x00030047,0x00000061, + 0x00000000,0x00030047,0x00000062,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003, + 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004, + 0x0004002b,0x00000006,0x0000000f,0x3f800000,0x0004002b,0x00000006,0x00000011,0x40400000, + 0x00040015,0x00000012,0x00000020,0x00000000,0x00090019,0x00000017,0x00000006,0x00000001, + 0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x00040020,0x00000018,0x00000000, + 0x00000017,0x0004003b,0x00000018,0x00000019,0x00000000,0x0002001a,0x0000001b,0x00040020, + 0x0000001c,0x00000000,0x0000001b,0x0004003b,0x0000001c,0x0000001d,0x00000000,0x0003001b, + 0x0000001f,0x00000017,0x0004002b,0x00000006,0x00000022,0x00000000,0x00040017,0x00000023, + 0x00000006,0x00000002,0x00040020,0x0000003c,0x00000003,0x00000006,0x0004003b,0x0000003c, + 0x0000003d,0x00000003,0x00040020,0x0000003e,0x00000001,0x00000007,0x0004003b,0x0000003e, + 0x0000003f,0x00000001,0x00040015,0x00000043,0x00000020,0x00000001,0x00040017,0x00000044, + 0x00000043,0x00000004,0x0017001e,0x00000045,0x00000006,0x00000006,0x00000006,0x00000006, + 0x00000012,0x00000012,0x00000012,0x00000012,0x00000044,0x00000023,0x00000023,0x00000012, + 0x00000006,0x00000012,0x00000006,0x00000006,0x00000012,0x00000006,0x00000006,0x00000006, + 0x00000012,0x00040020,0x00000046,0x00000002,0x00000045,0x0004003b,0x00000046,0x00000047, + 0x00000002,0x0004003b,0x00000018,0x00000048,0x00000000,0x0004003b,0x00000018,0x00000049, + 0x00000000,0x0004003b,0x0000001c,0x0000004a,0x00000000,0x0004003b,0x0000001c,0x0000004b, + 0x00000000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003d,0x00000007,0x00000041,0x0000003f,0x00050051,0x00000006,0x00000053,0x00000041, + 0x00000000,0x00050081,0x00000006,0x00000054,0x00000011,0x00000053,0x0004003d,0x00000017, + 0x00000055,0x00000019,0x0004003d,0x0000001b,0x00000056,0x0000001d,0x00050056,0x0000001f, + 0x00000057,0x00000055,0x00000056,0x00050050,0x00000023,0x00000059,0x00000054,0x00000022, + 0x00070058,0x00000007,0x0000005a,0x00000057,0x00000059,0x00000002,0x00000022,0x00050051, + 0x00000006,0x0000005b,0x0000005a,0x00000000,0x00050083,0x00000006,0x0000005d,0x0000000f, + 0x0000005b,0x00050051,0x00000006,0x0000005f,0x00000041,0x00000001,0x00050083,0x00000006, + 0x00000060,0x0000000f,0x0000005f,0x0004003d,0x00000017,0x00000061,0x00000019,0x0004003d, + 0x0000001b,0x00000062,0x0000001d,0x00050056,0x0000001f,0x00000063,0x00000061,0x00000062, + 0x00050050,0x00000023,0x00000065,0x00000060,0x00000022,0x00070058,0x00000007,0x00000066, + 0x00000063,0x00000065,0x00000002,0x00000022,0x00050051,0x00000006,0x00000067,0x00000066, + 0x00000000,0x00050083,0x00000006,0x00000069,0x0000005d,0x00000067,0x0003003e,0x0000003d, + 0x00000069,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/render_atlas_stroke.webgpu_frag.spirv new file mode 100644 index 0000000000000000000000000000000000000000..8af3fcb4a980ee8147d7919310088385676fada8 GIT binary patch literal 2508 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 VWNV}iKgB8hyA-|n4yt(~^k1Rf2#Wv! literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.h b/thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.h new file mode 100644 index 000000000..94bcd49e8 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.h @@ -0,0 +1,476 @@ +#pragma once + +const uint32_t tessellate_vert[] = { + 0x07230203,0x00010000,0x0008000b,0x000007e5,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0010000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x00000245,0x0000024a,0x00000251, + 0x00000261,0x00000272,0x000003dc,0x000003e4,0x000003ec,0x00000430,0x00000443,0x00000451, + 0x00030003,0x00000002,0x000001cc,0x000a0004,0x415f4c47,0x735f4252,0x65646168,0x74735f72, + 0x6761726f,0x75625f65,0x72656666,0x6a626f5f,0x00746365,0x000b0004,0x455f4c47,0x735f5458, + 0x6c706d61,0x656c7265,0x745f7373,0x75747865,0x665f6572,0x74636e75,0x736e6f69,0x00000000, + 0x000a0004,0x475f4c47,0x4c474f4f,0x70635f45,0x74735f70,0x5f656c79,0x656e696c,0x7269645f, + 0x69746365,0x00006576,0x00080004,0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,0x69645f65, + 0x74636572,0x00657669,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00060005,0x00000245, + 0x565f6c67,0x65747265,0x646e4978,0x00007865,0x00030005,0x0000024a,0x0000435a,0x00030005, + 0x00000251,0x00004441,0x00030005,0x00000261,0x0000434f,0x00030005,0x00000272,0x00004252, + 0x00030005,0x000002a7,0x0000424d,0x00040006,0x000002a7,0x00000000,0x00006250,0x00040006, + 0x000002a7,0x00000001,0x00006359,0x00040006,0x000002a7,0x00000002,0x00006552,0x00040006, + 0x000002a7,0x00000003,0x00006553,0x00040006,0x000002a7,0x00000004,0x0000366d,0x00040006, + 0x000002a7,0x00000005,0x0000676d,0x00040006,0x000002a7,0x00000006,0x00006544,0x00040006, + 0x000002a7,0x00000007,0x00006545,0x00040006,0x000002a7,0x00000008,0x00003755,0x00040006, + 0x000002a7,0x00000009,0x0000676a,0x00040006,0x000002a7,0x0000000a,0x0000635a,0x00040006, + 0x000002a7,0x0000000b,0x00003157,0x00040006,0x000002a7,0x0000000c,0x0000676e,0x00040006, + 0x000002a7,0x0000000d,0x00003559,0x00040006,0x000002a7,0x0000000e,0x0000324f,0x00040006, + 0x000002a7,0x0000000f,0x00006461,0x00040006,0x000002a7,0x00000010,0x00006579,0x00040006, + 0x000002a7,0x00000011,0x00003376,0x00040006,0x000002a7,0x00000012,0x00003377,0x00040006, + 0x000002a7,0x00000013,0x00006462,0x00040006,0x000002a7,0x00000014,0x00006767,0x00030005, + 0x000002a9,0x0000006b,0x00030005,0x000002d6,0x0000664b,0x00040006,0x000002d6,0x00000000, + 0x00003464,0x00030005,0x000002d8,0x00004358,0x00030005,0x000002e9,0x0000664a,0x00040006, + 0x000002e9,0x00000000,0x00003464,0x00030005,0x000002eb,0x0000424c,0x00030005,0x00000344, + 0x00004351,0x00030005,0x00000348,0x00003954,0x00030005,0x000003dc,0x00003677,0x00030005, + 0x000003e4,0x00003678,0x00030005,0x000003ec,0x0000344d,0x00030005,0x00000430,0x00003541, + 0x00030005,0x00000443,0x00003749,0x00060005,0x0000044f,0x505f6c67,0x65567265,0x78657472, + 0x00000000,0x00060006,0x0000044f,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006, + 0x0000044f,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000044f, + 0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000044f,0x00000003, + 0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000451,0x00000000,0x00040047, + 0x00000245,0x0000000b,0x0000002a,0x00040047,0x0000024a,0x0000001e,0x00000000,0x00040047, + 0x00000251,0x0000001e,0x00000001,0x00040047,0x00000261,0x0000001e,0x00000002,0x00040047, + 0x00000272,0x0000001e,0x00000003,0x00030047,0x000002a7,0x00000002,0x00050048,0x000002a7, + 0x00000000,0x00000023,0x00000000,0x00050048,0x000002a7,0x00000001,0x00000023,0x00000004, + 0x00050048,0x000002a7,0x00000002,0x00000023,0x00000008,0x00050048,0x000002a7,0x00000003, + 0x00000023,0x0000000c,0x00050048,0x000002a7,0x00000004,0x00000023,0x00000010,0x00050048, + 0x000002a7,0x00000005,0x00000023,0x00000014,0x00050048,0x000002a7,0x00000006,0x00000023, + 0x00000018,0x00050048,0x000002a7,0x00000007,0x00000023,0x0000001c,0x00050048,0x000002a7, + 0x00000008,0x00000023,0x00000020,0x00050048,0x000002a7,0x00000009,0x00000023,0x00000030, + 0x00050048,0x000002a7,0x0000000a,0x00000023,0x00000038,0x00050048,0x000002a7,0x0000000b, + 0x00000023,0x00000040,0x00050048,0x000002a7,0x0000000c,0x00000023,0x00000044,0x00050048, + 0x000002a7,0x0000000d,0x00000023,0x00000048,0x00050048,0x000002a7,0x0000000e,0x00000023, + 0x0000004c,0x00050048,0x000002a7,0x0000000f,0x00000023,0x00000050,0x00050048,0x000002a7, + 0x00000010,0x00000023,0x00000054,0x00050048,0x000002a7,0x00000011,0x00000023,0x00000058, + 0x00050048,0x000002a7,0x00000012,0x00000023,0x0000005c,0x00050048,0x000002a7,0x00000013, + 0x00000023,0x00000060,0x00050048,0x000002a7,0x00000014,0x00000023,0x00000064,0x00040047, + 0x000002a9,0x00000021,0x00000000,0x00040047,0x000002a9,0x00000022,0x00000000,0x00040047, + 0x000002d5,0x00000006,0x00000010,0x00030047,0x000002d6,0x00000003,0x00040048,0x000002d6, + 0x00000000,0x00000018,0x00050048,0x000002d6,0x00000000,0x00000023,0x00000000,0x00030047, + 0x000002d8,0x00000018,0x00040047,0x000002d8,0x00000021,0x00000006,0x00040047,0x000002d8, + 0x00000022,0x00000000,0x00040047,0x000002e8,0x00000006,0x00000010,0x00030047,0x000002e9, + 0x00000003,0x00040048,0x000002e9,0x00000000,0x00000018,0x00050048,0x000002e9,0x00000000, + 0x00000023,0x00000000,0x00030047,0x000002eb,0x00000018,0x00040047,0x000002eb,0x00000021, + 0x00000003,0x00040047,0x000002eb,0x00000022,0x00000000,0x00030047,0x00000344,0x00000000, + 0x00040047,0x00000344,0x00000021,0x0000000a,0x00040047,0x00000344,0x00000022,0x00000000, + 0x00030047,0x00000345,0x00000000,0x00030047,0x00000348,0x00000000,0x00040047,0x00000348, + 0x00000021,0x0000000a,0x00040047,0x00000348,0x00000022,0x00000000,0x00030047,0x00000349, + 0x00000000,0x00040047,0x000003dc,0x0000001e,0x00000000,0x00040047,0x000003e4,0x0000001e, + 0x00000001,0x00040047,0x000003ec,0x0000001e,0x00000002,0x00040047,0x00000430,0x0000001e, + 0x00000003,0x00030047,0x00000443,0x0000000e,0x00040047,0x00000443,0x0000001e,0x00000004, + 0x00030047,0x0000044f,0x00000002,0x00050048,0x0000044f,0x00000000,0x0000000b,0x00000000, + 0x00050048,0x0000044f,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000044f,0x00000002, + 0x0000000b,0x00000003,0x00050048,0x0000044f,0x00000003,0x0000000b,0x00000004,0x00020013, + 0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017, + 0x00000007,0x00000006,0x00000004,0x00040017,0x00000009,0x00000006,0x00000002,0x00040018, + 0x0000000a,0x00000009,0x00000002,0x0004002b,0x00000006,0x00000047,0x3f800000,0x0004002b, + 0x00000006,0x00000048,0x00000000,0x00040015,0x00000052,0x00000020,0x00000000,0x0004002b, + 0x00000052,0x00000053,0x00000000,0x0004002b,0x00000052,0x00000059,0x00000001,0x00020014, + 0x00000071,0x0004002b,0x00000006,0x0000007b,0xbf800000,0x0004002b,0x00000006,0x0000008e, + 0xc0400000,0x00040015,0x00000095,0x00000020,0x00000001,0x0004002b,0x00000095,0x00000096, + 0x00000000,0x00040017,0x00000099,0x00000071,0x00000002,0x0004002b,0x00000095,0x000000ad, + 0x00000001,0x0004002b,0x00000006,0x000000d9,0x40400000,0x0004002b,0x00000006,0x000000dd, + 0x40000000,0x0004002b,0x00000006,0x000000fb,0x40800000,0x0004002b,0x00000006,0x00000104, + 0x40c00000,0x0004002b,0x00000006,0x0000011c,0x3f7ff972,0x0004002b,0x00000006,0x00000135, + 0xbeaaaaab,0x0004002b,0x00000006,0x00000139,0x3f000000,0x0004002b,0x00000006,0x00000156, + 0xc0000000,0x0004002b,0x00000006,0x0000015a,0x3eaaaaab,0x0004002b,0x00000006,0x0000015c, + 0xc0060a92,0x0004002b,0x00000006,0x000001a1,0x3a83126f,0x0004002b,0x00000052,0x000001ad, + 0x00000002,0x0004002b,0x00000006,0x000001b0,0x3f7fbe77,0x0004002b,0x00000095,0x0000021e, + 0x00000003,0x00040020,0x00000244,0x00000001,0x00000095,0x0004003b,0x00000244,0x00000245, + 0x00000001,0x00040020,0x00000249,0x00000001,0x00000007,0x0004003b,0x00000249,0x0000024a, + 0x00000001,0x0004003b,0x00000249,0x00000251,0x00000001,0x0004002b,0x00000095,0x0000025a, + 0x00000004,0x0004003b,0x00000249,0x00000261,0x00000001,0x00040020,0x00000262,0x00000001, + 0x00000006,0x0004002b,0x00000052,0x00000266,0x00000003,0x00040017,0x00000270,0x00000052, + 0x00000004,0x00040020,0x00000271,0x00000001,0x00000270,0x0004003b,0x00000271,0x00000272, + 0x00000001,0x00040020,0x00000273,0x00000001,0x00000052,0x0004002b,0x00000095,0x0000027d, + 0x00000010,0x0004002b,0x00000052,0x00000281,0xffffffff,0x0004002b,0x00000095,0x00000297, + 0x00000002,0x00040017,0x000002a6,0x00000095,0x00000004,0x0017001e,0x000002a7,0x00000006, + 0x00000006,0x00000006,0x00000006,0x00000052,0x00000052,0x00000052,0x00000052,0x000002a6, + 0x00000009,0x00000009,0x00000052,0x00000006,0x00000052,0x00000006,0x00000006,0x00000052, + 0x00000006,0x00000006,0x00000006,0x00000052,0x00040020,0x000002a8,0x00000002,0x000002a7, + 0x0004003b,0x000002a8,0x000002a9,0x00000002,0x00040020,0x000002aa,0x00000002,0x00000006, + 0x0004002b,0x00000052,0x000002bb,0x000003ff,0x0004002b,0x00000095,0x000002c0,0x0000000a, + 0x0004002b,0x00000095,0x000002c6,0x00000014,0x0004002b,0x00000052,0x000002cd,0x0000ffff, + 0x0003001d,0x000002d5,0x00000270,0x0003001e,0x000002d6,0x000002d5,0x00040020,0x000002d7, + 0x00000002,0x000002d6,0x0004003b,0x000002d7,0x000002d8,0x00000002,0x00040020,0x000002dc, + 0x00000002,0x00000052,0x0003001d,0x000002e8,0x00000270,0x0003001e,0x000002e9,0x000002e8, + 0x00040020,0x000002ea,0x00000002,0x000002e9,0x0004003b,0x000002ea,0x000002eb,0x00000002, + 0x0004002b,0x00000052,0x000002ed,0x00000004,0x00040020,0x000002f0,0x00000002,0x00000270, + 0x0007002c,0x00000270,0x000002f4,0x00000053,0x00000053,0x00000053,0x00000053,0x0004002b, + 0x00000006,0x00000325,0x3ea2f983,0x0004002b,0x00000006,0x0000033c,0x3f7d70a4,0x00090019, + 0x00000342,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000, + 0x00040020,0x00000343,0x00000000,0x00000342,0x0004003b,0x00000343,0x00000344,0x00000000, + 0x0002001a,0x00000346,0x00040020,0x00000347,0x00000000,0x00000346,0x0004003b,0x00000347, + 0x00000348,0x00000000,0x0003001b,0x0000034a,0x00000342,0x0004002b,0x00000006,0x0000035f, + 0x3f2aaaab,0x0007002c,0x00000007,0x00000360,0x0000015a,0x0000015a,0x0000035f,0x0000035f, + 0x0004002b,0x00000052,0x0000036f,0x20000000,0x00040020,0x000003db,0x00000003,0x00000007, + 0x0004003b,0x000003db,0x000003dc,0x00000003,0x0004003b,0x000003db,0x000003e4,0x00000003, + 0x0004003b,0x000003db,0x000003ec,0x00000003,0x0004002b,0x00000052,0x0000041b,0x1e000000, + 0x0004002b,0x00000052,0x0000041d,0x0a000000,0x00040017,0x0000042e,0x00000006,0x00000003, + 0x00040020,0x0000042f,0x00000003,0x0000042e,0x0004003b,0x0000042f,0x00000430,0x00000003, + 0x00040020,0x00000433,0x00000003,0x00000006,0x0004002b,0x00000052,0x0000043f,0x00800000, + 0x00040020,0x00000442,0x00000003,0x00000052,0x0004003b,0x00000442,0x00000443,0x00000003, + 0x0004002b,0x00000006,0x00000446,0x3a800000,0x0004001c,0x0000044e,0x00000006,0x00000059, + 0x0006001e,0x0000044f,0x00000007,0x00000006,0x0000044e,0x0000044e,0x00040020,0x00000450, + 0x00000003,0x0000044f,0x0004003b,0x00000450,0x00000451,0x00000003,0x0003002e,0x00000009, + 0x000007e3,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, + 0x0004003d,0x00000095,0x00000246,0x00000245,0x0004003d,0x00000007,0x0000024b,0x0000024a, + 0x0007004f,0x00000009,0x0000024c,0x0000024b,0x0000024b,0x00000000,0x00000001,0x0007004f, + 0x00000009,0x0000024f,0x0000024b,0x0000024b,0x00000002,0x00000003,0x0004003d,0x00000007, + 0x00000252,0x00000251,0x0007004f,0x00000009,0x00000253,0x00000252,0x00000252,0x00000000, + 0x00000001,0x0007004f,0x00000009,0x00000256,0x00000252,0x00000252,0x00000002,0x00000003, + 0x000500b1,0x00000071,0x0000025b,0x00000246,0x0000025a,0x000300f7,0x00000260,0x00000000, + 0x000400fa,0x0000025b,0x0000025f,0x00000265,0x000200f8,0x0000025f,0x00050041,0x00000262, + 0x00000263,0x00000261,0x000001ad,0x0004003d,0x00000006,0x00000264,0x00000263,0x000200f9, + 0x00000260,0x000200f8,0x00000265,0x00050041,0x00000262,0x00000267,0x00000261,0x00000266, + 0x0004003d,0x00000006,0x00000268,0x00000267,0x000200f9,0x00000260,0x000200f8,0x00000260, + 0x000700f5,0x00000006,0x000006ea,0x00000264,0x0000025f,0x00000268,0x00000265,0x000300f7, + 0x0000026f,0x00000000,0x000400fa,0x0000025b,0x0000026e,0x00000276,0x000200f8,0x0000026e, + 0x00050041,0x00000273,0x00000274,0x00000272,0x00000053,0x0004003d,0x00000052,0x00000275, + 0x00000274,0x000200f9,0x0000026f,0x000200f8,0x00000276,0x00050041,0x00000273,0x00000277, + 0x00000272,0x00000059,0x0004003d,0x00000052,0x00000278,0x00000277,0x000200f9,0x0000026f, + 0x000200f8,0x0000026f,0x000700f5,0x00000052,0x000006eb,0x00000275,0x0000026e,0x00000278, + 0x00000276,0x0004007c,0x00000095,0x0000027a,0x000006eb,0x000500c4,0x00000095,0x0000027e, + 0x0000027a,0x0000027d,0x00050041,0x00000273,0x0000027f,0x00000272,0x000001ad,0x0004003d, + 0x00000052,0x00000280,0x0000027f,0x000500aa,0x00000071,0x00000282,0x00000280,0x00000281, + 0x000300f7,0x00000284,0x00000000,0x000400fa,0x00000282,0x00000283,0x00000284,0x000200f8, + 0x00000283,0x00050082,0x00000095,0x00000286,0x0000027e,0x000000ad,0x000200f9,0x00000284, + 0x000200f8,0x00000284,0x000700f5,0x00000095,0x000006ec,0x0000027e,0x0000026f,0x00000286, + 0x00000283,0x000500c3,0x00000095,0x00000289,0x000006ec,0x0000027d,0x0004006f,0x00000006, + 0x0000028a,0x00000289,0x000500c3,0x00000095,0x0000028d,0x0000027a,0x0000027d,0x0004006f, + 0x00000006,0x0000028e,0x0000028d,0x000500c7,0x00000095,0x00000291,0x00000246,0x000000ad, + 0x000500aa,0x00000071,0x00000292,0x00000291,0x00000096,0x000600a9,0x00000006,0x00000295, + 0x00000292,0x0000028a,0x0000028e,0x000500c7,0x00000095,0x00000298,0x00000246,0x00000297, + 0x000500aa,0x00000071,0x00000299,0x00000298,0x00000096,0x000300f7,0x0000029c,0x00000000, + 0x000400fa,0x00000299,0x0000029b,0x0000029f,0x000200f8,0x0000029b,0x00050081,0x00000006, + 0x0000029e,0x000006ea,0x00000047,0x000200f9,0x0000029c,0x000200f8,0x0000029f,0x000200f9, + 0x0000029c,0x000200f8,0x0000029c,0x000700f5,0x00000006,0x000006ed,0x0000029e,0x0000029b, + 0x000006ea,0x0000029f,0x00050050,0x00000009,0x000002a2,0x00000295,0x000006ed,0x00050083, + 0x00000006,0x000002a5,0x0000028e,0x0000028a,0x00050041,0x000002aa,0x000002ab,0x000002a9, + 0x000000ad,0x0004003d,0x00000006,0x000002ac,0x000002ab,0x00050085,0x00000006,0x000002ad, + 0x000002a5,0x000002ac,0x000500b8,0x00000071,0x000002ae,0x000002ad,0x00000048,0x000300f7, + 0x000002b0,0x00000000,0x000400fa,0x000002ae,0x000002af,0x000002b0,0x000200f8,0x000002af, + 0x00050085,0x00000006,0x000002b2,0x000000dd,0x000006ea,0x00050081,0x00000006,0x000002b3, + 0x000002b2,0x00000047,0x00050083,0x00000006,0x000002b6,0x000002b3,0x000006ed,0x00060052, + 0x00000009,0x000006d1,0x000002b6,0x000002a2,0x00000001,0x000200f9,0x000002b0,0x000200f8, + 0x000002b0,0x000700f5,0x00000009,0x000007b2,0x000002a2,0x0000029c,0x000006d1,0x000002af, + 0x000500c7,0x00000052,0x000002bc,0x00000280,0x000002bb,0x000500c2,0x00000052,0x000002c1, + 0x00000280,0x000002c0,0x000500c7,0x00000052,0x000002c2,0x000002c1,0x000002bb,0x000500c2, + 0x00000052,0x000002c7,0x00000280,0x000002c6,0x00050041,0x00000273,0x000002c9,0x00000272, + 0x00000266,0x0004003d,0x00000052,0x000002ca,0x000002c9,0x000500c7,0x00000052,0x000002ce, + 0x000002ca,0x000002cd,0x000500ac,0x00000071,0x000002d1,0x000002ce,0x00000053,0x000300f7, + 0x000002d4,0x00000000,0x000400fa,0x000002d1,0x000002d3,0x000002df,0x000200f8,0x000002d3, + 0x0007000c,0x00000052,0x000002da,0x00000001,0x00000029,0x000002ce,0x00000059,0x00050082, + 0x00000052,0x000002db,0x000002da,0x00000059,0x00070041,0x000002dc,0x000002dd,0x000002d8, + 0x00000096,0x000002db,0x000001ad,0x0004003d,0x00000052,0x000002de,0x000002dd,0x000200f9, + 0x000002d4,0x000200f8,0x000002df,0x000200f9,0x000002d4,0x000200f8,0x000002d4,0x000700f5, + 0x00000052,0x000006ee,0x000002de,0x000002d3,0x00000053,0x000002df,0x000500ab,0x00000071, + 0x000002e4,0x000006ee,0x00000053,0x000300f7,0x000002e7,0x00000000,0x000400fa,0x000002e4, + 0x000002e6,0x000002f3,0x000200f8,0x000002e6,0x00050084,0x00000052,0x000002ee,0x000006ee, + 0x000002ed,0x00050080,0x00000052,0x000002ef,0x000002ee,0x00000059,0x00060041,0x000002f0, + 0x000002f1,0x000002eb,0x00000096,0x000002ef,0x0004003d,0x00000270,0x000002f2,0x000002f1, + 0x000200f9,0x000002e7,0x000200f8,0x000002f3,0x000200f9,0x000002e7,0x000200f8,0x000002e7, + 0x000700f5,0x00000270,0x000006ef,0x000002f2,0x000002e6,0x000002f4,0x000002f3,0x00050051, + 0x00000052,0x000002f8,0x000006ef,0x00000002,0x0004007c,0x00000006,0x000002f9,0x000002f8, + 0x00050051,0x00000052,0x000002fc,0x000006ef,0x00000003,0x0004007c,0x00000006,0x000002fd, + 0x000002fc,0x000500b7,0x00000071,0x000002ff,0x000002fd,0x00000048,0x000500b4,0x00000071, + 0x00000301,0x000002f9,0x00000048,0x000500a7,0x00000071,0x00000302,0x000002ff,0x00000301, + 0x000300f7,0x00000304,0x00000000,0x000400fa,0x00000302,0x00000303,0x00000304,0x000200f8, + 0x00000303,0x000300f7,0x000004c0,0x00000000,0x000300fb,0x00000053,0x00000472,0x000200f8, + 0x00000472,0x00050083,0x00000009,0x00000475,0x00000256,0x0000024c,0x0006000c,0x00000006, + 0x00000479,0x00000001,0x00000042,0x00000475,0x000500b4,0x00000071,0x0000047b,0x00000479, + 0x00000048,0x000300f7,0x0000047d,0x00000000,0x000400fa,0x0000047b,0x0000047c,0x0000047d, + 0x000200f8,0x0000047c,0x000200f9,0x000004c0,0x000200f8,0x0000047d,0x00050051,0x00000006, + 0x0000047f,0x00000475,0x00000001,0x0004007f,0x00000006,0x00000480,0x0000047f,0x00050051, + 0x00000006,0x00000482,0x00000475,0x00000000,0x00050050,0x00000009,0x00000483,0x00000480, + 0x00000482,0x00050050,0x00000009,0x00000485,0x00000479,0x00000479,0x00050088,0x00000009, + 0x00000486,0x00000483,0x00000485,0x00050083,0x00000009,0x0000048a,0x00000253,0x0000024c, + 0x00050094,0x00000006,0x0000048b,0x00000486,0x0000048a,0x00050083,0x00000009,0x0000048f, + 0x0000024f,0x0000024c,0x00050094,0x00000006,0x00000490,0x00000486,0x0000048f,0x00050083, + 0x00000006,0x00000493,0x00000490,0x0000048b,0x00050085,0x00000006,0x00000495,0x000000d9, + 0x00000493,0x0004007f,0x00000006,0x00000497,0x00000490,0x00050083,0x00000006,0x00000499, + 0x00000497,0x00000493,0x000200f9,0x0000049b,0x000200f8,0x0000049b,0x000700f5,0x00000006, + 0x000006ff,0x00000139,0x0000047d,0x00000703,0x000004ad,0x000700f5,0x00000095,0x000006fe, + 0x00000096,0x0000047d,0x000004af,0x000004ad,0x000500b1,0x00000071,0x0000049e,0x000006fe, + 0x0000021e,0x000400f6,0x000004b0,0x000004ad,0x00000000,0x000400fa,0x0000049e,0x0000049f, + 0x000004b0,0x000200f8,0x0000049f,0x00050085,0x00000006,0x000004a2,0x00000495,0x000006ff, + 0x00050085,0x00000006,0x000004a5,0x000004a2,0x000006ff,0x00050083,0x00000006,0x000004a7, + 0x000004a5,0x00000490,0x00050081,0x00000006,0x000004aa,0x000004a2,0x00000499,0x00050085, + 0x00000006,0x000004ab,0x000000dd,0x000004aa,0x000500b8,0x00000071,0x000004c8,0x000004ab, + 0x00000048,0x000300f7,0x000004ce,0x00000000,0x000400fa,0x000004c8,0x000004c9,0x000004cc, + 0x000200f8,0x000004c9,0x0004007f,0x00000006,0x000004cb,0x000004a7,0x000200f9,0x000004ce, + 0x000200f8,0x000004cc,0x000200f9,0x000004ce,0x000200f8,0x000004ce,0x000700f5,0x00000006, + 0x00000700,0x000004cb,0x000004c9,0x000004a7,0x000004cc,0x0006000c,0x00000006,0x000004d1, + 0x00000001,0x00000004,0x000004ab,0x000500ba,0x00000071,0x000004d3,0x00000700,0x00000048, + 0x000300f7,0x000004e0,0x00000000,0x000400fa,0x000004d3,0x000004d4,0x000004df,0x000200f8, + 0x000004d4,0x000500b8,0x00000071,0x000004d7,0x00000700,0x000004d1,0x000300f7,0x000004dd, + 0x00000000,0x000400fa,0x000004d7,0x000004d8,0x000004dc,0x000200f8,0x000004d8,0x00050088, + 0x00000006,0x000004db,0x00000700,0x000004d1,0x000200f9,0x000004dd,0x000200f8,0x000004dc, + 0x000200f9,0x000004dd,0x000200f8,0x000004dd,0x000700f5,0x00000006,0x00000702,0x000004db, + 0x000004d8,0x00000047,0x000004dc,0x000200f9,0x000004e0,0x000200f8,0x000004df,0x000200f9, + 0x000004e0,0x000200f8,0x000004e0,0x000700f5,0x00000006,0x00000703,0x00000702,0x000004dd, + 0x00000048,0x000004df,0x000200f9,0x000004ad,0x000200f8,0x000004ad,0x00050080,0x00000095, + 0x000004af,0x000006fe,0x000000ad,0x000200f9,0x0000049b,0x000200f8,0x000004b0,0x00050085, + 0x00000006,0x000004b6,0x000006ff,0x00000495,0x00050085,0x00000006,0x000004b8,0x000000d9, + 0x00000499,0x00050081,0x00000006,0x000004b9,0x000004b6,0x000004b8,0x00050085,0x00000006, + 0x000004ba,0x000006ff,0x000004b9,0x00050085,0x00000006,0x000004bc,0x000000d9,0x00000490, + 0x00050081,0x00000006,0x000004bd,0x000004ba,0x000004bc,0x00050085,0x00000006,0x000004be, + 0x000006ff,0x000004bd,0x0006000c,0x00000006,0x000004bf,0x00000001,0x00000004,0x000004be, + 0x000200f9,0x000004c0,0x000200f8,0x000004c0,0x000700f5,0x00000006,0x00000708,0x00000139, + 0x0000047c,0x000006ff,0x000004b0,0x000700f5,0x00000006,0x00000707,0x00000048,0x0000047c, + 0x000004bf,0x000004b0,0x00050085,0x00000006,0x00000314,0x000002fd,0x0000015a,0x000300f7, + 0x000005d4,0x00000000,0x000300fb,0x00000053,0x0000050f,0x000200f8,0x0000050f,0x00050083, + 0x00000009,0x000005db,0x0000024f,0x0000024c,0x00050083,0x00000009,0x000005de,0x00000253, + 0x0000024f,0x00050083,0x00000009,0x000005e4,0x000005de,0x000005db,0x0005008e,0x00000009, + 0x000005e6,0x000005de,0x0000008e,0x00050081,0x00000009,0x000005e8,0x000005e6,0x00000475, + 0x0005008e,0x00000009,0x0000051a,0x000005e8,0x00000708,0x0005008e,0x00000009,0x0000051c, + 0x000005e4,0x000000dd,0x00050081,0x00000009,0x0000051d,0x0000051a,0x0000051c,0x0005008e, + 0x00000009,0x0000051f,0x0000051d,0x00000708,0x00050081,0x00000009,0x00000521,0x0000051f, + 0x000005db,0x0005008e,0x00000009,0x00000522,0x00000521,0x000000d9,0x0006000c,0x00000006, + 0x00000524,0x00000001,0x00000042,0x00000522,0x000500b4,0x00000071,0x00000526,0x00000524, + 0x00000048,0x000300f7,0x00000528,0x00000000,0x000400fa,0x00000526,0x00000527,0x00000528, + 0x000200f8,0x00000527,0x000200f9,0x000005d4,0x000200f8,0x00000528,0x00050088,0x00000006, + 0x0000052a,0x00000047,0x00000524,0x0005008e,0x00000009,0x0000052c,0x00000522,0x0000052a, + 0x00050094,0x00000006,0x0000052f,0x000005e8,0x0000052c,0x00050085,0x00000006,0x00000530, + 0x000000dd,0x0000052f,0x00050085,0x00000006,0x00000533,0x00000530,0x00000708,0x00050094, + 0x00000006,0x00000536,0x000005e4,0x0000052c,0x00050085,0x00000006,0x00000537,0x000000fb, + 0x00000536,0x00050081,0x00000006,0x00000538,0x00000533,0x00000537,0x00050085,0x00000006, + 0x00000539,0x000000d9,0x00000538,0x00050085,0x00000006,0x0000053b,0x00000539,0x00000708, + 0x00050094,0x00000006,0x0000053e,0x000005db,0x0000052c,0x00050085,0x00000006,0x0000053f, + 0x00000104,0x0000053e,0x00050081,0x00000006,0x00000540,0x0000053b,0x0000053f,0x00050083, + 0x00000006,0x00000543,0x00000047,0x00000708,0x0007000c,0x00000006,0x00000544,0x00000001, + 0x00000025,0x00000708,0x00000543,0x00050085,0x00000006,0x00000547,0x00000530,0x00000544, + 0x00050085,0x00000006,0x00000549,0x00000547,0x00000544,0x00050081,0x00000006,0x0000054b, + 0x00000549,0x00000540,0x00050085,0x00000006,0x0000054d,0x0000054b,0x00000544,0x00050085, + 0x00000006,0x00000550,0x0000054d,0x0000011c,0x0007000c,0x00000006,0x00000551,0x00000001, + 0x00000025,0x00000314,0x00000550,0x000500b4,0x00000071,0x00000553,0x00000530,0x00000048, + 0x000300f7,0x0000059c,0x00000000,0x000400fa,0x00000553,0x00000554,0x00000558,0x000200f8, + 0x00000554,0x00050088,0x00000006,0x00000557,0x00000551,0x00000540,0x000200f9,0x0000059c, + 0x000200f8,0x00000558,0x00050088,0x00000006,0x0000055a,0x00000139,0x0000052f,0x00050085, + 0x00000006,0x0000055d,0x00000540,0x0000055a,0x0004007f,0x00000006,0x0000055f,0x00000551, + 0x00050085,0x00000006,0x00000561,0x0000055f,0x0000055a,0x00050085,0x00000006,0x00000563, + 0x00000135,0x0000055d,0x00050085,0x00000006,0x00000565,0x00000139,0x00000561,0x00050085, + 0x00000006,0x00000568,0x00000565,0x00000565,0x00050085,0x00000006,0x0000056b,0x00000563, + 0x00000563,0x00050085,0x00000006,0x0000056d,0x0000056b,0x00000563,0x00050083,0x00000006, + 0x0000056e,0x00000568,0x0000056d,0x000500b8,0x00000071,0x00000570,0x0000056e,0x00000048, + 0x000300f7,0x0000059b,0x00000000,0x000400fa,0x00000570,0x00000571,0x00000583,0x000200f8, + 0x00000571,0x0006000c,0x00000006,0x00000573,0x00000001,0x0000001f,0x00000563,0x00050085, + 0x00000006,0x00000577,0x00000573,0x00000573,0x00050085,0x00000006,0x00000579,0x00000577, + 0x00000573,0x00050088,0x00000006,0x0000057a,0x00000565,0x00000579,0x0006000c,0x00000006, + 0x0000057b,0x00000001,0x00000011,0x0000057a,0x00050085,0x00000006,0x0000057d,0x00000156, + 0x00000573,0x00050085,0x00000006,0x0000057f,0x0000057b,0x0000015a,0x00050081,0x00000006, + 0x00000580,0x0000057f,0x0000015c,0x0006000c,0x00000006,0x00000581,0x00000001,0x0000000e, + 0x00000580,0x00050085,0x00000006,0x00000582,0x0000057d,0x00000581,0x000200f9,0x0000059b, + 0x000200f8,0x00000583,0x0006000c,0x00000006,0x00000585,0x00000001,0x00000004,0x00000565, + 0x0006000c,0x00000006,0x00000587,0x00000001,0x0000001f,0x0000056e,0x00050081,0x00000006, + 0x00000588,0x00000585,0x00000587,0x0007000c,0x00000006,0x00000589,0x00000001,0x0000001a, + 0x00000588,0x0000015a,0x000500b8,0x00000071,0x0000058b,0x00000565,0x00000048,0x000300f7, + 0x0000058f,0x00000000,0x000400fa,0x0000058b,0x0000058c,0x0000058f,0x000200f8,0x0000058c, + 0x0004007f,0x00000006,0x0000058e,0x00000589,0x000200f9,0x0000058f,0x000200f8,0x0000058f, + 0x000700f5,0x00000006,0x00000713,0x00000589,0x00000583,0x0000058e,0x0000058c,0x000500b7, + 0x00000071,0x00000591,0x00000713,0x00000048,0x000300f7,0x00000599,0x00000000,0x000400fa, + 0x00000591,0x00000592,0x00000598,0x000200f8,0x00000592,0x00050088,0x00000006,0x00000596, + 0x00000563,0x00000713,0x00050081,0x00000006,0x00000597,0x00000713,0x00000596,0x000200f9, + 0x00000599,0x000200f8,0x00000598,0x000200f9,0x00000599,0x000200f8,0x00000599,0x000700f5, + 0x00000006,0x00000714,0x00000597,0x00000592,0x00000048,0x00000598,0x000200f9,0x0000059b, + 0x000200f8,0x0000059b,0x000700f5,0x00000006,0x00000716,0x00000582,0x00000571,0x00000714, + 0x00000599,0x000200f9,0x0000059c,0x000200f8,0x0000059c,0x000700f5,0x00000006,0x00000715, + 0x00000557,0x00000554,0x00000716,0x0000059b,0x0006000c,0x00000006,0x0000059e,0x00000001, + 0x00000004,0x00000715,0x0004007f,0x00000006,0x000005a1,0x0000059e,0x00070050,0x00000007, + 0x000005a5,0x000005a1,0x000005a1,0x0000059e,0x0000059e,0x00070050,0x00000007,0x000005a6, + 0x00000708,0x00000708,0x00000708,0x00000708,0x00050081,0x00000007,0x000005a7,0x000005a6, + 0x000005a5,0x0009004f,0x00000007,0x000005a9,0x000005e8,0x000005e8,0x00000000,0x00000001, + 0x00000000,0x00000001,0x00050085,0x00000007,0x000005ab,0x000005a9,0x000005a7,0x0009004f, + 0x00000007,0x000005ad,0x000005e4,0x000005e4,0x00000000,0x00000001,0x00000000,0x00000001, + 0x0005008e,0x00000007,0x000005ae,0x000005ad,0x000000dd,0x00050081,0x00000007,0x000005af, + 0x000005ab,0x000005ae,0x00050085,0x00000007,0x000005b1,0x000005af,0x000005a7,0x0009004f, + 0x00000007,0x000005b3,0x000005db,0x000005db,0x00000000,0x00000001,0x00000000,0x00000001, + 0x00050081,0x00000007,0x000005b4,0x000005b1,0x000005b3,0x000500b7,0x00000099,0x000005f0, + 0x0000024c,0x0000024f,0x0004009a,0x00000071,0x000005f1,0x000005f0,0x000300f7,0x000005fd, + 0x00000000,0x000400fa,0x000005f1,0x000005f2,0x000005f4,0x000200f8,0x000005f2,0x000200f9, + 0x000005fd,0x000200f8,0x000005f4,0x000500b7,0x00000099,0x000005f7,0x0000024f,0x00000253, + 0x0004009a,0x00000071,0x000005f8,0x000005f7,0x00050050,0x00000099,0x000005fb,0x000005f8, + 0x000005f8,0x000600a9,0x00000009,0x000005fc,0x000005fb,0x00000253,0x00000256,0x000200f9, + 0x000005fd,0x000200f8,0x000005fd,0x000700f5,0x00000009,0x00000717,0x0000024f,0x000005f2, + 0x000005fc,0x000005f4,0x00050083,0x00000009,0x00000600,0x00000717,0x0000024c,0x000500b7, + 0x00000099,0x00000605,0x00000256,0x00000253,0x0004009a,0x00000071,0x00000606,0x00000605, + 0x000300f7,0x00000612,0x00000000,0x000400fa,0x00000606,0x00000607,0x00000609,0x000200f8, + 0x00000607,0x000200f9,0x00000612,0x000200f8,0x00000609,0x000500b7,0x00000099,0x0000060c, + 0x00000253,0x0000024f,0x0004009a,0x00000071,0x0000060d,0x0000060c,0x00050050,0x00000099, + 0x00000610,0x0000060d,0x0000060d,0x000600a9,0x00000009,0x00000611,0x00000610,0x0000024f, + 0x0000024c,0x000200f9,0x00000612,0x000200f8,0x00000612,0x000700f5,0x00000009,0x0000072a, + 0x00000253,0x00000607,0x00000611,0x00000609,0x00050083,0x00000009,0x00000614,0x00000256, + 0x0000072a,0x00050051,0x00000006,0x000005bb,0x000005a7,0x00000000,0x000500b8,0x00000071, + 0x000005bc,0x000005bb,0x000001a1,0x000300f7,0x000005c3,0x00000000,0x000400fa,0x000005bc, + 0x000005bd,0x000005c0,0x000200f8,0x000005bd,0x000200f9,0x000005c3,0x000200f8,0x000005c0, + 0x0007004f,0x00000009,0x000005c2,0x000005b4,0x000005b4,0x00000000,0x00000001,0x000200f9, + 0x000005c3,0x000200f8,0x000005c3,0x000700f5,0x00000009,0x0000072c,0x00000600,0x000005bd, + 0x000005c2,0x000005c0,0x00050051,0x00000006,0x000005c6,0x000005a7,0x00000002,0x000500ba, + 0x00000071,0x000005c7,0x000005c6,0x000001b0,0x000300f7,0x000005ce,0x00000000,0x000400fa, + 0x000005c7,0x000005c8,0x000005cb,0x000200f8,0x000005c8,0x000200f9,0x000005ce,0x000200f8, + 0x000005cb,0x0007004f,0x00000009,0x000005cd,0x000005b4,0x000005b4,0x00000002,0x00000003, + 0x000200f9,0x000005ce,0x000200f8,0x000005ce,0x000700f5,0x00000009,0x0000072d,0x00000614, + 0x000005c8,0x000005cd,0x000005cb,0x00050094,0x00000006,0x0000061e,0x0000072c,0x0000072d, + 0x00050094,0x00000006,0x00000621,0x0000072c,0x0000072c,0x00050094,0x00000006,0x00000624, + 0x0000072d,0x0000072d,0x00050085,0x00000006,0x00000625,0x00000621,0x00000624,0x000500b4, + 0x00000071,0x00000627,0x00000625,0x00000048,0x000300f7,0x0000062f,0x00000000,0x000400fa, + 0x00000627,0x00000628,0x00000629,0x000200f8,0x00000628,0x000200f9,0x0000062f,0x000200f8, + 0x00000629,0x0006000c,0x00000006,0x0000062c,0x00000001,0x00000020,0x00000625,0x00050085, + 0x00000006,0x0000062d,0x0000061e,0x0000062c,0x0008000c,0x00000006,0x0000062e,0x00000001, + 0x0000002b,0x0000062d,0x0000007b,0x00000047,0x000200f9,0x0000062f,0x000200f8,0x0000062f, + 0x000700f5,0x00000006,0x0000072e,0x00000047,0x00000628,0x0000062e,0x00000629,0x0006000c, + 0x00000006,0x000005d3,0x00000001,0x00000011,0x0000072e,0x000200f9,0x000005d4,0x000200f8, + 0x000005d4,0x000700f5,0x00000006,0x0000072f,0x00000048,0x00000527,0x000005d3,0x0000062f, + 0x00050085,0x00000006,0x00000326,0x0000072f,0x00000325,0x00050083,0x00000006,0x00000327, + 0x00000047,0x00000326,0x00050094,0x00000006,0x0000032f,0x00000475,0x00000475,0x00050085, + 0x00000006,0x00000332,0x00000314,0x00000314,0x00050088,0x00000006,0x00000333,0x0000032f, + 0x00000332,0x00050083,0x00000006,0x00000336,0x00000333,0x00000047,0x00050085,0x00000006, + 0x00000337,0x00000336,0x00000139,0x0007000c,0x00000006,0x0000033a,0x00000001,0x00000025, + 0x00000327,0x00000337,0x0007000c,0x00000006,0x0000033d,0x00000001,0x00000025,0x0000033a, + 0x0000033c,0x00050085,0x00000006,0x00000340,0x00000139,0x0000033d,0x0004003d,0x00000342, + 0x00000345,0x00000344,0x0004003d,0x00000346,0x00000349,0x00000348,0x00050056,0x0000034a, + 0x0000034b,0x00000345,0x00000349,0x00050050,0x00000009,0x0000034d,0x00000340,0x00000047, + 0x00070058,0x00000007,0x0000034e,0x0000034b,0x0000034d,0x00000002,0x00000048,0x00050051, + 0x00000006,0x0000034f,0x0000034e,0x00000000,0x00050085,0x00000006,0x00000350,0x0000034f, + 0x00000156,0x00050081,0x00000006,0x00000351,0x00000350,0x00000047,0x00050085,0x00000006, + 0x00000355,0x00000351,0x000002fd,0x000500b8,0x00000071,0x00000637,0x00000707,0x00000048, + 0x000300f7,0x0000063d,0x00000000,0x000400fa,0x00000637,0x00000638,0x0000063b,0x000200f8, + 0x00000638,0x0004007f,0x00000006,0x0000063a,0x00000355,0x000200f9,0x0000063d,0x000200f8, + 0x0000063b,0x000200f9,0x0000063d,0x000200f8,0x0000063d,0x000700f5,0x00000006,0x00000730, + 0x0000063a,0x00000638,0x00000355,0x0000063b,0x0006000c,0x00000006,0x00000640,0x00000001, + 0x00000004,0x00000707,0x000500ba,0x00000071,0x00000642,0x00000730,0x00000048,0x000300f7, + 0x0000064f,0x00000000,0x000400fa,0x00000642,0x00000643,0x0000064e,0x000200f8,0x00000643, + 0x000500b8,0x00000071,0x00000646,0x00000730,0x00000640,0x000300f7,0x0000064c,0x00000000, + 0x000400fa,0x00000646,0x00000647,0x0000064b,0x000200f8,0x00000647,0x00050088,0x00000006, + 0x0000064a,0x00000730,0x00000640,0x000200f9,0x0000064c,0x000200f8,0x0000064b,0x000200f9, + 0x0000064c,0x000200f8,0x0000064c,0x000700f5,0x00000006,0x00000732,0x0000064a,0x00000647, + 0x00000047,0x0000064b,0x000200f9,0x0000064f,0x000200f8,0x0000064e,0x000200f9,0x0000064f, + 0x000200f8,0x0000064f,0x000700f5,0x00000006,0x00000733,0x00000732,0x0000064c,0x00000048, + 0x0000064e,0x0009004f,0x00000007,0x0000035c,0x0000024b,0x000007e3,0x00000000,0x00000001, + 0x00000000,0x00000001,0x0009004f,0x00000007,0x0000035e,0x00000252,0x000007e3,0x00000002, + 0x00000003,0x00000002,0x00000003,0x0008000c,0x00000007,0x00000361,0x00000001,0x0000002e, + 0x0000035c,0x0000035e,0x00000360,0x0007004f,0x00000009,0x00000364,0x00000361,0x00000361, + 0x00000000,0x00000001,0x00050050,0x00000009,0x00000366,0x00000733,0x00000733,0x0008000c, + 0x00000009,0x00000367,0x00000001,0x0000002e,0x0000024f,0x00000364,0x00000366,0x0007004f, + 0x00000009,0x0000036a,0x00000361,0x00000361,0x00000002,0x00000003,0x0008000c,0x00000009, + 0x0000036d,0x00000001,0x0000002e,0x00000253,0x0000036a,0x00000366,0x000200f9,0x00000304, + 0x000200f8,0x00000304,0x000700f5,0x00000009,0x00000764,0x00000253,0x000002e7,0x0000036d, + 0x0000064f,0x000700f5,0x00000009,0x00000763,0x0000024f,0x000002e7,0x00000367,0x0000064f, + 0x000500c7,0x00000052,0x00000370,0x000002ca,0x0000036f,0x000500ab,0x00000071,0x00000371, + 0x00000370,0x00000053,0x000300f7,0x00000373,0x00000000,0x000400fa,0x00000371,0x00000372, + 0x00000373,0x000200f8,0x00000372,0x00050084,0x00000052,0x00000376,0x000006ee,0x000002ed, + 0x00060041,0x000002f0,0x00000377,0x000002eb,0x00000096,0x00000376,0x0004003d,0x00000270, + 0x00000378,0x00000377,0x0004007c,0x00000007,0x00000379,0x00000378,0x00050051,0x00000006, + 0x00000657,0x00000379,0x00000000,0x00050051,0x00000006,0x00000658,0x00000379,0x00000001, + 0x00050051,0x00000006,0x00000659,0x00000379,0x00000002,0x00050051,0x00000006,0x0000065a, + 0x00000379,0x00000003,0x00050050,0x00000009,0x0000065b,0x00000657,0x00000658,0x00050050, + 0x00000009,0x0000065c,0x00000659,0x0000065a,0x00050050,0x0000000a,0x0000065d,0x0000065b, + 0x0000065c,0x0005008e,0x00000009,0x0000037f,0x00000763,0x00000156,0x00050081,0x00000009, + 0x00000381,0x0000037f,0x00000764,0x00050081,0x00000009,0x00000383,0x00000381,0x0000024c, + 0x00050091,0x00000009,0x00000384,0x0000065d,0x00000383,0x0005008e,0x00000009,0x00000388, + 0x00000764,0x00000156,0x00050081,0x00000009,0x0000038a,0x00000388,0x00000256,0x00050081, + 0x00000009,0x0000038c,0x0000038a,0x00000763,0x00050091,0x00000009,0x0000038d,0x0000065d, + 0x0000038c,0x00050094,0x00000006,0x00000391,0x00000384,0x00000384,0x00050094,0x00000006, + 0x00000394,0x0000038d,0x0000038d,0x0007000c,0x00000006,0x00000395,0x00000001,0x00000028, + 0x00000391,0x00000394,0x0006000c,0x00000006,0x00000398,0x00000001,0x0000001f,0x00000395, + 0x00050085,0x00000006,0x00000399,0x000000d9,0x00000398,0x0006000c,0x00000006,0x0000039a, + 0x00000001,0x0000001f,0x00000399,0x0006000c,0x00000006,0x0000039b,0x00000001,0x00000009, + 0x0000039a,0x0007000c,0x00000006,0x0000039c,0x00000001,0x00000028,0x0000039b,0x00000047, + 0x0004006d,0x00000052,0x0000039e,0x0000039c,0x0007000c,0x00000052,0x000003a0,0x00000001, + 0x00000026,0x0000039e,0x000002bc,0x000200f9,0x00000373,0x000200f8,0x00000373,0x000700f5, + 0x00000052,0x0000077a,0x000002bc,0x00000304,0x000003a0,0x00000372,0x00050080,0x00000052, + 0x000003a4,0x0000077a,0x000002c2,0x00050080,0x00000052,0x000003a6,0x000003a4,0x000002c7, + 0x00050082,0x00000052,0x000003a7,0x000003a6,0x00000059,0x000500b7,0x00000099,0x00000665, + 0x0000024c,0x00000763,0x0004009a,0x00000071,0x00000666,0x00000665,0x000300f7,0x00000672, + 0x00000000,0x000400fa,0x00000666,0x00000667,0x00000669,0x000200f8,0x00000667,0x000200f9, + 0x00000672,0x000200f8,0x00000669,0x000500b7,0x00000099,0x0000066c,0x00000763,0x00000764, + 0x0004009a,0x00000071,0x0000066d,0x0000066c,0x00050050,0x00000099,0x00000670,0x0000066d, + 0x0000066d,0x000600a9,0x00000009,0x00000671,0x00000670,0x00000764,0x00000256,0x000200f9, + 0x00000672,0x000200f8,0x00000672,0x000700f5,0x00000009,0x0000077d,0x00000763,0x00000667, + 0x00000671,0x00000669,0x00050083,0x00000009,0x00000675,0x0000077d,0x0000024c,0x000500b7, + 0x00000099,0x0000067a,0x00000256,0x00000764,0x0004009a,0x00000071,0x0000067b,0x0000067a, + 0x000300f7,0x00000687,0x00000000,0x000400fa,0x0000067b,0x0000067c,0x0000067e,0x000200f8, + 0x0000067c,0x000200f9,0x00000687,0x000200f8,0x0000067e,0x000500b7,0x00000099,0x00000681, + 0x00000764,0x00000763,0x0004009a,0x00000071,0x00000682,0x00000681,0x00050050,0x00000099, + 0x00000685,0x00000682,0x00000682,0x000600a9,0x00000009,0x00000686,0x00000685,0x00000763, + 0x0000024c,0x000200f9,0x00000687,0x000200f8,0x00000687,0x000700f5,0x00000009,0x0000079a, + 0x00000764,0x0000067c,0x00000686,0x0000067e,0x00050083,0x00000009,0x00000689,0x00000256, + 0x0000079a,0x00050050,0x0000000a,0x000007e4,0x00000675,0x00000689,0x00050094,0x00000006, + 0x00000693,0x00000675,0x00000689,0x00050094,0x00000006,0x00000696,0x00000675,0x00000675, + 0x00050094,0x00000006,0x00000699,0x00000689,0x00000689,0x00050085,0x00000006,0x0000069a, + 0x00000696,0x00000699,0x000500b4,0x00000071,0x0000069c,0x0000069a,0x00000048,0x000300f7, + 0x000006a4,0x00000000,0x000400fa,0x0000069c,0x0000069d,0x0000069e,0x000200f8,0x0000069d, + 0x000200f9,0x000006a4,0x000200f8,0x0000069e,0x0006000c,0x00000006,0x000006a1,0x00000001, + 0x00000020,0x0000069a,0x00050085,0x00000006,0x000006a2,0x00000693,0x000006a1,0x0008000c, + 0x00000006,0x000006a3,0x00000001,0x0000002b,0x000006a2,0x0000007b,0x00000047,0x000200f9, + 0x000006a4,0x000200f8,0x000006a4,0x000700f5,0x00000006,0x0000079c,0x00000047,0x0000069d, + 0x000006a3,0x0000069e,0x0006000c,0x00000006,0x000003ba,0x00000001,0x00000011,0x0000079c, + 0x00040070,0x00000006,0x000003be,0x000002c2,0x00050088,0x00000006,0x000003bf,0x000003ba, + 0x000003be,0x00050083,0x00000009,0x000003c3,0x00000764,0x0000024c,0x00050083,0x00000009, + 0x000003c6,0x00000256,0x00000763,0x00050050,0x0000000a,0x000003cd,0x000003c3,0x000003c6, + 0x0006000c,0x00000006,0x000003ce,0x00000001,0x00000021,0x000003cd,0x000500b4,0x00000071, + 0x000003d0,0x000003ce,0x00000048,0x000300f7,0x000003d2,0x00000000,0x000400fa,0x000003d0, + 0x000003d1,0x000003d2,0x000200f8,0x000003d1,0x0006000c,0x00000006,0x000003d4,0x00000001, + 0x00000021,0x000007e4,0x000200f9,0x000003d2,0x000200f8,0x000003d2,0x000700f5,0x00000006, + 0x000007a3,0x000003ce,0x000006a4,0x000003d4,0x000003d1,0x000500b8,0x00000071,0x000003d6, + 0x000007a3,0x00000048,0x000300f7,0x000003d8,0x00000000,0x000400fa,0x000003d6,0x000003d7, + 0x000003d8,0x000200f8,0x000003d7,0x0004007f,0x00000006,0x000003da,0x000003bf,0x000200f9, + 0x000003d8,0x000200f8,0x000003d8,0x000700f5,0x00000006,0x000007ca,0x000003bf,0x000003d2, + 0x000003da,0x000003d7,0x00050051,0x00000006,0x000003df,0x0000024b,0x00000000,0x00050051, + 0x00000006,0x000003e0,0x0000024b,0x00000001,0x00050051,0x00000006,0x000003e1,0x00000763, + 0x00000000,0x00050051,0x00000006,0x000003e2,0x00000763,0x00000001,0x00070050,0x00000007, + 0x000003e3,0x000003df,0x000003e0,0x000003e1,0x000003e2,0x0003003e,0x000003dc,0x000003e3, + 0x00050051,0x00000006,0x000003e7,0x00000764,0x00000000,0x00050051,0x00000006,0x000003e8, + 0x00000764,0x00000001,0x00050051,0x00000006,0x000003e9,0x00000252,0x00000002,0x00050051, + 0x00000006,0x000003ea,0x00000252,0x00000003,0x00070050,0x00000007,0x000003eb,0x000003e7, + 0x000003e8,0x000003e9,0x000003ea,0x0003003e,0x000003e4,0x000003eb,0x00040070,0x00000006, + 0x000003ee,0x000003a7,0x00050051,0x00000006,0x000003f1,0x000007b2,0x00000000,0x00050083, + 0x00000006,0x000003f2,0x0000028e,0x000003f1,0x0006000c,0x00000006,0x000003f3,0x00000001, + 0x00000004,0x000003f2,0x00050083,0x00000006,0x000003f4,0x000003ee,0x000003f3,0x000500c4, + 0x00000052,0x000003f8,0x000002c7,0x000002c0,0x000500c5,0x00000052,0x000003fa,0x000003f8, + 0x0000077a,0x00040070,0x00000006,0x000003fb,0x000003fa,0x00070050,0x00000007,0x000003fd, + 0x000003f4,0x000003ee,0x000003fb,0x000007ca,0x0003003e,0x000003ec,0x000003fd,0x000500ac, + 0x00000071,0x000003ff,0x000002c7,0x00000059,0x000300f7,0x00000401,0x00000000,0x000400fa, + 0x000003ff,0x00000400,0x00000401,0x000200f8,0x00000400,0x0004003d,0x00000007,0x00000405, + 0x00000261,0x00050051,0x00000006,0x00000409,0x00000405,0x00000000,0x00050051,0x00000006, + 0x0000040a,0x00000405,0x00000001,0x00050050,0x00000009,0x0000040c,0x00000409,0x0000040a, + 0x00050050,0x0000000a,0x0000040d,0x00000689,0x0000040c,0x00050094,0x00000006,0x000006ad, + 0x00000689,0x0000040c,0x00050094,0x00000006,0x000006b3,0x0000040c,0x0000040c,0x00050085, + 0x00000006,0x000006b4,0x00000699,0x000006b3,0x000500b4,0x00000071,0x000006b6,0x000006b4, + 0x00000048,0x000300f7,0x000006be,0x00000000,0x000400fa,0x000006b6,0x000006b7,0x000006b8, + 0x000200f8,0x000006b7,0x000200f9,0x000006be,0x000200f8,0x000006b8,0x0006000c,0x00000006, + 0x000006bb,0x00000001,0x00000020,0x000006b4,0x00050085,0x00000006,0x000006bc,0x000006ad, + 0x000006bb,0x0008000c,0x00000006,0x000006bd,0x00000001,0x0000002b,0x000006bc,0x0000007b, + 0x00000047,0x000200f9,0x000006be,0x000200f8,0x000006be,0x000700f5,0x00000006,0x000007cb, + 0x00000047,0x000006b7,0x000006bd,0x000006b8,0x0006000c,0x00000006,0x00000416,0x00000001, + 0x00000011,0x000007cb,0x00040070,0x00000006,0x00000419,0x000002c7,0x000500c7,0x00000052, + 0x0000041c,0x000002ca,0x0000041b,0x000500aa,0x00000071,0x0000041e,0x0000041c,0x0000041d, + 0x000300f7,0x00000420,0x00000000,0x000400fa,0x0000041e,0x0000041f,0x00000420,0x000200f8, + 0x0000041f,0x00050083,0x00000006,0x00000422,0x00000419,0x000000dd,0x000200f9,0x00000420, + 0x000200f8,0x00000420,0x000700f5,0x00000006,0x000007d3,0x00000419,0x000006be,0x00000422, + 0x0000041f,0x00050088,0x00000006,0x00000426,0x00000416,0x000007d3,0x0006000c,0x00000006, + 0x00000428,0x00000001,0x00000021,0x0000040d,0x000500b8,0x00000071,0x00000429,0x00000428, + 0x00000048,0x000300f7,0x0000042b,0x00000000,0x000400fa,0x00000429,0x0000042a,0x0000042b, + 0x000200f8,0x0000042a,0x0004007f,0x00000006,0x0000042d,0x00000426,0x000200f9,0x0000042b, + 0x000200f8,0x0000042b,0x000700f5,0x00000006,0x000007d4,0x00000426,0x00000420,0x0000042d, + 0x0000042a,0x00050041,0x00000433,0x00000434,0x00000430,0x00000053,0x0003003e,0x00000434, + 0x00000409,0x00050041,0x00000433,0x00000436,0x00000430,0x00000059,0x0003003e,0x00000436, + 0x0000040a,0x00050041,0x00000433,0x00000439,0x00000430,0x000001ad,0x0003003e,0x00000439, + 0x000007d4,0x000200f9,0x00000401,0x000200f8,0x00000401,0x000500b8,0x00000071,0x0000043c, + 0x0000028e,0x0000028a,0x000300f7,0x0000043e,0x00000000,0x000400fa,0x0000043c,0x0000043d, + 0x0000043e,0x000200f8,0x0000043d,0x000500c5,0x00000052,0x00000441,0x000002ca,0x0000043f, + 0x000200f9,0x0000043e,0x000200f8,0x0000043e,0x000700f5,0x00000052,0x000007d8,0x000002ca, + 0x00000401,0x00000441,0x0000043d,0x0003003e,0x00000443,0x000007d8,0x00050085,0x00000006, + 0x000006c5,0x000003f1,0x00000446,0x00050083,0x00000006,0x000006c6,0x000006c5,0x00000047, + 0x00050051,0x00000006,0x000006c8,0x000007b2,0x00000001,0x00050085,0x00000006,0x000006ca, + 0x000006c8,0x000002ac,0x0006000c,0x00000006,0x000006cc,0x00000001,0x00000006,0x000002ac, + 0x00050083,0x00000006,0x000006cd,0x000006ca,0x000006cc,0x00070050,0x00000007,0x000006ce, + 0x000006c6,0x000006cd,0x00000048,0x00000047,0x00050041,0x000003db,0x00000453,0x00000451, + 0x00000096,0x0003003e,0x00000453,0x000006ce,0x000100fd,0x00010038, +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.spirv b/thirdparty/rive_renderer/source/generated/shaders/spirv/tessellate.vert.spirv new file mode 100644 index 0000000000000000000000000000000000000000..7be8b4521a7ae1a0a1569d46d54d7e975c3db138 GIT binary patch literal 15096 zcmZA73A|qOnFsKfES6HWR9j1g)~;cywY5khTuVqKN~AhhBsXc=Y;F>}3PI6Uht?8| z4z-MsqI}fUmSKu6e8w=X7S)+%TBX&^OsN|4`@Z))H)kB4oZs_%mjCl#&w1bX4q5Yq zYjrwnbl%ljyYpW`t_?eDhUtVG-o5vXpFDol!bLMiee`3yvA?@B#I0-Fp!1$C9-4pW zPMbZCa^RYs&Y_VbBhw=Nk>?Y#D)O7iZgD;!a%5yk{)@Tu!!$Uwvu>wneD9b^V|y2V zX4;It{@#U)=J!vV)z^E%;+Zp}&OhO^ebX1k?_K;3oN`p}!fA6C%<1c&)3z%oH-tqej2s^?wNkNKO`{_91b*YaOK`mrBdZGU(42_IRl zZxDUjjMcgob!w}g4Wpm5`)d0}(NAva8%IB(6~9UJS!v%~+>*iiTy*$H!H3Np$OF4( ze00F}Z1gG3-26KD(8dpL`@Ir<{Mdn*aT)j{o0x-xkJ@{Hx7JV2_-oUeKc&Ie{^3n~ z_Q05o2_Jjmkc_uAH6b`_YGPmiz_QZz@P>!k<}aLWeTQAE>u-H@`PuUpO`d&PMo!Ft zP5H4MFlY9HakCdLnl^8G-=Hn!bZv|0%o(()$G&v+WIbBr=69z?x3)(x=3=+L>1v=` zf8FuJQaxp2xTP7Kc4EKW|G^;Vo1oHbP3u!gfPin9m! zy}!lT2e>U-oc3@dTb%uXa~M`Wdjhvti!*Mx(JfA`xN$Ac{=gmF;_MOJ_!eiM;3l>> z{lp#B;_MgPlon^t;Ero?_6_d%7H5obGa}~G{@FU%Rr)pqYFGdF*o~z+%&&blB>3RO z)*h=dE?s^XfBTMIZdhCLmA*}|i~dsV?Y8XAYOD5XwN-k%Eqk}xg0&@HZu&MF%B3!Q zdjJpZV!q~>FI(I9z(L<39p`|HAKZ?kx8n|J`8qS&`^ve|-dE0!_P%m{wD*-W#G27A z%$8fXFV2*7ue(-Zm$m7#esOCAPYPB1ZE%GXCR&WA2X2#~a-tPkR~e`4d0myhn*Q~4G)SWLBlW;o|oh_SW_o^RdXiA&d)e@tBd@3x^Y^jjK^eR+e$ zRPFbLdpmQZv1fa(4DvWf3Tk4Mya{{ePfermz*H(uSM+hw&;s7*f#xM`o{Hx z>;4nbZ&+~V{vXK5j}7Ky9kj2~)ptOATzu6>uk(MiRC!Qzem#vJogcl<`_0q;L!--4 zb@c|{x_qbo^})V4KDs?h*htOC{NP+8wewsswe}L-^8u$_y5~b%_k5sNzReA0rnK}e z2lRFAol(KYgunK7jSl1Gr+dDXefI{p*W3Q#I-Mom__2-MIuK9y461s>9TYwO`)m>W z5y3d;^oStOAAQBK5p_+>T@H46=>wk`Q)?{t)h`mbN1kC>9`P8s#JnEHd*8lc?c0Om z;Jl)1>#$(w(}Za9j1R^U*BX(sO=#Je<*z)GLO9pTcXBX}xY~J+ZrPaSxieLIu6!zl z8l8!Mj^%g`x&D%R*?J>=5&eS4B+eN*J>uMSmaEAa&S>~I;wz6Bu@y5bSj@~w#e60h z-;NRc-x(h{U(P@BYMZZo>YSgutLmH={iKLCVQo5l7e$=M_OCXrmBkIOO?kwKt(cR8 z#aJg5b4ql4J4UQJ<$NV|%ByX@@|}_Ptbx;l+5aUq(LWy@=Q&Vqo)xUk8c#WwM8_|0 z=IWeaoacoxI5&5fF<@I7!RZftPSf7`!P@lRp#Ji4SHGHmllu7R6MylKH1QV(v#WQ0 z+6wGk6pSyQF9%nj%ID&6_{W+&mjqjD>Zm?l8XfPQ=ayua`?BbGZOBpaR|bo}B2w|o zg7M;w$u+?)W5RZIis)kT_lC1izZs18PO6`G1iSQ;?e+*x zAK=RMtzhqi>aD)t6%McORqH*`@#>$H5z?opg7Nz1JTWfShP!d$_pKake2kSC?VB@e z`2OG}k^3SKH{3rr+{)a`@8Mv4+wZZ)@6p_ApL{R4KQc2?d-MCj_{#NUFz$)SZO!;S z6^wTd7{6zNUB-{?>Bx%_;|H(T?CYNf>-&xo@y-PMO5dJ~&W;-s|L22Wh&&sy9@*Rb z`DcyYIBH*8+HC9iI#XWFSc*}Py7}JP^k-Etd-dm6(Ovq(_RGkhBHDn@ZEAisSln-O zU(#^D!$k)AF}(Bp;6FrOiRcHrv0jk-A0upP)~5X0Y3q1>;Qza{B}NUeMfe`swEKE6 zdv4vcGO+VT6ny#owej)Ha-Q;eD;)mY%~-r0jI%fHZn!lPAQ$fDhFdcnUp8xCsHC}! z8QYKuPM=^tE1QS=o59AqKRUa+y<`0^4n8`0Jzs9n#cuBpUw~F z%U1ooD0p(y&#yIgd@&qfw(|Q*@Pv2x{axe7R%gyvgYk0Id39OvPf{;i_3MgYeigSY z7{|x>T%Eh|aj&!b?F@*|t;TFf&ZiZP&9m-*W3#T=ZjZ3tnf^FuuMK7&k^29qGqiI@ zV~?pjN9cbc(#8j-lF z?dSAdYGZpQ@?u2WaP{fO!Q$k#=U$-a636yzQ}cUIuytY06nAg1 z^=}>2+W4nnzHH_9onWzS#oZq)w!N+%2*;PL{2mMz%T{yxP;kvDyD?aqyMDRX7_6QC z+gE3VlS6;XwpMJ$g-yP8UpL8l>WuaowEO(^At_g#s~beumV2Ee&jr^xQryqNIfL-U ztqO)U zyOwRD3+Z#j{nuy@QPhTX7!` z#<$zpFS@a8x3Pcpp&2~3YGZV;c(yuc4+u5}@_C=ja_x)@XWX}Kcs|vBPq04nDejP9 zJg(Y0EEuoN@;f{j-;SLa9q;?qYX8XS)xJH!r{;cgu=Z>2uL*XUd$yw@QzGUbuDL!Y zSYGv5590XnEuX2u_HBDkKOIgCTRkUwgXOAzO$)~HDQo? zE?7J%ZfRF1rJ-U2smH*CQd^`VL(VuIi^47ijb9d}w`C2#2 z;_&-mpT)c*T$T0dz5Wm3@ZLS%%H3t{;{Ou=8X>>UwQu=ET{L6%KLgayw6hF zelr+He4pjLh7j`0D3-f^nq!xnVF~AJo~-ubt}WPU(mIY7nFC z>gOiG`oyO`$KIE5ur6G69^D@u@3%#LeWbDLE87E+l@Wb|)xw94ukXzt4z`Af%ie4I zimAGHNloTKK5_C?jgJPaF{O9v^U!0_@qXV_V0iQczxhg+|~_;FYZI(_>g)AZ5xg+TfMJrAB?Z_dDmc< z{;};4*)gI&u>SF(qvL(1tTSQH41RqEwcqwN8M&-Sw!I=BkC4!KzeA_y{`t^~tBTk;4G*Z556{|k6rMp+` z?uivIpFZ-f_k`mzMtT&85NOJ%<+*r zCuaonAuhhPHfM%YBazSZc2>B`=b0s*U*-F3aOG>)B6e;o*0YSSSmQG^cjM)5eE82u zyZn4NF1E&wZF+3lXHyef{g$yHy5BP9=U(6apBRj<@BSACyR0R){s>MDaDDfGQt+$E z?YsXmIjMZle{#6`o}azG=RYNw&3Eo8uXAcJuJ-OR$%AthH>Kf>X>rFkT$&o>rZ$}L znx9XFlT(i3jtdsgALs8%J{`=Lt-jYdD~XI@of*dT>~MJF?i|4_jgI$ja!JFT8(mJe z%6CDqxOTpa!r{G}RK71o$7{RteL1>(Y<2cu6099k+}DEnk~*U=3pRE;M8xo^bLGm$ z=5rjsIxm+6`yPe8e6MQxvKN1K!y5}e)$TP7uU$SpxzEkK`;F_`=zVeD!|Xm+>`+#{H_) z>HU6YIJ`5mKX;e?fS(na9kCx^_41+PEAO0OIn90Lof{5s{dvD%5R4=B-g{y&zPn~p zS3AFU>I^tDdF5Aw7;V>k@8V$g_WS*5;jFiIJ*S7m>*p78cj+hojL7FB`UR_l4;^3q zJUdv<_V}F>4qyE|FBnIvpXUeT#ntgR>Q`oyR9^r~R}XRH13 z)!=t>mp2@~{FViaBef^43g*jpcjnFdxF#51&)*w@UB-^>?<3bnj1_F`_|WmShpr2@ zM@L5Ft2VC>Rx`WjOKzQS{})pP%$=zQ@t=8puM4|7)Bqv6bhxvY73A{<|~>hF`m+TA+BUgP<%!E802{}${r zo@`G=aK;a=e9r_|KJ#vz%g?>W;v2EaZ+yhaQSU@Q3TCgipN(E^v;8=N(>7f1c|Q#{ zKH4n1d$sxfsLm;+i-sghxcr#THcI~ zud#b8xbm@?H+}H8h-~#YA8!ZC@7dwJTtiX0tWh>a;;a+cyN@mo3-)(v)%SIx<6On9 z+i(MOI`Dq6UO2vNwWrn(b~drqnYAMNJGr|WAAWVF+#Svt##a089yn5K|G{9FKCyi} za&JVRU~8QZ9bfZwU$ELoM&zqD?+;cVd!1ts1oL%{vA55$%I#kJ=m#0Zp7?5CY`fh} z(?7YKWBh84KM>wr)qC$2(Y^O>o_qbR*N9;JmJ#zgGIy80vuzc@=__1oZ<}EGeFteg z%E!HGemb@A(GULO>rCA)SlxVT{C0@0A6rMvah**&2D8=t>>TV;Bil|9oEqUen?4+@ z9rcynz3O`=ZL_PHuh=o!GrQ;h(a3HQp9ky%x^-CgJsP`xz)rVD%f5GG_qR&ybnU67 z_J@1*@e{%J{Y4S;uwQhSKCYTe_0tRz)kNzu)`rVQxup=6KKfpXHu=&b{xw z4|~=e{I#O!QS>cpi@kak(zE8V0y z(^}e8EQBtBu7Q3HZG@KB6vaUNv|~ZIo~%+7&k>|o(Whvd*gWdA(ar5YoHnyEzq!3* z?)+)zRhp+Sm^BM=?)2G}86DX5)o$F`XEe7@n=`MqGQYLb-rn3%S=_N;ex-TVg0>kQ zEpyx22^%q+CQojfIIeldym`dDptaK6+R|2Op4l>=cr6Pn+SM8}*|oIIXk9QfH|UK; zzPH}w?fw=WTNLu{b8+I`@1zk`+QU3#VstnJ2k~zBl?gtQGPe$YV2m`!Ft(Ymv_+=dj-sd3NUC2l?DA zpT5Xv9o22$54kO~?~i;A`;K@6kS8DAE!QDWo7pW7M7|))XAttjW4iT&kr!q1UdYok z|9a%}Sl_-}MX`Q_+(d2d*8z}2*`6s|UuFBIY<-*XwRh&KPF|h0RkoMP)?V3uDm(PG zkH#5K7SYp#OKmsix?;u*JAK6LL13;SW?ci*N6cCUW}n5}e_-}nY)FRLZ?XL{%=N?? zGR(e za+v2S%-Wilanzp+X|KM6*|j}i4g7ZjvpVtbB-wi;7P9v!m%T^I`d^!PW5zyihL82F z%Svb`g^hgfK=z!4eHXlSH{Kd%W9#So%HB<}uzv)8=gys5-OmPi*AD+D;I$RkUwLD~ z!hbU|W51C9Qk83!jkTqe8yZ9ZW+^w8>#N^d%InL%DZf+7Q+L__t&|&f<-4tvi<*eH zy(;&L^>$R{UH-k?05?DEdzW%;DZAeOrCjVfHzTU@vWRz9DL1ZHw*QwPd)Gt13VBQ2 zgvOA!SN$Kio)sEr?L8mLElFl7{f)N}!TTEiOOUtJJ=19aE{C@l#}4m;KlXpg!1^V^J%Kv(GoNFRtub_d>oGtf~9GA94@IS_kHRcnGo%>O3oJ znH`=Lbq_<2LY@uz*vC3} zxkvejlizFb=CK9R?+s>$e(GL_#PpMY5keK<&M}8l|yT0#f^9vj2$Zr&SZOmDF z{k64r#%-HgGr#N50+q>xYfAxf=IN$hhXDz5cH86|=)NwD~tA<{I*G)^@^sZ+2u@4-Tz8I2>}_@N;%u@7zS{ zqo27L!&5=_3$0&e15C*E{D!FC!t%% ztj={pXZ^;byFclyL9QE%?ETlz8mNo+QXkgx`6b1BsV|uLQZU~wf%i}N;@$ANgkO~5 z<}?u8xVJ<0{(*E3`;xmkSmF()kv{e`9ejvQKXL2yJ!!s#92okg2@^Po? z;jP_fY~wk$H<-B3G5ZvL&i2W>un)Xzt%cX#n65j7+2Oj{>v7nh>eL*d1(xjk^*VaN{G)%H;6FvxY~eSi2~7!L0_a=17Bw9z(f zjz~64|6`-A`!~)iVi?QV+UxJPg1X0e#~>Etl3l#J)`P2a^y5pyI&4U`!{OB*#_V~B z?~W&ueo(TFSew9OoyXFdcoIz9vtv!3g?CsJbx%Q0L+)4J{cEEvz7#ui`UAY{=6dbo zj&`wk^~TUvUv2HZvFvx8uaWScFMm75Gy7P0ai7`dc|5$sJk=csod6k2-q_kGi^sh< z5#D>`IWo@4$Pq`~Nzgb*Klv-t*&74zIn&qJ`e~zWd^=8n_wIVe0-FTZ$pSfcDwxj% zZNu(NFmYpClg`~a2|J7V(u92%Ufj5GFPh=a%XdWhP6acjy0EJxJ8i>m7MN?Qi+9fK zWLG^?)%Qs&7=Oi3Nc~u95odoca@>zN&-0SK=UIK6&Gv+oLg8~e&QAxpI``>$S_JR< zt`qrR2qvzbJy^nQ51iwiU4p%5*}m+6zclGagI$d5?`?Izfz;i{dOn*jhgUxa{xiMn&mZ+Sq&}>KS7$$?55Iyp zo;{1b-3c#lkK%Vu7d(IEnNjb*ZA6XkNxA{(wTtJ`8hF=K@3Y&pFo?qQUQ{*Z1MIRTt;?19<+*?^E^G zKlbxs(j5q`=zbEk^5)z z=<_{(3AP2u&sr+X1VR2nXUTxR_g_WH-Y z+ZSFv?tEic-w8v&#G{wrfOnX$y01eALFOVKvG#{ImLr}e4PfHNGe2YLr++SsN6(iN zLqB7igSPQ}IRxHZeZFX?-uGpE=X?wOS`5VFIXal;iHqqU=X`jIUNdD@xN$?)dr z964=CYn=q#dF^;kj1qN-~Ygi8#jEpN`-jtTLUJpU7Y9dCmZ|Z{cA>cc%Ie$01~t3 z^4@*xUW+|#E58j~C(d~vaCMG2mwl71=TiOd@4bFW?|V<%h&2E{)`|CC9hkW1)qMAc zcbKobfzV*ceC0i}+9-?1v$Y=Hb#uLTai;G|dShs-ueMPO=dgVh-4@6@p`UTIjo%v1 zVf!*VbNBa%ei6r-u0i%Jsj57q;{GB7tOX#~Ge@_`R)-cX$P07c}3PI6Uht?8| z4z-MsqI}fUmSKu6e8w=X7S)+%TBX&^OsN|4`@Z))H)kB4oZs_%mjCl#&w1bX4q5Yq zYjrwnbl%ljyYpW`t_?eDhUtVG-o5vXpFDol!bLMiee`3yvA?@B#I0-Fp!1$C9-4pW zPMbZCa^RYs&Y_VbBhw=Nk>?Y#D)O7iZgD;!a%5yk{)@Tu!!$Uwvu>wneD9b^V|y2V zX4;It{@#U)=J!vV)z^E%;+Zp}&OhO^ebX1k?_K;3oN`p}!fA6C%<1c&)3z%oH-tqej2s^?wNkNKO`{_91b*YaOK`mrBdZGU(42_IRl zZxDUjjMcgob!w}g4Wpm5`)d0}(NAva8%IB(6~9UJS!v%~+>*iiTy*$H!H3Np$OF4( ze00F}Z1gG3-26KD(8dpL`@Ir<{Mdn*aT)j{o0x-xkJ@{Hx7JV2_-oUeKc&Ie{^3n~ z_Q05o2_Jjmkc_uAH6b`_YGPmiz_QZz@P>!k<}aLWeTQAE>u-H@`PuUpO`d&PMo!Ft zP5H4MFlY9HakCdLnl^8G-=Hn!bZv|0%o(()$G&v+WIbBr=69z?x3)(x=3=+L>1v=` zf8FuJQaxp2xTP7Kc4EKW|G^;Vo1oHbP3u!gfPin9m! zy}!lT2e>U-oc3@dTb%uXa~M`Wdjhvti!*Mx(JfA`xN$Ac{=gmF;_MOJ_!eiM;3l>> z{lp#B;_MgPlon^t;Ero?_6_d%7H5obGa}~G{@FU%Rr)pqYFGdF*o~z+%&&blB>3RO z)*h=dE?s^XfBTMIZdhCLmA*}|i~dsV?Y8XAYOD5XwN-k%Eqk}xg0&@HZu&MF%B3!Q zdjJpZV!q~>FI(I9z(L<39p`|HAKZ?ki{qk=Lt4JhjP|~AZnXE6v!lJQoFDCd10ZE_V9luC`h~HoAUnlB_4@UU^RM z`Ym~=^ozUt=#}zb7CbT{j-7sa#HH?Kxyw~`vag7gzq)@C>2yYquKX`__0FLFW>;S_ zs1Fs~Svjb05xxJ7vj+S9vFNuhU;bd_+q>)E8MGfgpsy_Z)B*qfNwe}`sj83Z>}m$L8P;P!gkKU}A?q#HlBv0De?>7GGVkGO-P$A6zK zVm~4n=bRo9EXyMv1DBZB!+7u8H>`bo zP#m0BbZs3L?0lLKO`h?=IO19(Qnm>#8?*eCXHp2~TKP^6#t~OL&(SR#vpjdEO3#%~ zg;1k2@z1dw&mq@eQZHL?q%Wdh@R-CoBd154o6d4I8N(S3|3-Y}5hJ!@W(A9x8L61h z1moK=V*fkiBj?NcM_z67l~0}Xb9Ysp^P-;=(I%`-XYZnj^Vt5?rnR!T;k7A`7_k*| za4wOQjS=aT67 z<;`536O8k`Fb3!5?lJ~!OCvb_fzN5$J3m;P-W$|kKJMyQ({EBAAARC4{*fmB!eDmw z&QDu`or{9;<@4p>>Qnh#91j0jljo9PYfT;1r%R*bz4P3X%yM5A9j^^JD*nn~@mEAD zepxVHyfL{Z*kw%Eu8w>?Vocz(Q;RmP4Ysy=f{lqdK789czSiPz<1bDgv3w^cpM89N zu)6syZQ8goy889QJTK4v*2papV^DkGwuV2iiCYm}EdJhb_USi+@!m=G^NwJbezM&j z!RZ5BxxN+beNesC_q)R3^}TAnCpupJlQKg3^i(ij-<&7LrP^>eF8scggN=`|5~F={ zW)0sTyd-j8~1Ot8!Nu{|AmF=G7S^_qSC(_nqyF(TfXU|;FmbJ5vxW8(jO@C%V=Bi18( zdq4lIu^UJ2YfGDL9bae4s~Jl%>QOh}Tbur@3TChV{3^Ojf7pH*`BOw2@VQORuLg_z zZSG4N?svGzKtG0eejogY$SV>3U^mtaa{pt5P0iYrUps9buMhlxm$t;H;k5|gBb#<# z4`$D;dsYT^-iU%PpT9Ofo>|UQK5vD?f4dorw}Wx^#@!9KMgru*-P~|%hU3d-4Gfhu zmoZ}-62a*c%x7iuaDOw{SocR~cei(}|HZ*aC$DGudZ|#2r-rj`#y0k<>-6w!wU5sX zcBz5wj0jE}uyIub9dBIZKPy1wKN<*wmQ4c3sw`kpy|{3 z!F<`OpBDvBZu?2bD|8$0S z?r7{Wb?1ov>k+&*;i~=mVD)RexErJ6aaI4#(ee6JXY%r3e)?9iw+1`A+3Gp)crd=! z&y&F}>xb=oksn6X2G-g%| znrTOzJUt07U$u%=pV-pfE7m#^FP}b^uk|C=-I;2QSy$Fky>rzXwQg#D?+LapteN8O z4YvNRgIXK^6wH^c{Js+`maVw^gT=Pj)dS)9vX$S1!D88JP9F-cIb}BnD|6Q`_Zow> z(|`NwjBs-3PubRr&A711*Y4{kIZvI@K7)3jzdj`8s&jRN=-P6xbL6?;I!B88SvY49 zzPMH4@cb{%_&bw-*>JvVGmf~I!r`5p<+oXMynYq8MRYmsy^7s3I$yT(+bS3@w*0n^ zj&IkpO?14usqy|$bmKiX!d}mZ?Sk2A5A6`_vKQF4kKl|IY@VKJbbRfNoq~H3Cs)ipg{SpV5-ee4#j?`*~G9*o!5irpjnsz^I_&*;8yWUKYNSFm`t%C~p0@n9?N znwhhmx+V2V0M?S?J z5{$=HTZaYXwOM|L2jknZ6QkpOzgq1d8NJ%KC-~IdPY%|8&HXjOE_2UzRAfrT+`~23 z#{|o(9_v9IAHL-?HQ2sw&*`VbiD9efL~pQM)vsy6I6lQq5B43g_~QD4<>z1AXM*vh zxX%TPC&kSTF23e&UO4e=^_*A`jIZ&zI=IG%?Zn8^h`z(M*A@mF^Q|K7c25q^Myi%m zgNv`RJ1v|(uvN~}gXP>X!d~%b2K#=zo%5`4{GENZhL%Lf`>wolo*i9Izo)QQ&U1q0 zWjDY2t&jRzvF8Pg&C%AawfHYIyuKT|YX5>@G3>QAFASDrvk1F-YwW)m-5Au^eRe<>*?ZPdDUHZ_j+b*oW04eFMP$;d;KNB?A7M7=+!3MrI9Nm+JtMqE)O=( zVynMbG&-AFde?nWZj9AN8Z|t?&bU5*pG>B4~vth z=Ih$vnn!*$j@N}}o0xMfbmzukT=8w&P2rt+Z7~kwZjOyz{DeFeakm7&)JW8B`*pVl z`P>>iKk*f}B6w9JpM&M}{!w{f4~O?z zO51M+m%))=4Pvxi?>HV_?D|#p3=1b;yPo0U@cOw? z?k@eruN7G*qF=B&_|Wl{cfH_x$Etp=9}Zvrd`~crR6jQi#_NMR+xfLq{oE=2kY5dA zv|at&Bv_yL)aTgyG7i>-tInhQqvQRysIQMSc70`gAhI%|Z?IbU(DC)X`NP515OLXi zZC^1}_b#c)Jjf?bo~rTDU^S-nPJJGFEIQurn`(SA*ri6c$0I+8s0r3CA3DBjd?L7N zls~Tx|Ib%U)%fAmXbj~OCr`bvjR>y~e2Uw;;qb+MC>$SB&!BC?@nx&`mF_de0}XWOO*K4sgtW#i|! z%E~o5SROvU=kr^lzbzTp=m+KQZ$|v)cy#*c_r}8_eDL)>(&52!sdGxkKf}^FB066- zYu7l|o|zDi-BqvEjwlUYQWxr8c$$B1c5D z4OgEI3Kl1?K8?@4;@Em3hegD}wT=!At~mV=$A@oQ$5+2Tl6J(&)00NZSFK{zC$@C= zirqc2;^osvzV)7PT*k=nn|?EO86TH>`TT8sCN)0RNz}A7a9=NfeJ6BUNHL=#a*8=V zQs?B1U_Qjfx7Oy&aB3v-dEU+nSNS}%#Ph3spAD{j?OMdnZN++)@fB-)hURX(+>Hi zHMxEFKPD%Y@A*#-SKsrq*Z2IV1he_hJ>_*y4aU{pJtlc@uHvRNoG~r#*oI3}gWS}H z6JGQ4sc>@2QQUFC;`!tJUCF0|`Lfmb8fPVuF|0Ggn4TRDZ`_?DxTVqY-c2rPxO1b+ z$yWI;2o~4QcTqUJcazHZrRaEVSH3StmyfN^{!4ue@`^;jKUK_X~n?q~3c^490iY zOzLXq*G`=QXC|-wY7nFCdhcBv%-(*#KP{Z~)~@IDaCrUvLhdg8#GeuQd_=!sb?~9% ztDk2F%h?{kbHd@PpXUYRNcHplV7$0`zpwo6)z7P9mtPHHv|atYFj$}X)Sg}ytp9Aa zKfW6LPVVxC!S%U1n;GFZD?N7!pT|23Gc#`E8T zUB;8`sR+*a!Ikfs;L2y-jdS_A*I0ZbHu;T@7&+>l=tsfq)%LT|t8KO)M{wGP>pkzM z!Ny0MWp}SOzn`4!>fkH3o?|Ztdxvoq_w$C+pW^-_oH2D3_n!^NufD(eML0R-5W{D` z?CIxoXRFv>1)DopaW6GoyWL-h^Zum7@_V`AavN;-l_+w`A%>53SLM!D>+02DXK&^D zL$JT|a9Kmv-XFtVoCeuye*YA#F7LnW<@;K&ob3J%%Jbp%U}ycx$afp=FX8Z>4OPpV z(eX8QZv|IAHuI(r{uYs~{^sNDVEH{eoR@1TDwj3NrbwK10(SM2S?15mu&N24(IaaydYajg}gV+;a?Tc-< zyJ`9-mvf9?&G84qo2z>7-6Fd8-pzBbzx5gsjNdY1K1b&6(s#D4A~=18Ywc|lEWhs{ zjYs*oSItkS7C!pHUwoaZ+XbtePmSLW(e-2Nh&isaX~$r;nxCD6U20_8DS}fYTxZjV zgSDf+vb$G(&!la3HS-laCVOW0+&>!GE#mWleL%Mk%f3frw-4Cq)@a%HZtVV6iJh)J zwbcG_uReYv*uK9gVjlL3?$SrLeIq!1gllh)2{xzu=Pq~oxa+4g;n}pyM|=FcxzdKe z>t(BT`rXWvbLXJ&HP4TR!}lal?bFAjJGabL#eP2={e#`3w;GdcD6TVa1+Vl3(W-%9qqBL4^G*_IUm literal 0 HcmV?d00001 diff --git a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.exports.h b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.hpp index 170682e4d..5e8f4bbb1 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.glsl.hpp @@ -1,15 +1,15 @@ #pragma once -#include "stencil_draw.exports.h" +#include "stencil_draw.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char stencil_draw[] = R"===(#ifdef AB -U0(f0)i0(0,a4,IB);V0 P2 Q2 E3 F3 q1(UE,f0,B,n,K){f Q=F2(IB.xy);uint X5=floatBitsToUint(IB.z)&0xffffu;Q.z=S8(X5);h1(Q);} +const char stencil_draw[] = R"===(#ifdef BB +A1(c0)r0(0,I3,JB);B1 P3 Q3 B4 C4 C1(LF,c0,G,v,S){v0(v,G,JB,I3);g O=H3(JB.xy);uint Z6=floatBitsToUint(JB.z)&0xffffu;O.z=ca(Z6);D1(O);} #endif -#ifdef HB -R2 S2 e2(i,MD){f2(E1(.0));} +#ifdef EB +y3 z3 V2(i,YD){F2(B0(.0));} #endif )==="; } // namespace glsl diff --git a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.minified.glsl b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.minified.glsl index 7a5389a68..af31d2e39 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.minified.glsl +++ b/thirdparty/rive_renderer/source/generated/shaders/stencil_draw.minified.glsl @@ -1,6 +1,6 @@ #ifdef VERTEX -U0(f0)i0(0,a4,IB);V0 P2 Q2 E3 F3 q1(UE,f0,B,n,K){f Q=F2(IB.xy);uint X5=floatBitsToUint(IB.z)&0xffffu;Q.z=S8(X5);h1(Q);} +A1(c0)r0(0,I3,JB);B1 P3 Q3 B4 C4 C1(LF,c0,G,v,S){v0(v,G,JB,I3);g O=H3(JB.xy);uint Z6=floatBitsToUint(JB.z)&0xffffu;O.z=ca(Z6);D1(O);} #endif #ifdef FRAGMENT -R2 S2 e2(i,MD){f2(E1(.0));} +y3 z3 V2(i,YD){F2(B0(.0));} #endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/tessellate.exports.h b/thirdparty/rive_renderer/source/generated/shaders/tessellate.exports.h deleted file mode 100644 index 7d86e26b3..000000000 --- a/thirdparty/rive_renderer/source/generated/shaders/tessellate.exports.h +++ /dev/null @@ -1,208 +0,0 @@ -#pragma once - -#define GLSL_ATLAS_BLIT "CB" -#define GLSL_ATLAS_BLIT_raw CB -#define GLSL_ATLAS_FEATHERED_FILL "QE" -#define GLSL_ATLAS_FEATHERED_FILL_raw QE -#define GLSL_ATLAS_FEATHERED_STROKE "SE" -#define GLSL_ATLAS_FEATHERED_STROKE_raw SE -#define GLSL_BASE_INSTANCE_UNIFORM_NAME "ED" -#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw ED -#define GLSL_BORROWED_COVERAGE_PREPASS "OC" -#define GLSL_BORROWED_COVERAGE_PREPASS_raw OC -#define GLSL_CLEAR_CLIP "OE" -#define GLSL_CLEAR_CLIP_raw OE -#define GLSL_CLEAR_COLOR "RD" -#define GLSL_CLEAR_COLOR_raw RD -#define GLSL_CLEAR_COVERAGE "NE" -#define GLSL_CLEAR_COVERAGE_raw NE -#define GLSL_CLOCKWISE_FILL "AD" -#define GLSL_CLOCKWISE_FILL_raw AD -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "LC" -#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw LC -#define GLSL_COLOR_PLANE_IDX_OVERRIDE "LD" -#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw LD -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "FE" -#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw FE -#define GLSL_DRAW_IMAGE "UC" -#define GLSL_DRAW_IMAGE_raw UC -#define GLSL_DRAW_IMAGE_MESH "UD" -#define GLSL_DRAW_IMAGE_MESH_raw UD -#define GLSL_DRAW_IMAGE_RECT "TC" -#define GLSL_DRAW_IMAGE_RECT_raw TC -#define GLSL_DRAW_INTERIOR_TRIANGLES "GB" -#define GLSL_DRAW_INTERIOR_TRIANGLES_raw GB -#define GLSL_DRAW_PATH "KC" -#define GLSL_DRAW_PATH_raw KC -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "VD" -#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw VD -#define GLSL_ENABLE_ADVANCED_BLEND "FB" -#define GLSL_ENABLE_ADVANCED_BLEND_raw FB -#define GLSL_ENABLE_CLIPPING "T" -#define GLSL_ENABLE_CLIPPING_raw T -#define GLSL_ENABLE_CLIP_RECT "BB" -#define GLSL_ENABLE_CLIP_RECT_raw BB -#define GLSL_ENABLE_EVEN_ODD "IC" -#define GLSL_ENABLE_EVEN_ODD_raw IC -#define GLSL_ENABLE_FEATHER "EB" -#define GLSL_ENABLE_FEATHER_raw EB -#define GLSL_ENABLE_HSL_BLEND_MODES "XB" -#define GLSL_ENABLE_HSL_BLEND_MODES_raw XB -#define GLSL_ENABLE_INSTANCE_INDEX "OD" -#define GLSL_ENABLE_INSTANCE_INDEX_raw OD -#define GLSL_ENABLE_KHR_BLEND "KD" -#define GLSL_ENABLE_KHR_BLEND_raw KD -#define GLSL_ENABLE_MIN_16_PRECISION "PD" -#define GLSL_ENABLE_MIN_16_PRECISION_raw PD -#define GLSL_ENABLE_NESTED_CLIPPING "CD" -#define GLSL_ENABLE_NESTED_CLIPPING_raw CD -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "QD" -#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw QD -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "FC" -#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw FC -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "QB" -#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw QB -#define GLSL_FRAGMENT "HB" -#define GLSL_FRAGMENT_raw HB -#define GLSL_FRAMEBUFFER_BOTTOM_UP "DE" -#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw DE -#define GLSL_FlushUniforms "VB" -#define GLSL_FlushUniforms_raw VB -#define GLSL_GLSL_VERSION "WB" -#define GLSL_GLSL_VERSION_raw WB -#define GLSL_INITIALIZE_PLS "WD" -#define GLSL_INITIALIZE_PLS_raw WD -#define GLSL_ImageDrawUniforms "EC" -#define GLSL_ImageDrawUniforms_raw EC -#define GLSL_LOAD_COLOR "TD" -#define GLSL_LOAD_COLOR_raw TD -#define GLSL_OPTIONALLY_FLAT "OB" -#define GLSL_OPTIONALLY_FLAT_raw OB -#define GLSL_PLS_BLEND_SRC_OVER "ZB" -#define GLSL_PLS_BLEND_SRC_OVER_raw ZB -#define GLSL_PLS_IMPL_ANGLE "_EXPORTED_PLS_IMPL_ANGLE" -#define GLSL_PLS_IMPL_ANGLE_raw _EXPORTED_PLS_IMPL_ANGLE -#define GLSL_PLS_IMPL_DEVICE_BUFFER "LE" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw LE -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "ME" -#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw ME -#define GLSL_PLS_IMPL_EXT_NATIVE "GE" -#define GLSL_PLS_IMPL_EXT_NATIVE_raw GE -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH "HE" -#define GLSL_PLS_IMPL_FRAMEBUFFER_FETCH_raw HE -#define GLSL_PLS_IMPL_NONE "KE" -#define GLSL_PLS_IMPL_NONE_raw KE -#define GLSL_PLS_IMPL_STORAGE_TEXTURE "IE" -#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw IE -#define GLSL_PLS_IMPL_SUBPASS_LOAD "JE" -#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw JE -#define GLSL_POST_INVERT_Y "EE" -#define GLSL_POST_INVERT_Y_raw EE -#define GLSL_RENDER_MODE_MSAA "DB" -#define GLSL_RENDER_MODE_MSAA_raw DB -#define GLSL_RESOLVE_PLS "HC" -#define GLSL_RESOLVE_PLS_raw HC -#define GLSL_STORE_COLOR "FD" -#define GLSL_STORE_COLOR_raw FD -#define GLSL_STORE_COLOR_CLEAR "XD" -#define GLSL_STORE_COLOR_CLEAR_raw XD -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "YD" -#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw YD -#define GLSL_TARGET_VULKAN "CC" -#define GLSL_TARGET_VULKAN_raw CC -#define GLSL_TESS_TEXTURE_FLOATING_POINT "CE" -#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw CE -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD "NC" -#define GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD_raw NC -#define GLSL_USING_PLS_STORAGE_TEXTURES "DD" -#define GLSL_USING_PLS_STORAGE_TEXTURES_raw DD -#define GLSL_VERTEX "AB" -#define GLSL_VERTEX_raw AB -#define GLSL_VULKAN_VENDOR_ID "BD" -#define GLSL_VULKAN_VENDOR_ID_raw BD -#define GLSL_a_args "RB" -#define GLSL_a_args_raw RB -#define GLSL_a_color0 "YC" -#define GLSL_a_color0_raw YC -#define GLSL_a_color1 "ZC" -#define GLSL_a_color1_raw ZC -#define GLSL_a_contourIDWithFlags "JD" -#define GLSL_a_contourIDWithFlags_raw JD -#define GLSL_a_imageRectVertex "YB" -#define GLSL_a_imageRectVertex_raw YB -#define GLSL_a_joinTan_and_ys "GC" -#define GLSL_a_joinTan_and_ys_raw GC -#define GLSL_a_mirroredVertexData "MB" -#define GLSL_a_mirroredVertexData_raw MB -#define GLSL_a_p0p1_ "RC" -#define GLSL_a_p0p1__raw RC -#define GLSL_a_p2p3_ "SC" -#define GLSL_a_p2p3__raw SC -#define GLSL_a_patchVertexData "LB" -#define GLSL_a_patchVertexData_raw LB -#define GLSL_a_position "SB" -#define GLSL_a_position_raw SB -#define GLSL_a_reflectionX0X1 "HD" -#define GLSL_a_reflectionX0X1_raw HD -#define GLSL_a_segmentCounts "ID" -#define GLSL_a_segmentCounts_raw ID -#define GLSL_a_span "AC" -#define GLSL_a_span_raw AC -#define GLSL_a_spanX "WC" -#define GLSL_a_spanX_raw WC -#define GLSL_a_texCoord "TB" -#define GLSL_a_texCoord_raw TB -#define GLSL_a_triangleVertex "IB" -#define GLSL_a_triangleVertex_raw IB -#define GLSL_a_x0x1 "GD" -#define GLSL_a_x0x1_raw GD -#define GLSL_a_yWithFlags "XC" -#define GLSL_a_yWithFlags_raw XC -#define GLSL_atlasFillFragmentMain "RE" -#define GLSL_atlasFillFragmentMain_raw RE -#define GLSL_atlasStrokeFragmentMain "TE" -#define GLSL_atlasStrokeFragmentMain_raw TE -#define GLSL_atlasTexture "ND" -#define GLSL_atlasTexture_raw ND -#define GLSL_atlasVertexMain "PE" -#define GLSL_atlasVertexMain_raw PE -#define GLSL_blitFragmentMain "MD" -#define GLSL_blitFragmentMain_raw MD -#define GLSL_blitVertexMain "ZD" -#define GLSL_blitVertexMain_raw ZD -#define GLSL_clearColor "SD" -#define GLSL_clearColor_raw SD -#define GLSL_colorRampFragmentMain "BE" -#define GLSL_colorRampFragmentMain_raw BE -#define GLSL_colorRampVertexMain "AE" -#define GLSL_colorRampVertexMain_raw AE -#define GLSL_contourBuffer "QC" -#define GLSL_contourBuffer_raw QC -#define GLSL_drawFragmentMain "NB" -#define GLSL_drawFragmentMain_raw NB -#define GLSL_drawVertexMain "PB" -#define GLSL_drawVertexMain_raw PB -#define GLSL_dstColorTexture "PC" -#define GLSL_dstColorTexture_raw PC -#define GLSL_featherTexture "JC" -#define GLSL_featherTexture_raw JC -#define GLSL_gradTexture "MC" -#define GLSL_gradTexture_raw MC -#define GLSL_imageTexture "UB" -#define GLSL_imageTexture_raw UB -#define GLSL_paintAuxBuffer "KB" -#define GLSL_paintAuxBuffer_raw KB -#define GLSL_paintBuffer "DC" -#define GLSL_paintBuffer_raw DC -#define GLSL_pathBuffer "JB" -#define GLSL_pathBuffer_raw JB -#define GLSL_sourceTexture "VC" -#define GLSL_sourceTexture_raw VC -#define GLSL_stencilVertexMain "UE" -#define GLSL_stencilVertexMain_raw UE -#define GLSL_tessVertexTexture "BC" -#define GLSL_tessVertexTexture_raw BC -#define GLSL_tessellateFragmentMain "WE" -#define GLSL_tessellateFragmentMain_raw WE -#define GLSL_tessellateVertexMain "VE" -#define GLSL_tessellateVertexMain_raw VE diff --git a/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.exports.h b/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.exports.h new file mode 100644 index 000000000..1f45f1c3a --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.exports.h @@ -0,0 +1,252 @@ +#pragma once + +#define GLSL_ATLAS_BLIT "DB" +#define GLSL_ATLAS_BLIT_raw DB +#define GLSL_ATLAS_FEATHERED_FILL "EC" +#define GLSL_ATLAS_FEATHERED_FILL_raw EC +#define GLSL_ATLAS_FEATHERED_STROKE "MC" +#define GLSL_ATLAS_FEATHERED_STROKE_raw MC +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE "MD" +#define GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE_raw MD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH "KD" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH_raw KD +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE "EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE" +#define GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE_raw EXPORTED_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT "LD" +#define GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT_raw LD +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM "GE" +#define GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM_raw GE +#define GLSL_BASE_INSTANCE_UNIFORM_NAME "OD" +#define GLSL_BASE_INSTANCE_UNIFORM_NAME_raw OD +#define GLSL_BORROWED_COVERAGE_PASS "QB" +#define GLSL_BORROWED_COVERAGE_PASS_raw QB +#define GLSL_CLEAR_CLIP "HF" +#define GLSL_CLEAR_CLIP_raw HF +#define GLSL_CLEAR_COLOR "DE" +#define GLSL_CLEAR_COLOR_raw DE +#define GLSL_CLEAR_COVERAGE "QD" +#define GLSL_CLEAR_COVERAGE_raw QD +#define GLSL_CLOCKWISE_FILL "YC" +#define GLSL_CLOCKWISE_FILL_raw YC +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER "TC" +#define GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER_raw TC +#define GLSL_COLOR_PLANE_IDX_OVERRIDE "XD" +#define GLSL_COLOR_PLANE_IDX_OVERRIDE_raw XD +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS "ZD" +#define GLSL_DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS_raw ZD +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS "ZE" +#define GLSL_DISABLE_SHADER_STORAGE_BUFFERS_raw ZE +#define GLSL_DRAW_IMAGE "WD" +#define GLSL_DRAW_IMAGE_raw WD +#define GLSL_DRAW_IMAGE_MESH "KB" +#define GLSL_DRAW_IMAGE_MESH_raw KB +#define GLSL_DRAW_IMAGE_RECT "CD" +#define GLSL_DRAW_IMAGE_RECT_raw CD +#define GLSL_DRAW_INTERIOR_TRIANGLES "CB" +#define GLSL_DRAW_INTERIOR_TRIANGLES_raw CB +#define GLSL_DRAW_PATH "BD" +#define GLSL_DRAW_PATH_raw BD +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS "OE" +#define GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS_raw OE +#define GLSL_ENABLE_ADVANCED_BLEND "FB" +#define GLSL_ENABLE_ADVANCED_BLEND_raw FB +#define GLSL_ENABLE_CLIPPING "M" +#define GLSL_ENABLE_CLIPPING_raw M +#define GLSL_ENABLE_CLIP_RECT "Z" +#define GLSL_ENABLE_CLIP_RECT_raw Z +#define GLSL_ENABLE_DITHER "IB" +#define GLSL_ENABLE_DITHER_raw IB +#define GLSL_ENABLE_EVEN_ODD "IC" +#define GLSL_ENABLE_EVEN_ODD_raw IC +#define GLSL_ENABLE_FEATHER "GB" +#define GLSL_ENABLE_FEATHER_raw GB +#define GLSL_ENABLE_HSL_BLEND_MODES "SB" +#define GLSL_ENABLE_HSL_BLEND_MODES_raw SB +#define GLSL_ENABLE_INSTANCE_INDEX "AE" +#define GLSL_ENABLE_INSTANCE_INDEX_raw AE +#define GLSL_ENABLE_KHR_BLEND "VD" +#define GLSL_ENABLE_KHR_BLEND_raw VD +#define GLSL_ENABLE_MIN_16_PRECISION "BE" +#define GLSL_ENABLE_MIN_16_PRECISION_raw BE +#define GLSL_ENABLE_NESTED_CLIPPING "NC" +#define GLSL_ENABLE_NESTED_CLIPPING_raw NC +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS "CE" +#define GLSL_ENABLE_RASTERIZER_ORDERED_VIEWS_raw CE +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE "KC" +#define GLSL_ENABLE_TYPED_UAV_LOAD_STORE_raw KC +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT "K" +#define GLSL_FIXED_FUNCTION_COLOR_OUTPUT_raw K +#define GLSL_FRAGMENT "EB" +#define GLSL_FRAGMENT_raw EB +#define GLSL_FRAMEBUFFER_BOTTOM_UP "PF" +#define GLSL_FRAMEBUFFER_BOTTOM_UP_raw PF +#define GLSL_FlushUniforms "MB" +#define GLSL_FlushUniforms_raw MB +#define GLSL_GLSL_VERSION "CC" +#define GLSL_GLSL_VERSION_raw CC +#define GLSL_GL_RENDERER_MALI "XE" +#define GLSL_GL_RENDERER_MALI_raw XE +#define GLSL_INITIALIZE_PLS "QE" +#define GLSL_INITIALIZE_PLS_raw QE +#define GLSL_INPUT_ATTACHMENT_BINDING "NE" +#define GLSL_INPUT_ATTACHMENT_BINDING_raw NE +#define GLSL_INPUT_ATTACHMENT_NONE "EF" +#define GLSL_INPUT_ATTACHMENT_NONE_raw EF +#define GLSL_ImageDrawUniforms "LC" +#define GLSL_ImageDrawUniforms_raw LC +#define GLSL_LOAD_COLOR "FE" +#define GLSL_LOAD_COLOR_raw FE +#define GLSL_NEEDS_CLIP_DISTANCE "KE" +#define GLSL_NEEDS_CLIP_DISTANCE_raw KE +#define GLSL_NEEDS_GAMMA_CORRECTION "VB" +#define GLSL_NEEDS_GAMMA_CORRECTION_raw VB +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND "PE" +#define GLSL_NEEDS_PATH_ID_CLAMP_WORKAROUND_raw PE +#define GLSL_NESTED_CLIP_UPDATE_ONLY "SC" +#define GLSL_NESTED_CLIP_UPDATE_ONLY_raw SC +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS "OF" +#define GLSL_NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS_raw OF +#define GLSL_NO_VARYING "LE" +#define GLSL_NO_VARYING_raw LE +#define GLSL_OPTIONALLY_FLAT "NB" +#define GLSL_OPTIONALLY_FLAT_raw NB +#define GLSL_PLS_BLEND_SRC_OVER "PC" +#define GLSL_PLS_BLEND_SRC_OVER_raw PC +#define GLSL_PLS_IMPL_ANGLE "EXPORTED_PLS_IMPL_ANGLE" +#define GLSL_PLS_IMPL_ANGLE_raw EXPORTED_PLS_IMPL_ANGLE +#define GLSL_PLS_IMPL_DEVICE_BUFFER "FF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_raw FF +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED "GF" +#define GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED_raw GF +#define GLSL_PLS_IMPL_EXT_NATIVE "AF" +#define GLSL_PLS_IMPL_EXT_NATIVE_raw AF +#define GLSL_PLS_IMPL_NONE "DF" +#define GLSL_PLS_IMPL_NONE_raw DF +#define GLSL_PLS_IMPL_STORAGE_TEXTURE "BF" +#define GLSL_PLS_IMPL_STORAGE_TEXTURE_raw BF +#define GLSL_PLS_IMPL_SUBPASS_LOAD "CF" +#define GLSL_PLS_IMPL_SUBPASS_LOAD_raw CF +#define GLSL_POST_INVERT_Y "JC" +#define GLSL_POST_INVERT_Y_raw JC +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC "PB" +#define GLSL_RENDER_MODE_CLOCKWISE_ATOMIC_raw PB +#define GLSL_RENDER_MODE_MSAA "AB" +#define GLSL_RENDER_MODE_MSAA_raw AB +#define GLSL_RESOLVE_PLS "HC" +#define GLSL_RESOLVE_PLS_raw HC +#define GLSL_SOURCE_TEXTURE_MSAA "ED" +#define GLSL_SOURCE_TEXTURE_MSAA_raw ED +#define GLSL_SPEC_CONST_NONE "ME" +#define GLSL_SPEC_CONST_NONE_raw ME +#define GLSL_STORE_COLOR "PD" +#define GLSL_STORE_COLOR_raw PD +#define GLSL_STORE_COLOR_CLEAR "RE" +#define GLSL_STORE_COLOR_CLEAR_raw RE +#define GLSL_SUPPORTS_SUBPASS_LOAD "KF" +#define GLSL_SUPPORTS_SUBPASS_LOAD_raw KF +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA "SE" +#define GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA_raw SE +#define GLSL_TARGET_SPIRV "WB" +#define GLSL_TARGET_SPIRV_raw WB +#define GLSL_TESS_TEXTURE_FLOATING_POINT "WE" +#define GLSL_TESS_TEXTURE_FLOATING_POINT_raw WE +#define GLSL_USE_FILTERING "WC" +#define GLSL_USE_FILTERING_raw WC +#define GLSL_USE_WEBGPU_SAMPLERS "YE" +#define GLSL_USE_WEBGPU_SAMPLERS_raw YE +#define GLSL_USING_PLS_STORAGE_TEXTURES "ND" +#define GLSL_USING_PLS_STORAGE_TEXTURES_raw ND +#define GLSL_VERTEX "BB" +#define GLSL_VERTEX_raw BB +#define GLSL_VULKAN_VENDOR_ID "RC" +#define GLSL_VULKAN_VENDOR_ID_raw RC +#define GLSL_a_args "RB" +#define GLSL_a_args_raw RB +#define GLSL_a_color0 "HD" +#define GLSL_a_color0_raw HD +#define GLSL_a_color1 "ID" +#define GLSL_a_color1_raw ID +#define GLSL_a_contourIDWithFlags "UD" +#define GLSL_a_contourIDWithFlags_raw UD +#define GLSL_a_imageRectVertex "YB" +#define GLSL_a_imageRectVertex_raw YB +#define GLSL_a_joinTan_and_ys "OC" +#define GLSL_a_joinTan_and_ys_raw OC +#define GLSL_a_mirroredVertexData "UB" +#define GLSL_a_mirroredVertexData_raw UB +#define GLSL_a_p0p1_ "ZC" +#define GLSL_a_p0p1__raw ZC +#define GLSL_a_p2p3_ "AD" +#define GLSL_a_p2p3__raw AD +#define GLSL_a_patchVertexData "TB" +#define GLSL_a_patchVertexData_raw TB +#define GLSL_a_position "FC" +#define GLSL_a_position_raw FC +#define GLSL_a_reflectionX0X1 "SD" +#define GLSL_a_reflectionX0X1_raw SD +#define GLSL_a_segmentCounts "TD" +#define GLSL_a_segmentCounts_raw TD +#define GLSL_a_span "AC" +#define GLSL_a_span_raw AC +#define GLSL_a_spanX "FD" +#define GLSL_a_spanX_raw FD +#define GLSL_a_texCoord "GC" +#define GLSL_a_texCoord_raw GC +#define GLSL_a_triangleVertex "JB" +#define GLSL_a_triangleVertex_raw JB +#define GLSL_a_x0x1 "RD" +#define GLSL_a_x0x1_raw RD +#define GLSL_a_yWithFlags "GD" +#define GLSL_a_yWithFlags_raw GD +#define GLSL_atlasFillFragmentMain "HE" +#define GLSL_atlasFillFragmentMain_raw HE +#define GLSL_atlasRenderTexture "JE" +#define GLSL_atlasRenderTexture_raw JE +#define GLSL_atlasResolveVertexMain "JF" +#define GLSL_atlasResolveVertexMain_raw JF +#define GLSL_atlasStrokeFragmentMain "IE" +#define GLSL_atlasStrokeFragmentMain_raw IE +#define GLSL_atlasTexture "VC" +#define GLSL_atlasTexture_raw VC +#define GLSL_atlasVertexMain "IF" +#define GLSL_atlasVertexMain_raw IF +#define GLSL_blitFragmentMain "YD" +#define GLSL_blitFragmentMain_raw YD +#define GLSL_blitVertexMain "TE" +#define GLSL_blitVertexMain_raw TE +#define GLSL_clearColor "EE" +#define GLSL_clearColor_raw EE +#define GLSL_colorRampFragmentMain "VE" +#define GLSL_colorRampFragmentMain_raw VE +#define GLSL_colorRampVertexMain "UE" +#define GLSL_colorRampVertexMain_raw UE +#define GLSL_contourBuffer "XC" +#define GLSL_contourBuffer_raw XC +#define GLSL_drawFragmentMain "HB" +#define GLSL_drawFragmentMain_raw HB +#define GLSL_drawVertexMain "XB" +#define GLSL_drawVertexMain_raw XB +#define GLSL_dstColorTexture "JD" +#define GLSL_dstColorTexture_raw JD +#define GLSL_featherTexture "QC" +#define GLSL_featherTexture_raw QC +#define GLSL_gradTexture "DD" +#define GLSL_gradTexture_raw DD +#define GLSL_imageTexture "DC" +#define GLSL_imageTexture_raw DC +#define GLSL_paintAuxBuffer "OB" +#define GLSL_paintAuxBuffer_raw OB +#define GLSL_paintBuffer "UC" +#define GLSL_paintBuffer_raw UC +#define GLSL_pathBuffer "LB" +#define GLSL_pathBuffer_raw LB +#define GLSL_sourceTexture "ZB" +#define GLSL_sourceTexture_raw ZB +#define GLSL_stencilVertexMain "LF" +#define GLSL_stencilVertexMain_raw LF +#define GLSL_tessVertexTexture "BC" +#define GLSL_tessVertexTexture_raw BC +#define GLSL_tessellateFragmentMain "NF" +#define GLSL_tessellateFragmentMain_raw NF +#define GLSL_tessellateVertexMain "MF" +#define GLSL_tessellateVertexMain_raw MF diff --git a/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.hpp b/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.hpp index 53df9614e..2d87c9aaa 100644 --- a/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.hpp +++ b/thirdparty/rive_renderer/source/generated/shaders/tessellate.glsl.hpp @@ -1,38 +1,42 @@ #pragma once -#include "tessellate.exports.h" +#include "tessellate.glsl.exports.h" namespace rive { namespace gpu { namespace glsl { -const char tessellate[] = R"===(#define Ve 10 -#ifdef AB -U0(f0)i0(0,f,RC);i0(1,f,SC);i0(2,f,GC); -#ifdef H8 -i0(3,uint,GD);i0(4,uint,HD);i0(5,uint,ID);i0(6,uint,JD); +const char tessellate[] = R"===(#define Sg 10 +#ifdef BB +A1(c0)r0(0,g,ZC);r0(1,g,AD);r0(2,g,OC); +#ifdef O9 +r0(3,uint,RD);r0(4,uint,SD);r0(5,uint,TD);r0(6,uint,UD); #else -i0(3,M,RB); +r0(3,Q,RB); #endif -V0 +B1 #endif -o1 n0 H(0,f,x5);n0 H(1,f,y5);n0 H(2,f,W3);n0 H(3,Z,J4);L2 H(4,uint,A6);p1 -#ifdef AB -P2 l5(U2,Z5,JC);Q2 P3(Z5,M8)E3 O3(Va,Td,JB);O3(Wa,Ud,QC);F3 q1(VE,f0,B,n,K){l0(K,B,RC,f);l0(K,B,SC,f);l0(K,B,GC,f); -#ifdef H8 -l0(K,B,GD,uint);l0(K,B,HD,uint);l0(K,B,ID,uint);l0(K,B,JD,uint);M RB=M(GD,HD,ID,JD); +h2 J0 d0(0,g,w6);J0 d0(1,g,x6);J0 d0(2,g,M4);J0 d0(3,V,A5);S4 d0(4,uint,I7);Z1 +#ifdef BB +P3 e6(X2,d7,QC);Q3 V3(d7,T9)B4 G4(vc,Jf,LB);G4(wc,Kf,XC);C4 C1(MF,c0,G,v,S){v0(S,G,ZC,g);v0(S,G,AD,g);v0(S,G,OC,g); +#ifdef O9 +v0(S,G,RD,uint);v0(S,G,SD,uint);v0(S,G,TD,uint);v0(S,G,UD,uint);Q RB=Q(RD,SD,TD,UD); #else -l0(K,B,RB,M); +v0(S,G,RB,Q); #endif -L(x5,f);L(y5,f);L(W3,f);L(J4,Z);L(A6,uint);c o0=RC.xy;c p0=RC.zw;c x0=SC.xy;c z0=SC.zw;bool Ub=n<4;float y=Ub?GC.z:GC.w;int E9=int(Ub?RB.x:RB.y); -#ifdef za -int Vb=E9<<16;if(RB.z==0xffffffffu){--Vb;}float O7=float(Vb>>16); +Y(w6,g);Y(x6,g);Y(M4,g);Y(A5,V);Y(I7,uint);c w0=ZC.xy;c x0=ZC.zw;c E0=AD.xy;c I0=AD.zw;bool zd=v<4;float y=zd?OC.z:OC.w;int Ma=int(zd?RB.x:RB.y); +#ifdef Xb +int Ad=Ma<<16;if(RB.z==0xffffffffu){--Ad;}float W8=float(Ad>>16); #else -float O7=float(E9<<16>>16); +float W8=float(Ma<<16>>16); #endif -float P7=float(E9>>16);c S1=c((n&1)==0?O7:P7,(n&2)==0?y+1.:y);if((P7-O7)*q.Fa<.0){S1.y=2.*y+1.-S1.y;}uint r2=RB.z&0x3ffu;uint Wb=(RB.z>>10)&0x3ffu;uint O1=RB.z>>20;uint Y=RB.w;uint R=Y!=sd?w0(QC,Aa(Y)).z:0u;M R3=R!=0u?w0(JB,R*4u+1u):M(0u,0u,0u,0u);float k2=uintBitsToFloat(R3.z);float l2=uintBitsToFloat(R3.w);if(l2!=.0&&k2==.0){float Xb;float We=Xc(o0,p0,x0,z0,Xb);float F9=l2*(1./U8);float Xe=Sc(o0,p0,x0,z0,Xb,F9);float B6=1.-Xe*(1./O2);float Ye=dot(z0-o0,z0-o0)/(F9*F9);float Ze=(Ye-1.)*.5;B6=min(B6,Ze);B6=min(B6,.99);float af=.5*B6;float x=Z4(af)*-2.+1.;float Yb=a7(x*l2,We);f Zb=mix(o0.xyxy,z0.xyxy,f(1./3.,1./3.,2./3.,2./3.));p0=mix(p0,Zb.xy,Yb);x0=mix(x0,Zb.zw,Yb);}if((Y&od)!=0u){S ac=D1(uintBitsToFloat(w0(JB,R*4u)));c bc=C0(ac,-2.*p0+x0+o0);c cc=C0(ac,-2.*x0+z0+p0);float W0=max(dot(bc,bc),dot(cc,cc));float e4=max(ceil(sqrt(.75*4.*sqrt(W0))),1.);r2=min(uint(e4),r2);}uint Q7=r2+Wb+O1-1u;S d2=D8(o0,p0,x0,z0);float O0=acos(C8(d2[0],d2[1]));float n3=O0/float(Wb);float G9=determinant(S(x0-o0,z0-p0));if(G9==.0)G9=determinant(d2);if(G9<.0)n3=-n3;x5=f(o0,p0);y5=f(x0,z0);W3=f(float(Q7)-abs(P7-S1.x),float(Q7),(O1<<10)|r2,n3);if(O1>1u){S H9=S(d2[1],GC.xy);float bf=acos(C8(H9[0],H9[1]));float dc=float(O1);if((Y&(a3|k7))==(i7|k7)){dc-=2.;}float I9=bf/dc;if(determinant(H9)<.0)I9=-I9;J4.xy=GC.xy;J4.z=I9;}if(P7>16);c l2=c((v&1)==0?W8:X8,(v&2)==0?y+1.:y);if((X8-W8)*k.Yc<.0){l2.y=2.*y+1.-l2.y;}uint N2=RB.z&0x3ffu;uint Bd=(RB.z>>10)&0x3ffu;uint f2=RB.z>>20;uint f0=RB.w;uint F8=f0&rc;uint m0=F8>0u?P0(XC,max(F8,1u)-1u).z:0u;Q I4=m0!=0u?P0(LB,m0*4u+1u):Q(0u,0u,0u,0u);float G2=uintBitsToFloat(I4.z);float H2=uintBitsToFloat(I4.w);if(H2!=.0&&G2==.0){float Cd;float Tg=Me(w0,x0,E0,I0,Cd);float Na=H2*(1./ea);float Ug=He(w0,x0,E0,I0,Cd,Na);float J7=1.-Ug*(1./x3);float Vg=dot(I0-w0,I0-w0)/(Na*Na);float Wg=(Vg-1.)*.5;J7=min(J7,Wg);J7=min(J7,.99);float Xg=.5*J7;float x=Wb(Xg)*-2.+1.;float Dd=k8(x*H2,Tg);g Ed=mix(w0.xyxy,I0.xyxy,g(1./3.,1./3.,2./3.,2./3.));x0=mix(x0,Ed.xy,Dd);E0=mix(E0,Ed.zw,Dd);}if((f0&mf)!=0u){a0 Fd=j2(uintBitsToFloat(P0(LB,m0*4u)));c Gd=Z0(Fd,-2.*x0+E0+w0);c Hd=Z0(Fd,-2.*E0+I0+x0);float o1=max(dot(Gd,Gd),dot(Hd,Hd));float J3=max(ceil(sqrt(.75*4.*sqrt(o1))),1.);N2=min(uint(J3),N2);}uint Y8=N2+Bd+f2-1u;a0 E2=L9(w0,x0,E0,I0);float j1=acos(K9(E2[0],E2[1]));float h4=j1/float(Bd);float Oa=determinant(a0(E0-w0,I0-x0));if(Oa==.0)Oa=determinant(E2);if(Oa<.0)h4=-h4;w6=g(w0,x0);x6=g(E0,I0);M4=g(float(Y8)-abs(X8-l2.x),float(Y8),(f2<<10)|N2,h4);if(f2>1u){a0 Pa=a0(E2[1],OC.xy);float Yg=acos(K9(Pa[0],Pa[1]));float Id=float(f2);if((f0&(U3|z8))==(x8|z8)){Id-=2.;}float Qa=Yg/Id;if(determinant(Pa)<.0)Qa=-Qa;A5.xy=OC.xy;A5.z=Qa;}if(X8>10);float n3=W3.w;uint Y=A6;float X3=Q7-O1;float X1=cf;if(X1<=X3){Y&=~a3;}else{o0=p0=x0=z0;d2=S(d2[1],J4.xy);r2=1.;X1-=X3;X3=O1;n3=J4.z;if((Y&a3)>i7){if(X1<2.5)Y|=V8;if(X1>1.5&&X1<3.5)Y|=Qa;}else if((Y&k7)!=0u||(Y&a3)==j7){X3-=2.;--X1;}Y|=n3<.0?l7:Ra;}c R7;float O0=.0;if(X1==.0||X1==X3||(Y&a3)>i7){bool x7=X1=0;--z5){float C6=S7+exp2(float(z5));if(C6<=ef){c K9=C6*o+df;K9=C6*K9+M5;float hf=dot(normalize(K9),J9);float L9=C6*ff+gf;L9=min(L9,O2);if(hf>=cos(L9))S7=C6;}}float jf=S7/r2;float fc=X1-S7;float T7=acos(clamp(J9.x,-1.,1.));T7=J9.y>=.0?T7:-T7;O0=fc*n3+T7;c B2=c(sin(O0),-cos(O0));float k=dot(B2,o),U7=dot(B2,r),B0=dot(B2,L1);float kf=max(U7*U7-k*B0,.0);float V1=sqrt(kf);if(U7>.0)V1=-V1;V1-=U7;float gc=-.5*V1*k;c M9=(abs(V1*V1+gc)>10);float h4=M4.w;uint f0=I7;float N4=Y8-f2;float y2=Zg;if(y2<=N4){f0&=~U3;}else{w0=x0=E0=I0;E2=a0(E2[1],A5.xy);N2=1.;y2-=N4;N4=f2;h4=A5.z;if((f0&U3)>x8){if(y2<2.5)f0|=fa;if(y2>1.5&&y2<3.5)f0|=pc;}else if((f0&z8)!=0u||(f0&U3)==y8){N4-=2.;--y2;}f0|=h4<.0?A8:qc;}c Z8;float j1=.0;if(y2==.0||y2==N4||(f0&U3)>x8){bool I8=y2=0;--Sa){float K7=a9+exp2(float(Sa));if(K7<=bh){c Ta=K7*A+ah;Ta=K7*Ta+M6;float eh=dot(normalize(Ta),Ra);float Ua=K7*ch+dh;Ua=min(Ua,x3);if(eh>=cos(Ua))a9=K7;}}float fh=a9/N2;float Kd=y2-a9;float c9=acos(clamp(Ra.x,-1.,1.));c9=Ra.y>=.0?c9:-c9;j1=Kd*h4+c9;c T2=c(sin(j1),-cos(j1));float o=dot(T2,A),d9=dot(T2,F),J1=dot(T2,d2);float gh=max(d9*d9-o*J1,.0);float q2=sqrt(gh);if(d9>.0)q2=-q2;q2-=d9;float Ld=-.5*q2*o;c Va=(abs(q2*q2+Ld)>16); +Y(w6,g);Y(x6,g);Y(M4,g);Y(A5,V);Y(I7,uint);c w0=ZC.xy;c x0=ZC.zw;c E0=AD.xy;c I0=AD.zw;bool zd=v<4;float y=zd?OC.z:OC.w;int Ma=int(zd?RB.x:RB.y); +#ifdef Xb +int Ad=Ma<<16;if(RB.z==0xffffffffu){--Ad;}float W8=float(Ad>>16); #else -float O7=float(E9<<16>>16); +float W8=float(Ma<<16>>16); #endif -float P7=float(E9>>16);c S1=c((n&1)==0?O7:P7,(n&2)==0?y+1.:y);if((P7-O7)*q.Fa<.0){S1.y=2.*y+1.-S1.y;}uint r2=RB.z&0x3ffu;uint Wb=(RB.z>>10)&0x3ffu;uint O1=RB.z>>20;uint Y=RB.w;uint R=Y!=sd?w0(QC,Aa(Y)).z:0u;M R3=R!=0u?w0(JB,R*4u+1u):M(0u,0u,0u,0u);float k2=uintBitsToFloat(R3.z);float l2=uintBitsToFloat(R3.w);if(l2!=.0&&k2==.0){float Xb;float We=Xc(o0,p0,x0,z0,Xb);float F9=l2*(1./U8);float Xe=Sc(o0,p0,x0,z0,Xb,F9);float B6=1.-Xe*(1./O2);float Ye=dot(z0-o0,z0-o0)/(F9*F9);float Ze=(Ye-1.)*.5;B6=min(B6,Ze);B6=min(B6,.99);float af=.5*B6;float x=Z4(af)*-2.+1.;float Yb=a7(x*l2,We);f Zb=mix(o0.xyxy,z0.xyxy,f(1./3.,1./3.,2./3.,2./3.));p0=mix(p0,Zb.xy,Yb);x0=mix(x0,Zb.zw,Yb);}if((Y&od)!=0u){S ac=D1(uintBitsToFloat(w0(JB,R*4u)));c bc=C0(ac,-2.*p0+x0+o0);c cc=C0(ac,-2.*x0+z0+p0);float W0=max(dot(bc,bc),dot(cc,cc));float e4=max(ceil(sqrt(.75*4.*sqrt(W0))),1.);r2=min(uint(e4),r2);}uint Q7=r2+Wb+O1-1u;S d2=D8(o0,p0,x0,z0);float O0=acos(C8(d2[0],d2[1]));float n3=O0/float(Wb);float G9=determinant(S(x0-o0,z0-p0));if(G9==.0)G9=determinant(d2);if(G9<.0)n3=-n3;x5=f(o0,p0);y5=f(x0,z0);W3=f(float(Q7)-abs(P7-S1.x),float(Q7),(O1<<10)|r2,n3);if(O1>1u){S H9=S(d2[1],GC.xy);float bf=acos(C8(H9[0],H9[1]));float dc=float(O1);if((Y&(a3|k7))==(i7|k7)){dc-=2.;}float I9=bf/dc;if(determinant(H9)<.0)I9=-I9;J4.xy=GC.xy;J4.z=I9;}if(P7>16);c l2=c((v&1)==0?W8:X8,(v&2)==0?y+1.:y);if((X8-W8)*k.Yc<.0){l2.y=2.*y+1.-l2.y;}uint N2=RB.z&0x3ffu;uint Bd=(RB.z>>10)&0x3ffu;uint f2=RB.z>>20;uint f0=RB.w;uint F8=f0&rc;uint m0=F8>0u?P0(XC,max(F8,1u)-1u).z:0u;Q I4=m0!=0u?P0(LB,m0*4u+1u):Q(0u,0u,0u,0u);float G2=uintBitsToFloat(I4.z);float H2=uintBitsToFloat(I4.w);if(H2!=.0&&G2==.0){float Cd;float Tg=Me(w0,x0,E0,I0,Cd);float Na=H2*(1./ea);float Ug=He(w0,x0,E0,I0,Cd,Na);float J7=1.-Ug*(1./x3);float Vg=dot(I0-w0,I0-w0)/(Na*Na);float Wg=(Vg-1.)*.5;J7=min(J7,Wg);J7=min(J7,.99);float Xg=.5*J7;float x=Wb(Xg)*-2.+1.;float Dd=k8(x*H2,Tg);g Ed=mix(w0.xyxy,I0.xyxy,g(1./3.,1./3.,2./3.,2./3.));x0=mix(x0,Ed.xy,Dd);E0=mix(E0,Ed.zw,Dd);}if((f0&mf)!=0u){a0 Fd=j2(uintBitsToFloat(P0(LB,m0*4u)));c Gd=Z0(Fd,-2.*x0+E0+w0);c Hd=Z0(Fd,-2.*E0+I0+x0);float o1=max(dot(Gd,Gd),dot(Hd,Hd));float J3=max(ceil(sqrt(.75*4.*sqrt(o1))),1.);N2=min(uint(J3),N2);}uint Y8=N2+Bd+f2-1u;a0 E2=L9(w0,x0,E0,I0);float j1=acos(K9(E2[0],E2[1]));float h4=j1/float(Bd);float Oa=determinant(a0(E0-w0,I0-x0));if(Oa==.0)Oa=determinant(E2);if(Oa<.0)h4=-h4;w6=g(w0,x0);x6=g(E0,I0);M4=g(float(Y8)-abs(X8-l2.x),float(Y8),(f2<<10)|N2,h4);if(f2>1u){a0 Pa=a0(E2[1],OC.xy);float Yg=acos(K9(Pa[0],Pa[1]));float Id=float(f2);if((f0&(U3|z8))==(x8|z8)){Id-=2.;}float Qa=Yg/Id;if(determinant(Pa)<.0)Qa=-Qa;A5.xy=OC.xy;A5.z=Qa;}if(X8>10);float n3=W3.w;uint Y=A6;float X3=Q7-O1;float X1=cf;if(X1<=X3){Y&=~a3;}else{o0=p0=x0=z0;d2=S(d2[1],J4.xy);r2=1.;X1-=X3;X3=O1;n3=J4.z;if((Y&a3)>i7){if(X1<2.5)Y|=V8;if(X1>1.5&&X1<3.5)Y|=Qa;}else if((Y&k7)!=0u||(Y&a3)==j7){X3-=2.;--X1;}Y|=n3<.0?l7:Ra;}c R7;float O0=.0;if(X1==.0||X1==X3||(Y&a3)>i7){bool x7=X1=0;--z5){float C6=S7+exp2(float(z5));if(C6<=ef){c K9=C6*o+df;K9=C6*K9+M5;float hf=dot(normalize(K9),J9);float L9=C6*ff+gf;L9=min(L9,O2);if(hf>=cos(L9))S7=C6;}}float jf=S7/r2;float fc=X1-S7;float T7=acos(clamp(J9.x,-1.,1.));T7=J9.y>=.0?T7:-T7;O0=fc*n3+T7;c B2=c(sin(O0),-cos(O0));float k=dot(B2,o),U7=dot(B2,r),B0=dot(B2,L1);float kf=max(U7*U7-k*B0,.0);float V1=sqrt(kf);if(U7>.0)V1=-V1;V1-=U7;float gc=-.5*V1*k;c M9=(abs(V1*V1+gc)>10);float h4=M4.w;uint f0=I7;float N4=Y8-f2;float y2=Zg;if(y2<=N4){f0&=~U3;}else{w0=x0=E0=I0;E2=a0(E2[1],A5.xy);N2=1.;y2-=N4;N4=f2;h4=A5.z;if((f0&U3)>x8){if(y2<2.5)f0|=fa;if(y2>1.5&&y2<3.5)f0|=pc;}else if((f0&z8)!=0u||(f0&U3)==y8){N4-=2.;--y2;}f0|=h4<.0?A8:qc;}c Z8;float j1=.0;if(y2==.0||y2==N4||(f0&U3)>x8){bool I8=y2=0;--Sa){float K7=a9+exp2(float(Sa));if(K7<=bh){c Ta=K7*A+ah;Ta=K7*Ta+M6;float eh=dot(normalize(Ta),Ra);float Ua=K7*ch+dh;Ua=min(Ua,x3);if(eh>=cos(Ua))a9=K7;}}float fh=a9/N2;float Kd=y2-a9;float c9=acos(clamp(Ra.x,-1.,1.));c9=Ra.y>=.0?c9:-c9;j1=Kd*h4+c9;c T2=c(sin(j1),-cos(j1));float o=dot(T2,A),d9=dot(T2,F),J1=dot(T2,d2);float gh=max(d9*d9-o*J1,.0);float q2=sqrt(gh);if(d9>.0)q2=-q2;q2-=d9;float Ld=-.5*q2*o;c Va=(abs(q2*q2+Ld)1 thread, we should + // incorporate its same logic here. + glMaxShaderCompilerThreadsKHR(2); + } +#endif +} + +void GLState::setScissor(IAABB scissor, uint32_t renderTargetHeight) +{ + assert(scissor.left >= 0); + assert(scissor.right >= scissor.left); + assert(scissor.top >= 0); + assert(scissor.bottom >= scissor.top); + setScissorRaw(scissor.left, + renderTargetHeight - scissor.bottom, + scissor.width(), + scissor.height()); +} + +void GLState::setScissorRaw(uint32_t left, + uint32_t top, + uint32_t width, + uint32_t height) +{ + if (!m_validState.scissorBox || + m_scissorBox != std::array{left, top, width, height}) + { + glScissor(left, top, width, height); + m_scissorBox = {left, top, width, height}; + m_validState.scissorBox = true; + } + + if (!m_validState.scissorEnabled || !m_scissorEnabled) + { + glEnable(GL_SCISSOR_TEST); + m_scissorEnabled = true; + m_validState.scissorEnabled = true; + } +} + +void GLState::disableScissor() +{ + if (!m_validState.scissorEnabled || m_scissorEnabled) + { + glDisable(GL_SCISSOR_TEST); + m_scissorEnabled = false; + m_validState.scissorEnabled = true; + } } static void gl_enable_disable(GLenum state, bool enabled) @@ -183,6 +243,18 @@ void GLState::setBlendEquation(gpu::BlendEquation blendEquation) glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); break; + case gpu::BlendEquation::plus: + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); + break; + case gpu::BlendEquation::min: + glBlendEquation(GL_MIN); + glBlendFunc(GL_ONE, GL_ONE); + break; + case gpu::BlendEquation::max: + glBlendEquation(GL_MAX); + glBlendFunc(GL_ONE, GL_ONE); + break; case gpu::BlendEquation::screen: glBlendEquation(GL_SCREEN_KHR); break; @@ -228,14 +300,6 @@ void GLState::setBlendEquation(gpu::BlendEquation blendEquation) case gpu::BlendEquation::luminosity: glBlendEquation(GL_HSL_LUMINOSITY_KHR); break; - case gpu::BlendEquation::plus: - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_ONE, GL_ONE); - break; - case gpu::BlendEquation::max: - glBlendEquation(GL_MAX); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - break; } m_blendEquation = blendEquation; m_validState.blendEquation = true; @@ -283,6 +347,7 @@ void GLState::setWriteMasks(bool colorWriteMask, void GLState::setPipelineState(const gpu::PipelineState& pipelineState) { + disableScissor(); // Scissor isn't currently used in the pipeline state. setDepthStencilEnabled(pipelineState.depthTestEnabled, pipelineState.stencilTestEnabled); if (pipelineState.stencilTestEnabled) diff --git a/thirdparty/rive_renderer/source/gl/gl_utils.cpp b/thirdparty/rive_renderer/source/gl/gl_utils.cpp index 91545bb13..48a932a8b 100644 --- a/thirdparty/rive_renderer/source/gl/gl_utils.cpp +++ b/thirdparty/rive_renderer/source/gl/gl_utils.cpp @@ -34,9 +34,17 @@ namespace glutils void CompileAndAttachShader(GLuint program, GLenum type, const char* source, - const GLCapabilities& capabilities) + const GLCapabilities& capabilities, + DebugPrintErrorAndAbort debugPrintErrornAndAbort) { - CompileAndAttachShader(program, type, nullptr, 0, &source, 1, capabilities); + CompileAndAttachShader(program, + type, + nullptr, + 0, + &source, + 1, + capabilities, + debugPrintErrornAndAbort); } void CompileAndAttachShader(GLuint program, @@ -45,23 +53,32 @@ void CompileAndAttachShader(GLuint program, size_t numDefines, const char* inputSources[], size_t numInputSources, - const GLCapabilities& capabilities) + const GLCapabilities& capabilities, + DebugPrintErrorAndAbort debugPrintErrornAndAbort) { GLuint shader = CompileShader(type, defines, numDefines, inputSources, numInputSources, - capabilities); + capabilities, + debugPrintErrornAndAbort); glAttachShader(program, shader); glDeleteShader(shader); } GLuint CompileShader(GLuint type, const char* source, - const GLCapabilities& capabilities) + const GLCapabilities& capabilities, + DebugPrintErrorAndAbort debugPrintErrornAndAbort) { - return CompileShader(type, nullptr, 0, &source, 1, capabilities); + return CompileShader(type, + nullptr, + 0, + &source, + 1, + capabilities, + debugPrintErrornAndAbort); } GLuint CompileShader(GLuint type, @@ -69,7 +86,8 @@ GLuint CompileShader(GLuint type, size_t numDefines, const char* inputSources[], size_t numInputSources, - const GLCapabilities& capabilities) + const GLCapabilities& capabilities, + DebugPrintErrorAndAbort debugPrintErrornAndAbort) { std::ostringstream shaderSource; shaderSource << "#version " << capabilities.contextVersionMajor @@ -106,15 +124,54 @@ GLuint CompileShader(GLuint type, { shaderSource << "#define " << GLSL_TESS_TEXTURE_FLOATING_POINT << '\n'; } + if (capabilities.isMali) + { + shaderSource << "#define " << GLSL_GL_RENDERER_MALI << '\n'; + } shaderSource << rive::gpu::glsl::glsl << "\n"; for (size_t i = 0; i < numInputSources; ++i) { shaderSource << inputSources[i] << "\n"; } - return CompileRawGLSL(type, shaderSource.str().c_str()); + return CompileRawGLSL(type, + shaderSource.str().c_str(), + debugPrintErrornAndAbort); } -[[nodiscard]] GLuint CompileRawGLSL(GLenum shaderType, const char* rawGLSL) +#ifdef DEBUG +void PrintShaderCompilationErrors(GLuint shader) +{ + GLint maxLength = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + std::vector infoLog(maxLength); + glGetShaderInfoLog(shader, maxLength, &maxLength, &infoLog[0]); + fprintf(stderr, "Failed to compile shader\n"); + // Print the error message *before* the shader in case stderr hasn't + // finished flushing when we call abort() further on. + fprintf(stderr, "%s\n", &infoLog[0]); + + GLint sourceLength = 0; + glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength); + std::vector shaderSource(sourceLength); + glGetShaderSource(shader, sourceLength, nullptr, shaderSource.data()); + int l = 1; + std::stringstream stream(shaderSource.data()); + std::string lineStr; + while (std::getline(stream, lineStr, '\n')) + { + fprintf(stderr, "%4i| %s\n", l++, lineStr.c_str()); + } + // Print the error message, again, *after* the shader where it's easier + // to find in the console. + fprintf(stderr, "%s\n", &infoLog[0]); + fflush(stderr); +} +#endif + +[[nodiscard]] GLuint CompileRawGLSL( + GLenum shaderType, + const char* rawGLSL, + DebugPrintErrorAndAbort debugPrintErrornAndAbort) { GLuint shader = glCreateShader(shaderType); #ifdef BYPASS_EMSCRIPTEN_SHADER_PARSER @@ -134,54 +191,54 @@ GLuint CompileShader(GLuint type, #endif glCompileShader(shader); #ifdef DEBUG - GLint isCompiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); - if (isCompiled == GL_FALSE) + if (debugPrintErrornAndAbort == DebugPrintErrorAndAbort::yes) { - GLint maxLength = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); - std::vector infoLog(maxLength); - glGetShaderInfoLog(shader, maxLength, &maxLength, &infoLog[0]); - fprintf(stderr, "Failed to compile shader\n"); - // Print the error message *before* the shader in case stderr hasn't - // finished flushing when we call abort() further on. - fprintf(stderr, "%s\n", &infoLog[0]); - int l = 1; - std::stringstream stream(rawGLSL); - std::string lineStr; - while (std::getline(stream, lineStr, '\n')) + GLint isCompiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) { - fprintf(stderr, "%4i| %s\n", l++, lineStr.c_str()); + PrintShaderCompilationErrors(shader); + glDeleteShader(shader); + // Give stderr another second to finish flushing before we abort. + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + abort(); } - // Print the error message, again, *after* the shader where it's easier - // to find in the console. - fprintf(stderr, "%s\n", &infoLog[0]); - fflush(stderr); - glDeleteShader(shader); - // Give stderr another second to finish flushing before we abort. - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - abort(); } +#else + std::ignore = debugPrintErrornAndAbort; #endif return shader; } -void LinkProgram(GLuint program) +#ifdef DEBUG +void PrintLinkProgramErrors(GLuint program) +{ + GLint maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + std::vector infoLog(maxLength); + glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); + fprintf(stderr, "Failed to link program %s\n", &infoLog[0]); + fflush(stderr); +} +#endif + +void LinkProgram(GLuint program, + DebugPrintErrorAndAbort debugPrintErrornAndAbort) { glLinkProgram(program); #ifdef DEBUG - GLint isLinked = 0; - glGetProgramiv(program, GL_LINK_STATUS, &isLinked); - if (isLinked == GL_FALSE) + if (debugPrintErrornAndAbort == DebugPrintErrorAndAbort::yes) { - GLint maxLength = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); - std::vector infoLog(maxLength); - glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); - fprintf(stderr, "Failed to link program %s\n", &infoLog[0]); - fflush(stderr); - abort(); + GLint isLinked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &isLinked); + if (isLinked == GL_FALSE) + { + PrintLinkProgramErrors(program); + abort(); + } } +#else + std::ignore = debugPrintErrornAndAbort; #endif } @@ -253,8 +310,8 @@ GLint gl_min_filter_for_image_filter(rive::ImageFilter filter) { switch (filter) { - case rive::ImageFilter::trilinear: - return GL_LINEAR_MIPMAP_LINEAR; + case rive::ImageFilter::bilinear: + return GL_LINEAR_MIPMAP_NEAREST; case rive::ImageFilter::nearest: return GL_NEAREST; } @@ -266,10 +323,10 @@ GLint gl_mag_filter_for_image_filter(rive::ImageFilter filter) { switch (filter) { - case rive::ImageFilter::trilinear: - return GL_LINEAR; case rive::ImageFilter::nearest: return GL_NEAREST; + case rive::ImageFilter::bilinear: + return GL_LINEAR; } RIVE_UNREACHABLE(); @@ -313,34 +370,4 @@ void Uniform1iByName(GLuint programID, const char* name, GLint value) assert(location != -1); glUniform1i(location, value); } - -// Setup a small test to verify that GL_PIXEL_LOCAL_FORMAT_ANGLE has the correct -// value. -bool validate_pixel_local_storage_angle() -{ -#if defined(RIVE_DESKTOP_GL) || defined(RIVE_WEBGL) - glutils::Texture tex; - glBindTexture(GL_TEXTURE_2D, tex); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 1, 1); - - glutils::Framebuffer fbo; - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glFramebufferTexturePixelLocalStorageANGLE(0, tex, 0, 0); - - // Clear the error queue. (Should already be empty.) - while (GLenum err = glGetError()) - { - fprintf(stderr, "WARNING: unhandled GL error 0x%x\n", err); - } - - GLint format = GL_NONE; - glGetFramebufferPixelLocalStorageParameterivANGLE( - 0, - GL_PIXEL_LOCAL_FORMAT_ANGLE, - &format); - return glGetError() == GL_NONE && format == GL_R32UI; -#else - return false; -#endif -} } // namespace glutils diff --git a/thirdparty/rive_renderer/source/gl/load_gles_extensions.cpp b/thirdparty/rive_renderer/source/gl/load_gles_extensions.cpp index e3e7b4940..0bf387155 100644 --- a/thirdparty/rive_renderer/source/gl/load_gles_extensions.cpp +++ b/thirdparty/rive_renderer/source/gl/load_gles_extensions.cpp @@ -4,9 +4,8 @@ #include "rive/renderer/gl/gles3.hpp" -#ifdef RIVE_ANDROID - #include +#include PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glDrawArraysInstancedBaseInstanceEXT = nullptr; @@ -19,11 +18,18 @@ PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT = nullptr; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = nullptr; +PFNGLBLENDBARRIERKHRPROC glBlendBarrierKHR = nullptr; +PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC +glFramebufferPixelLocalStorageSizeEXT = nullptr; +PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC glClearPixelLocalStorageuiEXT = nullptr; +PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glMaxShaderCompilerThreadsKHR = nullptr; -void LoadGLESExtensions(const GLCapabilities& extensions) +void LoadAndValidateGLESExtensions(GLCapabilities* extensions) { + assert(extensions != nullptr); + static GLCapabilities loadedExtensions{}; - if (extensions.EXT_base_instance && !loadedExtensions.EXT_base_instance) + if (extensions->EXT_base_instance && !loadedExtensions.EXT_base_instance) { glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)eglGetProcAddress( @@ -35,17 +41,33 @@ void LoadGLESExtensions(const GLCapabilities& extensions) (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) eglGetProcAddress( "glDrawElementsInstancedBaseVertexBaseInstanceEXT"); - loadedExtensions.EXT_base_instance = true; + if (glDrawArraysInstancedBaseInstanceEXT != nullptr && + glDrawElementsInstancedBaseInstanceEXT != nullptr && + glDrawElementsInstancedBaseVertexBaseInstanceEXT != nullptr) + { + loadedExtensions.EXT_base_instance = true; + } + else + { + extensions->EXT_base_instance = false; + } } - if (extensions.QCOM_shader_framebuffer_fetch_noncoherent && + if (extensions->QCOM_shader_framebuffer_fetch_noncoherent && !loadedExtensions.QCOM_shader_framebuffer_fetch_noncoherent) { glFramebufferFetchBarrierQCOM = (PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC)eglGetProcAddress( "glFramebufferFetchBarrierQCOM"); - loadedExtensions.QCOM_shader_framebuffer_fetch_noncoherent = true; + if (glFramebufferFetchBarrierQCOM != nullptr) + { + loadedExtensions.QCOM_shader_framebuffer_fetch_noncoherent = true; + } + else + { + extensions->QCOM_shader_framebuffer_fetch_noncoherent = false; + } } - if (extensions.EXT_multisampled_render_to_texture && + if (extensions->EXT_multisampled_render_to_texture && !loadedExtensions.EXT_multisampled_render_to_texture) { glFramebufferTexture2DMultisampleEXT = @@ -54,8 +76,62 @@ void LoadGLESExtensions(const GLCapabilities& extensions) glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)eglGetProcAddress( "glRenderbufferStorageMultisampleEXT"); - loadedExtensions.EXT_multisampled_render_to_texture = true; + if (glFramebufferTexture2DMultisampleEXT != nullptr && + glRenderbufferStorageMultisampleEXT != nullptr) + { + loadedExtensions.EXT_multisampled_render_to_texture = true; + } + else + { + extensions->EXT_multisampled_render_to_texture = false; + } + } + if (extensions->KHR_blend_equation_advanced && + !loadedExtensions.KHR_blend_equation_advanced) + { + glBlendBarrierKHR = + (PFNGLBLENDBARRIERKHRPROC)eglGetProcAddress("glBlendBarrierKHR"); + if (glBlendBarrierKHR != nullptr) + { + loadedExtensions.KHR_blend_equation_advanced = true; + } + else + { + extensions->KHR_blend_equation_advanced = false; + } + } + if (extensions->EXT_shader_pixel_local_storage2 && + !loadedExtensions.EXT_shader_pixel_local_storage2) + { + glFramebufferPixelLocalStorageSizeEXT = + (PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)eglGetProcAddress( + "glFramebufferPixelLocalStorageSizeEXT"); + glClearPixelLocalStorageuiEXT = + (PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC)eglGetProcAddress( + "glClearPixelLocalStorageuiEXT"); + if (glFramebufferPixelLocalStorageSizeEXT != nullptr && + glClearPixelLocalStorageuiEXT != nullptr) + { + loadedExtensions.EXT_shader_pixel_local_storage2 = true; + } + else + { + extensions->EXT_shader_pixel_local_storage2 = false; + } + } + if (extensions->KHR_parallel_shader_compile && + !loadedExtensions.KHR_parallel_shader_compile) + { + glMaxShaderCompilerThreadsKHR = + (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)eglGetProcAddress( + "glMaxShaderCompilerThreadsKHR"); + if (glMaxShaderCompilerThreadsKHR != nullptr) + { + loadedExtensions.KHR_parallel_shader_compile = true; + } + else + { + extensions->KHR_parallel_shader_compile = false; + } } } - -#endif diff --git a/thirdparty/rive_renderer/source/gl/load_store_actions_ext.cpp b/thirdparty/rive_renderer/source/gl/load_store_actions_ext.cpp index 3690dabde..0cf586704 100644 --- a/thirdparty/rive_renderer/source/gl/load_store_actions_ext.cpp +++ b/thirdparty/rive_renderer/source/gl/load_store_actions_ext.cpp @@ -21,7 +21,8 @@ LoadStoreActionsEXT BuildLoadActionsEXT(const gpu::FlushDescriptor& desc, { actions |= LoadStoreActionsEXT::loadColor; } - if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING) + if (enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING)) { actions |= LoadStoreActionsEXT::clearClip; } @@ -34,23 +35,23 @@ std::ostream& BuildLoadStoreEXTGLSL(std::ostream& shader, auto addDefine = [&shader](const char* name) { shader << "#define " << name << "\n"; }; - if (actions & LoadStoreActionsEXT::clearColor) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::clearColor)) { addDefine(GLSL_CLEAR_COLOR); } - if (actions & LoadStoreActionsEXT::loadColor) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::loadColor)) { addDefine(GLSL_LOAD_COLOR); } - if (actions & LoadStoreActionsEXT::storeColor) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::storeColor)) { addDefine(GLSL_STORE_COLOR); } - if (actions & LoadStoreActionsEXT::clearCoverage) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::clearCoverage)) { addDefine(GLSL_CLEAR_COVERAGE); } - if (actions & LoadStoreActionsEXT::clearClip) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::clearClip)) { addDefine(GLSL_CLEAR_CLIP); } diff --git a/thirdparty/rive_renderer/source/gl/pls_impl_ext_native.cpp b/thirdparty/rive_renderer/source/gl/pls_impl_ext_native.cpp index c055443f1..272250f79 100644 --- a/thirdparty/rive_renderer/source/gl/pls_impl_ext_native.cpp +++ b/thirdparty/rive_renderer/source/gl/pls_impl_ext_native.cpp @@ -6,11 +6,12 @@ #include "rive/renderer/gl/load_store_actions_ext.hpp" #include "rive/renderer/gl/gl_utils.hpp" -#include "rive/math/simd.hpp" #include "rive/renderer/gl/render_target_gl.hpp" +#include "shaders/constants.glsl" +#include #include -#include "generated/shaders/pls_load_store_ext.exports.h" +#include "generated/shaders/pls_load_store_ext.glsl.exports.h" namespace rive::gpu { @@ -41,7 +42,7 @@ class PLSLoadStoreProgram glDeleteShader(fragmentShader); glutils::LinkProgram(m_id); - if (actions & LoadStoreActionsEXT::clearColor) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::clearColor)) { m_colorClearUniLocation = glGetUniformLocation(m_id, GLSL_clearColor); @@ -78,14 +79,27 @@ class RenderContextGLImpl::PLSImplEXTNative void init(rcp state) override { m_state = std::move(state); } - bool supportsRasterOrdering(const GLCapabilities&) const override + void getSupportedInterlockModes( + const GLCapabilities& capabilities, + PlatformFeatures* platformFeatures) const override { - return true; + assert(capabilities.EXT_shader_pixel_local_storage); + platformFeatures->supportsRasterOrderingMode = true; + platformFeatures->supportsClockwiseMode = true; + platformFeatures->supportsClockwiseFixedFunctionMode = + capabilities.EXT_shader_pixel_local_storage2; } - bool supportsFragmentShaderAtomics( - const GLCapabilities& capabilities) const override + + void applyPipelineStateOverrides( + const DrawBatch&, + const FlushDescriptor& desc, + const PlatformFeatures&, + PipelineState* pipelineState) const override { - return false; + // Vivo Y21 and Oppo Reno 3 Pro both disable writes to pixel local + // storage when the color mask is off; just leave the color mask enabled + // in EXT_shader_pixel_local_storage mode. + pipelineState->colorWriteEnabled = true; } void activatePixelLocalStorage(RenderContextGLImpl* impl, @@ -97,35 +111,87 @@ class RenderContextGLImpl::PLSImplEXTNative auto renderTarget = static_cast(desc.renderTarget); renderTarget->bindDestinationFramebuffer(GL_FRAMEBUFFER); + if (desc.fixedFunctionColorOutput) + { + // We need EXT_shader_pixel_local_storage2 for + // fixedFunctionColorOutput. + assert(impl->m_capabilities.EXT_shader_pixel_local_storage2); + assert(desc.interlockMode == gpu::InterlockMode::clockwise); + assert(!enums::is_flag_set( + desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND)); + glFramebufferPixelLocalStorageSizeEXT(GL_FRAMEBUFFER, + 2 * sizeof(uint32_t)); + } + else if (impl->m_capabilities.usePixelLocalStorage2AsWorkaround) + { + // PowerVR Rogue GE8300, OpenGL ES 3.2 build 1.10@5187610 has severe + // pixel local storage corruption issues with our renderer. Using + // the EXT_shader_pixel_local_storage2 API to set the size is an + // apparent workaround that comes with worse performance and other, + // less severe visual artifacts. + assert(impl->m_capabilities.EXT_shader_pixel_local_storage2); + glFramebufferPixelLocalStorageSizeEXT(GL_FRAMEBUFFER, + PLS_PLANE_COUNT * + sizeof(uint32_t)); + } glEnable(GL_SHADER_PIXEL_LOCAL_STORAGE_EXT); - std::array clearColor4f; - LoadStoreActionsEXT actions = BuildLoadActionsEXT(desc, &clearColor4f); - const PLSLoadStoreProgram& plsProgram = - findLoadStoreProgram(actions, desc.combinedShaderFeatures); - m_state->bindProgram(plsProgram.id()); - if (plsProgram.clearColorUniLocation() >= 0) + m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); + if (desc.fixedFunctionColorOutput) { - glUniform4fv(plsProgram.clearColorUniLocation(), - 1, - clearColor4f.data()); + // Clear the main framebuffer. + float cc[4]; + UnpackColorToRGBA32FPremul(desc.colorClearValue, cc); + glClearColor(cc[0], cc[1], cc[2], cc[3]); + glClear(GL_COLOR_BUFFER_BIT); + + // Clear PLS using the EXT_shader_pixel_local_storage2 API. + assert(impl->m_capabilities.EXT_shader_pixel_local_storage2); + GLuint plsClearValues[2] = { + desc.coverageClearValue, + /*clipClearValue=*/0u, + }; + glClearPixelLocalStorageuiEXT(0, 2, plsClearValues); + } + else + { + // EXT_shader_pixel_local_storage doesn't have an initialization + // API. Initialize PLS by drawing a fullscreen quad. + std::array clearColor4f; + LoadStoreActionsEXT actions = + BuildLoadActionsEXT(desc, &clearColor4f); + const PLSLoadStoreProgram& plsProgram = + findLoadStoreProgram(actions, desc.combinedShaderFeatures); + m_state->bindProgram(plsProgram.id()); + if (plsProgram.clearColorUniLocation() >= 0) + { + glUniform4fv(plsProgram.clearColorUniLocation(), + 1, + clearColor4f.data()); + } + m_state->bindVAO(m_plsLoadStoreVAO); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } - m_state->bindVAO(m_plsLoadStoreVAO); - m_state->setCullFace(GL_BACK); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } void deactivatePixelLocalStorage(RenderContextGLImpl* impl, const FlushDescriptor& desc) override { - // Issue a fullscreen draw that transfers the color information in pixel - // local storage to the main framebuffer. - LoadStoreActionsEXT actions = LoadStoreActionsEXT::storeColor; - m_state->bindProgram( - findLoadStoreProgram(actions, desc.combinedShaderFeatures).id()); - m_state->bindVAO(m_plsLoadStoreVAO); - m_state->setCullFace(GL_BACK); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (!desc.fixedFunctionColorOutput) + { + // EXT_shader_pixel_local_storage doesn't support concurrent + // rendering to PLS and the framebuffer. Now that we're done, issue + // a fullscreen draw that transfers the color information from PLS + // to the main framebuffer. + LoadStoreActionsEXT actions = LoadStoreActionsEXT::storeColor; + m_state->bindProgram( + findLoadStoreProgram(actions, desc.combinedShaderFeatures) + .id()); + m_state->bindVAO(m_plsLoadStoreVAO); + m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } glDisable(GL_SHADER_PIXEL_LOCAL_STORAGE_EXT); } diff --git a/thirdparty/rive_renderer/source/gl/pls_impl_rw_texture.cpp b/thirdparty/rive_renderer/source/gl/pls_impl_rw_texture.cpp index 7cbf4cb83..d21535118 100644 --- a/thirdparty/rive_renderer/source/gl/pls_impl_rw_texture.cpp +++ b/thirdparty/rive_renderer/source/gl/pls_impl_rw_texture.cpp @@ -8,18 +8,17 @@ #include "shaders/constants.glsl" #include "rive/renderer/gl/gl_utils.hpp" -#include "generated/shaders/glsl.exports.h" +#include "generated/shaders/glsl.glsl.exports.h" + +#include namespace rive::gpu { -using DrawBufferMask = RenderTargetGL::DrawBufferMask; - -static bool needs_coalesced_atomic_resolve_and_transfer( +static bool wants_coalesced_atomic_resolve_and_transfer( const gpu::FlushDescriptor& desc) { - assert(desc.interlockMode == gpu::InterlockMode::atomics); - return (desc.combinedShaderFeatures & - ShaderFeatures::ENABLE_ADVANCED_BLEND) && + return desc.interlockMode == gpu::InterlockMode::atomics && + !desc.fixedFunctionColorOutput && lite_rtti_cast( static_cast(desc.renderTarget)) != nullptr; } @@ -27,142 +26,266 @@ static bool needs_coalesced_atomic_resolve_and_transfer( class RenderContextGLImpl::PLSImplRWTexture : public RenderContextGLImpl::PixelLocalStorageImpl { - bool supportsRasterOrdering( - const GLCapabilities& capabilities) const override + void init(rcp) override + { + glBindFramebuffer(GL_FRAMEBUFFER, m_plsClearFBO); + std::array plsClearBuffers; + std::iota(plsClearBuffers.begin(), + plsClearBuffers.end(), + GL_COLOR_ATTACHMENT0); + glDrawBuffers(plsClearBuffers.size(), plsClearBuffers.data()); + } + + void getSupportedInterlockModes( + const GLCapabilities& capabilities, + PlatformFeatures* platformFeatures) const override + { + if (capabilities.ARB_fragment_shader_interlock || + capabilities.INTEL_fragment_shader_ordering) + { + platformFeatures->supportsRasterOrderingMode = true; + platformFeatures->supportsClockwiseMode = true; + platformFeatures->supportsClockwiseFixedFunctionMode = true; + } + platformFeatures->supportsAtomicMode = true; + } + + void resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) override + { + assert(planeCount <= PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT); + + if (width == 0 || height == 0 || planeCount == 0) + { + m_plsTransientBackingTexture = glutils::Texture::Zero(); + } + else + { + m_plsTransientBackingTexture = glutils::Texture(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D_ARRAY, m_plsTransientBackingTexture); + glTexStorage3D(GL_TEXTURE_2D_ARRAY, + 1, + GL_R32UI, + width, + height, + planeCount); + } + + glBindFramebuffer(GL_FRAMEBUFFER, m_plsClearFBO); + for (uint32_t i = 0; i < PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT; ++i) + { + glFramebufferTextureLayer( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0 + PLS_TRANSIENT_BACKING_CLEAR_IDX + i, + (i < planeCount) ? m_plsTransientBackingTexture : 0, + 0, + i); + } + + RIVE_DEBUG_CODE(m_plsTransientBackingPlaneCount = planeCount;) + } + + void resizeAtomicCoverageBacking(uint32_t width, uint32_t height) override + { + if (width == 0 || height == 0) + { + m_atomicCoverageTexture = glutils::Texture::Zero(); + } + else + { + m_atomicCoverageTexture = glutils::Texture(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_atomicCoverageTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width, height); + } + + glBindFramebuffer(GL_FRAMEBUFFER, m_plsClearFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0 + + PLS_ATOMIC_COVERAGE_CLEAR_IDX, + GL_TEXTURE_2D, + m_atomicCoverageTexture, + 0); + } + + gpu::ShaderMiscFlags shaderMiscFlags(const gpu::FlushDescriptor& desc, + gpu::DrawType drawType) const final { - return capabilities.ARB_fragment_shader_interlock || - capabilities.INTEL_fragment_shader_ordering; + auto flags = gpu::ShaderMiscFlags::none; + if (drawType == gpu::DrawType::renderPassResolve && + wants_coalesced_atomic_resolve_and_transfer(desc)) + { + flags |= gpu::ShaderMiscFlags::coalescedResolveAndTransfer; + } + return flags; } - bool supportsFragmentShaderAtomics( - const GLCapabilities& capabilities) const override + void applyPipelineStateOverrides( + const DrawBatch& batch, + const FlushDescriptor& desc, + const PlatformFeatures&, + PipelineState* pipelineState) const override { - return true; + if (batch.drawType == gpu::DrawType::renderPassResolve && + wants_coalesced_atomic_resolve_and_transfer(desc)) + { + // If we opted for "coalescedResolveAndTransfer", turn color writes + // back on for this draw. + pipelineState->colorWriteEnabled = true; + } } void activatePixelLocalStorage(RenderContextGLImpl* renderContextImpl, const FlushDescriptor& desc) override { auto renderTarget = static_cast(desc.renderTarget); - renderTarget->allocateInternalPLSTextures(desc.interlockMode); - if (!desc.atomicFixedFunctionColorOutput) + // Bind and initialize the PLS backing textures. + renderContextImpl->state()->setPipelineState( + gpu::COLOR_ONLY_PIPELINE_STATE); + renderContextImpl->state()->setScissor(desc.renderTargetUpdateBounds, + renderTarget->height()); + + if (!desc.fixedFunctionColorOutput) { - if (auto framebufferRenderTarget = - lite_rtti_cast(renderTarget)) + if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget) { - // We're targeting an external FBO but can't render to it - // directly. Make sure to allocate and attach an offscreen - // target texture. - framebufferRenderTarget->allocateOffscreenTargetTexture(); - if (desc.colorLoadAction == - gpu::LoadAction::preserveRenderTarget) + if (auto framebufferRenderTarget = + lite_rtti_cast( + renderTarget)) { - // Copy the framebuffer's contents to our offscreen texture. + // We're targeting an external FBO but need to render to a + // texture. Since we also need to preserve the contents, + // blit the target framebuffer into the offscreen texture. framebufferRenderTarget->bindDestinationFramebuffer( GL_READ_FRAMEBUFFER); - framebufferRenderTarget->bindInternalFramebuffer( - GL_DRAW_FRAMEBUFFER, - DrawBufferMask::color); + framebufferRenderTarget->bindTextureFramebuffer( + GL_DRAW_FRAMEBUFFER); glutils::BlitFramebuffer(desc.renderTargetUpdateBounds, renderTarget->height()); } } + // If the color buffer is *not* a storage texture, we will clear it + // once the main framebuffer gets bound. + if (desc.colorLoadAction == gpu::LoadAction::clear) + { + float clearColor4f[4]; + UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f); + renderTarget->bindTextureFramebuffer(GL_FRAMEBUFFER); + glClearBufferfv(GL_COLOR, COLOR_PLANE_IDX, clearColor4f); + } + glBindImageTexture(COLOR_PLANE_IDX, + renderTarget->renderTexture(), + 0, + GL_FALSE, + 0, + GL_READ_WRITE, + GL_RGBA8); } - // Clear the necessary textures. - auto rwTexBuffers = DrawBufferMask::coverage; - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering) - { - rwTexBuffers |= - DrawBufferMask::color | DrawBufferMask::scratchColor; - } - else if (desc.combinedShaderFeatures & - ShaderFeatures::ENABLE_ADVANCED_BLEND) + glBindFramebuffer(GL_FRAMEBUFFER, m_plsClearFBO); + uint32_t nextTransientLayer = 0; { - rwTexBuffers |= DrawBufferMask::color; - } - if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING) - { - rwTexBuffers |= DrawBufferMask::clip; - } - renderTarget->bindInternalFramebuffer(GL_FRAMEBUFFER, rwTexBuffers); - if (desc.colorLoadAction == gpu::LoadAction::clear && - (rwTexBuffers & DrawBufferMask::color)) - { - // If the color buffer is not a storage texture, we will clear it - // once the main framebuffer gets bound. - float clearColor4f[4]; - UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f); - glClearBufferfv(GL_COLOR, COLOR_PLANE_IDX, clearColor4f); + GLuint coverageClear[4]{desc.coverageClearValue}; + if (desc.interlockMode == gpu::InterlockMode::rasterOrdering || + desc.interlockMode == gpu::InterlockMode::clockwise) + { + glClearBufferuiv(GL_COLOR, nextTransientLayer, coverageClear); + glBindImageTexture(COVERAGE_PLANE_IDX, + m_plsTransientBackingTexture, + 0, + GL_FALSE, + nextTransientLayer, + GL_READ_WRITE, + GL_R32UI); + ++nextTransientLayer; + } + else + { + assert(desc.interlockMode == gpu::InterlockMode::atomics); + glClearBufferuiv(GL_COLOR, + PLS_ATOMIC_COVERAGE_CLEAR_IDX, + coverageClear); + glBindImageTexture(COVERAGE_PLANE_IDX, + m_atomicCoverageTexture, + 0, + GL_FALSE, + 0, + GL_READ_WRITE, + GL_R32UI); + } } - if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING) + + if (enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING)) { constexpr static GLuint kZeroClear[4]{}; - glClearBufferuiv(GL_COLOR, CLIP_PLANE_IDX, kZeroClear); - } - { - GLuint coverageClear[4]{desc.coverageClearValue}; - glClearBufferuiv(GL_COLOR, COVERAGE_PLANE_IDX, coverageClear); + glClearBufferuiv(GL_COLOR, nextTransientLayer, kZeroClear); + glBindImageTexture(CLIP_PLANE_IDX, + m_plsTransientBackingTexture, + 0, + GL_FALSE, + nextTransientLayer, + GL_READ_WRITE, + GL_R32UI); + ++nextTransientLayer; } - switch (desc.interlockMode) + if (desc.interlockMode == gpu::InterlockMode::rasterOrdering || + (desc.interlockMode == gpu::InterlockMode::clockwise && + enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND))) { - case gpu::InterlockMode::rasterOrdering: - // rasterOrdering mode renders by storing to an image texture. - // Bind a framebuffer with no color attachments. - renderTarget->bindHeadlessFramebuffer( - renderContextImpl->m_capabilities); - break; - case gpu::InterlockMode::atomics: - renderTarget->bindDestinationFramebuffer(GL_FRAMEBUFFER); - if (desc.colorLoadAction == gpu::LoadAction::clear && - !(rwTexBuffers & DrawBufferMask::color)) - { - // We're rendering directly to the main framebuffer. Clear - // it now. - float cc[4]; - UnpackColorToRGBA32FPremul(desc.colorClearValue, cc); - glClearColor(cc[0], cc[1], cc[2], cc[3]); - glClear(GL_COLOR_BUFFER_BIT); - } - break; - default: - RIVE_UNREACHABLE(); + glBindImageTexture( + SCRATCH_COLOR_PLANE_IDX, + m_plsTransientBackingTexture, + 0, + GL_FALSE, + nextTransientLayer, + GL_READ_WRITE, + (desc.interlockMode == gpu::InterlockMode::clockwise) + ? GL_RGB10_A2 + : GL_RGBA8); + ++nextTransientLayer; } + assert(nextTransientLayer <= m_plsTransientBackingPlaneCount); - renderTarget->bindAsImageTextures(rwTexBuffers); - - glMemoryBarrierByRegion(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - } - - gpu::ShaderMiscFlags shaderMiscFlags(const gpu::FlushDescriptor& desc, - gpu::DrawType drawType) const final - { - auto flags = gpu::ShaderMiscFlags::none; - if (desc.interlockMode == gpu::InterlockMode::atomics) + if (desc.fixedFunctionColorOutput || + wants_coalesced_atomic_resolve_and_transfer(desc)) { - if (desc.atomicFixedFunctionColorOutput) + // Render directly to the main framebuffer. + renderTarget->bindDestinationFramebuffer(GL_FRAMEBUFFER); + if (desc.fixedFunctionColorOutput && + desc.colorLoadAction == gpu::LoadAction::clear) { - flags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput; - } - if (drawType == gpu::DrawType::atomicResolve && - needs_coalesced_atomic_resolve_and_transfer(desc)) - { - flags |= gpu::ShaderMiscFlags::coalescedResolveAndTransfer; + // Clear the main framebuffer. + float cc[4]; + UnpackColorToRGBA32FPremul(desc.colorClearValue, cc); + glClearColor(cc[0], cc[1], cc[2], cc[3]); + glClear(GL_COLOR_BUFFER_BIT); } } - return flags; + else + { + // Render by storing to an image texture, which we will copy out at + // the end of the render pass. + // Bind a framebuffer with no color attachments. + renderTarget->bindHeadlessFramebuffer( + renderContextImpl->m_capabilities); + } + + glMemoryBarrierByRegion(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } - void deactivatePixelLocalStorage(RenderContextGLImpl*, + void deactivatePixelLocalStorage(RenderContextGLImpl* renderContextImpl, const FlushDescriptor& desc) override { glMemoryBarrierByRegion(GL_ALL_BARRIER_BITS); - // atomic mode never needs to copy anything here because it transfers - // the offscreen texture during resolve. - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering) + if (!desc.fixedFunctionColorOutput && + !wants_coalesced_atomic_resolve_and_transfer(desc)) { if (auto framebufferRenderTarget = lite_rtti_cast( @@ -170,11 +293,12 @@ class RenderContextGLImpl::PLSImplRWTexture { // We rendered to an offscreen texture. Copy back to the // external target framebuffer. - framebufferRenderTarget->bindInternalFramebuffer( - GL_READ_FRAMEBUFFER, - DrawBufferMask::color); + framebufferRenderTarget->bindTextureFramebuffer( + GL_READ_FRAMEBUFFER); framebufferRenderTarget->bindDestinationFramebuffer( GL_DRAW_FRAMEBUFFER); + renderContextImpl->state()->setPipelineState( + gpu::COLOR_ONLY_PIPELINE_STATE); glutils::BlitFramebuffer(desc.renderTargetUpdateBounds, framebufferRenderTarget->height()); } @@ -192,6 +316,19 @@ class RenderContextGLImpl::PLSImplRWTexture { return glMemoryBarrierByRegion(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } + +private: + constexpr static uint32_t PLS_TRANSIENT_BACKING_CLEAR_IDX = 0; + constexpr static uint32_t PLS_ATOMIC_COVERAGE_CLEAR_IDX = + PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT; + constexpr static uint32_t PLS_CLEAR_BUFFER_COUNT = + PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT + 1; + + glutils::Texture m_plsTransientBackingTexture = glutils::Texture::Zero(); + glutils::Texture m_atomicCoverageTexture = glutils::Texture::Zero(); + glutils::Framebuffer m_plsClearFBO; // FBO solely for clearing PLS. + + RIVE_DEBUG_CODE(uint32_t m_plsTransientBackingPlaneCount = 0;) }; std::unique_ptr diff --git a/thirdparty/rive_renderer/source/gl/pls_impl_webgl.cpp b/thirdparty/rive_renderer/source/gl/pls_impl_webgl.cpp index be832fded..7039e5300 100644 --- a/thirdparty/rive_renderer/source/gl/pls_impl_webgl.cpp +++ b/thirdparty/rive_renderer/source/gl/pls_impl_webgl.cpp @@ -8,7 +8,7 @@ #include "rive/renderer/gl/render_target_gl.hpp" #include "shaders/constants.glsl" -#include "generated/shaders/glsl.exports.h" +#include "generated/shaders/glsl.glsl.exports.h" #ifdef RIVE_WEBGL #include @@ -19,8 +19,19 @@ EM_JS(bool, (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE gl), { gl = GL.getContext(gl).GLctx; - gl.pls = gl["getExtension"]("WEBGL_shader_pixel_local_storage"); - return Boolean(gl.pls && gl.pls["isCoherent"]()); + const pls = gl["getExtension"]("WEBGL_shader_pixel_local_storage"); + if (Boolean( + pls && pls["isCoherent"]() && + // WEBGL_shader_pixel_local_storage has breaking changes from + // time to time, while it's still a draft extension. A 5th + // argument was added to this function in 2026. Only use the + // extension if we are on the latest spec (with 5 arguments). + pls["framebufferTexturePixelLocalStorageWEBGL"].length == 5)) + { + gl.pls = pls; + return true; + } + return false; }); EM_JS(void, @@ -29,7 +40,8 @@ EM_JS(void, GLint plane, GLuint backingtexture, GLint level, - GLint layer), + GLint layer, + GLenum usage), { const pls = GL.getContext(gl).GLctx.pls; if (pls) @@ -38,7 +50,8 @@ EM_JS(void, plane, GL.textures[backingtexture], level, - layer); + layer, + usage); } }); @@ -123,23 +136,19 @@ bool webgl_enable_WEBGL_shader_pixel_local_storage_coherent() emscripten_webgl_get_current_context()); } -bool webgl_enable_WEBGL_provoking_vertex() -{ - return enable_WEBGL_provoking_vertex( - emscripten_webgl_get_current_context()); -} - void glFramebufferTexturePixelLocalStorageANGLE(GLint plane, GLuint backingtexture, GLint level, - GLint layer) + GLint layer, + GLenum usage) { framebufferTexturePixelLocalStorageWEBGL( emscripten_webgl_get_current_context(), plane, backingtexture, level, - layer); + layer, + usage); } void glFramebufferPixelLocalClearValuefvANGLE(GLint plane, @@ -180,6 +189,12 @@ void glGetFramebufferPixelLocalStorageParameterivANGLE(GLint plane, pname); } +bool webgl_enable_WEBGL_provoking_vertex() +{ + return enable_WEBGL_provoking_vertex( + emscripten_webgl_get_current_context()); +} + void glProvokingVertexANGLE(GLenum provokeMode) { provokingVertexWEBGL(emscripten_webgl_get_current_context(), provokeMode); @@ -188,8 +203,6 @@ void glProvokingVertexANGLE(GLenum provokeMode) namespace rive::gpu { -using DrawBufferMask = RenderTargetGL::DrawBufferMask; - static GLenum webgl_load_op(gpu::LoadAction loadAction) { switch (loadAction) @@ -207,23 +220,23 @@ static GLenum webgl_load_op(gpu::LoadAction loadAction) class RenderContextGLImpl::PLSImplWebGL : public RenderContextGLImpl::PixelLocalStorageImpl { - bool supportsRasterOrdering( - const GLCapabilities& capabilities) const override + void getSupportedInterlockModes( + const GLCapabilities& capabilities, + PlatformFeatures* platformFeatures) const override { - return capabilities.ANGLE_shader_pixel_local_storage_coherent; - } - - bool supportsFragmentShaderAtomics( - const GLCapabilities& capabilities) const override - { - return false; + assert(capabilities.ANGLE_shader_pixel_local_storage); + if (capabilities.ANGLE_shader_pixel_local_storage_coherent) + { + platformFeatures->supportsRasterOrderingMode = true; + } } void activatePixelLocalStorage(RenderContextGLImpl* renderContextImpl, const FlushDescriptor& desc) override { auto renderTarget = static_cast(desc.renderTarget); - renderTarget->allocateInternalPLSTextures(desc.interlockMode); + renderTarget->allocateWebGLPLSBacking( + renderContextImpl->capabilities()); auto framebufferRenderTarget = lite_rtti_cast(renderTarget); @@ -237,9 +250,10 @@ class RenderContextGLImpl::PLSImplWebGL // Copy the framebuffer's contents to our offscreen texture. framebufferRenderTarget->bindDestinationFramebuffer( GL_READ_FRAMEBUFFER); - framebufferRenderTarget->bindInternalFramebuffer( - GL_DRAW_FRAMEBUFFER, - DrawBufferMask::color); + framebufferRenderTarget->bindTextureFramebuffer( + GL_DRAW_FRAMEBUFFER); + renderContextImpl->state()->setPipelineState( + gpu::COLOR_ONLY_PIPELINE_STATE); glutils::BlitFramebuffer(desc.renderTargetUpdateBounds, renderTarget->height()); } @@ -256,7 +270,8 @@ class RenderContextGLImpl::PLSImplWebGL clearColor4f); } GLenum clipLoadAction = - (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING) + enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING) ? GL_LOAD_OP_ZERO_ANGLE : GL_DONT_CARE; GLenum loadOps[4] = {webgl_load_op(desc.colorLoadAction), @@ -270,7 +285,7 @@ class RenderContextGLImpl::PLSImplWebGL glBeginPixelLocalStorageANGLE(4, loadOps); } - void deactivatePixelLocalStorage(RenderContextGLImpl*, + void deactivatePixelLocalStorage(RenderContextGLImpl* renderContextImpl, const FlushDescriptor& desc) override { constexpr static GLenum kStoreOps[4] = {GL_STORE_OP_STORE_ANGLE, @@ -289,11 +304,12 @@ class RenderContextGLImpl::PLSImplWebGL { // We rendered to an offscreen texture. Copy back to the external // target FBO. - framebufferRenderTarget->bindInternalFramebuffer( - GL_READ_FRAMEBUFFER, - DrawBufferMask::color); + framebufferRenderTarget->bindTextureFramebuffer( + GL_READ_FRAMEBUFFER); framebufferRenderTarget->bindDestinationFramebuffer( GL_DRAW_FRAMEBUFFER); + renderContextImpl->state()->setPipelineState( + gpu::COLOR_ONLY_PIPELINE_STATE); glutils::BlitFramebuffer(desc.renderTargetUpdateBounds, framebufferRenderTarget->height()); } diff --git a/thirdparty/rive_renderer/source/gl/render_buffer_gl_impl.cpp b/thirdparty/rive_renderer/source/gl/render_buffer_gl_impl.cpp index 8cd79557a..649f6e4dc 100644 --- a/thirdparty/rive_renderer/source/gl/render_buffer_gl_impl.cpp +++ b/thirdparty/rive_renderer/source/gl/render_buffer_gl_impl.cpp @@ -41,12 +41,14 @@ void RenderBufferGLImpl::init(rcp state) glGenBuffers(1, &m_bufferID); m_state->bindVAO(0); m_state->bindBuffer(m_target, m_bufferID); - glBufferData(m_target, - sizeInBytes(), - nullptr, - (flags() & RenderBufferFlags::mappedOnceAtInitialization) - ? GL_STATIC_DRAW - : GL_DYNAMIC_DRAW); + glBufferData( + m_target, + sizeInBytes(), + nullptr, + enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization) + ? GL_STATIC_DRAW + : GL_DYNAMIC_DRAW); } GLuint RenderBufferGLImpl::detachBuffer() @@ -56,17 +58,9 @@ GLuint RenderBufferGLImpl::detachBuffer() void* RenderBufferGLImpl::onMap() { - if (!canMapBuffer()) - { - if (!m_fallbackMappedMemory) - { - m_fallbackMappedMemory.reset(new uint8_t[sizeInBytes()]); - } - return m_fallbackMappedMemory.get(); - } - else - { #ifndef RIVE_WEBGL + if (canMapBuffer()) + { m_state->bindVAO(0); m_state->bindBuffer(m_target, m_bufferID); return glMapBufferRange(m_target, @@ -74,10 +68,15 @@ void* RenderBufferGLImpl::onMap() sizeInBytes(), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); -#else - // WebGL doesn't declare glMapBufferRange(). - RIVE_UNREACHABLE(); + } + else #endif + { + if (!m_fallbackMappedMemory) + { + m_fallbackMappedMemory.reset(new uint8_t[sizeInBytes()]); + } + return m_fallbackMappedMemory.get(); } } @@ -85,35 +84,37 @@ void RenderBufferGLImpl::onUnmap() { m_state->bindVAO(0); m_state->bindBuffer(m_target, m_bufferID); - if (!canMapBuffer()) +#ifndef RIVE_WEBGL + if (canMapBuffer()) + { + glUnmapBuffer(m_target); + } + else +#endif { glBufferSubData(m_target, 0, sizeInBytes(), m_fallbackMappedMemory.get()); - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { m_fallbackMappedMemory .reset(); // This buffer will only be mapped once. } } - else - { -#ifndef RIVE_WEBGL - glUnmapBuffer(m_target); -#else - // WebGL doesn't declare glUnmapBuffer(). - RIVE_UNREACHABLE(); -#endif - } } +#ifndef RIVE_WEBGL bool RenderBufferGLImpl::canMapBuffer() const { - // WebGL doesn't support buffer mapping. - return !m_state->capabilities().isANGLEOrWebGL && + // WebGL doesn't support buffer mapping. Don't use it on ANGLE either since + // we don't trust ANGLE with features that haven't been validated by WebGL. + return !m_state->capabilities().isANGLESystemDriver && // NVIDIA gives performance warnings when mapping GL_STATIC_DRAW // buffers. - !(flags() & RenderBufferFlags::mappedOnceAtInitialization); + !enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization); } +#endif } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/gl/render_context_gl_impl.cpp b/thirdparty/rive_renderer/source/gl/render_context_gl_impl.cpp index 993fa8efa..0ad6e3e20 100644 --- a/thirdparty/rive_renderer/source/gl/render_context_gl_impl.cpp +++ b/thirdparty/rive_renderer/source/gl/render_context_gl_impl.cpp @@ -7,19 +7,33 @@ #include "rive/renderer/gl/render_buffer_gl_impl.hpp" #include "rive/renderer/gl/render_target_gl.hpp" #include "rive/renderer/draw.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif +#include "rive/renderer/render_context_impl.hpp" +#include "rive/renderer/rive_renderer.hpp" #include "rive/renderer/texture.hpp" #include "shaders/constants.glsl" +#include "instance_chunker.hpp" #include "generated/shaders/advanced_blend.glsl.hpp" #include "generated/shaders/color_ramp.glsl.hpp" #include "generated/shaders/constants.glsl.hpp" +#include "generated/shaders/image_draw_uniforms.glsl.hpp" +#include "generated/shaders/flush_uniforms.glsl.hpp" #include "generated/shaders/common.glsl.hpp" #include "generated/shaders/draw_path_common.glsl.hpp" -#include "generated/shaders/draw_path.glsl.hpp" -#include "generated/shaders/draw_image_mesh.glsl.hpp" +#include "generated/shaders/draw_path.vert.hpp" +#include "generated/shaders/draw_raster_order_path.frag.hpp" +#include "generated/shaders/draw_clockwise_path.frag.hpp" +#include "generated/shaders/draw_clockwise_clip.frag.hpp" +#include "generated/shaders/draw_image_mesh.vert.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" +#include "generated/shaders/draw_msaa_object.frag.hpp" #include "generated/shaders/bezier_utils.glsl.hpp" #include "generated/shaders/tessellate.glsl.hpp" #include "generated/shaders/render_atlas.glsl.hpp" +#include "generated/shaders/resolve_atlas.glsl.hpp" #include "generated/shaders/blit_texture_as_draw.glsl.hpp" #include "generated/shaders/stencil_draw.glsl.hpp" @@ -40,7 +54,6 @@ const char atomic_draw[] = ""; namespace rive::gpu { - static bool is_tessellation_draw(gpu::DrawType drawType) { switch (drawType) @@ -60,33 +73,110 @@ static bool is_tessellation_draw(gpu::DrawType drawType) case gpu::DrawType::imageMesh: case gpu::DrawType::interiorTriangulation: case gpu::DrawType::atlasBlit: - case gpu::DrawType::atomicInitialize: - case gpu::DrawType::atomicResolve: - case gpu::DrawType::msaaStencilClipReset: + case gpu::DrawType::clipReset: + case gpu::DrawType::renderPassInitialize: + case gpu::DrawType::renderPassResolve: return false; } RIVE_UNREACHABLE(); } +// Returns atlasDesiredRenderType, or the next supported AtlasRenderType down +// the list if it is not supported. +static RenderContextGLImpl::AtlasRenderType select_atlas_render_type( + const GLCapabilities& capabilities, + RenderContextGLImpl::AtlasRenderType atlasDesiredRenderType = + RenderContextGLImpl::AtlasRenderType::r16f) +{ + switch (atlasDesiredRenderType) + { + using AtlasRenderType = RenderContextGLImpl::AtlasRenderType; + case AtlasRenderType::r16f: + if (capabilities.EXT_color_buffer_half_float) + { + return AtlasRenderType::r16f; + } + [[fallthrough]]; + case AtlasRenderType::r32f: + if (capabilities.EXT_color_buffer_float && + capabilities.EXT_float_blend) + { + // fp32 is ideal for the atlas. When there's a lot of overlap, + // fp16 can run out of precision. + return AtlasRenderType::r32f; + } + [[fallthrough]]; + case AtlasRenderType::r32uiFramebufferFetch: + if (capabilities.EXT_shader_framebuffer_fetch) + { + return AtlasRenderType::r32uiFramebufferFetch; + } + [[fallthrough]]; + case AtlasRenderType::r8PixelLocalStorageEXT: +#ifdef RIVE_ANDROID + if (capabilities.EXT_shader_pixel_local_storage) + { + return AtlasRenderType::r8PixelLocalStorageEXT; + } +#endif + [[fallthrough]]; + case AtlasRenderType::r32uiPixelLocalStorageANGLE: +#ifndef RIVE_ANDROID + if (capabilities.ANGLE_shader_pixel_local_storage_coherent) + { + return AtlasRenderType::r32uiPixelLocalStorageANGLE; + } +#endif + [[fallthrough]]; + case AtlasRenderType::r32iAtomicTexture: +#ifndef RIVE_WEBGL + if (capabilities.ARB_shader_image_load_store || + capabilities.OES_shader_image_atomic) + { + return AtlasRenderType::r32iAtomicTexture; + } +#endif + [[fallthrough]]; + case AtlasRenderType::rgba8: + return AtlasRenderType::rgba8; + } + RIVE_UNREACHABLE(); +} + RenderContextGLImpl::RenderContextGLImpl( const char* rendererString, GLCapabilities capabilities, - std::unique_ptr plsImpl) : + std::unique_ptr plsImpl, + ShaderCompilationMode shaderCompilationMode) : m_capabilities(capabilities), m_plsImpl(std::move(plsImpl)), + m_atlasRenderType(select_atlas_render_type(m_capabilities)), + m_pipelineManager(shaderCompilationMode, this), m_state(make_rcp(m_capabilities)) - { + if (m_capabilities.isANGLESystemDriver && + capabilities.KHR_blend_equation_advanced) + { + // Some ANGLE devices report support for this extension but render + // incorrectly with it, so we'll need to run a quick test to validate + // that we get the proper color out of doing advance blending before + // rendering with it. + m_testForAdvancedBlendError = true; + } + if (m_plsImpl != nullptr) { - m_platformFeatures.supportsRasterOrdering = - m_plsImpl->supportsRasterOrdering(m_capabilities); - m_platformFeatures.supportsFragmentShaderAtomics = - m_plsImpl->supportsFragmentShaderAtomics(m_capabilities); + m_plsImpl->getSupportedInterlockModes(m_capabilities, + &m_platformFeatures); + } + if (m_capabilities.KHR_blend_equation_advanced || + m_capabilities.KHR_blend_equation_advanced_coherent) + { + m_platformFeatures.supportsBlendAdvancedKHR = true; } if (m_capabilities.KHR_blend_equation_advanced_coherent) { - m_platformFeatures.supportsKHRBlendEquations = true; + m_platformFeatures.supportsBlendAdvancedCoherentKHR = true; } if (m_capabilities.EXT_clip_cull_distance) { @@ -114,6 +204,14 @@ RenderContextGLImpl::RenderContextGLImpl( glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); m_platformFeatures.maxTextureSize = maxTextureSize; + m_platformFeatures.supportsTextureCompressionBC = + m_capabilities.EXT_texture_compression_s3tc && + m_capabilities.EXT_texture_compression_bptc; + m_platformFeatures.supportsTextureCompressionASTC = + m_capabilities.KHR_texture_compression_astc_ldr; + m_platformFeatures.supportsTextureCompressionETC2 = + m_capabilities.supportsETC2; + std::vector generalDefines; if (!m_capabilities.ARB_shader_storage_buffer_object) { @@ -121,6 +219,7 @@ RenderContextGLImpl::RenderContextGLImpl( } const char* colorRampSources[] = {glsl::constants, + glsl::flush_uniforms, glsl::common, glsl::color_ramp}; m_colorRampProgram.compileAndAttachShader(GL_VERTEX_SHADER, @@ -173,9 +272,13 @@ RenderContextGLImpl::RenderContextGLImpl( GL_RED, GL_HALF_FLOAT, gpu::g_inverseGaussianIntegralTableF16); - glutils::SetTexture2DSamplingParams(GL_LINEAR, GL_LINEAR); + const GLenum featherTextureFilter = + m_capabilities.OES_texture_half_float_linear ? GL_LINEAR : GL_NEAREST; + glutils::SetTexture2DSamplingParams(featherTextureFilter, + featherTextureFilter); const char* tessellateSources[] = {glsl::constants, + glsl::flush_uniforms, glsl::common, glsl::bezier_utils, glsl::tessellate}; @@ -306,6 +409,175 @@ RenderContextGLImpl::~RenderContextGLImpl() m_state->invalidate(); } +// Indicates that the atlas needs a fullscreen draw at the end, in order to +// resolve it into a GL_R8 texture that can be sampled. +constexpr static bool needs_atlas_resolve_draw( + RenderContextGLImpl::AtlasRenderType atlasRenderType) +{ + switch (atlasRenderType) + { + using AtlasRenderType = RenderContextGLImpl::AtlasRenderType; + case AtlasRenderType::r16f: + case AtlasRenderType::r32f: + return false; + case AtlasRenderType::r32uiFramebufferFetch: + case AtlasRenderType::r8PixelLocalStorageEXT: + case AtlasRenderType::r32uiPixelLocalStorageANGLE: + case AtlasRenderType::r32iAtomicTexture: + case AtlasRenderType::rgba8: + return true; + } + RIVE_UNREACHABLE(); +} + +void RenderContextGLImpl::buildAtlasRenderPipelines() +{ + std::vector defines; + defines.push_back(GLSL_DRAW_PATH); + defines.push_back(GLSL_ENABLE_FEATHER); + defines.push_back(GLSL_ENABLE_INSTANCE_INDEX); + if (!m_capabilities.ARB_shader_storage_buffer_object) + { + defines.push_back(GLSL_DISABLE_SHADER_STORAGE_BUFFERS); + } + m_atlasFillPipelineState = gpu::ATLAS_FILL_PIPELINE_STATE; + m_atlasStrokePipelineState = gpu::ATLAS_STROKE_PIPELINE_STATE; + switch (m_atlasRenderType) + { + case AtlasRenderType::r16f: + case AtlasRenderType::r32f: + break; + case AtlasRenderType::r32uiFramebufferFetch: + defines.push_back(GLSL_ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH); + m_atlasFillPipelineState.blendEquation = gpu::BlendEquation::none; + m_atlasStrokePipelineState.blendEquation = gpu::BlendEquation::none; + break; + case AtlasRenderType::r8PixelLocalStorageEXT: +#ifdef RIVE_ANDROID + defines.push_back(GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT); + m_atlasFillPipelineState.blendEquation = gpu::BlendEquation::none; + m_atlasStrokePipelineState.blendEquation = gpu::BlendEquation::none; +#else + RIVE_UNREACHABLE(); +#endif + break; + case AtlasRenderType::r32uiPixelLocalStorageANGLE: +#ifndef RIVE_ANDROID + defines.push_back(GLSL_ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE); + m_atlasFillPipelineState.blendEquation = gpu::BlendEquation::none; + m_atlasStrokePipelineState.blendEquation = gpu::BlendEquation::none; +#else + RIVE_UNREACHABLE(); +#endif + break; + case AtlasRenderType::r32iAtomicTexture: +#ifndef RIVE_WEBGL + defines.push_back(GLSL_ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE); + m_atlasFillPipelineState.colorWriteEnabled = false; + m_atlasFillPipelineState.blendEquation = gpu::BlendEquation::none; + m_atlasStrokePipelineState.colorWriteEnabled = false; + m_atlasStrokePipelineState.blendEquation = gpu::BlendEquation::none; +#else + RIVE_UNREACHABLE(); +#endif + break; + case AtlasRenderType::rgba8: + defines.push_back(GLSL_ATLAS_RENDER_TARGET_RGBA8_UNORM); + break; + } + + const char* atlasSources[] = {glsl::constants, + glsl::flush_uniforms, + glsl::common, + glsl::draw_path_common, + glsl::render_atlas}; + m_atlasVertexShader.compile(GL_VERTEX_SHADER, + defines.data(), + defines.size(), + atlasSources, + std::size(atlasSources), + m_capabilities); + + defines.push_back(GLSL_ATLAS_FEATHERED_FILL); + m_atlasFillProgram.compile(m_atlasVertexShader, + defines.data(), + defines.size(), + atlasSources, + std::size(atlasSources), + m_capabilities, + m_state.get()); + defines.pop_back(); + + defines.push_back(GLSL_ATLAS_FEATHERED_STROKE); + m_atlasStrokeProgram.compile(m_atlasVertexShader, + defines.data(), + defines.size(), + atlasSources, + std::size(atlasSources), + m_capabilities, + m_state.get()); + defines.pop_back(); + + if (needs_atlas_resolve_draw(m_atlasRenderType)) + { + // Build the pipelines for clearing and resolving + // EXT_shader_pixel_local_storage. + m_atlasResolveVertexShader.compile(GL_VERTEX_SHADER, + glsl::resolve_atlas, + m_capabilities); + + if (m_atlasRenderType == AtlasRenderType::r8PixelLocalStorageEXT) + { +#ifdef RIVE_ANDROID + // EXT_shader_pixel_local_storage doesn't support clearing, so we + // also need to build a program to clear it at the beginning of the + // atlas render pass. + const char* atlasClearDefines[] = { + GLSL_ATLAS_RENDER_TARGET_R8_PLS_EXT, + GLSL_CLEAR_COVERAGE}; + const char* atlasClearSources[] = {glsl::resolve_atlas}; + m_atlasClearProgram = glutils::Program(); + glAttachShader(m_atlasClearProgram, m_atlasResolveVertexShader); + m_atlasClearProgram.compileAndAttachShader( + GL_FRAGMENT_SHADER, + atlasClearDefines, + std::size(atlasClearDefines), + atlasClearSources, + std::size(atlasClearSources), + m_capabilities); + m_atlasClearProgram.link(); +#else + RIVE_UNREACHABLE(); +#endif + } + + const char* atlasResolveSources[] = {glsl::constants, + glsl::flush_uniforms, + glsl::common, + glsl::resolve_atlas}; + m_atlasResolveProgram = glutils::Program(); + glAttachShader(m_atlasResolveProgram, m_atlasResolveVertexShader); + m_atlasResolveProgram.compileAndAttachShader( + GL_FRAGMENT_SHADER, + defines.data(), + defines.size(), + atlasResolveSources, + std::size(atlasResolveSources), + m_capabilities); + m_atlasResolveProgram.link(); + + if (m_atlasRenderType == AtlasRenderType::rgba8) + { + // The "rgba8" resolve shader reads the coverageCount data via + // texelFetch(). + m_state->bindProgram(m_atlasResolveProgram); + glutils::Uniform1iByName(m_atlasResolveProgram, + GLSL_atlasRenderTexture, + 0); + } + } +} + void RenderContextGLImpl::invalidateGLState() { glActiveTexture(GL_TEXTURE0 + TESS_VERTEX_TEXTURE_IDX); @@ -353,35 +625,113 @@ class TextureGLImpl : public Texture const GLCapabilities& capabilities) : Texture(width, height), m_texture(glutils::Texture::Adopt(textureID)) {} + virtual ~TextureGLImpl() = default; operator GLuint() const { return m_texture; } + void* nativeHandle() const override + { + return reinterpret_cast( + static_cast(static_cast(m_texture))); + } -private: +protected: glutils::Texture m_texture; }; +#ifdef RIVE_CANVAS +// Lifetime hook for the source texture of a Rive 2D RenderCanvas. When +// this texture is destroyed, the canvas mirror registry entry on the +// owning RenderContextGLImpl must be removed so any subsequent +// wrapRiveTexture lookup for the freed GLuint cannot resurrect a stale +// mirror. The texture's GLuint itself is freed by the base class +// destructor (glutils::Texture RAII). +class CanvasSourceTextureGLImpl : public TextureGLImpl +{ +public: + CanvasSourceTextureGLImpl(uint32_t width, + uint32_t height, + GLuint textureID, + const GLCapabilities& caps, + RenderContextGLImpl* owner) : + TextureGLImpl(width, height, textureID, caps), + m_owner(owner), + m_glID(textureID) + {} + + ~CanvasSourceTextureGLImpl() override + { + if (m_owner != nullptr) + { + m_owner->unregisterCanvasTarget(m_glID); + } + } + +private: + RenderContextGLImpl* m_owner; + GLuint m_glID; +}; + +// Lifetime hook for the mirror texture of an imported canvas. When this +// texture is destroyed, we clear the mirror fields on the registry entry +// (if it still exists) and release the cached read/draw FBOs. The entry +// itself is left in place so the source canvas can re-allocate a new +// mirror later via getOrCreateCanvasMirror. +class CanvasMirrorTextureGLImpl : public TextureGLImpl +{ +public: + CanvasMirrorTextureGLImpl(uint32_t width, + uint32_t height, + GLuint textureID, + const GLCapabilities& caps, + RenderContextGLImpl* owner, + GLuint sourceTexID) : + TextureGLImpl(width, height, textureID, caps), + m_owner(owner), + m_sourceTexID(sourceTexID) + {} + + ~CanvasMirrorTextureGLImpl() override; // Defined below the class + // method definitions on + // RenderContextGLImpl so we + // can call its private API. + +private: + RenderContextGLImpl* m_owner; + GLuint m_sourceTexID; +}; +#endif // RIVE_CANVAS + rcp RenderContextGLImpl::makeImageTexture( uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) { + if (format != GPUTextureFormat::rgba32) + { + assert(!"unsupported format"); + return nullptr; + } + GLuint textureID; glGenTextures(1, &textureID); glActiveTexture(GL_TEXTURE0 + IMAGE_TEXTURE_IDX); glBindTexture(GL_TEXTURE_2D, textureID); glTexStorage2D(GL_TEXTURE_2D, mipLevelCount, GL_RGBA8, width, height); - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - width, - height, - GL_RGBA, - GL_UNSIGNED_BYTE, - imageDataRGBAPremul); - glutils::SetTexture2DSamplingParams(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); - glGenerateMipmap(GL_TEXTURE_2D); + if (imageDataRGBAPremul != nullptr) + { + glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + width, + height, + GL_RGBA, + GL_UNSIGNED_BYTE, + imageDataRGBAPremul); + glGenerateMipmap(GL_TEXTURE_2D); + } return adoptImageTexture(width, height, textureID); } @@ -392,6 +742,245 @@ rcp RenderContextGLImpl::adoptImageTexture(uint32_t width, return make_rcp(width, height, textureID, m_capabilities); } +#ifdef RIVE_CANVAS +rcp RenderContextGLImpl::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + GLuint tex; + glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height); + + // Wrap as a CanvasSourceTextureGLImpl so the registry entry is + // unregistered automatically when the source texture is destroyed. + // The texture takes ownership of `tex` (RAII via glutils::Texture). + auto sourceTexture = + rcp(new CanvasSourceTextureGLImpl(width, + height, + tex, + m_capabilities, + this)); + auto renderImage = make_rcp(std::move(sourceTexture)); + + // Wrap as TextureRenderTargetGL. It references the same GLuint without + // taking ownership. + auto renderTarget = make_rcp(width, height); + renderTarget->setTargetTexture(tex); + + // GL renders into the canvas with row 0 = visual bottom (framebuffer + // bottom-up convention). Register the source GLuint with the mirror + // registry so wrapRiveTexture (ore_context_gl.cpp) can detect it + // later and allocate a Y-flipped companion when an Ore pipeline + // imports it as a sampled texture. The registration is bookkeeping + // only — no GPU allocation happens until first import. + // See dev/ore_canvas_import_invariant.md. + registerCanvasTarget(tex); + + return make_rcp(std::move(renderImage), + std::move(renderTarget)); +} + +// ──────────────────────────────────────────────────────────────────────────── +// Canvas mirror registry implementation (GL-only "imported canvas" handling) +// ──────────────────────────────────────────────────────────────────────────── + +rcp RenderContextGLImpl::getCanvasImportMirror( + gpu::Texture* sourceTex, + uint32_t width, + uint32_t height) +{ + if (sourceTex == nullptr) + { + return nullptr; + } + GLuint glID = static_cast( + reinterpret_cast(sourceTex->nativeHandle())); + if (glID == 0) + { + return nullptr; + } + return getOrCreateCanvasMirror(glID, width, height); +} + +void RenderContextGLImpl::registerCanvasTarget(GLuint sourceTex) +{ + // Insert an empty entry. mirrorTex stays 0 / hasMirror stays false + // until the first wrapRiveTexture call for this source. + m_canvasMirrors[sourceTex] = RenderContextGLImpl::CanvasMirrorEntry{}; +} + +void RenderContextGLImpl::unregisterCanvasTarget(GLuint sourceTex) +{ + auto it = m_canvasMirrors.find(sourceTex); + if (it == m_canvasMirrors.end()) + { + return; + } + // Free FBOs if a mirror was ever allocated. The mirror texture itself + // is owned by its CanvasMirrorTextureGLImpl wrapper; that wrapper is + // either still alive (in which case its destructor will be a no-op + // when it tries to remove an already-removed entry) or already dead + // (in which case the FBOs have already been cleared and re-clearing + // is harmless). + if (it->second.readFBO != 0) + { + glDeleteFramebuffers(1, &it->second.readFBO); + } + if (it->second.drawFBO != 0) + { + glDeleteFramebuffers(1, &it->second.drawFBO); + } + m_canvasMirrors.erase(it); +} + +rcp RenderContextGLImpl::getOrCreateCanvasMirror( + GLuint sourceTex, + uint32_t width, + uint32_t height) +{ + auto it = m_canvasMirrors.find(sourceTex); + if (it == m_canvasMirrors.end()) + { + // Not a registered canvas target — caller should fall through + // and use the source texture directly. + return nullptr; + } + RenderContextGLImpl::CanvasMirrorEntry& entry = it->second; + + // If a mirror already exists, the caller should be reusing the + // RiveRenderImage they previously got back from us. We don't keep + // a strong ref to the mirror image (only the wrapping texture + // implementation), so re-creating one here would alias a live + // GLuint and double-free on shutdown. Therefore: if hasMirror is + // true, we MUST NOT allocate again. Return null and let the caller + // sample the source directly as a fallback. In practice this code + // path is unreachable — the Lua binding caches its cachedOreView + // after the first :view() call. + if (entry.hasMirror) + { + return nullptr; + } + + // Allocate a new companion texture sized to match the source. + GLuint mirrorTex; + glGenTextures(1, &mirrorTex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mirrorTex); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height); + + // Allocate persistent read/draw FBOs and attach source/mirror. + glGenFramebuffers(1, &entry.readFBO); + glGenFramebuffers(1, &entry.drawFBO); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, entry.readFBO); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + sourceTex, + 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, entry.drawFBO); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + mirrorTex, + 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + entry.mirrorTex = mirrorTex; + entry.width = width; + entry.height = height; + entry.hasMirror = true; + + // Wrap the mirror as a CanvasMirrorTextureGLImpl so its destructor + // can clear the entry's mirror fields when the wrapping + // RiveRenderImage is dropped (e.g. when the Lua script GCs the + // bind group containing the view). + auto mirrorTexture = + rcp(new CanvasMirrorTextureGLImpl(width, + height, + mirrorTex, + m_capabilities, + this, + sourceTex)); + auto mirrorImage = make_rcp(std::move(mirrorTexture)); + + // The constructor mutated GL FBO/texture bindings; invalidate + // Rive's GLState cache so subsequent rendering re-applies state. + m_state->invalidate(); + + return mirrorImage; +} + +void RenderContextGLImpl::blitMirrorIfRegistered(GLuint targetTex) +{ + auto it = m_canvasMirrors.find(targetTex); + if (it == m_canvasMirrors.end() || !it->second.hasMirror) + { + // Either not a canvas target or no consumer has imported it yet. + // Common case for non-canvas flushes: O(1) hash miss. + return; + } + const RenderContextGLImpl::CanvasMirrorEntry& entry = it->second; + + // Run the Y-flip blit. Source row 0 (visual bottom) → mirror row + // (h-1) (= visual top under WGSL convention). The destination rect's + // Y is reversed, the source rect is left untouched — that's the + // entire flip, computed by the GPU's hardware blitter. + glBindFramebuffer(GL_READ_FRAMEBUFFER, entry.readFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, entry.drawFBO); + glBlitFramebuffer(0, + 0, + entry.width, + entry.height, // src + 0, + entry.height, + entry.width, + 0, // dst (Y rev) + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + // The blit mutated GL FBO/state that Rive's GLState cache tracks. + // Invalidate so any subsequent Rive rendering re-applies state. + m_state->invalidate(); +} + +// Out-of-line definition for CanvasMirrorTextureGLImpl::~ — needs the +// full RenderContextGLImpl interface to access m_canvasMirrors. +CanvasMirrorTextureGLImpl::~CanvasMirrorTextureGLImpl() +{ + if (m_owner == nullptr) + { + return; + } + auto it = m_owner->m_canvasMirrors.find(m_sourceTexID); + if (it == m_owner->m_canvasMirrors.end()) + { + // Source canvas was already destroyed (and unregisterCanvasTarget + // freed our FBOs). Nothing to clean up here. + return; + } + RenderContextGLImpl::CanvasMirrorEntry& entry = it->second; + if (entry.readFBO != 0) + { + glDeleteFramebuffers(1, &entry.readFBO); + entry.readFBO = 0; + } + if (entry.drawFBO != 0) + { + glDeleteFramebuffers(1, &entry.drawFBO); + entry.drawFBO = 0; + } + entry.mirrorTex = 0; + entry.hasMirror = false; + // Leave the entry in the map — the source canvas is still alive and + // a future getOrCreateCanvasMirror call must be able to find it. +} +#endif + // BufferRingImpl in GL on a given buffer target. In order to support WebGL2, we // don't do hardware mapping. class BufferRingGLImpl : public BufferRing @@ -426,43 +1015,41 @@ class BufferRingGLImpl : public BufferRing void* onMapBuffer(int bufferIdx, size_t mapSizeInBytes) override { - if (m_state->capabilities().isANGLEOrWebGL) - { - // WebGL doesn't support buffer mapping. - return shadowBuffer(); - } - else - { #ifndef RIVE_WEBGL + // WebGL doesn't support buffer mapping. Don't use it on ANGLE either + // since we don't trust ANGLE with features that haven't been validated + // by WebGL. + if (!m_state->capabilities().isANGLESystemDriver) + { m_state->bindBuffer(m_target, m_bufferID); return glMapBufferRange(m_target, 0, mapSizeInBytes, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); -#else - // WebGL doesn't declare glMapBufferRange(). - RIVE_UNREACHABLE(); + } + else #endif + { + return shadowBuffer(); } } void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override { m_state->bindBuffer(m_target, m_bufferID); - if (m_state->capabilities().isANGLEOrWebGL) +#ifndef RIVE_WEBGL + // WebGL doesn't support buffer mapping. Don't use it on ANGLE either + // since we don't trust ANGLE with features that haven't been validated + // by WebGL. + if (!m_state->capabilities().isANGLESystemDriver) { - // WebGL doesn't support buffer mapping. - glBufferSubData(m_target, 0, mapSizeInBytes, shadowBuffer()); + glUnmapBuffer(m_target); } else - { -#ifndef RIVE_WEBGL - glUnmapBuffer(m_target); -#else - // WebGL doesn't declare glUnmapBuffer(). - RIVE_UNREACHABLE(); #endif + { + glBufferSubData(m_target, 0, mapSizeInBytes, shadowBuffer()); } } @@ -645,14 +1232,15 @@ void RenderContextGLImpl::resizeGradientTexture(uint32_t width, uint32_t height) if (width == 0 || height == 0) { m_gradientTexture = 0; - return; } - - glGenTextures(1, &m_gradientTexture); - glActiveTexture(GL_TEXTURE0 + GRAD_TEXTURE_IDX); - glBindTexture(GL_TEXTURE_2D, m_gradientTexture); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height); - glutils::SetTexture2DSamplingParams(GL_LINEAR, GL_LINEAR); + else + { + glGenTextures(1, &m_gradientTexture); + glActiveTexture(GL_TEXTURE0 + GRAD_TEXTURE_IDX); + glBindTexture(GL_TEXTURE_2D, m_gradientTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height); + glutils::SetTexture2DSamplingParams(GL_LINEAR, GL_LINEAR); + } glBindFramebuffer(GL_FRAMEBUFFER, m_colorRampFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, @@ -669,20 +1257,21 @@ void RenderContextGLImpl::resizeTessellationTexture(uint32_t width, if (width == 0 || height == 0) { m_tessVertexTexture = 0; - return; } - - glGenTextures(1, &m_tessVertexTexture); - glActiveTexture(GL_TEXTURE0 + TESS_VERTEX_TEXTURE_IDX); - glBindTexture(GL_TEXTURE_2D, m_tessVertexTexture); - glTexStorage2D(GL_TEXTURE_2D, - 1, - m_capabilities.needsFloatingPointTessellationTexture - ? GL_RGBA32F - : GL_RGBA32UI, - width, - height); - glutils::SetTexture2DSamplingParams(GL_NEAREST, GL_NEAREST); + else + { + glGenTextures(1, &m_tessVertexTexture); + glActiveTexture(GL_TEXTURE0 + TESS_VERTEX_TEXTURE_IDX); + glBindTexture(GL_TEXTURE_2D, m_tessVertexTexture); + glTexStorage2D(GL_TEXTURE_2D, + 1, + m_capabilities.needsFloatingPointTessellationTexture + ? GL_RGBA32F + : GL_RGBA32UI, + width, + height); + glutils::SetTexture2DSamplingParams(GL_NEAREST, GL_NEAREST); + } glBindFramebuffer(GL_FRAMEBUFFER, m_tessellateFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, @@ -735,78 +1324,191 @@ void RenderContextGLImpl::AtlasProgram::compile( } } +static GLenum atlas_render_format( + RenderContextGLImpl::AtlasRenderType atlasRenderType) +{ + switch (atlasRenderType) + { + using AtlasRenderType = RenderContextGLImpl::AtlasRenderType; + case AtlasRenderType::r16f: + return GL_R16F; + case AtlasRenderType::r32f: + return GL_R32F; + case AtlasRenderType::r32uiFramebufferFetch: + return GL_R32UI; + case AtlasRenderType::r8PixelLocalStorageEXT: + return GL_R8; + case AtlasRenderType::r32uiPixelLocalStorageANGLE: + return GL_R32UI; + case AtlasRenderType::r32iAtomicTexture: + return GL_R32I; + case AtlasRenderType::rgba8: + return GL_RGBA8; + } + RIVE_UNREACHABLE(); +} + void RenderContextGLImpl::resizeAtlasTexture(uint32_t width, uint32_t height) { + m_atlasRenderTexture = glutils::Texture::Zero(); + m_atlasTexture = glutils::Texture::Zero(); + m_atlasRenderFBO = glutils::Framebuffer::Zero(); + m_atlasResolveFBO = glutils::Framebuffer::Zero(); + if (width == 0 || height == 0) { - m_atlasTexture = glutils::Texture::Zero(); return; } + const GLenum atlasRenderFormat = atlas_render_format(m_atlasRenderType); + const bool canSampleAtlasRenderFormat = + atlasRenderFormat == GL_R8 || + (atlasRenderFormat == GL_R16F && + m_capabilities.OES_texture_half_float_linear); + if (!canSampleAtlasRenderFormat) + { + // The atlas format we render to cannot be sampled. Create a separate + // texture for rendering that will be resolved into the main (GL_R8) + // atlas texture. + m_atlasRenderTexture = glutils::Texture(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_atlasRenderTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, atlasRenderFormat, width, height); + glutils::SetTexture2DSamplingParams(GL_NEAREST, GL_NEAREST); + } + m_atlasTexture = glutils::Texture(); glActiveTexture(GL_TEXTURE0 + ATLAS_TEXTURE_IDX); glBindTexture(GL_TEXTURE_2D, m_atlasTexture); - glTexStorage2D( - GL_TEXTURE_2D, - 1, - m_capabilities.EXT_float_blend - ? GL_R32F // fp32 is ideal for the atlas. When there's a lot of - // overlap, fp16 can run out of precision. - : GL_R16F, // FIXME: Fallback for when EXT_color_buffer_half_float - // isn't supported. - width, - height); - glutils::SetTexture2DSamplingParams(GL_NEAREST, GL_NEAREST); - - glBindFramebuffer(GL_FRAMEBUFFER, m_atlasFBO); - glFramebufferTexture2D(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - m_atlasTexture, - 0); + glTexStorage2D(GL_TEXTURE_2D, + 1, + canSampleAtlasRenderFormat ? atlasRenderFormat : GL_R8, + width, + height); + glutils::SetTexture2DSamplingParams(GL_LINEAR, GL_LINEAR); - // Don't compile the atlas programs until we get an indication that they - // will be used. if (m_atlasVertexShader == 0) { - std::vector defines; - defines.push_back(GLSL_DRAW_PATH); - defines.push_back(GLSL_ENABLE_FEATHER); - defines.push_back(GLSL_ENABLE_INSTANCE_INDEX); - if (!m_capabilities.ARB_shader_storage_buffer_object) + // Don't compile the atlas programs until we get an indication that + // they will be used. + // FIXME: Do this in parallel at startup!! + buildAtlasRenderPipelines(); + } + + m_atlasRenderFBO = glutils::Framebuffer(); + glBindFramebuffer(GL_FRAMEBUFFER, m_atlasRenderFBO); + switch (m_atlasRenderType) + { + case AtlasRenderType::r16f: + case AtlasRenderType::r32f: + case AtlasRenderType::rgba8: + case AtlasRenderType::r32iAtomicTexture: { - defines.push_back(GLSL_DISABLE_SHADER_STORAGE_BUFFERS); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + (m_atlasRenderTexture != 0) + ? m_atlasRenderTexture + : m_atlasTexture, + 0); + + if (m_atlasRenderTexture != 0) + { + // The atlas will be resolved in a separate render pass or blit. + m_atlasResolveFBO = glutils::Framebuffer(); + glBindFramebuffer(GL_FRAMEBUFFER, m_atlasResolveFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + m_atlasTexture, + 0); + } + break; + } + case AtlasRenderType::r32uiFramebufferFetch: + { + // Use MRT to render and resolve the atlas in a single render pass. + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + m_atlasRenderTexture, + 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT1, + GL_TEXTURE_2D, + m_atlasTexture, + 0); + glDrawBuffers(2, + std::array{GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1} + .data()); + break; + } + case AtlasRenderType::r8PixelLocalStorageEXT: + { +#ifdef RIVE_ANDROID + // EXT_shader_pixel_local_storage can just resolve and output the + // render pass at the end of the PLS render pass. + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + m_atlasTexture, + 0); +#else + RIVE_UNREACHABLE(); +#endif + break; + } + case AtlasRenderType::r32uiPixelLocalStorageANGLE: + { +#ifndef RIVE_ANDROID + // ANGLE_shader_pixel_local_storage can just resolve and output the + // render pass at the end of the PLS render pass. + assert(m_atlasRenderTexture != 0); + glFramebufferTexturePixelLocalStorageANGLE(0, + m_atlasRenderTexture, + 0, + 0, + GL_NONE); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + m_atlasTexture, + 0); +#else + RIVE_UNREACHABLE(); +#endif + break; } - const char* atlasSources[] = {glsl::constants, - glsl::common, - glsl::draw_path_common, - glsl::render_atlas}; - m_atlasVertexShader.compile(GL_VERTEX_SHADER, - defines.data(), - defines.size(), - atlasSources, - std::size(atlasSources), - m_capabilities); - - defines.push_back(GLSL_ATLAS_FEATHERED_FILL); - m_atlasFillProgram.compile(m_atlasVertexShader, - defines.data(), - defines.size(), - atlasSources, - std::size(atlasSources), - m_capabilities, - m_state.get()); - defines.pop_back(); - - defines.push_back(GLSL_ATLAS_FEATHERED_STROKE); - m_atlasStrokeProgram.compile(m_atlasVertexShader, - defines.data(), - defines.size(), - atlasSources, - std::size(atlasSources), - m_capabilities, - m_state.get()); - defines.pop_back(); + } +} + +void RenderContextGLImpl::resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) +{ + if (m_plsImpl != nullptr) + { + m_plsImpl->resizeTransientPLSBacking(width, height, planeCount); + } + else + { + // If we don't support PLS we better not be allocating a backing for it. + assert((width | height | planeCount) == 0); + } +} + +void RenderContextGLImpl::resizeAtomicCoverageBacking(uint32_t width, + uint32_t height) +{ + if (m_plsImpl != nullptr) + { + m_plsImpl->resizeAtomicCoverageBacking(width, height); + } + else + { + // If we don't support PLS we better not be allocating a backing for it. + assert((width | height) == 0); } } @@ -838,25 +1540,31 @@ RenderContextGLImpl::DrawShader::DrawShader( // Atomics are currently always done on storage textures. defines.push_back(GLSL_USING_PLS_STORAGE_TEXTURES); } - if (shaderMiscFlags & gpu::ShaderMiscFlags::fixedFunctionColorOutput) + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput)) { defines.push_back(GLSL_FIXED_FUNCTION_COLOR_OUTPUT); } - if (shaderMiscFlags & gpu::ShaderMiscFlags::clockwiseFill) + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clockwiseFill)) { defines.push_back(GLSL_CLOCKWISE_FILL); } + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)) + { + defines.push_back(GLSL_BORROWED_COVERAGE_PASS); + } for (size_t i = 0; i < kShaderFeatureCount; ++i) { - ShaderFeatures feature = static_cast(1 << i); - if (shaderFeatures & feature) + const auto feature = ShaderFeatures(1 << i); + if (enums::is_flag_set(shaderFeatures, feature)) { - assert((kVertexShaderFeaturesMask & feature) || + assert(enums::is_flag_set(kVertexShaderFeaturesMask, feature) || shaderType == GL_FRAGMENT_SHADER); if (interlockMode == gpu::InterlockMode::msaa && feature == gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND && - renderContextImpl->m_capabilities - .KHR_blend_equation_advanced_coherent) + renderContextImpl->m_capabilities.KHR_blend_equation_advanced) { defines.push_back(GLSL_ENABLE_KHR_BLEND); } @@ -872,22 +1580,9 @@ RenderContextGLImpl::DrawShader::DrawShader( } assert(renderContextImpl->platformFeatures().framebufferBottomUp); defines.push_back(GLSL_FRAMEBUFFER_BOTTOM_UP); - - std::vector sources; - sources.push_back(glsl::constants); - sources.push_back(glsl::common); - if (shaderType == GL_FRAGMENT_SHADER && - (shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND)) - { - sources.push_back(glsl::advanced_blend); - } - if (renderContextImpl->platformFeatures().avoidFlatVaryings) - { - sources.push_back("#define " GLSL_OPTIONALLY_FLAT "\n"); - } - else + if (!renderContextImpl->m_capabilities.ARB_shader_storage_buffer_object) { - sources.push_back("#define " GLSL_OPTIONALLY_FLAT " flat\n"); + defines.push_back(GLSL_DISABLE_SHADER_STORAGE_BUFFERS); } switch (drawType) { @@ -906,65 +1601,153 @@ RenderContextGLImpl::DrawShader::DrawShader( defines.push_back(GLSL_ENABLE_INSTANCE_INDEX); } defines.push_back(GLSL_DRAW_PATH); - sources.push_back(gpu::glsl::draw_path_common); - sources.push_back(interlockMode == gpu::InterlockMode::atomics - ? gpu::glsl::atomic_draw - : gpu::glsl::draw_path); break; - case gpu::DrawType::msaaStencilClipReset: - assert(interlockMode == gpu::InterlockMode::msaa); - sources.push_back(gpu::glsl::stencil_draw); + case gpu::DrawType::clipReset: break; - case gpu::DrawType::atlasBlit: - defines.push_back(GLSL_ATLAS_BLIT); - [[fallthrough]]; case gpu::DrawType::interiorTriangulation: defines.push_back(GLSL_DRAW_INTERIOR_TRIANGLES); - sources.push_back(gpu::glsl::draw_path_common); - sources.push_back(interlockMode == gpu::InterlockMode::atomics - ? gpu::glsl::atomic_draw - : gpu::glsl::draw_path); + break; + case gpu::DrawType::atlasBlit: + defines.push_back(GLSL_ATLAS_BLIT); break; case gpu::DrawType::imageRect: assert(interlockMode == gpu::InterlockMode::atomics); defines.push_back(GLSL_DRAW_IMAGE); defines.push_back(GLSL_DRAW_IMAGE_RECT); - sources.push_back(gpu::glsl::draw_path_common); - sources.push_back(gpu::glsl::atomic_draw); break; case gpu::DrawType::imageMesh: defines.push_back(GLSL_DRAW_IMAGE); defines.push_back(GLSL_DRAW_IMAGE_MESH); - if (interlockMode == gpu::InterlockMode::atomics) - { - sources.push_back(gpu::glsl::draw_path_common); - sources.push_back(gpu::glsl::atomic_draw); - } - else - { - sources.push_back(gpu::glsl::draw_image_mesh); - } break; - case gpu::DrawType::atomicResolve: + case gpu::DrawType::renderPassResolve: assert(interlockMode == gpu::InterlockMode::atomics); defines.push_back(GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS); defines.push_back(GLSL_RESOLVE_PLS); - if (shaderMiscFlags & - gpu::ShaderMiscFlags::coalescedResolveAndTransfer) + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::coalescedResolveAndTransfer)) { assert(shaderType == GL_FRAGMENT_SHADER); defines.push_back(GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER); } - sources.push_back(gpu::glsl::draw_path_common); - sources.push_back(gpu::glsl::atomic_draw); break; - case gpu::DrawType::atomicInitialize: - assert(interlockMode == gpu::InterlockMode::atomics); + case gpu::DrawType::renderPassInitialize: RIVE_UNREACHABLE(); } - if (!renderContextImpl->m_capabilities.ARB_shader_storage_buffer_object) + + std::vector sources; + if (renderContextImpl->platformFeatures().avoidFlatVaryings) { - defines.push_back(GLSL_DISABLE_SHADER_STORAGE_BUFFERS); + sources.push_back("#define " GLSL_OPTIONALLY_FLAT "\n"); + } + else + { + sources.push_back("#define " GLSL_OPTIONALLY_FLAT " flat\n"); + } + sources.push_back(glsl::constants); + sources.push_back(glsl::flush_uniforms); + sources.push_back(glsl::common); + if (shaderType == GL_FRAGMENT_SHADER && + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_ADVANCED_BLEND)) + { + sources.push_back(glsl::advanced_blend); + } + switch (interlockMode) + { + case gpu::InterlockMode::rasterOrdering: + case gpu::InterlockMode::clockwise: + switch (drawType) + { + case gpu::DrawType::midpointFanPatches: + case gpu::DrawType::midpointFanCenterAAPatches: + case gpu::DrawType::outerCurvePatches: + case gpu::DrawType::interiorTriangulation: + sources.push_back(gpu::glsl::draw_path_common); + sources.push_back(gpu::glsl::draw_path_vert); + sources.push_back( + (interlockMode == gpu::InterlockMode::clockwise) + ? enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly) + ? gpu::glsl::draw_clockwise_clip_frag + : gpu::glsl::draw_clockwise_path_frag + : gpu::glsl::draw_raster_order_path_frag); + break; + case gpu::DrawType::atlasBlit: + sources.push_back(gpu::glsl::draw_path_common); + sources.push_back(gpu::glsl::draw_path_vert); + sources.push_back(gpu::glsl::draw_mesh_frag); + break; + case gpu::DrawType::imageMesh: + sources.push_back(gpu::glsl::image_draw_uniforms); + sources.push_back(gpu::glsl::draw_image_mesh_vert); + sources.push_back(gpu::glsl::draw_mesh_frag); + break; + case gpu::DrawType::imageRect: + case gpu::DrawType::msaaStrokes: + case gpu::DrawType::msaaMidpointFanBorrowedCoverage: + case gpu::DrawType::msaaMidpointFans: + case gpu::DrawType::msaaMidpointFanStencilReset: + case gpu::DrawType::msaaMidpointFanPathsStencil: + case gpu::DrawType::msaaMidpointFanPathsCover: + case gpu::DrawType::msaaOuterCubics: + case gpu::DrawType::clipReset: + case gpu::DrawType::renderPassInitialize: + case gpu::DrawType::renderPassResolve: + RIVE_UNREACHABLE(); + } + break; + + case gpu::InterlockMode::atomics: + if (gpu::DrawTypeIsImageDraw(drawType)) + { + sources.push_back(gpu::glsl::image_draw_uniforms); + } + sources.push_back(gpu::glsl::draw_path_common); + sources.push_back(gpu::glsl::atomic_draw); + break; + + case gpu::InterlockMode::msaa: + switch (drawType) + { + case gpu::DrawType::msaaStrokes: + case gpu::DrawType::msaaMidpointFanBorrowedCoverage: + case gpu::DrawType::msaaMidpointFans: + case gpu::DrawType::msaaMidpointFanStencilReset: + case gpu::DrawType::msaaMidpointFanPathsStencil: + case gpu::DrawType::msaaMidpointFanPathsCover: + case gpu::DrawType::msaaOuterCubics: + case gpu::DrawType::interiorTriangulation: + sources.push_back(gpu::glsl::draw_path_common); + sources.push_back(gpu::glsl::draw_path_vert); + sources.push_back(gpu::glsl::draw_msaa_object_frag); + break; + case gpu::DrawType::clipReset: + sources.push_back(gpu::glsl::stencil_draw); + break; + case gpu::DrawType::atlasBlit: + sources.push_back(gpu::glsl::draw_path_common); + sources.push_back(gpu::glsl::draw_path_vert); + sources.push_back(gpu::glsl::draw_msaa_object_frag); + break; + case gpu::DrawType::imageMesh: + sources.push_back(glsl::image_draw_uniforms); + sources.push_back(gpu::glsl::draw_image_mesh_vert); + sources.push_back(gpu::glsl::draw_msaa_object_frag); + break; + case gpu::DrawType::midpointFanPatches: + case gpu::DrawType::midpointFanCenterAAPatches: + case gpu::DrawType::outerCurvePatches: + case gpu::DrawType::imageRect: + case gpu::DrawType::renderPassInitialize: + case gpu::DrawType::renderPassResolve: + RIVE_UNREACHABLE(); + } + break; + + case gpu::InterlockMode::clockwiseAtomic: + RIVE_UNREACHABLE(); } m_id = glutils::CompileShader(shaderType, @@ -972,46 +1755,156 @@ RenderContextGLImpl::DrawShader::DrawShader( defines.size(), sources.data(), sources.size(), - renderContextImpl->m_capabilities); + renderContextImpl->m_capabilities, + glutils::DebugPrintErrorAndAbort::no); +} + +RenderContextGLImpl::DrawShader::DrawShader(DrawShader&& moveFrom) : + m_id(std::exchange(moveFrom.m_id, 0)) +{} + +RenderContextGLImpl::DrawShader& RenderContextGLImpl::DrawShader ::operator=( + DrawShader&& moveFrom) +{ + if (&moveFrom != this) + { + if (m_id != 0) + { + glDeleteShader(m_id); + } + + m_id = std::exchange(moveFrom.m_id, 0); + } + + return *this; +} + +RenderContextGLImpl::DrawShader::~DrawShader() +{ + if (m_id != 0) + { + glDeleteShader(m_id); + } } RenderContextGLImpl::DrawProgram::DrawProgram( RenderContextGLImpl* renderContextImpl, + PipelineCreateType createType, gpu::DrawType drawType, gpu::ShaderFeatures shaderFeatures, gpu::InterlockMode interlockMode, - gpu::ShaderMiscFlags shaderMiscFlags) : - m_fragmentShader(renderContextImpl, - GL_FRAGMENT_SHADER, - drawType, - shaderFeatures, - interlockMode, - shaderMiscFlags), + gpu::ShaderMiscFlags shaderMiscFlags +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType synthesizedFailureType +#endif + ) : m_state(renderContextImpl->m_state) { - // Not every vertex shader is unique. Cache them by just the vertex features - // and reuse when possible. - ShaderFeatures vertexShaderFeatures = - shaderFeatures & kVertexShaderFeaturesMask; - uint32_t vertexShaderKey = gpu::ShaderUniqueKey(drawType, - vertexShaderFeatures, - interlockMode, - gpu::ShaderMiscFlags::none); - const DrawShader& vertexShader = - renderContextImpl->m_vertexShaders - .try_emplace(vertexShaderKey, - renderContextImpl, - GL_VERTEX_SHADER, - drawType, - vertexShaderFeatures, - interlockMode, - gpu::ShaderMiscFlags::none) - .first->second; +#ifdef WITH_RIVE_TOOLS + m_synthesizedFailureType = synthesizedFailureType; + if (m_synthesizedFailureType == SynthesizedFailureType::shaderCompilation) + { + m_pipelineStatus = PipelineStatus::errored; + return; + } +#endif + + m_vertexShader = + &renderContextImpl->m_pipelineManager.getVertexShaderSynchronous( + drawType, + shaderFeatures, + interlockMode); + + m_fragmentShader = + &renderContextImpl->m_pipelineManager.getFragmentShaderSynchronous( + drawType, + shaderFeatures, + interlockMode, + shaderMiscFlags); m_id = glCreateProgram(); - glAttachShader(m_id, vertexShader.id()); - glAttachShader(m_id, m_fragmentShader.id()); - glutils::LinkProgram(m_id); + + // In async mode, we do not need to wait for the shaders to finish compiling + // before doing the link - the link is what we actually can poll to ensure + // everything finishes. If the linking fails, that is where we can check the + // compilation statuses and display compilation errors as needed. + glAttachShader(m_id, m_vertexShader->id()); + glAttachShader(m_id, m_fragmentShader->id()); + glutils::LinkProgram(m_id, glutils::DebugPrintErrorAndAbort::no); + + std::ignore = advanceCreation(renderContextImpl, + createType, + drawType, + shaderFeatures, + interlockMode, + shaderMiscFlags); +} + +bool RenderContextGLImpl::DrawProgram::advanceCreation( + RenderContextGLImpl* renderContextImpl, + PipelineCreateType createType, + gpu::DrawType drawType, + ShaderFeatures shaderFeatures, + gpu::InterlockMode interlockMode, + gpu::ShaderMiscFlags shaderMiscFlags) +{ + // This function should only be called if we're in the middle of creation. + assert(m_pipelineStatus == PipelineStatus::notReady); + + if (createType == PipelineCreateType::async && + renderContextImpl->capabilities().KHR_parallel_shader_compile) + { + // Like above, this is async creation so verify the program is linked + // before continuing. + + GLint completed = 0; + glGetProgramiv(m_id, GL_COMPLETION_STATUS_KHR, &completed); + if (completed == 0) + { + return false; + } + } + +#ifdef WITH_RIVE_TOOLS + if (m_synthesizedFailureType == SynthesizedFailureType::pipelineCreation) + { + m_pipelineStatus = PipelineStatus::errored; + return false; + } +#endif + + { + GLint successfullyLinked = 0; + glGetProgramiv(m_id, GL_LINK_STATUS, &successfullyLinked); + if (successfullyLinked == GL_FALSE) + { +#ifdef DEBUG + // The link failed, which might have been caused by compilation + // failures, so output any compilation failure messages first. + GLint compiledSuccessfully = 0; + glGetShaderiv(m_vertexShader->id(), + GL_COMPILE_STATUS, + &compiledSuccessfully); + if (compiledSuccessfully == GL_FALSE) + { + glutils::PrintShaderCompilationErrors(m_vertexShader->id()); + } + + glGetShaderiv(m_fragmentShader->id(), + GL_COMPILE_STATUS, + &compiledSuccessfully); + if (compiledSuccessfully == GL_FALSE) + { + glutils::PrintShaderCompilationErrors(m_fragmentShader->id()); + } + + glutils::PrintLinkProgramErrors(m_id); +#endif + m_pipelineStatus = PipelineStatus::errored; + return false; + } + } m_state->bindProgram(m_id); glUniformBlockBinding(m_id, @@ -1020,9 +1913,13 @@ RenderContextGLImpl::DrawProgram::DrawProgram( const bool isImageDraw = gpu::DrawTypeIsImageDraw(drawType); const bool isTessellationDraw = is_tessellation_draw(drawType); - const bool isPaintDraw = isTessellationDraw || - drawType == gpu::DrawType::interiorTriangulation || - drawType == gpu::DrawType::atlasBlit; + const bool isPaintDraw = + (isTessellationDraw || + drawType == gpu::DrawType::interiorTriangulation || + drawType == gpu::DrawType::atlasBlit) && + enums::no_flags_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly | + gpu::ShaderMiscFlags::borrowedCoveragePass); if (isImageDraw) { glUniformBlockBinding( @@ -1042,9 +1939,8 @@ RenderContextGLImpl::DrawProgram::DrawProgram( { glutils::Uniform1iByName(m_id, GLSL_gradTexture, GRAD_TEXTURE_IDX); } - if ((isTessellationDraw && - (shaderFeatures & ShaderFeatures::ENABLE_FEATHER)) || - drawType == gpu::DrawType::atlasBlit) + if (isTessellationDraw && + enums::is_flag_set(shaderFeatures, ShaderFeatures::ENABLE_FEATHER)) { assert(isPaintDraw || interlockMode == gpu::InterlockMode::atomics); glutils::Uniform1iByName(m_id, @@ -1084,8 +1980,11 @@ RenderContextGLImpl::DrawProgram::DrawProgram( } } if (interlockMode == gpu::InterlockMode::msaa && - (shaderFeatures & gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) && - !renderContextImpl->m_capabilities.KHR_blend_equation_advanced_coherent) + enums::is_flag_set(shaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) && + !renderContextImpl->m_capabilities.KHR_blend_equation_advanced && + !enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput)) { glutils::Uniform1iByName(m_id, GLSL_dstColorTexture, @@ -1097,11 +1996,18 @@ RenderContextGLImpl::DrawProgram::DrawProgram( m_baseInstanceUniformLocation = glGetUniformLocation(m_id, glutils::BASE_INSTANCE_UNIFORM_NAME); } + + // All done! This program is now usable by the renderer. + m_pipelineStatus = PipelineStatus::ready; + return true; } RenderContextGLImpl::DrawProgram::~DrawProgram() { - m_state->deleteProgram(m_id); + if (m_id != 0) + { + m_state->deleteProgram(m_id); + } } static GLuint gl_buffer_id(const BufferRing* bufferRing) @@ -1139,7 +2045,8 @@ void RenderContextGLImpl::PixelLocalStorageImpl::ensureRasterOrderingEnabled( bool enabled) { assert(!enabled || - supportsRasterOrdering(renderContextImpl->m_capabilities)); + renderContextImpl->platformFeatures().supportsRasterOrderingMode || + renderContextImpl->platformFeatures().supportsClockwiseMode); auto rasterOrderState = enabled ? gpu::TriState::yes : gpu::TriState::no; if (m_rasterOrderingEnabled != rasterOrderState) { @@ -1155,6 +2062,92 @@ void RenderContextGLImpl::PixelLocalStorageImpl::ensureRasterOrderingEnabled( } } +void RenderContextGLImpl::preBeginFrame(RenderContext* ctx) +{ + if (!m_testForAdvancedBlendError) + { + return; + } + + // We need to do a test to check whether or not KHR_blend_equation_advanced + // actually works as advertised. This is basically done by rendering a + // quad with a fancy blend mode to a tiny render target, reading it back, + // then checking how close to the true color we are. + + m_testForAdvancedBlendError = false; + + constexpr uint32_t RT_WIDTH = 4; + constexpr uint32_t RT_HEIGHT = 4; + constexpr ColorInt RT_CLEAR_COLOR = 0x8000ffff; + + RenderContext::FrameDescriptor fd = { + .renderTargetWidth = RT_WIDTH, + .renderTargetHeight = RT_HEIGHT, + .clearColor = RT_CLEAR_COLOR, + }; + + glutils::Texture texture; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, RT_WIDTH, RT_HEIGHT); + + TextureRenderTargetGL rt{RT_WIDTH, RT_HEIGHT}; + rt.setTargetTexture(texture); + + ctx->beginFrame(fd); + + RiveRenderer renderer{ctx}; + + constexpr ColorInt RT_QUAD_FILL_COLOR = 0x80404000; + + auto paint = ctx->makeRenderPaint(); + paint->style(RenderPaintStyle::fill); + paint->color(RT_QUAD_FILL_COLOR); + paint->blendMode(BlendMode::colorBurn); + + auto path = ctx->makeEmptyRenderPath(); + path->fillRule(FillRule::clockwise); + path->moveTo(-1.0f, -1.0f); + path->lineTo(float(RT_WIDTH + 1), -1.0f); + path->lineTo(float(RT_WIDTH + 1), float(RT_HEIGHT + 1)); + path->lineTo(-1.0f, float(RT_HEIGHT + 1)); + + renderer.drawPath(path.get(), paint.get()); + + ctx->flush({.renderTarget = &rt}); + + rt.bindDestinationFramebuffer(GL_READ_FRAMEBUFFER); + + uint8_t pixel[4]; + glReadPixels(1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); + + // Note that this color is *not* in the same channel order as the above + // colors. + uint8_t EXPECTED_COLOR[] = {0x10, 0x90, 0x80, 0xc0}; + + int maxRGBDiff = std::max({std::abs(int(pixel[0] - EXPECTED_COLOR[0])), + std::abs(int(pixel[1] - EXPECTED_COLOR[1])), + std::abs(int(pixel[2] - EXPECTED_COLOR[2]))}); + + // Note that the RGB mismatch we are seeing that this is fixing is 96. + constexpr int DIFF_TOLERANCE = 40; + if (maxRGBDiff > DIFF_TOLERANCE) + { + // If the blending was out of tolerance then we need to disable this + // feature. + m_capabilities.KHR_blend_equation_advanced_coherent = false; + m_capabilities.KHR_blend_equation_advanced = false; + m_platformFeatures.supportsBlendAdvancedCoherentKHR = false; + m_platformFeatures.supportsBlendAdvancedKHR = false; + + // We also need to clear the shader caches because shaders get built + // differently based on whether KHR_blend_equation_advanced is set. + // Thankfully we should only have a couple that we just created for + // the test. + m_pipelineManager.clearCache(); + } +} + void RenderContextGLImpl::flush(const FlushDescriptor& desc) { assert(desc.interlockMode != gpu::InterlockMode::clockwiseAtomic); @@ -1198,6 +2191,8 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) desc.firstContour * sizeof(gpu::ContourData)); } + GLFlushInjector flushInjector(m_capabilities); + // Render the complex color ramps into the gradient texture. if (desc.gradSpanCount > 0) { @@ -1218,124 +2213,329 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) &nullData); } + m_state->bindProgram(m_colorRampProgram); + glBindFramebuffer(GL_FRAMEBUFFER, m_colorRampFBO); + glViewport(0, 0, kGradTextureWidth, desc.gradDataHeight); m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); m_state->bindBuffer(GL_ARRAY_BUFFER, gl_buffer_id(gradSpanBufferRing())); m_state->bindVAO(m_colorRampVAO); - glVertexAttribIPointer( - 0, - 4, - GL_UNSIGNED_INT, - 0, - reinterpret_cast(desc.firstGradSpan * - sizeof(gpu::GradientSpan))); - glViewport(0, 0, kGradTextureWidth, desc.gradDataHeight); - glBindFramebuffer(GL_FRAMEBUFFER, m_colorRampFBO); - m_state->bindProgram(m_colorRampProgram); GLenum colorAttachment0 = GL_COLOR_ATTACHMENT0; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &colorAttachment0); - glDrawArraysInstanced(GL_TRIANGLE_STRIP, - 0, - gpu::GRAD_SPAN_TRI_STRIP_VERTEX_COUNT, - desc.gradSpanCount); + for (auto [chunkInstanceCount, chunkBaseInstance] : InstanceChunker( + desc.gradSpanCount, + math::lossless_numeric_cast(desc.firstGradSpan), + m_capabilities.maxSupportedInstancesPerFlush)) + + { + glVertexAttribIPointer( + 0, + 4, + GL_UNSIGNED_INT, + 0, + reinterpret_cast(chunkBaseInstance * + sizeof(gpu::GradientSpan))); + flushInjector.flushBeforeInstancedDrawIfNeeded(chunkInstanceCount); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, + 0, + gpu::GRAD_SPAN_TRI_STRIP_VERTEX_COUNT, + chunkInstanceCount); + } } // Tessellate all curves into vertices in the tessellation texture. if (desc.tessVertexSpanCount > 0) { + m_state->bindProgram(m_tessellateProgram); + glBindFramebuffer(GL_FRAMEBUFFER, m_tessellateFBO); + glViewport(0, 0, gpu::kTessTextureWidth, desc.tessDataHeight); m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); m_state->bindBuffer(GL_ARRAY_BUFFER, gl_buffer_id(tessSpanBufferRing())); m_state->bindVAO(m_tessellateVAO); - size_t tessSpanOffsetInBytes = - desc.firstTessVertexSpan * sizeof(gpu::TessVertexSpan); - for (GLuint i = 0; i < 3; ++i) - { - glVertexAttribPointer(i, - 4, - GL_FLOAT, - GL_FALSE, - sizeof(TessVertexSpan), - reinterpret_cast( - tessSpanOffsetInBytes + i * 4 * 4)); - } - glVertexAttribIPointer( - 3, - 4, - GL_UNSIGNED_INT, - sizeof(TessVertexSpan), - reinterpret_cast(tessSpanOffsetInBytes + - offsetof(TessVertexSpan, x0x1))); - glViewport(0, 0, gpu::kTessTextureWidth, desc.tessDataHeight); - glBindFramebuffer(GL_FRAMEBUFFER, m_tessellateFBO); - m_state->bindProgram(m_tessellateProgram); GLenum colorAttachment0 = GL_COLOR_ATTACHMENT0; glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &colorAttachment0); - glDrawElementsInstanced(GL_TRIANGLES, - std::size(gpu::kTessSpanIndices), - GL_UNSIGNED_SHORT, - 0, - desc.tessVertexSpanCount); + for (auto [chunkInstanceCount, chunkBaseInstance] : + InstanceChunker(desc.tessVertexSpanCount, + math::lossless_numeric_cast( + desc.firstTessVertexSpan), + m_capabilities.maxSupportedInstancesPerFlush)) + + { + size_t tessSpanOffsetInBytes = + chunkBaseInstance * sizeof(gpu::TessVertexSpan); + for (GLuint i = 0; i < 3; ++i) + { + glVertexAttribPointer(i, + 4, + GL_FLOAT, + GL_FALSE, + sizeof(TessVertexSpan), + reinterpret_cast( + tessSpanOffsetInBytes + i * 4 * 4)); + } + glVertexAttribIPointer( + 3, + 4, + GL_UNSIGNED_INT, + sizeof(TessVertexSpan), + reinterpret_cast(tessSpanOffsetInBytes + + offsetof(TessVertexSpan, x0x1))); + flushInjector.flushBeforeInstancedDrawIfNeeded(chunkInstanceCount); + glDrawElementsInstanced(GL_TRIANGLES, + std::size(gpu::kTessSpanIndices), + GL_UNSIGNED_SHORT, + 0, + chunkInstanceCount); + } } // Render the atlas if we have any offscreen feathers. if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0) { - glBindFramebuffer(GL_FRAMEBUFFER, m_atlasFBO); + // Finish setting up the atlas render pass and clear the atlas. + m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); + + glBindFramebuffer(GL_FRAMEBUFFER, m_atlasRenderFBO); glViewport(0, 0, desc.atlasContentWidth, desc.atlasContentHeight); - glEnable(GL_SCISSOR_TEST); - glScissor(0, 0, desc.atlasContentWidth, desc.atlasContentHeight); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - m_state->bindVAO(m_drawVAO); + + // Since the atlas texture is offscreen, we render with the top at the + // lower memory address, and therefore don't need the typical Y-flip + // that happens with GL rectangles. + m_state->setScissorRaw(0, + 0, + desc.atlasContentWidth, + desc.atlasContentHeight); + // Invert the front face for atlas draws because GL is bottom up. glFrontFace(GL_CCW); + switch (m_atlasRenderType) + { + case AtlasRenderType::r16f: + case AtlasRenderType::r32f: + case AtlasRenderType::rgba8: + { + constexpr GLfloat clearZero4f[4]{}; + glClearBufferfv(GL_COLOR, 0, clearZero4f); + break; + } + case AtlasRenderType::r32uiFramebufferFetch: + { + constexpr GLuint clearZero4ui[4]{}; + glClearBufferuiv(GL_COLOR, 1, clearZero4ui); + break; + } + case AtlasRenderType::r8PixelLocalStorageEXT: + { +#ifdef RIVE_ANDROID + glEnable(GL_SHADER_PIXEL_LOCAL_STORAGE_EXT); + // EXT_shader_pixel_local_storage doesn't support clearing. + // Render the clear color. + m_state->bindProgram(m_atlasClearProgram); + m_state->bindVAO(m_atlasResolveVAO); + m_state->setCullFace(GL_FRONT); + glDrawArrays(GL_TRIANGLES, 0, 3); +#else + RIVE_UNREACHABLE(); +#endif + break; + } + case AtlasRenderType::r32uiPixelLocalStorageANGLE: + { +#ifndef RIVE_ANDROID + glBeginPixelLocalStorageANGLE( + 1, + std::array{GL_LOAD_OP_ZERO_ANGLE}.data()); +#else + RIVE_UNREACHABLE(); +#endif + break; + } + case AtlasRenderType::r32iAtomicTexture: + { +#ifndef RIVE_WEBGL + constexpr GLint clearZero4i[4]{}; + glClearBufferiv(GL_COLOR, 0, clearZero4i); + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | + GL_FRAMEBUFFER_BARRIER_BIT); + m_state->setWriteMasks(false, false, 0); + glBindImageTexture(0, + m_atlasRenderTexture, + 0, + GL_FALSE, + 0, + GL_READ_WRITE, + GL_R32I); +#else + RIVE_UNREACHABLE(); +#endif + break; + } + } + m_state->bindVAO(m_drawVAO); + + // Draw the atlas fills. if (desc.atlasFillBatchCount != 0) { - m_state->setPipelineState(gpu::ATLAS_FILL_PIPELINE_STATE); + m_state->setPipelineState(m_atlasFillPipelineState); m_state->bindProgram(m_atlasFillProgram); for (size_t i = 0; i < desc.atlasFillBatchCount; ++i) { - const gpu::AtlasDrawBatch& fillBatch = desc.atlasFillBatches[i]; - glScissor(fillBatch.scissor.left, - fillBatch.scissor.top, - fillBatch.scissor.width(), - fillBatch.scissor.height()); - drawIndexedInstancedNoInstancedAttribs( - GL_TRIANGLES, - gpu::kMidpointFanCenterAAPatchIndexCount, - gpu::kMidpointFanCenterAAPatchBaseIndex, - fillBatch.patchCount, - fillBatch.basePatch, - m_atlasFillProgram.baseInstanceUniformLocation()); + const gpu::AtlasDrawBatch& fillBatch = desc.atlasFillBatches[i]; + m_state->setScissorRaw(fillBatch.scissor.left, + fillBatch.scissor.top, + fillBatch.scissor.width(), + fillBatch.scissor.height()); + drawIndexedInstancedNoInstancedAttribs( + GL_TRIANGLES, + gpu::kMidpointFanCenterAAPatchIndexCount, + gpu::kMidpointFanCenterAAPatchBaseIndex, + fillBatch.patchCount, + fillBatch.basePatch, + m_atlasFillProgram.baseInstanceUniformLocation(), + &flushInjector); + } + } + + // Draw the atlas strokes. + if (desc.atlasStrokeBatchCount != 0) + { + m_state->setPipelineState(m_atlasStrokePipelineState); + m_state->bindProgram(m_atlasStrokeProgram); + for (size_t i = 0; i < desc.atlasStrokeBatchCount; ++i) + { + const gpu::AtlasDrawBatch& strokeBatch = + desc.atlasStrokeBatches[i]; + m_state->setScissorRaw(strokeBatch.scissor.left, + strokeBatch.scissor.top, + strokeBatch.scissor.width(), + strokeBatch.scissor.height()); + drawIndexedInstancedNoInstancedAttribs( + GL_TRIANGLES, + gpu::kMidpointFanPatchBorderIndexCount, + gpu::kMidpointFanPatchBaseIndex, + strokeBatch.patchCount, + strokeBatch.basePatch, + m_atlasStrokeProgram.baseInstanceUniformLocation(), + &flushInjector); + } + } + + if (m_atlasResolveProgram != 0) + { + // We need an additional fullscreen draw to resolve the atlas + // into a GL_R8 texture that can be sampled. + if (m_atlasRenderType == AtlasRenderType::r32iAtomicTexture) + { +#ifndef RIVE_WEBGL + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); +#else + RIVE_UNREACHABLE(); +#endif + } + + if (m_atlasResolveFBO != 0) + { + glBindFramebuffer(GL_FRAMEBUFFER, m_atlasResolveFBO); + } + + if (m_atlasRenderType == AtlasRenderType::rgba8) + { + // The "rgba8" resolve shader reads the coverageCount data via + // texelFetch(). + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_atlasRenderTexture); + } + + m_state->bindProgram(m_atlasResolveProgram); + m_state->bindVAO(m_atlasResolveVAO); + m_state->setCullFace(GL_NONE); + m_state->setScissorRaw(0, + 0, + desc.atlasContentWidth, + desc.atlasContentHeight); + m_state->disableBlending(); + m_state->setWriteMasks(true, false, 0); + glDrawArrays(GL_TRIANGLES, 0, 3); + } + + // Finalize the atlas render pass if needed. + switch (m_atlasRenderType) + { + case AtlasRenderType::r16f: + case AtlasRenderType::r32f: + { + // If there is no m_atlasResolveFBO, it means we will sample + // directly from the (GL_R16F) atlas texture without resolving + // to GL_R8. + if (m_atlasResolveFBO != 0) + { + // Otherwise, blit m_atlasRenderTexture into the (GL_R8) + // m_atlasTexture. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_atlasResolveFBO); + m_state->disableScissor(); + glBlitFramebuffer(0, + 0, + desc.atlasContentWidth, + desc.atlasContentHeight, + 0, + 0, + desc.atlasContentWidth, + desc.atlasContentHeight, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + } + break; + } + case AtlasRenderType::r32uiFramebufferFetch: + { + // Let the tiler know it can discard the GL_R32UI coverageCount + // attachment now that we've resolved it to GL_R8. + glInvalidateFramebuffer( + GL_FRAMEBUFFER, + 1, + std::array{GL_COLOR_ATTACHMENT0}.data()); + break; + } + case AtlasRenderType::r8PixelLocalStorageEXT: + { +#ifdef RIVE_ANDROID + glDisable(GL_SHADER_PIXEL_LOCAL_STORAGE_EXT); +#else + RIVE_UNREACHABLE(); +#endif + break; + } + case AtlasRenderType::r32uiPixelLocalStorageANGLE: + { +#ifndef RIVE_ANDROID + // Discard PLS now that we've resolved it to GL_R8. + glEndPixelLocalStorageANGLE( + 1, + std::array{GL_DONT_CARE}.data()); +#else + RIVE_UNREACHABLE(); +#endif + break; + } + case AtlasRenderType::r32iAtomicTexture: + { +#ifndef RIVE_WEBGL + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | + GL_FRAMEBUFFER_BARRIER_BIT); +#else + RIVE_UNREACHABLE(); +#endif + break; } - } - - if (desc.atlasStrokeBatchCount != 0) - { - m_state->setPipelineState(gpu::ATLAS_STROKE_PIPELINE_STATE); - m_state->bindProgram(m_atlasStrokeProgram); - for (size_t i = 0; i < desc.atlasStrokeBatchCount; ++i) + case AtlasRenderType::rgba8: { - const gpu::AtlasDrawBatch& strokeBatch = - desc.atlasStrokeBatches[i]; - glScissor(strokeBatch.scissor.left, - strokeBatch.scissor.top, - strokeBatch.scissor.width(), - strokeBatch.scissor.height()); - drawIndexedInstancedNoInstancedAttribs( - GL_TRIANGLES, - gpu::kMidpointFanPatchBorderIndexCount, - gpu::kMidpointFanPatchBaseIndex, - strokeBatch.patchCount, - strokeBatch.basePatch, - m_atlasFillProgram.baseInstanceUniformLocation()); + break; } } glFrontFace(GL_CW); - glDisable(GL_SCISSOR_TEST); } // Bind the currently-submitted buffer in the triangleBufferRing to its @@ -1363,6 +2563,7 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) if (desc.interlockMode != gpu::InterlockMode::msaa) { assert(desc.msaaSampleCount == 0); + assert(m_plsImpl != nullptr); m_plsImpl->activatePixelLocalStorage(this, desc); if (desc.interlockMode == gpu::InterlockMode::atomics) { @@ -1404,11 +2605,11 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) glClearColor(cc[0], cc[1], cc[2], cc[3]); buffersToClear |= GL_COLOR_BUFFER_BIT; } - m_state->setWriteMasks(true, true, 0xff); + m_state->setPipelineState(gpu::GL_DEFAULT_PIPELINE_STATE); glClear(buffersToClear); - if (desc.combinedShaderFeatures & - gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) + if (enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND)) { if (m_capabilities.KHR_blend_equation_advanced_coherent) { @@ -1416,10 +2617,14 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) } else { - // Set up an internal texture to copy the framebuffer into, for - // in-shader blending. - renderTarget->bindInternalDstTexture(GL_TEXTURE0 + - DST_COLOR_TEXTURE_IDX); + // Bind the dstColorTexture where it can be read for in-shader + // blending. We will resolve MSAA into this texture before + // issuing draws that use advanced blend. + // NOTE: The dstColorTexture() function may lazily allocate the + // texture, so don't call glActiveTexture() until it returns. + GLuint dstColorTexture = renderTarget->dstColorTexture(); + glActiveTexture(GL_TEXTURE0 + DST_COLOR_TEXTURE_IDX); + glBindTexture(GL_TEXTURE_2D, dstColorTexture); } } } @@ -1435,28 +2640,30 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) ? desc.combinedShaderFeatures : batch.shaderFeatures; gpu::ShaderMiscFlags shaderMiscFlags = batch.shaderMiscFlags; - if (m_plsImpl != nullptr) + if (desc.interlockMode != gpu::InterlockMode::msaa) { + assert(m_plsImpl != nullptr); shaderMiscFlags |= m_plsImpl->shaderMiscFlags(desc, drawType); } - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && - (batch.drawContents & gpu::DrawContents::clockwiseFill)) - { - shaderMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill; - } - uint32_t fragmentShaderKey = gpu::ShaderUniqueKey(drawType, - shaderFeatures, - desc.interlockMode, - shaderMiscFlags); - const DrawProgram& drawProgram = m_drawPrograms - .try_emplace(fragmentShaderKey, - this, - drawType, - shaderFeatures, - desc.interlockMode, - shaderMiscFlags) - .first->second; - m_state->bindProgram(drawProgram.id()); + const DrawProgram* drawProgram = m_pipelineManager.tryGetPipeline( + { + .drawType = drawType, + .shaderFeatures = shaderFeatures, + .interlockMode = desc.interlockMode, + .shaderMiscFlags = shaderMiscFlags, +#ifdef WITH_RIVE_TOOLS + .synthesizedFailureType = desc.synthesizedFailureType, +#endif + }, + m_platformFeatures); + if (drawProgram == nullptr) + { + // There was an issue getting either the requested draw program or + // its ubershader counterpart so we cannot draw anything. + continue; + } + + m_state->bindProgram(drawProgram->id()); if (auto imageTextureGL = static_cast(batch.imageTexture)) @@ -1471,11 +2678,20 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) desc, m_platformFeatures, &pipelineState); - if (desc.interlockMode == gpu::InterlockMode::msaa) + if (desc.interlockMode != gpu::InterlockMode::msaa) + { + assert(m_plsImpl != nullptr); + m_plsImpl->applyPipelineStateOverrides(batch, + desc, + m_platformFeatures, + &pipelineState); + } + else { // Set up the next clipRect. bool needsClipPlanes = - (shaderFeatures & gpu::ShaderFeatures::ENABLE_CLIP_RECT); + enums::is_flag_set(shaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIP_RECT); if (needsClipPlanes != clipPlanesEnabled) { auto toggleEnableOrDisable = @@ -1487,41 +2703,40 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) clipPlanesEnabled = needsClipPlanes; } } - else if (desc.interlockMode == gpu::InterlockMode::atomics) - { - if (!desc.atomicFixedFunctionColorOutput && - drawType != gpu::DrawType::atomicResolve) - { - // When rendering to an offscreen texture in atomic mode, GL - // leaves the target framebuffer bound the whole time, but - // disables color writes until it's time to resolve. - pipelineState.colorWriteEnabled = false; - } - } m_state->setPipelineState(pipelineState); - if (batch.barriers & - (BarrierFlags::plsAtomic | BarrierFlags::plsAtomicPreResolve)) + if (enums::any_flag_set(batch.barriers, + BarrierFlags::plsAtomic | + BarrierFlags::plsAtomicPreResolve)) { assert(desc.interlockMode == gpu::InterlockMode::atomics); m_plsImpl->barrier(desc); } - else if (batch.barriers & BarrierFlags::dstColorTexture) + else if (enums::is_flag_set(batch.barriers, BarrierFlags::dstBlend)) { - // Read back the framebuffer where we need a dstColor for blending. - assert(desc.interlockMode == gpu::InterlockMode::msaa); - assert(batch.dstReadList != nullptr); - renderTarget->bindInternalFramebuffer( - GL_DRAW_FRAMEBUFFER, - RenderTargetGL::DrawBufferMask::color); - for (const Draw* draw = batch.dstReadList; draw != nullptr; - draw = draw->nextDstRead()) + assert(!m_capabilities.KHR_blend_equation_advanced_coherent); + if (m_capabilities.KHR_blend_equation_advanced) + { + glBlendBarrierKHR(); + } + else { - assert(draw->blendMode() != BlendMode::srcOver); - glutils::BlitFramebuffer(draw->pixelBounds(), - renderTarget->height()); + // Read back the framebuffer where we need a dstColor for + // blending. + assert(desc.interlockMode == gpu::InterlockMode::msaa); + assert(batch.dstReadList != nullptr); + renderTarget->bindDstColorFramebuffer(GL_DRAW_FRAMEBUFFER); + for (const Draw* draw = batch.dstReadList; draw != nullptr; + draw = draw->nextDstRead()) + { + assert(draw->blendMode() != BlendMode::srcOver); + glutils::BlitFramebuffer( + desc.renderTargetUpdateBounds.intersect( + draw->pixelBounds()), + renderTarget->height()); + } + renderTarget->bindMSAAFramebuffer(this, desc.msaaSampleCount); } - renderTarget->bindMSAAFramebuffer(this, desc.msaaSampleCount); } switch (drawType) @@ -1548,11 +2763,12 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) gpu::PatchBaseIndex(drawType), batch.elementCount, batch.baseElement, - drawProgram.baseInstanceUniformLocation()); + drawProgram->baseInstanceUniformLocation(), + &flushInjector); break; } - case gpu::DrawType::msaaStencilClipReset: + case gpu::DrawType::clipReset: { m_state->bindVAO(m_trianglesVAO); glDrawArrays(GL_TRIANGLES, @@ -1645,7 +2861,7 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) break; } - case gpu::DrawType::atomicResolve: + case gpu::DrawType::renderPassResolve: { assert(desc.interlockMode == gpu::InterlockMode::atomics); assert(m_plsImpl->rasterOrderingKnownDisabled()); @@ -1654,7 +2870,7 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) break; } - case gpu::DrawType::atomicInitialize: + case gpu::DrawType::renderPassInitialize: { RIVE_UNREACHABLE(); } @@ -1675,6 +2891,7 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) RenderTargetGL::MSAAResolveAction::framebufferBlit) { renderTarget->bindDestinationFramebuffer(GL_DRAW_FRAMEBUFFER); + m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); glutils::BlitFramebuffer(desc.renderTargetUpdateBounds, renderTarget->height(), GL_COLOR_BUFFER_BIT); @@ -1685,8 +2902,8 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) msaaDepthStencilColor.data() + 2); } - if ((desc.combinedShaderFeatures & - gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) && + if (enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) && m_capabilities.KHR_blend_equation_advanced_coherent) { glDisable(GL_BLEND_ADVANCED_COHERENT_KHR); @@ -1707,12 +2924,33 @@ void RenderContextGLImpl::flush(const FlushDescriptor& desc) } #endif - if (m_capabilities.isAdreno) + // Various Android vendors experience synchronization issues with multiple + // flushes per frame if we don't call glFlush in between. + glFlush(); + +#ifndef RIVE_WEBGL + // ARM Mali-G78 also needs a memory barrier sometimes to ensure a resolve of + // EXT_multisampled_render_to_texture. (Note that the spec says these + // resolves should all be implicit and automatic.) + // + // ALSO NOTE: We only do this barrier on Mali because the barrier actually + // introduces corruption on Xiaomi Redmi Note 8 (Qualcomm Adreno 610). + if (m_capabilities.isMali && m_capabilities.isGLES && + m_capabilities.isContextVersionAtLeast(3, 1)) { - // Qualcomm experiences synchronization issues with multiple flushes per - // frame if we don't call glFlush in between. - glFlush(); + glMemoryBarrier(GL_ALL_BARRIER_BITS); } +#endif + +#ifdef RIVE_CANVAS + // Imported canvas mirror sync. If the render target we just flushed + // is a Rive 2D RenderCanvas that some Ore consumer has imported as + // a sampled texture, run a Y-flip blit into the consumer's mirror + // texture now (while GL state is clean). The lookup is an O(1) hash + // miss for non-canvas targets and for canvas targets without active + // consumers — pure pay-for-what-you-use. + blitMirrorIfRegistered(renderTarget->renderTexture()); +#endif } void RenderContextGLImpl::drawIndexedInstancedNoInstancedAttribs( @@ -1721,19 +2959,19 @@ void RenderContextGLImpl::drawIndexedInstancedNoInstancedAttribs( uint32_t baseIndex, uint32_t instanceCount, uint32_t baseInstance, - GLint baseInstanceUniformLocation) + GLint baseInstanceUniformLocation, + GLFlushInjector* flushInjector) { assert(m_capabilities.ANGLE_base_vertex_base_instance_shader_builtin == (baseInstanceUniformLocation < 0)); const void* indexOffset = reinterpret_cast(baseIndex * sizeof(uint16_t)); - for (uint32_t endInstance = baseInstance + instanceCount; - baseInstance < endInstance;) - + for (auto [chunkInstanceCount, chunkBaseInstance] : + InstanceChunker(instanceCount, + baseInstance, + m_capabilities.maxSupportedInstancesPerFlush)) { - uint32_t subInstanceCount = - std::min(endInstance - baseInstance, - m_capabilities.maxSupportedInstancesPerDrawCommand); + flushInjector->flushBeforeInstancedDrawIfNeeded(chunkInstanceCount); #ifndef RIVE_WEBGL if (m_capabilities.ANGLE_base_vertex_base_instance_shader_builtin) { @@ -1741,20 +2979,19 @@ void RenderContextGLImpl::drawIndexedInstancedNoInstancedAttribs( indexCount, GL_UNSIGNED_SHORT, indexOffset, - subInstanceCount, - baseInstance); + chunkInstanceCount, + chunkBaseInstance); } else #endif { - glUniform1i(baseInstanceUniformLocation, baseInstance); + glUniform1i(baseInstanceUniformLocation, chunkBaseInstance); glDrawElementsInstanced(primitiveTopology, indexCount, GL_UNSIGNED_SHORT, indexOffset, - subInstanceCount); + chunkInstanceCount); } - baseInstance += subInstanceCount; } } @@ -1765,24 +3002,20 @@ void RenderContextGLImpl::blitTextureToFramebufferAsDraw( { if (m_blitAsDrawProgram == 0) { - // Define "USE_TEXEL_FETCH_WITH_FRAG_COORD" so the shader uses - // texelFetch() on the source texture instead of sampling it. This way - // we don't have to configure the texture's sampling parameters, and - // since textureID potentially refers to an external texture, it would - // be very messy to try and change its sampling params. - const char* blitDefines[] = {GLSL_USE_TEXEL_FETCH_WITH_FRAG_COORD}; const char* blitSources[] = {glsl::constants, + glsl::flush_uniforms, + glsl::common, glsl::blit_texture_as_draw}; m_blitAsDrawProgram = glutils::Program(); m_blitAsDrawProgram.compileAndAttachShader(GL_VERTEX_SHADER, - blitDefines, - std::size(blitDefines), + nullptr, + 0, blitSources, std::size(blitSources), m_capabilities); m_blitAsDrawProgram.compileAndAttachShader(GL_FRAGMENT_SHADER, - blitDefines, - std::size(blitDefines), + nullptr, + 0, blitSources, std::size(blitSources), m_capabilities); @@ -1792,58 +3025,145 @@ void RenderContextGLImpl::blitTextureToFramebufferAsDraw( } m_state->setPipelineState(gpu::COLOR_ONLY_PIPELINE_STATE); + m_state->setScissor(bounds, renderTargetHeight); m_state->bindProgram(m_blitAsDrawProgram); m_state->bindVAO(m_emptyVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID); - glEnable(GL_SCISSOR_TEST); - glScissor(bounds.left, - renderTargetHeight - bounds.bottom, - bounds.width(), - bounds.height()); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisable(GL_SCISSOR_TEST); } +#ifdef WITH_RIVE_TOOLS +RenderContextGLImpl::AtlasRenderType RenderContextGLImpl:: + testingOnly_resetAtlasDesiredRenderType( + RenderContext* owningRenderContext, + AtlasRenderType atlasDesiredRenderType) +{ + owningRenderContext->releaseResources(); + // Should be cleared by releaseResources(). + assert(m_atlasRenderTexture == 0); + assert(m_atlasTexture == 0); + assert(m_atlasRenderFBO == 0); + assert(m_atlasResolveFBO == 0); + + // Now release the atlas pipelines so they can be recompiled for the new + // AtlasRenderType. + m_atlasVertexShader = {}; + m_atlasFillProgram = {}; + m_atlasStrokeProgram = {}; + m_atlasResolveVertexShader = {}; + m_atlasClearProgram = glutils::Program::Zero(); + m_atlasResolveProgram = glutils::Program::Zero(); + + // ...And release all the DrawShaders in case any need to be recompiled for + // sampling a different AtlasRenderType. + m_pipelineManager.clearCache(); + + return std::exchange( + m_atlasRenderType, + select_atlas_render_type(m_capabilities, atlasDesiredRenderType)); +} + +bool RenderContextGLImpl::testingOnly_setBlendAdvancedCoherentKHRSupported( + bool supported) +{ + bool wasSupported = m_capabilities.KHR_blend_equation_advanced_coherent; + assert(wasSupported == m_platformFeatures.supportsBlendAdvancedCoherentKHR); + m_capabilities.KHR_blend_equation_advanced_coherent = supported; + m_platformFeatures.supportsBlendAdvancedCoherentKHR = supported; + + // Clear the shader cache since these are built with hard expectations about + // m_capabilities/m_platformFeatures. + m_pipelineManager.clearCache(); + + return wasSupported; +} + +bool RenderContextGLImpl::testingOnly_setBlendAdvancedKHRSupported( + bool supported) +{ + bool wasSupported = m_capabilities.KHR_blend_equation_advanced; + assert(wasSupported == m_platformFeatures.supportsBlendAdvancedKHR); + m_capabilities.KHR_blend_equation_advanced = supported; + m_platformFeatures.supportsBlendAdvancedKHR = supported; + + // Clear the shader cache since these are built with hard expectations about + // m_capabilities/m_platformFeatures. + m_pipelineManager.clearCache(); + + return wasSupported; +} +#endif + +#ifdef _MSC_VER +#define SSCANF sscanf_s +#else +#define SSCANF sscanf +#endif + std::unique_ptr RenderContextGLImpl::MakeContext( const ContextOptions& contextOptions) { - GLCapabilities capabilities{}; - const char* glVersionStr = (const char*)glGetString(GL_VERSION); + + GLenum rendererToken = GL_RENDERER; #ifdef RIVE_WEBGL - capabilities.isGLES = true; -#else - capabilities.isGLES = strstr(glVersionStr, "OpenGL ES") != NULL; -#endif - if (capabilities.isGLES) + if (emscripten_webgl_enable_extension( + emscripten_webgl_get_current_context(), + "WEBGL_debug_renderer_info")) { -#ifdef RIVE_WEBGL - capabilities.isANGLEOrWebGL = true; -#else - capabilities.isANGLEOrWebGL = strstr(glVersionStr, "ANGLE") != nullptr; + rendererToken = GL_UNMASKED_RENDERER_WEBGL; + } #endif -#ifdef _MSC_VER - sscanf_s( + const char* rendererString = + reinterpret_cast(glGetString(rendererToken)); + + GLCapabilities capabilities{}; +#ifdef RIVE_WEBGL + capabilities.isGLES = true; + // If GL_UNMASKED_RENDERER_WEBGL says "ANGLE", that means we are running on + // an ANGLE system driver. e.g.: + // + // WebGL (probably ANGLE) -> System OpenGL ES (also ANGLE) -> Vulkan + // + capabilities.isANGLESystemDriver = + strstr(rendererString, "ANGLE") != nullptr; #else - sscanf( + capabilities.isGLES = strstr(glVersionStr, "OpenGL ES") != nullptr; + capabilities.isANGLESystemDriver = + strstr(glVersionStr, "ANGLE") != nullptr || + strstr(rendererString, "ANGLE") != nullptr; #endif - glVersionStr, - "OpenGL ES %d.%d", - &capabilities.contextVersionMajor, - &capabilities.contextVersionMinor); + capabilities.isAdreno = strstr(rendererString, "Adreno"); + capabilities.isMali = strstr(rendererString, "Mali"); + capabilities.isPowerVR = strstr(rendererString, "PowerVR"); + + if (!capabilities.isGLES) + { + SSCANF(glVersionStr, + "%u.%u", + &capabilities.contextVersionMajor, + &capabilities.contextVersionMinor); + capabilities.vendorDriverVersionMajor = 0; + capabilities.vendorDriverVersionMinor = 0; + } + else if (capabilities.isPowerVR) + { + SSCANF(glVersionStr, + "OpenGL ES %u.%u build %u.%u@", + &capabilities.contextVersionMajor, + &capabilities.contextVersionMinor, + &capabilities.vendorDriverVersionMajor, + &capabilities.vendorDriverVersionMinor); } else { -#ifdef _MSC_VER - sscanf_s( -#else - sscanf( -#endif - glVersionStr, - "%d.%d", - &capabilities.contextVersionMajor, - &capabilities.contextVersionMinor); + SSCANF(glVersionStr, + "OpenGL ES %u.%u", + &capabilities.contextVersionMajor, + &capabilities.contextVersionMinor); + capabilities.vendorDriverVersionMajor = 0; + capabilities.vendorDriverVersionMinor = 0; } #ifdef RIVE_DESKTOP_GL assert(capabilities.contextVersionMajor == GLAD_GL_version_major); @@ -1851,6 +3171,12 @@ std::unique_ptr RenderContextGLImpl::MakeContext( assert(capabilities.isGLES == static_cast(GLAD_GL_version_es)); #endif + if (!capabilities.isAdreno || + !sscanf(rendererString, "Adreno (TM) %d", &capabilities.adrenoSeries)) + { + capabilities.adrenoSeries = 0; + } + if (capabilities.isGLES) { if (!capabilities.isContextVersionAtLeast(3, 0)) @@ -1876,21 +3202,8 @@ std::unique_ptr RenderContextGLImpl::MakeContext( } } - GLenum rendererToken = GL_RENDERER; -#ifdef RIVE_WEBGL - if (emscripten_webgl_enable_extension( - emscripten_webgl_get_current_context(), - "WEBGL_debug_renderer_info")) - { - rendererToken = GL_UNMASKED_RENDERER_WEBGL; - } -#endif - const char* rendererString = - reinterpret_cast(glGetString(rendererToken)); - capabilities.isAdreno = strstr(rendererString, "Adreno"); - capabilities.isMali = strstr(rendererString, "Mali"); - capabilities.isPowerVR = strstr(rendererString, "PowerVR"); - if (capabilities.isMali || capabilities.isPowerVR) + if (capabilities.isMali || capabilities.isPowerVR || + (capabilities.isAdreno && capabilities.adrenoSeries < 600)) { // We have observed crashes on Mali-G71 when issuing instanced draws // with somewhere between 2^15 and 2^16 instances. @@ -1898,23 +3211,33 @@ std::unique_ptr RenderContextGLImpl::MakeContext( // Skia also reports crashes on PowerVR when drawing somewhere between // 2^14 and 2^15 instances. // - // Limit the maximum number of instances we issue per-draw-call on these - // devices to a safe value, far below the observed crash thresholds. - capabilities.maxSupportedInstancesPerDrawCommand = 999; + // We have observed Adreno 308 crash when drawing too many instances + // spread across any number of draw calls. Breaking them up with glFlush + // appears to fix the crashes. + // + // Limit the maximum number of instances we issue per flush on these + // devices, splitting up draw calls if needed. + capabilities.maxSupportedInstancesPerFlush = (1u << 13) - 1u; } else { - capabilities.maxSupportedInstancesPerDrawCommand = ~0u; + capabilities.maxSupportedInstancesPerFlush = ~0u; } // Our baseline feature set is GLES 3.0. Capabilities from newer context // versions are reported as extensions. if (capabilities.isGLES) { + // ETC2 is mandatory in GLES 3.0+. + capabilities.supportsETC2 = true; if (capabilities.isContextVersionAtLeast(3, 1)) { capabilities.ARB_shader_storage_buffer_object = true; } + if (capabilities.isContextVersionAtLeast(3, 2)) + { + capabilities.OES_shader_image_atomic = true; + } } else { @@ -1943,12 +3266,16 @@ std::unique_ptr RenderContextGLImpl::MakeContext( } else if (strcmp(ext, "GL_ANGLE_shader_pixel_local_storage") == 0) { +#ifndef RIVE_ANDROID capabilities.ANGLE_shader_pixel_local_storage = true; +#endif } else if (strcmp(ext, "GL_ANGLE_shader_pixel_local_storage_coherent") == 0) { +#ifndef RIVE_ANDROID capabilities.ANGLE_shader_pixel_local_storage_coherent = true; +#endif } else if (strcmp(ext, "GL_ANGLE_provoking_vertex") == 0) { @@ -1974,6 +3301,10 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { capabilities.ARB_shader_storage_buffer_object = true; } + else if (strcmp(ext, "GL_OES_shader_image_atomic") == 0) + { + capabilities.OES_shader_image_atomic = true; + } else if (strcmp(ext, "GL_KHR_blend_equation_advanced") == 0) { capabilities.KHR_blend_equation_advanced = true; @@ -1982,32 +3313,23 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { capabilities.KHR_blend_equation_advanced_coherent = true; } + else if (strcmp(ext, "GL_KHR_parallel_shader_compile") == 0) + { + capabilities.KHR_parallel_shader_compile = true; + } else if (strcmp(ext, "GL_EXT_base_instance") == 0) { capabilities.EXT_base_instance = true; } -#ifdef RIVE_ANDROID - // Don't use EXT_clip_cull_distance if we're on ANGLE. Galaxy S22 - // (OpenGL Samsung Electronics Co., Ltd.; - // ANGLE (Samsung Xclipse 920) on Vulkan 1.1.179; - // OpenGL ES 3.2 ANGLE git hash: c7c78c41d520) advertises support for - // this extension but then doesn't support gl_ClipDistance in the - // shader. Only use clip planes on ANGLE if ANGLE_clip_cull_distance is - // supported. - else if (!capabilities.isANGLEOrWebGL && - strcmp(ext, "GL_EXT_clip_cull_distance") == 0) + else if (strcmp(ext, "GL_EXT_clip_cull_distance") == 0 || + strcmp(ext, "GL_ANGLE_clip_cull_distance") == 0) { capabilities.EXT_clip_cull_distance = true; } -#endif else if (strcmp(ext, "GL_EXT_multisampled_render_to_texture") == 0) { capabilities.EXT_multisampled_render_to_texture = true; } - else if (strcmp(ext, "GL_ANGLE_clip_cull_distance") == 0) - { - capabilities.EXT_clip_cull_distance = true; - } else if (strcmp(ext, "GL_INTEL_fragment_shader_ordering") == 0) { capabilities.INTEL_fragment_shader_ordering = true; @@ -2016,6 +3338,14 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { capabilities.EXT_color_buffer_half_float = true; } + else if (strcmp(ext, "GL_OES_texture_half_float_linear") == 0) + { + capabilities.OES_texture_half_float_linear = true; + } + else if (strcmp(ext, "GL_EXT_color_buffer_float") == 0) + { + capabilities.EXT_color_buffer_float = true; + } else if (strcmp(ext, "GL_EXT_float_blend") == 0) { capabilities.EXT_float_blend = true; @@ -2023,6 +3353,7 @@ std::unique_ptr RenderContextGLImpl::MakeContext( else if (strcmp(ext, "GL_ARB_color_buffer_float") == 0) { capabilities.EXT_color_buffer_half_float = true; + capabilities.EXT_color_buffer_float = true; capabilities.EXT_float_blend = true; } else if (strcmp(ext, "GL_EXT_shader_framebuffer_fetch") == 0) @@ -2033,13 +3364,56 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { capabilities.EXT_shader_pixel_local_storage = true; } + else if (strcmp(ext, "GL_EXT_shader_pixel_local_storage2") == 0) + { + capabilities.EXT_shader_pixel_local_storage2 = true; + } else if (strcmp(ext, "GL_QCOM_shader_framebuffer_fetch_noncoherent") == 0) { capabilities.QCOM_shader_framebuffer_fetch_noncoherent = true; } + else if (strcmp(ext, "GL_EXT_texture_compression_s3tc") == 0) + { + capabilities.EXT_texture_compression_s3tc = true; + } + else if (strcmp(ext, "GL_EXT_texture_compression_bptc") == 0 || + strcmp(ext, "GL_ARB_texture_compression_bptc") == 0) + { + capabilities.EXT_texture_compression_bptc = true; + } + else if (strcmp(ext, "GL_KHR_texture_compression_astc_ldr") == 0) + { + capabilities.KHR_texture_compression_astc_ldr = true; + } + else if (strcmp(ext, "GL_ARB_ES3_compatibility") == 0) + { + // Desktop GL exposes ETC2 via this extension. + capabilities.supportsETC2 = true; + } + } + +#ifdef RIVE_DESKTOP_GL + if (GLAD_GL_ANGLE_base_vertex_base_instance_shader_builtin) + { + capabilities.ANGLE_base_vertex_base_instance_shader_builtin = true; + } + if (GLAD_GL_ANGLE_polygon_mode) + { + capabilities.ANGLE_polygon_mode = true; + } + if (GLAD_GL_EXT_base_instance) + { + capabilities.EXT_base_instance = true; } +#endif + + // OES_texture_half_float_linear is core functionality in ES3. We only treat + // it as an extension because it's gated in WebGL2. + capabilities.OES_texture_half_float_linear = true; + #else // !RIVE_WEBGL -> RIVE_WEBGL + if (webgl_enable_WEBGL_shader_pixel_local_storage_coherent()) { capabilities.ANGLE_shader_pixel_local_storage = true; @@ -2063,29 +3437,47 @@ std::unique_ptr RenderContextGLImpl::MakeContext( } if (emscripten_webgl_enable_extension( emscripten_webgl_get_current_context(), - "EXT_color_buffer_float") && - emscripten_webgl_enable_extension( + "OES_texture_half_float_linear")) + { + capabilities.OES_texture_half_float_linear = true; + } + if (emscripten_webgl_enable_extension( + emscripten_webgl_get_current_context(), + "EXT_color_buffer_float")) + { + capabilities.EXT_color_buffer_float = true; + } + if (emscripten_webgl_enable_extension( emscripten_webgl_get_current_context(), "EXT_float_blend")) { capabilities.EXT_float_blend = true; } -#endif // RIVE_WEBGL - -#ifdef RIVE_DESKTOP_GL - if (GLAD_GL_ANGLE_base_vertex_base_instance_shader_builtin) + if (emscripten_webgl_enable_extension( + emscripten_webgl_get_current_context(), + "KHR_parallel_shader_compile")) { - capabilities.ANGLE_base_vertex_base_instance_shader_builtin = true; + capabilities.KHR_parallel_shader_compile = true; } - if (GLAD_GL_ANGLE_polygon_mode) + if (emscripten_webgl_enable_extension( + emscripten_webgl_get_current_context(), + "WEBGL_compressed_texture_s3tc")) { - capabilities.ANGLE_polygon_mode = true; + capabilities.EXT_texture_compression_s3tc = true; } - if (GLAD_GL_EXT_base_instance) + if (emscripten_webgl_enable_extension( + emscripten_webgl_get_current_context(), + "EXT_texture_compression_bptc")) { - capabilities.EXT_base_instance = true; + capabilities.EXT_texture_compression_bptc = true; } -#endif + if (emscripten_webgl_enable_extension( + emscripten_webgl_get_current_context(), + "WEBGL_compressed_texture_astc")) + { + capabilities.KHR_texture_compression_astc_ldr = true; + } +#endif // RIVE_WEBGL if (capabilities.ARB_shader_storage_buffer_object) { @@ -2100,49 +3492,96 @@ std::unique_ptr RenderContextGLImpl::MakeContext( } } - if (capabilities.ANGLE_shader_pixel_local_storage || - capabilities.ANGLE_shader_pixel_local_storage_coherent) + if (capabilities.OES_shader_image_atomic) { - // ANGLE_shader_pixel_local_storage enum values had a breaking change in - // early 2025. Disable the extension if we can't verify that we're - // running on the latest spec. - if (!glutils::validate_pixel_local_storage_angle()) + if (capabilities.isMali || capabilities.isPowerVR || + (capabilities.isAdreno && + strstr(rendererString, "Adreno (TM) 640") == nullptr)) { - fprintf(stderr, - "WARNING: detected an old version of " - "ANGLE_shader_pixel_local_storage. Disabling the " - "extension. Please update your drivers.\n"); - capabilities.ANGLE_shader_pixel_local_storage = - capabilities.ANGLE_shader_pixel_local_storage_coherent = false; + // Don't use image atomics for feathering on Adreno, Mali, or + // PowerVR. On Adreno (specifically 660 & 642L) and PowerVR they + // sometimes just don't render, and on Mali they lead to a failure + // that says: + // + // Error:glDrawElementsInstanced::failed to allocate CPU memory + // + // NOTE: We allow Adreno 640 to use atomics because it works + // reliably on our CI and gives us coverage of this codepath for ES. + // + // Realistically these vendors have better ways to render the + // feather atlas that they will use in real lifeanyway, namely, + // EXT_float_blend, EXT_color_buffer_half_float, + // EXT_shader_framebuffer_fetch, and/or + // EXT_shader_pixel_local_storage. + // + // It's possible we have some barriers wrong, but a fallback this + // deep isn't a priority right now on GL. + capabilities.OES_shader_image_atomic = false; } } - if (contextOptions.disableFragmentShaderInterlock) + if (capabilities.ANGLE_base_vertex_base_instance_shader_builtin) { - // Disable the extensions we don't want to use internally. - capabilities.ARB_fragment_shader_interlock = false; - capabilities.INTEL_fragment_shader_ordering = false; + if (capabilities.isANGLESystemDriver) + { + // Disable ANGLE_base_vertex_base_instance_shader_builtin on ANGLE. + // The extension has started crashing. + // (Meaning, now we only use it when we're Desktop GL and pretending + // we have ANGLE_base_vertex_base_instance_shader_builtin, but + // actually just have the functionality by default because it's part + // of Desktop GL.) + capabilities.ANGLE_base_vertex_base_instance_shader_builtin = false; + } + } + + if (capabilities.EXT_clip_cull_distance) + { + if (capabilities.isANGLESystemDriver) + { + // Don't use EXT_clip_cull_distance or ANGLE_clip_cull_distance if + // our system GL driver is ANGLE. Various Galaxy devices using ANGLE + // have bugs with these extensions. + capabilities.EXT_clip_cull_distance = false; + } } - if (strstr(rendererString, "Metal") != nullptr || - strstr(rendererString, "Direct3D") != nullptr) + if (capabilities.EXT_multisampled_render_to_texture) { - // Disable ANGLE_base_vertex_base_instance_shader_builtin on ANGLE/D3D - // and ANGLE/Metal. - // The extension is polyfilled on D3D anyway, and on Metal it crashes. - capabilities.ANGLE_base_vertex_base_instance_shader_builtin = false; + if (strstr(rendererString, "Direct3D") != nullptr) + { + // Our use of EXT_multisampled_render_to_texture causes a segfault + // in the Microsoft WARP (software) renderer. Just don't use this + // extension on D3D since it's polyfilled anyway. + capabilities.EXT_multisampled_render_to_texture = false; + } + if (capabilities.isPowerVR && + !capabilities.isVendorDriverVersionAtLeast(1, 13)) + { + // PowerVR Rogue GE8300, OpenGL ES 3.2 build 1.10@5187610 and + // PowerVR Rogue GM9446; OpenGL ES 3.2 build 1.11@5425693 both have + // similar artifacts when using EXT_multisampled_render_to_texture. + // Block the extension before the earliest known good driver, which + // is 1.13. + capabilities.EXT_multisampled_render_to_texture = false; + } } - if (strstr(rendererString, "Direct3D") != nullptr) + if (contextOptions.disableFragmentShaderInterlock) { - // Our use of EXT_multisampled_render_to_texture causes a segfault in - // the Microsoft WARP (software) renderer. Just don't use this extension - // on D3D since it's polyfilled anyway. - capabilities.EXT_multisampled_render_to_texture = false; + // Disable the extensions we don't want to use internally. + capabilities.ARB_fragment_shader_interlock = false; + capabilities.INTEL_fragment_shader_ordering = false; } +#ifdef RIVE_ANDROID + // On Android we need to explicitly load the extension functions. This will + // additionally clear the capabilities flags for any extension that could + // not load. + LoadAndValidateGLESExtensions(&capabilities); +#endif + if (strstr(rendererString, "ANGLE Metal Renderer") != nullptr && - capabilities.EXT_float_blend) + capabilities.EXT_color_buffer_float) { capabilities.needsFloatingPointTessellationTexture = true; } @@ -2150,10 +3589,32 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { capabilities.needsFloatingPointTessellationTexture = false; } -#ifdef RIVE_ANDROID - // Android doesn't load extension functions for us. - LoadGLESExtensions(capabilities); -#endif + + if (capabilities.EXT_shader_pixel_local_storage2) + { + if (capabilities.isPowerVR && + !capabilities.isVendorDriverVersionAtLeast(1, 11)) + { + // PowerVR Rogue GE8300, OpenGL ES 3.2 build 1.10@5187610 has severe + // pixel local storage corruption issues with our renderer. Using + // some of the EXT_shader_pixel_local_storage2 API is an apparent + // workaround that comes with worse performance and other, less + // severe visual artifacts. + // Require this workaround before the earliest known good driver, + // which is 1.11. + capabilities.usePixelLocalStorage2AsWorkaround = true; + } + } + + if (capabilities.ANGLE_shader_pixel_local_storage) + { + if (strstr(rendererString, "Direct3D11") != nullptr) + { + // ANGLE_shader_pixel_local_storage is currently broken with + // GL_TEXTURE_2D_ARRAY on ANGLE's d3d11 renderer. + capabilities.avoidTexture2DArrayWithWebGLPLS = true; + } + } if (!contextOptions.disablePixelLocalStorage) { @@ -2162,9 +3623,17 @@ std::unique_ptr RenderContextGLImpl::MakeContext( (capabilities.ARM_shader_framebuffer_fetch || capabilities.EXT_shader_framebuffer_fetch)) { - return MakeContext(rendererString, - capabilities, - MakePLSImplEXTNative(capabilities)); + // Favor MSAA over pixel local storage on PowerVR due to various + // bugs in its driver, except on PowerVR pre-1.15, where MSAA + // doesn't work. + if (!capabilities.isPowerVR || + !capabilities.isVendorDriverVersionAtLeast(1, 15)) + { + return MakeContext(rendererString, + capabilities, + MakePLSImplEXTNative(capabilities), + contextOptions.shaderCompilationMode); + } } #else if (capabilities.ANGLE_shader_pixel_local_storage_coherent) @@ -2175,7 +3644,8 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { return MakeContext(rendererString, capabilities, - MakePLSImplWebGL()); + MakePLSImplWebGL(), + contextOptions.shaderCompilationMode); } } #endif @@ -2185,23 +3655,116 @@ std::unique_ptr RenderContextGLImpl::MakeContext( { return MakeContext(rendererString, capabilities, - MakePLSImplRWTexture()); + MakePLSImplRWTexture(), + contextOptions.shaderCompilationMode); } #endif } - return MakeContext(rendererString, capabilities, nullptr); + return MakeContext(rendererString, + capabilities, + nullptr, + contextOptions.shaderCompilationMode); +} + +RenderContextGLImpl::GLPipelineManager::GLPipelineManager( + ShaderCompilationMode mode, + RenderContextGLImpl* context) : + Super(mode), m_context(context) +{} + +std::unique_ptr RenderContextGLImpl:: + GLPipelineManager::createPipeline(PipelineCreateType createType, + uint32_t, // unused key + const PipelineProps& props, + const PlatformFeatures&) +{ + return std::make_unique(m_context, + createType, + props.drawType, + props.shaderFeatures, + props.interlockMode, + props.shaderMiscFlags +#ifdef WITH_RIVE_TOOLS + , + props.synthesizedFailureType +#endif + ); +} + +PipelineStatus RenderContextGLImpl::GLPipelineManager::getPipelineStatus( + const DrawProgram& state) const +{ + return state.status(); +} + +bool RenderContextGLImpl::GLPipelineManager::advanceCreation( + DrawProgram& pipelineState, + const PipelineProps& props) +{ + return pipelineState.advanceCreation(m_context, + PipelineCreateType::async, + props.drawType, + props.shaderFeatures, + props.interlockMode, + props.shaderMiscFlags); +} + +std::unique_ptr RenderContextGLImpl:: + GLPipelineManager::createVertexShader(DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode) +{ + return std::make_unique(m_context, + GL_VERTEX_SHADER, + drawType, + shaderFeatures, + interlockMode, + ShaderMiscFlags::none); +} + +std::unique_ptr RenderContextGLImpl:: + GLPipelineManager::createFragmentShader(DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags miscFlags) +{ + return std::make_unique(m_context, + GL_FRAGMENT_SHADER, + drawType, + shaderFeatures, + interlockMode, + miscFlags); } std::unique_ptr RenderContextGLImpl::MakeContext( const char* rendererString, GLCapabilities capabilities, - std::unique_ptr plsImpl) + std::unique_ptr plsImpl, + ShaderCompilationMode shaderCompilationMode) { auto renderContextImpl = std::unique_ptr( new RenderContextGLImpl(rendererString, capabilities, - std::move(plsImpl))); + std::move(plsImpl), + shaderCompilationMode)); return std::make_unique(std::move(renderContextImpl)); } } // namespace rive::gpu + +#if defined(ORE_BACKEND_GL) && defined(RIVE_CANVAS) +rive::rcp rive::getCanvasImportMirrorGL( + gpu::RenderContext* renderCtx, + gpu::Texture* sourceTex, + uint32_t width, + uint32_t height) +{ + if (renderCtx == nullptr || + !renderCtx->platformFeatures().framebufferBottomUp) + { + return nullptr; + } + auto* glImpl = renderCtx->static_impl_cast(); + return glImpl->getCanvasImportMirror(sourceTex, width, height); +} +#endif diff --git a/thirdparty/rive_renderer/source/gl/render_target_gl.cpp b/thirdparty/rive_renderer/source/gl/render_target_gl.cpp index 542d2b532..081945401 100644 --- a/thirdparty/rive_renderer/source/gl/render_target_gl.cpp +++ b/thirdparty/rive_renderer/source/gl/render_target_gl.cpp @@ -10,47 +10,39 @@ namespace rive::gpu { -TextureRenderTargetGL::~TextureRenderTargetGL() {} - -static glutils::Texture make_backing_texture(GLenum internalformat, - uint32_t width, - uint32_t height) +GLuint RenderTargetGL::dstColorTexture() { - glutils::Texture texture; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, width, height); - return texture; + if (m_dstColorTexture == 0) + { + m_dstColorTexture = glutils::Texture(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_dstColorTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width(), height()); + } + return m_dstColorTexture; } -void TextureRenderTargetGL::allocateInternalPLSTextures( - gpu::InterlockMode interlockMode) +void RenderTargetGL::bindDstColorFramebuffer(GLenum target) { - if (m_coverageTexture == 0) + if (m_dstColorFramebuffer == 0) { - m_coverageTexture = make_backing_texture(GL_R32UI, width(), height()); - m_framebufferInternalAttachmentsDirty = true; - m_framebufferInternalPLSBindingsDirty = true; - } - if (m_clipTexture == 0) - { - m_clipTexture = make_backing_texture(GL_R32UI, width(), height()); - m_framebufferInternalAttachmentsDirty = true; - m_framebufferInternalPLSBindingsDirty = true; + m_dstColorFramebuffer = glutils::Framebuffer(); + glBindFramebuffer(target, m_dstColorFramebuffer); + glFramebufferTexture2D(target, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + dstColorTexture(), + 0); } - if (interlockMode == InterlockMode::rasterOrdering && - m_scratchColorTexture == 0) + else { - m_scratchColorTexture = - make_backing_texture(GL_RGBA8, width(), height()); - m_framebufferInternalAttachmentsDirty = true; - m_framebufferInternalPLSBindingsDirty = true; + glBindFramebuffer(target, m_dstColorFramebuffer); } } -void TextureRenderTargetGL::bindInternalFramebuffer( - GLenum target, - DrawBufferMask drawBufferMask) +TextureRenderTargetGL::~TextureRenderTargetGL() {} + +void TextureRenderTargetGL::bindTextureFramebuffer(GLenum target) { if (m_framebufferID == 0) { @@ -58,27 +50,6 @@ void TextureRenderTargetGL::bindInternalFramebuffer( } glBindFramebuffer(target, m_framebufferID); - if (target != GL_READ_FRAMEBUFFER && - m_internalDrawBufferMask != drawBufferMask) - { - GLenum drawBufferList[4]; - for (int i = 0; i < 4; ++i) - { - drawBufferList[i] = - (drawBufferMask & static_cast(1 << i)) - ? GL_COLOR_ATTACHMENT0 + i - : GL_NONE; - static_assert((int)DrawBufferMask::color == 1 << COLOR_PLANE_IDX); - static_assert((int)DrawBufferMask::clip == 1 << CLIP_PLANE_IDX); - static_assert((int)DrawBufferMask::scratchColor == - 1 << SCRATCH_COLOR_PLANE_IDX); - static_assert((int)DrawBufferMask::coverage == - 1 << COVERAGE_PLANE_IDX); - } - glDrawBuffers(4, drawBufferList); - m_internalDrawBufferMask = drawBufferMask; - } - if (m_framebufferTargetAttachmentDirty) { glFramebufferTexture2D(target, @@ -88,26 +59,6 @@ void TextureRenderTargetGL::bindInternalFramebuffer( 0); m_framebufferTargetAttachmentDirty = false; } - - if (m_framebufferInternalAttachmentsDirty) - { - glFramebufferTexture2D(target, - GL_COLOR_ATTACHMENT0 + CLIP_PLANE_IDX, - GL_TEXTURE_2D, - m_clipTexture, - 0); - glFramebufferTexture2D(target, - GL_COLOR_ATTACHMENT0 + SCRATCH_COLOR_PLANE_IDX, - GL_TEXTURE_2D, - m_scratchColorTexture, - 0); - glFramebufferTexture2D(target, - GL_COLOR_ATTACHMENT0 + COVERAGE_PLANE_IDX, - GL_TEXTURE_2D, - m_coverageTexture, - 0); - m_framebufferInternalAttachmentsDirty = false; - } } void TextureRenderTargetGL::bindHeadlessFramebuffer( @@ -136,83 +87,42 @@ void TextureRenderTargetGL::bindHeadlessFramebuffer( } #ifdef GL_ANGLE_shader_pixel_local_storage - if (capabilities.ANGLE_shader_pixel_local_storage) + if (capabilities.ANGLE_shader_pixel_local_storage && + m_webglPLSBindingsDirty) { - if (m_framebufferTargetPLSBindingDirty) + glFramebufferTexturePixelLocalStorageANGLE(COLOR_PLANE_IDX, + m_externalTextureID, + 0, + 0, + GL_NONE); + glFramebufferTexturePixelLocalStorageANGLE(COVERAGE_PLANE_IDX, + m_webglPLSBackingR32UI, + 0, + 0, + GL_NONE); + if (!capabilities.avoidTexture2DArrayWithWebGLPLS) { - glFramebufferTexturePixelLocalStorageANGLE(COLOR_PLANE_IDX, - m_externalTextureID, + glFramebufferTexturePixelLocalStorageANGLE(CLIP_PLANE_IDX, + m_webglPLSBackingR32UI, 0, - 0); - m_framebufferTargetPLSBindingDirty = false; + 1, + GL_NONE); } - - if (m_framebufferInternalPLSBindingsDirty) + else { - glFramebufferTexturePixelLocalStorageANGLE(CLIP_PLANE_IDX, - m_clipTexture, - 0, - 0); - glFramebufferTexturePixelLocalStorageANGLE(SCRATCH_COLOR_PLANE_IDX, - m_scratchColorTexture, - 0, - 0); - glFramebufferTexturePixelLocalStorageANGLE(COVERAGE_PLANE_IDX, - m_coverageTexture, - 0, - 0); - m_framebufferInternalPLSBindingsDirty = false; + glFramebufferTexturePixelLocalStorageANGLE( + CLIP_PLANE_IDX, + m_webglPLSBackingR32UIFallback, + 0, + 0, + GL_NONE); } - } -#endif -} - -void TextureRenderTargetGL::bindAsImageTextures(DrawBufferMask drawBufferMask) -{ -#ifndef RIVE_WEBGL - if (drawBufferMask & DrawBufferMask::color) - { - assert(m_externalTextureID != 0); - glBindImageTexture(COLOR_PLANE_IDX, - m_externalTextureID, - 0, - GL_FALSE, - 0, - GL_READ_WRITE, - GL_RGBA8); - } - if (drawBufferMask & DrawBufferMask::clip) - { - assert(m_clipTexture != 0); - glBindImageTexture(CLIP_PLANE_IDX, - m_clipTexture, - 0, - GL_FALSE, - 0, - GL_READ_WRITE, - GL_R32UI); - } - if (drawBufferMask & DrawBufferMask::scratchColor) - { - assert(m_scratchColorTexture != 0); - glBindImageTexture(SCRATCH_COLOR_PLANE_IDX, - m_scratchColorTexture, - 0, - GL_FALSE, - 0, - GL_READ_WRITE, - GL_RGBA8); - } - if (drawBufferMask & DrawBufferMask::coverage) - { - assert(m_coverageTexture != 0); - glBindImageTexture(COVERAGE_PLANE_IDX, - m_coverageTexture, - 0, - GL_FALSE, - 0, - GL_READ_WRITE, - GL_R32UI); + glFramebufferTexturePixelLocalStorageANGLE(SCRATCH_COLOR_PLANE_IDX, + m_webglPLSBackingRGBA8, + 0, + 0, + GL_NONE); + m_webglPLSBindingsDirty = false; } #endif } @@ -316,11 +226,46 @@ RenderTargetGL::MSAAResolveAction TextureRenderTargetGL::bindMSAAFramebuffer( } } -void TextureRenderTargetGL::bindInternalDstTexture(GLenum activeTexture) +#ifdef GL_ANGLE_shader_pixel_local_storage +void TextureRenderTargetGL::allocateWebGLPLSBacking( + const GLCapabilities& capabilities) { - glActiveTexture(activeTexture); - glBindTexture(GL_TEXTURE_2D, m_externalTextureID); + if (m_webglPLSBackingR32UI == 0) + { + glActiveTexture(GL_TEXTURE0); + m_webglPLSBackingR32UI = glutils::Texture(); + if (!capabilities.avoidTexture2DArrayWithWebGLPLS) + { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_webglPLSBackingR32UI); + glTexStorage3D(GL_TEXTURE_2D_ARRAY, + 1, + GL_R32UI, + width(), + height(), + 2); + } + else + { + // ANGLE_shader_pixel_local_storage is currently broken with + // GL_TEXTURE_2D_ARRAY on ANGLE's d3d11 renderer. + m_webglPLSBackingR32UIFallback = glutils::Texture(); + glBindTexture(GL_TEXTURE_2D, m_webglPLSBackingR32UI); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width(), height()); + glBindTexture(GL_TEXTURE_2D, m_webglPLSBackingR32UIFallback); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, width(), height()); + } + m_webglPLSBindingsDirty = true; + } + if (m_webglPLSBackingRGBA8 == 0) + { + m_webglPLSBackingRGBA8 = glutils::Texture(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_webglPLSBackingRGBA8); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width(), height()); + m_webglPLSBindingsDirty = true; + } } +#endif FramebufferRenderTargetGL::~FramebufferRenderTargetGL() {} @@ -333,24 +278,24 @@ void FramebufferRenderTargetGL::allocateOffscreenTargetTexture() { if (m_offscreenTargetTexture == 0) { - m_offscreenTargetTexture = - make_backing_texture(GL_RGBA8, width(), height()); + m_offscreenTargetTexture = glutils::Texture(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_offscreenTargetTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width(), height()); m_textureRenderTarget.setTargetTexture(m_offscreenTargetTexture); } } -void FramebufferRenderTargetGL::allocateInternalPLSTextures( - gpu::InterlockMode interlockMode) +GLuint FramebufferRenderTargetGL::renderTexture() { - m_textureRenderTarget.allocateInternalPLSTextures(interlockMode); + allocateOffscreenTargetTexture(); + return m_textureRenderTarget.renderTexture(); } -void FramebufferRenderTargetGL::bindInternalFramebuffer( - GLenum target, - DrawBufferMask drawBufferMask) +void FramebufferRenderTargetGL::bindTextureFramebuffer(GLenum target) { - - m_textureRenderTarget.bindInternalFramebuffer(target, drawBufferMask); + allocateOffscreenTargetTexture(); + m_textureRenderTarget.bindTextureFramebuffer(target); } void FramebufferRenderTargetGL::bindHeadlessFramebuffer( @@ -359,12 +304,6 @@ void FramebufferRenderTargetGL::bindHeadlessFramebuffer( m_textureRenderTarget.bindHeadlessFramebuffer(capabilities); } -void FramebufferRenderTargetGL::bindAsImageTextures( - DrawBufferMask drawBufferMask) -{ - m_textureRenderTarget.bindAsImageTextures(drawBufferMask); -} - RenderTargetGL::MSAAResolveAction FramebufferRenderTargetGL:: bindMSAAFramebuffer(RenderContextGLImpl* renderContextImpl, int sampleCount, @@ -397,10 +336,10 @@ RenderTargetGL::MSAAResolveAction FramebufferRenderTargetGL:: // (NOTE: step 2 gets skipped when we have // EXT_multisampled_render_to_texture.) allocateOffscreenTargetTexture(); - m_textureRenderTarget.bindInternalFramebuffer( - GL_DRAW_FRAMEBUFFER, - DrawBufferMask::color); + m_textureRenderTarget.bindTextureFramebuffer(GL_DRAW_FRAMEBUFFER); bindDestinationFramebuffer(GL_READ_FRAMEBUFFER); + renderContextImpl->state()->setPipelineState( + gpu::COLOR_ONLY_PIPELINE_STATE); glutils::BlitFramebuffer( *preserveBounds, height()); // Step 1. @@ -424,9 +363,11 @@ RenderTargetGL::MSAAResolveAction FramebufferRenderTargetGL:: } } -void FramebufferRenderTargetGL::bindInternalDstTexture(GLenum activeTexture) +#ifdef GL_ANGLE_shader_pixel_local_storage +void FramebufferRenderTargetGL::allocateWebGLPLSBacking( + const GLCapabilities& capabilities) { - allocateOffscreenTargetTexture(); - m_textureRenderTarget.bindInternalDstTexture(activeTexture); + m_textureRenderTarget.allocateWebGLPLSBacking(capabilities); } +#endif } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/gpu.cpp b/thirdparty/rive_renderer/source/gpu.cpp index 5c8e7d76f..58987e511 100644 --- a/thirdparty/rive_renderer/source/gpu.cpp +++ b/thirdparty/rive_renderer/source/gpu.cpp @@ -2,15 +2,16 @@ * Copyright 2022 Rive */ +#include "shaders/constants.glsl" +#include "rive/math/bitwise.hpp" #include "rive/renderer/gpu.hpp" - +#include "rive/renderer/render_context.hpp" #include "rive/renderer/render_target.hpp" -#include "shaders/constants.glsl" #include "rive/renderer/texture.hpp" -#include "rive_render_paint.hpp" #include "gradient.hpp" +#include "rive_render_paint.hpp" -#include "generated/shaders/draw_path.exports.h" +#include "generated/shaders/draw_path.vert.exports.h" namespace rive::gpu { @@ -18,21 +19,306 @@ static_assert(kGradTextureWidth == GRAD_TEXTURE_WIDTH); static_assert(kTessTextureWidth == TESS_TEXTURE_WIDTH); static_assert(kTessTextureWidthLog2 == TESS_TEXTURE_WIDTH_LOG2); +static Span get_valid_draw_types(InterlockMode mode) +{ + switch (mode) + { + case InterlockMode::rasterOrdering: + { + static constexpr DrawType types[] = { + DrawType::midpointFanPatches, + DrawType::midpointFanCenterAAPatches, + DrawType::outerCurvePatches, + DrawType::interiorTriangulation, + DrawType::atlasBlit, + DrawType::imageMesh, + DrawType::renderPassResolve, + }; + return make_span(types); + } + + case InterlockMode::clockwise: + { + static constexpr DrawType types[] = { + DrawType::midpointFanPatches, + DrawType::midpointFanCenterAAPatches, + DrawType::outerCurvePatches, + DrawType::interiorTriangulation, + DrawType::atlasBlit, + DrawType::imageMesh, + }; + return make_span(types); + } + case InterlockMode::atomics: + { + static constexpr DrawType types[] = { + DrawType::midpointFanPatches, + DrawType::midpointFanCenterAAPatches, + DrawType::outerCurvePatches, + DrawType::interiorTriangulation, + DrawType::atlasBlit, + DrawType::imageRect, + DrawType::imageMesh, + DrawType::renderPassInitialize, + DrawType::renderPassResolve, + }; + return make_span(types); + } + case InterlockMode::clockwiseAtomic: + { + static constexpr DrawType types[] = { + DrawType::midpointFanPatches, + DrawType::midpointFanCenterAAPatches, + DrawType::outerCurvePatches, + DrawType::interiorTriangulation, + DrawType::atlasBlit, + DrawType::imageMesh, + DrawType::clipReset, + DrawType::renderPassInitialize, + }; + return make_span(types); + } + case InterlockMode::msaa: + { + static constexpr DrawType types[] = { + DrawType::atlasBlit, + DrawType::imageMesh, + DrawType::msaaStrokes, + DrawType::msaaMidpointFanBorrowedCoverage, + DrawType::msaaMidpointFans, + DrawType::msaaMidpointFanStencilReset, + DrawType::msaaMidpointFanPathsStencil, + DrawType::msaaMidpointFanPathsCover, + DrawType::msaaOuterCubics, + DrawType::clipReset, + DrawType::renderPassInitialize, + DrawType::renderPassResolve, + }; + return make_span(types); + } + } + + assert(false && "Unexpected interlock mode"); + return {}; +} + +static ShaderMiscFlags get_valid_shader_misc_flags(DrawType drawType, + InterlockMode mode) +{ + ShaderMiscFlags outFlags = ShaderMiscFlags::none; + + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + case DrawType::interiorTriangulation: + case DrawType::clipReset: + // Clockwise modes introduce borrowed coverage and dedicated clip + // draws for paths. + if (mode == InterlockMode::clockwise || + mode == InterlockMode::clockwiseAtomic) + { + if (drawType == DrawType::interiorTriangulation || + mode == InterlockMode::clockwiseAtomic) + { + outFlags |= ShaderMiscFlags::borrowedCoveragePass; + } + + // midpointFanCenterAAPatches is only used for feathers, and + // feathers are never clips. + if (drawType != DrawType::midpointFanCenterAAPatches) + { + outFlags |= ShaderMiscFlags::clipUpdateOnly; + if (mode == InterlockMode::clockwiseAtomic) + { + outFlags |= ShaderMiscFlags::nestedClipUpdateOnly; + } + } + } + break; + + case DrawType::renderPassInitialize: + if (mode == InterlockMode::atomics) + { + outFlags |= ShaderMiscFlags::storeColorClear | + ShaderMiscFlags::swizzleColorBGRAToRGBA; + } + break; + case DrawType::renderPassResolve: + if (mode == InterlockMode::atomics) + { + outFlags |= ShaderMiscFlags::coalescedResolveAndTransfer; + } + break; + + case DrawType::atlasBlit: + case DrawType::imageRect: + case DrawType::imageMesh: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + break; + } + + switch (mode) + { + case InterlockMode::atomics: + case InterlockMode::clockwise: + case InterlockMode::clockwiseAtomic: + case InterlockMode::msaa: + outFlags |= ShaderMiscFlags::fixedFunctionColorOutput; + break; + + case InterlockMode::rasterOrdering: + outFlags |= ShaderMiscFlags::clockwiseFill; + break; + } + + return outFlags; +} + +void ForEachUbershaderPermutation( + InterlockMode interlockMode, + const PlatformFeatures& platformFeatures, + const std::function& func) +{ + // RenderPassInitialize is only needed in these two specific scenarios, and + // should be skipped otherwise. + const bool allowRenderPassInitialize = + (interlockMode == InterlockMode::atomics && + platformFeatures.atomicPLSInitNeedsDraw) || + (interlockMode == InterlockMode::clockwiseAtomic && + platformFeatures + .clockwiseAtomicBorrowedCoverageBarrierNeedsRenderPassInit) || + (interlockMode == InterlockMode::msaa && + platformFeatures.msaaColorPreserveNeedsDraw); + + for (auto drawType : get_valid_draw_types(interlockMode)) + { + if (drawType == DrawType::renderPassInitialize && + !allowRenderPassInitialize) + { + continue; + } + + const auto allValidMiscFlags = + get_valid_shader_misc_flags(drawType, interlockMode); + + for (auto curMiscFlags : + math::iterate_bit_combinations_in_mask(allValidMiscFlags)) + { + // Filter out any invalid combinations of ShaderMiscFlags + switch (interlockMode) + { + case InterlockMode::atomics: + if (enums::is_flag_set( + curMiscFlags, + ShaderMiscFlags::coalescedResolveAndTransfer)) + { + if (enums::is_flag_set( + curMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) + { + continue; + } + } + break; + + case InterlockMode::clockwiseAtomic: + if (enums::is_flag_set( + curMiscFlags, + ShaderMiscFlags::borrowedCoveragePass)) + { + // Borrowed coverage clockwiseAtomic passes always set + // fixedFunctionColorOutput because they never read (or + // even write, for that matter) the color buffer. + if (!enums::is_flag_set( + curMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) + { + continue; + } + // Borrowed coverage clockwiseAtomic passes never update + // clip. + if (enums::any_flag_set( + curMiscFlags, + ShaderMiscFlags::clipUpdateOnly | + ShaderMiscFlags::nestedClipUpdateOnly)) + { + continue; + } + } + break; + + case InterlockMode::rasterOrdering: + case InterlockMode::clockwise: + case InterlockMode::msaa: + break; + } + + // Get the minimal set of ubershader features (with no optional + // flags) + const auto minUbershaderFeatures = + UbershaderFeaturesMaskFor(ShaderFeatures::NONE, + drawType, + interlockMode, + curMiscFlags, + platformFeatures); + + // Now find the ubershader that has *all* flags set + const auto maxUbershaderFeatures = UbershaderFeaturesMaskFor( + ShaderFeaturesMaskFor(drawType, interlockMode), + drawType, + interlockMode, + curMiscFlags, + platformFeatures); + + // Get the flags that still change ubershader behavior + const ShaderFeatures allOptionalUbershaderFeatures = + minUbershaderFeatures ^ maxUbershaderFeatures; + + // Now iterate the + for (auto curOptionalFeatures : + math::iterate_bit_combinations_in_mask( + allOptionalUbershaderFeatures)) + { + ShaderFeatures features = + curOptionalFeatures | minUbershaderFeatures; + + if (!func(drawType, features, curMiscFlags)) + { + // Function returned false to stop iterating. + return; + } + } + } + } +} + uint32_t ShaderUniqueKey(DrawType drawType, ShaderFeatures shaderFeatures, InterlockMode interlockMode, ShaderMiscFlags miscFlags) { - if (miscFlags & ShaderMiscFlags::coalescedResolveAndTransfer) + if (enums::is_flag_set(miscFlags, + ShaderMiscFlags::coalescedResolveAndTransfer)) { - assert(drawType == DrawType::atomicResolve); - assert(shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND); + assert(drawType == DrawType::renderPassResolve); + assert(enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_ADVANCED_BLEND)); assert(interlockMode == InterlockMode::atomics); } - if (miscFlags & (ShaderMiscFlags::storeColorClear | - ShaderMiscFlags::swizzleColorBGRAToRGBA)) + if (enums::any_flag_set(miscFlags, + ShaderMiscFlags::storeColorClear | + ShaderMiscFlags::swizzleColorBGRAToRGBA)) { - assert(drawType == DrawType::atomicInitialize); + assert(drawType == DrawType::renderPassInitialize); + assert(interlockMode == InterlockMode::atomics); } uint32_t drawTypeKey; switch (drawType) @@ -61,25 +347,32 @@ uint32_t ShaderUniqueKey(DrawType drawType, case DrawType::imageMesh: drawTypeKey = 4; break; - case DrawType::atomicInitialize: - assert(interlockMode == gpu::InterlockMode::atomics); + case DrawType::clipReset: + assert(interlockMode == InterlockMode::clockwiseAtomic || + interlockMode == InterlockMode::msaa); + drawTypeKey = 7; + break; + case DrawType::renderPassInitialize: + assert(interlockMode == InterlockMode::atomics || + interlockMode == InterlockMode::msaa || + interlockMode == InterlockMode::clockwiseAtomic); drawTypeKey = 5; break; - case DrawType::atomicResolve: - assert(interlockMode == gpu::InterlockMode::atomics); + case DrawType::renderPassResolve: + assert(interlockMode == InterlockMode::rasterOrdering || + interlockMode == InterlockMode::atomics || + interlockMode == InterlockMode::msaa); drawTypeKey = 6; break; - case DrawType::msaaStencilClipReset: - assert(interlockMode == gpu::InterlockMode::msaa); - drawTypeKey = 7; - break; } uint32_t key = static_cast(miscFlags); - assert(static_cast(interlockMode) < 1 << 2); - key = (key << 2) | static_cast(interlockMode); + assert(static_cast(interlockMode) < + 1 << INTERLOCK_MODE_BIT_COUNT); + key = (key << INTERLOCK_MODE_BIT_COUNT) | + static_cast(interlockMode); key = (key << kShaderFeatureCount) | - (shaderFeatures & ShaderFeaturesMaskFor(drawType, interlockMode)) - .bits(); + uint32_t(shaderFeatures & + ShaderFeaturesMaskFor(drawType, interlockMode)); assert(drawTypeKey < 1 << 3); key = (key << 3) | drawTypeKey; return key; @@ -105,6 +398,8 @@ const char* GetShaderFeatureGLSLName(ShaderFeatures feature) return GLSL_ENABLE_NESTED_CLIPPING; case ShaderFeatures::ENABLE_HSL_BLEND_MODES: return GLSL_ENABLE_HSL_BLEND_MODES; + case ShaderFeatures::ENABLE_DITHER: + return GLSL_ENABLE_DITHER; } RIVE_UNREACHABLE(); } @@ -485,8 +780,18 @@ FlushUniforms::FlushUniforms(const FlushDescriptor& flushDesc, : 2.f) / flushDesc.atlasContentHeight), m_coverageBufferPrefix(flushDesc.coverageBufferPrefix), + m_epsilonForPseudoMemoryBarrier(1e-9f), m_pathIDGranularity(platformFeatures.pathIDGranularity), m_vertexDiscardValue(std::numeric_limits::quiet_NaN()), + m_mipMapLODBias(MIP_MAP_LOD_BIAS), + m_maxPathId(flushDesc.pathCount), + m_ditherScale((flushDesc.ditherMode == DitherMode::none) ? 0.0f + : (1.0f / 256.0f)), + m_ditherBias(m_ditherScale * -0.5f), + // Negate dither when storing to RGB10, in order to get some more variation. + m_ditherConversionToRGB10((flushDesc.ditherMode == DitherMode::none) + ? 0.0f + : (-1.0f / 1024.0f) / m_ditherScale), m_wireframeEnabled(flushDesc.wireframe) {} @@ -567,11 +872,11 @@ void PaintData::set(DrawContents singleDrawContents, break; } } - if (singleDrawContents & gpu::DrawContents::nonZeroFill) + if (enums::is_flag_set(singleDrawContents, DrawContents::nonZeroFill)) { localParams |= PAINT_FLAG_NON_ZERO_FILL; } - else if (singleDrawContents & gpu::DrawContents::evenOddFill) + else if (enums::is_flag_set(singleDrawContents, DrawContents::evenOddFill)) { localParams |= PAINT_FLAG_EVEN_ODD_FILL; } @@ -589,7 +894,7 @@ void PaintAuxData::set(const Mat2D& viewMatrix, const Texture* imageTexture, const ClipRectInverseMatrix* clipRectInverseMatrix, const RenderTarget* renderTarget, - const gpu::PlatformFeatures& platformFeatures) + const PlatformFeatures& platformFeatures) { switch (paintType) { @@ -623,7 +928,8 @@ void PaintAuxData::set(const Mat2D& viewMatrix, // Instead of finding sqrt(maxScaleFactorPow2), just multiply // the log by .5. m_imageTextureLOD = - log2f(std::max(maxScaleFactorPow2, 1.f)) * .5f; + (log2f(std::max(maxScaleFactorPow2, 1.f)) * .5f) + + MIP_MAP_LOD_BIAS; } else { @@ -763,87 +1069,210 @@ float find_transformed_area(const AABB& bounds, const Mat2D& matrix) .5f; } -static void get_depth_state(const DrawBatch& batch, - const FlushDescriptor& flushDesc, - PipelineState* pipelineState) +DepthState get_depth_state(InterlockMode interlockMode, + DrawType drawType, + DrawContents drawContents) { - if (flushDesc.interlockMode != InterlockMode::msaa) + if (interlockMode != InterlockMode::msaa) { - pipelineState->depthTestEnabled = false; - pipelineState->depthWriteEnabled = false; - return; + return {.depthTestEnabled = false, .depthWriteEnabled = false}; } - switch (batch.drawType) + switch (drawType) { case DrawType::imageRect: case DrawType::imageMesh: case DrawType::atlasBlit: case DrawType::outerCurvePatches: - pipelineState->depthTestEnabled = true; - pipelineState->depthWriteEnabled = false; - break; - case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaStencilClipReset: - pipelineState->depthTestEnabled = true; - pipelineState->depthWriteEnabled = false; + case DrawType::clipReset: + return {.depthTestEnabled = true, .depthWriteEnabled = false}; break; case DrawType::msaaStrokes: case DrawType::msaaOuterCubics: - pipelineState->depthTestEnabled = true; - pipelineState->depthWriteEnabled = true; + return {.depthTestEnabled = true, .depthWriteEnabled = true}; break; case DrawType::msaaMidpointFans: case DrawType::msaaMidpointFanPathsCover: - pipelineState->depthTestEnabled = true; - pipelineState->depthWriteEnabled = - !(batch.drawContents & gpu::DrawContents::clipUpdate); + return { + .depthTestEnabled = true, + .depthWriteEnabled = + !enums::is_flag_set(drawContents, DrawContents::clipUpdate), + }; break; case DrawType::msaaMidpointFanStencilReset: - pipelineState->depthTestEnabled = true; - pipelineState->depthWriteEnabled = - !(batch.drawContents & (gpu::DrawContents::clockwiseFill | - gpu::DrawContents::clipUpdate)); + return { + .depthTestEnabled = true, + .depthWriteEnabled = enums::no_flags_set( + drawContents, + DrawContents::clockwiseFill | DrawContents::clipUpdate), + }; + + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: + return {.depthTestEnabled = false, .depthWriteEnabled = false}; + + case DrawType::interiorTriangulation: + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: break; + } + + RIVE_UNREACHABLE(); +} + +StencilInfo get_stencil_info(InterlockMode interlockMode, + DrawType drawType, + DrawContents drawContents) +{ + bool areDrawContentsValid = true; + if (interlockMode != InterlockMode::msaa) + { + // Only MSAA has any valid stencil types + return {StencilType::disabled, + DrawContents::none, + areDrawContentsValid}; + } + + switch (drawType) + { + case DrawType::imageRect: + case DrawType::imageMesh: + case DrawType::atlasBlit: + case DrawType::msaaStrokes: + case DrawType::msaaOuterCubics: + if (enums::is_flag_set(drawContents, DrawContents::activeClip)) + { + return { + StencilType::activeStencilClip, + DrawContents::activeClip, + areDrawContentsValid, + }; + } + else + { + return { + StencilType::disabled, + DrawContents::none, + areDrawContentsValid, + }; + } + + case DrawType::msaaMidpointFanBorrowedCoverage: + return { + StencilType::borrowedCoverage, + DrawContents::activeClip, + areDrawContentsValid, + }; + + case DrawType::msaaMidpointFans: + return { + StencilType::forwardClippedByBackward, + DrawContents::activeClip | DrawContents::clipUpdate, + areDrawContentsValid, + }; + + case DrawType::msaaMidpointFanStencilReset: + return { + StencilType::backwardTriangleCleanup, + DrawContents::clockwiseFill | DrawContents::activeClip | + DrawContents::clipUpdate, + areDrawContentsValid, + }; + + case DrawType::msaaMidpointFanPathsStencil: + areDrawContentsValid = + enums::is_flag_set(drawContents, DrawContents::evenOddFill) || + enums::all_flags_set(drawContents, kNestedClipUpdateMask); + return { + StencilType::stencilNestedOrEvenOdd, + DrawContents::activeClip | DrawContents::evenOddFill, + areDrawContentsValid, + }; + + case DrawType::msaaMidpointFanPathsCover: + areDrawContentsValid = + enums::is_flag_set(drawContents, DrawContents::evenOddFill); + return {StencilType::evenOddDrawAndReset, + DrawContents::clipUpdate, + areDrawContentsValid}; + + case DrawType::clipReset: + return { + ((drawContents & kNestedClipUpdateMask) == + kNestedClipUpdateMask) + ? StencilType::nestedClipReset + : StencilType::clipReset, + DrawContents::clockwiseFill, + areDrawContentsValid, + }; + + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: + return { + StencilType::disabled, + DrawContents::none, + areDrawContentsValid, + }; case DrawType::interiorTriangulation: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: - RIVE_UNREACHABLE(); + case DrawType::outerCurvePatches: + break; } + + RIVE_UNREACHABLE(); } -static void get_stencil_state(const DrawBatch& batch, - const FlushDescriptor& flushDesc, - PipelineState* pipelineState) +// Returns an 8-bit key that uniquely identifies the stencil settings. +static void get_stencil_settings(InterlockMode interlockMode, + DrawType drawType, + DrawContents drawContents, + PipelineState* pipelineState) { - if (flushDesc.interlockMode != InterlockMode::msaa) + if (interlockMode != InterlockMode::msaa) { pipelineState->stencilTestEnabled = false; pipelineState->stencilWriteMask = 0; return; } + pipelineState->stencilTestEnabled = true; + + // Draw contents that affect on the stencil settings for this particular + // drawType. + const auto stencilInfo = + get_stencil_info(interlockMode, drawType, drawContents); + + assert(stencilInfo.areDrawContentsValid); + + // Apply the mask we were given - if the mask is missing bits, tests will + // fail. + drawContents &= stencilInfo.drawContentsMask; + + const bool isClockwiseFill = + enums::is_flag_set(drawContents, DrawContents::clockwiseFill); + const bool isEvenOddFill = + enums::is_flag_set(drawContents, DrawContents::evenOddFill); const bool hasActiveClip = - (batch.drawContents & gpu::DrawContents::activeClip); + enums::is_flag_set(drawContents, DrawContents::activeClip); const bool isClipUpdate = - (batch.drawContents & gpu::DrawContents::clipUpdate); - switch (batch.drawType) + enums::is_flag_set(drawContents, DrawContents::clipUpdate); + + switch (stencilInfo.stencilType) { - case DrawType::imageRect: - case DrawType::imageMesh: - case DrawType::atlasBlit: - case DrawType::msaaStrokes: - case DrawType::msaaOuterCubics: - pipelineState->stencilTestEnabled = true; - pipelineState->stencilDoubleSided = false; + case StencilType::disabled: + pipelineState->stencilTestEnabled = false; + pipelineState->stencilWriteMask = 0; + break; + + case StencilType::activeStencilClip: + assert(hasActiveClip); pipelineState->stencilCompareMask = 0xff; pipelineState->stencilWriteMask = 0xff; pipelineState->stencilReference = 0x80; @@ -851,16 +1280,15 @@ static void get_stencil_state(const DrawBatch& batch, .failOp = StencilOp::keep, .passOp = StencilOp::keep, .depthFailOp = StencilOp::keep, - .compareOp = hasActiveClip ? StencilCompareOp::equal - : StencilCompareOp::always, + .compareOp = StencilCompareOp::equal, }; + + pipelineState->stencilDoubleSided = false; break; - case DrawType::msaaMidpointFanBorrowedCoverage: + case StencilType::borrowedCoverage: // Count backward triangle hits (negative coverage) in the stencil // buffer. - pipelineState->stencilTestEnabled = true; - pipelineState->stencilDoubleSided = false; pipelineState->stencilCompareMask = 0xff; pipelineState->stencilWriteMask = 0x7f; pipelineState->stencilReference = 0x80; @@ -871,13 +1299,12 @@ static void get_stencil_state(const DrawBatch& batch, .compareOp = hasActiveClip ? StencilCompareOp::lessOrEqual : StencilCompareOp::always, }; + pipelineState->stencilDoubleSided = false; break; - case DrawType::msaaMidpointFans: + case StencilType::forwardClippedByBackward: // Draw forward triangles, clipped by the backward triangle counts. // (The depth test prevents double hits.) - pipelineState->stencilTestEnabled = true; - pipelineState->stencilDoubleSided = true; pipelineState->stencilCompareMask = hasActiveClip ? 0xff : 0x7f; pipelineState->stencilWriteMask = isClipUpdate ? 0xff : 0x7f; pipelineState->stencilReference = 0x80; @@ -894,16 +1321,15 @@ static void get_stencil_state(const DrawBatch& batch, .depthFailOp = StencilOp::keep, .compareOp = StencilCompareOp::less, }; + pipelineState->stencilDoubleSided = true; break; - case DrawType::msaaMidpointFanStencilReset: + case StencilType::backwardTriangleCleanup: // Clean up backward triangles in the stencil buffer, (also filling // negative winding numbers for nonZero fill). - pipelineState->stencilTestEnabled = true; - pipelineState->stencilDoubleSided = true; pipelineState->stencilCompareMask = hasActiveClip ? 0xff : 0x7f; pipelineState->stencilWriteMask = - (batch.drawContents & gpu::DrawContents::clockwiseFill) + isClockwiseFill // For clockwise fill, disable clip-bit writes when cleaning // up backward triangles. Clockwise only fills in forward // triangles. @@ -923,20 +1349,14 @@ static void get_stencil_state(const DrawBatch& batch, .depthFailOp = StencilOp::keep, .compareOp = StencilCompareOp::less, }; + pipelineState->stencilDoubleSided = true; break; - case DrawType::msaaMidpointFanPathsStencil: + case StencilType::stencilNestedOrEvenOdd: // Just stencil the path into the stencil buffer. This is used for // nested clip updates and for evenOdd paths. - assert(batch.drawContents & (gpu::DrawContents::evenOddFill) || - (batch.drawContents & gpu::kNestedClipUpdateMask) == - gpu::kNestedClipUpdateMask); - pipelineState->stencilTestEnabled = true; - pipelineState->stencilDoubleSided = true; pipelineState->stencilCompareMask = 0xff; - pipelineState->stencilWriteMask = - (batch.drawContents & gpu::DrawContents::evenOddFill) ? 0x1 - : 0x7f; + pipelineState->stencilWriteMask = isEvenOddFill ? 0x1 : 0x7f; pipelineState->stencilReference = 0x80; // Decrement front-facing triangles so the MSB is set when // clockwise. @@ -953,14 +1373,12 @@ static void get_stencil_state(const DrawBatch& batch, .depthFailOp = pipelineState->stencilFrontOps.depthFailOp, .compareOp = pipelineState->stencilFrontOps.compareOp, }; + pipelineState->stencilDoubleSided = true; break; - case DrawType::msaaMidpointFanPathsCover: + case StencilType::evenOddDrawAndReset: // Draw & reset stencil winding numbers. This is only needed for // evenOdd paths. - assert(batch.drawContents & gpu::DrawContents::evenOddFill); - pipelineState->stencilTestEnabled = true; - pipelineState->stencilDoubleSided = false; pipelineState->stencilCompareMask = 0x7f; pipelineState->stencilWriteMask = isClipUpdate ? 0xff : 0x1; pipelineState->stencilReference = 0x80; @@ -970,63 +1388,52 @@ static void get_stencil_state(const DrawBatch& batch, .depthFailOp = StencilOp::keep, .compareOp = StencilCompareOp::notEqual, }; + pipelineState->stencilDoubleSided = false; break; - case DrawType::msaaStencilClipReset: - pipelineState->stencilTestEnabled = true; + case StencilType::nestedClipReset: + // The nested clip just got stencilled and left in the stencil + // buffer. Intersect it with the existing clip. (Erasing regions of + // the existing clip that are outside the nested clip.) + pipelineState->stencilCompareMask = + isClockwiseFill + // clockwise: (0x80 & 0xc0) < (stencilValue & 0xc0) + // => "If clipbit is set and winding is negative" + // => "If clipbit is set and winding is clockwise" + // (because clockwise decrements) + // + ? 0xc0 + // non-clockwise: 0x80 < stencilValue + // => "If clipbit is set and winding is nonzero" + : 0xff; + pipelineState->stencilWriteMask = 0xff; + pipelineState->stencilReference = 0x80; + pipelineState->stencilFrontOps = { + .failOp = StencilOp::zero, + .passOp = StencilOp::replace, + .depthFailOp = StencilOp::keep, + .compareOp = StencilCompareOp::less, + }; pipelineState->stencilDoubleSided = false; - if ((batch.drawContents & gpu::kNestedClipUpdateMask) == - gpu::kNestedClipUpdateMask) - { - // The nested clip just got stencilled and left in the stencil - // buffer. Intersect it with the existing clip. (Erasing regions - // of the existing clip that are outside the nested clip.) - pipelineState->stencilCompareMask = - (batch.drawContents & gpu::DrawContents::clockwiseFill) - // clockwise: (0x80 & 0xc0) < (stencilValue & 0xc0) - // => "If clipbit is set and winding is negative" - // => "If clipbit is set and winding is clockwise" - // (because clockwise decrements) - // - ? 0xc0 - // non-clockwise: 0x80 < stencilValue - // => "If clipbit is set and winding is nonzero" - : 0xff; - pipelineState->stencilWriteMask = 0xff; - pipelineState->stencilReference = 0x80; - pipelineState->stencilFrontOps = { - .failOp = StencilOp::zero, - .passOp = StencilOp::replace, - .depthFailOp = StencilOp::keep, - .compareOp = StencilCompareOp::less, - }; - } - else - { - // Clear the entire previous clip. - pipelineState->stencilCompareMask = 0xff; - pipelineState->stencilWriteMask = 0xff; - pipelineState->stencilReference = 0x00; - pipelineState->stencilFrontOps = { - .failOp = StencilOp::keep, - .passOp = StencilOp::zero, - .depthFailOp = StencilOp::keep, - .compareOp = StencilCompareOp::notEqual, - }; - } break; - case DrawType::interiorTriangulation: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - RIVE_UNREACHABLE(); + case StencilType::clipReset: + // Clear the entire previous clip. + pipelineState->stencilCompareMask = 0xff; + pipelineState->stencilWriteMask = 0xff; + pipelineState->stencilReference = 0x00; + pipelineState->stencilFrontOps = { + .failOp = StencilOp::keep, + .passOp = StencilOp::zero, + .depthFailOp = StencilOp::keep, + .compareOp = StencilCompareOp::notEqual, + }; + pipelineState->stencilDoubleSided = false; + break; } } -static CullFace get_cull_face(DrawType drawType) +CullFace get_cull_face(DrawType drawType) { switch (drawType) { @@ -1037,7 +1444,7 @@ static CullFace get_cull_face(DrawType drawType) case DrawType::atlasBlit: case DrawType::msaaStrokes: case DrawType::msaaMidpointFans: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: return CullFace::counterclockwise; case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFanStencilReset: @@ -1051,39 +1458,91 @@ static CullFace get_cull_face(DrawType drawType) return CullFace::clockwise; case DrawType::imageRect: case DrawType::imageMesh: - case DrawType::atomicResolve: - case DrawType::atomicInitialize: case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: + case DrawType::renderPassResolve: + case DrawType::renderPassInitialize: return CullFace::none; } RIVE_UNREACHABLE(); } static BlendEquation get_blend_equation( - const FlushDescriptor& flushDesc, - const DrawBatch& batch, + DrawType drawType, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + DrawContents drawContents, + BlendMode blendMode, + bool fixedFunctionColorOutput, const PlatformFeatures& platformFeatures) { - switch (flushDesc.interlockMode) + switch (interlockMode) { case InterlockMode::rasterOrdering: case InterlockMode::atomics: - return flushDesc.atomicFixedFunctionColorOutput - ? BlendEquation::srcOver - : BlendEquation::none; + case InterlockMode::clockwise: + return fixedFunctionColorOutput ? BlendEquation::srcOver + : BlendEquation::none; case InterlockMode::clockwiseAtomic: - return BlendEquation::srcOver; + if (drawType == DrawType::renderPassInitialize) + { + // This draw is a seeming workaround for Qualcomm. Basically, + // input attachment reads of the clip and color buffers don't + // work unless we first draw these buffers into themselves + // between borrowed coverage and the main subpass. + return fixedFunctionColorOutput + // When using fixedFunctionColorOutput, this + // workaround doesn't apply to the color buffer, but + // we still need to make sure the existing color + // content doesn't change. To do this, we use srcOver + // blend and emit a color of 0. + ? BlendEquation::srcOver + // Otherwise, the workaround draws both color and + // clip into themselves. Blend needs to be disabled + // in this case because the existing color value + // might have transparency. + : BlendEquation::none; + } + else if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)) + { + // Borrowed coverage passes don't emit color. They only update + // the coverage buffer. + return BlendEquation::none; + } + else if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::nestedClipUpdateOnly)) + { + // The coverage of two intersecting clips is + // "min(clipCoverageA, clipCoverageB)". + return BlendEquation::min; + } + else if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly) && + drawType != gpu::DrawType::clipReset) + { + // clockwiseAtomic clips render coverage count directly to the + // clip buffer. + return BlendEquation::plus; + } + else + { + // For normal paths, clockwiseAtomic uses src-over to accumulate + // coverage, even with advanced blend. + return BlendEquation::srcOver; + } case InterlockMode::msaa: - if (batch.drawContents & DrawContents::opaquePaint) + if (enums::is_flag_set(drawContents, DrawContents::opaquePaint)) { return BlendEquation::none; } - else if (!platformFeatures.supportsKHRBlendEquations || - batch.firstBlendMode == BlendMode::srcOver) + else if (!platformFeatures.supportsBlendAdvancedKHR || + blendMode == BlendMode::srcOver) { // Normal and in-shader blending both use src-over hardware // blend coefficients. @@ -1091,23 +1550,31 @@ static BlendEquation get_blend_equation( // When drawing an advanced blend mode, the shader only does the // "color" portion of the blend equation, and relies on the // hardware blend unit to finish the "alpha" portion. + assert(drawType != DrawType::renderPassInitialize && + drawType != DrawType::renderPassResolve); return BlendEquation::srcOver; } else { - // When m_platformFeatures.supportsKHRBlendEquations is true in + // When m_platformFeatures.supportsBlendAdvancedKHR is true in // MSAA mode, the renderContext does not combine draws that have // different blend modes. - return static_cast(batch.firstBlendMode); + assert(drawType != DrawType::renderPassInitialize && + drawType != DrawType::renderPassResolve); + return static_cast(blendMode); } } RIVE_UNREACHABLE(); } -static bool get_color_writemask(const DrawBatch& batch) +bool get_color_write_enable(DrawType drawType, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + bool fixedFunctionColorOutput, + DrawContents drawContents) { - switch (batch.drawType) + switch (drawType) { case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: @@ -1116,36 +1583,148 @@ static bool get_color_writemask(const DrawBatch& batch) case DrawType::atlasBlit: case DrawType::imageRect: case DrawType::imageMesh: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: - return true; + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: + if (enums::any_flag_set(shaderMiscFlags, + ShaderMiscFlags::clipUpdateOnly | + ShaderMiscFlags::borrowedCoveragePass)) + { + // Clip updates and borrowed coverage passes don't output color. + return false; + } + // We generate pipeline state under the assumption that pixel local + // storage can still be written when colorWriteEnabled is false. + // Disable color writes when we're rendering only to PLS. + return fixedFunctionColorOutput || + interlockMode == InterlockMode::msaa; case DrawType::msaaStrokes: case DrawType::msaaOuterCubics: return true; case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: return false; case DrawType::msaaMidpointFans: case DrawType::msaaMidpointFanPathsCover: - return !(batch.drawContents & DrawContents::clipUpdate); + return !enums::is_flag_set(drawContents, DrawContents::clipUpdate); case DrawType::msaaMidpointFanStencilReset: // For clockwise fill, disable color writes when cleaning up // backward triangles. Clockwise only fills in forward triangles. - return !(batch.drawContents & - (DrawContents::clockwiseFill | DrawContents::clipUpdate)); + return enums::no_flags_set(drawContents, + DrawContents::clockwiseFill | + DrawContents::clipUpdate); } - return false; + + RIVE_UNREACHABLE(); +} + +uint64_t pipeline_unique_key(DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + DrawContents drawContents, + bool fixedFunctionColorOutput, + rive::BlendMode blendMode, + const PlatformFeatures& platformFeatures) +{ + uint64_t key = gpu::ShaderUniqueKey(drawType, + shaderFeatures, + interlockMode, + shaderMiscFlags); + + constexpr auto VALID_PIPELINE_DRAW_CONTENTS_BIT_COUNT = + math::count_set_bits(uint32_t(DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE)); + + const auto stencilInfo = + get_stencil_info(interlockMode, + drawType, + drawContents & DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE); + + const auto drawContentsMask = + (interlockMode == InterlockMode::msaa) + ? DrawContents(stencilInfo.drawContentsMask | + DrawContents::opaquePaint) + : DrawContents::none; + + assert((drawContentsMask & DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE) == + drawContentsMask); + + const auto effectiveDrawContents = + DrawContents(drawContents & drawContentsMask); + + // Compact the draw contents to only the bits that matter for the pipeline + // (and, thus, the key) + key = math::add_bits_to_key( + key, + math::compact_bitmask_value( + uint32_t(effectiveDrawContents), + uint32_t(DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE)), + VALID_PIPELINE_DRAW_CONTENTS_BIT_COUNT); + + // Only MSAA cares about other blend modes during pipeline creation. + auto effectiveBlendMode = (interlockMode == InterlockMode::msaa && + platformFeatures.supportsBlendAdvancedKHR) + ? blendMode + : BlendMode::srcOver; + + assert(uint32_t(effectiveBlendMode) < (1u << BLEND_MODE_BIT_COUNT)); + + key = math::add_bits_to_key(key, + uint32_t(effectiveBlendMode), + BLEND_MODE_BIT_COUNT); + + key = math::add_bits_to_key(key, + uint32_t(stencilInfo.stencilType), + STENCIL_TYPE_BIT_COUNT); + + const bool colorWriteEnabled = + get_color_write_enable(drawType, + interlockMode, + shaderMiscFlags, + fixedFunctionColorOutput, + effectiveDrawContents); + key = math::add_bits_to_key(key, uint32_t(colorWriteEnabled), 1); + const auto depthState = + get_depth_state(interlockMode, drawType, effectiveDrawContents); + key = math::add_bits_to_key(key, uint32_t(depthState.depthTestEnabled), 1); + key = math::add_bits_to_key(key, uint32_t(depthState.depthWriteEnabled), 1); + key = math::add_bits_to_key(key, + uint32_t(get_cull_face(drawType)), + CULL_FACE_BIT_COUNT); + return key; } void get_pipeline_state(const DrawBatch& batch, const FlushDescriptor& flushDesc, const PlatformFeatures& platformFeatures, - PipelineState* pipelineState) + PipelineState* pipelineStateOut) +{ + *pipelineStateOut = get_pipeline_state(batch.drawType, + flushDesc.interlockMode, + batch.shaderMiscFlags, + batch.drawContents, + flushDesc.fixedFunctionColorOutput, + batch.firstBlendMode, + platformFeatures); +} + +PipelineState get_pipeline_state(DrawType drawType, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags, + DrawContents drawContents, + bool fixedFunctionColorOutput, + rive::BlendMode blendMode, + const PlatformFeatures& platformFeatures) { + // Only some DrawContents flags are relevant (and only for msaa at the + // moment) + drawContents &= (interlockMode == InterlockMode::msaa) + ? DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE + : DrawContents::none; + #ifndef NDEBUG // Ensure drawType is compatible with the interlock mode. - switch (batch.drawType) + switch (drawType) { case DrawType::atlasBlit: case DrawType::imageMesh: @@ -1155,13 +1734,20 @@ void get_pipeline_state(const DrawBatch& batch, case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: case DrawType::interiorTriangulation: - assert(flushDesc.interlockMode != InterlockMode::msaa); + assert(interlockMode != InterlockMode::msaa); break; case DrawType::imageRect: - case DrawType::atomicResolve: - case DrawType::atomicInitialize: - assert(flushDesc.interlockMode == InterlockMode::atomics); + case DrawType::renderPassResolve: + assert(interlockMode == InterlockMode::rasterOrdering || + interlockMode == InterlockMode::atomics || + interlockMode == InterlockMode::msaa); + break; + + case DrawType::renderPassInitialize: + assert(interlockMode == InterlockMode::atomics || + interlockMode == InterlockMode::msaa || + interlockMode == InterlockMode::clockwiseAtomic); break; case DrawType::msaaStrokes: @@ -1171,18 +1757,36 @@ void get_pipeline_state(const DrawBatch& batch, case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - assert(flushDesc.interlockMode == InterlockMode::msaa); + assert(interlockMode == InterlockMode::msaa); + break; + + case DrawType::clipReset: + assert(interlockMode == InterlockMode::clockwiseAtomic || + interlockMode == InterlockMode::msaa); break; } #endif - get_depth_state(batch, flushDesc, pipelineState); - get_stencil_state(batch, flushDesc, pipelineState); - pipelineState->cullFace = get_cull_face(batch.drawType); - pipelineState->blendEquation = - get_blend_equation(flushDesc, batch, platformFeatures); - pipelineState->colorWriteEnabled = get_color_writemask(batch); + PipelineState pipelineState; + auto depthState = get_depth_state(interlockMode, drawType, drawContents); + pipelineState.depthTestEnabled = depthState.depthTestEnabled; + pipelineState.depthWriteEnabled = depthState.depthWriteEnabled; + get_stencil_settings(interlockMode, drawType, drawContents, &pipelineState); + pipelineState.cullFace = get_cull_face(drawType); + pipelineState.blendEquation = get_blend_equation(drawType, + interlockMode, + shaderMiscFlags, + drawContents, + blendMode, + fixedFunctionColorOutput, + platformFeatures); + pipelineState.colorWriteEnabled = + get_color_write_enable(drawType, + interlockMode, + shaderMiscFlags, + fixedFunctionColorOutput, + drawContents); + return pipelineState; } // Borrowed from: @@ -1229,7 +1833,7 @@ uint16x4 cast_f32_to_f16(float4 x) } // Code to generate g_gaussianIntegralTableF16. -#if 0 +#ifdef RIVE_GENERATE_FEATHER_LUT static float eval_normal_distribution(float x, float mu, float inverseSigma) { constexpr static float ONE_OVER_SQRT_2_PI = 0.398942280401433f; @@ -1270,6 +1874,29 @@ void generate_gausian_integral_table(float (&table)[GAUSSIAN_TABLE_SIZE]) { table[i] = fminf(fmaxf(table[i - 1], table[i] + shift), 1); } + + // How many entries to ease in and out, so the table has a soft landing at + // 0 and 1 on the edges. + constexpr size_t EASE_IN_OUT_DIST = 8; + for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i) + { + if (i < EASE_IN_OUT_DIST) + { + float fi = + static_cast(i) / static_cast(EASE_IN_OUT_DIST); + table[i] *= fi; + } + + if (i > (GAUSSIAN_TABLE_SIZE - EASE_IN_OUT_DIST) - 1) + { + float diffToOne = 1.0 - table[i]; + float fi = static_cast( + i - (GAUSSIAN_TABLE_SIZE - EASE_IN_OUT_DIST) + 1) / + static_cast(EASE_IN_OUT_DIST); + table[i] = table[i] + (diffToOne * fi); + } + } + printf("\nconst float g_gaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = " "{\n"); for (size_t i = 0; i < GAUSSIAN_TABLE_SIZE; ++i) @@ -1288,7 +1915,7 @@ void generate_gausian_integral_table(float (&table)[GAUSSIAN_TABLE_SIZE]) #endif const uint16_t g_gaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = { - 0x15a3, 0x15db, 0x1616, 0x1652, 0x1691, 0x16d1, 0x1715, 0x175a, 0x17a2, + 0x0, 0x9db, 0xe16, 0x10be, 0x1291, 0x1443, 0x154f, 0x166f, 0x17a2, 0x17ec, 0x181c, 0x1844, 0x186d, 0x1898, 0x18c4, 0x18f1, 0x1920, 0x1951, 0x1983, 0x19b7, 0x19ec, 0x1a23, 0x1a5d, 0x1a98, 0x1ad4, 0x1b13, 0x1b54, 0x1b97, 0x1bdc, 0x1c12, 0x1c36, 0x1c5c, 0x1c83, 0x1cac, 0x1cd5, 0x1d00, @@ -1344,11 +1971,11 @@ const uint16_t g_gaussianIntegralTableF16[GAUSSIAN_TABLE_SIZE] = { 0x3bf6, 0x3bf7, 0x3bf7, 0x3bf7, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf8, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bf9, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfa, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfb, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, 0x3bfc, - 0x3bfc, 0x3bfc, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, 0x3bfd, + 0x3bfd, 0x3bfd, 0x3bfe, 0x3bfe, 0x3bff, 0x3bff, 0x3c00, 0x3c00, }; // Code to generate g_inverseGaussianIntegralTableF32. -#if 0 +#ifdef RIVE_GENERATE_FEATHER_LUT void generate_inverse_gausian_integral_table( float (&table)[GAUSSIAN_TABLE_SIZE]) { diff --git a/thirdparty/rive_renderer/source/gr_triangulator.cpp b/thirdparty/rive_renderer/source/gr_triangulator.cpp index ac463ea3d..5b619a68d 100644 --- a/thirdparty/rive_renderer/source/gr_triangulator.cpp +++ b/thirdparty/rive_renderer/source/gr_triangulator.cpp @@ -50,7 +50,7 @@ static bool is_finite(Vec2D pt) return !std::isnan(accum); } -template +template static void list_insert(T* t, T* prev, T* next, T** head, T** tail) { t->*Prev = prev; @@ -73,7 +73,7 @@ static void list_insert(T* t, T* prev, T* next, T** head, T** tail) } } -template +template static void list_remove(T* t, T** head, T** tail) { if (t->*Prev) @@ -460,8 +460,10 @@ size_t GrTriangulator::emitMonotonePoly( { riveWeight = -riveWeight; } - if ((riveWeight < 0 && !(windingFaces & gpu::WindingFaces::negative)) || - (riveWeight >= 0 && !(windingFaces & gpu::WindingFaces::positive))) + if ((riveWeight < 0 && + !enums::is_flag_set(windingFaces, gpu::WindingFaces::negative)) || + (riveWeight >= 0 && + !enums::is_flag_set(windingFaces, gpu::WindingFaces::positive))) { return 0; } diff --git a/thirdparty/rive_renderer/source/gradient.cpp b/thirdparty/rive_renderer/source/gradient.cpp index 8d5da7963..88f9e5a55 100644 --- a/thirdparty/rive_renderer/source/gradient.cpp +++ b/thirdparty/rive_renderer/source/gradient.cpp @@ -4,8 +4,6 @@ #include "gradient.hpp" -#include "rive/renderer/rive_render_image.hpp" - namespace rive::gpu { // Ensure the given gradient stops are in a format expected by PLS. @@ -190,4 +188,39 @@ bool Gradient::isOpaque() const return m_isOpaque == gpu::TriState::yes; } +rcp Gradient::getModulated(float opacity) const +{ + // Fast path: no modulation needed + if (opacity == 1.0f) + { + return ref_rcp(const_cast(this)); + } + + // Check single-entry cache + if (m_lastModulatedOpacity == opacity && m_lastModulatedGradient) + { + return m_lastModulatedGradient; + } + + // Create new modulated gradient + GradDataArray newColors(m_count); + for (size_t i = 0; i < m_count; ++i) + { + newColors[i] = colorModulateOpacity(m_colors[i], opacity); + } + + GradDataArray newStops(m_stops.get(), m_count); + + m_lastModulatedGradient = rcp(new Gradient(m_paintType, + std::move(newColors), + std::move(newStops), + m_count, + m_coeffs[0], + m_coeffs[1], + m_coeffs[2])); + m_lastModulatedOpacity = opacity; + + return m_lastModulatedGradient; +} + } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/gradient.hpp b/thirdparty/rive_renderer/source/gradient.hpp index 099f12b76..e48072912 100644 --- a/thirdparty/rive_renderer/source/gradient.hpp +++ b/thirdparty/rive_renderer/source/gradient.hpp @@ -10,6 +10,7 @@ namespace rive::gpu { + // Copies an array of colors or stops for a gradient. // Stores the data locally if there are 4 values or fewer. // Spills onto the heap if there are >4 values. @@ -25,6 +26,13 @@ template class GradDataArray memcpy(m_data, data, count * sizeof(T)); } + // Allocate without initializing (caller must fill in data). + explicit GradDataArray(size_t count) + { + m_data = + count <= m_localData.size() ? m_localData.data() : new T[count]; + } + GradDataArray(GradDataArray&& other) { if (other.m_data == other.m_localData.data()) @@ -83,6 +91,11 @@ class Gradient : public LITE_RTTI_OVERRIDE(RenderShader, Gradient) size_t count() const { return m_count; } bool isOpaque() const; + // Get or create a modulated variant of this gradient. + // Caches the last-used modulated gradient for efficient reuse when the same + // opacity is requested multiple times (e.g., multiple draws in one frame). + rcp getModulated(float opacity) const; + private: Gradient(PaintType paintType, GradDataArray&& colors, // [count] @@ -107,6 +120,11 @@ class Gradient : public LITE_RTTI_OVERRIDE(RenderShader, Gradient) size_t m_count; std::array m_coeffs; mutable gpu::TriState m_isOpaque = gpu::TriState::unknown; + + // Single-entry cache for last-used modulated gradient + mutable rcp m_lastModulatedGradient; + mutable float m_lastModulatedOpacity = + -1.0f; // -1 as sentinel (valid range is 0..1) }; } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/instance_chunker.hpp b/thirdparty/rive_renderer/source/instance_chunker.hpp new file mode 100644 index 000000000..815650dec --- /dev/null +++ b/thirdparty/rive_renderer/source/instance_chunker.hpp @@ -0,0 +1,91 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include +#include +#include + +namespace rive::gpu +{ +// Some Mali and PowerVR devices crash when issuing draw commands with a large +// instance count. This class breaks large instance ranges up into chunks that +// can be safely issued on affected GPUs. +class InstanceChunker +{ +public: + struct Chunk + { + uint32_t instanceCount; + uint32_t baseInstance; + }; + + struct Iterator + { + public: + uint32_t currentChunkInstanceCount() const + { + return std::min(endInstance - currentInstance, + maxSupportedInstancesPerDrawCommand); + } + + Chunk operator*() const + { + return {currentChunkInstanceCount(), currentInstance}; + } + + Iterator& operator++() + { + currentInstance += currentChunkInstanceCount(); + return *this; + } + + bool operator==(const Iterator& other) const + { + assert(endInstance == other.endInstance); + assert(maxSupportedInstancesPerDrawCommand == + other.maxSupportedInstancesPerDrawCommand); + return currentInstance == other.currentInstance; + } + + bool operator!=(const Iterator& other) const + { + return !(*this == other); + } + + uint32_t currentInstance; + uint32_t endInstance; + uint32_t maxSupportedInstancesPerDrawCommand; + }; + + InstanceChunker(uint32_t instanceCount, + uint32_t baseInstance, + uint32_t maxSupportedInstancesPerDrawCommand) : + m_startInstance(baseInstance), + m_endInstance(baseInstance + instanceCount), + m_maxSupportedInstancesPerDrawCommand( + maxSupportedInstancesPerDrawCommand) + {} + + Iterator begin() const + { + return {m_startInstance, + m_endInstance, + m_maxSupportedInstancesPerDrawCommand}; + } + + Iterator end() const + { + return {m_endInstance, + m_endInstance, + m_maxSupportedInstancesPerDrawCommand}; + } + +private: + uint32_t m_startInstance; + uint32_t m_endInstance; + uint32_t m_maxSupportedInstancesPerDrawCommand; +}; +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/intersection_board.cpp b/thirdparty/rive_renderer/source/intersection_board.cpp index 827823de1..8fe439a00 100644 --- a/thirdparty/rive_renderer/source/intersection_board.cpp +++ b/thirdparty/rive_renderer/source/intersection_board.cpp @@ -16,7 +16,10 @@ namespace rive::gpu { -void IntersectionTile::reset(int left, int top, int16_t baselineGroupIndex) +void IntersectionTile::reset(int left, + int top, + int16_t baselineGroupIndex, + uint16_t baselineOverlapBits) { // Since we mask non-intersecting groupIndices to zero, the "mask and max" // algorithm is only correct for positive values. (baselineGroupIndex is @@ -25,94 +28,522 @@ void IntersectionTile::reset(int left, int top, int16_t baselineGroupIndex) m_topLeft = {left, top, left, top}; m_baselineGroupIndex = baselineGroupIndex; m_maxGroupIndex = baselineGroupIndex; + m_baselineOverlapBits = baselineOverlapBits; + m_overlapBitsForMaxGroup = baselineOverlapBits; m_edges.clear(); m_groupIndices.clear(); + m_overlapBits.clear(); m_rectangleCount = 0; } -void IntersectionTile::addRectangle(int4 ltrb, int16_t groupIndex) +template +void IntersectionTile::addRectangle(int4 ltrb, + int16_t groupIndex, + uint16_t currentRectangleOverlapBits) { assert(simd::all(ltrb.xy < ltrb.zw)); // Ensure ltrb isn't zero or negative. - // Ensure this rectangle preserves the integrity of our list. - assert(groupIndex > - simd::reduce_max(findMaxIntersectingGroupIndex(ltrb, 0))); - assert(groupIndex > m_baselineGroupIndex); assert(groupIndex >= 0); + if constexpr (Type == GroupingType::overlapAllowed) + { + if (m_overlapBits.size() != m_groupIndices.size()) + { + // We did not previously have any overlap bits and now we're about + // to - initialize the array with zeros (everything already in the + // intersection tile has zeros as its overlap bits, or else the + // boardContainsNonzeroOverlapBits flag would have already been + // set). + assert(m_overlapBits.empty()); + m_overlapBits.resize(m_groupIndices.size()); + } + } + else + { + static_assert(Type == GroupingType::disjoint); + + // Shouldn't pass any overlap bits in if we indicated they weren't + // relevant + assert(currentRectangleOverlapBits == 0); + } + +#if !defined(NDEBUG) + // Ensure this rectangle preserves the integrity of our list. + { + auto r = findMaxIntersectingGroupIndex(ltrb, {}); + auto maxGroup = simd::reduce_max(r.maxGroupIndices); + if constexpr (Type == GroupingType::overlapAllowed) + { + // If overlapping is allowed, this rectangle can be in the same + // group as another it overlaps, but cannot be below it. + assert(groupIndex >= maxGroup); + assert(groupIndex >= m_baselineGroupIndex); + } + else + { + // If no overlapping is allowed, this rectangle cannot be at or + // below a group it overlaps. + assert(groupIndex > maxGroup); + assert(groupIndex > m_baselineGroupIndex); + } + } +#endif + // Translate ltrb to our tile and negate the right and bottom sides. ltrb -= m_topLeft; - ltrb.zw = 255 - ltrb.zw; // right = 255 - right, bottom = 255 - bottom - assert(simd::all(ltrb < - 255)); // Ensure ltrb isn't completely outside the tile. + // right = TILE_DIM - right, bottom = TILE_DIM- bottom + ltrb.zw = TILE_DIM - ltrb.zw; + // Ensure ltrb isn't completely outside the tile. + assert(simd::all(ltrb < TILE_DIM)); ltrb = simd::max(ltrb, int4(0)); // Clamp ltrb to our tile. + if constexpr (Type == GroupingType::overlapAllowed) + { + if (groupIndex == m_baselineGroupIndex && + (currentRectangleOverlapBits | m_baselineOverlapBits) == + m_baselineOverlapBits) + { + // Nothing needs to be done here, this is going into the baseline + // group and it adds no new overlap bits that are not already in the + // baseline. + return; + } + } + if (simd::all(ltrb == 0)) { - // ltrb covers the entire tile -- reset to a new baseline. - assert(groupIndex > m_maxGroupIndex); - reset(m_topLeft.x, m_topLeft.y, groupIndex); + // ltrb covers the entire tile + if constexpr (Type == GroupingType::overlapAllowed) + { + // This rectangle is allowed to be at or higher than the max group + // (rather than strictly above it, in the no-overlap case) + assert(groupIndex >= m_maxGroupIndex); + + if (groupIndex == m_maxGroupIndex) + { + // This rectangle is within the existing max group, so do a + // heavier-handed update (some rectangles in the max group + // may still need to stay, so we can't do a reset) + updateBaselineToMaxGroupIndex( + currentRectangleOverlapBits); + return; + } + } + else + { + // If no overlapping is allowed, a full-tile rectangle had + // better be above the current max group. + assert(groupIndex > m_maxGroupIndex); + } + + // Setting a new baseline, so reset everything, update the group index + // and baseline overlap + reset(m_topLeft.x, + m_topLeft.y, + groupIndex, + currentRectangleOverlapBits); return; } // Append a chunk if needed, to make room for this new rectangle. - uint32_t subIdx = m_rectangleCount % kChunkSize; + uint32_t subIdx = m_rectangleCount % CHUNK_SIZE; if (subIdx == 0) { // Push back maximally negative rectangles so they always fail // intersection tests. - assert(m_edges.size() * kChunkSize == m_rectangleCount); - m_edges.push_back(int8x32(std::numeric_limits::max())); + assert(m_edges.size() * CHUNK_SIZE == m_rectangleCount); + m_edges.push_back(int8x32(TILE_DIM + TILE_EDGE_BIAS)); // Uninitialized since the corresponding rectangles never pass an // intersection test. - assert(m_groupIndices.size() * kChunkSize == m_rectangleCount); + assert(m_groupIndices.size() * CHUNK_SIZE == m_rectangleCount); m_groupIndices.emplace_back(); + + if constexpr (Type == GroupingType::overlapAllowed) + { + assert(m_overlapBits.size() * CHUNK_SIZE == m_rectangleCount); + m_overlapBits.emplace_back(); + } } - // m_edges is a list of 8 rectangles encoded as [L, T, 255 - R, 255 - B], - // relative to m_topLeft. The data is also transposed: [L0..L7, T0..T7, - // -R0..R7, -B0..B7]. Bias ltrb by -128 so we can use int8_t. SSE doesn't - // have an unsigned byte compare. - int4 biased = ltrb + std::numeric_limits::min(); + // m_edges is a list of 8 rectangles encoded as + // [L, T, TILE_DIM - R, TILE_DIM - B], relative to m_topLeft. The data is + // also transposed: [L0..L7, T0..T7, -R0..R7, -B0..B7]. Bias ltrb so + // we can use int8_t. SSE doesn't have an unsigned byte compare. + int4 biased = ltrb + TILE_EDGE_BIAS; m_edges.back()[subIdx] = biased.x; - m_edges.back()[subIdx + 8] = biased.y; - m_edges.back()[subIdx + 16] = - biased.z; // Already converted to "255 - right" above. - m_edges.back()[subIdx + 24] = - biased.w; // Already converted to "255 - bottom" above. + m_edges.back()[subIdx + 1 * CHUNK_SIZE] = biased.y; + m_edges.back()[subIdx + 2 * CHUNK_SIZE] = + biased.z; // Already converted to "TILE_DIM - right" above. + m_edges.back()[subIdx + 3 * CHUNK_SIZE] = + biased.w; // Already converted to "TILE_DIM - bottom" above. m_groupIndices.back()[subIdx] = groupIndex; - m_maxGroupIndex = std::max(groupIndex, m_maxGroupIndex); + if constexpr (Type == GroupingType::overlapAllowed) + { + m_overlapBits.back()[subIdx] = currentRectangleOverlapBits; + + if (groupIndex > m_maxGroupIndex) + { + // There's a new maximum group, so set it and restart its overlap + // bits. + m_maxGroupIndex = groupIndex; + m_overlapBitsForMaxGroup = currentRectangleOverlapBits; + } + else if (groupIndex == m_maxGroupIndex) + { + // This is going into the existing max group so add its overlap bits + // to the max group's tracked overlap bits + m_overlapBitsForMaxGroup |= currentRectangleOverlapBits; + } + } + else + { + // If we aren't tracking overlap bits then simply ensuring the max group + // index is correct is sufficient. + m_maxGroupIndex = std::max(m_maxGroupIndex, groupIndex); + } + ++m_rectangleCount; } -int16x8 IntersectionTile::findMaxIntersectingGroupIndex( +#ifdef WITH_RIVE_TOOLS +template +void IntersectionTile::testingOnly_addRectangleAndValidate( int4 ltrb, - int16x8 runningMaxGroupIndices) const + int16_t groupIndex, + uint16_t currentRectangleOverlapBits) +{ + addRectangle(ltrb, groupIndex, currentRectangleOverlapBits); + + // Baseline should not be higher than the inserted rectangle, + // max group should not be lower. + assert(m_baselineGroupIndex <= groupIndex); + assert(m_maxGroupIndex >= groupIndex); + + // Should be no baseline overlap bits if there's no baseline + // (ditto for max group) + assert(m_baselineGroupIndex != 0 || m_baselineOverlapBits == 0); + assert(m_maxGroupIndex != 0 || m_overlapBitsForMaxGroup == 0); + + uint16_t foundOverlapBitsForMaxGroup; + + if constexpr (Type == GroupingType::overlapAllowed) + { + foundOverlapBitsForMaxGroup = (m_baselineGroupIndex == m_maxGroupIndex) + ? m_baselineOverlapBits + : 0u; + } + else + { + // Ignore this value (not using std::ignore here because it + // would require initializing the value first, which would + // mean the compiler won't catch a mistake where this gets + // used elsewhere when it shouldn't be) + (void)foundOverlapBitsForMaxGroup; + + // If overlap isn't allowed this should never be allocated + assert(m_overlapBits.empty()); + } + + // Exhaustively check to ensure that the overlap bits and max + // group indices match our tracked values. + auto maxGroupIndexFound = m_baselineGroupIndex; + for (auto i = 0u; i < m_rectangleCount; i++) + { + auto outerI = i / CHUNK_SIZE; + auto innerI = i % CHUNK_SIZE; + + assert(m_groupIndices[outerI][innerI] >= m_baselineGroupIndex); + assert(m_groupIndices[outerI][innerI] <= m_maxGroupIndex); + if constexpr (Type == GroupingType::overlapAllowed) + { + if (m_groupIndices[outerI][innerI] == m_maxGroupIndex) + { + foundOverlapBitsForMaxGroup |= m_overlapBits[outerI][innerI]; + } + } + maxGroupIndexFound = + std::max(maxGroupIndexFound, m_groupIndices[outerI][innerI]); + } + + if constexpr (Type == GroupingType::overlapAllowed) + { + assert(foundOverlapBitsForMaxGroup == m_overlapBitsForMaxGroup); + if (m_baselineGroupIndex == m_maxGroupIndex) + { + // max group is allowed to have more set bits than the + // baseline (as there might be non-full-tile rectangles + // at that level), but there should never be bits in + // baseline that aren't part of the max group set if + // their group indices match. + assert((m_overlapBitsForMaxGroup | m_baselineOverlapBits) == + m_overlapBitsForMaxGroup); + } + } + else + { + assert(m_overlapBitsForMaxGroup == 0); + assert(m_baselineOverlapBits == 0); + } + + assert(maxGroupIndexFound == m_maxGroupIndex); +} +#endif + +template +void IntersectionTile::updateBaselineToMaxGroupIndex( + uint16_t additionalBaselineOverlapBits) +{ + // This should only be called when overlap testing is enabled. The template + // argument is really just here to make it hard to accidentally call this + // from a place where it will be wrong + static_assert(Type == GroupingType::overlapAllowed); + + // We've added a full-tile rectangle at m_maxGroupIndex, which means we can + // update the baseline and its overlap bits. + if ((additionalBaselineOverlapBits | m_overlapBitsForMaxGroup) == + additionalBaselineOverlapBits || + m_rectangleCount == 0) + { + // This rectangle both covers the whole tile and either it contains all + // of the existing overlap bits in this group, or there are no + // existing rectangles (the max group is the already just the baseline), + // which means we can do a simple reset, as we don't need to keep any + // rectangles - even ones that are in this max group. + reset(m_topLeft.x, + m_topLeft.y, + m_maxGroupIndex, + m_overlapBitsForMaxGroup | additionalBaselineOverlapBits); + return; + } + + m_overlapBitsForMaxGroup |= additionalBaselineOverlapBits; + + if (m_maxGroupIndex == m_baselineGroupIndex) + { + if (m_overlapBitsForMaxGroup == m_baselineOverlapBits) + { + // This rectangle does not change the baseline or its bits in + // any way, so we're done early. + return; + } + + m_baselineOverlapBits |= additionalBaselineOverlapBits; + } + else + { + m_baselineGroupIndex = m_maxGroupIndex; + m_baselineOverlapBits = additionalBaselineOverlapBits; + } + + // Do a pass through the array and zero out the group indices of any + // rectangles that should no longer remain in the list (this makes the test + // in the compaction loop more efficient). + { +#if !defined(FALLBACK_ON_SSE2_INTRINSICS) + auto baselineGroupIndexVector = int16x8(m_baselineGroupIndex); + auto baselineOverlapBitsVector = uint16x8(m_baselineOverlapBits); +#else + auto baselineGroupIndexVector = _mm_set1_epi16(m_baselineGroupIndex); + auto baselineOverlapBitsVector = _mm_set1_epi16(m_baselineOverlapBits); +#endif + for (size_t i = 0; i < m_groupIndices.size(); i++) + { +#if !defined(FALLBACK_ON_SSE2_INTRINSICS) + // Groups under the baseline will go away + auto mask = m_groupIndices[i] >= baselineGroupIndexVector; + + // Of those that remained, only keep the ones where the overlap bits + // have bits that aren't in the baseline's bits. + mask &= ((baselineOverlapBitsVector | m_overlapBits[i]) != + baselineOverlapBitsVector); + + m_groupIndices[i] &= mask; +#else + // The SSE2 code has to build the mask backwards from the above + // code, as there is neither a ">=" or "!=" operator. + auto groupIndices = math::bit_cast<__m128i>(m_groupIndices[i]); + auto overlapBits = math::bit_cast<__m128i>(m_overlapBits[i]); + auto mask = _mm_cmpgt_epi16(baselineGroupIndexVector, groupIndices); + + mask = _mm_or_si128( + mask, + _mm_cmpeq_epi16( + baselineOverlapBitsVector, + _mm_or_si128(baselineOverlapBitsVector, overlapBits))); + + // Conveniently, there is a (~mask & groupIndices) single operation + // to allow us to use the inverted mask directly. + groupIndices = _mm_andnot_si128(mask, groupIndices); + m_groupIndices[i] = math::bit_cast(groupIndices); +#endif + } + } + + // Now, remove all of the rectangles that are no longer above the line. + // (Thankfully, ordering doesn't matter, so we don't need the partitioning + // to be stable) + + // Start by scaning the first index forward until we find a rectangle that + // doesn't need to stay (or we hit the end) + size_t firstIdx = 0u; + while (m_groupIndices[firstIdx / CHUNK_SIZE][firstIdx % CHUNK_SIZE] != 0) + { + firstIdx++; + if (firstIdx == m_rectangleCount) + { + // Every rectangle stays! We don't have to do any additional + // work. + return; + } + } + + size_t lastIdx = m_rectangleCount - 1; + while (lastIdx > firstIdx && + m_groupIndices[lastIdx / CHUNK_SIZE][lastIdx % CHUNK_SIZE] == 0) + { + --lastIdx; + } + + while (firstIdx < lastIdx) + { + // Now first index points to something that should go and last index + // points to something that should stay, and they're out of order. Move + // the latter element to the beginning to put it into place. + { + size_t firstOuterIdx = firstIdx / CHUNK_SIZE; + size_t firstInnerIdx = firstIdx % CHUNK_SIZE; + size_t lastOuterIdx = lastIdx / CHUNK_SIZE; + size_t lastInnerIdx = lastIdx % CHUNK_SIZE; + + // Put the one that wants to stay at the first index. + + m_edges[firstOuterIdx][firstInnerIdx + 0] = + m_edges[lastOuterIdx][lastInnerIdx + 0]; + m_edges[firstOuterIdx][firstInnerIdx + CHUNK_SIZE] = + m_edges[lastOuterIdx][lastInnerIdx + CHUNK_SIZE]; + m_edges[firstOuterIdx][firstInnerIdx + 2 * CHUNK_SIZE] = + m_edges[lastOuterIdx][lastInnerIdx + 2 * CHUNK_SIZE]; + m_edges[firstOuterIdx][firstInnerIdx + 3 * CHUNK_SIZE] = + m_edges[lastOuterIdx][lastInnerIdx + 3 * CHUNK_SIZE]; + + m_groupIndices[firstOuterIdx][firstInnerIdx] = + m_groupIndices[lastOuterIdx][lastInnerIdx]; + m_overlapBits[firstOuterIdx][firstInnerIdx] = + m_overlapBits[lastOuterIdx][lastInnerIdx]; + + // Update the group index at the last index to be a 0, which now + // marks it as a "this doesn't need to stay" rectangle. This allows + // it to act as a sentinel value for the loop where we increment + // firstRectangleIndex so it can avoid an extra bounds check. + m_groupIndices[lastOuterIdx][lastInnerIdx] = 0; + } + + // Because of that zero, we're now guaranteed that there + // is a rectangle that should be removed to the right of the first index + // and one that should stay to the left of the last index (minimally, + // the ones we just adjusted), so these inner loops do not need to + // bounds check. + do + { + ++firstIdx; + assert(firstIdx < m_rectangleCount); + } while (m_groupIndices[firstIdx / CHUNK_SIZE][firstIdx % CHUNK_SIZE] != + 0); + + do + { + --lastIdx; + // NOTE: This assert seems backwards, but it's an unsigned variable + // and will wrap past zero, and thus go *very* positive. + assert(lastIdx < m_rectangleCount); + } while (m_groupIndices[lastIdx / CHUNK_SIZE][lastIdx % CHUNK_SIZE] == + 0); + } + + // firstRectangleIndex now points to the first rectangle that needs to be + // removed, which means it is also our new rectangle count. + m_rectangleCount = firstIdx; + auto vectorElementCount = (m_rectangleCount + CHUNK_SIZE - 1) / CHUNK_SIZE; + m_edges.resize(vectorElementCount); + m_groupIndices.resize(vectorElementCount); + m_overlapBits.resize(vectorElementCount); + + if (vectorElementCount > 0 && (m_rectangleCount % CHUNK_SIZE) != 0) + { + auto& lastEdges = m_edges.back(); + auto& lastGroupIndices = m_groupIndices.back(); + auto& lastOverlapBits = m_overlapBits.back(); + + constexpr auto DEFAULT_EDGE_EXTENT = TILE_DIM + TILE_EDGE_BIAS; + + // We have a chunk with potentially some boxes that had entries that + // shouldn't anymore, so clear them. + for (auto i = (m_rectangleCount % CHUNK_SIZE); i < CHUNK_SIZE; i++) + { + lastEdges[i + 0 * CHUNK_SIZE] = DEFAULT_EDGE_EXTENT; + lastEdges[i + 1 * CHUNK_SIZE] = DEFAULT_EDGE_EXTENT; + lastEdges[i + 2 * CHUNK_SIZE] = DEFAULT_EDGE_EXTENT; + lastEdges[i + 3 * CHUNK_SIZE] = DEFAULT_EDGE_EXTENT; + lastGroupIndices[i] = 0; + lastOverlapBits[i] = 0; + } + } +} + +template +IntersectionTile::FindResult IntersectionTile::findMaxIntersectingGroupIndex( + int4 ltrb, + FindResult running) const { assert(simd::all(ltrb.xy < ltrb.zw)); // Ensure ltrb isn't zero or negative. // Since we mask non-intersecting groupIndices to zero, the "mask and max" - // algorithm is only correct for positive values. (runningMaxGroupIndices is - // only signed because SSE doesn't have an unsigned max instruction.) - assert(simd::all(runningMaxGroupIndices >= 0)); + // algorithm is only correct for positive values. (running.maxGroupIndices + // is only signed because SSE pre 4.1 doesn't have an unsigned max + // instruction.) + assert(simd::all(running.maxGroupIndices >= 0)); assert(m_baselineGroupIndex >= 0); assert(m_maxGroupIndex >= m_baselineGroupIndex); // Translate ltrb to our tile and negate the left and top sides. ltrb -= m_topLeft; - ltrb.xy = 255 - ltrb.xy; // left = 255 - left, top = 255 - top + // left = TILE_DIM - left, top = TILE_DIM - top + ltrb.xy = TILE_DIM - ltrb.xy; assert( simd::all(ltrb > 0)); // Ensure ltrb isn't completely outside the tile. - ltrb = simd::min(ltrb, int4(255)); // Clamp ltrb to our tile. + ltrb = simd::min(ltrb, int4(TILE_DIM)); // Clamp ltrb to our tile. - if (simd::all(ltrb == 255)) + if (simd::all(ltrb == TILE_DIM)) { - // ltrb covers the entire -- we know it intersects with every rectangle. - runningMaxGroupIndices[0] = - std::max(runningMaxGroupIndices[0], m_maxGroupIndex); - return runningMaxGroupIndices; + // ltrb covers the tile -- we know it intersects with every rectangle. + if constexpr (Type == GroupingType::overlapAllowed) + { + auto currentMax = running.maxGroupIndices[0]; + if (currentMax < m_maxGroupIndex) + { + // The first element's max group index is changing, so restart + // its overlap bits with the new set. + running.maxGroupIndices[0] = m_maxGroupIndex; + running.overlapBits[0] = m_overlapBitsForMaxGroup; + } + else if (currentMax == m_maxGroupIndex) + { + // The group index of this element is the same, so just add in + // any new overlap bits that might exist. + running.overlapBits[0] |= m_overlapBitsForMaxGroup; + } + } + else + { + static_assert(Type == GroupingType::disjoint); + + running.maxGroupIndices[0] = + std::max(running.maxGroupIndices[0], m_maxGroupIndex); + } + + return running; } // Intersection test: l0 < r1 && @@ -128,18 +559,32 @@ int16x8 IntersectionTile::findMaxIntersectingGroupIndex( // m_edges are already encoded like the left column, so encode "ltrb" like // the right. // - // Bias ltrb by -128 so we can use int8_t. SSE doesn't have an unsigned byte - // compare. - int4 biased = ltrb + std::numeric_limits::min(); + // Bias ltrb so we can use int8_t. SSE (pre-4.1) doesn't have an unsigned + // byte compare. + int4 biased = ltrb + TILE_EDGE_BIAS; int8x8 r = biased.z; int8x8 b = biased.w; - int8x8 _l = biased.x; // Already converted to "255 - left" above. - int8x8 _t = biased.y; // Already converted to "255 - top" above. + int8x8 _l = biased.x; // Already converted to "TILE_DIM - left" above. + int8x8 _t = biased.y; // Already converted to "TILE_DIM - top" above. + + assert(m_edges.size() == m_groupIndices.size()); + if constexpr (Type == GroupingType::overlapAllowed) + { + assert(m_edges.size() == m_overlapBits.size()); + } #if !defined(FALLBACK_ON_SSE2_INTRINSICS) auto edges = m_edges.begin(); auto groupIndices = m_groupIndices.begin(); - assert(m_edges.size() == m_groupIndices.size()); + const uint16x8* groupOverlapBits = nullptr; + + // We only care about groupOverlapBits if this rectangle overlap testing is + // enabled *and* there are non-zero overlap bits in the mix + if constexpr (Type == GroupingType::overlapAllowed) + { + groupOverlapBits = m_overlapBits.data(); + } + PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() int8x32 complement = simd::join(r, b, _l, _t); for (; edges != m_edges.end(); ++edges, ++groupIndices) { @@ -161,19 +606,58 @@ int16x8 IntersectionTile::findMaxIntersectingGroupIndex( // Mask out any groupIndices we don't intersect with so they don't // participate in the test for maximum groupIndex. int16x8 maskedGroupIndices = isectMasks16 & *groupIndices; - runningMaxGroupIndices = - simd::max(maskedGroupIndices, runningMaxGroupIndices); + + // Doing this as a compile-time check to not have to do the test in the + // loop at runtime. + if constexpr (Type == GroupingType::overlapAllowed) + { + // Clear any bits from the running overlap where the new index is + // covering it (i.e. there's a new closest group index) + auto keepRunningBits = + (maskedGroupIndices <= running.maxGroupIndices); + running.overlapBits &= keepRunningBits; + + // Keep any bits from the current group where the running index is + // not closer (i.e. where current is not covered). + // Note: this will additionally keep bits where there has not yet + // been an intersection (index is 0), and the current rectangle was + // not intersected. This is fine - these bits will get cleared by + // the above code when a rectangle intersection finally *does* + // happen, so we can save on an additional mask with isectMask16. + auto keepCurrentBits = + (running.maxGroupIndices <= maskedGroupIndices); + auto maskedOverlapBits = *groupOverlapBits & keepCurrentBits; + + // Combine the two sets, ultimately this will add bits from + // overlapping rectangles that are in the new-highest draw group and + // clear any bits that are not. + running.overlapBits |= maskedOverlapBits; + + ++groupOverlapBits; + } + + running.maxGroupIndices = + simd::max(maskedGroupIndices, running.maxGroupIndices); } + POP_DISABLE_CLANG_SIMD_ABI_WARNING() + #else // MSVC doesn't get good codegen for the above loop. Provide direct SSE // intrinsics. const __m128i* edgeData = reinterpret_cast(m_edges.data()); const __m128i* groupIndices = reinterpret_cast(m_groupIndices.data()); + const __m128i* groupOverlapBits = nullptr; + if constexpr (Type == GroupingType::overlapAllowed) + { + groupOverlapBits = + reinterpret_cast(m_overlapBits.data()); + } __m128i complementLO = math::bit_cast<__m128i>(simd::join(r, b)); __m128i complementHI = math::bit_cast<__m128i>(simd::join(_l, _t)); __m128i localMaxGroupIndices = - math::bit_cast<__m128i>(runningMaxGroupIndices); + math::bit_cast<__m128i>(running.maxGroupIndices); + auto localOverlapBits = math::bit_cast<__m128i>(running.overlapBits); for (size_t i = 0; i < m_groupIndices.size(); ++i) { __m128i edgesLO = edgeData[i * 2]; @@ -192,19 +676,81 @@ int16x8 IntersectionTile::findMaxIntersectingGroupIndex( __m128i isectMasks16 = _mm_and_si128(partialIsectMasksLR16, partialIsectMasksTB16); // Mask out the groupIndices that don't intersect. - __m128i intersectingGroupIndices = + __m128i maskedGroupIndices = _mm_and_si128(isectMasks16, groupIndices[i]); + + // Doing this as a compile-time check to not have to do the test in the + // loop at runtime. + if constexpr (Type == GroupingType::overlapAllowed) + { + // Clear any bits from the running overlap where the new index is + // covering it (i.e. there's a new closest group index) + // NOTE: that masks and the "and"s are reversed from the non-SSE2 + // code above: SSE2 does not have integral >= or <= operations, so + // the formulation here uses "!(a > b)" as equivalent to (a <= b), + // thankfully using no additional instructions thanks to the + // existence of "andnot" instructions. + auto clearRunningBits = + _mm_cmpgt_epi16(maskedGroupIndices, localMaxGroupIndices); + + // andnot is (~a & b) so clearRunningBits needs to come first as + // it's what we intend to negate + localOverlapBits = + _mm_andnot_si128(clearRunningBits, localOverlapBits); + + // Keep any bits from the current group where the running index is + // not closer (i.e. where current is not covered). + // Note: this will additionally keep bits where there has not yet + // been an intersection (index is 0), and the current rectangle was + // not intersected. This is fine - these bits will get cleared by + // the above code when a rectangle intersection finally *does* + // happen, so we can save on an additional mask with isectMask16. + auto clearCurrentBits = + _mm_cmpgt_epi16(localMaxGroupIndices, maskedGroupIndices); + auto maskedOverlapBits = + _mm_andnot_si128(clearCurrentBits, groupOverlapBits[i]); + + // Combine the two sets, ultimately this will add bits from + // overlapping rectangles that are in the new-highest draw group and + // clear any bits that are not. + localOverlapBits = + _mm_or_si128(localOverlapBits, maskedOverlapBits); + } + // Accumulate max intersecting groupIndices. localMaxGroupIndices = - _mm_max_epi16(intersectingGroupIndices, localMaxGroupIndices); + _mm_max_epi16(maskedGroupIndices, localMaxGroupIndices); } - runningMaxGroupIndices = math::bit_cast(localMaxGroupIndices); + running.maxGroupIndices = math::bit_cast(localMaxGroupIndices); + + if constexpr (Type == GroupingType::overlapAllowed) + { + running.overlapBits = math::bit_cast(localOverlapBits); + } + #endif // !FALLBACK_ON_SSE2_INTRINSICS // Ensure we never drop below our baseline index. - runningMaxGroupIndices[0] = - std::max(runningMaxGroupIndices[0], m_baselineGroupIndex); - return runningMaxGroupIndices; + if constexpr (Type == GroupingType::overlapAllowed) + { + if (running.maxGroupIndices[0] < m_baselineGroupIndex) + { + // We're bumping this entry up so the overlap bits need to + // be cleared. + running.maxGroupIndices[0] = m_baselineGroupIndex; + running.overlapBits[0] = m_baselineOverlapBits; + } + else if (running.maxGroupIndices[0] == m_baselineGroupIndex) + { + running.overlapBits[0] |= m_baselineOverlapBits; + } + } + else + { + running.maxGroupIndices[0] = + std::max(running.maxGroupIndices[0], m_baselineGroupIndex); + } + return running; } void IntersectionBoard::resizeAndReset(uint32_t viewportWidth, @@ -213,8 +759,8 @@ void IntersectionBoard::resizeAndReset(uint32_t viewportWidth, m_viewportSize = int2{static_cast(viewportWidth), static_cast(viewportHeight)}; - // Divide the board into 255x255 tiles. - int2 dims = (m_viewportSize + 254) / 255; + // Divide the board into TILE_DIM x TILE_DIM tiles. + int2 dims = (m_viewportSize + TILE_DIM - 1) / TILE_DIM; m_cols = dims.x; m_rows = dims.y; if (m_tiles.size() < m_cols * m_rows) @@ -226,14 +772,49 @@ void IntersectionBoard::resizeAndReset(uint32_t viewportWidth, { for (int x = 0; x < m_cols; ++x) { - tileIter->reset(x * 255, y * 255); + tileIter->reset(x * TILE_DIM, y * TILE_DIM); ++tileIter; } } } -int16_t IntersectionBoard::addRectangle(int4 ltrb, int16_t layerCount) +int16_t IntersectionBoard::addRectangle(int4 ltrb, + uint16_t currentRectangleOverlapBits, + uint16_t disallowOverlapMask, + int16_t layerCount) +{ + switch (m_groupingType) + { + case GroupingType::overlapAllowed: + return addRectangle( + ltrb, + currentRectangleOverlapBits, + disallowOverlapMask, + layerCount); + case GroupingType::disjoint: + return addRectangle( + ltrb, + currentRectangleOverlapBits, + disallowOverlapMask, + layerCount); + } + + RIVE_UNREACHABLE(); +} + +template +int16_t IntersectionBoard::addRectangle(int4 ltrb, + uint16_t currentRectangleOverlapBits, + uint16_t disallowedOverlapBitsMask, + int16_t layerCount) { + if constexpr (Type == GroupingType::overlapAllowed) + { + assert( + layerCount == 1 && + "rectangles that are allowed to overlap should only be a single layer"); + } + // Discard empty, negative, or offscreen rectangles. if (simd::any(ltrb.xy >= m_viewportSize || ltrb.zw <= 0 || ltrb.xy >= ltrb.zw)) @@ -246,42 +827,103 @@ int16_t IntersectionBoard::addRectangle(int4 ltrb, int16_t layerCount) ltrb.zw = simd::min(ltrb.zw, m_viewportSize); // Find the tiled row and column that each corner of the rectangle falls on. - int4 span = (ltrb - int4{0, 0, 1, 1}) / 255; + int4 span = (ltrb - int4{0, 0, 1, 1}) / TILE_DIM; span = simd::clamp(span, int4(0), int4{m_cols, m_rows, m_cols, m_rows} - 1); assert(simd::all(span.xy <= span.zw)); // Accumulate the max groupIndex from each tile the rectangle touches. - int16x8 maxGroupIndices = 0; + IntersectionTile::FindResult results; for (int y = span.y; y <= span.w; ++y) { auto tileIter = m_tiles.begin() + y * m_cols + span.x; for (int x = span.x; x <= span.z; ++x) { - maxGroupIndices = - tileIter->findMaxIntersectingGroupIndex(ltrb, maxGroupIndices); + results = + tileIter->findMaxIntersectingGroupIndex(ltrb, results); ++tileIter; } } // Find the absolute max group index this rectangle intersects with. - int16_t maxIntersectingGroupIndex = simd::reduce_max(maxGroupIndices); + int16_t bottomGroupIndex = simd::reduce_max(results.maxGroupIndices); // It is the caller's responsibility to not insert more rectangles than can // fit in a signed 16-bit integer. - assert(maxIntersectingGroupIndex <= + assert(bottomGroupIndex <= std::numeric_limits::max() - layerCount); + if constexpr (Type == GroupingType::overlapAllowed) + { + // Clear bits of anything that wasn't in our max draw group, they don't + // matter (there's already a barrier between them) + auto overlapMask = (results.maxGroupIndices == bottomGroupIndex); + results.overlapBits &= overlapMask; + + // Now doing this reduce will give just the bits related to things we + // overlapped. + int16_t allOverlapBits = simd::reduce_or(results.overlapBits); + if ((allOverlapBits & disallowedOverlapBitsMask) != 0) + { + // Bits were set in any overlapping rectangle that prevent an + // overlap here, so we cannot stay in the same group. + bottomGroupIndex++; + } + else + { + bottomGroupIndex = std::max(bottomGroupIndex, int16_t(1)); + } + } + else + { + // With no overlapping allowed, always start in the next group up from + // the lowest one we intersected (or 1, if no intersection occurred) + bottomGroupIndex++; + } + // Add the rectangle and its newly-found groupIndex to each tile it touches. - int16_t finalLayerGroupIndex = maxIntersectingGroupIndex + layerCount; + int16_t topGroupIndex = bottomGroupIndex + layerCount - 1; for (int y = span.y; y <= span.w; ++y) { auto tileIter = m_tiles.begin() + y * m_cols + span.x; for (int x = span.x; x <= span.z; ++x) { - tileIter->addRectangle(ltrb, finalLayerGroupIndex); + tileIter->addRectangle(ltrb, + topGroupIndex, + currentRectangleOverlapBits); ++tileIter; } } - return maxIntersectingGroupIndex + 1; + return bottomGroupIndex; } + +// Explicitly instantiate the public template methods to ensure they get linked + +template IntersectionTile::FindResult IntersectionTile:: + findMaxIntersectingGroupIndex( + int4 ltrb, + FindResult running) const; +template IntersectionTile::FindResult IntersectionTile:: + findMaxIntersectingGroupIndex( + int4 ltrb, + FindResult running) const; + +template void IntersectionTile::addRectangle( + int4 ltrb, + int16_t groupIndex, + uint16_t overlapBits); +template void IntersectionTile::addRectangle( + int4 ltrb, + int16_t groupIndex, + uint16_t overlapBits); + +#ifdef WITH_RIVE_TOOLS +template void IntersectionTile::testingOnly_addRectangleAndValidate< + GroupingType::disjoint>(int4 ltrb, + int16_t groupIndex, + uint16_t overlapBits); +template void IntersectionTile::testingOnly_addRectangleAndValidate< + GroupingType::overlapAllowed>(int4 ltrb, + int16_t groupIndex, + uint16_t overlapBits); +#endif } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/intersection_board.hpp b/thirdparty/rive_renderer/source/intersection_board.hpp index 9cce93bec..4ea3df969 100644 --- a/thirdparty/rive_renderer/source/intersection_board.hpp +++ b/thirdparty/rive_renderer/source/intersection_board.hpp @@ -5,48 +5,131 @@ #pragma once #include "rive/math/simd.hpp" +#include "rive/enums.hpp" #include namespace rive::gpu { -// 255 x 255 tile that manages a set of rectangles and their groupIndex. -// From a given rectangle, finds the max groupIndex in the set of internal -// rectangles it intersects. The size is 255 so we can store bounding box -// coordinates in 8 bits. + +// Adding rectangles allows a grouping type to be specified - this determines +// whether a rectangle is allowed to share a group with another that it +// overlaps. +enum class GroupingType : bool +{ + // The current rectangle cannot be grouped with any others for any reason, + // so no additional testing/logic is necessary. (this is the default for + // most render modes) + disjoint, + + // The current rectangle is potentially allowed to group with others it + // overlaps, assuming the test of "overlap bits" succeeds. + overlapAllowed, +}; + +// Tile within an intersection board that manages a set of rectangles and their +// groupIndex. From a given rectangle, finds the max groupIndex in the set of +// internal rectangles it intersects and, when needed, also finds the full set +// of overlap bits from any interesections. The size is <= 255 so we can store +// bounding box coordinates in 8 bits. class IntersectionTile { public: - void reset(int left, int top, int16_t baselineGroupIndex = 0); + // The width and height of an intersection tile (must fit in an unsigned + // byte). + constexpr static int TILE_DIM = 255; + static_assert(TILE_DIM <= std::numeric_limits::max()); - void addRectangle(int4 ltrb, int16_t groupIndex); + // Performance is better passing these two vectors as a struct than using + // in/out parameters. + struct FindResult + { + int16x8 maxGroupIndices = 0; + uint16x8 overlapBits = 0; + }; + + void reset(int left, + int top, + int16_t baselineGroupIndex = 0, + uint16_t baselineOverlapBits = 0); + + template + void addRectangle(int4 ltrb, + int16_t groupIndex, + uint16_t currentRectangleOverlapBits); + +#ifdef WITH_RIVE_TOOLS + // a testing-specific version that validates after doing the add + template + void testingOnly_addRectangleAndValidate( + int4 ltrb, + int16_t groupIndex, + uint16_t currentRectangleOverlapBits); +#endif // Accumulate local maximum intersecting group indices for the given // rectangle in each channel of a int16x8. "runningMaxGroupIndices" is a // running set of local maximums if the IntersectionBoard also ran this same // test on other tile(s) that the rectangle touched. The absolute maximum // group index that this rectangle intersects with will be - // simd::reduce_max(returnValue). - int16x8 findMaxIntersectingGroupIndex(int4 ltrb, - int16x8 runningMaxGroupIndices) const; + // simd::reduce_max(result.maxGroupIndices), and the relevant overlap bits + // will be simd::reduce_or(result.overlapBits) + template + FindResult findMaxIntersectingGroupIndex(int4 ltrb, + FindResult runningResult) const; + + // The following were exposed for unit testing + +#ifdef WITH_RIVE_TOOLS + size_t testingOnly_rectangleCount() const { return m_rectangleCount; } + int16_t testingOnly_baselineGroupIndex() const + { + return m_baselineGroupIndex; + } + uint16_t testingOnly_baselineOverlapBits() const + { + return m_baselineOverlapBits; + } + + int16_t testingOnly_maxGroupIndex() const { return m_maxGroupIndex; } + uint16_t testingOnly_overlapBitsForMaxGroup() const + { + return m_overlapBitsForMaxGroup; + } +#endif private: - int4 m_topLeft; - int16_t m_baselineGroupIndex; - int16_t m_maxGroupIndex; + // Set the baseline to equal the current max group index + template + void updateBaselineToMaxGroupIndex(uint16_t additionalBaselineOverlapBits); + + int4 m_topLeft = {}; + int16_t m_baselineGroupIndex = 0; + uint16_t m_baselineOverlapBits = 0; + int16_t m_maxGroupIndex = 0; + uint16_t m_overlapBitsForMaxGroup = 0; size_t m_rectangleCount = 0; + // We may need a bias to get the tile coordinates to fit within a signed + // 8-bit value (because base-level SSE does not have unsigned comparisons) + constexpr static int TILE_EDGE_BIAS = + (TILE_DIM > std::numeric_limits::max()) ? -128 : 0; + // How many rectangles/groupIndices are in each chunk of data? - constexpr static size_t kChunkSize = 8; + constexpr static size_t CHUNK_SIZE = 8; - // Chunk of 8 rectangles encoded as [L, T, 255 - R, 255 - B], relative to - // m_left and m_top. The data is also transposed: [L0..L7, T0..T7, -R0..R7, - // -B0..B7]. + // Chunk of 8 rectangles encoded as [L, T, TILE_DIM - R, TILE_DIM - B], + // relative to m_left and m_top. The data is also transposed: + // [L0..L7, T0..T7, -R0..R7, -B0..B7]. std::vector m_edges; - static_assert(sizeof(m_edges[0]) == kChunkSize * 4); + static_assert(sizeof(m_edges[0]) == CHUNK_SIZE * 4); // Chunk of 8 groupIndices corresponding to the above edges. std::vector m_groupIndices; - static_assert(sizeof(m_groupIndices[0]) == kChunkSize * 2); + static_assert(sizeof(m_groupIndices[0]) == CHUNK_SIZE * 2); + + // Chunk of 8 sets of overlap bits corresponding to the above edges. + std::vector m_overlapBits; + static_assert(sizeof(m_overlapBits[0]) == CHUNK_SIZE * 2); }; // Manages a set of rectangles and their groupIndex across a variable-sized @@ -56,6 +139,11 @@ class IntersectionTile class IntersectionBoard { public: + constexpr static auto TILE_DIM = IntersectionTile::TILE_DIM; + + IntersectionBoard(GroupingType groupingType) : m_groupingType(groupingType) + {} + void resizeAndReset(uint32_t viewportWidth, uint32_t viewportHeight); // Adds a rectangle to the internal set and assigns it "layerCount" @@ -68,12 +156,32 @@ class IntersectionBoard // It is the caller's responsibility to not insert more rectangles than can // fit in a signed 16-bit integer. (The result is signed because SSE doesn't // have an unsigned max instruction.) - int16_t addRectangle(int4 ltrb, int16_t layerCount = 1); + int16_t addRectangle( + int4 ltrb, + uint16_t + currentRectangleOverlapBits, // "what is allowed to overlap me?" + uint16_t + disallowedOverlapBitsMask, // "what am I not allowed to overlap?" + int16_t layerCount); + + int16_t addRectangle(int4 ltrb, int16_t layerCount = 1) + { + return addRectangle(ltrb, 0, 0, layerCount); + } + + GroupingType groupingType() const { return m_groupingType; } private: - int2 m_viewportSize; - int32_t m_cols; - int32_t m_rows; + template + int16_t addRectangle(int4 ltrb, + uint16_t currentRectangleOverlapBits, + uint16_t disallowedOverlapBitsMask, + int16_t layerCount); + + GroupingType m_groupingType{}; + int2 m_viewportSize{}; + int32_t m_cols = 0; + int32_t m_rows = 0; std::vector m_tiles; }; } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/metal/background_shader_compiler.h b/thirdparty/rive_renderer/source/metal/background_shader_compiler.h index 00aa24eed..3e0993a43 100644 --- a/thirdparty/rive_renderer/source/metal/background_shader_compiler.h +++ b/thirdparty/rive_renderer/source/metal/background_shader_compiler.h @@ -14,8 +14,8 @@ namespace rive::gpu { -// Defines a job to compile a "draw" shader -- either draw_path.glsl or -// draw_image_mesh.glsl, with a specific set of features enabled. +// Defines a job to compile a "draw" shader, with a specific set of features +// enabled. struct BackgroundCompileJob { gpu::DrawType drawType; @@ -24,13 +24,13 @@ struct BackgroundCompileJob gpu::ShaderMiscFlags shaderMiscFlags; id compiledLibrary = nil; #ifdef WITH_RIVE_TOOLS - bool synthesizeCompilationFailure = false; + gpu::SynthesizedFailureType synthesizedFailureType = + gpu::SynthesizedFailureType::none; #endif }; -// Compiles "draw" shaders in a background thread. A "draw" shaders is either -// draw_path.glsl or draw_image_mesh.glsl, with a specific set of features -// enabled. +// Compiles "draw" shaders in a background thread, with a specific set of +// features enabled. class BackgroundShaderCompiler { public: diff --git a/thirdparty/rive_renderer/source/metal/background_shader_compiler.mm b/thirdparty/rive_renderer/source/metal/background_shader_compiler.mm index 9e7e478ba..e088025a3 100644 --- a/thirdparty/rive_renderer/source/metal/background_shader_compiler.mm +++ b/thirdparty/rive_renderer/source/metal/background_shader_compiler.mm @@ -6,11 +6,15 @@ #include "generated/shaders/metal.glsl.hpp" #include "generated/shaders/constants.glsl.hpp" +#include "generated/shaders/image_draw_uniforms.glsl.hpp" +#include "generated/shaders/flush_uniforms.glsl.hpp" #include "generated/shaders/common.glsl.hpp" #include "generated/shaders/advanced_blend.glsl.hpp" #include "generated/shaders/draw_path_common.glsl.hpp" -#include "generated/shaders/draw_path.glsl.hpp" -#include "generated/shaders/draw_image_mesh.glsl.hpp" +#include "generated/shaders/draw_path.vert.hpp" +#include "generated/shaders/draw_raster_order_path.frag.hpp" +#include "generated/shaders/draw_image_mesh.vert.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" #ifndef RIVE_IOS // iOS doesn't need the atomic shaders; every non-simulated iOS device supports @@ -26,7 +30,11 @@ { if (m_compilerThread.joinable()) { - m_shouldQuit = true; + { + std::lock_guard lock(m_mutex); + m_shouldQuit = true; + } + m_workAddedCondition.notify_all(); m_compilerThread.join(); } @@ -94,8 +102,8 @@ defines[@GLSL_FRAGMENT] = @""; for (size_t i = 0; i < gpu::kShaderFeatureCount; ++i) { - ShaderFeatures feature = static_cast(1 << i); - if (shaderFeatures & feature) + const auto feature = ShaderFeatures(1 << i); + if (enums::is_flag_set(shaderFeatures, feature)) { const char* macro = gpu::GetShaderFeatureGLSLName(feature); defines[[NSString stringWithUTF8String:macro]] = @"1"; @@ -110,13 +118,15 @@ { defines[@GLSL_PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED] = @""; } - if (shaderMiscFlags & - gpu::ShaderMiscFlags::fixedFunctionColorOutput) + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput)) { defines[@GLSL_FIXED_FUNCTION_COLOR_OUTPUT] = @""; } } - if (shaderMiscFlags & gpu::ShaderMiscFlags::clockwiseFill) + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clockwiseFill)) { defines[@GLSL_CLOCKWISE_FILL] = @"1"; } @@ -124,9 +134,16 @@ auto source = [[NSMutableString alloc] initWithCString:gpu::glsl::metal encoding:NSUTF8StringEncoding]; - [source - appendFormat:@"%s\n%s\n", gpu::glsl::constants, gpu::glsl::common]; - if (shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND) + [source appendFormat:@"%s\n%s\n%s\n", + gpu::glsl::constants, + gpu::glsl::flush_uniforms, + gpu::glsl::common]; + if (drawType == DrawType::imageRect || drawType == DrawType::imageMesh) + { + [source appendFormat:@"%s\n", gpu::glsl::image_draw_uniforms]; + } + if (enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_ADVANCED_BLEND)) { [source appendFormat:@"%s\n", gpu::glsl::advanced_blend]; } @@ -139,32 +156,12 @@ // Add baseInstance to the instanceID for path draws. defines[@GLSL_ENABLE_INSTANCE_INDEX] = @""; defines[@GLSL_DRAW_PATH] = @""; - [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; -#ifdef RIVE_IOS - [source appendFormat:@"%s\n", gpu::glsl::draw_path]; -#else - [source appendFormat:@"%s\n", - interlockMode == - gpu::InterlockMode::rasterOrdering - ? gpu::glsl::draw_path - : gpu::glsl::atomic_draw]; -#endif break; - case DrawType::atlasBlit: - defines[@GLSL_ATLAS_BLIT] = @"1"; - [[fallthrough]]; case DrawType::interiorTriangulation: defines[@GLSL_DRAW_INTERIOR_TRIANGLES] = @""; - [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; -#ifdef RIVE_IOS - [source appendFormat:@"%s\n", gpu::glsl::draw_path]; -#else - [source appendFormat:@"%s\n", - interlockMode == - gpu::InterlockMode::rasterOrdering - ? gpu::glsl::draw_path - : gpu::glsl::atomic_draw]; -#endif + break; + case DrawType::atlasBlit: + defines[@GLSL_ATLAS_BLIT] = @"1"; break; case DrawType::imageRect: #ifdef RIVE_IOS @@ -173,61 +170,45 @@ assert(interlockMode == InterlockMode::atomics); defines[@GLSL_DRAW_IMAGE] = @""; defines[@GLSL_DRAW_IMAGE_RECT] = @""; - [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; - [source appendFormat:@"%s\n", gpu::glsl::atomic_draw]; #endif break; case DrawType::imageMesh: defines[@GLSL_DRAW_IMAGE] = @""; defines[@GLSL_DRAW_IMAGE_MESH] = @""; -#ifdef RIVE_IOS - [source appendFormat:@"%s\n", gpu::glsl::draw_image_mesh]; -#else - if (interlockMode == gpu::InterlockMode::rasterOrdering) - { - [source appendFormat:@"%s\n", gpu::glsl::draw_image_mesh]; - } - else - { - [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; - [source appendFormat:@"%s\n", gpu::glsl::atomic_draw]; - } -#endif break; - case DrawType::atomicInitialize: + case DrawType::renderPassInitialize: #ifdef RIVE_IOS RIVE_UNREACHABLE(); #else assert(interlockMode == InterlockMode::atomics); defines[@GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS] = @""; defines[@GLSL_INITIALIZE_PLS] = @""; - if (shaderMiscFlags & gpu::ShaderMiscFlags::storeColorClear) + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::storeColorClear)) { defines[@GLSL_STORE_COLOR_CLEAR] = @""; } - if (shaderMiscFlags & - gpu::ShaderMiscFlags::swizzleColorBGRAToRGBA) + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::swizzleColorBGRAToRGBA)) { defines[@GLSL_SWIZZLE_COLOR_BGRA_TO_RGBA] = @""; } - [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; - [source appendFormat:@"%s\n", gpu::glsl::atomic_draw]; #endif break; - case DrawType::atomicResolve: + case DrawType::renderPassResolve: #ifdef RIVE_IOS RIVE_UNREACHABLE(); #else assert(interlockMode == InterlockMode::atomics); defines[@GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS] = @""; defines[@GLSL_RESOLVE_PLS] = @""; - if (shaderMiscFlags & - gpu::ShaderMiscFlags::coalescedResolveAndTransfer) + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::coalescedResolveAndTransfer)) { defines[@GLSL_COALESCED_PLS_RESOLVE_AND_TRANSFER] = @""; } - [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; - [source appendFormat:@"%s\n", gpu::glsl::atomic_draw]; #endif break; case DrawType::msaaStrokes: @@ -237,13 +218,58 @@ case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: RIVE_UNREACHABLE(); } - NSError* err = [NSError errorWithDomain:@"compile" - code:200 - userInfo:nil]; +#ifndef RIVE_IOS + if (interlockMode == gpu::InterlockMode::atomics) + { + [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; + [source appendFormat:@"%s\n", gpu::glsl::atomic_draw]; + } + else +#endif + { + assert(interlockMode == gpu::InterlockMode::rasterOrdering); + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + case DrawType::interiorTriangulation: + [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; + [source appendFormat:@"%s\n", gpu::glsl::draw_path_vert]; + [source + appendFormat:@"%s\n", + gpu::glsl::draw_raster_order_path_frag]; + break; + case DrawType::atlasBlit: + [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; + [source appendFormat:@"%s\n", gpu::glsl::draw_path_vert]; + [source appendFormat:@"%s\n", gpu::glsl::draw_mesh_frag]; + break; + case DrawType::imageMesh: + [source + appendFormat:@"%s\n", gpu::glsl::draw_image_mesh_vert]; + [source appendFormat:@"%s\n", gpu::glsl::draw_mesh_frag]; + break; + case DrawType::imageRect: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: + RIVE_UNREACHABLE(); + } + } + + NSError* err = nil; MTLCompileOptions* compileOptions = [MTLCompileOptions new]; #if defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR) compileOptions.languageVersion = @@ -259,7 +285,8 @@ } compileOptions.preprocessorMacros = defines; #ifdef WITH_RIVE_TOOLS - if (job.synthesizeCompilationFailure) + if (job.synthesizedFailureType == + SynthesizedFailureType::shaderCompilation) { assert(job.compiledLibrary == nil); } @@ -273,12 +300,13 @@ lock.lock(); - if (job.compiledLibrary == nil) + if (err != nil || job.compiledLibrary == nil) { #ifdef WITH_RIVE_TOOLS - if (job.synthesizeCompilationFailure) + if (job.synthesizedFailureType == + SynthesizedFailureType::shaderCompilation) { - fprintf(stderr, "Synthesizing shader compilation failure...\n"); + NSLog(@"RIVE: Synthesizing shader compilation failure..."); } else #endif @@ -291,15 +319,17 @@ std::string lineStr; while (std::getline(stream, lineStr, '\n')) { - fprintf(stderr, "%4i| %s\n", lineNumber++, lineStr.c_str()); + NSLog(@"RIVE: %4i| %s", lineNumber++, lineStr.c_str()); } - fprintf(stderr, "%s\n", err.localizedDescription.UTF8String); + NSLog(@"RIVE: Shader compilation error: %@", + err != nil ? err.localizedDescription : @""); } - fprintf(stderr, "Failed to compile shader.\n"); + NSLog(@"RIVE: Failed to compile shader."); assert(false #ifdef WITH_RIVE_TOOLS - || job.synthesizeCompilationFailure + || job.synthesizedFailureType == + SynthesizedFailureType::shaderCompilation #endif ); } diff --git a/thirdparty/rive_renderer/source/metal/render_context_metal_impl.mm b/thirdparty/rive_renderer/source/metal/render_context_metal_impl.mm index 3d53e0468..9448d5a8b 100644 --- a/thirdparty/rive_renderer/source/metal/render_context_metal_impl.mm +++ b/thirdparty/rive_renderer/source/metal/render_context_metal_impl.mm @@ -6,13 +6,16 @@ #include "background_shader_compiler.h" #include "rive/renderer/buffer_ring.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif #include "rive/renderer/texture.hpp" #include "rive/renderer/rive_render_buffer.hpp" #include "shaders/constants.glsl" #include -#include "generated/shaders/color_ramp.exports.h" -#include "generated/shaders/tessellate.exports.h" +#include "generated/shaders/color_ramp.glsl.exports.h" +#include "generated/shaders/tessellate.glsl.exports.h" #if defined(RIVE_IOS_SIMULATOR) #import @@ -39,15 +42,13 @@ static id make_pipeline_state( id gpu, MTLRenderPipelineDescriptor* desc) { - NSError* err = [NSError errorWithDomain:@"pipeline_create" - code:201 - userInfo:nil]; + NSError* err = nil; id state = [gpu newRenderPipelineStateWithDescriptor:desc error:&err]; - if (!state) + if (err != nil || state == nil) { - fprintf(stderr, "%s\n", err.localizedDescription.UTF8String); - abort(); + NSLog(@"RIVE: make_pipeline_state error %@", + err != nil ? err.localizedDescription : @""); } return state; } @@ -72,7 +73,7 @@ static MTLSamplerMinMagFilter min_mag_filter_for_image_filter( { switch (option) { - case ImageFilter::trilinear: + case ImageFilter::bilinear: return MTLSamplerMinMagFilterLinear; case ImageFilter::nearest: return MTLSamplerMinMagFilterNearest; @@ -85,9 +86,8 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) { switch (option) { - case ImageFilter::trilinear: - return MTLSamplerMipFilterLinear; case ImageFilter::nearest: + case ImageFilter::bilinear: return MTLSamplerMipFilterNearest; } @@ -152,7 +152,7 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) desc.vertexFunction = [plsLibrary newFunctionWithName:@GLSL_atlasVertexMain]; desc.fragmentFunction = [plsLibrary newFunctionWithName:fragmentMain]; - desc.colorAttachments[0].pixelFormat = MTLPixelFormatR32Float; + desc.colorAttachments[0].pixelFormat = MTLPixelFormatR16Float; desc.colorAttachments[0].blendingEnabled = TRUE; desc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; desc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOne; @@ -186,14 +186,14 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) { // Each feature corresponds to a specific index in the namespaceID. // These must stay in sync with generate_draw_combinations.py. - char namespaceID[] = "000000000"; + char namespaceID[] = "0000000000"; static_assert(sizeof(namespaceID) == gpu::kShaderFeatureCount + 1 /*DRAW_INTERIOR_TRIANGLES*/ + 1 /*ATLAS_BLIT*/ + 1 /*null terminator*/); for (size_t i = 0; i < gpu::kShaderFeatureCount; ++i) { - ShaderFeatures feature = static_cast(1 << i); - if (shaderFeatures & feature) + const auto feature = ShaderFeatures(1 << i); + if (enums::is_flag_set(shaderFeatures, feature)) { namespaceID[i] = '1'; } @@ -206,6 +206,7 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) 1 << 5); static_assert((int)ShaderFeatures::ENABLE_HSL_BLEND_MODES == 1 << 6); + static_assert((int)ShaderFeatures::ENABLE_DITHER == 1 << 7); } if (drawType == DrawType::interiorTriangulation) { @@ -226,7 +227,8 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) case DrawType::interiorTriangulation: case DrawType::atlasBlit: namespacePrefix = - (shaderMiscFlags & gpu::ShaderMiscFlags::clockwiseFill) + enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clockwiseFill) ? 'c' : 'p'; break; @@ -235,8 +237,6 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) case DrawType::imageMesh: namespacePrefix = 'm'; break; - case DrawType::atomicInitialize: - case DrawType::atomicResolve: case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -244,7 +244,9 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); } @@ -261,7 +263,12 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) gpu::DrawType drawType, gpu::InterlockMode interlockMode, gpu::ShaderFeatures shaderFeatures, - gpu::ShaderMiscFlags shaderMiscFlags) + gpu::ShaderMiscFlags shaderMiscFlags +#ifdef WITH_RIVE_TOOLS + , + gpu::SynthesizedFailureType synthesizedFailureType +#endif + ) { if (library == nil) { @@ -270,6 +277,14 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) return; } +#ifdef WITH_RIVE_TOOLS + if (synthesizedFailureType == SynthesizedFailureType::pipelineCreation) + { + NSLog(@"RIVE: Synthesizing pipeline creation failure..."); + return; + } +#endif + auto makePipelineState = [=](id vertexMain, id fragmentMain, MTLPixelFormat pixelFormat) { @@ -298,8 +313,9 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) // In atomic mode, the PLS planes are accessed as device // buffers. We only use the "framebuffer" attachment // configured above. - if (shaderMiscFlags & - gpu::ShaderMiscFlags::fixedFunctionColorOutput) + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput)) { // The shader expectes a "src-over" blend function in // order to to implement antialiasing and opacity. @@ -314,7 +330,7 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) framebuffer.alphaBlendOperation = MTLBlendOperationAdd; framebuffer.writeMask = MTLColorWriteMaskAll; } - else if (drawType == gpu::DrawType::atomicResolve) + else if (drawType == gpu::DrawType::renderPassResolve) { // We're resolving from the offscreen color buffer to // the framebuffer attachment. Write out the final color @@ -332,6 +348,7 @@ static MTLSamplerMipFilter mip_filter_for_image_filter(ImageFilter option) } break; + case gpu::InterlockMode::clockwise: case gpu::InterlockMode::clockwiseAtomic: case gpu::InterlockMode::msaa: RIVE_UNREACHABLE(); @@ -457,8 +474,8 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override m_platformFeatures.maxTextureSize = 8192; } #if defined(RIVE_IOS) || defined(RIVE_XROS) || defined(RIVE_APPLETVOS) - m_platformFeatures.supportsRasterOrdering = true; - m_platformFeatures.supportsFragmentShaderAtomics = false; + m_platformFeatures.supportsRasterOrderingMode = true; + m_platformFeatures.supportsAtomicMode = false; if (!is_apple_silicon(m_gpu)) { // The PowerVR GPU, at least on A10, has fp16 precision issues. We can't @@ -470,15 +487,29 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override defined(RIVE_APPLETVOS_SIMULATOR) // The simulator does not support framebuffer reads. Fall back on atomic // mode. - m_platformFeatures.supportsRasterOrdering = false; - m_platformFeatures.supportsFragmentShaderAtomics = true; + m_platformFeatures.supportsRasterOrderingMode = false; + m_platformFeatures.supportsAtomicMode = true; #else - m_platformFeatures.supportsRasterOrdering = + m_platformFeatures.supportsRasterOrderingMode = [m_gpu supportsFamily:MTLGPUFamilyApple1] && !contextOptions.disableFramebufferReads; - m_platformFeatures.supportsFragmentShaderAtomics = true; + m_platformFeatures.supportsAtomicMode = true; +#endif + m_platformFeatures.atomicPLSInitNeedsDraw = true; + + // Texture compression support varies by Apple platform family. +#if defined(RIVE_IOS) || defined(RIVE_XROS) || defined(RIVE_APPLETVOS) || \ + defined(RIVE_IOS_SIMULATOR) || defined(RIVE_XROS_SIMULATOR) || \ + defined(RIVE_APPLETVOS_SIMULATOR) + // iOS/tvOS/visionOS: ETC2 and ASTC are always supported. + m_platformFeatures.supportsTextureCompressionETC2 = true; + m_platformFeatures.supportsTextureCompressionASTC = true; +#else + // macOS: BC is always supported; ASTC only on Apple Silicon. + m_platformFeatures.supportsTextureCompressionBC = true; + m_platformFeatures.supportsTextureCompressionASTC = + [m_gpu supportsFamily:MTLGPUFamilyApple1]; #endif - m_platformFeatures.atomicPLSMustBeInitializedAsDraw = true; #if defined(RIVE_IOS) || defined(RIVE_XROS) || defined(RIVE_XROS_SIMULATOR) || \ defined(RIVE_APPLETVOS) || defined(RIVE_APPLETVOS_SIMULATOR) @@ -568,16 +599,14 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override #endif nil, nil); - NSError* err = [NSError errorWithDomain:@"metallib_load" - code:200 - userInfo:nil]; + NSError* err = nil; m_plsPrecompiledLibrary = [m_gpu newLibraryWithData:metallibData error:&err]; - if (m_plsPrecompiledLibrary == nil) + if (err != nil || m_plsPrecompiledLibrary == nil) { - fprintf(stderr, "Failed to load pls metallib.\n"); - fprintf(stderr, "%s\n", err.localizedDescription.UTF8String); - abort(); + NSLog(@"RIVE: Failed to load pls metallib error: %@", + err != nil ? err.localizedDescription : @""); + return; } m_colorRampPipeline = @@ -617,7 +646,7 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override // drawType in "rasterOrdering" mode. We load these at initialization and // use them while waiting for the background compiler to generate more // specialized, higher performance shaders. - if (m_platformFeatures.supportsRasterOrdering) + if (m_platformFeatures.supportsRasterOrderingMode) { for (auto drawType : {DrawType::midpointFanPatches, DrawType::interiorTriangulation, @@ -658,7 +687,12 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override drawType, gpu::InterlockMode::rasterOrdering, allShaderFeatures, - shaderMiscFlags); + shaderMiscFlags +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType::none +#endif + ); } } } @@ -716,7 +750,7 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override RenderTarget(width, height), m_gpu(gpu), m_pixelFormat(pixelFormat) { m_targetTexture = nil; // Will be configured later by setTargetTexture(). - if (platformFeatures.supportsRasterOrdering) + if (platformFeatures.supportsRasterOrderingMode) { m_coverageMemorylessTexture = make_pls_memoryless_texture( gpu, MTLPixelFormatR32Uint, width, height); @@ -752,7 +786,8 @@ void onUnmapAndSubmitBuffer(int bufferIdx, size_t mapSizeInBytes) override m_gpu(gpu) { int bufferCount = - flags() & RenderBufferFlags::mappedOnceAtInitialization + enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization) ? 1 : gpu::kBufferRingSize; for (int i = 0; i < bufferCount; ++i) @@ -827,7 +862,13 @@ void ensureMipmaps(id commandBuffer) const } } + // Adopt a pre-created MTLTexture (for RenderCanvas). + TextureMetalImpl(id texture, uint32_t width, uint32_t height) : + Texture(width, height), m_texture(texture), m_mipsDirty(false) + {} + id texture() const { return m_texture; } + void* nativeHandle() const override { return (__bridge void*)m_texture; } private: id m_texture; @@ -838,12 +879,50 @@ void ensureMipmaps(id commandBuffer) const uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) { + if (format != GPUTextureFormat::rgba32) + { + assert(!"unsupported format"); + return nullptr; + } + return make_rcp( m_gpu, width, height, mipLevelCount, imageDataRGBAPremul); } +#ifdef RIVE_CANVAS +rcp RenderContextMetalImpl::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + // Create an MTLTexture usable as both a render target and a shader-read + // image for compositing into Rive draws. + MTLTextureDescriptor* desc = [[MTLTextureDescriptor alloc] init]; + desc.pixelFormat = MTLPixelFormatRGBA8Unorm; + desc.width = width; + desc.height = height; + desc.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; + desc.textureType = MTLTextureType2D; + desc.mipmapLevelCount = 1; + desc.storageMode = MTLStorageModePrivate; + id mtlTexture = [m_gpu newTextureWithDescriptor:desc]; + + // Wrap as a RenderTarget for rendering into. + auto renderTarget = + makeRenderTarget(MTLPixelFormatRGBA8Unorm, width, height); + renderTarget->setTargetTexture(mtlTexture); + + // Wrap as a RiveRenderImage for compositing. The TextureMetalImpl adopt + // constructor takes a pre-created MTLTexture without uploading data. + auto texture = make_rcp(mtlTexture, width, height); + auto renderImage = make_rcp(std::move(texture)); + + return make_rcp(std::move(renderImage), + std::move(renderTarget)); +} +#endif + std::unique_ptr RenderContextMetalImpl::makeUniformBufferRing( size_t capacityInBytes) { @@ -909,7 +988,7 @@ void ensureMipmaps(id commandBuffer) const } MTLTextureDescriptor* desc = [[MTLTextureDescriptor alloc] init]; - desc.pixelFormat = MTLPixelFormatR32Float; + desc.pixelFormat = MTLPixelFormatR16Float; desc.width = width; desc.height = height; desc.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; @@ -945,22 +1024,28 @@ void ensureMipmaps(id commandBuffer) const // Find a fully-featured superset of features whose pipeline we can fall // back on while waiting for it to compile. ShaderFeatures fullyFeaturedPipelineFeatures = - gpu::ShaderFeaturesMaskFor(drawType, desc.interlockMode); - if (desc.interlockMode == gpu::InterlockMode::atomics) + gpu::UbershaderFeaturesMaskFor(shaderFeatures, + drawType, + desc.interlockMode, + shaderMiscFlags, + m_platformFeatures); + + if (m_contextOptions.shaderCompilationMode == + ShaderCompilationMode::onlyUbershaders) { - // Never add ENABLE_ADVANCED_BLEND to an atomic pipeline that doesn't - // use advanced blend, since in atomic mode, the shaders behave - // differently depending on whether advanced blend is enabled. - fullyFeaturedPipelineFeatures &= - shaderFeatures | ~ShaderFeatures::ENABLE_ADVANCED_BLEND; - // Never add ENABLE_CLIPPING to an atomic pipeline that doesn't use - // clipping; it will cause a "missing buffer binding" validation error - // because the shader will define an (unused) clipBuffer, but we won't - // bind anything to it. - fullyFeaturedPipelineFeatures &= - shaderFeatures | ~ShaderFeatures::ENABLE_CLIPPING; + // Force the shader features to be the full set if that's what was + // requested. + shaderFeatures = fullyFeaturedPipelineFeatures; } - shaderFeatures &= fullyFeaturedPipelineFeatures; + +#ifdef WITH_RIVE_TOOLS + if (desc.synthesizedFailureType == SynthesizedFailureType::ubershaderLoad) + { + // Pretend that the requested shader is not ready yet and the ubershader + // compilation failed + return nil; + } +#endif uint32_t pipelineKey = gpu::ShaderUniqueKey( drawType, shaderFeatures, desc.interlockMode, shaderMiscFlags); @@ -975,7 +1060,7 @@ void ensureMipmaps(id commandBuffer) const .interlockMode = desc.interlockMode, .shaderMiscFlags = shaderMiscFlags, #ifdef WITH_RIVE_TOOLS - .synthesizeCompilationFailure = desc.synthesizeCompilationFailures, + .synthesizedFailureType = desc.synthesizedFailureType, #endif }); pipelineIter = m_drawPipelines.insert({pipelineKey, nullptr}).first; @@ -995,7 +1080,8 @@ void ensureMipmaps(id commandBuffer) const BackgroundCompileJob job; bool shouldWaitForBackgroundCompilation = shaderFeatures == fullyFeaturedPipelineFeatures || - m_contextOptions.synchronousShaderCompilations; + m_contextOptions.shaderCompilationMode != + ShaderCompilationMode::allowAsynchronous; while (m_backgroundShaderCompiler->popFinishedJob( &job, shouldWaitForBackgroundCompilation)) { @@ -1011,7 +1097,12 @@ void ensureMipmaps(id commandBuffer) const job.drawType, job.interlockMode, job.shaderFeatures, - job.shaderMiscFlags); + job.shaderMiscFlags +#ifdef WITH_RIVE_TOOLS + , + desc.synthesizedFailureType +#endif + ); if (jobKey == pipelineKey) { // The shader we wanted was actually done compiling and pending @@ -1034,6 +1125,30 @@ void ensureMipmaps(id commandBuffer) const return pipelineIter->second.get(); } +void* RenderContextMetalImpl::makeCommandBuffer() +{ + if (m_commandQueue == nil) + { + return nullptr; + } + // __bridge_retained: transfers ARC ownership to the void* so it stays alive + // until commitCommandBuffer() releases it. + return (__bridge_retained void*)[m_commandQueue commandBuffer]; +} + +void RenderContextMetalImpl::commitCommandBuffer(void* commandBuffer) +{ + if (commandBuffer == nullptr) + { + return; + } + // __bridge_transfer: reclaims ARC ownership, balancing the + // __bridge_retained in makeCommandBuffer(). + id mtlCmdBuffer = + (__bridge_transfer id)commandBuffer; + [mtlCmdBuffer commit]; +} + void RenderContextMetalImpl::prepareToFlush(uint64_t nextFrameNumber, uint64_t safeFrameNumber) { @@ -1144,8 +1259,8 @@ static MTLScissorRect make_scissor(const TAABB& scissor) // separately. Since the PLS plane indices collide with other buffer // bindings, offset the binding indices of these buffers by // DEFAULT_BINDINGS_SET_SIZE. - if (!(baselineShaderMiscFlags & - gpu::ShaderMiscFlags::fixedFunctionColorOutput)) + if (!enums::is_flag_set(baselineShaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput)) { [encoder setFragmentBuffer:renderTarget->colorAtomicBuffer() @@ -1153,15 +1268,10 @@ static MTLScissorRect make_scissor(const TAABB& scissor) atIndex:METAL_BUFFER_IDX(COLOR_PLANE_IDX + DEFAULT_BINDINGS_SET_SIZE)]; } - if (flushDesc.combinedShaderFeatures & - gpu::ShaderFeatures::ENABLE_CLIPPING) - { - [encoder - setFragmentBuffer:renderTarget->clipAtomicBuffer() - offset:0 - atIndex:METAL_BUFFER_IDX(CLIP_PLANE_IDX + - DEFAULT_BINDINGS_SET_SIZE)]; - } + [encoder setFragmentBuffer:renderTarget->clipAtomicBuffer() + offset:0 + atIndex:METAL_BUFFER_IDX(CLIP_PLANE_IDX + + DEFAULT_BINDINGS_SET_SIZE)]; [encoder setFragmentBuffer:renderTarget->coverageAtomicBuffer() offset:0 atIndex:METAL_BUFFER_IDX(COVERAGE_PLANE_IDX + @@ -1176,6 +1286,7 @@ static MTLScissorRect make_scissor(const TAABB& scissor) void RenderContextMetalImpl::flush(const FlushDescriptor& desc) { + assert(desc.interlockMode != gpu::InterlockMode::clockwise); assert(desc.interlockMode != gpu::InterlockMode::clockwiseAtomic); assert(desc.interlockMode != gpu::InterlockMode::msaa); // TODO: msaa. @@ -1186,6 +1297,19 @@ static MTLScissorRect make_scissor(const TAABB& scissor) // Render the color ramps to the gradient texture. if (desc.gradSpanCount > 0) { + // We failed to load the precompiled library and therefore do not have + // the abililty to draw anything. + if (!m_colorRampPipeline) + { + return; + } + // We are removing the abort in the case this doesn't build. So give up + // drawing if we still don't have a pipeline here. + auto pipelineState = m_colorRampPipeline->pipelineState(); + if (!pipelineState) + { + return; + } MTLRenderPassDescriptor* gradPass = [MTLRenderPassDescriptor renderPassDescriptor]; gradPass.renderTargetWidth = kGradTextureWidth; @@ -1201,8 +1325,7 @@ static MTLScissorRect make_scissor(const TAABB& scissor) 0, kGradTextureWidth, static_cast(desc.gradDataHeight))]; - [gradEncoder - setRenderPipelineState:m_colorRampPipeline->pipelineState()]; + [gradEncoder setRenderPipelineState:pipelineState]; [gradEncoder setVertexBuffer:mtl_buffer(flushUniformBufferRing()) offset:desc.flushUniformDataOffsetInBytes @@ -1222,6 +1345,20 @@ static MTLScissorRect make_scissor(const TAABB& scissor) // Tessellate all curves into vertices in the tessellation texture. if (desc.tessVertexSpanCount > 0) { + // We failed to load the precompiled library and therefore do not have + // the abililty to draw anything. + if (!m_tessPipeline) + { + return; + } + // We are removing the abort in the case this doesn't build. So give up + // drawing if we still don't have a pipeline here. + auto pipelineState = m_tessPipeline->pipelineState(); + if (!pipelineState) + { + return; + } + MTLRenderPassDescriptor* tessPass = [MTLRenderPassDescriptor renderPassDescriptor]; tessPass.renderTargetWidth = kTessTextureWidth; @@ -1235,7 +1372,7 @@ static MTLScissorRect make_scissor(const TAABB& scissor) [tessEncoder setViewport:make_viewport( 0, 0, kTessTextureWidth, desc.tessDataHeight)]; - [tessEncoder setRenderPipelineState:m_tessPipeline->pipelineState()]; + [tessEncoder setRenderPipelineState:pipelineState]; [tessEncoder setVertexTexture:m_featherTexture atIndex:FEATHER_TEXTURE_IDX]; [tessEncoder @@ -1268,6 +1405,26 @@ static MTLScissorRect make_scissor(const TAABB& scissor) // Render the atlas if we have any offscreen feathers. if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0) { + // We failed to load the precompiled library and therefore do not have + // the abililty to draw anything. + if (!m_atlasStrokePipeline || !m_atlasFillPipeline) + { + return; + } + // We are removing the abort in the case this doesn't build. So give up + // drawing if we still don't have a pipeline here. + auto atlasFillpipelineState = m_atlasFillPipeline->pipelineState(); + if (!atlasFillpipelineState) + { + return; + } + + auto atlasStrokepipelineState = m_atlasStrokePipeline->pipelineState(); + if (!atlasStrokepipelineState) + { + return; + } + MTLRenderPassDescriptor* atlasPass = [MTLRenderPassDescriptor renderPassDescriptor]; atlasPass.renderTargetWidth = desc.atlasContentWidth; @@ -1324,12 +1481,11 @@ static MTLScissorRect make_scissor(const TAABB& scissor) [atlasEncoder setVertexBuffer:m_pathPatchVertexBuffer offset:0 atIndex:0]; - [atlasEncoder setCullMode:MTLCullModeBack]; if (desc.atlasFillBatchCount != 0) { - [atlasEncoder - setRenderPipelineState:m_atlasFillPipeline->pipelineState()]; + [atlasEncoder setCullMode:MTLCullModeNone]; + [atlasEncoder setRenderPipelineState:atlasFillpipelineState]; for (size_t i = 0; i < desc.atlasFillBatchCount; ++i) { const gpu::AtlasDrawBatch& fillBatch = desc.atlasFillBatches[i]; @@ -1354,8 +1510,8 @@ static MTLScissorRect make_scissor(const TAABB& scissor) if (desc.atlasStrokeBatchCount != 0) { - [atlasEncoder - setRenderPipelineState:m_atlasStrokePipeline->pipelineState()]; + [atlasEncoder setCullMode:MTLCullModeBack]; + [atlasEncoder setRenderPipelineState:atlasStrokepipelineState]; for (size_t i = 0; i < desc.atlasStrokeBatchCount; ++i) { const gpu::AtlasDrawBatch& strokeBatch = @@ -1450,13 +1606,8 @@ static MTLScissorRect make_scissor(const TAABB& scissor) pass.colorAttachments[COVERAGE_PLANE_IDX].storeAction = MTLStoreActionDontCare; } - else if (desc.atomicFixedFunctionColorOutput) - { - assert(desc.interlockMode == gpu::InterlockMode::atomics); - baselineShaderMiscFlags |= - gpu::ShaderMiscFlags::fixedFunctionColorOutput; - } - else if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget) + else if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget && + !desc.fixedFunctionColorOutput) { // Since we need to preserve the renderTarget during load, and since // we're rendering to an offscreen color buffer, we have to literally @@ -1491,28 +1642,36 @@ static MTLScissorRect make_scissor(const TAABB& scissor) for (const DrawBatch& batch : *desc.drawList) { // Setup the pipeline for this specific drawType and shaderFeatures. - gpu::ShaderFeatures shaderFeatures = - desc.interlockMode == gpu::InterlockMode::atomics - ? desc.combinedShaderFeatures - : batch.shaderFeatures; - gpu::ShaderMiscFlags batchMiscFlags = - baselineShaderMiscFlags | batch.shaderMiscFlags; - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && - (batch.drawContents & gpu::DrawContents::clockwiseFill)) + gpu::ShaderFeatures shaderFeatures; + if (desc.interlockMode == gpu::InterlockMode::atomics) + { + // The combined shader features might have more flags set than are + // actually relevant for this draw type, so filter them out. + shaderFeatures = + desc.combinedShaderFeatures & + gpu::ShaderFeaturesMaskFor(batch.drawType, desc.interlockMode); + } + else { - batchMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill; + shaderFeatures = batch.shaderFeatures; } - if (!(batchMiscFlags & gpu::ShaderMiscFlags::fixedFunctionColorOutput)) + + gpu::ShaderMiscFlags batchMiscFlags = + baselineShaderMiscFlags | batch.shaderMiscFlags; + if (!enums::is_flag_set(batchMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput)) { - if (batch.drawType == gpu::DrawType::atomicResolve) + if (batch.drawType == gpu::DrawType::renderPassResolve) { // Atomic mode can always do a coalesced resolve when rendering // to an offscreen color buffer. + assert(desc.interlockMode == gpu::InterlockMode::atomics); batchMiscFlags |= gpu::ShaderMiscFlags::coalescedResolveAndTransfer; } - else if (batch.drawType == gpu::DrawType::atomicInitialize) + else if (batch.drawType == gpu::DrawType::renderPassInitialize) { + assert(desc.interlockMode == gpu::InterlockMode::atomics); if (desc.colorLoadAction == gpu::LoadAction::clear) { batchMiscFlags |= gpu::ShaderMiscFlags::storeColorClear; @@ -1552,19 +1711,19 @@ static MTLScissorRect make_scissor(const TAABB& scissor) [encoder setFragmentSamplerState:m_imageSamplers[batch.imageSampler .asKey()] - atIndex:IMAGE_SAMPLER_IDX]; + atIndex:IMAGE_TEXTURE_IDX]; } else { [encoder setFragmentSamplerState: m_imageSamplers[ImageSampler::LINEAR_CLAMP_SAMPLER_KEY] - atIndex:IMAGE_SAMPLER_IDX]; + atIndex:IMAGE_TEXTURE_IDX]; } // Issue any barriers if needed. - if (batch.barriers & - (BarrierFlags::plsAtomic | BarrierFlags::plsAtomicPostInit | - BarrierFlags::plsAtomicPreResolve)) + if (enums::any_flag_set(batch.barriers, + BarrierFlags::plsAtomic | + BarrierFlags::plsAtomicPreResolve)) { assert(desc.interlockMode == gpu::InterlockMode::atomics); switch (m_metalFeatures.atomicBarrierType) @@ -1697,8 +1856,8 @@ static MTLScissorRect make_scissor(const TAABB& scissor) } break; } - case DrawType::atomicInitialize: - case DrawType::atomicResolve: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: { assert(desc.interlockMode == gpu::InterlockMode::atomics); [encoder setRenderPipelineState:drawPipelineState]; @@ -1714,7 +1873,7 @@ static MTLScissorRect make_scissor(const TAABB& scissor) case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: { RIVE_UNREACHABLE(); } diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_bind_group_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_bind_group_d3d11.cpp new file mode 100644 index 000000000..7003480f3 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_bind_group_d3d11.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_bind_group.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_buffer_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_buffer_d3d11.cpp new file mode 100644 index 000000000..5c968f6a5 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_buffer_d3d11.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/rive_types.hpp" + +#include + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + assert(m_d3d11Context != nullptr); + assert(m_d3d11Buffer != nullptr); + + // Always WRITE_DISCARD: it allocates fresh GPU memory and is safe + // for any update pattern, including the common dynamic-VB case + // where the GPU may still be reading the prior frame's contents. + // The previous code used `WRITE_NO_OVERWRITE` for vertex/index + // buffers as a perf optimization, which is undefined behavior per + // the D3D11 spec when overlapping with in-flight reads — the debug + // layer flags it. NO_OVERWRITE is only valid for append-style + // suballocation patterns Ore doesn't currently expose. + D3D11_MAPPED_SUBRESOURCE mapped{}; + [[maybe_unused]] HRESULT hr = m_d3d11Context->Map(m_d3d11Buffer.Get(), + 0, + D3D11_MAP_WRITE_DISCARD, + 0, + &mapped); + assert(SUCCEEDED(hr)); + memcpy(static_cast(mapped.pData) + offset, data, size); + m_d3d11Context->Unmap(m_d3d11Buffer.Get(), 0); +} + +void Buffer::onRefCntReachedZero() const { delete this; } + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_context_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_context_d3d11.cpp new file mode 100644 index 000000000..0e6e0fc48 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_context_d3d11.cpp @@ -0,0 +1,1591 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_context_d3d11.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/renderer/d3d11/render_context_d3d_impl.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include + +using Microsoft::WRL::ComPtr; + +namespace rive::ore +{ + +// ============================================================================ +// Enum -> DXGI / D3D11 conversion helpers +// ============================================================================ + +// Format info bundle: resource format (typeless for depth), SRV, RTV, DSV. +struct D3D11FormatInfo +{ + DXGI_FORMAT resource; // Texture resource format (typeless for depth). + DXGI_FORMAT srv; // SRV format for sampling. + DXGI_FORMAT rtv; // RTV format (UNKNOWN for depth). + DXGI_FORMAT dsv; // DSV format (UNKNOWN for color). + bool isDepth; +}; + +static D3D11FormatInfo oreFormatInfo(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return {DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rg8unorm: + return {DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba8unorm: + return {DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba8snorm: + return {DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::bgra8unorm: + return {DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba16float: + return {DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rg16float: + return {DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::r16float: + return {DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba32float: + return {DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rg32float: + return {DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::r32float: + return {DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgb10a2unorm: + return {DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::r11g11b10float: + return {DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + // Depth formats: typeless resource so both DSV and SRV are possible. + case TextureFormat::depth16unorm: + return {DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + true}; + case TextureFormat::depth24plusStencil8: + return {DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + true}; + case TextureFormat::depth32float: + return {DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT, + true}; + case TextureFormat::depth32floatStencil8: + return {DXGI_FORMAT_R32G8X24_TYPELESS, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + true}; + // Block-compressed (supported on D3D11 feature level 11.0). + case TextureFormat::bc1unorm: + return {DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::bc3unorm: + return {DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::bc7unorm: + return {DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + // ETC2/ASTC are not natively supported by D3D11. These are valid + // `TextureFormat` enum values that a Lua script can legitimately + // request, so we must NOT crash here — `d3d11MakeTexture` + // detects the `DXGI_FORMAT_UNKNOWN` resource sentinel and + // surfaces a clear `setLastError` instead. Per the + // `feedback_lua_gpu_misuse_validation` rule. + case TextureFormat::etc2rgb8: + case TextureFormat::etc2rgba8: + case TextureFormat::astc4x4: + case TextureFormat::astc6x6: + case TextureFormat::astc8x8: + return {DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + } + // C++ enum cast-from-int — not reachable from Lua (the bridge + // validates enum strings). Crash here is a programmer error. + RIVE_UNREACHABLE(); +} + +static D3D11_FILTER oreFilterToD3D(Filter min, + Filter mag, + Filter mip, + CompareFunction compare, + uint32_t aniso) +{ + bool isCompare = (compare != CompareFunction::none); + if (aniso > 1) + return isCompare ? D3D11_FILTER_COMPARISON_ANISOTROPIC + : D3D11_FILTER_ANISOTROPIC; + + // Build the filter from min/mag/mip combinations. + if (min == Filter::linear && mag == Filter::linear && mip == Filter::linear) + return isCompare ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR + : D3D11_FILTER_MIN_MAG_MIP_LINEAR; + if (min == Filter::linear && mag == Filter::linear && + mip == Filter::nearest) + return isCompare ? D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT + : D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; + if (min == Filter::linear && mag == Filter::nearest && + mip == Filter::linear) + return isCompare + ? D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR + : D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + if (min == Filter::linear && mag == Filter::nearest && + mip == Filter::nearest) + return isCompare ? D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT + : D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + if (min == Filter::nearest && mag == Filter::linear && + mip == Filter::linear) + return isCompare ? D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR + : D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; + if (min == Filter::nearest && mag == Filter::linear && + mip == Filter::nearest) + return isCompare + ? D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT + : D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + if (min == Filter::nearest && mag == Filter::nearest && + mip == Filter::linear) + return isCompare ? D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR + : D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + // nearest/nearest/nearest + return isCompare ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT + : D3D11_FILTER_MIN_MAG_MIP_POINT; +} + +static D3D11_TEXTURE_ADDRESS_MODE oreWrapToD3D(WrapMode mode) +{ + switch (mode) + { + case WrapMode::repeat: + return D3D11_TEXTURE_ADDRESS_WRAP; + case WrapMode::mirrorRepeat: + return D3D11_TEXTURE_ADDRESS_MIRROR; + case WrapMode::clampToEdge: + return D3D11_TEXTURE_ADDRESS_CLAMP; + } + RIVE_UNREACHABLE(); +} + +static D3D11_COMPARISON_FUNC oreCompareFunctionToD3D(CompareFunction fn) +{ + switch (fn) + { + case CompareFunction::none: + case CompareFunction::never: + return D3D11_COMPARISON_NEVER; + case CompareFunction::less: + return D3D11_COMPARISON_LESS; + case CompareFunction::equal: + return D3D11_COMPARISON_EQUAL; + case CompareFunction::lessEqual: + return D3D11_COMPARISON_LESS_EQUAL; + case CompareFunction::greater: + return D3D11_COMPARISON_GREATER; + case CompareFunction::notEqual: + return D3D11_COMPARISON_NOT_EQUAL; + case CompareFunction::greaterEqual: + return D3D11_COMPARISON_GREATER_EQUAL; + case CompareFunction::always: + return D3D11_COMPARISON_ALWAYS; + } + RIVE_UNREACHABLE(); +} + +static D3D11_BLEND oreBlendFactorToD3D(BlendFactor f) +{ + switch (f) + { + case BlendFactor::zero: + return D3D11_BLEND_ZERO; + case BlendFactor::one: + return D3D11_BLEND_ONE; + case BlendFactor::srcColor: + return D3D11_BLEND_SRC_COLOR; + case BlendFactor::oneMinusSrcColor: + return D3D11_BLEND_INV_SRC_COLOR; + case BlendFactor::srcAlpha: + return D3D11_BLEND_SRC_ALPHA; + case BlendFactor::oneMinusSrcAlpha: + return D3D11_BLEND_INV_SRC_ALPHA; + case BlendFactor::dstColor: + return D3D11_BLEND_DEST_COLOR; + case BlendFactor::oneMinusDstColor: + return D3D11_BLEND_INV_DEST_COLOR; + case BlendFactor::dstAlpha: + return D3D11_BLEND_DEST_ALPHA; + case BlendFactor::oneMinusDstAlpha: + return D3D11_BLEND_INV_DEST_ALPHA; + case BlendFactor::srcAlphaSaturated: + return D3D11_BLEND_SRC_ALPHA_SAT; + case BlendFactor::blendColor: + return D3D11_BLEND_BLEND_FACTOR; + case BlendFactor::oneMinusBlendColor: + return D3D11_BLEND_INV_BLEND_FACTOR; + } + RIVE_UNREACHABLE(); +} + +static D3D11_BLEND_OP oreBlendOpToD3D(BlendOp op) +{ + switch (op) + { + case BlendOp::add: + return D3D11_BLEND_OP_ADD; + case BlendOp::subtract: + return D3D11_BLEND_OP_SUBTRACT; + case BlendOp::reverseSubtract: + return D3D11_BLEND_OP_REV_SUBTRACT; + case BlendOp::min: + return D3D11_BLEND_OP_MIN; + case BlendOp::max: + return D3D11_BLEND_OP_MAX; + } + RIVE_UNREACHABLE(); +} + +static D3D11_STENCIL_OP oreStencilOpToD3D(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return D3D11_STENCIL_OP_KEEP; + case StencilOp::zero: + return D3D11_STENCIL_OP_ZERO; + case StencilOp::replace: + return D3D11_STENCIL_OP_REPLACE; + case StencilOp::incrementClamp: + return D3D11_STENCIL_OP_INCR_SAT; + case StencilOp::decrementClamp: + return D3D11_STENCIL_OP_DECR_SAT; + case StencilOp::invert: + return D3D11_STENCIL_OP_INVERT; + case StencilOp::incrementWrap: + return D3D11_STENCIL_OP_INCR; + case StencilOp::decrementWrap: + return D3D11_STENCIL_OP_DECR; + } + RIVE_UNREACHABLE(); +} + +static D3D11_CULL_MODE oreCullModeToD3D(CullMode mode) +{ + switch (mode) + { + case CullMode::none: + return D3D11_CULL_NONE; + case CullMode::front: + return D3D11_CULL_FRONT; + case CullMode::back: + return D3D11_CULL_BACK; + } + RIVE_UNREACHABLE(); +} + +static UINT8 oreColorWriteMaskToD3D(ColorWriteMask mask) +{ + UINT8 d3d = 0; + if ((mask & ColorWriteMask::red) != ColorWriteMask::none) + d3d |= D3D11_COLOR_WRITE_ENABLE_RED; + if ((mask & ColorWriteMask::green) != ColorWriteMask::none) + d3d |= D3D11_COLOR_WRITE_ENABLE_GREEN; + if ((mask & ColorWriteMask::blue) != ColorWriteMask::none) + d3d |= D3D11_COLOR_WRITE_ENABLE_BLUE; + if ((mask & ColorWriteMask::alpha) != ColorWriteMask::none) + d3d |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + return d3d; +} + +static DXGI_FORMAT oreVertexFormatToDXGI(VertexFormat fmt) +{ + switch (fmt) + { + case VertexFormat::float1: + return DXGI_FORMAT_R32_FLOAT; + case VertexFormat::float2: + return DXGI_FORMAT_R32G32_FLOAT; + case VertexFormat::float3: + return DXGI_FORMAT_R32G32B32_FLOAT; + case VertexFormat::float4: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case VertexFormat::uint8x4: + return DXGI_FORMAT_R8G8B8A8_UINT; + case VertexFormat::sint8x4: + return DXGI_FORMAT_R8G8B8A8_SINT; + case VertexFormat::unorm8x4: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case VertexFormat::snorm8x4: + return DXGI_FORMAT_R8G8B8A8_SNORM; + case VertexFormat::uint16x2: + return DXGI_FORMAT_R16G16_UINT; + case VertexFormat::sint16x2: + return DXGI_FORMAT_R16G16_SINT; + case VertexFormat::unorm16x2: + return DXGI_FORMAT_R16G16_UNORM; + case VertexFormat::snorm16x2: + return DXGI_FORMAT_R16G16_SNORM; + case VertexFormat::uint16x4: + return DXGI_FORMAT_R16G16B16A16_UINT; + case VertexFormat::sint16x4: + return DXGI_FORMAT_R16G16B16A16_SINT; + case VertexFormat::float16x2: + return DXGI_FORMAT_R16G16_FLOAT; + case VertexFormat::float16x4: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case VertexFormat::uint32: + return DXGI_FORMAT_R32_UINT; + case VertexFormat::uint32x2: + return DXGI_FORMAT_R32G32_UINT; + case VertexFormat::uint32x3: + return DXGI_FORMAT_R32G32B32_UINT; + case VertexFormat::uint32x4: + return DXGI_FORMAT_R32G32B32A32_UINT; + case VertexFormat::sint32: + return DXGI_FORMAT_R32_SINT; + case VertexFormat::sint32x2: + return DXGI_FORMAT_R32G32_SINT; + case VertexFormat::sint32x3: + return DXGI_FORMAT_R32G32B32_SINT; + case VertexFormat::sint32x4: + return DXGI_FORMAT_R32G32B32A32_SINT; + } + RIVE_UNREACHABLE(); +} + +// ============================================================================ +// D3D11 helper methods — always compiled (used by combined d3d11+d3d12 +// dispatch file). +// ============================================================================ + +// ============================================================================ +// d3d11MakeBuffer +// ============================================================================ + +rcp ContextD3D11::d3d11MakeBuffer(const BufferDesc& desc) +{ + if (desc.immutable && desc.data == nullptr) + { + setLastError( + "makeBuffer: immutable=true requires `data` (the buffer is " + "GPU-only after creation)"); + return nullptr; + } + + auto buffer = rcp(new Buffer(desc.size, desc.usage)); + buffer->m_d3d11Context = m_d3d11Context.Get(); + + D3D11_BUFFER_DESC bd{}; + bd.ByteWidth = desc.size; + if (desc.immutable) + { + // GPU-read-only, populated from initData. Fastest path on AMD — + // no CPU access flag means no shadow copy. + bd.Usage = D3D11_USAGE_IMMUTABLE; + bd.CPUAccessFlags = 0; + } + else + { + bd.Usage = D3D11_USAGE_DYNAMIC; + bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + } + + switch (desc.usage) + { + case BufferUsage::vertex: + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + break; + case BufferUsage::index: + bd.BindFlags = D3D11_BIND_INDEX_BUFFER; + break; + case BufferUsage::uniform: + // Constant buffers must be a multiple of 16 bytes. + bd.ByteWidth = (desc.size + 15u) & ~15u; + bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + break; + } + + D3D11_SUBRESOURCE_DATA initData{}; + initData.pSysMem = desc.data; + + HRESULT hr = m_d3d11Device->CreateBuffer( + &bd, + desc.data ? &initData : nullptr, + buffer->m_d3d11Buffer.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + { + setLastError("makeBuffer: CreateBuffer failed (hr=0x%08x, size=%u)", + static_cast(hr), + desc.size); + return nullptr; + } + + // Tag with the user's label so RenderDoc / PIX captures show it. + if (desc.label != nullptr) + { + buffer->m_d3d11Buffer->SetPrivateData( + WKPDID_D3DDebugObjectName, + static_cast(strlen(desc.label)), + desc.label); + } + + return buffer; +} + +// ============================================================================ +// d3d11MakeTexture +// ============================================================================ + +rcp ContextD3D11::d3d11MakeTexture(const TextureDesc& desc) +{ + const D3D11FormatInfo fmtInfo = oreFormatInfo(desc.format); + // ETC2 / ASTC have no native D3D11 path; `oreFormatInfo` returns + // an all-`DXGI_FORMAT_UNKNOWN` sentinel for those rather than + // crashing. Surface a clear error so a Lua script that asks for + // these on Windows gets a useful message instead of a generic null + // return. + if (fmtInfo.resource == DXGI_FORMAT_UNKNOWN) + { + setLastError("makeTexture: format %u (etc2*/astc*) has no native " + "D3D11 mapping; software-decode to rgba8unorm before " + "upload, or feature-gate via Features::etc2 / ::astc", + static_cast(desc.format)); + return nullptr; + } + + auto texture = rcp(new Texture(desc)); + texture->m_d3d11Context = m_d3d11Context.Get(); + + UINT bindFlags = D3D11_BIND_SHADER_RESOURCE; + if (fmtInfo.isDepth) + bindFlags |= D3D11_BIND_DEPTH_STENCIL; + else if (desc.renderTarget) + bindFlags |= D3D11_BIND_RENDER_TARGET; + + if (desc.type == TextureType::texture3D) + { + D3D11_TEXTURE3D_DESC td{}; + td.Width = desc.width; + td.Height = desc.height; + td.Depth = desc.depthOrArrayLayers; + td.MipLevels = desc.numMipmaps; + td.Format = fmtInfo.resource; + td.Usage = D3D11_USAGE_DEFAULT; + td.BindFlags = bindFlags; + + ComPtr tex3d; + HRESULT hr = + m_d3d11Device->CreateTexture3D(&td, nullptr, tex3d.GetAddressOf()); + if (FAILED(hr)) + return nullptr; + texture->m_d3d11Texture = tex3d; + } + else + { + D3D11_TEXTURE2D_DESC td{}; + td.Width = desc.width; + td.Height = desc.height; + td.MipLevels = desc.numMipmaps; + td.Format = fmtInfo.resource; + td.Usage = D3D11_USAGE_DEFAULT; + td.BindFlags = bindFlags; + td.SampleDesc.Count = desc.sampleCount; + td.SampleDesc.Quality = 0; + + if (desc.type == TextureType::cube) + { + td.ArraySize = 6; + td.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + } + else if (desc.type == TextureType::array2D) + { + td.ArraySize = desc.depthOrArrayLayers; + } + else + { + td.ArraySize = 1; + } + + ComPtr tex2d; + HRESULT hr = + m_d3d11Device->CreateTexture2D(&td, nullptr, tex2d.GetAddressOf()); + if (FAILED(hr)) + return nullptr; + texture->m_d3d11Texture = tex2d; + } + + // Tag with the user's label so RenderDoc / PIX captures show it. + if (desc.label != nullptr && texture->m_d3d11Texture) + { + texture->m_d3d11Texture->SetPrivateData( + WKPDID_D3DDebugObjectName, + static_cast(strlen(desc.label)), + desc.label); + } + + return texture; +} + +// ============================================================================ +// d3d11MakeTextureView +// ============================================================================ + +rcp ContextD3D11::d3d11MakeTextureView(const TextureViewDesc& desc) +{ + Texture* tex = desc.texture; + if (!tex) + return nullptr; + + auto view = rcp(new TextureView(ref_rcp(tex), desc)); + + const D3D11FormatInfo fmtInfo = oreFormatInfo(tex->format()); + + // --- Shader Resource View --- + if (fmtInfo.srv != DXGI_FORMAT_UNKNOWN) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{}; + srvDesc.Format = fmtInfo.srv; + + switch (desc.dimension) + { + case TextureViewDimension::texture2D: + if (tex->sampleCount() > 1) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } + else if (desc.layerCount > 1) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture2DArray.MipLevels = desc.mipCount; + srvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + srvDesc.Texture2DArray.ArraySize = desc.layerCount; + } + else + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture2D.MipLevels = desc.mipCount; + } + break; + case TextureViewDimension::cube: + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MostDetailedMip = desc.baseMipLevel; + srvDesc.TextureCube.MipLevels = desc.mipCount; + break; + case TextureViewDimension::cubeArray: + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + srvDesc.TextureCubeArray.MostDetailedMip = desc.baseMipLevel; + srvDesc.TextureCubeArray.MipLevels = desc.mipCount; + srvDesc.TextureCubeArray.First2DArrayFace = desc.baseLayer; + srvDesc.TextureCubeArray.NumCubes = desc.layerCount / 6; + break; + case TextureViewDimension::texture3D: + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Texture3D.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture3D.MipLevels = desc.mipCount; + break; + case TextureViewDimension::array2D: + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture2DArray.MipLevels = desc.mipCount; + srvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + srvDesc.Texture2DArray.ArraySize = desc.layerCount; + break; + } + + m_d3d11Device->CreateShaderResourceView( + tex->m_d3d11Texture.Get(), + &srvDesc, + view->m_d3dSRV.ReleaseAndGetAddressOf()); + } + + // --- Render Target View (color) --- + if (!fmtInfo.isDepth && tex->isRenderTarget() && + fmtInfo.rtv != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc{}; + rtvDesc.Format = fmtInfo.rtv; + + switch (desc.dimension) + { + case TextureViewDimension::texture2D: + if (tex->sampleCount() > 1) + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + } + // Use TEXTURE2DARRAY whenever targeting a specific array slice + // (baseLayer > 0) or multiple layers, because + // D3D11_RTV_DIMENSION_TEXTURE2D can only address slice 0. + // This covers cube-face RTVs where each face is a slice. + else if (desc.layerCount > 1 || desc.baseLayer > 0) + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = desc.baseMipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + rtvDesc.Texture2DArray.ArraySize = desc.layerCount; + } + else + { + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = desc.baseMipLevel; + } + break; + case TextureViewDimension::cube: + case TextureViewDimension::cubeArray: + case TextureViewDimension::array2D: + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = desc.baseMipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + rtvDesc.Texture2DArray.ArraySize = desc.layerCount; + break; + case TextureViewDimension::texture3D: + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = desc.baseMipLevel; + rtvDesc.Texture3D.FirstWSlice = desc.baseLayer; + rtvDesc.Texture3D.WSize = desc.layerCount; + break; + } + + m_d3d11Device->CreateRenderTargetView( + tex->m_d3d11Texture.Get(), + &rtvDesc, + view->m_d3dRTV.ReleaseAndGetAddressOf()); + } + + // --- Depth Stencil View --- + if (fmtInfo.isDepth && fmtInfo.dsv != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc{}; + dsvDesc.Format = fmtInfo.dsv; + if (tex->sampleCount() > 1) + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + } + else if (desc.dimension == TextureViewDimension::array2D || + (desc.dimension == TextureViewDimension::texture2D && + (desc.layerCount > 1 || desc.baseLayer > 0))) + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = desc.baseMipLevel; + dsvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + dsvDesc.Texture2DArray.ArraySize = desc.layerCount; + } + else + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = desc.baseMipLevel; + } + + m_d3d11Device->CreateDepthStencilView( + tex->m_d3d11Texture.Get(), + &dsvDesc, + view->m_d3dDSV.ReleaseAndGetAddressOf()); + } + + return view; +} + +// ============================================================================ +// d3d11MakeSampler +// ============================================================================ + +rcp ContextD3D11::d3d11MakeSampler(const SamplerDesc& desc) +{ + D3D11_SAMPLER_DESC sd{}; + sd.Filter = oreFilterToD3D(desc.minFilter, + desc.magFilter, + desc.mipmapFilter, + desc.compare, + desc.maxAnisotropy); + sd.AddressU = oreWrapToD3D(desc.wrapU); + sd.AddressV = oreWrapToD3D(desc.wrapV); + sd.AddressW = oreWrapToD3D(desc.wrapW); + sd.MipLODBias = 0.0f; + sd.MaxAnisotropy = desc.maxAnisotropy; + sd.ComparisonFunc = (desc.compare != CompareFunction::none) + ? oreCompareFunctionToD3D(desc.compare) + : D3D11_COMPARISON_NEVER; + sd.MinLOD = desc.minLod; + sd.MaxLOD = desc.maxLod; + + auto sampler = rcp(new Sampler()); + HRESULT hr = m_d3d11Device->CreateSamplerState( + &sd, + sampler->m_d3dSampler.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + return nullptr; + return sampler; +} + +// ============================================================================ +// d3d11MakeShaderModule +// ============================================================================ + +rcp ContextD3D11::d3d11MakeShaderModule( + const ShaderModuleDesc& desc) +{ + auto module = rcp(new ShaderModule()); + module->m_stage = desc.stage; + + // HLSL source compiled at first pipeline use via ensureD3DShaders. + // AMD drivers crash on cross-process DXBC, so we never ingest it. + assert(desc.hlslSource && desc.hlslSourceSize > 0 && + "ShaderModuleDesc::hlslSource is required for the D3D11 backend"); + module->m_hlslSource = std::string(desc.hlslSource, desc.hlslSourceSize); + if (desc.hlslEntryPoint) + module->m_hlslEntryPoint = desc.hlslEntryPoint; + + module->applyBindingMapFromDesc(desc); + return module; +} + +// ============================================================================ +// d3d11MakePipeline +// ============================================================================ + +rcp ContextD3D11::d3d11MakePipeline(const PipelineDesc& desc, + std::string* outError) +{ + auto pipeline = rcp(new Pipeline(desc)); + + // --- Validate user-supplied layouts against shader binding map --- + { + std::string err; + if (!validateLayoutsAgainstBindingMap(pipeline->m_bindingMap, + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + &err) || + !validateColorRequiresFragment(desc.colorCount, + desc.fragmentModule != nullptr, + &err)) + { + if (outError) + *outError = err; + else + setLastError("makePipeline: %s", err.c_str()); + return nullptr; + } + } + + // Keep ShaderModules alive for the lifetime of the Pipeline. + // The Luau GC can destroy the ScriptedShader (which owns the + // ShaderModule rcp) at any time after script init. + pipeline->m_vsModule = ref_rcp(desc.vertexModule); + if (desc.fragmentModule != nullptr) + pipeline->m_psModule = ref_rcp(desc.fragmentModule); + + std::string compileErr; + desc.vertexModule->ensureD3DShaders(m_d3d11Device.Get(), &compileErr); + if (!compileErr.empty()) + { + setLastError("Ore D3D11 VS: %s", compileErr.c_str()); + if (outError) + *outError = m_lastError; + return nullptr; + } + if (desc.fragmentModule != nullptr) + { + desc.fragmentModule->ensureD3DShaders(m_d3d11Device.Get(), &compileErr); + if (!compileErr.empty()) + { + setLastError("Ore D3D11 PS: %s", compileErr.c_str()); + if (outError) + *outError = m_lastError; + return nullptr; + } + } + + pipeline->m_d3dVS = desc.vertexModule->m_d3dVertexShader.Get(); + if (desc.fragmentModule != nullptr) + pipeline->m_d3dPS = desc.fragmentModule->m_d3dPixelShader.Get(); + + if (!pipeline->m_d3dVS || + (desc.fragmentModule != nullptr && !pipeline->m_d3dPS)) + { + setLastError("Ore D3D11: %s", + !pipeline->m_d3dVS + ? "vertexModule was not created as a vertex shader" + : "fragmentModule was not created as a pixel shader"); + if (outError) + *outError = m_lastError; + return nullptr; + } + + // --- Input Layout --- + // Semantic name "TEXCOORD" with SemanticIndex == shaderSlot is the + // convention used by SPIRV-Cross when targeting HLSL. + if (desc.vertexBufferCount > 0) + { + // Collect elements across all vertex buffers. + D3D11_INPUT_ELEMENT_DESC elements[32]; + UINT elementCount = 0; + + for (uint32_t bufIdx = 0; bufIdx < desc.vertexBufferCount; ++bufIdx) + { + const auto& layout = desc.vertexBuffers[bufIdx]; + for (uint32_t attrIdx = 0; attrIdx < layout.attributeCount; + ++attrIdx) + { + assert(elementCount < std::size(elements)); + const auto& attr = layout.attributes[attrIdx]; + D3D11_INPUT_ELEMENT_DESC& el = elements[elementCount++]; + el.SemanticName = "TEXCOORD"; + el.SemanticIndex = attr.shaderSlot; + el.Format = oreVertexFormatToDXGI(attr.format); + el.InputSlot = bufIdx; + el.AlignedByteOffset = attr.offset; + el.InputSlotClass = layout.stepMode == VertexStepMode::instance + ? D3D11_INPUT_PER_INSTANCE_DATA + : D3D11_INPUT_PER_VERTEX_DATA; + el.InstanceDataStepRate = + layout.stepMode == VertexStepMode::instance ? 1 : 0; + } + } + + const auto& vsBytecode = desc.vertexModule->m_bytecode; + HRESULT hr = m_d3d11Device->CreateInputLayout( + elements, + elementCount, + vsBytecode.data(), + vsBytecode.size(), + pipeline->m_d3dInputLayout.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + { + if (outError) + *outError = "CreateInputLayout failed (HRESULT " + + std::to_string(hr) + ")"; + return nullptr; + } + } + + // --- Rasterizer State --- + { + D3D11_RASTERIZER_DESC rd{}; + rd.FillMode = D3D11_FILL_SOLID; + rd.CullMode = oreCullModeToD3D(desc.cullMode); + rd.FrontCounterClockwise = + (desc.winding == FaceWinding::counterClockwise) ? TRUE : FALSE; + rd.DepthBias = desc.depthStencil.depthBias; + rd.DepthBiasClamp = desc.depthStencil.depthBiasClamp; + rd.SlopeScaledDepthBias = desc.depthStencil.depthBiasSlopeScale; + rd.DepthClipEnable = TRUE; + rd.ScissorEnable = + TRUE; // Always enable scissor; set full rect when not clipping. + rd.MultisampleEnable = (desc.sampleCount > 1) ? TRUE : FALSE; + rd.AntialiasedLineEnable = FALSE; + + HRESULT hr = m_d3d11Device->CreateRasterizerState( + &rd, + pipeline->m_d3dRasterizer.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + { + if (outError) + *outError = "CreateRasterizerState failed (HRESULT " + + std::to_string(hr) + ")"; + return nullptr; + } + } + + // --- Depth/Stencil State --- + { + D3D11_DEPTH_STENCIL_DESC dsd{}; + dsd.DepthEnable = + (desc.depthStencil.depthCompare != CompareFunction::always || + desc.depthStencil.depthWriteEnabled) + ? TRUE + : FALSE; + dsd.DepthWriteMask = desc.depthStencil.depthWriteEnabled + ? D3D11_DEPTH_WRITE_MASK_ALL + : D3D11_DEPTH_WRITE_MASK_ZERO; + dsd.DepthFunc = oreCompareFunctionToD3D(desc.depthStencil.depthCompare); + + bool hasStencil = + (desc.stencilFront.compare != CompareFunction::always || + desc.stencilFront.failOp != StencilOp::keep || + desc.stencilFront.depthFailOp != StencilOp::keep || + desc.stencilFront.passOp != StencilOp::keep || + desc.stencilBack.compare != CompareFunction::always || + desc.stencilBack.failOp != StencilOp::keep || + desc.stencilBack.depthFailOp != StencilOp::keep || + desc.stencilBack.passOp != StencilOp::keep); + + dsd.StencilEnable = hasStencil ? TRUE : FALSE; + dsd.StencilReadMask = desc.stencilReadMask; + dsd.StencilWriteMask = desc.stencilWriteMask; + + auto fillStencilOp = [](D3D11_DEPTH_STENCILOP_DESC& out, + const StencilFaceState& s) { + out.StencilFailOp = oreStencilOpToD3D(s.failOp); + out.StencilDepthFailOp = oreStencilOpToD3D(s.depthFailOp); + out.StencilPassOp = oreStencilOpToD3D(s.passOp); + out.StencilFunc = oreCompareFunctionToD3D(s.compare); + }; + fillStencilOp(dsd.FrontFace, desc.stencilFront); + fillStencilOp(dsd.BackFace, desc.stencilBack); + + HRESULT hr = m_d3d11Device->CreateDepthStencilState( + &dsd, + pipeline->m_d3dDepthStencil.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + { + if (outError) + *outError = "CreateDepthStencilState failed (HRESULT " + + std::to_string(hr) + ")"; + return nullptr; + } + } + + // --- Blend State --- + { + D3D11_BLEND_DESC bd{}; + bd.AlphaToCoverageEnable = FALSE; + bd.IndependentBlendEnable = (desc.colorCount > 1) ? TRUE : FALSE; + + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ct = desc.colorTargets[i]; + auto& rt = bd.RenderTarget[i]; + + rt.BlendEnable = ct.blendEnabled ? TRUE : FALSE; + rt.SrcBlend = oreBlendFactorToD3D(ct.blend.srcColor); + rt.DestBlend = oreBlendFactorToD3D(ct.blend.dstColor); + rt.BlendOp = oreBlendOpToD3D(ct.blend.colorOp); + rt.SrcBlendAlpha = oreBlendFactorToD3D(ct.blend.srcAlpha); + rt.DestBlendAlpha = oreBlendFactorToD3D(ct.blend.dstAlpha); + rt.BlendOpAlpha = oreBlendOpToD3D(ct.blend.alphaOp); + rt.RenderTargetWriteMask = oreColorWriteMaskToD3D(ct.writeMask); + } + + HRESULT hr = m_d3d11Device->CreateBlendState( + &bd, + pipeline->m_d3dBlend.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + { + if (outError) + *outError = "CreateBlendState failed (HRESULT " + + std::to_string(hr) + ")"; + return nullptr; + } + } + + return pipeline; +} + +// ============================================================================ +// d3d11MakeBindGroup +// ============================================================================ + +rcp ContextD3D11::d3d11MakeBindGroup(const BindGroupDesc& desc) +{ + if (desc.layout == nullptr) + { + setLastError("makeBindGroup: BindGroupDesc::layout is null"); + return nullptr; + } + BindGroupLayout* layout = desc.layout; + const uint32_t groupIndex = layout->groupIndex(); + if (groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroup: layout->groupIndex %u out of range", + groupIndex); + return nullptr; + } + + auto bg = rcp(new BindGroup()); + bg->m_context = this; + bg->m_layoutRef = ref_rcp(layout); + + // D3D11 has separate VS / PS register namespaces (b0 in VS vs b0 in PS + // are independent). HLSL SM5.0 has no register spaces, so all groups + // flatten into a single register namespace per kind. The allocator's + // per-stage native slots are populated on the layout entries by + // `makeLayoutFromShader`. + auto lookupStages = [&](uint32_t binding, + BindingKind expected, + uint16_t* outVS, + uint16_t* outPS) -> bool { + const BindGroupLayoutEntry* le = layout->findEntry(binding); + if (le == nullptr) + { + setLastError("makeBindGroup: (group=%u, binding=%u) not declared " + "in BindGroupLayout", + groupIndex, + binding); + return false; + } + const bool kindOK = le->kind == expected || + ((le->kind == BindingKind::sampler || + le->kind == BindingKind::comparisonSampler) && + (expected == BindingKind::sampler || + expected == BindingKind::comparisonSampler)); + if (!kindOK) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout kind " + "mismatch", + groupIndex, + binding); + return false; + } + *outVS = (le->nativeSlotVS == BindGroupLayoutEntry::kNativeSlotAbsent) + ? BindingMap::kAbsent + : static_cast(le->nativeSlotVS); + *outPS = (le->nativeSlotFS == BindGroupLayoutEntry::kNativeSlotAbsent) + ? BindingMap::kAbsent + : static_cast(le->nativeSlotFS); + if (*outVS == BindingMap::kAbsent && *outPS == BindingMap::kAbsent) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout has " + "no resolved native slot — call " + "makeLayoutFromShader", + groupIndex, + binding); + return false; + } + return true; + }; + + // UBO bindings. + uint32_t nBufs = std::min(desc.uboCount, 8u); + bg->m_d3d11UBOs.reserve(nBufs); + for (uint32_t i = 0; i < nBufs; ++i) + { + const auto& entry = desc.ubos[i]; + BindGroup::D3D11UBOBinding binding{}; + binding.buffer = entry.buffer->m_d3d11Buffer.Get(); + binding.binding = entry.slot; + if (!lookupStages(entry.slot, + BindingKind::uniformBuffer, + &binding.vsSlot, + &binding.psSlot)) + continue; + binding.offset = entry.offset; + binding.size = (entry.size != 0) + ? entry.size + : (entry.buffer->size() - entry.offset); + binding.hasDynamicOffset = layout->hasDynamicOffset(entry.slot); + if (binding.hasDynamicOffset) + bg->m_dynamicOffsetCount++; + bg->m_d3d11UBOs.push_back(binding); + bg->m_retainedBuffers.push_back(ref_rcp(entry.buffer)); + } + // Sort UBOs by WGSL @binding so `dynamicOffsets[]` is consumed in + // BindGroupLayout-entry order regardless of caller-supplied + // `desc.ubos[]` ordering (WebGPU contract; matches Dawn). + std::sort(bg->m_d3d11UBOs.begin(), + bg->m_d3d11UBOs.end(), + [](const BindGroup::D3D11UBOBinding& a, + const BindGroup::D3D11UBOBinding& b) { + return a.binding < b.binding; + }); + + // Texture bindings. + uint32_t nTexs = std::min(desc.textureCount, 8u); + bg->m_d3d11Textures.reserve(nTexs); + for (uint32_t i = 0; i < nTexs; ++i) + { + const auto& entry = desc.textures[i]; + BindGroup::D3D11TexBinding binding{}; + binding.srv = entry.view->m_d3dSRV.Get(); + if (!lookupStages(entry.slot, + BindingKind::sampledTexture, + &binding.vsSlot, + &binding.psSlot)) + continue; + bg->m_d3d11Textures.push_back(binding); + bg->m_retainedViews.push_back(ref_rcp(entry.view)); + } + + // Sampler bindings. + uint32_t nSamps = std::min(desc.samplerCount, 8u); + bg->m_d3d11Samplers.reserve(nSamps); + for (uint32_t i = 0; i < nSamps; ++i) + { + const auto& entry = desc.samplers[i]; + BindGroup::D3D11SamplerBinding binding{}; + binding.sampler = entry.sampler->m_d3dSampler.Get(); + if (!lookupStages(entry.slot, + BindingKind::sampler, + &binding.vsSlot, + &binding.psSlot)) + continue; + bg->m_d3d11Samplers.push_back(binding); + bg->m_retainedSamplers.push_back(ref_rcp(entry.sampler)); + } + + return bg; +} + +// ============================================================================ +// d3d11MakeBindGroupLayout +// ============================================================================ + +rcp ContextD3D11::d3d11MakeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + if (desc.groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroupLayout: groupIndex %u out of range [0, %u)", + desc.groupIndex, + kMaxBindGroups); + return nullptr; + } + auto layout = rcp(new BindGroupLayout()); + // D3D11 layouts use immediate-delete (no deferred destroy needed — + // no GPU handle to outlive a command list). Leave m_context = nullptr. + layout->m_groupIndex = desc.groupIndex; + layout->m_entries.reserve(desc.entryCount); + for (uint32_t i = 0; i < desc.entryCount; ++i) + layout->m_entries.push_back(desc.entries[i]); + return layout; +} + +// ============================================================================ +// d3d11BeginRenderPass +// ============================================================================ + +RenderPass ContextD3D11::d3d11BeginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + // Collect RTVs and DSV. + ID3D11RenderTargetView* rtvs[4] = {}; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + rtvs[i] = desc.colorAttachments[i].view->m_d3dRTV.Get(); + } + + ID3D11DepthStencilView* dsv = desc.depthStencil.view + ? desc.depthStencil.view->m_d3dDSV.Get() + : nullptr; + + m_d3d11Context->OMSetRenderTargets(desc.colorCount, rtvs, dsv); + + // Handle clear ops. + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + if (ca.loadOp == LoadOp::clear && rtvs[i] != nullptr) + { + float clearColor[4] = {ca.clearColor.r, + ca.clearColor.g, + ca.clearColor.b, + ca.clearColor.a}; + m_d3d11Context->ClearRenderTargetView(rtvs[i], clearColor); + } + } + + if (dsv && desc.depthStencil.view) + { + UINT clearFlags = 0; + if (desc.depthStencil.depthLoadOp == LoadOp::clear) + clearFlags |= D3D11_CLEAR_DEPTH; + + TextureFormat depthFmt = desc.depthStencil.view->texture()->format(); + bool hasStencil = (depthFmt == TextureFormat::depth24plusStencil8 || + depthFmt == TextureFormat::depth32floatStencil8); + if (hasStencil && desc.depthStencil.stencilLoadOp == LoadOp::clear) + clearFlags |= D3D11_CLEAR_STENCIL; + + if (clearFlags) + { + m_d3d11Context->ClearDepthStencilView( + dsv, + clearFlags, + desc.depthStencil.depthClearValue, + static_cast(desc.depthStencil.stencilClearValue)); + } + } + + // Set a default viewport covering the full render target. D3D11 + // initialises the viewport to {0,0,0,0} which clips all geometry. + // Metal defaults to the full attachment size, so scripts that omit + // setViewport() work on Metal but would produce empty output on D3D11 + // without this. + { + uint32_t w = 0, h = 0; + if (desc.colorCount > 0 && desc.colorAttachments[0].view) + { + w = desc.colorAttachments[0].view->texture()->width(); + h = desc.colorAttachments[0].view->texture()->height(); + } + else if (desc.depthStencil.view) + { + w = desc.depthStencil.view->texture()->width(); + h = desc.depthStencil.view->texture()->height(); + } + if (w > 0 && h > 0) + { + D3D11_VIEWPORT vp{}; + vp.Width = static_cast(w); + vp.Height = static_cast(h); + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + m_d3d11Context->RSSetViewports(1, &vp); + D3D11_RECT scissor = {0, 0, (LONG)w, (LONG)h}; + m_d3d11Context->RSSetScissorRects(1, &scissor); + } + } + + RenderPass pass; + pass.m_context = this; + pass.m_d3d11Context = m_d3d11Context.Get(); + pass.populateAttachmentMetadata(desc); + + // Record MSAA resolve pairs for finish(). Subresource index follows + // D3D11's formula: mipLevel + (arraySlice * mipCount). + pass.m_d3d11ResolveCount = 0; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + if (ca.resolveTarget && ca.view) + { + auto& entry = pass.m_d3d11Resolves[pass.m_d3d11ResolveCount++]; + entry.msaa = ca.view->texture()->m_d3d11Texture.Get(); + entry.resolve = ca.resolveTarget->texture()->m_d3d11Texture.Get(); + entry.format = + oreFormatInfo(ca.resolveTarget->texture()->format()).resource; + const uint32_t msaaMipCount = ca.view->texture()->numMipmaps(); + const uint32_t resolveMipCount = + ca.resolveTarget->texture()->numMipmaps(); + entry.msaaSubresource = + ca.view->baseMipLevel() + ca.view->baseLayer() * msaaMipCount; + entry.resolveSubresource = + ca.resolveTarget->baseMipLevel() + + ca.resolveTarget->baseLayer() * resolveMipCount; + } + } + + return pass; +} + +// ============================================================================ +// d3d11WrapCanvasTexture +// ============================================================================ + +rcp ContextD3D11::d3d11WrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + assert(canvas != nullptr); + + auto* d3dTarget = + static_cast(canvas->renderTarget()); + ID3D11Texture2D* d3dTex = d3dTarget->targetTexture(); + assert(d3dTex != nullptr); + + D3D11_TEXTURE2D_DESC d3dDesc{}; + d3dTex->GetDesc(&d3dDesc); + TextureFormat oreFormat; + switch (d3dDesc.Format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + oreFormat = TextureFormat::rgba8unorm; + break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + oreFormat = TextureFormat::rgba16float; + break; + case DXGI_FORMAT_R10G10B10A2_UNORM: + oreFormat = TextureFormat::rgb10a2unorm; + break; + default: /* DXGI_FORMAT_B8G8R8A8_UNORM */ + oreFormat = TextureFormat::bgra8unorm; + break; + } + + TextureDesc texDesc{}; + texDesc.width = canvas->width(); + texDesc.height = canvas->height(); + texDesc.format = oreFormat; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = true; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_d3d11Texture = d3dTex; // Borrow — RenderCanvas owns it. + texture->m_d3d11Context = m_d3d11Context.Get(); + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + // Borrow the existing RTV from the D3D render target (AddRefs via ComPtr). + view->m_d3dRTV = d3dTarget->targetRTV(); + return view; +} + +// ============================================================================ +// d3d11WrapRiveTexture +// ============================================================================ + +rcp ContextD3D11::d3d11WrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + if (!gpuTex) + return nullptr; + + auto* d3dTex = static_cast(gpuTex->nativeHandle()); + if (!d3dTex) + return nullptr; + + // Query the actual format from the D3D texture. + D3D11_TEXTURE2D_DESC d3dDesc{}; + d3dTex->GetDesc(&d3dDesc); + TextureFormat oreFormat; + switch (d3dDesc.Format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + oreFormat = TextureFormat::rgba8unorm; + break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + oreFormat = TextureFormat::bgra8unorm; + break; + default: + oreFormat = TextureFormat::rgba8unorm; + break; + } + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = oreFormat; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = false; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_d3d11Texture = d3dTex; // Borrow — caller owns via RenderImage. + texture->m_d3d11Context = m_d3d11Context.Get(); + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + // Create an SRV for sampling. The canvas path borrows an existing RTV, + // but for image sampling we need a ShaderResourceView. + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{}; + srvDesc.Format = d3dDesc.Format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = 1; + srvDesc.Texture2D.MostDetailedMip = 0; + ComPtr device; + m_d3d11Context->GetDevice(device.GetAddressOf()); + HRESULT hr = device->CreateShaderResourceView( + d3dTex, + &srvDesc, + view->m_d3dSRV.ReleaseAndGetAddressOf()); + if (FAILED(hr)) + return nullptr; + return view; +} + +// ============================================================================ +// Public method definitions (D3D11-only builds) +// ============================================================================ + +ContextD3D11::~ContextD3D11() +{ + m_d3d11Context.Reset(); + m_d3d11Device.Reset(); +} + +std::unique_ptr ContextD3D11::Make(ID3D11Device* device, + ID3D11DeviceContext* context) +{ + auto ctx = std::unique_ptr(new ContextD3D11()); + ctx->m_d3d11Device = device; + ctx->m_d3d11Context = context; + // QI the 11.1 context for offset-range constant-buffer binds. D3D11.1 is + // ubiquitous on supported Rive platforms; pre-11.1 drivers fall back to + // whole-buffer binds (no offsets). + context->QueryInterface(IID_PPV_ARGS(ctx->m_d3d11Context1.GetAddressOf())); + + // Populate features for D3D11 feature level 11.0. + Features& f = ctx->m_features; + f.colorBufferFloat = true; + f.perTargetBlend = true; + f.perTargetWriteMask = true; + f.textureViewSampling = true; + f.drawBaseInstance = + true; // DrawInstanced/DrawIndexedInstanced support baseInstance. + f.depthBiasClamp = true; + f.anisotropicFiltering = true; + f.texture3D = true; + f.textureArrays = true; + f.computeShaders = true; + f.storageBuffers = true; + f.bc = true; + f.etc2 = false; + f.astc = false; + + f.maxColorAttachments = 8; + f.maxTextureSize2D = 16384; + f.maxTextureSizeCube = 16384; + f.maxTextureSize3D = 2048; + f.maxUniformBufferSize = 64 * 1024; // D3D11 CBs capped at 65536 bytes. + f.maxVertexAttributes = 16; + f.maxSamplers = 16; + + return ctx; +} + +void ContextD3D11::beginFrame() +{ + // Release deferred BindGroups from last frame. By beginFrame() the + // caller has waited for the previous frame's GPU work to complete. + m_deferredBindGroups.clear(); +} // D3D11 immediate context has no command buffer. + +void ContextD3D11::waitForGPU() {} // D3D11 immediate context is synchronous. + +void ContextD3D11::endFrame() {} + +rcp ContextD3D11::makeBuffer(const BufferDesc& desc) +{ + return d3d11MakeBuffer(desc); +} + +rcp ContextD3D11::makeTexture(const TextureDesc& desc) +{ + return d3d11MakeTexture(desc); +} + +rcp ContextD3D11::makeTextureView(const TextureViewDesc& desc) +{ + return d3d11MakeTextureView(desc); +} + +rcp ContextD3D11::makeSampler(const SamplerDesc& desc) +{ + return d3d11MakeSampler(desc); +} + +rcp ContextD3D11::makeShaderModule(const ShaderModuleDesc& desc) +{ + return d3d11MakeShaderModule(desc); +} + +rcp ContextD3D11::makePipeline(const PipelineDesc& desc, + std::string* outError) +{ + return d3d11MakePipeline(desc, outError); +} + +rcp ContextD3D11::makeBindGroup(const BindGroupDesc& desc) +{ + return d3d11MakeBindGroup(desc); +} + +rcp ContextD3D11::makeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + return d3d11MakeBindGroupLayout(desc); +} + +RenderPass ContextD3D11::beginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + finishActiveRenderPass(); + return d3d11BeginRenderPass(desc, outError); +} + +rcp ContextD3D11::wrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + return d3d11WrapCanvasTexture(canvas); +} + +rcp ContextD3D11::wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + return d3d11WrapRiveTexture(gpuTex, w, h); +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_pipeline_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_pipeline_d3d11.cpp new file mode 100644 index 000000000..13e54959d --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_pipeline_d3d11.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +void Pipeline::onRefCntReachedZero() const { delete this; } + +void BindGroupLayout::onRefCntReachedZero() const { delete this; } + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_render_pass_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_render_pass_d3d11.cpp new file mode 100644 index 000000000..9283dd5e0 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_render_pass_d3d11.cpp @@ -0,0 +1,423 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_context_d3d11.hpp" // for RenderPass inline bodies +#include "rive/rive_types.hpp" + +#include + +namespace rive::ore +{ + +// ============================================================================ +// D3D11 static helpers — used by both the standalone D3D11-only RenderPass +// methods below and by the combined D3D11+D3D12 dispatch file +// (ore_render_pass_d3d11_d3d12.cpp) which #includes this file. +// ============================================================================ + +#if defined(ORE_BACKEND_D3D11) + +[[maybe_unused]] static D3D11_PRIMITIVE_TOPOLOGY oreTopologyToD3D( + PrimitiveTopology topo) +{ + switch (topo) + { + case PrimitiveTopology::pointList: + return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + case PrimitiveTopology::lineList: + return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + case PrimitiveTopology::lineStrip: + return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; + case PrimitiveTopology::triangleList: + return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case PrimitiveTopology::triangleStrip: + return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + } + RIVE_UNREACHABLE(); +} + +[[maybe_unused]] static DXGI_FORMAT oreIndexFormatToDXGI(IndexFormat format) +{ + switch (format) + { + case IndexFormat::uint16: + return DXGI_FORMAT_R16_UINT; + case IndexFormat::uint32: + return DXGI_FORMAT_R32_UINT; + case IndexFormat::none: + break; + } + RIVE_UNREACHABLE(); +} + +#endif // ORE_BACKEND_D3D11 + +// ============================================================================ +// RenderPass — D3D11-only method definitions +// ============================================================================ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +RenderPass::~RenderPass() +{ + if (!m_finished && m_d3d11Context != nullptr) + { + finish(); + } +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + m_currentPipeline(std::move(other.m_currentPipeline)), + m_d3d11Context(other.m_d3d11Context), + m_d3d11Topology(other.m_d3d11Topology), + m_d3d11IndexFormat(other.m_d3d11IndexFormat), + m_d3d11IndexOffset(other.m_d3d11IndexOffset), + m_d3d11StencilRef(other.m_d3d11StencilRef), + m_d3d11ResolveCount(other.m_d3d11ResolveCount) +{ + moveCrossBackendFieldsFrom(other); + m_d3d11BlendFactor[0] = other.m_d3d11BlendFactor[0]; + m_d3d11BlendFactor[1] = other.m_d3d11BlendFactor[1]; + m_d3d11BlendFactor[2] = other.m_d3d11BlendFactor[2]; + m_d3d11BlendFactor[3] = other.m_d3d11BlendFactor[3]; + for (uint32_t i = 0; i < m_d3d11ResolveCount; ++i) + m_d3d11Resolves[i] = other.m_d3d11Resolves[i]; + other.m_d3d11Context = nullptr; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && m_d3d11Context != nullptr) + { + finish(); + } + moveCrossBackendFieldsFrom(other); + m_d3d11Context = other.m_d3d11Context; + m_currentPipeline = std::move(other.m_currentPipeline); + m_d3d11Topology = other.m_d3d11Topology; + m_d3d11IndexFormat = other.m_d3d11IndexFormat; + m_d3d11IndexOffset = other.m_d3d11IndexOffset; + m_d3d11StencilRef = other.m_d3d11StencilRef; + m_d3d11BlendFactor[0] = other.m_d3d11BlendFactor[0]; + m_d3d11BlendFactor[1] = other.m_d3d11BlendFactor[1]; + m_d3d11BlendFactor[2] = other.m_d3d11BlendFactor[2]; + m_d3d11BlendFactor[3] = other.m_d3d11BlendFactor[3]; + m_d3d11ResolveCount = other.m_d3d11ResolveCount; + for (uint32_t i = 0; i < m_d3d11ResolveCount; ++i) + m_d3d11Resolves[i] = other.m_d3d11Resolves[i]; + other.m_d3d11Context = nullptr; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_d3d11Context != nullptr); +} + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + m_currentPipeline = ref_rcp(pipeline); + + const auto& desc = pipeline->desc(); + + m_d3d11Context->VSSetShader(pipeline->m_d3dVS, nullptr, 0); + m_d3d11Context->PSSetShader(pipeline->m_d3dPS, nullptr, 0); + m_d3d11Context->IASetInputLayout(pipeline->m_d3dInputLayout.Get()); + + m_d3d11Topology = oreTopologyToD3D(desc.topology); + m_d3d11Context->IASetPrimitiveTopology(m_d3d11Topology); + + m_d3d11Context->RSSetState(pipeline->m_d3dRasterizer.Get()); + m_d3d11Context->OMSetDepthStencilState(pipeline->m_d3dDepthStencil.Get(), + m_d3d11StencilRef); + m_d3d11Context->OMSetBlendState(pipeline->m_d3dBlend.Get(), + m_d3d11BlendFactor, + 0xFFFFFFFF); +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + UINT stride = (m_currentPipeline && + slot < m_currentPipeline->desc().vertexBufferCount) + ? m_currentPipeline->desc().vertexBuffers[slot].stride + : 0; + ID3D11Buffer* buf = buffer->m_d3d11Buffer.Get(); + UINT off = offset; + m_d3d11Context->IASetVertexBuffers(slot, 1, &buf, &stride, &off); +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + m_d3d11IndexFormat = oreIndexFormatToDXGI(format); + m_d3d11IndexOffset = offset; + m_d3d11Context->IASetIndexBuffer(buffer->m_d3d11Buffer.Get(), + m_d3d11IndexFormat, + offset); +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + assert(bg != nullptr); + + // Hold a strong reference so the BindGroup stays alive until finish(). + m_boundGroups[groupIndex] = ref_rcp(bg); + + // m_d3d11UBOs is sorted by WGSL `@binding` ascending at makeBindGroup + // time, so `dynamicOffsets[i]` here pairs with the i-th dynamic UBO + // in BindGroupLayout-entry order — matching WebGPU semantics + // independently of the caller's `desc.ubos[]` order. + uint32_t dynIdx = 0; + + // Bind UBOs per-stage. If an offset (static or dynamic) is non-zero, + // route through VSSetConstantBuffers1 / PSSetConstantBuffers1 whose + // firstConstant / numConstants take units of 16 bytes (one shader + // constant). D3D11 additionally requires firstConstant to be a + // multiple of 16 constants (256 bytes) — WebGPU's + // minUniformBufferOffsetAlignment default matches this, so a + // spec-compliant caller's offsets are already aligned. + // + // Per-stage emit: VS and PS register namespaces are independent on + // D3D11. Skip the stage whose slot is `kAbsent` so we don't clobber + // another resource's register. + ID3D11DeviceContext1* ctx1 = + m_context ? static_cast(m_context)->m_d3d11Context1.Get() + : nullptr; + for (const auto& ubo : bg->m_d3d11UBOs) + { + ID3D11Buffer* buf = ubo.buffer; + uint32_t offsetBytes = ubo.offset; + if (ubo.hasDynamicOffset && dynIdx < dynamicOffsetCount) + { + offsetBytes += dynamicOffsets[dynIdx]; + ++dynIdx; + } + // ubo.size was resolved to a concrete byte count at + // makeBindGroup time (see d3d11MakeBindGroup). `0` can only + // occur for an impossibly 0-sized buffer — fall back to + // whole-buffer bind in that case. + // + // D3D11.1 spec: `NumConstants` must be a multiple of 16 + // constants (= 256 bytes). NVIDIA's driver enforces this + // strictly — passing `1` (= 16 bytes, our default for a + // single vec4 UBO) silently drops the offset and falls back + // to binding from the buffer's start, producing wrong + // colors on `ore_binding_dynamic_ubo` (CI regen flagged a + // red-instead-of-yellow render on `nvidia_quadrop4000/d3datomic`). + // Round up to the spec-required multiple of 16, with a + // minimum of 16 (the smallest legal value). The shader + // still only reads `ubo.size` bytes; binding more is + // harmless for the shader and required for the API. + const bool useOffsetPath = + (offsetBytes != 0 && ctx1 != nullptr && ubo.size != 0); + const UINT firstConstant = useOffsetPath ? (offsetBytes / 16) : 0; + const UINT numConstantsRaw = (ubo.size + 15) / 16; + const UINT numConstants = + useOffsetPath + ? (numConstantsRaw < 16 ? 16u + : ((numConstantsRaw + 15u) & ~15u)) + : 0; + if (ubo.vsSlot != BindingMap::kAbsent) + { + if (useOffsetPath) + ctx1->VSSetConstantBuffers1(ubo.vsSlot, + 1, + &buf, + &firstConstant, + &numConstants); + else + m_d3d11Context->VSSetConstantBuffers(ubo.vsSlot, 1, &buf); + } + if (ubo.psSlot != BindingMap::kAbsent) + { + if (useOffsetPath) + ctx1->PSSetConstantBuffers1(ubo.psSlot, + 1, + &buf, + &firstConstant, + &numConstants); + else + m_d3d11Context->PSSetConstantBuffers(ubo.psSlot, 1, &buf); + } + } + + // SRVs and samplers, per-stage. Skipping kAbsent stages (rather than + // binding to both unconditionally) means a VS-only or PS-only + // resource can share a register number with a different resource in + // the other stage, matching D3D11's per-stage register file. + for (const auto& tex : bg->m_d3d11Textures) + { + if (tex.vsSlot != BindingMap::kAbsent) + m_d3d11Context->VSSetShaderResources(tex.vsSlot, 1, &tex.srv); + if (tex.psSlot != BindingMap::kAbsent) + m_d3d11Context->PSSetShaderResources(tex.psSlot, 1, &tex.srv); + } + + for (const auto& samp : bg->m_d3d11Samplers) + { + if (samp.vsSlot != BindingMap::kAbsent) + m_d3d11Context->VSSetSamplers(samp.vsSlot, 1, &samp.sampler); + if (samp.psSlot != BindingMap::kAbsent) + m_d3d11Context->PSSetSamplers(samp.psSlot, 1, &samp.sampler); + } +} + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ + validate(); + D3D11_VIEWPORT vp{}; + vp.TopLeftX = x; + vp.TopLeftY = y; + vp.Width = width; + vp.Height = height; + vp.MinDepth = minDepth; + vp.MaxDepth = maxDepth; + m_d3d11Context->RSSetViewports(1, &vp); + // The rasterizer state always has ScissorEnable=TRUE. Reset the scissor + // rect to cover the full viewport so draws are not silently clipped when + // the caller has not issued an explicit setScissorRect. D3D11 initialises + // scissor rects to {0,0,0,0} which discards every pixel. + D3D11_RECT scissor{}; + scissor.left = static_cast(x); + scissor.top = static_cast(y); + scissor.right = static_cast(x + width); + scissor.bottom = static_cast(y + height); + m_d3d11Context->RSSetScissorRects(1, &scissor); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + D3D11_RECT rect{}; + rect.left = static_cast(x); + rect.top = static_cast(y); + rect.right = static_cast(x + width); + rect.bottom = static_cast(y + height); + m_d3d11Context->RSSetScissorRects(1, &rect); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + m_d3d11StencilRef = ref; + if (m_currentPipeline) + { + m_d3d11Context->OMSetDepthStencilState( + m_currentPipeline->m_d3dDepthStencil.Get(), + ref); + } +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + m_d3d11BlendFactor[0] = r; + m_d3d11BlendFactor[1] = g; + m_d3d11BlendFactor[2] = b; + m_d3d11BlendFactor[3] = a; + if (m_currentPipeline) + { + m_d3d11Context->OMSetBlendState(m_currentPipeline->m_d3dBlend.Get(), + m_d3d11BlendFactor, + 0xFFFFFFFF); + } +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + if (instanceCount > 1 || firstInstance != 0) + { + m_d3d11Context->DrawInstanced(vertexCount, + instanceCount, + firstVertex, + firstInstance); + } + else + { + m_d3d11Context->Draw(vertexCount, firstVertex); + } +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + if (instanceCount > 1 || firstInstance != 0 || baseVertex != 0) + { + m_d3d11Context->DrawIndexedInstanced(indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); + } + else + { + m_d3d11Context->DrawIndexed(indexCount, firstIndex, 0); + } +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + if (m_d3d11Context != nullptr) + { + // Unbind render targets so attached textures can be used as SRVs. + m_d3d11Context->OMSetRenderTargets(0, nullptr, nullptr); + + // Resolve MSAA render targets to their 1x resolve targets. + for (uint32_t i = 0; i < m_d3d11ResolveCount; ++i) + { + const auto& r = m_d3d11Resolves[i]; + m_d3d11Context->ResolveSubresource(r.resolve, + r.resolveSubresource, + r.msaa, + r.msaaSubresource, + r.format); + } + + m_d3d11Context = nullptr; + } +} + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_sampler_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_sampler_d3d11.cpp new file mode 100644 index 000000000..59f8c5fed --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_sampler_d3d11.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_sampler.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +void Sampler::onRefCntReachedZero() const { delete this; } + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_shader_module_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_shader_module_d3d11.cpp new file mode 100644 index 000000000..3c1aaf695 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_shader_module_d3d11.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +void ShaderModule::onRefCntReachedZero() const { delete this; } + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d11/ore_texture_d3d11.cpp b/thirdparty/rive_renderer/source/ore/d3d11/ore_texture_d3d11.cpp new file mode 100644 index 000000000..b9152b86e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d11/ore_texture_d3d11.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/rive_types.hpp" + +#include + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_D3D11) && !defined(ORE_BACKEND_D3D12) + +void Texture::upload(const TextureDataDesc& data) +{ + assert(m_d3d11Context != nullptr); + assert(m_d3d11Texture != nullptr); + assert(data.data != nullptr); + + UINT subresource = + D3D11CalcSubresource(data.mipLevel, data.layer, m_numMipmaps); + + D3D11_BOX box{}; + box.left = data.x; + box.top = data.y; + box.front = data.z; + box.right = data.x + data.width; + box.bottom = data.y + data.height; + box.back = data.z + data.depth; + + m_d3d11Context->UpdateSubresource(m_d3d11Texture.Get(), + subresource, + &box, + data.data, + data.bytesPerRow, + data.bytesPerRow * data.rowsPerImage); +} + +void Texture::onRefCntReachedZero() const { delete this; } + +void TextureView::onRefCntReachedZero() const { delete this; } + +#endif // ORE_BACKEND_D3D11 && !ORE_BACKEND_D3D12 + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d11_d3d12.cpp new file mode 100644 index 000000000..ee9aae5e9 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d11_d3d12.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 BindGroup implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +#include "rive/renderer/ore/ore_bind_group.hpp" + +namespace rive::ore +{ + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d12.cpp new file mode 100644 index 000000000..f4ecf5dff --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_bind_group_d3d12.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_bind_group.hpp" + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d11_d3d12.cpp new file mode 100644 index 000000000..480a562b4 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d11_d3d12.cpp @@ -0,0 +1,63 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 Buffer implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include +#include + +namespace rive::ore +{ + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + if (m_d3d11Buffer) + { + // D3D11 path — map, copy, unmap. + assert(m_d3d11Context != nullptr); + D3D11_MAPPED_SUBRESOURCE mapped{}; + D3D11_MAP mapType = (m_usage == BufferUsage::uniform) + ? D3D11_MAP_WRITE_DISCARD + : D3D11_MAP_WRITE_NO_OVERWRITE; + [[maybe_unused]] HRESULT hr = + m_d3d11Context->Map(m_d3d11Buffer.Get(), 0, mapType, 0, &mapped); + assert(SUCCEEDED(hr)); + memcpy(static_cast(mapped.pData) + offset, data, size); + m_d3d11Context->Unmap(m_d3d11Buffer.Get(), 0); + } + else + { + // D3D12 path — UPLOAD heap buffer is persistently mapped. + assert(m_d3dBuffer != nullptr); + assert(m_d3dMappedPtr != nullptr); + memcpy(static_cast(m_d3dMappedPtr) + offset, data, size); + } +} + +void Buffer::onRefCntReachedZero() const +{ + // m_d3dOreContext is only set on D3D12-backed buffers (see + // d3d12MakeBuffer). D3D11-backed buffers keep the immediate-delete path + // unchanged. + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d12.cpp new file mode 100644 index 000000000..a4fe63b19 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_buffer_d3d12.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + assert(m_d3dBuffer != nullptr); + assert(m_d3dMappedPtr != nullptr); + + // UPLOAD heap buffer is persistently mapped — write directly. + memcpy(static_cast(m_d3dMappedPtr) + offset, data, size); +} + +void Buffer::onRefCntReachedZero() const +{ + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_context_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_context_d3d12.cpp new file mode 100644 index 000000000..bc524c64e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_context_d3d12.cpp @@ -0,0 +1,2163 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/renderer/d3d12/render_context_d3d12_impl.hpp" +#include "rive/rive_types.hpp" +#include "ore_d3d12_root_sig.hpp" + +#include +#include +#include +#include +#include +#include +#include + +using Microsoft::WRL::ComPtr; + +namespace rive::ore +{ + +// ============================================================================ +// Enum → DXGI / D3D12 conversion helpers +// (Shared format table with D3D11 but typed for D3D12.) +// ============================================================================ + +struct D3D12FormatInfo +{ + DXGI_FORMAT resource; // Typeless for depth; typed for colour. + DXGI_FORMAT srv; // Shader-resource view format. + DXGI_FORMAT rtv; // Render-target view (UNKNOWN for depth). + DXGI_FORMAT dsv; // Depth-stencil view (UNKNOWN for colour). + bool isDepth; +}; + +static D3D12FormatInfo oreFormatInfoD3D12(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return {DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rg8unorm: + return {DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba8unorm: + return {DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba8snorm: + return {DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::bgra8unorm: + return {DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba16float: + return {DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rg16float: + return {DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::r16float: + return {DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgba32float: + return {DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rg32float: + return {DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::r32float: + return {DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::rgb10a2unorm: + return {DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::r11g11b10float: + return {DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + false}; + // Depth — typeless resource for both DSV and SRV. + case TextureFormat::depth16unorm: + return {DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + true}; + case TextureFormat::depth24plusStencil8: + return {DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + true}; + case TextureFormat::depth32float: + return {DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT, + true}; + case TextureFormat::depth32floatStencil8: + return {DXGI_FORMAT_R32G8X24_TYPELESS, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + true}; + case TextureFormat::bc1unorm: + return {DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::bc3unorm: + return {DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::bc7unorm: + return {DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_BC7_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + false}; + case TextureFormat::etc2rgb8: + case TextureFormat::etc2rgba8: + case TextureFormat::astc4x4: + case TextureFormat::astc6x6: + case TextureFormat::astc8x8: + RIVE_UNREACHABLE(); + } + RIVE_UNREACHABLE(); +} + +static D3D12_FILTER oreFilterToD3D12(Filter min, + Filter mag, + Filter mip, + CompareFunction compare, + uint32_t aniso) +{ + bool isComp = (compare != CompareFunction::none); + if (aniso > 1) + return isComp ? D3D12_FILTER_COMPARISON_ANISOTROPIC + : D3D12_FILTER_ANISOTROPIC; + if (min == Filter::linear && mag == Filter::linear && mip == Filter::linear) + return isComp ? D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR + : D3D12_FILTER_MIN_MAG_MIP_LINEAR; + if (min == Filter::linear && mag == Filter::linear && + mip == Filter::nearest) + return isComp ? D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT + : D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; + if (min == Filter::linear && mag == Filter::nearest && + mip == Filter::linear) + return isComp ? D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR + : D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + if (min == Filter::linear && mag == Filter::nearest && + mip == Filter::nearest) + return isComp ? D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT + : D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT; + if (min == Filter::nearest && mag == Filter::linear && + mip == Filter::linear) + return isComp ? D3D12_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR + : D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR; + if (min == Filter::nearest && mag == Filter::linear && + mip == Filter::nearest) + return isComp ? D3D12_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT + : D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + if (min == Filter::nearest && mag == Filter::nearest && + mip == Filter::linear) + return isComp ? D3D12_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR + : D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR; + return isComp ? D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT + : D3D12_FILTER_MIN_MAG_MIP_POINT; +} + +static D3D12_TEXTURE_ADDRESS_MODE oreWrapToD3D12(WrapMode mode) +{ + switch (mode) + { + case WrapMode::repeat: + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + case WrapMode::mirrorRepeat: + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + case WrapMode::clampToEdge: + return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + } + RIVE_UNREACHABLE(); +} + +static D3D12_COMPARISON_FUNC oreCompareFunctionToD3D12(CompareFunction fn) +{ + switch (fn) + { + case CompareFunction::none: + case CompareFunction::never: + return D3D12_COMPARISON_FUNC_NEVER; + case CompareFunction::less: + return D3D12_COMPARISON_FUNC_LESS; + case CompareFunction::equal: + return D3D12_COMPARISON_FUNC_EQUAL; + case CompareFunction::lessEqual: + return D3D12_COMPARISON_FUNC_LESS_EQUAL; + case CompareFunction::greater: + return D3D12_COMPARISON_FUNC_GREATER; + case CompareFunction::notEqual: + return D3D12_COMPARISON_FUNC_NOT_EQUAL; + case CompareFunction::greaterEqual: + return D3D12_COMPARISON_FUNC_GREATER_EQUAL; + case CompareFunction::always: + return D3D12_COMPARISON_FUNC_ALWAYS; + } + RIVE_UNREACHABLE(); +} + +static D3D12_BLEND oreBlendFactorToD3D12(BlendFactor f) +{ + switch (f) + { + case BlendFactor::zero: + return D3D12_BLEND_ZERO; + case BlendFactor::one: + return D3D12_BLEND_ONE; + case BlendFactor::srcColor: + return D3D12_BLEND_SRC_COLOR; + case BlendFactor::oneMinusSrcColor: + return D3D12_BLEND_INV_SRC_COLOR; + case BlendFactor::srcAlpha: + return D3D12_BLEND_SRC_ALPHA; + case BlendFactor::oneMinusSrcAlpha: + return D3D12_BLEND_INV_SRC_ALPHA; + case BlendFactor::dstColor: + return D3D12_BLEND_DEST_COLOR; + case BlendFactor::oneMinusDstColor: + return D3D12_BLEND_INV_DEST_COLOR; + case BlendFactor::dstAlpha: + return D3D12_BLEND_DEST_ALPHA; + case BlendFactor::oneMinusDstAlpha: + return D3D12_BLEND_INV_DEST_ALPHA; + case BlendFactor::srcAlphaSaturated: + return D3D12_BLEND_SRC_ALPHA_SAT; + case BlendFactor::blendColor: + return D3D12_BLEND_BLEND_FACTOR; + case BlendFactor::oneMinusBlendColor: + return D3D12_BLEND_INV_BLEND_FACTOR; + } + RIVE_UNREACHABLE(); +} + +static D3D12_BLEND_OP oreBlendOpToD3D12(BlendOp op) +{ + switch (op) + { + case BlendOp::add: + return D3D12_BLEND_OP_ADD; + case BlendOp::subtract: + return D3D12_BLEND_OP_SUBTRACT; + case BlendOp::reverseSubtract: + return D3D12_BLEND_OP_REV_SUBTRACT; + case BlendOp::min: + return D3D12_BLEND_OP_MIN; + case BlendOp::max: + return D3D12_BLEND_OP_MAX; + } + RIVE_UNREACHABLE(); +} + +static D3D12_STENCIL_OP oreStencilOpToD3D12(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return D3D12_STENCIL_OP_KEEP; + case StencilOp::zero: + return D3D12_STENCIL_OP_ZERO; + case StencilOp::replace: + return D3D12_STENCIL_OP_REPLACE; + case StencilOp::incrementClamp: + return D3D12_STENCIL_OP_INCR_SAT; + case StencilOp::decrementClamp: + return D3D12_STENCIL_OP_DECR_SAT; + case StencilOp::invert: + return D3D12_STENCIL_OP_INVERT; + case StencilOp::incrementWrap: + return D3D12_STENCIL_OP_INCR; + case StencilOp::decrementWrap: + return D3D12_STENCIL_OP_DECR; + } + RIVE_UNREACHABLE(); +} + +static UINT8 oreColorWriteMaskToD3D12(ColorWriteMask mask) +{ + UINT8 d3d = 0; + if ((mask & ColorWriteMask::red) != ColorWriteMask::none) + d3d |= D3D12_COLOR_WRITE_ENABLE_RED; + if ((mask & ColorWriteMask::green) != ColorWriteMask::none) + d3d |= D3D12_COLOR_WRITE_ENABLE_GREEN; + if ((mask & ColorWriteMask::blue) != ColorWriteMask::none) + d3d |= D3D12_COLOR_WRITE_ENABLE_BLUE; + if ((mask & ColorWriteMask::alpha) != ColorWriteMask::none) + d3d |= D3D12_COLOR_WRITE_ENABLE_ALPHA; + return d3d; +} + +static DXGI_FORMAT oreVertexFormatToDXGI12(VertexFormat fmt) +{ + switch (fmt) + { + case VertexFormat::float1: + return DXGI_FORMAT_R32_FLOAT; + case VertexFormat::float2: + return DXGI_FORMAT_R32G32_FLOAT; + case VertexFormat::float3: + return DXGI_FORMAT_R32G32B32_FLOAT; + case VertexFormat::float4: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case VertexFormat::uint8x4: + return DXGI_FORMAT_R8G8B8A8_UINT; + case VertexFormat::sint8x4: + return DXGI_FORMAT_R8G8B8A8_SINT; + case VertexFormat::unorm8x4: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case VertexFormat::snorm8x4: + return DXGI_FORMAT_R8G8B8A8_SNORM; + case VertexFormat::uint16x2: + return DXGI_FORMAT_R16G16_UINT; + case VertexFormat::sint16x2: + return DXGI_FORMAT_R16G16_SINT; + case VertexFormat::unorm16x2: + return DXGI_FORMAT_R16G16_UNORM; + case VertexFormat::snorm16x2: + return DXGI_FORMAT_R16G16_SNORM; + case VertexFormat::uint16x4: + return DXGI_FORMAT_R16G16B16A16_UINT; + case VertexFormat::sint16x4: + return DXGI_FORMAT_R16G16B16A16_SINT; + case VertexFormat::float16x2: + return DXGI_FORMAT_R16G16_FLOAT; + case VertexFormat::float16x4: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case VertexFormat::uint32: + return DXGI_FORMAT_R32_UINT; + case VertexFormat::uint32x2: + return DXGI_FORMAT_R32G32_UINT; + case VertexFormat::uint32x3: + return DXGI_FORMAT_R32G32B32_UINT; + case VertexFormat::uint32x4: + return DXGI_FORMAT_R32G32B32A32_UINT; + case VertexFormat::sint32: + return DXGI_FORMAT_R32_SINT; + case VertexFormat::sint32x2: + return DXGI_FORMAT_R32G32_SINT; + case VertexFormat::sint32x3: + return DXGI_FORMAT_R32G32B32_SINT; + case VertexFormat::sint32x4: + return DXGI_FORMAT_R32G32B32A32_SINT; + } + RIVE_UNREACHABLE(); +} + +static D3D12_PRIMITIVE_TOPOLOGY oreTopologyToD3D12(PrimitiveTopology t) +{ + switch (t) + { + case PrimitiveTopology::pointList: + return D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + case PrimitiveTopology::lineList: + return D3D_PRIMITIVE_TOPOLOGY_LINELIST; + case PrimitiveTopology::lineStrip: + return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + case PrimitiveTopology::triangleList: + return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case PrimitiveTopology::triangleStrip: + return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + } + RIVE_UNREACHABLE(); +} + +static D3D12_PRIMITIVE_TOPOLOGY_TYPE oreTopologyTypeToD3D12(PrimitiveTopology t) +{ + switch (t) + { + case PrimitiveTopology::pointList: + return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + case PrimitiveTopology::lineList: + case PrimitiveTopology::lineStrip: + return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + case PrimitiveTopology::triangleList: + case PrimitiveTopology::triangleStrip: + return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + } + RIVE_UNREACHABLE(); +} + +// ============================================================================ +// GPU-side fence wait helper +// ============================================================================ + +static void d3d12WaitFence(ID3D12CommandQueue* queue, + ID3D12Fence* fence, + uint64_t& fenceValue, + HANDLE fenceEvent) +{ + ++fenceValue; + queue->Signal(fence, fenceValue); + if (fence->GetCompletedValue() < fenceValue) + { + fence->SetEventOnCompletion(fenceValue, fenceEvent); + WaitForSingleObject(fenceEvent, INFINITE); + } +} + +// ============================================================================ +// Context — public method definitions (D3D12-only builds) +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +// ============================================================================ + +ContextD3D12::~ContextD3D12() +{ + if (m_d3dDevice) + { + // Flush all pending GPU work before releasing resources. In + // external-CL mode Ore has no frame fence of its own, but the host + // must have waited on its fence before entering the destructor; we + // additionally wait on our own queue so pending destroys are safe. + if (m_d3dQueue && m_d3dFence && m_d3dFenceEvent) + d3d12WaitFence(m_d3dQueue.Get(), + m_d3dFence.Get(), + m_d3dFenceValue, + m_d3dFenceEvent); + + // Drain any closures that were queued while in external-CL mode. + d3dDrainDeferred(); + + m_d3dPendingUploads.clear(); + + if (m_d3dFenceEvent) + { + CloseHandle(m_d3dFenceEvent); + m_d3dFenceEvent = nullptr; + } + } +} + +// ============================================================================ +// ContextD3D12::Make +// ============================================================================ + +std::unique_ptr ContextD3D12::Make(ID3D12Device* device, + ID3D12CommandQueue* queue) +{ + auto ctx = std::unique_ptr(new ContextD3D12()); + ctx->m_d3dDevice = device; + ctx->m_d3dQueue = queue; + + // --- Command allocator + list for rendering --- + [[maybe_unused]] HRESULT hr; + hr = device->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(ctx->m_d3dAllocator.GetAddressOf())); + assert(SUCCEEDED(hr)); + hr = device->CreateCommandList( + 0, + D3D12_COMMAND_LIST_TYPE_DIRECT, + ctx->m_d3dAllocator.Get(), + nullptr, + IID_PPV_ARGS(ctx->m_d3dOwnedCmdList.GetAddressOf())); + assert(SUCCEEDED(hr)); + ctx->m_d3dCmdList = ctx->m_d3dOwnedCmdList.Get(); + // Close immediately; reopened in beginFrame(). + ctx->m_d3dCmdList->Close(); + + // --- Upload allocator + list --- + hr = device->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_DIRECT, + IID_PPV_ARGS(ctx->m_d3dUploadAllocator.GetAddressOf())); + assert(SUCCEEDED(hr)); + hr = device->CreateCommandList( + 0, + D3D12_COMMAND_LIST_TYPE_DIRECT, + ctx->m_d3dUploadAllocator.Get(), + nullptr, + IID_PPV_ARGS(ctx->m_d3dUploadCmdList.GetAddressOf())); + assert(SUCCEEDED(hr)); + ctx->m_d3dUploadCmdList->Close(); + + // --- Fence --- + hr = device->CreateFence(0, + D3D12_FENCE_FLAG_NONE, + IID_PPV_ARGS(ctx->m_d3dFence.GetAddressOf())); + assert(SUCCEEDED(hr)); + ctx->m_d3dFenceEvent = CreateEventW(nullptr, FALSE, FALSE, nullptr); + assert(ctx->m_d3dFenceEvent != nullptr); + + // Root signatures are per-pipeline (RFC v5 §3.2.2). Each pipeline + // builds its own from its `ore::BindingMap` via `buildPerPipeline- + // RootSig` at `d3d12MakePipeline` time; the render pass binds that + // sig at `setPipeline` when it differs from the currently-bound + // one. No context-wide root signature is needed. + + // --- Descriptor heap sizes --- + ctx->m_d3dSrvDescSize = device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + ctx->m_d3dRtvDescSize = device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + ctx->m_d3dDsvDescSize = device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + ctx->m_d3dSamplerDescSize = device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + + // --- CPU-visible heaps --- + auto makeCpuHeap = [&](D3D12_DESCRIPTOR_HEAP_TYPE type, + UINT count, + ComPtr& out) { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = type; + desc.NumDescriptors = count; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + [[maybe_unused]] HRESULT r = + device->CreateDescriptorHeap(&desc, + IID_PPV_ARGS(out.GetAddressOf())); + assert(SUCCEEDED(r)); + }; + makeCpuHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, + 1024, + ctx->m_d3dCpuSrvHeap); + makeCpuHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 256, ctx->m_d3dCpuRtvHeap); + makeCpuHeap(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 64, ctx->m_d3dCpuDsvHeap); + makeCpuHeap(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, + 256, + ctx->m_d3dCpuSamplerHeap); + + // --- GPU-visible heaps --- + auto makeGpuHeap = [&](D3D12_DESCRIPTOR_HEAP_TYPE type, + UINT count, + ComPtr& out) { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = type; + desc.NumDescriptors = count; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + [[maybe_unused]] HRESULT r = + device->CreateDescriptorHeap(&desc, + IID_PPV_ARGS(out.GetAddressOf())); + assert(SUCCEEDED(r)); + }; + makeGpuHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, + 4096, + ctx->m_d3dGpuSrvHeap); + makeGpuHeap(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, + 512, + ctx->m_d3dGpuSamplerHeap); + + // --- Null SRV (2D texture, for unused descriptor-table slots) --- + { + D3D12_CPU_DESCRIPTOR_HANDLE handle = + ctx->m_d3dCpuSrvHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += ctx->m_d3dCpuSrvAllocated++ * ctx->m_d3dSrvDescSize; + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Shader4ComponentMapping = + D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.Texture2D.MipLevels = 1; + device->CreateShaderResourceView(nullptr, &srvDesc, handle); + ctx->m_d3dNullSrv = handle; + } + + // --- Null Sampler --- + { + D3D12_CPU_DESCRIPTOR_HANDLE handle = + ctx->m_d3dCpuSamplerHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += + ctx->m_d3dCpuSamplerAllocated++ * ctx->m_d3dSamplerDescSize; + D3D12_SAMPLER_DESC sampDesc = {}; + sampDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + sampDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + sampDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; + sampDesc.MaxLOD = D3D12_FLOAT32_MAX; + device->CreateSampler(&sampDesc, handle); + ctx->m_d3dNullSampler = handle; + } + + // --- Features --- + Features& f = ctx->m_features; + f.colorBufferFloat = true; + f.perTargetBlend = true; + f.perTargetWriteMask = true; + f.textureViewSampling = true; + f.drawBaseInstance = true; + f.depthBiasClamp = true; + f.anisotropicFiltering = true; + f.texture3D = true; + f.textureArrays = true; + f.computeShaders = true; + f.storageBuffers = true; + f.bc = true; + f.etc2 = false; + f.astc = false; + f.maxColorAttachments = 8; + f.maxTextureSize2D = 16384; + f.maxTextureSizeCube = 16384; + f.maxTextureSize3D = 2048; + f.maxUniformBufferSize = 65536; + f.maxVertexAttributes = 16; + f.maxSamplers = 16; + + return ctx; +} + +// ============================================================================ +// beginFrame / endFrame / waitForGPU +// ============================================================================ + +void ContextD3D12::beginFrame() +{ + // Release deferred BindGroups from last frame. By beginFrame() the + // caller has waited for the previous frame's GPU work to complete. + m_deferredBindGroups.clear(); + +#if defined(ORE_BACKEND_D3D12) + // Drain any destroys queued while the previous frame was in external-CL + // mode. In owned-CL mode the queue is empty (closures run immediately). + d3dDrainDeferred(); + + m_d3dExternalCmdList = false; + m_d3dCmdList = m_d3dOwnedCmdList.Get(); + + // Flush any queued texture uploads before opening the main command list. + d3d12FlushUploads(); + + m_d3dAllocator->Reset(); + m_d3dCmdList->Reset(m_d3dAllocator.Get(), nullptr); + + // Reset frame-scoped GPU heap allocation offsets. + m_d3dGpuSrvAllocated = 0; + m_d3dGpuSamplerAllocated = 0; + + // Bind GPU-visible heaps once (both SRV/CBV and Sampler). Root sig + // is bound by `RenderPass::setPipeline` at the first pipeline use — + // every pipeline ships with its own (RFC v5 §3.2.2). + ID3D12DescriptorHeap* heaps[] = {m_d3dGpuSrvHeap.Get(), + m_d3dGpuSamplerHeap.Get()}; + m_d3dCmdList->SetDescriptorHeaps(2, heaps); +#endif +} + +void ContextD3D12::beginFrame(ID3D12GraphicsCommandList* externalCl) +{ +#if defined(ORE_BACKEND_D3D12) + assert(externalCl != nullptr); + + m_deferredBindGroups.clear(); + d3dDrainDeferred(); + + // Our upload CL is independent of the host's frame CL — submit any + // pending uploads now so textures are ready before the host's draws. + // The submit happens on the shared queue; D3D12 queue ordering ensures + // the uploads finish before the host's eventual frame submission. + d3d12FlushUploads(); + + m_d3dGpuSrvAllocated = 0; + m_d3dGpuSamplerAllocated = 0; + + m_d3dCmdList = externalCl; + m_d3dExternalCmdList = true; + + // The host's command list carries whatever state the host set before + // handing it to us. Bind Ore's descriptor heaps; each pipeline binds + // its own per-pipeline root sig at setPipeline. The host is + // responsible for re-binding its own state after endFrame(). + ID3D12DescriptorHeap* heaps[] = {m_d3dGpuSrvHeap.Get(), + m_d3dGpuSamplerHeap.Get()}; + m_d3dCmdList->SetDescriptorHeaps(2, heaps); +#else + (void)externalCl; +#endif +} + +void ContextD3D12::waitForGPU() +{ +#if defined(ORE_BACKEND_D3D12) + d3d12WaitFence(m_d3dQueue.Get(), + m_d3dFence.Get(), + m_d3dFenceValue, + m_d3dFenceEvent); +#endif +} + +void ContextD3D12::endFrame() +{ +#if defined(ORE_BACKEND_D3D12) + if (m_d3dExternalCmdList) + { + // External-CL mode: host owns Close/Execute/fence. Deferred destroys + // wait until the next beginFrame() when the host has waited on the + // prior frame fence. + return; + } + + m_d3dOwnedCmdList->Close(); + + ID3D12CommandList* lists[] = {m_d3dOwnedCmdList.Get()}; + m_d3dQueue->ExecuteCommandLists(1, lists); + + d3d12WaitFence(m_d3dQueue.Get(), + m_d3dFence.Get(), + m_d3dFenceValue, + m_d3dFenceEvent); + + // Release staging upload resources now that the GPU is idle. + m_d3dPendingUploads.clear(); +#endif +} + +// ============================================================================ +// d3d12FlushUploads + GPU-visible heap allocation helpers (called by +// RenderPass and d3d12* helpers) +// ============================================================================ + +#if defined(ORE_BACKEND_D3D12) + +void ContextD3D12::d3dDrainDeferred() +{ + for (auto& destroy : m_d3dDeferredDestroys) + destroy(); + m_d3dDeferredDestroys.clear(); +} + +void ContextD3D12::d3dDeferDestroy(std::function destroy) +{ + if (m_d3dExternalCmdList) + m_d3dDeferredDestroys.push_back(std::move(destroy)); + else + destroy(); +} + +void ContextD3D12::d3d12FlushUploads() +{ + if (!m_d3dUploadListOpen) + return; + + m_d3dUploadCmdList->Close(); + ID3D12CommandList* lists[] = {m_d3dUploadCmdList.Get()}; + m_d3dQueue->ExecuteCommandLists(1, lists); + d3d12WaitFence(m_d3dQueue.Get(), + m_d3dFence.Get(), + m_d3dFenceValue, + m_d3dFenceEvent); + m_d3dPendingUploads.clear(); + m_d3dUploadListOpen = false; +} + +UINT ContextD3D12::d3d12AllocGpuSrvSlots(UINT count) +{ + // Heap exhaustion is reachable from a Lua script that creates more + // bind groups than the GPU heap can hold (4096 SRV/CBV/UAV slots). + // Pre-fix this asserted and crashed in debug, GPU-hung in release. + // Per `feedback_lua_gpu_misuse_validation`, surface as setLastError + // and return a sentinel so the apply path can no-op the bind. + if (m_d3dGpuSrvAllocated + count > 4096) + { + setLastError("d3d12AllocGpuSrvSlots: GPU SRV heap exhausted (need %u, " + "%u/4096 used)", + count, + m_d3dGpuSrvAllocated); + return UINT_MAX; + } + UINT start = m_d3dGpuSrvAllocated; + m_d3dGpuSrvAllocated += count; + return start; +} + +UINT ContextD3D12::d3d12AllocGpuSamplerSlots(UINT count) +{ + if (m_d3dGpuSamplerAllocated + count > 512) + { + setLastError("d3d12AllocGpuSamplerSlots: GPU sampler heap exhausted " + "(need %u, %u/512 used)", + count, + m_d3dGpuSamplerAllocated); + return UINT_MAX; + } + UINT start = m_d3dGpuSamplerAllocated; + m_d3dGpuSamplerAllocated += count; + return start; +} + +D3D12_CPU_DESCRIPTOR_HANDLE ContextD3D12::d3d12GpuSrvCpuHandle(UINT index) const +{ + D3D12_CPU_DESCRIPTOR_HANDLE h = + m_d3dGpuSrvHeap->GetCPUDescriptorHandleForHeapStart(); + h.ptr += (SIZE_T)index * m_d3dSrvDescSize; + return h; +} + +D3D12_GPU_DESCRIPTOR_HANDLE ContextD3D12::d3d12GpuSrvGpuHandle(UINT index) const +{ + D3D12_GPU_DESCRIPTOR_HANDLE h = + m_d3dGpuSrvHeap->GetGPUDescriptorHandleForHeapStart(); + h.ptr += (UINT64)index * m_d3dSrvDescSize; + return h; +} + +D3D12_CPU_DESCRIPTOR_HANDLE ContextD3D12::d3d12GpuSamplerCpuHandle( + UINT index) const +{ + D3D12_CPU_DESCRIPTOR_HANDLE h = + m_d3dGpuSamplerHeap->GetCPUDescriptorHandleForHeapStart(); + h.ptr += (SIZE_T)index * m_d3dSamplerDescSize; + return h; +} + +D3D12_GPU_DESCRIPTOR_HANDLE ContextD3D12::d3d12GpuSamplerGpuHandle( + UINT index) const +{ + D3D12_GPU_DESCRIPTOR_HANDLE h = + m_d3dGpuSamplerHeap->GetGPUDescriptorHandleForHeapStart(); + h.ptr += (UINT64)index * m_d3dSamplerDescSize; + return h; +} + +#endif // ORE_BACKEND_D3D12 + +// ============================================================================ +// D3D12 helper methods — always compiled (used by combined d3d11+d3d12 +// dispatch file). +// ============================================================================ + +// ============================================================================ +// d3d12MakeBuffer +// ============================================================================ + +rcp ContextD3D12::d3d12MakeBuffer(const BufferDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + auto buffer = rcp(new Buffer(desc.size, desc.usage)); + buffer->m_d3dOreContext = this; + + // All ORE buffers live in UPLOAD heap — simple, safe for test workloads. + UINT64 alignedSize = desc.size; + if (desc.usage == BufferUsage::uniform) + alignedSize = (alignedSize + 255) & ~255ULL; // 256-byte CB alignment. + + D3D12_HEAP_PROPERTIES heapProps = {}; + heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_RESOURCE_DESC resDesc = {}; + resDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + resDesc.Width = alignedSize; + resDesc.Height = 1; + resDesc.DepthOrArraySize = 1; + resDesc.MipLevels = 1; + resDesc.Format = DXGI_FORMAT_UNKNOWN; + resDesc.SampleDesc.Count = 1; + resDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + + HRESULT hr = m_d3dDevice->CreateCommittedResource( + &heapProps, + D3D12_HEAP_FLAG_NONE, + &resDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(buffer->m_d3dBuffer.GetAddressOf())); + if (FAILED(hr)) + return nullptr; + + // Persistently map. UPLOAD heap memory is write-combined; keep mapped. + D3D12_RANGE readRange = {0, 0}; + hr = buffer->m_d3dBuffer->Map(0, &readRange, &buffer->m_d3dMappedPtr); + if (FAILED(hr)) + return nullptr; + + if (desc.data) + memcpy(buffer->m_d3dMappedPtr, desc.data, desc.size); + + return buffer; +#else + (void)desc; + return {}; +#endif +} + +// ============================================================================ +// d3d12MakeTexture +// ============================================================================ + +rcp ContextD3D12::d3d12MakeTexture(const TextureDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + auto texture = rcp(new Texture(desc)); + texture->m_d3dDevice = m_d3dDevice.Get(); + texture->m_d3dOreContext = this; + + const D3D12FormatInfo fmtInfo = oreFormatInfoD3D12(desc.format); + + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE; + D3D12_RESOURCE_STATES initialState; + const D3D12_CLEAR_VALUE* clearVal = nullptr; + D3D12_CLEAR_VALUE clearValue = {}; + + if (fmtInfo.isDepth) + { + flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + initialState = D3D12_RESOURCE_STATE_DEPTH_WRITE; + clearValue.Format = fmtInfo.dsv; + clearValue.DepthStencil.Depth = 1.0f; + clearValue.DepthStencil.Stencil = 0; + clearVal = &clearValue; + } + else if (desc.renderTarget) + { + flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + initialState = D3D12_RESOURCE_STATE_RENDER_TARGET; + clearValue.Format = fmtInfo.rtv; + clearValue.Color[3] = 1.0f; + clearVal = &clearValue; + } + else + { + initialState = D3D12_RESOURCE_STATE_COPY_DEST; + } + texture->m_d3dCurrentState = initialState; + + D3D12_HEAP_PROPERTIES heapProps = {}; + heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + + D3D12_RESOURCE_DESC resDesc = {}; + resDesc.MipLevels = static_cast(desc.numMipmaps); + resDesc.Format = fmtInfo.resource; + resDesc.Width = desc.width; + resDesc.Height = desc.height; + resDesc.Flags = flags; + resDesc.SampleDesc.Count = desc.sampleCount; + resDesc.SampleDesc.Quality = 0; + resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + + if (desc.type == TextureType::texture3D) + { + resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; + resDesc.DepthOrArraySize = static_cast(desc.depthOrArrayLayers); + } + else + { + resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resDesc.DepthOrArraySize = + (desc.type == TextureType::cube) + ? 6 + : static_cast(desc.depthOrArrayLayers); + } + + HRESULT hr = m_d3dDevice->CreateCommittedResource( + &heapProps, + D3D12_HEAP_FLAG_NONE, + &resDesc, + initialState, + clearVal, + IID_PPV_ARGS(texture->m_d3dTexture.GetAddressOf())); + if (FAILED(hr)) + return nullptr; + + return texture; +#else + (void)desc; + return {}; +#endif +} + +// ============================================================================ +// d3d12MakeTextureView +// ============================================================================ + +rcp ContextD3D12::d3d12MakeTextureView(const TextureViewDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + Texture* tex = desc.texture; + if (!tex) + return nullptr; + + auto view = rcp(new TextureView(ref_rcp(tex), desc)); + view->m_d3dOreContext = this; + + const D3D12FormatInfo fmtInfo = oreFormatInfoD3D12(tex->format()); + + // --- SRV --- + if (fmtInfo.srv != DXGI_FORMAT_UNKNOWN) + { + if (m_d3dCpuSrvAllocated >= 1024) + return nullptr; // CPU SRV descriptor heap exhausted. + D3D12_CPU_DESCRIPTOR_HANDLE handle = + m_d3dCpuSrvHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += (SIZE_T)m_d3dCpuSrvAllocated++ * m_d3dSrvDescSize; + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = fmtInfo.srv; + srvDesc.Shader4ComponentMapping = + D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + + switch (desc.dimension) + { + case TextureViewDimension::texture2D: + if (tex->sampleCount() > 1) + { + // MSAA resources require the _MS dimension variants. + // Using TEXTURE2D against a multisample resource is an + // illegal call that the driver caches and surfaces as + // DXGI_ERROR_INVALID_CALL → DEVICE_REMOVED at the next + // device API call. + if (desc.layerCount > 1) + { + srvDesc.ViewDimension = + D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc.Texture2DMSArray.FirstArraySlice = + desc.baseLayer; + srvDesc.Texture2DMSArray.ArraySize = desc.layerCount; + } + else + { + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; + } + } + else if (desc.layerCount > 1) + { + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture2DArray.MipLevels = desc.mipCount; + srvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + srvDesc.Texture2DArray.ArraySize = desc.layerCount; + } + else + { + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture2D.MipLevels = desc.mipCount; + } + break; + case TextureViewDimension::cube: + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MostDetailedMip = desc.baseMipLevel; + srvDesc.TextureCube.MipLevels = desc.mipCount; + break; + case TextureViewDimension::cubeArray: + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY; + srvDesc.TextureCubeArray.MostDetailedMip = desc.baseMipLevel; + srvDesc.TextureCubeArray.MipLevels = desc.mipCount; + srvDesc.TextureCubeArray.First2DArrayFace = desc.baseLayer; + srvDesc.TextureCubeArray.NumCubes = desc.layerCount / 6; + break; + case TextureViewDimension::texture3D: + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; + srvDesc.Texture3D.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture3D.MipLevels = desc.mipCount; + break; + case TextureViewDimension::array2D: + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = desc.baseMipLevel; + srvDesc.Texture2DArray.MipLevels = desc.mipCount; + srvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + srvDesc.Texture2DArray.ArraySize = desc.layerCount; + break; + } + + m_d3dDevice->CreateShaderResourceView(tex->m_d3dTexture.Get(), + &srvDesc, + handle); + view->m_d3dSrvHandle = handle; + } + + // --- RTV (colour only) --- + if (!fmtInfo.isDepth && tex->isRenderTarget() && + fmtInfo.rtv != DXGI_FORMAT_UNKNOWN) + { + D3D12_CPU_DESCRIPTOR_HANDLE handle = + m_d3dCpuRtvHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += (SIZE_T)m_d3dCpuRtvAllocated++ * m_d3dRtvDescSize; + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = fmtInfo.rtv; + + switch (desc.dimension) + { + case TextureViewDimension::texture2D: + if (tex->sampleCount() > 1) + { + // MSAA resources require the _MS dimension variants. + if (desc.layerCount > 1 || desc.baseLayer > 0) + { + rtvDesc.ViewDimension = + D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY; + rtvDesc.Texture2DMSArray.FirstArraySlice = + desc.baseLayer; + rtvDesc.Texture2DMSArray.ArraySize = desc.layerCount; + } + else + { + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; + } + } + else if (desc.layerCount > 1 || desc.baseLayer > 0) + { + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = desc.baseMipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + rtvDesc.Texture2DArray.ArraySize = desc.layerCount; + } + else + { + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = desc.baseMipLevel; + } + break; + case TextureViewDimension::cube: + case TextureViewDimension::cubeArray: + case TextureViewDimension::array2D: + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = desc.baseMipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + rtvDesc.Texture2DArray.ArraySize = desc.layerCount; + break; + case TextureViewDimension::texture3D: + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = desc.baseMipLevel; + rtvDesc.Texture3D.FirstWSlice = desc.baseLayer; + rtvDesc.Texture3D.WSize = desc.layerCount; + break; + } + + m_d3dDevice->CreateRenderTargetView(tex->m_d3dTexture.Get(), + &rtvDesc, + handle); + view->m_d3dRtvHandle = handle; + } + + // --- DSV (depth only) --- + if (fmtInfo.isDepth && fmtInfo.dsv != DXGI_FORMAT_UNKNOWN) + { + D3D12_CPU_DESCRIPTOR_HANDLE handle = + m_d3dCpuDsvHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += (SIZE_T)m_d3dCpuDsvAllocated++ * m_d3dDsvDescSize; + + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; + dsvDesc.Format = fmtInfo.dsv; + bool isArray = (desc.dimension == TextureViewDimension::array2D || + (desc.dimension == TextureViewDimension::texture2D && + (desc.layerCount > 1 || desc.baseLayer > 0))); + + if (tex->sampleCount() > 1) + { + // MSAA depth resources require the _MS dimension variants. + if (isArray) + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY; + dsvDesc.Texture2DMSArray.FirstArraySlice = desc.baseLayer; + dsvDesc.Texture2DMSArray.ArraySize = desc.layerCount; + } + else + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS; + } + } + else if (isArray) + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = desc.baseMipLevel; + dsvDesc.Texture2DArray.FirstArraySlice = desc.baseLayer; + dsvDesc.Texture2DArray.ArraySize = desc.layerCount; + } + else + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = desc.baseMipLevel; + } + + m_d3dDevice->CreateDepthStencilView(tex->m_d3dTexture.Get(), + &dsvDesc, + handle); + view->m_d3dDsvHandle = handle; + } + + return view; +#else + (void)desc; + return {}; +#endif +} + +// ============================================================================ +// d3d12MakeSampler +// ============================================================================ + +rcp ContextD3D12::d3d12MakeSampler(const SamplerDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + auto sampler = rcp(new Sampler()); + sampler->m_d3dOreContext = this; + + D3D12_CPU_DESCRIPTOR_HANDLE handle = + m_d3dCpuSamplerHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += (SIZE_T)m_d3dCpuSamplerAllocated++ * m_d3dSamplerDescSize; + + D3D12_SAMPLER_DESC sd = {}; + sd.Filter = oreFilterToD3D12(desc.minFilter, + desc.magFilter, + desc.mipmapFilter, + desc.compare, + desc.maxAnisotropy); + sd.AddressU = oreWrapToD3D12(desc.wrapU); + sd.AddressV = oreWrapToD3D12(desc.wrapV); + sd.AddressW = oreWrapToD3D12(desc.wrapW); + sd.MaxAnisotropy = desc.maxAnisotropy; + sd.ComparisonFunc = (desc.compare != CompareFunction::none) + ? oreCompareFunctionToD3D12(desc.compare) + : D3D12_COMPARISON_FUNC_ALWAYS; + sd.MinLOD = desc.minLod; + sd.MaxLOD = desc.maxLod; + + m_d3dDevice->CreateSampler(&sd, handle); + sampler->m_d3dSamplerHandle = handle; + + return sampler; +#else + (void)desc; + return {}; +#endif +} + +// ============================================================================ +// d3d12MakeShaderModule +// ============================================================================ + +rcp ContextD3D12::d3d12MakeShaderModule( + const ShaderModuleDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + auto module = rcp(new ShaderModule()); + + // HLSL source compiled in-process via D3DCompile. AMD drivers crash on + // cross-process DXBC, so we never ingest pre-compiled bytecode. + assert(desc.hlslSource && desc.hlslSourceSize > 0 && + "ShaderModuleDesc::hlslSource is required for the D3D12 backend"); + + // Normalize line endings (SPIRV-Cross emits \r\n on Windows). + std::string source(desc.hlslSource, desc.hlslSourceSize); + source.erase(std::remove(source.begin(), source.end(), '\r'), source.end()); + + const char* target = + (desc.stage == ShaderStage::fragment) ? "ps_5_0" : "vs_5_0"; + const char* entry = (desc.hlslEntryPoint && *desc.hlslEntryPoint) + ? desc.hlslEntryPoint + : "main"; + ComPtr compiled; + ComPtr errors; + HRESULT hr = D3DCompile(source.c_str(), + source.size(), + nullptr, + nullptr, + nullptr, + entry, + target, + D3DCOMPILE_ENABLE_STRICTNESS | + D3DCOMPILE_OPTIMIZATION_LEVEL3, + 0, + compiled.GetAddressOf(), + errors.GetAddressOf()); + if (FAILED(hr)) + { + const char* errMsg = + errors ? static_cast(errors->GetBufferPointer()) + : "(no error log)"; + setLastError( + "Ore D3D12: D3DCompile failed (entry=%s target=%s hr=0x%08x): %s", + entry, + target, + static_cast(hr), + errMsg); + return nullptr; + } + + const uint8_t* bytes = + static_cast(compiled->GetBufferPointer()); + module->m_d3dBytecode.assign(bytes, bytes + compiled->GetBufferSize()); + module->m_d3dIsVertex = (desc.stage == ShaderStage::vertex); + module->applyBindingMapFromDesc(desc); + return module; +#else + (void)desc; + return {}; +#endif +} + +// ============================================================================ +// d3d12MakePipeline +// ============================================================================ + +rcp ContextD3D12::d3d12MakePipeline(const PipelineDesc& desc, + std::string* outError) +{ + (void)outError; +#if defined(ORE_BACKEND_D3D12) + auto pipeline = rcp(new Pipeline(desc)); + pipeline->m_d3dOreContext = this; + pipeline->m_d3dTopology = oreTopologyToD3D12(desc.topology); + + // --- Validate user-supplied layouts against shader binding map --- + { + std::string err; + if (!validateLayoutsAgainstBindingMap(pipeline->m_bindingMap, + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + &err) || + !validateColorRequiresFragment(desc.colorCount, + desc.fragmentModule != nullptr, + &err)) + { + if (outError) + *outError = err; + else + setLastError("makePipeline: %s", err.c_str()); + return nullptr; + } + } + + // Per-pipeline root sig: composed from user-supplied BindGroupLayouts. + HRESULT rootSigHr = S_OK; + const char* rootSigErrMsg = nullptr; + pipeline->m_d3dRootSigOwned = + buildPerPipelineRootSig(m_d3dDevice.Get(), + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + pipeline->m_d3dGroupParams, + &rootSigHr, + &rootSigErrMsg); + if (!pipeline->m_d3dRootSigOwned) + { + // D3D12SerializeRootSignature/CreateRootSignature returned a + // failure HRESULT. Most common in practice: the device has been + // removed (TDR) or rejected the (otherwise valid) blob. Bail + // out gracefully so the caller's `if (!pipeline)` path runs + // instead of asserting in the helper. Per + // `feedback_lua_gpu_misuse_validation` — driver-side failure + // surfaces via `setLastError`, not a process abort. + HRESULT removedReason = m_d3dDevice->GetDeviceRemovedReason(); + setLastError("makePipeline: D3D12 root signature build failed " + "(label=%s, hr=0x%08lX, msg=%s, " + "deviceRemovedReason=0x%08lX)", + desc.label ? desc.label : "(none)", + static_cast(rootSigHr), + rootSigErrMsg ? rootSigErrMsg : "(none)", + static_cast(removedReason)); + if (outError) + *outError = lastError(); + return nullptr; + } + + // Cache vertex strides for use in RenderPass::setVertexBuffer(). + for (uint32_t i = 0; i < desc.vertexBufferCount && i < 8; ++i) + pipeline->m_d3dVertexStrides[i] = desc.vertexBuffers[i].stride; + + // --- Input layout elements --- + D3D12_INPUT_ELEMENT_DESC elements[32] = {}; + UINT elementCount = 0; + for (uint32_t bufIdx = 0; bufIdx < desc.vertexBufferCount; ++bufIdx) + { + const auto& layout = desc.vertexBuffers[bufIdx]; + for (uint32_t ai = 0; ai < layout.attributeCount; ++ai) + { + assert(elementCount < std::size(elements)); + const auto& attr = layout.attributes[ai]; + D3D12_INPUT_ELEMENT_DESC& el = elements[elementCount++]; + el.SemanticName = "TEXCOORD"; + el.SemanticIndex = attr.shaderSlot; + el.Format = oreVertexFormatToDXGI12(attr.format); + el.InputSlot = bufIdx; + el.AlignedByteOffset = attr.offset; + el.InputSlotClass = + layout.stepMode == VertexStepMode::instance + ? D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA + : D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + el.InstanceDataStepRate = + layout.stepMode == VertexStepMode::instance ? 1 : 0; + } + } + + // --- Blend state --- + D3D12_BLEND_DESC blendDesc = {}; + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = (desc.colorCount > 1) ? TRUE : FALSE; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ct = desc.colorTargets[i]; + auto& rt = blendDesc.RenderTarget[i]; + rt.BlendEnable = ct.blendEnabled ? TRUE : FALSE; + rt.SrcBlend = oreBlendFactorToD3D12(ct.blend.srcColor); + rt.DestBlend = oreBlendFactorToD3D12(ct.blend.dstColor); + rt.BlendOp = oreBlendOpToD3D12(ct.blend.colorOp); + rt.SrcBlendAlpha = oreBlendFactorToD3D12(ct.blend.srcAlpha); + rt.DestBlendAlpha = oreBlendFactorToD3D12(ct.blend.dstAlpha); + rt.BlendOpAlpha = oreBlendOpToD3D12(ct.blend.alphaOp); + rt.RenderTargetWriteMask = oreColorWriteMaskToD3D12(ct.writeMask); + rt.LogicOpEnable = FALSE; + rt.LogicOp = D3D12_LOGIC_OP_NOOP; + } + + // --- Rasterizer state --- + D3D12_RASTERIZER_DESC rastDesc = {}; + rastDesc.FillMode = D3D12_FILL_MODE_SOLID; + rastDesc.CullMode = (desc.cullMode == CullMode::none) ? D3D12_CULL_MODE_NONE + : (desc.cullMode == CullMode::front) + ? D3D12_CULL_MODE_FRONT + : D3D12_CULL_MODE_BACK; + rastDesc.FrontCounterClockwise = + (desc.winding == FaceWinding::counterClockwise) ? TRUE : FALSE; + rastDesc.DepthBias = desc.depthStencil.depthBias; + rastDesc.DepthBiasClamp = desc.depthStencil.depthBiasClamp; + rastDesc.SlopeScaledDepthBias = desc.depthStencil.depthBiasSlopeScale; + rastDesc.DepthClipEnable = TRUE; + rastDesc.MultisampleEnable = (desc.sampleCount > 1) ? TRUE : FALSE; + rastDesc.AntialiasedLineEnable = FALSE; + + // --- Depth/stencil state --- + D3D12_DEPTH_STENCIL_DESC dsDesc = {}; + dsDesc.DepthEnable = + (desc.depthStencil.depthCompare != CompareFunction::always || + desc.depthStencil.depthWriteEnabled) + ? TRUE + : FALSE; + dsDesc.DepthWriteMask = desc.depthStencil.depthWriteEnabled + ? D3D12_DEPTH_WRITE_MASK_ALL + : D3D12_DEPTH_WRITE_MASK_ZERO; + dsDesc.DepthFunc = + oreCompareFunctionToD3D12(desc.depthStencil.depthCompare); + + bool hasStencil = (desc.stencilFront.compare != CompareFunction::always || + desc.stencilFront.failOp != StencilOp::keep || + desc.stencilFront.depthFailOp != StencilOp::keep || + desc.stencilFront.passOp != StencilOp::keep || + desc.stencilBack.compare != CompareFunction::always || + desc.stencilBack.failOp != StencilOp::keep || + desc.stencilBack.depthFailOp != StencilOp::keep || + desc.stencilBack.passOp != StencilOp::keep); + dsDesc.StencilEnable = hasStencil ? TRUE : FALSE; + dsDesc.StencilReadMask = desc.stencilReadMask; + dsDesc.StencilWriteMask = desc.stencilWriteMask; + + auto fillStencilOp = [](D3D12_DEPTH_STENCILOP_DESC& out, + const StencilFaceState& s) { + out.StencilFailOp = oreStencilOpToD3D12(s.failOp); + out.StencilDepthFailOp = oreStencilOpToD3D12(s.depthFailOp); + out.StencilPassOp = oreStencilOpToD3D12(s.passOp); + out.StencilFunc = oreCompareFunctionToD3D12(s.compare); + }; + fillStencilOp(dsDesc.FrontFace, desc.stencilFront); + fillStencilOp(dsDesc.BackFace, desc.stencilBack); + + // --- Determine DSV and MSAA formats --- + DXGI_FORMAT dsvFormat = DXGI_FORMAT_UNKNOWN; + if (dsDesc.DepthEnable || hasStencil) + dsvFormat = oreFormatInfoD3D12(desc.depthStencil.format).dsv; + + // --- Build PSO --- + D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + psoDesc.pRootSignature = pipeline->m_d3dRootSigOwned.Get(); + psoDesc.VS.pShaderBytecode = desc.vertexModule->m_d3dBytecode.data(); + psoDesc.VS.BytecodeLength = desc.vertexModule->m_d3dBytecode.size(); + if (desc.fragmentModule != nullptr) + { + psoDesc.PS.pShaderBytecode = desc.fragmentModule->m_d3dBytecode.data(); + psoDesc.PS.BytecodeLength = desc.fragmentModule->m_d3dBytecode.size(); + } + // else: psoDesc.PS stays zero — D3D12 allows null PS for depth-only. + psoDesc.BlendState = blendDesc; + psoDesc.SampleMask = UINT_MAX; + psoDesc.RasterizerState = rastDesc; + psoDesc.DepthStencilState = dsDesc; + psoDesc.InputLayout = {elements, elementCount}; + psoDesc.PrimitiveTopologyType = oreTopologyTypeToD3D12(desc.topology); + psoDesc.NumRenderTargets = desc.colorCount; + for (uint32_t i = 0; i < desc.colorCount; ++i) + psoDesc.RTVFormats[i] = + oreFormatInfoD3D12(desc.colorTargets[i].format).rtv; + psoDesc.DSVFormat = dsvFormat; + psoDesc.SampleDesc.Count = desc.sampleCount; + psoDesc.SampleDesc.Quality = 0; + + HRESULT hr = m_d3dDevice->CreateGraphicsPipelineState( + &psoDesc, + IID_PPV_ARGS(pipeline->m_d3dPSO.GetAddressOf())); + if (FAILED(hr)) + { + if (outError) + *outError = "CreateGraphicsPipelineState failed"; + return nullptr; + } + + return pipeline; +#else + (void)desc; + return {}; +#endif +} + +// ===================================================================== + +// ============================================================================ +// d3d12MakeBindGroup +// ============================================================================ + +rcp ContextD3D12::d3d12MakeBindGroup(const BindGroupDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + if (desc.layout == nullptr) + { + setLastError("makeBindGroup: BindGroupDesc::layout is null"); + return nullptr; + } + BindGroupLayout* layout = desc.layout; + const uint32_t groupIndex = layout->groupIndex(); + if (groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroup: layout->groupIndex %u out of range", + groupIndex); + return nullptr; + } + + auto bg = rcp(new BindGroup()); + bg->m_context = this; + bg->m_layoutRef = ref_rcp(layout); + + // Count dynamic-offset UBOs declared by the layout — authoritative. + uint32_t dynamicCount = 0; + for (const auto& e : layout->entries()) + { + if (e.kind == BindingKind::uniformBuffer && e.hasDynamicOffset) + ++dynamicCount; + } + bg->m_dynamicOffsetCount = dynamicCount; + + // Native HLSL register slot per binding comes from the layout's + // pre-resolved nativeSlotVS/FS (D3D12 root tables are stage-shared, + // so VS slot suffices; fall back to FS for FS-only resources). + auto nativeSlot = + [&](uint32_t binding, BindingKind expected, uint32_t* outSlot) -> bool { + const BindGroupLayoutEntry* le = layout->findEntry(binding); + if (le == nullptr) + { + setLastError("makeBindGroup: (group=%u, binding=%u) not declared " + "in BindGroupLayout", + groupIndex, + binding); + return false; + } + const bool kindOK = le->kind == expected || + ((le->kind == BindingKind::sampler || + le->kind == BindingKind::comparisonSampler) && + (expected == BindingKind::sampler || + expected == BindingKind::comparisonSampler)); + if (!kindOK) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout kind " + "mismatch", + groupIndex, + binding); + return false; + } + uint32_t s = + (le->nativeSlotVS != BindGroupLayoutEntry::kNativeSlotAbsent) + ? le->nativeSlotVS + : le->nativeSlotFS; + if (s == BindGroupLayoutEntry::kNativeSlotAbsent) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout has " + "no resolved native slot — call " + "makeLayoutFromShader", + groupIndex, + binding); + return false; + } + *outSlot = s; + return true; + }; + + // UBO bindings. + for (uint32_t i = 0; i < desc.uboCount; ++i) + { + const auto& entry = desc.ubos[i]; + assert(entry.buffer != nullptr); + uint32_t slot = 0; + if (!nativeSlot(entry.slot, BindingKind::uniformBuffer, &slot)) + continue; + assert(slot < 8); + bg->m_d3dUBOAddresses[slot] = + entry.buffer->m_d3dBuffer->GetGPUVirtualAddress() + entry.offset; + bg->m_d3dUBOSizes[slot] = + entry.size > 0 ? entry.size + : static_cast(entry.buffer->size()); + bg->m_d3dUBOSlotMask |= static_cast(1u << slot); + if (layout->hasDynamicOffset(entry.slot)) + bg->m_d3dUBODynamicOffsetMask |= static_cast(1u << slot); + bg->m_retainedBuffers.push_back(ref_rcp(entry.buffer)); + } + + // Texture bindings. + for (uint32_t i = 0; i < desc.textureCount; ++i) + { + const auto& entry = desc.textures[i]; + assert(entry.view != nullptr); + uint32_t slot = 0; + if (!nativeSlot(entry.slot, BindingKind::sampledTexture, &slot)) + continue; + assert(slot < 8); + bg->m_d3dSrvHandles[slot] = entry.view->m_d3dSrvHandle; + bg->m_d3dSrvTextures[slot] = entry.view->texture(); + bg->m_d3dSrvSlotMask |= static_cast(1u << slot); + bg->m_retainedViews.push_back(ref_rcp(entry.view)); + } + + // Sampler bindings. + for (uint32_t i = 0; i < desc.samplerCount; ++i) + { + const auto& entry = desc.samplers[i]; + assert(entry.sampler != nullptr); + uint32_t slot = 0; + if (!nativeSlot(entry.slot, BindingKind::sampler, &slot)) + continue; + assert(slot < 8); + bg->m_d3dSamplerHandles[slot] = entry.sampler->m_d3dSamplerHandle; + bg->m_d3dSamplerSlotMask |= static_cast(1u << slot); + bg->m_retainedSamplers.push_back(ref_rcp(entry.sampler)); + } + + return bg; +#else + (void)desc; + return nullptr; +#endif +} + +// ============================================================================ +// d3d12MakeBindGroupLayout +// ============================================================================ + +rcp ContextD3D12::d3d12MakeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ +#if defined(ORE_BACKEND_D3D12) + if (desc.groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroupLayout: groupIndex %u out of range [0, %u)", + desc.groupIndex, + kMaxBindGroups); + return nullptr; + } + auto layout = rcp(new BindGroupLayout()); + layout->m_context = this; + layout->m_groupIndex = desc.groupIndex; + layout->m_entries.reserve(desc.entryCount); + for (uint32_t i = 0; i < desc.entryCount; ++i) + layout->m_entries.push_back(desc.entries[i]); + + // Pre-compute D3D12 per-group descriptor-table shape from the user's + // entries. The pipeline's root sig will compose these at makePipeline + // time, assigning final root-parameter indices. + tallyGroupFromLayoutDesc(desc, &layout->m_d3dGroupParams); + return layout; +#else + (void)desc; + return nullptr; +#endif +} + +// ============================================================================ +// d3d12BeginRenderPass +// ============================================================================ + +RenderPass ContextD3D12::d3d12BeginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ +#if defined(ORE_BACKEND_D3D12) + // Flush any pending texture uploads before rendering. + d3d12FlushUploads(); + + RenderPass pass; + pass.m_context = this; + pass.m_d3dCmdList = m_d3dCmdList; + pass.m_d3dDevice = m_d3dDevice.Get(); + pass.m_d3dContext = this; + // `m_d3dCurrentRootSig` starts nullptr; the first `setPipeline` + // calls `SetGraphicsRootSignature` with the pipeline's sig (every + // pipeline ships with its own per RFC v5 §3.2.2). + pass.populateAttachmentMetadata(desc); + + // Collect RTVs and DSV handles, transitioning resources to the correct + // state. + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandles[4] = {}; + D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = {}; + bool hasDsv = false; + + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + TextureView* view = desc.colorAttachments[i].view; + assert(view != nullptr); + + Texture* tex = view->texture(); + if (tex->m_d3dCurrentState != D3D12_RESOURCE_STATE_RENDER_TARGET) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = tex->m_d3dTexture.Get(); + barrier.Transition.StateBefore = tex->m_d3dCurrentState; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + tex->m_d3dCurrentState = D3D12_RESOURCE_STATE_RENDER_TARGET; + } + + rtvHandles[i] = view->m_d3dRtvHandle; + + // Record resource + final state for finish() to transition back. + pass.m_d3dColorResources[i] = tex->m_d3dTexture.Get(); + pass.m_d3dColorTextures[i] = tex; + // External (canvas) textures go back to COMMON; ORE-owned go to + // PIXEL_SHADER_RESOURCE. + const D3D12_RESOURCE_STATES colourFinalState = + tex->m_d3dIsExternal ? D3D12_RESOURCE_STATE_COMMON + : D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + pass.m_d3dColorFinalStates[i] = colourFinalState; + pass.m_d3dColorCount++; + + // Record MSAA resolve pair if present. D3D12 subresource index + // for the common single-plane case is mipLevel + arraySlice*mipCount. + TextureView* resolveView = desc.colorAttachments[i].resolveTarget; + if (resolveView != nullptr && resolveView->texture() != nullptr) + { + Texture* resolveTex = resolveView->texture(); + auto& r = pass.m_d3dResolves[pass.m_d3dResolveCount++]; + r.msaa = tex->m_d3dTexture.Get(); + r.resolve = resolveTex->m_d3dTexture.Get(); + r.resolveTex = resolveTex; + r.format = oreFormatInfoD3D12(resolveTex->format()).resource; + const uint32_t msaaMips = tex->numMipmaps(); + const uint32_t resolveMips = resolveTex->numMipmaps(); + r.msaaSubresource = + view->baseMipLevel() + view->baseLayer() * msaaMips; + r.resolveSubresource = resolveView->baseMipLevel() + + resolveView->baseLayer() * resolveMips; + r.resolvePriorState = resolveTex->m_d3dCurrentState; + r.resolveFinalState = + resolveTex->m_d3dIsExternal + ? D3D12_RESOURCE_STATE_COMMON + : D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + } + } + + if (desc.depthStencil.view) + { + TextureView* dsView = desc.depthStencil.view; + Texture* dsTex = dsView->texture(); + + D3D12_RESOURCE_STATES dsTarget = D3D12_RESOURCE_STATE_DEPTH_WRITE; + if (dsTex->m_d3dCurrentState != dsTarget) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = dsTex->m_d3dTexture.Get(); + barrier.Transition.StateBefore = dsTex->m_d3dCurrentState; + barrier.Transition.StateAfter = dsTarget; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + dsTex->m_d3dCurrentState = dsTarget; + } + + dsvHandle = dsView->m_d3dDsvHandle; + hasDsv = true; + + pass.m_d3dDepthResource = dsTex->m_d3dTexture.Get(); + pass.m_d3dDepthTexture = dsTex; + // When the depth is stored the caller intends to sample it as a + // shader resource (e.g. shadow map read-back), so transition to + // PIXEL_SHADER_RESOURCE. Otherwise DEPTH_READ is sufficient. + pass.m_d3dDepthFinalState = + (desc.depthStencil.depthStoreOp == StoreOp::store) + ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + : D3D12_RESOURCE_STATE_DEPTH_READ; + } + + m_d3dCmdList->OMSetRenderTargets(desc.colorCount, + rtvHandles, + FALSE, + hasDsv ? &dsvHandle : nullptr); + + // Handle clear ops. + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + if (ca.loadOp == LoadOp::clear) + { + float c[4] = {ca.clearColor.r, + ca.clearColor.g, + ca.clearColor.b, + ca.clearColor.a}; + m_d3dCmdList->ClearRenderTargetView(rtvHandles[i], c, 0, nullptr); + } + } + + // Default viewport + scissor covering the full attachment. D3D12 + // initialises viewport/scissor to zero on a fresh command list which + // clips all geometry. Metal defaults to the full attachment size, so + // scripts that omit setViewport() work on Metal but would produce empty + // output on D3D12 without this. Mirrors d3d11BeginRenderPass. + { + uint32_t w = 0, h = 0; + if (desc.colorCount > 0 && desc.colorAttachments[0].view) + { + w = desc.colorAttachments[0].view->texture()->width(); + h = desc.colorAttachments[0].view->texture()->height(); + } + else if (desc.depthStencil.view) + { + w = desc.depthStencil.view->texture()->width(); + h = desc.depthStencil.view->texture()->height(); + } + if (w > 0 && h > 0) + { + D3D12_VIEWPORT vp = {0.f, + 0.f, + static_cast(w), + static_cast(h), + 0.f, + 1.f}; + m_d3dCmdList->RSSetViewports(1, &vp); + D3D12_RECT scissor = {0, 0, (LONG)w, (LONG)h}; + m_d3dCmdList->RSSetScissorRects(1, &scissor); + } + } + + if (hasDsv && desc.depthStencil.view) + { + D3D12_CLEAR_FLAGS clearFlags = {}; + if (desc.depthStencil.depthLoadOp == LoadOp::clear) + clearFlags |= D3D12_CLEAR_FLAG_DEPTH; + TextureFormat depthFmt = desc.depthStencil.view->texture()->format(); + bool hasStencil = (depthFmt == TextureFormat::depth24plusStencil8 || + depthFmt == TextureFormat::depth32floatStencil8); + if (hasStencil && desc.depthStencil.stencilLoadOp == LoadOp::clear) + clearFlags |= D3D12_CLEAR_FLAG_STENCIL; + if (clearFlags) + m_d3dCmdList->ClearDepthStencilView( + dsvHandle, + clearFlags, + desc.depthStencil.depthClearValue, + static_cast(desc.depthStencil.stencilClearValue), + 0, + nullptr); + } + + return pass; +#else + (void)desc; + return RenderPass{}; +#endif +} + +// ============================================================================ +// d3d12WrapCanvasTexture +// ============================================================================ + +rcp ContextD3D12::d3d12WrapCanvasTexture(gpu::RenderCanvas* canvas) +{ +#if defined(ORE_BACKEND_D3D12) + assert(canvas != nullptr); + + auto* d3dTarget = + static_cast(canvas->renderTarget()); + gpu::D3D12Texture* d3dTex = d3dTarget->targetTexture(); + assert(d3dTex != nullptr); + + DXGI_FORMAT dxgiFmt = d3dTex->format(); + + TextureFormat oreFormat; + switch (dxgiFmt) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + oreFormat = TextureFormat::rgba8unorm; + break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + oreFormat = TextureFormat::rgba16float; + break; + case DXGI_FORMAT_R10G10B10A2_UNORM: + oreFormat = TextureFormat::rgb10a2unorm; + break; + default: /* DXGI_FORMAT_B8G8R8A8_UNORM */ + oreFormat = TextureFormat::bgra8unorm; + break; + } + + TextureDesc texDesc{}; + texDesc.width = canvas->width(); + texDesc.height = canvas->height(); + texDesc.format = oreFormat; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = true; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_d3dTexture = + d3dTex->resource(); // Borrow — RenderCanvas owns it. + texture->m_d3dCurrentState = D3D12_RESOURCE_STATE_COMMON; + texture->m_d3dIsExternal = true; + texture->m_d3dDevice = m_d3dDevice.Get(); + texture->m_d3dOreContext = this; + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_d3dOreContext = this; + + // Create the RTV in our CPU RTV heap. + D3D12_CPU_DESCRIPTOR_HANDLE handle = + m_d3dCpuRtvHeap->GetCPUDescriptorHandleForHeapStart(); + handle.ptr += (SIZE_T)m_d3dCpuRtvAllocated++ * m_d3dRtvDescSize; + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = dxgiFmt; + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = 0; + + m_d3dDevice->CreateRenderTargetView(d3dTex->resource(), &rtvDesc, handle); + view->m_d3dRtvHandle = handle; + + return view; +#else + (void)canvas; + return {}; +#endif +} + +rcp ContextD3D12::d3d12WrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ +#if defined(ORE_BACKEND_D3D12) + if (!gpuTex) + return nullptr; + + // nativeHandle() returns a D3D12Texture* for D3D12. + auto* d3dTex = static_cast(gpuTex->nativeHandle()); + if (!d3dTex) + return nullptr; + + DXGI_FORMAT dxgiFmt = d3dTex->format(); + + TextureFormat oreFormat; + switch (dxgiFmt) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + oreFormat = TextureFormat::rgba8unorm; + break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + oreFormat = TextureFormat::rgba16float; + break; + case DXGI_FORMAT_R10G10B10A2_UNORM: + oreFormat = TextureFormat::rgb10a2unorm; + break; + default: /* DXGI_FORMAT_B8G8R8A8_UNORM */ + oreFormat = TextureFormat::bgra8unorm; + break; + } + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = oreFormat; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = false; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_d3dTexture = d3dTex->resource(); // Borrow. + texture->m_d3dCurrentState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + texture->m_d3dIsExternal = true; + texture->m_d3dDevice = m_d3dDevice.Get(); + texture->m_d3dOreContext = this; + + // In external-CL mode the Rive texture may be in any state coming out of + // Rive's last recording (e.g. RENDER_TARGET from a PLS flush). Emit a + // transition into the same CL so the draw we're about to record sees it + // in PIXEL_SHADER_RESOURCE. This is the D3D12 analogue of the Vulkan + // wrapRiveTexture barrier — but we only do it when external-CL mode is + // active, because in owned-CL mode the Ore CL is submitted before Rive's + // CL and a barrier recorded here would reference a state the texture + // isn't actually in at submission time. + if (m_d3dExternalCmdList) + { + assert(m_d3dCmdList != nullptr); + auto* manager = + static_cast(d3dTex->manager()); + if (manager != nullptr && + d3dTex->lastState() != D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) + { + manager->transition(m_d3dCmdList, + d3dTex, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + } + } + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_d3dOreContext = this; + // Create SRV for sampling (images are read-only, no RTV needed). + if (m_d3dCpuSrvAllocated >= 1024) + return nullptr; // CPU SRV descriptor heap exhausted. + D3D12_CPU_DESCRIPTOR_HANDLE srvHandle = + m_d3dCpuSrvHeap->GetCPUDescriptorHandleForHeapStart(); + srvHandle.ptr += (SIZE_T)m_d3dCpuSrvAllocated++ * m_d3dSrvDescSize; + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = dxgiFmt; + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srvDesc.Texture2D.MipLevels = 1; + + m_d3dDevice->CreateShaderResourceView(d3dTex->resource(), + &srvDesc, + srvHandle); + view->m_d3dSrvHandle = srvHandle; + return view; +#else + (void)gpuTex; + (void)w; + (void)h; + return nullptr; +#endif +} + +// ============================================================================ +// Public method definitions (D3D12-only builds) +// ============================================================================ + +rcp ContextD3D12::makeBuffer(const BufferDesc& desc) +{ + return d3d12MakeBuffer(desc); +} + +rcp ContextD3D12::makeTexture(const TextureDesc& desc) +{ + return d3d12MakeTexture(desc); +} + +rcp ContextD3D12::makeTextureView(const TextureViewDesc& desc) +{ + return d3d12MakeTextureView(desc); +} + +rcp ContextD3D12::makeSampler(const SamplerDesc& desc) +{ + return d3d12MakeSampler(desc); +} + +rcp ContextD3D12::makeShaderModule(const ShaderModuleDesc& desc) +{ + return d3d12MakeShaderModule(desc); +} + +rcp ContextD3D12::makePipeline(const PipelineDesc& desc, + std::string* outError) +{ + return d3d12MakePipeline(desc, outError); +} + +rcp ContextD3D12::makeBindGroup(const BindGroupDesc& desc) +{ + return d3d12MakeBindGroup(desc); +} + +rcp ContextD3D12::makeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + return d3d12MakeBindGroupLayout(desc); +} + +RenderPass ContextD3D12::beginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + finishActiveRenderPass(); + return d3d12BeginRenderPass(desc, outError); +} + +rcp ContextD3D12::wrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + return d3d12WrapCanvasTexture(canvas); +} + +rcp ContextD3D12::wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + return d3d12WrapRiveTexture(gpuTex, w, h); +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_bind_group_apply.hpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_bind_group_apply.hpp new file mode 100644 index 000000000..abdc88846 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_bind_group_apply.hpp @@ -0,0 +1,219 @@ +/* + * Copyright 2026 Rive + * + * Shared D3D12 body for `RenderPass::setBindGroup`. Builds one merged + * CBV/SRV/UAV descriptor table per group + one sampler table per group + * using the per-pipeline root sig (RFC v5 §3.2.2 / "Commit 7b"). See + * `ore_d3d12_root_sig.hpp` for the root-sig layout. + * + * Defined inline here because two translation units need to call it: + * the D3D12-only build compiles `ore_render_pass_d3d12.cpp` + * standalone, and the combined Windows build compiles + * `ore_render_pass_d3d11_d3d12.cpp` (which runtime-dispatches to + * D3D11 or D3D12 based on which context opened the pass). Before + * this header both files carried a copy of the same logic. + */ + +#pragma once + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" + +#include +#include +#include +#include + +namespace rive::ore +{ + +inline void RenderPass::d3d12ApplyBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + assert(groupIndex < 4); // RFC v4 §9.1 / §14.2. + + Pipeline* pipe = m_d3dCurrentPipeline.get(); + assert(pipe != nullptr && pipe->m_d3dRootSigOwned && + "d3d12ApplyBindGroup: pipeline missing per-pipeline root sig — " + "every Ore D3D12 pipeline must ship with a populated binding map"); + + const auto& gp = pipe->m_d3dGroupParams[groupIndex]; + uint32_t dynIdx = 0; + + // Merged CBV/SRV/UAV table. + if (gp.cbvSrvUavRootParamIdx >= 0) + { + uint32_t total = uint32_t(gp.cbvCount) + uint32_t(gp.srvCount) + + uint32_t(gp.uavCount); + UINT heapStart = m_d3dContext->d3d12AllocGpuSrvSlots(total); + if (heapStart == UINT_MAX) + { + // Heap exhausted — `setLastError` was already populated by + // the allocator. Skip this table; subsequent draw will read + // whatever (stale) descriptors are still bound from the + // last successful call. Better than the prior assert/hang. + return; + } + uint32_t offset = 0; + + // CBVs: create D3D12_CONSTANT_BUFFER_VIEW_DESC descriptors in + // the shader-visible heap on the fly, one per slot covered by + // this group's CBV range. Null CBVs are left as default-init + // descriptor slots (CreateConstantBufferView(nullptr, ...) + // writes the D3D12-defined null CBV per the spec). + for (uint8_t i = 0; i < gp.cbvCount; ++i) + { + uint8_t globalSlot = gp.cbvBaseGlobalSlot + i; + D3D12_CPU_DESCRIPTOR_HANDLE dst = + m_d3dContext->d3d12GpuSrvCpuHandle(heapStart + offset++); + if (bg->m_d3dUBOSlotMask & (1u << globalSlot)) + { + D3D12_GPU_VIRTUAL_ADDRESS gpuVA = + bg->m_d3dUBOAddresses[globalSlot]; + if ((bg->m_d3dUBODynamicOffsetMask & (1u << globalSlot)) && + dynIdx < dynamicOffsetCount) + { + gpuVA += dynamicOffsets[dynIdx]; + ++dynIdx; + } + // CBV sizes must be 256-byte aligned per D3D12 spec. + uint32_t size = bg->m_d3dUBOSizes[globalSlot]; + size = (size + 255u) & ~255u; + D3D12_CONSTANT_BUFFER_VIEW_DESC cbv = {}; + cbv.BufferLocation = gpuVA; + cbv.SizeInBytes = size; + m_d3dDevice->CreateConstantBufferView(&cbv, dst); + } + else + { + m_d3dDevice->CreateConstantBufferView(nullptr, dst); + } + } + + // SRVs: copy each group-local SRV slot's CPU handle into the + // heap. Missing slots fall back to the context's null SRV + // descriptor so the table stays well-defined. + // + // Resource-state transitions: D3D12 requires textures bound as + // SRVs to be in a shader-resource state for the stages that + // sample them. Ore doesn't know which stages a given binding + // group will be sampled from at apply time, so transition into + // the *union* state — `PIXEL_SHADER_RESOURCE` for fragment + // samples plus `NON_PIXEL_SHADER_RESOURCE` for vertex/etc. + // samples — and require the texture to *already* cover both + // before skipping the barrier. + // + // Two cases this catches: + // 1. Depth-stencil texture born in `DEPTH_WRITE` (because + // `renderTarget=true`) and never attached as a DSV before + // being sampled. `ore_binding_shadow_sampler_d32` GM. + // 2. Color attachment finished into just + // `PIXEL_SHADER_RESOURCE` by an earlier render pass, then + // sampled from a *vertex* shader. `ore_binding_vs_texture` + // GM. Without `NON_PIXEL_SHADER_RESOURCE`, GBV fires + // `id=1358 Incompatible texture barrier layout: Shader + // Stage: VERTEX, Layout: + // D3D12_BARRIER_LAYOUT_LEGACY_PIXEL_SHADER_RESOURCE`. + // + // Without these barriers GPU-Based Validation eventually TDRs + // the device with `DXGI_ERROR_DEVICE_HUNG`. + constexpr D3D12_RESOURCE_STATES kSrvStates = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + for (uint8_t i = 0; i < gp.srvCount; ++i) + { + uint8_t globalSlot = gp.srvBaseGlobalSlot + i; + if (!(bg->m_d3dSrvSlotMask & (1u << globalSlot))) + continue; + Texture* tex = bg->m_d3dSrvTextures[globalSlot]; + if (tex == nullptr) + continue; + // Require *full* coverage of both shader-stage bits, not + // just any overlap. A texture in just + // `PIXEL_SHADER_RESOURCE` (typical post-finish state for + // color attachments) needs the `NON_PIXEL_SHADER_RESOURCE` + // bit added before a vertex-stage sample. + if ((tex->m_d3dCurrentState & kSrvStates) == kSrvStates) + continue; + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = tex->m_d3dTexture.Get(); + barrier.Transition.StateBefore = tex->m_d3dCurrentState; + barrier.Transition.StateAfter = kSrvStates; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + tex->m_d3dCurrentState = kSrvStates; + } + for (uint8_t i = 0; i < gp.srvCount; ++i) + { + uint8_t globalSlot = gp.srvBaseGlobalSlot + i; + D3D12_CPU_DESCRIPTOR_HANDLE dst = + m_d3dContext->d3d12GpuSrvCpuHandle(heapStart + offset++); + D3D12_CPU_DESCRIPTOR_HANDLE src = + (bg->m_d3dSrvSlotMask & (1u << globalSlot)) + ? bg->m_d3dSrvHandles[globalSlot] + : m_d3dContext->m_d3dNullSrv; + m_d3dDevice->CopyDescriptorsSimple( + 1, + dst, + src, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + // UAVs: Ore doesn't ship storage buffers/textures on day 1, + // but the helper reserves slots for forward-compat. Null-fill + // for now; the loop no-ops at gp.uavCount == 0. + for (uint8_t i = 0; i < gp.uavCount; ++i) + { + D3D12_CPU_DESCRIPTOR_HANDLE dst = + m_d3dContext->d3d12GpuSrvCpuHandle(heapStart + offset++); + m_d3dDevice->CopyDescriptorsSimple( + 1, + dst, + m_d3dContext->m_d3dNullSrv, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + } + + D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = + m_d3dContext->d3d12GpuSrvGpuHandle(heapStart); + m_d3dCmdList->SetGraphicsRootDescriptorTable( + static_cast(gp.cbvSrvUavRootParamIdx), + gpuHandle); + } + + // Sampler table (separate heap type). + if (gp.samplerRootParamIdx >= 0) + { + UINT heapStart = + m_d3dContext->d3d12AllocGpuSamplerSlots(gp.samplerCount); + if (heapStart == UINT_MAX) + return; + for (uint8_t i = 0; i < gp.samplerCount; ++i) + { + uint8_t globalSlot = gp.samplerBaseGlobalSlot + i; + D3D12_CPU_DESCRIPTOR_HANDLE dst = + m_d3dContext->d3d12GpuSamplerCpuHandle(heapStart + i); + D3D12_CPU_DESCRIPTOR_HANDLE src = + (bg->m_d3dSamplerSlotMask & (1u << globalSlot)) + ? bg->m_d3dSamplerHandles[globalSlot] + : m_d3dContext->m_d3dNullSampler; + m_d3dDevice->CopyDescriptorsSimple( + 1, + dst, + src, + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + } + D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = + m_d3dContext->d3d12GpuSamplerGpuHandle(heapStart); + m_d3dCmdList->SetGraphicsRootDescriptorTable( + static_cast(gp.samplerRootParamIdx), + gpuHandle); + } +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_root_sig.hpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_root_sig.hpp new file mode 100644 index 000000000..5743a89fb --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_d3d12_root_sig.hpp @@ -0,0 +1,249 @@ +/* + * Copyright 2026 Rive + * + * Private helper for building a per-pipeline ID3D12RootSignature from the + * pipeline's ore::BindingMap (RFC v5 §3.2.2 / "Commit 7b"). + * + * The rule: each `@group(g)` that has any bindings gets one or two dedicated + * root parameters in the pipeline's root signature: + * + * - One merged CBV/SRV/UAV descriptor table per group (if the group has + * any CBVs, SRVs, or UAVs). Ranges are packed in a canonical order + * (CBV → SRV → UAV) and appended contiguously into the GPU heap slice. + * - One sampler descriptor table per group (if the group has any samplers + * or comparison samplers). D3D12 requires samplers in a separate heap + * from CBV/SRV/UAV, so this is a distinct root parameter. + * + * All ranges use `RegisterSpace = 0` — the allocator emits SM5.0 HLSL with a + * single `space=0`, and the per-group isolation comes from each group's + * descriptor table spanning a disjoint `BaseShaderRegister` range. See RFC + * v5 §3.2.2 for the full rationale and comparison to Dawn's SM5.1+ approach. + * + * `SetGraphicsRootDescriptorTable(groupRootParamIdx, ...)` called at + * `setBindGroup(g, bg)` time is scoped to group g's root parameters only — + * other groups' already-bound tables survive across calls. This is the + * invariant that makes multi-group bind groups on D3D12 work at all. + */ + +#pragma once + +#include "rive/renderer/ore/ore_bind_group_layout.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" // D3D12GroupRootParams + +#include +#include +#include +#include + +namespace rive::ore +{ + +// D3D12-side alias for Ore's central `kMaxBindGroups`. +constexpr uint32_t kD3D12MaxGroups = kMaxBindGroups; + +// Walk a `BindGroupLayoutDesc`'s entries and populate the layout's +// `D3D12GroupRootParams` shape (counts + min global slot per kind). +// HLSL SM5 has a merged VS/PS register namespace, so the global slot +// can come from either stage's nativeSlot field. +inline void tallyGroupFromLayoutDesc(const BindGroupLayoutDesc& desc, + D3D12GroupRootParams* out) +{ + *out = D3D12GroupRootParams{}; + uint8_t cbvMin = 0xFF, srvMin = 0xFF, uavMin = 0xFF, sampMin = 0xFF; + + for (uint32_t i = 0; i < desc.entryCount; ++i) + { + const BindGroupLayoutEntry& e = desc.entries[i]; + // Pick a non-absent native slot (VS preferred). + uint32_t slot32 = + (e.nativeSlotVS != BindGroupLayoutEntry::kNativeSlotAbsent) + ? e.nativeSlotVS + : e.nativeSlotFS; + if (slot32 == BindGroupLayoutEntry::kNativeSlotAbsent) + continue; + uint8_t slot = static_cast(slot32); + + switch (e.kind) + { + case BindingKind::uniformBuffer: + out->cbvCount++; + if (slot < cbvMin) + cbvMin = slot; + break; + case BindingKind::sampledTexture: + case BindingKind::storageBufferRO: + out->srvCount++; + if (slot < srvMin) + srvMin = slot; + break; + case BindingKind::storageBufferRW: + case BindingKind::storageTexture: + out->uavCount++; + if (slot < uavMin) + uavMin = slot; + break; + case BindingKind::sampler: + case BindingKind::comparisonSampler: + out->samplerCount++; + if (slot < sampMin) + sampMin = slot; + break; + } + } + out->cbvBaseGlobalSlot = (cbvMin == 0xFF) ? 0 : cbvMin; + out->srvBaseGlobalSlot = (srvMin == 0xFF) ? 0 : srvMin; + out->uavBaseGlobalSlot = (uavMin == 0xFF) ? 0 : uavMin; + out->samplerBaseGlobalSlot = (sampMin == 0xFF) ? 0 : sampMin; + out->cbvSrvUavRootParamIdx = -1; + out->samplerRootParamIdx = -1; +} + +// Build a per-pipeline `ID3D12RootSignature` from user-supplied +// BindGroupLayouts, and populate `groupOut[kD3D12MaxGroups]` with the +// composed root-parameter indices + per-kind ranges (mirrored from each +// layout's pre-computed shape). Returns `nullptr` on failure. +inline Microsoft::WRL::ComPtr buildPerPipelineRootSig( + ID3D12Device* device, + BindGroupLayout* const* layouts, + uint32_t layoutCount, + D3D12GroupRootParams groupOut[kD3D12MaxGroups], + HRESULT* outHr = nullptr, + const char** outErrMsg = nullptr) +{ + // ── Step 1: build root parameters + ranges from layouts ── + constexpr uint32_t kMaxParams = 2 * kD3D12MaxGroups; + D3D12_ROOT_PARAMETER rootParams[kMaxParams]{}; + D3D12_DESCRIPTOR_RANGE ranges[kMaxParams * 3]{}; + uint32_t paramCount = 0; + uint32_t rangeCount = 0; + + for (uint32_t g = 0; g < kD3D12MaxGroups; ++g) + { + // Default-initialize this group's pipeline-side params. + groupOut[g] = D3D12GroupRootParams{}; + + // Skip groups with no layout supplied. + if (g >= layoutCount || layouts == nullptr || layouts[g] == nullptr) + continue; + + const D3D12GroupRootParams& src = layouts[g]->d3dGroupParams(); + D3D12GroupRootParams& out = groupOut[g]; + + // Mirror counts + base global slots from the layout. Indices get + // assigned below based on insertion order in the root sig. + out.cbvCount = src.cbvCount; + out.srvCount = src.srvCount; + out.uavCount = src.uavCount; + out.samplerCount = src.samplerCount; + out.cbvBaseGlobalSlot = src.cbvBaseGlobalSlot; + out.srvBaseGlobalSlot = src.srvBaseGlobalSlot; + out.uavBaseGlobalSlot = src.uavBaseGlobalSlot; + out.samplerBaseGlobalSlot = src.samplerBaseGlobalSlot; + + // Merged CBV / SRV / UAV table for this group. + if (src.cbvCount || src.srvCount || src.uavCount) + { + out.cbvSrvUavRootParamIdx = static_cast(paramCount); + + uint32_t firstRange = rangeCount; + uint32_t numRanges = 0; + if (src.cbvCount) + { + D3D12_DESCRIPTOR_RANGE& r = ranges[rangeCount++]; + r.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + r.NumDescriptors = src.cbvCount; + r.BaseShaderRegister = src.cbvBaseGlobalSlot; + r.RegisterSpace = 0; + r.OffsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + ++numRanges; + } + if (src.srvCount) + { + D3D12_DESCRIPTOR_RANGE& r = ranges[rangeCount++]; + r.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + r.NumDescriptors = src.srvCount; + r.BaseShaderRegister = src.srvBaseGlobalSlot; + r.RegisterSpace = 0; + r.OffsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + ++numRanges; + } + if (src.uavCount) + { + D3D12_DESCRIPTOR_RANGE& r = ranges[rangeCount++]; + r.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + r.NumDescriptors = src.uavCount; + r.BaseShaderRegister = src.uavBaseGlobalSlot; + r.RegisterSpace = 0; + r.OffsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + ++numRanges; + } + + D3D12_ROOT_PARAMETER& p = rootParams[paramCount++]; + p.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + p.DescriptorTable.NumDescriptorRanges = numRanges; + p.DescriptorTable.pDescriptorRanges = &ranges[firstRange]; + p.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + + // Sampler table for this group (separate heap type). + if (src.samplerCount) + { + out.samplerRootParamIdx = static_cast(paramCount); + + D3D12_DESCRIPTOR_RANGE& r = ranges[rangeCount++]; + r.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + r.NumDescriptors = src.samplerCount; + r.BaseShaderRegister = src.samplerBaseGlobalSlot; + r.RegisterSpace = 0; + r.OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER& p = rootParams[paramCount++]; + p.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + p.DescriptorTable.NumDescriptorRanges = 1; + p.DescriptorTable.pDescriptorRanges = &r; + p.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + } + } + + // ── Step 3: serialize + create ── + D3D12_ROOT_SIGNATURE_DESC rsDesc = {}; + rsDesc.NumParameters = paramCount; + rsDesc.pParameters = paramCount > 0 ? rootParams : nullptr; + rsDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + Microsoft::WRL::ComPtr sigBlob, errBlob; + HRESULT hr = D3D12SerializeRootSignature(&rsDesc, + D3D_ROOT_SIGNATURE_VERSION_1, + sigBlob.GetAddressOf(), + errBlob.GetAddressOf()); + if (FAILED(hr)) + { + if (outHr) + *outHr = hr; + if (outErrMsg) + *outErrMsg = + errBlob ? static_cast(errBlob->GetBufferPointer()) + : "D3D12SerializeRootSignature failed"; + return nullptr; + } + + Microsoft::WRL::ComPtr rootSig; + hr = device->CreateRootSignature(0, + sigBlob->GetBufferPointer(), + sigBlob->GetBufferSize(), + IID_PPV_ARGS(rootSig.GetAddressOf())); + if (FAILED(hr)) + { + if (outHr) + *outHr = hr; + if (outErrMsg) + *outErrMsg = "CreateRootSignature failed"; + return nullptr; + } + return rootSig; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d11_d3d12.cpp new file mode 100644 index 000000000..eb8b2b81b --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d11_d3d12.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 Pipeline implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" + +namespace rive::ore +{ + +void Pipeline::onRefCntReachedZero() const +{ + // m_d3dOreContext is only set on D3D12-backed pipelines (see + // d3d12MakePipeline). D3D11-backed pipelines keep the immediate-delete + // path unchanged. + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +void BindGroupLayout::onRefCntReachedZero() const +{ + // m_context is set for D3D12 layouts (deferred destroy); D3D11 layouts + // have m_context == nullptr and use the immediate-delete path. + ContextD3D12* ctx = static_cast(m_context); + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d12.cpp new file mode 100644 index 000000000..d4c977e84 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_pipeline_d3d12.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +void Pipeline::onRefCntReachedZero() const +{ + // Capture the context before `delete this` invalidates `m_d3dOreContext`. + // In owned-CL mode d3dDeferDestroy runs the closure immediately, matching + // prior behavior. In external-CL mode it queues the closure until the + // next beginFrame() drains it, so the ComPtr release (and the underlying + // D3D12 resource destroy) can't happen while the host's command list + // still references the pipeline state object. + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +void BindGroupLayout::onRefCntReachedZero() const +{ + // Layout has no GPU handle on D3D12 (root sig owns the descriptor + // table shape; it's per-pipeline). Just delete. + ContextD3D12* ctx = static_cast(m_context); + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d11_d3d12.cpp new file mode 100644 index 000000000..5bab6087a --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d11_d3d12.cpp @@ -0,0 +1,697 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 RenderPass implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. +// Provides all RenderPass method definitions with runtime dispatch: +// passes initialized via the D3D11 context path (m_d3d11Context != nullptr) +// use D3D11; passes initialized via the D3D12 context path +// (m_d3dCmdList != nullptr) use D3D12. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +// Pull in D3D12 static helpers (none currently, but keeps the pattern). +#include "ore_render_pass_d3d12.cpp" + +// Pull in D3D11 static helpers (oreTopologyToD3D, oreIndexFormatToDXGI). +#include "../d3d11/ore_render_pass_d3d11.cpp" + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_d3d11.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/rive_types.hpp" +#include "ore_d3d12_bind_group_apply.hpp" + +namespace rive::ore +{ + +// ============================================================================ +// RenderPass — lifecycle +// ============================================================================ + +RenderPass::~RenderPass() +{ + if (!m_finished && (m_d3d11Context != nullptr || m_d3dCmdList != nullptr)) + finish(); +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + // D3D11 members + m_currentPipeline(std::move(other.m_currentPipeline)), + m_d3d11Context(other.m_d3d11Context), + m_d3d11Topology(other.m_d3d11Topology), + m_d3d11IndexFormat(other.m_d3d11IndexFormat), + m_d3d11IndexOffset(other.m_d3d11IndexOffset), + m_d3d11StencilRef(other.m_d3d11StencilRef), + m_d3d11ResolveCount(other.m_d3d11ResolveCount), + // D3D12 members + m_d3dCmdList(other.m_d3dCmdList), + m_d3dDevice(other.m_d3dDevice), + m_d3dContext(other.m_d3dContext), + m_d3dCurrentPipeline(std::move(other.m_d3dCurrentPipeline)), + m_d3dIndexFormat(other.m_d3dIndexFormat), + m_d3dIndexOffset(other.m_d3dIndexOffset), + m_d3dStencilRef(other.m_d3dStencilRef), + m_d3dColorCount(other.m_d3dColorCount), + m_d3dDepthResource(other.m_d3dDepthResource), + m_d3dDepthFinalState(other.m_d3dDepthFinalState) +{ + moveCrossBackendFieldsFrom(other); + // D3D11 arrays + m_d3d11BlendFactor[0] = other.m_d3d11BlendFactor[0]; + m_d3d11BlendFactor[1] = other.m_d3d11BlendFactor[1]; + m_d3d11BlendFactor[2] = other.m_d3d11BlendFactor[2]; + m_d3d11BlendFactor[3] = other.m_d3d11BlendFactor[3]; + for (uint32_t i = 0; i < m_d3d11ResolveCount; ++i) + m_d3d11Resolves[i] = other.m_d3d11Resolves[i]; + // D3D12 arrays + for (int i = 0; i < 8; ++i) + { + m_d3dPendingUBOs[i] = other.m_d3dPendingUBOs[i]; + m_d3dPendingSrvHandles[i] = other.m_d3dPendingSrvHandles[i]; + m_d3dPendingSamplerHandles[i] = other.m_d3dPendingSamplerHandles[i]; + } + for (int i = 0; i < 4; ++i) + { + m_d3dBlendFactor[i] = other.m_d3dBlendFactor[i]; + m_d3dColorResources[i] = other.m_d3dColorResources[i]; + m_d3dColorTextures[i] = other.m_d3dColorTextures[i]; + m_d3dColorFinalStates[i] = other.m_d3dColorFinalStates[i]; + m_d3dResolves[i] = other.m_d3dResolves[i]; + } + m_d3dDepthTexture = other.m_d3dDepthTexture; + m_d3dResolveCount = other.m_d3dResolveCount; + + other.m_d3d11Context = nullptr; + other.m_d3dCmdList = nullptr; + other.m_d3dDevice = nullptr; + other.m_d3dContext = nullptr; + other.m_d3dDepthResource = nullptr; + other.m_d3dDepthTexture = nullptr; + other.m_d3dColorCount = 0; + other.m_d3dResolveCount = 0; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && + (m_d3d11Context != nullptr || m_d3dCmdList != nullptr)) + finish(); + + moveCrossBackendFieldsFrom(other); + // D3D11 + m_d3d11Context = other.m_d3d11Context; + m_currentPipeline = std::move(other.m_currentPipeline); + m_d3d11Topology = other.m_d3d11Topology; + m_d3d11IndexFormat = other.m_d3d11IndexFormat; + m_d3d11IndexOffset = other.m_d3d11IndexOffset; + m_d3d11StencilRef = other.m_d3d11StencilRef; + m_d3d11BlendFactor[0] = other.m_d3d11BlendFactor[0]; + m_d3d11BlendFactor[1] = other.m_d3d11BlendFactor[1]; + m_d3d11BlendFactor[2] = other.m_d3d11BlendFactor[2]; + m_d3d11BlendFactor[3] = other.m_d3d11BlendFactor[3]; + m_d3d11ResolveCount = other.m_d3d11ResolveCount; + for (uint32_t i = 0; i < m_d3d11ResolveCount; ++i) + m_d3d11Resolves[i] = other.m_d3d11Resolves[i]; + // D3D12 + m_d3dCmdList = other.m_d3dCmdList; + m_d3dDevice = other.m_d3dDevice; + m_d3dContext = other.m_d3dContext; + m_d3dCurrentPipeline = std::move(other.m_d3dCurrentPipeline); + m_d3dIndexFormat = other.m_d3dIndexFormat; + m_d3dIndexOffset = other.m_d3dIndexOffset; + m_d3dStencilRef = other.m_d3dStencilRef; + m_d3dColorCount = other.m_d3dColorCount; + m_d3dDepthResource = other.m_d3dDepthResource; + m_d3dDepthFinalState = other.m_d3dDepthFinalState; + for (int i = 0; i < 8; ++i) + { + m_d3dPendingUBOs[i] = other.m_d3dPendingUBOs[i]; + m_d3dPendingSrvHandles[i] = other.m_d3dPendingSrvHandles[i]; + m_d3dPendingSamplerHandles[i] = other.m_d3dPendingSamplerHandles[i]; + } + for (int i = 0; i < 4; ++i) + { + m_d3dBlendFactor[i] = other.m_d3dBlendFactor[i]; + m_d3dColorResources[i] = other.m_d3dColorResources[i]; + m_d3dColorTextures[i] = other.m_d3dColorTextures[i]; + m_d3dColorFinalStates[i] = other.m_d3dColorFinalStates[i]; + m_d3dResolves[i] = other.m_d3dResolves[i]; + } + m_d3dDepthTexture = other.m_d3dDepthTexture; + m_d3dResolveCount = other.m_d3dResolveCount; + + other.m_d3d11Context = nullptr; + other.m_d3dCmdList = nullptr; + other.m_d3dDevice = nullptr; + other.m_d3dContext = nullptr; + other.m_d3dDepthResource = nullptr; + other.m_d3dDepthTexture = nullptr; + other.m_d3dColorCount = 0; + other.m_d3dResolveCount = 0; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_d3d11Context != nullptr || m_d3dCmdList != nullptr); +} + +// ============================================================================ +// setPipeline +// ============================================================================ + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + if (m_d3d11Context) + { + m_currentPipeline = ref_rcp(pipeline); + const auto& desc = pipeline->desc(); + + m_d3d11Context->VSSetShader(pipeline->m_d3dVS, nullptr, 0); + m_d3d11Context->PSSetShader(pipeline->m_d3dPS, nullptr, 0); + m_d3d11Context->IASetInputLayout(pipeline->m_d3dInputLayout.Get()); + + m_d3d11Topology = oreTopologyToD3D(desc.topology); + m_d3d11Context->IASetPrimitiveTopology(m_d3d11Topology); + + m_d3d11Context->RSSetState(pipeline->m_d3dRasterizer.Get()); + m_d3d11Context->OMSetDepthStencilState( + pipeline->m_d3dDepthStencil.Get(), + m_d3d11StencilRef); + m_d3d11Context->OMSetBlendState(pipeline->m_d3dBlend.Get(), + m_d3d11BlendFactor, + 0xFFFFFFFF); + return; + } + + // D3D12 path. + m_d3dCurrentPipeline = ref_rcp(pipeline); + m_d3dCmdList->SetPipelineState(pipeline->m_d3dPSO.Get()); + m_d3dCmdList->IASetPrimitiveTopology(pipeline->m_d3dTopology); + // Each pipeline owns its own root sig (RFC v5 §3.2.2); rebind on + // change. See ore_render_pass_d3d12.cpp for the matching block — + // both files must stay in sync on this logic. + ID3D12RootSignature* rootSig = pipeline->m_d3dRootSigOwned.Get(); + if (rootSig != m_d3dCurrentRootSig) + { + m_d3dCmdList->SetGraphicsRootSignature(rootSig); + m_d3dCurrentRootSig = rootSig; + } + m_d3dCmdList->OMSetStencilRef(m_d3dStencilRef); + m_d3dCmdList->OMSetBlendFactor(m_d3dBlendFactor); +} + +// ============================================================================ +// setVertexBuffer +// ============================================================================ + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + if (m_d3d11Context) + { + UINT stride = (m_currentPipeline && + slot < m_currentPipeline->desc().vertexBufferCount) + ? m_currentPipeline->desc().vertexBuffers[slot].stride + : 0; + ID3D11Buffer* buf = buffer->m_d3d11Buffer.Get(); + UINT off = offset; + m_d3d11Context->IASetVertexBuffers(slot, 1, &buf, &stride, &off); + return; + } + + // D3D12 path. + assert(buffer->m_d3dBuffer != nullptr); + UINT stride = (m_d3dCurrentPipeline && + slot < m_d3dCurrentPipeline->desc().vertexBufferCount) + ? m_d3dCurrentPipeline->m_d3dVertexStrides[slot] + : 0; + D3D12_VERTEX_BUFFER_VIEW vbv = {}; + vbv.BufferLocation = buffer->m_d3dBuffer->GetGPUVirtualAddress() + offset; + vbv.SizeInBytes = buffer->m_size - offset; + vbv.StrideInBytes = stride; + m_d3dCmdList->IASetVertexBuffers(slot, 1, &vbv); +} + +// ============================================================================ +// setIndexBuffer +// ============================================================================ + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + if (m_d3d11Context) + { + m_d3d11IndexFormat = oreIndexFormatToDXGI(format); + m_d3d11IndexOffset = offset; + m_d3d11Context->IASetIndexBuffer(buffer->m_d3d11Buffer.Get(), + m_d3d11IndexFormat, + offset); + return; + } + + // D3D12 path. + assert(buffer->m_d3dBuffer != nullptr); + m_d3dIndexFormat = (format == IndexFormat::uint32) ? DXGI_FORMAT_R32_UINT + : DXGI_FORMAT_R16_UINT; + m_d3dIndexOffset = offset; + D3D12_INDEX_BUFFER_VIEW ibv = {}; + ibv.BufferLocation = buffer->m_d3dBuffer->GetGPUVirtualAddress() + offset; + ibv.SizeInBytes = buffer->m_size - offset; + ibv.Format = m_d3dIndexFormat; + m_d3dCmdList->IASetIndexBuffer(&ibv); +} + +// ============================================================================ +// setBindGroup +// ============================================================================ + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + assert(bg != nullptr); + m_boundGroups[groupIndex] = ref_rcp(bg); + + if (m_d3d11Context) + { + // m_d3d11UBOs is sorted by WGSL `@binding` ascending at + // makeBindGroup time, so `dynamicOffsets[i]` here pairs with + // the i-th dynamic UBO in BindGroupLayout-entry order. + uint32_t dynIdx = 0; + ID3D11DeviceContext1* ctx1 = + m_context + ? static_cast(m_context)->m_d3d11Context1.Get() + : nullptr; + for (const auto& ubo : bg->m_d3d11UBOs) + { + ID3D11Buffer* buf = ubo.buffer; + uint32_t offsetBytes = ubo.offset; + if (ubo.hasDynamicOffset && dynIdx < dynamicOffsetCount) + { + offsetBytes += dynamicOffsets[dynIdx]; + ++dynIdx; + } + // D3D11.1 spec: `NumConstants` must be a multiple of 16 + // (256 bytes), minimum 16. NVIDIA enforces strictly — + // passing 1 silently drops the offset and re-reads from + // buffer start. See sibling fix in + // `ore_render_pass_d3d11.cpp`. + const bool useOffsetPath = + (offsetBytes != 0 && ctx1 != nullptr && ubo.size != 0); + const UINT firstConstant = useOffsetPath ? (offsetBytes / 16) : 0; + const UINT numConstantsRaw = (ubo.size + 15) / 16; + const UINT numConstants = + useOffsetPath + ? (numConstantsRaw < 16 ? 16u + : ((numConstantsRaw + 15u) & ~15u)) + : 0; + // Per-stage emit: VS / PS register namespaces are independent + // on D3D11. Skip the stage whose slot is `kAbsent` so we don't + // clobber another resource's register. + if (ubo.vsSlot != BindingMap::kAbsent) + { + if (useOffsetPath) + ctx1->VSSetConstantBuffers1(ubo.vsSlot, + 1, + &buf, + &firstConstant, + &numConstants); + else + m_d3d11Context->VSSetConstantBuffers(ubo.vsSlot, 1, &buf); + } + if (ubo.psSlot != BindingMap::kAbsent) + { + if (useOffsetPath) + ctx1->PSSetConstantBuffers1(ubo.psSlot, + 1, + &buf, + &firstConstant, + &numConstants); + else + m_d3d11Context->PSSetConstantBuffers(ubo.psSlot, 1, &buf); + } + } + for (const auto& tex : bg->m_d3d11Textures) + { + if (tex.vsSlot != BindingMap::kAbsent) + m_d3d11Context->VSSetShaderResources(tex.vsSlot, 1, &tex.srv); + if (tex.psSlot != BindingMap::kAbsent) + m_d3d11Context->PSSetShaderResources(tex.psSlot, 1, &tex.srv); + } + for (const auto& samp : bg->m_d3d11Samplers) + { + if (samp.vsSlot != BindingMap::kAbsent) + m_d3d11Context->VSSetSamplers(samp.vsSlot, 1, &samp.sampler); + if (samp.psSlot != BindingMap::kAbsent) + m_d3d11Context->PSSetSamplers(samp.psSlot, 1, &samp.sampler); + } + return; + } + + // D3D12 path. Shared body lives in ore_d3d12_bind_group_apply.hpp so + // the D3D12-only file (ore_render_pass_d3d12.cpp) and this combined + // file call the same implementation. + d3d12ApplyBindGroup(groupIndex, bg, dynamicOffsets, dynamicOffsetCount); +} + +// ============================================================================ +// setViewport / setScissorRect +// ============================================================================ + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ + validate(); + if (m_d3d11Context) + { + D3D11_VIEWPORT vp{}; + vp.TopLeftX = x; + vp.TopLeftY = y; + vp.Width = width; + vp.Height = height; + vp.MinDepth = minDepth; + vp.MaxDepth = maxDepth; + m_d3d11Context->RSSetViewports(1, &vp); + D3D11_RECT scissor{}; + scissor.left = static_cast(x); + scissor.top = static_cast(y); + scissor.right = static_cast(x + width); + scissor.bottom = static_cast(y + height); + m_d3d11Context->RSSetScissorRects(1, &scissor); + return; + } + + // D3D12 path. + D3D12_VIEWPORT vp = {x, y, width, height, minDepth, maxDepth}; + m_d3dCmdList->RSSetViewports(1, &vp); + D3D12_RECT scissor = {(LONG)x, + (LONG)y, + (LONG)(x + width), + (LONG)(y + height)}; + m_d3dCmdList->RSSetScissorRects(1, &scissor); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + if (m_d3d11Context) + { + D3D11_RECT rect{}; + rect.left = static_cast(x); + rect.top = static_cast(y); + rect.right = static_cast(x + width); + rect.bottom = static_cast(y + height); + m_d3d11Context->RSSetScissorRects(1, &rect); + return; + } + + // D3D12 path. + D3D12_RECT rect = {(LONG)x, (LONG)y, (LONG)(x + width), (LONG)(y + height)}; + m_d3dCmdList->RSSetScissorRects(1, &rect); +} + +// ============================================================================ +// setStencilReference / setBlendColor +// ============================================================================ + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + if (m_d3d11Context) + { + m_d3d11StencilRef = ref; + if (m_currentPipeline) + { + m_d3d11Context->OMSetDepthStencilState( + m_currentPipeline->m_d3dDepthStencil.Get(), + ref); + } + return; + } + + // D3D12 path. + m_d3dStencilRef = ref; + m_d3dCmdList->OMSetStencilRef(ref); +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + if (m_d3d11Context) + { + m_d3d11BlendFactor[0] = r; + m_d3d11BlendFactor[1] = g; + m_d3d11BlendFactor[2] = b; + m_d3d11BlendFactor[3] = a; + if (m_currentPipeline) + { + m_d3d11Context->OMSetBlendState(m_currentPipeline->m_d3dBlend.Get(), + m_d3d11BlendFactor, + 0xFFFFFFFF); + } + return; + } + + // D3D12 path. + m_d3dBlendFactor[0] = r; + m_d3dBlendFactor[1] = g; + m_d3dBlendFactor[2] = b; + m_d3dBlendFactor[3] = a; + m_d3dCmdList->OMSetBlendFactor(m_d3dBlendFactor); +} + +// ============================================================================ +// draw / drawIndexed +// ============================================================================ + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + if (m_d3d11Context) + { + if (instanceCount > 1 || firstInstance != 0) + { + m_d3d11Context->DrawInstanced(vertexCount, + instanceCount, + firstVertex, + firstInstance); + } + else + { + m_d3d11Context->Draw(vertexCount, firstVertex); + } + return; + } + + // D3D12 path. + m_d3dCmdList->DrawInstanced(vertexCount, + instanceCount, + firstVertex, + firstInstance); +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + if (m_d3d11Context) + { + if (instanceCount > 1 || firstInstance != 0 || baseVertex != 0) + { + m_d3d11Context->DrawIndexedInstanced(indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); + } + else + { + m_d3d11Context->DrawIndexed(indexCount, firstIndex, 0); + } + return; + } + + // D3D12 path. + m_d3dCmdList->DrawIndexedInstanced(indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); +} + +// ============================================================================ +// finish +// ============================================================================ + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + + if (m_d3d11Context != nullptr) + { + // Unbind render targets so attached textures can be used as SRVs. + m_d3d11Context->OMSetRenderTargets(0, nullptr, nullptr); + + // Resolve MSAA render targets to their 1x resolve targets. + for (uint32_t i = 0; i < m_d3d11ResolveCount; ++i) + { + const auto& r = m_d3d11Resolves[i]; + m_d3d11Context->ResolveSubresource(r.resolve, + r.resolveSubresource, + r.msaa, + r.msaaSubresource, + r.format); + } + + m_d3d11Context = nullptr; + return; + } + + if (m_d3dCmdList == nullptr) + return; + + // MSAA resolve (D3D12 path). Mirrors ore_render_pass_d3d12.cpp. + if (m_d3dResolveCount > 0) + { + D3D12_RESOURCE_BARRIER pre[8] = {}; + uint32_t preCount = 0; + for (uint32_t i = 0; i < m_d3dResolveCount; ++i) + { + const auto& r = m_d3dResolves[i]; + pre[preCount].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + pre[preCount].Transition.pResource = r.msaa; + pre[preCount].Transition.StateBefore = + D3D12_RESOURCE_STATE_RENDER_TARGET; + pre[preCount].Transition.StateAfter = + D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + pre[preCount].Transition.Subresource = r.msaaSubresource; + ++preCount; + + pre[preCount].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + pre[preCount].Transition.pResource = r.resolve; + pre[preCount].Transition.StateBefore = r.resolvePriorState; + pre[preCount].Transition.StateAfter = + D3D12_RESOURCE_STATE_RESOLVE_DEST; + pre[preCount].Transition.Subresource = r.resolveSubresource; + ++preCount; + } + m_d3dCmdList->ResourceBarrier(preCount, pre); + + for (uint32_t i = 0; i < m_d3dResolveCount; ++i) + { + const auto& r = m_d3dResolves[i]; + m_d3dCmdList->ResolveSubresource(r.resolve, + r.resolveSubresource, + r.msaa, + r.msaaSubresource, + r.format); + } + + D3D12_RESOURCE_BARRIER post[4] = {}; + uint32_t postCount = 0; + for (uint32_t i = 0; i < m_d3dResolveCount; ++i) + { + const auto& r = m_d3dResolves[i]; + post[postCount].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + post[postCount].Transition.pResource = r.resolve; + post[postCount].Transition.StateBefore = + D3D12_RESOURCE_STATE_RESOLVE_DEST; + post[postCount].Transition.StateAfter = r.resolveFinalState; + post[postCount].Transition.Subresource = r.resolveSubresource; + ++postCount; + // Keep the resolve target's tracked state in sync. + if (r.resolveTex != nullptr) + r.resolveTex->m_d3dCurrentState = r.resolveFinalState; + } + if (postCount > 0) + m_d3dCmdList->ResourceBarrier(postCount, post); + } + + // Transition colour attachments back to their post-pass state. MSAA + // srcs that were resolved are now in RESOLVE_SOURCE; others RENDER_TARGET. + for (uint32_t i = 0; i < m_d3dColorCount; ++i) + { + if (!m_d3dColorResources[i]) + continue; + + D3D12_RESOURCE_STATES stateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + for (uint32_t r = 0; r < m_d3dResolveCount; ++r) + { + if (m_d3dResolves[r].msaa == m_d3dColorResources[i]) + { + stateBefore = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + break; + } + } + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dColorResources[i]; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = m_d3dColorFinalStates[i]; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + + if (m_d3dColorTextures[i] != nullptr) + m_d3dColorTextures[i]->m_d3dCurrentState = m_d3dColorFinalStates[i]; + } + + // Transition depth/stencil if present. + if (m_d3dDepthResource) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dDepthResource; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE; + barrier.Transition.StateAfter = m_d3dDepthFinalState; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + + if (m_d3dDepthTexture != nullptr) + m_d3dDepthTexture->m_d3dCurrentState = m_d3dDepthFinalState; + } + + m_d3dCmdList = nullptr; + m_d3dDevice = nullptr; + m_d3dContext = nullptr; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d12.cpp new file mode 100644 index 000000000..d3422c709 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_render_pass_d3d12.cpp @@ -0,0 +1,509 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/rive_types.hpp" +#include "ore_d3d12_bind_group_apply.hpp" + +#include +#include +#include + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +// ============================================================================ +// RenderPass — lifecycle +// ============================================================================ + +RenderPass::~RenderPass() +{ + if (!m_finished && m_d3dCmdList != nullptr) + finish(); +} + +RenderPass::RenderPass(RenderPass&& other) noexcept +#if defined(ORE_BACKEND_D3D12) + : + m_d3dCmdList(other.m_d3dCmdList), + m_d3dDevice(other.m_d3dDevice), + m_d3dContext(other.m_d3dContext), + m_d3dCurrentPipeline(std::move(other.m_d3dCurrentPipeline)), + m_d3dIndexFormat(other.m_d3dIndexFormat), + m_d3dIndexOffset(other.m_d3dIndexOffset), + m_d3dStencilRef(other.m_d3dStencilRef), + m_d3dColorCount(other.m_d3dColorCount), + m_d3dDepthResource(other.m_d3dDepthResource), + m_d3dDepthFinalState(other.m_d3dDepthFinalState) +#endif +{ + moveCrossBackendFieldsFrom(other); +#if defined(ORE_BACKEND_D3D12) + for (int i = 0; i < 8; ++i) + { + m_d3dPendingUBOs[i] = other.m_d3dPendingUBOs[i]; + m_d3dPendingSrvHandles[i] = other.m_d3dPendingSrvHandles[i]; + m_d3dPendingSamplerHandles[i] = other.m_d3dPendingSamplerHandles[i]; + } + for (int i = 0; i < 4; ++i) + { + m_d3dBlendFactor[i] = other.m_d3dBlendFactor[i]; + m_d3dColorResources[i] = other.m_d3dColorResources[i]; + m_d3dColorTextures[i] = other.m_d3dColorTextures[i]; + m_d3dColorFinalStates[i] = other.m_d3dColorFinalStates[i]; + m_d3dResolves[i] = other.m_d3dResolves[i]; + } + m_d3dDepthTexture = other.m_d3dDepthTexture; + m_d3dResolveCount = other.m_d3dResolveCount; + other.m_d3dCmdList = nullptr; + other.m_d3dDevice = nullptr; + other.m_d3dContext = nullptr; + other.m_d3dDepthResource = nullptr; + other.m_d3dDepthTexture = nullptr; + other.m_d3dColorCount = 0; + other.m_d3dResolveCount = 0; +#endif +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && m_d3dCmdList != nullptr) + finish(); + moveCrossBackendFieldsFrom(other); +#if defined(ORE_BACKEND_D3D12) + m_d3dCmdList = other.m_d3dCmdList; + m_d3dDevice = other.m_d3dDevice; + m_d3dContext = other.m_d3dContext; + m_d3dCurrentPipeline = std::move(other.m_d3dCurrentPipeline); + m_d3dIndexFormat = other.m_d3dIndexFormat; + m_d3dIndexOffset = other.m_d3dIndexOffset; + m_d3dStencilRef = other.m_d3dStencilRef; + m_d3dColorCount = other.m_d3dColorCount; + m_d3dDepthResource = other.m_d3dDepthResource; + m_d3dDepthFinalState = other.m_d3dDepthFinalState; + for (int i = 0; i < 8; ++i) + { + m_d3dPendingUBOs[i] = other.m_d3dPendingUBOs[i]; + m_d3dPendingSrvHandles[i] = other.m_d3dPendingSrvHandles[i]; + m_d3dPendingSamplerHandles[i] = other.m_d3dPendingSamplerHandles[i]; + } + for (int i = 0; i < 4; ++i) + { + m_d3dBlendFactor[i] = other.m_d3dBlendFactor[i]; + m_d3dColorResources[i] = other.m_d3dColorResources[i]; + m_d3dColorTextures[i] = other.m_d3dColorTextures[i]; + m_d3dColorFinalStates[i] = other.m_d3dColorFinalStates[i]; + m_d3dResolves[i] = other.m_d3dResolves[i]; + } + m_d3dDepthTexture = other.m_d3dDepthTexture; + m_d3dResolveCount = other.m_d3dResolveCount; + other.m_d3dCmdList = nullptr; + other.m_d3dDevice = nullptr; + other.m_d3dContext = nullptr; + other.m_d3dDepthResource = nullptr; + other.m_d3dDepthTexture = nullptr; + other.m_d3dColorCount = 0; + other.m_d3dResolveCount = 0; +#endif + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); +#if defined(ORE_BACKEND_D3D12) + assert(m_d3dCmdList != nullptr); +#endif +} + +// ============================================================================ +// setPipeline +// ============================================================================ + +void RenderPass::setPipeline(Pipeline* pipeline) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + if (!checkPipelineCompat(pipeline)) + return; + m_d3dCurrentPipeline = ref_rcp(pipeline); + + m_d3dCmdList->SetPipelineState(pipeline->m_d3dPSO.Get()); + m_d3dCmdList->IASetPrimitiveTopology(pipeline->m_d3dTopology); + // Each pipeline owns its own root sig (RFC v5 §3.2.2). Rebind on + // change; D3D12 resets all root-parameter state when the sig + // changes, so callers must rebind bind groups after any pipeline + // switch that flips sig. + ID3D12RootSignature* rootSig = pipeline->m_d3dRootSigOwned.Get(); + if (rootSig != m_d3dCurrentRootSig) + { + m_d3dCmdList->SetGraphicsRootSignature(rootSig); + m_d3dCurrentRootSig = rootSig; + } + // Stencil / blend colour — re-apply with new pipeline state. + m_d3dCmdList->OMSetStencilRef(m_d3dStencilRef); + m_d3dCmdList->OMSetBlendFactor(m_d3dBlendFactor); +#else + (void)pipeline; +#endif +} + +// ============================================================================ +// setVertexBuffer +// ============================================================================ + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + assert(buffer->m_d3dBuffer != nullptr); + + UINT stride = (m_d3dCurrentPipeline && + slot < m_d3dCurrentPipeline->desc().vertexBufferCount) + ? m_d3dCurrentPipeline->m_d3dVertexStrides[slot] + : 0; + + D3D12_VERTEX_BUFFER_VIEW vbv = {}; + vbv.BufferLocation = buffer->m_d3dBuffer->GetGPUVirtualAddress() + offset; + vbv.SizeInBytes = buffer->m_size - offset; + vbv.StrideInBytes = stride; + m_d3dCmdList->IASetVertexBuffers(slot, 1, &vbv); +#else + (void)slot; + (void)buffer; + (void)offset; +#endif +} + +// ============================================================================ +// setIndexBuffer +// ============================================================================ + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + assert(buffer->m_d3dBuffer != nullptr); + + m_d3dIndexFormat = (format == IndexFormat::uint32) ? DXGI_FORMAT_R32_UINT + : DXGI_FORMAT_R16_UINT; + m_d3dIndexOffset = offset; + + D3D12_INDEX_BUFFER_VIEW ibv = {}; + ibv.BufferLocation = buffer->m_d3dBuffer->GetGPUVirtualAddress() + offset; + ibv.SizeInBytes = buffer->m_size - offset; + ibv.Format = m_d3dIndexFormat; + m_d3dCmdList->IASetIndexBuffer(&ibv); +#else + (void)buffer; + (void)format; + (void)offset; +#endif +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + assert(bg != nullptr); + // Hold a strong reference so the BindGroup stays alive until finish(). + m_boundGroups[groupIndex] = ref_rcp(bg); + d3d12ApplyBindGroup(groupIndex, bg, dynamicOffsets, dynamicOffsetCount); +#else + (void)groupIndex; + (void)bg; + (void)dynamicOffsets; + (void)dynamicOffsetCount; +#endif +} + +// ============================================================================ +// setViewport / setScissorRect +// ============================================================================ + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + D3D12_VIEWPORT vp = {x, y, width, height, minDepth, maxDepth}; + m_d3dCmdList->RSSetViewports(1, &vp); + + // Reset scissor to full viewport. + D3D12_RECT scissor = {(LONG)x, + (LONG)y, + (LONG)(x + width), + (LONG)(y + height)}; + m_d3dCmdList->RSSetScissorRects(1, &scissor); +#else + (void)x; + (void)y; + (void)width; + (void)height; + (void)minDepth; + (void)maxDepth; +#endif +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + D3D12_RECT rect = {(LONG)x, (LONG)y, (LONG)(x + width), (LONG)(y + height)}; + m_d3dCmdList->RSSetScissorRects(1, &rect); +#else + (void)x; + (void)y; + (void)width; + (void)height; +#endif +} + +// ============================================================================ +// setStencilReference / setBlendColor +// ============================================================================ + +void RenderPass::setStencilReference(uint32_t ref) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + m_d3dStencilRef = ref; + m_d3dCmdList->OMSetStencilRef(ref); +#else + (void)ref; +#endif +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + m_d3dBlendFactor[0] = r; + m_d3dBlendFactor[1] = g; + m_d3dBlendFactor[2] = b; + m_d3dBlendFactor[3] = a; + m_d3dCmdList->OMSetBlendFactor(m_d3dBlendFactor); +#else + (void)r; + (void)g; + (void)b; + (void)a; +#endif +} + +// ============================================================================ +// draw / drawIndexed +// ============================================================================ + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + m_d3dCmdList->DrawInstanced(vertexCount, + instanceCount, + firstVertex, + firstInstance); +#else + (void)vertexCount; + (void)instanceCount; + (void)firstVertex; + (void)firstInstance; +#endif +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ +#if defined(ORE_BACKEND_D3D12) + validate(); + m_d3dCmdList->DrawIndexedInstanced(indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); +#else + (void)indexCount; + (void)instanceCount; + (void)firstIndex; + (void)baseVertex; + (void)firstInstance; +#endif +} + +// ============================================================================ +// finish +// ============================================================================ + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + +#if defined(ORE_BACKEND_D3D12) + if (m_d3dCmdList == nullptr) + return; + + // MSAA resolve, if any. Pattern per resolve pair: + // msaa: RENDER_TARGET → RESOLVE_SOURCE + // dst: prior-state → RESOLVE_DEST + // ResolveSubresource + // msaa: RESOLVE_SOURCE → final colour state (handled by loop below) + // dst: RESOLVE_DEST → dst's final state (handled here, since it + // isn't a colour attachment of this pass) + // A single barrier batch is issued for each phase so the driver can + // schedule efficiently. + if (m_d3dResolveCount > 0) + { + // Phase 1: transition MSAA srcs to RESOLVE_SOURCE and resolve dsts + // to RESOLVE_DEST. + D3D12_RESOURCE_BARRIER pre[8] = {}; + uint32_t preCount = 0; + for (uint32_t i = 0; i < m_d3dResolveCount; ++i) + { + const auto& r = m_d3dResolves[i]; + pre[preCount].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + pre[preCount].Transition.pResource = r.msaa; + pre[preCount].Transition.StateBefore = + D3D12_RESOURCE_STATE_RENDER_TARGET; + pre[preCount].Transition.StateAfter = + D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + pre[preCount].Transition.Subresource = r.msaaSubresource; + ++preCount; + + pre[preCount].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + pre[preCount].Transition.pResource = r.resolve; + pre[preCount].Transition.StateBefore = r.resolvePriorState; + pre[preCount].Transition.StateAfter = + D3D12_RESOURCE_STATE_RESOLVE_DEST; + pre[preCount].Transition.Subresource = r.resolveSubresource; + ++preCount; + } + m_d3dCmdList->ResourceBarrier(preCount, pre); + + // Phase 2: execute resolves. + for (uint32_t i = 0; i < m_d3dResolveCount; ++i) + { + const auto& r = m_d3dResolves[i]; + m_d3dCmdList->ResolveSubresource(r.resolve, + r.resolveSubresource, + r.msaa, + r.msaaSubresource, + r.format); + } + + // Phase 3: transition resolve dsts back. MSAA srcs still need a + // RESOLVE_SOURCE → final-state transition, which we fold into the + // colour-final-state loop below by adjusting StateBefore. + D3D12_RESOURCE_BARRIER post[4] = {}; + uint32_t postCount = 0; + for (uint32_t i = 0; i < m_d3dResolveCount; ++i) + { + const auto& r = m_d3dResolves[i]; + post[postCount].Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + post[postCount].Transition.pResource = r.resolve; + post[postCount].Transition.StateBefore = + D3D12_RESOURCE_STATE_RESOLVE_DEST; + post[postCount].Transition.StateAfter = r.resolveFinalState; + post[postCount].Transition.Subresource = r.resolveSubresource; + ++postCount; + // Keep the resolve target's tracked state in sync with the + // actual resource state so its next use (begin of a future pass, + // or an upload, etc.) sees the right StateBefore. + if (r.resolveTex != nullptr) + r.resolveTex->m_d3dCurrentState = r.resolveFinalState; + } + if (postCount > 0) + m_d3dCmdList->ResourceBarrier(postCount, post); + } + + // Transition colour attachments back to their post-pass state. + // MSAA srcs that were resolved are in RESOLVE_SOURCE; others are in + // RENDER_TARGET. Keep Texture::m_d3dCurrentState synced so the next + // use of the texture sees the right StateBefore. + for (uint32_t i = 0; i < m_d3dColorCount; ++i) + { + if (!m_d3dColorResources[i]) + continue; + + D3D12_RESOURCE_STATES stateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + for (uint32_t r = 0; r < m_d3dResolveCount; ++r) + { + if (m_d3dResolves[r].msaa == m_d3dColorResources[i]) + { + stateBefore = D3D12_RESOURCE_STATE_RESOLVE_SOURCE; + break; + } + } + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dColorResources[i]; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = m_d3dColorFinalStates[i]; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + + if (m_d3dColorTextures[i] != nullptr) + m_d3dColorTextures[i]->m_d3dCurrentState = m_d3dColorFinalStates[i]; + } + + // Transition depth/stencil if present. + if (m_d3dDepthResource) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dDepthResource; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE; + barrier.Transition.StateAfter = m_d3dDepthFinalState; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + m_d3dCmdList->ResourceBarrier(1, &barrier); + + if (m_d3dDepthTexture != nullptr) + m_d3dDepthTexture->m_d3dCurrentState = m_d3dDepthFinalState; + } + + m_d3dCmdList = nullptr; + m_d3dDevice = nullptr; + m_d3dContext = nullptr; +#endif +} + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d11_d3d12.cpp new file mode 100644 index 000000000..29bce964b --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d11_d3d12.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 Sampler implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" + +namespace rive::ore +{ + +void Sampler::onRefCntReachedZero() const +{ + // m_d3dOreContext is only set on D3D12-backed samplers (see + // d3d12MakeSampler). D3D11-backed samplers keep the immediate-delete + // path unchanged. + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d12.cpp new file mode 100644 index 000000000..662f3436b --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_sampler_d3d12.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +void Sampler::onRefCntReachedZero() const +{ + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d11_d3d12.cpp new file mode 100644 index 000000000..539dad862 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d11_d3d12.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 ShaderModule implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +void ShaderModule::onRefCntReachedZero() const { delete this; } + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d12.cpp new file mode 100644 index 000000000..74ddc8125 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_shader_module_d3d12.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +void ShaderModule::onRefCntReachedZero() const { delete this; } + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d11_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d11_d3d12.cpp new file mode 100644 index 000000000..04727c8cc --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d11_d3d12.cpp @@ -0,0 +1,218 @@ +/* + * Copyright 2025 Rive + */ + +// Combined D3D11 + D3D12 Texture implementation for Windows. +// Compiled when both ORE_BACKEND_D3D11 and ORE_BACKEND_D3D12 are active. + +#if defined(ORE_BACKEND_D3D11) && defined(ORE_BACKEND_D3D12) + +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include +#include +#include + +using Microsoft::WRL::ComPtr; + +namespace rive::ore +{ + +void Texture::upload(const TextureDataDesc& data) +{ + assert(data.data != nullptr); + + if (m_d3d11Texture) + { + // D3D11 path — UpdateSubresource. + assert(m_d3d11Context != nullptr); + + UINT subresource = + D3D11CalcSubresource(data.mipLevel, data.layer, m_numMipmaps); + + D3D11_BOX box{}; + box.left = data.x; + box.top = data.y; + box.front = data.z; + box.right = data.x + data.width; + box.bottom = data.y + data.height; + box.back = data.z + data.depth; + + m_d3d11Context->UpdateSubresource(m_d3d11Texture.Get(), + subresource, + &box, + data.data, + data.bytesPerRow, + data.bytesPerRow * data.rowsPerImage); + } + else + { + // D3D12 path — staging upload buffer + copy command. + assert(m_d3dTexture != nullptr); + assert(m_d3dDevice != nullptr); + assert(m_d3dOreContext != nullptr); + assert(!m_d3dIsExternal && + "Cannot upload into an external (canvas-wrapped) texture"); + + ContextD3D12* ctx = m_d3dOreContext; + + // Open the upload command list if not already recording. + if (!ctx->m_d3dUploadListOpen) + { + ctx->m_d3dUploadAllocator->Reset(); + ctx->m_d3dUploadCmdList->Reset(ctx->m_d3dUploadAllocator.Get(), + nullptr); + ctx->m_d3dUploadListOpen = true; + } + + // Compute the placed footprint for the requested subresource. + // D3D12 subresource index = `mipSlice + arraySlice * MipLevels` + // (see D3D12CalcSubresource). See sibling fix in + // ore_texture_d3d12.cpp. + D3D12_RESOURCE_DESC texDesc = m_d3dTexture->GetDesc(); + UINT subresource = + data.mipLevel + data.layer * static_cast(texDesc.MipLevels); + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = {}; + UINT numRows = 0; + UINT64 rowBytes = 0; + UINT64 totalBytes = 0; + m_d3dDevice->GetCopyableFootprints(&texDesc, + subresource, + 1, + /*baseOffset=*/0, + &footprint, + &numRows, + &rowBytes, + &totalBytes); + + // Allocate a staging (UPLOAD heap) buffer. + D3D12_HEAP_PROPERTIES uploadHeap = {}; + uploadHeap.Type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_RESOURCE_DESC bufDesc = {}; + bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + bufDesc.Width = totalBytes; + bufDesc.Height = 1; + bufDesc.DepthOrArraySize = 1; + bufDesc.MipLevels = 1; + bufDesc.Format = DXGI_FORMAT_UNKNOWN; + bufDesc.SampleDesc.Count = 1; + bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + bufDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + ComPtr staging; + [[maybe_unused]] HRESULT hr = m_d3dDevice->CreateCommittedResource( + &uploadHeap, + D3D12_HEAP_FLAG_NONE, + &bufDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(staging.GetAddressOf())); + assert(SUCCEEDED(hr) && + "Texture::upload: staging buffer creation failed"); + + // Map and copy row by row, respecting the D3D12 pitch alignment. + void* mapped = nullptr; + D3D12_RANGE readRange = {0, 0}; + staging->Map(0, &readRange, &mapped); + + const uint8_t* src = static_cast(data.data); + uint8_t* dst = static_cast(mapped); + UINT64 srcRow = data.bytesPerRow ? data.bytesPerRow : rowBytes; + UINT64 dstRow = footprint.Footprint.RowPitch; + + for (UINT row = 0; row < numRows; ++row) + memcpy(dst + row * dstRow, src + row * srcRow, (size_t)rowBytes); + + staging->Unmap(0, nullptr); + + // If the texture is not in COPY_DEST state, transition it. + if (m_d3dCurrentState != D3D12_RESOURCE_STATE_COPY_DEST) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dTexture.Get(); + barrier.Transition.StateBefore = m_d3dCurrentState; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + ctx->m_d3dUploadCmdList->ResourceBarrier(1, &barrier); + m_d3dCurrentState = D3D12_RESOURCE_STATE_COPY_DEST; + } + + // Record the copy. + D3D12_TEXTURE_COPY_LOCATION dst_loc = {}; + dst_loc.pResource = m_d3dTexture.Get(); + dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst_loc.SubresourceIndex = subresource; + + D3D12_TEXTURE_COPY_LOCATION src_loc = {}; + src_loc.pResource = staging.Get(); + src_loc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src_loc.PlacedFootprint = footprint; + + D3D12_BOX box = {}; + box.left = data.x; + box.top = data.y; + box.front = data.z; + box.right = data.x + data.width; + box.bottom = data.y + data.height; + box.back = data.z + data.depth; + + ctx->m_d3dUploadCmdList->CopyTextureRegion(&dst_loc, + data.x, + data.y, + data.z, + &src_loc, + &box); + + // Transition to PIXEL_SHADER_RESOURCE so it's ready to sample. + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dTexture.Get(); + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + ctx->m_d3dUploadCmdList->ResourceBarrier(1, &barrier); + m_d3dCurrentState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + } + + // Keep the staging buffer alive until the GPU is done. + ctx->m_d3dPendingUploads.push_back(std::move(staging)); + } +} + +void Texture::onRefCntReachedZero() const +{ + // m_d3dOreContext is only set on D3D12-backed textures (see + // d3d12MakeTexture / d3d12WrapCanvasTexture / d3d12WrapRiveTexture). + // D3D11-backed textures keep the immediate-delete path unchanged. + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +void TextureView::onRefCntReachedZero() const +{ + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_D3D11 && ORE_BACKEND_D3D12 diff --git a/thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d12.cpp b/thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d12.cpp new file mode 100644 index 000000000..7c31e0bed --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/d3d12/ore_texture_d3d12.cpp @@ -0,0 +1,192 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_context_d3d12.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include +#include + +using Microsoft::WRL::ComPtr; + +namespace rive::ore +{ + +// --- Public method definitions (D3D12-only builds) --- +// When both D3D11 and D3D12 are compiled, the combined +// ore_context_d3d11_d3d12.cpp file provides these methods with dispatch. +#if defined(ORE_BACKEND_D3D12) && !defined(ORE_BACKEND_D3D11) + +void Texture::upload(const TextureDataDesc& data) +{ +#if defined(ORE_BACKEND_D3D12) + assert(m_d3dTexture != nullptr); + assert(m_d3dDevice != nullptr); + assert(m_d3dOreContext != nullptr); + assert(!m_d3dIsExternal && + "Cannot upload into an external (canvas-wrapped) texture"); + assert(data.data != nullptr); + + ContextD3D12* ctx = m_d3dOreContext; + + // Open the upload command list if not already recording. + if (!ctx->m_d3dUploadListOpen) + { + ctx->m_d3dUploadAllocator->Reset(); + ctx->m_d3dUploadCmdList->Reset(ctx->m_d3dUploadAllocator.Get(), + nullptr); + ctx->m_d3dUploadListOpen = true; + } + + // Compute the placed footprint for the requested subresource. + // D3D12 subresource index formula: + // `mipSlice + arraySlice * MipLevels + planeSlice * MipLevels * + // ArraySize` + // (see D3D12CalcSubresource in d3dx12.h). Pre-fix this was + // `mipLevel * DepthOrArraySize + layer`, which is the *transposed* + // formula — works only when MipLevels=1 (every Ore GM today) and + // silently mis-targets the wrong subresource for any mipmapped + // array texture. + D3D12_RESOURCE_DESC texDesc = m_d3dTexture->GetDesc(); + UINT subresource = + data.mipLevel + data.layer * static_cast(texDesc.MipLevels); + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = {}; + UINT numRows = 0; + UINT64 rowBytes = 0; + UINT64 totalBytes = 0; + m_d3dDevice->GetCopyableFootprints(&texDesc, + subresource, + 1, + /*baseOffset=*/0, + &footprint, + &numRows, + &rowBytes, + &totalBytes); + + // Allocate a staging (UPLOAD heap) buffer. + D3D12_HEAP_PROPERTIES uploadHeap = {}; + uploadHeap.Type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_RESOURCE_DESC bufDesc = {}; + bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + bufDesc.Width = totalBytes; + bufDesc.Height = 1; + bufDesc.DepthOrArraySize = 1; + bufDesc.MipLevels = 1; + bufDesc.Format = DXGI_FORMAT_UNKNOWN; + bufDesc.SampleDesc.Count = 1; + bufDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + bufDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + ComPtr staging; + [[maybe_unused]] HRESULT hr = m_d3dDevice->CreateCommittedResource( + &uploadHeap, + D3D12_HEAP_FLAG_NONE, + &bufDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(staging.GetAddressOf())); + assert(SUCCEEDED(hr) && "Texture::upload: staging buffer creation failed"); + + // Map and copy row by row, respecting the D3D12 pitch alignment. + void* mapped = nullptr; + D3D12_RANGE readRange = {0, 0}; + staging->Map(0, &readRange, &mapped); + + const uint8_t* src = static_cast(data.data); + uint8_t* dst = static_cast(mapped); + UINT64 srcRow = data.bytesPerRow ? data.bytesPerRow : rowBytes; + UINT64 dstRow = footprint.Footprint.RowPitch; + + for (UINT row = 0; row < numRows; ++row) + memcpy(dst + row * dstRow, src + row * srcRow, (size_t)rowBytes); + + staging->Unmap(0, nullptr); + + // If the texture is not in COPY_DEST state, transition it. + if (m_d3dCurrentState != D3D12_RESOURCE_STATE_COPY_DEST) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dTexture.Get(); + barrier.Transition.StateBefore = m_d3dCurrentState; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + ctx->m_d3dUploadCmdList->ResourceBarrier(1, &barrier); + m_d3dCurrentState = D3D12_RESOURCE_STATE_COPY_DEST; + } + + // Record the copy. + D3D12_TEXTURE_COPY_LOCATION dst_loc = {}; + dst_loc.pResource = m_d3dTexture.Get(); + dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst_loc.SubresourceIndex = subresource; + + D3D12_TEXTURE_COPY_LOCATION src_loc = {}; + src_loc.pResource = staging.Get(); + src_loc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src_loc.PlacedFootprint = footprint; + + D3D12_BOX box = {}; + box.left = data.x; + box.top = data.y; + box.front = data.z; + box.right = data.x + data.width; + box.bottom = data.y + data.height; + box.back = data.z + data.depth; + + ctx->m_d3dUploadCmdList + ->CopyTextureRegion(&dst_loc, data.x, data.y, data.z, &src_loc, &box); + + // Transition to PIXEL_SHADER_RESOURCE so it's ready to sample without + // an explicit barrier in the render pass. + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = m_d3dTexture.Get(); + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + ctx->m_d3dUploadCmdList->ResourceBarrier(1, &barrier); + m_d3dCurrentState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + } + + // Keep the staging buffer alive until the GPU is done (freed in + // endFrame/FlushUploads). + ctx->m_d3dPendingUploads.push_back(std::move(staging)); +#else + (void)data; +#endif +} + +void Texture::onRefCntReachedZero() const +{ + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +void TextureView::onRefCntReachedZero() const +{ + ContextD3D12* ctx = m_d3dOreContext; + auto destroy = [p = const_cast(this)]() { delete p; }; + if (ctx != nullptr) + ctx->d3dDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // D3D12-only + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_bind_group_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_bind_group_gl.cpp new file mode 100644 index 000000000..3bfaef9e2 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_bind_group_gl.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_bind_group.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.cpp new file mode 100644 index 000000000..7ae793ac4 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/rive_types.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + assert(m_glBuffer != 0); + + if (m_usage == BufferUsage::index) + { + // WebGL forbids binding a buffer to GL_ELEMENT_ARRAY_BUFFER if it was + // ever bound to a different target, so index buffers must use their + // native target. GL_ELEMENT_ARRAY_BUFFER is VAO state, so we + // save/restore the current binding to avoid clobbering the host + // renderer's VAO. + GLint prevEBO; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevEBO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_glBuffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevEBO); + } + else + { + // Non-index buffers use GL_COPY_WRITE_BUFFER to avoid disturbing + // the host renderer's VAO element-buffer binding. + glBindBuffer(GL_COPY_WRITE_BUFFER, m_glBuffer); + glBufferSubData(GL_COPY_WRITE_BUFFER, offset, size, data); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + } +} + +void Buffer::onRefCntReachedZero() const +{ + if (m_glBuffer != 0) + { + GLuint buf = m_glBuffer; + glDeleteBuffers(1, &buf); + } + delete this; +} + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.mm new file mode 100644 index 000000000..65d25c48e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_buffer_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_buffer_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_context_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_context_gl.cpp new file mode 100644 index 000000000..c443d7dff --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_context_gl.cpp @@ -0,0 +1,1181 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/gl/render_target_gl.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_context_gl.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include +#include +#ifdef __EMSCRIPTEN__ +#include +#include +#endif + +namespace rive::ore +{ + +// ============================================================================ +// Enum → GL conversion helpers (used by factory methods) +// ============================================================================ + +static GLenum oreFormatToGLInternal(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return GL_R8; + case TextureFormat::rg8unorm: + return GL_RG8; + case TextureFormat::rgba8unorm: + return GL_RGBA8; + case TextureFormat::rgba8snorm: + return GL_RGBA8_SNORM; + case TextureFormat::bgra8unorm: + return GL_RGBA8; + case TextureFormat::rgba16float: + return GL_RGBA16F; + case TextureFormat::rg16float: + return GL_RG16F; + case TextureFormat::r16float: + return GL_R16F; + case TextureFormat::rgba32float: + return GL_RGBA32F; + case TextureFormat::rg32float: + return GL_RG32F; + case TextureFormat::r32float: + return GL_R32F; + case TextureFormat::rgb10a2unorm: + return GL_RGB10_A2; + case TextureFormat::r11g11b10float: + return GL_R11F_G11F_B10F; + case TextureFormat::depth16unorm: + return GL_DEPTH_COMPONENT16; + case TextureFormat::depth24plusStencil8: + return GL_DEPTH24_STENCIL8; + case TextureFormat::depth32float: + return GL_DEPTH_COMPONENT32F; + case TextureFormat::depth32floatStencil8: + return GL_DEPTH32F_STENCIL8; + case TextureFormat::etc2rgb8: + return GL_COMPRESSED_RGB8_ETC2; + case TextureFormat::etc2rgba8: + return GL_COMPRESSED_RGBA8_ETC2_EAC; +#ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT + case TextureFormat::bc1unorm: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case TextureFormat::bc3unorm: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; +#else + case TextureFormat::bc1unorm: + case TextureFormat::bc3unorm: + RIVE_UNREACHABLE(); +#endif +#ifdef GL_COMPRESSED_RGBA_BPTC_UNORM + case TextureFormat::bc7unorm: + return GL_COMPRESSED_RGBA_BPTC_UNORM; +#else + case TextureFormat::bc7unorm: + RIVE_UNREACHABLE(); +#endif +#ifdef GL_COMPRESSED_RGBA_ASTC_4x4_KHR + case TextureFormat::astc4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case TextureFormat::astc6x6: + return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case TextureFormat::astc8x8: + return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; +#else + case TextureFormat::astc4x4: + case TextureFormat::astc6x6: + case TextureFormat::astc8x8: + RIVE_UNREACHABLE(); +#endif + } + RIVE_UNREACHABLE(); +} + +static bool isDepthFormat(TextureFormat fmt) +{ + return fmt == TextureFormat::depth16unorm || + fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32float || + fmt == TextureFormat::depth32floatStencil8; +} + +static GLenum oreTextureTypeToGLTarget(TextureType type) +{ + switch (type) + { + case TextureType::texture2D: + return GL_TEXTURE_2D; + case TextureType::cube: + return GL_TEXTURE_CUBE_MAP; + case TextureType::texture3D: + return GL_TEXTURE_3D; + case TextureType::array2D: + return GL_TEXTURE_2D_ARRAY; + } + RIVE_UNREACHABLE(); +} + +static GLenum oreFilterToGL(Filter f) +{ + return (f == Filter::linear) ? GL_LINEAR : GL_NEAREST; +} + +static GLenum oreMipmapFilterToGL(Filter min, Filter mip) +{ + if (min == Filter::linear) + { + return (mip == Filter::linear) ? GL_LINEAR_MIPMAP_LINEAR + : GL_LINEAR_MIPMAP_NEAREST; + } + return (mip == Filter::linear) ? GL_NEAREST_MIPMAP_LINEAR + : GL_NEAREST_MIPMAP_NEAREST; +} + +static GLenum oreWrapToGL(WrapMode mode) +{ + switch (mode) + { + case WrapMode::repeat: + return GL_REPEAT; + case WrapMode::mirrorRepeat: + return GL_MIRRORED_REPEAT; + case WrapMode::clampToEdge: + return GL_CLAMP_TO_EDGE; + } + RIVE_UNREACHABLE(); +} + +static GLenum oreCompareFunctionToGL(CompareFunction fn) +{ + switch (fn) + { + case CompareFunction::none: + case CompareFunction::never: + return GL_NEVER; + case CompareFunction::less: + return GL_LESS; + case CompareFunction::equal: + return GL_EQUAL; + case CompareFunction::lessEqual: + return GL_LEQUAL; + case CompareFunction::greater: + return GL_GREATER; + case CompareFunction::notEqual: + return GL_NOTEQUAL; + case CompareFunction::greaterEqual: + return GL_GEQUAL; + case CompareFunction::always: + return GL_ALWAYS; + } + RIVE_UNREACHABLE(); +} + +// ============================================================================ +// Context lifecycle +// ============================================================================ + +ContextGL::~ContextGL() {} + +std::unique_ptr ContextGL::Make() +{ + auto ctx = std::unique_ptr(new ContextGL()); + + Features& f = ctx->m_features; + + // GLES3 / WebGL2 baseline capabilities. + f.colorBufferFloat = false; // Requires EXT_color_buffer_float. + f.perTargetBlend = false; // GLES3: global blend only. + f.perTargetWriteMask = false; + f.textureViewSampling = false; // No glTextureView on GLES3. + f.drawBaseInstance = false; + f.depthBiasClamp = false; // GLES3 glPolygonOffset has no clamp param. + f.anisotropicFiltering = false; + f.texture3D = true; + f.textureArrays = true; + f.computeShaders = false; + f.storageBuffers = false; + f.bc = false; + f.etc2 = true; // GLES3 mandates ETC2. + f.astc = false; + + // Query limits. + GLint maxTexSize = 0, maxCubeSize = 0, max3DSize = 0, maxUBOSize = 0; + GLint maxDrawBuffers = 0, maxVertexAttribs = 0, maxTexUnits = 0; + GLint maxSamples = 0; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeSize); + glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DSize); + glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUBOSize); + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexUnits); + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + + f.maxTextureSize2D = maxTexSize; + f.maxTextureSizeCube = maxCubeSize; + f.maxTextureSize3D = max3DSize; + f.maxUniformBufferSize = maxUBOSize; + f.maxColorAttachments = std::min(static_cast(maxDrawBuffers), 4u); + f.maxVertexAttributes = maxVertexAttribs; + f.maxSamplers = maxTexUnits; + f.maxSamples = std::max(maxSamples, 1); + + // Check extensions. + GLint numExtensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + for (GLint i = 0; i < numExtensions; ++i) + { + const char* ext = + reinterpret_cast(glGetStringi(GL_EXTENSIONS, i)); + if (!ext) + continue; + if (strcmp(ext, "GL_EXT_color_buffer_float") == 0) + f.colorBufferFloat = true; + else if (strcmp(ext, "GL_EXT_texture_filter_anisotropic") == 0) + f.anisotropicFiltering = true; + else if (strcmp(ext, "GL_KHR_texture_compression_astc_ldr") == 0) + f.astc = true; +#ifdef RIVE_DESKTOP_GL + else if (strcmp(ext, "GL_EXT_texture_compression_s3tc") == 0) + f.bc = true; +#endif + } + + return ctx; +} + +void ContextGL::beginFrame() +{ + // Release deferred BindGroups from last frame. By beginFrame() the + // caller has waited for the previous frame's GPU work to complete. + m_deferredBindGroups.clear(); + + // Save GL state that Ore will modify, so Rive's PLS renderer state is + // preserved across an Ore render pass. + glGetIntegerv(GL_CURRENT_PROGRAM, &m_savedState.program); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_savedState.arrayBuffer); + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_savedState.framebuffer); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &m_savedState.vertexArray); + // NOTE: GL_ELEMENT_ARRAY_BUFFER is intentionally NOT saved here because + // it is part of VAO state — restoring the VAO implicitly restores the + // element buffer that was associated with it. +} + +void ContextGL::waitForGPU() {} // GL is synchronous after glFinish/flush. + +void ContextGL::endFrame() +{ + // Restore saved state. Each `RenderPass::finish()` already restores + // its own captured VAO in-place, so by the time we get here only the + // program / array-buffer / framebuffer bindings need restoring — + // and only if they still exist. Mac ANGLE (GL-ES-3 over Metal) + // strictly validates non-zero object IDs via GL_KHR_debug and will + // abort if the host renderer has deleted a program or buffer + // between our `beginFrame` save and this restore. Guard each bind + // with the matching `glIs*` probe; name == 0 always refers to the + // default object (no validation error). + if (m_savedState.program == 0 || + glIsProgram(m_savedState.program) == GL_TRUE) + { + glUseProgram(m_savedState.program); + } + if (m_savedState.vertexArray == 0 || + glIsVertexArray(m_savedState.vertexArray) == GL_TRUE) + { + glBindVertexArray(m_savedState.vertexArray); + } + if (m_savedState.arrayBuffer == 0 || + glIsBuffer(m_savedState.arrayBuffer) == GL_TRUE) + { + glBindBuffer(GL_ARRAY_BUFFER, m_savedState.arrayBuffer); + } + // NOTE: GL_ELEMENT_ARRAY_BUFFER is intentionally NOT restored here. + // It is VAO state — binding the saved VAO above already restored the + // element buffer association. Explicitly binding it here would modify + // the active VAO's element buffer, which can corrupt the host + // renderer's VAO state if the saved value doesn't match. + if (m_savedState.framebuffer == 0 || + glIsFramebuffer(m_savedState.framebuffer) == GL_TRUE) + { + glBindFramebuffer(GL_FRAMEBUFFER, m_savedState.framebuffer); + } +} + +// ============================================================================ +// makeBuffer +// ============================================================================ + +rcp ContextGL::makeBuffer(const BufferDesc& desc) +{ + auto buffer = rcp(new Buffer(desc.size, desc.usage)); + + glGenBuffers(1, &buffer->m_glBuffer); + + switch (desc.usage) + { + case BufferUsage::vertex: + buffer->m_glTarget = GL_ARRAY_BUFFER; + break; + case BufferUsage::index: + buffer->m_glTarget = GL_ELEMENT_ARRAY_BUFFER; + break; + case BufferUsage::uniform: + buffer->m_glTarget = GL_UNIFORM_BUFFER; + break; + } + + // WebGL forbids binding a buffer to GL_ELEMENT_ARRAY_BUFFER if it was ever + // bound to a different target, so index buffers must use their native + // target. GL_ELEMENT_ARRAY_BUFFER is VAO state, so we save/restore the + // current binding to avoid clobbering the host renderer's VAO. + GLenum glUsage = (desc.data != nullptr) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW; + if (desc.usage == BufferUsage::index) + { + GLint prevEBO; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevEBO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->m_glBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, desc.size, desc.data, glUsage); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevEBO); + } + else + { + glBindBuffer(GL_COPY_WRITE_BUFFER, buffer->m_glBuffer); + glBufferData(GL_COPY_WRITE_BUFFER, desc.size, desc.data, glUsage); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + } + + return buffer; +} + +// ============================================================================ +// makeTexture +// ============================================================================ + +rcp ContextGL::makeTexture(const TextureDesc& desc) +{ + auto texture = rcp(new Texture(desc)); + + glGenTextures(1, &texture->m_glTexture); + texture->m_glTarget = oreTextureTypeToGLTarget(desc.type); + + GLenum internalFormat = oreFormatToGLInternal(desc.format); + + // Force the active unit to GL_TEXTURE0 before a transient bind. The host + // renderer (Rive PLS) reserves units 8..14 for its own textures and + // assumes those bindings persist between flushes. If the caller entered + // with one of those units active (common after a flush), a naked + // glBindTexture() here would overwrite Rive's binding on that unit. + glActiveTexture(GL_TEXTURE0); + glBindTexture(texture->m_glTarget, texture->m_glTexture); + + switch (desc.type) + { + case TextureType::texture2D: + if (desc.sampleCount > 1) + { + // MSAA render targets use renderbuffers — they can't be + // sampled anyway, and renderbuffers work on all + // GL/GLES3/WebGL2 (unlike GL_TEXTURE_2D_MULTISAMPLE). + glDeleteTextures(1, &texture->m_glTexture); + texture->m_glTexture = 0; + texture->m_glTarget = 0; + + glGenRenderbuffers(1, &texture->m_glRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, texture->m_glRenderbuffer); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, + desc.sampleCount, + internalFormat, + desc.width, + desc.height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + else + { + glTexStorage2D(GL_TEXTURE_2D, + desc.numMipmaps, + internalFormat, + desc.width, + desc.height); + } + break; + + case TextureType::cube: + glTexStorage2D(GL_TEXTURE_CUBE_MAP, + desc.numMipmaps, + internalFormat, + desc.width, + desc.height); + break; + + case TextureType::texture3D: + glTexStorage3D(GL_TEXTURE_3D, + desc.numMipmaps, + internalFormat, + desc.width, + desc.height, + desc.depthOrArrayLayers); + break; + + case TextureType::array2D: + glTexStorage3D(GL_TEXTURE_2D_ARRAY, + desc.numMipmaps, + internalFormat, + desc.width, + desc.height, + desc.depthOrArrayLayers); + break; + } + + // Renderbuffer-backed MSAA textures don't have sampler parameters. + if (texture->m_glRenderbuffer == 0) + { + glTexParameteri(texture->m_glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(texture->m_glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(texture->m_glTarget, + GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE); + glTexParameteri(texture->m_glTarget, + GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE); + glBindTexture(texture->m_glTarget, 0); + } + + return texture; +} + +// ============================================================================ +// makeTextureView +// ============================================================================ + +rcp ContextGL::makeTextureView(const TextureViewDesc& desc) +{ + Texture* tex = desc.texture; + if (!tex) + return nullptr; + + auto view = rcp(new TextureView(ref_rcp(tex), desc)); + + // GLES3 doesn't have glTextureView. We store m_glTextureView = 0 + // and use the base texture at bind time. FBO attachment targeting + // specific mip/layer is done via glFramebufferTextureLayer. + view->m_glTextureView = 0; + + return view; +} + +// ============================================================================ +// makeSampler +// ============================================================================ + +rcp ContextGL::makeSampler(const SamplerDesc& desc) +{ + auto sampler = rcp(new Sampler()); + + glGenSamplers(1, &sampler->m_glSampler); + GLuint s = sampler->m_glSampler; + + // Min filter includes mipmap mode. + if (desc.maxLod > 0.0f) + { + glSamplerParameteri( + s, + GL_TEXTURE_MIN_FILTER, + oreMipmapFilterToGL(desc.minFilter, desc.mipmapFilter)); + } + else + { + glSamplerParameteri(s, + GL_TEXTURE_MIN_FILTER, + oreFilterToGL(desc.minFilter)); + } + glSamplerParameteri(s, + GL_TEXTURE_MAG_FILTER, + oreFilterToGL(desc.magFilter)); + + glSamplerParameteri(s, GL_TEXTURE_WRAP_S, oreWrapToGL(desc.wrapU)); + glSamplerParameteri(s, GL_TEXTURE_WRAP_T, oreWrapToGL(desc.wrapV)); + glSamplerParameteri(s, GL_TEXTURE_WRAP_R, oreWrapToGL(desc.wrapW)); + + glSamplerParameterf(s, GL_TEXTURE_MIN_LOD, desc.minLod); + glSamplerParameterf(s, GL_TEXTURE_MAX_LOD, desc.maxLod); + + if (desc.compare != CompareFunction::none) + { + glSamplerParameteri(s, + GL_TEXTURE_COMPARE_MODE, + GL_COMPARE_REF_TO_TEXTURE); + glSamplerParameteri(s, + GL_TEXTURE_COMPARE_FUNC, + oreCompareFunctionToGL(desc.compare)); + } + + return sampler; +} + +// ============================================================================ +// makeShaderModule +// ============================================================================ + +rcp ContextGL::makeShaderModule(const ShaderModuleDesc& desc) +{ + auto module = rcp(new ShaderModule()); + + const char* source = static_cast(desc.code); + + bool isVertex; + if (desc.stage != ShaderStage::autoDetect) + { + isVertex = (desc.stage == ShaderStage::vertex); + } + else + { + // Legacy fallback: detect shader type from gl_Position presence. + // Use bounded search — RSTB blobs are NOT null-terminated. + const char* needle = "gl_Position"; + const size_t needleLen = 11; // strlen("gl_Position") + isVertex = false; + if (desc.codeSize >= needleLen) + { + const char* end = source + desc.codeSize - needleLen + 1; + for (const char* p = source; p < end; ++p) + { + if (memcmp(p, needle, needleLen) == 0) + { + isVertex = true; + break; + } + } + } + } + module->m_glShaderType = isVertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; + + module->m_glShader = glCreateShader(module->m_glShaderType); + + GLint length = static_cast(desc.codeSize); + glShaderSource(module->m_glShader, 1, &source, &length); + glCompileShader(module->m_glShader); + + GLint status = 0; + glGetShaderiv(module->m_glShader, GL_COMPILE_STATUS, &status); + if (!status) + { + char log[1024] = {}; + GLint logLen = 0; + glGetShaderiv(module->m_glShader, GL_INFO_LOG_LENGTH, &logLen); + if (logLen > 0) + { + glGetShaderInfoLog(module->m_glShader, + std::min(logLen, (GLint)sizeof(log)), + nullptr, + log); + } + setLastError("Ore GL shader compile error: %s", log); + glDeleteShader(module->m_glShader); + return nullptr; + } + + module->applyBindingMapFromDesc(desc); + return module; +} + +// ============================================================================ +// GL uniform fixup (shared by pure GL and VK+GL backends) +// ============================================================================ + +/// Fix up UBO block bindings and sampler texture unit assignments for a +/// linked GL program. Driven entirely by the RSTB-baked fixup tables +/// carried on each `ShaderModule` (sidecar targets 14 = VS, 15 = FS). +/// The runtime never parses the emitted GLSL names — the shader-side +/// allocator and the runtime-side `BindingMap::lookup` agree on a single +/// set of GL slots via the allocator's output. +/// +/// Calls `glUniformBlockBinding` / `glUniform1i` by name: redundant +/// calls (a UBO declared in both VS and FS, which shows up in both +/// stages' fixup tables with the same slot) are harmless — the GL +/// driver overwrites with the same value. +// Depth-only pipelines have no user-supplied fragment shader, but GLES 3.0 +// won't link a non-separable program object that lacks a fragment stage. +// Mirror Dawn's GL backend (its +// `UsePlaceholderFragmentInVertexOnlyPipeline` toggle, enabled on GLES): +// synthesize a no-op FS, attach + immediately glDeleteShader. The shader +// stays alive via GL refcount until the program is destroyed. +static void attachNoOpGLFragmentShader(GLuint program) +{ + static const char kSrc[] = "#version 300 es\nvoid main() {}\n"; + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + const char* src = kSrc; + GLint len = static_cast(sizeof(kSrc) - 1); + glShaderSource(fs, 1, &src, &len); + glCompileShader(fs); + glAttachShader(program, fs); + glDeleteShader(fs); +} + +static void oreGLFixupProgramBindings(GLuint program, + const ShaderModule* vsModule, + const ShaderModule* fsModule) +{ + glUseProgram(program); + + auto applyEntry = [&](const ShaderModule::GLFixupEntry& e) { + if (e.kind == ShaderModule::GLFixupEntry::Kind::UBOBlock) + { + GLuint idx = glGetUniformBlockIndex(program, e.name.c_str()); + if (idx != GL_INVALID_INDEX) + glUniformBlockBinding(program, idx, e.slot); + } + else // SamplerUniform + { + GLint loc = glGetUniformLocation(program, e.name.c_str()); + if (loc >= 0) + glUniform1i(loc, e.slot); + } + }; + + if (vsModule != nullptr) + { + for (const auto& e : vsModule->m_glFixup) + applyEntry(e); + } + if (fsModule != nullptr && fsModule != vsModule) + { + for (const auto& e : fsModule->m_glFixup) + applyEntry(e); + } + + glUseProgram(0); +} + +// ============================================================================ +// makePipeline +// ============================================================================ + +rcp ContextGL::makePipeline(const PipelineDesc& desc, + std::string* outError) +{ + auto pipeline = rcp(new Pipeline(desc)); + + // --- Validate user-supplied layouts against shader binding map --- + { + std::string err; + if (!validateLayoutsAgainstBindingMap(pipeline->m_bindingMap, + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + &err) || + !validateColorRequiresFragment(desc.colorCount, + desc.fragmentModule != nullptr, + &err)) + { + if (outError) + *outError = err; + else + setLastError("makePipeline: %s", err.c_str()); + return nullptr; + } + } + + pipeline->m_glProgram = glCreateProgram(); + glAttachShader(pipeline->m_glProgram, desc.vertexModule->m_glShader); + if (desc.fragmentModule != nullptr) + { + glAttachShader(pipeline->m_glProgram, desc.fragmentModule->m_glShader); + } + else + { + attachNoOpGLFragmentShader(pipeline->m_glProgram); + } + + // Bind vertex attribute locations before linking (matches shaderSlot). + for (uint32_t bufIdx = 0; bufIdx < desc.vertexBufferCount; ++bufIdx) + { + const auto& layout = desc.vertexBuffers[bufIdx]; + for (uint32_t attrIdx = 0; attrIdx < layout.attributeCount; ++attrIdx) + { + const auto& attr = layout.attributes[attrIdx]; + char name[32]; + snprintf(name, sizeof(name), "a_attr%u", attr.shaderSlot); + glBindAttribLocation(pipeline->m_glProgram, attr.shaderSlot, name); + } + } + + glLinkProgram(pipeline->m_glProgram); + + GLint status = 0; + glGetProgramiv(pipeline->m_glProgram, GL_LINK_STATUS, &status); + if (!status) + { + std::string linkLog = "GL program link failed"; + GLint logLen = 0; + glGetProgramiv(pipeline->m_glProgram, GL_INFO_LOG_LENGTH, &logLen); + if (logLen > 0) + { + char log[1024]; + glGetProgramInfoLog(pipeline->m_glProgram, + std::min(logLen, (GLint)sizeof(log)), + nullptr, + log); + linkLog = log; + } + setLastError("Ore GL program link error: %s", linkLog.c_str()); + if (outError) + *outError = std::move(linkLog); + return nullptr; + } + + oreGLFixupProgramBindings(pipeline->m_glProgram, + desc.vertexModule, + desc.fragmentModule); + + // (Removed: a `m_glState` cache that was populated here but never + // consulted by `setPipeline`. Re-add when an actual delta-tracking + // path lands.) + + return pipeline; +} + +// ============================================================================ +// makeBindGroup +// ============================================================================ + +rcp ContextGL::makeBindGroup(const BindGroupDesc& desc) +{ + if (desc.layout == nullptr) + { + setLastError("makeBindGroup: BindGroupDesc::layout is null"); + return nullptr; + } + BindGroupLayout* layout = desc.layout; + const uint32_t groupIndex = layout->groupIndex(); + if (groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroup: layout->groupIndex %u out of range", + groupIndex); + return nullptr; + } + auto bg = rcp(new BindGroup()); + bg->m_context = this; + bg->m_layoutRef = ref_rcp(layout); + + // Native GL slot resolution: layout entries are pre-resolved by the + // GM/Lua helper (makeLayoutFromShader) using the shader's binding map. + // The v1 GLSL allocator's global-counter-per-kind ensures slots are + // unique across groups. Sampler entries carry the paired-texture's GL + // unit (combined-sampler fold-in), matching the GL link-side fixup. + auto nativeSlot = + [&](uint32_t binding, BindingKind expected, uint32_t* outSlot) -> bool { + const BindGroupLayoutEntry* le = layout->findEntry(binding); + if (le == nullptr) + { + setLastError("makeBindGroup: (group=%u, binding=%u) not declared " + "in BindGroupLayout", + groupIndex, + binding); + return false; + } + const bool kindOK = le->kind == expected || + ((le->kind == BindingKind::sampler || + le->kind == BindingKind::comparisonSampler) && + (expected == BindingKind::sampler || + expected == BindingKind::comparisonSampler)); + if (!kindOK) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout kind " + "mismatch", + groupIndex, + binding); + return false; + } + uint32_t s = + (le->nativeSlotVS != BindGroupLayoutEntry::kNativeSlotAbsent) + ? le->nativeSlotVS + : le->nativeSlotFS; + if (s == BindGroupLayoutEntry::kNativeSlotAbsent) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout has " + "no resolved native slot — call " + "makeLayoutFromShader", + groupIndex, + binding); + return false; + } + *outSlot = s; + return true; + }; + + // UBO bindings. + uint32_t nBufs = std::min(desc.uboCount, 8u); + bg->m_glUBOs.reserve(nBufs); + for (uint32_t i = 0; i < nBufs; ++i) + { + const auto& entry = desc.ubos[i]; + BindGroup::GLUBOBinding binding{}; + binding.buffer = entry.buffer->m_glBuffer; + binding.offset = entry.offset; + binding.size = entry.size != 0 + ? entry.size + : static_cast(entry.buffer->size()); + binding.binding = entry.slot; + if (!nativeSlot(entry.slot, BindingKind::uniformBuffer, &binding.slot)) + continue; + binding.hasDynamicOffset = layout->hasDynamicOffset(entry.slot); + if (binding.hasDynamicOffset) + bg->m_dynamicOffsetCount++; + bg->m_glUBOs.push_back(binding); + bg->m_retainedBuffers.push_back(ref_rcp(entry.buffer)); + } + std::sort( + bg->m_glUBOs.begin(), + bg->m_glUBOs.end(), + [](const BindGroup::GLUBOBinding& a, const BindGroup::GLUBOBinding& b) { + return a.binding < b.binding; + }); + + uint32_t nTexs = std::min(desc.textureCount, 8u); + bg->m_glTextures.reserve(nTexs); + for (uint32_t i = 0; i < nTexs; ++i) + { + const auto& entry = desc.textures[i]; + BindGroup::GLTexBinding binding{}; + binding.texture = entry.view->m_glTextureView != 0 + ? entry.view->m_glTextureView + : entry.view->texture()->m_glTexture; + binding.target = entry.view->texture()->m_glTarget; + if (!nativeSlot(entry.slot, BindingKind::sampledTexture, &binding.slot)) + continue; + bg->m_glTextures.push_back(binding); + bg->m_retainedViews.push_back(ref_rcp(entry.view)); + } + + uint32_t nSamps = std::min(desc.samplerCount, 8u); + bg->m_glSamplers.reserve(nSamps); + for (uint32_t i = 0; i < nSamps; ++i) + { + const auto& entry = desc.samplers[i]; + BindGroup::GLSamplerBinding binding{}; + binding.sampler = entry.sampler->m_glSampler; + if (!nativeSlot(entry.slot, BindingKind::sampler, &binding.slot)) + continue; + bg->m_glSamplers.push_back(binding); + bg->m_retainedSamplers.push_back(ref_rcp(entry.sampler)); + } + + return bg; +} + +// ============================================================================ +// makeBindGroupLayout +// ============================================================================ + +rcp ContextGL::makeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + if (desc.groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroupLayout: groupIndex %u out of range [0, %u)", + desc.groupIndex, + kMaxBindGroups); + return nullptr; + } + auto layout = rcp(new BindGroupLayout()); + layout->m_context = this; + layout->m_groupIndex = desc.groupIndex; + layout->m_entries.reserve(desc.entryCount); + for (uint32_t i = 0; i < desc.entryCount; ++i) + layout->m_entries.push_back(desc.entries[i]); + // GL has no native layout object — entries-only suffices. + return layout; +} + +// ============================================================================ +// beginRenderPass +// ============================================================================ + +RenderPass ContextGL::beginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + finishActiveRenderPass(); + + RenderPass pass; + pass.m_context = this; + pass.populateAttachmentMetadata(desc); + + // Save the host renderer's VAO and FBO so we can restore them in finish(). + GLint prevVAO = 0, prevFBO = 0; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO); + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFBO); + pass.m_prevVAO = static_cast(prevVAO); + pass.m_prevFBO = static_cast(prevFBO); + + // Create an FBO for this render pass. + glGenFramebuffers(1, &pass.m_glFBO); + pass.m_ownsFBO = true; + glBindFramebuffer(GL_FRAMEBUFFER, pass.m_glFBO); + + // Attach color targets. + GLenum drawBuffers[4] = {}; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + if (ca.view) + { + Texture* tex = ca.view->texture(); + GLenum attachment = GL_COLOR_ATTACHMENT0 + i; + + if (tex->m_glRenderbuffer != 0) + { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + attachment, + GL_RENDERBUFFER, + tex->m_glRenderbuffer); + } + else if (tex->type() == TextureType::cube) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, + attachment, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + + ca.view->baseLayer(), + tex->m_glTexture, + ca.view->baseMipLevel()); + } + else if (tex->type() == TextureType::array2D || + tex->type() == TextureType::texture3D) + { + glFramebufferTextureLayer(GL_FRAMEBUFFER, + attachment, + tex->m_glTexture, + ca.view->baseMipLevel(), + ca.view->baseLayer()); + } + else + { + glFramebufferTexture2D(GL_FRAMEBUFFER, + attachment, + GL_TEXTURE_2D, + tex->m_glTexture, + ca.view->baseMipLevel()); + } + + // Record resolve target for MSAA blit in finish(). + if (ca.resolveTarget) + { + auto& r = pass.m_glResolves[pass.m_glResolveCount++]; + r.colorIndex = i; + r.resolveTex = ca.resolveTarget->texture()->m_glTexture; + r.resolveTarget = ca.resolveTarget->texture()->m_glTarget; + r.width = tex->width(); + r.height = tex->height(); + } + + drawBuffers[i] = attachment; + } + } + + if (desc.colorCount > 0) + { + glDrawBuffers(desc.colorCount, drawBuffers); + } + + // Attach depth/stencil. + if (desc.depthStencil.view) + { + Texture* depthTex = desc.depthStencil.view->texture(); + GLenum depthAttachment; + + TextureFormat depthFmt = depthTex->format(); + bool hasStencil = (depthFmt == TextureFormat::depth24plusStencil8 || + depthFmt == TextureFormat::depth32floatStencil8); + depthAttachment = + hasStencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; + + if (depthTex->m_glRenderbuffer != 0) + { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + depthAttachment, + GL_RENDERBUFFER, + depthTex->m_glRenderbuffer); + } + else + { + glFramebufferTexture2D(GL_FRAMEBUFFER, + depthAttachment, + GL_TEXTURE_2D, + depthTex->m_glTexture, + desc.depthStencil.view->baseMipLevel()); + } + } + + // Verify completeness (debug only). + assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == + GL_FRAMEBUFFER_COMPLETE && + "Ore GL FBO incomplete"); + + // Handle clear ops. + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + if (ca.loadOp == LoadOp::clear) + { + GLfloat clearColor[4] = {ca.clearColor.r, + ca.clearColor.g, + ca.clearColor.b, + ca.clearColor.a}; + glClearBufferfv(GL_COLOR, i, clearColor); + } + } + + if (desc.depthStencil.view) + { + TextureFormat depthFmt = desc.depthStencil.view->texture()->format(); + bool hasStencil = (depthFmt == TextureFormat::depth24plusStencil8 || + depthFmt == TextureFormat::depth32floatStencil8); + + if (desc.depthStencil.depthLoadOp == LoadOp::clear && hasStencil && + desc.depthStencil.stencilLoadOp == LoadOp::clear) + { + glDepthMask(GL_TRUE); + glStencilMask(0xFF); + GLfloat depth = desc.depthStencil.depthClearValue; + GLint stencil = + static_cast(desc.depthStencil.stencilClearValue); + glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil); + } + else + { + if (desc.depthStencil.depthLoadOp == LoadOp::clear) + { + glDepthMask(GL_TRUE); + GLfloat depth = desc.depthStencil.depthClearValue; + glClearBufferfv(GL_DEPTH, 0, &depth); + } + if (hasStencil && desc.depthStencil.stencilLoadOp == LoadOp::clear) + { + glStencilMask(0xFF); + GLint stencil = + static_cast(desc.depthStencil.stencilClearValue); + glClearBufferiv(GL_STENCIL, 0, &stencil); + } + } + } + + // Create a dedicated VAO for this render pass so Ore's vertex attrib state + // doesn't contaminate the host renderer's VAO (e.g., Rive's draw VAO). + glGenVertexArrays(1, &pass.m_glVAO); + pass.m_ownsVAO = true; + glBindVertexArray(pass.m_glVAO); + + // Set a default viewport from the first color or depth attachment so + // scripts that omit setViewport() still render correctly. Metal infers + // this automatically; GL does not. + uint32_t defaultW = 0, defaultH = 0; + if (desc.colorCount > 0 && desc.colorAttachments[0].view) + { + defaultW = desc.colorAttachments[0].view->texture()->width(); + defaultH = desc.colorAttachments[0].view->texture()->height(); + } + else if (desc.depthStencil.view) + { + defaultW = desc.depthStencil.view->texture()->width(); + defaultH = desc.depthStencil.view->texture()->height(); + } + if (defaultW > 0 && defaultH > 0) + { + glViewport(0, 0, defaultW, defaultH); + pass.m_viewportWidth = defaultW; + pass.m_viewportHeight = defaultH; + } + + return pass; +} + +// ============================================================================ +// wrapCanvasTexture +// ============================================================================ + +rcp ContextGL::wrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + assert(canvas != nullptr); + + auto* glTarget = + static_cast(canvas->renderTarget()); + GLuint texID = glTarget->externalTextureID(); + assert(texID != 0); + + TextureDesc texDesc{}; + texDesc.width = canvas->width(); + texDesc.height = canvas->height(); + texDesc.format = TextureFormat::rgba8unorm; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = true; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_glTexture = texID; // Borrow — RenderCanvas owns it. + texture->m_glTarget = GL_TEXTURE_2D; + texture->m_glOwnsTexture = false; + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + return rcp(new TextureView(std::move(texture), viewDesc)); +} + +rcp ContextGL::wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + if (!gpuTex) + return nullptr; + + GLuint texID = static_cast( + reinterpret_cast(gpuTex->nativeHandle())); + if (texID == 0) + return nullptr; + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = TextureFormat::rgba8unorm; // Images decode to RGBA8. + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = false; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_glTexture = texID; // Borrow — caller owns via RenderImage. + texture->m_glTarget = GL_TEXTURE_2D; + texture->m_glOwnsTexture = false; + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + return rcp(new TextureView(std::move(texture), viewDesc)); +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_context_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_context_gl.mm new file mode 100644 index 000000000..6fc2421ff --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_context_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_context_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.cpp new file mode 100644 index 000000000..d222f770e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +void Pipeline::onRefCntReachedZero() const +{ + if (m_glProgram != 0) + { + glDeleteProgram(m_glProgram); + } + delete this; +} + +void BindGroupLayout::onRefCntReachedZero() const { delete this; } + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL && !ORE_BACKEND_VK + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.mm new file mode 100644 index 000000000..47e80e30d --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_pipeline_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_pipeline_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.cpp new file mode 100644 index 000000000..d6e825ac9 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.cpp @@ -0,0 +1,740 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_context_gl.hpp" // for RenderPass inline bodies +#include "rive/rive_types.hpp" + +namespace rive::ore +{ + +static GLenum oreTopologyToGL(PrimitiveTopology topo) +{ + switch (topo) + { + case PrimitiveTopology::pointList: + return GL_POINTS; + case PrimitiveTopology::lineList: + return GL_LINES; + case PrimitiveTopology::lineStrip: + return GL_LINE_STRIP; + case PrimitiveTopology::triangleList: + return GL_TRIANGLES; + case PrimitiveTopology::triangleStrip: + return GL_TRIANGLE_STRIP; + } + RIVE_UNREACHABLE(); +} + +static GLenum oreBlendFactorToGL(BlendFactor f) +{ + switch (f) + { + case BlendFactor::zero: + return GL_ZERO; + case BlendFactor::one: + return GL_ONE; + case BlendFactor::srcColor: + return GL_SRC_COLOR; + case BlendFactor::oneMinusSrcColor: + return GL_ONE_MINUS_SRC_COLOR; + case BlendFactor::srcAlpha: + return GL_SRC_ALPHA; + case BlendFactor::oneMinusSrcAlpha: + return GL_ONE_MINUS_SRC_ALPHA; + case BlendFactor::dstColor: + return GL_DST_COLOR; + case BlendFactor::oneMinusDstColor: + return GL_ONE_MINUS_DST_COLOR; + case BlendFactor::dstAlpha: + return GL_DST_ALPHA; + case BlendFactor::oneMinusDstAlpha: + return GL_ONE_MINUS_DST_ALPHA; + case BlendFactor::srcAlphaSaturated: + return GL_SRC_ALPHA_SATURATE; + case BlendFactor::blendColor: + return GL_CONSTANT_COLOR; + case BlendFactor::oneMinusBlendColor: + return GL_ONE_MINUS_CONSTANT_COLOR; + } + RIVE_UNREACHABLE(); +} + +static GLenum oreBlendOpToGL(BlendOp op) +{ + switch (op) + { + case BlendOp::add: + return GL_FUNC_ADD; + case BlendOp::subtract: + return GL_FUNC_SUBTRACT; + case BlendOp::reverseSubtract: + return GL_FUNC_REVERSE_SUBTRACT; + case BlendOp::min: + return GL_MIN; + case BlendOp::max: + return GL_MAX; + } + RIVE_UNREACHABLE(); +} + +static GLenum oreCompareFunctionToGL(CompareFunction fn) +{ + switch (fn) + { + case CompareFunction::none: + case CompareFunction::never: + return GL_NEVER; + case CompareFunction::less: + return GL_LESS; + case CompareFunction::equal: + return GL_EQUAL; + case CompareFunction::lessEqual: + return GL_LEQUAL; + case CompareFunction::greater: + return GL_GREATER; + case CompareFunction::notEqual: + return GL_NOTEQUAL; + case CompareFunction::greaterEqual: + return GL_GEQUAL; + case CompareFunction::always: + return GL_ALWAYS; + } + RIVE_UNREACHABLE(); +} + +static GLenum oreStencilOpToGL(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return GL_KEEP; + case StencilOp::zero: + return GL_ZERO; + case StencilOp::replace: + return GL_REPLACE; + case StencilOp::incrementClamp: + return GL_INCR; + case StencilOp::decrementClamp: + return GL_DECR; + case StencilOp::invert: + return GL_INVERT; + case StencilOp::incrementWrap: + return GL_INCR_WRAP; + case StencilOp::decrementWrap: + return GL_DECR_WRAP; + } + RIVE_UNREACHABLE(); +} + +// Vertex format → GL type, component count, normalized. +struct GLVertexInfo +{ + GLenum type; + GLint count; + GLboolean normalized; +}; + +static GLVertexInfo oreVertexFormatToGL(VertexFormat fmt) +{ + switch (fmt) + { + case VertexFormat::float1: + return {GL_FLOAT, 1, GL_FALSE}; + case VertexFormat::float2: + return {GL_FLOAT, 2, GL_FALSE}; + case VertexFormat::float3: + return {GL_FLOAT, 3, GL_FALSE}; + case VertexFormat::float4: + return {GL_FLOAT, 4, GL_FALSE}; + case VertexFormat::uint8x4: + return {GL_UNSIGNED_BYTE, 4, GL_FALSE}; + case VertexFormat::sint8x4: + return {GL_BYTE, 4, GL_FALSE}; + case VertexFormat::unorm8x4: + return {GL_UNSIGNED_BYTE, 4, GL_TRUE}; + case VertexFormat::snorm8x4: + return {GL_BYTE, 4, GL_TRUE}; + case VertexFormat::uint16x2: + return {GL_UNSIGNED_SHORT, 2, GL_FALSE}; + case VertexFormat::sint16x2: + return {GL_SHORT, 2, GL_FALSE}; + case VertexFormat::unorm16x2: + return {GL_UNSIGNED_SHORT, 2, GL_TRUE}; + case VertexFormat::snorm16x2: + return {GL_SHORT, 2, GL_TRUE}; + case VertexFormat::uint16x4: + return {GL_UNSIGNED_SHORT, 4, GL_FALSE}; + case VertexFormat::sint16x4: + return {GL_SHORT, 4, GL_FALSE}; + case VertexFormat::float16x2: + return {GL_HALF_FLOAT, 2, GL_FALSE}; + case VertexFormat::float16x4: + return {GL_HALF_FLOAT, 4, GL_FALSE}; + case VertexFormat::uint32: + return {GL_UNSIGNED_INT, 1, GL_FALSE}; + case VertexFormat::uint32x2: + return {GL_UNSIGNED_INT, 2, GL_FALSE}; + case VertexFormat::uint32x3: + return {GL_UNSIGNED_INT, 3, GL_FALSE}; + case VertexFormat::uint32x4: + return {GL_UNSIGNED_INT, 4, GL_FALSE}; + case VertexFormat::sint32: + return {GL_INT, 1, GL_FALSE}; + case VertexFormat::sint32x2: + return {GL_INT, 2, GL_FALSE}; + case VertexFormat::sint32x3: + return {GL_INT, 3, GL_FALSE}; + case VertexFormat::sint32x4: + return {GL_INT, 4, GL_FALSE}; + } + RIVE_UNREACHABLE(); +} + +// ============================================================================ +// RenderPass +// ============================================================================ + +// When both Metal and GL are compiled (macOS), ore_render_pass_metal_gl.mm +// provides all RenderPass method bodies with runtime dispatch. This file +// only contributes the static helper functions in that case. +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +RenderPass::~RenderPass() +{ + if (!m_finished && m_context != nullptr) + { + finish(); + } +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + m_glFBO(other.m_glFBO), + m_glVAO(other.m_glVAO), + m_prevVAO(other.m_prevVAO), + m_prevFBO(other.m_prevFBO), + m_ownsFBO(other.m_ownsFBO), + m_ownsVAO(other.m_ownsVAO), + m_currentPipeline(std::move(other.m_currentPipeline)), + m_viewportWidth(other.m_viewportWidth), + m_viewportHeight(other.m_viewportHeight), + m_maxSamplerSlot(other.m_maxSamplerSlot), + m_maxAttribSlot(other.m_maxAttribSlot), + m_usedSamplers(other.m_usedSamplers), + m_usedAttribs(other.m_usedAttribs), + m_glResolveCount(other.m_glResolveCount) +{ + moveCrossBackendFieldsFrom(other); + for (uint32_t i = 0; i < m_glResolveCount; ++i) + m_glResolves[i] = other.m_glResolves[i]; + other.m_ownsFBO = false; + other.m_ownsVAO = false; + other.m_glResolveCount = 0; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && m_context != nullptr) + { + finish(); + } + moveCrossBackendFieldsFrom(other); + m_glFBO = other.m_glFBO; + m_glVAO = other.m_glVAO; + m_prevVAO = other.m_prevVAO; + m_prevFBO = other.m_prevFBO; + m_ownsFBO = other.m_ownsFBO; + m_ownsVAO = other.m_ownsVAO; + m_currentPipeline = std::move(other.m_currentPipeline); + m_viewportWidth = other.m_viewportWidth; + m_viewportHeight = other.m_viewportHeight; + m_maxSamplerSlot = other.m_maxSamplerSlot; + m_maxAttribSlot = other.m_maxAttribSlot; + m_usedSamplers = other.m_usedSamplers; + m_usedAttribs = other.m_usedAttribs; + m_glResolveCount = other.m_glResolveCount; + for (uint32_t i = 0; i < m_glResolveCount; ++i) + m_glResolves[i] = other.m_glResolves[i]; + other.m_ownsFBO = false; + other.m_ownsVAO = false; + other.m_glResolveCount = 0; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_context != nullptr); +} + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + m_currentPipeline = ref_rcp(pipeline); + + const auto& desc = pipeline->desc(); + + glUseProgram(pipeline->m_glProgram); + + // Cull mode. + if (desc.cullMode == CullMode::none) + { + glDisable(GL_CULL_FACE); + } + else + { + glEnable(GL_CULL_FACE); + glCullFace(desc.cullMode == CullMode::front ? GL_FRONT : GL_BACK); + } + + // Face winding — inverted to compensate for the WGSL→GLSL Y-flip + // baked into every vertex shader at compile time. The same approach + // is used by wgpu and Dawn's GL backends. + glFrontFace(desc.winding == FaceWinding::counterClockwise ? GL_CW : GL_CCW); + + // Depth. + if (desc.depthStencil.depthCompare != CompareFunction::always || + desc.depthStencil.depthWriteEnabled) + { + glEnable(GL_DEPTH_TEST); + glDepthFunc(oreCompareFunctionToGL(desc.depthStencil.depthCompare)); + glDepthMask(desc.depthStencil.depthWriteEnabled ? GL_TRUE : GL_FALSE); + } + else + { + glDisable(GL_DEPTH_TEST); + } + + // Depth bias (polygon offset). + if (desc.depthStencil.depthBias != 0 || + desc.depthStencil.depthBiasSlopeScale != 0.0f) + { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(desc.depthStencil.depthBiasSlopeScale, + static_cast(desc.depthStencil.depthBias)); + } + else + { + glDisable(GL_POLYGON_OFFSET_FILL); + } + + // Stencil. + bool hasStencil = (desc.stencilFront.compare != CompareFunction::always || + desc.stencilFront.failOp != StencilOp::keep || + desc.stencilFront.depthFailOp != StencilOp::keep || + desc.stencilFront.passOp != StencilOp::keep || + desc.stencilBack.compare != CompareFunction::always || + desc.stencilBack.failOp != StencilOp::keep || + desc.stencilBack.depthFailOp != StencilOp::keep || + desc.stencilBack.passOp != StencilOp::keep); + + if (hasStencil) + { + glEnable(GL_STENCIL_TEST); + glStencilMaskSeparate(GL_FRONT, desc.stencilWriteMask); + glStencilMaskSeparate(GL_BACK, desc.stencilWriteMask); + glStencilFuncSeparate(GL_FRONT, + oreCompareFunctionToGL(desc.stencilFront.compare), + static_cast(m_glStencilRef), + desc.stencilReadMask); + glStencilFuncSeparate(GL_BACK, + oreCompareFunctionToGL(desc.stencilBack.compare), + static_cast(m_glStencilRef), + desc.stencilReadMask); + glStencilOpSeparate(GL_FRONT, + oreStencilOpToGL(desc.stencilFront.failOp), + oreStencilOpToGL(desc.stencilFront.depthFailOp), + oreStencilOpToGL(desc.stencilFront.passOp)); + glStencilOpSeparate(GL_BACK, + oreStencilOpToGL(desc.stencilBack.failOp), + oreStencilOpToGL(desc.stencilBack.depthFailOp), + oreStencilOpToGL(desc.stencilBack.passOp)); + } + else + { + glDisable(GL_STENCIL_TEST); + } + + // Blending — GLES3 only supports global blend (colorTargets[0]). + if (desc.colorCount > 0 && desc.colorTargets[0].blendEnabled) + { + glEnable(GL_BLEND); + const auto& b = desc.colorTargets[0].blend; + glBlendFuncSeparate(oreBlendFactorToGL(b.srcColor), + oreBlendFactorToGL(b.dstColor), + oreBlendFactorToGL(b.srcAlpha), + oreBlendFactorToGL(b.dstAlpha)); + glBlendEquationSeparate(oreBlendOpToGL(b.colorOp), + oreBlendOpToGL(b.alphaOp)); + } + else + { + glDisable(GL_BLEND); + } + + // Color write mask (global on GLES3). + if (desc.colorCount > 0) + { + auto mask = desc.colorTargets[0].writeMask; + glColorMask((mask & ColorWriteMask::red) != ColorWriteMask::none, + (mask & ColorWriteMask::green) != ColorWriteMask::none, + (mask & ColorWriteMask::blue) != ColorWriteMask::none, + (mask & ColorWriteMask::alpha) != ColorWriteMask::none); + } +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + assert(m_currentPipeline != nullptr && "setPipeline must be called first"); + assert(slot < m_currentPipeline->desc().vertexBufferCount); + + const auto& layout = m_currentPipeline->desc().vertexBuffers[slot]; + + glBindBuffer(GL_ARRAY_BUFFER, buffer->m_glBuffer); + + for (uint32_t i = 0; i < layout.attributeCount; ++i) + { + const auto& attr = layout.attributes[i]; + GLVertexInfo info = oreVertexFormatToGL(attr.format); + + glEnableVertexAttribArray(attr.shaderSlot); + + bool isIntType = + (info.type == GL_UNSIGNED_INT || info.type == GL_INT || + info.type == GL_UNSIGNED_BYTE || info.type == GL_BYTE || + info.type == GL_UNSIGNED_SHORT || info.type == GL_SHORT) && + !info.normalized; + + if (isIntType) + { + glVertexAttribIPointer( + attr.shaderSlot, + info.count, + info.type, + layout.stride, + reinterpret_cast( + static_cast(attr.offset + offset))); + } + else + { + glVertexAttribPointer( + attr.shaderSlot, + info.count, + info.type, + info.normalized, + layout.stride, + reinterpret_cast( + static_cast(attr.offset + offset))); + } + + if (layout.stepMode == VertexStepMode::instance) + { + glVertexAttribDivisor(attr.shaderSlot, 1); + } + else + { + glVertexAttribDivisor(attr.shaderSlot, 0); + } + + // Track for cleanup in finish(). + if (!m_usedAttribs || attr.shaderSlot > m_maxAttribSlot) + m_maxAttribSlot = attr.shaderSlot; + m_usedAttribs = true; + } +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->m_glBuffer); + m_glIndexFormat = format; + (void)offset; +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + assert(bg != nullptr); + + // Hold a strong reference so the BindGroup stays alive until finish(). + m_boundGroups[groupIndex] = ref_rcp(bg); + + uint32_t dynIdx = 0; + + // Bind UBOs via glBindBufferRange. Dynamic-offset flag is cached + // on the binding from `Pipeline::isDynamicUBO()` at makeBindGroup + // time; consume one `dynamicOffsets[]` entry per dynamic UBO. + for (const auto& ubo : bg->m_glUBOs) + { + uint32_t offset = ubo.offset; + if (ubo.hasDynamicOffset && dynIdx < dynamicOffsetCount) + { + offset += dynamicOffsets[dynIdx]; + ++dynIdx; + } + glBindBufferRange(GL_UNIFORM_BUFFER, + ubo.slot, + ubo.buffer, + offset, + ubo.size); + } + + // Bind textures. + for (const auto& tex : bg->m_glTextures) + { + glActiveTexture(GL_TEXTURE0 + tex.slot); + glBindTexture(tex.target, tex.texture); + + // Track for cleanup in finish(). + if (!m_usedSamplers || tex.slot > m_maxSamplerSlot) + m_maxSamplerSlot = tex.slot; + m_usedSamplers = true; + } + + // Bind samplers. + for (const auto& samp : bg->m_glSamplers) + { + glBindSampler(samp.slot, samp.sampler); + + if (!m_usedSamplers || samp.slot > m_maxSamplerSlot) + m_maxSamplerSlot = samp.slot; + m_usedSamplers = true; + } +} + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ + validate(); + m_viewportWidth = static_cast(width); + m_viewportHeight = static_cast(height); + // Ore NDC convention: Y-up clip space, depth in [0, 1]. + // GLES has Y-up natively, so no viewport flip is needed here (unlike + // Vulkan). The depth range mismatch (GLES [-1,1] vs ore's [0,1]) and + // the Y-flip required by the Vulkan-style WGSL coordinate space are + // both corrected in the compiled vertex shader at WGSL→GLSL compile + // time — no runtime fixup is needed. + glViewport(static_cast(x), + static_cast(y), + static_cast(width), + static_cast(height)); + glDepthRangef(minDepth, maxDepth); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + glEnable(GL_SCISSOR_TEST); + glScissor(x, y, width, height); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + // Cache the ref so a subsequent `setPipeline` re-applies it. WebGPU + // semantics: `setStencilReference` is pass-state and persists across + // pipeline changes — calling it BEFORE the first `setPipeline` is + // valid, so we must not depend on `m_currentPipeline` here. + m_glStencilRef = ref; + if (m_currentPipeline) + { + const auto& desc = m_currentPipeline->desc(); + glStencilFuncSeparate(GL_FRONT, + oreCompareFunctionToGL(desc.stencilFront.compare), + static_cast(ref), + desc.stencilReadMask); + glStencilFuncSeparate(GL_BACK, + oreCompareFunctionToGL(desc.stencilBack.compare), + static_cast(ref), + desc.stencilReadMask); + } +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + glBlendColor(r, g, b, a); +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + assert(m_currentPipeline != nullptr); + GLenum mode = oreTopologyToGL(m_currentPipeline->desc().topology); + + (void)firstInstance; // GLES3 doesn't support base instance. + + if (instanceCount > 1) + { + glDrawArraysInstanced(mode, firstVertex, vertexCount, instanceCount); + } + else + { + glDrawArrays(mode, firstVertex, vertexCount); + } +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + assert(m_currentPipeline != nullptr); + GLenum mode = oreTopologyToGL(m_currentPipeline->desc().topology); + GLenum indexType = (m_glIndexFormat == IndexFormat::uint32) + ? GL_UNSIGNED_INT + : GL_UNSIGNED_SHORT; + uint32_t indexSize = + (indexType == GL_UNSIGNED_INT) ? sizeof(uint32_t) : sizeof(uint16_t); + const void* offset = reinterpret_cast( + static_cast(firstIndex * indexSize)); + + (void)baseVertex; // Not supported on base GLES3. + (void)firstInstance; // Not supported on GLES3. + + if (instanceCount > 1) + { + glDrawElementsInstanced(mode, + indexCount, + indexType, + offset, + instanceCount); + } + else + { + glDrawElements(mode, indexCount, indexType, offset); + } +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + + // Restore defaults. + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_POLYGON_OFFSET_FILL); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + // Unbind sampler objects and textures so they don't override texture + // parameters in subsequent draws by the host renderer (e.g. Rive's MSAA + // path). + if (m_usedSamplers) + { + for (uint32_t i = 0; i <= m_maxSamplerSlot; ++i) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindSampler(i, 0); + } + glActiveTexture(GL_TEXTURE0); + } + + // Disable vertex attrib arrays that were enabled, so they don't + // contaminate the host renderer's VAO state. + if (m_usedAttribs) + { + for (uint32_t i = 0; i <= m_maxAttribSlot; ++i) + glDisableVertexAttribArray(i); + } + + // Unbind the global array buffer. (GL_ELEMENT_ARRAY_BUFFER is VAO state + // and will be cleaned up when the per-pass VAO is deleted below — we must + // NOT unbind it here because on some WebGL2 implementations the EBO=0 + // can leak through the VAO delete/restore and corrupt the host VAO.) + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // Delete the per-pass VAO and restore the host renderer's VAO so its + // element-array-buffer binding (and other attrib state) is intact. + if (m_ownsVAO && m_glVAO != 0) + { + glDeleteVertexArrays(1, &m_glVAO); + m_glVAO = 0; + } + glBindVertexArray(m_prevVAO); + + // Resolve MSAA renderbuffers → single-sample resolve targets. + if (m_glResolveCount > 0) + { + GLuint resolveFBO; + glGenFramebuffers(1, &resolveFBO); + for (uint32_t i = 0; i < m_glResolveCount; ++i) + { + const auto& r = m_glResolves[i]; + // Read from the render pass FBO (MSAA renderbuffer attached). + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_glFBO); + glReadBuffer(GL_COLOR_ATTACHMENT0 + r.colorIndex); + + // Write to a temp FBO with the single-sample resolve texture. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + r.resolveTarget, + r.resolveTex, + 0); + + glBlitFramebuffer(0, + 0, + r.width, + r.height, + 0, + 0, + r.width, + r.height, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + } + glDeleteFramebuffers(1, &resolveFBO); + } + + // Delete our FBO and restore the host renderer's FBO. + if (m_ownsFBO && m_glFBO != 0) + { + glDeleteFramebuffers(1, &m_glFBO); + } + glBindFramebuffer(GL_FRAMEBUFFER, m_prevFBO); + + m_context = nullptr; +} + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.mm new file mode 100644 index 000000000..4b971c183 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_render_pass_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_render_pass_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.cpp new file mode 100644 index 000000000..b50c53ffe --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +void Sampler::onRefCntReachedZero() const +{ + if (m_glSampler != 0) + { + GLuint samp = m_glSampler; + glDeleteSamplers(1, &samp); + } + delete this; +} + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.mm new file mode 100644 index 000000000..205aa2b3d --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_sampler_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_sampler_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.cpp new file mode 100644 index 000000000..f13c553c9 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +void ShaderModule::onRefCntReachedZero() const +{ + if (m_glShader != 0) + { + glDeleteShader(m_glShader); + } + delete this; +} + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.mm new file mode 100644 index 000000000..e2522167e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_shader_module_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_shader_module_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.cpp b/thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.cpp new file mode 100644 index 000000000..645196209 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.cpp @@ -0,0 +1,386 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/rive_types.hpp" + +namespace rive::ore +{ + +// GL internal format for a given ore TextureFormat. +static GLenum oreFormatToGLInternal(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return GL_R8; + case TextureFormat::rg8unorm: + return GL_RG8; + case TextureFormat::rgba8unorm: + return GL_RGBA8; + case TextureFormat::rgba8snorm: + return GL_RGBA8_SNORM; + case TextureFormat::bgra8unorm: + // GLES3 doesn't have GL_BGRA8; use RGBA8 (swizzle in shader). + return GL_RGBA8; + case TextureFormat::rgba16float: + return GL_RGBA16F; + case TextureFormat::rg16float: + return GL_RG16F; + case TextureFormat::r16float: + return GL_R16F; + case TextureFormat::rgba32float: + return GL_RGBA32F; + case TextureFormat::rg32float: + return GL_RG32F; + case TextureFormat::r32float: + return GL_R32F; + case TextureFormat::rgb10a2unorm: + return GL_RGB10_A2; + case TextureFormat::r11g11b10float: + return GL_R11F_G11F_B10F; + case TextureFormat::depth16unorm: + return GL_DEPTH_COMPONENT16; + case TextureFormat::depth24plusStencil8: + return GL_DEPTH24_STENCIL8; + case TextureFormat::depth32float: + return GL_DEPTH_COMPONENT32F; + case TextureFormat::depth32floatStencil8: + return GL_DEPTH32F_STENCIL8; + // Compressed formats — internal format constants. +#ifdef GL_COMPRESSED_RGB_S3TC_DXT1_EXT + case TextureFormat::bc1unorm: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case TextureFormat::bc3unorm: + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; +#else + case TextureFormat::bc1unorm: + case TextureFormat::bc3unorm: + RIVE_UNREACHABLE(); +#endif +#ifdef GL_COMPRESSED_RGBA_BPTC_UNORM + case TextureFormat::bc7unorm: + return GL_COMPRESSED_RGBA_BPTC_UNORM; +#else + case TextureFormat::bc7unorm: + RIVE_UNREACHABLE(); +#endif + case TextureFormat::etc2rgb8: + return GL_COMPRESSED_RGB8_ETC2; + case TextureFormat::etc2rgba8: + return GL_COMPRESSED_RGBA8_ETC2_EAC; +#ifdef GL_COMPRESSED_RGBA_ASTC_4x4_KHR + case TextureFormat::astc4x4: + return GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + case TextureFormat::astc6x6: + return GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + case TextureFormat::astc8x8: + return GL_COMPRESSED_RGBA_ASTC_8x8_KHR; +#else + case TextureFormat::astc4x4: + case TextureFormat::astc6x6: + case TextureFormat::astc8x8: + RIVE_UNREACHABLE(); +#endif + } + RIVE_UNREACHABLE(); +} + +// GL format + type for upload. +static GLenum oreFormatToGLFormat(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + case TextureFormat::r16float: + case TextureFormat::r32float: + return GL_RED; + case TextureFormat::rg8unorm: + case TextureFormat::rg16float: + case TextureFormat::rg32float: + return GL_RG; + case TextureFormat::rgba8unorm: + case TextureFormat::rgba8snorm: + case TextureFormat::bgra8unorm: + case TextureFormat::rgba16float: + case TextureFormat::rgba32float: + return GL_RGBA; + case TextureFormat::rgb10a2unorm: + return GL_RGBA; + case TextureFormat::r11g11b10float: + return GL_RGB; + case TextureFormat::depth16unorm: + case TextureFormat::depth32float: + return GL_DEPTH_COMPONENT; + case TextureFormat::depth24plusStencil8: + case TextureFormat::depth32floatStencil8: + return GL_DEPTH_STENCIL; + default: + RIVE_UNREACHABLE(); + } +} + +static GLenum oreFormatToGLType(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + case TextureFormat::rg8unorm: + case TextureFormat::rgba8unorm: + case TextureFormat::bgra8unorm: + return GL_UNSIGNED_BYTE; + case TextureFormat::rgba8snorm: + return GL_BYTE; + case TextureFormat::rgba16float: + case TextureFormat::rg16float: + case TextureFormat::r16float: + return GL_HALF_FLOAT; + case TextureFormat::rgba32float: + case TextureFormat::rg32float: + case TextureFormat::r32float: + case TextureFormat::depth32float: + return GL_FLOAT; + case TextureFormat::rgb10a2unorm: + return GL_UNSIGNED_INT_2_10_10_10_REV; + case TextureFormat::r11g11b10float: + return GL_UNSIGNED_INT_10F_11F_11F_REV; + case TextureFormat::depth16unorm: + return GL_UNSIGNED_SHORT; + case TextureFormat::depth24plusStencil8: + return GL_UNSIGNED_INT_24_8; + case TextureFormat::depth32floatStencil8: + return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; + default: + RIVE_UNREACHABLE(); + } +} + +static bool isDepthFormat(TextureFormat fmt) +{ + return fmt == TextureFormat::depth16unorm || + fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32float || + fmt == TextureFormat::depth32floatStencil8; +} + +static GLenum oreTextureTypeToGLTarget(TextureType type) +{ + switch (type) + { + case TextureType::texture2D: + return GL_TEXTURE_2D; + case TextureType::cube: + return GL_TEXTURE_CUBE_MAP; + case TextureType::texture3D: + return GL_TEXTURE_3D; + case TextureType::array2D: + return GL_TEXTURE_2D_ARRAY; + } + RIVE_UNREACHABLE(); +} + +// Block-compressed format detection. For these formats, `bytesPerRow` is +// the byte size of a row of compressed *blocks* (4×4 for BC1/BC3/BC7/ETC2/ +// ASTC4x4, 6×6 / 8×8 for the corresponding ASTC variants), and the upload +// path must go through `glCompressedTexSubImage*` with `imageSize` bytes. +static bool isCompressedFormat(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::bc1unorm: + case TextureFormat::bc3unorm: + case TextureFormat::bc7unorm: + case TextureFormat::etc2rgb8: + case TextureFormat::etc2rgba8: + case TextureFormat::astc4x4: + case TextureFormat::astc6x6: + case TextureFormat::astc8x8: + return true; + default: + return false; + } +} + +#if defined(ORE_BACKEND_GL) && !defined(ORE_BACKEND_METAL) && \ + !defined(ORE_BACKEND_VK) + +void Texture::upload(const TextureDataDesc& data) +{ + assert(m_glTexture != 0); + assert(data.data != nullptr); + + // GLES3 has no `GL_BGRA8` internal format, and uploading BGRA bytes + // through `GL_RGBA + GL_UNSIGNED_BYTE` silently swizzles channels + // (red ↔ blue) in the resulting texture. Reject explicitly here + // rather than letting the corruption render. Callers that need + // BGRA-source data on GL should pre-swizzle in software or use + // `rgba8unorm`. (BGRA *render targets* — e.g. canvas wrapping — + // remain valid since they don't go through this upload path.) + assert(m_format != TextureFormat::bgra8unorm && + "GLES3 cannot upload BGRA pixels — " + "pre-swizzle to rgba8unorm or use a different format"); + + // Force the active unit to GL_TEXTURE0 before a transient bind. See + // Context::makeTexture() for the full rationale — Rive PLS reserves + // units 8..14 and a naked glBindTexture() on one of those units would + // clobber Rive's state. + glActiveTexture(GL_TEXTURE0); + glBindTexture(m_glTarget, m_glTexture); + + GLenum internalFmt = oreFormatToGLInternal(m_format); + + // Compressed formats route through `glCompressedTexSubImage*` with a + // byte count, not format/type. `bytesPerRow * rowsPerImage` is the + // total compressed byte size for one slice; multiply by `depth` for + // 3D / array uploads. Pre-fix the GL backend always called + // `glTexSubImage*` regardless of format — uploads of any compressed + // texture (ETC2/BC/ASTC) failed silently with `GL_INVALID_OPERATION`. + if (isCompressedFormat(m_format)) + { + const uint32_t imageSize = + data.bytesPerRow * + (data.rowsPerImage > 0 ? data.rowsPerImage : data.height) * + (data.depth > 0 ? data.depth : 1); + if (m_glTarget == GL_TEXTURE_3D || m_glTarget == GL_TEXTURE_2D_ARRAY) + { + glCompressedTexSubImage3D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.layer, + data.width, + data.height, + data.depth, + internalFmt, + imageSize, + data.data); + } + else if (m_glTarget == GL_TEXTURE_CUBE_MAP) + { + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + + data.layer, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + internalFmt, + imageSize, + data.data); + } + else + { + glCompressedTexSubImage2D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + internalFmt, + imageSize, + data.data); + } + glBindTexture(m_glTarget, 0); + return; + } + + GLenum format = oreFormatToGLFormat(m_format); + GLenum type = oreFormatToGLType(m_format); + + // Honor `bytesPerRow` / `rowsPerImage` for non-tightly-packed source + // data via `GL_UNPACK_ROW_LENGTH` / `GL_UNPACK_IMAGE_HEIGHT`. Save + + // restore so we don't trash the host's pixel-store state. Pre-fix the + // GL backend ignored these fields — uploads from a sub-rect of a + // larger source buffer (or from a layout that pads rows) read garbage + // bytes between rows. + GLint savedRowLength = 0, savedImageHeight = 0; + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &savedRowLength); + glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &savedImageHeight); + const uint32_t bpt = textureFormatBytesPerTexel(m_format); + if (data.bytesPerRow != 0 && bpt != 0 && (data.bytesPerRow % bpt) == 0) + { + glPixelStorei(GL_UNPACK_ROW_LENGTH, + static_cast(data.bytesPerRow / bpt)); + } + if (data.rowsPerImage != 0) + { + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, + static_cast(data.rowsPerImage)); + } + + if (m_glTarget == GL_TEXTURE_3D || m_glTarget == GL_TEXTURE_2D_ARRAY) + { + glTexSubImage3D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.layer, + data.width, + data.height, + data.depth, + format, + type, + data.data); + } + else if (m_glTarget == GL_TEXTURE_CUBE_MAP) + { + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + data.layer, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + format, + type, + data.data); + } + else + { + glTexSubImage2D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + format, + type, + data.data); + } + + // Restore host pixel-store state. + glPixelStorei(GL_UNPACK_ROW_LENGTH, savedRowLength); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, savedImageHeight); + + glBindTexture(m_glTarget, 0); +} + +void Texture::onRefCntReachedZero() const +{ + if (m_glRenderbuffer != 0 && m_glOwnsTexture) + { + GLuint rb = m_glRenderbuffer; + glDeleteRenderbuffers(1, &rb); + } + if (m_glTexture != 0 && m_glOwnsTexture) + { + GLuint tex = m_glTexture; + glDeleteTextures(1, &tex); + } + delete this; +} + +void TextureView::onRefCntReachedZero() const +{ + if (m_glTextureView != 0) + { + GLuint tex = m_glTextureView; + glDeleteTextures(1, &tex); + } + delete this; +} + +#endif // ORE_BACKEND_GL && !ORE_BACKEND_METAL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.mm b/thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.mm new file mode 100644 index 000000000..3f953f4e3 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/gl/ore_texture_gl.mm @@ -0,0 +1,3 @@ +// ObjC++ wrapper for macOS — ore headers include when both +// backends are active. +#include "ore_texture_gl.cpp" diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal.mm new file mode 100644 index 000000000..4bbf26d2e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal.mm @@ -0,0 +1,26 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_metal.hpp" + +#import + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal_gl.mm new file mode 100644 index 000000000..2fffd6225 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_bind_group_metal_gl.mm @@ -0,0 +1,29 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL BindGroup implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_metal.hpp" + +#import + +namespace rive::ore +{ + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(). By the time refcount reaches + // zero here, the GPU is guaranteed to be done. + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal.mm new file mode 100644 index 000000000..60cc2db62 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal.mm @@ -0,0 +1,29 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/rive_types.hpp" + +#import + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + memcpy(static_cast([m_mtlBuffer contents]) + offset, data, size); +} + +void Buffer::onRefCntReachedZero() const +{ + // Release the Metal buffer by destroying this object. + delete this; +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal_gl.mm new file mode 100644 index 000000000..aff3e86a0 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_buffer_metal_gl.mm @@ -0,0 +1,44 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL Buffer implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/rive_types.hpp" + +#import + +namespace rive::ore +{ + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + if (m_glBuffer != 0) + { + glBindBuffer(m_glTarget, m_glBuffer); + glBufferSubData(m_glTarget, offset, size, data); + glBindBuffer(m_glTarget, 0); + return; + } + memcpy(static_cast([m_mtlBuffer contents]) + offset, data, size); +} + +void Buffer::onRefCntReachedZero() const +{ + if (m_glBuffer != 0) + { + GLuint buf = m_glBuffer; + glDeleteBuffers(1, &buf); + } + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_context_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_context_metal.mm new file mode 100644 index 000000000..e62956580 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_context_metal.mm @@ -0,0 +1,1379 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_context_metal.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/renderer/metal/render_context_metal_impl.h" +#include "rive/rive_types.hpp" + +#include + +#import + +namespace rive::ore +{ + +// ============================================================================ +// Enum → Metal conversion helpers +// ============================================================================ + +static MTLPixelFormat oreFormatToMTL(TextureFormat format) +{ + switch (format) + { + case TextureFormat::r8unorm: + return MTLPixelFormatR8Unorm; + case TextureFormat::rg8unorm: + return MTLPixelFormatRG8Unorm; + case TextureFormat::rgba8unorm: + return MTLPixelFormatRGBA8Unorm; + case TextureFormat::rgba8snorm: + return MTLPixelFormatRGBA8Snorm; + case TextureFormat::bgra8unorm: + return MTLPixelFormatBGRA8Unorm; + case TextureFormat::rgba16float: + return MTLPixelFormatRGBA16Float; + case TextureFormat::rg16float: + return MTLPixelFormatRG16Float; + case TextureFormat::r16float: + return MTLPixelFormatR16Float; + case TextureFormat::rgba32float: + return MTLPixelFormatRGBA32Float; + case TextureFormat::rg32float: + return MTLPixelFormatRG32Float; + case TextureFormat::r32float: + return MTLPixelFormatR32Float; + case TextureFormat::rgb10a2unorm: + return MTLPixelFormatRGB10A2Unorm; + case TextureFormat::r11g11b10float: + return MTLPixelFormatRG11B10Float; + case TextureFormat::depth16unorm: + return MTLPixelFormatDepth16Unorm; + case TextureFormat::depth24plusStencil8: +#if defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR) || TARGET_CPU_ARM64 + // iOS and Apple Silicon (ARM64) don't support Depth24Unorm. + return MTLPixelFormatDepth32Float_Stencil8; +#else + return MTLPixelFormatDepth24Unorm_Stencil8; +#endif + case TextureFormat::depth32float: + return MTLPixelFormatDepth32Float; + case TextureFormat::depth32floatStencil8: + return MTLPixelFormatDepth32Float_Stencil8; + case TextureFormat::bc1unorm: +#if TARGET_OS_OSX || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 160400) + if (@available(iOS 16.4, *)) + return MTLPixelFormatBC1_RGBA; +#endif + RIVE_UNREACHABLE(); + case TextureFormat::bc3unorm: +#if TARGET_OS_OSX || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 160400) + if (@available(iOS 16.4, *)) + return MTLPixelFormatBC3_RGBA; +#endif + RIVE_UNREACHABLE(); + case TextureFormat::bc7unorm: +#if TARGET_OS_OSX || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 160400) + if (@available(iOS 16.4, *)) + return MTLPixelFormatBC7_RGBAUnorm; +#endif + RIVE_UNREACHABLE(); + case TextureFormat::etc2rgb8: + return MTLPixelFormatETC2_RGB8; + case TextureFormat::etc2rgba8: + return MTLPixelFormatEAC_RGBA8; + case TextureFormat::astc4x4: + return MTLPixelFormatASTC_4x4_LDR; + case TextureFormat::astc6x6: + return MTLPixelFormatASTC_6x6_LDR; + case TextureFormat::astc8x8: + return MTLPixelFormatASTC_8x8_LDR; + } + RIVE_UNREACHABLE(); +} + +static MTLTextureType oreTextureTypeToMTL(TextureType type) +{ + switch (type) + { + case TextureType::texture2D: + return MTLTextureType2D; + case TextureType::cube: + return MTLTextureTypeCube; + case TextureType::texture3D: + return MTLTextureType3D; + case TextureType::array2D: + return MTLTextureType2DArray; + } + RIVE_UNREACHABLE(); +} + +static MTLSamplerMinMagFilter oreFilterToMTL(Filter filter) +{ + switch (filter) + { + case Filter::nearest: + return MTLSamplerMinMagFilterNearest; + case Filter::linear: + return MTLSamplerMinMagFilterLinear; + } + RIVE_UNREACHABLE(); +} + +static MTLSamplerMipFilter oreMipFilterToMTL(Filter filter) +{ + switch (filter) + { + case Filter::nearest: + return MTLSamplerMipFilterNearest; + case Filter::linear: + return MTLSamplerMipFilterLinear; + } + RIVE_UNREACHABLE(); +} + +static MTLSamplerAddressMode oreWrapToMTL(WrapMode mode) +{ + switch (mode) + { + case WrapMode::repeat: + return MTLSamplerAddressModeRepeat; + case WrapMode::mirrorRepeat: + return MTLSamplerAddressModeMirrorRepeat; + case WrapMode::clampToEdge: + return MTLSamplerAddressModeClampToEdge; + } + RIVE_UNREACHABLE(); +} + +static MTLCompareFunction oreCompareFunctionToMTL(CompareFunction fn) +{ + switch (fn) + { + case CompareFunction::none: + return MTLCompareFunctionNever; // Should not be called for none. + case CompareFunction::never: + return MTLCompareFunctionNever; + case CompareFunction::less: + return MTLCompareFunctionLess; + case CompareFunction::equal: + return MTLCompareFunctionEqual; + case CompareFunction::lessEqual: + return MTLCompareFunctionLessEqual; + case CompareFunction::greater: + return MTLCompareFunctionGreater; + case CompareFunction::notEqual: + return MTLCompareFunctionNotEqual; + case CompareFunction::greaterEqual: + return MTLCompareFunctionGreaterEqual; + case CompareFunction::always: + return MTLCompareFunctionAlways; + } + RIVE_UNREACHABLE(); +} + +static MTLLoadAction oreLoadOpToMTL(LoadOp op) +{ + switch (op) + { + case LoadOp::clear: + return MTLLoadActionClear; + case LoadOp::load: + return MTLLoadActionLoad; + case LoadOp::dontCare: + return MTLLoadActionDontCare; + } + RIVE_UNREACHABLE(); +} + +static MTLStoreAction oreStoreOpToMTL(StoreOp op) +{ + switch (op) + { + case StoreOp::store: + return MTLStoreActionStore; + case StoreOp::discard: + return MTLStoreActionDontCare; + } + RIVE_UNREACHABLE(); +} + +static MTLBlendFactor oreBlendFactorToMTL(BlendFactor f) +{ + switch (f) + { + case BlendFactor::zero: + return MTLBlendFactorZero; + case BlendFactor::one: + return MTLBlendFactorOne; + case BlendFactor::srcColor: + return MTLBlendFactorSourceColor; + case BlendFactor::oneMinusSrcColor: + return MTLBlendFactorOneMinusSourceColor; + case BlendFactor::srcAlpha: + return MTLBlendFactorSourceAlpha; + case BlendFactor::oneMinusSrcAlpha: + return MTLBlendFactorOneMinusSourceAlpha; + case BlendFactor::dstColor: + return MTLBlendFactorDestinationColor; + case BlendFactor::oneMinusDstColor: + return MTLBlendFactorOneMinusDestinationColor; + case BlendFactor::dstAlpha: + return MTLBlendFactorDestinationAlpha; + case BlendFactor::oneMinusDstAlpha: + return MTLBlendFactorOneMinusDestinationAlpha; + case BlendFactor::srcAlphaSaturated: + return MTLBlendFactorSourceAlphaSaturated; + case BlendFactor::blendColor: + return MTLBlendFactorBlendColor; + case BlendFactor::oneMinusBlendColor: + return MTLBlendFactorOneMinusBlendColor; + } + RIVE_UNREACHABLE(); +} + +static MTLBlendOperation oreBlendOpToMTL(BlendOp op) +{ + switch (op) + { + case BlendOp::add: + return MTLBlendOperationAdd; + case BlendOp::subtract: + return MTLBlendOperationSubtract; + case BlendOp::reverseSubtract: + return MTLBlendOperationReverseSubtract; + case BlendOp::min: + return MTLBlendOperationMin; + case BlendOp::max: + return MTLBlendOperationMax; + } + RIVE_UNREACHABLE(); +} + +static MTLStencilOperation oreStencilOpToMTL(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return MTLStencilOperationKeep; + case StencilOp::zero: + return MTLStencilOperationZero; + case StencilOp::replace: + return MTLStencilOperationReplace; + case StencilOp::incrementClamp: + return MTLStencilOperationIncrementClamp; + case StencilOp::decrementClamp: + return MTLStencilOperationDecrementClamp; + case StencilOp::invert: + return MTLStencilOperationInvert; + case StencilOp::incrementWrap: + return MTLStencilOperationIncrementWrap; + case StencilOp::decrementWrap: + return MTLStencilOperationDecrementWrap; + } + RIVE_UNREACHABLE(); +} + +static MTLPrimitiveType orePrimitiveTopologyToMTL(PrimitiveTopology topo) +{ + switch (topo) + { + case PrimitiveTopology::pointList: + return MTLPrimitiveTypePoint; + case PrimitiveTopology::lineList: + return MTLPrimitiveTypeLine; + case PrimitiveTopology::lineStrip: + return MTLPrimitiveTypeLineStrip; + case PrimitiveTopology::triangleList: + return MTLPrimitiveTypeTriangle; + case PrimitiveTopology::triangleStrip: + return MTLPrimitiveTypeTriangleStrip; + } + RIVE_UNREACHABLE(); +} + +static MTLVertexFormat oreVertexFormatToMTL(VertexFormat fmt) +{ + switch (fmt) + { + case VertexFormat::float1: + return MTLVertexFormatFloat; + case VertexFormat::float2: + return MTLVertexFormatFloat2; + case VertexFormat::float3: + return MTLVertexFormatFloat3; + case VertexFormat::float4: + return MTLVertexFormatFloat4; + case VertexFormat::uint8x4: + return MTLVertexFormatUChar4; + case VertexFormat::sint8x4: + return MTLVertexFormatChar4; + case VertexFormat::unorm8x4: + return MTLVertexFormatUChar4Normalized; + case VertexFormat::snorm8x4: + return MTLVertexFormatChar4Normalized; + case VertexFormat::uint16x2: + return MTLVertexFormatUShort2; + case VertexFormat::sint16x2: + return MTLVertexFormatShort2; + case VertexFormat::unorm16x2: + return MTLVertexFormatUShort2Normalized; + case VertexFormat::snorm16x2: + return MTLVertexFormatShort2Normalized; + case VertexFormat::uint16x4: + return MTLVertexFormatUShort4; + case VertexFormat::sint16x4: + return MTLVertexFormatShort4; + case VertexFormat::float16x2: + return MTLVertexFormatHalf2; + case VertexFormat::float16x4: + return MTLVertexFormatHalf4; + case VertexFormat::uint32: + return MTLVertexFormatUInt; + case VertexFormat::uint32x2: + return MTLVertexFormatUInt2; + case VertexFormat::uint32x3: + return MTLVertexFormatUInt3; + case VertexFormat::uint32x4: + return MTLVertexFormatUInt4; + case VertexFormat::sint32: + return MTLVertexFormatInt; + case VertexFormat::sint32x2: + return MTLVertexFormatInt2; + case VertexFormat::sint32x3: + return MTLVertexFormatInt3; + case VertexFormat::sint32x4: + return MTLVertexFormatInt4; + } + RIVE_UNREACHABLE(); +} + +static MTLCullMode oreCullModeToMTL(CullMode mode) +{ + switch (mode) + { + case CullMode::none: + return MTLCullModeNone; + case CullMode::front: + return MTLCullModeFront; + case CullMode::back: + return MTLCullModeBack; + } + RIVE_UNREACHABLE(); +} + +static MTLWinding oreWindingToMTL(FaceWinding winding) +{ + switch (winding) + { + case FaceWinding::clockwise: + return MTLWindingClockwise; + case FaceWinding::counterClockwise: + return MTLWindingCounterClockwise; + } + RIVE_UNREACHABLE(); +} + +static MTLColorWriteMask oreColorWriteMaskToMTL(ColorWriteMask mask) +{ + MTLColorWriteMask mtl = MTLColorWriteMaskNone; + if ((mask & ColorWriteMask::red) != ColorWriteMask::none) + mtl |= MTLColorWriteMaskRed; + if ((mask & ColorWriteMask::green) != ColorWriteMask::none) + mtl |= MTLColorWriteMaskGreen; + if ((mask & ColorWriteMask::blue) != ColorWriteMask::none) + mtl |= MTLColorWriteMaskBlue; + if ((mask & ColorWriteMask::alpha) != ColorWriteMask::none) + mtl |= MTLColorWriteMaskAlpha; + return mtl; +} + +static MTLIndexType oreIndexFormatToMTL(IndexFormat format) +{ + switch (format) + { + case IndexFormat::uint16: + return MTLIndexTypeUInt16; + case IndexFormat::uint32: + return MTLIndexTypeUInt32; + case IndexFormat::none: + break; + } + RIVE_UNREACHABLE(); +} + +// Metal uses a single [[buffer(n)]] namespace for both vertex buffers and +// uniform/constant buffers. WGSL→MSL compilation assigns uniform buffers +// starting at buffer index 0. To avoid collisions we reserve the first N +// slots for uniforms and map vertex buffers to slots +// [kMetalVertexBufferBase, ...). +static constexpr uint32_t kMetalVertexBufferBase = 16; + +static TextureFormat mtlFormatToOre(MTLPixelFormat fmt) +{ + switch (fmt) + { + case MTLPixelFormatRGBA8Unorm: + return TextureFormat::rgba8unorm; + case MTLPixelFormatBGRA8Unorm: + return TextureFormat::bgra8unorm; + case MTLPixelFormatRGBA16Float: + return TextureFormat::rgba16float; + case MTLPixelFormatRGB10A2Unorm: + return TextureFormat::rgb10a2unorm; + default: + return TextureFormat::rgba8unorm; + } +} + +// ============================================================================ +// Metal implementation helpers (inline) +// Shared between metal-only and metal+gl builds. +// ============================================================================ + +inline void ContextMetal::mtlPopulateFeatures(id device) +{ + Features& f = m_features; + f.colorBufferFloat = true; + f.perTargetBlend = true; + f.perTargetWriteMask = true; + f.textureViewSampling = true; + f.drawBaseInstance = true; + f.depthBiasClamp = true; + f.anisotropicFiltering = true; + f.texture3D = true; + f.textureArrays = true; + f.computeShaders = true; + f.storageBuffers = true; + +#if defined(RIVE_IOS) || defined(RIVE_IOS_SIMULATOR) + f.bc = false; + f.etc2 = true; + f.astc = true; +#else + f.bc = true; + f.etc2 = false; + f.astc = false; +#endif + + f.maxColorAttachments = 8; + f.maxTextureSize2D = 16384; + f.maxTextureSizeCube = 16384; + f.maxTextureSize3D = 2048; + f.maxUniformBufferSize = 256 * 1024; + f.maxVertexAttributes = 31; + f.maxSamplers = 16; + + // Query the actual MSAA sample count limit from the device. + f.maxSamples = 1; + for (uint32_t sc : {8u, 4u, 2u}) + { + if ([device supportsTextureSampleCount:sc]) + { + f.maxSamples = sc; + break; + } + } +} + +inline rcp ContextMetal::mtlMakeBuffer(const BufferDesc& desc) +{ + auto buffer = rcp(new Buffer(desc.size, desc.usage)); + if (desc.data) + { + buffer->m_mtlBuffer = + [m_mtlDevice newBufferWithBytes:desc.data + length:desc.size + options:MTLResourceStorageModeShared]; + } + else + { + buffer->m_mtlBuffer = + [m_mtlDevice newBufferWithLength:desc.size + options:MTLResourceStorageModeShared]; + } + if (desc.label) + { + buffer->m_mtlBuffer.label = @(desc.label); + } + return buffer; +} + +inline rcp ContextMetal::mtlMakeTexture(const TextureDesc& desc) +{ + MTLTextureDescriptor* td = [[MTLTextureDescriptor alloc] init]; + + bool isMSAA = desc.sampleCount > 1 && desc.type == TextureType::texture2D; + td.textureType = + isMSAA ? MTLTextureType2DMultisample : oreTextureTypeToMTL(desc.type); + td.pixelFormat = oreFormatToMTL(desc.format); + td.width = desc.width; + td.height = desc.height; + td.mipmapLevelCount = isMSAA ? 1 : desc.numMipmaps; + td.sampleCount = desc.sampleCount; + // Private storage is GPU-only — replaceRegion (CPU upload) is undefined. + // Use Shared for uploadable textures so upload() works on all Metal + // devices. Render-target-only textures stay Private. + td.storageMode = + desc.renderTarget ? MTLStorageModePrivate : MTLStorageModeShared; + td.usage = MTLTextureUsageShaderRead; + + if (desc.type == TextureType::texture3D) + { + td.depth = desc.depthOrArrayLayers; + td.arrayLength = 1; + } + else if (desc.type == TextureType::array2D) + { + td.depth = 1; + td.arrayLength = desc.depthOrArrayLayers; + } + else if (desc.type == TextureType::cube) + { + td.depth = 1; + td.arrayLength = 1; + } + else + { + td.depth = 1; + td.arrayLength = 1; + } + + if (desc.renderTarget) + { + td.usage |= MTLTextureUsageRenderTarget; + } + + TextureFormat fmt = desc.format; + if (fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32floatStencil8) + { + td.usage |= MTLTextureUsagePixelFormatView; + } + + auto texture = rcp(new Texture(desc)); +#if RIVE_OBJC_EXCEPTIONS + @try + { + texture->m_mtlTexture = [m_mtlDevice newTextureWithDescriptor:td]; + } + @catch (NSException* e) + { + NSLog(@"RIVE ORE: makeTexture exception: %@", e.reason ?: @"unknown"); + return nullptr; + } +#else + texture->m_mtlTexture = [m_mtlDevice newTextureWithDescriptor:td]; +#endif + if (texture->m_mtlTexture == nil) + { + NSLog(@"RIVE ORE: makeTexture: newTextureWithDescriptor returned nil"); + return nullptr; + } + if (desc.label) + { + texture->m_mtlTexture.label = @(desc.label); + } + return texture; +} + +inline rcp ContextMetal::mtlMakeTextureView( + const TextureViewDesc& desc) +{ + Texture* tex = desc.texture; + assert(tex != nullptr); + + auto view = rcp(new TextureView(ref_rcp(tex), desc)); + + if (tex->m_mtlTexture.textureType == MTLTextureType2DMultisample) + return view; + + MTLTextureType viewType; + switch (desc.dimension) + { + case TextureViewDimension::texture2D: + viewType = MTLTextureType2D; + break; + case TextureViewDimension::cube: + viewType = MTLTextureTypeCube; + break; + case TextureViewDimension::texture3D: + viewType = MTLTextureType3D; + break; + case TextureViewDimension::array2D: + viewType = MTLTextureType2DArray; + break; + case TextureViewDimension::cubeArray: + viewType = MTLTextureTypeCubeArray; + break; + } + + NSRange mipRange = NSMakeRange(desc.baseMipLevel, desc.mipCount); + NSRange sliceRange = NSMakeRange(desc.baseLayer, desc.layerCount); + + view->m_mtlTextureView = [tex->m_mtlTexture + newTextureViewWithPixelFormat:tex->m_mtlTexture.pixelFormat + textureType:viewType + levels:mipRange + slices:sliceRange]; + return view; +} + +inline rcp ContextMetal::mtlMakeSampler(const SamplerDesc& desc) +{ + MTLSamplerDescriptor* sd = [[MTLSamplerDescriptor alloc] init]; + sd.minFilter = oreFilterToMTL(desc.minFilter); + sd.magFilter = oreFilterToMTL(desc.magFilter); + sd.mipFilter = oreMipFilterToMTL(desc.mipmapFilter); + sd.sAddressMode = oreWrapToMTL(desc.wrapU); + sd.tAddressMode = oreWrapToMTL(desc.wrapV); + sd.rAddressMode = oreWrapToMTL(desc.wrapW); + sd.lodMinClamp = desc.minLod; + sd.lodMaxClamp = desc.maxLod; + sd.maxAnisotropy = desc.maxAnisotropy; + + if (desc.compare != CompareFunction::none) + { + sd.compareFunction = oreCompareFunctionToMTL(desc.compare); + } + + if (desc.label) + { + sd.label = @(desc.label); + } + + auto sampler = rcp(new Sampler()); + sampler->m_mtlSampler = [m_mtlDevice newSamplerStateWithDescriptor:sd]; + return sampler; +} + +inline rcp ContextMetal::mtlMakeShaderModule( + const ShaderModuleDesc& desc) +{ + auto module = rcp(new ShaderModule()); + + NSError* err = nil; + NSString* source = [[NSString alloc] initWithBytes:desc.code + length:desc.codeSize + encoding:NSUTF8StringEncoding]; + module->m_mtlLibrary = + [m_mtlDevice newLibraryWithSource:source options:nil error: &err]; + if (err != nil || module->m_mtlLibrary == nil) + { + NSLog(@"RIVE ORE: makeShaderModule error: %@", + err ? err.localizedDescription : @""); + return nullptr; + } + + module->applyBindingMapFromDesc(desc); + return module; +} + +inline rcp ContextMetal::mtlMakePipeline(const PipelineDesc& desc, + std::string* outError) +{ + auto pipeline = rcp(new Pipeline(desc)); + + // --- Validate user-supplied layouts against shader binding map --- + { + std::string err; + if (!validateLayoutsAgainstBindingMap(pipeline->m_bindingMap, + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + &err) || + !validateColorRequiresFragment( + desc.colorCount, desc.fragmentModule != nullptr, &err)) + { + if (outError) + *outError = err; + else + setLastError("makePipeline: %s", err.c_str()); + return nullptr; + } + } + + // --- Render Pipeline State --- + MTLRenderPipelineDescriptor* rpd = + [[MTLRenderPipelineDescriptor alloc] init]; + + // Vertex function. + if (desc.vertexModule->m_mtlLibrary == nil) + { + if (outError) + *outError = "vertex shader library is nil"; + return nullptr; + } + rpd.vertexFunction = [desc.vertexModule->m_mtlLibrary + newFunctionWithName:@(desc.vertexEntryPoint)]; + if (rpd.vertexFunction == nil) + { + std::string msg = std::string("vertex entry point '") + + desc.vertexEntryPoint + + "' not found in shader library"; + NSLog(@"RIVE ORE: makePipeline: %s", msg.c_str()); + if (outError) + *outError = msg; + return nullptr; + } + // Fragment function. Depth-only pipelines leave it nil — Metal allows + // a vertex-only pipeline that writes only depth. + if (desc.fragmentModule != nullptr) + { + if (desc.fragmentModule->m_mtlLibrary == nil) + { + if (outError) + *outError = "fragment shader library is nil"; + return nullptr; + } + rpd.fragmentFunction = [desc.fragmentModule->m_mtlLibrary + newFunctionWithName:@(desc.fragmentEntryPoint)]; + if (rpd.fragmentFunction == nil) + { + std::string msg = std::string("fragment entry point '") + + desc.fragmentEntryPoint + + "' not found in shader library"; + NSLog(@"RIVE ORE: makePipeline: %s", msg.c_str()); + if (outError) + *outError = msg; + return nullptr; + } + } + + // Vertex descriptor. + if (desc.vertexBufferCount > 0) + { + MTLVertexDescriptor* vd = [[MTLVertexDescriptor alloc] init]; + for (uint32_t bufIdx = 0; bufIdx < desc.vertexBufferCount; ++bufIdx) + { + const auto& layout = desc.vertexBuffers[bufIdx]; + uint32_t mtlBufIdx = bufIdx + kMetalVertexBufferBase; + vd.layouts[mtlBufIdx].stride = layout.stride; + vd.layouts[mtlBufIdx].stepFunction = + layout.stepMode == VertexStepMode::instance + ? MTLVertexStepFunctionPerInstance + : MTLVertexStepFunctionPerVertex; + vd.layouts[mtlBufIdx].stepRate = 1; + + for (uint32_t attrIdx = 0; attrIdx < layout.attributeCount; + ++attrIdx) + { + const auto& attr = layout.attributes[attrIdx]; + vd.attributes[attr.shaderSlot].format = + oreVertexFormatToMTL(attr.format); + vd.attributes[attr.shaderSlot].offset = attr.offset; + vd.attributes[attr.shaderSlot].bufferIndex = mtlBufIdx; + } + } + rpd.vertexDescriptor = vd; + } + + // Color attachments. + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ct = desc.colorTargets[i]; + rpd.colorAttachments[i].pixelFormat = oreFormatToMTL(ct.format); + rpd.colorAttachments[i].writeMask = + oreColorWriteMaskToMTL(ct.writeMask); + + if (ct.blendEnabled) + { + rpd.colorAttachments[i].blendingEnabled = YES; + rpd.colorAttachments[i].sourceRGBBlendFactor = + oreBlendFactorToMTL(ct.blend.srcColor); + rpd.colorAttachments[i].destinationRGBBlendFactor = + oreBlendFactorToMTL(ct.blend.dstColor); + rpd.colorAttachments[i].rgbBlendOperation = + oreBlendOpToMTL(ct.blend.colorOp); + rpd.colorAttachments[i].sourceAlphaBlendFactor = + oreBlendFactorToMTL(ct.blend.srcAlpha); + rpd.colorAttachments[i].destinationAlphaBlendFactor = + oreBlendFactorToMTL(ct.blend.dstAlpha); + rpd.colorAttachments[i].alphaBlendOperation = + oreBlendOpToMTL(ct.blend.alphaOp); + } + } + + // Depth/stencil attachment format. The format sentinel + // (`rgba8unorm` = "no depth-stencil", per `ore_types.hpp`) is the + // single source of truth — the depthCompare/depthWrite/stencil flags + // configure how the attachment is *used*, not whether it exists. + // Pre-fix this gated on the ops, so a stencil prepass with + // `compare=always passOp=replace` (writes stencil but doesn't depth- + // test or stencil-test) was treated as "no depth-stencil" and the + // pipeline got `MTLPixelFormatInvalid`, mismatching the framebuffer + // attachment at draw time. + const bool hasDepthStencil = + desc.depthStencil.format != TextureFormat::rgba8unorm; + if (hasDepthStencil) + { + rpd.depthAttachmentPixelFormat = + oreFormatToMTL(desc.depthStencil.format); + if (desc.depthStencil.format == TextureFormat::depth24plusStencil8 || + desc.depthStencil.format == TextureFormat::depth32floatStencil8) + { + rpd.stencilAttachmentPixelFormat = + oreFormatToMTL(desc.depthStencil.format); + } + } + + rpd.rasterSampleCount = desc.sampleCount; + + if (desc.label) + { + rpd.label = @(desc.label); + } + + NSError* pipelineErr = nil; +#if RIVE_OBJC_EXCEPTIONS + @try + { + pipeline->m_mtlPipeline = + [m_mtlDevice newRenderPipelineStateWithDescriptor:rpd + error:&pipelineErr]; + } + @catch (NSException* e) + { + NSString* msg = e.reason ?: @"unknown Metal exception"; + NSLog(@"RIVE ORE: makePipeline exception: %@", msg); + if (outError) + *outError = msg.UTF8String; + return nullptr; + } +#else + pipeline->m_mtlPipeline = + [m_mtlDevice newRenderPipelineStateWithDescriptor:rpd + error:&pipelineErr]; +#endif + if (pipelineErr != nil || pipeline->m_mtlPipeline == nil) + { + NSString* msg = pipelineErr ? pipelineErr.localizedDescription + : @"nil pipeline, no error details"; + NSLog(@"RIVE ORE: makePipeline error: %@", msg); + if (outError) + *outError = msg.UTF8String; + return nullptr; + } + + // --- Depth/Stencil State --- + MTLDepthStencilDescriptor* dsd = [[MTLDepthStencilDescriptor alloc] init]; + dsd.depthCompareFunction = + oreCompareFunctionToMTL(desc.depthStencil.depthCompare); + dsd.depthWriteEnabled = desc.depthStencil.depthWriteEnabled; + + // Stencil front. + MTLStencilDescriptor* frontStencil = [[MTLStencilDescriptor alloc] init]; + frontStencil.stencilCompareFunction = + oreCompareFunctionToMTL(desc.stencilFront.compare); + frontStencil.stencilFailureOperation = + oreStencilOpToMTL(desc.stencilFront.failOp); + frontStencil.depthFailureOperation = + oreStencilOpToMTL(desc.stencilFront.depthFailOp); + frontStencil.depthStencilPassOperation = + oreStencilOpToMTL(desc.stencilFront.passOp); + frontStencil.readMask = desc.stencilReadMask; + frontStencil.writeMask = desc.stencilWriteMask; + dsd.frontFaceStencil = frontStencil; + + // Stencil back. + MTLStencilDescriptor* backStencil = [[MTLStencilDescriptor alloc] init]; + backStencil.stencilCompareFunction = + oreCompareFunctionToMTL(desc.stencilBack.compare); + backStencil.stencilFailureOperation = + oreStencilOpToMTL(desc.stencilBack.failOp); + backStencil.depthFailureOperation = + oreStencilOpToMTL(desc.stencilBack.depthFailOp); + backStencil.depthStencilPassOperation = + oreStencilOpToMTL(desc.stencilBack.passOp); + backStencil.readMask = desc.stencilReadMask; + backStencil.writeMask = desc.stencilWriteMask; + dsd.backFaceStencil = backStencil; + + pipeline->m_mtlDepthStencil = + [m_mtlDevice newDepthStencilStateWithDescriptor:dsd]; + + return pipeline; +} + +inline rcp ContextMetal::mtlMakeBindGroup(const BindGroupDesc& desc) +{ + if (desc.layout == nullptr) + { + setLastError("makeBindGroup: BindGroupDesc::layout is null"); + return nullptr; + } + BindGroupLayout* layout = desc.layout; + const uint32_t groupIndex = layout->groupIndex(); + if (groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroup: layout->groupIndex %u out of range", + groupIndex); + return nullptr; + } + + auto bg = rcp(new BindGroup()); + bg->m_context = this; + bg->m_layoutRef = ref_rcp(layout); + + // Resolve per-stage Metal slots from the layout's pre-resolved + // nativeSlotVS/FS fields. The layout was built via + // `makeLayoutFromShader` (helper) which queried the shader's + // BindingMap. Both stage slots may differ (Metal has independent + // VS/FS argument tables); kNativeSlotAbsent skips the per-stage emit + // at setBindGroup time. + auto lookupStages = [&](uint32_t binding, + BindingKind expected, + uint16_t* outVS, + uint16_t* outFS) -> bool { + const BindGroupLayoutEntry* le = layout->findEntry(binding); + if (le == nullptr) + { + setLastError("makeBindGroup: (group=%u, binding=%u) not declared " + "in BindGroupLayout", + groupIndex, + binding); + return false; + } + const bool kindOK = le->kind == expected || + ((le->kind == BindingKind::sampler || + le->kind == BindingKind::comparisonSampler) && + (expected == BindingKind::sampler || + expected == BindingKind::comparisonSampler)); + if (!kindOK) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout kind " + "mismatch", + groupIndex, + binding); + return false; + } + *outVS = (le->nativeSlotVS == BindGroupLayoutEntry::kNativeSlotAbsent) + ? BindingMap::kAbsent + : static_cast(le->nativeSlotVS); + *outFS = (le->nativeSlotFS == BindGroupLayoutEntry::kNativeSlotAbsent) + ? BindingMap::kAbsent + : static_cast(le->nativeSlotFS); + if (*outVS == BindingMap::kAbsent && *outFS == BindingMap::kAbsent) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout has no " + "resolved native slot — call makeLayoutFromShader", + groupIndex, + binding); + return false; + } + return true; + }; + + uint32_t nBufs = std::min(desc.uboCount, 8u); + for (uint32_t i = 0; i < nBufs; i++) + { + const auto& u = desc.ubos[i]; + bg->m_retainedBuffers.push_back(ref_rcp(u.buffer)); + BindGroup::MTLBufferBinding binding; + binding.buffer = u.buffer->m_mtlBuffer; + binding.offset = u.offset; + binding.binding = u.slot; + if (!lookupStages(u.slot, + BindingKind::uniformBuffer, + &binding.vsSlot, + &binding.fsSlot)) + continue; + binding.hasDynamicOffset = layout->hasDynamicOffset(u.slot); + if (binding.hasDynamicOffset) + bg->m_dynamicOffsetCount++; + bg->m_mtlBuffers.push_back(binding); + } + // Sort UBOs by WGSL @binding so dynamicOffsets[] is consumed in + // BindGroupLayout-entry order (WebGPU contract). + std::sort(bg->m_mtlBuffers.begin(), + bg->m_mtlBuffers.end(), + [](const BindGroup::MTLBufferBinding& a, + const BindGroup::MTLBufferBinding& b) { + return a.binding < b.binding; + }); + + uint32_t nTexs = std::min(desc.textureCount, 8u); + for (uint32_t i = 0; i < nTexs; i++) + { + const auto& t = desc.textures[i]; + bg->m_retainedViews.push_back(ref_rcp(t.view)); + BindGroup::MTLTextureBinding binding; + binding.texture = t.view->mtlTexture(); + if (!lookupStages(t.slot, + BindingKind::sampledTexture, + &binding.vsSlot, + &binding.fsSlot)) + continue; + bg->m_mtlTextures.push_back(binding); + } + + uint32_t nSamps = std::min(desc.samplerCount, 8u); + for (uint32_t i = 0; i < nSamps; i++) + { + const auto& s = desc.samplers[i]; + bg->m_retainedSamplers.push_back(ref_rcp(s.sampler)); + BindGroup::MTLSamplerBinding binding; + binding.sampler = s.sampler->m_mtlSampler; + if (!lookupStages( + s.slot, BindingKind::sampler, &binding.vsSlot, &binding.fsSlot)) + continue; + bg->m_mtlSamplers.push_back(binding); + } + + return bg; +} + +inline RenderPass ContextMetal::mtlBeginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + assert(m_mtlCommandBuffer != nil); + + MTLRenderPassDescriptor* rpd = + [MTLRenderPassDescriptor renderPassDescriptor]; + + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + id mtlTex = ca.view->mtlTexture(); + rpd.colorAttachments[i].texture = mtlTex; + bool hasView = (mtlTex != ca.view->texture()->mtlTexture()); + rpd.colorAttachments[i].level = hasView ? 0 : ca.view->baseMipLevel(); + rpd.colorAttachments[i].slice = hasView ? 0 : ca.view->baseLayer(); + rpd.colorAttachments[i].loadAction = oreLoadOpToMTL(ca.loadOp); + rpd.colorAttachments[i].storeAction = oreStoreOpToMTL(ca.storeOp); + rpd.colorAttachments[i].clearColor = MTLClearColorMake( + ca.clearColor.r, ca.clearColor.g, ca.clearColor.b, ca.clearColor.a); + + if (ca.resolveTarget) + { + id resolveTex = ca.resolveTarget->mtlTexture(); + rpd.colorAttachments[i].resolveTexture = resolveTex; + bool resolveHasView = + (resolveTex != ca.resolveTarget->texture()->mtlTexture()); + rpd.colorAttachments[i].resolveLevel = + resolveHasView ? 0 : ca.resolveTarget->baseMipLevel(); + rpd.colorAttachments[i].resolveSlice = + resolveHasView ? 0 : ca.resolveTarget->baseLayer(); + // Honor the user's storeOp on the MSAA buffer: when they + // ask for `Store` AND a resolve target, use Metal's + // combined `StoreAndMultisampleResolve` so the MSAA + // attachment survives for a subsequent load+resolve + // pattern. Pre-fix this unconditionally collapsed to + // `MultisampleResolve`, discarding the multisample buffer + // even when the script asked to keep it. + rpd.colorAttachments[i].storeAction = + (ca.storeOp == StoreOp::store) + ? MTLStoreActionStoreAndMultisampleResolve + : MTLStoreActionMultisampleResolve; + } + } + + if (desc.depthStencil.view) + { + id depthTex = desc.depthStencil.view->mtlTexture(); + bool depthHasView = + (depthTex != desc.depthStencil.view->texture()->mtlTexture()); + rpd.depthAttachment.texture = depthTex; + rpd.depthAttachment.level = + depthHasView ? 0 : desc.depthStencil.view->baseMipLevel(); + rpd.depthAttachment.slice = + depthHasView ? 0 : desc.depthStencil.view->baseLayer(); + rpd.depthAttachment.loadAction = + oreLoadOpToMTL(desc.depthStencil.depthLoadOp); + rpd.depthAttachment.storeAction = + oreStoreOpToMTL(desc.depthStencil.depthStoreOp); + rpd.depthAttachment.clearDepth = desc.depthStencil.depthClearValue; + + TextureFormat depthFmt = desc.depthStencil.view->texture()->format(); + if (depthFmt == TextureFormat::depth24plusStencil8 || + depthFmt == TextureFormat::depth32floatStencil8) + { + rpd.stencilAttachment.texture = depthTex; + rpd.stencilAttachment.level = + depthHasView ? 0 : desc.depthStencil.view->baseMipLevel(); + rpd.stencilAttachment.slice = + depthHasView ? 0 : desc.depthStencil.view->baseLayer(); + rpd.stencilAttachment.loadAction = + oreLoadOpToMTL(desc.depthStencil.stencilLoadOp); + rpd.stencilAttachment.storeAction = + oreStoreOpToMTL(desc.depthStencil.stencilStoreOp); + rpd.stencilAttachment.clearStencil = + desc.depthStencil.stencilClearValue; + } + } + + id encoder = + [m_mtlCommandBuffer renderCommandEncoderWithDescriptor:rpd]; + + if (encoder == nil) + { + NSLog(@"RIVE ORE: beginRenderPass: renderCommandEncoderWithDescriptor " + @"returned nil — render pass descriptor is invalid. " + @"colorCount=%u, hasDepth=%s", + desc.colorCount, + desc.depthStencil.view ? "yes" : "no"); + } + + if (desc.label) + { + encoder.label = @(desc.label); + } + + RenderPass pass; + pass.m_context = this; + pass.m_mtlEncoder = encoder; + pass.m_mtlCommandBuffer = m_mtlCommandBuffer; + pass.populateAttachmentMetadata(desc); + return pass; +} + +inline rcp ContextMetal::mtlWrapCanvasTexture( + gpu::RenderCanvas* canvas) +{ + assert(canvas != nullptr); + + auto* metalTarget = + static_cast(canvas->renderTarget()); + id mtlTexture = metalTarget->targetTexture(); + assert(mtlTexture != nil); + + uint32_t w = canvas->width(); + uint32_t h = canvas->height(); + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = mtlFormatToOre(mtlTexture.pixelFormat); + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = true; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_mtlTexture = mtlTexture; + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_mtlTextureView = mtlTexture; + return view; +} + +// ============================================================================ +// ContextMetal +// ============================================================================ + +ContextMetal::~ContextMetal() +{ + m_mtlCommandBuffer = nil; + m_mtlQueue = nil; + m_mtlDevice = nil; +} + +std::unique_ptr ContextMetal::Make(id device, + id queue) +{ + auto ctx = std::unique_ptr(new ContextMetal()); + ctx->m_mtlDevice = device; + ctx->m_mtlQueue = queue; + ctx->mtlPopulateFeatures(device); + return ctx; +} + +void ContextMetal::beginFrame() +{ + m_mtlCommandBuffer = [m_mtlQueue commandBuffer]; +} + +void ContextMetal::waitForGPU() +{ +#if defined(ORE_BACKEND_METAL) + if (m_mtlCommandBuffer) + [m_mtlCommandBuffer waitUntilCompleted]; +#endif +} + +void ContextMetal::endFrame() +{ + if (m_mtlCommandBuffer) + { + // Capture deferred BindGroups in a `__block` vector that the + // completion handler clears once the GPU is done with the + // command buffer. Pre-fix the next `beginFrame()` cleared + // `m_deferredBindGroups` immediately, which freed the + // underlying `id` resources while the GPU was still + // reading them — surfaces under iOS thermal-throttle delays + // and Apple-Silicon shared-memory races. Refcount drops happen + // on a Metal-internal thread; safe because each resource's + // destructor is `delete this` against ARC-managed handles. + if (!m_deferredBindGroups.empty()) + { + __block std::vector> deferred = + std::move(m_deferredBindGroups); + m_deferredBindGroups.clear(); + [m_mtlCommandBuffer addCompletedHandler:^(id) { + deferred.clear(); + }]; + } + [m_mtlCommandBuffer commit]; + m_mtlCommandBuffer = nil; + } +} + +// ============================================================================ +// makeBuffer +// ============================================================================ + +rcp ContextMetal::makeBuffer(const BufferDesc& desc) +{ + return mtlMakeBuffer(desc); +} + +// ============================================================================ +// makeTexture +// ============================================================================ + +rcp ContextMetal::makeTexture(const TextureDesc& desc) +{ + return mtlMakeTexture(desc); +} + +// ============================================================================ +// makeTextureView +// ============================================================================ + +rcp ContextMetal::makeTextureView(const TextureViewDesc& desc) +{ + return mtlMakeTextureView(desc); +} + +// ============================================================================ +// makeSampler +// ============================================================================ + +rcp ContextMetal::makeSampler(const SamplerDesc& desc) +{ + return mtlMakeSampler(desc); +} + +// ============================================================================ +// makeShaderModule +// ============================================================================ + +rcp ContextMetal::makeShaderModule(const ShaderModuleDesc& desc) +{ + return mtlMakeShaderModule(desc); +} + +// ============================================================================ +// makePipeline +// ============================================================================ + +rcp ContextMetal::makePipeline(const PipelineDesc& desc, + std::string* outError) +{ + return mtlMakePipeline(desc, outError); +} + +// ============================================================================ +// makeBindGroup +// ============================================================================ + +rcp ContextMetal::makeBindGroup(const BindGroupDesc& desc) +{ + return mtlMakeBindGroup(desc); +} + +// ============================================================================ +// makeBindGroupLayout +// ============================================================================ + +rcp ContextMetal::makeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + if (desc.groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroupLayout: groupIndex %u out of range [0, %u)", + desc.groupIndex, + kMaxBindGroups); + return nullptr; + } + auto layout = rcp(new BindGroupLayout()); + layout->m_context = this; + layout->m_groupIndex = desc.groupIndex; + layout->m_entries.reserve(desc.entryCount); + for (uint32_t i = 0; i < desc.entryCount; ++i) + layout->m_entries.push_back(desc.entries[i]); + // Metal has no native layout object — entries-only suffices. + return layout; +} + +// ============================================================================ +// beginRenderPass +// ============================================================================ + +RenderPass ContextMetal::beginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + finishActiveRenderPass(); + return mtlBeginRenderPass(desc, outError); +} + +// ============================================================================ +// wrapCanvasTexture +// ============================================================================ + +rcp ContextMetal::wrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + return mtlWrapCanvasTexture(canvas); +} + +rcp ContextMetal::wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + if (!gpuTex) + return nullptr; + + id mtlTex = (__bridge id)gpuTex->nativeHandle(); + if (!mtlTex) + return nullptr; + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = mtlFormatToOre(mtlTex.pixelFormat); + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = false; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_mtlTexture = mtlTex; // Borrow — caller owns via RenderImage. + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_mtlTextureView = mtlTex; + return view; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal.mm new file mode 100644 index 000000000..4af28d7e1 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal.mm @@ -0,0 +1,19 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void Pipeline::onRefCntReachedZero() const { delete this; } + +void BindGroupLayout::onRefCntReachedZero() const { delete this; } + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal_gl.mm new file mode 100644 index 000000000..8b1c8425d --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_pipeline_metal_gl.mm @@ -0,0 +1,30 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL Pipeline implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" + +namespace rive::ore +{ + +void Pipeline::onRefCntReachedZero() const +{ + if (m_glProgram != 0) + { + glDeleteProgram(m_glProgram); + } + delete this; +} + +void BindGroupLayout::onRefCntReachedZero() const { delete this; } + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal.mm new file mode 100644 index 000000000..300f98170 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal.mm @@ -0,0 +1,404 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_context_metal.hpp" // for RenderPass inline bodies +#include "rive/rive_types.hpp" + +#import + +namespace rive::ore +{ + +static MTLPrimitiveType orePrimitiveTopologyToMTL(PrimitiveTopology topo) +{ + switch (topo) + { + case PrimitiveTopology::pointList: + return MTLPrimitiveTypePoint; + case PrimitiveTopology::lineList: + return MTLPrimitiveTypeLine; + case PrimitiveTopology::lineStrip: + return MTLPrimitiveTypeLineStrip; + case PrimitiveTopology::triangleList: + return MTLPrimitiveTypeTriangle; + case PrimitiveTopology::triangleStrip: + return MTLPrimitiveTypeTriangleStrip; + } + RIVE_UNREACHABLE(); +} + +static MTLIndexType oreIndexFormatToMTL(IndexFormat format) +{ + switch (format) + { + case IndexFormat::uint16: + return MTLIndexTypeUInt16; + case IndexFormat::uint32: + return MTLIndexTypeUInt32; + case IndexFormat::none: + break; + } + RIVE_UNREACHABLE(); +} + +static MTLCullMode oreCullModeToMTL(CullMode mode) +{ + switch (mode) + { + case CullMode::none: + return MTLCullModeNone; + case CullMode::front: + return MTLCullModeFront; + case CullMode::back: + return MTLCullModeBack; + } + RIVE_UNREACHABLE(); +} + +static MTLWinding oreWindingToMTL(FaceWinding winding) +{ + switch (winding) + { + case FaceWinding::clockwise: + return MTLWindingClockwise; + case FaceWinding::counterClockwise: + return MTLWindingCounterClockwise; + } + RIVE_UNREACHABLE(); +} + +// Must match kMetalVertexBufferBase in ore_context_metal.mm — vertex buffers +// are bound at slots [kMetalVertexBufferBase, ...) to avoid colliding with +// uniform buffers mapped to the low buffer indices ([[buffer(0)]] etc). +static constexpr uint32_t kMetalVertexBufferBase = 16; + +// ============================================================================ +// Metal implementation helpers (inline) +// Shared between metal-only and metal+gl builds. +// ============================================================================ + +inline void RenderPass::mtlSetPipeline(Pipeline* pipeline) +{ + [m_mtlEncoder setRenderPipelineState:pipeline->m_mtlPipeline]; + [m_mtlEncoder setDepthStencilState:pipeline->m_mtlDepthStencil]; + + const auto& desc = pipeline->desc(); + [m_mtlEncoder setCullMode:oreCullModeToMTL(desc.cullMode)]; + [m_mtlEncoder setFrontFacingWinding:oreWindingToMTL(desc.winding)]; + m_mtlPrimitiveType = orePrimitiveTopologyToMTL(desc.topology); + + if (desc.depthStencil.depthBias != 0 || + desc.depthStencil.depthBiasSlopeScale != 0.0f) + { + [m_mtlEncoder setDepthBias:(float)desc.depthStencil.depthBias + slopeScale:desc.depthStencil.depthBiasSlopeScale + clamp:desc.depthStencil.depthBiasClamp]; + } +} + +inline void RenderPass::mtlSetVertexBuffer(uint32_t slot, + Buffer* buffer, + uint32_t offset) +{ + [m_mtlEncoder setVertexBuffer:buffer->m_mtlBuffer + offset:offset + atIndex:slot + kMetalVertexBufferBase]; +} + +inline void RenderPass::mtlSetIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + m_mtlIndexBuffer = buffer->m_mtlBuffer; + m_mtlIndexType = oreIndexFormatToMTL(format); + m_mtlIndexBufferOffset = offset; +} + +inline void RenderPass::mtlSetBindGroup(BindGroup* bg, + uint32_t groupIndex, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + (void)groupIndex; + // m_mtlBuffers is sorted by WGSL `@binding` ascending at makeBindGroup + // time, so `dynamicOffsets[i]` here pairs with the i-th dynamic UBO + // in BindGroupLayout-entry order — matching WebGPU semantics + // independently of the caller's `desc.ubos[]` order. + uint32_t dynIdx = 0; + for (auto& b : bg->m_mtlBuffers) + { + uint32_t offset = b.offset; + if (b.hasDynamicOffset && dynIdx < dynamicOffsetCount) + offset += dynamicOffsets[dynIdx++]; + // Per-stage emit: skip the stage whose slot is kAbsent so we + // don't clobber another resource's slot in that stage's argument + // table. + if (b.vsSlot != BindingMap::kAbsent) + [m_mtlEncoder setVertexBuffer:b.buffer + offset:offset + atIndex:b.vsSlot]; + if (b.fsSlot != BindingMap::kAbsent) + [m_mtlEncoder setFragmentBuffer:b.buffer + offset:offset + atIndex:b.fsSlot]; + } + for (auto& t : bg->m_mtlTextures) + { + if (t.vsSlot != BindingMap::kAbsent) + [m_mtlEncoder setVertexTexture:t.texture atIndex:t.vsSlot]; + if (t.fsSlot != BindingMap::kAbsent) + [m_mtlEncoder setFragmentTexture:t.texture atIndex:t.fsSlot]; + } + for (auto& s : bg->m_mtlSamplers) + { + if (s.vsSlot != BindingMap::kAbsent) + [m_mtlEncoder setVertexSamplerState:s.sampler atIndex:s.vsSlot]; + if (s.fsSlot != BindingMap::kAbsent) + [m_mtlEncoder setFragmentSamplerState:s.sampler atIndex:s.fsSlot]; + } +} + +inline void RenderPass::mtlSetViewport( + float x, float y, float width, float height, float minDepth, float maxDepth) +{ + MTLViewport vp = { + .originX = (double)x, + .originY = (double)y, + .width = (double)width, + .height = (double)height, + .znear = (double)minDepth, + .zfar = (double)maxDepth, + }; + [m_mtlEncoder setViewport:vp]; +} + +inline void RenderPass::mtlSetScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + MTLScissorRect rect = { + .x = x, + .y = y, + .width = width, + .height = height, + }; + [m_mtlEncoder setScissorRect:rect]; +} + +inline void RenderPass::mtlSetStencilRef(uint32_t ref) +{ + [m_mtlEncoder setStencilReferenceValue:ref]; +} + +inline void RenderPass::mtlSetBlendColor(float r, float g, float b, float a) +{ + [m_mtlEncoder setBlendColorRed:r green:g blue:b alpha:a]; +} + +inline void RenderPass::mtlDraw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + [m_mtlEncoder drawPrimitives:m_mtlPrimitiveType + vertexStart:firstVertex + vertexCount:vertexCount + instanceCount:instanceCount + baseInstance:firstInstance]; +} + +inline void RenderPass::mtlDrawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + assert(m_mtlIndexBuffer != nil && + "Must call setIndexBuffer before drawIndexed"); + + uint32_t indexSize = (m_mtlIndexType == MTLIndexTypeUInt32) + ? sizeof(uint32_t) + : sizeof(uint16_t); + NSUInteger indexBufferOffset = + m_mtlIndexBufferOffset + firstIndex * indexSize; + + [m_mtlEncoder drawIndexedPrimitives:m_mtlPrimitiveType + indexCount:indexCount + indexType:m_mtlIndexType + indexBuffer:m_mtlIndexBuffer + indexBufferOffset:indexBufferOffset + instanceCount:instanceCount + baseVertex:baseVertex + baseInstance:firstInstance]; +} + +inline void RenderPass::mtlFinish() +{ + [m_mtlEncoder endEncoding]; + m_mtlEncoder = nil; +} + +// ============================================================================ +// RenderPass +// ============================================================================ + +// When both Metal and GL are compiled (macOS), ore_render_pass_metal_gl.mm +// provides all RenderPass method bodies with runtime dispatch. This file +// only contributes the static helper functions in that case. +#if !defined(ORE_BACKEND_GL) + +RenderPass::~RenderPass() +{ + if (!m_finished && m_mtlEncoder != nil) + { + finish(); + } +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + m_mtlEncoder(other.m_mtlEncoder), + m_mtlCommandBuffer(other.m_mtlCommandBuffer), + m_mtlIndexBuffer(other.m_mtlIndexBuffer), + m_mtlIndexType(other.m_mtlIndexType), + m_mtlIndexBufferOffset(other.m_mtlIndexBufferOffset), + m_mtlPrimitiveType(other.m_mtlPrimitiveType) +{ + moveCrossBackendFieldsFrom(other); + other.m_mtlEncoder = nil; + other.m_mtlCommandBuffer = nil; + other.m_mtlIndexBuffer = nil; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && m_mtlEncoder != nil) + { + finish(); + } + moveCrossBackendFieldsFrom(other); + m_mtlEncoder = other.m_mtlEncoder; + m_mtlCommandBuffer = other.m_mtlCommandBuffer; + m_mtlIndexBuffer = other.m_mtlIndexBuffer; + m_mtlIndexType = other.m_mtlIndexType; + m_mtlIndexBufferOffset = other.m_mtlIndexBufferOffset; + m_mtlPrimitiveType = other.m_mtlPrimitiveType; + other.m_mtlEncoder = nil; + other.m_mtlCommandBuffer = nil; + other.m_mtlIndexBuffer = nil; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_mtlEncoder != nil); +} + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + mtlSetPipeline(pipeline); +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + mtlSetVertexBuffer(slot, buffer, offset); +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + mtlSetIndexBuffer(buffer, format, offset); +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + m_boundGroups[groupIndex] = ref_rcp(bg); + mtlSetBindGroup(bg, groupIndex, dynamicOffsets, dynamicOffsetCount); +} + +void RenderPass::setViewport( + float x, float y, float width, float height, float minDepth, float maxDepth) +{ + validate(); + mtlSetViewport(x, y, width, height, minDepth, maxDepth); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + mtlSetScissorRect(x, y, width, height); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + mtlSetStencilRef(ref); +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + mtlSetBlendColor(r, g, b, a); +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + mtlDraw(vertexCount, instanceCount, firstVertex, firstInstance); +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + mtlDrawIndexed( + indexCount, instanceCount, firstIndex, baseVertex, firstInstance); +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + if (m_mtlEncoder != nil) + { + mtlFinish(); + } + // Release bound BindGroup refs. + for (auto& bg : m_boundGroups) + bg.reset(); +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal_gl.mm new file mode 100644 index 000000000..1c2ca8cee --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_render_pass_metal_gl.mm @@ -0,0 +1,537 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL RenderPass implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. +// Provides all RenderPass method definitions with runtime dispatch: +// passes initialized via the Metal context path (m_mtlEncoder != nil) use +// Metal; passes initialized via the GL context path (m_context != nullptr) +// use GL. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +// Pull in Metal static helpers (orePrimitiveTopologyToMTL, etc.). +// The !defined(ORE_BACKEND_GL) guard in ore_render_pass_metal.mm excludes +// RenderPass method bodies, so we get only the static helper functions. +#include "ore_render_pass_metal.mm" + +// Pull in GL static helpers (oreTopologyToGL, oreBlendFactorToGL, etc.). +// The !defined(ORE_BACKEND_METAL) guard in ore_render_pass_gl.cpp excludes +// RenderPass method bodies, so we get only the static helper functions. +#include "../gl/ore_render_pass_gl.cpp" + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" + +namespace rive::ore +{ + +RenderPass::~RenderPass() +{ + if (!m_finished) + { + if (m_mtlEncoder != nil || m_context != nullptr) + finish(); + } +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + // Metal members + m_mtlEncoder(other.m_mtlEncoder), + m_mtlCommandBuffer(other.m_mtlCommandBuffer), + m_mtlIndexBuffer(other.m_mtlIndexBuffer), + m_mtlIndexType(other.m_mtlIndexType), + m_mtlIndexBufferOffset(other.m_mtlIndexBufferOffset), + m_mtlPrimitiveType(other.m_mtlPrimitiveType), + // GL members + m_glFBO(other.m_glFBO), + m_glVAO(other.m_glVAO), + m_ownsFBO(other.m_ownsFBO), + m_ownsVAO(other.m_ownsVAO), + m_currentPipeline(std::move(other.m_currentPipeline)), + m_viewportWidth(other.m_viewportWidth), + m_viewportHeight(other.m_viewportHeight), + m_maxSamplerSlot(other.m_maxSamplerSlot), + m_maxAttribSlot(other.m_maxAttribSlot), + m_usedSamplers(other.m_usedSamplers), + m_usedAttribs(other.m_usedAttribs) +{ + moveCrossBackendFieldsFrom(other); + other.m_mtlEncoder = nil; + other.m_mtlCommandBuffer = nil; + other.m_mtlIndexBuffer = nil; + other.m_ownsFBO = false; + other.m_ownsVAO = false; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && (m_mtlEncoder != nil || m_context != nullptr)) + finish(); + moveCrossBackendFieldsFrom(other); + m_mtlEncoder = other.m_mtlEncoder; + m_mtlCommandBuffer = other.m_mtlCommandBuffer; + m_mtlIndexBuffer = other.m_mtlIndexBuffer; + m_mtlIndexType = other.m_mtlIndexType; + m_mtlIndexBufferOffset = other.m_mtlIndexBufferOffset; + m_mtlPrimitiveType = other.m_mtlPrimitiveType; + m_glFBO = other.m_glFBO; + m_glVAO = other.m_glVAO; + m_ownsFBO = other.m_ownsFBO; + m_ownsVAO = other.m_ownsVAO; + m_currentPipeline = std::move(other.m_currentPipeline); + m_viewportWidth = other.m_viewportWidth; + m_viewportHeight = other.m_viewportHeight; + m_maxSamplerSlot = other.m_maxSamplerSlot; + m_maxAttribSlot = other.m_maxAttribSlot; + m_usedSamplers = other.m_usedSamplers; + m_usedAttribs = other.m_usedAttribs; + other.m_mtlEncoder = nil; + other.m_mtlCommandBuffer = nil; + other.m_mtlIndexBuffer = nil; + other.m_ownsFBO = false; + other.m_ownsVAO = false; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_mtlEncoder != nil || m_context != nullptr); +} + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + if (m_mtlEncoder != nil) + { + mtlSetPipeline(pipeline); + return; + } + + // GL path. + m_currentPipeline = ref_rcp(pipeline); + const auto& desc = pipeline->desc(); + glUseProgram(pipeline->m_glProgram); + + if (desc.cullMode == CullMode::none) + { + glDisable(GL_CULL_FACE); + } + else + { + glEnable(GL_CULL_FACE); + glCullFace(desc.cullMode == CullMode::front ? GL_FRONT : GL_BACK); + } + + glFrontFace(desc.winding == FaceWinding::counterClockwise ? GL_CCW : GL_CW); + + if (desc.depthStencil.depthCompare != CompareFunction::always || + desc.depthStencil.depthWriteEnabled) + { + glEnable(GL_DEPTH_TEST); + glDepthFunc(oreCompareFunctionToGL(desc.depthStencil.depthCompare)); + glDepthMask(desc.depthStencil.depthWriteEnabled ? GL_TRUE : GL_FALSE); + } + else + { + glDisable(GL_DEPTH_TEST); + } + + if (desc.depthStencil.depthBias != 0 || + desc.depthStencil.depthBiasSlopeScale != 0.0f) + { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(desc.depthStencil.depthBiasSlopeScale, + static_cast(desc.depthStencil.depthBias)); + } + else + { + glDisable(GL_POLYGON_OFFSET_FILL); + } + + bool hasStencil = (desc.stencilFront.compare != CompareFunction::always || + desc.stencilFront.failOp != StencilOp::keep || + desc.stencilFront.depthFailOp != StencilOp::keep || + desc.stencilFront.passOp != StencilOp::keep || + desc.stencilBack.compare != CompareFunction::always || + desc.stencilBack.failOp != StencilOp::keep || + desc.stencilBack.depthFailOp != StencilOp::keep || + desc.stencilBack.passOp != StencilOp::keep); + + if (hasStencil) + { + glEnable(GL_STENCIL_TEST); + glStencilMaskSeparate(GL_FRONT, desc.stencilWriteMask); + glStencilMaskSeparate(GL_BACK, desc.stencilWriteMask); + glStencilFuncSeparate(GL_FRONT, + oreCompareFunctionToGL(desc.stencilFront.compare), + 0, + desc.stencilReadMask); + glStencilFuncSeparate(GL_BACK, + oreCompareFunctionToGL(desc.stencilBack.compare), + 0, + desc.stencilReadMask); + glStencilOpSeparate(GL_FRONT, + oreStencilOpToGL(desc.stencilFront.failOp), + oreStencilOpToGL(desc.stencilFront.depthFailOp), + oreStencilOpToGL(desc.stencilFront.passOp)); + glStencilOpSeparate(GL_BACK, + oreStencilOpToGL(desc.stencilBack.failOp), + oreStencilOpToGL(desc.stencilBack.depthFailOp), + oreStencilOpToGL(desc.stencilBack.passOp)); + } + else + { + glDisable(GL_STENCIL_TEST); + } + + if (desc.colorCount > 0 && desc.colorTargets[0].blendEnabled) + { + glEnable(GL_BLEND); + const auto& b = desc.colorTargets[0].blend; + glBlendFuncSeparate(oreBlendFactorToGL(b.srcColor), + oreBlendFactorToGL(b.dstColor), + oreBlendFactorToGL(b.srcAlpha), + oreBlendFactorToGL(b.dstAlpha)); + glBlendEquationSeparate(oreBlendOpToGL(b.colorOp), + oreBlendOpToGL(b.alphaOp)); + } + else + { + glDisable(GL_BLEND); + } + + if (desc.colorCount > 0) + { + auto mask = desc.colorTargets[0].writeMask; + glColorMask((mask & ColorWriteMask::red) != ColorWriteMask::none, + (mask & ColorWriteMask::green) != ColorWriteMask::none, + (mask & ColorWriteMask::blue) != ColorWriteMask::none, + (mask & ColorWriteMask::alpha) != ColorWriteMask::none); + } +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlSetVertexBuffer(slot, buffer, offset); + return; + } + + // GL path. + assert(m_currentPipeline != nullptr && "setPipeline must be called first"); + assert(slot < m_currentPipeline->desc().vertexBufferCount); + + const auto& layout = m_currentPipeline->desc().vertexBuffers[slot]; + glBindBuffer(GL_ARRAY_BUFFER, buffer->m_glBuffer); + + for (uint32_t i = 0; i < layout.attributeCount; ++i) + { + const auto& attr = layout.attributes[i]; + GLVertexInfo info = oreVertexFormatToGL(attr.format); + glEnableVertexAttribArray(attr.shaderSlot); + + bool isIntType = + (info.type == GL_UNSIGNED_INT || info.type == GL_INT || + info.type == GL_UNSIGNED_BYTE || info.type == GL_BYTE || + info.type == GL_UNSIGNED_SHORT || info.type == GL_SHORT) && + !info.normalized; + + if (isIntType) + { + glVertexAttribIPointer( + attr.shaderSlot, + info.count, + info.type, + layout.stride, + reinterpret_cast( + static_cast(attr.offset + offset))); + } + else + { + glVertexAttribPointer( + attr.shaderSlot, + info.count, + info.type, + info.normalized, + layout.stride, + reinterpret_cast( + static_cast(attr.offset + offset))); + } + + if (layout.stepMode == VertexStepMode::instance) + glVertexAttribDivisor(attr.shaderSlot, 1); + else + glVertexAttribDivisor(attr.shaderSlot, 0); + + if (!m_usedAttribs || attr.shaderSlot > m_maxAttribSlot) + m_maxAttribSlot = attr.shaderSlot; + m_usedAttribs = true; + } +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlSetIndexBuffer(buffer, format, offset); + return; + } + + // GL path. + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->m_glBuffer); + m_glIndexFormat = format; + (void)offset; +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + m_boundGroups[groupIndex] = ref_rcp(bg); + + if (m_mtlEncoder != nil) + { + mtlSetBindGroup(bg, groupIndex, dynamicOffsets, dynamicOffsetCount); + return; + } + + // GL path. + (void)groupIndex; + uint32_t dynIdx = 0; + for (auto& b : bg->m_glUBOs) + { + uint32_t offset = b.offset; + if (b.hasDynamicOffset && dynIdx < dynamicOffsetCount) + offset += dynamicOffsets[dynIdx++]; + glBindBufferRange(GL_UNIFORM_BUFFER, b.slot, b.buffer, offset, b.size); + } + for (auto& t : bg->m_glTextures) + { + glActiveTexture(GL_TEXTURE0 + t.slot); + glBindTexture(t.target, t.texture); + if (!m_usedSamplers || t.slot > m_maxSamplerSlot) + m_maxSamplerSlot = t.slot; + m_usedSamplers = true; + } + for (auto& s : bg->m_glSamplers) + { + glBindSampler(s.slot, s.sampler); + } +} + +void RenderPass::setViewport( + float x, float y, float width, float height, float minDepth, float maxDepth) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlSetViewport(x, y, width, height, minDepth, maxDepth); + return; + } + + // GL path. + m_viewportWidth = static_cast(width); + m_viewportHeight = static_cast(height); + glViewport(static_cast(x), + static_cast(y), + static_cast(width), + static_cast(height)); + glDepthRangef(minDepth, maxDepth); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlSetScissorRect(x, y, width, height); + return; + } + + // GL path. + glEnable(GL_SCISSOR_TEST); + glScissor(x, y, width, height); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlSetStencilRef(ref); + return; + } + + // GL path. + if (m_currentPipeline) + { + const auto& desc = m_currentPipeline->desc(); + glStencilFuncSeparate(GL_FRONT, + oreCompareFunctionToGL(desc.stencilFront.compare), + ref, + desc.stencilReadMask); + glStencilFuncSeparate(GL_BACK, + oreCompareFunctionToGL(desc.stencilBack.compare), + ref, + desc.stencilReadMask); + } +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlSetBlendColor(r, g, b, a); + return; + } + + // GL path. + glBlendColor(r, g, b, a); +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlDraw(vertexCount, instanceCount, firstVertex, firstInstance); + return; + } + + // GL path. + assert(m_currentPipeline != nullptr); + GLenum mode = oreTopologyToGL(m_currentPipeline->desc().topology); + (void)firstInstance; + if (instanceCount > 1) + glDrawArraysInstanced(mode, firstVertex, vertexCount, instanceCount); + else + glDrawArrays(mode, firstVertex, vertexCount); +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + if (m_mtlEncoder != nil) + { + mtlDrawIndexed( + indexCount, instanceCount, firstIndex, baseVertex, firstInstance); + return; + } + + // GL path. + assert(m_currentPipeline != nullptr); + GLenum mode = oreTopologyToGL(m_currentPipeline->desc().topology); + GLenum indexType = (m_glIndexFormat == IndexFormat::uint32) + ? GL_UNSIGNED_INT + : GL_UNSIGNED_SHORT; + uint32_t indexSize = + (indexType == GL_UNSIGNED_INT) ? sizeof(uint32_t) : sizeof(uint16_t); + const void* offset = reinterpret_cast( + static_cast(firstIndex * indexSize)); + (void)baseVertex; + (void)firstInstance; + if (instanceCount > 1) + glDrawElementsInstanced( + mode, indexCount, indexType, offset, instanceCount); + else + glDrawElements(mode, indexCount, indexType, offset); +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + + // Release bound BindGroup refs. + for (auto& bg : m_boundGroups) + bg.reset(); + + if (m_mtlEncoder != nil) + { + mtlFinish(); + return; + } + + // GL path. + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_POLYGON_OFFSET_FILL); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + if (m_usedSamplers) + { + for (uint32_t i = 0; i <= m_maxSamplerSlot; ++i) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindSampler(i, 0); + } + glActiveTexture(GL_TEXTURE0); + } + + if (m_usedAttribs) + { + for (uint32_t i = 0; i <= m_maxAttribSlot; ++i) + glDisableVertexAttribArray(i); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + // NOTE: GL_ELEMENT_ARRAY_BUFFER is VAO state — do NOT unbind it here. + // The per-pass VAO deletion below handles cleanup. Unbinding it could + // corrupt the host renderer's VAO on some WebGL2 implementations. + + if (m_ownsVAO && m_glVAO != 0) + { + glDeleteVertexArrays(1, &m_glVAO); + m_glVAO = 0; + } + + if (m_ownsFBO && m_glFBO != 0) + { + glDeleteFramebuffers(1, &m_glFBO); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + m_context = nullptr; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal.mm new file mode 100644 index 000000000..2a40b5718 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal.mm @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_sampler.hpp" + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void Sampler::onRefCntReachedZero() const { delete this; } + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal_gl.mm new file mode 100644 index 000000000..dd5411005 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_sampler_metal_gl.mm @@ -0,0 +1,28 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL Sampler implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" + +namespace rive::ore +{ + +void Sampler::onRefCntReachedZero() const +{ + if (m_glSampler != 0) + { + GLuint samp = m_glSampler; + glDeleteSamplers(1, &samp); + } + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal.mm new file mode 100644 index 000000000..8778b1a09 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal.mm @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void ShaderModule::onRefCntReachedZero() const { delete this; } + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal_gl.mm new file mode 100644 index 000000000..53b6aeca3 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_shader_module_metal_gl.mm @@ -0,0 +1,27 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL ShaderModule implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +void ShaderModule::onRefCntReachedZero() const +{ + if (m_glShader != 0) + { + glDeleteShader(m_glShader); + } + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_texture_metal.mm b/thirdparty/rive_renderer/source/ore/metal/ore_texture_metal.mm new file mode 100644 index 000000000..8fe293d2c --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_texture_metal.mm @@ -0,0 +1,48 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/rive_types.hpp" + +#import + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void Texture::upload(const TextureDataDesc& data) +{ + assert(m_mtlTexture != nil); + assert(data.data != nullptr); + + MTLRegion region = MTLRegionMake3D( + data.x, data.y, data.z, data.width, data.height, data.depth); + + // Apple's `replaceRegion:` docs require `bytesPerImage = 0` for + // non-array 2D textures (Metal API Validation aborts on any other + // value). For texture3D / array2D / cubeArray the value is the + // per-slice stride. Pre-fix this passed + // `bytesPerRow * rowsPerImage` unconditionally, which trips the + // validator on every 2D upload. + const NSUInteger mtlBytesPerImage = + (m_type == TextureType::texture3D || m_type == TextureType::array2D) + ? static_cast(data.bytesPerRow) * data.rowsPerImage + : 0; + + [m_mtlTexture replaceRegion:region + mipmapLevel:data.mipLevel + slice:data.layer + withBytes:data.data + bytesPerRow:data.bytesPerRow + bytesPerImage:mtlBytesPerImage]; +} + +void Texture::onRefCntReachedZero() const { delete this; } + +void TextureView::onRefCntReachedZero() const { delete this; } + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/metal/ore_texture_metal_gl.mm b/thirdparty/rive_renderer/source/ore/metal/ore_texture_metal_gl.mm new file mode 100644 index 000000000..7c0ac6cd6 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/metal/ore_texture_metal_gl.mm @@ -0,0 +1,113 @@ +/* + * Copyright 2025 Rive + */ + +// Combined Metal + GL Texture implementation for macOS. +// Compiled when both ORE_BACKEND_METAL and ORE_BACKEND_GL are active. + +#if defined(ORE_BACKEND_METAL) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/rive_types.hpp" + +#import + +// Pull in GL static helpers (format conversion functions). +// The #ifndef ORE_BACKEND_METAL guard in ore_texture_gl.cpp excludes +// class method bodies, so we get only the helper functions. +#include "../gl/ore_texture_gl.cpp" + +namespace rive::ore +{ + +void Texture::upload(const TextureDataDesc& data) +{ + assert(data.data != nullptr); + + if (m_glTexture != 0) + { + glBindTexture(m_glTarget, m_glTexture); + + GLenum internalFmt = oreFormatToGLInternal(m_format); + GLenum format = oreFormatToGLFormat(m_format); + GLenum type = oreFormatToGLType(m_format); + (void)internalFmt; + + if (m_glTarget == GL_TEXTURE_3D || m_glTarget == GL_TEXTURE_2D_ARRAY) + { + glTexSubImage3D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.layer, + data.width, + data.height, + data.depth, + format, + type, + data.data); + } + else if (m_glTarget == GL_TEXTURE_CUBE_MAP) + { + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + data.layer, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + format, + type, + data.data); + } + else + { + glTexSubImage2D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + format, + type, + data.data); + } + + glBindTexture(m_glTarget, 0); + return; + } + + assert(m_mtlTexture != nil); + MTLRegion region = MTLRegionMake3D( + data.x, data.y, data.z, data.width, data.height, data.depth); + [m_mtlTexture replaceRegion:region + mipmapLevel:data.mipLevel + slice:data.layer + withBytes:data.data + bytesPerRow:data.bytesPerRow + bytesPerImage:data.bytesPerRow * data.rowsPerImage]; +} + +void Texture::onRefCntReachedZero() const +{ + if (m_glTexture != 0 && m_glOwnsTexture) + { + GLuint tex = m_glTexture; + glDeleteTextures(1, &tex); + } + delete this; +} + +void TextureView::onRefCntReachedZero() const +{ + if (m_glTextureView != 0) + { + GLuint tex = m_glTextureView; + glDeleteTextures(1, &tex); + } + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_METAL && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/ore_bind_group_layout.cpp b/thirdparty/rive_renderer/source/ore/ore_bind_group_layout.cpp new file mode 100644 index 000000000..4a7a24b09 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/ore_bind_group_layout.cpp @@ -0,0 +1,244 @@ +/* + * Copyright 2026 Rive + */ + +#include "rive/renderer/ore/ore_bind_group_layout.hpp" +#include "rive/renderer/ore/ore_binding_map.hpp" + +#include + +namespace rive::ore +{ + +const BindGroupLayoutEntry* BindGroupLayout::findEntry(uint32_t binding) const +{ + for (const auto& e : m_entries) + { + if (e.binding == binding) + { + return &e; + } + } + return nullptr; +} + +bool BindGroupLayout::hasDynamicOffset(uint32_t binding) const +{ + const BindGroupLayoutEntry* e = findEntry(binding); + return e != nullptr && e->kind == BindingKind::uniformBuffer && + e->hasDynamicOffset; +} + +// Map ore::BindingKind (public layout API) ↔ ore::ResourceKind (binding-map +// internal). Kept private to this TU. +static bool kindsMatch(BindingKind layoutKind, ResourceKind shaderKind) +{ + switch (layoutKind) + { + case BindingKind::uniformBuffer: + return shaderKind == ResourceKind::UniformBuffer; + case BindingKind::storageBufferRO: + return shaderKind == ResourceKind::StorageBufferRO; + case BindingKind::storageBufferRW: + return shaderKind == ResourceKind::StorageBufferRW; + case BindingKind::sampledTexture: + return shaderKind == ResourceKind::SampledTexture; + case BindingKind::storageTexture: + return shaderKind == ResourceKind::StorageTexture; + case BindingKind::sampler: + // Sampler / ComparisonSampler are interchangeable on the + // bind-API side — matches the BindingMap::lookup collapse + // (ore_binding_map.hpp:201-208). Layout is allowed to declare + // either; runtime treats them as one bind-time category. + return shaderKind == ResourceKind::Sampler || + shaderKind == ResourceKind::ComparisonSampler; + case BindingKind::comparisonSampler: + return shaderKind == ResourceKind::Sampler || + shaderKind == ResourceKind::ComparisonSampler; + } + return false; +} + +static const char* kindName(BindingKind k) +{ + switch (k) + { + case BindingKind::uniformBuffer: + return "uniformBuffer"; + case BindingKind::storageBufferRO: + return "storageBufferRO"; + case BindingKind::storageBufferRW: + return "storageBufferRW"; + case BindingKind::sampledTexture: + return "sampledTexture"; + case BindingKind::storageTexture: + return "storageTexture"; + case BindingKind::sampler: + return "sampler"; + case BindingKind::comparisonSampler: + return "comparisonSampler"; + } + return "?"; +} + +static const char* shaderKindName(ResourceKind k) +{ + switch (k) + { + case ResourceKind::UniformBuffer: + return "uniformBuffer"; + case ResourceKind::StorageBufferRO: + return "storageBufferRO"; + case ResourceKind::StorageBufferRW: + return "storageBufferRW"; + case ResourceKind::SampledTexture: + return "sampledTexture"; + case ResourceKind::StorageTexture: + return "storageTexture"; + case ResourceKind::Sampler: + return "sampler"; + case ResourceKind::ComparisonSampler: + return "comparisonSampler"; + } + return "?"; +} + +bool validateLayoutsAgainstBindingMap(const BindingMap& bindingMap, + BindGroupLayout* const* layouts, + uint32_t layoutCount, + std::string* outError) +{ + auto fail = [&](const std::string& msg) { + if (outError != nullptr) + { + *outError = msg; + } + return false; + }; + + // Every binding the shader references must have a corresponding layout + // entry. Unused layout entries (declared but not referenced by the shader) + // are allowed — Dawn permits this and it lets pipelines reuse a more + // permissive layout than the shader strictly needs. + for (size_t i = 0; i < bindingMap.size(); ++i) + { + const BindingMap::Entry& shaderEntry = bindingMap.at(i); + const uint32_t group = shaderEntry.group; + const uint32_t binding = shaderEntry.binding; + + if (group >= layoutCount || layouts == nullptr || + layouts[group] == nullptr) + { + std::ostringstream oss; + oss << "@group(" << group << ") @binding(" << binding + << "): shader declares " << shaderKindName(shaderEntry.kind) + << " but PipelineDesc::bindGroupLayouts has no entry for " + "group " + << group; + return fail(oss.str()); + } + + const BindGroupLayout* layout = layouts[group]; + if (layout->groupIndex() != group) + { + std::ostringstream oss; + oss << "PipelineDesc::bindGroupLayouts[" << group + << "]->groupIndex == " << layout->groupIndex() << ", expected " + << group + << " (positional index must match layout's groupIndex)"; + return fail(oss.str()); + } + + const BindGroupLayoutEntry* layoutEntry = layout->findEntry(binding); + if (layoutEntry == nullptr) + { + std::ostringstream oss; + oss << "@group(" << group << ") @binding(" << binding + << "): layout has no entry for this binding (shader expects " + << shaderKindName(shaderEntry.kind) << ")"; + return fail(oss.str()); + } + + if (!kindsMatch(layoutEntry->kind, shaderEntry.kind)) + { + std::ostringstream oss; + oss << "@group(" << group << ") @binding(" << binding + << "): layout declares " << kindName(layoutEntry->kind) + << " but shader declares " << shaderKindName(shaderEntry.kind); + return fail(oss.str()); + } + + // Visibility narrower than the shader's stageMask is rejected. + // Layout broader than shader is fine (allowed by WebGPU spec). + const uint8_t shaderStageMask = shaderEntry.stageMask; + const uint8_t layoutVisibility = layoutEntry->visibility.mask; + if ((shaderStageMask & ~layoutVisibility) != 0) + { + std::ostringstream oss; + oss << "@group(" << group << ") @binding(" << binding + << "): layout visibility 0x" << std::hex + << static_cast(layoutVisibility) + << " missing stages required by shader (stageMask=0x" + << static_cast(shaderStageMask) << ")"; + return fail(oss.str()); + } + + // Texture dimension/sampleType compatibility (texture kinds only). + if (layoutEntry->kind == BindingKind::sampledTexture || + layoutEntry->kind == BindingKind::storageTexture) + { + // Map TextureViewDim (binding-map) ↔ TextureViewDimension + // (public layout API). The binding-map enum has D1/D2/D2Array/ + // Cube/CubeArray/D3; the public enum has texture2D/cube/ + // texture3D/array2D/cubeArray. + auto dimsMatch = [](TextureViewDimension a, TextureViewDim b) { + switch (a) + { + case TextureViewDimension::texture2D: + return b == TextureViewDim::D2; + case TextureViewDimension::cube: + return b == TextureViewDim::Cube; + case TextureViewDimension::texture3D: + return b == TextureViewDim::D3; + case TextureViewDimension::array2D: + return b == TextureViewDim::D2Array; + case TextureViewDimension::cubeArray: + return b == TextureViewDim::CubeArray; + } + return false; + }; + + // Shader's textureViewDim is Undefined for non-texture kinds + // and may also be Undefined for textures the shader compiler + // didn't reflect a dim for. Skip the check when shader side + // is Undefined. + if (shaderEntry.textureViewDim != TextureViewDim::Undefined && + !dimsMatch(layoutEntry->textureViewDim, + shaderEntry.textureViewDim)) + { + std::ostringstream oss; + oss << "@group(" << group << ") @binding(" << binding + << "): texture view dimension mismatch"; + return fail(oss.str()); + } + } + } + return true; +} + +bool validateColorRequiresFragment(uint32_t colorCount, + bool hasFragmentModule, + std::string* outError) +{ + if (colorCount > 0 && !hasFragmentModule) + { + if (outError != nullptr) + *outError = "pipeline declares color outputs but has no fragment " + "shader; supply `fragment`, or omit `colorTargets` " + "for a depth-only pipeline"; + return false; + } + return true; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/ore_binding_map.cpp b/thirdparty/rive_renderer/source/ore/ore_binding_map.cpp new file mode 100644 index 000000000..e2496b3b1 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/ore_binding_map.cpp @@ -0,0 +1,189 @@ +/* + * Copyright 2026 Rive + */ + +#include "rive/renderer/ore/ore_binding_map.hpp" + +#include +#include + +// BindingMap serialization (toBlob/fromBlob), sort/finalize, and lookup. +// All construction at runtime goes through `fromBlob` against an RSTB +// sidecar; the editor-side toolchain produces the blob via `toBlob`. + +namespace rive::ore +{ + +namespace +{ + +// On-disk blob layout: +// +// offset 0 [u8] blob_version (= kBlobVersion) +// 1 [u8] allocator_version (= kAllocatorVersion) +// 2 [u16] entry_size (LE) (grows append-only) +// 4 [u32] entry_count (LE) +// 8 [entry_count * entry_size] entries +// +// Each entry (entry_size = 14 bytes, no trailing alignment): +// +// 0 [u8] group +// 1 [u8] binding +// 2 [u8] kind (ResourceKind) +// 3 [u8] stageMask +// 4 [u8] backendSpace +// 5 [u16] backendSlot[0] (VS, LE) +// 7 [u16] backendSlot[1] (FS, LE) +// 9 [u16] backendSlot[2] (CS, LE) +// 11 [u8] textureViewDim (TextureViewDim) +// 12 [u8] textureSampleType (TextureSampleType) +// 13 [u8] textureMultisampled (0 or 1) +// +// Forward compat: a newer writer may emit entries larger than the current +// reader knows about by bumping entry_size. The reader skips the trailing +// unknown bytes per entry. New fields are always *appended* at the tail. +// No reserved-for-future slots inside the known prefix, since entry_size +// already gives us self-describing append-only growth. Any mismatch that +// matters semantically (blob_version or allocator_version) is a loud +// error. + +constexpr size_t kBlobHeaderSize = 8; +constexpr uint16_t kEntryWireSize = 14; + +inline uint16_t readU16LE(const uint8_t* p) +{ + return static_cast(p[0]) | (static_cast(p[1]) << 8); +} + +inline uint32_t readU32LE(const uint8_t* p) +{ + return static_cast(p[0]) | (static_cast(p[1]) << 8) | + (static_cast(p[2]) << 16) | + (static_cast(p[3]) << 24); +} + +#ifdef WITH_RIVE_TOOLS +inline void writeU16LE(uint8_t* p, uint16_t v) +{ + p[0] = static_cast(v & 0xFF); + p[1] = static_cast((v >> 8) & 0xFF); +} + +inline void writeU32LE(uint8_t* p, uint32_t v) +{ + p[0] = static_cast(v & 0xFF); + p[1] = static_cast((v >> 8) & 0xFF); + p[2] = static_cast((v >> 16) & 0xFF); + p[3] = static_cast((v >> 24) & 0xFF); +} +#endif + +} // namespace + +// Runtime API: fromBlob trusts its input to be sorted (toBlob iterates +// m_entries in canonical order). No sort on the hot path. +bool BindingMap::fromBlob(const uint8_t* data, size_t size, BindingMap* out) +{ + if (out == nullptr || data == nullptr) + return false; + out->m_entries.clear(); +#ifdef WITH_RIVE_TOOLS + out->m_finalized = false; +#endif + + if (size < kBlobHeaderSize) + return false; + + const uint8_t blobVer = data[0]; + const uint8_t allocVer = data[1]; + if (blobVer != kBlobVersion) + return false; // Never silent-fallback on a malformed blob. + if (allocVer != kAllocatorVersion) + return false; + + const uint16_t entrySize = readU16LE(&data[2]); + const uint32_t entryCount = readU32LE(&data[4]); + + // Reject writers that emit fewer fields than the reader needs. + // Larger entry_size is fine — trailing unknown bytes are skipped. + if (entrySize < kEntryWireSize) + return false; + + const size_t needed = + kBlobHeaderSize + static_cast(entryCount) * entrySize; + if (size < needed) + return false; + + out->m_entries.reserve(entryCount); + const uint8_t* p = data + kBlobHeaderSize; + for (uint32_t i = 0; i < entryCount; ++i) + { + Entry e{}; + e.group = p[0]; + e.binding = p[1]; + e.kind = static_cast(p[2]); + e.stageMask = p[3]; + e.backendSpace = p[4]; + e.backendSlot[0] = readU16LE(&p[5]); + e.backendSlot[1] = readU16LE(&p[7]); + e.backendSlot[2] = readU16LE(&p[9]); + e.textureViewDim = static_cast(p[11]); + e.textureSampleType = static_cast(p[12]); + e.textureMultisampled = (p[13] != 0); + // bytes [kEntryWireSize..entrySize] are future-version fields — skip. + out->m_entries.push_back(e); + p += entrySize; + } +#ifdef WITH_RIVE_TOOLS + // Flip the finalized flag so tooling-build lookups satisfy their assert. + // The blob is already sorted by construction; no std::sort call. + out->m_finalized = true; +#endif + return true; +} + +#ifdef WITH_RIVE_TOOLS + +std::vector BindingMap::toBlob() const +{ + std::vector blob(kBlobHeaderSize + + m_entries.size() * kEntryWireSize); + blob[0] = kBlobVersion; + blob[1] = kAllocatorVersion; + writeU16LE(&blob[2], kEntryWireSize); + writeU32LE(&blob[4], static_cast(m_entries.size())); + + uint8_t* p = blob.data() + kBlobHeaderSize; + for (const Entry& e : m_entries) + { + p[0] = e.group; + p[1] = e.binding; + p[2] = static_cast(e.kind); + p[3] = e.stageMask; + p[4] = e.backendSpace; + writeU16LE(&p[5], e.backendSlot[0]); + writeU16LE(&p[7], e.backendSlot[1]); + writeU16LE(&p[9], e.backendSlot[2]); + p[11] = static_cast(e.textureViewDim); + p[12] = static_cast(e.textureSampleType); + p[13] = e.textureMultisampled ? 1u : 0u; + p += kEntryWireSize; + } + return blob; +} + +void BindingMap::finalize() +{ + std::sort(m_entries.begin(), + m_entries.end(), + [](const Entry& a, const Entry& b) { + if (a.group != b.group) + return a.group < b.group; + return a.binding < b.binding; + }); + m_finalized = true; +} + +#endif // WITH_RIVE_TOOLS + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_bind_group_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_bind_group_vulkan.cpp new file mode 100644 index 000000000..e79d2bc92 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_bind_group_vulkan.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void BindGroup::onRefCntReachedZero() const +{ + // Free the VkDescriptorSet back to the persistent pool. Without + // this the pool grows unbounded — long editor sessions hit + // `VK_ERROR_OUT_OF_POOL_MEMORY` on subsequent makeBindGroup calls, + // which Context returns as a silent nullptr (post-Phase-1 we now + // also setLastError, but the leak is the underlying problem). The + // pool was created with `VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT` + // exactly to support per-set free here. + // + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + auto* ctx = static_cast(m_context); + if (m_vkDescriptorSet != VK_NULL_HANDLE && ctx != nullptr && + ctx->m_vkPersistentDescriptorPool != VK_NULL_HANDLE) + { + ctx->m_vk.FreeDescriptorSets(ctx->m_vkDevice, + ctx->m_vkPersistentDescriptorPool, + 1, + &m_vkDescriptorSet); + } + delete this; +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_buffer_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_buffer_vulkan.cpp new file mode 100644 index 000000000..1fe347406 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_buffer_vulkan.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" + +#include + +#include +#include + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + assert(m_vkMappedPtr != nullptr); + memcpy(static_cast(m_vkMappedPtr) + offset, data, size); +} + +void Buffer::onRefCntReachedZero() const +{ + VmaAllocator allocator = m_vmaAllocator; + VkBuffer buf = m_vkBuffer; + VmaAllocation alloc = m_vmaAllocation; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (buf != VK_NULL_HANDLE) + vmaDestroyBuffer(allocator, buf, alloc); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // !ORE_BACKEND_GL +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_context_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_context_vulkan.cpp new file mode 100644 index 000000000..af9dc2288 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_context_vulkan.cpp @@ -0,0 +1,1476 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_context_vulkan.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/renderer/vulkan/render_target_vulkan.hpp" + +#include "ore_vulkan_dsl.hpp" // for createDSLFromLayoutDesc + +#include +// VMA_IMPLEMENTATION is defined in src/vulkan/vulkan_memory_allocator.cpp, +// which is compiled when --with_vulkan is passed (required for this backend). + +#include +#include +#include + +namespace rive::ore +{ + +// ============================================================================ +// Enum → VkFormat helper (shared with ore_texture_vulkan.cpp via header, +// but declared again here as a file-local helper for the render pass builder). +// ============================================================================ + +static VkFormat oreFormatToVkLocal(TextureFormat fmt) +{ + // Mirror of oreFormatToVk in ore_texture_vulkan.cpp. + switch (fmt) + { + case TextureFormat::r8unorm: + return VK_FORMAT_R8_UNORM; + case TextureFormat::rg8unorm: + return VK_FORMAT_R8G8_UNORM; + case TextureFormat::rgba8unorm: + return VK_FORMAT_R8G8B8A8_UNORM; + case TextureFormat::rgba8snorm: + return VK_FORMAT_R8G8B8A8_SNORM; + case TextureFormat::bgra8unorm: + return VK_FORMAT_B8G8R8A8_UNORM; + case TextureFormat::rgba16float: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case TextureFormat::rg16float: + return VK_FORMAT_R16G16_SFLOAT; + case TextureFormat::r16float: + return VK_FORMAT_R16_SFLOAT; + case TextureFormat::rgba32float: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case TextureFormat::rg32float: + return VK_FORMAT_R32G32_SFLOAT; + case TextureFormat::r32float: + return VK_FORMAT_R32_SFLOAT; + case TextureFormat::rgb10a2unorm: + return VK_FORMAT_A2B10G10R10_UNORM_PACK32; + case TextureFormat::r11g11b10float: + return VK_FORMAT_B10G11R11_UFLOAT_PACK32; + case TextureFormat::depth16unorm: + return VK_FORMAT_D16_UNORM; + case TextureFormat::depth24plusStencil8: + return VK_FORMAT_D24_UNORM_S8_UINT; + case TextureFormat::depth32float: + return VK_FORMAT_D32_SFLOAT; + case TextureFormat::depth32floatStencil8: + return VK_FORMAT_D32_SFLOAT_S8_UINT; + case TextureFormat::bc1unorm: + return VK_FORMAT_BC1_RGBA_UNORM_BLOCK; + case TextureFormat::bc3unorm: + return VK_FORMAT_BC3_UNORM_BLOCK; + case TextureFormat::bc7unorm: + return VK_FORMAT_BC7_UNORM_BLOCK; + case TextureFormat::etc2rgb8: + return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; + case TextureFormat::etc2rgba8: + return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; + case TextureFormat::astc4x4: + return VK_FORMAT_ASTC_4x4_UNORM_BLOCK; + case TextureFormat::astc6x6: + return VK_FORMAT_ASTC_6x6_UNORM_BLOCK; + case TextureFormat::astc8x8: + return VK_FORMAT_ASTC_8x8_UNORM_BLOCK; + } + return VK_FORMAT_UNDEFINED; +} + +static bool isDepthStencilFormatLocal(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::depth16unorm: + case TextureFormat::depth24plusStencil8: + case TextureFormat::depth32float: + case TextureFormat::depth32floatStencil8: + return true; + default: + return false; + } +} + +static bool hasStencilLocal(TextureFormat fmt) +{ + return fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32floatStencil8; +} + +static VkAttachmentLoadOp oreLoadOpToVk(LoadOp op) +{ + switch (op) + { + case LoadOp::clear: + return VK_ATTACHMENT_LOAD_OP_CLEAR; + case LoadOp::load: + return VK_ATTACHMENT_LOAD_OP_LOAD; + case LoadOp::dontCare: + return VK_ATTACHMENT_LOAD_OP_DONT_CARE; + } + return VK_ATTACHMENT_LOAD_OP_DONT_CARE; +} + +static VkAttachmentStoreOp oreStoreOpToVk(StoreOp op) +{ + switch (op) + { + case StoreOp::store: + return VK_ATTACHMENT_STORE_OP_STORE; + case StoreOp::discard: + return VK_ATTACHMENT_STORE_OP_DONT_CARE; + } + return VK_ATTACHMENT_STORE_OP_DONT_CARE; +} + +// ============================================================================ +// Context lifecycle +// ============================================================================ + +ContextVulkan::~ContextVulkan() +{ + if (m_vkDevice == VK_NULL_HANDLE) + return; + + // Wait for any in-flight GPU work before tearing down resources. Use + // QueueWaitIdle to also cover the external-CB path where the host owns + // the frame fence and may have submitted work Ore doesn't track. + if (m_vkQueue != VK_NULL_HANDLE) + m_vk.QueueWaitIdle(m_vkQueue); + if (m_vkFrameFence != VK_NULL_HANDLE) + m_vk.DestroyFence(m_vkDevice, m_vkFrameFence, nullptr); + + // Drop any BindGroups that were deferred past the final endFrame(). Their + // descriptor sets live in m_vkPersistentDescriptorPool and must go away + // before that pool is destroyed below, otherwise validation flags leaked + // VkDescriptorSets at vkDestroyDevice time. + m_deferredBindGroups.clear(); + + vkDrainDeferred(); + + // Drain the render pass cache. + for (auto& [key, rp] : m_vkRenderPassCache) + m_vk.DestroyRenderPass(m_vkDevice, rp, nullptr); + m_vkRenderPassCache.clear(); + + if (m_vkDescriptorPool != VK_NULL_HANDLE) + m_vk.DestroyDescriptorPool(m_vkDevice, m_vkDescriptorPool, nullptr); + + // The persistent pool backs BindGroups (allocated lazily in makeBindGroup). + // Destroying it implicitly frees any remaining descriptor sets it owns. + if (m_vkPersistentDescriptorPool != VK_NULL_HANDLE) + m_vk.DestroyDescriptorPool(m_vkDevice, + m_vkPersistentDescriptorPool, + nullptr); + + if (m_vkEmptyDSL != VK_NULL_HANDLE) + m_vk.DestroyDescriptorSetLayout(m_vkDevice, m_vkEmptyDSL, nullptr); + + if (m_vkCommandPool != VK_NULL_HANDLE) + m_vk.DestroyCommandPool(m_vkDevice, m_vkCommandPool, nullptr); +} + +// ============================================================================ +// ContextVulkan::Make +// ============================================================================ + +std::unique_ptr ContextVulkan::Make( + VkInstance instance, + VkPhysicalDevice physicalDevice, + VkDevice device, + VkQueue queue, + uint32_t queueFamilyIndex, + VmaAllocator allocator, + PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr) +{ + auto ctx = std::unique_ptr(new ContextVulkan()); + ctx->m_vkPhysicalDevice = physicalDevice; + ctx->m_vkDevice = device; + ctx->m_vkQueue = queue; + ctx->m_vkQueueFamily = queueFamilyIndex; + ctx->m_vmaAllocator = allocator; + + // Load instance-level function pointers. +#define LOAD_INSTANCE_CMD(CMD) \ + ctx->m_vk.CMD = reinterpret_cast( \ + pfnGetInstanceProcAddr(instance, "vk" #CMD)); + ORE_VK_INSTANCE_COMMANDS(LOAD_INSTANCE_CMD) +#undef LOAD_INSTANCE_CMD + + // Load device-level function pointers via GetDeviceProcAddr. +#define LOAD_DEVICE_CMD(CMD) \ + ctx->m_vk.CMD = reinterpret_cast( \ + ctx->m_vk.GetDeviceProcAddr(device, "vk" #CMD)); + ORE_VK_DEVICE_COMMANDS(LOAD_DEVICE_CMD) +#undef LOAD_DEVICE_CMD + + // Command pool: reset-per-command-buffer for single-threaded use. + VkCommandPoolCreateInfo poolCI{}; + poolCI.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolCI.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + poolCI.queueFamilyIndex = queueFamilyIndex; + ctx->m_vk.CreateCommandPool(device, + &poolCI, + nullptr, + &ctx->m_vkCommandPool); + + // Single reusable command buffer. + VkCommandBufferAllocateInfo cbAI{}; + cbAI.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + cbAI.commandPool = ctx->m_vkCommandPool; + cbAI.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cbAI.commandBufferCount = 1; + ctx->m_vk.AllocateCommandBuffers(device, &cbAI, &ctx->m_vkCommandBuffer); + + // Descriptor pool: sized generously for per-frame allocation + reset. + // 3 sets per draw × 256 draws per frame × 3 types = 2304 descriptors. + VkDescriptorPoolSize poolSizes[3]; + poolSizes[0] = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2048}; + poolSizes[1] = {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2048}; + poolSizes[2] = {VK_DESCRIPTOR_TYPE_SAMPLER, 2048}; + + VkDescriptorPoolCreateInfo dpCI{}; + dpCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + dpCI.flags = 0; // No FREE_DESCRIPTOR_SET — we reset the whole pool. + dpCI.maxSets = 768; + dpCI.poolSizeCount = 3; + dpCI.pPoolSizes = poolSizes; + ctx->m_vk.CreateDescriptorPool(device, + &dpCI, + nullptr, + &ctx->m_vkDescriptorPool); + + // Frame fence — signaled after each endFrame() QueueSubmit, waited on + // in the next beginFrame() (or the destructor) so we never destroy + // resources the GPU is still using. Created in the signaled state so + // the first beginFrame() can wait without blocking. + VkFenceCreateInfo fenceCI{}; + fenceCI.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCI.flags = VK_FENCE_CREATE_SIGNALED_BIT; + ctx->m_vk.CreateFence(device, &fenceCI, nullptr, &ctx->m_vkFrameFence); + + // Populate features from physical device properties. + VkPhysicalDeviceProperties props{}; + ctx->m_vk.GetPhysicalDeviceProperties(physicalDevice, &props); + VkPhysicalDeviceFeatures feat{}; + ctx->m_vk.GetPhysicalDeviceFeatures(physicalDevice, &feat); + + Features& f = ctx->m_features; + f.colorBufferFloat = true; // All Vulkan 1.1+ support rgba16f attachments. + f.perTargetBlend = feat.independentBlend == VK_TRUE; + f.perTargetWriteMask = feat.independentBlend == VK_TRUE; + f.textureViewSampling = true; + f.drawBaseInstance = true; + f.depthBiasClamp = feat.depthBiasClamp == VK_TRUE; + f.anisotropicFiltering = feat.samplerAnisotropy == VK_TRUE; + f.texture3D = true; + f.textureArrays = true; + f.computeShaders = true; + f.storageBuffers = true; + // Compressed format support via format properties. + f.bc = feat.textureCompressionBC == VK_TRUE; + f.etc2 = feat.textureCompressionETC2 == VK_TRUE; + f.astc = feat.textureCompressionASTC_LDR == VK_TRUE; + f.maxColorAttachments = props.limits.maxColorAttachments; + f.maxTextureSize2D = props.limits.maxImageDimension2D; + f.maxTextureSizeCube = props.limits.maxImageDimensionCube; + f.maxTextureSize3D = props.limits.maxImageDimension3D; + f.maxUniformBufferSize = + static_cast(props.limits.maxUniformBufferRange); + f.maxVertexAttributes = props.limits.maxVertexInputAttributes; + f.maxSamplers = props.limits.maxPerStageDescriptorSamplers; + + return ctx; +} + +// ============================================================================ +// Frame lifecycle +// ============================================================================ + +void ContextVulkan::vkDrainDeferred() +{ + for (VkFramebuffer fb : m_vkDeferredFramebuffers) + m_vk.DestroyFramebuffer(m_vkDevice, fb, nullptr); + m_vkDeferredFramebuffers.clear(); + + for (auto& buf : m_vkDeferredStagingBuffers) + vmaDestroyBuffer(m_vmaAllocator, buf.buffer, buf.allocation); + m_vkDeferredStagingBuffers.clear(); + + for (auto& destroy : m_vkDeferredDestroys) + destroy(); + m_vkDeferredDestroys.clear(); +} + +void ContextVulkan::vkDeferDestroy(std::function destroy) +{ + if (m_vkExternalCmdBuf) + m_vkDeferredDestroys.push_back(std::move(destroy)); + else + destroy(); +} + +// Lazy-create a shared empty `VkDescriptorSetLayout`. Used to fill null +// slots in a pipeline's `pSetLayouts[]` when the user supplies a sparse +// `bindGroupLayouts[]` (e.g. `[NULL, layout1, layout2]` for a shader +// that only binds to groups 1 and 2). Vulkan VUID 06753 forbids +// VK_NULL_HANDLE in pSetLayouts without graphicsPipelineLibrary. +VkDescriptorSetLayout ContextVulkan::vkGetOrCreateEmptyDSL() +{ + if (m_vkEmptyDSL != VK_NULL_HANDLE) + return m_vkEmptyDSL; + VkDescriptorSetLayoutCreateInfo ci{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO}; + ci.bindingCount = 0; + ci.pBindings = nullptr; + m_vk.CreateDescriptorSetLayout(m_vkDevice, &ci, nullptr, &m_vkEmptyDSL); + return m_vkEmptyDSL; +} + +void ContextVulkan::vkFlushPendingInitialTransitions() +{ + if (m_vkPendingInitialTransitions.empty()) + return; + + // Only transition textures that are still in UNDEFINED — another code + // path (upload(), a prior render pass attachment) may have moved the + // layout forward since we queued this entry. Emitting UNDEFINED→ + // SHADER_READ_ONLY on an already-initialized image would let the driver + // discard its contents. + std::vector barriers; + barriers.reserve(m_vkPendingInitialTransitions.size()); + for (const auto& pt : m_vkPendingInitialTransitions) + { + if (pt.texture->m_vkLayout != VK_IMAGE_LAYOUT_UNDEFINED) + continue; + + VkImageMemoryBarrier b{}; + b.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + b.srcAccessMask = 0; + b.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + b.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + b.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + b.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + b.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + b.image = pt.texture->m_vkImage; + b.subresourceRange.aspectMask = pt.aspectMask; + b.subresourceRange.baseMipLevel = 0; + b.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + b.subresourceRange.baseArrayLayer = 0; + b.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + barriers.push_back(b); + pt.texture->m_vkLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } + if (!barriers.empty()) + { + m_vk.CmdPipelineBarrier(m_vkCommandBuffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, + 0, + nullptr, + 0, + nullptr, + static_cast(barriers.size()), + barriers.data()); + } + m_vkPendingInitialTransitions.clear(); +} + +void ContextVulkan::beginFrame() +{ + // Release deferred BindGroups from last frame. endFrame() already + // waited for GPU completion, so these are safe to destroy. + m_deferredBindGroups.clear(); + + // If the previous frame was external, its endFrame() skipped draining. + if (!m_vkDeferredFramebuffers.empty() || + !m_vkDeferredStagingBuffers.empty()) + { + vkDrainDeferred(); + } + + m_vkExternalCmdBuf = false; + + // Reset the descriptor pool — all sets from last frame are invalid. + m_vk.ResetDescriptorPool(m_vkDevice, m_vkDescriptorPool, 0); + + // Begin the frame command buffer. + m_vk.ResetCommandBuffer(m_vkCommandBuffer, 0); + + VkCommandBufferBeginInfo beginInfo{}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + m_vk.BeginCommandBuffer(m_vkCommandBuffer, &beginInfo); + + // Flush any lazy-init barriers queued between frames (e.g. BindGroups + // created before beginFrame that referenced a still-UNDEFINED texture). + vkFlushPendingInitialTransitions(); +} + +void ContextVulkan::beginFrame(VkCommandBuffer externalCb) +{ + assert(externalCb != VK_NULL_HANDLE); + + m_deferredBindGroups.clear(); + vkDrainDeferred(); + + m_vk.ResetDescriptorPool(m_vkDevice, m_vkDescriptorPool, 0); + + m_vkCommandBuffer = externalCb; + m_vkExternalCmdBuf = true; + + // Flush any lazy-init barriers queued before this frame. Host has + // already called BeginCommandBuffer on externalCb, so recording is safe. + vkFlushPendingInitialTransitions(); +} + +void ContextVulkan::waitForGPU() +{ +#if defined(ORE_BACKEND_VK) + if (m_vkFrameFence != VK_NULL_HANDLE) + m_vk.WaitForFences(m_vkDevice, 1, &m_vkFrameFence, VK_TRUE, UINT64_MAX); +#endif +} + +void ContextVulkan::endFrame() +{ + if (m_vkExternalCmdBuf) + { + // External-CB mode: host owns End/Submit/fence. Deferred destroys + // wait until the next beginFrame() when the host has waited on the + // prior submission. + return; + } + + m_vk.EndCommandBuffer(m_vkCommandBuffer); + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &m_vkCommandBuffer; + m_vk.ResetFences(m_vkDevice, 1, &m_vkFrameFence); + m_vk.QueueSubmit(m_vkQueue, 1, &submitInfo, m_vkFrameFence); + // Wait for GPU completion before returning — callers destroy Ore + // resources (textures, views, pipelines) after endFrame(), and those + // must not be in use by the GPU. Matches D3D12's endFrame() behavior. + m_vk.WaitForFences(m_vkDevice, 1, &m_vkFrameFence, VK_TRUE, UINT64_MAX); + + vkDrainDeferred(); +} + +// ============================================================================ +// getOrCreateRenderPass +// ============================================================================ + +VkRenderPass ContextVulkan::getOrCreateRenderPass(const VKRenderPassKey& key) +{ + // Linear scan — cache is typically <10 entries. + for (auto& [k, rp] : m_vkRenderPassCache) + { + if (k == key) + return rp; + } + + // Build attachment descriptions. Layout: [color × N][resolve × N_resolve] + // [depth?]. Resolve attachments are interleaved after the colors so the + // subpass's `pResolveAttachments` array indexes into a contiguous range. + constexpr uint32_t kMaxAttachments = 9; // 4 color + 4 resolve + 1 depth. + VkAttachmentDescription attachments[kMaxAttachments]{}; + VkAttachmentReference colorRefs[4]{}; + VkAttachmentReference resolveRefs[4]{}; + VkAttachmentReference depthRef{}; + uint32_t attachIdx = 0; + bool anyResolve = false; + + for (uint32_t i = 0; i < key.colorCount; ++i) + { + VkAttachmentDescription& a = attachments[attachIdx]; + a.format = oreFormatToVkLocal(key.colorFormats[i]); + a.samples = static_cast(key.sampleCount); + a.loadOp = oreLoadOpToVk(key.colorLoadOps[i]); + a.storeOp = oreStoreOpToVk(key.colorStoreOps[i]); + a.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + a.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + // After finish(), color images are always in SHADER_READ_ONLY_OPTIMAL. + // A subsequent LoadOp::load pass must start from that layout. + a.initialLayout = (key.colorLoadOps[i] == LoadOp::load) + ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + : VK_IMAGE_LAYOUT_UNDEFINED; + a.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + colorRefs[i].attachment = attachIdx; + colorRefs[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + ++attachIdx; + anyResolve = anyResolve || key.colorHasResolve[i]; + } + + // Resolve attachments (single-sample). Must be in the same order as + // colorRefs; an `attachment = VK_ATTACHMENT_UNUSED` entry signals + // "this color attachment has no resolve target." Vulkan requires the + // resolve and color attachment to share format and aspect. + if (anyResolve) + { + for (uint32_t i = 0; i < key.colorCount; ++i) + { + if (!key.colorHasResolve[i]) + { + resolveRefs[i].attachment = VK_ATTACHMENT_UNUSED; + resolveRefs[i].layout = VK_IMAGE_LAYOUT_UNDEFINED; + continue; + } + VkAttachmentDescription& a = attachments[attachIdx]; + a.format = oreFormatToVkLocal(key.colorFormats[i]); + a.samples = VK_SAMPLE_COUNT_1_BIT; + a.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + a.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + a.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + a.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + a.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + a.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + resolveRefs[i].attachment = attachIdx; + resolveRefs[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + ++attachIdx; + } + } + + bool hasDepthAttach = false; + if (key.hasDepth) + { + VkAttachmentDescription& a = attachments[attachIdx]; + a.format = oreFormatToVkLocal(key.depthFormat); + a.samples = static_cast(key.sampleCount); + a.loadOp = oreLoadOpToVk(key.depthLoadOp); + a.storeOp = oreStoreOpToVk(key.depthStoreOp); + a.stencilLoadOp = oreLoadOpToVk(key.depthLoadOp); + a.stencilStoreOp = oreStoreOpToVk(key.depthStoreOp); + a.initialLayout = (key.depthLoadOp == LoadOp::load) + ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_UNDEFINED; + a.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + depthRef.attachment = attachIdx; + depthRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + ++attachIdx; + hasDepthAttach = true; + } + + VkSubpassDescription subpass{}; + subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.colorAttachmentCount = key.colorCount; + subpass.pColorAttachments = colorRefs; + subpass.pResolveAttachments = anyResolve ? resolveRefs : nullptr; + subpass.pDepthStencilAttachment = hasDepthAttach ? &depthRef : nullptr; + + // Subpass dependency: ensure the render pass waits for prior renders before + // writing to attachments, and makes writes visible before subsequent reads. + VkSubpassDependency deps[2]{}; + deps[0].srcSubpass = VK_SUBPASS_EXTERNAL; + deps[0].dstSubpass = 0; + deps[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + deps[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + deps[0].srcAccessMask = 0; + deps[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + deps[1].srcSubpass = 0; + deps[1].dstSubpass = VK_SUBPASS_EXTERNAL; + deps[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + // Include VERTEX_SHADER so a subsequent pass that samples this + // attachment from a vertex shader (legal in WGSL) sees the writes + // with proper visibility. Fragment is the common case; vertex is + // near-free insurance. Not covered: compute, transfer — those + // consumers must emit their own barrier. + deps[1].dstStageMask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + deps[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + deps[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + + VkRenderPassCreateInfo rpCI{}; + rpCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rpCI.attachmentCount = attachIdx; + rpCI.pAttachments = attachments; + rpCI.subpassCount = 1; + rpCI.pSubpasses = &subpass; + rpCI.dependencyCount = 2; + rpCI.pDependencies = deps; + + VkRenderPass rp = VK_NULL_HANDLE; + m_vk.CreateRenderPass(m_vkDevice, &rpCI, nullptr, &rp); + + m_vkRenderPassCache.emplace_back(key, rp); + return rp; +} + +// ============================================================================ +// makeBuffer +// ============================================================================ + +rcp ContextVulkan::makeBuffer(const BufferDesc& desc) +{ + auto buffer = rcp(new Buffer(desc.size, desc.usage)); + buffer->m_vkDevice = m_vkDevice; + buffer->m_vmaAllocator = m_vmaAllocator; + buffer->m_vkOreContext = this; + + VkBufferUsageFlags usage = 0; + switch (desc.usage) + { + case BufferUsage::vertex: + usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + break; + case BufferUsage::index: + usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + break; + case BufferUsage::uniform: + usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + break; + } + + VkBufferCreateInfo bufCI{}; + bufCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufCI.size = desc.size; + bufCI.usage = usage; + + // Host-visible, persistently mapped — direct CPU writes, no staging. + VmaAllocationCreateInfo allocCI{}; + allocCI.usage = VMA_MEMORY_USAGE_CPU_TO_GPU; + allocCI.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VmaAllocationInfo allocInfo{}; + vmaCreateBuffer(m_vmaAllocator, + &bufCI, + &allocCI, + &buffer->m_vkBuffer, + &buffer->m_vmaAllocation, + &allocInfo); + buffer->m_vkMappedPtr = allocInfo.pMappedData; + + if (desc.data != nullptr) + { + memcpy(buffer->m_vkMappedPtr, desc.data, desc.size); + } + + return buffer; +} + +// ============================================================================ +// makeTexture +// ============================================================================ + +rcp ContextVulkan::makeTexture(const TextureDesc& desc) +{ + auto texture = rcp(new Texture(desc)); + texture->m_vkDevice = m_vkDevice; + texture->m_vmaAllocator = m_vmaAllocator; + texture->m_vkOreContext = this; + + VkImageUsageFlags usage = + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + if (desc.renderTarget) + { + bool isDS = isDepthStencilFormatLocal(desc.format); + usage |= isDS ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + } + + VkImageType imageType = VK_IMAGE_TYPE_2D; + VkImageCreateFlags createFlags = 0; + uint32_t arrayLayers = desc.depthOrArrayLayers; + + switch (desc.type) + { + case TextureType::texture2D: + imageType = VK_IMAGE_TYPE_2D; + arrayLayers = 1; + break; + case TextureType::cube: + imageType = VK_IMAGE_TYPE_2D; + createFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + arrayLayers = 6; + break; + case TextureType::texture3D: + imageType = VK_IMAGE_TYPE_3D; + arrayLayers = 1; + break; + case TextureType::array2D: + imageType = VK_IMAGE_TYPE_2D; + break; + } + + VkImageCreateInfo imgCI{}; + imgCI.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imgCI.flags = createFlags; + imgCI.imageType = imageType; + imgCI.format = oreFormatToVkLocal(desc.format); + imgCI.extent = {desc.width, desc.height, 1}; + imgCI.mipLevels = desc.numMipmaps > 0 ? desc.numMipmaps : 1; + imgCI.arrayLayers = arrayLayers; + imgCI.samples = static_cast(desc.sampleCount); + imgCI.tiling = VK_IMAGE_TILING_OPTIMAL; + imgCI.usage = usage; + imgCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VmaAllocationCreateInfo allocCI{}; + allocCI.usage = VMA_MEMORY_USAGE_GPU_ONLY; + + vmaCreateImage(m_vmaAllocator, + &imgCI, + &allocCI, + &texture->m_vkImage, + &texture->m_vmaAllocation, + nullptr); + texture->m_vkLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + return texture; +} + +// ============================================================================ +// makeTextureView +// ============================================================================ + +rcp ContextVulkan::makeTextureView(const TextureViewDesc& desc) +{ + Texture* tex = desc.texture; + if (!tex) + return nullptr; + + auto view = rcp(new TextureView(ref_rcp(tex), desc)); + view->m_vkDevice = m_vkDevice; + view->m_vkOreContext = this; + + VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + switch (desc.aspect) + { + case TextureAspect::all: + aspectMask = isDepthStencilFormatLocal(tex->format()) + ? (VK_IMAGE_ASPECT_DEPTH_BIT | + (hasStencilLocal(tex->format()) + ? VK_IMAGE_ASPECT_STENCIL_BIT + : 0u)) + : VK_IMAGE_ASPECT_COLOR_BIT; + break; + case TextureAspect::depthOnly: + aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + break; + case TextureAspect::stencilOnly: + aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + break; + } + + VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D; + switch (desc.dimension) + { + case TextureViewDimension::texture2D: + viewType = VK_IMAGE_VIEW_TYPE_2D; + break; + case TextureViewDimension::cube: + viewType = VK_IMAGE_VIEW_TYPE_CUBE; + break; + case TextureViewDimension::texture3D: + viewType = VK_IMAGE_VIEW_TYPE_3D; + break; + case TextureViewDimension::array2D: + viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + break; + case TextureViewDimension::cubeArray: + viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + break; + } + + VkImageViewCreateInfo viewCI{}; + viewCI.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewCI.image = tex->m_vkImage; + viewCI.viewType = viewType; + viewCI.format = oreFormatToVkLocal(tex->format()); + viewCI.subresourceRange.aspectMask = aspectMask; + viewCI.subresourceRange.baseMipLevel = desc.baseMipLevel; + viewCI.subresourceRange.levelCount = + desc.mipCount > 0 ? desc.mipCount : VK_REMAINING_MIP_LEVELS; + viewCI.subresourceRange.baseArrayLayer = desc.baseLayer; + viewCI.subresourceRange.layerCount = + desc.layerCount > 0 ? desc.layerCount : VK_REMAINING_ARRAY_LAYERS; + + m_vk.CreateImageView(m_vkDevice, &viewCI, nullptr, &view->m_vkImageView); + view->m_vkDestroyImageView = m_vk.DestroyImageView; + + return view; +} + +// ============================================================================ +// makeSampler +// ============================================================================ + +rcp ContextVulkan::makeSampler(const SamplerDesc& desc) +{ + auto sampler = rcp(new Sampler()); + sampler->m_vkDevice = m_vkDevice; + sampler->m_vkOreContext = this; + + auto filterToVk = [](Filter f) { + return f == Filter::linear ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; + }; + auto mipmapToVk = [](Filter f) { + return f == Filter::linear ? VK_SAMPLER_MIPMAP_MODE_LINEAR + : VK_SAMPLER_MIPMAP_MODE_NEAREST; + }; + auto wrapToVk = [](WrapMode w) -> VkSamplerAddressMode { + switch (w) + { + case WrapMode::repeat: + return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case WrapMode::mirrorRepeat: + return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case WrapMode::clampToEdge: + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + } + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + }; + auto compareToVk = [](CompareFunction c) -> VkCompareOp { + switch (c) + { + case CompareFunction::none: + case CompareFunction::always: + return VK_COMPARE_OP_ALWAYS; + case CompareFunction::never: + return VK_COMPARE_OP_NEVER; + case CompareFunction::less: + return VK_COMPARE_OP_LESS; + case CompareFunction::equal: + return VK_COMPARE_OP_EQUAL; + case CompareFunction::lessEqual: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case CompareFunction::greater: + return VK_COMPARE_OP_GREATER; + case CompareFunction::notEqual: + return VK_COMPARE_OP_NOT_EQUAL; + case CompareFunction::greaterEqual: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + } + return VK_COMPARE_OP_ALWAYS; + }; + + VkSamplerCreateInfo sCI{}; + sCI.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + sCI.magFilter = filterToVk(desc.magFilter); + sCI.minFilter = filterToVk(desc.minFilter); + sCI.mipmapMode = mipmapToVk(desc.mipmapFilter); + sCI.addressModeU = wrapToVk(desc.wrapU); + sCI.addressModeV = wrapToVk(desc.wrapV); + sCI.addressModeW = wrapToVk(desc.wrapW); + sCI.mipLodBias = 0.0f; + sCI.anisotropyEnable = + (desc.maxAnisotropy > 1 && m_features.anisotropicFiltering) ? VK_TRUE + : VK_FALSE; + sCI.maxAnisotropy = static_cast(desc.maxAnisotropy); + sCI.compareEnable = + (desc.compare != CompareFunction::none) ? VK_TRUE : VK_FALSE; + sCI.compareOp = compareToVk(desc.compare); + sCI.minLod = desc.minLod; + sCI.maxLod = desc.maxLod; + sCI.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + + m_vk.CreateSampler(m_vkDevice, &sCI, nullptr, &sampler->m_vkSampler); + sampler->m_vkDestroySampler = m_vk.DestroySampler; + + return sampler; +} + +// ============================================================================ +// makeShaderModule +// ============================================================================ + +rcp ContextVulkan::makeShaderModule(const ShaderModuleDesc& desc) +{ + auto module = rcp(new ShaderModule()); + module->m_vkDevice = m_vkDevice; + + VkShaderModuleCreateInfo smCI{}; + smCI.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + smCI.codeSize = desc.codeSize; + smCI.pCode = static_cast(desc.code); + + VkResult result = m_vk.CreateShaderModule(m_vkDevice, + &smCI, + nullptr, + &module->m_vkShaderModule); + if (result != VK_SUCCESS || module->m_vkShaderModule == VK_NULL_HANDLE) + { + setLastError("Ore Vulkan: vkCreateShaderModule failed (VkResult=%d)", + static_cast(result)); + return nullptr; + } + module->m_vkDestroyShaderModule = m_vk.DestroyShaderModule; + + module->applyBindingMapFromDesc(desc); + return module; +} + +// ============================================================================ +// makeBindGroupLayout +// ============================================================================ + +rcp ContextVulkan::makeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + if (desc.groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroupLayout: groupIndex %u out of range [0, %u)", + desc.groupIndex, + kMaxBindGroups); + return nullptr; + } + auto layout = rcp(new BindGroupLayout()); + layout->m_context = this; + layout->m_groupIndex = desc.groupIndex; + layout->m_entries.reserve(desc.entryCount); + for (uint32_t i = 0; i < desc.entryCount; ++i) + layout->m_entries.push_back(desc.entries[i]); + + layout->m_vkDevice = m_vkDevice; + layout->m_vkDestroyDescriptorSetLayout = m_vk.DestroyDescriptorSetLayout; + layout->m_vkDSL = createDSLFromLayoutDesc(m_vk.CreateDescriptorSetLayout, + m_vkDevice, + desc); + if (layout->m_vkDSL == VK_NULL_HANDLE) + { + setLastError("makeBindGroupLayout: vkCreateDescriptorSetLayout failed " + "(group=%u)", + desc.groupIndex); + return nullptr; + } + return layout; +} + +// ============================================================================ +// makeBindGroup +// ============================================================================ + +rcp ContextVulkan::makeBindGroup(const BindGroupDesc& desc) +{ + if (desc.layout == nullptr) + { + setLastError("makeBindGroup: BindGroupDesc::layout is null"); + return nullptr; + } + BindGroupLayout* layout = desc.layout; + const uint32_t groupIndex = layout->groupIndex(); + if (groupIndex >= kMaxBindGroups) + { + setLastError( + "makeBindGroup: layout->groupIndex %u out of range [0, %u)", + groupIndex, + kMaxBindGroups); + return nullptr; + } + + auto bg = rcp(new BindGroup()); + bg->m_context = this; + bg->m_layoutRef = ref_rcp(layout); + + // Count dynamic-offset UBOs declared by the layout — authoritative. + uint32_t dynamicCount = 0; + for (const auto& e : layout->entries()) + { + if (e.kind == BindingKind::uniformBuffer && e.hasDynamicOffset) + ++dynamicCount; + } + bg->m_dynamicOffsetCount = dynamicCount; + + // Lazily create the persistent descriptor pool (supports + // VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT so individual sets can + // be freed when the BindGroup is destroyed). + if (m_vkPersistentDescriptorPool == VK_NULL_HANDLE) + { + VkDescriptorPoolSize poolSizes[] = { + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 256}, + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 256}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 256}, + {VK_DESCRIPTOR_TYPE_SAMPLER, 256}, + }; + VkDescriptorPoolCreateInfo ci{ + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO}; + ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + ci.maxSets = 256; + ci.poolSizeCount = 4; + ci.pPoolSizes = poolSizes; + m_vk.CreateDescriptorPool(m_vkDevice, + &ci, + nullptr, + &m_vkPersistentDescriptorPool); + } + + // Allocate a descriptor set from the persistent pool using the layout's + // pre-built VkDescriptorSetLayout. + VkDescriptorSetLayout dsl = layout->m_vkDSL; + VkDescriptorSetAllocateInfo allocInfo{ + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO}; + allocInfo.descriptorPool = m_vkPersistentDescriptorPool; + allocInfo.descriptorSetCount = 1; + allocInfo.pSetLayouts = &dsl; + + VkResult result = m_vk.AllocateDescriptorSets(m_vkDevice, + &allocInfo, + &bg->m_vkDescriptorSet); + if (result != VK_SUCCESS) + { + // Allocation failed — pool may be exhausted. + return nullptr; + } + + // Build VkWriteDescriptorSet entries for each binding. Vulkan binding + // numbers equal WGSL `@binding` directly (Vulkan is per-set namespaced). + // Validate against the layout's entries. + constexpr uint32_t kMaxWrites = 32; + VkWriteDescriptorSet writes[kMaxWrites] = {}; + VkDescriptorBufferInfo bufferInfos[kMaxWrites] = {}; + VkDescriptorImageInfo imageInfos[kMaxWrites] = {}; + uint32_t writeIdx = 0; + uint32_t bufInfoIdx = 0; + uint32_t imgInfoIdx = 0; + + // Resolves the layout's native descriptor binding for a WGSL @binding. + // The SPIR-V emitter compacts sparse @binding's into per-group + // sequential indices; the VkDescriptorSet was built using those + // compacted indices (via createDSLFromLayoutDesc), so dstBinding has + // to match. Falls back to the raw @binding for entries without a + // pre-resolved native slot (forward-compat / non-shader-resolved + // layouts) — matches Dawn's `BindGroupVk.cpp` `dstBinding = + // uint32_t(bindingIndex)` pattern. + auto resolveLayout = [&](uint32_t binding, + BindingKind expected, + uint32_t* outNativeBinding) -> bool { + const BindGroupLayoutEntry* le = layout->findEntry(binding); + if (le == nullptr) + { + setLastError("makeBindGroup: (group=%u, binding=%u) not declared " + "in BindGroupLayout", + groupIndex, + binding); + return false; + } + if (le->kind != expected && + !((le->kind == BindingKind::sampler || + le->kind == BindingKind::comparisonSampler) && + (expected == BindingKind::sampler || + expected == BindingKind::comparisonSampler))) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout kind " + "mismatch", + groupIndex, + binding); + return false; + } + const uint32_t kAbsent = BindGroupLayoutEntry::kNativeSlotAbsent; + *outNativeBinding = (le->nativeSlotVS != kAbsent) ? le->nativeSlotVS + : (le->nativeSlotFS != kAbsent) ? le->nativeSlotFS + : binding; + return true; + }; + + // UBO entries. + for (uint32_t i = 0; i < desc.uboCount; ++i) + { + const auto& ubo = desc.ubos[i]; + uint32_t dstBinding = 0; + if (!resolveLayout(ubo.slot, BindingKind::uniformBuffer, &dstBinding)) + continue; + assert(writeIdx < kMaxWrites && bufInfoIdx < kMaxWrites); + + VkDescriptorBufferInfo& bi = bufferInfos[bufInfoIdx++]; + bi.buffer = ubo.buffer->m_vkBuffer; + bi.offset = ubo.offset; + bi.range = (ubo.size > 0) ? ubo.size : ubo.buffer->size(); + + VkWriteDescriptorSet& w = writes[writeIdx++]; + w.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + w.dstSet = bg->m_vkDescriptorSet; + w.dstBinding = dstBinding; + w.dstArrayElement = 0; + w.descriptorCount = 1; + w.descriptorType = layout->hasDynamicOffset(ubo.slot) + ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC + : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + w.pBufferInfo = &bi; + + bg->m_retainedBuffers.push_back(ref_rcp(ubo.buffer)); + } + + // Texture entries (combined image sampler — imageView only, sampler set + // separately via the sampler bind group). + for (uint32_t i = 0; i < desc.textureCount; ++i) + { + const auto& tex = desc.textures[i]; + uint32_t dstBinding = 0; + if (!resolveLayout(tex.slot, BindingKind::sampledTexture, &dstBinding)) + continue; + assert(writeIdx < kMaxWrites && imgInfoIdx < kMaxWrites); + + // Lazy-init: a renderTarget-capable texture that has never been + // uploaded or used as an attachment is still in + // VK_IMAGE_LAYOUT_UNDEFINED, but the descriptor below claims + // SHADER_READ_ONLY_OPTIMAL. Queue an UNDEFINED → READ_ONLY + // barrier — flushed at beginFrame()/beginRenderPass() before any + // draw can reference this descriptor. Mirrors WebGPU's + // lazy-initialize-on-first-use semantic. The layout is updated + // at flush time, not here, so an intervening upload() still sees + // UNDEFINED and emits the correct upload barrier sequence. + Texture* baseTex = tex.view->texture(); + if (baseTex->m_vkLayout == VK_IMAGE_LAYOUT_UNDEFINED) + { + VkImageAspectFlags aspect = + isDepthStencilFormatLocal(baseTex->format()) + ? (VK_IMAGE_ASPECT_DEPTH_BIT | + (hasStencilLocal(baseTex->format()) + ? VK_IMAGE_ASPECT_STENCIL_BIT + : 0)) + : VK_IMAGE_ASPECT_COLOR_BIT; + m_vkPendingInitialTransitions.push_back({ref_rcp(baseTex), aspect}); + } + + VkDescriptorImageInfo& ii = imageInfos[imgInfoIdx++]; + ii.imageView = tex.view->m_vkImageView; + ii.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + ii.sampler = VK_NULL_HANDLE; // Sampler bound separately. + + VkWriteDescriptorSet& w = writes[writeIdx++]; + w.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + w.dstSet = bg->m_vkDescriptorSet; + w.dstBinding = dstBinding; + w.dstArrayElement = 0; + w.descriptorCount = 1; + w.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + w.pImageInfo = ⅈ + + bg->m_retainedViews.push_back(ref_rcp(tex.view)); + } + + // Sampler entries. + for (uint32_t i = 0; i < desc.samplerCount; ++i) + { + const auto& samp = desc.samplers[i]; + uint32_t dstBinding = 0; + if (!resolveLayout(samp.slot, BindingKind::sampler, &dstBinding)) + continue; + assert(writeIdx < kMaxWrites && imgInfoIdx < kMaxWrites); + + VkDescriptorImageInfo& ii = imageInfos[imgInfoIdx++]; + ii.sampler = samp.sampler->m_vkSampler; + ii.imageView = VK_NULL_HANDLE; + ii.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VkWriteDescriptorSet& w = writes[writeIdx++]; + w.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + w.dstSet = bg->m_vkDescriptorSet; + w.dstBinding = dstBinding; + w.dstArrayElement = 0; + w.descriptorCount = 1; + w.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + w.pImageInfo = ⅈ + + bg->m_retainedSamplers.push_back(ref_rcp(samp.sampler)); + } + + if (writeIdx > 0) + { + m_vk.UpdateDescriptorSets(m_vkDevice, writeIdx, writes, 0, nullptr); + } + + return bg; +} + +// ============================================================================ +// beginRenderPass +// ============================================================================ + +RenderPass ContextVulkan::beginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + finishActiveRenderPass(); + + // Flush lazy-init barriers before we enter the render pass — barriers + // inside a render pass are restricted to declared self-dependencies, + // so any UNDEFINED → SHADER_READ_ONLY_OPTIMAL transitions recorded by + // makeBindGroup must be emitted here. + vkFlushPendingInitialTransitions(); + + RenderPass pass; + pass.m_context = this; + pass.m_vkContext = this; + pass.m_vkCmdBuf = m_vkCommandBuffer; + pass.populateAttachmentMetadata(desc); + + // Build render pass key from the actual load/store ops + formats. + // Attachment layout in `attachViews`: [color × N][resolve × N_resolve] + // [depth?]. Order must match `getOrCreateRenderPass`'s attachment + // layout exactly — the framebuffer's pAttachments and the render + // pass's attachment indices share the same numbering space. + VKRenderPassKey key{}; + key.colorCount = desc.colorCount; + key.sampleCount = 1; + uint32_t passWidth = 0, passHeight = 0; + + VkImageView attachViews[9]{}; // 4 color + 4 resolve + 1 depth + uint32_t attachCount = 0; + VkImageView resolveViews[4]{}; + bool anyResolve = false; + + pass.m_vkColorCount = desc.colorCount; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const ColorAttachment& ca = desc.colorAttachments[i]; + assert(ca.view != nullptr); + Texture* tex = ca.view->texture(); + key.colorFormats[i] = tex->format(); + key.colorLoadOps[i] = ca.loadOp; + key.colorStoreOps[i] = ca.storeOp; + key.colorHasResolve[i] = (ca.resolveTarget != nullptr); + if (key.colorHasResolve[i]) + { + anyResolve = true; + resolveViews[i] = ca.resolveTarget->m_vkImageView; + } + if (key.sampleCount == 1) + key.sampleCount = tex->sampleCount(); + passWidth = tex->width(); + passHeight = tex->height(); + attachViews[attachCount++] = ca.view->m_vkImageView; + // Store image handle, layer range, and render target back-ref for + // finish(). + pass.m_vkColorImages[i] = tex->m_vkImage; + pass.m_vkColorBaseLayer[i] = ca.view->baseLayer(); + pass.m_vkColorLayerCount[i] = ca.view->layerCount(); + pass.m_vkColorRenderTargets[i] = ca.view->m_vkRenderTarget; + } + + // Resolve image views must be appended in the same order as the + // resolveRefs[] array in `getOrCreateRenderPass`. A color attachment + // without a resolve target gets no entry here (the render pass uses + // VK_ATTACHMENT_UNUSED in its place). + if (anyResolve) + { + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + if (key.colorHasResolve[i]) + attachViews[attachCount++] = resolveViews[i]; + } + } + + if (desc.depthStencil.view != nullptr) + { + Texture* dsTex = desc.depthStencil.view->texture(); + key.hasDepth = true; + key.depthFormat = dsTex->format(); + key.depthLoadOp = desc.depthStencil.depthLoadOp; + key.depthStoreOp = desc.depthStencil.depthStoreOp; + attachViews[attachCount++] = desc.depthStencil.view->m_vkImageView; + // Store depth image handle and layer range for finish() barrier. + pass.m_vkDepthImage = dsTex->m_vkImage; + pass.m_vkDepthBaseLayer = desc.depthStencil.view->baseLayer(); + pass.m_vkDepthLayerCount = desc.depthStencil.view->layerCount(); + // Depth-only pass: no color attachments contributed dimensions. + if (passWidth == 0) + { + passWidth = dsTex->width(); + passHeight = dsTex->height(); + } + } + + VkRenderPass renderPass = getOrCreateRenderPass(key); + + // Framebuffer. + VkFramebufferCreateInfo fbCI{}; + fbCI.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + fbCI.renderPass = renderPass; + fbCI.attachmentCount = attachCount; + fbCI.pAttachments = attachViews; + fbCI.width = passWidth; + fbCI.height = passHeight; + fbCI.layers = 1; + m_vk.CreateFramebuffer(m_vkDevice, &fbCI, nullptr, &pass.m_vkFramebuffer); + + // Clear values — must match the attachment ordering that + // `getOrCreateRenderPass` builds: [color × N][resolve × R][depth?]. + // Resolve attachments use loadOp=DONT_CARE so their slots can hold + // any value, but Vulkan still requires `clearValueCount == + // attachmentCount`. + VkClearValue clearValues[9]{}; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const ClearColor& c = desc.colorAttachments[i].clearColor; + clearValues[i].color = {{c.r, c.g, c.b, c.a}}; + } + if (key.hasDepth) + { + // Depth comes after the colors AND the resolve attachments. + uint32_t resolveCount = 0; + if (anyResolve) + { + for (uint32_t i = 0; i < desc.colorCount; ++i) + if (key.colorHasResolve[i]) + ++resolveCount; + } + clearValues[desc.colorCount + resolveCount].depthStencil = { + desc.depthStencil.depthClearValue, + desc.depthStencil.stencilClearValue}; + } + + VkRenderPassBeginInfo rpBI{}; + rpBI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rpBI.renderPass = renderPass; + rpBI.framebuffer = pass.m_vkFramebuffer; + rpBI.renderArea.offset = {0, 0}; + rpBI.renderArea.extent = {passWidth, passHeight}; + rpBI.clearValueCount = attachCount; + rpBI.pClearValues = clearValues; + + m_vk.CmdBeginRenderPass(m_vkCommandBuffer, + &rpBI, + VK_SUBPASS_CONTENTS_INLINE); + + return pass; +} + +// ============================================================================ +// wrapCanvasTexture +// ============================================================================ + +rcp ContextVulkan::wrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + assert(canvas != nullptr); + + auto* vkTarget = + static_cast(canvas->renderTarget()); + + VkImage image = vkTarget->targetImage(); + VkImageView imageView = vkTarget->targetImageView(); + if (image == VK_NULL_HANDLE || imageView == VK_NULL_HANDLE) + return nullptr; + + // Derive the ore format from the actual Vulkan surface format so any MSAA + // texture created from this descriptor matches the resolve target exactly + // (Vulkan requires identical formats for MSAA resolve). + auto vkFmt = vkTarget->framebufferFormat(); + TextureFormat oreFormat; + switch (vkFmt) + { + case VK_FORMAT_B8G8R8A8_UNORM: + oreFormat = TextureFormat::bgra8unorm; + break; + case VK_FORMAT_R16G16B16A16_SFLOAT: + oreFormat = TextureFormat::rgba16float; + break; + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + oreFormat = TextureFormat::rgb10a2unorm; + break; + default: + oreFormat = TextureFormat::rgba8unorm; + break; + } + + TextureDesc texDesc{}; + texDesc.width = canvas->width(); + texDesc.height = canvas->height(); + texDesc.format = oreFormat; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = true; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + // Borrow the VkImage — the RenderCanvas owns it. + auto texture = rcp(new Texture(texDesc)); + texture->m_vkImage = image; + // Mark as not VMA-owned so onRefCntReachedZero skips the VMA free. + texture->m_vmaAllocation = VK_NULL_HANDLE; + texture->m_vkLayout = VK_IMAGE_LAYOUT_UNDEFINED; + // No destroy pointers needed — caller (canvas) owns the image lifetime. + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_vkImageView = imageView; + view->m_vkOreContext = this; + // No destroy pointer — caller owns the image view lifetime. + // Store the back-ref so RenderPass::finish() can update Rive's layout + // tracking after the Ore render pass transitions the image. + view->m_vkRenderTarget = vkTarget; + + return view; +} + +rcp ContextVulkan::wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + if (!gpuTex) + return nullptr; + + // On Vulkan, gpu::Texture is vkutil::Texture2D. + auto* vkTex = static_cast(gpuTex); + VkImage image = vkTex->vkImage(); + VkImageView imageView = vkTex->vkImageView(); + if (image == VK_NULL_HANDLE || imageView == VK_NULL_HANDLE) + return nullptr; + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = TextureFormat::rgba8unorm; // Images are decoded to RGBA8. + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = false; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + // Transition the Rive-owned image to SHADER_READ_ONLY_OPTIMAL in the + // current command buffer so Ore can sample it. Requires an open frame + // CB — in external-CB mode this lands in the host's CB (same submission + // as Rive's writes), which is the only way this works correctly for the + // Rive-writes → Ore-reads direction. Rive's lastAccess tracker is + // updated by barrier() so Rive's subsequent uses stay consistent. + assert(m_vkCommandBuffer != VK_NULL_HANDLE && + "wrapRiveTexture requires an open frame: call beginFrame() first"); + vkTex->prepareForFragmentShaderRead(m_vkCommandBuffer); + + auto texture = rcp(new Texture(texDesc)); + texture->m_vkImage = image; + texture->m_vmaAllocation = VK_NULL_HANDLE; // Borrowed, not VMA-owned. + texture->m_vkLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_vkImageView = imageView; + view->m_vkOreContext = this; + return view; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_pipeline_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_pipeline_vulkan.cpp new file mode 100644 index 000000000..2dfb5efc8 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_pipeline_vulkan.cpp @@ -0,0 +1,593 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/rive_types.hpp" +#include "ore_vulkan_dsl.hpp" + +#include + +namespace rive::ore +{ + +// hasStencilLocal() is also defined as `static` in ore_context_vulkan.cpp; +// each definition is TU-local so they coexist without a link conflict. +static bool hasStencilLocal(TextureFormat fmt) +{ + return fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32floatStencil8; +} + +// ============================================================================ +// Enum → Vulkan conversion helpers +// ============================================================================ + +static VkFormat oreVertexFormatToVk(VertexFormat fmt) +{ + switch (fmt) + { + case VertexFormat::float1: + return VK_FORMAT_R32_SFLOAT; + case VertexFormat::float2: + return VK_FORMAT_R32G32_SFLOAT; + case VertexFormat::float3: + return VK_FORMAT_R32G32B32_SFLOAT; + case VertexFormat::float4: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case VertexFormat::uint8x4: + return VK_FORMAT_R8G8B8A8_UINT; + case VertexFormat::sint8x4: + return VK_FORMAT_R8G8B8A8_SINT; + case VertexFormat::unorm8x4: + return VK_FORMAT_R8G8B8A8_UNORM; + case VertexFormat::snorm8x4: + return VK_FORMAT_R8G8B8A8_SNORM; + case VertexFormat::uint16x2: + return VK_FORMAT_R16G16_UINT; + case VertexFormat::sint16x2: + return VK_FORMAT_R16G16_SINT; + case VertexFormat::unorm16x2: + return VK_FORMAT_R16G16_UNORM; + case VertexFormat::snorm16x2: + return VK_FORMAT_R16G16_SNORM; + case VertexFormat::uint16x4: + return VK_FORMAT_R16G16B16A16_UINT; + case VertexFormat::sint16x4: + return VK_FORMAT_R16G16B16A16_SINT; + case VertexFormat::float16x2: + return VK_FORMAT_R16G16_SFLOAT; + case VertexFormat::float16x4: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case VertexFormat::uint32: + return VK_FORMAT_R32_UINT; + case VertexFormat::uint32x2: + return VK_FORMAT_R32G32_UINT; + case VertexFormat::uint32x3: + return VK_FORMAT_R32G32B32_UINT; + case VertexFormat::uint32x4: + return VK_FORMAT_R32G32B32A32_UINT; + case VertexFormat::sint32: + return VK_FORMAT_R32_SINT; + case VertexFormat::sint32x2: + return VK_FORMAT_R32G32_SINT; + case VertexFormat::sint32x3: + return VK_FORMAT_R32G32B32_SINT; + case VertexFormat::sint32x4: + return VK_FORMAT_R32G32B32A32_SINT; + } + RIVE_UNREACHABLE(); +} + +static VkPrimitiveTopology oreTopologyToVk(PrimitiveTopology t) +{ + switch (t) + { + case PrimitiveTopology::pointList: + return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + case PrimitiveTopology::lineList: + return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + case PrimitiveTopology::lineStrip: + return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; + case PrimitiveTopology::triangleList: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + case PrimitiveTopology::triangleStrip: + return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + } + RIVE_UNREACHABLE(); +} + +static VkCullModeFlags oreCullModeToVk(CullMode c) +{ + switch (c) + { + case CullMode::none: + return VK_CULL_MODE_NONE; + case CullMode::front: + return VK_CULL_MODE_FRONT_BIT; + case CullMode::back: + return VK_CULL_MODE_BACK_BIT; + } + RIVE_UNREACHABLE(); +} + +static VkFrontFace oreWindingToVk(FaceWinding w) +{ + // Vulkan's default is counter-clockwise = front. + return (w == FaceWinding::counterClockwise) + ? VK_FRONT_FACE_COUNTER_CLOCKWISE + : VK_FRONT_FACE_CLOCKWISE; +} + +static VkBlendFactor oreBlendFactorToVk(BlendFactor f) +{ + switch (f) + { + case BlendFactor::zero: + return VK_BLEND_FACTOR_ZERO; + case BlendFactor::one: + return VK_BLEND_FACTOR_ONE; + case BlendFactor::srcColor: + return VK_BLEND_FACTOR_SRC_COLOR; + case BlendFactor::oneMinusSrcColor: + return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + case BlendFactor::srcAlpha: + return VK_BLEND_FACTOR_SRC_ALPHA; + case BlendFactor::oneMinusSrcAlpha: + return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + case BlendFactor::dstColor: + return VK_BLEND_FACTOR_DST_COLOR; + case BlendFactor::oneMinusDstColor: + return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; + case BlendFactor::dstAlpha: + return VK_BLEND_FACTOR_DST_ALPHA; + case BlendFactor::oneMinusDstAlpha: + return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; + case BlendFactor::srcAlphaSaturated: + return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; + case BlendFactor::blendColor: + return VK_BLEND_FACTOR_CONSTANT_COLOR; + case BlendFactor::oneMinusBlendColor: + return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; + } + RIVE_UNREACHABLE(); +} + +static VkBlendOp oreBlendOpToVk(BlendOp op) +{ + switch (op) + { + case BlendOp::add: + return VK_BLEND_OP_ADD; + case BlendOp::subtract: + return VK_BLEND_OP_SUBTRACT; + case BlendOp::reverseSubtract: + return VK_BLEND_OP_REVERSE_SUBTRACT; + case BlendOp::min: + return VK_BLEND_OP_MIN; + case BlendOp::max: + return VK_BLEND_OP_MAX; + } + RIVE_UNREACHABLE(); +} + +static VkColorComponentFlags oreColorWriteMaskToVk(ColorWriteMask mask) +{ + VkColorComponentFlags result = 0; + if ((mask & ColorWriteMask::red) != ColorWriteMask::none) + result |= VK_COLOR_COMPONENT_R_BIT; + if ((mask & ColorWriteMask::green) != ColorWriteMask::none) + result |= VK_COLOR_COMPONENT_G_BIT; + if ((mask & ColorWriteMask::blue) != ColorWriteMask::none) + result |= VK_COLOR_COMPONENT_B_BIT; + if ((mask & ColorWriteMask::alpha) != ColorWriteMask::none) + result |= VK_COLOR_COMPONENT_A_BIT; + return result; +} + +static VkCompareOp oreCompareFuncToVk(CompareFunction f) +{ + switch (f) + { + case CompareFunction::none: + case CompareFunction::always: + return VK_COMPARE_OP_ALWAYS; + case CompareFunction::never: + return VK_COMPARE_OP_NEVER; + case CompareFunction::less: + return VK_COMPARE_OP_LESS; + case CompareFunction::equal: + return VK_COMPARE_OP_EQUAL; + case CompareFunction::lessEqual: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case CompareFunction::greater: + return VK_COMPARE_OP_GREATER; + case CompareFunction::notEqual: + return VK_COMPARE_OP_NOT_EQUAL; + case CompareFunction::greaterEqual: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + } + RIVE_UNREACHABLE(); +} + +static VkStencilOp oreStencilOpToVk(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return VK_STENCIL_OP_KEEP; + case StencilOp::zero: + return VK_STENCIL_OP_ZERO; + case StencilOp::replace: + return VK_STENCIL_OP_REPLACE; + case StencilOp::incrementClamp: + return VK_STENCIL_OP_INCREMENT_AND_CLAMP; + case StencilOp::decrementClamp: + return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case StencilOp::invert: + return VK_STENCIL_OP_INVERT; + case StencilOp::incrementWrap: + return VK_STENCIL_OP_INCREMENT_AND_WRAP; + case StencilOp::decrementWrap: + return VK_STENCIL_OP_DECREMENT_AND_WRAP; + } + RIVE_UNREACHABLE(); +} + +static VkStencilOpState oreStencilFaceToVk(const StencilFaceState& s, + uint8_t readMask, + uint8_t writeMask) +{ + VkStencilOpState state{}; + state.failOp = oreStencilOpToVk(s.failOp); + state.passOp = oreStencilOpToVk(s.passOp); + state.depthFailOp = oreStencilOpToVk(s.depthFailOp); + state.compareOp = oreCompareFuncToVk(s.compare); + state.compareMask = readMask; + state.writeMask = writeMask; + state.reference = 0; // Dynamic state — set via vkCmdSetStencilReference. + return state; +} + +// ============================================================================ +// Pipeline::onRefCntReachedZero +// +// Phase E: per-group VkDescriptorSetLayouts are now owned by BindGroupLayout +// objects (referenced by m_layouts[]). Pipeline only destroys its own +// VkPipeline + VkPipelineLayout; DSL teardown is handled by +// BindGroupLayout::onRefCntReachedZero when its rcp drops. +// ============================================================================ + +#if !defined(ORE_BACKEND_GL) + +void Pipeline::onRefCntReachedZero() const +{ + VkDevice dev = m_vkDevice; + VkPipeline pipe = m_vkPipeline; + VkPipelineLayout layout = m_vkPipelineLayout; + auto destroyPipe = m_vkDestroyPipeline; + auto destroyLayout = m_vkDestroyPipelineLayout; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (pipe != VK_NULL_HANDLE && destroyPipe != nullptr) + destroyPipe(dev, pipe, nullptr); + if (layout != VK_NULL_HANDLE && destroyLayout != nullptr) + destroyLayout(dev, layout, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// BindGroupLayout::onRefCntReachedZero (Vulkan) +// ============================================================================ + +void BindGroupLayout::onRefCntReachedZero() const +{ + VkDevice dev = m_vkDevice; + VkDescriptorSetLayout dsl = m_vkDSL; + auto destroyDSL = m_vkDestroyDescriptorSetLayout; + ContextVulkan* ctx = static_cast(m_context); + + auto destroy = [=]() { + if (dsl != VK_NULL_HANDLE && destroyDSL != nullptr) + destroyDSL(dev, dsl, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // !ORE_BACKEND_GL — resource onRefCntReachedZero defs + +// ============================================================================ +// ContextVulkan::makePipeline — called from ore_context_vulkan.cpp. +// Always compiled when ORE_BACKEND_VK is defined (regardless of GL coexist), +// because the per-backend ContextVulkan vtable requires this body. +// ============================================================================ + +rcp ContextVulkan::makePipeline(const PipelineDesc& desc, + std::string* outError) +{ + auto pipeline = rcp(new Pipeline(desc)); + pipeline->m_vkDevice = m_vkDevice; + pipeline->m_vkOreContext = this; + pipeline->m_vkTopology = oreTopologyToVk(desc.topology); + + // --- Validate user-supplied layouts against shader binding map --- + { + std::string err; + if (!validateLayoutsAgainstBindingMap(pipeline->m_bindingMap, + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + &err) || + !validateColorRequiresFragment(desc.colorCount, + desc.fragmentModule != nullptr, + &err)) + { + if (outError) + *outError = err; + else + setLastError("makePipeline: %s", err.c_str()); + return nullptr; + } + } + + // --- Pipeline layout — composed from user-supplied BGLs --- + // Vulkan spec (VUID-VkPipelineLayoutCreateInfo- + // graphicsPipelineLibrary-06753) requires every pSetLayouts entry to + // be a valid handle. Null slots get the shared empty DSL. + VkDescriptorSetLayout dsls[kVkMaxGroups] = {}; + VkDescriptorSetLayout emptyDSL = VK_NULL_HANDLE; + for (uint32_t g = 0; g < desc.bindGroupLayoutCount && g < kVkMaxGroups; ++g) + { + if (desc.bindGroupLayouts[g] != nullptr) + { + dsls[g] = desc.bindGroupLayouts[g]->m_vkDSL; + } + else + { + if (emptyDSL == VK_NULL_HANDLE) + emptyDSL = vkGetOrCreateEmptyDSL(); + dsls[g] = emptyDSL; + } + } + VkPipelineLayoutCreateInfo layoutCI{}; + layoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layoutCI.setLayoutCount = desc.bindGroupLayoutCount; + layoutCI.pSetLayouts = desc.bindGroupLayoutCount > 0 ? dsls : nullptr; + m_vk.CreatePipelineLayout(m_vkDevice, + &layoutCI, + nullptr, + &pipeline->m_vkPipelineLayout); + pipeline->m_vkDestroyPipelineLayout = m_vk.DestroyPipelineLayout; + + // --- Shader stages --- (depth-only pipelines omit the fragment stage) + VkPipelineShaderStageCreateInfo stages[2]{}; + stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stages[0].module = desc.vertexModule->m_vkShaderModule; + stages[0].pName = desc.vertexEntryPoint; + + uint32_t stageCount = 1; + if (desc.fragmentModule != nullptr) + { + stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stages[1].module = desc.fragmentModule->m_vkShaderModule; + stages[1].pName = desc.fragmentEntryPoint; + stageCount = 2; + } + + // --- Vertex input --- + constexpr uint32_t kMaxBindings = 8; + constexpr uint32_t kMaxAttribs = 32; + VkVertexInputBindingDescription bindings[kMaxBindings]; + VkVertexInputAttributeDescription attribs[kMaxAttribs]; + uint32_t attribIdx = 0; + + for (uint32_t b = 0; b < desc.vertexBufferCount; ++b) + { + const VertexBufferLayout& layout = desc.vertexBuffers[b]; + bindings[b].binding = b; + bindings[b].stride = layout.stride; + bindings[b].inputRate = (layout.stepMode == VertexStepMode::instance) + ? VK_VERTEX_INPUT_RATE_INSTANCE + : VK_VERTEX_INPUT_RATE_VERTEX; + for (uint32_t a = 0; a < layout.attributeCount; ++a) + { + assert(attribIdx < kMaxAttribs); + const VertexAttribute& attr = layout.attributes[a]; + attribs[attribIdx].location = attr.shaderSlot; + attribs[attribIdx].binding = b; + attribs[attribIdx].format = oreVertexFormatToVk(attr.format); + attribs[attribIdx].offset = attr.offset; + ++attribIdx; + } + } + + VkPipelineVertexInputStateCreateInfo vertexInput{}; + vertexInput.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInput.vertexBindingDescriptionCount = desc.vertexBufferCount; + vertexInput.pVertexBindingDescriptions = bindings; + vertexInput.vertexAttributeDescriptionCount = attribIdx; + vertexInput.pVertexAttributeDescriptions = attribs; + + // --- Input assembly --- + VkPipelineInputAssemblyStateCreateInfo inputAssembly{}; + inputAssembly.sType = + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssembly.topology = pipeline->m_vkTopology; + inputAssembly.primitiveRestartEnable = VK_FALSE; + + // --- Viewport / scissor (dynamic) --- + VkPipelineViewportStateCreateInfo viewportState{}; + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewportState.viewportCount = 1; + viewportState.scissorCount = 1; + + // --- Rasterization --- + VkPipelineRasterizationStateCreateInfo raster{}; + raster.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + raster.polygonMode = VK_POLYGON_MODE_FILL; + raster.cullMode = oreCullModeToVk(desc.cullMode); + raster.frontFace = oreWindingToVk(desc.winding); + raster.lineWidth = 1.0f; + if (desc.depthStencil.depthBias != 0 || + desc.depthStencil.depthBiasSlopeScale != 0.0f) + { + raster.depthBiasEnable = VK_TRUE; + raster.depthBiasConstantFactor = + static_cast(desc.depthStencil.depthBias); + raster.depthBiasSlopeFactor = desc.depthStencil.depthBiasSlopeScale; + raster.depthBiasClamp = desc.depthStencil.depthBiasClamp; + } + + // --- Multisample --- + VkPipelineMultisampleStateCreateInfo multisample{}; + multisample.sType = + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + multisample.rasterizationSamples = + static_cast(desc.sampleCount); + + // --- Depth / stencil --- + // Use rgba8unorm as a sentinel for "no depth/stencil attachment". + // Vulkan forbids enabling depth/stencil test when the render pass has no + // depth/stencil attachment + // (VUID-VkGraphicsPipelineCreateInfo-renderPass-07752). + const bool hasDepthStencil = + (desc.depthStencil.format != TextureFormat::rgba8unorm); + + VkPipelineDepthStencilStateCreateInfo depthStencil{}; + depthStencil.sType = + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + depthStencil.depthTestEnable = + (hasDepthStencil && + desc.depthStencil.depthCompare != CompareFunction::always) + ? VK_TRUE + : VK_FALSE; + depthStencil.depthWriteEnable = + (hasDepthStencil && desc.depthStencil.depthWriteEnabled) ? VK_TRUE + : VK_FALSE; + depthStencil.depthCompareOp = + oreCompareFuncToVk(desc.depthStencil.depthCompare); + depthStencil.stencilTestEnable = + hasDepthStencil && hasStencilLocal(desc.depthStencil.format) ? VK_TRUE + : VK_FALSE; + depthStencil.front = oreStencilFaceToVk(desc.stencilFront, + desc.stencilReadMask, + desc.stencilWriteMask); + depthStencil.back = oreStencilFaceToVk(desc.stencilBack, + desc.stencilReadMask, + desc.stencilWriteMask); + + // --- Color blend --- + VkPipelineColorBlendAttachmentState blendAttachments[4]{}; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const ColorTargetState& ct = desc.colorTargets[i]; + VkPipelineColorBlendAttachmentState& ba = blendAttachments[i]; + ba.colorWriteMask = oreColorWriteMaskToVk(ct.writeMask); + ba.blendEnable = ct.blendEnabled ? VK_TRUE : VK_FALSE; + if (ct.blendEnabled) + { + ba.srcColorBlendFactor = oreBlendFactorToVk(ct.blend.srcColor); + ba.dstColorBlendFactor = oreBlendFactorToVk(ct.blend.dstColor); + ba.colorBlendOp = oreBlendOpToVk(ct.blend.colorOp); + ba.srcAlphaBlendFactor = oreBlendFactorToVk(ct.blend.srcAlpha); + ba.dstAlphaBlendFactor = oreBlendFactorToVk(ct.blend.dstAlpha); + ba.alphaBlendOp = oreBlendOpToVk(ct.blend.alphaOp); + } + } + + VkPipelineColorBlendStateCreateInfo colorBlend{}; + colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlend.attachmentCount = desc.colorCount; + colorBlend.pAttachments = blendAttachments; + + // --- Dynamic state --- + constexpr VkDynamicState kDynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_BLEND_CONSTANTS, + }; + VkPipelineDynamicStateCreateInfo dynamicState{}; + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.dynamicStateCount = static_cast( + sizeof(kDynamicStates) / sizeof(kDynamicStates[0])); + dynamicState.pDynamicStates = kDynamicStates; + + // --- Render pass (format-only, DONT_CARE ops for pipeline compatibility) + // --- Build a VKRenderPassKey from the pipeline's color/depth formats. + struct VKRenderPassKey key{}; + key.colorCount = desc.colorCount; + key.sampleCount = desc.sampleCount; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + key.colorFormats[i] = desc.colorTargets[i].format; + key.colorLoadOps[i] = LoadOp::dontCare; + key.colorStoreOps[i] = StoreOp::discard; + } + if (desc.depthStencil.format != TextureFormat::rgba8unorm) + { + key.depthFormat = desc.depthStencil.format; + key.depthLoadOp = LoadOp::dontCare; + key.depthStoreOp = StoreOp::discard; + key.hasDepth = true; + } + + VkRenderPass compatRenderPass = getOrCreateRenderPass(key); + + // --- Assemble VkGraphicsPipelineCreateInfo --- + // pColorBlendState must be nullptr for depth-only pipelines per Dawn's + // pattern; otherwise validation flags an unused blend state. + VkGraphicsPipelineCreateInfo pipelineCI{}; + pipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineCI.stageCount = stageCount; + pipelineCI.pStages = stages; + pipelineCI.pVertexInputState = &vertexInput; + pipelineCI.pInputAssemblyState = &inputAssembly; + pipelineCI.pViewportState = &viewportState; + pipelineCI.pRasterizationState = &raster; + pipelineCI.pMultisampleState = &multisample; + pipelineCI.pDepthStencilState = &depthStencil; + pipelineCI.pColorBlendState = + (desc.fragmentModule != nullptr) ? &colorBlend : nullptr; + pipelineCI.pDynamicState = &dynamicState; + pipelineCI.layout = pipeline->m_vkPipelineLayout; + pipelineCI.renderPass = compatRenderPass; + pipelineCI.subpass = 0; + + VkResult vkr = m_vk.CreateGraphicsPipelines(m_vkDevice, + VK_NULL_HANDLE, + 1, + &pipelineCI, + nullptr, + &pipeline->m_vkPipeline); + if (vkr != VK_SUCCESS) + { + setLastError("Ore Vulkan: vkCreateGraphicsPipelines failed (%d)", vkr); + if (outError) + *outError = m_lastError; + return nullptr; + } + pipeline->m_vkDestroyPipeline = m_vk.DestroyPipeline; + + return pipeline; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vk_gl.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vk_gl.cpp new file mode 100644 index 000000000..466e40d23 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vk_gl.cpp @@ -0,0 +1,796 @@ +/* + * Copyright 2025 Rive + */ + +// Combined VK + GL RenderPass implementation for dual-backend builds. +// Compiled when both ORE_BACKEND_VK and ORE_BACKEND_GL are active. +// Provides all RenderPass method definitions with runtime dispatch: +// passes initialized via the Vulkan context path (m_vkContext != nullptr) use +// Vulkan; passes initialized via the GL context path (m_context != nullptr) +// use GL. + +#if defined(ORE_BACKEND_VK) && defined(ORE_BACKEND_GL) + +// Pull in VK static helpers (layout transitions, etc.). +// The !defined(ORE_BACKEND_GL) guard in ore_render_pass_vulkan.cpp excludes +// RenderPass method bodies, so we get only the static helper functions. +#include "ore_render_pass_vulkan.cpp" + +// Pull in GL static helpers (oreTopologyToGL, oreBlendFactorToGL, etc.). +// The !defined(ORE_BACKEND_METAL) && !defined(ORE_BACKEND_VK) guard in +// ore_render_pass_gl.cpp excludes RenderPass method bodies, so we get only +// the static helper functions. +#include "../gl/ore_render_pass_gl.cpp" + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" // for RenderPass inline bodies + +namespace rive::ore +{ + +RenderPass::~RenderPass() +{ + if (!m_finished) + { + if (m_vkContext != nullptr || m_context != nullptr) + finish(); + } +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + m_currentPipeline(std::move(other.m_currentPipeline)), + // VK members + m_vkContext(other.m_vkContext), + m_vkCmdBuf(other.m_vkCmdBuf), + m_vkFramebuffer(other.m_vkFramebuffer), + m_vkIndexBuffer(other.m_vkIndexBuffer), + m_vkIndexType(other.m_vkIndexType), + m_vkIndexOffset(other.m_vkIndexOffset), + m_vkColorCount(other.m_vkColorCount), + m_vkDepthImage(other.m_vkDepthImage), + m_vkDepthBaseLayer(other.m_vkDepthBaseLayer), + m_vkDepthLayerCount(other.m_vkDepthLayerCount), + // GL members + m_glFBO(other.m_glFBO), + m_glVAO(other.m_glVAO), + m_prevVAO(other.m_prevVAO), + m_prevFBO(other.m_prevFBO), + m_ownsFBO(other.m_ownsFBO), + m_ownsVAO(other.m_ownsVAO), + m_viewportWidth(other.m_viewportWidth), + m_viewportHeight(other.m_viewportHeight), + m_maxSamplerSlot(other.m_maxSamplerSlot), + m_maxAttribSlot(other.m_maxAttribSlot), + m_usedSamplers(other.m_usedSamplers), + m_usedAttribs(other.m_usedAttribs), + m_glIndexFormat(other.m_glIndexFormat), + m_glResolveCount(other.m_glResolveCount) +{ + moveCrossBackendFieldsFrom(other); + // VK arrays + memcpy(m_vkColorImages, other.m_vkColorImages, sizeof(m_vkColorImages)); + memcpy(m_vkColorBaseLayer, + other.m_vkColorBaseLayer, + sizeof(m_vkColorBaseLayer)); + memcpy(m_vkColorLayerCount, + other.m_vkColorLayerCount, + sizeof(m_vkColorLayerCount)); + memcpy(m_vkColorRenderTargets, + other.m_vkColorRenderTargets, + sizeof(m_vkColorRenderTargets)); + // GL resolve array + for (uint32_t i = 0; i < m_glResolveCount; ++i) + m_glResolves[i] = other.m_glResolves[i]; + other.m_vkContext = nullptr; + other.m_vkFramebuffer = VK_NULL_HANDLE; + other.m_ownsFBO = false; + other.m_ownsVAO = false; + other.m_glResolveCount = 0; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && (m_vkContext != nullptr || m_context != nullptr)) + finish(); + moveCrossBackendFieldsFrom(other); + m_currentPipeline = std::move(other.m_currentPipeline); + // VK members + m_vkContext = other.m_vkContext; + m_vkCmdBuf = other.m_vkCmdBuf; + m_vkFramebuffer = other.m_vkFramebuffer; + m_vkIndexBuffer = other.m_vkIndexBuffer; + m_vkIndexType = other.m_vkIndexType; + m_vkIndexOffset = other.m_vkIndexOffset; + memcpy(m_vkColorImages, other.m_vkColorImages, sizeof(m_vkColorImages)); + memcpy(m_vkColorBaseLayer, + other.m_vkColorBaseLayer, + sizeof(m_vkColorBaseLayer)); + memcpy(m_vkColorLayerCount, + other.m_vkColorLayerCount, + sizeof(m_vkColorLayerCount)); + m_vkColorCount = other.m_vkColorCount; + memcpy(m_vkColorRenderTargets, + other.m_vkColorRenderTargets, + sizeof(m_vkColorRenderTargets)); + m_vkDepthImage = other.m_vkDepthImage; + m_vkDepthBaseLayer = other.m_vkDepthBaseLayer; + m_vkDepthLayerCount = other.m_vkDepthLayerCount; + // GL members + m_glFBO = other.m_glFBO; + m_glVAO = other.m_glVAO; + m_prevVAO = other.m_prevVAO; + m_prevFBO = other.m_prevFBO; + m_ownsFBO = other.m_ownsFBO; + m_ownsVAO = other.m_ownsVAO; + m_viewportWidth = other.m_viewportWidth; + m_viewportHeight = other.m_viewportHeight; + m_maxSamplerSlot = other.m_maxSamplerSlot; + m_maxAttribSlot = other.m_maxAttribSlot; + m_usedSamplers = other.m_usedSamplers; + m_usedAttribs = other.m_usedAttribs; + m_glIndexFormat = other.m_glIndexFormat; + m_glResolveCount = other.m_glResolveCount; + for (uint32_t i = 0; i < m_glResolveCount; ++i) + m_glResolves[i] = other.m_glResolves[i]; + other.m_vkContext = nullptr; + other.m_vkFramebuffer = VK_NULL_HANDLE; + other.m_ownsFBO = false; + other.m_ownsVAO = false; + other.m_glResolveCount = 0; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_vkContext != nullptr || m_context != nullptr); +} + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + if (m_vkContext != nullptr) + { + m_currentPipeline = ref_rcp(pipeline); + m_vkContext->m_vk.CmdBindPipeline(m_vkCmdBuf, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline->m_vkPipeline); + return; + } + + // GL path. + m_currentPipeline = ref_rcp(pipeline); + const auto& desc = pipeline->desc(); + glUseProgram(pipeline->m_glProgram); + + if (desc.cullMode == CullMode::none) + { + glDisable(GL_CULL_FACE); + } + else + { + glEnable(GL_CULL_FACE); + glCullFace(desc.cullMode == CullMode::front ? GL_FRONT : GL_BACK); + } + + glFrontFace(desc.winding == FaceWinding::counterClockwise ? GL_CCW : GL_CW); + + if (desc.depthStencil.depthCompare != CompareFunction::always || + desc.depthStencil.depthWriteEnabled) + { + glEnable(GL_DEPTH_TEST); + glDepthFunc(oreCompareFunctionToGL(desc.depthStencil.depthCompare)); + glDepthMask(desc.depthStencil.depthWriteEnabled ? GL_TRUE : GL_FALSE); + } + else + { + glDisable(GL_DEPTH_TEST); + } + + if (desc.depthStencil.depthBias != 0 || + desc.depthStencil.depthBiasSlopeScale != 0.0f) + { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(desc.depthStencil.depthBiasSlopeScale, + static_cast(desc.depthStencil.depthBias)); + } + else + { + glDisable(GL_POLYGON_OFFSET_FILL); + } + + bool hasStencil = (desc.stencilFront.compare != CompareFunction::always || + desc.stencilFront.failOp != StencilOp::keep || + desc.stencilFront.depthFailOp != StencilOp::keep || + desc.stencilFront.passOp != StencilOp::keep || + desc.stencilBack.compare != CompareFunction::always || + desc.stencilBack.failOp != StencilOp::keep || + desc.stencilBack.depthFailOp != StencilOp::keep || + desc.stencilBack.passOp != StencilOp::keep); + + if (hasStencil) + { + glEnable(GL_STENCIL_TEST); + glStencilMaskSeparate(GL_FRONT, desc.stencilWriteMask); + glStencilMaskSeparate(GL_BACK, desc.stencilWriteMask); + glStencilFuncSeparate(GL_FRONT, + oreCompareFunctionToGL(desc.stencilFront.compare), + static_cast(m_glStencilRef), + desc.stencilReadMask); + glStencilFuncSeparate(GL_BACK, + oreCompareFunctionToGL(desc.stencilBack.compare), + static_cast(m_glStencilRef), + desc.stencilReadMask); + glStencilOpSeparate(GL_FRONT, + oreStencilOpToGL(desc.stencilFront.failOp), + oreStencilOpToGL(desc.stencilFront.depthFailOp), + oreStencilOpToGL(desc.stencilFront.passOp)); + glStencilOpSeparate(GL_BACK, + oreStencilOpToGL(desc.stencilBack.failOp), + oreStencilOpToGL(desc.stencilBack.depthFailOp), + oreStencilOpToGL(desc.stencilBack.passOp)); + } + else + { + glDisable(GL_STENCIL_TEST); + } + + if (desc.colorCount > 0 && desc.colorTargets[0].blendEnabled) + { + glEnable(GL_BLEND); + const auto& b = desc.colorTargets[0].blend; + glBlendFuncSeparate(oreBlendFactorToGL(b.srcColor), + oreBlendFactorToGL(b.dstColor), + oreBlendFactorToGL(b.srcAlpha), + oreBlendFactorToGL(b.dstAlpha)); + glBlendEquationSeparate(oreBlendOpToGL(b.colorOp), + oreBlendOpToGL(b.alphaOp)); + } + else + { + glDisable(GL_BLEND); + } + + if (desc.colorCount > 0) + { + auto mask = desc.colorTargets[0].writeMask; + glColorMask((mask & ColorWriteMask::red) != ColorWriteMask::none, + (mask & ColorWriteMask::green) != ColorWriteMask::none, + (mask & ColorWriteMask::blue) != ColorWriteMask::none, + (mask & ColorWriteMask::alpha) != ColorWriteMask::none); + } +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + if (m_vkContext != nullptr) + { + VkDeviceSize vkOffset = offset; + m_vkContext->m_vk.CmdBindVertexBuffers(m_vkCmdBuf, + slot, + 1, + &buffer->m_vkBuffer, + &vkOffset); + return; + } + + // GL path. + assert(m_currentPipeline != nullptr && "setPipeline must be called first"); + assert(slot < m_currentPipeline->desc().vertexBufferCount); + + const auto& layout = m_currentPipeline->desc().vertexBuffers[slot]; + glBindBuffer(GL_ARRAY_BUFFER, buffer->m_glBuffer); + + for (uint32_t i = 0; i < layout.attributeCount; ++i) + { + const auto& attr = layout.attributes[i]; + GLVertexInfo info = oreVertexFormatToGL(attr.format); + glEnableVertexAttribArray(attr.shaderSlot); + + bool isIntType = + (info.type == GL_UNSIGNED_INT || info.type == GL_INT || + info.type == GL_UNSIGNED_BYTE || info.type == GL_BYTE || + info.type == GL_UNSIGNED_SHORT || info.type == GL_SHORT) && + !info.normalized; + + if (isIntType) + { + glVertexAttribIPointer( + attr.shaderSlot, + info.count, + info.type, + layout.stride, + reinterpret_cast( + static_cast(attr.offset + offset))); + } + else + { + glVertexAttribPointer( + attr.shaderSlot, + info.count, + info.type, + info.normalized, + layout.stride, + reinterpret_cast( + static_cast(attr.offset + offset))); + } + + if (layout.stepMode == VertexStepMode::instance) + glVertexAttribDivisor(attr.shaderSlot, 1); + else + glVertexAttribDivisor(attr.shaderSlot, 0); + + if (!m_usedAttribs || attr.shaderSlot > m_maxAttribSlot) + m_maxAttribSlot = attr.shaderSlot; + m_usedAttribs = true; + } +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + if (m_vkContext != nullptr) + { + m_vkIndexBuffer = buffer->m_vkBuffer; + m_vkIndexType = (format == IndexFormat::uint32) ? VK_INDEX_TYPE_UINT32 + : VK_INDEX_TYPE_UINT16; + m_vkIndexOffset = offset; + m_vkContext->m_vk.CmdBindIndexBuffer(m_vkCmdBuf, + buffer->m_vkBuffer, + offset, + m_vkIndexType); + return; + } + + // GL path. + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->m_glBuffer); + m_glIndexFormat = format; + (void)offset; +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + m_boundGroups[groupIndex] = ref_rcp(bg); + + if (m_vkContext != nullptr) + { + assert(bg != nullptr); + assert(m_currentPipeline != nullptr && + "setPipeline must be called before setBindGroup"); + + m_vkContext->m_vk.CmdBindDescriptorSets( + m_vkCmdBuf, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_currentPipeline->m_vkPipelineLayout, + groupIndex, + 1, + &bg->m_vkDescriptorSet, + dynamicOffsetCount, + dynamicOffsets); + return; + } + + // GL path. + (void)groupIndex; + uint32_t dynIdx = 0; + for (auto& b : bg->m_glUBOs) + { + uint32_t offset = b.offset; + if (b.hasDynamicOffset && dynIdx < dynamicOffsetCount) + offset += dynamicOffsets[dynIdx++]; + glBindBufferRange(GL_UNIFORM_BUFFER, b.slot, b.buffer, offset, b.size); + } + for (auto& t : bg->m_glTextures) + { + glActiveTexture(GL_TEXTURE0 + t.slot); + glBindTexture(t.target, t.texture); + if (!m_usedSamplers || t.slot > m_maxSamplerSlot) + m_maxSamplerSlot = t.slot; + m_usedSamplers = true; + } + for (auto& s : bg->m_glSamplers) + { + glBindSampler(s.slot, s.sampler); + } +} + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ + validate(); + if (m_vkContext != nullptr) + { + // Ore NDC convention: Y-up clip space, depth in [0, 1]. + // Vulkan's clip space is Y-down, so we flip the viewport with a + // negative height (VK_KHR_maintenance1). + VkViewport vp{}; + vp.x = x; + vp.y = y + height; // Start at the bottom. + vp.width = width; + vp.height = -height; // Negative height flips Y. + vp.minDepth = minDepth; + vp.maxDepth = maxDepth; + m_vkContext->m_vk.CmdSetViewport(m_vkCmdBuf, 0, 1, &vp); + + // Match the other backends' implicit behaviour: scissor defaults + // to the full viewport rectangle. `VkRect2D` is integer-typed, + // so floor the corner / ceil the far edge to avoid clipping + // fractional sub-rects, and clamp negative origins to 0 + // (`static_cast` of a negative float is UB). + const float x0 = std::floor(x); + const float y0 = std::floor(y); + const float x1 = std::ceil(x + width); + const float y1 = std::ceil(y + height); + VkRect2D scissor{}; + scissor.offset = {static_cast(std::max(0.0f, x0)), + static_cast(std::max(0.0f, y0))}; + scissor.extent = {static_cast(std::max(0.0f, x1 - x0)), + static_cast(std::max(0.0f, y1 - y0))}; + m_vkContext->m_vk.CmdSetScissor(m_vkCmdBuf, 0, 1, &scissor); + return; + } + + // GL path. + m_viewportWidth = static_cast(width); + m_viewportHeight = static_cast(height); + glViewport(static_cast(x), + static_cast(y), + static_cast(width), + static_cast(height)); + glDepthRangef(minDepth, maxDepth); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + if (m_vkContext != nullptr) + { + VkRect2D scissor{}; + scissor.offset = {static_cast(x), static_cast(y)}; + scissor.extent = {width, height}; + m_vkContext->m_vk.CmdSetScissor(m_vkCmdBuf, 0, 1, &scissor); + return; + } + + // GL path. + glEnable(GL_SCISSOR_TEST); + glScissor(x, y, width, height); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + if (m_vkContext != nullptr) + { + m_vkContext->m_vk.CmdSetStencilReference(m_vkCmdBuf, + VK_STENCIL_FACE_FRONT_AND_BACK, + ref); + return; + } + + // GL path. Cache the ref so a subsequent `setPipeline` re-applies + // it — WebGPU semantics make `setStencilReference` pass-state, so + // calling it before the first `setPipeline` must not be a no-op. + m_glStencilRef = ref; + if (m_currentPipeline) + { + const auto& desc = m_currentPipeline->desc(); + glStencilFuncSeparate(GL_FRONT, + oreCompareFunctionToGL(desc.stencilFront.compare), + static_cast(ref), + desc.stencilReadMask); + glStencilFuncSeparate(GL_BACK, + oreCompareFunctionToGL(desc.stencilBack.compare), + static_cast(ref), + desc.stencilReadMask); + } +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + if (m_vkContext != nullptr) + { + float constants[4] = {r, g, b, a}; + m_vkContext->m_vk.CmdSetBlendConstants(m_vkCmdBuf, constants); + return; + } + + // GL path. + glBlendColor(r, g, b, a); +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + if (m_vkContext != nullptr) + { + m_vkContext->m_vk.CmdDraw(m_vkCmdBuf, + vertexCount, + instanceCount, + firstVertex, + firstInstance); + return; + } + + // GL path. + assert(m_currentPipeline != nullptr); + GLenum mode = oreTopologyToGL(m_currentPipeline->desc().topology); + (void)firstInstance; + if (instanceCount > 1) + glDrawArraysInstanced(mode, firstVertex, vertexCount, instanceCount); + else + glDrawArrays(mode, firstVertex, vertexCount); +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + if (m_vkContext != nullptr) + { + m_vkContext->m_vk.CmdDrawIndexed(m_vkCmdBuf, + indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); + return; + } + + // GL path. + assert(m_currentPipeline != nullptr); + GLenum mode = oreTopologyToGL(m_currentPipeline->desc().topology); + GLenum indexType = (m_glIndexFormat == IndexFormat::uint32) + ? GL_UNSIGNED_INT + : GL_UNSIGNED_SHORT; + uint32_t indexSize = + (indexType == GL_UNSIGNED_INT) ? sizeof(uint32_t) : sizeof(uint16_t); + const void* offset = reinterpret_cast( + static_cast(firstIndex * indexSize)); + (void)baseVertex; + (void)firstInstance; + if (instanceCount > 1) + glDrawElementsInstanced(mode, + indexCount, + indexType, + offset, + instanceCount); + else + glDrawElements(mode, indexCount, indexType, offset); +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + + // Release bound BindGroup refs. + for (auto& bg : m_boundGroups) + bg.reset(); + + if (m_vkContext != nullptr) + { + m_vkContext->m_vk.CmdEndRenderPass(m_vkCmdBuf); + + // Transition color attachments COLOR_ATTACHMENT_OPTIMAL -> + // SHADER_READ_ONLY_OPTIMAL so callers (e.g. Rive drawImage) can + // sample. + constexpr gpu::vkutil::ImageAccess kColorAttachmentWriteAccess = { + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + for (uint32_t i = 0; i < m_vkColorCount; ++i) + { + if (m_vkColorImages[i] == VK_NULL_HANDLE) + continue; + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = m_vkColorImages[i]; + barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, + 0, + 1, + m_vkColorBaseLayer[i], + m_vkColorLayerCount[i]}; + barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask = 0; // visibility established in Rive's CB + m_vkContext->m_vk.CmdPipelineBarrier( + m_vkCmdBuf, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); + if (m_vkColorRenderTargets[i] != nullptr) + m_vkColorRenderTargets[i]->updateLastAccess( + kColorAttachmentWriteAccess); + } + + // Transition depth attachment DEPTH_STENCIL_ATTACHMENT_OPTIMAL -> + // SHADER_READ_ONLY_OPTIMAL. + if (m_vkDepthImage != VK_NULL_HANDLE) + { + // Aspect mask must cover stencil when format contains one, else + // strict drivers / validation layer fault on a missing-aspect + // transition for depth+stencil-combined formats. + VkImageAspectFlags depthAspect = VK_IMAGE_ASPECT_DEPTH_BIT; + if (m_depthFormat == TextureFormat::depth24plusStencil8 || + m_depthFormat == TextureFormat::depth32floatStencil8) + { + depthAspect |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + + VkImageMemoryBarrier depthBarrier{}; + depthBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + depthBarrier.oldLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + depthBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + depthBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + depthBarrier.image = m_vkDepthImage; + depthBarrier.subresourceRange = {depthAspect, + 0, + 1, + m_vkDepthBaseLayer, + m_vkDepthLayerCount}; + depthBarrier.srcAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + depthBarrier.dstAccessMask = 0; + m_vkContext->m_vk.CmdPipelineBarrier( + m_vkCmdBuf, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &depthBarrier); + } + + if (m_vkFramebuffer != VK_NULL_HANDLE) + { + // Defer destruction -- the command buffer still references this + // framebuffer until endFrame() submits and waits. + m_vkContext->m_vkDeferredFramebuffers.push_back(m_vkFramebuffer); + m_vkFramebuffer = VK_NULL_HANDLE; + } + return; + } + + // GL path. + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_POLYGON_OFFSET_FILL); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + // Unbind sampler objects and textures so they don't override texture + // parameters in subsequent draws by the host renderer (e.g. Rive's MSAA + // path). + if (m_usedSamplers) + { + for (uint32_t i = 0; i <= m_maxSamplerSlot; ++i) + { + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindSampler(i, 0); + } + glActiveTexture(GL_TEXTURE0); + } + + if (m_usedAttribs) + { + for (uint32_t i = 0; i <= m_maxAttribSlot; ++i) + glDisableVertexAttribArray(i); + } + + // Unbind the global array buffer. (GL_ELEMENT_ARRAY_BUFFER is VAO state + // and will be cleaned up when the per-pass VAO is deleted below — we must + // NOT unbind it here because on some WebGL2 implementations the EBO=0 + // can leak through the VAO delete/restore and corrupt the host VAO.) + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // Delete the per-pass VAO and restore the host renderer's VAO so its + // element-array-buffer binding (and other attrib state) is intact. + if (m_ownsVAO && m_glVAO != 0) + { + glDeleteVertexArrays(1, &m_glVAO); + m_glVAO = 0; + } + glBindVertexArray(m_prevVAO); + + // Resolve MSAA renderbuffers → single-sample resolve targets. + if (m_glResolveCount > 0) + { + GLuint resolveFBO; + glGenFramebuffers(1, &resolveFBO); + for (uint32_t i = 0; i < m_glResolveCount; ++i) + { + const auto& r = m_glResolves[i]; + // Read from the render pass FBO (MSAA renderbuffer attached). + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_glFBO); + glReadBuffer(GL_COLOR_ATTACHMENT0 + r.colorIndex); + + // Write to a temp FBO with the single-sample resolve texture. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + r.resolveTarget, + r.resolveTex, + 0); + + glBlitFramebuffer(0, + 0, + r.width, + r.height, + 0, + 0, + r.width, + r.height, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + } + glDeleteFramebuffers(1, &resolveFBO); + } + + // Delete our FBO and restore the host renderer's FBO. + if (m_ownsFBO && m_glFBO != 0) + { + glDeleteFramebuffers(1, &m_glFBO); + } + glBindFramebuffer(GL_FRAMEBUFFER, m_prevFBO); + + m_context = nullptr; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_VK && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vulkan.cpp new file mode 100644 index 000000000..a2cf4c874 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_render_pass_vulkan.cpp @@ -0,0 +1,340 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/vulkan/render_target_vulkan.hpp" +#include "rive/rive_types.hpp" + +#include +#include +#include +#include + +namespace rive::ore +{ + +// ============================================================================ +// RenderPass methods +// ============================================================================ + +#if !defined(ORE_BACKEND_GL) + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + if (!checkPipelineCompat(pipeline)) + return; + m_currentPipeline = ref_rcp(pipeline); + m_vkContext->m_vk.CmdBindPipeline(m_vkCmdBuf, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline->m_vkPipeline); +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + VkDeviceSize vkOffset = offset; + m_vkContext->m_vk.CmdBindVertexBuffers(m_vkCmdBuf, + slot, + 1, + &buffer->m_vkBuffer, + &vkOffset); +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + m_vkIndexBuffer = buffer->m_vkBuffer; + m_vkIndexType = (format == IndexFormat::uint32) ? VK_INDEX_TYPE_UINT32 + : VK_INDEX_TYPE_UINT16; + m_vkIndexOffset = offset; + m_vkContext->m_vk.CmdBindIndexBuffer(m_vkCmdBuf, + buffer->m_vkBuffer, + offset, + m_vkIndexType); +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + assert(bg != nullptr); + assert(m_currentPipeline != nullptr && + "setPipeline must be called before setBindGroup"); + + m_vkContext->m_vk.CmdBindDescriptorSets( + m_vkCmdBuf, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_currentPipeline->m_vkPipelineLayout, + groupIndex, + 1, + &bg->m_vkDescriptorSet, + dynamicOffsetCount, + dynamicOffsets); + + // Hold a strong ref so the BindGroup (and its retained resources) stay + // alive until the render pass is finished. + m_boundGroups[groupIndex] = ref_rcp(bg); +} + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ + // Ore NDC convention: Y-up clip space, depth in [0, 1]. + // Vulkan's clip space is Y-down, so we flip the viewport with a negative + // height (VK_KHR_maintenance1). This is handled here rather than in the + // shader so that WGSL authors see a consistent Y-up coordinate system + // across all backends without any shader-level fixup. + VkViewport vp{}; + vp.x = x; + vp.y = y + height; // Start at the bottom. + vp.width = width; + vp.height = -height; // Negative height flips Y. + vp.minDepth = minDepth; + vp.maxDepth = maxDepth; + m_vkContext->m_vk.CmdSetViewport(m_vkCmdBuf, 0, 1, &vp); + + // Match the other backends' implicit behaviour: scissor defaults to the + // full viewport rectangle. Callers can override with setScissorRect(). + // Vulkan's `VkRect2D` is integer-typed so we have to discretize the + // float-valued viewport. Use floor on the corner and ceil on the + // far edge so the scissor never clips the requested area, and clamp + // negative origins to 0 — `static_cast` on a negative + // float is UB, and the previous `int32_t` cast truncated fractional + // pixels (e.g. y=0.5 → 0 vs height=255.5 → 255 dropped a pixel row + // on every fractional sub-rect). + const float x0 = std::floor(x); + const float y0 = std::floor(y); + const float x1 = std::ceil(x + width); + const float y1 = std::ceil(y + height); + VkRect2D scissor{}; + scissor.offset = {static_cast(std::max(0.0f, x0)), + static_cast(std::max(0.0f, y0))}; + scissor.extent = {static_cast(std::max(0.0f, x1 - x0)), + static_cast(std::max(0.0f, y1 - y0))}; + m_vkContext->m_vk.CmdSetScissor(m_vkCmdBuf, 0, 1, &scissor); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + VkRect2D scissor{}; + scissor.offset = {static_cast(x), static_cast(y)}; + scissor.extent = {width, height}; + m_vkContext->m_vk.CmdSetScissor(m_vkCmdBuf, 0, 1, &scissor); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + m_vkContext->m_vk.CmdSetStencilReference(m_vkCmdBuf, + VK_STENCIL_FACE_FRONT_AND_BACK, + ref); +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + float constants[4] = {r, g, b, a}; + m_vkContext->m_vk.CmdSetBlendConstants(m_vkCmdBuf, constants); +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + m_vkContext->m_vk.CmdDraw(m_vkCmdBuf, + vertexCount, + instanceCount, + firstVertex, + firstInstance); +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + m_vkContext->m_vk.CmdDrawIndexed(m_vkCmdBuf, + indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + + m_vkContext->m_vk.CmdEndRenderPass(m_vkCmdBuf); + + // Transition color attachments COLOR_ATTACHMENT_OPTIMAL → + // SHADER_READ_ONLY_OPTIMAL so callers (e.g. Rive drawImage) can sample. + // + // We tell Rive that the last access was a COLOR_ATTACHMENT_WRITE (not a + // shader read), so that Rive's prepareForFragmentShaderRead() emits a + // proper barrier in its own command buffer. A barrier in Rive's CB with + // srcStageMask=COLOR_ATTACHMENT_OUTPUT covers the writes from this earlier + // same-queue submission (Vulkan 7.6.2), ensuring cross-submission memory + // visibility. Without this, Rive would skip its barrier (thinking the + // image is already in READ state) and the fragment shader could read stale + // cache data. + constexpr gpu::vkutil::ImageAccess kColorAttachmentWriteAccess = { + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + for (uint32_t i = 0; i < m_vkColorCount; ++i) + { + if (m_vkColorImages[i] == VK_NULL_HANDLE) + continue; + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = m_vkColorImages[i]; + barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, + 0, + 1, + m_vkColorBaseLayer[i], + m_vkColorLayerCount[i]}; + barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask = 0; // visibility established in Rive's CB + m_vkContext->m_vk.CmdPipelineBarrier( + m_vkCmdBuf, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // just the layout transition + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); + // Tell Rive the image was last written as a color attachment and is now + // in SHADER_READ_ONLY_OPTIMAL. Rive's prepareForFragmentShaderRead() + // will emit the availability→visibility barrier in its own CB. + if (m_vkColorRenderTargets[i] != nullptr) + m_vkColorRenderTargets[i]->updateLastAccess( + kColorAttachmentWriteAccess); + } + + // Transition depth attachment DEPTH_STENCIL_ATTACHMENT_OPTIMAL → + // SHADER_READ_ONLY_OPTIMAL so subsequent operations don't see stale + // depth writes. Without this barrier NVIDIA drivers report + // ERROR_DEVICE_LOST during pixel readback. + if (m_vkDepthImage != VK_NULL_HANDLE) + { + // Aspect mask must cover stencil when format contains one, else + // strict drivers / validation layer fault on a missing-aspect + // transition for depth+stencil-combined formats. + VkImageAspectFlags depthAspect = VK_IMAGE_ASPECT_DEPTH_BIT; + if (m_depthFormat == TextureFormat::depth24plusStencil8 || + m_depthFormat == TextureFormat::depth32floatStencil8) + { + depthAspect |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + + VkImageMemoryBarrier depthBarrier{}; + depthBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + depthBarrier.oldLayout = + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + depthBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + depthBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + depthBarrier.image = m_vkDepthImage; + depthBarrier.subresourceRange = {depthAspect, + 0, + 1, + m_vkDepthBaseLayer, + m_vkDepthLayerCount}; + depthBarrier.srcAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + depthBarrier.dstAccessMask = 0; + m_vkContext->m_vk.CmdPipelineBarrier( + m_vkCmdBuf, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &depthBarrier); + } + + if (m_vkFramebuffer != VK_NULL_HANDLE) + { + // Defer destruction — the command buffer still references this + // framebuffer until endFrame() submits and waits. + m_vkContext->m_vkDeferredFramebuffers.push_back(m_vkFramebuffer); + m_vkFramebuffer = VK_NULL_HANDLE; + } +} + +RenderPass::~RenderPass() { finish(); } + +RenderPass::RenderPass(RenderPass&& other) noexcept +{ +#if defined(ORE_BACKEND_VK) + moveCrossBackendFieldsFrom(other); + m_vkContext = other.m_vkContext; + m_currentPipeline = std::move(other.m_currentPipeline); + m_vkCmdBuf = other.m_vkCmdBuf; + m_vkFramebuffer = other.m_vkFramebuffer; + m_vkIndexBuffer = other.m_vkIndexBuffer; + m_vkIndexType = other.m_vkIndexType; + m_vkIndexOffset = other.m_vkIndexOffset; + memcpy(m_vkColorImages, other.m_vkColorImages, sizeof(m_vkColorImages)); + memcpy(m_vkColorBaseLayer, + other.m_vkColorBaseLayer, + sizeof(m_vkColorBaseLayer)); + memcpy(m_vkColorLayerCount, + other.m_vkColorLayerCount, + sizeof(m_vkColorLayerCount)); + m_vkColorCount = other.m_vkColorCount; + memcpy(m_vkColorRenderTargets, + other.m_vkColorRenderTargets, + sizeof(m_vkColorRenderTargets)); + other.m_vkFramebuffer = VK_NULL_HANDLE; +#endif +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + finish(); + new (this) RenderPass(std::move(other)); + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass has already been finished"); +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_resources_vk_gl.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_resources_vk_gl.cpp new file mode 100644 index 000000000..eafc764c9 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_resources_vk_gl.cpp @@ -0,0 +1,691 @@ +/* + * Copyright 2025 Rive + */ + +// Unified resource method implementations for VK+GL dual-backend builds. +// Each resource knows which backend created it by which handle is non-null. +// No dispatch abstraction -- just direct handle checks. + +#if defined(ORE_BACKEND_VK) && defined(ORE_BACKEND_GL) + +#include "rive/renderer/gl/load_gles_extensions.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" + +#include "ore_vulkan_dsl.hpp" // for kVkMaxGroups + +#include +#include +#include + +namespace rive::ore +{ + +// ============================================================================ +// Buffer +// ============================================================================ + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + + if (m_glBuffer != 0) + { + if (m_usage == BufferUsage::index) + { + // WebGL forbids binding a buffer to GL_ELEMENT_ARRAY_BUFFER if it + // was ever bound to a different target, so index buffers must use + // their native target. GL_ELEMENT_ARRAY_BUFFER is VAO state, so we + // save/restore the current binding to avoid clobbering the host + // renderer's VAO. + GLint prevEBO; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prevEBO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_glBuffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevEBO); + } + else + { + // Non-index buffers use GL_COPY_WRITE_BUFFER to avoid disturbing + // the host renderer's VAO element-buffer binding. + glBindBuffer(GL_COPY_WRITE_BUFFER, m_glBuffer); + glBufferSubData(GL_COPY_WRITE_BUFFER, offset, size, data); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + } + return; + } + + assert(m_vkMappedPtr != nullptr); + memcpy(static_cast(m_vkMappedPtr) + offset, data, size); +} + +void Buffer::onRefCntReachedZero() const +{ + if (m_glBuffer != 0) + { + GLuint buf = m_glBuffer; + glDeleteBuffers(1, &buf); + delete this; + return; + } + + VmaAllocator allocator = m_vmaAllocator; + VkBuffer vkBuf = m_vkBuffer; + VmaAllocation alloc = m_vmaAllocation; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (vkBuf != VK_NULL_HANDLE) + vmaDestroyBuffer(allocator, vkBuf, alloc); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// Texture -- local helpers +// ============================================================================ + +// GL format + type for upload (local to this TU). +static GLenum oreFormatToGLFormat(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + case TextureFormat::r16float: + case TextureFormat::r32float: + return GL_RED; + case TextureFormat::rg8unorm: + case TextureFormat::rg16float: + case TextureFormat::rg32float: + return GL_RG; + case TextureFormat::rgba8unorm: + case TextureFormat::rgba8snorm: + case TextureFormat::bgra8unorm: + case TextureFormat::rgba16float: + case TextureFormat::rgba32float: + return GL_RGBA; + case TextureFormat::rgb10a2unorm: + return GL_RGBA; + case TextureFormat::r11g11b10float: + return GL_RGB; + case TextureFormat::depth16unorm: + case TextureFormat::depth32float: + return GL_DEPTH_COMPONENT; + case TextureFormat::depth24plusStencil8: + case TextureFormat::depth32floatStencil8: + return GL_DEPTH_STENCIL; + default: + RIVE_UNREACHABLE(); + } +} + +static GLenum oreFormatToGLType(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + case TextureFormat::rg8unorm: + case TextureFormat::rgba8unorm: + case TextureFormat::bgra8unorm: + return GL_UNSIGNED_BYTE; + case TextureFormat::rgba8snorm: + return GL_BYTE; + case TextureFormat::rgba16float: + case TextureFormat::rg16float: + case TextureFormat::r16float: + return GL_HALF_FLOAT; + case TextureFormat::rgba32float: + case TextureFormat::rg32float: + case TextureFormat::r32float: + case TextureFormat::depth32float: + return GL_FLOAT; + case TextureFormat::rgb10a2unorm: + return GL_UNSIGNED_INT_2_10_10_10_REV; + case TextureFormat::r11g11b10float: + return GL_UNSIGNED_INT_10F_11F_11F_REV; + case TextureFormat::depth16unorm: + return GL_UNSIGNED_SHORT; + case TextureFormat::depth24plusStencil8: + return GL_UNSIGNED_INT_24_8; + case TextureFormat::depth32floatStencil8: + return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; + default: + RIVE_UNREACHABLE(); + } +} + +// VK helpers (local to this TU). +static bool isDepthStencilFormat(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::depth16unorm: + case TextureFormat::depth24plusStencil8: + case TextureFormat::depth32float: + case TextureFormat::depth32floatStencil8: + return true; + default: + return false; + } +} + +static bool hasStencil(TextureFormat fmt) +{ + return fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32floatStencil8; +} + +static VkImageAspectFlags aspectMask(TextureFormat fmt) +{ + if (isDepthStencilFormat(fmt)) + { + VkImageAspectFlags flags = VK_IMAGE_ASPECT_DEPTH_BIT; + if (hasStencil(fmt)) + flags |= VK_IMAGE_ASPECT_STENCIL_BIT; + return flags; + } + return VK_IMAGE_ASPECT_COLOR_BIT; +} + +// Transition an image from one layout to another using a pipeline barrier. +static void transitionLayout(PFN_vkCmdPipelineBarrier pfnCmdPipelineBarrier, + VkCommandBuffer cmdBuf, + VkImage image, + VkImageAspectFlags aspect, + VkImageLayout oldLayout, + VkImageLayout newLayout, + uint32_t mipCount = 1, + uint32_t layerCount = 1) +{ + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange.aspectMask = aspect; + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = mipCount; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = layerCount; + + VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && + newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && + newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + { + barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + dstStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && + newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { + barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + } + else + { + // Generic fallback -- conservative but correct. + barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; + barrier.dstAccessMask = + VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + } + + pfnCmdPipelineBarrier(cmdBuf, + srcStage, + dstStage, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); +} + +// ============================================================================ +// Texture +// ============================================================================ + +void Texture::upload(const TextureDataDesc& data) +{ + if (m_glTexture != 0) + { + // GL path. + assert(data.data != nullptr); + + glBindTexture(m_glTarget, m_glTexture); + + GLenum format = oreFormatToGLFormat(m_format); + GLenum type = oreFormatToGLType(m_format); + + // Honor `bytesPerRow` / `rowsPerImage` for non-tightly-packed + // source data via `GL_UNPACK_ROW_LENGTH` / `GL_UNPACK_IMAGE_HEIGHT`. + // Save + restore so we don't trash the host's pixel-store state. + // Pre-fix the combined VK+GL backend ignored these fields entirely + // — uploads from a sub-rect of a larger source buffer (or from a + // layout that pads rows) read garbage bytes between rows. The + // standalone GL TU (`ore_texture_gl.cpp`) had this from the + // Phase 3 GL fix, but this combined-backend TU was never + // updated and silently shipped the broken behaviour on every + // build that compiles both VK and GL (e.g. Android). + GLint savedRowLength = 0, savedImageHeight = 0; + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &savedRowLength); + glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &savedImageHeight); + const uint32_t bpt = textureFormatBytesPerTexel(m_format); + if (data.bytesPerRow != 0 && bpt != 0 && (data.bytesPerRow % bpt) == 0) + { + glPixelStorei(GL_UNPACK_ROW_LENGTH, + static_cast(data.bytesPerRow / bpt)); + } + if (data.rowsPerImage != 0) + { + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, + static_cast(data.rowsPerImage)); + } + + if (m_glTarget == GL_TEXTURE_3D || m_glTarget == GL_TEXTURE_2D_ARRAY) + { + glTexSubImage3D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.layer, + data.width, + data.height, + data.depth, + format, + type, + data.data); + } + else if (m_glTarget == GL_TEXTURE_CUBE_MAP) + { + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + data.layer, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + format, + type, + data.data); + } + else + { + glTexSubImage2D(m_glTarget, + data.mipLevel, + data.x, + data.y, + data.width, + data.height, + format, + type, + data.data); + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, savedRowLength); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, savedImageHeight); + + glBindTexture(m_glTarget, 0); + return; + } + + // VK staging upload path — resolve the current frame CB and VK + // dispatch table from the owning Context (owned or host-external). + assert(m_vkOreContext != nullptr); + VkCommandBuffer cmdBuf = m_vkOreContext->m_vkCommandBuffer; + auto pfnCmdPipelineBarrier = m_vkOreContext->m_vk.CmdPipelineBarrier; + auto pfnCmdCopyBufferToImage = m_vkOreContext->m_vk.CmdCopyBufferToImage; + assert(cmdBuf != VK_NULL_HANDLE); + assert(m_vkImage != VK_NULL_HANDLE); + + // Determine byte size of the upload region. + uint32_t bytesPerRow = data.bytesPerRow; + uint32_t height = data.height > 0 ? data.height : m_height; + uint32_t depth = data.depth > 0 ? data.depth : m_depthOrArrayLayers; + VkDeviceSize uploadSize = + static_cast(bytesPerRow) * height * depth; + + // Create a transient host-visible staging buffer. + VkBufferCreateInfo bufCI{}; + bufCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufCI.size = uploadSize; + bufCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + + VmaAllocationCreateInfo allocCI{}; + allocCI.usage = VMA_MEMORY_USAGE_CPU_ONLY; + allocCI.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VmaAllocationInfo allocInfo{}; + VkBuffer stagingBuf = VK_NULL_HANDLE; + VmaAllocation stagingAlloc = VK_NULL_HANDLE; + vmaCreateBuffer(m_vmaAllocator, + &bufCI, + &allocCI, + &stagingBuf, + &stagingAlloc, + &allocInfo); + + memcpy(allocInfo.pMappedData, data.data, static_cast(uploadSize)); + + // Transition to TRANSFER_DST. + transitionLayout(pfnCmdPipelineBarrier, + cmdBuf, + m_vkImage, + aspectMask(m_format), + m_vkLayout, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + m_numMipmaps, + m_depthOrArrayLayers); + m_vkLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + // Copy staging buffer -> image. `bufferRowLength` and + // `bufferImageHeight` are in texels — 0 means "tightly packed at + // imageExtent". When the caller's source has padding (e.g. a + // sub-rect of a larger image, or `bytesPerRow > width * + // bytesPerTexel`), the staging copy must honour that pitch or the + // image comes back with the padding bytes interleaved into every + // other row. Pre-fix this was hardcoded to 0 — the + // `ore_array_upload` GM (Phase 4 witness) caught it on every + // Android Vulkan target by uploading with a 2× row stride filled + // with `0xCC` sentinel bytes that then leaked into the rendered + // texture as alternating colour/grey stripes. + const uint32_t bptVK = textureFormatBytesPerTexel(m_format); + VkBufferImageCopy region{}; + region.bufferOffset = 0; + region.bufferRowLength = + (data.bytesPerRow != 0 && bptVK != 0 && (data.bytesPerRow % bptVK) == 0) + ? data.bytesPerRow / bptVK + : 0; + region.bufferImageHeight = data.rowsPerImage; + region.imageSubresource.aspectMask = aspectMask(m_format); + region.imageSubresource.mipLevel = data.mipLevel; + region.imageSubresource.baseArrayLayer = data.layer; + region.imageSubresource.layerCount = 1; + region.imageOffset = {static_cast(data.x), + static_cast(data.y), + static_cast(data.z)}; + region.imageExtent = {data.width > 0 ? data.width : m_width, height, depth}; + + pfnCmdCopyBufferToImage(cmdBuf, + stagingBuf, + m_vkImage, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + ®ion); + + // Transition back to SHADER_READ_ONLY. + transitionLayout(pfnCmdPipelineBarrier, + cmdBuf, + m_vkImage, + aspectMask(m_format), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + m_numMipmaps, + m_depthOrArrayLayers); + m_vkLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + // Defer staging buffer destruction to Context::endFrame(), which + // submits the command buffer and waits on the fence before cleaning up. + m_vkOreContext->m_vkDeferredStagingBuffers.push_back( + {stagingBuf, stagingAlloc}); +} + +void Texture::onRefCntReachedZero() const +{ + if (m_glTexture != 0 || m_glRenderbuffer != 0) + { + // GL path. + if (m_glRenderbuffer != 0 && m_glOwnsTexture) + { + GLuint rb = m_glRenderbuffer; + glDeleteRenderbuffers(1, &rb); + } + if (m_glTexture != 0 && m_glOwnsTexture) + { + GLuint tex = m_glTexture; + glDeleteTextures(1, &tex); + } + delete this; + return; + } + + // VK path — only destroy VMA-owned images (borrowed textures have + // m_vmaAllocation==null). + VmaAllocator allocator = m_vmaAllocator; + VkImage image = m_vkImage; + VmaAllocation alloc = m_vmaAllocation; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (image != VK_NULL_HANDLE && alloc != VK_NULL_HANDLE) + vmaDestroyImage(allocator, image, alloc); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// TextureView +// ============================================================================ + +void TextureView::onRefCntReachedZero() const +{ + if (m_glTextureView != 0) + { + GLuint tex = m_glTextureView; + glDeleteTextures(1, &tex); + delete this; + return; + } + + VkDevice dev = m_vkDevice; + VkImageView view = m_vkImageView; + auto destroyFn = m_vkDestroyImageView; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (view != VK_NULL_HANDLE && destroyFn != nullptr) + destroyFn(dev, view, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// Pipeline +// ============================================================================ + +void Pipeline::onRefCntReachedZero() const +{ + if (m_glProgram != 0) + { + glDeleteProgram(m_glProgram); + delete this; + return; + } + + // VK path: per-group VkDescriptorSetLayouts are owned by BindGroupLayout + // (m_layouts[]) — Pipeline only destroys its own VkPipeline + Layout. + VkDevice dev = m_vkDevice; + VkPipeline pipe = m_vkPipeline; + VkPipelineLayout layout = m_vkPipelineLayout; + auto destroyPipe = m_vkDestroyPipeline; + auto destroyLayout = m_vkDestroyPipelineLayout; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (pipe != VK_NULL_HANDLE && destroyPipe != nullptr) + destroyPipe(dev, pipe, nullptr); + if (layout != VK_NULL_HANDLE && destroyLayout != nullptr) + destroyLayout(dev, layout, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// BindGroupLayout +// ============================================================================ + +void BindGroupLayout::onRefCntReachedZero() const +{ + VkDevice dev = m_vkDevice; + VkDescriptorSetLayout dsl = m_vkDSL; + auto destroyDSL = m_vkDestroyDescriptorSetLayout; + // In VK+GL builds m_context can point at either a ContextVulkan (set by + // ContextVulkan::makeBindGroupLayout) or a ContextGL (set by + // ContextGL::makeBindGroupLayout). m_vkDSL is the unambiguous signal that + // this is a VK-created layout — GL layouts leave it VK_NULL_HANDLE — so we + // only downcast and defer when there is actually a Vulkan handle to + // destroy. + ContextVulkan* ctx = (dsl != VK_NULL_HANDLE) + ? static_cast(m_context) + : nullptr; + + auto destroy = [=]() { + if (dsl != VK_NULL_HANDLE && destroyDSL != nullptr) + destroyDSL(dev, dsl, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// Sampler +// ============================================================================ + +void Sampler::onRefCntReachedZero() const +{ + if (m_glSampler != 0) + { + GLuint samp = m_glSampler; + glDeleteSamplers(1, &samp); + delete this; + return; + } + + VkDevice dev = m_vkDevice; + VkSampler samp = m_vkSampler; + auto destroyFn = m_vkDestroySampler; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (samp != VK_NULL_HANDLE && destroyFn != nullptr) + destroyFn(dev, samp, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// ShaderModule +// ============================================================================ + +void ShaderModule::onRefCntReachedZero() const +{ + if (m_glShader != 0) + { + glDeleteShader(m_glShader); + } + else if (m_vkShaderModule != VK_NULL_HANDLE && + m_vkDestroyShaderModule != nullptr) + { + m_vkDestroyShaderModule(m_vkDevice, m_vkShaderModule, nullptr); + } + delete this; +} + +// ============================================================================ +// BindGroup +// ============================================================================ + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +} // namespace rive::ore + +#endif // ORE_BACKEND_VK && ORE_BACKEND_GL diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_sampler_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_sampler_vulkan.cpp new file mode 100644 index 000000000..31ce9d7ca --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_sampler_vulkan.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void Sampler::onRefCntReachedZero() const +{ + VkDevice dev = m_vkDevice; + VkSampler samp = m_vkSampler; + auto destroyFn = m_vkDestroySampler; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (samp != VK_NULL_HANDLE && destroyFn != nullptr) + destroyFn(dev, samp, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_shader_module_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_shader_module_vulkan.cpp new file mode 100644 index 000000000..4eb8fb809 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_shader_module_vulkan.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" + +namespace rive::ore +{ + +#if !defined(ORE_BACKEND_GL) + +void ShaderModule::onRefCntReachedZero() const +{ + if (m_vkShaderModule != VK_NULL_HANDLE && + m_vkDestroyShaderModule != nullptr) + { + m_vkDestroyShaderModule(m_vkDevice, m_vkShaderModule, nullptr); + } + delete this; +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_texture_vulkan.cpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_texture_vulkan.cpp new file mode 100644 index 000000000..d132b2b23 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_texture_vulkan.cpp @@ -0,0 +1,401 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_context_vulkan.hpp" + +#include + +#include + +namespace rive::ore +{ + +// ============================================================================ +// Helpers +// ============================================================================ + +static VkFormat oreFormatToVk(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return VK_FORMAT_R8_UNORM; + case TextureFormat::rg8unorm: + return VK_FORMAT_R8G8_UNORM; + case TextureFormat::rgba8unorm: + return VK_FORMAT_R8G8B8A8_UNORM; + case TextureFormat::rgba8snorm: + return VK_FORMAT_R8G8B8A8_SNORM; + case TextureFormat::bgra8unorm: + return VK_FORMAT_B8G8R8A8_UNORM; + case TextureFormat::rgba16float: + return VK_FORMAT_R16G16B16A16_SFLOAT; + case TextureFormat::rg16float: + return VK_FORMAT_R16G16_SFLOAT; + case TextureFormat::r16float: + return VK_FORMAT_R16_SFLOAT; + case TextureFormat::rgba32float: + return VK_FORMAT_R32G32B32A32_SFLOAT; + case TextureFormat::rg32float: + return VK_FORMAT_R32G32_SFLOAT; + case TextureFormat::r32float: + return VK_FORMAT_R32_SFLOAT; + case TextureFormat::rgb10a2unorm: + return VK_FORMAT_A2B10G10R10_UNORM_PACK32; + case TextureFormat::r11g11b10float: + return VK_FORMAT_B10G11R11_UFLOAT_PACK32; + case TextureFormat::depth16unorm: + return VK_FORMAT_D16_UNORM; + case TextureFormat::depth24plusStencil8: + return VK_FORMAT_D24_UNORM_S8_UINT; + case TextureFormat::depth32float: + return VK_FORMAT_D32_SFLOAT; + case TextureFormat::depth32floatStencil8: + return VK_FORMAT_D32_SFLOAT_S8_UINT; + case TextureFormat::bc1unorm: + return VK_FORMAT_BC1_RGBA_UNORM_BLOCK; + case TextureFormat::bc3unorm: + return VK_FORMAT_BC3_UNORM_BLOCK; + case TextureFormat::bc7unorm: + return VK_FORMAT_BC7_UNORM_BLOCK; + case TextureFormat::etc2rgb8: + return VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; + case TextureFormat::etc2rgba8: + return VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; + case TextureFormat::astc4x4: + return VK_FORMAT_ASTC_4x4_UNORM_BLOCK; + case TextureFormat::astc6x6: + return VK_FORMAT_ASTC_6x6_UNORM_BLOCK; + case TextureFormat::astc8x8: + return VK_FORMAT_ASTC_8x8_UNORM_BLOCK; + } + assert(false && "Unhandled TextureFormat"); + return VK_FORMAT_UNDEFINED; +} + +static bool isDepthStencilFormat(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::depth16unorm: + case TextureFormat::depth24plusStencil8: + case TextureFormat::depth32float: + case TextureFormat::depth32floatStencil8: + return true; + default: + return false; + } +} + +static bool hasStencil(TextureFormat fmt) +{ + return fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32floatStencil8; +} + +static VkImageAspectFlags aspectMask(TextureFormat fmt) +{ + if (isDepthStencilFormat(fmt)) + { + VkImageAspectFlags flags = VK_IMAGE_ASPECT_DEPTH_BIT; + if (hasStencil(fmt)) + flags |= VK_IMAGE_ASPECT_STENCIL_BIT; + return flags; + } + return VK_IMAGE_ASPECT_COLOR_BIT; +} + +static VkImageAspectFlags oreAspectToVk(TextureAspect aspect, TextureFormat fmt) +{ + switch (aspect) + { + case TextureAspect::all: + return aspectMask(fmt); + case TextureAspect::depthOnly: + return VK_IMAGE_ASPECT_DEPTH_BIT; + case TextureAspect::stencilOnly: + return VK_IMAGE_ASPECT_STENCIL_BIT; + } + assert(false); + return VK_IMAGE_ASPECT_COLOR_BIT; +} + +static VkImageViewType oreViewDimToVk(TextureViewDimension dim) +{ + switch (dim) + { + case TextureViewDimension::texture2D: + return VK_IMAGE_VIEW_TYPE_2D; + case TextureViewDimension::cube: + return VK_IMAGE_VIEW_TYPE_CUBE; + case TextureViewDimension::texture3D: + return VK_IMAGE_VIEW_TYPE_3D; + case TextureViewDimension::array2D: + return VK_IMAGE_VIEW_TYPE_2D_ARRAY; + case TextureViewDimension::cubeArray: + return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + } + assert(false); + return VK_IMAGE_VIEW_TYPE_2D; +} + +// Transition an image from one layout to another using a pipeline barrier +// on the given command buffer. +static void transitionLayout(PFN_vkCmdPipelineBarrier pfnCmdPipelineBarrier, + VkCommandBuffer cmdBuf, + VkImage image, + VkImageAspectFlags aspectMask, + VkImageLayout oldLayout, + VkImageLayout newLayout, + uint32_t mipCount = 1, + uint32_t layerCount = 1) +{ + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange.aspectMask = aspectMask; + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = mipCount; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = layerCount; + + VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && + newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && + newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + { + barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + dstStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && + newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + { + barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + } + else + { + // Generic fallback — conservative but correct. + barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT; + barrier.dstAccessMask = + VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + } + + pfnCmdPipelineBarrier(cmdBuf, + srcStage, + dstStage, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); +} + +// ============================================================================ +// Texture +// ============================================================================ + +#if !defined(ORE_BACKEND_GL) + +void Texture::upload(const TextureDataDesc& data) +{ + // Staging upload records into whichever command buffer the owning + // Context currently has open — either Ore's own CB (owned-CB mode) or + // the host's CB (external-CB mode). Resolved at call time so the same + // Texture can span both modes across its lifetime. + assert(m_vkOreContext != nullptr); + VkCommandBuffer cmdBuf = m_vkOreContext->m_vkCommandBuffer; + auto pfnCmdPipelineBarrier = m_vkOreContext->m_vk.CmdPipelineBarrier; + auto pfnCmdCopyBufferToImage = m_vkOreContext->m_vk.CmdCopyBufferToImage; + assert(cmdBuf != VK_NULL_HANDLE); + assert(m_vkImage != VK_NULL_HANDLE); + + // Determine byte size of the upload region. + uint32_t bytesPerRow = data.bytesPerRow; + uint32_t height = data.height > 0 ? data.height : m_height; + uint32_t depth = data.depth > 0 ? data.depth : m_depthOrArrayLayers; + VkDeviceSize uploadSize = + static_cast(bytesPerRow) * height * depth; + + // Create a transient host-visible staging buffer. + VkBufferCreateInfo bufCI{}; + bufCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufCI.size = uploadSize; + bufCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + + VmaAllocationCreateInfo allocCI{}; + allocCI.usage = VMA_MEMORY_USAGE_CPU_ONLY; + allocCI.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VmaAllocationInfo allocInfo{}; + VkBuffer stagingBuf = VK_NULL_HANDLE; + VmaAllocation stagingAlloc = VK_NULL_HANDLE; + vmaCreateBuffer(m_vmaAllocator, + &bufCI, + &allocCI, + &stagingBuf, + &stagingAlloc, + &allocInfo); + + memcpy(allocInfo.pMappedData, data.data, static_cast(uploadSize)); + + // Transition to TRANSFER_DST. + transitionLayout(pfnCmdPipelineBarrier, + cmdBuf, + m_vkImage, + aspectMask(m_format), + m_vkLayout, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + m_numMipmaps, + m_depthOrArrayLayers); + m_vkLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + // Copy staging buffer → image. `bufferRowLength` and + // `bufferImageHeight` are in texels — 0 means "tightly packed at + // imageExtent". When the caller's source has padding (e.g. a + // sub-rect of a larger image, or `bytesPerRow > width * + // bytesPerTexel`), the staging copy must honour that pitch or the + // image comes back with the padding bytes interleaved into every + // other row. Pre-fix this was hardcoded to 0; the + // `ore_array_upload` GM (Phase 4 witness) caught the regression + // on every Android Vulkan target. + const uint32_t bptVK = textureFormatBytesPerTexel(m_format); + VkBufferImageCopy region{}; + region.bufferOffset = 0; + region.bufferRowLength = + (data.bytesPerRow != 0 && bptVK != 0 && (data.bytesPerRow % bptVK) == 0) + ? data.bytesPerRow / bptVK + : 0; + region.bufferImageHeight = data.rowsPerImage; + region.imageSubresource.aspectMask = aspectMask(m_format); + region.imageSubresource.mipLevel = data.mipLevel; + region.imageSubresource.baseArrayLayer = data.layer; + region.imageSubresource.layerCount = 1; + region.imageOffset = {static_cast(data.x), + static_cast(data.y), + static_cast(data.z)}; + region.imageExtent = {data.width > 0 ? data.width : m_width, height, depth}; + + pfnCmdCopyBufferToImage(cmdBuf, + stagingBuf, + m_vkImage, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + ®ion); + + // Transition back to SHADER_READ_ONLY. + transitionLayout(pfnCmdPipelineBarrier, + cmdBuf, + m_vkImage, + aspectMask(m_format), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + m_numMipmaps, + m_depthOrArrayLayers); + m_vkLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + // The staging buffer must stay alive until the frame command buffer has + // been submitted and the GPU is done with it. Defer destruction to + // Context::endFrame(), which submits the command buffer and waits on the + // fence before cleaning up. + m_vkOreContext->m_vkDeferredStagingBuffers.push_back( + {stagingBuf, stagingAlloc}); +} + +void Texture::onRefCntReachedZero() const +{ + // Only destroy VMA-owned images (borrowed textures have + // m_vmaAllocation==null). + VmaAllocator allocator = m_vmaAllocator; + VkImage image = m_vkImage; + VmaAllocation alloc = m_vmaAllocation; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (image != VK_NULL_HANDLE && alloc != VK_NULL_HANDLE) + vmaDestroyImage(allocator, image, alloc); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +// ============================================================================ +// TextureView +// ============================================================================ + +void TextureView::onRefCntReachedZero() const +{ + VkDevice dev = m_vkDevice; + VkImageView view = m_vkImageView; + auto destroyFn = m_vkDestroyImageView; + ContextVulkan* ctx = m_vkOreContext; + + auto destroy = [=]() { + if (view != VK_NULL_HANDLE && destroyFn != nullptr) + destroyFn(dev, view, nullptr); + }; + + delete this; + + if (ctx != nullptr) + ctx->vkDeferDestroy(std::move(destroy)); + else + destroy(); +} + +#endif // !ORE_BACKEND_GL + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/vulkan/ore_vulkan_dsl.hpp b/thirdparty/rive_renderer/source/ore/vulkan/ore_vulkan_dsl.hpp new file mode 100644 index 000000000..f1af4ba1a --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/vulkan/ore_vulkan_dsl.hpp @@ -0,0 +1,112 @@ +/* + * Copyright 2026 Rive + * + * Private helpers for building `VkDescriptorSetLayout`s from a public + * `BindGroupLayoutDesc`. The user supplies entries up front via + * `Context::makeBindGroupLayout`, and the DSL is built once per layout + * instead of per pipeline. + */ + +#pragma once + +#include "rive/renderer/ore/ore_types.hpp" // BindGroupLayoutDesc, kMaxBindGroups + +#include +#include +#include + +namespace rive::ore +{ + +constexpr uint32_t kVkMaxGroups = kMaxBindGroups; + +// Upper bound on bindings per group. WebGPU's default +// `maxBindingsPerBindGroup` is 1000, but Ore doesn't need that much +// headroom — a generous fixed ceiling keeps the pipeline-create path +// off the heap. If we ever blow past this, bump it. +constexpr uint32_t kVkMaxBindingsPerGroup = 16; + +inline VkDescriptorType oreBindingKindToVk(BindingKind kind, bool dynamic) +{ + switch (kind) + { + case BindingKind::uniformBuffer: + return dynamic ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC + : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + case BindingKind::storageBufferRO: + case BindingKind::storageBufferRW: + return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + case BindingKind::sampledTexture: + return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + case BindingKind::storageTexture: + return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + case BindingKind::sampler: + case BindingKind::comparisonSampler: + return VK_DESCRIPTOR_TYPE_SAMPLER; + } + assert(false && "oreBindingKindToVk: unhandled BindingKind"); + return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; +} + +inline VkShaderStageFlags oreVisibilityToVk(StageVisibility v) +{ + VkShaderStageFlags out = 0; + if (v.mask & StageVisibility::kVertex) + out |= VK_SHADER_STAGE_VERTEX_BIT; + if (v.mask & StageVisibility::kFragment) + out |= VK_SHADER_STAGE_FRAGMENT_BIT; + if (v.mask & StageVisibility::kCompute) + out |= VK_SHADER_STAGE_COMPUTE_BIT; + return out; +} + +// Build a `VkDescriptorSetLayout` from a public `BindGroupLayoutDesc`. +// One entry → one VkDescriptorSetLayoutBinding. +// +// The SPIR-V backend COMPACTS sparse `@binding`s within a group +// (`@binding(0,7)` → slots `0,1`). The descriptor `binding` here must +// match what the SPIR-V emits, which is the allocator-assigned native +// slot (`nativeSlotVS` / `nativeSlotFS`) — NOT the raw WGSL `@binding`. +// `makeLayoutFromShader` populates these from the shader's binding map. +// +// Empty descs produce a valid empty DSL. +inline VkDescriptorSetLayout createDSLFromLayoutDesc( + PFN_vkCreateDescriptorSetLayout pfnCreateDSL, + VkDevice device, + const BindGroupLayoutDesc& desc) +{ + VkDescriptorSetLayoutBinding bindings[kVkMaxBindingsPerGroup]; + const uint32_t n = std::min(desc.entryCount, kVkMaxBindingsPerGroup); + + for (uint32_t i = 0; i < n; ++i) + { + const BindGroupLayoutEntry& e = desc.entries[i]; + const bool dynamic = + e.kind == BindingKind::uniformBuffer && e.hasDynamicOffset; + VkDescriptorSetLayoutBinding& b = bindings[i]; + // Prefer pre-resolved native slot; fall back to FS for FS-only + // resources; final fallback to WGSL @binding (identity for + // shader paths that don't compact). + const uint32_t kAbsent = BindGroupLayoutEntry::kNativeSlotAbsent; + const uint32_t nativeBinding = + (e.nativeSlotVS != kAbsent) ? e.nativeSlotVS + : (e.nativeSlotFS != kAbsent) ? e.nativeSlotFS + : e.binding; + b.binding = nativeBinding; + b.descriptorType = oreBindingKindToVk(e.kind, dynamic); + b.descriptorCount = 1; + b.stageFlags = oreVisibilityToVk(e.visibility); + b.pImmutableSamplers = nullptr; + } + + VkDescriptorSetLayoutCreateInfo ci{}; + ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + ci.bindingCount = n; + ci.pBindings = bindings; + + VkDescriptorSetLayout dsl = VK_NULL_HANDLE; + pfnCreateDSL(device, &ci, nullptr, &dsl); + return dsl; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_bind_group_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_bind_group_wgpu.cpp new file mode 100644 index 000000000..6d8d58ae4 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_bind_group_wgpu.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_bind_group.hpp" + +namespace rive::ore +{ + +void BindGroup::onRefCntReachedZero() const +{ + // Deferred destruction is handled at the Lua GC level via + // Context::deferBindGroupDestroy(), which keeps the rcp<> alive + // until after endFrame(). By the time refcount reaches zero here, + // the GPU is guaranteed to be done. + delete this; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_buffer_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_buffer_wgpu.cpp new file mode 100644 index 000000000..0ddcfc473 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_buffer_wgpu.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/rive_types.hpp" + +namespace rive::ore +{ + +void Buffer::update(const void* data, uint32_t size, uint32_t offset) +{ + assert(offset + size <= m_size); + assert(m_wgpuBuffer != nullptr); + m_wgpuQueue.WriteBuffer(m_wgpuBuffer, offset, data, size); +} + +void Buffer::onRefCntReachedZero() const +{ + // wgpu::Buffer RAII destructor releases the GPU resource. + delete this; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_context_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_context_wgpu.cpp new file mode 100644 index 000000000..0e74e9ccc --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_context_wgpu.cpp @@ -0,0 +1,1271 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_context_wgpu.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_shader_module.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/render_canvas.hpp" +#include "rive/renderer/webgpu/render_context_webgpu_impl.hpp" +#include "rive/rive_types.hpp" +#include "ore_wgpu_layout.hpp" + +#include +#include +#include + +namespace rive::ore +{ + +// ============================================================================ +// Enum → WebGPU conversion helpers +// ============================================================================ + +static wgpu::TextureFormat oreFormatToWGPU(TextureFormat fmt) +{ + switch (fmt) + { + case TextureFormat::r8unorm: + return wgpu::TextureFormat::R8Unorm; + case TextureFormat::rg8unorm: + return wgpu::TextureFormat::RG8Unorm; + case TextureFormat::rgba8unorm: + return wgpu::TextureFormat::RGBA8Unorm; + case TextureFormat::rgba8snorm: + return wgpu::TextureFormat::RGBA8Snorm; + case TextureFormat::bgra8unorm: + return wgpu::TextureFormat::BGRA8Unorm; + case TextureFormat::rgba16float: + return wgpu::TextureFormat::RGBA16Float; + case TextureFormat::rg16float: + return wgpu::TextureFormat::RG16Float; + case TextureFormat::r16float: + return wgpu::TextureFormat::R16Float; + case TextureFormat::rgba32float: + return wgpu::TextureFormat::RGBA32Float; + case TextureFormat::rg32float: + return wgpu::TextureFormat::RG32Float; + case TextureFormat::r32float: + return wgpu::TextureFormat::R32Float; + case TextureFormat::rgb10a2unorm: + return wgpu::TextureFormat::RGB10A2Unorm; + case TextureFormat::r11g11b10float: + return wgpu::TextureFormat::RG11B10Ufloat; + case TextureFormat::depth16unorm: + return wgpu::TextureFormat::Depth16Unorm; + case TextureFormat::depth24plusStencil8: + return wgpu::TextureFormat::Depth24PlusStencil8; + case TextureFormat::depth32float: + return wgpu::TextureFormat::Depth32Float; + case TextureFormat::depth32floatStencil8: + return wgpu::TextureFormat::Depth32FloatStencil8; + case TextureFormat::bc1unorm: + return wgpu::TextureFormat::BC1RGBAUnorm; + case TextureFormat::bc3unorm: + return wgpu::TextureFormat::BC3RGBAUnorm; + case TextureFormat::bc7unorm: + return wgpu::TextureFormat::BC7RGBAUnorm; + case TextureFormat::etc2rgb8: + return wgpu::TextureFormat::ETC2RGB8Unorm; + case TextureFormat::etc2rgba8: + return wgpu::TextureFormat::ETC2RGBA8Unorm; + case TextureFormat::astc4x4: + return wgpu::TextureFormat::ASTC4x4Unorm; + case TextureFormat::astc6x6: + return wgpu::TextureFormat::ASTC6x6Unorm; + case TextureFormat::astc8x8: + return wgpu::TextureFormat::ASTC8x8Unorm; + } + RIVE_UNREACHABLE(); +} + +static wgpu::TextureDimension oreTypeToWGPUDimension(TextureType type) +{ + switch (type) + { + case TextureType::texture2D: + case TextureType::cube: + case TextureType::array2D: + return wgpu::TextureDimension::e2D; + case TextureType::texture3D: + return wgpu::TextureDimension::e3D; + } + RIVE_UNREACHABLE(); +} + +static wgpu::TextureViewDimension oreViewDimToWGPU(TextureViewDimension dim) +{ + switch (dim) + { + case TextureViewDimension::texture2D: + return wgpu::TextureViewDimension::e2D; + case TextureViewDimension::cube: + return wgpu::TextureViewDimension::Cube; + case TextureViewDimension::texture3D: + return wgpu::TextureViewDimension::e3D; + case TextureViewDimension::array2D: + return wgpu::TextureViewDimension::e2DArray; + case TextureViewDimension::cubeArray: + return wgpu::TextureViewDimension::CubeArray; + } + RIVE_UNREACHABLE(); +} + +static wgpu::TextureAspect oreAspectToWGPU(TextureAspect aspect) +{ + switch (aspect) + { + case TextureAspect::all: + return wgpu::TextureAspect::All; + case TextureAspect::depthOnly: + return wgpu::TextureAspect::DepthOnly; + case TextureAspect::stencilOnly: + return wgpu::TextureAspect::StencilOnly; + } + RIVE_UNREACHABLE(); +} + +// Aspect-restricted views of combined depth/stencil textures: leave +// view.format Undefined so the impl auto-derives the per-aspect format +// (spec §6.2.1, "resolving GPUTextureViewDescriptor defaults"). Matches +// Dawn's e2e tests (DepthStencilSamplingTests, +// ReadOnlyDepthStencilAttachmentTests), which only set `aspect`. The +// explicit form (e.g. Depth24Plus view of D24S8) is also spec-valid and +// Dawn accepts it — Undefined is purely for following the most-exercised +// upstream call shape. +static wgpu::TextureFormat oreViewFormatForAspect(TextureFormat texFormat, + TextureAspect aspect) +{ + if (aspect == TextureAspect::depthOnly) + { + if (texFormat == TextureFormat::depth24plusStencil8 || + texFormat == TextureFormat::depth32floatStencil8) + return wgpu::TextureFormat::Undefined; + } + else if (aspect == TextureAspect::stencilOnly) + { + return wgpu::TextureFormat::Undefined; + } + return oreFormatToWGPU(texFormat); +} + +static wgpu::FilterMode oreFilterToWGPU(Filter f) +{ + return (f == Filter::linear) ? wgpu::FilterMode::Linear + : wgpu::FilterMode::Nearest; +} + +static wgpu::MipmapFilterMode oreMipmapFilterToWGPU(Filter f) +{ + return (f == Filter::linear) ? wgpu::MipmapFilterMode::Linear + : wgpu::MipmapFilterMode::Nearest; +} + +static wgpu::AddressMode oreWrapToWGPU(WrapMode mode) +{ + switch (mode) + { + case WrapMode::repeat: + return wgpu::AddressMode::Repeat; + case WrapMode::mirrorRepeat: + return wgpu::AddressMode::MirrorRepeat; + case WrapMode::clampToEdge: + return wgpu::AddressMode::ClampToEdge; + } + RIVE_UNREACHABLE(); +} + +static wgpu::CompareFunction oreCompareFunctionToWGPU(CompareFunction fn) +{ + switch (fn) + { + case CompareFunction::none: + return wgpu::CompareFunction::Undefined; + case CompareFunction::never: + return wgpu::CompareFunction::Never; + case CompareFunction::less: + return wgpu::CompareFunction::Less; + case CompareFunction::equal: + return wgpu::CompareFunction::Equal; + case CompareFunction::lessEqual: + return wgpu::CompareFunction::LessEqual; + case CompareFunction::greater: + return wgpu::CompareFunction::Greater; + case CompareFunction::notEqual: + return wgpu::CompareFunction::NotEqual; + case CompareFunction::greaterEqual: + return wgpu::CompareFunction::GreaterEqual; + case CompareFunction::always: + return wgpu::CompareFunction::Always; + } + RIVE_UNREACHABLE(); +} + +static wgpu::PrimitiveTopology oreTopologyToWGPU(PrimitiveTopology topo) +{ + switch (topo) + { + case PrimitiveTopology::pointList: + return wgpu::PrimitiveTopology::PointList; + case PrimitiveTopology::lineList: + return wgpu::PrimitiveTopology::LineList; + case PrimitiveTopology::lineStrip: + return wgpu::PrimitiveTopology::LineStrip; + case PrimitiveTopology::triangleList: + return wgpu::PrimitiveTopology::TriangleList; + case PrimitiveTopology::triangleStrip: + return wgpu::PrimitiveTopology::TriangleStrip; + } + RIVE_UNREACHABLE(); +} + +static wgpu::IndexFormat oreIndexFormatToWGPU(IndexFormat fmt) +{ + switch (fmt) + { + case IndexFormat::none: + case IndexFormat::uint16: + return wgpu::IndexFormat::Uint16; + case IndexFormat::uint32: + return wgpu::IndexFormat::Uint32; + } + RIVE_UNREACHABLE(); +} + +static wgpu::CullMode oreCullModeToWGPU(CullMode mode) +{ + switch (mode) + { + case CullMode::none: + return wgpu::CullMode::None; + case CullMode::front: + return wgpu::CullMode::Front; + case CullMode::back: + return wgpu::CullMode::Back; + } + RIVE_UNREACHABLE(); +} + +static wgpu::FrontFace oreWindingToWGPU(FaceWinding w) +{ + return (w == FaceWinding::counterClockwise) ? wgpu::FrontFace::CCW + : wgpu::FrontFace::CW; +} + +static wgpu::BlendFactor oreBlendFactorToWGPU(BlendFactor f) +{ + switch (f) + { + case BlendFactor::zero: + return wgpu::BlendFactor::Zero; + case BlendFactor::one: + return wgpu::BlendFactor::One; + case BlendFactor::srcColor: + return wgpu::BlendFactor::Src; + case BlendFactor::oneMinusSrcColor: + return wgpu::BlendFactor::OneMinusSrc; + case BlendFactor::srcAlpha: + return wgpu::BlendFactor::SrcAlpha; + case BlendFactor::oneMinusSrcAlpha: + return wgpu::BlendFactor::OneMinusSrcAlpha; + case BlendFactor::dstColor: + return wgpu::BlendFactor::Dst; + case BlendFactor::oneMinusDstColor: + return wgpu::BlendFactor::OneMinusDst; + case BlendFactor::dstAlpha: + return wgpu::BlendFactor::DstAlpha; + case BlendFactor::oneMinusDstAlpha: + return wgpu::BlendFactor::OneMinusDstAlpha; + case BlendFactor::srcAlphaSaturated: + return wgpu::BlendFactor::SrcAlphaSaturated; + case BlendFactor::blendColor: + return wgpu::BlendFactor::Constant; + case BlendFactor::oneMinusBlendColor: + return wgpu::BlendFactor::OneMinusConstant; + } + RIVE_UNREACHABLE(); +} + +static wgpu::BlendOperation oreBlendOpToWGPU(BlendOp op) +{ + switch (op) + { + case BlendOp::add: + return wgpu::BlendOperation::Add; + case BlendOp::subtract: + return wgpu::BlendOperation::Subtract; + case BlendOp::reverseSubtract: + return wgpu::BlendOperation::ReverseSubtract; + case BlendOp::min: + return wgpu::BlendOperation::Min; + case BlendOp::max: + return wgpu::BlendOperation::Max; + } + RIVE_UNREACHABLE(); +} + +static wgpu::StencilOperation oreStencilOpToWGPU(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return wgpu::StencilOperation::Keep; + case StencilOp::zero: + return wgpu::StencilOperation::Zero; + case StencilOp::replace: + return wgpu::StencilOperation::Replace; + case StencilOp::incrementClamp: + return wgpu::StencilOperation::IncrementClamp; + case StencilOp::decrementClamp: + return wgpu::StencilOperation::DecrementClamp; + case StencilOp::invert: + return wgpu::StencilOperation::Invert; + case StencilOp::incrementWrap: + return wgpu::StencilOperation::IncrementWrap; + case StencilOp::decrementWrap: + return wgpu::StencilOperation::DecrementWrap; + } + RIVE_UNREACHABLE(); +} + +static wgpu::ColorWriteMask oreColorWriteMaskToWGPU(ColorWriteMask mask) +{ + wgpu::ColorWriteMask result = wgpu::ColorWriteMask::None; + if ((mask & ColorWriteMask::red) != ColorWriteMask::none) + result |= wgpu::ColorWriteMask::Red; + if ((mask & ColorWriteMask::green) != ColorWriteMask::none) + result |= wgpu::ColorWriteMask::Green; + if ((mask & ColorWriteMask::blue) != ColorWriteMask::none) + result |= wgpu::ColorWriteMask::Blue; + if ((mask & ColorWriteMask::alpha) != ColorWriteMask::none) + result |= wgpu::ColorWriteMask::Alpha; + return result; +} + +static wgpu::VertexFormat oreVertexFormatToWGPU(VertexFormat fmt) +{ + switch (fmt) + { + case VertexFormat::float1: + return wgpu::VertexFormat::Float32; + case VertexFormat::float2: + return wgpu::VertexFormat::Float32x2; + case VertexFormat::float3: + return wgpu::VertexFormat::Float32x3; + case VertexFormat::float4: + return wgpu::VertexFormat::Float32x4; + case VertexFormat::uint8x4: + return wgpu::VertexFormat::Uint8x4; + case VertexFormat::sint8x4: + return wgpu::VertexFormat::Sint8x4; + case VertexFormat::unorm8x4: + return wgpu::VertexFormat::Unorm8x4; + case VertexFormat::snorm8x4: + return wgpu::VertexFormat::Snorm8x4; + case VertexFormat::uint16x2: + return wgpu::VertexFormat::Uint16x2; + case VertexFormat::sint16x2: + return wgpu::VertexFormat::Sint16x2; + case VertexFormat::unorm16x2: + return wgpu::VertexFormat::Unorm16x2; + case VertexFormat::snorm16x2: + return wgpu::VertexFormat::Snorm16x2; + case VertexFormat::uint16x4: + return wgpu::VertexFormat::Uint16x4; + case VertexFormat::sint16x4: + return wgpu::VertexFormat::Sint16x4; + case VertexFormat::float16x2: + return wgpu::VertexFormat::Float16x2; + case VertexFormat::float16x4: + return wgpu::VertexFormat::Float16x4; + case VertexFormat::uint32: + return wgpu::VertexFormat::Uint32; + case VertexFormat::uint32x2: + return wgpu::VertexFormat::Uint32x2; + case VertexFormat::uint32x3: + return wgpu::VertexFormat::Uint32x3; + case VertexFormat::uint32x4: + return wgpu::VertexFormat::Uint32x4; + case VertexFormat::sint32: + return wgpu::VertexFormat::Sint32; + case VertexFormat::sint32x2: + return wgpu::VertexFormat::Sint32x2; + case VertexFormat::sint32x3: + return wgpu::VertexFormat::Sint32x3; + case VertexFormat::sint32x4: + return wgpu::VertexFormat::Sint32x4; + } + RIVE_UNREACHABLE(); +} + +static wgpu::VertexStepMode oreStepModeToWGPU(VertexStepMode mode) +{ + return (mode == VertexStepMode::instance) ? wgpu::VertexStepMode::Instance + : wgpu::VertexStepMode::Vertex; +} + +// ============================================================================ +// Shader compilation helpers +// ============================================================================ + +#ifdef RIVE_DAWN +static wgpu::ShaderModule compileDawnWGSLShader(wgpu::Device device, + const char* source, + uint32_t codeSize) +{ + WGPUShaderSourceWGSL wgslDesc = WGPU_SHADER_SOURCE_WGSL_INIT; + wgslDesc.code.data = source; + wgslDesc.code.length = codeSize > 0 ? codeSize : WGPU_STRLEN; + + WGPUShaderModuleDescriptor descriptor = WGPU_SHADER_MODULE_DESCRIPTOR_INIT; + descriptor.nextInChain = reinterpret_cast(&wgslDesc); + + return wgpu::ShaderModule::Acquire( + wgpuDeviceCreateShaderModule(device.Get(), &descriptor)); +} +#else +static wgpu::ShaderModule compileWagyuShader(wgpu::Device device, + const char* source, + uint32_t codeSize, + WGPUWagyuShaderLanguage language) +{ + WGPUWagyuShaderModuleDescriptor wagyuDesc = + WGPU_WAGYU_SHADER_MODULE_DESCRIPTOR_INIT; + wagyuDesc.code = source; + wagyuDesc.codeSize = codeSize > 0 ? codeSize : strlen(source); + wagyuDesc.language = language; + + WGPUShaderModuleDescriptor descriptor = WGPU_SHADER_MODULE_DESCRIPTOR_INIT; + descriptor.nextInChain = reinterpret_cast(&wagyuDesc); + + return wgpu::ShaderModule::Acquire( + wgpuDeviceCreateShaderModule(device.Get(), &descriptor)); +} +#endif + +// ============================================================================ +// Context lifecycle +// ============================================================================ + +ContextWGPU::~ContextWGPU() {} + +std::unique_ptr ContextWGPU::Make(wgpu::Device device, + wgpu::Queue queue, + wgpu::BackendType backendType) +{ + auto ctx = std::unique_ptr(new ContextWGPU()); + ctx->m_wgpuDevice = std::move(device); + ctx->m_wgpuQueue = std::move(queue); + ctx->m_wgpuBackend = (backendType == wgpu::BackendType::OpenGLES) + ? WGPUBackend::OpenGLES + : WGPUBackend::Vulkan; + + // Populate features with WebGPU-level capabilities. + Features& f = ctx->m_features; + f.colorBufferFloat = true; + f.perTargetBlend = true; + f.perTargetWriteMask = true; + f.textureViewSampling = true; + f.drawBaseInstance = true; + f.depthBiasClamp = true; + f.anisotropicFiltering = + false; // Requires wgpu::FeatureName::TextureCompressionBC + f.texture3D = true; + f.textureArrays = true; + f.computeShaders = true; + f.storageBuffers = true; + f.bc = false; + f.etc2 = true; + f.astc = false; + f.maxColorAttachments = 4; + f.maxTextureSize2D = 8192; + f.maxTextureSizeCube = 8192; + f.maxTextureSize3D = 2048; + f.maxUniformBufferSize = 65536; + f.maxVertexAttributes = 16; + f.maxSamplers = 16; + + return ctx; +} + +void ContextWGPU::beginFrame() +{ + // Release deferred BindGroups from last frame. By beginFrame() the + // caller has waited for the previous frame's GPU work to complete. + m_deferredBindGroups.clear(); + m_wgpuExternalEncoder = false; + + wgpu::CommandEncoderDescriptor encoderDesc{}; + m_wgpuCommandEncoder = m_wgpuDevice.CreateCommandEncoder(&encoderDesc); +} + +void ContextWGPU::beginFrame(wgpu::CommandEncoder externalEncoder) +{ + assert(externalEncoder != nullptr); + // Same drain contract as owned-encoder mode: by the time we're called + // again for a new frame the host must have submitted/awaited the prior + // frame's work, so any BindGroups deferred at that point are GPU-idle. + m_deferredBindGroups.clear(); + m_wgpuCommandEncoder = std::move(externalEncoder); + m_wgpuExternalEncoder = true; +} + +void ContextWGPU::waitForGPU() {} // WGPU submit is synchronous for Dawn. + +void ContextWGPU::endFrame() +{ + assert(m_wgpuCommandEncoder != nullptr); + if (m_wgpuExternalEncoder) + { + // Host owns Finish()/Submit() and the frame fence; just drop our + // reference to the shared encoder. + m_wgpuCommandEncoder = nullptr; + m_wgpuExternalEncoder = false; + return; + } + wgpu::CommandBuffer commands = m_wgpuCommandEncoder.Finish(); + m_wgpuQueue.Submit(1, &commands); + m_wgpuCommandEncoder = nullptr; +} + +// ============================================================================ +// makeBuffer +// ============================================================================ + +rcp ContextWGPU::makeBuffer(const BufferDesc& desc) +{ + auto buffer = rcp(new Buffer(desc.size, desc.usage)); + buffer->m_wgpuQueue = m_wgpuQueue; // addref'd copy for WriteBuffer + + wgpu::BufferUsage usage = wgpu::BufferUsage::CopyDst; + switch (desc.usage) + { + case BufferUsage::vertex: + usage |= wgpu::BufferUsage::Vertex; + break; + case BufferUsage::index: + usage |= wgpu::BufferUsage::Index; + break; + case BufferUsage::uniform: + usage |= wgpu::BufferUsage::Uniform; + break; + } + + wgpu::BufferDescriptor wDesc{}; + wDesc.label = desc.label; + wDesc.size = desc.size; + wDesc.usage = usage; + wDesc.mappedAtCreation = false; + + buffer->m_wgpuBuffer = m_wgpuDevice.CreateBuffer(&wDesc); + + if (desc.data != nullptr) + { + m_wgpuQueue.WriteBuffer(buffer->m_wgpuBuffer, 0, desc.data, desc.size); + } + + return buffer; +} + +// ============================================================================ +// makeTexture +// ============================================================================ + +rcp ContextWGPU::makeTexture(const TextureDesc& desc) +{ + auto texture = rcp(new Texture(desc)); + texture->m_wgpuQueue = m_wgpuQueue; + + wgpu::TextureUsage usage = + wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst; + if (desc.renderTarget) + usage |= wgpu::TextureUsage::RenderAttachment; + + wgpu::TextureDescriptor wDesc{}; + wDesc.label = desc.label; + wDesc.usage = usage; + wDesc.dimension = oreTypeToWGPUDimension(desc.type); + wDesc.size = {desc.width, desc.height, desc.depthOrArrayLayers}; + wDesc.format = oreFormatToWGPU(desc.format); + wDesc.mipLevelCount = desc.numMipmaps; + wDesc.sampleCount = desc.sampleCount; + + texture->m_wgpuTexture = m_wgpuDevice.CreateTexture(&wDesc); + + return texture; +} + +// ============================================================================ +// makeTextureView +// ============================================================================ + +rcp ContextWGPU::makeTextureView(const TextureViewDesc& desc) +{ + Texture* tex = desc.texture; + if (!tex) + return nullptr; + + auto view = rcp(new TextureView(ref_rcp(tex), desc)); + + wgpu::TextureViewDescriptor wDesc{}; + wDesc.dimension = oreViewDimToWGPU(desc.dimension); + wDesc.aspect = oreAspectToWGPU(desc.aspect); + wDesc.baseMipLevel = desc.baseMipLevel; + wDesc.mipLevelCount = desc.mipCount; + wDesc.baseArrayLayer = desc.baseLayer; + wDesc.arrayLayerCount = desc.layerCount; + wDesc.format = oreViewFormatForAspect(tex->format(), desc.aspect); + + view->m_wgpuTextureView = tex->m_wgpuTexture.CreateView(&wDesc); + + return view; +} + +// ============================================================================ +// makeSampler +// ============================================================================ + +rcp ContextWGPU::makeSampler(const SamplerDesc& desc) +{ + auto sampler = rcp(new Sampler()); + + wgpu::SamplerDescriptor wDesc{}; + wDesc.label = desc.label; + wDesc.addressModeU = oreWrapToWGPU(desc.wrapU); + wDesc.addressModeV = oreWrapToWGPU(desc.wrapV); + wDesc.addressModeW = oreWrapToWGPU(desc.wrapW); + wDesc.magFilter = oreFilterToWGPU(desc.magFilter); + wDesc.minFilter = oreFilterToWGPU(desc.minFilter); + wDesc.mipmapFilter = oreMipmapFilterToWGPU(desc.mipmapFilter); + wDesc.lodMinClamp = desc.minLod; + wDesc.lodMaxClamp = desc.maxLod; + wDesc.compare = oreCompareFunctionToWGPU(desc.compare); + // Dawn rejects `maxAnisotropy = 0`. The Lua surface defaults to 1 + // (Phase 2B) but a C++ caller could pass through any default-init'd + // SamplerDesc, so floor-clamp here as defense-in-depth. + wDesc.maxAnisotropy = + static_cast(desc.maxAnisotropy < 1 ? 1 : desc.maxAnisotropy); + + sampler->m_wgpuSampler = m_wgpuDevice.CreateSampler(&wDesc); + + return sampler; +} + +// ============================================================================ +// makeShaderModule +// ============================================================================ + +rcp ContextWGPU::makeShaderModule(const ShaderModuleDesc& desc) +{ + auto module = rcp(new ShaderModule()); + + const char* source = static_cast(desc.code); + uint32_t codeSize = desc.codeSize > 0 + ? desc.codeSize + : static_cast(strlen(source)); + +#ifdef RIVE_DAWN + assert(desc.language == ShaderLanguage::wgsl && + "Dawn ore backend only supports WGSL shaders"); + module->m_wgpuShaderModule = + compileDawnWGSLShader(m_wgpuDevice, source, codeSize); + assert(module->m_wgpuShaderModule != nullptr && + "Ore Dawn WGSL shader compilation failed"); +#else + WGPUWagyuShaderLanguage language; + if (desc.language == ShaderLanguage::wgsl) + { + // WGSL works on all wagyu backends without any pragma injection. + language = WGPUWagyuShaderLanguage_WGSL; + } + else + { + // GLSL: GLES uses GLSLRAW (no glslang), Vulkan uses GLSL (glslang). + language = (m_wgpuBackend == WGPUBackend::OpenGLES) + ? WGPUWagyuShaderLanguage_GLSLRAW + : WGPUWagyuShaderLanguage_GLSL; + } + + module->m_wgpuShaderModule = + compileWagyuShader(m_wgpuDevice, source, codeSize, language); + + assert(module->m_wgpuShaderModule != nullptr && + "Ore WGPU wagyu shader compilation failed"); +#endif + + module->applyBindingMapFromDesc(desc); + return module; +} + +// ============================================================================ +// makePipeline +// ============================================================================ + +rcp ContextWGPU::makePipeline(const PipelineDesc& desc, + std::string* outError) +{ + auto pipeline = rcp(new Pipeline(desc)); + + // --- Vertex state --- + // Flatten attribute arrays per buffer slot. + constexpr uint32_t kMaxBuffers = 8; + constexpr uint32_t kMaxAttribs = 32; + wgpu::VertexAttribute wAttribs[kMaxAttribs]; + wgpu::VertexBufferLayout wBuffers[kMaxBuffers]; + uint32_t attrIdx = 0; + + for (uint32_t b = 0; b < desc.vertexBufferCount; ++b) + { + const auto& layout = desc.vertexBuffers[b]; + wgpu::VertexBufferLayout& wLayout = wBuffers[b]; + wLayout.arrayStride = layout.stride; + wLayout.stepMode = oreStepModeToWGPU(layout.stepMode); + wLayout.attributeCount = layout.attributeCount; + wLayout.attributes = &wAttribs[attrIdx]; + + for (uint32_t a = 0; a < layout.attributeCount; ++a) + { + const auto& attr = layout.attributes[a]; + // Use explicit field assignment — wgpu::VertexAttribute has + // nextInChain as its first field, so positional aggregate init + // would map format→nextInChain (bad pointer) and corrupt the + // vertex layout. + wgpu::VertexAttribute& wa = wAttribs[attrIdx++]; + wa = {}; + wa.format = oreVertexFormatToWGPU(attr.format); + wa.offset = attr.offset; + wa.shaderLocation = attr.shaderSlot; + } + } + + wgpu::VertexState vertexState{}; + vertexState.module = desc.vertexModule->m_wgpuShaderModule; + vertexState.entryPoint = desc.vertexEntryPoint; + vertexState.bufferCount = desc.vertexBufferCount; + vertexState.buffers = wBuffers; + + // --- Primitive state --- + wgpu::PrimitiveState primitiveState{}; + primitiveState.topology = oreTopologyToWGPU(desc.topology); + primitiveState.stripIndexFormat = + (desc.topology == PrimitiveTopology::triangleStrip || + desc.topology == PrimitiveTopology::lineStrip) + ? oreIndexFormatToWGPU(desc.indexFormat) + : wgpu::IndexFormat::Undefined; + primitiveState.frontFace = oreWindingToWGPU(desc.winding); + primitiveState.cullMode = oreCullModeToWGPU(desc.cullMode); + + // --- Depth/stencil state --- + // + // The presence of a depth attachment is encoded purely by the + // `depthStencil.format` sentinel: `rgba8unorm` means "no depth + // attachment" (documented in `ore_types.hpp`), anything else means + // there's a depth attachment to declare. Pre-fix this also gated on + // `depthCompare != always || depthWriteEnabled`, which let a script + // request a depth attachment for stencil-only operations and got + // `pDepthStencil = nullptr` — Dawn then rejected the pipeline as + // "depth-stencil format mismatch" against any pass with a depth + // attachment. The format-only check is sufficient and matches Dawn's + // own behavior: a pipeline with a depth-stencil-format declaration + // must be paired with a pass that has the matching attachment, no + // matter what compare / write the pipeline configures. + wgpu::DepthStencilState depthStencilState{}; + const bool hasDepth = + (desc.depthStencil.format != TextureFormat::rgba8unorm); + + wgpu::DepthStencilState* pDepthStencil = nullptr; + if (hasDepth) + { + depthStencilState.format = oreFormatToWGPU(desc.depthStencil.format); + depthStencilState.depthWriteEnabled = + desc.depthStencil.depthWriteEnabled; + depthStencilState.depthCompare = + oreCompareFunctionToWGPU(desc.depthStencil.depthCompare); + + depthStencilState.stencilFront.compare = + oreCompareFunctionToWGPU(desc.stencilFront.compare); + depthStencilState.stencilFront.failOp = + oreStencilOpToWGPU(desc.stencilFront.failOp); + depthStencilState.stencilFront.depthFailOp = + oreStencilOpToWGPU(desc.stencilFront.depthFailOp); + depthStencilState.stencilFront.passOp = + oreStencilOpToWGPU(desc.stencilFront.passOp); + + depthStencilState.stencilBack.compare = + oreCompareFunctionToWGPU(desc.stencilBack.compare); + depthStencilState.stencilBack.failOp = + oreStencilOpToWGPU(desc.stencilBack.failOp); + depthStencilState.stencilBack.depthFailOp = + oreStencilOpToWGPU(desc.stencilBack.depthFailOp); + depthStencilState.stencilBack.passOp = + oreStencilOpToWGPU(desc.stencilBack.passOp); + + depthStencilState.stencilReadMask = desc.stencilReadMask; + depthStencilState.stencilWriteMask = desc.stencilWriteMask; + depthStencilState.depthBias = desc.depthStencil.depthBias; + depthStencilState.depthBiasSlopeScale = + desc.depthStencil.depthBiasSlopeScale; + depthStencilState.depthBiasClamp = desc.depthStencil.depthBiasClamp; + + pDepthStencil = &depthStencilState; + } + + // --- Multisample state --- + wgpu::MultisampleState multisampleState{}; + multisampleState.count = desc.sampleCount; + multisampleState.mask = 0xFFFFFFFF; + + // --- Fragment state + blend --- + wgpu::BlendState blendStates[4]; + wgpu::ColorTargetState colorTargets[4]; + + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ct = desc.colorTargets[i]; + wgpu::ColorTargetState& wct = colorTargets[i]; + wct.format = oreFormatToWGPU(ct.format); + wct.writeMask = oreColorWriteMaskToWGPU(ct.writeMask); + + if (ct.blendEnabled) + { + blendStates[i] = { + {oreBlendOpToWGPU(ct.blend.colorOp), + oreBlendFactorToWGPU(ct.blend.srcColor), + oreBlendFactorToWGPU(ct.blend.dstColor)}, + {oreBlendOpToWGPU(ct.blend.alphaOp), + oreBlendFactorToWGPU(ct.blend.srcAlpha), + oreBlendFactorToWGPU(ct.blend.dstAlpha)}, + }; + wct.blend = &blendStates[i]; + } + else + { + wct.blend = nullptr; + } + } + + // Fragment state is omitted for depth-only pipelines. + wgpu::FragmentState fragmentState{}; + if (desc.fragmentModule != nullptr) + { + fragmentState.module = desc.fragmentModule->m_wgpuShaderModule; + fragmentState.entryPoint = desc.fragmentEntryPoint; + fragmentState.targetCount = desc.colorCount; + fragmentState.targets = colorTargets; + } + + // --- Validate user-supplied layouts against shader binding map --- + // + // Phase E: explicit `bindGroupLayouts[]` is the source of truth. The + // shader's reflected BindingMap drives the validation only — every + // shader binding must be declared by the corresponding layout. + { + std::string err; + if (!validateLayoutsAgainstBindingMap(pipeline->m_bindingMap, + desc.bindGroupLayouts, + desc.bindGroupLayoutCount, + &err) || + !validateColorRequiresFragment(desc.colorCount, + desc.fragmentModule != nullptr, + &err)) + { + if (outError) + *outError = err; + else + setLastError("makePipeline: %s", err.c_str()); + return nullptr; + } + } + + // --- Assemble the pipeline layout from user-supplied BGLs --- + wgpu::BindGroupLayout rawBGLs[kWGPUMaxGroups]; + for (uint32_t g = 0; g < desc.bindGroupLayoutCount && g < kWGPUMaxGroups; + ++g) + { + if (desc.bindGroupLayouts[g] != nullptr) + rawBGLs[g] = desc.bindGroupLayouts[g]->m_wgpuBGL; + } + wgpu::PipelineLayoutDescriptor plDesc{}; + plDesc.label = desc.label ? desc.label : ""; + plDesc.bindGroupLayoutCount = desc.bindGroupLayoutCount; + plDesc.bindGroupLayouts = desc.bindGroupLayoutCount > 0 ? rawBGLs : nullptr; + pipeline->m_wgpuPipelineLayout = m_wgpuDevice.CreatePipelineLayout(&plDesc); + + // --- Assemble the render pipeline --- + wgpu::RenderPipelineDescriptor rpDesc{}; + rpDesc.label = desc.label; + rpDesc.layout = pipeline->m_wgpuPipelineLayout; + rpDesc.vertex = vertexState; + rpDesc.primitive = primitiveState; + rpDesc.depthStencil = pDepthStencil; + rpDesc.multisample = multisampleState; + rpDesc.fragment = + (desc.fragmentModule != nullptr) ? &fragmentState : nullptr; + + pipeline->m_wgpuDevice = m_wgpuDevice; + pipeline->m_wgpuPipeline = m_wgpuDevice.CreateRenderPipeline(&rpDesc); + if (!pipeline->m_wgpuPipeline) + { + if (outError) + *outError = "CreateRenderPipeline returned null"; + return nullptr; + } + + return pipeline; +} + +// ============================================================================ +// makeBindGroupLayout +// ============================================================================ + +rcp ContextWGPU::makeBindGroupLayout( + const BindGroupLayoutDesc& desc) +{ + if (desc.groupIndex >= kMaxBindGroups) + { + setLastError("makeBindGroupLayout: groupIndex %u out of range [0, %u)", + desc.groupIndex, + kMaxBindGroups); + return nullptr; + } + auto layout = rcp(new BindGroupLayout()); + layout->m_context = this; + layout->m_groupIndex = desc.groupIndex; + layout->m_entries.reserve(desc.entryCount); + for (uint32_t i = 0; i < desc.entryCount; ++i) + layout->m_entries.push_back(desc.entries[i]); + + layout->m_wgpuBGL = buildWGPUBindGroupLayoutFromDesc(m_wgpuDevice, desc); + if (!layout->m_wgpuBGL) + { + setLastError("makeBindGroupLayout: CreateBindGroupLayout returned " + "null (group=%u)", + desc.groupIndex); + return nullptr; + } + return layout; +} + +// ============================================================================ +// makeBindGroup +// ============================================================================ + +rcp ContextWGPU::makeBindGroup(const BindGroupDesc& desc) +{ + if (desc.layout == nullptr) + { + setLastError("makeBindGroup: BindGroupDesc::layout is null"); + return nullptr; + } + BindGroupLayout* layout = desc.layout; + if (layout->groupIndex() >= kMaxBindGroups) + { + setLastError("makeBindGroup: layout->groupIndex %u out of range [0, " + "%u)", + layout->groupIndex(), + kMaxBindGroups); + return nullptr; + } + + auto bg = rcp(new BindGroup()); + bg->m_context = this; + bg->m_layoutRef = ref_rcp(layout); + + // Count dynamic-offset UBOs declared by the layout. Authoritative — + // dynamic-ness is a layout property (WebGPU/Vulkan model). + uint32_t dynamicCount = 0; + for (const auto& e : layout->entries()) + { + if (e.kind == BindingKind::uniformBuffer && e.hasDynamicOffset) + ++dynamicCount; + } + bg->m_dynamicOffsetCount = dynamicCount; + + // WebGPU is natively per-group-namespaced — `wgpu::BindGroupEntry::binding` + // is the WGSL `@binding` value directly. Validate against the layout's + // declared entries; missing entries set lastError and skip. + auto checkLayout = [&](uint32_t binding, BindingKind expected) -> bool { + const BindGroupLayoutEntry* le = layout->findEntry(binding); + if (le == nullptr) + { + setLastError("makeBindGroup: (group=%u, binding=%u) not declared " + "in BindGroupLayout", + layout->groupIndex(), + binding); + return false; + } + // Sampler/comparison-sampler are interchangeable on the bind side. + if (le->kind != expected && + !((le->kind == BindingKind::sampler || + le->kind == BindingKind::comparisonSampler) && + (expected == BindingKind::sampler || + expected == BindingKind::comparisonSampler))) + { + setLastError("makeBindGroup: (group=%u, binding=%u) layout kind " + "mismatch", + layout->groupIndex(), + binding); + return false; + } + return true; + }; + + uint32_t totalCapacity = + desc.uboCount + desc.textureCount + desc.samplerCount; + std::vector entries(totalCapacity); + uint32_t idx = 0; + + for (uint32_t i = 0; i < desc.uboCount; ++i) + { + const auto& ubo = desc.ubos[i]; + if (!checkLayout(ubo.slot, BindingKind::uniformBuffer)) + continue; + wgpu::BindGroupEntry& e = entries[idx++]; + e = {}; + e.binding = ubo.slot; + e.buffer = ubo.buffer->m_wgpuBuffer; + e.offset = ubo.offset; + e.size = (ubo.size > 0) ? ubo.size : ubo.buffer->size(); + bg->m_retainedBuffers.push_back(ref_rcp(ubo.buffer)); + } + + for (uint32_t i = 0; i < desc.textureCount; ++i) + { + const auto& tex = desc.textures[i]; + if (!checkLayout(tex.slot, BindingKind::sampledTexture)) + continue; + wgpu::BindGroupEntry& e = entries[idx++]; + e = {}; + e.binding = tex.slot; + e.textureView = tex.view->m_wgpuTextureView; + bg->m_retainedViews.push_back(ref_rcp(tex.view)); + } + + for (uint32_t i = 0; i < desc.samplerCount; ++i) + { + const auto& samp = desc.samplers[i]; + if (!checkLayout(samp.slot, BindingKind::sampler)) + continue; + wgpu::BindGroupEntry& e = entries[idx++]; + e = {}; + e.binding = samp.slot; + e.sampler = samp.sampler->m_wgpuSampler; + bg->m_retainedSamplers.push_back(ref_rcp(samp.sampler)); + } + + wgpu::BindGroupDescriptor bgDesc{}; + bgDesc.label = desc.label; + bgDesc.layout = layout->m_wgpuBGL; + bgDesc.entryCount = idx; + bgDesc.entries = (idx > 0) ? entries.data() : nullptr; + + bg->m_wgpuBindGroup = m_wgpuDevice.CreateBindGroup(&bgDesc); + if (bg->m_wgpuBindGroup == nullptr) + return nullptr; + + return bg; +} + +// ============================================================================ +// beginRenderPass +// ============================================================================ + +RenderPass ContextWGPU::beginRenderPass(const RenderPassDesc& desc, + std::string* outError) +{ + finishActiveRenderPass(); + + assert(m_wgpuCommandEncoder != nullptr && + "beginFrame must be called before beginRenderPass"); + + RenderPass pass; + pass.m_context = this; + pass.m_wgpuContext = this; + pass.populateAttachmentMetadata(desc); + + // Color attachments. + wgpu::RenderPassColorAttachment colorAttachments[4]; + for (uint32_t i = 0; i < desc.colorCount; ++i) + { + const auto& ca = desc.colorAttachments[i]; + wgpu::RenderPassColorAttachment& wca = colorAttachments[i]; + wca.view = ca.view ? ca.view->m_wgpuTextureView : nullptr; + wca.resolveTarget = + ca.resolveTarget ? ca.resolveTarget->m_wgpuTextureView : nullptr; + wca.loadOp = (ca.loadOp == LoadOp::clear) ? wgpu::LoadOp::Clear + : wgpu::LoadOp::Load; + wca.storeOp = (ca.storeOp == StoreOp::store) ? wgpu::StoreOp::Store + : wgpu::StoreOp::Discard; + wca.clearValue = {ca.clearColor.r, + ca.clearColor.g, + ca.clearColor.b, + ca.clearColor.a}; + } + + // Depth/stencil attachment. + wgpu::RenderPassDepthStencilAttachment depthStencilAttachment{}; + wgpu::RenderPassDepthStencilAttachment* pDepthStencil = nullptr; + if (desc.depthStencil.view) + { + const auto& ds = desc.depthStencil; + depthStencilAttachment.view = ds.view->m_wgpuTextureView; + depthStencilAttachment.depthLoadOp = (ds.depthLoadOp == LoadOp::clear) + ? wgpu::LoadOp::Clear + : wgpu::LoadOp::Load; + depthStencilAttachment.depthStoreOp = + (ds.depthStoreOp == StoreOp::store) ? wgpu::StoreOp::Store + : wgpu::StoreOp::Discard; + depthStencilAttachment.depthClearValue = ds.depthClearValue; + // Only set stencil ops when the texture has a stencil aspect. + // Dawn validates that stencil ops must not be set on depth-only + // formats. + TextureFormat fmt = ds.view->texture()->format(); + bool hasStencil = (fmt == TextureFormat::depth24plusStencil8 || + fmt == TextureFormat::depth32floatStencil8); + if (hasStencil) + { + depthStencilAttachment.stencilLoadOp = + (ds.stencilLoadOp == LoadOp::clear) ? wgpu::LoadOp::Clear + : wgpu::LoadOp::Load; + depthStencilAttachment.stencilStoreOp = + (ds.stencilStoreOp == StoreOp::store) ? wgpu::StoreOp::Store + : wgpu::StoreOp::Discard; + depthStencilAttachment.stencilClearValue = ds.stencilClearValue; + } + else + { + depthStencilAttachment.stencilReadOnly = true; + } + pDepthStencil = &depthStencilAttachment; + } + + wgpu::RenderPassDescriptor passDesc{}; + passDesc.label = desc.label; + passDesc.colorAttachmentCount = desc.colorCount; + passDesc.colorAttachments = colorAttachments; + passDesc.depthStencilAttachment = pDepthStencil; + + pass.m_wgpuPassEncoder = m_wgpuCommandEncoder.BeginRenderPass(&passDesc); + + return pass; +} + +// ============================================================================ +// wrapCanvasTexture +// ============================================================================ + +rcp ContextWGPU::wrapCanvasTexture(gpu::RenderCanvas* canvas) +{ + assert(canvas != nullptr); + + auto* wgpuTarget = + static_cast(canvas->renderTarget()); + + // Derive the ore format from the actual WebGPU surface format so any MSAA + // texture created from this descriptor matches the resolve target exactly. + auto wgpuFmt = wgpuTarget->framebufferFormat(); + TextureFormat oreFormat; + switch (wgpuFmt) + { + case wgpu::TextureFormat::BGRA8Unorm: + oreFormat = TextureFormat::bgra8unorm; + break; + case wgpu::TextureFormat::RGBA16Float: + oreFormat = TextureFormat::rgba16float; + break; + case wgpu::TextureFormat::RGB10A2Unorm: + oreFormat = TextureFormat::rgb10a2unorm; + break; + default: + oreFormat = TextureFormat::rgba8unorm; + break; + } + + TextureDesc texDesc{}; + texDesc.width = canvas->width(); + texDesc.height = canvas->height(); + texDesc.format = oreFormat; + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = true; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + // Borrow the WebGPU texture — the RenderCanvas owns it. + auto texture = rcp(new Texture(texDesc)); + texture->m_wgpuTexture = wgpuTarget->targetTexture(); + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + view->m_wgpuTextureView = wgpuTarget->targetTextureView(); + + return view; +} + +rcp ContextWGPU::wrapRiveTexture(gpu::Texture* gpuTex, + uint32_t w, + uint32_t h) +{ + if (!gpuTex) + return nullptr; + + // nativeHandle() returns the raw WGPUTexture handle. + WGPUTexture rawTex = static_cast(gpuTex->nativeHandle()); + if (!rawTex) + return nullptr; + + // Acquire takes ownership (will release on destruction). Since we're + // borrowing, AddRef/Reference first so the original owner's ref is + // preserved. Use the same version guard as the rest of the codebase. +#if (defined(RIVE_WEBGPU) && RIVE_WEBGPU > 1) || defined(RIVE_DAWN) + wgpuTextureAddRef(rawTex); +#else + wgpuTextureReference(rawTex); +#endif + wgpu::Texture wgpuTex = wgpu::Texture::Acquire(rawTex); + + TextureDesc texDesc{}; + texDesc.width = w; + texDesc.height = h; + texDesc.format = TextureFormat::rgba8unorm; // Images decode to RGBA8. + texDesc.type = TextureType::texture2D; + texDesc.renderTarget = false; + texDesc.numMipmaps = 1; + texDesc.sampleCount = 1; + + auto texture = rcp(new Texture(texDesc)); + texture->m_wgpuTexture = wgpuTex; // Borrow. + + TextureViewDesc viewDesc{}; + viewDesc.texture = texture.get(); + viewDesc.dimension = TextureViewDimension::texture2D; + viewDesc.baseMipLevel = 0; + viewDesc.mipCount = 1; + viewDesc.baseLayer = 0; + viewDesc.layerCount = 1; + + auto view = rcp(new TextureView(std::move(texture), viewDesc)); + // Create a wgpu::TextureView for sampling. + wgpu::TextureViewDescriptor tvd{}; + tvd.format = wgpu::TextureFormat::RGBA8Unorm; + tvd.dimension = wgpu::TextureViewDimension::e2D; + tvd.baseMipLevel = 0; + tvd.mipLevelCount = 1; + tvd.baseArrayLayer = 0; + tvd.arrayLayerCount = 1; + view->m_wgpuTextureView = wgpuTex.CreateView(&tvd); + + return view; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_pipeline_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_pipeline_wgpu.cpp new file mode 100644 index 000000000..229d02184 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_pipeline_wgpu.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/renderer/ore/ore_bind_group_layout.hpp" + +namespace rive::ore +{ + +void Pipeline::onRefCntReachedZero() const +{ + // wgpu::RenderPipeline and wgpu::PipelineLayout RAII destructors release + // the GPU resources. Per-group BGLs are owned by `m_layouts[g]` and freed + // when those rcps drop. + delete this; +} + +void BindGroupLayout::onRefCntReachedZero() const +{ + // wgpu::BindGroupLayout RAII destructor releases the GPU resource. + delete this; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_render_pass_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_render_pass_wgpu.cpp new file mode 100644 index 000000000..a319b4eb4 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_render_pass_wgpu.cpp @@ -0,0 +1,199 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_render_pass.hpp" +#include "rive/renderer/ore/ore_bind_group.hpp" +#include "rive/renderer/ore/ore_context_wgpu.hpp" +#include "rive/renderer/ore/ore_buffer.hpp" +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_sampler.hpp" +#include "rive/renderer/ore/ore_pipeline.hpp" +#include "rive/rive_types.hpp" + +namespace rive::ore +{ + +// ============================================================================ +// RenderPass +// ============================================================================ + +RenderPass::~RenderPass() +{ + if (!m_finished && m_wgpuPassEncoder != nullptr) + { + finish(); + } +} + +RenderPass::RenderPass(RenderPass&& other) noexcept : + m_currentPipeline(std::move(other.m_currentPipeline)), + m_wgpuContext(other.m_wgpuContext), + m_wgpuPassEncoder(std::move(other.m_wgpuPassEncoder)), + m_wgpuIndexBuffer(std::move(other.m_wgpuIndexBuffer)), + m_wgpuIndexFormat(other.m_wgpuIndexFormat), + m_wgpuIndexOffset(other.m_wgpuIndexOffset) +{ + moveCrossBackendFieldsFrom(other); + other.m_wgpuContext = nullptr; +} + +RenderPass& RenderPass::operator=(RenderPass&& other) noexcept +{ + if (this != &other) + { + if (!m_finished && m_wgpuPassEncoder != nullptr) + finish(); + + moveCrossBackendFieldsFrom(other); + m_wgpuContext = other.m_wgpuContext; + m_currentPipeline = std::move(other.m_currentPipeline); + m_wgpuPassEncoder = std::move(other.m_wgpuPassEncoder); + m_wgpuIndexBuffer = std::move(other.m_wgpuIndexBuffer); + m_wgpuIndexFormat = other.m_wgpuIndexFormat; + m_wgpuIndexOffset = other.m_wgpuIndexOffset; + + other.m_wgpuContext = nullptr; + } + return *this; +} + +void RenderPass::validate() const +{ + assert(!m_finished && "RenderPass already finished"); + assert(m_wgpuPassEncoder != nullptr); +} + +void RenderPass::setPipeline(Pipeline* pipeline) +{ + validate(); + if (!checkPipelineCompat(pipeline)) + return; + m_currentPipeline = ref_rcp(pipeline); + m_wgpuPassEncoder.SetPipeline(pipeline->m_wgpuPipeline); +} + +void RenderPass::setVertexBuffer(uint32_t slot, Buffer* buffer, uint32_t offset) +{ + validate(); + m_wgpuPassEncoder.SetVertexBuffer(slot, + buffer->m_wgpuBuffer, + offset, + buffer->size() - offset); +} + +void RenderPass::setIndexBuffer(Buffer* buffer, + IndexFormat format, + uint32_t offset) +{ + validate(); + wgpu::IndexFormat wFmt = (format == IndexFormat::uint32) + ? wgpu::IndexFormat::Uint32 + : wgpu::IndexFormat::Uint16; + m_wgpuIndexBuffer = buffer->m_wgpuBuffer; + m_wgpuIndexFormat = wFmt; + m_wgpuIndexOffset = offset; + m_wgpuPassEncoder.SetIndexBuffer(buffer->m_wgpuBuffer, + wFmt, + offset, + buffer->size() - offset); +} + +void RenderPass::setBindGroup(uint32_t groupIndex, + BindGroup* bg, + const uint32_t* dynamicOffsets, + uint32_t dynamicOffsetCount) +{ + validate(); + assert(bg != nullptr); + + m_wgpuPassEncoder.SetBindGroup(groupIndex, + bg->m_wgpuBindGroup, + dynamicOffsetCount, + dynamicOffsets); + + // Hold a strong ref so the BindGroup (and its retained resources) stay + // alive until the render pass is finished. + m_boundGroups[groupIndex] = ref_rcp(bg); +} + +void RenderPass::setViewport(float x, + float y, + float width, + float height, + float minDepth, + float maxDepth) +{ + validate(); + m_wgpuPassEncoder.SetViewport(x, y, width, height, minDepth, maxDepth); +} + +void RenderPass::setScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) +{ + validate(); + m_wgpuPassEncoder.SetScissorRect(x, y, width, height); +} + +void RenderPass::setStencilReference(uint32_t ref) +{ + validate(); + m_wgpuPassEncoder.SetStencilReference(ref); +} + +void RenderPass::setBlendColor(float r, float g, float b, float a) +{ + validate(); + wgpu::Color color{r, g, b, a}; + m_wgpuPassEncoder.SetBlendConstant(&color); +} + +void RenderPass::draw(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + validate(); + assert(m_currentPipeline != nullptr && "setPipeline must be called first"); + + m_wgpuPassEncoder.Draw(vertexCount, + instanceCount, + firstVertex, + firstInstance); +} + +void RenderPass::drawIndexed(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t baseVertex, + uint32_t firstInstance) +{ + validate(); + assert(m_currentPipeline != nullptr && "setPipeline must be called first"); + + m_wgpuPassEncoder.DrawIndexed(indexCount, + instanceCount, + firstIndex, + baseVertex, + firstInstance); +} + +void RenderPass::finish() +{ + if (m_finished) + return; + m_finished = true; + + if (m_wgpuPassEncoder != nullptr) + { + m_wgpuPassEncoder.End(); + m_wgpuPassEncoder = nullptr; + } + + m_wgpuContext = nullptr; + m_currentPipeline = nullptr; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_sampler_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_sampler_wgpu.cpp new file mode 100644 index 000000000..468e39304 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_sampler_wgpu.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_sampler.hpp" + +namespace rive::ore +{ + +void Sampler::onRefCntReachedZero() const +{ + // wgpu::Sampler RAII destructor releases the GPU resource. + delete this; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_shader_module_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_shader_module_wgpu.cpp new file mode 100644 index 000000000..ffde7f86e --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_shader_module_wgpu.cpp @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_shader_module.hpp" + +namespace rive::ore +{ + +void ShaderModule::onRefCntReachedZero() const +{ + // wgpu::ShaderModule RAII destructor releases the GPU resource. + delete this; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_texture_wgpu.cpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_texture_wgpu.cpp new file mode 100644 index 000000000..bdd42c8c6 --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_texture_wgpu.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/renderer/ore/ore_texture.hpp" +#include "rive/renderer/ore/ore_types.hpp" +#include "rive/rive_types.hpp" + +namespace rive::ore +{ + +void Texture::upload(const TextureDataDesc& data) +{ + assert(m_wgpuTexture != nullptr); + assert(data.data != nullptr); + + wgpu::TexelCopyTextureInfo dst{}; + dst.texture = m_wgpuTexture; + dst.mipLevel = data.mipLevel; + dst.origin = {data.x, data.y, data.layer}; + dst.aspect = wgpu::TextureAspect::All; + + // Compute the actual row stride. If not provided, assume tightly packed. + // Block-compressed formats have no simple bytes-per-texel value, so callers + // must always supply bytesPerRow for them. + constexpr uint32_t kDawnBytesPerRowAlignment = 256; + uint32_t bpt = textureFormatBytesPerTexel(m_format); + assert((bpt != 0 || data.bytesPerRow != 0) && + "bytesPerRow must be provided for block-compressed formats"); + uint32_t actualBytesPerRow = data.bytesPerRow; + if (actualBytesPerRow == 0) + actualBytesPerRow = data.width * bpt; + + uint32_t rowsPerImage = + data.rowsPerImage > 0 ? data.rowsPerImage : data.height; + + // Dawn requires bytesPerRow to be a multiple of 256 when height > 1. + // If the data is tightly packed and doesn't meet alignment, upload row by + // row for uncompressed 2D textures (bpt != 0, depth == 1): height == 1 per + // call allows WGPU_COPY_STRIDE_UNDEFINED, avoiding the alignment + // requirement. Block-compressed formats (bpt == 0) can't use this path + // since we can't compute a packed row size — callers must supply + // 256-aligned strides. For depth > 1, bytesPerRow and rowsPerImage must be + // valid — callers are expected to supply aligned strides for 3D/array + // uploads. + bool needsRowByRow = (bpt != 0) && (data.height > 1) && (data.depth == 1) && + (actualBytesPerRow % kDawnBytesPerRowAlignment != 0); + if (needsRowByRow) + { + // Use the packed pixel size (no padding) as the data size passed to + // WriteTexture — WGPU_COPY_STRIDE_UNDEFINED means Dawn expects packed + // data for a single row. Advance rowPtr by the full source stride so + // any caller-provided row padding is correctly skipped. + uint32_t packedRowBytes = data.width * bpt; + wgpu::TexelCopyBufferLayout rowLayout{}; + rowLayout.bytesPerRow = WGPU_COPY_STRIDE_UNDEFINED; + rowLayout.rowsPerImage = WGPU_COPY_STRIDE_UNDEFINED; + wgpu::Extent3D rowExtent{data.width, 1, 1}; + const uint8_t* rowPtr = static_cast(data.data); + for (uint32_t y = 0; y < data.height; ++y) + { + dst.origin.y = data.y + y; + m_wgpuQueue.WriteTexture(&dst, + rowPtr, + packedRowBytes, + &rowLayout, + &rowExtent); + rowPtr += actualBytesPerRow; + } + return; + } + + wgpu::TexelCopyBufferLayout layout{}; + layout.bytesPerRow = actualBytesPerRow; + layout.rowsPerImage = rowsPerImage; + + wgpu::Extent3D extent{data.width, data.height, data.depth}; + + uint32_t dataSize = actualBytesPerRow * rowsPerImage * data.depth; + m_wgpuQueue.WriteTexture(&dst, data.data, dataSize, &layout, &extent); +} + +void Texture::onRefCntReachedZero() const +{ + // wgpu::Texture RAII destructor releases the GPU resource. + delete this; +} + +void TextureView::onRefCntReachedZero() const +{ + // wgpu::TextureView RAII destructor releases the GPU resource. + delete this; +} + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/ore/wgpu/ore_wgpu_layout.hpp b/thirdparty/rive_renderer/source/ore/wgpu/ore_wgpu_layout.hpp new file mode 100644 index 000000000..efc32d30a --- /dev/null +++ b/thirdparty/rive_renderer/source/ore/wgpu/ore_wgpu_layout.hpp @@ -0,0 +1,283 @@ +/* + * Copyright 2026 Rive + * + * Private helpers for building explicit `wgpu::BindGroupLayout` + + * `wgpu::PipelineLayout` from the pipeline's `ore::BindingMap` + * (RFC v5 §3.2.2 / §14.1 — "Commit 7c"). + * + * Why explicit layout over WebGPU's `layout: "auto"`: + * - Auto-layout numbering is implementation-visible and has diverged + * across Chrome/Firefox in the past (RFC v5 §14.1). Ore's stability + * contract promises that a WGSL shader's on-disk RSTB keeps + * rendering the same forever; auto-layout breaks that promise if + * Dawn/wgpu ever retune. + * - Explicit layout lets callers declare `hasDynamicOffset` per UBO + * at pipeline-creation time (same plumbing as + * `PipelineDesc::dynamicUBOs` on Vulkan — see + * ore_vulkan_dsl.hpp). + * - Aligns the WebGPU backend with Vulkan/D3D12 — every backend + * builds its layout from the binding map. + */ + +#pragma once + +#include "rive/renderer/ore/ore_binding_map.hpp" +#include "rive/renderer/ore/ore_types.hpp" + +#include + +#include +#include +#include + +namespace rive::ore +{ + +// WebGPU-side alias for Ore's central `kMaxBindGroups` +// (RFC v4 §9.1 / §14.2). Single source of truth in `ore_types.hpp`. +constexpr uint32_t kWGPUMaxGroups = kMaxBindGroups; + +// Map `ore::TextureViewDim` → `wgpu::TextureViewDimension`. Numeric +// values match so we could `static_cast`, but an explicit switch is +// robust against either side reordering. +inline wgpu::TextureViewDimension toWGPUViewDim(TextureViewDim d) +{ + switch (d) + { + case TextureViewDim::Undefined: + // Shader reflection didn't populate this field (the entry + // came from a non-WebGPU allocator path that doesn't carry + // dimension metadata). `e2D` is the safe default — Dawn's + // frontend validator only checks the value when the shader + // also declares a dimension, so this only matters for + // entries the shader doesn't actually use. + return wgpu::TextureViewDimension::e2D; + case TextureViewDim::D1: + return wgpu::TextureViewDimension::e1D; + case TextureViewDim::D2: + return wgpu::TextureViewDimension::e2D; + case TextureViewDim::D2Array: + return wgpu::TextureViewDimension::e2DArray; + case TextureViewDim::Cube: + return wgpu::TextureViewDimension::Cube; + case TextureViewDim::CubeArray: + return wgpu::TextureViewDimension::CubeArray; + case TextureViewDim::D3: + return wgpu::TextureViewDimension::e3D; + } + return wgpu::TextureViewDimension::e2D; +} + +// Map `ore::TextureSampleType` → `wgpu::TextureSampleType`. Dawn's +// `ValidateCompatibilityOfSingleBindingWithLayout` only accepts a +// shader `Depth` binding against a layout `Depth` or `UnfilterableFloat`; +// `Float` is rejected — so we must emit `Depth` when the shader reflects +// it. +inline wgpu::TextureSampleType toWGPUSampleType(TextureSampleType s) +{ + switch (s) + { + case TextureSampleType::Undefined: + case TextureSampleType::Float: + return wgpu::TextureSampleType::Float; + case TextureSampleType::UnfilterableFloat: + return wgpu::TextureSampleType::UnfilterableFloat; + case TextureSampleType::Depth: + return wgpu::TextureSampleType::Depth; + case TextureSampleType::Sint: + return wgpu::TextureSampleType::Sint; + case TextureSampleType::Uint: + return wgpu::TextureSampleType::Uint; + } + return wgpu::TextureSampleType::Float; +} + +// Map an `ore::ResourceKind` plus texture reflection onto a +// `wgpu::BindGroupLayoutEntry`. UBOs with `hasDynamicOffset=true` are +// the declared dynamic-offset case from `PipelineDesc::dynamicUBOs`. +// +// `textureViewDim`, `textureSampleType`, and `textureMultisampled` are +// the shader-reflected metadata from the `BindingMap::Entry`. Dawn compares +// these against its own Tint-reflected view of the shader module in +// `ValidateCompatibilityOfSingleBindingWithLayout` (see +// src/dawn/native/ShaderModule.cpp) — mismatches produce +// "The shader's binding dimension (...) doesn't match the layout's" +// errors at pipeline-creation time. +inline wgpu::BindGroupLayoutEntry makeWGPUBGLEntry( + uint32_t binding, + ResourceKind kind, + bool hasDynamicOffset, + wgpu::ShaderStage visibility, + TextureViewDim textureViewDim = TextureViewDim::Undefined, + TextureSampleType textureSampleType = TextureSampleType::Undefined, + bool textureMultisampled = false) +{ + wgpu::BindGroupLayoutEntry e{}; + e.binding = binding; + e.visibility = visibility; + + switch (kind) + { + case ResourceKind::UniformBuffer: + e.buffer.type = wgpu::BufferBindingType::Uniform; + e.buffer.hasDynamicOffset = hasDynamicOffset; + break; + case ResourceKind::StorageBufferRO: + e.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage; + break; + case ResourceKind::StorageBufferRW: + e.buffer.type = wgpu::BufferBindingType::Storage; + break; + case ResourceKind::SampledTexture: + e.texture.sampleType = toWGPUSampleType(textureSampleType); + e.texture.viewDimension = toWGPUViewDim(textureViewDim); + e.texture.multisampled = textureMultisampled; + break; + case ResourceKind::StorageTexture: + // Ore doesn't ship storage textures on day 1. When it does, + // `format` and `access` come from WGSL reflection. Stubbed + // here for forward-compat. Using the + // C enum constant through a cast because Dawn spells this + // `Rgba8Unorm` while wagyu spells it `RGBA8Unorm`; the + // underlying `WGPUTextureFormat_RGBA8Unorm` is stable + // across both. + e.storageTexture.access = wgpu::StorageTextureAccess::WriteOnly; + e.storageTexture.format = + static_cast(WGPUTextureFormat_RGBA8Unorm); + e.storageTexture.viewDimension = toWGPUViewDim(textureViewDim); + break; + case ResourceKind::Sampler: + e.sampler.type = wgpu::SamplerBindingType::Filtering; + break; + case ResourceKind::ComparisonSampler: + e.sampler.type = wgpu::SamplerBindingType::Comparison; + break; + } + return e; +} + +// (Legacy `buildWGPUBindGroupLayout` driven by the pipeline's BindingMap +// was removed in Phase E. Layouts are now built from public +// `BindGroupLayoutDesc` via `buildWGPUBindGroupLayoutFromDesc` below; the +// pipeline composes them into a `wgpu::PipelineLayout` directly in +// `Context::makePipeline`.) + +// Map `ore::BindingKind` (public layout API) → wgpu BGL entry shape. +// Mirror of `makeWGPUBGLEntry` for the public-API path. Used by +// `buildWGPUBindGroupLayoutFromDesc` (below) which builds from a +// caller-supplied `BindGroupLayoutDesc` rather than the binding map. +inline wgpu::BindGroupLayoutEntry makeWGPUBGLEntryFromDesc( + const BindGroupLayoutEntry& src) +{ + wgpu::BindGroupLayoutEntry e{}; + e.binding = src.binding; + + wgpu::ShaderStage vis = wgpu::ShaderStage::None; + if (src.visibility.mask & StageVisibility::kVertex) + vis |= wgpu::ShaderStage::Vertex; + if (src.visibility.mask & StageVisibility::kFragment) + vis |= wgpu::ShaderStage::Fragment; + if (src.visibility.mask & StageVisibility::kCompute) + vis |= wgpu::ShaderStage::Compute; + e.visibility = vis; + + auto toViewDim = [](TextureViewDimension d) { + switch (d) + { + case TextureViewDimension::texture2D: + return wgpu::TextureViewDimension::e2D; + case TextureViewDimension::cube: + return wgpu::TextureViewDimension::Cube; + case TextureViewDimension::texture3D: + return wgpu::TextureViewDimension::e3D; + case TextureViewDimension::array2D: + return wgpu::TextureViewDimension::e2DArray; + case TextureViewDimension::cubeArray: + return wgpu::TextureViewDimension::CubeArray; + } + return wgpu::TextureViewDimension::e2D; + }; + + auto toSampleType = [](BindGroupLayoutEntry::SampleType s) { + using ST = BindGroupLayoutEntry::SampleType; + switch (s) + { + case ST::floatFilterable: + return wgpu::TextureSampleType::Float; + case ST::floatUnfilterable: + return wgpu::TextureSampleType::UnfilterableFloat; + case ST::depth: + return wgpu::TextureSampleType::Depth; + case ST::sint: + return wgpu::TextureSampleType::Sint; + case ST::uint: + return wgpu::TextureSampleType::Uint; + } + return wgpu::TextureSampleType::Float; + }; + + switch (src.kind) + { + case BindingKind::uniformBuffer: + e.buffer.type = wgpu::BufferBindingType::Uniform; + e.buffer.hasDynamicOffset = src.hasDynamicOffset; + e.buffer.minBindingSize = src.minBindingSize; + break; + case BindingKind::storageBufferRO: + e.buffer.type = wgpu::BufferBindingType::ReadOnlyStorage; + e.buffer.minBindingSize = src.minBindingSize; + break; + case BindingKind::storageBufferRW: + e.buffer.type = wgpu::BufferBindingType::Storage; + e.buffer.minBindingSize = src.minBindingSize; + break; + case BindingKind::sampledTexture: + e.texture.sampleType = toSampleType(src.textureSampleType); + e.texture.viewDimension = toViewDim(src.textureViewDim); + e.texture.multisampled = src.textureMultisampled; + break; + case BindingKind::storageTexture: + e.storageTexture.access = wgpu::StorageTextureAccess::WriteOnly; + e.storageTexture.format = + static_cast(WGPUTextureFormat_RGBA8Unorm); + e.storageTexture.viewDimension = toViewDim(src.textureViewDim); + break; + case BindingKind::sampler: + e.sampler.type = wgpu::SamplerBindingType::Filtering; + break; + case BindingKind::comparisonSampler: + e.sampler.type = wgpu::SamplerBindingType::Comparison; + break; + } + return e; +} + +// Build a `wgpu::BindGroupLayout` from the public `BindGroupLayoutDesc` — +// the path called from `Context::makeBindGroupLayout`. Each entry's +// visibility and texture metadata come from the caller's desc, not from +// shader reflection. +inline wgpu::BindGroupLayout buildWGPUBindGroupLayoutFromDesc( + const wgpu::Device& device, + const BindGroupLayoutDesc& desc) +{ + constexpr uint32_t kMaxEntriesPerGroup = 16; + wgpu::BindGroupLayoutEntry entries[kMaxEntriesPerGroup]; + const uint32_t n = + std::min(desc.entryCount, static_cast(kMaxEntriesPerGroup)); + for (uint32_t i = 0; i < n; ++i) + { + entries[i] = makeWGPUBGLEntryFromDesc(desc.entries[i]); + } + + wgpu::BindGroupLayoutDescriptor bglDesc{}; + bglDesc.label = desc.label ? desc.label : ""; + bglDesc.entryCount = n; + bglDesc.entries = n > 0 ? entries : nullptr; + return device.CreateBindGroupLayout(&bglDesc); +} + +// (Legacy `buildWGPUPipelineLayout` removed in Phase E — pipelines now +// take pre-built `wgpu::BindGroupLayout`s from each user-supplied +// `BindGroupLayout::m_wgpuBGL` and compose them inline.) + +} // namespace rive::ore diff --git a/thirdparty/rive_renderer/source/render_context.cpp b/thirdparty/rive_renderer/source/render_context.cpp index ba675adcf..4fecb6c55 100644 --- a/thirdparty/rive_renderer/source/render_context.cpp +++ b/thirdparty/rive_renderer/source/render_context.cpp @@ -9,8 +9,15 @@ #include "gradient.hpp" #include "rive_render_paint.hpp" #include "rive/renderer/draw.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif #include "rive/renderer/rive_render_image.hpp" #include "rive/renderer/render_context_impl.hpp" +#include "rive/texture_archive.hpp" +#include "rive/renderer/stack_vector.hpp" +#include "rive/profiler/profiler_macros.h" + #include "shaders/constants.glsl" #include @@ -19,6 +26,8 @@ #include "rive/decoders/bitmap_decoder.hpp" #endif +#include "sort_key_builder.hpp" + namespace rive::gpu { constexpr size_t kDefaultSimpleGradientCapacity = 512; @@ -109,6 +118,12 @@ RenderContext::RenderContext(std::unique_ptr impl) : // directly by pathID. m_maxPathID(MaxPathID(m_impl->platformFeatures().pathIDGranularity) - 1) { +#ifdef RIVE_GENERATE_FEATHER_LUT + float table[GAUSSIAN_TABLE_SIZE]; + generate_gausian_integral_table(table); + generate_inverse_gausian_integral_table(table); +#endif + setResourceSizes(ResourceAllocationCounts(), /*forceRealloc =*/true); releaseResources(); } @@ -134,16 +149,44 @@ rcp RenderContext::makeRenderBuffer(RenderBufferType type, return m_impl->makeRenderBuffer(type, flags, sizeInBytes); } +#ifdef RIVE_CANVAS +rcp RenderContext::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + return m_impl->makeRenderCanvas(width, height); +} +#endif + rcp RenderContext::decodeImage(Span encodedBytes) { + RIVE_PROF_SCOPE_L(1) rcp texture = m_impl->platformDecodeImageTexture(encodedBytes); + + // Detect rtex container by 'RTEX' magic. GPU format read from header + // (bc7/astc/etc2/rgba32). + if (texture == nullptr && encodedBytes.size() >= 4 && + encodedBytes[0] == 'R' && encodedBytes[1] == 'T' && + encodedBytes[2] == 'E' && encodedBytes[3] == 'X') + { + TextureDirectory texDir; + if (texDir.import(encodedBytes) && !texDir.dir.empty()) + { + const TextureData& texData = texDir.dir[0]; + texture = m_impl->makeImageTexture(texData.width, + texData.height, + texData.numMips, + texData.format, + texDir.dataBlob.data()); + } + } + #ifdef RIVE_DECODERS if (texture == nullptr) { auto bitmap = Bitmap::decode(encodedBytes.data(), encodedBytes.size()); if (bitmap) { - // For now, RenderContextImpl::makeImageTexture() only accepts RGBA. + // Bitmap::decode always produces RGBA — convert if needed. if (bitmap->pixelFormat() != Bitmap::PixelFormat::RGBAPremul) { bitmap->pixelFormat(Bitmap::PixelFormat::RGBAPremul); @@ -154,6 +197,7 @@ rcp RenderContext::decodeImage(Span encodedBytes) texture = m_impl->makeImageTexture(width, height, mipLevelCount, + GPUTextureFormat::rgba32, bitmap->bytes()); } } @@ -196,6 +240,7 @@ RenderContext::LogicalFlush::LogicalFlush(RenderContext* parent) : m_ctx(parent) void RenderContext::LogicalFlush::rewind() { + RIVE_PROF_SCOPE_L(1) m_resourceCounts = Draw::ResourceCounters(); m_drawPassCount = 0; m_simpleGradients.clear(); @@ -209,6 +254,7 @@ void RenderContext::LogicalFlush::rewind() std::numeric_limits::max(), std::numeric_limits::min(), std::numeric_limits::min()}; + m_combinedDrawContents = gpu::DrawContents::none; m_pathPaddingCount = 0; m_paintPaddingCount = 0; @@ -219,10 +265,13 @@ void RenderContext::LogicalFlush::rewind() m_outerCubicTessEndLocation = 0; m_outerCubicTessVertexIdx = 0; m_midpointFanTessVertexIdx = 0; + m_baselineShaderMiscFlags = gpu::ShaderMiscFlags::none; m_flushDesc = FlushDescriptor(); m_drawList.reset(); + m_firstDstBlendBarrier = nullptr; + m_dstBlendBarrierListTail = &m_firstDstBlendBarrier; m_combinedShaderFeatures = gpu::ShaderFeatures::NONE; m_currentPathID = 0; @@ -273,42 +322,58 @@ void RenderContext::LogicalFlush::resetContainers() // usecases where it isn't used at all. } -void RenderContext::beginFrame(const FrameDescriptor& frameDescriptor) +static gpu::InterlockMode select_interlock_mode( + const RenderContext::FrameDescriptor& frameDescriptor, + const gpu::PlatformFeatures& platformFeatures) { - assert(!m_didBeginFrame); - assert(frameDescriptor.renderTargetWidth > 0); - assert(frameDescriptor.renderTargetHeight > 0); - m_frameDescriptor = frameDescriptor; - if (!platformFeatures().supportsRasterOrdering && - !platformFeatures().supportsFragmentShaderAtomics) + if (frameDescriptor.msaaSampleCount != 0) { - // We don't have pixel local storage in any form. Use 4x MSAA if - // msaaSampleCount wasn't already specified. - m_frameDescriptor.msaaSampleCount = - m_frameDescriptor.msaaSampleCount > 0 - ? m_frameDescriptor.msaaSampleCount - : 4; + return gpu::InterlockMode::msaa; } - if (m_frameDescriptor.msaaSampleCount > 0) + if (frameDescriptor.clockwiseFillOverride) { - m_frameInterlockMode = gpu::InterlockMode::msaa; + if (platformFeatures.supportsClockwiseMode && + !frameDescriptor.disableRasterOrdering) + { + return gpu::InterlockMode::clockwise; + } + if (platformFeatures.supportsClockwiseAtomicMode) + { + return gpu::InterlockMode::clockwiseAtomic; + } } - else if (platformFeatures().supportsRasterOrdering && - (!m_frameDescriptor.disableRasterOrdering || - !platformFeatures().supportsFragmentShaderAtomics)) + if (platformFeatures.supportsRasterOrderingMode && + (!frameDescriptor.disableRasterOrdering || + // Only respect "disableRasterOrdering" if we have atomic mode to fall + // back on. + // FIXME: This API can be improved. + !platformFeatures.supportsAtomicMode)) { - m_frameInterlockMode = gpu::InterlockMode::rasterOrdering; + return gpu::InterlockMode::rasterOrdering; } - else if (frameDescriptor.clockwiseFillOverride && - platformFeatures().supportsClockwiseAtomicRendering) + if (platformFeatures.supportsAtomicMode) { - assert(platformFeatures().supportsFragmentShaderAtomics); - m_frameInterlockMode = gpu::InterlockMode::clockwiseAtomic; + return gpu::InterlockMode::atomics; } - else + return gpu::InterlockMode::msaa; +} + +void RenderContext::beginFrame(const FrameDescriptor& frameDescriptor) +{ + RIVE_PROF_SCOPE_L(0) + + m_impl->preBeginFrame(this); + assert(!m_didBeginFrame); + assert(frameDescriptor.renderTargetWidth > 0); + assert(frameDescriptor.renderTargetHeight > 0); + m_frameDescriptor = frameDescriptor; + m_frameInterlockMode = + select_interlock_mode(m_frameDescriptor, platformFeatures()); + if (m_frameInterlockMode == gpu::InterlockMode::msaa && + m_frameDescriptor.msaaSampleCount == 0) { - assert(platformFeatures().supportsFragmentShaderAtomics); - m_frameInterlockMode = gpu::InterlockMode::atomics; + // Use 4x MSAA if msaaSampleCount wasn't already specified. + m_frameDescriptor.msaaSampleCount = 4; } m_frameShaderFeaturesMask = gpu::ShaderFeaturesMaskFor(m_frameInterlockMode); @@ -389,8 +454,10 @@ bool RenderContext::pushDraws(DrawUniquePtr draws[], size_t drawCount) bool RenderContext::LogicalFlush::pushDraws(DrawUniquePtr draws[], size_t drawCount) { + RIVE_PROF_SCOPE_L(1) assert(!m_hasDoneLayout); + PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() auto countsVector = m_resourceCounts.toVec(); for (size_t i = 0; i < drawCount; ++i) { @@ -399,6 +466,7 @@ bool RenderContext::LogicalFlush::pushDraws(DrawUniquePtr draws[], draws[i]->clipRectInverseMatrix() == nullptr); countsVector += draws[i]->resourceCounts().toVec(); } + POP_DISABLE_CLANG_SIMD_ABI_WARNING() Draw::ResourceCounters countsWithNewBatch = countsVector; // Textures and buffers have hard size limits. If the new batch doesn't fit @@ -453,6 +521,7 @@ bool RenderContext::LogicalFlush::pushDraws(DrawUniquePtr draws[], m_draws.push_back(std::move(draws[i])); m_combinedDrawBounds = m_combinedDrawBounds.join(m_draws.back()->pixelBounds()); + m_combinedDrawContents |= m_draws.back()->drawContents(); } m_resourceCounts = countsWithNewBatch; @@ -464,6 +533,7 @@ bool RenderContext::LogicalFlush::allocateGradient( const Gradient* gradient, gpu::ColorRampLocation* colorRampLocation) { + RIVE_PROF_SCOPE_L(2) assert(!m_hasDoneLayout); const float* stops = gradient->stops(); @@ -556,12 +626,14 @@ bool RenderContext::LogicalFlush::allocateAtlasDraw( uint16_t* y, TAABB* paddedRegion) { + RIVE_PROF_SCOPE_L(2) + if (m_atlasRectanizer == nullptr) { uint16_t atlasMaxSize = m_ctx->atlasMaxSize(); // Use an atlas larger than atlasMaxSize if it's too small for the // request (meaning the render target is larger than atlasMaxSize). - m_atlasRectanizer = std::make_unique( + m_atlasRectanizer = std::make_unique( std::max(atlasMaxSize, drawWidth), std::max(atlasMaxSize, drawHeight)); } @@ -607,6 +679,7 @@ bool RenderContext::LogicalFlush::allocateAtlasDraw( size_t RenderContext::LogicalFlush::allocateCoverageBufferRange(size_t length) { + RIVE_PROF_SCOPE_L(2) assert(m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic); assert(length % (32 * 32) == 0u); // Allocations must support 32x32 tiles. uint32_t offset = m_coverageBufferLength; @@ -633,6 +706,7 @@ void RenderContext::logicalFlush() void RenderContext::flush(const FlushResources& flushResources) { + RIVE_PROF_SCOPE_L(0) assert(m_didBeginFrame); assert(flushResources.renderTarget->width() == m_frameDescriptor.renderTargetWidth); @@ -654,31 +728,47 @@ void RenderContext::flush(const FlushResources& flushResources) // Determine the minimum required resource allocation sizes to service this // flush. - ResourceAllocationCounts resourceRequirements; - resourceRequirements.flushUniformBufferCount = m_logicalFlushes.size(); - resourceRequirements.imageDrawUniformBufferCount = - totalFrameResourceCounts.imageDrawCount; - resourceRequirements.pathBufferCount = - totalFrameResourceCounts.pathCount + layoutCounts.pathPaddingCount; - resourceRequirements.paintBufferCount = - totalFrameResourceCounts.pathCount + layoutCounts.paintPaddingCount; - resourceRequirements.paintAuxBufferCount = - totalFrameResourceCounts.pathCount + layoutCounts.paintAuxPaddingCount; - resourceRequirements.contourBufferCount = - totalFrameResourceCounts.contourCount + - layoutCounts.contourPaddingCount; - resourceRequirements.gradSpanBufferCount = - layoutCounts.gradSpanCount + layoutCounts.gradSpanPaddingCount; - resourceRequirements.tessSpanBufferCount = - totalFrameResourceCounts.maxTessellatedSegmentCount; - resourceRequirements.triangleVertexBufferCount = - totalFrameResourceCounts.maxTriangleVertexCount; - resourceRequirements.gradTextureHeight = layoutCounts.maxGradTextureHeight; - resourceRequirements.tessTextureHeight = layoutCounts.maxTessTextureHeight; - resourceRequirements.atlasTextureWidth = layoutCounts.maxAtlasWidth; - resourceRequirements.atlasTextureHeight = layoutCounts.maxAtlasHeight; - resourceRequirements.coverageBufferLength = - layoutCounts.maxCoverageBufferLength; + const ResourceAllocationCounts resourceRequirements = { + .flushUniformBufferCount = m_logicalFlushes.size(), + .imageDrawUniformBufferCount = totalFrameResourceCounts.imageDrawCount, + .pathBufferCount = + totalFrameResourceCounts.pathCount + layoutCounts.pathPaddingCount, + .paintBufferCount = + totalFrameResourceCounts.pathCount + layoutCounts.paintPaddingCount, + .paintAuxBufferCount = totalFrameResourceCounts.pathCount + + layoutCounts.paintAuxPaddingCount, + .contourBufferCount = totalFrameResourceCounts.contourCount + + layoutCounts.contourPaddingCount, + .gradSpanBufferCount = + layoutCounts.gradSpanCount + layoutCounts.gradSpanPaddingCount, + .tessSpanBufferCount = + totalFrameResourceCounts.maxTessellatedSegmentCount, + .triangleVertexBufferCount = + totalFrameResourceCounts.maxTriangleVertexCount, + .gradTextureHeight = layoutCounts.maxGradTextureHeight, + .tessTextureHeight = layoutCounts.maxTessTextureHeight, + .atlasTextureWidth = layoutCounts.maxAtlasWidth, + .atlasTextureHeight = layoutCounts.maxAtlasHeight, + .plsTransientBackingWidth = + (layoutCounts.maxPLSTransientBackingPlaneCount > 0) + ? static_cast(m_frameDescriptor.renderTargetWidth) + : 0, + .plsTransientBackingHeight = + (layoutCounts.maxPLSTransientBackingPlaneCount > 0) + ? static_cast(m_frameDescriptor.renderTargetHeight) + : 0, + .plsTransientBackingPlaneCount = + layoutCounts.maxPLSTransientBackingPlaneCount, + .plsAtomicCoverageBackingWidth = + (frameInterlockMode() == gpu::InterlockMode::atomics) + ? static_cast(m_frameDescriptor.renderTargetWidth) + : 0, + .plsAtomicCoverageBackingHeight = + (frameInterlockMode() == gpu::InterlockMode::atomics) + ? static_cast(m_frameDescriptor.renderTargetHeight) + : 0, + .coverageBufferLength = layoutCounts.maxCoverageBufferLength, + }; // Ensure we're within hardware limits. assert(resourceRequirements.gradTextureHeight <= kMaxTextureHeight); @@ -689,23 +779,53 @@ void RenderContext::flush(const FlushResources& flushResources) assert(resourceRequirements.atlasTextureHeight <= atlasMaxSize() || resourceRequirements.atlasTextureHeight <= frameDescriptor().renderTargetHeight); + assert(resourceRequirements.plsTransientBackingWidth <= + m_frameDescriptor.renderTargetWidth); + assert(resourceRequirements.plsTransientBackingHeight <= + m_frameDescriptor.renderTargetHeight); assert(resourceRequirements.coverageBufferLength <= platformFeatures().maxCoverageBufferLength); + PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() + // Track m_maxRecentResourceRequirements so we can trim GPU allocations when // steady-state usage goes down. - m_maxRecentResourceRequirements = + m_maxRecentResourceRequirements = ResourceAllocationCounts::FromVec( simd::max(resourceRequirements.toVec(), - m_maxRecentResourceRequirements.toVec()); + m_maxRecentResourceRequirements.toVec())); // Grow resources enough to handle this flush. // If "allocs" already fits in our current allocations, then don't change - // them. If they don't fit, overallocate by 25% in order to create some - // slack for growth. - ResourceAllocationCounts allocs = simd::if_then_else( - resourceRequirements.toVec() <= m_currentResourceAllocations.toVec(), - m_currentResourceAllocations.toVec(), - resourceRequirements.toVec() * size_t(5) / size_t(4)); + // them. + // If they don't fit, overallocate by the specified amount in order to + // create some slack for growth. + constexpr static ResourceAllocationCounts OVERALLOC_x4 = { + .flushUniformBufferCount = 5, // 125% + .imageDrawUniformBufferCount = 5, // 125% + .pathBufferCount = 5, // 125% + .paintBufferCount = 5, // 125% + .paintAuxBufferCount = 5, // 125% + .contourBufferCount = 5, // 125% + .gradSpanBufferCount = 5, // 125% + .tessSpanBufferCount = 5, // 125% + .triangleVertexBufferCount = 5, // 125% + .gradTextureHeight = 5, // 125% + .tessTextureHeight = 5, // 125% + .atlasTextureWidth = 5, // 125% + .atlasTextureHeight = 5, // 125% + .plsTransientBackingWidth = 4, // 100% (i.e., don't overallocate) + .plsTransientBackingHeight = 4, // 100% (i.e., don't overallocate) + .plsTransientBackingPlaneCount = 4, // 100% (i.e., don't overallocate) + .plsAtomicCoverageBackingWidth = 4, // 100% (i.e., don't overallocate) + .plsAtomicCoverageBackingHeight = 4, // 100% (i.e., don't overallocate) + .coverageBufferLength = 5, // 125% + }; + ResourceAllocationCounts allocs = + ResourceAllocationCounts::FromVec(simd::if_then_else( + resourceRequirements.toVec() <= + m_currentResourceAllocations.toVec(), + m_currentResourceAllocations.toVec(), + (resourceRequirements.toVec() * OVERALLOC_x4.toVec()) >> 2)); // In case the 25% growth pushed us above limits. allocs.gradTextureHeight = @@ -728,14 +848,38 @@ void RenderContext::flush(const FlushResources& flushResources) bool needsResourceTrim = flushTime - m_lastResourceTrimTimeInSeconds >= 5; if (needsResourceTrim) { - // Trim GPU resource allocations to 125% of their maximum recent usage, - // and only if the recent usage is 2/3 or less of the current - // allocation. - allocs = simd::if_then_else(m_maxRecentResourceRequirements.toVec() <= - allocs.toVec() * size_t(2) / size_t(3), - m_maxRecentResourceRequirements.toVec() * - size_t(5) / size_t(4), - allocs.toVec()); + // Trim GPU resource allocations to their maximum recent usage, plus + // overallocation, and only if the recent usage is below a certain + // threshold. + constexpr static ResourceAllocationCounts SHRINK_THRESHOLD_x3 = { + .flushUniformBufferCount = 2, // 66.7% + .imageDrawUniformBufferCount = 2, // 66.7% + .pathBufferCount = 2, // 66.7% + .paintBufferCount = 2, // 66.7% + .paintAuxBufferCount = 2, // 66.7% + .contourBufferCount = 2, // 66.7% + .gradSpanBufferCount = 2, // 66.7% + .tessSpanBufferCount = 2, // 66.7% + .triangleVertexBufferCount = 2, // 66.7% + .gradTextureHeight = 2, // 66.7% + .tessTextureHeight = 2, // 66.7% + .atlasTextureWidth = 2, // 66.7% + .atlasTextureHeight = 2, // 66.7% + .plsTransientBackingWidth = 3, // 100% (i.e., always shrink) + .plsTransientBackingHeight = 3, // 100% (i.e., always shrink) + .plsTransientBackingPlaneCount = 3, // 100% (i.e., always shrink) + .plsAtomicCoverageBackingWidth = 3, // 100% (i.e., always shrink) + .plsAtomicCoverageBackingHeight = 3, // 100% (i.e., always shrink) + .coverageBufferLength = 2, // 66.7% + }; + allocs = ResourceAllocationCounts::FromVec(simd::if_then_else( + m_maxRecentResourceRequirements.toVec() <= + (allocs.toVec() * SHRINK_THRESHOLD_x3.toVec()) / size_t(3), + // TODO: Do we actually need overallocation here?? Or should we just + // trust the past 5 seconds of steady usage? + (m_maxRecentResourceRequirements.toVec() * OVERALLOC_x4.toVec()) >> + 2, + allocs.toVec())); // Ensure we stayed within limits. assert(allocs.gradTextureHeight <= kMaxTextureHeight); @@ -753,44 +897,54 @@ void RenderContext::flush(const FlushResources& flushResources) m_lastResourceTrimTimeInSeconds = flushTime; } + assert(simd::all(allocs.toVec() >= resourceRequirements.toVec())); + POP_DISABLE_CLANG_SIMD_ABI_WARNING() + setResourceSizes(allocs); m_impl->prepareToFlush(flushResources.currentFrameNumber, flushResources.safeFrameNumber); - - mapResourceBuffers(resourceRequirements); - - for (const auto& flush : m_logicalFlushes) + if (mapResourceBuffers(resourceRequirements)) { - flush->writeResources(); - } - - assert(m_flushUniformData.elementsWritten() == m_logicalFlushes.size()); - assert(m_imageDrawUniformData.elementsWritten() == - totalFrameResourceCounts.imageDrawCount); - assert(m_pathData.elementsWritten() == - totalFrameResourceCounts.pathCount + layoutCounts.pathPaddingCount); - assert(m_paintData.elementsWritten() == - totalFrameResourceCounts.pathCount + layoutCounts.paintPaddingCount); - assert(m_paintAuxData.elementsWritten() == - totalFrameResourceCounts.pathCount + - layoutCounts.paintAuxPaddingCount); - assert(m_contourData.elementsWritten() == - totalFrameResourceCounts.contourCount + - layoutCounts.contourPaddingCount); - assert(m_gradSpanData.elementsWritten() == - layoutCounts.gradSpanCount + layoutCounts.gradSpanPaddingCount); - assert(m_tessSpanData.elementsWritten() <= - totalFrameResourceCounts.maxTessellatedSegmentCount); - assert(m_triangleVertexData.elementsWritten() <= - totalFrameResourceCounts.maxTriangleVertexCount); - - unmapResourceBuffers(resourceRequirements); + for (const auto& flush : m_logicalFlushes) + { + flush->writeResources(); + } - // Issue logical flushes to the backend. - for (const auto& flush : m_logicalFlushes) + assert(m_flushUniformData.elementsWritten() == m_logicalFlushes.size()); + assert(m_imageDrawUniformData.elementsWritten() == + totalFrameResourceCounts.imageDrawCount); + assert(m_pathData.elementsWritten() == + totalFrameResourceCounts.pathCount + + layoutCounts.pathPaddingCount); + assert(m_paintData.elementsWritten() == + totalFrameResourceCounts.pathCount + + layoutCounts.paintPaddingCount); + assert(m_paintAuxData.elementsWritten() == + totalFrameResourceCounts.pathCount + + layoutCounts.paintAuxPaddingCount); + assert(m_contourData.elementsWritten() == + totalFrameResourceCounts.contourCount + + layoutCounts.contourPaddingCount); + assert(m_gradSpanData.elementsWritten() == + layoutCounts.gradSpanCount + layoutCounts.gradSpanPaddingCount); + assert(m_tessSpanData.elementsWritten() <= + totalFrameResourceCounts.maxTessellatedSegmentCount); + assert(m_triangleVertexData.elementsWritten() <= + totalFrameResourceCounts.maxTriangleVertexCount); + + unmapResourceBuffers(resourceRequirements); + + // Issue logical flushes to the backend. + for (const auto& flush : m_logicalFlushes) + { + m_impl->flush(flush->desc()); + } + } + else { - m_impl->flush(flush->desc()); + fprintf(stderr, "Buffer mapping failed, cannot render.\n"); + unmapResourceBuffers(resourceRequirements); } m_impl->postFlush(flushResources); @@ -821,12 +975,83 @@ void RenderContext::flush(const FlushResources& flushResources) } } +static uint32_t pls_transient_backing_plane_count( + gpu::InterlockMode interlockMode, + gpu::DrawContents combinedDrawContents) +{ + switch (interlockMode) + { + case gpu::InterlockMode::rasterOrdering: + return 3; // clip, scratch, coverage + case gpu::InterlockMode::atomics: + case gpu::InterlockMode::clockwiseAtomic: + return 1; // only clip (coverage is atomic) + case gpu::InterlockMode::clockwise: + { + uint32_t n = 1; // coverage + if (enums::any_flag_set(combinedDrawContents, + gpu::DrawContents::activeClip | + gpu::DrawContents::clipUpdate)) + { + ++n; // clip + } + if (enums::is_flag_set(combinedDrawContents, + gpu::DrawContents::advancedBlend)) + { + ++n; // scratch color + } + return n; + } + case gpu::InterlockMode::msaa: + return 0; // N/A + } + RIVE_UNREACHABLE(); +} + +static bool wants_fixed_function_color_output( + const gpu::PlatformFeatures& platformFeatures, + gpu::InterlockMode interlockMode, + gpu::DrawContents combinedDrawContents, + bool manuallyResolved) +{ + switch (interlockMode) + { + case gpu::InterlockMode::rasterOrdering: + // rasterOrdering shaders always read the framebuffer, even with + // srcOver blend. + return false; + + case gpu::InterlockMode::atomics: + case gpu::InterlockMode::clockwiseAtomic: + return !enums::is_flag_set(combinedDrawContents, + gpu::DrawContents::advancedBlend); + + case gpu::InterlockMode::clockwise: + assert(enums::no_flags_set(combinedDrawContents, + gpu::DrawContents::nonZeroFill | + gpu::DrawContents::evenOddFill)); + return platformFeatures.supportsClockwiseFixedFunctionMode && + !enums::is_flag_set(combinedDrawContents, + gpu::DrawContents::advancedBlend); + + case gpu::InterlockMode::msaa: + // Manual MSAA resolves read the framebuffer, so they can't use + // fixedFunctionColorOutput. + return !manuallyResolved && + !enums::is_flag_set(combinedDrawContents, + gpu::DrawContents::advancedBlend); + } + + RIVE_UNREACHABLE(); +} + void RenderContext::LogicalFlush::layoutResources( const FlushResources& flushResources, size_t logicalFlushIdx, ResourceCounters* runningFrameResourceCounts, LayoutCounters* runningFrameLayoutCounts) { + RIVE_PROF_SCOPE_L(1) assert(!m_hasDoneLayout); const FrameDescriptor& frameDescriptor = m_ctx->frameDescriptor(); @@ -993,6 +1218,27 @@ void RenderContext::LogicalFlush::layoutResources( m_flushDesc.renderTargetUpdateBounds = {0, 0, 0, 0}; } + m_flushDesc.virtualTileWidth = frameDescriptor.virtualTileWidth; + m_flushDesc.virtualTileHeight = frameDescriptor.virtualTileHeight; + + m_flushDesc.manuallyResolved = m_ctx->m_impl->wantsManualRenderPassResolve( + m_flushDesc.interlockMode, + m_flushDesc.renderTarget, + m_flushDesc.renderTargetUpdateBounds, + m_flushDesc.virtualTileWidth, + m_flushDesc.virtualTileHeight, + m_combinedDrawContents); + + m_flushDesc.fixedFunctionColorOutput = + wants_fixed_function_color_output(m_ctx->platformFeatures(), + m_ctx->frameInterlockMode(), + m_combinedDrawContents, + m_flushDesc.manuallyResolved); + if (m_flushDesc.fixedFunctionColorOutput) + { + m_baselineShaderMiscFlags |= + gpu::ShaderMiscFlags::fixedFunctionColorOutput; + } m_flushDesc.atlasContentWidth = m_atlasMaxX; m_flushDesc.atlasContentHeight = m_atlasMaxY; @@ -1019,15 +1265,18 @@ void RenderContext::LogicalFlush::layoutResources( m_flushDesc.tessDataHeight = tessDataHeight; m_flushDesc.clockwiseFillOverride = frameDescriptor.clockwiseFillOverride; m_flushDesc.wireframe = frameDescriptor.wireframe; + m_flushDesc.ditherMode = m_ctx->frameDescriptor().ditherMode; #ifdef WITH_RIVE_TOOLS - m_flushDesc.synthesizeCompilationFailures = - frameDescriptor.synthesizeCompilationFailures; + m_flushDesc.synthesizedFailureType = frameDescriptor.synthesizedFailureType; #endif m_flushDesc.externalCommandBuffer = flushResources.externalCommandBuffer; + PUSH_DISABLE_CLANG_SIMD_ABI_WARNING() *runningFrameResourceCounts = runningFrameResourceCounts->toVec() + m_resourceCounts.toVec(); + POP_DISABLE_CLANG_SIMD_ABI_WARNING() + runningFrameLayoutCounts->pathPaddingCount += m_pathPaddingCount; runningFrameLayoutCounts->paintPaddingCount += m_paintPaddingCount; runningFrameLayoutCounts->paintAuxPaddingCount += m_paintAuxPaddingCount; @@ -1044,6 +1293,10 @@ void RenderContext::LogicalFlush::layoutResources( std::max(m_atlasMaxX, runningFrameLayoutCounts->maxAtlasWidth); runningFrameLayoutCounts->maxAtlasHeight = std::max(m_atlasMaxY, runningFrameLayoutCounts->maxAtlasHeight); + runningFrameLayoutCounts->maxPLSTransientBackingPlaneCount = + std::max(pls_transient_backing_plane_count(m_flushDesc.interlockMode, + m_combinedDrawContents), + runningFrameLayoutCounts->maxPLSTransientBackingPlaneCount); runningFrameLayoutCounts->maxCoverageBufferLength = std::max(m_coverageBufferLength, runningFrameLayoutCounts->maxCoverageBufferLength); @@ -1061,8 +1314,39 @@ void RenderContext::LogicalFlush::layoutResources( RIVE_DEBUG_CODE(m_hasDoneLayout = true;) } +void RenderContext::LogicalFlush::pushBarriers(BarrierFlags barrierFlags) +{ + if (m_ctx->platformFeatures() + .clockwiseAtomicBorrowedCoverageBarrierNeedsRenderPassInit && + enums::is_flag_set(barrierFlags, + gpu::BarrierFlags::clockwiseBorrowedCoverage)) + { + // We need a workaround in order for input attachments to work. + BarrierFlags workaroundBarriers = + BarrierFlags::clockwiseBorrowedCoverage | BarrierFlags::plsAtomic; + if (enums::is_flag_set(m_combinedDrawContents, + gpu::DrawContents::advancedBlend)) + { + workaroundBarriers |= BarrierFlags::dstBlend; + } + m_drawList.emplace_back(m_ctx->perFrameAllocator(), + gpu::DrawType::renderPassInitialize, + m_baselineShaderMiscFlags, + gpu::DrawContents::none, + 1, + 0, + BlendMode::overlay, + ImageSampler::LinearClamp(), + workaroundBarriers); + barrierFlags &= ~gpu::BarrierFlags::clockwiseBorrowedCoverage; + } + + m_pendingBarriers |= barrierFlags; +} + void RenderContext::LogicalFlush::writeResources() { + RIVE_PROF_SCOPE_L(1) const gpu::PlatformFeatures& platformFeatures = m_ctx->platformFeatures(); assert(m_hasDoneLayout); assert(m_flushDesc.firstPath == m_ctx->m_pathData.elementsWritten()); @@ -1231,32 +1515,90 @@ void RenderContext::LogicalFlush::writeResources() indirectDrawList.clear(); indirectDrawList.reserve(m_drawPassCount); + // TODO: For clockwiseAtomic, these next values aren't constant (they're + // constants now just to have stand-in values representing the default + // case). Instead: + // - There would be (at least) three relevant "overlap bits": + // - color buffer write + // - clip buffer read + // - clip buffer write + // - groupingType should be GroupingType::overlapAllowed (unless there + // is some reason the current draw could *never* overlap anything + // else) + // - Any draws that write to the color buffer (which may include draws + // that also use the *clip* buffer) would set the "color buffer + // write" bit in its overlap bits + // - Draws that are using advanced blending would set the "color buffer + // write" bit in its disallow mask, so that they are not allowed to + // overlap things that write to the color buffer (there is nothing + // extra for advanced blending that goes into the overlap bits - + // advanced blending has no bearing on whether or not things can + // overlap on top of it!) + // - Any draws that read from the clip buffer: + // - set the "clip buffer read" bit in `overlapBits` - this gets + // stored with the rectangle and signifies that the rectangle is + // involved in a clip buffer read + // - sets the "clip buffer write" bit in `disallowOverlapMask` - this + // tells the intersection board that if this draw overlaps a clip + // buffer write, it needs to go in the next draw group (there needs + // to be a barrier) + // - Any draws that write to the clip buffer: + // - set the "clip buffer write" bit in `overlapBits` + // - sets *both* the "clip buffer read/write" bits in + // `disallowOverlapMask` - this means that these draws would need a + // barrier between any previous overlapping clip buffer reads or + // writes. + // - Similarly, the ordering of the bits in the sort key would likely + // want to change for this mode to ensure that the sorting preserves + // proper ordering within a given draw group, since now there are + // overlaps and thus draw ordering can matter. + // (it also might be worth double checking that there aren't other + // modes where a different sort ordering could be more efficient, to + // perhaps better group like things together that don't cause + // barriers) + constexpr static uint16_t kOverlapBits = 0; + constexpr static uint16_t kDisallowOverlapMask = 0; + constexpr static GroupingType kGroupingType = GroupingType::disjoint; + if (m_ctx->m_intersectionBoard == nullptr) { - m_ctx->m_intersectionBoard = std::make_unique(); + m_ctx->m_intersectionBoard = + std::make_unique(kGroupingType); } + + assert(m_ctx->m_intersectionBoard->groupingType() == kGroupingType); IntersectionBoard* intersectionBoard = m_ctx->m_intersectionBoard.get(); intersectionBoard->resizeAndReset(m_flushDesc.renderTarget->width(), m_flushDesc.renderTarget->height()); - // Build a list of sort keys that determine the final draw order. - constexpr static int kDrawGroupShift = - 48; // Where in the key does the draw group begin? - constexpr static int64_t kDrawGroupMask = 0x7fffllu << kDrawGroupShift; - constexpr static int kDrawTypeShift = 45; - constexpr static int64_t kDrawTypeMask RIVE_MAYBE_UNUSED = - 7llu << kDrawTypeShift; - constexpr static int kTextureHashShift = 31; - constexpr static int64_t kTextureHashMask = 0x3fffllu - << kTextureHashShift; - constexpr static int kBlendModeShift = 27; - constexpr static int kBlendModeMask = 0xf << kBlendModeShift; - constexpr static int kDrawContentsShift = 18; - constexpr static int64_t kDrawContentsMask = 0x1ffllu - << kDrawContentsShift; - constexpr static int kDrawIndexShift = 2; - constexpr static int64_t kDrawIndexMask = 0x7fff << kDrawIndexShift; - constexpr static int64_t kSubpassIndexMask = 0x3; + static constexpr SortKeyBuilder keyBuilder{ + // Our top priority in re-ordering is to group non-overlapping draws + // together, in order to maximize batching while preserving + // correctness. + {.entry = SortEntry::drawGroup, .bitCount = 15}, + + // Within sub-groups of non-overlapping draws, sort similar draw + // types together. + {.entry = SortEntry::drawType, .bitCount = 3}, + + // Within sub-groups of matching draw type, sort by texture binding. + {.entry = SortEntry::textureHash, .bitCount = 14}, + + // If using KHR_blend_equation_advanced, we need a batching barrier + // between draws with different blend modes. If not using + // KHR_blend_equation_advanced, sorting by blend mode may still give + // us better branching on the GPU. + {.entry = SortEntry::blendMode, .bitCount = 4}, + + // msaa mode draws strokes, fills, and even/odd with different + // stencil settings. + {.entry = SortEntry::drawContents, .bitCount = 9}, + + // Draw and subpass indices go at the bottom of the key so we can + // reference them again after sorting without affecting the order. + {.entry = SortEntry::drawIndex, .bitCount = 15}, + {.entry = SortEntry::subpassIndex, .bitCount = 3}, + }; for (size_t i = 0; i < m_draws.size(); ++i) { @@ -1272,59 +1614,62 @@ void RenderContext::LogicalFlush::writeResources() drawBounds != int4{kMin32i, kMin32i, kMax32i, kMax32i}, drawBounds + int4{-1, -1, 1, 1}, drawBounds); + if (m_ctx->frameInterlockMode() == + gpu::InterlockMode::clockwiseAtomic && + enums::is_flag_set(draw->drawContents(), + gpu::DrawContents::clipUpdate)) + { + // ***FIXME***: until we implement scissors for clipping, + // clockwiseAtomic clip updates can't be reordered. Expand their + // pixel bounds to block reordering. + drawBounds = { + 0, + 0, + static_cast( + m_ctx->frameDescriptor().renderTargetWidth), + static_cast( + m_ctx->frameDescriptor().renderTargetHeight), + }; + } + + // When the dstBlend barrier has no other option than to copy out a + // texture, this copy destroys MSAA information and we can no longer + // put subpasses in different drawGroups. + // Otherwise, we put subpasses into different draw groups because it + // yields better reordering. + const bool allSubpassesInSameDrawGroup = + m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa && + !platformFeatures.supportsBlendAdvancedKHR && + enums::is_flag_set(m_combinedDrawContents, + gpu::DrawContents::advancedBlend); // Our top priority in re-ordering is to group non-overlapping draws // together, in order to maximize batching while preserving // correctness. - int maxPasses = + const int maxSubpasses = std::max(draw->prepassCount(), draw->subpassCount()); - int16_t drawGroupIdx = - intersectionBoard->addRectangle(drawBounds, maxPasses); + int16_t drawGroupIdx = intersectionBoard->addRectangle( + drawBounds, + kOverlapBits, + kDisallowOverlapMask, + allSubpassesInSameDrawGroup ? 1 : maxSubpasses); assert(drawGroupIdx > 0); - int64_t key = static_cast(drawGroupIdx) << kDrawGroupShift; - - // Within sub-groups of non-overlapping draws, sort similar draw - // types together. - int64_t drawType = static_cast(draw->type()); - assert(drawType <= kDrawTypeMask >> kDrawTypeShift); - key |= drawType << kDrawTypeShift; - - // Within sub-groups of matching draw type, sort by texture binding. - int64_t textureHash = - draw->imageTexture() != nullptr - ? draw->imageTexture()->textureResourceHash() & - (kTextureHashMask >> kTextureHashShift) + const auto textureHash = + (draw->imageTexture() != nullptr) + ? draw->imageTexture()->textureResourceHash() : 0; - key |= textureHash << kTextureHashShift; - - // If using KHR_blend_equation_advanced, we need a batching barrier - // between draws with different blend modes. If not using - // KHR_blend_equation_advanced, sorting by blend mode may still give - // us better branching on the GPU. - int64_t blendMode = - gpu::ConvertBlendModeToPLSBlendMode(draw->blendMode()); - assert(blendMode <= kBlendModeMask >> kBlendModeShift); - key |= blendMode << kBlendModeShift; - - // msaa mode draws strokes, fills, and even/odd with different - // stencil settings. - int64_t drawContents = static_cast(draw->drawContents()); - assert(drawContents <= kDrawContentsMask >> kDrawContentsShift); - key |= drawContents << kDrawContentsShift; - - // Draw and subpass indices go at the bottom of the key so we can - // reference them again after sorting without affecting the order. - assert(i <= kDrawIndexMask >> kDrawIndexShift); - key |= i << kDrawIndexShift; - - assert((key & kDrawGroupMask) >> kDrawGroupShift == drawGroupIdx); - assert((key & kDrawTypeMask) >> kDrawTypeShift == drawType); - assert((key & kTextureHashMask) >> kTextureHashShift == - textureHash); - assert((key & kBlendModeMask) >> kBlendModeShift == blendMode); - assert((key & kDrawContentsMask) >> kDrawContentsShift == - drawContents); - assert((key & kDrawIndexMask) >> kDrawIndexShift == i); + int64_t key = keyBuilder.buildKey({ + {SortEntry::blendMode, + gpu::ConvertBlendModeToPLSBlendMode(draw->blendMode())}, + {SortEntry::drawContents, draw->drawContents()}, + {SortEntry::drawIndex, i}, + {SortEntry::drawGroup, drawGroupIdx}, + {SortEntry::drawType, draw->type()}, + {SortEntry::subpassIndex, 0}, // This gets added later + + // The hash may lose bits in the key + {SortEntry::textureHash, textureHash, ValidateKeyEntry::no}, + }); // Add the first prepass and subpass, if any. if (draw->prepassCount() > 0) @@ -1339,25 +1684,44 @@ void RenderContext::LogicalFlush::writeResources() } // Add any additional passes. - for (int i = 1; i < maxPasses; ++i) + if (maxSubpasses > 1) { - // Increment the drawGroupIdx and i both at once. (The - // intersectionBoard already reserved "maxPasses" layers of - // drawGroupIndices for us.) - key += (1ll << kDrawGroupShift) + 1; - assert((key & kDrawGroupMask) >> kDrawGroupShift == - drawGroupIdx + i); - assert((key & kSubpassIndexMask) == i); - - if (i < draw->prepassCount()) - { - // Negating the key is an easy way to sort the prepasses - // front-to-back, and before the subpasses. - indirectDrawList.push_back(-key); - } - if (i < draw->subpassCount()) + const auto subpassKeyIncrement = + allSubpassesInSameDrawGroup + // Special case: All subpasses belong to the same + // drawGroup, so only increment subpassIndex. + ? keyBuilder.buildPartialKey({ + {SortEntry::subpassIndex, 1}, + }) + // Usual case: Increment the drawGroup and subpassIndex + // both at once. (The intersectionBoard already reserved + // "maxPasses" layers of drawGroupIndices for us.) + : keyBuilder.buildPartialKey({ + {SortEntry::drawGroup, 1}, + {SortEntry::subpassIndex, 1}, + }); + for (int i = 1; i < maxSubpasses; ++i) { - indirectDrawList.push_back(key); + key += subpassKeyIncrement; + + assert(keyBuilder.extract(SortEntry::drawGroup, + key) == + int16_t(allSubpassesInSameDrawGroup + ? drawGroupIdx + : drawGroupIdx + i)); + assert(keyBuilder.extract(SortEntry::subpassIndex, + key) == i); + + if (i < draw->prepassCount()) + { + // Negating the key is an easy way to sort the prepasses + // front-to-back, and before the subpasses. + indirectDrawList.push_back(-key); + } + if (i < draw->subpassCount()) + { + indirectDrawList.push_back(key); + } } } } @@ -1366,89 +1730,181 @@ void RenderContext::LogicalFlush::writeResources() // Re-order the draws!! std::sort(indirectDrawList.begin(), indirectDrawList.end()); - // Atomic mode sometimes needs to initialize PLS with a draw when the - // backend can't do it with typical clear/load APIs. - if (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics) + assert(m_pendingBarriers == BarrierFlags::none); + if (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics && + platformFeatures.atomicPLSInitNeedsDraw) { - assert(m_pendingBarriers == BarrierFlags::none); - if (platformFeatures.atomicPLSMustBeInitializedAsDraw) - { - m_drawList.emplace_back(m_ctx->perFrameAllocator(), - DrawType::atomicInitialize, - gpu::ShaderMiscFlags::none, - 1, - 0, - BlendMode::srcOver, - ImageSampler::LinearClamp(), - BarrierFlags::none); - } - m_pendingBarriers |= BarrierFlags::plsAtomicPostInit; + // Atomic mode sometimes needs to initialize PLS with a draw when + // the backend can't do it with typical clear/load APIs. + // So far only Metal needs this, and its implementation doesn't + // require a barrier before or after. + m_drawList.emplace_back(m_ctx->perFrameAllocator(), + gpu::DrawType::renderPassInitialize, + m_baselineShaderMiscFlags, + gpu::DrawContents::none, + 1, + 0, + BlendMode::srcOver, + ImageSampler::LinearClamp(), + BarrierFlags::none); + } + else if (m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa && + m_flushDesc.colorLoadAction == + gpu::LoadAction::preserveRenderTarget && + platformFeatures.msaaColorPreserveNeedsDraw) + { + // When implemented with a transient attachment, MSAA needs us to + // draw the old renderTarget contents into the framebuffer at the + // beginning of the render pass when + // LoadAction::preserveRenderTarget is specified. + m_drawList.emplace_back( + m_ctx->perFrameAllocator(), + gpu::DrawType::renderPassInitialize, + m_baselineShaderMiscFlags, + gpu::DrawContents::opaquePaint, + 1, + 0, + // A more realistic value here would be "BlendMode::none" (which + // is what actually happens), but since that isn't a Rive blend + // mode, we just need any value here. It will get ignored by the + // draw. + BlendMode::srcOver, + ImageSampler{.filter = ImageFilter::bilinear}, + // The MSAA init reads the framebuffer, so it needs the + // equivalent of a "dstBlend" barrier. + BarrierFlags::dstBlend); + m_combinedDrawContents |= m_drawList.tail()->drawContents; + // The draw that follows the this init will need a special + // "msaaPostInit" barrier. + pushBarriers(BarrierFlags::msaaPostInit); + assert(m_dstBlendBarrierListTail == &m_firstDstBlendBarrier); + assert(m_firstDstBlendBarrier == nullptr); + m_firstDstBlendBarrier = m_drawList.tail(); + m_dstBlendBarrierListTail = &m_drawList.tail()->nextDstBlendBarrier; } + // Indicates required barriers between draws whose keys differ on the + // given mask. + struct BarriersForKeyDiff + { + int64_t mask; + BarrierFlags barrier; + }; + StackVector barriersForKeyDiffs; + // Find a mask that tells us when to insert barriers, and which barriers // are needed. When the keys of two adjacent draws differ within this // bitmask, we insert a barrier between them. - int64_t needsBarrierMask = 0; - BarrierFlags neededBarriers = BarrierFlags::none; switch (m_flushDesc.interlockMode) { case gpu::InterlockMode::rasterOrdering: - // rasterOrdering mode doesn't reorder draws. + // rasterOrdering and clockwise modes don't reorder draws. RIVE_UNREACHABLE(); case gpu::InterlockMode::atomics: + { // In atomic mode, we need barriers any time draws overlap. // Insert a barrier every time the drawGroupIdx changes. - needsBarrierMask = kDrawGroupMask; - neededBarriers = BarrierFlags::plsAtomic; + barriersForKeyDiffs.push_back( + {keyBuilder.mask(SortEntry::drawGroup), + BarrierFlags::plsAtomic | BarrierFlags::drawBatchBreak}); + // We need a plsAtomic barrier after the initial clears, loads, + // etc. + pushBarriers(BarrierFlags::plsAtomic | + BarrierFlags::drawBatchBreak); + break; + } + + case gpu::InterlockMode::clockwise: + // clockwise mode doesn't need barriers, but we still reorder in + // order to improve batching. break; case gpu::InterlockMode::clockwiseAtomic: + { // In clockwiseAtomic mode, we only need a barrier between the // borrowedCoverage prepasses and the main rendering. Prepasses // have a negative key, so just insert a barrier when the sign // changes. - needsBarrierMask = 1ll << 63; - neededBarriers = BarrierFlags::clockwiseBorrowedCoverage; + constexpr static int64_t SIGN_BIT = (1ll << 63); + barriersForKeyDiffs.push_back( + {SIGN_BIT, + BarrierFlags::clockwiseBorrowedCoverage | + BarrierFlags::drawBatchBreak}); + // Just break batching between draw groups. If we also need a + // dstBlend or "clip read" (plsAtomic) barrier, that will be + // handled with more sophisticated logic later on. + barriersForKeyDiffs.push_back( + {keyBuilder.mask(SortEntry::drawGroup), + BarrierFlags::drawBatchBreak}); + if (indirectDrawList.empty() || indirectDrawList[0] >= 0) + { + // There are no borrowed coverage passes. Initiate the + // transition to the main subpass immediately. + pushBarriers(BarrierFlags::clockwiseBorrowedCoverage); + } break; + } case gpu::InterlockMode::msaa: + { // MSAA mode can't batch draws that overlap because they both // rely on the stencil buffer across subpasses. Stop batching // every time the drawGroupIdx changes. - needsBarrierMask = kDrawGroupMask; + int64_t needsBreakMask = keyBuilder.mask(SortEntry::drawGroup); // MSAA mode draws clips, strokes, fills, and even/odd with // different stencil settings, so these can't be batched. - needsBarrierMask |= kDrawContentsMask; - if (platformFeatures.supportsKHRBlendEquations) + needsBreakMask |= keyBuilder.mask(SortEntry::drawContents); + if (platformFeatures.supportsBlendAdvancedKHR) { // If using KHR_blend_equation_advanced, we also need to // stop batching between blend modes in order to change the // blend equation. - needsBarrierMask |= kBlendModeMask; + needsBreakMask |= keyBuilder.mask(SortEntry::blendMode); } // MSAA barriers only need to prevent batching of draws for now. - // If we also need a dstColorTexture barrier, that will be - // decided later. - neededBarriers = BarrierFlags::drawBatchBreak; + // If we also need a dstBlend barrier, that will be decided + // later. + barriersForKeyDiffs.push_back( + {needsBreakMask, BarrierFlags::drawBatchBreak}); break; + } } // Write out the draw data from the sorted draw list, and build up a // condensed/batched list of low-level draws. - int64_t priorSignedKey = - !indirectDrawList.empty() ? indirectDrawList[0] : 0; + constexpr int64_t BEGIN_KEY = std::numeric_limits::min(); + int64_t priorSignedKey = BEGIN_KEY; + int16_t currentDrawGroup = -1; + DrawBatch* firstBatchInCurrentDrawGroup = nullptr; + + // clockwiseAtomic (CWA) needs more sophisticated barrier logic for + // clips. + bool hasCWAClipReadBarrier = false; + bool currentDrawGroupHasCWAClipUpdate = false; + for (const int64_t signedKey : indirectDrawList) { assert(signedKey >= priorSignedKey); - if ((priorSignedKey & needsBarrierMask) != - (signedKey & needsBarrierMask)) + // The first draw never gets simple barriers. If barriers are + // required before the first draw, those get scheduled outside this + // loop. + if (priorSignedKey != BEGIN_KEY) { - m_pendingBarriers |= neededBarriers; + for (auto [mask, barriers] : barriersForKeyDiffs) + { + if ((priorSignedKey & mask) != (signedKey & mask)) + { + pushBarriers(barriers); + } + } } + int64_t key = abs(signedKey); - uint32_t drawIndex = (key & kDrawIndexMask) >> kDrawIndexShift; - int subpassIndex = key & kSubpassIndexMask; + auto drawIndex = + keyBuilder.extract(SortEntry::drawIndex, key); + auto subpassIndex = + keyBuilder.extract(SortEntry::subpassIndex, key); if (signedKey < 0) { // Negative keys are a prepass. Update the subpassIndex to be @@ -1457,31 +1913,172 @@ void RenderContext::LogicalFlush::writeResources() } // FIXME: m_currentZIndex shouldn't be a stateful variable; it // should be passed to pushToRenderContext() instead. - m_currentZIndex = math::lossless_numeric_cast( - abs(key >> static_cast(kDrawGroupShift))); - m_draws[drawIndex]->pushToRenderContext(this, subpassIndex); + int16_t drawGroup = + keyBuilder.extract(SortEntry::drawGroup, key); + assert(drawGroup > 0); + m_currentZIndex = drawGroup; + + Draw* draw = m_draws[drawIndex].get(); + assert( + draw->drawContents() == + keyBuilder.extract(SortEntry::drawContents, + key)); + assert(draw->blendMode() != BlendMode::srcOver == + draw->hasAdvancedBlend()); + + DrawBatch* batch = draw->pushToRenderContext(this, subpassIndex); + + // Some barriers need more sophisticated logic than "do my keys + // differ". + if ((m_ctx->frameInterlockMode() == + gpu::InterlockMode::clockwiseAtomic || + m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa) && + subpassIndex == 0 && batch != nullptr) + { + // Barriers at this level have to go on the first batch in the + // current drawGroup. Otherwise we might see something get + // reordered like this: + // + // - drawA, subpass0 + // - dstBlendBarrier (because drawB has a dstBlend) + // - drawB, subpass0 + // - drawA, subpass1 + // - drawB, subpass1 + // + // In this scenario, drawA gets a dstBlend barrier between + // subpasses. When dstBlend is implemented as a texture copy, it + // interrupts the render pass and resolves MSAA, causing the + // MSAA data to be lost between supbasses of drawA. + // + // Since drawA and drawB don't overlap, the correct solution is + // to only apply barriers on the first batch of a drawGroup: + // + // - dstBlendBarrier (because drawB has a dstBlend) + // - drawA, subpass0 + // - drawB, subpass0 + // - drawA, subpass1 + // - drawB, subpass1 + // + // (This also leads to fewer barriers overall.) + if (currentDrawGroup != drawGroup) + { + if (currentDrawGroupHasCWAClipUpdate) + { + // Now that we're moving on to a new drawGroup, reset + // hasCWAClipReadBarrier if the clip got written, since + // any future clip reads may overlap what was written. + hasCWAClipReadBarrier = false; + currentDrawGroupHasCWAClipUpdate = false; + } + firstBatchInCurrentDrawGroup = batch; + currentDrawGroup = drawGroup; + } + assert(firstBatchInCurrentDrawGroup != nullptr); + + if (draw->hasAdvancedBlend() && + (m_ctx->frameInterlockMode() != gpu::InterlockMode::msaa || + !m_ctx->platformFeatures() + .supportsBlendAdvancedCoherentKHR)) + { + // An implementation-dependent barrier is required between + // overlapping draws. Add a "dstBlend" barrier and build up + // a list of "dstReads" for the batch. The dstRead list will + // be required in the event that the implementation has to + // handle dstReads by copying out a texture. + assert(draw->nextDstRead() == nullptr); + firstBatchInCurrentDrawGroup->dstReadList = + draw->addToDstReadList( + firstBatchInCurrentDrawGroup->dstReadList); + if (!enums::is_flag_set( + firstBatchInCurrentDrawGroup->barriers, + BarrierFlags::dstBlend)) + { + firstBatchInCurrentDrawGroup->barriers |= + BarrierFlags::dstBlend; + addBatchToDstBarrierList(firstBatchInCurrentDrawGroup); + } + // We either added ourselves to the dstBlendBarrier + // list or merged into a batch that was already part + // of it. + assert(m_dstBlendBarrierListTail == + &firstBatchInCurrentDrawGroup->nextDstBlendBarrier); + } + + // clockwiseAtomic (CWA) needs more sophisticated barrier logic + // for clips. + if (m_ctx->frameInterlockMode() == + gpu::InterlockMode::clockwiseAtomic) + { + if (draw->isClipUpdate()) + { + // Once the clip gets written, it needs a barrier before + // it can be read again from fragment shaders. + // + // NOTE: This won't immediately reset + // "hasCWAClipReadBarrier" because clip reads and writes + // in the same drawGroup don't overlap. Instead, we + // defer resetting hasCWAClipReadBarrier until we begin + // the next drawGroup. + // + // NOTE2: It's ok of activeClip is also set here + // (i.e., nested clip updates, or "clipUpdate | + // activeClip"). Those don't need a barrier. Nested + // clips use hardware blend to apply the existing clip, + // rather than reading it in the fragment shader. + currentDrawGroupHasCWAClipUpdate = true; + } + else if (draw->hasActiveClip() && !hasCWAClipReadBarrier) + { + // Clipped path draws need a barrier because they access + // the clip buffer via input attachment in the fragment + // shader. + firstBatchInCurrentDrawGroup->barriers |= + gpu::BarrierFlags::plsAtomic; + hasCWAClipReadBarrier = true; + } + } + else + { + assert(m_ctx->frameInterlockMode() == + gpu::InterlockMode::msaa); + + // msaa doesn't mix srcOver draws with advanced blend draws. + assert(enums::is_flag_set( + batch->shaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) == + (draw->blendMode() != BlendMode::srcOver)); + + // If using KHR_blend_equation_advanced, we can't mix blend + // modes in a batch. + assert( + !m_ctx->platformFeatures().supportsBlendAdvancedKHR || + batch->firstBlendMode == draw->blendMode()); + } + } + priorSignedKey = signedKey; } + } - // Atomic mode needs one more draw to resolve all the pixels. - if (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics) - { - // We can ignore any pending "plsAtomic" barriers; the - // plsAtomicPreResolve can replace them. - assert((m_pendingBarriers & ~(BarrierFlags::plsAtomic | - BarrierFlags::plsAtomicPostInit)) == - BarrierFlags::none); - m_drawList - .emplace_back(m_ctx->perFrameAllocator(), - DrawType::atomicResolve, - gpu::ShaderMiscFlags::none, - 1, - 0, - BlendMode::srcOver, - ImageSampler::LinearClamp(), - BarrierFlags::plsAtomicPreResolve) - .shaderFeatures = m_combinedShaderFeatures; - } + // Some modes need one more draw to resolve all the pixels. + if (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics || + m_flushDesc.manuallyResolved) + { + m_drawList.emplace_back( + m_ctx->perFrameAllocator(), + gpu::DrawType::renderPassResolve, + m_baselineShaderMiscFlags, + (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics) + ? gpu::DrawContents::none + : gpu::DrawContents::opaquePaint, + 1, + 0, + BlendMode::srcOver, + ImageSampler::LinearClamp(), + (m_ctx->frameInterlockMode() == gpu::InterlockMode::atomics) + ? BarrierFlags::plsAtomicPreResolve + : BarrierFlags::preManualResolve); + m_combinedDrawContents |= m_drawList.tail()->drawContents; } // Write out the draws to the feather atlas. Do this after the main draws @@ -1601,9 +2198,6 @@ void RenderContext::LogicalFlush::writeResources() // Some of the flushDescriptor's data isn't known until after // writeResources(). Update it now that it's known. m_flushDesc.combinedShaderFeatures = m_combinedShaderFeatures; - m_flushDesc.atomicFixedFunctionColorOutput = - m_ctx->frameInterlockMode() == InterlockMode::atomics && - !(m_combinedShaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND); if (m_coverageBufferLength > 0) { @@ -1624,15 +2218,27 @@ void RenderContext::LogicalFlush::writeResources() initialTriangleVertexDataSize; m_flushDesc.drawList = &m_drawList; - + m_flushDesc.firstDstBlendBarrier = m_firstDstBlendBarrier; + m_flushDesc.unresolvedBarriers = m_pendingBarriers; // Write out the uniforms for this flush now that the flushDescriptor is // complete. m_ctx->m_flushUniformData.emplace_back(m_flushDesc, platformFeatures); + +#ifndef NDEBUG + for (const DrawBatch& batch : *m_flushDesc.drawList) + { + assert((batch.drawContents & m_combinedDrawContents) == + batch.drawContents); + assert((batch.shaderFeatures & m_flushDesc.combinedShaderFeatures) == + batch.shaderFeatures); + } +#endif } void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, bool forceRealloc) { + RIVE_PROF_SCOPE_L(1) #if 0 class Logger { @@ -1687,6 +2293,38 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, (newHeight * newWidth * bytesPerPixel) >> 10); } + void logTexture3dSize(const char* name, + size_t oldWidth, + size_t oldHeight, + size_t oldDepth, + size_t newWidth, + size_t newHeight, + size_t newDepth, + size_t bytesPerPixel) + { + m_totalSizeInBytes += newHeight * newWidth * bytesPerPixel; + if (oldWidth == newWidth && oldHeight == newHeight && + oldDepth == newDepth) + { + return; + } + if (!m_hasChanged) + { + printf("RenderContext::setResourceSizes():\n"); + m_hasChanged = true; + } + printf(" resize %s: [%zu x %zu x %zu] -> [%zu x %zu x %zu] " + "(%zu KiB)\n", + name, + oldWidth, + oldHeight, + oldDepth, + newWidth, + newHeight, + newDepth, + (newHeight * newWidth * newDepth * bytesPerPixel) >> 10); + } + ~Logger() { if (!m_hasChanged) @@ -1706,19 +2344,33 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, m_currentResourceAllocations.NAME, \ allocs.NAME, \ allocs.NAME* ITEM_SIZE_IN_BYTES* gpu::kBufferRingSize) -#define LOG_TEXTURE_HEIGHT(NAME, BYTES_PER_ROW) \ +#define LOG_TEXTURE_SIZE(NAME, BYTES_PER_VALUE) \ logger.logSize(#NAME, \ m_currentResourceAllocations.NAME, \ allocs.NAME, \ - allocs.NAME* BYTES_PER_ROW) -#define LOG_TEXTURE_SIZE(WIDTH_NAME, HEIGHT_NAME, BYTES_PER_PIXEL) \ - logger.logTextureSize(#WIDTH_NAME, \ - #HEIGHT_NAME, \ - m_currentResourceAllocations.WIDTH_NAME, \ - m_currentResourceAllocations.HEIGHT_NAME, \ - allocs.WIDTH_NAME, \ - allocs.HEIGHT_NAME, \ - BYTES_PER_PIXEL) + allocs.NAME*(BYTES_PER_VALUE)) +#define LOG_TEXTURE_2D_SIZE(NAME, WIDTH_NAME, HEIGHT_NAME, BYTES_PER_PIXEL) \ + logger.logTexture3dSize(NAME, \ + m_currentResourceAllocations.WIDTH_NAME, \ + m_currentResourceAllocations.HEIGHT_NAME, \ + 1, \ + allocs.WIDTH_NAME, \ + allocs.HEIGHT_NAME, \ + 1, \ + BYTES_PER_PIXEL) +#define LOG_TEXTURE_3D_SIZE(NAME, \ + WIDTH_NAME, \ + HEIGHT_NAME, \ + DEPTH_NAME, \ + BYTES_PER_PIXEL) \ + logger.logTexture3dSize(NAME, \ + m_currentResourceAllocations.WIDTH_NAME, \ + m_currentResourceAllocations.HEIGHT_NAME, \ + m_currentResourceAllocations.DEPTH_NAME, \ + allocs.WIDTH_NAME, \ + allocs.HEIGHT_NAME, \ + allocs.DEPTH_NAME, \ + BYTES_PER_PIXEL) #define LOG_BUFFER_SIZE(NAME, BYTES_PER_ELEMENT) \ logger.logSize(#NAME, \ m_currentResourceAllocations.NAME, \ @@ -1726,8 +2378,13 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, allocs.NAME* BYTES_PER_ELEMENT) #else #define LOG_BUFFER_RING_SIZE(NAME, ITEM_SIZE_IN_BYTES) -#define LOG_TEXTURE_HEIGHT(NAME, BYTES_PER_ROW) -#define LOG_TEXTURE_SIZE(WIDTH_NAME, HEIGHT_NAME, BYTES_PER_PIXEL) +#define LOG_TEXTURE_SIZE(NAME, BYTES_PER_ROW) +#define LOG_TEXTURE_2D_SIZE(NAME, WIDTH_NAME, HEIGHT_NAME, BYTES_PER_PIXEL) +#define LOG_TEXTURE_3D_SIZE(NAME, \ + WIDTH_NAME, \ + HEIGHT_NAME, \ + DEPTH_NAME, \ + BYTES_PER_PIXEL) #define LOG_BUFFER_SIZE(NAME, BYTES_PER_ELEMENT) #endif @@ -1819,7 +2476,7 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, } assert(allocs.gradTextureHeight <= kMaxTextureHeight); - LOG_TEXTURE_HEIGHT(gradTextureHeight, gpu::kGradTextureWidth * 4); + LOG_TEXTURE_SIZE(gradTextureHeight, gpu::kGradTextureWidth * 4); if (allocs.gradTextureHeight != m_currentResourceAllocations.gradTextureHeight || forceRealloc) @@ -1830,7 +2487,7 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, } assert(allocs.tessTextureHeight <= kMaxTextureHeight); - LOG_TEXTURE_HEIGHT(tessTextureHeight, gpu::kTessTextureWidth * 4 * 4); + LOG_TEXTURE_SIZE(tessTextureHeight, gpu::kTessTextureWidth * 4 * 4); if (allocs.tessTextureHeight != m_currentResourceAllocations.tessTextureHeight || forceRealloc) @@ -1844,7 +2501,10 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, allocs.atlasTextureWidth <= frameDescriptor().renderTargetWidth); assert(allocs.atlasTextureHeight <= atlasMaxSize() || allocs.atlasTextureHeight <= frameDescriptor().renderTargetHeight); - LOG_TEXTURE_SIZE(atlasTextureWidth, atlasTextureHeight, sizeof(uint16_t)); + LOG_TEXTURE_2D_SIZE("atlasTexture", + atlasTextureWidth, + atlasTextureHeight, + sizeof(uint16_t)); if (allocs.atlasTextureWidth != m_currentResourceAllocations.atlasTextureWidth || allocs.atlasTextureHeight != @@ -1856,6 +2516,51 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, math::lossless_numeric_cast(allocs.atlasTextureHeight)); } + assert(allocs.plsTransientBackingPlaneCount <= + RenderContextImpl::PLS_TRANSIENT_BACKING_MAX_PLANE_COUNT); + LOG_TEXTURE_3D_SIZE("plsTransientBacking", + plsTransientBackingWidth, + plsTransientBackingHeight, + plsTransientBackingPlaneCount, + sizeof(uint32_t)); + if (allocs.plsTransientBackingWidth != + m_currentResourceAllocations.plsTransientBackingWidth || + allocs.plsTransientBackingHeight != + m_currentResourceAllocations.plsTransientBackingHeight || + allocs.plsTransientBackingPlaneCount != + m_currentResourceAllocations.plsTransientBackingPlaneCount || + forceRealloc) + { + m_impl->resizeTransientPLSBacking( + math::lossless_numeric_cast( + allocs.plsTransientBackingWidth), + math::lossless_numeric_cast( + allocs.plsTransientBackingHeight), + math::lossless_numeric_cast( + allocs.plsTransientBackingPlaneCount)); + } + + assert(allocs.plsAtomicCoverageBackingWidth <= + allocs.plsTransientBackingWidth); + assert(allocs.plsAtomicCoverageBackingHeight <= + allocs.plsTransientBackingHeight); + LOG_TEXTURE_2D_SIZE("plsAtomicCoverageBacking", + plsAtomicCoverageBackingWidth, + plsAtomicCoverageBackingHeight, + sizeof(uint32_t)); + if (allocs.plsAtomicCoverageBackingWidth != + m_currentResourceAllocations.plsAtomicCoverageBackingWidth || + allocs.plsAtomicCoverageBackingHeight != + m_currentResourceAllocations.plsAtomicCoverageBackingHeight || + forceRealloc) + { + m_impl->resizeAtomicCoverageBacking( + math::lossless_numeric_cast( + allocs.plsAtomicCoverageBackingWidth), + math::lossless_numeric_cast( + allocs.plsAtomicCoverageBackingHeight)); + } + assert(allocs.coverageBufferLength <= platformFeatures().maxCoverageBufferLength); LOG_BUFFER_SIZE(coverageBufferLength, sizeof(uint32_t)); @@ -1874,90 +2579,111 @@ void RenderContext::setResourceSizes(ResourceAllocationCounts allocs, m_currentResourceAllocations = allocs; } -void RenderContext::mapResourceBuffers( +bool RenderContext::mapResourceBuffers( const ResourceAllocationCounts& mapCounts) { + RIVE_PROF_SCOPE_L(1) + +#define HANDLE_MAP_FAILURE(...) \ + do \ + { \ + if (!(__VA_ARGS__)) \ + { \ + return false; \ + } \ + } while (false) + if (mapCounts.flushUniformBufferCount > 0) { - m_flushUniformData.mapElements( + HANDLE_MAP_FAILURE(m_flushUniformData.mapElements( m_impl.get(), &RenderContextImpl::mapFlushUniformBuffer, - mapCounts.flushUniformBufferCount); + mapCounts.flushUniformBufferCount)); } assert(m_flushUniformData.hasRoomFor(mapCounts.flushUniformBufferCount)); if (mapCounts.imageDrawUniformBufferCount > 0) { - m_imageDrawUniformData.mapElements( + HANDLE_MAP_FAILURE(m_imageDrawUniformData.mapElements( m_impl.get(), &RenderContextImpl::mapImageDrawUniformBuffer, - mapCounts.imageDrawUniformBufferCount); + mapCounts.imageDrawUniformBufferCount)); } assert(m_imageDrawUniformData.hasRoomFor( mapCounts.imageDrawUniformBufferCount > 0)); if (mapCounts.pathBufferCount > 0) { - m_pathData.mapElements(m_impl.get(), - &RenderContextImpl::mapPathBuffer, - mapCounts.pathBufferCount); + HANDLE_MAP_FAILURE( + m_pathData.mapElements(m_impl.get(), + &RenderContextImpl::mapPathBuffer, + mapCounts.pathBufferCount)); } assert(m_pathData.hasRoomFor(mapCounts.pathBufferCount)); if (mapCounts.paintBufferCount > 0) { - m_paintData.mapElements(m_impl.get(), - &RenderContextImpl::mapPaintBuffer, - mapCounts.paintBufferCount); + HANDLE_MAP_FAILURE( + m_paintData.mapElements(m_impl.get(), + &RenderContextImpl::mapPaintBuffer, + mapCounts.paintBufferCount)); } assert(m_paintData.hasRoomFor(mapCounts.paintBufferCount)); if (mapCounts.paintAuxBufferCount > 0) { - m_paintAuxData.mapElements(m_impl.get(), - &RenderContextImpl::mapPaintAuxBuffer, - mapCounts.paintAuxBufferCount); + HANDLE_MAP_FAILURE( + m_paintAuxData.mapElements(m_impl.get(), + &RenderContextImpl::mapPaintAuxBuffer, + mapCounts.paintAuxBufferCount)); } assert(m_paintAuxData.hasRoomFor(mapCounts.paintAuxBufferCount)); if (mapCounts.contourBufferCount > 0) { - m_contourData.mapElements(m_impl.get(), - &RenderContextImpl::mapContourBuffer, - mapCounts.contourBufferCount); + HANDLE_MAP_FAILURE( + m_contourData.mapElements(m_impl.get(), + &RenderContextImpl::mapContourBuffer, + mapCounts.contourBufferCount)); } assert(m_contourData.hasRoomFor(mapCounts.contourBufferCount)); if (mapCounts.gradSpanBufferCount > 0) { - m_gradSpanData.mapElements(m_impl.get(), - &RenderContextImpl::mapGradSpanBuffer, - mapCounts.gradSpanBufferCount); + HANDLE_MAP_FAILURE( + m_gradSpanData.mapElements(m_impl.get(), + &RenderContextImpl::mapGradSpanBuffer, + mapCounts.gradSpanBufferCount)); } assert(m_gradSpanData.hasRoomFor(mapCounts.gradSpanBufferCount)); if (mapCounts.tessSpanBufferCount > 0) { - m_tessSpanData.mapElements(m_impl.get(), - &RenderContextImpl::mapTessVertexSpanBuffer, - mapCounts.tessSpanBufferCount); + HANDLE_MAP_FAILURE(m_tessSpanData.mapElements( + m_impl.get(), + &RenderContextImpl::mapTessVertexSpanBuffer, + mapCounts.tessSpanBufferCount)); } assert(m_tessSpanData.hasRoomFor(mapCounts.tessSpanBufferCount)); if (mapCounts.triangleVertexBufferCount > 0) { - m_triangleVertexData.mapElements( + HANDLE_MAP_FAILURE(m_triangleVertexData.mapElements( m_impl.get(), &RenderContextImpl::mapTriangleVertexBuffer, - mapCounts.triangleVertexBufferCount); + mapCounts.triangleVertexBufferCount)); } assert( m_triangleVertexData.hasRoomFor(mapCounts.triangleVertexBufferCount)); + +#undef HANDLE_MAP_FAILURE + return true; } void RenderContext::unmapResourceBuffers( const ResourceAllocationCounts& mapCounts) { + RIVE_PROF_SCOPE_L(1) if (m_flushUniformData) { m_flushUniformData.unmapElements( @@ -2021,6 +2747,7 @@ void RenderContext::unmapResourceBuffers( uint32_t RenderContext::incrementCoverageBufferPrefix( bool* needsCoverageBufferClear) { + RIVE_PROF_SCOPE_L(1) assert(m_didBeginFrame); assert(frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic); do @@ -2032,7 +2759,7 @@ uint32_t RenderContext::incrementCoverageBufferPrefix( // monotonically increasing. *needsCoverageBufferClear = true; } - m_coverageBufferPrefix += 1 << CLOCKWISE_COVERAGE_BIT_COUNT; + m_coverageBufferPrefix += CLOCKWISE_COVERAGE_PREFIX_ONE_VALUE; } while (m_coverageBufferPrefix == 0); return m_coverageBufferPrefix; @@ -2058,6 +2785,7 @@ uint32_t RenderContext::LogicalFlush::allocateOuterCubicTessVertices( uint32_t RenderContext::LogicalFlush::pushPath(const PathDraw* draw) { + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); ++m_currentPathID; @@ -2110,6 +2838,7 @@ RenderContext::TessellationWriter::TessellationWriter( m_pathTessLocation(forwardTessLocation), m_pathMirroredTessLocation(mirroredTessLocation) { + RIVE_PROF_SCOPE_L(2) RIVE_DEBUG_CODE(m_expectedPathTessEndLocation = m_pathTessLocation + forwardTessVertexCount;) RIVE_DEBUG_CODE(m_expectedPathMirroredTessEndLocation = @@ -2138,6 +2867,7 @@ uint32_t RenderContext::LogicalFlush::pushContour(uint32_t pathID, bool closed, uint32_t vertexIndex0) { + RIVE_PROF_SCOPE_L(2) assert(pathID != 0); assert(isStroke || closed); @@ -2160,6 +2890,7 @@ uint32_t RenderContext::TessellationWriter::pushContour( bool closed, uint32_t paddingVertexCount) { + RIVE_PROF_SCOPE_L(2) // The first curve of the contour will be pre-padded with // 'paddingVertexCount' tessellation vertices, colocated at T=0. The caller // must use this argument align the end of the contour on a boundary of the @@ -2182,13 +2913,19 @@ void RenderContext::TessellationWriter::pushCubic( uint32_t joinSegmentCount, uint32_t contourIDWithFlags) { + RIVE_PROF_SCOPE_L(3) assert(0 <= parametricSegmentCount && parametricSegmentCount <= kMaxParametricSegments); assert(0 <= polarSegmentCount && polarSegmentCount <= kMaxPolarSegments); assert(joinSegmentCount > 0); - assert((contourIDWithFlags & 0xffff) == - (m_flush->m_currentContourID & 0xffff)); - assert((contourIDWithFlags & 0xffff) != 0); // contourID can't be zero. + assert((contourIDWithFlags & CONTOUR_ID_MASK) == + (m_flush->m_currentContourID & CONTOUR_ID_MASK)); + // contourID can't be zero. + assert((contourIDWithFlags & CONTOUR_ID_MASK) != 0); + // contourID can't be out of range in the contour buffer. (Contour buffer + // indices are 1-based.) + assert((contourIDWithFlags & CONTOUR_ID_MASK) <= + m_flush->desc().contourCount); // Polar and parametric segments share the same beginning and ending // vertices, so the merged *vertex* count is equal to the sum of polar and @@ -2247,6 +2984,7 @@ RIVE_ALWAYS_INLINE void RenderContext::TessellationWriter:: uint32_t joinSegmentCount, uint32_t contourIDWithFlags) { + RIVE_PROF_SCOPE_L(3) assert(totalVertexCount > 0); uint32_t y = m_pathTessLocation / kTessTextureWidth; @@ -2385,6 +3123,7 @@ RIVE_ALWAYS_INLINE void RenderContext::TessellationWriter:: void RenderContext::LogicalFlush::pushPaddingVertices(uint32_t count, uint32_t tessLocation) { + RIVE_PROF_SCOPE_L(3) assert(m_hasDoneLayout); assert(count > 0); @@ -2403,13 +3142,14 @@ void RenderContext::LogicalFlush::pushPaddingVertices(uint32_t count, INVALID_CONTOUR_ID_WITH_FLAGS); } -void RenderContext::LogicalFlush::pushMidpointFanDraw( +gpu::DrawBatch& RenderContext::LogicalFlush::pushMidpointFanDraw( const PathDraw* draw, gpu::DrawType drawType, uint32_t tessVertexCount, uint32_t tessLocation, gpu::ShaderMiscFlags shaderMiscFlags) { + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); uint32_t baseInstance = math::lossless_numeric_cast( @@ -2421,16 +3161,21 @@ void RenderContext::LogicalFlush::pushMidpointFanDraw( // flush() is responsible for alignment. assert(instanceCount * kMidpointFanPatchSegmentSpan == tessVertexCount); - pushPathDraw(draw, drawType, shaderMiscFlags, instanceCount, baseInstance); + return pushPathDraw(draw, + drawType, + shaderMiscFlags, + instanceCount, + baseInstance); } -void RenderContext::LogicalFlush::pushOuterCubicsDraw( +gpu::DrawBatch& RenderContext::LogicalFlush::pushOuterCubicsDraw( const PathDraw* draw, gpu::DrawType drawType, uint32_t tessVertexCount, uint32_t tessLocation, gpu::ShaderMiscFlags shaderMiscFlags) { + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); uint32_t baseInstance = math::lossless_numeric_cast( @@ -2442,15 +3187,21 @@ void RenderContext::LogicalFlush::pushOuterCubicsDraw( // flush() is responsible for alignment. assert(instanceCount * kOuterCurvePatchSegmentSpan == tessVertexCount); - pushPathDraw(draw, drawType, shaderMiscFlags, instanceCount, baseInstance); + return pushPathDraw(draw, + drawType, + shaderMiscFlags, + instanceCount, + baseInstance); } -size_t RenderContext::LogicalFlush::pushInteriorTriangulationDraw( +gpu::DrawBatch* RenderContext::LogicalFlush::pushInteriorTriangulationDraw( const PathDraw* draw, uint32_t pathID, gpu::WindingFaces windingFaces, - gpu::ShaderMiscFlags shaderMiscFlags) + gpu::ShaderMiscFlags shaderMiscFlags RIVE_DEBUG_CODE(, + size_t* vertexCounter)) { + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); assert(pathID != 0); @@ -2462,19 +3213,23 @@ size_t RenderContext::LogicalFlush::pushInteriorTriangulationDraw( &m_ctx->m_triangleVertexData); assert(baseVertex + actualVertexCount == m_ctx->m_triangleVertexData.elementsWritten()); + RIVE_DEBUG_CODE(*vertexCounter += actualVertexCount;) if (actualVertexCount > 0) { - pushPathDraw(draw, - DrawType::interiorTriangulation, - shaderMiscFlags, - math::lossless_numeric_cast(actualVertexCount), - baseVertex); + return &pushPathDraw( + draw, + DrawType::interiorTriangulation, + shaderMiscFlags, + math::lossless_numeric_cast(actualVertexCount), + baseVertex); } - return actualVertexCount; + return nullptr; } -void RenderContext::LogicalFlush::pushAtlasBlit(PathDraw* draw, uint32_t pathID) +gpu::DrawBatch& RenderContext::LogicalFlush::pushAtlasBlit(PathDraw* draw, + uint32_t pathID) { + RIVE_PROF_SCOPE_L(2) auto baseVertex = math::lossless_numeric_cast( m_ctx->m_triangleVertexData.elementsWritten()); auto [l, t, r, b] = AABB(draw->pixelBounds()); @@ -2484,15 +3239,17 @@ void RenderContext::LogicalFlush::pushAtlasBlit(PathDraw* draw, uint32_t pathID) m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, b}, 1, pathID); m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, t}, 1, pathID); m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, t}, 1, pathID); - pushPathDraw(draw, - DrawType::atlasBlit, - gpu::ShaderMiscFlags::none, - 6, - baseVertex); + return pushPathDraw(draw, + DrawType::atlasBlit, + m_baselineShaderMiscFlags, + 6, + baseVertex); } -void RenderContext::LogicalFlush::pushImageRectDraw(ImageRectDraw* draw) +gpu::DrawBatch& RenderContext::LogicalFlush::pushImageRectDraw( + ImageRectDraw* draw) { + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); // If we support image paints for paths, the client should use pushPath() @@ -2509,17 +3266,19 @@ void RenderContext::LogicalFlush::pushImageRectDraw(ImageRectDraw* draw) DrawBatch& batch = pushDraw(draw, DrawType::imageRect, - gpu::ShaderMiscFlags::none, + m_baselineShaderMiscFlags, PaintType::image, 1, 0); batch.imageDrawDataOffset = math::lossless_numeric_cast(imageDrawDataOffset); + return batch; } -void RenderContext::LogicalFlush::pushImageMeshDraw(ImageMeshDraw* draw) +gpu::DrawBatch& RenderContext::LogicalFlush::pushImageMeshDraw( + ImageMeshDraw* draw) { - + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); size_t imageDrawDataOffset = m_ctx->m_imageDrawUniformData.bytesWritten(); @@ -2532,7 +3291,7 @@ void RenderContext::LogicalFlush::pushImageMeshDraw(ImageMeshDraw* draw) DrawBatch& batch = pushDraw(draw, DrawType::imageMesh, - gpu::ShaderMiscFlags::none, + m_baselineShaderMiscFlags, PaintType::image, draw->indexCount(), 0); @@ -2541,11 +3300,12 @@ void RenderContext::LogicalFlush::pushImageMeshDraw(ImageMeshDraw* draw) batch.indexBuffer = draw->indexBuffer(); batch.imageDrawDataOffset = math::lossless_numeric_cast(imageDrawDataOffset); + return batch; } -void RenderContext::LogicalFlush::pushStencilClipResetDraw( - StencilClipReset* draw) +gpu::DrawBatch& RenderContext::LogicalFlush::pushClipResetDraw(ClipReset* draw) { + RIVE_PROF_SCOPE_L(2) assert(m_hasDoneLayout); uint32_t baseVertex = math::lossless_numeric_cast( @@ -2561,12 +3321,12 @@ void RenderContext::LogicalFlush::pushStencilClipResetDraw( m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, b}, 0, z); m_ctx->m_triangleVertexData.emplace_back(Vec2D{l, t}, 0, z); m_ctx->m_triangleVertexData.emplace_back(Vec2D{r, t}, 0, z); - pushDraw(draw, - DrawType::msaaStencilClipReset, - gpu::ShaderMiscFlags::none, - PaintType::clipUpdate, - 6, - baseVertex); + return pushDraw(draw, + DrawType::clipReset, + gpu::ShaderMiscFlags::none, + PaintType::clipUpdate, + 6, + baseVertex); } gpu::DrawBatch& RenderContext::LogicalFlush::pushPathDraw( @@ -2576,8 +3336,20 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushPathDraw( uint32_t vertexCount, uint32_t baseVertex) { + RIVE_PROF_SCOPE_L(3) assert(m_hasDoneLayout); + // Clockwise fills get their own shaders in rasterOrdering mode. + // TODO: eventually we will use draw_clockwise_path.frag for these + // draws in rasterOrdering mode, instead of just making a variant of + // draw_raster_order_path.frag. + if (m_ctx->frameInterlockMode() == gpu::InterlockMode::rasterOrdering && + enums::is_flag_set(draw->drawContents(), + gpu::DrawContents::clockwiseFill)) + { + shaderMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill; + } + DrawBatch& batch = pushDraw(draw, drawType, shaderMiscFlags, @@ -2592,9 +3364,11 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushPathDraw( { pathShaderFeatures |= ShaderFeatures::ENABLE_FEATHER; } - if (draw->drawContents() & gpu::DrawContents::evenOddFill) + if (enums::is_flag_set(draw->drawContents(), + gpu::DrawContents::evenOddFill)) { - assert(!(shaderMiscFlags & gpu::ShaderMiscFlags::clockwiseFill)); + assert(!enums::is_flag_set(batch.shaderMiscFlags, + gpu::ShaderMiscFlags::clockwiseFill)); pathShaderFeatures |= ShaderFeatures::ENABLE_EVEN_ODD; } constexpr static gpu::DrawContents NESTED_CLIP_FLAGS = @@ -2605,39 +3379,36 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushPathDraw( } batch.shaderFeatures |= pathShaderFeatures & m_ctx->m_frameShaderFeaturesMask; - m_combinedShaderFeatures |= batch.shaderFeatures; assert( (batch.shaderFeatures & gpu::ShaderFeaturesMaskFor(drawType, m_ctx->frameInterlockMode())) == batch.shaderFeatures); + m_combinedShaderFeatures |= batch.shaderFeatures; return batch; } -RIVE_ALWAYS_INLINE static bool can_combine_draw_contents( - gpu::InterlockMode interlockMode, - gpu::DrawContents batchContents, - const Draw* draw) -{ - // Feathered fills should never attempt to combine with fills, strokes, or - // feathered strokes because they use a different DrawType. - assert((batchContents & gpu::DrawContents::featheredFill).bits() == - (draw->drawContents() & gpu::DrawContents::featheredFill).bits()); - - constexpr static auto ANY_FILL = gpu::DrawContents::clockwiseFill | - gpu::DrawContents::evenOddFill | - gpu::DrawContents::nonZeroFill; - // Raster ordering uses a different shader for clockwise fills, so we - // can't combine both legacy and clockwise fills into the same draw. - if (interlockMode == gpu::InterlockMode::rasterOrdering && - // Anything can be combined if either the existing batch or the new draw - // don't have fills yet. - (batchContents & ANY_FILL) && (draw->drawContents() & ANY_FILL)) - { - assert(!(draw->drawContents() & gpu::DrawContents::stroke)); - return (batchContents & gpu::DrawContents::clockwiseFill).bits() == - (draw->drawContents() & gpu::DrawContents::clockwiseFill).bits(); +RIVE_ALWAYS_INLINE static bool can_combine_shader_misc_flags( + const gpu::DrawBatch* batch, + const Draw* draw, + gpu::ShaderMiscFlags shaderMiscFlags) +{ + // If a path doesn't have ANY_PATH_FILL bits, it means it's a stroke. + constexpr static auto ANY_PATH_FILL = gpu::DrawContents::clockwiseFill | + gpu::DrawContents::evenOddFill | + gpu::DrawContents::nonZeroFill; + + gpu::ShaderMiscFlags compareMask = ~gpu::ShaderMiscFlags::none; + + // Strokes draw identically in the clockwise and legacy shaders, so strokes + // can be combined with paths of any fill type. + if ((enums::no_flags_set(batch->drawContents, ANY_PATH_FILL) || + enums::no_flags_set(draw->drawContents(), ANY_PATH_FILL))) + { + compareMask &= ~gpu::ShaderMiscFlags::clockwiseFill; } - return true; + + return (batch->shaderMiscFlags & compareMask) == + (shaderMiscFlags & compareMask); } RIVE_ALWAYS_INLINE static bool can_combine_draw_images( @@ -2666,9 +3437,49 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw( uint32_t elementCount, uint32_t baseElement) { + RIVE_PROF_SCOPE_L(3) assert(m_hasDoneLayout); assert(elementCount > 0); + shaderMiscFlags |= m_baselineShaderMiscFlags; + + if ((m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwise || + (m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic && + !enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass))) && + enums::is_flag_set(draw->drawContents(), gpu::DrawContents::clipUpdate)) + { + // Clockwise modes give clip updates a dedicated draw by setting + // gpu::ShaderMiscFlags::clipUpdateOnly. + shaderMiscFlags |= gpu::ShaderMiscFlags::clipUpdateOnly; + if (m_ctx->frameInterlockMode() == + gpu::InterlockMode::clockwiseAtomic && + enums::is_flag_set(draw->drawContents(), + gpu::DrawContents::activeClip)) + { + // clockwiseAtomic takes it a step futher and separates out nested + // clip updates into their own draw type. + shaderMiscFlags |= gpu::ShaderMiscFlags::nestedClipUpdateOnly; + } + } + + // In clockwiseAtomic and msaa modes, individual draws can use + // fixedFunctionColorOutput even if the render pass as a whole does not. + if (m_ctx->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic) + { + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass) || + draw->blendMode() == BlendMode::srcOver) + { + shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput; + } + } + else if (m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa && + draw->blendMode() == BlendMode::srcOver) + { + shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput; + } + bool canMergeWithPreviousBatch; switch (drawType) { @@ -2684,22 +3495,23 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw( case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - if (!m_drawList.empty() && m_pendingBarriers == BarrierFlags::none) + case DrawType::clipReset: + if (!m_drawList.empty() && + !enums::is_flag_set(m_pendingBarriers, + gpu::BarrierFlags::drawBatchBreak)) { - const DrawBatch& currentBatch = m_drawList.tail(); + const DrawBatch* currentBatch = m_drawList.tail(); canMergeWithPreviousBatch = - currentBatch.drawType == drawType && - currentBatch.shaderMiscFlags == shaderMiscFlags && - can_combine_draw_contents(m_ctx->frameInterlockMode(), - currentBatch.drawContents, - draw) && - can_combine_draw_images(currentBatch.imageTexture, + currentBatch->drawType == drawType && + can_combine_shader_misc_flags(currentBatch, + draw, + shaderMiscFlags) && + can_combine_draw_images(currentBatch->imageTexture, draw->imageTexture(), - currentBatch.imageSampler, + currentBatch->imageSampler, draw->imageSampler()); if (canMergeWithPreviousBatch && - currentBatch.baseElement + currentBatch.elementCount != + currentBatch->baseElement + currentBatch->elementCount != baseElement) { // In MSAA mode, multiple subpasses reference the same @@ -2718,34 +3530,52 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw( // own unique uniforms. case DrawType::imageRect: case DrawType::imageMesh: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: canMergeWithPreviousBatch = false; break; } DrawBatch* batch; - if (canMergeWithPreviousBatch) + if (!canMergeWithPreviousBatch) + { + batch = m_drawList.emplace_back(m_ctx->perFrameAllocator(), + drawType, + shaderMiscFlags, + draw->drawContents(), + elementCount, + baseElement, + draw->blendMode(), + draw->imageSampler(), + m_pendingBarriers); + } + else { - batch = &m_drawList.tail(); - assert(m_pendingBarriers == BarrierFlags::none); + batch = m_drawList.tail(); assert(batch->drawType == drawType); - assert(batch->shaderMiscFlags == shaderMiscFlags); assert(batch->baseElement + batch->elementCount == baseElement); + batch->elementCount += elementCount; + + // clockwise doesn't mix regular draws and clip updates. + assert(m_ctx->frameInterlockMode() != gpu::InterlockMode::clockwise || + (batch->drawContents & gpu::DrawContents::clipUpdate) == + (draw->drawContents() & gpu::DrawContents::clipUpdate)); + + // Feathered fills should never combine with fills, strokes, or + // feathered strokes because they use a different DrawType. + assert((batch->drawContents & gpu::DrawContents::featheredFill) == + (draw->drawContents() & gpu::DrawContents::featheredFill)); + + // msaa can't mix drawContents in a batch. + assert(m_ctx->frameInterlockMode() != gpu::InterlockMode::msaa || + batch->drawContents == draw->drawContents()); + + batch->shaderMiscFlags |= shaderMiscFlags; + batch->drawContents |= draw->drawContents(); + batch->barriers |= m_pendingBarriers; } - else - { - batch = &m_drawList.emplace_back( - m_ctx->perFrameAllocator(), - drawType, - shaderMiscFlags, - elementCount, - baseElement, - draw->blendMode(), - draw->imageSampler(), - std::exchange(m_pendingBarriers, BarrierFlags::none)); - } + m_pendingBarriers = gpu::BarrierFlags::none; // If the batch was merged into a previous one, this ensures it was a valid // merge. @@ -2765,9 +3595,19 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw( { shaderFeatures |= ShaderFeatures::ENABLE_CLIP_RECT; } + + if (frameDescriptor().ditherMode == + gpu::DitherMode::interleavedGradientNoise) + { + shaderFeatures |= ShaderFeatures::ENABLE_DITHER; + } + if (paintType != PaintType::clipUpdate && - !(shaderMiscFlags & gpu::ShaderMiscFlags::borrowedCoveragePrepass)) + !enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)) { + assert(!enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly)); switch (draw->blendMode()) { case BlendMode::hue: @@ -2794,14 +3634,11 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw( } } batch->shaderFeatures |= shaderFeatures & m_ctx->m_frameShaderFeaturesMask; - m_combinedShaderFeatures |= batch->shaderFeatures; assert( (batch->shaderFeatures & gpu::ShaderFeaturesMaskFor(drawType, m_ctx->frameInterlockMode())) == batch->shaderFeatures); - batch->drawContents |= draw->drawContents(); - if (paintType == PaintType::image) { assert(draw->imageTexture() != nullptr); @@ -2812,41 +3649,7 @@ gpu::DrawBatch& RenderContext::LogicalFlush::pushDraw( assert(batch->imageTexture == draw->imageTexture()); } - if (m_ctx->frameInterlockMode() == gpu::InterlockMode::msaa) - { - // msaa can't mix drawContents in a batch. - assert(batch->drawContents == draw->drawContents()); - // msaa does't mix src-over draws with advanced blend draws. - assert((batch->shaderFeatures & - gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND) == - (draw->blendMode() != BlendMode::srcOver)); - // If using KHR_blend_equation_advanced, we can't mix blend modes in a - // batch. - assert(!m_ctx->platformFeatures().supportsKHRBlendEquations || - batch->firstBlendMode == draw->blendMode()); - if (draw->blendMode() != BlendMode::srcOver && - !m_ctx->platformFeatures().supportsKHRBlendEquations) - { - // The MSAA shader needs to do a manual blend mode. Add a - // "dstColorTexture" barrier and build up a list of "dstReads" for - // the batch. In MSAA mode, we don't always have a mechanism for - // shaders to read the framebuffer, so the backend may have to blit - // their bounding boxes to a separate texture that mirrors the - // framebuffer. - // - // (But if the draw already has a "nextDstRead" neighbor, do - // nothing. It means an earlier subpass will already issue the - // barrier and sync this region of the framebuffer. Since nothing - // that overlaps will be ordered between that first subpass and us, - // that barrier for the first subpass is all we need.) - if (draw->nextDstRead() == nullptr) - { - batch->barriers |= BarrierFlags::dstColorTexture; - batch->dstReadList = draw->addToDstReadList(batch->dstReadList); - } - } - } - + m_combinedShaderFeatures |= batch->shaderFeatures; return *batch; } } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/rive_render_paint.cpp b/thirdparty/rive_renderer/source/rive_render_paint.cpp index 3833519d2..f5d19d671 100644 --- a/thirdparty/rive_renderer/source/rive_render_paint.cpp +++ b/thirdparty/rive_renderer/source/rive_render_paint.cpp @@ -31,6 +31,15 @@ void RiveRenderPaint::shader(rcp shader) m_imageTexture.reset(); } +rcp RiveRenderPaint::getGradientWithOpacity(float opacity) const +{ + if (m_gradient) + { + return m_gradient->getModulated(opacity); + } + return nullptr; +} + void RiveRenderPaint::image(rcp imageTexture, float opacity) { m_paintType = gpu::PaintType::image; diff --git a/thirdparty/rive_renderer/source/rive_render_paint.hpp b/thirdparty/rive_renderer/source/rive_render_paint.hpp index 54baf38e4..4b347b0d9 100644 --- a/thirdparty/rive_renderer/source/rive_render_paint.hpp +++ b/thirdparty/rive_renderer/source/rive_render_paint.hpp @@ -45,6 +45,7 @@ class RiveRenderPaint : public LITE_RTTI_OVERRIDE(RenderPaint, RiveRenderPaint) bool getIsStroked() const { return m_stroked; } ColorInt getColor() const { return m_simpleValue.color; } const gpu::Gradient* getGradient() const { return m_gradient.get(); } + rcp getGradientWithOpacity(float opacity) const; gpu::Texture* getImageTexture() const { return m_imageTexture.get(); } ImageSampler getImageSampler() const { return m_imageSampler; } float getImageOpacity() const { return m_simpleValue.imageOpacity; } diff --git a/thirdparty/rive_renderer/source/rive_render_path.cpp b/thirdparty/rive_renderer/source/rive_render_path.cpp index 8e90d4579..a1db7c353 100644 --- a/thirdparty/rive_renderer/source/rive_render_path.cpp +++ b/thirdparty/rive_renderer/source/rive_render_path.cpp @@ -7,6 +7,7 @@ #include "rive/math/bezier_utils.hpp" #include "rive/math/simd.hpp" #include "rive/renderer/gpu.hpp" +#include "rive/profiler/profiler_macros.h" #include "shaders/constants.glsl" namespace rive @@ -78,10 +79,10 @@ void RiveRenderPath::close() m_dirt = kAllDirt; } -void RiveRenderPath::addRenderPath(RenderPath* path, const Mat2D& matrix) +void RiveRenderPath::addRenderPath(const RenderPath* path, const Mat2D& matrix) { assert(m_rawPathMutationLockCount == 0); - RiveRenderPath* riveRenderPath = static_cast(path); + auto riveRenderPath = static_cast(path); bool isIdentity = matrix == Mat2D(); RawPath::Iter transformedPathIter = @@ -95,10 +96,10 @@ void RiveRenderPath::addRenderPath(RenderPath* path, const Mat2D& matrix) m_dirt = kAllDirt; } -void RiveRenderPath::addRenderPathBackwards(RenderPath* path, +void RiveRenderPath::addRenderPathBackwards(const RenderPath* path, const Mat2D& transform) { - RiveRenderPath* riveRenderPath = static_cast(path); + auto riveRenderPath = static_cast(path); RawPath::Iter transformedPathIter = m_rawPath.addPathBackwards(riveRenderPath->m_rawPath, &transform); if (transform != Mat2D()) @@ -161,6 +162,7 @@ static void chop_cubic_at_uniform_rotation(RawPath* path, int numChops, const Mat2D& rotationMatrix) { + RIVE_PROF_SCOPE_L(3) math::CubicCoeffs coeffs(p); float2 tangent = simd::load2f(&tangents[0]); float4 rotation = simd::load4f(rotationMatrix.values()); @@ -249,6 +251,7 @@ rcp RiveRenderPath::makeSoftenedCopyForFeathering( float feather, float matrixMaxScale) { + RIVE_PROF_SCOPE_L(2) // Since curvature is what breaks 1-dimensional feathering along the normal // vector, chop into segments that rotate no more than a certain threshold. constexpr static int POLAR_JOIN_PRECISION = 2; @@ -307,14 +310,14 @@ rcp RiveRenderPath::makeSoftenedCopyForFeathering( // Cross through cusps with short lines to avoid unstable // math. Large cusp padding empirically gets better results. constexpr static float CUSP_PADDING = 1e-2f; - for (int i = 0; i < n; ++i) + for (int i = n - 1; i >= 0; --i) { // If the cusps are extremely close together, don't // allow the straddle points to cross. float minT = i == 0 ? 0.f : (T[i - 1] + T[i]) * .5f; float maxT = i + 1 == n ? 1.f : (T[i + 1] + T[i]) * .5f; - T[i * 2 + 0] = fmaxf(T[i] - CUSP_PADDING, minT); T[i * 2 + 1] = fminf(T[i] + CUSP_PADDING, maxT); + T[i * 2 + 0] = fmaxf(T[i] - CUSP_PADDING, minT); } n *= 2; } diff --git a/thirdparty/rive_renderer/source/rive_render_path.hpp b/thirdparty/rive_renderer/source/rive_render_path.hpp index 84d41245d..95d605ad2 100644 --- a/thirdparty/rive_renderer/source/rive_render_path.hpp +++ b/thirdparty/rive_renderer/source/rive_render_path.hpp @@ -29,8 +29,8 @@ class RiveRenderPath : public LITE_RTTI_OVERRIDE(RenderPath, RiveRenderPath) { addRenderPath(p->renderPath(), m); } - void addRenderPath(RenderPath* path, const Mat2D& matrix) override; - void addRenderPathBackwards(RenderPath* path, + void addRenderPath(const RenderPath* path, const Mat2D& matrix) override; + void addRenderPathBackwards(const RenderPath* path, const Mat2D& transform) override; void addRawPath(const RawPath& path) override; const RawPath& getRawPath() const { return m_rawPath; } diff --git a/thirdparty/rive_renderer/source/rive_renderer.cpp b/thirdparty/rive_renderer/source/rive_renderer.cpp index a5a9654f8..99a71b029 100644 --- a/thirdparty/rive_renderer/source/rive_renderer.cpp +++ b/thirdparty/rive_renderer/source/rive_renderer.cpp @@ -9,11 +9,13 @@ #include "rive/math/math_types.hpp" #include "rive/math/simd.hpp" #include "rive/renderer/rive_render_image.hpp" +#include "rive/profiler/profiler_macros.h" namespace rive { bool RiveRenderer::IsAABB(const RawPath& path, AABB* result) { + RIVE_PROF_SCOPE_L(3) // Any quadrilateral begins with a move plus 3 lines. constexpr static size_t kAABBVerbCount = 4; constexpr static PathVerb aabbVerbs[kAABBVerbCount] = {PathVerb::move, @@ -106,8 +108,15 @@ void RiveRenderer::transform(const Mat2D& matrix) m_stack.back().matrix = m_stack.back().matrix * matrix; } +void RiveRenderer::modulateOpacity(float opacity) +{ + m_stack.back().modulatedOpacity = + std::max(0.0f, m_stack.back().modulatedOpacity * opacity); +} + void RiveRenderer::drawPath(RenderPath* renderPath, RenderPaint* renderPaint) { + RIVE_PROF_SCOPE_L(2) LITE_RTTI_CAST_OR_RETURN(path, RiveRenderPath*, renderPath); LITE_RTTI_CAST_OR_RETURN(paint, RiveRenderPaint*, renderPaint); @@ -158,6 +167,7 @@ void RiveRenderer::drawPath(RenderPath* renderPath, RenderPaint* renderPaint) matrixMaxScale), path->getFillRule(), paint, + m_stack.back().modulatedOpacity, &m_scratchPath)); return; } @@ -168,20 +178,15 @@ void RiveRenderer::drawPath(RenderPath* renderPath, RenderPaint* renderPaint) ref_rcp(path), path->getFillRule(), paint, + m_stack.back().modulatedOpacity, &m_scratchPath)); } void RiveRenderer::clipPath(RenderPath* renderPath) { + RIVE_PROF_SCOPE_L(2) LITE_RTTI_CAST_OR_RETURN(path, RiveRenderPath*, renderPath); - if (m_context->frameInterlockMode() == gpu::InterlockMode::clockwiseAtomic) - { - // Just discard clips in clockwiseAtomic mode for now. - // TODO: Implement clipping in clockwiseAtomic mode. - return; - } - if (m_stack.back().clipIsEmpty) { return; @@ -247,6 +252,7 @@ static bool transform_rect_to_new_space(AABB* rect, void RiveRenderer::clipRectImpl(AABB rect, const RiveRenderPath* originalPath) { + RIVE_PROF_SCOPE_L(3) bool hasClipRect = m_stack.back().clipRectInverseMatrix != nullptr; if (rect.isEmptyOrNaN()) { @@ -293,6 +299,7 @@ void RiveRenderer::clipRectImpl(AABB rect, const RiveRenderPath* originalPath) void RiveRenderer::clipPathImpl(const RiveRenderPath* path) { + RIVE_PROF_SCOPE_L(3) if (path->getBounds().isEmptyOrNaN()) { m_stack.back().clipIsEmpty = true; @@ -325,6 +332,7 @@ void RiveRenderer::drawImage(const RenderImage* renderImage, BlendMode blendMode, float opacity) { + RIVE_PROF_SCOPE_L(2) LITE_RTTI_CAST_OR_RETURN(image, const RiveRenderImage*, renderImage); rcp imageTexture = image->refTexture(); @@ -336,6 +344,10 @@ void RiveRenderer::drawImage(const RenderImage* renderImage, return; } + // Apply modulated opacity (clamp to prevent negative values) + float finalOpacity = + std::max(0.0f, opacity * m_stack.back().modulatedOpacity); + // Scale the view matrix so we can draw this image as the rect [0, 0, 1, 1]. save(); scale(image->width(), image->height()); @@ -355,7 +367,7 @@ void RiveRenderer::drawImage(const RenderImage* renderImage, blendMode, std::move(imageTexture), imageSampler, - opacity))); + finalOpacity))); } } else @@ -371,7 +383,7 @@ void RiveRenderer::drawImage(const RenderImage* renderImage, } RiveRenderPaint paint; - paint.image(std::move(imageTexture), opacity); + paint.image(std::move(imageTexture), finalOpacity); paint.blendMode(blendMode); paint.imageSampler(imageSampler); drawPath(m_unitRectPath.get(), &paint); @@ -390,6 +402,7 @@ void RiveRenderer::drawImageMesh(const RenderImage* renderImage, BlendMode blendMode, float opacity) { + RIVE_PROF_SCOPE_L(2) LITE_RTTI_CAST_OR_RETURN(image, const RiveRenderImage*, renderImage); rcp imageTexture = image->refTexture(); @@ -410,6 +423,10 @@ void RiveRenderer::drawImageMesh(const RenderImage* renderImage, return; } + // Apply modulated opacity (clamp to prevent negative values) + float finalOpacity = + std::max(0.0f, opacity * m_stack.back().modulatedOpacity); + clipAndPushDraw(gpu::DrawUniquePtr( m_context->make(gpu::Draw::FULLSCREEN_PIXEL_BOUNDS, m_stack.back().matrix, @@ -420,11 +437,12 @@ void RiveRenderer::drawImageMesh(const RenderImage* renderImage, std::move(uvCoords_f32), std::move(indices_u16), indexCount, - opacity))); + finalOpacity))); } void RiveRenderer::clipAndPushDraw(gpu::DrawUniquePtr draw) { + RIVE_PROF_SCOPE_L(3) assert(!m_stack.back().clipIsEmpty); if (draw.get() == nullptr) { @@ -498,8 +516,68 @@ void RiveRenderer::clipAndPushDraw(gpu::DrawUniquePtr draw) "are too complex.\n"); } +// Used by clipping in clockwiseAtomic mode. +// +// Returns the inverse of a path, meaning, regions that were filled in the old +// path are now empty, and empty regions in the old path are now filled. +// +// NOTE: A true inverse path would expand infinitely in all directions, but this +// function limits it by the provided "bounds". +// +// NOTE: The returned path is always clockwise, even if the given path was not. +// If the given path is not clockwise, we attempt to convert it to clockwise +// based on its dominant winding direction. This may or may not be accurate. +rcp invert_clockwise_path(const RiveRenderPath* path, + FillRule pathFillRule, + const Mat2D& viewMatrix, + IAABB bounds) +{ + auto inversePath = make_rcp(); + inversePath->fillRule(FillRule::clockwise); + Mat2D viewInverseMatrix; + if (viewMatrix.invert(&viewInverseMatrix)) + { + // Add the pre-viewMatrix "bounds" rect to the new path. + std::array boundsVertices = { + Vec2D(bounds.left, bounds.top), + Vec2D(bounds.right, bounds.top), + Vec2D(bounds.right, bounds.bottom), + Vec2D(bounds.left, bounds.bottom), + }; + viewInverseMatrix.mapPoints(boundsVertices.data(), + boundsVertices.data(), + 4); + inversePath->move(boundsVertices[0]); + if (const float viewMatrixDeterminant = + viewMatrix[0] * viewMatrix[3] - viewMatrix[2] * viewMatrix[1]; + viewMatrixDeterminant >= 0) + { + inversePath->line(boundsVertices[1]); + inversePath->line(boundsVertices[2]); + inversePath->line(boundsVertices[3]); + } + else + { + inversePath->line(boundsVertices[3]); + inversePath->line(boundsVertices[2]); + inversePath->line(boundsVertices[1]); + } + // Subtract the given path out of the bounds rect. + if (pathFillRule == FillRule::clockwise || path->getCoarseArea() >= 0) + { + inversePath->addRenderPathBackwards(path, Mat2D()); + } + else + { + inversePath->addRenderPath(path, Mat2D()); + } + } + return inversePath; +} + RiveRenderer::ApplyClipResult RiveRenderer::applyClip(gpu::Draw* draw) { + RIVE_PROF_SCOPE_L(3) if (m_stack.back().clipIsEmpty) { return ApplyClipResult::clipEmpty; @@ -534,18 +612,20 @@ RiveRenderer::ApplyClipResult RiveRenderer::applyClip(gpu::Draw* draw) clipIdxCurrentlyInClipBuffer == -1 ? 0 // The next clip to be drawn is not nested. : m_clipStack[clipIdxCurrentlyInClipBuffer].clipID; - if (m_context->frameInterlockMode() == gpu::InterlockMode::msaa) + if (m_context->frameInterlockMode() == + gpu::InterlockMode::clockwiseAtomic || + m_context->frameInterlockMode() == gpu::InterlockMode::msaa) { if (lastClipID == 0 && m_context->getClipContentID() != 0) { // Time for a new stencil clip! Erase the clip currently in the // stencil buffer before we draw the new one. auto stencilClipClear = - gpu::DrawUniquePtr(m_context->make( + gpu::DrawUniquePtr(m_context->make( m_context, m_context->getClipContentID(), gpu::DrawContents::none, - gpu::StencilClipReset::ResetAction::clearPreviousClip)); + gpu::ClipReset::ResetAction::clearPreviousClip)); if (!m_context->isOutsideCurrentFrame( stencilClipClear->pixelBounds())) { @@ -563,12 +643,30 @@ RiveRenderer::ApplyClipResult RiveRenderer::applyClip(gpu::Draw* draw) RiveRenderPaint clipUpdatePaint; clipUpdatePaint.clipUpdate(/*clip THIS clipDraw against:*/ lastClipID); - gpu::DrawUniquePtr clipDraw = gpu::PathDraw::Make(m_context, - clip.matrix, - clip.path, - clip.fillRule, - &clipUpdatePaint, - &m_scratchPath); + rcp clipPath = clip.path; + FillRule clipFillRule = clip.fillRule; + if (m_context->frameInterlockMode() == + gpu::InterlockMode::clockwiseAtomic && + lastClipID != 0) + { + // clockwiseAtomic implements nested clips by erasing the inverse + // of the inner path from the outer clip. + clipPath = invert_clockwise_path( + clipPath.get(), + clipFillRule, + clip.matrix, + m_context->getClipContentBounds(lastClipID)); + clipFillRule = FillRule::clockwise; + } + + gpu::DrawUniquePtr clipDraw = + gpu::PathDraw::Make(m_context, + clip.matrix, + std::move(clipPath), + clipFillRule, + &clipUpdatePaint, + 1.0f, // no opacity modulation for clips + &m_scratchPath); if (clipDraw == nullptr) { @@ -604,12 +702,11 @@ RiveRenderer::ApplyClipResult RiveRenderer::applyClip(gpu::Draw* draw) // which involves erasing the region of the current clip in the // stencil buffer that is outside the the one we just drew. auto stencilClipIntersect = - gpu::DrawUniquePtr(m_context->make( + gpu::DrawUniquePtr(m_context->make( m_context, lastClipID, clipDrawContents, - gpu::StencilClipReset::ResetAction:: - intersectPreviousClip)); + gpu::ClipReset::ResetAction::intersectPreviousClip)); if (!m_context->isOutsideCurrentFrame( stencilClipIntersect->pixelBounds())) { diff --git a/thirdparty/rive_renderer/source/shaders/Makefile b/thirdparty/rive_renderer/source/shaders/Makefile index 588b36d2a..9634c3816 100644 --- a/thirdparty/rive_renderer/source/shaders/Makefile +++ b/thirdparty/rive_renderer/source/shaders/Makefile @@ -7,10 +7,14 @@ OUT := out/generated FLAGS := ## Shader minification. -MINIFY_INPUTS := $(wildcard *.glsl) -MINIFY_EXPORT_OUTPUTS := $(addprefix $(OUT)/, $(patsubst %.glsl, %.exports.h, $(MINIFY_INPUTS))) -MINIFY_GLSL_OUTPUTS := $(addprefix $(OUT)/, $(patsubst %.glsl, %.minified.glsl, $(MINIFY_INPUTS))) -MINIFY_HPP_OUTPUTS := $(addprefix $(OUT)/, $(patsubst %.glsl, %.glsl.hpp, $(MINIFY_INPUTS))) +MINIFY_INPUTS := $(wildcard *.glsl) $(wildcard *.vert) $(wildcard *.frag) +MINIFY_EXPORT_OUTPUTS := $(addprefix $(OUT)/, $(addsuffix .exports.h, $(MINIFY_INPUTS))) +MINIFY_GLSL_OUTPUTS := $(addprefix $(OUT)/,\ + $(patsubst %.glsl, %.minified.glsl,\ + $(patsubst %.vert, %.minified.vert,\ + $(patsubst %.frag, %.minified.frag,\ + $(MINIFY_INPUTS))))) +MINIFY_HPP_OUTPUTS := $(addprefix $(OUT)/, $(addsuffix .hpp, $(MINIFY_INPUTS))) MINIFY_OUTPUTS := $(MINIFY_EXPORT_OUTPUTS) $(MINIFY_GLSL_OUTPUTS) $(MINIFY_HPP_OUTPUTS) MINIFY_STAMP := $(OUT)/glsl.stamp @@ -26,16 +30,23 @@ $(MINIFY_STAMP): $(MINIFY_INPUTS) minify.py python3 minify.py $(FLAGS) -o $(OUT) $(MINIFY_INPUTS) @touch $(MINIFY_STAMP) +$(OUT)/.: + @mkdir -p $@ ## Metal shader offline compiling. +$(OUT)/ios/.: | $(OUT)/. + @mkdir -p $@ + +$(OUT)/macosx/.: | $(OUT)/. + @mkdir -p $@ + DRAW_COMBINATIONS_METAL := $(OUT)/draw_combinations.metal METAL_INPUTS := $(wildcard metal/*.metal) METAL_MACOSX_AIR_OUTPUTS := \ $(addprefix $(OUT)/, $(patsubst metal/%.metal, macosx/%.air, $(METAL_INPUTS))) METAL_IOS_AIR_OUTPUTS := $(addprefix $(OUT)/, $(patsubst metal/%.metal, ios/%.air, $(METAL_INPUTS))) -$(DRAW_COMBINATIONS_METAL): metal/generate_draw_combinations.py - @mkdir -p $(OUT) +$(DRAW_COMBINATIONS_METAL): metal/generate_draw_combinations.py | $(OUT)/. python3 metal/generate_draw_combinations.py $(DRAW_COMBINATIONS_METAL) rive_pls_macosx_metallib: $(OUT)/rive_pls_macosx.metallib.c @@ -48,11 +59,10 @@ rive_renderer_appletvsimulator_metallib: $(OUT)/rive_renderer_appletvsimulator.m ## The source files all get regenerated in a batch, so there's no need to separate out separate ## rules for each intermediate file. -$(OUT)/macosx/rive_pls_macosx.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/macosx +$(OUT)/macosx/rive_pls_macosx.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/macosx/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk macosx metal -std=macos-metal2.3 \ - -mmacosx-version-min=10.0 \ + -mmacosx-version-min=11.0 \ -I$(OUT) -ffast-math -ffp-contract=fast -fpreserve-invariance -fvisibility=hidden \ -c $(FILE) \ -o $(patsubst metal/%.metal, $(OUT)/macosx/%.air, $(FILE));) @@ -63,8 +73,7 @@ $(OUT)/rive_pls_macosx.metallib.c: $(OUT)/macosx/rive_pls_macosx.metallib $(OUT)/macosx/rive_pls_macosx.metallib \ $(OUT)/rive_pls_macosx.metallib.c -$(OUT)/ios/rive_pls_ios.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/ios +$(OUT)/ios/rive_pls_ios.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/ios/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk iphoneos metal -std=ios-metal2.2 \ -I$(OUT) -mios-version-min=13 -ffast-math -ffp-contract=fast -fpreserve-invariance \ @@ -76,8 +85,7 @@ $(OUT)/ios/rive_pls_ios.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_ $(OUT)/rive_pls_ios.metallib.c: $(OUT)/ios/rive_pls_ios.metallib xxd -i -n rive_pls_ios_metallib $(OUT)/ios/rive_pls_ios.metallib $(OUT)/rive_pls_ios.metallib.c -$(OUT)/ios/rive_pls_ios_simulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/ios +$(OUT)/ios/rive_pls_ios_simulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/ios/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk iphonesimulator metal -std=ios-metal2.2 \ -I$(OUT) -miphonesimulator-version-min=13 -ffast-math -ffp-contract=fast -fpreserve-invariance \ @@ -89,8 +97,7 @@ $(OUT)/ios/rive_pls_ios_simulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUT $(OUT)/rive_pls_ios_simulator.metallib.c: $(OUT)/ios/rive_pls_ios_simulator.metallib xxd -i -n rive_pls_ios_simulator_metallib $(OUT)/ios/rive_pls_ios_simulator.metallib $(OUT)/rive_pls_ios_simulator.metallib.c -$(OUT)/ios/rive_renderer_xros.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/ios +$(OUT)/ios/rive_renderer_xros.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/ios/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk xros metal -std=metal3.1 \ -I$(OUT) --target=air64-apple-xros1.0 -ffast-math -ffp-contract=fast -fpreserve-invariance \ @@ -102,8 +109,7 @@ $(OUT)/ios/rive_renderer_xros.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $ $(OUT)/rive_renderer_xros.metallib.c: $(OUT)/ios/rive_renderer_xros.metallib xxd -i -n rive_renderer_xros_metallib $(OUT)/ios/rive_renderer_xros.metallib $(OUT)/rive_renderer_xros.metallib.c -$(OUT)/ios/rive_renderer_xros_simulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/ios +$(OUT)/ios/rive_renderer_xros_simulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/ios/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk xrsimulator metal -std=metal3.1 \ -I$(OUT) --target=air64-apple-xros1.0-simulator -ffast-math -ffp-contract=fast -fpreserve-invariance \ @@ -115,8 +121,7 @@ $(OUT)/ios/rive_renderer_xros_simulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL $(OUT)/rive_renderer_xros_simulator.metallib.c: $(OUT)/ios/rive_renderer_xros_simulator.metallib xxd -i -n rive_renderer_xros_simulator_metallib $(OUT)/ios/rive_renderer_xros_simulator.metallib $(OUT)/rive_renderer_xros_simulator.metallib.c -$(OUT)/ios/rive_renderer_appletvos.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/ios +$(OUT)/ios/rive_renderer_appletvos.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/ios/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk appletvos metal -std=metal3.0 \ -I$(OUT) -mappletvos-version-min=16.0 -ffast-math -ffp-contract=fast -fpreserve-invariance \ @@ -128,8 +133,7 @@ $(OUT)/ios/rive_renderer_appletvos.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPU $(OUT)/rive_renderer_appletvos.metallib.c: $(OUT)/ios/rive_renderer_appletvos.metallib xxd -i -n rive_renderer_appletvos_metallib $(OUT)/ios/rive_renderer_appletvos.metallib $(OUT)/rive_renderer_appletvos.metallib.c -$(OUT)/ios/rive_renderer_appletvsimulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) - @mkdir -p $(OUT)/ios +$(OUT)/ios/rive_renderer_appletvsimulator.metallib: $(MINIFY_GLSL_OUTPUTS) $(METAL_INPUTS) $(DRAW_COMBINATIONS_METAL) | $(OUT)/ios/. $(foreach FILE, $(METAL_INPUTS), \ xcrun -sdk appletvsimulator metal -std=metal3.0 \ -I$(OUT) -mappletvsimulator-version-min=16.0 -ffast-math -ffp-contract=fast -fpreserve-invariance \ @@ -143,78 +147,223 @@ $(OUT)/rive_renderer_appletvsimulator.metallib.c: $(OUT)/ios/rive_renderer_apple ## SPIRV compilation. -SPIRV_INPUTS := $(wildcard spirv/*.main) \ - $(wildcard spirv/*.vert) \ - $(wildcard spirv/*.frag) - -SPIRV_OUTPUTS_HEADERS := \ - $(addprefix $(OUT)/, $(patsubst %.main, %.vert.h, $(wildcard spirv/*.main))) \ - $(addprefix $(OUT)/, $(patsubst %.main, %.frag.h, $(wildcard spirv/*.main))) \ - $(addprefix $(OUT)/, $(patsubst %.vert, %.vert.h, $(wildcard spirv/*.vert))) \ - $(addprefix $(OUT)/, $(patsubst %.frag, %.frag.h, $(wildcard spirv/*.frag))) \ - $(OUT)/spirv/atomic_draw_image_mesh.fixedcolor_frag.h \ - $(OUT)/spirv/atomic_draw_image_rect.fixedcolor_frag.h \ - $(OUT)/spirv/atomic_draw_interior_triangles.fixedcolor_frag.h \ - $(OUT)/spirv/atomic_draw_atlas_blit.fixedcolor_frag.h \ - $(OUT)/spirv/atomic_draw_path.fixedcolor_frag.h \ - $(OUT)/spirv/atomic_resolve.fixedcolor_frag.h \ - -SPIRV_OUTPUTS_BINARY := \ - $(addprefix $(OUT)/, $(patsubst %.main, %.vert.spirv, $(wildcard spirv/*.main))) \ - $(addprefix $(OUT)/, $(patsubst %.main, %.frag.spirv, $(wildcard spirv/*.main))) \ - $(addprefix $(OUT)/, $(patsubst %.vert, %.vert.spirv, $(wildcard spirv/*.vert))) \ - $(addprefix $(OUT)/, $(patsubst %.frag, %.frag.spirv, $(wildcard spirv/*.frag))) \ - $(OUT)/spirv/atomic_draw_image_mesh.fixedcolor_frag.spirv \ - $(OUT)/spirv/atomic_draw_image_rect.fixedcolor_frag.spirv \ - $(OUT)/spirv/atomic_draw_interior_triangles.fixedcolor_frag.spirv \ - $(OUT)/spirv/atomic_draw_atlas_blit.fixedcolor_frag.spirv \ - $(OUT)/spirv/atomic_draw_path.fixedcolor_frag.spirv \ - $(OUT)/spirv/atomic_resolve.fixedcolor_frag.spirv \ - -## Compile *.main into vertex shaders. First rule generates the binary spirv, then the .h file after. -$(OUT)/spirv/%.vert.spirv: spirv/%.main $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S vert -DTARGET_VULKAN -DVERTEX -I$(OUT) -V -o $@ $< - -$(OUT)/spirv/%.vert.h: spirv/%.main $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S vert -DTARGET_VULKAN -DVERTEX -I$(OUT) -V --vn $(subst .main,_vert,$(notdir $<)) -o $@ $< - -## Compile *.main again into fragment shaders. -$(OUT)/spirv/%.frag.spirv: spirv/%.main $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S frag -DTARGET_VULKAN -DFRAGMENT -I$(OUT) -V -o $@ $< - -$(OUT)/spirv/%.frag.h: spirv/%.main $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S frag -DTARGET_VULKAN -DFRAGMENT -I$(OUT) -V --vn $(subst .main,_frag,$(notdir $<)) -o $@ $< - -## Compile atomic fragment shaders again with FIXED_FUNCTION_COLOR_OUTPUT defined. -$(OUT)/spirv/%.fixedcolor_frag.spirv: spirv/%.main $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S frag -DTARGET_VULKAN -DFRAGMENT -DFIXED_FUNCTION_COLOR_OUTPUT -I$(OUT) -V -o $@ $< - -$(OUT)/spirv/%.fixedcolor_frag.h: spirv/%.main $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S frag -DTARGET_VULKAN -DFRAGMENT -DFIXED_FUNCTION_COLOR_OUTPUT -I$(OUT) -V --vn $(subst .main,_fixedcolor_frag,$(notdir $<)) -o $@ $< - -## Compile *.vert into vertex shaders. -$(OUT)/spirv/%.vert.spirv: spirv/%.vert $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S vert -DTARGET_VULKAN -DVERTEX -I$(OUT) -V -o $@ $< - -$(OUT)/spirv/%.vert.h: spirv/%.vert $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S vert -DTARGET_VULKAN -DVERTEX -I$(OUT) -V --vn $(subst .vert,_vert,$(notdir $<)) -o $@ $< - -## Compile *.frag into fragment shaders. -$(OUT)/spirv/%.frag.spirv: spirv/%.frag $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S frag -DTARGET_VULKAN -DFRAGMENT -I$(OUT) -V -o $@ $< - -$(OUT)/spirv/%.frag.h: spirv/%.frag $(MINIFY_STAMP) - @mkdir -p $(OUT)/spirv - @glslangValidator -S frag -DTARGET_VULKAN -DFRAGMENT -I$(OUT) -V --vn $(subst .frag,_frag,$(notdir $<)) -o $@ $< + +$(OUT)/spirv/.: | $(OUT)/. + @mkdir -p $@ + +# All glsl source files that need to be built +SPIRV_STANDARD_INPUTS := $(wildcard spirv/*.main) \ + $(wildcard spirv/*.vert) \ + $(wildcard spirv/*.frag) + +# WebGPU needs some additional shaders to be built specifically for it, +# to ensure the proper sampler binding set is used. +SPIRV_WEBGPU_INPUTS := \ + spirv/tessellate.main \ + spirv/render_atlas.vert \ + spirv/render_atlas_fill.frag \ + spirv/render_atlas_stroke.frag \ + spirv/blit_texture_as_draw_filtered.main \ + +# Files that need separate fragment shaders with FIXED_FUNCTION_COLOR_OUTPUT defined. +SPIRV_FIXEDCOLOR_FRAG_INPUTS := \ + spirv/atomic_draw_image_mesh.main \ + spirv/atomic_draw_image_rect.main \ + spirv/atomic_draw_interior_triangles.main \ + spirv/atomic_draw_atlas_blit.main \ + spirv/atomic_draw_path.main \ + spirv/atomic_resolve.main \ + spirv/draw_clockwise_path.main \ + spirv/draw_clockwise_clip.main \ + spirv/draw_clockwise_interior_triangles.main \ + spirv/draw_clockwise_clip_interior_triangles.main \ + spirv/draw_clockwise_atlas_blit.main \ + spirv/draw_clockwise_image_mesh.main \ + spirv/draw_clockwise_atomic_path.main \ + spirv/draw_clockwise_atomic_interior_triangles.main \ + spirv/draw_clockwise_atomic_atlas_blit.main \ + spirv/draw_clockwise_atomic_image_mesh.main \ + spirv/init_clockwise_atomic_workaround.frag \ + spirv/draw_clockwise_atomic_clip.frag \ + spirv/draw_clockwise_atomic_clip_interior_triangles.frag \ + spirv/clear_clockwise_atomic_clip.main \ + spirv/draw_msaa_atlas_blit.main \ + spirv/draw_msaa_image_mesh.main \ + spirv/draw_msaa_path.main \ + spirv/draw_msaa_stencil.main \ + +# MSAA vertex and fragment shaders are built multiple times with different flags. +SPIRV_DRAW_MSAA_INPUTS := \ + spirv/draw_msaa_path.main \ + spirv/draw_msaa_image_mesh.main \ + spirv/draw_msaa_atlas_blit.main \ + + +## Helpers for use in SPIRV_LIST_RULE (using lower_snake_case to distinguish things that use inputs like $1, $2, etc) +spirv_typed_filename = $(basename $1).$2 +spirv_out_filename_no_ext = $(OUT)/$(call spirv_typed_filename,$1,$2) +spirv_type = $(lastword $(subst _, ,$2)) +spirv_is_vert = $(findstring vert,$(spirv_type)) +spirv_is_webgpu = $(findstring webgpu,$2) +spirv_is_atomic_or_clockwise_atomic = $(findstring atomic,$1) +spirv_is_not_clockwise_atomic = $(if $(findstring clockwise_atomic,$1),,1) +spirv_is_clockwise = $(and $(findstring clockwise,$1), $(call spirv_is_not_clockwise_atomic,$1)) + +## SPIR-V Optimizer settings + +## To work around a driver bug in Android 9/10-era Adreno 5/6xx driver bugs, we need to run the +## fragment shaders through a preprocess optimization. The important bits for the workaround are: +## --merge-return +## --inline-entry-points-exhaustive +## without those, the pipelines on the affected devices will fail to link. However, we can do +## more optimizations while we're here, which will reduce the binary size. + +## Vertex shaders can be optimized using the standard "optimize for performance" option +## with no known issues +SPIRV_STANDARD_VERT_OPT_PARAMS = -O + +## Fragment shaders are a bit different: This is mostly a copy of the settings that spirv-opt +## reports for "-O" except with the --simplify-instructions option removed, which causes many +## issues on Adreno drivers. Additionally, the following three options cause problems with +## our atomic shaders: +## --ssa-rewrite +## --eliminate-local-single-block +## --eliminate-local-single-store +## So for atomic shaders, we end up with a different, even-more-pared-down set of instructions +## that doesn't drastically grow their sizes while also dodging all of the driver issues. +## +## Also use "-O" for the WebGPU shaders (for dawn) because something about the big list of +## options causes an internal compiler error error in its driver, but -O works great. +## +## TODO: Figure out why these cause issues with the atomic shaders and see if we can fix it +## to get consistent fragment shader optimizations. +spirv_frag_opt_params = \ + $(if $(spirv_is_webgpu),-O, \ + $(if $(spirv_is_atomic_or_clockwise_atomic), \ + --preserve-bindings \ + --preserve-interface \ + --wrap-opkill \ + --simplify-instructions \ + --eliminate-dead-branches \ + --merge-return \ + --inline-entry-points-exhaustive \ + --eliminate-dead-inserts \ + --eliminate-dead-members \ + --merge-blocks \ + --redundancy-elimination \ + --cfg-cleanup \ + --eliminate-dead-const \ + --eliminate-dead-variables \ + --eliminate-dead-functions \ + --eliminate-dead-code-aggressive \ + , \ + --wrap-opkill \ + --eliminate-dead-branches \ + --merge-return \ + --inline-entry-points-exhaustive \ + --eliminate-dead-functions \ + --eliminate-dead-code-aggressive \ + --private-to-local \ + --eliminate-local-single-block \ + --eliminate-local-single-store \ + --eliminate-dead-code-aggressive \ + --scalar-replacement=100 \ + --convert-local-access-chains \ + --eliminate-local-single-block \ + --eliminate-local-single-store \ + --eliminate-dead-code-aggressive \ + --ssa-rewrite \ + --eliminate-dead-code-aggressive \ + --ccp \ + --eliminate-dead-code-aggressive \ + --loop-unroll \ + --eliminate-dead-branches \ + --redundancy-elimination \ + --combine-access-chains \ + --scalar-replacement=100 \ + --convert-local-access-chains \ + --eliminate-local-single-block \ + --eliminate-local-single-store \ + --eliminate-dead-code-aggressive \ + --ssa-rewrite \ + --eliminate-dead-code-aggressive \ + --vector-dce \ + --eliminate-dead-inserts \ + --eliminate-dead-branches \ + --if-conversion \ + --copy-propagate-arrays \ + --reduce-load-size \ + --eliminate-dead-code-aggressive \ + --merge-blocks \ + --redundancy-elimination \ + --eliminate-dead-branches \ + --merge-blocks \ + ) \ + ) + +## WebGPU fragment shaders need a different PLS_IMPL value +spirv_frag_params = $(if $(spirv_is_webgpu), \ + -DPLS_IMPL_NONE, \ + $(if $(spirv_is_clockwise), \ + -DPLS_IMPL_STORAGE_TEXTURE, \ + -DPLS_IMPL_SUBPASS_LOAD)) + +## Vertex shaders get the standard optimizations. +## Fragment shaders get the adreno workaround options if they're in the workaround list +## or they'll get the "atomic" +spirv_opt_params = \ + $(if $(spirv_is_vert), \ + $(SPIRV_STANDARD_VERT_OPT_PARAMS), \ + $(spirv_frag_opt_params) \ + ) \ + + +## The rules/outputs for a given input/output pair +## Usage: $(eval $(call spirv_list_rule, INPUT_FILENAME, OUTPUT_TYPE [, ADDITIONAL_COMPILE_OPTIONS])) +## Where OUTPUT_TYPE is, say, "vert" or "frag" or "fixedcolor_frag", etc +define spirv_list_rule + $(spirv_out_filename_no_ext).spirv: $1 $(MINIFY_STAMP) | $(OUT)/spirv/. + @glslangValidator -S $(spirv_type) -DTARGET_SPIRV \ + $(if $(spirv_is_vert), -DVERTEX, -DFRAGMENT $(spirv_frag_params)) \ + -I$(OUT) -V $3 -o $(spirv_out_filename_no_ext).spirv.unoptimized $1 + @spirv-opt --preserve-bindings --preserve-interface $(spirv_opt_params) \ + $(spirv_out_filename_no_ext).spirv.unoptimized -o $(spirv_out_filename_no_ext).spirv + @rm $(spirv_out_filename_no_ext).spirv.unoptimized + + $(spirv_out_filename_no_ext).h: $(spirv_out_filename_no_ext).spirv + @python3 spirv_binary_to_header.py $(spirv_out_filename_no_ext).spirv $(spirv_out_filename_no_ext).h $(subst $(suffix $1),_$2,$(notdir $1)) + + SPIRV_OUTPUTS_BINARY += $(spirv_out_filename_no_ext).spirv + SPIRV_OUTPUTS_HEADERS += $(spirv_out_filename_no_ext).h +endef + +## Make a set of rules for a given set of files and output types +## Usage: $(eval $(call make_spirv_rules, LIST_OF_INPUT_FILES, LIST_OF_OUTPUT_TYPES [, ADDITIONAL_COMPILE_OPTIONS])) +## Where LIST_OF_OUTPUT_TYPES can contain one or more of entries like "vert" or "frag" or "fixedcolor_frag" +define make_spirv_rules + ## Note that the inner foreach will filter out ".frag" files from the list for any vert targets, and vice versa. + $(foreach type,$2,\ + $(foreach file,$(filter-out %.$(if $(findstring vert, $(type)),frag,vert),$1),\ + $(eval $(call spirv_list_rule,$(file),$(type),$3))\ + )\ + ) +endef + +## All .main/vert/frag files should build +$(eval $(call make_spirv_rules, $(SPIRV_STANDARD_INPUTS), vert frag)) + +SPIRV_COMMON_WEBGPU_PARAMS = -DSPEC_CONST_NONE -DUSE_WEBGPU_SAMPLERS + +## Each of the specialized SPIRV lists have their own associated rules +$(eval $(call make_spirv_rules, $(SPIRV_FIXEDCOLOR_FRAG_INPUTS), fixedcolor_frag, -DFIXED_FUNCTION_COLOR_OUTPUT)) +$(eval $(call make_spirv_rules, $(SPIRV_DRAW_MSAA_INPUTS), noclipdistance_vert, -DDISABLE_CLIP_DISTANCE_FOR_UBERSHADERS)) +$(eval $(call make_spirv_rules, $(SPIRV_WEBGPU_INPUTS), webgpu_vert, $(SPIRV_COMMON_WEBGPU_PARAMS))) +$(eval $(call make_spirv_rules, $(SPIRV_WEBGPU_INPUTS), webgpu_frag, $(SPIRV_COMMON_WEBGPU_PARAMS) -DINPUT_ATTACHMENT_NONE)) +$(eval $(call make_spirv_rules, $(SPIRV_DRAW_MSAA_INPUTS), webgpu_vert, $(SPIRV_COMMON_WEBGPU_PARAMS))) +$(eval $(call make_spirv_rules, $(SPIRV_DRAW_MSAA_INPUTS), webgpu_noclipdistance_vert, $(SPIRV_COMMON_WEBGPU_PARAMS) -DDISABLE_CLIP_DISTANCE_FOR_UBERSHADERS)) +$(eval $(call make_spirv_rules, $(SPIRV_DRAW_MSAA_INPUTS), webgpu_frag, $(SPIRV_COMMON_WEBGPU_PARAMS) -DINPUT_ATTACHMENT_NONE)) +$(eval $(call make_spirv_rules, $(SPIRV_DRAW_MSAA_INPUTS), webgpu_fixedcolor_frag, $(SPIRV_COMMON_WEBGPU_PARAMS) -DINPUT_ATTACHMENT_NONE -DFIXED_FUNCTION_COLOR_OUTPUT)) + spirv: $(SPIRV_OUTPUTS_HEADERS) spirv-binary: $(SPIRV_OUTPUTS_BINARY) @@ -222,6 +371,12 @@ spirv-binary: $(SPIRV_OUTPUTS_BINARY) ## d3d compilation. .PHONY: $(OUT)/d3d/render_atlas.frag.h +$(OUT)/d3d/.: | $(OUT)/. + @mkdir -p $@ + + +FXC_DEBUG_FLAG := $(if $(filter --human-readable,$(FLAGS)),/Zi,) + D3D_OUTPUTS := \ $(OUT)/d3d/root.sig.h \ $(addprefix $(OUT)/, $(patsubst %.hlsl, %.vert.h, $(wildcard d3d/*.hlsl))) \ @@ -229,25 +384,20 @@ D3D_OUTPUTS := \ $(OUT)/d3d/render_atlas_stroke.frag.h\ $(OUT)/d3d/render_atlas_fill.frag.h\ -$(OUT)/d3d/%.vert.h: d3d/%.hlsl $(MINIFY_STAMP) - @mkdir -p $(OUT)/d3d - @fxc /D VERTEX /I $(OUT) /T vs_5_0 /Fh $@ $< +$(OUT)/d3d/%.vert.h: d3d/%.hlsl $(MINIFY_STAMP) | $(OUT)/d3d/. + @fxc /D VERTEX /I $(OUT) $(FXC_DEBUG_FLAG) /T vs_5_0 /Fh $@ $< -$(OUT)/d3d/%.frag.h: d3d/%.hlsl $(MINIFY_STAMP) - @mkdir -p $(OUT)/d3d - @fxc /D FRAGMENT /I $(OUT) /T ps_5_0 /Fh $@ $< +$(OUT)/d3d/%.frag.h: d3d/%.hlsl $(MINIFY_STAMP) | $(OUT)/d3d/. + @fxc /D FRAGMENT /I $(OUT) $(FXC_DEBUG_FLAG) /T ps_5_0 /Fh $@ $< -$(OUT)/d3d/render_atlas_stroke.frag.h: d3d/render_atlas.hlsl $(MINIFY_STAMP) - @mkdir -p $(OUT)/d3d - @fxc /D FRAGMENT /D ATLAS_FEATHERED_STROKE /I $(OUT) /T ps_5_0 /Fh $@ $< +$(OUT)/d3d/render_atlas_stroke.frag.h: d3d/render_atlas.hlsl $(MINIFY_STAMP) | $(OUT)/d3d/. + @fxc /D FRAGMENT /D ATLAS_FEATHERED_STROKE $(FXC_DEBUG_FLAG) /I $(OUT) /T ps_5_0 /Fh $@ $< -$(OUT)/d3d/render_atlas_fill.frag.h: d3d/render_atlas.hlsl $(MINIFY_STAMP) - @mkdir -p $(OUT)/d3d - @fxc /D FRAGMENT /D ATLAS_FEATHERED_FILL /I $(OUT) /T ps_5_0 /Fh $@ $< +$(OUT)/d3d/render_atlas_fill.frag.h: d3d/render_atlas.hlsl $(MINIFY_STAMP) | $(OUT)/d3d/. + @fxc /D FRAGMENT /D ATLAS_FEATHERED_FILL $(FXC_DEBUG_FLAG) /I $(OUT) /T ps_5_0 /Fh $@ $< -$(OUT)/d3d/root.sig.h: d3d/root.sig - @mkdir -p $(OUT)/d3d - @fxc /I $(OUT) /T rootsig_1_1 /E ROOT_SIG /Fh $@ $< +$(OUT)/d3d/root.sig.h: d3d/root.sig | $(OUT)/d3d/. + @fxc /I $(OUT) /T rootsig_1_1 /E ROOT_SIG /Fh $@ $< d3d: $(D3D_OUTPUTS) diff --git a/thirdparty/rive_renderer/source/shaders/advanced_blend.glsl b/thirdparty/rive_renderer/source/shaders/advanced_blend.glsl index bde63e6fa..d54328088 100644 --- a/thirdparty/rive_renderer/source/shaders/advanced_blend.glsl +++ b/thirdparty/rive_renderer/source/shaders/advanced_blend.glsl @@ -79,6 +79,10 @@ layout( #ifdef @ENABLE_ADVANCED_BLEND #ifdef @ENABLE_HSL_BLEND_MODES +// Note: the following routines are mathematically equivalent to those in +// https://registry.khronos.org/OpenGL/extensions/KHR/KHR_blend_equation_advanced.txt +// but have been rearranged to be more efficient. + // When using one of the HSL blend equations in table X.2 as the blend equation, // the blend coefficients are effectively obtained by converting both the // non-premultiplied source and destination colors to the HSL (hue, saturation, @@ -87,58 +91,63 @@ layout( // and then converting the result back to RGB. The HSL blend equations are only // well defined when the values of the input color components are in the range // [0..1]. -half minv3(half3 c) { return min(min(c.r, c.g), c.b); } -half maxv3(half3 c) { return max(max(c.r, c.g), c.b); } -half lumv3(half3 c) { return dot(c, make_half3(.30, .59, .11)); } -half satv3(half3 c) { return maxv3(c) - minv3(c); } +half lum_from_rgb(half3 c) { return dot(c, make_half3(.30, .59, .11)); } -// If any color components are outside [0,1], adjust the color to get the -// components in range. -half3 clip_color(half3 color) +// Take the base RGB color and override its luminosity with that of another +// RGB color (lumColor). +half3 set_lum(half3 baseColor, half3 lumColor) { - half lum = lumv3(color); - half mincol = minv3(color); - half maxcol = maxv3(color); - if (mincol < .0) - color = lum + ((color - lum) * lum) / (lum - mincol); - if (maxcol > 1.) - color = lum + ((color - lum) * (1. - lum)) / (maxcol - lum); - return color; -} + half lumTarget = lum_from_rgb(lumColor); -// Take the base RGB color and override its luminosity with that of the -// RGB color . -half3 set_lum(half3 cbase, half3 clum) -{ - half lbase = lumv3(cbase); - half llum = lumv3(clum); - half ldiff = llum - lbase; - half3 color = cbase + make_half3(ldiff); - return clip_color(color); + // Bias the color such that its original luminance is now the 0 point. + half3 biased = baseColor - lum_from_rgb(baseColor); + + // Now we potentially need to rescale the color to get it to fit within + // 0..1. Effectively to keep the relative luminance, we may need to squish + // the rgb range so it still fits. + + // Calculate the scale values necessary to push the min or max component + // back into range. One is for if the luminance pushes the rgb values + // negative (pushing min component back into range), the other for if they + // go above 1.0 (pushing max component). + half2 scales = + make_half2(lumTarget, 1.0 - lumTarget) / + max(make_half2(EPSILON_FP16_NON_DENORM), + make_half2(-min_component(biased), max_component(biased))); + + // Take the minimum scale of the above (but nothing larger than 1, since we + // only ever want to scale *down* the range) + half satScale = min(make_half(1.0), min(scales.x, scales.y)); + + // Now we can apply the scale to get the rgb range right, then re-bias it + // back into the correct place (at the new luminance) + return biased * satScale + lumTarget; } -// Take the base RGB color and override its saturation with that of the -// RGB color . The override the luminosity of the result with that of the -// RGB color . -half3 set_lum_sat(half3 cbase, half3 csat, half3 clum) +// Take the hue from hueColor, the saturation from satColor, and the luminance +// from lumColor and combine them into one resulting color. +half3 set_lum_sat(half3 hueColor, half3 satColor, half3 lumColor) { - half minbase = minv3(cbase); - half sbase = satv3(cbase); - half ssat = satv3(csat); - half3 color; - if (sbase > .0) - { - // Equivalent (modulo rounding errors) to setting the smallest (R,G,B) - // component to 0, the largest to , and interpolating the "middle" - // component based on its original value relative to the - // smallest/largest. - color = (cbase - minbase) * ssat / sbase; - } - else - { - color = make_half3(.0); - } - return set_lum(color, clum); + // The saturation of a color is the difference between its max and min + // components. + float satTarget = max_component(satColor) - min_component(satColor); + + // Bias the hue color so its min component is 0 (this is not *strictly* + // required but it simplifies the saturation calculation and matches the + // canonical math). + hueColor -= min_component(hueColor); + + // Because of that bias, the minimum component is now 0, so the saturation + // is just the max component. + float satSource = max_component(hueColor); + + // Rescale hueColor to have the new saturation. If satSource == 0, then + // hueColor == {0, 0, 0}, so do a max on the denominator to avoid a divide + // by 0. + float scale = satTarget / max(EPSILON_FP16_NON_DENORM, satSource); + + // Now apply the luminance from lumColor to the rescaled color. + return set_lum(hueColor * scale, lumColor); } #endif // ENABLE_HSL_BLEND_MODES @@ -158,13 +167,15 @@ half3 advanced_blend_coeffs(half3 src, half4 dstPremul, ushort mode) break; case BLEND_MODE_OVERLAY: { - for (int i = 0; i < 3; ++i) - { - if (dst[i] <= .5) - coeffs[i] = 2. * src[i] * dst[i]; - else - coeffs[i] = 1. - 2. * (1. - src[i]) * (1. - dst[i]); - } + // This logic is equivalent to the following, but should be more + // efficient, and works around a Vulkan Adreno 6-series Android 9/10 + // driver bug: + // f(Cs,Cd) = 2*Cs*Cd, if Cd <= 0.5 + // 1-2*(1-Cs)*(1-Cd), otherwise + half3 sd = src * dst; + coeffs = 2.0 * mix(sd, + src + dst - sd - 0.5, + greaterThan(dst, make_half3(0.5))); break; } case BLEND_MODE_DARKEN: @@ -197,30 +208,40 @@ half3 advanced_blend_coeffs(half3 src, half4 dstPremul, ushort mode) } case BLEND_MODE_HARDLIGHT: { - for (int i = 0; i < 3; ++i) - { - if (src[i] <= .5) - coeffs[i] = 2. * src[i] * dst[i]; - else - coeffs[i] = 1. - 2. * (1. - src[i]) * (1. - dst[i]); - } + // This logic is equivalent to the following, but should be more + // efficient, and works around a Vulkan Adreno 6-series Android 9/10 + // driver bug: + // f(Cs,Cd) = 2*Cs*Cd, if Cs <= 0.5 + // 1-2*(1-Cs)*(1-Cd), otherwise + half3 sd = src * dst; + coeffs = 2.0 * mix(sd, + src + dst - sd - 0.5, + greaterThan(src, make_half3(0.5))); break; } case BLEND_MODE_SOFTLIGHT: { + // This logic is equivalent to the following, but should be more + // efficient, and works around a Vulkan Adreno 6-series Android 9/10 + // driver bug: + // f(Cs,Cd) = + // Cd-(1-2*Cs)*Cd*(1-Cd), + // if Cs <= 0.5 + // Cd+(2*Cs-1)*Cd*((16*Cd-12)*Cd+3), + // if Cs > 0.5 and Cd <= 0.25 + // Cd+(2*Cs-1)*(sqrt(Cd)-Cd), + // if Cs > 0.5 and Cd > 0.25 for (int i = 0; i < 3; ++i) { if (src[i] <= 0.5) - coeffs[i] = - dst[i] - (1. - 2. * src[i]) * dst[i] * (1. - dst[i]); - else if (dst[i] <= .25) - coeffs[i] = - dst[i] + (2. * src[i] - 1.) * dst[i] * - ((16. * dst[i] - 12.) * dst[i] + 3.); + coeffs[i] = (1.0 - dst[i]); + else if (dst[i] <= 0.25) + coeffs[i] = ((16.0 * dst[i] - 12.0) * dst[i] + 3.0); else - coeffs[i] = - dst[i] + (2. * src[i] - 1.) * (sqrt(dst[i]) - dst[i]); + coeffs[i] = (inversesqrt(dst[i]) - 1.0); } + + coeffs = dst + dst * (2.0 * src - 1.0) * coeffs; break; } case BLEND_MODE_DIFFERENCE: @@ -299,8 +320,10 @@ INLINE half3 advanced_color_blend(half3 src, half4 dstPremul, ushort mode) // Also, since (X,Y,Z) == 1, alpha simplifies to standard src-over // rules: A = Ad * (1 - As) + As half3 coeffs = advanced_blend_coeffs(src, dstPremul, mode); - half2 p = make_half2(dstPremul.a, 1. - dstPremul.a); // p2 cancelled to 0. - return MUL(make_half2x3(coeffs, src), p); + + // Because p0 is (Ad), p1 is (1 - Ad), and p2 is 0, this is equivalent to + // that matrix multiply: + return mix(src, coeffs, make_half3(dstPremul.a)); } #endif // ENABLE_ADVANCED_BLEND diff --git a/thirdparty/rive_renderer/source/shaders/atomic_draw.glsl b/thirdparty/rive_renderer/source/shaders/atomic_draw.glsl index e8c5c67c2..4ff405a37 100644 --- a/thirdparty/rive_renderer/source/shaders/atomic_draw.glsl +++ b/thirdparty/rive_renderer/source/shaders/atomic_draw.glsl @@ -68,7 +68,7 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #endif // VERTEX #endif // DRAW_PATH -#ifdef @DRAW_INTERIOR_TRIANGLES +#if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT) #ifdef @VERTEX ATTR_BLOCK_BEGIN(Attrs) ATTR(0, packed_float3, @a_triangleVertex); @@ -120,8 +120,8 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) VARYING_PACK(v_pathID); EMIT_VERTEX(pos); } -#endif // VERTEX -#endif // DRAW_INTERIOR_TRIANGLES +#endif // @VERTEX +#endif // @DRAW_INTERIOR_TRIANGLES || @ATLAS_BLIT #ifdef @DRAW_IMAGE_RECT #ifdef @VERTEX @@ -309,8 +309,8 @@ PLS_BLOCK_BEGIN // render to it as a normal color attachment. #ifndef @FIXED_FUNCTION_COLOR_OUTPUT #ifdef @COLOR_PLANE_IDX_OVERRIDE -// D3D11 doesn't let us bind the framebuffer UAV to slot 0 when there is a color -// output. +// D3D11 doesn't let us bind the framebuffer UAV to slot 0 when there is a +// color output. #define LOCAL_COLOR_PLANE_IDX @COLOR_PLANE_IDX_OVERRIDE #else #define LOCAL_COLOR_PLANE_IDX COLOR_PLANE_IDX @@ -322,10 +322,10 @@ PLS_DECL4F(LOCAL_COLOR_PLANE_IDX, colorBuffer); #endif #endif // !FIXED_FUNCTION_COLOR_OUTPUT #ifdef @PLS_BLEND_SRC_OVER -// When PLS has src-over blending enabled, the clip buffer is RGBA8 so we can -// preserve clip contents by emitting a=0 instead of loading the current value. -// This is also is a hint to the hardware that it doesn't need to write anything -// to the clip attachment. +// When PLS has src-over blending enabled, the clip buffer is RGBA8 so we +// can preserve clip contents by emitting a=0 instead of loading the current +// value. This is also is a hint to the hardware that it doesn't need to +// write anything to the clip attachment. #define CLIP_VALUE_TYPE half4 #define PLS_LOAD_CLIP_TYPE PLS_LOAD4F #define MAKE_NON_UPDATING_CLIP_VALUE make_half4(.0) @@ -338,8 +338,8 @@ PLS_DECL4F_READONLY(CLIP_PLANE_IDX, clipBuffer); #endif #endif // ENABLE_CLIPPING #else -// When PLS does not have src-over blending, the clip buffer the usual packed -// R32UI. +// When PLS does not have src-over blending, the clip buffer the usual +// packed R32UI. #define CLIP_VALUE_TYPE uint #define MAKE_NON_UPDATING_CLIP_VALUE 0u #define PLS_LOAD_CLIP_TYPE PLS_LOADUI @@ -348,7 +348,7 @@ PLS_DECL4F_READONLY(CLIP_PLANE_IDX, clipBuffer); PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); #endif // ENABLE_CLIPPING #endif // !PLS_BLEND_SRC_OVER -PLS_DECLUI_ATOMIC(COVERAGE_PLANE_IDX, coverageAtomicBuffer); +PLS_DECLUI_UAV(COVERAGE_PLANE_IDX, coverageAtomicBuffer); PLS_BLOCK_END FRAG_STORAGE_BUFFER_BLOCK_BEGIN @@ -368,6 +368,18 @@ INLINE half from_fixed(uint x) (-FIXED_COVERAGE_ZERO * FIXED_COVERAGE_INVERSE_PRECISION)); } +ushort apply_driver_workaround_for_path_id(ushort pathID) +{ +#ifdef @NEEDS_PATH_ID_CLAMP_WORKAROUND + // We have observed that on some hardware, inactive threads or helper lanes + // appear to issue calls that access storage textures, even though they + // should be NO-OP. clamping the path ID prevents crashes in these + // scenarios. + pathID = min(pathID, uniforms.maxPathId); +#endif + return pathID; +} + #ifdef @ENABLE_CLIPPING INLINE void apply_clip(uint clipID, CLIP_VALUE_TYPE clipData, @@ -490,7 +502,8 @@ INLINE void resolve_paint(uint pathID, // Apply the advanced blend mode, if applicable. ushort blendMode; if (@ENABLE_ADVANCED_BLEND && fragColorOut.a != .0 && - (blendMode = cast_uint_to_ushort((paintData.x >> 4) & 0xfu)) != 0u) + (blendMode = cast_uint_to_ushort((paintData.x >> 4) & 0xfu)) != + BLEND_SRC_OVER) { half4 dstColorPremul = PLS_LOAD4F(colorBuffer); fragColorOut.rgb = @@ -498,12 +511,16 @@ INLINE void resolve_paint(uint pathID, } #endif // !FIXED_FUNCTION_COLOR_OUTPUT && ENABLE_ADVANCED_BLEND - // When PLS_BLEND_SRC_OVER is defined, the caller and/or blend state - // multiply alpha into fragColorOut for us. Otherwise, we have to - // premultiply it. -#ifndef @PLS_BLEND_SRC_OVER - fragColorOut.rgb *= fragColorOut.a; +// Certain platforms give us less control of the format of what we are +// rendering too. Specifically, we are auto converted from linear -> sRGB on +// render target writes in unreal. In those cases we made need to end up in +// linear color space +#if defined(@NEEDS_GAMMA_CORRECTION) && \ + (defined(@FIXED_FUNCTION_COLOR_OUTPUT) || defined(@RESOLVE_PLS)) + fragColorOut = gamma_to_linear(fragColorOut); #endif + + fragColorOut.rgb *= fragColorOut.a; } #if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) && \ @@ -519,7 +536,8 @@ INLINE void blend_pls_color_src_over(half4 fragColorOut PLS_CONTEXT_DECL) #endif PLS_STORE4F(colorBuffer, fragColorOut); } -#endif // !@FIXED_FUNCTION_COLOR_OUTPUT && !@COALESCED_PLS_RESOLVE_AND_TRANSFER +#endif // !@FIXED_FUNCTION_COLOR_OUTPUT && + // !@COALESCED_PLS_RESOLVE_AND_TRANSFER #if defined(@ENABLE_CLIPPING) && !defined(@RESOLVE_PLS) INLINE void emit_pls_clip(CLIP_VALUE_TYPE fragClipOut PLS_CONTEXT_DECL) @@ -555,6 +573,7 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) VARYING_UNPACK(v_pathID, ushort); half fragmentCoverage; + #ifdef @ENABLE_FEATHER if (@ENABLE_FEATHER && is_feathered_stroke(v_coverages)) { @@ -598,6 +617,9 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) PLS_ATOMIC_MAX(coverageAtomicBuffer, minCoverageData); ushort lastPathID = cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT); + + lastPathID = apply_driver_workaround_for_path_id(lastPathID); + if (lastPathID == v_pathID) { // This is not the first fragment of the current path to touch this @@ -630,6 +652,10 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK); } + fragColorOut.rgb = add_dither(fragColorOut.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); #ifdef @FIXED_FUNCTION_COLOR_OUTPUT _fragColor = fragColorOut; #else @@ -643,7 +669,7 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) } #endif // DRAW_PATH -#ifdef @DRAW_INTERIOR_TRIANGLES +#if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT) ATOMIC_PLS_MAIN(@drawFragmentMain) { #ifdef @ATLAS_BLIT @@ -653,10 +679,10 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) #endif VARYING_UNPACK(v_pathID, ushort); - uint lastCoverageData = PLS_LOADUI_ATOMIC(coverageAtomicBuffer); + uint lastCoverageData = PLS_LOADUI_UAV(coverageAtomicBuffer); ushort lastPathID = cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT); - + lastPathID = apply_driver_workaround_for_path_id(lastPathID); // Update coverageAtomicBuffer with the coverage weight of the current // triangle. This does not need to be atomic since interior triangles don't // overlap. @@ -676,16 +702,17 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) half coverage; #ifdef @ATLAS_BLIT - coverage = filter_feather_atlas( - v_atlasCoord, - uniforms.atlasTextureInverseSize TEXTURE_CONTEXT_FORWARD); + coverage = clamp( + TEXTURE_SAMPLE_LOD(@atlasTexture, atlasSampler, v_atlasCoord, .0).r, + make_half(.0), + make_half(1.)); #else coverage = v_windingWeight; #endif int coverageDeltaFixed = int(round(coverage * FIXED_COVERAGE_PRECISION)); - PLS_STOREUI_ATOMIC(coverageAtomicBuffer, - currPathCoverageData + uint(coverageDeltaFixed)); + PLS_STOREUI_UAV(coverageAtomicBuffer, + currPathCoverageData + uint(coverageDeltaFixed)); half4 fragColorOut = make_half4(.0); #ifdef @ENABLE_CLIPPING @@ -712,6 +739,10 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK); } + fragColorOut.rgb = add_dither(fragColorOut.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); #ifdef @FIXED_FUNCTION_COLOR_OUTPUT _fragColor = fragColorOut; #else @@ -723,7 +754,7 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) EMIT_ATOMIC_PLS } -#endif // DRAW_INTERIOR_TRIANGLES +#endif // @DRAW_INTERIOR_TRIANGLES || @ATLAS_BLIT #ifdef @DRAW_IMAGE ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) @@ -750,15 +781,16 @@ ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) #ifdef @ENABLE_CLIP_RECT if (@ENABLE_CLIP_RECT) { - half clipRectCoverage = min_value(cast_float4_to_half4(v_clipRect)); + half clipRectCoverage = min_component(cast_float4_to_half4(v_clipRect)); imageCoverage = clamp(clipRectCoverage, make_half(.0), imageCoverage); } #endif // Resolve the previous path. - uint lastCoverageData = PLS_LOADUI_ATOMIC(coverageAtomicBuffer); + uint lastCoverageData = PLS_LOADUI_UAV(coverageAtomicBuffer); ushort lastPathID = cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT); + lastPathID = apply_driver_workaround_for_path_id(lastPathID); half lastCoverageCount = from_fixed(lastCoverageData & FIXED_COVERAGE_MASK); half4 fragColorOut; #ifdef @ENABLE_CLIPPING @@ -778,14 +810,8 @@ ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) #endif FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK); -#ifdef @PLS_BLEND_SRC_OVER - // Image draws use a premultiplied blend state, but resolve_paint() did not - // premultiply fragColorOut. Multiply fragColorOut by alpha now. - fragColorOut.rgb *= fragColorOut.a; -#endif - - // Clip the image after resolving the previous path, since that can affect - // the clip buffer. +// Clip the image after resolving the previous path, since that can affect +// the clip buffer. #ifdef @ENABLE_CLIPPING // TODO! ENABLE_IMAGE_CLIPPING in addition to // ENABLE_CLIPPING? if (@ENABLE_CLIPPING && imageDrawUniforms.clipID != 0u) @@ -797,7 +823,7 @@ ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) } #endif // ENABLE_CLIPPING - // Prepare imageColor for premultiplied src-over blending. +// Prepare imageColor for premultiplied src-over blending. #if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) && defined(@ENABLE_ADVANCED_BLEND) if (@ENABLE_ADVANCED_BLEND && imageDrawUniforms.blendMode != BLEND_SRC_OVER) { @@ -815,11 +841,19 @@ ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) #endif // !FIXED_FUNCTION_COLOR_OUTPUT && ENABLE_ADVANCED_BLEND imageColor *= imageCoverage * cast_float_to_half(imageDrawUniforms.opacity); +#if defined(@NEEDS_GAMMA_CORRECTION) + imageColor = gamma_to_linear(imageColor); +#endif + // Leverage the property that premultiplied src-over blending is associative // and blend the imageColor and fragColorOut before passing them on to the // blending pipeline. fragColorOut = fragColorOut * (1. - imageColor.a) + imageColor; + fragColorOut.rgb = add_dither(fragColorOut.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); #ifdef @FIXED_FUNCTION_COLOR_OUTPUT _fragColor = fragColorOut; #else @@ -831,7 +865,7 @@ ATOMIC_PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) // Write out a coverage value of "zero at pathID=0" so a future resolve // attempt doesn't affect this pixel. - PLS_STOREUI_ATOMIC(coverageAtomicBuffer, FIXED_COVERAGE_ZERO_UINT); + PLS_STOREUI_UAV(coverageAtomicBuffer, FIXED_COVERAGE_ZERO_UINT); EMIT_ATOMIC_PLS } @@ -848,7 +882,7 @@ ATOMIC_PLS_MAIN(@drawFragmentMain) half4 color = PLS_LOAD4F(colorBuffer); PLS_STORE4F(colorBuffer, color.bgra); #endif - PLS_STOREUI_ATOMIC(coverageAtomicBuffer, uniforms.coverageClearValue); + PLS_STOREUI_UAV(coverageAtomicBuffer, uniforms.coverageClearValue); #ifdef @ENABLE_CLIPPING if (@ENABLE_CLIPPING) { @@ -871,32 +905,33 @@ PLS_FRAG_COLOR_MAIN(@drawFragmentMain) ATOMIC_PLS_MAIN(@drawFragmentMain) #endif { - uint lastCoverageData = PLS_LOADUI_ATOMIC(coverageAtomicBuffer); + uint lastCoverageData = PLS_LOADUI_UAV(coverageAtomicBuffer); half coverageCount = from_fixed(lastCoverageData & FIXED_COVERAGE_MASK); ushort lastPathID = cast_uint_to_ushort(lastCoverageData >> FIXED_COVERAGE_BIT_COUNT); + lastPathID = apply_driver_workaround_for_path_id(lastPathID); half4 fragColorOut; resolve_paint(lastPathID, coverageCount, fragColorOut FRAGMENT_CONTEXT_UNPACK PLS_CONTEXT_UNPACK); #ifdef @COALESCED_PLS_RESOLVE_AND_TRANSFER -#ifdef @PLS_BLEND_SRC_OVER - // When PLS_BLEND_SRC_OVER is defined, the blend state usually multiplies - // alpha into fragColorOut for us. But since the coalesced resolve does not - // use blend, premultiply it now. - fragColorOut.rgb *= fragColorOut.a; -#endif float oneMinusSrcAlpha = 1. - fragColorOut.a; if (oneMinusSrcAlpha != .0) fragColorOut += PLS_LOAD4F(colorBuffer) * oneMinusSrcAlpha; _fragColor = fragColorOut; EMIT_PLS_AND_FRAG_COLOR #else + + fragColorOut.rgb = add_dither(fragColorOut.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); #ifdef @FIXED_FUNCTION_COLOR_OUTPUT _fragColor = fragColorOut; #else blend_pls_color_src_over(fragColorOut PLS_CONTEXT_UNPACK); #endif + EMIT_ATOMIC_PLS #endif // COALESCED_PLS_RESOLVE_AND_TRANSFER } diff --git a/thirdparty/rive_renderer/source/shaders/blit_texture_as_draw.glsl b/thirdparty/rive_renderer/source/shaders/blit_texture_as_draw.glsl index 14e8e6c45..fc4c76f87 100644 --- a/thirdparty/rive_renderer/source/shaders/blit_texture_as_draw.glsl +++ b/thirdparty/rive_renderer/source/shaders/blit_texture_as_draw.glsl @@ -3,7 +3,7 @@ */ VARYING_BLOCK_BEGIN -#ifndef @USE_TEXEL_FETCH_WITH_FRAG_COORD +#ifdef @USE_FILTERING NO_PERSPECTIVE VARYING(0, float2, v_texCoord); #endif VARYING_BLOCK_END @@ -15,6 +15,9 @@ VERTEX_TEXTURE_BLOCK_END VERTEX_STORAGE_BUFFER_BLOCK_BEGIN VERTEX_STORAGE_BUFFER_BLOCK_END +ATTR_BLOCK_BEGIN(Attrs) +ATTR_BLOCK_END + VERTEX_MAIN(@blitVertexMain, Attrs, attrs, _vertexID, _instanceID) { // Fill the entire screen. The caller will use a scissor test to control the @@ -22,7 +25,7 @@ VERTEX_MAIN(@blitVertexMain, Attrs, attrs, _vertexID, _instanceID) float2 coord; coord.x = (_vertexID & 1) == 0 ? -1. : 1.; coord.y = (_vertexID & 2) == 0 ? -1. : 1.; -#ifndef @USE_TEXEL_FETCH_WITH_FRAG_COORD +#ifdef @USE_FILTERING VARYING_INIT(v_texCoord, float2); v_texCoord.x = coord.x * .5 + .5; v_texCoord.y = coord.y * -.5 + .5; @@ -35,21 +38,32 @@ VERTEX_MAIN(@blitVertexMain, Attrs, attrs, _vertexID, _instanceID) #ifdef @FRAGMENT FRAG_TEXTURE_BLOCK_BEGIN -TEXTURE_RGBA8(0, 0, @sourceTexture); +#ifdef @SOURCE_TEXTURE_MSAA +TEXTURE_RGBA8_MS(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @sourceTexture); +#else +TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @sourceTexture); +#endif FRAG_TEXTURE_BLOCK_END -#ifndef @USE_TEXEL_FETCH_WITH_FRAG_COORD +#ifdef @USE_FILTERING DYNAMIC_SAMPLER_BLOCK_BEGIN -SAMPLER_DYNAMIC(0, blitSampler) +SAMPLER_DYNAMIC_IMAGE(blitSampler) DYNAMIC_SAMPLER_BLOCK_END #endif FRAG_DATA_MAIN(half4, @blitFragmentMain) { half4 srcColor; -#ifndef @USE_TEXEL_FETCH_WITH_FRAG_COORD +#ifdef @USE_FILTERING VARYING_UNPACK(v_texCoord, float2); - srcColor = TEXTURE_SAMPLE_LOD(@sourceTexture, blitSampler, v_texCoord, .0); + srcColor = + TEXTURE_SAMPLE_DYNAMIC_LOD(@sourceTexture, blitSampler, v_texCoord, .0); +#elif defined(@SOURCE_TEXTURE_MSAA) + srcColor = (TEXEL_FETCH_MS(@sourceTexture, 0, int2(floor(_fragCoord.xy))) + + TEXEL_FETCH_MS(@sourceTexture, 1, int2(floor(_fragCoord.xy))) + + TEXEL_FETCH_MS(@sourceTexture, 2, int2(floor(_fragCoord.xy))) + + TEXEL_FETCH_MS(@sourceTexture, 3, int2(floor(_fragCoord.xy)))) * + 0.25; #else srcColor = TEXEL_FETCH(@sourceTexture, int2(floor(_fragCoord.xy))); #endif diff --git a/thirdparty/rive_renderer/source/shaders/clear_clockwise_atomic_clip.glsl b/thirdparty/rive_renderer/source/shaders/clear_clockwise_atomic_clip.glsl new file mode 100644 index 000000000..af85b18a8 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/clear_clockwise_atomic_clip.glsl @@ -0,0 +1,36 @@ +/* + * Copyright 2026 Rive + */ + +#ifdef @VERTEX +ATTR_BLOCK_BEGIN(Attrs) +ATTR(0, packed_float3, @a_triangleVertex); +ATTR_BLOCK_END + +VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) +{ + ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, packed_float3); + float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(@a_triangleVertex.xy); + EMIT_VERTEX(pos); +} +#endif + +#ifdef @FRAGMENT +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +PLS_DECL4F(CLIP_PLANE_IDX, clipBuffer); +PLS_BLOCK_END + +CLOCKWISE_ATOMIC_PLS_MAIN(@drawFragmentMain) +{ + // srcOver blend is enabled: emit an alpha value of 1 to overwrite the + // existing clip. + PLS_STORE4F(clipBuffer, make_half4(.0, .0, .0, 1.)); + + // srcOver blend is enabled: emit a color of 0 to make sure the framebuffer + // remains unchanged. + EMIT_CLOCKWISE_ATOMIC_PLS(make_half4(.0)); +} +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/color_ramp.glsl b/thirdparty/rive_renderer/source/shaders/color_ramp.glsl index 7bae817c4..3ab579ba3 100644 --- a/thirdparty/rive_renderer/source/shaders/color_ramp.glsl +++ b/thirdparty/rive_renderer/source/shaders/color_ramp.glsl @@ -86,6 +86,9 @@ VERTEX_MAIN(@colorRampVertexMain, Attrs, attrs, _vertexID, _instanceID) float4 pos = pixel_coord_to_clip_coord(float2(x, y), 2., uniforms.gradInverseViewportY); +#ifdef @POST_INVERT_Y + pos.y = -pos.y; +#endif VARYING_PACK(v_rampColor); EMIT_VERTEX(pos); diff --git a/thirdparty/rive_renderer/source/shaders/common.glsl b/thirdparty/rive_renderer/source/shaders/common.glsl index 4a6fc784b..a406c4d86 100644 --- a/thirdparty/rive_renderer/source/shaders/common.glsl +++ b/thirdparty/rive_renderer/source/shaders/common.glsl @@ -37,6 +37,15 @@ #define TESSDATA_AS_UINT(X) X #endif +// Gathers a 4xN matrix of texels, in the same order as the textureGather() API. +// clang-format off +#define TEXTURE_GATHER_MATRIX(NAME, COORD, COMPONENTS) \ + TEXEL_FETCH(NAME, int2(COORD) + int2(-1, 0))COMPONENTS, \ + TEXEL_FETCH(NAME, int2(COORD) + int2(0, 0))COMPONENTS, \ + TEXEL_FETCH(NAME, int2(COORD) + int2(0, -1))COMPONENTS, \ + TEXEL_FETCH(NAME, int2(COORD) + int2(-1, -1))COMPONENTS +// clang-format on + // This is a macro because we can't (at least for now) forward texture refs to a // function in a way that works in all the languages we support. // This is a macro because we can't (at least for now) forward texture refs to a @@ -138,6 +147,8 @@ INLINE half4 make_half4(half x) return ret; } +INLINE half4 make_half4(half4 x) { return x; } + INLINE bool2 make_bool2(bool b) { return bool2(b, b); } INLINE half3x3 make_half3x3(half3 a, half3 b, half3 c) @@ -157,15 +168,20 @@ INLINE half2x3 make_half2x3(half3 a, half3 b) return ret; } +INLINE half4x4 make_half4x4(half4 a, half4 b, half4 c, half4 d) +{ + half4x4 ret; + ret[0] = a; + ret[1] = b; + ret[2] = c; + ret[3] = d; + return ret; +} + INLINE float2x2 make_float2x2(float4 x) { return float2x2(x.xy, x.zw); } INLINE uint make_uint(ushort x) { return x; } -INLINE uint contour_data_idx(uint contourIDWithFlags) -{ - return (contourIDWithFlags & CONTOUR_ID_MASK) - 1u; -} - INLINE float2 unchecked_mix(float2 a, float2 b, float t) { return (b - a) * t + a; @@ -199,36 +215,114 @@ INLINE half3 unmultiply_rgb(half4 premul) return premul.rgb * (premul.a != .0 ? 1. / premul.a : .0); } -INLINE half min_value(half4 min4) +INLINE half min_component(half2 min2) { return min(min2.x, min2.y); } + +INLINE half min_component(half3 min3) +{ + return min(min_component(min3.xy), min3.z); +} + +INLINE half min_component(half4 min4) { half2 min2 = min(min4.xy, min4.zw); half min1 = min(min2.x, min2.y); return min1; } +INLINE half max_component(half2 max2) { return max(max2.x, max2.y); } + +INLINE half max_component(half3 max3) +{ + return max(max_component(max3.xy), max3.z); +} + +INLINE half max_component(half4 max4) +{ + half2 max2 = max(max4.xy, max4.zw); + half max1 = max(max2.x, max2.y); + return max1; +} + INLINE float manhattan_width(float2 x) { return abs(x.x) + abs(x.y); } -#ifndef $UNIFORM_DEFINITIONS_AUTO_GENERATED -UNIFORM_BLOCK_BEGIN(FLUSH_UNIFORM_BUFFER_IDX, @FlushUniforms) -float gradInverseViewportY; -float tessInverseViewportY; -float renderTargetInverseViewportX; -float renderTargetInverseViewportY; -uint renderTargetWidth; -uint renderTargetHeight; -uint colorClearValue; // Only used if clears are implemented as draws. -uint coverageClearValue; // Only used if clears are implemented as draws. -int4 renderTargetUpdateBounds; // drawBounds, or renderTargetBounds if there is - // a clear. (LTRB.) -float2 atlasTextureInverseSize; // 1 / [atlasWidth, atlasHeight] -float2 atlasContentInverseViewport; // 2 / atlasContentBounds -uint coverageBufferPrefix; -uint pathIDGranularity; // Spacing between adjacent path IDs (1 if IEEE - // compliant). -float vertexDiscardValue; -// Debugging. -uint wireframeEnabled; -UNIFORM_BLOCK_END(uniforms) +// ARM Mali has experienced multiple errors for us when calling clamp(), in both +// GL and Vulkan. +INLINE half safe_clamp_for_mali(half x, half lo, half hi) +{ +#if defined(@GL_RENDERER_MALI) || defined(@VULKAN_VENDOR_ID) +#ifdef @VULKAN_VENDOR_ID + if (@VULKAN_VENDOR_ID == VULKAN_VENDOR_ARM) +#endif + { + if (x < hi) + if (x > lo) + return x; + else + return lo; + else + return hi; + } +#endif // @GL_RENDERER_MALI || @VULKAN_VENDOR_ID + return clamp(x, lo, hi); +} + +INLINE half interleaved_gradient_noise(float2 fragCoord, half scale, half bias) +{ + half v1 = fract(0.06711056 * fragCoord.x + 0.00583715 * fragCoord.y); + half v2 = fract(52.9829189 * v1); + return (v2 * scale) + bias; +} + +#if 0 +// Bayer 4x4 and Bayer 2x2 variants included for reference, +// but not currently used. +INLINE half bayer4x4f(float2 fragCoord, float scale, float bias) +{ + int x = int(fragCoord.x); + int y = int(fragCoord.y); + + int xxory = (x ^ y); + int b = (y >> 1) & 1; + b |= (xxory & 2); + b |= (y & 1) << 2; + b |= (xxory & 1) << 3; + float fb = float(b); + half hb = cast_float_to_half(fb) / 16.0; + return (hb * scale) + bias; +} + +INLINE half bayer2x2f(float2 fragCoord, float scale, float bias) +{ + fragCoord.y *= 0.5; + fragCoord.x = fract(fragCoord.x * 0.5 + fragCoord.y); + fragCoord.y = fract(fragCoord.y); + float n = (fragCoord.y * 0.5 + fragCoord.x); + return (n * scale) + bias; +} +#endif + +#ifdef @ENABLE_DITHER +INLINE half get_dither(float2 fragCoord, half scale, half bias) +{ + return @ENABLE_DITHER ? interleaved_gradient_noise(fragCoord, scale, bias) + : .0; +} + +INLINE half3 add_dither(half3 color, float2 fragCoord, half scale, half bias) +{ + return @ENABLE_DITHER + ? (interleaved_gradient_noise(fragCoord, scale, bias) + color) + : color; +} + +#else + +INLINE half get_dither(float2 fragCoord, float scale, float bias) { return 0.; } + +INLINE half3 add_dither(half3 color, float2 fragCoord, half scale, half bias) +{ + return color; +} #endif #ifdef @VERTEX @@ -275,7 +369,7 @@ INLINE float4 find_clip_rect_coverage_distances(float2x2 clipRectInverseMatrix, } } -#else // RENDER_MODE_MSAA +#else // !@RENDER_MODE_MSAA => @RENDER_MODE_MSAA INLINE float normalize_z_index(uint zIndex) { @@ -285,9 +379,17 @@ INLINE float normalize_z_index(uint zIndex) #ifdef @ENABLE_CLIP_RECT INLINE void set_clip_rect_plane_distances(float2x2 clipRectInverseMatrix, float2 clipRectInverseTranslate, - float2 pixelPosition) + float2 pixelPosition + CLIP_CONTEXT_FORWARD) { - if (clipRectInverseMatrix != float2x2(0)) +// MSAA uses gl_ClipDistance when ENABLE_CLIP_RECT is set, but since SPIRV uses +// specialization constants (as opposed to compile-time flags), it means that +// the usage of them is in the compiled shader even if that codepath is not +// going to be taken, which ends up as a validation failure on systems that do +// not support that extension. In those cases, we compile separate SPIRV +// binaries with gl_ClipDistance explicitly disabled. +#ifndef @DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS + if (any(notEqual(float4(clipRectInverseMatrix), float4(.0, .0, .0, .0)))) { float2 clipRectCoord = MUL(clipRectInverseMatrix, pixelPosition) + clipRectInverseTranslate.xy; @@ -304,25 +406,58 @@ INLINE void set_clip_rect_plane_distances(float2x2 clipRectInverseMatrix, gl_ClipDistance[0] = gl_ClipDistance[1] = gl_ClipDistance[2] = gl_ClipDistance[3] = clipRectInverseTranslate.x - .5; } +#endif // !@DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS } #endif // ENABLE_CLIP_RECT -#endif // RENDER_MODE_MSAA + +#endif // @RENDER_MODE_MSAA #endif // VERTEX -#ifdef @DRAW_IMAGE -#ifndef $UNIFORM_DEFINITIONS_AUTO_GENERATED -UNIFORM_BLOCK_BEGIN(IMAGE_DRAW_UNIFORM_BUFFER_IDX, @ImageDrawUniforms) -float4 viewMatrix; -float2 translate; -float opacity; -float padding; -// clipRectInverseMatrix transforms from pixel coordinates to a space where the -// clipRect is the normalized rectangle: [-1, -1, 1, 1]. -float4 clipRectInverseMatrix; -float2 clipRectInverseTranslate; -uint clipID; -uint blendMode; -uint zIndex; -UNIFORM_BLOCK_END(imageDrawUniforms) -#endif -#endif +#ifdef @FRAGMENT +#ifdef @NEEDS_GAMMA_CORRECTION +INLINE half gamma_to_linear(half color) +{ + return (color <= 0.04045) ? color / 12.92 + : pow(abs((color + 0.055) / 1.055), 2.4); +} + +INLINE half3 gamma_to_linear(half3 color) +{ + return make_half3(gamma_to_linear(color.r), + gamma_to_linear(color.g), + gamma_to_linear(color.b)); +} + +INLINE half4 gamma_to_linear(half4 color) +{ + return make_half4(gamma_to_linear(color.rgb), color.a); +} +#endif // NEEDS_GAMMA_CORRECTION +#endif // FRAGMENT + +// The Qualcomm compiler can't handle line breaks in #ifs. +// clang-format off +#if defined(@FRAGMENT) && defined(@RENDER_MODE_MSAA) && !defined(@FIXED_FUNCTION_COLOR_OUTPUT) +// clang-format on +INLINE half4 dst_color_fetch(half4x4 dstSamples, int sampleMask) +{ + if (sampleMask == 0xf) + { + // Average together all samples for this fragment. + return (dstSamples[0] + dstSamples[1] + dstSamples[2] + dstSamples[3]) * + .25; + } + else + { + // Average together only the samples that are inside the sample mask. + half4 mask = float4(notEqual(sampleMask & int4(1, 2, 4, 8), int4(0))); + half4 ret = MUL(dstSamples, mask); + // Since the sample mask can only have 4 bits, counting them is faster + // this way on Galaxy S24 than calling bitCount(). + int numSamples = (sampleMask & 5) + ((sampleMask >> 1) & 5); + numSamples = (numSamples & 3) + (numSamples >> 2); + ret *= 1. / float(numSamples); + return ret; + } +} +#endif // @FRAGMENT && @RENDER_MODE_MSAA && !@FIXED_FUNCTION_COLOR_OUTPUT diff --git a/thirdparty/rive_renderer/source/shaders/constants.glsl b/thirdparty/rive_renderer/source/shaders/constants.glsl index eb5f3c63b..3f8837df9 100644 --- a/thirdparty/rive_renderer/source/shaders/constants.glsl +++ b/thirdparty/rive_renderer/source/shaders/constants.glsl @@ -32,6 +32,9 @@ // need at least one segment, thus a minimum of 2 (plus helper vertices). #define FEATHER_JOIN_MIN_SEGMENT_COUNT (2u + FEATHER_JOIN_HELPER_SEGMENT_COUNT) +#define MIN_FEATHER float(0.0) +#define MAX_FEATHER float(1.0) + // Width to use for a texture that emulates a storage buffer. // // Minimize width since the texture needs to be updated in entire rows from the @@ -96,6 +99,9 @@ #define RIGHT_JOIN_CONTOUR_FLAG (1u << 19u) #define CONTOUR_ID_MASK 0xffffu +// This is guaranteed to not collide with any path IDs being rendered. +#define INVALID_PATH_ID .0 + // This is guaranteed to not collide with a neighboring contour ID. #define INVALID_CONTOUR_ID_WITH_FLAGS 0u @@ -143,22 +149,27 @@ #define FEATHER_TEXTURE_IDX 10 #define ATLAS_TEXTURE_IDX 11 #define IMAGE_TEXTURE_IDX 12 -#define IMAGE_SAMPLER_IDX 13 -#define DST_COLOR_TEXTURE_IDX 14 -#define DEFAULT_BINDINGS_SET_SIZE 15 +#define DST_COLOR_TEXTURE_IDX 13 +#define DEFAULT_BINDINGS_SET_SIZE 14 + +// WebGPU needs image sampler index as a separate value. +#define WEBGPU_IMAGE_SAMPLER_IDX 14 +#define WEBGPU_BINDINGS_SET_SIZE 15 // Metal doesn't allow us to bind buffers index 0 or 1. Offset them by 2. #define METAL_BUFFER_IDX(IDX) (2 + IDX) -// Samplers are accessed at the same index as their corresponding texture, so we -// put them in a separate binding set. -#define IMMUTABLE_SAMPLER_BINDINGS_SET 2 - // PLS textures are accessed at the same index as their PLS planes, so we put // them in a separate binding set. -#define PLS_TEXTURE_BINDINGS_SET 3 +#define PLS_TEXTURE_BINDINGS_SET 2 -#define BINDINGS_SET_COUNT 4 +// In WebGPU there needs to be an additional binding set for samplers, because +// there is no way to bind a texture and sampler to the same binding index in +// the same binding set like there is in Vulkan. +#define WEBGPU_SAMPLER_BINDINGS_SET 3 + +#define VULKAN_BINDINGS_SET_COUNT 3 +#define WEBGPU_BINDINGS_SET_COUNT 4 // Index of each pixel local storage plane. #define COLOR_PLANE_IDX 0 @@ -166,7 +177,19 @@ #define SCRATCH_COLOR_PLANE_IDX 2 #define COVERAGE_PLANE_IDX 3 #define PLS_PLANE_COUNT 4 -#define DEPTH_STENCIL_IDX PLS_PLANE_COUNT + +// This is the framebuffer attachment index of the final color output during the +// "coalesced" atomic resolve. (Currently only used by Vulkan.) +// NOTE: This attachment is still referenced as color attachment 0 by the +// resolve subpass, so the shader doesn't need to know about it. +// NOTE: Atomic mode does not use SCRATCH_COLOR_PLANE_IDX, which is why we chose +// to alias this one. +#define COALESCED_ATOMIC_RESOLVE_IDX SCRATCH_COLOR_PLANE_IDX + +// MSAA attaches different resources to the framebuffer instead of PLS planes. +#define MSAA_DEPTH_STENCIL_IDX 1u +#define MSAA_RESOLVE_IDX 2u +#define MSAA_COLOR_SEED_IDX 3u // Rive has a hard-coded miter limit of 4 in the editor and all runtimes. #define RIVE_MITER_LIMIT float(4) @@ -178,6 +201,11 @@ // empirically unreliable on Android as ID values. #define MAX_DENORM_F16 1023u +// The minimum non-denormalized fp16 value is ~6.10e-5. So steer safely within +// this value (and outside of denormals, which may not be respected by GPUs), by +// using using 6.2e-5. +#define EPSILON_FP16_NON_DENORM 6.2e-5 + // Blend modes. Mirrors rive::BlendMode, but 0-based and contiguous for tighter // packing. #define BLEND_SRC_OVER 0u @@ -210,14 +238,30 @@ #define FIXED_COVERAGE_MASK 0x1ffffu // Fixed-point coverage values for clockwiseAtomic mode. -// clockwiseAtomic mode uses 6:11 fixed point, so the winding number breaks if a -// shape has more than 32 levels of self overlap in either winding direction at -// any point. -#define CLOCKWISE_COVERAGE_BIT_COUNT 17u -#define CLOCKWISE_COVERAGE_MASK 0x1ffffu -#define CLOCKWISE_COVERAGE_PRECISION float(2048) -#define CLOCKWISE_COVERAGE_INVERSE_PRECISION float(0.00048828125) -#define CLOCKWISE_FILL_ZERO_VALUE (1u << 16) +// +// The coverage buffer is laid out as: +// +// prefix(12) : blendColorValid(1) : coverageInt(9) : coverageFract(10) +// +// The prefix is a monotonically increasing token that instructs the shader to +// treat coverage as "cleared to zero" when it doesn't match the expectation, +// effectively allowing us to clear the coverage buffer by incrementing the +// token. +// +// The "blendColorValid" bit is used by shaders to signal once the blend color +// has become valid (and before overwriting the framebuffer), indicating that +// fragments should use that value instead of reading the framebuffer. +// +// NOTE: Coverage uses 9:10 fixed point, so the entire coverage buffer breaks if +// a shape has more than 2^8 levels of self overlap in either winding direction +// at any point. This impacts future paths as well. +#define CLOCKWISE_COVERAGE_PRECISION float(1024) +#define CLOCKWISE_COVERAGE_INVERSE_PRECISION float(0.0009765625) +#define CLOCKWISE_COVERAGE_BIT_COUNT 19u +#define CLOCKWISE_FILL_ZERO_VALUE (1u << (CLOCKWISE_COVERAGE_BIT_COUNT - 1u)) +#define CLOCKWISE_COVERAGE_MASK ((1u << CLOCKWISE_COVERAGE_BIT_COUNT) - 1u) +#define BLEND_COLOR_VALID_BIT (1u << CLOCKWISE_COVERAGE_BIT_COUNT) +#define CLOCKWISE_COVERAGE_PREFIX_ONE_VALUE (BLEND_COLOR_VALID_BIT << 1u) // Vendor IDs for driver workarounds. #define VULKAN_VENDOR_AMD 0x1002u @@ -226,6 +270,7 @@ #define VULKAN_VENDOR_ARM 0x13B5u #define VULKAN_VENDOR_QUALCOMM 0x5143u #define VULKAN_VENDOR_INTEL 0x8086u +#define VULKAN_VENDOR_SAMSUNG 0x144d // Indices for SPIRV specialization constants (used in lieu of #defines in // Vulkan.) @@ -236,7 +281,18 @@ #define EVEN_ODD_SPECIALIZATION_IDX 4 #define NESTED_CLIPPING_SPECIALIZATION_IDX 5 #define HSL_BLEND_MODES_SPECIALIZATION_IDX 6 -#define CLOCKWISE_FILL_SPECIALIZATION_IDX 7 -#define BORROWED_COVERAGE_PREPASS_SPECIALIZATION_IDX 8 -#define VULKAN_VENDOR_ID_SPECIALIZATION_IDX 9 -#define SPECIALIZATION_COUNT 10 +#define DITHER_SPECIALIZATION_IDX 7 +#define CLOCKWISE_FILL_SPECIALIZATION_IDX 8 +#define BORROWED_COVERAGE_PASS_SPECIALIZATION_IDX 9 +#define NESTED_CLIP_UPDATE_ONLY_IDX 10 +#define VULKAN_VENDOR_ID_SPECIALIZATION_IDX 11 +#define SPECIALIZATION_COUNT 12 + +// When rendering to an r32i feather atlas, use 16:16 fixed point. +#define ATLAS_R32I_FIXED_POINT_FACTOR 65536. + +// When we have to fall back on an 8-bit color buffer to render the feather +// atlas, sacrifice precision to lessen overflows. +// Throwing away the bottom 3 bits seems to be the best tradeoff, based on our +// golden image suite. +#define ATLAS_UNORM8_COVERAGE_SCALE_FACTOR 8. diff --git a/thirdparty/rive_renderer/source/shaders/d3d/color_ramp.hlsl_ b/thirdparty/rive_renderer/source/shaders/d3d/color_ramp.hlsl_ deleted file mode 100644 index 4a56bef78..000000000 --- a/thirdparty/rive_renderer/source/shaders/d3d/color_ramp.hlsl_ +++ /dev/null @@ -1,4 +0,0 @@ -#include "hlsl.minified.glsl" -#include "constants.minified.glsl" -#include "common.minified.glsl" -#include "color_ramp.minified.glsl" \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/d3d/render_atlas.hlsl_ b/thirdparty/rive_renderer/source/shaders/d3d/render_atlas.hlsl_ deleted file mode 100644 index 669112dae..000000000 --- a/thirdparty/rive_renderer/source/shaders/d3d/render_atlas.hlsl_ +++ /dev/null @@ -1,8 +0,0 @@ -#define DRAW_PATH -#define ENABLE_FEATHER - -#include "hlsl.minified.glsl" -#include "constants.minified.glsl" -#include "common.minified.glsl" -#include "draw_path_common.minified.glsl" -#include "render_atlas.minified.glsl" \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/d3d/root.sig_ b/thirdparty/rive_renderer/source/shaders/d3d/root.sig_ deleted file mode 100644 index ea04d873c..000000000 --- a/thirdparty/rive_renderer/source/shaders/d3d/root.sig_ +++ /dev/null @@ -1,93 +0,0 @@ -// d3d12 has the concept of descriptor heaps. -// This means we define the "slot" in our root -// signature and then offset our heap to represent positions in that signature. -// These are the offsets needed for each shader resource -// note: rtv's are not considered shader resource but they are a heap - -// all srv and uav are one heap. -// srv -// these are dynamic -#define PATH_BUFFER_HEAP_OFFSET 0 -#define PAINT_BUFFER_HEAP_OFFSET 1 -#define PAINT_AUX_BUFFER_HEAP_OFFSET 2 -#define CONTOUR_BUFFER_HEAP_OFFSET 3 -// these are static -#define TESS_IMAGE_HEAP_OFFSET 4 -#define GRAD_IMAGE_HEAP_OFFSET 5 -#define FEATHER_IMAGE_HEAP_OFFSET 6 -#define ATLAS_IMAGE_HEAP_OFFSET 7 -// uavs -#define ATOMIC_COLOR_HEAP_OFFSET 8 -#define ATOMIC_CLIP_HEAP_OFFSET 9 -#define ATOMIC_SCRATCH_COLOR_HEAP_OFFSET 10 -#define ATOMIC_COVERAGE_HEAP_OFFSET 11 -// images -#define IMAGE_HEAP_OFFSET_START 12 - -#define STATIC_SRV_UAV_HEAP_DESCRIPTOPR_START TESS_IMAGE_HEAP_OFFSET -#define DYNAMIC_SRV_UAV_HEAP_DESCRIPTOPR_START PATH_BUFFER_HEAP_OFFSET - -// this is for copies that happen every logical flush -#define NUM_DYNAMIC_SRV_HEAP_DESCRIPTORS CONTOUR_BUFFER_HEAP_OFFSET + 1 -#define NUM_SRV_HEAP_DESCRIPTORS ATLAS_IMAGE_HEAP_OFFSET + 1 -// this is for the first flush where we copy everything the things that don't -// change only once -#define NUM_STATIC_SRV_UAV_HEAP_DESCRIPTORS \ - ATOMIC_COVERAGE_HEAP_OFFSET - NUM_DYNAMIC_SRV_HEAP_DESCRIPTORS - -#define NUM_SRV_UAV_HEAP_DESCRIPTORS IMAGE_HEAP_OFFSET_START + 1 - -// all samplers are another heap -#define TESS_SAMPLER_HEAP_OFFSET 0 -#define GRAD_SAMPLER_HEAP_OFFSET 1 -#define FEATHER_SAMPLER_HEAP_OFFSET 2 -#define ATLAS_SAMPLER_HEAP_OFFSET 3 -#define IMAGE_SAMPLER_HEAP_OFFSET 4 - -#define NUM_SAMPLER_HEAP_DESCRIPTORS IMAGE_SAMPLER_HEAP_OFFSET + 1 -// constant buffers are bound directly to the sig so we can change it out as we -// go, to change a heap we would have to create a new one and use SetHeaps which -// is very slow -#define FLUSH_UNIFORM_BUFFFER_SIG_INDEX 0 -#define IMAGE_UNIFORM_BUFFFER_SIG_INDEX 1 -#define VERTEX_DRAW_UNIFORM_SIG_INDEX 2 -#define DYNAMIC_SRV_SIG_INDEX 3 -#define STATIC_SRV_SIG_INDEX 4 -#define IMAGE_SIG_INDEX 5 -#define UAV_SIG_INDEX 6 -#define SAMPLER_SIG_INDEX 7 -#define DYNAMIC_SAMPLER_SIG_INDEX 8 - -#define SRV_START_HEAP_INDEX PATH_BUFFER_HEAP_OFFSET -#define UAV_START_HEAP_INDEX ATOMIC_COLOR_HEAP_OFFSET -// samplers just start at 0 - -// rtv offsets -#define GRAD_RTV_HEAP_OFFSET 0 -#define TESS_RTV_HEAP_OFFSET 1 -#define ATLAS_RTV_HEAP_OFFSET 2 -#define TARGET_RTV_HEAP_OFFSET 3 - -// The root signature macro doesn't seem to support string splicing. We need to manually ensure the numbers here stay in sync with the above definitions. -#define ROOT_SIG "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " \ - "CBV(b0, flags=DATA_VOLATILE, visibility=SHADER_VISIBILITY_ALL), "\ - "CBV(b2, flags=DATA_VOLATILE, visibility=SHADER_VISIBILITY_ALL), "\ - "RootConstants(num32BitConstants=1, b1, visibility=SHADER_VISIBILITY_VERTEX), "\ - "DescriptorTable(SRV(t3), "\ - "SRV(t4),"\ - "SRV(t5),"\ - "SRV(t6), visibility=SHADER_VISIBILITY_ALL), "\ - "DescriptorTable(SRV(t8, flags=DESCRIPTORS_VOLATILE),"\ - "SRV(t9, flags=DESCRIPTORS_VOLATILE), "\ - "SRV(t10, flags=DESCRIPTORS_VOLATILE), " \ - "SRV(t11, flags=DESCRIPTORS_VOLATILE), visibility=SHADER_VISIBILITY_ALL), "\ - "DescriptorTable(SRV(t12, flags=DESCRIPTORS_VOLATILE), visibility=SHADER_VISIBILITY_PIXEL), "\ - "DescriptorTable(UAV(u0, flags=DESCRIPTORS_VOLATILE | DATA_VOLATILE),"\ - "UAV(u1, flags=DATA_VOLATILE),"\ - "UAV(u2, flags=DESCRIPTORS_VOLATILE | DATA_VOLATILE),"\ - "UAV(u3, flags=DATA_VOLATILE), visibility=SHADER_VISIBILITY_PIXEL),"\ - "DescriptorTable(Sampler(s8),"\ - "Sampler(s9),"\ - "Sampler(s10),"\ - "Sampler(s11), visibility=SHADER_VISIBILITY_ALL),"\ - "DescriptorTable(Sampler(s13, flags=DESCRIPTORS_VOLATILE), visibility=SHADER_VISIBILITY_PIXEL) " diff --git a/thirdparty/rive_renderer/source/shaders/d3d/tessellate.hlsl_ b/thirdparty/rive_renderer/source/shaders/d3d/tessellate.hlsl_ deleted file mode 100644 index c4b8324a3..000000000 --- a/thirdparty/rive_renderer/source/shaders/d3d/tessellate.hlsl_ +++ /dev/null @@ -1,5 +0,0 @@ -#include "hlsl.minified.glsl" -#include "constants.minified.glsl" -#include "common.minified.glsl" -#include "bezier_utils.minified.glsl" -#include "tessellate.minified.glsl" \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_borrowed_coverage.frag b/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_borrowed_coverage.frag new file mode 100644 index 000000000..7134e3180 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_borrowed_coverage.frag @@ -0,0 +1,55 @@ +/* + * Copyright 2026 Rive + */ + +#ifdef @FRAGMENT + +FRAG_STORAGE_BUFFER_BLOCK_BEGIN +STORAGE_BUFFER_U32_ATOMIC(COVERAGE_BUFFER_IDX, CoverageBuffer, coverageBuffer); +FRAG_STORAGE_BUFFER_BLOCK_END + +void main() +{ +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_INIT(v_windingWeight, half); +#else + VARYING_INIT(v_coverages, COVERAGE_TYPE); +#endif //@DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_coveragePlacement, uint2); + VARYING_UNPACK(v_coverageCoord, float2); + + half fragCoverage = +#ifdef @DRAW_INTERIOR_TRIANGLES + v_windingWeight; +#else + find_frag_coverage(v_coverages); +#endif + + uint2 coverageCoord = uint2(floor(v_coverageCoord)); + uint coveragePitch = v_coveragePlacement.y; + uint coverageIndex = v_coveragePlacement.x + + swizzle_buffer_idx_32x32(coverageCoord, coveragePitch); + + // Try to apply borrowedCoverage, assuming the existing coverage value + // is zero. + uint borrowedCoverageFixed = + clockwise_atomic_coverage_delta_to_fixed(abs(fragCoverage)); + uint targetCoverageValue = + uniforms.coverageBufferPrefix | + (CLOCKWISE_FILL_ZERO_VALUE - borrowedCoverageFixed); + uint coverageBeforeMax = STORAGE_BUFFER_ATOMIC_MAX(coverageBuffer, + coverageIndex, + targetCoverageValue); + if (coverageBeforeMax >= uniforms.coverageBufferPrefix) + { + // Coverage was not zero. Undo the atomicMax and then subtract + // borrowedCoverageFixed this time. + uint undoAtomicMax = + coverageBeforeMax - max(coverageBeforeMax, targetCoverageValue); + STORAGE_BUFFER_ATOMIC_ADD(coverageBuffer, + coverageIndex, + undoAtomicMax - borrowedCoverageFixed); + } +} + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_clip.frag b/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_clip.frag new file mode 100644 index 000000000..3dd382dcc --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_clip.frag @@ -0,0 +1,138 @@ +/* + * Copyright 2026 Rive + */ + +#ifdef @FRAGMENT + +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +PLS_DECL4F_WRITEONLY(CLIP_PLANE_IDX, clipBuffer); +PLS_BLOCK_END + +#ifdef @NESTED_CLIP_UPDATE_ONLY +FRAG_STORAGE_BUFFER_BLOCK_BEGIN +STORAGE_BUFFER_U32_ATOMIC(COVERAGE_BUFFER_IDX, CoverageBuffer, coverageBuffer); +FRAG_STORAGE_BUFFER_BLOCK_END +#endif + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT +#define CLOCKWISE_ATOMIC_PLS_MAIN PLS_FRAG_COLOR_MAIN +#define EMIT_CLOCKWISE_ATOMIC_PLS(FRAG_COLOR) \ + _fragColor = FRAG_COLOR; \ + EMIT_PLS_AND_FRAG_COLOR +#else +#define CLOCKWISE_ATOMIC_PLS_MAIN PLS_MAIN +#define EMIT_CLOCKWISE_ATOMIC_PLS(FRAG_COLOR) \ + PLS_STORE4F(colorBuffer, FRAG_COLOR); \ + EMIT_PLS; +#endif + +CLOCKWISE_ATOMIC_PLS_MAIN(@drawFragmentMain) +{ +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_windingWeight, half); + half fragCoverage = v_windingWeight; +#else + VARYING_UNPACK(v_coverages, COVERAGE_TYPE); + half fragCoverage = v_coverages.x; +#endif //@DRAW_INTERIOR_TRIANGLES + +#ifdef @NESTED_CLIP_UPDATE_ONLY + if (@NESTED_CLIP_UPDATE_ONLY) + { + VARYING_UNPACK(v_coveragePlacement, uint2); + VARYING_UNPACK(v_coverageCoord, float2); + + uint coveragePitch = v_coveragePlacement.y; + uint coverageIndex = + v_coveragePlacement.x + + swizzle_buffer_idx_32x32(uint2(floor(v_coverageCoord)), + coveragePitch); + + uint preexistingCoverageValue = + STORAGE_BUFFER_LOAD(coverageBuffer, coverageIndex); + half pathCoverage; + if (fragCoverage >= 1. && + (preexistingCoverageValue < uniforms.coverageBufferPrefix || + preexistingCoverageValue >= + (uniforms.coverageBufferPrefix | CLOCKWISE_FILL_ZERO_VALUE))) + { + // The inverse path has reached a coverage of 1, meaning, the area + // we are erasing from the clip has reached 0. + pathCoverage = .0; + // No need to update the coverage buffer because the blend op is + // min() and we have bottomed out at 0 -- it doesn't matter what any + // future fragments do anymore. + } + else + { + // clockwiseAtomic nested clip updates take the inverse path as + // input. + half inversePathCoverage = fragCoverage; + half unappliedFragCoverage = fragCoverage; + if (preexistingCoverageValue < uniforms.coverageBufferPrefix) + { + // There was no borrowed coverage and we *might* be the first + // fragment of the path to touch this pixel. Attempt to write + // out our coverage with an atomicMax. + uint targetCoverageValue = + uniforms.coverageBufferPrefix | + (CLOCKWISE_FILL_ZERO_VALUE + + clockwise_atomic_coverage_delta_to_fixed( + abs(fragCoverage))); + uint coverageBeforeMax = + STORAGE_BUFFER_ATOMIC_MAX(coverageBuffer, + coverageIndex, + targetCoverageValue); + if (coverageBeforeMax <= uniforms.coverageBufferPrefix) + { + // Success! We were the first fragment of the path at this + // pixel. + unappliedFragCoverage = .0; // We're done. + } + else if (coverageBeforeMax < targetCoverageValue) + { + // We were not first fragment of the path at this pixel, AND + // our atomicMax had some effect, but did not fully apply + // our coverage. + unappliedFragCoverage = + clockwise_atomic_fixed_to_coverage(coverageBeforeMax); + } + } + if (unappliedFragCoverage > .0) + { + // Coverage wasn't fully applied during the implicit clear + // operations above. Apply it now. + uint coverageBeforeAdd = STORAGE_BUFFER_ATOMIC_ADD( + coverageBuffer, + coverageIndex, + clockwise_atomic_coverage_delta_to_fixed( + abs(unappliedFragCoverage))); + inversePathCoverage = + clockwise_atomic_fixed_to_coverage(coverageBeforeAdd) + + fragCoverage; + } + + // clockwiseAtomic nested clip updates take the inverse path as + // input, so take 1 - inversePathCoverageto get back to the original + // nested path. + pathCoverage = 1. - inversePathCoverage; + } + + PLS_STORE4F(clipBuffer, make_half4(pathCoverage)); + + // Since the blend op is min(), emitting a color of 1 is effectively a + // no-op as long as we're using unorm targets. + EMIT_CLOCKWISE_ATOMIC_PLS(make_half4(1.)) + } + else +#endif + { + PLS_STORE4F(clipBuffer, make_half4(fragCoverage)); + EMIT_CLOCKWISE_ATOMIC_PLS(make_half4(.0)) + } +} + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_path.frag b/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_path.frag new file mode 100644 index 000000000..6b800fc16 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_clockwise_atomic_path.frag @@ -0,0 +1,379 @@ +/* + * Copyright 2023 Rive + */ + +#ifdef @FRAGMENT + +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +PLS_DECL4F(CLIP_PLANE_IDX, clipBuffer); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F_RGB10_A2_UAV(SCRATCH_COLOR_PLANE_IDX, blendColorBuffer); +#endif +PLS_BLOCK_END + +FRAG_STORAGE_BUFFER_BLOCK_BEGIN +STORAGE_BUFFER_U32_ATOMIC(COVERAGE_BUFFER_IDX, CoverageBuffer, coverageBuffer); +FRAG_STORAGE_BUFFER_BLOCK_END + +INLINE void apply_stroke_coverage(INOUT(float) paintAlpha, + half fragCoverage, + uint coverageIndex, + OUT(uint) preexistingCoverageValue, + OUT(half) newCoverage) +{ +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT + if (min(paintAlpha, fragCoverage) >= 1.) + { + // Solid stroke pixels don't need to work out coverage at all. We can + // just blast them out without ever touching the coverage buffer, even + // if another fragment from the path will get drawn on top. This is + // because any fragment drawn on top will be the same color, and any + // color blended onto a fully opaque version of itself is a no-op. + return; + } +#endif + + half X; + uint fragCoverageFixed = + clockwise_atomic_coverage_delta_to_fixed(abs(fragCoverage)); + preexistingCoverageValue = STORAGE_BUFFER_ATOMIC_MAX( + coverageBuffer, + coverageIndex, + uniforms.coverageBufferPrefix | fragCoverageFixed); + if (preexistingCoverageValue < uniforms.coverageBufferPrefix) + { + // This is the first fragment of the stroke to touch this pixel. Just + // multiply in our coverage and write it out. + X = fragCoverage; +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + newCoverage = fragCoverage; +#endif + } + else + { +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + if ((preexistingCoverageValue & BLEND_COLOR_VALID_BIT) != 0u) + { + // The BLEND_COLOR_VALID_BIT had already been set at this fragment. + // Redo the atomic max with that bit set. + preexistingCoverageValue = STORAGE_BUFFER_ATOMIC_MAX( + coverageBuffer, + coverageIndex, + uniforms.coverageBufferPrefix | BLEND_COLOR_VALID_BIT | + fragCoverageFixed); + } +#endif + // This pixel has been touched previously by a fragment in the stroke. + // Multiply in an incremental coverage value that mixes with what's + // already in the framebuffer. + half c0 = cast_uint_to_half(preexistingCoverageValue & + CLOCKWISE_COVERAGE_MASK) * + CLOCKWISE_COVERAGE_INVERSE_PRECISION; + half c1 = max(c0, fragCoverage); + X = incremental_clockwise_coverage(c0, c1, paintAlpha); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + newCoverage = c1; +#endif + } + + paintAlpha *= X; +} + +INLINE void apply_fill_coverage(INOUT(float) paintAlpha, + half fragCoverageRemaining, + uint coverageIndex, + OUT(uint) preexistingCoverageValue, + OUT(half) newCoverage) +{ + half X = .0; // Amount by which to multiply paintAlpha. + uint fragCoverageRemainingFixed = + clockwise_atomic_coverage_delta_to_fixed(abs(fragCoverageRemaining)); + + preexistingCoverageValue = + STORAGE_BUFFER_LOAD(coverageBuffer, coverageIndex); + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT + if (min(paintAlpha, fragCoverageRemaining) >= 1. && + (preexistingCoverageValue < uniforms.coverageBufferPrefix || + preexistingCoverageValue >= + (uniforms.coverageBufferPrefix | CLOCKWISE_FILL_ZERO_VALUE))) + { + // If we're solid, AND the current coverage at this pixel is >= 0, then + // we can just write out our color without working out coverage any + // further, even if another fragment from the path will get drawn on + // top. This is because any fragment drawn on top will be the same + // color, and any color blended onto a fully opaque version of itself is + // a no-op. + return; + } +#endif + + if (preexistingCoverageValue < uniforms.coverageBufferPrefix) + { + // The initial coverage value does not belong to this path. We *might* + // be the first fragment of the path to touch this pixel. Attempt to + // write out our coverage with an atomicMax. + uint targetCoverage = + uniforms.coverageBufferPrefix | + (CLOCKWISE_FILL_ZERO_VALUE + fragCoverageRemainingFixed); + uint coverageBeforeMax = STORAGE_BUFFER_ATOMIC_MAX(coverageBuffer, + coverageIndex, + targetCoverage); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + preexistingCoverageValue = coverageBeforeMax; +#endif + if (coverageBeforeMax <= uniforms.coverageBufferPrefix) + { + // Success! We were the first fragment of the path at this pixel. + X = fragCoverageRemaining; // Just multiply paintAlpha by coverage. +#ifdef @DRAW_INTERIOR_TRIANGLES + X = min(X, 1.); +#endif +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + newCoverage = X; +#endif + fragCoverageRemaining = .0; // We're done. + } + else if (coverageBeforeMax < targetCoverage) + { + // We were not first fragment of the path at this pixel, AND our + // atomicMax had an effect that we now have to account for in + // paintAlpha. Coverage increased from "coverageBeforeMax" to + // "fragCoverageRemaining". + // + // NOTE: because we know coverage was initially zero, and because + // coverage is always positive in this pass, we know + // coverageBeforeMax >= 0. + uint c0Fixed = (coverageBeforeMax & CLOCKWISE_COVERAGE_MASK) - + CLOCKWISE_FILL_ZERO_VALUE; + half c0 = cast_uint_to_half(c0Fixed) * + CLOCKWISE_COVERAGE_INVERSE_PRECISION; + half c1 = fragCoverageRemaining; +#ifdef @DRAW_INTERIOR_TRIANGLES + c1 = min(c1, 1.); +#endif +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + newCoverage = c1; +#endif + // Apply the coverage increase from the atomicMax here. The next + // step will apply the remaining increase. + X = incremental_clockwise_coverage(c0, c1, paintAlpha); + + // We increased coverage by an amount of "fragCoverageRemaining" - + // "coverageBeforeMax". However, we wanted to increase coverage by + // "fragCoverageRemaining". So the remaining amount we still need to + // increase by is "coverageBeforeMax". + fragCoverageRemainingFixed = c0Fixed; + fragCoverageRemaining = c0; + } + } + + if (fragCoverageRemaining > .0) + { + // At this point we know the value in the coverage buffer belongs to + // this path, so we can do a simple atomicAdd. + uint coverageBeforeAdd = + STORAGE_BUFFER_ATOMIC_ADD(coverageBuffer, + coverageIndex, + fragCoverageRemainingFixed); + half c0 = clockwise_atomic_fixed_to_coverage(coverageBeforeAdd); + half c1 = c0 + fragCoverageRemaining; + c0 = clamp(c0, .0, 1.); + c1 = clamp(c1, .0, 1.); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + newCoverage = c1; +#endif + // Apply the coverage increase from c0 -> c1 that we just did, in + // addition to any coverage that had been applied previously. + X += (1. - X * paintAlpha) * + incremental_clockwise_coverage(c0, c1, paintAlpha); + } + + paintAlpha *= X; +} + +CLOCKWISE_ATOMIC_PLS_MAIN(@drawFragmentMain) +{ + VARYING_UNPACK(v_paint, float4); +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_INIT(v_windingWeight, half); +#else + VARYING_INIT(v_coverages, COVERAGE_TYPE); +#endif //@DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_pathID, half); +#ifdef @ENABLE_CLIPPING + VARYING_UNPACK(v_clipIDs, half2); +#endif +#ifdef @ENABLE_CLIP_RECT + VARYING_UNPACK(v_clipRect, float4); +#endif +#ifdef @ENABLE_ADVANCED_BLEND + VARYING_UNPACK(v_blendMode, half); +#endif + VARYING_UNPACK(v_coveragePlacement, uint2); + VARYING_UNPACK(v_coverageCoord, float2); + + half4 paintColor = find_paint_color(v_paint, 1. FRAGMENT_CONTEXT_UNPACK); + +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + // Fetch the framebuffer BEFORE any atomic operations on the coverage + // buffer. In order for advanced blend to work, we have to fetch the + // framebuffer value before checking if it's still valid. + half4 dstColor = PLS_LOAD4F(colorBuffer); +#endif + + half fragCoverage = +#ifdef @DRAW_INTERIOR_TRIANGLES + v_windingWeight; +#else + find_frag_coverage(v_coverages); +#endif + + float2 coverageCoord = v_coverageCoord; +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + // This little trick forces the shader to fetch the framebuffer BEFORE any + // atomic operations on the coverage buffer. (i.e., not to reorder the above + // fetch past this point). In order for advanced blend to work, we have to + // fetch the framebuffer value before operating on coverage. + // + // NOTE: Since v_coverageCoord is pixel-grid aligned, it will always have a + // fractional value of ~.5 (because varyings are sampled at at pixel + // center). So as long as colorBuffer is a standard unorm in the range 0..1, + // this will have literally no effect on the final outcome. If we ever + // support rendering to full floating point targets outside the range 0..1, + // we may need to put some more thought into this. + coverageCoord += + (dstColor.rg + dstColor.ba) * uniforms.epsilonForPseudoMemoryBarrier; +#endif + coverageCoord = floor(coverageCoord); + uint coveragePitch = v_coveragePlacement.y; + uint coverageIndex = + v_coveragePlacement.x + + swizzle_buffer_idx_32x32(uint2(coverageCoord), coveragePitch); + + half maxCoverage = 1.; + +#ifdef @ENABLE_CLIP_RECT + if (@ENABLE_CLIP_RECT) + { + half clipRectMin = min_component(cast_float4_to_half4(v_clipRect)); + maxCoverage = min(clipRectMin, maxCoverage); + } +#endif + +#ifdef @ENABLE_CLIPPING + if (@ENABLE_CLIPPING && v_clipIDs.x != .0) + { + half clip = PLS_LOAD4F(clipBuffer).r; + maxCoverage = min(clip, maxCoverage); + } +#endif + + maxCoverage = max(maxCoverage, .0); + fragCoverage = clamp(fragCoverage, .0, maxCoverage); + + uint preexistingCoverageValue; + float newCoverage; +#ifndef @DRAW_INTERIOR_TRIANGLES + if (is_stroke(v_coverages)) + { + apply_stroke_coverage(paintColor.a, + fragCoverage, + coverageIndex, + preexistingCoverageValue, + newCoverage); + } + else // It's a fill. +#endif // !DRAW_INTERIOR_TRIANGLES + { + apply_fill_coverage(paintColor.a, + fragCoverage, + coverageIndex, + preexistingCoverageValue, + newCoverage); + } + +#ifdef @ENABLE_DITHER + half dither; + if (@ENABLE_DITHER) + { + dither = get_dither(_fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); + } +#endif + +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + if (paintColor.a > .0) + { + bool wasBlendColorValid = + preexistingCoverageValue >= uniforms.coverageBufferPrefix && + (preexistingCoverageValue & BLEND_COLOR_VALID_BIT) != 0u; + if (!wasBlendColorValid) + { + // If the saved blend color was not yet valid after we fetched + // dstColor, we are guaranteed that dstColor is valid because the + // BLEND_COLOR_VALID_BIT gets set before any color outputs that + // might overwrite the framebuffer. + // Calculate a blendColor based on dstColor. + paintColor.rgb = + advanced_color_blend(paintColor.rgb, + dstColor, + cast_half_to_ushort(v_blendMode)); + + // Anybody who updated, or will update, the coverage buffer before + // we overwrite the framebuffer is guaranteed to have a dstColor + // that is unaffected by our color output. They already have it. + // But if 0 < coverage < 1 after our fragment, we have to save out + // the blend color we just found for any future fragments that may + // need to blend, before we overwrite the contents of the + // framebuffer. + if (newCoverage < 1.) + { + half3 blendRGBToSave = paintColor.rgb; +#ifdef @ENABLE_DITHER + if (@ENABLE_DITHER) + { + blendRGBToSave += dither * uniforms.ditherConversionToRGB10; + } +#endif + PLS_STORE4F_UAV(blendColorBuffer, + make_half4(blendRGBToSave, .0)); + + // Mark this pixel as having a valid blendColor, AFTER writing + // out the blendColor, but BEFORE updating the framebuffer. + memoryBarrier(); + STORAGE_BUFFER_ATOMIC_OR(coverageBuffer, + coverageIndex, + BLEND_COLOR_VALID_BIT); + } + } + else + { + // Use the saved blendColor whenever it's valid, because shortly + // after that point the framebuffer can be overwritten, invalidating + // the dstColor. + paintColor.rgb = PLS_LOAD4F_UAV(blendColorBuffer).rgb; + } + } +#endif + + paintColor.rgb *= paintColor.a; + +#ifdef @ENABLE_DITHER + if (@ENABLE_DITHER) + { + paintColor.rgb += dither; + } +#endif + + // Since blend is enabled, storing 0 to the clip will ensure it remains + // unchanged. + PLS_STORE4F(clipBuffer, make_half4(.0)); + EMIT_CLOCKWISE_ATOMIC_PLS(paintColor); +} + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_clip.frag b/thirdparty/rive_renderer/source/shaders/draw_clockwise_clip.frag new file mode 100644 index 000000000..ccce07c47 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_clockwise_clip.frag @@ -0,0 +1,101 @@ +/* + * Copyright 2025 Rive + */ + +#ifdef @FRAGMENT + +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F_RGB10_A2(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer); +#endif +PLS_DECLUI(COVERAGE_PLANE_IDX, coverageBuffer); +PLS_BLOCK_END + +PLS_MAIN(@drawFragmentMain) +{ + VARYING_UNPACK(v_clipIDs, half2); + half clipID = -v_clipIDs.x; + +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_windingWeight, half); + half fragCoverage = v_windingWeight; +#else + VARYING_UNPACK(v_coverages, COVERAGE_TYPE); + half fragCoverage = v_coverages.x; +#endif //@DRAW_INTERIOR_TRIANGLES + + PLS_INTERLOCK_BEGIN; + + half2 clipData; + half clipBufferID, clipCoverage; +#if defined(@DRAW_INTERIOR_TRIANGLES) && defined(@BORROWED_COVERAGE_PASS) + if (@BORROWED_COVERAGE_PASS) + { + // Interior triangles with borrowed coverage are always the first + // fragment of the path at their pixel, so we don't need to check the + // current coverage value. + clipCoverage = fragCoverage; + } + else +#endif + { + clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); + clipBufferID = clipData.g; + half initialCoverage = + clipBufferID == clipID ? clipData.r : make_half(.0); + clipCoverage = initialCoverage + fragCoverage; + } + +#ifdef @ENABLE_NESTED_CLIPPING + half outerClipID = v_clipIDs.y; + if (@ENABLE_NESTED_CLIPPING && outerClipID != .0) + { + half outerClipCoverage = .0; +#if defined(@DRAW_INTERIOR_TRIANGLES) && defined(@BORROWED_COVERAGE_PASS) + if (@BORROWED_COVERAGE_PASS) + { + // Interior triangles with borrowed coverage did not load the clip + // buffer already, so do that now. + clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); + clipBufferID = clipData.g; + } +#endif + if (clipBufferID != clipID) + { + outerClipCoverage = clipBufferID == outerClipID ? clipData.r : .0; + // The coverage buffer is a free resource when rendering clip + // because we don't use it to track coverage. Use it instead to + // temporarily save the outer clip for nested clips. But make sure + // to write an invalid pathID so we don't corrupt any future paths + // that will be drawn. + PLS_STOREUI( + coverageBuffer, + packHalf2x16(make_half2(outerClipCoverage, INVALID_PATH_ID))); + } + else + { + outerClipCoverage = unpackHalf2x16(PLS_LOADUI(coverageBuffer)).r; + PLS_PRESERVE_UI(coverageBuffer); + } + clipCoverage = min(clipCoverage, outerClipCoverage); + } + else +#endif + { + PLS_PRESERVE_UI(coverageBuffer); + } + + PLS_STOREUI(clipBuffer, packHalf2x16(make_half2(clipCoverage, clipID))); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + PLS_PRESERVE_4F(colorBuffer); +#endif + PLS_INTERLOCK_END; + + EMIT_PLS; +} + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_image_mesh.glsl b/thirdparty/rive_renderer/source/shaders/draw_clockwise_image_mesh.glsl deleted file mode 100644 index a8855c4fc..000000000 --- a/thirdparty/rive_renderer/source/shaders/draw_clockwise_image_mesh.glsl +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2024 Rive - */ - -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(PositionAttr) -ATTR(0, float2, @a_position); -ATTR_BLOCK_END - -ATTR_BLOCK_BEGIN(UVAttr) -ATTR(1, float2, @a_texCoord); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -NO_PERSPECTIVE VARYING(0, float2, v_texCoord); -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_TEXTURE_BLOCK_BEGIN -VERTEX_TEXTURE_BLOCK_END - -IMAGE_MESH_VERTEX_MAIN(@drawVertexMain, - PositionAttr, - position, - UVAttr, - uv, - _vertexID) -{ - ATTR_UNPACK(_vertexID, position, @a_position, float2); - ATTR_UNPACK(_vertexID, uv, @a_texCoord, float2); - - VARYING_INIT(v_texCoord, float2); - - float2 vertexPosition = - MUL(make_float2x2(imageDrawUniforms.viewMatrix), @a_position) + - imageDrawUniforms.translate; - v_texCoord = @a_texCoord; - float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); - - VARYING_PACK(v_texCoord); - EMIT_VERTEX(pos); -} -#endif - -#ifdef @FRAGMENT -FRAG_TEXTURE_BLOCK_BEGIN -TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture); -FRAG_TEXTURE_BLOCK_END - -DYNAMIC_SAMPLER_BLOCK_BEGIN -SAMPLER_DYNAMIC(IMAGE_SAMPLER_IDX, imageSampler) -DYNAMIC_SAMPLER_BLOCK_END - -FRAG_STORAGE_BUFFER_BLOCK_BEGIN -FRAG_STORAGE_BUFFER_BLOCK_END - -FRAG_DATA_MAIN(half4, @drawFragmentMain) -{ - VARYING_UNPACK(v_texCoord, float2); - - half4 meshColor = - TEXTURE_SAMPLE_DYNAMIC(@imageTexture, imageSampler, v_texCoord); - meshColor = make_half4(unmultiply_rgb(meshColor), - meshColor.a * imageDrawUniforms.opacity); - - EMIT_FRAG_DATA(meshColor); -} -#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_path.frag b/thirdparty/rive_renderer/source/shaders/draw_clockwise_path.frag new file mode 100644 index 000000000..f4f5a153d --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_clockwise_path.frag @@ -0,0 +1,253 @@ +/* + * Copyright 2025 Rive + */ + +#ifdef @FRAGMENT + +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F_RGB10_A2(SCRATCH_COLOR_PLANE_IDX, blendColorBuffer); +#endif +PLS_DECLUI(COVERAGE_PLANE_IDX, coverageBuffer); +PLS_BLOCK_END + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_FRAG_COLOR_MAIN(@drawFragmentMain) +#else +PLS_MAIN(@drawFragmentMain) +#endif +{ + VARYING_UNPACK(v_paint, float4); +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_windingWeight, half); +#else + VARYING_UNPACK(v_coverages, COVERAGE_TYPE); +#endif //@DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_pathID, half); +#ifdef @ENABLE_CLIPPING + VARYING_UNPACK(v_clipIDs, half2); +#endif +#ifdef @ENABLE_CLIP_RECT + VARYING_UNPACK(v_clipRect, float4); +#endif +#ifdef @ENABLE_ADVANCED_BLEND + VARYING_UNPACK(v_blendMode, half); +#endif + + // Calculate fragment coverage before entering the interlock. + half fragCoverage = +#ifdef @DRAW_INTERIOR_TRIANGLES + v_windingWeight; +#else + find_frag_coverage(v_coverages); +#endif + + half4 paintColor; + half maxCoverage; +#if defined(@DRAW_INTERIOR_TRIANGLES) && defined(@BORROWED_COVERAGE_PASS) + if (!@BORROWED_COVERAGE_PASS) +#endif + { + // Calculate the paint color before entering the interlock. + paintColor = find_paint_color(v_paint, 1. FRAGMENT_CONTEXT_UNPACK); + + maxCoverage = 1.; +#ifdef @ENABLE_CLIP_RECT + // Calculate the clip rect before entering the interlock. + if (@ENABLE_CLIP_RECT) + { + half clipRectMin = min_component(cast_float4_to_half4(v_clipRect)); + maxCoverage = min(clipRectMin, maxCoverage); + } +#endif + } + + PLS_INTERLOCK_BEGIN; + +#if defined(@DRAW_INTERIOR_TRIANGLES) && defined(@BORROWED_COVERAGE_PASS) + if (@BORROWED_COVERAGE_PASS) + { + // Interior triangles with borrowed coverage never write color. They're + // also always the first fragment of the path at their pixel, so just + // blindly write coverage and move on. + PLS_STOREUI(coverageBuffer, + packHalf2x16(make_half2(fragCoverage, v_pathID))); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + PLS_PRESERVE_4F(colorBuffer); +#endif + } + else +#endif // !@DRAW_INTERIOR_TRIANGLES && @BORROWED_COVERAGE_PASS + { + half2 coverageData = unpackHalf2x16(PLS_LOADUI(coverageBuffer)); + half coverageBufferID = coverageData.g; + half initialCoverage = + coverageBufferID == v_pathID ? coverageData.r : make_half(.0); + half finalCoverage = +#ifndef @DRAW_INTERIOR_TRIANGLES + is_stroke(v_coverages) ? max(initialCoverage, fragCoverage) : +#endif + initialCoverage + fragCoverage; + +#ifdef @ENABLE_CLIPPING + if (@ENABLE_CLIPPING && v_clipIDs.x != .0) + { + half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); + half clipBufferID = clipData.g; + half clip = + clipBufferID == v_clipIDs.x ? clipData.r : make_half(.0); + maxCoverage = min(clip, maxCoverage); + } +#endif + + // Find the coverage delta (c0 -> c1) that this fragment will apply, + // where c0 is the coverage with which "paintColor" is already blended + // into the framebuffer, and c1 is the total coverage with which we + // *want* it to be blended after this fragment. The geometry is ordered + // such that if c1 > 0, c1 >= c0 as well. + maxCoverage = max(maxCoverage, .0); + half c0 = safe_clamp_for_mali(initialCoverage, .0, maxCoverage); + half c1 = safe_clamp_for_mali(finalCoverage, .0, maxCoverage); + +#ifdef @ENABLE_DITHER + half dither; + if (@ENABLE_DITHER) + { + dither = get_dither(_fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); + } +#endif + +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + half4 dstColorPremul = PLS_LOAD4F(colorBuffer); +#ifdef @ENABLE_ADVANCED_BLEND + if (@ENABLE_ADVANCED_BLEND) + { + // Don't bother with advanced blend until coverage becomes > 0. This + // way, cutout regions don't pay the cost of advanced blend. + if (v_blendMode != cast_uint_to_half(BLEND_SRC_OVER) && c1 != .0) + { + if (c0 == .0) + { + // This is the first fragment of the path to apply the blend + // mode, meaning, the current dstColor is the correct value + // we need to pass to advanced_color_blend(). Calculate the + // color-blended paint color before coverage. Coverage can + // be applied later as a simple src-over operation. + paintColor.rgb = + advanced_color_blend(paintColor.rgb, + dstColorPremul, + cast_half_to_ushort(v_blendMode)); + // Normally we need to save the color-blended paint color + // for any future fragments at this same pixel because once + // we blend this fragment, the original dstColor will be + // destroyed. However, there are 2 exceptions: + // + // * No need to save the color-blended paint color if we're + // a + // (clockwise) interior triangle, because those are always + // guaranteed to be the final fragment of the path at a + // given pixel. + // + // * No need to save the color-blended paint color once + // coverage + // is maxed out, out because once it's maxed, any future + // fragments will effectively be no-ops (since c1 - c0 == + // 0). +#ifndef @DRAW_INTERIOR_TRIANGLES + if (c1 < maxCoverage) + { + half3 blendRGBToSave = paintColor.rgb; +#ifdef @ENABLE_DITHER + if (@ENABLE_DITHER) + { + blendRGBToSave += + dither * uniforms.ditherConversionToRGB10; + } +#endif + PLS_STORE4F(blendColorBuffer, + make_half4(blendRGBToSave, 0.0)); + } +#endif + } + else + { + // This is not the first fragment of the path to apply the + // blend mode, meaning, the current dstColor is no longer + // the correct value we need to pass to + // advanced_color_blend(). Instead, the first fragment saved + // its result of advanced_color_blend() to the + // blendColorBuffer, which we can pull back up and use to + // apply our fragment's coverage contribution. + paintColor.rgb = PLS_LOAD4F(blendColorBuffer).rgb; + PLS_PRESERVE_4F(blendColorBuffer); + } + } + // GENERATE_PREMULTIPLIED_PAINT_COLORS is false when + // @ENABLE_ADVANCED_BLEND is defined because advanced blend needs + // unmultiplied colors. Premultiply alpha now. + paintColor.rgb *= paintColor.a; + } +#endif // @ENABLE_ADVANCED_BLEND +#endif // @FIXED_FUNCTION_COLOR_OUTPUT + + // Emit a paint color whose post-src-over-blend result is algebraically + // equivalent to applying the c0 -> c1 coverage delta. + paintColor *= incremental_clockwise_coverage(c0, c1, paintColor.a); +#ifdef @ENABLE_DITHER + if (@ENABLE_DITHER) + { + paintColor.rgb += dither; + } +#endif +#ifndef @DRAW_INTERIOR_TRIANGLES + // Update the coverage buffer with our final value if we aren't an + // interior triangle, because another fragment from this same path might + // come along at this pixel. The only exception is if we're src-over and + // fully opaque, because at that point the next fragment will + // effectively be a no-op (since any color blended with itself is a + // no-op). +#ifdef @ENABLE_ADVANCED_BLEND + // We can't skip the write for advanced blends either because they use + // the ID in the coverage buffer to detect the first fragment of the + // path for dst reads. +#define COVERAGE_UPDATE_OPTIONAL \ + (!@ENABLE_ADVANCED_BLEND || \ + v_blendMode == cast_uint_to_half(BLEND_SRC_OVER)) && \ + paintColor.a >= 1. +#else +#define COVERAGE_UPDATE_OPTIONAL paintColor.a >= 1. +#endif + PLS_STOREUI_OPTIONAL_IF( + COVERAGE_UPDATE_OPTIONAL, + coverageBuffer, + packHalf2x16(make_half2(finalCoverage, v_pathID))); +#else // -> @DRAW_INTERIOR_TRIANGLES + PLS_PRESERVE_UI(coverageBuffer); +#endif + +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + PLS_STORE4F_OPTIONAL_IF(paintColor.a == .0, + colorBuffer, + dstColorPremul * (1. - paintColor.a) + + paintColor); +#endif + } + + PLS_PRESERVE_UI(clipBuffer); + PLS_INTERLOCK_END; + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT + _fragColor = paintColor; + EMIT_PLS_AND_FRAG_COLOR +#else + EMIT_PLS; +#endif +} + +#endif // @FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_clockwise_path.glsl b/thirdparty/rive_renderer/source/shaders/draw_clockwise_path.glsl deleted file mode 100644 index 62d0d80e9..000000000 --- a/thirdparty/rive_renderer/source/shaders/draw_clockwise_path.glsl +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#ifdef @DRAW_PATH -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(Attrs) -// [localVertexID, outset, fillCoverage, vertexType] -ATTR(0, float4, @a_patchVertexData); -ATTR(1, float4, @a_mirroredVertexData); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -FLAT VARYING(0, ushort, v_pathID); -NO_PERSPECTIVE VARYING(1, float4, v_coverages); -NO_PERSPECTIVE VARYING(2, float2, v_atlasCoord); -FLAT VARYING(3, uint2, v_coveragePlacement); -VARYING(4, float2, v_coverageCoord); -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) -{ - ATTR_UNPACK(_vertexID, attrs, @a_patchVertexData, float4); - ATTR_UNPACK(_vertexID, attrs, @a_mirroredVertexData, float4); - - VARYING_INIT(v_pathID, ushort); - VARYING_INIT(v_coverages, float4); - VARYING_INIT(v_coveragePlacement, uint2); - VARYING_INIT(v_coverageCoord, float2); - - float4 pos; - uint pathID; - float2 vertexPosition; - if (unpack_tessellated_path_vertex(@a_patchVertexData, - @a_mirroredVertexData, - _instanceID, - pathID, - vertexPosition, - v_coverages VERTEX_CONTEXT_UNPACK)) - { - uint4 coverageData = - STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u); - v_pathID = pathID; - v_coveragePlacement = coverageData.xy; - v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw); - pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); - } - else - { - pos = float4(uniforms.vertexDiscardValue, - uniforms.vertexDiscardValue, - uniforms.vertexDiscardValue, - uniforms.vertexDiscardValue); - } - - VARYING_PACK(v_pathID); - VARYING_PACK(v_coverages); - VARYING_PACK(v_coveragePlacement); - VARYING_PACK(v_coverageCoord); - EMIT_VERTEX(pos); -} -#endif // VERTEX -#endif // DRAW_PATH - -#ifdef @DRAW_INTERIOR_TRIANGLES -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(Attrs) -ATTR(0, packed_float3, @a_triangleVertex); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -FLAT VARYING(0, ushort, v_pathID); -#ifdef @ATLAS_BLIT -NO_PERSPECTIVE VARYING(1, float2, v_atlasCoord); -#else -@OPTIONALLY_FLAT VARYING(1, half, v_windingWeight); -FLAT VARYING(2, uint2, v_coveragePlacement); -VARYING(3, float2, v_coverageCoord); -#endif -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) -{ - ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, float3); - -#ifdef @ATLAS_BLIT - VARYING_INIT(v_atlasCoord, float2); -#else -#endif - VARYING_INIT(v_pathID, ushort); -#ifdef @ATLAS_BLIT - VARYING_INIT(v_atlasCoord, float2); -#else - VARYING_INIT(v_windingWeight, half); - VARYING_INIT(v_coveragePlacement, uint2); - VARYING_INIT(v_coverageCoord, float2); -#endif - - uint pathID; - float2 vertexPosition; -#ifdef @ATLAS_BLIT - vertexPosition = - unpack_atlas_coverage_vertex(@a_triangleVertex, - pathID, - v_atlasCoord VERTEX_CONTEXT_UNPACK); -#else - vertexPosition = - unpack_interior_triangle_vertex(@a_triangleVertex, - pathID, - v_windingWeight VERTEX_CONTEXT_UNPACK); - uint4 coverageData = STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u); - v_coveragePlacement = coverageData.xy; - v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw); -#endif - v_pathID = cast_uint_to_ushort(pathID); - float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); - - VARYING_PACK(v_pathID); -#ifdef @ATLAS_BLIT - VARYING_PACK(v_atlasCoord); -#else - VARYING_PACK(v_windingWeight); - VARYING_PACK(v_coveragePlacement); - VARYING_PACK(v_coverageCoord); -#endif - - EMIT_VERTEX(pos); -} -#endif // VERTEX -#endif // DRAW_INTERIOR_TRIANGLES - -#ifdef @FRAGMENT -FRAG_STORAGE_BUFFER_BLOCK_BEGIN -STORAGE_BUFFER_U32x2(PAINT_BUFFER_IDX, PaintBuffer, @paintBuffer); -STORAGE_BUFFER_F32x4(PAINT_AUX_BUFFER_IDX, PaintAuxBuffer, @paintAuxBuffer); -STORAGE_BUFFER_U32_ATOMIC(COVERAGE_BUFFER_IDX, CoverageBuffer, coverageBuffer); -FRAG_STORAGE_BUFFER_BLOCK_END - -#ifdef @BORROWED_COVERAGE_PREPASS -INLINE void apply_borrowed_coverage(half borrowedCoverage, uint coverageIndex) -{ - // Try to apply borrowedCoverage, assuming the existing coverage value - // is zero. - uint borrowedCoverageFixed = - uint(abs(borrowedCoverage) * CLOCKWISE_COVERAGE_PRECISION + .5); - uint targetCoverageValue = - uniforms.coverageBufferPrefix | - (CLOCKWISE_FILL_ZERO_VALUE - borrowedCoverageFixed); - uint coverageBeforeMax = STORAGE_BUFFER_ATOMIC_MAX(coverageBuffer, - coverageIndex, - targetCoverageValue); - if (coverageBeforeMax >= uniforms.coverageBufferPrefix) - { - // Coverage was not zero. Undo the atomicMax and then subtract - // borrowedCoverageFixed this time. - uint undoAtomicMax = - coverageBeforeMax - max(coverageBeforeMax, targetCoverageValue); - STORAGE_BUFFER_ATOMIC_ADD(coverageBuffer, - coverageIndex, - undoAtomicMax - borrowedCoverageFixed); - } -} -#endif - -INLINE void apply_stroke_coverage(INOUT(float) paintAlpha, - half fragCoverage, - uint coverageIndex) -{ - if (min(paintAlpha, fragCoverage) >= 1.) - { - // Solid stroke pixels don't need to work out coverage at all. We can - // just blast them out without ever touching the coverage buffer. - return; - } - - half X; - uint fragCoverageFixed = - uint(abs(fragCoverage) * CLOCKWISE_COVERAGE_PRECISION + .5); - uint coverageBeforeMax = STORAGE_BUFFER_ATOMIC_MAX( - coverageBuffer, - coverageIndex, - uniforms.coverageBufferPrefix | fragCoverageFixed); - if (coverageBeforeMax < uniforms.coverageBufferPrefix) - { - // This is the first fragment of the stroke to touch this pixel. Just - // multiply in our coverage and write it out. - X = fragCoverage; - } - else - { - // This pixel has been touched previously by a fragment in the stroke. - // Multiply in an incremental coverage value that mixes with what's - // already in the framebuffer. - half c1 = - cast_uint_to_half(coverageBeforeMax & CLOCKWISE_COVERAGE_MASK) * - CLOCKWISE_COVERAGE_INVERSE_PRECISION; - half c2 = max(c1, fragCoverage); - X = (c2 - c1) / (1. - c1 * paintAlpha); - } - - paintAlpha *= X; -} - -INLINE void apply_fill_coverage(INOUT(float) paintAlpha, - half fragCoverageRemaining, - uint coverageIndex) -{ - uint coverageInitialValue = - STORAGE_BUFFER_LOAD(coverageBuffer, coverageIndex); - if (min(paintAlpha, fragCoverageRemaining) >= 1. && - (coverageInitialValue < uniforms.coverageBufferPrefix || - coverageInitialValue >= - (uniforms.coverageBufferPrefix | CLOCKWISE_FILL_ZERO_VALUE))) - { - // If we're solid, AND the current coverage at this pixel is >= 0, then - // we can just write out or color without working out coverage any - // further. - return; - } - - half X = .0; // Amount by which to multiply paintAlpha. - uint fragCoverageRemainingFixed = - uint(abs(fragCoverageRemaining) * CLOCKWISE_COVERAGE_PRECISION + .5); - if (coverageInitialValue < uniforms.coverageBufferPrefix) - { - // The initial coverage value does not belong to this path. We *might* - // be the first fragment of the path to touch this pixel. Attempt to - // write out our coverage with an atomicMax. - uint targetCoverage = - uniforms.coverageBufferPrefix | - (CLOCKWISE_FILL_ZERO_VALUE + fragCoverageRemainingFixed); - uint coverageBeforeMax = STORAGE_BUFFER_ATOMIC_MAX(coverageBuffer, - coverageIndex, - targetCoverage); - if (coverageBeforeMax <= uniforms.coverageBufferPrefix) - { - // Success! We were the first fragment of the path at this pixel. - X = fragCoverageRemaining; // Just multiply paintAlpha by coverage. -#ifdef @DRAW_INTERIOR_TRIANGLES - X = min(X, 1.); -#endif - fragCoverageRemaining = .0; // We're done. - } - else if (coverageBeforeMax < targetCoverage) - { - // We were not first fragment of the path at this pixel, AND our - // atomicMax had an effect that we now have to account for in - // paintAlpha. Coverage increased from "coverageBeforeMax" to - // "fragCoverageRemaining". - // - // NOTE: because we know coverage was initially zero, and because - // coverage is always positive in this pass, we know - // coverageBeforeMax >= 0. - uint c1Fixed = (coverageBeforeMax & CLOCKWISE_COVERAGE_MASK) - - CLOCKWISE_FILL_ZERO_VALUE; - half c1 = cast_uint_to_half(c1Fixed) * - CLOCKWISE_COVERAGE_INVERSE_PRECISION; - half c2 = fragCoverageRemaining; -#ifdef @DRAW_INTERIOR_TRIANGLES - c2 = min(c2, 1.); -#endif - // Apply the coverage increase from the atomicMax here. The next - // step will apply the remaining increase. - X = (c2 - c1) / (1. - c1 * paintAlpha); - - // We increased coverage by an amount of "fragCoverageRemaining" - - // "coverageBeforeMax". However, we wanted to increase coverage by - // "fragCoverageRemaining". So the remaining amount we still need to - // increase by is "coverageBeforeMax". - fragCoverageRemainingFixed = c1Fixed; - fragCoverageRemaining = c1; - } - } - - if (fragCoverageRemaining > .0) - { - // At this point we know the value in the coverage buffer belongs to - // this path, so we can do a simple atomicAdd. - uint coverageBeforeAdd = - STORAGE_BUFFER_ATOMIC_ADD(coverageBuffer, - coverageIndex, - fragCoverageRemainingFixed); - half c1 = - cast_int_to_half(int((coverageBeforeAdd & CLOCKWISE_COVERAGE_MASK) - - CLOCKWISE_FILL_ZERO_VALUE)) * - CLOCKWISE_COVERAGE_INVERSE_PRECISION; - half c2 = c1 + fragCoverageRemaining; - c1 = clamp(c1, .0, 1.); - c2 = clamp(c2, .0, 1.); - // Apply the coverage increase from c1 -> c2 that we just did, in - // addition to any coverage that had been applied previously. - half one_minus_c1a = 1. - c1 * paintAlpha; - if (one_minus_c1a <= .0) - discard; - X += (1. - X * paintAlpha) * (c2 - c1) / one_minus_c1a; - } - - paintAlpha *= X; -} - -FRAG_DATA_MAIN(half4, @drawFragmentMain) -{ - VARYING_UNPACK(v_pathID, ushort); -#ifdef DRAW_PATH - VARYING_UNPACK(v_coverages, float4); -#elif defined(@ATLAS_BLIT) - VARYING_UNPACK(v_atlasCoord, float2); -#else - VARYING_UNPACK(v_windingWeight, half); -#endif -#ifndef @ATLAS_BLIT - VARYING_UNPACK(v_coveragePlacement, uint2); - VARYING_UNPACK(v_coverageCoord, float2); -#endif - - half4 paintColor; - uint pathID = v_pathID; - uint2 paintData = STORAGE_BUFFER_LOAD2(@paintBuffer, pathID); - uint paintType = paintData.x & 0xfu; - if (paintType <= SOLID_COLOR_PAINT_TYPE) // CLIP_UPDATE_PAINT_TYPE or - // SOLID_COLOR_PAINT_TYPE - { - paintColor = unpackUnorm4x8(paintData.y); - } - else // LINEAR_GRADIENT_PAINT_TYPE, - // RADIAL_GRADIENT_PAINT_TYPE, or - // IMAGE_PAINT_TYPE - { - float2x2 M = - make_float2x2(STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u)); - float4 translate = - STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u + 1u); - float2 paintCoord = MUL(M, _fragCoord) + translate.xy; - if (paintType != IMAGE_PAINT_TYPE) - { - float t = paintType == LINEAR_GRADIENT_PAINT_TYPE - ? /*linear*/ paintCoord.x - : /*radial*/ length(paintCoord); - t = clamp(t, .0, 1.); - float x = t * translate.z + translate.w; - float y = uintBitsToFloat(paintData.y); - paintColor = - TEXTURE_SAMPLE_LOD(@gradTexture, gradSampler, float2(x, y), .0); - } - else - { - float opacity = uintBitsToFloat(paintData.y); - float lod = translate.z; - paintColor = TEXTURE_SAMPLE_LOD(@imageTexture, - imageSampler, - paintCoord, - lod); - paintColor = - make_half4(unmultiply_rgb(paintColor), paintColor.a * opacity); - } - } - - if (paintColor.a == .0) - { - discard; - } - -#ifdef @ATLAS_BLIT - paintColor.a *= filter_feather_atlas( - v_atlasCoord, - uniforms.atlasTextureInverseSize TEXTURE_CONTEXT_FORWARD); -#else - // Swizzle the coverage buffer in a tiled format, starting with 32x32 - // row-major tiles. - uint coverageIndex = v_coveragePlacement.x; - uint coveragePitch = v_coveragePlacement.y; - uint2 coverageCoord = uint2(floor(v_coverageCoord)); - coverageIndex += (coverageCoord.y >> 5) * (coveragePitch << 5) + - (coverageCoord.x >> 5) * (32 << 5); - // Subdivide each main tile into 4x4 column-major tiles. - coverageIndex += ((coverageCoord.x & 0x1f) >> 2) * (32 << 2) + - ((coverageCoord.y & 0x1f) >> 2) * (4 << 2); - // Let the 4x4 tiles be row-major. - coverageIndex += (coverageCoord.y & 0x3) * 4 + (coverageCoord.x & 0x3); - -#ifdef @BORROWED_COVERAGE_PREPASS - if (@BORROWED_COVERAGE_PREPASS) - { -#ifdef @DRAW_INTERIOR_TRIANGLES - half borrowedCoverage = -v_windingWeight; -#else - half fragCoverage; -#ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_fill(v_coverages)) - { - fragCoverage = - eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif - { - fragCoverage = v_coverages.x; - } - half borrowedCoverage = max(-fragCoverage, .0); -#endif - apply_borrowed_coverage(borrowedCoverage, coverageIndex); - discard; - } -#endif // BORROWED_COVERAGE_PREPASS - -#ifndef @DRAW_INTERIOR_TRIANGLES - if (is_stroke(v_coverages)) - { - half fragCoverage; -#ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_stroke(v_coverages)) - { - fragCoverage = - eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif - { - fragCoverage = min(v_coverages.x, v_coverages.y); - } - fragCoverage = clamp(fragCoverage, .0, 1.); - apply_stroke_coverage(paintColor.a, fragCoverage, coverageIndex); - } - else // It's a fill. -#endif // !DRAW_INTERIOR_TRIANGLES - { -#ifdef @DRAW_INTERIOR_TRIANGLES - half fragCoverage = v_windingWeight; -#else - half fragCoverage; -#ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_fill(v_coverages)) - { - fragCoverage = - eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif - { - fragCoverage = v_coverages.x; - } - fragCoverage = clamp(fragCoverage, .0, 1.); -#endif - apply_fill_coverage(paintColor.a, fragCoverage, coverageIndex); - } -#endif // @ATLAS_BLIT - - EMIT_FRAG_DATA(paintColor); -} -#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_fullscreen_quad.vert b/thirdparty/rive_renderer/source/shaders/draw_fullscreen_quad.vert new file mode 100644 index 000000000..56d7782ae --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_fullscreen_quad.vert @@ -0,0 +1,15 @@ +/* + * Copyright 2025 Rive + */ + +#ifdef @VERTEX +void main() +{ + // Fill the entire screen. The caller will use a scissor test to control the + // bounds being drawn. + gl_Position.x = (gl_VertexID & 1) == 0 ? -1. : 1.; + gl_Position.y = (gl_VertexID & 2) == 0 ? -1. : 1.; + gl_Position.z = 0.; + gl_Position.w = 1.; +} +#endif diff --git a/thirdparty/rive_renderer/source/shaders/draw_image_mesh.glsl b/thirdparty/rive_renderer/source/shaders/draw_image_mesh.glsl deleted file mode 100644 index c62e51772..000000000 --- a/thirdparty/rive_renderer/source/shaders/draw_image_mesh.glsl +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(PositionAttr) -ATTR(0, float2, @a_position); -ATTR_BLOCK_END - -ATTR_BLOCK_BEGIN(UVAttr) -ATTR(1, float2, @a_texCoord); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -NO_PERSPECTIVE VARYING(0, float2, v_texCoord); -#ifdef @ENABLE_CLIPPING -@OPTIONALLY_FLAT VARYING(1, half, v_clipID); -#endif -#ifdef @ENABLE_CLIP_RECT -NO_PERSPECTIVE VARYING(2, float4, v_clipRect); -#endif -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_TEXTURE_BLOCK_BEGIN -VERTEX_TEXTURE_BLOCK_END - -IMAGE_MESH_VERTEX_MAIN(@drawVertexMain, - PositionAttr, - position, - UVAttr, - uv, - _vertexID) -{ - ATTR_UNPACK(_vertexID, position, @a_position, float2); - ATTR_UNPACK(_vertexID, uv, @a_texCoord, float2); - - VARYING_INIT(v_texCoord, float2); -#ifdef @ENABLE_CLIPPING - VARYING_INIT(v_clipID, half); -#endif -#ifdef @ENABLE_CLIP_RECT - VARYING_INIT(v_clipRect, float4); -#endif - - float2 vertexPosition = - MUL(make_float2x2(imageDrawUniforms.viewMatrix), @a_position) + - imageDrawUniforms.translate; - v_texCoord = @a_texCoord; -#ifdef @ENABLE_CLIPPING - if (@ENABLE_CLIPPING) - { - v_clipID = id_bits_to_f16(imageDrawUniforms.clipID, - uniforms.pathIDGranularity); - } -#endif -#ifdef @ENABLE_CLIP_RECT - if (@ENABLE_CLIP_RECT) - { -#ifndef @RENDER_MODE_MSAA - v_clipRect = find_clip_rect_coverage_distances( - make_float2x2(imageDrawUniforms.clipRectInverseMatrix), - imageDrawUniforms.clipRectInverseTranslate, - vertexPosition); -#else // RENDER_MODE_MSAA - set_clip_rect_plane_distances( - make_float2x2(imageDrawUniforms.clipRectInverseMatrix), - imageDrawUniforms.clipRectInverseTranslate, - vertexPosition); -#endif // RENDER_MODE_MSAA - } -#endif // ENABLE_CLIP_RECT - float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); -#ifdef @RENDER_MODE_MSAA - pos.z = normalize_z_index(imageDrawUniforms.zIndex); -#endif - - VARYING_PACK(v_texCoord); -#ifdef @ENABLE_CLIPPING - VARYING_PACK(v_clipID); -#endif -#ifdef @ENABLE_CLIP_RECT - VARYING_PACK(v_clipRect); -#endif - EMIT_VERTEX(pos); -} -#endif - -#ifdef @FRAGMENT -FRAG_TEXTURE_BLOCK_BEGIN -TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture); -#ifdef @RENDER_MODE_MSAA -#ifdef @ENABLE_ADVANCED_BLEND -TEXTURE_RGBA8(PER_FLUSH_BINDINGS_SET, DST_COLOR_TEXTURE_IDX, @dstColorTexture); -#endif -#endif -FRAG_TEXTURE_BLOCK_END - -DYNAMIC_SAMPLER_BLOCK_BEGIN -SAMPLER_DYNAMIC(IMAGE_SAMPLER_IDX, imageSampler) -DYNAMIC_SAMPLER_BLOCK_END - -FRAG_STORAGE_BUFFER_BLOCK_BEGIN -FRAG_STORAGE_BUFFER_BLOCK_END - -#ifndef @RENDER_MODE_MSAA - -PLS_BLOCK_BEGIN -PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); -PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); -PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer); -PLS_DECLUI(COVERAGE_PLANE_IDX, coverageCountBuffer); -PLS_BLOCK_END - -PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) -{ - VARYING_UNPACK(v_texCoord, float2); -#ifdef @ENABLE_CLIPPING - VARYING_UNPACK(v_clipID, half); -#endif -#ifdef @ENABLE_CLIP_RECT - VARYING_UNPACK(v_clipRect, float4); -#endif - - half4 color = - TEXTURE_SAMPLE_DYNAMIC(@imageTexture, imageSampler, v_texCoord); - half coverage = 1.; - -#ifdef @ENABLE_CLIP_RECT - if (@ENABLE_CLIP_RECT) - { - half clipRectCoverage = min_value(cast_float4_to_half4(v_clipRect)); - coverage = clamp(clipRectCoverage, make_half(.0), coverage); - } -#endif - - PLS_INTERLOCK_BEGIN; - -#ifdef @ENABLE_CLIPPING - if (@ENABLE_CLIPPING && v_clipID != .0) - { - half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); - half clipContentID = clipData.g; - half clipCoverage = - clipContentID == v_clipID ? clipData.r : make_half(.0); - coverage = min(coverage, clipCoverage); - } -#endif - - // Blend with the framebuffer color. - half4 dstColorPremul = PLS_LOAD4F(colorBuffer); -#ifdef @ENABLE_ADVANCED_BLEND - if (@ENABLE_ADVANCED_BLEND && imageDrawUniforms.blendMode != BLEND_SRC_OVER) - { - color.rgb = advanced_color_blend( - unmultiply_rgb(color), - dstColorPremul, - cast_uint_to_ushort(imageDrawUniforms.blendMode)) * - color.a; - } -#endif - color *= imageDrawUniforms.opacity * coverage; - color += dstColorPremul * (1. - color.a); - - PLS_STORE4F(colorBuffer, color); - PLS_PRESERVE_UI(clipBuffer); - PLS_PRESERVE_UI(coverageCountBuffer); - - PLS_INTERLOCK_END; - - EMIT_PLS; -} - -#else // RENDER_MODE_MSAA - -FRAG_DATA_MAIN(half4, @drawFragmentMain) -{ - VARYING_UNPACK(v_texCoord, float2); - - half4 color = - TEXTURE_SAMPLE_DYNAMIC(@imageTexture, imageSampler, v_texCoord) * - imageDrawUniforms.opacity; - -#ifdef @ENABLE_ADVANCED_BLEND - if (@ENABLE_ADVANCED_BLEND) - { - // Do the color portion of the blend mode in the shader. - half4 dstColorPremul = - TEXEL_FETCH(@dstColorTexture, int2(floor(_fragCoord.xy))); - color.rgb = advanced_color_blend(unmultiply_rgb(color), - dstColorPremul, - imageDrawUniforms.blendMode); - // Src-over blending is enabled, so just premultiply and let the HW - // finish the the the alpha portion of the blend mode. - color.rgb *= color.a; - } -#endif // !ENABLE_ADVANCED_BLEND - - EMIT_FRAG_DATA(color); -} - -#endif // RENDER_MODE_MSAA -#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_image_mesh.vert b/thirdparty/rive_renderer/source/shaders/draw_image_mesh.vert new file mode 100644 index 000000000..d29fc451c --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_image_mesh.vert @@ -0,0 +1,91 @@ +/* + * Copyright 2023 Rive + */ + +#ifdef @VERTEX +ATTR_BLOCK_BEGIN(PositionAttr) +ATTR(0, float2, @a_position); +ATTR_BLOCK_END + +ATTR_BLOCK_BEGIN(UVAttr) +ATTR(1, float2, @a_texCoord); +ATTR_BLOCK_END +#endif + +VARYING_BLOCK_BEGIN +NO_PERSPECTIVE VARYING(0, float2, v_texCoord); +#ifdef @ENABLE_CLIPPING +@OPTIONALLY_FLAT VARYING(1, half, v_clipID); +#endif +#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_MSAA) +NO_PERSPECTIVE VARYING(2, float4, v_clipRect); +#endif +VARYING_BLOCK_END + +#ifdef @VERTEX +VERTEX_TEXTURE_BLOCK_BEGIN +VERTEX_TEXTURE_BLOCK_END + +IMAGE_MESH_VERTEX_MAIN(@drawVertexMain, + PositionAttr, + position, + UVAttr, + uv, + _vertexID) +{ + ATTR_UNPACK(_vertexID, position, @a_position, float2); + ATTR_UNPACK(_vertexID, uv, @a_texCoord, float2); + + VARYING_INIT(v_texCoord, float2); +#ifdef @ENABLE_CLIPPING + VARYING_INIT(v_clipID, half); +#endif +#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_MSAA) + VARYING_INIT(v_clipRect, float4); +#endif + + float2 vertexPosition = + MUL(make_float2x2(imageDrawUniforms.viewMatrix), @a_position) + + imageDrawUniforms.translate; + v_texCoord = @a_texCoord; +#ifdef @ENABLE_CLIPPING + if (@ENABLE_CLIPPING) + { + v_clipID = id_bits_to_f16(imageDrawUniforms.clipID, + uniforms.pathIDGranularity); + } +#endif +#ifdef @ENABLE_CLIP_RECT + if (@ENABLE_CLIP_RECT) + { +#ifndef @RENDER_MODE_MSAA + v_clipRect = find_clip_rect_coverage_distances( + make_float2x2(imageDrawUniforms.clipRectInverseMatrix), + imageDrawUniforms.clipRectInverseTranslate, + vertexPosition CLIP_CONTEXT_UNPACK); +#else + set_clip_rect_plane_distances( + make_float2x2(imageDrawUniforms.clipRectInverseMatrix), + imageDrawUniforms.clipRectInverseTranslate, + vertexPosition CLIP_CONTEXT_UNPACK); +#endif + } +#endif // ENABLE_CLIP_RECT + float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); +#ifdef @POST_INVERT_Y + pos.y = -pos.y; +#endif +#ifdef @RENDER_MODE_MSAA + pos.z = normalize_z_index(imageDrawUniforms.zIndex); +#endif + + VARYING_PACK(v_texCoord); +#ifdef @ENABLE_CLIPPING + VARYING_PACK(v_clipID); +#endif +#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_MSAA) + VARYING_PACK(v_clipRect); +#endif + EMIT_VERTEX(pos); +} +#endif diff --git a/thirdparty/rive_renderer/source/shaders/draw_input_attachment.frag b/thirdparty/rive_renderer/source/shaders/draw_input_attachment.frag new file mode 100644 index 000000000..3ad62643a --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_input_attachment.frag @@ -0,0 +1,18 @@ +/* + * Copyright 2025 Rive + */ + +#ifdef @FRAGMENT +layout(input_attachment_index = 0, +#ifdef @INPUT_ATTACHMENT_BINDING + binding = @INPUT_ATTACHMENT_BINDING, +#else + binding = 0, +#endif + set = PLS_TEXTURE_BINDINGS_SET) uniform lowp subpassInput + inputAttachment; + +layout(location = 0) out half4 outputColor; + +void main() { outputColor = subpassLoad(inputAttachment); } +#endif diff --git a/thirdparty/rive_renderer/source/shaders/draw_mesh.frag b/thirdparty/rive_renderer/source/shaders/draw_mesh.frag new file mode 100644 index 000000000..85aa3981b --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_mesh.frag @@ -0,0 +1,218 @@ +/* + * Copyright 2023 Rive + */ + +#ifdef @FRAGMENT + +// This is a basic fragment shader for non-msaa, non-path objects, e.g., image +// meshes, atlas blits. +// These objects are simple in that they can write their fragments out directly, +// without having to cooperate with overlapping fragments to work out coverage. + +#if (defined(@FIXED_FUNCTION_COLOR_OUTPUT) && !defined(@ENABLE_CLIPPING)) || \ + defined(@RENDER_MODE_CLOCKWISE_ATOMIC) +// @FIXED_FUNCTION_COLOR_OUTPUT without clipping can skip the interlock. +#undef NEEDS_INTERLOCK +#else +#define NEEDS_INTERLOCK +#endif + +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC +PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer); +#endif +PLS_DECLUI(COVERAGE_PLANE_IDX, coverageBuffer); +#else // @RENDER_MODE_CLOCKWISE_ATOMIC +PLS_DECL4F(CLIP_PLANE_IDX, clipBuffer); +#endif +PLS_BLOCK_END + +// ATLAS_BLIT includes draw_path_common.glsl, which declares the textures & +// samplers, so we only need to declare these for image meshes. +#ifdef @DRAW_IMAGE_MESH +FRAG_TEXTURE_BLOCK_BEGIN +TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture); +FRAG_TEXTURE_BLOCK_END + +DYNAMIC_SAMPLER_BLOCK_BEGIN +SAMPLER_DYNAMIC_IMAGE(imageSampler) +DYNAMIC_SAMPLER_BLOCK_END + +FRAG_STORAGE_BUFFER_BLOCK_BEGIN +FRAG_STORAGE_BUFFER_BLOCK_END +#endif // @DRAW_IMAGE_MESH + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT +#ifdef @DRAW_IMAGE_MESH +PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) +#else +PLS_FRAG_COLOR_MAIN(@drawFragmentMain) +#endif +#else +#ifdef @DRAW_IMAGE_MESH +PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain) +#else +PLS_MAIN(@drawFragmentMain) +#endif +#endif +{ +#ifdef @ATLAS_BLIT + VARYING_UNPACK(v_paint, float4); + VARYING_UNPACK(v_atlasCoord, float2); +#endif +#ifdef @DRAW_IMAGE_MESH + VARYING_UNPACK(v_texCoord, float2); +#endif +#ifdef @ENABLE_CLIPPING + VARYING_UNPACK(v_clipID, half); +#endif +#ifdef @ENABLE_CLIP_RECT + VARYING_UNPACK(v_clipRect, float4); +#endif +#if defined(@ATLAS_BLIT) && defined(@ENABLE_ADVANCED_BLEND) + VARYING_UNPACK(v_blendMode, half); +#endif + +#ifdef @ATLAS_BLIT + half4 color = find_paint_color(v_paint, 1. FRAGMENT_CONTEXT_UNPACK); + half coverage = clamp( + TEXTURE_SAMPLE_LOD(@atlasTexture, atlasSampler, v_atlasCoord, .0).r, + make_half(.0), + make_half(1.)); +#endif + +#ifdef @DRAW_IMAGE_MESH + half4 color = TEXTURE_SAMPLE_DYNAMIC_LODBIAS(@imageTexture, + imageSampler, + v_texCoord, + uniforms.mipMapLODBias); + half coverage = 1.; +#endif + +#ifdef @ENABLE_CLIP_RECT + // Calculate the clip rect before entering the interlock. + if (@ENABLE_CLIP_RECT) + { + half clipRectCoverage = + max(min_component(cast_float4_to_half4(v_clipRect)), make_half(.0)); + coverage = min(clipRectCoverage, coverage); + } +#endif + +#ifdef NEEDS_INTERLOCK + PLS_INTERLOCK_BEGIN; +#endif + +#if defined(@ENABLE_CLIPPING) + if (@ENABLE_CLIPPING && v_clipID != .0) + { + half clipCoverage; +#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC + half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); + half clipContentID = clipData.g; + clipCoverage = + max(clipContentID == v_clipID ? clipData.r : make_half(.0), + make_half(.0)); +#else + clipCoverage = PLS_LOAD4F(clipBuffer).r; +#endif + clipCoverage = max(clipCoverage, make_half(.0)); + coverage = min(coverage, clipCoverage); + } +#endif + +#ifdef @DRAW_IMAGE_MESH + // Apply opacity after clipping. + coverage *= imageDrawUniforms.opacity; +#endif + +#if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) + half4 dstColorPremul = PLS_LOAD4F(colorBuffer); +#ifdef @ENABLE_ADVANCED_BLEND + if (@ENABLE_ADVANCED_BLEND) + { +#ifdef @ATLAS_BLIT + // GENERATE_PREMULTIPLIED_PAINT_COLORS is false in this case for + // find_paint_color() because advanced blend needs unmultiplied colors. + ushort blendMode = cast_half_to_ushort(v_blendMode); +#endif + +#ifdef @DRAW_IMAGE_MESH + // Unmultiply the image for advanced blend. Images are always + // premultiplied so that the filtering works correctly. + // TODO: This unmultiply technically isn't necessary with srcOver blend. + // We may want to experiment with dynamically not premultiplying here + // and in find_paint_color() when the blend mode is srcOver. + color.rgb = unmultiply_rgb(color); + ushort blendMode = cast_uint_to_ushort(imageDrawUniforms.blendMode); +#endif + + if (blendMode != BLEND_SRC_OVER) + { + color.rgb = + advanced_color_blend(color.rgb, dstColorPremul, blendMode); + } + // Premultiply alpha now. + color.a *= coverage; + color.rgb *= color.a; + } + else +#endif // @ENABLE_ADVANCED_BLEND + { + color *= coverage; + } + + // Certain platforms give us less control of the format of what we are + // rendering too. Specifically, we are auto converted from linear -> sRGB on + // render target writes in unreal. In those cases we made need to end up in + // linear color space +#ifdef @NEEDS_GAMMA_CORRECTION + if (@NEEDS_GAMMA_CORRECTION) + { + color = gamma_to_linear(color); + } +#endif + + color.rgb = add_dither(color.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); + +#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC + color = dstColorPremul * (1. - color.a) + color; +#endif + + PLS_STORE4F(colorBuffer, color); +#endif // !@FIXED_FUNCTION_COLOR_OUTPUT + +#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC + PLS_PRESERVE_UI(clipBuffer); + PLS_PRESERVE_UI(coverageBuffer); +#else + // Since blend is enabled, storing 0 to the clip will ensure it remains + // unchanged. + PLS_STORE4F(clipBuffer, make_half4(.0)); +#endif +#ifdef NEEDS_INTERLOCK + PLS_INTERLOCK_END; +#endif + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT + color = (color * coverage); + color.rgb = add_dither(color.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); + _fragColor = color; + EMIT_PLS_AND_FRAG_COLOR +#else + EMIT_PLS; +#endif +} + +#endif // @FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_msaa_object.frag b/thirdparty/rive_renderer/source/shaders/draw_msaa_object.frag new file mode 100644 index 000000000..8df178ee2 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_msaa_object.frag @@ -0,0 +1,103 @@ +/* + * Copyright 2022 Rive + */ + +#ifdef @FRAGMENT + +// Path draws include draw_path_common.glsl, which declares the textures & +// samplers, so we only need to declare these for image meshes. +#ifdef @DRAW_IMAGE_MESH +FRAG_TEXTURE_BLOCK_BEGIN +TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture); +#ifdef @ENABLE_ADVANCED_BLEND +DST_COLOR_TEXTURE(@dstColorTexture); +#endif +FRAG_TEXTURE_BLOCK_END + +DYNAMIC_SAMPLER_BLOCK_BEGIN +SAMPLER_DYNAMIC_IMAGE(imageSampler) +DYNAMIC_SAMPLER_BLOCK_END +#endif // @DRAW_IMAGE_MESH + +FRAG_DATA_MAIN(half4, @drawFragmentMain) +{ +#ifdef @DRAW_IMAGE_MESH + VARYING_UNPACK(v_texCoord, float2); +#else + VARYING_UNPACK(v_paint, float4); +#ifdef @ATLAS_BLIT + VARYING_UNPACK(v_atlasCoord, float2); +#endif // @ATLAS_BLIT +#ifdef @ENABLE_ADVANCED_BLEND + VARYING_UNPACK(v_blendMode, half); +#endif +#endif // !@DRAW_IMAGE_MESH + +#ifdef @DRAW_IMAGE_MESH + half4 color = TEXTURE_SAMPLE_DYNAMIC_LODBIAS(@imageTexture, + imageSampler, + v_texCoord, + uniforms.mipMapLODBias) * + imageDrawUniforms.opacity; +#else + half coverage = +#ifdef @ATLAS_BLIT + clamp( + TEXTURE_SAMPLE_LOD(@atlasTexture, atlasSampler, v_atlasCoord, .0).r, + make_half(.0), + make_half(1.)); +#else + 1.; +#endif + half4 color = find_paint_color(v_paint, coverage FRAGMENT_CONTEXT_UNPACK); +#endif + +// Need to check both flags here because in GL when KHR_blend_equation_advanced +// is supported, it is possible that neither is defined. +#if defined(@ENABLE_ADVANCED_BLEND) && !defined(@FIXED_FUNCTION_COLOR_OUTPUT) + // Do the color portion of the blend mode in the shader. +#ifdef @DRAW_IMAGE_MESH + color.rgb = unmultiply_rgb(color); + ushort blendMode = cast_uint_to_ushort(imageDrawUniforms.blendMode); +#else + // NOTE: for non-image-meshes, "color" is already unmultiplied because + // GENERATE_PREMULTIPLIED_PAINT_COLORS is false when using advanced + // blend. + ushort blendMode = cast_half_to_ushort(v_blendMode); +#endif + half4 dstColorPremul = DST_COLOR_FETCH(@dstColorTexture); + color.rgb = advanced_color_blend(color.rgb, dstColorPremul, blendMode); + + // Src-over blending is enabled, so just premultiply and let the HW + // finish the the the alpha portion of the blend mode. + color.rgb *= color.a; + // clang-format off +#elif defined(@SPEC_CONST_NONE) && defined(@FIXED_FUNCTION_COLOR_OUTPUT) && !defined(@DRAW_IMAGE_MESH) + // clang-format on + // in WebGPU with no specialization constants (when SPEC_CONST_NONE) is + // true), ENABLE_ADVANCED_BLEND is always set to true, so the vertex + // shader will not premultiply the color (Except with image meshes, where + // it's always premultiplied). Premultiply it now to get the correct color + // for srcOver blending. + color.rgb *= color.a; +#endif + + // Certain platforms give us less control of the format of what we are + // rendering too. Specifically, we are auto converted from linear -> sRGB on + // render target writes in unreal. In those cases we made need to end up in + // linear color space +#ifdef @NEEDS_GAMMA_CORRECTION + if (@NEEDS_GAMMA_CORRECTION) + { + color = gamma_to_linear(color); + } +#endif + + color.rgb = add_dither(color.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); + EMIT_FRAG_DATA(color); +} + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_msaa_resolve.frag b/thirdparty/rive_renderer/source/shaders/draw_msaa_resolve.frag new file mode 100644 index 000000000..c901d4e74 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_msaa_resolve.frag @@ -0,0 +1,18 @@ +/* + * Copyright 2025 Rive + */ + +#ifdef @FRAGMENT +layout(input_attachment_index = 0, + binding = COLOR_PLANE_IDX, + set = PLS_TEXTURE_BINDINGS_SET) uniform lowp subpassInputMS msaaColor; + +layout(location = 0) out half4 outputColor; + +void main() +{ + outputColor = (subpassLoad(msaaColor, 0) + subpassLoad(msaaColor, 1) + + subpassLoad(msaaColor, 2) + subpassLoad(msaaColor, 3)) * + .25; +} +#endif diff --git a/thirdparty/rive_renderer/source/shaders/draw_path.glsl b/thirdparty/rive_renderer/source/shaders/draw_path.vert similarity index 55% rename from thirdparty/rive_renderer/source/shaders/draw_path.glsl rename to thirdparty/rive_renderer/source/shaders/draw_path.vert index ab690ecf1..211c0c368 100644 --- a/thirdparty/rive_renderer/source/shaders/draw_path.glsl +++ b/thirdparty/rive_renderer/source/shaders/draw_path.vert @@ -2,7 +2,15 @@ * Copyright 2022 Rive */ -#ifdef @ENABLE_ADVANCED_BLEND +// undef GENERATE_PREMULTIPLIED_PAINT_COLORS first because this file gets +// included multiple times with different defines in the Metal library. +#undef GENERATE_PREMULTIPLIED_PAINT_COLORS + +#ifdef @NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +// The specific fragment shader we're being compiled for expects un-multiplied +// paint colors all the time. +#define GENERATE_PREMULTIPLIED_PAINT_COLORS false +#elif defined(@ENABLE_ADVANCED_BLEND) // If advanced blend is enabled, we generate unmultiplied paint colors in the // shader. Otherwise we would have to just turn around and unmultiply them in // order to run the blend equation. @@ -13,9 +21,18 @@ #define GENERATE_PREMULTIPLIED_PAINT_COLORS true #endif +// undef COVERAGE_TYPE first because this file gets included multiple times with +// different defines in the Metal library. +#undef COVERAGE_TYPE +#ifdef @ENABLE_FEATHER +#define COVERAGE_TYPE float4 +#else +#define COVERAGE_TYPE half2 +#endif + #ifdef @VERTEX ATTR_BLOCK_BEGIN(Attrs) -#ifdef @DRAW_INTERIOR_TRIANGLES +#if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT) ATTR(0, packed_float3, @a_triangleVertex); #else ATTR(0, @@ -34,29 +51,37 @@ NO_PERSPECTIVE VARYING(1, float2, v_atlasCoord); #elif !defined(@RENDER_MODE_MSAA) #ifdef @DRAW_INTERIOR_TRIANGLES @OPTIONALLY_FLAT VARYING(1, half, v_windingWeight); -#elif defined(@ENABLE_FEATHER) -NO_PERSPECTIVE VARYING(2, float4, v_coverages); #else -NO_PERSPECTIVE VARYING(2, half2, v_coverages); +NO_PERSPECTIVE VARYING(2, COVERAGE_TYPE, v_coverages); #endif //@DRAW_INTERIOR_TRIANGLES @OPTIONALLY_FLAT VARYING(3, half, v_pathID); #endif // !@RENDER_MODE_MSAA #ifdef @ENABLE_CLIPPING +#ifdef @ATLAS_BLIT +@OPTIONALLY_FLAT VARYING(4, half, v_clipID); // [clipID, outerClipID] +#else @OPTIONALLY_FLAT VARYING(4, half2, v_clipIDs); // [clipID, outerClipID] #endif -#ifdef @ENABLE_CLIP_RECT +#endif // @ENABLE_CLIPPING +#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_MSAA) NO_PERSPECTIVE VARYING(5, float4, v_clipRect); #endif #ifdef @ENABLE_ADVANCED_BLEND @OPTIONALLY_FLAT VARYING(6, half, v_blendMode); #endif + +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC +FLAT VARYING(7, uint2, v_coveragePlacement); +VARYING(8, float2, v_coverageCoord); +#endif + VARYING_BLOCK_END #ifdef @VERTEX VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) { -#ifdef @DRAW_INTERIOR_TRIANGLES +#if defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT) ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, float3); #else ATTR_UNPACK(_vertexID, attrs, @a_patchVertexData, float4); @@ -70,23 +95,29 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #elif !defined(@RENDER_MODE_MSAA) #ifdef @DRAW_INTERIOR_TRIANGLES VARYING_INIT(v_windingWeight, half); -#elif defined(@ENABLE_FEATHER) - VARYING_INIT(v_coverages, float4); #else - VARYING_INIT(v_coverages, half2); + VARYING_INIT(v_coverages, COVERAGE_TYPE); #endif //@DRAW_INTERIOR_TRIANGLES VARYING_INIT(v_pathID, half); #endif // !@RENDER_MODE_MSAA #ifdef @ENABLE_CLIPPING +#ifdef @ATLAS_BLIT + VARYING_INIT(v_clipID, half); +#else VARYING_INIT(v_clipIDs, half2); #endif -#ifdef @ENABLE_CLIP_RECT +#endif // @ENABLE_CLIPPING +#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_MSAA) VARYING_INIT(v_clipRect, float4); #endif #ifdef @ENABLE_ADVANCED_BLEND VARYING_INIT(v_blendMode, half); #endif +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC + VARYING_INIT(v_coveragePlacement, uint2); + VARYING_INIT(v_coverageCoord, float2); +#endif bool shouldDiscardVertex = false; uint pathID; @@ -163,7 +194,11 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) // buffer. if (paintType == CLIP_UPDATE_PAINT_TYPE) clipID = -clipID; +#ifdef @ATLAS_BLIT + v_clipID = clipID; +#else v_clipIDs.x = clipID; +#endif } #endif #ifdef @ENABLE_ADVANCED_BLEND @@ -194,10 +229,10 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) find_clip_rect_coverage_distances(clipRectInverseMatrix, clipRectInverseTranslate.xy, fragCoord); -#else // @RENDER_MODE_MSAA +#else // !@RENDER_MODE_MSAA => @RENDER_MODE_MSAA set_clip_rect_plane_distances(clipRectInverseMatrix, clipRectInverseTranslate.xy, - fragCoord); + fragCoord CLIP_CONTEXT_UNPACK); #endif // @RENDER_MODE_MSAA } #endif // ENABLE_CLIP_RECT @@ -210,7 +245,7 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) color.rgb *= color.a; v_paint = float4(color); } -#ifdef @ENABLE_CLIPPING +#if defined(@ENABLE_CLIPPING) && !defined(@ATLAS_BLIT) else if (@ENABLE_CLIPPING && paintType == CLIP_UPDATE_PAINT_TYPE) { half outerClipID = @@ -287,6 +322,11 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #endif #ifdef @RENDER_MODE_MSAA pos.z = normalize_z_index(pathZIndex); +#elif defined(@RENDER_MODE_CLOCKWISE_ATOMIC) + uint4 coverageData = + STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u); + v_coveragePlacement = coverageData.xy; + v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw); #endif } else @@ -303,8 +343,6 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #elif !defined(@RENDER_MODE_MSAA) #ifdef @DRAW_INTERIOR_TRIANGLES VARYING_PACK(v_windingWeight); -#elif defined(@ENABLE_FEATHER) - VARYING_PACK(v_coverages); #else VARYING_PACK(v_coverages); #endif //@DRAW_INTERIOR_TRIANGLES @@ -312,22 +350,33 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #endif // !@RENDER_MODE_MSAA #ifdef @ENABLE_CLIPPING +#ifdef @ATLAS_BLIT + VARYING_PACK(v_clipID); +#else VARYING_PACK(v_clipIDs); #endif -#ifdef @ENABLE_CLIP_RECT +#endif // @ENABLE_CLIPPING +#if defined(@ENABLE_CLIP_RECT) && !defined(@RENDER_MODE_MSAA) VARYING_PACK(v_clipRect); #endif #ifdef @ENABLE_ADVANCED_BLEND VARYING_PACK(v_blendMode); +#endif +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC + VARYING_PACK(v_coveragePlacement); + VARYING_PACK(v_coverageCoord); #endif EMIT_VERTEX(pos); } #endif #ifdef @FRAGMENT + FRAG_STORAGE_BUFFER_BLOCK_BEGIN FRAG_STORAGE_BUFFER_BLOCK_END +// Add a function here for fragments to unpack the paint since we're the ones +// who packed it in the vertex shader. INLINE half4 find_paint_color(float4 paint, float coverage FRAGMENT_CONTEXT_DECL) { @@ -381,316 +430,55 @@ INLINE half4 find_paint_color(float4 paint, return color; } -#ifndef @RENDER_MODE_MSAA - -PLS_BLOCK_BEGIN -PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); -PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); -PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer); -PLS_DECLUI(COVERAGE_PLANE_IDX, coverageCountBuffer); -PLS_BLOCK_END +#if !defined(@DRAW_INTERIOR_TRIANGLES) && !defined(@ATLAS_BLIT) -PLS_MAIN(@drawFragmentMain) +// Add functions here for fragments to unpack and evaluate coverage since we're +// the ones who packed the coverage components in the vertex shader. +INLINE half find_stroke_coverage(COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL) { - VARYING_UNPACK(v_paint, float4); - -#ifdef @ATLAS_BLIT - VARYING_UNPACK(v_atlasCoord, float2); -#elif !defined(@RENDER_MODE_MSAA) -#ifdef @DRAW_INTERIOR_TRIANGLES - VARYING_UNPACK(v_windingWeight, half); -#elif defined(@ENABLE_FEATHER) - VARYING_UNPACK(v_coverages, float4); -#else - VARYING_UNPACK(v_coverages, half2); -#endif //@DRAW_INTERIOR_TRIANGLES - VARYING_UNPACK(v_pathID, half); -#endif // !@RENDER_MODE_MSAA - -#ifdef @ENABLE_CLIPPING - VARYING_UNPACK(v_clipIDs, half2); -#endif -#ifdef @ENABLE_CLIP_RECT - VARYING_UNPACK(v_clipRect, float4); -#endif -#ifdef @ENABLE_ADVANCED_BLEND - VARYING_UNPACK(v_blendMode, half); -#endif - -#if !defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT) - // Interior triangles don't overlap, so don't need raster ordering. - PLS_INTERLOCK_BEGIN; -#endif - - half coverage; -#ifdef @ATLAS_BLIT - coverage = filter_feather_atlas( - v_atlasCoord, - uniforms.atlasTextureInverseSize TEXTURE_CONTEXT_FORWARD); -#else - half2 coverageData = unpackHalf2x16(PLS_LOADUI(coverageCountBuffer)); - half coverageBufferID = coverageData.g; - half coverageCount = - coverageBufferID == v_pathID ? coverageData.r : make_half(.0); - -#ifdef @DRAW_INTERIOR_TRIANGLES - coverageCount += v_windingWeight; - PLS_PRESERVE_UI(coverageCountBuffer); -#else - if (is_stroke(v_coverages)) - { - half fragCoverage; #ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_stroke(v_coverages)) - { - fragCoverage = - eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else + if (@ENABLE_FEATHER && is_feathered_stroke(coverages)) + return eval_feathered_stroke(coverages TEXTURE_CONTEXT_FORWARD); + else #endif // @ENABLE_FEATHER - { - fragCoverage = min(v_coverages.x, v_coverages.y); - } - coverageCount = max(fragCoverage, coverageCount); - } - else // Fill. (Back-face culling handles the sign of v_coverages.x.) - { - half fragCoverage; -#if defined(@ENABLE_FEATHER) - if (@ENABLE_FEATHER && is_feathered_fill(v_coverages)) - { - fragCoverage = - eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif // @CLOCKWISE_FILL && @ENABLE_FEATHER - { - fragCoverage = v_coverages.x; - } - coverageCount += fragCoverage; - } - - // Save the updated coverage. - PLS_STOREUI(coverageCountBuffer, - packHalf2x16(make_half2(coverageCount, v_pathID))); -#endif // !@DRAW_INTERIOR_TRIANGLES + return min(coverages.x, coverages.y); +} - // Convert coverageCount to coverage. -#ifdef @CLOCKWISE_FILL - if (@CLOCKWISE_FILL) - { -#ifdef @VULKAN_VENDOR_ID - if (@VULKAN_VENDOR_ID == VULKAN_VENDOR_ARM) - { - // ARM hits a bug if we use clamp() here. - if (coverageCount < .0) - coverage = .0; - else if (coverageCount <= 1.) - coverage = coverageCount; - else - coverage = 1.; - } - else -#endif - { - coverage = clamp(coverageCount, make_half(.0), make_half(1.)); - } - } +INLINE half find_fill_coverage(COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL) +{ +#if defined(@ENABLE_FEATHER) + if (@ENABLE_FEATHER && is_feathered_fill(coverages)) + return eval_feathered_fill(coverages TEXTURE_CONTEXT_FORWARD); else -#endif // CLOCKWISE_FILL - { - coverage = abs(coverageCount); -#ifdef @ENABLE_EVEN_ODD - if (@ENABLE_EVEN_ODD && v_pathID < .0 /*even-odd*/) - { - coverage = 1. - make_half(abs(fract(coverage * .5) * 2. + -1.)); - } -#endif - // This also caps stroke coverage, which can be >1. - coverage = min(coverage, make_half(1.)); - } -#endif // !@ATLAS_BLIT - -#ifdef @ENABLE_CLIPPING - if (@ENABLE_CLIPPING && v_clipIDs.x < .0) // Update the clip buffer. - { - half clipID = -v_clipIDs.x; -#ifdef @ENABLE_NESTED_CLIPPING - if (@ENABLE_NESTED_CLIPPING) - { - half outerClipID = v_clipIDs.y; - if (outerClipID != .0) - { - // This is a nested clip. Intersect coverage with the enclosing - // clip (outerClipID). - half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); - half clipContentID = clipData.g; - half outerClipCoverage; - if (clipContentID != clipID) - { - // First hit: either clipBuffer contains outerClipCoverage, - // or this pixel is not inside the outer clip and - // outerClipCoverage is zero. - outerClipCoverage = - clipContentID == outerClipID ? clipData.r : .0; -#ifndef @DRAW_INTERIOR_TRIANGLES - // Stash outerClipCoverage before overwriting clipBuffer, in - // case we hit this pixel again and need it. (Not necessary - // when drawing interior triangles because they always go - // last and don't overlap.) - PLS_STORE4F(scratchColorBuffer, - make_half4(outerClipCoverage, .0, .0, .0)); -#endif - } - else - { - // Subsequent hit: outerClipCoverage is stashed in - // scratchColorBuffer. - outerClipCoverage = PLS_LOAD4F(scratchColorBuffer).r; -#ifndef @DRAW_INTERIOR_TRIANGLES - // Since interior triangles are always last, there's no need - // to preserve this value. - PLS_PRESERVE_4F(scratchColorBuffer); -#endif - } - coverage = min(coverage, outerClipCoverage); - } - } -#endif // @ENABLE_NESTED_CLIPPING - PLS_STOREUI(clipBuffer, packHalf2x16(make_half2(coverage, clipID))); - PLS_PRESERVE_4F(colorBuffer); - } - else // Render to the main framebuffer. -#endif // @ENABLE_CLIPPING - { -#ifdef @ENABLE_CLIPPING - if (@ENABLE_CLIPPING) - { - // Apply the clip. - half clipID = v_clipIDs.x; - if (clipID != .0) - { - // Clip IDs are not necessarily drawn in monotonically - // increasing order, so always check exact equality of the - // clipID. - half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); - half clipContentID = clipData.g; - coverage = (clipContentID == clipID) ? min(clipData.r, coverage) - : make_half(.0); - } - } -#endif -#ifdef @ENABLE_CLIP_RECT - if (@ENABLE_CLIP_RECT) - { - half clipRectCoverage = min_value(cast_float4_to_half4(v_clipRect)); - coverage = clamp(clipRectCoverage, make_half(.0), coverage); - } -#endif // ENABLE_CLIP_RECT - - half4 color = - find_paint_color(v_paint, coverage FRAGMENT_CONTEXT_UNPACK); - - half4 dstColorPremul; -#ifdef @ATLAS_BLIT - dstColorPremul = PLS_LOAD4F(colorBuffer); -#else - if (coverageBufferID != v_pathID) - { - // This is the first fragment from pathID to touch this pixel. - dstColorPremul = PLS_LOAD4F(colorBuffer); -#ifndef @DRAW_INTERIOR_TRIANGLES - // We don't need to store coverage when drawing interior triangles - // because they always go last and don't overlap, so every fragment - // is the final one in the path. - PLS_STORE4F(scratchColorBuffer, dstColorPremul); -#endif - } - else - { - dstColorPremul = PLS_LOAD4F(scratchColorBuffer); -#ifndef @DRAW_INTERIOR_TRIANGLES - // Since interior triangles are always last, there's no need to - // preserve this value. - PLS_PRESERVE_4F(scratchColorBuffer); -#endif - } -#endif // @ATLAS_BLIT - - // Blend with the framebuffer color. -#ifdef @ENABLE_ADVANCED_BLEND - if (@ENABLE_ADVANCED_BLEND) - { - // GENERATE_PREMULTIPLIED_PAINT_COLORS is false in this case because - // advanced blend needs unmultiplied colors. - if (v_blendMode != cast_uint_to_half(BLEND_SRC_OVER)) - { - color.rgb = - advanced_color_blend(color.rgb, - dstColorPremul, - cast_half_to_ushort(v_blendMode)); - } - // Premultiply alpha now. - color.rgb *= color.a; - } -#endif - color += dstColorPremul * (1. - color.a); - - PLS_STORE4F(colorBuffer, color); - PLS_PRESERVE_UI(clipBuffer); - } - -#if !defined(@DRAW_INTERIOR_TRIANGLES) || defined(@ATLAS_BLIT) - // Interior triangles don't overlap, so don't need raster ordering. - PLS_INTERLOCK_END; -#endif - - EMIT_PLS; +#endif // @ENABLE_FEATHER + return coverages.x; } -#else // @RENDER_MODE_MSAA - -FRAG_DATA_MAIN(half4, @drawFragmentMain) +INLINE half find_frag_coverage(COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL) { - VARYING_UNPACK(v_paint, float4); -#ifdef @ATLAS_BLIT - VARYING_UNPACK(v_atlasCoord, float2); -#endif -#ifdef @ENABLE_ADVANCED_BLEND - VARYING_UNPACK(v_blendMode, half); -#endif - - half coverage = -#ifdef @ATLAS_BLIT - filter_feather_atlas( - v_atlasCoord, - uniforms.atlasTextureInverseSize TEXTURE_CONTEXT_FORWARD); -#else - 1.; -#endif - half4 color = find_paint_color(v_paint, coverage FRAGMENT_CONTEXT_UNPACK); + if (is_stroke(coverages)) + return find_stroke_coverage(coverages TEXTURE_CONTEXT_FORWARD); + else // Fill. (Back-face culling handles the sign of coverages.x.) + return find_fill_coverage(coverages TEXTURE_CONTEXT_FORWARD); +} -#ifdef @ENABLE_ADVANCED_BLEND - if (@ENABLE_ADVANCED_BLEND) +INLINE half apply_frag_coverage(half initialCoverage, + COVERAGE_TYPE coverages TEXTURE_CONTEXT_DECL) +{ + if (is_stroke(coverages)) + { + half fragCoverage = + find_stroke_coverage(coverages TEXTURE_CONTEXT_FORWARD); + return max(fragCoverage, initialCoverage); + } + else // Fill. (Back-face culling handles the sign of coverages.x.) { - // Do the color portion of the blend mode in the shader. - // - // NOTE: "color" is already unmultiplied because - // GENERATE_PREMULTIPLIED_PAINT_COLORS is false when using advanced - // blend. - half4 dstColorPremul = - TEXEL_FETCH(@dstColorTexture, int2(floor(_fragCoord.xy))); - color.rgb = advanced_color_blend(color.rgb, - dstColorPremul, - cast_half_to_ushort(v_blendMode)); - // Src-over blending is enabled, so just premultiply and let the HW - // finish the the the alpha portion of the blend mode. - color.rgb *= color.a; + half fragCoverage = + find_fill_coverage(coverages TEXTURE_CONTEXT_FORWARD); + return initialCoverage + fragCoverage; } -#endif // ENABLE_ADVANCED_BLEND - EMIT_FRAG_DATA(color); } -#endif // !RENDER_MODE_MSAA +#endif // !@DRAW_INTERIOR_TRIANGLES && !@ATLAS_BLIT -#endif // FRAGMENT +#endif // @FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/draw_path_common.glsl b/thirdparty/rive_renderer/source/shaders/draw_path_common.glsl index 729d6c53d..3ea093948 100644 --- a/thirdparty/rive_renderer/source/shaders/draw_path_common.glsl +++ b/thirdparty/rive_renderer/source/shaders/draw_path_common.glsl @@ -57,11 +57,14 @@ TEXTURE_R16F_1D_ARRAY(PER_FLUSH_BINDINGS_SET, @featherTexture); #endif #ifdef @ATLAS_BLIT -TEXTURE_R16F(PER_DRAW_BINDINGS_SET, ATLAS_TEXTURE_IDX, @atlasTexture); +TEXTURE_R16F(PER_FLUSH_BINDINGS_SET, ATLAS_TEXTURE_IDX, @atlasTexture); #endif TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture); -#if defined(@RENDER_MODE_MSAA) && defined(@ENABLE_ADVANCED_BLEND) -TEXTURE_RGBA8(PER_FLUSH_BINDINGS_SET, DST_COLOR_TEXTURE_IDX, @dstColorTexture); +// The Qualcomm compiler can't handle line breaks in #ifs. +// clang-format off +#if defined(@RENDER_MODE_MSAA) && defined(@ENABLE_ADVANCED_BLEND) && !defined(@FIXED_FUNCTION_COLOR_OUTPUT) +// clang-format on +DST_COLOR_TEXTURE(@dstColorTexture); #endif FRAG_TEXTURE_BLOCK_END @@ -72,7 +75,7 @@ SAMPLER_LINEAR(GRAD_TEXTURE_IDX, gradSampler) SAMPLER_LINEAR(ATLAS_TEXTURE_IDX, atlasSampler) #endif DYNAMIC_SAMPLER_BLOCK_BEGIN -SAMPLER_DYNAMIC(IMAGE_SAMPLER_IDX, imageSampler) +SAMPLER_DYNAMIC_IMAGE(imageSampler) DYNAMIC_SAMPLER_BLOCK_END #endif // @FRAGMENT @@ -253,38 +256,6 @@ INLINE half eval_feathered_stroke(float4 coverages TEXTURE_CONTEXT_DECL) } #endif // @ENABLE_FEATHER -#if defined(@FRAGMENT) && defined(@ATLAS_BLIT) -// Upscales a pre-rendered feather from the atlas, converting from gaussian -// space to linear before doing a bilerp. -INLINE half -filter_feather_atlas(float2 atlasCoord, - float2 atlasTextureInverseSize TEXTURE_CONTEXT_DECL) -{ - // Gather the quad of pixels we need to filter. - // Gather from the exact center of the quad to make sure there are no - // rounding differences between us and the texture unit. - float2 atlasQuadCenter = round(atlasCoord); - half4 coverages = TEXTURE_GATHER(@atlasTexture, - atlasSampler, - atlasQuadCenter, - atlasTextureInverseSize); - // Convert each pixel from gaussian space back to linear. - coverages = make_half4(INVERSE_FEATHER(coverages.x), - INVERSE_FEATHER(coverages.y), - INVERSE_FEATHER(coverages.z), - INVERSE_FEATHER(coverages.w)); - // Bilerp in linear space. - coverages.xw = mix(coverages.xw, - coverages.yz, - make_half(atlasCoord.x + .5 - atlasQuadCenter.x)); - coverages.x = mix(coverages.w, - coverages.x, - make_half(atlasCoord.y + .5 - atlasQuadCenter.y)); - // Go back to gaussian now that the bilerp is finished. - return FEATHER(coverages.x); -} -#endif // @FRAGMENT && @ATLAS_BLIT - #if defined(@VERTEX) && defined(@DRAW_PATH) INLINE int2 tess_texel_coord(int texelIndex) { @@ -328,9 +299,11 @@ INLINE bool unpack_tessellated_path_vertex(float4 patchVertexData, uint contourIDWithFlags = TESSDATA_AS_UINT(tessVertexData.w); // Fetch and unpack the contour referenced by the tessellation vertex. - uint4 contourData = - STORAGE_BUFFER_LOAD4(@contourBuffer, - contour_data_idx(contourIDWithFlags)); + // NOTE: The contourID is guaranteed to be >= 1 at this point, but clamp it + // anyway because in the event of a bug, a buffer load at index "0u - 1" can + // be very serious and hard to catch. + uint contourID = max(contourIDWithFlags & CONTOUR_ID_MASK, 1u); + uint4 contourData = STORAGE_BUFFER_LOAD4(@contourBuffer, contourID - 1u); float2 midpoint = uintBitsToFloat(contourData.xy); outPathID = contourData.z & 0xffffu; uint vertexIndex0 = contourData.w; @@ -776,7 +749,11 @@ INLINE bool unpack_tessellated_path_vertex(float4 patchVertexData, if (bool(contourIDWithFlags & MIRRORED_CONTOUR_CONTOUR_FLAG) != bool(contourIDWithFlags & NEGATE_PATH_FILL_COVERAGE_FLAG)) { - outCoverages.x = -outCoverages.x; + // Effectively: outCoverages.x = -outCoverages.x + // + // ... But don't write that because it hits a bug in the Mali T720 + // compiler that also negates Y. + outCoverages *= float4(-1., +1., +1., +1.); } #endif // !RENDER_MODE_MSAA @@ -858,7 +835,75 @@ unpack_atlas_coverage_vertex(float3 triangleVertex, // outAtlasCoord tells the fragment shader where to fetch coverage from the // atlas, when using atlas coverage. float3 atlasTransform = uintBitsToFloat(pathData2.yzw); - outAtlasCoord = vertexPos * atlasTransform.x + atlasTransform.yz; + outAtlasCoord = (vertexPos * atlasTransform.x + atlasTransform.yz) * + uniforms.atlasTextureInverseSize; return vertexPos; } #endif // @VERTEX && @ATLAS_BLIT + +// Calculates a coverage value to multiply into the paintColor that will +// convert the current framebuffer value from "paint blended on top with +// coverage of c0" to "paint blended on top with coverage of c1". +// +// i.e., The paint has already been blended into the framebuffer with coverage +// "c0". After this fragment blends, it will be equivalent to the paint having +// been blended into the framebuffer with coverage "c1". +// +// NOTE: c1 must be > c0, which is why this is only applicable in clockwise +// modes. +INLINE half incremental_clockwise_coverage(half c0, half c1, half paintAlpha) +{ + // NOTE: "max(, eps)" is just to avoid a divide by zero. When the + // denominator would be 0, c0 == 1, which also means c1 == 1, and there is + // no coverage to apply. Since c0 == c1 == 1, (c1 - c0) / eps == 0, which is + // the result we want in this case. + return (c1 - c0) / max(1. - c0 * paintAlpha, EPSILON_FP16_NON_DENORM); +} + +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC + +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT +#define CLOCKWISE_ATOMIC_PLS_MAIN PLS_FRAG_COLOR_MAIN +#define EMIT_CLOCKWISE_ATOMIC_PLS(FRAG_COLOR) \ + _fragColor = FRAG_COLOR; \ + EMIT_PLS_AND_FRAG_COLOR +#else +#define CLOCKWISE_ATOMIC_PLS_MAIN PLS_MAIN +#define EMIT_CLOCKWISE_ATOMIC_PLS(FRAG_COLOR) \ + PLS_STORE4F(colorBuffer, FRAG_COLOR); \ + EMIT_PLS; +#endif + +// Converts an x,y image coordinate into a buffer index, swizzling into 32x32 +// tiles for better cache performance. +// imageWidth must be a multiple of 32. +INLINE uint swizzle_buffer_idx_32x32(uint2 imageCoord, uint imageWidth) +{ + uint idx = (imageCoord.y >> 5u) * (imageWidth << 5u) + + (imageCoord.x >> 5u) * (32u << 5u); + // Subdivide each main tile into 4x4 column-major tiles. + idx += ((imageCoord.x & 0x1fu) >> 2u) * (32u << 2u) + + ((imageCoord.y & 0x1fu) >> 2u) * (4u << 2u); + // Let the 4x4 tiles be row-major. + idx += (imageCoord.y & 0x3u) * 4u + (imageCoord.x & 0x3u); + return idx; +} + +// Extracts coverage from its fixed-point encoding in a coverage buffer value. +INLINE half clockwise_atomic_fixed_to_coverage(uint coverageFixed) +{ + return cast_int_to_half(int((coverageFixed & CLOCKWISE_COVERAGE_MASK) - + CLOCKWISE_FILL_ZERO_VALUE)) * + CLOCKWISE_COVERAGE_INVERSE_PRECISION; +} + +// Converts a coverage to a fixed point delta that may be added to a coverage +// buffer value. +// NOTE: This is not the same as converting it to a plain coverage value, since +// those must be biased by CLOCKWISE_FILL_ZERO_VALUE. +INLINE uint clockwise_atomic_coverage_delta_to_fixed(half coverage) +{ + return uint(coverage * CLOCKWISE_COVERAGE_PRECISION + .5); +} + +#endif // @RENDER_MODE_CLOCKWISE_ATOMIC diff --git a/thirdparty/rive_renderer/source/shaders/draw_raster_order_path.frag b/thirdparty/rive_renderer/source/shaders/draw_raster_order_path.frag new file mode 100644 index 000000000..ebef5ca35 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/draw_raster_order_path.frag @@ -0,0 +1,232 @@ +/* + * Copyright 2022 Rive + */ + +#ifdef @FRAGMENT + +PLS_BLOCK_BEGIN +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer); +PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer); +PLS_DECLUI(COVERAGE_PLANE_IDX, coverageCountBuffer); +PLS_BLOCK_END + +PLS_MAIN(@drawFragmentMain) +{ + VARYING_UNPACK(v_paint, float4); + +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_windingWeight, half); +#else + VARYING_UNPACK(v_coverages, COVERAGE_TYPE); +#endif //@DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_pathID, half); + +#ifdef @ENABLE_CLIPPING + VARYING_UNPACK(v_clipIDs, half2); +#endif +#ifdef @ENABLE_CLIP_RECT + VARYING_UNPACK(v_clipRect, float4); +#endif +#ifdef @ENABLE_ADVANCED_BLEND + VARYING_UNPACK(v_blendMode, half); +#endif + +#if !defined(@DRAW_INTERIOR_TRIANGLES) + // Interior triangles don't overlap, so don't need raster ordering. + PLS_INTERLOCK_BEGIN; +#endif + + half2 coverageData = unpackHalf2x16(PLS_LOADUI(coverageCountBuffer)); + half coverageBufferID = coverageData.g; + half coverageCount = + coverageBufferID == v_pathID ? coverageData.r : make_half(.0); + +#ifdef @DRAW_INTERIOR_TRIANGLES + coverageCount += v_windingWeight; + // Preserve the coverage buffer even though we don't use it, so it doesn't + // get overwritten in a way that would corrupt a future draw (e.g., by + // accidentally writing the next path's id with a bogus coverage.) + PLS_PRESERVE_UI(coverageCountBuffer); +#else + coverageCount = + apply_frag_coverage(coverageCount, v_coverages TEXTURE_CONTEXT_FORWARD); + // Save the updated coverage. + PLS_STOREUI(coverageCountBuffer, + packHalf2x16(make_half2(coverageCount, v_pathID))); +#endif // !@DRAW_INTERIOR_TRIANGLES + + // Convert coverageCount to coverage. + half coverage; +#ifdef @CLOCKWISE_FILL + if (@CLOCKWISE_FILL) + { + coverage = + safe_clamp_for_mali(coverageCount, make_half(.0), make_half(1.)); + } + else +#endif // CLOCKWISE_FILL + { + coverage = abs(coverageCount); +#ifdef @ENABLE_EVEN_ODD + if (@ENABLE_EVEN_ODD && v_pathID < .0 /*even-odd*/) + { + coverage = 1. - make_half(abs(fract(coverage * .5) * 2. + -1.)); + } +#endif + // This also caps stroke coverage, which can be >1. + coverage = min(coverage, make_half(1.)); + } + +#ifdef @ENABLE_CLIPPING + if (@ENABLE_CLIPPING && v_clipIDs.x < .0) // Update the clip buffer. + { + half clipID = -v_clipIDs.x; +#ifdef @ENABLE_NESTED_CLIPPING + if (@ENABLE_NESTED_CLIPPING) + { + half outerClipID = v_clipIDs.y; + if (outerClipID != .0) + { + // This is a nested clip. Intersect coverage with the enclosing + // clip (outerClipID). + half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); + half clipContentID = clipData.g; + half outerClipCoverage; + if (clipContentID != clipID) + { + // First hit: either clipBuffer contains outerClipCoverage, + // or this pixel is not inside the outer clip and + // outerClipCoverage is zero. + outerClipCoverage = + clipContentID == outerClipID ? clipData.r : .0; +#ifndef @DRAW_INTERIOR_TRIANGLES + // Stash outerClipCoverage before overwriting clipBuffer, in + // case we hit this pixel again and need it. (Not necessary + // when drawing interior triangles because they always go + // last and don't overlap.) + PLS_STORE4F(scratchColorBuffer, + make_half4(outerClipCoverage, .0, .0, .0)); +#endif + } + else + { + // Subsequent hit: outerClipCoverage is stashed in + // scratchColorBuffer. + outerClipCoverage = PLS_LOAD4F(scratchColorBuffer).r; +#ifndef @DRAW_INTERIOR_TRIANGLES + // Since interior triangles are always last, there's no need + // to preserve this value. + PLS_PRESERVE_4F(scratchColorBuffer); +#endif + } + coverage = min(coverage, outerClipCoverage); + } + } +#endif // @ENABLE_NESTED_CLIPPING + PLS_STOREUI(clipBuffer, packHalf2x16(make_half2(coverage, clipID))); + PLS_PRESERVE_4F(colorBuffer); + } + else // Render to the main framebuffer. +#endif // @ENABLE_CLIPPING + { +#ifdef @ENABLE_CLIPPING + if (@ENABLE_CLIPPING) + { + // Apply the clip. + half clipID = v_clipIDs.x; + if (clipID != .0) + { + // Clip IDs are not necessarily drawn in monotonically + // increasing order, so always check exact equality of the + // clipID. + half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); + half clipContentID = clipData.g; + coverage = (clipContentID == clipID) ? min(clipData.r, coverage) + : make_half(.0); + } + } +#endif +#ifdef @ENABLE_CLIP_RECT + if (@ENABLE_CLIP_RECT) + { + half clipRectCoverage = + min_component(cast_float4_to_half4(v_clipRect)); + coverage = clamp(clipRectCoverage, make_half(.0), coverage); + } +#endif // ENABLE_CLIP_RECT + + half4 color = + find_paint_color(v_paint, coverage FRAGMENT_CONTEXT_UNPACK); + + half4 dstColorPremul; + if (coverageBufferID != v_pathID) + { + // This is the first fragment from pathID to touch this pixel. + dstColorPremul = PLS_LOAD4F(colorBuffer); +#ifndef @DRAW_INTERIOR_TRIANGLES + // We don't need to store coverage when drawing interior triangles + // because they always go last and don't overlap, so every fragment + // is the final one in the path. + PLS_STORE4F(scratchColorBuffer, dstColorPremul); +#endif + } + else + { + dstColorPremul = PLS_LOAD4F(scratchColorBuffer); +#ifndef @DRAW_INTERIOR_TRIANGLES + // Since interior triangles are always last, there's no need to + // preserve this value. + PLS_PRESERVE_4F(scratchColorBuffer); +#endif + } + + // Blend with the framebuffer color. +#ifdef @ENABLE_ADVANCED_BLEND + if (@ENABLE_ADVANCED_BLEND) + { + // GENERATE_PREMULTIPLIED_PAINT_COLORS is false in this case because + // advanced blend needs unmultiplied colors. + if (v_blendMode != cast_uint_to_half(BLEND_SRC_OVER)) + { + color.rgb = + advanced_color_blend(color.rgb, + dstColorPremul, + cast_half_to_ushort(v_blendMode)); + } + // Premultiply alpha now. + color.rgb *= color.a; + } +#endif + + // Certain platforms give us less control of the format of what we are + // rendering too. Specifically, we are auto converted from linear -> + // sRGB on render target writes in unreal. In those cases we made need + // to end up in linear color space +#ifdef @NEEDS_GAMMA_CORRECTION + if (@NEEDS_GAMMA_CORRECTION) + { + color = gamma_to_linear(color); + } +#endif + + color += dstColorPremul * (1. - color.a); + + color.rgb = add_dither(color.rgb, + _fragCoord.xy, + uniforms.ditherScale, + uniforms.ditherBias); + + PLS_STORE4F(colorBuffer, color); + PLS_PRESERVE_UI(clipBuffer); + } + +#if !defined(@DRAW_INTERIOR_TRIANGLES) + // Interior triangles don't overlap, so don't need raster ordering. + PLS_INTERLOCK_END; +#endif + + EMIT_PLS; +} + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/flush_uniforms.glsl b/thirdparty/rive_renderer/source/shaders/flush_uniforms.glsl new file mode 100644 index 000000000..75c260fea --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/flush_uniforms.glsl @@ -0,0 +1,58 @@ +#ifndef DECLARE_UNIFORM_FLOAT +#define DECLARE_UNIFORM_FLOAT(UNIFORM_NAME) float UNIFORM_NAME; +#endif +#ifndef DECLARE_UNIFORM_UINT +#define DECLARE_UNIFORM_UINT(UNIFORM_NAME) uint UNIFORM_NAME; +#endif +#ifndef DECLARE_UNIFORM_INT4 +#define DECLARE_UNIFORM_INT4(UNIFORM_NAME) int4 UNIFORM_NAME; +#endif +#ifndef DECLARE_UNIFORM_FLOAT2 +#define DECLARE_UNIFORM_FLOAT2(UNIFORM_NAME) float2 UNIFORM_NAME; +#endif +#ifndef DECLARE_UNIFORM_FLOAT4 +#define DECLARE_UNIFORM_FLOAT4(UNIFORM_NAME) float4 UNIFORM_NAME; +#endif + +#ifndef FLUSH_UNIFORMS_NAME +#define FLUSH_UNIFORMS_NAME @FlushUniforms +#endif + +UNIFORM_BLOCK_BEGIN(FLUSH_UNIFORM_BUFFER_IDX, FLUSH_UNIFORMS_NAME) +DECLARE_UNIFORM_FLOAT(gradInverseViewportY) +DECLARE_UNIFORM_FLOAT(tessInverseViewportY) +DECLARE_UNIFORM_FLOAT(renderTargetInverseViewportX) +DECLARE_UNIFORM_FLOAT(renderTargetInverseViewportY) +DECLARE_UNIFORM_UINT(renderTargetWidth) +DECLARE_UNIFORM_UINT(renderTargetHeight) +// Only used if clears are implemented as draws. +DECLARE_UNIFORM_UINT(colorClearValue) +// Only used if clears are implemented as draws. +DECLARE_UNIFORM_UINT(coverageClearValue) +// drawBounds, or renderTargetBounds if there is a clear. (LTRB.) +DECLARE_UNIFORM_INT4(renderTargetUpdateBounds) +// 1 / [atlasWidth, atlasHeight] +DECLARE_UNIFORM_FLOAT2(atlasTextureInverseSize) +// 2 / atlasContentBounds +DECLARE_UNIFORM_FLOAT2(atlasContentInverseViewport) +DECLARE_UNIFORM_UINT(coverageBufferPrefix) +// GLSL doesn't appear to provide a lightweight, region-local barrier for memory +// ordering outside of memoryBarrier*(), which have severe consequences for +// tiling. When we are already relying on other API level barriers and only need +// to guard against instruction reordering, we can multiply by a tiny epsilon +// instead, and introduce artifical dependencies that enforce ordering but don't +// actually have an effect on the final outcome. +DECLARE_UNIFORM_FLOAT(epsilonForPseudoMemoryBarrier) +// Spacing between adjacent path IDs (1 if IEEE compliant). +DECLARE_UNIFORM_UINT(pathIDGranularity) +DECLARE_UNIFORM_FLOAT(vertexDiscardValue) +DECLARE_UNIFORM_FLOAT(mipMapLODBias) +DECLARE_UNIFORM_UINT(maxPathId) +DECLARE_UNIFORM_FLOAT(ditherScale) +DECLARE_UNIFORM_FLOAT(ditherBias) +// Amount by which to multiply a computed dither value when storing as RGB10 (as +// opposed to writing it out to the framebuffer). +DECLARE_UNIFORM_FLOAT(ditherConversionToRGB10) +// Debugging. +DECLARE_UNIFORM_UINT(wireframeEnabled) +UNIFORM_BLOCK_END(uniforms) \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/glsl.glsl b/thirdparty/rive_renderer/source/shaders/glsl.glsl index 9baebc7db..0de50e8c9 100644 --- a/thirdparty/rive_renderer/source/shaders/glsl.glsl +++ b/thirdparty/rive_renderer/source/shaders/glsl.glsl @@ -24,6 +24,7 @@ #define half4 mediump vec4 #define half3x3 mediump mat3x3 #define half2x3 mediump mat2x3 +#define half4x4 mediump mat4x4 #define int2 ivec2 #define int3 ivec3 @@ -61,15 +62,33 @@ #extension GL_KHR_blend_equation_advanced : require #endif +// Enable the necessary extensions for rendering the feather atlas. +// NOTE: We do this here instead of render_atlas.glsl because extensions have to +// be declared before any code. +#ifdef @ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH +#extension GL_EXT_shader_framebuffer_fetch : require +#elif defined(@ATLAS_RENDER_TARGET_R8_PLS_EXT) +#extension GL_EXT_shader_pixel_local_storage : require +#elif defined(@ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) +#extension GL_ANGLE_shader_pixel_local_storage : require +#elif defined(@ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE) +#ifdef GL_ARB_shader_image_load_store +#extension GL_ARB_shader_image_load_store : require +#endif +#ifdef GL_OES_shader_image_atomic +#extension GL_OES_shader_image_atomic : require +#endif +#endif + // clang-format off -#if defined(@RENDER_MODE_MSAA) && defined(@ENABLE_CLIP_RECT) && defined(GL_ES) -// clang-format on +#if defined(@RENDER_MODE_MSAA) && defined(@ENABLE_CLIP_RECT) && defined(GL_ES) && !defined(@DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS) #ifdef GL_EXT_clip_cull_distance #extension GL_EXT_clip_cull_distance : require #elif defined(GL_ANGLE_clip_cull_distance) #extension GL_ANGLE_clip_cull_distance : require #endif -#endif // RENDER_MODE_MSAA && ENABLE_CLIP_RECT +#endif // RENDER_MODE_MSAA && ENABLE_CLIP_RECT && GL_ES && !DISABLE_CLIP_DISTANCE_FOR_UBERSHADERS +// clang-format on #if @GLSL_VERSION >= 310 #define UNIFORM_BLOCK_BEGIN(IDX, NAME) \ @@ -110,7 +129,7 @@ #define VARYING_BLOCK_END // clang-format off -#ifdef @TARGET_VULKAN +#ifdef @TARGET_SPIRV // Since Vulkan is compiled offline and not all platforms support noperspective, don't use it. # define NO_PERSPECTIVE #else @@ -136,7 +155,7 @@ #define DYNAMIC_SAMPLER_BLOCK_BEGIN #define DYNAMIC_SAMPLER_BLOCK_END -#ifdef @TARGET_VULKAN +#ifdef @TARGET_SPIRV #define TEXTURE_RGBA32UI(SET, IDX, NAME) \ layout(set = SET, binding = IDX) uniform highp utexture2D NAME #define TEXTURE_RGBA32F(SET, IDX, NAME) \ @@ -145,6 +164,12 @@ layout(set = SET, binding = IDX) uniform mediump texture2D NAME #define TEXTURE_R16F(SET, IDX, NAME) \ layout(binding = IDX) uniform mediump texture2D NAME +#define TEXTURE_R32I(SET, IDX, NAME) \ + layout(binding = IDX) uniform highp itexture2D NAME +#define TEXTURE_R32UI(SET, IDX, NAME) \ + layout(binding = IDX) uniform highp utexture2D NAME +#if defined(@FRAGMENT) && defined(@RENDER_MODE_MSAA) +#endif // @FRAGMENT && @RENDER_MODE_MSAA #elif @GLSL_VERSION >= 310 #define TEXTURE_RGBA32UI(SET, IDX, NAME) \ layout(binding = IDX) uniform highp usampler2D NAME @@ -154,46 +179,71 @@ layout(binding = IDX) uniform mediump sampler2D NAME #define TEXTURE_R16F(SET, IDX, NAME) \ layout(binding = IDX) uniform mediump sampler2D NAME +#define TEXTURE_R32I(SET, IDX, NAME) \ + layout(binding = IDX) uniform highp isampler2D NAME +#define TEXTURE_R32UI(SET, IDX, NAME) \ + layout(binding = IDX) uniform highp usampler2D NAME #else #define TEXTURE_RGBA32UI(SET, IDX, NAME) uniform highp usampler2D NAME #define TEXTURE_RGBA32F(SET, IDX, NAME) uniform highp sampler2D NAME #define TEXTURE_RGBA8(SET, IDX, NAME) uniform mediump sampler2D NAME #define TEXTURE_R16F(SET, IDX, NAME) uniform mediump sampler2D NAME +#define TEXTURE_R32I(SET, IDX, NAME) uniform highp isampler2D NAME +#define TEXTURE_R32UI(SET, IDX, NAME) uniform highp usampler2D NAME #endif -#ifdef @TARGET_VULKAN +#ifdef @TARGET_SPIRV + +#define SAMPLER_DYNAMIC(SET, IDX, NAME) \ + layout(set = SET, binding = IDX) uniform mediump sampler NAME; + +#ifdef @USE_WEBGPU_SAMPLERS #define SAMPLER_LINEAR(TEXTURE_IDX, NAME) \ - layout(set = IMMUTABLE_SAMPLER_BINDINGS_SET, binding = TEXTURE_IDX) \ + layout(set = WEBGPU_SAMPLER_BINDINGS_SET, binding = TEXTURE_IDX) \ uniform mediump sampler NAME; -#define SAMPLER_MIPMAP(TEXTURE_IDX, NAME) \ - layout(set = IMMUTABLE_SAMPLER_BINDINGS_SET, binding = TEXTURE_IDX) \ - uniform mediump sampler NAME; -#define SAMPLER_DYNAMIC(TEXTURE_IDX, NAME) \ - layout(set = PER_DRAW_BINDINGS_SET, binding = TEXTURE_IDX) \ +#define SAMPLER_DYNAMIC_IMAGE(NAME) \ + SAMPLER_DYNAMIC(PER_DRAW_BINDINGS_SET, WEBGPU_IMAGE_SAMPLER_IDX, NAME) +#else +#define SAMPLER_LINEAR(TEXTURE_IDX, NAME) \ + layout(set = PER_FLUSH_BINDINGS_SET, binding = TEXTURE_IDX) \ uniform mediump sampler NAME; +#define SAMPLER_DYNAMIC_IMAGE(NAME) \ + SAMPLER_DYNAMIC(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, NAME) +#endif #define TEXTURE_SAMPLE(NAME, SAMPLER_NAME, COORD) \ texture(sampler2D(NAME, SAMPLER_NAME), COORD) #define TEXTURE_SAMPLE_LOD(NAME, SAMPLER_NAME, COORD, LOD) \ textureLod(sampler2D(NAME, SAMPLER_NAME), COORD, LOD) +#define TEXTURE_SAMPLE_LODBIAS(NAME, SAMPLER_NAME, COORD, LODBIAS) \ + texture(sampler2D(NAME, SAMPLER_NAME), COORD, LODBIAS) #define TEXTURE_SAMPLE_GRAD(NAME, SAMPLER_NAME, COORD, DDX, DDY) \ textureGrad(sampler2D(NAME, SAMPLER_NAME), COORD, DDX, DDY) -#else -// SAMPLER_LINEAR and SAMPLER_MIPMAP are no-ops because in GL, sampling -// parameters are API-level state tied to the texture. +#if defined(@FRAGMENT) && defined(@RENDER_MODE_MSAA) +#extension GL_OES_sample_variables : require +#endif // @FRAGMENT && @RENDER_MODE_MSAA + +#else // @TARGET_SPIRV -> !@TARGET_SPIRV + +// SAMPLER_LINEAR is a no-op because in GL, sampling parameters are API-level +// state tied to the texture. #define SAMPLER_LINEAR(TEXTURE_IDX, NAME) -#define SAMPLER_MIPMAP(TEXTURE_IDX, NAME) -#define SAMPLER_DYNAMIC(TEXTURE_IDX, NAME) +#define SAMPLER_DYNAMIC(SET, IDX, NAME) +#define SAMPLER_DYNAMIC_IMAGE(NAME) #define TEXTURE_SAMPLE(NAME, SAMPLER_NAME, COORD) texture(NAME, COORD) #define TEXTURE_SAMPLE_LOD(NAME, SAMPLER_NAME, COORD, LOD) \ textureLod(NAME, COORD, LOD) +#define TEXTURE_SAMPLE_LODBIAS(NAME, SAMPLER_NAME, COORD, LODBIAS) \ + texture(NAME, COORD, LODBIAS) #define TEXTURE_SAMPLE_GRAD(NAME, SAMPLER_NAME, COORD, DDX, DDY) \ textureGrad(NAME, COORD, DDX, DDY) -#endif // !@TARGET_VULKAN +#endif // !@TARGET_SPIRV #define TEXTURE_SAMPLE_DYNAMIC(TEXTURE, SAMPLER_NAME, COORD) \ TEXTURE_SAMPLE(TEXTURE, SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_DYNAMIC_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) \ TEXTURE_SAMPLE_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) +#define TEXTURE_SAMPLE_DYNAMIC_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) \ + TEXTURE_SAMPLE_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) // Polyfill the feather texture as a sampler2D since ES doesn't support // sampler1DArray. This is why the macro needs "ARRAY_INDEX_NORMALIZED": when @@ -213,7 +263,7 @@ #define TEXTURE_CONTEXT_FORWARD #define TEXEL_FETCH(NAME, COORD) texelFetch(NAME, COORD, 0) -#ifdef @TARGET_VULKAN +#ifdef @TARGET_SPIRV #define TEXTURE_GATHER(NAME, SAMPLER_NAME, COORD, TEXTURE_INVERSE_SIZE) \ textureGather(sampler2D(NAME, SAMPLER_NAME), \ (COORD) * (TEXTURE_INVERSE_SIZE)) @@ -222,10 +272,7 @@ textureGather(NAME, (COORD) * (TEXTURE_INVERSE_SIZE)) #else #define TEXTURE_GATHER(NAME, SAMPLER_NAME, COORD, TEXTURE_INVERSE_SIZE) \ - make_half4(TEXEL_FETCH(NAME, int2(COORD) + int2(-1, 0)).r, \ - TEXEL_FETCH(NAME, int2(COORD) + int2(0, 0)).r, \ - TEXEL_FETCH(NAME, int2(COORD) + int2(0, -1)).r, \ - TEXEL_FETCH(NAME, int2(COORD) + int2(-1, -1)).r) + TEXTURE_GATHER_MATRIX(NAME, COORD, .r) #endif #define VERTEX_STORAGE_BUFFER_BLOCK_BEGIN @@ -283,6 +330,7 @@ #define STORAGE_BUFFER_LOAD(NAME, I) NAME._values[I] #define STORAGE_BUFFER_ATOMIC_MAX(NAME, I, X) atomicMax(NAME._values[I], X) #define STORAGE_BUFFER_ATOMIC_ADD(NAME, I, X) atomicAdd(NAME._values[I], X) +#define STORAGE_BUFFER_ATOMIC_OR(NAME, I, X) atomicOr(NAME._values[I], X) #endif // DISABLE_SHADER_STORAGE_BUFFERS @@ -294,7 +342,7 @@ #define PLS_BLOCK_BEGIN #define PLS_DECL4F(IDX, NAME) \ - layout(binding = IDX, rgba8) uniform lowp pixelLocalANGLE NAME + layout(binding = IDX, rgba8) uniform mediump pixelLocalANGLE NAME #define PLS_DECLUI(IDX, NAME) \ layout(binding = IDX, r32ui) uniform highp upixelLocalANGLE NAME #define PLS_BLOCK_END @@ -314,12 +362,19 @@ #ifdef @PLS_IMPL_EXT_NATIVE -#extension GL_EXT_shader_pixel_local_storage : enable +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT +// fixedFunctionColorOutput renders directly to the framebuffer, which requires +// EXT_shader_pixel_local_storage2. +#extension GL_EXT_shader_pixel_local_storage2 : require +#else +#extension GL_EXT_shader_pixel_local_storage : require +#endif #define PLS_BLOCK_BEGIN \ __pixel_localEXT PLS \ { -#define PLS_DECL4F(IDX, NAME) layout(rgba8) lowp vec4 NAME +#define PLS_DECL4F(IDX, NAME) layout(rgba8) mediump vec4 NAME +#define PLS_DECL4F_RGB10_A2(IDX, NAME) layout(rgb10_a2) mediump vec4 NAME #define PLS_DECLUI(IDX, NAME) layout(r32ui) highp uint NAME #define PLS_BLOCK_END \ } \ @@ -336,32 +391,18 @@ #define PLS_INTERLOCK_BEGIN #define PLS_INTERLOCK_END -#endif - -#ifdef @PLS_IMPL_FRAMEBUFFER_FETCH - -#extension GL_EXT_shader_framebuffer_fetch : require - -#define PLS_BLOCK_BEGIN -#define PLS_DECL4F(IDX, NAME) layout(location = IDX) inout lowp vec4 NAME -#define PLS_DECLUI(IDX, NAME) layout(location = IDX) inout highp uvec4 NAME -#define PLS_BLOCK_END - -#define PLS_LOAD4F(PLANE) PLANE -#define PLS_LOADUI(PLANE) PLANE.r -#define PLS_STORE4F(PLANE, VALUE) PLANE = (VALUE) -#define PLS_STOREUI(PLANE, VALUE) PLANE.r = (VALUE) - -// When using multiple color attachments, we have to write a value to every -// color attachment, every shader invocation, or else the contents become -// undefined. -#define PLS_PRESERVE_4F(PLANE) PLS_STORE4F(PLANE, PLS_LOAD4F(PLANE)) -#define PLS_PRESERVE_UI(PLANE) PLS_STOREUI(PLANE, PLS_LOADUI(PLANE)) - -#define PLS_INTERLOCK_BEGIN -#define PLS_INTERLOCK_END +#ifdef @FIXED_FUNCTION_COLOR_OUTPUT +// EXT_shader_pixel_local_storage2 requires explicit output format qualifiers +// on fragment shader outputs. +#define PLS_FRAG_COLOR_MAIN(NAME) \ + layout(location = 0, rgba8) out half4 _fragColor; \ + PLS_MAIN(NAME) -#endif // PLS_IMPL_FRAMEBUFFER_FETCH +#define PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS(NAME) \ + layout(location = 0, rgba8) out half4 _fragColor; \ + PLS_MAIN(NAME) +#endif +#endif #ifdef @PLS_IMPL_STORAGE_TEXTURE @@ -382,16 +423,21 @@ #endif #define PLS_BLOCK_BEGIN -#ifdef @TARGET_VULKAN +#ifdef @TARGET_SPIRV #define PLS_DECL4F(IDX, NAME) \ layout(set = PLS_TEXTURE_BINDINGS_SET, binding = IDX, rgba8) \ - uniform lowp coherent image2D NAME + uniform mediump coherent image2D NAME +#define PLS_DECL4F_RGB10_A2(IDX, NAME) \ + layout(set = PLS_TEXTURE_BINDINGS_SET, binding = IDX, rgb10_a2) \ + uniform mediump coherent image2D NAME #define PLS_DECLUI(IDX, NAME) \ layout(set = PLS_TEXTURE_BINDINGS_SET, binding = IDX, r32ui) \ uniform highp coherent uimage2D NAME #else #define PLS_DECL4F(IDX, NAME) \ - layout(binding = IDX, rgba8) uniform lowp coherent image2D NAME + layout(binding = IDX, rgba8) uniform mediump coherent image2D NAME +#define PLS_DECL4F_RGB10_A2(IDX, NAME) \ + layout(binding = IDX, rgb10_a2) uniform mediump coherent image2D NAME #define PLS_DECLUI(IDX, NAME) \ layout(binding = IDX, r32ui) uniform highp coherent uimage2D NAME #endif @@ -407,8 +453,7 @@ #ifndef @USING_PLS_STORAGE_TEXTURES #define @USING_PLS_STORAGE_TEXTURES - -#endif // PLS_IMPL_STORAGE_TEXTURE +#endif #endif // PLS_IMPL_STORAGE_TEXTURE @@ -419,10 +464,12 @@ layout(input_attachment_index = IDX, \ binding = IDX, \ set = PLS_TEXTURE_BINDINGS_SET) \ - uniform lowp subpassInput _in_##NAME; + uniform mediump subpassInput _in_##NAME +#define PLS_DECL4F_WRITEONLY(IDX, NAME) \ + layout(location = IDX) out mediump vec4 NAME #define PLS_DECL4F(IDX, NAME) \ PLS_DECL4F_READONLY(IDX, NAME); \ - layout(location = IDX) out lowp vec4 NAME + PLS_DECL4F_WRITEONLY(IDX, NAME) #define PLS_DECLUI(IDX, NAME) \ layout(input_attachment_index = IDX, \ binding = IDX, \ @@ -447,7 +494,7 @@ #ifdef @PLS_IMPL_NONE #define PLS_BLOCK_BEGIN -#define PLS_DECL4F(IDX, NAME) layout(location = IDX) out lowp vec4 NAME +#define PLS_DECL4F(IDX, NAME) layout(location = IDX) out mediump vec4 NAME #define PLS_DECLUI(IDX, NAME) layout(location = IDX) out highp uvec4 NAME #define PLS_BLOCK_END @@ -464,13 +511,17 @@ #endif -#ifdef @TARGET_VULKAN +#ifndef PLS_DECL4F_READONLY +#define PLS_DECL4F_READONLY PLS_DECL4F +#endif + +#ifdef @TARGET_SPIRV #define gl_VertexID gl_VertexIndex #endif // clang-format off #ifdef @ENABLE_INSTANCE_INDEX -# ifdef @TARGET_VULKAN +# ifdef @TARGET_SPIRV # define INSTANCE_INDEX gl_InstanceIndex # else # ifdef @BASE_INSTANCE_UNIFORM_NAME @@ -490,6 +541,9 @@ #define VERTEX_CONTEXT_DECL #define VERTEX_CONTEXT_UNPACK +#define CLIP_CONTEXT_FORWARD +#define CLIP_CONTEXT_UNPACK + #define VERTEX_MAIN(NAME, Attrs, attrs, _vertexID, _instanceID) \ void main() \ { \ @@ -515,6 +569,10 @@ layout(location = 0) out DATA_TYPE _fd; \ void main() +#define FRAG_DATA_MAIN_WITH_CLOCKWISE FRAG_DATA_MAIN + +#define _clockwise gl_FrontFacing + #define EMIT_FRAG_DATA(VALUE) _fd = VALUE #define _fragCoord gl_FragCoord.xy @@ -524,17 +582,23 @@ #ifdef @USING_PLS_STORAGE_TEXTURES -#ifdef @TARGET_VULKAN -#define PLS_DECLUI_ATOMIC(IDX, NAME) \ +#ifdef @TARGET_SPIRV +#define PLS_DECLUI_UAV(IDX, NAME) \ layout(set = PLS_TEXTURE_BINDINGS_SET, binding = IDX, r32ui) \ uniform highp coherent uimage2D NAME +#define PLS_DECL4F_RGB10_A2_UAV(IDX, NAME) \ + layout(set = PLS_TEXTURE_BINDINGS_SET, binding = IDX, rgb10_a2) \ + uniform mediump coherent image2D NAME #else -#define PLS_DECLUI_ATOMIC(IDX, NAME) \ +#define PLS_DECLUI_UAV(IDX, NAME) \ layout(binding = IDX, r32ui) uniform highp coherent uimage2D NAME +#define PLS_DECL4F_RGB10_A2_UAV(IDX, NAME) \ + layout(binding = IDX, rgb10_a2) uniform mediump coherent image2D NAME; #endif -#define PLS_LOADUI_ATOMIC(PLANE) imageLoad(PLANE, _plsCoord).r -#define PLS_STOREUI_ATOMIC(PLANE, VALUE) \ - imageStore(PLANE, _plsCoord, uvec4(VALUE)) +#define PLS_LOADUI_UAV(PLANE) imageLoad(PLANE, _plsCoord).r +#define PLS_STOREUI_UAV(PLANE, VALUE) imageStore(PLANE, _plsCoord, uvec4(VALUE)) +#define PLS_LOAD4F_UAV(PLANE) imageLoad(PLANE, _plsCoord) +#define PLS_STORE4F_UAV(PLANE, VALUE) imageStore(PLANE, _plsCoord, VALUE) #define PLS_ATOMIC_MAX(PLANE, X) imageAtomicMax(PLANE, _plsCoord, X) #define PLS_ATOMIC_ADD(PLANE, X) imageAtomicAdd(PLANE, _plsCoord, X) @@ -548,6 +612,19 @@ #define EMIT_PLS } +// Storage textures are expensive to update. It's faster to conditionally update +// them when possible. +#define PLS_STORE4F_OPTIONAL_IF(CONDITION, PLANE, VALUE) \ + if (!(CONDITION)) \ + { \ + PLS_STORE4F(PLANE, VALUE); \ + } +#define PLS_STOREUI_OPTIONAL_IF(CONDITION, PLANE, VALUE) \ + if (!(CONDITION)) \ + { \ + PLS_STOREUI(PLANE, VALUE); \ + } + #else // !USING_PLS_STORAGE_TEXTURES #define PLS_CONTEXT_DECL @@ -556,20 +633,48 @@ #define PLS_MAIN(NAME) void main() #define EMIT_PLS +// Cheap forms of PLS do better to update unconditionally, even if it might be a +// no-op. (Especially since we otherwise would have had to preserve anyway.) +#define PLS_STORE4F_OPTIONAL_IF(CONDITION, PLANE, VALUE) \ + PLS_STORE4F(PLANE, VALUE); +#define PLS_STOREUI_OPTIONAL_IF(CONDITION, PLANE, VALUE) \ + PLS_STOREUI(PLANE, VALUE); + #endif // !USING_PLS_STORAGE_TEXTURES #define PLS_MAIN_WITH_IMAGE_UNIFORMS(NAME) PLS_MAIN(NAME) +#ifndef PLS_FRAG_COLOR_MAIN #define PLS_FRAG_COLOR_MAIN(NAME) \ layout(location = 0) out half4 _fragColor; \ PLS_MAIN(NAME) +#endif +#ifndef PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS #define PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS(NAME) \ layout(location = 0) out half4 _fragColor; \ PLS_MAIN(NAME) +#endif #define EMIT_PLS_AND_FRAG_COLOR EMIT_PLS +#if defined(@TARGET_SPIRV) && !defined(@INPUT_ATTACHMENT_NONE) +#define DST_COLOR_TEXTURE(NAME) \ + layout(input_attachment_index = 0, \ + binding = COLOR_PLANE_IDX, \ + set = PLS_TEXTURE_BINDINGS_SET) uniform mediump subpassInputMS NAME +#define DST_COLOR_FETCH(NAME) \ + dst_color_fetch(mat4(subpassLoad(NAME, 0), \ + subpassLoad(NAME, 1), \ + subpassLoad(NAME, 2), \ + subpassLoad(NAME, 3)), \ + gl_SampleMaskIn[0]) +#else +#define DST_COLOR_TEXTURE(NAME) \ + TEXTURE_RGBA8(PER_FLUSH_BINDINGS_SET, DST_COLOR_TEXTURE_IDX, NAME) +#define DST_COLOR_FETCH(NAME) texelFetch(NAME, ivec2(floor(_fragCoord.xy)), 0) +#endif + #define MUL(A, B) ((A) * (B)) precision highp float; @@ -577,20 +682,13 @@ precision highp int; #if @GLSL_VERSION < 310 // Polyfill ES 3.1+ methods. -INLINE half4 unpackUnorm4x8(uint u) +INLINE half4 polyfill_unpackUnorm4x8(uint u) { uint4 vals = uint4(u & 0xffu, (u >> 8) & 0xffu, (u >> 16) & 0xffu, u >> 24); return float4(vals) * (1. / 255.); } +// Use #define for unpackUnorm4x8 because some drivers (e.g., Adreno 308) +// incorrectly declare this builtin on ES 3.0, leading to compiler errors if we +// just declare it as a normal function. +#define unpackUnorm4x8 polyfill_unpackUnorm4x8 #endif - -// clang-format off -#if @GLSL_VERSION >= 310 && defined(@VERTEX) && defined(@RENDER_MODE_MSAA) && defined(@ENABLE_CLIP_RECT) -out gl_PerVertex -{ - // Redeclare gl_ClipDistance with exactly 4 clip planes. - float gl_ClipDistance[4]; - float4 gl_Position; -}; -#endif -// clang-format on diff --git a/thirdparty/rive_renderer/source/shaders/hlsl.glsl b/thirdparty/rive_renderer/source/shaders/hlsl.glsl index e17e23a60..f45d6ff11 100644 --- a/thirdparty/rive_renderer/source/shaders/hlsl.glsl +++ b/thirdparty/rive_renderer/source/shaders/hlsl.glsl @@ -37,6 +37,7 @@ #define float2x2 $float2x2 #define half3x3 $half3x3 #define half2x3 $half2x3 +#define half4x4 $half4x4 #endif $typedef float3 packed_float3; @@ -128,19 +129,20 @@ $typedef float3 packed_float3; #define TEXTURE_R16F_1D_ARRAY(SET, IDX, NAME) \ uniform $Texture1DArray NAME : $register($t##IDX) -// SAMPLER_LINEAR and SAMPLER_MIPMAP are the same because in d3d11, sampler +// SAMPLER_LINEAR is the same as SAMPLER because in d3d11, sampler // parameters are defined at the API level. -#define SAMPLER(TEXTURE_IDX, NAME) \ - $SamplerState NAME : $register($s##TEXTURE_IDX); +#define SAMPLER(IDX, NAME) $SamplerState NAME : $register($s##IDX); #define SAMPLER_LINEAR SAMPLER -#define SAMPLER_MIPMAP SAMPLER -#define SAMPLER_DYNAMIC SAMPLER +#define SAMPLER_DYNAMIC(SET, IDX, NAME) SAMPLER(IDX, NAME) +#define SAMPLER_DYNAMIC_IMAGE(NAME) SAMPLER(IMAGE_TEXTURE_IDX, NAME) #define TEXEL_FETCH(NAME, COORD) NAME[COORD] #define TEXTURE_SAMPLE(NAME, SAMPLER_NAME, COORD) \ NAME.$Sample(SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_LOD(NAME, SAMPLER_NAME, COORD, LOD) \ NAME.$SampleLevel(SAMPLER_NAME, COORD, LOD) +#define TEXTURE_SAMPLE_LODBIAS(NAME, SAMPLER_NAME, COORD, LODBIAS) \ + NAME.$SampleBias(SAMPLER_NAME, COORD, LODBIAS) #define TEXTURE_SAMPLE_GRAD(NAME, SAMPLER_NAME, COORD, DDX, DDY) \ NAME.$SampleGrad(SAMPLER_NAME, COORD, DDX, DDY) #define TEXTURE_GATHER(NAME, SAMPLER_NAME, COORD, TEXTURE_INVERSE_SIZE) \ @@ -157,7 +159,8 @@ $typedef float3 packed_float3; TEXTURE_SAMPLE(TEXTURE, SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_DYNAMIC_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) \ TEXTURE_SAMPLE_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) - +#define TEXTURE_SAMPLE_DYNAMIC_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) \ + TEXTURE_SAMPLE_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) #define PLS_INTERLOCK_BEGIN #define PLS_INTERLOCK_END @@ -176,9 +179,9 @@ $typedef float3 packed_float3; #endif #define PLS_DECL4F_READONLY PLS_DECL4F #define PLS_DECLUI(IDX, NAME) uniform PLS_TEX2D NAME : $register($u##IDX) -#define PLS_DECLUI_ATOMIC PLS_DECLUI -#define PLS_LOADUI_ATOMIC PLS_LOADUI -#define PLS_STOREUI_ATOMIC PLS_STOREUI +#define PLS_DECLUI_UAV PLS_DECLUI +#define PLS_LOADUI_UAV PLS_LOADUI +#define PLS_STOREUI_UAV PLS_STOREUI #define PLS_BLOCK_END #ifdef @ENABLE_TYPED_UAV_LOAD_STORE @@ -221,6 +224,9 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) #define TEXTURE_CONTEXT_DECL #define TEXTURE_CONTEXT_FORWARD +#define CLIP_CONTEXT_FORWARD +#define CLIP_CONTEXT_UNPACK + #define VERTEX_MAIN(NAME, Attrs, attrs, _vertexID, _instanceID) \ $cbuffer DrawUniforms \ : UNIFORM_BUFFER_REGISTER(PATH_BASE_INSTANCE_UNIFORM_BUFFER_IDX) \ @@ -230,9 +236,9 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) uint NAME##_pad1; \ uint NAME##_pad2; \ } \ - Varyings main(Attrs attrs, uint _vertexID \ - : $SV_VertexID, uint _instanceIDWithoutBase \ - : $SV_InstanceID) \ + Varyings main(Attrs attrs, \ + uint _vertexID : $SV_VertexID, \ + uint _instanceIDWithoutBase : $SV_InstanceID) \ { \ uint _instanceID = _instanceIDWithoutBase + baseInstance; \ Varyings _varyings; @@ -249,8 +255,9 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) UVAttr, \ uv, \ _vertexID) \ - Varyings main(PositionAttr position, UVAttr uv, uint _vertexID \ - : $SV_VertexID) \ + Varyings main(PositionAttr position, \ + UVAttr uv, \ + uint _vertexID : $SV_VertexID) \ { \ Varyings _varyings; \ float4 _pos; @@ -264,6 +271,11 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) DATA_TYPE main(Varyings _varyings) : $SV_Target \ { +#define FRAG_DATA_MAIN_WITH_CLOCKWISE(DATA_TYPE, NAME) \ + DATA_TYPE main(Varyings _varyings, bool _clockwise : $SV_IsFrontFace) : \ + $SV_Target \ + { + #define EMIT_FRAG_DATA(VALUE) \ return VALUE; \ } @@ -362,6 +374,18 @@ INLINE float2x2 inverse(float2x2 m) return adjoint * (1. / determinant(m)); } +// mix() with a boolean type in glsl maps to the hlsl ternary operator + +INLINE float mix(float x, float y, bool s) { return s ? y : x; } +INLINE float2 mix(float2 x, float2 y, bool2 s) { return s ? y : x; } +INLINE float3 mix(float3 x, float3 y, bool3 s) { return s ? y : x; } +INLINE float4 mix(float4 x, float4 y, bool4 s) { return s ? y : x; } + +INLINE half mix(half x, half y, bool s) { return s ? y : x; } +INLINE half2 mix(half2 x, half2 y, bool2 s) { return s ? y : x; } +INLINE half3 mix(half3 x, half3 y, bool3 s) { return s ? y : x; } +INLINE half4 mix(half4 x, half4 y, bool4 s) { return s ? y : x; } + // Redirects for intrinsics that have different names in HLSL INLINE float mix(float x, float y, float s) { return $lerp(x, y, s); } @@ -369,10 +393,10 @@ INLINE float2 mix(float2 x, float2 y, float2 s) { return $lerp(x, y, s); } INLINE float3 mix(float3 x, float3 y, float3 s) { return $lerp(x, y, s); } INLINE float4 mix(float4 x, float4 y, float4 s) { return $lerp(x, y, s); } -INLINE half mix(half x, half y, half s) { return x + s * (y - x); } -INLINE half2 mix(half2 x, half2 y, half2 s) { return x + s * (y - x); } -INLINE half3 mix(half3 x, half3 y, half3 s) { return x + s * (y - x); } -INLINE half4 mix(half4 x, half4 y, half4 s) { return x + s * (y - x); } +INLINE half mix(half x, half y, half s) { return $lerp(x, y, s); } +INLINE half2 mix(half2 x, half2 y, half2 s) { return $lerp(x, y, s); } +INLINE half3 mix(half3 x, half3 y, half3 s) { return $lerp(x, y, s); } +INLINE half4 mix(half4 x, half4 y, half4 s) { return $lerp(x, y, s); } INLINE float fract(float x) { return $frac(x); } INLINE float2 fract(float2 x) { return $frac(x); } diff --git a/thirdparty/rive_renderer/source/shaders/image_draw_uniforms.glsl b/thirdparty/rive_renderer/source/shaders/image_draw_uniforms.glsl new file mode 100644 index 000000000..485402ecc --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/image_draw_uniforms.glsl @@ -0,0 +1,16 @@ +#ifndef DRAW_IMAGE_UNIFORMS_NAME +#define DRAW_IMAGE_UNIFORMS_NAME @ImageDrawUniforms +#endif +UNIFORM_BLOCK_BEGIN(IMAGE_DRAW_UNIFORM_BUFFER_IDX, DRAW_IMAGE_UNIFORMS_NAME) +DECLARE_UNIFORM_FLOAT4(viewMatrix) +DECLARE_UNIFORM_FLOAT2(translate) +DECLARE_UNIFORM_FLOAT(opacity) +DECLARE_UNIFORM_FLOAT(padding) +// clipRectInverseMatrix transforms from pixel coordinates to a space where the +// clipRect is the normalized rectangle: [-1, -1, 1, 1]. +DECLARE_UNIFORM_FLOAT4(clipRectInverseMatrix) +DECLARE_UNIFORM_FLOAT2(clipRectInverseTranslate) +DECLARE_UNIFORM_UINT(clipID) +DECLARE_UNIFORM_UINT(blendMode) +DECLARE_UNIFORM_UINT(zIndex) +UNIFORM_BLOCK_END(imageDrawUniforms) \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/init_clockwise_atomic_workaround.frag b/thirdparty/rive_renderer/source/shaders/init_clockwise_atomic_workaround.frag new file mode 100644 index 000000000..22abd67a8 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/init_clockwise_atomic_workaround.frag @@ -0,0 +1,33 @@ +/* + * Copyright 2026 Rive + */ + +// This shader implements a seeming workaround for Qualcomm. Basically, input +// attachment reads of the clip and color buffers don't work unless we first +// draw these buffers into themselves between borrowed coverage and the main +// subpass. This draw is issued with a scissor that only allows one pixel +// through, so the fill rate impact should be negligible. +#ifdef @FRAGMENT + +PLS_BLOCK_BEGIN +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); +#endif +PLS_DECL4F(CLIP_PLANE_IDX, clipBuffer); +PLS_BLOCK_END + +CLOCKWISE_ATOMIC_PLS_MAIN(@drawFragmentMain) +{ + // Draw the clip buffer onto itself. + PLS_STORE4F(clipBuffer, make_half4(PLS_LOAD4F(clipBuffer).r, .0, .0, 1.)); +#ifndef @FIXED_FUNCTION_COLOR_OUTPUT + // Draw the color buffer onto itself. + EMIT_CLOCKWISE_ATOMIC_PLS(PLS_LOAD4F(colorBuffer)); +#else + // This render pass doesn't read the color buffer. Emit 0 (since srcOver + // blend is enabled) to leave the color buffer unaffected. + EMIT_CLOCKWISE_ATOMIC_PLS(make_half4(.0)); +#endif +} + +#endif diff --git a/thirdparty/rive_renderer/source/shaders/metal.glsl b/thirdparty/rive_renderer/source/shaders/metal.glsl index 18a0cfb45..6a2500dd8 100644 --- a/thirdparty/rive_renderer/source/shaders/metal.glsl +++ b/thirdparty/rive_renderer/source/shaders/metal.glsl @@ -40,6 +40,7 @@ #define float2x2 $float2x2 #define half3x3 $half3x3 #define half2x3 $half2x3 +#define half4x4 $half4x4 #endif #define INLINE $inline @@ -147,15 +148,16 @@ #define SAMPLER_LINEAR(TEXTURE_IDX, NAME) \ $constexpr $sampler NAME($filter::$linear, $mip_filter::$none); -#define SAMPLER_MIPMAP(TEXTURE_IDX, NAME) \ - $constexpr $sampler NAME($filter::$linear, $mip_filter::$linear); -#define SAMPLER_DYNAMIC(SAMPLER_IDX, NAME) \ - [[$sampler(SAMPLER_IDX)]] $sampler NAME; +#define SAMPLER_DYNAMIC(SET, IDX, NAME) [[$sampler(IDX)]] $sampler NAME; +#define SAMPLER_DYNAMIC_IMAGE(NAME) \ + [[$sampler(IMAGE_TEXTURE_IDX)]] $sampler NAME; #define TEXEL_FETCH(TEXTURE, COORD) _textures.TEXTURE.$read(uint2(COORD)) #define TEXTURE_SAMPLE(TEXTURE, SAMPLER_NAME, COORD) \ _textures.TEXTURE.$sample(SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) \ _textures.TEXTURE.$sample(SAMPLER_NAME, COORD, $level(LOD)) +#define TEXTURE_SAMPLE_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) \ + _textures.TEXTURE.$sample(SAMPLER_NAME, COORD, $bias(LODBIAS)) #define TEXTURE_SAMPLE_GRAD(TEXTURE, SAMPLER_NAME, COORD, DDX, DDY) \ _textures.TEXTURE.$sample(SAMPLER_NAME, COORD, $gradient2d(DDX, DDY)) #define TEXTURE_GATHER(TEXTURE, SAMPLER_NAME, COORD, TEXTURE_INVERSE_SIZE) \ @@ -164,6 +166,10 @@ _textures.TEXTURE.$sample(_dynamicSampler.SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_DYNAMIC_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) \ _textures.TEXTURE.$sample(_dynamicSampler.SAMPLER_NAME, COORD, $level(LOD)) +#define TEXTURE_SAMPLE_DYNAMIC_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) \ + _textures.TEXTURE.$sample(_dynamicSampler.SAMPLER_NAME, \ + COORD, \ + $bias(LODBIAS)) #define TEXTURE_SAMPLE_LOD_1D_ARRAY(TEXTURE, \ SAMPLER_NAME, \ X, \ @@ -247,6 +253,13 @@ FragmentTextures _textures) \ { +#define FRAG_DATA_MAIN_WITH_CLOCKWISE(DATA_TYPE, NAME) \ + DATA_TYPE $__attribute__(($visibility("default"))) $fragment NAME( \ + Varyings _varyings [[$stage_in]], \ + FragmentTextures _textures, \ + bool _clockwise [[$front_facing]]) \ + { + #define EMIT_FRAG_DATA(VALUE) \ return VALUE; \ } @@ -260,6 +273,9 @@ #define TEXTURE_CONTEXT_DECL , FragmentTextures _textures #define TEXTURE_CONTEXT_FORWARD , _textures +#define CLIP_CONTEXT_FORWARD +#define CLIP_CONTEXT_UNPACK + #ifdef @PLS_IMPL_DEVICE_BUFFER #define PLS_BLOCK_BEGIN \ @@ -278,7 +294,7 @@ $device uint* NAME \ [[$buffer(METAL_BUFFER_IDX(IDX + DEFAULT_BINDINGS_SET_SIZE)), \ $raster_order_group(0)]] -#define PLS_DECLUI_ATOMIC(IDX, NAME) \ +#define PLS_DECLUI_UAV(IDX, NAME) \ $device $atomic_uint* NAME \ [[$buffer(METAL_BUFFER_IDX(IDX + DEFAULT_BINDINGS_SET_SIZE)), \ $raster_order_group(0)]] @@ -291,7 +307,7 @@ #define PLS_DECLUI(IDX, NAME) \ $device uint* NAME \ [[$buffer(METAL_BUFFER_IDX(IDX + DEFAULT_BINDINGS_SET_SIZE))]] -#define PLS_DECLUI_ATOMIC(IDX, NAME) \ +#define PLS_DECLUI_UAV(IDX, NAME) \ $device $atomic_uint* NAME \ [[$buffer(METAL_BUFFER_IDX(IDX + DEFAULT_BINDINGS_SET_SIZE))]] #endif // @PLS_IMPL_DEVICE_BUFFER_RASTER_ORDERED @@ -303,12 +319,12 @@ #define PLS_LOAD4F(PLANE) unpackUnorm4x8(_pls.PLANE[_plsIdx]) #define PLS_LOADUI(PLANE) _pls.PLANE[_plsIdx] -#define PLS_LOADUI_ATOMIC(PLANE) \ +#define PLS_LOADUI_UAV(PLANE) \ $atomic_load_explicit(&_pls.PLANE[_plsIdx], \ $memory_order::$memory_order_relaxed) #define PLS_STORE4F(PLANE, VALUE) _pls.PLANE[_plsIdx] = packUnorm4x8(VALUE) #define PLS_STOREUI(PLANE, VALUE) _pls.PLANE[_plsIdx] = (VALUE) -#define PLS_STOREUI_ATOMIC(PLANE, VALUE) \ +#define PLS_STOREUI_UAV(PLANE, VALUE) \ $atomic_store_explicit(&_pls.PLANE[_plsIdx], \ VALUE, \ $memory_order::$memory_order_relaxed) @@ -385,7 +401,7 @@ { #define PLS_DECL4F(IDX, NAME) [[$color(IDX)]] half4 NAME #define PLS_DECLUI(IDX, NAME) [[$color(IDX)]] uint NAME -#define PLS_DECLUI_ATOMIC PLS_DECLUI +#define PLS_DECLUI_UAV PLS_DECLUI #define PLS_BLOCK_END \ } \ ; @@ -394,10 +410,10 @@ #define PLS_LOAD4F(PLANE) _inpls.PLANE #define PLS_LOADUI(PLANE) _inpls.PLANE -#define PLS_LOADUI_ATOMIC(PLANE) PLS_LOADUI +#define PLS_LOADUI_UAV(PLANE) PLS_LOADUI #define PLS_STORE4F(PLANE, VALUE) _pls.PLANE = (VALUE) #define PLS_STOREUI(PLANE, VALUE) _pls.PLANE = (VALUE) -#define PLS_STOREUI_ATOMIC(PLANE) PLS_STOREUI +#define PLS_STOREUI_UAV(PLANE) PLS_STOREUI #define PLS_PRESERVE_4F(PLANE) _pls.PLANE = _inpls.PLANE #define PLS_PRESERVE_UI(PLANE) _pls.PLANE = _inpls.PLANE @@ -442,6 +458,8 @@ INLINE uint pls_atomic_add($thread uint& dst, uint x) PLS_METAL_MAIN( \ NAME, \ PLS _inpls, \ + $constant @FlushUniforms& uniforms \ + [[$buffer(METAL_BUFFER_IDX(FLUSH_UNIFORM_BUFFER_IDX))]], \ Varyings _varyings [[$stage_in]], \ FragmentTextures _textures, \ FragmentStorageBuffers _buffers, \ @@ -467,16 +485,21 @@ INLINE uint pls_atomic_add($thread uint& dst, uint x) PLS _pls; #define PLS_FRAG_COLOR_MAIN(NAME) \ - PLS_FRAG_COLOR_METAL_MAIN(NAME, \ - PLS _inpls, \ - Varyings _varyings [[$stage_in]], \ - FragmentTextures _textures, \ - FragmentStorageBuffers _buffers) + PLS_FRAG_COLOR_METAL_MAIN( \ + NAME, \ + PLS _inpls, \ + $constant @FlushUniforms& uniforms \ + [[$buffer(METAL_BUFFER_IDX(FLUSH_UNIFORM_BUFFER_IDX))]], \ + Varyings _varyings [[$stage_in]], \ + FragmentTextures _textures, \ + FragmentStorageBuffers _buffers) #define PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS(NAME) \ PLS_FRAG_COLOR_METAL_MAIN( \ NAME, \ PLS _inpls, \ + $constant @FlushUniforms& uniforms \ + [[$buffer(METAL_BUFFER_IDX(FLUSH_UNIFORM_BUFFER_IDX))]], \ Varyings _varyings [[$stage_in]], \ FragmentTextures _textures, \ FragmentStorageBuffers _buffers, \ diff --git a/thirdparty/rive_renderer/source/shaders/metal/color_ramp.metal b/thirdparty/rive_renderer/source/shaders/metal/color_ramp.metal index 9c0f0c089..c0c7c59fd 100644 --- a/thirdparty/rive_renderer/source/shaders/metal/color_ramp.metal +++ b/thirdparty/rive_renderer/source/shaders/metal/color_ramp.metal @@ -5,5 +5,7 @@ #include "metal.minified.glsl" #include "constants.minified.glsl" + +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "color_ramp.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/metal/draw.metal b/thirdparty/rive_renderer/source/shaders/metal/draw.metal index 674f42903..df9d7c77d 100644 --- a/thirdparty/rive_renderer/source/shaders/metal/draw.metal +++ b/thirdparty/rive_renderer/source/shaders/metal/draw.metal @@ -9,6 +9,9 @@ #include "metal.minified.glsl" #include "constants.minified.glsl" #define DRAW_IMAGE + +#include "flush_uniforms.minified.glsl" +#include "image_draw_uniforms.minified.glsl" #include "common.minified.glsl" #undef DRAW_IMAGE #define DRAW_PATH diff --git a/thirdparty/rive_renderer/source/shaders/metal/generate_draw_combinations.py b/thirdparty/rive_renderer/source/shaders/metal/generate_draw_combinations.py index 31a44ff06..0f676dc2c 100644 --- a/thirdparty/rive_renderer/source/shaders/metal/generate_draw_combinations.py +++ b/thirdparty/rive_renderer/source/shaders/metal/generate_draw_combinations.py @@ -18,8 +18,9 @@ def __init__(self, name, index): ENABLE_EVEN_ODD = Feature('ENABLE_EVEN_ODD', 4) ENABLE_NESTED_CLIPPING = Feature('ENABLE_NESTED_CLIPPING', 5) ENABLE_HSL_BLEND_MODES = Feature('ENABLE_HSL_BLEND_MODES', 6) -DRAW_INTERIOR_TRIANGLES = Feature('DRAW_INTERIOR_TRIANGLES', 7) -ATLAS_BLIT = Feature('ATLAS_BLIT', 8) +ENABLE_DITHER = Feature('ENABLE_DITHER', 7) +DRAW_INTERIOR_TRIANGLES = Feature('DRAW_INTERIOR_TRIANGLES', 8) +ATLAS_BLIT = Feature('ATLAS_BLIT', 9) whole_program_features = {ENABLE_CLIPPING, ENABLE_CLIP_RECT, @@ -28,7 +29,8 @@ def __init__(self, name, index): fragment_only_features = {ENABLE_EVEN_ODD, ENABLE_NESTED_CLIPPING, - ENABLE_HSL_BLEND_MODES} + ENABLE_HSL_BLEND_MODES, + ENABLE_DITHER} all_features = whole_program_features.union(fragment_only_features) @@ -75,7 +77,7 @@ def emit_shader(out, shader_type, draw_type, fill_type, feature_set): out.write('#define FRAGMENT\n') if draw_type == DrawType.IMAGE_MESH: assert(is_image_mesh_feature_set(feature_set)) - namespace_id = ['0', '0', '0', '0', '0', '0', '0', '0', '0'] + namespace_id = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0'] for feature in feature_set: namespace_id[feature.index] = '1' for feature in feature_set: @@ -83,17 +85,28 @@ def emit_shader(out, shader_type, draw_type, fill_type, feature_set): if fill_type == FillType.CLOCKWISE: out.write('#define CLOCKWISE_FILL 1\n') if draw_type == DrawType.PATH: + out.write('#define DRAW_PATH 1\n') out.write('namespace %s%s\n' % ('c' if fill_type == FillType.CLOCKWISE else 'p', ''.join(namespace_id))) out.write('{\n') - out.write('#include "draw_path.minified.glsl"\n') + out.write('#include "draw_path.minified.vert"\n') + if ATLAS_BLIT in feature_set: + out.write('#include "draw_mesh.minified.frag"\n') + else: + out.write('#include "draw_raster_order_path.minified.frag"\n') out.write('}\n') + out.write('#undef DRAW_PATH\n') else: + out.write('#define DRAW_IMAGE 1\n') + out.write('#define DRAW_IMAGE_MESH 1\n') out.write('namespace m%s\n' % ''.join(namespace_id)) out.write('{\n') - out.write('#include "draw_image_mesh.minified.glsl"\n') + out.write('#include "draw_image_mesh.minified.vert"\n') + out.write('#include "draw_mesh.minified.frag"\n') out.write('}\n') + out.write('#undef DRAW_IMAGE_MESH\n') + out.write('#undef DRAW_IMAGE\n') for feature in feature_set: out.write('#undef %s\n' % feature.name) if shader_type == ShaderType.VERTEX: diff --git a/thirdparty/rive_renderer/source/shaders/metal/tessellate.metal b/thirdparty/rive_renderer/source/shaders/metal/tessellate.metal index 26d542b34..ed197a924 100644 --- a/thirdparty/rive_renderer/source/shaders/metal/tessellate.metal +++ b/thirdparty/rive_renderer/source/shaders/metal/tessellate.metal @@ -5,6 +5,8 @@ #include "metal.minified.glsl" #include "constants.minified.glsl" + +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "bezier_utils.minified.glsl" #include "tessellate.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/minify.py b/thirdparty/rive_renderer/source/shaders/minify.py index 5edc6b27f..c01fade10 100644 --- a/thirdparty/rive_renderer/source/shaders/minify.py +++ b/thirdparty/rive_renderer/source/shaders/minify.py @@ -1,5 +1,6 @@ import argparse import glob +import io import os import re import sys @@ -35,17 +36,22 @@ help="OUTPUT directory to store the header files") parser.add_argument("-H", "--human-readable", action='store_true', help="don't rename or strip out comments or whitespace") -parser.add_argument("-p", "--ply-path", required=True, type=str, help="path to ply module") +parser.add_argument("-p", "--ply-path", type=str, help="path to ply module") +parser.add_argument("-m", "--msvc", action="store_true", help="set this to generate MSVC-compatible headers") args = parser.parse_args() -# Convert posix path to windows -convertedPath = args.ply_path -if sys.platform.startswith('win32') and args.ply_path[:2] == '/c': - convertedPath = 'C:\\' + args.ply_path[2:] - print('Using ply path:' + convertedPath) +if args.ply_path: + # --ply-path was specified, so add it to the sys path so we can locate the module. + # (if it was not specified we'll assume that it's already reachable via the path) -sys.path.append(convertedPath) + # Convert posix path to windows + convertedPath = args.ply_path + if sys.platform.startswith('win32') and args.ply_path[:2] == '/c': + convertedPath = 'C:\\' + args.ply_path[2:] + print('Using ply path:' + convertedPath) + + sys.path.append(convertedPath) import ply.lex as lex @@ -224,7 +230,7 @@ def t_error(tok): "outerProduct", "outerProduct", "outerProduct", "outerProduct", "outerProduct", "outerProduct", "outerProduct", "outerProduct", "packDouble2x32", "packHalf2x16", "packSnorm2x16", "packSnorm4x8", "packUnorm2x16", "packUnorm4x8", "pixelLocalLoadANGLE", "pixelLocalStoreANGLE", - "pow", "precision", "r16f", "r32f", "r32ui", "radians", "reflect", "reflect", "refract", + "pow", "precision", "r16f", "r32f", "r32i", "r32ui", "radians", "reflect", "reflect", "refract", "refract", "return", "rg16f", "rgb_2_yuv", "rgba8", "rgba8i", "rgba8ui", "round", "round", "roundEven", "roundEven", "sampler2D", "sampler2DArray", "sampler2DArrayShadow", "sampler2DShadow", "sampler3D", "samplerCube", "samplerCubeShadow", "shadow1D", "shadow1DLod", @@ -308,13 +314,15 @@ def t_error(tok): "usampler2DArray", "usampler3D", "usamplerCube", "usubBorrow", "uvec2", "uvec3", "uvec4", "vec2", "vec3", "vec4", "void", "volatile", "while", "yuv_2_rgb", "__pixel_localEXT", "__pixel_local_inEXT", "__pixel_local_outEXT", "set", "texture2D", "utexture2D", "sampler", - "subpassInput", "usubpassInput", "input_attachment_index", "readonly", "buffer", - "unpackUnorm4x8", "defined", "elif", "extension", "enable", "require", "endif", "undef", - "pragma", "__VERSION__", "constant_id", "blend_support_all_equations", "blend_support_multiply", + "subpassInput", "subpassInputMS", "usubpassInput", "input_attachment_index", + "readonly", "buffer", "unpackUnorm4x8", "defined", "elif", "extension", + "enable", "require", "endif", "undef", "pragma", "__VERSION__", + "constant_id", "blend_support_all_equations", "blend_support_multiply", "blend_support_screen", "blend_support_overlay", "blend_support_darken", - "blend_support_lighten", "blend_support_colordodge", "blend_support_colorburn", - "blend_support_hardlight", "blend_support_softlight", "blend_support_difference", - "blend_support_exclusion", + "blend_support_lighten", "blend_support_colordodge", + "blend_support_colorburn", "blend_support_hardlight", + "blend_support_softlight", "blend_support_difference", + "blend_support_exclusion", "rgb10_a2", } # rgba and stpq get rewritten to xyzw, so we only need to check xyzw here. This way we can keep @@ -343,7 +351,7 @@ def remove_leading_annotation(name): if name[0] == '@': # A leading '@' indicates identifier names that should be exported. Rename '@my_var' to # '_EXPORTED_my_var' to enforce that '@my_var' and 'my_var' are not interchangeable. - return '_EXPORTED_' + name[1:] + return 'EXPORTED_' + name[1:] if name[0] == '$': # A leading '$' indicates identifier names that should not be renamed. return name[1:] @@ -449,7 +457,7 @@ def strip_tokens(self): # generates rewritten glsl from our tokens. - def emit_tokens_to_rewritten_glsl(self, out, *, preserve_exported_switches): + def emit_tokens_to_rewritten_glsl(self, out, *, preserve_exported_switches, calling_token_type:str=None): # stand-in for a null token. lasttoken = lambda : None lasttoken.type = "" @@ -468,7 +476,8 @@ def emit_tokens_to_rewritten_glsl(self, out, *, preserve_exported_switches): is_directive = tok.type in ["DEFINE", "IFDEF", "DIRECTIVE"] needs_whitespace = tok.type in ["FLOAT", "INT", "HEX", "ID", "DEFINED_ID"] - if is_directive and not is_newline: + # Adding this calling_token_type != 'DEFINE' prevents us from adding a new line to stringify macros + if is_directive and not is_newline and calling_token_type != 'DEFINE': out.write('\n') elif needs_whitespace and lasttoken_needs_whitespace: out.write(' ') @@ -492,13 +501,15 @@ def emit_tokens_to_rewritten_glsl(self, out, *, preserve_exported_switches): if tok.define_arglist != None: is_newline = tok.define_arglist.emit_tokens_to_rewritten_glsl(\ out,\ - preserve_exported_switches=preserve_exported_switches) + preserve_exported_switches=preserve_exported_switches,\ + calling_token_type=tok.type) assert(not is_newline) if tok.define_val != None: out.write(' ') is_newline = tok.define_val.emit_tokens_to_rewritten_glsl(\ out,\ - preserve_exported_switches=preserve_exported_switches) + preserve_exported_switches=preserve_exported_switches,\ + calling_token_type=tok.type) elif tok.type == "IFDEF": out.write('#') @@ -516,7 +527,8 @@ def emit_tokens_to_rewritten_glsl(self, out, *, preserve_exported_switches): if tok.directive_val != None: is_newline = tok.directive_val.emit_tokens_to_rewritten_glsl(\ out,\ - preserve_exported_switches=preserve_exported_switches) + preserve_exported_switches=preserve_exported_switches,\ + calling_token_type=tok.type) else: out.write(tok.value) @@ -543,8 +555,8 @@ def write_identifier(self, out, identifier, preserve_exported_switches): def write_exports(self, outdir): - output_path = os.path.join(outdir, os.path.splitext(self.basename)[0] + ".exports.h") - print("Exporting %s <- %s" % (output_path, self.basename)) + output_path = os.path.join(outdir, f"{self.basename}.exports.h") + print(f"Exporting {output_path} <- {self.basename}") out = open(output_path, "w", newline='\n') out.write('#pragma once\n\n') for exp in sorted(self.exports): @@ -559,27 +571,57 @@ def write_embedded_glsl(self, outdir): out = open(output_path, "w", newline='\n') out.write("#pragma once\n\n") - out.write('#include "%s"\n\n' % (os.path.splitext(self.basename)[0] + ".exports.h")) + out.write(f'#include "{self.basename}.exports.h"\n\n') # emit shader code. + root, ext = os.path.splitext(self.basename) + cpp_name = root + if ext != '.glsl': + cpp_name = f"{root}_{ext[1:]}" out.write("namespace rive {\n") out.write("namespace gpu {\n") out.write("namespace glsl {\n") - out.write('const char %s[] = R"===(' % os.path.splitext(self.basename)[0]) + if args.msvc: + # MSVC cannot compile raw shaders as strings because of an internal + # string length limit. There is, however, no limit on arrays so + # instead write it out as an array of individual characters. + out.write(f'const char {cpp_name}[] = {{\n ') + + codeIO = io.StringIO() + self.emit_tokens_to_rewritten_glsl(codeIO, preserve_exported_switches=False) + + out_ch_count = 0 + for ch in codeIO.getvalue(): + # use `repr` to escape the characters (but we need to handle single + # quote manually, since it will represent that as "'" - which will + # definitely not compile) + + out.write(f" {repr(ch)},") if ch != "'" else out.write(" '\\'',") + out_ch_count = out_ch_count + 1 + CHAR_COUNT_PER_LINE = 12 + if (out_ch_count % CHAR_COUNT_PER_LINE) == 0: + out.write('\n ') + # Null-terminate so the array is a valid C-string when passed to + # APIs like ostream::operator<<(const char*), which read until '\0'. + out.write(" '\\0'\n};\n") + else: + # For non-MSVC outputs just output as a raw string + out.write(f'const char {cpp_name}[] = R"===(') - is_newline = self.emit_tokens_to_rewritten_glsl(out, preserve_exported_switches=False) - if not is_newline: - out.write('\n') + is_newline = self.emit_tokens_to_rewritten_glsl(out, preserve_exported_switches=False) + if not is_newline: + out.write('\n') - out.write(')===";\n') + out.write(')===";\n') out.write("} // namespace glsl\n") out.write("} // namespace gpu\n") out.write("} // namespace rive") out.close() def write_offline_glsl(self, outdir): - output_path = os.path.join(outdir, os.path.splitext(self.basename)[0] + ".minified.glsl") - print("Minifying %s <- %s" % (output_path, self.basename)) + root, ext = os.path.splitext(self.basename) + output_path = os.path.join(outdir, f"{root}.minified{ext}") + print(f"Minifying f{output_path} <- {self.basename}") out = open(output_path, "w", newline='\n') self.emit_tokens_to_rewritten_glsl(out, preserve_exported_switches=True) out.close() diff --git a/thirdparty/rive_renderer/source/shaders/pls_load_store_ext.glsl b/thirdparty/rive_renderer/source/shaders/pls_load_store_ext.glsl index 75ce40375..31b112702 100644 --- a/thirdparty/rive_renderer/source/shaders/pls_load_store_ext.glsl +++ b/thirdparty/rive_renderer/source/shaders/pls_load_store_ext.glsl @@ -15,6 +15,9 @@ void main() equal(gl_VertexID & ivec2(1, 2), ivec2(0))), 0, 1); +#ifdef @POST_INVERT_Y + gl_Position.y = -gl_Position.y; +#endif } #endif diff --git a/thirdparty/rive_renderer/source/shaders/render_atlas.glsl b/thirdparty/rive_renderer/source/shaders/render_atlas.glsl index 32c0d2353..9c97676d4 100644 --- a/thirdparty/rive_renderer/source/shaders/render_atlas.glsl +++ b/thirdparty/rive_renderer/source/shaders/render_atlas.glsl @@ -40,6 +40,9 @@ VERTEX_MAIN(@atlasVertexMain, Attrs, attrs, _vertexID, _instanceID) pos = pixel_coord_to_clip_coord(vertexPosition, uniforms.atlasContentInverseViewport.x, uniforms.atlasContentInverseViewport.y); +#ifdef @POST_INVERT_Y + pos.y = -pos.y; +#endif } else { @@ -57,19 +60,190 @@ VERTEX_MAIN(@atlasVertexMain, Attrs, attrs, _vertexID, _instanceID) #ifdef @FRAGMENT #ifdef @ATLAS_FEATHERED_FILL -FRAG_DATA_MAIN(float, @atlasFillFragmentMain) +INLINE half signed_fill_coverage(float4 coverages, + bool clockwise TEXTURE_CONTEXT_DECL) +{ + half coverage = eval_feathered_fill(coverages TEXTURE_CONTEXT_FORWARD); + if (!clockwise) + coverage = -coverage; + return coverage; +} +#endif + +#ifdef @ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH + +// Store coverage as fp32 data bits in an r32ui color buffer, and use +// framebuffer-fetch to manipulate it. +layout(location = 0) inout uint4 coverageCount; + +#ifdef @ATLAS_FEATHERED_FILL +void main() +{ + float coverage = uintBitsToFloat(coverageCount.r); + coverage += signed_fill_coverage(v_coverages, + gl_FrontFacing TEXTURE_CONTEXT_FORWARD); + coverageCount.r = floatBitsToUint(coverage); +} +#endif + +#ifdef @ATLAS_FEATHERED_STROKE +void main() +{ + float coverage = uintBitsToFloat(coverageCount.r); + coverage = max(coverage, eval_feathered_stroke(v_coverages)); + coverageCount.r = floatBitsToUint(coverage); +} +#endif + +#elif defined(@ATLAS_RENDER_TARGET_R8_PLS_EXT) + +// Manipulate fp32 coverage in pixel local storage, which will be written out +// to an r32ui color buffer during a separate resolve step. +__pixel_localEXT PLS { layout(r32f) float coverageCount; }; + +#ifdef @ATLAS_FEATHERED_FILL +void main() +{ + coverageCount += + signed_fill_coverage(v_coverages, + gl_FrontFacing TEXTURE_CONTEXT_FORWARD); +} +#endif + +#ifdef @ATLAS_FEATHERED_STROKE +void main() +{ + coverageCount = max(coverageCount, eval_feathered_stroke(v_coverages)); +} +#endif + +#elif defined(@ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) + +// Store and manipulate coverage as fp32 data bits in r32ui-texture-backed pixel +// local storage. +layout(binding = 0, r32ui) uniform highp upixelLocalANGLE coverageCount; + +#ifdef @ATLAS_FEATHERED_FILL +void main() +{ + float coverage = uintBitsToFloat(pixelLocalLoadANGLE(coverageCount).r); + coverage += signed_fill_coverage(v_coverages, + gl_FrontFacing TEXTURE_CONTEXT_FORWARD); + pixelLocalStoreANGLE(coverageCount, uint4(floatBitsToUint(coverage))); +} +#endif + +#ifdef @ATLAS_FEATHERED_STROKE +void main() +{ + float coverage = uintBitsToFloat(pixelLocalLoadANGLE(coverageCount).r); + coverage = max(coverage, eval_feathered_stroke(v_coverages)); + pixelLocalStoreANGLE(coverageCount, uint4(floatBitsToUint(coverage))); +} +#endif + +#elif defined(@ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE) + +// Store coverage as 16:16 fixed point in an r32i texture, which we manipulate +// with atomics. +layout(binding = 0, r32i) uniform highp coherent iimage2D _atlasImage; +ivec2 image_coord() { return ivec2(floor(_fragCoord)); } +int fixedpoint_coverage(float coverage) +{ + return int(coverage * ATLAS_R32I_FIXED_POINT_FACTOR); +} + +#ifdef @ATLAS_FEATHERED_FILL +void main() +{ + int coverage = fixedpoint_coverage( + signed_fill_coverage(v_coverages, + gl_FrontFacing TEXTURE_CONTEXT_FORWARD)); + imageAtomicAdd(_atlasImage, image_coord(), coverage); +} +#endif + +#ifdef @ATLAS_FEATHERED_STROKE +void main() +{ + int coverage = fixedpoint_coverage(eval_feathered_stroke(v_coverages)); + imageAtomicMax(_atlasImage, image_coord(), coverage); +} +#endif + +#elif defined(@ATLAS_RENDER_TARGET_RGBA8_UNORM) + +// We don't have any extensions to count high precision coverage. (This is very +// rare.). Just split up coverage across rgba8 components and hope for the best. + +#ifdef @ATLAS_FEATHERED_FILL +FRAG_DATA_MAIN_WITH_CLOCKWISE(half4, @atlasFillFragmentMain) { VARYING_UNPACK(v_coverages, float4); - EMIT_FRAG_DATA(eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD)); + half coverage = + signed_fill_coverage(v_coverages, _clockwise TEXTURE_CONTEXT_FORWARD); + // i.e., is abs(coverage) ~= FEATHER(1), allowing for some sub-8-bit slop in + // the texture unit performing a clamp to edge. + if (abs(coverage) > MAX_FEATHER - 1e-3) + { + // All the "fan triangles" in a feather have solid coverage. This is a + // substantial number of triangles, so we dedicate 2 channels to + // counting solid coverage (i.e, +1 or -1). These channels are also much + // slower to overflow, so it preserves a basic skeleton of the feather + // when the fractional channels overflow. + EMIT_FRAG_DATA(coverage > .0 + // B counts integer, positive coverage. + ? make_half4(.0, .0, 1. / 255., .0) + // A counts integer, negative coverage. + : make_half4(.0, .0, .0, 1. / 255.)); + } + else + { + coverage *= 1. / ATLAS_UNORM8_COVERAGE_SCALE_FACTOR; + EMIT_FRAG_DATA(make_half4( + max(coverage, .0), // R counts fractional, positive coverage. + max(-coverage, .0), // G counts fractional, negative coverage. + .0, + .0)); + } } #endif // @ATLAS_FEATHERED_FILL +#ifdef @ATLAS_FEATHERED_STROKE +FRAG_DATA_MAIN(half4, @atlasStrokeFragmentMain) +{ + VARYING_UNPACK(v_coverages, float4); + half coverage = eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD); + // Strokes only have positive coverage, and since we only need to saturate + // the max for stroking, we can just use the R channel. + coverage *= 1. / ATLAS_UNORM8_COVERAGE_SCALE_FACTOR; + EMIT_FRAG_DATA(make_half4(coverage, .0, .0, .0)); +} +#endif // @ATLAS_FEATHERED_STROKE + +#else + +// This is the ideal case. We have full support for floating point color +// buffers, including blending. Render to float and let the fixed function blend +// hardware count the coverage. + +#ifdef @ATLAS_FEATHERED_FILL +FRAG_DATA_MAIN_WITH_CLOCKWISE(float, @atlasFillFragmentMain) +{ + VARYING_UNPACK(v_coverages, float4); + EMIT_FRAG_DATA( + signed_fill_coverage(v_coverages, _clockwise TEXTURE_CONTEXT_FORWARD)); +} +#endif + #ifdef @ATLAS_FEATHERED_STROKE FRAG_DATA_MAIN(float, @atlasStrokeFragmentMain) { VARYING_UNPACK(v_coverages, float4); EMIT_FRAG_DATA(eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD)); } -#endif // @ATLAS_FEATHERED_STROKE +#endif + +#endif #endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/resolve_atlas.glsl b/thirdparty/rive_renderer/source/shaders/resolve_atlas.glsl new file mode 100644 index 000000000..2eb5d9277 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/resolve_atlas.glsl @@ -0,0 +1,93 @@ +/* + * Copyright 2025 Rive + */ + +// This shader provides a mechanism for resolving various atlas types into GL_R8 +// so they can be sampled linearly. +// +// Additionally, EXT_shader_pixel_local_storage extension does not have a +// "clear" function, so this shader also provides a clear mechanism for PLS. + +#ifdef @VERTEX +VERTEX_MAIN(@atlasResolveVertexMain, Attrs, attrs, _vertexID, _instanceID) +{ + // Draw a right triangle that covers the entire screen. + float4 pos; + pos.x = (_vertexID != 2) ? -1. : 3.; + pos.y = (_vertexID != 1) ? -1. : 3.; + pos.zw = float2(.0, 1.); + EMIT_VERTEX(pos); +} +#endif + +#ifdef @FRAGMENT + +INLINE ivec2 atlas_frag_coord() { return ivec2(floor(gl_FragCoord)); } + +#ifdef @ATLAS_RENDER_TARGET_R32UI_FRAMEBUFFER_FETCH + +layout(location = 0) inout uint4 coverageCount; +layout(location = 1) out half4 resolvedCoverage; + +void main() { resolvedCoverage.r = uintBitsToFloat(coverageCount.r); } + +#elif defined(@ATLAS_RENDER_TARGET_R8_PLS_EXT) + +#ifdef @CLEAR_COVERAGE +__pixel_local_outEXT PLS { layout(r32f) float coverageCount; }; +#else +__pixel_local_inEXT PLS { layout(r32f) float coverageCount; }; +layout(location = 0) out half4 resolvedCoverage; +#endif + +void main() +{ +#ifdef @CLEAR_COVERAGE + coverageCount = .0; +#else + resolvedCoverage.r = coverageCount; +#endif +} + +#elif defined(@ATLAS_RENDER_TARGET_R32UI_PLS_ANGLE) + +layout(binding = 0, r32ui) uniform highp upixelLocalANGLE coverageCount; +layout(location = 0) out half4 resolvedCoverage; + +void main() +{ + resolvedCoverage.r = uintBitsToFloat(pixelLocalLoadANGLE(coverageCount).r); +} + +#elif defined(@ATLAS_RENDER_TARGET_R32I_ATOMIC_TEXTURE) + +layout(binding = 0, r32i) uniform highp coherent iimage2D _atlasImage; +layout(location = 0) out half4 resolvedCoverage; + +void main() +{ + resolvedCoverage.r = float(imageLoad(_atlasImage, atlas_frag_coord()).r) * + (1. / ATLAS_R32I_FIXED_POINT_FACTOR); +} + +#elif defined(@ATLAS_RENDER_TARGET_RGBA8_UNORM) + +TEXTURE_RGBA8(PER_FLUSH_BINDINGS_SET, 0, @atlasRenderTexture); +layout(location = 0) out half4 resolvedCoverage; + +void main() +{ + // Apply the following weights to the RGBA of each u8x4 coverage value: + // - R counts fractional, positive coverage. + // - G counts fractional, negative coverage. + // - B counts integer, positive coverage. + // - A counts integer, negative coverage. + half4 coverages = TEXEL_FETCH(@atlasRenderTexture, atlas_frag_coord()); + resolvedCoverage.r = + (coverages.r - coverages.g) * ATLAS_UNORM8_COVERAGE_SCALE_FACTOR + + (coverages.b - coverages.a) * 255.; +} + +#endif + +#endif // FRAGMENT diff --git a/thirdparty/rive_renderer/source/shaders/rhi.glsl b/thirdparty/rive_renderer/source/shaders/rhi.glsl index 84dd4628a..769083e4f 100644 --- a/thirdparty/rive_renderer/source/shaders/rhi.glsl +++ b/thirdparty/rive_renderer/source/shaders/rhi.glsl @@ -46,6 +46,7 @@ #define float2x2 $float2x2 #define half3x3 $half3x3 #define half2x3 $half2x3 +#define half4x4 $half4x4 #endif $typedef float3 packed_float3; @@ -68,7 +69,7 @@ $typedef $uint ushort; #endif // ENABLE_MIN_16_PRECISION -#define SPLAT(A, B) A##B +#define CONCAT(A, B) A##B #define INLINE $inline #define OUT(ARG_TYPE) out ARG_TYPE @@ -77,7 +78,7 @@ $typedef $uint ushort; #define ATTR_BLOCK_BEGIN(NAME) \ struct NAME \ { -#define ATTR(IDX, TYPE, NAME) TYPE NAME : SPLAT(ATTRIBUTE, IDX) +#define ATTR(IDX, TYPE, NAME) TYPE NAME : CONCAT(ATTRIBUTE, IDX) #define ATTR_BLOCK_END \ } \ ; @@ -102,12 +103,20 @@ $typedef $uint ushort; #define NO_PERSPECTIVE $noperspective #define @OPTIONALLY_FLAT $nointerpolation #define FLAT $nointerpolation -#define VARYING(IDX, TYPE, NAME) TYPE NAME : SPLAT($TEXCOORD, IDX) +#define VARYING(IDX, TYPE, NAME) TYPE NAME : CONCAT($TEXCOORD, IDX) +#ifdef @NEEDS_CLIP_DISTANCE #define VARYING_BLOCK_END \ float4 _pos : $SV_Position; \ + float4 _clip : $SV_ClipDistance; \ } \ ; +#else // !@NEEDS_CLIP_DISTANCE +#define VARYING_BLOCK_END \ + float4 _pos : $SV_Position; \ + } \ + ; +#endif // @NEEDS_CLIP_DISTANCE #define VARYING_INIT(NAME, TYPE) TYPE NAME #define VARYING_PACK(NAME) _varyings.NAME = NAME @@ -128,25 +137,33 @@ $typedef $uint ushort; #define TEXTURE_RGBA32UI(SET, IDX, NAME) uniform $Texture2D NAME #define TEXTURE_RGBA32F(SET, IDX, NAME) uniform $Texture2D NAME -#define TEXTURE_RGBA8(SET, IDX, NAME) uniform $Texture2D NAME +#ifdef @SOURCE_TEXTURE_MSAA +#define TEXTURE_RGBA8_MS(SET, IDX, NAME) uniform $Texture2DMS NAME +#endif +#define TEXTURE_RGBA8(SET, IDX, NAME) uniform $Texture2D NAME #define TEXTURE_R16F(SET, IDX, NAME) uniform $Texture2D NAME #define TEXTURE_R16F_1D_ARRAY(SET, IDX, NAME) uniform $Texture2DArray NAME #define SAMPLED_R16F_REF(NAME, SAMPLER_NAME) \ $Texture2D NAME, $SamplerState SAMPLER_NAME #define SAMPLED_R16F(NAME, SAMPLER_NAME) NAME, SAMPLER_NAME -// SAMPLER_LINEAR and SAMPLER_MIPMAP are the same because in d3d11, sampler +// SAMPLER_LINEAR is the same as SAMPLER because in d3d11, sampler // parameters are defined at the API level. -#define SAMPLER(TEXTURE_IDX, NAME) $SamplerState NAME; +#define SAMPLER(IDX, NAME) $SamplerState NAME; #define SAMPLER_LINEAR SAMPLER -#define SAMPLER_MIPMAP SAMPLER -#define SAMPLER_DYNAMIC SAMPLER +#define SAMPLER_DYNAMIC(SET, IDX, NAME) SAMPLER(IDX, NAME) +#define SAMPLER_DYNAMIC_IMAGE(NAME) SAMPLER(IMAGE_TEXTURE_IDX, NAME) +#ifdef SOURCE_TEXTURE_MSAA +#define TEXEL_FETCH_MS(NAME, LEVEL, COORD) NAME.Load(COORD, LEVEL) +#endif #define TEXEL_FETCH(NAME, COORD) NAME[COORD] #define TEXTURE_SAMPLE(NAME, SAMPLER_NAME, COORD) \ NAME.$Sample(SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_LOD(NAME, SAMPLER_NAME, COORD, LOD) \ NAME.$SampleLevel(SAMPLER_NAME, COORD, LOD) +#define TEXTURE_SAMPLE_LODBIAS(NAME, SAMPLER_NAME, COORD, LODBIAS) \ + NAME.$SampleBias(SAMPLER_NAME, COORD, LODBIAS) #define TEXTURE_REF_SAMPLE_LOD TEXTURE_SAMPLE_LOD #define TEXTURE_SAMPLE_GRAD(NAME, SAMPLER_NAME, COORD, DDX, DDY) \ NAME.$SampleGrad(SAMPLER_NAME, COORD, DDX, DDY) @@ -164,6 +181,8 @@ $typedef $uint ushort; TEXTURE_SAMPLE(TEXTURE, SAMPLER_NAME, COORD) #define TEXTURE_SAMPLE_DYNAMIC_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) \ TEXTURE_SAMPLE_LOD(TEXTURE, SAMPLER_NAME, COORD, LOD) +#define TEXTURE_SAMPLE_DYNAMIC_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) \ + TEXTURE_SAMPLE_LODBIAS(TEXTURE, SAMPLER_NAME, COORD, LODBIAS) #define PLS_INTERLOCK_BEGIN #define PLS_INTERLOCK_END @@ -174,7 +193,28 @@ $typedef $uint ushort; #define PLS_TEX2D $RWTexture2D #endif +#if defined(@FRAGMENT) && defined(@RENDER_MODE_MSAA) + +#ifdef @SUPPORTS_SUBPASS_LOAD +#define DST_COLOR_TEXTURE(NAME) \ + [[vk::input_attachment_index(COLOR_PLANE_IDX)]] $SubpassInputMS NAME + +#define DST_COLOR_FETCH(NAME) \ + dst_color_fetch(half4x4(NAME.SubpassLoad(0), \ + NAME.SubpassLoad(1), \ + NAME.SubpassLoad(2), \ + NAME.SubpassLoad(3)), \ + _sampleMask) +#else +#define DST_COLOR_TEXTURE(NAME) $Texture2D NAME + +#define DST_COLOR_FETCH(NAME) NAME[_plsCoord] +#endif +#endif // @FRAGMENT && @RENDER_MODE_MSAA + #define PLS_BLOCK_BEGIN +#define PLS_BLOCK_END + #ifdef @ENABLE_TYPED_UAV_LOAD_STORE #define PLS_DECL4F(IDX, NAME) uniform PLS_TEX2D NAME #else @@ -182,10 +222,19 @@ $typedef $uint ushort; #endif #define PLS_DECL4F_READONLY PLS_DECL4F #define PLS_DECLUI(IDX, NAME) uniform PLS_TEX2D NAME -#define PLS_DECLUI_ATOMIC PLS_DECLUI -#define PLS_LOADUI_ATOMIC PLS_LOADUI -#define PLS_STOREUI_ATOMIC PLS_STOREUI -#define PLS_BLOCK_END + +#define PLS_LOADUI_UAV PLS_LOADUI +#define PLS_STOREUI_UAV PLS_STOREUI + +#if $COMPILER_METAL || $FORCE_ATOMIC_BUFFER +#define PLS_DECLUI_UAV(IDX, NAME) uniform $RWBuffer NAME +#define PLS_LOADUI_UAV(PLANE) PLANE[_plsIdx] +#define PLS_STOREUI_UAV(PLANE, VALUE) PLANE[_plsIdx] = VALUE +#else +#define PLS_DECLUI_UAV PLS_DECLUI +#define PLS_LOADUI_UAV PLS_LOADUI +#define PLS_STOREUI_UAV PLS_STOREUI +#endif // COMPILER_METAL #ifdef @ENABLE_TYPED_UAV_LOAD_STORE #define PLS_LOAD4F(PLANE) PLANE[_plsCoord] @@ -200,6 +249,25 @@ $typedef $uint ushort; #endif #define PLS_STOREUI(PLANE, VALUE) PLANE[_plsCoord] = (VALUE) +#if $COMPILER_METAL || $FORCE_ATOMIC_BUFFER +INLINE uint pls_atomic_max($RWBuffer plane, uint _plsIdx, uint x) +{ + uint originalValue; + $InterlockedMax(plane[_plsIdx], x, originalValue); + return originalValue; +} + +#define PLS_ATOMIC_MAX(PLANE, X) pls_atomic_max(PLANE, _plsIdx, X) + +INLINE uint pls_atomic_add($RWBuffer plane, uint _plsIdx, uint x) +{ + uint originalValue; + $InterlockedAdd(plane[_plsIdx], x, originalValue); + return originalValue; +} + +#define PLS_ATOMIC_ADD(PLANE, X) pls_atomic_add(PLANE, _plsIdx, X) +#else INLINE uint pls_atomic_max(PLS_TEX2D plane, int2 _plsCoord, uint x) { uint originalValue; @@ -217,6 +285,7 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) } #define PLS_ATOMIC_ADD(PLANE, X) pls_atomic_add(PLANE, _plsCoord, X) +#endif #define PLS_PRESERVE_4F(PLANE) #define PLS_PRESERVE_UI(PLANE) @@ -227,13 +296,32 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) #define TEXTURE_CONTEXT_DECL #define TEXTURE_CONTEXT_FORWARD +#ifdef @NO_VARYING + #define VERTEX_MAIN(NAME, Attrs, attrs, _vertexID, _instanceID) \ \ uint $baseInstance; \ \ - Varyings NAME(Attrs attrs, uint _vertexID \ - : $SV_VertexID, uint _instanceIDWithoutBase \ - : $SV_InstanceID) \ + float4 NAME(Attrs attrs, \ + uint _vertexID : $SV_VertexID, \ + uint _instanceIDWithoutBase : $SV_InstanceID) : \ + $SV_Position \ + { \ + uint _instanceID = _instanceIDWithoutBase + $baseInstance; + +#define EMIT_VERTEX(POSITION) \ + return POSITION; \ + } + +#else // !@NO_VARYING + +#define VERTEX_MAIN(NAME, Attrs, attrs, _vertexID, _instanceID) \ + \ + uint $baseInstance; \ + \ + Varyings NAME(Attrs attrs, \ + uint _vertexID : $SV_VertexID, \ + uint _instanceIDWithoutBase : $SV_InstanceID) \ { \ uint _instanceID = _instanceIDWithoutBase + $baseInstance; \ Varyings _varyings; @@ -250,8 +338,9 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) UVAttr, \ uv, \ _vertexID) \ - Varyings NAME(PositionAttr position, UVAttr uv, uint _vertexID \ - : $SV_VertexID) \ + Varyings NAME(PositionAttr position, \ + UVAttr uv, \ + uint _vertexID : $SV_VertexID) \ { \ Varyings _varyings; \ float4 _pos; @@ -260,14 +349,58 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) _varyings._pos = POSITION; \ } \ return _varyings; +#endif // End !@NO_VARYING +// RHI is forced counter clockwise front. So reverse the "isFrontFace" argument +// for clockwise + +#ifdef @NO_VARYING #define FRAG_DATA_MAIN(DATA_TYPE, NAME) \ - DATA_TYPE NAME(Varyings _varyings) : $SV_Target \ - { + $EARLYDEPTHSTENCIL DATA_TYPE NAME(float4 _pos : $SV_Position) : $SV_Target \ + { \ + float2 _fragCoord = _pos.xy; + +#define FRAG_DATA_MAIN_WITH_CLOCKWISE(DATA_TYPE, NAME) \ + EARLYDEPTHSTENCIL DATA_TYPE NAME(float4 _pos : $SV_Position, \ + uint _sampleMask : $SV_Coverage, \ + bool _isFrontFace : $SV_IsFrontFace) : \ + $SV_Target \ + { \ + float2 _fragCoord = _pos.xy; \ + bool _clockwise = !_isFrontFace; +#else +#define FRAG_DATA_MAIN(DATA_TYPE, NAME) \ + $EARLYDEPTHSTENCIL DATA_TYPE NAME(Varyings _varyings, \ + uint _sampleMask : $SV_Coverage) : \ + $SV_Target \ + { \ + float2 _fragCoord = _varyings._pos.xy; \ + int2 _plsCoord = int2(floor(_fragCoord)); \ + uint _plsIdx = _plsCoord.y * uniforms.renderTargetWidth + _plsCoord.x; + +#define FRAG_DATA_MAIN_WITH_CLOCKWISE(DATA_TYPE, NAME) \ + DATA_TYPE NAME(Varyings _varyings, \ + uint _sampleMask : $SV_Coverage, \ + bool _isFrontFace : $SV_IsFrontFace) : \ + $SV_Target \ + { \ + float2 _fragCoord = _varyings._pos.xy; \ + int2 _plsCoord = int2(floor(_fragCoord)); \ + uint _plsIdx = _plsCoord.y * uniforms.renderTargetWidth + _plsCoord.x; \ + bool _clockwise = !_isFrontFace; + +#endif #define EMIT_FRAG_DATA(VALUE) \ return VALUE; \ } +#ifdef @NEEDS_CLIP_DISTANCE +#define CLIP_CONTEXT_FORWARD , out float4 gl_ClipDistance +#define CLIP_CONTEXT_UNPACK , _varyings._clip +#else +#define CLIP_CONTEXT_FORWARD +#define CLIP_CONTEXT_UNPACK +#endif #define FRAGMENT_CONTEXT_DECL , float2 _fragCoord #define FRAGMENT_CONTEXT_UNPACK , _fragCoord @@ -276,20 +409,26 @@ INLINE uint pls_atomic_add(PLS_TEX2D plane, int2 _plsCoord, uint x) #define PLS_CONTEXT_UNPACK , _plsCoord #define PLS_MAIN(NAME) \ - EARLYDEPTHSTENCIL void NAME(Varyings _varyings) \ + $EARLYDEPTHSTENCIL void NAME(Varyings _varyings) \ { \ float2 _fragCoord = _varyings._pos.xy; \ - int2 _plsCoord = int2(floor(_fragCoord)); + int2 _plsCoord = int2(floor(_fragCoord)); \ + uint _plsIdx = _plsCoord.y * uniforms.renderTargetWidth + _plsCoord.x; #define PLS_MAIN_WITH_IMAGE_UNIFORMS(NAME) PLS_MAIN(NAME) +#if defined(@FIXED_FUNCTION_COLOR_OUTPUT) && defined(@DRAW_IMAGE_MESH) +#define EMIT_PLS EMIT_PLS_AND_FRAG_COLOR +#else #define EMIT_PLS } +#endif #define PLS_FRAG_COLOR_MAIN(NAME) \ - EARLYDEPTHSTENCIL half4 NAME(Varyings _varyings) : $SV_Target \ + $EARLYDEPTHSTENCIL half4 NAME(Varyings _varyings) : $SV_Target \ { \ float2 _fragCoord = _varyings._pos.xy; \ int2 _plsCoord = int2(floor(_fragCoord)); \ + uint _plsIdx = _plsCoord.y * uniforms.renderTargetWidth + _plsCoord.x; \ half4 _fragColor; #define PLS_FRAG_COLOR_MAIN_WITH_IMAGE_UNIFORMS(NAME) PLS_FRAG_COLOR_MAIN(NAME) diff --git a/thirdparty/rive_renderer/source/shaders/specialization.glsl b/thirdparty/rive_renderer/source/shaders/specialization.glsl index d2d119e89..b53e6f7f7 100644 --- a/thirdparty/rive_renderer/source/shaders/specialization.glsl +++ b/thirdparty/rive_renderer/source/shaders/specialization.glsl @@ -1,3 +1,5 @@ +#ifndef @SPEC_CONST_NONE + layout(constant_id = CLIPPING_SPECIALIZATION_IDX) const bool kEnableClipping = true; layout(constant_id = CLIP_RECT_SPECIALIZATION_IDX) const @@ -12,10 +14,13 @@ layout(constant_id = NESTED_CLIPPING_SPECIALIZATION_IDX) const bool kEnableNestedClipping = true; layout(constant_id = HSL_BLEND_MODES_SPECIALIZATION_IDX) const bool kEnableHSLBlendModes = true; +layout(constant_id = DITHER_SPECIALIZATION_IDX) const bool kEnableDither = true; layout(constant_id = CLOCKWISE_FILL_SPECIALIZATION_IDX) const bool kClockwiseFill = true; -layout(constant_id = BORROWED_COVERAGE_PREPASS_SPECIALIZATION_IDX) const +layout(constant_id = BORROWED_COVERAGE_PASS_SPECIALIZATION_IDX) const bool kBorrowedCoveragePrepass = true; +layout(constant_id = NESTED_CLIP_UPDATE_ONLY_IDX) const + bool kNestedClipUpdateOnly = true; layout(constant_id = VULKAN_VENDOR_ID_SPECIALIZATION_IDX) const uint kVulkanVendorID = 0; @@ -26,6 +31,26 @@ layout(constant_id = VULKAN_VENDOR_ID_SPECIALIZATION_IDX) const uint #define @ENABLE_EVEN_ODD kEnableEvenOdd #define @ENABLE_NESTED_CLIPPING kEnableNestedClipping #define @ENABLE_HSL_BLEND_MODES kEnableHSLBlendModes +#define @ENABLE_DITHER kEnableDither #define @CLOCKWISE_FILL kClockwiseFill -#define @BORROWED_COVERAGE_PREPASS kBorrowedCoveragePrepass +#define @BORROWED_COVERAGE_PASS kBorrowedCoveragePrepass +#define @NESTED_CLIP_UPDATE_ONLY kNestedClipUpdateOnly #define @VULKAN_VENDOR_ID kVulkanVendorID + +#else + +// Specialization constants aren't supported; just compile an ubershader. +#define @ENABLE_CLIPPING true +#define @ENABLE_CLIP_RECT true +#define @ENABLE_ADVANCED_BLEND true +#define @ENABLE_FEATHER true +#define @ENABLE_EVEN_ODD true +#define @ENABLE_NESTED_CLIPPING true +#define @ENABLE_HSL_BLEND_MODES true +#define @ENABLE_DITHER true +#define @CLOCKWISE_FILL true +#define @BORROWED_COVERAGE_PASS false +#define @NESTED_CLIP_UPDATE_ONLY false +#define @VULKAN_VENDOR_ID 0 + +#endif diff --git a/thirdparty/rive_renderer/source/shaders/spirv/atomic_base.glsl b/thirdparty/rive_renderer/source/shaders/spirv/atomic_base.glsl index decb95e50..42264de40 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/atomic_base.glsl +++ b/thirdparty/rive_renderer/source/shaders/spirv/atomic_base.glsl @@ -1,12 +1,15 @@ #extension GL_EXT_samplerless_texture_functions : require #define ENABLE_INSTANCE_INDEX -#define PLS_IMPL_SUBPASS_LOAD #define USING_PLS_STORAGE_TEXTURES #define PLS_BLEND_SRC_OVER #define OPTIONALLY_FLAT flat #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#ifdef DRAW_IMAGE +#include "image_draw_uniforms.minified.glsl" +#endif #include "common.minified.glsl" #include "advanced_blend.minified.glsl" #include "draw_path_common.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/blit_texture_as_draw.main b/thirdparty/rive_renderer/source/shaders/spirv/blit_texture_as_draw_filtered.main similarity index 67% rename from thirdparty/rive_renderer/source/shaders/spirv/blit_texture_as_draw.main rename to thirdparty/rive_renderer/source/shaders/spirv/blit_texture_as_draw_filtered.main index 75c4ec7a4..65be25024 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/blit_texture_as_draw.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/blit_texture_as_draw_filtered.main @@ -1,6 +1,9 @@ -#version 310 es +#version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require +#define USE_FILTERING #include "glsl.minified.glsl" #include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" #include "blit_texture_as_draw.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/clear_clockwise_atomic_clip.main b/thirdparty/rive_renderer/source/shaders/spirv/clear_clockwise_atomic_clip.main new file mode 100644 index 000000000..d3804f849 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/clear_clockwise_atomic_clip.main @@ -0,0 +1,18 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define RENDER_MODE_CLOCKWISE_ATOMIC + +// This shader doesn't need ENABLE_CLIP_RECT functionality. Disable it so that +// it does not fail to compile on systems without ClipDistance support. +#define DISABLE_CLIP_RECT_FOR_VULKAN_MSAA + +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "clear_clockwise_atomic_clip.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/color_ramp.main b/thirdparty/rive_renderer/source/shaders/spirv/color_ramp.main index 32fc24178..8ed8a8a62 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/color_ramp.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/color_ramp.main @@ -1,6 +1,7 @@ -#version 310 es +#version 460 #extension GL_GOOGLE_include_directive : require #include "glsl.minified.glsl" #include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "color_ramp.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_atlas_blit.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_atlas_blit.main index 111f1a222..1262d72d6 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_atlas_blit.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_atlas_blit.main @@ -1,14 +1,14 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat -#define DRAW_INTERIOR_TRIANGLES #define ATLAS_BLIT #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atlas_blit.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atlas_blit.main index 0d3421154..c2ffbcf72 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atlas_blit.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atlas_blit.main @@ -1,14 +1,15 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require -#define PLS_IMPL_SUBPASS_LOAD +#define ENABLE_INSTANCE_INDEX #define OPTIONALLY_FLAT flat -#define DRAW_INTERIOR_TRIANGLES #define ATLAS_BLIT #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_atlas_blit.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_atlas_blit.main new file mode 100644 index 000000000..179be2a09 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_atlas_blit.main @@ -0,0 +1,16 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define ATLAS_BLIT +#define RENDER_MODE_CLOCKWISE_ATOMIC +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag new file mode 100644 index 000000000..57082b378 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag @@ -0,0 +1,17 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define DRAW_PATH +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_borrowed_coverage.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag new file mode 100644 index 000000000..b173625d1 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag @@ -0,0 +1,16 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define DRAW_INTERIOR_TRIANGLES +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_borrowed_coverage.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip.frag new file mode 100644 index 000000000..766e32521 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip.frag @@ -0,0 +1,17 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define DRAW_PATH +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_clip.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag new file mode 100644 index 000000000..2307dae84 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag @@ -0,0 +1,16 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define DRAW_INTERIOR_TRIANGLES +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_clip.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_image_mesh.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_image_mesh.main new file mode 100644 index 000000000..221a1fe69 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_image_mesh.main @@ -0,0 +1,17 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define DRAW_IMAGE +#define DRAW_IMAGE_MESH +#define RENDER_MODE_CLOCKWISE_ATOMIC +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "image_draw_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_interior_triangles.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_interior_triangles.main new file mode 100644 index 000000000..fbb2437fc --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_interior_triangles.main @@ -0,0 +1,20 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define DRAW_INTERIOR_TRIANGLES +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +#define USING_PLS_STORAGE_TEXTURES +#endif +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" + +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_path.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_path.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_path.main new file mode 100644 index 000000000..de2e24596 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_atomic_path.main @@ -0,0 +1,20 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define DRAW_PATH +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +#ifndef FIXED_FUNCTION_COLOR_OUTPUT +#define USING_PLS_STORAGE_TEXTURES +#endif +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_path.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip.main new file mode 100644 index 000000000..7cf42076d --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip.main @@ -0,0 +1,15 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define DRAW_PATH +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_clip.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip_interior_triangles.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip_interior_triangles.main new file mode 100644 index 000000000..408ab7c1b --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_clip_interior_triangles.main @@ -0,0 +1,14 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define DRAW_INTERIOR_TRIANGLES +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_clip.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_image_mesh.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_image_mesh.main index 7d6a4497b..da7255955 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_image_mesh.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_image_mesh.main @@ -1,13 +1,15 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require -#define ENABLE_INSTANCE_INDEX -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat #define DRAW_IMAGE +#define DRAW_IMAGE_MESH #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "image_draw_uniforms.minified.glsl" #include "common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_image_mesh.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_interior_triangles.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_interior_triangles.main index 1f456a32e..15a111db6 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_interior_triangles.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_interior_triangles.main @@ -1,13 +1,14 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat #define DRAW_INTERIOR_TRIANGLES #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_path.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_path.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_path.main index ba10481b5..cf2e1c075 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_path.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_clockwise_path.main @@ -2,13 +2,14 @@ #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require #define ENABLE_INSTANCE_INDEX -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat #define DRAW_PATH #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_path.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_fullscreen_quad.vert b/thirdparty/rive_renderer/source/shaders/spirv/draw_fullscreen_quad.vert new file mode 100644 index 000000000..56ad4bf1c --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_fullscreen_quad.vert @@ -0,0 +1,7 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_fullscreen_quad.minified.vert" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_image_mesh.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_image_mesh.main index 2c967eebb..da7255955 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_image_mesh.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_image_mesh.main @@ -1,13 +1,15 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat #define DRAW_IMAGE #define DRAW_IMAGE_MESH #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "image_draw_uniforms.minified.glsl" #include "common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_image_mesh.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_input_attachment.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_input_attachment.frag new file mode 100644 index 000000000..f735db283 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_input_attachment.frag @@ -0,0 +1,7 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_input_attachment.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_interior_triangles.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_interior_triangles.main index f8c67dd32..968e82779 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_interior_triangles.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_interior_triangles.main @@ -1,13 +1,14 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat #define DRAW_INTERIOR_TRIANGLES #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_atlas_blit.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_atlas_blit.main new file mode 100644 index 000000000..c8f7d7bfd --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_atlas_blit.main @@ -0,0 +1,16 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define DRAW_INTERIOR_TRIANGLES +#define ATLAS_BLIT +#define RENDER_MODE_MSAA +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_msaa_object.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_color_seed_attachment.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_color_seed_attachment.frag new file mode 100644 index 000000000..f6e124dad --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_color_seed_attachment.frag @@ -0,0 +1,8 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#define INPUT_ATTACHMENT_BINDING 3 // MSAA_COLOR_SEED_IDX +#include "draw_input_attachment.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_image_mesh.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_image_mesh.main new file mode 100644 index 000000000..929bdb9da --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_image_mesh.main @@ -0,0 +1,16 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define DRAW_IMAGE +#define DRAW_IMAGE_MESH +#define RENDER_MODE_MSAA +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "image_draw_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_msaa_object.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_path.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_path.main new file mode 100644 index 000000000..026fc6106 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_path.main @@ -0,0 +1,16 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX +#define OPTIONALLY_FLAT flat +#define DRAW_PATH +#define RENDER_MODE_MSAA +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_msaa_object.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_resolve.frag b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_resolve.frag new file mode 100644 index 000000000..84f519742 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_resolve.frag @@ -0,0 +1,7 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "draw_msaa_resolve.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_stencil.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_stencil.main new file mode 100644 index 000000000..6a1191642 --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_msaa_stencil.main @@ -0,0 +1,17 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_samplerless_texture_functions : require +#define OPTIONALLY_FLAT flat +#define RENDER_MODE_MSAA + +// This shader doesn't need ENABLE_CLIP_RECT functionality. Disable it so that +// it does not fail to compile on systems without ClipDistance support. +#define DISABLE_CLIP_RECT_FOR_VULKAN_MSAA + +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" +#include "common.minified.glsl" +#include "advanced_blend.minified.glsl" +#include "stencil_draw.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/draw_path.main b/thirdparty/rive_renderer/source/shaders/spirv/draw_path.main index f40514243..dd2cda8b1 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/draw_path.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/draw_path.main @@ -2,13 +2,14 @@ #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require #define ENABLE_INSTANCE_INDEX -#define PLS_IMPL_SUBPASS_LOAD #define OPTIONALLY_FLAT flat #define DRAW_PATH #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_raster_order_path.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/init_clockwise_atomic_workaround.frag b/thirdparty/rive_renderer/source/shaders/spirv/init_clockwise_atomic_workaround.frag new file mode 100644 index 000000000..33769a89a --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv/init_clockwise_atomic_workaround.frag @@ -0,0 +1,11 @@ +#version 460 +#extension GL_GOOGLE_include_directive : require +#define RENDER_MODE_CLOCKWISE_ATOMIC +// This shader doesn't need ENABLE_CLIP_RECT functionality. Disable it so that +// it does not fail to compile on systems without ClipDistance support. +#define DISABLE_CLIP_RECT_FOR_VULKAN_MSAA +#include "glsl.minified.glsl" +#include "constants.minified.glsl" +#include "common.minified.glsl" +#include "draw_path_common.minified.glsl" +#include "init_clockwise_atomic_workaround.minified.frag" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas.vert b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas.vert index 3a32a5560..1a239a7eb 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas.vert +++ b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas.vert @@ -1,3 +1,3 @@ -#version 310 es +#version 460 #extension GL_GOOGLE_include_directive : require #include "render_atlas_common.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_common.glsl b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_common.glsl index cfa869737..ea0f16533 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_common.glsl +++ b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_common.glsl @@ -5,6 +5,7 @@ #define ENABLE_FEATHER true #include "glsl.minified.glsl" #include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "render_atlas.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_fill.frag b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_fill.frag index 57f14b3fb..5f19335d8 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_fill.frag +++ b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_fill.frag @@ -1,4 +1,4 @@ -#version 310 es +#version 460 #extension GL_GOOGLE_include_directive : require #define ATLAS_FEATHERED_FILL #include "render_atlas_common.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_stroke.frag b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_stroke.frag index b165ee39a..9089568c6 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_stroke.frag +++ b/thirdparty/rive_renderer/source/shaders/spirv/render_atlas_stroke.frag @@ -1,4 +1,4 @@ -#version 310 es +#version 460 #extension GL_GOOGLE_include_directive : require #define ATLAS_FEATHERED_STROKE #include "render_atlas_common.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv/tessellate.main b/thirdparty/rive_renderer/source/shaders/spirv/tessellate.main index 49ec88173..ef3f553dc 100644 --- a/thirdparty/rive_renderer/source/shaders/spirv/tessellate.main +++ b/thirdparty/rive_renderer/source/shaders/spirv/tessellate.main @@ -1,8 +1,9 @@ -#version 310 es +#version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require #include "glsl.minified.glsl" #include "constants.minified.glsl" +#include "flush_uniforms.minified.glsl" #include "common.minified.glsl" #include "bezier_utils.minified.glsl" #include "tessellate.minified.glsl" diff --git a/thirdparty/rive_renderer/source/shaders/spirv_binary_to_header.py b/thirdparty/rive_renderer/source/shaders/spirv_binary_to_header.py new file mode 100644 index 000000000..0daf1fdac --- /dev/null +++ b/thirdparty/rive_renderer/source/shaders/spirv_binary_to_header.py @@ -0,0 +1,29 @@ +# This is a little utility to take a SPIR-V binary file and turn it into a header file +import struct +import sys + +if (len(sys.argv) != 4): + print("Usage: python binary_to_header.py ") + sys.exit(1) + +inPath = sys.argv[1] +outPath = sys.argv[2] +arrayName = sys.argv[3] + +# Read the entire file in as binary then convert it into an array of integers +with open(inPath, "rb") as file: + binaryData = file.read() +if (len(binaryData) % 4 != 0): + printf("ERROR: Shader binary length was expected to be a multiple of 32 bits") + sys.exit(1) +data = struct.unpack(f"<{len(binaryData)//4}I", binaryData) + +with open(outPath, "w") as file: + file.write("#pragma once\n\n") + file.write(f"const uint32_t {arrayName}[] = {{") + for i,val in enumerate(data): + # Add newlines (and indents) every 8 elements + if (i % 8 == 0): + file.write("\n ") + file.write(f"{val:#010x},") + file.write("\n};\n") \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/stencil_draw.glsl b/thirdparty/rive_renderer/source/shaders/stencil_draw.glsl index 0b065e0d6..583255861 100644 --- a/thirdparty/rive_renderer/source/shaders/stencil_draw.glsl +++ b/thirdparty/rive_renderer/source/shaders/stencil_draw.glsl @@ -15,6 +15,7 @@ VERTEX_STORAGE_BUFFER_BLOCK_END VERTEX_MAIN(@stencilVertexMain, Attrs, attrs, _vertexID, _instanceID) { + ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, packed_float3); float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(@a_triangleVertex.xy); uint zIndex = floatBitsToUint(@a_triangleVertex.z) & 0xffffu; pos.z = normalize_z_index(zIndex); diff --git a/thirdparty/rive_renderer/source/shaders/tessellate.glsl b/thirdparty/rive_renderer/source/shaders/tessellate.glsl index e5c3eb2e0..63a838fe7 100644 --- a/thirdparty/rive_renderer/source/shaders/tessellate.glsl +++ b/thirdparty/rive_renderer/source/shaders/tessellate.glsl @@ -14,10 +14,9 @@ #ifdef @VERTEX ATTR_BLOCK_BEGIN(Attrs) -ATTR( - 0, - float4, - @a_p0p1_); // End in '_' because D3D interprets the '1' as a semantic index. +// RHI Version > 5.8 failes to parse this when it's multi line +// End in '_' because D3D interprets the '1' as a semantic index. +ATTR(0, float4, @a_p0p1_); ATTR(1, float4, @a_p2p3_); ATTR(2, float4, @a_joinTan_and_ys); // [joinTangent, y, reflectionY] #ifdef SPLIT_UINT4_ATTRIBUTES @@ -125,11 +124,17 @@ VERTEX_MAIN(@tessellateVertexMain, Attrs, attrs, _vertexID, _instanceID) uint polarSegmentCount = (@a_args.z >> 10) & 0x3ffu; uint joinSegmentCount = @a_args.z >> 20; uint contourIDWithFlags = @a_args.w; + uint contourID = contourIDWithFlags & CONTOUR_ID_MASK; uint pathID = - contourIDWithFlags != INVALID_CONTOUR_ID_WITH_FLAGS - ? STORAGE_BUFFER_LOAD4(@contourBuffer, - contour_data_idx(contourIDWithFlags)) - .z + contourID > 0u + // Clamp contourID at 1, even though this is the expression + // of "contourID > 0u", and even though GLSL specifies short-circuit + // evaluation for the ternary operator. + // + // PowerVR (B-Series BXM-8-256, build 1.15) appears to evaluate this + // expression unconditionally, leading to a load at buffer index + // 0xffffffff when contourID == 0, which crashes the render pass. + ? STORAGE_BUFFER_LOAD4(@contourBuffer, max(contourID, 1u) - 1u).z : 0u; uint4 pathData = pathID != 0u ? STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 1u) @@ -197,7 +202,6 @@ VERTEX_MAIN(@tessellateVertexMain, Attrs, attrs, _vertexID, _instanceID) float2x2 mat = make_float2x2( uintBitsToFloat(STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u))); float2 d0 = MUL(mat, -2. * p1 + p2 + p0); - float2 d1 = MUL(mat, -2. * p2 + p3 + p1); float m = max(dot(d0, d0), dot(d1, d1)); float n = max(ceil(sqrt(.75 * 4. * sqrt(m))), 1.); @@ -265,6 +269,9 @@ VERTEX_MAIN(@tessellateVertexMain, Attrs, attrs, _vertexID, _instanceID) float4 pos = pixel_coord_to_clip_coord(coord, 2. / TESS_TEXTURE_WIDTH, uniforms.tessInverseViewportY); +#ifdef @POST_INVERT_Y + pos.y = -pos.y; +#endif VARYING_PACK(v_p0p1); VARYING_PACK(v_p2p3); diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_base.ush b/thirdparty/rive_renderer/source/shaders/unreal/atomic_base.ush deleted file mode 100644 index d0f8ee43b..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_base.ush +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#define USING_PLS_STORAGE_TEXTURES 1 -#define OPTIONALLY_FLAT flat - -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif -#include "parse_environment.ush" -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/advanced_blend.minified.ush" -#include "Generated/draw_path_common.minified.ush" -#include "Generated/atomic_draw.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_atlas_blit.usf b/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_atlas_blit.usf deleted file mode 100644 index 0773cf38f..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_atlas_blit.usf +++ /dev/null @@ -1,4 +0,0 @@ -#define DRAW_INTERIOR_TRIANGLES -#define ATLAS_BLIT -#include "/Engine/Public/Platform.ush" -#include "atomic_base.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_mesh.usf b/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_mesh.usf deleted file mode 100644 index 8eb85eda4..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_mesh.usf +++ /dev/null @@ -1,4 +0,0 @@ -#define DRAW_IMAGE -#define DRAW_IMAGE_MESH -#include "/Engine/Public/Platform.ush" -#include "atomic_base.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_rect.usf b/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_rect.usf deleted file mode 100644 index 36fb1673c..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_image_rect.usf +++ /dev/null @@ -1,4 +0,0 @@ -#define DRAW_IMAGE -#define DRAW_IMAGE_RECT -#include "/Engine/Public/Platform.ush" -#include "atomic_base.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_interior_triangles.usf b/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_interior_triangles.usf deleted file mode 100644 index c883d718c..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_interior_triangles.usf +++ /dev/null @@ -1,3 +0,0 @@ -#define DRAW_INTERIOR_TRIANGLES -#include "/Engine/Public/Platform.ush" -#include "atomic_base.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_path.usf b/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_path.usf deleted file mode 100644 index b0c74527c..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_draw_path.usf +++ /dev/null @@ -1,3 +0,0 @@ -#define DRAW_PATH -#include "/Engine/Public/Platform.ush" -#include "atomic_base.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/atomic_resolve_pls.usf b/thirdparty/rive_renderer/source/shaders/unreal/atomic_resolve_pls.usf deleted file mode 100644 index 62da1f340..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/atomic_resolve_pls.usf +++ /dev/null @@ -1,4 +0,0 @@ -#define DRAW_RENDER_TARGET_UPDATE_BOUNDS 1 -#define RESOLVE_PLS 1 -#include "/Engine/Public/Platform.ush" -#include "atomic_base.ush" \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/shaders/unreal/blt_u324_to_f4.usf b/thirdparty/rive_renderer/source/shaders/unreal/blt_u324_to_f4.usf deleted file mode 100644 index f28c12d0b..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/blt_u324_to_f4.usf +++ /dev/null @@ -1,9 +0,0 @@ -#include "/Engine/Public/Platform.ush" -Texture2D SourceTexture; - -void FragmentMain( in float4 Position : SV_Position, - out float4 OutColor : SV_Target0) -{ - uint4 Result = SourceTexture[Position.xy]; - OutColor = float4( float(Result.r), float(Result.g), float(Result.b), 1.0 ); -} diff --git a/thirdparty/rive_renderer/source/shaders/unreal/blt_u32_as_f4.usf b/thirdparty/rive_renderer/source/shaders/unreal/blt_u32_as_f4.usf deleted file mode 100644 index 2bbbee50e..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/blt_u32_as_f4.usf +++ /dev/null @@ -1,9 +0,0 @@ -#include "/Engine/Public/Platform.ush" -Texture2D SourceTexture; - -void FragmentMain( in float4 Position : SV_Position, - out float4 OutColor : SV_Target0) -{ - uint Result = SourceTexture[Position.xy]; - OutColor = float4( Result, 0, 0, 1.0 ); -} diff --git a/thirdparty/rive_renderer/source/shaders/unreal/color_ramp.usf b/thirdparty/rive_renderer/source/shaders/unreal/color_ramp.usf deleted file mode 100644 index e28095a29..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/color_ramp.usf +++ /dev/null @@ -1,12 +0,0 @@ -#include "/Engine/Public/Platform.ush" -#define SPLIT_UINT4_ATTRIBUTES 1 - -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "parse_environment.ush" -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/color_ramp.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_fill.usf b/thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_fill.usf deleted file mode 100644 index 569178729..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_fill.usf +++ /dev/null @@ -1,14 +0,0 @@ -#include "/Engine/Public/Platform.ush" -#define DRAW_PATH -#define ENABLE_FEATHER -#define ATLAS_FEATHERED_FILL - -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/draw_path_common.minified.ush" -#include "Generated/render_atlas.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_stroke.usf b/thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_stroke.usf deleted file mode 100644 index 57f6d39a1..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/draw_atlas_stroke.usf +++ /dev/null @@ -1,14 +0,0 @@ -#include "/Engine/Public/Platform.ush" -#define DRAW_PATH -#define ENABLE_FEATHER -#define ATLAS_FEATHERED_STROKE - -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/draw_path_common.minified.ush" -#include "Generated/render_atlas.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/draw_image_mesh.usf b/thirdparty/rive_renderer/source/shaders/unreal/draw_image_mesh.usf deleted file mode 100644 index fd491170a..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/draw_image_mesh.usf +++ /dev/null @@ -1,17 +0,0 @@ -#define PLS_IMPL_SUBPASS_LOAD -#define OPTIONALLY_FLAT flat -#define DRAW_IMAGE -#define DRAW_IMAGE_MESH - -#include "/Engine/Public/Platform.ush" -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "parse_environment.ush" -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/specialization.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/advanced_blend.minified.ush" -#include "Generated/draw_image_mesh.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/draw_interior_triangles.usf b/thirdparty/rive_renderer/source/shaders/unreal/draw_interior_triangles.usf deleted file mode 100644 index 86984350b..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/draw_interior_triangles.usf +++ /dev/null @@ -1,16 +0,0 @@ -#define PLS_IMPL_SUBPASS_LOAD -#define OPTIONALLY_FLAT flat -#define DRAW_INTERIOR_TRIANGLES - -#include "/Engine/Public/Platform.ush" -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "parse_environment.ush" -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/draw_path_common.minified.ush" -#include "Generated/advanced_blend.minified.ush" -#include "Generated/draw_path.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/draw_path.usf b/thirdparty/rive_renderer/source/shaders/unreal/draw_path.usf deleted file mode 100644 index 888ce2fc0..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/draw_path.usf +++ /dev/null @@ -1,17 +0,0 @@ -#define ENABLE_INSTANCE_INDEX -#define PLS_IMPL_SUBPASS_LOAD -#define OPTIONALLY_FLAT flat -#define DRAW_PATH - -#include "/Engine/Public/Platform.ush" -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "parse_environment.ush" -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/draw_path_common.minified.ush" -#include "Generated/advanced_blend.minified.ush" -#include "Generated/draw_path.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/parse_environment.ush b/thirdparty/rive_renderer/source/shaders/unreal/parse_environment.ush deleted file mode 100644 index 50348ce02..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/parse_environment.ush +++ /dev/null @@ -1,41 +0,0 @@ -// unreal rhi always defines the permutation values, however, we expect them to either exist or not. so -// here we check if its set to false and undef if it is -#if !ENABLE_CLIPPING -#undef ENABLE_CLIPPING -#endif - -#if !ENABLE_CLIP_RECT -#undef ENABLE_CLIP_RECT -#endif - -#if !ENABLE_ADVANCED_BLEND -#undef ENABLE_ADVANCED_BLEND -#endif - -#if !FIXED_FUNCTION_COLOR_OUTPUT -#undef FIXED_FUNCTION_COLOR_OUTPUT -#endif - -#if !ENABLE_HSL_BLEND_MODES -#undef ENABLE_HSL_BLEND_MODES -#endif - -#if !ENABLE_NESTED_CLIPPING -#undef ENABLE_NESTED_CLIPPING -#endif - -#if !ENABLE_EVEN_ODD -#undef ENABLE_EVEN_ODD -#endif - -#if !ENABLE_TYPED_UAV_LOAD_STORE -#undef ENABLE_TYPED_UAV_LOAD_STORE -#endif - -#if !ENABLE_FEATHER -#undef ENABLE_FEATHER -#endif - -#if !ATLAS_COVERAGE -#undef ATLAS_COVERAGE -#endif diff --git a/thirdparty/rive_renderer/source/shaders/unreal/tessellate.usf b/thirdparty/rive_renderer/source/shaders/unreal/tessellate.usf deleted file mode 100644 index 99f178fb5..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/tessellate.usf +++ /dev/null @@ -1,13 +0,0 @@ -#include "/Engine/Public/Platform.ush" -#define SPLIT_UINT4_ATTRIBUTES 1 - -#ifdef UNIFORM_DEFINITIONS_AUTO_GENERATED -#include "/Engine/Generated/GeneratedUniformBuffers.ush" -#endif - -#include "parse_environment.ush" -#include "Generated/rhi.minified.ush" -#include "Generated/constants.minified.ush" -#include "Generated/common.minified.ush" -#include "Generated/bezier_utils.minified.ush" -#include "Generated/tessellate.minified.ush" diff --git a/thirdparty/rive_renderer/source/shaders/unreal/visualize_buffer.usf b/thirdparty/rive_renderer/source/shaders/unreal/visualize_buffer.usf deleted file mode 100644 index b1ce7a470..000000000 --- a/thirdparty/rive_renderer/source/shaders/unreal/visualize_buffer.usf +++ /dev/null @@ -1,23 +0,0 @@ -#include "/Engine/Public/Platform.ush" -StructuredBuffer SourceBuffer; - -uint2 ViewSize; -uint BufferSize; - -inline float usin(uint v) -{ - return (sin(float(v)) + 1.0) / 2.0; -} - -inline float ucos(uint v) -{ - return (cos(float(v)) + 1.0) / 2.0; -} - -void FragmentMain( in float4 Position : SV_Position, - out float4 OutColor : SV_Target0) -{ - float index = (((Position.y * ViewSize.g) + Position.y) / (ViewSize.r * ViewSize.g)) * BufferSize; - uint2 Result = SourceBuffer[index]; - OutColor = float4( ucos(Result.r), usin(Result.g), 0, 1.0 ); -} \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/sk_rectanizer_skyline.cpp b/thirdparty/rive_renderer/source/sk_rectanizer_skyline.cpp index 36c325249..598510c84 100644 --- a/thirdparty/rive_renderer/source/sk_rectanizer_skyline.cpp +++ b/thirdparty/rive_renderer/source/sk_rectanizer_skyline.cpp @@ -15,9 +15,8 @@ #include #include -namespace skgpu +namespace rive { - bool RectanizerSkyline::addRect(int width, int height, int16_t* x, int16_t* y) { if ((unsigned)width > (unsigned)this->width() || @@ -151,5 +150,4 @@ void RectanizerSkyline::addSkylineLevel(int skylineIndex, } } } - -} // End of namespace skgpu +} // End of namespace rive diff --git a/thirdparty/rive_renderer/source/sort_key_builder.hpp b/thirdparty/rive_renderer/source/sort_key_builder.hpp new file mode 100644 index 000000000..8aa91042a --- /dev/null +++ b/thirdparty/rive_renderer/source/sort_key_builder.hpp @@ -0,0 +1,220 @@ +#pragma once + +#include "rive/renderer.hpp" +#include "rive/renderer/gpu.hpp" + +#include + +// Unit tests override RIVE_ENABLE_SORT_KEY_VALIDATION to enable it even in +// release builds so we can always test validation. +#if !defined(RIVE_ENABLE_SORT_KEY_VALIDATION) +#if defined(NDEBUG) +#define RIVE_ENABLE_SORT_KEY_VALIDATION 0 +#else +#define RIVE_ENABLE_SORT_KEY_VALIDATION 1 +#endif +#endif + +namespace rive::gpu +{ +// The order of the values in the enum does not matter - the prioritization +// order is set at SortKeyBuilder construction time. +enum class SortEntry +{ + blendMode, + drawContents, + drawIndex, + drawGroup, + drawType, + subpassIndex, + textureHash, +}; +constexpr uint32_t SORT_ENTRY_COUNT = 7; + +namespace internal +{ +// Note: this function is not constexpr, specifically so that compilation will +// fail when called at compile time. If it is called at runtime, it will assert +// with the given message. +inline void FailConstexpr(const char* message) +{ +// the unit tests declare this macro so we can catch test failures more cleanly. +#ifdef TESTING_ASSERT + TESTING_ASSERT(false, message); +#else + assert(false && message); +#endif +} +} // namespace internal + +// Make an "assert" that will cause constexpr compilation to fail if the +// condition is false (regardless of whether asserts are enabled or not) +// This will work like an assert at runtime. +#define RIVE_CONSTEXPR_CHECK(v, message) \ + do \ + { \ + if (!(v)) \ + { \ + internal::FailConstexpr(message); \ + } \ + } while (false) + +enum class ValidateKeyEntry : bool +{ + no, + yes, +}; + +// Helper class to build the draw sort key for the render context. It is +// intended to be initialized at compile time, which will pre-bake the masks and +// shifts for each element into compile-time constants (rather than buliding +// them up at runtime) +class SortKeyBuilder +{ +public: + struct Initializer + { + SortEntry entry; + uint32_t bitCount; + }; + + struct Value + { + // Allow constructing a Value with any type (that can cast to uint64_t) + template + constexpr Value(SortEntry e, + T v, + ValidateKeyEntry vk = ValidateKeyEntry::yes) : + entry(e), value(uint64_t(v)), validate(vk) + {} + + SortEntry entry; + uint64_t value; + ValidateKeyEntry validate; + }; + + constexpr SortKeyBuilder(const std::initializer_list& init) + { + std::array isSpecified{}; + uint32_t currentBitCount = 0; + + // These are in priority order so iterate from last to first (the lowest + // priority bits are shifted the least) + for (auto iter = rbegin(init); iter != rend(init); ++iter) + { + auto& e = *iter; + auto i = int(e.entry); + RIVE_CONSTEXPR_CHECK(!isSpecified[i], "SortEntry specified twice"); + isSpecified[i] = true; + + if (e.bitCount != 0) + { + m_elements[i].mask = ((1ull << e.bitCount) - 1) + << currentBitCount; + m_elements[i].shift = currentBitCount; + } + + currentBitCount += e.bitCount; + RIVE_CONSTEXPR_CHECK(e.bitCount <= 63, + "More than 63 bits were specified"); + RIVE_CONSTEXPR_CHECK(currentBitCount <= 63, + "More than 63 bits were specified"); + } + + for (auto b : isSpecified) + { + RIVE_CONSTEXPR_CHECK(b, "Missing SortEntry"); + } + + RIVE_CONSTEXPR_CHECK(currentBitCount > 0, "No bits specified"); + } + + // Build a key, but don't require every element to be specified. + constexpr uint64_t buildPartialKey( + const std::initializer_list& values) const + { + RIVE_CONSTEXPR_CHECK(values.size() > 0, + "No values specified to add to key"); + uint64_t key = 0; + for (const auto& value : values) + { + const auto m = mask(value.entry); + const auto s = shift(value.entry); + RIVE_CONSTEXPR_CHECK((key & m) == 0, + "Same value added multiple times"); + key |= (value.value << s) & m; + +#if RIVE_ENABLE_SORT_KEY_VALIDATION + if (value.validate == ValidateKeyEntry::yes && m != 0) + { + auto extracted = (key & m) >> s; + RIVE_CONSTEXPR_CHECK(extracted == value.value, + "Not enough bits to store given value"); + } +#endif + } + + return key; + } + + // Build a key, requiring every member of SortEntry to be specified once. + constexpr uint64_t buildKey( + const std::initializer_list& values) const + { +#if RIVE_ENABLE_SORT_KEY_VALIDATION + std::array isSpecified{}; + for (auto& v : values) + { + RIVE_CONSTEXPR_CHECK(!isSpecified[int(v.entry)], + "SortEntry specified multiple times"); + isSpecified[int(v.entry)] = true; + } + + for (auto b : isSpecified) + { + RIVE_CONSTEXPR_CHECK(b, "Missing SortEntry while building key"); + } +#endif + return buildPartialKey(values); + } + + // Pull the given value out of a key + template + T extract(SortEntry entry, uint64_t key) const + { + if constexpr (std::is_enum_v) + { + return T(extract>(entry, key)); + } + else + { + return math::lossless_numeric_cast((key & mask(entry)) >> + shift(entry)); + } + } + + constexpr uint64_t mask(SortEntry e) const + { + return m_elements[int(e)].mask; + } + + constexpr uint64_t shift(SortEntry e) const + { + return m_elements[int(e)].shift; + } + +private: + struct Element + { + uint64_t mask; + uint32_t shift; + }; + + std::array m_elements{}; +}; + +#undef RIVE_KEY_ENTRIES +#undef RIVE_CONSTEXPR_ASSERT +#undef RIVE_ENABLE_SORT_KEY_VALIDATION + +} // namespace rive::gpu \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/vulkan/common_layouts.hpp b/thirdparty/rive_renderer/source/vulkan/common_layouts.hpp new file mode 100644 index 000000000..c21fecd81 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/common_layouts.hpp @@ -0,0 +1,200 @@ +#include "rive/renderer/gpu.hpp" +#include "rive/renderer/vulkan/vkutil.hpp" +#include "shaders/constants.glsl" +#include + +// Common layout descriptors shared by various pipelines. +namespace rive::gpu::layout +{ +// rasterOrdering mode with a non-input-attachment renderTarget currently +// requires the most attachments in a single pass: all 4 PLS planes plus one +// more resolve target. +constexpr static uint32_t MAX_RENDER_PASS_ATTACHMENTS = PLS_PLANE_COUNT + 1; + +constexpr VkVertexInputBindingDescription PATH_INPUT_BINDINGS[] = {{ + .binding = 0, + .stride = sizeof(rive::gpu::PatchVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, +}}; +constexpr VkVertexInputAttributeDescription PATH_VERTEX_ATTRIBS[] = { + { + .location = 0, + .binding = 0, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = 0, + }, + { + .location = 1, + .binding = 0, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = 4 * sizeof(float), + }, +}; +constexpr VkPipelineVertexInputStateCreateInfo PATH_VERTEX_INPUT_STATE = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = std::size(PATH_INPUT_BINDINGS), + .pVertexBindingDescriptions = PATH_INPUT_BINDINGS, + .vertexAttributeDescriptionCount = std::size(PATH_VERTEX_ATTRIBS), + .pVertexAttributeDescriptions = PATH_VERTEX_ATTRIBS, +}; + +constexpr VkVertexInputBindingDescription INTERIOR_TRI_INPUT_BINDINGS[] = {{ + .binding = 0, + .stride = sizeof(rive::gpu::TriangleVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, +}}; +constexpr VkVertexInputAttributeDescription INTERIOR_TRI_VERTEX_ATTRIBS[] = { + { + .location = 0, + .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = 0, + }, +}; +constexpr VkPipelineVertexInputStateCreateInfo INTERIOR_TRI_VERTEX_INPUT_STATE = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = std::size(INTERIOR_TRI_INPUT_BINDINGS), + .pVertexBindingDescriptions = INTERIOR_TRI_INPUT_BINDINGS, + .vertexAttributeDescriptionCount = + std::size(INTERIOR_TRI_VERTEX_ATTRIBS), + .pVertexAttributeDescriptions = INTERIOR_TRI_VERTEX_ATTRIBS, +}; + +constexpr VkVertexInputBindingDescription IMAGE_RECT_INPUT_BINDINGS[] = {{ + .binding = 0, + .stride = sizeof(rive::gpu::ImageRectVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, +}}; +constexpr VkVertexInputAttributeDescription IMAGE_RECT_VERTEX_ATTRIBS[] = { + { + .location = 0, + .binding = 0, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = 0, + }, +}; +constexpr VkPipelineVertexInputStateCreateInfo IMAGE_RECT_VERTEX_INPUT_STATE = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = std::size(IMAGE_RECT_INPUT_BINDINGS), + .pVertexBindingDescriptions = IMAGE_RECT_INPUT_BINDINGS, + .vertexAttributeDescriptionCount = std::size(IMAGE_RECT_VERTEX_ATTRIBS), + .pVertexAttributeDescriptions = IMAGE_RECT_VERTEX_ATTRIBS, +}; + +constexpr VkVertexInputBindingDescription IMAGE_MESH_INPUT_BINDINGS[] = { + { + .binding = 0, + .stride = sizeof(float) * 2, + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }, + { + .binding = 1, + .stride = sizeof(float) * 2, + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }, +}; +constexpr VkVertexInputAttributeDescription IMAGE_MESH_VERTEX_ATTRIBS[] = { + { + .location = 0, + .binding = 0, + .format = VK_FORMAT_R32G32_SFLOAT, + .offset = 0, + }, + { + .location = 1, + .binding = 1, + .format = VK_FORMAT_R32G32_SFLOAT, + .offset = 0, + }, +}; +constexpr VkPipelineVertexInputStateCreateInfo IMAGE_MESH_VERTEX_INPUT_STATE = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = std::size(IMAGE_MESH_INPUT_BINDINGS), + .pVertexBindingDescriptions = IMAGE_MESH_INPUT_BINDINGS, + .vertexAttributeDescriptionCount = std::size(IMAGE_MESH_VERTEX_ATTRIBS), + .pVertexAttributeDescriptions = IMAGE_MESH_VERTEX_ATTRIBS, +}; + +constexpr VkPipelineVertexInputStateCreateInfo EMPTY_VERTEX_INPUT_STATE = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = 0, + .vertexAttributeDescriptionCount = 0, +}; + +constexpr VkPipelineInputAssemblyStateCreateInfo INPUT_ASSEMBLY_TRIANGLE_STRIP = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, +}; + +constexpr VkPipelineInputAssemblyStateCreateInfo INPUT_ASSEMBLY_TRIANGLE_LIST = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, +}; + +constexpr VkPipelineViewportStateCreateInfo SINGLE_VIEWPORT = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1, + .scissorCount = 1, +}; + +constexpr VkPipelineRasterizationStateCreateInfo RASTER_STATE_CULL_BACK_CCW = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .lineWidth = 1.f, +}; + +constexpr VkPipelineRasterizationStateCreateInfo RASTER_STATE_CULL_BACK_CW = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .lineWidth = 1.f, +}; + +constexpr VkPipelineRasterizationStateCreateInfo RASTER_STATE_CULL_NONE_CW = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .lineWidth = 1.f, +}; + +constexpr VkPipelineMultisampleStateCreateInfo MSAA_DISABLED = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, +}; + +constexpr VkPipelineColorBlendAttachmentState BLEND_DISABLED_VALUES = { + .colorWriteMask = rive::gpu::vkutil::kColorWriteMaskRGBA}; +constexpr VkPipelineColorBlendStateCreateInfo SINGLE_ATTACHMENT_BLEND_DISABLED = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &BLEND_DISABLED_VALUES, +}; + +constexpr VkDynamicState DYNAMIC_VIEWPORT_SCISSOR_VALUES[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, +}; +constexpr VkPipelineDynamicStateCreateInfo DYNAMIC_VIEWPORT_SCISSOR = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = std::size(DYNAMIC_VIEWPORT_SCISSOR_VALUES), + .pDynamicStates = DYNAMIC_VIEWPORT_SCISSOR_VALUES, +}; + +constexpr VkAttachmentReference SINGLE_ATTACHMENT_SUBPASS_REFERENCE = { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, +}; +constexpr VkSubpassDescription SINGLE_ATTACHMENT_SUBPASS = { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1, + .pColorAttachments = &SINGLE_ATTACHMENT_SUBPASS_REFERENCE, +}; +} // namespace rive::gpu::layout diff --git a/thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.cpp b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.cpp new file mode 100644 index 000000000..6b54fd6d5 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.cpp @@ -0,0 +1,176 @@ +/* + * Copyright 2025 Rive + */ + +#include "draw_pipeline_layout_vulkan.hpp" + +#include "rive/renderer/stack_vector.hpp" +#include "rive/renderer/vulkan/vulkan_context.hpp" +#include "rive/renderer/vulkan/render_context_vulkan_impl.hpp" +#include "shaders/constants.glsl" +#include "pipeline_manager_vulkan.hpp" + +namespace rive::gpu +{ +DrawPipelineLayoutVulkan::DrawPipelineLayoutVulkan( + PipelineManagerVulkan* pipelineManager, + gpu::InterlockMode interlockMode, + RenderPassOptionsVulkan renderPassOptions) : + m_vk(ref_rcp(pipelineManager->vulkanContext())), + m_interlockMode(interlockMode), + m_renderPassOptions(renderPassOptions) +{ + const bool fixedFunctionColorOutput = + enums::is_flag_set(m_renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput); + + // PLS planes get bound per flush as input attachments or storage + // textures. + const VkDescriptorType plsDescriptorType = + (pipelineManager->plsBackingType(interlockMode) == + PipelineManagerVulkan::PLSBackingType::storageTexture) + ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + : VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + + StackVector + plsLayoutBindings; + + if (!fixedFunctionColorOutput) + { + plsLayoutBindings.push_back({ + .binding = COLOR_PLANE_IDX, + .descriptorType = plsDescriptorType, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }); + } + + if (interlockMode != gpu::InterlockMode::msaa) + { + plsLayoutBindings.push_back({ + .binding = CLIP_PLANE_IDX, + .descriptorType = plsDescriptorType, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }); + } + + if (interlockMode == gpu::InterlockMode::rasterOrdering || + ((interlockMode == gpu::InterlockMode::clockwise || + interlockMode == gpu::InterlockMode::clockwiseAtomic) && + !fixedFunctionColorOutput)) + { + plsLayoutBindings.push_back({ + .binding = SCRATCH_COLOR_PLANE_IDX, + .descriptorType = + (interlockMode == gpu::InterlockMode::clockwiseAtomic) + ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + : plsDescriptorType, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }); + } + + if (interlockMode == gpu::InterlockMode::rasterOrdering || + interlockMode == gpu::InterlockMode::atomics || + interlockMode == gpu::InterlockMode::clockwise) + { + plsLayoutBindings.push_back({ + .binding = COVERAGE_PLANE_IDX, + .descriptorType = m_interlockMode == gpu::InterlockMode::atomics + ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + : plsDescriptorType, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }); + } + else if (interlockMode == gpu::InterlockMode::msaa) + { + // TODO: pipeline layouts aren't currently keyed by loadAction, but if + // they were, we could only include this binding with + // preserveRenderTarget. + plsLayoutBindings.push_back({ + .binding = MSAA_COLOR_SEED_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }); + } + + if (plsLayoutBindings.size() > 0) + { + VkDescriptorSetLayoutCreateInfo plsLayoutInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = plsLayoutBindings.size(), + .pBindings = plsLayoutBindings.data(), + }; + + VK_CHECK( + m_vk->CreateDescriptorSetLayout(m_vk->device, + &plsLayoutInfo, + nullptr, + &m_plsTextureDescriptorSetLayout)); + } + + VkDescriptorSetLayout pipelineDescriptorSetLayouts[] = { + pipelineManager->perFlushDescriptorSetLayout(), + pipelineManager->perDrawDescriptorSetLayout(), + m_plsTextureDescriptorSetLayout, + }; + static_assert(COLOR_PLANE_IDX == 0); + static_assert(CLIP_PLANE_IDX == 1); + static_assert(SCRATCH_COLOR_PLANE_IDX == 2); + static_assert(COVERAGE_PLANE_IDX == 3); + static_assert(VULKAN_BINDINGS_SET_COUNT == 3); + + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = m_plsTextureDescriptorSetLayout != VK_NULL_HANDLE + ? VULKAN_BINDINGS_SET_COUNT + : VULKAN_BINDINGS_SET_COUNT - 1u, + .pSetLayouts = pipelineDescriptorSetLayouts, + }; + + VK_CHECK(m_vk->CreatePipelineLayout(m_vk->device, + &pipelineLayoutCreateInfo, + nullptr, + &m_pipelineLayout)); +} + +DrawPipelineLayoutVulkan::~DrawPipelineLayoutVulkan() +{ + m_vk->DestroyDescriptorSetLayout(m_vk->device, + m_plsTextureDescriptorSetLayout, + nullptr); + m_vk->DestroyPipelineLayout(m_vk->device, m_pipelineLayout, nullptr); +} + +uint32_t DrawPipelineLayoutVulkan::colorAttachmentCount( + uint32_t subpassIndex, + RenderPassOptionsVulkan renderPassOptions) const +{ + switch (m_interlockMode) + { + case gpu::InterlockMode::rasterOrdering: + assert(subpassIndex == 0 || subpassIndex == 1); + return (subpassIndex == 0) ? 4u : 1u; + case gpu::InterlockMode::atomics: + assert(subpassIndex <= 1); + return 2u - subpassIndex; // Subpass 0 -> 2, subpass 1 -> 1. + case gpu::InterlockMode::clockwise: + assert(subpassIndex == 0); + return enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput) + ? 1u + : 0u; + case gpu::InterlockMode::clockwiseAtomic: + assert(subpassIndex == 0 || subpassIndex == 1); + return 2; // color & clip. + case gpu::InterlockMode::msaa: + assert(0 <= subpassIndex && subpassIndex <= 2); + return 1u; + } + RIVE_UNREACHABLE(); +} +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.hpp b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.hpp new file mode 100644 index 000000000..a745d48a8 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_layout_vulkan.hpp @@ -0,0 +1,56 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include + +#include "rive/renderer/gpu.hpp" +#include "rive/refcnt.hpp" +#include "render_pass_vulkan.hpp" + +namespace rive::gpu +{ +class PipelineManagerVulkan; +class VulkanContext; + +// VkPipelineLayout wrapper for Rive flushes. +class DrawPipelineLayoutVulkan +{ +public: + DrawPipelineLayoutVulkan(PipelineManagerVulkan*, + gpu::InterlockMode, + RenderPassOptionsVulkan); + ~DrawPipelineLayoutVulkan(); + + DrawPipelineLayoutVulkan(const DrawPipelineLayoutVulkan&) = delete; + DrawPipelineLayoutVulkan& operator=(const DrawPipelineLayoutVulkan&) = + delete; + + gpu::InterlockMode interlockMode() const { return m_interlockMode; } + RenderPassOptionsVulkan renderPassOptions() const + { + return m_renderPassOptions; + } + + uint32_t colorAttachmentCount(uint32_t subpassIndex, + RenderPassOptionsVulkan) const; + + VkDescriptorSetLayout plsLayout() const + { + return m_plsTextureDescriptorSetLayout; + } + + VkPipelineLayout operator*() const { return m_pipelineLayout; } + VkPipelineLayout vkPipelineLayout() const { return m_pipelineLayout; } + +private: + const rcp m_vk; + const gpu::InterlockMode m_interlockMode; + const RenderPassOptionsVulkan m_renderPassOptions; + + VkDescriptorSetLayout m_plsTextureDescriptorSetLayout = VK_NULL_HANDLE; + VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; +}; +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.cpp b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.cpp new file mode 100644 index 000000000..f62d8a885 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.cpp @@ -0,0 +1,582 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/math/bitwise.hpp" +#include "rive/renderer/vulkan/render_context_vulkan_impl.hpp" +#include "rive/renderer/vulkan/vulkan_context.hpp" +#include "rive/renderer/stack_vector.hpp" +#include "shaders/constants.glsl" +#include "common_layouts.hpp" +#include "draw_pipeline_layout_vulkan.hpp" +#include "pipeline_manager_vulkan.hpp" +#include "render_pass_vulkan.hpp" + +namespace rive::gpu +{ +static VkStencilOp vk_stencil_op(StencilOp op) +{ + switch (op) + { + case StencilOp::keep: + return VK_STENCIL_OP_KEEP; + case StencilOp::replace: + return VK_STENCIL_OP_REPLACE; + case StencilOp::zero: + return VK_STENCIL_OP_ZERO; + case StencilOp::decrClamp: + return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case StencilOp::incrWrap: + return VK_STENCIL_OP_INCREMENT_AND_WRAP; + case StencilOp::decrWrap: + return VK_STENCIL_OP_DECREMENT_AND_WRAP; + } + RIVE_UNREACHABLE(); +} + +static VkCompareOp vk_compare_op(gpu::StencilCompareOp op) +{ + switch (op) + { + case gpu::StencilCompareOp::less: + return VK_COMPARE_OP_LESS; + case gpu::StencilCompareOp::equal: + return VK_COMPARE_OP_EQUAL; + case gpu::StencilCompareOp::lessOrEqual: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case gpu::StencilCompareOp::notEqual: + return VK_COMPARE_OP_NOT_EQUAL; + case gpu::StencilCompareOp::always: + return VK_COMPARE_OP_ALWAYS; + } + RIVE_UNREACHABLE(); +} + +static VkCullModeFlags vk_cull_mode(CullFace cullFace) +{ + switch (cullFace) + { + case CullFace::none: + return VK_CULL_MODE_NONE; + case CullFace::clockwise: + return VK_CULL_MODE_FRONT_BIT; + case CullFace::counterclockwise: + return VK_CULL_MODE_BACK_BIT; + } + RIVE_UNREACHABLE(); +} + +constexpr static VkBlendOp vk_blend_op(gpu::BlendEquation equation) +{ + switch (equation) + { + case gpu::BlendEquation::none: + case gpu::BlendEquation::srcOver: + case gpu::BlendEquation::plus: + return VK_BLEND_OP_ADD; + case gpu::BlendEquation::min: + return VK_BLEND_OP_MIN; + case gpu::BlendEquation::max: + return VK_BLEND_OP_MAX; + case gpu::BlendEquation::screen: + case gpu::BlendEquation::overlay: + case gpu::BlendEquation::darken: + case gpu::BlendEquation::lighten: + case gpu::BlendEquation::colorDodge: + case gpu::BlendEquation::colorBurn: + case gpu::BlendEquation::hardLight: + case gpu::BlendEquation::softLight: + case gpu::BlendEquation::difference: + case gpu::BlendEquation::exclusion: + case gpu::BlendEquation::multiply: + case gpu::BlendEquation::hue: + case gpu::BlendEquation::saturation: + case gpu::BlendEquation::color: + case gpu::BlendEquation::luminosity: + break; + } + RIVE_UNREACHABLE(); +} + +constexpr static VkBlendFactor vk_dst_blend_factor(gpu::BlendEquation equation) +{ + switch (equation) + { + case gpu::BlendEquation::none: + return VK_BLEND_FACTOR_ZERO; + case gpu::BlendEquation::srcOver: + return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + case gpu::BlendEquation::plus: + case gpu::BlendEquation::min: + case gpu::BlendEquation::max: + return VK_BLEND_FACTOR_ONE; + case gpu::BlendEquation::screen: + case gpu::BlendEquation::overlay: + case gpu::BlendEquation::darken: + case gpu::BlendEquation::lighten: + case gpu::BlendEquation::colorDodge: + case gpu::BlendEquation::colorBurn: + case gpu::BlendEquation::hardLight: + case gpu::BlendEquation::softLight: + case gpu::BlendEquation::difference: + case gpu::BlendEquation::exclusion: + case gpu::BlendEquation::multiply: + case gpu::BlendEquation::hue: + case gpu::BlendEquation::saturation: + case gpu::BlendEquation::color: + case gpu::BlendEquation::luminosity: + break; + } + RIVE_UNREACHABLE(); +} + +uint64_t DrawPipelineVulkan::PipelineProps::createKey( + const PlatformFeatures& platformFeatures) const +{ + uint64_t key = gpu::pipeline_unique_key( + drawType, + shaderFeatures, + interlockMode, + shaderMiscFlags, + drawContents, + enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput), + blendMode, + platformFeatures); + + const uint64_t renderPassKeyNoInterlockMode = + RenderPassVulkan::KeyNoInterlockMode(renderPassOptions, + renderTargetFormat, + colorLoadAction); + key = math::add_bits_to_key( + key, + renderPassKeyNoInterlockMode, + RenderPassVulkan::KEY_NO_INTERLOCK_MODE_BIT_COUNT); + + key = + math::add_bits_to_key(key, uint64_t(drawPipelineOptions), OPTION_COUNT); + + return key; +} + +uint32_t subpass_index(gpu::DrawType drawType, + gpu::LoadAction colorLoadAction, + gpu::InterlockMode interlockMode, + gpu::ShaderMiscFlags shaderMiscFlags) +{ + if (interlockMode == gpu::InterlockMode::clockwiseAtomic) + { + // In clockwiseAtomic mode, borrowed coverage is rendered in a separate + // subpass prior to the main one. + return enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass) + ? 0 + : 1; + } + + const uint32_t mainSubpassIdx = + (interlockMode == gpu::InterlockMode::msaa && + colorLoadAction == gpu::LoadAction::preserveRenderTarget) + ? 1 + : 0; + switch (drawType) + { + case gpu::DrawType::renderPassInitialize: + assert(mainSubpassIdx == 1); + return 0; + case gpu::DrawType::midpointFanPatches: + case gpu::DrawType::midpointFanCenterAAPatches: + case gpu::DrawType::outerCurvePatches: + case gpu::DrawType::interiorTriangulation: + case gpu::DrawType::atlasBlit: + case gpu::DrawType::imageRect: + case gpu::DrawType::imageMesh: + case gpu::DrawType::msaaStrokes: + case gpu::DrawType::msaaMidpointFanBorrowedCoverage: + case gpu::DrawType::msaaMidpointFans: + case gpu::DrawType::msaaMidpointFanStencilReset: + case gpu::DrawType::msaaMidpointFanPathsStencil: + case gpu::DrawType::msaaMidpointFanPathsCover: + case gpu::DrawType::msaaOuterCubics: + case gpu::DrawType::clipReset: + return mainSubpassIdx; + case gpu::DrawType::renderPassResolve: + return mainSubpassIdx + 1; + } + + RIVE_UNREACHABLE(); +} + +DrawPipelineVulkan::DrawPipelineVulkan( + PipelineManagerVulkan* pipelineManager, + const DrawPipelineLayoutVulkan& pipelineLayout, + const PipelineProps& props, + VkRenderPass vkRenderPass, + const PlatformFeatures& platformFeatures +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType synthesizedFailureType +#endif + + ) : + m_vk(ref_rcp(pipelineManager->vulkanContext())) +{ +#ifdef WITH_RIVE_TOOLS + if (synthesizedFailureType == SynthesizedFailureType::pipelineCreation) + { + return; + } +#endif + + const bool pipelineWriteOnlyRenderTarget = + enums::is_flag_set(props.renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput); + + const gpu::PipelineState pipelineState = + get_pipeline_state(props.drawType, + props.interlockMode, + props.shaderMiscFlags, + props.drawContents, + pipelineWriteOnlyRenderTarget, + props.blendMode, + platformFeatures); + + const gpu::InterlockMode interlockMode = pipelineLayout.interlockMode(); + uint32_t subpassIndex = subpass_index(props.drawType, + props.colorLoadAction, + interlockMode, + props.shaderMiscFlags); + + auto& vertShader = + pipelineManager->getVertexShaderSynchronous(props.drawType, + props.shaderFeatures, + interlockMode); + + if (vertShader.module() == VK_NULL_HANDLE) + { + return; + } + auto& fragShader = + pipelineManager->getFragmentShaderSynchronous(props.drawType, + props.shaderFeatures, + interlockMode, + props.shaderMiscFlags); + if (fragShader.module() == VK_NULL_HANDLE) + { + return; + } + + uint32_t shaderPermutationFlags[SPECIALIZATION_COUNT] = { + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIP_RECT), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_FEATHER), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_EVEN_ODD), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_NESTED_CLIPPING), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_HSL_BLEND_MODES), + enums::is_flag_set(props.shaderFeatures, + gpu::ShaderFeatures::ENABLE_DITHER), + enums::is_flag_set(props.shaderMiscFlags, + gpu::ShaderMiscFlags::clockwiseFill), + enums::is_flag_set(props.shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass), + enums::is_flag_set(props.shaderMiscFlags, + gpu::ShaderMiscFlags::nestedClipUpdateOnly), + pipelineManager->vendorID(), + }; + static_assert(CLIPPING_SPECIALIZATION_IDX == 0); + static_assert(CLIP_RECT_SPECIALIZATION_IDX == 1); + static_assert(ADVANCED_BLEND_SPECIALIZATION_IDX == 2); + static_assert(FEATHER_SPECIALIZATION_IDX == 3); + static_assert(EVEN_ODD_SPECIALIZATION_IDX == 4); + static_assert(NESTED_CLIPPING_SPECIALIZATION_IDX == 5); + static_assert(HSL_BLEND_MODES_SPECIALIZATION_IDX == 6); + static_assert(DITHER_SPECIALIZATION_IDX == 7); + static_assert(CLOCKWISE_FILL_SPECIALIZATION_IDX == 8); + static_assert(BORROWED_COVERAGE_PASS_SPECIALIZATION_IDX == 9); + static_assert(NESTED_CLIP_UPDATE_ONLY_IDX == 10); + static_assert(VULKAN_VENDOR_ID_SPECIALIZATION_IDX == 11); + static_assert(SPECIALIZATION_COUNT == 12); + + VkSpecializationMapEntry permutationMapEntries[SPECIALIZATION_COUNT]; + for (uint32_t i = 0; i < SPECIALIZATION_COUNT; ++i) + { + permutationMapEntries[i] = { + .constantID = i, + .offset = i * static_cast(sizeof(uint32_t)), + .size = sizeof(uint32_t), + }; + } + + VkSpecializationInfo specializationInfo = { + .mapEntryCount = SPECIALIZATION_COUNT, + .pMapEntries = permutationMapEntries, + .dataSize = sizeof(shaderPermutationFlags), + .pData = &shaderPermutationFlags, + }; + + VkPipelineShaderStageCreateInfo stages[] = { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = vertShader.module(), + .pName = "main", + .pSpecializationInfo = &specializationInfo, + }, + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = fragShader.module(), + .pName = "main", + .pSpecializationInfo = &specializationInfo, + }, + }; + + VkPipelineRasterizationStateCreateInfo + pipelineRasterizationStateCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .polygonMode = enums::is_flag_set(props.drawPipelineOptions, + Options::wireframe) + ? VK_POLYGON_MODE_LINE + : VK_POLYGON_MODE_FILL, + .cullMode = vk_cull_mode(pipelineState.cullFace), + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .lineWidth = 1.0, + }; + + gpu::BlendEquation blendEquation = pipelineState.blendEquation; + bool colorWriteEnabled = pipelineState.colorWriteEnabled; + if (interlockMode == gpu::InterlockMode::rasterOrdering || + interlockMode == gpu::InterlockMode::atomics || + (interlockMode == gpu::InterlockMode::clockwiseAtomic && + !enums::is_flag_set(props.shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass))) + { + // The pipeline state gets generated under the assumption that pixel + // local storage can still be written when colorWriteEnabled is false. + // So when Vulkan implements PLS via color attachments, we need to + // override the colorWriteEnabled state. + colorWriteEnabled = true; + } + if (interlockMode == gpu::InterlockMode::atomics && + !enums::is_flag_set(props.shaderMiscFlags, + gpu::ShaderMiscFlags::coalescedResolveAndTransfer)) + { + // Vulkan deviates from the other renderers by enabling src-over + // blending for PLS planes in atomic mode. + // + // Advanced blend modes are handled by rearranging the math such that + // the correct color isn't reached until *AFTER* this blend state is + // applied. This primarily benefits us by hinting to the hardware that + // it doesn't need to read or write anything when a == 0, but it also + // saves flops by offloading the blend work onto the ROP blending unit. + // + // Clip also has blend enabled, which allows us to preserve both clip + // and color contents by just emitting a=0 (instead of loading and + // re-emitting the current value) when a PLS plane needs to remain + // unchanged during a fragment invocation. + blendEquation = gpu::BlendEquation::srcOver; + } +#ifndef NDEBUG + else if (enums::is_flag_set( + props.shaderMiscFlags, + gpu::ShaderMiscFlags::coalescedResolveAndTransfer)) + { + assert(interlockMode == gpu::InterlockMode::atomics); + assert(blendEquation == gpu::BlendEquation::none); + } +#endif + + StackVector + blendStates; + blendStates.push_back_n( + pipelineLayout.colorAttachmentCount(subpassIndex, + pipelineLayout.renderPassOptions()), + { + .blendEnable = blendEquation != gpu::BlendEquation::none, + .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, + .dstColorBlendFactor = vk_dst_blend_factor(blendEquation), + .colorBlendOp = vk_blend_op(blendEquation), + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = vk_dst_blend_factor(blendEquation), + .alphaBlendOp = vk_blend_op(blendEquation), + .colorWriteMask = colorWriteEnabled ? vkutil::kColorWriteMaskRGBA + : vkutil::kColorWriteMaskNone, + }); + + if (m_vk->features.independentBlend && + interlockMode == gpu::InterlockMode::clockwiseAtomic) + { + // Since we support independentBlend, it will hopefully give us a perf + // boost to disable color writes to clip/color when not being updated. + // Otherwise, we will rely on the shader emitting no-op values for the + // non-updated planes. + if (enums::is_flag_set(props.shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly)) + { + blendStates[COLOR_PLANE_IDX].colorWriteMask = + vkutil::kColorWriteMaskNone; + } + else if (props.drawType != gpu::DrawType::renderPassInitialize) + { + assert(props.drawType != gpu::DrawType::clipReset); + assert(!enums::is_flag_set( + props.shaderMiscFlags, + gpu::ShaderMiscFlags::nestedClipUpdateOnly)); + blendStates[CLIP_PLANE_IDX].colorWriteMask = + vkutil::kColorWriteMaskNone; + } + } + + VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .attachmentCount = blendStates.size(), + .pAttachments = blendStates.data(), + }; + + if (interlockMode == gpu::InterlockMode::rasterOrdering && + m_vk->features.rasterizationOrderColorAttachmentAccess) + { + pipelineColorBlendStateCreateInfo.flags |= + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT; + } + + VkPipelineDepthStencilStateCreateInfo depthStencilState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = pipelineState.depthTestEnabled, + .depthWriteEnable = pipelineState.depthWriteEnabled, + .depthCompareOp = VK_COMPARE_OP_LESS, + .depthBoundsTestEnable = VK_FALSE, + .stencilTestEnable = pipelineState.stencilTestEnabled, + .minDepthBounds = gpu::DEPTH_MIN, + .maxDepthBounds = gpu::DEPTH_MAX, + }; + if (pipelineState.stencilTestEnabled) + { + depthStencilState.front = { + .failOp = vk_stencil_op(pipelineState.stencilFrontOps.failOp), + .passOp = vk_stencil_op(pipelineState.stencilFrontOps.passOp), + .depthFailOp = + vk_stencil_op(pipelineState.stencilFrontOps.depthFailOp), + .compareOp = vk_compare_op(pipelineState.stencilFrontOps.compareOp), + .compareMask = pipelineState.stencilCompareMask, + .writeMask = pipelineState.stencilWriteMask, + .reference = pipelineState.stencilReference, + }; + depthStencilState.back = + !pipelineState.stencilDoubleSided + ? depthStencilState.front + : VkStencilOpState{ + .failOp = + vk_stencil_op(pipelineState.stencilBackOps.failOp), + .passOp = + vk_stencil_op(pipelineState.stencilBackOps.passOp), + .depthFailOp = vk_stencil_op( + pipelineState.stencilBackOps.depthFailOp), + .compareOp = + vk_compare_op(pipelineState.stencilBackOps.compareOp), + .compareMask = pipelineState.stencilCompareMask, + .writeMask = pipelineState.stencilWriteMask, + .reference = pipelineState.stencilReference, + }; + } + + VkPipelineMultisampleStateCreateInfo msaaState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = + (interlockMode == gpu::InterlockMode::msaa && + props.drawType != gpu::DrawType::renderPassResolve) + ? VK_SAMPLE_COUNT_4_BIT + : VK_SAMPLE_COUNT_1_BIT, + }; + + VkGraphicsPipelineCreateInfo pipelineCreateInfo = { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .stageCount = 2, + .pStages = stages, + .pViewportState = &layout::SINGLE_VIEWPORT, + .pRasterizationState = &pipelineRasterizationStateCreateInfo, + .pMultisampleState = &msaaState, + .pDepthStencilState = interlockMode == gpu::InterlockMode::msaa + ? &depthStencilState + : nullptr, + .pColorBlendState = &pipelineColorBlendStateCreateInfo, + .pDynamicState = &layout::DYNAMIC_VIEWPORT_SCISSOR, + .layout = *pipelineLayout, + .renderPass = vkRenderPass, + .subpass = subpassIndex, + }; + + switch (props.drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + case DrawType::msaaOuterCubics: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + pipelineCreateInfo.pVertexInputState = + &layout::PATH_VERTEX_INPUT_STATE; + pipelineCreateInfo.pInputAssemblyState = + &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; + break; + + case DrawType::clipReset: + case DrawType::interiorTriangulation: + case DrawType::atlasBlit: + pipelineCreateInfo.pVertexInputState = + &layout::INTERIOR_TRI_VERTEX_INPUT_STATE; + pipelineCreateInfo.pInputAssemblyState = + &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; + break; + + case DrawType::imageRect: + pipelineCreateInfo.pVertexInputState = + &layout::IMAGE_RECT_VERTEX_INPUT_STATE; + pipelineCreateInfo.pInputAssemblyState = + &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; + break; + + case DrawType::imageMesh: + pipelineCreateInfo.pVertexInputState = + &layout::IMAGE_MESH_VERTEX_INPUT_STATE; + pipelineCreateInfo.pInputAssemblyState = + &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; + break; + + case DrawType::renderPassResolve: + case DrawType::renderPassInitialize: + pipelineCreateInfo.pVertexInputState = + &layout::EMPTY_VERTEX_INPUT_STATE; + pipelineCreateInfo.pInputAssemblyState = + &layout::INPUT_ASSEMBLY_TRIANGLE_STRIP; + break; + } + + if (m_vk->CreateGraphicsPipelines(m_vk->device, + VK_NULL_HANDLE, + 1, + &pipelineCreateInfo, + nullptr, + &m_vkPipeline) != VK_SUCCESS) + { + m_vkPipeline = VK_NULL_HANDLE; + } +} + +DrawPipelineVulkan::~DrawPipelineVulkan() +{ + m_vk->DestroyPipeline(m_vk->device, m_vkPipeline, nullptr); +} +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.hpp b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.hpp new file mode 100644 index 000000000..d5fbcd39e --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/draw_pipeline_vulkan.hpp @@ -0,0 +1,74 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/gpu.hpp" +#include "draw_shader_vulkan.hpp" +#include "render_pass_vulkan.hpp" + +namespace rive::gpu +{ +class PipelineManagerVulkan; + +class DrawPipelineVulkan +{ +public: + enum class Options + { + none = 0, + wireframe = 1 << 0, + }; + constexpr static int OPTION_COUNT = 1; + + struct PipelineProps + { + DrawType drawType; + ShaderFeatures shaderFeatures; + InterlockMode interlockMode; + ShaderMiscFlags shaderMiscFlags; + + // Vulkan has pipeline props beyond just the standard ones + + DrawContents drawContents; + rive::BlendMode blendMode; + Options drawPipelineOptions; + RenderPassOptionsVulkan renderPassOptions; + VkFormat renderTargetFormat; + LoadAction colorLoadAction; + +#ifdef WITH_RIVE_TOOLS + SynthesizedFailureType synthesizedFailureType = + SynthesizedFailureType::none; +#endif + + uint64_t createKey(const PlatformFeatures&) const; + }; + + using VertexShaderType = DrawShaderVulkan; + using FragmentShaderType = DrawShaderVulkan; + + DrawPipelineVulkan(PipelineManagerVulkan*, + const DrawPipelineLayoutVulkan&, + const PipelineProps&, + VkRenderPass, + const PlatformFeatures& +#ifdef WITH_RIVE_TOOLS + , + SynthesizedFailureType +#endif + ); + ~DrawPipelineVulkan(); + + DrawPipelineVulkan(const DrawPipelineVulkan&) = delete; + DrawPipelineVulkan& operator=(const DrawPipelineVulkan&) = delete; + + operator VkPipeline() const { return m_vkPipeline; } + +private: + const rcp m_vk; + VkPipeline m_vkPipeline = VK_NULL_HANDLE; +}; + +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.cpp b/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.cpp index 433717412..cb3938d0a 100644 --- a/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.cpp +++ b/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.cpp @@ -2,430 +2,479 @@ * Copyright 2023 Rive */ -#include "draw_shader_vulkan.hpp" - -#include "rive/renderer/vulkan/vkutil.hpp" #include "rive/renderer/vulkan/vulkan_context.hpp" -#include "shaders/constants.glsl" +#include "draw_shader_vulkan.hpp" +#include "vulkan_shaders.hpp" namespace rive::gpu { -namespace spirv_embedded -{ -// Draw setup shaders. -#include "generated/shaders/spirv/color_ramp.vert.h" -#include "generated/shaders/spirv/color_ramp.frag.h" -#include "generated/shaders/spirv/tessellate.vert.h" -#include "generated/shaders/spirv/tessellate.frag.h" -#include "generated/shaders/spirv/render_atlas.vert.h" -#include "generated/shaders/spirv/render_atlas_fill.frag.h" -#include "generated/shaders/spirv/render_atlas_stroke.frag.h" - -// InterlockMode::rasterOrdering shaders. -#include "generated/shaders/spirv/draw_path.vert.h" -#include "generated/shaders/spirv/draw_path.frag.h" -#include "generated/shaders/spirv/draw_interior_triangles.vert.h" -#include "generated/shaders/spirv/draw_interior_triangles.frag.h" -#include "generated/shaders/spirv/draw_atlas_blit.vert.h" -#include "generated/shaders/spirv/draw_atlas_blit.frag.h" -#include "generated/shaders/spirv/draw_image_mesh.vert.h" -#include "generated/shaders/spirv/draw_image_mesh.frag.h" - -// InterlockMode::atomics shaders. -#include "generated/shaders/spirv/atomic_draw_path.vert.h" -#include "generated/shaders/spirv/atomic_draw_path.frag.h" -#include "generated/shaders/spirv/atomic_draw_path.fixedcolor_frag.h" -#include "generated/shaders/spirv/atomic_draw_interior_triangles.vert.h" -#include "generated/shaders/spirv/atomic_draw_interior_triangles.frag.h" -#include "generated/shaders/spirv/atomic_draw_interior_triangles.fixedcolor_frag.h" -#include "generated/shaders/spirv/atomic_draw_atlas_blit.vert.h" -#include "generated/shaders/spirv/atomic_draw_atlas_blit.frag.h" -#include "generated/shaders/spirv/atomic_draw_atlas_blit.fixedcolor_frag.h" -#include "generated/shaders/spirv/atomic_draw_image_rect.vert.h" -#include "generated/shaders/spirv/atomic_draw_image_rect.frag.h" -#include "generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.h" -#include "generated/shaders/spirv/atomic_draw_image_mesh.vert.h" -#include "generated/shaders/spirv/atomic_draw_image_mesh.frag.h" -#include "generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.h" -#include "generated/shaders/spirv/atomic_resolve.vert.h" -#include "generated/shaders/spirv/atomic_resolve.frag.h" -#include "generated/shaders/spirv/atomic_resolve.fixedcolor_frag.h" -#include "generated/shaders/spirv/atomic_resolve_coalesced.vert.h" -#include "generated/shaders/spirv/atomic_resolve_coalesced.frag.h" - -// InterlockMode::clockwiseAtomic shaders. -#include "generated/shaders/spirv/draw_clockwise_path.vert.h" -#include "generated/shaders/spirv/draw_clockwise_path.frag.h" -#include "generated/shaders/spirv/draw_clockwise_interior_triangles.vert.h" -#include "generated/shaders/spirv/draw_clockwise_interior_triangles.frag.h" -#include "generated/shaders/spirv/draw_clockwise_atlas_blit.vert.h" -#include "generated/shaders/spirv/draw_clockwise_atlas_blit.frag.h" -#include "generated/shaders/spirv/draw_clockwise_image_mesh.vert.h" -#include "generated/shaders/spirv/draw_clockwise_image_mesh.frag.h" -}; // namespace spirv_embedded - -namespace spirv -{ -rive::Span color_ramp_vert = - rive::make_span(spirv_embedded::color_ramp_vert); -rive::Span color_ramp_frag = - rive::make_span(spirv_embedded::color_ramp_frag); -rive::Span tessellate_vert = - rive::make_span(spirv_embedded::tessellate_vert); -rive::Span tessellate_frag = - rive::make_span(spirv_embedded::tessellate_frag); -rive::Span render_atlas_vert = - rive::make_span(spirv_embedded::render_atlas_vert); -rive::Span render_atlas_fill_frag = - rive::make_span(spirv_embedded::render_atlas_fill_frag); -rive::Span render_atlas_stroke_frag = - rive::make_span(spirv_embedded::render_atlas_stroke_frag); -rive::Span draw_path_vert = - rive::make_span(spirv_embedded::draw_path_vert); -rive::Span draw_path_frag = - rive::make_span(spirv_embedded::draw_path_frag); -rive::Span draw_interior_triangles_vert = - rive::make_span(spirv_embedded::draw_interior_triangles_vert); -rive::Span draw_interior_triangles_frag = - rive::make_span(spirv_embedded::draw_interior_triangles_frag); -rive::Span draw_atlas_blit_vert = - rive::make_span(spirv_embedded::draw_atlas_blit_vert); -rive::Span draw_atlas_blit_frag = - rive::make_span(spirv_embedded::draw_atlas_blit_frag); -rive::Span draw_image_mesh_vert = - rive::make_span(spirv_embedded::draw_image_mesh_vert); -rive::Span draw_image_mesh_frag = - rive::make_span(spirv_embedded::draw_image_mesh_frag); -rive::Span atomic_draw_path_vert = - rive::make_span(spirv_embedded::atomic_draw_path_vert); -rive::Span atomic_draw_path_frag = - rive::make_span(spirv_embedded::atomic_draw_path_frag); -rive::Span atomic_draw_path_fixedcolor_frag = rive::make_span( - spirv_embedded::atomic_draw_path_fixedcolor_frag, - std::size(spirv_embedded::atomic_draw_path_fixedcolor_frag)); -rive::Span atomic_draw_interior_triangles_vert = - rive::make_span(spirv_embedded::atomic_draw_interior_triangles_vert); -rive::Span atomic_draw_interior_triangles_frag = - rive::make_span(spirv_embedded::atomic_draw_interior_triangles_frag); -rive::Span atomic_draw_interior_triangles_fixedcolor_frag = - rive::make_span( - spirv_embedded::atomic_draw_interior_triangles_fixedcolor_frag); -rive::Span atomic_draw_atlas_blit_vert = - rive::make_span(spirv_embedded::atomic_draw_atlas_blit_vert); -rive::Span atomic_draw_atlas_blit_frag = - rive::make_span(spirv_embedded::atomic_draw_atlas_blit_frag); -rive::Span atomic_draw_atlas_blit_fixedcolor_frag = - rive::make_span(spirv_embedded::atomic_draw_atlas_blit_fixedcolor_frag); -rive::Span atomic_draw_image_rect_vert = - rive::make_span(spirv_embedded::atomic_draw_image_rect_vert); -rive::Span atomic_draw_image_rect_frag = - rive::make_span(spirv_embedded::atomic_draw_image_rect_frag); -rive::Span atomic_draw_image_rect_fixedcolor_frag = - rive::make_span(spirv_embedded::atomic_draw_image_rect_fixedcolor_frag); -rive::Span atomic_draw_image_mesh_vert = - rive::make_span(spirv_embedded::atomic_draw_image_mesh_vert); -rive::Span atomic_draw_image_mesh_frag = - rive::make_span(spirv_embedded::atomic_draw_image_mesh_frag); -rive::Span atomic_draw_image_mesh_fixedcolor_frag = - rive::make_span(spirv_embedded::atomic_draw_image_mesh_fixedcolor_frag); -rive::Span atomic_resolve_vert = - rive::make_span(spirv_embedded::atomic_resolve_vert); -rive::Span atomic_resolve_frag = - rive::make_span(spirv_embedded::atomic_resolve_frag); -rive::Span atomic_resolve_fixedcolor_frag = - rive::make_span(spirv_embedded::atomic_resolve_fixedcolor_frag, - std::size(spirv_embedded::atomic_resolve_fixedcolor_frag)); -rive::Span atomic_resolve_coalesced_vert = - rive::make_span(spirv_embedded::atomic_resolve_coalesced_vert); -rive::Span atomic_resolve_coalesced_frag = - rive::make_span(spirv_embedded::atomic_resolve_coalesced_frag); -rive::Span draw_clockwise_path_vert = - rive::make_span(spirv_embedded::draw_clockwise_path_vert); -rive::Span draw_clockwise_path_frag = - rive::make_span(spirv_embedded::draw_clockwise_path_frag); -rive::Span draw_clockwise_interior_triangles_vert = - rive::make_span(spirv_embedded::draw_clockwise_interior_triangles_vert); -rive::Span draw_clockwise_interior_triangles_frag = - rive::make_span(spirv_embedded::draw_clockwise_interior_triangles_frag); -rive::Span draw_clockwise_atlas_blit_vert = - rive::make_span(spirv_embedded::draw_clockwise_atlas_blit_vert); -rive::Span draw_clockwise_atlas_blit_frag = - rive::make_span(spirv_embedded::draw_clockwise_atlas_blit_frag); -rive::Span draw_clockwise_image_mesh_vert = - rive::make_span(spirv_embedded::draw_clockwise_image_mesh_vert); -rive::Span draw_clockwise_image_mesh_frag = - rive::make_span(spirv_embedded::draw_clockwise_image_mesh_frag); - -void hotload_shaders(rive::Span spirvData) -{ - size_t spirvIndex = 0; - auto readNextBytecodeSpan = [spirvData, - &spirvIndex]() -> rive::Span { - size_t insnCount = spirvData[spirvIndex++]; - const uint32_t* insnData = spirvData.data() + spirvIndex; - spirvIndex += insnCount; - return rive::make_span(insnData, insnCount); - }; - - spirv::color_ramp_vert = readNextBytecodeSpan(); - spirv::color_ramp_frag = readNextBytecodeSpan(); - spirv::tessellate_vert = readNextBytecodeSpan(); - spirv::tessellate_frag = readNextBytecodeSpan(); - spirv::render_atlas_vert = readNextBytecodeSpan(); - spirv::render_atlas_fill_frag = readNextBytecodeSpan(); - spirv::render_atlas_stroke_frag = readNextBytecodeSpan(); - spirv::draw_path_vert = readNextBytecodeSpan(); - spirv::draw_path_frag = readNextBytecodeSpan(); - spirv::draw_interior_triangles_vert = readNextBytecodeSpan(); - spirv::draw_interior_triangles_frag = readNextBytecodeSpan(); - spirv::draw_atlas_blit_vert = readNextBytecodeSpan(); - spirv::draw_atlas_blit_frag = readNextBytecodeSpan(); - spirv::draw_image_mesh_vert = readNextBytecodeSpan(); - spirv::draw_image_mesh_frag = readNextBytecodeSpan(); - spirv::atomic_draw_path_vert = readNextBytecodeSpan(); - spirv::atomic_draw_path_frag = readNextBytecodeSpan(); - spirv::atomic_draw_path_fixedcolor_frag = readNextBytecodeSpan(); - spirv::atomic_draw_interior_triangles_vert = readNextBytecodeSpan(); - spirv::atomic_draw_interior_triangles_frag = readNextBytecodeSpan(); - spirv::atomic_draw_interior_triangles_fixedcolor_frag = - readNextBytecodeSpan(); - spirv::atomic_draw_atlas_blit_vert = readNextBytecodeSpan(); - spirv::atomic_draw_atlas_blit_frag = readNextBytecodeSpan(); - spirv::atomic_draw_atlas_blit_fixedcolor_frag = readNextBytecodeSpan(); - spirv::atomic_draw_image_rect_vert = readNextBytecodeSpan(); - spirv::atomic_draw_image_rect_frag = readNextBytecodeSpan(); - spirv::atomic_draw_image_rect_fixedcolor_frag = readNextBytecodeSpan(); - spirv::atomic_draw_image_mesh_vert = readNextBytecodeSpan(); - spirv::atomic_draw_image_mesh_frag = readNextBytecodeSpan(); - spirv::atomic_draw_image_mesh_fixedcolor_frag = readNextBytecodeSpan(); - spirv::atomic_resolve_vert = readNextBytecodeSpan(); - spirv::atomic_resolve_frag = readNextBytecodeSpan(); - spirv::atomic_resolve_fixedcolor_frag = readNextBytecodeSpan(); - spirv::atomic_resolve_coalesced_vert = readNextBytecodeSpan(); - spirv::atomic_resolve_coalesced_frag = readNextBytecodeSpan(); - spirv::draw_clockwise_path_vert = readNextBytecodeSpan(); - spirv::draw_clockwise_path_frag = readNextBytecodeSpan(); - spirv::draw_clockwise_interior_triangles_vert = readNextBytecodeSpan(); - spirv::draw_clockwise_interior_triangles_frag = readNextBytecodeSpan(); - spirv::draw_clockwise_atlas_blit_vert = readNextBytecodeSpan(); - spirv::draw_clockwise_atlas_blit_frag = readNextBytecodeSpan(); - spirv::draw_clockwise_image_mesh_vert = readNextBytecodeSpan(); - spirv::draw_clockwise_image_mesh_frag = readNextBytecodeSpan(); -} -}; // namespace spirv - -DrawShaderVulkan::DrawShaderVulkan(VulkanContext* vk, - gpu::DrawType drawType, - gpu::InterlockMode interlockMode, - gpu::ShaderFeatures shaderFeatures, - gpu::ShaderMiscFlags shaderMiscFlags) : +DrawShaderVulkan::DrawShaderVulkan(Type type, + VulkanContext* vk, + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags shaderMiscFlags) : m_vk(ref_rcp(vk)) { - VkShaderModuleCreateInfo vsInfo = { - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO}; - VkShaderModuleCreateInfo fsInfo = { + VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO}; - if (interlockMode == gpu::InterlockMode::rasterOrdering) + const bool fixedFunctionColorOutput = + enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput); + + if (type == Type::fragment && interlockMode == InterlockMode::msaa && + drawType != DrawType::renderPassInitialize && + drawType != DrawType::renderPassResolve) { - switch (drawType) - { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - vkutil::set_shader_code(vsInfo, spirv::draw_path_vert); - vkutil::set_shader_code(fsInfo, spirv::draw_path_frag); - break; - - case DrawType::interiorTriangulation: - vkutil::set_shader_code(vsInfo, - spirv::draw_interior_triangles_vert); - vkutil::set_shader_code(fsInfo, - spirv::draw_interior_triangles_frag); - break; - - case DrawType::atlasBlit: - vkutil::set_shader_code(vsInfo, spirv::draw_atlas_blit_vert); - vkutil::set_shader_code(fsInfo, spirv::draw_atlas_blit_frag); - break; - - case DrawType::imageMesh: - vkutil::set_shader_code(vsInfo, spirv::draw_image_mesh_vert); - vkutil::set_shader_code(fsInfo, spirv::draw_image_mesh_frag); - break; - - case DrawType::imageRect: - case DrawType::atomicResolve: - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); - } + // Fixed function color output and advanced blend are mutually exclusive + // and one of them should always be set in msaa mode. + assert(fixedFunctionColorOutput != + bool(shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND)); } - else if (interlockMode == gpu::InterlockMode::atomics) + + Span vertCode; + Span fragCode; + + switch (interlockMode) { - assert(interlockMode == gpu::InterlockMode::atomics); - bool fixedFunctionColorOutput = - shaderMiscFlags & gpu::ShaderMiscFlags::fixedFunctionColorOutput; - switch (drawType) + case gpu::InterlockMode::rasterOrdering: { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - vkutil::set_shader_code(vsInfo, spirv::atomic_draw_path_vert); - vkutil::set_shader_code_if_then_else( - fsInfo, - fixedFunctionColorOutput, - spirv::atomic_draw_path_fixedcolor_frag, - spirv::atomic_draw_path_frag); - break; - - case DrawType::interiorTriangulation: - vkutil::set_shader_code( - vsInfo, - spirv::atomic_draw_interior_triangles_vert); - vkutil::set_shader_code_if_then_else( - fsInfo, - fixedFunctionColorOutput, - spirv::atomic_draw_interior_triangles_fixedcolor_frag, - spirv::atomic_draw_interior_triangles_frag); - break; - - case DrawType::atlasBlit: - vkutil::set_shader_code(vsInfo, - spirv::atomic_draw_atlas_blit_vert); - vkutil::set_shader_code_if_then_else( - fsInfo, - fixedFunctionColorOutput, - spirv::atomic_draw_atlas_blit_fixedcolor_frag, - spirv::atomic_draw_atlas_blit_frag); - break; - - case DrawType::imageRect: - vkutil::set_shader_code(vsInfo, - spirv::atomic_draw_image_rect_vert); - vkutil::set_shader_code_if_then_else( - fsInfo, - fixedFunctionColorOutput, - spirv::atomic_draw_image_rect_fixedcolor_frag, - spirv::atomic_draw_image_rect_frag); - break; - - case DrawType::imageMesh: - vkutil::set_shader_code(vsInfo, - spirv::atomic_draw_image_mesh_vert); - vkutil::set_shader_code_if_then_else( - fsInfo, - fixedFunctionColorOutput, - spirv::atomic_draw_image_mesh_fixedcolor_frag, - spirv::atomic_draw_image_mesh_frag); - break; - - case DrawType::atomicResolve: - if (shaderMiscFlags & - gpu::ShaderMiscFlags::coalescedResolveAndTransfer) - { - vkutil::set_shader_code( - vsInfo, - spirv::atomic_resolve_coalesced_vert); - vkutil::set_shader_code( - fsInfo, - spirv::atomic_resolve_coalesced_frag); - } - else - { - vkutil::set_shader_code(vsInfo, spirv::atomic_resolve_vert); - vkutil::set_shader_code_if_then_else( - fsInfo, - fixedFunctionColorOutput, - spirv::atomic_resolve_fixedcolor_frag, - spirv::atomic_resolve_frag); - } - break; - - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + vertCode = spirv::draw_path_vert; + fragCode = spirv::draw_path_frag; + break; + + case DrawType::interiorTriangulation: + vertCode = spirv::draw_interior_triangles_vert; + fragCode = spirv::draw_interior_triangles_frag; + break; + + case DrawType::atlasBlit: + vertCode = spirv::draw_atlas_blit_vert; + fragCode = spirv::draw_atlas_blit_frag; + break; + + case DrawType::imageMesh: + vertCode = spirv::draw_image_mesh_vert; + fragCode = spirv::draw_image_mesh_frag; + break; + + case DrawType::renderPassResolve: + vertCode = spirv::draw_fullscreen_quad_vert; + fragCode = spirv::draw_input_attachment_frag; + break; + + case DrawType::imageRect: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + RIVE_UNREACHABLE(); + } + break; } - } - else - { - assert(interlockMode == gpu::InterlockMode::clockwiseAtomic); - switch (drawType) + + case gpu::InterlockMode::atomics: + { + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + vertCode = spirv::atomic_draw_path_vert; + fragCode = fixedFunctionColorOutput + ? spirv::atomic_draw_path_fixedcolor_frag + : spirv::atomic_draw_path_frag; + break; + + case DrawType::interiorTriangulation: + vertCode = spirv::atomic_draw_interior_triangles_vert; + fragCode = + fixedFunctionColorOutput + ? spirv:: + atomic_draw_interior_triangles_fixedcolor_frag + : spirv::atomic_draw_interior_triangles_frag; + break; + + case DrawType::atlasBlit: + vertCode = spirv::atomic_draw_atlas_blit_vert; + fragCode = + fixedFunctionColorOutput + ? spirv::atomic_draw_atlas_blit_fixedcolor_frag + : spirv::atomic_draw_atlas_blit_frag; + break; + + case DrawType::imageRect: + vertCode = spirv::atomic_draw_image_rect_vert; + fragCode = + fixedFunctionColorOutput + ? spirv::atomic_draw_image_rect_fixedcolor_frag + : spirv::atomic_draw_image_rect_frag; + break; + + case DrawType::imageMesh: + vertCode = spirv::atomic_draw_image_mesh_vert; + fragCode = + fixedFunctionColorOutput + ? spirv::atomic_draw_image_mesh_fixedcolor_frag + : spirv::atomic_draw_image_mesh_frag; + break; + + case DrawType::renderPassResolve: + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::coalescedResolveAndTransfer)) + { + vertCode = spirv::atomic_resolve_coalesced_vert; + fragCode = spirv::atomic_resolve_coalesced_frag; + } + else + { + vertCode = spirv::atomic_resolve_vert; + fragCode = fixedFunctionColorOutput + ? spirv::atomic_resolve_fixedcolor_frag + : spirv::atomic_resolve_frag; + } + break; + + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + RIVE_UNREACHABLE(); + } + break; + } + + case gpu::InterlockMode::clockwise: { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - vkutil::set_shader_code(vsInfo, - spirv::draw_clockwise_path_vert); - vkutil::set_shader_code(fsInfo, - spirv::draw_clockwise_path_frag); - break; - - case DrawType::interiorTriangulation: - vkutil::set_shader_code( - vsInfo, - spirv::draw_clockwise_interior_triangles_vert); - vkutil::set_shader_code( - fsInfo, - spirv::draw_clockwise_interior_triangles_frag); - break; - - case DrawType::atlasBlit: - vkutil::set_shader_code(vsInfo, - spirv::draw_clockwise_atlas_blit_vert); - vkutil::set_shader_code(fsInfo, - spirv::draw_clockwise_atlas_blit_frag); - break; - - case DrawType::imageMesh: - vkutil::set_shader_code(vsInfo, - spirv::draw_clockwise_image_mesh_vert); - vkutil::set_shader_code(fsInfo, - spirv::draw_clockwise_image_mesh_frag); - break; - - case DrawType::imageRect: - case DrawType::atomicResolve: - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); +#ifndef RIVE_ANDROID + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + vertCode = spirv::draw_clockwise_path_vert; + fragCode = + enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly) + ? fixedFunctionColorOutput + ? spirv::draw_clockwise_clip_fixedcolor_frag + : spirv::draw_clockwise_clip_frag + : fixedFunctionColorOutput + ? spirv::draw_clockwise_path_fixedcolor_frag + : spirv::draw_clockwise_path_frag; + break; + + case DrawType::interiorTriangulation: + vertCode = spirv::draw_clockwise_interior_triangles_vert; + fragCode = + enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly) + ? fixedFunctionColorOutput + ? spirv:: + draw_clockwise_clip_interior_triangles_fixedcolor_frag + + : spirv:: + draw_clockwise_clip_interior_triangles_frag + : fixedFunctionColorOutput + ? spirv:: + draw_clockwise_interior_triangles_fixedcolor_frag + : spirv::draw_clockwise_interior_triangles_frag; + break; + + case DrawType::atlasBlit: + vertCode = spirv::draw_clockwise_atlas_blit_vert; + fragCode = + fixedFunctionColorOutput + ? spirv::draw_clockwise_atlas_blit_fixedcolor_frag + : spirv::draw_clockwise_atlas_blit_frag; + break; + + case DrawType::imageMesh: + vertCode = spirv::draw_clockwise_image_mesh_vert; + fragCode = + fixedFunctionColorOutput + ? spirv::draw_clockwise_image_mesh_fixedcolor_frag + : spirv::draw_clockwise_image_mesh_frag; + break; + + case DrawType::imageRect: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::clipReset: + case DrawType::renderPassResolve: + case DrawType::renderPassInitialize: + RIVE_UNREACHABLE(); + } + break; +#else + RIVE_UNREACHABLE(); +#endif + } + + case gpu::InterlockMode::clockwiseAtomic: + { + // Since advanced blend is done via input attachments in + // clockwiseAtomic mode, we can swap out the "_fixedcolor" shader + // variants on a per-draw basis instead of per render pass. + const bool drawUsesAdvancedBlend = + enums::is_flag_set(shaderFeatures, + gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND); + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + vertCode = spirv::draw_clockwise_atomic_path_vert; + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)) + { + assert(fixedFunctionColorOutput); + assert(!enums::any_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly | + gpu::ShaderMiscFlags::nestedClipUpdateOnly)); + assert(!drawUsesAdvancedBlend); + fragCode = + spirv::draw_clockwise_atomic_borrowed_coverage_frag; + } + else if (enums::any_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly | + gpu::ShaderMiscFlags:: + nestedClipUpdateOnly)) + { + fragCode = + !drawUsesAdvancedBlend + ? spirv:: + draw_clockwise_atomic_clip_fixedcolor_frag + : spirv::draw_clockwise_atomic_clip_frag; + } + else + { + fragCode = + !drawUsesAdvancedBlend + ? spirv:: + draw_clockwise_atomic_path_fixedcolor_frag + : spirv::draw_clockwise_atomic_path_frag; + } + break; + + case DrawType::interiorTriangulation: + vertCode = + spirv::draw_clockwise_atomic_interior_triangles_vert; + if (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)) + { + assert(fixedFunctionColorOutput); + assert(!enums::any_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly | + gpu::ShaderMiscFlags::nestedClipUpdateOnly)); + assert(!drawUsesAdvancedBlend); + fragCode = spirv:: + draw_clockwise_atomic_borrowed_coverage_interior_triangles_frag; + } + else if (enums::any_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly | + gpu::ShaderMiscFlags:: + nestedClipUpdateOnly)) + { + fragCode = + !drawUsesAdvancedBlend + ? spirv:: + draw_clockwise_atomic_clip_interior_triangles_fixedcolor_frag + : spirv:: + draw_clockwise_atomic_clip_interior_triangles_frag; + } + else + { + fragCode = + !drawUsesAdvancedBlend + ? spirv:: + draw_clockwise_atomic_interior_triangles_fixedcolor_frag + : spirv:: + draw_clockwise_atomic_interior_triangles_frag; + } + break; + + case DrawType::atlasBlit: + vertCode = spirv::draw_clockwise_atomic_atlas_blit_vert; + fragCode = + !drawUsesAdvancedBlend + ? spirv:: + draw_clockwise_atomic_atlas_blit_fixedcolor_frag + : spirv::draw_clockwise_atomic_atlas_blit_frag; + break; + + case DrawType::imageMesh: + vertCode = spirv::draw_clockwise_atomic_image_mesh_vert; + fragCode = + !drawUsesAdvancedBlend + ? spirv:: + draw_clockwise_atomic_image_mesh_fixedcolor_frag + : spirv::draw_clockwise_atomic_image_mesh_frag; + break; + + case DrawType::clipReset: + vertCode = spirv::clear_clockwise_atomic_clip_vert; + fragCode = + !drawUsesAdvancedBlend + ? spirv::clear_clockwise_atomic_clip_fixedcolor_frag + : spirv::clear_clockwise_atomic_clip_frag; + break; + + case DrawType::renderPassInitialize: + vertCode = spirv::draw_fullscreen_quad_vert; + fragCode = + fixedFunctionColorOutput + ? spirv:: + init_clockwise_atomic_workaround_fixedcolor_frag + : spirv::init_clockwise_atomic_workaround_frag; + break; + + case DrawType::imageRect: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + case DrawType::msaaOuterCubics: + case DrawType::renderPassResolve: + RIVE_UNREACHABLE(); + } + break; } + + case gpu::InterlockMode::msaa: + { + switch (drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + RIVE_UNREACHABLE(); + + case DrawType::msaaOuterCubics: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + vertCode = + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_CLIP_RECT) + ? spirv::draw_msaa_path_vert + : spirv::draw_msaa_path_noclipdistance_vert; + fragCode = fixedFunctionColorOutput + ? spirv::draw_msaa_path_fixedcolor_frag + : spirv::draw_msaa_path_frag; + break; + + case DrawType::clipReset: + vertCode = spirv::draw_msaa_stencil_vert; + fragCode = spirv::draw_msaa_stencil_frag; + break; + + case DrawType::interiorTriangulation: + // Interior triangulation is not yet implemented for MSAA. + RIVE_UNREACHABLE(); + break; + + case DrawType::atlasBlit: + vertCode = + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_CLIP_RECT) + ? spirv::draw_msaa_atlas_blit_vert + : spirv::draw_msaa_atlas_blit_noclipdistance_vert; + fragCode = fixedFunctionColorOutput + ? spirv::draw_msaa_atlas_blit_fixedcolor_frag + : spirv::draw_msaa_atlas_blit_frag; + break; + + case DrawType::imageMesh: + vertCode = + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_CLIP_RECT) + ? spirv::draw_msaa_image_mesh_vert + : spirv::draw_msaa_image_mesh_noclipdistance_vert; + fragCode = fixedFunctionColorOutput + ? spirv::draw_msaa_image_mesh_fixedcolor_frag + : spirv::draw_msaa_image_mesh_frag; + break; + + case DrawType::renderPassInitialize: + // MSAA render passes get initialized by drawing the + // previous contents into the framebuffer. + // (LoadAction::preserveRenderTarget only.) + vertCode = spirv::draw_fullscreen_quad_vert; + fragCode = spirv::draw_msaa_color_seed_attachment_frag; + break; + + case DrawType::renderPassResolve: + vertCode = spirv::draw_fullscreen_quad_vert; + fragCode = spirv::draw_msaa_resolve_frag; + break; + + case DrawType::imageRect: + RIVE_UNREACHABLE(); + } + break; + } + } + + Span code; + switch (type) + { + case Type::vertex: + code = vertCode; + break; + case Type::fragment: + code = fragCode; + break; } - VK_CHECK(m_vk->CreateShaderModule(m_vk->device, - &vsInfo, - nullptr, - &m_vertexModule)); - VK_CHECK(m_vk->CreateShaderModule(m_vk->device, - &fsInfo, - nullptr, - &m_fragmentModule)); + assert(code.size_bytes() > 0); + createInfo.pCode = code.data(); + createInfo.codeSize = code.size_bytes(); + + if (m_vk->CreateShaderModule(m_vk->device, + &createInfo, + nullptr, + &m_module) != VK_SUCCESS) + { + m_module = VK_NULL_HANDLE; + } } DrawShaderVulkan::~DrawShaderVulkan() { - m_vk->DestroyShaderModule(m_vk->device, m_vertexModule, nullptr); - m_vk->DestroyShaderModule(m_vk->device, m_fragmentModule, nullptr); + m_vk->DestroyShaderModule(m_vk->device, m_module, nullptr); } } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.hpp b/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.hpp index e65d6bbc6..3e0f3ebdf 100644 --- a/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.hpp +++ b/thirdparty/rive_renderer/source/vulkan/draw_shader_vulkan.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2023 Rive + * Copyright 2025 Rive */ #pragma once @@ -10,85 +10,35 @@ namespace rive::gpu { -namespace spirv -{ -// Draw setup shaders. -extern rive::Span color_ramp_vert; -extern rive::Span color_ramp_frag; -extern rive::Span tessellate_vert; -extern rive::Span tessellate_frag; -extern rive::Span render_atlas_vert; -extern rive::Span render_atlas_fill_frag; -extern rive::Span render_atlas_stroke_frag; - -// InterlockMode::rasterOrdering shaders. -extern rive::Span draw_path_vert; -extern rive::Span draw_path_frag; -extern rive::Span draw_interior_triangles_vert; -extern rive::Span draw_interior_triangles_frag; -extern rive::Span draw_atlas_blit_vert; -extern rive::Span draw_atlas_blit_frag; -extern rive::Span draw_image_mesh_vert; -extern rive::Span draw_image_mesh_frag; - -// InterlockMode::atomics shaders. -extern rive::Span atomic_draw_path_vert; -extern rive::Span atomic_draw_path_frag; -extern rive::Span atomic_draw_path_fixedcolor_frag; -extern rive::Span atomic_draw_interior_triangles_vert; -extern rive::Span atomic_draw_interior_triangles_frag; -extern rive::Span - atomic_draw_interior_triangles_fixedcolor_frag; -extern rive::Span atomic_draw_atlas_blit_vert; -extern rive::Span atomic_draw_atlas_blit_frag; -extern rive::Span atomic_draw_atlas_blit_fixedcolor_frag; -extern rive::Span atomic_draw_image_rect_vert; -extern rive::Span atomic_draw_image_rect_frag; -extern rive::Span atomic_draw_image_rect_fixedcolor_frag; -extern rive::Span atomic_draw_image_mesh_vert; -extern rive::Span atomic_draw_image_mesh_frag; -extern rive::Span atomic_draw_image_mesh_fixedcolor_frag; -extern rive::Span atomic_resolve_vert; -extern rive::Span atomic_resolve_frag; -extern rive::Span atomic_resolve_fixedcolor_frag; -extern rive::Span atomic_resolve_coalesced_vert; -extern rive::Span atomic_resolve_coalesced_frag; - -// InterlockMode::clockwiseAtomic shaders. -extern rive::Span draw_clockwise_path_vert; -extern rive::Span draw_clockwise_path_frag; -extern rive::Span draw_clockwise_interior_triangles_vert; -extern rive::Span draw_clockwise_interior_triangles_frag; -extern rive::Span draw_clockwise_atlas_blit_vert; -extern rive::Span draw_clockwise_atlas_blit_frag; -extern rive::Span draw_clockwise_image_mesh_vert; -extern rive::Span draw_clockwise_image_mesh_frag; - -// Reload global SPIRV buffers from runtime data. -void hotload_shaders(rive::Span spirvData); -}; // namespace spirv - class VulkanContext; +} -// Wraps vertex and fragment shader modules for a specific combination of -// DrawType, InterlockMode, and ShaderFeatures. +namespace rive::gpu +{ class DrawShaderVulkan { public: - DrawShaderVulkan(VulkanContext*, - gpu::DrawType, - gpu::InterlockMode, - gpu::ShaderFeatures, - gpu::ShaderMiscFlags); + enum class Type + { + vertex, + fragment, + }; + DrawShaderVulkan(Type, + VulkanContext*, + DrawType, + ShaderFeatures, + InterlockMode, + ShaderMiscFlags); ~DrawShaderVulkan(); - VkShaderModule vertexModule() const { return m_vertexModule; } - VkShaderModule fragmentModule() const { return m_fragmentModule; } + DrawShaderVulkan(const DrawShaderVulkan&) = delete; + DrawShaderVulkan& operator=(const DrawShaderVulkan&) = delete; + + VkShaderModule module() const { return m_module; } private: const rcp m_vk; - VkShaderModule m_vertexModule = VK_NULL_HANDLE; - VkShaderModule m_fragmentModule = VK_NULL_HANDLE; + VkShaderModule m_module = VK_NULL_HANDLE; }; -} // namespace rive::gpu +} // namespace rive::gpu \ No newline at end of file diff --git a/thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.cpp b/thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.cpp new file mode 100644 index 000000000..dd2c6992a --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.cpp @@ -0,0 +1,664 @@ +/* + * Copyright 2025 Rive + */ + +#include "rive/math/bitwise.hpp" +#include "rive/renderer/vulkan/render_context_vulkan_impl.hpp" +#include "shaders/constants.glsl" +#include "draw_pipeline_layout_vulkan.hpp" +#include "pipeline_manager_vulkan.hpp" + +namespace rive::gpu +{ +static VkSamplerMipmapMode vk_sampler_mipmap_mode(rive::ImageFilter option) +{ + switch (option) + { + case rive::ImageFilter::nearest: + case rive::ImageFilter::bilinear: + return VK_SAMPLER_MIPMAP_MODE_NEAREST; + } + + RIVE_UNREACHABLE(); +} + +static VkSamplerAddressMode vk_sampler_address_mode(rive::ImageWrap option) +{ + switch (option) + { + case rive::ImageWrap::clamp: + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case rive::ImageWrap::repeat: + return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case rive::ImageWrap::mirror: + return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + } + + RIVE_UNREACHABLE(); +} + +static VkFilter vk_filter(rive::ImageFilter option) +{ + switch (option) + { + case rive::ImageFilter::bilinear: + return VK_FILTER_LINEAR; + case rive::ImageFilter::nearest: + return VK_FILTER_NEAREST; + } + + RIVE_UNREACHABLE(); +} + +PipelineManagerVulkan::PipelineManagerVulkan(rcp vk, + ShaderCompilationMode mode, + VkImageView nullTextureView) : + Super(mode), m_vk(std::move(vk)), m_atlasFormat(VK_FORMAT_R16_SFLOAT) +{ + // Create the immutable samplers. + VkSamplerCreateInfo linearSamplerCreateInfo = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = VK_FILTER_LINEAR, + .minFilter = VK_FILTER_LINEAR, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .minLod = 0, + .maxLod = 0, + }; + + VK_CHECK(m_vk->CreateSampler(m_vk->device, + &linearSamplerCreateInfo, + nullptr, + &m_linearSampler)); + + for (size_t i = 0; i < ImageSampler::MAX_SAMPLER_PERMUTATIONS; ++i) + { + ImageWrap wrapX = ImageSampler::GetWrapXOptionFromKey(i); + ImageWrap wrapY = ImageSampler::GetWrapYOptionFromKey(i); + ImageFilter filter = ImageSampler::GetFilterOptionFromKey(i); + VkFilter minMagFilter = vk_filter(filter); + + VkSamplerCreateInfo samplerCreateInfo = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = minMagFilter, + .minFilter = minMagFilter, + .mipmapMode = vk_sampler_mipmap_mode(filter), + .addressModeU = vk_sampler_address_mode(wrapX), + .addressModeV = vk_sampler_address_mode(wrapY), + .minLod = 0, + .maxLod = VK_LOD_CLAMP_NONE, + }; + + VK_CHECK(m_vk->CreateSampler(m_vk->device, + &samplerCreateInfo, + nullptr, + m_imageSamplers + i)); + } + + // All pipelines share the same perFlush bindings. + VkDescriptorSetLayoutBinding perFlushLayoutBindings[] = { + { + .binding = FLUSH_UNIFORM_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + }, + { + .binding = IMAGE_DRAW_UNIFORM_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + .descriptorCount = 1, + .stageFlags = + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + }, + { + .binding = PATH_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + }, + { + .binding = PAINT_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = 1, + .stageFlags = + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + }, + { + .binding = PAINT_AUX_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = 1, + .stageFlags = + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + }, + { + .binding = CONTOUR_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + }, + { + .binding = COVERAGE_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }, + { + .binding = TESS_VERTEX_TEXTURE_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + }, + { + .binding = GRAD_TEXTURE_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = &m_linearSampler, + }, + { + .binding = FEATHER_TEXTURE_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .stageFlags = + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = &m_linearSampler, + }, + { + .binding = ATLAS_TEXTURE_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = &m_linearSampler, + }, + }; + + VkDescriptorSetLayoutCreateInfo perFlushLayoutInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = std::size(perFlushLayoutBindings), + .pBindings = perFlushLayoutBindings, + }; + + VK_CHECK(m_vk->CreateDescriptorSetLayout(m_vk->device, + &perFlushLayoutInfo, + nullptr, + &m_perFlushDescriptorSetLayout)); + + // The imageTexture gets updated with every draw that uses it. + VkDescriptorSetLayoutBinding perDrawLayoutBindings[] = { + { + .binding = IMAGE_TEXTURE_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }, + }; + + VkDescriptorSetLayoutCreateInfo perDrawLayoutInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = std::size(perDrawLayoutBindings), + .pBindings = perDrawLayoutBindings, + }; + + VK_CHECK(m_vk->CreateDescriptorSetLayout(m_vk->device, + &perDrawLayoutInfo, + nullptr, + &m_perDrawDescriptorSetLayout)); + + // For when a set isn't used at all by a shader. + VkDescriptorSetLayoutCreateInfo emptyLayoutInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = 0, + }; + + VK_CHECK(m_vk->CreateDescriptorSetLayout(m_vk->device, + &emptyLayoutInfo, + nullptr, + &m_emptyDescriptorSetLayout)); + + // Create static descriptor sets. + VkDescriptorPoolSize staticDescriptorPoolSizes[] = { + { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, // m_nullImageTexture + }, + }; + + VkDescriptorPoolCreateInfo staticDescriptorPoolCreateInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .maxSets = 2, + .poolSizeCount = std::size(staticDescriptorPoolSizes), + .pPoolSizes = staticDescriptorPoolSizes, + }; + + VK_CHECK(m_vk->CreateDescriptorPool(m_vk->device, + &staticDescriptorPoolCreateInfo, + nullptr, + &m_staticDescriptorPool)); + + // Create a descriptor set to bind m_nullImageTexture when there is no image + // paint. + VkDescriptorSetAllocateInfo nullImageDescriptorSetInfo = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = m_staticDescriptorPool, + .descriptorSetCount = 1, + .pSetLayouts = &m_perDrawDescriptorSetLayout, + }; + + VK_CHECK(m_vk->AllocateDescriptorSets(m_vk->device, + &nullImageDescriptorSetInfo, + &m_nullImageDescriptorSet)); + + m_vk->updateImageDescriptorSets( + m_nullImageDescriptorSet, + { + .dstBinding = IMAGE_TEXTURE_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + }, + {{ + .sampler = m_imageSamplers[ImageSampler::LINEAR_CLAMP_SAMPLER_KEY], + .imageView = nullTextureView, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }}); +} + +PipelineManagerVulkan::~PipelineManagerVulkan() +{ + shutdownBackgroundThread(); + + m_vk->DestroyDescriptorSetLayout(m_vk->device, + m_perFlushDescriptorSetLayout, + nullptr); + m_vk->DestroyDescriptorSetLayout(m_vk->device, + m_perDrawDescriptorSetLayout, + nullptr); + m_vk->DestroyDescriptorSetLayout(m_vk->device, + m_emptyDescriptorSetLayout, + nullptr); + + m_vk->DestroyDescriptorPool(m_vk->device, m_staticDescriptorPool, nullptr); + for (VkSampler sampler : m_imageSamplers) + { + m_vk->DestroySampler(m_vk->device, sampler, nullptr); + } + m_vk->DestroySampler(m_vk->device, m_linearSampler, nullptr); +} + +DrawPipelineLayoutVulkan& PipelineManagerVulkan:: + getDrawPipelineLayoutSynchronous(InterlockMode interlockMode, + RenderPassOptionsVulkan renderPassOptions) +{ + // Mask off the options that don't affect layout. + renderPassOptions &= RENDER_PASS_OPTIONS_LAYOUT_MASK; + + const uint32_t key = + (static_cast(interlockMode) << RENDER_PASS_OPTION_COUNT) | + static_cast(renderPassOptions); + + // Make sure our key doesn't overflow 32 bits. + assert(key >> RENDER_PASS_OPTION_COUNT == + static_cast(interlockMode)); + + return getSharedObjectSynchronous(key, m_drawPipelineLayouts, [&]() { + return std::make_unique(this, + interlockMode, + renderPassOptions); + }); +} + +std::unique_ptr PipelineManagerVulkan::createVertexShader( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode) +{ + return std::make_unique(DrawShaderVulkan::Type::vertex, + vulkanContext(), + drawType, + shaderFeatures, + interlockMode, + ShaderMiscFlags::none); +} + +std::unique_ptr PipelineManagerVulkan::createFragmentShader( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags miscFlags) +{ + return std::make_unique(DrawShaderVulkan::Type::fragment, + vulkanContext(), + drawType, + shaderFeatures, + interlockMode, + miscFlags); +} + +RenderPassVulkan& PipelineManagerVulkan::getRenderPassSynchronous( + InterlockMode interlockMode, + RenderPassOptionsVulkan renderPassOptions, + VkFormat renderTargetFormat, + LoadAction colorLoadAction) +{ + const uint32_t key = RenderPassVulkan::Key(interlockMode, + renderPassOptions, + renderTargetFormat, + colorLoadAction); + + return getSharedObjectSynchronous(key, m_renderPasses, [&]() { + return std::make_unique(this, + interlockMode, + renderPassOptions, + renderTargetFormat, + colorLoadAction); + }); +} + +std::unique_ptr PipelineManagerVulkan::createPipeline( + PipelineCreateType createType, + uint64_t key, + const PipelineProps& props, + const PlatformFeatures& platformFeatures) +{ + if (createType == PipelineCreateType::async) + { + this->queueBackgroundJob(key, props, platformFeatures); + return nullptr; + } + + auto& renderPass = getRenderPassSynchronous(props.interlockMode, + props.renderPassOptions, + props.renderTargetFormat, + props.colorLoadAction); + + assert(createType == PipelineCreateType::sync); + return std::make_unique( + this, + *renderPass.drawPipelineLayout(), + props, + renderPass, + platformFeatures +#ifdef WITH_RIVE_TOOLS + , + props.synthesizedFailureType +#endif + ); +} + +PipelineStatus PipelineManagerVulkan::getPipelineStatus( + const DrawPipelineVulkan& pipeline) const +{ + return (VkPipeline(pipeline) == VK_NULL_HANDLE) ? PipelineStatus::errored + : PipelineStatus::ready; +} + +void PipelineManagerVulkan::clearCacheInternal() +{ + m_drawPipelineLayouts.clear(); + m_renderPasses.clear(); +} + +static Span get_relevant_blend_modes_for_pipeline_creation( + InterlockMode interlockMode, + DrawType drawType, + ShaderMiscFlags miscFlags, + DrawContents drawContents, + const PlatformFeatures& platformFeatures) +{ + constexpr BlendMode SRC_OVER_ONLY[] = {BlendMode::srcOver}; + + switch (interlockMode) + { + case InterlockMode::rasterOrdering: + case InterlockMode::atomics: + case InterlockMode::clockwise: + case InterlockMode::clockwiseAtomic: + return make_span(SRC_OVER_ONLY); + + case InterlockMode::msaa: + // If this assert ever fires (i.e. if we ever support GPU fixed- + // function advanced blend in Vulkan), we'll need to return a list + // of all blend modes instead of just srcOver. + assert( + enums::is_flag_set(drawContents, DrawContents::opaquePaint) || + !platformFeatures.supportsBlendAdvancedKHR); + return make_span(SRC_OVER_ONLY); + } + + RIVE_UNREACHABLE(); +} + +void PipelineManagerVulkan::forEachUbershaderPermutation( + InterlockMode interlockMode, + VkFormat renderTargetFormat, + VkImageUsageFlags renderTargetUsage, + LoadAction colorLoadAction, + const PlatformFeatures& platformFeatures, + const std::function& func) +{ + ForEachUbershaderPermutation( + interlockMode, + platformFeatures, + [&](DrawType drawType, + ShaderFeatures shaderFeatures, + ShaderMiscFlags shaderMiscFlags) { + PipelineProps props{ + .drawType = drawType, + .shaderFeatures = shaderFeatures, + .interlockMode = interlockMode, + .shaderMiscFlags = shaderMiscFlags, + .drawPipelineOptions = DrawPipelineVulkan::Options::none, + .renderTargetFormat = renderTargetFormat, + .colorLoadAction = colorLoadAction, + }; + + // only MSAA has draw contents options that are relevant to pipeline + // creation + const auto validDrawContents = + (interlockMode == InterlockMode::msaa) + ? DRAW_CONTENTS_FOR_MSAA_PIPELINE_STATE + : DrawContents::none; + + RenderPassOptionsVulkan fixedPassOptions = + RenderPassOptionsVulkan::none; + + if (interlockMode != InterlockMode::clockwiseAtomic && + interlockMode != InterlockMode::msaa && + enums::is_flag_set(shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) + { + // In non-clockwiseAtomic mode, the render pass + // fixedFunctionColorOutput should match the one in + // shaderMiscFlags + fixedPassOptions |= + RenderPassOptionsVulkan::fixedFunctionColorOutput; + } + + RenderPassOptionsVulkan validPassOptions = + RenderPassOptionsVulkan::none; + + switch (interlockMode) + { + case InterlockMode::rasterOrdering: + validPassOptions |= + RenderPassOptionsVulkan::manuallyResolved | + RenderPassOptionsVulkan::rasterOrderingInterruptible | + RenderPassOptionsVulkan::rasterOrderingResume; + break; + case InterlockMode::atomics: + if (!(renderTargetUsage & + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && + !enums::is_flag_set( + shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) + { + fixedPassOptions |= RenderPassOptionsVulkan:: + atomicCoalescedResolveAndTransfer; + } + break; + case InterlockMode::clockwise: + // no additional options + break; + case InterlockMode::clockwiseAtomic: + // Clockwise atomic render passes are allowed to (not) have + // this flag even if the shader has it specified (a shader + // is allowed to say "I don't read from the framebuffer" + // even if something else in the pipleine does) + if (enums::is_flag_set( + shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) + { + validPassOptions |= + RenderPassOptionsVulkan::fixedFunctionColorOutput; + } + break; + + case InterlockMode::msaa: + validPassOptions |= + RenderPassOptionsVulkan::manuallyResolved | + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture; + + if (enums::is_flag_set( + shaderMiscFlags, + ShaderMiscFlags::fixedFunctionColorOutput)) + { + // Like clockwiseAtomic, msaa render passes are allowed + // to not have this flag even if a specific shader + // specifies it. + validPassOptions |= + RenderPassOptionsVulkan::fixedFunctionColorOutput; + } + break; + } + + for (auto drawContents : + math::iterate_bit_combinations_in_mask(validDrawContents)) + { + const auto stencilInfo = + get_stencil_info(interlockMode, drawType, drawContents); + if (!stencilInfo.areDrawContentsValid) + { + continue; + } + + props.drawContents = drawContents; + for (auto variableRenderPassOptions : + math::iterate_bit_combinations_in_mask(validPassOptions)) + { + props.renderPassOptions = + variableRenderPassOptions | fixedPassOptions; + if (enums::is_flag_set( + props.renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved) && + enums::any_flag_set( + props.renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput | + RenderPassOptionsVulkan:: + rasterOrderingInterruptible)) + { + // manuallyResolved and these other flags are mutually + // exclusive + continue; + } + + if (enums::is_flag_set( + props.renderPassOptions, + RenderPassOptionsVulkan:: + atomicCoalescedResolveAndTransfer)) + { + if (enums::is_flag_set(props.renderPassOptions, + RenderPassOptionsVulkan:: + fixedFunctionColorOutput)) + { + // atomicCoalescedResolveAndTransfer should never be + // set when fixedFunctionColorOutput is set. + continue; + } + + if (drawType == DrawType::renderPassResolve && + !enums::is_flag_set( + props.shaderMiscFlags, + ShaderMiscFlags::coalescedResolveAndTransfer)) + { + // ShaderMiscFlags::coalescedResolveAndTransfer will + // never be set if atomicCoalescedResolveAndTransfer + // is not set on the render pass + continue; + } + } + + auto blendModes = + get_relevant_blend_modes_for_pipeline_creation( + interlockMode, + drawType, + shaderMiscFlags, + props.drawContents, + platformFeatures); + for (auto blendMode : blendModes) + { + props.blendMode = blendMode; + if (!func(props)) + { + return false; + } + } + } + } + + return true; + }); +} + +#if !defined(NDEBUG) +bool PipelineManagerVulkan::isValidUbershaderPipelineProps( + const PipelineProps& props, + const PlatformFeatures& platformFeatures) +{ + bool found = false; + auto curKey = props.createKey(platformFeatures); + + forEachUbershaderPermutation( + props.interlockMode, + props.renderTargetFormat, + enums::is_flag_set( + props.renderPassOptions, + RenderPassOptionsVulkan::atomicCoalescedResolveAndTransfer) + ? VkImageUsageFlagBits(0) + : VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + props.colorLoadAction, + platformFeatures, + [&found, curKey, &platformFeatures](const PipelineProps& validProps) { + auto testKey = validProps.createKey(platformFeatures); + if (testKey == curKey) + { + found = true; + } + + return !found; // Keep iterating if not found. + }); + + return found; +} +#endif + +void PipelineManagerVulkan::queueUbershaderPipelineCreation( + InterlockMode interlockMode, + VkFormat renderTargetFormat, + VkImageUsageFlags renderTargetUsage, + LoadAction colorLoadAction, + const PlatformFeatures& platformFeatures) +{ + forEachUbershaderPermutation( + interlockMode, + renderTargetFormat, + renderTargetUsage, + colorLoadAction, + platformFeatures, + [this, &platformFeatures](const PipelineProps& props) { + queuePipelineIfNotFound(props, platformFeatures); + return true; + }); +} + +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.hpp b/thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.hpp new file mode 100644 index 000000000..68762de64 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/pipeline_manager_vulkan.hpp @@ -0,0 +1,144 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include "rive/renderer/async_pipeline_manager.hpp" +#include "draw_pipeline_vulkan.hpp" +#include "render_pass_vulkan.hpp" + +namespace rive::gpu +{ +class PipelineManagerVulkan : public AsyncPipelineManager +{ + using Super = AsyncPipelineManager; + +public: + PipelineManagerVulkan(rcp, + ShaderCompilationMode, + VkImageView nullTextureView); + ~PipelineManagerVulkan(); + + RenderPassVulkan& getRenderPassSynchronous(InterlockMode, + RenderPassOptionsVulkan, + VkFormat, + LoadAction); + + DrawPipelineLayoutVulkan& getDrawPipelineLayoutSynchronous( + InterlockMode, + RenderPassOptionsVulkan); + + uint32_t vendorID() const + { + return m_vk->physicalDeviceProperties().vendorID; + } + + VkFormat atlasFormat() const { return m_atlasFormat; } + + VulkanContext* vulkanContext() const { return m_vk.get(); } + VkDescriptorSetLayout perFlushDescriptorSetLayout() const + { + return m_perFlushDescriptorSetLayout; + } + VkDescriptorSetLayout perDrawDescriptorSetLayout() const + { + return m_perDrawDescriptorSetLayout; + } + VkDescriptorSetLayout emptyDescriptorSetLayout() const + { + return m_emptyDescriptorSetLayout; + } + + VkSampler linearSampler() const { return m_linearSampler; } + VkSampler imageSampler(uint32_t i) const { return m_imageSamplers[i]; } + + VkDescriptorSet nullImageDescriptorSet() const + { + return m_nullImageDescriptorSet; + } + + enum class PLSBackingType : bool + { + inputAttachment, + storageTexture, + }; + + PLSBackingType plsBackingType(gpu::InterlockMode interlockMode) + { + if (interlockMode == gpu::InterlockMode::clockwise) + { + assert(m_vk->features.fragmentShaderPixelInterlock); + return PLSBackingType::storageTexture; + } + return PLSBackingType::inputAttachment; + } + + void forEachUbershaderPermutation( + InterlockMode, + VkFormat renderTargetFormat, + VkImageUsageFlags renderTargetUsage, + LoadAction, + const PlatformFeatures&, + const std::function& props); + +#if !defined(NDEBUG) + virtual bool isValidUbershaderPipelineProps( + const PipelineProps& props, + const PlatformFeatures& platformFeatures) override; +#endif + + void queueUbershaderPipelineCreation(InterlockMode, + VkFormat renderTargetFormat, + VkImageUsageFlags renderTargetUsage, + LoadAction, + const PlatformFeatures&); + +private: + virtual std::unique_ptr createVertexShader( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode) override; + + virtual std::unique_ptr createFragmentShader( + DrawType drawType, + ShaderFeatures shaderFeatures, + InterlockMode interlockMode, + ShaderMiscFlags miscFlags) override; + + virtual std::unique_ptr createPipeline( + PipelineCreateType createType, + uint64_t key, + const PipelineProps& props, + const PlatformFeatures&) override; + + virtual PipelineStatus getPipelineStatus( + const DrawPipelineVulkan&) const override; + + virtual void clearCacheInternal() override; + + std::unordered_map> + m_drawPipelineLayouts; + + std::unordered_map> + m_renderPasses; + + rcp m_vk; + VkFormat m_atlasFormat; + + // Samplers. + VkSampler m_linearSampler; + VkSampler m_imageSamplers[ImageSampler::MAX_SAMPLER_PERMUTATIONS]; + + // With the exception of PLS texture bindings, which differ by interlock + // mode, all other shaders use the same shared descriptor set layouts. + VkDescriptorSetLayout m_perFlushDescriptorSetLayout; + VkDescriptorSetLayout m_perDrawDescriptorSetLayout; + VkDescriptorSetLayout m_emptyDescriptorSetLayout; // For when a set isn't + // used by a shader. + VkDescriptorPool m_staticDescriptorPool; // For descriptorSets that never + // change between frames. + VkDescriptorSet m_nullImageDescriptorSet; +}; + +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/render_context_vulkan_impl.cpp b/thirdparty/rive_renderer/source/vulkan/render_context_vulkan_impl.cpp index 55fe55b1e..f56904c86 100644 --- a/thirdparty/rive_renderer/source/vulkan/render_context_vulkan_impl.cpp +++ b/thirdparty/rive_renderer/source/vulkan/render_context_vulkan_impl.cpp @@ -4,217 +4,34 @@ #include "rive/renderer/vulkan/render_context_vulkan_impl.hpp" -#include "draw_shader_vulkan.hpp" +#include "vulkan_shaders.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif #include "rive/renderer/stack_vector.hpp" #include "rive/renderer/texture.hpp" #include "rive/renderer/rive_render_buffer.hpp" #include "rive/renderer/vulkan/render_target_vulkan.hpp" #include "shaders/constants.glsl" +#include "common_layouts.hpp" +#include "draw_pipeline_vulkan.hpp" +#include "draw_pipeline_layout_vulkan.hpp" +#include "draw_shader_vulkan.hpp" +#include "pipeline_manager_vulkan.hpp" +#include "render_pass_vulkan.hpp" +#include "instance_chunker.hpp" +#include -// Common layout descriptors shared by various pipelines. -namespace layout +namespace rive::gpu { -constexpr static VkVertexInputBindingDescription PATH_INPUT_BINDINGS[] = {{ - .binding = 0, - .stride = sizeof(rive::gpu::PatchVertex), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, -}}; -constexpr static VkVertexInputAttributeDescription PATH_VERTEX_ATTRIBS[] = { - { - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = 0, - }, - { - .location = 1, - .binding = 0, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = 4 * sizeof(float), - }, -}; -constexpr static VkPipelineVertexInputStateCreateInfo PATH_VERTEX_INPUT_STATE = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = std::size(PATH_INPUT_BINDINGS), - .pVertexBindingDescriptions = PATH_INPUT_BINDINGS, - .vertexAttributeDescriptionCount = std::size(PATH_VERTEX_ATTRIBS), - .pVertexAttributeDescriptions = PATH_VERTEX_ATTRIBS, -}; - -constexpr static VkVertexInputBindingDescription INTERIOR_TRI_INPUT_BINDINGS[] = - {{ - .binding = 0, - .stride = sizeof(rive::gpu::TriangleVertex), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }}; -constexpr static VkVertexInputAttributeDescription - INTERIOR_TRI_VERTEX_ATTRIBS[] = { - { - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32G32B32_SFLOAT, - .offset = 0, - }, -}; -constexpr static VkPipelineVertexInputStateCreateInfo - INTERIOR_TRI_VERTEX_INPUT_STATE = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = std::size(INTERIOR_TRI_INPUT_BINDINGS), - .pVertexBindingDescriptions = INTERIOR_TRI_INPUT_BINDINGS, - .vertexAttributeDescriptionCount = - std::size(INTERIOR_TRI_VERTEX_ATTRIBS), - .pVertexAttributeDescriptions = INTERIOR_TRI_VERTEX_ATTRIBS, -}; - -constexpr static VkVertexInputBindingDescription IMAGE_RECT_INPUT_BINDINGS[] = { - { - .binding = 0, - .stride = sizeof(rive::gpu::ImageRectVertex), - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }}; -constexpr static VkVertexInputAttributeDescription IMAGE_RECT_VERTEX_ATTRIBS[] = - { - { - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = 0, - }, -}; -constexpr static VkPipelineVertexInputStateCreateInfo - IMAGE_RECT_VERTEX_INPUT_STATE = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = std::size(IMAGE_RECT_INPUT_BINDINGS), - .pVertexBindingDescriptions = IMAGE_RECT_INPUT_BINDINGS, - .vertexAttributeDescriptionCount = std::size(IMAGE_RECT_VERTEX_ATTRIBS), - .pVertexAttributeDescriptions = IMAGE_RECT_VERTEX_ATTRIBS, -}; - -constexpr static VkVertexInputBindingDescription IMAGE_MESH_INPUT_BINDINGS[] = { - { - .binding = 0, - .stride = sizeof(float) * 2, - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }, - { - .binding = 1, - .stride = sizeof(float) * 2, - .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, - }, -}; -constexpr static VkVertexInputAttributeDescription IMAGE_MESH_VERTEX_ATTRIBS[] = - { - { - .location = 0, - .binding = 0, - .format = VK_FORMAT_R32G32_SFLOAT, - .offset = 0, - }, - { - .location = 1, - .binding = 1, - .format = VK_FORMAT_R32G32_SFLOAT, - .offset = 0, - }, -}; -constexpr static VkPipelineVertexInputStateCreateInfo - IMAGE_MESH_VERTEX_INPUT_STATE = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = std::size(IMAGE_MESH_INPUT_BINDINGS), - .pVertexBindingDescriptions = IMAGE_MESH_INPUT_BINDINGS, - .vertexAttributeDescriptionCount = std::size(IMAGE_MESH_VERTEX_ATTRIBS), - .pVertexAttributeDescriptions = IMAGE_MESH_VERTEX_ATTRIBS, -}; - -constexpr static VkPipelineVertexInputStateCreateInfo EMPTY_VERTEX_INPUT_STATE = - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 0, - .vertexAttributeDescriptionCount = 0, -}; - -constexpr static VkPipelineInputAssemblyStateCreateInfo - INPUT_ASSEMBLY_TRIANGLE_STRIP = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, -}; - -constexpr static VkPipelineInputAssemblyStateCreateInfo - INPUT_ASSEMBLY_TRIANGLE_LIST = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, -}; - -constexpr static VkPipelineViewportStateCreateInfo SINGLE_VIEWPORT = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .viewportCount = 1, - .scissorCount = 1, -}; +using PLSBackingType = PipelineManagerVulkan::PLSBackingType; -constexpr static VkPipelineRasterizationStateCreateInfo - RASTER_STATE_CULL_BACK_CCW = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .polygonMode = VK_POLYGON_MODE_FILL, - .cullMode = VK_CULL_MODE_BACK_BIT, - .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, - .lineWidth = 1.f, -}; - -constexpr static VkPipelineRasterizationStateCreateInfo - RASTER_STATE_CULL_BACK_CW = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .polygonMode = VK_POLYGON_MODE_FILL, - .cullMode = VK_CULL_MODE_BACK_BIT, - .frontFace = VK_FRONT_FACE_CLOCKWISE, - .lineWidth = 1.f, -}; - -constexpr static VkPipelineMultisampleStateCreateInfo MSAA_DISABLED = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, -}; - -constexpr static VkPipelineColorBlendAttachmentState BLEND_DISABLED_VALUES = { - .colorWriteMask = rive::gpu::vkutil::kColorWriteMaskRGBA}; -constexpr static VkPipelineColorBlendStateCreateInfo - SINGLE_ATTACHMENT_BLEND_DISABLED = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &BLEND_DISABLED_VALUES, -}; +// Indices of coverage and clip images in the m_plsTransientImageArray. +constexpr uint32_t PLS_TRANSIENT_COVERAGE_IDX = 0u; +constexpr uint32_t PLS_TRANSIENT_CLIP_IDX = 1u; -constexpr static VkDynamicState DYNAMIC_VIEWPORT_SCISSOR_VALUES[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, -}; -constexpr static VkPipelineDynamicStateCreateInfo DYNAMIC_VIEWPORT_SCISSOR = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = std::size(DYNAMIC_VIEWPORT_SCISSOR_VALUES), - .pDynamicStates = DYNAMIC_VIEWPORT_SCISSOR_VALUES, -}; - -constexpr static VkAttachmentReference SINGLE_ATTACHMENT_SUBPASS_REFERENCE = { - .attachment = 0, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, -}; -constexpr static VkSubpassDescription SINGLE_ATTACHMENT_SUBPASS = { - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .colorAttachmentCount = 1, - .pColorAttachments = &SINGLE_ATTACHMENT_SUBPASS_REFERENCE, -}; -} // namespace layout - -namespace rive::gpu -{ -// This is the render pass attachment index for the final color output in the -// "coalesced" atomic resolve. -// NOTE: This attachment is still referenced as color attachment 0 by the -// resolve subpass, so the shader doesn't need to know about it. -// NOTE: Atomic mode does not use SCRATCH_COLOR_PLANE_IDX, which is why we chose -// to alias this one. -constexpr static uint32_t COALESCED_ATOMIC_RESOLVE_IDX = - SCRATCH_COLOR_PLANE_IDX; +constexpr VkDeviceSize ZERO_OFFSET[1] = {0}; +constexpr uint32_t ZERO_OFFSET_32[1] = {0}; static VkBufferUsageFlagBits render_buffer_usage_flags( RenderBufferType renderBufferType) @@ -273,28 +90,310 @@ rcp RenderContextVulkanImpl::makeImageTexture( uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) { - auto texture = m_vk->makeTexture2D({ - .format = VK_FORMAT_R8G8B8A8_UNORM, - .extent = {width, height}, - .mipLevels = mipLevelCount, - }); - texture->stageContentsForUpload(imageDataRGBAPremul, height * width * 4); + if (format != GPUTextureFormat::rgba32) + { + assert(!"unsupported format"); + return nullptr; + } + + auto texture = m_vk->makeTexture2D( + { + .format = VK_FORMAT_R8G8B8A8_UNORM, + .extent = {width, height}, + .mipLevels = mipLevelCount, + }, + "RenderContext imageTexture"); + texture->scheduleUpload(imageDataRGBAPremul, height * width * 4); return texture; } +// A RenderTargetVulkan backed by a vkutil::Texture2D. Used by RenderCanvas. +// The texture is shared with a RiveRenderImage for compositing. +class RenderTargetVulkanTexture : public RenderTargetVulkan +{ +public: + RenderTargetVulkanTexture(rcp vk, + rcp texture, + uint32_t width, + uint32_t height, + VkFormat format, + VkImageUsageFlags usage) : + RenderTargetVulkan(std::move(vk), width, height, format, usage), + m_texture(std::move(texture)) + {} + + VkImage targetImage() const override { return m_texture->vkImage(); } + VkImageView targetImageView() const override + { + return m_texture->vkImageView(); + } + + void updateLastAccess(const vkutil::ImageAccess& a) override + { + m_texture->lastAccess() = a; + } + + VkImage accessTargetImage(VkCommandBuffer commandBuffer, + const vkutil::ImageAccess& dstAccess, + vkutil::ImageAccessAction accessAction) override + { + m_texture->barrier(commandBuffer, dstAccess, accessAction); + return m_texture->vkImage(); + } + + VkImageView accessTargetImageView( + VkCommandBuffer commandBuffer, + const vkutil::ImageAccess& dstAccess, + vkutil::ImageAccessAction accessAction) override + { + m_texture->barrier(commandBuffer, dstAccess, accessAction); + return m_texture->vkImageView(); + } + +private: + rcp m_texture; +}; + +#ifdef RIVE_CANVAS +rcp RenderContextVulkanImpl::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + VkImageUsageFlags usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT; + + auto texture = m_vk->makeTexture2D( + { + .format = format, + .extent = {width, height}, + .usage = usage, + }, + "RenderCanvas"); + + auto renderImage = make_rcp(texture); + + auto renderTarget = rcp(new RenderTargetVulkanTexture(m_vk, + std::move(texture), + width, + height, + format, + usage)); + + return make_rcp(std::move(renderImage), + std::move(renderTarget)); +} +#endif + +// Common base class for a pipeline that renders a texture resource at the +// beginning of a flush, which is then read during the main draw pass. +class RenderContextVulkanImpl::ResourceTexturePipeline +{ +public: + ResourceTexturePipeline(rcp vk, + VkFormat format, + VkAttachmentLoadOp loadOp, + VkPipelineStageFlags resourceConsumptionStage, + const char* label, + const DriverWorkarounds& workarounds) : + m_vk(std::move(vk)) + { + const VkAttachmentDescription attachment = { + .format = format, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = loadOp, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + + const VkSubpassDependency dependencies[] = { + { + .srcSubpass = VK_SUBPASS_EXTERNAL, + .dstSubpass = 0, + .srcStageMask = resourceConsumptionStage, + .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = VK_ACCESS_SHADER_READ_BIT, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + }, + { + .srcSubpass = 0, + .dstSubpass = VK_SUBPASS_EXTERNAL, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = resourceConsumptionStage, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, + }, + }; + + const VkRenderPassCreateInfo renderPassCreateInfo = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &attachment, + .subpassCount = 1, + .pSubpasses = &layout::SINGLE_ATTACHMENT_SUBPASS, + .dependencyCount = std::size(dependencies), + .pDependencies = dependencies, + }; + + VK_CHECK(m_vk->CreateRenderPass(m_vk->device, + &renderPassCreateInfo, + nullptr, + &m_renderPass)); + + const std::string renderPassLabel = + (std::ostringstream() << label << " RenderPass").str(); + m_vk->setDebugNameIfEnabled(uint64_t(m_renderPass), + VK_OBJECT_TYPE_RENDER_PASS, + renderPassLabel.c_str()); + + if (workarounds.needsInterruptibleRenderPasses()) + { + // We are running on a device that is known to crash if a render + // pass is too complex. Create another render pass that is designed + // to resume atlas rendering in the event that the previous render + // pass had to be interrupted (in order to work around the crash). + auto resumingAttachment = attachment; + resumingAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + resumingAttachment.initialLayout = + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkRenderPassCreateInfo resumingRenderPassCreateInfo = + renderPassCreateInfo; + resumingRenderPassCreateInfo.pAttachments = &resumingAttachment; + + VK_CHECK(m_vk->CreateRenderPass(m_vk->device, + &resumingRenderPassCreateInfo, + nullptr, + &m_resumingRenderPass)); + + const std::string resumingRenderPassLabel = + (std::ostringstream() << label << " RESUME RenderPass").str(); + m_vk->setDebugNameIfEnabled(uint64_t(m_resumingRenderPass), + VK_OBJECT_TYPE_RENDER_PASS, + resumingRenderPassLabel.c_str()); + } + } + + virtual ~ResourceTexturePipeline() + { + m_vk->DestroyRenderPass(m_vk->device, m_renderPass, nullptr); + if (m_resumingRenderPass != VK_NULL_HANDLE) + { + m_vk->DestroyRenderPass(m_vk->device, + m_resumingRenderPass, + nullptr); + } + } + + VkRenderPass renderPass() const { return m_renderPass; } + + void beginRenderPass(VkCommandBuffer commandBuffer, + VkRect2D renderArea, + VkFramebuffer framebuffer) + { + beginRenderPass(commandBuffer, + renderArea, + framebuffer, + RenderPassType::primary); + } + + // Some early Android tilers are known to crash when a render pass is too + // complex. This is a mechanism to interrupt and begin a new render pass on + // affected devices after a pre-set complexity is reached. + void interruptRenderPassIfNeeded(VkCommandBuffer commandBuffer, + VkRect2D renderArea, + VkFramebuffer framebuffer, + uint32_t nextInstanceCount, + const DriverWorkarounds& workarounds) + { + assert(m_instanceCountInCurrentRenderPass <= + workarounds.maxInstancesPerRenderPass); + assert(nextInstanceCount <= workarounds.maxInstancesPerRenderPass); + + if (m_instanceCountInCurrentRenderPass + nextInstanceCount > + workarounds.maxInstancesPerRenderPass) + { + m_vk->CmdEndRenderPass(commandBuffer); + + // We don't need to bind new pipelines, even though we changed + // the render pass, because Vulkan allows for pipelines to be + // used interchangeably with "compatible" render passes. + beginRenderPass(commandBuffer, + renderArea, + framebuffer, + RenderPassType::resume); + } + m_instanceCountInCurrentRenderPass += nextInstanceCount; + }; + +protected: + const rcp m_vk; + +private: + enum class RenderPassType + { + primary, + resume, + }; + + void beginRenderPass(VkCommandBuffer commandBuffer, + VkRect2D renderArea, + VkFramebuffer framebuffer, + RenderPassType renderPassType) + { + constexpr static VkClearValue CLEAR_ZERO = {}; + + const VkRenderPass renderPass = + (renderPassType == RenderPassType::primary) ? m_renderPass + : m_resumingRenderPass; + assert(renderPass != VK_NULL_HANDLE); + + VkRenderPassBeginInfo renderPassBeginInfo = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = renderPass, + .framebuffer = framebuffer, + .renderArea = renderArea, + .clearValueCount = 1, + .pClearValues = &CLEAR_ZERO, + }; + + m_vk->CmdBeginRenderPass(commandBuffer, + &renderPassBeginInfo, + VK_SUBPASS_CONTENTS_INLINE); + + m_instanceCountInCurrentRenderPass = 0; + } + + VkRenderPass m_renderPass; + VkRenderPass m_resumingRenderPass = VK_NULL_HANDLE; + uint32_t m_instanceCountInCurrentRenderPass; +}; + // Renders color ramps to the gradient texture. class RenderContextVulkanImpl::ColorRampPipeline + : public ResourceTexturePipeline { public: - ColorRampPipeline(RenderContextVulkanImpl* impl) : - m_vk(ref_rcp(impl->vulkanContext())) + ColorRampPipeline(PipelineManagerVulkan* pipelineManager, + const DriverWorkarounds& workarounds) : + ResourceTexturePipeline(ref_rcp(pipelineManager->vulkanContext()), + VK_FORMAT_R8G8B8A8_UNORM, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + "ColorRamp", + workarounds) { + VkDescriptorSetLayout perFlushDescriptorSetLayout = + pipelineManager->perFlushDescriptorSetLayout(); VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 1, - .pSetLayouts = &impl->m_perFlushDescriptorSetLayout, + .pSetLayouts = &perFlushDescriptorSetLayout, }; VK_CHECK(m_vk->CreatePipelineLayout(m_vk->device, @@ -363,27 +462,6 @@ class RenderContextVulkanImpl::ColorRampPipeline .pVertexAttributeDescriptions = &vertexAttributeDescription, }; - VkAttachmentDescription attachment = { - .format = VK_FORMAT_R8G8B8A8_UNORM, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - VkRenderPassCreateInfo renderPassCreateInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &attachment, - .subpassCount = 1, - .pSubpasses = &layout::SINGLE_ATTACHMENT_SUBPASS, - }; - - VK_CHECK(m_vk->CreateRenderPass(m_vk->device, - &renderPassCreateInfo, - nullptr, - &m_renderPass)); - VkGraphicsPipelineCreateInfo pipelineCreateInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .stageCount = 2, @@ -396,7 +474,7 @@ class RenderContextVulkanImpl::ColorRampPipeline .pColorBlendState = &layout::SINGLE_ATTACHMENT_BLEND_DISABLED, .pDynamicState = &layout::DYNAMIC_VIEWPORT_SCISSOR, .layout = m_pipelineLayout, - .renderPass = m_renderPass, + .renderPass = renderPass(), }; VK_CHECK(m_vk->CreateGraphicsPipelines(m_vk->device, @@ -405,6 +483,9 @@ class RenderContextVulkanImpl::ColorRampPipeline &pipelineCreateInfo, nullptr, &m_renderPipeline)); + m_vk->setDebugNameIfEnabled(uint64_t(m_renderPipeline), + VK_OBJECT_TYPE_PIPELINE, + "Color Ramp Pipeline"); m_vk->DestroyShaderModule(m_vk->device, vertexShader, nullptr); m_vk->DestroyShaderModule(m_vk->device, fragmentShader, nullptr); @@ -413,35 +494,36 @@ class RenderContextVulkanImpl::ColorRampPipeline ~ColorRampPipeline() { m_vk->DestroyPipelineLayout(m_vk->device, m_pipelineLayout, nullptr); - m_vk->DestroyRenderPass(m_vk->device, m_renderPass, nullptr); m_vk->DestroyPipeline(m_vk->device, m_renderPipeline, nullptr); } VkPipelineLayout pipelineLayout() const { return m_pipelineLayout; } - VkRenderPass renderPass() const { return m_renderPass; } VkPipeline renderPipeline() const { return m_renderPipeline; } private: - rcp m_vk; VkPipelineLayout m_pipelineLayout; - VkRenderPass m_renderPass; VkPipeline m_renderPipeline; }; // Renders tessellated vertices to the tessellation texture. class RenderContextVulkanImpl::TessellatePipeline + : public ResourceTexturePipeline { public: - TessellatePipeline(RenderContextVulkanImpl* impl) : - m_vk(ref_rcp(impl->vulkanContext())) + TessellatePipeline(PipelineManagerVulkan* pipelineManager, + const DriverWorkarounds& workarounds) : + ResourceTexturePipeline(ref_rcp(pipelineManager->vulkanContext()), + VK_FORMAT_R32G32B32A32_UINT, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + "Tessellate", + workarounds) { VkDescriptorSetLayout pipelineDescriptorSetLayouts[] = { - impl->m_perFlushDescriptorSetLayout, - impl->m_emptyDescriptorSetLayout, - impl->m_immutableSamplerDescriptorSetLayout, + pipelineManager->perFlushDescriptorSetLayout(), + pipelineManager->emptyDescriptorSetLayout(), }; static_assert(PER_FLUSH_BINDINGS_SET == 0); - static_assert(IMMUTABLE_SAMPLER_BINDINGS_SET == 2); VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, @@ -536,27 +618,6 @@ class RenderContextVulkanImpl::TessellatePipeline .pVertexAttributeDescriptions = vertexAttributeDescriptions, }; - VkAttachmentDescription attachment = { - .format = VK_FORMAT_R32G32B32A32_UINT, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - VkRenderPassCreateInfo renderPassCreateInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &attachment, - .subpassCount = 1, - .pSubpasses = &layout::SINGLE_ATTACHMENT_SUBPASS, - }; - - VK_CHECK(m_vk->CreateRenderPass(m_vk->device, - &renderPassCreateInfo, - nullptr, - &m_renderPass)); - VkGraphicsPipelineCreateInfo pipelineCreateInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .stageCount = 2, @@ -569,7 +630,7 @@ class RenderContextVulkanImpl::TessellatePipeline .pColorBlendState = &layout::SINGLE_ATTACHMENT_BLEND_DISABLED, .pDynamicState = &layout::DYNAMIC_VIEWPORT_SCISSOR, .layout = m_pipelineLayout, - .renderPass = m_renderPass, + .renderPass = renderPass(), }; VK_CHECK(m_vk->CreateGraphicsPipelines(m_vk->device, @@ -578,43 +639,46 @@ class RenderContextVulkanImpl::TessellatePipeline &pipelineCreateInfo, nullptr, &m_renderPipeline)); + m_vk->setDebugNameIfEnabled(uint64_t(m_renderPipeline), + VK_OBJECT_TYPE_PIPELINE, + "Tesselation Pipeline"); m_vk->DestroyShaderModule(m_vk->device, vertexShader, nullptr); m_vk->DestroyShaderModule(m_vk->device, fragmentShader, nullptr); } - ~TessellatePipeline() + ~TessellatePipeline() override { m_vk->DestroyPipelineLayout(m_vk->device, m_pipelineLayout, nullptr); - m_vk->DestroyRenderPass(m_vk->device, m_renderPass, nullptr); m_vk->DestroyPipeline(m_vk->device, m_renderPipeline, nullptr); } VkPipelineLayout pipelineLayout() const { return m_pipelineLayout; } - VkRenderPass renderPass() const { return m_renderPass; } VkPipeline renderPipeline() const { return m_renderPipeline; } private: - rcp m_vk; VkPipelineLayout m_pipelineLayout; - VkRenderPass m_renderPass; VkPipeline m_renderPipeline; }; // Renders feathers to the atlas. -class RenderContextVulkanImpl::AtlasPipeline +class RenderContextVulkanImpl::AtlasPipeline : public ResourceTexturePipeline { public: - AtlasPipeline(RenderContextVulkanImpl* impl) : - m_vk(ref_rcp(impl->vulkanContext())) + AtlasPipeline(PipelineManagerVulkan* pipelineManager, + const DriverWorkarounds& workarounds) : + ResourceTexturePipeline(ref_rcp(pipelineManager->vulkanContext()), + pipelineManager->atlasFormat(), + VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + "Atlas", + workarounds) { VkDescriptorSetLayout pipelineDescriptorSetLayouts[] = { - impl->m_perFlushDescriptorSetLayout, - impl->m_emptyDescriptorSetLayout, - impl->m_immutableSamplerDescriptorSetLayout, + pipelineManager->perFlushDescriptorSetLayout(), + pipelineManager->emptyDescriptorSetLayout(), }; static_assert(PER_FLUSH_BINDINGS_SET == 0); - static_assert(IMMUTABLE_SAMPLER_BINDINGS_SET == 2); VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, @@ -679,26 +743,6 @@ class RenderContextVulkanImpl::AtlasPipeline }, }; - VkAttachmentDescription attachment = { - .format = impl->m_atlasFormat, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - VkRenderPassCreateInfo renderPassCreateInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &attachment, - .subpassCount = 1, - .pSubpasses = &layout::SINGLE_ATTACHMENT_SUBPASS, - }; - VK_CHECK(m_vk->CreateRenderPass(m_vk->device, - &renderPassCreateInfo, - nullptr, - &m_renderPass)); - VkPipelineColorBlendAttachmentState blendState = VkPipelineColorBlendAttachmentState{ .blendEnable = VK_TRUE, @@ -719,12 +763,12 @@ class RenderContextVulkanImpl::AtlasPipeline .pVertexInputState = &layout::PATH_VERTEX_INPUT_STATE, .pInputAssemblyState = &layout::INPUT_ASSEMBLY_TRIANGLE_LIST, .pViewportState = &layout::SINGLE_VIEWPORT, - .pRasterizationState = &layout::RASTER_STATE_CULL_BACK_CW, + .pRasterizationState = &layout::RASTER_STATE_CULL_NONE_CW, .pMultisampleState = &layout::MSAA_DISABLED, .pColorBlendState = &blendStateCreateInfo, .pDynamicState = &layout::DYNAMIC_VIEWPORT_SCISSOR, .layout = m_pipelineLayout, - .renderPass = m_renderPass, + .renderPass = renderPass(), }; stages[1].module = fragmentFillShader; @@ -735,6 +779,9 @@ class RenderContextVulkanImpl::AtlasPipeline &pipelineCreateInfo, nullptr, &m_fillPipeline)); + m_vk->setDebugNameIfEnabled(uint64_t(m_fillPipeline), + VK_OBJECT_TYPE_PIPELINE, + "Atlas Fill Pipeline"); stages[1].module = fragmentStrokeShader; blendState.colorBlendOp = VK_BLEND_OP_MAX; @@ -744,1231 +791,229 @@ class RenderContextVulkanImpl::AtlasPipeline &pipelineCreateInfo, nullptr, &m_strokePipeline)); + m_vk->setDebugNameIfEnabled(uint64_t(m_strokePipeline), + VK_OBJECT_TYPE_PIPELINE, + "Atlas Stroke Pipeline"); m_vk->DestroyShaderModule(m_vk->device, vertexShader, nullptr); m_vk->DestroyShaderModule(m_vk->device, fragmentFillShader, nullptr); m_vk->DestroyShaderModule(m_vk->device, fragmentStrokeShader, nullptr); } - ~AtlasPipeline() + ~AtlasPipeline() override { m_vk->DestroyPipelineLayout(m_vk->device, m_pipelineLayout, nullptr); - m_vk->DestroyRenderPass(m_vk->device, m_renderPass, nullptr); m_vk->DestroyPipeline(m_vk->device, m_fillPipeline, nullptr); m_vk->DestroyPipeline(m_vk->device, m_strokePipeline, nullptr); } VkPipelineLayout pipelineLayout() const { return m_pipelineLayout; } - VkRenderPass renderPass() const { return m_renderPass; } VkPipeline fillPipeline() const { return m_fillPipeline; } VkPipeline strokePipeline() const { return m_strokePipeline; } private: - rcp m_vk; VkPipelineLayout m_pipelineLayout; - VkRenderPass m_renderPass; VkPipeline m_fillPipeline; VkPipeline m_strokePipeline; }; -// VkPipelineLayout wrapper for Rive flushes. -class RenderContextVulkanImpl::DrawPipelineLayout +RenderContextVulkanImpl::RenderContextVulkanImpl( + rcp vk, + const ContextOptions& contextOptions) : + m_vk(std::move(vk)), + m_workarounds({ + .maxInstancesPerRenderPass = + (m_vk->physicalDeviceProperties().apiVersion < VK_API_VERSION_1_3 && + (m_vk->physicalDeviceProperties().vendorID == VULKAN_VENDOR_ARM || + m_vk->physicalDeviceProperties().vendorID == + VULKAN_VENDOR_IMG_TEC)) + // Early Mali and PowerVR devices are known to crash when a + // single render pass is too complex. + ? (1u << 13) - 1u + : UINT32_MAX, + // Early Xclipse drivers struggle with our manual msaa resolve, so we + // always do automatic fullscreen resolves on that GPU family. + .avoidManualMSAAResolves = + m_vk->physicalDeviceProperties().vendorID == VULKAN_VENDOR_SAMSUNG, + // Some Android drivers (some Android 12 and earlier Adreno drivers) + // have issues with having both a self-dependency for dst reads and + // resolve attachments. For now we just always manually resolve these + // render passes that use advanced blend on Qualcomm. + .needsManualMSAAResolveAfterDstRead = + m_vk->physicalDeviceProperties().vendorID == VULKAN_VENDOR_QUALCOMM, + }), + m_flushUniformBufferPool(m_vk, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), + m_imageDrawUniformBufferPool(m_vk, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), + m_pathBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), + m_paintBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), + m_paintAuxBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), + m_contourBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), + m_gradSpanBufferPool(m_vk, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), + m_tessSpanBufferPool(m_vk, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), + m_triangleBufferPool(m_vk, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), + m_descriptorSetPoolPool(make_rcp(m_vk)) { -public: - // Number of render pass variants that can be used with a single - // DrawPipelineLayout (framebufferFormat x loadOp). - constexpr static int kRenderPassVariantCount = 6; - - DrawPipelineLayout(RenderContextVulkanImpl* impl, - gpu::InterlockMode interlockMode, - DrawPipelineLayoutOptions options) : - m_vk(ref_rcp(impl->vulkanContext())), - m_interlockMode(interlockMode), - m_options(options) - { - assert(interlockMode != gpu::InterlockMode::msaa); // TODO: msaa. + const auto& physicalDeviceProps = m_vk->physicalDeviceProperties(); - if (interlockMode == gpu::InterlockMode::rasterOrdering || - interlockMode == gpu::InterlockMode::atomics) - { - // PLS planes get bound per flush as input attachments or storage - // textures. - VkDescriptorSetLayoutBinding plsLayoutBindings[] = { - { - .binding = COLOR_PLANE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = CLIP_PLANE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = SCRATCH_COLOR_PLANE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = COVERAGE_PLANE_IDX, - .descriptorType = - m_interlockMode == gpu::InterlockMode::atomics - ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE - : VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - }; - static_assert(COLOR_PLANE_IDX == 0); - static_assert(CLIP_PLANE_IDX == 1); - static_assert(SCRATCH_COLOR_PLANE_IDX == 2); - static_assert(COVERAGE_PLANE_IDX == 3); - - VkDescriptorSetLayoutCreateInfo plsLayoutInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - }; - if (m_options & DrawPipelineLayoutOptions::fixedFunctionColorOutput) - { - // Drop the COLOR input attachment when using - // fixedFunctionColorOutput. - assert(plsLayoutBindings[0].binding == COLOR_PLANE_IDX); - plsLayoutInfo.bindingCount = std::size(plsLayoutBindings) - 1; - plsLayoutInfo.pBindings = plsLayoutBindings + 1; - } - else - { - plsLayoutInfo.bindingCount = std::size(plsLayoutBindings); - plsLayoutInfo.pBindings = plsLayoutBindings; - } - - VK_CHECK(m_vk->CreateDescriptorSetLayout( - m_vk->device, - &plsLayoutInfo, - nullptr, - &m_plsTextureDescriptorSetLayout)); - } - else - { - // clockwiseAtomic and msaa modes don't use pixel local storage. - m_plsTextureDescriptorSetLayout = VK_NULL_HANDLE; - } - - VkDescriptorSetLayout pipelineDescriptorSetLayouts[] = { - impl->m_perFlushDescriptorSetLayout, - impl->m_perDrawDescriptorSetLayout, - impl->m_immutableSamplerDescriptorSetLayout, - m_plsTextureDescriptorSetLayout, - }; - static_assert(COLOR_PLANE_IDX == 0); - static_assert(CLIP_PLANE_IDX == 1); - static_assert(SCRATCH_COLOR_PLANE_IDX == 2); - static_assert(COVERAGE_PLANE_IDX == 3); - static_assert(BINDINGS_SET_COUNT == 4); - - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = m_plsTextureDescriptorSetLayout != VK_NULL_HANDLE - ? BINDINGS_SET_COUNT - : BINDINGS_SET_COUNT - 1u, - .pSetLayouts = pipelineDescriptorSetLayouts, - }; - - VK_CHECK(m_vk->CreatePipelineLayout(m_vk->device, - &pipelineLayoutCreateInfo, - nullptr, - &m_pipelineLayout)); - } - - ~DrawPipelineLayout() - { - m_vk->DestroyDescriptorSetLayout(m_vk->device, - m_plsTextureDescriptorSetLayout, - nullptr); - m_vk->DestroyPipelineLayout(m_vk->device, m_pipelineLayout, nullptr); - } - - gpu::InterlockMode interlockMode() const { return m_interlockMode; } - DrawPipelineLayoutOptions options() const { return m_options; } - - uint32_t attachmentCount(uint32_t subpassIndex) const - { - switch (m_interlockMode) - { - case gpu::InterlockMode::rasterOrdering: - assert(subpassIndex == 0); - return 4; - case gpu::InterlockMode::atomics: - assert(subpassIndex <= 1); - return 2u - subpassIndex; // Subpass 0 -> 2, subpass 1 -> 1. - case gpu::InterlockMode::clockwiseAtomic: - assert(subpassIndex == 0); - return 1; - case gpu::InterlockMode::msaa: - assert(subpassIndex == 0); - return 2; - } - } - - VkDescriptorSetLayout plsLayout() const - { - return m_plsTextureDescriptorSetLayout; - } - - VkPipelineLayout operator*() const { return m_pipelineLayout; } - VkPipelineLayout vkPipelineLayout() const { return m_pipelineLayout; } - -private: - const rcp m_vk; - const gpu::InterlockMode m_interlockMode; - const DrawPipelineLayoutOptions m_options; - - VkDescriptorSetLayout m_plsTextureDescriptorSetLayout; - VkPipelineLayout m_pipelineLayout; -}; - -constexpr static VkAttachmentLoadOp vk_load_op(gpu::LoadAction loadAction) -{ - switch (loadAction) - { - case gpu::LoadAction::preserveRenderTarget: - return VK_ATTACHMENT_LOAD_OP_LOAD; - case gpu::LoadAction::clear: - return VK_ATTACHMENT_LOAD_OP_CLEAR; - case gpu::LoadAction::dontCare: - return VK_ATTACHMENT_LOAD_OP_DONT_CARE; - } - RIVE_UNREACHABLE(); -} - -// VkRenderPass wrapper for Rive flushes. -class RenderContextVulkanImpl::RenderPass -{ -public: - constexpr static uint64_t FORMAT_BIT_COUNT = 19; - constexpr static uint64_t LOAD_OP_BIT_COUNT = 2; - constexpr static uint64_t KEY_BIT_COUNT = - FORMAT_BIT_COUNT + DRAW_PIPELINE_LAYOUT_BIT_COUNT + LOAD_OP_BIT_COUNT; - static_assert(KEY_BIT_COUNT <= 32); - - static uint32_t Key(gpu::InterlockMode interlockMode, - DrawPipelineLayoutOptions layoutOptions, - VkFormat renderTargetFormat, - gpu::LoadAction loadAction) - { - uint32_t formatKey = static_cast(renderTargetFormat); - if (formatKey > VK_FORMAT_ASTC_12x12_SRGB_BLOCK) - { - assert(formatKey >= VK_FORMAT_G8B8G8R8_422_UNORM); - formatKey -= VK_FORMAT_G8B8G8R8_422_UNORM - - VK_FORMAT_ASTC_12x12_SRGB_BLOCK - 1; - } - assert(formatKey <= 1 << FORMAT_BIT_COUNT); - - uint32_t drawPipelineLayoutIdx = - DrawPipelineLayoutIdx(interlockMode, layoutOptions); - assert(drawPipelineLayoutIdx < 1 << DRAW_PIPELINE_LAYOUT_BIT_COUNT); - - assert(static_cast(loadAction) < 1 << LOAD_OP_BIT_COUNT); - - return (formatKey << (DRAW_PIPELINE_LAYOUT_BIT_COUNT + - LOAD_OP_BIT_COUNT)) | - (drawPipelineLayoutIdx << LOAD_OP_BIT_COUNT) | - static_cast(loadAction); - } - - RenderPass(RenderContextVulkanImpl* impl, - gpu::InterlockMode interlockMode, - DrawPipelineLayoutOptions layoutOptions, - VkFormat renderTargetFormat, - gpu::LoadAction loadAction) : - m_vk(ref_rcp(impl->vulkanContext())) - { - uint32_t pipelineLayoutIdx = - DrawPipelineLayoutIdx(interlockMode, layoutOptions); - assert(pipelineLayoutIdx < impl->m_drawPipelineLayouts.size()); - if (impl->m_drawPipelineLayouts[pipelineLayoutIdx] == nullptr) - { - impl->m_drawPipelineLayouts[pipelineLayoutIdx] = - std::make_unique(impl, - interlockMode, - layoutOptions); - } - m_drawPipelineLayout = - impl->m_drawPipelineLayouts[pipelineLayoutIdx].get(); - - // COLOR attachment. - const VkImageLayout colorAttachmentLayout = - (layoutOptions & - DrawPipelineLayoutOptions::fixedFunctionColorOutput) - ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - : VK_IMAGE_LAYOUT_GENERAL; - StackVector attachments; - StackVector colorAttachments; - StackVector resolveAttachments; - assert(attachments.size() == COLOR_PLANE_IDX); - assert(colorAttachments.size() == COLOR_PLANE_IDX); - attachments.push_back({ - .format = renderTargetFormat, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = vk_load_op(loadAction), - .storeOp = (layoutOptions & - DrawPipelineLayoutOptions::coalescedResolveAndTransfer) - ? VK_ATTACHMENT_STORE_OP_DONT_CARE - : VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = loadAction == gpu::LoadAction::preserveRenderTarget - ? colorAttachmentLayout - : VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = colorAttachmentLayout, - }); - colorAttachments.push_back({ - .attachment = COLOR_PLANE_IDX, - .layout = colorAttachmentLayout, - }); - - if (interlockMode == gpu::InterlockMode::rasterOrdering || - interlockMode == gpu::InterlockMode::atomics) - { - // CLIP attachment. - assert(attachments.size() == CLIP_PLANE_IDX); - assert(colorAttachments.size() == CLIP_PLANE_IDX); - attachments.push_back({ - // The clip buffer is encoded as RGBA8 in atomic mode so we can - // block writes by emitting alpha=0. - .format = interlockMode == gpu::InterlockMode::atomics - ? VK_FORMAT_R8G8B8A8_UNORM - : VK_FORMAT_R32_UINT, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_GENERAL, - }); - colorAttachments.push_back({ - .attachment = CLIP_PLANE_IDX, - .layout = VK_IMAGE_LAYOUT_GENERAL, - }); - } - - if (interlockMode == gpu::InterlockMode::rasterOrdering) - { - // SCRATCH_COLOR attachment. - assert(attachments.size() == SCRATCH_COLOR_PLANE_IDX); - assert(colorAttachments.size() == SCRATCH_COLOR_PLANE_IDX); - attachments.push_back({ - .format = renderTargetFormat, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_GENERAL, - }); - colorAttachments.push_back({ - .attachment = SCRATCH_COLOR_PLANE_IDX, - .layout = VK_IMAGE_LAYOUT_GENERAL, - }); - - // COVERAGE attachment. - assert(attachments.size() == COVERAGE_PLANE_IDX); - assert(colorAttachments.size() == COVERAGE_PLANE_IDX); - attachments.push_back({ - .format = VK_FORMAT_R32_UINT, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .finalLayout = VK_IMAGE_LAYOUT_GENERAL, - }); - colorAttachments.push_back({ - .attachment = COVERAGE_PLANE_IDX, - .layout = VK_IMAGE_LAYOUT_GENERAL, - }); - } - else if (interlockMode == gpu::InterlockMode::atomics) - { - if (layoutOptions & - DrawPipelineLayoutOptions::coalescedResolveAndTransfer) - { - // COALESCED_ATOMIC_RESOLVE attachment (primary render target). - assert(attachments.size() == COALESCED_ATOMIC_RESOLVE_IDX); - attachments.push_back({ - .format = renderTargetFormat, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_STORE, - // This could sometimes be VK_IMAGE_LAYOUT_UNDEFINED, but it - // might not preserve the portion outside the renderArea - // when it isn't the full render target. Instead we rely on - // accessTargetImageView() to invalidate the target texture - // when we can. - .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }); - - // The resolve subpass only renders to the resolve texture. - // And the "coalesced" resolve shader outputs to color - // attachment 0, so alias the COALESCED_ATOMIC_RESOLVE - // attachment on output 0 for this subpass. - assert(resolveAttachments.size() == 0); - resolveAttachments.push_back({ - .attachment = COALESCED_ATOMIC_RESOLVE_IDX, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }); - } - else - { - // When not in "coalesced" mode, the resolve texture is the - // same as the COLOR texture. - static_assert(COLOR_PLANE_IDX == 0); - assert(resolveAttachments.size() == 0); - resolveAttachments.push_back(colorAttachments[0]); - } - } - - // Input attachments. - StackVector inputAttachments; - if (interlockMode != gpu::InterlockMode::clockwiseAtomic) - { - inputAttachments.push_back_n(colorAttachments.size(), - colorAttachments.data()); - if (layoutOptions & - DrawPipelineLayoutOptions::fixedFunctionColorOutput) - { - // COLOR is not an input attachment if we're using fixed - // function blending. - inputAttachments[0] = {.attachment = VK_ATTACHMENT_UNUSED}; - } - } - - // Draw subpass. - constexpr uint32_t MAX_SUBPASSES = 2; - const bool rasterOrderedAttachmentAccess = - interlockMode == gpu::InterlockMode::rasterOrdering && - m_vk->features.rasterizationOrderColorAttachmentAccess; - StackVector subpassDescs; - StackVector subpassDeps; - assert(subpassDescs.size() == 0); - assert(subpassDeps.size() == 0); - assert(colorAttachments.size() == - m_drawPipelineLayout->attachmentCount(0)); - subpassDescs.push_back({ - .flags = - rasterOrderedAttachmentAccess - ? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT - : 0u, - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .inputAttachmentCount = inputAttachments.size(), - .pInputAttachments = inputAttachments.data(), - .colorAttachmentCount = colorAttachments.size(), - .pColorAttachments = colorAttachments.data(), - .pDepthStencilAttachment = nullptr, - }); - - // Draw subpass self-dependencies. - if (interlockMode == gpu::InterlockMode::clockwiseAtomic) - { - // clockwiseAtomic mode has a dependency when we switch from - // borrowed coverage into forward. - subpassDeps.push_back({ - .srcSubpass = 0, - .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, - .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, - }); - } - else if (!rasterOrderedAttachmentAccess) - { - // Normally our dependencies are input attachments. - // - // In implicit rasterOrdering mode (meaning - // EXT_rasterization_order_attachment_access is not present, but - // we're on ARM hardware and know the hardware is raster ordered - // anyway), we also need to declare this dependency even though - // we won't be issuing any barriers. - subpassDeps.push_back({ - .srcSubpass = 0, - .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - // TODO: We should add SHADER_READ/SHADER_WRITE flags for the - // coverage buffer as well, but ironically, adding those causes - // artifacts on Qualcomm. Leave them out for now unless we find - // a case where we don't work without them. - .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, - }); - } - - // Resolve subpass (atomic mode only). - if (interlockMode == gpu::InterlockMode::atomics) - { - // The resolve happens in a separate subpass. - assert(subpassDescs.size() == 1); - assert(resolveAttachments.size() == - m_drawPipelineLayout->attachmentCount(1)); - subpassDescs.push_back({ - .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .inputAttachmentCount = inputAttachments.size(), - .pInputAttachments = inputAttachments.data(), - .colorAttachmentCount = resolveAttachments.size(), - .pColorAttachments = resolveAttachments.data(), - }); - - // The resolve subpass depends on the previous one, but not itself. - subpassDeps.push_back({ - .srcSubpass = 0, - .dstSubpass = 1, - .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - // TODO: We should add SHADER_READ/SHADER_WRITE flags for the - // coverage buffer as well, but ironically, adding those causes - // artifacts on Qualcomm. Leave them out for now unless we find - // a case where we don't work without them. - .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, - }); - } - - VkRenderPassCreateInfo renderPassCreateInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = attachments.size(), - .pAttachments = attachments.data(), - .subpassCount = subpassDescs.size(), - .pSubpasses = subpassDescs.data(), - .dependencyCount = subpassDeps.size(), - .pDependencies = subpassDeps.data(), - }; - - VK_CHECK(m_vk->CreateRenderPass(m_vk->device, - &renderPassCreateInfo, - nullptr, - &m_renderPass)); - } - - ~RenderPass() - { - // Don't touch m_drawPipelineLayout in the destructor since destruction - // order of us vs. impl->m_drawPipelineLayouts is uncertain. - m_vk->DestroyRenderPass(m_vk->device, m_renderPass, nullptr); - } - - const DrawPipelineLayout* drawPipelineLayout() const - { - return m_drawPipelineLayout; - } - - operator VkRenderPass() const { return m_renderPass; } - -private: - const rcp m_vk; - // Raw pointer into impl->m_drawPipelineLayouts. RenderContextVulkanImpl - // ensures the pipline layouts outlive this RenderPass instance. - const DrawPipelineLayout* m_drawPipelineLayout; - VkRenderPass m_renderPass; -}; - -// Pipeline options that don't affect the shader. -enum class DrawPipelineOptions -{ - none = 0, - wireframe = 1 << 0, -}; -constexpr static int DRAW_PIPELINE_OPTION_COUNT = 1; -RIVE_MAKE_ENUM_BITSET(DrawPipelineOptions); - -// VkPipeline wrapper for Rive draw calls. -class RenderContextVulkanImpl::DrawPipeline -{ -public: - static uint64_t Key(DrawType drawType, - ShaderFeatures shaderFeatures, - InterlockMode interlockMode, - ShaderMiscFlags shaderMiscFlags, - DrawPipelineOptions drawPipelineOptions, - uint32_t renderPassKey) - { - uint64_t key = gpu::ShaderUniqueKey(drawType, - shaderFeatures, - interlockMode, - shaderMiscFlags); - - assert(key << DRAW_PIPELINE_OPTION_COUNT >> - DRAW_PIPELINE_OPTION_COUNT == - key); - key = (key << DRAW_PIPELINE_OPTION_COUNT) | - static_cast(drawPipelineOptions); - - assert(key << RenderPass::KEY_BIT_COUNT >> RenderPass::KEY_BIT_COUNT == - key); - key = (key << RenderPass::KEY_BIT_COUNT) | renderPassKey; - - return key; - } - - DrawPipeline(RenderContextVulkanImpl* impl, - gpu::DrawType drawType, - const DrawPipelineLayout& pipelineLayout, - gpu::ShaderFeatures shaderFeatures, - gpu::ShaderMiscFlags shaderMiscFlags, - DrawPipelineOptions drawPipelineOptions, - VkRenderPass vkRenderPass) : - m_vk(ref_rcp(impl->vulkanContext())) - { - gpu::InterlockMode interlockMode = pipelineLayout.interlockMode(); - uint32_t shaderKey = gpu::ShaderUniqueKey(drawType, - shaderFeatures, - interlockMode, - shaderMiscFlags); - const uint32_t subpassIndex = - drawType == gpu::DrawType::atomicResolve ? 1u : 0u; - - std::unique_ptr& drawShader = - impl->m_drawShaders[shaderKey]; - if (drawShader == nullptr) - { - drawShader = std::make_unique(m_vk.get(), - drawType, - interlockMode, - shaderFeatures, - shaderMiscFlags); - } - - uint32_t shaderPermutationFlags[SPECIALIZATION_COUNT] = { - shaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING, - shaderFeatures & gpu::ShaderFeatures::ENABLE_CLIP_RECT, - shaderFeatures & gpu::ShaderFeatures::ENABLE_ADVANCED_BLEND, - shaderFeatures & gpu::ShaderFeatures::ENABLE_FEATHER, - shaderFeatures & gpu::ShaderFeatures::ENABLE_EVEN_ODD, - shaderFeatures & gpu::ShaderFeatures::ENABLE_NESTED_CLIPPING, - shaderFeatures & gpu::ShaderFeatures::ENABLE_HSL_BLEND_MODES, - shaderMiscFlags & gpu::ShaderMiscFlags::clockwiseFill, - shaderMiscFlags & gpu::ShaderMiscFlags::borrowedCoveragePrepass, - impl->m_vendorID, - }; - static_assert(CLIPPING_SPECIALIZATION_IDX == 0); - static_assert(CLIP_RECT_SPECIALIZATION_IDX == 1); - static_assert(ADVANCED_BLEND_SPECIALIZATION_IDX == 2); - static_assert(FEATHER_SPECIALIZATION_IDX == 3); - static_assert(EVEN_ODD_SPECIALIZATION_IDX == 4); - static_assert(NESTED_CLIPPING_SPECIALIZATION_IDX == 5); - static_assert(HSL_BLEND_MODES_SPECIALIZATION_IDX == 6); - static_assert(CLOCKWISE_FILL_SPECIALIZATION_IDX == 7); - static_assert(BORROWED_COVERAGE_PREPASS_SPECIALIZATION_IDX == 8); - static_assert(VULKAN_VENDOR_ID_SPECIALIZATION_IDX == 9); - static_assert(SPECIALIZATION_COUNT == 10); - - VkSpecializationMapEntry permutationMapEntries[SPECIALIZATION_COUNT]; - for (uint32_t i = 0; i < SPECIALIZATION_COUNT; ++i) - { - permutationMapEntries[i] = { - .constantID = i, - .offset = i * static_cast(sizeof(uint32_t)), - .size = sizeof(uint32_t), - }; - } - - VkSpecializationInfo specializationInfo = { - .mapEntryCount = SPECIALIZATION_COUNT, - .pMapEntries = permutationMapEntries, - .dataSize = sizeof(shaderPermutationFlags), - .pData = &shaderPermutationFlags, - }; - - VkPipelineShaderStageCreateInfo stages[] = { - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = drawShader->vertexModule(), - .pName = "main", - .pSpecializationInfo = &specializationInfo, - }, - { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = drawShader->fragmentModule(), - .pName = "main", - .pSpecializationInfo = &specializationInfo, - }, - }; - - VkPipelineRasterizationStateCreateInfo - pipelineRasterizationStateCreateInfo = { - .sType = - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .polygonMode = - (drawPipelineOptions & DrawPipelineOptions::wireframe) - ? VK_POLYGON_MODE_LINE - : VK_POLYGON_MODE_FILL, - .cullMode = static_cast( - DrawTypeIsImageDraw(drawType) ? VK_CULL_MODE_NONE - : VK_CULL_MODE_BACK_BIT), - .frontFace = VK_FRONT_FACE_CLOCKWISE, - .lineWidth = 1.0, - }; - - VkPipelineColorBlendAttachmentState blendState; - if (interlockMode == gpu::InterlockMode::rasterOrdering || - (shaderMiscFlags & - gpu::ShaderMiscFlags::coalescedResolveAndTransfer)) - { - blendState = { - .blendEnable = VK_FALSE, - .colorWriteMask = vkutil::kColorWriteMaskRGBA, - }; - } - else if (shaderMiscFlags & - gpu::ShaderMiscFlags::borrowedCoveragePrepass) - { - // Borrowed coverage draws only update the coverage buffer. - blendState = { - .blendEnable = VK_FALSE, - .colorWriteMask = vkutil::kColorWriteMaskNone, - }; - } - else - { - // Atomic mode blends the color and clip both as independent RGBA8 - // values. - // - // Advanced blend modes are handled by rearranging the math - // such that the correct color isn't reached until *AFTER* this - // blend state is applied. - // - // This allows us to preserve clip and color contents by just - // emitting a=0 instead of loading the current value. It also saves - // flops by offloading the blending work onto the ROP blending - // unit, and serves as a hint to the hardware that it doesn't need - // to read or write anything when a == 0. - blendState = { - .blendEnable = VK_TRUE, - // Image draws use premultiplied src-over so they can blend - // the image with the previous paint together, out of order. - // (Premultiplied src-over is associative.) - // - // Otherwise we save 3 flops and let the ROP multiply alpha - // into the color when it does the blending. - .srcColorBlendFactor = - interlockMode == gpu::InterlockMode::atomics && - gpu::DrawTypeIsImageDraw(drawType) - ? VK_BLEND_FACTOR_ONE - : VK_BLEND_FACTOR_SRC_ALPHA, - .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .alphaBlendOp = VK_BLEND_OP_ADD, - .colorWriteMask = vkutil::kColorWriteMaskRGBA, - }; - } - - StackVector - blendStates; - blendStates.push_back_n(pipelineLayout.attachmentCount(subpassIndex), - blendState); - VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = - { - .sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .attachmentCount = blendStates.size(), - .pAttachments = blendStates.data(), - }; - - if (interlockMode == gpu::InterlockMode::rasterOrdering && - m_vk->features.rasterizationOrderColorAttachmentAccess) - { - pipelineColorBlendStateCreateInfo.flags |= - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT; - } - - VkPipelineDepthStencilStateCreateInfo depthStencilState = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_FALSE, - .depthWriteEnable = VK_FALSE, - .depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL, - .depthBoundsTestEnable = VK_FALSE, - .stencilTestEnable = VK_FALSE, - .minDepthBounds = DEPTH_MIN, - .maxDepthBounds = DEPTH_MAX, - }; - - VkGraphicsPipelineCreateInfo pipelineCreateInfo = { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .stageCount = 2, - .pStages = stages, - .pViewportState = &layout::SINGLE_VIEWPORT, - .pRasterizationState = &pipelineRasterizationStateCreateInfo, - .pMultisampleState = &layout::MSAA_DISABLED, - .pDepthStencilState = interlockMode == gpu::InterlockMode::msaa - ? &depthStencilState - : nullptr, - .pColorBlendState = &pipelineColorBlendStateCreateInfo, - .pDynamicState = &layout::DYNAMIC_VIEWPORT_SCISSOR, - .layout = *pipelineLayout, - .renderPass = vkRenderPass, - .subpass = subpassIndex, - }; - - switch (drawType) - { - case DrawType::midpointFanPatches: - case DrawType::midpointFanCenterAAPatches: - case DrawType::outerCurvePatches: - pipelineCreateInfo.pVertexInputState = - &layout::PATH_VERTEX_INPUT_STATE; - pipelineCreateInfo.pInputAssemblyState = - &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; - break; - - case DrawType::interiorTriangulation: - case DrawType::atlasBlit: - pipelineCreateInfo.pVertexInputState = - &layout::INTERIOR_TRI_VERTEX_INPUT_STATE; - pipelineCreateInfo.pInputAssemblyState = - &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; - break; - - case DrawType::imageRect: - pipelineCreateInfo.pVertexInputState = - &layout::IMAGE_RECT_VERTEX_INPUT_STATE; - pipelineCreateInfo.pInputAssemblyState = - &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; - break; - - case DrawType::imageMesh: - pipelineCreateInfo.pVertexInputState = - &layout::IMAGE_MESH_VERTEX_INPUT_STATE; - pipelineCreateInfo.pInputAssemblyState = - &layout::INPUT_ASSEMBLY_TRIANGLE_LIST; - break; - - case DrawType::atomicResolve: - pipelineCreateInfo.pVertexInputState = - &layout::EMPTY_VERTEX_INPUT_STATE; - pipelineCreateInfo.pInputAssemblyState = - &layout::INPUT_ASSEMBLY_TRIANGLE_STRIP; - break; - - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); - } - - VK_CHECK(m_vk->CreateGraphicsPipelines(m_vk->device, - VK_NULL_HANDLE, - 1, - &pipelineCreateInfo, - nullptr, - &m_vkPipeline)); - } - - ~DrawPipeline() - { - m_vk->DestroyPipeline(m_vk->device, m_vkPipeline, nullptr); - } - - operator VkPipeline() const { return m_vkPipeline; } - -private: - const rcp m_vk; - VkPipeline m_vkPipeline; -}; - -RenderContextVulkanImpl::RenderContextVulkanImpl( - rcp vk, - const VkPhysicalDeviceProperties& physicalDeviceProps) : - m_vk(std::move(vk)), - m_vendorID(physicalDeviceProps.vendorID), - m_atlasFormat(m_vk->isFormatSupportedWithFeatureFlags( - VK_FORMAT_R32_SFLOAT, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) - ? VK_FORMAT_R32_SFLOAT - : VK_FORMAT_R16_SFLOAT), - m_flushUniformBufferPool(m_vk, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), - m_imageDrawUniformBufferPool(m_vk, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT), - m_pathBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), - m_paintBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), - m_paintAuxBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), - m_contourBufferPool(m_vk, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), - m_gradSpanBufferPool(m_vk, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), - m_tessSpanBufferPool(m_vk, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), - m_triangleBufferPool(m_vk, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), - m_descriptorSetPoolPool(make_rcp(m_vk)) -{ - m_platformFeatures.supportsRasterOrdering = + m_platformFeatures.supportsRasterOrderingMode = + !contextOptions.forceAtomicMode && m_vk->features.rasterizationOrderColorAttachmentAccess; - m_platformFeatures.supportsFragmentShaderAtomics = - m_vk->features.fragmentStoresAndAtomics; - m_platformFeatures.supportsClockwiseAtomicRendering = +#ifdef RIVE_ANDROID + m_platformFeatures.supportsAtomicMode = + m_vk->features.fragmentStoresAndAtomics && + // For now, disable gpu::InterlockMode::atomics on Android unless + // explicitly requested. We will focus on stabilizing MSAA first, and + // then roll this mode back in. + contextOptions.forceAtomicMode; +#else + m_platformFeatures.supportsAtomicMode = m_vk->features.fragmentStoresAndAtomics; + m_platformFeatures.supportsClockwiseMode = + m_vk->features.fragmentShaderPixelInterlock && + !contextOptions.forceAtomicMode && + // TODO: Before we can support rasterOrdering and clockwise at the same + // time, we need to figure out barriers between transient PLS + // attachments being bound as both input attachments and storage + // textures. (Probably by using + // VK_EXT_rasterization_order_attachment_access whenever possible in + // clockwise mode.) + !m_platformFeatures.supportsRasterOrderingMode; + m_platformFeatures.supportsClockwiseFixedFunctionMode = + m_platformFeatures.supportsClockwiseMode && + !contextOptions.disableClockwiseFixedFunctionMode; +#endif + m_platformFeatures.supportsClockwiseAtomicMode = + m_platformFeatures.supportsAtomicMode; + m_platformFeatures.supportsClipPlanes = + m_vk->features.shaderClipDistance && + // The Vulkan spec mandates that the minimum value for maxClipDistances + // is 8, but we might as well make this >= 4 check to be more clear + // about how we're using it. + physicalDeviceProps.limits.maxClipDistances >= 4; m_platformFeatures.clipSpaceBottomUp = false; m_platformFeatures.framebufferBottomUp = false; + // Vulkan can't load color from a different texture into the transient MSAA + // texture. We need to draw the previous renderTarget contents into it + // manually when LoadAction::preserveRenderTarget is specified. + m_platformFeatures.msaaColorPreserveNeedsDraw = true; + m_platformFeatures.maxTextureSize = + physicalDeviceProps.limits.maxImageDimension2D; + m_platformFeatures.supportsTextureCompressionBC = + m_vk->features.textureCompressionBC; + m_platformFeatures.supportsTextureCompressionASTC = + m_vk->features.textureCompressionASTC_LDR; + m_platformFeatures.supportsTextureCompressionETC2 = + m_vk->features.textureCompressionETC2; m_platformFeatures.maxCoverageBufferLength = std::min(physicalDeviceProps.limits.maxStorageBufferRange, 1u << 28) / sizeof(uint32_t); - switch (m_vendorID) + switch (physicalDeviceProps.vendorID) { case VULKAN_VENDOR_QUALCOMM: // Qualcomm advertises EXT_rasterization_order_attachment_access, // but it's slow. Use atomics instead on this platform. - m_platformFeatures.supportsRasterOrdering = false; + m_platformFeatures.supportsRasterOrderingMode = false; + // Framebuffer reads on Qualcomm seem to not work in clockwiseAtomic + // mode unless we issue a simple, 1-pixel draw that reads the + // framebuffer between borrowed coverage and the main draws. + m_platformFeatures + .clockwiseAtomicBorrowedCoverageBarrierNeedsRenderPassInit = + true; // Pixel4 struggles with fine-grained fp16 path IDs. m_platformFeatures.pathIDGranularity = 2; break; case VULKAN_VENDOR_ARM: - // This is undocumented, but raster ordering always works on ARM - // Mali GPUs if you define a subpass dependency, even without - // EXT_rasterization_order_attachment_access. - m_platformFeatures.supportsRasterOrdering = true; + // Raster ordering is known to work on ARM hardware, even on old + // drivers without EXT_rasterization_order_attachment_access, as + // long as you define a subpass self-dependency. + m_platformFeatures.supportsRasterOrderingMode = + !contextOptions.forceAtomicMode; break; - } -} - -static VkFilter vk_filter(rive::ImageFilter option) -{ - switch (option) - { - case rive::ImageFilter::trilinear: - return VK_FILTER_LINEAR; - case rive::ImageFilter::nearest: - return VK_FILTER_NEAREST; - } - - RIVE_UNREACHABLE(); -} -static VkSamplerMipmapMode vk_sampler_mipmap_mode(rive::ImageFilter option) -{ - switch (option) - { - case rive::ImageFilter::trilinear: - return VK_SAMPLER_MIPMAP_MODE_LINEAR; - case rive::ImageFilter::nearest: - return VK_SAMPLER_MIPMAP_MODE_NEAREST; - } - - RIVE_UNREACHABLE(); -} - -static VkSamplerAddressMode vk_sampler_address_mode(rive::ImageWrap option) -{ - switch (option) - { - case rive::ImageWrap::clamp: - return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - case rive::ImageWrap::repeat: - return VK_SAMPLER_ADDRESS_MODE_REPEAT; - case rive::ImageWrap::mirror: - return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case VULKAN_VENDOR_IMG_TEC: + // Raster ordering is known to work on IMG hardware, even without + // EXT_rasterization_order_attachment_access, as long as you define + // a subpass self-dependency. + // IMG just can't expose the extension because they do _not_ + // guarantee raster ordering across samples, which is required by + // the extension, but irrelevant to Rive. + // THAT BEING SAID: while Google Chrome relies on implicit raster + // ordering on all IMG devices, it has only been observed to work + // with Rive on Vulkan 1.3 contexts (PowerVR Rogue GE9215 -- driver + // 1.555, and PowerVR D-Series DXT-48-1536 (Pixel 10) -- driver + // 1.602). + m_platformFeatures.supportsRasterOrderingMode = + !contextOptions.forceAtomicMode && + m_vk->features.apiVersion >= VK_API_VERSION_1_3; + break; } - - RIVE_UNREACHABLE(); } -void RenderContextVulkanImpl::initGPUObjects() +void RenderContextVulkanImpl::initGPUObjects( + ShaderCompilationMode shaderCompilationMode) { - // Create the immutable samplers. - VkSamplerCreateInfo linearSamplerCreateInfo = { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .magFilter = VK_FILTER_LINEAR, - .minFilter = VK_FILTER_LINEAR, - .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST, - .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - .minLod = 0, - .maxLod = 0, - }; - - VK_CHECK(m_vk->CreateSampler(m_vk->device, - &linearSamplerCreateInfo, - nullptr, - &m_linearSampler)); - - for (size_t i = 0; i < ImageSampler::MAX_SAMPLER_PERMUTATIONS; ++i) - { - ImageWrap wrapX = ImageSampler::GetWrapXOptionFromKey(i); - ImageWrap wrapY = ImageSampler::GetWrapYOptionFromKey(i); - ImageFilter filter = ImageSampler::GetFilterOptionFromKey(i); - VkFilter minMagFilter = vk_filter(filter); - - VkSamplerCreateInfo samplerCreateInfo = { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .magFilter = minMagFilter, - .minFilter = minMagFilter, - .mipmapMode = vk_sampler_mipmap_mode(filter), - .addressModeU = vk_sampler_address_mode(wrapX), - .addressModeV = vk_sampler_address_mode(wrapY), - .minLod = 0, - .maxLod = VK_LOD_CLAMP_NONE, - }; - - VK_CHECK(m_vk->CreateSampler(m_vk->device, - &samplerCreateInfo, - nullptr, - m_imageSamplers + i)); - } - // Bound when there is not an image paint. - constexpr static uint8_t black[] = {0, 0, 0, 1}; - m_nullImageTexture = m_vk->makeTexture2D({ - .format = VK_FORMAT_R8G8B8A8_UNORM, - .extent = {1, 1}, - }); - m_nullImageTexture->stageContentsForUpload(black, sizeof(black)); - - // All pipelines share the same perFlush bindings. - VkDescriptorSetLayoutBinding perFlushLayoutBindings[] = { - { - .binding = FLUSH_UNIFORM_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = 1, - .stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = IMAGE_DRAW_UNIFORM_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - .descriptorCount = 1, - .stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = PATH_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - }, - { - .binding = PAINT_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = 1, - .stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = PAINT_AUX_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = 1, - .stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = CONTOUR_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - }, - { - .binding = COVERAGE_BUFFER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = TESS_VERTEX_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, - }, - { - .binding = GRAD_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = FEATHER_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = ATLAS_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - }; - - VkDescriptorSetLayoutCreateInfo perFlushLayoutInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = std::size(perFlushLayoutBindings), - .pBindings = perFlushLayoutBindings, - }; - - VK_CHECK(m_vk->CreateDescriptorSetLayout(m_vk->device, - &perFlushLayoutInfo, - nullptr, - &m_perFlushDescriptorSetLayout)); - - // The imageTexture gets updated with every draw that uses it. - VkDescriptorSetLayoutBinding perDrawLayoutBindings[] = { - { - .binding = IMAGE_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - { - .binding = IMAGE_SAMPLER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - }, - }; - - VkDescriptorSetLayoutCreateInfo perDrawLayoutInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = std::size(perDrawLayoutBindings), - .pBindings = perDrawLayoutBindings, - }; - - VK_CHECK(m_vk->CreateDescriptorSetLayout(m_vk->device, - &perDrawLayoutInfo, - nullptr, - &m_perDrawDescriptorSetLayout)); - - // Every shader uses the same immutable sampler layout. - VkDescriptorSetLayoutBinding immutableSamplerLayoutBindings[] = { - { - .binding = GRAD_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = &m_linearSampler, - }, - { - .binding = FEATHER_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 1, - .stageFlags = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = &m_linearSampler, - }, - { - .binding = ATLAS_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, - .pImmutableSamplers = &m_linearSampler, - }, - }; - - VkDescriptorSetLayoutCreateInfo immutableSamplerLayoutInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = std::size(immutableSamplerLayoutBindings), - .pBindings = immutableSamplerLayoutBindings, - }; - - VK_CHECK(m_vk->CreateDescriptorSetLayout( - m_vk->device, - &immutableSamplerLayoutInfo, - nullptr, - &m_immutableSamplerDescriptorSetLayout)); - - // For when a set isn't used at all by a shader. - VkDescriptorSetLayoutCreateInfo emptyLayoutInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = 0, - }; - - VK_CHECK(m_vk->CreateDescriptorSetLayout(m_vk->device, - &emptyLayoutInfo, - nullptr, - &m_emptyDescriptorSetLayout)); - - // Create static descriptor sets. - VkDescriptorPoolSize staticDescriptorPoolSizes[] = { - { - .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = 1, // m_nullImageTexture - }, - { - .type = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = 4, // grad, feather, atlas, image samplers - }, - }; - - VkDescriptorPoolCreateInfo staticDescriptorPoolCreateInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, - .maxSets = 2, - .poolSizeCount = std::size(staticDescriptorPoolSizes), - .pPoolSizes = staticDescriptorPoolSizes, - }; - - VK_CHECK(m_vk->CreateDescriptorPool(m_vk->device, - &staticDescriptorPoolCreateInfo, - nullptr, - &m_staticDescriptorPool)); - - // Create a descriptor set to bind m_nullImageTexture when there is no image - // paint. - VkDescriptorSetAllocateInfo nullImageDescriptorSetInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = m_staticDescriptorPool, - .descriptorSetCount = 1, - .pSetLayouts = &m_perDrawDescriptorSetLayout, - }; - - VK_CHECK(m_vk->AllocateDescriptorSets(m_vk->device, - &nullImageDescriptorSetInfo, - &m_nullImageDescriptorSet)); - - m_vk->updateImageDescriptorSets( - m_nullImageDescriptorSet, - { - .dstBinding = IMAGE_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - }, - {{ - .imageView = m_nullImageTexture->vkImageView(), - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }}); - - m_vk->updateImageDescriptorSets( - m_nullImageDescriptorSet, + constexpr static uint8_t black[] = {0, 0, 0, 1}; + m_nullImageTexture = m_vk->makeTexture2D( { - .dstBinding = IMAGE_SAMPLER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .format = VK_FORMAT_R8G8B8A8_UNORM, + .extent = {1, 1}, }, - {{ - .sampler = m_imageSamplers[ImageSampler::LINEAR_CLAMP_SAMPLER_KEY], - }}); - - // Create an empty descriptor set for IMMUTABLE_SAMPLER_BINDINGS_SET. Vulkan - // requires this even though the samplers are all immutable. - VkDescriptorSetAllocateInfo immutableSamplerDescriptorSetInfo = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = m_staticDescriptorPool, - .descriptorSetCount = 1, - .pSetLayouts = &m_immutableSamplerDescriptorSetLayout, - }; + "null image texture"); + m_nullImageTexture->scheduleUpload(black, sizeof(black)); + + if (strstr(m_vk->physicalDeviceProperties().deviceName, "Adreno (TM) 8") != + nullptr) + { + // The Adreno 8s (at least on the Galaxy S25) have a strange + // synchronization issue around our tesselation texture, where the + // barriers appear to not work properly (leading to tesselation texture + // corruption, even across frames). + // We can do a blit to a 1x1 texture, however, which seems to make the + // synchronization play nice. + m_tesselationSyncIssueWorkaroundTexture = m_vk->makeTexture2D( + { + .format = VK_FORMAT_R8G8B8A8_UINT, + .extent = {1, 1}, + .usage = VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + }, + "tesselation sync bug workaround texture"); + } - VK_CHECK(m_vk->AllocateDescriptorSets(m_vk->device, - &immutableSamplerDescriptorSetInfo, - &m_immutableSamplerDescriptorSet)); + m_pipelineManager = std::make_unique( + m_vk, + shaderCompilationMode, + m_nullImageTexture->vkImageView()); // The pipelines reference our vulkan objects. Delete them first. - m_colorRampPipeline = std::make_unique(this); - m_tessellatePipeline = std::make_unique(this); - m_atlasPipeline = std::make_unique(this); + m_colorRampPipeline = + std::make_unique(m_pipelineManager.get(), + m_workarounds); + m_tessellatePipeline = + std::make_unique(m_pipelineManager.get(), + m_workarounds); + m_atlasPipeline = + std::make_unique(m_pipelineManager.get(), m_workarounds); + + // Determine usage flags for transient PLS backing textures. + m_plsTransientUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + if (m_platformFeatures.supportsClockwiseMode) + { + // When we support the interlock, PLS backings can be storage textures. + m_plsTransientUsageFlags |= VK_IMAGE_USAGE_STORAGE_BIT | + // For vkCmdClearColorImage. + VK_IMAGE_USAGE_TRANSFER_DST_BIT; + } + else if (!m_workarounds.needsInterruptibleRenderPasses()) + { + // Otherwise, and as long as we don't have to build interruptible render + // passes, PLS backings are transient input attachments. + m_plsTransientUsageFlags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + } // Emulate the feather texture1d array as a 2d texture until we add // texture1d support in Vulkan. @@ -1982,16 +1027,18 @@ void RenderContextVulkanImpl::initGPUObjects() sizeof(gpu::g_inverseGaussianIntegralTableF16)); static_assert(FEATHER_FUNCTION_ARRAY_INDEX == 0); static_assert(FEATHER_INVERSE_FUNCTION_ARRAY_INDEX == 1); - m_featherTexture = m_vk->makeTexture2D({ - .format = VK_FORMAT_R16_SFLOAT, - .extent = - { - .width = gpu::GAUSSIAN_TABLE_SIZE, - .height = FEATHER_TEXTURE_1D_ARRAY_LENGTH, - }, - }); - m_featherTexture->stageContentsForUpload(featherTextureData, - sizeof(featherTextureData)); + m_featherTexture = m_vk->makeTexture2D( + { + .format = VK_FORMAT_R16_SFLOAT, + .extent = + { + .width = gpu::GAUSSIAN_TABLE_SIZE, + .height = FEATHER_TEXTURE_1D_ARRAY_LENGTH, + }, + }, + "feather texture"); + m_featherTexture->scheduleUpload(featherTextureData, + sizeof(featherTextureData)); m_tessSpanIndexBuffer = m_vk->makeBuffer( { @@ -2057,29 +1104,15 @@ RenderContextVulkanImpl::~RenderContextVulkanImpl() assert(m_tessSpanBuffer == nullptr); assert(m_triangleBuffer == nullptr); + if (m_canvasCommandPool != VK_NULL_HANDLE) + { + m_vk->DestroyCommandPool(m_vk->device, m_canvasCommandPool, nullptr); + } + // Tell the context we are entering our shutdown cycle. After this point, // all resources will be deleted immediately upon their refCount reaching // zero, as opposed to being kept alive for in-flight command buffers. m_vk->shutdown(); - - m_vk->DestroyDescriptorPool(m_vk->device, m_staticDescriptorPool, nullptr); - m_vk->DestroyDescriptorSetLayout(m_vk->device, - m_perFlushDescriptorSetLayout, - nullptr); - m_vk->DestroyDescriptorSetLayout(m_vk->device, - m_perDrawDescriptorSetLayout, - nullptr); - m_vk->DestroyDescriptorSetLayout(m_vk->device, - m_immutableSamplerDescriptorSetLayout, - nullptr); - m_vk->DestroyDescriptorSetLayout(m_vk->device, - m_emptyDescriptorSetLayout, - nullptr); - for (VkSampler sampler : m_imageSamplers) - { - m_vk->DestroySampler(m_vk->device, sampler, nullptr); - } - m_vk->DestroySampler(m_vk->device, m_linearSampler, nullptr); } void RenderContextVulkanImpl::resizeGradientTexture(uint32_t width, @@ -2087,25 +1120,24 @@ void RenderContextVulkanImpl::resizeGradientTexture(uint32_t width, { width = std::max(width, 1u); height = std::max(height, 1u); - if (m_gradTexture == nullptr || m_gradTexture->width() != width || - m_gradTexture->height() != height) - { - m_gradTexture = m_vk->makeTexture2D({ + + m_gradTexture = m_vk->makeTexture2D( + { .format = VK_FORMAT_R8G8B8A8_UNORM, .extent = {width, height}, .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - }); + }, + "gradient texture"); - m_gradTextureFramebuffer = m_vk->makeFramebuffer({ - .renderPass = m_colorRampPipeline->renderPass(), - .attachmentCount = 1, - .pAttachments = m_gradTexture->vkImageViewAddressOf(), - .width = width, - .height = height, - .layers = 1, - }); - } + m_gradTextureFramebuffer = m_vk->makeFramebuffer({ + .renderPass = m_colorRampPipeline->renderPass(), + .attachmentCount = 1, + .pAttachments = m_gradTexture->vkImageViewAddressOf(), + .width = width, + .height = height, + .layers = 1, + }); } void RenderContextVulkanImpl::resizeTessellationTexture(uint32_t width, @@ -2113,25 +1145,33 @@ void RenderContextVulkanImpl::resizeTessellationTexture(uint32_t width, { width = std::max(width, 1u); height = std::max(height, 1u); - if (m_tessTexture == nullptr || m_tessTexture->width() != width || - m_tessTexture->height() != height) + + VkImageUsageFlags usage = + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + + // If we are doing the Adreno synchronization workaround we also need the + // TRANSFER_SRC bit + if (m_tesselationSyncIssueWorkaroundTexture != nullptr) { - m_tessTexture = m_vk->makeTexture2D({ + usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + } + + m_tessTexture = m_vk->makeTexture2D( + { .format = VK_FORMAT_R32G32B32A32_UINT, .extent = {width, height}, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_SAMPLED_BIT, - }); + .usage = usage, + }, + "tesselation texture"); - m_tessTextureFramebuffer = m_vk->makeFramebuffer({ - .renderPass = m_tessellatePipeline->renderPass(), - .attachmentCount = 1, - .pAttachments = m_tessTexture->vkImageViewAddressOf(), - .width = width, - .height = height, - .layers = 1, - }); - } + m_tessTextureFramebuffer = m_vk->makeFramebuffer({ + .renderPass = m_tessellatePipeline->renderPass(), + .attachmentCount = 1, + .pAttachments = m_tessTexture->vkImageViewAddressOf(), + .width = width, + .height = height, + .layers = 1, + }); } void RenderContextVulkanImpl::resizeAtlasTexture(uint32_t width, @@ -2139,24 +1179,59 @@ void RenderContextVulkanImpl::resizeAtlasTexture(uint32_t width, { width = std::max(width, 1u); height = std::max(height, 1u); - if (m_atlasTexture == nullptr || m_atlasTexture->width() != width || - m_atlasTexture->height() != height) - { - m_atlasTexture = m_vk->makeTexture2D({ - .format = m_atlasFormat, + + m_atlasTexture = m_vk->makeTexture2D( + { + .format = m_pipelineManager->atlasFormat(), .extent = {width, height}, .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, - }); + }, + "atlas texture"); - m_atlasFramebuffer = m_vk->makeFramebuffer({ - .renderPass = m_atlasPipeline->renderPass(), - .attachmentCount = 1, - .pAttachments = m_atlasTexture->vkImageViewAddressOf(), - .width = width, - .height = height, - .layers = 1, - }); + m_atlasFramebuffer = m_vk->makeFramebuffer({ + .renderPass = m_atlasPipeline->renderPass(), + .attachmentCount = 1, + .pAttachments = m_atlasTexture->vkImageViewAddressOf(), + .width = width, + .height = height, + .layers = 1, + }); +} + +void RenderContextVulkanImpl::resizeTransientPLSBacking(uint32_t width, + uint32_t height, + uint32_t planeCount) +{ + // Erase the backings and allocate them lazily. Our Vulkan backend needs + // different allocations based on interlock mode and other factors. + m_plsExtent = {width, height, 1}; + m_plsTransientPlaneCount = planeCount; + m_plsTransientImageArray.reset(); + m_plsTransientCoverageView.reset(); + m_plsTransientClipView.reset(); + m_plsTransientScratchColorTexture.reset(); + m_plsBlendStorageTexture_RGB10_A2.reset(); + m_plsTransientClipTexture_R16F.reset(); + m_plsOffscreenColorTexture.reset(); +} + +void RenderContextVulkanImpl::resizeAtomicCoverageBacking(uint32_t width, + uint32_t height) +{ + m_plsAtomicCoverageTexture.reset(); + + if (width != 0 && height != 0) + { + m_plsAtomicCoverageTexture = m_vk->makeTexture2D( + { + .format = VK_FORMAT_R32_UINT, + .extent = {width, height}, + .usage = + VK_IMAGE_USAGE_STORAGE_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT, // For vkCmdClearColorImage + }, + "atomic coverage backing"); } } @@ -2178,6 +1253,332 @@ void RenderContextVulkanImpl::resizeCoverageBuffer(size_t sizeInBytes) } } +vkutil::Image* RenderContextVulkanImpl::plsTransientImageArray() +{ + assert(m_plsExtent.width != 0); + assert(m_plsExtent.height != 0); + assert(m_plsExtent.depth == 1); + assert(m_plsTransientPlaneCount != 0); + + if (m_plsTransientImageArray == nullptr) + { + m_plsTransientImageArray = m_vk->makeImage( + { + .imageType = VK_IMAGE_TYPE_2D, + .format = VK_FORMAT_R32_UINT, + .extent = m_plsExtent, + .arrayLayers = std::min(m_plsTransientPlaneCount, 2u), + .usage = m_plsTransientUsageFlags, + }, + "plsTransientImageArray"); + } + + return m_plsTransientImageArray.get(); +} + +vkutil::ImageView* RenderContextVulkanImpl::plsTransientCoverageView() +{ + if (m_plsTransientCoverageView == nullptr) + { + m_plsTransientCoverageView = + makePLSTransientImageView(VK_FORMAT_R32_UINT, + PLS_TRANSIENT_COVERAGE_IDX, + "plsTransientCoverageView"); + } + return m_plsTransientCoverageView.get(); +} + +vkutil::ImageView* RenderContextVulkanImpl::plsTransientClipView() +{ + if (m_plsTransientClipView == nullptr) + { + m_plsTransientClipView = + makePLSTransientImageView(VK_FORMAT_R32_UINT, + PLS_TRANSIENT_CLIP_IDX, + "plsTransientClipView"); + } + return m_plsTransientClipView.get(); +} + +rcp RenderContextVulkanImpl::makePLSTransientImageView( + VkFormat format, + uint32_t index, + const char* debugName) +{ + return m_vk->makeImageView( + ref_rcp(plsTransientImageArray()), + { + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = format, + .subresourceRange = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .levelCount = 1, + // If the transient array isn't large enough to host this + // index, it's safe to alias with a lower one (e.g., a clip + // and coverage view that will never be used together in the + // same render pass). + .baseArrayLayer = + std::min(index, m_plsTransientPlaneCount - 1u), + .layerCount = 1, + }, + }, + debugName); +} + +vkutil::Texture2D* RenderContextVulkanImpl::plsTransientScratchColorTexture() +{ + assert(m_plsExtent.width != 0); + assert(m_plsExtent.height != 0); + assert(m_plsExtent.depth == 1); + assert(m_plsTransientPlaneCount != 0); + + if (m_plsTransientScratchColorTexture == nullptr) + { + m_plsTransientScratchColorTexture = m_vk->makeTexture2D( + { + .flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, + .format = VK_FORMAT_R8G8B8A8_UNORM, + .extent = m_plsExtent, + .usage = m_plsTransientUsageFlags, + }, + "plsTransientScratchColorTexture"); + } + + return m_plsTransientScratchColorTexture.get(); +} + +vkutil::Texture2D* RenderContextVulkanImpl::plsBlendStorageTexture_RGB10_A2() +{ + if (m_plsBlendStorageTexture_RGB10_A2 == nullptr) + { + m_plsBlendStorageTexture_RGB10_A2 = m_vk->makeTexture2D( + { + .format = VK_FORMAT_A2B10G10R10_UNORM_PACK32, + .extent = m_plsExtent, + .usage = VK_IMAGE_USAGE_STORAGE_BIT | + // For vkCmdClearColorImage. + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + }, + "plsBlendStorageTexture_RGB10_A2"); + } + + return m_plsBlendStorageTexture_RGB10_A2.get(); +} + +vkutil::Texture2D* RenderContextVulkanImpl::plsTransientClipTexture_R16F() +{ + if (m_plsTransientClipTexture_R16F == nullptr) + { + m_plsTransientClipTexture_R16F = m_vk->makeTexture2D( + { + .format = VK_FORMAT_R16_SFLOAT, + .extent = m_plsExtent, + .usage = m_plsTransientUsageFlags, + }, + "plsTransientClipTexture_R16F"); + } + + return m_plsTransientClipTexture_R16F.get(); +} + +vkutil::Texture2D* RenderContextVulkanImpl::accessPLSOffscreenColorTexture( + VkCommandBuffer commandBuffer, + const vkutil::ImageAccess& dstAccess, + vkutil::ImageAccessAction imageAccessAction) +{ + assert(m_plsExtent.width != 0); + assert(m_plsExtent.height != 0); + assert(m_plsExtent.depth == 1); + assert(m_plsTransientPlaneCount != 0); + + if (m_plsOffscreenColorTexture == nullptr) + { + m_plsOffscreenColorTexture = m_vk->makeTexture2D( + { + .format = VK_FORMAT_R8G8B8A8_UNORM, + .extent = m_plsExtent, + .usage = (m_plsTransientUsageFlags | + // For copying back to the main render target. + VK_IMAGE_USAGE_TRANSFER_SRC_BIT) & + // This texture is never transient. + ~VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + }, + "PLSOffscreenColorTexture"); + } + + m_plsOffscreenColorTexture->barrier(commandBuffer, + dstAccess, + imageAccessAction); + + return m_plsOffscreenColorTexture.get(); +} + +vkutil::Texture2D* RenderContextVulkanImpl::clearPLSOffscreenColorTexture( + VkCommandBuffer commandBuffer, + ColorInt clearColor, + const vkutil::ImageAccess& dstAccessAfterClear) +{ + m_vk->clearColorImage( + commandBuffer, + clearColor, + accessPLSOffscreenColorTexture( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + vkutil::ImageAccessAction::invalidateContents) + ->vkImage(), + VK_IMAGE_LAYOUT_GENERAL); + + return accessPLSOffscreenColorTexture(commandBuffer, dstAccessAfterClear); +} + +vkutil::Texture2D* RenderContextVulkanImpl:: + copyRenderTargetToPLSOffscreenColorTexture( + VkCommandBuffer commandBuffer, + RenderTargetVulkan* renderTarget, + const IAABB& copyBounds, + const vkutil::ImageAccess& dstAccessAfterCopy) +{ + m_vk->blitSubRect(commandBuffer, + renderTarget->accessTargetImage( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }), + VK_IMAGE_LAYOUT_GENERAL, + accessPLSOffscreenColorTexture( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + vkutil::ImageAccessAction::invalidateContents) + ->vkImage(), + VK_IMAGE_LAYOUT_GENERAL, + copyBounds); + + return accessPLSOffscreenColorTexture(commandBuffer, dstAccessAfterCopy); +} + +bool RenderContextVulkanImpl::wantsManualRenderPassResolve( + gpu::InterlockMode interlockMode, + const RenderTarget* renderTarget, + const IAABB& renderTargetUpdateBounds, + uint32_t virtualTileWidth, + uint32_t virtualTileHeight, + gpu::DrawContents combinedDrawContents) const +{ + if (interlockMode == gpu::InterlockMode::rasterOrdering && + virtualTileWidth == 0 && virtualTileHeight == 0 && + !m_workarounds.needsInterruptibleRenderPasses()) + { +#ifndef __APPLE__ + // If the render target doesn't support input attachment usage, we will + // render to an offscreen texture that does. Add a resolve operation at + // the end of the render pass that transfers the offscreen data back to + // the main render target. On tilers, this saves the memory bandwidth of + // a fullscreen copy. + // NOTE: The manual resolve doesn't seem to work on MoltenVK, so don't + // do it on Apple. + auto renderTargetVulkan = + static_cast(renderTarget); + return !(renderTargetVulkan->targetUsageFlags() & + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); +#endif + } + if (interlockMode == gpu::InterlockMode::msaa && + !m_workarounds.avoidManualMSAAResolves) + { + if (!renderTargetUpdateBounds.contains(renderTarget->bounds())) + { + // Do manual resolves after partial updates because automatic + // resolves only support fullscreen. + // TODO: Identify when and if this is actually better than just + // taking the hit of an automatic fullscreen resolve. + return true; + } + if (m_workarounds.needsManualMSAAResolveAfterDstRead && + enums::is_flag_set(combinedDrawContents, + gpu::DrawContents::advancedBlend)) + { + return true; + } + } + return false; +} + +void RenderContextVulkanImpl::setCanvasQueue(VkQueue queue, + uint32_t queueFamilyIndex) +{ + m_canvasQueue = queue; + m_canvasQueueFamilyIndex = queueFamilyIndex; +} + +void* RenderContextVulkanImpl::makeCommandBuffer() +{ + if (m_canvasQueue == VK_NULL_HANDLE) + { + return nullptr; + } + if (m_canvasCommandPool == VK_NULL_HANDLE) + { + VkCommandPoolCreateInfo ci = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = m_canvasQueueFamilyIndex, + }; + VK_CHECK(m_vk->CreateCommandPool(m_vk->device, + &ci, + nullptr, + &m_canvasCommandPool)); + } + VkCommandBuffer cmdBuf; + VkCommandBufferAllocateInfo ai = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .commandPool = m_canvasCommandPool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + if (m_vk->AllocateCommandBuffers(m_vk->device, &ai, &cmdBuf) != VK_SUCCESS) + { + return nullptr; + } + VkCommandBufferBeginInfo bi = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + }; + m_vk->BeginCommandBuffer(cmdBuf, &bi); + return reinterpret_cast(cmdBuf); +} + +void RenderContextVulkanImpl::commitCommandBuffer(void* commandBuffer) +{ + if (commandBuffer == nullptr) + { + return; + } + auto cmdBuf = reinterpret_cast(commandBuffer); + m_vk->EndCommandBuffer(cmdBuf); + + VkSubmitInfo si = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .commandBufferCount = 1, + .pCommandBuffers = &cmdBuf, + }; + m_vk->QueueSubmit(m_canvasQueue, 1, &si, VK_NULL_HANDLE); + // Wait for completion so the canvas texture is ready for compositing + // and the command buffer can be freed immediately. + m_vk->QueueWaitIdle(m_canvasQueue); + m_vk->FreeCommandBuffers(m_vk->device, m_canvasCommandPool, 1, &cmdBuf); +} + void RenderContextVulkanImpl::prepareToFlush(uint64_t nextFrameNumber, uint64_t safeFrameNumber) { @@ -2194,7 +1595,14 @@ void RenderContextVulkanImpl::prepareToFlush(uint64_t nextFrameNumber, // Advance the context frame and delete resources that are no longer // referenced by in-flight command buffers. - m_vk->advanceFrameNumber(nextFrameNumber, safeFrameNumber); + // When nextFrameNumber is 0 this is a canvas pre-pass flush that uses its + // own command buffer (via makeCommandBuffer/commitCommandBuffer). Skip + // advancing the frame number because the pre-pass executes synchronously + // and doesn't participate in frame lifetime tracking. + if (nextFrameNumber != 0) + { + m_vk->advanceFrameNumber(nextFrameNumber, safeFrameNumber); + } // Acquire buffers for the flush. m_flushUniformBuffer = m_flushUniformBufferPool.acquire(); @@ -2213,10 +1621,11 @@ namespace descriptor_pool_limits constexpr static uint32_t kMaxUniformUpdates = 3; constexpr static uint32_t kMaxDynamicUniformUpdates = 1; constexpr static uint32_t kMaxImageTextureUpdates = 256; -constexpr static uint32_t kMaxSampledImageUpdates = - 4 + kMaxImageTextureUpdates; // tess + grad + feather + atlas + images +constexpr static uint32_t kMaxCombinedImageSamplerUpdates = + 3 + kMaxImageTextureUpdates; // grad + feather + atlas + images +constexpr static uint32_t kMaxSampledImageUpdates = 1; // tess constexpr static uint32_t kMaxStorageImageUpdates = - 1; // coverageAtomicTexture in atomic mode. + 4; // color/coverage/clip/scratch in clockwise mode. constexpr static uint32_t kMaxStorageBufferUpdates = 7 + // path/paint/uniform buffers 1; // coverage buffer in clockwiseAtomic mode @@ -2238,12 +1647,13 @@ RenderContextVulkanImpl::DescriptorSetPool::DescriptorSetPool( descriptor_pool_limits::kMaxDynamicUniformUpdates, }, { - .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - .descriptorCount = descriptor_pool_limits::kMaxSampledImageUpdates, + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = + descriptor_pool_limits::kMaxCombinedImageSamplerUpdates, }, { - .type = VK_DESCRIPTOR_TYPE_SAMPLER, - .descriptorCount = descriptor_pool_limits::kMaxImageTextureUpdates, + .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = descriptor_pool_limits::kMaxSampledImageUpdates, }, { .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, @@ -2315,56 +1725,402 @@ rcp RenderContextVulkanImpl:: { descriptorSetPool->reset(); } - return descriptorSetPool; + return descriptorSetPool; +} + +RenderContextVulkanImpl::DescriptorSetAllocator::DescriptorSetAllocator( + RenderContextVulkanImpl* impl) : + m_descriptorSetPoolPool(impl->m_descriptorSetPoolPool), + m_descriptorSetPool(m_descriptorSetPoolPool->acquire()), + m_perFlushDescriptorSet(m_descriptorSetPool->allocateDescriptorSet( + impl->m_pipelineManager->perFlushDescriptorSetLayout())), + m_perDrawDescriptorSetLayout( + impl->m_pipelineManager->perDrawDescriptorSetLayout()) +{} + +RenderContextVulkanImpl::DescriptorSetAllocator::~DescriptorSetAllocator() +{ + m_descriptorSetPoolPool->recycle(std::move(m_descriptorSetPool)); +} + +VkDescriptorSet RenderContextVulkanImpl::DescriptorSetAllocator:: + allocatePerDrawDescriptorSet() +{ + if (m_imageTextureUpdateCount >= + descriptor_pool_limits::kMaxImageTextureUpdates) + { + // We ran out of room for image texture updates. Allocate a new pool. + m_descriptorSetPoolPool->recycle(std::move(m_descriptorSetPool)); + m_descriptorSetPool = m_descriptorSetPoolPool->acquire(); + m_imageTextureUpdateCount = 0; + } + ++m_imageTextureUpdateCount; + return m_descriptorSetPool->allocateDescriptorSet( + m_perDrawDescriptorSetLayout); +} + +VkDescriptorSet RenderContextVulkanImpl::DescriptorSetAllocator:: + allocateDescriptorSet(VkDescriptorSetLayout layout) +{ + return m_descriptorSetPool->allocateDescriptorSet(layout); +} + +RenderContextVulkanImpl::DrawRenderPass::DrawRenderPass( + RenderContextVulkanImpl* impl, + const FlushDescriptor& desc, + gpu::LoadAction overrideColorLoadAction, + const IAABB& drawBounds, + VkImageView colorImageView, + VkImageView msaaColorSeedImageView, + VkImageView msaaResolveImageView, + RenderPassOptionsVulkan renderPassOptions, + const IAABB& scissor) : + m_impl(impl), + m_desc(desc), + m_drawBounds(drawBounds), + m_colorImageView(colorImageView), + m_msaaColorSeedImageView(msaaColorSeedImageView), + m_msaaResolveImageView(msaaResolveImageView), + m_pipelineLayout(begin(overrideColorLoadAction, renderPassOptions, scissor)) +{} + +const DrawPipelineLayoutVulkan& RenderContextVulkanImpl::DrawRenderPass::begin( + gpu::LoadAction overrideColorLoadAction, + RenderPassOptionsVulkan renderPassOptions, + const IAABB& scissor) +{ + VulkanContext* const vk = m_impl->m_vk.get(); + PipelineManagerVulkan* pipelineManager = m_impl->m_pipelineManager.get(); + const auto commandBuffer = + reinterpret_cast(m_desc.externalCommandBuffer); + auto* const renderTarget = + static_cast(m_desc.renderTarget); + + RenderPassVulkan& renderPass = pipelineManager->getRenderPassSynchronous( + m_desc.interlockMode, + renderPassOptions, + renderTarget->framebufferFormat(), + overrideColorLoadAction); + + const DrawPipelineLayoutVulkan& pipelineLayout = + *renderPass.drawPipelineLayout(); + + // Create the framebuffer. + StackVector + framebufferViews; + StackVector clearValues; + if (pipelineManager->plsBackingType(m_desc.interlockMode) == + PLSBackingType::inputAttachment || + enums::is_flag_set(pipelineLayout.renderPassOptions(), + RenderPassOptionsVulkan::fixedFunctionColorOutput)) + { + assert(framebufferViews.size() == COLOR_PLANE_IDX); + framebufferViews.push_back(m_colorImageView); + clearValues.push_back( + {.color = vkutil::color_clear_rgba32f(m_desc.colorClearValue)}); + } + switch (m_desc.interlockMode) + { + case gpu::InterlockMode::rasterOrdering: + assert(framebufferViews.size() == CLIP_PLANE_IDX); + framebufferViews.push_back(*m_impl->plsTransientClipView()); + clearValues.push_back({}); + + assert(framebufferViews.size() == SCRATCH_COLOR_PLANE_IDX); + framebufferViews.push_back( + m_impl->plsTransientScratchColorTexture()->vkImageView()); + clearValues.push_back({}); + + assert(framebufferViews.size() == COVERAGE_PLANE_IDX); + framebufferViews.push_back(*m_impl->plsTransientCoverageView()); + clearValues.push_back({.color = vkutil::color_clear_r32ui( + m_desc.coverageClearValue)}); + + if (enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)) + { + // The render pass will transfer the color data back into the + // renderTarget at the end. + assert(framebufferViews.size() == PLS_PLANE_COUNT); + framebufferViews.push_back(renderTarget->accessTargetImageView( + commandBuffer, + { + .pipelineStages = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }, + vkutil::ImageAccessAction::invalidateContents)); + clearValues.push_back({}); + } + break; + + case gpu::InterlockMode::atomics: + assert(framebufferViews.size() == CLIP_PLANE_IDX); + framebufferViews.push_back( + m_impl->plsTransientScratchColorTexture()->vkImageView()); + clearValues.push_back({}); + + if (enums::is_flag_set( + pipelineLayout.renderPassOptions(), + RenderPassOptionsVulkan::atomicCoalescedResolveAndTransfer)) + { + assert(m_desc.interlockMode == gpu::InterlockMode::atomics); + assert(framebufferViews.size() == COALESCED_ATOMIC_RESOLVE_IDX); + framebufferViews.push_back(renderTarget->accessTargetImageView( + commandBuffer, + { + .pipelineStages = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }, + m_drawBounds.contains( + IAABB{0, + 0, + static_cast(renderTarget->width()), + static_cast(renderTarget->height())}) + ? vkutil::ImageAccessAction::invalidateContents + : vkutil::ImageAccessAction::preserveContents)); + clearValues.push_back({}); + } + break; + + case gpu::InterlockMode::clockwise: + // clockwise uses storage textures exclusively instead of MRT. + break; + + case gpu::InterlockMode::clockwiseAtomic: + assert(framebufferViews.size() == CLIP_PLANE_IDX); + framebufferViews.push_back( + m_impl->plsTransientClipTexture_R16F()->vkImageView()); + clearValues.push_back({}); + break; + + case gpu::InterlockMode::msaa: + assert(framebufferViews.size() == MSAA_DEPTH_STENCIL_IDX); + framebufferViews.push_back( + renderTarget->msaaDepthStencilTexture()->vkImageView()); + clearValues.push_back({.depthStencil = {m_desc.depthClearValue, + m_desc.stencilClearValue}}); + + assert(framebufferViews.size() == MSAA_RESOLVE_IDX); + framebufferViews.push_back(m_msaaResolveImageView); + clearValues.push_back({}); + + if (enums::is_flag_set( + pipelineLayout.renderPassOptions(), + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture)) + { + assert(overrideColorLoadAction == + gpu::LoadAction::preserveRenderTarget); + assert(m_msaaColorSeedImageView != VK_NULL_HANDLE); + assert(m_msaaColorSeedImageView != m_msaaResolveImageView); + assert(framebufferViews.size() == MSAA_COLOR_SEED_IDX); + framebufferViews.push_back(m_msaaColorSeedImageView); + clearValues.push_back({}); + } + break; + } + + rcp framebuffer = vk->makeFramebuffer({ + .renderPass = renderPass, + .attachmentCount = framebufferViews.size(), + .pAttachments = framebufferViews.data(), + .width = static_cast(renderTarget->width()), + .height = static_cast(renderTarget->height()), + .layers = 1, + }); + + assert(clearValues.size() == framebufferViews.size()); + VkRenderPassBeginInfo renderPassBeginInfo = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = renderPass, + .framebuffer = *framebuffer, + .renderArea = vkutil::rect2d(m_drawBounds), + .clearValueCount = clearValues.size(), + .pClearValues = clearValues.data(), + }; + + vk->CmdBeginRenderPass(commandBuffer, + &renderPassBeginInfo, + VK_SUBPASS_CONTENTS_INLINE); + + vk->CmdSetViewport( + commandBuffer, + 0, + 1, + vkutil::ViewportFromRect2D( + {.extent = {renderTarget->width(), renderTarget->height()}})); + + VkRect2D scissorRect = vkutil::rect2d(scissor); + vk->CmdSetScissor(commandBuffer, 0, 1, &scissorRect); + + m_renderPassOptions = renderPassOptions; + m_scissor = scissor; + m_patchCountInCurrentDrawPass = 0; + + return pipelineLayout; +} + +void RenderContextVulkanImpl::DrawRenderPass::restart( + gpu::LoadAction colorLoadAction, + RenderPassOptionsVulkan renderPassOptions, + const IAABB& scissor) +{ + VulkanContext* const vk = m_impl->m_vk.get(); + const auto commandBuffer = + reinterpret_cast(m_desc.externalCommandBuffer); + + vk->CmdEndRenderPass(commandBuffer); + + const DrawPipelineLayoutVulkan& restartedLayout RIVE_MAYBE_UNUSED = + begin(colorLoadAction, renderPassOptions, scissor); + // We don't need to bind new pipelines, even though we changed the render + // pass, because Vulkan allows for pipelines to be used interchangeably with + // "compatible" render passes. + + // The renderPassOptions dealing with interrupting a render pass don't + // affect the layout. We count on the new render pass having the same + // VkPipelineLayout so we don't have to update any descriptor sets after the + // interruption. + assert(&restartedLayout == &m_pipelineLayout); +} + +void RenderContextVulkanImpl::DrawRenderPass::interruptIfNeeded( + uint32_t nextTessPatchCount, + uint32_t pendingTessPatchCount) +{ + const DriverWorkarounds& workarounds = m_impl->m_workarounds; + assert(nextTessPatchCount <= workarounds.maxInstancesPerRenderPass); + + if (m_desc.interlockMode == gpu::InterlockMode::rasterOrdering && + m_patchCountInCurrentDrawPass + nextTessPatchCount > + workarounds.maxInstancesPerRenderPass) + { + // We're on an early Android tiler that is known to crash when a render + // pass is too complex, and we've reached the complexity threshold. + // Interrupt and begin a new render pass. + RenderPassOptionsVulkan renderPassOptions = m_renderPassOptions; + assert(enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingInterruptible)); + // Manually resolved render passes aren't currently compatible with + // interruptions. + assert(!enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)); + + renderPassOptions |= RenderPassOptionsVulkan::rasterOrderingResume; + if (pendingTessPatchCount <= workarounds.maxInstancesPerRenderPass) + { + renderPassOptions &= + ~RenderPassOptionsVulkan::rasterOrderingInterruptible; + } + + restart(gpu::LoadAction::preserveRenderTarget, + renderPassOptions, + m_scissor); + } + + m_patchCountInCurrentDrawPass += nextTessPatchCount; } void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) { - constexpr static VkDeviceSize ZERO_OFFSET[1] = {0}; - constexpr static uint32_t ZERO_OFFSET_32[1] = {0}; + auto* const renderTarget = + static_cast(desc.renderTarget); - if (desc.interlockMode == gpu::InterlockMode::msaa) + IAABB drawBounds = desc.renderTargetUpdateBounds; + if (drawBounds.empty()) { return; } - if (desc.renderTargetUpdateBounds.empty()) + auto renderPassOptions = RenderPassOptionsVulkan::none; + if (desc.fixedFunctionColorOutput) { - return; + // In the case of Vulkan, fixedFunctionColorOutput means the color + // buffer will never be bound as an input attachment. + renderPassOptions |= RenderPassOptionsVulkan::fixedFunctionColorOutput; } - - auto commandBuffer = - reinterpret_cast(desc.externalCommandBuffer); - rcp descriptorSetPool = - m_descriptorSetPoolPool->acquire(); - - // Apply pending texture updates. - if (m_featherTexture->hasUpdates()) + if (desc.manuallyResolved) { - m_featherTexture->synchronize(commandBuffer); + // The drawList ends with a batch of type of type + // DrawType::renderPassResolve, and the render pass needs to be set up + // to handle manual resolving. + renderPassOptions |= RenderPassOptionsVulkan::manuallyResolved; } - if (m_nullImageTexture->hasUpdates()) + else if (desc.interlockMode == gpu::InterlockMode::msaa) { - m_nullImageTexture->synchronize(commandBuffer); + // Vulkan does not support partial MSAA resolves when using resolve + // attachments. + drawBounds = renderTarget->bounds(); } + // Vulkan builtin MSAA resolves don't support partial drawBounds. + assert(desc.interlockMode != gpu::InterlockMode::msaa || + desc.manuallyResolved || drawBounds == renderTarget->bounds()); + + const auto commandBuffer = + reinterpret_cast(desc.externalCommandBuffer); + assert(commandBuffer != VK_NULL_HANDLE); + + m_featherTexture->prepareForVertexOrFragmentShaderRead(commandBuffer); + m_nullImageTexture->prepareForFragmentShaderRead(commandBuffer); + + uint32_t pendingTessPatchCount = 0; for (const DrawBatch& batch : *desc.drawList) { + // Apply pending image texture updates. if (auto imageTextureVulkan = static_cast(batch.imageTexture)) { - if (imageTextureVulkan->hasUpdates()) - { - imageTextureVulkan->synchronize(commandBuffer); - } + imageTextureVulkan->prepareForFragmentShaderRead(commandBuffer); + } + + // Count up the complexity in tessellation patches of this flush. + switch (batch.drawType) + { + case DrawType::midpointFanPatches: + case DrawType::midpointFanCenterAAPatches: + case DrawType::outerCurvePatches: + case DrawType::msaaOuterCubics: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: + pendingTessPatchCount += batch.elementCount; + break; + case DrawType::clipReset: + case DrawType::interiorTriangulation: + case DrawType::atlasBlit: + case DrawType::imageRect: + case DrawType::imageMesh: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: + break; } } + if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && + pendingTessPatchCount > m_workarounds.maxInstancesPerRenderPass) + { + // Some early Android tilers are known to crash when a render pass is + // too complex. Make this render pass interruptible so we can break it + // up and avoid the crash. + assert(!(m_plsTransientUsageFlags & + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)); + // Manually resolved render passes aren't currently compatible with + // interruptions. + assert(!desc.manuallyResolved); + renderPassOptions |= + RenderPassOptionsVulkan::rasterOrderingInterruptible; + } - // Create a per-flush descriptor set. - VkDescriptorSet perFlushDescriptorSet = - descriptorSetPool->allocateDescriptorSet(m_perFlushDescriptorSetLayout); + DescriptorSetAllocator descriptorSetAllocator(this); m_vk->updateBufferDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = FLUSH_UNIFORM_BUFFER_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, @@ -2376,7 +2132,7 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); m_vk->updateBufferDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = IMAGE_DRAW_UNIFORM_BUFFER_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, @@ -2388,7 +2144,7 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); m_vk->updateBufferDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = PATH_BUFFER_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -2400,27 +2156,37 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); m_vk->updateBufferDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = PAINT_BUFFER_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, }, + {{ + .buffer = *m_paintBuffer, + .offset = desc.firstPaint * sizeof(gpu::PaintData), + .range = VK_WHOLE_SIZE, + }}); + + // NOTE: This technically could be part of the above call (passing two + // buffers instead of one to set them both at once), but there is a bug on + // some Adreno devices where the second one does not get applied properly + // (all reads from PaintAuxBuffer end up reading 0s), so instead we'll do it + // as a separate call. + m_vk->updateBufferDescriptorSets( + descriptorSetAllocator.perFlushDescriptorSet(), { - { - .buffer = *m_paintBuffer, - .offset = desc.firstPaint * sizeof(gpu::PaintData), - .range = VK_WHOLE_SIZE, - }, - { - .buffer = *m_paintAuxBuffer, - .offset = desc.firstPaintAux * sizeof(gpu::PaintAuxData), - .range = VK_WHOLE_SIZE, - }, - }); + .dstBinding = PAINT_AUX_BUFFER_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + }, + {{ + .buffer = *m_paintAuxBuffer, + .offset = desc.firstPaintAux * sizeof(gpu::PaintAuxData), + .range = VK_WHOLE_SIZE, + }}); static_assert(PAINT_AUX_BUFFER_IDX == PAINT_BUFFER_IDX + 1); m_vk->updateBufferDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = CONTOUR_BUFFER_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -2435,7 +2201,7 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) m_coverageBuffer != nullptr) { m_vk->updateBufferDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = COVERAGE_BUFFER_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -2448,7 +2214,7 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) } m_vk->updateImageDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = TESS_VERTEX_TEXTURE_IDX, .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, @@ -2459,10 +2225,10 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); m_vk->updateImageDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = GRAD_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, }, {{ .imageView = m_gradTexture->vkImageView(), @@ -2470,10 +2236,10 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); m_vk->updateImageDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = FEATHER_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, }, {{ .imageView = m_featherTexture->vkImageView(), @@ -2481,10 +2247,10 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); m_vk->updateImageDescriptorSets( - perFlushDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), { .dstBinding = ATLAS_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, }, {{ .imageView = m_atlasTexture->vkImageView(), @@ -2494,35 +2260,13 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) // Render the complex color ramps to the gradient texture. if (desc.gradSpanCount > 0) { - // Wait for previous accesses to finish before rendering to the gradient - // texture. - m_gradTexture->barrier( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }, - vkutil::ImageAccessAction::invalidateContents); - VkRect2D renderArea = { .extent = {gpu::kGradTextureWidth, desc.gradDataHeight}, }; - VkRenderPassBeginInfo renderPassBeginInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = m_colorRampPipeline->renderPass(), - .framebuffer = *m_gradTextureFramebuffer, - .renderArea = renderArea, - }; - - m_vk->CmdBeginRenderPass(commandBuffer, - &renderPassBeginInfo, - VK_SUBPASS_CONTENTS_INLINE); - - m_vk->CmdBindPipeline(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_colorRampPipeline->renderPipeline()); + m_colorRampPipeline->beginRenderPass(commandBuffer, + renderArea, + *m_gradTextureFramebuffer); m_vk->CmdSetViewport(commandBuffer, 0, @@ -2540,20 +2284,38 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) &gradSpanBuffer, &gradSpanOffset); - m_vk->CmdBindDescriptorSets(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_colorRampPipeline->pipelineLayout(), - PER_FLUSH_BINDINGS_SET, - 1, - &perFlushDescriptorSet, - 1, - ZERO_OFFSET_32); - - m_vk->CmdDraw(commandBuffer, - gpu::GRAD_SPAN_TRI_STRIP_VERTEX_COUNT, - desc.gradSpanCount, - 0, - 0); + m_vk->CmdBindDescriptorSets( + commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_colorRampPipeline->pipelineLayout(), + PER_FLUSH_BINDINGS_SET, + 1, + &descriptorSetAllocator.perFlushDescriptorSet(), + 1, + ZERO_OFFSET_32); + + m_vk->CmdBindPipeline(commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_colorRampPipeline->renderPipeline()); + + for (auto [chunkInstanceCount, chunkFirstInstance] : + InstanceChunker(desc.gradSpanCount, + 0, + m_workarounds.maxInstancesPerRenderPass)) + + { + m_colorRampPipeline->interruptRenderPassIfNeeded( + commandBuffer, + renderArea, + *m_gradTextureFramebuffer, + chunkInstanceCount, + m_workarounds); + m_vk->CmdDraw(commandBuffer, + gpu::GRAD_SPAN_TRI_STRIP_VERTEX_COUNT, + chunkInstanceCount, + 0, + chunkFirstInstance); + } m_vk->CmdEndRenderPass(commandBuffer); @@ -2562,22 +2324,32 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) m_gradTexture->lastAccess().layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - - // Ensure the gradient texture has finished updating before the path - // fragment shaders read it. - m_gradTexture->barrier( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - .accessMask = VK_ACCESS_SHADER_READ_BIT, - .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }); + else + { + // The above render pass has the barriers in it, but if it was not run, + // we still are going to bind it as READ_ONLY_OPTIMAL so need to + // transition it + // TODO: Perhaps we should have a "null" texture that we can bind for + // cases like this where we need to bind all the textures but know it's + // not needed + m_gradTexture->barrier( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = VK_ACCESS_SHADER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }); + } // Tessellate all curves into vertices in the tessellation texture. if (desc.tessVertexSpanCount > 0) { // Don't render new vertices until the previous flush has finished using // the tessellation texture. + // TODO: What this barrier does is also part of the tessellation + // renderpass, and should be handled automatically, but on early PowerVR + // devices (Reno 3 Plus, Vivo Y21) tesselation is still incorrect + // without this explicit barrier. Figure out why. m_tessTexture->barrier( commandBuffer, { @@ -2587,31 +2359,20 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }, vkutil::ImageAccessAction::invalidateContents); - VkRect2D renderArea = { + const VkRect2D tessellateArea = { .extent = {gpu::kTessTextureWidth, desc.tessDataHeight}, }; - VkRenderPassBeginInfo renderPassBeginInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = m_tessellatePipeline->renderPass(), - .framebuffer = *m_tessTextureFramebuffer, - .renderArea = renderArea, - }; - - m_vk->CmdBeginRenderPass(commandBuffer, - &renderPassBeginInfo, - VK_SUBPASS_CONTENTS_INLINE); - - m_vk->CmdBindPipeline(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_tessellatePipeline->renderPipeline()); + m_tessellatePipeline->beginRenderPass(commandBuffer, + tessellateArea, + *m_tessTextureFramebuffer); m_vk->CmdSetViewport(commandBuffer, 0, 1, - vkutil::ViewportFromRect2D(renderArea)); + vkutil::ViewportFromRect2D(tessellateArea)); - m_vk->CmdSetScissor(commandBuffer, 0, 1, &renderArea); + m_vk->CmdSetScissor(commandBuffer, 0, 1, &tessellateArea); VkBuffer tessBuffer = *m_tessSpanBuffer; VkDeviceSize tessOffset = @@ -2627,29 +2388,39 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) 0, VK_INDEX_TYPE_UINT16); - m_vk->CmdBindDescriptorSets(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_tessellatePipeline->pipelineLayout(), - PER_FLUSH_BINDINGS_SET, - 1, - &perFlushDescriptorSet, - 1, - ZERO_OFFSET_32); - m_vk->CmdBindDescriptorSets(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_tessellatePipeline->pipelineLayout(), - IMMUTABLE_SAMPLER_BINDINGS_SET, - 1, - &m_immutableSamplerDescriptorSet, - 0, - nullptr); + m_vk->CmdBindDescriptorSets( + commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_tessellatePipeline->pipelineLayout(), + PER_FLUSH_BINDINGS_SET, + 1, + &descriptorSetAllocator.perFlushDescriptorSet(), + 1, + ZERO_OFFSET_32); - m_vk->CmdDrawIndexed(commandBuffer, - std::size(gpu::kTessSpanIndices), - desc.tessVertexSpanCount, - 0, + m_vk->CmdBindPipeline(commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_tessellatePipeline->renderPipeline()); + + for (auto [chunkInstanceCount, chunkFirstInstance] : + InstanceChunker(desc.tessVertexSpanCount, 0, - 0); + m_workarounds.maxInstancesPerRenderPass)) + + { + m_tessellatePipeline->interruptRenderPassIfNeeded( + commandBuffer, + tessellateArea, + *m_tessTextureFramebuffer, + chunkInstanceCount, + m_workarounds); + m_vk->CmdDrawIndexed(commandBuffer, + std::size(gpu::kTessSpanIndices), + chunkInstanceCount, + 0, + 0, + chunkFirstInstance); + } m_vk->CmdEndRenderPass(commandBuffer); @@ -2657,10 +2428,61 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL. m_tessTexture->lastAccess().layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + if (m_tesselationSyncIssueWorkaroundTexture != nullptr) + { + // On the Adreno 8xx series drivers we've encountered, there is some + // sort of synchronization issue with the tesselation texture that + // causes the barriers to not work, and it ends up being corrupted. + // However, if we first just blit it to an offscreen texture (just a + // 1x1 texture), the render corruption goes away. + m_tessTexture->barrier( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }); + + // We need this transition but really only one time (if we haven't + // done so already) + if (m_tesselationSyncIssueWorkaroundTexture->lastAccess().layout != + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + { + m_tesselationSyncIssueWorkaroundTexture->barrier( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + }, + vkutil::ImageAccessAction::invalidateContents); + } + + m_vk->blitSubRect( + commandBuffer, + m_tessTexture->vkImage(), + VK_IMAGE_LAYOUT_GENERAL, + m_tesselationSyncIssueWorkaroundTexture->vkImage(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + IAABB::MakeWH( + m_tesselationSyncIssueWorkaroundTexture->width(), + m_tesselationSyncIssueWorkaroundTexture->height())); + + // NOTE: Technically there should be a barrier after this blit to + // prevent a write-after-write hazard. However, we don't use this + // texture at all and thus don't care if we overwrite it, so there + // is intentionally no barrier here...but you will get a failure on + // this texture if you enable synchronization validation on a device + // with the workaround enabled. + } } // Ensure the tessellation texture has finished rendering before the path // vertex shaders read it. + // TODO: Similar to the barrier on the way into rendering the tesselation + // texture, this barrier should already be covered by the tesselation + // renderpass but fails on early PowerVR devices. m_tessTexture->barrier( commandBuffer, { @@ -2672,39 +2494,22 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) // Render the atlas if we have any offscreen feathers. if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0) { - // Don't render new vertices until the previous flush has finished using - // the atlas texture. - m_atlasTexture->barrier( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }, - vkutil::ImageAccessAction::invalidateContents); - VkRect2D renderArea = { .extent = {desc.atlasContentWidth, desc.atlasContentHeight}, }; - VkClearValue atlasClearValue = {}; + // Begin the render pass before binding buffers or updating descriptor + // sets. It's valid Vulkan to do these tasks in any order, but Adreno + // 730, 740, and 840 appreciate it when we begin the render pass first. + m_atlasPipeline->beginRenderPass(commandBuffer, + renderArea, + *m_atlasFramebuffer); - VkRenderPassBeginInfo renderPassBeginInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = m_atlasPipeline->renderPass(), - .framebuffer = *m_atlasFramebuffer, - .renderArea = renderArea, - .clearValueCount = 1, - .pClearValues = &atlasClearValue, - }; - - m_vk->CmdBeginRenderPass(commandBuffer, - &renderPassBeginInfo, - VK_SUBPASS_CONTENTS_INLINE); m_vk->CmdSetViewport(commandBuffer, 0, 1, vkutil::ViewportFromRect2D(renderArea)); + m_vk->CmdBindVertexBuffers(commandBuffer, 0, 1, @@ -2714,22 +2519,16 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) *m_pathPatchIndexBuffer, 0, VK_INDEX_TYPE_UINT16); - m_vk->CmdBindDescriptorSets(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_atlasPipeline->pipelineLayout(), - PER_FLUSH_BINDINGS_SET, - 1, - &perFlushDescriptorSet, - 1, - ZERO_OFFSET_32); - m_vk->CmdBindDescriptorSets(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - m_atlasPipeline->pipelineLayout(), - IMMUTABLE_SAMPLER_BINDINGS_SET, - 1, - &m_immutableSamplerDescriptorSet, - 0, - nullptr); + m_vk->CmdBindDescriptorSets( + commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + m_atlasPipeline->pipelineLayout(), + PER_FLUSH_BINDINGS_SET, + 1, + &descriptorSetAllocator.perFlushDescriptorSet(), + 1, + ZERO_OFFSET_32); + if (desc.atlasFillBatchCount != 0) { m_vk->CmdBindPipeline(commandBuffer, @@ -2744,12 +2543,26 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) fillBatch.scissor.height()}, }; m_vk->CmdSetScissor(commandBuffer, 0, 1, &scissor); - m_vk->CmdDrawIndexed(commandBuffer, - gpu::kMidpointFanCenterAAPatchIndexCount, - fillBatch.patchCount, - gpu::kMidpointFanCenterAAPatchBaseIndex, - 0, - fillBatch.basePatch); + for (auto [chunkPatchCount, chunkFirstPatch] : + InstanceChunker(fillBatch.patchCount, + fillBatch.basePatch, + m_workarounds.maxInstancesPerRenderPass)) + + { + m_atlasPipeline->interruptRenderPassIfNeeded( + commandBuffer, + renderArea, + *m_atlasFramebuffer, + chunkPatchCount, + m_workarounds); + m_vk->CmdDrawIndexed( + commandBuffer, + gpu::kMidpointFanCenterAAPatchIndexCount, + chunkPatchCount, + gpu::kMidpointFanCenterAAPatchBaseIndex, + 0, + chunkFirstPatch); + } } } @@ -2769,12 +2582,25 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) strokeBatch.scissor.height()}, }; m_vk->CmdSetScissor(commandBuffer, 0, 1, &scissor); - m_vk->CmdDrawIndexed(commandBuffer, - gpu::kMidpointFanPatchBorderIndexCount, - strokeBatch.patchCount, - gpu::kMidpointFanPatchBaseIndex, - 0, - strokeBatch.basePatch); + for (auto [chunkPatchCount, chunkFirstPatch] : + InstanceChunker(strokeBatch.patchCount, + strokeBatch.basePatch, + m_workarounds.maxInstancesPerRenderPass)) + + { + m_atlasPipeline->interruptRenderPassIfNeeded( + commandBuffer, + renderArea, + *m_atlasFramebuffer, + chunkPatchCount, + m_workarounds); + m_vk->CmdDrawIndexed(commandBuffer, + gpu::kMidpointFanPatchBorderIndexCount, + chunkPatchCount, + gpu::kMidpointFanPatchBaseIndex, + 0, + chunkFirstPatch); + } } } @@ -2786,215 +2612,235 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } - // Ensure the atlas texture has finished rendering before the fragment - // shaders read it. - m_atlasTexture->barrier( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - .accessMask = VK_ACCESS_SHADER_READ_BIT, - .layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }); - - auto* renderTarget = static_cast(desc.renderTarget); - - vkutil::Texture2D *clipTexture, *scratchColorTexture, *coverageTexture; - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering) - { - clipTexture = renderTarget->clipTextureR32UI(); - scratchColorTexture = renderTarget->scratchColorTexture(); - coverageTexture = renderTarget->coverageTexture(); - } - else if (desc.interlockMode == gpu::InterlockMode::atomics) - { - clipTexture = renderTarget->clipTextureRGBA8(); - scratchColorTexture = nullptr; - coverageTexture = renderTarget->coverageAtomicTexture(); - } - - // Ensure any previous accesses to the color texture complete before we + // Ensures any previous accesses to a color attachment complete before we // begin rendering. const vkutil::ImageAccess colorLoadAccess = { // "Load" operations always occur in // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT. .pipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .layout = desc.atomicFixedFunctionColorOutput + .layout = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL, }; - const bool renderAreaIsFullTarget = desc.renderTargetUpdateBounds.contains( + const bool renderAreaIsFullTarget = drawBounds.contains( IAABB{0, 0, static_cast(renderTarget->width()), static_cast(renderTarget->height())}); - VkImageView colorImageView; - bool colorAttachmentIsOffscreen; - if (desc.atomicFixedFunctionColorOutput || - (renderTarget->targetUsageFlags() & - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) - { - colorImageView = renderTarget->accessTargetImageView( - commandBuffer, - colorLoadAccess, - renderAreaIsFullTarget && desc.colorLoadAction != - gpu::LoadAction::preserveRenderTarget - ? vkutil::ImageAccessAction::invalidateContents - : vkutil::ImageAccessAction::preserveContents); - colorAttachmentIsOffscreen = false; - } - else if (desc.colorLoadAction != gpu::LoadAction::preserveRenderTarget) - { - colorImageView = renderTarget - ->accessOffscreenColorTexture( - commandBuffer, - colorLoadAccess, - vkutil::ImageAccessAction::invalidateContents) - ->vkImageView(); - colorAttachmentIsOffscreen = true; - } - else + const vkutil::ImageAccessAction targetAccessAction = + renderAreaIsFullTarget && + desc.colorLoadAction != gpu::LoadAction::preserveRenderTarget + ? vkutil::ImageAccessAction::invalidateContents + : vkutil::ImageAccessAction::preserveContents; + + const PLSBackingType plsBackingType = + m_pipelineManager->plsBackingType(desc.interlockMode); + + VkImageView colorImageView = VK_NULL_HANDLE; + bool colorAttachmentIsOffscreen = false; + + VkImageView msaaResolveImageView = VK_NULL_HANDLE; + VkImageView msaaColorSeedImageView = VK_NULL_HANDLE; + + if (desc.interlockMode == gpu::InterlockMode::msaa) { - // Preserve the target texture by blitting its contents into our - // offscreen color texture. - m_vk->blitSubRect( - commandBuffer, - renderTarget->accessTargetImage( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, - .accessMask = VK_ACCESS_TRANSFER_READ_BIT, - .layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - }), - renderTarget - ->accessOffscreenColorTexture( + colorImageView = renderTarget->msaaColorTexture()->vkImageView(); + +#if 0 + // TODO: Some early Qualcomm devices struggle when seeding from and + // resolving to the same texture, even if we implement the MSAA resolve + // manually. For now, always copy out the render target to a separate + // texture when there's a preserve, but we should investigate this + // further. + if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget && + (renderTarget->targetUsageFlags() & + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) + { + // We can seed from, and resolve to the the same texture. + msaaColorSeedImageView = msaaResolveImageView = + renderTarget->accessTargetImageView( commandBuffer, { - .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, - .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - vkutil::ImageAccessAction::invalidateContents) - ->vkImage(), - desc.renderTargetUpdateBounds); + // Apply a barrier for reading from this texture as an + // input attachment. + // vkCmdNextSubpass() will handle the barrier between + // reading this texture and resolving to it. + .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }); + } + else +#endif + { + if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget) + { + // We have to seed the MSAA attachment from a separate texture + // because the render target doesn't support being bound as an + // input attachment. + msaaColorSeedImageView = + renderTarget + ->copyTargetImageToOffscreenColorTexture( + commandBuffer, + { + .pipelineStages = + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + drawBounds) + ->vkImageView(); + renderPassOptions |= + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture; + } + msaaResolveImageView = renderTarget->accessTargetImageView( + commandBuffer, + { + .pipelineStages = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }, + renderAreaIsFullTarget + ? vkutil::ImageAccessAction::invalidateContents + : vkutil::ImageAccessAction::preserveContents); + } + } + else if (enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput) || + ((desc.interlockMode == gpu::InterlockMode::rasterOrdering || + desc.interlockMode == gpu::InterlockMode::atomics) && + (renderTarget->targetUsageFlags() & + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) + { + // We can render directly to the render target. colorImageView = - renderTarget - ->accessOffscreenColorTexture(commandBuffer, colorLoadAccess) - ->vkImageView(); - colorAttachmentIsOffscreen = true; + renderTarget->accessTargetImageView(commandBuffer, + colorLoadAccess, + targetAccessAction); + } + else if (plsBackingType == PLSBackingType::storageTexture) + { + constexpr static vkutil::ImageAccess PLS_STORAGE_TEXTURE_ACCESS = { + .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }; + + if ((renderTarget->targetUsageFlags() & VK_IMAGE_USAGE_STORAGE_BIT) && + renderTarget->framebufferFormat() == VK_FORMAT_R8G8B8A8_UNORM) + { + // We can bind the renderTarget as a storage texture directly to the + // color plane_. + if (desc.colorLoadAction == gpu::LoadAction::clear) + { + colorImageView = renderTarget->clearTargetImageView( + commandBuffer, + desc.colorClearValue, + PLS_STORAGE_TEXTURE_ACCESS); + } + else + { + colorImageView = renderTarget->accessTargetImageView( + commandBuffer, + PLS_STORAGE_TEXTURE_ACCESS, + targetAccessAction); + } + } + else + { + // We have to bind a separate texture to the color plane. + switch (desc.colorLoadAction) + { + case gpu::LoadAction::clear: + colorImageView = clearPLSOffscreenColorTexture( + commandBuffer, + desc.colorClearValue, + PLS_STORAGE_TEXTURE_ACCESS) + ->vkImageView(); + break; + case gpu::LoadAction::preserveRenderTarget: + // Preserve the target texture by copying its contents into + // our offscreen color texture. + colorImageView = copyRenderTargetToPLSOffscreenColorTexture( + commandBuffer, + renderTarget, + drawBounds, + PLS_STORAGE_TEXTURE_ACCESS) + ->vkImageView(); + break; + case gpu::LoadAction::dontCare: + colorImageView = + accessPLSOffscreenColorTexture( + commandBuffer, + PLS_STORAGE_TEXTURE_ACCESS, + vkutil::ImageAccessAction::invalidateContents) + ->vkImageView(); + break; + } + colorAttachmentIsOffscreen = true; + } } - - auto pipelineLayoutOptions = DrawPipelineLayoutOptions::none; - if (desc.interlockMode == gpu::InterlockMode::atomics) + else { - if (desc.atomicFixedFunctionColorOutput) + // The renderTarget doesn't support input attachments, so we have to + // attach a separate texture to the framebuffer for color. + if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget) + { + // Preserve the target texture by copying its contents into our + // offscreen color texture. + colorImageView = + renderTarget + ->copyTargetImageToOffscreenColorTexture(commandBuffer, + colorLoadAccess, + drawBounds) + ->vkImageView(); + } + else { - pipelineLayoutOptions |= - DrawPipelineLayoutOptions::fixedFunctionColorOutput; + colorImageView = + renderTarget + ->accessOffscreenColorTexture( + commandBuffer, + colorLoadAccess, + vkutil::ImageAccessAction::invalidateContents) + ->vkImageView(); } - else if (colorAttachmentIsOffscreen) + if (desc.interlockMode == gpu::InterlockMode::atomics) { - pipelineLayoutOptions |= - DrawPipelineLayoutOptions::coalescedResolveAndTransfer; + renderPassOptions |= + RenderPassOptionsVulkan::atomicCoalescedResolveAndTransfer; } + colorAttachmentIsOffscreen = true; } - const uint32_t renderPassKey = - RenderPass::Key(desc.interlockMode, - pipelineLayoutOptions, - renderTarget->framebufferFormat(), - desc.colorLoadAction); - std::unique_ptr& renderPass = m_renderPasses[renderPassKey]; - if (renderPass == nullptr) + if (desc.interlockMode == gpu::InterlockMode::clockwise || + desc.interlockMode == gpu::InterlockMode::atomics) { - renderPass = - std::make_unique(this, - desc.interlockMode, - pipelineLayoutOptions, - renderTarget->framebufferFormat(), - desc.colorLoadAction); - } - const DrawPipelineLayout& pipelineLayout = - *renderPass->drawPipelineLayout(); - - // Create the framebuffer. - StackVector framebufferViews; - assert(framebufferViews.size() == COLOR_PLANE_IDX); - framebufferViews.push_back(colorImageView); - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering) - { - assert(framebufferViews.size() == CLIP_PLANE_IDX); - framebufferViews.push_back(clipTexture->vkImageView()); - assert(framebufferViews.size() == SCRATCH_COLOR_PLANE_IDX); - framebufferViews.push_back(scratchColorTexture->vkImageView()); - assert(framebufferViews.size() == COVERAGE_PLANE_IDX); - framebufferViews.push_back(coverageTexture->vkImageView()); - } - else if (desc.interlockMode == gpu::InterlockMode::atomics) - { - assert(framebufferViews.size() == CLIP_PLANE_IDX); - framebufferViews.push_back(clipTexture->vkImageView()); - if (pipelineLayout.options() & - DrawPipelineLayoutOptions::coalescedResolveAndTransfer) - { - assert(framebufferViews.size() == COALESCED_ATOMIC_RESOLVE_IDX); - framebufferViews.push_back(renderTarget->accessTargetImageView( - commandBuffer, - { - .pipelineStages = - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .accessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }, - renderAreaIsFullTarget - ? vkutil::ImageAccessAction::invalidateContents - : vkutil::ImageAccessAction::preserveContents)); - } - } - - rcp framebuffer = m_vk->makeFramebuffer({ - .renderPass = *renderPass, - .attachmentCount = framebufferViews.size(), - .pAttachments = framebufferViews.data(), - .width = static_cast(renderTarget->width()), - .height = static_cast(renderTarget->height()), - .layers = 1, - }); + // Clear the PLS planes that are bound as storage textures. + const VkImage storageImageToClear = + (desc.interlockMode == gpu::InterlockMode::atomics) + ? m_plsAtomicCoverageTexture->vkImage() + : *plsTransientImageArray(); - VkRect2D renderArea = { - .offset = {desc.renderTargetUpdateBounds.left, - desc.renderTargetUpdateBounds.top}, - .extent = {static_cast(desc.renderTargetUpdateBounds.width()), - static_cast( - desc.renderTargetUpdateBounds.height())}, - }; - - VkClearValue clearValues[] = { - {.color = vkutil::color_clear_rgba32f(desc.colorClearValue)}, - {}, - {}, - {.color = vkutil::color_clear_r32ui(desc.coverageClearValue)}, - {.depthStencil = {desc.depthClearValue, desc.stencilClearValue}}, - }; - static_assert(COLOR_PLANE_IDX == 0); - static_assert(CLIP_PLANE_IDX == 1); - static_assert(SCRATCH_COLOR_PLANE_IDX == 2); - static_assert(COVERAGE_PLANE_IDX == 3); - static_assert(DEPTH_STENCIL_IDX == 4); - - if (desc.interlockMode == gpu::InterlockMode::atomics) - { - // Clear the coverage texture, which is not an attachment. - VkImageSubresourceRange clearRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .levelCount = 1, - .layerCount = 1, - }; + assert(plsBackingType == PLSBackingType::inputAttachment || + !m_platformFeatures.supportsRasterOrderingMode); - // Don't clear the coverage texture until shaders in the previous flush + // Don't clear the storageImageToClear until shaders in previous flushes // have finished using it. + // NOTE: This currently only works becauses we never support PLS as + // storage texture (i.e., clockwise) and rasterOrdering at the same + // time. If that changes, we will need to consider that the + // plsTransientImageArray may have been bound previously as input + // attachments. m_vk->imageMemoryBarrier( commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, @@ -3005,21 +2851,59 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .image = renderTarget->coverageAtomicTexture()->vkImage(), + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .image = storageImageToClear, }); - const VkClearColorValue coverageClearValue = - vkutil::color_clear_r32ui(desc.coverageClearValue); - m_vk->CmdClearColorImage( - commandBuffer, - renderTarget->coverageAtomicTexture()->vkImage(), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - &coverageClearValue, - 1, - &clearRange); + // Clear the entire storageImageToClear, even if we aren't going to use + // the whole thing. There is a future world where we may want to + // consider a "renderPassInitialize" draw to clear only the + // renderTargetUpdateBounds, but in most cases, a full clear will almost + // definitely be faster due to hardware optimizations. + if (desc.interlockMode == gpu::InterlockMode::atomics) + { + const VkClearColorValue coverageClearValue = + vkutil::color_clear_r32ui(desc.coverageClearValue); + + const VkImageSubresourceRange clearRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .levelCount = 1, + .layerCount = 1, + }; + + m_vk->CmdClearColorImage(commandBuffer, + m_plsAtomicCoverageTexture->vkImage(), + VK_IMAGE_LAYOUT_GENERAL, + &coverageClearValue, + 1, + &clearRange); + } + else + { + assert(desc.coverageClearValue == 0); + const VkClearColorValue zeroClearValue = {}; + + const VkImageSubresourceRange transientClearRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = + enums::is_flag_set(desc.combinedShaderFeatures, + gpu::ShaderFeatures::ENABLE_CLIPPING) + ? 2u // coverage and clip. + : 1u, // coverage only. + }; - // Don't use the coverage texture in shaders until the clear finishes. + m_vk->CmdClearColorImage(commandBuffer, + *plsTransientImageArray(), + VK_IMAGE_LAYOUT_GENERAL, + &zeroClearValue, + 1, + &transientClearRange); + } + + // Don't use the storageImageToClear in shaders until the clear + // finishes. m_vk->imageMemoryBarrier( commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, @@ -3029,12 +2913,43 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .image = renderTarget->coverageAtomicTexture()->vkImage(), + .image = storageImageToClear, }); } - else if (desc.interlockMode == gpu::InterlockMode::clockwiseAtomic) + else + { + // Any color writes in prior frames should already be complete before + // the following load operations. NOTE: This currently only works + // because we never support PLS as storage texture (i.e. clockwise) and + // rasterOrdering at the same time. If that changes, we will need to + // consider that the plsTransientImageArray may have been bound + // previously as storage textures. + assert(desc.interlockMode != gpu::InterlockMode::rasterOrdering || + !m_platformFeatures.supportsClockwiseMode); + } + + if ((desc.interlockMode == gpu::InterlockMode::clockwise || + desc.interlockMode == gpu::InterlockMode::clockwiseAtomic) && + !enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput)) + { + // Clockwise modes use an extra storage texture for a blendColor when + // advanced blend is active. Wait for any memory transactions on the + // blend texture before beginning. + plsBlendStorageTexture_RGB10_A2()->barrier( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .accessMask = + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + vkutil::ImageAccessAction::invalidateContents); + } + + if (desc.interlockMode == gpu::InterlockMode::clockwiseAtomic) { VkPipelineStageFlags lastCoverageBufferStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; @@ -3084,57 +2999,60 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) } } - // Ensure all reads to any internal attachments complete before we execute - // the load operations. - m_vk->memoryBarrier( - commandBuffer, - // "Load" operations always occur in - // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT. - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - 0, - { - .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - }); - - VkRenderPassBeginInfo renderPassBeginInfo = { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = *renderPass, - .framebuffer = *framebuffer, - .renderArea = renderArea, - .clearValueCount = std::size(clearValues), - .pClearValues = clearValues, - }; - - m_vk->CmdBeginRenderPass(commandBuffer, - &renderPassBeginInfo, - VK_SUBPASS_CONTENTS_INLINE); - - m_vk->CmdSetViewport( - commandBuffer, - 0, - 1, - vkutil::ViewportFromRect2D( - {.extent = {renderTarget->width(), renderTarget->height()}})); + // If requested, split the frame up into virtual tiles. As of now, each tile + // gets drawn in a separate render pass. The purpose of these virtual tiles, + // for now, is to break the frame up into smaller chunks so that Rive can be + // pre-empted by other rendering processes. + // + // This is not yet supported on MSAA. + int32_t virtualTileWidth = drawBounds.width(); + int32_t virtualTileHeight = drawBounds.height(); + if (desc.virtualTileWidth != 0 && desc.virtualTileHeight != 0 && + desc.interlockMode != gpu::InterlockMode::msaa) + { + virtualTileWidth = desc.virtualTileWidth; + virtualTileHeight = desc.virtualTileHeight; + } - m_vk->CmdSetScissor(commandBuffer, 0, 1, &renderArea); + auto scissorBox = IAABB::MakeWH(virtualTileWidth, virtualTileHeight) + .offset(drawBounds.left, drawBounds.top) + .intersect(drawBounds); + + // Begin the render pass before binding buffers or updating descriptor sets. + // It's valid Vulkan to do these tasks in any order, but Adreno 730, 740, + // and 840 appreciate it when we begin the render pass first. + DrawRenderPass drawRenderPass(this, + desc, + desc.colorLoadAction, + drawBounds, + colorImageView, + msaaColorSeedImageView, + msaaResolveImageView, + renderPassOptions, + scissorBox); // Update the PLS input attachment descriptor sets. VkDescriptorSet inputAttachmentDescriptorSet = VK_NULL_HANDLE; - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering || - desc.interlockMode == gpu::InterlockMode::atomics) + if (drawRenderPass.pipelineLayout().plsLayout() != VK_NULL_HANDLE) { - inputAttachmentDescriptorSet = descriptorSetPool->allocateDescriptorSet( - pipelineLayout.plsLayout()); + const VkDescriptorType plsDescriptorType = + (plsBackingType == + PipelineManagerVulkan::PLSBackingType::storageTexture) + ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + : VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; + inputAttachmentDescriptorSet = + descriptorSetAllocator.allocateDescriptorSet( + drawRenderPass.pipelineLayout().plsLayout()); - if (!desc.atomicFixedFunctionColorOutput) + if (!enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput)) { m_vk->updateImageDescriptorSets( inputAttachmentDescriptorSet, { .dstBinding = COLOR_PLANE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + .descriptorType = plsDescriptorType, }, {{ .imageView = colorImageView, @@ -3142,76 +3060,217 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) }}); } - m_vk->updateImageDescriptorSets( - inputAttachmentDescriptorSet, - { - .dstBinding = CLIP_PLANE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - }, - {{ - .imageView = clipTexture->vkImageView(), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }}); + if (desc.interlockMode != gpu::InterlockMode::msaa) + { + m_vk->updateImageDescriptorSets( + inputAttachmentDescriptorSet, + { + .dstBinding = CLIP_PLANE_IDX, + .descriptorType = plsDescriptorType, + }, + {{ + .imageView = + (desc.interlockMode == gpu::InterlockMode::atomics) + ? plsTransientScratchColorTexture()->vkImageView() + : (desc.interlockMode == + gpu::InterlockMode::clockwiseAtomic) + ? plsTransientClipTexture_R16F()->vkImageView() + : *plsTransientClipView(), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }}); + } - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering) + if (desc.interlockMode == gpu::InterlockMode::rasterOrdering || + ((desc.interlockMode == gpu::InterlockMode::clockwise || + desc.interlockMode == gpu::InterlockMode::clockwiseAtomic) && + !enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput))) { m_vk->updateImageDescriptorSets( inputAttachmentDescriptorSet, { .dstBinding = SCRATCH_COLOR_PLANE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + .descriptorType = (desc.interlockMode == + gpu::InterlockMode::clockwiseAtomic) + ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + : plsDescriptorType, }, {{ - .imageView = scratchColorTexture->vkImageView(), + .imageView = + (desc.interlockMode == gpu::InterlockMode::clockwise || + desc.interlockMode == + gpu::InterlockMode::clockwiseAtomic) + ? plsBlendStorageTexture_RGB10_A2()->vkImageView() + : plsTransientScratchColorTexture()->vkImageView(), .imageLayout = VK_IMAGE_LAYOUT_GENERAL, }}); } - assert(coverageTexture != nullptr); - m_vk->updateImageDescriptorSets( - inputAttachmentDescriptorSet, - { - .dstBinding = COVERAGE_PLANE_IDX, - .descriptorType = - desc.interlockMode == gpu::InterlockMode::atomics - ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE - : VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - }, - {{ - .imageView = coverageTexture->vkImageView(), - .imageLayout = VK_IMAGE_LAYOUT_GENERAL, - }}); + if (desc.interlockMode == gpu::InterlockMode::rasterOrdering || + desc.interlockMode == gpu::InterlockMode::atomics || + desc.interlockMode == gpu::InterlockMode::clockwise) + { + m_vk->updateImageDescriptorSets( + inputAttachmentDescriptorSet, + { + .dstBinding = COVERAGE_PLANE_IDX, + .descriptorType = + (desc.interlockMode == gpu::InterlockMode::atomics) + ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + : plsDescriptorType, + }, + {{ + .imageView = + (desc.interlockMode == gpu::InterlockMode::atomics) + ? m_plsAtomicCoverageTexture->vkImageView() + : *plsTransientCoverageView(), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }}); + } + + if (msaaColorSeedImageView != VK_NULL_HANDLE) + { + assert(desc.interlockMode == gpu::InterlockMode::msaa && + desc.colorLoadAction == + gpu::LoadAction::preserveRenderTarget); + m_vk->updateImageDescriptorSets( + inputAttachmentDescriptorSet, + { + .dstBinding = MSAA_COLOR_SEED_IDX, + .descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + }, + {{ + .imageView = msaaColorSeedImageView, + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }}); + } } // Bind the descriptor sets for this draw pass. // (The imageTexture and imageDraw dynamic uniform offsets might have to // update between draws, but this is otherwise all we need to bind!) VkDescriptorSet drawDescriptorSets[] = { - perFlushDescriptorSet, - m_nullImageDescriptorSet, - m_immutableSamplerDescriptorSet, + descriptorSetAllocator.perFlushDescriptorSet(), + m_pipelineManager->nullImageDescriptorSet(), inputAttachmentDescriptorSet, }; static_assert(PER_FLUSH_BINDINGS_SET == 0); static_assert(PER_DRAW_BINDINGS_SET == 1); - static_assert(IMMUTABLE_SAMPLER_BINDINGS_SET == 2); - static_assert(PLS_TEXTURE_BINDINGS_SET == 3); - static_assert(BINDINGS_SET_COUNT == 4); + static_assert(PLS_TEXTURE_BINDINGS_SET == 2); + static_assert(VULKAN_BINDINGS_SET_COUNT == 3); m_vk->CmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - *pipelineLayout, + *drawRenderPass.pipelineLayout(), PER_FLUSH_BINDINGS_SET, - drawDescriptorSets[PLS_TEXTURE_BINDINGS_SET] != + drawRenderPass.pipelineLayout().plsLayout() != VK_NULL_HANDLE - ? BINDINGS_SET_COUNT - : BINDINGS_SET_COUNT - 1, + ? VULKAN_BINDINGS_SET_COUNT + : VULKAN_BINDINGS_SET_COUNT - 1, drawDescriptorSets, 1, ZERO_OFFSET_32); - // Execute the DrawList. - uint32_t imageTextureUpdateCount = 0; + for (int32_t y = drawBounds.top; y < drawBounds.bottom; + y += virtualTileHeight) + { + for (int32_t x = drawBounds.left; x < drawBounds.right; + x += virtualTileWidth) + { + // Don't restart the render pass on the first tile. + if (x > drawBounds.left || y > drawBounds.top) + { + auto scissorBox = + IAABB::MakeWH(virtualTileWidth, virtualTileHeight) + .offset(x, y) + .intersect(drawBounds); + + drawRenderPass.restart( + (desc.colorLoadAction == gpu::LoadAction::dontCare) + ? gpu::LoadAction::dontCare + : gpu::LoadAction::preserveRenderTarget, + renderPassOptions, + scissorBox); + } + + submitDrawList(desc, + &descriptorSetAllocator, + &drawRenderPass, + pendingTessPatchCount); + } + } + + m_vk->CmdEndRenderPass(commandBuffer); + + // If the color attachment is offscreen and wasn't resolved already, copy + // it back to the main renderTarget. + if (colorAttachmentIsOffscreen && + enums::no_flags_set( + renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved | + RenderPassOptionsVulkan::atomicCoalescedResolveAndTransfer)) + { +#ifndef __APPLE__ + // In general, rasterOrdering flushes should not need this copy because + // they transfer from offscreen back to the rendreTarget as part of the + // draw pass (the one exception being interruptible render passes, which + // aren't currently compatible with manual resolves). + // NOTE: The manual resolve doesn't seem to work on MoltenVK, so don't + // do it on Apple. + assert(desc.interlockMode != gpu::InterlockMode::rasterOrdering || + desc.virtualTileWidth != 0 || desc.virtualTileHeight != 0 || + m_workarounds.needsInterruptibleRenderPasses()); +#endif + + // Atomic flushes don't need this copy either because we always use + // "atomicCoalescedResolveAndTransfer" when the color attachment is + // offscreen. + assert(desc.interlockMode != gpu::InterlockMode::atomics); + + // MSAA never needs this copy. It handles resolves differently. + assert(desc.interlockMode != gpu::InterlockMode::msaa); + + constexpr static vkutil::ImageAccess ACCESS_COPY_FROM = { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }; + + m_vk->blitSubRect( + commandBuffer, + ((plsBackingType == PLSBackingType::storageTexture) + ? accessPLSOffscreenColorTexture(commandBuffer, + ACCESS_COPY_FROM) + : renderTarget->accessOffscreenColorTexture(commandBuffer, + ACCESS_COPY_FROM)) + ->vkImage(), + ACCESS_COPY_FROM.layout, + renderTarget->accessTargetImage( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + vkutil::ImageAccessAction::invalidateContents), + VK_IMAGE_LAYOUT_GENERAL, + drawBounds); + } +} + +void RenderContextVulkanImpl::submitDrawList( + const FlushDescriptor& desc, + DescriptorSetAllocator* descriptorSetAllocator, + DrawRenderPass* drawRenderPass, + uint32_t pendingTessPatchCount) +{ + const auto commandBuffer = + reinterpret_cast(desc.externalCommandBuffer); + auto* const renderTarget = + static_cast(desc.renderTarget); + + // Submit the DrawList. for (const DrawBatch& batch : *desc.drawList) { assert(batch.elementCount > 0); @@ -3230,42 +3289,23 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) { // Update the image's "texture binding" descriptor set. (These // expire every frame, so we need to make a new one each frame.) - if (imageTextureUpdateCount >= - descriptor_pool_limits::kMaxImageTextureUpdates) - { - // We ran out of room for image texture updates. Allocate a - // new pool. - m_descriptorSetPoolPool->recycle( - std::move(descriptorSetPool)); - descriptorSetPool = m_descriptorSetPoolPool->acquire(); - imageTextureUpdateCount = 0; - } - - imageDescriptorSet = descriptorSetPool->allocateDescriptorSet( - m_perDrawDescriptorSetLayout); + imageDescriptorSet = + descriptorSetAllocator->allocatePerDrawDescriptorSet(); m_vk->updateImageDescriptorSets( imageDescriptorSet, { .dstBinding = IMAGE_TEXTURE_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorType = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, }, {{ + .sampler = m_pipelineManager->imageSampler( + batch.imageSampler.asKey()), .imageView = imageTexture->vkImageView(), .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, }}); - m_vk->updateImageDescriptorSets( - imageDescriptorSet, - { - .dstBinding = IMAGE_SAMPLER_IDX, - .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, - }, - {{ - .sampler = m_imageSamplers[batch.imageSampler.asKey()], - }}); - - ++imageTextureUpdateCount; imageTexture->updateCachedDescriptorSet( imageDescriptorSet, m_vk->currentFrameNumber(), @@ -3273,14 +3313,16 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) } VkDescriptorSet imageDescriptorSets[] = { - perFlushDescriptorSet, // Dynamic offset to imageDraw uniforms. - imageDescriptorSet, // imageTexture. + // Dynamic offset to imageDraw uniforms. + descriptorSetAllocator->perFlushDescriptorSet(), + // imageTexture. + imageDescriptorSet, }; static_assert(PER_DRAW_BINDINGS_SET == PER_FLUSH_BINDINGS_SET + 1); m_vk->CmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - *pipelineLayout, + *drawRenderPass->pipelineLayout(), PER_FLUSH_BINDINGS_SET, std::size(imageDescriptorSets), imageDescriptorSets, @@ -3295,66 +3337,50 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) : batch.shaderFeatures; auto shaderMiscFlags = batch.shaderMiscFlags; - if (desc.atomicFixedFunctionColorOutput) - { - shaderMiscFlags |= gpu::ShaderMiscFlags::fixedFunctionColorOutput; - } - if (desc.interlockMode == gpu::InterlockMode::rasterOrdering && - (batch.drawContents & gpu::DrawContents::clockwiseFill)) - { - shaderMiscFlags |= gpu::ShaderMiscFlags::clockwiseFill; - } - if ((pipelineLayout.options() & - DrawPipelineLayoutOptions::coalescedResolveAndTransfer) && - (drawType == gpu::DrawType::atomicResolve)) + if (enums::is_flag_set( + drawRenderPass->renderPassOptions(), + RenderPassOptionsVulkan::atomicCoalescedResolveAndTransfer) && + drawType == gpu::DrawType::renderPassResolve) { + assert(desc.interlockMode == gpu::InterlockMode::atomics); shaderMiscFlags |= gpu::ShaderMiscFlags::coalescedResolveAndTransfer; } - auto drawPipelineOptions = DrawPipelineOptions::none; + auto drawPipelineOptions = DrawPipelineVulkan::Options::none; if (desc.wireframe && m_vk->features.fillModeNonSolid) { - drawPipelineOptions |= DrawPipelineOptions::wireframe; + drawPipelineOptions |= DrawPipelineVulkan::Options::wireframe; } - std::unique_ptr& drawPipeline = - m_drawPipelines[DrawPipeline::Key(drawType, - shaderFeatures, - desc.interlockMode, - shaderMiscFlags, - drawPipelineOptions, - renderPassKey)]; - if (drawPipeline == nullptr) - { - drawPipeline = std::make_unique(this, - drawType, - pipelineLayout, - shaderFeatures, - shaderMiscFlags, - drawPipelineOptions, - *renderPass); - } - m_vk->CmdBindPipeline(commandBuffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - *drawPipeline); - - if (batch.barriers & BarrierFlags::plsAtomicPreResolve) + if (enums::any_flag_set(batch.barriers, + gpu::BarrierFlags::plsAtomicPreResolve | + gpu::BarrierFlags::msaaPostInit | + gpu::BarrierFlags::preManualResolve | + BarrierFlags::clockwiseBorrowedCoverage)) { - // The atomic resolve gets its barrier via vkCmdNextSubpass(). - assert(desc.interlockMode == gpu::InterlockMode::atomics); - assert(drawType == gpu::DrawType::atomicResolve); m_vk->CmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); } - else if (batch.barriers & - (BarrierFlags::plsAtomicPostInit | BarrierFlags::plsAtomic)) - { + + if (enums::any_flag_set(batch.barriers, + BarrierFlags::plsAtomic | + BarrierFlags::dstBlend)) + { + assert(desc.interlockMode == gpu::InterlockMode::atomics || + (desc.interlockMode == gpu::InterlockMode::clockwiseAtomic && + (!desc.fixedFunctionColorOutput || + enums::is_flag_set(batch.barriers, + BarrierFlags::plsAtomic))) || + (desc.interlockMode == gpu::InterlockMode::msaa && + (!desc.fixedFunctionColorOutput || + // The MSAA init also reads the framebuffer. + batch.drawType == gpu::DrawType::renderPassInitialize))); + assert(!enums::is_flag_set( + batch.shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)); + assert(drawType != gpu::DrawType::renderPassResolve); // Wait for color attachment writes to complete before we read the - // input attachments again. (We also checked for "plsAtomicPostInit" - // because this barrier has to occur after the Vulkan load - // operations as well.) - assert(desc.interlockMode == gpu::InterlockMode::atomics); - assert(drawType != gpu::DrawType::atomicResolve); + // input attachments again. m_vk->memoryBarrier( commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, @@ -3369,19 +3395,31 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, }); } - else if (batch.barriers & BarrierFlags::clockwiseBorrowedCoverage) + + const DrawPipelineVulkan* drawPipeline = + m_pipelineManager->tryGetPipeline( + { + .drawType = drawType, + .shaderFeatures = shaderFeatures, + .interlockMode = desc.interlockMode, + .shaderMiscFlags = shaderMiscFlags, + .drawContents = batch.drawContents, + .blendMode = batch.firstBlendMode, + .drawPipelineOptions = drawPipelineOptions, + .renderPassOptions = drawRenderPass->renderPassOptions(), + .renderTargetFormat = renderTarget->framebufferFormat(), + .colorLoadAction = desc.colorLoadAction, +#ifdef WITH_RIVE_TOOLS + .synthesizedFailureType = desc.synthesizedFailureType, +#endif + }, + m_platformFeatures); + + if (drawPipeline != nullptr) { - // Wait for prior fragment shaders to finish updating the coverage - // buffer before we read it again. - assert(desc.interlockMode == gpu::InterlockMode::clockwiseAtomic); - m_vk->memoryBarrier(commandBuffer, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_DEPENDENCY_BY_REGION_BIT, - { - .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, - }); + m_vk->CmdBindPipeline(commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + *drawPipeline); } switch (drawType) @@ -3389,6 +3427,13 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: + case DrawType::msaaOuterCubics: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: { // Draw patches that connect the tessellation vertices. m_vk->CmdBindVertexBuffers( @@ -3401,15 +3446,28 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) *m_pathPatchIndexBuffer, 0, VK_INDEX_TYPE_UINT16); - m_vk->CmdDrawIndexed(commandBuffer, - gpu::PatchIndexCount(drawType), - batch.elementCount, - gpu::PatchBaseIndex(drawType), - 0, - batch.baseElement); + for (auto [chunkPatchCount, chunkFirstPatch] : + InstanceChunker(batch.elementCount, + batch.baseElement, + m_workarounds.maxInstancesPerRenderPass)) + { + drawRenderPass->interruptIfNeeded(chunkPatchCount, + pendingTessPatchCount); + pendingTessPatchCount -= chunkPatchCount; + if (drawPipeline != nullptr) + { + m_vk->CmdDrawIndexed(commandBuffer, + gpu::PatchIndexCount(drawType), + chunkPatchCount, + gpu::PatchBaseIndex(drawType), + 0, + chunkFirstPatch); + } + } break; } + case DrawType::clipReset: case DrawType::interiorTriangulation: case DrawType::atlasBlit: { @@ -3419,11 +3477,14 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) 1, &buffer, ZERO_OFFSET); - m_vk->CmdDraw(commandBuffer, - batch.elementCount, - 1, - batch.baseElement, - 0); + if (drawPipeline != nullptr) + { + m_vk->CmdDraw(commandBuffer, + batch.elementCount, + 1, + batch.baseElement, + 0); + } break; } @@ -3440,12 +3501,15 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) *m_imageRectIndexBuffer, 0, VK_INDEX_TYPE_UINT16); - m_vk->CmdDrawIndexed(commandBuffer, - std::size(gpu::kImageRectIndices), - 1, - batch.baseElement, - 0, - 0); + if (drawPipeline != nullptr) + { + m_vk->CmdDrawIndexed(commandBuffer, + std::size(gpu::kImageRectIndices), + 1, + batch.baseElement, + 0, + 0); + } break; } @@ -3476,66 +3540,63 @@ void RenderContextVulkanImpl::flush(const FlushDescriptor& desc) *indexBuffer->currentBuffer(), 0, VK_INDEX_TYPE_UINT16); - m_vk->CmdDrawIndexed(commandBuffer, - batch.elementCount, - 1, - batch.baseElement, - 0, - 0); + if (drawPipeline != nullptr) + { + m_vk->CmdDrawIndexed(commandBuffer, + batch.elementCount, + 1, + batch.baseElement, + 0, + 0); + } break; } - case DrawType::atomicResolve: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: { - assert(desc.interlockMode == gpu::InterlockMode::atomics); - m_vk->CmdDraw(commandBuffer, 4, 1, 0, 0); + if (drawPipeline != nullptr) + { + if (desc.interlockMode == + gpu::InterlockMode::clockwiseAtomic) + { + // clockwiseAtomic's renderPassInitialize is just a + // workaround for Qualcomm, and only needs to touch one + // pixel. + // TODO: add scissor to DrawBatch. + VkRect2D scissorRect = + vkutil::rect2d(IAABB{0, 0, 1, 1}); + m_vk->CmdSetScissor(commandBuffer, 0, 1, &scissorRect); + } + + m_vk->CmdDraw(commandBuffer, 4, 1, 0, 0); + + if (desc.interlockMode == + gpu::InterlockMode::clockwiseAtomic) + { + // Restore the scissor. + // TODO: add scissor to DrawBatch. + VkRect2D scissorRect = + vkutil::rect2d(drawRenderPass->scissor()); + m_vk->CmdSetScissor(commandBuffer, 0, 1, &scissorRect); + } + } break; } - - case DrawType::atomicInitialize: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: - RIVE_UNREACHABLE(); } } - m_vk->CmdEndRenderPass(commandBuffer); - - if (colorAttachmentIsOffscreen && - !(pipelineLayout.options() & - DrawPipelineLayoutOptions::coalescedResolveAndTransfer)) + if (enums::is_flag_set(desc.unresolvedBarriers, + gpu::BarrierFlags::clockwiseBorrowedCoverage)) { - // Copy from the offscreen texture back to the target. - m_vk->blitSubRect( - commandBuffer, - renderTarget - ->accessOffscreenColorTexture( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, - .accessMask = VK_ACCESS_TRANSFER_READ_BIT, - .layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - }) - ->vkImage(), - renderTarget->accessTargetImage( - commandBuffer, - { - .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, - .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - }, - vkutil::ImageAccessAction::invalidateContents), - desc.renderTargetUpdateBounds); + // clockwiseAtomic render passes need to call vkCmdNextSubpass(), even + // if we didn't draw anything. Vulkan requires render passes to always + // reach the final subpass before calling vkCmdEndRenderPass(). + m_vk->CmdNextSubpass(commandBuffer, VK_SUBPASS_CONTENTS_INLINE); } - m_descriptorSetPoolPool->recycle(std::move(descriptorSetPool)); -} + assert(pendingTessPatchCount == 0); +} // namespace rive::gpu void RenderContextVulkanImpl::postFlush(const RenderContext::FlushResources&) { @@ -3554,14 +3615,49 @@ void RenderContextVulkanImpl::postFlush(const RenderContext::FlushResources&) void RenderContextVulkanImpl::hotloadShaders( rive::Span spirvData) { + m_pipelineManager->clearCache(); spirv::hotload_shaders(spirvData); // Delete and replace old shaders - m_colorRampPipeline = std::make_unique(this); - m_tessellatePipeline = std::make_unique(this); - m_atlasPipeline = std::make_unique(this); - m_drawShaders.clear(); - m_drawPipelines.clear(); + m_colorRampPipeline = + std::make_unique(m_pipelineManager.get(), + m_workarounds); + m_tessellatePipeline = + std::make_unique(m_pipelineManager.get(), + m_workarounds); + m_atlasPipeline = + std::make_unique(m_pipelineManager.get(), m_workarounds); +} + +void RenderContextVulkanImpl::startAsyncPipelineCreation( + InterlockMode interlockMode, + VkFormat renderTargetFormat, + VkImageUsageFlags renderTargetUsage, + LoadAction colorLoadAction) +{ + m_pipelineManager->queueUbershaderPipelineCreation(interlockMode, + renderTargetFormat, + renderTargetUsage, + colorLoadAction, + platformFeatures()); +} + +void RenderContextVulkanImpl::startAsyncPipelineCreation( + InterlockMode interlockMode, + RenderTargetVulkan& renderTarget, + LoadAction colorLoadAction) +{ + m_pipelineManager->queueUbershaderPipelineCreation( + interlockMode, + renderTarget.framebufferFormat(), + renderTarget.targetUsageFlags(), + colorLoadAction, + platformFeatures()); +} + +void RenderContextVulkanImpl::waitForAsyncPipelineCreation() +{ + m_pipelineManager->waitForAllBackgroundPipelineCreation(); } std::unique_ptr RenderContextVulkanImpl::MakeContext( @@ -3569,23 +3665,45 @@ std::unique_ptr RenderContextVulkanImpl::MakeContext( VkPhysicalDevice physicalDevice, VkDevice device, const VulkanFeatures& features, - PFN_vkGetInstanceProcAddr pfnvkGetInstanceProcAddr) + PFN_vkGetInstanceProcAddr pfnvkGetInstanceProcAddr, + const ContextOptions& contextOptions) { rcp vk = make_rcp(instance, physicalDevice, device, features, pfnvkGetInstanceProcAddr); - VkPhysicalDeviceProperties physicalDeviceProps; - vk->GetPhysicalDeviceProperties(vk->physicalDevice, &physicalDeviceProps); + + if (vk->physicalDeviceProperties().apiVersion < VK_API_VERSION_1_1) + { + fprintf( + stderr, + "ERROR: Rive Vulkan renderer requires a driver that supports at least Vulkan 1.1.\n"); + return nullptr; + } + + if (vk->physicalDeviceProperties().vendorID == VULKAN_VENDOR_IMG_TEC && + vk->physicalDeviceProperties().apiVersion < VK_API_VERSION_1_3) + { + fprintf( + stderr, + "ERROR: Rive Vulkan renderer requires a driver that supports at least Vulkan 1.3 on PowerVR chipsets.\n"); + return nullptr; + } + std::unique_ptr impl( - new RenderContextVulkanImpl(std::move(vk), physicalDeviceProps)); - if (!impl->platformFeatures().supportsRasterOrdering && - !impl->platformFeatures().supportsFragmentShaderAtomics) + new RenderContextVulkanImpl(std::move(vk), contextOptions)); + + if (contextOptions.forceAtomicMode && + !impl->platformFeatures().supportsAtomicMode) { - return nullptr; // TODO: implement MSAA. + fprintf( + stderr, + "ERROR: Requested \"atomic\" mode but Vulkan does not support fragmentStoresAndAtomics on this platform.\n"); + return nullptr; } - impl->initGPUObjects(); + + impl->initGPUObjects(contextOptions.shaderCompilationMode); return std::make_unique(std::move(impl)); } } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.cpp b/thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.cpp new file mode 100644 index 000000000..32f3ac99a --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.cpp @@ -0,0 +1,896 @@ +/* + * Copyright 2025 Rive + */ + +#include +#include +#include +#include +#include "rive/renderer/vulkan/render_context_vulkan_impl.hpp" +#include "rive/renderer/stack_vector.hpp" +#include "shaders/constants.glsl" +#include "common_layouts.hpp" +#include "draw_pipeline_layout_vulkan.hpp" +#include "pipeline_manager_vulkan.hpp" +#include "render_pass_vulkan.hpp" + +namespace rive::gpu +{ +constexpr static VkAttachmentLoadOp vk_color_load_op( + gpu::LoadAction loadAction, + gpu::InterlockMode interlockMode) +{ + switch (loadAction) + { + case gpu::LoadAction::preserveRenderTarget: + return (interlockMode == gpu::InterlockMode::msaa) + // In MSAA we need to implement the loadOp with a manual + // draw instead, since the MSAA attachment is transient + // and its color is seeded from the actual render target. + ? VK_ATTACHMENT_LOAD_OP_DONT_CARE + : VK_ATTACHMENT_LOAD_OP_LOAD; + case gpu::LoadAction::clear: + return VK_ATTACHMENT_LOAD_OP_CLEAR; + case gpu::LoadAction::dontCare: + return VK_ATTACHMENT_LOAD_OP_DONT_CARE; + } + RIVE_UNREACHABLE(); +} + +constexpr static VkFormat LAST_NON_SPARSE_VK_FORMAT = + VK_FORMAT_ASTC_12x12_SRGB_BLOCK; + +// The VkFormat values are very sparse after LAST_NON_SPARSE_VK_FORMAT. This +// table converts the sparse formats to a 0-based, tightly-packed index that can +// be used to build a key. +static uint32_t vk_sparse_format_index(VkFormat format) +{ + assert(format > LAST_NON_SPARSE_VK_FORMAT); + switch (format) + { + // Turn off clang-format so we can fit our case labels on one line. + // clang-format off + case VK_FORMAT_G8B8G8R8_422_UNORM: return 0; + case VK_FORMAT_B8G8R8G8_422_UNORM: return 1; + case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return 2; + case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return 3; + case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: return 4; + case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: return 5; + case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return 6; + case VK_FORMAT_R10X6_UNORM_PACK16: return 7; + case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: return 8; + case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: return 9; + case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: return 10; + case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: return 11; + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: return 12; + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: return 13; + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: return 14; + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: return 15; + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: return 16; + case VK_FORMAT_R12X4_UNORM_PACK16: return 17; + case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: return 18; + case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: return 19; + case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: return 20; + case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: return 21; + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: return 22; + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: return 23; + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: return 24; + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: return 25; + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return 26; + case VK_FORMAT_G16B16G16R16_422_UNORM: return 27; + case VK_FORMAT_B16G16R16G16_422_UNORM: return 28; + case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: return 29; + case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: return 30; + case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: return 31; + case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: return 32; + case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return 33; + case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM: return 34; + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16: return 35; + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16: return 36; + case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM: return 37; + case VK_FORMAT_A4R4G4B4_UNORM_PACK16: return 38; + case VK_FORMAT_A4B4G4R4_UNORM_PACK16: return 39; + case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK: return 40; + case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK: return 41; + case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK: return 42; + case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK: return 43; + case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK: return 44; + case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK: return 45; + case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK: return 46; + case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK: return 47; + case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK: return 48; + case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK: return 49; + case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK: return 50; + case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK: return 51; + case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK: return 52; + case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK: return 53; + case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: return 56; + case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: return 57; + case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: return 58; + case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: return 59; + case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: return 60; + case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: return 61; + case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return 62; + case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return 63; +#ifndef __APPLE__ + // Apple clang++ intentionally prioritizes '/usr/local/include' over any + // search paths provided via -I or -isystem. This means we get the + // locally installed MoltenVk headers instead of the Rive-official + // Vulkan headers when building for Apple. + // The following VkFormats are not defined in MoltenVK's headers. + case VK_FORMAT_A1B5G5R5_UNORM_PACK16: return 54; + case VK_FORMAT_A8_UNORM: return 55; + case VK_FORMAT_R8_BOOL_ARM: return 64; + case VK_FORMAT_R16G16_SFIXED5_NV: return 65; + case VK_FORMAT_R10X6_UINT_PACK16_ARM: return 66; + case VK_FORMAT_R10X6G10X6_UINT_2PACK16_ARM: return 67; + case VK_FORMAT_R10X6G10X6B10X6A10X6_UINT_4PACK16_ARM: return 68; + case VK_FORMAT_R12X4_UINT_PACK16_ARM: return 69; + case VK_FORMAT_R12X4G12X4_UINT_2PACK16_ARM: return 70; + case VK_FORMAT_R12X4G12X4B12X4A12X4_UINT_4PACK16_ARM: return 71; + case VK_FORMAT_R14X2_UINT_PACK16_ARM: return 72; + case VK_FORMAT_R14X2G14X2_UINT_2PACK16_ARM: return 73; + case VK_FORMAT_R14X2G14X2B14X2A14X2_UINT_4PACK16_ARM: return 74; + case VK_FORMAT_R14X2_UNORM_PACK16_ARM: return 75; + case VK_FORMAT_R14X2G14X2_UNORM_2PACK16_ARM: return 76; + case VK_FORMAT_R14X2G14X2B14X2A14X2_UNORM_4PACK16_ARM: return 77; + case VK_FORMAT_G14X2_B14X2R14X2_2PLANE_420_UNORM_3PACK16_ARM: return 78; + case VK_FORMAT_G14X2_B14X2R14X2_2PLANE_422_UNORM_3PACK16_ARM: return 79; +#endif + default: break; + // clang-format on + } + assert(false && "Given sparse VkFormat is not supported"); + return (1 << RenderPassVulkan::FORMAT_BIT_COUNT) - 1 - + (LAST_NON_SPARSE_VK_FORMAT + 1); +} + +static uint32_t vk_format_key(VkFormat format) +{ + if (format <= LAST_NON_SPARSE_VK_FORMAT) + { + // Basic case: Almost all normal formats already fit in 8 bits. + return static_cast(format); + } + else + { + // Pack the sparse VkFormats into a tighter key. + return vk_sparse_format_index(format) + LAST_NON_SPARSE_VK_FORMAT + 1; + } +} + +uint32_t RenderPassVulkan::KeyNoInterlockMode( + RenderPassOptionsVulkan renderPassOptions, + VkFormat renderTargetFormat, + gpu::LoadAction loadAction) +{ + // gpu::LoadAction. + assert(static_cast(loadAction) < 1 << LOAD_OP_BIT_COUNT); + uint32_t key = static_cast(loadAction); + + // VkFormat. + const uint32_t renderFormatKey = vk_format_key(renderTargetFormat); + assert(renderFormatKey < 1 << FORMAT_BIT_COUNT); + assert(key << FORMAT_BIT_COUNT >> FORMAT_BIT_COUNT == key); + key = (key << FORMAT_BIT_COUNT) | renderFormatKey; + + // DrawPipelineLayoutVulkan::Options. + assert(static_cast(renderPassOptions) < + 1 << RENDER_PASS_OPTION_COUNT); + assert(key << RENDER_PASS_OPTION_COUNT >> RENDER_PASS_OPTION_COUNT == key); + key = (key << RENDER_PASS_OPTION_COUNT) | + static_cast(renderPassOptions); + + assert(key < 1 << KEY_NO_INTERLOCK_MODE_BIT_COUNT); + return key; +} + +uint32_t RenderPassVulkan::Key(gpu::InterlockMode interlockMode, + RenderPassOptionsVulkan renderPassOptions, + VkFormat renderTargetFormat, + gpu::LoadAction loadAction) +{ + uint32_t key = + KeyNoInterlockMode(renderPassOptions, renderTargetFormat, loadAction); + + // gpu::InterlockMode. + assert(key << gpu::INTERLOCK_MODE_BIT_COUNT >> + gpu::INTERLOCK_MODE_BIT_COUNT == + key); + assert(static_cast(interlockMode) < + 1 << gpu::INTERLOCK_MODE_BIT_COUNT); + key = (key << gpu::INTERLOCK_MODE_BIT_COUNT) | + static_cast(interlockMode); + + assert(key < 1 << KEY_BIT_COUNT); + return key; +} + +RenderPassVulkan::RenderPassVulkan(PipelineManagerVulkan* pipelineManager, + gpu::InterlockMode interlockMode, + RenderPassOptionsVulkan renderPassOptions, + VkFormat renderTargetFormat, + gpu::LoadAction loadAction) : + m_vk(ref_rcp(pipelineManager->vulkanContext())) +{ + m_drawPipelineLayout = + &pipelineManager->getDrawPipelineLayoutSynchronous(interlockMode, + renderPassOptions); + + // COLOR attachment. + const VkImageLayout colorAttachmentLayout = + enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput) + ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + : VK_IMAGE_LAYOUT_GENERAL; + const VkSampleCountFlagBits msaaSampleCount = + (interlockMode == gpu::InterlockMode::msaa) ? VK_SAMPLE_COUNT_4_BIT + : VK_SAMPLE_COUNT_1_BIT; + StackVector + attachments; + StackVector colorAttachmentRefs; + std::optional depthStencilAttachmentRef; + std::optional resolveAttachmentRef; + if (pipelineManager->plsBackingType(interlockMode) == + PipelineManagerVulkan::PLSBackingType::inputAttachment || + enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput)) + { + assert(attachments.size() == COLOR_PLANE_IDX); + assert(colorAttachmentRefs.size() == COLOR_PLANE_IDX); + attachments.push_back({ + .format = renderTargetFormat, + .samples = msaaSampleCount, + .loadOp = vk_color_load_op(loadAction, interlockMode), + .storeOp = (enums::any_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved | + RenderPassOptionsVulkan:: + atomicCoalescedResolveAndTransfer) || + interlockMode == gpu::InterlockMode::msaa) + ? VK_ATTACHMENT_STORE_OP_DONT_CARE + : VK_ATTACHMENT_STORE_OP_STORE, + // This could be VK_IMAGE_LAYOUT_UNDEFINED more often, but it would + // invalidate the portion outside the renderArea when it isn't the + // full renderTarget, and currently we don't have separate render + // passes for "full renderTarget bounds" and "partial renderTarget + // bounds". Instead, we rely on + // vkutil::ImageAccessAction::invalidateContents to invalidate the + // color attachment when we can. + .initialLayout = + ((enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan:: + atomicCoalescedResolveAndTransfer) && + loadAction != gpu::LoadAction::preserveRenderTarget) || + interlockMode == gpu::InterlockMode::msaa) + ? VK_IMAGE_LAYOUT_UNDEFINED + : colorAttachmentLayout, + .finalLayout = colorAttachmentLayout, + }); + colorAttachmentRefs.push_back({ + .attachment = COLOR_PLANE_IDX, + .layout = colorAttachmentLayout, + }); + } + + if (interlockMode == gpu::InterlockMode::rasterOrdering || + interlockMode == gpu::InterlockMode::atomics || + interlockMode == gpu::InterlockMode::clockwiseAtomic) + { + // CLIP attachment. + assert(attachments.size() == CLIP_PLANE_IDX); + assert(colorAttachmentRefs.size() == CLIP_PLANE_IDX); + attachments.push_back({ + .format = + (interlockMode == gpu::InterlockMode::atomics) + // The clip buffer is encoded as RGBA8 in atomic mode so we + // can block writes by emitting alpha=0. + ? VK_FORMAT_R8G8B8A8_UNORM + : (interlockMode == gpu::InterlockMode::clockwiseAtomic) + ? VK_FORMAT_R16_SFLOAT + : VK_FORMAT_R32_UINT, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingResume) + ? VK_ATTACHMENT_LOAD_OP_LOAD + : VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingInterruptible) + ? VK_ATTACHMENT_STORE_OP_STORE + : VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingResume) + ? VK_IMAGE_LAYOUT_GENERAL + : VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_GENERAL, + }); + colorAttachmentRefs.push_back({ + .attachment = CLIP_PLANE_IDX, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }); + } + + if (interlockMode == gpu::InterlockMode::rasterOrdering) + { + // SCRATCH_COLOR attachment. + assert(attachments.size() == SCRATCH_COLOR_PLANE_IDX); + assert(colorAttachmentRefs.size() == SCRATCH_COLOR_PLANE_IDX); + attachments.push_back({ + .format = VK_FORMAT_R8G8B8A8_UNORM, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingResume) + ? VK_ATTACHMENT_LOAD_OP_LOAD + : VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingInterruptible) + ? VK_ATTACHMENT_STORE_OP_STORE + : VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingResume) + ? VK_IMAGE_LAYOUT_GENERAL + : VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_GENERAL, + }); + colorAttachmentRefs.push_back({ + .attachment = SCRATCH_COLOR_PLANE_IDX, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }); + + // COVERAGE attachment. + assert(attachments.size() == COVERAGE_PLANE_IDX); + assert(colorAttachmentRefs.size() == COVERAGE_PLANE_IDX); + attachments.push_back({ + .format = VK_FORMAT_R32_UINT, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingResume) + ? VK_ATTACHMENT_LOAD_OP_LOAD + : VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingInterruptible) + ? VK_ATTACHMENT_STORE_OP_STORE + : VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingResume) + ? VK_IMAGE_LAYOUT_GENERAL + : VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_GENERAL, + }); + colorAttachmentRefs.push_back({ + .attachment = COVERAGE_PLANE_IDX, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }); + + if (enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)) + { + // The renderTarget does not support + // VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, so we will instead use an + // offscreen color texture for the main subpass, and then transfer + // it into the renderTarget at the end of the render pass. + assert(attachments.size() == PLS_PLANE_COUNT); + attachments.push_back({ + .format = renderTargetFormat, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }); + resolveAttachmentRef = { + .attachment = PLS_PLANE_COUNT, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; + } + } + else if (interlockMode == gpu::InterlockMode::atomics) + { + if (enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::atomicCoalescedResolveAndTransfer)) + { + // COALESCED_ATOMIC_RESOLVE attachment (primary render target). + assert(attachments.size() == COALESCED_ATOMIC_RESOLVE_IDX); + attachments.push_back({ + .format = renderTargetFormat, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + // This could sometimes be VK_IMAGE_LAYOUT_UNDEFINED, but it + // would invalidate the portion outside the renderArea when it + // isn't the full renderTarget, and currently we don't have + // separate render passes for "full renderTarget bounds" and + // "partial renderTarget bounds". Instead, we rely on + // vkutil::ImageAccessAction::invalidateContents to invalidate + // the atomic resolve attachment when we can. + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }); + + // The resolve subpass only renders to the resolve texture. + // And the "coalesced" resolve shader outputs to color + // attachment 0, so alias the COALESCED_ATOMIC_RESOLVE + // attachment on output 0 for this subpass. + assert(!resolveAttachmentRef.has_value()); + resolveAttachmentRef = { + .attachment = COALESCED_ATOMIC_RESOLVE_IDX, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; + } + else + { + // When not in "coalesced" mode, the resolve texture is the + // same as the COLOR texture. + static_assert(COLOR_PLANE_IDX == 0); + assert(!resolveAttachmentRef.has_value()); + resolveAttachmentRef = colorAttachmentRefs[0]; + } + } + else if (interlockMode == gpu::InterlockMode::msaa) + { + // DEPTH attachment. + assert(attachments.size() == MSAA_DEPTH_STENCIL_IDX); + attachments.push_back({ + .format = vkutil::get_preferred_depth_stencil_format( + m_vk->supportsD24S8()), + .samples = msaaSampleCount, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }); + depthStencilAttachmentRef = { + .attachment = MSAA_DEPTH_STENCIL_IDX, + .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }; + + // MSAA_RESOLVE attachment. + const bool readsMSAAResolveAttachment = + loadAction == gpu::LoadAction::preserveRenderTarget && + !enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture); + const VkImageLayout msaaResolveLayout = + readsMSAAResolveAttachment + ? VK_IMAGE_LAYOUT_GENERAL + : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + assert(attachments.size() == MSAA_RESOLVE_IDX); + attachments.push_back({ + .format = renderTargetFormat, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = readsMSAAResolveAttachment + ? VK_ATTACHMENT_LOAD_OP_LOAD + : VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = + (readsMSAAResolveAttachment || + enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)) + ? msaaResolveLayout + // NOTE: This can only be VK_IMAGE_LAYOUT_UNDEFINED because + // Vulkan does not support partial resolves to MSAA resolve + // attachments. So every MSAA render pass without + // "manuallyResolved" covers the entire render area. + : VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = msaaResolveLayout, + }); + resolveAttachmentRef = { + .attachment = MSAA_RESOLVE_IDX, + .layout = msaaResolveLayout, + }; + assert(colorAttachmentRefs.size() == 1); + + if (enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture)) + { + // MSAA_SEED attachment. + assert(loadAction == gpu::LoadAction::preserveRenderTarget); + assert(attachments.size() == MSAA_COLOR_SEED_IDX); + attachments.push_back({ + .format = renderTargetFormat, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_GENERAL, + .finalLayout = VK_IMAGE_LAYOUT_GENERAL, + }); + } + } + + // Input attachments. + StackVector inputAttachmentRefs; + StackVector msaaColorSeedInputAttachmentRef; + inputAttachmentRefs.push_back_n(colorAttachmentRefs.size(), + colorAttachmentRefs.data()); + if (enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput)) + { + // COLOR is not an input attachment if we're using fixed function + // blending. + if (inputAttachmentRefs.size() > 1) + { + inputAttachmentRefs[0] = {.attachment = VK_ATTACHMENT_UNUSED}; + } + else + { + inputAttachmentRefs.clear(); + } + } + if (interlockMode == gpu::InterlockMode::msaa && + loadAction == gpu::LoadAction::preserveRenderTarget) + { + msaaColorSeedInputAttachmentRef.push_back({ + .attachment = + enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture) + ? MSAA_COLOR_SEED_IDX + : MSAA_RESOLVE_IDX, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }); + } + + const bool rasterOrderedAttachmentAccess = + interlockMode == gpu::InterlockMode::rasterOrdering && + m_vk->features.rasterizationOrderColorAttachmentAccess; + + constexpr uint32_t MAX_SUBPASSES = 3; + StackVector subpassDescs; + + constexpr uint32_t MAX_SUBPASS_DEPS = 9; + StackVector subpassDeps; + + // The standard initial external input dependency, to ensure that all + // previous writes to subpass 0's color attachment are completed before this + // render pass starts. + static constexpr VkSubpassDependency EXTERNAL_COLOR_INPUT_DEPENDENCY = { + .srcSubpass = VK_SUBPASS_EXTERNAL, + .dstSubpass = 0, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = VK_ACCESS_NONE, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + .dependencyFlags = 0, + }; + + // Helper to add a typical dependency between the current subpass and the + // next one, which blocks between the color attachment being written in the + // current pass and fragment shader reads from the next. + auto addStandardColorDependencyToNextSubpass = + [&](uint32_t dstSubpassIndex) { + subpassDeps.push_back({ + .srcSubpass = dstSubpassIndex - 1, + .dstSubpass = dstSubpassIndex, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, + }); + }; + + // MSAA color-load subpass. + if (interlockMode == gpu::InterlockMode::msaa && + loadAction == gpu::LoadAction::preserveRenderTarget) + { + assert(msaaColorSeedInputAttachmentRef.size() == + colorAttachmentRefs.size()); + assert(subpassDescs.size() == 0); + + // The color-load subpass takes the seed texture (which may be the same + // as the resolve texture) and writes it out. + subpassDescs.push_back({ + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = msaaColorSeedInputAttachmentRef.size(), + .pInputAttachments = msaaColorSeedInputAttachmentRef.data(), + .colorAttachmentCount = colorAttachmentRefs.size(), + .pColorAttachments = colorAttachmentRefs.data(), + }); + + // The color-load subpass has a self dependency because it reads the + // result of seed attachment's loadOp when it draws it into the MSAA + // attachment. (loadOps always occur in + // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT.) + // NOTE: This subpass, per the vulkan synchronization validation, + // should not be necessary, as the external input subpass dependency + // should handle it, but in practice without this extra barrier + // everything fails to render properly on Adreno devices. + subpassDeps.push_back({ + .srcSubpass = 0, + .dstSubpass = 0, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, + }); + + // This subpass needs an external dependency on the color stages to + // ensure that all of the color rendering from before this renderpass + // completes. + subpassDeps.push_back(EXTERNAL_COLOR_INPUT_DEPENDENCY); + + if (enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::msaaSeedFromOffscreenTexture)) + { + // If we're seeding from offscreen texture, this pass needs an + // external output dependency to ensure that any future writes + // finish after we're done with it. + subpassDeps.push_back({ + .srcSubpass = 0, + .dstSubpass = VK_SUBPASS_EXTERNAL, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_NONE, + .dependencyFlags = 0, + }); + } + + // The next subpass (the main subpass) needs an external dependency on + // the depth buffer (which is not used in this subpass but is used in + // that one). + VkSubpassDependency externalInputDeps = { + .srcSubpass = VK_SUBPASS_EXTERNAL, + .dstSubpass = 1, + .srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + .dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = VK_ACCESS_NONE, + .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dependencyFlags = 0, + }; + + if (!enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)) + { + // If we are not doing the manual MSAA resolve, this pass also needs + // barriers to protect the layout transition of the resolve target + // from the load op (even though it's LOAD_OP_DONT_CARE, it is + // possible that it performs a write), so we also need to specify + // COLOR_ATTACHMENT_WRITE as a destination access flag. + // (If we *were* doing the manual resolve the transition and load + // would happen in that subpass instead of this one) + externalInputDeps.dstStageMask |= + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + externalInputDeps.dstAccessMask |= + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } + + subpassDeps.push_back(externalInputDeps); + + // Finally, the standard color dependency from subpass 0 -> subpass 1 + addStandardColorDependencyToNextSubpass(subpassDescs.size()); + } + else + { + // Without the extra color-load subpass we need an external dependency + // into the main subpass + auto externalInDep = EXTERNAL_COLOR_INPUT_DEPENDENCY; + if (interlockMode == gpu::InterlockMode::msaa) + { + // for msaa where the main subpass is first, the external dependency + // additionally needs to cover depth/stencil. + externalInDep.srcStageMask |= + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + externalInDep.dstStageMask |= + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + externalInDep.dstAccessMask |= + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + subpassDeps.push_back(externalInDep); + } + + if (interlockMode == gpu::InterlockMode::clockwiseAtomic) + { + // Borrowed coverage subpass. (This only writes to the coverage buffer, + // not color attachments.) + subpassDescs.push_back({ + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + // Even though we don't write to attachments in the borrowed + // coverage subpass, we need to include them because it's subpass 0 + // and they get loaded/cleared. + .colorAttachmentCount = colorAttachmentRefs.size(), + .pColorAttachments = colorAttachmentRefs.data(), + }); + + // Add an input attachment dependency between borrowed coverage and the + // main subpass because the clear of clip and color occur in subpass 0. + // + // Furthermore, *don't* add SHADER_READ/SHADER_WRITE dependencies, even + // though that's what we're doing with the coverage buffer. Since the + // coverage buffer is atomic and we only access pixel-local locations in + // it, all we need is the pipeline stage barrier plus + // VK_DEPENDENCY_BY_REGION_BIT. SHADER_READ/SHADER_WRITE have + // catastrophic effects on performance for tilers since they cause a + // flush. + addStandardColorDependencyToNextSubpass(subpassDescs.size()); + } + + // Main subpass. + const uint32_t mainSubpassIdx = subpassDescs.size(); + assert(colorAttachmentRefs.size() == + m_drawPipelineLayout->colorAttachmentCount(mainSubpassIdx, + renderPassOptions)); + subpassDescs.push_back({ + .flags = + rasterOrderedAttachmentAccess + ? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT + : 0u, + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = inputAttachmentRefs.size(), + .pInputAttachments = inputAttachmentRefs.data(), + .colorAttachmentCount = colorAttachmentRefs.size(), + .pColorAttachments = colorAttachmentRefs.data(), + .pResolveAttachments = + (interlockMode == gpu::InterlockMode::msaa && + !enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)) + ? &resolveAttachmentRef.value() + : nullptr, + .pDepthStencilAttachment = depthStencilAttachmentRef.has_value() + ? &depthStencilAttachmentRef.value() + : nullptr, + }); + + // Add any main subpass self-dependencies if needed + if ((interlockMode == gpu::InterlockMode::rasterOrdering && + !rasterOrderedAttachmentAccess) || + interlockMode == gpu::InterlockMode::atomics || + interlockMode == gpu::InterlockMode::clockwiseAtomic || + (interlockMode == gpu::InterlockMode::msaa && + !enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput))) + { + // Any subpass that reads the framebuffer or PLS planes has a self + // dependency. + // + // In implicit rasterOrdering mode (meaning + // EXT_rasterization_order_attachment_access is not present, but + // we're on ARM hardware and know the hardware is raster ordered + // anyway), we also need to declare this dependency even though + // we won't be issuing any barriers. + subpassDeps.push_back({ + .srcSubpass = mainSubpassIdx, + .dstSubpass = mainSubpassIdx, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + // TODO: We should add SHADER_READ/SHADER_WRITE flags for the + // coverage buffer as well, but ironically, adding those seems to + // cause artifacts on Qualcomm. Leave them out for now until we can + // investigate further. + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + .dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT, + }); + } + + if (interlockMode == gpu::InterlockMode::msaa) + { + // Main subpass needs a separate external dependency for depth/stencil + subpassDeps.push_back({ + .srcSubpass = subpassDescs.size() - 1, + .dstSubpass = VK_SUBPASS_EXTERNAL, + .srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_NONE, + .dependencyFlags = 0, + }); + } + + // PLS-resolve subpass (atomic mode only). + if (interlockMode == gpu::InterlockMode::atomics) + { + // Add the dependency from main subpass to the resolve subpass. + addStandardColorDependencyToNextSubpass(subpassDescs.size()); + + // The resolve happens in a separate subpass. + assert(subpassDescs.size() == 1); + assert( + m_drawPipelineLayout->colorAttachmentCount(1, renderPassOptions) == + 1); + assert(resolveAttachmentRef.has_value()); + subpassDescs.push_back({ + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = inputAttachmentRefs.size(), + .pInputAttachments = inputAttachmentRefs.data(), + .colorAttachmentCount = 1, + .pColorAttachments = &resolveAttachmentRef.value(), + }); + } + else if (enums::is_flag_set(renderPassOptions, + RenderPassOptionsVulkan::manuallyResolved)) + { + assert(!enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::fixedFunctionColorOutput)); + // Manually resolved render passes aren't currently compatible with + // interruptions. + assert(!enums::is_flag_set( + renderPassOptions, + RenderPassOptionsVulkan::rasterOrderingInterruptible)); + assert(inputAttachmentRefs[0].attachment == COLOR_PLANE_IDX); + + addStandardColorDependencyToNextSubpass(subpassDescs.size()); + + subpassDescs.push_back({ + .flags = + rasterOrderedAttachmentAccess + ? VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT + : 0u, + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = 1u, + .pInputAttachments = inputAttachmentRefs.data(), + .colorAttachmentCount = 1u, + .pColorAttachments = &resolveAttachmentRef.value(), + }); + } + + // There always needs to be a final external output dependency for the final + // rendering target. + subpassDeps.push_back({ + .srcSubpass = subpassDescs.size() - 1, + .dstSubpass = VK_SUBPASS_EXTERNAL, + .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_TRANSFER_BIT, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_NONE, + .dependencyFlags = 0, + }); + + VkRenderPassCreateInfo renderPassCreateInfo = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = attachments.size(), + .pAttachments = attachments.data(), + .subpassCount = subpassDescs.size(), + .pSubpasses = subpassDescs.data(), + .dependencyCount = subpassDeps.size(), + .pDependencies = subpassDeps.data(), + }; + + VK_CHECK(m_vk->CreateRenderPass(m_vk->device, + &renderPassCreateInfo, + nullptr, + &m_renderPass)); + + const std::string renderPipelineLabel = + (std::ostringstream() + << "RIVE_Draw{interlockMode=" << int(interlockMode) + << ", renderPassOptions=" << int(renderPassOptions) + << ", renderTargetFormat=" << int(renderTargetFormat) + << ", loadAction=" << int(loadAction) << '}') + .str(); + m_vk->setDebugNameIfEnabled(uint64_t(m_renderPass), + VK_OBJECT_TYPE_RENDER_PASS, + renderPipelineLabel.c_str()); +} + +RenderPassVulkan::~RenderPassVulkan() +{ + // Don't touch m_drawPipelineLayout in the destructor since destruction + // order of us vs. impl->m_drawPipelineLayouts is uncertain. + m_vk->DestroyRenderPass(m_vk->device, m_renderPass, VK_NULL_HANDLE); +} +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.hpp b/thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.hpp new file mode 100644 index 000000000..ef2c220a4 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/render_pass_vulkan.hpp @@ -0,0 +1,106 @@ +/* + * Copyright 2025 Rive + */ + +#pragma once + +#include +#include "rive/renderer/vulkan/vulkan_context.hpp" +#include "rive/renderer/gpu.hpp" + +namespace rive::gpu +{ +class DrawPipelineLayoutVulkan; +class PipelineManagerVulkan; + +// Rive-specific options for configuring a render pass. +enum class RenderPassOptionsVulkan +{ + none = 0, + + // No need to attach the COLOR texture as an input attachment. There are + // no advanced blend modes so we can use built-in hardware blending. + fixedFunctionColorOutput = 1 << 0, + + // rasterOrdering or msaa only: The render pass has a fullscreen draw at + // the end that resolves rendering data into the renderTarget. (e.g., by + // transferring color from offscreen or manually averaging MSAA.) + manuallyResolved = 1 << 1, + + // rasterOrdering mode only: Store all transient attachments to memory + // so the render pass can be interrupted and restarted. + rasterOrderingInterruptible = 1 << 2, + + // rasterOrdering mode only: This render pass is resuming after an + // interrupt; load all transient attachments from memory. + rasterOrderingResume = 1 << 3, + + // Atomic mode only: Use an offscreen texture to render color, but also + // attach the real target texture at the COALESCED_ATOMIC_RESOLVE index, + // and render to it directly in the atomic resolve step. + atomicCoalescedResolveAndTransfer = 1 << 4, + + // MSAA only, while using LoadAction::preserveRenderTarget: We have to + // initialize the (transient) MSAA color attachment from an offscreen + // texture bound as an input attachment, because the final render target + // itself can't be bound as an input attachment. + msaaSeedFromOffscreenTexture = 1 << 5, +}; + +constexpr static int RENDER_PASS_OPTION_COUNT = 6; + +// This masks out RenderPassOptions that don't affect layout, allowing different +// render passes to reference the same VkPipelineLayout where possible. +// e.g., RenderPassOptions that deal with interrupting a render pass don't +// affect layout. +constexpr static RenderPassOptionsVulkan RENDER_PASS_OPTIONS_LAYOUT_MASK = + ~(RenderPassOptionsVulkan::rasterOrderingInterruptible | + RenderPassOptionsVulkan::rasterOrderingResume); + +class RenderPassVulkan +{ +public: + constexpr static uint64_t FORMAT_BIT_COUNT = 9; + constexpr static uint64_t LOAD_OP_BIT_COUNT = 2; + constexpr static uint64_t KEY_NO_INTERLOCK_MODE_BIT_COUNT = + FORMAT_BIT_COUNT + RENDER_PASS_OPTION_COUNT + LOAD_OP_BIT_COUNT; + constexpr static uint64_t KEY_BIT_COUNT = + KEY_NO_INTERLOCK_MODE_BIT_COUNT + gpu::INTERLOCK_MODE_BIT_COUNT; + static_assert(KEY_BIT_COUNT <= 32); + + // Shader unique keys also include the interlock mode, so we don't always + // need it in the render pass key. + static uint32_t KeyNoInterlockMode(RenderPassOptionsVulkan, + VkFormat renderTargetFormat, + gpu::LoadAction); + + static uint32_t Key(gpu::InterlockMode, + RenderPassOptionsVulkan, + VkFormat renderTargetFormat, + gpu::LoadAction); + + RenderPassVulkan(PipelineManagerVulkan*, + gpu::InterlockMode, + RenderPassOptionsVulkan, + VkFormat renderTargetFormat, + gpu::LoadAction); + ~RenderPassVulkan(); + + RenderPassVulkan(const RenderPassVulkan&) = delete; + RenderPassVulkan& operator=(const RenderPassVulkan&) = delete; + + const DrawPipelineLayoutVulkan* drawPipelineLayout() const + { + return m_drawPipelineLayout; + } + + operator VkRenderPass() const { return m_renderPass; } + +private: + const rcp m_vk; + // Raw pointer into impl->m_drawPipelineLayouts. RenderContextVulkanImpl + // ensures the pipline layouts outlive this RenderPass instance. + const DrawPipelineLayoutVulkan* m_drawPipelineLayout = nullptr; + VkRenderPass m_renderPass = VK_NULL_HANDLE; +}; +} // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/render_target_vulkan.cpp b/thirdparty/rive_renderer/source/vulkan/render_target_vulkan.cpp index 088cdb9f4..a095d0850 100644 --- a/thirdparty/rive_renderer/source/vulkan/render_target_vulkan.cpp +++ b/thirdparty/rive_renderer/source/vulkan/render_target_vulkan.cpp @@ -50,6 +50,26 @@ VkImageView RenderTargetVulkanImpl::accessTargetImageView( return m_targetImageView; } +VkImageView RenderTargetVulkan::clearTargetImageView( + VkCommandBuffer commandBuffer, + ColorInt clearColor, + const vkutil::ImageAccess& dstAccessAfterClear) +{ + m_vk->clearColorImage( + commandBuffer, + clearColor, + accessTargetImage(commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + vkutil::ImageAccessAction::invalidateContents), + VK_IMAGE_LAYOUT_GENERAL); + + return accessTargetImageView(commandBuffer, dstAccessAfterClear); +} + vkutil::Texture2D* RenderTargetVulkan::accessOffscreenColorTexture( VkCommandBuffer commandBuffer, const vkutil::ImageAccess& dstAccess, @@ -57,14 +77,16 @@ vkutil::Texture2D* RenderTargetVulkan::accessOffscreenColorTexture( { if (m_offscreenColorTexture == nullptr) { - m_offscreenColorTexture = m_vk->makeTexture2D({ - .format = m_framebufferFormat, - .extent = {width(), height()}, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSFER_SRC_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT, - }); + m_offscreenColorTexture = m_vk->makeTexture2D( + { + .format = m_framebufferFormat, + .extent = {width(), height()}, + .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + }, + "offscreen color texture"); } m_offscreenColorTexture->barrier(commandBuffer, @@ -74,93 +96,69 @@ vkutil::Texture2D* RenderTargetVulkan::accessOffscreenColorTexture( return m_offscreenColorTexture.get(); } -vkutil::Texture2D* RenderTargetVulkan::clipTextureR32UI() -{ - if (m_clipTextureR32UI == nullptr) - { - m_clipTextureR32UI = m_vk->makeTexture2D({ - .format = VK_FORMAT_R32_UINT, - .extent = {width(), height()}, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - }); - } - return m_clipTextureR32UI.get(); -} - -vkutil::Texture2D* RenderTargetVulkan::scratchColorTexture() -{ - if (m_scratchColorTexture == nullptr) - { - m_scratchColorTexture = m_vk->makeTexture2D({ - .format = m_framebufferFormat, - .extent = {width(), height()}, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - }); - } - return m_scratchColorTexture.get(); -} - -vkutil::Texture2D* RenderTargetVulkan::coverageTexture() +vkutil::Texture2D* RenderTargetVulkan::copyTargetImageToOffscreenColorTexture( + VkCommandBuffer commandBuffer, + const vkutil::ImageAccess& dstAccessAfterCopy, + const IAABB& copyBounds) { - if (m_coverageTexture == nullptr) - { - m_coverageTexture = m_vk->makeTexture2D({ - .format = VK_FORMAT_R32_UINT, - .extent = {width(), height()}, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - }); - } - return m_coverageTexture.get(); -} + m_vk->blitSubRect( + commandBuffer, + accessTargetImage(commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_READ_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }), + VK_IMAGE_LAYOUT_GENERAL, + accessOffscreenColorTexture( + commandBuffer, + { + .pipelineStages = VK_PIPELINE_STAGE_TRANSFER_BIT, + .accessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .layout = VK_IMAGE_LAYOUT_GENERAL, + }, + vkutil::ImageAccessAction::invalidateContents) + ->vkImage(), + VK_IMAGE_LAYOUT_GENERAL, + copyBounds); -vkutil::Texture2D* RenderTargetVulkan::clipTextureRGBA8() -{ - if (m_clipTextureRGBA8 == nullptr) - { - m_clipTextureRGBA8 = m_vk->makeTexture2D({ - .format = VK_FORMAT_R8G8B8A8_UNORM, - .extent = {width(), height()}, - .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - }); - } - return m_clipTextureRGBA8.get(); + return accessOffscreenColorTexture(commandBuffer, dstAccessAfterCopy); } -vkutil::Texture2D* RenderTargetVulkan::coverageAtomicTexture() +vkutil::Texture2D* RenderTargetVulkan::msaaColorTexture() { - if (m_coverageAtomicTexture == nullptr) + if (m_msaaColorTexture == nullptr) { - m_coverageAtomicTexture = m_vk->makeTexture2D({ - .format = VK_FORMAT_R32_UINT, - .extent = {width(), height()}, - .usage = - VK_IMAGE_USAGE_STORAGE_BIT | - VK_IMAGE_USAGE_TRANSFER_DST_BIT, // For vkCmdClearColorImage - }); + m_msaaColorTexture = m_vk->makeTexture2D( + { + .format = m_framebufferFormat, + .extent = {width(), height(), 1}, + .samples = VK_SAMPLE_COUNT_4_BIT, + .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + }, + "MSAA Color Texture"); } - return m_coverageAtomicTexture.get(); + return m_msaaColorTexture.get(); } -vkutil::Texture2D* RenderTargetVulkan::depthStencilTexture() +vkutil::Texture2D* RenderTargetVulkan::msaaDepthStencilTexture() { - if (m_depthStencilTexture == nullptr) + if (m_msaaDepthStencilTexture == nullptr) { - m_depthStencilTexture = m_vk->makeTexture2D({ - .format = vkutil::get_preferred_depth_stencil_format( - m_vk->supportsD24S8()), - .extent = {width(), height()}, - .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - }); + m_msaaDepthStencilTexture = m_vk->makeTexture2D( + { + .format = vkutil::get_preferred_depth_stencil_format( + m_vk->supportsD24S8()), + .extent = {width(), height(), 1}, + .samples = VK_SAMPLE_COUNT_4_BIT, + .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + }, + "MSAA Depth/Stencil Texture"); } - return m_depthStencilTexture.get(); + return m_msaaDepthStencilTexture.get(); } rcp RenderContextVulkanImpl::makeRenderTarget( diff --git a/thirdparty/rive_renderer/source/vulkan/vkutil.cpp b/thirdparty/rive_renderer/source/vulkan/vkutil.cpp index ffc826991..b88ab7087 100644 --- a/thirdparty/rive_renderer/source/vulkan/vkutil.cpp +++ b/thirdparty/rive_renderer/source/vulkan/vkutil.cpp @@ -10,6 +10,42 @@ namespace rive::gpu::vkutil { +#define STR_CASE(result) \ + case VK_##result: \ + return #result + +const char* string_from_vk_result(VkResult result) +{ + switch (result) + { + STR_CASE(SUCCESS); + STR_CASE(NOT_READY); + STR_CASE(TIMEOUT); + STR_CASE(EVENT_SET); + STR_CASE(EVENT_RESET); + STR_CASE(INCOMPLETE); + STR_CASE(ERROR_OUT_OF_HOST_MEMORY); + STR_CASE(ERROR_OUT_OF_DEVICE_MEMORY); + STR_CASE(ERROR_INITIALIZATION_FAILED); + STR_CASE(ERROR_DEVICE_LOST); + STR_CASE(ERROR_MEMORY_MAP_FAILED); + STR_CASE(ERROR_LAYER_NOT_PRESENT); + STR_CASE(ERROR_EXTENSION_NOT_PRESENT); + STR_CASE(ERROR_FEATURE_NOT_PRESENT); + STR_CASE(ERROR_INCOMPATIBLE_DRIVER); + STR_CASE(ERROR_TOO_MANY_OBJECTS); + STR_CASE(ERROR_FORMAT_NOT_SUPPORTED); + STR_CASE(ERROR_SURFACE_LOST_KHR); + STR_CASE(SUBOPTIMAL_KHR); + STR_CASE(ERROR_OUT_OF_DATE_KHR); + STR_CASE(ERROR_INCOMPATIBLE_DISPLAY_KHR); + STR_CASE(ERROR_NATIVE_WINDOW_IN_USE_KHR); + STR_CASE(ERROR_VALIDATION_FAILED_EXT); + STR_CASE(ERROR_OUT_OF_POOL_MEMORY); + default: + return ""; + } +} Resource::Resource(rcp vk) : GPUResource(std::move(vk)) {} VulkanContext* Resource::vk() const @@ -159,7 +195,9 @@ rcp BufferPool::acquire() return buffer; } -Image::Image(rcp vulkanContext, const VkImageCreateInfo& info) : +Image::Image(rcp vulkanContext, + const VkImageCreateInfo& info, + const char* name) : Resource(std::move(vulkanContext)), m_info(info) { m_info = info; @@ -200,6 +238,9 @@ Image::Image(rcp vulkanContext, const VkImageCreateInfo& info) : &m_vmaAllocation, nullptr) == VK_SUCCESS) { + vk()->setDebugNameIfEnabled(uint64_t(m_vkImage), + VK_OBJECT_TYPE_IMAGE, + name); return; } } @@ -214,6 +255,9 @@ Image::Image(rcp vulkanContext, const VkImageCreateInfo& info) : &m_vkImage, &m_vmaAllocation, nullptr)); + vk()->setDebugNameIfEnabled(uint64_t(m_vkImage), + VK_OBJECT_TYPE_IMAGE, + name); } Image::~Image() @@ -226,15 +270,28 @@ Image::~Image() ImageView::ImageView(rcp vulkanContext, rcp textureRef, - const VkImageViewCreateInfo& info) : + const VkImageViewCreateInfo& info, + const char* name) : Resource(std::move(vulkanContext)), m_textureRefOrNull(std::move(textureRef)), m_info(info) { - assert(m_textureRefOrNull == nullptr || info.image == *m_textureRefOrNull); + if (m_info.image == VK_NULL_HANDLE) + { + assert(m_textureRefOrNull != nullptr); + m_info.image = *m_textureRefOrNull; + } + else + { + assert(m_textureRefOrNull == nullptr || + m_info.image == *m_textureRefOrNull); + } m_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; VK_CHECK( vk()->CreateImageView(vk()->device, &m_info, nullptr, &m_vkImageView)); + vk()->setDebugNameIfEnabled(uint64_t(m_vkImageView), + VK_OBJECT_TYPE_IMAGE_VIEW, + name); } ImageView::~ImageView() @@ -242,7 +299,9 @@ ImageView::~ImageView() vk()->DestroyImageView(vk()->device, m_vkImageView, nullptr); } -Texture2D::Texture2D(rcp vk, VkImageCreateInfo info) : +Texture2D::Texture2D(rcp vk, + VkImageCreateInfo info, + const char* name) : rive::gpu::Texture(info.extent.width, info.extent.height), m_lastAccess({ .pipelineStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, @@ -264,26 +323,33 @@ Texture2D::Texture2D(rcp vk, VkImageCreateInfo info) : info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; } - m_image = vk->makeImage(info); - m_imageView = vk->makeImageView(m_image); + m_image = vk->makeImage(info, name); + m_imageView = vk->makeImageView(m_image, name); } -void Texture2D::stageContentsForUpload(const void* imageData, - size_t imageDataSizeInBytes) +void Texture2D::scheduleUpload(const void* imageDataRGBAPremul, + size_t imageDataSizeInBytes) { - m_imageUploadBuffer = m_image->vk()->makeBuffer( + rcp imageBufferRGBAPremul = m_image->vk()->makeBuffer( { .size = imageDataSizeInBytes, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, }, vkutil::Mappability::writeOnly); - memcpy(m_imageUploadBuffer->contents(), imageData, imageDataSizeInBytes); - m_imageUploadBuffer->flushContents(); + memcpy(imageBufferRGBAPremul->contents(), + imageDataRGBAPremul, + imageDataSizeInBytes); + imageBufferRGBAPremul->flushContents(); + scheduleUpload(std::move(imageBufferRGBAPremul)); +} + +void Texture2D::scheduleUpload(rcp imageBufferRGBAPremul) +{ + m_imageUploadBuffer = std::move(imageBufferRGBAPremul); } -void Texture2D::synchronize(VkCommandBuffer commandBuffer) +void Texture2D::applyImageUploadBuffer(VkCommandBuffer commandBuffer) { - assert(hasUpdates()); assert(m_imageUploadBuffer != nullptr); VkBufferImageCopy bufferImageCopy = { @@ -325,6 +391,9 @@ void Texture2D::barrier(VkCommandBuffer commandBuffer, vkutil::ImageAccessAction imageAccessAction, VkDependencyFlags dependencyFlags) { + // Always perform the barrier, even if m_lastAccess == dstAccess, because + // a pipeline barrier may still be needed even if we aren't transitioning + // the image or interacting with other stages. m_lastAccess = m_image->vk()->simpleImageMemoryBarrier(commandBuffer, m_lastAccess, dstAccess, diff --git a/thirdparty/rive_renderer/source/vulkan/vulkan_context.cpp b/thirdparty/rive_renderer/source/vulkan/vulkan_context.cpp index a6c511af3..026ef317e 100644 --- a/thirdparty/rive_renderer/source/vulkan/vulkan_context.cpp +++ b/thirdparty/rive_renderer/source/vulkan/vulkan_context.cpp @@ -19,6 +19,7 @@ static VmaAllocator make_vma_allocator( .vkGetDeviceProcAddr = vk->GetDeviceProcAddr, .vkGetPhysicalDeviceProperties = vk->GetPhysicalDeviceProperties, }; + VmaAllocatorCreateInfo vmaCreateInfo = { // We are single-threaded. .flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, @@ -53,6 +54,12 @@ VulkanContext::VulkanContext( #undef LOAD_VULKAN_DEVICE_COMMAND m_vmaAllocator(make_vma_allocator(this, pfnvkGetInstanceProcAddr)) { + GetPhysicalDeviceProperties(physicalDevice, &m_physicalDeviceProperties); + + // Check that we weren't told the device was more capable than it is + assert(m_physicalDeviceProperties.apiVersion >= features.apiVersion && + "Supplied API version should not be newer than the physical device"); + // VK spec says between D24_S8 and D32_S8, one of them must be supported m_supportsD24S8 = isFormatSupportedWithFeatureFlags( VK_FORMAT_D24_UNORM_S8_UINT, @@ -86,9 +93,10 @@ rcp VulkanContext::makeBuffer(const VkBufferCreateInfo& info, return rcp(new vkutil::Buffer(ref_rcp(this), info, mappability)); } -rcp VulkanContext::makeImage(const VkImageCreateInfo& info) +rcp VulkanContext::makeImage(const VkImageCreateInfo& info, + const char* name) { - return rcp(new vkutil::Image(ref_rcp(this), info)); + return rcp(new vkutil::Image(ref_rcp(this), info, name)); } rcp VulkanContext::makeFramebuffer( @@ -126,14 +134,14 @@ static VkImageAspectFlags image_aspect_flags_for_format(VkFormat format) RIVE_UNREACHABLE(); } -rcp VulkanContext::makeImageView(rcp image) +rcp VulkanContext::makeImageView(rcp image, + const char* name) { const VkImageCreateInfo& texInfo = image->info(); return makeImageView( image, { - .image = *image, .viewType = image_view_type_for_image_type(texInfo.imageType), .format = texInfo.format, .subresourceRange = @@ -142,28 +150,34 @@ rcp VulkanContext::makeImageView(rcp image) .levelCount = texInfo.mipLevels, .layerCount = 1, }, - }); + }, + name); } rcp VulkanContext::makeImageView( rcp image, - const VkImageViewCreateInfo& info) + const VkImageViewCreateInfo& info, + const char* name) { assert(image); - return rcp(new vkutil::ImageView(ref_rcp(this), std::move(image), info)); + return rcp( + new vkutil::ImageView(ref_rcp(this), std::move(image), info, name)); } rcp VulkanContext::makeExternalImageView( - const VkImageViewCreateInfo& info) + const VkImageViewCreateInfo& info, + const char* name) { return rcp( - new vkutil::ImageView(ref_rcp(this), nullptr, info)); + new vkutil::ImageView(ref_rcp(this), nullptr, info, name)); } rcp VulkanContext::makeTexture2D( - const VkImageCreateInfo& info) + const VkImageCreateInfo& info, + const char* name) { - return rcp(new vkutil::Texture2D(ref_rcp(this), info)); + return rcp( + new vkutil::Texture2D(ref_rcp(this), info, name)); } void VulkanContext::updateImageDescriptorSets( @@ -305,9 +319,33 @@ void VulkanContext::bufferMemoryBarrier( nullptr); } +void VulkanContext::clearColorImage(VkCommandBuffer commandBuffer, + ColorInt clearColor, + VkImage image, + VkImageLayout imageLayout) +{ + const VkClearColorValue colorClearValue = { + vkutil::color_clear_rgba32f(clearColor)}; + + const VkImageSubresourceRange colorClearRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .levelCount = 1, + .layerCount = 1, + }; + + CmdClearColorImage(commandBuffer, + image, + imageLayout, + &colorClearValue, + 1, + &colorClearRange); +} + void VulkanContext::blitSubRect(VkCommandBuffer commandBuffer, - VkImage src, - VkImage dst, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, const IAABB& blitBounds) { if (blitBounds.empty()) @@ -335,12 +373,30 @@ void VulkanContext::blitSubRect(VkCommandBuffer commandBuffer, imageBlit.dstOffsets[1] = {blitBounds.right, blitBounds.bottom, 1}; CmdBlitImage(commandBuffer, - src, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - dst, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + srcImage, + srcImageLayout, + dstImage, + dstImageLayout, 1, &imageBlit, VK_FILTER_NEAREST); } + +void VulkanContext::setDebugNameIfEnabled(uint64_t handle, + VkObjectType objectType, + const char* name) +{ + if (SetDebugUtilsObjectNameEXT != nullptr && name != nullptr) + { + VkDebugUtilsObjectNameInfoEXT nameInfo = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .objectType = objectType, + .objectHandle = handle, + .pObjectName = name, + }; + + SetDebugUtilsObjectNameEXT(device, &nameInfo); + } +} + } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/vulkan/vulkan_shaders.cpp b/thirdparty/rive_renderer/source/vulkan/vulkan_shaders.cpp new file mode 100644 index 000000000..f0247ed6f --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/vulkan_shaders.cpp @@ -0,0 +1,456 @@ +/* + * Copyright 2023 Rive + */ + +#include "vulkan_shaders.hpp" + +#include "rive/span.hpp" + +namespace rive::gpu::spirv +{ +namespace embedded +{ +// Draw setup shaders. +#include "generated/shaders/spirv/color_ramp.vert.h" +#include "generated/shaders/spirv/color_ramp.frag.h" +#include "generated/shaders/spirv/tessellate.vert.h" +#include "generated/shaders/spirv/tessellate.frag.h" +#include "generated/shaders/spirv/render_atlas.vert.h" +#include "generated/shaders/spirv/render_atlas_fill.frag.h" +#include "generated/shaders/spirv/render_atlas_stroke.frag.h" + +// InterlockMode::rasterOrdering shaders. +#include "generated/shaders/spirv/draw_path.vert.h" +#include "generated/shaders/spirv/draw_path.frag.h" +#include "generated/shaders/spirv/draw_interior_triangles.vert.h" +#include "generated/shaders/spirv/draw_interior_triangles.frag.h" +#include "generated/shaders/spirv/draw_atlas_blit.vert.h" +#include "generated/shaders/spirv/draw_atlas_blit.frag.h" +#include "generated/shaders/spirv/draw_image_mesh.vert.h" +#include "generated/shaders/spirv/draw_image_mesh.frag.h" + +// InterlockMode::atomics shaders. +#include "generated/shaders/spirv/atomic_draw_path.vert.h" +#include "generated/shaders/spirv/atomic_draw_path.frag.h" +#include "generated/shaders/spirv/atomic_draw_path.fixedcolor_frag.h" +#include "generated/shaders/spirv/atomic_draw_interior_triangles.vert.h" +#include "generated/shaders/spirv/atomic_draw_interior_triangles.frag.h" +#include "generated/shaders/spirv/atomic_draw_interior_triangles.fixedcolor_frag.h" +#include "generated/shaders/spirv/atomic_draw_atlas_blit.vert.h" +#include "generated/shaders/spirv/atomic_draw_atlas_blit.frag.h" +#include "generated/shaders/spirv/atomic_draw_atlas_blit.fixedcolor_frag.h" +#include "generated/shaders/spirv/atomic_draw_image_rect.vert.h" +#include "generated/shaders/spirv/atomic_draw_image_rect.frag.h" +#include "generated/shaders/spirv/atomic_draw_image_rect.fixedcolor_frag.h" +#include "generated/shaders/spirv/atomic_draw_image_mesh.vert.h" +#include "generated/shaders/spirv/atomic_draw_image_mesh.frag.h" +#include "generated/shaders/spirv/atomic_draw_image_mesh.fixedcolor_frag.h" +#include "generated/shaders/spirv/atomic_resolve.vert.h" +#include "generated/shaders/spirv/atomic_resolve.frag.h" +#include "generated/shaders/spirv/atomic_resolve.fixedcolor_frag.h" +#include "generated/shaders/spirv/atomic_resolve_coalesced.vert.h" +#include "generated/shaders/spirv/atomic_resolve_coalesced.frag.h" + +// InterlockMode::clockwise shaders. +#ifndef RIVE_ANDROID +#include "generated/shaders/spirv/draw_clockwise_path.vert.h" +#include "generated/shaders/spirv/draw_clockwise_path.frag.h" +#include "generated/shaders/spirv/draw_clockwise_path.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_clip.frag.h" +#include "generated/shaders/spirv/draw_clockwise_clip.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_interior_triangles.vert.h" +#include "generated/shaders/spirv/draw_clockwise_interior_triangles.frag.h" +#include "generated/shaders/spirv/draw_clockwise_interior_triangles.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_clip_interior_triangles.frag.h" +#include "generated/shaders/spirv/draw_clockwise_clip_interior_triangles.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_atlas_blit.vert.h" +#include "generated/shaders/spirv/draw_clockwise_atlas_blit.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atlas_blit.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_image_mesh.vert.h" +#include "generated/shaders/spirv/draw_clockwise_image_mesh.frag.h" +#include "generated/shaders/spirv/draw_clockwise_image_mesh.fixedcolor_frag.h" +#endif + +// InterlockMode::clockwiseAtomic shaders. +#include "generated/shaders/spirv/draw_clockwise_atomic_path.vert.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_path.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_path.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_clip.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_clip.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_borrowed_coverage_interior_triangles.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_clip_interior_triangles.fixedcolor_frag.h" +#include "generated/shaders/spirv/clear_clockwise_atomic_clip.vert.h" +#include "generated/shaders/spirv/clear_clockwise_atomic_clip.frag.h" +#include "generated/shaders/spirv/clear_clockwise_atomic_clip.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.fixedcolor_frag.h" +#include "generated/shaders/spirv/init_clockwise_atomic_workaround.frag.h" +#include "generated/shaders/spirv/init_clockwise_atomic_workaround.fixedcolor_frag.h" + +// InterlockMode::msaa shaders. +#include "generated/shaders/spirv/draw_msaa_path.vert.h" +#include "generated/shaders/spirv/draw_msaa_path.frag.h" +#include "generated/shaders/spirv/draw_msaa_path.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_path.noclipdistance_vert.h" +#include "generated/shaders/spirv/draw_msaa_stencil.vert.h" +#include "generated/shaders/spirv/draw_msaa_stencil.frag.h" +#include "generated/shaders/spirv/draw_msaa_stencil.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.vert.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.frag.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.noclipdistance_vert.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.vert.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.frag.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.noclipdistance_vert.h" +#include "generated/shaders/spirv/draw_fullscreen_quad.vert.h" +#include "generated/shaders/spirv/draw_input_attachment.frag.h" +#include "generated/shaders/spirv/draw_msaa_color_seed_attachment.frag.h" +#include "generated/shaders/spirv/draw_msaa_resolve.frag.h" +} // namespace embedded + +// Draw setup shaders. +rive::Span color_ramp_vert = + rive::make_span(embedded::color_ramp_vert); +rive::Span color_ramp_frag = + rive::make_span(embedded::color_ramp_frag); +rive::Span tessellate_vert = + rive::make_span(embedded::tessellate_vert); +rive::Span tessellate_frag = + rive::make_span(embedded::tessellate_frag); +rive::Span render_atlas_vert = + rive::make_span(embedded::render_atlas_vert); +rive::Span render_atlas_fill_frag = + rive::make_span(embedded::render_atlas_fill_frag); +rive::Span render_atlas_stroke_frag = + rive::make_span(embedded::render_atlas_stroke_frag); + +// InterlockMode::rasterOrdering shaders. +rive::Span draw_path_vert = + rive::make_span(embedded::draw_path_vert); +rive::Span draw_path_frag = + rive::make_span(embedded::draw_path_frag); +rive::Span draw_interior_triangles_vert = + rive::make_span(embedded::draw_interior_triangles_vert); +rive::Span draw_interior_triangles_frag = + rive::make_span(embedded::draw_interior_triangles_frag); +rive::Span draw_atlas_blit_vert = + rive::make_span(embedded::draw_atlas_blit_vert); +rive::Span draw_atlas_blit_frag = + rive::make_span(embedded::draw_atlas_blit_frag); +rive::Span draw_image_mesh_vert = + rive::make_span(embedded::draw_image_mesh_vert); +rive::Span draw_image_mesh_frag = + rive::make_span(embedded::draw_image_mesh_frag); + +// InterlockMode::atomics shaders. +rive::Span atomic_draw_path_vert = + rive::make_span(embedded::atomic_draw_path_vert); +rive::Span atomic_draw_path_frag = + rive::make_span(embedded::atomic_draw_path_frag); +rive::Span atomic_draw_path_fixedcolor_frag = + rive::make_span(embedded::atomic_draw_path_fixedcolor_frag); +rive::Span atomic_draw_interior_triangles_vert = + rive::make_span(embedded::atomic_draw_interior_triangles_vert); +rive::Span atomic_draw_interior_triangles_frag = + rive::make_span(embedded::atomic_draw_interior_triangles_frag); +rive::Span atomic_draw_interior_triangles_fixedcolor_frag = + rive::make_span(embedded::atomic_draw_interior_triangles_fixedcolor_frag); +rive::Span atomic_draw_atlas_blit_vert = + rive::make_span(embedded::atomic_draw_atlas_blit_vert); +rive::Span atomic_draw_atlas_blit_frag = + rive::make_span(embedded::atomic_draw_atlas_blit_frag); +rive::Span atomic_draw_atlas_blit_fixedcolor_frag = + rive::make_span(embedded::atomic_draw_atlas_blit_fixedcolor_frag); +rive::Span atomic_draw_image_rect_vert = + rive::make_span(embedded::atomic_draw_image_rect_vert); +rive::Span atomic_draw_image_rect_frag = + rive::make_span(embedded::atomic_draw_image_rect_frag); +rive::Span atomic_draw_image_rect_fixedcolor_frag = + rive::make_span(embedded::atomic_draw_image_rect_fixedcolor_frag); +rive::Span atomic_draw_image_mesh_vert = + rive::make_span(embedded::atomic_draw_image_mesh_vert); +rive::Span atomic_draw_image_mesh_frag = + rive::make_span(embedded::atomic_draw_image_mesh_frag); +rive::Span atomic_draw_image_mesh_fixedcolor_frag = + rive::make_span(embedded::atomic_draw_image_mesh_fixedcolor_frag); +rive::Span atomic_resolve_vert = + rive::make_span(embedded::atomic_resolve_vert); +rive::Span atomic_resolve_frag = + rive::make_span(embedded::atomic_resolve_frag); +rive::Span atomic_resolve_fixedcolor_frag = + rive::make_span(embedded::atomic_resolve_fixedcolor_frag); +rive::Span atomic_resolve_coalesced_vert = + rive::make_span(embedded::atomic_resolve_coalesced_vert); +rive::Span atomic_resolve_coalesced_frag = + rive::make_span(embedded::atomic_resolve_coalesced_frag); + +#ifndef RIVE_ANDROID +// InterlockMode::clockwise shaders. +rive::Span draw_clockwise_path_vert = + rive::make_span(embedded::draw_clockwise_path_vert); +rive::Span draw_clockwise_path_frag = + rive::make_span(embedded::draw_clockwise_path_frag); +rive::Span draw_clockwise_path_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_path_fixedcolor_frag); +rive::Span draw_clockwise_clip_frag = + rive::make_span(embedded::draw_clockwise_clip_frag); +rive::Span draw_clockwise_clip_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_clip_fixedcolor_frag); +rive::Span draw_clockwise_interior_triangles_vert = + rive::make_span(embedded::draw_clockwise_interior_triangles_vert); +rive::Span draw_clockwise_interior_triangles_frag = + rive::make_span(embedded::draw_clockwise_interior_triangles_frag); +rive::Span draw_clockwise_interior_triangles_fixedcolor_frag = + rive::make_span( + embedded::draw_clockwise_interior_triangles_fixedcolor_frag); +rive::Span draw_clockwise_clip_interior_triangles_frag = + rive::make_span(embedded::draw_clockwise_clip_interior_triangles_frag); +rive::Span + draw_clockwise_clip_interior_triangles_fixedcolor_frag = rive::make_span( + embedded::draw_clockwise_clip_interior_triangles_fixedcolor_frag); +rive::Span draw_clockwise_atlas_blit_vert = + rive::make_span(embedded::draw_clockwise_atlas_blit_vert); +rive::Span draw_clockwise_atlas_blit_frag = + rive::make_span(embedded::draw_clockwise_atlas_blit_frag); +rive::Span draw_clockwise_atlas_blit_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atlas_blit_fixedcolor_frag); +rive::Span draw_clockwise_image_mesh_vert = + rive::make_span(embedded::draw_clockwise_image_mesh_vert); +rive::Span draw_clockwise_image_mesh_frag = + rive::make_span(embedded::draw_clockwise_image_mesh_frag); +rive::Span draw_clockwise_image_mesh_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_image_mesh_fixedcolor_frag); +#endif + +// InterlockMode::clockwiseAtomic shaders. +rive::Span draw_clockwise_atomic_path_vert = + rive::make_span(embedded::draw_clockwise_atomic_path_vert); +rive::Span draw_clockwise_atomic_path_frag = + rive::make_span(embedded::draw_clockwise_atomic_path_frag); +rive::Span draw_clockwise_atomic_path_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atomic_path_fixedcolor_frag); +rive::Span draw_clockwise_atomic_clip_frag = + rive::make_span(embedded::draw_clockwise_atomic_clip_frag); +rive::Span draw_clockwise_atomic_clip_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atomic_clip_fixedcolor_frag); +rive::Span draw_clockwise_atomic_borrowed_coverage_frag = + rive::make_span(embedded::draw_clockwise_atomic_borrowed_coverage_frag); +rive::Span draw_clockwise_atomic_interior_triangles_vert = + rive::make_span(embedded::draw_clockwise_atomic_interior_triangles_vert); +rive::Span draw_clockwise_atomic_interior_triangles_frag = + rive::make_span(embedded::draw_clockwise_atomic_interior_triangles_frag); +rive::Span + draw_clockwise_atomic_interior_triangles_fixedcolor_frag = rive::make_span( + embedded::draw_clockwise_atomic_interior_triangles_fixedcolor_frag); +rive::Span draw_clockwise_atomic_clip_interior_triangles_frag = + rive::make_span( + embedded::draw_clockwise_atomic_clip_interior_triangles_frag); +rive::Span + draw_clockwise_atomic_clip_interior_triangles_fixedcolor_frag = + rive::make_span( + embedded:: + draw_clockwise_atomic_clip_interior_triangles_fixedcolor_frag); +rive::Span + draw_clockwise_atomic_borrowed_coverage_interior_triangles_frag = + rive::make_span( + embedded:: + draw_clockwise_atomic_borrowed_coverage_interior_triangles_frag); +rive::Span clear_clockwise_atomic_clip_vert = + rive::make_span(embedded::clear_clockwise_atomic_clip_vert); +rive::Span clear_clockwise_atomic_clip_frag = + rive::make_span(embedded::clear_clockwise_atomic_clip_frag); +rive::Span clear_clockwise_atomic_clip_fixedcolor_frag = + rive::make_span(embedded::clear_clockwise_atomic_clip_fixedcolor_frag); +rive::Span draw_clockwise_atomic_atlas_blit_vert = + rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_vert); +rive::Span draw_clockwise_atomic_atlas_blit_frag = + rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_frag); +rive::Span draw_clockwise_atomic_atlas_blit_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_fixedcolor_frag); +rive::Span draw_clockwise_atomic_image_mesh_vert = + rive::make_span(embedded::draw_clockwise_atomic_image_mesh_vert); +rive::Span draw_clockwise_atomic_image_mesh_frag = + rive::make_span(embedded::draw_clockwise_atomic_image_mesh_frag); +rive::Span draw_clockwise_atomic_image_mesh_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atomic_image_mesh_fixedcolor_frag); +rive::Span init_clockwise_atomic_workaround_frag = + rive::make_span(embedded::init_clockwise_atomic_workaround_frag); +rive::Span init_clockwise_atomic_workaround_fixedcolor_frag = + rive::make_span(embedded::init_clockwise_atomic_workaround_fixedcolor_frag); + +// InterlockMode::msaa shaders. +rive::Span draw_msaa_path_vert = + rive::make_span(embedded::draw_msaa_path_vert); +rive::Span draw_msaa_path_noclipdistance_vert = + rive::make_span(embedded::draw_msaa_path_noclipdistance_vert); +rive::Span draw_msaa_path_frag = + rive::make_span(embedded::draw_msaa_path_frag); +rive::Span draw_msaa_path_fixedcolor_frag = + rive::make_span(embedded::draw_msaa_path_fixedcolor_frag); +rive::Span draw_msaa_stencil_vert = + rive::make_span(embedded::draw_msaa_stencil_vert); +rive::Span draw_msaa_stencil_frag = + rive::make_span(embedded::draw_msaa_stencil_frag); +rive::Span draw_msaa_stencil_fixedcolor_frag = + rive::make_span(embedded::draw_msaa_stencil_fixedcolor_frag); +rive::Span draw_msaa_atlas_blit_vert = + rive::make_span(embedded::draw_msaa_atlas_blit_vert); +rive::Span draw_msaa_atlas_blit_noclipdistance_vert = + rive::make_span(embedded::draw_msaa_atlas_blit_noclipdistance_vert); +rive::Span draw_msaa_atlas_blit_frag = + rive::make_span(embedded::draw_msaa_atlas_blit_frag); +rive::Span draw_msaa_atlas_blit_fixedcolor_frag = + rive::make_span(embedded::draw_msaa_atlas_blit_fixedcolor_frag); +rive::Span draw_msaa_image_mesh_vert = + rive::make_span(embedded::draw_msaa_image_mesh_vert); +rive::Span draw_msaa_image_mesh_noclipdistance_vert = + rive::make_span(embedded::draw_msaa_image_mesh_noclipdistance_vert); +rive::Span draw_msaa_image_mesh_frag = + rive::make_span(embedded::draw_msaa_image_mesh_frag); +rive::Span draw_msaa_image_mesh_fixedcolor_frag = + rive::make_span(embedded::draw_msaa_image_mesh_fixedcolor_frag); +rive::Span draw_fullscreen_quad_vert = + rive::make_span(embedded::draw_fullscreen_quad_vert); +rive::Span draw_input_attachment_frag = + rive::make_span(embedded::draw_input_attachment_frag); +rive::Span draw_msaa_color_seed_attachment_frag = + rive::make_span(embedded::draw_msaa_color_seed_attachment_frag); +rive::Span draw_msaa_resolve_frag = + rive::make_span(embedded::draw_msaa_resolve_frag); + +void hotload_shaders(rive::Span spirvData) +{ + size_t spirvIndex = 0; + auto readNextBytecodeSpan = [spirvData, + &spirvIndex]() -> rive::Span { + size_t insnCount = spirvData[spirvIndex++]; + const uint32_t* insnData = spirvData.data() + spirvIndex; + spirvIndex += insnCount; + return rive::make_span(insnData, insnCount); + }; + + spirv::color_ramp_vert = readNextBytecodeSpan(); + spirv::color_ramp_frag = readNextBytecodeSpan(); + spirv::tessellate_vert = readNextBytecodeSpan(); + spirv::tessellate_frag = readNextBytecodeSpan(); + spirv::render_atlas_vert = readNextBytecodeSpan(); + spirv::render_atlas_fill_frag = readNextBytecodeSpan(); + spirv::render_atlas_stroke_frag = readNextBytecodeSpan(); + spirv::draw_path_vert = readNextBytecodeSpan(); + spirv::draw_path_frag = readNextBytecodeSpan(); + spirv::draw_interior_triangles_vert = readNextBytecodeSpan(); + spirv::draw_interior_triangles_frag = readNextBytecodeSpan(); + spirv::draw_atlas_blit_vert = readNextBytecodeSpan(); + spirv::draw_atlas_blit_frag = readNextBytecodeSpan(); + spirv::draw_image_mesh_vert = readNextBytecodeSpan(); + spirv::draw_image_mesh_frag = readNextBytecodeSpan(); + + spirv::atomic_draw_path_vert = readNextBytecodeSpan(); + spirv::atomic_draw_path_frag = readNextBytecodeSpan(); + spirv::atomic_draw_path_fixedcolor_frag = readNextBytecodeSpan(); + spirv::atomic_draw_interior_triangles_vert = readNextBytecodeSpan(); + spirv::atomic_draw_interior_triangles_frag = readNextBytecodeSpan(); + spirv::atomic_draw_interior_triangles_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::atomic_draw_atlas_blit_vert = readNextBytecodeSpan(); + spirv::atomic_draw_atlas_blit_frag = readNextBytecodeSpan(); + spirv::atomic_draw_atlas_blit_fixedcolor_frag = readNextBytecodeSpan(); + spirv::atomic_draw_image_rect_vert = readNextBytecodeSpan(); + spirv::atomic_draw_image_rect_frag = readNextBytecodeSpan(); + spirv::atomic_draw_image_rect_fixedcolor_frag = readNextBytecodeSpan(); + spirv::atomic_draw_image_mesh_vert = readNextBytecodeSpan(); + spirv::atomic_draw_image_mesh_frag = readNextBytecodeSpan(); + spirv::atomic_draw_image_mesh_fixedcolor_frag = readNextBytecodeSpan(); + spirv::atomic_resolve_vert = readNextBytecodeSpan(); + spirv::atomic_resolve_frag = readNextBytecodeSpan(); + spirv::atomic_resolve_fixedcolor_frag = readNextBytecodeSpan(); + spirv::atomic_resolve_coalesced_vert = readNextBytecodeSpan(); + spirv::atomic_resolve_coalesced_frag = readNextBytecodeSpan(); + +#ifndef RIVE_ANDROID + spirv::draw_clockwise_path_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_path_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_path_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_clip_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_clip_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_interior_triangles_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_interior_triangles_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_interior_triangles_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_clip_interior_triangles_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_clip_interior_triangles_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atlas_blit_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_atlas_blit_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atlas_blit_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_image_mesh_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_image_mesh_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_image_mesh_fixedcolor_frag = readNextBytecodeSpan(); +#endif + + spirv::draw_clockwise_atomic_path_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_path_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_path_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_clip_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_clip_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_borrowed_coverage_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_interior_triangles_vert = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_interior_triangles_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_interior_triangles_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_clip_interior_triangles_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_clip_interior_triangles_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_borrowed_coverage_interior_triangles_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_atlas_blit_vert = readNextBytecodeSpan(); + spirv::clear_clockwise_atomic_clip_vert = readNextBytecodeSpan(); + spirv::clear_clockwise_atomic_clip_frag = readNextBytecodeSpan(); + spirv::clear_clockwise_atomic_clip_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_atlas_blit_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_atlas_blit_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_atlas_blit_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_image_mesh_vert = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_image_mesh_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_image_mesh_fixedcolor_frag = + readNextBytecodeSpan(); + spirv::init_clockwise_atomic_workaround_frag = readNextBytecodeSpan(); + spirv::init_clockwise_atomic_workaround_fixedcolor_frag = + readNextBytecodeSpan(); + + spirv::draw_msaa_path_vert = readNextBytecodeSpan(); + spirv::draw_msaa_path_noclipdistance_vert = readNextBytecodeSpan(); + spirv::draw_msaa_path_frag = readNextBytecodeSpan(); + spirv::draw_msaa_path_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_msaa_stencil_vert = readNextBytecodeSpan(); + spirv::draw_msaa_stencil_frag = readNextBytecodeSpan(); + spirv::draw_msaa_stencil_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_msaa_atlas_blit_vert = readNextBytecodeSpan(); + spirv::draw_msaa_atlas_blit_noclipdistance_vert = readNextBytecodeSpan(); + spirv::draw_msaa_atlas_blit_frag = readNextBytecodeSpan(); + spirv::draw_msaa_atlas_blit_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_msaa_image_mesh_vert = readNextBytecodeSpan(); + spirv::draw_msaa_image_mesh_noclipdistance_vert = readNextBytecodeSpan(); + spirv::draw_msaa_image_mesh_frag = readNextBytecodeSpan(); + spirv::draw_msaa_image_mesh_fixedcolor_frag = readNextBytecodeSpan(); + spirv::draw_fullscreen_quad_vert = readNextBytecodeSpan(); + spirv::draw_input_attachment_frag = readNextBytecodeSpan(); + spirv::draw_msaa_color_seed_attachment_frag = readNextBytecodeSpan(); + spirv::draw_msaa_resolve_frag = readNextBytecodeSpan(); +} +} // namespace rive::gpu::spirv diff --git a/thirdparty/rive_renderer/source/vulkan/vulkan_shaders.hpp b/thirdparty/rive_renderer/source/vulkan/vulkan_shaders.hpp new file mode 100644 index 000000000..3fb135075 --- /dev/null +++ b/thirdparty/rive_renderer/source/vulkan/vulkan_shaders.hpp @@ -0,0 +1,132 @@ +/* + * Copyright 2023 Rive + */ + +#pragma once + +#include +#include "rive/span.hpp" + +namespace rive::gpu::spirv +{ +// Draw setup shaders. +extern rive::Span color_ramp_vert; +extern rive::Span color_ramp_frag; +extern rive::Span tessellate_vert; +extern rive::Span tessellate_frag; +extern rive::Span render_atlas_vert; +extern rive::Span render_atlas_fill_frag; +extern rive::Span render_atlas_stroke_frag; + +// InterlockMode::rasterOrdering shaders. +extern rive::Span draw_path_vert; +extern rive::Span draw_path_frag; +extern rive::Span draw_interior_triangles_vert; +extern rive::Span draw_interior_triangles_frag; +extern rive::Span draw_atlas_blit_vert; +extern rive::Span draw_atlas_blit_frag; +extern rive::Span draw_image_mesh_vert; +extern rive::Span draw_image_mesh_frag; + +// InterlockMode::atomics shaders. +extern rive::Span atomic_draw_path_vert; +extern rive::Span atomic_draw_path_frag; +extern rive::Span atomic_draw_path_fixedcolor_frag; +extern rive::Span atomic_draw_interior_triangles_vert; +extern rive::Span atomic_draw_interior_triangles_frag; +extern rive::Span + atomic_draw_interior_triangles_fixedcolor_frag; +extern rive::Span atomic_draw_atlas_blit_vert; +extern rive::Span atomic_draw_atlas_blit_frag; +extern rive::Span atomic_draw_atlas_blit_fixedcolor_frag; +extern rive::Span atomic_draw_image_rect_vert; +extern rive::Span atomic_draw_image_rect_frag; +extern rive::Span atomic_draw_image_rect_fixedcolor_frag; +extern rive::Span atomic_draw_image_mesh_vert; +extern rive::Span atomic_draw_image_mesh_frag; +extern rive::Span atomic_draw_image_mesh_fixedcolor_frag; +extern rive::Span atomic_resolve_vert; +extern rive::Span atomic_resolve_frag; +extern rive::Span atomic_resolve_fixedcolor_frag; +extern rive::Span atomic_resolve_coalesced_vert; +extern rive::Span atomic_resolve_coalesced_frag; + +#ifndef RIVE_ANDROID +// InterlockMode::clockwise shaders. +extern rive::Span draw_clockwise_path_vert; +extern rive::Span draw_clockwise_path_frag; +extern rive::Span draw_clockwise_path_fixedcolor_frag; +extern rive::Span draw_clockwise_clip_frag; +extern rive::Span draw_clockwise_clip_fixedcolor_frag; +extern rive::Span draw_clockwise_interior_triangles_vert; +extern rive::Span draw_clockwise_interior_triangles_frag; +extern rive::Span + draw_clockwise_interior_triangles_fixedcolor_frag; +extern rive::Span draw_clockwise_clip_interior_triangles_frag; +extern rive::Span + draw_clockwise_clip_interior_triangles_fixedcolor_frag; +extern rive::Span draw_clockwise_atlas_blit_vert; +extern rive::Span draw_clockwise_atlas_blit_frag; +extern rive::Span draw_clockwise_atlas_blit_fixedcolor_frag; +extern rive::Span draw_clockwise_image_mesh_vert; +extern rive::Span draw_clockwise_image_mesh_frag; +extern rive::Span draw_clockwise_image_mesh_fixedcolor_frag; +#endif + +// InterlockMode::clockwiseAtomic shaders. +extern rive::Span draw_clockwise_atomic_path_vert; +extern rive::Span draw_clockwise_atomic_path_frag; +extern rive::Span draw_clockwise_atomic_path_fixedcolor_frag; +extern rive::Span draw_clockwise_atomic_clip_frag; +extern rive::Span draw_clockwise_atomic_clip_fixedcolor_frag; +extern rive::Span draw_clockwise_atomic_borrowed_coverage_frag; +extern rive::Span draw_clockwise_atomic_interior_triangles_vert; +extern rive::Span draw_clockwise_atomic_interior_triangles_frag; +extern rive::Span + draw_clockwise_atomic_interior_triangles_fixedcolor_frag; +extern rive::Span + draw_clockwise_atomic_clip_interior_triangles_frag; +extern rive::Span + draw_clockwise_atomic_clip_interior_triangles_fixedcolor_frag; +extern rive::Span + draw_clockwise_atomic_borrowed_coverage_interior_triangles_frag; +extern rive::Span clear_clockwise_atomic_clip_vert; +extern rive::Span clear_clockwise_atomic_clip_frag; +extern rive::Span clear_clockwise_atomic_clip_fixedcolor_frag; +extern rive::Span draw_clockwise_atomic_atlas_blit_vert; +extern rive::Span draw_clockwise_atomic_atlas_blit_frag; +extern rive::Span + draw_clockwise_atomic_atlas_blit_fixedcolor_frag; +extern rive::Span draw_clockwise_atomic_image_mesh_vert; +extern rive::Span draw_clockwise_atomic_image_mesh_frag; +extern rive::Span + draw_clockwise_atomic_image_mesh_fixedcolor_frag; +extern rive::Span init_clockwise_atomic_workaround_vert; +extern rive::Span init_clockwise_atomic_workaround_frag; +extern rive::Span + init_clockwise_atomic_workaround_fixedcolor_frag; + +// InterlockMode::msaa shaders. +extern rive::Span draw_msaa_path_vert; +extern rive::Span draw_msaa_path_noclipdistance_vert; +extern rive::Span draw_msaa_path_frag; +extern rive::Span draw_msaa_path_fixedcolor_frag; +extern rive::Span draw_msaa_stencil_vert; +extern rive::Span draw_msaa_stencil_frag; +extern rive::Span draw_msaa_stencil_fixedcolor_frag; +extern rive::Span draw_msaa_atlas_blit_vert; +extern rive::Span draw_msaa_atlas_blit_noclipdistance_vert; +extern rive::Span draw_msaa_atlas_blit_frag; +extern rive::Span draw_msaa_atlas_blit_fixedcolor_frag; +extern rive::Span draw_msaa_image_mesh_vert; +extern rive::Span draw_msaa_image_mesh_noclipdistance_vert; +extern rive::Span draw_msaa_image_mesh_frag; +extern rive::Span draw_msaa_image_mesh_fixedcolor_frag; +extern rive::Span draw_fullscreen_quad_vert; +extern rive::Span draw_input_attachment_frag; +extern rive::Span draw_msaa_color_seed_attachment_frag; +extern rive::Span draw_msaa_resolve_frag; + +// Reload global SPIRV buffers from runtime data. +void hotload_shaders(rive::Span spirvData); +} // namespace rive::gpu::spirv diff --git a/thirdparty/rive_renderer/source/webgpu/em_js_handle.cpp b/thirdparty/rive_renderer/source/webgpu/em_js_handle.cpp deleted file mode 100644 index 5d1f1d0fd..000000000 --- a/thirdparty/rive_renderer/source/webgpu/em_js_handle.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#include "rive/renderer/webgpu/em_js_handle.hpp" - -EmJsHandle& EmJsHandle::operator=(EmJsHandle&& rhs) -{ - int tmp = rhs.m_handle; - rhs.m_handle = this->m_handle; - this->m_handle = tmp; - return *this; -} - -#ifdef RIVE_DAWN -EmJsHandle::~EmJsHandle() { assert(m_handle == 0); } - -wgpu::ShaderModule EmJsHandle::compileShaderModule(wgpu::Device device, - const char* language, - const char* source) -{ - RIVE_UNREACHABLE(); -} - -wgpu::ShaderModule EmJsHandle::compileSPIRVShaderModule(wgpu::Device device, - const uint32_t* code, - uint32_t codeSize) -{ - wgpu::ShaderModuleSPIRVDescriptor spirvDesc; - spirvDesc.code = code; - spirvDesc.codeSize = codeSize; - wgpu::ShaderModuleDescriptor descriptor; - descriptor.nextInChain = &spirvDesc; - return device.CreateShaderModule(&descriptor); -} -#endif - -#ifdef RIVE_WEBGPU -EmJsHandle::~EmJsHandle() -{ - if (m_handle != 0) - { - emscripten_webgpu_release_js_handle(m_handle); - } -} - -EM_JS(int, - compile_glsl_shader_module_js, - (int device, const char* language, const char* source), - { - device = JsValStore.get(device); - language = UTF8ToString(language); - source = UTF8ToString(source); - const shader = device.createShaderModule({ - language : language, - code : source, - }); - return JsValStore.add(shader); - }); - -wgpu::ShaderModule EmJsHandle::compileShaderModule(wgpu::Device device, - const char* language, - const char* source) -{ - m_handle = compile_glsl_shader_module_js( - emscripten_webgpu_export_device(device.Get()), - source, - language); - return wgpu::ShaderModule::Acquire( - emscripten_webgpu_import_shader_module(m_handle)); -} - -EM_JS(int, - compile_spirv_shader_module_js, - (int device, uintptr_t indexU32, uint32_t codeSize), - { - device = JsValStore.get(device); - // Copy data off the WASM heap before sending it to WebGPU bindings. - const code = new Uint32Array(codeSize); - code.set(Module.HEAPU32.subarray(indexU32, indexU32 + codeSize)); - const shader = device.createShaderModule({ - language : "spirv", - code : code, - }); - return JsValStore.add(shader); - }); - -wgpu::ShaderModule EmJsHandle::compileSPIRVShaderModule(wgpu::Device device, - const uint32_t* code, - uint32_t codeSize) -{ - assert(reinterpret_cast(code) % sizeof(uint32_t) == 0); - m_handle = compile_spirv_shader_module_js( - emscripten_webgpu_export_device(device.Get()), - reinterpret_cast(code) / sizeof(uint32_t), - codeSize); - return wgpu::ShaderModule::Acquire( - emscripten_webgpu_import_shader_module(m_handle)); -} -#endif diff --git a/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_impl.cpp b/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_impl.cpp index 1787aa46f..7c8aca2ec 100644 --- a/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_impl.cpp +++ b/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_impl.cpp @@ -4,126 +4,318 @@ #include "rive/renderer/webgpu/render_context_webgpu_impl.hpp" -#include "rive/renderer/rive_render_image.hpp" +#include "rive/renderer/draw.hpp" +#ifdef RIVE_CANVAS +#include "rive/renderer/render_canvas.hpp" +#endif +#include "rive/renderer/stack_vector.hpp" +#include "rive/texture_archive.hpp" #include "shaders/constants.glsl" -#include "generated/shaders/spirv/blit_texture_as_draw.vert.h" -#include "generated/shaders/spirv/blit_texture_as_draw.frag.h" -#include "generated/shaders/spirv/color_ramp.vert.h" -#include "generated/shaders/spirv/color_ramp.frag.h" -#include "generated/shaders/spirv/tessellate.vert.h" -#include "generated/shaders/spirv/tessellate.frag.h" -#include "generated/shaders/spirv/render_atlas.vert.h" -#include "generated/shaders/spirv/render_atlas_fill.frag.h" -#include "generated/shaders/spirv/render_atlas_stroke.frag.h" -#include "generated/shaders/spirv/draw_path.vert.h" -#include "generated/shaders/spirv/draw_path.frag.h" -#include "generated/shaders/spirv/draw_interior_triangles.vert.h" -#include "generated/shaders/spirv/draw_interior_triangles.frag.h" -#include "generated/shaders/spirv/draw_atlas_blit.vert.h" -#include "generated/shaders/spirv/draw_atlas_blit.frag.h" -#include "generated/shaders/spirv/draw_image_mesh.vert.h" -#include "generated/shaders/spirv/draw_image_mesh.frag.h" - -#include "generated/shaders/glsl.glsl.hpp" -#include "generated/shaders/constants.glsl.hpp" -#include "generated/shaders/common.glsl.hpp" -#include "generated/shaders/bezier_utils.glsl.hpp" -#include "generated/shaders/tessellate.glsl.hpp" -#include "generated/shaders/render_atlas.glsl.hpp" -#include "generated/shaders/advanced_blend.glsl.hpp" -#include "generated/shaders/draw_path.glsl.hpp" -#include "generated/shaders/draw_path_common.glsl.hpp" -#include "generated/shaders/draw_image_mesh.glsl.hpp" - #include #include -// When compiling "glsl-raw" shaders, the WebGPU driver will automatically -// search for a uniform with this name and update its value when draw commands -// have a base instance. -constexpr static char BASE_INSTANCE_UNIFORM_NAME[] = "nrdp_BaseInstance"; +namespace spirv +{ +#include "generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_vert.h" +#include "generated/shaders/spirv/blit_texture_as_draw_filtered.webgpu_frag.h" +#include "generated/shaders/spirv/color_ramp.vert.h" +#include "generated/shaders/spirv/color_ramp.frag.h" +#include "generated/shaders/spirv/tessellate.webgpu_vert.h" +#include "generated/shaders/spirv/tessellate.webgpu_frag.h" +#include "generated/shaders/spirv/render_atlas.webgpu_vert.h" +#include "generated/shaders/spirv/render_atlas_fill.webgpu_frag.h" +#include "generated/shaders/spirv/render_atlas_stroke.webgpu_frag.h" +#include "generated/shaders/spirv/draw_msaa_path.webgpu_vert.h" +#include "generated/shaders/spirv/draw_msaa_path.webgpu_noclipdistance_vert.h" +#include "generated/shaders/spirv/draw_msaa_path.webgpu_frag.h" +#include "generated/shaders/spirv/draw_msaa_path.webgpu_fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_vert.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_noclipdistance_vert.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_frag.h" +#include "generated/shaders/spirv/draw_msaa_atlas_blit.webgpu_fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.webgpu_vert.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.webgpu_noclipdistance_vert.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.webgpu_frag.h" +#include "generated/shaders/spirv/draw_msaa_image_mesh.webgpu_fixedcolor_frag.h" +#include "generated/shaders/spirv/draw_msaa_stencil.vert.h" +#include "generated/shaders/spirv/draw_msaa_stencil.frag.h" +} // namespace spirv #ifdef RIVE_DAWN #include +#endif + +#ifdef RIVE_WEBGPU +#include +#include +#include +#if RIVE_WEBGPU == 1 +#include "webgpu_compat.h" +#endif +#endif +#if RIVE_WEBGPU == 1 namespace wgpu { -using ImageCopyBuffer = TexelCopyBufferInfo; -using ImageCopyTexture = TexelCopyTextureInfo; -using TextureDataLayout = TexelCopyBufferLayout; +using TexelCopyBufferInfo = ImageCopyBuffer; +using TexelCopyTextureInfo = ImageCopyTexture; +using TexelCopyBufferLayout = TextureDataLayout; +using ShaderSourceSPIRV = ShaderModuleSPIRVDescriptor; }; // namespace wgpu -static void enable_shader_pixel_local_storage_ext(wgpu::RenderPassEncoder, - bool enabled) +static WGPUBool wgpu_bool(bool value) { return static_cast(value); } +#else +#define WGPU_STRING_VIEW(s) \ + { \ + .data = s, \ + .length = strlen(s), \ + } + +static WGPUOptionalBool wgpu_bool(bool value) +{ + return value ? WGPUOptionalBool_True : WGPUOptionalBool_False; +} +#endif + +constexpr static auto RIVE_FRONT_FACE = wgpu::FrontFace::CW; + +constexpr static uint32_t MSAA_SAMPLE_COUNT = 4u; + +constexpr static WGPUBlendComponent BLEND_COMPONENT_SRC_OVER = { + .operation = WGPUBlendOperation_Add, + .srcFactor = WGPUBlendFactor_One, + .dstFactor = WGPUBlendFactor_OneMinusSrcAlpha, +}; + +constexpr static WGPUBlendState BLEND_STATE_SRC_OVER = { + .color = BLEND_COMPONENT_SRC_OVER, + .alpha = BLEND_COMPONENT_SRC_OVER, +}; + +constexpr static WGPUStencilFaceState STENCIL_FACE_STATE_DISABLED = { + .compare = WGPUCompareFunction_Always, + .failOp = WGPUStencilOperation_Keep, + .depthFailOp = WGPUStencilOperation_Keep, + .passOp = WGPUStencilOperation_Keep, +}; + +static WGPUCullMode wgpu_cull_mode(rive::gpu::CullFace face) { + switch (face) + { + case rive::gpu::CullFace::none: + return WGPUCullMode_None; + case rive::gpu::CullFace::clockwise: + return WGPUCullMode_Front; + case rive::gpu::CullFace::counterclockwise: + return WGPUCullMode_Back; + } RIVE_UNREACHABLE(); } -static bool generate_mipmaps_builtin(wgpu::CommandEncoder encoder, - wgpu::Texture texture) +static WGPUCompareFunction wgpu_compare_function(rive::gpu::StencilCompareOp op) +{ + switch (op) + { + case rive::gpu::StencilCompareOp::less: + return WGPUCompareFunction_Less; + case rive::gpu::StencilCompareOp::equal: + return WGPUCompareFunction_Equal; + case rive::gpu::StencilCompareOp::lessOrEqual: + return WGPUCompareFunction_LessEqual; + case rive::gpu::StencilCompareOp::notEqual: + return WGPUCompareFunction_NotEqual; + case rive::gpu::StencilCompareOp::always: + return WGPUCompareFunction_Always; + } + RIVE_UNREACHABLE(); +}; + +static WGPUStencilOperation wgpu_stencil_operation(rive::gpu::StencilOp op) { - return false; + switch (op) + { + case rive::gpu::StencilOp::keep: + return WGPUStencilOperation_Keep; + case rive::gpu::StencilOp::replace: + return WGPUStencilOperation_Replace; + case rive::gpu::StencilOp::zero: + return WGPUStencilOperation_Zero; + case rive::gpu::StencilOp::decrClamp: + return WGPUStencilOperation_DecrementClamp; + case rive::gpu::StencilOp::incrWrap: + return WGPUStencilOperation_IncrementWrap; + case rive::gpu::StencilOp::decrWrap: + return WGPUStencilOperation_DecrementWrap; + }; + RIVE_UNREACHABLE(); } -#endif -#ifdef RIVE_WEBGPU -#include "render_context_webgpu_vulkan.hpp" -#include -#include -#include - -EM_JS(void, - enable_shader_pixel_local_storage_ext_js, - (int renderPass, bool enabled), - { - renderPass = JsValStore.get(renderPass); - renderPass.setShaderPixelLocalStorageEnabled(Boolean(enabled)); - }); - -static void enable_shader_pixel_local_storage_ext( - wgpu::RenderPassEncoder renderPass, - bool enabled) +static WGPUStencilFaceState wgpu_stencil_face_state( + rive::gpu::StencilFaceOps face) +{ + return { + .compare = wgpu_compare_function(face.compareOp), + .failOp = wgpu_stencil_operation(face.failOp), + .depthFailOp = wgpu_stencil_operation(face.depthFailOp), + .passOp = wgpu_stencil_operation(face.passOp), + }; +} + +static wgpu::Color wgpu_color_premul(rive::ColorInt riveColor) { - enable_shader_pixel_local_storage_ext_js( - emscripten_webgpu_export_render_pass_encoder(renderPass.Get()), - enabled); + float premul[4]; + rive::UnpackColorToRGBA32FPremul(riveColor, premul); + return {premul[0], premul[1], premul[2], premul[3]}; } -EM_JS(bool, generate_mipmaps_builtin_js, (int encoder, int texture), { - encoder = JsValStore.get(encoder); - texture = JsValStore.get(texture); - if (encoder.generateMipmap) +static wgpu::AddressMode webgpu_address_mode(rive::ImageWrap wrap) +{ + switch (wrap) { - encoder.generateMipmap(texture); - return true; + case rive::ImageWrap::clamp: + return wgpu::AddressMode::ClampToEdge; + case rive::ImageWrap::repeat: + return wgpu::AddressMode::Repeat; + case rive::ImageWrap::mirror: + return wgpu::AddressMode::MirrorRepeat; } - return false; + RIVE_UNREACHABLE(); +} + +static wgpu::FilterMode webgpu_filter_mode(rive::ImageFilter filter) +{ + switch (filter) + { + case rive::ImageFilter::bilinear: + return wgpu::FilterMode::Linear; + case rive::ImageFilter::nearest: + return wgpu::FilterMode::Nearest; + } + RIVE_UNREACHABLE(); +} + +static wgpu::MipmapFilterMode webgpu_mipmap_filter_mode( + rive::ImageFilter filter) +{ + switch (filter) + { + case rive::ImageFilter::nearest: + case rive::ImageFilter::bilinear: + return wgpu::MipmapFilterMode::Nearest; + } + RIVE_UNREACHABLE(); +} + +static wgpu::ShaderModule compile_shader_module_spirv(wgpu::Device device, + const uint32_t* code, + uint32_t codeSize) +{ + wgpu::ShaderSourceSPIRV spirvSource; + spirvSource.code = code; + spirvSource.codeSize = codeSize; + wgpu::ShaderModuleDescriptor descriptor = {.nextInChain = &spirvSource}; + return device.CreateShaderModule(&descriptor); +} + +#ifdef RIVE_WAGYU +#include + +#include "generated/shaders/glsl.glsl.hpp" +#include "generated/shaders/constants.glsl.hpp" +#include "generated/shaders/image_draw_uniforms.glsl.hpp" +#include "generated/shaders/flush_uniforms.glsl.hpp" +#include "generated/shaders/common.glsl.hpp" +#include "generated/shaders/color_ramp.glsl.hpp" +#include "generated/shaders/bezier_utils.glsl.hpp" +#include "generated/shaders/tessellate.glsl.hpp" +#include "generated/shaders/render_atlas.glsl.hpp" +#include "generated/shaders/advanced_blend.glsl.hpp" +#include "generated/shaders/draw_path_common.glsl.hpp" +#include "generated/shaders/draw_path.vert.hpp" +#include "generated/shaders/draw_raster_order_path.frag.hpp" +#include "generated/shaders/draw_clockwise_path.frag.hpp" +#include "generated/shaders/draw_clockwise_clip.frag.hpp" +#include "generated/shaders/draw_image_mesh.vert.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" + +// When compiling "glslRaw" shaders, the WebGPU driver will automatically search +// for a uniform with this name and update its value when draw commands have a +// base instance. +constexpr static char BASE_INSTANCE_UNIFORM_NAME[] = "nrdp_BaseInstance"; + +EM_JS(int, gl_max_vertex_shader_storage_blocks, (), { + const version = globalThis.nrdp ?.version || navigator.getNrdpVersion(); + return version.libraries.opengl.options.limits + .GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS; }); -static bool generate_mipmaps_builtin(wgpu::CommandEncoder encoder, - wgpu::Texture texture) +wgpu::ShaderModule compile_shader_module_wagyu(wgpu::Device device, + const char* source, + WGPUWagyuShaderLanguage language) { - return generate_mipmaps_builtin_js( - emscripten_webgpu_export_command_encoder(encoder.Get()), - emscripten_webgpu_export_texture(texture.Get())); + WGPUChainedStruct* chainedShaderModuleDescriptor = nullptr; + WGPUWagyuShaderModuleDescriptor wagyuDesc = + WGPU_WAGYU_SHADER_MODULE_DESCRIPTOR_INIT; + wagyuDesc.codeSize = strlen(source); + wagyuDesc.code = source; + wagyuDesc.language = language; + chainedShaderModuleDescriptor = &wagyuDesc.chain; + + WGPUShaderModuleDescriptor descriptor = WGPU_SHADER_MODULE_DESCRIPTOR_INIT; + descriptor.nextInChain = chainedShaderModuleDescriptor; + auto ret = wgpuDeviceCreateShaderModule(device.Get(), &descriptor); + return wgpu::ShaderModule::Acquire(ret); } -#endif + +static bool using_pls(rive::gpu::InterlockMode interlockMode) +{ + switch (interlockMode) + { + case rive::gpu::InterlockMode::rasterOrdering: + case rive::gpu::InterlockMode::clockwise: + return true; + case rive::gpu::InterlockMode::atomics: + case rive::gpu::InterlockMode::clockwiseAtomic: + case rive::gpu::InterlockMode::msaa: + return false; + } + RIVE_UNREACHABLE(); +} +#endif // RIVE_WAGYU namespace rive::gpu { +#ifdef RIVE_WAGYU // Draws emulated render-pass load/store actions for // EXT_shader_pixel_local_storage. class RenderContextWebGPUImpl::LoadStoreEXTPipeline { public: + constexpr static uint32_t Key(LoadStoreActionsEXT actions, + wgpu::TextureFormat framebufferFormat) + { + uint32_t key = static_cast(framebufferFormat); + + assert(key << LOAD_STORE_ACTIONS_EXT_COUNT >> + LOAD_STORE_ACTIONS_EXT_COUNT == + key); + assert(static_cast(actions) < + 1 << LOAD_STORE_ACTIONS_EXT_COUNT); + key = (key << LOAD_STORE_ACTIONS_EXT_COUNT) | + static_cast(actions); + + return key; + } + LoadStoreEXTPipeline(RenderContextWebGPUImpl* context, LoadStoreActionsEXT actions, wgpu::TextureFormat framebufferFormat) : m_framebufferFormat(framebufferFormat) { wgpu::PipelineLayoutDescriptor pipelineLayoutDesc; - if (actions & LoadStoreActionsEXT::clearColor) + if (enums::is_flag_set(actions, LoadStoreActionsEXT::clearColor)) { // Create a uniform buffer binding for the clear color. wgpu::BindGroupLayoutEntry bindingLayouts[] = { @@ -164,18 +356,13 @@ class RenderContextWebGPUImpl::LoadStoreEXTPipeline wgpu::ShaderModule fragmentShader; std::ostringstream glsl; glsl << "#version 310 es\n"; - glsl << "#pragma shader_stage(fragment)\n"; glsl << "#define " GLSL_FRAGMENT " true\n"; glsl << "#define " GLSL_ENABLE_CLIPPING " true\n"; - if (context->m_contextOptions.invertRenderTargetY) - { - glsl << "#define " GLSL_POST_INVERT_Y " true\n"; - } BuildLoadStoreEXTGLSL(glsl, actions); fragmentShader = - m_fragmentShaderHandle.compileShaderModule(context->m_device, - glsl.str().c_str(), - "glsl-raw"); + compile_shader_module_wagyu(context->m_device, + glsl.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); wgpu::ColorTargetState colorTargetState = { .format = framebufferFormat, @@ -189,6 +376,7 @@ class RenderContextWebGPUImpl::LoadStoreEXTPipeline }; wgpu::RenderPipelineDescriptor desc = { + .label = "RIVE_LoadStoreEXTPipeline", .layout = pipelineLayout, .vertex = { @@ -200,8 +388,8 @@ class RenderContextWebGPUImpl::LoadStoreEXTPipeline .primitive = { .topology = wgpu::PrimitiveTopology::TriangleStrip, - .frontFace = context->frontFaceForRenderTargetDraws(), - .cullMode = wgpu::CullMode::Back, + .frontFace = RIVE_FRONT_FACE, + .cullMode = wgpu::CullMode::None, }, .fragment = &fragmentState, }; @@ -226,9 +414,9 @@ class RenderContextWebGPUImpl::LoadStoreEXTPipeline private: const wgpu::TextureFormat m_framebufferFormat RIVE_MAYBE_UNUSED; wgpu::BindGroupLayout m_bindGroupLayout; - EmJsHandle m_fragmentShaderHandle; wgpu::RenderPipeline m_renderPipeline; }; +#endif // Renders color ramps to the gradient texture. class RenderContextWebGPUImpl::ColorRampPipeline @@ -254,11 +442,52 @@ class RenderContextWebGPUImpl::ColorRampPipeline wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc); - wgpu::ShaderModule vertexShader = - m_vertexShaderHandle.compileSPIRVShaderModule( - device, - color_ramp_vert, - std::size(color_ramp_vert)); + wgpu::ShaderModule vertexShader, fragmentShader; +#ifdef RIVE_WAGYU + if (impl->m_capabilities.backendType == wgpu::BackendType::OpenGLES) + { + // Rive shaders tend to be long and prone to vendor bugs in the + // compiler. Instead of SPIRV, send down the raw Rive GLSL sources, + // which have various workarounds for known issues and are tested + // regularly. + std::ostringstream glsl; + glsl << "#define " << GLSL_POST_INVERT_Y << " true\n"; + glsl << glsl::glsl << "\n"; + glsl << glsl::constants << "\n"; + glsl << glsl::flush_uniforms << '\n'; + glsl << glsl::common << "\n"; + glsl << glsl::color_ramp << "\n"; + + std::ostringstream vertexGLSL; + vertexGLSL << "#version 310 es\n"; + vertexGLSL << "#define " GLSL_VERTEX " true\n"; + vertexGLSL << glsl.str(); + vertexShader = + compile_shader_module_wagyu(device, + vertexGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); + + std::ostringstream fragmentGLSL; + fragmentGLSL << "#version 310 es\n"; + fragmentGLSL << "#define " GLSL_FRAGMENT " true\n"; + fragmentGLSL << glsl.str(); + fragmentShader = + compile_shader_module_wagyu(device, + fragmentGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); + } + else +#endif + { + vertexShader = + compile_shader_module_spirv(device, + spirv::color_ramp_vert, + std::size(spirv::color_ramp_vert)); + fragmentShader = + compile_shader_module_spirv(device, + spirv::color_ramp_frag, + std::size(spirv::color_ramp_frag)); + } wgpu::VertexAttribute attrs[] = { { @@ -269,17 +498,13 @@ class RenderContextWebGPUImpl::ColorRampPipeline }; wgpu::VertexBufferLayout vertexBufferLayout = { - .arrayStride = sizeof(gpu::GradientSpan), - .stepMode = wgpu::VertexStepMode::Instance, .attributeCount = std::size(attrs), .attributes = attrs, }; - - wgpu::ShaderModule fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - device, - color_ramp_frag, - std::size(color_ramp_frag)); + // arrayStride and stepMode are defined in different orders in webgpu1 + // vs webgpu2, so can't be in the designated initializer. + vertexBufferLayout.arrayStride = sizeof(gpu::GradientSpan); + vertexBufferLayout.stepMode = wgpu::VertexStepMode::Instance; wgpu::ColorTargetState colorTargetState = { .format = wgpu::TextureFormat::RGBA8Unorm, @@ -293,6 +518,7 @@ class RenderContextWebGPUImpl::ColorRampPipeline }; wgpu::RenderPipelineDescriptor desc = { + .label = "RIVE_ColorRampPipeline", .layout = pipelineLayout, .vertex = { @@ -304,8 +530,8 @@ class RenderContextWebGPUImpl::ColorRampPipeline .primitive = { .topology = wgpu::PrimitiveTopology::TriangleStrip, - .frontFace = kFrontFaceForOffscreenDraws, - .cullMode = wgpu::CullMode::Back, + .frontFace = RIVE_FRONT_FACE, + .cullMode = wgpu::CullMode::None, }, .fragment = &fragmentState, }; @@ -321,8 +547,6 @@ class RenderContextWebGPUImpl::ColorRampPipeline private: wgpu::BindGroupLayout m_bindGroupLayout; - EmJsHandle m_vertexShaderHandle; - EmJsHandle m_fragmentShaderHandle; wgpu::RenderPipeline m_renderPipeline; }; @@ -345,9 +569,9 @@ class RenderContextWebGPUImpl::TessellatePipeline wgpu::BindGroupLayout layouts[] = { m_perFlushBindingsLayout, impl->m_emptyBindingsLayout, - impl->m_drawBindGroupLayouts[IMMUTABLE_SAMPLER_BINDINGS_SET], + impl->m_emptyBindingsLayout, + impl->m_drawBindGroupLayouts[WEBGPU_SAMPLER_BINDINGS_SET], }; - static_assert(IMMUTABLE_SAMPLER_BINDINGS_SET == 2); wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = { .bindGroupLayoutCount = std::size(layouts), @@ -357,37 +581,57 @@ class RenderContextWebGPUImpl::TessellatePipeline wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc); - wgpu::ShaderModule vertexShader; - if (impl->m_contextOptions.disableStorageBuffers) + wgpu::ShaderModule vertexShader, fragmentShader; +#ifdef RIVE_WAGYU + if (impl->m_capabilities.backendType == wgpu::BackendType::OpenGLES) { - // The built-in SPIRV does not #define - // DISABLE_SHADER_STORAGE_BUFFERS. Recompile the tessellation shader - // with storage buffers disabled. + // Rive shaders tend to be long and prone to vendor bugs in the + // compiler. Instead of SPIRV, send down the raw Rive GLSL sources, + // which have various workarounds for known issues and are tested + // regularly. + std::ostringstream glsl; + if (impl->m_capabilities.polyfillVertexStorageBuffers) + { + glsl << "#define " GLSL_DISABLE_SHADER_STORAGE_BUFFERS + " true\n"; + } + glsl << "#define " << GLSL_POST_INVERT_Y << " true\n"; + glsl << glsl::glsl << "\n"; + glsl << glsl::constants << "\n"; + glsl << glsl::flush_uniforms << "\n"; + glsl << glsl::common << "\n"; + glsl << glsl::bezier_utils << "\n"; + glsl << glsl::tessellate << "\n"; + std::ostringstream vertexGLSL; - vertexGLSL << "#version 460\n"; - vertexGLSL << "#pragma shader_stage(vertex)\n"; + vertexGLSL << "#version 310 es\n"; vertexGLSL << "#define " GLSL_VERTEX " true\n"; - vertexGLSL << "#define " GLSL_DISABLE_SHADER_STORAGE_BUFFERS - " true\n"; - vertexGLSL << "#define " GLSL_TARGET_VULKAN " true\n"; - vertexGLSL - << "#extension GL_EXT_samplerless_texture_functions : enable\n"; - vertexGLSL << glsl::glsl << "\n"; - vertexGLSL << glsl::constants << "\n"; - vertexGLSL << glsl::common << "\n"; - vertexGLSL << glsl::bezier_utils << "\n"; - vertexGLSL << glsl::tessellate << "\n"; - vertexShader = m_vertexShaderHandle.compileShaderModule( - device, - vertexGLSL.str().c_str(), - "glsl"); + vertexGLSL << glsl.str(); + vertexShader = + compile_shader_module_wagyu(device, + vertexGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); + + std::ostringstream fragmentGLSL; + fragmentGLSL << "#version 310 es\n"; + fragmentGLSL << "#define " GLSL_FRAGMENT " true\n"; + fragmentGLSL << glsl.str(); + fragmentShader = + compile_shader_module_wagyu(device, + fragmentGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); } else +#endif { - vertexShader = m_vertexShaderHandle.compileSPIRVShaderModule( + vertexShader = compile_shader_module_spirv( + device, + spirv::tessellate_webgpu_vert, + std::size(spirv::tessellate_webgpu_vert)); + fragmentShader = compile_shader_module_spirv( device, - tessellate_vert, - std::size(tessellate_vert)); + spirv::tessellate_webgpu_frag, + std::size(spirv::tessellate_webgpu_frag)); } wgpu::VertexAttribute attrs[] = { @@ -414,17 +658,13 @@ class RenderContextWebGPUImpl::TessellatePipeline }; wgpu::VertexBufferLayout vertexBufferLayout = { - .arrayStride = sizeof(gpu::TessVertexSpan), - .stepMode = wgpu::VertexStepMode::Instance, .attributeCount = std::size(attrs), .attributes = attrs, }; - - wgpu::ShaderModule fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - device, - tessellate_frag, - std::size(tessellate_frag)); + // arrayStride and stepMode are defined in different orders in webgpu1 + // vs webgpu2, so can't be in the designated initializer. + vertexBufferLayout.arrayStride = sizeof(gpu::TessVertexSpan); + vertexBufferLayout.stepMode = wgpu::VertexStepMode::Instance; wgpu::ColorTargetState colorTargetState = { .format = wgpu::TextureFormat::RGBA32Uint, @@ -438,6 +678,7 @@ class RenderContextWebGPUImpl::TessellatePipeline }; wgpu::RenderPipelineDescriptor desc = { + .label = "RIVE_TessellatePipeline", .layout = pipelineLayout, .vertex = { @@ -449,8 +690,8 @@ class RenderContextWebGPUImpl::TessellatePipeline .primitive = { .topology = wgpu::PrimitiveTopology::TriangleList, - .frontFace = kFrontFaceForOffscreenDraws, - .cullMode = wgpu::CullMode::Back, + .frontFace = RIVE_FRONT_FACE, + .cullMode = wgpu::CullMode::None, }, .fragment = &fragmentState, }; @@ -466,8 +707,6 @@ class RenderContextWebGPUImpl::TessellatePipeline private: wgpu::BindGroupLayout m_perFlushBindingsLayout; - EmJsHandle m_vertexShaderHandle; - EmJsHandle m_fragmentShaderHandle; wgpu::RenderPipeline m_renderPipeline; }; @@ -490,9 +729,9 @@ class RenderContextWebGPUImpl::AtlasPipeline wgpu::BindGroupLayout layouts[] = { m_perFlushBindingsLayout, impl->m_emptyBindingsLayout, - impl->m_drawBindGroupLayouts[IMMUTABLE_SAMPLER_BINDINGS_SET], + impl->m_emptyBindingsLayout, + impl->m_drawBindGroupLayouts[WEBGPU_SAMPLER_BINDINGS_SET], }; - static_assert(IMMUTABLE_SAMPLER_BINDINGS_SET == 2); wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = { .bindGroupLayoutCount = std::size(layouts), @@ -503,38 +742,80 @@ class RenderContextWebGPUImpl::AtlasPipeline device.CreatePipelineLayout(&pipelineLayoutDesc); wgpu::ShaderModule vertexShader; - if (impl->m_contextOptions.disableStorageBuffers) + wgpu::ShaderModule fillFragmentShader, strokeFragmentShader; +#ifdef RIVE_WAGYU + if (impl->m_capabilities.backendType == wgpu::BackendType::OpenGLES) { - // The built-in SPIRV does not #define - // DISABLE_SHADER_STORAGE_BUFFERS. Recompile the tessellation shader - // with storage buffers disabled. + // Rive shaders tend to be long and prone to vendor bugs in the + // compiler. Instead of SPIRV, send down the raw Rive GLSL sources, + // which have various workarounds for known issues and are tested + // regularly. + std::ostringstream glsl; + glsl << "#define " << GLSL_DRAW_PATH << " true\n"; + glsl << "#define " << GLSL_ENABLE_FEATHER << " true\n"; + glsl << "#define " << GLSL_ENABLE_INSTANCE_INDEX << " true\n"; + glsl << "#define " << GLSL_BASE_INSTANCE_UNIFORM_NAME << ' ' + << BASE_INSTANCE_UNIFORM_NAME << '\n'; + glsl << "#define " << GLSL_POST_INVERT_Y << " true\n"; + if (impl->m_capabilities.polyfillVertexStorageBuffers) + { + glsl << "#define " GLSL_DISABLE_SHADER_STORAGE_BUFFERS + " true\n"; + } + glsl << glsl::glsl << '\n'; + glsl << glsl::constants << '\n'; + glsl << glsl::flush_uniforms << '\n'; + glsl << glsl::common << '\n'; + glsl << glsl::draw_path_common << '\n'; + glsl << glsl::render_atlas << '\n'; + std::ostringstream vertexGLSL; - vertexGLSL << "#version 460\n"; - vertexGLSL - << "#extension GL_EXT_samplerless_texture_functions : enable\n"; + vertexGLSL << "#version 310 es\n"; vertexGLSL << "#pragma shader_stage(vertex)\n"; vertexGLSL << "#define " GLSL_VERTEX " true\n"; - vertexGLSL << "#define " GLSL_DISABLE_SHADER_STORAGE_BUFFERS - " true\n"; - vertexGLSL << "#define " GLSL_TARGET_VULKAN " true\n"; - vertexGLSL << "#define " << GLSL_DRAW_PATH << '\n'; - vertexGLSL << "#define " << GLSL_ENABLE_FEATHER << "true\n"; - vertexGLSL << glsl::glsl << '\n'; - vertexGLSL << glsl::constants << '\n'; - vertexGLSL << glsl::common << '\n'; - vertexGLSL << glsl::draw_path_common << '\n'; - vertexGLSL << glsl::render_atlas << '\n'; - vertexShader = m_vertexShaderHandle.compileShaderModule( - device, - vertexGLSL.str().c_str(), - "glsl"); + vertexGLSL << glsl.str(); + vertexShader = + compile_shader_module_wagyu(device, + vertexGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); + + std::ostringstream fillGLSL; + fillGLSL << "#version 310 es\n"; + fillGLSL << "#pragma shader_stage(fragment)\n"; + fillGLSL << "#define " GLSL_FRAGMENT " true\n"; + fillGLSL << "#define " GLSL_ATLAS_FEATHERED_FILL " true\n"; + fillGLSL << glsl.str(); + fillFragmentShader = + compile_shader_module_wagyu(device, + fillGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); + + std::ostringstream strokeGLSL; + strokeGLSL << "#version 310 es\n"; + strokeGLSL << "#pragma shader_stage(fragment)\n"; + strokeGLSL << "#define " GLSL_FRAGMENT " true\n"; + strokeGLSL << "#define " GLSL_ATLAS_FEATHERED_STROKE " true\n"; + strokeGLSL << glsl.str(); + strokeFragmentShader = + compile_shader_module_wagyu(device, + strokeGLSL.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); } else +#endif { - vertexShader = m_vertexShaderHandle.compileSPIRVShaderModule( + vertexShader = compile_shader_module_spirv( device, - render_atlas_vert, - std::size(render_atlas_vert)); + spirv::render_atlas_webgpu_vert, + std::size(spirv::render_atlas_webgpu_vert)); + fillFragmentShader = compile_shader_module_spirv( + device, + spirv::render_atlas_fill_webgpu_frag, + std::size(spirv::render_atlas_fill_webgpu_frag)); + strokeFragmentShader = compile_shader_module_spirv( + device, + spirv::render_atlas_stroke_webgpu_frag, + std::size(spirv::render_atlas_stroke_webgpu_frag)); } wgpu::VertexAttribute attrs[] = { @@ -551,23 +832,13 @@ class RenderContextWebGPUImpl::AtlasPipeline }; wgpu::VertexBufferLayout vertexBufferLayout = { - .arrayStride = sizeof(gpu::PatchVertex), - .stepMode = wgpu::VertexStepMode::Vertex, .attributeCount = std::size(attrs), .attributes = attrs, }; - - wgpu::ShaderModule fillFragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - device, - render_atlas_fill_frag, - std::size(render_atlas_fill_frag)); - - wgpu::ShaderModule strokeFragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - device, - render_atlas_stroke_frag, - std::size(render_atlas_stroke_frag)); + // arrayStride and stepMode are defined in different orders in webgpu1 + // vs webgpu2, so can't be in the designated initializer. + vertexBufferLayout.arrayStride = sizeof(gpu::PatchVertex); + vertexBufferLayout.stepMode = wgpu::VertexStepMode::Vertex; wgpu::BlendState blendState = { .color = { @@ -589,6 +860,7 @@ class RenderContextWebGPUImpl::AtlasPipeline }; wgpu::RenderPipelineDescriptor desc = { + .label = "RIVE_AtlasPipeline", .layout = pipelineLayout, .vertex = { @@ -600,8 +872,8 @@ class RenderContextWebGPUImpl::AtlasPipeline .primitive = { .topology = wgpu::PrimitiveTopology::TriangleList, - .frontFace = kFrontFaceForOffscreenDraws, - .cullMode = wgpu::CullMode::Back, + .frontFace = RIVE_FRONT_FACE, + .cullMode = wgpu::CullMode::None, }, .fragment = &fragmentState, }; @@ -622,8 +894,6 @@ class RenderContextWebGPUImpl::AtlasPipeline private: wgpu::BindGroupLayout m_perFlushBindingsLayout; - EmJsHandle m_vertexShaderHandle; - EmJsHandle m_fragmentShaderHandle; wgpu::RenderPipeline m_fillPipeline; wgpu::RenderPipeline m_strokePipeline; }; @@ -635,26 +905,31 @@ class RenderContextWebGPUImpl::DrawPipeline DrawPipeline(RenderContextWebGPUImpl* context, DrawType drawType, gpu::ShaderFeatures shaderFeatures, - const ContextOptions& contextOptions) + gpu::InterlockMode interlockMode, + gpu::ShaderMiscFlags shaderMiscFlags, + const gpu::PipelineState& pipelineState, + bool targetIsGLFBO0) { - PixelLocalStorageType plsType = context->m_contextOptions.plsType; + const bool fixedFunctionColorOutput = + enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::fixedFunctionColorOutput); wgpu::ShaderModule vertexShader, fragmentShader; - if (plsType == PixelLocalStorageType::subpassLoad || - plsType == PixelLocalStorageType::EXT_shader_pixel_local_storage || - contextOptions.disableStorageBuffers) +#ifdef RIVE_WAGYU + PixelLocalStorageType plsType = context->m_capabilities.plsType; + if (using_pls(interlockMode)) { - const char* language; + WGPUWagyuShaderLanguage language; const char* versionString; std::ostringstream glsl; auto addDefine = [&glsl](const char* name) { glsl << "#define " << name << " true\n"; }; - if (plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage) + if (context->m_capabilities.backendType == + wgpu::BackendType::OpenGLES) { - language = "glsl-raw"; + language = WGPUWagyuShaderLanguage_GLSLRAW; versionString = "#version 310 es"; - if (context->m_contextOptions.invertRenderTargetY) + if (!targetIsGLFBO0) { addDefine(GLSL_POST_INVERT_Y); } @@ -663,21 +938,21 @@ class RenderContextWebGPUImpl::DrawPipeline } else { - language = "glsl"; + language = WGPUWagyuShaderLanguage_GLSL; versionString = "#version 460"; - addDefine(GLSL_TARGET_VULKAN); + addDefine(GLSL_TARGET_SPIRV); } if (plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage) + PixelLocalStorageType::GL_EXT_shader_pixel_local_storage) { glsl << "#ifdef GL_EXT_shader_pixel_local_storage\n"; addDefine(GLSL_PLS_IMPL_EXT_NATIVE); glsl << "#else\n"; - glsl << "#extension GL_EXT_samplerless_texture_functions : " - "enable\n"; // If we are being compiled by SPIRV transpiler for // introspection, GL_EXT_shader_pixel_local_storage will not be // defined. + glsl << "#extension GL_EXT_samplerless_texture_functions : " + "enable\n"; addDefine(GLSL_PLS_IMPL_NONE); glsl << "#endif\n"; } @@ -685,11 +960,13 @@ class RenderContextWebGPUImpl::DrawPipeline { glsl << "#extension GL_EXT_samplerless_texture_functions : " "enable\n"; - addDefine(plsType == PixelLocalStorageType::subpassLoad - ? GLSL_PLS_IMPL_SUBPASS_LOAD - : GLSL_PLS_IMPL_NONE); + addDefine( + plsType == PixelLocalStorageType:: + VK_EXT_rasterization_order_attachment_access + ? GLSL_PLS_IMPL_SUBPASS_LOAD + : GLSL_PLS_IMPL_NONE); } - if (contextOptions.disableStorageBuffers) + if (context->m_capabilities.polyfillVertexStorageBuffers) { addDefine(GLSL_DISABLE_SHADER_STORAGE_BUFFERS); } @@ -698,14 +975,15 @@ class RenderContextWebGPUImpl::DrawPipeline case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: + addDefine(GLSL_DRAW_PATH); addDefine(GLSL_ENABLE_INSTANCE_INDEX); break; - case DrawType::atlasBlit: - addDefine(GLSL_ATLAS_BLIT); - [[fallthrough]]; case DrawType::interiorTriangulation: addDefine(GLSL_DRAW_INTERIOR_TRIANGLES); break; + case DrawType::atlasBlit: + addDefine(GLSL_ATLAS_BLIT); + break; case DrawType::imageRect: addDefine(GLSL_DRAW_IMAGE); addDefine(GLSL_DRAW_IMAGE_RECT); @@ -715,16 +993,6 @@ class RenderContextWebGPUImpl::DrawPipeline addDefine(GLSL_DRAW_IMAGE); addDefine(GLSL_DRAW_IMAGE_MESH); break; - case DrawType::atomicInitialize: - addDefine(GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS); - addDefine(GLSL_INITIALIZE_PLS); - RIVE_UNREACHABLE(); - break; - case DrawType::atomicResolve: - addDefine(GLSL_DRAW_RENDER_TARGET_UPDATE_BOUNDS); - addDefine(GLSL_RESOLVE_PLS); - RIVE_UNREACHABLE(); - break; case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -732,22 +1000,40 @@ class RenderContextWebGPUImpl::DrawPipeline case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); break; } for (size_t i = 0; i < gpu::kShaderFeatureCount; ++i) { - ShaderFeatures feature = static_cast(1 << i); - if (shaderFeatures & feature) + const auto feature = ShaderFeatures(1 << i); + if (enums::is_flag_set(shaderFeatures, feature)) { addDefine(GetShaderFeatureGLSLName(feature)); } } + if (fixedFunctionColorOutput) + { + addDefine(GLSL_FIXED_FUNCTION_COLOR_OUTPUT); + } + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::clockwiseFill)) + { + addDefine(GLSL_CLOCKWISE_FILL); + } + if (enums::is_flag_set(shaderMiscFlags, + gpu::ShaderMiscFlags::borrowedCoveragePass)) + { + addDefine(GLSL_BORROWED_COVERAGE_PASS); + } glsl << gpu::glsl::glsl << '\n'; glsl << gpu::glsl::constants << '\n'; + glsl << glsl::flush_uniforms << '\n'; glsl << gpu::glsl::common << '\n'; - if (shaderFeatures & ShaderFeatures::ENABLE_ADVANCED_BLEND) + if (enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_ADVANCED_BLEND)) { glsl << gpu::glsl::advanced_blend << '\n'; } @@ -762,21 +1048,35 @@ class RenderContextWebGPUImpl::DrawPipeline case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: - addDefine(GLSL_DRAW_PATH); + case DrawType::interiorTriangulation: glsl << gpu::glsl::draw_path_common << '\n'; - glsl << gpu::glsl::draw_path << '\n'; + glsl << gpu::glsl::draw_path_vert << '\n'; + if (interlockMode == gpu::InterlockMode::rasterOrdering) + { + glsl << gpu::glsl::draw_raster_order_path_frag << '\n'; + } + else + { + assert(interlockMode == gpu::InterlockMode::clockwise); + glsl << (enums::is_flag_set( + shaderMiscFlags, + gpu::ShaderMiscFlags::clipUpdateOnly) + ? gpu::glsl::draw_clockwise_clip_frag + : gpu::glsl::draw_clockwise_path_frag) + << '\n'; + } break; - case DrawType::interiorTriangulation: case DrawType::atlasBlit: glsl << gpu::glsl::draw_path_common << '\n'; - glsl << gpu::glsl::draw_path << '\n'; + glsl << gpu::glsl::draw_path_vert << '\n'; + glsl << gpu::glsl::draw_mesh_frag << '\n'; break; case DrawType::imageMesh: - glsl << gpu::glsl::draw_image_mesh << '\n'; + glsl << gpu::glsl::image_draw_uniforms << '\n'; + glsl << gpu::glsl::draw_image_mesh_vert << '\n'; + glsl << gpu::glsl::draw_mesh_frag << '\n'; break; case DrawType::imageRect: - case DrawType::atomicInitialize: - case DrawType::atomicResolve: case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: @@ -784,9 +1084,10 @@ class RenderContextWebGPUImpl::DrawPipeline case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::clipReset: + case DrawType::renderPassInitialize: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); - break; } std::ostringstream vertexGLSL; @@ -794,101 +1095,134 @@ class RenderContextWebGPUImpl::DrawPipeline vertexGLSL << "#pragma shader_stage(vertex)\n"; vertexGLSL << "#define " GLSL_VERTEX " true\n"; vertexGLSL << glsl.str(); - vertexShader = m_vertexShaderHandle.compileShaderModule( - context->m_device, - vertexGLSL.str().c_str(), - language); + vertexShader = compile_shader_module_wagyu(context->m_device, + vertexGLSL.str().c_str(), + language); std::ostringstream fragmentGLSL; fragmentGLSL << versionString << "\n"; fragmentGLSL << "#pragma shader_stage(fragment)\n"; fragmentGLSL << "#define " GLSL_FRAGMENT " true\n"; fragmentGLSL << glsl.str(); - fragmentShader = m_fragmentShaderHandle.compileShaderModule( - context->m_device, - fragmentGLSL.str().c_str(), - language); + fragmentShader = + compile_shader_module_wagyu(context->m_device, + fragmentGLSL.str().c_str(), + language); } else +#endif { + assert(interlockMode == gpu::InterlockMode::msaa); + Span vertCode; + Span fragCode; switch (drawType) { case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: - vertexShader = - m_vertexShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_path_vert, - std::size(draw_path_vert)); - fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_path_frag, - std::size(draw_path_frag)); - break; - case DrawType::interiorTriangulation: - vertexShader = - m_vertexShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_interior_triangles_vert, - std::size(draw_interior_triangles_vert)); - fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_interior_triangles_frag, - std::size(draw_interior_triangles_frag)); - break; - case DrawType::atlasBlit: - vertexShader = - m_vertexShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_atlas_blit_vert, - std::size(draw_atlas_blit_vert)); - fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_atlas_blit_frag, - std::size(draw_atlas_blit_frag)); - break; - case DrawType::imageRect: RIVE_UNREACHABLE(); - case DrawType::imageMesh: - vertexShader = - m_vertexShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_image_mesh_vert, - std::size(draw_image_mesh_vert)); - fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - context->m_device, - draw_image_mesh_frag, - std::size(draw_image_mesh_frag)); - break; - case DrawType::atomicInitialize: - case DrawType::atomicResolve: + + case DrawType::msaaOuterCubics: case DrawType::msaaStrokes: case DrawType::msaaMidpointFanBorrowedCoverage: case DrawType::msaaMidpointFans: case DrawType::msaaMidpointFanStencilReset: case DrawType::msaaMidpointFanPathsStencil: case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + vertCode = + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_CLIP_RECT) + ? make_span(spirv::draw_msaa_path_webgpu_vert) + : make_span( + spirv:: + draw_msaa_path_webgpu_noclipdistance_vert); + fragCode = + fixedFunctionColorOutput + ? make_span( + spirv::draw_msaa_path_webgpu_fixedcolor_frag) + : make_span(spirv::draw_msaa_path_webgpu_frag); + break; + + case DrawType::clipReset: + vertCode = make_span(spirv::draw_msaa_stencil_vert); + fragCode = make_span(spirv::draw_msaa_stencil_frag); + break; + + case DrawType::interiorTriangulation: + // Interior triangulation is not yet implemented for MSAA. + RIVE_UNREACHABLE(); + break; + + case DrawType::atlasBlit: + vertCode = + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_CLIP_RECT) + ? make_span(spirv::draw_msaa_atlas_blit_webgpu_vert) + : make_span( + spirv:: + draw_msaa_atlas_blit_webgpu_noclipdistance_vert); + fragCode = + fixedFunctionColorOutput + ? make_span( + spirv:: + draw_msaa_atlas_blit_webgpu_fixedcolor_frag) + : make_span( + spirv::draw_msaa_atlas_blit_webgpu_frag); + break; + + case DrawType::imageMesh: + vertCode = + enums::is_flag_set(shaderFeatures, + ShaderFeatures::ENABLE_CLIP_RECT) + ? make_span(spirv::draw_msaa_image_mesh_webgpu_vert) + : make_span( + spirv:: + draw_msaa_image_mesh_webgpu_noclipdistance_vert); + fragCode = + fixedFunctionColorOutput + ? make_span( + spirv:: + draw_msaa_image_mesh_webgpu_fixedcolor_frag) + : make_span( + spirv::draw_msaa_image_mesh_webgpu_frag); + break; + + case DrawType::renderPassInitialize: + // MSAA render passes get initialized by drawing the + // previous contents into the framebuffer. + // (LoadAction::preserveRenderTarget only.) + vertCode = make_span( + spirv::blit_texture_as_draw_filtered_webgpu_vert); + fragCode = make_span( + spirv::blit_texture_as_draw_filtered_webgpu_frag); + break; + + case DrawType::imageRect: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); } + vertexShader = compile_shader_module_spirv( + context->m_device, + vertCode.data(), + math::lossless_numeric_cast(vertCode.count())); + fragmentShader = compile_shader_module_spirv( + context->m_device, + fragCode.data(), + math::lossless_numeric_cast(fragCode.count())); } for (auto framebufferFormat : {wgpu::TextureFormat::BGRA8Unorm, wgpu::TextureFormat::RGBA8Unorm}) { int pipelineIdx = RenderPipelineIdx(framebufferFormat); - m_renderPipelines[pipelineIdx] = context->makeDrawPipeline( - drawType, - framebufferFormat, - vertexShader, - fragmentShader, - &m_renderPipelineHandles[pipelineIdx]); + m_renderPipelines[pipelineIdx] = + context->makeDrawPipeline(drawType, + interlockMode, + shaderMiscFlags, + framebufferFormat, + vertexShader, + fragmentShader, + pipelineState); } } @@ -906,23 +1240,98 @@ class RenderContextWebGPUImpl::DrawPipeline return framebufferFormat == wgpu::TextureFormat::BGRA8Unorm ? 1 : 0; } - EmJsHandle m_vertexShaderHandle; - EmJsHandle m_fragmentShaderHandle; wgpu::RenderPipeline m_renderPipelines[2]; - EmJsHandle m_renderPipelineHandles[2]; }; +#ifdef RIVE_WAGYU +static void parse_vendor_extensions(WGPUAdapter adapter, + WGPUDevice device, + RenderContextWebGPUImpl::Capabilities* caps) +{ + WGPUWagyuStringArray extensions = WGPU_WAGYU_STRING_ARRAY_INIT; + if (caps->backendType == wgpu::BackendType::Vulkan) + { + wgpuWagyuDeviceGetExtensions(device, &extensions); + for (size_t i = 0; i < extensions.stringCount; ++i) + { + if (!strcmp(extensions.strings[i].data, + "VK_EXT_rasterization_order_attachment_access")) + { + caps->VK_EXT_rasterization_order_attachment_access = true; + } + } + } + else if (caps->backendType == wgpu::BackendType::OpenGLES) + { + wgpuWagyuAdapterGetExtensions(adapter, &extensions); + for (size_t i = 0; i < extensions.stringCount; ++i) + { + if (!strcmp(extensions.strings[i].data, + "GL_EXT_shader_pixel_local_storage")) + { + caps->GL_EXT_shader_pixel_local_storage = true; + } + else if (!strcmp(extensions.strings[i].data, + "GL_EXT_shader_pixel_local_storage2")) + { + caps->GL_EXT_shader_pixel_local_storage2 = true; + } + } + } + wgpuWagyuStringArrayFreeMembers(extensions); +} +#endif + RenderContextWebGPUImpl::RenderContextWebGPUImpl( + wgpu::Adapter adapter, wgpu::Device device, wgpu::Queue queue, const ContextOptions& contextOptions) : m_device(device), m_queue(queue), m_contextOptions(contextOptions) { - // All backends currently use raster ordered shaders. - // TODO: update this flag once we have msaa and atomic modes. - m_platformFeatures.supportsRasterOrdering = true; +#ifdef RIVE_WAGYU + m_capabilities.backendType = static_cast( + wgpuWagyuAdapterGetBackend(adapter.Get())); + + parse_vendor_extensions(adapter.Get(), device.Get(), &m_capabilities); + + // Determine plsType. + if (m_capabilities.VK_EXT_rasterization_order_attachment_access) + { + m_capabilities.plsType = + PixelLocalStorageType::VK_EXT_rasterization_order_attachment_access; + m_platformFeatures.supportsRasterOrderingMode = true; + } + else if (m_capabilities.GL_EXT_shader_pixel_local_storage) + { + m_capabilities.plsType = + PixelLocalStorageType::GL_EXT_shader_pixel_local_storage; + m_platformFeatures.supportsRasterOrderingMode = true; + m_platformFeatures.supportsClockwiseMode = true; + m_platformFeatures.supportsClockwiseFixedFunctionMode = + m_capabilities.GL_EXT_shader_pixel_local_storage2; + } + + // Compatibility workarounds. + if (m_capabilities.backendType == wgpu::BackendType::OpenGLES && + gl_max_vertex_shader_storage_blocks() < 4) + { + // Rive requires 4 storage buffers in the vertex shader. Polyfill them + // if the hardware doesn't support this. + m_capabilities.polyfillVertexStorageBuffers = true; + } +#endif + m_platformFeatures.clipSpaceBottomUp = true; m_platformFeatures.framebufferBottomUp = false; + m_platformFeatures.msaaColorPreserveNeedsDraw = true; + + m_platformFeatures.supportsTextureCompressionBC = + m_device.HasFeature(wgpu::FeatureName::TextureCompressionBC); + m_platformFeatures.supportsTextureCompressionASTC = + m_device.HasFeature(wgpu::FeatureName::TextureCompressionASTC); + m_platformFeatures.supportsTextureCompressionETC2 = + m_device.HasFeature(wgpu::FeatureName::TextureCompressionETC2); } void RenderContextWebGPUImpl::initGPUObjects() @@ -937,7 +1346,8 @@ void RenderContextWebGPUImpl::initGPUObjects() .type = wgpu::BufferBindingType::Uniform, }, }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupLayoutEntry{ .binding = PATH_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -947,6 +1357,7 @@ void RenderContextWebGPUImpl::initGPUObjects() .viewDimension = wgpu::TextureViewDimension::e2D, }, } : +#endif wgpu::BindGroupLayoutEntry{ .binding = PATH_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -955,7 +1366,8 @@ void RenderContextWebGPUImpl::initGPUObjects() .type = wgpu::BufferBindingType::ReadOnlyStorage, }, }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupLayoutEntry{ .binding = PAINT_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -965,6 +1377,7 @@ void RenderContextWebGPUImpl::initGPUObjects() .viewDimension = wgpu::TextureViewDimension::e2D, }, } : +#endif wgpu::BindGroupLayoutEntry{ .binding = PAINT_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -973,7 +1386,8 @@ void RenderContextWebGPUImpl::initGPUObjects() .type = wgpu::BufferBindingType::ReadOnlyStorage, }, }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupLayoutEntry{ .binding = PAINT_AUX_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -983,6 +1397,7 @@ void RenderContextWebGPUImpl::initGPUObjects() .viewDimension = wgpu::TextureViewDimension::e2D, }, } : +#endif wgpu::BindGroupLayoutEntry{ .binding = PAINT_AUX_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -991,7 +1406,8 @@ void RenderContextWebGPUImpl::initGPUObjects() .type = wgpu::BufferBindingType::ReadOnlyStorage, }, }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupLayoutEntry{ .binding = CONTOUR_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -1001,6 +1417,7 @@ void RenderContextWebGPUImpl::initGPUObjects() .viewDimension = wgpu::TextureViewDimension::e2D, }, } : +#endif wgpu::BindGroupLayoutEntry{ .binding = CONTOUR_BUFFER_IDX, .visibility = wgpu::ShaderStage::Vertex, @@ -1057,8 +1474,17 @@ void RenderContextWebGPUImpl::initGPUObjects() .minBindingSize = sizeof(gpu::ImageDrawUniforms), }, }, + { + .binding = DST_COLOR_TEXTURE_IDX, + .visibility = wgpu::ShaderStage::Fragment, + .texture = + { + .sampleType = wgpu::TextureSampleType::Float, + .viewDimension = wgpu::TextureViewDimension::e2D, + }, + }, }}; - static_assert(DRAW_BINDINGS_COUNT == 10); + static_assert(DRAW_BINDINGS_COUNT == 11); static_assert(sizeof(m_perFlushBindingLayouts) == DRAW_BINDINGS_COUNT * sizeof(wgpu::BindGroupLayoutEntry)); @@ -1080,6 +1506,11 @@ void RenderContextWebGPUImpl::initGPUObjects() .viewDimension = wgpu::TextureViewDimension::e2D, }, }, + { + .binding = WEBGPU_IMAGE_SAMPLER_IDX, + .visibility = wgpu::ShaderStage::Fragment, + .sampler = {.type = wgpu::SamplerBindingType::Filtering}, + }, }; wgpu::BindGroupLayoutDescriptor perDrawBindingsDesc = { @@ -1116,14 +1547,6 @@ void RenderContextWebGPUImpl::initGPUObjects() .type = wgpu::SamplerBindingType::Filtering, }, }, - { - .binding = IMAGE_TEXTURE_IDX, - .visibility = wgpu::ShaderStage::Fragment, - .sampler = - { - .type = wgpu::SamplerBindingType::Filtering, - }, - }, }; wgpu::BindGroupLayoutDescriptor samplerBindingsDesc = { @@ -1131,7 +1554,7 @@ void RenderContextWebGPUImpl::initGPUObjects() .entries = drawBindingSamplerLayouts, }; - m_drawBindGroupLayouts[IMMUTABLE_SAMPLER_BINDINGS_SET] = + m_drawBindGroupLayouts[WEBGPU_SAMPLER_BINDINGS_SET] = m_device.CreateBindGroupLayout(&samplerBindingsDesc); wgpu::SamplerDescriptor linearSamplerDesc = { @@ -1144,15 +1567,23 @@ void RenderContextWebGPUImpl::initGPUObjects() m_linearSampler = m_device.CreateSampler(&linearSamplerDesc); - wgpu::SamplerDescriptor mipmapSamplerDesc = { - .addressModeU = wgpu::AddressMode::ClampToEdge, - .addressModeV = wgpu::AddressMode::ClampToEdge, - .magFilter = wgpu::FilterMode::Linear, - .minFilter = wgpu::FilterMode::Linear, - .mipmapFilter = wgpu::MipmapFilterMode::Nearest, - }; + for (size_t i = 0; i < ImageSampler::MAX_SAMPLER_PERMUTATIONS; ++i) + { + ImageWrap wrapX = ImageSampler::GetWrapXOptionFromKey(i); + ImageWrap wrapY = ImageSampler::GetWrapYOptionFromKey(i); + ImageFilter filter = ImageSampler::GetFilterOptionFromKey(i); + wgpu::FilterMode minMagFilter = webgpu_filter_mode(filter); + + wgpu::SamplerDescriptor samplerDesc = { + .addressModeU = webgpu_address_mode(wrapX), + .addressModeV = webgpu_address_mode(wrapY), + .magFilter = minMagFilter, + .minFilter = minMagFilter, + .mipmapFilter = webgpu_mipmap_filter_mode(filter), + }; - m_mipmapSampler = m_device.CreateSampler(&mipmapSamplerDesc); + m_imageSamplers[i] = m_device.CreateSampler(&samplerDesc); + } wgpu::BindGroupEntry samplerBindingEntries[] = { { @@ -1167,33 +1598,58 @@ void RenderContextWebGPUImpl::initGPUObjects() .binding = ATLAS_TEXTURE_IDX, .sampler = m_linearSampler, }, - { - .binding = IMAGE_TEXTURE_IDX, - .sampler = m_mipmapSampler, - }, }; wgpu::BindGroupDescriptor samplerBindGroupDesc = { - .layout = m_drawBindGroupLayouts[IMMUTABLE_SAMPLER_BINDINGS_SET], + .layout = m_drawBindGroupLayouts[WEBGPU_SAMPLER_BINDINGS_SET], .entryCount = std::size(samplerBindingEntries), .entries = samplerBindingEntries, }; m_samplerBindings = m_device.CreateBindGroup(&samplerBindGroupDesc); - bool needsTextureBindings = - m_contextOptions.plsType == PixelLocalStorageType::subpassLoad; - if (needsTextureBindings) +#ifdef RIVE_WAGYU + const bool supportsPLSInputAttachmentBindings = + m_capabilities.plsType == + PixelLocalStorageType::VK_EXT_rasterization_order_attachment_access; + if (supportsPLSInputAttachmentBindings) + { + WGPUWagyuInputTextureBindingLayout inputAttachmentLayout = + WGPU_WAGYU_INPUT_TEXTURE_BINDING_LAYOUT_INIT; + inputAttachmentLayout.viewDimension = WGPUTextureViewDimension_2D; + + WGPUBindGroupLayoutEntry inputAttachments[4]; + memset(inputAttachments, 0, sizeof(inputAttachments)); + for (uint32_t i = 0; i < std::size(inputAttachments); ++i) + { + inputAttachments[i].nextInChain = &inputAttachmentLayout.chain; + inputAttachments[i].binding = i; + inputAttachments[i].visibility = WGPUShaderStage_Fragment; + } + + WGPUBindGroupLayoutDescriptor inputAttachmentsLayoutDesc = + WGPU_BIND_GROUP_LAYOUT_DESCRIPTOR_INIT; + inputAttachmentsLayoutDesc.entryCount = std::size(inputAttachments), + inputAttachmentsLayoutDesc.entries = inputAttachments, + + m_drawBindGroupLayouts[PLS_TEXTURE_BINDINGS_SET] = + wgpu::BindGroupLayout::Acquire( + wgpuDeviceCreateBindGroupLayout(m_device.Get(), + &inputAttachmentsLayoutDesc)); + } + else { m_drawBindGroupLayouts[PLS_TEXTURE_BINDINGS_SET] = - initTextureBindGroup(); + m_emptyBindingsLayout; } +#endif wgpu::PipelineLayoutDescriptor drawPipelineLayoutDesc = { - .bindGroupLayoutCount = static_cast( - needsTextureBindings ? BINDINGS_SET_COUNT : BINDINGS_SET_COUNT - 1), + .bindGroupLayoutCount = static_cast(WEBGPU_BINDINGS_SET_COUNT), .bindGroupLayouts = m_drawBindGroupLayouts, }; + static_assert(PLS_TEXTURE_BINDINGS_SET == WEBGPU_BINDINGS_SET_COUNT - 2); + static_assert(WEBGPU_SAMPLER_BINDINGS_SET == WEBGPU_BINDINGS_SET_COUNT - 1); m_drawPipelineLayout = m_device.CreatePipelineLayout(&drawPipelineLayoutDesc); @@ -1201,14 +1657,16 @@ void RenderContextWebGPUImpl::initGPUObjects() wgpu::BindGroupLayoutDescriptor emptyBindingsDesc = {}; m_emptyBindingsLayout = m_device.CreateBindGroupLayout(&emptyBindingsDesc); - if (m_contextOptions.plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage) +#ifdef RIVE_WAGYU + const bool supportsShaderPixelLocalStorageEXT = + m_capabilities.plsType == + PixelLocalStorageType::GL_EXT_shader_pixel_local_storage; + if (supportsShaderPixelLocalStorageEXT) { // We have to manually implement load/store operations from a shader // when using EXT_shader_pixel_local_storage. std::ostringstream glsl; glsl << "#version 310 es\n"; - glsl << "#pragma shader_stage(vertex)\n"; glsl << "#define " GLSL_VERTEX " true\n"; // If we are being compiled by SPIRV transpiler for introspection, use // gl_VertexIndex instead of gl_VertexID. @@ -1216,18 +1674,14 @@ void RenderContextWebGPUImpl::initGPUObjects() glsl << "#define gl_VertexID gl_VertexIndex\n"; glsl << "#endif\n"; glsl << "#define " GLSL_ENABLE_CLIPPING " true\n"; - if (m_contextOptions.invertRenderTargetY) - { - glsl << "#define " GLSL_POST_INVERT_Y " true\n"; - } BuildLoadStoreEXTGLSL(glsl, LoadStoreActionsEXT::none); m_loadStoreEXTVertexShader = - m_loadStoreEXTVertexShaderHandle.compileShaderModule( - m_device, - glsl.str().c_str(), - "glsl-raw"); + compile_shader_module_wagyu(m_device, + glsl.str().c_str(), + WGPUWagyuShaderLanguage_GLSLRAW); m_loadStoreEXTUniforms = makeUniformBufferRing(sizeof(float) * 4); } +#endif wgpu::BufferDescriptor tessSpanIndexBufferDesc = { .usage = wgpu::BufferUsage::Index, @@ -1271,8 +1725,8 @@ void RenderContextWebGPUImpl::initGPUObjects() }; m_featherTexture = m_device.CreateTexture(&featherTextureDesc); - wgpu::ImageCopyTexture dest = {.texture = m_featherTexture}; - wgpu::TextureDataLayout layout = { + wgpu::TexelCopyTextureInfo dest = {.texture = m_featherTexture}; + wgpu::TexelCopyBufferLayout layout = { .bytesPerRow = sizeof(gpu::g_gaussianIntegralTableF16), }; wgpu::Extent3D extent = { @@ -1292,16 +1746,15 @@ void RenderContextWebGPUImpl::initGPUObjects() &extent); m_featherTextureView = m_featherTexture.CreateView(); - wgpu::TextureDescriptor nullImagePaintTextureDesc = { + wgpu::TextureDescriptor nullTextureDesc = { .usage = wgpu::TextureUsage::TextureBinding, .dimension = wgpu::TextureDimension::e2D, .size = {1, 1}, .format = wgpu::TextureFormat::RGBA8Unorm, }; - m_nullImagePaintTexture = - m_device.CreateTexture(&nullImagePaintTextureDesc); - m_nullImagePaintTextureView = m_nullImagePaintTexture.CreateView(); + m_nullTexture = m_device.CreateTexture(&nullTextureDesc); + m_nullTextureView = m_nullTexture.CreateView(); m_colorRampPipeline = std::make_unique(this); m_tessellatePipeline = std::make_unique(this); @@ -1312,33 +1765,164 @@ RenderContextWebGPUImpl::~RenderContextWebGPUImpl() {} RenderTargetWebGPU::RenderTargetWebGPU( wgpu::Device device, + const RenderContextWebGPUImpl::Capabilities& capabilities, wgpu::TextureFormat framebufferFormat, uint32_t width, - uint32_t height, - wgpu::TextureUsage additionalTextureFlags) : - RenderTarget(width, height), m_framebufferFormat(framebufferFormat) + uint32_t height) : + RenderTarget(width, height), + m_device(std::move(device)), + m_framebufferFormat(framebufferFormat), + m_transientPLSUsage(wgpu::TextureUsage::RenderAttachment), + m_targetTextureView{} // Will be configured later by setTargetTexture(). { - wgpu::TextureDescriptor desc = { - .usage = wgpu::TextureUsage::RenderAttachment | additionalTextureFlags, - .size = {static_cast(width), static_cast(height)}, - }; +#ifdef RIVE_WAGYU + if (capabilities.plsType == + RenderContextWebGPUImpl::PixelLocalStorageType:: + VK_EXT_rasterization_order_attachment_access) + { + m_transientPLSUsage |= static_cast( + WGPUTextureUsage_WagyuInputAttachment | + WGPUTextureUsage_WagyuTransientAttachment); + } +#endif +} - desc.format = wgpu::TextureFormat::R32Uint; - m_coverageTexture = device.CreateTexture(&desc); - m_clipTexture = device.CreateTexture(&desc); +void RenderTargetWebGPU::setTargetTextureView(wgpu::TextureView textureView, + wgpu::Texture texture) +{ + m_targetTexture = texture; + m_targetTextureView = textureView; +} - desc.format = m_framebufferFormat; - m_scratchColorTexture = device.CreateTexture(&desc); +wgpu::TextureView RenderTargetWebGPU::coverageTextureView() +{ + if (m_coverageTextureView == nullptr) + { + wgpu::TextureDescriptor desc = { + .usage = m_transientPLSUsage, + .size = {static_cast(width()), + static_cast(height())}, + .format = wgpu::TextureFormat::R32Uint, + }; + m_coverageTexture = m_device.CreateTexture(&desc); + m_coverageTextureView = m_coverageTexture.CreateView(); + } + return m_coverageTextureView; +} - m_targetTextureView = {}; // Will be configured later by setTargetTexture(). - m_coverageTextureView = m_coverageTexture.CreateView(); - m_clipTextureView = m_clipTexture.CreateView(); - m_scratchColorTextureView = m_scratchColorTexture.CreateView(); +wgpu::TextureView RenderTargetWebGPU::clipTextureView() +{ + if (m_clipTexture == nullptr) + { + wgpu::TextureDescriptor desc = { + .usage = m_transientPLSUsage, + .size = {static_cast(width()), + static_cast(height())}, + .format = wgpu::TextureFormat::R32Uint, + }; + m_clipTexture = m_device.CreateTexture(&desc); + m_clipTextureView = m_clipTexture.CreateView(); + } + return m_clipTextureView; } -void RenderTargetWebGPU::setTargetTextureView(wgpu::TextureView textureView) +wgpu::TextureView RenderTargetWebGPU::scratchColorTextureView() { - m_targetTextureView = textureView; + if (m_scratchColorTexture == nullptr) + { + wgpu::TextureDescriptor desc = { + .usage = m_transientPLSUsage, + .size = {static_cast(width()), + static_cast(height())}, + .format = m_framebufferFormat, + }; + m_scratchColorTexture = m_device.CreateTexture(&desc); + m_scratchColorTextureView = m_scratchColorTexture.CreateView(); + } + return m_scratchColorTextureView; +} + +wgpu::TextureView RenderTargetWebGPU::msaaColorTextureView() +{ + if (m_msaaColorTexture == nullptr) + { + wgpu::TextureDescriptor desc = { + .usage = wgpu::TextureUsage::RenderAttachment, + .size = {static_cast(width()), + static_cast(height())}, + .format = m_framebufferFormat, + .sampleCount = MSAA_SAMPLE_COUNT, + }; + m_msaaColorTexture = m_device.CreateTexture(&desc); + m_msaaColorTextureView = m_msaaColorTexture.CreateView(); + } + return m_msaaColorTextureView; +} + +wgpu::TextureView RenderTargetWebGPU::msaaDepthStencilTextureView() +{ + if (m_msaaDepthStencilTexture == nullptr) + { + wgpu::TextureDescriptor desc = { + .usage = wgpu::TextureUsage::RenderAttachment, + .size = {static_cast(width()), + static_cast(height())}, + .format = wgpu::TextureFormat::Depth24PlusStencil8, + .sampleCount = MSAA_SAMPLE_COUNT, + }; + m_msaaDepthStencilTexture = m_device.CreateTexture(&desc); + m_msaaDepthStencilTextureView = m_msaaDepthStencilTexture.CreateView(); + } + return m_msaaDepthStencilTextureView; +} + +wgpu::Texture RenderTargetWebGPU::dstColorTexture() +{ + if (m_dstColorTexture == nullptr) + { + wgpu::TextureDescriptor desc = { + .usage = wgpu::TextureUsage::CopyDst | + wgpu::TextureUsage::TextureBinding, + .size = {static_cast(width()), + static_cast(height())}, + .format = wgpu::TextureFormat::RGBA8Unorm, + .sampleCount = 1, + }; + m_dstColorTexture = m_device.CreateTexture(&desc); + } + return m_dstColorTexture; +} + +wgpu::TextureView RenderTargetWebGPU::dstColorTextureView() +{ + if (m_dstColorTextureView == nullptr) + { + m_dstColorTextureView = dstColorTexture().CreateView(); + } + return m_dstColorTextureView; +} + +void RenderTargetWebGPU::copyTargetToDstColorTexture( + wgpu::CommandEncoder commandEncoder, + IAABB dstReadBounds) +{ + const wgpu::Origin3D origin = { + .x = static_cast(dstReadBounds.left), + .y = static_cast(dstReadBounds.top), + }; + const wgpu::TexelCopyTextureInfo src = { + .texture = m_targetTexture, + .origin = origin, + }; + const wgpu::TexelCopyTextureInfo dst = { + .texture = dstColorTexture(), + .origin = origin, + }; + const wgpu::Extent3D copySize = { + .width = static_cast(dstReadBounds.width()), + .height = static_cast(dstReadBounds.height()), + }; + commandEncoder.CopyTextureToTexture(&src, &dst, ©Size); } rcp RenderContextWebGPUImpl::makeRenderTarget( @@ -1347,12 +1931,42 @@ rcp RenderContextWebGPUImpl::makeRenderTarget( uint32_t height) { return rcp(new RenderTargetWebGPU(m_device, + m_capabilities, framebufferFormat, width, - height, - wgpu::TextureUsage::None)); + height)); } +#ifdef RIVE_CANVAS +rcp RenderContextWebGPUImpl::makeRenderCanvas(uint32_t width, + uint32_t height) +{ + wgpu::TextureDescriptor textureDesc = { + .usage = wgpu::TextureUsage::TextureBinding | + wgpu::TextureUsage::RenderAttachment | + wgpu::TextureUsage::CopySrc, + .dimension = wgpu::TextureDimension::e2D, + .size = {width, height}, + .format = wgpu::TextureFormat::RGBA8Unorm, + }; + + auto texture = + make_rcp(width, + height, + m_device.CreateTexture(&textureDesc)); + + auto renderTarget = + makeRenderTarget(wgpu::TextureFormat::RGBA8Unorm, width, height); + renderTarget->setTargetTextureView(texture->textureView(), + texture->texture()); + + auto renderImage = make_rcp(std::move(texture)); + + return make_rcp(std::move(renderImage), + std::move(renderTarget)); +} +#endif + class RenderBufferWebGPUImpl : public RenderBuffer { public: @@ -1366,7 +1980,8 @@ class RenderBufferWebGPUImpl : public RenderBuffer m_queue(queue) { bool mappedOnceAtInitialization = - flags() & RenderBufferFlags::mappedOnceAtInitialization; + enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization); int bufferCount = mappedOnceAtInitialization ? 1 : gpu::kBufferRingSize; wgpu::BufferDescriptor desc = { .usage = type() == RenderBufferType::index @@ -1397,7 +2012,8 @@ class RenderBufferWebGPUImpl : public RenderBuffer m_submittedBufferIdx = (m_submittedBufferIdx + 1) % gpu::kBufferRingSize; assert(m_buffers[m_submittedBufferIdx] != nullptr); - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { return m_buffers[m_submittedBufferIdx].GetMappedRange(); } @@ -1413,7 +2029,8 @@ class RenderBufferWebGPUImpl : public RenderBuffer void onUnmap() override { - if (flags() & RenderBufferFlags::mappedOnceAtInitialization) + if (enums::is_flag_set(flags(), + RenderBufferFlags::mappedOnceAtInitialization)) { m_buffers[m_submittedBufferIdx].Unmap(); } @@ -1446,22 +2063,7 @@ rcp RenderContextWebGPUImpl::makeRenderBuffer( sizeInBytes); } -class TextureWebGPUImpl : public Texture -{ -public: - TextureWebGPUImpl(uint32_t width, uint32_t height, wgpu::Texture texture) : - Texture(width, height), - m_texture(std::move(texture)), - m_textureView(m_texture.CreateView()) - {} - - wgpu::TextureView textureView() const { return m_textureView; } - -private: - wgpu::Texture m_texture; - wgpu::TextureView m_textureView; -}; - +#ifndef RIVE_WAGYU // Blits texture-to-texture using a draw command. class RenderContextWebGPUImpl::BlitTextureAsDrawPipeline { @@ -1472,7 +2074,7 @@ class RenderContextWebGPUImpl::BlitTextureAsDrawPipeline wgpu::BindGroupLayoutEntry bindingEntries[] = { { - .binding = 0, + .binding = IMAGE_TEXTURE_IDX, .visibility = wgpu::ShaderStage::Fragment, .texture = { @@ -1481,7 +2083,7 @@ class RenderContextWebGPUImpl::BlitTextureAsDrawPipeline }, }, { - .binding = 1, + .binding = WEBGPU_IMAGE_SAMPLER_IDX, .visibility = wgpu::ShaderStage::Fragment, .sampler = { @@ -1495,27 +2097,31 @@ class RenderContextWebGPUImpl::BlitTextureAsDrawPipeline .entries = bindingEntries, }; - m_bindGroupLayout = device.CreateBindGroupLayout(&bindingsDesc); + m_perDrawBindGroupLayout = device.CreateBindGroupLayout(&bindingsDesc); + + wgpu::BindGroupLayout layouts[] = { + impl->m_emptyBindingsLayout, + m_perDrawBindGroupLayout, + }; + static_assert(PER_DRAW_BINDINGS_SET == 1); wgpu::PipelineLayoutDescriptor pipelineLayoutDesc = { - .bindGroupLayoutCount = 1, - .bindGroupLayouts = &m_bindGroupLayout, + .bindGroupLayoutCount = std::size(layouts), + .bindGroupLayouts = layouts, }; wgpu::PipelineLayout pipelineLayout = device.CreatePipelineLayout(&pipelineLayoutDesc); - wgpu::ShaderModule vertexShader = - m_vertexShaderHandle.compileSPIRVShaderModule( - device, - blit_texture_as_draw_vert, - std::size(blit_texture_as_draw_vert)); + wgpu::ShaderModule vertexShader = compile_shader_module_spirv( + device, + spirv::blit_texture_as_draw_filtered_webgpu_vert, + std::size(spirv::blit_texture_as_draw_filtered_webgpu_vert)); - wgpu::ShaderModule fragmentShader = - m_fragmentShaderHandle.compileSPIRVShaderModule( - device, - blit_texture_as_draw_frag, - std::size(blit_texture_as_draw_frag)); + wgpu::ShaderModule fragmentShader = compile_shader_module_spirv( + device, + spirv::blit_texture_as_draw_filtered_webgpu_frag, + std::size(spirv::blit_texture_as_draw_filtered_webgpu_frag)); wgpu::ColorTargetState colorTargetState = { .format = wgpu::TextureFormat::RGBA8Unorm, @@ -1529,6 +2135,7 @@ class RenderContextWebGPUImpl::BlitTextureAsDrawPipeline }; wgpu::RenderPipelineDescriptor desc = { + .label = "RIVE_BlitTextureAsDrawPipeline", .layout = pipelineLayout, .vertex = { @@ -1545,86 +2152,86 @@ class RenderContextWebGPUImpl::BlitTextureAsDrawPipeline m_renderPipeline = device.CreateRenderPipeline(&desc); } - const wgpu::BindGroupLayout& bindGroupLayout() const + const wgpu::BindGroupLayout& perDrawBindGroupLayout() const { - return m_bindGroupLayout; + return m_perDrawBindGroupLayout; } wgpu::RenderPipeline renderPipeline() const { return m_renderPipeline; } private: - wgpu::BindGroupLayout m_bindGroupLayout; - EmJsHandle m_vertexShaderHandle; - EmJsHandle m_fragmentShaderHandle; + wgpu::BindGroupLayout m_perDrawBindGroupLayout; wgpu::RenderPipeline m_renderPipeline; }; +#endif void RenderContextWebGPUImpl::generateMipmaps(wgpu::Texture texture) { wgpu::CommandEncoder mipEncoder = m_device.CreateCommandEncoder(); - if (!generate_mipmaps_builtin(mipEncoder, texture)) +#ifdef RIVE_WAGYU + wgpuWagyuCommandEncoderGenerateMipmap(mipEncoder.Get(), texture.Get()); +#else + // Generate the mipmaps manually by drawing each layer. + if (m_blitTextureAsDrawPipeline == nullptr) { - // Generate the mipmaps manually by drawing each layer. - if (m_blitTextureAsDrawPipeline == nullptr) - { - m_blitTextureAsDrawPipeline = - std::make_unique(this); - } + m_blitTextureAsDrawPipeline = + std::make_unique(this); + } - wgpu::TextureViewDescriptor textureViewDesc = { - .baseMipLevel = 0, - .mipLevelCount = 1, - }; + wgpu::TextureViewDescriptor textureViewDesc = { + .baseMipLevel = 0, + .mipLevelCount = 1, + }; - wgpu::TextureView dstView, - srcView = texture.CreateView(&textureViewDesc); + wgpu::TextureView dstView, srcView = texture.CreateView(&textureViewDesc); - for (uint32_t level = 1; level < texture.GetMipLevelCount(); - ++level, srcView = std::move(dstView)) - { - textureViewDesc.baseMipLevel = level; - dstView = texture.CreateView(&textureViewDesc); + for (uint32_t level = 1; level < texture.GetMipLevelCount(); + ++level, srcView = std::move(dstView)) + { + textureViewDesc.baseMipLevel = level; + dstView = texture.CreateView(&textureViewDesc); - wgpu::RenderPassColorAttachment attachment = { - .view = dstView, - .loadOp = wgpu::LoadOp::Clear, - .storeOp = wgpu::StoreOp::Store, - .clearValue = {}, - }; + wgpu::RenderPassColorAttachment attachment = { + .view = dstView, + .loadOp = wgpu::LoadOp::Clear, + .storeOp = wgpu::StoreOp::Store, + .clearValue = {}, + }; - wgpu::RenderPassDescriptor mipPassDesc = { - .colorAttachmentCount = 1, - .colorAttachments = &attachment, - }; + wgpu::RenderPassDescriptor mipPassDesc = { + .label = "RIVE_MipMap_Generation_Pass", + .colorAttachmentCount = 1, + .colorAttachments = &attachment, + }; - wgpu::RenderPassEncoder mipPass = - mipEncoder.BeginRenderPass(&mipPassDesc); + wgpu::RenderPassEncoder mipPass = + mipEncoder.BeginRenderPass(&mipPassDesc); - wgpu::BindGroupEntry bindingEntries[] = { - { - .binding = 0, - .textureView = srcView, - }, - { - .binding = 1, - .sampler = m_linearSampler, - }, - }; + wgpu::BindGroupEntry bindingEntries[] = { + { + .binding = IMAGE_TEXTURE_IDX, + .textureView = srcView, + }, + { + .binding = WEBGPU_IMAGE_SAMPLER_IDX, + .sampler = m_linearSampler, + }, + }; - wgpu::BindGroupDescriptor bindGroupDesc = { - .layout = m_blitTextureAsDrawPipeline->bindGroupLayout(), - .entryCount = std::size(bindingEntries), - .entries = bindingEntries, - }; + wgpu::BindGroupDescriptor bindGroupDesc = { + .layout = m_blitTextureAsDrawPipeline->perDrawBindGroupLayout(), + .entryCount = std::size(bindingEntries), + .entries = bindingEntries, + }; - wgpu::BindGroup bindings = m_device.CreateBindGroup(&bindGroupDesc); - mipPass.SetBindGroup(0, bindings); + wgpu::BindGroup bindings = m_device.CreateBindGroup(&bindGroupDesc); + mipPass.SetBindGroup(PER_DRAW_BINDINGS_SET, bindings); - mipPass.SetPipeline(m_blitTextureAsDrawPipeline->renderPipeline()); - mipPass.Draw(4); - mipPass.End(); - } + mipPass.SetPipeline(m_blitTextureAsDrawPipeline->renderPipeline()); + mipPass.Draw(4); + mipPass.End(); } +#endif wgpu::CommandBuffer commands = mipEncoder.Finish(); m_queue.Submit(1, &commands); @@ -1634,8 +2241,14 @@ rcp RenderContextWebGPUImpl::makeImageTexture( uint32_t width, uint32_t height, uint32_t mipLevelCount, + GPUTextureFormat format, const uint8_t imageDataRGBAPremul[]) { + if (format != GPUTextureFormat::rgba32) + { + assert(!"unsupported format"); + return nullptr; + } wgpu::TextureDescriptor textureDesc = { .usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst, @@ -1646,13 +2259,19 @@ rcp RenderContextWebGPUImpl::makeImageTexture( }; if (mipLevelCount > 1) { +#ifdef RIVE_WAGYU + // Wagyu generates mipmaps with copies. + textureDesc.usage |= wgpu::TextureUsage::CopySrc; +#else + // Unextended WebGPU implements mipmaps with draws. textureDesc.usage |= wgpu::TextureUsage::RenderAttachment; +#endif } wgpu::Texture texture = m_device.CreateTexture(&textureDesc); - wgpu::ImageCopyTexture dest = {.texture = texture}; - wgpu::TextureDataLayout layout = {.bytesPerRow = width * 4}; + wgpu::TexelCopyTextureInfo dest = {.texture = texture}; + wgpu::TexelCopyBufferLayout layout = {.bytesPerRow = width * 4}; wgpu::Extent3D extent = {width, height}; m_queue.WriteTexture(&dest, imageDataRGBAPremul, @@ -1773,11 +2392,11 @@ class StorageTextureBufferWebGPU : public BufferWebGPU void updateTextureFromBuffer(size_t bindingSizeInBytes, size_t offsetSizeInBytes, - wgpu::CommandEncoder encoder) const + wgpu::CommandEncoder commandEncoder) const { auto [updateWidth, updateHeight] = gpu::StorageTextureSize(bindingSizeInBytes, m_bufferStructure); - wgpu::ImageCopyBuffer srcBuffer = { + wgpu::TexelCopyBufferInfo srcBuffer = { .layout = { .offset = offsetSizeInBytes, @@ -1787,7 +2406,7 @@ class StorageTextureBufferWebGPU : public BufferWebGPU }, .buffer = submittedBuffer(), }; - wgpu::ImageCopyTexture dstTexture = { + wgpu::TexelCopyTextureInfo dstTexture = { .texture = m_texture, .origin = {0, 0, 0}, }; @@ -1795,7 +2414,7 @@ class StorageTextureBufferWebGPU : public BufferWebGPU .width = updateWidth, .height = updateHeight, }; - encoder.CopyBufferToTexture(&srcBuffer, &dstTexture, ©Size); + commandEncoder.CopyBufferToTexture(&srcBuffer, &dstTexture, ©Size); } wgpu::TextureView textureView() const { return m_textureView; } @@ -1822,7 +2441,8 @@ std::unique_ptr RenderContextWebGPUImpl::makeStorageBufferRing( size_t capacityInBytes, gpu::StorageBufferStructure bufferStructure) { - if (m_contextOptions.disableStorageBuffers) +#ifdef RIVE_WAGYU + if (m_capabilities.polyfillVertexStorageBuffers) { return std::make_unique(m_device, m_queue, @@ -1830,6 +2450,7 @@ std::unique_ptr RenderContextWebGPUImpl::makeStorageBufferRing( bufferStructure); } else +#endif { return std::make_unique(m_device, m_queue, @@ -1899,215 +2520,460 @@ void RenderContextWebGPUImpl::resizeAtlasTexture(uint32_t width, } wgpu::RenderPipeline RenderContextWebGPUImpl::makeDrawPipeline( - rive::gpu::DrawType drawType, + gpu::DrawType drawType, + gpu::InterlockMode interlockMode, + gpu::ShaderMiscFlags shaderMiscFlags, wgpu::TextureFormat framebufferFormat, wgpu::ShaderModule vertexShader, wgpu::ShaderModule fragmentShader, - EmJsHandle* pipelineJSHandleIfNeeded) + const gpu::PipelineState& pipelineState) { - std::vector attrs; - std::vector vertexBufferLayouts; + std::vector attrs; + std::vector vertexBufferLayouts; + WGPUPrimitiveTopology topology; switch (drawType) { case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: + case DrawType::msaaOuterCubics: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: { attrs = { - { - .format = wgpu::VertexFormat::Float32x4, + WGPUVertexAttribute{ + .format = WGPUVertexFormat_Float32x4, .offset = 0, .shaderLocation = 0, }, - { - .format = wgpu::VertexFormat::Float32x4, + WGPUVertexAttribute{ + .format = WGPUVertexFormat_Float32x4, .offset = 4 * sizeof(float), .shaderLocation = 1, }, }; - vertexBufferLayouts = { - { - .arrayStride = sizeof(gpu::PatchVertex), - .stepMode = wgpu::VertexStepMode::Vertex, - .attributeCount = std::size(attrs), - .attributes = attrs.data(), - }, - }; + vertexBufferLayouts = {WGPU_VERTEX_BUFFER_LAYOUT_INIT}; + vertexBufferLayouts[0].attributeCount = std::size(attrs); + vertexBufferLayouts[0].attributes = attrs.data(); + vertexBufferLayouts[0].arrayStride = sizeof(gpu::PatchVertex); + vertexBufferLayouts[0].stepMode = WGPUVertexStepMode_Vertex; + + topology = WGPUPrimitiveTopology_TriangleList; break; } + case DrawType::clipReset: case DrawType::interiorTriangulation: case DrawType::atlasBlit: { attrs = { - { - .format = wgpu::VertexFormat::Float32x3, + WGPUVertexAttribute{ + .format = WGPUVertexFormat_Float32x3, .offset = 0, .shaderLocation = 0, }, }; - vertexBufferLayouts = { - { - .arrayStride = sizeof(gpu::TriangleVertex), - .stepMode = wgpu::VertexStepMode::Vertex, - .attributeCount = std::size(attrs), - .attributes = attrs.data(), - }, - }; + vertexBufferLayouts = {WGPU_VERTEX_BUFFER_LAYOUT_INIT}; + vertexBufferLayouts[0].attributeCount = std::size(attrs); + vertexBufferLayouts[0].attributes = attrs.data(); + vertexBufferLayouts[0].arrayStride = sizeof(gpu::TriangleVertex); + vertexBufferLayouts[0].stepMode = WGPUVertexStepMode_Vertex; + + topology = WGPUPrimitiveTopology_TriangleList; break; } case DrawType::imageRect: RIVE_UNREACHABLE(); case DrawType::imageMesh: attrs = { - { - .format = wgpu::VertexFormat::Float32x2, + WGPUVertexAttribute{ + .format = WGPUVertexFormat_Float32x2, .offset = 0, .shaderLocation = 0, }, - { - .format = wgpu::VertexFormat::Float32x2, + WGPUVertexAttribute{ + .format = WGPUVertexFormat_Float32x2, .offset = 0, .shaderLocation = 1, }, }; - vertexBufferLayouts = { - { - .arrayStride = sizeof(float) * 2, - .stepMode = wgpu::VertexStepMode::Vertex, - .attributeCount = 1, - .attributes = &attrs[0], - }, - { - .arrayStride = sizeof(float) * 2, - .stepMode = wgpu::VertexStepMode::Vertex, - .attributeCount = 1, - .attributes = &attrs[1], - }, - }; + vertexBufferLayouts = {WGPU_VERTEX_BUFFER_LAYOUT_INIT, + WGPU_VERTEX_BUFFER_LAYOUT_INIT}; + + vertexBufferLayouts[0].attributeCount = 1; + vertexBufferLayouts[0].attributes = &attrs[0]; + vertexBufferLayouts[0].arrayStride = sizeof(float) * 2; + vertexBufferLayouts[0].stepMode = WGPUVertexStepMode_Vertex; + + vertexBufferLayouts[1].attributeCount = 1; + vertexBufferLayouts[1].attributes = &attrs[1]; + vertexBufferLayouts[1].arrayStride = sizeof(float) * 2; + vertexBufferLayouts[1].stepMode = WGPUVertexStepMode_Vertex; + + topology = WGPUPrimitiveTopology_TriangleList; break; - case DrawType::atomicInitialize: - case DrawType::atomicResolve: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + case DrawType::renderPassInitialize: + // No attrs. + topology = WGPUPrimitiveTopology_TriangleStrip; + break; + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); } - wgpu::BlendState srcOverBlend = { - .color = {.dstFactor = wgpu::BlendFactor::OneMinusSrcAlpha}, - .alpha = {.dstFactor = wgpu::BlendFactor::OneMinusSrcAlpha}, + WGPUChainedStruct* extraColorTargetState = nullptr; +#ifdef RIVE_WAGYU + const bool usingPLSInputAttachments = + using_pls(interlockMode) && + m_capabilities.plsType == + PixelLocalStorageType::VK_EXT_rasterization_order_attachment_access; + WGPUWagyuColorTargetState wagyuColorTargetState = + WGPU_WAGYU_COLOR_TARGET_STATE_INIT; + if (usingPLSInputAttachments) + { + // WGPUWagyu needs us to tell it when color attachments are also used as + // input attachments. + wagyuColorTargetState.usedAsInput = WGPUOptionalBool_True; + extraColorTargetState = &wagyuColorTargetState.chain; + } +#endif + + StackVector colorAttachments; + + assert(colorAttachments.size() == COLOR_PLANE_IDX); + assert(pipelineState.blendEquation == gpu::BlendEquation::none || + pipelineState.blendEquation == gpu::BlendEquation::srcOver); + colorAttachments.push_back({ + .nextInChain = extraColorTargetState, + .format = static_cast(framebufferFormat), + .blend = (pipelineState.blendEquation == gpu::BlendEquation::srcOver) + ? &BLEND_STATE_SRC_OVER + : nullptr, + .writeMask = pipelineState.colorWriteEnabled ? WGPUColorWriteMask_All + : WGPUColorWriteMask_None, + }); + +#ifdef RIVE_WAGYU + if (usingPLSInputAttachments) + { + assert(colorAttachments.size() == CLIP_PLANE_IDX); + colorAttachments.push_back({ + .nextInChain = extraColorTargetState, + .format = WGPUTextureFormat_R32Uint, + .writeMask = WGPUColorWriteMask_All, + }); + + assert(colorAttachments.size() == SCRATCH_COLOR_PLANE_IDX); + colorAttachments.push_back({ + .nextInChain = extraColorTargetState, + .format = static_cast(framebufferFormat), + .writeMask = WGPUColorWriteMask_All, + }); + + assert(colorAttachments.size() == COVERAGE_PLANE_IDX); + colorAttachments.push_back({ + .nextInChain = extraColorTargetState, + .format = WGPUTextureFormat_R32Uint, + .writeMask = WGPUColorWriteMask_All, + }); + } +#endif + + WGPUFragmentState fragmentState = { + .module = fragmentShader.Get(), + .entryPoint = WGPU_STRING_VIEW("main"), + .targetCount = colorAttachments.size(), + .targets = colorAttachments.data(), }; - wgpu::ColorTargetState colorTargets[] = { +#ifdef RIVE_WAGYU + WGPUWagyuInputAttachmentState inputAttachments[PLS_PLANE_COUNT]; + WGPUWagyuFragmentState wagyuFragmentState = WGPU_WAGYU_FRAGMENT_STATE_INIT; + if (usingPLSInputAttachments) + { + for (size_t i = 0; i < PLS_PLANE_COUNT; ++i) { - .format = framebufferFormat, - .blend = (m_contextOptions.plsType == PixelLocalStorageType::none) - ? &srcOverBlend - : nullptr, - }, - {.format = wgpu::TextureFormat::R32Uint}, - {.format = framebufferFormat}, - {.format = wgpu::TextureFormat::R32Uint}, - }; - static_assert(COLOR_PLANE_IDX == 0); - static_assert(CLIP_PLANE_IDX == 1); - static_assert(SCRATCH_COLOR_PLANE_IDX == 2); - static_assert(COVERAGE_PLANE_IDX == 3); - - wgpu::FragmentState fragmentState = { - .module = fragmentShader, - .entryPoint = "main", - .targetCount = static_cast( - m_contextOptions.plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage - ? 1 - : 4), - .targets = colorTargets, - }; + inputAttachments[i] = WGPU_WAGYU_INPUT_ATTACHMENT_STATE_INIT; + inputAttachments[i].format = colorAttachments[i].format; + inputAttachments[i].usedAsColor = WGPUOptionalBool_True; + } + wagyuFragmentState.inputCount = std::size(inputAttachments); + wagyuFragmentState.inputs = inputAttachments; + wagyuFragmentState.featureFlags = + WGPUWagyuFragmentStateFeaturesFlags_RasterizationOrderAttachmentAccess; + fragmentState.nextInChain = &wagyuFragmentState.chain; + } +#endif - wgpu::RenderPipelineDescriptor desc = { - .layout = m_drawPipelineLayout, + const std::string renderPipelineLabel = + (std::ostringstream() + << "RIVE_Draw{drawType=" << static_cast(drawType) + << ",interlockMode=" << static_cast(interlockMode) << '}') + .str(); + + WGPURenderPipelineDescriptor renderPipelineDescriptor = { + .label = WGPU_STRING_VIEW(renderPipelineLabel.c_str()), + .layout = m_drawPipelineLayout.Get(), .vertex = { - .module = vertexShader, - .entryPoint = "main", + .module = vertexShader.Get(), + .entryPoint = WGPU_STRING_VIEW("main"), .bufferCount = std::size(vertexBufferLayouts), .buffers = vertexBufferLayouts.data(), }, .primitive = { - .topology = wgpu::PrimitiveTopology::TriangleList, - .frontFace = frontFaceForRenderTargetDraws(), - .cullMode = DrawTypeIsImageDraw(drawType) - ? wgpu::CullMode::None - : wgpu::CullMode::Back, + .topology = topology, + .frontFace = static_cast(RIVE_FRONT_FACE), + .cullMode = wgpu_cull_mode(pipelineState.cullFace), + }, + .multisample = + { + .count = interlockMode == gpu::InterlockMode::msaa + ? MSAA_SAMPLE_COUNT + : 1u, + .mask = 0xffffffff, }, .fragment = &fragmentState, }; - return m_device.CreateRenderPipeline(&desc); + WGPUDepthStencilState depthStencilState; + if (interlockMode == gpu::InterlockMode::msaa) + { + depthStencilState = { + .format = WGPUTextureFormat_Depth24PlusStencil8, + .depthWriteEnabled = wgpu_bool(pipelineState.depthWriteEnabled), + .depthCompare = pipelineState.depthTestEnabled + ? WGPUCompareFunction_Less + : WGPUCompareFunction_Always, + .stencilFront = + pipelineState.stencilTestEnabled + ? wgpu_stencil_face_state(pipelineState.stencilFrontOps) + : STENCIL_FACE_STATE_DISABLED, + .stencilBack = pipelineState.stencilTestEnabled + ? wgpu_stencil_face_state( + pipelineState.stencilDoubleSided + ? pipelineState.stencilBackOps + : pipelineState.stencilFrontOps) + : STENCIL_FACE_STATE_DISABLED, + .stencilReadMask = pipelineState.stencilCompareMask, + .stencilWriteMask = pipelineState.stencilWriteMask, + }; + renderPipelineDescriptor.depthStencil = &depthStencilState; + } + + return wgpu::RenderPipeline::Acquire( + wgpuDeviceCreateRenderPipeline(m_device.Get(), + &renderPipelineDescriptor)); } -wgpu::RenderPassEncoder RenderContextWebGPUImpl::makePLSRenderPass( - wgpu::CommandEncoder encoder, - const RenderTargetWebGPU* renderTarget, - wgpu::LoadOp loadOp, - const wgpu::Color& clearColor, - EmJsHandle* renderPassJSHandleIfNeeded) +wgpu::RenderPassEncoder RenderContextWebGPUImpl::beginPLSRenderPass( + wgpu::CommandEncoder commandEncoder, + const FlushDescriptor& desc) { - wgpu::RenderPassColorAttachment plsAttachments[4] = { - { - // framebuffer - .view = renderTarget->m_targetTextureView, - .loadOp = loadOp, - .storeOp = wgpu::StoreOp::Store, - .clearValue = clearColor, - }, + auto* const renderTarget = + static_cast(desc.renderTarget); + + const auto colorLoadOp = + (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget) + ? WGPULoadOp_Load + : WGPULoadOp_Clear; + + StackVector plsAttachments; + + WGPUColor targetClearValue = + math::bit_cast(wgpu_color_premul(desc.colorClearValue)); + + WGPURenderPassDescriptor passDesc = WGPU_RENDER_PASS_DESCRIPTOR_INIT; + passDesc.label = WGPU_STRING_VIEW("RIVE_PLS_RenderPass"); + + // framebuffer + assert(plsAttachments.size() == COLOR_PLANE_IDX); + plsAttachments.push_back({ + .view = renderTarget->targetTextureView().Get(), + .depthSlice = WGPU_DEPTH_SLICE_UNDEFINED, + .loadOp = colorLoadOp, + .storeOp = WGPUStoreOp_Store, + .clearValue = targetClearValue, + }); + +#ifdef RIVE_WAGYU + WGPUWagyuRenderPassDescriptor wagyuRenderPassDescriptor = + WGPU_WAGYU_RENDER_PASS_DESCRIPTOR_INIT; + + StackVector + inputAttachments; + + if (using_pls(desc.interlockMode)) + { + if (m_capabilities.plsType == + PixelLocalStorageType::VK_EXT_rasterization_order_attachment_access) { + assert(inputAttachments.size() == COLOR_PLANE_IDX); + inputAttachments.push_back({ + .view = renderTarget->targetTextureView().Get(), + .clearValue = &targetClearValue, + .loadOp = colorLoadOp, + .storeOp = WGPUStoreOp_Store, + }); + + WGPUColor zeroClearValue = {}; + // clip - .view = renderTarget->m_clipTextureView, - .loadOp = wgpu::LoadOp::Clear, - .storeOp = wgpu::StoreOp::Discard, - .clearValue = {}, - }, - { + assert(plsAttachments.size() == CLIP_PLANE_IDX); + plsAttachments.push_back({ + .view = renderTarget->clipTextureView().Get(), + .depthSlice = WGPU_DEPTH_SLICE_UNDEFINED, + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Discard, + .clearValue = {}, + }); + assert(inputAttachments.size() == CLIP_PLANE_IDX); + inputAttachments.push_back({ + .view = renderTarget->clipTextureView().Get(), + .clearValue = &zeroClearValue, + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Discard, + }); + // scratchColor - .view = renderTarget->m_scratchColorTextureView, - .loadOp = wgpu::LoadOp::Clear, - .storeOp = wgpu::StoreOp::Discard, - .clearValue = {}, - }, - { + assert(plsAttachments.size() == SCRATCH_COLOR_PLANE_IDX); + plsAttachments.push_back({ + .view = renderTarget->scratchColorTextureView().Get(), + .depthSlice = WGPU_DEPTH_SLICE_UNDEFINED, + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Discard, + .clearValue = {}, + }); + assert(inputAttachments.size() == SCRATCH_COLOR_PLANE_IDX); + inputAttachments.push_back({ + .view = renderTarget->scratchColorTextureView().Get(), + .clearValue = &zeroClearValue, + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Discard, + }); + // coverage - .view = renderTarget->m_coverageTextureView, - .loadOp = wgpu::LoadOp::Clear, - .storeOp = wgpu::StoreOp::Discard, - .clearValue = {}, - }, + assert(plsAttachments.size() == COVERAGE_PLANE_IDX); + plsAttachments.push_back({ + .view = renderTarget->coverageTextureView().Get(), + .depthSlice = WGPU_DEPTH_SLICE_UNDEFINED, + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Discard, + .clearValue = {}, + }); + assert(inputAttachments.size() == COVERAGE_PLANE_IDX); + inputAttachments.push_back({ + .view = renderTarget->coverageTextureView().Get(), + .clearValue = &zeroClearValue, + .loadOp = WGPULoadOp_Clear, + .storeOp = WGPUStoreOp_Discard, + }); + + assert(plsAttachments.size() == PLS_PLANE_COUNT); + assert(inputAttachments.size() == PLS_PLANE_COUNT); + + wagyuRenderPassDescriptor.inputAttachmentCount = + inputAttachments.size(); + wagyuRenderPassDescriptor.inputAttachments = + inputAttachments.data(); + } + else if (m_capabilities.plsType == + PixelLocalStorageType::GL_EXT_shader_pixel_local_storage) + { + wagyuRenderPassDescriptor.pixelLocalStorageEnabled = + WGPUOptionalBool_True; + if (desc.fixedFunctionColorOutput) + { + assert(m_capabilities.GL_EXT_shader_pixel_local_storage2); + wagyuRenderPassDescriptor.pixelLocalStorageSize = + 2 * sizeof(uint32_t); + } + } + passDesc.nextInChain = &wagyuRenderPassDescriptor.chain; + } +#endif + + passDesc.colorAttachmentCount = plsAttachments.size(); + passDesc.colorAttachments = plsAttachments.data(); + + wgpu::RenderPassEncoder drawPass = wgpu::RenderPassEncoder::Acquire( + wgpuCommandEncoderBeginRenderPass(commandEncoder.Get(), &passDesc)); + initDrawRenderPass(drawPass, desc); + return drawPass; +} + +wgpu::RenderPassEncoder RenderContextWebGPUImpl::beginMSAARenderPass( + wgpu::CommandEncoder commandEncoder, + MSAABeginType msaaBeginType, + MSAAEndType msaaEndType, + const FlushDescriptor& desc) +{ + auto* const renderTarget = + static_cast(desc.renderTarget); + + // Our MSAA buffers are treated as completely transient (i.e., + // Clear/Discard) unless we have to do render pass breaks for dst copies. + // For LoadAction::preserveRenderTarget, we manually draw the old content + // into the transient MSAA buffer, so we still load with Clear. + // TODO: wgpu::LoadOp::ExpandResolveTexture for the color buffer when + // supported. + const auto msaaLoadOp = msaaBeginType == MSAABeginType::restartAfterDstCopy + ? wgpu::LoadOp::Load + : wgpu::LoadOp::Clear; + const auto msaaStoreOp = (msaaEndType == MSAAEndType::breakForDstCopy) + ? wgpu::StoreOp::Store + : wgpu::StoreOp::Discard; + + wgpu::RenderPassColorAttachment msaaColorAttachment = { + .view = renderTarget->msaaColorTextureView(), + .resolveTarget = renderTarget->targetTextureView().Get(), + .loadOp = msaaLoadOp, + .storeOp = msaaStoreOp, + .clearValue = wgpu_color_premul(desc.colorClearValue), + }; + + wgpu::RenderPassDepthStencilAttachment msaaDepthStencilAttachment = { + .view = renderTarget->msaaDepthStencilTextureView(), + .depthLoadOp = msaaLoadOp, + .depthStoreOp = msaaStoreOp, + .depthClearValue = desc.depthClearValue, + .depthReadOnly = false, + .stencilLoadOp = msaaLoadOp, + .stencilStoreOp = msaaStoreOp, + .stencilClearValue = desc.stencilClearValue, + .stencilReadOnly = false, }; - static_assert(COLOR_PLANE_IDX == 0); - static_assert(CLIP_PLANE_IDX == 1); - static_assert(SCRATCH_COLOR_PLANE_IDX == 2); - static_assert(COVERAGE_PLANE_IDX == 3); - - wgpu::RenderPassDescriptor passDesc = { - .colorAttachmentCount = static_cast( - m_contextOptions.plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage - ? 1 - : 4), - .colorAttachments = plsAttachments, + + wgpu::RenderPassDescriptor renderPassDescriptor = { + .label = "RIVE_MSAA_RenderPass", + .colorAttachmentCount = 1, + .colorAttachments = &msaaColorAttachment, + .depthStencilAttachment = &msaaDepthStencilAttachment, }; - return encoder.BeginRenderPass(&passDesc); + wgpu::RenderPassEncoder drawPass = + commandEncoder.BeginRenderPass(&renderPassDescriptor); + initDrawRenderPass(drawPass, desc); + return drawPass; +} + +void RenderContextWebGPUImpl::initDrawRenderPass( + wgpu::RenderPassEncoder drawPass, + const FlushDescriptor& desc) +{ + drawPass.SetViewport(0.f, + 0.f, + desc.renderTarget->width(), + desc.renderTarget->height(), + 0.0, + 1.0); + drawPass.SetBindGroup(WEBGPU_SAMPLER_BINDINGS_SET, m_samplerBindings); } static wgpu::Buffer webgpu_buffer(const BufferRing* bufferRing) @@ -2120,7 +2986,7 @@ template void update_webgpu_storage_texture(const BufferRing* bufferRing, size_t bindingCount, size_t firstElement, - wgpu::CommandEncoder encoder) + wgpu::CommandEncoder commandEncoder) { assert(bufferRing != nullptr); auto storageTextureBuffer = @@ -2128,7 +2994,7 @@ void update_webgpu_storage_texture(const BufferRing* bufferRing, storageTextureBuffer->updateTextureFromBuffer( bindingCount * sizeof(HighLevelStruct), firstElement * sizeof(HighLevelStruct), - encoder); + commandEncoder); } wgpu::TextureView webgpu_storage_texture_view(const BufferRing* bufferRing) @@ -2140,37 +3006,51 @@ wgpu::TextureView webgpu_storage_texture_view(const BufferRing* bufferRing) void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) { - auto* renderTarget = - static_cast(desc.renderTarget); - wgpu::CommandEncoder encoder = m_device.CreateCommandEncoder(); + auto* const renderTarget = + static_cast(desc.renderTarget); + wgpu::CommandEncoder commandEncoder; + { + auto wgpuEncoder = + static_cast(desc.externalCommandBuffer); + assert(wgpuEncoder != nullptr); +#if (defined(RIVE_WEBGPU) && RIVE_WEBGPU > 1) || defined(RIVE_DAWN) + wgpuCommandEncoderAddRef(wgpuEncoder); +#else + wgpuCommandEncoderReference(wgpuEncoder); +#endif + commandEncoder = wgpu::CommandEncoder::Acquire(wgpuEncoder); + } + +#ifdef RIVE_WAGYU // If storage buffers are disabled, copy their contents to textures. - if (m_contextOptions.disableStorageBuffers) + if (m_capabilities.polyfillVertexStorageBuffers) { if (desc.pathCount > 0) { update_webgpu_storage_texture(pathBufferRing(), desc.pathCount, desc.firstPath, - encoder); + commandEncoder); update_webgpu_storage_texture(paintBufferRing(), desc.pathCount, desc.firstPaint, - encoder); + commandEncoder); update_webgpu_storage_texture( paintAuxBufferRing(), desc.pathCount, desc.firstPaintAux, - encoder); + commandEncoder); } if (desc.contourCount > 0) { update_webgpu_storage_texture(contourBufferRing(), desc.contourCount, desc.firstContour, - encoder); + commandEncoder); } } +#endif wgpu::BindGroupEntry perFlushBindingEntries[DRAW_BINDINGS_COUNT] = { { @@ -2178,41 +3058,49 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) .buffer = webgpu_buffer(flushUniformBufferRing()), .offset = desc.flushUniformDataOffsetInBytes, }, - m_contextOptions.disableStorageBuffers ? - wgpu::BindGroupEntry{ - .binding = PATH_BUFFER_IDX, - .textureView = webgpu_storage_texture_view(pathBufferRing()) - } : +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers + ? wgpu::BindGroupEntry{.binding = PATH_BUFFER_IDX, + .textureView = webgpu_storage_texture_view( + pathBufferRing())} + : +#endif wgpu::BindGroupEntry{ .binding = PATH_BUFFER_IDX, .buffer = webgpu_buffer(pathBufferRing()), .offset = desc.firstPath * sizeof(gpu::PathData), }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupEntry{ .binding = PAINT_BUFFER_IDX, .textureView = webgpu_storage_texture_view(paintBufferRing()), } : +#endif wgpu::BindGroupEntry{ .binding = PAINT_BUFFER_IDX, .buffer = webgpu_buffer(paintBufferRing()), .offset = desc.firstPaint * sizeof(gpu::PaintData), }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupEntry{ .binding = PAINT_AUX_BUFFER_IDX, .textureView = webgpu_storage_texture_view(paintAuxBufferRing()), } : +#endif wgpu::BindGroupEntry{ .binding = PAINT_AUX_BUFFER_IDX, .buffer = webgpu_buffer(paintAuxBufferRing()), .offset = desc.firstPaintAux * sizeof(gpu::PaintAuxData), }, - m_contextOptions.disableStorageBuffers ? +#ifdef RIVE_WAGYU + m_capabilities.polyfillVertexStorageBuffers ? wgpu::BindGroupEntry{ .binding = CONTOUR_BUFFER_IDX, .textureView = webgpu_storage_texture_view(contourBufferRing()), } : +#endif wgpu::BindGroupEntry{ .binding = CONTOUR_BUFFER_IDX, .buffer = webgpu_buffer(contourBufferRing()), @@ -2239,6 +3127,13 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) .buffer = webgpu_buffer(imageDrawUniformBufferRing()), .size = sizeof(gpu::ImageDrawUniforms), }, + { + .binding = DST_COLOR_TEXTURE_IDX, + .textureView = desc.interlockMode == gpu::InterlockMode::msaa && + !desc.fixedFunctionColorOutput + ? renderTarget->dstColorTextureView() + : m_nullTextureView, + }, }; // Render the complex color ramps to the gradient texture. @@ -2263,7 +3158,7 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) }; wgpu::RenderPassEncoder gradPass = - encoder.BeginRenderPass(&gradPassDesc); + commandEncoder.BeginRenderPass(&gradPassDesc); gradPass.SetViewport(0.f, 0.f, gpu::kGradTextureWidth, @@ -2307,7 +3202,7 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) }; wgpu::RenderPassEncoder tessPass = - encoder.BeginRenderPass(&tessPassDesc); + commandEncoder.BeginRenderPass(&tessPassDesc); tessPass.SetViewport(0.f, 0.f, gpu::kTessTextureWidth, @@ -2323,8 +3218,7 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) wgpu::IndexFormat::Uint16); tessPass.SetBindGroup(PER_FLUSH_BINDINGS_SET, m_device.CreateBindGroup(&tessBindGroupDesc)); - tessPass.SetBindGroup(IMMUTABLE_SAMPLER_BINDINGS_SET, - m_samplerBindings); + tessPass.SetBindGroup(WEBGPU_SAMPLER_BINDINGS_SET, m_samplerBindings); tessPass.DrawIndexed(std::size(gpu::kTessSpanIndices), desc.tessVertexSpanCount, 0, @@ -2355,7 +3249,7 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) }; wgpu::RenderPassEncoder atlasPass = - encoder.BeginRenderPass(&atlasPassDesc); + commandEncoder.BeginRenderPass(&atlasPassDesc); atlasPass.SetViewport(0.f, 0.f, desc.atlasContentWidth, @@ -2367,8 +3261,7 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) wgpu::IndexFormat::Uint16); atlasPass.SetBindGroup(PER_FLUSH_BINDINGS_SET, m_device.CreateBindGroup(&atlasBindGroupDesc)); - atlasPass.SetBindGroup(IMMUTABLE_SAMPLER_BINDINGS_SET, - m_samplerBindings); + atlasPass.SetBindGroup(WEBGPU_SAMPLER_BINDINGS_SET, m_samplerBindings); if (desc.atlasFillBatchCount != 0) { @@ -2410,36 +3303,35 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) atlasPass.End(); } - wgpu::LoadOp loadOp; - wgpu::Color clearColor; - if (desc.colorLoadAction == LoadAction::clear) + wgpu::RenderPassEncoder drawPass; + if (desc.interlockMode == gpu::InterlockMode::msaa) { - loadOp = wgpu::LoadOp::Clear; - float cc[4]; - UnpackColorToRGBA32FPremul(desc.colorClearValue, cc); - clearColor = {cc[0], cc[1], cc[2], cc[3]}; + // If we're preserving the render target with a draw, don't start the + // render pass yet. We will get a dstBlend barrier on the first draw + // that does a copy and starts a new render pass. + if (desc.drawList->empty() || desc.drawList->head()->drawType != + gpu::DrawType::renderPassInitialize) + { + drawPass = + beginMSAARenderPass(commandEncoder, + MSAABeginType::primary, + (desc.firstDstBlendBarrier != nullptr) + ? MSAAEndType::breakForDstCopy + : MSAAEndType::finish, + desc); + } } else { - loadOp = wgpu::LoadOp::Load; + drawPass = beginPLSRenderPass(commandEncoder, desc); } - EmJsHandle drawPassJSHandle; - wgpu::RenderPassEncoder drawPass = makePLSRenderPass(encoder, - renderTarget, - loadOp, - clearColor, - &drawPassJSHandle); - drawPass.SetViewport(0.f, - 0.f, - renderTarget->width(), - renderTarget->height(), - 0.0, - 1.0); - - bool needsTextureBindings = - m_contextOptions.plsType == PixelLocalStorageType::subpassLoad; - if (needsTextureBindings) +#ifdef RIVE_WAGYU + const bool usingInputAttachmentBindings = + using_pls(desc.interlockMode) && + m_capabilities.plsType == + PixelLocalStorageType::VK_EXT_rasterization_order_attachment_access; + if (usingInputAttachmentBindings) { wgpu::BindGroupEntry plsTextureBindingEntries[] = { { @@ -2448,15 +3340,15 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) }, { .binding = CLIP_PLANE_IDX, - .textureView = renderTarget->m_clipTextureView, + .textureView = renderTarget->clipTextureView(), }, { .binding = SCRATCH_COLOR_PLANE_IDX, - .textureView = renderTarget->m_scratchColorTextureView, + .textureView = renderTarget->scratchColorTextureView(), }, { .binding = COVERAGE_PLANE_IDX, - .textureView = renderTarget->m_coverageTextureView, + .textureView = renderTarget->coverageTextureView(), }, }; @@ -2470,59 +3362,82 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) m_device.CreateBindGroup(&plsTextureBindingsGroupDesc); drawPass.SetBindGroup(PLS_TEXTURE_BINDINGS_SET, plsTextureBindings); } +#endif - if (m_contextOptions.plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage) +#ifdef RIVE_WAGYU + const bool usingShaderPixelLocalStorageEXT = + using_pls(desc.interlockMode) && + m_capabilities.plsType == + PixelLocalStorageType::GL_EXT_shader_pixel_local_storage; + if (usingShaderPixelLocalStorageEXT) { - enable_shader_pixel_local_storage_ext(drawPass, true); - - // Draw the load action for EXT_shader_pixel_local_storage. - std::array clearColor; - LoadStoreActionsEXT loadActions = - gpu::BuildLoadActionsEXT(desc, &clearColor); - const LoadStoreEXTPipeline& loadPipeline = - m_loadStoreEXTPipelines - .try_emplace(loadActions, - this, - loadActions, - renderTarget->framebufferFormat()) - .first->second; - - if (loadActions & LoadStoreActionsEXT::clearColor) + if (desc.fixedFunctionColorOutput) { - void* uniformData = - m_loadStoreEXTUniforms->mapBuffer(sizeof(clearColor)); - memcpy(uniformData, clearColor.data(), sizeof(clearColor)); - m_loadStoreEXTUniforms->unmapAndSubmitBuffer(); - - wgpu::BindGroupEntry uniformBindingEntries[] = { - { - .binding = 0, - .buffer = webgpu_buffer(m_loadStoreEXTUniforms.get()), - }, + // Clear PLS using the EXT_shader_pixel_local_storage2 API. + assert(m_capabilities.GL_EXT_shader_pixel_local_storage2); + uint32_t plsClearValues[2] = { + desc.coverageClearValue, + /*clipClearValue=*/0u, }; + wgpuWagyuRenderPassEncoderClearPixelLocalStorage( + drawPass.Get(), + 0, + std::size(plsClearValues), + plsClearValues); + } + else + { + // EXT_shader_pixel_local_storage doesn't have an initialization + // API. Initialize PLS by drawing a fullscreen quad. + std::array clearColor; + LoadStoreActionsEXT loadActions = + gpu::BuildLoadActionsEXT(desc, &clearColor); + const LoadStoreEXTPipeline& loadPipeline = + m_loadStoreEXTPipelines + .try_emplace(LoadStoreEXTPipeline::Key( + loadActions, + renderTarget->framebufferFormat()), + this, + loadActions, + renderTarget->framebufferFormat()) + .first->second; + + if (enums::is_flag_set(loadActions, + LoadStoreActionsEXT::clearColor)) + { + void* uniformData = + m_loadStoreEXTUniforms->mapBuffer(sizeof(clearColor)); + memcpy(uniformData, clearColor.data(), sizeof(clearColor)); + m_loadStoreEXTUniforms->unmapAndSubmitBuffer(); - wgpu::BindGroupDescriptor uniformBindGroupDesc = { - .layout = loadPipeline.bindGroupLayout(), - .entryCount = std::size(uniformBindingEntries), - .entries = uniformBindingEntries, - }; + wgpu::BindGroupEntry uniformBindingEntries[] = { + { + .binding = 0, + .buffer = webgpu_buffer(m_loadStoreEXTUniforms.get()), + }, + }; - wgpu::BindGroup uniformBindings = - m_device.CreateBindGroup(&uniformBindGroupDesc); - drawPass.SetBindGroup(0, uniformBindings); - } + wgpu::BindGroupDescriptor uniformBindGroupDesc = { + .layout = loadPipeline.bindGroupLayout(), + .entryCount = std::size(uniformBindingEntries), + .entries = uniformBindingEntries, + }; - drawPass.SetPipeline( - loadPipeline.renderPipeline(renderTarget->framebufferFormat())); - drawPass.Draw(4); - } + wgpu::BindGroup uniformBindings = + m_device.CreateBindGroup(&uniformBindGroupDesc); + drawPass.SetBindGroup(0, uniformBindings); + } - drawPass.SetBindGroup(IMMUTABLE_SAMPLER_BINDINGS_SET, m_samplerBindings); + drawPass.SetPipeline( + loadPipeline.renderPipeline(renderTarget->framebufferFormat())); + drawPass.Draw(4); + } + } +#endif wgpu::BindGroupDescriptor perFlushBindGroupDesc = { .layout = m_drawBindGroupLayouts[PER_FLUSH_BINDINGS_SET], - .entryCount = std::size(perFlushBindingEntries), + .entryCount = DRAW_BINDINGS_COUNT, .entries = perFlushBindingEntries, }; @@ -2535,14 +3450,79 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) { DrawType drawType = batch.drawType; + if (enums::is_flag_set(batch.barriers, gpu::BarrierFlags::dstBlend)) + { + // For a dstBlend barrier, our only option in unextended WebGPU is + // to copy out the dst pixels we want to read into a separate + // texture. + assert(desc.interlockMode == gpu::InterlockMode::msaa); + assert(!desc.fixedFunctionColorOutput || + drawType == gpu::DrawType::renderPassInitialize); +#ifdef RIVE_WAGYU + assert(!usingInputAttachmentBindings); +#endif + + MSAABeginType msaaBeginType; + if (drawType == gpu::DrawType::renderPassInitialize) + { + assert(drawPass == nullptr); + assert(desc.colorLoadAction == + gpu::LoadAction::preserveRenderTarget); + + // Copy out the entire target texture in order to seed the MSAA + // color buffer. We can't seed from the target texture itself + // because it's also the resolveTarget. + renderTarget->copyTargetToDstColorTexture( + commandEncoder, + renderTarget->bounds()); + + msaaBeginType = MSAABeginType::primary; + } + else + { + // Break the render pass to copy out a dst texture. + drawPass.End(); + + // Copy the resolve texture into yet another "dstRead" texture + // for shaders to read. + for (const Draw* draw = batch.dstReadList; draw != nullptr; + draw = draw->nextDstRead()) + { + assert(draw->blendMode() != BlendMode::srcOver); + renderTarget->copyTargetToDstColorTexture( + commandEncoder, + desc.renderTargetUpdateBounds.intersect( + draw->pixelBounds())); + } + + msaaBeginType = MSAABeginType::restartAfterDstCopy; + } + + // Restart the render pass after the copies are finished. + drawPass = + beginMSAARenderPass(commandEncoder, + msaaBeginType, + (batch.nextDstBlendBarrier != nullptr) + ? MSAAEndType::breakForDstCopy + : MSAAEndType::finish, + desc); + needsNewBindings = true; + } + // Bind the appropriate image texture, if any. - wgpu::TextureView imageTextureView = m_nullImagePaintTextureView; + wgpu::TextureView imageTextureView = m_nullTextureView; if (auto imageTexture = static_cast(batch.imageTexture)) { imageTextureView = imageTexture->textureView(); needsNewBindings = true; } + else if (drawType == gpu::DrawType::renderPassInitialize) + { + assert(desc.interlockMode == gpu::InterlockMode::msaa); + assert(needsNewBindings); + imageTextureView = renderTarget->dstColorTextureView(); + } if (needsNewBindings || // Image draws always re-bind because they update the dynamic offset @@ -2559,6 +3539,10 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) .binding = IMAGE_TEXTURE_IDX, .textureView = imageTextureView, }, + { + .binding = WEBGPU_IMAGE_SAMPLER_IDX, + .sampler = m_imageSamplers[batch.imageSampler.asKey()], + }, }; wgpu::BindGroupDescriptor perDrawBindGroupDesc = { @@ -2575,27 +3559,74 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) nullptr); } + gpu::PipelineState pipelineState; + gpu::get_pipeline_state(batch, + desc, + m_platformFeatures, + &pipelineState); + if (desc.interlockMode == gpu::InterlockMode::rasterOrdering || + desc.interlockMode == gpu::InterlockMode::clockwise) + { + // All forms of PLS used by our webgpu backend require color writes + // to be enabled, so override the Rive state, which expects PLS to + // work when color writes are disabled. + // TODO: We shouldn't technically update the pipelineState without + // also updating the uniqueKey, but this works for now because + // interlockMode is also part of the pipeline key. + pipelineState.colorWriteEnabled = true; + } + // Setup the pipeline for this specific drawType and shaderFeatures. + bool targetIsGLFBO0 = false; +#ifdef RIVE_WAGYU + if (m_capabilities.backendType == wgpu::BackendType::OpenGLES) + { + targetIsGLFBO0 = wgpuWagyuTextureIsSwapchain( + renderTarget->m_targetTexture.Get()); + } +#endif + uint64_t pipelineKey = + gpu::pipeline_unique_key(drawType, + batch.shaderFeatures, + desc.interlockMode, + batch.shaderMiscFlags, + batch.drawContents, + desc.fixedFunctionColorOutput, + batch.firstBlendMode, + platformFeatures()); + + pipelineKey = math::add_bits_to_key(pipelineKey, targetIsGLFBO0, 1); + const DrawPipeline& drawPipeline = m_drawPipelines - .try_emplace( - gpu::ShaderUniqueKey(drawType, - batch.shaderFeatures, - gpu::InterlockMode::rasterOrdering, - gpu::ShaderMiscFlags::none), - this, - drawType, - batch.shaderFeatures, - m_contextOptions) + .try_emplace(pipelineKey, + this, + drawType, + batch.shaderFeatures, + desc.interlockMode, + batch.shaderMiscFlags, + pipelineState, + targetIsGLFBO0) .first->second; drawPass.SetPipeline( drawPipeline.renderPipeline(renderTarget->framebufferFormat())); + if (pipelineState.stencilTestEnabled) + { + drawPass.SetStencilReference(pipelineState.stencilReference); + } switch (drawType) { case DrawType::midpointFanPatches: case DrawType::midpointFanCenterAAPatches: case DrawType::outerCurvePatches: + case DrawType::msaaOuterCubics: + case DrawType::msaaStrokes: + case DrawType::msaaMidpointFanBorrowedCoverage: + case DrawType::msaaMidpointFans: + case DrawType::msaaMidpointFanStencilReset: + case DrawType::msaaMidpointFanPathsStencil: + case DrawType::msaaMidpointFanPathsCover: { // Draw PLS patches that connect the tessellation vertices. drawPass.SetVertexBuffer(0, m_pathPatchVertexBuffer); @@ -2608,6 +3639,8 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) batch.baseElement); break; } + + case DrawType::clipReset: case DrawType::interiorTriangulation: case DrawType::atlasBlit: { @@ -2616,8 +3649,7 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) drawPass.Draw(batch.elementCount, 1, batch.baseElement); break; } - case DrawType::imageRect: - RIVE_UNREACHABLE(); + case DrawType::imageMesh: { auto vertexBuffer = static_cast( @@ -2633,65 +3665,71 @@ void RenderContextWebGPUImpl::flush(const FlushDescriptor& desc) drawPass.DrawIndexed(batch.elementCount, 1, batch.baseElement); break; } - case DrawType::atomicInitialize: - case DrawType::atomicResolve: - case DrawType::msaaStrokes: - case DrawType::msaaMidpointFanBorrowedCoverage: - case DrawType::msaaMidpointFans: - case DrawType::msaaMidpointFanStencilReset: - case DrawType::msaaMidpointFanPathsStencil: - case DrawType::msaaMidpointFanPathsCover: - case DrawType::msaaOuterCubics: - case DrawType::msaaStencilClipReset: + + case DrawType::renderPassInitialize: + drawPass.Draw(4); + break; + + case DrawType::imageRect: + case DrawType::renderPassResolve: RIVE_UNREACHABLE(); } } - if (m_contextOptions.plsType == - PixelLocalStorageType::EXT_shader_pixel_local_storage) +#ifdef RIVE_WAGYU + if (usingShaderPixelLocalStorageEXT && !desc.fixedFunctionColorOutput) { - // Draw the store action for EXT_shader_pixel_local_storage. - LoadStoreActionsEXT actions = LoadStoreActionsEXT::storeColor; + // EXT_shader_pixel_local_storage doesn't support concurrent rendering + // to PLS and the framebuffer. Now that we're done, issue a fullscreen + // draw that transfers the color information from PLS to the main + // framebuffer. + LoadStoreActionsEXT storeActions = LoadStoreActionsEXT::storeColor; auto it = m_loadStoreEXTPipelines.try_emplace( - actions, + LoadStoreEXTPipeline::Key(storeActions, + renderTarget->framebufferFormat()), this, - actions, + storeActions, renderTarget->framebufferFormat()); LoadStoreEXTPipeline* storePipeline = &it.first->second; drawPass.SetPipeline( storePipeline->renderPipeline(renderTarget->framebufferFormat())); drawPass.Draw(4); - - enable_shader_pixel_local_storage_ext(drawPass, false); } +#endif drawPass.End(); - - wgpu::CommandBuffer commands = encoder.Finish(); - m_queue.Submit(1, &commands); } std::unique_ptr RenderContextWebGPUImpl::MakeContext( + wgpu::Adapter adapter, wgpu::Device device, wgpu::Queue queue, const ContextOptions& contextOptions) { - std::unique_ptr impl; - switch (contextOptions.plsType) - { - case PixelLocalStorageType::subpassLoad: -#ifdef RIVE_WEBGPU - impl = std::unique_ptr( - new RenderContextWebGPUVulkan(device, queue, contextOptions)); - break; -#endif - case PixelLocalStorageType::EXT_shader_pixel_local_storage: - case PixelLocalStorageType::none: - impl = std::unique_ptr( - new RenderContextWebGPUImpl(device, queue, contextOptions)); - break; - } + auto impl = std::unique_ptr( + new RenderContextWebGPUImpl(adapter, device, queue, contextOptions)); impl->initGPUObjects(); return std::make_unique(std::move(impl)); } + +void* RenderContextWebGPUImpl::makeCommandBuffer() +{ + wgpu::CommandEncoder encoder = m_device.CreateCommandEncoder(); + // Release the C++ wrapper's ref and return the raw handle. + // The caller (commitCommandBuffer) will re-acquire it. + return encoder.MoveToCHandle(); +} + +void RenderContextWebGPUImpl::commitCommandBuffer(void* commandBuffer) +{ + if (commandBuffer == nullptr) + { + return; + } + // Re-acquire ownership of the raw handle. + wgpu::CommandEncoder encoder = wgpu::CommandEncoder::Acquire( + static_cast(commandBuffer)); + wgpu::CommandBuffer commands = encoder.Finish(); + m_queue.Submit(1, &commands); +} } // namespace rive::gpu diff --git a/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.cpp b/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.cpp deleted file mode 100644 index 8ed5027c5..000000000 --- a/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#ifdef RIVE_WEBGPU - -#include "render_context_webgpu_vulkan.hpp" - -#include "shaders/constants.glsl" - -#include -#include -#include - -namespace rive::gpu -{ -// Create a group for binding PLS textures as Vulkan input attachments. The -// "inputTexture" property is nonstandard WebGPU. -EM_JS(int, make_pls_input_attachment_texture_bind_group, (int device), { - device = JsValStore.get(device); - const plsBindBroupLayout = device.createBindGroupLayout({ - entries : [ - { - binding : 0, - visibility : GPUShaderStage.FRAGMENT, - inputTexture : {viewDimension : "2d"}, - }, - { - binding : 1, - visibility : GPUShaderStage.FRAGMENT, - inputTexture : {viewDimension : "2d"}, - }, - { - binding : 2, - visibility : GPUShaderStage.FRAGMENT, - inputTexture : {viewDimension : "2d"}, - }, - { - binding : 3, - visibility : GPUShaderStage.FRAGMENT, - inputTexture : {viewDimension : "2d"}, - }, - ] - }); - return JsValStore.add(plsBindBroupLayout); -}); - -wgpu::BindGroupLayout RenderContextWebGPUVulkan::initTextureBindGroup() -{ - m_plsTextureBindGroupJSHandle = - EmJsHandle(make_pls_input_attachment_texture_bind_group( - emscripten_webgpu_export_device(device().Get()))); - return wgpu::BindGroupLayout::Acquire( - emscripten_webgpu_import_bind_group_layout( - m_plsTextureBindGroupJSHandle.get())); -} - -// The "TRANSIENT_ATTACHMENT" and "INPUT_ATTACHMENT" flags are nonstandard -// WebGPU. -EM_JS(int, texture_usage_transient_input_attachment, (), { - return GPUTextureUsage.TRANSIENT_ATTACHMENT | - GPUTextureUsage.INPUT_ATTACHMENT; -}); - -rcp RenderContextWebGPUVulkan::makeRenderTarget( - wgpu::TextureFormat framebufferFormat, - uint32_t width, - uint32_t height) -{ - return rcp(new RenderTargetWebGPU( - device(), - framebufferFormat, - width, - height, - static_cast( - texture_usage_transient_input_attachment()))); -} - -// Create a standard PLS "draw" pipeline that uses Vulkan input attachments and -// VK_EXT_rasterization_order_attachment_access for pixel local storage. The -// "inputs" and "features" properties on GPUFragmentState, and the "usedAsInput" -// property on GPUColorTargetState are nonstandard WebGPU. -EM_JS(int, - make_pls_draw_pipeline, - (int device, - rive::gpu::DrawType drawType, - wgpu::TextureFormat framebufferFormat, - int vertexShader, - int fragmentShader, - int pipelineLayout, - bool clockwiseFrontFace), - { - device = JsValStore.get(device); - vertexShader = JsValStore.get(vertexShader); - fragmentShader = JsValStore.get(fragmentShader); - pipelineLayout = JsValStore.get(pipelineLayout); - - const RGBA8_UNORM = 0x00000012; - const BGRA8_UNORM = 0x00000017; - switch (framebufferFormat) - { - case RGBA8_UNORM: - framebufferFormat = "rgba8unorm"; - break; - case BGRA8_UNORM: - framebufferFormat = "bgra8unorm"; - break; - default: - throw "unsupported framebuffer format " + framebufferFormat; - } - - let vertexBufferLayout; - switch (drawType) - { - case 0: - case 1: - attrs = [ - { - format : "float32x4", - offset : 0, - shaderLocation : 0, - }, - { - format : "float32x4", - offset : 4 * 4, - shaderLocation : 1, - }, - ]; - vertexBufferLayouts = [ - { - arrayStride : 4 * 8, - stepMode : "vertex", - attributes : attrs, - }, - ]; - break; - case 2: - attrs = [ - { - format : "float32x3", - offset : 0, - shaderLocation : 0, - }, - ]; - - vertexBufferLayouts = [ - { - arrayStride : 4 * 3, - stepMode : "vertex", - attributes : attrs, - }, - ]; - break; - case 3: - attrs = [ - { - format : "float32x2", - offset : 0, - shaderLocation : 0, - }, - { - format : "float32x2", - offset : 0, - shaderLocation : 1, - }, - ]; - - vertexBufferLayouts = [ - { - arrayStride : 4 * 2, - stepMode : "vertex", - attributes : [attrs[0]], - }, - { - arrayStride : 4 * 2, - stepMode : "vertex", - attributes : [attrs[1]], - }, - ]; - break; - } - - const pipelineDesc = { - vertex : { - module : vertexShader, - entryPoint : "main", - buffers : vertexBufferLayouts, - }, - fragment : { - module : fragmentShader, - entryPoint : "main", - inputs : [ - {format : framebufferFormat, usedAsColor : true}, - {format : "r32uint", usedAsColor : true}, - {format : framebufferFormat, usedAsColor : true}, - {format : "r32uint", usedAsColor : true}, - ], - targets : [ - {format : framebufferFormat, usedAsInput : true}, - {format : "r32uint", usedAsInput : true}, - {format : framebufferFormat, usedAsInput : true}, - {format : "r32uint", usedAsInput : true}, - ], - features : GPUFragmentStateFeatures - .RASTERIZATION_ORDER_ATTACHMENT_ACCESS, - }, - primitive : { - topology : "triangle-list", - frontFace : clockwiseFrontFace ? "cw" : "ccw", - cullMode : drawType != 3 ? "back" : "none" - }, - layout : pipelineLayout - }; - - const pipeline = device.createRenderPipeline(pipelineDesc); - return JsValStore.add(pipeline); - }); - -wgpu::RenderPipeline RenderContextWebGPUVulkan::makeDrawPipeline( - rive::gpu::DrawType drawType, - wgpu::TextureFormat framebufferFormat, - wgpu::ShaderModule vertexShader, - wgpu::ShaderModule fragmentShader, - EmJsHandle* pipelineJSHandleIfNeeded) -{ - *pipelineJSHandleIfNeeded = EmJsHandle(make_pls_draw_pipeline( - emscripten_webgpu_export_device(device().Get()), - drawType, - framebufferFormat, - emscripten_webgpu_export_shader_module(vertexShader.Get()), - emscripten_webgpu_export_shader_module(fragmentShader.Get()), - emscripten_webgpu_export_pipeline_layout(drawPipelineLayout().Get()), - frontFaceForRenderTargetDraws() == wgpu::FrontFace::CW)); - static_assert(COLOR_PLANE_IDX == 0); - static_assert(CLIP_PLANE_IDX == 1); - static_assert(SCRATCH_COLOR_PLANE_IDX == 2); - static_assert(COVERAGE_PLANE_IDX == 3); - return wgpu::RenderPipeline::Acquire( - emscripten_webgpu_import_render_pipeline( - pipelineJSHandleIfNeeded->get())); -} - -// Create a standard PLS "draw" render pass that uses Vulkan input attachments -// for pixel local storage. The "inputAttachments" property on -// GPURenderPassDescriptor is nonstandard WebGPU. -EM_JS(int, - make_pls_render_pass, - (int encoder, - int tex0, - int tex1, - int tex2, - int tex3, - wgpu::LoadOp loadOp, - double r, - double g, - double b, - double a), - { - encoder = JsValStore.get(encoder); - tex0 = JsValStore.get(tex0); - tex1 = JsValStore.get(tex1); - tex2 = JsValStore.get(tex2); - tex3 = JsValStore.get(tex3); - - const CLEAR = 1; - const LOAD = 2; - switch (loadOp) - { - case CLEAR: - loadOp = "clear"; - break; - case LOAD: - loadOp = "load"; - break; - default: - throw "unsupported framebuffer format " + framebufferFormat; - } - - const zero = {r : 0, g : 0, b : 0, a : 0}; - const plsAttachments = [ - { - view : tex0, - loadOp : loadOp, - storeOp : "store", - clearValue : {r : r, g : g, b : b, a : a}, - }, - { - view : tex1, - loadOp : "clear", - storeOp : "discard", - clearValue : zero, - }, - { - view : tex2, - loadOp : "clear", - storeOp : "discard", - clearValue : zero, - }, - { - view : tex3, - loadOp : "clear", - storeOp : "discard", - clearValue : zero, - }, - ]; - - const renderPass = encoder.beginRenderPass({ - inputAttachments : plsAttachments, - colorAttachments : plsAttachments, - }); - - return JsValStore.add(renderPass); - }); - -wgpu::RenderPassEncoder RenderContextWebGPUVulkan::makePLSRenderPass( - wgpu::CommandEncoder encoder, - const RenderTargetWebGPU* renderTarget, - wgpu::LoadOp loadOp, - const wgpu::Color& clearColor, - EmJsHandle* renderPassJSHandleIfNeeded) -{ - *renderPassJSHandleIfNeeded = EmJsHandle(make_pls_render_pass( - emscripten_webgpu_export_command_encoder(encoder.Get()), - emscripten_webgpu_export_texture_view( - renderTarget->m_targetTextureView.Get()), - emscripten_webgpu_export_texture_view( - renderTarget->m_coverageTextureView.Get()), - emscripten_webgpu_export_texture_view( - renderTarget->m_clipTextureView.Get()), - emscripten_webgpu_export_texture_view( - renderTarget->m_scratchColorTextureView.Get()), - loadOp, - clearColor.r, - clearColor.g, - clearColor.b, - clearColor.a)); - return wgpu::RenderPassEncoder::Acquire( - emscripten_webgpu_import_render_pass_encoder( - renderPassJSHandleIfNeeded->get())); -} -} // namespace rive::gpu - -#endif diff --git a/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.hpp b/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.hpp deleted file mode 100644 index f91557e85..000000000 --- a/thirdparty/rive_renderer/source/webgpu/render_context_webgpu_vulkan.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 Rive - */ - -#pragma once - -#ifdef RIVE_WEBGPU - -#include "rive/renderer/webgpu/render_context_webgpu_impl.hpp" - -namespace rive::gpu -{ -// WebGPU implementation that uses Vulkan input attachments, -// VK_EXT_rasterization_order_attachment_access, and subpassLoad() for pixel -// local storage. These Vulkan features are accessed via nonstandard WebGPU -// APIs. -class RenderContextWebGPUVulkan : public RenderContextWebGPUImpl -{ -public: - rcp makeRenderTarget(wgpu::TextureFormat, - uint32_t width, - uint32_t height) override; - -protected: - wgpu::BindGroupLayout initTextureBindGroup() override; - - wgpu::RenderPipeline makeDrawPipeline( - rive::gpu::DrawType drawType, - wgpu::TextureFormat framebufferFormat, - wgpu::ShaderModule vertexShader, - wgpu::ShaderModule fragmentShader, - EmJsHandle* pipelineJSHandleIfNeeded) override; - - wgpu::RenderPassEncoder makePLSRenderPass( - wgpu::CommandEncoder, - const RenderTargetWebGPU*, - wgpu::LoadOp, - const wgpu::Color& clearColor, - EmJsHandle* renderPassJSHandleIfNeeded) override; - -private: - friend class RenderContextWebGPUImpl; - - RenderContextWebGPUVulkan(wgpu::Device device, - wgpu::Queue queue, - const ContextOptions& contextOptions) : - RenderContextWebGPUImpl(device, queue, contextOptions) - { - assert(contextOptions.plsType == PixelLocalStorageType::subpassLoad); - m_platformFeatures.supportsRasterOrdering = true; - } - - EmJsHandle m_plsTextureBindGroupJSHandle; -}; -} // namespace rive::gpu - -#endif diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu.h b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu.h new file mode 100644 index 000000000..1655e5743 --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu.h @@ -0,0 +1,2828 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, "WebGPU native" developers +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef WEBGPU_H_ +#define WEBGPU_H_ + +#if defined(WGPU_SHARED_LIBRARY) +# if defined(_WIN32) +# if defined(WGPU_IMPLEMENTATION) +# define WGPU_EXPORT __declspec(dllexport) +# else +# define WGPU_EXPORT __declspec(dllimport) +# endif +# else // defined(_WIN32) +# if defined(WGPU_IMPLEMENTATION) +# define WGPU_EXPORT __attribute__((visibility("default"))) +# else +# define WGPU_EXPORT +# endif +# endif // defined(_WIN32) +#else // defined(WGPU_SHARED_LIBRARY) +# define WGPU_EXPORT +#endif // defined(WGPU_SHARED_LIBRARY) + +#if !defined(WGPU_OBJECT_ATTRIBUTE) +#define WGPU_OBJECT_ATTRIBUTE +#endif +#if !defined(WGPU_ENUM_ATTRIBUTE) +#define WGPU_ENUM_ATTRIBUTE +#endif +#if !defined(WGPU_STRUCTURE_ATTRIBUTE) +#define WGPU_STRUCTURE_ATTRIBUTE +#endif +#if !defined(WGPU_FUNCTION_ATTRIBUTE) +#define WGPU_FUNCTION_ATTRIBUTE +#endif +#if !defined(WGPU_NULLABLE) +#define WGPU_NULLABLE +#endif + +#include +#include +#include + +#define _wgpu_COMMA , +#if defined(__cplusplus) +# define _wgpu_ENUM_ZERO_INIT(type) type(0) +# define _wgpu_STRUCT_ZERO_INIT {} +# if __cplusplus >= 201103L +# define _wgpu_MAKE_INIT_STRUCT(type, value) (type value) +# else +# define _wgpu_MAKE_INIT_STRUCT(type, value) value +# endif +#else +# define _wgpu_ENUM_ZERO_INIT(type) (type)0 +# define _wgpu_STRUCT_ZERO_INIT {0} +# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +# define _wgpu_MAKE_INIT_STRUCT(type, value) ((type) value) +# else +# define _wgpu_MAKE_INIT_STRUCT(type, value) value +# endif +#endif + +#define WGPU_TRUE (UINT32_C(1)) +#define WGPU_FALSE (UINT32_C(0)) +#define WGPU_ARRAY_LAYER_COUNT_UNDEFINED (UINT32_MAX) +#define WGPU_COPY_STRIDE_UNDEFINED (UINT32_MAX) +#define WGPU_DEPTH_CLEAR_VALUE_UNDEFINED (NAN) +#define WGPU_DEPTH_SLICE_UNDEFINED (UINT32_MAX) +#define WGPU_LIMIT_U32_UNDEFINED (UINT32_MAX) +#define WGPU_LIMIT_U64_UNDEFINED (UINT64_MAX) +#define WGPU_MIP_LEVEL_COUNT_UNDEFINED (UINT32_MAX) +#define WGPU_QUERY_SET_INDEX_UNDEFINED (UINT32_MAX) +#define WGPU_STRLEN (SIZE_MAX) +#define WGPU_WHOLE_MAP_SIZE (SIZE_MAX) +#define WGPU_WHOLE_SIZE (UINT64_MAX) + +typedef struct WGPUStringView { + WGPU_NULLABLE char const * data; + size_t length; +} WGPUStringView WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_STRING_VIEW_INIT _wgpu_MAKE_INIT_STRUCT(WGPUStringView, { \ + /*.data=*/NULL _wgpu_COMMA \ + /*.length=*/WGPU_STRLEN _wgpu_COMMA \ +}) + +typedef uint64_t WGPUFlags; +typedef uint32_t WGPUBool; + +typedef struct WGPUAdapterImpl* WGPUAdapter WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBindGroupImpl* WGPUBindGroup WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBufferImpl* WGPUBuffer WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUCommandBufferImpl* WGPUCommandBuffer WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUCommandEncoderImpl* WGPUCommandEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUComputePassEncoderImpl* WGPUComputePassEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUComputePipelineImpl* WGPUComputePipeline WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUDeviceImpl* WGPUDevice WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUInstanceImpl* WGPUInstance WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUPipelineLayoutImpl* WGPUPipelineLayout WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUQuerySetImpl* WGPUQuerySet WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUQueueImpl* WGPUQueue WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderBundleImpl* WGPURenderBundle WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderBundleEncoderImpl* WGPURenderBundleEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderPipelineImpl* WGPURenderPipeline WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSamplerImpl* WGPUSampler WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUShaderModuleImpl* WGPUShaderModule WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSurfaceImpl* WGPUSurface WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUTextureImpl* WGPUTexture WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUTextureViewImpl* WGPUTextureView WGPU_OBJECT_ATTRIBUTE; + +// Structure forward declarations +struct WGPUAdapterInfo; +struct WGPUBindGroupEntry; +struct WGPUBlendComponent; +struct WGPUBufferBindingLayout; +struct WGPUBufferDescriptor; +struct WGPUColor; +struct WGPUCommandBufferDescriptor; +struct WGPUCommandEncoderDescriptor; +struct WGPUCompatibilityModeLimits; +struct WGPUConstantEntry; +struct WGPUDawnCompilationMessageUtf16; +struct WGPUEmscriptenSurfaceSourceCanvasHTMLSelector; +struct WGPUExtent3D; +struct WGPUFuture; +struct WGPUInstanceLimits; +struct WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER; +struct WGPUMultisampleState; +struct WGPUOrigin3D; +struct WGPUPassTimestampWrites; +struct WGPUPipelineLayoutDescriptor; +struct WGPUPrimitiveState; +struct WGPUQuerySetDescriptor; +struct WGPUQueueDescriptor; +struct WGPURenderBundleDescriptor; +struct WGPURenderBundleEncoderDescriptor; +struct WGPURenderPassDepthStencilAttachment; +struct WGPURenderPassMaxDrawCount; +struct WGPURequestAdapterWebXROptions; +struct WGPUSamplerBindingLayout; +struct WGPUSamplerDescriptor; +struct WGPUShaderSourceSPIRV; +struct WGPUShaderSourceWGSL; +struct WGPUStencilFaceState; +struct WGPUStorageTextureBindingLayout; +struct WGPUSupportedFeatures; +struct WGPUSupportedInstanceFeatures; +struct WGPUSupportedWGSLLanguageFeatures; +struct WGPUSurfaceCapabilities; +struct WGPUSurfaceColorManagement; +struct WGPUSurfaceConfiguration; +struct WGPUSurfaceTexture; +struct WGPUTexelCopyBufferLayout; +struct WGPUTextureBindingLayout; +struct WGPUTextureBindingViewDimensionDescriptor; +struct WGPUTextureComponentSwizzle; +struct WGPUVertexAttribute; +struct WGPUBindGroupDescriptor; +struct WGPUBindGroupLayoutEntry; +struct WGPUBlendState; +struct WGPUCompilationMessage; +struct WGPUComputePassDescriptor; +struct WGPUComputeState; +struct WGPUDepthStencilState; +struct WGPUFutureWaitInfo; +struct WGPUInstanceDescriptor; +struct WGPULimits; +struct WGPURenderPassColorAttachment; +struct WGPURequestAdapterOptions; +struct WGPUShaderModuleDescriptor; +struct WGPUSurfaceDescriptor; +struct WGPUTexelCopyBufferInfo; +struct WGPUTexelCopyTextureInfo; +struct WGPUTextureComponentSwizzleDescriptor; +struct WGPUTextureDescriptor; +struct WGPUVertexBufferLayout; +struct WGPUBindGroupLayoutDescriptor; +struct WGPUColorTargetState; +struct WGPUCompilationInfo; +struct WGPUComputePipelineDescriptor; +struct WGPUDeviceDescriptor; +struct WGPURenderPassDescriptor; +struct WGPUTextureViewDescriptor; +struct WGPUVertexState; +struct WGPUFragmentState; +struct WGPURenderPipelineDescriptor; + +// Callback info structure forward declarations. +struct WGPUBufferMapCallbackInfo; +struct WGPUCompilationInfoCallbackInfo; +struct WGPUCreateComputePipelineAsyncCallbackInfo; +struct WGPUCreateRenderPipelineAsyncCallbackInfo; +struct WGPUDeviceLostCallbackInfo; +struct WGPUPopErrorScopeCallbackInfo; +struct WGPUQueueWorkDoneCallbackInfo; +struct WGPURequestAdapterCallbackInfo; +struct WGPURequestDeviceCallbackInfo; +struct WGPUUncapturedErrorCallbackInfo; + +typedef enum WGPUAdapterType { + WGPUAdapterType_DiscreteGPU = 0x00000001, + WGPUAdapterType_IntegratedGPU = 0x00000002, + WGPUAdapterType_CPU = 0x00000003, + WGPUAdapterType_Unknown = 0x00000004, + WGPUAdapterType_Force32 = 0x7FFFFFFF +} WGPUAdapterType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUAddressMode { + WGPUAddressMode_Undefined = 0x00000000, + WGPUAddressMode_ClampToEdge = 0x00000001, + WGPUAddressMode_Repeat = 0x00000002, + WGPUAddressMode_MirrorRepeat = 0x00000003, + WGPUAddressMode_Force32 = 0x7FFFFFFF +} WGPUAddressMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBackendType { + WGPUBackendType_Undefined = 0x00000000, + WGPUBackendType_Null = 0x00000001, + WGPUBackendType_WebGPU = 0x00000002, + WGPUBackendType_D3D11 = 0x00000003, + WGPUBackendType_D3D12 = 0x00000004, + WGPUBackendType_Metal = 0x00000005, + WGPUBackendType_Vulkan = 0x00000006, + WGPUBackendType_OpenGL = 0x00000007, + WGPUBackendType_OpenGLES = 0x00000008, + WGPUBackendType_Force32 = 0x7FFFFFFF +} WGPUBackendType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBlendFactor { + WGPUBlendFactor_Undefined = 0x00000000, + WGPUBlendFactor_Zero = 0x00000001, + WGPUBlendFactor_One = 0x00000002, + WGPUBlendFactor_Src = 0x00000003, + WGPUBlendFactor_OneMinusSrc = 0x00000004, + WGPUBlendFactor_SrcAlpha = 0x00000005, + WGPUBlendFactor_OneMinusSrcAlpha = 0x00000006, + WGPUBlendFactor_Dst = 0x00000007, + WGPUBlendFactor_OneMinusDst = 0x00000008, + WGPUBlendFactor_DstAlpha = 0x00000009, + WGPUBlendFactor_OneMinusDstAlpha = 0x0000000A, + WGPUBlendFactor_SrcAlphaSaturated = 0x0000000B, + WGPUBlendFactor_Constant = 0x0000000C, + WGPUBlendFactor_OneMinusConstant = 0x0000000D, + WGPUBlendFactor_Src1 = 0x0000000E, + WGPUBlendFactor_OneMinusSrc1 = 0x0000000F, + WGPUBlendFactor_Src1Alpha = 0x00000010, + WGPUBlendFactor_OneMinusSrc1Alpha = 0x00000011, + WGPUBlendFactor_Force32 = 0x7FFFFFFF +} WGPUBlendFactor WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBlendOperation { + WGPUBlendOperation_Undefined = 0x00000000, + WGPUBlendOperation_Add = 0x00000001, + WGPUBlendOperation_Subtract = 0x00000002, + WGPUBlendOperation_ReverseSubtract = 0x00000003, + WGPUBlendOperation_Min = 0x00000004, + WGPUBlendOperation_Max = 0x00000005, + WGPUBlendOperation_Force32 = 0x7FFFFFFF +} WGPUBlendOperation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferBindingType { + WGPUBufferBindingType_BindingNotUsed = 0x00000000, + WGPUBufferBindingType_Undefined = 0x00000001, + WGPUBufferBindingType_Uniform = 0x00000002, + WGPUBufferBindingType_Storage = 0x00000003, + WGPUBufferBindingType_ReadOnlyStorage = 0x00000004, + WGPUBufferBindingType_Force32 = 0x7FFFFFFF +} WGPUBufferBindingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferMapState { + WGPUBufferMapState_Unmapped = 0x00000001, + WGPUBufferMapState_Pending = 0x00000002, + WGPUBufferMapState_Mapped = 0x00000003, + WGPUBufferMapState_Force32 = 0x7FFFFFFF +} WGPUBufferMapState WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCallbackMode { + WGPUCallbackMode_WaitAnyOnly = 0x00000001, + WGPUCallbackMode_AllowProcessEvents = 0x00000002, + WGPUCallbackMode_AllowSpontaneous = 0x00000003, + WGPUCallbackMode_Force32 = 0x7FFFFFFF +} WGPUCallbackMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompareFunction { + WGPUCompareFunction_Undefined = 0x00000000, + WGPUCompareFunction_Never = 0x00000001, + WGPUCompareFunction_Less = 0x00000002, + WGPUCompareFunction_Equal = 0x00000003, + WGPUCompareFunction_LessEqual = 0x00000004, + WGPUCompareFunction_Greater = 0x00000005, + WGPUCompareFunction_NotEqual = 0x00000006, + WGPUCompareFunction_GreaterEqual = 0x00000007, + WGPUCompareFunction_Always = 0x00000008, + WGPUCompareFunction_Force32 = 0x7FFFFFFF +} WGPUCompareFunction WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompilationInfoRequestStatus { + WGPUCompilationInfoRequestStatus_Success = 0x00000001, + WGPUCompilationInfoRequestStatus_CallbackCancelled = 0x00000002, + WGPUCompilationInfoRequestStatus_Force32 = 0x7FFFFFFF +} WGPUCompilationInfoRequestStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompilationMessageType { + WGPUCompilationMessageType_Error = 0x00000001, + WGPUCompilationMessageType_Warning = 0x00000002, + WGPUCompilationMessageType_Info = 0x00000003, + WGPUCompilationMessageType_Force32 = 0x7FFFFFFF +} WGPUCompilationMessageType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUComponentSwizzle { + WGPUComponentSwizzle_Undefined = 0x00000000, + WGPUComponentSwizzle_Zero = 0x00000001, + WGPUComponentSwizzle_One = 0x00000002, + WGPUComponentSwizzle_R = 0x00000003, + WGPUComponentSwizzle_G = 0x00000004, + WGPUComponentSwizzle_B = 0x00000005, + WGPUComponentSwizzle_A = 0x00000006, + WGPUComponentSwizzle_Force32 = 0x7FFFFFFF +} WGPUComponentSwizzle WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompositeAlphaMode { + WGPUCompositeAlphaMode_Auto = 0x00000000, + WGPUCompositeAlphaMode_Opaque = 0x00000001, + WGPUCompositeAlphaMode_Premultiplied = 0x00000002, + WGPUCompositeAlphaMode_Unpremultiplied = 0x00000003, + WGPUCompositeAlphaMode_Inherit = 0x00000004, + WGPUCompositeAlphaMode_Force32 = 0x7FFFFFFF +} WGPUCompositeAlphaMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCreatePipelineAsyncStatus { + WGPUCreatePipelineAsyncStatus_Success = 0x00000001, + WGPUCreatePipelineAsyncStatus_CallbackCancelled = 0x00000002, + WGPUCreatePipelineAsyncStatus_ValidationError = 0x00000003, + WGPUCreatePipelineAsyncStatus_InternalError = 0x00000004, + WGPUCreatePipelineAsyncStatus_Force32 = 0x7FFFFFFF +} WGPUCreatePipelineAsyncStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCullMode { + WGPUCullMode_Undefined = 0x00000000, + WGPUCullMode_None = 0x00000001, + WGPUCullMode_Front = 0x00000002, + WGPUCullMode_Back = 0x00000003, + WGPUCullMode_Force32 = 0x7FFFFFFF +} WGPUCullMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUDeviceLostReason { + WGPUDeviceLostReason_Unknown = 0x00000001, + WGPUDeviceLostReason_Destroyed = 0x00000002, + WGPUDeviceLostReason_CallbackCancelled = 0x00000003, + WGPUDeviceLostReason_FailedCreation = 0x00000004, + WGPUDeviceLostReason_Force32 = 0x7FFFFFFF +} WGPUDeviceLostReason WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUErrorFilter { + WGPUErrorFilter_Validation = 0x00000001, + WGPUErrorFilter_OutOfMemory = 0x00000002, + WGPUErrorFilter_Internal = 0x00000003, + WGPUErrorFilter_Force32 = 0x7FFFFFFF +} WGPUErrorFilter WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUErrorType { + WGPUErrorType_NoError = 0x00000001, + WGPUErrorType_Validation = 0x00000002, + WGPUErrorType_OutOfMemory = 0x00000003, + WGPUErrorType_Internal = 0x00000004, + WGPUErrorType_Unknown = 0x00000005, + WGPUErrorType_Force32 = 0x7FFFFFFF +} WGPUErrorType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFeatureLevel { + WGPUFeatureLevel_Undefined = 0x00000000, + WGPUFeatureLevel_Compatibility = 0x00000001, + WGPUFeatureLevel_Core = 0x00000002, + WGPUFeatureLevel_Force32 = 0x7FFFFFFF +} WGPUFeatureLevel WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFeatureName { + WGPUFeatureName_CoreFeaturesAndLimits = 0x00000001, + WGPUFeatureName_DepthClipControl = 0x00000002, + WGPUFeatureName_Depth32FloatStencil8 = 0x00000003, + WGPUFeatureName_TextureCompressionBC = 0x00000004, + WGPUFeatureName_TextureCompressionBCSliced3D = 0x00000005, + WGPUFeatureName_TextureCompressionETC2 = 0x00000006, + WGPUFeatureName_TextureCompressionASTC = 0x00000007, + WGPUFeatureName_TextureCompressionASTCSliced3D = 0x00000008, + WGPUFeatureName_TimestampQuery = 0x00000009, + WGPUFeatureName_IndirectFirstInstance = 0x0000000A, + WGPUFeatureName_ShaderF16 = 0x0000000B, + WGPUFeatureName_RG11B10UfloatRenderable = 0x0000000C, + WGPUFeatureName_BGRA8UnormStorage = 0x0000000D, + WGPUFeatureName_Float32Filterable = 0x0000000E, + WGPUFeatureName_Float32Blendable = 0x0000000F, + WGPUFeatureName_ClipDistances = 0x00000010, + WGPUFeatureName_DualSourceBlending = 0x00000011, + WGPUFeatureName_Subgroups = 0x00000012, + WGPUFeatureName_TextureFormatsTier1 = 0x00000013, + WGPUFeatureName_TextureFormatsTier2 = 0x00000014, + WGPUFeatureName_PrimitiveIndex = 0x00000015, + WGPUFeatureName_TextureComponentSwizzle = 0x00000016, + WGPUFeatureName_Unorm16TextureFormats = 0x0005000C, + WGPUFeatureName_Snorm16TextureFormats = 0x0005000D, + WGPUFeatureName_MultiDrawIndirect = 0x00050034, + WGPUFeatureName_Force32 = 0x7FFFFFFF +} WGPUFeatureName WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFilterMode { + WGPUFilterMode_Undefined = 0x00000000, + WGPUFilterMode_Nearest = 0x00000001, + WGPUFilterMode_Linear = 0x00000002, + WGPUFilterMode_Force32 = 0x7FFFFFFF +} WGPUFilterMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFrontFace { + WGPUFrontFace_Undefined = 0x00000000, + WGPUFrontFace_CCW = 0x00000001, + WGPUFrontFace_CW = 0x00000002, + WGPUFrontFace_Force32 = 0x7FFFFFFF +} WGPUFrontFace WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUIndexFormat { + WGPUIndexFormat_Undefined = 0x00000000, + WGPUIndexFormat_Uint16 = 0x00000001, + WGPUIndexFormat_Uint32 = 0x00000002, + WGPUIndexFormat_Force32 = 0x7FFFFFFF +} WGPUIndexFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUInstanceFeatureName { + WGPUInstanceFeatureName_TimedWaitAny = 0x00000001, + WGPUInstanceFeatureName_ShaderSourceSPIRV = 0x00000002, + WGPUInstanceFeatureName_MultipleDevicesPerAdapter = 0x00000003, + WGPUInstanceFeatureName_Force32 = 0x7FFFFFFF +} WGPUInstanceFeatureName WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPULoadOp { + WGPULoadOp_Undefined = 0x00000000, + WGPULoadOp_Load = 0x00000001, + WGPULoadOp_Clear = 0x00000002, + WGPULoadOp_Force32 = 0x7FFFFFFF +} WGPULoadOp WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUMapAsyncStatus { + WGPUMapAsyncStatus_Success = 0x00000001, + WGPUMapAsyncStatus_CallbackCancelled = 0x00000002, + WGPUMapAsyncStatus_Error = 0x00000003, + WGPUMapAsyncStatus_Aborted = 0x00000004, + WGPUMapAsyncStatus_Force32 = 0x7FFFFFFF +} WGPUMapAsyncStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUMipmapFilterMode { + WGPUMipmapFilterMode_Undefined = 0x00000000, + WGPUMipmapFilterMode_Nearest = 0x00000001, + WGPUMipmapFilterMode_Linear = 0x00000002, + WGPUMipmapFilterMode_Force32 = 0x7FFFFFFF +} WGPUMipmapFilterMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUOptionalBool { + WGPUOptionalBool_False = 0x00000000, + WGPUOptionalBool_True = 0x00000001, + WGPUOptionalBool_Undefined = 0x00000002, + WGPUOptionalBool_Force32 = 0x7FFFFFFF +} WGPUOptionalBool WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPopErrorScopeStatus { + WGPUPopErrorScopeStatus_Success = 0x00000001, + WGPUPopErrorScopeStatus_CallbackCancelled = 0x00000002, + WGPUPopErrorScopeStatus_Error = 0x00000003, + WGPUPopErrorScopeStatus_Force32 = 0x7FFFFFFF +} WGPUPopErrorScopeStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPowerPreference { + WGPUPowerPreference_Undefined = 0x00000000, + WGPUPowerPreference_LowPower = 0x00000001, + WGPUPowerPreference_HighPerformance = 0x00000002, + WGPUPowerPreference_Force32 = 0x7FFFFFFF +} WGPUPowerPreference WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPredefinedColorSpace { + WGPUPredefinedColorSpace_SRGB = 0x00000001, + WGPUPredefinedColorSpace_DisplayP3 = 0x00000002, + WGPUPredefinedColorSpace_Force32 = 0x7FFFFFFF +} WGPUPredefinedColorSpace WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPresentMode { + WGPUPresentMode_Undefined = 0x00000000, + WGPUPresentMode_Fifo = 0x00000001, + WGPUPresentMode_FifoRelaxed = 0x00000002, + WGPUPresentMode_Immediate = 0x00000003, + WGPUPresentMode_Mailbox = 0x00000004, + WGPUPresentMode_Force32 = 0x7FFFFFFF +} WGPUPresentMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPrimitiveTopology { + WGPUPrimitiveTopology_Undefined = 0x00000000, + WGPUPrimitiveTopology_PointList = 0x00000001, + WGPUPrimitiveTopology_LineList = 0x00000002, + WGPUPrimitiveTopology_LineStrip = 0x00000003, + WGPUPrimitiveTopology_TriangleList = 0x00000004, + WGPUPrimitiveTopology_TriangleStrip = 0x00000005, + WGPUPrimitiveTopology_Force32 = 0x7FFFFFFF +} WGPUPrimitiveTopology WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUQueryType { + WGPUQueryType_Occlusion = 0x00000001, + WGPUQueryType_Timestamp = 0x00000002, + WGPUQueryType_Force32 = 0x7FFFFFFF +} WGPUQueryType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUQueueWorkDoneStatus { + WGPUQueueWorkDoneStatus_Success = 0x00000001, + WGPUQueueWorkDoneStatus_CallbackCancelled = 0x00000002, + WGPUQueueWorkDoneStatus_Error = 0x00000003, + WGPUQueueWorkDoneStatus_Force32 = 0x7FFFFFFF +} WGPUQueueWorkDoneStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURequestAdapterStatus { + WGPURequestAdapterStatus_Success = 0x00000001, + WGPURequestAdapterStatus_CallbackCancelled = 0x00000002, + WGPURequestAdapterStatus_Unavailable = 0x00000003, + WGPURequestAdapterStatus_Error = 0x00000004, + WGPURequestAdapterStatus_Force32 = 0x7FFFFFFF +} WGPURequestAdapterStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURequestDeviceStatus { + WGPURequestDeviceStatus_Success = 0x00000001, + WGPURequestDeviceStatus_CallbackCancelled = 0x00000002, + WGPURequestDeviceStatus_Error = 0x00000003, + WGPURequestDeviceStatus_Force32 = 0x7FFFFFFF +} WGPURequestDeviceStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSamplerBindingType { + WGPUSamplerBindingType_BindingNotUsed = 0x00000000, + WGPUSamplerBindingType_Undefined = 0x00000001, + WGPUSamplerBindingType_Filtering = 0x00000002, + WGPUSamplerBindingType_NonFiltering = 0x00000003, + WGPUSamplerBindingType_Comparison = 0x00000004, + WGPUSamplerBindingType_Force32 = 0x7FFFFFFF +} WGPUSamplerBindingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStatus { + WGPUStatus_Success = 0x00000001, + WGPUStatus_Error = 0x00000002, + WGPUStatus_Force32 = 0x7FFFFFFF +} WGPUStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStencilOperation { + WGPUStencilOperation_Undefined = 0x00000000, + WGPUStencilOperation_Keep = 0x00000001, + WGPUStencilOperation_Zero = 0x00000002, + WGPUStencilOperation_Replace = 0x00000003, + WGPUStencilOperation_Invert = 0x00000004, + WGPUStencilOperation_IncrementClamp = 0x00000005, + WGPUStencilOperation_DecrementClamp = 0x00000006, + WGPUStencilOperation_IncrementWrap = 0x00000007, + WGPUStencilOperation_DecrementWrap = 0x00000008, + WGPUStencilOperation_Force32 = 0x7FFFFFFF +} WGPUStencilOperation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStorageTextureAccess { + WGPUStorageTextureAccess_BindingNotUsed = 0x00000000, + WGPUStorageTextureAccess_Undefined = 0x00000001, + WGPUStorageTextureAccess_WriteOnly = 0x00000002, + WGPUStorageTextureAccess_ReadOnly = 0x00000003, + WGPUStorageTextureAccess_ReadWrite = 0x00000004, + WGPUStorageTextureAccess_Force32 = 0x7FFFFFFF +} WGPUStorageTextureAccess WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStoreOp { + WGPUStoreOp_Undefined = 0x00000000, + WGPUStoreOp_Store = 0x00000001, + WGPUStoreOp_Discard = 0x00000002, + WGPUStoreOp_Force32 = 0x7FFFFFFF +} WGPUStoreOp WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSType { + WGPUSType_ShaderSourceSPIRV = 0x00000001, + WGPUSType_ShaderSourceWGSL = 0x00000002, + WGPUSType_RenderPassMaxDrawCount = 0x00000003, + WGPUSType_SurfaceSourceMetalLayer = 0x00000004, + WGPUSType_SurfaceSourceWindowsHWND = 0x00000005, + WGPUSType_SurfaceSourceXlibWindow = 0x00000006, + WGPUSType_SurfaceSourceWaylandSurface = 0x00000007, + WGPUSType_SurfaceSourceAndroidNativeWindow = 0x00000008, + WGPUSType_SurfaceSourceXCBWindow = 0x00000009, + WGPUSType_SurfaceColorManagement = 0x0000000A, + WGPUSType_RequestAdapterWebXROptions = 0x0000000B, + WGPUSType_TextureComponentSwizzleDescriptor = 0x0000000C, + WGPUSType_CompatibilityModeLimits = 0x00020000, + WGPUSType_TextureBindingViewDimensionDescriptor = 0x00020001, + WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector = 0x00040000, + WGPUSType_DawnCompilationMessageUtf16 = 0x0005003F, + WGPUSType_Force32 = 0x7FFFFFFF +} WGPUSType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSurfaceGetCurrentTextureStatus { + WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal = 0x00000001, + WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal = 0x00000002, + WGPUSurfaceGetCurrentTextureStatus_Timeout = 0x00000003, + WGPUSurfaceGetCurrentTextureStatus_Outdated = 0x00000004, + WGPUSurfaceGetCurrentTextureStatus_Lost = 0x00000005, + WGPUSurfaceGetCurrentTextureStatus_Error = 0x00000006, + WGPUSurfaceGetCurrentTextureStatus_Force32 = 0x7FFFFFFF +} WGPUSurfaceGetCurrentTextureStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureAspect { + WGPUTextureAspect_Undefined = 0x00000000, + WGPUTextureAspect_All = 0x00000001, + WGPUTextureAspect_StencilOnly = 0x00000002, + WGPUTextureAspect_DepthOnly = 0x00000003, + WGPUTextureAspect_Force32 = 0x7FFFFFFF +} WGPUTextureAspect WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureDimension { + WGPUTextureDimension_Undefined = 0x00000000, + WGPUTextureDimension_1D = 0x00000001, + WGPUTextureDimension_2D = 0x00000002, + WGPUTextureDimension_3D = 0x00000003, + WGPUTextureDimension_Force32 = 0x7FFFFFFF +} WGPUTextureDimension WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureFormat { + WGPUTextureFormat_Undefined = 0x00000000, + WGPUTextureFormat_R8Unorm = 0x00000001, + WGPUTextureFormat_R8Snorm = 0x00000002, + WGPUTextureFormat_R8Uint = 0x00000003, + WGPUTextureFormat_R8Sint = 0x00000004, + WGPUTextureFormat_R16Unorm = 0x00000005, + WGPUTextureFormat_R16Snorm = 0x00000006, + WGPUTextureFormat_R16Uint = 0x00000007, + WGPUTextureFormat_R16Sint = 0x00000008, + WGPUTextureFormat_R16Float = 0x00000009, + WGPUTextureFormat_RG8Unorm = 0x0000000A, + WGPUTextureFormat_RG8Snorm = 0x0000000B, + WGPUTextureFormat_RG8Uint = 0x0000000C, + WGPUTextureFormat_RG8Sint = 0x0000000D, + WGPUTextureFormat_R32Float = 0x0000000E, + WGPUTextureFormat_R32Uint = 0x0000000F, + WGPUTextureFormat_R32Sint = 0x00000010, + WGPUTextureFormat_RG16Unorm = 0x00000011, + WGPUTextureFormat_RG16Snorm = 0x00000012, + WGPUTextureFormat_RG16Uint = 0x00000013, + WGPUTextureFormat_RG16Sint = 0x00000014, + WGPUTextureFormat_RG16Float = 0x00000015, + WGPUTextureFormat_RGBA8Unorm = 0x00000016, + WGPUTextureFormat_RGBA8UnormSrgb = 0x00000017, + WGPUTextureFormat_RGBA8Snorm = 0x00000018, + WGPUTextureFormat_RGBA8Uint = 0x00000019, + WGPUTextureFormat_RGBA8Sint = 0x0000001A, + WGPUTextureFormat_BGRA8Unorm = 0x0000001B, + WGPUTextureFormat_BGRA8UnormSrgb = 0x0000001C, + WGPUTextureFormat_RGB10A2Uint = 0x0000001D, + WGPUTextureFormat_RGB10A2Unorm = 0x0000001E, + WGPUTextureFormat_RG11B10Ufloat = 0x0000001F, + WGPUTextureFormat_RGB9E5Ufloat = 0x00000020, + WGPUTextureFormat_RG32Float = 0x00000021, + WGPUTextureFormat_RG32Uint = 0x00000022, + WGPUTextureFormat_RG32Sint = 0x00000023, + WGPUTextureFormat_RGBA16Unorm = 0x00000024, + WGPUTextureFormat_RGBA16Snorm = 0x00000025, + WGPUTextureFormat_RGBA16Uint = 0x00000026, + WGPUTextureFormat_RGBA16Sint = 0x00000027, + WGPUTextureFormat_RGBA16Float = 0x00000028, + WGPUTextureFormat_RGBA32Float = 0x00000029, + WGPUTextureFormat_RGBA32Uint = 0x0000002A, + WGPUTextureFormat_RGBA32Sint = 0x0000002B, + WGPUTextureFormat_Stencil8 = 0x0000002C, + WGPUTextureFormat_Depth16Unorm = 0x0000002D, + WGPUTextureFormat_Depth24Plus = 0x0000002E, + WGPUTextureFormat_Depth24PlusStencil8 = 0x0000002F, + WGPUTextureFormat_Depth32Float = 0x00000030, + WGPUTextureFormat_Depth32FloatStencil8 = 0x00000031, + WGPUTextureFormat_BC1RGBAUnorm = 0x00000032, + WGPUTextureFormat_BC1RGBAUnormSrgb = 0x00000033, + WGPUTextureFormat_BC2RGBAUnorm = 0x00000034, + WGPUTextureFormat_BC2RGBAUnormSrgb = 0x00000035, + WGPUTextureFormat_BC3RGBAUnorm = 0x00000036, + WGPUTextureFormat_BC3RGBAUnormSrgb = 0x00000037, + WGPUTextureFormat_BC4RUnorm = 0x00000038, + WGPUTextureFormat_BC4RSnorm = 0x00000039, + WGPUTextureFormat_BC5RGUnorm = 0x0000003A, + WGPUTextureFormat_BC5RGSnorm = 0x0000003B, + WGPUTextureFormat_BC6HRGBUfloat = 0x0000003C, + WGPUTextureFormat_BC6HRGBFloat = 0x0000003D, + WGPUTextureFormat_BC7RGBAUnorm = 0x0000003E, + WGPUTextureFormat_BC7RGBAUnormSrgb = 0x0000003F, + WGPUTextureFormat_ETC2RGB8Unorm = 0x00000040, + WGPUTextureFormat_ETC2RGB8UnormSrgb = 0x00000041, + WGPUTextureFormat_ETC2RGB8A1Unorm = 0x00000042, + WGPUTextureFormat_ETC2RGB8A1UnormSrgb = 0x00000043, + WGPUTextureFormat_ETC2RGBA8Unorm = 0x00000044, + WGPUTextureFormat_ETC2RGBA8UnormSrgb = 0x00000045, + WGPUTextureFormat_EACR11Unorm = 0x00000046, + WGPUTextureFormat_EACR11Snorm = 0x00000047, + WGPUTextureFormat_EACRG11Unorm = 0x00000048, + WGPUTextureFormat_EACRG11Snorm = 0x00000049, + WGPUTextureFormat_ASTC4x4Unorm = 0x0000004A, + WGPUTextureFormat_ASTC4x4UnormSrgb = 0x0000004B, + WGPUTextureFormat_ASTC5x4Unorm = 0x0000004C, + WGPUTextureFormat_ASTC5x4UnormSrgb = 0x0000004D, + WGPUTextureFormat_ASTC5x5Unorm = 0x0000004E, + WGPUTextureFormat_ASTC5x5UnormSrgb = 0x0000004F, + WGPUTextureFormat_ASTC6x5Unorm = 0x00000050, + WGPUTextureFormat_ASTC6x5UnormSrgb = 0x00000051, + WGPUTextureFormat_ASTC6x6Unorm = 0x00000052, + WGPUTextureFormat_ASTC6x6UnormSrgb = 0x00000053, + WGPUTextureFormat_ASTC8x5Unorm = 0x00000054, + WGPUTextureFormat_ASTC8x5UnormSrgb = 0x00000055, + WGPUTextureFormat_ASTC8x6Unorm = 0x00000056, + WGPUTextureFormat_ASTC8x6UnormSrgb = 0x00000057, + WGPUTextureFormat_ASTC8x8Unorm = 0x00000058, + WGPUTextureFormat_ASTC8x8UnormSrgb = 0x00000059, + WGPUTextureFormat_ASTC10x5Unorm = 0x0000005A, + WGPUTextureFormat_ASTC10x5UnormSrgb = 0x0000005B, + WGPUTextureFormat_ASTC10x6Unorm = 0x0000005C, + WGPUTextureFormat_ASTC10x6UnormSrgb = 0x0000005D, + WGPUTextureFormat_ASTC10x8Unorm = 0x0000005E, + WGPUTextureFormat_ASTC10x8UnormSrgb = 0x0000005F, + WGPUTextureFormat_ASTC10x10Unorm = 0x00000060, + WGPUTextureFormat_ASTC10x10UnormSrgb = 0x00000061, + WGPUTextureFormat_ASTC12x10Unorm = 0x00000062, + WGPUTextureFormat_ASTC12x10UnormSrgb = 0x00000063, + WGPUTextureFormat_ASTC12x12Unorm = 0x00000064, + WGPUTextureFormat_ASTC12x12UnormSrgb = 0x00000065, + WGPUTextureFormat_Force32 = 0x7FFFFFFF +} WGPUTextureFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureSampleType { + WGPUTextureSampleType_BindingNotUsed = 0x00000000, + WGPUTextureSampleType_Undefined = 0x00000001, + WGPUTextureSampleType_Float = 0x00000002, + WGPUTextureSampleType_UnfilterableFloat = 0x00000003, + WGPUTextureSampleType_Depth = 0x00000004, + WGPUTextureSampleType_Sint = 0x00000005, + WGPUTextureSampleType_Uint = 0x00000006, + WGPUTextureSampleType_Force32 = 0x7FFFFFFF +} WGPUTextureSampleType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureViewDimension { + WGPUTextureViewDimension_Undefined = 0x00000000, + WGPUTextureViewDimension_1D = 0x00000001, + WGPUTextureViewDimension_2D = 0x00000002, + WGPUTextureViewDimension_2DArray = 0x00000003, + WGPUTextureViewDimension_Cube = 0x00000004, + WGPUTextureViewDimension_CubeArray = 0x00000005, + WGPUTextureViewDimension_3D = 0x00000006, + WGPUTextureViewDimension_Force32 = 0x7FFFFFFF +} WGPUTextureViewDimension WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUToneMappingMode { + WGPUToneMappingMode_Standard = 0x00000001, + WGPUToneMappingMode_Extended = 0x00000002, + WGPUToneMappingMode_Force32 = 0x7FFFFFFF +} WGPUToneMappingMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUVertexFormat { + WGPUVertexFormat_Uint8 = 0x00000001, + WGPUVertexFormat_Uint8x2 = 0x00000002, + WGPUVertexFormat_Uint8x4 = 0x00000003, + WGPUVertexFormat_Sint8 = 0x00000004, + WGPUVertexFormat_Sint8x2 = 0x00000005, + WGPUVertexFormat_Sint8x4 = 0x00000006, + WGPUVertexFormat_Unorm8 = 0x00000007, + WGPUVertexFormat_Unorm8x2 = 0x00000008, + WGPUVertexFormat_Unorm8x4 = 0x00000009, + WGPUVertexFormat_Snorm8 = 0x0000000A, + WGPUVertexFormat_Snorm8x2 = 0x0000000B, + WGPUVertexFormat_Snorm8x4 = 0x0000000C, + WGPUVertexFormat_Uint16 = 0x0000000D, + WGPUVertexFormat_Uint16x2 = 0x0000000E, + WGPUVertexFormat_Uint16x4 = 0x0000000F, + WGPUVertexFormat_Sint16 = 0x00000010, + WGPUVertexFormat_Sint16x2 = 0x00000011, + WGPUVertexFormat_Sint16x4 = 0x00000012, + WGPUVertexFormat_Unorm16 = 0x00000013, + WGPUVertexFormat_Unorm16x2 = 0x00000014, + WGPUVertexFormat_Unorm16x4 = 0x00000015, + WGPUVertexFormat_Snorm16 = 0x00000016, + WGPUVertexFormat_Snorm16x2 = 0x00000017, + WGPUVertexFormat_Snorm16x4 = 0x00000018, + WGPUVertexFormat_Float16 = 0x00000019, + WGPUVertexFormat_Float16x2 = 0x0000001A, + WGPUVertexFormat_Float16x4 = 0x0000001B, + WGPUVertexFormat_Float32 = 0x0000001C, + WGPUVertexFormat_Float32x2 = 0x0000001D, + WGPUVertexFormat_Float32x3 = 0x0000001E, + WGPUVertexFormat_Float32x4 = 0x0000001F, + WGPUVertexFormat_Uint32 = 0x00000020, + WGPUVertexFormat_Uint32x2 = 0x00000021, + WGPUVertexFormat_Uint32x3 = 0x00000022, + WGPUVertexFormat_Uint32x4 = 0x00000023, + WGPUVertexFormat_Sint32 = 0x00000024, + WGPUVertexFormat_Sint32x2 = 0x00000025, + WGPUVertexFormat_Sint32x3 = 0x00000026, + WGPUVertexFormat_Sint32x4 = 0x00000027, + WGPUVertexFormat_Unorm10_10_10_2 = 0x00000028, + WGPUVertexFormat_Unorm8x4BGRA = 0x00000029, + WGPUVertexFormat_Force32 = 0x7FFFFFFF +} WGPUVertexFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUVertexStepMode { + WGPUVertexStepMode_Undefined = 0x00000000, + WGPUVertexStepMode_Vertex = 0x00000001, + WGPUVertexStepMode_Instance = 0x00000002, + WGPUVertexStepMode_Force32 = 0x7FFFFFFF +} WGPUVertexStepMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUWaitStatus { + WGPUWaitStatus_Success = 0x00000001, + WGPUWaitStatus_TimedOut = 0x00000002, + WGPUWaitStatus_Error = 0x00000003, + WGPUWaitStatus_Force32 = 0x7FFFFFFF +} WGPUWaitStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUWGSLLanguageFeatureName { + WGPUWGSLLanguageFeatureName_ReadonlyAndReadwriteStorageTextures = 0x00000001, + WGPUWGSLLanguageFeatureName_Packed4x8IntegerDotProduct = 0x00000002, + WGPUWGSLLanguageFeatureName_UnrestrictedPointerParameters = 0x00000003, + WGPUWGSLLanguageFeatureName_PointerCompositeAccess = 0x00000004, + WGPUWGSLLanguageFeatureName_Force32 = 0x7FFFFFFF +} WGPUWGSLLanguageFeatureName WGPU_ENUM_ATTRIBUTE; + +typedef WGPUFlags WGPUBufferUsage; +static const WGPUBufferUsage WGPUBufferUsage_None = 0x0000000000000000; +static const WGPUBufferUsage WGPUBufferUsage_MapRead = 0x0000000000000001; +static const WGPUBufferUsage WGPUBufferUsage_MapWrite = 0x0000000000000002; +static const WGPUBufferUsage WGPUBufferUsage_CopySrc = 0x0000000000000004; +static const WGPUBufferUsage WGPUBufferUsage_CopyDst = 0x0000000000000008; +static const WGPUBufferUsage WGPUBufferUsage_Index = 0x0000000000000010; +static const WGPUBufferUsage WGPUBufferUsage_Vertex = 0x0000000000000020; +static const WGPUBufferUsage WGPUBufferUsage_Uniform = 0x0000000000000040; +static const WGPUBufferUsage WGPUBufferUsage_Storage = 0x0000000000000080; +static const WGPUBufferUsage WGPUBufferUsage_Indirect = 0x0000000000000100; +static const WGPUBufferUsage WGPUBufferUsage_QueryResolve = 0x0000000000000200; + +typedef WGPUFlags WGPUColorWriteMask; +static const WGPUColorWriteMask WGPUColorWriteMask_None = 0x0000000000000000; +static const WGPUColorWriteMask WGPUColorWriteMask_Red = 0x0000000000000001; +static const WGPUColorWriteMask WGPUColorWriteMask_Green = 0x0000000000000002; +static const WGPUColorWriteMask WGPUColorWriteMask_Blue = 0x0000000000000004; +static const WGPUColorWriteMask WGPUColorWriteMask_Alpha = 0x0000000000000008; +static const WGPUColorWriteMask WGPUColorWriteMask_All = 0x000000000000000F; + +typedef WGPUFlags WGPUMapMode; +static const WGPUMapMode WGPUMapMode_None = 0x0000000000000000; +static const WGPUMapMode WGPUMapMode_Read = 0x0000000000000001; +static const WGPUMapMode WGPUMapMode_Write = 0x0000000000000002; + +typedef WGPUFlags WGPUShaderStage; +static const WGPUShaderStage WGPUShaderStage_None = 0x0000000000000000; +static const WGPUShaderStage WGPUShaderStage_Vertex = 0x0000000000000001; +static const WGPUShaderStage WGPUShaderStage_Fragment = 0x0000000000000002; +static const WGPUShaderStage WGPUShaderStage_Compute = 0x0000000000000004; + +typedef WGPUFlags WGPUTextureUsage; +static const WGPUTextureUsage WGPUTextureUsage_None = 0x0000000000000000; +static const WGPUTextureUsage WGPUTextureUsage_CopySrc = 0x0000000000000001; +static const WGPUTextureUsage WGPUTextureUsage_CopyDst = 0x0000000000000002; +static const WGPUTextureUsage WGPUTextureUsage_TextureBinding = 0x0000000000000004; +static const WGPUTextureUsage WGPUTextureUsage_StorageBinding = 0x0000000000000008; +static const WGPUTextureUsage WGPUTextureUsage_RenderAttachment = 0x0000000000000010; + +typedef void (*WGPUProc)(void) WGPU_FUNCTION_ATTRIBUTE; + +// Callback function pointers +typedef void (*WGPUBufferMapCallback)(WGPUMapAsyncStatus status, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUCompilationInfoCallback)(WGPUCompilationInfoRequestStatus status, struct WGPUCompilationInfo const * compilationInfo, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUCreateComputePipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUCreateRenderPipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUDeviceLostCallback)(WGPUDevice const * device, WGPUDeviceLostReason reason, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUPopErrorScopeCallback)(WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUQueueWorkDoneCallback)(WGPUQueueWorkDoneStatus status, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPURequestAdapterCallback)(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPURequestDeviceCallback)(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef void (*WGPUUncapturedErrorCallback)(WGPUDevice const * device, WGPUErrorType type, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef struct WGPUChainedStruct { + struct WGPUChainedStruct * next; + WGPUSType sType; +} WGPUChainedStruct WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBufferMapCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUBufferMapCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUBufferMapCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BUFFER_MAP_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBufferMapCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUCompilationInfoCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUCompilationInfoCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUCompilationInfoCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPILATION_INFO_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCompilationInfoCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUCreateComputePipelineAsyncCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUCreateComputePipelineAsyncCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUCreateComputePipelineAsyncCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_CREATE_COMPUTE_PIPELINE_ASYNC_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCreateComputePipelineAsyncCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUCreateRenderPipelineAsyncCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUCreateRenderPipelineAsyncCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUCreateRenderPipelineAsyncCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_CREATE_RENDER_PIPELINE_ASYNC_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCreateRenderPipelineAsyncCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUDeviceLostCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUDeviceLostCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUDeviceLostCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_DEVICE_LOST_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUDeviceLostCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUPopErrorScopeCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUPopErrorScopeCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUPopErrorScopeCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_POP_ERROR_SCOPE_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUPopErrorScopeCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUQueueWorkDoneCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPUQueueWorkDoneCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUQueueWorkDoneCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_QUEUE_WORK_DONE_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUQueueWorkDoneCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPURequestAdapterCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPURequestAdapterCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPURequestAdapterCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_REQUEST_ADAPTER_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPURequestAdapterCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPURequestDeviceCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUCallbackMode mode; + WGPURequestDeviceCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPURequestDeviceCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_REQUEST_DEVICE_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPURequestDeviceCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.mode=*/_wgpu_ENUM_ZERO_INIT(WGPUCallbackMode) _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUUncapturedErrorCallbackInfo { + WGPUChainedStruct * nextInChain; + WGPUUncapturedErrorCallback callback; + WGPU_NULLABLE void* userdata1; + WGPU_NULLABLE void* userdata2; +} WGPUUncapturedErrorCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_UNCAPTURED_ERROR_CALLBACK_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUUncapturedErrorCallbackInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.callback=*/NULL _wgpu_COMMA \ + /*.userdata1=*/NULL _wgpu_COMMA \ + /*.userdata2=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUAdapterInfo { + WGPUChainedStruct * nextInChain; + WGPUStringView vendor; + WGPUStringView architecture; + WGPUStringView device; + WGPUStringView description; + WGPUBackendType backendType; + WGPUAdapterType adapterType; + uint32_t vendorID; + uint32_t deviceID; + uint32_t subgroupMinSize; + uint32_t subgroupMaxSize; +} WGPUAdapterInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_ADAPTER_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUAdapterInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.vendor=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.architecture=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.device=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.description=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.backendType=*/WGPUBackendType_Undefined _wgpu_COMMA \ + /*.adapterType=*/_wgpu_ENUM_ZERO_INIT(WGPUAdapterType) _wgpu_COMMA \ + /*.vendorID=*/0 _wgpu_COMMA \ + /*.deviceID=*/0 _wgpu_COMMA \ + /*.subgroupMinSize=*/0 _wgpu_COMMA \ + /*.subgroupMaxSize=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUBindGroupEntry { + WGPUChainedStruct * nextInChain; + uint32_t binding; + WGPU_NULLABLE WGPUBuffer buffer; + uint64_t offset; + uint64_t size; + WGPU_NULLABLE WGPUSampler sampler; + WGPU_NULLABLE WGPUTextureView textureView; +} WGPUBindGroupEntry WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BIND_GROUP_ENTRY_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBindGroupEntry, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.binding=*/0 _wgpu_COMMA \ + /*.buffer=*/NULL _wgpu_COMMA \ + /*.offset=*/0 _wgpu_COMMA \ + /*.size=*/WGPU_WHOLE_SIZE _wgpu_COMMA \ + /*.sampler=*/NULL _wgpu_COMMA \ + /*.textureView=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUBlendComponent { + WGPUBlendOperation operation; + WGPUBlendFactor srcFactor; + WGPUBlendFactor dstFactor; +} WGPUBlendComponent WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BLEND_COMPONENT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBlendComponent, { \ + /*.operation=*/WGPUBlendOperation_Undefined _wgpu_COMMA \ + /*.srcFactor=*/WGPUBlendFactor_Undefined _wgpu_COMMA \ + /*.dstFactor=*/WGPUBlendFactor_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUBufferBindingLayout { + WGPUChainedStruct * nextInChain; + WGPUBufferBindingType type; + WGPUBool hasDynamicOffset; + uint64_t minBindingSize; +} WGPUBufferBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BUFFER_BINDING_LAYOUT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBufferBindingLayout, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.type=*/WGPUBufferBindingType_Undefined _wgpu_COMMA \ + /*.hasDynamicOffset=*/WGPU_FALSE _wgpu_COMMA \ + /*.minBindingSize=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUBufferDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPUBufferUsage usage; + uint64_t size; + WGPUBool mappedAtCreation; +} WGPUBufferDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BUFFER_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBufferDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.usage=*/WGPUBufferUsage_None _wgpu_COMMA \ + /*.size=*/0 _wgpu_COMMA \ + /*.mappedAtCreation=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPUColor { + double r; + double g; + double b; + double a; +} WGPUColor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COLOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUColor, { \ + /*.r=*/0. _wgpu_COMMA \ + /*.g=*/0. _wgpu_COMMA \ + /*.b=*/0. _wgpu_COMMA \ + /*.a=*/0. _wgpu_COMMA \ +}) + +typedef struct WGPUCommandBufferDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; +} WGPUCommandBufferDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMMAND_BUFFER_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCommandBufferDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUCommandEncoderDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; +} WGPUCommandEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMMAND_ENCODER_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCommandEncoderDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +// Can be chained in WGPULimits +typedef struct WGPUCompatibilityModeLimits { + WGPUChainedStruct chain; + uint32_t maxStorageBuffersInVertexStage; + uint32_t maxStorageTexturesInVertexStage; + uint32_t maxStorageBuffersInFragmentStage; + uint32_t maxStorageTexturesInFragmentStage; +} WGPUCompatibilityModeLimits WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPATIBILITY_MODE_LIMITS_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCompatibilityModeLimits, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_CompatibilityModeLimits _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.maxStorageBuffersInVertexStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxStorageTexturesInVertexStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxStorageBuffersInFragmentStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxStorageTexturesInFragmentStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ +}) + +typedef struct WGPUConstantEntry { + WGPUChainedStruct * nextInChain; + WGPUStringView key; + double value; +} WGPUConstantEntry WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_CONSTANT_ENTRY_INIT _wgpu_MAKE_INIT_STRUCT(WGPUConstantEntry, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.key=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.value=*/0. _wgpu_COMMA \ +}) + +// Can be chained in WGPUCompilationMessage +typedef struct WGPUDawnCompilationMessageUtf16 { + WGPUChainedStruct chain; + uint64_t linePos; + uint64_t offset; + uint64_t length; +} WGPUDawnCompilationMessageUtf16 WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_DAWN_COMPILATION_MESSAGE_UTF16_INIT _wgpu_MAKE_INIT_STRUCT(WGPUDawnCompilationMessageUtf16, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_DawnCompilationMessageUtf16 _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.linePos=*/0 _wgpu_COMMA \ + /*.offset=*/0 _wgpu_COMMA \ + /*.length=*/0 _wgpu_COMMA \ +}) + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUEmscriptenSurfaceSourceCanvasHTMLSelector { + WGPUChainedStruct chain; + WGPUStringView selector; +} WGPUEmscriptenSurfaceSourceCanvasHTMLSelector WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_EMSCRIPTEN_SURFACE_SOURCE_CANVAS_HTML_SELECTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUEmscriptenSurfaceSourceCanvasHTMLSelector, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.selector=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUExtent3D { + uint32_t width; + uint32_t height; + uint32_t depthOrArrayLayers; +} WGPUExtent3D WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_EXTENT_3D_INIT _wgpu_MAKE_INIT_STRUCT(WGPUExtent3D, { \ + /*.width=*/0 _wgpu_COMMA \ + /*.height=*/1 _wgpu_COMMA \ + /*.depthOrArrayLayers=*/1 _wgpu_COMMA \ +}) + +typedef struct WGPUFuture { + uint64_t id; +} WGPUFuture WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_FUTURE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUFuture, { \ + /*.id=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUInstanceLimits { + WGPUChainedStruct * nextInChain; + size_t timedWaitAnyMaxCount; +} WGPUInstanceLimits WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_INSTANCE_LIMITS_INIT _wgpu_MAKE_INIT_STRUCT(WGPUInstanceLimits, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.timedWaitAnyMaxCount=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER { + WGPUBool unused; +} WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_INTERNAL_HAVE_EMDAWNWEBGPU_HEADER_INIT _wgpu_MAKE_INIT_STRUCT(WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER, { \ + /*.unused=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPUMultisampleState { + WGPUChainedStruct * nextInChain; + uint32_t count; + uint32_t mask; + WGPUBool alphaToCoverageEnabled; +} WGPUMultisampleState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_MULTISAMPLE_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUMultisampleState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.count=*/1 _wgpu_COMMA \ + /*.mask=*/0xFFFFFFFF _wgpu_COMMA \ + /*.alphaToCoverageEnabled=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPUOrigin3D { + uint32_t x; + uint32_t y; + uint32_t z; +} WGPUOrigin3D WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_ORIGIN_3D_INIT _wgpu_MAKE_INIT_STRUCT(WGPUOrigin3D, { \ + /*.x=*/0 _wgpu_COMMA \ + /*.y=*/0 _wgpu_COMMA \ + /*.z=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUPassTimestampWrites { + WGPUChainedStruct * nextInChain; + WGPUQuerySet querySet; + uint32_t beginningOfPassWriteIndex; + uint32_t endOfPassWriteIndex; +} WGPUPassTimestampWrites WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_PASS_TIMESTAMP_WRITES_INIT _wgpu_MAKE_INIT_STRUCT(WGPUPassTimestampWrites, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.querySet=*/NULL _wgpu_COMMA \ + /*.beginningOfPassWriteIndex=*/WGPU_QUERY_SET_INDEX_UNDEFINED _wgpu_COMMA \ + /*.endOfPassWriteIndex=*/WGPU_QUERY_SET_INDEX_UNDEFINED _wgpu_COMMA \ +}) + +typedef struct WGPUPipelineLayoutDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + size_t bindGroupLayoutCount; + WGPUBindGroupLayout const * bindGroupLayouts; + uint32_t immediateSize; +} WGPUPipelineLayoutDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_PIPELINE_LAYOUT_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUPipelineLayoutDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.bindGroupLayoutCount=*/0 _wgpu_COMMA \ + /*.bindGroupLayouts=*/NULL _wgpu_COMMA \ + /*.immediateSize=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUPrimitiveState { + WGPUChainedStruct * nextInChain; + WGPUPrimitiveTopology topology; + WGPUIndexFormat stripIndexFormat; + WGPUFrontFace frontFace; + WGPUCullMode cullMode; + WGPUBool unclippedDepth; +} WGPUPrimitiveState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_PRIMITIVE_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUPrimitiveState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.topology=*/WGPUPrimitiveTopology_Undefined _wgpu_COMMA \ + /*.stripIndexFormat=*/WGPUIndexFormat_Undefined _wgpu_COMMA \ + /*.frontFace=*/WGPUFrontFace_Undefined _wgpu_COMMA \ + /*.cullMode=*/WGPUCullMode_Undefined _wgpu_COMMA \ + /*.unclippedDepth=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPUQuerySetDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPUQueryType type; + uint32_t count; +} WGPUQuerySetDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_QUERY_SET_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUQuerySetDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.type=*/_wgpu_ENUM_ZERO_INIT(WGPUQueryType) _wgpu_COMMA \ + /*.count=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUQueueDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; +} WGPUQueueDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_QUEUE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUQueueDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPURenderBundleDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; +} WGPURenderBundleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_BUNDLE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderBundleDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPURenderBundleEncoderDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + size_t colorFormatCount; + WGPUTextureFormat const * colorFormats; + WGPUTextureFormat depthStencilFormat; + uint32_t sampleCount; + WGPUBool depthReadOnly; + WGPUBool stencilReadOnly; +} WGPURenderBundleEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_BUNDLE_ENCODER_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderBundleEncoderDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.colorFormatCount=*/0 _wgpu_COMMA \ + /*.colorFormats=*/NULL _wgpu_COMMA \ + /*.depthStencilFormat=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.sampleCount=*/1 _wgpu_COMMA \ + /*.depthReadOnly=*/WGPU_FALSE _wgpu_COMMA \ + /*.stencilReadOnly=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPURenderPassDepthStencilAttachment { + WGPUChainedStruct * nextInChain; + WGPUTextureView view; + WGPULoadOp depthLoadOp; + WGPUStoreOp depthStoreOp; + float depthClearValue; + WGPUBool depthReadOnly; + WGPULoadOp stencilLoadOp; + WGPUStoreOp stencilStoreOp; + uint32_t stencilClearValue; + WGPUBool stencilReadOnly; +} WGPURenderPassDepthStencilAttachment WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderPassDepthStencilAttachment, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.view=*/NULL _wgpu_COMMA \ + /*.depthLoadOp=*/WGPULoadOp_Undefined _wgpu_COMMA \ + /*.depthStoreOp=*/WGPUStoreOp_Undefined _wgpu_COMMA \ + /*.depthClearValue=*/WGPU_DEPTH_CLEAR_VALUE_UNDEFINED _wgpu_COMMA \ + /*.depthReadOnly=*/WGPU_FALSE _wgpu_COMMA \ + /*.stencilLoadOp=*/WGPULoadOp_Undefined _wgpu_COMMA \ + /*.stencilStoreOp=*/WGPUStoreOp_Undefined _wgpu_COMMA \ + /*.stencilClearValue=*/0 _wgpu_COMMA \ + /*.stencilReadOnly=*/WGPU_FALSE _wgpu_COMMA \ +}) + +// Can be chained in WGPURenderPassDescriptor +typedef struct WGPURenderPassMaxDrawCount { + WGPUChainedStruct chain; + uint64_t maxDrawCount; +} WGPURenderPassMaxDrawCount WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_PASS_MAX_DRAW_COUNT_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderPassMaxDrawCount, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_RenderPassMaxDrawCount _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.maxDrawCount=*/50000000 _wgpu_COMMA \ +}) + +// Can be chained in WGPURequestAdapterOptions +typedef struct WGPURequestAdapterWebXROptions { + WGPUChainedStruct chain; + WGPUBool xrCompatible; +} WGPURequestAdapterWebXROptions WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_REQUEST_ADAPTER_WEBXR_OPTIONS_INIT _wgpu_MAKE_INIT_STRUCT(WGPURequestAdapterWebXROptions, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_RequestAdapterWebXROptions _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.xrCompatible=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPUSamplerBindingLayout { + WGPUChainedStruct * nextInChain; + WGPUSamplerBindingType type; +} WGPUSamplerBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SAMPLER_BINDING_LAYOUT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSamplerBindingLayout, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.type=*/WGPUSamplerBindingType_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUSamplerDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPUAddressMode addressModeU; + WGPUAddressMode addressModeV; + WGPUAddressMode addressModeW; + WGPUFilterMode magFilter; + WGPUFilterMode minFilter; + WGPUMipmapFilterMode mipmapFilter; + float lodMinClamp; + float lodMaxClamp; + WGPUCompareFunction compare; + uint16_t maxAnisotropy; +} WGPUSamplerDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SAMPLER_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSamplerDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.addressModeU=*/WGPUAddressMode_Undefined _wgpu_COMMA \ + /*.addressModeV=*/WGPUAddressMode_Undefined _wgpu_COMMA \ + /*.addressModeW=*/WGPUAddressMode_Undefined _wgpu_COMMA \ + /*.magFilter=*/WGPUFilterMode_Undefined _wgpu_COMMA \ + /*.minFilter=*/WGPUFilterMode_Undefined _wgpu_COMMA \ + /*.mipmapFilter=*/WGPUMipmapFilterMode_Undefined _wgpu_COMMA \ + /*.lodMinClamp=*/0.f _wgpu_COMMA \ + /*.lodMaxClamp=*/32.f _wgpu_COMMA \ + /*.compare=*/WGPUCompareFunction_Undefined _wgpu_COMMA \ + /*.maxAnisotropy=*/1 _wgpu_COMMA \ +}) + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUShaderSourceSPIRV { + WGPUChainedStruct chain; + uint32_t codeSize; + uint32_t const * code; +} WGPUShaderSourceSPIRV WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SHADER_SOURCE_SPIRV_INIT _wgpu_MAKE_INIT_STRUCT(WGPUShaderSourceSPIRV, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_ShaderSourceSPIRV _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.codeSize=*/0 _wgpu_COMMA \ + /*.code=*/NULL _wgpu_COMMA \ +}) + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUShaderSourceWGSL { + WGPUChainedStruct chain; + WGPUStringView code; +} WGPUShaderSourceWGSL WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SHADER_SOURCE_WGSL_INIT _wgpu_MAKE_INIT_STRUCT(WGPUShaderSourceWGSL, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_ShaderSourceWGSL _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.code=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUStencilFaceState { + WGPUCompareFunction compare; + WGPUStencilOperation failOp; + WGPUStencilOperation depthFailOp; + WGPUStencilOperation passOp; +} WGPUStencilFaceState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_STENCIL_FACE_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUStencilFaceState, { \ + /*.compare=*/WGPUCompareFunction_Undefined _wgpu_COMMA \ + /*.failOp=*/WGPUStencilOperation_Undefined _wgpu_COMMA \ + /*.depthFailOp=*/WGPUStencilOperation_Undefined _wgpu_COMMA \ + /*.passOp=*/WGPUStencilOperation_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUStorageTextureBindingLayout { + WGPUChainedStruct * nextInChain; + WGPUStorageTextureAccess access; + WGPUTextureFormat format; + WGPUTextureViewDimension viewDimension; +} WGPUStorageTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_STORAGE_TEXTURE_BINDING_LAYOUT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUStorageTextureBindingLayout, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.access=*/WGPUStorageTextureAccess_Undefined _wgpu_COMMA \ + /*.format=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.viewDimension=*/WGPUTextureViewDimension_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUSupportedFeatures { + size_t featureCount; + WGPUFeatureName const * features; +} WGPUSupportedFeatures WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SUPPORTED_FEATURES_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSupportedFeatures, { \ + /*.featureCount=*/0 _wgpu_COMMA \ + /*.features=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUSupportedInstanceFeatures { + size_t featureCount; + WGPUInstanceFeatureName const * features; +} WGPUSupportedInstanceFeatures WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SUPPORTED_INSTANCE_FEATURES_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSupportedInstanceFeatures, { \ + /*.featureCount=*/0 _wgpu_COMMA \ + /*.features=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUSupportedWGSLLanguageFeatures { + size_t featureCount; + WGPUWGSLLanguageFeatureName const * features; +} WGPUSupportedWGSLLanguageFeatures WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SUPPORTED_WGSL_LANGUAGE_FEATURES_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSupportedWGSLLanguageFeatures, { \ + /*.featureCount=*/0 _wgpu_COMMA \ + /*.features=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUSurfaceCapabilities { + WGPUChainedStruct * nextInChain; + WGPUTextureUsage usages; + size_t formatCount; + WGPUTextureFormat const * formats; + size_t presentModeCount; + WGPUPresentMode const * presentModes; + size_t alphaModeCount; + WGPUCompositeAlphaMode const * alphaModes; +} WGPUSurfaceCapabilities WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SURFACE_CAPABILITIES_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSurfaceCapabilities, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.usages=*/WGPUTextureUsage_None _wgpu_COMMA \ + /*.formatCount=*/0 _wgpu_COMMA \ + /*.formats=*/NULL _wgpu_COMMA \ + /*.presentModeCount=*/0 _wgpu_COMMA \ + /*.presentModes=*/NULL _wgpu_COMMA \ + /*.alphaModeCount=*/0 _wgpu_COMMA \ + /*.alphaModes=*/NULL _wgpu_COMMA \ +}) + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceColorManagement { + WGPUChainedStruct chain; + WGPUPredefinedColorSpace colorSpace; + WGPUToneMappingMode toneMappingMode; +} WGPUSurfaceColorManagement WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SURFACE_COLOR_MANAGEMENT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSurfaceColorManagement, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_SurfaceColorManagement _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.colorSpace=*/_wgpu_ENUM_ZERO_INIT(WGPUPredefinedColorSpace) _wgpu_COMMA \ + /*.toneMappingMode=*/_wgpu_ENUM_ZERO_INIT(WGPUToneMappingMode) _wgpu_COMMA \ +}) + +typedef struct WGPUSurfaceConfiguration { + WGPUChainedStruct * nextInChain; + WGPUDevice device; + WGPUTextureFormat format; + WGPUTextureUsage usage; + uint32_t width; + uint32_t height; + size_t viewFormatCount; + WGPUTextureFormat const * viewFormats; + WGPUCompositeAlphaMode alphaMode; + WGPUPresentMode presentMode; +} WGPUSurfaceConfiguration WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SURFACE_CONFIGURATION_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSurfaceConfiguration, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.device=*/NULL _wgpu_COMMA \ + /*.format=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.usage=*/WGPUTextureUsage_RenderAttachment _wgpu_COMMA \ + /*.width=*/0 _wgpu_COMMA \ + /*.height=*/0 _wgpu_COMMA \ + /*.viewFormatCount=*/0 _wgpu_COMMA \ + /*.viewFormats=*/NULL _wgpu_COMMA \ + /*.alphaMode=*/WGPUCompositeAlphaMode_Auto _wgpu_COMMA \ + /*.presentMode=*/WGPUPresentMode_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUSurfaceTexture { + WGPUChainedStruct * nextInChain; + WGPUTexture texture; + WGPUSurfaceGetCurrentTextureStatus status; +} WGPUSurfaceTexture WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SURFACE_TEXTURE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSurfaceTexture, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.texture=*/NULL _wgpu_COMMA \ + /*.status=*/_wgpu_ENUM_ZERO_INIT(WGPUSurfaceGetCurrentTextureStatus) _wgpu_COMMA \ +}) + +typedef struct WGPUTexelCopyBufferLayout { + uint64_t offset; + uint32_t bytesPerRow; + uint32_t rowsPerImage; +} WGPUTexelCopyBufferLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXEL_COPY_BUFFER_LAYOUT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTexelCopyBufferLayout, { \ + /*.offset=*/0 _wgpu_COMMA \ + /*.bytesPerRow=*/WGPU_COPY_STRIDE_UNDEFINED _wgpu_COMMA \ + /*.rowsPerImage=*/WGPU_COPY_STRIDE_UNDEFINED _wgpu_COMMA \ +}) + +typedef struct WGPUTextureBindingLayout { + WGPUChainedStruct * nextInChain; + WGPUTextureSampleType sampleType; + WGPUTextureViewDimension viewDimension; + WGPUBool multisampled; +} WGPUTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXTURE_BINDING_LAYOUT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTextureBindingLayout, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.sampleType=*/WGPUTextureSampleType_Undefined _wgpu_COMMA \ + /*.viewDimension=*/WGPUTextureViewDimension_Undefined _wgpu_COMMA \ + /*.multisampled=*/WGPU_FALSE _wgpu_COMMA \ +}) + +// Can be chained in WGPUTextureDescriptor +typedef struct WGPUTextureBindingViewDimensionDescriptor { + WGPUChainedStruct chain; + WGPUTextureViewDimension textureBindingViewDimension; +} WGPUTextureBindingViewDimensionDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXTURE_BINDING_VIEW_DIMENSION_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTextureBindingViewDimensionDescriptor, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_TextureBindingViewDimensionDescriptor _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.textureBindingViewDimension=*/WGPUTextureViewDimension_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUTextureComponentSwizzle { + WGPUComponentSwizzle r; + WGPUComponentSwizzle g; + WGPUComponentSwizzle b; + WGPUComponentSwizzle a; +} WGPUTextureComponentSwizzle WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXTURE_COMPONENT_SWIZZLE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTextureComponentSwizzle, { \ + /*.r=*/WGPUComponentSwizzle_Undefined _wgpu_COMMA \ + /*.g=*/WGPUComponentSwizzle_Undefined _wgpu_COMMA \ + /*.b=*/WGPUComponentSwizzle_Undefined _wgpu_COMMA \ + /*.a=*/WGPUComponentSwizzle_Undefined _wgpu_COMMA \ +}) + +typedef struct WGPUVertexAttribute { + WGPUChainedStruct * nextInChain; + WGPUVertexFormat format; + uint64_t offset; + uint32_t shaderLocation; +} WGPUVertexAttribute WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_VERTEX_ATTRIBUTE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUVertexAttribute, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.format=*/_wgpu_ENUM_ZERO_INIT(WGPUVertexFormat) _wgpu_COMMA \ + /*.offset=*/0 _wgpu_COMMA \ + /*.shaderLocation=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUBindGroupDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPUBindGroupLayout layout; + size_t entryCount; + WGPUBindGroupEntry const * entries; +} WGPUBindGroupDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BIND_GROUP_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBindGroupDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.layout=*/NULL _wgpu_COMMA \ + /*.entryCount=*/0 _wgpu_COMMA \ + /*.entries=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUBindGroupLayoutEntry { + WGPUChainedStruct * nextInChain; + uint32_t binding; + WGPUShaderStage visibility; + uint32_t bindingArraySize; + WGPUBufferBindingLayout buffer; + WGPUSamplerBindingLayout sampler; + WGPUTextureBindingLayout texture; + WGPUStorageTextureBindingLayout storageTexture; +} WGPUBindGroupLayoutEntry WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BIND_GROUP_LAYOUT_ENTRY_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBindGroupLayoutEntry, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.binding=*/0 _wgpu_COMMA \ + /*.visibility=*/WGPUShaderStage_None _wgpu_COMMA \ + /*.bindingArraySize=*/0 _wgpu_COMMA \ + /*.buffer=*/_wgpu_STRUCT_ZERO_INIT _wgpu_COMMA \ + /*.sampler=*/_wgpu_STRUCT_ZERO_INIT _wgpu_COMMA \ + /*.texture=*/_wgpu_STRUCT_ZERO_INIT _wgpu_COMMA \ + /*.storageTexture=*/_wgpu_STRUCT_ZERO_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUBlendState { + WGPUBlendComponent color; + WGPUBlendComponent alpha; +} WGPUBlendState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BLEND_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBlendState, { \ + /*.color=*/WGPU_BLEND_COMPONENT_INIT _wgpu_COMMA \ + /*.alpha=*/WGPU_BLEND_COMPONENT_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUCompilationMessage { + WGPUChainedStruct * nextInChain; + WGPUStringView message; + WGPUCompilationMessageType type; + uint64_t lineNum; + uint64_t linePos; + uint64_t offset; + uint64_t length; +} WGPUCompilationMessage WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPILATION_MESSAGE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCompilationMessage, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.message=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.type=*/_wgpu_ENUM_ZERO_INIT(WGPUCompilationMessageType) _wgpu_COMMA \ + /*.lineNum=*/0 _wgpu_COMMA \ + /*.linePos=*/0 _wgpu_COMMA \ + /*.offset=*/0 _wgpu_COMMA \ + /*.length=*/0 _wgpu_COMMA \ +}) + +typedef struct WGPUComputePassDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPU_NULLABLE WGPUPassTimestampWrites const * timestampWrites; +} WGPUComputePassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPUTE_PASS_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUComputePassDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.timestampWrites=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUComputeState { + WGPUChainedStruct * nextInChain; + WGPUShaderModule module; + WGPUStringView entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; +} WGPUComputeState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPUTE_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUComputeState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.module=*/NULL _wgpu_COMMA \ + /*.entryPoint=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.constantCount=*/0 _wgpu_COMMA \ + /*.constants=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUDepthStencilState { + WGPUChainedStruct * nextInChain; + WGPUTextureFormat format; + WGPUOptionalBool depthWriteEnabled; + WGPUCompareFunction depthCompare; + WGPUStencilFaceState stencilFront; + WGPUStencilFaceState stencilBack; + uint32_t stencilReadMask; + uint32_t stencilWriteMask; + int32_t depthBias; + float depthBiasSlopeScale; + float depthBiasClamp; +} WGPUDepthStencilState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_DEPTH_STENCIL_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUDepthStencilState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.format=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.depthWriteEnabled=*/WGPUOptionalBool_Undefined _wgpu_COMMA \ + /*.depthCompare=*/WGPUCompareFunction_Undefined _wgpu_COMMA \ + /*.stencilFront=*/WGPU_STENCIL_FACE_STATE_INIT _wgpu_COMMA \ + /*.stencilBack=*/WGPU_STENCIL_FACE_STATE_INIT _wgpu_COMMA \ + /*.stencilReadMask=*/0xFFFFFFFF _wgpu_COMMA \ + /*.stencilWriteMask=*/0xFFFFFFFF _wgpu_COMMA \ + /*.depthBias=*/0 _wgpu_COMMA \ + /*.depthBiasSlopeScale=*/0.f _wgpu_COMMA \ + /*.depthBiasClamp=*/0.f _wgpu_COMMA \ +}) + +typedef struct WGPUFutureWaitInfo { + WGPUFuture future; + WGPUBool completed; +} WGPUFutureWaitInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_FUTURE_WAIT_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUFutureWaitInfo, { \ + /*.future=*/WGPU_FUTURE_INIT _wgpu_COMMA \ + /*.completed=*/WGPU_FALSE _wgpu_COMMA \ +}) + +typedef struct WGPUInstanceDescriptor { + WGPUChainedStruct * nextInChain; + size_t requiredFeatureCount; + WGPUInstanceFeatureName const * requiredFeatures; + WGPU_NULLABLE WGPUInstanceLimits const * requiredLimits; +} WGPUInstanceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_INSTANCE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUInstanceDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.requiredFeatureCount=*/0 _wgpu_COMMA \ + /*.requiredFeatures=*/NULL _wgpu_COMMA \ + /*.requiredLimits=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPULimits { + WGPUChainedStruct * nextInChain; + uint32_t maxTextureDimension1D; + uint32_t maxTextureDimension2D; + uint32_t maxTextureDimension3D; + uint32_t maxTextureArrayLayers; + uint32_t maxBindGroups; + uint32_t maxBindGroupsPlusVertexBuffers; + uint32_t maxBindingsPerBindGroup; + uint32_t maxDynamicUniformBuffersPerPipelineLayout; + uint32_t maxDynamicStorageBuffersPerPipelineLayout; + uint32_t maxSampledTexturesPerShaderStage; + uint32_t maxSamplersPerShaderStage; + uint32_t maxStorageBuffersPerShaderStage; + uint32_t maxStorageTexturesPerShaderStage; + uint32_t maxUniformBuffersPerShaderStage; + uint64_t maxUniformBufferBindingSize; + uint64_t maxStorageBufferBindingSize; + uint32_t minUniformBufferOffsetAlignment; + uint32_t minStorageBufferOffsetAlignment; + uint32_t maxVertexBuffers; + uint64_t maxBufferSize; + uint32_t maxVertexAttributes; + uint32_t maxVertexBufferArrayStride; + uint32_t maxInterStageShaderVariables; + uint32_t maxColorAttachments; + uint32_t maxColorAttachmentBytesPerSample; + uint32_t maxComputeWorkgroupStorageSize; + uint32_t maxComputeInvocationsPerWorkgroup; + uint32_t maxComputeWorkgroupSizeX; + uint32_t maxComputeWorkgroupSizeY; + uint32_t maxComputeWorkgroupSizeZ; + uint32_t maxComputeWorkgroupsPerDimension; + uint32_t maxImmediateSize; +} WGPULimits WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_LIMITS_INIT _wgpu_MAKE_INIT_STRUCT(WGPULimits, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.maxTextureDimension1D=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxTextureDimension2D=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxTextureDimension3D=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxTextureArrayLayers=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxBindGroups=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxBindGroupsPlusVertexBuffers=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxBindingsPerBindGroup=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxDynamicUniformBuffersPerPipelineLayout=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxDynamicStorageBuffersPerPipelineLayout=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxSampledTexturesPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxSamplersPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxStorageBuffersPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxStorageTexturesPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxUniformBuffersPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxUniformBufferBindingSize=*/WGPU_LIMIT_U64_UNDEFINED _wgpu_COMMA \ + /*.maxStorageBufferBindingSize=*/WGPU_LIMIT_U64_UNDEFINED _wgpu_COMMA \ + /*.minUniformBufferOffsetAlignment=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.minStorageBufferOffsetAlignment=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxVertexBuffers=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxBufferSize=*/WGPU_LIMIT_U64_UNDEFINED _wgpu_COMMA \ + /*.maxVertexAttributes=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxVertexBufferArrayStride=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxInterStageShaderVariables=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxColorAttachments=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxColorAttachmentBytesPerSample=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxComputeWorkgroupStorageSize=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxComputeInvocationsPerWorkgroup=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxComputeWorkgroupSizeX=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxComputeWorkgroupSizeY=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxComputeWorkgroupSizeZ=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxComputeWorkgroupsPerDimension=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ + /*.maxImmediateSize=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA \ +}) + +typedef struct WGPURenderPassColorAttachment { + WGPUChainedStruct * nextInChain; + WGPU_NULLABLE WGPUTextureView view; + uint32_t depthSlice; + WGPU_NULLABLE WGPUTextureView resolveTarget; + WGPULoadOp loadOp; + WGPUStoreOp storeOp; + WGPUColor clearValue; +} WGPURenderPassColorAttachment WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_PASS_COLOR_ATTACHMENT_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderPassColorAttachment, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.view=*/NULL _wgpu_COMMA \ + /*.depthSlice=*/WGPU_DEPTH_SLICE_UNDEFINED _wgpu_COMMA \ + /*.resolveTarget=*/NULL _wgpu_COMMA \ + /*.loadOp=*/WGPULoadOp_Undefined _wgpu_COMMA \ + /*.storeOp=*/WGPUStoreOp_Undefined _wgpu_COMMA \ + /*.clearValue=*/WGPU_COLOR_INIT _wgpu_COMMA \ +}) + +typedef struct WGPURequestAdapterOptions { + WGPUChainedStruct * nextInChain; + WGPUFeatureLevel featureLevel; + WGPUPowerPreference powerPreference; + WGPUBool forceFallbackAdapter; + WGPUBackendType backendType; + WGPU_NULLABLE WGPUSurface compatibleSurface; +} WGPURequestAdapterOptions WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_REQUEST_ADAPTER_OPTIONS_INIT _wgpu_MAKE_INIT_STRUCT(WGPURequestAdapterOptions, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.featureLevel=*/WGPUFeatureLevel_Undefined _wgpu_COMMA \ + /*.powerPreference=*/WGPUPowerPreference_Undefined _wgpu_COMMA \ + /*.forceFallbackAdapter=*/WGPU_FALSE _wgpu_COMMA \ + /*.backendType=*/WGPUBackendType_Undefined _wgpu_COMMA \ + /*.compatibleSurface=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUShaderModuleDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; +} WGPUShaderModuleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SHADER_MODULE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUShaderModuleDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUSurfaceDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; +} WGPUSurfaceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_SURFACE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUSurfaceDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUTexelCopyBufferInfo { + WGPUTexelCopyBufferLayout layout; + WGPUBuffer buffer; +} WGPUTexelCopyBufferInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXEL_COPY_BUFFER_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTexelCopyBufferInfo, { \ + /*.layout=*/WGPU_TEXEL_COPY_BUFFER_LAYOUT_INIT _wgpu_COMMA \ + /*.buffer=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUTexelCopyTextureInfo { + WGPUTexture texture; + uint32_t mipLevel; + WGPUOrigin3D origin; + WGPUTextureAspect aspect; +} WGPUTexelCopyTextureInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXEL_COPY_TEXTURE_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTexelCopyTextureInfo, { \ + /*.texture=*/NULL _wgpu_COMMA \ + /*.mipLevel=*/0 _wgpu_COMMA \ + /*.origin=*/WGPU_ORIGIN_3D_INIT _wgpu_COMMA \ + /*.aspect=*/WGPUTextureAspect_Undefined _wgpu_COMMA \ +}) + +// Can be chained in WGPUTextureViewDescriptor +typedef struct WGPUTextureComponentSwizzleDescriptor { + WGPUChainedStruct chain; + WGPUTextureComponentSwizzle swizzle; +} WGPUTextureComponentSwizzleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXTURE_COMPONENT_SWIZZLE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTextureComponentSwizzleDescriptor, { \ + /*.chain=*/_wgpu_MAKE_INIT_STRUCT(WGPUChainedStruct, { \ + /*.next=*/NULL _wgpu_COMMA \ + /*.sType=*/WGPUSType_TextureComponentSwizzleDescriptor _wgpu_COMMA \ + }) _wgpu_COMMA \ + /*.swizzle=*/WGPU_TEXTURE_COMPONENT_SWIZZLE_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUTextureDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPUTextureUsage usage; + WGPUTextureDimension dimension; + WGPUExtent3D size; + WGPUTextureFormat format; + uint32_t mipLevelCount; + uint32_t sampleCount; + size_t viewFormatCount; + WGPUTextureFormat const * viewFormats; +} WGPUTextureDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXTURE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTextureDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.usage=*/WGPUTextureUsage_None _wgpu_COMMA \ + /*.dimension=*/WGPUTextureDimension_Undefined _wgpu_COMMA \ + /*.size=*/WGPU_EXTENT_3D_INIT _wgpu_COMMA \ + /*.format=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.mipLevelCount=*/1 _wgpu_COMMA \ + /*.sampleCount=*/1 _wgpu_COMMA \ + /*.viewFormatCount=*/0 _wgpu_COMMA \ + /*.viewFormats=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUVertexBufferLayout { + WGPUChainedStruct * nextInChain; + WGPUVertexStepMode stepMode; + uint64_t arrayStride; + size_t attributeCount; + WGPUVertexAttribute const * attributes; +} WGPUVertexBufferLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_VERTEX_BUFFER_LAYOUT_INIT _wgpu_MAKE_INIT_STRUCT(WGPUVertexBufferLayout, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.stepMode=*/WGPUVertexStepMode_Undefined _wgpu_COMMA \ + /*.arrayStride=*/0 _wgpu_COMMA \ + /*.attributeCount=*/0 _wgpu_COMMA \ + /*.attributes=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUBindGroupLayoutDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + size_t entryCount; + WGPUBindGroupLayoutEntry const * entries; +} WGPUBindGroupLayoutDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_BIND_GROUP_LAYOUT_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUBindGroupLayoutDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.entryCount=*/0 _wgpu_COMMA \ + /*.entries=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUColorTargetState { + WGPUChainedStruct * nextInChain; + WGPUTextureFormat format; + WGPU_NULLABLE WGPUBlendState const * blend; + WGPUColorWriteMask writeMask; +} WGPUColorTargetState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COLOR_TARGET_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUColorTargetState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.format=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.blend=*/NULL _wgpu_COMMA \ + /*.writeMask=*/WGPUColorWriteMask_All _wgpu_COMMA \ +}) + +typedef struct WGPUCompilationInfo { + WGPUChainedStruct * nextInChain; + size_t messageCount; + WGPUCompilationMessage const * messages; +} WGPUCompilationInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPILATION_INFO_INIT _wgpu_MAKE_INIT_STRUCT(WGPUCompilationInfo, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.messageCount=*/0 _wgpu_COMMA \ + /*.messages=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUComputePipelineDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPU_NULLABLE WGPUPipelineLayout layout; + WGPUComputeState compute; +} WGPUComputePipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COMPUTE_PIPELINE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUComputePipelineDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.layout=*/NULL _wgpu_COMMA \ + /*.compute=*/WGPU_COMPUTE_STATE_INIT _wgpu_COMMA \ +}) + +typedef struct WGPUDeviceDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + size_t requiredFeatureCount; + WGPUFeatureName const * requiredFeatures; + WGPU_NULLABLE WGPULimits const * requiredLimits; + WGPUQueueDescriptor defaultQueue; + WGPUDeviceLostCallbackInfo deviceLostCallbackInfo; + WGPUUncapturedErrorCallbackInfo uncapturedErrorCallbackInfo; +} WGPUDeviceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_DEVICE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUDeviceDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.requiredFeatureCount=*/0 _wgpu_COMMA \ + /*.requiredFeatures=*/NULL _wgpu_COMMA \ + /*.requiredLimits=*/NULL _wgpu_COMMA \ + /*.defaultQueue=*/WGPU_QUEUE_DESCRIPTOR_INIT _wgpu_COMMA \ + /*.deviceLostCallbackInfo=*/WGPU_DEVICE_LOST_CALLBACK_INFO_INIT _wgpu_COMMA \ + /*.uncapturedErrorCallbackInfo=*/WGPU_UNCAPTURED_ERROR_CALLBACK_INFO_INIT _wgpu_COMMA \ +}) + +typedef struct WGPURenderPassDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + size_t colorAttachmentCount; + WGPURenderPassColorAttachment const * colorAttachments; + WGPU_NULLABLE WGPURenderPassDepthStencilAttachment const * depthStencilAttachment; + WGPU_NULLABLE WGPUQuerySet occlusionQuerySet; + WGPU_NULLABLE WGPUPassTimestampWrites const * timestampWrites; +} WGPURenderPassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_PASS_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderPassDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.colorAttachmentCount=*/0 _wgpu_COMMA \ + /*.colorAttachments=*/NULL _wgpu_COMMA \ + /*.depthStencilAttachment=*/NULL _wgpu_COMMA \ + /*.occlusionQuerySet=*/NULL _wgpu_COMMA \ + /*.timestampWrites=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUTextureViewDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPUTextureFormat format; + WGPUTextureViewDimension dimension; + uint32_t baseMipLevel; + uint32_t mipLevelCount; + uint32_t baseArrayLayer; + uint32_t arrayLayerCount; + WGPUTextureAspect aspect; + WGPUTextureUsage usage; +} WGPUTextureViewDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_TEXTURE_VIEW_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPUTextureViewDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.format=*/WGPUTextureFormat_Undefined _wgpu_COMMA \ + /*.dimension=*/WGPUTextureViewDimension_Undefined _wgpu_COMMA \ + /*.baseMipLevel=*/0 _wgpu_COMMA \ + /*.mipLevelCount=*/WGPU_MIP_LEVEL_COUNT_UNDEFINED _wgpu_COMMA \ + /*.baseArrayLayer=*/0 _wgpu_COMMA \ + /*.arrayLayerCount=*/WGPU_ARRAY_LAYER_COUNT_UNDEFINED _wgpu_COMMA \ + /*.aspect=*/WGPUTextureAspect_Undefined _wgpu_COMMA \ + /*.usage=*/WGPUTextureUsage_None _wgpu_COMMA \ +}) + +typedef struct WGPUVertexState { + WGPUChainedStruct * nextInChain; + WGPUShaderModule module; + WGPUStringView entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; + size_t bufferCount; + WGPUVertexBufferLayout const * buffers; +} WGPUVertexState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_VERTEX_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUVertexState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.module=*/NULL _wgpu_COMMA \ + /*.entryPoint=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.constantCount=*/0 _wgpu_COMMA \ + /*.constants=*/NULL _wgpu_COMMA \ + /*.bufferCount=*/0 _wgpu_COMMA \ + /*.buffers=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPUFragmentState { + WGPUChainedStruct * nextInChain; + WGPUShaderModule module; + WGPUStringView entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; + size_t targetCount; + WGPUColorTargetState const * targets; +} WGPUFragmentState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_FRAGMENT_STATE_INIT _wgpu_MAKE_INIT_STRUCT(WGPUFragmentState, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.module=*/NULL _wgpu_COMMA \ + /*.entryPoint=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.constantCount=*/0 _wgpu_COMMA \ + /*.constants=*/NULL _wgpu_COMMA \ + /*.targetCount=*/0 _wgpu_COMMA \ + /*.targets=*/NULL _wgpu_COMMA \ +}) + +typedef struct WGPURenderPipelineDescriptor { + WGPUChainedStruct * nextInChain; + WGPUStringView label; + WGPU_NULLABLE WGPUPipelineLayout layout; + WGPUVertexState vertex; + WGPUPrimitiveState primitive; + WGPU_NULLABLE WGPUDepthStencilState const * depthStencil; + WGPUMultisampleState multisample; + WGPU_NULLABLE WGPUFragmentState const * fragment; +} WGPURenderPipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_RENDER_PIPELINE_DESCRIPTOR_INIT _wgpu_MAKE_INIT_STRUCT(WGPURenderPipelineDescriptor, { \ + /*.nextInChain=*/NULL _wgpu_COMMA \ + /*.label=*/WGPU_STRING_VIEW_INIT _wgpu_COMMA \ + /*.layout=*/NULL _wgpu_COMMA \ + /*.vertex=*/WGPU_VERTEX_STATE_INIT _wgpu_COMMA \ + /*.primitive=*/WGPU_PRIMITIVE_STATE_INIT _wgpu_COMMA \ + /*.depthStencil=*/NULL _wgpu_COMMA \ + /*.multisample=*/WGPU_MULTISAMPLE_STATE_INIT _wgpu_COMMA \ + /*.fragment=*/NULL _wgpu_COMMA \ +}) + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(WGPU_SKIP_PROCS) +// TODO(374150686): Remove these Emscripten specific declarations from the +// header once they are fully deprecated. +WGPU_EXPORT WGPUDevice emscripten_webgpu_get_device(void); +// Global procs +typedef WGPUInstance (*WGPUProcCreateInstance)(WGPU_NULLABLE WGPUInstanceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcGetInstanceFeatures)(WGPUSupportedInstanceFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcGetInstanceLimits)(WGPUInstanceLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcHasInstanceFeature)(WGPUInstanceFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUStringView procName) WGPU_FUNCTION_ATTRIBUTE; + + +// Procs of Adapter +typedef void (*WGPUProcAdapterGetFeatures)(WGPUAdapter adapter, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcAdapterGetInfo)(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcAdapterGetLimits)(WGPUAdapter adapter, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcAdapterHasFeature)(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcAdapterRequestDevice)(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterAddRef)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterRelease)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of AdapterInfo +typedef void (*WGPUProcAdapterInfoFreeMembers)(WGPUAdapterInfo adapterInfo) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of BindGroup +typedef void (*WGPUProcBindGroupSetLabel)(WGPUBindGroup bindGroup, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupAddRef)(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupRelease)(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of BindGroupLayout +typedef void (*WGPUProcBindGroupLayoutSetLabel)(WGPUBindGroupLayout bindGroupLayout, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupLayoutAddRef)(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupLayoutRelease)(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Buffer +typedef void (*WGPUProcBufferDestroy)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void const * (*WGPUProcBufferGetConstMappedRange)(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void * (*WGPUProcBufferGetMappedRange)(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBufferMapState (*WGPUProcBufferGetMapState)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef uint64_t (*WGPUProcBufferGetSize)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBufferUsage (*WGPUProcBufferGetUsage)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcBufferMapAsync)(WGPUBuffer buffer, WGPUMapMode mode, size_t offset, size_t size, WGPUBufferMapCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcBufferReadMappedRange)(WGPUBuffer buffer, size_t offset, void * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferSetLabel)(WGPUBuffer buffer, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferUnmap)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcBufferWriteMappedRange)(WGPUBuffer buffer, size_t offset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferAddRef)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferRelease)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of CommandBuffer +typedef void (*WGPUProcCommandBufferSetLabel)(WGPUCommandBuffer commandBuffer, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandBufferAddRef)(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandBufferRelease)(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of CommandEncoder +typedef WGPUComputePassEncoder (*WGPUProcCommandEncoderBeginComputePass)(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUComputePassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderPassEncoder (*WGPUProcCommandEncoderBeginRenderPass)(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderClearBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyBufferToBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyBufferToTexture)(WGPUCommandEncoder commandEncoder, WGPUTexelCopyBufferInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToBuffer)(WGPUCommandEncoder commandEncoder, WGPUTexelCopyTextureInfo const * source, WGPUTexelCopyBufferInfo const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToTexture)(WGPUCommandEncoder commandEncoder, WGPUTexelCopyTextureInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUCommandBuffer (*WGPUProcCommandEncoderFinish)(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderInsertDebugMarker)(WGPUCommandEncoder commandEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderPopDebugGroup)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderPushDebugGroup)(WGPUCommandEncoder commandEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderResolveQuerySet)(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderSetLabel)(WGPUCommandEncoder commandEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderWriteTimestamp)(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderAddRef)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderRelease)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ComputePassEncoder +typedef void (*WGPUProcComputePassEncoderDispatchWorkgroups)(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderDispatchWorkgroupsIndirect)(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderEnd)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderInsertDebugMarker)(WGPUComputePassEncoder computePassEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderPopDebugGroup)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderPushDebugGroup)(WGPUComputePassEncoder computePassEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetBindGroup)(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetLabel)(WGPUComputePassEncoder computePassEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetPipeline)(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderWriteTimestamp)(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderAddRef)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderRelease)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ComputePipeline +typedef WGPUBindGroupLayout (*WGPUProcComputePipelineGetBindGroupLayout)(WGPUComputePipeline computePipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineSetLabel)(WGPUComputePipeline computePipeline, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineAddRef)(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineRelease)(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Device +typedef WGPUBindGroup (*WGPUProcDeviceCreateBindGroup)(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBindGroupLayout (*WGPUProcDeviceCreateBindGroupLayout)(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPU_NULLABLE WGPUBuffer (*WGPUProcDeviceCreateBuffer)(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUCommandEncoder (*WGPUProcDeviceCreateCommandEncoder)(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUComputePipeline (*WGPUProcDeviceCreateComputePipeline)(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcDeviceCreateComputePipelineAsync)(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUPipelineLayout (*WGPUProcDeviceCreatePipelineLayout)(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQuerySet (*WGPUProcDeviceCreateQuerySet)(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderBundleEncoder (*WGPUProcDeviceCreateRenderBundleEncoder)(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderPipeline (*WGPUProcDeviceCreateRenderPipeline)(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcDeviceCreateRenderPipelineAsync)(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUSampler (*WGPUProcDeviceCreateSampler)(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUShaderModule (*WGPUProcDeviceCreateShaderModule)(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTexture (*WGPUProcDeviceCreateTexture)(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceDestroy)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcDeviceGetAdapterInfo)(WGPUDevice device, WGPUAdapterInfo * adapterInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceGetFeatures)(WGPUDevice device, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcDeviceGetLimits)(WGPUDevice device, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcDeviceGetLostFuture)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQueue (*WGPUProcDeviceGetQueue)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcDeviceHasFeature)(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcDevicePopErrorScope)(WGPUDevice device, WGPUPopErrorScopeCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDevicePushErrorScope)(WGPUDevice device, WGPUErrorFilter filter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetLabel)(WGPUDevice device, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceAddRef)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceRelease)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Instance +typedef WGPUSurface (*WGPUProcInstanceCreateSurface)(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceGetWGSLLanguageFeatures)(WGPUInstance instance, WGPUSupportedWGSLLanguageFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcInstanceHasWGSLLanguageFeature)(WGPUInstance instance, WGPUWGSLLanguageFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceProcessEvents)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUFuture (*WGPUProcInstanceRequestAdapter)(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUWaitStatus (*WGPUProcInstanceWaitAny)(WGPUInstance instance, size_t futureCount, WGPU_NULLABLE WGPUFutureWaitInfo * futures, uint64_t timeoutNS) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceAddRef)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceRelease)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of PipelineLayout +typedef void (*WGPUProcPipelineLayoutSetLabel)(WGPUPipelineLayout pipelineLayout, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcPipelineLayoutAddRef)(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcPipelineLayoutRelease)(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of QuerySet +typedef void (*WGPUProcQuerySetDestroy)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcQuerySetGetCount)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQueryType (*WGPUProcQuerySetGetType)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetSetLabel)(WGPUQuerySet querySet, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetAddRef)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetRelease)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Queue +typedef WGPUFuture (*WGPUProcQueueOnSubmittedWorkDone)(WGPUQueue queue, WGPUQueueWorkDoneCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueSetLabel)(WGPUQueue queue, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueSubmit)(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueWriteBuffer)(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueWriteTexture)(WGPUQueue queue, WGPUTexelCopyTextureInfo const * destination, void const * data, size_t dataSize, WGPUTexelCopyBufferLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueAddRef)(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueRelease)(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderBundle +typedef void (*WGPUProcRenderBundleSetLabel)(WGPURenderBundle renderBundle, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleAddRef)(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleRelease)(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderBundleEncoder +typedef void (*WGPUProcRenderBundleEncoderDraw)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndexed)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndexedIndirect)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndirect)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderBundle (*WGPUProcRenderBundleEncoderFinish)(WGPURenderBundleEncoder renderBundleEncoder, WGPU_NULLABLE WGPURenderBundleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderInsertDebugMarker)(WGPURenderBundleEncoder renderBundleEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderPopDebugGroup)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderPushDebugGroup)(WGPURenderBundleEncoder renderBundleEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetBindGroup)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetIndexBuffer)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetLabel)(WGPURenderBundleEncoder renderBundleEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetPipeline)(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetVertexBuffer)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderAddRef)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderRelease)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderPassEncoder +typedef void (*WGPUProcRenderPassEncoderBeginOcclusionQuery)(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDraw)(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndexed)(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndexedIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderEnd)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderEndOcclusionQuery)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderExecuteBundles)(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderInsertDebugMarker)(WGPURenderPassEncoder renderPassEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderMultiDrawIndexedIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, WGPU_NULLABLE WGPUBuffer drawCountBuffer, uint64_t drawCountBufferOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderMultiDrawIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, WGPU_NULLABLE WGPUBuffer drawCountBuffer, uint64_t drawCountBufferOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderPopDebugGroup)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderPushDebugGroup)(WGPURenderPassEncoder renderPassEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetBindGroup)(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetBlendConstant)(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetIndexBuffer)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetLabel)(WGPURenderPassEncoder renderPassEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetPipeline)(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetScissorRect)(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetStencilReference)(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetVertexBuffer)(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetViewport)(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderWriteTimestamp)(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderAddRef)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderRelease)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderPipeline +typedef WGPUBindGroupLayout (*WGPUProcRenderPipelineGetBindGroupLayout)(WGPURenderPipeline renderPipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineSetLabel)(WGPURenderPipeline renderPipeline, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineAddRef)(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineRelease)(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Sampler +typedef void (*WGPUProcSamplerSetLabel)(WGPUSampler sampler, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSamplerAddRef)(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSamplerRelease)(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ShaderModule +typedef WGPUFuture (*WGPUProcShaderModuleGetCompilationInfo)(WGPUShaderModule shaderModule, WGPUCompilationInfoCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleSetLabel)(WGPUShaderModule shaderModule, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleAddRef)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleRelease)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of SupportedFeatures +typedef void (*WGPUProcSupportedFeaturesFreeMembers)(WGPUSupportedFeatures supportedFeatures) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of SupportedInstanceFeatures +typedef void (*WGPUProcSupportedInstanceFeaturesFreeMembers)(WGPUSupportedInstanceFeatures supportedInstanceFeatures) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of SupportedWGSLLanguageFeatures +typedef void (*WGPUProcSupportedWGSLLanguageFeaturesFreeMembers)(WGPUSupportedWGSLLanguageFeatures supportedWGSLLanguageFeatures) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Surface +typedef void (*WGPUProcSurfaceConfigure)(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcSurfaceGetCapabilities)(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceGetCurrentTexture)(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUStatus (*WGPUProcSurfacePresent)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceSetLabel)(WGPUSurface surface, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceUnconfigure)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceAddRef)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceRelease)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of SurfaceCapabilities +typedef void (*WGPUProcSurfaceCapabilitiesFreeMembers)(WGPUSurfaceCapabilities surfaceCapabilities) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Texture +typedef WGPUTextureView (*WGPUProcTextureCreateView)(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureDestroy)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetDepthOrArrayLayers)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureDimension (*WGPUProcTextureGetDimension)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureFormat (*WGPUProcTextureGetFormat)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetHeight)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetMipLevelCount)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetSampleCount)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureUsage (*WGPUProcTextureGetUsage)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetWidth)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureSetLabel)(WGPUTexture texture, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureAddRef)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureRelease)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of TextureView +typedef void (*WGPUProcTextureViewSetLabel)(WGPUTextureView textureView, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureViewAddRef)(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureViewRelease)(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; + +#endif // !defined(WGPU_SKIP_PROCS) + +#if !defined(WGPU_SKIP_DECLARATIONS) +WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPU_NULLABLE WGPUInstanceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuGetInstanceFeatures(WGPUSupportedInstanceFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuGetInstanceLimits(WGPUInstanceLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuHasInstanceFeature(WGPUInstanceFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUStringView procName) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Adapter +WGPU_EXPORT void wgpuAdapterGetFeatures(WGPUAdapter adapter, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuAdapterGetInfo(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuAdapterGetLimits(WGPUAdapter adapter, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterAddRef(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterRelease(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of AdapterInfo +WGPU_EXPORT void wgpuAdapterInfoFreeMembers(WGPUAdapterInfo adapterInfo) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of BindGroup +WGPU_EXPORT void wgpuBindGroupSetLabel(WGPUBindGroup bindGroup, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupAddRef(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupRelease(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of BindGroupLayout +WGPU_EXPORT void wgpuBindGroupLayoutSetLabel(WGPUBindGroupLayout bindGroupLayout, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupLayoutAddRef(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupLayoutRelease(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Buffer +WGPU_EXPORT void wgpuBufferDestroy(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void const * wgpuBufferGetConstMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void * wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBufferMapState wgpuBufferGetMapState(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint64_t wgpuBufferGetSize(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBufferUsage wgpuBufferGetUsage(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuBufferMapAsync(WGPUBuffer buffer, WGPUMapMode mode, size_t offset, size_t size, WGPUBufferMapCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuBufferReadMappedRange(WGPUBuffer buffer, size_t offset, void * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferSetLabel(WGPUBuffer buffer, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferUnmap(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuBufferWriteMappedRange(WGPUBuffer buffer, size_t offset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferAddRef(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferRelease(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of CommandBuffer +WGPU_EXPORT void wgpuCommandBufferSetLabel(WGPUCommandBuffer commandBuffer, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandBufferAddRef(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandBufferRelease(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of CommandEncoder +WGPU_EXPORT WGPUComputePassEncoder wgpuCommandEncoderBeginComputePass(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUComputePassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderPassEncoder wgpuCommandEncoderBeginRenderPass(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderClearBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyBufferToBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyBufferToTexture(WGPUCommandEncoder commandEncoder, WGPUTexelCopyBufferInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToBuffer(WGPUCommandEncoder commandEncoder, WGPUTexelCopyTextureInfo const * source, WGPUTexelCopyBufferInfo const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToTexture(WGPUCommandEncoder commandEncoder, WGPUTexelCopyTextureInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUCommandBuffer wgpuCommandEncoderFinish(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderInsertDebugMarker(WGPUCommandEncoder commandEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderPopDebugGroup(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderPushDebugGroup(WGPUCommandEncoder commandEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderResolveQuerySet(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderSetLabel(WGPUCommandEncoder commandEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderWriteTimestamp(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderAddRef(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderRelease(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ComputePassEncoder +WGPU_EXPORT void wgpuComputePassEncoderDispatchWorkgroups(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderDispatchWorkgroupsIndirect(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderEnd(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderInsertDebugMarker(WGPUComputePassEncoder computePassEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderPopDebugGroup(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderPushDebugGroup(WGPUComputePassEncoder computePassEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetBindGroup(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetLabel(WGPUComputePassEncoder computePassEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetPipeline(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderWriteTimestamp(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderAddRef(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderRelease(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ComputePipeline +WGPU_EXPORT WGPUBindGroupLayout wgpuComputePipelineGetBindGroupLayout(WGPUComputePipeline computePipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineSetLabel(WGPUComputePipeline computePipeline, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineAddRef(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineRelease(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Device +WGPU_EXPORT WGPUBindGroup wgpuDeviceCreateBindGroup(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBindGroupLayout wgpuDeviceCreateBindGroupLayout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPU_NULLABLE WGPUBuffer wgpuDeviceCreateBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUCommandEncoder wgpuDeviceCreateCommandEncoder(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUComputePipeline wgpuDeviceCreateComputePipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuDeviceCreateComputePipelineAsync(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUPipelineLayout wgpuDeviceCreatePipelineLayout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQuerySet wgpuDeviceCreateQuerySet(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderBundleEncoder wgpuDeviceCreateRenderBundleEncoder(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderPipeline wgpuDeviceCreateRenderPipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuDeviceCreateRenderPipelineAsync(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUSampler wgpuDeviceCreateSampler(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUShaderModule wgpuDeviceCreateShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTexture wgpuDeviceCreateTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceDestroy(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuDeviceGetAdapterInfo(WGPUDevice device, WGPUAdapterInfo * adapterInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceGetFeatures(WGPUDevice device, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuDeviceGetLimits(WGPUDevice device, WGPULimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuDeviceGetLostFuture(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQueue wgpuDeviceGetQueue(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuDeviceHasFeature(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuDevicePopErrorScope(WGPUDevice device, WGPUPopErrorScopeCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDevicePushErrorScope(WGPUDevice device, WGPUErrorFilter filter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetLabel(WGPUDevice device, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceAddRef(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceRelease(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Instance +WGPU_EXPORT WGPUSurface wgpuInstanceCreateSurface(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceGetWGSLLanguageFeatures(WGPUInstance instance, WGPUSupportedWGSLLanguageFeatures * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuInstanceHasWGSLLanguageFeature(WGPUInstance instance, WGPUWGSLLanguageFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceProcessEvents(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuInstanceRequestAdapter(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUWaitStatus wgpuInstanceWaitAny(WGPUInstance instance, size_t futureCount, WGPU_NULLABLE WGPUFutureWaitInfo * futures, uint64_t timeoutNS) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceAddRef(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceRelease(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of PipelineLayout +WGPU_EXPORT void wgpuPipelineLayoutSetLabel(WGPUPipelineLayout pipelineLayout, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuPipelineLayoutAddRef(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuPipelineLayoutRelease(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of QuerySet +WGPU_EXPORT void wgpuQuerySetDestroy(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuQuerySetGetCount(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQueryType wgpuQuerySetGetType(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetSetLabel(WGPUQuerySet querySet, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetAddRef(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetRelease(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Queue +WGPU_EXPORT WGPUFuture wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, WGPUQueueWorkDoneCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueSetLabel(WGPUQueue queue, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueSubmit(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueWriteTexture(WGPUQueue queue, WGPUTexelCopyTextureInfo const * destination, void const * data, size_t dataSize, WGPUTexelCopyBufferLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueAddRef(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueRelease(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderBundle +WGPU_EXPORT void wgpuRenderBundleSetLabel(WGPURenderBundle renderBundle, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleAddRef(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleRelease(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderBundleEncoder +WGPU_EXPORT void wgpuRenderBundleEncoderDraw(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndexed(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndexedIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderBundle wgpuRenderBundleEncoderFinish(WGPURenderBundleEncoder renderBundleEncoder, WGPU_NULLABLE WGPURenderBundleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderInsertDebugMarker(WGPURenderBundleEncoder renderBundleEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderPopDebugGroup(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderPushDebugGroup(WGPURenderBundleEncoder renderBundleEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetBindGroup(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetIndexBuffer(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetLabel(WGPURenderBundleEncoder renderBundleEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetPipeline(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetVertexBuffer(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderAddRef(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderRelease(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderPassEncoder +WGPU_EXPORT void wgpuRenderPassEncoderBeginOcclusionQuery(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDraw(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndexed(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndexedIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderEnd(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderEndOcclusionQuery(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderExecuteBundles(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderInsertDebugMarker(WGPURenderPassEncoder renderPassEncoder, WGPUStringView markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderMultiDrawIndexedIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, WGPU_NULLABLE WGPUBuffer drawCountBuffer, uint64_t drawCountBufferOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderMultiDrawIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, WGPU_NULLABLE WGPUBuffer drawCountBuffer, uint64_t drawCountBufferOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderPopDebugGroup(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderPushDebugGroup(WGPURenderPassEncoder renderPassEncoder, WGPUStringView groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetBindGroup(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetBlendConstant(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetIndexBuffer(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetLabel(WGPURenderPassEncoder renderPassEncoder, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetPipeline(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetScissorRect(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetStencilReference(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetVertexBuffer(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetViewport(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderWriteTimestamp(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderAddRef(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderRelease(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderPipeline +WGPU_EXPORT WGPUBindGroupLayout wgpuRenderPipelineGetBindGroupLayout(WGPURenderPipeline renderPipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineSetLabel(WGPURenderPipeline renderPipeline, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineAddRef(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineRelease(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Sampler +WGPU_EXPORT void wgpuSamplerSetLabel(WGPUSampler sampler, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSamplerAddRef(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSamplerRelease(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ShaderModule +WGPU_EXPORT WGPUFuture wgpuShaderModuleGetCompilationInfo(WGPUShaderModule shaderModule, WGPUCompilationInfoCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleAddRef(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleRelease(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of SupportedFeatures +WGPU_EXPORT void wgpuSupportedFeaturesFreeMembers(WGPUSupportedFeatures supportedFeatures) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of SupportedInstanceFeatures +WGPU_EXPORT void wgpuSupportedInstanceFeaturesFreeMembers(WGPUSupportedInstanceFeatures supportedInstanceFeatures) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of SupportedWGSLLanguageFeatures +WGPU_EXPORT void wgpuSupportedWGSLLanguageFeaturesFreeMembers(WGPUSupportedWGSLLanguageFeatures supportedWGSLLanguageFeatures) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Surface +WGPU_EXPORT void wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceGetCurrentTexture(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUStatus wgpuSurfacePresent(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceSetLabel(WGPUSurface surface, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceUnconfigure(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceAddRef(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceRelease(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of SurfaceCapabilities +WGPU_EXPORT void wgpuSurfaceCapabilitiesFreeMembers(WGPUSurfaceCapabilities surfaceCapabilities) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Texture +WGPU_EXPORT WGPUTextureView wgpuTextureCreateView(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureDestroy(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetDepthOrArrayLayers(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureDimension wgpuTextureGetDimension(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureFormat wgpuTextureGetFormat(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetHeight(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetMipLevelCount(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetSampleCount(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureUsage wgpuTextureGetUsage(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetWidth(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureSetLabel(WGPUTexture texture, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureAddRef(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureRelease(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of TextureView +WGPU_EXPORT void wgpuTextureViewSetLabel(WGPUTextureView textureView, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureViewAddRef(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureViewRelease(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; + +#endif // !defined(WGPU_SKIP_DECLARATIONS) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // WEBGPU_H_ diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp.h b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp.h new file mode 100644 index 000000000..cbd830a8b --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp.h @@ -0,0 +1,5833 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +#ifndef WEBGPU_CPP_H_ +#define WEBGPU_CPP_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "webgpu/webgpu.h" +#include "webgpu/webgpu_cpp_chained_struct.h" +#include "webgpu/webgpu_enum_class_bitmasks.h" // IWYU pragma: export + +namespace wgpu { + +static constexpr uint32_t kArrayLayerCountUndefined = WGPU_ARRAY_LAYER_COUNT_UNDEFINED; +static constexpr uint32_t kCopyStrideUndefined = WGPU_COPY_STRIDE_UNDEFINED; +static constexpr float kDepthClearValueUndefined = std::numeric_limits::quiet_NaN(); +static constexpr uint32_t kDepthSliceUndefined = WGPU_DEPTH_SLICE_UNDEFINED; +static constexpr uint32_t kLimitU32Undefined = WGPU_LIMIT_U32_UNDEFINED; +static constexpr uint64_t kLimitU64Undefined = WGPU_LIMIT_U64_UNDEFINED; +static constexpr uint32_t kMipLevelCountUndefined = WGPU_MIP_LEVEL_COUNT_UNDEFINED; +static constexpr uint32_t kQuerySetIndexUndefined = WGPU_QUERY_SET_INDEX_UNDEFINED; +static constexpr size_t kStrlen = WGPU_STRLEN; +static constexpr size_t kWholeMapSize = WGPU_WHOLE_MAP_SIZE; +static constexpr uint64_t kWholeSize = WGPU_WHOLE_SIZE; + +enum class AdapterType : uint32_t { + DiscreteGPU = WGPUAdapterType_DiscreteGPU, + IntegratedGPU = WGPUAdapterType_IntegratedGPU, + CPU = WGPUAdapterType_CPU, + Unknown = WGPUAdapterType_Unknown, +}; +static_assert(sizeof(AdapterType) == sizeof(WGPUAdapterType), "sizeof mismatch for AdapterType"); +static_assert(alignof(AdapterType) == alignof(WGPUAdapterType), "alignof mismatch for AdapterType"); + +enum class AddressMode : uint32_t { + Undefined = WGPUAddressMode_Undefined, + ClampToEdge = WGPUAddressMode_ClampToEdge, + Repeat = WGPUAddressMode_Repeat, + MirrorRepeat = WGPUAddressMode_MirrorRepeat, +}; +static_assert(sizeof(AddressMode) == sizeof(WGPUAddressMode), "sizeof mismatch for AddressMode"); +static_assert(alignof(AddressMode) == alignof(WGPUAddressMode), "alignof mismatch for AddressMode"); + +enum class BackendType : uint32_t { + Undefined = WGPUBackendType_Undefined, + Null = WGPUBackendType_Null, + WebGPU = WGPUBackendType_WebGPU, + D3D11 = WGPUBackendType_D3D11, + D3D12 = WGPUBackendType_D3D12, + Metal = WGPUBackendType_Metal, + Vulkan = WGPUBackendType_Vulkan, + OpenGL = WGPUBackendType_OpenGL, + OpenGLES = WGPUBackendType_OpenGLES, +}; +static_assert(sizeof(BackendType) == sizeof(WGPUBackendType), "sizeof mismatch for BackendType"); +static_assert(alignof(BackendType) == alignof(WGPUBackendType), "alignof mismatch for BackendType"); + +enum class BlendFactor : uint32_t { + Undefined = WGPUBlendFactor_Undefined, + Zero = WGPUBlendFactor_Zero, + One = WGPUBlendFactor_One, + Src = WGPUBlendFactor_Src, + OneMinusSrc = WGPUBlendFactor_OneMinusSrc, + SrcAlpha = WGPUBlendFactor_SrcAlpha, + OneMinusSrcAlpha = WGPUBlendFactor_OneMinusSrcAlpha, + Dst = WGPUBlendFactor_Dst, + OneMinusDst = WGPUBlendFactor_OneMinusDst, + DstAlpha = WGPUBlendFactor_DstAlpha, + OneMinusDstAlpha = WGPUBlendFactor_OneMinusDstAlpha, + SrcAlphaSaturated = WGPUBlendFactor_SrcAlphaSaturated, + Constant = WGPUBlendFactor_Constant, + OneMinusConstant = WGPUBlendFactor_OneMinusConstant, + Src1 = WGPUBlendFactor_Src1, + OneMinusSrc1 = WGPUBlendFactor_OneMinusSrc1, + Src1Alpha = WGPUBlendFactor_Src1Alpha, + OneMinusSrc1Alpha = WGPUBlendFactor_OneMinusSrc1Alpha, +}; +static_assert(sizeof(BlendFactor) == sizeof(WGPUBlendFactor), "sizeof mismatch for BlendFactor"); +static_assert(alignof(BlendFactor) == alignof(WGPUBlendFactor), "alignof mismatch for BlendFactor"); + +enum class BlendOperation : uint32_t { + Undefined = WGPUBlendOperation_Undefined, + Add = WGPUBlendOperation_Add, + Subtract = WGPUBlendOperation_Subtract, + ReverseSubtract = WGPUBlendOperation_ReverseSubtract, + Min = WGPUBlendOperation_Min, + Max = WGPUBlendOperation_Max, +}; +static_assert(sizeof(BlendOperation) == sizeof(WGPUBlendOperation), "sizeof mismatch for BlendOperation"); +static_assert(alignof(BlendOperation) == alignof(WGPUBlendOperation), "alignof mismatch for BlendOperation"); + +enum class BufferBindingType : uint32_t { + BindingNotUsed = WGPUBufferBindingType_BindingNotUsed, + Undefined = WGPUBufferBindingType_Undefined, + Uniform = WGPUBufferBindingType_Uniform, + Storage = WGPUBufferBindingType_Storage, + ReadOnlyStorage = WGPUBufferBindingType_ReadOnlyStorage, +}; +static_assert(sizeof(BufferBindingType) == sizeof(WGPUBufferBindingType), "sizeof mismatch for BufferBindingType"); +static_assert(alignof(BufferBindingType) == alignof(WGPUBufferBindingType), "alignof mismatch for BufferBindingType"); + +enum class BufferMapState : uint32_t { + Unmapped = WGPUBufferMapState_Unmapped, + Pending = WGPUBufferMapState_Pending, + Mapped = WGPUBufferMapState_Mapped, +}; +static_assert(sizeof(BufferMapState) == sizeof(WGPUBufferMapState), "sizeof mismatch for BufferMapState"); +static_assert(alignof(BufferMapState) == alignof(WGPUBufferMapState), "alignof mismatch for BufferMapState"); + +enum class CallbackMode : uint32_t { + WaitAnyOnly = WGPUCallbackMode_WaitAnyOnly, + AllowProcessEvents = WGPUCallbackMode_AllowProcessEvents, + AllowSpontaneous = WGPUCallbackMode_AllowSpontaneous, +}; +static_assert(sizeof(CallbackMode) == sizeof(WGPUCallbackMode), "sizeof mismatch for CallbackMode"); +static_assert(alignof(CallbackMode) == alignof(WGPUCallbackMode), "alignof mismatch for CallbackMode"); + +enum class CompareFunction : uint32_t { + Undefined = WGPUCompareFunction_Undefined, + Never = WGPUCompareFunction_Never, + Less = WGPUCompareFunction_Less, + Equal = WGPUCompareFunction_Equal, + LessEqual = WGPUCompareFunction_LessEqual, + Greater = WGPUCompareFunction_Greater, + NotEqual = WGPUCompareFunction_NotEqual, + GreaterEqual = WGPUCompareFunction_GreaterEqual, + Always = WGPUCompareFunction_Always, +}; +static_assert(sizeof(CompareFunction) == sizeof(WGPUCompareFunction), "sizeof mismatch for CompareFunction"); +static_assert(alignof(CompareFunction) == alignof(WGPUCompareFunction), "alignof mismatch for CompareFunction"); + +enum class CompilationInfoRequestStatus : uint32_t { + Success = WGPUCompilationInfoRequestStatus_Success, + CallbackCancelled = WGPUCompilationInfoRequestStatus_CallbackCancelled, +}; +static_assert(sizeof(CompilationInfoRequestStatus) == sizeof(WGPUCompilationInfoRequestStatus), "sizeof mismatch for CompilationInfoRequestStatus"); +static_assert(alignof(CompilationInfoRequestStatus) == alignof(WGPUCompilationInfoRequestStatus), "alignof mismatch for CompilationInfoRequestStatus"); + +enum class CompilationMessageType : uint32_t { + Error = WGPUCompilationMessageType_Error, + Warning = WGPUCompilationMessageType_Warning, + Info = WGPUCompilationMessageType_Info, +}; +static_assert(sizeof(CompilationMessageType) == sizeof(WGPUCompilationMessageType), "sizeof mismatch for CompilationMessageType"); +static_assert(alignof(CompilationMessageType) == alignof(WGPUCompilationMessageType), "alignof mismatch for CompilationMessageType"); + +enum class ComponentSwizzle : uint32_t { + Undefined = WGPUComponentSwizzle_Undefined, + Zero = WGPUComponentSwizzle_Zero, + One = WGPUComponentSwizzle_One, + R = WGPUComponentSwizzle_R, + G = WGPUComponentSwizzle_G, + B = WGPUComponentSwizzle_B, + A = WGPUComponentSwizzle_A, +}; +static_assert(sizeof(ComponentSwizzle) == sizeof(WGPUComponentSwizzle), "sizeof mismatch for ComponentSwizzle"); +static_assert(alignof(ComponentSwizzle) == alignof(WGPUComponentSwizzle), "alignof mismatch for ComponentSwizzle"); + +enum class CompositeAlphaMode : uint32_t { + Auto = WGPUCompositeAlphaMode_Auto, + Opaque = WGPUCompositeAlphaMode_Opaque, + Premultiplied = WGPUCompositeAlphaMode_Premultiplied, + Unpremultiplied = WGPUCompositeAlphaMode_Unpremultiplied, + Inherit = WGPUCompositeAlphaMode_Inherit, +}; +static_assert(sizeof(CompositeAlphaMode) == sizeof(WGPUCompositeAlphaMode), "sizeof mismatch for CompositeAlphaMode"); +static_assert(alignof(CompositeAlphaMode) == alignof(WGPUCompositeAlphaMode), "alignof mismatch for CompositeAlphaMode"); + +enum class CreatePipelineAsyncStatus : uint32_t { + Success = WGPUCreatePipelineAsyncStatus_Success, + CallbackCancelled = WGPUCreatePipelineAsyncStatus_CallbackCancelled, + ValidationError = WGPUCreatePipelineAsyncStatus_ValidationError, + InternalError = WGPUCreatePipelineAsyncStatus_InternalError, +}; +static_assert(sizeof(CreatePipelineAsyncStatus) == sizeof(WGPUCreatePipelineAsyncStatus), "sizeof mismatch for CreatePipelineAsyncStatus"); +static_assert(alignof(CreatePipelineAsyncStatus) == alignof(WGPUCreatePipelineAsyncStatus), "alignof mismatch for CreatePipelineAsyncStatus"); + +enum class CullMode : uint32_t { + Undefined = WGPUCullMode_Undefined, + None = WGPUCullMode_None, + Front = WGPUCullMode_Front, + Back = WGPUCullMode_Back, +}; +static_assert(sizeof(CullMode) == sizeof(WGPUCullMode), "sizeof mismatch for CullMode"); +static_assert(alignof(CullMode) == alignof(WGPUCullMode), "alignof mismatch for CullMode"); + +enum class DeviceLostReason : uint32_t { + Unknown = WGPUDeviceLostReason_Unknown, + Destroyed = WGPUDeviceLostReason_Destroyed, + CallbackCancelled = WGPUDeviceLostReason_CallbackCancelled, + FailedCreation = WGPUDeviceLostReason_FailedCreation, +}; +static_assert(sizeof(DeviceLostReason) == sizeof(WGPUDeviceLostReason), "sizeof mismatch for DeviceLostReason"); +static_assert(alignof(DeviceLostReason) == alignof(WGPUDeviceLostReason), "alignof mismatch for DeviceLostReason"); + +enum class ErrorFilter : uint32_t { + Validation = WGPUErrorFilter_Validation, + OutOfMemory = WGPUErrorFilter_OutOfMemory, + Internal = WGPUErrorFilter_Internal, +}; +static_assert(sizeof(ErrorFilter) == sizeof(WGPUErrorFilter), "sizeof mismatch for ErrorFilter"); +static_assert(alignof(ErrorFilter) == alignof(WGPUErrorFilter), "alignof mismatch for ErrorFilter"); + +enum class ErrorType : uint32_t { + NoError = WGPUErrorType_NoError, + Validation = WGPUErrorType_Validation, + OutOfMemory = WGPUErrorType_OutOfMemory, + Internal = WGPUErrorType_Internal, + Unknown = WGPUErrorType_Unknown, +}; +static_assert(sizeof(ErrorType) == sizeof(WGPUErrorType), "sizeof mismatch for ErrorType"); +static_assert(alignof(ErrorType) == alignof(WGPUErrorType), "alignof mismatch for ErrorType"); + +enum class FeatureLevel : uint32_t { + Undefined = WGPUFeatureLevel_Undefined, + Compatibility = WGPUFeatureLevel_Compatibility, + Core = WGPUFeatureLevel_Core, +}; +static_assert(sizeof(FeatureLevel) == sizeof(WGPUFeatureLevel), "sizeof mismatch for FeatureLevel"); +static_assert(alignof(FeatureLevel) == alignof(WGPUFeatureLevel), "alignof mismatch for FeatureLevel"); + +enum class FeatureName : uint32_t { + CoreFeaturesAndLimits = WGPUFeatureName_CoreFeaturesAndLimits, + DepthClipControl = WGPUFeatureName_DepthClipControl, + Depth32FloatStencil8 = WGPUFeatureName_Depth32FloatStencil8, + TextureCompressionBC = WGPUFeatureName_TextureCompressionBC, + TextureCompressionBCSliced3D = WGPUFeatureName_TextureCompressionBCSliced3D, + TextureCompressionETC2 = WGPUFeatureName_TextureCompressionETC2, + TextureCompressionASTC = WGPUFeatureName_TextureCompressionASTC, + TextureCompressionASTCSliced3D = WGPUFeatureName_TextureCompressionASTCSliced3D, + TimestampQuery = WGPUFeatureName_TimestampQuery, + IndirectFirstInstance = WGPUFeatureName_IndirectFirstInstance, + ShaderF16 = WGPUFeatureName_ShaderF16, + RG11B10UfloatRenderable = WGPUFeatureName_RG11B10UfloatRenderable, + BGRA8UnormStorage = WGPUFeatureName_BGRA8UnormStorage, + Float32Filterable = WGPUFeatureName_Float32Filterable, + Float32Blendable = WGPUFeatureName_Float32Blendable, + ClipDistances = WGPUFeatureName_ClipDistances, + DualSourceBlending = WGPUFeatureName_DualSourceBlending, + Subgroups = WGPUFeatureName_Subgroups, + TextureFormatsTier1 = WGPUFeatureName_TextureFormatsTier1, + TextureFormatsTier2 = WGPUFeatureName_TextureFormatsTier2, + PrimitiveIndex = WGPUFeatureName_PrimitiveIndex, + TextureComponentSwizzle = WGPUFeatureName_TextureComponentSwizzle, + Unorm16TextureFormats = WGPUFeatureName_Unorm16TextureFormats, + Snorm16TextureFormats = WGPUFeatureName_Snorm16TextureFormats, + MultiDrawIndirect = WGPUFeatureName_MultiDrawIndirect, +}; +static_assert(sizeof(FeatureName) == sizeof(WGPUFeatureName), "sizeof mismatch for FeatureName"); +static_assert(alignof(FeatureName) == alignof(WGPUFeatureName), "alignof mismatch for FeatureName"); + +enum class FilterMode : uint32_t { + Undefined = WGPUFilterMode_Undefined, + Nearest = WGPUFilterMode_Nearest, + Linear = WGPUFilterMode_Linear, +}; +static_assert(sizeof(FilterMode) == sizeof(WGPUFilterMode), "sizeof mismatch for FilterMode"); +static_assert(alignof(FilterMode) == alignof(WGPUFilterMode), "alignof mismatch for FilterMode"); + +enum class FrontFace : uint32_t { + Undefined = WGPUFrontFace_Undefined, + CCW = WGPUFrontFace_CCW, + CW = WGPUFrontFace_CW, +}; +static_assert(sizeof(FrontFace) == sizeof(WGPUFrontFace), "sizeof mismatch for FrontFace"); +static_assert(alignof(FrontFace) == alignof(WGPUFrontFace), "alignof mismatch for FrontFace"); + +enum class IndexFormat : uint32_t { + Undefined = WGPUIndexFormat_Undefined, + Uint16 = WGPUIndexFormat_Uint16, + Uint32 = WGPUIndexFormat_Uint32, +}; +static_assert(sizeof(IndexFormat) == sizeof(WGPUIndexFormat), "sizeof mismatch for IndexFormat"); +static_assert(alignof(IndexFormat) == alignof(WGPUIndexFormat), "alignof mismatch for IndexFormat"); + +enum class InstanceFeatureName : uint32_t { + TimedWaitAny = WGPUInstanceFeatureName_TimedWaitAny, + ShaderSourceSPIRV = WGPUInstanceFeatureName_ShaderSourceSPIRV, + MultipleDevicesPerAdapter = WGPUInstanceFeatureName_MultipleDevicesPerAdapter, +}; +static_assert(sizeof(InstanceFeatureName) == sizeof(WGPUInstanceFeatureName), "sizeof mismatch for InstanceFeatureName"); +static_assert(alignof(InstanceFeatureName) == alignof(WGPUInstanceFeatureName), "alignof mismatch for InstanceFeatureName"); + +enum class LoadOp : uint32_t { + Undefined = WGPULoadOp_Undefined, + Load = WGPULoadOp_Load, + Clear = WGPULoadOp_Clear, +}; +static_assert(sizeof(LoadOp) == sizeof(WGPULoadOp), "sizeof mismatch for LoadOp"); +static_assert(alignof(LoadOp) == alignof(WGPULoadOp), "alignof mismatch for LoadOp"); + +enum class MapAsyncStatus : uint32_t { + Success = WGPUMapAsyncStatus_Success, + CallbackCancelled = WGPUMapAsyncStatus_CallbackCancelled, + Error = WGPUMapAsyncStatus_Error, + Aborted = WGPUMapAsyncStatus_Aborted, +}; +static_assert(sizeof(MapAsyncStatus) == sizeof(WGPUMapAsyncStatus), "sizeof mismatch for MapAsyncStatus"); +static_assert(alignof(MapAsyncStatus) == alignof(WGPUMapAsyncStatus), "alignof mismatch for MapAsyncStatus"); + +enum class MipmapFilterMode : uint32_t { + Undefined = WGPUMipmapFilterMode_Undefined, + Nearest = WGPUMipmapFilterMode_Nearest, + Linear = WGPUMipmapFilterMode_Linear, +}; +static_assert(sizeof(MipmapFilterMode) == sizeof(WGPUMipmapFilterMode), "sizeof mismatch for MipmapFilterMode"); +static_assert(alignof(MipmapFilterMode) == alignof(WGPUMipmapFilterMode), "alignof mismatch for MipmapFilterMode"); + +enum class PopErrorScopeStatus : uint32_t { + Success = WGPUPopErrorScopeStatus_Success, + CallbackCancelled = WGPUPopErrorScopeStatus_CallbackCancelled, + Error = WGPUPopErrorScopeStatus_Error, +}; +static_assert(sizeof(PopErrorScopeStatus) == sizeof(WGPUPopErrorScopeStatus), "sizeof mismatch for PopErrorScopeStatus"); +static_assert(alignof(PopErrorScopeStatus) == alignof(WGPUPopErrorScopeStatus), "alignof mismatch for PopErrorScopeStatus"); + +enum class PowerPreference : uint32_t { + Undefined = WGPUPowerPreference_Undefined, + LowPower = WGPUPowerPreference_LowPower, + HighPerformance = WGPUPowerPreference_HighPerformance, +}; +static_assert(sizeof(PowerPreference) == sizeof(WGPUPowerPreference), "sizeof mismatch for PowerPreference"); +static_assert(alignof(PowerPreference) == alignof(WGPUPowerPreference), "alignof mismatch for PowerPreference"); + +enum class PredefinedColorSpace : uint32_t { + SRGB = WGPUPredefinedColorSpace_SRGB, + DisplayP3 = WGPUPredefinedColorSpace_DisplayP3, +}; +static_assert(sizeof(PredefinedColorSpace) == sizeof(WGPUPredefinedColorSpace), "sizeof mismatch for PredefinedColorSpace"); +static_assert(alignof(PredefinedColorSpace) == alignof(WGPUPredefinedColorSpace), "alignof mismatch for PredefinedColorSpace"); + +enum class PresentMode : uint32_t { + Undefined = WGPUPresentMode_Undefined, + Fifo = WGPUPresentMode_Fifo, + FifoRelaxed = WGPUPresentMode_FifoRelaxed, + Immediate = WGPUPresentMode_Immediate, + Mailbox = WGPUPresentMode_Mailbox, +}; +static_assert(sizeof(PresentMode) == sizeof(WGPUPresentMode), "sizeof mismatch for PresentMode"); +static_assert(alignof(PresentMode) == alignof(WGPUPresentMode), "alignof mismatch for PresentMode"); + +enum class PrimitiveTopology : uint32_t { + Undefined = WGPUPrimitiveTopology_Undefined, + PointList = WGPUPrimitiveTopology_PointList, + LineList = WGPUPrimitiveTopology_LineList, + LineStrip = WGPUPrimitiveTopology_LineStrip, + TriangleList = WGPUPrimitiveTopology_TriangleList, + TriangleStrip = WGPUPrimitiveTopology_TriangleStrip, +}; +static_assert(sizeof(PrimitiveTopology) == sizeof(WGPUPrimitiveTopology), "sizeof mismatch for PrimitiveTopology"); +static_assert(alignof(PrimitiveTopology) == alignof(WGPUPrimitiveTopology), "alignof mismatch for PrimitiveTopology"); + +enum class QueryType : uint32_t { + Occlusion = WGPUQueryType_Occlusion, + Timestamp = WGPUQueryType_Timestamp, +}; +static_assert(sizeof(QueryType) == sizeof(WGPUQueryType), "sizeof mismatch for QueryType"); +static_assert(alignof(QueryType) == alignof(WGPUQueryType), "alignof mismatch for QueryType"); + +enum class QueueWorkDoneStatus : uint32_t { + Success = WGPUQueueWorkDoneStatus_Success, + CallbackCancelled = WGPUQueueWorkDoneStatus_CallbackCancelled, + Error = WGPUQueueWorkDoneStatus_Error, +}; +static_assert(sizeof(QueueWorkDoneStatus) == sizeof(WGPUQueueWorkDoneStatus), "sizeof mismatch for QueueWorkDoneStatus"); +static_assert(alignof(QueueWorkDoneStatus) == alignof(WGPUQueueWorkDoneStatus), "alignof mismatch for QueueWorkDoneStatus"); + +enum class RequestAdapterStatus : uint32_t { + Success = WGPURequestAdapterStatus_Success, + CallbackCancelled = WGPURequestAdapterStatus_CallbackCancelled, + Unavailable = WGPURequestAdapterStatus_Unavailable, + Error = WGPURequestAdapterStatus_Error, +}; +static_assert(sizeof(RequestAdapterStatus) == sizeof(WGPURequestAdapterStatus), "sizeof mismatch for RequestAdapterStatus"); +static_assert(alignof(RequestAdapterStatus) == alignof(WGPURequestAdapterStatus), "alignof mismatch for RequestAdapterStatus"); + +enum class RequestDeviceStatus : uint32_t { + Success = WGPURequestDeviceStatus_Success, + CallbackCancelled = WGPURequestDeviceStatus_CallbackCancelled, + Error = WGPURequestDeviceStatus_Error, +}; +static_assert(sizeof(RequestDeviceStatus) == sizeof(WGPURequestDeviceStatus), "sizeof mismatch for RequestDeviceStatus"); +static_assert(alignof(RequestDeviceStatus) == alignof(WGPURequestDeviceStatus), "alignof mismatch for RequestDeviceStatus"); + +enum class SamplerBindingType : uint32_t { + BindingNotUsed = WGPUSamplerBindingType_BindingNotUsed, + Undefined = WGPUSamplerBindingType_Undefined, + Filtering = WGPUSamplerBindingType_Filtering, + NonFiltering = WGPUSamplerBindingType_NonFiltering, + Comparison = WGPUSamplerBindingType_Comparison, +}; +static_assert(sizeof(SamplerBindingType) == sizeof(WGPUSamplerBindingType), "sizeof mismatch for SamplerBindingType"); +static_assert(alignof(SamplerBindingType) == alignof(WGPUSamplerBindingType), "alignof mismatch for SamplerBindingType"); + +enum class Status : uint32_t { + Success = WGPUStatus_Success, + Error = WGPUStatus_Error, +}; +static_assert(sizeof(Status) == sizeof(WGPUStatus), "sizeof mismatch for Status"); +static_assert(alignof(Status) == alignof(WGPUStatus), "alignof mismatch for Status"); + +enum class StencilOperation : uint32_t { + Undefined = WGPUStencilOperation_Undefined, + Keep = WGPUStencilOperation_Keep, + Zero = WGPUStencilOperation_Zero, + Replace = WGPUStencilOperation_Replace, + Invert = WGPUStencilOperation_Invert, + IncrementClamp = WGPUStencilOperation_IncrementClamp, + DecrementClamp = WGPUStencilOperation_DecrementClamp, + IncrementWrap = WGPUStencilOperation_IncrementWrap, + DecrementWrap = WGPUStencilOperation_DecrementWrap, +}; +static_assert(sizeof(StencilOperation) == sizeof(WGPUStencilOperation), "sizeof mismatch for StencilOperation"); +static_assert(alignof(StencilOperation) == alignof(WGPUStencilOperation), "alignof mismatch for StencilOperation"); + +enum class StorageTextureAccess : uint32_t { + BindingNotUsed = WGPUStorageTextureAccess_BindingNotUsed, + Undefined = WGPUStorageTextureAccess_Undefined, + WriteOnly = WGPUStorageTextureAccess_WriteOnly, + ReadOnly = WGPUStorageTextureAccess_ReadOnly, + ReadWrite = WGPUStorageTextureAccess_ReadWrite, +}; +static_assert(sizeof(StorageTextureAccess) == sizeof(WGPUStorageTextureAccess), "sizeof mismatch for StorageTextureAccess"); +static_assert(alignof(StorageTextureAccess) == alignof(WGPUStorageTextureAccess), "alignof mismatch for StorageTextureAccess"); + +enum class StoreOp : uint32_t { + Undefined = WGPUStoreOp_Undefined, + Store = WGPUStoreOp_Store, + Discard = WGPUStoreOp_Discard, +}; +static_assert(sizeof(StoreOp) == sizeof(WGPUStoreOp), "sizeof mismatch for StoreOp"); +static_assert(alignof(StoreOp) == alignof(WGPUStoreOp), "alignof mismatch for StoreOp"); + +enum class SType : uint32_t { + ShaderSourceSPIRV = WGPUSType_ShaderSourceSPIRV, + ShaderSourceWGSL = WGPUSType_ShaderSourceWGSL, + RenderPassMaxDrawCount = WGPUSType_RenderPassMaxDrawCount, + SurfaceSourceMetalLayer = WGPUSType_SurfaceSourceMetalLayer, + SurfaceSourceWindowsHWND = WGPUSType_SurfaceSourceWindowsHWND, + SurfaceSourceXlibWindow = WGPUSType_SurfaceSourceXlibWindow, + SurfaceSourceWaylandSurface = WGPUSType_SurfaceSourceWaylandSurface, + SurfaceSourceAndroidNativeWindow = WGPUSType_SurfaceSourceAndroidNativeWindow, + SurfaceSourceXCBWindow = WGPUSType_SurfaceSourceXCBWindow, + SurfaceColorManagement = WGPUSType_SurfaceColorManagement, + RequestAdapterWebXROptions = WGPUSType_RequestAdapterWebXROptions, + TextureComponentSwizzleDescriptor = WGPUSType_TextureComponentSwizzleDescriptor, + CompatibilityModeLimits = WGPUSType_CompatibilityModeLimits, + TextureBindingViewDimensionDescriptor = WGPUSType_TextureBindingViewDimensionDescriptor, + EmscriptenSurfaceSourceCanvasHTMLSelector = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector, + DawnCompilationMessageUtf16 = WGPUSType_DawnCompilationMessageUtf16, +}; +static_assert(sizeof(SType) == sizeof(WGPUSType), "sizeof mismatch for SType"); +static_assert(alignof(SType) == alignof(WGPUSType), "alignof mismatch for SType"); + +enum class SurfaceGetCurrentTextureStatus : uint32_t { + SuccessOptimal = WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal, + SuccessSuboptimal = WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal, + Timeout = WGPUSurfaceGetCurrentTextureStatus_Timeout, + Outdated = WGPUSurfaceGetCurrentTextureStatus_Outdated, + Lost = WGPUSurfaceGetCurrentTextureStatus_Lost, + Error = WGPUSurfaceGetCurrentTextureStatus_Error, +}; +static_assert(sizeof(SurfaceGetCurrentTextureStatus) == sizeof(WGPUSurfaceGetCurrentTextureStatus), "sizeof mismatch for SurfaceGetCurrentTextureStatus"); +static_assert(alignof(SurfaceGetCurrentTextureStatus) == alignof(WGPUSurfaceGetCurrentTextureStatus), "alignof mismatch for SurfaceGetCurrentTextureStatus"); + +enum class TextureAspect : uint32_t { + Undefined = WGPUTextureAspect_Undefined, + All = WGPUTextureAspect_All, + StencilOnly = WGPUTextureAspect_StencilOnly, + DepthOnly = WGPUTextureAspect_DepthOnly, +}; +static_assert(sizeof(TextureAspect) == sizeof(WGPUTextureAspect), "sizeof mismatch for TextureAspect"); +static_assert(alignof(TextureAspect) == alignof(WGPUTextureAspect), "alignof mismatch for TextureAspect"); + +enum class TextureDimension : uint32_t { + Undefined = WGPUTextureDimension_Undefined, + e1D = WGPUTextureDimension_1D, + e2D = WGPUTextureDimension_2D, + e3D = WGPUTextureDimension_3D, +}; +static_assert(sizeof(TextureDimension) == sizeof(WGPUTextureDimension), "sizeof mismatch for TextureDimension"); +static_assert(alignof(TextureDimension) == alignof(WGPUTextureDimension), "alignof mismatch for TextureDimension"); + +enum class TextureFormat : uint32_t { + Undefined = WGPUTextureFormat_Undefined, + R8Unorm = WGPUTextureFormat_R8Unorm, + R8Snorm = WGPUTextureFormat_R8Snorm, + R8Uint = WGPUTextureFormat_R8Uint, + R8Sint = WGPUTextureFormat_R8Sint, + R16Unorm = WGPUTextureFormat_R16Unorm, + R16Snorm = WGPUTextureFormat_R16Snorm, + R16Uint = WGPUTextureFormat_R16Uint, + R16Sint = WGPUTextureFormat_R16Sint, + R16Float = WGPUTextureFormat_R16Float, + RG8Unorm = WGPUTextureFormat_RG8Unorm, + RG8Snorm = WGPUTextureFormat_RG8Snorm, + RG8Uint = WGPUTextureFormat_RG8Uint, + RG8Sint = WGPUTextureFormat_RG8Sint, + R32Float = WGPUTextureFormat_R32Float, + R32Uint = WGPUTextureFormat_R32Uint, + R32Sint = WGPUTextureFormat_R32Sint, + RG16Unorm = WGPUTextureFormat_RG16Unorm, + RG16Snorm = WGPUTextureFormat_RG16Snorm, + RG16Uint = WGPUTextureFormat_RG16Uint, + RG16Sint = WGPUTextureFormat_RG16Sint, + RG16Float = WGPUTextureFormat_RG16Float, + RGBA8Unorm = WGPUTextureFormat_RGBA8Unorm, + RGBA8UnormSrgb = WGPUTextureFormat_RGBA8UnormSrgb, + RGBA8Snorm = WGPUTextureFormat_RGBA8Snorm, + RGBA8Uint = WGPUTextureFormat_RGBA8Uint, + RGBA8Sint = WGPUTextureFormat_RGBA8Sint, + BGRA8Unorm = WGPUTextureFormat_BGRA8Unorm, + BGRA8UnormSrgb = WGPUTextureFormat_BGRA8UnormSrgb, + RGB10A2Uint = WGPUTextureFormat_RGB10A2Uint, + RGB10A2Unorm = WGPUTextureFormat_RGB10A2Unorm, + RG11B10Ufloat = WGPUTextureFormat_RG11B10Ufloat, + RGB9E5Ufloat = WGPUTextureFormat_RGB9E5Ufloat, + RG32Float = WGPUTextureFormat_RG32Float, + RG32Uint = WGPUTextureFormat_RG32Uint, + RG32Sint = WGPUTextureFormat_RG32Sint, + RGBA16Unorm = WGPUTextureFormat_RGBA16Unorm, + RGBA16Snorm = WGPUTextureFormat_RGBA16Snorm, + RGBA16Uint = WGPUTextureFormat_RGBA16Uint, + RGBA16Sint = WGPUTextureFormat_RGBA16Sint, + RGBA16Float = WGPUTextureFormat_RGBA16Float, + RGBA32Float = WGPUTextureFormat_RGBA32Float, + RGBA32Uint = WGPUTextureFormat_RGBA32Uint, + RGBA32Sint = WGPUTextureFormat_RGBA32Sint, + Stencil8 = WGPUTextureFormat_Stencil8, + Depth16Unorm = WGPUTextureFormat_Depth16Unorm, + Depth24Plus = WGPUTextureFormat_Depth24Plus, + Depth24PlusStencil8 = WGPUTextureFormat_Depth24PlusStencil8, + Depth32Float = WGPUTextureFormat_Depth32Float, + Depth32FloatStencil8 = WGPUTextureFormat_Depth32FloatStencil8, + BC1RGBAUnorm = WGPUTextureFormat_BC1RGBAUnorm, + BC1RGBAUnormSrgb = WGPUTextureFormat_BC1RGBAUnormSrgb, + BC2RGBAUnorm = WGPUTextureFormat_BC2RGBAUnorm, + BC2RGBAUnormSrgb = WGPUTextureFormat_BC2RGBAUnormSrgb, + BC3RGBAUnorm = WGPUTextureFormat_BC3RGBAUnorm, + BC3RGBAUnormSrgb = WGPUTextureFormat_BC3RGBAUnormSrgb, + BC4RUnorm = WGPUTextureFormat_BC4RUnorm, + BC4RSnorm = WGPUTextureFormat_BC4RSnorm, + BC5RGUnorm = WGPUTextureFormat_BC5RGUnorm, + BC5RGSnorm = WGPUTextureFormat_BC5RGSnorm, + BC6HRGBUfloat = WGPUTextureFormat_BC6HRGBUfloat, + BC6HRGBFloat = WGPUTextureFormat_BC6HRGBFloat, + BC7RGBAUnorm = WGPUTextureFormat_BC7RGBAUnorm, + BC7RGBAUnormSrgb = WGPUTextureFormat_BC7RGBAUnormSrgb, + ETC2RGB8Unorm = WGPUTextureFormat_ETC2RGB8Unorm, + ETC2RGB8UnormSrgb = WGPUTextureFormat_ETC2RGB8UnormSrgb, + ETC2RGB8A1Unorm = WGPUTextureFormat_ETC2RGB8A1Unorm, + ETC2RGB8A1UnormSrgb = WGPUTextureFormat_ETC2RGB8A1UnormSrgb, + ETC2RGBA8Unorm = WGPUTextureFormat_ETC2RGBA8Unorm, + ETC2RGBA8UnormSrgb = WGPUTextureFormat_ETC2RGBA8UnormSrgb, + EACR11Unorm = WGPUTextureFormat_EACR11Unorm, + EACR11Snorm = WGPUTextureFormat_EACR11Snorm, + EACRG11Unorm = WGPUTextureFormat_EACRG11Unorm, + EACRG11Snorm = WGPUTextureFormat_EACRG11Snorm, + ASTC4x4Unorm = WGPUTextureFormat_ASTC4x4Unorm, + ASTC4x4UnormSrgb = WGPUTextureFormat_ASTC4x4UnormSrgb, + ASTC5x4Unorm = WGPUTextureFormat_ASTC5x4Unorm, + ASTC5x4UnormSrgb = WGPUTextureFormat_ASTC5x4UnormSrgb, + ASTC5x5Unorm = WGPUTextureFormat_ASTC5x5Unorm, + ASTC5x5UnormSrgb = WGPUTextureFormat_ASTC5x5UnormSrgb, + ASTC6x5Unorm = WGPUTextureFormat_ASTC6x5Unorm, + ASTC6x5UnormSrgb = WGPUTextureFormat_ASTC6x5UnormSrgb, + ASTC6x6Unorm = WGPUTextureFormat_ASTC6x6Unorm, + ASTC6x6UnormSrgb = WGPUTextureFormat_ASTC6x6UnormSrgb, + ASTC8x5Unorm = WGPUTextureFormat_ASTC8x5Unorm, + ASTC8x5UnormSrgb = WGPUTextureFormat_ASTC8x5UnormSrgb, + ASTC8x6Unorm = WGPUTextureFormat_ASTC8x6Unorm, + ASTC8x6UnormSrgb = WGPUTextureFormat_ASTC8x6UnormSrgb, + ASTC8x8Unorm = WGPUTextureFormat_ASTC8x8Unorm, + ASTC8x8UnormSrgb = WGPUTextureFormat_ASTC8x8UnormSrgb, + ASTC10x5Unorm = WGPUTextureFormat_ASTC10x5Unorm, + ASTC10x5UnormSrgb = WGPUTextureFormat_ASTC10x5UnormSrgb, + ASTC10x6Unorm = WGPUTextureFormat_ASTC10x6Unorm, + ASTC10x6UnormSrgb = WGPUTextureFormat_ASTC10x6UnormSrgb, + ASTC10x8Unorm = WGPUTextureFormat_ASTC10x8Unorm, + ASTC10x8UnormSrgb = WGPUTextureFormat_ASTC10x8UnormSrgb, + ASTC10x10Unorm = WGPUTextureFormat_ASTC10x10Unorm, + ASTC10x10UnormSrgb = WGPUTextureFormat_ASTC10x10UnormSrgb, + ASTC12x10Unorm = WGPUTextureFormat_ASTC12x10Unorm, + ASTC12x10UnormSrgb = WGPUTextureFormat_ASTC12x10UnormSrgb, + ASTC12x12Unorm = WGPUTextureFormat_ASTC12x12Unorm, + ASTC12x12UnormSrgb = WGPUTextureFormat_ASTC12x12UnormSrgb, +}; +static_assert(sizeof(TextureFormat) == sizeof(WGPUTextureFormat), "sizeof mismatch for TextureFormat"); +static_assert(alignof(TextureFormat) == alignof(WGPUTextureFormat), "alignof mismatch for TextureFormat"); + +enum class TextureSampleType : uint32_t { + BindingNotUsed = WGPUTextureSampleType_BindingNotUsed, + Undefined = WGPUTextureSampleType_Undefined, + Float = WGPUTextureSampleType_Float, + UnfilterableFloat = WGPUTextureSampleType_UnfilterableFloat, + Depth = WGPUTextureSampleType_Depth, + Sint = WGPUTextureSampleType_Sint, + Uint = WGPUTextureSampleType_Uint, +}; +static_assert(sizeof(TextureSampleType) == sizeof(WGPUTextureSampleType), "sizeof mismatch for TextureSampleType"); +static_assert(alignof(TextureSampleType) == alignof(WGPUTextureSampleType), "alignof mismatch for TextureSampleType"); + +enum class TextureViewDimension : uint32_t { + Undefined = WGPUTextureViewDimension_Undefined, + e1D = WGPUTextureViewDimension_1D, + e2D = WGPUTextureViewDimension_2D, + e2DArray = WGPUTextureViewDimension_2DArray, + Cube = WGPUTextureViewDimension_Cube, + CubeArray = WGPUTextureViewDimension_CubeArray, + e3D = WGPUTextureViewDimension_3D, +}; +static_assert(sizeof(TextureViewDimension) == sizeof(WGPUTextureViewDimension), "sizeof mismatch for TextureViewDimension"); +static_assert(alignof(TextureViewDimension) == alignof(WGPUTextureViewDimension), "alignof mismatch for TextureViewDimension"); + +enum class ToneMappingMode : uint32_t { + Standard = WGPUToneMappingMode_Standard, + Extended = WGPUToneMappingMode_Extended, +}; +static_assert(sizeof(ToneMappingMode) == sizeof(WGPUToneMappingMode), "sizeof mismatch for ToneMappingMode"); +static_assert(alignof(ToneMappingMode) == alignof(WGPUToneMappingMode), "alignof mismatch for ToneMappingMode"); + +enum class VertexFormat : uint32_t { + Uint8 = WGPUVertexFormat_Uint8, + Uint8x2 = WGPUVertexFormat_Uint8x2, + Uint8x4 = WGPUVertexFormat_Uint8x4, + Sint8 = WGPUVertexFormat_Sint8, + Sint8x2 = WGPUVertexFormat_Sint8x2, + Sint8x4 = WGPUVertexFormat_Sint8x4, + Unorm8 = WGPUVertexFormat_Unorm8, + Unorm8x2 = WGPUVertexFormat_Unorm8x2, + Unorm8x4 = WGPUVertexFormat_Unorm8x4, + Snorm8 = WGPUVertexFormat_Snorm8, + Snorm8x2 = WGPUVertexFormat_Snorm8x2, + Snorm8x4 = WGPUVertexFormat_Snorm8x4, + Uint16 = WGPUVertexFormat_Uint16, + Uint16x2 = WGPUVertexFormat_Uint16x2, + Uint16x4 = WGPUVertexFormat_Uint16x4, + Sint16 = WGPUVertexFormat_Sint16, + Sint16x2 = WGPUVertexFormat_Sint16x2, + Sint16x4 = WGPUVertexFormat_Sint16x4, + Unorm16 = WGPUVertexFormat_Unorm16, + Unorm16x2 = WGPUVertexFormat_Unorm16x2, + Unorm16x4 = WGPUVertexFormat_Unorm16x4, + Snorm16 = WGPUVertexFormat_Snorm16, + Snorm16x2 = WGPUVertexFormat_Snorm16x2, + Snorm16x4 = WGPUVertexFormat_Snorm16x4, + Float16 = WGPUVertexFormat_Float16, + Float16x2 = WGPUVertexFormat_Float16x2, + Float16x4 = WGPUVertexFormat_Float16x4, + Float32 = WGPUVertexFormat_Float32, + Float32x2 = WGPUVertexFormat_Float32x2, + Float32x3 = WGPUVertexFormat_Float32x3, + Float32x4 = WGPUVertexFormat_Float32x4, + Uint32 = WGPUVertexFormat_Uint32, + Uint32x2 = WGPUVertexFormat_Uint32x2, + Uint32x3 = WGPUVertexFormat_Uint32x3, + Uint32x4 = WGPUVertexFormat_Uint32x4, + Sint32 = WGPUVertexFormat_Sint32, + Sint32x2 = WGPUVertexFormat_Sint32x2, + Sint32x3 = WGPUVertexFormat_Sint32x3, + Sint32x4 = WGPUVertexFormat_Sint32x4, + Unorm10_10_10_2 = WGPUVertexFormat_Unorm10_10_10_2, + Unorm8x4BGRA = WGPUVertexFormat_Unorm8x4BGRA, +}; +static_assert(sizeof(VertexFormat) == sizeof(WGPUVertexFormat), "sizeof mismatch for VertexFormat"); +static_assert(alignof(VertexFormat) == alignof(WGPUVertexFormat), "alignof mismatch for VertexFormat"); + +enum class VertexStepMode : uint32_t { + Undefined = WGPUVertexStepMode_Undefined, + Vertex = WGPUVertexStepMode_Vertex, + Instance = WGPUVertexStepMode_Instance, +}; +static_assert(sizeof(VertexStepMode) == sizeof(WGPUVertexStepMode), "sizeof mismatch for VertexStepMode"); +static_assert(alignof(VertexStepMode) == alignof(WGPUVertexStepMode), "alignof mismatch for VertexStepMode"); + +enum class WaitStatus : uint32_t { + Success = WGPUWaitStatus_Success, + TimedOut = WGPUWaitStatus_TimedOut, + Error = WGPUWaitStatus_Error, +}; +static_assert(sizeof(WaitStatus) == sizeof(WGPUWaitStatus), "sizeof mismatch for WaitStatus"); +static_assert(alignof(WaitStatus) == alignof(WGPUWaitStatus), "alignof mismatch for WaitStatus"); + +enum class WGSLLanguageFeatureName : uint32_t { + ReadonlyAndReadwriteStorageTextures = WGPUWGSLLanguageFeatureName_ReadonlyAndReadwriteStorageTextures, + Packed4x8IntegerDotProduct = WGPUWGSLLanguageFeatureName_Packed4x8IntegerDotProduct, + UnrestrictedPointerParameters = WGPUWGSLLanguageFeatureName_UnrestrictedPointerParameters, + PointerCompositeAccess = WGPUWGSLLanguageFeatureName_PointerCompositeAccess, +}; +static_assert(sizeof(WGSLLanguageFeatureName) == sizeof(WGPUWGSLLanguageFeatureName), "sizeof mismatch for WGSLLanguageFeatureName"); +static_assert(alignof(WGSLLanguageFeatureName) == alignof(WGPUWGSLLanguageFeatureName), "alignof mismatch for WGSLLanguageFeatureName"); + + +enum class BufferUsage : uint64_t { + None = WGPUBufferUsage_None, + MapRead = WGPUBufferUsage_MapRead, + MapWrite = WGPUBufferUsage_MapWrite, + CopySrc = WGPUBufferUsage_CopySrc, + CopyDst = WGPUBufferUsage_CopyDst, + Index = WGPUBufferUsage_Index, + Vertex = WGPUBufferUsage_Vertex, + Uniform = WGPUBufferUsage_Uniform, + Storage = WGPUBufferUsage_Storage, + Indirect = WGPUBufferUsage_Indirect, + QueryResolve = WGPUBufferUsage_QueryResolve, +}; +static_assert(sizeof(BufferUsage) == sizeof(WGPUBufferUsage), "sizeof mismatch for BufferUsage"); +static_assert(alignof(BufferUsage) == alignof(WGPUBufferUsage), "alignof mismatch for BufferUsage"); + +enum class ColorWriteMask : uint64_t { + None = WGPUColorWriteMask_None, + Red = WGPUColorWriteMask_Red, + Green = WGPUColorWriteMask_Green, + Blue = WGPUColorWriteMask_Blue, + Alpha = WGPUColorWriteMask_Alpha, + All = WGPUColorWriteMask_All, +}; +static_assert(sizeof(ColorWriteMask) == sizeof(WGPUColorWriteMask), "sizeof mismatch for ColorWriteMask"); +static_assert(alignof(ColorWriteMask) == alignof(WGPUColorWriteMask), "alignof mismatch for ColorWriteMask"); + +enum class MapMode : uint64_t { + None = WGPUMapMode_None, + Read = WGPUMapMode_Read, + Write = WGPUMapMode_Write, +}; +static_assert(sizeof(MapMode) == sizeof(WGPUMapMode), "sizeof mismatch for MapMode"); +static_assert(alignof(MapMode) == alignof(WGPUMapMode), "alignof mismatch for MapMode"); + +enum class ShaderStage : uint64_t { + None = WGPUShaderStage_None, + Vertex = WGPUShaderStage_Vertex, + Fragment = WGPUShaderStage_Fragment, + Compute = WGPUShaderStage_Compute, +}; +static_assert(sizeof(ShaderStage) == sizeof(WGPUShaderStage), "sizeof mismatch for ShaderStage"); +static_assert(alignof(ShaderStage) == alignof(WGPUShaderStage), "alignof mismatch for ShaderStage"); + +enum class TextureUsage : uint64_t { + None = WGPUTextureUsage_None, + CopySrc = WGPUTextureUsage_CopySrc, + CopyDst = WGPUTextureUsage_CopyDst, + TextureBinding = WGPUTextureUsage_TextureBinding, + StorageBinding = WGPUTextureUsage_StorageBinding, + RenderAttachment = WGPUTextureUsage_RenderAttachment, +}; +static_assert(sizeof(TextureUsage) == sizeof(WGPUTextureUsage), "sizeof mismatch for TextureUsage"); +static_assert(alignof(TextureUsage) == alignof(WGPUTextureUsage), "alignof mismatch for TextureUsage"); + + +// TODO(crbug.com/42241461): Update these to not be using the C callback types, and instead be +// defined using C++ types instead. Note that when we remove these, the C++ callback info types +// should also all be removed as they will no longer be necessary given the C++ templated +// functions calls and setter utilities. +using Proc = WGPUProc; + +// Special class for booleans in order to allow implicit conversions. +class Bool { + public: + constexpr Bool() = default; + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + constexpr Bool(bool value) : mValue(static_cast(value)) {} + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + Bool(WGPUBool value): mValue(value) {} + + constexpr operator bool() const { return static_cast(mValue); } + + private: + friend struct std::hash; + // Default to false. + WGPUBool mValue = static_cast(false); +}; + +// Special class for optional booleans in order to allow conversions. +class OptionalBool { + public: + constexpr OptionalBool() = default; + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + constexpr OptionalBool(bool value) : mValue(static_cast(value)) {} + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + constexpr OptionalBool(std::optional value) : + mValue(value ? static_cast(*value) : WGPUOptionalBool_Undefined) {} + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + constexpr OptionalBool(WGPUOptionalBool value): mValue(value) {} + + // Define the values that are equivalent to the enums. + static const OptionalBool False; + static const OptionalBool True; + static const OptionalBool Undefined; + + // Assignment operators. + OptionalBool& operator=(const bool& value) { + mValue = static_cast(value); + return *this; + } + OptionalBool& operator=(const std::optional& value) { + mValue = value ? static_cast(*value) : WGPUOptionalBool_Undefined; + return *this; + } + OptionalBool& operator=(const WGPUOptionalBool& value) { + mValue = value; + return *this; + } + + // Conversion functions. + operator WGPUOptionalBool() const { return mValue; } + operator std::optional() const { + if (mValue == WGPUOptionalBool_Undefined) { + return std::nullopt; + } + return static_cast(mValue); + } + + // Comparison functions. + friend bool operator==(const OptionalBool& lhs, const OptionalBool& rhs) { + return lhs.mValue == rhs.mValue; + } + friend bool operator!=(const OptionalBool& lhs, const OptionalBool& rhs) { + return lhs.mValue != rhs.mValue; + } + + private: + friend struct std::hash; + // Default to undefined. + WGPUOptionalBool mValue = WGPUOptionalBool_Undefined; +}; +inline const OptionalBool OptionalBool::False = OptionalBool(WGPUOptionalBool_False); +inline const OptionalBool OptionalBool::True = OptionalBool(WGPUOptionalBool_True); +inline const OptionalBool OptionalBool::Undefined = OptionalBool(WGPUOptionalBool_Undefined); + +// Helper class to wrap Status which allows implicit conversion to bool. +// Used while callers switch to checking the Status enum instead of booleans. +// TODO(crbug.com/42241199): Remove when all callers check the enum. +struct ConvertibleStatus { + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + constexpr ConvertibleStatus(Status status) : status(status) {} + // NOLINTNEXTLINE(runtime/explicit) allow implicit conversion + constexpr operator bool() const { + return status == Status::Success; + } + // NOLINTNEXTLINE(runtime/explicit) allow implicit conversion + constexpr operator Status() const { + return status; + } + Status status; +}; + +template +class ObjectBase { + public: + ObjectBase() = default; + ObjectBase(CType handle): mHandle(handle) { + if (mHandle) Derived::WGPUAddRef(mHandle); + } + ~ObjectBase() { + if (mHandle) Derived::WGPURelease(mHandle); + } + + ObjectBase(ObjectBase const& other) + : ObjectBase(other.Get()) { + } + Derived& operator=(ObjectBase const& other) { + if (&other != this) { + if (mHandle) Derived::WGPURelease(mHandle); + mHandle = other.mHandle; + if (mHandle) Derived::WGPUAddRef(mHandle); + } + + return static_cast(*this); + } + + ObjectBase(ObjectBase&& other) { + mHandle = other.mHandle; + other.mHandle = 0; + } + Derived& operator=(ObjectBase&& other) { + if (&other != this) { + if (mHandle) Derived::WGPURelease(mHandle); + mHandle = other.mHandle; + other.mHandle = 0; + } + + return static_cast(*this); + } + + ObjectBase(std::nullptr_t) {} + Derived& operator=(std::nullptr_t) { + if (mHandle != nullptr) { + Derived::WGPURelease(mHandle); + mHandle = nullptr; + } + return static_cast(*this); + } + + bool operator==(std::nullptr_t) const { + return mHandle == nullptr; + } + bool operator!=(std::nullptr_t) const { + return mHandle != nullptr; + } + + explicit operator bool() const { + return mHandle != nullptr; + } + CType Get() const { + return mHandle; + } + CType MoveToCHandle() { + CType result = mHandle; + mHandle = 0; + return result; + } + static Derived Acquire(CType handle) { + Derived result; + result.mHandle = handle; + return result; + } + + protected: + CType mHandle = nullptr; +}; + +class Adapter; +class BindGroup; +class BindGroupLayout; +class Buffer; +class CommandBuffer; +class CommandEncoder; +class ComputePassEncoder; +class ComputePipeline; +class Device; +class Instance; +class PipelineLayout; +class QuerySet; +class Queue; +class RenderBundle; +class RenderBundleEncoder; +class RenderPassEncoder; +class RenderPipeline; +class Sampler; +class ShaderModule; +class Surface; +class Texture; +class TextureView; + +struct StringView; +struct AdapterInfo; +struct BindGroupEntry; +struct BlendComponent; +struct BufferBindingLayout; +struct BufferDescriptor; +struct Color; +struct CommandBufferDescriptor; +struct CommandEncoderDescriptor; +struct CompatibilityModeLimits; +struct ConstantEntry; +struct DawnCompilationMessageUtf16; +struct EmscriptenSurfaceSourceCanvasHTMLSelector; +struct Extent3D; +struct Future; +struct InstanceLimits; +struct INTERNAL_HAVE_EMDAWNWEBGPU_HEADER; +struct MultisampleState; +struct Origin3D; +struct PassTimestampWrites; +struct PipelineLayoutDescriptor; +struct PrimitiveState; +struct QuerySetDescriptor; +struct QueueDescriptor; +struct RenderBundleDescriptor; +struct RenderBundleEncoderDescriptor; +struct RenderPassDepthStencilAttachment; +struct RenderPassMaxDrawCount; +struct RequestAdapterWebXROptions; +struct SamplerBindingLayout; +struct SamplerDescriptor; +struct ShaderSourceSPIRV; +struct ShaderSourceWGSL; +struct StencilFaceState; +struct StorageTextureBindingLayout; +struct SupportedFeatures; +struct SupportedInstanceFeatures; +struct SupportedWGSLLanguageFeatures; +struct SurfaceCapabilities; +struct SurfaceColorManagement; +struct SurfaceConfiguration; +struct SurfaceTexture; +struct TexelCopyBufferLayout; +struct TextureBindingLayout; +struct TextureBindingViewDimensionDescriptor; +struct TextureComponentSwizzle; +struct VertexAttribute; +struct BindGroupDescriptor; +struct BindGroupLayoutEntry; +struct BlendState; +struct CompilationMessage; +struct ComputePassDescriptor; +struct ComputeState; +struct DepthStencilState; +struct FutureWaitInfo; +struct InstanceDescriptor; +struct Limits; +struct RenderPassColorAttachment; +struct RequestAdapterOptions; +struct ShaderModuleDescriptor; +struct SurfaceDescriptor; +struct TexelCopyBufferInfo; +struct TexelCopyTextureInfo; +struct TextureComponentSwizzleDescriptor; +struct TextureDescriptor; +struct VertexBufferLayout; +struct BindGroupLayoutDescriptor; +struct ColorTargetState; +struct CompilationInfo; +struct ComputePipelineDescriptor; +struct DeviceDescriptor; +struct RenderPassDescriptor; +struct TextureViewDescriptor; +struct VertexState; +struct FragmentState; +struct RenderPipelineDescriptor; + +// TODO(42241188): Remove once all clients use StringView versions of the callbacks. +// To make MSVC happy we need a StringView constructor from the adapter, so we first need to +// forward declare StringViewAdapter here. Otherwise MSVC complains about an ambiguous conversion. +namespace detail { + struct StringViewAdapter; +} // namespace detail + +struct StringView { + char const * data = nullptr; + size_t length = WGPU_STRLEN; + + inline constexpr StringView() noexcept = default; + + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + inline constexpr StringView(const std::string_view& sv) noexcept { + this->data = sv.data(); + this->length = sv.length(); + } + + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + inline constexpr StringView(const char* s) { + this->data = s; + this->length = WGPU_STRLEN; // use strlen + } + + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + inline constexpr StringView(WGPUStringView s) { + this->data = s.data; + this->length = s.length; + } + + inline constexpr StringView(const char* data, size_t length) { + this->data = data; + this->length = length; + } + + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + inline constexpr StringView(std::nullptr_t) { + this->data = nullptr; + this->length = WGPU_STRLEN; + } + + // NOLINTNEXTLINE(runtime/explicit) allow implicit construction + inline constexpr StringView(std::nullopt_t) { + this->data = nullptr; + this->length = WGPU_STRLEN; + } + + bool IsUndefined() const { + return this->data == nullptr && this->length == wgpu::kStrlen; + } + + // NOLINTNEXTLINE(runtime/explicit) allow implicit conversion + operator std::string_view() const { + if (this->length == wgpu::kStrlen) { + if (IsUndefined()) { + return {}; + } + return {this->data}; + } + return {this->data, this->length}; + } + + template >> + explicit operator View() const { + if (this->length == wgpu::kStrlen) { + if (IsUndefined()) { + return {}; + } + return {this->data}; + } + return {this->data, this->length}; + } + + + StringView(const detail::StringViewAdapter& s); +}; + +namespace detail { +constexpr size_t ConstexprMax(size_t a, size_t b) { + return a > b ? a : b; +} + +template +static T& AsNonConstReference(const T& value) { + return const_cast(value); +} + +// A wrapper around StringView that can be implicitly converted to const char* with temporary +// storage that adds the \0 for output strings that are all explicitly-sized. +// TODO(42241188): Remove once all clients use StringView versions of the callbacks. +struct StringViewAdapter { + WGPUStringView sv; + char* nullTerminated = nullptr; + + StringViewAdapter(WGPUStringView sv) : sv(sv) {} + ~StringViewAdapter() { delete[] nullTerminated; } + operator ::WGPUStringView() { return sv; } + operator StringView() { return {sv.data, sv.length}; } + operator const char*() { + assert(sv.length != WGPU_STRLEN); + assert(nullTerminated == nullptr); + nullTerminated = new char[sv.length + 1]; + for (size_t i = 0; i < sv.length; i++) { + nullTerminated[i] = sv.data[i]; + } + nullTerminated[sv.length] = 0; + return nullTerminated; + } +}; +} // namespace detail + +inline StringView::StringView(const detail::StringViewAdapter& s): data(s.sv.data), length(s.sv.length) {} + +namespace detail { +// For callbacks, we support two modes: +// 1) No userdata where we allow a std::function type that can include argument captures. +// 2) Explicit typed userdata where we only allow non-capturing lambdas or function pointers. +template +struct CallbackTypeBase; +template +struct CallbackTypeBase> { + using Callback = std::function; +}; +template +struct CallbackTypeBase, void> { + using Callback = void (Args...); +}; +template +struct CallbackTypeBase, T> { + using Callback = void (Args..., T); +}; +} // namespace detail + + +template +using BufferMapCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using CompilationInfoCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using CreateComputePipelineAsyncCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using CreateRenderPipelineAsyncCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using PopErrorScopeCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using QueueWorkDoneCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using RequestAdapterCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using RequestDeviceCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using DeviceLostCallback = typename detail::CallbackTypeBase, T...>::Callback; +template +using UncapturedErrorCallback = typename detail::CallbackTypeBase, T...>::Callback; + + + + +class Adapter : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void GetFeatures(SupportedFeatures * features) const; + inline ConvertibleStatus GetInfo(AdapterInfo * info) const; + inline ConvertibleStatus GetLimits(Limits * limits) const; + inline Bool HasFeature(FeatureName feature) const; + template , + typename CbChar = void (RequestDeviceStatus status, Device device, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future RequestDevice(DeviceDescriptor const * descriptor, CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future RequestDevice(DeviceDescriptor const * descriptor, CallbackMode callbackMode,L callback) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUAdapter handle); + static inline void WGPURelease(WGPUAdapter handle); +}; + +class BindGroup : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUBindGroup handle); + static inline void WGPURelease(WGPUBindGroup handle); +}; + +class BindGroupLayout : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUBindGroupLayout handle); + static inline void WGPURelease(WGPUBindGroupLayout handle); +}; + +class Buffer : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void Destroy() const; + inline void const * GetConstMappedRange(size_t offset = 0, size_t size = kWholeMapSize) const; + inline void * GetMappedRange(size_t offset = 0, size_t size = kWholeMapSize) const; + inline BufferMapState GetMapState() const; + inline uint64_t GetSize() const; + inline BufferUsage GetUsage() const; + template , + typename CbChar = void (MapAsyncStatus status, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future MapAsync(MapMode mode, size_t offset, size_t size, CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future MapAsync(MapMode mode, size_t offset, size_t size, CallbackMode callbackMode,L callback) const; + inline ConvertibleStatus ReadMappedRange(size_t offset, void * data, size_t size) const; + inline void SetLabel(StringView label) const; + inline void Unmap() const; + inline ConvertibleStatus WriteMappedRange(size_t offset, void const * data, size_t size) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUBuffer handle); + static inline void WGPURelease(WGPUBuffer handle); +}; + +class CommandBuffer : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUCommandBuffer handle); + static inline void WGPURelease(WGPUCommandBuffer handle); +}; + +class CommandEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline ComputePassEncoder BeginComputePass(ComputePassDescriptor const * descriptor = nullptr) const; + inline RenderPassEncoder BeginRenderPass(RenderPassDescriptor const * descriptor) const; + inline void ClearBuffer(Buffer const& buffer, uint64_t offset = 0, uint64_t size = kWholeSize) const; + inline void CopyBufferToBuffer(Buffer const& source, uint64_t sourceOffset, Buffer const& destination, uint64_t destinationOffset, uint64_t size) const; + inline void CopyBufferToTexture(TexelCopyBufferInfo const * source, TexelCopyTextureInfo const * destination, Extent3D const * copySize) const; + inline void CopyTextureToBuffer(TexelCopyTextureInfo const * source, TexelCopyBufferInfo const * destination, Extent3D const * copySize) const; + inline void CopyTextureToTexture(TexelCopyTextureInfo const * source, TexelCopyTextureInfo const * destination, Extent3D const * copySize) const; + inline CommandBuffer Finish(CommandBufferDescriptor const * descriptor = nullptr) const; + inline void InsertDebugMarker(StringView markerLabel) const; + inline void PopDebugGroup() const; + inline void PushDebugGroup(StringView groupLabel) const; + inline void ResolveQuerySet(QuerySet const& querySet, uint32_t firstQuery, uint32_t queryCount, Buffer const& destination, uint64_t destinationOffset) const; + inline void SetLabel(StringView label) const; + inline void WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUCommandEncoder handle); + static inline void WGPURelease(WGPUCommandEncoder handle); +}; + +class ComputePassEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void DispatchWorkgroups(uint32_t workgroupCountX, uint32_t workgroupCountY = 1, uint32_t workgroupCountZ = 1) const; + inline void DispatchWorkgroupsIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + inline void End() const; + inline void InsertDebugMarker(StringView markerLabel) const; + inline void PopDebugGroup() const; + inline void PushDebugGroup(StringView groupLabel) const; + inline void SetBindGroup(uint32_t groupIndex, BindGroup const& group = nullptr, size_t dynamicOffsetCount = 0, uint32_t const * dynamicOffsets = nullptr) const; + inline void SetLabel(StringView label) const; + inline void SetPipeline(ComputePipeline const& pipeline) const; + inline void WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUComputePassEncoder handle); + static inline void WGPURelease(WGPUComputePassEncoder handle); +}; + +class ComputePipeline : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline BindGroupLayout GetBindGroupLayout(uint32_t groupIndex) const; + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUComputePipeline handle); + static inline void WGPURelease(WGPUComputePipeline handle); +}; + +class Device : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline BindGroup CreateBindGroup(BindGroupDescriptor const * descriptor) const; + inline BindGroupLayout CreateBindGroupLayout(BindGroupLayoutDescriptor const * descriptor) const; + inline Buffer CreateBuffer(BufferDescriptor const * descriptor) const; + inline CommandEncoder CreateCommandEncoder(CommandEncoderDescriptor const * descriptor = nullptr) const; + inline ComputePipeline CreateComputePipeline(ComputePipelineDescriptor const * descriptor) const; + template , + typename CbChar = void (CreatePipelineAsyncStatus status, ComputePipeline pipeline, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future CreateComputePipelineAsync(ComputePipelineDescriptor const * descriptor, CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future CreateComputePipelineAsync(ComputePipelineDescriptor const * descriptor, CallbackMode callbackMode,L callback) const; + inline PipelineLayout CreatePipelineLayout(PipelineLayoutDescriptor const * descriptor) const; + inline QuerySet CreateQuerySet(QuerySetDescriptor const * descriptor) const; + inline RenderBundleEncoder CreateRenderBundleEncoder(RenderBundleEncoderDescriptor const * descriptor) const; + inline RenderPipeline CreateRenderPipeline(RenderPipelineDescriptor const * descriptor) const; + template , + typename CbChar = void (CreatePipelineAsyncStatus status, RenderPipeline pipeline, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future CreateRenderPipelineAsync(RenderPipelineDescriptor const * descriptor, CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future CreateRenderPipelineAsync(RenderPipelineDescriptor const * descriptor, CallbackMode callbackMode,L callback) const; + inline Sampler CreateSampler(SamplerDescriptor const * descriptor = nullptr) const; + inline ShaderModule CreateShaderModule(ShaderModuleDescriptor const * descriptor) const; + inline Texture CreateTexture(TextureDescriptor const * descriptor) const; + inline void Destroy() const; + inline ConvertibleStatus GetAdapterInfo(AdapterInfo * adapterInfo) const; + inline void GetFeatures(SupportedFeatures * features) const; + inline ConvertibleStatus GetLimits(Limits * limits) const; + inline Future GetLostFuture() const; + inline Queue GetQueue() const; + inline Bool HasFeature(FeatureName feature) const; + template , + typename CbChar = void (PopErrorScopeStatus status, ErrorType type, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future PopErrorScope(CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future PopErrorScope(CallbackMode callbackMode,L callback) const; + inline void PushErrorScope(ErrorFilter filter) const; + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUDevice handle); + static inline void WGPURelease(WGPUDevice handle); +}; + +class Instance : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline Surface CreateSurface(SurfaceDescriptor const * descriptor) const; + inline void GetWGSLLanguageFeatures(SupportedWGSLLanguageFeatures * features) const; + inline Bool HasWGSLLanguageFeature(WGSLLanguageFeatureName feature) const; + inline void ProcessEvents() const; + template , + typename CbChar = void (RequestAdapterStatus status, Adapter adapter, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future RequestAdapter(RequestAdapterOptions const * options, CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future RequestAdapter(RequestAdapterOptions const * options, CallbackMode callbackMode,L callback) const; + inline WaitStatus WaitAny(size_t futureCount, FutureWaitInfo * futures, uint64_t timeoutNS) const; + + inline WaitStatus WaitAny(Future f, uint64_t timeout) const; + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUInstance handle); + static inline void WGPURelease(WGPUInstance handle); +}; + +class PipelineLayout : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUPipelineLayout handle); + static inline void WGPURelease(WGPUPipelineLayout handle); +}; + +class QuerySet : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void Destroy() const; + inline uint32_t GetCount() const; + inline QueryType GetType() const; + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUQuerySet handle); + static inline void WGPURelease(WGPUQuerySet handle); +}; + +class Queue : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + template , + typename CbChar = void (QueueWorkDoneStatus status, const char* message, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future OnSubmittedWorkDone(CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future OnSubmittedWorkDone(CallbackMode callbackMode,L callback) const; + inline void SetLabel(StringView label) const; + inline void Submit(size_t commandCount, CommandBuffer const * commands) const; + inline void WriteBuffer(Buffer const& buffer, uint64_t bufferOffset, void const * data, size_t size) const; + inline void WriteTexture(TexelCopyTextureInfo const * destination, void const * data, size_t dataSize, TexelCopyBufferLayout const * dataLayout, Extent3D const * writeSize) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUQueue handle); + static inline void WGPURelease(WGPUQueue handle); +}; + +class RenderBundle : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPURenderBundle handle); + static inline void WGPURelease(WGPURenderBundle handle); +}; + +class RenderBundleEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void Draw(uint32_t vertexCount, uint32_t instanceCount = 1, uint32_t firstVertex = 0, uint32_t firstInstance = 0) const; + inline void DrawIndexed(uint32_t indexCount, uint32_t instanceCount = 1, uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) const; + inline void DrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + inline void DrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + inline RenderBundle Finish(RenderBundleDescriptor const * descriptor = nullptr) const; + inline void InsertDebugMarker(StringView markerLabel) const; + inline void PopDebugGroup() const; + inline void PushDebugGroup(StringView groupLabel) const; + inline void SetBindGroup(uint32_t groupIndex, BindGroup const& group = nullptr, size_t dynamicOffsetCount = 0, uint32_t const * dynamicOffsets = nullptr) const; + inline void SetIndexBuffer(Buffer const& buffer, IndexFormat format, uint64_t offset = 0, uint64_t size = kWholeSize) const; + inline void SetLabel(StringView label) const; + inline void SetPipeline(RenderPipeline const& pipeline) const; + inline void SetVertexBuffer(uint32_t slot, Buffer const& buffer = nullptr, uint64_t offset = 0, uint64_t size = kWholeSize) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPURenderBundleEncoder handle); + static inline void WGPURelease(WGPURenderBundleEncoder handle); +}; + +class RenderPassEncoder : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void BeginOcclusionQuery(uint32_t queryIndex) const; + inline void Draw(uint32_t vertexCount, uint32_t instanceCount = 1, uint32_t firstVertex = 0, uint32_t firstInstance = 0) const; + inline void DrawIndexed(uint32_t indexCount, uint32_t instanceCount = 1, uint32_t firstIndex = 0, int32_t baseVertex = 0, uint32_t firstInstance = 0) const; + inline void DrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + inline void DrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const; + inline void End() const; + inline void EndOcclusionQuery() const; + inline void ExecuteBundles(size_t bundleCount, RenderBundle const * bundles) const; + inline void InsertDebugMarker(StringView markerLabel) const; + inline void MultiDrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, Buffer const& drawCountBuffer = nullptr, uint64_t drawCountBufferOffset = 0) const; + inline void MultiDrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, Buffer const& drawCountBuffer = nullptr, uint64_t drawCountBufferOffset = 0) const; + inline void PopDebugGroup() const; + inline void PushDebugGroup(StringView groupLabel) const; + inline void SetBindGroup(uint32_t groupIndex, BindGroup const& group = nullptr, size_t dynamicOffsetCount = 0, uint32_t const * dynamicOffsets = nullptr) const; + inline void SetBlendConstant(Color const * color) const; + inline void SetIndexBuffer(Buffer const& buffer, IndexFormat format, uint64_t offset = 0, uint64_t size = kWholeSize) const; + inline void SetLabel(StringView label) const; + inline void SetPipeline(RenderPipeline const& pipeline) const; + inline void SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) const; + inline void SetStencilReference(uint32_t reference) const; + inline void SetVertexBuffer(uint32_t slot, Buffer const& buffer = nullptr, uint64_t offset = 0, uint64_t size = kWholeSize) const; + inline void SetViewport(float x, float y, float width, float height, float minDepth, float maxDepth) const; + inline void WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPURenderPassEncoder handle); + static inline void WGPURelease(WGPURenderPassEncoder handle); +}; + +class RenderPipeline : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline BindGroupLayout GetBindGroupLayout(uint32_t groupIndex) const; + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPURenderPipeline handle); + static inline void WGPURelease(WGPURenderPipeline handle); +}; + +class Sampler : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUSampler handle); + static inline void WGPURelease(WGPUSampler handle); +}; + +class ShaderModule : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + template , + typename CbChar = void (CompilationInfoRequestStatus status, CompilationInfo const * compilationInfo, T userdata), + typename = std::enable_if_t || std::is_convertible_v>> + Future GetCompilationInfo(CallbackMode callbackMode,F callback, T userdata) const; + template , + typename CbChar = std::function, + typename = std::enable_if_t || std::is_convertible_v>> + Future GetCompilationInfo(CallbackMode callbackMode,L callback) const; + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUShaderModule handle); + static inline void WGPURelease(WGPUShaderModule handle); +}; + +class Surface : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void Configure(SurfaceConfiguration const * config) const; + inline ConvertibleStatus GetCapabilities(Adapter const& adapter, SurfaceCapabilities * capabilities) const; + inline void GetCurrentTexture(SurfaceTexture * surfaceTexture) const; + inline ConvertibleStatus Present() const; + inline void SetLabel(StringView label) const; + inline void Unconfigure() const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUSurface handle); + static inline void WGPURelease(WGPUSurface handle); +}; + +class Texture : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline TextureView CreateView(TextureViewDescriptor const * descriptor = nullptr) const; + inline void Destroy() const; + inline uint32_t GetDepthOrArrayLayers() const; + inline TextureDimension GetDimension() const; + inline TextureFormat GetFormat() const; + inline uint32_t GetHeight() const; + inline uint32_t GetMipLevelCount() const; + inline uint32_t GetSampleCount() const; + inline TextureUsage GetUsage() const; + inline uint32_t GetWidth() const; + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUTexture handle); + static inline void WGPURelease(WGPUTexture handle); +}; + +class TextureView : public ObjectBase { + public: + using ObjectBase::ObjectBase; + using ObjectBase::operator=; + + inline void SetLabel(StringView label) const; + + + private: + friend ObjectBase; + static inline void WGPUAddRef(WGPUTextureView handle); + static inline void WGPURelease(WGPUTextureView handle); +}; + + +// ChainedStruct +static_assert(sizeof(ChainedStruct) == sizeof(WGPUChainedStruct), + "sizeof mismatch for ChainedStruct"); +static_assert(alignof(ChainedStruct) == alignof(WGPUChainedStruct), + "alignof mismatch for ChainedStruct"); +static_assert(offsetof(ChainedStruct, nextInChain) == offsetof(WGPUChainedStruct, next), + "offsetof mismatch for ChainedStruct::nextInChain"); +static_assert(offsetof(ChainedStruct, sType) == offsetof(WGPUChainedStruct, sType), + "offsetof mismatch for ChainedStruct::sType"); + + +struct AdapterInfo { + inline AdapterInfo(); + inline ~AdapterInfo(); + AdapterInfo(const AdapterInfo&) = delete; + AdapterInfo& operator=(const AdapterInfo&) = delete; + inline AdapterInfo(AdapterInfo&&); + inline AdapterInfo& operator=(AdapterInfo&&); + inline operator const WGPUAdapterInfo&() const noexcept; + + ChainedStructOut * nextInChain = nullptr; + StringView const vendor = {}; + StringView const architecture = {}; + StringView const device = {}; + StringView const description = {}; + BackendType const backendType = BackendType::Undefined; + AdapterType const adapterType = {}; + uint32_t const vendorID = {}; + uint32_t const deviceID = {}; + uint32_t const subgroupMinSize = {}; + uint32_t const subgroupMaxSize = {}; + + private: + inline void FreeMembers(); + static inline void Reset(AdapterInfo& value); +}; + +struct BindGroupEntry { + inline operator const WGPUBindGroupEntry&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + uint32_t binding; + Buffer buffer = nullptr; + uint64_t offset = 0; + uint64_t size = kWholeSize; + Sampler sampler = nullptr; + TextureView textureView = nullptr; +}; + +struct BlendComponent { + inline operator const WGPUBlendComponent&() const noexcept; + + BlendOperation operation = BlendOperation::Undefined; + BlendFactor srcFactor = BlendFactor::Undefined; + BlendFactor dstFactor = BlendFactor::Undefined; +}; + +struct BufferBindingLayout { + inline operator const WGPUBufferBindingLayout&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + BufferBindingType type = BufferBindingType::Undefined; + Bool hasDynamicOffset = false; + uint64_t minBindingSize = 0; +}; + +struct BufferDescriptor { + inline operator const WGPUBufferDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + BufferUsage usage = BufferUsage::None; + uint64_t size; + Bool mappedAtCreation = false; +}; + +struct Color { + inline operator const WGPUColor&() const noexcept; + + double r; + double g; + double b; + double a; +}; + +struct CommandBufferDescriptor { + inline operator const WGPUCommandBufferDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; +}; + +struct CommandEncoderDescriptor { + inline operator const WGPUCommandEncoderDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; +}; + +// Can be chained in Limits +struct CompatibilityModeLimits : ChainedStructOut { + inline CompatibilityModeLimits(); + + struct Init; + inline CompatibilityModeLimits(Init&& init); + inline operator const WGPUCompatibilityModeLimits&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint32_t)); + alignas(kFirstMemberAlignment) uint32_t maxStorageBuffersInVertexStage = kLimitU32Undefined; + uint32_t maxStorageTexturesInVertexStage = kLimitU32Undefined; + uint32_t maxStorageBuffersInFragmentStage = kLimitU32Undefined; + uint32_t maxStorageTexturesInFragmentStage = kLimitU32Undefined; +}; + +struct ConstantEntry { + inline operator const WGPUConstantEntry&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView key = {}; + double value; +}; + +// Can be chained in CompilationMessage +struct DawnCompilationMessageUtf16 : ChainedStruct { + inline DawnCompilationMessageUtf16(); + + struct Init; + inline DawnCompilationMessageUtf16(Init&& init); + inline operator const WGPUDawnCompilationMessageUtf16&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint64_t)); + alignas(kFirstMemberAlignment) uint64_t linePos; + uint64_t offset; + uint64_t length; +}; + +// Can be chained in SurfaceDescriptor +struct EmscriptenSurfaceSourceCanvasHTMLSelector : ChainedStruct { + inline EmscriptenSurfaceSourceCanvasHTMLSelector(); + + struct Init; + inline EmscriptenSurfaceSourceCanvasHTMLSelector(Init&& init); + inline operator const WGPUEmscriptenSurfaceSourceCanvasHTMLSelector&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(StringView)); + alignas(kFirstMemberAlignment) StringView selector = {}; +}; + +struct Extent3D { + inline operator const WGPUExtent3D&() const noexcept; + + uint32_t width; + uint32_t height = 1; + uint32_t depthOrArrayLayers = 1; +}; + +struct Future { + inline operator const WGPUFuture&() const noexcept; + + uint64_t id; +}; + +struct InstanceLimits { + inline operator const WGPUInstanceLimits&() const noexcept; + + ChainedStructOut * nextInChain = nullptr; + size_t timedWaitAnyMaxCount = 0; +}; + +struct INTERNAL_HAVE_EMDAWNWEBGPU_HEADER { + inline operator const WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER&() const noexcept; + + Bool unused = false; +}; + +struct MultisampleState { + inline operator const WGPUMultisampleState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + uint32_t count = 1; + uint32_t mask = 0xFFFFFFFF; + Bool alphaToCoverageEnabled = false; +}; + +struct Origin3D { + inline operator const WGPUOrigin3D&() const noexcept; + + uint32_t x = 0; + uint32_t y = 0; + uint32_t z = 0; +}; + +struct PassTimestampWrites { + inline operator const WGPUPassTimestampWrites&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + QuerySet querySet = nullptr; + uint32_t beginningOfPassWriteIndex = kQuerySetIndexUndefined; + uint32_t endOfPassWriteIndex = kQuerySetIndexUndefined; +}; + +struct PipelineLayoutDescriptor { + inline operator const WGPUPipelineLayoutDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + size_t bindGroupLayoutCount; + BindGroupLayout const * bindGroupLayouts = nullptr; + uint32_t immediateSize = 0; +}; + +struct PrimitiveState { + inline operator const WGPUPrimitiveState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + PrimitiveTopology topology = PrimitiveTopology::Undefined; + IndexFormat stripIndexFormat = IndexFormat::Undefined; + FrontFace frontFace = FrontFace::Undefined; + CullMode cullMode = CullMode::Undefined; + Bool unclippedDepth = false; +}; + +struct QuerySetDescriptor { + inline operator const WGPUQuerySetDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + QueryType type = {}; + uint32_t count; +}; + +struct QueueDescriptor { + inline operator const WGPUQueueDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; +}; + +struct RenderBundleDescriptor { + inline operator const WGPURenderBundleDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; +}; + +struct RenderBundleEncoderDescriptor { + inline operator const WGPURenderBundleEncoderDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + size_t colorFormatCount; + TextureFormat const * colorFormats = nullptr; + TextureFormat depthStencilFormat = TextureFormat::Undefined; + uint32_t sampleCount = 1; + Bool depthReadOnly = false; + Bool stencilReadOnly = false; +}; + +struct RenderPassDepthStencilAttachment { + inline operator const WGPURenderPassDepthStencilAttachment&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + TextureView view = nullptr; + LoadOp depthLoadOp = LoadOp::Undefined; + StoreOp depthStoreOp = StoreOp::Undefined; + float depthClearValue = kDepthClearValueUndefined; + Bool depthReadOnly = false; + LoadOp stencilLoadOp = LoadOp::Undefined; + StoreOp stencilStoreOp = StoreOp::Undefined; + uint32_t stencilClearValue = 0; + Bool stencilReadOnly = false; +}; + +// Can be chained in RenderPassDescriptor +struct RenderPassMaxDrawCount : ChainedStruct { + inline RenderPassMaxDrawCount(); + + struct Init; + inline RenderPassMaxDrawCount(Init&& init); + inline operator const WGPURenderPassMaxDrawCount&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint64_t)); + alignas(kFirstMemberAlignment) uint64_t maxDrawCount = 50000000; +}; + +// Can be chained in RequestAdapterOptions +struct RequestAdapterWebXROptions : ChainedStruct { + inline RequestAdapterWebXROptions(); + + struct Init; + inline RequestAdapterWebXROptions(Init&& init); + inline operator const WGPURequestAdapterWebXROptions&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(Bool)); + alignas(kFirstMemberAlignment) Bool xrCompatible; +}; + +struct SamplerBindingLayout { + inline operator const WGPUSamplerBindingLayout&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + SamplerBindingType type = SamplerBindingType::Undefined; +}; + +struct SamplerDescriptor { + inline operator const WGPUSamplerDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + AddressMode addressModeU = AddressMode::Undefined; + AddressMode addressModeV = AddressMode::Undefined; + AddressMode addressModeW = AddressMode::Undefined; + FilterMode magFilter = FilterMode::Undefined; + FilterMode minFilter = FilterMode::Undefined; + MipmapFilterMode mipmapFilter = MipmapFilterMode::Undefined; + float lodMinClamp = 0.f; + float lodMaxClamp = 32.f; + CompareFunction compare = CompareFunction::Undefined; + uint16_t maxAnisotropy = 1; +}; + +// Can be chained in ShaderModuleDescriptor +struct ShaderSourceSPIRV : ChainedStruct { + inline ShaderSourceSPIRV(); + + struct Init; + inline ShaderSourceSPIRV(Init&& init); + inline operator const WGPUShaderSourceSPIRV&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(uint32_t)); + alignas(kFirstMemberAlignment) uint32_t codeSize; + uint32_t const * code = nullptr; +}; + +// Can be chained in ShaderModuleDescriptor +struct ShaderSourceWGSL : ChainedStruct { + inline ShaderSourceWGSL(); + + struct Init; + inline ShaderSourceWGSL(Init&& init); + inline operator const WGPUShaderSourceWGSL&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(StringView)); + alignas(kFirstMemberAlignment) StringView code = {}; +}; + +struct StencilFaceState { + inline operator const WGPUStencilFaceState&() const noexcept; + + CompareFunction compare = CompareFunction::Undefined; + StencilOperation failOp = StencilOperation::Undefined; + StencilOperation depthFailOp = StencilOperation::Undefined; + StencilOperation passOp = StencilOperation::Undefined; +}; + +struct StorageTextureBindingLayout { + inline operator const WGPUStorageTextureBindingLayout&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StorageTextureAccess access = StorageTextureAccess::Undefined; + TextureFormat format = TextureFormat::Undefined; + TextureViewDimension viewDimension = TextureViewDimension::Undefined; +}; + +struct SupportedFeatures { + inline SupportedFeatures(); + inline ~SupportedFeatures(); + SupportedFeatures(const SupportedFeatures&) = delete; + SupportedFeatures& operator=(const SupportedFeatures&) = delete; + inline SupportedFeatures(SupportedFeatures&&); + inline SupportedFeatures& operator=(SupportedFeatures&&); + inline operator const WGPUSupportedFeatures&() const noexcept; + + size_t const featureCount = {}; + FeatureName const * const features = nullptr; + + private: + inline void FreeMembers(); + static inline void Reset(SupportedFeatures& value); +}; + +struct SupportedInstanceFeatures { + inline SupportedInstanceFeatures(); + inline ~SupportedInstanceFeatures(); + SupportedInstanceFeatures(const SupportedInstanceFeatures&) = delete; + SupportedInstanceFeatures& operator=(const SupportedInstanceFeatures&) = delete; + inline SupportedInstanceFeatures(SupportedInstanceFeatures&&); + inline SupportedInstanceFeatures& operator=(SupportedInstanceFeatures&&); + inline operator const WGPUSupportedInstanceFeatures&() const noexcept; + + size_t const featureCount = {}; + InstanceFeatureName const * const features = nullptr; + + private: + inline void FreeMembers(); + static inline void Reset(SupportedInstanceFeatures& value); +}; + +struct SupportedWGSLLanguageFeatures { + inline SupportedWGSLLanguageFeatures(); + inline ~SupportedWGSLLanguageFeatures(); + SupportedWGSLLanguageFeatures(const SupportedWGSLLanguageFeatures&) = delete; + SupportedWGSLLanguageFeatures& operator=(const SupportedWGSLLanguageFeatures&) = delete; + inline SupportedWGSLLanguageFeatures(SupportedWGSLLanguageFeatures&&); + inline SupportedWGSLLanguageFeatures& operator=(SupportedWGSLLanguageFeatures&&); + inline operator const WGPUSupportedWGSLLanguageFeatures&() const noexcept; + + size_t const featureCount = {}; + WGSLLanguageFeatureName const * const features = nullptr; + + private: + inline void FreeMembers(); + static inline void Reset(SupportedWGSLLanguageFeatures& value); +}; + +struct SurfaceCapabilities { + inline SurfaceCapabilities(); + inline ~SurfaceCapabilities(); + SurfaceCapabilities(const SurfaceCapabilities&) = delete; + SurfaceCapabilities& operator=(const SurfaceCapabilities&) = delete; + inline SurfaceCapabilities(SurfaceCapabilities&&); + inline SurfaceCapabilities& operator=(SurfaceCapabilities&&); + inline operator const WGPUSurfaceCapabilities&() const noexcept; + + ChainedStructOut * nextInChain = nullptr; + TextureUsage const usages = TextureUsage::None; + size_t const formatCount = {}; + TextureFormat const * const formats = nullptr; + size_t const presentModeCount = {}; + PresentMode const * const presentModes = nullptr; + size_t const alphaModeCount = {}; + CompositeAlphaMode const * const alphaModes = nullptr; + + private: + inline void FreeMembers(); + static inline void Reset(SurfaceCapabilities& value); +}; + +// Can be chained in SurfaceDescriptor +struct SurfaceColorManagement : ChainedStruct { + inline SurfaceColorManagement(); + + struct Init; + inline SurfaceColorManagement(Init&& init); + inline operator const WGPUSurfaceColorManagement&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(PredefinedColorSpace)); + alignas(kFirstMemberAlignment) PredefinedColorSpace colorSpace = {}; + ToneMappingMode toneMappingMode = {}; +}; + +struct SurfaceConfiguration { + inline operator const WGPUSurfaceConfiguration&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + Device device = nullptr; + TextureFormat format = TextureFormat::Undefined; + TextureUsage usage = TextureUsage::RenderAttachment; + uint32_t width; + uint32_t height; + size_t viewFormatCount = 0; + TextureFormat const * viewFormats = nullptr; + CompositeAlphaMode alphaMode = CompositeAlphaMode::Auto; + PresentMode presentMode = PresentMode::Undefined; +}; + +struct SurfaceTexture { + inline operator const WGPUSurfaceTexture&() const noexcept; + + ChainedStructOut * nextInChain = nullptr; + Texture texture = nullptr; + SurfaceGetCurrentTextureStatus status = {}; +}; + +struct TexelCopyBufferLayout { + inline operator const WGPUTexelCopyBufferLayout&() const noexcept; + + uint64_t offset = 0; + uint32_t bytesPerRow = kCopyStrideUndefined; + uint32_t rowsPerImage = kCopyStrideUndefined; +}; + +struct TextureBindingLayout { + inline operator const WGPUTextureBindingLayout&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + TextureSampleType sampleType = TextureSampleType::Undefined; + TextureViewDimension viewDimension = TextureViewDimension::Undefined; + Bool multisampled = false; +}; + +// Can be chained in TextureDescriptor +struct TextureBindingViewDimensionDescriptor : ChainedStruct { + inline TextureBindingViewDimensionDescriptor(); + + struct Init; + inline TextureBindingViewDimensionDescriptor(Init&& init); + inline operator const WGPUTextureBindingViewDimensionDescriptor&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(TextureViewDimension)); + alignas(kFirstMemberAlignment) TextureViewDimension textureBindingViewDimension = TextureViewDimension::Undefined; +}; + +struct TextureComponentSwizzle { + inline operator const WGPUTextureComponentSwizzle&() const noexcept; + + ComponentSwizzle r = ComponentSwizzle::Undefined; + ComponentSwizzle g = ComponentSwizzle::Undefined; + ComponentSwizzle b = ComponentSwizzle::Undefined; + ComponentSwizzle a = ComponentSwizzle::Undefined; +}; + +struct VertexAttribute { + inline operator const WGPUVertexAttribute&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + VertexFormat format = {}; + uint64_t offset; + uint32_t shaderLocation; +}; + +struct BindGroupDescriptor { + inline operator const WGPUBindGroupDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + BindGroupLayout layout = nullptr; + size_t entryCount = 0; + BindGroupEntry const * entries = nullptr; +}; + +struct BindGroupLayoutEntry { + inline operator const WGPUBindGroupLayoutEntry&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + uint32_t binding; + ShaderStage visibility = ShaderStage::None; + uint32_t bindingArraySize = 0; + BufferBindingLayout buffer = { nullptr, BufferBindingType::BindingNotUsed, false, 0 }; + SamplerBindingLayout sampler = { nullptr, SamplerBindingType::BindingNotUsed }; + TextureBindingLayout texture = { nullptr, TextureSampleType::BindingNotUsed, TextureViewDimension::e2D, false }; + StorageTextureBindingLayout storageTexture = { nullptr, StorageTextureAccess::BindingNotUsed, TextureFormat::Undefined, TextureViewDimension::e2D }; +}; + +struct BlendState { + inline operator const WGPUBlendState&() const noexcept; + + BlendComponent color = {}; + BlendComponent alpha = {}; +}; + +struct CompilationMessage { + inline operator const WGPUCompilationMessage&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView message = {}; + CompilationMessageType type = {}; + uint64_t lineNum; + uint64_t linePos; + uint64_t offset; + uint64_t length; +}; + +struct ComputePassDescriptor { + inline operator const WGPUComputePassDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + PassTimestampWrites const * timestampWrites = nullptr; +}; + +struct ComputeState { + inline operator const WGPUComputeState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + ShaderModule module = nullptr; + StringView entryPoint = {}; + size_t constantCount = 0; + ConstantEntry const * constants = nullptr; +}; + +struct DepthStencilState { + inline operator const WGPUDepthStencilState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + TextureFormat format = TextureFormat::Undefined; + OptionalBool depthWriteEnabled = OptionalBool::Undefined; + CompareFunction depthCompare = CompareFunction::Undefined; + StencilFaceState stencilFront = {}; + StencilFaceState stencilBack = {}; + uint32_t stencilReadMask = 0xFFFFFFFF; + uint32_t stencilWriteMask = 0xFFFFFFFF; + int32_t depthBias = 0; + float depthBiasSlopeScale = 0.f; + float depthBiasClamp = 0.f; +}; + +struct FutureWaitInfo { + inline operator const WGPUFutureWaitInfo&() const noexcept; + + Future future = {}; + Bool completed = false; +}; + +struct InstanceDescriptor { + inline operator const WGPUInstanceDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + size_t requiredFeatureCount = 0; + InstanceFeatureName const * requiredFeatures = nullptr; + InstanceLimits const * requiredLimits = nullptr; +}; + +struct Limits { + inline operator const WGPULimits&() const noexcept; + + ChainedStructOut * nextInChain = nullptr; + uint32_t maxTextureDimension1D = kLimitU32Undefined; + uint32_t maxTextureDimension2D = kLimitU32Undefined; + uint32_t maxTextureDimension3D = kLimitU32Undefined; + uint32_t maxTextureArrayLayers = kLimitU32Undefined; + uint32_t maxBindGroups = kLimitU32Undefined; + uint32_t maxBindGroupsPlusVertexBuffers = kLimitU32Undefined; + uint32_t maxBindingsPerBindGroup = kLimitU32Undefined; + uint32_t maxDynamicUniformBuffersPerPipelineLayout = kLimitU32Undefined; + uint32_t maxDynamicStorageBuffersPerPipelineLayout = kLimitU32Undefined; + uint32_t maxSampledTexturesPerShaderStage = kLimitU32Undefined; + uint32_t maxSamplersPerShaderStage = kLimitU32Undefined; + uint32_t maxStorageBuffersPerShaderStage = kLimitU32Undefined; + uint32_t maxStorageTexturesPerShaderStage = kLimitU32Undefined; + uint32_t maxUniformBuffersPerShaderStage = kLimitU32Undefined; + uint64_t maxUniformBufferBindingSize = kLimitU64Undefined; + uint64_t maxStorageBufferBindingSize = kLimitU64Undefined; + uint32_t minUniformBufferOffsetAlignment = kLimitU32Undefined; + uint32_t minStorageBufferOffsetAlignment = kLimitU32Undefined; + uint32_t maxVertexBuffers = kLimitU32Undefined; + uint64_t maxBufferSize = kLimitU64Undefined; + uint32_t maxVertexAttributes = kLimitU32Undefined; + uint32_t maxVertexBufferArrayStride = kLimitU32Undefined; + uint32_t maxInterStageShaderVariables = kLimitU32Undefined; + uint32_t maxColorAttachments = kLimitU32Undefined; + uint32_t maxColorAttachmentBytesPerSample = kLimitU32Undefined; + uint32_t maxComputeWorkgroupStorageSize = kLimitU32Undefined; + uint32_t maxComputeInvocationsPerWorkgroup = kLimitU32Undefined; + uint32_t maxComputeWorkgroupSizeX = kLimitU32Undefined; + uint32_t maxComputeWorkgroupSizeY = kLimitU32Undefined; + uint32_t maxComputeWorkgroupSizeZ = kLimitU32Undefined; + uint32_t maxComputeWorkgroupsPerDimension = kLimitU32Undefined; + uint32_t maxImmediateSize = kLimitU32Undefined; +}; + +struct RenderPassColorAttachment { + inline operator const WGPURenderPassColorAttachment&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + TextureView view = nullptr; + uint32_t depthSlice = kDepthSliceUndefined; + TextureView resolveTarget = nullptr; + LoadOp loadOp = LoadOp::Undefined; + StoreOp storeOp = StoreOp::Undefined; + Color clearValue = {}; +}; + +struct RequestAdapterOptions { + inline operator const WGPURequestAdapterOptions&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + FeatureLevel featureLevel = FeatureLevel::Undefined; + PowerPreference powerPreference = PowerPreference::Undefined; + Bool forceFallbackAdapter = false; + BackendType backendType = BackendType::Undefined; + Surface compatibleSurface = nullptr; +}; + +struct ShaderModuleDescriptor { + inline operator const WGPUShaderModuleDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; +}; + +struct SurfaceDescriptor { + inline operator const WGPUSurfaceDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; +}; + +struct TexelCopyBufferInfo { + inline operator const WGPUTexelCopyBufferInfo&() const noexcept; + + TexelCopyBufferLayout layout = {}; + Buffer buffer = nullptr; +}; + +struct TexelCopyTextureInfo { + inline operator const WGPUTexelCopyTextureInfo&() const noexcept; + + Texture texture = nullptr; + uint32_t mipLevel = 0; + Origin3D origin = {}; + TextureAspect aspect = TextureAspect::Undefined; +}; + +// Can be chained in TextureViewDescriptor +struct TextureComponentSwizzleDescriptor : ChainedStruct { + inline TextureComponentSwizzleDescriptor(); + + struct Init; + inline TextureComponentSwizzleDescriptor(Init&& init); + inline operator const WGPUTextureComponentSwizzleDescriptor&() const noexcept; + + static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct), alignof(TextureComponentSwizzle)); + alignas(kFirstMemberAlignment) TextureComponentSwizzle swizzle = {}; +}; + +struct TextureDescriptor { + inline operator const WGPUTextureDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + TextureUsage usage = TextureUsage::None; + TextureDimension dimension = TextureDimension::Undefined; + Extent3D size = {}; + TextureFormat format = TextureFormat::Undefined; + uint32_t mipLevelCount = 1; + uint32_t sampleCount = 1; + size_t viewFormatCount = 0; + TextureFormat const * viewFormats = nullptr; +}; + +struct VertexBufferLayout { + inline operator const WGPUVertexBufferLayout&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + VertexStepMode stepMode = VertexStepMode::Undefined; + uint64_t arrayStride; + size_t attributeCount; + VertexAttribute const * attributes = nullptr; +}; + +struct BindGroupLayoutDescriptor { + inline operator const WGPUBindGroupLayoutDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + size_t entryCount = 0; + BindGroupLayoutEntry const * entries = nullptr; +}; + +struct ColorTargetState { + inline operator const WGPUColorTargetState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + TextureFormat format = TextureFormat::Undefined; + BlendState const * blend = nullptr; + ColorWriteMask writeMask = ColorWriteMask::All; +}; + +struct CompilationInfo { + inline operator const WGPUCompilationInfo&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + size_t messageCount; + CompilationMessage const * messages = nullptr; +}; + +struct ComputePipelineDescriptor { + inline operator const WGPUComputePipelineDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + PipelineLayout layout = nullptr; + ComputeState compute = {}; +}; + +struct RenderPassDescriptor { + inline operator const WGPURenderPassDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + size_t colorAttachmentCount; + RenderPassColorAttachment const * colorAttachments = nullptr; + RenderPassDepthStencilAttachment const * depthStencilAttachment = nullptr; + QuerySet occlusionQuerySet = nullptr; + PassTimestampWrites const * timestampWrites = nullptr; +}; + +struct TextureViewDescriptor { + inline operator const WGPUTextureViewDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + TextureFormat format = TextureFormat::Undefined; + TextureViewDimension dimension = TextureViewDimension::Undefined; + uint32_t baseMipLevel = 0; + uint32_t mipLevelCount = kMipLevelCountUndefined; + uint32_t baseArrayLayer = 0; + uint32_t arrayLayerCount = kArrayLayerCountUndefined; + TextureAspect aspect = TextureAspect::Undefined; + TextureUsage usage = TextureUsage::None; +}; + +struct VertexState { + inline operator const WGPUVertexState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + ShaderModule module = nullptr; + StringView entryPoint = {}; + size_t constantCount = 0; + ConstantEntry const * constants = nullptr; + size_t bufferCount = 0; + VertexBufferLayout const * buffers = nullptr; +}; + +struct FragmentState { + inline operator const WGPUFragmentState&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + ShaderModule module = nullptr; + StringView entryPoint = {}; + size_t constantCount = 0; + ConstantEntry const * constants = nullptr; + size_t targetCount; + ColorTargetState const * targets = nullptr; +}; + +struct RenderPipelineDescriptor { + inline operator const WGPURenderPipelineDescriptor&() const noexcept; + + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + PipelineLayout layout = nullptr; + VertexState vertex = {}; + PrimitiveState primitive = {}; + DepthStencilState const * depthStencil = nullptr; + MultisampleState multisample = {}; + FragmentState const * fragment = nullptr; +}; + + +namespace detail { +struct DeviceDescriptor { + ChainedStruct const * nextInChain = nullptr; + StringView label = {}; + size_t requiredFeatureCount = 0; + FeatureName const * requiredFeatures = nullptr; + Limits const * requiredLimits = nullptr; + QueueDescriptor defaultQueue = {}; + WGPUDeviceLostCallbackInfo deviceLostCallbackInfo = WGPU_DEVICE_LOST_CALLBACK_INFO_INIT; + WGPUUncapturedErrorCallbackInfo uncapturedErrorCallbackInfo = WGPU_UNCAPTURED_ERROR_CALLBACK_INFO_INIT; +}; +} // namespace detail +struct DeviceDescriptor : protected detail::DeviceDescriptor { + inline operator const WGPUDeviceDescriptor&() const noexcept; + + using detail::DeviceDescriptor::nextInChain; + using detail::DeviceDescriptor::label; + using detail::DeviceDescriptor::requiredFeatureCount; + using detail::DeviceDescriptor::requiredFeatures; + using detail::DeviceDescriptor::requiredLimits; + using detail::DeviceDescriptor::defaultQueue; + + inline DeviceDescriptor(); + struct Init; + inline DeviceDescriptor(Init&& init); + + template , + typename = std::enable_if_t>> + void SetDeviceLostCallback(CallbackMode callbackMode, F callback, T userdata); + template , + typename = std::enable_if_t>> + void SetDeviceLostCallback(CallbackMode callbackMode, L callback); + + template , + typename = std::enable_if_t>> + void SetUncapturedErrorCallback(F callback, T userdata); + template , + typename = std::enable_if_t>> + void SetUncapturedErrorCallback(L callback); +}; + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +// error: 'offsetof' within non-standard-layout type 'wgpu::XXX' is conditionally-supported +#pragma GCC diagnostic ignored "-Winvalid-offsetof" +#endif + +// AdapterInfo implementation +AdapterInfo::AdapterInfo() = default; +AdapterInfo::~AdapterInfo() { + FreeMembers(); +} + +AdapterInfo::AdapterInfo(AdapterInfo&& rhs) + : vendor(rhs.vendor), + architecture(rhs.architecture), + device(rhs.device), + description(rhs.description), + backendType(rhs.backendType), + adapterType(rhs.adapterType), + vendorID(rhs.vendorID), + deviceID(rhs.deviceID), + subgroupMinSize(rhs.subgroupMinSize), + subgroupMaxSize(rhs.subgroupMaxSize){ + Reset(rhs); +} + +AdapterInfo& AdapterInfo::operator=(AdapterInfo&& rhs) { + if (&rhs == this) { + return *this; + } + FreeMembers(); + detail::AsNonConstReference(this->vendor) = std::move(rhs.vendor); + detail::AsNonConstReference(this->architecture) = std::move(rhs.architecture); + detail::AsNonConstReference(this->device) = std::move(rhs.device); + detail::AsNonConstReference(this->description) = std::move(rhs.description); + detail::AsNonConstReference(this->backendType) = std::move(rhs.backendType); + detail::AsNonConstReference(this->adapterType) = std::move(rhs.adapterType); + detail::AsNonConstReference(this->vendorID) = std::move(rhs.vendorID); + detail::AsNonConstReference(this->deviceID) = std::move(rhs.deviceID); + detail::AsNonConstReference(this->subgroupMinSize) = std::move(rhs.subgroupMinSize); + detail::AsNonConstReference(this->subgroupMaxSize) = std::move(rhs.subgroupMaxSize); + Reset(rhs); + return *this; +} + +void AdapterInfo::FreeMembers() { + bool needsFreeing = false; if (this->vendor.data != nullptr) { needsFreeing = true; } if (this->architecture.data != nullptr) { needsFreeing = true; } if (this->device.data != nullptr) { needsFreeing = true; } if (this->description.data != nullptr) { needsFreeing = true; }if (needsFreeing) { + wgpuAdapterInfoFreeMembers( + *reinterpret_cast(this)); + } +} + +// static +void AdapterInfo::Reset(AdapterInfo& value) { + AdapterInfo defaultValue{}; + detail::AsNonConstReference(value.vendor) = defaultValue.vendor; + detail::AsNonConstReference(value.architecture) = defaultValue.architecture; + detail::AsNonConstReference(value.device) = defaultValue.device; + detail::AsNonConstReference(value.description) = defaultValue.description; + detail::AsNonConstReference(value.backendType) = defaultValue.backendType; + detail::AsNonConstReference(value.adapterType) = defaultValue.adapterType; + detail::AsNonConstReference(value.vendorID) = defaultValue.vendorID; + detail::AsNonConstReference(value.deviceID) = defaultValue.deviceID; + detail::AsNonConstReference(value.subgroupMinSize) = defaultValue.subgroupMinSize; + detail::AsNonConstReference(value.subgroupMaxSize) = defaultValue.subgroupMaxSize; +} + +AdapterInfo::operator const WGPUAdapterInfo&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(AdapterInfo) == sizeof(WGPUAdapterInfo), "sizeof mismatch for AdapterInfo"); +static_assert(alignof(AdapterInfo) == alignof(WGPUAdapterInfo), "alignof mismatch for AdapterInfo"); +static_assert(offsetof(AdapterInfo, nextInChain) == offsetof(WGPUAdapterInfo, nextInChain), + "offsetof mismatch for AdapterInfo::nextInChain"); +static_assert(offsetof(AdapterInfo, vendor) == offsetof(WGPUAdapterInfo, vendor), + "offsetof mismatch for AdapterInfo::vendor"); +static_assert(offsetof(AdapterInfo, architecture) == offsetof(WGPUAdapterInfo, architecture), + "offsetof mismatch for AdapterInfo::architecture"); +static_assert(offsetof(AdapterInfo, device) == offsetof(WGPUAdapterInfo, device), + "offsetof mismatch for AdapterInfo::device"); +static_assert(offsetof(AdapterInfo, description) == offsetof(WGPUAdapterInfo, description), + "offsetof mismatch for AdapterInfo::description"); +static_assert(offsetof(AdapterInfo, backendType) == offsetof(WGPUAdapterInfo, backendType), + "offsetof mismatch for AdapterInfo::backendType"); +static_assert(offsetof(AdapterInfo, adapterType) == offsetof(WGPUAdapterInfo, adapterType), + "offsetof mismatch for AdapterInfo::adapterType"); +static_assert(offsetof(AdapterInfo, vendorID) == offsetof(WGPUAdapterInfo, vendorID), + "offsetof mismatch for AdapterInfo::vendorID"); +static_assert(offsetof(AdapterInfo, deviceID) == offsetof(WGPUAdapterInfo, deviceID), + "offsetof mismatch for AdapterInfo::deviceID"); +static_assert(offsetof(AdapterInfo, subgroupMinSize) == offsetof(WGPUAdapterInfo, subgroupMinSize), + "offsetof mismatch for AdapterInfo::subgroupMinSize"); +static_assert(offsetof(AdapterInfo, subgroupMaxSize) == offsetof(WGPUAdapterInfo, subgroupMaxSize), + "offsetof mismatch for AdapterInfo::subgroupMaxSize"); + +// BindGroupEntry implementation + +BindGroupEntry::operator const WGPUBindGroupEntry&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BindGroupEntry) == sizeof(WGPUBindGroupEntry), "sizeof mismatch for BindGroupEntry"); +static_assert(alignof(BindGroupEntry) == alignof(WGPUBindGroupEntry), "alignof mismatch for BindGroupEntry"); +static_assert(offsetof(BindGroupEntry, nextInChain) == offsetof(WGPUBindGroupEntry, nextInChain), + "offsetof mismatch for BindGroupEntry::nextInChain"); +static_assert(offsetof(BindGroupEntry, binding) == offsetof(WGPUBindGroupEntry, binding), + "offsetof mismatch for BindGroupEntry::binding"); +static_assert(offsetof(BindGroupEntry, buffer) == offsetof(WGPUBindGroupEntry, buffer), + "offsetof mismatch for BindGroupEntry::buffer"); +static_assert(offsetof(BindGroupEntry, offset) == offsetof(WGPUBindGroupEntry, offset), + "offsetof mismatch for BindGroupEntry::offset"); +static_assert(offsetof(BindGroupEntry, size) == offsetof(WGPUBindGroupEntry, size), + "offsetof mismatch for BindGroupEntry::size"); +static_assert(offsetof(BindGroupEntry, sampler) == offsetof(WGPUBindGroupEntry, sampler), + "offsetof mismatch for BindGroupEntry::sampler"); +static_assert(offsetof(BindGroupEntry, textureView) == offsetof(WGPUBindGroupEntry, textureView), + "offsetof mismatch for BindGroupEntry::textureView"); + +// BlendComponent implementation + +BlendComponent::operator const WGPUBlendComponent&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BlendComponent) == sizeof(WGPUBlendComponent), "sizeof mismatch for BlendComponent"); +static_assert(alignof(BlendComponent) == alignof(WGPUBlendComponent), "alignof mismatch for BlendComponent"); +static_assert(offsetof(BlendComponent, operation) == offsetof(WGPUBlendComponent, operation), + "offsetof mismatch for BlendComponent::operation"); +static_assert(offsetof(BlendComponent, srcFactor) == offsetof(WGPUBlendComponent, srcFactor), + "offsetof mismatch for BlendComponent::srcFactor"); +static_assert(offsetof(BlendComponent, dstFactor) == offsetof(WGPUBlendComponent, dstFactor), + "offsetof mismatch for BlendComponent::dstFactor"); + +// BufferBindingLayout implementation + +BufferBindingLayout::operator const WGPUBufferBindingLayout&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BufferBindingLayout) == sizeof(WGPUBufferBindingLayout), "sizeof mismatch for BufferBindingLayout"); +static_assert(alignof(BufferBindingLayout) == alignof(WGPUBufferBindingLayout), "alignof mismatch for BufferBindingLayout"); +static_assert(offsetof(BufferBindingLayout, nextInChain) == offsetof(WGPUBufferBindingLayout, nextInChain), + "offsetof mismatch for BufferBindingLayout::nextInChain"); +static_assert(offsetof(BufferBindingLayout, type) == offsetof(WGPUBufferBindingLayout, type), + "offsetof mismatch for BufferBindingLayout::type"); +static_assert(offsetof(BufferBindingLayout, hasDynamicOffset) == offsetof(WGPUBufferBindingLayout, hasDynamicOffset), + "offsetof mismatch for BufferBindingLayout::hasDynamicOffset"); +static_assert(offsetof(BufferBindingLayout, minBindingSize) == offsetof(WGPUBufferBindingLayout, minBindingSize), + "offsetof mismatch for BufferBindingLayout::minBindingSize"); + +// BufferDescriptor implementation + +BufferDescriptor::operator const WGPUBufferDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BufferDescriptor) == sizeof(WGPUBufferDescriptor), "sizeof mismatch for BufferDescriptor"); +static_assert(alignof(BufferDescriptor) == alignof(WGPUBufferDescriptor), "alignof mismatch for BufferDescriptor"); +static_assert(offsetof(BufferDescriptor, nextInChain) == offsetof(WGPUBufferDescriptor, nextInChain), + "offsetof mismatch for BufferDescriptor::nextInChain"); +static_assert(offsetof(BufferDescriptor, label) == offsetof(WGPUBufferDescriptor, label), + "offsetof mismatch for BufferDescriptor::label"); +static_assert(offsetof(BufferDescriptor, usage) == offsetof(WGPUBufferDescriptor, usage), + "offsetof mismatch for BufferDescriptor::usage"); +static_assert(offsetof(BufferDescriptor, size) == offsetof(WGPUBufferDescriptor, size), + "offsetof mismatch for BufferDescriptor::size"); +static_assert(offsetof(BufferDescriptor, mappedAtCreation) == offsetof(WGPUBufferDescriptor, mappedAtCreation), + "offsetof mismatch for BufferDescriptor::mappedAtCreation"); + +// Color implementation + +Color::operator const WGPUColor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(Color) == sizeof(WGPUColor), "sizeof mismatch for Color"); +static_assert(alignof(Color) == alignof(WGPUColor), "alignof mismatch for Color"); +static_assert(offsetof(Color, r) == offsetof(WGPUColor, r), + "offsetof mismatch for Color::r"); +static_assert(offsetof(Color, g) == offsetof(WGPUColor, g), + "offsetof mismatch for Color::g"); +static_assert(offsetof(Color, b) == offsetof(WGPUColor, b), + "offsetof mismatch for Color::b"); +static_assert(offsetof(Color, a) == offsetof(WGPUColor, a), + "offsetof mismatch for Color::a"); + +// CommandBufferDescriptor implementation + +CommandBufferDescriptor::operator const WGPUCommandBufferDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(CommandBufferDescriptor) == sizeof(WGPUCommandBufferDescriptor), "sizeof mismatch for CommandBufferDescriptor"); +static_assert(alignof(CommandBufferDescriptor) == alignof(WGPUCommandBufferDescriptor), "alignof mismatch for CommandBufferDescriptor"); +static_assert(offsetof(CommandBufferDescriptor, nextInChain) == offsetof(WGPUCommandBufferDescriptor, nextInChain), + "offsetof mismatch for CommandBufferDescriptor::nextInChain"); +static_assert(offsetof(CommandBufferDescriptor, label) == offsetof(WGPUCommandBufferDescriptor, label), + "offsetof mismatch for CommandBufferDescriptor::label"); + +// CommandEncoderDescriptor implementation + +CommandEncoderDescriptor::operator const WGPUCommandEncoderDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(CommandEncoderDescriptor) == sizeof(WGPUCommandEncoderDescriptor), "sizeof mismatch for CommandEncoderDescriptor"); +static_assert(alignof(CommandEncoderDescriptor) == alignof(WGPUCommandEncoderDescriptor), "alignof mismatch for CommandEncoderDescriptor"); +static_assert(offsetof(CommandEncoderDescriptor, nextInChain) == offsetof(WGPUCommandEncoderDescriptor, nextInChain), + "offsetof mismatch for CommandEncoderDescriptor::nextInChain"); +static_assert(offsetof(CommandEncoderDescriptor, label) == offsetof(WGPUCommandEncoderDescriptor, label), + "offsetof mismatch for CommandEncoderDescriptor::label"); + +// CompatibilityModeLimits implementation +CompatibilityModeLimits::CompatibilityModeLimits() + : ChainedStructOut { nullptr, SType::CompatibilityModeLimits } {} +struct CompatibilityModeLimits::Init { + ChainedStructOut * nextInChain; + uint32_t maxStorageBuffersInVertexStage = kLimitU32Undefined; + uint32_t maxStorageTexturesInVertexStage = kLimitU32Undefined; + uint32_t maxStorageBuffersInFragmentStage = kLimitU32Undefined; + uint32_t maxStorageTexturesInFragmentStage = kLimitU32Undefined; +}; +CompatibilityModeLimits::CompatibilityModeLimits(CompatibilityModeLimits::Init&& init) + : ChainedStructOut { init.nextInChain, SType::CompatibilityModeLimits }, + maxStorageBuffersInVertexStage(std::move(init.maxStorageBuffersInVertexStage)), + maxStorageTexturesInVertexStage(std::move(init.maxStorageTexturesInVertexStage)), + maxStorageBuffersInFragmentStage(std::move(init.maxStorageBuffersInFragmentStage)), + maxStorageTexturesInFragmentStage(std::move(init.maxStorageTexturesInFragmentStage)){} + +CompatibilityModeLimits::operator const WGPUCompatibilityModeLimits&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(CompatibilityModeLimits) == sizeof(WGPUCompatibilityModeLimits), "sizeof mismatch for CompatibilityModeLimits"); +static_assert(alignof(CompatibilityModeLimits) == alignof(WGPUCompatibilityModeLimits), "alignof mismatch for CompatibilityModeLimits"); +static_assert(offsetof(CompatibilityModeLimits, maxStorageBuffersInVertexStage) == offsetof(WGPUCompatibilityModeLimits, maxStorageBuffersInVertexStage), + "offsetof mismatch for CompatibilityModeLimits::maxStorageBuffersInVertexStage"); +static_assert(offsetof(CompatibilityModeLimits, maxStorageTexturesInVertexStage) == offsetof(WGPUCompatibilityModeLimits, maxStorageTexturesInVertexStage), + "offsetof mismatch for CompatibilityModeLimits::maxStorageTexturesInVertexStage"); +static_assert(offsetof(CompatibilityModeLimits, maxStorageBuffersInFragmentStage) == offsetof(WGPUCompatibilityModeLimits, maxStorageBuffersInFragmentStage), + "offsetof mismatch for CompatibilityModeLimits::maxStorageBuffersInFragmentStage"); +static_assert(offsetof(CompatibilityModeLimits, maxStorageTexturesInFragmentStage) == offsetof(WGPUCompatibilityModeLimits, maxStorageTexturesInFragmentStage), + "offsetof mismatch for CompatibilityModeLimits::maxStorageTexturesInFragmentStage"); + +// ConstantEntry implementation + +ConstantEntry::operator const WGPUConstantEntry&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ConstantEntry) == sizeof(WGPUConstantEntry), "sizeof mismatch for ConstantEntry"); +static_assert(alignof(ConstantEntry) == alignof(WGPUConstantEntry), "alignof mismatch for ConstantEntry"); +static_assert(offsetof(ConstantEntry, nextInChain) == offsetof(WGPUConstantEntry, nextInChain), + "offsetof mismatch for ConstantEntry::nextInChain"); +static_assert(offsetof(ConstantEntry, key) == offsetof(WGPUConstantEntry, key), + "offsetof mismatch for ConstantEntry::key"); +static_assert(offsetof(ConstantEntry, value) == offsetof(WGPUConstantEntry, value), + "offsetof mismatch for ConstantEntry::value"); + +// DawnCompilationMessageUtf16 implementation +DawnCompilationMessageUtf16::DawnCompilationMessageUtf16() + : ChainedStruct { nullptr, SType::DawnCompilationMessageUtf16 } {} +struct DawnCompilationMessageUtf16::Init { + ChainedStruct * const nextInChain; + uint64_t linePos; + uint64_t offset; + uint64_t length; +}; +DawnCompilationMessageUtf16::DawnCompilationMessageUtf16(DawnCompilationMessageUtf16::Init&& init) + : ChainedStruct { init.nextInChain, SType::DawnCompilationMessageUtf16 }, + linePos(std::move(init.linePos)), + offset(std::move(init.offset)), + length(std::move(init.length)){} + +DawnCompilationMessageUtf16::operator const WGPUDawnCompilationMessageUtf16&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(DawnCompilationMessageUtf16) == sizeof(WGPUDawnCompilationMessageUtf16), "sizeof mismatch for DawnCompilationMessageUtf16"); +static_assert(alignof(DawnCompilationMessageUtf16) == alignof(WGPUDawnCompilationMessageUtf16), "alignof mismatch for DawnCompilationMessageUtf16"); +static_assert(offsetof(DawnCompilationMessageUtf16, linePos) == offsetof(WGPUDawnCompilationMessageUtf16, linePos), + "offsetof mismatch for DawnCompilationMessageUtf16::linePos"); +static_assert(offsetof(DawnCompilationMessageUtf16, offset) == offsetof(WGPUDawnCompilationMessageUtf16, offset), + "offsetof mismatch for DawnCompilationMessageUtf16::offset"); +static_assert(offsetof(DawnCompilationMessageUtf16, length) == offsetof(WGPUDawnCompilationMessageUtf16, length), + "offsetof mismatch for DawnCompilationMessageUtf16::length"); + +// EmscriptenSurfaceSourceCanvasHTMLSelector implementation +EmscriptenSurfaceSourceCanvasHTMLSelector::EmscriptenSurfaceSourceCanvasHTMLSelector() + : ChainedStruct { nullptr, SType::EmscriptenSurfaceSourceCanvasHTMLSelector } {} +struct EmscriptenSurfaceSourceCanvasHTMLSelector::Init { + ChainedStruct * const nextInChain; + StringView selector = {}; +}; +EmscriptenSurfaceSourceCanvasHTMLSelector::EmscriptenSurfaceSourceCanvasHTMLSelector(EmscriptenSurfaceSourceCanvasHTMLSelector::Init&& init) + : ChainedStruct { init.nextInChain, SType::EmscriptenSurfaceSourceCanvasHTMLSelector }, + selector(std::move(init.selector)){} + +EmscriptenSurfaceSourceCanvasHTMLSelector::operator const WGPUEmscriptenSurfaceSourceCanvasHTMLSelector&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(EmscriptenSurfaceSourceCanvasHTMLSelector) == sizeof(WGPUEmscriptenSurfaceSourceCanvasHTMLSelector), "sizeof mismatch for EmscriptenSurfaceSourceCanvasHTMLSelector"); +static_assert(alignof(EmscriptenSurfaceSourceCanvasHTMLSelector) == alignof(WGPUEmscriptenSurfaceSourceCanvasHTMLSelector), "alignof mismatch for EmscriptenSurfaceSourceCanvasHTMLSelector"); +static_assert(offsetof(EmscriptenSurfaceSourceCanvasHTMLSelector, selector) == offsetof(WGPUEmscriptenSurfaceSourceCanvasHTMLSelector, selector), + "offsetof mismatch for EmscriptenSurfaceSourceCanvasHTMLSelector::selector"); + +// Extent3D implementation + +Extent3D::operator const WGPUExtent3D&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(Extent3D) == sizeof(WGPUExtent3D), "sizeof mismatch for Extent3D"); +static_assert(alignof(Extent3D) == alignof(WGPUExtent3D), "alignof mismatch for Extent3D"); +static_assert(offsetof(Extent3D, width) == offsetof(WGPUExtent3D, width), + "offsetof mismatch for Extent3D::width"); +static_assert(offsetof(Extent3D, height) == offsetof(WGPUExtent3D, height), + "offsetof mismatch for Extent3D::height"); +static_assert(offsetof(Extent3D, depthOrArrayLayers) == offsetof(WGPUExtent3D, depthOrArrayLayers), + "offsetof mismatch for Extent3D::depthOrArrayLayers"); + +// Future implementation + +Future::operator const WGPUFuture&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(Future) == sizeof(WGPUFuture), "sizeof mismatch for Future"); +static_assert(alignof(Future) == alignof(WGPUFuture), "alignof mismatch for Future"); +static_assert(offsetof(Future, id) == offsetof(WGPUFuture, id), + "offsetof mismatch for Future::id"); + +// InstanceLimits implementation + +InstanceLimits::operator const WGPUInstanceLimits&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(InstanceLimits) == sizeof(WGPUInstanceLimits), "sizeof mismatch for InstanceLimits"); +static_assert(alignof(InstanceLimits) == alignof(WGPUInstanceLimits), "alignof mismatch for InstanceLimits"); +static_assert(offsetof(InstanceLimits, nextInChain) == offsetof(WGPUInstanceLimits, nextInChain), + "offsetof mismatch for InstanceLimits::nextInChain"); +static_assert(offsetof(InstanceLimits, timedWaitAnyMaxCount) == offsetof(WGPUInstanceLimits, timedWaitAnyMaxCount), + "offsetof mismatch for InstanceLimits::timedWaitAnyMaxCount"); + +// INTERNAL_HAVE_EMDAWNWEBGPU_HEADER implementation + +INTERNAL_HAVE_EMDAWNWEBGPU_HEADER::operator const WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(INTERNAL_HAVE_EMDAWNWEBGPU_HEADER) == sizeof(WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER), "sizeof mismatch for INTERNAL_HAVE_EMDAWNWEBGPU_HEADER"); +static_assert(alignof(INTERNAL_HAVE_EMDAWNWEBGPU_HEADER) == alignof(WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER), "alignof mismatch for INTERNAL_HAVE_EMDAWNWEBGPU_HEADER"); +static_assert(offsetof(INTERNAL_HAVE_EMDAWNWEBGPU_HEADER, unused) == offsetof(WGPUINTERNAL_HAVE_EMDAWNWEBGPU_HEADER, unused), + "offsetof mismatch for INTERNAL_HAVE_EMDAWNWEBGPU_HEADER::unused"); + +// MultisampleState implementation + +MultisampleState::operator const WGPUMultisampleState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(MultisampleState) == sizeof(WGPUMultisampleState), "sizeof mismatch for MultisampleState"); +static_assert(alignof(MultisampleState) == alignof(WGPUMultisampleState), "alignof mismatch for MultisampleState"); +static_assert(offsetof(MultisampleState, nextInChain) == offsetof(WGPUMultisampleState, nextInChain), + "offsetof mismatch for MultisampleState::nextInChain"); +static_assert(offsetof(MultisampleState, count) == offsetof(WGPUMultisampleState, count), + "offsetof mismatch for MultisampleState::count"); +static_assert(offsetof(MultisampleState, mask) == offsetof(WGPUMultisampleState, mask), + "offsetof mismatch for MultisampleState::mask"); +static_assert(offsetof(MultisampleState, alphaToCoverageEnabled) == offsetof(WGPUMultisampleState, alphaToCoverageEnabled), + "offsetof mismatch for MultisampleState::alphaToCoverageEnabled"); + +// Origin3D implementation + +Origin3D::operator const WGPUOrigin3D&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(Origin3D) == sizeof(WGPUOrigin3D), "sizeof mismatch for Origin3D"); +static_assert(alignof(Origin3D) == alignof(WGPUOrigin3D), "alignof mismatch for Origin3D"); +static_assert(offsetof(Origin3D, x) == offsetof(WGPUOrigin3D, x), + "offsetof mismatch for Origin3D::x"); +static_assert(offsetof(Origin3D, y) == offsetof(WGPUOrigin3D, y), + "offsetof mismatch for Origin3D::y"); +static_assert(offsetof(Origin3D, z) == offsetof(WGPUOrigin3D, z), + "offsetof mismatch for Origin3D::z"); + +// PassTimestampWrites implementation + +PassTimestampWrites::operator const WGPUPassTimestampWrites&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(PassTimestampWrites) == sizeof(WGPUPassTimestampWrites), "sizeof mismatch for PassTimestampWrites"); +static_assert(alignof(PassTimestampWrites) == alignof(WGPUPassTimestampWrites), "alignof mismatch for PassTimestampWrites"); +static_assert(offsetof(PassTimestampWrites, nextInChain) == offsetof(WGPUPassTimestampWrites, nextInChain), + "offsetof mismatch for PassTimestampWrites::nextInChain"); +static_assert(offsetof(PassTimestampWrites, querySet) == offsetof(WGPUPassTimestampWrites, querySet), + "offsetof mismatch for PassTimestampWrites::querySet"); +static_assert(offsetof(PassTimestampWrites, beginningOfPassWriteIndex) == offsetof(WGPUPassTimestampWrites, beginningOfPassWriteIndex), + "offsetof mismatch for PassTimestampWrites::beginningOfPassWriteIndex"); +static_assert(offsetof(PassTimestampWrites, endOfPassWriteIndex) == offsetof(WGPUPassTimestampWrites, endOfPassWriteIndex), + "offsetof mismatch for PassTimestampWrites::endOfPassWriteIndex"); + +// PipelineLayoutDescriptor implementation + +PipelineLayoutDescriptor::operator const WGPUPipelineLayoutDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(PipelineLayoutDescriptor) == sizeof(WGPUPipelineLayoutDescriptor), "sizeof mismatch for PipelineLayoutDescriptor"); +static_assert(alignof(PipelineLayoutDescriptor) == alignof(WGPUPipelineLayoutDescriptor), "alignof mismatch for PipelineLayoutDescriptor"); +static_assert(offsetof(PipelineLayoutDescriptor, nextInChain) == offsetof(WGPUPipelineLayoutDescriptor, nextInChain), + "offsetof mismatch for PipelineLayoutDescriptor::nextInChain"); +static_assert(offsetof(PipelineLayoutDescriptor, label) == offsetof(WGPUPipelineLayoutDescriptor, label), + "offsetof mismatch for PipelineLayoutDescriptor::label"); +static_assert(offsetof(PipelineLayoutDescriptor, bindGroupLayoutCount) == offsetof(WGPUPipelineLayoutDescriptor, bindGroupLayoutCount), + "offsetof mismatch for PipelineLayoutDescriptor::bindGroupLayoutCount"); +static_assert(offsetof(PipelineLayoutDescriptor, bindGroupLayouts) == offsetof(WGPUPipelineLayoutDescriptor, bindGroupLayouts), + "offsetof mismatch for PipelineLayoutDescriptor::bindGroupLayouts"); +static_assert(offsetof(PipelineLayoutDescriptor, immediateSize) == offsetof(WGPUPipelineLayoutDescriptor, immediateSize), + "offsetof mismatch for PipelineLayoutDescriptor::immediateSize"); + +// PrimitiveState implementation + +PrimitiveState::operator const WGPUPrimitiveState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(PrimitiveState) == sizeof(WGPUPrimitiveState), "sizeof mismatch for PrimitiveState"); +static_assert(alignof(PrimitiveState) == alignof(WGPUPrimitiveState), "alignof mismatch for PrimitiveState"); +static_assert(offsetof(PrimitiveState, nextInChain) == offsetof(WGPUPrimitiveState, nextInChain), + "offsetof mismatch for PrimitiveState::nextInChain"); +static_assert(offsetof(PrimitiveState, topology) == offsetof(WGPUPrimitiveState, topology), + "offsetof mismatch for PrimitiveState::topology"); +static_assert(offsetof(PrimitiveState, stripIndexFormat) == offsetof(WGPUPrimitiveState, stripIndexFormat), + "offsetof mismatch for PrimitiveState::stripIndexFormat"); +static_assert(offsetof(PrimitiveState, frontFace) == offsetof(WGPUPrimitiveState, frontFace), + "offsetof mismatch for PrimitiveState::frontFace"); +static_assert(offsetof(PrimitiveState, cullMode) == offsetof(WGPUPrimitiveState, cullMode), + "offsetof mismatch for PrimitiveState::cullMode"); +static_assert(offsetof(PrimitiveState, unclippedDepth) == offsetof(WGPUPrimitiveState, unclippedDepth), + "offsetof mismatch for PrimitiveState::unclippedDepth"); + +// QuerySetDescriptor implementation + +QuerySetDescriptor::operator const WGPUQuerySetDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(QuerySetDescriptor) == sizeof(WGPUQuerySetDescriptor), "sizeof mismatch for QuerySetDescriptor"); +static_assert(alignof(QuerySetDescriptor) == alignof(WGPUQuerySetDescriptor), "alignof mismatch for QuerySetDescriptor"); +static_assert(offsetof(QuerySetDescriptor, nextInChain) == offsetof(WGPUQuerySetDescriptor, nextInChain), + "offsetof mismatch for QuerySetDescriptor::nextInChain"); +static_assert(offsetof(QuerySetDescriptor, label) == offsetof(WGPUQuerySetDescriptor, label), + "offsetof mismatch for QuerySetDescriptor::label"); +static_assert(offsetof(QuerySetDescriptor, type) == offsetof(WGPUQuerySetDescriptor, type), + "offsetof mismatch for QuerySetDescriptor::type"); +static_assert(offsetof(QuerySetDescriptor, count) == offsetof(WGPUQuerySetDescriptor, count), + "offsetof mismatch for QuerySetDescriptor::count"); + +// QueueDescriptor implementation + +QueueDescriptor::operator const WGPUQueueDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(QueueDescriptor) == sizeof(WGPUQueueDescriptor), "sizeof mismatch for QueueDescriptor"); +static_assert(alignof(QueueDescriptor) == alignof(WGPUQueueDescriptor), "alignof mismatch for QueueDescriptor"); +static_assert(offsetof(QueueDescriptor, nextInChain) == offsetof(WGPUQueueDescriptor, nextInChain), + "offsetof mismatch for QueueDescriptor::nextInChain"); +static_assert(offsetof(QueueDescriptor, label) == offsetof(WGPUQueueDescriptor, label), + "offsetof mismatch for QueueDescriptor::label"); + +// RenderBundleDescriptor implementation + +RenderBundleDescriptor::operator const WGPURenderBundleDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderBundleDescriptor) == sizeof(WGPURenderBundleDescriptor), "sizeof mismatch for RenderBundleDescriptor"); +static_assert(alignof(RenderBundleDescriptor) == alignof(WGPURenderBundleDescriptor), "alignof mismatch for RenderBundleDescriptor"); +static_assert(offsetof(RenderBundleDescriptor, nextInChain) == offsetof(WGPURenderBundleDescriptor, nextInChain), + "offsetof mismatch for RenderBundleDescriptor::nextInChain"); +static_assert(offsetof(RenderBundleDescriptor, label) == offsetof(WGPURenderBundleDescriptor, label), + "offsetof mismatch for RenderBundleDescriptor::label"); + +// RenderBundleEncoderDescriptor implementation + +RenderBundleEncoderDescriptor::operator const WGPURenderBundleEncoderDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderBundleEncoderDescriptor) == sizeof(WGPURenderBundleEncoderDescriptor), "sizeof mismatch for RenderBundleEncoderDescriptor"); +static_assert(alignof(RenderBundleEncoderDescriptor) == alignof(WGPURenderBundleEncoderDescriptor), "alignof mismatch for RenderBundleEncoderDescriptor"); +static_assert(offsetof(RenderBundleEncoderDescriptor, nextInChain) == offsetof(WGPURenderBundleEncoderDescriptor, nextInChain), + "offsetof mismatch for RenderBundleEncoderDescriptor::nextInChain"); +static_assert(offsetof(RenderBundleEncoderDescriptor, label) == offsetof(WGPURenderBundleEncoderDescriptor, label), + "offsetof mismatch for RenderBundleEncoderDescriptor::label"); +static_assert(offsetof(RenderBundleEncoderDescriptor, colorFormatCount) == offsetof(WGPURenderBundleEncoderDescriptor, colorFormatCount), + "offsetof mismatch for RenderBundleEncoderDescriptor::colorFormatCount"); +static_assert(offsetof(RenderBundleEncoderDescriptor, colorFormats) == offsetof(WGPURenderBundleEncoderDescriptor, colorFormats), + "offsetof mismatch for RenderBundleEncoderDescriptor::colorFormats"); +static_assert(offsetof(RenderBundleEncoderDescriptor, depthStencilFormat) == offsetof(WGPURenderBundleEncoderDescriptor, depthStencilFormat), + "offsetof mismatch for RenderBundleEncoderDescriptor::depthStencilFormat"); +static_assert(offsetof(RenderBundleEncoderDescriptor, sampleCount) == offsetof(WGPURenderBundleEncoderDescriptor, sampleCount), + "offsetof mismatch for RenderBundleEncoderDescriptor::sampleCount"); +static_assert(offsetof(RenderBundleEncoderDescriptor, depthReadOnly) == offsetof(WGPURenderBundleEncoderDescriptor, depthReadOnly), + "offsetof mismatch for RenderBundleEncoderDescriptor::depthReadOnly"); +static_assert(offsetof(RenderBundleEncoderDescriptor, stencilReadOnly) == offsetof(WGPURenderBundleEncoderDescriptor, stencilReadOnly), + "offsetof mismatch for RenderBundleEncoderDescriptor::stencilReadOnly"); + +// RenderPassDepthStencilAttachment implementation + +RenderPassDepthStencilAttachment::operator const WGPURenderPassDepthStencilAttachment&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderPassDepthStencilAttachment) == sizeof(WGPURenderPassDepthStencilAttachment), "sizeof mismatch for RenderPassDepthStencilAttachment"); +static_assert(alignof(RenderPassDepthStencilAttachment) == alignof(WGPURenderPassDepthStencilAttachment), "alignof mismatch for RenderPassDepthStencilAttachment"); +static_assert(offsetof(RenderPassDepthStencilAttachment, nextInChain) == offsetof(WGPURenderPassDepthStencilAttachment, nextInChain), + "offsetof mismatch for RenderPassDepthStencilAttachment::nextInChain"); +static_assert(offsetof(RenderPassDepthStencilAttachment, view) == offsetof(WGPURenderPassDepthStencilAttachment, view), + "offsetof mismatch for RenderPassDepthStencilAttachment::view"); +static_assert(offsetof(RenderPassDepthStencilAttachment, depthLoadOp) == offsetof(WGPURenderPassDepthStencilAttachment, depthLoadOp), + "offsetof mismatch for RenderPassDepthStencilAttachment::depthLoadOp"); +static_assert(offsetof(RenderPassDepthStencilAttachment, depthStoreOp) == offsetof(WGPURenderPassDepthStencilAttachment, depthStoreOp), + "offsetof mismatch for RenderPassDepthStencilAttachment::depthStoreOp"); +static_assert(offsetof(RenderPassDepthStencilAttachment, depthClearValue) == offsetof(WGPURenderPassDepthStencilAttachment, depthClearValue), + "offsetof mismatch for RenderPassDepthStencilAttachment::depthClearValue"); +static_assert(offsetof(RenderPassDepthStencilAttachment, depthReadOnly) == offsetof(WGPURenderPassDepthStencilAttachment, depthReadOnly), + "offsetof mismatch for RenderPassDepthStencilAttachment::depthReadOnly"); +static_assert(offsetof(RenderPassDepthStencilAttachment, stencilLoadOp) == offsetof(WGPURenderPassDepthStencilAttachment, stencilLoadOp), + "offsetof mismatch for RenderPassDepthStencilAttachment::stencilLoadOp"); +static_assert(offsetof(RenderPassDepthStencilAttachment, stencilStoreOp) == offsetof(WGPURenderPassDepthStencilAttachment, stencilStoreOp), + "offsetof mismatch for RenderPassDepthStencilAttachment::stencilStoreOp"); +static_assert(offsetof(RenderPassDepthStencilAttachment, stencilClearValue) == offsetof(WGPURenderPassDepthStencilAttachment, stencilClearValue), + "offsetof mismatch for RenderPassDepthStencilAttachment::stencilClearValue"); +static_assert(offsetof(RenderPassDepthStencilAttachment, stencilReadOnly) == offsetof(WGPURenderPassDepthStencilAttachment, stencilReadOnly), + "offsetof mismatch for RenderPassDepthStencilAttachment::stencilReadOnly"); + +// RenderPassMaxDrawCount implementation +RenderPassMaxDrawCount::RenderPassMaxDrawCount() + : ChainedStruct { nullptr, SType::RenderPassMaxDrawCount } {} +struct RenderPassMaxDrawCount::Init { + ChainedStruct * const nextInChain; + uint64_t maxDrawCount = 50000000; +}; +RenderPassMaxDrawCount::RenderPassMaxDrawCount(RenderPassMaxDrawCount::Init&& init) + : ChainedStruct { init.nextInChain, SType::RenderPassMaxDrawCount }, + maxDrawCount(std::move(init.maxDrawCount)){} + +RenderPassMaxDrawCount::operator const WGPURenderPassMaxDrawCount&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderPassMaxDrawCount) == sizeof(WGPURenderPassMaxDrawCount), "sizeof mismatch for RenderPassMaxDrawCount"); +static_assert(alignof(RenderPassMaxDrawCount) == alignof(WGPURenderPassMaxDrawCount), "alignof mismatch for RenderPassMaxDrawCount"); +static_assert(offsetof(RenderPassMaxDrawCount, maxDrawCount) == offsetof(WGPURenderPassMaxDrawCount, maxDrawCount), + "offsetof mismatch for RenderPassMaxDrawCount::maxDrawCount"); + +// RequestAdapterWebXROptions implementation +RequestAdapterWebXROptions::RequestAdapterWebXROptions() + : ChainedStruct { nullptr, SType::RequestAdapterWebXROptions } {} +struct RequestAdapterWebXROptions::Init { + ChainedStruct * const nextInChain; + Bool xrCompatible; +}; +RequestAdapterWebXROptions::RequestAdapterWebXROptions(RequestAdapterWebXROptions::Init&& init) + : ChainedStruct { init.nextInChain, SType::RequestAdapterWebXROptions }, + xrCompatible(std::move(init.xrCompatible)){} + +RequestAdapterWebXROptions::operator const WGPURequestAdapterWebXROptions&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RequestAdapterWebXROptions) == sizeof(WGPURequestAdapterWebXROptions), "sizeof mismatch for RequestAdapterWebXROptions"); +static_assert(alignof(RequestAdapterWebXROptions) == alignof(WGPURequestAdapterWebXROptions), "alignof mismatch for RequestAdapterWebXROptions"); +static_assert(offsetof(RequestAdapterWebXROptions, xrCompatible) == offsetof(WGPURequestAdapterWebXROptions, xrCompatible), + "offsetof mismatch for RequestAdapterWebXROptions::xrCompatible"); + +// SamplerBindingLayout implementation + +SamplerBindingLayout::operator const WGPUSamplerBindingLayout&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SamplerBindingLayout) == sizeof(WGPUSamplerBindingLayout), "sizeof mismatch for SamplerBindingLayout"); +static_assert(alignof(SamplerBindingLayout) == alignof(WGPUSamplerBindingLayout), "alignof mismatch for SamplerBindingLayout"); +static_assert(offsetof(SamplerBindingLayout, nextInChain) == offsetof(WGPUSamplerBindingLayout, nextInChain), + "offsetof mismatch for SamplerBindingLayout::nextInChain"); +static_assert(offsetof(SamplerBindingLayout, type) == offsetof(WGPUSamplerBindingLayout, type), + "offsetof mismatch for SamplerBindingLayout::type"); + +// SamplerDescriptor implementation + +SamplerDescriptor::operator const WGPUSamplerDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SamplerDescriptor) == sizeof(WGPUSamplerDescriptor), "sizeof mismatch for SamplerDescriptor"); +static_assert(alignof(SamplerDescriptor) == alignof(WGPUSamplerDescriptor), "alignof mismatch for SamplerDescriptor"); +static_assert(offsetof(SamplerDescriptor, nextInChain) == offsetof(WGPUSamplerDescriptor, nextInChain), + "offsetof mismatch for SamplerDescriptor::nextInChain"); +static_assert(offsetof(SamplerDescriptor, label) == offsetof(WGPUSamplerDescriptor, label), + "offsetof mismatch for SamplerDescriptor::label"); +static_assert(offsetof(SamplerDescriptor, addressModeU) == offsetof(WGPUSamplerDescriptor, addressModeU), + "offsetof mismatch for SamplerDescriptor::addressModeU"); +static_assert(offsetof(SamplerDescriptor, addressModeV) == offsetof(WGPUSamplerDescriptor, addressModeV), + "offsetof mismatch for SamplerDescriptor::addressModeV"); +static_assert(offsetof(SamplerDescriptor, addressModeW) == offsetof(WGPUSamplerDescriptor, addressModeW), + "offsetof mismatch for SamplerDescriptor::addressModeW"); +static_assert(offsetof(SamplerDescriptor, magFilter) == offsetof(WGPUSamplerDescriptor, magFilter), + "offsetof mismatch for SamplerDescriptor::magFilter"); +static_assert(offsetof(SamplerDescriptor, minFilter) == offsetof(WGPUSamplerDescriptor, minFilter), + "offsetof mismatch for SamplerDescriptor::minFilter"); +static_assert(offsetof(SamplerDescriptor, mipmapFilter) == offsetof(WGPUSamplerDescriptor, mipmapFilter), + "offsetof mismatch for SamplerDescriptor::mipmapFilter"); +static_assert(offsetof(SamplerDescriptor, lodMinClamp) == offsetof(WGPUSamplerDescriptor, lodMinClamp), + "offsetof mismatch for SamplerDescriptor::lodMinClamp"); +static_assert(offsetof(SamplerDescriptor, lodMaxClamp) == offsetof(WGPUSamplerDescriptor, lodMaxClamp), + "offsetof mismatch for SamplerDescriptor::lodMaxClamp"); +static_assert(offsetof(SamplerDescriptor, compare) == offsetof(WGPUSamplerDescriptor, compare), + "offsetof mismatch for SamplerDescriptor::compare"); +static_assert(offsetof(SamplerDescriptor, maxAnisotropy) == offsetof(WGPUSamplerDescriptor, maxAnisotropy), + "offsetof mismatch for SamplerDescriptor::maxAnisotropy"); + +// ShaderSourceSPIRV implementation +ShaderSourceSPIRV::ShaderSourceSPIRV() + : ChainedStruct { nullptr, SType::ShaderSourceSPIRV } {} +struct ShaderSourceSPIRV::Init { + ChainedStruct * const nextInChain; + uint32_t codeSize; + uint32_t const * code = nullptr; +}; +ShaderSourceSPIRV::ShaderSourceSPIRV(ShaderSourceSPIRV::Init&& init) + : ChainedStruct { init.nextInChain, SType::ShaderSourceSPIRV }, + codeSize(std::move(init.codeSize)), + code(std::move(init.code)){} + +ShaderSourceSPIRV::operator const WGPUShaderSourceSPIRV&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ShaderSourceSPIRV) == sizeof(WGPUShaderSourceSPIRV), "sizeof mismatch for ShaderSourceSPIRV"); +static_assert(alignof(ShaderSourceSPIRV) == alignof(WGPUShaderSourceSPIRV), "alignof mismatch for ShaderSourceSPIRV"); +static_assert(offsetof(ShaderSourceSPIRV, codeSize) == offsetof(WGPUShaderSourceSPIRV, codeSize), + "offsetof mismatch for ShaderSourceSPIRV::codeSize"); +static_assert(offsetof(ShaderSourceSPIRV, code) == offsetof(WGPUShaderSourceSPIRV, code), + "offsetof mismatch for ShaderSourceSPIRV::code"); + +// ShaderSourceWGSL implementation +ShaderSourceWGSL::ShaderSourceWGSL() + : ChainedStruct { nullptr, SType::ShaderSourceWGSL } {} +struct ShaderSourceWGSL::Init { + ChainedStruct * const nextInChain; + StringView code = {}; +}; +ShaderSourceWGSL::ShaderSourceWGSL(ShaderSourceWGSL::Init&& init) + : ChainedStruct { init.nextInChain, SType::ShaderSourceWGSL }, + code(std::move(init.code)){} + +ShaderSourceWGSL::operator const WGPUShaderSourceWGSL&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ShaderSourceWGSL) == sizeof(WGPUShaderSourceWGSL), "sizeof mismatch for ShaderSourceWGSL"); +static_assert(alignof(ShaderSourceWGSL) == alignof(WGPUShaderSourceWGSL), "alignof mismatch for ShaderSourceWGSL"); +static_assert(offsetof(ShaderSourceWGSL, code) == offsetof(WGPUShaderSourceWGSL, code), + "offsetof mismatch for ShaderSourceWGSL::code"); + +// StencilFaceState implementation + +StencilFaceState::operator const WGPUStencilFaceState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(StencilFaceState) == sizeof(WGPUStencilFaceState), "sizeof mismatch for StencilFaceState"); +static_assert(alignof(StencilFaceState) == alignof(WGPUStencilFaceState), "alignof mismatch for StencilFaceState"); +static_assert(offsetof(StencilFaceState, compare) == offsetof(WGPUStencilFaceState, compare), + "offsetof mismatch for StencilFaceState::compare"); +static_assert(offsetof(StencilFaceState, failOp) == offsetof(WGPUStencilFaceState, failOp), + "offsetof mismatch for StencilFaceState::failOp"); +static_assert(offsetof(StencilFaceState, depthFailOp) == offsetof(WGPUStencilFaceState, depthFailOp), + "offsetof mismatch for StencilFaceState::depthFailOp"); +static_assert(offsetof(StencilFaceState, passOp) == offsetof(WGPUStencilFaceState, passOp), + "offsetof mismatch for StencilFaceState::passOp"); + +// StorageTextureBindingLayout implementation + +StorageTextureBindingLayout::operator const WGPUStorageTextureBindingLayout&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(StorageTextureBindingLayout) == sizeof(WGPUStorageTextureBindingLayout), "sizeof mismatch for StorageTextureBindingLayout"); +static_assert(alignof(StorageTextureBindingLayout) == alignof(WGPUStorageTextureBindingLayout), "alignof mismatch for StorageTextureBindingLayout"); +static_assert(offsetof(StorageTextureBindingLayout, nextInChain) == offsetof(WGPUStorageTextureBindingLayout, nextInChain), + "offsetof mismatch for StorageTextureBindingLayout::nextInChain"); +static_assert(offsetof(StorageTextureBindingLayout, access) == offsetof(WGPUStorageTextureBindingLayout, access), + "offsetof mismatch for StorageTextureBindingLayout::access"); +static_assert(offsetof(StorageTextureBindingLayout, format) == offsetof(WGPUStorageTextureBindingLayout, format), + "offsetof mismatch for StorageTextureBindingLayout::format"); +static_assert(offsetof(StorageTextureBindingLayout, viewDimension) == offsetof(WGPUStorageTextureBindingLayout, viewDimension), + "offsetof mismatch for StorageTextureBindingLayout::viewDimension"); + +// SupportedFeatures implementation +SupportedFeatures::SupportedFeatures() = default; +SupportedFeatures::~SupportedFeatures() { + FreeMembers(); +} + +SupportedFeatures::SupportedFeatures(SupportedFeatures&& rhs) + : featureCount(rhs.featureCount), + features(rhs.features){ + Reset(rhs); +} + +SupportedFeatures& SupportedFeatures::operator=(SupportedFeatures&& rhs) { + if (&rhs == this) { + return *this; + } + FreeMembers(); + detail::AsNonConstReference(this->featureCount) = std::move(rhs.featureCount); + detail::AsNonConstReference(this->features) = std::move(rhs.features); + Reset(rhs); + return *this; +} + +void SupportedFeatures::FreeMembers() { + bool needsFreeing = false; if (this->features != nullptr) { needsFreeing = true; }if (needsFreeing) { + wgpuSupportedFeaturesFreeMembers( + *reinterpret_cast(this)); + } +} + +// static +void SupportedFeatures::Reset(SupportedFeatures& value) { + SupportedFeatures defaultValue{}; + detail::AsNonConstReference(value.featureCount) = defaultValue.featureCount; + detail::AsNonConstReference(value.features) = defaultValue.features; +} + +SupportedFeatures::operator const WGPUSupportedFeatures&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SupportedFeatures) == sizeof(WGPUSupportedFeatures), "sizeof mismatch for SupportedFeatures"); +static_assert(alignof(SupportedFeatures) == alignof(WGPUSupportedFeatures), "alignof mismatch for SupportedFeatures"); +static_assert(offsetof(SupportedFeatures, featureCount) == offsetof(WGPUSupportedFeatures, featureCount), + "offsetof mismatch for SupportedFeatures::featureCount"); +static_assert(offsetof(SupportedFeatures, features) == offsetof(WGPUSupportedFeatures, features), + "offsetof mismatch for SupportedFeatures::features"); + +// SupportedInstanceFeatures implementation +SupportedInstanceFeatures::SupportedInstanceFeatures() = default; +SupportedInstanceFeatures::~SupportedInstanceFeatures() { + FreeMembers(); +} + +SupportedInstanceFeatures::SupportedInstanceFeatures(SupportedInstanceFeatures&& rhs) + : featureCount(rhs.featureCount), + features(rhs.features){ + Reset(rhs); +} + +SupportedInstanceFeatures& SupportedInstanceFeatures::operator=(SupportedInstanceFeatures&& rhs) { + if (&rhs == this) { + return *this; + } + FreeMembers(); + detail::AsNonConstReference(this->featureCount) = std::move(rhs.featureCount); + detail::AsNonConstReference(this->features) = std::move(rhs.features); + Reset(rhs); + return *this; +} + +void SupportedInstanceFeatures::FreeMembers() { + bool needsFreeing = false; if (this->features != nullptr) { needsFreeing = true; }if (needsFreeing) { + wgpuSupportedInstanceFeaturesFreeMembers( + *reinterpret_cast(this)); + } +} + +// static +void SupportedInstanceFeatures::Reset(SupportedInstanceFeatures& value) { + SupportedInstanceFeatures defaultValue{}; + detail::AsNonConstReference(value.featureCount) = defaultValue.featureCount; + detail::AsNonConstReference(value.features) = defaultValue.features; +} + +SupportedInstanceFeatures::operator const WGPUSupportedInstanceFeatures&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SupportedInstanceFeatures) == sizeof(WGPUSupportedInstanceFeatures), "sizeof mismatch for SupportedInstanceFeatures"); +static_assert(alignof(SupportedInstanceFeatures) == alignof(WGPUSupportedInstanceFeatures), "alignof mismatch for SupportedInstanceFeatures"); +static_assert(offsetof(SupportedInstanceFeatures, featureCount) == offsetof(WGPUSupportedInstanceFeatures, featureCount), + "offsetof mismatch for SupportedInstanceFeatures::featureCount"); +static_assert(offsetof(SupportedInstanceFeatures, features) == offsetof(WGPUSupportedInstanceFeatures, features), + "offsetof mismatch for SupportedInstanceFeatures::features"); + +// SupportedWGSLLanguageFeatures implementation +SupportedWGSLLanguageFeatures::SupportedWGSLLanguageFeatures() = default; +SupportedWGSLLanguageFeatures::~SupportedWGSLLanguageFeatures() { + FreeMembers(); +} + +SupportedWGSLLanguageFeatures::SupportedWGSLLanguageFeatures(SupportedWGSLLanguageFeatures&& rhs) + : featureCount(rhs.featureCount), + features(rhs.features){ + Reset(rhs); +} + +SupportedWGSLLanguageFeatures& SupportedWGSLLanguageFeatures::operator=(SupportedWGSLLanguageFeatures&& rhs) { + if (&rhs == this) { + return *this; + } + FreeMembers(); + detail::AsNonConstReference(this->featureCount) = std::move(rhs.featureCount); + detail::AsNonConstReference(this->features) = std::move(rhs.features); + Reset(rhs); + return *this; +} + +void SupportedWGSLLanguageFeatures::FreeMembers() { + bool needsFreeing = false; if (this->features != nullptr) { needsFreeing = true; }if (needsFreeing) { + wgpuSupportedWGSLLanguageFeaturesFreeMembers( + *reinterpret_cast(this)); + } +} + +// static +void SupportedWGSLLanguageFeatures::Reset(SupportedWGSLLanguageFeatures& value) { + SupportedWGSLLanguageFeatures defaultValue{}; + detail::AsNonConstReference(value.featureCount) = defaultValue.featureCount; + detail::AsNonConstReference(value.features) = defaultValue.features; +} + +SupportedWGSLLanguageFeatures::operator const WGPUSupportedWGSLLanguageFeatures&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SupportedWGSLLanguageFeatures) == sizeof(WGPUSupportedWGSLLanguageFeatures), "sizeof mismatch for SupportedWGSLLanguageFeatures"); +static_assert(alignof(SupportedWGSLLanguageFeatures) == alignof(WGPUSupportedWGSLLanguageFeatures), "alignof mismatch for SupportedWGSLLanguageFeatures"); +static_assert(offsetof(SupportedWGSLLanguageFeatures, featureCount) == offsetof(WGPUSupportedWGSLLanguageFeatures, featureCount), + "offsetof mismatch for SupportedWGSLLanguageFeatures::featureCount"); +static_assert(offsetof(SupportedWGSLLanguageFeatures, features) == offsetof(WGPUSupportedWGSLLanguageFeatures, features), + "offsetof mismatch for SupportedWGSLLanguageFeatures::features"); + +// SurfaceCapabilities implementation +SurfaceCapabilities::SurfaceCapabilities() = default; +SurfaceCapabilities::~SurfaceCapabilities() { + FreeMembers(); +} + +SurfaceCapabilities::SurfaceCapabilities(SurfaceCapabilities&& rhs) + : usages(rhs.usages), + formatCount(rhs.formatCount), + formats(rhs.formats), + presentModeCount(rhs.presentModeCount), + presentModes(rhs.presentModes), + alphaModeCount(rhs.alphaModeCount), + alphaModes(rhs.alphaModes){ + Reset(rhs); +} + +SurfaceCapabilities& SurfaceCapabilities::operator=(SurfaceCapabilities&& rhs) { + if (&rhs == this) { + return *this; + } + FreeMembers(); + detail::AsNonConstReference(this->usages) = std::move(rhs.usages); + detail::AsNonConstReference(this->formatCount) = std::move(rhs.formatCount); + detail::AsNonConstReference(this->formats) = std::move(rhs.formats); + detail::AsNonConstReference(this->presentModeCount) = std::move(rhs.presentModeCount); + detail::AsNonConstReference(this->presentModes) = std::move(rhs.presentModes); + detail::AsNonConstReference(this->alphaModeCount) = std::move(rhs.alphaModeCount); + detail::AsNonConstReference(this->alphaModes) = std::move(rhs.alphaModes); + Reset(rhs); + return *this; +} + +void SurfaceCapabilities::FreeMembers() { + bool needsFreeing = false; if (this->formats != nullptr) { needsFreeing = true; } if (this->presentModes != nullptr) { needsFreeing = true; } if (this->alphaModes != nullptr) { needsFreeing = true; }if (needsFreeing) { + wgpuSurfaceCapabilitiesFreeMembers( + *reinterpret_cast(this)); + } +} + +// static +void SurfaceCapabilities::Reset(SurfaceCapabilities& value) { + SurfaceCapabilities defaultValue{}; + detail::AsNonConstReference(value.usages) = defaultValue.usages; + detail::AsNonConstReference(value.formatCount) = defaultValue.formatCount; + detail::AsNonConstReference(value.formats) = defaultValue.formats; + detail::AsNonConstReference(value.presentModeCount) = defaultValue.presentModeCount; + detail::AsNonConstReference(value.presentModes) = defaultValue.presentModes; + detail::AsNonConstReference(value.alphaModeCount) = defaultValue.alphaModeCount; + detail::AsNonConstReference(value.alphaModes) = defaultValue.alphaModes; +} + +SurfaceCapabilities::operator const WGPUSurfaceCapabilities&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SurfaceCapabilities) == sizeof(WGPUSurfaceCapabilities), "sizeof mismatch for SurfaceCapabilities"); +static_assert(alignof(SurfaceCapabilities) == alignof(WGPUSurfaceCapabilities), "alignof mismatch for SurfaceCapabilities"); +static_assert(offsetof(SurfaceCapabilities, nextInChain) == offsetof(WGPUSurfaceCapabilities, nextInChain), + "offsetof mismatch for SurfaceCapabilities::nextInChain"); +static_assert(offsetof(SurfaceCapabilities, usages) == offsetof(WGPUSurfaceCapabilities, usages), + "offsetof mismatch for SurfaceCapabilities::usages"); +static_assert(offsetof(SurfaceCapabilities, formatCount) == offsetof(WGPUSurfaceCapabilities, formatCount), + "offsetof mismatch for SurfaceCapabilities::formatCount"); +static_assert(offsetof(SurfaceCapabilities, formats) == offsetof(WGPUSurfaceCapabilities, formats), + "offsetof mismatch for SurfaceCapabilities::formats"); +static_assert(offsetof(SurfaceCapabilities, presentModeCount) == offsetof(WGPUSurfaceCapabilities, presentModeCount), + "offsetof mismatch for SurfaceCapabilities::presentModeCount"); +static_assert(offsetof(SurfaceCapabilities, presentModes) == offsetof(WGPUSurfaceCapabilities, presentModes), + "offsetof mismatch for SurfaceCapabilities::presentModes"); +static_assert(offsetof(SurfaceCapabilities, alphaModeCount) == offsetof(WGPUSurfaceCapabilities, alphaModeCount), + "offsetof mismatch for SurfaceCapabilities::alphaModeCount"); +static_assert(offsetof(SurfaceCapabilities, alphaModes) == offsetof(WGPUSurfaceCapabilities, alphaModes), + "offsetof mismatch for SurfaceCapabilities::alphaModes"); + +// SurfaceColorManagement implementation +SurfaceColorManagement::SurfaceColorManagement() + : ChainedStruct { nullptr, SType::SurfaceColorManagement } {} +struct SurfaceColorManagement::Init { + ChainedStruct * const nextInChain; + PredefinedColorSpace colorSpace = {}; + ToneMappingMode toneMappingMode = {}; +}; +SurfaceColorManagement::SurfaceColorManagement(SurfaceColorManagement::Init&& init) + : ChainedStruct { init.nextInChain, SType::SurfaceColorManagement }, + colorSpace(std::move(init.colorSpace)), + toneMappingMode(std::move(init.toneMappingMode)){} + +SurfaceColorManagement::operator const WGPUSurfaceColorManagement&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SurfaceColorManagement) == sizeof(WGPUSurfaceColorManagement), "sizeof mismatch for SurfaceColorManagement"); +static_assert(alignof(SurfaceColorManagement) == alignof(WGPUSurfaceColorManagement), "alignof mismatch for SurfaceColorManagement"); +static_assert(offsetof(SurfaceColorManagement, colorSpace) == offsetof(WGPUSurfaceColorManagement, colorSpace), + "offsetof mismatch for SurfaceColorManagement::colorSpace"); +static_assert(offsetof(SurfaceColorManagement, toneMappingMode) == offsetof(WGPUSurfaceColorManagement, toneMappingMode), + "offsetof mismatch for SurfaceColorManagement::toneMappingMode"); + +// SurfaceConfiguration implementation + +SurfaceConfiguration::operator const WGPUSurfaceConfiguration&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SurfaceConfiguration) == sizeof(WGPUSurfaceConfiguration), "sizeof mismatch for SurfaceConfiguration"); +static_assert(alignof(SurfaceConfiguration) == alignof(WGPUSurfaceConfiguration), "alignof mismatch for SurfaceConfiguration"); +static_assert(offsetof(SurfaceConfiguration, nextInChain) == offsetof(WGPUSurfaceConfiguration, nextInChain), + "offsetof mismatch for SurfaceConfiguration::nextInChain"); +static_assert(offsetof(SurfaceConfiguration, device) == offsetof(WGPUSurfaceConfiguration, device), + "offsetof mismatch for SurfaceConfiguration::device"); +static_assert(offsetof(SurfaceConfiguration, format) == offsetof(WGPUSurfaceConfiguration, format), + "offsetof mismatch for SurfaceConfiguration::format"); +static_assert(offsetof(SurfaceConfiguration, usage) == offsetof(WGPUSurfaceConfiguration, usage), + "offsetof mismatch for SurfaceConfiguration::usage"); +static_assert(offsetof(SurfaceConfiguration, width) == offsetof(WGPUSurfaceConfiguration, width), + "offsetof mismatch for SurfaceConfiguration::width"); +static_assert(offsetof(SurfaceConfiguration, height) == offsetof(WGPUSurfaceConfiguration, height), + "offsetof mismatch for SurfaceConfiguration::height"); +static_assert(offsetof(SurfaceConfiguration, viewFormatCount) == offsetof(WGPUSurfaceConfiguration, viewFormatCount), + "offsetof mismatch for SurfaceConfiguration::viewFormatCount"); +static_assert(offsetof(SurfaceConfiguration, viewFormats) == offsetof(WGPUSurfaceConfiguration, viewFormats), + "offsetof mismatch for SurfaceConfiguration::viewFormats"); +static_assert(offsetof(SurfaceConfiguration, alphaMode) == offsetof(WGPUSurfaceConfiguration, alphaMode), + "offsetof mismatch for SurfaceConfiguration::alphaMode"); +static_assert(offsetof(SurfaceConfiguration, presentMode) == offsetof(WGPUSurfaceConfiguration, presentMode), + "offsetof mismatch for SurfaceConfiguration::presentMode"); + +// SurfaceTexture implementation + +SurfaceTexture::operator const WGPUSurfaceTexture&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SurfaceTexture) == sizeof(WGPUSurfaceTexture), "sizeof mismatch for SurfaceTexture"); +static_assert(alignof(SurfaceTexture) == alignof(WGPUSurfaceTexture), "alignof mismatch for SurfaceTexture"); +static_assert(offsetof(SurfaceTexture, nextInChain) == offsetof(WGPUSurfaceTexture, nextInChain), + "offsetof mismatch for SurfaceTexture::nextInChain"); +static_assert(offsetof(SurfaceTexture, texture) == offsetof(WGPUSurfaceTexture, texture), + "offsetof mismatch for SurfaceTexture::texture"); +static_assert(offsetof(SurfaceTexture, status) == offsetof(WGPUSurfaceTexture, status), + "offsetof mismatch for SurfaceTexture::status"); + +// TexelCopyBufferLayout implementation + +TexelCopyBufferLayout::operator const WGPUTexelCopyBufferLayout&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TexelCopyBufferLayout) == sizeof(WGPUTexelCopyBufferLayout), "sizeof mismatch for TexelCopyBufferLayout"); +static_assert(alignof(TexelCopyBufferLayout) == alignof(WGPUTexelCopyBufferLayout), "alignof mismatch for TexelCopyBufferLayout"); +static_assert(offsetof(TexelCopyBufferLayout, offset) == offsetof(WGPUTexelCopyBufferLayout, offset), + "offsetof mismatch for TexelCopyBufferLayout::offset"); +static_assert(offsetof(TexelCopyBufferLayout, bytesPerRow) == offsetof(WGPUTexelCopyBufferLayout, bytesPerRow), + "offsetof mismatch for TexelCopyBufferLayout::bytesPerRow"); +static_assert(offsetof(TexelCopyBufferLayout, rowsPerImage) == offsetof(WGPUTexelCopyBufferLayout, rowsPerImage), + "offsetof mismatch for TexelCopyBufferLayout::rowsPerImage"); + +// TextureBindingLayout implementation + +TextureBindingLayout::operator const WGPUTextureBindingLayout&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TextureBindingLayout) == sizeof(WGPUTextureBindingLayout), "sizeof mismatch for TextureBindingLayout"); +static_assert(alignof(TextureBindingLayout) == alignof(WGPUTextureBindingLayout), "alignof mismatch for TextureBindingLayout"); +static_assert(offsetof(TextureBindingLayout, nextInChain) == offsetof(WGPUTextureBindingLayout, nextInChain), + "offsetof mismatch for TextureBindingLayout::nextInChain"); +static_assert(offsetof(TextureBindingLayout, sampleType) == offsetof(WGPUTextureBindingLayout, sampleType), + "offsetof mismatch for TextureBindingLayout::sampleType"); +static_assert(offsetof(TextureBindingLayout, viewDimension) == offsetof(WGPUTextureBindingLayout, viewDimension), + "offsetof mismatch for TextureBindingLayout::viewDimension"); +static_assert(offsetof(TextureBindingLayout, multisampled) == offsetof(WGPUTextureBindingLayout, multisampled), + "offsetof mismatch for TextureBindingLayout::multisampled"); + +// TextureBindingViewDimensionDescriptor implementation +TextureBindingViewDimensionDescriptor::TextureBindingViewDimensionDescriptor() + : ChainedStruct { nullptr, SType::TextureBindingViewDimensionDescriptor } {} +struct TextureBindingViewDimensionDescriptor::Init { + ChainedStruct * const nextInChain; + TextureViewDimension textureBindingViewDimension = TextureViewDimension::Undefined; +}; +TextureBindingViewDimensionDescriptor::TextureBindingViewDimensionDescriptor(TextureBindingViewDimensionDescriptor::Init&& init) + : ChainedStruct { init.nextInChain, SType::TextureBindingViewDimensionDescriptor }, + textureBindingViewDimension(std::move(init.textureBindingViewDimension)){} + +TextureBindingViewDimensionDescriptor::operator const WGPUTextureBindingViewDimensionDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TextureBindingViewDimensionDescriptor) == sizeof(WGPUTextureBindingViewDimensionDescriptor), "sizeof mismatch for TextureBindingViewDimensionDescriptor"); +static_assert(alignof(TextureBindingViewDimensionDescriptor) == alignof(WGPUTextureBindingViewDimensionDescriptor), "alignof mismatch for TextureBindingViewDimensionDescriptor"); +static_assert(offsetof(TextureBindingViewDimensionDescriptor, textureBindingViewDimension) == offsetof(WGPUTextureBindingViewDimensionDescriptor, textureBindingViewDimension), + "offsetof mismatch for TextureBindingViewDimensionDescriptor::textureBindingViewDimension"); + +// TextureComponentSwizzle implementation + +TextureComponentSwizzle::operator const WGPUTextureComponentSwizzle&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TextureComponentSwizzle) == sizeof(WGPUTextureComponentSwizzle), "sizeof mismatch for TextureComponentSwizzle"); +static_assert(alignof(TextureComponentSwizzle) == alignof(WGPUTextureComponentSwizzle), "alignof mismatch for TextureComponentSwizzle"); +static_assert(offsetof(TextureComponentSwizzle, r) == offsetof(WGPUTextureComponentSwizzle, r), + "offsetof mismatch for TextureComponentSwizzle::r"); +static_assert(offsetof(TextureComponentSwizzle, g) == offsetof(WGPUTextureComponentSwizzle, g), + "offsetof mismatch for TextureComponentSwizzle::g"); +static_assert(offsetof(TextureComponentSwizzle, b) == offsetof(WGPUTextureComponentSwizzle, b), + "offsetof mismatch for TextureComponentSwizzle::b"); +static_assert(offsetof(TextureComponentSwizzle, a) == offsetof(WGPUTextureComponentSwizzle, a), + "offsetof mismatch for TextureComponentSwizzle::a"); + +// VertexAttribute implementation + +VertexAttribute::operator const WGPUVertexAttribute&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(VertexAttribute) == sizeof(WGPUVertexAttribute), "sizeof mismatch for VertexAttribute"); +static_assert(alignof(VertexAttribute) == alignof(WGPUVertexAttribute), "alignof mismatch for VertexAttribute"); +static_assert(offsetof(VertexAttribute, nextInChain) == offsetof(WGPUVertexAttribute, nextInChain), + "offsetof mismatch for VertexAttribute::nextInChain"); +static_assert(offsetof(VertexAttribute, format) == offsetof(WGPUVertexAttribute, format), + "offsetof mismatch for VertexAttribute::format"); +static_assert(offsetof(VertexAttribute, offset) == offsetof(WGPUVertexAttribute, offset), + "offsetof mismatch for VertexAttribute::offset"); +static_assert(offsetof(VertexAttribute, shaderLocation) == offsetof(WGPUVertexAttribute, shaderLocation), + "offsetof mismatch for VertexAttribute::shaderLocation"); + +// BindGroupDescriptor implementation + +BindGroupDescriptor::operator const WGPUBindGroupDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BindGroupDescriptor) == sizeof(WGPUBindGroupDescriptor), "sizeof mismatch for BindGroupDescriptor"); +static_assert(alignof(BindGroupDescriptor) == alignof(WGPUBindGroupDescriptor), "alignof mismatch for BindGroupDescriptor"); +static_assert(offsetof(BindGroupDescriptor, nextInChain) == offsetof(WGPUBindGroupDescriptor, nextInChain), + "offsetof mismatch for BindGroupDescriptor::nextInChain"); +static_assert(offsetof(BindGroupDescriptor, label) == offsetof(WGPUBindGroupDescriptor, label), + "offsetof mismatch for BindGroupDescriptor::label"); +static_assert(offsetof(BindGroupDescriptor, layout) == offsetof(WGPUBindGroupDescriptor, layout), + "offsetof mismatch for BindGroupDescriptor::layout"); +static_assert(offsetof(BindGroupDescriptor, entryCount) == offsetof(WGPUBindGroupDescriptor, entryCount), + "offsetof mismatch for BindGroupDescriptor::entryCount"); +static_assert(offsetof(BindGroupDescriptor, entries) == offsetof(WGPUBindGroupDescriptor, entries), + "offsetof mismatch for BindGroupDescriptor::entries"); + +// BindGroupLayoutEntry implementation + +BindGroupLayoutEntry::operator const WGPUBindGroupLayoutEntry&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BindGroupLayoutEntry) == sizeof(WGPUBindGroupLayoutEntry), "sizeof mismatch for BindGroupLayoutEntry"); +static_assert(alignof(BindGroupLayoutEntry) == alignof(WGPUBindGroupLayoutEntry), "alignof mismatch for BindGroupLayoutEntry"); +static_assert(offsetof(BindGroupLayoutEntry, nextInChain) == offsetof(WGPUBindGroupLayoutEntry, nextInChain), + "offsetof mismatch for BindGroupLayoutEntry::nextInChain"); +static_assert(offsetof(BindGroupLayoutEntry, binding) == offsetof(WGPUBindGroupLayoutEntry, binding), + "offsetof mismatch for BindGroupLayoutEntry::binding"); +static_assert(offsetof(BindGroupLayoutEntry, visibility) == offsetof(WGPUBindGroupLayoutEntry, visibility), + "offsetof mismatch for BindGroupLayoutEntry::visibility"); +static_assert(offsetof(BindGroupLayoutEntry, bindingArraySize) == offsetof(WGPUBindGroupLayoutEntry, bindingArraySize), + "offsetof mismatch for BindGroupLayoutEntry::bindingArraySize"); +static_assert(offsetof(BindGroupLayoutEntry, buffer) == offsetof(WGPUBindGroupLayoutEntry, buffer), + "offsetof mismatch for BindGroupLayoutEntry::buffer"); +static_assert(offsetof(BindGroupLayoutEntry, sampler) == offsetof(WGPUBindGroupLayoutEntry, sampler), + "offsetof mismatch for BindGroupLayoutEntry::sampler"); +static_assert(offsetof(BindGroupLayoutEntry, texture) == offsetof(WGPUBindGroupLayoutEntry, texture), + "offsetof mismatch for BindGroupLayoutEntry::texture"); +static_assert(offsetof(BindGroupLayoutEntry, storageTexture) == offsetof(WGPUBindGroupLayoutEntry, storageTexture), + "offsetof mismatch for BindGroupLayoutEntry::storageTexture"); + +// BlendState implementation + +BlendState::operator const WGPUBlendState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BlendState) == sizeof(WGPUBlendState), "sizeof mismatch for BlendState"); +static_assert(alignof(BlendState) == alignof(WGPUBlendState), "alignof mismatch for BlendState"); +static_assert(offsetof(BlendState, color) == offsetof(WGPUBlendState, color), + "offsetof mismatch for BlendState::color"); +static_assert(offsetof(BlendState, alpha) == offsetof(WGPUBlendState, alpha), + "offsetof mismatch for BlendState::alpha"); + +// CompilationMessage implementation + +CompilationMessage::operator const WGPUCompilationMessage&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(CompilationMessage) == sizeof(WGPUCompilationMessage), "sizeof mismatch for CompilationMessage"); +static_assert(alignof(CompilationMessage) == alignof(WGPUCompilationMessage), "alignof mismatch for CompilationMessage"); +static_assert(offsetof(CompilationMessage, nextInChain) == offsetof(WGPUCompilationMessage, nextInChain), + "offsetof mismatch for CompilationMessage::nextInChain"); +static_assert(offsetof(CompilationMessage, message) == offsetof(WGPUCompilationMessage, message), + "offsetof mismatch for CompilationMessage::message"); +static_assert(offsetof(CompilationMessage, type) == offsetof(WGPUCompilationMessage, type), + "offsetof mismatch for CompilationMessage::type"); +static_assert(offsetof(CompilationMessage, lineNum) == offsetof(WGPUCompilationMessage, lineNum), + "offsetof mismatch for CompilationMessage::lineNum"); +static_assert(offsetof(CompilationMessage, linePos) == offsetof(WGPUCompilationMessage, linePos), + "offsetof mismatch for CompilationMessage::linePos"); +static_assert(offsetof(CompilationMessage, offset) == offsetof(WGPUCompilationMessage, offset), + "offsetof mismatch for CompilationMessage::offset"); +static_assert(offsetof(CompilationMessage, length) == offsetof(WGPUCompilationMessage, length), + "offsetof mismatch for CompilationMessage::length"); + +// ComputePassDescriptor implementation + +ComputePassDescriptor::operator const WGPUComputePassDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ComputePassDescriptor) == sizeof(WGPUComputePassDescriptor), "sizeof mismatch for ComputePassDescriptor"); +static_assert(alignof(ComputePassDescriptor) == alignof(WGPUComputePassDescriptor), "alignof mismatch for ComputePassDescriptor"); +static_assert(offsetof(ComputePassDescriptor, nextInChain) == offsetof(WGPUComputePassDescriptor, nextInChain), + "offsetof mismatch for ComputePassDescriptor::nextInChain"); +static_assert(offsetof(ComputePassDescriptor, label) == offsetof(WGPUComputePassDescriptor, label), + "offsetof mismatch for ComputePassDescriptor::label"); +static_assert(offsetof(ComputePassDescriptor, timestampWrites) == offsetof(WGPUComputePassDescriptor, timestampWrites), + "offsetof mismatch for ComputePassDescriptor::timestampWrites"); + +// ComputeState implementation + +ComputeState::operator const WGPUComputeState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ComputeState) == sizeof(WGPUComputeState), "sizeof mismatch for ComputeState"); +static_assert(alignof(ComputeState) == alignof(WGPUComputeState), "alignof mismatch for ComputeState"); +static_assert(offsetof(ComputeState, nextInChain) == offsetof(WGPUComputeState, nextInChain), + "offsetof mismatch for ComputeState::nextInChain"); +static_assert(offsetof(ComputeState, module) == offsetof(WGPUComputeState, module), + "offsetof mismatch for ComputeState::module"); +static_assert(offsetof(ComputeState, entryPoint) == offsetof(WGPUComputeState, entryPoint), + "offsetof mismatch for ComputeState::entryPoint"); +static_assert(offsetof(ComputeState, constantCount) == offsetof(WGPUComputeState, constantCount), + "offsetof mismatch for ComputeState::constantCount"); +static_assert(offsetof(ComputeState, constants) == offsetof(WGPUComputeState, constants), + "offsetof mismatch for ComputeState::constants"); + +// DepthStencilState implementation + +DepthStencilState::operator const WGPUDepthStencilState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(DepthStencilState) == sizeof(WGPUDepthStencilState), "sizeof mismatch for DepthStencilState"); +static_assert(alignof(DepthStencilState) == alignof(WGPUDepthStencilState), "alignof mismatch for DepthStencilState"); +static_assert(offsetof(DepthStencilState, nextInChain) == offsetof(WGPUDepthStencilState, nextInChain), + "offsetof mismatch for DepthStencilState::nextInChain"); +static_assert(offsetof(DepthStencilState, format) == offsetof(WGPUDepthStencilState, format), + "offsetof mismatch for DepthStencilState::format"); +static_assert(offsetof(DepthStencilState, depthWriteEnabled) == offsetof(WGPUDepthStencilState, depthWriteEnabled), + "offsetof mismatch for DepthStencilState::depthWriteEnabled"); +static_assert(offsetof(DepthStencilState, depthCompare) == offsetof(WGPUDepthStencilState, depthCompare), + "offsetof mismatch for DepthStencilState::depthCompare"); +static_assert(offsetof(DepthStencilState, stencilFront) == offsetof(WGPUDepthStencilState, stencilFront), + "offsetof mismatch for DepthStencilState::stencilFront"); +static_assert(offsetof(DepthStencilState, stencilBack) == offsetof(WGPUDepthStencilState, stencilBack), + "offsetof mismatch for DepthStencilState::stencilBack"); +static_assert(offsetof(DepthStencilState, stencilReadMask) == offsetof(WGPUDepthStencilState, stencilReadMask), + "offsetof mismatch for DepthStencilState::stencilReadMask"); +static_assert(offsetof(DepthStencilState, stencilWriteMask) == offsetof(WGPUDepthStencilState, stencilWriteMask), + "offsetof mismatch for DepthStencilState::stencilWriteMask"); +static_assert(offsetof(DepthStencilState, depthBias) == offsetof(WGPUDepthStencilState, depthBias), + "offsetof mismatch for DepthStencilState::depthBias"); +static_assert(offsetof(DepthStencilState, depthBiasSlopeScale) == offsetof(WGPUDepthStencilState, depthBiasSlopeScale), + "offsetof mismatch for DepthStencilState::depthBiasSlopeScale"); +static_assert(offsetof(DepthStencilState, depthBiasClamp) == offsetof(WGPUDepthStencilState, depthBiasClamp), + "offsetof mismatch for DepthStencilState::depthBiasClamp"); + +// FutureWaitInfo implementation + +FutureWaitInfo::operator const WGPUFutureWaitInfo&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(FutureWaitInfo) == sizeof(WGPUFutureWaitInfo), "sizeof mismatch for FutureWaitInfo"); +static_assert(alignof(FutureWaitInfo) == alignof(WGPUFutureWaitInfo), "alignof mismatch for FutureWaitInfo"); +static_assert(offsetof(FutureWaitInfo, future) == offsetof(WGPUFutureWaitInfo, future), + "offsetof mismatch for FutureWaitInfo::future"); +static_assert(offsetof(FutureWaitInfo, completed) == offsetof(WGPUFutureWaitInfo, completed), + "offsetof mismatch for FutureWaitInfo::completed"); + +// InstanceDescriptor implementation + +InstanceDescriptor::operator const WGPUInstanceDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(InstanceDescriptor) == sizeof(WGPUInstanceDescriptor), "sizeof mismatch for InstanceDescriptor"); +static_assert(alignof(InstanceDescriptor) == alignof(WGPUInstanceDescriptor), "alignof mismatch for InstanceDescriptor"); +static_assert(offsetof(InstanceDescriptor, nextInChain) == offsetof(WGPUInstanceDescriptor, nextInChain), + "offsetof mismatch for InstanceDescriptor::nextInChain"); +static_assert(offsetof(InstanceDescriptor, requiredFeatureCount) == offsetof(WGPUInstanceDescriptor, requiredFeatureCount), + "offsetof mismatch for InstanceDescriptor::requiredFeatureCount"); +static_assert(offsetof(InstanceDescriptor, requiredFeatures) == offsetof(WGPUInstanceDescriptor, requiredFeatures), + "offsetof mismatch for InstanceDescriptor::requiredFeatures"); +static_assert(offsetof(InstanceDescriptor, requiredLimits) == offsetof(WGPUInstanceDescriptor, requiredLimits), + "offsetof mismatch for InstanceDescriptor::requiredLimits"); + +// Limits implementation + +Limits::operator const WGPULimits&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(Limits) == sizeof(WGPULimits), "sizeof mismatch for Limits"); +static_assert(alignof(Limits) == alignof(WGPULimits), "alignof mismatch for Limits"); +static_assert(offsetof(Limits, nextInChain) == offsetof(WGPULimits, nextInChain), + "offsetof mismatch for Limits::nextInChain"); +static_assert(offsetof(Limits, maxTextureDimension1D) == offsetof(WGPULimits, maxTextureDimension1D), + "offsetof mismatch for Limits::maxTextureDimension1D"); +static_assert(offsetof(Limits, maxTextureDimension2D) == offsetof(WGPULimits, maxTextureDimension2D), + "offsetof mismatch for Limits::maxTextureDimension2D"); +static_assert(offsetof(Limits, maxTextureDimension3D) == offsetof(WGPULimits, maxTextureDimension3D), + "offsetof mismatch for Limits::maxTextureDimension3D"); +static_assert(offsetof(Limits, maxTextureArrayLayers) == offsetof(WGPULimits, maxTextureArrayLayers), + "offsetof mismatch for Limits::maxTextureArrayLayers"); +static_assert(offsetof(Limits, maxBindGroups) == offsetof(WGPULimits, maxBindGroups), + "offsetof mismatch for Limits::maxBindGroups"); +static_assert(offsetof(Limits, maxBindGroupsPlusVertexBuffers) == offsetof(WGPULimits, maxBindGroupsPlusVertexBuffers), + "offsetof mismatch for Limits::maxBindGroupsPlusVertexBuffers"); +static_assert(offsetof(Limits, maxBindingsPerBindGroup) == offsetof(WGPULimits, maxBindingsPerBindGroup), + "offsetof mismatch for Limits::maxBindingsPerBindGroup"); +static_assert(offsetof(Limits, maxDynamicUniformBuffersPerPipelineLayout) == offsetof(WGPULimits, maxDynamicUniformBuffersPerPipelineLayout), + "offsetof mismatch for Limits::maxDynamicUniformBuffersPerPipelineLayout"); +static_assert(offsetof(Limits, maxDynamicStorageBuffersPerPipelineLayout) == offsetof(WGPULimits, maxDynamicStorageBuffersPerPipelineLayout), + "offsetof mismatch for Limits::maxDynamicStorageBuffersPerPipelineLayout"); +static_assert(offsetof(Limits, maxSampledTexturesPerShaderStage) == offsetof(WGPULimits, maxSampledTexturesPerShaderStage), + "offsetof mismatch for Limits::maxSampledTexturesPerShaderStage"); +static_assert(offsetof(Limits, maxSamplersPerShaderStage) == offsetof(WGPULimits, maxSamplersPerShaderStage), + "offsetof mismatch for Limits::maxSamplersPerShaderStage"); +static_assert(offsetof(Limits, maxStorageBuffersPerShaderStage) == offsetof(WGPULimits, maxStorageBuffersPerShaderStage), + "offsetof mismatch for Limits::maxStorageBuffersPerShaderStage"); +static_assert(offsetof(Limits, maxStorageTexturesPerShaderStage) == offsetof(WGPULimits, maxStorageTexturesPerShaderStage), + "offsetof mismatch for Limits::maxStorageTexturesPerShaderStage"); +static_assert(offsetof(Limits, maxUniformBuffersPerShaderStage) == offsetof(WGPULimits, maxUniformBuffersPerShaderStage), + "offsetof mismatch for Limits::maxUniformBuffersPerShaderStage"); +static_assert(offsetof(Limits, maxUniformBufferBindingSize) == offsetof(WGPULimits, maxUniformBufferBindingSize), + "offsetof mismatch for Limits::maxUniformBufferBindingSize"); +static_assert(offsetof(Limits, maxStorageBufferBindingSize) == offsetof(WGPULimits, maxStorageBufferBindingSize), + "offsetof mismatch for Limits::maxStorageBufferBindingSize"); +static_assert(offsetof(Limits, minUniformBufferOffsetAlignment) == offsetof(WGPULimits, minUniformBufferOffsetAlignment), + "offsetof mismatch for Limits::minUniformBufferOffsetAlignment"); +static_assert(offsetof(Limits, minStorageBufferOffsetAlignment) == offsetof(WGPULimits, minStorageBufferOffsetAlignment), + "offsetof mismatch for Limits::minStorageBufferOffsetAlignment"); +static_assert(offsetof(Limits, maxVertexBuffers) == offsetof(WGPULimits, maxVertexBuffers), + "offsetof mismatch for Limits::maxVertexBuffers"); +static_assert(offsetof(Limits, maxBufferSize) == offsetof(WGPULimits, maxBufferSize), + "offsetof mismatch for Limits::maxBufferSize"); +static_assert(offsetof(Limits, maxVertexAttributes) == offsetof(WGPULimits, maxVertexAttributes), + "offsetof mismatch for Limits::maxVertexAttributes"); +static_assert(offsetof(Limits, maxVertexBufferArrayStride) == offsetof(WGPULimits, maxVertexBufferArrayStride), + "offsetof mismatch for Limits::maxVertexBufferArrayStride"); +static_assert(offsetof(Limits, maxInterStageShaderVariables) == offsetof(WGPULimits, maxInterStageShaderVariables), + "offsetof mismatch for Limits::maxInterStageShaderVariables"); +static_assert(offsetof(Limits, maxColorAttachments) == offsetof(WGPULimits, maxColorAttachments), + "offsetof mismatch for Limits::maxColorAttachments"); +static_assert(offsetof(Limits, maxColorAttachmentBytesPerSample) == offsetof(WGPULimits, maxColorAttachmentBytesPerSample), + "offsetof mismatch for Limits::maxColorAttachmentBytesPerSample"); +static_assert(offsetof(Limits, maxComputeWorkgroupStorageSize) == offsetof(WGPULimits, maxComputeWorkgroupStorageSize), + "offsetof mismatch for Limits::maxComputeWorkgroupStorageSize"); +static_assert(offsetof(Limits, maxComputeInvocationsPerWorkgroup) == offsetof(WGPULimits, maxComputeInvocationsPerWorkgroup), + "offsetof mismatch for Limits::maxComputeInvocationsPerWorkgroup"); +static_assert(offsetof(Limits, maxComputeWorkgroupSizeX) == offsetof(WGPULimits, maxComputeWorkgroupSizeX), + "offsetof mismatch for Limits::maxComputeWorkgroupSizeX"); +static_assert(offsetof(Limits, maxComputeWorkgroupSizeY) == offsetof(WGPULimits, maxComputeWorkgroupSizeY), + "offsetof mismatch for Limits::maxComputeWorkgroupSizeY"); +static_assert(offsetof(Limits, maxComputeWorkgroupSizeZ) == offsetof(WGPULimits, maxComputeWorkgroupSizeZ), + "offsetof mismatch for Limits::maxComputeWorkgroupSizeZ"); +static_assert(offsetof(Limits, maxComputeWorkgroupsPerDimension) == offsetof(WGPULimits, maxComputeWorkgroupsPerDimension), + "offsetof mismatch for Limits::maxComputeWorkgroupsPerDimension"); +static_assert(offsetof(Limits, maxImmediateSize) == offsetof(WGPULimits, maxImmediateSize), + "offsetof mismatch for Limits::maxImmediateSize"); + +// RenderPassColorAttachment implementation + +RenderPassColorAttachment::operator const WGPURenderPassColorAttachment&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderPassColorAttachment) == sizeof(WGPURenderPassColorAttachment), "sizeof mismatch for RenderPassColorAttachment"); +static_assert(alignof(RenderPassColorAttachment) == alignof(WGPURenderPassColorAttachment), "alignof mismatch for RenderPassColorAttachment"); +static_assert(offsetof(RenderPassColorAttachment, nextInChain) == offsetof(WGPURenderPassColorAttachment, nextInChain), + "offsetof mismatch for RenderPassColorAttachment::nextInChain"); +static_assert(offsetof(RenderPassColorAttachment, view) == offsetof(WGPURenderPassColorAttachment, view), + "offsetof mismatch for RenderPassColorAttachment::view"); +static_assert(offsetof(RenderPassColorAttachment, depthSlice) == offsetof(WGPURenderPassColorAttachment, depthSlice), + "offsetof mismatch for RenderPassColorAttachment::depthSlice"); +static_assert(offsetof(RenderPassColorAttachment, resolveTarget) == offsetof(WGPURenderPassColorAttachment, resolveTarget), + "offsetof mismatch for RenderPassColorAttachment::resolveTarget"); +static_assert(offsetof(RenderPassColorAttachment, loadOp) == offsetof(WGPURenderPassColorAttachment, loadOp), + "offsetof mismatch for RenderPassColorAttachment::loadOp"); +static_assert(offsetof(RenderPassColorAttachment, storeOp) == offsetof(WGPURenderPassColorAttachment, storeOp), + "offsetof mismatch for RenderPassColorAttachment::storeOp"); +static_assert(offsetof(RenderPassColorAttachment, clearValue) == offsetof(WGPURenderPassColorAttachment, clearValue), + "offsetof mismatch for RenderPassColorAttachment::clearValue"); + +// RequestAdapterOptions implementation + +RequestAdapterOptions::operator const WGPURequestAdapterOptions&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RequestAdapterOptions) == sizeof(WGPURequestAdapterOptions), "sizeof mismatch for RequestAdapterOptions"); +static_assert(alignof(RequestAdapterOptions) == alignof(WGPURequestAdapterOptions), "alignof mismatch for RequestAdapterOptions"); +static_assert(offsetof(RequestAdapterOptions, nextInChain) == offsetof(WGPURequestAdapterOptions, nextInChain), + "offsetof mismatch for RequestAdapterOptions::nextInChain"); +static_assert(offsetof(RequestAdapterOptions, featureLevel) == offsetof(WGPURequestAdapterOptions, featureLevel), + "offsetof mismatch for RequestAdapterOptions::featureLevel"); +static_assert(offsetof(RequestAdapterOptions, powerPreference) == offsetof(WGPURequestAdapterOptions, powerPreference), + "offsetof mismatch for RequestAdapterOptions::powerPreference"); +static_assert(offsetof(RequestAdapterOptions, forceFallbackAdapter) == offsetof(WGPURequestAdapterOptions, forceFallbackAdapter), + "offsetof mismatch for RequestAdapterOptions::forceFallbackAdapter"); +static_assert(offsetof(RequestAdapterOptions, backendType) == offsetof(WGPURequestAdapterOptions, backendType), + "offsetof mismatch for RequestAdapterOptions::backendType"); +static_assert(offsetof(RequestAdapterOptions, compatibleSurface) == offsetof(WGPURequestAdapterOptions, compatibleSurface), + "offsetof mismatch for RequestAdapterOptions::compatibleSurface"); + +// ShaderModuleDescriptor implementation + +ShaderModuleDescriptor::operator const WGPUShaderModuleDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ShaderModuleDescriptor) == sizeof(WGPUShaderModuleDescriptor), "sizeof mismatch for ShaderModuleDescriptor"); +static_assert(alignof(ShaderModuleDescriptor) == alignof(WGPUShaderModuleDescriptor), "alignof mismatch for ShaderModuleDescriptor"); +static_assert(offsetof(ShaderModuleDescriptor, nextInChain) == offsetof(WGPUShaderModuleDescriptor, nextInChain), + "offsetof mismatch for ShaderModuleDescriptor::nextInChain"); +static_assert(offsetof(ShaderModuleDescriptor, label) == offsetof(WGPUShaderModuleDescriptor, label), + "offsetof mismatch for ShaderModuleDescriptor::label"); + +// SurfaceDescriptor implementation + +SurfaceDescriptor::operator const WGPUSurfaceDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(SurfaceDescriptor) == sizeof(WGPUSurfaceDescriptor), "sizeof mismatch for SurfaceDescriptor"); +static_assert(alignof(SurfaceDescriptor) == alignof(WGPUSurfaceDescriptor), "alignof mismatch for SurfaceDescriptor"); +static_assert(offsetof(SurfaceDescriptor, nextInChain) == offsetof(WGPUSurfaceDescriptor, nextInChain), + "offsetof mismatch for SurfaceDescriptor::nextInChain"); +static_assert(offsetof(SurfaceDescriptor, label) == offsetof(WGPUSurfaceDescriptor, label), + "offsetof mismatch for SurfaceDescriptor::label"); + +// TexelCopyBufferInfo implementation + +TexelCopyBufferInfo::operator const WGPUTexelCopyBufferInfo&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TexelCopyBufferInfo) == sizeof(WGPUTexelCopyBufferInfo), "sizeof mismatch for TexelCopyBufferInfo"); +static_assert(alignof(TexelCopyBufferInfo) == alignof(WGPUTexelCopyBufferInfo), "alignof mismatch for TexelCopyBufferInfo"); +static_assert(offsetof(TexelCopyBufferInfo, layout) == offsetof(WGPUTexelCopyBufferInfo, layout), + "offsetof mismatch for TexelCopyBufferInfo::layout"); +static_assert(offsetof(TexelCopyBufferInfo, buffer) == offsetof(WGPUTexelCopyBufferInfo, buffer), + "offsetof mismatch for TexelCopyBufferInfo::buffer"); + +// TexelCopyTextureInfo implementation + +TexelCopyTextureInfo::operator const WGPUTexelCopyTextureInfo&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TexelCopyTextureInfo) == sizeof(WGPUTexelCopyTextureInfo), "sizeof mismatch for TexelCopyTextureInfo"); +static_assert(alignof(TexelCopyTextureInfo) == alignof(WGPUTexelCopyTextureInfo), "alignof mismatch for TexelCopyTextureInfo"); +static_assert(offsetof(TexelCopyTextureInfo, texture) == offsetof(WGPUTexelCopyTextureInfo, texture), + "offsetof mismatch for TexelCopyTextureInfo::texture"); +static_assert(offsetof(TexelCopyTextureInfo, mipLevel) == offsetof(WGPUTexelCopyTextureInfo, mipLevel), + "offsetof mismatch for TexelCopyTextureInfo::mipLevel"); +static_assert(offsetof(TexelCopyTextureInfo, origin) == offsetof(WGPUTexelCopyTextureInfo, origin), + "offsetof mismatch for TexelCopyTextureInfo::origin"); +static_assert(offsetof(TexelCopyTextureInfo, aspect) == offsetof(WGPUTexelCopyTextureInfo, aspect), + "offsetof mismatch for TexelCopyTextureInfo::aspect"); + +// TextureComponentSwizzleDescriptor implementation +TextureComponentSwizzleDescriptor::TextureComponentSwizzleDescriptor() + : ChainedStruct { nullptr, SType::TextureComponentSwizzleDescriptor } {} +struct TextureComponentSwizzleDescriptor::Init { + ChainedStruct * const nextInChain; + TextureComponentSwizzle swizzle = {}; +}; +TextureComponentSwizzleDescriptor::TextureComponentSwizzleDescriptor(TextureComponentSwizzleDescriptor::Init&& init) + : ChainedStruct { init.nextInChain, SType::TextureComponentSwizzleDescriptor }, + swizzle(std::move(init.swizzle)){} + +TextureComponentSwizzleDescriptor::operator const WGPUTextureComponentSwizzleDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TextureComponentSwizzleDescriptor) == sizeof(WGPUTextureComponentSwizzleDescriptor), "sizeof mismatch for TextureComponentSwizzleDescriptor"); +static_assert(alignof(TextureComponentSwizzleDescriptor) == alignof(WGPUTextureComponentSwizzleDescriptor), "alignof mismatch for TextureComponentSwizzleDescriptor"); +static_assert(offsetof(TextureComponentSwizzleDescriptor, swizzle) == offsetof(WGPUTextureComponentSwizzleDescriptor, swizzle), + "offsetof mismatch for TextureComponentSwizzleDescriptor::swizzle"); + +// TextureDescriptor implementation + +TextureDescriptor::operator const WGPUTextureDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TextureDescriptor) == sizeof(WGPUTextureDescriptor), "sizeof mismatch for TextureDescriptor"); +static_assert(alignof(TextureDescriptor) == alignof(WGPUTextureDescriptor), "alignof mismatch for TextureDescriptor"); +static_assert(offsetof(TextureDescriptor, nextInChain) == offsetof(WGPUTextureDescriptor, nextInChain), + "offsetof mismatch for TextureDescriptor::nextInChain"); +static_assert(offsetof(TextureDescriptor, label) == offsetof(WGPUTextureDescriptor, label), + "offsetof mismatch for TextureDescriptor::label"); +static_assert(offsetof(TextureDescriptor, usage) == offsetof(WGPUTextureDescriptor, usage), + "offsetof mismatch for TextureDescriptor::usage"); +static_assert(offsetof(TextureDescriptor, dimension) == offsetof(WGPUTextureDescriptor, dimension), + "offsetof mismatch for TextureDescriptor::dimension"); +static_assert(offsetof(TextureDescriptor, size) == offsetof(WGPUTextureDescriptor, size), + "offsetof mismatch for TextureDescriptor::size"); +static_assert(offsetof(TextureDescriptor, format) == offsetof(WGPUTextureDescriptor, format), + "offsetof mismatch for TextureDescriptor::format"); +static_assert(offsetof(TextureDescriptor, mipLevelCount) == offsetof(WGPUTextureDescriptor, mipLevelCount), + "offsetof mismatch for TextureDescriptor::mipLevelCount"); +static_assert(offsetof(TextureDescriptor, sampleCount) == offsetof(WGPUTextureDescriptor, sampleCount), + "offsetof mismatch for TextureDescriptor::sampleCount"); +static_assert(offsetof(TextureDescriptor, viewFormatCount) == offsetof(WGPUTextureDescriptor, viewFormatCount), + "offsetof mismatch for TextureDescriptor::viewFormatCount"); +static_assert(offsetof(TextureDescriptor, viewFormats) == offsetof(WGPUTextureDescriptor, viewFormats), + "offsetof mismatch for TextureDescriptor::viewFormats"); + +// VertexBufferLayout implementation + +VertexBufferLayout::operator const WGPUVertexBufferLayout&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(VertexBufferLayout) == sizeof(WGPUVertexBufferLayout), "sizeof mismatch for VertexBufferLayout"); +static_assert(alignof(VertexBufferLayout) == alignof(WGPUVertexBufferLayout), "alignof mismatch for VertexBufferLayout"); +static_assert(offsetof(VertexBufferLayout, nextInChain) == offsetof(WGPUVertexBufferLayout, nextInChain), + "offsetof mismatch for VertexBufferLayout::nextInChain"); +static_assert(offsetof(VertexBufferLayout, stepMode) == offsetof(WGPUVertexBufferLayout, stepMode), + "offsetof mismatch for VertexBufferLayout::stepMode"); +static_assert(offsetof(VertexBufferLayout, arrayStride) == offsetof(WGPUVertexBufferLayout, arrayStride), + "offsetof mismatch for VertexBufferLayout::arrayStride"); +static_assert(offsetof(VertexBufferLayout, attributeCount) == offsetof(WGPUVertexBufferLayout, attributeCount), + "offsetof mismatch for VertexBufferLayout::attributeCount"); +static_assert(offsetof(VertexBufferLayout, attributes) == offsetof(WGPUVertexBufferLayout, attributes), + "offsetof mismatch for VertexBufferLayout::attributes"); + +// BindGroupLayoutDescriptor implementation + +BindGroupLayoutDescriptor::operator const WGPUBindGroupLayoutDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(BindGroupLayoutDescriptor) == sizeof(WGPUBindGroupLayoutDescriptor), "sizeof mismatch for BindGroupLayoutDescriptor"); +static_assert(alignof(BindGroupLayoutDescriptor) == alignof(WGPUBindGroupLayoutDescriptor), "alignof mismatch for BindGroupLayoutDescriptor"); +static_assert(offsetof(BindGroupLayoutDescriptor, nextInChain) == offsetof(WGPUBindGroupLayoutDescriptor, nextInChain), + "offsetof mismatch for BindGroupLayoutDescriptor::nextInChain"); +static_assert(offsetof(BindGroupLayoutDescriptor, label) == offsetof(WGPUBindGroupLayoutDescriptor, label), + "offsetof mismatch for BindGroupLayoutDescriptor::label"); +static_assert(offsetof(BindGroupLayoutDescriptor, entryCount) == offsetof(WGPUBindGroupLayoutDescriptor, entryCount), + "offsetof mismatch for BindGroupLayoutDescriptor::entryCount"); +static_assert(offsetof(BindGroupLayoutDescriptor, entries) == offsetof(WGPUBindGroupLayoutDescriptor, entries), + "offsetof mismatch for BindGroupLayoutDescriptor::entries"); + +// ColorTargetState implementation + +ColorTargetState::operator const WGPUColorTargetState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ColorTargetState) == sizeof(WGPUColorTargetState), "sizeof mismatch for ColorTargetState"); +static_assert(alignof(ColorTargetState) == alignof(WGPUColorTargetState), "alignof mismatch for ColorTargetState"); +static_assert(offsetof(ColorTargetState, nextInChain) == offsetof(WGPUColorTargetState, nextInChain), + "offsetof mismatch for ColorTargetState::nextInChain"); +static_assert(offsetof(ColorTargetState, format) == offsetof(WGPUColorTargetState, format), + "offsetof mismatch for ColorTargetState::format"); +static_assert(offsetof(ColorTargetState, blend) == offsetof(WGPUColorTargetState, blend), + "offsetof mismatch for ColorTargetState::blend"); +static_assert(offsetof(ColorTargetState, writeMask) == offsetof(WGPUColorTargetState, writeMask), + "offsetof mismatch for ColorTargetState::writeMask"); + +// CompilationInfo implementation + +CompilationInfo::operator const WGPUCompilationInfo&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(CompilationInfo) == sizeof(WGPUCompilationInfo), "sizeof mismatch for CompilationInfo"); +static_assert(alignof(CompilationInfo) == alignof(WGPUCompilationInfo), "alignof mismatch for CompilationInfo"); +static_assert(offsetof(CompilationInfo, nextInChain) == offsetof(WGPUCompilationInfo, nextInChain), + "offsetof mismatch for CompilationInfo::nextInChain"); +static_assert(offsetof(CompilationInfo, messageCount) == offsetof(WGPUCompilationInfo, messageCount), + "offsetof mismatch for CompilationInfo::messageCount"); +static_assert(offsetof(CompilationInfo, messages) == offsetof(WGPUCompilationInfo, messages), + "offsetof mismatch for CompilationInfo::messages"); + +// ComputePipelineDescriptor implementation + +ComputePipelineDescriptor::operator const WGPUComputePipelineDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(ComputePipelineDescriptor) == sizeof(WGPUComputePipelineDescriptor), "sizeof mismatch for ComputePipelineDescriptor"); +static_assert(alignof(ComputePipelineDescriptor) == alignof(WGPUComputePipelineDescriptor), "alignof mismatch for ComputePipelineDescriptor"); +static_assert(offsetof(ComputePipelineDescriptor, nextInChain) == offsetof(WGPUComputePipelineDescriptor, nextInChain), + "offsetof mismatch for ComputePipelineDescriptor::nextInChain"); +static_assert(offsetof(ComputePipelineDescriptor, label) == offsetof(WGPUComputePipelineDescriptor, label), + "offsetof mismatch for ComputePipelineDescriptor::label"); +static_assert(offsetof(ComputePipelineDescriptor, layout) == offsetof(WGPUComputePipelineDescriptor, layout), + "offsetof mismatch for ComputePipelineDescriptor::layout"); +static_assert(offsetof(ComputePipelineDescriptor, compute) == offsetof(WGPUComputePipelineDescriptor, compute), + "offsetof mismatch for ComputePipelineDescriptor::compute"); + +// RenderPassDescriptor implementation + +RenderPassDescriptor::operator const WGPURenderPassDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderPassDescriptor) == sizeof(WGPURenderPassDescriptor), "sizeof mismatch for RenderPassDescriptor"); +static_assert(alignof(RenderPassDescriptor) == alignof(WGPURenderPassDescriptor), "alignof mismatch for RenderPassDescriptor"); +static_assert(offsetof(RenderPassDescriptor, nextInChain) == offsetof(WGPURenderPassDescriptor, nextInChain), + "offsetof mismatch for RenderPassDescriptor::nextInChain"); +static_assert(offsetof(RenderPassDescriptor, label) == offsetof(WGPURenderPassDescriptor, label), + "offsetof mismatch for RenderPassDescriptor::label"); +static_assert(offsetof(RenderPassDescriptor, colorAttachmentCount) == offsetof(WGPURenderPassDescriptor, colorAttachmentCount), + "offsetof mismatch for RenderPassDescriptor::colorAttachmentCount"); +static_assert(offsetof(RenderPassDescriptor, colorAttachments) == offsetof(WGPURenderPassDescriptor, colorAttachments), + "offsetof mismatch for RenderPassDescriptor::colorAttachments"); +static_assert(offsetof(RenderPassDescriptor, depthStencilAttachment) == offsetof(WGPURenderPassDescriptor, depthStencilAttachment), + "offsetof mismatch for RenderPassDescriptor::depthStencilAttachment"); +static_assert(offsetof(RenderPassDescriptor, occlusionQuerySet) == offsetof(WGPURenderPassDescriptor, occlusionQuerySet), + "offsetof mismatch for RenderPassDescriptor::occlusionQuerySet"); +static_assert(offsetof(RenderPassDescriptor, timestampWrites) == offsetof(WGPURenderPassDescriptor, timestampWrites), + "offsetof mismatch for RenderPassDescriptor::timestampWrites"); + +// TextureViewDescriptor implementation + +TextureViewDescriptor::operator const WGPUTextureViewDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(TextureViewDescriptor) == sizeof(WGPUTextureViewDescriptor), "sizeof mismatch for TextureViewDescriptor"); +static_assert(alignof(TextureViewDescriptor) == alignof(WGPUTextureViewDescriptor), "alignof mismatch for TextureViewDescriptor"); +static_assert(offsetof(TextureViewDescriptor, nextInChain) == offsetof(WGPUTextureViewDescriptor, nextInChain), + "offsetof mismatch for TextureViewDescriptor::nextInChain"); +static_assert(offsetof(TextureViewDescriptor, label) == offsetof(WGPUTextureViewDescriptor, label), + "offsetof mismatch for TextureViewDescriptor::label"); +static_assert(offsetof(TextureViewDescriptor, format) == offsetof(WGPUTextureViewDescriptor, format), + "offsetof mismatch for TextureViewDescriptor::format"); +static_assert(offsetof(TextureViewDescriptor, dimension) == offsetof(WGPUTextureViewDescriptor, dimension), + "offsetof mismatch for TextureViewDescriptor::dimension"); +static_assert(offsetof(TextureViewDescriptor, baseMipLevel) == offsetof(WGPUTextureViewDescriptor, baseMipLevel), + "offsetof mismatch for TextureViewDescriptor::baseMipLevel"); +static_assert(offsetof(TextureViewDescriptor, mipLevelCount) == offsetof(WGPUTextureViewDescriptor, mipLevelCount), + "offsetof mismatch for TextureViewDescriptor::mipLevelCount"); +static_assert(offsetof(TextureViewDescriptor, baseArrayLayer) == offsetof(WGPUTextureViewDescriptor, baseArrayLayer), + "offsetof mismatch for TextureViewDescriptor::baseArrayLayer"); +static_assert(offsetof(TextureViewDescriptor, arrayLayerCount) == offsetof(WGPUTextureViewDescriptor, arrayLayerCount), + "offsetof mismatch for TextureViewDescriptor::arrayLayerCount"); +static_assert(offsetof(TextureViewDescriptor, aspect) == offsetof(WGPUTextureViewDescriptor, aspect), + "offsetof mismatch for TextureViewDescriptor::aspect"); +static_assert(offsetof(TextureViewDescriptor, usage) == offsetof(WGPUTextureViewDescriptor, usage), + "offsetof mismatch for TextureViewDescriptor::usage"); + +// VertexState implementation + +VertexState::operator const WGPUVertexState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(VertexState) == sizeof(WGPUVertexState), "sizeof mismatch for VertexState"); +static_assert(alignof(VertexState) == alignof(WGPUVertexState), "alignof mismatch for VertexState"); +static_assert(offsetof(VertexState, nextInChain) == offsetof(WGPUVertexState, nextInChain), + "offsetof mismatch for VertexState::nextInChain"); +static_assert(offsetof(VertexState, module) == offsetof(WGPUVertexState, module), + "offsetof mismatch for VertexState::module"); +static_assert(offsetof(VertexState, entryPoint) == offsetof(WGPUVertexState, entryPoint), + "offsetof mismatch for VertexState::entryPoint"); +static_assert(offsetof(VertexState, constantCount) == offsetof(WGPUVertexState, constantCount), + "offsetof mismatch for VertexState::constantCount"); +static_assert(offsetof(VertexState, constants) == offsetof(WGPUVertexState, constants), + "offsetof mismatch for VertexState::constants"); +static_assert(offsetof(VertexState, bufferCount) == offsetof(WGPUVertexState, bufferCount), + "offsetof mismatch for VertexState::bufferCount"); +static_assert(offsetof(VertexState, buffers) == offsetof(WGPUVertexState, buffers), + "offsetof mismatch for VertexState::buffers"); + +// FragmentState implementation + +FragmentState::operator const WGPUFragmentState&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(FragmentState) == sizeof(WGPUFragmentState), "sizeof mismatch for FragmentState"); +static_assert(alignof(FragmentState) == alignof(WGPUFragmentState), "alignof mismatch for FragmentState"); +static_assert(offsetof(FragmentState, nextInChain) == offsetof(WGPUFragmentState, nextInChain), + "offsetof mismatch for FragmentState::nextInChain"); +static_assert(offsetof(FragmentState, module) == offsetof(WGPUFragmentState, module), + "offsetof mismatch for FragmentState::module"); +static_assert(offsetof(FragmentState, entryPoint) == offsetof(WGPUFragmentState, entryPoint), + "offsetof mismatch for FragmentState::entryPoint"); +static_assert(offsetof(FragmentState, constantCount) == offsetof(WGPUFragmentState, constantCount), + "offsetof mismatch for FragmentState::constantCount"); +static_assert(offsetof(FragmentState, constants) == offsetof(WGPUFragmentState, constants), + "offsetof mismatch for FragmentState::constants"); +static_assert(offsetof(FragmentState, targetCount) == offsetof(WGPUFragmentState, targetCount), + "offsetof mismatch for FragmentState::targetCount"); +static_assert(offsetof(FragmentState, targets) == offsetof(WGPUFragmentState, targets), + "offsetof mismatch for FragmentState::targets"); + +// RenderPipelineDescriptor implementation + +RenderPipelineDescriptor::operator const WGPURenderPipelineDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +static_assert(sizeof(RenderPipelineDescriptor) == sizeof(WGPURenderPipelineDescriptor), "sizeof mismatch for RenderPipelineDescriptor"); +static_assert(alignof(RenderPipelineDescriptor) == alignof(WGPURenderPipelineDescriptor), "alignof mismatch for RenderPipelineDescriptor"); +static_assert(offsetof(RenderPipelineDescriptor, nextInChain) == offsetof(WGPURenderPipelineDescriptor, nextInChain), + "offsetof mismatch for RenderPipelineDescriptor::nextInChain"); +static_assert(offsetof(RenderPipelineDescriptor, label) == offsetof(WGPURenderPipelineDescriptor, label), + "offsetof mismatch for RenderPipelineDescriptor::label"); +static_assert(offsetof(RenderPipelineDescriptor, layout) == offsetof(WGPURenderPipelineDescriptor, layout), + "offsetof mismatch for RenderPipelineDescriptor::layout"); +static_assert(offsetof(RenderPipelineDescriptor, vertex) == offsetof(WGPURenderPipelineDescriptor, vertex), + "offsetof mismatch for RenderPipelineDescriptor::vertex"); +static_assert(offsetof(RenderPipelineDescriptor, primitive) == offsetof(WGPURenderPipelineDescriptor, primitive), + "offsetof mismatch for RenderPipelineDescriptor::primitive"); +static_assert(offsetof(RenderPipelineDescriptor, depthStencil) == offsetof(WGPURenderPipelineDescriptor, depthStencil), + "offsetof mismatch for RenderPipelineDescriptor::depthStencil"); +static_assert(offsetof(RenderPipelineDescriptor, multisample) == offsetof(WGPURenderPipelineDescriptor, multisample), + "offsetof mismatch for RenderPipelineDescriptor::multisample"); +static_assert(offsetof(RenderPipelineDescriptor, fragment) == offsetof(WGPURenderPipelineDescriptor, fragment), + "offsetof mismatch for RenderPipelineDescriptor::fragment"); + +// DeviceDescriptor implementation + +DeviceDescriptor::operator const WGPUDeviceDescriptor&() const noexcept { + return *reinterpret_cast(this); +} + +DeviceDescriptor::DeviceDescriptor() : detail::DeviceDescriptor {} { + static_assert(offsetof(DeviceDescriptor, nextInChain) == offsetof(WGPUDeviceDescriptor, nextInChain), + "offsetof mismatch for DeviceDescriptor::nextInChain"); + static_assert(offsetof(DeviceDescriptor, label) == offsetof(WGPUDeviceDescriptor, label), + "offsetof mismatch for DeviceDescriptor::label"); + static_assert(offsetof(DeviceDescriptor, requiredFeatureCount) == offsetof(WGPUDeviceDescriptor, requiredFeatureCount), + "offsetof mismatch for DeviceDescriptor::requiredFeatureCount"); + static_assert(offsetof(DeviceDescriptor, requiredFeatures) == offsetof(WGPUDeviceDescriptor, requiredFeatures), + "offsetof mismatch for DeviceDescriptor::requiredFeatures"); + static_assert(offsetof(DeviceDescriptor, requiredLimits) == offsetof(WGPUDeviceDescriptor, requiredLimits), + "offsetof mismatch for DeviceDescriptor::requiredLimits"); + static_assert(offsetof(DeviceDescriptor, defaultQueue) == offsetof(WGPUDeviceDescriptor, defaultQueue), + "offsetof mismatch for DeviceDescriptor::defaultQueue"); + static_assert(offsetof(DeviceDescriptor, deviceLostCallbackInfo) == offsetof(WGPUDeviceDescriptor, deviceLostCallbackInfo), + "offsetof mismatch for DeviceDescriptor::deviceLostCallbackInfo"); + static_assert(offsetof(DeviceDescriptor, uncapturedErrorCallbackInfo) == offsetof(WGPUDeviceDescriptor, uncapturedErrorCallbackInfo), + "offsetof mismatch for DeviceDescriptor::uncapturedErrorCallbackInfo"); +} + +struct DeviceDescriptor::Init { + ChainedStruct const * nextInChain; + StringView label = {}; + size_t requiredFeatureCount = 0; + FeatureName const * requiredFeatures = nullptr; + Limits const * requiredLimits = nullptr; + QueueDescriptor defaultQueue = {}; +}; + +DeviceDescriptor::DeviceDescriptor(DeviceDescriptor::Init&& init) : detail::DeviceDescriptor { + init.nextInChain, + std::move(init.label), + std::move(init.requiredFeatureCount), + std::move(init.requiredFeatures), + std::move(init.requiredLimits), + std::move(init.defaultQueue)} {} + +static_assert(sizeof(DeviceDescriptor) == sizeof(WGPUDeviceDescriptor), "sizeof mismatch for DeviceDescriptor"); +static_assert(alignof(DeviceDescriptor) == alignof(WGPUDeviceDescriptor), "alignof mismatch for DeviceDescriptor"); + +template +void DeviceDescriptor::SetDeviceLostCallback(CallbackMode callbackMode, F callback, T userdata) { + assert(deviceLostCallbackInfo.callback == nullptr); + + deviceLostCallbackInfo.mode = static_cast(callbackMode); + deviceLostCallbackInfo.callback = [](WGPUDevice const * device, WGPUDeviceLostReason reason, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + // We manually acquire and release the device to avoid changing any ref counts. + auto apiDevice = Device::Acquire(*device); + (*cb)(apiDevice, static_cast(reason), message, static_cast(userdata_param)); + apiDevice.MoveToCHandle(); + }; + deviceLostCallbackInfo.userdata1 = reinterpret_cast(+callback); + deviceLostCallbackInfo.userdata2 = reinterpret_cast(userdata); +} + +template +void DeviceDescriptor::SetDeviceLostCallback(CallbackMode callbackMode, L callback) { + assert(deviceLostCallbackInfo.callback == nullptr); + using F = DeviceLostCallback; + + deviceLostCallbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + deviceLostCallbackInfo.callback = [](WGPUDevice const * device, WGPUDeviceLostReason reason, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + // We manually acquire and release the device to avoid changing any ref counts. + auto apiDevice = Device::Acquire(*device); + (*cb)(apiDevice, static_cast(reason), message); + apiDevice.MoveToCHandle(); + }; + deviceLostCallbackInfo.userdata1 = reinterpret_cast(+callback); + deviceLostCallbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + deviceLostCallbackInfo.callback = [](WGPUDevice const * device, WGPUDeviceLostReason reason, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + // We manually acquire and release the device to avoid changing any ref counts. + auto apiDevice = Device::Acquire(*device); + (*the_lambda)(apiDevice, static_cast(reason), message); + apiDevice.MoveToCHandle(); + }; + deviceLostCallbackInfo.userdata1 = reinterpret_cast(lambda); + deviceLostCallbackInfo.userdata2 = nullptr; + } +} + +template +void DeviceDescriptor::SetUncapturedErrorCallback(F callback, T userdata) { + assert(uncapturedErrorCallbackInfo.callback == nullptr); + + uncapturedErrorCallbackInfo.callback = [](WGPUDevice const * device, WGPUErrorType type, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + // We manually acquire and release the device to avoid changing any ref counts. + auto apiDevice = Device::Acquire(*device); + (*cb)(apiDevice, static_cast(type), message, static_cast(userdata_param)); + apiDevice.MoveToCHandle(); + }; + uncapturedErrorCallbackInfo.userdata1 = reinterpret_cast(+callback); + uncapturedErrorCallbackInfo.userdata2 = reinterpret_cast(userdata); +} + +template +void DeviceDescriptor::SetUncapturedErrorCallback(L callback) { + assert(uncapturedErrorCallbackInfo.callback == nullptr); + using F = UncapturedErrorCallback; + static_assert(std::is_convertible_v, "Uncaptured error callback cannot be a binding lambda"); + + uncapturedErrorCallbackInfo.callback = [](WGPUDevice const * device, WGPUErrorType type, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + // We manually acquire and release the device to avoid changing any ref counts. + auto apiDevice = Device::Acquire(*device); + (*cb)(apiDevice, static_cast(type), message); + apiDevice.MoveToCHandle(); + }; + uncapturedErrorCallbackInfo.userdata1 = reinterpret_cast(+callback); + uncapturedErrorCallbackInfo.userdata2 = nullptr; +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +// Adapter implementation + +void Adapter::GetFeatures(SupportedFeatures * features) const { + *features = SupportedFeatures(); + wgpuAdapterGetFeatures(Get(), reinterpret_cast(features)); +} +ConvertibleStatus Adapter::GetInfo(AdapterInfo * info) const { + *info = AdapterInfo(); + auto result = wgpuAdapterGetInfo(Get(), reinterpret_cast(info)); + return static_cast(result); +} +ConvertibleStatus Adapter::GetLimits(Limits * limits) const { + auto result = wgpuAdapterGetLimits(Get(), reinterpret_cast(limits)); + return static_cast(result); +} +Bool Adapter::HasFeature(FeatureName feature) const { + auto result = wgpuAdapterHasFeature(Get(), static_cast(feature)); + return result; +} +template +Future Adapter::RequestDevice(DeviceDescriptor const * descriptor, CallbackMode callbackMode,F callback, T userdata) const { + WGPURequestDeviceCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), Device::Acquire(device), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), Device::Acquire(device), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuAdapterRequestDevice(Get(), reinterpret_cast(descriptor), callbackInfo); + return Future { + result.id + }; +} +template +Future Adapter::RequestDevice(DeviceDescriptor const * descriptor, CallbackMode callbackMode,L callback) const { + using F = RequestDeviceCallback; + + WGPURequestDeviceCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), Device::Acquire(device), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), Device::Acquire(device), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuAdapterRequestDevice(Get(), reinterpret_cast(descriptor), callbackInfo); + return Future { + result.id + }; +} + + +void Adapter::WGPUAddRef(WGPUAdapter handle) { + if (handle != nullptr) { + wgpuAdapterAddRef(handle); + } +} +void Adapter::WGPURelease(WGPUAdapter handle) { + if (handle != nullptr) { + wgpuAdapterRelease(handle); + } +} +static_assert(sizeof(Adapter) == sizeof(WGPUAdapter), "sizeof mismatch for Adapter"); +static_assert(alignof(Adapter) == alignof(WGPUAdapter), "alignof mismatch for Adapter"); + +// BindGroup implementation + +void BindGroup::SetLabel(StringView label) const { + wgpuBindGroupSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void BindGroup::WGPUAddRef(WGPUBindGroup handle) { + if (handle != nullptr) { + wgpuBindGroupAddRef(handle); + } +} +void BindGroup::WGPURelease(WGPUBindGroup handle) { + if (handle != nullptr) { + wgpuBindGroupRelease(handle); + } +} +static_assert(sizeof(BindGroup) == sizeof(WGPUBindGroup), "sizeof mismatch for BindGroup"); +static_assert(alignof(BindGroup) == alignof(WGPUBindGroup), "alignof mismatch for BindGroup"); + +// BindGroupLayout implementation + +void BindGroupLayout::SetLabel(StringView label) const { + wgpuBindGroupLayoutSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void BindGroupLayout::WGPUAddRef(WGPUBindGroupLayout handle) { + if (handle != nullptr) { + wgpuBindGroupLayoutAddRef(handle); + } +} +void BindGroupLayout::WGPURelease(WGPUBindGroupLayout handle) { + if (handle != nullptr) { + wgpuBindGroupLayoutRelease(handle); + } +} +static_assert(sizeof(BindGroupLayout) == sizeof(WGPUBindGroupLayout), "sizeof mismatch for BindGroupLayout"); +static_assert(alignof(BindGroupLayout) == alignof(WGPUBindGroupLayout), "alignof mismatch for BindGroupLayout"); + +// Buffer implementation + +void Buffer::Destroy() const { + wgpuBufferDestroy(Get()); +} +void const * Buffer::GetConstMappedRange(size_t offset, size_t size) const { + auto result = wgpuBufferGetConstMappedRange(Get(), offset, size); + return result; +} +void * Buffer::GetMappedRange(size_t offset, size_t size) const { + auto result = wgpuBufferGetMappedRange(Get(), offset, size); + return result; +} +BufferMapState Buffer::GetMapState() const { + auto result = wgpuBufferGetMapState(Get()); + return static_cast(result); +} +uint64_t Buffer::GetSize() const { + auto result = wgpuBufferGetSize(Get()); + return result; +} +BufferUsage Buffer::GetUsage() const { + auto result = wgpuBufferGetUsage(Get()); + return static_cast(result); +} +template +Future Buffer::MapAsync(MapMode mode, size_t offset, size_t size, CallbackMode callbackMode,F callback, T userdata) const { + WGPUBufferMapCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUMapAsyncStatus status, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPUMapAsyncStatus status, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuBufferMapAsync(Get(), static_cast(mode), offset, size, callbackInfo); + return Future { + result.id + }; +} +template +Future Buffer::MapAsync(MapMode mode, size_t offset, size_t size, CallbackMode callbackMode,L callback) const { + using F = BufferMapCallback; + + WGPUBufferMapCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUMapAsyncStatus status, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPUMapAsyncStatus status, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuBufferMapAsync(Get(), static_cast(mode), offset, size, callbackInfo); + return Future { + result.id + }; +} +ConvertibleStatus Buffer::ReadMappedRange(size_t offset, void * data, size_t size) const { + auto result = wgpuBufferReadMappedRange(Get(), offset, reinterpret_cast(data), size); + return static_cast(result); +} +void Buffer::SetLabel(StringView label) const { + wgpuBufferSetLabel(Get(), *reinterpret_cast(&label)); +} +void Buffer::Unmap() const { + wgpuBufferUnmap(Get()); +} +ConvertibleStatus Buffer::WriteMappedRange(size_t offset, void const * data, size_t size) const { + auto result = wgpuBufferWriteMappedRange(Get(), offset, reinterpret_cast(data), size); + return static_cast(result); +} + + +void Buffer::WGPUAddRef(WGPUBuffer handle) { + if (handle != nullptr) { + wgpuBufferAddRef(handle); + } +} +void Buffer::WGPURelease(WGPUBuffer handle) { + if (handle != nullptr) { + wgpuBufferRelease(handle); + } +} +static_assert(sizeof(Buffer) == sizeof(WGPUBuffer), "sizeof mismatch for Buffer"); +static_assert(alignof(Buffer) == alignof(WGPUBuffer), "alignof mismatch for Buffer"); + +// CommandBuffer implementation + +void CommandBuffer::SetLabel(StringView label) const { + wgpuCommandBufferSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void CommandBuffer::WGPUAddRef(WGPUCommandBuffer handle) { + if (handle != nullptr) { + wgpuCommandBufferAddRef(handle); + } +} +void CommandBuffer::WGPURelease(WGPUCommandBuffer handle) { + if (handle != nullptr) { + wgpuCommandBufferRelease(handle); + } +} +static_assert(sizeof(CommandBuffer) == sizeof(WGPUCommandBuffer), "sizeof mismatch for CommandBuffer"); +static_assert(alignof(CommandBuffer) == alignof(WGPUCommandBuffer), "alignof mismatch for CommandBuffer"); + +// CommandEncoder implementation + +ComputePassEncoder CommandEncoder::BeginComputePass(ComputePassDescriptor const * descriptor) const { + auto result = wgpuCommandEncoderBeginComputePass(Get(), reinterpret_cast(descriptor)); + return ComputePassEncoder::Acquire(result); +} +RenderPassEncoder CommandEncoder::BeginRenderPass(RenderPassDescriptor const * descriptor) const { + auto result = wgpuCommandEncoderBeginRenderPass(Get(), reinterpret_cast(descriptor)); + return RenderPassEncoder::Acquire(result); +} +void CommandEncoder::ClearBuffer(Buffer const& buffer, uint64_t offset, uint64_t size) const { + wgpuCommandEncoderClearBuffer(Get(), buffer.Get(), offset, size); +} +void CommandEncoder::CopyBufferToBuffer(Buffer const& source, uint64_t sourceOffset, Buffer const& destination, uint64_t destinationOffset, uint64_t size) const { + wgpuCommandEncoderCopyBufferToBuffer(Get(), source.Get(), sourceOffset, destination.Get(), destinationOffset, size); +} +void CommandEncoder::CopyBufferToTexture(TexelCopyBufferInfo const * source, TexelCopyTextureInfo const * destination, Extent3D const * copySize) const { + wgpuCommandEncoderCopyBufferToTexture(Get(), reinterpret_cast(source), reinterpret_cast(destination), reinterpret_cast(copySize)); +} +void CommandEncoder::CopyTextureToBuffer(TexelCopyTextureInfo const * source, TexelCopyBufferInfo const * destination, Extent3D const * copySize) const { + wgpuCommandEncoderCopyTextureToBuffer(Get(), reinterpret_cast(source), reinterpret_cast(destination), reinterpret_cast(copySize)); +} +void CommandEncoder::CopyTextureToTexture(TexelCopyTextureInfo const * source, TexelCopyTextureInfo const * destination, Extent3D const * copySize) const { + wgpuCommandEncoderCopyTextureToTexture(Get(), reinterpret_cast(source), reinterpret_cast(destination), reinterpret_cast(copySize)); +} +CommandBuffer CommandEncoder::Finish(CommandBufferDescriptor const * descriptor) const { + auto result = wgpuCommandEncoderFinish(Get(), reinterpret_cast(descriptor)); + return CommandBuffer::Acquire(result); +} +void CommandEncoder::InsertDebugMarker(StringView markerLabel) const { + wgpuCommandEncoderInsertDebugMarker(Get(), *reinterpret_cast(&markerLabel)); +} +void CommandEncoder::PopDebugGroup() const { + wgpuCommandEncoderPopDebugGroup(Get()); +} +void CommandEncoder::PushDebugGroup(StringView groupLabel) const { + wgpuCommandEncoderPushDebugGroup(Get(), *reinterpret_cast(&groupLabel)); +} +void CommandEncoder::ResolveQuerySet(QuerySet const& querySet, uint32_t firstQuery, uint32_t queryCount, Buffer const& destination, uint64_t destinationOffset) const { + wgpuCommandEncoderResolveQuerySet(Get(), querySet.Get(), firstQuery, queryCount, destination.Get(), destinationOffset); +} +void CommandEncoder::SetLabel(StringView label) const { + wgpuCommandEncoderSetLabel(Get(), *reinterpret_cast(&label)); +} +void CommandEncoder::WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const { + wgpuCommandEncoderWriteTimestamp(Get(), querySet.Get(), queryIndex); +} + + +void CommandEncoder::WGPUAddRef(WGPUCommandEncoder handle) { + if (handle != nullptr) { + wgpuCommandEncoderAddRef(handle); + } +} +void CommandEncoder::WGPURelease(WGPUCommandEncoder handle) { + if (handle != nullptr) { + wgpuCommandEncoderRelease(handle); + } +} +static_assert(sizeof(CommandEncoder) == sizeof(WGPUCommandEncoder), "sizeof mismatch for CommandEncoder"); +static_assert(alignof(CommandEncoder) == alignof(WGPUCommandEncoder), "alignof mismatch for CommandEncoder"); + +// ComputePassEncoder implementation + +void ComputePassEncoder::DispatchWorkgroups(uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) const { + wgpuComputePassEncoderDispatchWorkgroups(Get(), workgroupCountX, workgroupCountY, workgroupCountZ); +} +void ComputePassEncoder::DispatchWorkgroupsIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const { + wgpuComputePassEncoderDispatchWorkgroupsIndirect(Get(), indirectBuffer.Get(), indirectOffset); +} +void ComputePassEncoder::End() const { + wgpuComputePassEncoderEnd(Get()); +} +void ComputePassEncoder::InsertDebugMarker(StringView markerLabel) const { + wgpuComputePassEncoderInsertDebugMarker(Get(), *reinterpret_cast(&markerLabel)); +} +void ComputePassEncoder::PopDebugGroup() const { + wgpuComputePassEncoderPopDebugGroup(Get()); +} +void ComputePassEncoder::PushDebugGroup(StringView groupLabel) const { + wgpuComputePassEncoderPushDebugGroup(Get(), *reinterpret_cast(&groupLabel)); +} +void ComputePassEncoder::SetBindGroup(uint32_t groupIndex, BindGroup const& group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) const { + wgpuComputePassEncoderSetBindGroup(Get(), groupIndex, group.Get(), dynamicOffsetCount, reinterpret_cast(dynamicOffsets)); +} +void ComputePassEncoder::SetLabel(StringView label) const { + wgpuComputePassEncoderSetLabel(Get(), *reinterpret_cast(&label)); +} +void ComputePassEncoder::SetPipeline(ComputePipeline const& pipeline) const { + wgpuComputePassEncoderSetPipeline(Get(), pipeline.Get()); +} +void ComputePassEncoder::WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const { + wgpuComputePassEncoderWriteTimestamp(Get(), querySet.Get(), queryIndex); +} + + +void ComputePassEncoder::WGPUAddRef(WGPUComputePassEncoder handle) { + if (handle != nullptr) { + wgpuComputePassEncoderAddRef(handle); + } +} +void ComputePassEncoder::WGPURelease(WGPUComputePassEncoder handle) { + if (handle != nullptr) { + wgpuComputePassEncoderRelease(handle); + } +} +static_assert(sizeof(ComputePassEncoder) == sizeof(WGPUComputePassEncoder), "sizeof mismatch for ComputePassEncoder"); +static_assert(alignof(ComputePassEncoder) == alignof(WGPUComputePassEncoder), "alignof mismatch for ComputePassEncoder"); + +// ComputePipeline implementation + +BindGroupLayout ComputePipeline::GetBindGroupLayout(uint32_t groupIndex) const { + auto result = wgpuComputePipelineGetBindGroupLayout(Get(), groupIndex); + return BindGroupLayout::Acquire(result); +} +void ComputePipeline::SetLabel(StringView label) const { + wgpuComputePipelineSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void ComputePipeline::WGPUAddRef(WGPUComputePipeline handle) { + if (handle != nullptr) { + wgpuComputePipelineAddRef(handle); + } +} +void ComputePipeline::WGPURelease(WGPUComputePipeline handle) { + if (handle != nullptr) { + wgpuComputePipelineRelease(handle); + } +} +static_assert(sizeof(ComputePipeline) == sizeof(WGPUComputePipeline), "sizeof mismatch for ComputePipeline"); +static_assert(alignof(ComputePipeline) == alignof(WGPUComputePipeline), "alignof mismatch for ComputePipeline"); + +// Device implementation + +BindGroup Device::CreateBindGroup(BindGroupDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateBindGroup(Get(), reinterpret_cast(descriptor)); + return BindGroup::Acquire(result); +} +BindGroupLayout Device::CreateBindGroupLayout(BindGroupLayoutDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateBindGroupLayout(Get(), reinterpret_cast(descriptor)); + return BindGroupLayout::Acquire(result); +} +Buffer Device::CreateBuffer(BufferDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateBuffer(Get(), reinterpret_cast(descriptor)); + return Buffer::Acquire(result); +} +CommandEncoder Device::CreateCommandEncoder(CommandEncoderDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateCommandEncoder(Get(), reinterpret_cast(descriptor)); + return CommandEncoder::Acquire(result); +} +ComputePipeline Device::CreateComputePipeline(ComputePipelineDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateComputePipeline(Get(), reinterpret_cast(descriptor)); + return ComputePipeline::Acquire(result); +} +template +Future Device::CreateComputePipelineAsync(ComputePipelineDescriptor const * descriptor, CallbackMode callbackMode,F callback, T userdata) const { + WGPUCreateComputePipelineAsyncCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), ComputePipeline::Acquire(pipeline), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), ComputePipeline::Acquire(pipeline), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuDeviceCreateComputePipelineAsync(Get(), reinterpret_cast(descriptor), callbackInfo); + return Future { + result.id + }; +} +template +Future Device::CreateComputePipelineAsync(ComputePipelineDescriptor const * descriptor, CallbackMode callbackMode,L callback) const { + using F = CreateComputePipelineAsyncCallback; + + WGPUCreateComputePipelineAsyncCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), ComputePipeline::Acquire(pipeline), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), ComputePipeline::Acquire(pipeline), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuDeviceCreateComputePipelineAsync(Get(), reinterpret_cast(descriptor), callbackInfo); + return Future { + result.id + }; +} +PipelineLayout Device::CreatePipelineLayout(PipelineLayoutDescriptor const * descriptor) const { + auto result = wgpuDeviceCreatePipelineLayout(Get(), reinterpret_cast(descriptor)); + return PipelineLayout::Acquire(result); +} +QuerySet Device::CreateQuerySet(QuerySetDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateQuerySet(Get(), reinterpret_cast(descriptor)); + return QuerySet::Acquire(result); +} +RenderBundleEncoder Device::CreateRenderBundleEncoder(RenderBundleEncoderDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateRenderBundleEncoder(Get(), reinterpret_cast(descriptor)); + return RenderBundleEncoder::Acquire(result); +} +RenderPipeline Device::CreateRenderPipeline(RenderPipelineDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateRenderPipeline(Get(), reinterpret_cast(descriptor)); + return RenderPipeline::Acquire(result); +} +template +Future Device::CreateRenderPipelineAsync(RenderPipelineDescriptor const * descriptor, CallbackMode callbackMode,F callback, T userdata) const { + WGPUCreateRenderPipelineAsyncCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), RenderPipeline::Acquire(pipeline), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), RenderPipeline::Acquire(pipeline), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuDeviceCreateRenderPipelineAsync(Get(), reinterpret_cast(descriptor), callbackInfo); + return Future { + result.id + }; +} +template +Future Device::CreateRenderPipelineAsync(RenderPipelineDescriptor const * descriptor, CallbackMode callbackMode,L callback) const { + using F = CreateRenderPipelineAsyncCallback; + + WGPUCreateRenderPipelineAsyncCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), RenderPipeline::Acquire(pipeline), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), RenderPipeline::Acquire(pipeline), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuDeviceCreateRenderPipelineAsync(Get(), reinterpret_cast(descriptor), callbackInfo); + return Future { + result.id + }; +} +Sampler Device::CreateSampler(SamplerDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateSampler(Get(), reinterpret_cast(descriptor)); + return Sampler::Acquire(result); +} +ShaderModule Device::CreateShaderModule(ShaderModuleDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateShaderModule(Get(), reinterpret_cast(descriptor)); + return ShaderModule::Acquire(result); +} +Texture Device::CreateTexture(TextureDescriptor const * descriptor) const { + auto result = wgpuDeviceCreateTexture(Get(), reinterpret_cast(descriptor)); + return Texture::Acquire(result); +} +void Device::Destroy() const { + wgpuDeviceDestroy(Get()); +} +ConvertibleStatus Device::GetAdapterInfo(AdapterInfo * adapterInfo) const { + *adapterInfo = AdapterInfo(); + auto result = wgpuDeviceGetAdapterInfo(Get(), reinterpret_cast(adapterInfo)); + return static_cast(result); +} +void Device::GetFeatures(SupportedFeatures * features) const { + *features = SupportedFeatures(); + wgpuDeviceGetFeatures(Get(), reinterpret_cast(features)); +} +ConvertibleStatus Device::GetLimits(Limits * limits) const { + auto result = wgpuDeviceGetLimits(Get(), reinterpret_cast(limits)); + return static_cast(result); +} +Future Device::GetLostFuture() const { + auto result = wgpuDeviceGetLostFuture(Get()); + return Future { + result.id + }; +} +Queue Device::GetQueue() const { + auto result = wgpuDeviceGetQueue(Get()); + return Queue::Acquire(result); +} +Bool Device::HasFeature(FeatureName feature) const { + auto result = wgpuDeviceHasFeature(Get(), static_cast(feature)); + return result; +} +template +Future Device::PopErrorScope(CallbackMode callbackMode,F callback, T userdata) const { + WGPUPopErrorScopeCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), static_cast(type), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), static_cast(type), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuDevicePopErrorScope(Get(), callbackInfo); + return Future { + result.id + }; +} +template +Future Device::PopErrorScope(CallbackMode callbackMode,L callback) const { + using F = PopErrorScopeCallback; + + WGPUPopErrorScopeCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), static_cast(type), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), static_cast(type), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuDevicePopErrorScope(Get(), callbackInfo); + return Future { + result.id + }; +} +void Device::PushErrorScope(ErrorFilter filter) const { + wgpuDevicePushErrorScope(Get(), static_cast(filter)); +} +void Device::SetLabel(StringView label) const { + wgpuDeviceSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void Device::WGPUAddRef(WGPUDevice handle) { + if (handle != nullptr) { + wgpuDeviceAddRef(handle); + } +} +void Device::WGPURelease(WGPUDevice handle) { + if (handle != nullptr) { + wgpuDeviceRelease(handle); + } +} +static_assert(sizeof(Device) == sizeof(WGPUDevice), "sizeof mismatch for Device"); +static_assert(alignof(Device) == alignof(WGPUDevice), "alignof mismatch for Device"); + +// Instance implementation + +Surface Instance::CreateSurface(SurfaceDescriptor const * descriptor) const { + auto result = wgpuInstanceCreateSurface(Get(), reinterpret_cast(descriptor)); + return Surface::Acquire(result); +} +void Instance::GetWGSLLanguageFeatures(SupportedWGSLLanguageFeatures * features) const { + *features = SupportedWGSLLanguageFeatures(); + wgpuInstanceGetWGSLLanguageFeatures(Get(), reinterpret_cast(features)); +} +Bool Instance::HasWGSLLanguageFeature(WGSLLanguageFeatureName feature) const { + auto result = wgpuInstanceHasWGSLLanguageFeature(Get(), static_cast(feature)); + return result; +} +void Instance::ProcessEvents() const { + wgpuInstanceProcessEvents(Get()); +} +template +Future Instance::RequestAdapter(RequestAdapterOptions const * options, CallbackMode callbackMode,F callback, T userdata) const { + WGPURequestAdapterCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), Adapter::Acquire(adapter), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), Adapter::Acquire(adapter), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuInstanceRequestAdapter(Get(), reinterpret_cast(options), callbackInfo); + return Future { + result.id + }; +} +template +Future Instance::RequestAdapter(RequestAdapterOptions const * options, CallbackMode callbackMode,L callback) const { + using F = RequestAdapterCallback; + + WGPURequestAdapterCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), Adapter::Acquire(adapter), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), Adapter::Acquire(adapter), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuInstanceRequestAdapter(Get(), reinterpret_cast(options), callbackInfo); + return Future { + result.id + }; +} +WaitStatus Instance::WaitAny(size_t futureCount, FutureWaitInfo * futures, uint64_t timeoutNS) const { + auto result = wgpuInstanceWaitAny(Get(), futureCount, reinterpret_cast(futures), timeoutNS); + return static_cast(result); +} + +WaitStatus Instance::WaitAny(Future f, uint64_t timeout) const { + FutureWaitInfo waitInfo { f }; + return WaitAny(1, &waitInfo, timeout); +} + +void Instance::WGPUAddRef(WGPUInstance handle) { + if (handle != nullptr) { + wgpuInstanceAddRef(handle); + } +} +void Instance::WGPURelease(WGPUInstance handle) { + if (handle != nullptr) { + wgpuInstanceRelease(handle); + } +} +static_assert(sizeof(Instance) == sizeof(WGPUInstance), "sizeof mismatch for Instance"); +static_assert(alignof(Instance) == alignof(WGPUInstance), "alignof mismatch for Instance"); + +// PipelineLayout implementation + +void PipelineLayout::SetLabel(StringView label) const { + wgpuPipelineLayoutSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void PipelineLayout::WGPUAddRef(WGPUPipelineLayout handle) { + if (handle != nullptr) { + wgpuPipelineLayoutAddRef(handle); + } +} +void PipelineLayout::WGPURelease(WGPUPipelineLayout handle) { + if (handle != nullptr) { + wgpuPipelineLayoutRelease(handle); + } +} +static_assert(sizeof(PipelineLayout) == sizeof(WGPUPipelineLayout), "sizeof mismatch for PipelineLayout"); +static_assert(alignof(PipelineLayout) == alignof(WGPUPipelineLayout), "alignof mismatch for PipelineLayout"); + +// QuerySet implementation + +void QuerySet::Destroy() const { + wgpuQuerySetDestroy(Get()); +} +uint32_t QuerySet::GetCount() const { + auto result = wgpuQuerySetGetCount(Get()); + return result; +} +QueryType QuerySet::GetType() const { + auto result = wgpuQuerySetGetType(Get()); + return static_cast(result); +} +void QuerySet::SetLabel(StringView label) const { + wgpuQuerySetSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void QuerySet::WGPUAddRef(WGPUQuerySet handle) { + if (handle != nullptr) { + wgpuQuerySetAddRef(handle); + } +} +void QuerySet::WGPURelease(WGPUQuerySet handle) { + if (handle != nullptr) { + wgpuQuerySetRelease(handle); + } +} +static_assert(sizeof(QuerySet) == sizeof(WGPUQuerySet), "sizeof mismatch for QuerySet"); +static_assert(alignof(QuerySet) == alignof(WGPUQuerySet), "alignof mismatch for QuerySet"); + +// Queue implementation + +template +Future Queue::OnSubmittedWorkDone(CallbackMode callbackMode,F callback, T userdata) const { + WGPUQueueWorkDoneCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUQueueWorkDoneStatus status, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), StringView { + message.data, + message.length +}, static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPUQueueWorkDoneStatus status, WGPUStringView message, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), {detail::StringViewAdapter(message)}, static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuQueueOnSubmittedWorkDone(Get(), callbackInfo); + return Future { + result.id + }; +} +template +Future Queue::OnSubmittedWorkDone(CallbackMode callbackMode,L callback) const { + using F = QueueWorkDoneCallback; + + WGPUQueueWorkDoneCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUQueueWorkDoneStatus status, WGPUStringView message, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), StringView { + message.data, + message.length +}); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPUQueueWorkDoneStatus status, WGPUStringView message, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), {detail::StringViewAdapter(message)}); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuQueueOnSubmittedWorkDone(Get(), callbackInfo); + return Future { + result.id + }; +} +void Queue::SetLabel(StringView label) const { + wgpuQueueSetLabel(Get(), *reinterpret_cast(&label)); +} +void Queue::Submit(size_t commandCount, CommandBuffer const * commands) const { + wgpuQueueSubmit(Get(), commandCount, reinterpret_cast(commands)); +} +void Queue::WriteBuffer(Buffer const& buffer, uint64_t bufferOffset, void const * data, size_t size) const { + wgpuQueueWriteBuffer(Get(), buffer.Get(), bufferOffset, reinterpret_cast(data), size); +} +void Queue::WriteTexture(TexelCopyTextureInfo const * destination, void const * data, size_t dataSize, TexelCopyBufferLayout const * dataLayout, Extent3D const * writeSize) const { + wgpuQueueWriteTexture(Get(), reinterpret_cast(destination), reinterpret_cast(data), dataSize, reinterpret_cast(dataLayout), reinterpret_cast(writeSize)); +} + + +void Queue::WGPUAddRef(WGPUQueue handle) { + if (handle != nullptr) { + wgpuQueueAddRef(handle); + } +} +void Queue::WGPURelease(WGPUQueue handle) { + if (handle != nullptr) { + wgpuQueueRelease(handle); + } +} +static_assert(sizeof(Queue) == sizeof(WGPUQueue), "sizeof mismatch for Queue"); +static_assert(alignof(Queue) == alignof(WGPUQueue), "alignof mismatch for Queue"); + +// RenderBundle implementation + +void RenderBundle::SetLabel(StringView label) const { + wgpuRenderBundleSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void RenderBundle::WGPUAddRef(WGPURenderBundle handle) { + if (handle != nullptr) { + wgpuRenderBundleAddRef(handle); + } +} +void RenderBundle::WGPURelease(WGPURenderBundle handle) { + if (handle != nullptr) { + wgpuRenderBundleRelease(handle); + } +} +static_assert(sizeof(RenderBundle) == sizeof(WGPURenderBundle), "sizeof mismatch for RenderBundle"); +static_assert(alignof(RenderBundle) == alignof(WGPURenderBundle), "alignof mismatch for RenderBundle"); + +// RenderBundleEncoder implementation + +void RenderBundleEncoder::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const { + wgpuRenderBundleEncoderDraw(Get(), vertexCount, instanceCount, firstVertex, firstInstance); +} +void RenderBundleEncoder::DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) const { + wgpuRenderBundleEncoderDrawIndexed(Get(), indexCount, instanceCount, firstIndex, baseVertex, firstInstance); +} +void RenderBundleEncoder::DrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const { + wgpuRenderBundleEncoderDrawIndexedIndirect(Get(), indirectBuffer.Get(), indirectOffset); +} +void RenderBundleEncoder::DrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const { + wgpuRenderBundleEncoderDrawIndirect(Get(), indirectBuffer.Get(), indirectOffset); +} +RenderBundle RenderBundleEncoder::Finish(RenderBundleDescriptor const * descriptor) const { + auto result = wgpuRenderBundleEncoderFinish(Get(), reinterpret_cast(descriptor)); + return RenderBundle::Acquire(result); +} +void RenderBundleEncoder::InsertDebugMarker(StringView markerLabel) const { + wgpuRenderBundleEncoderInsertDebugMarker(Get(), *reinterpret_cast(&markerLabel)); +} +void RenderBundleEncoder::PopDebugGroup() const { + wgpuRenderBundleEncoderPopDebugGroup(Get()); +} +void RenderBundleEncoder::PushDebugGroup(StringView groupLabel) const { + wgpuRenderBundleEncoderPushDebugGroup(Get(), *reinterpret_cast(&groupLabel)); +} +void RenderBundleEncoder::SetBindGroup(uint32_t groupIndex, BindGroup const& group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) const { + wgpuRenderBundleEncoderSetBindGroup(Get(), groupIndex, group.Get(), dynamicOffsetCount, reinterpret_cast(dynamicOffsets)); +} +void RenderBundleEncoder::SetIndexBuffer(Buffer const& buffer, IndexFormat format, uint64_t offset, uint64_t size) const { + wgpuRenderBundleEncoderSetIndexBuffer(Get(), buffer.Get(), static_cast(format), offset, size); +} +void RenderBundleEncoder::SetLabel(StringView label) const { + wgpuRenderBundleEncoderSetLabel(Get(), *reinterpret_cast(&label)); +} +void RenderBundleEncoder::SetPipeline(RenderPipeline const& pipeline) const { + wgpuRenderBundleEncoderSetPipeline(Get(), pipeline.Get()); +} +void RenderBundleEncoder::SetVertexBuffer(uint32_t slot, Buffer const& buffer, uint64_t offset, uint64_t size) const { + wgpuRenderBundleEncoderSetVertexBuffer(Get(), slot, buffer.Get(), offset, size); +} + + +void RenderBundleEncoder::WGPUAddRef(WGPURenderBundleEncoder handle) { + if (handle != nullptr) { + wgpuRenderBundleEncoderAddRef(handle); + } +} +void RenderBundleEncoder::WGPURelease(WGPURenderBundleEncoder handle) { + if (handle != nullptr) { + wgpuRenderBundleEncoderRelease(handle); + } +} +static_assert(sizeof(RenderBundleEncoder) == sizeof(WGPURenderBundleEncoder), "sizeof mismatch for RenderBundleEncoder"); +static_assert(alignof(RenderBundleEncoder) == alignof(WGPURenderBundleEncoder), "alignof mismatch for RenderBundleEncoder"); + +// RenderPassEncoder implementation + +void RenderPassEncoder::BeginOcclusionQuery(uint32_t queryIndex) const { + wgpuRenderPassEncoderBeginOcclusionQuery(Get(), queryIndex); +} +void RenderPassEncoder::Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const { + wgpuRenderPassEncoderDraw(Get(), vertexCount, instanceCount, firstVertex, firstInstance); +} +void RenderPassEncoder::DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) const { + wgpuRenderPassEncoderDrawIndexed(Get(), indexCount, instanceCount, firstIndex, baseVertex, firstInstance); +} +void RenderPassEncoder::DrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const { + wgpuRenderPassEncoderDrawIndexedIndirect(Get(), indirectBuffer.Get(), indirectOffset); +} +void RenderPassEncoder::DrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset) const { + wgpuRenderPassEncoderDrawIndirect(Get(), indirectBuffer.Get(), indirectOffset); +} +void RenderPassEncoder::End() const { + wgpuRenderPassEncoderEnd(Get()); +} +void RenderPassEncoder::EndOcclusionQuery() const { + wgpuRenderPassEncoderEndOcclusionQuery(Get()); +} +void RenderPassEncoder::ExecuteBundles(size_t bundleCount, RenderBundle const * bundles) const { + wgpuRenderPassEncoderExecuteBundles(Get(), bundleCount, reinterpret_cast(bundles)); +} +void RenderPassEncoder::InsertDebugMarker(StringView markerLabel) const { + wgpuRenderPassEncoderInsertDebugMarker(Get(), *reinterpret_cast(&markerLabel)); +} +void RenderPassEncoder::MultiDrawIndexedIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, Buffer const& drawCountBuffer, uint64_t drawCountBufferOffset) const { + wgpuRenderPassEncoderMultiDrawIndexedIndirect(Get(), indirectBuffer.Get(), indirectOffset, maxDrawCount, drawCountBuffer.Get(), drawCountBufferOffset); +} +void RenderPassEncoder::MultiDrawIndirect(Buffer const& indirectBuffer, uint64_t indirectOffset, uint32_t maxDrawCount, Buffer const& drawCountBuffer, uint64_t drawCountBufferOffset) const { + wgpuRenderPassEncoderMultiDrawIndirect(Get(), indirectBuffer.Get(), indirectOffset, maxDrawCount, drawCountBuffer.Get(), drawCountBufferOffset); +} +void RenderPassEncoder::PopDebugGroup() const { + wgpuRenderPassEncoderPopDebugGroup(Get()); +} +void RenderPassEncoder::PushDebugGroup(StringView groupLabel) const { + wgpuRenderPassEncoderPushDebugGroup(Get(), *reinterpret_cast(&groupLabel)); +} +void RenderPassEncoder::SetBindGroup(uint32_t groupIndex, BindGroup const& group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) const { + wgpuRenderPassEncoderSetBindGroup(Get(), groupIndex, group.Get(), dynamicOffsetCount, reinterpret_cast(dynamicOffsets)); +} +void RenderPassEncoder::SetBlendConstant(Color const * color) const { + wgpuRenderPassEncoderSetBlendConstant(Get(), reinterpret_cast(color)); +} +void RenderPassEncoder::SetIndexBuffer(Buffer const& buffer, IndexFormat format, uint64_t offset, uint64_t size) const { + wgpuRenderPassEncoderSetIndexBuffer(Get(), buffer.Get(), static_cast(format), offset, size); +} +void RenderPassEncoder::SetLabel(StringView label) const { + wgpuRenderPassEncoderSetLabel(Get(), *reinterpret_cast(&label)); +} +void RenderPassEncoder::SetPipeline(RenderPipeline const& pipeline) const { + wgpuRenderPassEncoderSetPipeline(Get(), pipeline.Get()); +} +void RenderPassEncoder::SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) const { + wgpuRenderPassEncoderSetScissorRect(Get(), x, y, width, height); +} +void RenderPassEncoder::SetStencilReference(uint32_t reference) const { + wgpuRenderPassEncoderSetStencilReference(Get(), reference); +} +void RenderPassEncoder::SetVertexBuffer(uint32_t slot, Buffer const& buffer, uint64_t offset, uint64_t size) const { + wgpuRenderPassEncoderSetVertexBuffer(Get(), slot, buffer.Get(), offset, size); +} +void RenderPassEncoder::SetViewport(float x, float y, float width, float height, float minDepth, float maxDepth) const { + wgpuRenderPassEncoderSetViewport(Get(), x, y, width, height, minDepth, maxDepth); +} +void RenderPassEncoder::WriteTimestamp(QuerySet const& querySet, uint32_t queryIndex) const { + wgpuRenderPassEncoderWriteTimestamp(Get(), querySet.Get(), queryIndex); +} + + +void RenderPassEncoder::WGPUAddRef(WGPURenderPassEncoder handle) { + if (handle != nullptr) { + wgpuRenderPassEncoderAddRef(handle); + } +} +void RenderPassEncoder::WGPURelease(WGPURenderPassEncoder handle) { + if (handle != nullptr) { + wgpuRenderPassEncoderRelease(handle); + } +} +static_assert(sizeof(RenderPassEncoder) == sizeof(WGPURenderPassEncoder), "sizeof mismatch for RenderPassEncoder"); +static_assert(alignof(RenderPassEncoder) == alignof(WGPURenderPassEncoder), "alignof mismatch for RenderPassEncoder"); + +// RenderPipeline implementation + +BindGroupLayout RenderPipeline::GetBindGroupLayout(uint32_t groupIndex) const { + auto result = wgpuRenderPipelineGetBindGroupLayout(Get(), groupIndex); + return BindGroupLayout::Acquire(result); +} +void RenderPipeline::SetLabel(StringView label) const { + wgpuRenderPipelineSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void RenderPipeline::WGPUAddRef(WGPURenderPipeline handle) { + if (handle != nullptr) { + wgpuRenderPipelineAddRef(handle); + } +} +void RenderPipeline::WGPURelease(WGPURenderPipeline handle) { + if (handle != nullptr) { + wgpuRenderPipelineRelease(handle); + } +} +static_assert(sizeof(RenderPipeline) == sizeof(WGPURenderPipeline), "sizeof mismatch for RenderPipeline"); +static_assert(alignof(RenderPipeline) == alignof(WGPURenderPipeline), "alignof mismatch for RenderPipeline"); + +// Sampler implementation + +void Sampler::SetLabel(StringView label) const { + wgpuSamplerSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void Sampler::WGPUAddRef(WGPUSampler handle) { + if (handle != nullptr) { + wgpuSamplerAddRef(handle); + } +} +void Sampler::WGPURelease(WGPUSampler handle) { + if (handle != nullptr) { + wgpuSamplerRelease(handle); + } +} +static_assert(sizeof(Sampler) == sizeof(WGPUSampler), "sizeof mismatch for Sampler"); +static_assert(alignof(Sampler) == alignof(WGPUSampler), "alignof mismatch for Sampler"); + +// ShaderModule implementation + +template +Future ShaderModule::GetCompilationInfo(CallbackMode callbackMode,F callback, T userdata) const { + WGPUCompilationInfoCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUCompilationInfoRequestStatus status, WGPUCompilationInfo const * compilationInfo, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), reinterpret_cast(compilationInfo), static_cast(userdata_param)); + }; + } else { + callbackInfo.callback = [](WGPUCompilationInfoRequestStatus status, WGPUCompilationInfo const * compilationInfo, void* callback_param, void* userdata_param) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), reinterpret_cast(compilationInfo), static_cast(userdata_param)); + }; + } + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = reinterpret_cast(userdata); + auto result = wgpuShaderModuleGetCompilationInfo(Get(), callbackInfo); + return Future { + result.id + }; +} +template +Future ShaderModule::GetCompilationInfo(CallbackMode callbackMode,L callback) const { + using F = CompilationInfoCallback; + + WGPUCompilationInfoCallbackInfo callbackInfo = {}; + callbackInfo.mode = static_cast(callbackMode); + if constexpr (std::is_convertible_v) { + callbackInfo.callback = [](WGPUCompilationInfoRequestStatus status, WGPUCompilationInfo const * compilationInfo, void* callback_param, void*) { + auto cb = reinterpret_cast(callback_param); + (*cb)(static_cast(status), reinterpret_cast(compilationInfo)); + }; + callbackInfo.userdata1 = reinterpret_cast(+callback); + callbackInfo.userdata2 = nullptr; + } else { + auto* lambda = new L(std::move(callback)); + callbackInfo.callback = [](WGPUCompilationInfoRequestStatus status, WGPUCompilationInfo const * compilationInfo, void* callback_param, void*) { + std::unique_ptr the_lambda(reinterpret_cast(callback_param)); + (*the_lambda)(static_cast(status), reinterpret_cast(compilationInfo)); + }; + callbackInfo.userdata1 = reinterpret_cast(lambda); + callbackInfo.userdata2 = nullptr; + } + auto result = wgpuShaderModuleGetCompilationInfo(Get(), callbackInfo); + return Future { + result.id + }; +} +void ShaderModule::SetLabel(StringView label) const { + wgpuShaderModuleSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void ShaderModule::WGPUAddRef(WGPUShaderModule handle) { + if (handle != nullptr) { + wgpuShaderModuleAddRef(handle); + } +} +void ShaderModule::WGPURelease(WGPUShaderModule handle) { + if (handle != nullptr) { + wgpuShaderModuleRelease(handle); + } +} +static_assert(sizeof(ShaderModule) == sizeof(WGPUShaderModule), "sizeof mismatch for ShaderModule"); +static_assert(alignof(ShaderModule) == alignof(WGPUShaderModule), "alignof mismatch for ShaderModule"); + +// Surface implementation + +void Surface::Configure(SurfaceConfiguration const * config) const { + wgpuSurfaceConfigure(Get(), reinterpret_cast(config)); +} +ConvertibleStatus Surface::GetCapabilities(Adapter const& adapter, SurfaceCapabilities * capabilities) const { + *capabilities = SurfaceCapabilities(); + auto result = wgpuSurfaceGetCapabilities(Get(), adapter.Get(), reinterpret_cast(capabilities)); + return static_cast(result); +} +void Surface::GetCurrentTexture(SurfaceTexture * surfaceTexture) const { + wgpuSurfaceGetCurrentTexture(Get(), reinterpret_cast(surfaceTexture)); +} +ConvertibleStatus Surface::Present() const { + auto result = wgpuSurfacePresent(Get()); + return static_cast(result); +} +void Surface::SetLabel(StringView label) const { + wgpuSurfaceSetLabel(Get(), *reinterpret_cast(&label)); +} +void Surface::Unconfigure() const { + wgpuSurfaceUnconfigure(Get()); +} + + +void Surface::WGPUAddRef(WGPUSurface handle) { + if (handle != nullptr) { + wgpuSurfaceAddRef(handle); + } +} +void Surface::WGPURelease(WGPUSurface handle) { + if (handle != nullptr) { + wgpuSurfaceRelease(handle); + } +} +static_assert(sizeof(Surface) == sizeof(WGPUSurface), "sizeof mismatch for Surface"); +static_assert(alignof(Surface) == alignof(WGPUSurface), "alignof mismatch for Surface"); + +// Texture implementation + +TextureView Texture::CreateView(TextureViewDescriptor const * descriptor) const { + auto result = wgpuTextureCreateView(Get(), reinterpret_cast(descriptor)); + return TextureView::Acquire(result); +} +void Texture::Destroy() const { + wgpuTextureDestroy(Get()); +} +uint32_t Texture::GetDepthOrArrayLayers() const { + auto result = wgpuTextureGetDepthOrArrayLayers(Get()); + return result; +} +TextureDimension Texture::GetDimension() const { + auto result = wgpuTextureGetDimension(Get()); + return static_cast(result); +} +TextureFormat Texture::GetFormat() const { + auto result = wgpuTextureGetFormat(Get()); + return static_cast(result); +} +uint32_t Texture::GetHeight() const { + auto result = wgpuTextureGetHeight(Get()); + return result; +} +uint32_t Texture::GetMipLevelCount() const { + auto result = wgpuTextureGetMipLevelCount(Get()); + return result; +} +uint32_t Texture::GetSampleCount() const { + auto result = wgpuTextureGetSampleCount(Get()); + return result; +} +TextureUsage Texture::GetUsage() const { + auto result = wgpuTextureGetUsage(Get()); + return static_cast(result); +} +uint32_t Texture::GetWidth() const { + auto result = wgpuTextureGetWidth(Get()); + return result; +} +void Texture::SetLabel(StringView label) const { + wgpuTextureSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void Texture::WGPUAddRef(WGPUTexture handle) { + if (handle != nullptr) { + wgpuTextureAddRef(handle); + } +} +void Texture::WGPURelease(WGPUTexture handle) { + if (handle != nullptr) { + wgpuTextureRelease(handle); + } +} +static_assert(sizeof(Texture) == sizeof(WGPUTexture), "sizeof mismatch for Texture"); +static_assert(alignof(Texture) == alignof(WGPUTexture), "alignof mismatch for Texture"); + +// TextureView implementation + +void TextureView::SetLabel(StringView label) const { + wgpuTextureViewSetLabel(Get(), *reinterpret_cast(&label)); +} + + +void TextureView::WGPUAddRef(WGPUTextureView handle) { + if (handle != nullptr) { + wgpuTextureViewAddRef(handle); + } +} +void TextureView::WGPURelease(WGPUTextureView handle) { + if (handle != nullptr) { + wgpuTextureViewRelease(handle); + } +} +static_assert(sizeof(TextureView) == sizeof(WGPUTextureView), "sizeof mismatch for TextureView"); +static_assert(alignof(TextureView) == alignof(WGPUTextureView), "alignof mismatch for TextureView"); + + + + +// Free Functions +static inline Instance CreateInstance(InstanceDescriptor const * descriptor = nullptr) { + auto result = wgpuCreateInstance(reinterpret_cast(descriptor)); + return Instance::Acquire(result); +} +static inline void GetInstanceFeatures(SupportedInstanceFeatures * features) { + wgpuGetInstanceFeatures(reinterpret_cast(features)); +} +static inline Status GetInstanceLimits(InstanceLimits * limits) { + auto result = wgpuGetInstanceLimits(reinterpret_cast(limits)); + return static_cast(result); +} +static inline Bool HasInstanceFeature(InstanceFeatureName feature) { + auto result = wgpuHasInstanceFeature(static_cast(feature)); + return result; +} +static inline Proc GetProcAddress(StringView procName) { + auto result = wgpuGetProcAddress(*reinterpret_cast(&procName)); + return reinterpret_cast(result); +} + +} // namespace wgpu + +namespace wgpu { + +template<> +struct IsWGPUBitmask { + static constexpr bool enable = true; +}; + +template<> +struct IsWGPUBitmask { + static constexpr bool enable = true; +}; + +template<> +struct IsWGPUBitmask { + static constexpr bool enable = true; +}; + +template<> +struct IsWGPUBitmask { + static constexpr bool enable = true; +}; + +template<> +struct IsWGPUBitmask { + static constexpr bool enable = true; +}; + + +inline bool operator==(const TextureComponentSwizzle& s1, const TextureComponentSwizzle& s2) { + return s1.r == s2.r && s1.g == s2.g && s1.b == s2.b && s1.a == s2.a; +} +inline bool operator!=(const TextureComponentSwizzle& s1, const TextureComponentSwizzle& s2) { + return !(s1 == s2); +} + +} // namespace wgpu + +namespace std { +// Custom boolean class needs corresponding hash function so that it appears as a transparent bool. +template <> +struct hash { + public: + size_t operator()(const wgpu::Bool &v) const { + return hash()(v); + } +}; +template <> +struct hash { + public: + size_t operator()(const wgpu::OptionalBool &v) const { + return hash()(v.mValue); + } +}; +} // namespace std + +#endif // WEBGPU_CPP_H_ diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp_chained_struct.h b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp_chained_struct.h new file mode 100644 index 000000000..50376f058 --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_cpp_chained_struct.h @@ -0,0 +1,54 @@ +// Copyright 2023 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#ifndef WEBGPU_CPP_CHAINED_STRUCT_H_ +#define WEBGPU_CPP_CHAINED_STRUCT_H_ + +#include +#include + +// This header file declares the ChainedStruct structures separately from the WebGPU +// headers so that dependencies can directly extend structures without including the larger header +// which exposes capabilities that may require correctly set proc tables. +namespace wgpu { + + enum class SType : uint32_t; + + struct ChainedStruct { + ChainedStruct const * nextInChain = nullptr; + SType sType = SType(0u); + }; + + struct ChainedStructOut { + ChainedStructOut * nextInChain = nullptr; + SType sType = SType(0u); + }; + +} // namespace wgpu} + +#endif // WEBGPU_CPP_CHAINED_STRUCT_H_ diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_enum_class_bitmasks.h b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_enum_class_bitmasks.h new file mode 100644 index 000000000..e98c8c5da --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_enum_class_bitmasks.h @@ -0,0 +1,161 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef WEBGPU_ENUM_CLASS_BITMASKS_H_ +#define WEBGPU_ENUM_CLASS_BITMASKS_H_ + +#include + +// The operators in wgpu:: namespace need be introduced into other namespaces with +// using-declarations for C++ Argument Dependent Lookup to work. +#define WGPU_IMPORT_BITMASK_OPERATORS \ + using wgpu::operator|; \ + using wgpu::operator&; \ + using wgpu::operator^; \ + using wgpu::operator~; \ + using wgpu::operator&=; \ + using wgpu::operator|=; \ + using wgpu::operator^=; \ + using wgpu::HasZeroOrOneBits; + +namespace wgpu { + +template +struct IsWGPUBitmask { + static constexpr bool enable = false; +}; + +template +struct LowerBitmask { + static constexpr bool enable = false; +}; + +template +struct LowerBitmask::enable>::type> { + static constexpr bool enable = true; + using type = T; + constexpr static T Lower(T t) { return t; } +}; + +template +struct BoolConvertible { + using Integral = typename std::underlying_type::type; + + // NOLINTNEXTLINE(runtime/explicit) + explicit constexpr BoolConvertible(Integral value) : value(value) {} + constexpr operator bool() const { return value != 0; } + constexpr operator T() const { return static_cast(value); } + + Integral value; +}; + +template +struct LowerBitmask> { + static constexpr bool enable = true; + using type = T; + static constexpr type Lower(BoolConvertible t) { return t; } +}; + +template < + typename T1, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr BoolConvertible::type> operator|(T1 left, T2 right) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(static_cast(LowerBitmask::Lower(left)) | + static_cast(LowerBitmask::Lower(right))); +} + +template < + typename T1, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr BoolConvertible::type> operator&(T1 left, T2 right) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(static_cast(LowerBitmask::Lower(left)) & + static_cast(LowerBitmask::Lower(right))); +} + +template < + typename T1, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr BoolConvertible::type> operator^(T1 left, T2 right) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(static_cast(LowerBitmask::Lower(left)) ^ + static_cast(LowerBitmask::Lower(right))); +} + +template +constexpr BoolConvertible::type> operator~(T1 t) { + using T = typename LowerBitmask::type; + using Integral = typename std::underlying_type::type; + return BoolConvertible(~static_cast(LowerBitmask::Lower(t))); +} + +template < + typename T, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr T& operator&=(T& l, T2 right) { + T r = LowerBitmask::Lower(right); + l = l & r; + return l; +} + +template < + typename T, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr T& operator|=(T& l, T2 right) { + T r = LowerBitmask::Lower(right); + l = l | r; + return l; +} + +template < + typename T, + typename T2, + typename = typename std::enable_if::enable && LowerBitmask::enable>::type> +constexpr T& operator^=(T& l, T2 right) { + T r = LowerBitmask::Lower(right); + l = l ^ r; + return l; +} + +template +constexpr bool HasZeroOrOneBits(T value) { + using Integral = typename std::underlying_type::type; + return (static_cast(value) & (static_cast(value) - 1)) == 0; +} + +} // namespace wgpu + +#endif // WEBGPU_ENUM_CLASS_BITMASKS_H_ diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h new file mode 100644 index 000000000..c3e559742 --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h @@ -0,0 +1,689 @@ +#ifndef WEBGPU_WAGYU_H +#define WEBGPU_WAGYU_H + +#include "webgpu/webgpu.h" + +#define WGPU_WAGYU_EXTENSION_LEVEL 1 + +// Reserved range for Wagyu starts at 0x00060000 +// https://github.com/webgpu-native/webgpu-headers/blob/main/doc/articles/Extensions.md#registry-of-prefixes-and-enum-blocks +#define WGPU_WAGYU_RESERVED_RANGE_BASE 0x00060000 + +#define WGPU_WAGYU_MAKE_INIT_STRUCT _wgpu_MAKE_INIT_STRUCT + +#define WGPU_WAGYU_CHAIN_INIT(sType) \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUChainedStruct, { /*.next = */ NULL _wgpu_COMMA /*.sType = */ (WGPUSType) sType _wgpu_COMMA }) + +#define WGPU_WAGYU_STRLEN SIZE_MAX +#define WGPU_WAGYU_PIXEL_LOCAL_STORAGE_SIZE_UNDEFINED UINT32_MAX + +typedef struct WGPUWagyuExternalTextureImpl *WGPUWagyuExternalTexture WGPU_OBJECT_ATTRIBUTE; + +// These values extend the WGPUSType enum set from webgpu.h +typedef enum WGPUSType_Wagyu +{ + WGPUSType_WagyuAdapterInfo = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0001, + WGPUSType_WagyuColorTargetState = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0002, + WGPUSType_WagyuCommandEncoderDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0003, + WGPUSType_WagyuComputePipelineDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0004, + WGPUSType_WagyuDeviceDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0005, + WGPUSType_WagyuExternalTextureBindingEntry = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0006, + WGPUSType_WagyuExternalTextureBindingLayout = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0007, + WGPUSType_WagyuFragmentState = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0008, + WGPUSType_WagyuInputTextureBindingLayout = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0009, + WGPUSType_WagyuRenderPassDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000A, + WGPUSType_WagyuRenderPipelineDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000B, + WGPUSType_WagyuShaderModuleDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000C, + WGPUSType_WagyuSurfaceConfiguration = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000D, + WGPUSType_WagyuTextureDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000E, + WGPUSType_WagyuForce32 = 0x7FFFFFFF +} WGPUSType_Wagyu WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUWagyuDeviceFlushStatus +{ + WGPUWagyuDeviceFlushStatus_Success = 0x00000000, + WGPUWagyuDeviceFlushStatus_Error = 0x00000001, + WGPUWagyuDeviceFlushStatus_Force32 = 0x7FFFFFFF +} WGPUWagyuDeviceFlushStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUWagyuDevicePipelineBinaryCacheError +{ + WGPUWagyuDevicePipelineBinaryCacheError_Version = 0x00000000, + WGPUWagyuDevicePipelineBinaryCacheError_Corrupt = 0x00000001, + WGPUWagyuDevicePipelineBinaryCacheError_Link = 0x00000002, + WGPUWagyuDevicePipelineBinaryCacheError_Create = 0x00000003, + WGPUWagyuDevicePipelineBinaryCacheError_Force32 = 0x7FFFFFFF +} WGPUWagyuDevicePipelineBinaryCacheError WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUWagyuShaderLanguage +{ + WGPUWagyuShaderLanguage_Detect = 0x00000000, + WGPUWagyuShaderLanguage_GLSL = 0x00000001, + WGPUWagyuShaderLanguage_GLSLRAW = 0x00000002, + WGPUWagyuShaderLanguage_WGSL = 0x00000003, + WGPUWagyuShaderLanguage_SPIRV = 0x00000004, + WGPUWagyuShaderLanguage_Force32 = 0x7FFFFFFF +} WGPUWagyuShaderLanguage WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUWagyuWGSLFeatureType +{ + WGPUWagyuWGSLFeatureType_Testing = 0x00000001, + WGPUWagyuWGSLFeatureType_UnsafeExperimental = 0x00000002, + WGPUWagyuWGSLFeatureType_Experimental = 0x00000004, + WGPUWagyuWGSLFeatureType_All = 0x00000007, + WGPUWagyuWGSLFeatureType_Force32 = 0x7FFFFFFF +} WGPUWagyuWGSLFeatureType WGPU_ENUM_ATTRIBUTE; + +typedef WGPUFlags WGPUWagyuFragmentStateFeaturesFlags; +static const WGPUWagyuFragmentStateFeaturesFlags WGPUWagyuFragmentStateFeaturesFlags_None = 0x00000000; +static const WGPUWagyuFragmentStateFeaturesFlags WGPUWagyuFragmentStateFeaturesFlags_RasterizationOrderAttachmentAccess = 0x00000001; + +// These values extend the WGPUTextureUsage enum set from webgpu.h +static const WGPUTextureUsage WGPUTextureUsage_WagyuInputAttachment = (WGPUTextureUsage)(0x0000000040000000); +static const WGPUTextureUsage WGPUTextureUsage_WagyuTransientAttachment = (WGPUTextureUsage)(0x0000000020000000); + +// Forward declarations for callbacks +struct WGPUWagyuDevicePipelineBinaryCacheStatistics; +struct WGPUWagyuDevicePipelineBinaryEvent; +struct WGPUWagyuShaderEntryPointArray; + +typedef void (*WGPUWagyuDeviceFlushCallback)(WGPUDevice device, WGPUWagyuDeviceFlushStatus status, void *userdata1, void *userdata2) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUWagyuExecuteCallback)(void *userdata1, void *userdata2) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUWagyuPipelineBinaryCacheStatisticsCallback)(WGPUDevice device, WGPUWagyuDeviceFlushStatus status, const struct WGPUWagyuDevicePipelineBinaryCacheStatistics *statistics, void *userdata1, void *userdata2) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUWagyuPipelineBinaryCallback)(WGPUDevice device, const struct WGPUWagyuDevicePipelineBinaryEvent *event, void *userdata1, void *userdata2) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUWagyuPipelineBinaryErrorCallback)(WGPUDevice device, WGPUStringView reason, WGPUStringView message, void *userdata1, void *userdata2) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUWagyuShaderModuleEntryPointsCallback)(WGPUShaderModule shaderModule, WGPUWagyuDeviceFlushStatus status, const struct WGPUWagyuShaderEntryPointArray *entryPoints, void *userdata1, void *userdata2) WGPU_FUNCTION_ATTRIBUTE; + +typedef struct WGPUWagyuNrdpVersion +{ + uint32_t major; + uint32_t minor; + uint32_t patch; + uint32_t rev; +} WGPUWagyuNrdpVersion WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_NRDP_VERSION_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuNrdpVersion, { /*.major = */ 0 _wgpu_COMMA /*.minor = */ 0 _wgpu_COMMA /*.patch = */ 0 _wgpu_COMMA /*.rev = */ 0 _wgpu_COMMA }) + +typedef struct WGPUWagyuAdapterInfo +{ + WGPUChainedStruct chain; + uint32_t extensionLevel; + WGPUWagyuNrdpVersion nrdpVersion; +} WGPUWagyuAdapterInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_ADAPTER_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuAdapterInfo, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuAdapterInfo) _wgpu_COMMA /*.level*/ 0 _wgpu_COMMA /*.nrdpVersion*/ WGPU_WAGYU_NRDP_VERSION_INIT _wgpu_COMMA }) + +typedef struct WGPUWagyuColorTargetState +{ + WGPUChainedStruct chain; + WGPUOptionalBool usedAsInput; +} WGPUWagyuColorTargetState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_COLOR_TARGET_STATE_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuColorTargetState, \ + { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuColorTargetState) _wgpu_COMMA /*.usedAsInput*/ WGPUOptionalBool_Undefined _wgpu_COMMA }) + +typedef struct WGPUWagyuCommandEncoderDescriptor +{ + WGPUChainedStruct chain; + WGPUOptionalBool measureExecutionTime; +} WGPUWagyuCommandEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_COMMAND_ENCODER_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuCommandEncoderDescriptor, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuCommandEncoderDescriptor) _wgpu_COMMA /*.measureExecutionTime*/ WGPUOptionalBool_Undefined _wgpu_COMMA }) + +typedef struct WGPUWagyuComputePipelineDescriptor +{ + WGPUChainedStruct chain; + WGPUStringView cacheKey; +} WGPUWagyuComputePipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_COMPUTE_PIPELINE_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuComputePipelineDescriptor, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuComputePipelineDescriptor) _wgpu_COMMA /*.cacheKey*/ WGPU_STRING_VIEW_INIT _wgpu_COMMA }) + +typedef struct WGPUWagyuOrigin2D +{ + uint32_t x; + uint32_t y; +} WGPUWagyuOrigin2D WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_ORIGIN_2D_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuOrigin2D, { /* .x */ 0 _wgpu_COMMA /* .y */ 0 _wgpu_COMMA }) + +typedef struct WGPUWagyuCopyExternalImageSourceInfo +{ + WGPUStringView source; + WGPUWagyuOrigin2D origin; + WGPUBool flipY; +} WGPUWagyuCopyExternalImageSourceInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COPY_EXTERNAL_IMAGE_SOURCE_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuCopyExternalImageSourceInfo, { /* .source */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /* .origin */ WGPU_WAGYU_ORIGIN_2D_INIT _wgpu_COMMA /* .flipY */ WGPU_FALSE _wgpu_COMMA }) + +typedef struct WGPUWagyuCopyExternalImageDestInfo +{ + WGPUTexture texture; + uint32_t mipLevel; + WGPUOrigin3D origin; + WGPUTextureAspect aspect; + WGPUPredefinedColorSpace colorSpace; + WGPUBool premultipliedAlpha; +} WGPUWagyuCopyExternalImageDestInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_COPY_EXTERNAL_IMAGE_DEST_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuCopyExternalImageDestInfo, { /* .texture */ NULL _wgpu_COMMA /* .mipLevel */ 0 _wgpu_COMMA /* .origin */ WGPU_ORIGIN_3D_INIT _wgpu_COMMA /* .aspect */ WGPUTextureAspect_All _wgpu_COMMA /* .colorSpace */ WGPUPredefinedColorSpace_SRGB _wgpu_COMMA /* .premultipliedAlpha */ WGPU_FALSE _wgpu_COMMA }) + +typedef struct WGPUWagyuDeviceDescriptor +{ + WGPUChainedStruct chain; + WGPUOptionalBool dataBufferNeedsDetach; + WGPUOptionalBool wantsIndirectRendering; + WGPUOptionalBool wantsBufferClear; + WGPUOptionalBool wantsTextureClear; +} WGPUWagyuDeviceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDeviceDescriptor, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuDeviceDescriptor) _wgpu_COMMA /*.dataBufferNeedsDetach*/ WGPUOptionalBool_Undefined _wgpu_COMMA /*.wantsIndirectRendering*/ WGPUOptionalBool_Undefined _wgpu_COMMA /*.wantsBufferClear*/ WGPUOptionalBool_Undefined _wgpu_COMMA /*.wantsTextureClear*/ WGPUOptionalBool_Undefined _wgpu_COMMA }) + +typedef struct WGPUWagyuDeviceFlushCallbackInfo +{ + WGPUChainedStruct *nextInChain; + WGPUCallbackMode mode; + WGPUWagyuDeviceFlushCallback callback; + void *userdata1; + void *userdata2; +} WGPUWagyuDeviceFlushCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_FLUSH_CALLBACK_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDeviceFlushCallbackInfo, { /*.nextInChain = */ NULL _wgpu_COMMA /*.mode = */ WGPUCallbackMode_AllowSpontaneous _wgpu_COMMA /*.callback = */ NULL _wgpu_COMMA /*.userdata1 = */ NULL _wgpu_COMMA /*.userdata2 = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuExecuteCallbackInfo +{ + WGPUChainedStruct *nextInChain; + WGPUCallbackMode mode; + WGPUWagyuExecuteCallback callback; + void *userdata1; + void *userdata2; +} WGPUWagyuExecuteCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_EXECUTE_CALLBACK_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuExecuteCallbackInfo, { /*.nextInChain = */ NULL _wgpu_COMMA /*.mode = */ WGPUCallbackMode_AllowSpontaneous _wgpu_COMMA /*.callback = */ NULL _wgpu_COMMA /*.userdata1 = */ NULL _wgpu_COMMA /*.userdata2 = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuDevicePipelineBinary +{ + size_t binarySize; + void *binary; + size_t blobKeySize; + void *blobKey; +} WGPUWagyuDevicePipelineBinary WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_PIPELINE_BINARY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDevicePipelineBinary, { /*.binarySize*/ 0 _wgpu_COMMA /*.binary*/ NULL _wgpu_COMMA /*.blobKeySize*/ 0 _wgpu_COMMA /*.blobKey*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuDevicePipelineBinaryBlobKey +{ + size_t size; + const void *data; +} WGPUWagyuDevicePipelineBinaryBlobKey WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_PIPELINE_BINARY_BLOB_KEY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDevicePipelineBinaryBlobKey, { /*.size*/ 0 _wgpu_COMMA /*.data*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuDevicePipelineBinaryCacheKey +{ + WGPUStringView cacheKey; + size_t blobKeysLength; + WGPUWagyuDevicePipelineBinaryBlobKey *blobKeys; +} WGPUWagyuDevicePipelineBinaryCacheKey WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_PIPELINE_BINARY_CACHE_KEY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDevicePipelineBinaryCacheKey, { /*.cacheKey*/ WGPU_STRING_VIEW_INIT _wgpu_COMMA /*.blobKeysLength*/ 0 _wgpu_COMMA /*.blobKeys*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuDevicePipelineBinaryCacheStatistics +{ + uint32_t hits; + uint32_t misses; + size_t entryCount; + WGPUStringView *entries; + size_t errorCount; + WGPUWagyuDevicePipelineBinaryCacheError *errors; +} WGPUWagyuDevicePipelineBinaryCacheStatistics WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_PIPELINE_BINARY_CACHE_STATISTICS_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDevicePipelineBinaryCacheStatistics, { /*.hits*/ 0 _wgpu_COMMA /*.misses*/ 0 _wgpu_COMMA /*.entryCount*/ 0 _wgpu_COMMA /*.entries*/ NULL _wgpu_COMMA /*.errorCount*/ 0 _wgpu_COMMA /*.errors*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuPipelineBinaryCacheStatisticsCallbackInfo +{ + WGPUChainedStruct *nextInChain; + WGPUCallbackMode mode; + WGPUWagyuPipelineBinaryCacheStatisticsCallback callback; + void *userdata1; + void *userdata2; +} WGPUWagyuPipelineBinaryCacheStatisticsCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_PIPELINE_BINARY_CACHE_STATISTICS_CALLBACK_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuPipelineBinaryCacheStatisticsCallbackInfo, { /*.nextInChain = */ NULL _wgpu_COMMA /*.mode = */ WGPUCallbackMode_AllowSpontaneous _wgpu_COMMA /*.callback = */ NULL _wgpu_COMMA /*.userdata1 = */ NULL _wgpu_COMMA /*.userdata2 = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuDevicePipelineBinaryData +{ + size_t binariesLength; + WGPUWagyuDevicePipelineBinary *binaries; + size_t cacheKeysLength; + WGPUWagyuDevicePipelineBinaryCacheKey *cacheKeys; +} WGPUWagyuDevicePipelineBinaryData WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_PIPELINE_BINARY_DATA_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDevicePipelineBinaryData, { /*.binariesLength*/ 0 _wgpu_COMMA /*.binaries*/ NULL _wgpu_COMMA /*.cacheKeysLength*/ 0 _wgpu_COMMA /*.cacheKeys*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuDevicePipelineBinaryEvent +{ + WGPUStringView cacheKey; + WGPUStringView pipelineLabel; + size_t binariesLength; + const WGPUWagyuDevicePipelineBinary *binaries; +} WGPUWagyuDevicePipelineBinaryEvent WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_DEVICE_PIPELINE_BINARY_EVENT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDevicePipelineBinaryEvent, { /*.cacheKey*/ WGPU_STRING_VIEW_INIT _wgpu_COMMA /*.pipelineLabel*/ WGPU_STRING_VIEW_INIT _wgpu_COMMA /*.binariesLength*/ 0 _wgpu_COMMA /*.binaries*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuExternalTextureDescriptor +{ + const WGPUChainedStruct *nextInChain; + WGPUStringView label; + WGPUStringView source; + WGPUPredefinedColorSpace colorSpace; +} WGPUWagyuExternalTextureDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_EXTERNAL_TEXTURE_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuExternalTextureDescriptor, { /*nextInChain = */ NULL _wgpu_COMMA /*label = */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /*source = */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /*colorSpace = */ WGPUPredefinedColorSpace_SRGB _wgpu_COMMA }) + +typedef struct WGPUWagyuExternalTextureInfo +{ + uint32_t visibleWidth; + uint32_t visibleHeight; + uint32_t textureWidth; + uint32_t textureHeight; + int64_t pts; +} WGPUWagyuExternalTextureInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_EXTERNAL_TEXTURE_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuExternalTextureInfo, { /*.visibleWidth*/ 0 _wgpu_COMMA /*.visibleHeight*/ 0 _wgpu_COMMA /*.textureWidth*/ 0 _wgpu_COMMA /*.textureHeight*/ 0 _wgpu_COMMA /*.pts*/ 0 _wgpu_COMMA }) + +typedef struct WGPUWagyuExternalTextureBindingEntry +{ + WGPUChainedStruct chain; + WGPUWagyuExternalTexture externalTexture; +} WGPUWagyuExternalTextureBindingEntry WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_EXTERNAL_TEXTURE_BINDING_ENTRY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuExternalTextureBindingEntry, \ + { /*.chain = */ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuExternalTextureBindingEntry) _wgpu_COMMA /*.externalTexture = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuExternalTextureBindingLayout +{ + WGPUChainedStruct chain; +} WGPUWagyuExternalTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_EXTERNAL_TEXTURE_BINDING_LAYOUT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuExternalTextureBindingLayout, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuExternalTextureBindingLayout) _wgpu_COMMA }) + +typedef struct WGPUWagyuInputAttachmentState +{ + WGPUTextureFormat format; + WGPUOptionalBool usedAsColor; +} WGPUWagyuInputAttachmentState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_INPUT_ATTACHMENT_STATE_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuInputAttachmentState, \ + { /*.format*/ WGPUTextureFormat_Undefined _wgpu_COMMA /*.usedAsColor*/ WGPUOptionalBool_Undefined _wgpu_COMMA }) + +typedef struct WGPUWagyuFragmentState +{ + WGPUChainedStruct chain; + size_t inputCount; + WGPU_NULLABLE WGPUWagyuInputAttachmentState *inputs; + WGPUWagyuFragmentStateFeaturesFlags featureFlags; +} WGPUWagyuFragmentState WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_FRAGMENT_STATE_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuFragmentState, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuFragmentState) _wgpu_COMMA /*.inputCount*/ 0 _wgpu_COMMA /*.inputs*/ NULL _wgpu_COMMA /*.featureFlags*/ WGPUWagyuFragmentStateFeaturesFlags_None _wgpu_COMMA }) + +typedef struct WGPUWagyuInputTextureBindingLayout +{ + WGPUChainedStruct chain; + WGPUTextureViewDimension viewDimension; +} WGPUWagyuInputTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_INPUT_TEXTURE_BINDING_LAYOUT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuInputTextureBindingLayout, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuInputTextureBindingLayout) _wgpu_COMMA /*.viewDimension*/ WGPUTextureViewDimension_2D _wgpu_COMMA }) + +typedef struct WGPUWagyuPipelineBinaryCallbackInfo +{ + WGPUChainedStruct *nextInChain; + WGPUCallbackMode mode; + WGPUWagyuPipelineBinaryCallback callback; + void *userdata1; + void *userdata2; +} WGPUWagyuPipelineBinaryCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_PIPELINE_BINARY_CALLBACK_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuPipelineBinaryCallbackInfo, { /*.nextInChain = */ NULL _wgpu_COMMA /*.mode = */ WGPUCallbackMode_AllowSpontaneous _wgpu_COMMA /*.callback = */ NULL _wgpu_COMMA /*.userdata1 = */ NULL _wgpu_COMMA /*.userdata2 = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuPipelineBinaryErrorCallbackInfo +{ + WGPUChainedStruct *nextInChain; + WGPUCallbackMode mode; + WGPUWagyuPipelineBinaryErrorCallback callback; + void *userdata1; + void *userdata2; +} WGPUWagyuPipelineBinaryErrorCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_PIPELINE_BINARY_ERROR_CALLBACK_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuPipelineBinaryErrorCallbackInfo, { /*.nextInChain = */ NULL _wgpu_COMMA /*.mode = */ WGPUCallbackMode_AllowSpontaneous _wgpu_COMMA /*.callback = */ NULL _wgpu_COMMA /*.userdata1 = */ NULL _wgpu_COMMA /*.userdata2 = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuRect +{ + int32_t x; + int32_t y; + uint32_t width; + uint32_t height; +} WGPUWagyuRect WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_RECT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuRect, { /* .x */ 0 _wgpu_COMMA /* .y */ 0 _wgpu_COMMA /* .width */ 0 _wgpu_COMMA /* .height */ 0 _wgpu_COMMA }) + +typedef struct WGPUWagyuRenderPassInputAttachment +{ + WGPUTextureView view; + WGPU_NULLABLE WGPUColor *clearValue; + WGPULoadOp loadOp; + WGPUStoreOp storeOp; +} WGPUWagyuRenderPassInputAttachment WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_RENDER_PASS_INPUT_ATTACHMENT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuRenderPassInputAttachment, { /* .view */ NULL _wgpu_COMMA /* .clearValue */ NULL _wgpu_COMMA /* .loadOp */ WGPULoadOp_Undefined _wgpu_COMMA /* .storeOp */ WGPUStoreOp_Undefined _wgpu_COMMA }) + +typedef struct WGPUWagyuRenderPassDescriptor +{ + WGPUChainedStruct chain; + size_t inputAttachmentCount; + WGPU_NULLABLE WGPUWagyuRenderPassInputAttachment *inputAttachments; + WGPUOptionalBool pixelLocalStorageEnabled; + uint32_t pixelLocalStorageSize; +} WGPUWagyuRenderPassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_RENDER_PASS_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuRenderPassDescriptor, { /* .chain */ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuRenderPassDescriptor) _wgpu_COMMA /* .inputAttachmentCount */ 0 _wgpu_COMMA /* .inputAttachments */ NULL _wgpu_COMMA /* .pixelLocalStorageEnabled */ WGPUOptionalBool_Undefined _wgpu_COMMA /* .pixelLocalStorageSize */ WGPU_WAGYU_PIXEL_LOCAL_STORAGE_SIZE_UNDEFINED _wgpu_COMMA }) + +typedef struct WGPUWagyuRenderPipelineDescriptor +{ + WGPUChainedStruct chain; + WGPUStringView cacheKey; +} WGPUWagyuRenderPipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_RENDER_PIPELINE_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuRenderPipelineDescriptor, { /* .chain */ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuRenderPipelineDescriptor) _wgpu_COMMA /* .cacheKey */ WGPU_STRING_VIEW_INIT _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderModuleEntryPointsCallbackInfo +{ + WGPUChainedStruct *nextInChain; + WGPUCallbackMode mode; + WGPUWagyuShaderModuleEntryPointsCallback callback; + void *userdata1; + void *userdata2; +} WGPUWagyuShaderModuleEntryPointsCallbackInfo WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_MODULE_ENTRY_POINTS_CALLBACK_INFO_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderModuleEntryPointsCallbackInfo, { /*.nextInChain = */ NULL _wgpu_COMMA /*.mode = */ WGPUCallbackMode_AllowSpontaneous _wgpu_COMMA /*.callback = */ NULL _wgpu_COMMA /*.userdata1 = */ NULL _wgpu_COMMA /*.userdata2 = */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderReflectionStructMember +{ + WGPUStringView name; + uint32_t group; + uint32_t binding; + uint32_t offset; + uint32_t size; + uint32_t type; + WGPUBool imageMultisampled; + WGPUTextureViewDimension imageDimension; + WGPUTextureFormat imageFormat; +} WGPUWagyuShaderReflectionStructMember WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_REFLECTION_STRUCT_MEMBER_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderReflectionStructMember, { /* .name */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /* .group */ 0 _wgpu_COMMA /* .binding */ 0 _wgpu_COMMA /* .offset */ 0 _wgpu_COMMA /* .size */ 0 _wgpu_COMMA /* .type */ 0 _wgpu_COMMA /* .imageMultisampled */ WGPU_FALSE _wgpu_COMMA /* .imageDimension */ WGPUTextureViewDimension_Undefined _wgpu_COMMA /* .imageFormat */ WGPUTextureFormat_Undefined _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderReflectionLocation +{ + WGPUStringView name; + uint32_t location; + uint32_t size; + uint32_t type; +} WGPUWagyuShaderReflectionLocation WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_REFLECTION_LOCATION_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderReflectionLocation, { /* .name */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /* .location */ 0 _wgpu_COMMA /* .size */ 0 _wgpu_COMMA /* .type */ 0 _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderReflectionResource +{ + WGPUStringView name; + uint32_t group; + uint32_t binding; + uint32_t bindingType; + WGPUBool multisampled; + WGPUTextureViewDimension dimension; + WGPUTextureFormat format; + uint64_t bufferSize; +} WGPUWagyuShaderReflectionResource WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_REFLECTION_RESOURCE_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderReflectionResource, { /* .name */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /* .group */ 0 _wgpu_COMMA /* .binding */ 0 _wgpu_COMMA /* .bindingType */ 0 _wgpu_COMMA /* .multisampled */ WGPU_FALSE _wgpu_COMMA /* .dimension */ WGPUTextureViewDimension_Undefined _wgpu_COMMA /* .format */ WGPUTextureFormat_Undefined _wgpu_COMMA /* .bufferSize */ 0 _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderReflectionSpecializationConstant +{ + uint32_t id; + uint32_t internalId; + uint32_t type; + WGPUStringView name; +} WGPUWagyuShaderReflectionSpecializationConstant WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_REFLECTION_SPECIALIZATION_CONSTANT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderReflectionSpecializationConstant, { /* .id */ 0 _wgpu_COMMA /* .internalId */ 0 _wgpu_COMMA /* .type */ 0 _wgpu_COMMA /* .name */ WGPU_STRING_VIEW_INIT _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderReflectionData +{ + size_t resourceCount; + WGPUWagyuShaderReflectionResource *resources; + size_t constantCount; + WGPUWagyuShaderReflectionSpecializationConstant *constants; + size_t uniformCount; + WGPUWagyuShaderReflectionStructMember *uniforms; + size_t attributeCount; + WGPUWagyuShaderReflectionLocation *attributes; + WGPUStringView wgsl; +} WGPUWagyuShaderReflectionData WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_REFLECTION_DATA_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderReflectionData, { /* .resourceCount */ 0 _wgpu_COMMA /* .resources */ NULL _wgpu_COMMA /* .constantCount */ 0 _wgpu_COMMA /* .constants */ NULL _wgpu_COMMA /* .uniformCount */ 0 _wgpu_COMMA /* .uniforms */ NULL _wgpu_COMMA /* .attributeCount */ 0 _wgpu_COMMA /* .attributes */ NULL _wgpu_COMMA /* .wgsl */ WGPU_STRING_VIEW_INIT _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderEntryPoint +{ + WGPUStringView entryPoint; + WGPUShaderStage stage; + WGPUWagyuShaderReflectionData reflection; +} WGPUWagyuShaderEntryPoint WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_ENTRY_POINT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderEntryPoint, { /* .entryPoint */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /* .stage */ WGPUShaderStage_NONE _wgpu_COMMA /* .reflection */ WGPU_WAGYU_SHADER_REFLECTION_DATA_INIT _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderEntryPointArray +{ + size_t entryPointCount; + WGPUWagyuShaderEntryPoint *entryPoints; +} WGPUWagyuShaderEntryPointArray WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_ENTRY_POINT_ARRAY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderEntryPointArray, { /* .entryPointCount */ 0 _wgpu_COMMA /* .entryPoints */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderModuleCompilationHint +{ + WGPUChainedStruct *nextInChain; + WGPUStringView entryPoint; + /** + * If set to NULL, it will be treated as "auto" + */ + WGPUPipelineLayout layout; +} WGPUWagyuShaderModuleCompilationHint; + +#define WGPU_WAGYU_SHADER_MODULE_COMPILATION_HINT_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderModuleCompilationHint, { /* .nextInChain */ NULL _wgpu_COMMA /* .entryPoint */ WGPU_STRING_VIEW_INIT _wgpu_COMMA /* .layout */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuShaderModuleDescriptor +{ + WGPUChainedStruct chain; + size_t codeSize; // bytes + const void *code; + WGPUWagyuShaderLanguage language; + size_t compilationHintCount; + const struct WGPUWagyuShaderModuleCompilationHint *compilationHints; +} WGPUWagyuShaderModuleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SHADER_MODULE_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuShaderModuleDescriptor, { /*.chain=*/WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuShaderModuleDescriptor) _wgpu_COMMA /*.codeSize*/ 0 _wgpu_COMMA /*.code*/ NULL _wgpu_COMMA /*.language*/ WGPUWagyuShaderLanguage_Detect _wgpu_COMMA /*.compilationHintCount*/ 0 _wgpu_COMMA /*.compilationHints*/ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuStringArray +{ + size_t stringCount; + WGPU_NULLABLE WGPUStringView *strings; +} WGPUWagyuStringArray WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_STRING_ARRAY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuStringArray, { /* .stringCount */ 0 _wgpu_COMMA /* .strings */ NULL _wgpu_COMMA }) + +typedef struct WGPUWagyuSurfaceConfiguration +{ + WGPUChainedStruct chain; + int32_t *indirectRenderTargets; + WGPUPredefinedColorSpace colorSpace; + WGPUToneMappingMode toneMappingMode; +} WGPUWagyuSurfaceConfiguration WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_SURFACE_CONFIGURATION_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuSurfaceConfiguration, { /*.chain=*/WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuSurfaceConfiguration) _wgpu_COMMA /*.indirectRenderTargets*/ NULL _wgpu_COMMA /*.colorSpace*/ WGPUPredefinedColorSpace_SRGB _wgpu_COMMA /*.toneMappingMode*/ WGPUToneMappingMode_Standard _wgpu_COMMA }) + +typedef struct WGPUWagyuTextureDescriptor +{ + WGPUChainedStruct chain; + WGPUBool useSurfaceCache; +} WGPUWagyuTextureDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_TEXTURE_DESCRIPTOR_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuTextureDescriptor, { /*.chain = */ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuTextureDescriptor) _wgpu_COMMA /*.useSurfaceCache = */ WGPU_TRUE _wgpu_COMMA }) + +typedef struct WGPUWagyuWGSLFeatureTypeArray +{ + size_t featureCount; + WGPU_NULLABLE WGPUWagyuWGSLFeatureType *features; +} WGPUWagyuWGSLFeatureTypeArray WGPU_STRUCTURE_ATTRIBUTE; + +#define WGPU_WAGYU_WGSL_FEATURE_TYPE_ARRAY_INIT \ + WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuWGSLFeatureTypeArray, { /* .featureCount */ 0 _wgpu_COMMA /* .features */ NULL _wgpu_COMMA }) + +#if defined(__cplusplus) && !defined(__cppcheck) +extern "C" { +#endif + +WGPU_EXPORT WGPUBackendType wgpuWagyuAdapterGetBackend(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuAdapterGetExtensions(WGPUAdapter adapter, WGPUWagyuStringArray *extensions) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuAdapterGetGraphicsReport(WGPUAdapter adapter, WGPUStringView *graphicsReport) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuAdapterGetName(WGPUAdapter adapter, WGPUStringView *name) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUDevice wgpuWagyuAdapterRequestDeviceSync(WGPUAdapter adapter, WGPU_NULLABLE const WGPUDeviceDescriptor *options) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuCommandEncoderBlit(WGPUCommandEncoder commandEncoder, const WGPUTexelCopyTextureInfo *source, const WGPUExtent3D *sourceExtent, const WGPUTexelCopyTextureInfo *destination, const WGPUExtent3D *destinationExtent, WGPUFilterMode filter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuCommandEncoderExecuteCallback(WGPUCommandEncoder commandEncoder, WGPUWagyuExecuteCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuCommandEncoderGenerateMipmap(WGPUCommandEncoder commandEncoder, WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuComputePassEncoderExecuteCallback(WGPUComputePassEncoder computePassEncoder, WGPUWagyuExecuteCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuDeviceClearPipelineBinaryCache(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuDeviceEnableImaginationWorkarounds(WGPUDevice device, WGPUBool enable) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuDeviceGetExtensions(WGPUDevice device, WGPUWagyuStringArray *extensions) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuWagyuDeviceFlush(WGPUDevice device, WGPUWagyuDeviceFlushCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUWagyuExternalTexture wgpuWagyuDeviceImportExternalTexture(WGPUDevice device, const WGPUWagyuExternalTextureDescriptor *descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuDeviceIntrospectShaderCode(WGPUDevice device, WGPUShaderStage stages, const WGPUShaderModuleDescriptor *descriptor, WGPUWagyuShaderEntryPointArray *entryPoints) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuWagyuDevicePipelineBinaryCacheStatistics(WGPUDevice device, WGPUWagyuPipelineBinaryCacheStatisticsCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuDevicePopulatePipelineBinaryCache(WGPUDevice device, const WGPUWagyuDevicePipelineBinaryData *data) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuDeviceSetPipelineBinaryCallback(WGPUDevice device, WGPUWagyuPipelineBinaryCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuDeviceSetPipelineBinaryErrorCallback(WGPUDevice device, WGPUWagyuPipelineBinaryErrorCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuExternalTextureAddRef(WGPUWagyuExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuExternalTextureGetInfo(WGPUWagyuExternalTexture externalTexture, WGPUWagyuExternalTextureInfo *info) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuExternalTextureRelease(WGPUWagyuExternalTexture externalTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuExternalTextureSetLabel(WGPUWagyuExternalTexture externalTexture, WGPUStringView label) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuInstanceEnableImaginationWorkarounds(WGPUInstance instance, WGPUBool enable) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuWagyuInstanceGetApiVersion(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBackendType wgpuWagyuInstanceGetBackend(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceGetExposedWgslFeatures(WGPUInstance instance, WGPUWagyuWGSLFeatureTypeArray *wgslFeatures) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureFormat wgpuWagyuInstanceGetScreenDirectFormat(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureFormat wgpuWagyuInstanceGetScreenIndirectFormat(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuWagyuInstanceGetSync(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUAdapter wgpuWagyuInstanceRequestAdapterSync(WGPUInstance instance, WGPU_NULLABLE const WGPURequestAdapterOptions *options) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceSetCommandBufferLimit(WGPUInstance instance, uint32_t limit) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceSetExposedWgslFeatures(WGPUInstance instance, const WGPUWagyuWGSLFeatureTypeArray *wgslFeatures) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceSetImmediate(WGPUInstance instance, WGPUBool enabled) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceSetRunBarriersOnIncoherent(WGPUInstance instance, WGPUBool run) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceSetStagingBufferCacheSize(WGPUInstance instance, uint32_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuInstanceSetSync(WGPUInstance instance, WGPUBool sync) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuQueueCopyExternalImageToTexture(WGPUQueue queue, const WGPUWagyuCopyExternalImageSourceInfo *source, const WGPUWagyuCopyExternalImageDestInfo *destination, const WGPUExtent3D *copySize) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderClearColorAttachments(WGPURenderBundleEncoder renderBundleEncoder, const WGPUWagyuRect *rect, uint32_t baseAttachment, uint32_t numAttachments, const WGPUColor *color, uint32_t baseArrayLayer, uint32_t layerCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderClearDepthAttachment(WGPURenderBundleEncoder renderBundleEncoder, const WGPUWagyuRect *rect, float depth, uint32_t baseArrayLayer, uint32_t layerCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderClearPixelLocalStorage(WGPURenderBundleEncoder renderBundleEncoder, uint32_t offset, uint32_t size, WGPU_NULLABLE const uint32_t *values) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderClearStencilAttachment(WGPURenderBundleEncoder renderBundleEncoder, const WGPUWagyuRect *rect, uint32_t stencil, uint32_t baseArrayLayer, uint32_t layerCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderExecuteCallback(WGPURenderBundleEncoder renderBundleEncoder, WGPUWagyuExecuteCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderSetScissorRect(WGPURenderBundleEncoder renderBundleEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderSetScissorRectIndirect(WGPURenderBundleEncoder renderBundleEncoder, uint64_t indirectOffset, const uint32_t *indirectBuffer, size_t indirectBufferCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderSetViewport(WGPURenderBundleEncoder renderBundleEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderSetViewportWithDepthIndirect(WGPURenderBundleEncoder renderBundleEncoder, uint64_t indirectOffset, const float *indirectBuffer, size_t indirectBufferCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderBundleEncoderSetViewportWithoutDepthIndirect(WGPURenderBundleEncoder renderBundleEncoder, uint64_t indirectOffset, const float *indirectBuffer, size_t indirectBufferCount) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuRenderPassEncoderClearColorAttachments(WGPURenderPassEncoder renderPassEncoder, const WGPUWagyuRect *rect, uint32_t baseAttachment, uint32_t numAttachments, const WGPUColor *color, uint32_t baseArrayLayer, uint32_t layerCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderPassEncoderClearDepthAttachment(WGPURenderPassEncoder renderPassEncoder, const WGPUWagyuRect *rect, float depth, uint32_t baseArrayLayer, uint32_t layerCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderPassEncoderClearStencilAttachment(WGPURenderPassEncoder renderPassEncoder, const WGPUWagyuRect *rect, uint32_t stencil, uint32_t baseArrayLayer, uint32_t layerCount) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderPassEncoderClearPixelLocalStorage(WGPURenderPassEncoder renderPassEncoder, uint32_t offset, uint32_t size, WGPU_NULLABLE const uint32_t *values) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderPassEncoderExecuteBundle(WGPURenderPassEncoder renderPassEncoder, WGPURenderBundle bundle) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuRenderPassEncoderExecuteCallback(WGPURenderPassEncoder renderPassEncoder, WGPUWagyuExecuteCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuShaderEntryPointArrayFreeMembers(WGPUWagyuShaderEntryPointArray shaderEntryPointArray) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuShaderModuleDestroy(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUFuture wgpuWagyuShaderModuleEntryPoints(WGPUShaderModule shaderModule, uint32_t stage, WGPUWagyuShaderModuleEntryPointsCallbackInfo callbackInfo) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuShaderModuleIntrospect(WGPUShaderModule shaderModule, WGPUShaderStage stages, WGPUWagyuShaderEntryPointArray *shaderEntryPointArray) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuStringArrayFreeMembers(WGPUWagyuStringArray stringArray) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuSurfaceDestroy(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTexture wgpuWagyuSurfaceGetCurrentDepthStencilTexture(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT float wgpuWagyuSurfaceGetHeight(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT float wgpuWagyuSurfaceGetWidth(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT float wgpuWagyuSurfaceGetX(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT float wgpuWagyuSurfaceGetY(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuSurfacePresent(WGPUSurface surface, WGPUTexture target) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuSurfaceSetHeight(WGPUSurface surface, float height) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuSurfaceSetWidth(WGPUSurface surface, float width) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuSurfaceSetX(WGPUSurface surface, float x) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuSurfaceSetY(WGPUSurface surface, float y) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT WGPUBool wgpuWagyuTextureIsSwapchain(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuWagyuTextureReadPixels(WGPUTexture texture, void *data, size_t dataSize) WGPU_FUNCTION_ATTRIBUTE; + +WGPU_EXPORT void wgpuWagyuWGSLFeatureTypeArrayFreeMembers(WGPUWagyuWGSLFeatureTypeArray wgslFeatureTypeArray) WGPU_FUNCTION_ATTRIBUTE; + +#if defined(__cplusplus) && !defined(__cppcheck) +} // extern "C" +#endif + +#endif /* WEBGPU_WAGYU_H */ diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/src/webgpu.c b/thirdparty/rive_renderer/source/webgpu/wagyu-port/src/webgpu.c new file mode 100644 index 000000000..0c1924d2b --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/src/webgpu.c @@ -0,0 +1,22 @@ +#include "webgpu/webgpu_wagyu.h" + +#define WGPU_WAGYU_HEADER_VERSION_MAJOR 1 +#define WGPU_WAGYU_HEADER_VERSION_MINOR 0 + +#define WASM_EXPORT(NAME) __attribute__((used, export_name(#NAME))) NAME + +typedef struct WGPUWagyuVersionInfo +{ + uint32_t webgpuMajor; + uint32_t webgpuMinor; + uint32_t wagyuExtensionLevel; +} WGPUWagyuVersionInfo; + +void WASM_EXPORT(wgpuWagyuGetCompiledVersion)(WGPUWagyuVersionInfo *versionInfo) +{ + if (versionInfo) { + versionInfo->webgpuMajor = WGPU_WAGYU_HEADER_VERSION_MAJOR; + versionInfo->webgpuMinor = WGPU_WAGYU_HEADER_VERSION_MINOR; + versionInfo->wagyuExtensionLevel = WGPU_WAGYU_EXTENSION_LEVEL; + } +} diff --git a/thirdparty/rive_renderer/source/webgpu/wagyu-port/webgpu-port.py b/thirdparty/rive_renderer/source/webgpu/wagyu-port/webgpu-port.py new file mode 100644 index 000000000..cb91db092 --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/wagyu-port/webgpu-port.py @@ -0,0 +1,123 @@ +# Emscripten WebGPU port with optional Wagyu extensions + + +import os +import zlib +from typing import Dict, Optional + + +OPTIONS = { + 'wagyu': "Enable Wagyu extensions (default: false)", +} +_VALID_OPTION_VALUES = { + 'wagyu': {'true', 'false'}, +} +_opts: Dict[str, Optional[str]] = { + 'wagyu': 'false', +} + + +def _get_base_dir(): + return os.path.dirname(os.path.realpath(__file__)) + + +def _get_include_dir(): + return os.path.join(_get_base_dir(), 'include') + + +def _get_src_dir(): + return os.path.join(_get_base_dir(), 'src') + + +def _get_srcs(): + return [ _get_src_dir() + '/webgpu.c' ] + +def _recurse_dir(path): + for (dirpath, dirnames, filenames) in os.walk(path): + for filename in filenames: + yield os.path.join(dirpath, filename) + + +def _get_build_files(): + return sorted([ + __file__, + *_get_srcs(), + *_recurse_dir(_get_include_dir()), + ]) + + +# compiler + +def _check_option(option, value, error_handler): + if value not in _VALID_OPTION_VALUES[option]: + error_handler( + f'[{option}] can be {list(_VALID_OPTION_VALUES[option])}, got [{value}]' + ) + return value + + +def handle_options(options, error_handler): + for option, value in options.items(): + value = value.lower() + _opts[option] = _check_option(option, value, error_handler) + + +def process_args(ports): + args = ['-isystem', _get_include_dir()] + return args + + +# linker + +def _get_flags(settings): + lib_name_suffix = '' + flags = [] + return (lib_name_suffix, flags) + + +def _get_name(settings): + hash_value = 0 + + def add(x): + nonlocal hash_value + hash_value = zlib.adler32(x, hash_value) + + build_files = _get_build_files() + for filename in build_files: + add(open(filename, 'rb').read()) + + (lib_name_suffix, _) = _get_flags(settings) + return f'libwebgpu-{hash_value:08x}{lib_name_suffix}.a' + + +def clear(ports, settings, shared): + shared.cache.erase_lib(_get_name(settings)) + + +def get(ports, settings, shared): + if settings.allowed_settings: + return [] + + def create(final): + includes = [_get_include_dir()] + (_, flags) = _get_flags(settings) + flags += [] + ports.build_port(_get_src_dir(), final, 'webgpu', includes=includes, flags=flags, srcs=_get_srcs()) + + lib_name = _get_name(settings) + return [shared.cache.get_lib(lib_name, create, what='port')] + + +def linker_setup(ports, settings): + if settings.USE_WEBGPU: + raise Exception('webgpu-port is not compatible with deprecated Emscripten USE_WEBGPU option') + + src_dir = _get_src_dir() + + settings.JS_LIBRARIES += [ os.path.join(src_dir, 'library_webgpu_stubs.js') ] + + # Ensure the function gets exported + settings.EXPORTED_FUNCTIONS += ['_wgpuWagyuGetCompiledVersion'] + + if _opts['wagyu'] == 'true': + settings.JS_LIBRARIES += [ os.path.join(src_dir, 'library_webgpu_wagyu_stubs.js') ] diff --git a/thirdparty/rive_renderer/source/webgpu/webgpu_compat.h b/thirdparty/rive_renderer/source/webgpu/webgpu_compat.h new file mode 100644 index 000000000..56c7444e1 --- /dev/null +++ b/thirdparty/rive_renderer/source/webgpu/webgpu_compat.h @@ -0,0 +1,640 @@ +#ifndef WEBGPU_COMPAT_H +#define WEBGPU_COMPAT_H + +#define WGPU_DEPTH_CLEAR_VALUE_UNDEFINED NAN + +#define WGPUTexelCopyBufferInfo WGPUImageCopyBuffer +#define WGPUTexelCopyTextureInfo WGPUImageCopyTexture +#define WGPUTexelCopyBufferLayout WGPUTextureDataLayout +#define WGPUInstanceCapabilities WGPUInstanceFeatures + +#if !defined(WGPUOptionalBool) +#define WGPUOptionalBool int32_t +#define WGPUOptionalBool_False 0x00000000 +#define WGPUOptionalBool_True 0x00000001 +#define WGPUOptionalBool_Undefined 0x00000002 +#define WGPUOptionalBool_Force32 0x7FFFFFFF +#endif + +#define WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal \ + WGPUSurfaceGetCurrentTextureStatus_Success + +#define WGPUMapAsyncStatus_Success WGPUBufferMapAsyncStatus_Success +#define WGPUMapAsyncStatus_Force32 WGPUBufferMapAsyncStatus_Force32 + +#define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor +#define WGPUStatus int + +#define WGPUStatus_Success 1 + +#define wgpuGetInstanceCapabilities wgpuGetInstanceFeatures + +#define WGPUMapAsyncStatus WGPUBufferMapAsyncStatus +#define WGPUShaderSourceWGSL WGPUShaderModuleWGSLDescriptor +#define WGPURenderPassMaxDrawCount WGPURenderPassDescriptorMaxDrawCount +#define WGPUWGSLLanguageFeatureName WGPUWGSLFeatureName + +#define WGPUEmscriptenSurfaceSourceCanvasHTMLSelector \ + WGPUSurfaceDescriptorFromCanvasHTMLSelector +#define WGPUWGSLLanguageFeatureName_Force32 WGPUWGSLFeatureName_Force32 +#define WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector \ + WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector +#define WGPUSType_RenderPassMaxDrawCount \ + WGPUSType_RenderPassDescriptorMaxDrawCount +#define WGPUSType_ShaderSourceWGSL WGPUSType_ShaderModuleWGSLDescriptor +#define WGPUWGSLLanguageFeatureName_Packed4x8IntegerDotProduct \ + WGPUWGSLFeatureName_Packed4x8IntegerDotProduct +#define WGPUWGSLLanguageFeatureName_PointerCompositeAccess \ + WGPUWGSLFeatureName_PointerCompositeAccess +#define WGPUWGSLLanguageFeatureName_ReadonlyAndReadwriteStorageTextures \ + WGPUWGSLFeatureName_ReadonlyAndReadwriteStorageTextures +// #define WGPUWGSLLanguageFeatureName_Undefined WGPUWGSLFeatureName_Undefined +#define WGPUWGSLLanguageFeatureName_UnrestrictedPointerParameters \ + WGPUWGSLFeatureName_UnrestrictedPointerParameters + +#define WGPU_STRING_VIEW(s) s +#define WGPU_STRING_VIEW_INIT NULL +#define WGPU_STRING_VIEW_TO_STRING(s) std::string(s) +#define WGPU_STRING_VIEW_TO_CSTR(s) s +#define WGPU_STRING_VIEW_FROM_STRING(s) strdup(s.c_str()) +#define WGPU_STRING_VIEW_FREE(s) free(const_cast(s)) +#define WGPUStringView const char* + +#define WGPU_ADDREF(d, o) wgpu##d##Reference(o) + +#define WGPU_CHECK_STATUS(s) s + +#if defined(__cplusplus) +#if __cplusplus >= 201103L +#define WGPU_MAKE_INIT_STRUCT(type, value) (type value) +#else +#define WGPU_MAKE_INIT_STRUCT(type, value) value +#endif +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define WGPU_MAKE_INIT_STRUCT(type, value) ((type)value) +#else +#define WGPU_MAKE_INIT_STRUCT(type, value) value +#endif + +#ifndef _wgpu_COMMA +#define _wgpu_COMMA , +#endif + +#define WGPU_ADAPTER_INFO_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUAdapterInfo, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.vendor=*/NULL \ + _wgpu_COMMA /*.architecture=*/NULL _wgpu_COMMA /*.device=*/NULL \ + _wgpu_COMMA /*.description=*/NULL \ + _wgpu_COMMA /*.backendType=*/ \ + {} _wgpu_COMMA /*.adapterType=*/{} _wgpu_COMMA /*.vendorID=*/ \ + {} _wgpu_COMMA /*.deviceID=*/{} _wgpu_COMMA}) + +#define WGPU_BIND_GROUP_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBindGroupDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.layout=*/{} _wgpu_COMMA /*.entryCount=*/ \ + {} _wgpu_COMMA /*.entries=*/{} _wgpu_COMMA}) + +#define WGPU_BIND_GROUP_ENTRY_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBindGroupEntry, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.binding=*/{} _wgpu_COMMA /*.buffer=*/NULL \ + _wgpu_COMMA /*.offset=*/0 _wgpu_COMMA /*.size=*/ \ + WGPU_WHOLE_SIZE _wgpu_COMMA /*.sampler=*/NULL \ + _wgpu_COMMA /*.textureView=*/NULL _wgpu_COMMA}) + +#define WGPU_BIND_GROUP_LAYOUT_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUBindGroupLayoutDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.entryCount=*/ \ + {} _wgpu_COMMA /*.entries=*/{} _wgpu_COMMA}) + +#define WGPU_BIND_GROUP_LAYOUT_ENTRY_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBindGroupLayoutEntry, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.binding=*/ \ + {} _wgpu_COMMA /*.visibility=*/{} _wgpu_COMMA /*.buffer=*/ \ + WGPU_BUFFER_BINDING_LAYOUT_INIT \ + _wgpu_COMMA /*.sampler=*/WGPU_SAMPLER_BINDING_LAYOUT_INIT \ + _wgpu_COMMA /*.texture=*/WGPU_TEXTURE_BINDING_LAYOUT_INIT \ + _wgpu_COMMA /*.storageTexture=*/ \ + WGPU_STORAGE_TEXTURE_BINDING_LAYOUT_INIT \ + _wgpu_COMMA}) + +#define WGPU_BLEND_COMPONENT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBlendComponent, \ + {/*.operation=*/WGPUBlendOperation_Add _wgpu_COMMA /*.srcFactor=*/ \ + WGPUBlendFactor_One \ + _wgpu_COMMA /*.dstFactor=*/WGPUBlendFactor_Zero _wgpu_COMMA}) + +#define WGPU_BLEND_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBlendState, \ + {/*.color=*/WGPU_BLEND_COMPONENT_INIT _wgpu_COMMA /*.alpha=*/ \ + WGPU_BLEND_COMPONENT_INIT _wgpu_COMMA}) + +#define WGPU_BUFFER_BINDING_LAYOUT_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUBufferBindingLayout, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.type=*/ \ + WGPUBufferBindingType_Undefined \ + _wgpu_COMMA /*.hasDynamicOffset=*/ \ + 0 _wgpu_COMMA /*.minBindingSize=*/0 _wgpu_COMMA}) + +#define WGPU_BUFFER_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBufferDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.usage=*/{} _wgpu_COMMA /*.size=*/ \ + {} _wgpu_COMMA /*.mappedAtCreation=*/0 _wgpu_COMMA}) + +#define WGPU_BUFFER_MAP_CALLBACK_INFO_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUBufferMapCallbackInfo, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.mode=*/{} _wgpu_COMMA /*.callback=*/NULL \ + _wgpu_COMMA /*.userdata1=*/NULL \ + _wgpu_COMMA /*.userdata2=*/NULL _wgpu_COMMA}) + +#define WGPU_COLOR_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUColor, \ + {/*.r=*/{} _wgpu_COMMA /*.g=*/{} _wgpu_COMMA /*.b=*/ \ + {} _wgpu_COMMA /*.a=*/{} _wgpu_COMMA}) + +#define WGPU_COLOR_TARGET_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUColorTargetState, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.format=*/{} _wgpu_COMMA /*.blend=*/NULL \ + _wgpu_COMMA /*.writeMask=*/WGPUColorWriteMask_All \ + _wgpu_COMMA}) + +#define WGPU_COMMAND_BUFFER_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUCommandBufferDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL _wgpu_COMMA}) + +#define WGPU_COMMAND_ENCODER_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUCommandEncoderDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL _wgpu_COMMA}) + +#define WGPU_COMPILATION_INFO_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUCompilationInfo, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.messageCount=*/ \ + {} _wgpu_COMMA /*.messages=*/{} _wgpu_COMMA}) + +#define WGPU_COMPILATION_MESSAGE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUCompilationMessage, \ + , \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.message=*/NULL \ + _wgpu_COMMA /*.type=*/{} _wgpu_COMMA /*.lineNum=*/ \ + {} _wgpu_COMMA /*.linePos=*/{} _wgpu_COMMA /*.offset=*/ \ + {} _wgpu_COMMA /*.length=*/{} _wgpu_COMMA /*.utf16LinePos=*/ \ + {} _wgpu_COMMA /*.utf16Offset=*/{} _wgpu_COMMA /*.utf16Length=*/ \ + {} _wgpu_COMMA}) + +#define WGPU_COMPUTE_PASS_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUComputePassDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.timestampWrites=*/NULL _wgpu_COMMA}) + +#define WGPU_COMPUTE_PASS_TIMESTAMP_WRITES_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUComputePassTimestampWrites, \ + {/*.querySet=*/{} _wgpu_COMMA /*.beginningOfPassWriteIndex=*/ \ + WGPU_QUERY_SET_INDEX_UNDEFINED \ + _wgpu_COMMA /*.endOfPassWriteIndex=*/ \ + WGPU_QUERY_SET_INDEX_UNDEFINED _wgpu_COMMA}) + +#define WGPU_COMPUTE_PIPELINE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUComputePipelineDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.layout=*/NULL _wgpu_COMMA /*.compute=*/ \ + WGPU_COMPUTE_STATE_INIT _wgpu_COMMA}) + +#define WGPU_COMPUTE_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUProgrammableStageDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.module=*/NULL \ + _wgpu_COMMA /*.entryPoint=*/NULL \ + _wgpu_COMMA /*.constantCount=*/0 _wgpu_COMMA /*.constants=*/ \ + NULL _wgpu_COMMA}) + +#define WGPU_CONSTANT_ENTRY_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUConstantEntry, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.key=*/NULL \ + _wgpu_COMMA /*.value=*/{} _wgpu_COMMA}) + +#define WGPU_DEPTH_STENCIL_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUDepthStencilState, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.format=*/{} _wgpu_COMMA /*.depthWriteEnabled=*/ \ + 0 _wgpu_COMMA /*.depthCompare=*/WGPUCompareFunction_Undefined \ + _wgpu_COMMA /*.stencilFront=*/WGPU_STENCIL_FACE_STATE_INIT \ + _wgpu_COMMA /*.stencilBack=*/WGPU_STENCIL_FACE_STATE_INIT \ + _wgpu_COMMA /*.stencilReadMask=*/ \ + 0xFFFFFFFF _wgpu_COMMA /*.stencilWriteMask=*/ \ + 0xFFFFFFFF _wgpu_COMMA /*.depthBias=*/ \ + 0 _wgpu_COMMA /*.depthBiasSlopeScale=*/ \ + 0.0f _wgpu_COMMA /*.depthBiasClamp=*/0.0f _wgpu_COMMA}) + +#define WGPU_DEVICE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUDeviceDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.requiredFeatureCount=*/ \ + 0 _wgpu_COMMA /*.requiredFeatures=*/NULL \ + _wgpu_COMMA /*.requiredLimits=*/NULL \ + _wgpu_COMMA /*.defaultQueue=*/WGPU_QUEUE_DESCRIPTOR_INIT \ + _wgpu_COMMA /*.deviceLostCallback=*/NULL \ + _wgpu_COMMA /*.deviceLostUserdata=*/NULL \ + _wgpu_COMMA}) + +#define WGPU_EXTENT_3D_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUExtent3D, \ + {/*.width=*/0 _wgpu_COMMA /*.height=*/ \ + 1 _wgpu_COMMA /*.depthOrArrayLayers=*/1 _wgpu_COMMA}) + +#define WGPU_FRAGMENT_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUFragmentState, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.module=*/{} _wgpu_COMMA /*.entryPoint=*/NULL \ + _wgpu_COMMA /*.constantCount=*/0 _wgpu_COMMA /*.constants=*/ \ + {} _wgpu_COMMA /*.targetCount=*/{} _wgpu_COMMA /*.targets=*/ \ + {} _wgpu_COMMA}) + +#define WGPU_TEXEL_COPY_BUFFER_INFO_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUTexelCopyBufferInfo, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.layout=*/ \ + WGPU_TEXTURE_DATA_LAYOUT_INIT \ + _wgpu_COMMA /*.buffer=*/{} _wgpu_COMMA}) + +#define WGPU_TEXEL_COPY_TEXTURE_INFO_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUTexelCopyTextureInfo, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.texture=*/ \ + {} _wgpu_COMMA /*.mipLevel=*/0 _wgpu_COMMA /*.origin=*/ \ + WGPU_ORIGIN_3D_INIT _wgpu_COMMA /*.aspect=*/WGPUTextureAspect_All \ + _wgpu_COMMA}) + +#define WGPU_INSTANCE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUInstanceDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.features=*/ \ + WGPU_INSTANCE_CAPABILITIES_INIT _wgpu_COMMA}) + +#define WGPU_INSTANCE_CAPABILITIES_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUInstanceCapabilities, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.timedWaitAnyEnable=*/ \ + 0 _wgpu_COMMA /*.timedWaitAnyMaxCount=*/0 _wgpu_COMMA}) + +#define WGPU_LIMITS_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPULimits, \ + {/*.maxTextureDimension1D=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxTextureDimension2D=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxTextureDimension3D=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxTextureArrayLayers=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxBindGroups=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxBindGroupsPlusVertexBuffers=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxBindingsPerBindGroup=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxDynamicUniformBuffersPerPipelineLayout=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxDynamicStorageBuffersPerPipelineLayout=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxSampledTexturesPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxSamplersPerShaderStage=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxStorageBuffersPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxStorageTexturesPerShaderStage=*/WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxUniformBuffersPerShaderStage=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxUniformBufferBindingSize=*/WGPU_LIMIT_U64_UNDEFINED \ + _wgpu_COMMA /*.maxStorageBufferBindingSize=*/WGPU_LIMIT_U64_UNDEFINED _wgpu_COMMA /*.minUniformBufferOffsetAlignment=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.minStorageBufferOffsetAlignment=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxVertexBuffers=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxBufferSize=*/WGPU_LIMIT_U64_UNDEFINED _wgpu_COMMA /*.maxVertexAttributes=*/ \ + WGPU_LIMIT_U32_UNDEFINED _wgpu_COMMA /*.maxVertexBufferArrayStride=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxInterStageShaderComponents=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxInterStageShaderVariables=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxColorAttachments=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxColorAttachmentBytesPerSample=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxComputeWorkgroupStorageSize=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxComputeInvocationsPerWorkgroup=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxComputeWorkgroupSizeX=*/WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxComputeWorkgroupSizeY=*/ \ + WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxComputeWorkgroupSizeZ=*/ \ + WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA /*.maxComputeWorkgroupsPerDimension=*/ \ + WGPU_LIMIT_U32_UNDEFINED \ + _wgpu_COMMA}) + +#define WGPU_MULTISAMPLE_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUMultisampleState, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.count=*/1 _wgpu_COMMA /*.mask=*/ \ + 0xFFFFFFFF _wgpu_COMMA /*.alphaToCoverageEnabled=*/0 _wgpu_COMMA}) + +#define WGPU_ORIGIN_3D_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUOrigin3D, \ + {/*.x=*/0 _wgpu_COMMA /*.y=*/0 _wgpu_COMMA /*.z=*/0 _wgpu_COMMA}) + +#define WGPU_PIPELINE_LAYOUT_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUPipelineLayoutDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.bindGroupLayoutCount=*/ \ + {} _wgpu_COMMA /*.bindGroupLayouts=*/NULL _wgpu_COMMA}) + +#define WGPU_PRIMITIVE_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUPrimitiveState, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.topology=*/ \ + WGPUPrimitiveTopology_TriangleList \ + _wgpu_COMMA /*.stripIndexFormat=*/WGPUIndexFormat_Undefined \ + _wgpu_COMMA /*.frontFace=*/WGPUFrontFace_CCW \ + _wgpu_COMMA /*.cullMode=*/WGPUCullMode_None \ + _wgpu_COMMA}) + +#define WGPU_QUERY_SET_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUQuerySetDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.type=*/{} _wgpu_COMMA /*.count=*/{} _wgpu_COMMA}) + +#define WGPU_QUEUE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUQueueDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL _wgpu_COMMA}) + +#define WGPU_RENDER_BUNDLE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderBundleDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL _wgpu_COMMA}) + +#define WGPU_RENDER_BUNDLE_ENCODER_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderBundleEncoderDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.colorFormatCount=*/ \ + {} _wgpu_COMMA /*.colorFormats=*/ \ + {} _wgpu_COMMA /*.depthStencilFormat=*/WGPUTextureFormat_Undefined \ + _wgpu_COMMA /*.sampleCount=*/1 _wgpu_COMMA /*.depthReadOnly=*/ \ + 0 _wgpu_COMMA /*.stencilReadOnly=*/0 _wgpu_COMMA}) + +#define WGPU_RENDER_PASS_COLOR_ATTACHMENT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderPassColorAttachment, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.view=*/NULL \ + _wgpu_COMMA /*.depthSlice=*/WGPU_DEPTH_SLICE_UNDEFINED \ + _wgpu_COMMA /*.resolveTarget=*/NULL \ + _wgpu_COMMA /*.loadOp=*/{} _wgpu_COMMA /*.storeOp=*/ \ + {} _wgpu_COMMA /*.clearValue=*/WGPU_COLOR_INIT _wgpu_COMMA}) + +#define WGPU_RENDER_PASS_DEPTH_STENCIL_ATTACHMENT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderPassDepthStencilAttachment, \ + {/*.view=*/{} _wgpu_COMMA /*.depthLoadOp=*/WGPULoadOp_Undefined \ + _wgpu_COMMA /*.depthStoreOp=*/WGPUStoreOp_Undefined \ + _wgpu_COMMA /*.depthClearValue=*/ \ + WGPU_DEPTH_CLEAR_VALUE_UNDEFINED \ + _wgpu_COMMA /*.depthReadOnly=*/ \ + 0 _wgpu_COMMA /*.stencilLoadOp=*/WGPULoadOp_Undefined \ + _wgpu_COMMA /*.stencilStoreOp=*/WGPUStoreOp_Undefined \ + _wgpu_COMMA /*.stencilClearValue=*/ \ + 0 _wgpu_COMMA /*.stencilReadOnly=*/0 _wgpu_COMMA}) + +#define WGPU_RENDER_PASS_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderPassDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.colorAttachmentCount=*/ \ + {} _wgpu_COMMA /*.colorAttachments=*/ \ + {} _wgpu_COMMA /*.depthStencilAttachment=*/NULL \ + _wgpu_COMMA /*.occlusionQuerySet=*/NULL \ + _wgpu_COMMA /*.timestampWrites=*/NULL _wgpu_COMMA}) + +#define WGPU_RENDER_PASS_MAX_DRAW_COUNT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderPassMaxDrawCount, \ + {/*.chain= WGPUChainedStruct*/ { \ + /*.next=*/NULL _wgpu_COMMA /*.sType=*/ \ + WGPUSType_RenderPassDescriptorMaxDrawCount \ + _wgpu_COMMA} _wgpu_COMMA /*.maxDrawCount=*/ \ + 50000000 _wgpu_COMMA}) + +#define WGPU_RENDER_PASS_TIMESTAMP_WRITES_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderPassTimestampWrites, \ + {/*.querySet=*/{} _wgpu_COMMA /*.beginningOfPassWriteIndex=*/ \ + WGPU_QUERY_SET_INDEX_UNDEFINED \ + _wgpu_COMMA /*.endOfPassWriteIndex=*/ \ + WGPU_QUERY_SET_INDEX_UNDEFINED _wgpu_COMMA}) + +#define WGPU_RENDER_PIPELINE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURenderPipelineDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.layout=*/NULL _wgpu_COMMA /*.vertex=*/ \ + WGPU_VERTEX_STATE_INIT _wgpu_COMMA /*.primitive=*/ \ + WGPU_PRIMITIVE_STATE_INIT _wgpu_COMMA /*.depthStencil=*/ \ + NULL _wgpu_COMMA /*.multisample=*/ \ + WGPU_MULTISAMPLE_STATE_INIT \ + _wgpu_COMMA /*.fragment=*/NULL _wgpu_COMMA}) + +#define WGPU_REQUEST_ADAPTER_OPTIONS_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURequestAdapterOptions, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.compatibleSurface=*/NULL \ + _wgpu_COMMA /*.powerPreference=*/WGPUPowerPreference_Undefined \ + _wgpu_COMMA /*.backendType=*/WGPUBackendType_Undefined \ + _wgpu_COMMA /*.forceFallbackAdapter=*/ \ + 0 _wgpu_COMMA /*.compatibilityMode=*/0 _wgpu_COMMA}) + +#define WGPU_REQUIRED_LIMITS_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPURequiredLimits, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.limits=*/WGPU_LIMITS_INIT \ + _wgpu_COMMA}) + +#define WGPU_SAMPLER_BINDING_LAYOUT_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUSamplerBindingLayout, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.type=*/ \ + WGPUSamplerBindingType_Undefined _wgpu_COMMA}) + +#define WGPU_SAMPLER_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUSamplerDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.addressModeU=*/WGPUAddressMode_ClampToEdge \ + _wgpu_COMMA /*.addressModeV=*/WGPUAddressMode_ClampToEdge \ + _wgpu_COMMA /*.addressModeW=*/WGPUAddressMode_ClampToEdge \ + _wgpu_COMMA /*.magFilter=*/WGPUFilterMode_Nearest \ + _wgpu_COMMA /*.minFilter=*/WGPUFilterMode_Nearest \ + _wgpu_COMMA /*.mipmapFilter=*/ \ + WGPUMipmapFilterMode_Nearest \ + _wgpu_COMMA /*.lodMinClamp=*/ \ + 0.0f _wgpu_COMMA /*.lodMaxClamp=*/32.0f _wgpu_COMMA /*.compare=*/ \ + WGPUCompareFunction_Undefined \ + _wgpu_COMMA /*.maxAnisotropy=*/1 _wgpu_COMMA}) + +#define WGPU_SHADER_MODULE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUShaderModuleDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL _wgpu_COMMA}) + +#define WGPU_SHADER_SOURCE_SPIRV_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUShaderSourceSPIRV, \ + {/*.chain= WGPUChainedStruct*/ { \ + /*.next=*/NULL _wgpu_COMMA /*.sType=*/WGPUSType_ShaderSourceSPIRV \ + _wgpu_COMMA} _wgpu_COMMA /*.codeSize=*/{}, \ + .code = {} _wgpu_COMMA}) + +#define WGPU_SHADER_SOURCE_WGSL_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUShaderSourceWGSL, \ + {/*.chain= WGPUChainedStruct*/ { \ + /*.next=*/NULL _wgpu_COMMA /*.sType=*/WGPUSType_ShaderSourceWGSL \ + _wgpu_COMMA} _wgpu_COMMA /*.code=*/NULL _wgpu_COMMA}) + +#define WGPU_STENCIL_FACE_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUStencilFaceState, \ + {/*.compare=*/WGPUCompareFunction_Always _wgpu_COMMA /*.failOp=*/ \ + WGPUStencilOperation_Keep \ + _wgpu_COMMA /*.depthFailOp=*/WGPUStencilOperation_Keep \ + _wgpu_COMMA /*.passOp=*/WGPUStencilOperation_Keep \ + _wgpu_COMMA}) + +#define WGPU_STORAGE_TEXTURE_BINDING_LAYOUT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUStorageTextureBindingLayout, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.access=*/ \ + WGPUStorageTextureAccess_Undefined _wgpu_COMMA /*.format=*/ \ + WGPUTextureFormat_Undefined _wgpu_COMMA /*.viewDimension=*/ \ + WGPUTextureViewDimension_Undefined _wgpu_COMMA}) + +#define WGPU_SUPPORTED_LIMITS_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUSupportedLimits, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.limits=*/WGPU_LIMITS_INIT \ + _wgpu_COMMA}) + +#define WGPU_SURFACE_CAPABILITIES_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUSurfaceCapabilities, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.formatCount=*/ \ + {} _wgpu_COMMA /*.formats=*/{} _wgpu_COMMA /*.presentModeCount=*/ \ + {} _wgpu_COMMA /*.presentModes=*/{} _wgpu_COMMA /*.alphaModeCount=*/ \ + {} _wgpu_COMMA /*.alphaModes=*/{} _wgpu_COMMA}) + +#define WGPU_SURFACE_CONFIGURATION_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUSurfaceConfiguration, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.device=*/{} _wgpu_COMMA /*.format=*/ \ + {} _wgpu_COMMA /*.usage=*/WGPUTextureUsage_RenderAttachment \ + _wgpu_COMMA /*.viewFormatCount=*/0 _wgpu_COMMA /*.viewFormats=*/ \ + NULL _wgpu_COMMA /*.alphaMode=*/WGPUCompositeAlphaMode_Auto \ + _wgpu_COMMA /*.width=*/{} _wgpu_COMMA /*.height=*/ \ + {} _wgpu_COMMA /*.presentMode=*/WGPUPresentMode_Fifo _wgpu_COMMA}) + +#define WGPU_SURFACE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUSurfaceDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL _wgpu_COMMA}) + +#define WGPU_SURFACE_TEXTURE_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUSurfaceTexture, \ + {/*.texture=*/{} _wgpu_COMMA /*.suboptimal=*/ \ + {} _wgpu_COMMA /*.status=*/{} _wgpu_COMMA}) + +#define WGPU_TEXTURE_BINDING_LAYOUT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUTextureBindingLayout, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.sampleType=*/ \ + WGPUTextureSampleType_Undefined _wgpu_COMMA /*.viewDimension=*/ \ + WGPUTextureViewDimension_Undefined \ + _wgpu_COMMA /*.multisampled=*/0 _wgpu_COMMA}) + +#define WGPU_TEXTURE_BINDING_VIEW_DIMENSION_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUTextureBindingViewDimensionDescriptor, \ + {/*.chain= WGPUChainedStruct*/ { \ + /*.next=*/NULL _wgpu_COMMA /*.sType=*/ \ + WGPUSType_TextureBindingViewDimensionDescriptor \ + _wgpu_COMMA} _wgpu_COMMA /*.textureBindingViewDimension=*/ \ + WGPUTextureViewDimension_Undefined _wgpu_COMMA}) + +#define WGPU_TEXTURE_DATA_LAYOUT_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUTextureDataLayout, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.offset=*/0 _wgpu_COMMA /*.bytesPerRow=*/ \ + WGPU_COPY_STRIDE_UNDEFINED _wgpu_COMMA /*.rowsPerImage=*/ \ + WGPU_COPY_STRIDE_UNDEFINED _wgpu_COMMA}) + +#define WGPU_TEXTURE_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUTextureDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.usage=*/{} _wgpu_COMMA /*.dimension=*/ \ + WGPUTextureDimension_2D _wgpu_COMMA /*.size=*/ \ + WGPU_EXTENT_3D_INIT _wgpu_COMMA /*.format=*/ \ + {} _wgpu_COMMA /*.mipLevelCount=*/1 _wgpu_COMMA /*.sampleCount=*/ \ + 1 _wgpu_COMMA /*.viewFormatCount=*/0 _wgpu_COMMA /*.viewFormats=*/ \ + NULL _wgpu_COMMA}) + +#define WGPU_TEXTURE_VIEW_DESCRIPTOR_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUTextureViewDescriptor, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.label=*/NULL \ + _wgpu_COMMA /*.format=*/WGPUTextureFormat_Undefined \ + _wgpu_COMMA /*.dimension=*/WGPUTextureViewDimension_Undefined \ + _wgpu_COMMA /*.baseMipLevel=*/ \ + 0 _wgpu_COMMA /*.mipLevelCount=*/WGPU_MIP_LEVEL_COUNT_UNDEFINED \ + _wgpu_COMMA /*.baseArrayLayer=*/ \ + 0 _wgpu_COMMA /*.arrayLayerCount=*/WGPU_ARRAY_LAYER_COUNT_UNDEFINED \ + _wgpu_COMMA /*.aspect=*/WGPUTextureAspect_All _wgpu_COMMA}) + +#define WGPU_VERTEX_ATTRIBUTE_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUVertexAttribute, \ + {/*.format=*/{} _wgpu_COMMA /*.offset=*/ \ + {} _wgpu_COMMA /*.shaderLocation=*/{} _wgpu_COMMA}) + +#define WGPU_VERTEX_BUFFER_LAYOUT_INIT \ + WGPU_MAKE_INIT_STRUCT(WGPUVertexBufferLayout, \ + {/*.arrayStride=*/{} _wgpu_COMMA /*.stepMode=*/ \ + {} _wgpu_COMMA /*.attributeCount=*/ \ + {} _wgpu_COMMA /*.attributes=*/{} _wgpu_COMMA}) + +#define WGPU_VERTEX_STATE_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUVertexState, \ + {/*.nextInChain=*/NULL \ + _wgpu_COMMA /*.module=*/{} _wgpu_COMMA /*.entryPoint=*/NULL \ + _wgpu_COMMA /*.constantCount=*/0 _wgpu_COMMA /*.constants=*/ \ + {} _wgpu_COMMA /*.bufferCount=*/0 _wgpu_COMMA /*.buffers=*/ \ + {} _wgpu_COMMA}) + +#define WGPU_QUEUE_WORK_DONE_CALLBACK_INFO_INIT \ + WGPU_MAKE_INIT_STRUCT( \ + WGPUQueueWorkDoneCallbackInfo, \ + {/*.nextInChain=*/NULL _wgpu_COMMA /*.callback=*/NULL \ + _wgpu_COMMA /*.userdata1=*/NULL _wgpu_COMMA /*.userdata2=*/NULL \ + _wgpu_COMMA}) + +#if defined(__cplusplus) +#define WGPU_WAGYU_STRING_VIEW(s) \ + WGPUWagyuStringView{s, (s != NULL) ? strlen(s) : 0} +#else +#define WGPU_WAGYU_STRING_VIEW(s) \ + (WGPUWagyuStringView){s, (s != NULL) ? strlen(s) : 0} +#endif + +#endif // WEBGPU_COMPAT_H diff --git a/thirdparty/rive_vendor_versions.json b/thirdparty/rive_vendor_versions.json new file mode 100644 index 000000000..ad1a61a91 --- /dev/null +++ b/thirdparty/rive_vendor_versions.json @@ -0,0 +1,71 @@ +{ + "dependencies": [ + { + "checkout": "972e52893bf03fd26920d4d191d1a09c7e0b0fa5", + "name": "rive", + "ref": "runtime-v0.1.62", + "version": "0.1.62" + }, + { + "checkout": "972e52893bf03fd26920d4d191d1a09c7e0b0fa5", + "name": "rive_renderer", + "ref": "runtime-v0.1.62", + "version": "0.1.62" + }, + { + "checkout": "972e52893bf03fd26920d4d191d1a09c7e0b0fa5", + "name": "rive_decoders", + "ref": "runtime-v0.1.62", + "version": "0.1.62" + }, + { + "checkout": "58a7e5d9badc3241a136b6e3c6f71d58c0f7bb84", + "name": "luau", + "ref": "rive_0_35", + "version": "0.35" + }, + { + "checkout": "f11e8d2d4385c1df7dd21082be421d2d6101f03a", + "name": "libhydrogen", + "ref": "rive_0_1", + "version": "0.1" + }, + { + "checkout": "08d34675f64b1ac4880f4f10c9fd474a56dd4399", + "name": "harfbuzz", + "ref": "rive_13.1.1", + "version": "13.1.1" + }, + { + "checkout": "adfccc46504b1be37b8894f064121c56c31312f7", + "name": "sheenbidi_library", + "ref": "v2.6", + "version": "2.6" + }, + { + "checkout": "b827168e5e66c56b3117660a12607fe4f54ea33c", + "name": "yoga_library", + "ref": "rive_changes_v2_0_1_2", + "version": "2.0.2.1" + }, + { + "checkout": "8c62c3b86a8832d47d6089ee4e5caf64177473c3", + "name": "libpng", + "ref": "libpng16", + "version": "1.6" + }, + { + "checkout": "845d5476a866141ba35ac133f856fa62f0b7445f", + "name": "libwebp", + "ref": "v1.4.0", + "version": "1.4.0" + }, + { + "checkout": "51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf", + "name": "zlib", + "ref": "v1.3.1", + "version": "1.3.1" + } + ], + "generatedAt": "2026-05-10T17:45:01.364694+00:00" +} diff --git a/thirdparty/sheenbidi_library/sheenbidi_library.c b/thirdparty/sheenbidi_library/sheenbidi_library.c index 0cd380a26..626b2a1e8 100644 --- a/thirdparty/sheenbidi_library/sheenbidi_library.c +++ b/thirdparty/sheenbidi_library/sheenbidi_library.c @@ -28,6 +28,7 @@ #pragma GCC diagnostic ignored "-Wnonportable-include-path" #endif +// BEGIN YUP GENERATED SHEENBIDI INCLUDES #include "source/SBBase.c" #include "source/RunQueue.c" #include "source/BidiTypeLookup.c" @@ -48,6 +49,8 @@ #include "source/SBParagraph.c" #include "source/IsolatingRun.c" #include "source/SBAlgorithm.c" +// END YUP GENERATED SHEENBIDI INCLUDES + #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop diff --git a/thirdparty/yoga_library/upstream/yoga/Utils.cpp b/thirdparty/yoga_library/upstream/yoga/Utils.cpp index 7cc94022b..43f11ee84 100644 --- a/thirdparty/yoga_library/upstream/yoga/Utils.cpp +++ b/thirdparty/yoga_library/upstream/yoga/Utils.cpp @@ -78,6 +78,6 @@ void yoga::throwLogicalErrorWithMessage(const char* message) { #if defined(__cpp_exceptions) throw std::logic_error(message); #else // !defined(__cpp_exceptions) - std::terminate(); +// std::terminate(); #endif // defined(__cpp_exceptions) } diff --git a/thirdparty/yoga_library/upstream/yoga/YGMacros.h b/thirdparty/yoga_library/upstream/yoga/YGMacros.h index 6597c097d..38196218e 100644 --- a/thirdparty/yoga_library/upstream/yoga/YGMacros.h +++ b/thirdparty/yoga_library/upstream/yoga/YGMacros.h @@ -19,12 +19,14 @@ #define YG_EXTERN_C_END #endif +#if !defined(YG_DEPRECATED) #if defined(__cplusplus) -#define YG_DEPRECATED(message) //[[deprecated(message)]] +#define YG_DEPRECATED(message) [[deprecated(message)]] #elif defined(_MSC_VER) -#define YG_DEPRECATED(message) //__declspec(deprecated(message)) +#define YG_DEPRECATED(message) __declspec(deprecated(message)) #else -#define YG_DEPRECATED(message) //__attribute__((deprecated(message))) +#define YG_DEPRECATED(message) __attribute__((deprecated(message))) +#endif #endif #ifdef _WINDLL diff --git a/thirdparty/yoga_library/upstream/yoga/YGNode.h b/thirdparty/yoga_library/upstream/yoga/YGNode.h index e3c202f2b..deb2d85fb 100644 --- a/thirdparty/yoga_library/upstream/yoga/YGNode.h +++ b/thirdparty/yoga_library/upstream/yoga/YGNode.h @@ -27,6 +27,7 @@ struct YGNodeFlags { bool measureUsesContext : 1; bool baselineUsesContext : 1; bool printUsesContext : 1; + bool hasError : 1; }; #pragma pack(pop) @@ -104,6 +105,8 @@ struct YOGA_EXPORT YGNode { bool getHasNewLayout() const { return flags_.hasNewLayout; } + bool getHasError() const { return flags_.hasError; } + YGNodeType getNodeType() const { return static_cast(flags_.nodeType); } @@ -249,6 +252,8 @@ struct YOGA_EXPORT YGNode { flags_.hasNewLayout = hasNewLayout; } + void setHasError(bool hasError) { flags_.hasError = hasError; } + void setNodeType(YGNodeType nodeType) { flags_.nodeType = static_cast(nodeType); } diff --git a/thirdparty/yoga_library/upstream/yoga/Yoga.cpp b/thirdparty/yoga_library/upstream/yoga/Yoga.cpp index 26cfe2f3a..1e264aba6 100644 --- a/thirdparty/yoga_library/upstream/yoga/Yoga.cpp +++ b/thirdparty/yoga_library/upstream/yoga/Yoga.cpp @@ -197,27 +197,9 @@ YOGA_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { return node; } -namespace { -struct YogaWrapperWithCleanup { - YogaWrapperWithCleanup() - : defaultConfig (YGConfigNew()) - { - } - - ~YogaWrapperWithCleanup() { - if (defaultConfig != nullptr) { - YGConfigFree (defaultConfig); - defaultConfig = nullptr; - } - } - - YGConfigRef defaultConfig = nullptr; -}; -} // namespace - YOGA_EXPORT YGConfigRef YGConfigGetDefault() { - static YogaWrapperWithCleanup defaultWrapper = YogaWrapperWithCleanup(); - return defaultWrapper.defaultConfig; + static YGConfigRef defaultConfig = YGConfigNew(); + return defaultConfig; } YOGA_EXPORT YGNodeRef YGNodeNew(void) { @@ -1996,6 +1978,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // Add items to the current line until it's full or we run out of items. uint32_t endOfLineIndex = startOfLineIndex; + bool isFirstElementInLine = true; for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { const YGNodeRef child = node->getChild(endOfLineIndex); if (child->getStyle().display() == YGDisplayNone || @@ -2003,12 +1986,11 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( continue; } - const bool isFirstElementInLine = (endOfLineIndex - startOfLineIndex) == 0; - child->setLineIndex(lineCount); const float childMarginMainAxis = child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap(); const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap; + isFirstElementInLine = false; const float flexBasisWithMinAndMaxConstraints = YGNodeBoundAxisWithinMinAndMax( child, @@ -2533,13 +2515,24 @@ static void YGJustifyMainAxis( float maxAscentForCurrentLine = 0; float maxDescentForCurrentLine = 0; bool isNodeBaselineLayout = YGIsBaselineLayout(node); + int lastVisibleChildIndex = 0; + for (uint32_t i = startOfLineIndex; + i < collectedFlexItemsValues.endOfLineIndex; + i++) { + const YGNodeRef child = node->getChild(i); + const YGStyle& childStyle = child->getStyle(); + if (childStyle.display() == YGDisplayNone) { + continue; + } + lastVisibleChildIndex = i; + } for (uint32_t i = startOfLineIndex; i < collectedFlexItemsValues.endOfLineIndex; i++) { const YGNodeRef child = node->getChild(i); const YGStyle& childStyle = child->getStyle(); const YGLayout childLayout = child->getLayout(); - const bool isLastChild = i == collectedFlexItemsValues.endOfLineIndex - 1; + const bool isLastChild = i == lastVisibleChildIndex; // remove the gap if it is the last element of the line if (isLastChild) { betweenMainDim -= gap; @@ -4291,6 +4284,7 @@ void YGAssertWithNode( const char* message) { if (!condition) { Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message); + node->setHasError(true); throwLogicalErrorWithMessage(message); } } diff --git a/thirdparty/yoga_library/yoga_library.cpp b/thirdparty/yoga_library/yoga_library.cpp index 5d07da574..5016b6af5 100644 --- a/thirdparty/yoga_library/yoga_library.cpp +++ b/thirdparty/yoga_library/yoga_library.cpp @@ -21,6 +21,7 @@ #include "yoga_library.h" +// BEGIN YUP GENERATED YOGA INCLUDES #include "upstream/yoga/event/event.cpp" #include "upstream/yoga/log.cpp" #include "upstream/yoga/Utils.cpp" @@ -32,3 +33,5 @@ #include "upstream/yoga/YGStyle.cpp" #include "upstream/yoga/YGValue.cpp" #include "upstream/yoga/Yoga.cpp" +// END YUP GENERATED YOGA INCLUDES + diff --git a/thirdparty/yoga_library/yoga_library.h b/thirdparty/yoga_library/yoga_library.h index a764158f4..74e8a37fc 100644 --- a/thirdparty/yoga_library/yoga_library.h +++ b/thirdparty/yoga_library/yoga_library.h @@ -41,4 +41,8 @@ #pragma once +#ifndef YOGA_EXPORT +#define YOGA_EXPORT +#endif + #include "upstream/yoga/Yoga.h" diff --git a/thirdparty/zlib/src/README b/thirdparty/zlib/src/README index 758cc5002..c5f917540 100644 --- a/thirdparty/zlib/src/README +++ b/thirdparty/zlib/src/README @@ -1,56 +1,51 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.3 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). These documents are also available in other -formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The -compression library itself is composed of all source files except example.c and -minigzip.c. +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. To compile all files and run the test program, follow the instructions given at -the top of Makefile. In short "make test; make install" should work for most -machines. For Unix: "./configure; make test; make install". For MSDOS, use one -of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, -please check this site to verify that you have the latest version of zlib; -otherwise get the latest version and check whether the problem still exists or -not. + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. -PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking -for help. +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available in -http://dogma.net/markn/articles/zlibtool/zlibtool.htm +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.2.3 are documented in the file ChangeLog. +The changes made in version 1.3.1 are documented in the file ChangeLog. -Unsupported third party contributions are provided in directory "contrib". +Unsupported third party contributions are provided in directory contrib/ . -A Java implementation of zlib is available in the Java Development Kit -http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html -See the zlib home page http://www.zlib.org for details. +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . -A Perl interface to zlib written by Paul Marquess is in the -CPAN (Comprehensive Perl Archive Network) sites -http://www.cpan.org/modules/by-module/Compress/ +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html +http://docs.python.org/library/zlib.html . -A zlib binding for TCL written by Andreas Kupries is -availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html +zlib is built into tcl: http://wiki.tcl.tk/4610 . An experimental package to read and write files in .zip format, written on top of zlib by Gilles Vollant , is available in the @@ -68,31 +63,27 @@ Notes for some targets: - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works when compiled with cc. -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is +- On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is necessary to get gzprintf working correctly. This is done by configure. - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with other compilers. Use "make test" to check your compiler. -- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. +- gzdopen is not supported on RISCOS or BEOS. - For PalmOs, see http://palmzlib.sourceforge.net/ -- When building a shared, i.e. dynamic library on Mac OS X, the library must be - installed before testing (do "make install" before "make test"), since the - library location is specified in the library. - Acknowledgments: - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. Copyright notice: - (C) 1995-2004 Jean-loup Gailly and Mark Adler + (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -113,13 +104,14 @@ Copyright notice: Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. - -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. Please -read the FAQ for more information on the distribution of modified source -versions. +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. We make all +contributions to and distributions of this project solely in our personal +capacity, and are not conveying any rights to any intellectual property of +any third parties. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/thirdparty/zlib/src/adler32.c b/thirdparty/zlib/src/adler32.c index bf5cbd200..04b81d29b 100644 --- a/thirdparty/zlib/src/adler32.c +++ b/thirdparty/zlib/src/adler32.c @@ -1,143 +1,164 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: adler32.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 > BASE) sum1 -= BASE; - if (sum1 > BASE) sum1 -= BASE; - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 > BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { + return adler32_z(adler, buf, len); +} + +/* ========================================================================= */ +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { + return adler32_combine_(adler1, adler2, len2); +} diff --git a/thirdparty/zlib/src/compress.c b/thirdparty/zlib/src/compress.c index 05c49c552..f43bacf7a 100644 --- a/thirdparty/zlib/src/compress.c +++ b/thirdparty/zlib/src/compress.c @@ -1,70 +1,75 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: compress.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen, int level) -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (uLong sourceLen) -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; -} +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + sourceLen -= stream.avail_in; + } + err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + deflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound(uLong sourceLen) { + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/thirdparty/zlib/src/crc32.c b/thirdparty/zlib/src/crc32.c index 9314d7eb6..6c38f5c04 100644 --- a/thirdparty/zlib/src/crc32.c +++ b/thirdparty/zlib/src/crc32.c @@ -1,407 +1,1049 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id: crc32.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, unsigned len) -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = (u4) (crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]) -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len) -{ - u4 c; - const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = (u4) (crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8)); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = (u4) (crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8)); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = (u4) (crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]) -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf, unsigned len) -{ - u4 c; - const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = (u4) (crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8)); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = (u4) (crc_table[4][(c >> 24) ^ (u4) *buf++] ^ (c << 8)); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times (unsigned long *mat, unsigned long vec) -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square (unsigned long *square, unsigned long *mat) -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine (uLong crc1, uLong crc2, z_off_t len2) -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case */ - if (len2 == 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320L; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + MAKECRCH can be #defined to write out crc32.h. A main() routine is also + produced, so that this one source file can be compiled to an executable. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ + + /* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32.h would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. + */ + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + z_crc_t must be at least 32 bits. z_word_t must be at least as long as + z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and + that bytes are eight bits. + */ + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif +#else +# ifdef MAKECRCH +# define W 8 /* required for MAKECRCH */ +# else +# if defined(__x86_64__) || defined(__aarch64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 && defined(Z_U8) + typedef Z_U8 z_word_t; +# elif defined(Z_U4) +# undef W +# define W 4 + typedef Z_U4 z_word_t; +# else +# undef W +# endif +#endif + +/* If available, use the ARM processor CRC32 instruction. */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 +# define ARMCRC32 +#endif + +#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) +/* + Swap the bytes in a z_word_t to convert between little and big endian. Any + self-respecting compiler will optimize this to a single machine byte-swap + instruction, if one is available. This assumes that word_t is either 32 bits + or 64 bits. + */ +local z_word_t byte_swap(z_word_t word) { +# if W == 8 + return + (word & 0xff00000000000000) >> 56 | + (word & 0xff000000000000) >> 40 | + (word & 0xff0000000000) >> 24 | + (word & 0xff00000000) >> 8 | + (word & 0xff000000) << 8 | + (word & 0xff0000) << 24 | + (word & 0xff00) << 40 | + (word & 0xff) << 56; +# else /* W == 4 */ + return + (word & 0xff000000) >> 24 | + (word & 0xff0000) >> 8 | + (word & 0xff00) << 8 | + (word & 0xff) << 24; +# endif +} +#endif + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ +local z_crc_t FAR crc_table[256]; +#ifdef W + local z_word_t FAR crc_big_table[256]; + local z_crc_t FAR crc_braid_table[W][256]; + local z_word_t FAR crc_braid_big_table[W][256]; + local void braid(z_crc_t [][256], z_word_t [][256], int, int); +#endif +#ifdef MAKECRCH + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); +#endif /* MAKECRCH */ + +/* + Define a once() function depending on the availability of atomics. If this is + compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in + multiple threads, and if atomics are not available, then get_crc_table() must + be called to initialize the tables and must return before any threads are + allowed to compute or combine CRCs. + */ + +/* Definition of once functionality. */ +typedef struct once_s once_t; + +/* Check for the availability of atomics. */ +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ + !defined(__STDC_NO_ATOMICS__) + +#include + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + atomic_flag begun; + atomic_int done; +}; +#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} + +/* + Run the provided init() function exactly once, even if multiple threads + invoke once() at the same time. The state must be a once_t initialized with + ONCE_INIT. + */ +local void once(once_t *state, void (*init)(void)) { + if (!atomic_load(&state->done)) { + if (atomic_flag_test_and_set(&state->begun)) + while (!atomic_load(&state->done)) + ; + else { + init(); + atomic_store(&state->done, 1); + } + } +} + +#else /* no atomics */ + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + volatile int begun; + volatile int done; +}; +#define ONCE_INIT {0, 0} + +/* Test and set. Alas, not atomic, but tries to minimize the period of + vulnerability. */ +local int test_and_set(int volatile *flag) { + int was; + + was = *flag; + *flag = 1; + return was; +} + +/* Run the provided init() function once. This is not thread-safe. */ +local void once(once_t *state, void (*init)(void)) { + if (!state->done) { + if (test_and_set(&state->begun)) + while (!state->done) + ; + else { + init(); + state->done = 1; + } + } +} + +#endif + +/* State for once(). */ +local once_t made = ONCE_INIT; + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. + */ + +local void make_crc_table(void) { + unsigned i, j, n; + z_crc_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; +#ifdef W + crc_big_table[i] = byte_swap(p); +#endif + } + + /* initialize the x^2^n mod p(x) table */ + p = (z_crc_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + +#ifdef W + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +#endif + +#ifdef MAKECRCH + { + /* + The crc32.h header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. + */ +#if !defined(W) || W != 8 +# error Need a 64-bit integer type in order to generate crc32.h. +#endif + FILE *out; + int k, n; + z_crc_t ltl[8][256]; + z_word_t big[8][256]; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + + /* write out little-endian CRC table to crc32.h */ + fprintf(out, + "/* crc32.h -- tables for rapid CRC calculation\n" + " * Generated automatically by crc32.c\n */\n" + "\n" + "local const z_crc_t FAR crc_table[] = {\n" + " "); + write_table(out, crc_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#ifdef W\n" + "\n" + "#if W == 8\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table64(out, crc_big_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_word_t FAR crc_big_table[] = {\n" + " "); + write_table32hi(out, crc_big_table, 256); + fprintf(out, + "};\n" + "\n" + "#endif\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + fprintf(out, + "\n" + "#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#if W == 8\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table64(out, big[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "local const z_crc_t FAR crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table32hi(out, big[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "#endif\n" + "\n" + "#endif\n"); + } + fprintf(out, + "\n" + "#endif\n"); + + /* write out zeros operator table to crc32.h */ + fprintf(out, + "\n" + "local const z_crc_t FAR x2n_table[] = {\n" + " "); + write_table(out, x2n_table, 32); + fprintf(out, + "};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", + (unsigned long long)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +/* Actually do the deed. */ +int main(void) { + make_crc_table(); + return 0; +} + +#endif /* MAKECRCH */ + +#ifdef W +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. + */ +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + z_crc_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp((n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = byte_swap(q); + } + } +} +#endif + +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32(), and to force the + * generation of the CRC tables in a threaded application. + */ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= + * Use ARM machine instructions if available. This will compute the CRC about + * ten times faster than the braided calculation. This code does not check for + * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will + * only be defined if the compilation specifies an ARM processor architecture + * that has the instructions. For example, compiling with -march=armv8.1-a or + * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 + * instructions. + */ +#ifdef ARMCRC32 + +/* + Constants empirically determined to maximize speed. These values are from + measurements on a Cortex-A57. Your mileage may vary. + */ +#define Z_BATCH 3990 /* number of words in a batch */ +#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ +#define Z_BATCH_MIN 800 /* fewest words in a final batch */ + +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + z_crc_t val; + z_word_t crc1, crc2; + const z_word_t *word; + z_word_t val0, val1, val2; + z_size_t last, last2, i; + z_size_t num; + + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + + /* Compute the CRC up to a word boundary. */ + while (len && ((z_size_t)buf & 7) != 0) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ + word = (z_word_t const *)buf; + num = len >> 3; + len &= 7; + + /* Do three interleaved CRCs to realize the throughput of one crc32x + instruction per cycle. Each CRC is calculated on Z_BATCH words. The + three CRCs are combined into a single CRC after each set of batches. */ + while (num >= 3 * Z_BATCH) { + crc1 = 0; + crc2 = 0; + for (i = 0; i < Z_BATCH; i++) { + val0 = word[i]; + val1 = word[i + Z_BATCH]; + val2 = word[i + 2 * Z_BATCH]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * Z_BATCH; + num -= 3 * Z_BATCH; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; + } + + /* Do one last smaller batch with the remaining words, if there are enough + to pay for the combination of CRCs. */ + last = num / 3; + if (last >= Z_BATCH_MIN) { + last2 = last << 1; + crc1 = 0; + crc2 = 0; + for (i = 0; i < last; i++) { + val0 = word[i]; + val1 = word[i + last]; + val2 = word[i + last2]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * last; + num -= 3 * last; + val = x2nmodp(last, 6); + crc = multmodp(val, crc) ^ crc1; + crc = multmodp(val, crc) ^ crc2; + } + + /* Compute the CRC on any remaining words. */ + for (i = 0; i < num; i++) { + val0 = word[i]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + } + word += num; + + /* Complete the CRC on any remaining bytes. */ + buf = (const unsigned char FAR *)word; + while (len) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#else + +#ifdef W + +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +local z_crc_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (z_crc_t)data; +} + +local z_word_t crc_word_big(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} + +#endif + +/* ========================================================================= */ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { + /* Return initial CRC, if requested. */ + if (buf == Z_NULL) return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + +#ifdef W + + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + z_size_t blks; + z_word_t const *words; + unsigned endian; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((z_size_t)buf & (W - 1)) != 0) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + /* Do endian check at execution time instead of compile time, since ARM + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the + check and the unused branch. */ + endian = 1; + if (*(unsigned char *)&endian) { + /* Little endian. */ + + z_crc_t crc0; + z_word_t word0; +#if N > 1 + z_crc_t crc1; + z_word_t word1; +#if N > 2 + z_crc_t crc2; + z_word_t word2; +#if N > 3 + z_crc_t crc3; + z_word_t word3; +#if N > 4 + z_crc_t crc4; + z_word_t word4; +#if N > 5 + z_crc_t crc5; + z_word_t word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = crc; +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + crc = crc_word(crc0 ^ words[0]); +#if N > 1 + crc = crc_word(crc1 ^ words[1] ^ crc); +#if N > 2 + crc = crc_word(crc2 ^ words[2] ^ crc); +#if N > 3 + crc = crc_word(crc3 ^ words[3] ^ crc); +#if N > 4 + crc = crc_word(crc4 ^ words[4] ^ crc); +#if N > 5 + crc = crc_word(crc5 ^ words[5] ^ crc); +#endif +#endif +#endif +#endif +#endif + words += N; + } + else { + /* Big endian. */ + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = byte_swap(crc); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_big_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_big_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_big_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_big_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_big_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_big_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + comb = crc_word_big(crc0 ^ words[0]); +#if N > 1 + comb = crc_word_big(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word_big(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word_big(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word_big(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word_big(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + crc = byte_swap(comb); + } + + /* + Update the pointer to the remaining bytes to process. + */ + buf = (unsigned char const *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + while (len) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#endif + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { + return crc32_z(crc, buf, len); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { + return crc32_combine64(crc1, crc2, (z_off64_t)len2); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + return x2nmodp(len2, 3); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { + return crc32_combine_gen64((z_off64_t)len2); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { + return multmodp(op, crc1) ^ (crc2 & 0xffffffff); +} diff --git a/thirdparty/zlib/src/crc32.h b/thirdparty/zlib/src/crc32.h index 5de49bc97..137df68d6 100644 --- a/thirdparty/zlib/src/crc32.h +++ b/thirdparty/zlib/src/crc32.h @@ -1,441 +1,9446 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +local const z_word_t FAR crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +local const z_word_t FAR crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#if N == 1 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif + +#endif + +#if N == 2 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + +#endif + +#endif + +#if N == 3 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif + +#endif + +#if N == 4 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif + +#endif + +#if N == 5 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif + +#endif + +#if N == 6 + +#if W == 8 + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +local const z_crc_t FAR crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +local const z_word_t FAR crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif + +#endif + +#endif + +local const z_crc_t FAR x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; diff --git a/thirdparty/zlib/src/deflate.c b/thirdparty/zlib/src/deflate.c index ce87dd918..012ea8148 100644 --- a/thirdparty/zlib/src/deflate.c +++ b/thirdparty/zlib/src/deflate.c @@ -1,1679 +1,2139 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id: deflate.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size) -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_ (z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size) -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength) -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - - (void) hash_head; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (z_streamp strm) -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (z_streamp strm, gz_headerp head) -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (z_streamp strm, int bits, int value) -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams (z_streamp strm, int level, int strategy) -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune (z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain) -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. - */ -uLong ZEXPORT deflateBound (z_streamp strm, uLong sourceLen) -{ - deflate_state *s; - uLong destLen; - - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; - - /* if can't get parameters, return conservative bound */ - if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; - - /* if not default parameters, return conservative bound */ - s = strm->state; - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; - - /* default settings: return tight bound for that case */ - return compressBound(sourceLen); -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (deflate_state *s, uInt b) -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending (z_streamp strm) -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (z_streamp strm, int flush) -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (z_streamp strm) -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (z_streamp dest, z_streamp source) -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf (z_streamp strm, Bytef *buf, unsigned size) -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (deflate_state *s) -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(deflate_state *s, IPos cur_match) -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - Bytef *scan = s->window + s->strstart; /* current string */ - Bytef *match; /* matched string */ - int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - ush scan_start = *(ushf*)scan; - ush scan_end = *(ushf*)(scan+best_len-1); -#else - Bytef *strend = s->window + s->strstart + MAX_MATCH; - Byte scan_end1 = scan[best_len-1]; - Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ -#endif /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only - */ -local uInt longest_match_fast (deflate_state *s, IPos cur_match) -{ - Bytef *scan = s->window + s->strstart; /* current string */ - Bytef *match; /* matched string */ - int len; /* length of current match */ - Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(deflate_state *s, IPos start, IPos match, int length) -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window (deflate_state *s) -{ - unsigned n, m; - Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - /* %%% avoid this when Z_RLE */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(deflate_state *s, int flush) -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(deflate_state *s, int flush) -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ -#ifdef FASTEST - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(deflate_state *s, int flush) -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -#if 0 -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt run; /* length of run */ - uInt max; /* maximum length of run */ - uInt prev; /* byte at distance one to match */ - Bytef *scan; /* scan for end of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - run = 0; - if (s->strstart > 0) { /* if there is a previous byte, that is */ - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; - scan = s->window + s->strstart - 1; - prev = *scan++; - do { - if (*scan++ != prev) - break; - } while (++run < max); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (run >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, run); - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); - s->lookahead -= run; - s->strstart += run; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func)(deflate_state *s, int flush); +/* Compression function. Returns the block state after the call. */ + +local block_state deflate_stored(deflate_state *s, int flush); +local block_state deflate_fast(deflate_state *s, int flush); +#ifndef FASTEST +local block_state deflate_slow(deflate_state *s, int flush); +#endif +local block_state deflate_rle(deflate_state *s, int flush); +local block_state deflate_huff(deflate_state *s, int flush); + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + do { \ + s->head[s->hash_size - 1] = NIL; \ + zmemzero((Bytef *)s->head, \ + (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ + } while (0) + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __attribute__((no_sanitize("memory"))) +# endif +#endif +local void slide_hash(deflate_state *s) { + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(deflate_state *s) { + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize + MAX_DIST(s)) { + + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* ========================================================================= */ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, + int stream_size) { + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size) { + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + if (windowBits < -15) + return Z_STREAM_ERROR; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = (uInt)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = (uInt)memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n - 2) bits have been written, just + * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 + * symbols are written.) The closest the writing gets to what is unread is + * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); + s->pending_buf_size = (ulg)s->lit_bufsize * 4; + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; +#endif + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck(z_streamp strm) { + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep(z_streamp strm) { + deflate_state *s; + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + INIT_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = -2; + + _tr_init(s); + + return Z_OK; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init(deflate_state *s) { + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset(z_streamp strm) { + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { + deflate_state *s; + int put; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else + if (bits < 0 || bits > 16 || + s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#endif + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { + deflate_state *s; + compress_func func; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + s->last_flush != -2) { + /* Flush the last buffer: */ + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, + int nice_length, int max_chain) { + deflate_state *s; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (uInt)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns a + * close to exact, as well as small, upper bound on the compressed size. This + * is an expansion of ~0.03%, plus a small constant. + * + * For any setting other than those defaults for windowBits and memLevel, one + * of two worst case bounds is returned. This is at most an expansion of ~4% or + * ~13%, plus a small constant. + * + * Both the 0.03% and 4% derive from the overhead of stored blocks. The first + * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second + * is for stored blocks of 127 bytes (the worst case memLevel == 1). The + * expansion results from five bytes of header for each stored block. + * + * The larger expansion of 13% results from a window size less than or equal to + * the symbols buffer size (windowBits <= memLevel + 7). In that case some of + * the data being compressed may have slid out of the sliding window, impeding + * a stored block from being emitted. Then the only choice is a fixed or + * dynamic block, where a fixed block limits the maximum expansion to 9 bits + * per 8-bit byte, plus 10 bits for every block. The smallest block size for + * which this can occur is 255 (memLevel == 2). + * + * Shifts are used to approximate divisions, for speed. + */ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { + deflate_state *s; + uLong fixedlen, storelen, wraplen; + + /* upper bound for fixed blocks with 9-bit literals and length 255 + (memLevel == 2, which is the lowest that may not use stored blocks) -- + ~13% overhead plus a small constant */ + fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + + (sourceLen >> 9) + 4; + + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + + (sourceLen >> 11) + 7; + + /* if can't get parameters, return larger bound plus a zlib wrapper */ + if (deflateStateCheck(strm)) + return (fixedlen > storelen ? fixedlen : storelen) + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return one of the conservative bounds */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + + wraplen; + + /* default settings: return tight bound for that case -- ~0.03% overhead + plus a small constant */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB(deflate_state *s, uInt b) { + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +local void flush_pending(z_streamp strm) { + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int ZEXPORT deflate(z_streamp strm, int flush) { + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE && s->wrap == 0) + s->status = BUSY_STATE; + if (s->status == INIT_STATE) { + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd(z_streamp strm) { + int status; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { +#ifdef MAXSEG_64K + (void)dest; + (void)source; + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + + + if (deflateStateCheck(source) || dest == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +local uInt longest_match(deflate_state *s, IPos cur_match) { + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = (int)s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan + best_len - 1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len - 1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match + best_len - 1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart + 3, + 5, up to strstart + 257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + *(ushf*)(scan += 2) == *(ushf*)(match += 2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window + strstart + 257 */ + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend - scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len - 1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len - 1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window + (unsigned)(s->window_size - 1), + "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan + best_len - 1); +#else + scan_end1 = scan[best_len - 1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(deflate_state *s, IPos cur_match) { + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len - 1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart + 258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(deflate_state *s, IPos start, IPos match, int length) { + /* check that the match is indeed a match */ + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); + do { + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start - match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* ZLIB_DEBUG */ + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunities to have a single copy from next_in to next_out. + */ +local block_state deflate_stored(deflate_state *s, int flush) { + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + s->insert = s->strstart; + } + else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + if (s->insert > s->strstart) + s->insert = s->strstart; + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + s->insert += MIN(used, s->w_size - s->insert); + } + s->block_start = s->strstart; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + if (s->insert > s->strstart) + s->insert = s->strstart; + } + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + s->insert += MIN(have, s->w_size - s->insert); + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(deflate_state *s, int flush) { + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart + 2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(deflate_state *s, int flush) { + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart + 2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart - 1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart - 1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart - 1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length - 1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(deflate_state *s, int flush) { + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (uInt)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window + (uInt)(s->window_size - 1), + "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(deflate_state *s, int flush) { + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/thirdparty/zlib/src/deflate.h b/thirdparty/zlib/src/deflate.h index a3bae5f1e..300c6ada6 100644 --- a/thirdparty/zlib/src/deflate.h +++ b/thirdparty/zlib/src/deflate.h @@ -1,333 +1,377 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2004 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id: deflate.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -#define NO_DUMMY_DECL - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch _length_code[]; - extern uch _dist_code[]; -#else - extern const uch _length_code[]; - extern const uch _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2024 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + ulg pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + ulg gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 + uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt sym_next; /* running index in symbol buffer */ + uInt sym_end; /* symbol table full when sym_next reaches this */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef ZLIB_DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init(deflate_state *s); +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last); +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); +void ZLIB_INTERNAL _tr_align(deflate_state *s); +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef ZLIB_DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->sym_buf[s->sym_next++] = (uch)dist; \ + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ + s->sym_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#endif +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/thirdparty/zlib/src/gzclose.c b/thirdparty/zlib/src/gzclose.c new file mode 100644 index 000000000..48d6a86f0 --- /dev/null +++ b/thirdparty/zlib/src/gzclose.c @@ -0,0 +1,23 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(gzFile file) { +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/thirdparty/zlib/src/gzguts.h b/thirdparty/zlib/src/gzguts.h new file mode 100644 index 000000000..eba72085b --- /dev/null +++ b/thirdparty/zlib/src/gzguts.h @@ -0,0 +1,214 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# undef _FILE_OFFSET_BITS +# undef _TIME_BITS +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#if defined(_WIN32) +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc(uInt size); + extern void free(voidpf ptr); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + int reset; /* true if a reset is pending after a Z_FINISH */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror(DWORD error); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +unsigned ZLIB_INTERNAL gz_intmax(void); +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/thirdparty/zlib/src/gzlib.c b/thirdparty/zlib/src/gzlib.c new file mode 100644 index 000000000..983153cc8 --- /dev/null +++ b/thirdparty/zlib/src/gzlib.c @@ -0,0 +1,582 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(gz_statep state) { + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + else /* for writing ... */ + state->reset = 0; /* no deflateReset pending */ + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(const void *path, int fd, const char *mode) { + gz_statep state; + z_size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (z_size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef WIDECHAR + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(int fd, const char *mode) { + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(gzFile file, unsigned size) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 8) + size = 8; /* needed to behave well with flushing */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(gzFile file) { + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(gzFile file) { + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(gzFile file) { + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(gzFile file, int *errnum) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(gzFile file) { + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif +} + +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax(void) { +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +#endif +} diff --git a/thirdparty/zlib/src/gzread.c b/thirdparty/zlib/src/gzread.c new file mode 100644 index 000000000..4168cbc88 --- /dev/null +++ b/thirdparty/zlib/src/gzread.c @@ -0,0 +1,602 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(gz_statep state, unsigned char *buf, unsigned len, + unsigned *have) { + int ret; + unsigned get, max = ((unsigned)-1 >> 2) + 1; + + *have = 0; + do { + get = len - *have; + if (get > max) + get = max; + ret = read(state->fd, buf + *have, get); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(gz_statep state) { + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(gz_statep state) { + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(gz_statep state) { + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(gz_statep state) { + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(gz_statep state, z_off64_t len) { + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) { + z_size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) { + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(gzFile file) { + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(gzFile file) { + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(int c, gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* in case this was just opened, set up the input buffer */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(gzFile file, char *buf, int len) { + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(gzFile file) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(gzFile file) { + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/thirdparty/zlib/src/gzwrite.c b/thirdparty/zlib/src/gzwrite.c new file mode 100644 index 000000000..435b4621b --- /dev/null +++ b/thirdparty/zlib/src/gzwrite.c @@ -0,0 +1,631 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +local int gz_init(gz_statep state) { + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +local int gz_comp(gz_statep state, int flush) { + int ret, writ; + unsigned have, put, max = ((unsigned)-1 >> 2) + 1; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + while (strm->avail_in) { + put = strm->avail_in > max ? max : strm->avail_in; + writ = write(state->fd, strm->next_in, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in -= (unsigned)writ; + strm->next_in += writ; + } + return 0; + } + + /* check for a pending reset */ + if (state->reset) { + /* don't start a new gzip member unless there is data to write */ + if (strm->avail_in == 0) + return 0; + deflateReset(strm); + state->reset = 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + while (strm->next_out > state->x.next) { + put = strm->next_out - state->x.next > (int)max ? max : + (unsigned)(strm->next_out - state->x.next); + writ = write(state->fd, state->x.next, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + state->x.next += writ; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + state->reset = 1; + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +local int gz_zero(gz_statep state, z_off64_t len) { + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* Write len bytes from buf to file. Return the number of bytes written. If + the returned value is less than len, then there was an error. */ +local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { + z_size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const Bytef *)buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, + gzFile file) { + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(gzFile file, int c) { + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(gzFile file, const char *s) { + z_size_t len, put; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(s); + if ((int)len < 0 || (unsigned)len != len) { + gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); + return -1; + } + put = gz_write(state, s, len); + return put < len ? -1 : (int)len; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { + int len; + unsigned left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(next, format, va); + for (len = 0; len < state->size; len++) + if (next[len] == 0) break; +# else + len = vsprintf(next, format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(next, state->size, format, va); + len = strlen(next); +# else + len = vsnprintf(next, state->size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, + int a4, int a5, int a6, int a7, int a8, int a9, int a10, + int a11, int a12, int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) { + unsigned len, left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return Z_STREAM_ERROR; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->error; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->error; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(strm->next_in + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (next[len] == 0) + break; +# else + len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, + a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(next); +# else + len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return (int)len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(gzFile file, int flush) { + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(gzFile file) { + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/thirdparty/zlib/src/infback.c b/thirdparty/zlib/src/infback.c index c259d01fc..e7b25b307 100644 --- a/thirdparty/zlib/src/infback.c +++ b/thirdparty/zlib/src/infback.c @@ -1,611 +1,628 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables1 OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size) -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->write = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables1 (struct inflate_state FAR *state) -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc) -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code thisx; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables1(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - thisx = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(thisx.bits) <= bits) break; - PULLBYTE(); - } - if (thisx.val < 16) { - NEEDBITS(thisx.bits); - DROPBITS(thisx.bits); - state->lens[state->have++] = thisx.val; - } - else { - if (thisx.val == 16) { - NEEDBITS(thisx.bits + 2); - DROPBITS(thisx.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (thisx.val == 17) { - NEEDBITS(thisx.bits + 3); - DROPBITS(thisx.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(thisx.bits + 7); - DROPBITS(thisx.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - thisx = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(thisx.bits) <= bits) break; - PULLBYTE(); - } - if (thisx.op && (thisx.op & 0xf0) == 0) { - last = thisx; - for (;;) { - thisx = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + thisx.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(thisx.bits); - state->length = (unsigned)thisx.val; - - /* process literal */ - if (thisx.op == 0) { - Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", thisx.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (thisx.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (thisx.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(thisx.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - thisx = state->distcode[BITS(state->distbits)]; - if ((unsigned)(thisx.bits) <= bits) break; - PULLBYTE(); - } - if ((thisx.op & 0xf0) == 0) { - last = thisx; - for (;;) { - thisx = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + thisx.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(thisx.bits); - if (thisx.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)thisx.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(thisx.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd (z_streamp strm) -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, const char *version, + int stream_size) { + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = (uInt)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + state->sane = 1; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc) { + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + /* fallthrough */ + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: + /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Write leftover output and return unused input */ + inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && + ret == Z_STREAM_END) + ret = Z_BUF_ERROR; + } + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(z_streamp strm) { + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/thirdparty/zlib/src/inffast.c b/thirdparty/zlib/src/inffast.c index 6ac383d4e..9354676e7 100644 --- a/thirdparty/zlib/src/inffast.c +++ b/thirdparty/zlib/src/inffast.c @@ -1,316 +1,320 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void inflate_fast (z_streamp strm, unsigned start) -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code thisx; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - write = state->write; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - thisx = lcode[hold & lmask]; - dolen: - op = (unsigned)(thisx.bits); - hold >>= op; - bits -= op; - op = (unsigned)(thisx.op); - if (op == 0) { /* literal */ - Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", thisx.val)); - PUP(out) = (unsigned char)(thisx.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(thisx.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - thisx = dcode[hold & dmask]; - dodist: - op = (unsigned)(thisx.bits); - hold >>= op; - bits -= op; - op = (unsigned)(thisx.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(thisx.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - from = window - OFF; - if (write == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += write - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - thisx = dcode[thisx.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - thisx = lcode[thisx.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code const *here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - 5); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = lcode + (hold & lmask); + dolen: + op = (unsigned)(here->bits); + hold >>= op; + bits -= op; + op = (unsigned)(here->op); + if (op == 0) { /* literal */ + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here->val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = dcode + (hold & dmask); + dodist: + op = (unsigned)(here->bits); + hold >>= op; + bits -= op; + op = (unsigned)(here->op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here->val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = window; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } while (len > 2); + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode + here->val + (hold & ((1U << op) - 1)); + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode + here->val + (hold & ((1U << op) - 1)); + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/thirdparty/zlib/src/inffast.h b/thirdparty/zlib/src/inffast.h index 614fa7877..49c6d156c 100644 --- a/thirdparty/zlib/src/inffast.h +++ b/thirdparty/zlib/src/inffast.h @@ -1,11 +1,11 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void inflate_fast OF((z_streamp strm, unsigned start)); +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/thirdparty/zlib/src/inffixed.h b/thirdparty/zlib/src/inffixed.h index 423d5c5b5..d62832776 100644 --- a/thirdparty/zlib/src/inffixed.h +++ b/thirdparty/zlib/src/inffixed.h @@ -1,94 +1,94 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/thirdparty/zlib/src/inflate.c b/thirdparty/zlib/src/inflate.c index eef0d37db..94ecff015 100644 --- a/thirdparty/zlib/src/inflate.c +++ b/thirdparty/zlib/src/inflate.c @@ -1,1339 +1,1526 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset (z_streamp strm) -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->write = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflatePrime (z_streamp strm, int bits, int value) -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1 << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version, int stream_size) -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { - ZFREE(strm, state); - strm->state = Z_NULL; - return Z_STREAM_ERROR; - } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); -} - -int ZEXPORT inflateInit_ (z_streamp strm, const char *version, int stream_size) -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables (struct inflate_state FAR *state) -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow (z_streamp strm, unsigned out) -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->write = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->write; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; - state->whave = state->wsize; - } - else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate (z_streamp strm, int flush) -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code thisx; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - thisx = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(thisx.bits) <= bits) break; - PULLBYTE(); - } - if (thisx.val < 16) { - NEEDBITS(thisx.bits); - DROPBITS(thisx.bits); - state->lens[state->have++] = thisx.val; - } - else { - if (thisx.val == 16) { - NEEDBITS(thisx.bits + 2); - DROPBITS(thisx.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (thisx.val == 17) { - NEEDBITS(thisx.bits + 3); - DROPBITS(thisx.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(thisx.bits + 7); - DROPBITS(thisx.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - break; - } - for (;;) { - thisx = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(thisx.bits) <= bits) break; - PULLBYTE(); - } - if (thisx.op && (thisx.op & 0xf0) == 0) { - last = thisx; - for (;;) { - thisx = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + thisx.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(thisx.bits); - state->length = (unsigned)thisx.val; - if ((int)(thisx.op) == 0) { - Tracevv((stderr, thisx.val >= 0x20 && thisx.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", thisx.val)); - state->mode = LIT; - break; - } - if (thisx.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - if (thisx.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(thisx.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->mode = DIST; - case DIST: - for (;;) { - thisx = state->distcode[BITS(state->distbits)]; - if ((unsigned)(thisx.bits) <= bits) break; - PULLBYTE(); - } - if ((thisx.op & 0xf0) == 0) { - last = thisx; - for (;;) { - thisx = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + thisx.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(thisx.bits); - if (thisx.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)thisx.val; - state->extra = (unsigned)(thisx.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->write - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd (z_streamp strm) -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength) -{ - struct inflate_state FAR *state; - unsigned long id_; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id_ = adler32(0L, Z_NULL, 0); - id_ = adler32(id_, dictionary, dictLength); - if (id_ != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader (z_streamp strm, gz_headerp head) -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch (unsigned FAR *have, unsigned char FAR *buf, unsigned len) -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync (z_streamp strm) -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint (z_streamp strm) -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +local int inflateStateCheck(z_streamp strm) { + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int ZEXPORT inflateResetKeep(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->flags = -1; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + if (windowBits < -15) + return Z_STREAM_ERROR; + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(struct inflate_state FAR *state) { +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed(void) +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE_CHECK(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(z_streamp strm, int flush) { + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > 15 || len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + /* fallthrough */ + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + /* fallthrough */ + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + /* fallthrough */ + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + /* fallthrough */ + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL && + (len = state->head->extra_len - state->length) < + state->head->extra_max) { + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + /* fallthrough */ + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + /* fallthrough */ + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + /* fallthrough */ + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + /* fallthrough */ + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + /* fallthrough */ + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case COPY_: + state->mode = COPY; + /* fallthrough */ + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + /* fallthrough */ + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + /* fallthrough */ + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + /* fallthrough */ + case LEN_: + state->mode = LEN; + /* fallthrough */ + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + /* fallthrough */ + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + /* fallthrough */ + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + /* fallthrough */ + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + /* fallthrough */ + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE_CHECK(state->check, put - out, out); + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + /* fallthrough */ + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + /* fallthrough */ + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* fallthrough */ + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE_CHECK(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(z_streamp strm) { + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(z_streamp strm) { + unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold >>= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->flags = flags; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + (void)subvert; + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int ZEXPORT inflateValidate(z_streamp strm, int check) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check && state->wrap) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long ZEXPORT inflateMark(z_streamp strm) { + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) + return -(1L << 16); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/thirdparty/zlib/src/inflate.h b/thirdparty/zlib/src/inflate.h index 31b1279c5..f127b6b1f 100644 --- a/thirdparty/zlib/src/inflate.h +++ b/thirdparty/zlib/src/inflate.h @@ -1,121 +1,126 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFLATE_H_ -#define _INFLATE_H_ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to the BAD or MEM mode -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 7K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ -}; - - -#endif +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/thirdparty/zlib/src/inftrees.c b/thirdparty/zlib/src/inftrees.c index dfc0aa73e..98cfe1644 100644 --- a/thirdparty/zlib/src/inftrees.c +++ b/thirdparty/zlib/src/inftrees.c @@ -1,328 +1,299 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int inflate_table (codetype type, - unsigned short FAR *lens, - unsigned codes, - code FAR * FAR *table, - unsigned FAR *bits, - unsigned short FAR *work) -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code thisx; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 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 unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 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 unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - thisx.op = (unsigned char)64; /* invalid code marker */ - thisx.bits = (unsigned char)1; - thisx.val = (unsigned short)0; - *(*table)++ = thisx; /* make a table to force an error */ - *(*table)++ = thisx; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min <= MAXBITS; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - thisx.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - thisx.op = (unsigned char)0; - thisx.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - thisx.op = (unsigned char)(extra[work[sym]]); - thisx.val = base[work[sym]]; - } - else { - thisx.op = (unsigned char)(32 + 64); /* end of block */ - thisx.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = thisx; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - thisx.op = (unsigned char)64; /* invalid code marker */ - thisx.bits = (unsigned char)(len - drop); - thisx.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - thisx.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = thisx; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2024 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 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 unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 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 unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/thirdparty/zlib/src/inftrees.h b/thirdparty/zlib/src/inftrees.h index ea64af090..396f74b5d 100644 --- a/thirdparty/zlib/src/inftrees.h +++ b/thirdparty/zlib/src/inftrees.h @@ -1,61 +1,62 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFTREES_H_ -#define _INFTREES_H_ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1444 code structures (852 for length/literals - and 592 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 2048 -#define MAXD 592 - -/* Type of code to build for inftable() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -extern int inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); - - -#endif +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/thirdparty/zlib/src/trees.c b/thirdparty/zlib/src/trees.c index bcb2670c5..6a523ef34 100644 --- a/thirdparty/zlib/src/trees.c +++ b/thirdparty/zlib/src/trees.c @@ -1,1191 +1,1117 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id: trees.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {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}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {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}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits (deflate_state *s, int value, int length) -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += (int) (length - Buf_size); - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(deflate_state *s) -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block (deflate_state *s) -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap (deflate_state *s, - ct_data *tree, /* the tree to restore */ - int k) /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen (deflate_state *s, tree_desc *desc) -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (ct_data *tree, /* the tree to decorate */ - int max_code, /* largest code with non zero frequency */ - ushf *bl_count) /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code_ = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code_ = (code_ + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code_ + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (deflate_state *s, - ct_data *tree, /* the tree to be scanned */ - int max_code) /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (deflate_state *s, - ct_data *tree, /* the tree to be scanned */ - int max_code) /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree (deflate_state *s) -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees (deflate_state *s, - int lcodes, int dcodes, int blcodes) /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block (deflate_state *s, charf *buf, ulg stored_len, int eof) -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align (deflate_state *s) -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void _tr_flush_block (deflate_state *s, - charf *buf, /* input block, or NULL if too old */ - ulg stored_len, /* length of input block */ - int eof) /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) - set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (eof) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (deflate_state *s, - unsigned dist, /* distance of matched string */ - unsigned lc) /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block (deflate_state *s, - ct_data *ltree, /* literal tree */ - ct_data *dtree) /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code_; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code_ = _length_code[lc]; - send_code(s, code_+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code_]; - if (extra != 0) { - lc -= base_length[code_]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code_ = d_code(dist); - Assert (code_ < D_CODES, "bad d_code"); - - send_code(s, code_, dtree); /* send the distance code */ - extra = extra_dbits[code_]; - if (extra != 0) { - dist -= base_dist[code_]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local void set_data_type (deflate_state *s) -{ - int n; - - for (n = 0; n < 9; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - if (n == 9) - for (n = 14; n < 32; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse (unsigned code_, int len) -{ - unsigned res = 0; - do { - res |= code_ & 1; - code_ >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush (deflate_state *s) -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup (deflate_state *s) -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(deflate_state *s, - charf *buf, /* the input data */ - unsigned len, /* its length */ - int header) /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2024 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef ZLIB_DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {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}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {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}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +#ifdef NO_INIT_GLOBAL_POINTERS +# define TCONST +#else +# define TCONST const +#endif + +local TCONST static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local TCONST static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local TCONST static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(unsigned code, int len) { + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(deflate_state *s) { + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(deflate_state *s) { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent + 7) & ~7; +#endif +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + } +} + +#ifdef GEN_TREES_H +local void gen_trees_header(void); +#endif + +#ifndef ZLIB_DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* !ZLIB_DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef ZLIB_DEBUG +local void send_bits(deflate_state *s, int value, int length) { + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !ZLIB_DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = (int)value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* ZLIB_DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init(void) { +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length - 1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256 + dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Generate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef ZLIB_DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width) - 1 ? ",\n" : ", ")) + +void gen_trees_header(void) { + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(deflate_state *s) { + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(deflate_state *s, ct_data *tree, int k) { + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(deflate_state *s, tree_desc *desc) { + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n - base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); + } + if (overflow == 0) return; + + Tracev((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +#ifdef DUMP_BL_TREE +# include +#endif + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(deflate_state *s, tree_desc *desc) { + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code + 1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree(deflate_state *s, ct_data *tree, int max_code) { + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code + 1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(deflate_state *s) { + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except the + * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(deflate_state *s, int lcodes, int dcodes, + int blcodes) { + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { + send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + if (stored_len) + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2*16; + s->bits_sent += stored_len << 3; +#endif +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(deflate_state *s) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef ZLIB_DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(deflate_state *s, const ct_data *ltree, + const ct_data *dtree) { + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in symbol buffers */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; +#endif + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(deflate_state *s) { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long block_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>= 1) + if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("allow-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len + 3 + 7) >> 3; + static_lenb = (s->static_len + 3 + 7) >> 3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + +#ifndef FORCE_STATIC + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) +#endif + opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len + 4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (static_lenb == opt_lenb) { + send_bits(s, (STATIC_TREES<<1) + last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1) + last, 3); + send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, + max_blindex + 1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef ZLIB_DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + s->compressed_len - 7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else + s->sym_buf[s->sym_next++] = (uch)dist; + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); + s->sym_buf[s->sym_next++] = (uch)lc; +#endif + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + return (s->sym_next == s->sym_end); +} diff --git a/thirdparty/zlib/src/trees.h b/thirdparty/zlib/src/trees.h index 5ac45a723..d35639d82 100644 --- a/thirdparty/zlib/src/trees.h +++ b/thirdparty/zlib/src/trees.h @@ -1,127 +1,128 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/thirdparty/zlib/src/uncompr.c b/thirdparty/zlib/src/uncompr.c index 839602f4b..5e256663b 100644 --- a/thirdparty/zlib/src/uncompr.c +++ b/thirdparty/zlib/src/uncompr.c @@ -1,60 +1,85 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: uncompr.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (Bytef *dest, - uLongf *destLen, - const Bytef *source, - uLong sourceLen) -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong len, left; + Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } + else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (uLong)max ? max : (uInt)len; + len -= stream.avail_in; + } + err = inflate(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + inflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { + return uncompress2(dest, destLen, source, &sourceLen); +} diff --git a/thirdparty/zlib/src/zconf.h b/thirdparty/zlib/src/zconf.h index 81cbda60d..62adc8d84 100644 --- a/thirdparty/zlib/src/zconf.h +++ b/thirdparty/zlib/src/zconf.h @@ -1,345 +1,543 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: zconf.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#ifndef ZCONF_H -#define ZCONF_H - -// *** Just a few hacks here to make it compile nicely with Yup.. -#define Z_PREFIX 1 -#undef __MACTYPES__ - -#ifdef _MSC_VER - #pragma warning (disable : 4131 4127 4244 4267) -#endif - - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define inflatePrime z_inflatePrime -# define inflateGetHeader z_inflateGetHeader -# define adler32_combine z_adler32_combine -# define crc32_combine z_crc32_combine -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/thirdparty/zlib/src/zconf.in.h b/thirdparty/zlib/src/zconf.in.h deleted file mode 100644 index 018173ab6..000000000 --- a/thirdparty/zlib/src/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: zconf.in.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/thirdparty/zlib/src/zlib.h b/thirdparty/zlib/src/zlib.h index bdf8af7d0..8d4b932ea 100644 --- a/thirdparty/zlib/src/zlib.h +++ b/thirdparty/zlib/src/zlib.h @@ -1,1358 +1,1938 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -//extern "C" { -#endif - -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 - - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -//ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -//ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); - -#ifdef __cplusplus -//} -#endif - -#endif /* ZLIB_H */ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.3.1, January 22nd, 2024 + + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 1 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte will go here */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. total_in, total_out, adler, and msg are initialized. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. total_in, total_out, adler, and msg are initialized. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); + +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. len2 must be non-negative. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). len2 must be non-negative. +*/ + +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# define z_crc32_combine_gen z_crc32_combine_gen64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# define crc32_combine_gen crc32_combine_gen64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); + +#endif /* !Z_SOLO */ + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/thirdparty/zlib/src/zutil.c b/thirdparty/zlib/src/zutil.c index 630305ca2..b1c5d2d3c 100644 --- a/thirdparty/zlib/src/zutil.c +++ b/thirdparty/zlib/src/zutil.c @@ -1,311 +1,299 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: zutil.c,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -/*const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch (sizeof(uInt)) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch (sizeof(uLong)) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch (sizeof(voidpf)) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch (sizeof(z_off_t)) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -}*/ - -#if 0 - -# ifndef verbose -# define verbose 0 -# endif -int z_verbose = verbose; - -void z_error (const char *m) -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(int err) -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +z_const char * const z_errmsg[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + + +const char * ZEXPORT zlibVersion(void) { + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags(void) { + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif + /* +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif + */ +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +#include +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error(char *m) { + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(int err) { + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 + /* The older Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { + voidpf buf; + ulg bsize = (ulg)items*size; + + (void)opaque; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + int n; + + (void)opaque; + + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { + (void)opaque; + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + (void)opaque; + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); +#endif + +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { + (void)opaque; + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { + (void)opaque; + free(ptr); +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/thirdparty/zlib/src/zutil.h b/thirdparty/zlib/src/zutil.h index 393985870..48dd7feba 100644 --- a/thirdparty/zlib/src/zutil.h +++ b/thirdparty/zlib/src/zutil.h @@ -1,271 +1,254 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id: zutil.h,v 1.1 2007/06/07 17:54:37 jules_rms Exp $ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL -#include "zlib.h" - -#ifdef STDC -# ifndef _WIN32_WCE -# include -# endif -# include -# include -#endif -#ifdef NO_ERRNO_H -# ifdef _WIN32_WCE - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. We rename it to - * avoid conflict with other libraries that use the same workaround. - */ -# define errno z_errno -# endif - extern int errno; -#else -# ifndef _WIN32_WCE -# include -# endif -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# ifdef M_I86 - #include -# endif -#endif - -#if defined(MACOS) || TARGET_OS_MAC -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#if 0 -# include - extern int z_verbose; - extern void z_error OF((const char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -# define z_error(x) -# define z_verbose 0 -#endif - - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) +# include +# if (ULONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long +# elif (ULLONG_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned long long +# elif (UINT_MAX == 0xffffffffffffffff) +# define Z_U8 unsigned +# endif +#endif + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 2 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) +# define OS_CODE 7 +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error(char *m); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/thirdparty/zlib/zlib.c b/thirdparty/zlib/zlib.c index 89acdd920..6aa00bbc0 100644 --- a/thirdparty/zlib/zlib.c +++ b/thirdparty/zlib/zlib.c @@ -24,27 +24,7 @@ #include #include -#if _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4309) -#pragma warning (disable: 4305) -#pragma warning (disable: 4365) -#pragma warning (disable: 6385) -#pragma warning (disable: 6326) -#pragma warning (disable: 6340) -#else -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wshadow" -#pragma clang diagnostic ignored "-Wdeprecated-register" -#pragma clang diagnostic ignored "-Wswitch-enum" -#pragma clang diagnostic ignored "-Wswitch-default" -#pragma clang diagnostic ignored "-Wredundant-decls" -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" -#pragma clang diagnostic ignored "-Wcomma" -#endif +YUP_ZLIB_BEGIN_IGNORE_WARNINGS #include "src/adler32.c" #include "src/compress.c" @@ -52,21 +32,8 @@ #undef DO8 #include "src/crc32.c" #include "src/deflate.c" -#include "src/inffast.c" -#undef PULLBYTE -#undef LOAD -#undef RESTORE -#undef INITBITS -#undef NEEDBITS -#undef DROPBITS -#undef BYTEBITS -#include "src/inflate.c" -#include "src/inftrees.c" #include "src/trees.c" +#undef GZIP #include "src/zutil.c" -#if _MSC_VER -#pragma warning (pop) -#else -#pragma clang diagnostic pop -#endif +YUP_ZLIB_END_IGNORE_WARNINGS diff --git a/thirdparty/zlib/zlib.h b/thirdparty/zlib/zlib.h index a64c3b0fb..885c175e6 100644 --- a/thirdparty/zlib/zlib.h +++ b/thirdparty/zlib/zlib.h @@ -51,6 +51,40 @@ extern "C" { #define NO_DUMMY_DECL #include "src/zlib.h" +#if ! defined (Z_PREFIX) +typedef uInt z_uInt; +#endif + +#if defined (_MSC_VER) +#define YUP_ZLIB_BEGIN_IGNORE_WARNINGS \ + __pragma (warning (push)) \ + __pragma (warning (disable: 4309)) \ + __pragma (warning (disable: 4305)) \ + __pragma (warning (disable: 4365)) \ + __pragma (warning (disable: 6385)) \ + __pragma (warning (disable: 6326)) \ + __pragma (warning (disable: 6340)) +#define YUP_ZLIB_END_IGNORE_WARNINGS __pragma (warning (pop)) +#elif defined (__clang__) +#define YUP_ZLIB_PRAGMA(x) _Pragma (#x) +#define YUP_ZLIB_BEGIN_IGNORE_WARNINGS \ + YUP_ZLIB_PRAGMA (clang diagnostic push) \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wconversion") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wsign-conversion") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wshadow") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wdeprecated-register") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wswitch-enum") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wswitch-default") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wredundant-decls") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wimplicit-fallthrough") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wzero-as-null-pointer-constant") \ + YUP_ZLIB_PRAGMA (clang diagnostic ignored "-Wcomma") +#define YUP_ZLIB_END_IGNORE_WARNINGS YUP_ZLIB_PRAGMA (clang diagnostic pop) +#else +#define YUP_ZLIB_BEGIN_IGNORE_WARNINGS +#define YUP_ZLIB_END_IGNORE_WARNINGS +#endif + #if __cplusplus } // extern "C" #endif diff --git a/thirdparty/zlib/zlib_inffast.c b/thirdparty/zlib/zlib_inffast.c new file mode 100644 index 000000000..93ceeb6eb --- /dev/null +++ b/thirdparty/zlib/zlib_inffast.c @@ -0,0 +1,28 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "zlib.h" + +YUP_ZLIB_BEGIN_IGNORE_WARNINGS + +#include "src/inffast.c" + +YUP_ZLIB_END_IGNORE_WARNINGS diff --git a/thirdparty/zlib/zlib_inflate.c b/thirdparty/zlib/zlib_inflate.c new file mode 100644 index 000000000..bd87a51ac --- /dev/null +++ b/thirdparty/zlib/zlib_inflate.c @@ -0,0 +1,28 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "zlib.h" + +YUP_ZLIB_BEGIN_IGNORE_WARNINGS + +#include "src/inflate.c" + +YUP_ZLIB_END_IGNORE_WARNINGS diff --git a/thirdparty/zlib/zlib_inftrees.c b/thirdparty/zlib/zlib_inftrees.c new file mode 100644 index 000000000..06ae858f7 --- /dev/null +++ b/thirdparty/zlib/zlib_inftrees.c @@ -0,0 +1,28 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include "zlib.h" + +YUP_ZLIB_BEGIN_IGNORE_WARNINGS + +#include "src/inftrees.c" + +YUP_ZLIB_END_IGNORE_WARNINGS diff --git a/tools/update_rive.py b/tools/rive_update.py similarity index 86% rename from tools/update_rive.py rename to tools/rive_update.py index 8b4e0c41f..4190af27a 100755 --- a/tools/update_rive.py +++ b/tools/rive_update.py @@ -40,6 +40,26 @@ DEFAULT_MANIFEST = SCRIPT_DIR / "rive_update_manifest.json" SHA_RE = re.compile(r"^[0-9a-fA-F]{7,40}$") PREMAKE_GITHUB_RE = re.compile(r"dependency\.github\s*\(\s*['\"]([^'\"]+)['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)") +YUP_C_FILE_HEADER = """/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/""" @dataclass @@ -102,10 +122,15 @@ def is_relative_to(path: Path, parent: Path) -> bool: def matches_pattern(value: str, pattern: str) -> bool: - if fnmatch.fnmatch(value, pattern): + if "/" not in pattern: + if "/" in value: + return False + return fnmatch.fnmatchcase(value, pattern) + + if fnmatch.fnmatchcase(value, pattern): return True if pattern.startswith("**/"): - return fnmatch.fnmatch(value, pattern[3:]) + return fnmatch.fnmatchcase(value, pattern[3:]) return False @@ -125,6 +150,36 @@ def write_text_if_changed(path: Path, text: str) -> bool: return True +def generated_file_text(entry: dict[str, Any]) -> str: + parts: list[str] = [] + + file_header = entry.get("file_header") + if file_header == "yup_c": + parts.append(YUP_C_FILE_HEADER) + elif file_header: + raise SystemExit(f"Unknown generated file header '{file_header}' in {entry['path']}") + + if "content" in entry: + parts.append(str(entry["content"]).rstrip()) + elif "lines" in entry: + parts.append("\n".join(entry["lines"]).rstrip()) + else: + raise SystemExit(f"Generated file entry is missing content or lines: {entry['path']}") + + return "\n\n".join(part for part in parts if part) + "\n" + + +def process_generated_files(manifest: dict[str, Any]) -> int: + changed = 0 + for entry in manifest.get("generated_files", []): + path = (REPO_ROOT / entry["path"]).resolve() + if not is_relative_to(path, REPO_ROOT): + raise SystemExit(f"Generated file path escapes repository root: {path}") + if write_text_if_changed(path, generated_file_text(entry)): + changed += 1 + return changed + + def parse_dep_override(value: str) -> tuple[str, str]: if "=" not in value: raise argparse.ArgumentTypeError("--dep must be formatted as name=ref") @@ -335,6 +390,38 @@ def replace_module_version(header_path: Path, version: str) -> bool: return write_text_if_changed(header_path, new_text) +def patch_text(value: str | list[str]) -> str: + if isinstance(value, list): + return "\n".join(value) + return value + + +def apply_dependency_patches(destination_root: Path, dep: dict[str, Any]) -> list[str]: + notes: list[str] = [] + for patch in dep.get("patches", []): + path = (destination_root / patch["path"]).resolve() + if not is_relative_to(path, destination_root): + raise SystemExit(f"Patch path escapes dependency root: {path}") + if not path.exists(): + raise SystemExit(f"Missing patch target: {path}") + + text = read_text(path) + already_contains = patch.get("already_contains") + if already_contains and already_contains in text: + continue + + replacement = patch["replace"] + old = patch_text(replacement["from"]) + new = patch_text(replacement["to"]) + if old not in text: + raise SystemExit(f"Could not apply patch '{patch.get('note', patch['path'])}' to {path}") + + if write_text_if_changed(path, text.replace(old, new, 1)): + notes.append(patch.get("note", f"patched {patch['path']}")) + + return notes + + def generate_include_lines(block: dict[str, Any]) -> list[str]: if "entries" in block: return list(block["entries"]) @@ -342,6 +429,7 @@ def generate_include_lines(block: dict[str, Any]) -> list[str]: root = REPO_ROOT / block["root"] include_globs = block.get("include_globs", []) exclude_globs = block.get("exclude_globs", []) + include_overrides = block.get("include_overrides", {}) prefix = block.get("prefix", "") paths: list[str] = [] @@ -354,7 +442,14 @@ def generate_include_lines(block: dict[str, Any]) -> list[str]: include_path = f"{prefix}/{rel}" if prefix else rel paths.append(include_path) - return [f'#include "{path}"' for path in sorted(paths)] + lines: list[str] = [] + for path in sorted(paths): + override = include_overrides.get(path) + if override: + lines.extend(override) + else: + lines.append(f'#include "{path}"') + return lines def find_generated_range(text: str, start_marker: str, end_marker: str) -> tuple[int, int] | None: @@ -397,17 +492,23 @@ def order_include_lines(generated_lines: list[str], current_text: str) -> list[s if not current_text.strip(): return generated_lines - by_text = {line: line for line in generated_lines} + remaining: dict[str, int] = {} + for line in generated_lines: + remaining[line] = remaining.get(line, 0) + 1 + ordered: list[str] = [] - seen: set[str] = set() for line in current_text.splitlines(): stripped = line.strip() - if stripped in by_text and stripped not in seen: + if remaining.get(stripped, 0) > 0: ordered.append(stripped) - seen.add(stripped) + remaining[stripped] -= 1 + + for line in generated_lines: + if remaining.get(line, 0) > 0: + ordered.append(line) + remaining[line] -= 1 - ordered.extend(line for line in generated_lines if line not in seen) return ordered @@ -428,6 +529,7 @@ def regenerate_include_block(block: dict[str, Any]) -> bool: leading_newline = "\n" include_lines = order_include_lines(generate_include_lines(block), current_include_text) + replacement = leading_newline + "\n".join([start_marker, *include_lines, end_marker, ""]) new_text = text[:start] + replacement + text[end:] @@ -660,6 +762,8 @@ def update_dependencies( for copy_rule in dep.get("copies", []): result.copy_stats.append(copy_tree(checkout_dir, destination_root, copy_rule, global_excludes)) + result.notes.extend(apply_dependency_patches(destination_root, dep)) + if dep.get("module_header") and dep.get("module_version_from_ref"): changed = replace_module_version(REPO_ROOT / dep["module_header"], version) if changed: @@ -673,6 +777,18 @@ def update_dependencies( results.append(result) + generated_file_changes = process_generated_files(manifest) + if generated_file_changes: + results.append( + DependencyResult( + name="generated-files", + ref="generated", + version="", + checkout="", + notes=[f"regenerated {generated_file_changes} manifest generated files"], + ) + ) + include_changes = process_include_blocks(manifest) if include_changes: results.append( diff --git a/tools/rive_update_manifest.json b/tools/rive_update_manifest.json index b7ab17cd2..507c3f934 100644 --- a/tools/rive_update_manifest.json +++ b/tools/rive_update_manifest.json @@ -217,6 +217,77 @@ } ] }, + { + "name": "luau", + "repo": "https://github.com/luigi-rosso/luau.git", + "rive_dependency_premake": { + "file": "scripting/premake5.lua", + "project": "luigi-rosso/luau" + }, + "destination": "thirdparty/luau", + "license": "MIT", + "module_header": "thirdparty/luau/luau.h", + "module_version_from_ref": true, + "copies": [ + { + "from": "Common/include", + "to": "upstream/Common/include", + "include_globs": [ + "**/*.h", + "**/*.hpp" + ] + }, + { + "from": "Common/src", + "to": "upstream/Common/src", + "include_globs": [ + "**/*.cpp", + "**/*.h", + "**/*.hpp" + ] + }, + { + "from": "VM/include", + "to": "upstream/VM/include", + "include_globs": [ + "**/*.h", + "**/*.hpp" + ] + }, + { + "from": "VM/src", + "to": "upstream/VM/src", + "include_globs": [ + "**/*.cpp", + "**/*.h", + "**/*.hpp" + ] + } + ] + }, + { + "name": "libhydrogen", + "repo": "https://github.com/luigi-rosso/libhydrogen.git", + "rive_dependency_premake": { + "file": "scripting/premake5.lua", + "project": "luigi-rosso/libhydrogen" + }, + "destination": "thirdparty/libhydrogen", + "license": "ISC", + "module_header": "thirdparty/libhydrogen/libhydrogen.h", + "module_version_from_ref": true, + "copies": [ + { + "from": ".", + "to": "upstream", + "include_globs": [ + "libhydrogen.c", + "libhydrogen.h", + "impl/**" + ] + } + ] + }, { "name": "harfbuzz", "repo": "https://github.com/rive-app/harfbuzz.git", @@ -238,9 +309,13 @@ "**/*.rl" ], "exclude_globs": [ + "harfbuzz-subset.cc", "*-test*", + "test.cc", "test-*", - "main.cc" + "main.cc", + "graph/test-*.cc", + "wasm/sample/**" ] } ] @@ -293,6 +368,39 @@ "tests/**" ] } + ], + "patches": [ + { + "path": "upstream/yoga/YGMacros.h", + "note": "patched YG_DEPRECATED override guard", + "already_contains": "#if !defined(YG_DEPRECATED)", + "replace": { + "from": [ + "#if defined(__cplusplus)", + "#define YG_DEPRECATED(message) [[deprecated(message)]]", + "#elif defined(_MSC_VER)", + "#define YG_DEPRECATED(message) __declspec(deprecated(message))", + "#else", + "#define YG_DEPRECATED(message) __attribute__((deprecated(message)))", + "#endif", + "", + "#ifdef _WINDLL" + ], + "to": [ + "#if !defined(YG_DEPRECATED)", + "#if defined(__cplusplus)", + "#define YG_DEPRECATED(message) [[deprecated(message)]]", + "#elif defined(_MSC_VER)", + "#define YG_DEPRECATED(message) __declspec(deprecated(message))", + "#else", + "#define YG_DEPRECATED(message) __attribute__((deprecated(message)))", + "#endif", + "#endif", + "", + "#ifdef _WINDLL" + ] + } + } ] }, { @@ -320,6 +428,9 @@ "exclude_globs": [ "pngtest.c", "arm/filter_neon.S" + ], + "preserve_globs": [ + "pnglibconf.h" ] } ] @@ -370,6 +481,24 @@ ] } ], + "generated_files": [ + { + "path": "thirdparty/libwebp/upstream/src/webp/config.h", + "file_header": "yup_c", + "lines": [ + "#ifndef WEBP_CONFIG_H_", + "#define WEBP_CONFIG_H_", + "", + "/*", + " libwebp expects this generated header when HAVE_CONFIG_H is defined. The YUP", + " unity wrapper defines the actual feature macros before including upstream", + " sources, so this file only provides the include target expected by upstream.", + "*/", + "", + "#endif /* WEBP_CONFIG_H_ */" + ] + } + ], "include_blocks": [ { "path": "thirdparty/rive/rive.cpp", @@ -386,7 +515,118 @@ ], "exclude_globs": [ "**/*_test.*" - ] + ], + "include_overrides": { + "source/animation/nested_bool.cpp": [ + "#define StateMachineInstance YUPRiveNestedBoolStateMachineInstance", + "#include \"source/animation/nested_bool.cpp\"", + "#undef StateMachineInstance" + ], + "source/animation/nested_number.cpp": [ + "#define StateMachineInstance YUPRiveNestedNumberStateMachineInstance", + "#include \"source/animation/nested_number.cpp\"", + "#undef StateMachineInstance" + ], + "source/animation/nested_trigger.cpp": [ + "#define StateMachineInstance YUPRiveNestedTriggerStateMachineInstance", + "#include \"source/animation/nested_trigger.cpp\"", + "#undef StateMachineInstance" + ], + "source/constraints/constraint.cpp": [ + "#define identity yup_rive_constraint_identity", + "#include \"source/constraints/constraint.cpp\"", + "#undef identity" + ], + "source/core/binary_data_reader.cpp": [ + "#define is_big_endian yup_rive_binary_data_reader_is_big_endian", + "#define decode_uint_leb yup_rive_binary_data_reader_decode_uint_leb", + "#define decode_uint_leb32 yup_rive_binary_data_reader_decode_uint_leb32", + "#define decode_string yup_rive_binary_data_reader_decode_string", + "#define decode_double yup_rive_binary_data_reader_decode_double", + "#define decode_float yup_rive_binary_data_reader_decode_float", + "#define decode_uint_8 yup_rive_binary_data_reader_decode_uint_8", + "#define decode_uint_16 yup_rive_binary_data_reader_decode_uint_16", + "#define decode_uint_32 yup_rive_binary_data_reader_decode_uint_32", + "#include \"source/core/binary_data_reader.cpp\"", + "#undef is_big_endian", + "#undef decode_uint_leb", + "#undef decode_uint_leb32", + "#undef decode_string", + "#undef decode_double", + "#undef decode_float", + "#undef decode_uint_8", + "#undef decode_uint_16", + "#undef decode_uint_32" + ], + "source/core/binary_reader.cpp": [ + "#define is_big_endian yup_rive_binary_reader_is_big_endian", + "#define decode_uint_leb yup_rive_binary_reader_decode_uint_leb", + "#define decode_uint_leb32 yup_rive_binary_reader_decode_uint_leb32", + "#define decode_string yup_rive_binary_reader_decode_string", + "#define decode_double yup_rive_binary_reader_decode_double", + "#define decode_float yup_rive_binary_reader_decode_float", + "#define decode_uint_8 yup_rive_binary_reader_decode_uint_8", + "#define decode_uint_16 yup_rive_binary_reader_decode_uint_16", + "#define decode_uint_32 yup_rive_binary_reader_decode_uint_32", + "#include \"source/core/binary_reader.cpp\"", + "#undef is_big_endian", + "#undef decode_uint_leb", + "#undef decode_uint_leb32", + "#undef decode_string", + "#undef decode_double", + "#undef decode_float", + "#undef decode_uint_8", + "#undef decode_uint_16", + "#undef decode_uint_32" + ], + "source/core/binary_writer.cpp": [ + "#define is_big_endian yup_rive_binary_writer_is_big_endian", + "#define decode_uint_leb yup_rive_binary_writer_decode_uint_leb", + "#define decode_uint_leb32 yup_rive_binary_writer_decode_uint_leb32", + "#define decode_string yup_rive_binary_writer_decode_string", + "#define decode_double yup_rive_binary_writer_decode_double", + "#define decode_float yup_rive_binary_writer_decode_float", + "#define decode_uint_8 yup_rive_binary_writer_decode_uint_8", + "#define decode_uint_16 yup_rive_binary_writer_decode_uint_16", + "#define decode_uint_32 yup_rive_binary_writer_decode_uint_32", + "#include \"source/core/binary_writer.cpp\"", + "#undef is_big_endian", + "#undef decode_uint_leb", + "#undef decode_uint_leb32", + "#undef decode_string", + "#undef decode_double", + "#undef decode_float", + "#undef decode_uint_8", + "#undef decode_uint_16", + "#undef decode_uint_32" + ], + "source/lua/lua_data_context.cpp": [ + "#define data_value_namecall yup_rive_lua_data_context_namecall", + "#include \"source/lua/lua_data_context.cpp\"", + "#undef data_value_namecall" + ], + "source/lua/lua_data_value.cpp": [ + "#define data_value_namecall yup_rive_lua_data_value_namecall", + "#include \"source/lua/lua_data_value.cpp\"", + "#undef data_value_namecall" + ], + "source/math/hit_test.cpp": [ + "#include \"rive/math/hit_test.hpp\"", + "#include \"rive/math/mat2d.hpp\"", + "#define graphics_roundf yup_rive_hit_test_graphics_roundf", + "#define graphics_round yup_rive_hit_test_graphics_round", + "#define lerp yup_rive_hit_test_lerp", + "#include \"source/math/hit_test.cpp\"", + "#undef graphics_roundf", + "#undef graphics_round", + "#undef lerp" + ], + "source/shapes/clipping_shape.cpp": [ + "#define identity yup_rive_clipping_shape_identity", + "#include \"source/shapes/clipping_shape.cpp\"", + "#undef identity" + ] + } }, { "path": "thirdparty/rive_renderer/rive_renderer.cpp", @@ -423,19 +663,9 @@ }, { "path": "thirdparty/harfbuzz/harfbuzz.cpp", - "start_marker": "// BEGIN YUP GENERATED HARFBUZZ INCLUDES", - "end_marker": "// END YUP GENERATED HARFBUZZ INCLUDES", - "insert_after": "#include \"harfbuzz.h\"", - "insert_before": "#if __clang__", - "root": "thirdparty/harfbuzz/upstream", - "prefix": "upstream", - "include_globs": [ - "**/*.cc" - ], - "exclude_globs": [ - "main.cc", - "*-test*", - "test-*" + "validate_existing_includes": true, + "search_roots": [ + "thirdparty/harfbuzz" ] }, { @@ -466,18 +696,7 @@ }, { "path": "thirdparty/libpng/libpng.c", - "start_marker": "// BEGIN YUP GENERATED LIBPNG INCLUDES", - "end_marker": "// END YUP GENERATED LIBPNG INCLUDES", - "insert_after": "#include \"libpng.h\"", - "insert_before": "#if defined(__arm__)", - "root": "thirdparty/libpng/upstream", - "prefix": "upstream", - "include_globs": [ - "*.c" - ], - "exclude_globs": [ - "pngtest.c" - ] + "validate_existing_includes": true }, { "path": "thirdparty/libwebp/libwebp.c", @@ -487,6 +706,25 @@ "thirdparty/libwebp/upstream" ] }, + { + "path": "thirdparty/luau/luau.cpp", + "validate_existing_includes": true + }, + { + "path": "thirdparty/luau/luau_split.cpp", + "start_marker": "// BEGIN YUP GENERATED LUAU COMMON INCLUDES", + "end_marker": "// END YUP GENERATED LUAU COMMON INCLUDES", + "insert_after": "#include \"luau.h\"", + "root": "thirdparty/luau/upstream/Common/src", + "prefix": "upstream/Common/src", + "include_globs": [ + "**/*.cpp" + ] + }, + { + "path": "thirdparty/libhydrogen/libhydrogen.c", + "validate_existing_includes": true + }, { "path": "thirdparty/zlib/zlib.c", "validate_existing_includes": true From 74f07d71640065acbd0c43299422a1f8d2c97f51 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 11 May 2026 08:10:42 +0200 Subject: [PATCH 3/5] Fix glad --- .gitignore | 2 + thirdparty/glad/glad.c | 3 +- thirdparty/glad/glad.h | 8 +- thirdparty/glad/include/EGL/eglplatform.h | 175 ++ .../glad/include/{ => KHR}/khrplatform.h | 0 thirdparty/glad/include/glad.h | 2117 -------------- thirdparty/glad/include/glad/egl.h | 550 ++++ thirdparty/glad/include/glad/gles2.h | 2169 +++++++++++++++ thirdparty/glad/include/glad_custom.h | 28 +- thirdparty/glad/source/egl.c | 397 +++ thirdparty/glad/source/glad.c | 918 ------- thirdparty/glad/source/glad_custom.c | 12 +- thirdparty/glad/source/gles2.c | 1089 ++++++++ .../generated/shaders/d3d/color_ramp.frag.h | 120 + .../generated/shaders/d3d/color_ramp.vert.h | 523 ++++ .../generated/shaders/d3d/render_atlas.vert.h | 2434 +++++++++++++++++ .../shaders/d3d/render_atlas_fill.frag.h | 371 +++ .../shaders/d3d/render_atlas_stroke.frag.h | 195 ++ .../source/generated/shaders/d3d/root.sig.h | 123 + .../generated/shaders/d3d/tessellate.frag.h | 1418 ++++++++++ .../generated/shaders/d3d/tessellate.vert.h | 2400 ++++++++++++++++ thirdparty/rive_vendor_versions.json | 6 + tools/rive_update.py | 47 +- tools/rive_update_manifest.json | 67 +- 24 files changed, 12106 insertions(+), 3066 deletions(-) create mode 100644 thirdparty/glad/include/EGL/eglplatform.h rename thirdparty/glad/include/{ => KHR}/khrplatform.h (100%) delete mode 100644 thirdparty/glad/include/glad.h create mode 100644 thirdparty/glad/include/glad/egl.h create mode 100644 thirdparty/glad/include/glad/gles2.h create mode 100644 thirdparty/glad/source/egl.c delete mode 100644 thirdparty/glad/source/glad.c create mode 100644 thirdparty/glad/source/gles2.c create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h create mode 100644 thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h diff --git a/.gitignore b/.gitignore index 064ddd3d5..7b40ce3bd 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ *.exe *.out *.app +*.pyc # Cruft .DS_Store @@ -40,6 +41,7 @@ cmake-build* out/* # Ides/Agents +__pycache__/ .gitnexus/ .vscode/ .idea/ diff --git a/thirdparty/glad/glad.c b/thirdparty/glad/glad.c index 20d73c5c1..fcd6e8e59 100644 --- a/thirdparty/glad/glad.c +++ b/thirdparty/glad/glad.c @@ -21,5 +21,6 @@ #include "glad.h" -#include "source/glad.c" +#include "source/egl.c" +#include "source/gles2.c" #include "source/glad_custom.c" diff --git a/thirdparty/glad/glad.h b/thirdparty/glad/glad.h index 56feb3320..0aa25395b 100644 --- a/thirdparty/glad/glad.h +++ b/thirdparty/glad/glad.h @@ -26,7 +26,7 @@ ID: glad vendor: glad - version: 1.0.0 + version: 0.1.62 name: Vulkan/GL/GLES/EGL/GLX/WGL Loader-Generator description: Vulkan/GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specifications for multiple languages.. website: https://glad.dav1d.de/ @@ -41,6 +41,8 @@ #pragma once -#include "include/glad.h" +#include "include/EGL/eglplatform.h" +#include "include/KHR/khrplatform.h" +#include "include/glad/egl.h" +#include "include/glad/gles2.h" #include "include/glad_custom.h" -#include "include/khrplatform.h" diff --git a/thirdparty/glad/include/EGL/eglplatform.h b/thirdparty/glad/include/EGL/eglplatform.h new file mode 100644 index 000000000..6786afd90 --- /dev/null +++ b/thirdparty/glad/include/EGL/eglplatform.h @@ -0,0 +1,175 @@ +#ifndef __eglplatform_h_ +#define __eglplatform_h_ + +/* +** 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 /* __eglplatform_h */ diff --git a/thirdparty/glad/include/khrplatform.h b/thirdparty/glad/include/KHR/khrplatform.h similarity index 100% rename from thirdparty/glad/include/khrplatform.h rename to thirdparty/glad/include/KHR/khrplatform.h diff --git a/thirdparty/glad/include/glad.h b/thirdparty/glad/include/glad.h deleted file mode 100644 index 4c05561bc..000000000 --- a/thirdparty/glad/include/glad.h +++ /dev/null @@ -1,2117 +0,0 @@ -/* - - OpenGL ES loader generated by glad 0.1.36 on Wed Apr 3 22:10:47 2024. - - Language/Generator: C/C++ - Specification: gl - APIs: gles2=3.1 - Profile: compatibility - Extensions: - GL_EXT_base_instance, - GL_EXT_clip_cull_distance, - GL_EXT_multisampled_render_to_texture, - GL_KHR_blend_equation_advanced, - GL_KHR_blend_equation_advanced_coherent, - GL_KHR_debug - Loader: True - Local files: True - Omit khrplatform: False - Reproducible: False - - Commandline: - --profile="compatibility" --api="gles2=3.1" --generator="c" --spec="gl" --local-files --extensions="GL_EXT_base_instance,GL_EXT_clip_cull_distance,GL_EXT_multisampled_render_to_texture,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_debug" - Online: - https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gles2%3D3.1&extensions=GL_EXT_base_instance&extensions=GL_EXT_clip_cull_distance&extensions=GL_EXT_multisampled_render_to_texture&extensions=GL_KHR_blend_equation_advanced&extensions=GL_KHR_blend_equation_advanced_coherent&extensions=GL_KHR_debug -*/ - - -#ifndef __glad_h_ -#define __glad_h_ - -#ifdef __gl2_h_ -#error OpenGL ES 2 header already included, remove this include, glad already provides it -#endif -#define __gl2_h_ - -#ifdef __gl3_h_ -#error OpenGL ES 3 header already included, remove this include, glad already provides it -#endif -#define __gl3_h_ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define APIENTRY __stdcall -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif - -#ifndef GLAPIENTRY -#define GLAPIENTRY APIENTRY -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -struct gladGLversionStruct { - int major; - int minor; -}; - -typedef void* (* GLADloadproc)(const char *name); - -#ifndef GLAPI -# if defined(GLAD_GLAPI_EXPORT) -# if defined(_WIN32) || defined(__CYGWIN__) -# if defined(GLAD_GLAPI_EXPORT_BUILD) -# if defined(__GNUC__) -# define GLAPI __attribute__ ((dllexport)) extern -# else -# define GLAPI __declspec(dllexport) extern -# endif -# else -# if defined(__GNUC__) -# define GLAPI __attribute__ ((dllimport)) extern -# else -# define GLAPI __declspec(dllimport) extern -# endif -# endif -# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) -# define GLAPI __attribute__ ((visibility ("default"))) extern -# else -# define GLAPI extern -# endif -# else -# define GLAPI extern -# endif -#endif - -GLAPI struct gladGLversionStruct GLVersion; -GLAPI int gladLoadGLES2Loader(GLADloadproc); - -#include "khrplatform.h" -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; -typedef khronos_intptr_t GLintptr; -typedef khronos_intptr_t GLintptrARB; -typedef khronos_ssize_t GLsizeiptr; -typedef khronos_ssize_t GLsizeiptrARB; -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 (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); -typedef unsigned short GLhalfNV; -typedef GLintptr GLvdpauSurfaceNV; -typedef void (APIENTRY *GLVULKANPROCNV)(void); -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_COLOR_BUFFER_BIT 0x00004000 -#define GL_FALSE 0 -#define GL_TRUE 1 -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -#define GL_FUNC_ADD 0x8006 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_STREAM_DRAW 0x88E0 -#define GL_STATIC_DRAW 0x88E4 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_FRONT_AND_BACK 0x0408 -#define GL_TEXTURE_2D 0x0DE1 -#define GL_CULL_FACE 0x0B44 -#define GL_BLEND 0x0BE2 -#define GL_DITHER 0x0BD0 -#define GL_STENCIL_TEST 0x0B90 -#define GL_DEPTH_TEST 0x0B71 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_OUT_OF_MEMORY 0x0505 -#define GL_CW 0x0900 -#define GL_CCW 0x0901 -#define GL_LINE_WIDTH 0x0B21 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#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_VIEWPORT 0x0BA2 -#define GL_SCISSOR_BOX 0x0C10 -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_FIXED 0x140C -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A -#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_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_SHADER_TYPE 0x8B4F -#define GL_DELETE_STATUS 0x8B80 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_INVERT 0x150A -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 -#define GL_TEXTURE 0x1702 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#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_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_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_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_REPEAT 0x2901 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_COMPILE_STATUS 0x8B81 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGB565 0x8D62 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_NONE 0 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_READ_BUFFER 0x0C02 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_RED 0x1903 -#define GL_RGB8 0x8051 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_COLOR_ATTACHMENT16 0x8CF0 -#define GL_COLOR_ATTACHMENT17 0x8CF1 -#define GL_COLOR_ATTACHMENT18 0x8CF2 -#define GL_COLOR_ATTACHMENT19 0x8CF3 -#define GL_COLOR_ATTACHMENT20 0x8CF4 -#define GL_COLOR_ATTACHMENT21 0x8CF5 -#define GL_COLOR_ATTACHMENT22 0x8CF6 -#define GL_COLOR_ATTACHMENT23 0x8CF7 -#define GL_COLOR_ATTACHMENT24 0x8CF8 -#define GL_COLOR_ATTACHMENT25 0x8CF9 -#define GL_COLOR_ATTACHMENT26 0x8CFA -#define GL_COLOR_ATTACHMENT27 0x8CFB -#define GL_COLOR_ATTACHMENT28 0x8CFC -#define GL_COLOR_ATTACHMENT29 0x8CFD -#define GL_COLOR_ATTACHMENT30 0x8CFE -#define GL_COLOR_ATTACHMENT31 0x8CFF -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_HALF_FLOAT 0x140B -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_RG8 0x822B -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFF -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A -#define GL_SAMPLER_BINDING 0x8919 -#define GL_RGB10_A2UI 0x906F -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_INT_2_10_10_10_REV 0x8D9F -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_PROGRAM_BINARY_FORMATS 0x87FF -#define GL_COMPRESSED_R11_EAC 0x9270 -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#define GL_COMPRESSED_RG11_EAC 0x9272 -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 -#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F -#define GL_MAX_ELEMENT_INDEX 0x8D6B -#define GL_NUM_SAMPLE_COUNTS 0x9380 -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF -#define GL_COMPUTE_SHADER 0x91B9 -#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB -#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC -#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD -#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 -#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 -#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 -#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 -#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 -#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB -#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE -#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF -#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 -#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE -#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF -#define GL_COMPUTE_SHADER_BIT 0x00000020 -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 -#define GL_MAX_UNIFORM_LOCATIONS 0x826E -#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 -#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 -#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 -#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 -#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 -#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 -#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 -#define GL_UNIFORM 0x92E1 -#define GL_UNIFORM_BLOCK 0x92E2 -#define GL_PROGRAM_INPUT 0x92E3 -#define GL_PROGRAM_OUTPUT 0x92E4 -#define GL_BUFFER_VARIABLE 0x92E5 -#define GL_SHADER_STORAGE_BLOCK 0x92E6 -#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 -#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 -#define GL_ACTIVE_RESOURCES 0x92F5 -#define GL_MAX_NAME_LENGTH 0x92F6 -#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 -#define GL_NAME_LENGTH 0x92F9 -#define GL_TYPE 0x92FA -#define GL_ARRAY_SIZE 0x92FB -#define GL_OFFSET 0x92FC -#define GL_BLOCK_INDEX 0x92FD -#define GL_ARRAY_STRIDE 0x92FE -#define GL_MATRIX_STRIDE 0x92FF -#define GL_IS_ROW_MAJOR 0x9300 -#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 -#define GL_BUFFER_BINDING 0x9302 -#define GL_BUFFER_DATA_SIZE 0x9303 -#define GL_NUM_ACTIVE_VARIABLES 0x9304 -#define GL_ACTIVE_VARIABLES 0x9305 -#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 -#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A -#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B -#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C -#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D -#define GL_LOCATION 0x930E -#define GL_VERTEX_SHADER_BIT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#define GL_ALL_SHADER_BITS 0xFFFFFFFF -#define GL_PROGRAM_SEPARABLE 0x8258 -#define GL_ACTIVE_PROGRAM 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING 0x825A -#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 -#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 -#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 -#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC -#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 -#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 -#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 -#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 -#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 -#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC -#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 -#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB -#define GL_MAX_IMAGE_UNITS 0x8F38 -#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA -#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE -#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF -#define GL_IMAGE_BINDING_NAME 0x8F3A -#define GL_IMAGE_BINDING_LEVEL 0x8F3B -#define GL_IMAGE_BINDING_LAYERED 0x8F3C -#define GL_IMAGE_BINDING_LAYER 0x8F3D -#define GL_IMAGE_BINDING_ACCESS 0x8F3E -#define GL_IMAGE_BINDING_FORMAT 0x906E -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 -#define GL_COMMAND_BARRIER_BIT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 -#define GL_ALL_BARRIER_BITS 0xFFFFFFFF -#define GL_IMAGE_2D 0x904D -#define GL_IMAGE_3D 0x904E -#define GL_IMAGE_CUBE 0x9050 -#define GL_IMAGE_2D_ARRAY 0x9053 -#define GL_INT_IMAGE_2D 0x9058 -#define GL_INT_IMAGE_3D 0x9059 -#define GL_INT_IMAGE_CUBE 0x905B -#define GL_INT_IMAGE_2D_ARRAY 0x905E -#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 -#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 -#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 -#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_SHADER_STORAGE_BUFFER 0x90D2 -#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 -#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 -#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 -#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 -#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA -#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB -#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC -#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD -#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE -#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF -#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 -#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 -#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA -#define GL_STENCIL_INDEX 0x1901 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_TEXTURE_WIDTH 0x1000 -#define GL_TEXTURE_HEIGHT 0x1001 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 -#define GL_TEXTURE_RED_SIZE 0x805C -#define GL_TEXTURE_GREEN_SIZE 0x805D -#define GL_TEXTURE_BLUE_SIZE 0x805E -#define GL_TEXTURE_ALPHA_SIZE 0x805F -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_VERTEX_ATTRIB_BINDING 0x82D4 -#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 -#define GL_VERTEX_BINDING_DIVISOR 0x82D6 -#define GL_VERTEX_BINDING_OFFSET 0x82D7 -#define GL_VERTEX_BINDING_STRIDE 0x82D8 -#define GL_VERTEX_BINDING_BUFFER 0x8F4F -#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 -#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA -#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 -#ifndef GL_ES_VERSION_2_0 -#define GL_ES_VERSION_2_0 1 -GLAPI int GLAD_GL_ES_VERSION_2_0; -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture); -GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; -#define glActiveTexture glad_glActiveTexture -typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); -GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; -#define glAttachShader glad_glAttachShader -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar *name); -GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; -#define glBindAttribLocation glad_glBindAttribLocation -typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); -GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; -#define glBindBuffer glad_glBindBuffer -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); -GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; -#define glBindFramebuffer glad_glBindFramebuffer -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); -GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; -#define glBindRenderbuffer glad_glBindRenderbuffer -typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); -GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; -#define glBindTexture glad_glBindTexture -typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; -#define glBlendColor glad_glBlendColor -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode); -GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; -#define glBlendEquation glad_glBlendEquation -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); -GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; -#define glBlendEquationSeparate glad_glBlendEquationSeparate -typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); -GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; -#define glBlendFunc glad_glBlendFunc -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; -#define glBlendFuncSeparate glad_glBlendFuncSeparate -typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage); -GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; -#define glBufferData glad_glBufferData -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; -#define glBufferSubData glad_glBufferSubData -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); -GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; -#define glCheckFramebufferStatus glad_glCheckFramebufferStatus -typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield mask); -GLAPI PFNGLCLEARPROC glad_glClear; -#define glClear glad_glClear -typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; -#define glClearColor glad_glClearColor -typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC)(GLfloat d); -GLAPI PFNGLCLEARDEPTHFPROC glad_glClearDepthf; -#define glClearDepthf glad_glClearDepthf -typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint s); -GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; -#define glClearStencil glad_glClearStencil -typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GLAPI PFNGLCOLORMASKPROC glad_glColorMask; -#define glColorMask glad_glColorMask -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader); -GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; -#define glCompileShader glad_glCompileShader -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; -#define glCompressedTexImage2D glad_glCompressedTexImage2D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; -#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; -#define glCopyTexImage2D glad_glCopyTexImage2D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; -#define glCopyTexSubImage2D glad_glCopyTexSubImage2D -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(void); -GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; -#define glCreateProgram glad_glCreateProgram -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum type); -GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; -#define glCreateShader glad_glCreateShader -typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum mode); -GLAPI PFNGLCULLFACEPROC glad_glCullFace; -#define glCullFace glad_glCullFace -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers); -GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; -#define glDeleteBuffers glad_glDeleteBuffers -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers); -GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; -#define glDeleteFramebuffers glad_glDeleteFramebuffers -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program); -GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; -#define glDeleteProgram glad_glDeleteProgram -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint *renderbuffers); -GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; -#define glDeleteRenderbuffers glad_glDeleteRenderbuffers -typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader); -GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; -#define glDeleteShader glad_glDeleteShader -typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures); -GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; -#define glDeleteTextures glad_glDeleteTextures -typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum func); -GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; -#define glDepthFunc glad_glDepthFunc -typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean flag); -GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; -#define glDepthMask glad_glDepthMask -typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); -GLAPI PFNGLDEPTHRANGEFPROC glad_glDepthRangef; -#define glDepthRangef glad_glDepthRangef -typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); -GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; -#define glDetachShader glad_glDetachShader -typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum cap); -GLAPI PFNGLDISABLEPROC glad_glDisable; -#define glDisable glad_glDisable -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); -GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; -#define glDisableVertexAttribArray glad_glDisableVertexAttribArray -typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); -GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; -#define glDrawArrays glad_glDrawArrays -typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices); -GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; -#define glDrawElements glad_glDrawElements -typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum cap); -GLAPI PFNGLENABLEPROC glad_glEnable; -#define glEnable glad_glEnable -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); -GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; -#define glEnableVertexAttribArray glad_glEnableVertexAttribArray -typedef void (APIENTRYP PFNGLFINISHPROC)(void); -GLAPI PFNGLFINISHPROC glad_glFinish; -#define glFinish glad_glFinish -typedef void (APIENTRYP PFNGLFLUSHPROC)(void); -GLAPI PFNGLFLUSHPROC glad_glFlush; -#define glFlush glad_glFlush -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; -#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; -#define glFramebufferTexture2D glad_glFramebufferTexture2D -typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum mode); -GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; -#define glFrontFace glad_glFrontFace -typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers); -GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; -#define glGenBuffers glad_glGenBuffers -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum target); -GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; -#define glGenerateMipmap glad_glGenerateMipmap -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers); -GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; -#define glGenFramebuffers glad_glGenFramebuffers -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers); -GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; -#define glGenRenderbuffers glad_glGenRenderbuffers -typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures); -GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; -#define glGenTextures glad_glGenTextures -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; -#define glGetActiveAttrib glad_glGetActiveAttrib -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; -#define glGetActiveUniform glad_glGetActiveUniform -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); -GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; -#define glGetAttachedShaders glad_glGetAttachedShaders -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; -#define glGetAttribLocation glad_glGetAttribLocation -typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean *data); -GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; -#define glGetBooleanv glad_glGetBooleanv -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; -#define glGetBufferParameteriv glad_glGetBufferParameteriv -typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(void); -GLAPI PFNGLGETERRORPROC glad_glGetError; -#define glGetError glad_glGetError -typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum pname, GLfloat *data); -GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; -#define glGetFloatv glad_glGetFloatv -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; -#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data); -GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; -#define glGetIntegerv glad_glGetIntegerv -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params); -GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; -#define glGetProgramiv glad_glGetProgramiv -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; -#define glGetProgramInfoLog glad_glGetProgramInfoLog -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; -#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params); -GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; -#define glGetShaderiv glad_glGetShaderiv -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; -#define glGetShaderInfoLog glad_glGetShaderInfoLog -typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -GLAPI PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; -#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; -#define glGetShaderSource glad_glGetShaderSource -typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name); -GLAPI PFNGLGETSTRINGPROC glad_glGetString; -#define glGetString glad_glGetString -typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; -#define glGetTexParameterfv glad_glGetTexParameterfv -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; -#define glGetTexParameteriv glad_glGetTexParameteriv -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat *params); -GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; -#define glGetUniformfv glad_glGetUniformfv -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint *params); -GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; -#define glGetUniformiv glad_glGetUniformiv -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; -#define glGetUniformLocation glad_glGetUniformLocation -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat *params); -GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; -#define glGetVertexAttribfv glad_glGetVertexAttribfv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint *params); -GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; -#define glGetVertexAttribiv glad_glGetVertexAttribiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void **pointer); -GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; -#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -typedef void (APIENTRYP PFNGLHINTPROC)(GLenum target, GLenum mode); -GLAPI PFNGLHINTPROC glad_glHint; -#define glHint glad_glHint -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint buffer); -GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; -#define glIsBuffer glad_glIsBuffer -typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum cap); -GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; -#define glIsEnabled glad_glIsEnabled -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); -GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; -#define glIsFramebuffer glad_glIsFramebuffer -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint program); -GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; -#define glIsProgram glad_glIsProgram -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); -GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; -#define glIsRenderbuffer glad_glIsRenderbuffer -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint shader); -GLAPI PFNGLISSHADERPROC glad_glIsShader; -#define glIsShader glad_glIsShader -typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture); -GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; -#define glIsTexture glad_glIsTexture -typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat width); -GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; -#define glLineWidth glad_glLineWidth -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program); -GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; -#define glLinkProgram glad_glLinkProgram -typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); -GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; -#define glPixelStorei glad_glPixelStorei -typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); -GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; -#define glPolygonOffset glad_glPolygonOffset -typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); -GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; -#define glReadPixels glad_glReadPixels -typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC)(void); -GLAPI PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; -#define glReleaseShaderCompiler glad_glReleaseShaderCompiler -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; -#define glRenderbufferStorage glad_glRenderbufferStorage -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); -GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; -#define glSampleCoverage glad_glSampleCoverage -typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLSCISSORPROC glad_glScissor; -#define glScissor glad_glScissor -typedef void (APIENTRYP PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); -GLAPI PFNGLSHADERBINARYPROC glad_glShaderBinary; -#define glShaderBinary glad_glShaderBinary -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); -GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; -#define glShaderSource glad_glShaderSource -typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); -GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; -#define glStencilFunc glad_glStencilFunc -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); -GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; -#define glStencilFuncSeparate glad_glStencilFuncSeparate -typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint mask); -GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; -#define glStencilMask glad_glStencilMask -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); -GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; -#define glStencilMaskSeparate glad_glStencilMaskSeparate -typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); -GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; -#define glStencilOp glad_glStencilOp -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; -#define glStencilOpSeparate glad_glStencilOpSeparate -typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; -#define glTexImage2D glad_glTexImage2D -typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); -GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; -#define glTexParameterf glad_glTexParameterf -typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat *params); -GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; -#define glTexParameterfv glad_glTexParameterfv -typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; -#define glTexParameteri glad_glTexParameteri -typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint *params); -GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; -#define glTexParameteriv glad_glTexParameteriv -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; -#define glTexSubImage2D glad_glTexSubImage2D -typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); -GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; -#define glUniform1f glad_glUniform1f -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; -#define glUniform1fv glad_glUniform1fv -typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0); -GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; -#define glUniform1i glad_glUniform1i -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; -#define glUniform1iv glad_glUniform1iv -typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); -GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; -#define glUniform2f glad_glUniform2f -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; -#define glUniform2fv glad_glUniform2fv -typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); -GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; -#define glUniform2i glad_glUniform2i -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; -#define glUniform2iv glad_glUniform2iv -typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; -#define glUniform3f glad_glUniform3f -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; -#define glUniform3fv glad_glUniform3fv -typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); -GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; -#define glUniform3i glad_glUniform3i -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; -#define glUniform3iv glad_glUniform3iv -typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; -#define glUniform4f glad_glUniform4f -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; -#define glUniform4fv glad_glUniform4fv -typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; -#define glUniform4i glad_glUniform4i -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; -#define glUniform4iv glad_glUniform4iv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; -#define glUniformMatrix2fv glad_glUniformMatrix2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; -#define glUniformMatrix3fv glad_glUniformMatrix3fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; -#define glUniformMatrix4fv glad_glUniformMatrix4fv -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program); -GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; -#define glUseProgram glad_glUseProgram -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint program); -GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; -#define glValidateProgram glad_glValidateProgram -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); -GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; -#define glVertexAttrib1f glad_glVertexAttrib1f -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; -#define glVertexAttrib1fv glad_glVertexAttrib1fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); -GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; -#define glVertexAttrib2f glad_glVertexAttrib2f -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; -#define glVertexAttrib2fv glad_glVertexAttrib2fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; -#define glVertexAttrib3f glad_glVertexAttrib3f -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; -#define glVertexAttrib3fv glad_glVertexAttrib3fv -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; -#define glVertexAttrib4f glad_glVertexAttrib4f -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat *v); -GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; -#define glVertexAttrib4fv glad_glVertexAttrib4fv -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); -GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; -#define glVertexAttribPointer glad_glVertexAttribPointer -typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLVIEWPORTPROC glad_glViewport; -#define glViewport glad_glViewport -#endif -#ifndef GL_ES_VERSION_3_0 -#define GL_ES_VERSION_3_0 1 -GLAPI int GLAD_GL_ES_VERSION_3_0; -typedef void (APIENTRYP PFNGLREADBUFFERPROC)(GLenum src); -GLAPI PFNGLREADBUFFERPROC glad_glReadBuffer; -#define glReadBuffer glad_glReadBuffer -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); -GLAPI PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; -#define glDrawRangeElements glad_glDrawRangeElements -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXIMAGE3DPROC glad_glTexImage3D; -#define glTexImage3D glad_glTexImage3D -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); -GLAPI PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; -#define glTexSubImage3D glad_glTexSubImage3D -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; -#define glCopyTexSubImage3D glad_glCopyTexSubImage3D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; -#define glCompressedTexImage3D glad_glCompressedTexImage3D -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); -GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; -#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -typedef void (APIENTRYP PFNGLGENQUERIESPROC)(GLsizei n, GLuint *ids); -GLAPI PFNGLGENQUERIESPROC glad_glGenQueries; -#define glGenQueries glad_glGenQueries -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint *ids); -GLAPI PFNGLDELETEQUERIESPROC glad_glDeleteQueries; -#define glDeleteQueries glad_glDeleteQueries -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC)(GLuint id); -GLAPI PFNGLISQUERYPROC glad_glIsQuery; -#define glIsQuery glad_glIsQuery -typedef void (APIENTRYP PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); -GLAPI PFNGLBEGINQUERYPROC glad_glBeginQuery; -#define glBeginQuery glad_glBeginQuery -typedef void (APIENTRYP PFNGLENDQUERYPROC)(GLenum target); -GLAPI PFNGLENDQUERYPROC glad_glEndQuery; -#define glEndQuery glad_glEndQuery -typedef void (APIENTRYP PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETQUERYIVPROC glad_glGetQueryiv; -#define glGetQueryiv glad_glGetQueryiv -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint *params); -GLAPI PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; -#define glGetQueryObjectuiv glad_glGetQueryObjectuiv -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC)(GLenum target); -GLAPI PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; -#define glUnmapBuffer glad_glUnmapBuffer -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void **params); -GLAPI PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; -#define glGetBufferPointerv glad_glGetBufferPointerv -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum *bufs); -GLAPI PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; -#define glDrawBuffers glad_glDrawBuffers -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; -#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; -#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; -#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; -#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; -#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; -#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; -#define glBlitFramebuffer glad_glBlitFramebuffer -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; -#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; -#define glFramebufferTextureLayer glad_glFramebufferTextureLayer -typedef void * (APIENTRYP PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; -#define glMapBufferRange glad_glMapBufferRange -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); -GLAPI PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; -#define glFlushMappedBufferRange glad_glFlushMappedBufferRange -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC)(GLuint array); -GLAPI PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; -#define glBindVertexArray glad_glBindVertexArray -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint *arrays); -GLAPI PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; -#define glDeleteVertexArrays glad_glDeleteVertexArrays -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays); -GLAPI PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; -#define glGenVertexArrays glad_glGenVertexArrays -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint array); -GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; -#define glIsVertexArray glad_glIsVertexArray -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint *data); -GLAPI PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; -#define glGetIntegeri_v glad_glGetIntegeri_v -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); -GLAPI PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; -#define glBeginTransformFeedback glad_glBeginTransformFeedback -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC)(void); -GLAPI PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; -#define glEndTransformFeedback glad_glEndTransformFeedback -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; -#define glBindBufferRange glad_glBindBufferRange -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); -GLAPI PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; -#define glBindBufferBase glad_glBindBufferBase -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); -GLAPI PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; -#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; -#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; -#define glVertexAttribIPointer glad_glVertexAttribIPointer -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint *params); -GLAPI PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; -#define glGetVertexAttribIiv glad_glGetVertexAttribIiv -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint *params); -GLAPI PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; -#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; -#define glVertexAttribI4i glad_glVertexAttribI4i -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; -#define glVertexAttribI4ui glad_glVertexAttribI4ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint *v); -GLAPI PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; -#define glVertexAttribI4iv glad_glVertexAttribI4iv -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint *v); -GLAPI PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; -#define glVertexAttribI4uiv glad_glVertexAttribI4uiv -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint *params); -GLAPI PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; -#define glGetUniformuiv glad_glGetUniformuiv -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; -#define glGetFragDataLocation glad_glGetFragDataLocation -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); -GLAPI PFNGLUNIFORM1UIPROC glad_glUniform1ui; -#define glUniform1ui glad_glUniform1ui -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); -GLAPI PFNGLUNIFORM2UIPROC glad_glUniform2ui; -#define glUniform2ui glad_glUniform2ui -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI PFNGLUNIFORM3UIPROC glad_glUniform3ui; -#define glUniform3ui glad_glUniform3ui -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI PFNGLUNIFORM4UIPROC glad_glUniform4ui; -#define glUniform4ui glad_glUniform4ui -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; -#define glUniform1uiv glad_glUniform1uiv -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; -#define glUniform2uiv glad_glUniform2uiv -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; -#define glUniform3uiv glad_glUniform3uiv -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; -#define glUniform4uiv glad_glUniform4uiv -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; -#define glClearBufferiv glad_glClearBufferiv -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; -#define glClearBufferuiv glad_glClearBufferuiv -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; -#define glClearBufferfv glad_glClearBufferfv -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GLAPI PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; -#define glClearBufferfi glad_glClearBufferfi -typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); -GLAPI PFNGLGETSTRINGIPROC glad_glGetStringi; -#define glGetStringi glad_glGetStringi -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -#define glGetActiveUniformsiv glad_glGetActiveUniformsiv -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar *uniformBlockName); -GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -#define glGetUniformBlockIndex glad_glGetUniformBlockIndex -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -#define glDrawElementsInstanced glad_glDrawElementsInstanced -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); -GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync); -GLAPI PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync); -GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -#define glClientWaitSync glad_glClientWaitSync -typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 *data); -GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -#define glGetInteger64v glad_glGetInteger64v -typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); -GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; -#define glGetSynciv glad_glGetSynciv -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 *data); -GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -#define glGetInteger64i_v glad_glGetInteger64i_v -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 *params); -GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -#define glGetBufferParameteri64v glad_glGetBufferParameteri64v -typedef void (APIENTRYP PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint *samplers); -GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers; -#define glGenSamplers glad_glGenSamplers -typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint *samplers); -GLAPI PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -#define glDeleteSamplers glad_glDeleteSamplers -typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC)(GLuint sampler); -GLAPI PFNGLISSAMPLERPROC glad_glIsSampler; -#define glIsSampler glad_glIsSampler -typedef void (APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); -GLAPI PFNGLBINDSAMPLERPROC glad_glBindSampler; -#define glBindSampler glad_glBindSampler -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); -GLAPI PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; -#define glSamplerParameteri glad_glSamplerParameteri -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint *param); -GLAPI PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; -#define glSamplerParameteriv glad_glSamplerParameteriv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); -GLAPI PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; -#define glSamplerParameterf glad_glSamplerParameterf -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat *param); -GLAPI PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; -#define glSamplerParameterfv glad_glSamplerParameterfv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; -#define glGetSamplerParameteriv glad_glGetSamplerParameteriv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat *params); -GLAPI PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; -#define glGetSamplerParameterfv glad_glGetSamplerParameterfv -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); -GLAPI PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -#define glVertexAttribDivisor glad_glVertexAttribDivisor -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); -GLAPI PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; -#define glBindTransformFeedback glad_glBindTransformFeedback -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint *ids); -GLAPI PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; -#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint *ids); -GLAPI PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; -#define glGenTransformFeedbacks glad_glGenTransformFeedbacks -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); -GLAPI PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; -#define glIsTransformFeedback glad_glIsTransformFeedback -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); -GLAPI PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; -#define glPauseTransformFeedback glad_glPauseTransformFeedback -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); -GLAPI PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; -#define glResumeTransformFeedback glad_glResumeTransformFeedback -typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); -GLAPI PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; -#define glGetProgramBinary glad_glGetProgramBinary -typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); -GLAPI PFNGLPROGRAMBINARYPROC glad_glProgramBinary; -#define glProgramBinary glad_glProgramBinary -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); -GLAPI PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; -#define glProgramParameteri glad_glProgramParameteri -typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum *attachments); -GLAPI PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; -#define glInvalidateFramebuffer glad_glInvalidateFramebuffer -typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; -#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer -typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; -#define glTexStorage2D glad_glTexStorage2D -typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GLAPI PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; -#define glTexStorage3D glad_glTexStorage3D -typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); -GLAPI PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; -#define glGetInternalformativ glad_glGetInternalformativ -#endif -#ifndef GL_ES_VERSION_3_1 -#define GL_ES_VERSION_3_1 1 -GLAPI int GLAD_GL_ES_VERSION_3_1; -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -GLAPI PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; -#define glDispatchCompute glad_glDispatchCompute -typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect); -GLAPI PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; -#define glDispatchComputeIndirect glad_glDispatchComputeIndirect -typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void *indirect); -GLAPI PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; -#define glDrawArraysIndirect glad_glDrawArraysIndirect -typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void *indirect); -GLAPI PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; -#define glDrawElementsIndirect glad_glDrawElementsIndirect -typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -GLAPI PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; -#define glFramebufferParameteri glad_glFramebufferParameteri -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); -GLAPI PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; -#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv -typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); -GLAPI PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; -#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv -typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar *name); -GLAPI PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; -#define glGetProgramResourceIndex glad_glGetProgramResourceIndex -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -GLAPI PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; -#define glGetProgramResourceName glad_glGetProgramResourceName -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); -GLAPI PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; -#define glGetProgramResourceiv glad_glGetProgramResourceiv -typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar *name); -GLAPI PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; -#define glGetProgramResourceLocation glad_glGetProgramResourceLocation -typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program); -GLAPI PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; -#define glUseProgramStages glad_glUseProgramStages -typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program); -GLAPI PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; -#define glActiveShaderProgram glad_glActiveShaderProgram -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const*strings); -GLAPI PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; -#define glCreateShaderProgramv glad_glCreateShaderProgramv -typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline); -GLAPI PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; -#define glBindProgramPipeline glad_glBindProgramPipeline -typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint *pipelines); -GLAPI PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; -#define glDeleteProgramPipelines glad_glDeleteProgramPipelines -typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint *pipelines); -GLAPI PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; -#define glGenProgramPipelines glad_glGenProgramPipelines -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline); -GLAPI PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; -#define glIsProgramPipeline glad_glIsProgramPipeline -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint *params); -GLAPI PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; -#define glGetProgramPipelineiv glad_glGetProgramPipelineiv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0); -GLAPI PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; -#define glProgramUniform1i glad_glProgramUniform1i -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1); -GLAPI PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; -#define glProgramUniform2i glad_glProgramUniform2i -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; -#define glProgramUniform3i glad_glProgramUniform3i -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; -#define glProgramUniform4i glad_glProgramUniform4i -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0); -GLAPI PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; -#define glProgramUniform1ui glad_glProgramUniform1ui -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; -#define glProgramUniform2ui glad_glProgramUniform2ui -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; -#define glProgramUniform3ui glad_glProgramUniform3ui -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; -#define glProgramUniform4ui glad_glProgramUniform4ui -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0); -GLAPI PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; -#define glProgramUniform1f glad_glProgramUniform1f -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; -#define glProgramUniform2f glad_glProgramUniform2f -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; -#define glProgramUniform3f glad_glProgramUniform3f -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; -#define glProgramUniform4f glad_glProgramUniform4f -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; -#define glProgramUniform1iv glad_glProgramUniform1iv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; -#define glProgramUniform2iv glad_glProgramUniform2iv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; -#define glProgramUniform3iv glad_glProgramUniform3iv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; -#define glProgramUniform4iv glad_glProgramUniform4iv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; -#define glProgramUniform1uiv glad_glProgramUniform1uiv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; -#define glProgramUniform2uiv glad_glProgramUniform2uiv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; -#define glProgramUniform3uiv glad_glProgramUniform3uiv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; -#define glProgramUniform4uiv glad_glProgramUniform4uiv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; -#define glProgramUniform1fv glad_glProgramUniform1fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; -#define glProgramUniform2fv glad_glProgramUniform2fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; -#define glProgramUniform3fv glad_glProgramUniform3fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; -#define glProgramUniform4fv glad_glProgramUniform4fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; -#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; -#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; -#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; -#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; -#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; -#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; -#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; -#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; -#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline); -GLAPI PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; -#define glValidateProgramPipeline glad_glValidateProgramPipeline -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; -#define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog -typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -GLAPI PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; -#define glBindImageTexture glad_glBindImageTexture -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean *data); -GLAPI PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; -#define glGetBooleani_v glad_glGetBooleani_v -typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC)(GLbitfield barriers); -GLAPI PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; -#define glMemoryBarrier glad_glMemoryBarrier -typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers); -GLAPI PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; -#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion -typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; -#define glTexStorage2DMultisample glad_glTexStorage2DMultisample -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat *val); -GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); -GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; -#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv -typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; -#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv -typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -GLAPI PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; -#define glBindVertexBuffer glad_glBindVertexBuffer -typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -GLAPI PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; -#define glVertexAttribFormat glad_glVertexAttribFormat -typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -GLAPI PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; -#define glVertexAttribIFormat glad_glVertexAttribIFormat -typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex); -GLAPI PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; -#define glVertexAttribBinding glad_glVertexAttribBinding -typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor); -GLAPI PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; -#define glVertexBindingDivisor glad_glVertexBindingDivisor -#endif -#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 -#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 -#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA -#define GL_CLIP_DISTANCE0_EXT 0x3000 -#define GL_CLIP_DISTANCE1_EXT 0x3001 -#define GL_CLIP_DISTANCE2_EXT 0x3002 -#define GL_CLIP_DISTANCE3_EXT 0x3003 -#define GL_CLIP_DISTANCE4_EXT 0x3004 -#define GL_CLIP_DISTANCE5_EXT 0x3005 -#define GL_CLIP_DISTANCE6_EXT 0x3006 -#define GL_CLIP_DISTANCE7_EXT 0x3007 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#define GL_MULTIPLY_KHR 0x9294 -#define GL_SCREEN_KHR 0x9295 -#define GL_OVERLAY_KHR 0x9296 -#define GL_DARKEN_KHR 0x9297 -#define GL_LIGHTEN_KHR 0x9298 -#define GL_COLORDODGE_KHR 0x9299 -#define GL_COLORBURN_KHR 0x929A -#define GL_HARDLIGHT_KHR 0x929B -#define GL_SOFTLIGHT_KHR 0x929C -#define GL_DIFFERENCE_KHR 0x929E -#define GL_EXCLUSION_KHR 0x92A0 -#define GL_HSL_HUE_KHR 0x92AD -#define GL_HSL_SATURATION_KHR 0x92AE -#define GL_HSL_COLOR_KHR 0x92AF -#define GL_HSL_LUMINOSITY_KHR 0x92B0 -#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_BUFFER 0x82E0 -#define GL_SHADER 0x82E1 -#define GL_PROGRAM 0x82E2 -#define GL_VERTEX_ARRAY 0x8074 -#define GL_QUERY 0x82E3 -#define GL_PROGRAM_PIPELINE 0x82E4 -#define GL_SAMPLER 0x82E6 -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 -#define GL_DEBUG_SOURCE_API_KHR 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A -#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B -#define GL_DEBUG_TYPE_ERROR_KHR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 -#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 -#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D -#define GL_BUFFER_KHR 0x82E0 -#define GL_SHADER_KHR 0x82E1 -#define GL_PROGRAM_KHR 0x82E2 -#define GL_VERTEX_ARRAY_KHR 0x8074 -#define GL_QUERY_KHR 0x82E3 -#define GL_PROGRAM_PIPELINE_KHR 0x82E4 -#define GL_SAMPLER_KHR 0x82E6 -#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 -#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 -#define GL_DEBUG_OUTPUT_KHR 0x92E0 -#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 -#define GL_STACK_OVERFLOW_KHR 0x0503 -#define GL_STACK_UNDERFLOW_KHR 0x0504 -#define GL_DISPLAY_LIST 0x82E7 -#ifndef GL_EXT_base_instance -#define GL_EXT_base_instance 1 -GLAPI int GLAD_GL_EXT_base_instance; -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -GLAPI PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawArraysInstancedBaseInstanceEXT; -#define glDrawArraysInstancedBaseInstanceEXT glad_glDrawArraysInstancedBaseInstanceEXT -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); -GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseInstanceEXT; -#define glDrawElementsInstancedBaseInstanceEXT glad_glDrawElementsInstancedBaseInstanceEXT -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT; -#define glDrawElementsInstancedBaseVertexBaseInstanceEXT glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT -#endif -#ifndef GL_EXT_clip_cull_distance -#define GL_EXT_clip_cull_distance 1 -GLAPI int GLAD_GL_EXT_clip_cull_distance; -#endif -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_EXT_multisampled_render_to_texture 1 -GLAPI int GLAD_GL_EXT_multisampled_render_to_texture; -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; -#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); -GLAPI PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glad_glFramebufferTexture2DMultisampleEXT; -#define glFramebufferTexture2DMultisampleEXT glad_glFramebufferTexture2DMultisampleEXT -#endif -#ifndef GL_KHR_blend_equation_advanced -#define GL_KHR_blend_equation_advanced 1 -GLAPI int GLAD_GL_KHR_blend_equation_advanced; -typedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC)(void); -GLAPI PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR; -#define glBlendBarrierKHR glad_glBlendBarrierKHR -#endif -#ifndef GL_KHR_blend_equation_advanced_coherent -#define GL_KHR_blend_equation_advanced_coherent 1 -GLAPI int GLAD_GL_KHR_blend_equation_advanced_coherent; -#endif -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 -GLAPI int GLAD_GL_KHR_debug; -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; -#define glDebugMessageControl glad_glDebugMessageControl -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; -#define glDebugMessageInsert glad_glDebugMessageInsert -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void *userParam); -GLAPI PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; -#define glDebugMessageCallback glad_glDebugMessageCallback -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GLAPI PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; -#define glGetDebugMessageLog glad_glGetDebugMessageLog -typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar *message); -GLAPI PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; -#define glPushDebugGroup glad_glPushDebugGroup -typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC)(void); -GLAPI PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; -#define glPopDebugGroup glad_glPopDebugGroup -typedef void (APIENTRYP PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -GLAPI PFNGLOBJECTLABELPROC glad_glObjectLabel; -#define glObjectLabel glad_glObjectLabel -typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; -#define glGetObjectLabel glad_glGetObjectLabel -typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC)(const void *ptr, GLsizei length, const GLchar *label); -GLAPI PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; -#define glObjectPtrLabel glad_glObjectPtrLabel -typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; -#define glGetObjectPtrLabel glad_glGetObjectPtrLabel -typedef void (APIENTRYP PFNGLGETPOINTERVPROC)(GLenum pname, void **params); -GLAPI PFNGLGETPOINTERVPROC glad_glGetPointerv; -#define glGetPointerv glad_glGetPointerv -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; -#define glDebugMessageControlKHR glad_glDebugMessageControlKHR -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; -#define glDebugMessageInsertKHR glad_glDebugMessageInsertKHR -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC)(GLDEBUGPROCKHR callback, const void *userParam); -GLAPI PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; -#define glDebugMessageCallbackKHR glad_glDebugMessageCallbackKHR -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GLAPI PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; -#define glGetDebugMessageLogKHR glad_glGetDebugMessageLogKHR -typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC)(GLenum source, GLuint id, GLsizei length, const GLchar *message); -GLAPI PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; -#define glPushDebugGroupKHR glad_glPushDebugGroupKHR -typedef void (APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC)(void); -GLAPI PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; -#define glPopDebugGroupKHR glad_glPopDebugGroupKHR -typedef void (APIENTRYP PFNGLOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -GLAPI PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; -#define glObjectLabelKHR glad_glObjectLabelKHR -typedef void (APIENTRYP PFNGLGETOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; -#define glGetObjectLabelKHR glad_glGetObjectLabelKHR -typedef void (APIENTRYP PFNGLOBJECTPTRLABELKHRPROC)(const void *ptr, GLsizei length, const GLchar *label); -GLAPI PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; -#define glObjectPtrLabelKHR glad_glObjectPtrLabelKHR -typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -GLAPI PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; -#define glGetObjectPtrLabelKHR glad_glGetObjectPtrLabelKHR -typedef void (APIENTRYP PFNGLGETPOINTERVKHRPROC)(GLenum pname, void **params); -GLAPI PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; -#define glGetPointervKHR glad_glGetPointervKHR -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/glad/include/glad/egl.h b/thirdparty/glad/include/glad/egl.h new file mode 100644 index 000000000..10bf18e21 --- /dev/null +++ b/thirdparty/glad/include/glad/egl.h @@ -0,0 +1,550 @@ +/** + * Loader generated by glad 2.0.8 on Thu Aug 21 23:03:28 2025 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: egl + * Extensions: 0 + * + * APIs: + * - egl=1.5 + * + * Options: + * - ALIAS = False + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = True + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='egl=1.5' --extensions='' c --loader + * + * Online: + * http://glad.sh/#api=egl%3D1.5&extensions=&generator=c&options=LOADER + * + */ + +#ifndef GLAD_EGL_H_ +#define GLAD_EGL_H_ + + +#define GLAD_EGL +#define GLAD_OPTION_EGL_LOADER + +#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_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_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_DONT_CARE EGL_CAST(EGLint,-1) +#define EGL_DRAW 0x3059 +#define EGL_EXTENSIONS 0x3055 +#define EGL_FALSE 0 +#define EGL_FOREVER 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_LARGEST_PBUFFER 0x3058 +#define EGL_LEVEL 0x3029 +#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_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_RESET_NOTIFICATION 0x31BE +#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) +#define EGL_NO_SYNC 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_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_SIGNALED 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_CONDITION 0x30F8 +#define EGL_SYNC_FENCE 0x30F9 +#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 +#define EGL_SYNC_STATUS 0x30F1 +#define EGL_SYNC_TYPE 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_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_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 + + +#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; + + +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 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 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 *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); +typedef EGLSync (GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib * 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 *PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSYNCPROC)(EGLDisplay dpy, EGLSync 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 __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 *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 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 *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 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 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 PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface; +#define eglCreatePlatformWindowSurface glad_eglCreatePlatformWindowSurface +GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync; +#define eglCreateSync glad_eglCreateSync +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 PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface; +#define eglDestroySurface glad_eglDestroySurface +GLAD_API_CALL PFNEGLDESTROYSYNCPROC glad_eglDestroySync; +#define eglDestroySync glad_eglDestroySync +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 PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress; +#define eglGetProcAddress glad_eglGetProcAddress +GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib; +#define eglGetSyncAttrib glad_eglGetSyncAttrib +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 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 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 GLAD_EGL + +GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display); + +GLAD_API_CALL void gladLoaderUnloadEGL(void); + +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/glad/include/glad/gles2.h b/thirdparty/glad/include/glad/gles2.h new file mode 100644 index 000000000..e38cb20ae --- /dev/null +++ b/thirdparty/glad/include/glad/gles2.h @@ -0,0 +1,2169 @@ +/** + * Loader generated by glad 2.0.8 on Thu Aug 21 23:03:29 2025 + * + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + * + * Generator: C/C++ + * Specification: gl + * Extensions: 7 + * + * APIs: + * - gles2=3.1 + * + * Options: + * - ALIAS = False + * - DEBUG = False + * - HEADER_ONLY = False + * - LOADER = True + * - MX = False + * - ON_DEMAND = False + * + * Commandline: + * --api='gles2=3.1' --extensions='GL_EXT_base_instance,GL_EXT_clip_cull_distance,GL_EXT_multisampled_render_to_texture,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_debug,GL_KHR_parallel_shader_compile' c --loader + * + * Online: + * http://glad.sh/#api=gles2%3D3.1&extensions=GL_EXT_base_instance%2CGL_EXT_clip_cull_distance%2CGL_EXT_multisampled_render_to_texture%2CGL_KHR_blend_equation_advanced%2CGL_KHR_blend_equation_advanced_coherent%2CGL_KHR_debug%2CGL_KHR_parallel_shader_compile&generator=c&options=LOADER + * + */ + +#ifndef GLAD_GLES2_H_ +#define GLAD_GLES2_H_ + +#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_LOADER + +#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_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_ALPHA 0x1906 +#define GL_ALPHA_BITS 0x0D55 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_ALWAYS 0x0207 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ARRAY_SIZE 0x92FB +#define GL_ARRAY_STRIDE 0x92FE +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_BACK 0x0405 +#define GL_BLEND 0x0BE2 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#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_BLOCK_INDEX 0x92FD +#define GL_BLUE 0x1905 +#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_FLAGS 0x911F +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_BUFFER_KHR 0x82E0 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_BYTE 0x1400 +#define GL_CCW 0x0901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLIP_DISTANCE0_EXT 0x3000 +#define GL_CLIP_DISTANCE1_EXT 0x3001 +#define GL_CLIP_DISTANCE2_EXT 0x3002 +#define GL_CLIP_DISTANCE3_EXT 0x3003 +#define GL_CLIP_DISTANCE4_EXT 0x3004 +#define GL_CLIP_DISTANCE5_EXT 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE6_EXT 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_CLIP_DISTANCE7_EXT 0x3007 +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 +#define GL_COLOR 0x1800 +#define GL_COLORBURN_KHR 0x929A +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_COMPARE_R_TO_TEXTURE 0x884E +#define GL_COMPILE_STATUS 0x8B81 +#define GL_COMPLETION_STATUS_KHR 0x91B1 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_CONDITION_SATISFIED 0x911C +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_CURRENT_QUERY 0x8865 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_CW 0x0900 +#define GL_DARKEN_KHR 0x9297 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DECR 0x1E03 +#define GL_DECR_WRAP 0x8508 +#define GL_DELETE_STATUS 0x8B80 +#define GL_DEPTH 0x1801 +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_DEPTH32F_STENCIL8 0x8CAD +#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 0x81A6 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DIFFERENCE_KHR 0x929E +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_DITHER 0x0BD0 +#define GL_DONT_CARE 0x1100 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_DST_ALPHA 0x0304 +#define GL_DST_COLOR 0x0306 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_EQUAL 0x0202 +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_EXTENSIONS 0x1F03 +#define GL_FALSE 0 +#define GL_FASTEST 0x1101 +#define GL_FIXED 0x140C +#define GL_FLOAT 0x1406 +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4 0x8B5C +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_FRAMEBUFFER 0x8D40 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#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 0x1904 +#define GL_GREEN_BITS 0x0D53 +#define GL_HALF_FLOAT 0x140B +#define GL_HARDLIGHT_KHR 0x929B +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#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_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#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_INDEX 0xFFFFFFFF +#define GL_INVALID_OPERATION 0x0502 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVERT 0x150A +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_KEEP 0x1E00 +#define GL_LEQUAL 0x0203 +#define GL_LESS 0x0201 +#define GL_LIGHTEN_KHR 0x9298 +#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_LOCATION 0x930E +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_MAJOR_VERSION 0x821B +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MATRIX_STRIDE 0x92FF +#define GL_MAX 0x8008 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#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_MIN 0x8007 +#define GL_MINOR_VERSION 0x821C +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_NAME_LENGTH 0x92F9 +#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_ACTIVE_VARIABLES 0x9304 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_NUM_EXTENSIONS 0x821D +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_OBJECT_TYPE 0x9112 +#define GL_OFFSET 0x92FC +#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_OVERLAY_KHR 0x9296 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_POINTS 0x0000 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_PROGRAM_PIPELINE_KHR 0x82E4 +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_QUERY_KHR 0x82E3 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_R16F 0x822D +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32F 0x822E +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_R8 0x8229 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R8_SNORM 0x8F94 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_READ_BUFFER 0x0C02 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_READ_ONLY 0x88B8 +#define GL_READ_WRITE 0x88BA +#define GL_RED 0x1903 +#define GL_RED_BITS 0x0D52 +#define GL_RED_INTEGER 0x8D94 +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#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_SAMPLES 0x8CAB +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#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_RG 0x8227 +#define GL_RG16F 0x822F +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32F 0x8230 +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_RG8 0x822B +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB 0x1907 +#define GL_RGB10_A2 0x8059 +#define GL_RGB10_A2UI 0x906F +#define GL_RGB16F 0x881B +#define GL_RGB16I 0x8D89 +#define GL_RGB16UI 0x8D77 +#define GL_RGB32F 0x8815 +#define GL_RGB32I 0x8D83 +#define GL_RGB32UI 0x8D71 +#define GL_RGB565 0x8D62 +#define GL_RGB5_A1 0x8057 +#define GL_RGB8 0x8051 +#define GL_RGB8I 0x8D8F +#define GL_RGB8UI 0x8D7D +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGB9_E5 0x8C3D +#define GL_RGBA 0x1908 +#define GL_RGBA16F 0x881A +#define GL_RGBA16I 0x8D88 +#define GL_RGBA16UI 0x8D76 +#define GL_RGBA32F 0x8814 +#define GL_RGBA32I 0x8D82 +#define GL_RGBA32UI 0x8D70 +#define GL_RGBA4 0x8056 +#define GL_RGBA8 0x8058 +#define GL_RGBA8I 0x8D8E +#define GL_RGBA8UI 0x8D7C +#define GL_RGBA8_SNORM 0x8F97 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RG_INTEGER 0x8228 +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_BINDING 0x8919 +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_SAMPLER_KHR 0x82E6 +#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_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SCREEN_KHR 0x9295 +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_SHADER_KHR 0x82E1 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_TYPE 0x8B4F +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_SHORT 0x1402 +#define GL_SIGNALED 0x9119 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_SRC_ALPHA 0x0302 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_SRC_COLOR 0x0300 +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +#define GL_STATIC_COPY 0x88E6 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STENCIL 0x1802 +#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_INDEX 0x1901 +#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_COPY 0x88E2 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_SYNC_STATUS 0x9114 +#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_ARRAY 0x8C1A +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPRESSED 0x86A1 +#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_DEPTH 0x8071 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRUE 1 +#define GL_TYPE 0x92FA +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNSIGNALED 0x9118 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_INT 0x1405 +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_UNSIGNED_NORMALIZED 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 0x85B5 +#define GL_VERTEX_ARRAY_KHR 0x8074 +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#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_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_VIEWPORT 0x0BA2 +#define GL_WAIT_FAILED 0x911D +#define GL_WRITE_ONLY 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_ES_VERSION_3_0 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_3_0; +#define GL_ES_VERSION_3_1 1 +GLAD_API_CALL int GLAD_GL_ES_VERSION_3_1; +#define GL_EXT_base_instance 1 +GLAD_API_CALL int GLAD_GL_EXT_base_instance; +#define GL_EXT_clip_cull_distance 1 +GLAD_API_CALL int GLAD_GL_EXT_clip_cull_distance; +#define GL_EXT_multisampled_render_to_texture 1 +GLAD_API_CALL int GLAD_GL_EXT_multisampled_render_to_texture; +#define GL_KHR_blend_equation_advanced 1 +GLAD_API_CALL int GLAD_GL_KHR_blend_equation_advanced; +#define GL_KHR_blend_equation_advanced_coherent 1 +GLAD_API_CALL int GLAD_GL_KHR_blend_equation_advanced_coherent; +#define GL_KHR_debug 1 +GLAD_API_CALL int GLAD_GL_KHR_debug; +#define GL_KHR_parallel_shader_compile 1 +GLAD_API_CALL int GLAD_GL_KHR_parallel_shader_compile; + + +typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program); +typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); +typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); +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 *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); +typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); +typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GLAD_API_PTR *PFNGLBLENDBARRIERKHRPROC)(void); +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 *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +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 *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); +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 GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +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 *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, 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 *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +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 void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); +typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const* strings); +typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKKHRPROC)(GLDEBUGPROCKHR callback, const void * userParam); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLKHRPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTKHRPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +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 *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); +typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); +typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(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 *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, 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 *PFNGLENDQUERYPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); +typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); +typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); +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 *PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +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 *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); +typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); +typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); +typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(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 *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); +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 *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); +typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); +typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); +typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); +typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELKHRPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); +typedef void (GLAD_API_PTR *PFNGLGETPOINTERVKHRPROC)(GLenum pname, void ** params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint * params); +typedef GLuint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei count, GLsizei * length, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, 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 const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); +typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params); +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 void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); +typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); +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 *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); +typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * 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 void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +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 *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline); +typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); +typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); +typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); +typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); +typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); +typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); +typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); +typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); +typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); +typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAD_API_PTR *PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)(GLuint count); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers); +typedef void (GLAD_API_PTR *PFNGLOBJECTLABELKHRPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELKHRPROC)(const void * ptr, GLsizei length, const GLchar * label); +typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); +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 *PFNGLPOPDEBUGGROUPKHRPROC)(void); +typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length); +typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPKHRPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message); +typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); +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 *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); +typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); +typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); +typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); +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 *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, 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 *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +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 *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); +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 *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); +typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * 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 *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); +typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * 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 *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * 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 *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(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 *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(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 void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); +typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline); +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 *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor); +typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); + +GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; +#define glActiveShaderProgram glad_glActiveShaderProgram +GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; +#define glActiveTexture glad_glActiveTexture +GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; +#define glAttachShader glad_glAttachShader +GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; +#define glBeginQuery glad_glBeginQuery +GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; +#define glBeginTransformFeedback glad_glBeginTransformFeedback +GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; +#define glBindAttribLocation glad_glBindAttribLocation +GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; +#define glBindBuffer glad_glBindBuffer +GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; +#define glBindBufferBase glad_glBindBufferBase +GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; +#define glBindBufferRange glad_glBindBufferRange +GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; +#define glBindFramebuffer glad_glBindFramebuffer +GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; +#define glBindImageTexture glad_glBindImageTexture +GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; +#define glBindProgramPipeline glad_glBindProgramPipeline +GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; +#define glBindRenderbuffer glad_glBindRenderbuffer +GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; +#define glBindSampler glad_glBindSampler +GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; +#define glBindTexture glad_glBindTexture +GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; +#define glBindTransformFeedback glad_glBindTransformFeedback +GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; +#define glBindVertexArray glad_glBindVertexArray +GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; +#define glBindVertexBuffer glad_glBindVertexBuffer +GLAD_API_CALL PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR; +#define glBlendBarrierKHR glad_glBlendBarrierKHR +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 PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; +#define glBlitFramebuffer glad_glBlitFramebuffer +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 PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; +#define glClearBufferfi glad_glClearBufferfi +GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; +#define glClearBufferfv glad_glClearBufferfv +GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; +#define glClearBufferiv glad_glClearBufferiv +GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; +#define glClearBufferuiv glad_glClearBufferuiv +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 PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +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 PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; +#define glCompressedTexImage3D glad_glCompressedTexImage3D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; +#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D +GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; +#define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D +GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; +#define glCopyBufferSubData glad_glCopyBufferSubData +GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; +#define glCopyTexImage2D glad_glCopyTexImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; +#define glCopyTexSubImage2D glad_glCopyTexSubImage2D +GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; +#define glCopyTexSubImage3D glad_glCopyTexSubImage3D +GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; +#define glCreateProgram glad_glCreateProgram +GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; +#define glCreateShader glad_glCreateShader +GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; +#define glCreateShaderProgramv glad_glCreateShaderProgramv +GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; +#define glCullFace glad_glCullFace +GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; +#define glDebugMessageCallbackKHR glad_glDebugMessageCallbackKHR +GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; +#define glDebugMessageControlKHR glad_glDebugMessageControlKHR +GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; +#define glDebugMessageInsertKHR glad_glDebugMessageInsertKHR +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 PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; +#define glDeleteProgramPipelines glad_glDeleteProgramPipelines +GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; +#define glDeleteQueries glad_glDeleteQueries +GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; +#define glDeleteRenderbuffers glad_glDeleteRenderbuffers +GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; +#define glDeleteSamplers glad_glDeleteSamplers +GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; +#define glDeleteShader glad_glDeleteShader +GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; +#define glDeleteTextures glad_glDeleteTextures +GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; +#define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks +GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; +#define glDeleteVertexArrays glad_glDeleteVertexArrays +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 PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; +#define glDispatchCompute glad_glDispatchCompute +GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; +#define glDispatchComputeIndirect glad_glDispatchComputeIndirect +GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; +#define glDrawArrays glad_glDrawArrays +GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; +#define glDrawArraysIndirect glad_glDrawArraysIndirect +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; +#define glDrawArraysInstanced glad_glDrawArraysInstanced +GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawArraysInstancedBaseInstanceEXT; +#define glDrawArraysInstancedBaseInstanceEXT glad_glDrawArraysInstancedBaseInstanceEXT +GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; +#define glDrawBuffers glad_glDrawBuffers +GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; +#define glDrawElements glad_glDrawElements +GLAD_API_CALL PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; +#define glDrawElementsIndirect glad_glDrawElementsIndirect +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; +#define glDrawElementsInstanced glad_glDrawElementsInstanced +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseInstanceEXT; +#define glDrawElementsInstancedBaseInstanceEXT glad_glDrawElementsInstancedBaseInstanceEXT +GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT; +#define glDrawElementsInstancedBaseVertexBaseInstanceEXT glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT +GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; +#define glDrawRangeElements glad_glDrawRangeElements +GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; +#define glEnable glad_glEnable +GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; +#define glEnableVertexAttribArray glad_glEnableVertexAttribArray +GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; +#define glEndQuery glad_glEndQuery +GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; +#define glEndTransformFeedback glad_glEndTransformFeedback +GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; +#define glFinish glad_glFinish +GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; +#define glFlush glad_glFlush +GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; +#define glFlushMappedBufferRange glad_glFlushMappedBufferRange +GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; +#define glFramebufferParameteri glad_glFramebufferParameteri +GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; +#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; +#define glFramebufferTexture2D glad_glFramebufferTexture2D +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glad_glFramebufferTexture2DMultisampleEXT; +#define glFramebufferTexture2DMultisampleEXT glad_glFramebufferTexture2DMultisampleEXT +GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; +#define glFramebufferTextureLayer glad_glFramebufferTextureLayer +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 PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; +#define glGenProgramPipelines glad_glGenProgramPipelines +GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; +#define glGenQueries glad_glGenQueries +GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; +#define glGenRenderbuffers glad_glGenRenderbuffers +GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; +#define glGenSamplers glad_glGenSamplers +GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; +#define glGenTextures glad_glGenTextures +GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; +#define glGenTransformFeedbacks glad_glGenTransformFeedbacks +GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; +#define glGenVertexArrays glad_glGenVertexArrays +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 PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; +#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName +GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; +#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv +GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; +#define glGetActiveUniformsiv glad_glGetActiveUniformsiv +GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; +#define glGetAttachedShaders glad_glGetAttachedShaders +GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; +#define glGetAttribLocation glad_glGetAttribLocation +GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; +#define glGetBooleani_v glad_glGetBooleani_v +GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; +#define glGetBooleanv glad_glGetBooleanv +GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; +#define glGetBufferParameteri64v glad_glGetBufferParameteri64v +GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; +#define glGetBufferParameteriv glad_glGetBufferParameteriv +GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; +#define glGetBufferPointerv glad_glGetBufferPointerv +GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; +#define glGetDebugMessageLogKHR glad_glGetDebugMessageLogKHR +GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; +#define glGetError glad_glGetError +GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; +#define glGetFloatv glad_glGetFloatv +GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; +#define glGetFragDataLocation glad_glGetFragDataLocation +GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; +#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv +GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; +#define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv +GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; +#define glGetInteger64i_v glad_glGetInteger64i_v +GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; +#define glGetIntegeri_v glad_glGetIntegeri_v +GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; +#define glGetIntegerv glad_glGetIntegerv +GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; +#define glGetInternalformativ glad_glGetInternalformativ +GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; +#define glGetMultisamplefv glad_glGetMultisamplefv +GLAD_API_CALL PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; +#define glGetObjectLabelKHR glad_glGetObjectLabelKHR +GLAD_API_CALL PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; +#define glGetObjectPtrLabelKHR glad_glGetObjectPtrLabelKHR +GLAD_API_CALL PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; +#define glGetPointervKHR glad_glGetPointervKHR +GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; +#define glGetProgramBinary glad_glGetProgramBinary +GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; +#define glGetProgramInfoLog glad_glGetProgramInfoLog +GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; +#define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; +#define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog +GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; +#define glGetProgramPipelineiv glad_glGetProgramPipelineiv +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; +#define glGetProgramResourceIndex glad_glGetProgramResourceIndex +GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; +#define glGetProgramResourceLocation glad_glGetProgramResourceLocation +GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; +#define glGetProgramResourceName glad_glGetProgramResourceName +GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; +#define glGetProgramResourceiv glad_glGetProgramResourceiv +GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; +#define glGetProgramiv glad_glGetProgramiv +GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; +#define glGetQueryObjectuiv glad_glGetQueryObjectuiv +GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; +#define glGetQueryiv glad_glGetQueryiv +GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; +#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; +#define glGetSamplerParameterfv glad_glGetSamplerParameterfv +GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; +#define glGetSamplerParameteriv glad_glGetSamplerParameteriv +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 PFNGLGETSTRINGIPROC glad_glGetStringi; +#define glGetStringi glad_glGetStringi +GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; +#define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv +GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; +#define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv +GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; +#define glGetTexParameterfv glad_glGetTexParameterfv +GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; +#define glGetTexParameteriv glad_glGetTexParameteriv +GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; +#define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying +GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; +#define glGetUniformBlockIndex glad_glGetUniformBlockIndex +GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; +#define glGetUniformIndices glad_glGetUniformIndices +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 PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; +#define glGetUniformuiv glad_glGetUniformuiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; +#define glGetVertexAttribIiv glad_glGetVertexAttribIiv +GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; +#define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv +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 PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; +#define glInvalidateFramebuffer glad_glInvalidateFramebuffer +GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; +#define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer +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 PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; +#define glIsProgramPipeline glad_glIsProgramPipeline +GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; +#define glIsQuery glad_glIsQuery +GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; +#define glIsRenderbuffer glad_glIsRenderbuffer +GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; +#define glIsSampler glad_glIsSampler +GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; +#define glIsShader glad_glIsShader +GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; +#define glIsTexture glad_glIsTexture +GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; +#define glIsTransformFeedback glad_glIsTransformFeedback +GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; +#define glIsVertexArray glad_glIsVertexArray +GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; +#define glLineWidth glad_glLineWidth +GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; +#define glLinkProgram glad_glLinkProgram +GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; +#define glMapBufferRange glad_glMapBufferRange +GLAD_API_CALL PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR; +#define glMaxShaderCompilerThreadsKHR glad_glMaxShaderCompilerThreadsKHR +GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; +#define glMemoryBarrier glad_glMemoryBarrier +GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; +#define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion +GLAD_API_CALL PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; +#define glObjectLabelKHR glad_glObjectLabelKHR +GLAD_API_CALL PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; +#define glObjectPtrLabelKHR glad_glObjectPtrLabelKHR +GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; +#define glPauseTransformFeedback glad_glPauseTransformFeedback +GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; +#define glPixelStorei glad_glPixelStorei +GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; +#define glPolygonOffset glad_glPolygonOffset +GLAD_API_CALL PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; +#define glPopDebugGroupKHR glad_glPopDebugGroupKHR +GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; +#define glProgramBinary glad_glProgramBinary +GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; +#define glProgramParameteri glad_glProgramParameteri +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; +#define glProgramUniform1f glad_glProgramUniform1f +GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; +#define glProgramUniform1fv glad_glProgramUniform1fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; +#define glProgramUniform1i glad_glProgramUniform1i +GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; +#define glProgramUniform1iv glad_glProgramUniform1iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; +#define glProgramUniform1ui glad_glProgramUniform1ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; +#define glProgramUniform1uiv glad_glProgramUniform1uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; +#define glProgramUniform2f glad_glProgramUniform2f +GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; +#define glProgramUniform2fv glad_glProgramUniform2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; +#define glProgramUniform2i glad_glProgramUniform2i +GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; +#define glProgramUniform2iv glad_glProgramUniform2iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; +#define glProgramUniform2ui glad_glProgramUniform2ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; +#define glProgramUniform2uiv glad_glProgramUniform2uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; +#define glProgramUniform3f glad_glProgramUniform3f +GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; +#define glProgramUniform3fv glad_glProgramUniform3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; +#define glProgramUniform3i glad_glProgramUniform3i +GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; +#define glProgramUniform3iv glad_glProgramUniform3iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; +#define glProgramUniform3ui glad_glProgramUniform3ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; +#define glProgramUniform3uiv glad_glProgramUniform3uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; +#define glProgramUniform4f glad_glProgramUniform4f +GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; +#define glProgramUniform4fv glad_glProgramUniform4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; +#define glProgramUniform4i glad_glProgramUniform4i +GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; +#define glProgramUniform4iv glad_glProgramUniform4iv +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; +#define glProgramUniform4ui glad_glProgramUniform4ui +GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; +#define glProgramUniform4uiv glad_glProgramUniform4uiv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; +#define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; +#define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; +#define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; +#define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; +#define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; +#define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; +#define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; +#define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv +GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; +#define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv +GLAD_API_CALL PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; +#define glPushDebugGroupKHR glad_glPushDebugGroupKHR +GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; +#define glReadBuffer glad_glReadBuffer +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 PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; +#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample +GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; +#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT +GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; +#define glResumeTransformFeedback glad_glResumeTransformFeedback +GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; +#define glSampleCoverage glad_glSampleCoverage +GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; +#define glSampleMaski glad_glSampleMaski +GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; +#define glSamplerParameterf glad_glSamplerParameterf +GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; +#define glSamplerParameterfv glad_glSamplerParameterfv +GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; +#define glSamplerParameteri glad_glSamplerParameteri +GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; +#define glSamplerParameteriv glad_glSamplerParameteriv +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 PFNGLTEXIMAGE3DPROC glad_glTexImage3D; +#define glTexImage3D glad_glTexImage3D +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 PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; +#define glTexStorage2D glad_glTexStorage2D +GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; +#define glTexStorage2DMultisample glad_glTexStorage2DMultisample +GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; +#define glTexStorage3D glad_glTexStorage3D +GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; +#define glTexSubImage2D glad_glTexSubImage2D +GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; +#define glTexSubImage3D glad_glTexSubImage3D +GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; +#define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings +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 PFNGLUNIFORM1UIPROC glad_glUniform1ui; +#define glUniform1ui glad_glUniform1ui +GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; +#define glUniform1uiv glad_glUniform1uiv +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 PFNGLUNIFORM2UIPROC glad_glUniform2ui; +#define glUniform2ui glad_glUniform2ui +GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; +#define glUniform2uiv glad_glUniform2uiv +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 PFNGLUNIFORM3UIPROC glad_glUniform3ui; +#define glUniform3ui glad_glUniform3ui +GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; +#define glUniform3uiv glad_glUniform3uiv +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 PFNGLUNIFORM4UIPROC glad_glUniform4ui; +#define glUniform4ui glad_glUniform4ui +GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; +#define glUniform4uiv glad_glUniform4uiv +GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; +#define glUniformBlockBinding glad_glUniformBlockBinding +GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; +#define glUniformMatrix2fv glad_glUniformMatrix2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; +#define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; +#define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; +#define glUniformMatrix3fv glad_glUniformMatrix3fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; +#define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; +#define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; +#define glUniformMatrix4fv glad_glUniformMatrix4fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; +#define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv +GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; +#define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv +GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; +#define glUnmapBuffer glad_glUnmapBuffer +GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; +#define glUseProgram glad_glUseProgram +GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; +#define glUseProgramStages glad_glUseProgramStages +GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; +#define glValidateProgram glad_glValidateProgram +GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; +#define glValidateProgramPipeline glad_glValidateProgramPipeline +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 PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; +#define glVertexAttribBinding glad_glVertexAttribBinding +GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; +#define glVertexAttribDivisor glad_glVertexAttribDivisor +GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; +#define glVertexAttribFormat glad_glVertexAttribFormat +GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; +#define glVertexAttribI4i glad_glVertexAttribI4i +GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; +#define glVertexAttribI4iv glad_glVertexAttribI4iv +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; +#define glVertexAttribI4ui glad_glVertexAttribI4ui +GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; +#define glVertexAttribI4uiv glad_glVertexAttribI4uiv +GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; +#define glVertexAttribIFormat glad_glVertexAttribIFormat +GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; +#define glVertexAttribIPointer glad_glVertexAttribIPointer +GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; +#define glVertexAttribPointer glad_glVertexAttribPointer +GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; +#define glVertexBindingDivisor glad_glVertexBindingDivisor +GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; +#define glViewport glad_glViewport +GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync + + + + + +GLAD_API_CALL int gladLoadGLES2UserPtr( GLADuserptrloadfunc load, void *userptr); +GLAD_API_CALL int gladLoadGLES2( GLADloadfunc load); + + +#ifdef GLAD_GLES2 + +GLAD_API_CALL int gladLoaderLoadGLES2(void); +GLAD_API_CALL void gladLoaderUnloadGLES2(void); + +#endif /* GLAD_GLES2 */ + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/glad/include/glad_custom.h b/thirdparty/glad/include/glad_custom.h index a612692e3..eafe43d32 100644 --- a/thirdparty/glad/include/glad_custom.h +++ b/thirdparty/glad/include/glad_custom.h @@ -1,12 +1,12 @@ #pragma once -#include "glad.h" +#include #ifdef __cplusplus extern "C" { #endif -int gladLoadCustomLoader(GLADloadproc); +int gladLoadCustomLoader(GLADloadfunc); GLAPI int GLAD_GL_version_es; GLAPI int GLAD_GL_version_major; @@ -39,34 +39,34 @@ GLAPI int GLAD_GL_ANGLE_base_vertex_base_instance_shader_builtin; #define GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE 0x96ED GLAPI int GLAD_GL_ANGLE_shader_pixel_local_storage; GLAPI int GLAD_GL_ANGLE_shader_pixel_local_storage_coherent; -typedef void (APIENTRYP PFNGLFRAMEBUFFERMEMORYLESSPIXELLOCALSTORAGEANGLEPROC) (GLint plane, GLenum internalformat); +typedef void (GLAD_API_PTR* PFNGLFRAMEBUFFERMEMORYLESSPIXELLOCALSTORAGEANGLEPROC) (GLint plane, GLenum internalformat); GLAPI PFNGLFRAMEBUFFERMEMORYLESSPIXELLOCALSTORAGEANGLEPROC glad_glFramebufferMemorylessPixelLocalStorageANGLE; #define glFramebufferMemorylessPixelLocalStorageANGLE glad_glFramebufferMemorylessPixelLocalStorageANGLE -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC) (GLint plane, GLuint backingtexture, GLint level, GLint layer); +typedef void (GLAD_API_PTR* PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC) (GLint plane, GLuint backingtexture, GLint level, GLint layer, GLenum usage); GLAPI PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC glad_glFramebufferTexturePixelLocalStorageANGLE; #define glFramebufferTexturePixelLocalStorageANGLE glad_glFramebufferTexturePixelLocalStorageANGLE -typedef void (APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEFVANGLEPROC) (GLint plane, const GLfloat value[4]); +typedef void (GLAD_API_PTR* PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEFVANGLEPROC) (GLint plane, const GLfloat value[4]); GLAPI PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEFVANGLEPROC glad_glFramebufferPixelLocalClearValuefvANGLE; #define glFramebufferPixelLocalClearValuefvANGLE glad_glFramebufferPixelLocalClearValuefvANGLE -typedef void (APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC) (GLint plane, const GLint value[4]); +typedef void (GLAD_API_PTR* PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC) (GLint plane, const GLint value[4]); GLAPI PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEIVANGLEPROC glad_glFramebufferPixelLocalClearValueivANGLE; #define glFramebufferPixelLocalClearValueivANGLE glad_glFramebufferPixelLocalClearValueivANGLE -typedef void (APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC) (GLint plane, const GLuint value[4]); +typedef void (GLAD_API_PTR* PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC) (GLint plane, const GLuint value[4]); GLAPI PFNGLFRAMEBUFFERPIXELLOCALCLEARVALUEUIVANGLEPROC glad_glFramebufferPixelLocalClearValueuivANGLE; #define glFramebufferPixelLocalClearValueuivANGLE glad_glFramebufferPixelLocalClearValueuivANGLE -typedef void (APIENTRYP PFNGLBEGINPIXELLOCALSTORAGEANGLEPROC) (GLsizei n, const GLenum loadops[]); +typedef void (GLAD_API_PTR* PFNGLBEGINPIXELLOCALSTORAGEANGLEPROC) (GLsizei n, const GLenum loadops[]); GLAPI PFNGLBEGINPIXELLOCALSTORAGEANGLEPROC glad_glBeginPixelLocalStorageANGLE; #define glBeginPixelLocalStorageANGLE glad_glBeginPixelLocalStorageANGLE -typedef void (APIENTRYP PFNGLENDPIXELLOCALSTORAGEANGLEPROC) (GLsizei n, const GLenum storeops[]); +typedef void (GLAD_API_PTR* PFNGLENDPIXELLOCALSTORAGEANGLEPROC) (GLsizei n, const GLenum storeops[]); GLAPI PFNGLENDPIXELLOCALSTORAGEANGLEPROC glad_glEndPixelLocalStorageANGLE; #define glEndPixelLocalStorageANGLE glad_glEndPixelLocalStorageANGLE -typedef void (APIENTRYP PFNGLPIXELLOCALSTORAGEBARRIERANGLEPROC) (); +typedef void (GLAD_API_PTR* PFNGLPIXELLOCALSTORAGEBARRIERANGLEPROC) (); GLAPI PFNGLPIXELLOCALSTORAGEBARRIERANGLEPROC glad_glPixelLocalStorageBarrierANGLE; #define glPixelLocalStorageBarrierANGLE glad_glPixelLocalStorageBarrierANGLE -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC) (GLint plane, GLenum pname, GLfloat* params); +typedef void (GLAD_API_PTR* PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC) (GLint plane, GLenum pname, GLfloat* params); GLAPI PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC glad_glGetFramebufferPixelLocalStorageParameterfvANGLE; #define glGetFramebufferPixelLocalStorageParameterfvANGLE glad_glGetFramebufferPixelLocalStorageParameterfvANGLE -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERIVANGLEPROC) (GLint plane, GLenum pname, GLint* params); +typedef void (GLAD_API_PTR* PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERIVANGLEPROC) (GLint plane, GLenum pname, GLint* params); GLAPI PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERIVANGLEPROC glad_glGetFramebufferPixelLocalStorageParameterivANGLE; #define glGetFramebufferPixelLocalStorageParameterivANGLE glad_glGetFramebufferPixelLocalStorageParameterivANGLE #endif /* GL_ANGLE_shader_pixel_local_storage */ @@ -78,7 +78,7 @@ GLAPI PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERIVANGLEPROC glad_glGetFramebu #define GL_LINE_ANGLE 0x1B01 #define GL_FILL_ANGLE 0x1B02 GLAPI int GLAD_GL_ANGLE_polygon_mode; -typedef void (APIENTRYP PFNGLPOLYGONMODEANGLEPROC) (GLenum face, GLenum mode); +typedef void (GLAD_API_PTR* PFNGLPOLYGONMODEANGLEPROC) (GLenum face, GLenum mode); GLAPI PFNGLPOLYGONMODEANGLEPROC glad_glPolygonModeANGLE; #define glPolygonModeANGLE glad_glPolygonModeANGLE #endif /* GL_ANGLE_polygon_mode */ @@ -89,7 +89,7 @@ GLAPI PFNGLPOLYGONMODEANGLEPROC glad_glPolygonModeANGLE; #define GL_LAST_VERTEX_CONVENTION_ANGLE 0x8E4E #define GL_PROVOKING_VERTEX_ANGLE 0x8E4F GLAPI int GLAD_GL_ANGLE_provoking_vertex; -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXANGLEPROC) (GLenum provokeMode); +typedef void (GLAD_API_PTR* PFNGLPROVOKINGVERTEXANGLEPROC) (GLenum provokeMode); GLAPI PFNGLPROVOKINGVERTEXANGLEPROC glad_glProvokingVertexANGLE; #define glProvokingVertexANGLE glad_glProvokingVertexANGLE #endif /* GL_ANGLE_provoking_vertex */ diff --git a/thirdparty/glad/source/egl.c b/thirdparty/glad/source/egl.c new file mode 100644 index 000000000..18a697e3d --- /dev/null +++ b/thirdparty/glad/source/egl.c @@ -0,0 +1,397 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include +#include +#include +#include + +#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; + + + +PFNEGLBINDAPIPROC glad_eglBindAPI = NULL; +PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage = NULL; +PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig = NULL; +PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync = NULL; +PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers = NULL; +PFNEGLCREATECONTEXTPROC glad_eglCreateContext = NULL; +PFNEGLCREATEIMAGEPROC glad_eglCreateImage = NULL; +PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer = NULL; +PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface = NULL; +PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface = NULL; +PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface = NULL; +PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface = NULL; +PFNEGLCREATESYNCPROC glad_eglCreateSync = NULL; +PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface = NULL; +PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext = NULL; +PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage = NULL; +PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface = NULL; +PFNEGLDESTROYSYNCPROC glad_eglDestroySync = 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; +PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress = NULL; +PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib = NULL; +PFNEGLINITIALIZEPROC glad_eglInitialize = NULL; +PFNEGLMAKECURRENTPROC glad_eglMakeCurrent = NULL; +PFNEGLQUERYAPIPROC glad_eglQueryAPI = NULL; +PFNEGLQUERYCONTEXTPROC glad_eglQueryContext = NULL; +PFNEGLQUERYSTRINGPROC glad_eglQueryString = NULL; +PFNEGLQUERYSURFACEPROC glad_eglQuerySurface = NULL; +PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage = NULL; +PFNEGLRELEASETHREADPROC glad_eglReleaseThread = 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 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_UNUSED(&glad_egl_has_extension); + + 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; + + + return version; +} + +int gladLoadEGL(EGLDisplay display, GLADloadfunc load) { + return gladLoadEGLUserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + +#ifdef GLAD_EGL + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include +#include + +#if GLAD_PLATFORM_WIN32 +#include +#else +#include +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +struct _glad_egl_userptr { + void *handle; + PFNEGLGETPROCADDRESSPROC get_proc_address_ptr; +}; + +static GLADapiproc glad_egl_get_proc(void *vuserptr, const char* name) { + struct _glad_egl_userptr userptr = *(struct _glad_egl_userptr*) vuserptr; + GLADapiproc result = NULL; + + result = glad_dlsym_handle(userptr.handle, name); + if (result == NULL) { + result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.get_proc_address_ptr(name); + } + + return result; +} + +static void* _egl_handle = NULL; + +static void* glad_egl_dlopen_handle(void) { +#if GLAD_PLATFORM_APPLE + static const char *NAMES[] = {"libEGL.dylib"}; +#elif GLAD_PLATFORM_WIN32 + static const char *NAMES[] = {"libEGL.dll", "EGL.dll"}; +#else + static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"}; +#endif + + if (_egl_handle == NULL) { + _egl_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _egl_handle; +} + +static struct _glad_egl_userptr glad_egl_build_userptr(void *handle) { + struct _glad_egl_userptr userptr; + userptr.handle = handle; + userptr.get_proc_address_ptr = (PFNEGLGETPROCADDRESSPROC) glad_dlsym_handle(handle, "eglGetProcAddress"); + return userptr; +} + +int gladLoaderLoadEGL(EGLDisplay display) { + int version = 0; + void *handle = NULL; + int did_load = 0; + struct _glad_egl_userptr userptr; + + did_load = _egl_handle == NULL; + handle = glad_egl_dlopen_handle(); + if (handle != NULL) { + userptr = glad_egl_build_userptr(handle); + + if (userptr.get_proc_address_ptr != NULL) { + version = gladLoadEGLUserPtr(display, glad_egl_get_proc, &userptr); + } + + if (!version && did_load) { + gladLoaderUnloadEGL(); + } + } + + return version; +} + + +void gladLoaderUnloadEGL(void) { + if (_egl_handle != NULL) { + glad_close_dlopen_handle(_egl_handle); + _egl_handle = NULL; + } +} + +#endif /* GLAD_EGL */ + +#ifdef __cplusplus +} +#endif diff --git a/thirdparty/glad/source/glad.c b/thirdparty/glad/source/glad.c deleted file mode 100644 index 38fb37fa7..000000000 --- a/thirdparty/glad/source/glad.c +++ /dev/null @@ -1,918 +0,0 @@ -/* - - OpenGL ES loader generated by glad 0.1.36 on Wed Apr 3 22:10:47 2024. - - Language/Generator: C/C++ - Specification: gl - APIs: gles2=3.1 - Profile: compatibility - Extensions: - GL_EXT_base_instance, - GL_EXT_clip_cull_distance, - GL_EXT_multisampled_render_to_texture, - GL_KHR_blend_equation_advanced, - GL_KHR_blend_equation_advanced_coherent, - GL_KHR_debug - Loader: True - Local files: True - Omit khrplatform: False - Reproducible: False - - Commandline: - --profile="compatibility" --api="gles2=3.1" --generator="c" --spec="gl" --local-files --extensions="GL_EXT_base_instance,GL_EXT_clip_cull_distance,GL_EXT_multisampled_render_to_texture,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_debug" - Online: - https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gles2%3D3.1&extensions=GL_EXT_base_instance&extensions=GL_EXT_clip_cull_distance&extensions=GL_EXT_multisampled_render_to_texture&extensions=GL_KHR_blend_equation_advanced&extensions=GL_KHR_blend_equation_advanced_coherent&extensions=GL_KHR_debug -*/ - -#include -#include -#include -#include "glad.h" - -struct gladGLversionStruct GLVersion = { 0, 0 }; - -#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) -#define _GLAD_IS_SOME_NEW_VERSION 1 -#endif - -static int max_loaded_major; -static int max_loaded_minor; - -static const char *exts = NULL; -static int num_exts_i = 0; -static char **exts_i = NULL; - -static int get_exts(void) { -#ifdef _GLAD_IS_SOME_NEW_VERSION - if(max_loaded_major < 3) { -#endif - exts = (const char *)glGetString(GL_EXTENSIONS); -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - unsigned int index; - - num_exts_i = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **)malloc((size_t)num_exts_i * (sizeof *exts_i)); - } - - if (exts_i == NULL) { - return 0; - } - - for(index = 0; index < (unsigned)num_exts_i; index++) { - const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp); - - char *local_str = (char*)malloc((len+1) * sizeof(char)); - if(local_str != NULL) { - memcpy(local_str, gl_str_tmp, (len+1) * sizeof(char)); - } - exts_i[index] = local_str; - } - } -#endif - return 1; -} - -static void free_exts(void) { - if (exts_i != NULL) { - int index; - for(index = 0; index < num_exts_i; index++) { - free((char *)exts_i[index]); - } - free((void *)exts_i); - exts_i = NULL; - } -} - -static int has_ext(const char *ext) { -#ifdef _GLAD_IS_SOME_NEW_VERSION - if(max_loaded_major < 3) { -#endif - 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; - } -#ifdef _GLAD_IS_SOME_NEW_VERSION - } else { - int index; - if(exts_i == NULL) return 0; - for(index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - - if(exts_i[index] != NULL && strcmp(e, ext) == 0) { - return 1; - } - } - } -#endif - - return 0; -} -int GLAD_GL_ES_VERSION_2_0 = 0; -int GLAD_GL_ES_VERSION_3_0 = 0; -int GLAD_GL_ES_VERSION_3_1 = 0; -PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; -PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; -PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; -PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; -PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; -PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; -PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; -PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; -PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; -PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; -PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; -PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; -PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; -PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; -PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; -PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; -PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; -PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; -PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; -PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; -PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; -PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; -PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; -PFNGLBUFFERDATAPROC glad_glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; -PFNGLCLEARPROC glad_glClear = NULL; -PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; -PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; -PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; -PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; -PFNGLCLEARCOLORPROC glad_glClearColor = NULL; -PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; -PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; -PFNGLCOLORMASKPROC glad_glColorMask = NULL; -PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; -PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; -PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; -PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; -PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; -PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; -PFNGLCREATESHADERPROC glad_glCreateShader = NULL; -PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; -PFNGLCULLFACEPROC glad_glCullFace = NULL; -PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; -PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; -PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; -PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; -PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; -PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; -PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; -PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; -PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = 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; -PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; -PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; -PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; -PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; -PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; -PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLENABLEPROC glad_glEnable = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; -PFNGLENDQUERYPROC glad_glEndQuery = NULL; -PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; -PFNGLFINISHPROC glad_glFinish = NULL; -PFNGLFLUSHPROC glad_glFlush = NULL; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; -PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; -PFNGLFRONTFACEPROC glad_glFrontFace = NULL; -PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; -PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; -PFNGLGENQUERIESPROC glad_glGenQueries = NULL; -PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; -PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; -PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; -PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; -PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; -PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; -PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; -PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; -PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; -PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; -PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; -PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; -PFNGLGETERRORPROC glad_glGetError = NULL; -PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; -PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; -PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; -PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; -PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; -PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; -PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL; -PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL; -PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL; -PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL; -PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL; -PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; -PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; -PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; -PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; -PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; -PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; -PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; -PFNGLGETSTRINGPROC glad_glGetString = NULL; -PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; -PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; -PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; -PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; -PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; -PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; -PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; -PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; -PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; -PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; -PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; -PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; -PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; -PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; -PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; -PFNGLHINTPROC glad_glHint = NULL; -PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; -PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; -PFNGLISBUFFERPROC glad_glIsBuffer = NULL; -PFNGLISENABLEDPROC glad_glIsEnabled = NULL; -PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; -PFNGLISPROGRAMPROC glad_glIsProgram = NULL; -PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; -PFNGLISQUERYPROC glad_glIsQuery = NULL; -PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSAMPLERPROC glad_glIsSampler = NULL; -PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; -PFNGLISTEXTUREPROC glad_glIsTexture = NULL; -PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; -PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; -PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; -PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; -PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; -PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; -PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; -PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; -PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; -PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; -PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; -PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; -PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; -PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; -PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; -PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; -PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; -PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; -PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; -PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; -PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; -PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; -PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; -PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; -PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; -PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; -PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; -PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; -PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; -PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; -PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; -PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; -PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; -PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; -PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; -PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; -PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; -PFNGLREADPIXELSPROC glad_glReadPixels = NULL; -PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; -PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; -PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; -PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; -PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; -PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; -PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = 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; -PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; -PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; -PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; -PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; -PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; -PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; -PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; -PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; -PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; -PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; -PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; -PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; -PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; -PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; -PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; -PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; -PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; -PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; -PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; -PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; -PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; -PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; -PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; -PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; -PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; -PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; -PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; -PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; -PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; -PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; -PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; -PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; -PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; -PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; -PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; -PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; -PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; -PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; -PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; -PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; -PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; -PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; -PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; -PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; -PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = 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; -PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; -PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; -PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; -PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; -PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; -PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; -PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; -PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL; -PFNGLVIEWPORTPROC glad_glViewport = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; -int GLAD_GL_EXT_base_instance = 0; -int GLAD_GL_EXT_clip_cull_distance = 0; -int GLAD_GL_EXT_multisampled_render_to_texture = 0; -int GLAD_GL_KHR_blend_equation_advanced = 0; -int GLAD_GL_KHR_blend_equation_advanced_coherent = 0; -int GLAD_GL_KHR_debug = 0; -PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawArraysInstancedBaseInstanceEXT = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseInstanceEXT = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glad_glFramebufferTexture2DMultisampleEXT = NULL; -PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL; -PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; -PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; -PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; -PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; -PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; -PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; -PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; -PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; -PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; -PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; -PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; -PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL; -PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL; -PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL; -PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL; -PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL; -PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL; -PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL; -PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL; -PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL; -PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL; -PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL; -static void load_GL_ES_VERSION_2_0(GLADloadproc load) { - if(!GLAD_GL_ES_VERSION_2_0) return; - glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); - glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); - glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); - glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); - glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); - glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); - glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); - glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); - glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); - glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); - glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); - glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); - glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); - glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); - glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); - glad_glClear = (PFNGLCLEARPROC)load("glClear"); - glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); - glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC)load("glClearDepthf"); - glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); - glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); - glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); - glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); - glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); - glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); - glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); - glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); - glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); - glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); - glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); - glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); - glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); - glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); - glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); - glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); - glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); - glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); - glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC)load("glDepthRangef"); - glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); - glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); - glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); - glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); - glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); - glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); - glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); - glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); - glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); - glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); - glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); - glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); - glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); - glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); - glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); - glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); - glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); - glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); - glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); - glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); - glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); - glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); - glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); - glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); - glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); - glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); - glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); - glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); - glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); - glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); - glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); - glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); - glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)load("glGetShaderPrecisionFormat"); - glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); - glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); - glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); - glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); - glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); - glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); - glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); - glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); - glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); - glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); - glad_glHint = (PFNGLHINTPROC)load("glHint"); - glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); - glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); - glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); - glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); - glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); - glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); - glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); - glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); - glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); - glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); - glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); - glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); - glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)load("glReleaseShaderCompiler"); - glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); - glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); - glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); - glad_glShaderBinary = (PFNGLSHADERBINARYPROC)load("glShaderBinary"); - glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); - glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); - glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); - glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); - glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); - glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); - glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); - glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); - glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); - glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); - glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); - glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); - glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); - glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); - glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); - glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); - glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); - glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); - glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); - glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); - glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); - glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); - glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); - glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); - glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); - glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); - glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); - glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); - glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); - glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); - glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); - glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); - glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); - glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); - glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); - glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); - glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); - glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); - glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); - glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); - glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); - glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); - glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); - glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); -} -static void load_GL_ES_VERSION_3_0(GLADloadproc load) { - if(!GLAD_GL_ES_VERSION_3_0) return; - glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); - glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); - glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); - glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); - glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); - glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); - glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); - glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); - glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); - glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); - glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); - glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); - glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); - glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); - glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); - glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); - glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); - glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); - glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); - glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); - glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); - glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); - glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); - glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); - glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); - glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); - glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); - glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); - glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); - glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); - glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); - glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); - glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); - glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); - glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); - glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); - glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); - glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); - glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); - glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); - glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); - glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); - glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); - glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); - glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); - glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); - glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); - glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); - glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); - glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); - glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); - glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); - glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); - glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); - glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); - glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); - glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); - glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); - glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); - glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); - glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); - glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); - glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); - glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); - glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); - glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); - glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); - glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); - glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); - glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); - glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); - glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); - glad_glGenSamplers = (PFNGLGENSAMPLERSPROC)load("glGenSamplers"); - glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)load("glDeleteSamplers"); - glad_glIsSampler = (PFNGLISSAMPLERPROC)load("glIsSampler"); - glad_glBindSampler = (PFNGLBINDSAMPLERPROC)load("glBindSampler"); - glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)load("glSamplerParameteri"); - glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)load("glSamplerParameteriv"); - glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)load("glSamplerParameterf"); - glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)load("glSamplerParameterfv"); - glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)load("glGetSamplerParameteriv"); - glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)load("glGetSamplerParameterfv"); - glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)load("glVertexAttribDivisor"); - glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)load("glBindTransformFeedback"); - glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)load("glDeleteTransformFeedbacks"); - glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)load("glGenTransformFeedbacks"); - glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)load("glIsTransformFeedback"); - glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)load("glPauseTransformFeedback"); - glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)load("glResumeTransformFeedback"); - glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)load("glGetProgramBinary"); - glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC)load("glProgramBinary"); - glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)load("glProgramParameteri"); - glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)load("glInvalidateFramebuffer"); - glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)load("glInvalidateSubFramebuffer"); - glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)load("glTexStorage2D"); - glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)load("glTexStorage3D"); - glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)load("glGetInternalformativ"); -} -static void load_GL_ES_VERSION_3_1(GLADloadproc load) { - if(!GLAD_GL_ES_VERSION_3_1) return; - glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)load("glDispatchCompute"); - glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)load("glDispatchComputeIndirect"); - glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)load("glDrawArraysIndirect"); - glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)load("glDrawElementsIndirect"); - glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)load("glFramebufferParameteri"); - glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)load("glGetFramebufferParameteriv"); - glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)load("glGetProgramInterfaceiv"); - glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)load("glGetProgramResourceIndex"); - glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)load("glGetProgramResourceName"); - glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)load("glGetProgramResourceiv"); - glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)load("glGetProgramResourceLocation"); - glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)load("glUseProgramStages"); - glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)load("glActiveShaderProgram"); - glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)load("glCreateShaderProgramv"); - glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)load("glBindProgramPipeline"); - glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)load("glDeleteProgramPipelines"); - glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)load("glGenProgramPipelines"); - glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)load("glIsProgramPipeline"); - glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)load("glGetProgramPipelineiv"); - glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)load("glProgramUniform1i"); - glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)load("glProgramUniform2i"); - glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)load("glProgramUniform3i"); - glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)load("glProgramUniform4i"); - glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)load("glProgramUniform1ui"); - glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)load("glProgramUniform2ui"); - glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)load("glProgramUniform3ui"); - glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)load("glProgramUniform4ui"); - glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)load("glProgramUniform1f"); - glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)load("glProgramUniform2f"); - glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)load("glProgramUniform3f"); - glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)load("glProgramUniform4f"); - glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)load("glProgramUniform1iv"); - glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)load("glProgramUniform2iv"); - glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)load("glProgramUniform3iv"); - glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)load("glProgramUniform4iv"); - glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)load("glProgramUniform1uiv"); - glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)load("glProgramUniform2uiv"); - glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)load("glProgramUniform3uiv"); - glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)load("glProgramUniform4uiv"); - glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)load("glProgramUniform1fv"); - glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)load("glProgramUniform2fv"); - glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)load("glProgramUniform3fv"); - glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)load("glProgramUniform4fv"); - glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)load("glProgramUniformMatrix2fv"); - glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)load("glProgramUniformMatrix3fv"); - glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)load("glProgramUniformMatrix4fv"); - glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)load("glProgramUniformMatrix2x3fv"); - glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)load("glProgramUniformMatrix3x2fv"); - glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)load("glProgramUniformMatrix2x4fv"); - glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)load("glProgramUniformMatrix4x2fv"); - glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)load("glProgramUniformMatrix3x4fv"); - glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)load("glProgramUniformMatrix4x3fv"); - glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)load("glValidateProgramPipeline"); - glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)load("glGetProgramPipelineInfoLog"); - glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)load("glBindImageTexture"); - glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); - glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)load("glMemoryBarrier"); - glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)load("glMemoryBarrierByRegion"); - glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)load("glTexStorage2DMultisample"); - glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); - glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); - glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); - glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); - glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)load("glBindVertexBuffer"); - glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)load("glVertexAttribFormat"); - glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)load("glVertexAttribIFormat"); - glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)load("glVertexAttribBinding"); - glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)load("glVertexBindingDivisor"); -} -static void load_GL_EXT_base_instance(GLADloadproc load) { - if(!GLAD_GL_EXT_base_instance) return; - glad_glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)load("glDrawArraysInstancedBaseInstanceEXT"); - glad_glDrawElementsInstancedBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)load("glDrawElementsInstancedBaseInstanceEXT"); - glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)load("glDrawElementsInstancedBaseVertexBaseInstanceEXT"); -} -static void load_GL_EXT_multisampled_render_to_texture(GLADloadproc load) { - if(!GLAD_GL_EXT_multisampled_render_to_texture) return; - glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)load("glRenderbufferStorageMultisampleEXT"); - glad_glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)load("glFramebufferTexture2DMultisampleEXT"); -} -static void load_GL_KHR_blend_equation_advanced(GLADloadproc load) { - if(!GLAD_GL_KHR_blend_equation_advanced) return; - glad_glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC)load("glBlendBarrierKHR"); -} -static void load_GL_KHR_debug(GLADloadproc load) { - if(!GLAD_GL_KHR_debug) return; - glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)load("glDebugMessageControl"); - glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)load("glDebugMessageInsert"); - glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)load("glDebugMessageCallback"); - glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)load("glGetDebugMessageLog"); - glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)load("glPushDebugGroup"); - glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)load("glPopDebugGroup"); - glad_glObjectLabel = (PFNGLOBJECTLABELPROC)load("glObjectLabel"); - glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)load("glGetObjectLabel"); - glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)load("glObjectPtrLabel"); - glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)load("glGetObjectPtrLabel"); - glad_glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv"); - glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC)load("glDebugMessageControlKHR"); - glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC)load("glDebugMessageInsertKHR"); - glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC)load("glDebugMessageCallbackKHR"); - glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC)load("glGetDebugMessageLogKHR"); - glad_glPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC)load("glPushDebugGroupKHR"); - glad_glPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC)load("glPopDebugGroupKHR"); - glad_glObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC)load("glObjectLabelKHR"); - glad_glGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC)load("glGetObjectLabelKHR"); - glad_glObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC)load("glObjectPtrLabelKHR"); - glad_glGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC)load("glGetObjectPtrLabelKHR"); - glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC)load("glGetPointervKHR"); -} -static int find_extensionsGLES2(void) { - if (!get_exts()) return 0; - GLAD_GL_EXT_base_instance = has_ext("GL_EXT_base_instance"); - GLAD_GL_EXT_clip_cull_distance = has_ext("GL_EXT_clip_cull_distance"); - GLAD_GL_EXT_multisampled_render_to_texture = has_ext("GL_EXT_multisampled_render_to_texture"); - GLAD_GL_KHR_blend_equation_advanced = has_ext("GL_KHR_blend_equation_advanced"); - GLAD_GL_KHR_blend_equation_advanced_coherent = has_ext("GL_KHR_blend_equation_advanced_coherent"); - GLAD_GL_KHR_debug = has_ext("GL_KHR_debug"); - free_exts(); - return 1; -} - -static void find_coreGLES2(void) { - - /* Thank you @elmindreda - * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 - * https://github.com/glfw/glfw/blob/master/src/context.c#L36 - */ - int i, major, minor; - - const char* version; - const char* prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - NULL - }; - - version = (const char*) glGetString(GL_VERSION); - if (!version) return; - - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } - -/* PR #18 */ -#ifdef _MSC_VER - sscanf_s(version, "%d.%d", &major, &minor); -#else - sscanf(version, "%d.%d", &major, &minor); -#endif - - GLVersion.major = major; GLVersion.minor = minor; - max_loaded_major = major; max_loaded_minor = minor; - GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_ES_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_ES_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 1)) { - max_loaded_major = 3; - max_loaded_minor = 1; - } -} - -int gladLoadGLES2Loader(GLADloadproc load) { - GLVersion.major = 0; GLVersion.minor = 0; - glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); - if(glGetString == NULL) return 0; - if(glGetString(GL_VERSION) == NULL) return 0; - find_coreGLES2(); - load_GL_ES_VERSION_2_0(load); - load_GL_ES_VERSION_3_0(load); - load_GL_ES_VERSION_3_1(load); - - if (!find_extensionsGLES2()) return 0; - load_GL_EXT_base_instance(load); - load_GL_EXT_multisampled_render_to_texture(load); - load_GL_KHR_blend_equation_advanced(load); - load_GL_KHR_debug(load); - return GLVersion.major != 0 || GLVersion.minor != 0; -} diff --git a/thirdparty/glad/source/glad_custom.c b/thirdparty/glad/source/glad_custom.c index c78b2f7b7..33b60fd25 100644 --- a/thirdparty/glad/source/glad_custom.c +++ b/thirdparty/glad/source/glad_custom.c @@ -7,7 +7,7 @@ int GLAD_GL_version_es = 1; int GLAD_GL_version_major = 1; int GLAD_GL_version_minor = 0; -static void load_Desktop_GL(GLADloadproc load) { +static void load_Desktop_GL(GLADloadfunc load) { if (GLAD_GL_version_es) return; GLAD_GL_ANGLE_polygon_mode = 1; @@ -45,7 +45,7 @@ int GLAD_GL_ANGLE_shader_pixel_local_storage = 0; int GLAD_GL_ANGLE_shader_pixel_local_storage_coherent = 0; int GLAD_GL_ANGLE_polygon_mode = 0; int GLAD_GL_ANGLE_provoking_vertex = 0; -static void load_GL_ANGLE_shader_pixel_local_storage(GLADloadproc load) { +static void load_GL_ANGLE_shader_pixel_local_storage(GLADloadfunc load) { if(!GLAD_GL_ANGLE_shader_pixel_local_storage) return; glad_glFramebufferMemorylessPixelLocalStorageANGLE = (PFNGLFRAMEBUFFERMEMORYLESSPIXELLOCALSTORAGEANGLEPROC)load("glFramebufferMemorylessPixelLocalStorageANGLE"); glad_glFramebufferTexturePixelLocalStorageANGLE = (PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC)load("glFramebufferTexturePixelLocalStorageANGLE"); @@ -58,16 +58,16 @@ static void load_GL_ANGLE_shader_pixel_local_storage(GLADloadproc load) { glad_glGetFramebufferPixelLocalStorageParameterfvANGLE = (PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERFVANGLEPROC)load("glGetFramebufferPixelLocalStorageParameterfvANGLE"); glad_glGetFramebufferPixelLocalStorageParameterivANGLE = (PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGEPARAMETERIVANGLEPROC)load("glGetFramebufferPixelLocalStorageParameterivANGLE"); } -static void load_GL_ANGLE_polygon_mode(GLADloadproc load) { +static void load_GL_ANGLE_polygon_mode(GLADloadfunc load) { if(!GLAD_GL_ANGLE_polygon_mode) return; glad_glPolygonModeANGLE = (PFNGLPOLYGONMODEANGLEPROC)load("glPolygonModeANGLE"); } -static void load_GL_ANGLE_provoking_vertex(GLADloadproc load) { +static void load_GL_ANGLE_provoking_vertex(GLADloadfunc load) { if(!GLAD_GL_ANGLE_provoking_vertex) return; glad_glProvokingVertexANGLE = (PFNGLPROVOKINGVERTEXANGLEPROC)load("glProvokingVertexANGLE"); } -int gladLoadCustomLoader(GLADloadproc load) { - int ret = gladLoadGLES2Loader(load); +int gladLoadCustomLoader(GLADloadfunc load) { + int ret = gladLoadGLES2(load); const char* version = (const char*)glGetString(GL_VERSION); GLAD_GL_version_es = strstr(version, "OpenGL ES") != NULL; diff --git a/thirdparty/glad/source/gles2.c b/thirdparty/glad/source/gles2.c new file mode 100644 index 000000000..65ee778e0 --- /dev/null +++ b/thirdparty/glad/source/gles2.c @@ -0,0 +1,1089 @@ +/** + * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 + */ +#include +#include +#include +#include + +#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_ES_VERSION_3_0 = 0; +int GLAD_GL_ES_VERSION_3_1 = 0; +int GLAD_GL_EXT_base_instance = 0; +int GLAD_GL_EXT_clip_cull_distance = 0; +int GLAD_GL_EXT_multisampled_render_to_texture = 0; +int GLAD_GL_KHR_blend_equation_advanced = 0; +int GLAD_GL_KHR_blend_equation_advanced_coherent = 0; +int GLAD_GL_KHR_debug = 0; +int GLAD_GL_KHR_parallel_shader_compile = 0; + + + +PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; +PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; +PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; +PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; +PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; +PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; +PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; +PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; +PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; +PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; +PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; +PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; +PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; +PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; +PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; +PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; +PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL; +PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; +PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; +PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; +PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; +PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; +PFNGLBUFFERDATAPROC glad_glBufferData = NULL; +PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; +PFNGLCLEARPROC glad_glClear = NULL; +PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; +PFNGLCLEARCOLORPROC glad_glClearColor = NULL; +PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; +PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLCOLORMASKPROC glad_glColorMask = NULL; +PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; +PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; +PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; +PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; +PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; +PFNGLCREATESHADERPROC glad_glCreateShader = NULL; +PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; +PFNGLCULLFACEPROC glad_glCullFace = NULL; +PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL; +PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL; +PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL; +PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; +PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; +PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; +PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; +PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; +PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; +PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; +PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = 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; +PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; +PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; +PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; +PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; +PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawArraysInstancedBaseInstanceEXT = NULL; +PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; +PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; +PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseInstanceEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = NULL; +PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; +PFNGLENABLEPROC glad_glEnable = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; +PFNGLENDQUERYPROC glad_glEndQuery = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLFINISHPROC glad_glFinish = NULL; +PFNGLFLUSHPROC glad_glFlush = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; +PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glad_glFramebufferTexture2DMultisampleEXT = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; +PFNGLFRONTFACEPROC glad_glFrontFace = NULL; +PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; +PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; +PFNGLGENQUERIESPROC glad_glGenQueries = NULL; +PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; +PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; +PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; +PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; +PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; +PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; +PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; +PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; +PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; +PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; +PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL; +PFNGLGETERRORPROC glad_glGetError = NULL; +PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; +PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; +PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; +PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; +PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; +PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; +PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL; +PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL; +PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL; +PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; +PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; +PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL; +PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL; +PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL; +PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL; +PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; +PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; +PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; +PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; +PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; +PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; +PFNGLGETSTRINGPROC glad_glGetString = NULL; +PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; +PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; +PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; +PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; +PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; +PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; +PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; +PFNGLHINTPROC glad_glHint = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; +PFNGLISBUFFERPROC glad_glIsBuffer = NULL; +PFNGLISENABLEDPROC glad_glIsEnabled = NULL; +PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; +PFNGLISPROGRAMPROC glad_glIsProgram = NULL; +PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; +PFNGLISQUERYPROC glad_glIsQuery = NULL; +PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; +PFNGLISSAMPLERPROC glad_glIsSampler = NULL; +PFNGLISSHADERPROC glad_glIsShader = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLISTEXTUREPROC glad_glIsTexture = NULL; +PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; +PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; +PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; +PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; +PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; +PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR = NULL; +PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; +PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; +PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL; +PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; +PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; +PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; +PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL; +PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; +PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; +PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; +PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; +PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; +PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; +PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; +PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; +PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; +PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; +PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; +PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; +PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; +PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; +PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; +PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; +PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; +PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; +PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; +PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; +PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; +PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; +PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; +PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; +PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; +PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; +PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL; +PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; +PFNGLREADPIXELSPROC glad_glReadPixels = NULL; +PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; +PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; +PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; +PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = 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; +PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; +PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; +PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; +PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; +PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; +PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; +PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; +PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; +PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; +PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; +PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; +PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; +PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; +PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; +PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; +PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; +PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; +PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; +PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; +PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; +PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; +PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; +PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; +PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; +PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; +PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; +PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; +PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; +PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; +PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; +PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; +PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; +PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; +PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; +PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; +PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = 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; +PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; +PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; +PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; +PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; +PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL; +PFNGLVIEWPORTPROC glad_glViewport = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = 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_ES_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_3_0) return; + glad_glBeginQuery = (PFNGLBEGINQUERYPROC) load(userptr, "glBeginQuery"); + glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load(userptr, "glBeginTransformFeedback"); + glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load(userptr, "glBindBufferBase"); + glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load(userptr, "glBindBufferRange"); + glad_glBindSampler = (PFNGLBINDSAMPLERPROC) load(userptr, "glBindSampler"); + glad_glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load(userptr, "glBindTransformFeedback"); + glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load(userptr, "glBindVertexArray"); + glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load(userptr, "glBlitFramebuffer"); + glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load(userptr, "glClearBufferfi"); + glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load(userptr, "glClearBufferfv"); + glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load(userptr, "glClearBufferiv"); + glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load(userptr, "glClearBufferuiv"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load(userptr, "glClientWaitSync"); + glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load(userptr, "glCompressedTexImage3D"); + glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load(userptr, "glCompressedTexSubImage3D"); + glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load(userptr, "glCopyBufferSubData"); + glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load(userptr, "glCopyTexSubImage3D"); + glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC) load(userptr, "glDeleteQueries"); + glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load(userptr, "glDeleteSamplers"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC) load(userptr, "glDeleteSync"); + glad_glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load(userptr, "glDeleteTransformFeedbacks"); + glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load(userptr, "glDeleteVertexArrays"); + glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load(userptr, "glDrawArraysInstanced"); + glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load(userptr, "glDrawBuffers"); + glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load(userptr, "glDrawElementsInstanced"); + glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load(userptr, "glDrawRangeElements"); + glad_glEndQuery = (PFNGLENDQUERYPROC) load(userptr, "glEndQuery"); + glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load(userptr, "glEndTransformFeedback"); + glad_glFenceSync = (PFNGLFENCESYNCPROC) load(userptr, "glFenceSync"); + glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load(userptr, "glFlushMappedBufferRange"); + glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glFramebufferTextureLayer"); + glad_glGenQueries = (PFNGLGENQUERIESPROC) load(userptr, "glGenQueries"); + glad_glGenSamplers = (PFNGLGENSAMPLERSPROC) load(userptr, "glGenSamplers"); + glad_glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load(userptr, "glGenTransformFeedbacks"); + glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load(userptr, "glGenVertexArrays"); + glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load(userptr, "glGetActiveUniformBlockName"); + glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load(userptr, "glGetActiveUniformBlockiv"); + glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load(userptr, "glGetActiveUniformsiv"); + glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load(userptr, "glGetBufferParameteri64v"); + glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load(userptr, "glGetBufferPointerv"); + glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load(userptr, "glGetFragDataLocation"); + glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load(userptr, "glGetInteger64i_v"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC) load(userptr, "glGetInteger64v"); + glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load(userptr, "glGetIntegeri_v"); + glad_glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load(userptr, "glGetInternalformativ"); + glad_glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load(userptr, "glGetProgramBinary"); + glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load(userptr, "glGetQueryObjectuiv"); + glad_glGetQueryiv = (PFNGLGETQUERYIVPROC) load(userptr, "glGetQueryiv"); + glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load(userptr, "glGetSamplerParameterfv"); + glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load(userptr, "glGetSamplerParameteriv"); + glad_glGetStringi = (PFNGLGETSTRINGIPROC) load(userptr, "glGetStringi"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC) load(userptr, "glGetSynciv"); + glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load(userptr, "glGetTransformFeedbackVarying"); + glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load(userptr, "glGetUniformBlockIndex"); + glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load(userptr, "glGetUniformIndices"); + glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load(userptr, "glGetUniformuiv"); + glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load(userptr, "glGetVertexAttribIiv"); + glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load(userptr, "glGetVertexAttribIuiv"); + glad_glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load(userptr, "glInvalidateFramebuffer"); + glad_glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load(userptr, "glInvalidateSubFramebuffer"); + glad_glIsQuery = (PFNGLISQUERYPROC) load(userptr, "glIsQuery"); + glad_glIsSampler = (PFNGLISSAMPLERPROC) load(userptr, "glIsSampler"); + glad_glIsSync = (PFNGLISSYNCPROC) load(userptr, "glIsSync"); + glad_glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load(userptr, "glIsTransformFeedback"); + glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load(userptr, "glIsVertexArray"); + glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load(userptr, "glMapBufferRange"); + glad_glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load(userptr, "glPauseTransformFeedback"); + glad_glProgramBinary = (PFNGLPROGRAMBINARYPROC) load(userptr, "glProgramBinary"); + glad_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load(userptr, "glProgramParameteri"); + glad_glReadBuffer = (PFNGLREADBUFFERPROC) load(userptr, "glReadBuffer"); + glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glRenderbufferStorageMultisample"); + glad_glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load(userptr, "glResumeTransformFeedback"); + glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load(userptr, "glSamplerParameterf"); + glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load(userptr, "glSamplerParameterfv"); + glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load(userptr, "glSamplerParameteri"); + glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load(userptr, "glSamplerParameteriv"); + glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC) load(userptr, "glTexImage3D"); + glad_glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load(userptr, "glTexStorage2D"); + glad_glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load(userptr, "glTexStorage3D"); + glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load(userptr, "glTexSubImage3D"); + glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load(userptr, "glTransformFeedbackVaryings"); + glad_glUniform1ui = (PFNGLUNIFORM1UIPROC) load(userptr, "glUniform1ui"); + glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load(userptr, "glUniform1uiv"); + glad_glUniform2ui = (PFNGLUNIFORM2UIPROC) load(userptr, "glUniform2ui"); + glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load(userptr, "glUniform2uiv"); + glad_glUniform3ui = (PFNGLUNIFORM3UIPROC) load(userptr, "glUniform3ui"); + glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load(userptr, "glUniform3uiv"); + glad_glUniform4ui = (PFNGLUNIFORM4UIPROC) load(userptr, "glUniform4ui"); + glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load(userptr, "glUniform4uiv"); + glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load(userptr, "glUniformBlockBinding"); + glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load(userptr, "glUniformMatrix2x3fv"); + glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load(userptr, "glUniformMatrix2x4fv"); + glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load(userptr, "glUniformMatrix3x2fv"); + glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load(userptr, "glUniformMatrix3x4fv"); + glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load(userptr, "glUniformMatrix4x2fv"); + glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load(userptr, "glUniformMatrix4x3fv"); + glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load(userptr, "glUnmapBuffer"); + glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load(userptr, "glVertexAttribDivisor"); + glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load(userptr, "glVertexAttribI4i"); + glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load(userptr, "glVertexAttribI4iv"); + glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load(userptr, "glVertexAttribI4ui"); + glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load(userptr, "glVertexAttribI4uiv"); + glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load(userptr, "glVertexAttribIPointer"); + glad_glWaitSync = (PFNGLWAITSYNCPROC) load(userptr, "glWaitSync"); +} +static void glad_gl_load_GL_ES_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_ES_VERSION_3_1) return; + glad_glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load(userptr, "glActiveShaderProgram"); + glad_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load(userptr, "glBindImageTexture"); + glad_glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load(userptr, "glBindProgramPipeline"); + glad_glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load(userptr, "glBindVertexBuffer"); + glad_glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load(userptr, "glCreateShaderProgramv"); + glad_glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load(userptr, "glDeleteProgramPipelines"); + glad_glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load(userptr, "glDispatchCompute"); + glad_glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load(userptr, "glDispatchComputeIndirect"); + glad_glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load(userptr, "glDrawArraysIndirect"); + glad_glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load(userptr, "glDrawElementsIndirect"); + glad_glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load(userptr, "glFramebufferParameteri"); + glad_glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load(userptr, "glGenProgramPipelines"); + glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load(userptr, "glGetBooleani_v"); + glad_glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetFramebufferParameteriv"); + glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load(userptr, "glGetMultisamplefv"); + glad_glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load(userptr, "glGetProgramInterfaceiv"); + glad_glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load(userptr, "glGetProgramPipelineInfoLog"); + glad_glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load(userptr, "glGetProgramPipelineiv"); + glad_glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load(userptr, "glGetProgramResourceIndex"); + glad_glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load(userptr, "glGetProgramResourceLocation"); + glad_glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load(userptr, "glGetProgramResourceName"); + glad_glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load(userptr, "glGetProgramResourceiv"); + glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load(userptr, "glGetTexLevelParameterfv"); + glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load(userptr, "glGetTexLevelParameteriv"); + glad_glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load(userptr, "glIsProgramPipeline"); + glad_glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load(userptr, "glMemoryBarrier"); + glad_glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load(userptr, "glMemoryBarrierByRegion"); + glad_glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load(userptr, "glProgramUniform1f"); + glad_glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load(userptr, "glProgramUniform1fv"); + glad_glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load(userptr, "glProgramUniform1i"); + glad_glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load(userptr, "glProgramUniform1iv"); + glad_glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load(userptr, "glProgramUniform1ui"); + glad_glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load(userptr, "glProgramUniform1uiv"); + glad_glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load(userptr, "glProgramUniform2f"); + glad_glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load(userptr, "glProgramUniform2fv"); + glad_glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load(userptr, "glProgramUniform2i"); + glad_glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load(userptr, "glProgramUniform2iv"); + glad_glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load(userptr, "glProgramUniform2ui"); + glad_glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load(userptr, "glProgramUniform2uiv"); + glad_glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load(userptr, "glProgramUniform3f"); + glad_glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load(userptr, "glProgramUniform3fv"); + glad_glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load(userptr, "glProgramUniform3i"); + glad_glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load(userptr, "glProgramUniform3iv"); + glad_glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load(userptr, "glProgramUniform3ui"); + glad_glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load(userptr, "glProgramUniform3uiv"); + glad_glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load(userptr, "glProgramUniform4f"); + glad_glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load(userptr, "glProgramUniform4fv"); + glad_glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load(userptr, "glProgramUniform4i"); + glad_glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load(userptr, "glProgramUniform4iv"); + glad_glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load(userptr, "glProgramUniform4ui"); + glad_glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load(userptr, "glProgramUniform4uiv"); + glad_glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load(userptr, "glProgramUniformMatrix2fv"); + glad_glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load(userptr, "glProgramUniformMatrix2x3fv"); + glad_glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load(userptr, "glProgramUniformMatrix2x4fv"); + glad_glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load(userptr, "glProgramUniformMatrix3fv"); + glad_glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load(userptr, "glProgramUniformMatrix3x2fv"); + glad_glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load(userptr, "glProgramUniformMatrix3x4fv"); + glad_glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load(userptr, "glProgramUniformMatrix4fv"); + glad_glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load(userptr, "glProgramUniformMatrix4x2fv"); + glad_glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load(userptr, "glProgramUniformMatrix4x3fv"); + glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC) load(userptr, "glSampleMaski"); + glad_glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load(userptr, "glTexStorage2DMultisample"); + glad_glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load(userptr, "glUseProgramStages"); + glad_glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load(userptr, "glValidateProgramPipeline"); + glad_glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load(userptr, "glVertexAttribBinding"); + glad_glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load(userptr, "glVertexAttribFormat"); + glad_glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load(userptr, "glVertexAttribIFormat"); + glad_glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load(userptr, "glVertexBindingDivisor"); +} +static void glad_gl_load_GL_EXT_base_instance( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_base_instance) return; + glad_glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) load(userptr, "glDrawArraysInstancedBaseInstanceEXT"); + glad_glDrawElementsInstancedBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) load(userptr, "glDrawElementsInstancedBaseInstanceEXT"); + glad_glDrawElementsInstancedBaseVertexBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) load(userptr, "glDrawElementsInstancedBaseVertexBaseInstanceEXT"); +} +static void glad_gl_load_GL_EXT_multisampled_render_to_texture( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_EXT_multisampled_render_to_texture) return; + glad_glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) load(userptr, "glFramebufferTexture2DMultisampleEXT"); + glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glRenderbufferStorageMultisampleEXT"); +} +static void glad_gl_load_GL_KHR_blend_equation_advanced( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_blend_equation_advanced) return; + glad_glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC) load(userptr, "glBlendBarrierKHR"); +} +static void glad_gl_load_GL_KHR_debug( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_debug) return; + glad_glDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC) load(userptr, "glDebugMessageCallbackKHR"); + glad_glDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC) load(userptr, "glDebugMessageControlKHR"); + glad_glDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC) load(userptr, "glDebugMessageInsertKHR"); + glad_glGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC) load(userptr, "glGetDebugMessageLogKHR"); + glad_glGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC) load(userptr, "glGetObjectLabelKHR"); + glad_glGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC) load(userptr, "glGetObjectPtrLabelKHR"); + glad_glGetPointervKHR = (PFNGLGETPOINTERVKHRPROC) load(userptr, "glGetPointervKHR"); + glad_glObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC) load(userptr, "glObjectLabelKHR"); + glad_glObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC) load(userptr, "glObjectPtrLabelKHR"); + glad_glPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC) load(userptr, "glPopDebugGroupKHR"); + glad_glPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC) load(userptr, "glPushDebugGroupKHR"); +} +static void glad_gl_load_GL_KHR_parallel_shader_compile( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_GL_KHR_parallel_shader_compile) return; + glad_glMaxShaderCompilerThreadsKHR = (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) load(userptr, "glMaxShaderCompilerThreadsKHR"); +} + + + +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_EXT_base_instance = glad_gl_has_extension(exts, exts_i, "GL_EXT_base_instance"); + GLAD_GL_EXT_clip_cull_distance = glad_gl_has_extension(exts, exts_i, "GL_EXT_clip_cull_distance"); + GLAD_GL_EXT_multisampled_render_to_texture = glad_gl_has_extension(exts, exts_i, "GL_EXT_multisampled_render_to_texture"); + GLAD_GL_KHR_blend_equation_advanced = glad_gl_has_extension(exts, exts_i, "GL_KHR_blend_equation_advanced"); + GLAD_GL_KHR_blend_equation_advanced_coherent = glad_gl_has_extension(exts, exts_i, "GL_KHR_blend_equation_advanced_coherent"); + GLAD_GL_KHR_debug = glad_gl_has_extension(exts, exts_i, "GL_KHR_debug"); + GLAD_GL_KHR_parallel_shader_compile = glad_gl_has_extension(exts, exts_i, "GL_KHR_parallel_shader_compile"); + + 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; + GLAD_GL_ES_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_ES_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + + 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); + glad_gl_load_GL_ES_VERSION_3_0(load, userptr); + glad_gl_load_GL_ES_VERSION_3_1(load, userptr); + + if (!glad_gl_find_extensions_gles2()) return 0; + glad_gl_load_GL_EXT_base_instance(load, userptr); + glad_gl_load_GL_EXT_multisampled_render_to_texture(load, userptr); + glad_gl_load_GL_KHR_blend_equation_advanced(load, userptr); + glad_gl_load_GL_KHR_debug(load, userptr); + glad_gl_load_GL_KHR_parallel_shader_compile(load, userptr); + + + + return version; +} + + +int gladLoadGLES2( GLADloadfunc load) { + return gladLoadGLES2UserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +} + + + + + +#ifdef GLAD_GLES2 + +#ifndef GLAD_LOADER_LIBRARY_C_ +#define GLAD_LOADER_LIBRARY_C_ + +#include +#include + +#if GLAD_PLATFORM_WIN32 +#include +#else +#include +#endif + + +static void* glad_get_dlopen_handle(const char *lib_names[], int length) { + void *handle = NULL; + int i; + + for (i = 0; i < length; ++i) { +#if GLAD_PLATFORM_WIN32 + #if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR) malloc(buffer_size); + if (buffer != NULL) { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) { + handle = (void*) LoadPackagedLibrary(buffer, 0); + } + free((void*) buffer); + } + #else + handle = (void*) LoadLibraryA(lib_names[i]); + #endif +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) { + return handle; + } + } + + return NULL; +} + +static void glad_close_dlopen_handle(void* handle) { + if (handle != NULL) { +#if GLAD_PLATFORM_WIN32 + FreeLibrary((HMODULE) handle); +#else + dlclose(handle); +#endif + } +} + +static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { + if (handle == NULL) { + return NULL; + } + +#if GLAD_PLATFORM_WIN32 + return (GLADapiproc) GetProcAddress((HMODULE) handle, name); +#else + return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); +#endif +} + +#endif /* GLAD_LOADER_LIBRARY_C_ */ + +#if GLAD_PLATFORM_EMSCRIPTEN +#ifndef GLAD_EGL_H_ + typedef void (*__eglMustCastToProperFunctionPointerType)(void); + typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *name); +#endif + extern __eglMustCastToProperFunctionPointerType emscripten_GetProcAddress(const char *name); +#elif defined(GLAD_GLES2_USE_SYSTEM_EGL) + #include + typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *name); +#else + #include +#endif + + +struct _glad_gles2_userptr { + void *handle; + PFNEGLGETPROCADDRESSPROC get_proc_address_ptr; +}; + + +static GLADapiproc glad_gles2_get_proc(void *vuserptr, const char* name) { + struct _glad_gles2_userptr userptr = *(struct _glad_gles2_userptr*) vuserptr; + GLADapiproc result = NULL; + +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(&glad_dlsym_handle); +#else + result = glad_dlsym_handle(userptr.handle, name); +#endif + if (result == NULL) { + result = userptr.get_proc_address_ptr(name); + } + + return result; +} + +static void* _glad_GLES2_loader_handle = NULL; + +static void* glad_gles2_dlopen_handle(void) { +#if GLAD_PLATFORM_EMSCRIPTEN +#elif GLAD_PLATFORM_APPLE + static const char *NAMES[] = {"libGLESv2.dylib"}; +#elif GLAD_PLATFORM_WIN32 + static const char *NAMES[] = {"GLESv2.dll", "libGLESv2.dll"}; +#else + static const char *NAMES[] = {"libGLESv2.so.2", "libGLESv2.so"}; +#endif + +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(&glad_get_dlopen_handle); + return NULL; +#else + if (_glad_GLES2_loader_handle == NULL) { + _glad_GLES2_loader_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + } + + return _glad_GLES2_loader_handle; +#endif +} + +static struct _glad_gles2_userptr glad_gles2_build_userptr(void *handle) { + struct _glad_gles2_userptr userptr; +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(handle); + userptr.get_proc_address_ptr = emscripten_GetProcAddress; +#else + userptr.handle = handle; + userptr.get_proc_address_ptr = eglGetProcAddress; +#endif + return userptr; +} + +int gladLoaderLoadGLES2(void) { + int version = 0; + void *handle = NULL; + int did_load = 0; + struct _glad_gles2_userptr userptr; + +#if GLAD_PLATFORM_EMSCRIPTEN + GLAD_UNUSED(handle); + GLAD_UNUSED(did_load); + GLAD_UNUSED(&glad_gles2_dlopen_handle); + GLAD_UNUSED(&glad_gles2_build_userptr); + userptr.get_proc_address_ptr = emscripten_GetProcAddress; + version = gladLoadGLES2UserPtr(glad_gles2_get_proc, &userptr); +#else +#ifndef GLAD_GLES2_USE_SYSTEM_EGL + if (eglGetProcAddress == NULL) { + return 0; + } +#endif + did_load = _glad_GLES2_loader_handle == NULL; + handle = glad_gles2_dlopen_handle(); + if (handle != NULL) { + userptr = glad_gles2_build_userptr(handle); + + version = gladLoadGLES2UserPtr(glad_gles2_get_proc, &userptr); + + if (!version && did_load) { + gladLoaderUnloadGLES2(); + } + } +#endif + + return version; +} + + + +void gladLoaderUnloadGLES2(void) { + if (_glad_GLES2_loader_handle != NULL) { + glad_close_dlopen_handle(_glad_GLES2_loader_handle); + _glad_GLES2_loader_handle = NULL; + } +} + +#endif /* GLAD_GLES2 */ + +#ifdef __cplusplus +} +#endif diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.frag.h new file mode 100644 index 000000000..66a3537ea --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.frag.h @@ -0,0 +1,120 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xyzw +// SV_Position 0 xyzw 1 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +ps_5_0 +dcl_globalFlags refactoringAllowed +dcl_input_ps linear noperspective v0.xyzw +dcl_output o0.xyzw +mov o0.xyzw, v0.xyzw +ret +// Approximately 2 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 202, 17, + 242, 193, 235, 99, 30, 245, + 188, 236, 148, 16, 208, 141, + 89, 243, 1, 0, 0, 0, + 12, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 160, 0, 0, 0, 248, 0, + 0, 0, 44, 1, 0, 0, + 112, 1, 0, 0, 82, 68, + 69, 70, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 255, 255, 0, 1, 0, 0, + 60, 0, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, + 48, 46, 49, 0, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 15, + 0, 0, 65, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 83, + 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 83, 72, 69, 88, 60, 0, + 0, 0, 80, 0, 0, 0, + 15, 0, 0, 0, 106, 8, + 0, 1, 98, 32, 0, 3, + 242, 16, 16, 0, 0, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 0, 0, + 0, 0, 70, 30, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.vert.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.vert.h new file mode 100644 index 000000000..afeb76547 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/color_ramp.vert.h @@ -0,0 +1,523 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer MB +// { +// +// struct +// { +// +// float Pb; // Offset: 0 +// float Yc; // Offset: 4 +// float Re; // Offset: 8 +// float Se; // Offset: 12 +// uint m6; // Offset: 16 +// uint mg; // Offset: 20 +// uint De; // Offset: 24 +// uint Ee; // Offset: 28 +// int4 U7; // Offset: 32 +// float2 jg; // Offset: 48 +// float2 Zc; // Offset: 56 +// uint W1; // Offset: 64 +// float ng; // Offset: 68 +// uint Y5; // Offset: 72 +// float O2; // Offset: 76 +// float ad; // Offset: 80 +// uint ye; // Offset: 84 +// float v3; // Offset: 88 +// float w3; // Offset: 92 +// float bd; // Offset: 96 +// uint gg; // Offset: 100 +// +// } k; // Offset: 0 Size: 104 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// MB cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// AC 0 xyzw 0 NONE uint xyzw +// SV_VertexID 0 x 1 VERTID uint x +// SV_InstanceID 0 x 2 INSTID uint +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xyzw +// SV_Position 0 xyzw 1 POS float xyzw +// +vs_5_0 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[1], immediateIndexed +dcl_input v0.xyzw +dcl_input_sgv v1.x, vertex_id +dcl_output o0.xyzw +dcl_output_siv o1.xyzw, position +dcl_temps 2 +ushr r0.x, v1.x, l(1) +ige r0.y, l(1), r0.x +ieq r0.xz, r0.xxxx, l(0, 0, 3, 0) +movc r1.z, r0.y, v0.z, v0.w +ushr r1.xyw, r1.zzzz, l(16, 8, 0, 24) +and r1.xyzw, r1.xyzw, l(255, 255, 255, 255) +utof r1.xyzw, r1.xyzw +mul o0.xyzw, r1.xyzw, l(0.003922, 0.003922, 0.003922, 0.003922) +ushr r0.w, v0.x, l(16) +and r1.xyzw, v0.xyyy, l(0x0000ffff, 0x1fffffff, 0x80000000, 0x20000000) +movc r0.y, r0.y, r1.x, r0.w +utof r0.y, r0.y +mad r0.w, r0.y, l(0.000015), l(-0.001953) +mul r0.y, r0.y, l(0.000015) +movc r0.w, r1.w, l(0), r0.w +ine r1.x, r1.z, l(0) +and r0.x, r0.x, r1.x +movc r0.x, r0.x, r0.w, r0.y +add r0.y, r0.x, l(0.001953) +movc r0.y, r1.w, l(1.000000), r0.y +utof r0.w, r1.y +and r1.x, v0.y, l(0x40000000) +ine r1.x, r1.x, l(0) +and r0.z, r0.z, r1.x +movc r0.x, r0.z, r0.y, r0.x +mad o1.x, r0.x, l(2.000000), l(-1.000000) +and r0.x, v1.x, l(1) +movc r0.xy, r0.xxxx, l(1.000000,0,0,0), l(0,1.000000,0,0) +lt r0.z, cb0[0].x, l(0.000000) +movc r0.x, r0.z, r0.y, r0.x +add r0.x, r0.x, r0.w +lt r0.y, l(0.000000), cb0[0].x +iadd r0.y, -r0.y, r0.z +itof r0.y, r0.y +mad o1.y, r0.x, cb0[0].x, -r0.y +mov o1.zw, l(0,0,0,1.000000) +ret +// Approximately 37 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 42, 125, + 131, 204, 217, 30, 216, 32, + 211, 77, 174, 13, 56, 115, + 5, 11, 1, 0, 0, 0, + 140, 9, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 36, 3, 0, 0, 156, 3, + 0, 0, 244, 3, 0, 0, + 240, 8, 0, 0, 82, 68, + 69, 70, 232, 2, 0, 0, + 1, 0, 0, 0, 96, 0, + 0, 0, 1, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 254, 255, 0, 1, 0, 0, + 192, 2, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 77, 66, 0, 171, + 92, 0, 0, 0, 1, 0, + 0, 0, 120, 0, 0, 0, + 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 160, 0, 0, 0, 0, 0, + 0, 0, 104, 0, 0, 0, + 2, 0, 0, 0, 156, 2, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 107, 0, + 60, 117, 110, 110, 97, 109, + 101, 100, 62, 0, 80, 98, + 0, 102, 108, 111, 97, 116, + 0, 171, 171, 171, 0, 0, + 3, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 175, 0, 0, 0, 89, 99, + 0, 82, 101, 0, 83, 101, + 0, 109, 54, 0, 100, 119, + 111, 114, 100, 0, 171, 171, + 0, 0, 19, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 232, 0, 0, 0, + 109, 103, 0, 68, 101, 0, + 69, 101, 0, 85, 55, 0, + 105, 110, 116, 52, 0, 171, + 171, 171, 1, 0, 2, 0, + 1, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 1, + 0, 0, 106, 103, 0, 102, + 108, 111, 97, 116, 50, 0, + 171, 171, 1, 0, 3, 0, + 1, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79, 1, + 0, 0, 90, 99, 0, 87, + 49, 0, 110, 103, 0, 89, + 53, 0, 79, 50, 0, 97, + 100, 0, 121, 101, 0, 118, + 51, 0, 119, 51, 0, 98, + 100, 0, 103, 103, 0, 171, + 171, 171, 172, 0, 0, 0, + 184, 0, 0, 0, 0, 0, + 0, 0, 220, 0, 0, 0, + 184, 0, 0, 0, 4, 0, + 0, 0, 223, 0, 0, 0, + 184, 0, 0, 0, 8, 0, + 0, 0, 226, 0, 0, 0, + 184, 0, 0, 0, 12, 0, + 0, 0, 229, 0, 0, 0, + 240, 0, 0, 0, 16, 0, + 0, 0, 20, 1, 0, 0, + 240, 0, 0, 0, 20, 0, + 0, 0, 23, 1, 0, 0, + 240, 0, 0, 0, 24, 0, + 0, 0, 26, 1, 0, 0, + 240, 0, 0, 0, 28, 0, + 0, 0, 29, 1, 0, 0, + 40, 1, 0, 0, 32, 0, + 0, 0, 76, 1, 0, 0, + 88, 1, 0, 0, 48, 0, + 0, 0, 124, 1, 0, 0, + 88, 1, 0, 0, 56, 0, + 0, 0, 127, 1, 0, 0, + 240, 0, 0, 0, 64, 0, + 0, 0, 130, 1, 0, 0, + 184, 0, 0, 0, 68, 0, + 0, 0, 133, 1, 0, 0, + 240, 0, 0, 0, 72, 0, + 0, 0, 136, 1, 0, 0, + 184, 0, 0, 0, 76, 0, + 0, 0, 139, 1, 0, 0, + 184, 0, 0, 0, 80, 0, + 0, 0, 142, 1, 0, 0, + 240, 0, 0, 0, 84, 0, + 0, 0, 145, 1, 0, 0, + 184, 0, 0, 0, 88, 0, + 0, 0, 148, 1, 0, 0, + 184, 0, 0, 0, 92, 0, + 0, 0, 151, 1, 0, 0, + 184, 0, 0, 0, 96, 0, + 0, 0, 154, 1, 0, 0, + 240, 0, 0, 0, 100, 0, + 0, 0, 5, 0, 0, 0, + 1, 0, 26, 0, 0, 0, + 21, 0, 160, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 162, 0, + 0, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, + 73, 83, 71, 78, 112, 0, + 0, 0, 3, 0, 0, 0, + 8, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 15, 15, 0, 0, 83, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 1, 0, 0, 95, 0, + 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 65, 67, + 0, 83, 86, 95, 86, 101, + 114, 116, 101, 120, 73, 68, + 0, 83, 86, 95, 73, 110, + 115, 116, 97, 110, 99, 101, + 73, 68, 0, 171, 171, 171, + 79, 83, 71, 78, 80, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 65, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 15, 0, 0, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 83, 86, 95, 80, 111, + 115, 105, 116, 105, 111, 110, + 0, 171, 171, 171, 83, 72, + 69, 88, 244, 4, 0, 0, + 80, 0, 1, 0, 61, 1, + 0, 0, 106, 8, 0, 1, + 89, 0, 0, 4, 70, 142, + 32, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 95, 0, + 0, 3, 242, 16, 16, 0, + 0, 0, 0, 0, 96, 0, + 0, 4, 18, 16, 16, 0, + 1, 0, 0, 0, 6, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 103, 0, 0, 4, + 242, 32, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 104, 0, 0, 2, 2, 0, + 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 33, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 32, 0, + 0, 10, 82, 0, 16, 0, + 0, 0, 0, 0, 6, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 66, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 16, + 16, 0, 0, 0, 0, 0, + 58, 16, 16, 0, 0, 0, + 0, 0, 85, 0, 0, 10, + 178, 0, 16, 0, 1, 0, + 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, + 8, 0, 0, 0, 0, 0, + 0, 0, 24, 0, 0, 0, + 1, 0, 0, 10, 242, 0, + 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, + 255, 0, 0, 0, 255, 0, + 0, 0, 255, 0, 0, 0, + 255, 0, 0, 0, 86, 0, + 0, 5, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 14, + 16, 0, 1, 0, 0, 0, + 56, 0, 0, 10, 242, 32, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, + 129, 128, 128, 59, 129, 128, + 128, 59, 129, 128, 128, 59, + 129, 128, 128, 59, 85, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 16, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 16, 0, + 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 1, 0, + 0, 0, 70, 21, 16, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 255, 255, 0, 0, + 255, 255, 255, 31, 0, 0, + 0, 128, 0, 0, 0, 32, + 55, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 9, + 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 55, + 1, 64, 0, 0, 0, 0, + 0, 187, 56, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 55, + 55, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 39, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 55, 0, 0, 9, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 59, + 55, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 26, 0, + 16, 0, 0, 0, 0, 0, + 86, 0, 0, 5, 130, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 1, 0, + 0, 0, 26, 16, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, + 39, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 55, 0, 0, 9, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 9, + 18, 32, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, + 1, 64, 0, 0, 0, 0, + 128, 191, 1, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 55, 0, 0, 15, 50, 0, + 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 0, 0, + 49, 0, 0, 8, 66, 0, + 16, 0, 0, 0, 0, 0, + 10, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 49, 0, 0, 8, 34, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 10, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 8, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 43, 0, + 0, 5, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 50, 0, 0, 11, 34, 32, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 10, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, + 194, 32, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 128, 63, 62, 0, + 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 37, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 9, 0, 0, 0, + 5, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h new file mode 100644 index 000000000..666aa6c85 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas.vert.h @@ -0,0 +1,2434 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer MB +// { +// +// struct +// { +// +// float Pb; // Offset: 0 +// float Yc; // Offset: 4 +// float Re; // Offset: 8 +// float Se; // Offset: 12 +// uint m6; // Offset: 16 +// uint mg; // Offset: 20 +// uint De; // Offset: 24 +// uint Ee; // Offset: 28 +// int4 U7; // Offset: 32 +// float2 jg; // Offset: 48 +// float2 Zc; // Offset: 56 +// uint W1; // Offset: 64 +// float ng; // Offset: 68 +// uint Y5; // Offset: 72 +// float O2; // Offset: 76 +// float ad; // Offset: 80 +// uint ye; // Offset: 84 +// float v3; // Offset: 88 +// float w3; // Offset: 92 +// float bd; // Offset: 96 +// uint gg; // Offset: 100 +// +// } k; // Offset: 0 Size: 104 +// +// } +// +// cbuffer ei +// { +// +// uint ug; // Offset: 0 Size: 4 +// uint IFfi; // Offset: 4 Size: 4 [unused] +// uint IFgi; // Offset: 8 Size: 4 [unused] +// uint IFhi; // Offset: 12 Size: 4 [unused] +// +// } +// +// Resource bind info for LB +// { +// +// uint4 $Element; // Offset: 0 Size: 16 +// +// } +// +// Resource bind info for XC +// { +// +// uint4 $Element; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// LB texture struct r/o t3 1 +// XC texture struct r/o t6 1 +// BC texture uint4 2d t8 1 +// MB cbuffer NA NA cb0 1 +// ei cbuffer NA NA cb1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TB 0 xyzw 0 NONE float xyzw +// UB 0 xyzw 1 NONE float xyz +// SV_VertexID 0 x 2 VERTID uint +// SV_InstanceID 0 x 3 INSTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xyzw +// SV_Position 0 xyzw 1 POS float xyzw +// +vs_5_0 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[7], immediateIndexed +dcl_constantbuffer CB1[1], immediateIndexed +dcl_resource_structured t3, 16 +dcl_resource_structured t6, 16 +dcl_resource_texture2d (uint,uint,uint,uint) t8 +dcl_input v0.xyzw +dcl_input v1.xyz +dcl_input_sgv v3.x, instance_id +dcl_output o0.xyzw +dcl_output_siv o1.xyzw, position +dcl_temps 14 +iadd r0.x, v3.x, cb1[0].x +ftoi r1.x, v0.x +ishr r0.y, v0.w, l(2) +and r0.z, v0.w, l(3) +iadd r0.w, r0.y, l(-1) +imin r0.w, r0.w, r1.x +imad r0.x, r0.x, r0.y, r0.w +and r2.x, r0.x, l(2047) +ishr r2.y, r0.x, l(11) +mov r2.zw, l(0,0,0,0) +ld_indexable(texture2d)(uint,uint,uint,uint) r2.xyzw, r2.xyzw, t8.xyzw +and r3.xy, r2.wwww, l(0x0000ffff, 0x00800000, 0, 0) +umax r0.y, r3.x, l(1) +iadd r0.y, r0.y, l(-1) +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r4.xyzw, r0.y, l(0), t6.xyzw +bfi r3.xz, l(16, 0, 16, 0), l(2, 0, 2, 0), r4.zzzz, l(0, 0, 2, 0) +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r5.xyzw, r3.x, l(0), t3.xyzw +iadd r0.y, r3.x, l(1) +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r6.xyzw, r0.y, l(0), t3.xyzw +ftoi r7.x, v1.x +mov r7.yz, v1.yyzy +mov r1.yz, v0.yyzy +movc r1.xyz, r3.yyyy, r7.zxyz, r1.zxyz +ine r0.y, r0.w, r1.y +if_nz r0.y + iadd r0.y, r0.x, r1.y + iadd r0.y, -r0.w, r0.y + and r7.x, r0.y, l(2047) + ishr r7.y, r0.y, l(11) + mov r7.zw, l(0,0,0,0) + ld_indexable(texture2d)(uint,uint,uint,uint) r7.xyzw, r7.xyzw, t8.wxyz + and r0.w, r7.x, l(0x0080ffff) + and r3.x, r2.w, l(0x0080ffff) + ine r0.w, r0.w, r3.x + if_nz r0.w + eq r0.w, r6.z, l(0.000000) + ne r3.x, r4.x, l(0.000000) + or r0.w, r0.w, r3.x + if_nz r0.w + and r8.x, r4.w, l(2047) + ishr r8.y, r4.w, l(11) + mov r8.zw, l(0,0,0,0) + ld_indexable(texture2d)(uint,uint,uint,uint) r7.xyzw, r8.xyzw, t8.wxyz + mov r0.x, r4.w + mov r2.xyz, r7.yzwy + else + mov r7.x, r2.w + endif + else + mov r0.x, r0.y + mov r2.xyz, r7.yzwy + endif + and r0.y, r7.x, l(0xff7fffff) + iadd r2.w, r3.y, r0.y +endif +and r0.y, r2.w, l(0x1c000000) +ieq r0.w, r0.y, l(0x04000000) +ieq r3.x, r0.z, l(0) +and r0.w, r0.w, r3.x +if_nz r0.w + and r3.x, r2.z, l(0x0000ffff) + utof r7.z, r3.x + ushr r3.x, r2.z, l(16) + utof r3.x, r3.x + add r3.y, -r7.z, l(-1.000000) + add r3.w, -r7.z, r3.x + add r3.w, r3.w, l(1.000000) + ftoi r8.xy, r3.ywyy + and r3.y, r2.w, l(0x00800000) + ineg r8.zw, r8.xxxy + movc r3.yw, r3.yyyy, r8.zzzw, r8.xxxy + iadd r3.yw, r0.xxxx, r3.yyyw + and r8.xy, r3.ywyy, l(2047, 2047, 0, 0) + ishr r9.xy, r3.ywyy, l(11, 11, 0, 0) + mov r8.z, r9.x + mov r8.w, l(0) + ld_indexable(texture2d)(uint,uint,uint,uint) r3.yw, r8.xzww, t8.xzyw + mov r9.zw, r8.yyyw + ld_indexable(texture2d)(uint,uint,uint,uint) r8.xy, r9.zyww, t8.zwxy + and r4.z, r8.y, l(0x0080ffff) + and r3.w, r3.w, l(0x0080ffff) + ine r3.w, r3.w, r4.z + if_nz r3.w + and r9.x, r4.w, l(2047) + ishr r9.y, r4.w, l(11) + mov r9.zw, l(0,0,0,0) + ld_indexable(texture2d)(uint,uint,uint,uint) r8.x, r9.xyzw, t8.zwxy + endif + add r3.w, -r3.y, r8.x + lt r4.z, l(3.141593), |r3.w| + lt r4.w, l(0.000000), r3.w + lt r8.y, r3.w, l(0.000000) + iadd r4.w, -r4.w, r8.y + itof r4.w, r4.w + mad r4.w, -r4.w, l(6.283185), r3.w + movc r9.y, r4.z, r4.w, r3.w + add r3.xw, r3.xxxx, l(-2.000000, 0.000000, 0.000000, -3.000000) + mul r4.z, r3.x, |r9.y| + mul r4.z, r4.z, l(0.318310) + round_ne r4.z, r4.z + max r4.z, r4.z, l(1.000000) + min r10.w, r3.w, r4.z + add r7.w, r3.x, -r10.w + ge r3.x, r7.w, r7.z + lt r3.w, l(0.000000), r9.y + lt r4.z, r9.y, l(0.000000) + iadd r3.w, -r3.w, r4.z + itof r3.w, r3.w + mad r3.w, r3.w, l(3.141593), -r9.y + mov r7.y, -r3.w + eq r3.w, r7.w, r7.z + movc r7.x, r3.w, -r1.z, r1.z + add r4.zw, r7.wwww, l(0.000000, 0.000000, 1.000000, 2.000000) + eq r3.w, r4.z, r7.z + add r10.z, -r4.w, r7.z + mov r10.x, r1.z + movc r9.xzw, r3.wwww, l(0,0,0,0), r10.xxzw + movc r7.xyzw, r3.xxxx, r7.xyzw, r9.xyzw + eq r3.x, r7.w, r7.z + div r3.w, r7.z, r7.w + mad r3.w, r7.y, r3.w, r3.y + movc r2.z, r3.x, r8.x, r3.w + mov r3.x, r7.x + mov r7.x, r3.y +else + mov r3.x, r1.z +endif +sincos r8.x, r9.x, r2.z +mov r8.y, -r9.x +ne r3.yw, r6.wwwz, l(0.000000, 0.000000, 0.000000, 0.000000) +dp2 r9.x, r8.xyxx, r5.xzxx +dp2 r9.y, r8.xyxx, r5.ywyy +dp2 r4.z, r9.xyxx, r9.xyxx +sqrt r4.w, r4.z +div r4.w, l(1.000000, 1.000000, 1.000000, 1.000000), r4.w +max r4.w, r4.w, r6.w +movc r3.y, r3.y, r4.w, r6.w +if_nz r3.w + mul r3.w, r5.z, r5.y + mad r3.w, r5.x, r5.w, -r3.w + lt r4.w, l(0.000000), r3.w + lt r3.w, r3.w, l(0.000000) + iadd r3.w, -r4.w, r3.w + itof r3.w, r3.w + mul r3.w, r3.w, r3.x + and r7.zw, r2.wwww, l(0, 0, 0x00100000, 0x00080000) + min r4.w, r3.w, l(0.000000) + movc r3.w, r7.z, r4.w, r3.w + max r4.w, r3.w, l(0.000000) + movc r3.w, r7.w, r4.w, r3.w + ne r4.w, r3.y, l(0.000000) + add r6.w, |r9.y|, |r9.x| + div r4.z, l(1.000000, 1.000000, 1.000000, 1.000000), r4.z + mul r4.z, r4.z, r6.w + mul r4.z, r4.z, l(0.500000) + movc r9.x, r4.w, r3.y, r4.z + lt r4.z, r6.z, r9.x + eq r6.w, r3.y, l(0.000000) + and r4.z, r4.z, r6.w + div r9.y, r6.z, r9.x + mov r10.x, r6.z + mov r10.y, l(1.000000) + movc r6.zw, r4.zzzz, r9.xxxy, r10.xxxy + add r4.z, r9.x, r6.z + mul r8.zw, r4.zzzz, r8.xxxy + mul r10.x, r3.w, r4.z + add r7.w, r9.x, r9.x + div r7.w, l(1.000000, 1.000000, 1.000000, 1.000000), r7.w + mov r10.y, -r10.x + add r9.yz, r6.zzzz, r10.xxyx + mad r9.yz, r7.wwww, r9.yyzy, l(0.000000, 0.500000, 0.500000, 0.000000) + ult r7.w, l(0x08000000), r0.y + if_nz r7.w + and r10.xyzw, r2.wwww, l(0x00400000, 0x00800000, 0x02000000, 0x00200000) + movc r11.xyz, r10.xxzx, l(2,-2,1.000000,0), l(-2,2,0.250000,0) + movc r7.w, r10.y, r11.y, r11.x + iadd r0.x, r0.x, r7.w + and r12.x, r0.x, l(2047) + ishr r12.y, r0.x, l(11) + mov r12.zw, l(0,0,0,0) + ld_indexable(texture2d)(uint,uint,uint,uint) r0.x, r12.xyzw, t8.zxyw + add r0.x, -r2.z, r0.x + lt r7.w, l(3.141593), |r0.x| + add r10.y, -|r0.x|, l(6.283185) + movc r0.x, r7.w, r10.y, |r0.x| + ine r7.w, r10.x, l(0) + ine r10.x, r7.z, l(0) + ieq r7.w, r7.w, r10.x + movc r7.w, r7.w, l(-0.500000), l(0.500000) + mad r7.w, r0.x, r7.w, r2.z + sincos r10.x, r11.x, r7.w + mov r10.y, -r11.x + dp2 r11.x, r10.xyxx, r5.xzxx + dp2 r11.y, r10.xyxx, r5.ywyy + add r7.w, |r11.y|, |r11.x| + dp2 r10.z, r11.xyxx, r11.xyxx + div r10.z, l(1.000000, 1.000000, 1.000000, 1.000000), r10.z + mul r7.w, r7.w, r10.z + mul r0.x, r0.x, l(0.500000) + sincos null, r0.x, r0.x + ieq r11.xy, r0.yyyy, l(0x14000000, 0x10000000, 0, 0) + ge r0.y, r0.x, l(0.250000) + and r0.y, r0.y, r11.y + or r0.y, r0.y, r11.x + max r10.z, r11.z, r0.x + div r10.z, l(1.000000, 1.000000, 1.000000, 1.000000), r10.z + mul r10.z, r6.z, r10.z + mul r11.x, r7.w, l(0.500000) + mad r6.z, r6.z, r0.x, r11.x + movc r0.y, r0.y, r10.z, r6.z + mad r0.y, r7.w, l(0.500000), r0.y + mul r6.z, r9.x, l(0.125000) + mad r6.z, r0.y, r0.x, r6.z + ge r6.z, r6.z, r4.z + div r0.x, l(1.000000, 1.000000, 1.000000, 1.000000), r0.x + mul r0.x, r0.x, r4.z + mul r11.xyzw, r0.xxyy, r10.xyyx + dp2 r12.x, r8.zwzz, r8.zwzz + dp2 r12.y, r11.zwzz, r11.zwzz + mul r0.x, r8.w, r11.w + mad r0.x, r8.z, r11.z, -r0.x + div r0.x, l(1.000000, 1.000000, 1.000000, 1.000000), r0.x + mul r13.xz, r11.zzwz, l(1.000000, 0.000000, -1.000000, 0.000000) + mul r13.yw, r8.wwwz, l(0.000000, -1.000000, 0.000000, 1.000000) + mul r13.xyzw, r0.xxxx, r13.xyzw + dp2 r13.x, r13.xyxx, r12.xyxx + dp2 r13.y, r13.zwzz, r12.xyxx + movc r11.xy, r6.zzzz, r11.xyxx, r13.xyxx + movc r8.zw, r10.wwww, r11.xxxy, r8.zzzw + mul r10.zw, |r3.wwww|, r8.zzzw + dp2 r0.x, r10.zwzz, r10.xyxx + add r0.x, -r0.x, r0.y + div r9.w, r0.x, r7.w + movc r9.yz, r7.zzzz, r9.yywy, r9.wwzw + endif + mul r0.xy, r6.wwww, r9.yzyy + max r10.y, r0.y, l(0.000100) + mad r0.y, -r9.y, r6.w, l(-2.000000) + movc r10.x, r4.w, r0.y, r0.x + mul r0.xy, r3.wwww, r8.zwzz + dp2 r9.x, r0.xyxx, r5.xzxx + dp2 r9.y, r0.xyxx, r5.ywyy + ine r0.x, r0.z, l(0) + mov o0.zw, l(0,0,0,0) +else + ne r0.y, r3.y, l(0.000000) + if_nz r0.y + lt r0.y, r7.y, l(0.000000) + add r11.x, r7.y, r7.x + mov r11.y, -r7.y + movc r4.zw, r0.yyyy, r11.xxxy, r7.xxxy + add r0.y, r2.z, -r4.z + add r0.y, r0.y, l(1.570796) + mul r0.y, r0.y, l(0.159155) + ge r2.z, r0.y, -r0.y + frc r0.y, |r0.y| + movc r0.y, r2.z, r0.y, -r0.y + mad r0.y, r0.y, l(6.283185), l(-1.570796) + max r0.y, r0.y, l(0.000000) + min r0.y, r4.w, r0.y + mul r2.z, r4.w, l(0.500000) + lt r2.z, r2.z, r0.y + add r3.w, -r0.y, r4.w + movc r0.y, r2.z, r3.w, r0.y + sincos r7.x, r11.x, r0.y + mov r7.y, r11.x + mad r6.zw, -r7.xxxy, |r3.xxxx|, l(0.000000, 0.000000, 1.000000, 1.000000) + mul r7.xy, r6.zwzz, l(0.500000, 0.500000, 0.000000, 0.000000) + add r0.y, r4.w, l(-1.570796) + lt r0.y, |r0.y|, l(0.001000) + sincos r11.x, r12.x, r4.w + div r2.z, r11.x, r12.x + add r3.w, -r4.w, l(1.570796) + lt r4.z, l(0.000000), r3.w + lt r3.w, r3.w, l(0.000000) + iadd r3.w, -r4.z, r3.w + itof r3.w, r3.w + max r4.z, |r2.z|, l(0.000001) + div r4.z, r3.w, r4.z + ge r3.w, r4.z, l(0.000000) + mad r11.xy, -r6.zwzz, l(0.500000, 0.500000, 0.000000, 0.000000), l(1.000000, -2.000000, 0.000000, 0.000000) + mad r6.z, -r11.x, r2.z, r7.y + mad r2.z, r7.x, r2.z, r7.y + movc r4.w, r3.w, r6.z, r2.z + movc r11.zw, r0.yyyy, l(0,0,0,0), r4.zzzw + max r0.y, r7.x, l(0.000000) + add r11.x, r0.y, l(0.250000) + mov r7.xw, r1.xxxx + mov r7.yz, l(0,-2.000000,1000000.000000,0) + movc r1.xyzw, r0.wwww, r11.xyzw, r7.xyzw + mul r0.y, r3.y, r3.x + mul r0.yw, r8.xxxy, r0.yyyy + dp2 r9.x, r0.ywyy, r5.xzxx + dp2 r9.y, r0.ywyy, r5.ywyy + else + mul r0.y, r5.z, r5.y + mad r0.y, r5.x, r5.w, -r0.y + div r0.y, l(1.000000, 1.000000, 1.000000, 1.000000), r0.y + mul r7.xyzw, r5.wyzx, l(1.000000, -1.000000, -1.000000, 1.000000) + mul r7.xyzw, r0.yyyy, r7.xyzw + mul r0.yw, r3.xxxx, r8.xxxy + dp2 r3.x, r7.xyxx, r0.ywyy + dp2 r3.y, r7.zwzz, r0.ywyy + lt r0.yw, l(0.000000, 0.000000, 0.000000, 0.000000), r3.xxxy + lt r3.xy, r3.xyxx, l(0.000000, 0.000000, 0.000000, 0.000000) + iadd r0.yw, -r0.yyyw, r3.xxxy + itof r0.yw, r0.yyyw + mul r9.xy, r0.ywyy, l(0.500000, 0.500000, 0.000000, 0.000000) + mov r1.yzw, l(0,-1.000000,0,0) + endif + and r3.xyw, r2.wwww, l(0x00800000, 0x01000000, 0, 0x80000000) + ine r3.xyw, r3.xyxw, l(0, 0, 0, 0) + ine r0.y, r3.y, r3.x + mul r7.xyzw, r1.xyzw, l(-1.000000, 1.000000, 1.000000, 1.000000) + movc r10.xyzw, r0.yyyy, r7.xyzw, r1.xyzw + ieq r0.y, r0.z, l(2) + movc r2.xy, r0.yyyy, r4.xyxx, r2.xyxx + ine r0.y, r0.z, l(1) + and r0.x, r0.y, r3.w + mov o0.zw, r10.zzzw +endif +dp2 r1.x, r2.xyxx, r5.xzxx +dp2 r1.y, r2.xyxx, r5.ywyy +add r0.yz, r9.xxyx, r1.xxyx +add r0.yz, r6.xxyx, r0.yyzy +movc r1.xy, cb0[6].yyyy, l(1.000000,-1.000000,0,0), r10.xyxx +movc o0.xy, r0.xxxx, r10.xyxx, r1.xyxx +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r1.xyz, r3.z, l(4), t3.xyzx +mad r0.yz, r0.yyzy, r1.xxxx, r1.yyzy +mad r1.x, r0.y, cb0[3].z, l(-1.000000) +lt r0.y, l(0.000000), cb0[3].w +lt r0.w, cb0[3].w, l(0.000000) +iadd r0.y, -r0.y, r0.w +itof r0.y, r0.y +mad r1.y, r0.z, cb0[3].w, -r0.y +mov r1.zw, l(0,0,0,1.000000) +movc o1.xyzw, r0.xxxx, cb0[4].wwww, r1.xyzw +ret +// Approximately 338 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 59, 66, + 134, 87, 78, 78, 227, 153, + 109, 214, 140, 0, 38, 199, + 75, 147, 1, 0, 0, 0, + 124, 46, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 84, 5, 0, 0, 228, 5, + 0, 0, 60, 6, 0, 0, + 224, 45, 0, 0, 82, 68, + 69, 70, 24, 5, 0, 0, + 4, 0, 0, 0, 236, 0, + 0, 0, 5, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 254, 255, 0, 1, 0, 0, + 240, 4, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 220, 0, 0, 0, 5, 0, + 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 16, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 223, 0, 0, 0, + 5, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 0, + 16, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 226, 0, + 0, 0, 2, 0, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, + 8, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 229, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 232, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 76, 66, + 0, 88, 67, 0, 66, 67, + 0, 77, 66, 0, 101, 105, + 0, 171, 229, 0, 0, 0, + 1, 0, 0, 0, 76, 1, + 0, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 232, 0, 0, 0, + 4, 0, 0, 0, 148, 3, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 220, 0, 0, 0, + 1, 0, 0, 0, 108, 4, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 223, 0, 0, 0, + 1, 0, 0, 0, 200, 4, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 116, 1, 0, 0, + 0, 0, 0, 0, 104, 0, + 0, 0, 2, 0, 0, 0, + 112, 3, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 107, 0, 60, 117, 110, 110, + 97, 109, 101, 100, 62, 0, + 80, 98, 0, 102, 108, 111, + 97, 116, 0, 171, 171, 171, + 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 131, 1, 0, 0, + 89, 99, 0, 82, 101, 0, + 83, 101, 0, 109, 54, 0, + 100, 119, 111, 114, 100, 0, + 171, 171, 0, 0, 19, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 188, 1, + 0, 0, 109, 103, 0, 68, + 101, 0, 69, 101, 0, 85, + 55, 0, 105, 110, 116, 52, + 0, 171, 171, 171, 1, 0, + 2, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 244, 1, 0, 0, 106, 103, + 0, 102, 108, 111, 97, 116, + 50, 0, 171, 171, 1, 0, + 3, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 35, 2, 0, 0, 90, 99, + 0, 87, 49, 0, 110, 103, + 0, 89, 53, 0, 79, 50, + 0, 97, 100, 0, 121, 101, + 0, 118, 51, 0, 119, 51, + 0, 98, 100, 0, 103, 103, + 0, 171, 171, 171, 128, 1, + 0, 0, 140, 1, 0, 0, + 0, 0, 0, 0, 176, 1, + 0, 0, 140, 1, 0, 0, + 4, 0, 0, 0, 179, 1, + 0, 0, 140, 1, 0, 0, + 8, 0, 0, 0, 182, 1, + 0, 0, 140, 1, 0, 0, + 12, 0, 0, 0, 185, 1, + 0, 0, 196, 1, 0, 0, + 16, 0, 0, 0, 232, 1, + 0, 0, 196, 1, 0, 0, + 20, 0, 0, 0, 235, 1, + 0, 0, 196, 1, 0, 0, + 24, 0, 0, 0, 238, 1, + 0, 0, 196, 1, 0, 0, + 28, 0, 0, 0, 241, 1, + 0, 0, 252, 1, 0, 0, + 32, 0, 0, 0, 32, 2, + 0, 0, 44, 2, 0, 0, + 48, 0, 0, 0, 80, 2, + 0, 0, 44, 2, 0, 0, + 56, 0, 0, 0, 83, 2, + 0, 0, 196, 1, 0, 0, + 64, 0, 0, 0, 86, 2, + 0, 0, 140, 1, 0, 0, + 68, 0, 0, 0, 89, 2, + 0, 0, 196, 1, 0, 0, + 72, 0, 0, 0, 92, 2, + 0, 0, 140, 1, 0, 0, + 76, 0, 0, 0, 95, 2, + 0, 0, 140, 1, 0, 0, + 80, 0, 0, 0, 98, 2, + 0, 0, 196, 1, 0, 0, + 84, 0, 0, 0, 101, 2, + 0, 0, 140, 1, 0, 0, + 88, 0, 0, 0, 104, 2, + 0, 0, 140, 1, 0, 0, + 92, 0, 0, 0, 107, 2, + 0, 0, 140, 1, 0, 0, + 96, 0, 0, 0, 110, 2, + 0, 0, 196, 1, 0, 0, + 100, 0, 0, 0, 5, 0, + 0, 0, 1, 0, 26, 0, + 0, 0, 21, 0, 116, 2, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 118, 1, 0, 0, 52, 4, + 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 2, 0, + 0, 0, 56, 4, 0, 0, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 92, 4, 0, 0, + 4, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 56, 4, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 97, 4, 0, 0, 8, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 56, 4, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 102, 4, + 0, 0, 12, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 56, 4, 0, 0, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 117, 103, 0, 171, + 0, 0, 19, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 188, 1, 0, 0, + 73, 70, 102, 105, 0, 73, + 70, 103, 105, 0, 73, 70, + 104, 105, 0, 171, 148, 4, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 164, 4, 0, 0, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 36, 69, 108, 101, + 109, 101, 110, 116, 0, 117, + 105, 110, 116, 52, 0, 171, + 1, 0, 19, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 157, 4, 0, 0, + 148, 4, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 164, 4, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, + 49, 0, 73, 83, 71, 78, + 136, 0, 0, 0, 4, 0, + 0, 0, 8, 0, 0, 0, + 104, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 15, 0, 0, + 107, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 15, 7, 0, 0, + 110, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 122, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 1, 1, 0, 0, + 84, 66, 0, 85, 66, 0, + 83, 86, 95, 86, 101, 114, + 116, 101, 120, 73, 68, 0, + 83, 86, 95, 73, 110, 115, + 116, 97, 110, 99, 101, 73, + 68, 0, 79, 83, 71, 78, + 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 65, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 15, 0, 0, 0, + 84, 69, 88, 67, 79, 79, + 82, 68, 0, 83, 86, 95, + 80, 111, 115, 105, 116, 105, + 111, 110, 0, 171, 171, 171, + 83, 72, 69, 88, 156, 39, + 0, 0, 80, 0, 1, 0, + 231, 9, 0, 0, 106, 8, + 0, 1, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 7, 0, 0, 0, + 89, 0, 0, 4, 70, 142, + 32, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 162, 0, + 0, 4, 0, 112, 16, 0, + 3, 0, 0, 0, 16, 0, + 0, 0, 162, 0, 0, 4, + 0, 112, 16, 0, 6, 0, + 0, 0, 16, 0, 0, 0, + 88, 24, 0, 4, 0, 112, + 16, 0, 8, 0, 0, 0, + 68, 68, 0, 0, 95, 0, + 0, 3, 242, 16, 16, 0, + 0, 0, 0, 0, 95, 0, + 0, 3, 114, 16, 16, 0, + 1, 0, 0, 0, 96, 0, + 0, 4, 18, 16, 16, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 103, 0, 0, 4, + 242, 32, 16, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 104, 0, 0, 2, 14, 0, + 0, 0, 30, 0, 0, 8, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 3, 0, 0, 0, 10, 128, + 32, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 27, 0, + 0, 5, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 16, + 16, 0, 0, 0, 0, 0, + 42, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 58, 16, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 58, 16, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 3, 0, + 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 255, 255, 255, 255, + 37, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 35, 0, + 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 255, 7, + 0, 0, 42, 0, 0, 7, + 34, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 11, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 137, + 194, 0, 0, 128, 3, 17, + 17, 0, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, + 70, 126, 16, 0, 8, 0, + 0, 0, 1, 0, 0, 10, + 50, 0, 16, 0, 3, 0, + 0, 0, 246, 15, 16, 0, + 2, 0, 0, 0, 2, 64, + 0, 0, 255, 255, 0, 0, + 0, 0, 128, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 83, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 30, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 255, 255, + 255, 255, 167, 0, 0, 139, + 2, 131, 0, 128, 131, 153, + 25, 0, 242, 0, 16, 0, + 4, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 6, 0, 0, 0, 140, 0, + 0, 20, 82, 0, 16, 0, + 3, 0, 0, 0, 2, 64, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 166, 10, 16, 0, + 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 167, 0, 0, 139, 2, 131, + 0, 128, 131, 153, 25, 0, + 242, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 3, 0, + 0, 0, 30, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 167, 0, 0, 139, 2, 131, + 0, 128, 131, 153, 25, 0, + 242, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 3, 0, + 0, 0, 27, 0, 0, 5, + 18, 0, 16, 0, 7, 0, + 0, 0, 10, 16, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 98, 0, 16, 0, + 7, 0, 0, 0, 86, 22, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 98, 0, + 16, 0, 1, 0, 0, 0, + 86, 22, 16, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 114, 0, 16, 0, 1, 0, + 0, 0, 86, 5, 16, 0, + 3, 0, 0, 0, 38, 9, + 16, 0, 7, 0, 0, 0, + 38, 9, 16, 0, 1, 0, + 0, 0, 39, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, + 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, + 30, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 30, 0, + 0, 8, 34, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 18, 0, + 16, 0, 7, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 255, 7, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, + 7, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 11, 0, + 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, + 0, 137, 194, 0, 0, 128, + 3, 17, 17, 0, 242, 0, + 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 7, 0, + 0, 0, 54, 121, 16, 0, + 8, 0, 0, 0, 1, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, + 1, 64, 0, 0, 255, 255, + 128, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 255, 255, 128, 0, + 39, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, + 0, 0, 0, 0, 24, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 57, 0, 0, 7, + 18, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 130, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, + 8, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 255, 7, + 0, 0, 42, 0, 0, 7, + 34, 0, 16, 0, 8, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 11, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 8, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 137, + 194, 0, 0, 128, 3, 17, + 17, 0, 242, 0, 16, 0, + 7, 0, 0, 0, 70, 14, + 16, 0, 8, 0, 0, 0, + 54, 121, 16, 0, 8, 0, + 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 54, 0, + 0, 5, 114, 0, 16, 0, + 2, 0, 0, 0, 150, 7, + 16, 0, 7, 0, 0, 0, + 18, 0, 0, 1, 54, 0, + 0, 5, 18, 0, 16, 0, + 7, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, + 21, 0, 0, 1, 18, 0, + 0, 1, 54, 0, 0, 5, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 114, 0, 16, 0, + 2, 0, 0, 0, 150, 7, + 16, 0, 7, 0, 0, 0, + 21, 0, 0, 1, 1, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, + 1, 64, 0, 0, 255, 255, + 127, 255, 30, 0, 0, 7, + 130, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 21, 0, 0, 1, 1, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 28, 32, 0, 0, 7, + 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 4, + 32, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 255, 255, 0, 0, + 86, 0, 0, 5, 66, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 85, 0, 0, 7, + 18, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, + 86, 0, 0, 5, 18, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 0, 0, 0, 8, + 34, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 128, + 65, 0, 0, 0, 7, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 191, 0, 0, + 0, 8, 130, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 7, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 0, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 27, 0, + 0, 5, 50, 0, 16, 0, + 8, 0, 0, 0, 214, 5, + 16, 0, 3, 0, 0, 0, + 1, 0, 0, 7, 34, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 0, 40, 0, + 0, 5, 194, 0, 16, 0, + 8, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, + 55, 0, 0, 9, 162, 0, + 16, 0, 3, 0, 0, 0, + 86, 5, 16, 0, 3, 0, + 0, 0, 166, 14, 16, 0, + 8, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, + 30, 0, 0, 7, 162, 0, + 16, 0, 3, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, + 3, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, + 8, 0, 0, 0, 214, 5, + 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 255, 7, + 0, 0, 255, 7, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 42, 0, 0, 10, + 50, 0, 16, 0, 9, 0, + 0, 0, 214, 5, 16, 0, + 3, 0, 0, 0, 2, 64, + 0, 0, 11, 0, 0, 0, + 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 66, 0, + 16, 0, 8, 0, 0, 0, + 10, 0, 16, 0, 9, 0, + 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 8, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 45, 0, + 0, 137, 194, 0, 0, 128, + 3, 17, 17, 0, 162, 0, + 16, 0, 3, 0, 0, 0, + 134, 15, 16, 0, 8, 0, + 0, 0, 134, 125, 16, 0, + 8, 0, 0, 0, 54, 0, + 0, 5, 194, 0, 16, 0, + 9, 0, 0, 0, 86, 13, + 16, 0, 8, 0, 0, 0, + 45, 0, 0, 137, 194, 0, + 0, 128, 3, 17, 17, 0, + 50, 0, 16, 0, 8, 0, + 0, 0, 102, 15, 16, 0, + 9, 0, 0, 0, 230, 116, + 16, 0, 8, 0, 0, 0, + 1, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 8, 0, + 0, 0, 1, 64, 0, 0, + 255, 255, 128, 0, 1, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 255, 255, + 128, 0, 39, 0, 0, 7, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 31, 0, 4, 3, 58, 0, + 16, 0, 3, 0, 0, 0, + 1, 0, 0, 7, 18, 0, + 16, 0, 9, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 255, 7, 0, 0, 42, 0, + 0, 7, 34, 0, 16, 0, + 9, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 11, 0, + 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, + 0, 137, 194, 0, 0, 128, + 3, 17, 17, 0, 18, 0, + 16, 0, 8, 0, 0, 0, + 70, 14, 16, 0, 9, 0, + 0, 0, 230, 116, 16, 0, + 8, 0, 0, 0, 21, 0, + 0, 1, 0, 0, 0, 8, + 130, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 8, 0, 0, 0, 49, 0, + 0, 8, 66, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 219, 15, 73, 64, + 58, 0, 16, 128, 129, 0, + 0, 0, 3, 0, 0, 0, + 49, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 49, 0, + 0, 7, 34, 0, 16, 0, + 8, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 8, + 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 26, 0, 16, 0, + 8, 0, 0, 0, 43, 0, + 0, 5, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 50, 0, 0, 10, 130, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 128, 65, 0, + 0, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 219, 15, + 201, 64, 58, 0, 16, 0, + 3, 0, 0, 0, 55, 0, + 0, 9, 34, 0, 16, 0, + 9, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 0, 0, + 0, 10, 146, 0, 16, 0, + 3, 0, 0, 0, 6, 0, + 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 192, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 64, 192, 56, 0, 0, 8, + 66, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 128, 129, 0, 0, 0, + 9, 0, 0, 0, 56, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 131, 249, + 162, 62, 64, 0, 0, 5, + 66, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 52, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 51, 0, 0, 7, + 130, 0, 16, 0, 10, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 0, 0, 0, 8, 130, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 10, 0, + 0, 0, 29, 0, 0, 7, + 18, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 42, 0, + 16, 0, 7, 0, 0, 0, + 49, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 9, 0, 0, 0, 49, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 26, 0, + 16, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 8, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 43, 0, + 0, 5, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 50, 0, 0, 10, 130, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 219, 15, 73, 64, 26, 0, + 16, 128, 65, 0, 0, 0, + 9, 0, 0, 0, 54, 0, + 0, 6, 34, 0, 16, 0, + 7, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 24, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, + 42, 0, 16, 0, 7, 0, + 0, 0, 55, 0, 0, 10, + 18, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 0, 0, 0, 10, 194, 0, + 16, 0, 4, 0, 0, 0, + 246, 15, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 63, + 0, 0, 0, 64, 24, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 7, 0, + 0, 0, 0, 0, 0, 8, + 66, 0, 16, 0, 10, 0, + 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 7, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, + 10, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 55, 0, 0, 12, 210, 0, + 16, 0, 9, 0, 0, 0, + 246, 15, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 14, + 16, 0, 10, 0, 0, 0, + 55, 0, 0, 9, 242, 0, + 16, 0, 7, 0, 0, 0, + 6, 0, 16, 0, 3, 0, + 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 70, 14, + 16, 0, 9, 0, 0, 0, + 24, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, + 7, 0, 0, 0, 14, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 7, 0, + 0, 0, 50, 0, 0, 9, + 130, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 3, 0, + 0, 0, 55, 0, 0, 9, + 66, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 10, 0, + 16, 0, 8, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, + 7, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, + 18, 0, 0, 1, 54, 0, + 0, 5, 18, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 21, 0, 0, 1, 77, 0, + 0, 7, 18, 0, 16, 0, + 8, 0, 0, 0, 18, 0, + 16, 0, 9, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 54, 0, 0, 6, + 34, 0, 16, 0, 8, 0, + 0, 0, 10, 0, 16, 128, + 65, 0, 0, 0, 9, 0, + 0, 0, 57, 0, 0, 10, + 162, 0, 16, 0, 3, 0, + 0, 0, 246, 11, 16, 0, + 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 7, 18, 0, + 16, 0, 9, 0, 0, 0, + 70, 0, 16, 0, 8, 0, + 0, 0, 134, 0, 16, 0, + 5, 0, 0, 0, 15, 0, + 0, 7, 34, 0, 16, 0, + 9, 0, 0, 0, 70, 0, + 16, 0, 8, 0, 0, 0, + 214, 5, 16, 0, 5, 0, + 0, 0, 15, 0, 0, 7, + 66, 0, 16, 0, 4, 0, + 0, 0, 70, 0, 16, 0, + 9, 0, 0, 0, 70, 0, + 16, 0, 9, 0, 0, 0, + 75, 0, 0, 5, 130, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 14, 0, 0, 10, + 130, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 58, 0, + 16, 0, 4, 0, 0, 0, + 52, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 55, 0, + 0, 9, 34, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 31, 0, + 4, 3, 58, 0, 16, 0, + 3, 0, 0, 0, 56, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 5, 0, + 0, 0, 50, 0, 0, 10, + 130, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 5, 0, 0, 0, 58, 0, + 16, 0, 5, 0, 0, 0, + 58, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, + 49, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 49, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 30, 0, 0, 8, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 43, 0, + 0, 5, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 0, + 0, 10, 194, 0, 16, 0, + 7, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 8, 0, 51, 0, 0, 7, + 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 130, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 52, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 55, 0, + 0, 9, 130, 0, 16, 0, + 3, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 57, 0, + 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, + 130, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 128, + 129, 0, 0, 0, 9, 0, + 0, 0, 10, 0, 16, 128, + 129, 0, 0, 0, 9, 0, + 0, 0, 14, 0, 0, 10, + 66, 0, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 42, 0, + 16, 0, 4, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 56, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 63, 55, 0, 0, 9, + 18, 0, 16, 0, 9, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 49, 0, 0, 7, + 66, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 24, 0, 0, 7, 130, 0, + 16, 0, 6, 0, 0, 0, + 26, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 6, 0, + 0, 0, 14, 0, 0, 7, + 34, 0, 16, 0, 9, 0, + 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 54, 0, 0, 5, 18, 0, + 16, 0, 10, 0, 0, 0, + 42, 0, 16, 0, 6, 0, + 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 10, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 55, 0, + 0, 9, 194, 0, 16, 0, + 6, 0, 0, 0, 166, 10, + 16, 0, 4, 0, 0, 0, + 6, 4, 16, 0, 9, 0, + 0, 0, 6, 4, 16, 0, + 10, 0, 0, 0, 0, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 42, 0, 16, 0, 6, 0, + 0, 0, 56, 0, 0, 7, + 194, 0, 16, 0, 8, 0, + 0, 0, 166, 10, 16, 0, + 4, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 10, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 7, 130, 0, 16, 0, + 7, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 10, 0, 16, 0, 9, 0, + 0, 0, 14, 0, 0, 10, + 130, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 58, 0, + 16, 0, 7, 0, 0, 0, + 54, 0, 0, 6, 34, 0, + 16, 0, 10, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 10, 0, 0, 0, + 0, 0, 0, 7, 98, 0, + 16, 0, 9, 0, 0, 0, + 166, 10, 16, 0, 6, 0, + 0, 0, 6, 1, 16, 0, + 10, 0, 0, 0, 50, 0, + 0, 12, 98, 0, 16, 0, + 9, 0, 0, 0, 246, 15, + 16, 0, 7, 0, 0, 0, + 86, 6, 16, 0, 9, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 63, 0, 0, 0, 63, + 0, 0, 0, 0, 79, 0, + 0, 7, 130, 0, 16, 0, + 7, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 8, + 26, 0, 16, 0, 0, 0, + 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 7, 0, + 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 10, 0, + 0, 0, 246, 15, 16, 0, + 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 64, 0, + 0, 0, 128, 0, 0, 0, + 0, 2, 0, 0, 32, 0, + 55, 0, 0, 15, 114, 0, + 16, 0, 11, 0, 0, 0, + 6, 2, 16, 0, 10, 0, + 0, 0, 2, 64, 0, 0, + 2, 0, 0, 0, 254, 255, + 255, 255, 0, 0, 128, 63, + 0, 0, 0, 0, 2, 64, + 0, 0, 254, 255, 255, 255, + 2, 0, 0, 0, 0, 0, + 128, 62, 0, 0, 0, 0, + 55, 0, 0, 9, 130, 0, + 16, 0, 7, 0, 0, 0, + 26, 0, 16, 0, 10, 0, + 0, 0, 26, 0, 16, 0, + 11, 0, 0, 0, 10, 0, + 16, 0, 11, 0, 0, 0, + 30, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 1, 0, + 0, 7, 18, 0, 16, 0, + 12, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 255, 7, + 0, 0, 42, 0, 0, 7, + 34, 0, 16, 0, 12, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 11, 0, 0, 0, + 54, 0, 0, 8, 194, 0, + 16, 0, 12, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 45, 0, 0, 137, + 194, 0, 0, 128, 3, 17, + 17, 0, 18, 0, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 12, 0, 0, 0, + 38, 125, 16, 0, 8, 0, + 0, 0, 0, 0, 0, 8, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 128, + 65, 0, 0, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 49, 0, + 0, 8, 130, 0, 16, 0, + 7, 0, 0, 0, 1, 64, + 0, 0, 219, 15, 73, 64, + 10, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 34, 0, + 16, 0, 10, 0, 0, 0, + 10, 0, 16, 128, 193, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 219, 15, + 201, 64, 55, 0, 0, 10, + 18, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 26, 0, + 16, 0, 10, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 39, 0, 0, 7, 130, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 10, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 39, 0, + 0, 7, 18, 0, 16, 0, + 10, 0, 0, 0, 42, 0, + 16, 0, 7, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 32, 0, 0, 7, + 130, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 10, 0, + 16, 0, 10, 0, 0, 0, + 55, 0, 0, 9, 130, 0, + 16, 0, 7, 0, 0, 0, + 58, 0, 16, 0, 7, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 191, 1, 64, + 0, 0, 0, 0, 0, 63, + 50, 0, 0, 9, 130, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, + 77, 0, 0, 7, 18, 0, + 16, 0, 10, 0, 0, 0, + 18, 0, 16, 0, 11, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 54, 0, + 0, 6, 34, 0, 16, 0, + 10, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, + 11, 0, 0, 0, 15, 0, + 0, 7, 18, 0, 16, 0, + 11, 0, 0, 0, 70, 0, + 16, 0, 10, 0, 0, 0, + 134, 0, 16, 0, 5, 0, + 0, 0, 15, 0, 0, 7, + 34, 0, 16, 0, 11, 0, + 0, 0, 70, 0, 16, 0, + 10, 0, 0, 0, 214, 5, + 16, 0, 5, 0, 0, 0, + 0, 0, 0, 9, 130, 0, + 16, 0, 7, 0, 0, 0, + 26, 0, 16, 128, 129, 0, + 0, 0, 11, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 11, 0, 0, 0, + 15, 0, 0, 7, 66, 0, + 16, 0, 10, 0, 0, 0, + 70, 0, 16, 0, 11, 0, + 0, 0, 70, 0, 16, 0, + 11, 0, 0, 0, 14, 0, + 0, 10, 66, 0, 16, 0, + 10, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 42, 0, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 7, + 130, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 42, 0, + 16, 0, 10, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 77, 0, + 0, 6, 0, 208, 0, 0, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 32, 0, + 0, 10, 50, 0, 16, 0, + 11, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 20, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, + 0, 0, 29, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 62, + 1, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 11, 0, 0, 0, 60, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 11, 0, + 0, 0, 52, 0, 0, 7, + 66, 0, 16, 0, 10, 0, + 0, 0, 42, 0, 16, 0, + 11, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 14, 0, 0, 10, 66, 0, + 16, 0, 10, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, + 128, 63, 42, 0, 16, 0, + 10, 0, 0, 0, 56, 0, + 0, 7, 66, 0, 16, 0, + 10, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 10, 0, + 0, 0, 56, 0, 0, 7, + 18, 0, 16, 0, 11, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 63, + 50, 0, 0, 9, 66, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 11, 0, 0, 0, + 55, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 10, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, + 50, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 7, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 26, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 9, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 62, 50, 0, + 0, 9, 66, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 29, 0, + 0, 7, 66, 0, 16, 0, + 6, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 14, 0, 0, 10, + 18, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 10, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 56, 0, + 0, 7, 242, 0, 16, 0, + 11, 0, 0, 0, 6, 5, + 16, 0, 0, 0, 0, 0, + 70, 1, 16, 0, 10, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 12, 0, + 0, 0, 230, 10, 16, 0, + 8, 0, 0, 0, 230, 10, + 16, 0, 8, 0, 0, 0, + 15, 0, 0, 7, 34, 0, + 16, 0, 12, 0, 0, 0, + 230, 10, 16, 0, 11, 0, + 0, 0, 230, 10, 16, 0, + 11, 0, 0, 0, 56, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 8, 0, 0, 0, + 58, 0, 16, 0, 11, 0, + 0, 0, 50, 0, 0, 10, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 8, 0, 0, 0, 42, 0, + 16, 0, 11, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 14, 0, 0, 10, 18, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, + 128, 63, 10, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 10, 82, 0, 16, 0, + 13, 0, 0, 0, 166, 11, + 16, 0, 11, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 0, + 0, 0, 128, 191, 0, 0, + 0, 0, 56, 0, 0, 10, + 162, 0, 16, 0, 13, 0, + 0, 0, 246, 11, 16, 0, + 8, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 128, 63, + 56, 0, 0, 7, 242, 0, + 16, 0, 13, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 70, 14, 16, 0, + 13, 0, 0, 0, 15, 0, + 0, 7, 18, 0, 16, 0, + 13, 0, 0, 0, 70, 0, + 16, 0, 13, 0, 0, 0, + 70, 0, 16, 0, 12, 0, + 0, 0, 15, 0, 0, 7, + 34, 0, 16, 0, 13, 0, + 0, 0, 230, 10, 16, 0, + 13, 0, 0, 0, 70, 0, + 16, 0, 12, 0, 0, 0, + 55, 0, 0, 9, 50, 0, + 16, 0, 11, 0, 0, 0, + 166, 10, 16, 0, 6, 0, + 0, 0, 70, 0, 16, 0, + 11, 0, 0, 0, 70, 0, + 16, 0, 13, 0, 0, 0, + 55, 0, 0, 9, 194, 0, + 16, 0, 8, 0, 0, 0, + 246, 15, 16, 0, 10, 0, + 0, 0, 6, 4, 16, 0, + 11, 0, 0, 0, 166, 14, + 16, 0, 8, 0, 0, 0, + 56, 0, 0, 8, 194, 0, + 16, 0, 10, 0, 0, 0, + 246, 15, 16, 128, 129, 0, + 0, 0, 3, 0, 0, 0, + 166, 14, 16, 0, 8, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 230, 10, 16, 0, + 10, 0, 0, 0, 70, 0, + 16, 0, 10, 0, 0, 0, + 0, 0, 0, 8, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 14, 0, 0, 7, + 130, 0, 16, 0, 9, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 7, 0, 0, 0, + 55, 0, 0, 9, 98, 0, + 16, 0, 9, 0, 0, 0, + 166, 10, 16, 0, 7, 0, + 0, 0, 86, 7, 16, 0, + 9, 0, 0, 0, 246, 14, + 16, 0, 9, 0, 0, 0, + 21, 0, 0, 1, 56, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 246, 15, + 16, 0, 6, 0, 0, 0, + 150, 5, 16, 0, 9, 0, + 0, 0, 52, 0, 0, 7, + 34, 0, 16, 0, 10, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 23, 183, 209, 56, + 50, 0, 0, 10, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 128, 65, 0, + 0, 0, 9, 0, 0, 0, + 58, 0, 16, 0, 6, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 192, 55, 0, + 0, 9, 18, 0, 16, 0, + 10, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 8, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 9, 0, + 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 134, 0, + 16, 0, 5, 0, 0, 0, + 15, 0, 0, 7, 34, 0, + 16, 0, 9, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 214, 5, 16, 0, + 5, 0, 0, 0, 39, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 8, + 194, 32, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 18, 0, + 0, 1, 57, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 26, 0, + 16, 0, 0, 0, 0, 0, + 49, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 7, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 7, 18, 0, 16, 0, + 11, 0, 0, 0, 26, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 0, 7, 0, + 0, 0, 54, 0, 0, 6, + 34, 0, 16, 0, 11, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 7, 0, + 0, 0, 55, 0, 0, 9, + 194, 0, 16, 0, 4, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 6, 4, + 16, 0, 11, 0, 0, 0, + 6, 4, 16, 0, 7, 0, + 0, 0, 0, 0, 0, 8, + 34, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 219, 15, + 201, 63, 56, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 131, 249, 34, 62, + 29, 0, 0, 8, 66, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 26, 0, 0, 6, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 129, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 10, + 34, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 50, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 219, 15, 201, 64, 1, 64, + 0, 0, 219, 15, 201, 191, + 52, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 51, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 66, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 63, + 49, 0, 0, 7, 66, 0, + 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 8, 130, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 55, 0, 0, 9, 34, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 77, 0, 0, 7, 18, 0, + 16, 0, 7, 0, 0, 0, + 18, 0, 16, 0, 11, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 34, 0, 16, 0, + 7, 0, 0, 0, 10, 0, + 16, 0, 11, 0, 0, 0, + 50, 0, 0, 14, 194, 0, + 16, 0, 6, 0, 0, 0, + 6, 4, 16, 128, 65, 0, + 0, 0, 7, 0, 0, 0, + 6, 0, 16, 128, 129, 0, + 0, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 56, 0, 0, 10, + 50, 0, 16, 0, 7, 0, + 0, 0, 230, 10, 16, 0, + 6, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 219, 15, 201, 191, 49, 0, + 0, 8, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 128, 129, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 111, 18, 131, 58, + 77, 0, 0, 7, 18, 0, + 16, 0, 11, 0, 0, 0, + 18, 0, 16, 0, 12, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 14, 0, + 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 11, 0, 0, 0, + 10, 0, 16, 0, 12, 0, + 0, 0, 0, 0, 0, 8, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 219, 15, 201, 63, 49, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 49, 0, 0, 7, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 30, 0, 0, 8, 130, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 43, 0, 0, 5, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 52, 0, + 0, 8, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 128, 129, 0, 0, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 189, 55, 134, 53, + 14, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 29, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 16, + 50, 0, 16, 0, 11, 0, + 0, 0, 230, 10, 16, 128, + 65, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 63, 0, 0, + 0, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 63, + 0, 0, 0, 192, 0, 0, + 0, 0, 0, 0, 0, 0, + 50, 0, 0, 10, 66, 0, + 16, 0, 6, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 11, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 50, 0, + 0, 9, 66, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 55, 0, + 0, 9, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 6, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 55, 0, + 0, 12, 194, 0, 16, 0, + 11, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 52, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, + 18, 0, 16, 0, 11, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 62, + 54, 0, 0, 5, 146, 0, + 16, 0, 7, 0, 0, 0, + 6, 0, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 8, + 98, 0, 16, 0, 7, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 192, 0, 36, 116, 73, + 0, 0, 0, 0, 55, 0, + 0, 9, 242, 0, 16, 0, + 1, 0, 0, 0, 246, 15, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 11, 0, + 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 56, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 7, + 162, 0, 16, 0, 0, 0, + 0, 0, 6, 4, 16, 0, + 8, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 15, 0, 0, 7, 18, 0, + 16, 0, 9, 0, 0, 0, + 214, 5, 16, 0, 0, 0, + 0, 0, 134, 0, 16, 0, + 5, 0, 0, 0, 15, 0, + 0, 7, 34, 0, 16, 0, + 9, 0, 0, 0, 214, 5, + 16, 0, 0, 0, 0, 0, + 214, 5, 16, 0, 5, 0, + 0, 0, 18, 0, 0, 1, + 56, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 50, 0, + 0, 10, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, + 58, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 14, 0, 0, 10, + 34, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 26, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, + 118, 2, 16, 0, 5, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 191, 0, 0, 128, 191, + 0, 0, 128, 63, 56, 0, + 0, 7, 242, 0, 16, 0, + 7, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 7, 0, + 0, 0, 56, 0, 0, 7, + 162, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, + 3, 0, 0, 0, 6, 4, + 16, 0, 8, 0, 0, 0, + 15, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 7, 0, + 0, 0, 214, 5, 16, 0, + 0, 0, 0, 0, 15, 0, + 0, 7, 34, 0, 16, 0, + 3, 0, 0, 0, 230, 10, + 16, 0, 7, 0, 0, 0, + 214, 5, 16, 0, 0, 0, + 0, 0, 49, 0, 0, 10, + 162, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 4, + 16, 0, 3, 0, 0, 0, + 49, 0, 0, 10, 50, 0, + 16, 0, 3, 0, 0, 0, + 70, 0, 16, 0, 3, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 30, 0, + 0, 8, 162, 0, 16, 0, + 0, 0, 0, 0, 86, 13, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 6, 4, + 16, 0, 3, 0, 0, 0, + 43, 0, 0, 5, 162, 0, + 16, 0, 0, 0, 0, 0, + 86, 13, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 10, + 50, 0, 16, 0, 9, 0, + 0, 0, 214, 5, 16, 0, + 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 63, + 0, 0, 0, 63, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 8, 226, 0, + 16, 0, 1, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, + 1, 0, 0, 10, 178, 0, + 16, 0, 3, 0, 0, 0, + 246, 15, 16, 0, 2, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 128, 39, 0, + 0, 10, 178, 0, 16, 0, + 3, 0, 0, 0, 70, 12, + 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 39, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 56, 0, 0, 10, 242, 0, + 16, 0, 7, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 191, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 55, 0, + 0, 9, 242, 0, 16, 0, + 10, 0, 0, 0, 86, 5, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 32, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 2, 0, + 0, 0, 55, 0, 0, 9, + 50, 0, 16, 0, 2, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 2, 0, + 0, 0, 39, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 54, 0, + 0, 5, 194, 32, 16, 0, + 0, 0, 0, 0, 166, 14, + 16, 0, 10, 0, 0, 0, + 21, 0, 0, 1, 15, 0, + 0, 7, 18, 0, 16, 0, + 1, 0, 0, 0, 70, 0, + 16, 0, 2, 0, 0, 0, + 134, 0, 16, 0, 5, 0, + 0, 0, 15, 0, 0, 7, + 34, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, + 2, 0, 0, 0, 214, 5, + 16, 0, 5, 0, 0, 0, + 0, 0, 0, 7, 98, 0, + 16, 0, 0, 0, 0, 0, + 6, 1, 16, 0, 9, 0, + 0, 0, 6, 1, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 7, 98, 0, 16, 0, + 0, 0, 0, 0, 6, 1, + 16, 0, 6, 0, 0, 0, + 86, 6, 16, 0, 0, 0, + 0, 0, 55, 0, 0, 13, + 50, 0, 16, 0, 1, 0, + 0, 0, 86, 133, 32, 0, + 0, 0, 0, 0, 6, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 191, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 10, 0, 0, 0, + 55, 0, 0, 9, 50, 32, + 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 10, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, + 167, 0, 0, 139, 2, 131, + 0, 128, 131, 153, 25, 0, + 114, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 4, 0, 0, 0, + 70, 114, 16, 0, 3, 0, + 0, 0, 50, 0, 0, 9, + 98, 0, 16, 0, 0, 0, + 0, 0, 86, 6, 16, 0, + 0, 0, 0, 0, 6, 0, + 16, 0, 1, 0, 0, 0, + 86, 6, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 18, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 128, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 191, + 49, 0, 0, 8, 34, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 58, 128, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 49, 0, 0, 8, + 130, 0, 16, 0, 0, 0, + 0, 0, 58, 128, 32, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, + 0, 8, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 43, 0, 0, 5, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 50, 0, 0, 11, + 34, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 58, 128, + 32, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 8, 194, 0, 16, 0, + 1, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 63, + 55, 0, 0, 10, 242, 32, + 16, 0, 1, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 246, 143, 32, 0, + 0, 0, 0, 0, 4, 0, + 0, 0, 70, 14, 16, 0, + 1, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 82, 1, + 0, 0, 14, 0, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 162, 0, 0, 0, + 39, 0, 0, 0, 28, 0, + 0, 0, 6, 0, 0, 0, + 8, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 28, 0, 0, 0, + 32, 0, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h new file mode 100644 index 000000000..ad5f3f711 --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_fill.frag.h @@ -0,0 +1,371 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// T9 sampler NA NA s10 1 +// QC texture float 1darray t10 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xyzw +// SV_Position 0 xyzw 1 POS float +// SV_IsFrontFace 0 x 2 FFACE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 x 0 TARGET float x +// +ps_5_0 +dcl_globalFlags refactoringAllowed +dcl_sampler s10, mode_default +dcl_resource_texture1darray (float,float,float,float) t10 +dcl_input_ps linear noperspective v0.xyzw +dcl_input_ps_sgv constant v2.x, is_front_face +dcl_output o0.x +dcl_temps 6 +max r0.x, v0.w, l(0.000000) +ge r0.z, v0.z, l(0.000000) +mov r0.y, l(0) +sample_l_indexable(texture1darray)(float,float,float,float) r0.y, r0.xyxx, t10.yxzw, s10, l(0.000000) +and r0.y, r0.y, r0.z +lt r0.z, |v0.z|, l(1000.000000) +if_nz r0.z + add r0.z, |v0.x|, l(-0.250000) + add r0.w, -v0.y, l(-2.000000) + add r1.x, -r0.x, r0.w + mul r1.y, r1.x, l(0.598413) + mad r2.xyzw, r1.xxxx, l(0.125000, 0.375000, 0.625000, 0.875000), r0.xxxx + mad r0.x, r0.w, v0.z, r0.z + mad r3.xyzw, r2.zxwy, -v0.zzzz, r0.xxxx + mov r4.xz, r3.yywy + mov r4.yw, l(0,0,0,0) + sample_l_indexable(texture1darray)(float,float,float,float) r5.x, r4.xyxx, t10.xyzw, s10, l(0.000000) + sample_l_indexable(texture1darray)(float,float,float,float) r5.y, r4.zwzz, t10.yxzw, s10, l(0.000000) + mov r3.yw, l(0,0,0,0) + sample_l_indexable(texture1darray)(float,float,float,float) r5.z, r3.xyxx, t10.yzxw, s10, l(0.000000) + sample_l_indexable(texture1darray)(float,float,float,float) r5.w, r3.zwzz, t10.yzwx, s10, l(0.000000) + mad r2.xyzw, r2.xyzw, l(5.095931, 5.095931, 5.095931, 5.095931), l(-2.547965, -2.547965, -2.547965, -2.547965) + mul r2.xyzw, r2.xyzw, -r2.xyzw + exp r2.xyzw, r2.xyzw + dp4 r0.x, r5.xyzw, r2.xyzw + mad r0.y, r0.x, r1.y, r0.y +endif +lt r0.x, l(0.000000), v0.x +lt r0.z, v0.x, l(0.000000) +iadd r0.x, -r0.x, r0.z +itof r0.x, r0.x +mul r0.x, r0.x, r0.y +movc o0.x, v2.x, r0.x, -r0.x +ret +// Approximately 34 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 71, 73, + 131, 187, 158, 232, 178, 57, + 202, 193, 177, 156, 166, 199, + 110, 194, 1, 0, 0, 0, + 224, 6, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 232, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 68, 6, 0, 0, 82, 68, + 69, 70, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 255, 255, 0, 1, 0, 0, + 130, 0, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 124, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 127, 0, 0, 0, + 2, 0, 0, 0, 5, 0, + 0, 0, 3, 0, 0, 0, + 255, 255, 255, 255, 10, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 84, 57, + 0, 81, 67, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, + 49, 0, 171, 171, 73, 83, + 71, 78, 116, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 15, + 0, 0, 89, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 101, 0, 0, 0, + 0, 0, 0, 0, 9, 0, + 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 1, 1, + 0, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 83, + 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 83, + 86, 95, 73, 115, 70, 114, + 111, 110, 116, 70, 97, 99, + 101, 0, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 1, 14, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 83, 72, 69, 88, 164, 4, + 0, 0, 80, 0, 0, 0, + 41, 1, 0, 0, 106, 8, + 0, 1, 90, 0, 0, 3, + 0, 96, 16, 0, 10, 0, + 0, 0, 88, 56, 0, 4, + 0, 112, 16, 0, 10, 0, + 0, 0, 85, 85, 0, 0, + 98, 32, 0, 3, 242, 16, + 16, 0, 0, 0, 0, 0, + 99, 8, 0, 4, 18, 16, + 16, 0, 2, 0, 0, 0, + 9, 0, 0, 0, 101, 0, + 0, 3, 18, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 6, 0, 0, 0, + 52, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 58, 16, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 29, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 16, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 34, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 72, 0, + 0, 141, 194, 1, 0, 128, + 67, 85, 21, 0, 34, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 0, 0, + 0, 0, 22, 126, 16, 0, + 10, 0, 0, 0, 0, 96, + 16, 0, 10, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 49, 0, 0, 8, 66, 0, + 16, 0, 0, 0, 0, 0, + 42, 16, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 122, 68, 31, 0, 4, 3, + 42, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 8, + 66, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 128, + 129, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 190, 0, 0, + 0, 8, 130, 0, 16, 0, + 0, 0, 0, 0, 26, 16, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 192, + 0, 0, 0, 8, 18, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 34, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 159, 49, 25, 63, + 50, 0, 0, 12, 242, 0, + 16, 0, 2, 0, 0, 0, + 6, 0, 16, 0, 1, 0, + 0, 0, 2, 64, 0, 0, + 255, 255, 255, 61, 0, 0, + 192, 62, 0, 0, 32, 63, + 255, 255, 95, 63, 6, 0, + 16, 0, 0, 0, 0, 0, + 50, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, + 58, 0, 16, 0, 0, 0, + 0, 0, 42, 16, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 50, 0, 0, 10, 242, 0, + 16, 0, 3, 0, 0, 0, + 38, 7, 16, 0, 2, 0, + 0, 0, 166, 26, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 82, 0, 16, 0, + 4, 0, 0, 0, 86, 7, + 16, 0, 3, 0, 0, 0, + 54, 0, 0, 8, 162, 0, + 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 72, 0, 0, 141, + 194, 1, 0, 128, 67, 85, + 21, 0, 18, 0, 16, 0, + 5, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, + 70, 126, 16, 0, 10, 0, + 0, 0, 0, 96, 16, 0, + 10, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 72, 0, 0, 141, 194, 1, + 0, 128, 67, 85, 21, 0, + 34, 0, 16, 0, 5, 0, + 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 22, 126, + 16, 0, 10, 0, 0, 0, + 0, 96, 16, 0, 10, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 8, 162, 0, 16, 0, + 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 72, 0, 0, 141, 194, 1, + 0, 128, 67, 85, 21, 0, + 66, 0, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 150, 124, + 16, 0, 10, 0, 0, 0, + 0, 96, 16, 0, 10, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 72, 0, + 0, 141, 194, 1, 0, 128, + 67, 85, 21, 0, 130, 0, + 16, 0, 5, 0, 0, 0, + 230, 10, 16, 0, 3, 0, + 0, 0, 150, 115, 16, 0, + 10, 0, 0, 0, 0, 96, + 16, 0, 10, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 15, + 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 2, 64, + 0, 0, 221, 17, 163, 64, + 221, 17, 163, 64, 221, 17, + 163, 64, 221, 17, 163, 64, + 2, 64, 0, 0, 221, 17, + 35, 192, 221, 17, 35, 192, + 221, 17, 35, 192, 221, 17, + 35, 192, 56, 0, 0, 8, + 242, 0, 16, 0, 2, 0, + 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 70, 14, + 16, 128, 65, 0, 0, 0, + 2, 0, 0, 0, 25, 0, + 0, 5, 242, 0, 16, 0, + 2, 0, 0, 0, 70, 14, + 16, 0, 2, 0, 0, 0, + 17, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 70, 14, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, + 2, 0, 0, 0, 50, 0, + 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 21, 0, + 0, 1, 49, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 16, + 16, 0, 0, 0, 0, 0, + 49, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, + 10, 16, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 30, 0, + 0, 8, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 43, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 55, 0, 0, 10, 18, 32, + 16, 0, 0, 0, 0, 0, + 10, 16, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 34, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 18, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h new file mode 100644 index 000000000..f1d1bd6fe --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/render_atlas_stroke.frag.h @@ -0,0 +1,195 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// T9 sampler NA NA s10 1 +// QC texture float 1darray t10 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xy +// SV_Position 0 xyzw 1 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 x 0 TARGET float x +// +ps_5_0 +dcl_globalFlags refactoringAllowed +dcl_sampler s10, mode_default +dcl_resource_texture1darray (float,float,float,float) t10 +dcl_input_ps linear noperspective v0.xy +dcl_output o0.x +dcl_temps 1 +add r0.x, v0.x, l(3.000000) +mov r0.yw, l(0,0,0,0) +sample_l_indexable(texture1darray)(float,float,float,float) r0.x, r0.xyxx, t10.xyzw, s10, l(0.000000) +add r0.x, -r0.x, l(1.000000) +add r0.z, -v0.y, l(1.000000) +sample_l_indexable(texture1darray)(float,float,float,float) r0.y, r0.zwzz, t10.yxzw, s10, l(0.000000) +add o0.x, -r0.y, r0.x +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 194, 80, + 240, 180, 198, 31, 49, 54, + 176, 11, 143, 3, 188, 119, + 250, 52, 1, 0, 0, 0, + 104, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 232, 0, 0, 0, 64, 1, + 0, 0, 116, 1, 0, 0, + 204, 2, 0, 0, 82, 68, + 69, 70, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 255, 255, 0, 1, 0, 0, + 130, 0, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 124, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 127, 0, 0, 0, + 2, 0, 0, 0, 5, 0, + 0, 0, 3, 0, 0, 0, + 255, 255, 255, 255, 10, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 84, 57, + 0, 81, 67, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, + 49, 0, 171, 171, 73, 83, + 71, 78, 80, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 3, + 0, 0, 65, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 83, + 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 1, 14, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 83, 72, 69, 88, 80, 1, + 0, 0, 80, 0, 0, 0, + 84, 0, 0, 0, 106, 8, + 0, 1, 90, 0, 0, 3, + 0, 96, 16, 0, 10, 0, + 0, 0, 88, 56, 0, 4, + 0, 112, 16, 0, 10, 0, + 0, 0, 85, 85, 0, 0, + 98, 32, 0, 3, 50, 16, + 16, 0, 0, 0, 0, 0, + 101, 0, 0, 3, 18, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 0, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 64, 64, + 54, 0, 0, 8, 162, 0, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 72, 0, 0, 141, + 194, 1, 0, 128, 67, 85, + 21, 0, 18, 0, 16, 0, + 0, 0, 0, 0, 70, 0, + 16, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 10, 0, + 0, 0, 0, 96, 16, 0, + 10, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 8, + 66, 0, 16, 0, 0, 0, + 0, 0, 26, 16, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 72, 0, + 0, 141, 194, 1, 0, 128, + 67, 85, 21, 0, 34, 0, + 16, 0, 0, 0, 0, 0, + 230, 10, 16, 0, 0, 0, + 0, 0, 22, 126, 16, 0, + 10, 0, 0, 0, 0, 96, + 16, 0, 10, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, + 18, 32, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 148, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h new file mode 100644 index 000000000..2243f093b --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/root.sig.h @@ -0,0 +1,123 @@ +#if 0 +Disassembly failed +#endif + +const BYTE g_ROOT_SIG[] = +{ + 68, 88, 66, 67, 191, 116, + 174, 43, 15, 88, 191, 39, + 78, 109, 124, 157, 110, 3, + 127, 251, 1, 0, 0, 0, + 180, 2, 0, 0, 1, 0, + 0, 0, 36, 0, 0, 0, + 82, 84, 83, 48, 136, 2, + 0, 0, 2, 0, 0, 0, + 9, 0, 0, 0, 24, 0, + 0, 0, 0, 0, 0, 0, + 136, 2, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 132, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 144, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 156, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 168, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 16, 1, + 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 120, 1, + 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 152, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 104, 2, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, + 176, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 1, 0, 0, 0, + 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 1, 0, 0, 0, + 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 4, 0, + 0, 0, 24, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 1, 0, + 0, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 255, 255, 255, 255, + 1, 0, 0, 0, 128, 1, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 255, 255, + 255, 255, 4, 0, 0, 0, + 160, 1, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 255, 255, 255, 255, 1, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 255, 255, 255, 255, 1, 0, + 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 255, 255, 255, 255, 1, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 255, 255, 255, 255, 4, 0, + 0, 0, 8, 2, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 3, 0, 0, 0, 1, 0, + 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 3, 0, 0, 0, 1, 0, + 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 3, 0, 0, 0, 1, 0, + 0, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 1, 0, 0, 0, 112, 2, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 255, 255, + 255, 255 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h new file mode 100644 index 000000000..57d4036af --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.frag.h @@ -0,0 +1,1418 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xyzw +// TEXCOORD 1 xyzw 1 NONE float xyzw +// TEXCOORD 2 xyzw 2 NONE float xyzw +// TEXCOORD 3 xyz 3 NONE float xyz +// TEXCOORD 4 x 4 NONE uint x +// SV_Position 0 xyzw 5 POS float +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET uint xyzw +// +ps_5_0 +dcl_globalFlags refactoringAllowed +dcl_input_ps linear noperspective v0.xyzw +dcl_input_ps linear noperspective v1.xyzw +dcl_input_ps linear noperspective v2.xyzw +dcl_input_ps linear noperspective v3.xyz +dcl_input_ps constant v4.x +dcl_output o0.xyzw +dcl_temps 10 +ne r0.xy, v0.zwzz, v0.xyxx +or r0.x, r0.y, r0.x +ne r0.yz, v0.zzwz, v1.xxyx +or r0.y, r0.z, r0.y +movc r0.zw, r0.yyyy, v1.xxxy, v1.zzzw +movc r0.xz, r0.xxxx, v0.zzwz, r0.zzwz +add r0.xz, r0.xxzx, -v0.xxyx +ne r1.xy, v1.xyxx, v1.zwzz +or r0.w, r1.y, r1.x +movc r1.xy, r0.yyyy, v0.zwzz, v0.xyxx +movc r0.yw, r0.wwww, v1.xxxy, r1.xxxy +add r0.yw, -r0.yyyw, v1.zzzw +round_ni r1.x, v2.x +max r1.w, r1.x, l(0.000000) +ftou r2.x, v2.z +and r2.y, r2.x, l(1023) +utof r3.x, r2.y +ushr r2.x, r2.x, l(10) +utof r2.y, r2.x +add r1.z, -r2.y, v2.y +ge r2.w, r1.z, r1.w +add r2.z, -r1.z, r1.w +and r4.xyz, v4.xxxx, l(0xe3ffffff, 0x1c000000, 0x02000000, 0) +ult r3.w, l(0x08000000), r4.y +lt r5.xy, r2.zzzz, l(2.500000, 3.500000, 0.000000, 0.000000) +or r4.w, v4.x, l(0x00400000) +movc r4.w, r5.x, r4.w, v4.x +lt r5.x, l(1.500000), r2.z +and r5.x, r5.y, r5.x +or r5.y, r4.w, l(0x00200000) +movc r2.x, r5.x, r5.y, r4.w +ine r4.z, r4.z, l(0) +ieq r4.y, r4.y, l(0x04000000) +or r4.y, r4.y, r4.z +add r4.zw, r2.yyyz, l(0.000000, 0.000000, -2.000000, -1.000000) +movc r5.yz, r4.yyyy, r4.zzwz, r2.yyzy +mov r5.x, v4.x +movc r5.xzw, r3.wwww, r2.xxyz, r5.xxyz +lt r2.x, v3.z, l(0.000000) +movc r2.x, r2.x, l(0x00100000), l(0x00080000) +or r2.z, r2.x, r5.x +mov r1.xy, v1.xyxx +mov r5.xy, v1.zwzz +movc r1.xyzw, r2.wwww, r1.xyzw, r5.xyzw +movc r4.yz, r2.wwww, v0.xxyx, v1.zzwz +movc r0.xz, r2.wwww, r0.xxzx, r0.yywy +mov r3.y, v2.w +mov r3.z, r4.x +mov r2.x, l(1.000000) +mov r2.y, v3.z +movc r3.xyw, r2.wwww, r3.xyxz, r2.xyxz +eq r2.x, r1.w, l(0.000000) +eq r2.y, r1.z, r1.w +or r2.x, r2.y, r2.x +and r2.y, r3.w, l(0x1c000000) +ult r2.z, l(0x08000000), r2.y +or r2.x, r2.z, r2.x +if_nz r2.x + movc r0.yw, r2.wwww, r0.yyyw, v3.xxxy + mul r2.x, r1.z, l(0.500000) + lt r2.x, r1.w, r2.x + movc r3.xy, r2.xxxx, r4.yzyy, v1.zwzz + movc r0.yw, r2.xxxx, r0.xxxz, r0.yyyw + dp2 r2.x, r0.ywyy, r0.ywyy + rsq r2.x, r2.x + mul r0.yw, r0.yyyw, r2.xxxx + max r0.y, r0.y, l(-1.000000) + min r0.y, r0.y, l(1.000000) + add r2.x, -|r0.y|, l(1.000000) + sqrt r2.x, r2.x + mad r2.z, |r0.y|, l(-0.018729), l(0.074261) + mad r2.z, r2.z, |r0.y|, l(-0.212114) + mad r2.z, r2.z, |r0.y|, l(1.570729) + mul r4.x, r2.x, r2.z + mad r4.x, r4.x, l(-2.000000), l(3.141593) + lt r0.y, r0.y, -r0.y + and r0.y, r0.y, r4.x + mad r0.y, r2.z, r2.x, r0.y + ge r0.w, r0.w, l(0.000000) + movc r0.y, r0.w, r0.y, -r0.y +else + movc r2.xz, r2.wwww, v0.zzwz, v1.zzwz + and r0.w, r3.w, l(0x80000000) + if_nz r0.w + mov r3.xy, r2.xzxx + mov r0.y, l(0) + else + eq r0.w, r1.z, r3.x + if_nz r0.w + div r5.x, r1.w, r3.x + mov r5.y, l(0) + mov r0.w, l(0) + else + add r4.xw, -r4.yyyz, r2.xxxz + add r5.zw, -r4.yyyz, v1.zzzw + add r6.xy, r1.xyxx, -r2.xzxx + add r6.zw, -r4.xxxw, r6.xxxy + mad r5.zw, r6.xxxy, l(0.000000, 0.000000, -3.000000, -3.000000), r5.zzzw + add r2.w, r3.x, r3.x + mul r6.xy, r2.wwww, r6.zwzz + mul r2.w, r3.x, r3.x + mul r7.xy, r2.wwww, r4.xwxx + add r2.w, r3.x, l(-1.000000) + min r2.w, r1.w, r2.w + dp2 r7.z, r0.xzxx, r0.xzxx + rsq r7.z, r7.z + mul r0.xz, r0.xxzx, r7.zzzz + add r7.z, r1.w, l(1.000000) + mul r7.z, |r3.y|, r7.z + mov r7.w, l(0) + mov r8.x, l(9) + loop + ilt r8.y, r8.x, l(0) + breakc_nz r8.y + itof r8.y, r8.x + exp r8.y, r8.y + add r8.y, r7.w, r8.y + ge r8.z, r2.w, r8.y + mad r9.xy, r8.yyyy, r5.zwzz, r6.xyxx + mad r9.xy, r8.yyyy, r9.xyxx, r7.xyxx + dp2 r8.w, r9.xyxx, r9.xyxx + rsq r8.w, r8.w + mul r9.xy, r8.wwww, r9.xyxx + dp2 r8.w, r9.xyxx, r0.xzxx + mad r9.x, r8.y, -|r3.y|, r7.z + min r9.x, r9.x, l(3.141593) + sincos null, r9.x, r9.x + ge r8.w, r8.w, r9.x + movc r8.y, r8.w, r8.y, r7.w + movc r7.w, r8.z, r8.y, r7.w + iadd r8.x, r8.x, l(-1) + endloop + div r2.w, r7.w, r3.x + add r6.x, r1.w, -r7.w + max r0.x, r0.x, l(-1.000000) + min r0.x, r0.x, l(1.000000) + add r6.y, -|r0.x|, l(1.000000) + sqrt r6.y, r6.y + mad r7.x, |r0.x|, l(-0.018729), l(0.074261) + mad r7.x, r7.x, |r0.x|, l(-0.212114) + mad r7.x, r7.x, |r0.x|, l(1.570729) + mul r7.y, r6.y, r7.x + mad r7.y, r7.y, l(-2.000000), l(3.141593) + lt r0.x, r0.x, -r0.x + and r0.x, r0.x, r7.y + mad r0.x, r7.x, r6.y, r0.x + ge r0.z, r0.z, l(0.000000) + movc r0.x, r0.z, r0.x, -r0.x + mad r0.w, r6.x, r3.y, r0.x + sincos r7.x, r0.x, r0.w + mov r7.y, -r0.x + dp2 r8.z, r7.xyxx, r5.zwzz + dp2 r0.x, r7.xyxx, r6.zwzz + dp2 r8.x, r7.xyxx, r4.xwxx + mul r0.z, r8.x, r8.z + mad r0.z, r0.x, r0.x, -r0.z + max r0.z, r0.z, l(0.000000) + sqrt r0.z, r0.z + lt r4.x, l(0.000000), r0.x + movc r0.z, r4.x, -r0.z, r0.z + add r8.y, -r0.x, r0.z + mul r0.x, r8.y, r8.z + mul r0.x, r0.x, l(-0.500000) + mad r0.z, r8.y, r8.y, r0.x + mad r0.x, r8.z, r8.x, r0.x + lt r0.x, |r0.z|, |r0.x| + movc r0.xz, r0.xxxx, r8.yyzy, r8.xxyx + ne r4.x, r0.z, l(0.000000) + div r0.x, r0.x, r0.z + and r0.x, r0.x, r4.x + mov_sat r0.x, r0.x + eq r0.z, r6.x, l(0.000000) + movc r5.y, r0.z, l(0), r0.x + max r5.x, r2.w, r5.y + endif + add r0.xz, -r4.yyzy, r2.xxzx + mad r0.xz, r0.xxzx, r5.xxxx, r4.yyzy + add r4.xy, r1.xyxx, -r2.xzxx + mad r2.xz, r4.xxyx, r5.xxxx, r2.xxzx + add r4.xy, -r1.xyxx, v1.zwzz + mad r1.xy, r4.xyxx, r5.xxxx, r1.xyxx + add r4.xy, -r0.xzxx, r2.xzxx + mad r0.xz, r4.xxyx, r5.xxxx, r0.xxzx + add r1.xy, -r2.xzxx, r1.xyxx + mad r1.xy, r1.xyxx, r5.xxxx, r2.xzxx + add r1.xy, -r0.xzxx, r1.xyxx + mad r3.xy, r1.xyxx, r5.xxxx, r0.xzxx + ne r0.x, r5.y, r5.x + dp2 r0.z, r1.xyxx, r1.xyxx + rsq r0.z, r0.z + mul r1.xy, r0.zzzz, r1.xyxx + max r0.z, r1.x, l(-1.000000) + min r0.z, r0.z, l(1.000000) + add r1.x, -|r0.z|, l(1.000000) + sqrt r1.x, r1.x + mad r2.x, |r0.z|, l(-0.018729), l(0.074261) + mad r2.x, r2.x, |r0.z|, l(-0.212114) + mad r2.x, r2.x, |r0.z|, l(1.570729) + mul r2.z, r1.x, r2.x + mad r2.z, r2.z, l(-2.000000), l(3.141593) + lt r0.z, r0.z, -r0.z + and r0.z, r0.z, r2.z + mad r0.z, r2.x, r1.x, r0.z + ge r1.x, r1.y, l(0.000000) + movc r0.z, r1.x, r0.z, -r0.z + movc r0.y, r0.x, r0.z, r0.w + endif +endif +ieq r0.x, r2.y, l(0x04000000) +ftou r0.zw, r1.zzzw +ishl r0.z, r0.z, l(16) +or r0.z, r0.w, r0.z +mul r0.y, r0.y, l(0.159155) +ge r0.w, r0.y, -r0.y +frc r0.y, |r0.y| +movc r0.y, r0.w, r0.y, -r0.y +mul r0.y, r0.y, l(6.283185) +movc r3.z, r0.x, r0.z, r0.y +mov o0.xyzw, r3.xyzw +ret +// Approximately 220 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 225, 236, + 243, 192, 161, 17, 15, 154, + 184, 138, 170, 204, 240, 23, + 147, 97, 1, 0, 0, 0, + 40, 27, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 160, 0, 0, 0, 88, 1, + 0, 0, 140, 1, 0, 0, + 140, 26, 0, 0, 82, 68, + 69, 70, 100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 255, 255, 0, 1, 0, 0, + 60, 0, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, + 48, 46, 49, 0, 73, 83, + 71, 78, 176, 0, 0, 0, + 6, 0, 0, 0, 8, 0, + 0, 0, 152, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 15, + 0, 0, 152, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 15, 15, + 0, 0, 152, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 15, 15, + 0, 0, 152, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 7, 7, + 0, 0, 152, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 1, 1, + 0, 0, 161, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 5, 0, 0, 0, 15, 0, + 0, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 83, + 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 171, + 171, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171, + 83, 72, 69, 88, 248, 24, + 0, 0, 80, 0, 0, 0, + 62, 6, 0, 0, 106, 8, + 0, 1, 98, 32, 0, 3, + 242, 16, 16, 0, 0, 0, + 0, 0, 98, 32, 0, 3, + 242, 16, 16, 0, 1, 0, + 0, 0, 98, 32, 0, 3, + 242, 16, 16, 0, 2, 0, + 0, 0, 98, 32, 0, 3, + 114, 16, 16, 0, 3, 0, + 0, 0, 98, 8, 0, 3, + 18, 16, 16, 0, 4, 0, + 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, + 0, 0, 104, 0, 0, 2, + 10, 0, 0, 0, 57, 0, + 0, 7, 50, 0, 16, 0, + 0, 0, 0, 0, 230, 26, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 0, 0, + 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 57, 0, 0, 7, 98, 0, + 16, 0, 0, 0, 0, 0, + 166, 27, 16, 0, 0, 0, + 0, 0, 6, 17, 16, 0, + 1, 0, 0, 0, 60, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 194, 0, 16, 0, 0, 0, + 0, 0, 86, 5, 16, 0, + 0, 0, 0, 0, 6, 20, + 16, 0, 1, 0, 0, 0, + 166, 30, 16, 0, 1, 0, + 0, 0, 55, 0, 0, 9, + 82, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 166, 27, + 16, 0, 0, 0, 0, 0, + 166, 11, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 8, + 82, 0, 16, 0, 0, 0, + 0, 0, 6, 2, 16, 0, + 0, 0, 0, 0, 6, 17, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 57, 0, + 0, 7, 50, 0, 16, 0, + 1, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, + 230, 26, 16, 0, 1, 0, + 0, 0, 60, 0, 0, 7, + 130, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 55, 0, 0, 9, 50, 0, + 16, 0, 1, 0, 0, 0, + 86, 5, 16, 0, 0, 0, + 0, 0, 230, 26, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 162, 0, + 16, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 0, 0, + 0, 0, 6, 20, 16, 0, + 1, 0, 0, 0, 6, 4, + 16, 0, 1, 0, 0, 0, + 0, 0, 0, 8, 162, 0, + 16, 0, 0, 0, 0, 0, + 86, 13, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 166, 30, 16, 0, 1, 0, + 0, 0, 65, 0, 0, 5, + 18, 0, 16, 0, 1, 0, + 0, 0, 10, 16, 16, 0, + 2, 0, 0, 0, 52, 0, + 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 28, 0, 0, 5, + 18, 0, 16, 0, 2, 0, + 0, 0, 42, 16, 16, 0, + 2, 0, 0, 0, 1, 0, + 0, 7, 34, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 255, 3, + 0, 0, 86, 0, 0, 5, + 18, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 85, 0, + 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 10, 0, + 0, 0, 86, 0, 0, 5, + 34, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 0, 0, + 0, 8, 66, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 2, 0, 0, 0, 26, 16, + 16, 0, 2, 0, 0, 0, + 29, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 8, 66, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 1, 0, 0, 10, 114, 0, + 16, 0, 4, 0, 0, 0, + 6, 16, 16, 0, 4, 0, + 0, 0, 2, 64, 0, 0, + 255, 255, 255, 227, 0, 0, + 0, 28, 0, 0, 0, 2, + 0, 0, 0, 0, 79, 0, + 0, 7, 130, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 8, + 26, 0, 16, 0, 4, 0, + 0, 0, 49, 0, 0, 10, + 50, 0, 16, 0, 5, 0, + 0, 0, 166, 10, 16, 0, + 2, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 32, 64, + 0, 0, 96, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 10, 16, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 64, 0, 55, 0, + 0, 9, 130, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 10, 16, 16, 0, + 4, 0, 0, 0, 49, 0, + 0, 7, 18, 0, 16, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 192, 63, + 42, 0, 16, 0, 2, 0, + 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, + 60, 0, 0, 7, 34, 0, + 16, 0, 5, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 32, 0, 55, 0, + 0, 9, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 39, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 32, 0, 0, 7, + 34, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 4, + 60, 0, 0, 7, 34, 0, + 16, 0, 4, 0, 0, 0, + 26, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 10, 194, 0, 16, 0, + 4, 0, 0, 0, 86, 9, + 16, 0, 2, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 0, 0, + 128, 191, 55, 0, 0, 9, + 98, 0, 16, 0, 5, 0, + 0, 0, 86, 5, 16, 0, + 4, 0, 0, 0, 166, 11, + 16, 0, 4, 0, 0, 0, + 86, 6, 16, 0, 2, 0, + 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 5, 0, + 0, 0, 10, 16, 16, 0, + 4, 0, 0, 0, 55, 0, + 0, 9, 210, 0, 16, 0, + 5, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, + 6, 9, 16, 0, 2, 0, + 0, 0, 6, 9, 16, 0, + 5, 0, 0, 0, 49, 0, + 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 42, 16, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 16, 0, + 1, 64, 0, 0, 0, 0, + 8, 0, 60, 0, 0, 7, + 66, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, + 54, 0, 0, 5, 50, 0, + 16, 0, 1, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 5, 0, + 0, 0, 230, 26, 16, 0, + 1, 0, 0, 0, 55, 0, + 0, 9, 242, 0, 16, 0, + 1, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, + 70, 14, 16, 0, 1, 0, + 0, 0, 70, 14, 16, 0, + 5, 0, 0, 0, 55, 0, + 0, 9, 98, 0, 16, 0, + 4, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, + 6, 17, 16, 0, 0, 0, + 0, 0, 166, 27, 16, 0, + 1, 0, 0, 0, 55, 0, + 0, 9, 82, 0, 16, 0, + 0, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, + 6, 2, 16, 0, 0, 0, + 0, 0, 86, 7, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 34, 0, 16, 0, + 3, 0, 0, 0, 58, 16, + 16, 0, 2, 0, 0, 0, + 54, 0, 0, 5, 66, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 4, 0, + 0, 0, 54, 0, 0, 5, + 18, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 54, 0, + 0, 5, 34, 0, 16, 0, + 2, 0, 0, 0, 42, 16, + 16, 0, 3, 0, 0, 0, + 55, 0, 0, 9, 178, 0, + 16, 0, 3, 0, 0, 0, + 246, 15, 16, 0, 2, 0, + 0, 0, 70, 8, 16, 0, + 3, 0, 0, 0, 70, 8, + 16, 0, 2, 0, 0, 0, + 24, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 24, 0, + 0, 7, 34, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 28, 79, 0, + 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 8, + 26, 0, 16, 0, 2, 0, + 0, 0, 60, 0, 0, 7, + 18, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 31, 0, 4, 3, 10, 0, + 16, 0, 2, 0, 0, 0, + 55, 0, 0, 9, 162, 0, + 16, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 2, 0, + 0, 0, 86, 13, 16, 0, + 0, 0, 0, 0, 6, 20, + 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 63, 49, 0, + 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 55, 0, 0, 9, + 50, 0, 16, 0, 3, 0, + 0, 0, 6, 0, 16, 0, + 2, 0, 0, 0, 150, 5, + 16, 0, 4, 0, 0, 0, + 230, 26, 16, 0, 1, 0, + 0, 0, 55, 0, 0, 9, + 162, 0, 16, 0, 0, 0, + 0, 0, 6, 0, 16, 0, + 2, 0, 0, 0, 6, 8, + 16, 0, 0, 0, 0, 0, + 86, 13, 16, 0, 0, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 2, 0, + 0, 0, 214, 5, 16, 0, + 0, 0, 0, 0, 214, 5, + 16, 0, 0, 0, 0, 0, + 68, 0, 0, 5, 18, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 56, 0, 0, 7, + 162, 0, 16, 0, 0, 0, + 0, 0, 86, 13, 16, 0, + 0, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, + 52, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 191, 51, 0, + 0, 7, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 8, + 18, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 128, + 193, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 75, 0, + 0, 5, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 50, 0, 0, 10, 66, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 48, 110, + 153, 188, 1, 64, 0, 0, + 39, 22, 152, 61, 50, 0, + 0, 10, 66, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 132, 52, + 89, 190, 50, 0, 0, 10, + 66, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 128, 129, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 164, 13, 201, 63, + 56, 0, 0, 7, 18, 0, + 16, 0, 4, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 50, 0, + 0, 9, 18, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 192, 1, 64, 0, 0, + 219, 15, 73, 64, 49, 0, + 0, 8, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 4, 0, 0, 0, 50, 0, + 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 29, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 10, + 34, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 18, 0, 0, 1, 55, 0, + 0, 9, 82, 0, 16, 0, + 2, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, + 166, 27, 16, 0, 0, 0, + 0, 0, 166, 27, 16, 0, + 1, 0, 0, 0, 1, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 128, 31, 0, 4, 3, + 58, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 3, 0, + 0, 0, 134, 0, 16, 0, + 2, 0, 0, 0, 54, 0, + 0, 5, 34, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 18, 0, 0, 1, 24, 0, + 0, 7, 130, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 31, 0, 4, 3, + 58, 0, 16, 0, 0, 0, + 0, 0, 14, 0, 0, 7, + 18, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 54, 0, 0, 5, 34, 0, + 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 18, 0, + 0, 1, 0, 0, 0, 8, + 146, 0, 16, 0, 4, 0, + 0, 0, 86, 9, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 6, 8, 16, 0, + 2, 0, 0, 0, 0, 0, + 0, 8, 194, 0, 16, 0, + 5, 0, 0, 0, 86, 9, + 16, 128, 65, 0, 0, 0, + 4, 0, 0, 0, 166, 30, + 16, 0, 1, 0, 0, 0, + 0, 0, 0, 8, 50, 0, + 16, 0, 6, 0, 0, 0, + 70, 0, 16, 0, 1, 0, + 0, 0, 134, 0, 16, 128, + 65, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 8, + 194, 0, 16, 0, 6, 0, + 0, 0, 6, 12, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 6, 4, 16, 0, + 6, 0, 0, 0, 50, 0, + 0, 12, 194, 0, 16, 0, + 5, 0, 0, 0, 6, 4, + 16, 0, 6, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 64, 192, 0, 0, + 64, 192, 166, 14, 16, 0, + 5, 0, 0, 0, 0, 0, + 0, 7, 130, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 7, + 50, 0, 16, 0, 6, 0, + 0, 0, 246, 15, 16, 0, + 2, 0, 0, 0, 230, 10, + 16, 0, 6, 0, 0, 0, + 56, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 56, 0, + 0, 7, 50, 0, 16, 0, + 7, 0, 0, 0, 246, 15, + 16, 0, 2, 0, 0, 0, + 198, 0, 16, 0, 4, 0, + 0, 0, 0, 0, 0, 7, + 130, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 191, + 51, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, + 7, 0, 0, 0, 134, 0, + 16, 0, 0, 0, 0, 0, + 134, 0, 16, 0, 0, 0, + 0, 0, 68, 0, 0, 5, + 66, 0, 16, 0, 7, 0, + 0, 0, 42, 0, 16, 0, + 7, 0, 0, 0, 56, 0, + 0, 7, 82, 0, 16, 0, + 0, 0, 0, 0, 6, 2, + 16, 0, 0, 0, 0, 0, + 166, 10, 16, 0, 7, 0, + 0, 0, 0, 0, 0, 7, + 66, 0, 16, 0, 7, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 56, 0, 0, 8, 66, 0, + 16, 0, 7, 0, 0, 0, + 26, 0, 16, 128, 129, 0, + 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 7, 0, + 0, 0, 54, 0, 0, 5, + 130, 0, 16, 0, 7, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 18, 0, 16, 0, + 8, 0, 0, 0, 1, 64, + 0, 0, 9, 0, 0, 0, + 48, 0, 0, 1, 34, 0, + 0, 7, 34, 0, 16, 0, + 8, 0, 0, 0, 10, 0, + 16, 0, 8, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 3, 0, 4, 3, + 26, 0, 16, 0, 8, 0, + 0, 0, 43, 0, 0, 5, + 34, 0, 16, 0, 8, 0, + 0, 0, 10, 0, 16, 0, + 8, 0, 0, 0, 25, 0, + 0, 5, 34, 0, 16, 0, + 8, 0, 0, 0, 26, 0, + 16, 0, 8, 0, 0, 0, + 0, 0, 0, 7, 34, 0, + 16, 0, 8, 0, 0, 0, + 58, 0, 16, 0, 7, 0, + 0, 0, 26, 0, 16, 0, + 8, 0, 0, 0, 29, 0, + 0, 7, 66, 0, 16, 0, + 8, 0, 0, 0, 58, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 8, 0, + 0, 0, 50, 0, 0, 9, + 50, 0, 16, 0, 9, 0, + 0, 0, 86, 5, 16, 0, + 8, 0, 0, 0, 230, 10, + 16, 0, 5, 0, 0, 0, + 70, 0, 16, 0, 6, 0, + 0, 0, 50, 0, 0, 9, + 50, 0, 16, 0, 9, 0, + 0, 0, 86, 5, 16, 0, + 8, 0, 0, 0, 70, 0, + 16, 0, 9, 0, 0, 0, + 70, 0, 16, 0, 7, 0, + 0, 0, 15, 0, 0, 7, + 130, 0, 16, 0, 8, 0, + 0, 0, 70, 0, 16, 0, + 9, 0, 0, 0, 70, 0, + 16, 0, 9, 0, 0, 0, + 68, 0, 0, 5, 130, 0, + 16, 0, 8, 0, 0, 0, + 58, 0, 16, 0, 8, 0, + 0, 0, 56, 0, 0, 7, + 50, 0, 16, 0, 9, 0, + 0, 0, 246, 15, 16, 0, + 8, 0, 0, 0, 70, 0, + 16, 0, 9, 0, 0, 0, + 15, 0, 0, 7, 130, 0, + 16, 0, 8, 0, 0, 0, + 70, 0, 16, 0, 9, 0, + 0, 0, 134, 0, 16, 0, + 0, 0, 0, 0, 50, 0, + 0, 10, 18, 0, 16, 0, + 9, 0, 0, 0, 26, 0, + 16, 0, 8, 0, 0, 0, + 26, 0, 16, 128, 193, 0, + 0, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 7, 0, + 0, 0, 51, 0, 0, 7, + 18, 0, 16, 0, 9, 0, + 0, 0, 10, 0, 16, 0, + 9, 0, 0, 0, 1, 64, + 0, 0, 219, 15, 73, 64, + 77, 0, 0, 6, 0, 208, + 0, 0, 18, 0, 16, 0, + 9, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 29, 0, 0, 7, 130, 0, + 16, 0, 8, 0, 0, 0, + 58, 0, 16, 0, 8, 0, + 0, 0, 10, 0, 16, 0, + 9, 0, 0, 0, 55, 0, + 0, 9, 34, 0, 16, 0, + 8, 0, 0, 0, 58, 0, + 16, 0, 8, 0, 0, 0, + 26, 0, 16, 0, 8, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 55, 0, + 0, 9, 130, 0, 16, 0, + 7, 0, 0, 0, 42, 0, + 16, 0, 8, 0, 0, 0, + 26, 0, 16, 0, 8, 0, + 0, 0, 58, 0, 16, 0, + 7, 0, 0, 0, 30, 0, + 0, 7, 18, 0, 16, 0, + 8, 0, 0, 0, 10, 0, + 16, 0, 8, 0, 0, 0, + 1, 64, 0, 0, 255, 255, + 255, 255, 22, 0, 0, 1, + 14, 0, 0, 7, 130, 0, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 7, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 0, 0, + 0, 8, 18, 0, 16, 0, + 6, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 58, 0, 16, 128, 65, 0, + 0, 0, 7, 0, 0, 0, + 52, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 191, 51, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 8, + 34, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 128, + 193, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 75, 0, + 0, 5, 34, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, + 50, 0, 0, 10, 18, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 48, 110, + 153, 188, 1, 64, 0, 0, + 39, 22, 152, 61, 50, 0, + 0, 10, 18, 0, 16, 0, + 7, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 132, 52, + 89, 190, 50, 0, 0, 10, + 18, 0, 16, 0, 7, 0, + 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 10, 0, + 16, 128, 129, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 164, 13, 201, 63, + 56, 0, 0, 7, 34, 0, + 16, 0, 7, 0, 0, 0, + 26, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 7, 0, 0, 0, 50, 0, + 0, 9, 34, 0, 16, 0, + 7, 0, 0, 0, 26, 0, + 16, 0, 7, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 192, 1, 64, 0, 0, + 219, 15, 73, 64, 49, 0, + 0, 8, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 7, 0, 0, 0, 50, 0, + 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 7, 0, 0, 0, + 26, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 29, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 10, + 18, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 50, 0, 0, 9, 130, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 77, 0, 0, 7, 18, 0, + 16, 0, 7, 0, 0, 0, + 18, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 6, 34, 0, 16, 0, + 7, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, + 8, 0, 0, 0, 70, 0, + 16, 0, 7, 0, 0, 0, + 230, 10, 16, 0, 5, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 7, 0, 0, 0, 230, 10, + 16, 0, 6, 0, 0, 0, + 15, 0, 0, 7, 18, 0, + 16, 0, 8, 0, 0, 0, + 70, 0, 16, 0, 7, 0, + 0, 0, 198, 0, 16, 0, + 4, 0, 0, 0, 56, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 8, 0, 0, 0, + 42, 0, 16, 0, 8, 0, + 0, 0, 50, 0, 0, 10, + 66, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 52, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 75, 0, + 0, 5, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 49, 0, 0, 7, 18, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 55, 0, + 0, 10, 66, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 8, + 34, 0, 16, 0, 8, 0, + 0, 0, 10, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 8, 0, 0, 0, + 42, 0, 16, 0, 8, 0, + 0, 0, 56, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 191, + 50, 0, 0, 9, 66, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 8, 0, + 0, 0, 26, 0, 16, 0, + 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 50, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 8, 0, + 0, 0, 10, 0, 16, 0, + 8, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 49, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 82, 0, + 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 0, 0, + 0, 0, 86, 6, 16, 0, + 8, 0, 0, 0, 6, 1, + 16, 0, 8, 0, 0, 0, + 57, 0, 0, 7, 18, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 14, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 1, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 4, 0, 0, 0, + 54, 32, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 24, 0, 0, 7, + 66, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 34, 0, + 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 52, 0, 0, 7, 18, 0, + 16, 0, 5, 0, 0, 0, + 58, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 21, 0, + 0, 1, 0, 0, 0, 8, + 82, 0, 16, 0, 0, 0, + 0, 0, 86, 6, 16, 128, + 65, 0, 0, 0, 4, 0, + 0, 0, 6, 2, 16, 0, + 2, 0, 0, 0, 50, 0, + 0, 9, 82, 0, 16, 0, + 0, 0, 0, 0, 6, 2, + 16, 0, 0, 0, 0, 0, + 6, 0, 16, 0, 5, 0, + 0, 0, 86, 6, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 8, 50, 0, 16, 0, + 4, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, + 134, 0, 16, 128, 65, 0, + 0, 0, 2, 0, 0, 0, + 50, 0, 0, 9, 82, 0, + 16, 0, 2, 0, 0, 0, + 6, 1, 16, 0, 4, 0, + 0, 0, 6, 0, 16, 0, + 5, 0, 0, 0, 6, 2, + 16, 0, 2, 0, 0, 0, + 0, 0, 0, 8, 50, 0, + 16, 0, 4, 0, 0, 0, + 70, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, + 230, 26, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, + 50, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, + 4, 0, 0, 0, 6, 0, + 16, 0, 5, 0, 0, 0, + 70, 0, 16, 0, 1, 0, + 0, 0, 0, 0, 0, 8, + 50, 0, 16, 0, 4, 0, + 0, 0, 134, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 134, 0, 16, 0, + 2, 0, 0, 0, 50, 0, + 0, 9, 82, 0, 16, 0, + 0, 0, 0, 0, 6, 1, + 16, 0, 4, 0, 0, 0, + 6, 0, 16, 0, 5, 0, + 0, 0, 6, 2, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 8, 50, 0, 16, 0, + 1, 0, 0, 0, 134, 0, + 16, 128, 65, 0, 0, 0, + 2, 0, 0, 0, 70, 0, + 16, 0, 1, 0, 0, 0, + 50, 0, 0, 9, 50, 0, + 16, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 1, 0, + 0, 0, 6, 0, 16, 0, + 5, 0, 0, 0, 134, 0, + 16, 0, 2, 0, 0, 0, + 0, 0, 0, 8, 50, 0, + 16, 0, 1, 0, 0, 0, + 134, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 9, + 50, 0, 16, 0, 3, 0, + 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 6, 0, + 16, 0, 5, 0, 0, 0, + 134, 0, 16, 0, 0, 0, + 0, 0, 57, 0, 0, 7, + 18, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 10, 0, + 16, 0, 5, 0, 0, 0, + 15, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, + 70, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 68, 0, + 0, 5, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 50, 0, + 16, 0, 1, 0, 0, 0, + 166, 10, 16, 0, 0, 0, + 0, 0, 70, 0, 16, 0, + 1, 0, 0, 0, 52, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 191, 51, 0, 0, 7, + 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 0, 0, 0, 8, 18, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 128, 193, 0, + 0, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 75, 0, 0, 5, + 18, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 50, 0, + 0, 10, 18, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 128, 129, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 48, 110, 153, 188, + 1, 64, 0, 0, 39, 22, + 152, 61, 50, 0, 0, 10, + 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 128, 129, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 132, 52, 89, 190, + 50, 0, 0, 10, 18, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 128, + 129, 0, 0, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 164, 13, 201, 63, 56, 0, + 0, 7, 66, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 50, 0, 0, 9, + 66, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 192, + 1, 64, 0, 0, 219, 15, + 73, 64, 49, 0, 0, 8, + 66, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 50, 0, 0, 9, + 66, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 29, 0, 0, 7, + 18, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 55, 0, 0, 10, 66, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 55, 0, + 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 21, 0, + 0, 1, 21, 0, 0, 1, + 32, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 4, 28, 0, + 0, 5, 194, 0, 16, 0, + 0, 0, 0, 0, 166, 14, + 16, 0, 1, 0, 0, 0, + 41, 0, 0, 7, 66, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 16, 0, 0, 0, 60, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 58, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 131, 249, 34, 62, + 29, 0, 0, 8, 130, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 26, 0, 0, 6, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 128, + 129, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 10, + 34, 0, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 34, 0, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 219, 15, 201, 64, 55, 0, + 0, 9, 66, 0, 16, 0, + 3, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 3, 0, 0, 0, + 62, 0, 0, 1, 83, 84, + 65, 84, 148, 0, 0, 0, + 220, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 130, 0, + 0, 0, 6, 0, 0, 0, + 22, 0, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 28, 0, 0, 0, + 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; diff --git a/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h b/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h new file mode 100644 index 000000000..65fdb207d --- /dev/null +++ b/thirdparty/rive_renderer/source/generated/shaders/d3d/tessellate.vert.h @@ -0,0 +1,2400 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Buffer Definitions: +// +// cbuffer MB +// { +// +// struct +// { +// +// float Pb; // Offset: 0 +// float Yc; // Offset: 4 +// float Re; // Offset: 8 +// float Se; // Offset: 12 +// uint m6; // Offset: 16 +// uint mg; // Offset: 20 +// uint De; // Offset: 24 +// uint Ee; // Offset: 28 +// int4 U7; // Offset: 32 +// float2 jg; // Offset: 48 +// float2 Zc; // Offset: 56 +// uint W1; // Offset: 64 +// float ng; // Offset: 68 +// uint Y5; // Offset: 72 +// float O2; // Offset: 76 +// float ad; // Offset: 80 +// uint ye; // Offset: 84 +// float v3; // Offset: 88 +// float w3; // Offset: 92 +// float bd; // Offset: 96 +// uint gg; // Offset: 100 +// +// } k; // Offset: 0 Size: 104 +// +// } +// +// Resource bind info for LB +// { +// +// uint4 $Element; // Offset: 0 Size: 16 +// +// } +// +// Resource bind info for XC +// { +// +// uint4 $Element; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// T9 sampler NA NA s10 1 +// LB texture struct r/o t3 1 +// XC texture struct r/o t6 1 +// QC texture float 1darray t10 1 +// MB cbuffer NA NA cb0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// ZC 0 xyzw 0 NONE float xyzw +// AD 0 xyzw 1 NONE float xyzw +// OC 0 xyzw 2 NONE float xyzw +// RB 0 xyzw 3 NONE uint xyzw +// SV_VertexID 0 x 4 VERTID uint x +// SV_InstanceID 0 x 5 INSTID uint +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// TEXCOORD 0 xyzw 0 NONE float xyzw +// TEXCOORD 1 xyzw 1 NONE float xyzw +// TEXCOORD 2 xyzw 2 NONE float xyzw +// TEXCOORD 3 xyz 3 NONE float xyz +// TEXCOORD 4 x 4 NONE uint x +// SV_Position 0 xyzw 5 POS float xyzw +// +vs_5_0 +dcl_globalFlags refactoringAllowed +dcl_constantbuffer CB0[1], immediateIndexed +dcl_sampler s10, mode_default +dcl_resource_structured t3, 16 +dcl_resource_structured t6, 16 +dcl_resource_texture1darray (float,float,float,float) t10 +dcl_input v0.xyzw +dcl_input v1.xyzw +dcl_input v2.xyzw +dcl_input v3.xyzw +dcl_input_sgv v4.x, vertex_id +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyz +dcl_output o4.x +dcl_output_siv o5.xyzw, position +dcl_temps 10 +ult r0.x, v4.x, l(4) +movc r0.y, r0.x, v2.z, v2.w +movc r0.x, r0.x, v3.x, v3.y +ibfe r0.z, l(16), l(0), r0.x +ishr r0.x, r0.x, l(16) +itof r0.xz, r0.xxzx +and r1.xy, v4.xxxx, l(1, 2, 0, 0) +movc r0.w, r1.x, r0.x, r0.z +add r1.x, r0.y, l(1.000000) +movc r1.x, r1.y, r0.y, r1.x +add r1.y, -r0.z, r0.x +mul r1.y, r1.y, cb0[0].y +lt r1.y, r1.y, l(0.000000) +mad r0.y, r0.y, l(2.000000), l(1.000000) +add r0.y, -r1.x, r0.y +movc r0.y, r1.y, r0.y, r1.x +ubfe r1.x, l(10), l(10), v3.z +ushr r1.y, v3.z, l(20) +and r2.xyzw, v3.zwww, l(1023, 0x0000ffff, 0x20000000, 0x1e000000) +ult r1.z, l(0), r2.y +umax r1.w, r2.y, l(1) +iadd r1.w, r1.w, l(-1) +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r1.w, r1.w, l(8), t6.xxxx +and r1.z, r1.w, r1.z +ishl r1.w, r1.z, l(2) +bfi r2.y, l(30), l(2), r1.z, l(1) +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r3.xy, r2.y, l(8), t3.xyxx +movc r3.xy, r1.zzzz, r3.xyxx, l(0,0,0,0) +ne r1.z, r3.y, l(0.000000) +eq r2.y, r3.x, l(0.000000) +and r1.z, r1.z, r2.y +if_nz r1.z + add r4.xyzw, -v0.xyzw, v1.zwxy + dp2 r1.z, r4.xyxx, r4.xyxx + sqrt r2.y, r1.z + ne r3.x, r2.y, l(0.000000) + if_nz r3.x + mul r3.xz, r4.yyxy, l(-1.000000, 0.000000, 1.000000, 0.000000) + div r3.xz, r3.xxzx, r2.yyyy + add r5.xy, -v0.xyxx, v1.xyxx + dp2 r2.y, r3.xzxx, r5.xyxx + add r5.xy, -v0.xyxx, v0.zwzz + dp2 r3.x, r3.xzxx, r5.xyxx + add r2.y, -r2.y, r3.x + mul r3.z, r2.y, l(3.000000) + add r2.y, -r2.y, -r3.x + mov r3.w, l(0.500000) + mov r5.x, l(0) + loop + ige r5.y, r5.x, l(3) + breakc_nz r5.y + mul r5.y, r3.w, r3.z + mad r5.y, r5.y, r3.w, -r3.x + mad r5.z, r3.z, r3.w, r2.y + add r5.w, r5.z, r5.z + lt r5.z, r5.z, l(0.000000) + movc r5.y, r5.z, -r5.y, r5.y + lt r5.z, l(0.000000), r5.y + lt r6.x, r5.y, |r5.w| + div r5.y, r5.y, |r5.w| + movc r5.y, r6.x, r5.y, l(1.000000) + and r3.w, r5.y, r5.z + iadd r5.x, r5.x, l(1) + endloop + mul r2.y, r2.y, l(3.000000) + mad r2.y, r3.w, r3.z, r2.y + mul r3.x, r3.x, l(3.000000) + mad r2.y, r3.w, r2.y, r3.x + mul r2.y, r2.y, r3.w + mov r2.y, |r2.y| + else + mov r3.w, l(0.500000) + mov r2.y, l(0) + endif + mul r3.x, r3.y, l(0.333333) + add r5.xyzw, -v0.xyxy, v0.zwzw + add r6.xy, r4.zwzz, -r5.zwzz + mad r7.xyzw, r4.zwzw, l(-3.000000, -3.000000, -3.000000, -3.000000), r4.xyxy + add r8.xyzw, r6.xyxy, r6.xyxy + mad r4.zw, r7.zzzw, r3.wwww, r8.xxxy + mad r4.zw, r4.zzzw, r3.wwww, r5.xxxy + mul r4.zw, r4.zzzw, l(0.000000, 0.000000, 3.000000, 3.000000) + dp2 r3.z, r4.zwzz, r4.zwzz + sqrt r3.z, r3.z + ne r6.z, r3.z, l(0.000000) + if_nz r6.z + div r3.z, l(1.000000, 1.000000, 1.000000, 1.000000), r3.z + mul r4.zw, r3.zzzz, r4.zzzw + dp2 r3.z, r7.zwzz, r4.zwzz + add r6.z, r3.z, r3.z + dp2 r6.x, r6.xyxx, r4.zwzz + mul r6.x, r6.x, l(4.000000) + mad r6.x, r6.z, r3.w, r6.x + mul r6.x, r3.w, r6.x + dp2 r4.z, r5.zwzz, r4.zwzz + mul r4.z, r4.z, l(6.000000) + mad r4.z, r6.x, l(3.000000), r4.z + add r4.w, -r3.w, l(1.000000) + min r4.w, r3.w, r4.w + mul r6.x, r4.w, r4.w + mad r6.x, r6.x, r6.z, r4.z + mul r4.w, r4.w, r6.x + mul r4.w, r4.w, l(0.999900) + min r4.w, r3.x, r4.w + eq r3.z, r3.z, l(0.000000) + if_nz r3.z + div r3.z, r4.w, r4.z + else + div r6.x, l(1.000000, 1.000000, 1.000000, 1.000000), r6.z + mul r4.z, r4.z, r6.x + mul r4.w, -r4.w, r6.x + mul r4.z, r4.z, l(-0.333333) + mul r6.x, r4.w, l(0.500000) + mul r6.y, r4.z, r4.z + mul r6.y, r4.z, r6.y + mad r6.y, r6.x, r6.x, -r6.y + lt r6.z, r6.y, l(0.000000) + sqrt r6.w, r4.z + mul r9.x, r6.w, r6.w + mul r9.x, r6.w, r9.x + div r9.x, r6.x, r9.x + add r9.y, -|r9.x|, l(1.000000) + sqrt r9.y, r9.y + mad r9.z, |r9.x|, l(-0.018729), l(0.074261) + mad r9.z, r9.z, |r9.x|, l(-0.212114) + mad r9.z, r9.z, |r9.x|, l(1.570729) + mul r9.w, r9.y, r9.z + mad r9.w, r9.w, l(-2.000000), l(3.141593) + lt r9.x, r9.x, -r9.x + and r9.x, r9.x, r9.w + mad r9.x, r9.z, r9.y, r9.x + mul r6.w, r6.w, l(-2.000000) + mad r9.x, r9.x, l(0.333333), l(-2.094395) + sincos null, r9.x, r9.x + mul r6.w, r6.w, r9.x + sqrt r6.y, r6.y + add r6.x, r6.y, |r6.x| + log r6.x, r6.x + mul r6.x, r6.x, l(0.333333) + exp r6.x, r6.x + lt r4.w, r4.w, l(0.000000) + movc r4.w, r4.w, -r6.x, r6.x + ne r6.x, r4.w, l(0.000000) + div r4.z, r4.z, r4.w + add r4.z, r4.z, r4.w + and r4.z, r4.z, r6.x + movc r3.z, r6.z, r6.w, r4.z + endif + mov r6.zw, |r3.zzzz| + mov r6.xy, -r6.wwww + add r6.xyzw, r3.wwww, r6.xyzw + mad r7.xyzw, r7.xyzw, r6.xyzw, r8.xyzw + mad r5.xyzw, r7.xyzw, r6.xyzw, r5.xyzw + ne r3.zw, v0.zzzw, v0.xxxy + or r3.z, r3.w, r3.z + ne r4.zw, v0.zzzw, v1.xxxy + or r3.w, r4.w, r4.z + movc r4.zw, r3.wwww, v1.xxxy, v1.zzzw + movc r4.zw, r3.zzzz, v0.zzzw, r4.zzzw + add r4.zw, r4.zzzw, -v0.xxxy + ne r6.xz, v1.xxyx, v1.zzwz + or r3.z, r6.z, r6.x + movc r6.xz, r3.wwww, v0.zzwz, v0.xxyx + movc r3.zw, r3.zzzz, v1.xxxy, r6.xxxz + add r3.zw, -r3.zzzw, v1.zzzw + lt r6.x, r6.y, l(0.001000) + movc r4.zw, r6.xxxx, r4.zzzw, r5.xxxy + lt r5.x, l(0.999000), r6.w + movc r3.zw, r5.xxxx, r3.zzzw, r5.zzzw + dp2 r5.x, r4.zwzz, r3.zwzz + dp2 r4.z, r4.zwzz, r4.zwzz + dp2 r3.z, r3.zwzz, r3.zwzz + mul r3.z, r3.z, r4.z + eq r3.w, r3.z, l(0.000000) + rsq r3.z, r3.z + mul r3.z, r3.z, r5.x + max r3.z, r3.z, l(-1.000000) + min r3.z, r3.z, l(1.000000) + movc r3.z, r3.w, l(1.000000), r3.z + add r3.w, -|r3.z|, l(1.000000) + sqrt r3.w, r3.w + mad r4.z, |r3.z|, l(-0.018729), l(0.074261) + mad r4.z, r4.z, |r3.z|, l(-0.212114) + mad r4.z, r4.z, |r3.z|, l(1.570729) + mul r4.w, r3.w, r4.z + mad r4.w, r4.w, l(-2.000000), l(3.141593) + lt r3.z, r3.z, -r3.z + and r3.z, r3.z, r4.w + mad r3.z, r4.z, r3.w, r3.z + else + mov r3.z, l(0) + endif + mad r3.z, -r3.z, l(0.318310), l(1.000000) + mul r3.x, r3.x, r3.x + div r1.z, r1.z, r3.x + add r1.z, r1.z, l(-1.000000) + mul r1.z, r1.z, l(0.500000) + min r1.z, r1.z, r3.z + min r1.z, r1.z, l(0.990000) + mul r5.x, r1.z, l(0.500000) + mov r5.y, l(1.000000) + sample_l_indexable(texture1darray)(float,float,float,float) r1.z, r5.xyxx, t10.yzxw, s10, l(0.000000) + mad r1.z, r1.z, l(-2.000000), l(1.000000) + mul r1.z, r3.y, r1.z + lt r3.x, l(0.000000), r1.z + lt r3.y, r1.z, r2.y + div r1.z, r1.z, r2.y + movc r1.z, r3.y, r1.z, l(1.000000) + and r1.z, r1.z, r3.x + mad r3.xyzw, r4.xyxy, l(0.333333, 0.333333, 0.666667, 0.666667), v0.xyxy + add r3.xy, r3.xyxx, -v0.zwzz + mad r4.xy, r1.zzzz, r3.xyxx, v0.zwzz + add r3.xy, r3.zwzz, -v1.xyxx + mad r3.xy, r1.zzzz, r3.xyxx, v1.xyxx +else + mov r4.xy, v0.zwzz + mov r3.xy, v1.xyxx +endif +ld_structured_indexable(structured_buffer, stride=16)(mixed,mixed,mixed,mixed) r5.xyzw, r1.w, l(0), t3.xyzw +mad r1.zw, r4.xxxy, l(0.000000, 0.000000, -2.000000, -2.000000), r3.xxxy +add r1.zw, r1.zzzw, v0.xxxy +dp2 r6.x, r1.zwzz, r5.xzxx +dp2 r6.y, r1.zwzz, r5.ywyy +mad r1.zw, r3.xxxy, l(0.000000, 0.000000, -2.000000, -2.000000), v1.zzzw +add r1.zw, r4.xxxy, r1.zzzw +dp2 r7.x, r1.zwzz, r5.xzxx +dp2 r7.y, r1.zwzz, r5.ywyy +dp2 r1.z, r6.xyxx, r6.xyxx +dp2 r1.w, r7.xyxx, r7.xyxx +max r1.z, r1.w, r1.z +sqrt r1.z, r1.z +mul r1.z, r1.z, l(3.000000) +sqrt r1.z, r1.z +round_pi r1.z, r1.z +max r1.z, r1.z, l(1.000000) +ftou r1.z, r1.z +umin r1.z, r2.x, r1.z +movc r1.z, r2.z, r1.z, r2.x +iadd r1.w, r1.x, r1.z +iadd r1.w, r1.y, r1.w +iadd r1.w, r1.w, l(-1) +ne r2.xy, r4.xyxx, v0.xyxx +or r2.x, r2.y, r2.x +ne r2.yz, r3.xxyx, r4.xxyx +or r2.y, r2.z, r2.y +movc r5.xy, r2.yyyy, r3.xyxx, v1.zwzz +movc r2.xz, r2.xxxx, r4.xxyx, r5.xxyx +add r2.xz, r2.xxzx, -v0.xxyx +ne r5.xy, r3.xyxx, v1.zwzz +or r5.x, r5.y, r5.x +movc r5.yz, r2.yyyy, r4.xxyx, v0.xxyx +movc r5.xy, r5.xxxx, r3.xyxx, r5.yzyy +add r5.xy, -r5.xyxx, v1.zwzz +dp2 r2.y, r2.xzxx, r5.xyxx +dp2 r5.z, r2.xzxx, r2.xzxx +dp2 r5.w, r5.xyxx, r5.xyxx +mul r5.z, r5.w, r5.z +eq r6.x, r5.z, l(0.000000) +rsq r5.z, r5.z +mul r2.yz, r2.yyzy, r5.zzxz +max r2.y, r2.y, l(-1.000000) +min r2.y, r2.y, l(1.000000) +movc r2.y, r6.x, l(1.000000), r2.y +add r5.z, -|r2.y|, l(1.000000) +sqrt r5.z, r5.z +mad r6.x, |r2.y|, l(-0.018729), l(0.074261) +mad r6.x, r6.x, |r2.y|, l(-0.212114) +mad r6.x, r6.x, |r2.y|, l(1.570729) +mul r6.y, r5.z, r6.x +mad r6.y, r6.y, l(-2.000000), l(3.141593) +lt r2.y, r2.y, -r2.y +and r2.y, r2.y, r6.y +mad r2.y, r6.x, r5.z, r2.y +utof r1.x, r1.x +div r1.x, r2.y, r1.x +add r6.xy, r3.xyxx, -v0.xyxx +add r6.zw, -r4.yyyx, v1.wwwz +mul r2.y, r6.w, r6.y +mad r2.y, r6.x, r6.z, -r2.y +eq r5.z, r2.y, l(0.000000) +mad r2.x, r2.x, r5.y, -r2.z +movc r2.x, r5.z, r2.x, r2.y +lt r2.x, r2.x, l(0.000000) +movc o2.w, r2.x, -r1.x, r1.x +utof r1.x, r1.w +add r1.w, -r0.w, r0.x +add o2.x, -|r1.w|, r1.x +imad r1.z, r1.y, l(1024), r1.z +utof o2.z, r1.z +dp2 r1.z, r5.xyxx, v2.xyxx +dp2 r1.w, v2.xyxx, v2.xyxx +mul r1.w, r1.w, r5.w +eq r2.x, r1.w, l(0.000000) +rsq r1.w, r1.w +mul r1.z, r1.w, r1.z +max r1.z, r1.z, l(-1.000000) +min r1.z, r1.z, l(1.000000) +movc r1.z, r2.x, l(1.000000), r1.z +add r1.w, -|r1.z|, l(1.000000) +sqrt r1.w, r1.w +mad r2.x, |r1.z|, l(-0.018729), l(0.074261) +mad r2.x, r2.x, |r1.z|, l(-0.212114) +mad r2.x, r2.x, |r1.z|, l(1.570729) +mul r2.y, r1.w, r2.x +mad r2.y, r2.y, l(-2.000000), l(3.141593) +lt r1.z, r1.z, -r1.z +and r1.z, r1.z, r2.y +mad r1.z, r2.x, r1.w, r1.z +utof r1.y, r1.y +ieq r1.w, r2.w, l(0x0a000000) +add r2.x, r1.y, l(-2.000000) +movc r1.y, r1.w, r2.x, r1.y +div r1.y, r1.z, r1.y +mul r1.z, r5.y, v2.x +mad r1.z, r5.x, v2.y, -r1.z +lt r1.z, r1.z, l(0.000000) +movc o3.z, r1.z, -r1.y, r1.y +lt r0.x, r0.x, r0.z +or r0.z, v3.w, l(0x00800000) +movc o4.x, r0.x, r0.z, v3.w +mad o5.x, r0.w, l(0.000977), l(-1.000000) +lt r0.x, l(0.000000), cb0[0].y +lt r0.z, cb0[0].y, l(0.000000) +iadd r0.x, -r0.x, r0.z +itof r0.x, r0.x +mad o5.y, r0.y, cb0[0].y, -r0.x +mov r4.zw, v0.xxxy +mov o0.xyzw, r4.zwxy +mov r3.zw, v1.zzzw +mov o1.xyzw, r3.xyzw +mov o2.y, r1.x +mov o5.zw, l(0,0,0,1.000000) +mov o3.xy, v2.xyxx +ret +// Approximately 334 instruction slots used +#endif + +const BYTE g_main[] = +{ + 68, 88, 66, 67, 89, 26, + 141, 244, 94, 200, 9, 193, + 173, 156, 143, 151, 177, 144, + 102, 149, 1, 0, 0, 0, + 192, 45, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 100, 4, 0, 0, 44, 5, + 0, 0, 228, 5, 0, 0, + 36, 45, 0, 0, 82, 68, + 69, 70, 40, 4, 0, 0, + 3, 0, 0, 0, 236, 0, + 0, 0, 5, 0, 0, 0, + 60, 0, 0, 0, 0, 5, + 254, 255, 0, 1, 0, 0, + 0, 4, 0, 0, 82, 68, + 49, 49, 60, 0, 0, 0, + 24, 0, 0, 0, 32, 0, + 0, 0, 40, 0, 0, 0, + 36, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 0, 0, + 220, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 223, 0, 0, 0, + 5, 0, 0, 0, 6, 0, + 0, 0, 1, 0, 0, 0, + 16, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 226, 0, + 0, 0, 5, 0, 0, 0, + 6, 0, 0, 0, 1, 0, + 0, 0, 16, 0, 0, 0, + 6, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, + 229, 0, 0, 0, 2, 0, + 0, 0, 5, 0, 0, 0, + 3, 0, 0, 0, 255, 255, + 255, 255, 10, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 232, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 84, 57, + 0, 76, 66, 0, 88, 67, + 0, 81, 67, 0, 77, 66, + 0, 171, 232, 0, 0, 0, + 1, 0, 0, 0, 52, 1, + 0, 0, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 223, 0, 0, 0, + 1, 0, 0, 0, 124, 3, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 226, 0, 0, 0, + 1, 0, 0, 0, 216, 3, + 0, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 92, 1, 0, 0, + 0, 0, 0, 0, 104, 0, + 0, 0, 2, 0, 0, 0, + 88, 3, 0, 0, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 107, 0, 60, 117, 110, 110, + 97, 109, 101, 100, 62, 0, + 80, 98, 0, 102, 108, 111, + 97, 116, 0, 171, 171, 171, + 0, 0, 3, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 107, 1, 0, 0, + 89, 99, 0, 82, 101, 0, + 83, 101, 0, 109, 54, 0, + 100, 119, 111, 114, 100, 0, + 171, 171, 0, 0, 19, 0, + 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 164, 1, + 0, 0, 109, 103, 0, 68, + 101, 0, 69, 101, 0, 85, + 55, 0, 105, 110, 116, 52, + 0, 171, 171, 171, 1, 0, + 2, 0, 1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 220, 1, 0, 0, 106, 103, + 0, 102, 108, 111, 97, 116, + 50, 0, 171, 171, 1, 0, + 3, 0, 1, 0, 2, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 11, 2, 0, 0, 90, 99, + 0, 87, 49, 0, 110, 103, + 0, 89, 53, 0, 79, 50, + 0, 97, 100, 0, 121, 101, + 0, 118, 51, 0, 119, 51, + 0, 98, 100, 0, 103, 103, + 0, 171, 171, 171, 104, 1, + 0, 0, 116, 1, 0, 0, + 0, 0, 0, 0, 152, 1, + 0, 0, 116, 1, 0, 0, + 4, 0, 0, 0, 155, 1, + 0, 0, 116, 1, 0, 0, + 8, 0, 0, 0, 158, 1, + 0, 0, 116, 1, 0, 0, + 12, 0, 0, 0, 161, 1, + 0, 0, 172, 1, 0, 0, + 16, 0, 0, 0, 208, 1, + 0, 0, 172, 1, 0, 0, + 20, 0, 0, 0, 211, 1, + 0, 0, 172, 1, 0, 0, + 24, 0, 0, 0, 214, 1, + 0, 0, 172, 1, 0, 0, + 28, 0, 0, 0, 217, 1, + 0, 0, 228, 1, 0, 0, + 32, 0, 0, 0, 8, 2, + 0, 0, 20, 2, 0, 0, + 48, 0, 0, 0, 56, 2, + 0, 0, 20, 2, 0, 0, + 56, 0, 0, 0, 59, 2, + 0, 0, 172, 1, 0, 0, + 64, 0, 0, 0, 62, 2, + 0, 0, 116, 1, 0, 0, + 68, 0, 0, 0, 65, 2, + 0, 0, 172, 1, 0, 0, + 72, 0, 0, 0, 68, 2, + 0, 0, 116, 1, 0, 0, + 76, 0, 0, 0, 71, 2, + 0, 0, 116, 1, 0, 0, + 80, 0, 0, 0, 74, 2, + 0, 0, 172, 1, 0, 0, + 84, 0, 0, 0, 77, 2, + 0, 0, 116, 1, 0, 0, + 88, 0, 0, 0, 80, 2, + 0, 0, 116, 1, 0, 0, + 92, 0, 0, 0, 83, 2, + 0, 0, 116, 1, 0, 0, + 96, 0, 0, 0, 86, 2, + 0, 0, 172, 1, 0, 0, + 100, 0, 0, 0, 5, 0, + 0, 0, 1, 0, 26, 0, + 0, 0, 21, 0, 92, 2, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 94, 1, 0, 0, 164, 3, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 2, 0, + 0, 0, 180, 3, 0, 0, + 0, 0, 0, 0, 255, 255, + 255, 255, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 36, 69, 108, 101, + 109, 101, 110, 116, 0, 117, + 105, 110, 116, 52, 0, 171, + 1, 0, 19, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 173, 3, 0, 0, + 164, 3, 0, 0, 0, 0, + 0, 0, 16, 0, 0, 0, + 2, 0, 0, 0, 180, 3, + 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 255, 255, 255, 255, + 0, 0, 0, 0, 77, 105, + 99, 114, 111, 115, 111, 102, + 116, 32, 40, 82, 41, 32, + 72, 76, 83, 76, 32, 83, + 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, + 101, 114, 32, 49, 48, 46, + 49, 0, 73, 83, 71, 78, + 192, 0, 0, 0, 6, 0, + 0, 0, 8, 0, 0, 0, + 152, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 15, 0, 0, + 155, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 158, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 2, 0, + 0, 0, 15, 15, 0, 0, + 161, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 15, 15, 0, 0, + 164, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 1, 0, 0, 0, 4, 0, + 0, 0, 1, 1, 0, 0, + 176, 0, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, + 1, 0, 0, 0, 5, 0, + 0, 0, 1, 0, 0, 0, + 90, 67, 0, 65, 68, 0, + 79, 67, 0, 82, 66, 0, + 83, 86, 95, 86, 101, 114, + 116, 101, 120, 73, 68, 0, + 83, 86, 95, 73, 110, 115, + 116, 97, 110, 99, 101, 73, + 68, 0, 171, 171, 79, 83, + 71, 78, 176, 0, 0, 0, + 6, 0, 0, 0, 8, 0, + 0, 0, 152, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 152, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 152, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 15, 0, + 0, 0, 152, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 7, 8, + 0, 0, 152, 0, 0, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 4, 0, 0, 0, 1, 14, + 0, 0, 161, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 5, 0, 0, 0, 15, 0, + 0, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 83, + 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 171, + 171, 171, 83, 72, 69, 88, + 56, 39, 0, 0, 80, 0, + 1, 0, 206, 9, 0, 0, + 106, 8, 0, 1, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 10, 0, + 0, 0, 162, 0, 0, 4, + 0, 112, 16, 0, 3, 0, + 0, 0, 16, 0, 0, 0, + 162, 0, 0, 4, 0, 112, + 16, 0, 6, 0, 0, 0, + 16, 0, 0, 0, 88, 56, + 0, 4, 0, 112, 16, 0, + 10, 0, 0, 0, 85, 85, + 0, 0, 95, 0, 0, 3, + 242, 16, 16, 0, 0, 0, + 0, 0, 95, 0, 0, 3, + 242, 16, 16, 0, 1, 0, + 0, 0, 95, 0, 0, 3, + 242, 16, 16, 0, 2, 0, + 0, 0, 95, 0, 0, 3, + 242, 16, 16, 0, 3, 0, + 0, 0, 96, 0, 0, 4, + 18, 16, 16, 0, 4, 0, + 0, 0, 6, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 1, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 2, 0, 0, 0, + 101, 0, 0, 3, 114, 32, + 16, 0, 3, 0, 0, 0, + 101, 0, 0, 3, 18, 32, + 16, 0, 4, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 5, 0, 0, 0, + 1, 0, 0, 0, 104, 0, + 0, 2, 10, 0, 0, 0, + 79, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 16, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 4, 0, 0, 0, 55, 0, + 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 42, 16, 16, 0, 2, 0, + 0, 0, 58, 16, 16, 0, + 2, 0, 0, 0, 55, 0, + 0, 9, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 10, 16, 16, 0, 3, 0, + 0, 0, 26, 16, 16, 0, + 3, 0, 0, 0, 139, 0, + 0, 9, 66, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 16, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 0, 7, 18, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 1, 64, 0, 0, 16, 0, + 0, 0, 43, 0, 0, 5, + 82, 0, 16, 0, 0, 0, + 0, 0, 6, 2, 16, 0, + 0, 0, 0, 0, 1, 0, + 0, 10, 50, 0, 16, 0, + 1, 0, 0, 0, 6, 16, + 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 130, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 7, + 18, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 55, 0, 0, 9, 18, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 0, 0, 0, 8, 34, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 8, + 34, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 0, + 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 9, + 34, 0, 16, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 64, + 1, 64, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 8, + 34, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 128, + 65, 0, 0, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 0, 0, 0, 0, 55, 0, + 0, 9, 34, 0, 16, 0, + 0, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 138, 0, + 0, 9, 18, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 10, 0, 0, 0, + 1, 64, 0, 0, 10, 0, + 0, 0, 42, 16, 16, 0, + 3, 0, 0, 0, 85, 0, + 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 42, 16, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 20, 0, + 0, 0, 1, 0, 0, 10, + 242, 0, 16, 0, 2, 0, + 0, 0, 230, 31, 16, 0, + 3, 0, 0, 0, 2, 64, + 0, 0, 255, 3, 0, 0, + 255, 255, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 30, + 79, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 83, 0, + 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 1, 0, + 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 255, 255, 255, 255, + 167, 0, 0, 139, 2, 131, + 0, 128, 131, 153, 25, 0, + 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, + 6, 112, 16, 0, 6, 0, + 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 41, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 2, 0, 0, 0, 140, 0, + 0, 11, 34, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 30, 0, 0, 0, + 1, 64, 0, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 1, 0, 0, 0, + 167, 0, 0, 139, 2, 131, + 0, 128, 131, 153, 25, 0, + 50, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 8, 0, 0, 0, + 70, 112, 16, 0, 3, 0, + 0, 0, 55, 0, 0, 12, + 50, 0, 16, 0, 3, 0, + 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 57, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 24, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 31, 0, 4, 3, + 42, 0, 16, 0, 1, 0, + 0, 0, 0, 0, 0, 8, + 242, 0, 16, 0, 4, 0, + 0, 0, 70, 30, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 230, 20, 16, 0, + 1, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 70, 0, + 16, 0, 4, 0, 0, 0, + 70, 0, 16, 0, 4, 0, + 0, 0, 75, 0, 0, 5, + 34, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 57, 0, + 0, 7, 18, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 31, 0, 4, 3, + 10, 0, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 10, + 82, 0, 16, 0, 3, 0, + 0, 0, 86, 4, 16, 0, + 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, + 128, 63, 0, 0, 0, 0, + 14, 0, 0, 7, 82, 0, + 16, 0, 3, 0, 0, 0, + 6, 2, 16, 0, 3, 0, + 0, 0, 86, 5, 16, 0, + 2, 0, 0, 0, 0, 0, + 0, 8, 50, 0, 16, 0, + 5, 0, 0, 0, 70, 16, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, + 15, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, + 134, 0, 16, 0, 3, 0, + 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 0, 0, + 0, 8, 50, 0, 16, 0, + 5, 0, 0, 0, 70, 16, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 230, 26, + 16, 0, 0, 0, 0, 0, + 15, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, + 134, 0, 16, 0, 3, 0, + 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 0, 0, + 0, 8, 34, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 64, 64, 0, 0, + 0, 9, 34, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 2, 0, 0, 0, 10, 0, + 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 54, 0, + 0, 5, 130, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 63, + 54, 0, 0, 5, 18, 0, + 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 48, 0, 0, 1, + 33, 0, 0, 7, 34, 0, + 16, 0, 5, 0, 0, 0, + 10, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 3, 0, 0, 0, 3, 0, + 4, 3, 26, 0, 16, 0, + 5, 0, 0, 0, 56, 0, + 0, 7, 34, 0, 16, 0, + 5, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 50, 0, 0, 10, + 34, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, + 50, 0, 0, 9, 66, 0, + 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 0, 0, 0, 7, 130, 0, + 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, + 5, 0, 0, 0, 49, 0, + 0, 7, 66, 0, 16, 0, + 5, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 10, + 34, 0, 16, 0, 5, 0, + 0, 0, 42, 0, 16, 0, + 5, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 5, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, + 49, 0, 0, 7, 66, 0, + 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 49, 0, + 0, 8, 18, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, + 58, 0, 16, 128, 129, 0, + 0, 0, 5, 0, 0, 0, + 14, 0, 0, 8, 34, 0, + 16, 0, 5, 0, 0, 0, + 26, 0, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 128, + 129, 0, 0, 0, 5, 0, + 0, 0, 55, 0, 0, 9, + 34, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 1, 0, 0, 7, + 130, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, + 30, 0, 0, 7, 18, 0, + 16, 0, 5, 0, 0, 0, + 10, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 1, 0, 0, 0, 22, 0, + 0, 1, 56, 0, 0, 7, + 34, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 64, 64, + 50, 0, 0, 9, 34, 0, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 64, 64, 50, 0, + 0, 9, 34, 0, 16, 0, + 2, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 56, 0, + 0, 7, 34, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 54, 0, 0, 6, + 34, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 128, + 129, 0, 0, 0, 2, 0, + 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 130, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 63, 54, 0, 0, 5, + 34, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 21, 0, + 0, 1, 56, 0, 0, 7, + 18, 0, 16, 0, 3, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 171, 170, 170, 62, + 0, 0, 0, 8, 242, 0, + 16, 0, 5, 0, 0, 0, + 70, 20, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 230, 30, 16, 0, 0, 0, + 0, 0, 0, 0, 0, 8, + 50, 0, 16, 0, 6, 0, + 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 230, 10, + 16, 128, 65, 0, 0, 0, + 5, 0, 0, 0, 50, 0, + 0, 12, 242, 0, 16, 0, + 7, 0, 0, 0, 230, 14, + 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 64, 192, 0, 0, 64, 192, + 0, 0, 64, 192, 0, 0, + 64, 192, 70, 4, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 7, 242, 0, 16, 0, + 8, 0, 0, 0, 70, 4, + 16, 0, 6, 0, 0, 0, + 70, 4, 16, 0, 6, 0, + 0, 0, 50, 0, 0, 9, + 194, 0, 16, 0, 4, 0, + 0, 0, 166, 14, 16, 0, + 7, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, + 6, 4, 16, 0, 8, 0, + 0, 0, 50, 0, 0, 9, + 194, 0, 16, 0, 4, 0, + 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, + 6, 4, 16, 0, 5, 0, + 0, 0, 56, 0, 0, 10, + 194, 0, 16, 0, 4, 0, + 0, 0, 166, 14, 16, 0, + 4, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 64, 64, 0, 0, 64, 64, + 15, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 75, 0, + 0, 5, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, + 57, 0, 0, 7, 66, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 31, 0, + 4, 3, 42, 0, 16, 0, + 6, 0, 0, 0, 14, 0, + 0, 10, 66, 0, 16, 0, + 3, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 42, 0, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 7, + 194, 0, 16, 0, 4, 0, + 0, 0, 166, 10, 16, 0, + 3, 0, 0, 0, 166, 14, + 16, 0, 4, 0, 0, 0, + 15, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 7, 0, + 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 7, 66, 0, 16, 0, + 6, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 6, 0, + 0, 0, 70, 0, 16, 0, + 6, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 64, 50, 0, + 0, 9, 18, 0, 16, 0, + 6, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 56, 0, + 0, 7, 18, 0, 16, 0, + 6, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 15, 0, 0, 7, + 66, 0, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, + 5, 0, 0, 0, 230, 10, + 16, 0, 4, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 192, 64, 50, 0, + 0, 9, 66, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 64, 64, 42, 0, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 8, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 51, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 56, 0, + 0, 7, 18, 0, 16, 0, + 6, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 50, 0, 0, 9, + 18, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 42, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 56, 0, 0, 7, + 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 56, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 114, 249, 127, 63, 51, 0, + 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 24, 0, 0, 7, + 66, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 31, 0, 4, 3, 42, 0, + 16, 0, 3, 0, 0, 0, + 14, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 18, 0, + 0, 1, 14, 0, 0, 10, + 18, 0, 16, 0, 6, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 128, 63, 0, 0, + 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 42, 0, + 16, 0, 6, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 56, 0, + 0, 8, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 171, 170, 170, 190, 56, 0, + 0, 7, 18, 0, 16, 0, + 6, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 63, 56, 0, 0, 7, + 34, 0, 16, 0, 6, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 56, 0, 0, 7, 34, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 50, 0, + 0, 10, 34, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 128, + 65, 0, 0, 0, 6, 0, + 0, 0, 49, 0, 0, 7, + 66, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 75, 0, 0, 5, 130, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 56, 0, 0, 7, + 18, 0, 16, 0, 9, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 58, 0, + 16, 0, 6, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 9, 0, 0, 0, + 58, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 9, 0, 0, 0, 14, 0, + 0, 7, 18, 0, 16, 0, + 9, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 9, 0, + 0, 0, 0, 0, 0, 8, + 34, 0, 16, 0, 9, 0, + 0, 0, 10, 0, 16, 128, + 193, 0, 0, 0, 9, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 75, 0, + 0, 5, 34, 0, 16, 0, + 9, 0, 0, 0, 26, 0, + 16, 0, 9, 0, 0, 0, + 50, 0, 0, 10, 66, 0, + 16, 0, 9, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 48, 110, + 153, 188, 1, 64, 0, 0, + 39, 22, 152, 61, 50, 0, + 0, 10, 66, 0, 16, 0, + 9, 0, 0, 0, 42, 0, + 16, 0, 9, 0, 0, 0, + 10, 0, 16, 128, 129, 0, + 0, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 132, 52, + 89, 190, 50, 0, 0, 10, + 66, 0, 16, 0, 9, 0, + 0, 0, 42, 0, 16, 0, + 9, 0, 0, 0, 10, 0, + 16, 128, 129, 0, 0, 0, + 9, 0, 0, 0, 1, 64, + 0, 0, 164, 13, 201, 63, + 56, 0, 0, 7, 130, 0, + 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 9, 0, + 0, 0, 42, 0, 16, 0, + 9, 0, 0, 0, 50, 0, + 0, 9, 130, 0, 16, 0, + 9, 0, 0, 0, 58, 0, + 16, 0, 9, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 192, 1, 64, 0, 0, + 219, 15, 73, 64, 49, 0, + 0, 8, 18, 0, 16, 0, + 9, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 9, 0, 0, 0, + 1, 0, 0, 7, 18, 0, + 16, 0, 9, 0, 0, 0, + 10, 0, 16, 0, 9, 0, + 0, 0, 58, 0, 16, 0, + 9, 0, 0, 0, 50, 0, + 0, 9, 18, 0, 16, 0, + 9, 0, 0, 0, 42, 0, + 16, 0, 9, 0, 0, 0, + 26, 0, 16, 0, 9, 0, + 0, 0, 10, 0, 16, 0, + 9, 0, 0, 0, 56, 0, + 0, 7, 130, 0, 16, 0, + 6, 0, 0, 0, 58, 0, + 16, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 192, 50, 0, 0, 9, + 18, 0, 16, 0, 9, 0, + 0, 0, 10, 0, 16, 0, + 9, 0, 0, 0, 1, 64, + 0, 0, 171, 170, 170, 62, + 1, 64, 0, 0, 146, 10, + 6, 192, 77, 0, 0, 6, + 0, 208, 0, 0, 18, 0, + 16, 0, 9, 0, 0, 0, + 10, 0, 16, 0, 9, 0, + 0, 0, 56, 0, 0, 7, + 130, 0, 16, 0, 6, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 9, 0, 0, 0, + 75, 0, 0, 5, 34, 0, + 16, 0, 6, 0, 0, 0, + 26, 0, 16, 0, 6, 0, + 0, 0, 0, 0, 0, 8, + 18, 0, 16, 0, 6, 0, + 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 128, 129, 0, 0, 0, + 6, 0, 0, 0, 47, 0, + 0, 5, 18, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 56, 0, 0, 7, 18, 0, + 16, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 1, 64, 0, 0, + 171, 170, 170, 62, 25, 0, + 0, 5, 18, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 49, 0, 0, 7, 130, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 55, 0, + 0, 10, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 0, 4, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 6, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 57, 0, 0, 7, + 18, 0, 16, 0, 6, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 14, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 0, 0, + 0, 7, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 55, 0, 0, 9, 66, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 6, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 21, 0, 0, 1, 54, 0, + 0, 6, 194, 0, 16, 0, + 6, 0, 0, 0, 166, 10, + 16, 128, 129, 0, 0, 0, + 3, 0, 0, 0, 54, 0, + 0, 6, 50, 0, 16, 0, + 6, 0, 0, 0, 246, 15, + 16, 128, 65, 0, 0, 0, + 6, 0, 0, 0, 0, 0, + 0, 7, 242, 0, 16, 0, + 6, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, + 70, 14, 16, 0, 6, 0, + 0, 0, 50, 0, 0, 9, + 242, 0, 16, 0, 7, 0, + 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 8, 0, + 0, 0, 50, 0, 0, 9, + 242, 0, 16, 0, 5, 0, + 0, 0, 70, 14, 16, 0, + 7, 0, 0, 0, 70, 14, + 16, 0, 6, 0, 0, 0, + 70, 14, 16, 0, 5, 0, + 0, 0, 57, 0, 0, 7, + 194, 0, 16, 0, 3, 0, + 0, 0, 166, 30, 16, 0, + 0, 0, 0, 0, 6, 20, + 16, 0, 0, 0, 0, 0, + 60, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 57, 0, + 0, 7, 194, 0, 16, 0, + 4, 0, 0, 0, 166, 30, + 16, 0, 0, 0, 0, 0, + 6, 20, 16, 0, 1, 0, + 0, 0, 60, 0, 0, 7, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 55, 0, 0, 9, 194, 0, + 16, 0, 4, 0, 0, 0, + 246, 15, 16, 0, 3, 0, + 0, 0, 6, 20, 16, 0, + 1, 0, 0, 0, 166, 30, + 16, 0, 1, 0, 0, 0, + 55, 0, 0, 9, 194, 0, + 16, 0, 4, 0, 0, 0, + 166, 10, 16, 0, 3, 0, + 0, 0, 166, 30, 16, 0, + 0, 0, 0, 0, 166, 14, + 16, 0, 4, 0, 0, 0, + 0, 0, 0, 8, 194, 0, + 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 4, 0, + 0, 0, 6, 20, 16, 128, + 65, 0, 0, 0, 0, 0, + 0, 0, 57, 0, 0, 7, + 82, 0, 16, 0, 6, 0, + 0, 0, 6, 17, 16, 0, + 1, 0, 0, 0, 166, 27, + 16, 0, 1, 0, 0, 0, + 60, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 55, 0, + 0, 9, 82, 0, 16, 0, + 6, 0, 0, 0, 246, 15, + 16, 0, 3, 0, 0, 0, + 166, 27, 16, 0, 0, 0, + 0, 0, 6, 17, 16, 0, + 0, 0, 0, 0, 55, 0, + 0, 9, 194, 0, 16, 0, + 3, 0, 0, 0, 166, 10, + 16, 0, 3, 0, 0, 0, + 6, 20, 16, 0, 1, 0, + 0, 0, 6, 8, 16, 0, + 6, 0, 0, 0, 0, 0, + 0, 8, 194, 0, 16, 0, + 3, 0, 0, 0, 166, 14, + 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 166, 30, + 16, 0, 1, 0, 0, 0, + 49, 0, 0, 7, 18, 0, + 16, 0, 6, 0, 0, 0, + 26, 0, 16, 0, 6, 0, + 0, 0, 1, 64, 0, 0, + 111, 18, 131, 58, 55, 0, + 0, 9, 194, 0, 16, 0, + 4, 0, 0, 0, 6, 0, + 16, 0, 6, 0, 0, 0, + 166, 14, 16, 0, 4, 0, + 0, 0, 6, 4, 16, 0, + 5, 0, 0, 0, 49, 0, + 0, 7, 18, 0, 16, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 119, 190, 127, 63, + 58, 0, 16, 0, 6, 0, + 0, 0, 55, 0, 0, 9, + 194, 0, 16, 0, 3, 0, + 0, 0, 6, 0, 16, 0, + 5, 0, 0, 0, 166, 14, + 16, 0, 3, 0, 0, 0, + 166, 14, 16, 0, 5, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 5, 0, + 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 230, 10, + 16, 0, 3, 0, 0, 0, + 15, 0, 0, 7, 66, 0, + 16, 0, 4, 0, 0, 0, + 230, 10, 16, 0, 4, 0, + 0, 0, 230, 10, 16, 0, + 4, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 230, 10, + 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 3, 0, + 0, 0, 56, 0, 0, 7, + 66, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 4, 0, 0, 0, + 24, 0, 0, 7, 130, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 68, 0, + 0, 5, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 10, 0, 16, 0, + 5, 0, 0, 0, 52, 0, + 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 191, 51, 0, 0, 7, + 66, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 55, 0, 0, 9, 66, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 42, 0, + 16, 0, 3, 0, 0, 0, + 0, 0, 0, 8, 130, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 128, 193, 0, + 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 75, 0, 0, 5, + 130, 0, 16, 0, 3, 0, + 0, 0, 58, 0, 16, 0, + 3, 0, 0, 0, 50, 0, + 0, 10, 66, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 128, 129, 0, 0, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 48, 110, 153, 188, + 1, 64, 0, 0, 39, 22, + 152, 61, 50, 0, 0, 10, + 66, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 42, 0, + 16, 128, 129, 0, 0, 0, + 3, 0, 0, 0, 1, 64, + 0, 0, 132, 52, 89, 190, + 50, 0, 0, 10, 66, 0, + 16, 0, 4, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 42, 0, 16, 128, + 129, 0, 0, 0, 3, 0, + 0, 0, 1, 64, 0, 0, + 164, 13, 201, 63, 56, 0, + 0, 7, 130, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 4, 0, + 0, 0, 50, 0, 0, 9, + 130, 0, 16, 0, 4, 0, + 0, 0, 58, 0, 16, 0, + 4, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 192, + 1, 64, 0, 0, 219, 15, + 73, 64, 49, 0, 0, 8, + 66, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 7, 66, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, + 58, 0, 16, 0, 4, 0, + 0, 0, 50, 0, 0, 9, + 66, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 4, 0, 0, 0, 58, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 0, 3, 0, + 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 66, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 21, 0, 0, 1, + 50, 0, 0, 10, 66, 0, + 16, 0, 3, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 131, 249, + 162, 62, 1, 64, 0, 0, + 0, 0, 128, 63, 56, 0, + 0, 7, 18, 0, 16, 0, + 3, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 10, 0, 16, 0, 3, 0, + 0, 0, 14, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 3, 0, 0, 0, + 0, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 191, 56, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 63, 51, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 3, 0, 0, 0, + 51, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 164, 112, 125, 63, 56, 0, + 0, 7, 18, 0, 16, 0, + 5, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 63, 54, 0, 0, 5, + 34, 0, 16, 0, 5, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 72, 0, + 0, 141, 194, 1, 0, 128, + 67, 85, 21, 0, 66, 0, + 16, 0, 1, 0, 0, 0, + 70, 0, 16, 0, 5, 0, + 0, 0, 150, 124, 16, 0, + 10, 0, 0, 0, 0, 96, + 16, 0, 10, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 9, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 192, + 1, 64, 0, 0, 0, 0, + 128, 63, 56, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 49, 0, 0, 7, 18, 0, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 49, 0, + 0, 7, 34, 0, 16, 0, + 3, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 14, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 55, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 1, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 3, 0, 0, 0, 50, 0, + 0, 12, 242, 0, 16, 0, + 3, 0, 0, 0, 70, 4, + 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 171, 170, + 170, 62, 171, 170, 170, 62, + 171, 170, 42, 63, 171, 170, + 42, 63, 70, 20, 16, 0, + 0, 0, 0, 0, 0, 0, + 0, 8, 50, 0, 16, 0, + 3, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, + 230, 26, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 50, 0, 0, 9, 50, 0, + 16, 0, 4, 0, 0, 0, + 166, 10, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, + 3, 0, 0, 0, 230, 26, + 16, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 50, 0, + 16, 0, 3, 0, 0, 0, + 230, 10, 16, 0, 3, 0, + 0, 0, 70, 16, 16, 128, + 65, 0, 0, 0, 1, 0, + 0, 0, 50, 0, 0, 9, + 50, 0, 16, 0, 3, 0, + 0, 0, 166, 10, 16, 0, + 1, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 18, 0, 0, 1, + 54, 0, 0, 5, 50, 0, + 16, 0, 4, 0, 0, 0, + 230, 26, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 50, 0, 16, 0, 3, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 21, 0, + 0, 1, 167, 0, 0, 139, + 2, 131, 0, 128, 131, 153, + 25, 0, 242, 0, 16, 0, + 5, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 70, 126, 16, 0, + 3, 0, 0, 0, 50, 0, + 0, 12, 194, 0, 16, 0, + 1, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 0, 0, + 0, 192, 6, 4, 16, 0, + 3, 0, 0, 0, 0, 0, + 0, 7, 194, 0, 16, 0, + 1, 0, 0, 0, 166, 14, + 16, 0, 1, 0, 0, 0, + 6, 20, 16, 0, 0, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 6, 0, + 0, 0, 230, 10, 16, 0, + 1, 0, 0, 0, 134, 0, + 16, 0, 5, 0, 0, 0, + 15, 0, 0, 7, 34, 0, + 16, 0, 6, 0, 0, 0, + 230, 10, 16, 0, 1, 0, + 0, 0, 214, 5, 16, 0, + 5, 0, 0, 0, 50, 0, + 0, 12, 194, 0, 16, 0, + 1, 0, 0, 0, 6, 4, + 16, 0, 3, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 0, 0, + 0, 192, 166, 30, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 7, 194, 0, 16, 0, + 1, 0, 0, 0, 6, 4, + 16, 0, 4, 0, 0, 0, + 166, 14, 16, 0, 1, 0, + 0, 0, 15, 0, 0, 7, + 18, 0, 16, 0, 7, 0, + 0, 0, 230, 10, 16, 0, + 1, 0, 0, 0, 134, 0, + 16, 0, 5, 0, 0, 0, + 15, 0, 0, 7, 34, 0, + 16, 0, 7, 0, 0, 0, + 230, 10, 16, 0, 1, 0, + 0, 0, 214, 5, 16, 0, + 5, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 70, 0, + 16, 0, 6, 0, 0, 0, + 70, 0, 16, 0, 6, 0, + 0, 0, 15, 0, 0, 7, + 130, 0, 16, 0, 1, 0, + 0, 0, 70, 0, 16, 0, + 7, 0, 0, 0, 70, 0, + 16, 0, 7, 0, 0, 0, + 52, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 75, 0, + 0, 5, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 56, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 64, 64, 75, 0, + 0, 5, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 66, 0, 0, 5, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 52, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 28, 0, 0, 5, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 84, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 55, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 30, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 30, 0, + 0, 7, 130, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 30, 0, 0, 7, + 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 255, 255, 255, 255, + 57, 0, 0, 7, 50, 0, + 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 4, 0, + 0, 0, 70, 16, 16, 0, + 0, 0, 0, 0, 60, 0, + 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 57, 0, 0, 7, + 98, 0, 16, 0, 2, 0, + 0, 0, 6, 1, 16, 0, + 3, 0, 0, 0, 6, 1, + 16, 0, 4, 0, 0, 0, + 60, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 55, 0, + 0, 9, 50, 0, 16, 0, + 5, 0, 0, 0, 86, 5, + 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 3, 0, + 0, 0, 230, 26, 16, 0, + 1, 0, 0, 0, 55, 0, + 0, 9, 82, 0, 16, 0, + 2, 0, 0, 0, 6, 0, + 16, 0, 2, 0, 0, 0, + 6, 1, 16, 0, 4, 0, + 0, 0, 6, 1, 16, 0, + 5, 0, 0, 0, 0, 0, + 0, 8, 82, 0, 16, 0, + 2, 0, 0, 0, 6, 2, + 16, 0, 2, 0, 0, 0, + 6, 17, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 57, 0, 0, 7, 50, 0, + 16, 0, 5, 0, 0, 0, + 70, 0, 16, 0, 3, 0, + 0, 0, 230, 26, 16, 0, + 1, 0, 0, 0, 60, 0, + 0, 7, 18, 0, 16, 0, + 5, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, + 10, 0, 16, 0, 5, 0, + 0, 0, 55, 0, 0, 9, + 98, 0, 16, 0, 5, 0, + 0, 0, 86, 5, 16, 0, + 2, 0, 0, 0, 6, 1, + 16, 0, 4, 0, 0, 0, + 6, 17, 16, 0, 0, 0, + 0, 0, 55, 0, 0, 9, + 50, 0, 16, 0, 5, 0, + 0, 0, 6, 0, 16, 0, + 5, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, + 150, 5, 16, 0, 5, 0, + 0, 0, 0, 0, 0, 8, + 50, 0, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 128, + 65, 0, 0, 0, 5, 0, + 0, 0, 230, 26, 16, 0, + 1, 0, 0, 0, 15, 0, + 0, 7, 34, 0, 16, 0, + 2, 0, 0, 0, 134, 0, + 16, 0, 2, 0, 0, 0, + 70, 0, 16, 0, 5, 0, + 0, 0, 15, 0, 0, 7, + 66, 0, 16, 0, 5, 0, + 0, 0, 134, 0, 16, 0, + 2, 0, 0, 0, 134, 0, + 16, 0, 2, 0, 0, 0, + 15, 0, 0, 7, 130, 0, + 16, 0, 5, 0, 0, 0, + 70, 0, 16, 0, 5, 0, + 0, 0, 70, 0, 16, 0, + 5, 0, 0, 0, 56, 0, + 0, 7, 66, 0, 16, 0, + 5, 0, 0, 0, 58, 0, + 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 24, 0, 0, 7, + 18, 0, 16, 0, 6, 0, + 0, 0, 42, 0, 16, 0, + 5, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 68, 0, 0, 5, 66, 0, + 16, 0, 5, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 56, 0, 0, 7, + 98, 0, 16, 0, 2, 0, + 0, 0, 86, 6, 16, 0, + 2, 0, 0, 0, 166, 8, + 16, 0, 5, 0, 0, 0, + 52, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 191, 51, 0, + 0, 7, 34, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 55, 0, 0, 9, + 34, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 26, 0, 16, 0, 2, 0, + 0, 0, 0, 0, 0, 8, + 66, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 128, + 193, 0, 0, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 75, 0, + 0, 5, 66, 0, 16, 0, + 5, 0, 0, 0, 42, 0, + 16, 0, 5, 0, 0, 0, + 50, 0, 0, 10, 18, 0, + 16, 0, 6, 0, 0, 0, + 26, 0, 16, 128, 129, 0, + 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 48, 110, + 153, 188, 1, 64, 0, 0, + 39, 22, 152, 61, 50, 0, + 0, 10, 18, 0, 16, 0, + 6, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 26, 0, 16, 128, 129, 0, + 0, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 132, 52, + 89, 190, 50, 0, 0, 10, + 18, 0, 16, 0, 6, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 128, 129, 0, 0, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 164, 13, 201, 63, + 56, 0, 0, 7, 34, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, + 6, 0, 0, 0, 50, 0, + 0, 9, 34, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 192, 1, 64, 0, 0, + 219, 15, 73, 64, 49, 0, + 0, 8, 34, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 128, 65, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 7, 34, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 6, 0, 0, 0, 50, 0, + 0, 9, 34, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 6, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 26, 0, 16, 0, + 2, 0, 0, 0, 86, 0, + 0, 5, 18, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 1, 0, 0, 0, + 14, 0, 0, 7, 18, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 8, 50, 0, 16, 0, + 6, 0, 0, 0, 70, 0, + 16, 0, 3, 0, 0, 0, + 70, 16, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 194, 0, + 16, 0, 6, 0, 0, 0, + 86, 1, 16, 128, 65, 0, + 0, 0, 4, 0, 0, 0, + 246, 27, 16, 0, 1, 0, + 0, 0, 56, 0, 0, 7, + 34, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 0, 6, 0, 0, 0, + 50, 0, 0, 10, 34, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 6, 0, + 0, 0, 42, 0, 16, 0, + 6, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 2, 0, 0, 0, 24, 0, + 0, 7, 66, 0, 16, 0, + 5, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 10, + 18, 0, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 5, 0, 0, 0, + 42, 0, 16, 128, 65, 0, + 0, 0, 2, 0, 0, 0, + 55, 0, 0, 9, 18, 0, + 16, 0, 2, 0, 0, 0, + 42, 0, 16, 0, 5, 0, + 0, 0, 10, 0, 16, 0, + 2, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 49, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 55, 0, + 0, 10, 130, 32, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 86, 0, 0, 5, + 18, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 8, 130, 0, 16, 0, + 1, 0, 0, 0, 58, 0, + 16, 128, 65, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 18, 32, + 16, 0, 2, 0, 0, 0, + 58, 0, 16, 128, 193, 0, + 0, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 1, 0, + 0, 0, 35, 0, 0, 9, + 66, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 4, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 86, 0, 0, 5, + 66, 32, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 15, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 70, 0, + 16, 0, 5, 0, 0, 0, + 70, 16, 16, 0, 2, 0, + 0, 0, 15, 0, 0, 7, + 130, 0, 16, 0, 1, 0, + 0, 0, 70, 16, 16, 0, + 2, 0, 0, 0, 70, 16, + 16, 0, 2, 0, 0, 0, + 56, 0, 0, 7, 130, 0, + 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 5, 0, 0, 0, 24, 0, + 0, 7, 18, 0, 16, 0, + 2, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 68, 0, 0, 5, + 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 56, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 52, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 191, + 51, 0, 0, 7, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 55, 0, + 0, 9, 66, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 42, 0, 16, 0, + 1, 0, 0, 0, 0, 0, + 0, 8, 130, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 128, 193, 0, 0, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 75, 0, 0, 5, 130, 0, + 16, 0, 1, 0, 0, 0, + 58, 0, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 10, + 18, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 128, + 129, 0, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 48, 110, 153, 188, 1, 64, + 0, 0, 39, 22, 152, 61, + 50, 0, 0, 10, 18, 0, + 16, 0, 2, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 42, 0, 16, 128, + 129, 0, 0, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 132, 52, 89, 190, 50, 0, + 0, 10, 18, 0, 16, 0, + 2, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 42, 0, 16, 128, 129, 0, + 0, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 164, 13, + 201, 63, 56, 0, 0, 7, + 34, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 10, 0, + 16, 0, 2, 0, 0, 0, + 50, 0, 0, 9, 34, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 192, 1, 64, + 0, 0, 219, 15, 73, 64, + 49, 0, 0, 8, 66, 0, + 16, 0, 1, 0, 0, 0, + 42, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 128, + 65, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 2, 0, 0, 0, + 50, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 58, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 86, 0, 0, 5, 34, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, + 0, 0, 32, 0, 0, 7, + 130, 0, 16, 0, 1, 0, + 0, 0, 58, 0, 16, 0, + 2, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 10, + 0, 0, 0, 7, 18, 0, + 16, 0, 2, 0, 0, 0, + 26, 0, 16, 0, 1, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 192, 55, 0, + 0, 9, 34, 0, 16, 0, + 1, 0, 0, 0, 58, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 2, 0, + 0, 0, 26, 0, 16, 0, + 1, 0, 0, 0, 14, 0, + 0, 7, 34, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 26, 0, 16, 0, 1, 0, + 0, 0, 56, 0, 0, 7, + 66, 0, 16, 0, 1, 0, + 0, 0, 26, 0, 16, 0, + 5, 0, 0, 0, 10, 16, + 16, 0, 2, 0, 0, 0, + 50, 0, 0, 10, 66, 0, + 16, 0, 1, 0, 0, 0, + 10, 0, 16, 0, 5, 0, + 0, 0, 26, 16, 16, 0, + 2, 0, 0, 0, 42, 0, + 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 49, 0, + 0, 7, 66, 0, 16, 0, + 1, 0, 0, 0, 42, 0, + 16, 0, 1, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 0, 0, 55, 0, 0, 10, + 66, 32, 16, 0, 3, 0, + 0, 0, 42, 0, 16, 0, + 1, 0, 0, 0, 26, 0, + 16, 128, 65, 0, 0, 0, + 1, 0, 0, 0, 26, 0, + 16, 0, 1, 0, 0, 0, + 49, 0, 0, 7, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 0, 0, 0, + 0, 0, 42, 0, 16, 0, + 0, 0, 0, 0, 60, 0, + 0, 7, 66, 0, 16, 0, + 0, 0, 0, 0, 58, 16, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 0, 55, 0, 0, 9, + 18, 32, 16, 0, 4, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 58, 16, 16, 0, 3, 0, + 0, 0, 50, 0, 0, 9, + 18, 32, 16, 0, 5, 0, + 0, 0, 58, 0, 16, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 58, + 1, 64, 0, 0, 0, 0, + 128, 191, 49, 0, 0, 8, + 18, 0, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 0, + 0, 8, 66, 0, 16, 0, + 0, 0, 0, 0, 26, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 0, 0, + 30, 0, 0, 8, 18, 0, + 16, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 42, 0, 16, 0, 0, 0, + 0, 0, 43, 0, 0, 5, + 18, 0, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 50, 0, + 0, 11, 34, 32, 16, 0, + 5, 0, 0, 0, 26, 0, + 16, 0, 0, 0, 0, 0, + 26, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 10, 0, 16, 128, 65, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 194, 0, + 16, 0, 4, 0, 0, 0, + 6, 20, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 0, 0, + 0, 0, 230, 4, 16, 0, + 4, 0, 0, 0, 54, 0, + 0, 5, 194, 0, 16, 0, + 3, 0, 0, 0, 166, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 14, 16, 0, 3, 0, + 0, 0, 54, 0, 0, 5, + 34, 32, 16, 0, 2, 0, + 0, 0, 10, 0, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 8, 194, 32, 16, 0, + 5, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 63, + 54, 0, 0, 5, 50, 32, + 16, 0, 3, 0, 0, 0, + 70, 16, 16, 0, 2, 0, + 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 148, 0, + 0, 0, 78, 1, 0, 0, + 10, 0, 0, 0, 0, 0, + 0, 0, 11, 0, 0, 0, + 223, 0, 0, 0, 11, 0, + 0, 0, 23, 0, 0, 0, + 5, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 30, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 +}; diff --git a/thirdparty/rive_vendor_versions.json b/thirdparty/rive_vendor_versions.json index ad1a61a91..8b828cdff 100644 --- a/thirdparty/rive_vendor_versions.json +++ b/thirdparty/rive_vendor_versions.json @@ -12,6 +12,12 @@ "ref": "runtime-v0.1.62", "version": "0.1.62" }, + { + "checkout": "972e52893bf03fd26920d4d191d1a09c7e0b0fa5", + "name": "glad", + "ref": "runtime-v0.1.62", + "version": "0.1.62" + }, { "checkout": "972e52893bf03fd26920d4d191d1a09c7e0b0fa5", "name": "rive_decoders", diff --git a/tools/rive_update.py b/tools/rive_update.py index 4190af27a..db0102b75 100755 --- a/tools/rive_update.py +++ b/tools/rive_update.py @@ -576,12 +576,34 @@ def process_include_blocks(manifest: dict[str, Any]) -> int: return changed -def selected_shader_targets(shader_config: dict[str, Any], skipped_targets: set[str]) -> list[str]: +def selected_shader_targets( + shader_config: dict[str, Any], + skipped_targets: set[str], + auto_skip_unavailable_optional_targets: bool = False, +) -> list[str]: targets = shader_config.get("targets", []) unknown = skipped_targets.difference(targets) if unknown: raise SystemExit(f"Unknown shader target(s) for --skip-shader-target: {', '.join(sorted(unknown))}") - return [target for target in targets if target not in skipped_targets] + + selected = [target for target in targets if target not in skipped_targets] + if not auto_skip_unavailable_optional_targets: + return selected + + optional_targets = set(shader_config.get("optional_targets", [])) + required_tools = shader_config.get("required_tools", {}) + return [ + target + for target in selected + if target not in optional_targets + or all(shutil.which(tool) is not None for tool in required_tools.get(target, [])) + ] + + +def auto_skipped_shader_targets(shader_config: dict[str, Any], skipped_targets: set[str]) -> set[str]: + requested = set(selected_shader_targets(shader_config, skipped_targets)) + selected = set(selected_shader_targets(shader_config, skipped_targets, True)) + return requested.difference(selected) def preflight_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped_targets: set[str]) -> None: @@ -595,7 +617,7 @@ def preflight_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped missing: dict[str, list[str]] = {} required_tools = shader_config.get("required_tools", {}) - for target in selected_shader_targets(shader_config, skipped_targets): + for target in selected_shader_targets(shader_config, skipped_targets, True): missing_tools = [tool for tool in required_tools.get(target, []) if shutil.which(tool) is None] if missing_tools: missing[target] = missing_tools @@ -613,6 +635,14 @@ def preflight_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped raise SystemExit("\n".join(lines)) +def find_venv_site_packages(venv_dir: Path) -> Path | None: + candidates = [ + *(venv_dir / "lib").glob("python*/site-packages"), + venv_dir / "Lib" / "site-packages", + ] + return next((path for path in candidates if path.exists()), None) + + def run_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped_targets: set[str]) -> int: shader_config = dep.get("shader_generation") if not shader_config: @@ -630,10 +660,11 @@ def run_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped_targe if package: run([str(python_bin), "-m", "pip", "install", package]) - site_packages = next((venv_dir / "lib").glob("python*/site-packages"), None) + site_packages = find_venv_site_packages(venv_dir) flags = [f"--ply-path={site_packages}"] if site_packages else [] - targets = selected_shader_targets(shader_config, skipped_targets) + auto_skipped_targets = auto_skipped_shader_targets(shader_config, skipped_targets) + targets = selected_shader_targets(shader_config, skipped_targets, True) for target in targets: run(["make", f"FLAGS={' '.join(flags)}", target], cwd=shader_dir) @@ -654,7 +685,7 @@ def run_shader_generation(dep: dict[str, Any], checkout_dir: Path, skipped_targe shutil.copy2(source, target) count += 1 - if not skipped_targets: + if not skipped_targets and not auto_skipped_targets: for existing in sorted(path for path in destination.rglob("*") if path.is_file()): if existing.resolve() not in copied_paths: existing.unlink() @@ -774,6 +805,10 @@ def update_dependencies( result.notes.append(f"copied {result.generated_files} generated shader files") if dep.get("shader_generation") and skipped_shader_targets: result.notes.append(f"skipped shader targets: {', '.join(sorted(skipped_shader_targets))}") + if dep.get("shader_generation"): + auto_skipped_targets = auto_skipped_shader_targets(dep["shader_generation"], skipped_shader_targets) + if auto_skipped_targets: + result.notes.append(f"auto-skipped unavailable optional shader targets: {', '.join(sorted(auto_skipped_targets))}") results.append(result) diff --git a/tools/rive_update_manifest.json b/tools/rive_update_manifest.json index 507c3f934..749aeb660 100644 --- a/tools/rive_update_manifest.json +++ b/tools/rive_update_manifest.json @@ -101,6 +101,8 @@ "**/*.mm", "**/*.glsl", "**/*.metal", + "**/*.hlsl", + "**/*.sig", "**/*.frag", "**/*.vert", "**/*.main", @@ -166,6 +168,10 @@ "spirv-binary": [ "make", "glslangValidator" + ], + "d3d": [ + "make", + "fxc" ] }, "targets": [ @@ -178,10 +184,69 @@ "rive_renderer_appletvos_metallib", "rive_renderer_appletvsimulator_metallib", "spirv", - "spirv-binary" + "spirv-binary", + "d3d" + ], + "optional_targets": [ + "d3d" ] } }, + { + "name": "glad", + "repo": "https://github.com/rive-app/rive-runtime.git", + "ref": "main", + "destination": "thirdparty/glad", + "license": "MIT", + "module_header": "thirdparty/glad/glad.h", + "module_version_from_ref": true, + "follow_rive_ref": true, + "copies": [ + { + "from": "renderer/glad/include", + "to": "include", + "include_globs": [ + "**/*.h" + ], + "preserve_globs": [ + "glad_custom.h" + ] + }, + { + "from": "renderer/glad", + "to": "include", + "include_globs": [ + "glad_custom.h" + ], + "preserve_globs": [ + "EGL/**", + "KHR/**", + "glad/**" + ] + }, + { + "from": "renderer/glad/src", + "to": "source", + "include_globs": [ + "**/*.c" + ], + "preserve_globs": [ + "glad_custom.c" + ] + }, + { + "from": "renderer/glad", + "to": "source", + "include_globs": [ + "glad_custom.c" + ], + "preserve_globs": [ + "egl.c", + "gles2.c" + ] + } + ] + }, { "name": "rive_decoders", "repo": "https://github.com/rive-app/rive-runtime.git", From e58828849f373203a7f62f0711f95f69b3105b65 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 11 May 2026 08:18:24 +0200 Subject: [PATCH 4/5] More fixes --- modules/yup_graphics/native/yup_GraphicsContext_gl.cpp | 8 ++++---- .../yup_graphics/native/yup_GraphicsContext_opengl.cpp | 10 +++++----- thirdparty/rive_renderer/rive_renderer_emscripten.cpp | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/yup_graphics/native/yup_GraphicsContext_gl.cpp b/modules/yup_graphics/native/yup_GraphicsContext_gl.cpp index fd4ed4021..17ecabbaa 100644 --- a/modules/yup_graphics/native/yup_GraphicsContext_gl.cpp +++ b/modules/yup_graphics/native/yup_GraphicsContext_gl.cpp @@ -38,14 +38,14 @@ static void GLAPIENTRY err_msg_callback (GLenum source, const GLchar* message, const void* userParam) { - if (type == GL_DEBUG_TYPE_ERROR) + if (type == GL_DEBUG_TYPE_ERROR_KHR) { printf ("GL ERROR: %s\n", message); fflush (stdout); assert (false); } - else if (type == GL_DEBUG_TYPE_PERFORMANCE) + else if (type == GL_DEBUG_TYPE_PERFORMANCE_KHR) { if (strcmp (message, "API_ID_REDUNDANT_FBO performance warning has been generated. Redundant state " @@ -73,7 +73,7 @@ class LowLevelRenderContextGL : public GraphicsContext { #if RIVE_DESKTOP_GL // Load the OpenGL API using glad. - if (! gladLoadCustomLoader ((GLADloadproc) options.loaderFunction)) + if (! gladLoadCustomLoader ((GLADloadfunc) options.loaderFunction)) { fprintf (stderr, "Failed to initialize glad.\n"); exit (-1); @@ -105,7 +105,7 @@ class LowLevelRenderContextGL : public GraphicsContext #if RIVE_DESKTOP_GL && DEBUG if (GLAD_GL_KHR_debug) { - glEnable (GL_DEBUG_OUTPUT); + glEnable (GL_DEBUG_OUTPUT_KHR); glDebugMessageControlKHR (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); glDebugMessageCallbackKHR (&err_msg_callback, nullptr); } diff --git a/modules/yup_graphics/native/yup_GraphicsContext_opengl.cpp b/modules/yup_graphics/native/yup_GraphicsContext_opengl.cpp index 83758abe8..60f533d1a 100644 --- a/modules/yup_graphics/native/yup_GraphicsContext_opengl.cpp +++ b/modules/yup_graphics/native/yup_GraphicsContext_opengl.cpp @@ -40,14 +40,14 @@ static void GLAPIENTRY err_msg_callback (GLenum source, const GLchar* message, const void* userParam) { - if (type == GL_DEBUG_TYPE_ERROR) + if (type == GL_DEBUG_TYPE_ERROR_KHR) { printf ("GL ERROR: %s\n", message); fflush (stdout); assert (false); } - else if (type == GL_DEBUG_TYPE_PERFORMANCE) + else if (type == GL_DEBUG_TYPE_PERFORMANCE_KHR) { if (strcmp (message, "API_ID_REDUNDANT_FBO performance warning has been generated. Redundant state " @@ -84,7 +84,7 @@ class LowLevelRenderContextGL : public GraphicsContext { #if RIVE_DESKTOP_GL // Load the OpenGL API using glad. - if (! gladLoadCustomLoader ((GLADloadproc) options.loaderFunction)) + if (! gladLoadCustomLoader ((GLADloadfunc) options.loaderFunction)) { fprintf (stderr, "Failed to initialize glad.\n"); return; @@ -108,7 +108,7 @@ class LowLevelRenderContextGL : public GraphicsContext #if DEBUG if (GLAD_GL_KHR_debug) { - glEnable (GL_DEBUG_OUTPUT); + glEnable (GL_DEBUG_OUTPUT_KHR); glDebugMessageControlKHR (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); glDebugMessageCallbackKHR (&err_msg_callback, nullptr); } @@ -278,4 +278,4 @@ std::unique_ptr yup_constructOpenGLGraphicsContext (GraphicsCon } } // namespace yup -#endif \ No newline at end of file +#endif diff --git a/thirdparty/rive_renderer/rive_renderer_emscripten.cpp b/thirdparty/rive_renderer/rive_renderer_emscripten.cpp index db25ae00a..57a94892a 100644 --- a/thirdparty/rive_renderer/rive_renderer_emscripten.cpp +++ b/thirdparty/rive_renderer/rive_renderer_emscripten.cpp @@ -35,7 +35,6 @@ #elif RIVE_WEBGL #include "source/gl/gl_state.cpp" #include "source/gl/gl_utils.cpp" -#include "source/gl/load_gles_extensions.cpp" #include "source/gl/load_store_actions_ext.cpp" #include "source/gl/pls_impl_webgl.cpp" #include "source/gl/render_buffer_gl_impl.cpp" From 758f668800c10d25a9a01918bae2e17da1d7399e Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 11 May 2026 08:36:24 +0200 Subject: [PATCH 5/5] More fixes --- thirdparty/rive_renderer/rive_renderer_apple.mm | 1 - thirdparty/rive_renderer/rive_renderer_linux.cpp | 1 - thirdparty/rive_renderer/rive_renderer_windows.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/thirdparty/rive_renderer/rive_renderer_apple.mm b/thirdparty/rive_renderer/rive_renderer_apple.mm index 6fbd4ef81..37918620a 100644 --- a/thirdparty/rive_renderer/rive_renderer_apple.mm +++ b/thirdparty/rive_renderer/rive_renderer_apple.mm @@ -39,7 +39,6 @@ #if YUP_RIVE_USE_OPENGL #include "source/gl/gl_state.cpp" #include "source/gl/gl_utils.cpp" -#include "source/gl/load_gles_extensions.cpp" #include "source/gl/load_store_actions_ext.cpp" #include "source/gl/pls_impl_ext_native.cpp" #include "source/gl/pls_impl_rw_texture.cpp" diff --git a/thirdparty/rive_renderer/rive_renderer_linux.cpp b/thirdparty/rive_renderer/rive_renderer_linux.cpp index 168781750..b5f35e28b 100644 --- a/thirdparty/rive_renderer/rive_renderer_linux.cpp +++ b/thirdparty/rive_renderer/rive_renderer_linux.cpp @@ -32,7 +32,6 @@ #include "source/gl/gl_state.cpp" #include "source/gl/gl_utils.cpp" -#include "source/gl/load_gles_extensions.cpp" #include "source/gl/load_store_actions_ext.cpp" #include "source/gl/pls_impl_ext_native.cpp" #include "source/gl/pls_impl_rw_texture.cpp" diff --git a/thirdparty/rive_renderer/rive_renderer_windows.cpp b/thirdparty/rive_renderer/rive_renderer_windows.cpp index 046be431c..230ffe608 100644 --- a/thirdparty/rive_renderer/rive_renderer_windows.cpp +++ b/thirdparty/rive_renderer/rive_renderer_windows.cpp @@ -38,7 +38,6 @@ #include "source/gl/gl_state.cpp" #include "source/gl/gl_utils.cpp" -#include "source/gl/load_gles_extensions.cpp" #include "source/gl/load_store_actions_ext.cpp" #include "source/gl/pls_impl_ext_native.cpp" #include "source/gl/pls_impl_rw_texture.cpp"